diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..284091b --- /dev/null +++ b/.gitignore @@ -0,0 +1,69 @@ +# Xcode +# +# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore + +## Build generated +build/ +DerivedData/ + +## Various settings +*.pbxuser +!default.pbxuser +*.mode1v3 +!default.mode1v3 +*.mode2v3 +!default.mode2v3 +*.perspectivev3 +!default.perspectivev3 +xcuserdata/ + +## Other +*.moved-aside +*.xccheckout +*.xcscmblueprint +*.DS_Store + +## Obj-C/Swift specific +*.hmap +*.ipa +*.dSYM.zip +*.dSYM + +## Playgrounds +timeline.xctimeline +playground.xcworkspace + +# Swift Package Manager +# +# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. +# Packages/ +# Package.pins +# Package.resolved +.build/ + +# CocoaPods +# +# We recommend against adding the Pods directory to your .gitignore. However +# you should judge for yourself, the pros and cons are mentioned at: +# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control +# +# Pods/ + +# Carthage +# +# Add this line if you want to avoid checking in source code from Carthage dependencies. +# Carthage/Checkouts + +Carthage/Build + +# fastlane +# +# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the +# screenshots whenever they are needed. +# For more information about the recommended setup visit: +# https://docs.fastlane.tools/best-practices/source-control/#source-control + +fastlane/report.xml +fastlane/Preview.html +fastlane/screenshots/**/*.png +fastlane/test_output diff --git a/FoodApp/FoodApp.xcodeproj/project.pbxproj b/FoodApp/FoodApp.xcodeproj/project.pbxproj index 5d043eb..2d6b088 100644 --- a/FoodApp/FoodApp.xcodeproj/project.pbxproj +++ b/FoodApp/FoodApp.xcodeproj/project.pbxproj @@ -7,21 +7,69 @@ objects = { /* Begin PBXBuildFile section */ + 2584FC0E118C60CC92B3E235 /* Pods_FoodApp.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B232B2D87D2ABD85CF14E4AE /* Pods_FoodApp.framework */; }; + 7935D49C2253C0E80046F903 /* Review.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7935D49B2253C0E80046F903 /* Review.swift */; }; + 79388B622251533500B6B8A2 /* UserProfile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 79388B612251533500B6B8A2 /* UserProfile.swift */; }; + 7940E1B822554A8F00AFC558 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 7940E1B722554A8F00AFC558 /* Assets.xcassets */; }; + 796D57DE225278CD00D34142 /* ShoppingCartTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 796D57DC225278CD00D34142 /* ShoppingCartTableViewCell.swift */; }; + 796D57DF225278CD00D34142 /* ShoppingCartTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 796D57DD225278CD00D34142 /* ShoppingCartTableViewCell.xib */; }; + 79735C6F224FE0D600575723 /* FirebaseAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 79735C6E224FE0D600575723 /* FirebaseAPI.swift */; }; + 79735C71224FE19F00575723 /* MenuCategory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 79735C70224FE19F00575723 /* MenuCategory.swift */; }; + 79AA0B9E22440C1400B18A88 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 79AA0B9D22440C1400B18A88 /* GoogleService-Info.plist */; }; 79EBBE27221340D8006C4341 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 79EBBE26221340D8006C4341 /* AppDelegate.swift */; }; - 79EBBE29221340D8006C4341 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 79EBBE28221340D8006C4341 /* ViewController.swift */; }; + 79EBBE29221340D8006C4341 /* HomeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 79EBBE28221340D8006C4341 /* HomeViewController.swift */; }; 79EBBE2C221340D8006C4341 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 79EBBE2A221340D8006C4341 /* Main.storyboard */; }; - 79EBBE2E221340DA006C4341 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 79EBBE2D221340DA006C4341 /* Assets.xcassets */; }; 79EBBE31221340DA006C4341 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 79EBBE2F221340DA006C4341 /* LaunchScreen.storyboard */; }; + BF0A38E02243FD6400651A6E /* OrderViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF0A38DF2243FD6400651A6E /* OrderViewController.swift */; }; + BF0A38E2224416E900651A6E /* DescriptionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF0A38E1224416E900651A6E /* DescriptionViewController.swift */; }; + BF0A38E42244175800651A6E /* RatingsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF0A38E32244175800651A6E /* RatingsViewController.swift */; }; + BF0A39052246682700651A6E /* CategoriesCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF0A39042246682700651A6E /* CategoriesCollectionViewCell.swift */; }; + BF1D4F2B221F20A9000B95D5 /* TabBarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF1D4F29221F20A9000B95D5 /* TabBarController.swift */; }; + BF1D4F31221F38DD000B95D5 /* MenuItemCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF1D4F2F221F38DD000B95D5 /* MenuItemCollectionViewCell.swift */; }; + BF1D4F32221F38DD000B95D5 /* MenuItemCollectionViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = BF1D4F30221F38DD000B95D5 /* MenuItemCollectionViewCell.xib */; }; + BF509C4E223C1B6A0064AF82 /* ShoppingCartViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF509C4D223C1B6A0064AF82 /* ShoppingCartViewController.swift */; }; + BF509C50223C1B740064AF82 /* ProfileViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF509C4F223C1B740064AF82 /* ProfileViewController.swift */; }; + BF509C52223C78DA0064AF82 /* MenuItemDetailViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF509C51223C78DA0064AF82 /* MenuItemDetailViewController.swift */; }; + BF509C54223C79050064AF82 /* MenuItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF509C53223C79050064AF82 /* MenuItem.swift */; }; + BF509C782240661F0064AF82 /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF509C772240661F0064AF82 /* Extensions.swift */; }; + BF8046FA224FDE0A002DE18F /* RatingsTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF8046F8224FDE0A002DE18F /* RatingsTableViewCell.swift */; }; + BF8046FB224FDE0A002DE18F /* RatingsTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = BF8046F9224FDE0A002DE18F /* RatingsTableViewCell.xib */; }; + BF8046FF225149A2002DE18F /* LoginViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF8046FE225149A2002DE18F /* LoginViewController.swift */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ + 4A43F00BDF9963E6B1072C32 /* Pods-FoodApp.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-FoodApp.release.xcconfig"; path = "Target Support Files/Pods-FoodApp/Pods-FoodApp.release.xcconfig"; sourceTree = ""; }; + 7935D49B2253C0E80046F903 /* Review.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Review.swift; sourceTree = ""; }; + 79388B612251533500B6B8A2 /* UserProfile.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserProfile.swift; sourceTree = ""; }; + 7940E1B722554A8F00AFC558 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 796D57DC225278CD00D34142 /* ShoppingCartTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShoppingCartTableViewCell.swift; sourceTree = ""; }; + 796D57DD225278CD00D34142 /* ShoppingCartTableViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ShoppingCartTableViewCell.xib; sourceTree = ""; }; + 79735C6E224FE0D600575723 /* FirebaseAPI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FirebaseAPI.swift; sourceTree = ""; }; + 79735C70224FE19F00575723 /* MenuCategory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuCategory.swift; sourceTree = ""; }; + 79AA0B9D22440C1400B18A88 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; }; 79EBBE23221340D8006C4341 /* FoodApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = FoodApp.app; sourceTree = BUILT_PRODUCTS_DIR; }; 79EBBE26221340D8006C4341 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; - 79EBBE28221340D8006C4341 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; + 79EBBE28221340D8006C4341 /* HomeViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeViewController.swift; sourceTree = ""; }; 79EBBE2B221340D8006C4341 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; - 79EBBE2D221340DA006C4341 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 79EBBE30221340DA006C4341 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 79EBBE32221340DA006C4341 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + AB5036CBA5BD3555774A829D /* Pods-FoodApp.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-FoodApp.debug.xcconfig"; path = "Target Support Files/Pods-FoodApp/Pods-FoodApp.debug.xcconfig"; sourceTree = ""; }; + B232B2D87D2ABD85CF14E4AE /* Pods_FoodApp.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_FoodApp.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + BF0A38DF2243FD6400651A6E /* OrderViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OrderViewController.swift; sourceTree = ""; }; + BF0A38E1224416E900651A6E /* DescriptionViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DescriptionViewController.swift; sourceTree = ""; }; + BF0A38E32244175800651A6E /* RatingsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RatingsViewController.swift; sourceTree = ""; }; + BF0A39042246682700651A6E /* CategoriesCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CategoriesCollectionViewCell.swift; sourceTree = ""; }; + BF1D4F29221F20A9000B95D5 /* TabBarController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabBarController.swift; sourceTree = ""; }; + BF1D4F2F221F38DD000B95D5 /* MenuItemCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = MenuItemCollectionViewCell.swift; path = FoodApp/Views/MenuItemCollectionViewCell.swift; sourceTree = SOURCE_ROOT; }; + BF1D4F30221F38DD000B95D5 /* MenuItemCollectionViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = MenuItemCollectionViewCell.xib; path = FoodApp/Views/MenuItemCollectionViewCell.xib; sourceTree = SOURCE_ROOT; }; + BF509C4D223C1B6A0064AF82 /* ShoppingCartViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShoppingCartViewController.swift; sourceTree = ""; }; + BF509C4F223C1B740064AF82 /* ProfileViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileViewController.swift; sourceTree = ""; }; + BF509C51223C78DA0064AF82 /* MenuItemDetailViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuItemDetailViewController.swift; sourceTree = ""; }; + BF509C53223C79050064AF82 /* MenuItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuItem.swift; sourceTree = ""; }; + BF509C772240661F0064AF82 /* Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Extensions.swift; sourceTree = ""; }; + BF8046F8224FDE0A002DE18F /* RatingsTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RatingsTableViewCell.swift; sourceTree = ""; }; + BF8046F9224FDE0A002DE18F /* RatingsTableViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = RatingsTableViewCell.xib; sourceTree = ""; }; + BF8046FE225149A2002DE18F /* LoginViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginViewController.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -29,17 +77,37 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 2584FC0E118C60CC92B3E235 /* Pods_FoodApp.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 414AEAA7698D5A021620C0CE /* Frameworks */ = { + isa = PBXGroup; + children = ( + B232B2D87D2ABD85CF14E4AE /* Pods_FoodApp.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 533B5E719277C63027DED21D /* Pods */ = { + isa = PBXGroup; + children = ( + AB5036CBA5BD3555774A829D /* Pods-FoodApp.debug.xcconfig */, + 4A43F00BDF9963E6B1072C32 /* Pods-FoodApp.release.xcconfig */, + ); + path = Pods; + sourceTree = ""; + }; 79EBBE1A221340D8006C4341 = { isa = PBXGroup; children = ( - 79EBBE25221340D8006C4341 /* FoodApp */, 79EBBE24221340D8006C4341 /* Products */, + DE112B0C17C210FFD0D04006 /* FoodApp */, + 533B5E719277C63027DED21D /* Pods */, + 414AEAA7698D5A021620C0CE /* Frameworks */, ); sourceTree = ""; }; @@ -51,15 +119,77 @@ name = Products; sourceTree = ""; }; - 79EBBE25221340D8006C4341 /* FoodApp */ = { + BF0A38DE2243FCF400651A6E /* PageViewControllers */ = { + isa = PBXGroup; + children = ( + BF0A38DF2243FD6400651A6E /* OrderViewController.swift */, + BF0A38E1224416E900651A6E /* DescriptionViewController.swift */, + BF0A38E32244175800651A6E /* RatingsViewController.swift */, + ); + path = PageViewControllers; + sourceTree = ""; + }; + BF439FCB2225BBA400BCDF9A /* Models */ = { + isa = PBXGroup; + children = ( + BF509C53223C79050064AF82 /* MenuItem.swift */, + 79735C6E224FE0D600575723 /* FirebaseAPI.swift */, + 79735C70224FE19F00575723 /* MenuCategory.swift */, + 79388B612251533500B6B8A2 /* UserProfile.swift */, + 7935D49B2253C0E80046F903 /* Review.swift */, + ); + path = Models; + sourceTree = ""; + }; + BF439FCC2225BBAB00BCDF9A /* Views */ = { + isa = PBXGroup; + children = ( + BF0A39042246682700651A6E /* CategoriesCollectionViewCell.swift */, + BF8046F8224FDE0A002DE18F /* RatingsTableViewCell.swift */, + BF8046F9224FDE0A002DE18F /* RatingsTableViewCell.xib */, + BF1D4F2F221F38DD000B95D5 /* MenuItemCollectionViewCell.swift */, + BF1D4F30221F38DD000B95D5 /* MenuItemCollectionViewCell.xib */, + 796D57DC225278CD00D34142 /* ShoppingCartTableViewCell.swift */, + 796D57DD225278CD00D34142 /* ShoppingCartTableViewCell.xib */, + ); + path = Views; + sourceTree = ""; + }; + BF439FCD2225BBB000BCDF9A /* Controllers */ = { + isa = PBXGroup; + children = ( + BF8046FE225149A2002DE18F /* LoginViewController.swift */, + BF1D4F29221F20A9000B95D5 /* TabBarController.swift */, + BF80470022517619002DE18F /* Tabs */, + BF509C51223C78DA0064AF82 /* MenuItemDetailViewController.swift */, + BF0A38DE2243FCF400651A6E /* PageViewControllers */, + ); + path = Controllers; + sourceTree = ""; + }; + BF80470022517619002DE18F /* Tabs */ = { + isa = PBXGroup; + children = ( + 79EBBE28221340D8006C4341 /* HomeViewController.swift */, + BF509C4D223C1B6A0064AF82 /* ShoppingCartViewController.swift */, + BF509C4F223C1B740064AF82 /* ProfileViewController.swift */, + ); + path = Tabs; + sourceTree = ""; + }; + DE112B0C17C210FFD0D04006 /* FoodApp */ = { isa = PBXGroup; children = ( + 7940E1B722554A8F00AFC558 /* Assets.xcassets */, 79EBBE26221340D8006C4341 /* AppDelegate.swift */, - 79EBBE28221340D8006C4341 /* ViewController.swift */, + BF509C772240661F0064AF82 /* Extensions.swift */, + BF439FCD2225BBB000BCDF9A /* Controllers */, + BF439FCC2225BBAB00BCDF9A /* Views */, + BF439FCB2225BBA400BCDF9A /* Models */, 79EBBE2A221340D8006C4341 /* Main.storyboard */, - 79EBBE2D221340DA006C4341 /* Assets.xcassets */, 79EBBE2F221340DA006C4341 /* LaunchScreen.storyboard */, 79EBBE32221340DA006C4341 /* Info.plist */, + 79AA0B9D22440C1400B18A88 /* GoogleService-Info.plist */, ); path = FoodApp; sourceTree = ""; @@ -71,9 +201,11 @@ isa = PBXNativeTarget; buildConfigurationList = 79EBBE35221340DA006C4341 /* Build configuration list for PBXNativeTarget "FoodApp" */; buildPhases = ( + 3817D01C6A3B8A656496F9BE /* [CP] Check Pods Manifest.lock */, 79EBBE1F221340D8006C4341 /* Sources */, 79EBBE20221340D8006C4341 /* Frameworks */, 79EBBE21221340D8006C4341 /* Resources */, + EBCA613563E3DDDB7E653021 /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -123,20 +255,109 @@ buildActionMask = 2147483647; files = ( 79EBBE31221340DA006C4341 /* LaunchScreen.storyboard in Resources */, - 79EBBE2E221340DA006C4341 /* Assets.xcassets in Resources */, + BF8046FB224FDE0A002DE18F /* RatingsTableViewCell.xib in Resources */, + 79AA0B9E22440C1400B18A88 /* GoogleService-Info.plist in Resources */, 79EBBE2C221340D8006C4341 /* Main.storyboard in Resources */, + 7940E1B822554A8F00AFC558 /* Assets.xcassets in Resources */, + BF1D4F32221F38DD000B95D5 /* MenuItemCollectionViewCell.xib in Resources */, + 796D57DF225278CD00D34142 /* ShoppingCartTableViewCell.xib in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXResourcesBuildPhase section */ +/* Begin PBXShellScriptBuildPhase section */ + 3817D01C6A3B8A656496F9BE /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-FoodApp-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + EBCA613563E3DDDB7E653021 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-FoodApp/Pods-FoodApp-frameworks.sh", + "${BUILT_PRODUCTS_DIR}/BoringSSL-GRPC/openssl_grpc.framework", + "${BUILT_PRODUCTS_DIR}/CodableFirebase/CodableFirebase.framework", + "${BUILT_PRODUCTS_DIR}/GTMSessionFetcher/GTMSessionFetcher.framework", + "${BUILT_PRODUCTS_DIR}/GoogleUtilities/GoogleUtilities.framework", + "${BUILT_PRODUCTS_DIR}/IQKeyboardManagerSwift/IQKeyboardManagerSwift.framework", + "${BUILT_PRODUCTS_DIR}/Protobuf/Protobuf.framework", + "${BUILT_PRODUCTS_DIR}/SkyFloatingLabelTextField/SkyFloatingLabelTextField.framework", + "${BUILT_PRODUCTS_DIR}/gRPC-C++/grpcpp.framework", + "${BUILT_PRODUCTS_DIR}/gRPC-Core/grpc.framework", + "${BUILT_PRODUCTS_DIR}/leveldb-library/leveldb.framework", + "${BUILT_PRODUCTS_DIR}/nanopb/nanopb.framework", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + ); + outputPaths = ( + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/openssl_grpc.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CodableFirebase.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GTMSessionFetcher.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GoogleUtilities.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/IQKeyboardManagerSwift.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Protobuf.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SkyFloatingLabelTextField.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/grpcpp.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/grpc.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/leveldb.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/nanopb.framework", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-FoodApp/Pods-FoodApp-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + /* Begin PBXSourcesBuildPhase section */ 79EBBE1F221340D8006C4341 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 79EBBE29221340D8006C4341 /* ViewController.swift in Sources */, + BF8046FA224FDE0A002DE18F /* RatingsTableViewCell.swift in Sources */, + BF509C4E223C1B6A0064AF82 /* ShoppingCartViewController.swift in Sources */, + BF0A38E2224416E900651A6E /* DescriptionViewController.swift in Sources */, + BF8046FF225149A2002DE18F /* LoginViewController.swift in Sources */, + 79EBBE29221340D8006C4341 /* HomeViewController.swift in Sources */, 79EBBE27221340D8006C4341 /* AppDelegate.swift in Sources */, + 7935D49C2253C0E80046F903 /* Review.swift in Sources */, + BF509C52223C78DA0064AF82 /* MenuItemDetailViewController.swift in Sources */, + BF1D4F2B221F20A9000B95D5 /* TabBarController.swift in Sources */, + 796D57DE225278CD00D34142 /* ShoppingCartTableViewCell.swift in Sources */, + 79735C6F224FE0D600575723 /* FirebaseAPI.swift in Sources */, + 79388B622251533500B6B8A2 /* UserProfile.swift in Sources */, + BF0A39052246682700651A6E /* CategoriesCollectionViewCell.swift in Sources */, + BF509C50223C1B740064AF82 /* ProfileViewController.swift in Sources */, + BF0A38E42244175800651A6E /* RatingsViewController.swift in Sources */, + BF1D4F31221F38DD000B95D5 /* MenuItemCollectionViewCell.swift in Sources */, + BF509C782240661F0064AF82 /* Extensions.swift in Sources */, + 79735C71224FE19F00575723 /* MenuCategory.swift in Sources */, + BF509C54223C79050064AF82 /* MenuItem.swift in Sources */, + BF0A38E02243FD6400651A6E /* OrderViewController.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -280,9 +501,11 @@ }; 79EBBE36221340DA006C4341 /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReference = AB5036CBA5BD3555774A829D /* Pods-FoodApp.debug.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = HRVS9455XM; INFOPLIST_FILE = FoodApp/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", @@ -297,9 +520,11 @@ }; 79EBBE37221340DA006C4341 /* Release */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 4A43F00BDF9963E6B1072C32 /* Pods-FoodApp.release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = HRVS9455XM; INFOPLIST_FILE = FoodApp/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", diff --git a/FoodApp/FoodApp.xcodeproj/project.pbxproj.orig b/FoodApp/FoodApp.xcodeproj/project.pbxproj.orig new file mode 100644 index 0000000..696bd15 --- /dev/null +++ b/FoodApp/FoodApp.xcodeproj/project.pbxproj.orig @@ -0,0 +1,574 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + 7935D49C2253C0E80046F903 /* Review.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7935D49B2253C0E80046F903 /* Review.swift */; }; + 79388B622251533500B6B8A2 /* UserProfile.swift in Sources */ = {isa = PBXBuildFile; fileRef = 79388B612251533500B6B8A2 /* UserProfile.swift */; }; + 796D57DE225278CD00D34142 /* ShoppingCartTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 796D57DC225278CD00D34142 /* ShoppingCartTableViewCell.swift */; }; + 796D57DF225278CD00D34142 /* ShoppingCartTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 796D57DD225278CD00D34142 /* ShoppingCartTableViewCell.xib */; }; + 79735C6F224FE0D600575723 /* FirebaseAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 79735C6E224FE0D600575723 /* FirebaseAPI.swift */; }; + 79735C71224FE19F00575723 /* MenuCategory.swift in Sources */ = {isa = PBXBuildFile; fileRef = 79735C70224FE19F00575723 /* MenuCategory.swift */; }; + 79AA0B9E22440C1400B18A88 /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 79AA0B9D22440C1400B18A88 /* GoogleService-Info.plist */; }; + 79EBBE27221340D8006C4341 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 79EBBE26221340D8006C4341 /* AppDelegate.swift */; }; + 79EBBE29221340D8006C4341 /* HomeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 79EBBE28221340D8006C4341 /* HomeViewController.swift */; }; + 79EBBE2C221340D8006C4341 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 79EBBE2A221340D8006C4341 /* Main.storyboard */; }; + 79EBBE2E221340DA006C4341 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 79EBBE2D221340DA006C4341 /* Assets.xcassets */; }; + 79EBBE31221340DA006C4341 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 79EBBE2F221340DA006C4341 /* LaunchScreen.storyboard */; }; + B599769FA18FFF14459F2FCF /* Pods_FoodApp.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 94B7EB9ABB21F02BA5F1AC2A /* Pods_FoodApp.framework */; }; + BF0A38E02243FD6400651A6E /* OrderViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF0A38DF2243FD6400651A6E /* OrderViewController.swift */; }; + BF0A38E2224416E900651A6E /* DescriptionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF0A38E1224416E900651A6E /* DescriptionViewController.swift */; }; + BF0A38E42244175800651A6E /* RatingsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF0A38E32244175800651A6E /* RatingsViewController.swift */; }; + BF0A39052246682700651A6E /* CategoriesCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF0A39042246682700651A6E /* CategoriesCollectionViewCell.swift */; }; + BF1D4F2B221F20A9000B95D5 /* TabBarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF1D4F29221F20A9000B95D5 /* TabBarController.swift */; }; + BF1D4F31221F38DD000B95D5 /* MenuItemCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF1D4F2F221F38DD000B95D5 /* MenuItemCollectionViewCell.swift */; }; + BF1D4F32221F38DD000B95D5 /* MenuItemCollectionViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = BF1D4F30221F38DD000B95D5 /* MenuItemCollectionViewCell.xib */; }; + BF509C4E223C1B6A0064AF82 /* ShoppingCartViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF509C4D223C1B6A0064AF82 /* ShoppingCartViewController.swift */; }; + BF509C50223C1B740064AF82 /* ProfileViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF509C4F223C1B740064AF82 /* ProfileViewController.swift */; }; + BF509C52223C78DA0064AF82 /* MenuItemDetailViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF509C51223C78DA0064AF82 /* MenuItemDetailViewController.swift */; }; + BF509C54223C79050064AF82 /* MenuItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF509C53223C79050064AF82 /* MenuItem.swift */; }; + BF509C782240661F0064AF82 /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF509C772240661F0064AF82 /* Extensions.swift */; }; + BF8046FA224FDE0A002DE18F /* RatingsTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF8046F8224FDE0A002DE18F /* RatingsTableViewCell.swift */; }; + BF8046FB224FDE0A002DE18F /* RatingsTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = BF8046F9224FDE0A002DE18F /* RatingsTableViewCell.xib */; }; + BF8046FF225149A2002DE18F /* LoginViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF8046FE225149A2002DE18F /* LoginViewController.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 7935D49B2253C0E80046F903 /* Review.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Review.swift; sourceTree = ""; }; + 79388B612251533500B6B8A2 /* UserProfile.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserProfile.swift; sourceTree = ""; }; + 796D57DC225278CD00D34142 /* ShoppingCartTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShoppingCartTableViewCell.swift; sourceTree = ""; }; + 796D57DD225278CD00D34142 /* ShoppingCartTableViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ShoppingCartTableViewCell.xib; sourceTree = ""; }; + 79735C6E224FE0D600575723 /* FirebaseAPI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FirebaseAPI.swift; sourceTree = ""; }; + 79735C70224FE19F00575723 /* MenuCategory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuCategory.swift; sourceTree = ""; }; + 79AA0B9D22440C1400B18A88 /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; }; + 79EBBE23221340D8006C4341 /* FoodApp.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = FoodApp.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 79EBBE26221340D8006C4341 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 79EBBE28221340D8006C4341 /* HomeViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeViewController.swift; sourceTree = ""; }; + 79EBBE2B221340D8006C4341 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 79EBBE2D221340DA006C4341 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 79EBBE30221340DA006C4341 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 79EBBE32221340DA006C4341 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 7A136462236305D5C1B0116E /* Pods-FoodApp.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-FoodApp.debug.xcconfig"; path = "Target Support Files/Pods-FoodApp/Pods-FoodApp.debug.xcconfig"; sourceTree = ""; }; + 94B7EB9ABB21F02BA5F1AC2A /* Pods_FoodApp.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_FoodApp.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + BF0A38DF2243FD6400651A6E /* OrderViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OrderViewController.swift; sourceTree = ""; }; + BF0A38E1224416E900651A6E /* DescriptionViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DescriptionViewController.swift; sourceTree = ""; }; + BF0A38E32244175800651A6E /* RatingsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RatingsViewController.swift; sourceTree = ""; }; + BF0A39042246682700651A6E /* CategoriesCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CategoriesCollectionViewCell.swift; sourceTree = ""; }; + BF1D4F29221F20A9000B95D5 /* TabBarController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TabBarController.swift; sourceTree = ""; }; + BF1D4F2F221F38DD000B95D5 /* MenuItemCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = MenuItemCollectionViewCell.swift; path = FoodApp/Views/MenuItemCollectionViewCell.swift; sourceTree = SOURCE_ROOT; }; + BF1D4F30221F38DD000B95D5 /* MenuItemCollectionViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = MenuItemCollectionViewCell.xib; path = FoodApp/Views/MenuItemCollectionViewCell.xib; sourceTree = SOURCE_ROOT; }; + BF509C4D223C1B6A0064AF82 /* ShoppingCartViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShoppingCartViewController.swift; sourceTree = ""; }; + BF509C4F223C1B740064AF82 /* ProfileViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileViewController.swift; sourceTree = ""; }; + BF509C51223C78DA0064AF82 /* MenuItemDetailViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuItemDetailViewController.swift; sourceTree = ""; }; + BF509C53223C79050064AF82 /* MenuItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuItem.swift; sourceTree = ""; }; + BF509C772240661F0064AF82 /* Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Extensions.swift; sourceTree = ""; }; + BF8046F8224FDE0A002DE18F /* RatingsTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RatingsTableViewCell.swift; sourceTree = ""; }; + BF8046F9224FDE0A002DE18F /* RatingsTableViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = RatingsTableViewCell.xib; sourceTree = ""; }; + BF8046FE225149A2002DE18F /* LoginViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginViewController.swift; sourceTree = ""; }; + D59F8127439E5E39BB747D7F /* Pods-FoodApp.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-FoodApp.release.xcconfig"; path = "Target Support Files/Pods-FoodApp/Pods-FoodApp.release.xcconfig"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 79EBBE20221340D8006C4341 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + B599769FA18FFF14459F2FCF /* Pods_FoodApp.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 533B5E719277C63027DED21D /* Pods */ = { + isa = PBXGroup; + children = ( + 7A136462236305D5C1B0116E /* Pods-FoodApp.debug.xcconfig */, + D59F8127439E5E39BB747D7F /* Pods-FoodApp.release.xcconfig */, + ); + path = Pods; + sourceTree = ""; + }; + 682E154F7090291C82290607 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 94B7EB9ABB21F02BA5F1AC2A /* Pods_FoodApp.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 79EBBE1A221340D8006C4341 = { + isa = PBXGroup; + children = ( + 79EBBE24221340D8006C4341 /* Products */, + DE112B0C17C210FFD0D04006 /* FoodApp */, + 533B5E719277C63027DED21D /* Pods */, + 682E154F7090291C82290607 /* Frameworks */, + ); + sourceTree = ""; + }; + 79EBBE24221340D8006C4341 /* Products */ = { + isa = PBXGroup; + children = ( + 79EBBE23221340D8006C4341 /* FoodApp.app */, + ); + name = Products; + sourceTree = ""; + }; + BF0A38DE2243FCF400651A6E /* PageViewControllers */ = { + isa = PBXGroup; + children = ( + BF0A38DF2243FD6400651A6E /* OrderViewController.swift */, + BF0A38E1224416E900651A6E /* DescriptionViewController.swift */, + BF0A38E32244175800651A6E /* RatingsViewController.swift */, + ); + path = PageViewControllers; + sourceTree = ""; + }; + BF439FCB2225BBA400BCDF9A /* Models */ = { + isa = PBXGroup; + children = ( + BF509C53223C79050064AF82 /* MenuItem.swift */, + 79735C6E224FE0D600575723 /* FirebaseAPI.swift */, + 79735C70224FE19F00575723 /* MenuCategory.swift */, + 79388B612251533500B6B8A2 /* UserProfile.swift */, + 7935D49B2253C0E80046F903 /* Review.swift */, + ); + path = Models; + sourceTree = ""; + }; + BF439FCC2225BBAB00BCDF9A /* Views */ = { + isa = PBXGroup; + children = ( + BF0A39042246682700651A6E /* CategoriesCollectionViewCell.swift */, + BF8046F8224FDE0A002DE18F /* RatingsTableViewCell.swift */, + BF8046F9224FDE0A002DE18F /* RatingsTableViewCell.xib */, + BF1D4F2F221F38DD000B95D5 /* MenuItemCollectionViewCell.swift */, + BF1D4F30221F38DD000B95D5 /* MenuItemCollectionViewCell.xib */, + 796D57DC225278CD00D34142 /* ShoppingCartTableViewCell.swift */, + 796D57DD225278CD00D34142 /* ShoppingCartTableViewCell.xib */, + ); + path = Views; + sourceTree = ""; + }; + BF439FCD2225BBB000BCDF9A /* Controllers */ = { + isa = PBXGroup; + children = ( + BF8046FE225149A2002DE18F /* LoginViewController.swift */, + BF1D4F29221F20A9000B95D5 /* TabBarController.swift */, + BF80470022517619002DE18F /* Tabs */, + BF509C51223C78DA0064AF82 /* MenuItemDetailViewController.swift */, + BF0A38DE2243FCF400651A6E /* PageViewControllers */, + ); + path = Controllers; + sourceTree = ""; + }; + BF80470022517619002DE18F /* Tabs */ = { + isa = PBXGroup; + children = ( + 79EBBE28221340D8006C4341 /* HomeViewController.swift */, + BF509C4D223C1B6A0064AF82 /* ShoppingCartViewController.swift */, + BF509C4F223C1B740064AF82 /* ProfileViewController.swift */, + ); + path = Tabs; + sourceTree = ""; + }; + DE112B0C17C210FFD0D04006 /* FoodApp */ = { + isa = PBXGroup; + children = ( + 79EBBE26221340D8006C4341 /* AppDelegate.swift */, + BF509C772240661F0064AF82 /* Extensions.swift */, + BF439FCD2225BBB000BCDF9A /* Controllers */, + BF439FCC2225BBAB00BCDF9A /* Views */, + BF439FCB2225BBA400BCDF9A /* Models */, + 79EBBE2D221340DA006C4341 /* Assets.xcassets */, + 79EBBE2A221340D8006C4341 /* Main.storyboard */, + 79EBBE2F221340DA006C4341 /* LaunchScreen.storyboard */, + 79EBBE32221340DA006C4341 /* Info.plist */, + 79AA0B9D22440C1400B18A88 /* GoogleService-Info.plist */, + ); + path = FoodApp; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 79EBBE22221340D8006C4341 /* FoodApp */ = { + isa = PBXNativeTarget; + buildConfigurationList = 79EBBE35221340DA006C4341 /* Build configuration list for PBXNativeTarget "FoodApp" */; + buildPhases = ( + 2D4861CDD82585292E712D3B /* [CP] Check Pods Manifest.lock */, + 79EBBE1F221340D8006C4341 /* Sources */, + 79EBBE20221340D8006C4341 /* Frameworks */, + 79EBBE21221340D8006C4341 /* Resources */, + 9E37725C4B58B3977A3DC71D /* [CP] Embed Pods Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = FoodApp; + productName = FoodApp; + productReference = 79EBBE23221340D8006C4341 /* FoodApp.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 79EBBE1B221340D8006C4341 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 1010; + LastUpgradeCheck = 1010; + ORGANIZATIONNAME = SparkDev; + TargetAttributes = { + 79EBBE22221340D8006C4341 = { + CreatedOnToolsVersion = 10.1; + }; + }; + }; + buildConfigurationList = 79EBBE1E221340D8006C4341 /* Build configuration list for PBXProject "FoodApp" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 79EBBE1A221340D8006C4341; + productRefGroup = 79EBBE24221340D8006C4341 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 79EBBE22221340D8006C4341 /* FoodApp */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 79EBBE21221340D8006C4341 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 79EBBE31221340DA006C4341 /* LaunchScreen.storyboard in Resources */, + 79EBBE2E221340DA006C4341 /* Assets.xcassets in Resources */, + BF8046FB224FDE0A002DE18F /* RatingsTableViewCell.xib in Resources */, + 79AA0B9E22440C1400B18A88 /* GoogleService-Info.plist in Resources */, + 79EBBE2C221340D8006C4341 /* Main.storyboard in Resources */, + BF1D4F32221F38DD000B95D5 /* MenuItemCollectionViewCell.xib in Resources */, + 796D57DF225278CD00D34142 /* ShoppingCartTableViewCell.xib in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 2D4861CDD82585292E712D3B /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-FoodApp-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + 9E37725C4B58B3977A3DC71D /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-FoodApp/Pods-FoodApp-frameworks.sh", + "${BUILT_PRODUCTS_DIR}/BoringSSL-GRPC/openssl_grpc.framework", + "${BUILT_PRODUCTS_DIR}/CodableFirebase/CodableFirebase.framework", + "${BUILT_PRODUCTS_DIR}/GTMSessionFetcher/GTMSessionFetcher.framework", + "${BUILT_PRODUCTS_DIR}/GoogleUtilities/GoogleUtilities.framework", +<<<<<<< HEAD + "${BUILT_PRODUCTS_DIR}/IQKeyboardManagerSwift/IQKeyboardManagerSwift.framework", +======= + "${BUILT_PRODUCTS_DIR}/Protobuf/Protobuf.framework", +>>>>>>> e52f18c2553988c046c489e0ecf20b0cf96fe655 + "${BUILT_PRODUCTS_DIR}/SkyFloatingLabelTextField/SkyFloatingLabelTextField.framework", + "${BUILT_PRODUCTS_DIR}/gRPC-C++/grpcpp.framework", + "${BUILT_PRODUCTS_DIR}/gRPC-Core/grpc.framework", + "${BUILT_PRODUCTS_DIR}/leveldb-library/leveldb.framework", + "${BUILT_PRODUCTS_DIR}/nanopb/nanopb.framework", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + ); + outputPaths = ( + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/openssl_grpc.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CodableFirebase.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GTMSessionFetcher.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GoogleUtilities.framework", +<<<<<<< HEAD + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/IQKeyboardManagerSwift.framework", +======= + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Protobuf.framework", +>>>>>>> e52f18c2553988c046c489e0ecf20b0cf96fe655 + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SkyFloatingLabelTextField.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/grpcpp.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/grpc.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/leveldb.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/nanopb.framework", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-FoodApp/Pods-FoodApp-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 79EBBE1F221340D8006C4341 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + BF8046FA224FDE0A002DE18F /* RatingsTableViewCell.swift in Sources */, + BF509C4E223C1B6A0064AF82 /* ShoppingCartViewController.swift in Sources */, + BF0A38E2224416E900651A6E /* DescriptionViewController.swift in Sources */, + BF8046FF225149A2002DE18F /* LoginViewController.swift in Sources */, + 79EBBE29221340D8006C4341 /* HomeViewController.swift in Sources */, + 79EBBE27221340D8006C4341 /* AppDelegate.swift in Sources */, + 7935D49C2253C0E80046F903 /* Review.swift in Sources */, + BF509C52223C78DA0064AF82 /* MenuItemDetailViewController.swift in Sources */, + BF1D4F2B221F20A9000B95D5 /* TabBarController.swift in Sources */, +<<<<<<< HEAD +======= + 796D57DE225278CD00D34142 /* ShoppingCartTableViewCell.swift in Sources */, + 79735C6F224FE0D600575723 /* FirebaseAPI.swift in Sources */, + 79388B622251533500B6B8A2 /* UserProfile.swift in Sources */, + BF202AFD222866B90040F010 /* FoodItemCollectionView.swift in Sources */, +>>>>>>> e52f18c2553988c046c489e0ecf20b0cf96fe655 + BF0A39052246682700651A6E /* CategoriesCollectionViewCell.swift in Sources */, + BF509C50223C1B740064AF82 /* ProfileViewController.swift in Sources */, + BF0A38E42244175800651A6E /* RatingsViewController.swift in Sources */, + BF1D4F31221F38DD000B95D5 /* MenuItemCollectionViewCell.swift in Sources */, + BF509C782240661F0064AF82 /* Extensions.swift in Sources */, + 79735C71224FE19F00575723 /* MenuCategory.swift in Sources */, + BF509C54223C79050064AF82 /* MenuItem.swift in Sources */, + BF0A38E02243FD6400651A6E /* OrderViewController.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 79EBBE2A221340D8006C4341 /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 79EBBE2B221340D8006C4341 /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 79EBBE2F221340DA006C4341 /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 79EBBE30221340DA006C4341 /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 79EBBE33221340DA006C4341 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 12.1; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 79EBBE34221340DA006C4341 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 12.1; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 79EBBE36221340DA006C4341 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7A136462236305D5C1B0116E /* Pods-FoodApp.debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = HRVS9455XM; + INFOPLIST_FILE = FoodApp/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.SparkDev.FoodApp; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 4.2; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 79EBBE37221340DA006C4341 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = D59F8127439E5E39BB747D7F /* Pods-FoodApp.release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = HRVS9455XM; + INFOPLIST_FILE = FoodApp/Info.plist; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.SparkDev.FoodApp; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 4.2; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 79EBBE1E221340D8006C4341 /* Build configuration list for PBXProject "FoodApp" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 79EBBE33221340DA006C4341 /* Debug */, + 79EBBE34221340DA006C4341 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 79EBBE35221340DA006C4341 /* Build configuration list for PBXNativeTarget "FoodApp" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 79EBBE36221340DA006C4341 /* Debug */, + 79EBBE37221340DA006C4341 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 79EBBE1B221340D8006C4341 /* Project object */; +} diff --git a/FoodApp/FoodApp.xcodeproj/project.xcworkspace/xcuserdata/czuria.xcuserdatad/UserInterfaceState.xcuserstate b/FoodApp/FoodApp.xcodeproj/project.xcworkspace/xcuserdata/czuria.xcuserdatad/UserInterfaceState.xcuserstate deleted file mode 100644 index 4e6fd06..0000000 Binary files a/FoodApp/FoodApp.xcodeproj/project.xcworkspace/xcuserdata/czuria.xcuserdatad/UserInterfaceState.xcuserstate and /dev/null differ diff --git a/FoodApp/FoodApp.xcodeproj/xcshareddata/xcschemes/FoodApp.xcscheme b/FoodApp/FoodApp.xcodeproj/xcshareddata/xcschemes/FoodApp.xcscheme new file mode 100644 index 0000000..da99f9f --- /dev/null +++ b/FoodApp/FoodApp.xcodeproj/xcshareddata/xcschemes/FoodApp.xcscheme @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/FoodApp/FoodApp.xcworkspace/contents.xcworkspacedata b/FoodApp/FoodApp.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..eb6e691 --- /dev/null +++ b/FoodApp/FoodApp.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/FoodApp/FoodApp.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/FoodApp/FoodApp.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/FoodApp/FoodApp.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/FoodApp/FoodApp.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/FoodApp/FoodApp.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings new file mode 100644 index 0000000..0c67376 --- /dev/null +++ b/FoodApp/FoodApp.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings @@ -0,0 +1,5 @@ + + + + + diff --git a/FoodApp/FoodApp/AppDelegate.swift b/FoodApp/FoodApp/AppDelegate.swift index 5d836f3..02924dc 100644 --- a/FoodApp/FoodApp/AppDelegate.swift +++ b/FoodApp/FoodApp/AppDelegate.swift @@ -7,6 +7,8 @@ // import UIKit +import Firebase +import IQKeyboardManagerSwift @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { @@ -15,7 +17,17 @@ class AppDelegate: UIResponder, UIApplicationDelegate { func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { - // Override point for customization after application launch. + + FirebaseApp.configure() + + window = UIWindow(frame: UIScreen.main.bounds) + window?.rootViewController = LoginViewController() + window?.makeKeyAndVisible() + + UITabBar.appearance().tintColor = .customOrange + + IQKeyboardManager.shared.enable = true + return true } diff --git a/FoodApp/FoodApp/AppDelegate.swift.orig b/FoodApp/FoodApp/AppDelegate.swift.orig new file mode 100644 index 0000000..5f2c82b --- /dev/null +++ b/FoodApp/FoodApp/AppDelegate.swift.orig @@ -0,0 +1,56 @@ +// +// AppDelegate.swift +// FoodApp +// +// Created by Cassandra Zuria on 2/12/19. +// Copyright © 2019 SparkDev. All rights reserved. +// + +import UIKit +import Firebase +import IQKeyboardManagerSwift + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + var window: UIWindow? + + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + + FirebaseApp.configure() + + window = UIWindow(frame: UIScreen.main.bounds) + window?.rootViewController = LoginViewController() + window?.makeKeyAndVisible() + + IQKeyboardManager.shared.enable = true + + return true + } + + func applicationWillResignActive(_ application: UIApplication) { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. + } + + func applicationDidEnterBackground(_ application: UIApplication) { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. + } + + func applicationWillEnterForeground(_ application: UIApplication) { + // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. + } + + func applicationDidBecomeActive(_ application: UIApplication) { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. + } + + func applicationWillTerminate(_ application: UIApplication) { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. + } + + +} + diff --git a/FoodApp/FoodApp/AppDelegate_BACKUP_1928.swift b/FoodApp/FoodApp/AppDelegate_BACKUP_1928.swift new file mode 100644 index 0000000..ec6b896 --- /dev/null +++ b/FoodApp/FoodApp/AppDelegate_BACKUP_1928.swift @@ -0,0 +1,61 @@ +// +// AppDelegate.swift +// FoodApp +// +// Created by Cassandra Zuria on 2/12/19. +// Copyright © 2019 SparkDev. All rights reserved. +// + +import UIKit +import Firebase +import IQKeyboardManagerSwift + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + var window: UIWindow? + + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + + FirebaseApp.configure() + + window = UIWindow(frame: UIScreen.main.bounds) +<<<<<<< HEAD + window?.rootViewController = LoginViewController() +======= + window?.rootViewController = TabBarController() +// window?.rootViewController = ShoppingCartViewController() +>>>>>>> e52f18c2553988c046c489e0ecf20b0cf96fe655 + window?.makeKeyAndVisible() + + IQKeyboardManager.shared.enable = true + + return true + } + + func applicationWillResignActive(_ application: UIApplication) { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. + } + + func applicationDidEnterBackground(_ application: UIApplication) { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. + } + + func applicationWillEnterForeground(_ application: UIApplication) { + // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. + } + + func applicationDidBecomeActive(_ application: UIApplication) { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. + } + + func applicationWillTerminate(_ application: UIApplication) { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. + } + + +} + diff --git a/FoodApp/FoodApp/AppDelegate_BACKUP_2088.swift b/FoodApp/FoodApp/AppDelegate_BACKUP_2088.swift new file mode 100644 index 0000000..5f2c82b --- /dev/null +++ b/FoodApp/FoodApp/AppDelegate_BACKUP_2088.swift @@ -0,0 +1,56 @@ +// +// AppDelegate.swift +// FoodApp +// +// Created by Cassandra Zuria on 2/12/19. +// Copyright © 2019 SparkDev. All rights reserved. +// + +import UIKit +import Firebase +import IQKeyboardManagerSwift + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + var window: UIWindow? + + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + + FirebaseApp.configure() + + window = UIWindow(frame: UIScreen.main.bounds) + window?.rootViewController = LoginViewController() + window?.makeKeyAndVisible() + + IQKeyboardManager.shared.enable = true + + return true + } + + func applicationWillResignActive(_ application: UIApplication) { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. + } + + func applicationDidEnterBackground(_ application: UIApplication) { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. + } + + func applicationWillEnterForeground(_ application: UIApplication) { + // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. + } + + func applicationDidBecomeActive(_ application: UIApplication) { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. + } + + func applicationWillTerminate(_ application: UIApplication) { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. + } + + +} + diff --git a/FoodApp/FoodApp/AppDelegate_BACKUP_2182.swift b/FoodApp/FoodApp/AppDelegate_BACKUP_2182.swift new file mode 100644 index 0000000..5f2c82b --- /dev/null +++ b/FoodApp/FoodApp/AppDelegate_BACKUP_2182.swift @@ -0,0 +1,56 @@ +// +// AppDelegate.swift +// FoodApp +// +// Created by Cassandra Zuria on 2/12/19. +// Copyright © 2019 SparkDev. All rights reserved. +// + +import UIKit +import Firebase +import IQKeyboardManagerSwift + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + var window: UIWindow? + + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + + FirebaseApp.configure() + + window = UIWindow(frame: UIScreen.main.bounds) + window?.rootViewController = LoginViewController() + window?.makeKeyAndVisible() + + IQKeyboardManager.shared.enable = true + + return true + } + + func applicationWillResignActive(_ application: UIApplication) { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. + } + + func applicationDidEnterBackground(_ application: UIApplication) { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. + } + + func applicationWillEnterForeground(_ application: UIApplication) { + // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. + } + + func applicationDidBecomeActive(_ application: UIApplication) { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. + } + + func applicationWillTerminate(_ application: UIApplication) { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. + } + + +} + diff --git a/FoodApp/FoodApp/AppDelegate_BASE_1928.swift b/FoodApp/FoodApp/AppDelegate_BASE_1928.swift new file mode 100644 index 0000000..b888a45 --- /dev/null +++ b/FoodApp/FoodApp/AppDelegate_BASE_1928.swift @@ -0,0 +1,52 @@ +// +// AppDelegate.swift +// FoodApp +// +// Created by Cassandra Zuria on 2/12/19. +// Copyright © 2019 SparkDev. All rights reserved. +// + +import UIKit +import Firebase + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + var window: UIWindow? + + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + FirebaseApp.configure() + + window = UIWindow(frame: UIScreen.main.bounds) + window?.rootViewController = TabBarController() + window?.makeKeyAndVisible() + + return true + } + + func applicationWillResignActive(_ application: UIApplication) { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. + } + + func applicationDidEnterBackground(_ application: UIApplication) { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. + } + + func applicationWillEnterForeground(_ application: UIApplication) { + // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. + } + + func applicationDidBecomeActive(_ application: UIApplication) { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. + } + + func applicationWillTerminate(_ application: UIApplication) { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. + } + + +} + diff --git a/FoodApp/FoodApp/AppDelegate_BASE_2088.swift b/FoodApp/FoodApp/AppDelegate_BASE_2088.swift new file mode 100644 index 0000000..b888a45 --- /dev/null +++ b/FoodApp/FoodApp/AppDelegate_BASE_2088.swift @@ -0,0 +1,52 @@ +// +// AppDelegate.swift +// FoodApp +// +// Created by Cassandra Zuria on 2/12/19. +// Copyright © 2019 SparkDev. All rights reserved. +// + +import UIKit +import Firebase + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + var window: UIWindow? + + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + FirebaseApp.configure() + + window = UIWindow(frame: UIScreen.main.bounds) + window?.rootViewController = TabBarController() + window?.makeKeyAndVisible() + + return true + } + + func applicationWillResignActive(_ application: UIApplication) { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. + } + + func applicationDidEnterBackground(_ application: UIApplication) { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. + } + + func applicationWillEnterForeground(_ application: UIApplication) { + // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. + } + + func applicationDidBecomeActive(_ application: UIApplication) { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. + } + + func applicationWillTerminate(_ application: UIApplication) { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. + } + + +} + diff --git a/FoodApp/FoodApp/AppDelegate_BASE_2182.swift b/FoodApp/FoodApp/AppDelegate_BASE_2182.swift new file mode 100644 index 0000000..b888a45 --- /dev/null +++ b/FoodApp/FoodApp/AppDelegate_BASE_2182.swift @@ -0,0 +1,52 @@ +// +// AppDelegate.swift +// FoodApp +// +// Created by Cassandra Zuria on 2/12/19. +// Copyright © 2019 SparkDev. All rights reserved. +// + +import UIKit +import Firebase + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + var window: UIWindow? + + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + FirebaseApp.configure() + + window = UIWindow(frame: UIScreen.main.bounds) + window?.rootViewController = TabBarController() + window?.makeKeyAndVisible() + + return true + } + + func applicationWillResignActive(_ application: UIApplication) { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. + } + + func applicationDidEnterBackground(_ application: UIApplication) { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. + } + + func applicationWillEnterForeground(_ application: UIApplication) { + // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. + } + + func applicationDidBecomeActive(_ application: UIApplication) { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. + } + + func applicationWillTerminate(_ application: UIApplication) { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. + } + + +} + diff --git a/FoodApp/FoodApp/AppDelegate_LOCAL_1928.swift b/FoodApp/FoodApp/AppDelegate_LOCAL_1928.swift new file mode 100644 index 0000000..aa2b650 --- /dev/null +++ b/FoodApp/FoodApp/AppDelegate_LOCAL_1928.swift @@ -0,0 +1,55 @@ +// +// AppDelegate.swift +// FoodApp +// +// Created by Cassandra Zuria on 2/12/19. +// Copyright © 2019 SparkDev. All rights reserved. +// + +import UIKit +import Firebase +import IQKeyboardManagerSwift + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + var window: UIWindow? + + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + FirebaseApp.configure() + + window = UIWindow(frame: UIScreen.main.bounds) + window?.rootViewController = LoginViewController() + window?.makeKeyAndVisible() + + IQKeyboardManager.shared.enable = true + + return true + } + + func applicationWillResignActive(_ application: UIApplication) { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. + } + + func applicationDidEnterBackground(_ application: UIApplication) { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. + } + + func applicationWillEnterForeground(_ application: UIApplication) { + // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. + } + + func applicationDidBecomeActive(_ application: UIApplication) { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. + } + + func applicationWillTerminate(_ application: UIApplication) { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. + } + + +} + diff --git a/FoodApp/FoodApp/AppDelegate_LOCAL_2088.swift b/FoodApp/FoodApp/AppDelegate_LOCAL_2088.swift new file mode 100644 index 0000000..aa2b650 --- /dev/null +++ b/FoodApp/FoodApp/AppDelegate_LOCAL_2088.swift @@ -0,0 +1,55 @@ +// +// AppDelegate.swift +// FoodApp +// +// Created by Cassandra Zuria on 2/12/19. +// Copyright © 2019 SparkDev. All rights reserved. +// + +import UIKit +import Firebase +import IQKeyboardManagerSwift + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + var window: UIWindow? + + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + FirebaseApp.configure() + + window = UIWindow(frame: UIScreen.main.bounds) + window?.rootViewController = LoginViewController() + window?.makeKeyAndVisible() + + IQKeyboardManager.shared.enable = true + + return true + } + + func applicationWillResignActive(_ application: UIApplication) { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. + } + + func applicationDidEnterBackground(_ application: UIApplication) { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. + } + + func applicationWillEnterForeground(_ application: UIApplication) { + // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. + } + + func applicationDidBecomeActive(_ application: UIApplication) { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. + } + + func applicationWillTerminate(_ application: UIApplication) { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. + } + + +} + diff --git a/FoodApp/FoodApp/AppDelegate_LOCAL_2182.swift b/FoodApp/FoodApp/AppDelegate_LOCAL_2182.swift new file mode 100644 index 0000000..aa2b650 --- /dev/null +++ b/FoodApp/FoodApp/AppDelegate_LOCAL_2182.swift @@ -0,0 +1,55 @@ +// +// AppDelegate.swift +// FoodApp +// +// Created by Cassandra Zuria on 2/12/19. +// Copyright © 2019 SparkDev. All rights reserved. +// + +import UIKit +import Firebase +import IQKeyboardManagerSwift + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + var window: UIWindow? + + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + FirebaseApp.configure() + + window = UIWindow(frame: UIScreen.main.bounds) + window?.rootViewController = LoginViewController() + window?.makeKeyAndVisible() + + IQKeyboardManager.shared.enable = true + + return true + } + + func applicationWillResignActive(_ application: UIApplication) { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. + } + + func applicationDidEnterBackground(_ application: UIApplication) { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. + } + + func applicationWillEnterForeground(_ application: UIApplication) { + // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. + } + + func applicationDidBecomeActive(_ application: UIApplication) { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. + } + + func applicationWillTerminate(_ application: UIApplication) { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. + } + + +} + diff --git a/FoodApp/FoodApp/AppDelegate_REMOTE_1928.swift b/FoodApp/FoodApp/AppDelegate_REMOTE_1928.swift new file mode 100644 index 0000000..ef2bb84 --- /dev/null +++ b/FoodApp/FoodApp/AppDelegate_REMOTE_1928.swift @@ -0,0 +1,54 @@ +// +// AppDelegate.swift +// FoodApp +// +// Created by Cassandra Zuria on 2/12/19. +// Copyright © 2019 SparkDev. All rights reserved. +// + +import UIKit +import Firebase + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + var window: UIWindow? + + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + + FirebaseApp.configure() + + window = UIWindow(frame: UIScreen.main.bounds) + window?.rootViewController = TabBarController() +// window?.rootViewController = ShoppingCartViewController() + window?.makeKeyAndVisible() + + return true + } + + func applicationWillResignActive(_ application: UIApplication) { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. + } + + func applicationDidEnterBackground(_ application: UIApplication) { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. + } + + func applicationWillEnterForeground(_ application: UIApplication) { + // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. + } + + func applicationDidBecomeActive(_ application: UIApplication) { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. + } + + func applicationWillTerminate(_ application: UIApplication) { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. + } + + +} + diff --git a/FoodApp/FoodApp/AppDelegate_REMOTE_2088.swift b/FoodApp/FoodApp/AppDelegate_REMOTE_2088.swift new file mode 100644 index 0000000..ef2bb84 --- /dev/null +++ b/FoodApp/FoodApp/AppDelegate_REMOTE_2088.swift @@ -0,0 +1,54 @@ +// +// AppDelegate.swift +// FoodApp +// +// Created by Cassandra Zuria on 2/12/19. +// Copyright © 2019 SparkDev. All rights reserved. +// + +import UIKit +import Firebase + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + var window: UIWindow? + + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + + FirebaseApp.configure() + + window = UIWindow(frame: UIScreen.main.bounds) + window?.rootViewController = TabBarController() +// window?.rootViewController = ShoppingCartViewController() + window?.makeKeyAndVisible() + + return true + } + + func applicationWillResignActive(_ application: UIApplication) { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. + } + + func applicationDidEnterBackground(_ application: UIApplication) { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. + } + + func applicationWillEnterForeground(_ application: UIApplication) { + // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. + } + + func applicationDidBecomeActive(_ application: UIApplication) { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. + } + + func applicationWillTerminate(_ application: UIApplication) { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. + } + + +} + diff --git a/FoodApp/FoodApp/AppDelegate_REMOTE_2182.swift b/FoodApp/FoodApp/AppDelegate_REMOTE_2182.swift new file mode 100644 index 0000000..ef2bb84 --- /dev/null +++ b/FoodApp/FoodApp/AppDelegate_REMOTE_2182.swift @@ -0,0 +1,54 @@ +// +// AppDelegate.swift +// FoodApp +// +// Created by Cassandra Zuria on 2/12/19. +// Copyright © 2019 SparkDev. All rights reserved. +// + +import UIKit +import Firebase + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + var window: UIWindow? + + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + + FirebaseApp.configure() + + window = UIWindow(frame: UIScreen.main.bounds) + window?.rootViewController = TabBarController() +// window?.rootViewController = ShoppingCartViewController() + window?.makeKeyAndVisible() + + return true + } + + func applicationWillResignActive(_ application: UIApplication) { + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. + // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. + } + + func applicationDidEnterBackground(_ application: UIApplication) { + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. + } + + func applicationWillEnterForeground(_ application: UIApplication) { + // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. + } + + func applicationDidBecomeActive(_ application: UIApplication) { + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. + } + + func applicationWillTerminate(_ application: UIApplication) { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. + } + + +} + diff --git a/FoodApp/FoodApp/Assets.xcassets/AppIcon.appiconset/Contents.json b/FoodApp/FoodApp/Assets.xcassets/AppIcon.appiconset/Contents.json index d8db8d6..1880b64 100644 --- a/FoodApp/FoodApp/Assets.xcassets/AppIcon.appiconset/Contents.json +++ b/FoodApp/FoodApp/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -1,93 +1,111 @@ { "images" : [ { - "idiom" : "iphone", "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-42.png", "scale" : "2x" }, { - "idiom" : "iphone", "size" : "20x20", + "idiom" : "iphone", + "filename" : "Icon-60.png", "scale" : "3x" }, { - "idiom" : "iphone", "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-59.png", "scale" : "2x" }, { - "idiom" : "iphone", "size" : "29x29", + "idiom" : "iphone", + "filename" : "Icon-87.png", "scale" : "3x" }, { - "idiom" : "iphone", "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-81.png", "scale" : "2x" }, { - "idiom" : "iphone", "size" : "40x40", + "idiom" : "iphone", + "filename" : "Icon-120.png", "scale" : "3x" }, { - "idiom" : "iphone", "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-121.png", "scale" : "2x" }, { - "idiom" : "iphone", "size" : "60x60", + "idiom" : "iphone", + "filename" : "Icon-180.png", "scale" : "3x" }, { - "idiom" : "ipad", "size" : "20x20", + "idiom" : "ipad", + "filename" : "Icon-20.png", "scale" : "1x" }, { - "idiom" : "ipad", "size" : "20x20", + "idiom" : "ipad", + "filename" : "Icon-41.png", "scale" : "2x" }, { - "idiom" : "ipad", "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-29.png", "scale" : "1x" }, { - "idiom" : "ipad", "size" : "29x29", + "idiom" : "ipad", + "filename" : "Icon-58.png", "scale" : "2x" }, { - "idiom" : "ipad", "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-40.png", "scale" : "1x" }, { - "idiom" : "ipad", "size" : "40x40", + "idiom" : "ipad", + "filename" : "Icon-80.png", "scale" : "2x" }, { - "idiom" : "ipad", "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-76.png", "scale" : "1x" }, { - "idiom" : "ipad", "size" : "76x76", + "idiom" : "ipad", + "filename" : "Icon-152.png", "scale" : "2x" }, { - "idiom" : "ipad", "size" : "83.5x83.5", + "idiom" : "ipad", + "filename" : "Icon-167.png", "scale" : "2x" }, { - "idiom" : "ios-marketing", "size" : "1024x1024", + "idiom" : "ios-marketing", + "filename" : "Icon-1024.png", "scale" : "1x" } ], diff --git a/FoodApp/FoodApp/Assets.xcassets/AppIcon.appiconset/Icon-1024.png b/FoodApp/FoodApp/Assets.xcassets/AppIcon.appiconset/Icon-1024.png new file mode 100644 index 0000000..043038d Binary files /dev/null and b/FoodApp/FoodApp/Assets.xcassets/AppIcon.appiconset/Icon-1024.png differ diff --git a/FoodApp/FoodApp/Assets.xcassets/AppIcon.appiconset/Icon-120.png b/FoodApp/FoodApp/Assets.xcassets/AppIcon.appiconset/Icon-120.png new file mode 100644 index 0000000..606ac2a Binary files /dev/null and b/FoodApp/FoodApp/Assets.xcassets/AppIcon.appiconset/Icon-120.png differ diff --git a/FoodApp/FoodApp/Assets.xcassets/AppIcon.appiconset/Icon-121.png b/FoodApp/FoodApp/Assets.xcassets/AppIcon.appiconset/Icon-121.png new file mode 100644 index 0000000..606ac2a Binary files /dev/null and b/FoodApp/FoodApp/Assets.xcassets/AppIcon.appiconset/Icon-121.png differ diff --git a/FoodApp/FoodApp/Assets.xcassets/AppIcon.appiconset/Icon-152.png b/FoodApp/FoodApp/Assets.xcassets/AppIcon.appiconset/Icon-152.png new file mode 100644 index 0000000..2d08eaf Binary files /dev/null and b/FoodApp/FoodApp/Assets.xcassets/AppIcon.appiconset/Icon-152.png differ diff --git a/FoodApp/FoodApp/Assets.xcassets/AppIcon.appiconset/Icon-167.png b/FoodApp/FoodApp/Assets.xcassets/AppIcon.appiconset/Icon-167.png new file mode 100644 index 0000000..13b7e9d Binary files /dev/null and b/FoodApp/FoodApp/Assets.xcassets/AppIcon.appiconset/Icon-167.png differ diff --git a/FoodApp/FoodApp/Assets.xcassets/AppIcon.appiconset/Icon-180.png b/FoodApp/FoodApp/Assets.xcassets/AppIcon.appiconset/Icon-180.png new file mode 100644 index 0000000..b54244d Binary files /dev/null and b/FoodApp/FoodApp/Assets.xcassets/AppIcon.appiconset/Icon-180.png differ diff --git a/FoodApp/FoodApp/Assets.xcassets/AppIcon.appiconset/Icon-20.png b/FoodApp/FoodApp/Assets.xcassets/AppIcon.appiconset/Icon-20.png new file mode 100644 index 0000000..4f1cab4 Binary files /dev/null and b/FoodApp/FoodApp/Assets.xcassets/AppIcon.appiconset/Icon-20.png differ diff --git a/FoodApp/FoodApp/Assets.xcassets/AppIcon.appiconset/Icon-29.png b/FoodApp/FoodApp/Assets.xcassets/AppIcon.appiconset/Icon-29.png new file mode 100644 index 0000000..ec90040 Binary files /dev/null and b/FoodApp/FoodApp/Assets.xcassets/AppIcon.appiconset/Icon-29.png differ diff --git a/FoodApp/FoodApp/Assets.xcassets/AppIcon.appiconset/Icon-40.png b/FoodApp/FoodApp/Assets.xcassets/AppIcon.appiconset/Icon-40.png new file mode 100644 index 0000000..f8e5cd8 Binary files /dev/null and b/FoodApp/FoodApp/Assets.xcassets/AppIcon.appiconset/Icon-40.png differ diff --git a/FoodApp/FoodApp/Assets.xcassets/AppIcon.appiconset/Icon-41.png b/FoodApp/FoodApp/Assets.xcassets/AppIcon.appiconset/Icon-41.png new file mode 100644 index 0000000..f8e5cd8 Binary files /dev/null and b/FoodApp/FoodApp/Assets.xcassets/AppIcon.appiconset/Icon-41.png differ diff --git a/FoodApp/FoodApp/Assets.xcassets/AppIcon.appiconset/Icon-42.png b/FoodApp/FoodApp/Assets.xcassets/AppIcon.appiconset/Icon-42.png new file mode 100644 index 0000000..f8e5cd8 Binary files /dev/null and b/FoodApp/FoodApp/Assets.xcassets/AppIcon.appiconset/Icon-42.png differ diff --git a/FoodApp/FoodApp/Assets.xcassets/AppIcon.appiconset/Icon-58.png b/FoodApp/FoodApp/Assets.xcassets/AppIcon.appiconset/Icon-58.png new file mode 100644 index 0000000..33ede5a Binary files /dev/null and b/FoodApp/FoodApp/Assets.xcassets/AppIcon.appiconset/Icon-58.png differ diff --git a/FoodApp/FoodApp/Assets.xcassets/AppIcon.appiconset/Icon-59.png b/FoodApp/FoodApp/Assets.xcassets/AppIcon.appiconset/Icon-59.png new file mode 100644 index 0000000..33ede5a Binary files /dev/null and b/FoodApp/FoodApp/Assets.xcassets/AppIcon.appiconset/Icon-59.png differ diff --git a/FoodApp/FoodApp/Assets.xcassets/AppIcon.appiconset/Icon-60.png b/FoodApp/FoodApp/Assets.xcassets/AppIcon.appiconset/Icon-60.png new file mode 100644 index 0000000..12a7c34 Binary files /dev/null and b/FoodApp/FoodApp/Assets.xcassets/AppIcon.appiconset/Icon-60.png differ diff --git a/FoodApp/FoodApp/Assets.xcassets/AppIcon.appiconset/Icon-76.png b/FoodApp/FoodApp/Assets.xcassets/AppIcon.appiconset/Icon-76.png new file mode 100644 index 0000000..0c0a189 Binary files /dev/null and b/FoodApp/FoodApp/Assets.xcassets/AppIcon.appiconset/Icon-76.png differ diff --git a/FoodApp/FoodApp/Assets.xcassets/AppIcon.appiconset/Icon-80.png b/FoodApp/FoodApp/Assets.xcassets/AppIcon.appiconset/Icon-80.png new file mode 100644 index 0000000..e3fc245 Binary files /dev/null and b/FoodApp/FoodApp/Assets.xcassets/AppIcon.appiconset/Icon-80.png differ diff --git a/FoodApp/FoodApp/Assets.xcassets/AppIcon.appiconset/Icon-81.png b/FoodApp/FoodApp/Assets.xcassets/AppIcon.appiconset/Icon-81.png new file mode 100644 index 0000000..e3fc245 Binary files /dev/null and b/FoodApp/FoodApp/Assets.xcassets/AppIcon.appiconset/Icon-81.png differ diff --git a/FoodApp/FoodApp/Assets.xcassets/AppIcon.appiconset/Icon-87.png b/FoodApp/FoodApp/Assets.xcassets/AppIcon.appiconset/Icon-87.png new file mode 100644 index 0000000..9a3df53 Binary files /dev/null and b/FoodApp/FoodApp/Assets.xcassets/AppIcon.appiconset/Icon-87.png differ diff --git a/FoodApp/FoodApp/Assets.xcassets/cart.imageset/Contents.json b/FoodApp/FoodApp/Assets.xcassets/cart.imageset/Contents.json new file mode 100644 index 0000000..fa54af7 --- /dev/null +++ b/FoodApp/FoodApp/Assets.xcassets/cart.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "shopping-list.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/FoodApp/FoodApp/Assets.xcassets/cart.imageset/shopping-list.png b/FoodApp/FoodApp/Assets.xcassets/cart.imageset/shopping-list.png new file mode 100644 index 0000000..2b5c7e8 Binary files /dev/null and b/FoodApp/FoodApp/Assets.xcassets/cart.imageset/shopping-list.png differ diff --git a/FoodApp/FoodApp/Assets.xcassets/home.imageset/Contents.json b/FoodApp/FoodApp/Assets.xcassets/home.imageset/Contents.json new file mode 100644 index 0000000..08ef703 --- /dev/null +++ b/FoodApp/FoodApp/Assets.xcassets/home.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "home.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/FoodApp/FoodApp/Assets.xcassets/home.imageset/home.png b/FoodApp/FoodApp/Assets.xcassets/home.imageset/home.png new file mode 100644 index 0000000..0b6ff63 Binary files /dev/null and b/FoodApp/FoodApp/Assets.xcassets/home.imageset/home.png differ diff --git a/FoodApp/FoodApp/Assets.xcassets/logo.imageset/Contents.json b/FoodApp/FoodApp/Assets.xcassets/logo.imageset/Contents.json new file mode 100644 index 0000000..8463aca --- /dev/null +++ b/FoodApp/FoodApp/Assets.xcassets/logo.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "logo.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/FoodApp/FoodApp/Assets.xcassets/logo.imageset/logo.png b/FoodApp/FoodApp/Assets.xcassets/logo.imageset/logo.png new file mode 100644 index 0000000..93b5ebf Binary files /dev/null and b/FoodApp/FoodApp/Assets.xcassets/logo.imageset/logo.png differ diff --git a/FoodApp/FoodApp/Assets.xcassets/pizzapic.imageset/Contents.json b/FoodApp/FoodApp/Assets.xcassets/pizzapic.imageset/Contents.json new file mode 100644 index 0000000..d77cd08 --- /dev/null +++ b/FoodApp/FoodApp/Assets.xcassets/pizzapic.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "pizzapic.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/FoodApp/FoodApp/Assets.xcassets/pizzapic.imageset/pizzapic.png b/FoodApp/FoodApp/Assets.xcassets/pizzapic.imageset/pizzapic.png new file mode 100644 index 0000000..921f72b Binary files /dev/null and b/FoodApp/FoodApp/Assets.xcassets/pizzapic.imageset/pizzapic.png differ diff --git a/FoodApp/FoodApp/Assets.xcassets/user.imageset/Contents.json b/FoodApp/FoodApp/Assets.xcassets/user.imageset/Contents.json new file mode 100644 index 0000000..f5dc3cb --- /dev/null +++ b/FoodApp/FoodApp/Assets.xcassets/user.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "user.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/FoodApp/FoodApp/Assets.xcassets/user.imageset/user.png b/FoodApp/FoodApp/Assets.xcassets/user.imageset/user.png new file mode 100644 index 0000000..bb5f157 Binary files /dev/null and b/FoodApp/FoodApp/Assets.xcassets/user.imageset/user.png differ diff --git a/FoodApp/FoodApp/Assets.xcassets/woman.imageset/Contents.json b/FoodApp/FoodApp/Assets.xcassets/woman.imageset/Contents.json new file mode 100644 index 0000000..92c3d30 --- /dev/null +++ b/FoodApp/FoodApp/Assets.xcassets/woman.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "Screen Shot 2019-03-30 at 6.20.59 PM.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/FoodApp/FoodApp/Assets.xcassets/woman.imageset/Screen Shot 2019-03-30 at 6.20.59 PM.png b/FoodApp/FoodApp/Assets.xcassets/woman.imageset/Screen Shot 2019-03-30 at 6.20.59 PM.png new file mode 100644 index 0000000..bdbd53f Binary files /dev/null and b/FoodApp/FoodApp/Assets.xcassets/woman.imageset/Screen Shot 2019-03-30 at 6.20.59 PM.png differ diff --git a/FoodApp/FoodApp/Controllers/LoginViewController.swift b/FoodApp/FoodApp/Controllers/LoginViewController.swift new file mode 100644 index 0000000..2c5af06 --- /dev/null +++ b/FoodApp/FoodApp/Controllers/LoginViewController.swift @@ -0,0 +1,168 @@ +// +// LoginViewController.swift +// FoodApp +// +// Created by gnoa001 on 3/31/19. +// Copyright © 2019 SparkDev. All rights reserved. +// + +import UIKit +import SkyFloatingLabelTextField + +class LoginViewController: UIViewController { + + // MARK: UI Elements + private lazy var chowDown: UILabel = { + let label = UILabel() + label.adjustsFontForContentSizeCategory = true + label.font = UIFont.preferredFont(forTextStyle: .largeTitle) + label.textColor = .darkGray + label.text = "ChowDown" + label.textAlignment = .center + return label + }() + + private lazy var imageView: UIImageView = { + let imageView = UIImageView() + imageView.image = #imageLiteral(resourceName: "logo") + return imageView + }() + + private lazy var emailTextField: SkyFloatingLabelTextField = { + let sky = SkyFloatingLabelTextField() + sky.textColor = UIColor.darkGray + sky.placeholder = "Email" + sky.placeholderColor = .lightGray + sky.titleColor = .customOrange + sky.lineColor = .darkGray + sky.selectedLineColor = .customOrange + sky.selectedTitleColor = .customOrange + return sky + }() + + private lazy var passwordTextField: SkyFloatingLabelTextField = { + let sky = SkyFloatingLabelTextField() + sky.isSecureTextEntry = true + sky.textColor = UIColor.darkGray + sky.placeholder = "Password" + sky.placeholderColor = .lightGray + sky.titleColor = .customOrange + sky.lineColor = .darkGray + sky.selectedLineColor = .customOrange + sky.selectedTitleColor = .customOrange + return sky + }() + + private lazy var loginButton: UIButton = { + let button = UIButton() + button.backgroundColor = .customOrange + button.setTitleColor(.white, for: .normal) + button.layer.cornerRadius = 25 + button.setTitle("Login", for: .normal) + button.addTarget(self, action: #selector(loginButtonTapped(_:)), for: .touchUpInside) + return button + }() + + private lazy var stackView: UIStackView = { + let stackView = UIStackView(arrangedSubviews: [chowDown, imageView, emailTextField, passwordTextField, loginButton]) + stackView.translatesAutoresizingMaskIntoConstraints = false + stackView.axis = .vertical + stackView.alignment = .center + stackView.distribution = .fill + stackView.spacing = 16 + stackView.setCustomSpacing(64, after: passwordTextField) + return stackView + }() + + // MARK: Lifecycle + override func viewDidLoad() { + super.viewDidLoad() + + emailTextField.delegate = self + passwordTextField.delegate = self + + setupUI() + } + + // MARK: Setup + func setupUI() { + view.backgroundColor = .customGray + // addGradientLayer() + view.addSubview(stackView) + + let safeArea = view.safeAreaLayoutGuide + view.addConstraints([ + imageView.heightAnchor.constraint(equalToConstant: 100), + imageView.widthAnchor.constraint(equalToConstant: 100), + emailTextField.heightAnchor.constraint(equalToConstant: 55), + emailTextField.widthAnchor.constraint(equalToConstant: 230), + passwordTextField.heightAnchor.constraint(equalToConstant: 55), + passwordTextField.widthAnchor.constraint(equalToConstant: 230), + loginButton.heightAnchor.constraint(equalToConstant: 50), + loginButton.widthAnchor.constraint(equalToConstant: 140), + stackView.centerXAnchor.constraint(equalTo: safeArea.centerXAnchor), + stackView.topAnchor.constraint(equalTo: safeArea.topAnchor, constant: 100) + ]) + } + + + // MARK: Actions + @objc func loginButtonTapped(_ sender: UIButton) { + let userEmail = emailTextField.text; + let userPassword = passwordTextField.text; + + + let alert = UIAlertController(title: "Invalid login", message: "Please make sure you enter both your email and your password", preferredStyle: .alert) + + alert.addAction(UIAlertAction(title: "Continue", style: .default, handler: nil)) + + if((userEmail?.isEmpty)! || (userPassword?.isEmpty)!){ + present(alert, animated: true, completion: nil) + return + } + + if validate(field: emailTextField) == nil { + let alert = UIAlertController(title: "Invalid email.", message: "Please enter valid email", preferredStyle: .alert) + + alert.addAction(UIAlertAction(title: "Continue", style: .default, handler: nil)) + + present(alert, animated: true, completion: nil) + return + } else { + + FirebaseAPI().loginUser(email: userEmail!, password: userPassword!) { (error, user) in + + let tabBarController = TabBarController() + self.present(tabBarController, animated: true) + } + } + } + + func validate(field: UITextField) -> String?{ + guard let trimmedText = emailTextField.text?.trimmingCharacters(in: .whitespacesAndNewlines) else { + return nil + } + + guard let dataDetector = try? NSDataDetector(types: NSTextCheckingResult.CheckingType.link.rawValue) else{ + return nil + } + + let range = NSMakeRange(0, NSString(string: trimmedText).length) + let allMatches = dataDetector.matches(in: trimmedText, options: [], range: range) + + if allMatches.count == 1, + allMatches.first?.url?.absoluteString.contains("mailto:") == true + { + return trimmedText + } + + return nil + } +} + +extension LoginViewController: UITextFieldDelegate { + func textFieldShouldReturn(_ textField: UITextField) -> Bool { + textField.resignFirstResponder() + return true + } +} diff --git a/FoodApp/FoodApp/Controllers/MenuItemDetailViewController.swift b/FoodApp/FoodApp/Controllers/MenuItemDetailViewController.swift new file mode 100644 index 0000000..5f8bf68 --- /dev/null +++ b/FoodApp/FoodApp/Controllers/MenuItemDetailViewController.swift @@ -0,0 +1,124 @@ +// +// MenuItemDetailViewController.swift +// FoodApp +// +// Created by gnoa001 on 3/15/19. +// Copyright © 2019 SparkDev. All rights reserved. +// + +import UIKit + +protocol Pages {} + +class MenuItemDetailViewController: UIViewController { + + //MARK: Variables + var pages = [Pages]() + +// var menuItem = MenuItem() + + var selectedSegmentIndex: Int { + return segmentedControl.selectedSegmentIndex + } + + var pagingForward: Bool { + return selectedViewController < selectedSegmentIndex + } + + var selectedViewController = 0 + + // MARK: UI Elements + lazy var imageView: UIImageView = { + let imageView = UIImageView() + imageView.image = #imageLiteral(resourceName: "pizzapic") + imageView.setContentHuggingPriority(.defaultLow, for: .vertical) + imageView.setContentCompressionResistancePriority(.defaultHigh, for: .vertical) + imageView.contentMode = .scaleAspectFit // might need to comment out + return imageView + }() + + lazy var titleLabel: UILabel = { + let label = UILabel() + label.text = "Pizza" + return label + }() + + lazy var ratingsLabel: UILabel = { + let label = UILabel() + label.text = "⭐️ 4.5(12)" + return label + }() + + lazy var segmentedControl: UISegmentedControl = { + let segmentedControl = UISegmentedControl(items: ["Order", "Description", "Ratings"]) + segmentedControl.addTarget(self, action: #selector(valueChanged(_:)), for: .valueChanged) + segmentedControl.selectedSegmentIndex = 0 + return segmentedControl + }() + + lazy var stackView: UIStackView = { + let stackView = UIStackView(arrangedSubviews: [imageView, titleLabel, ratingsLabel, segmentedControl]) + stackView.translatesAutoresizingMaskIntoConstraints = false + stackView.axis = .vertical + stackView.alignment = .center + stackView.distribution = .equalCentering + stackView.spacing = 8 + return stackView + }() + + // MARK: Controllers + private lazy var pageViewController: UIPageViewController = { + let pageViewController = UIPageViewController(transitionStyle: .scroll, + navigationOrientation: .horizontal, + options: nil) + pageViewController.view.translatesAutoresizingMaskIntoConstraints = false + return pageViewController + }() + + // MARK: Lifecycle + override func viewDidLoad() { + super.viewDidLoad() + + setupUI() + setPages() + + pageViewController.setViewControllers([pages[selectedSegmentIndex] as! UIViewController], direction: .forward, animated: true) + } + + // MARK: Setup + func setupUI() { + view.backgroundColor = .white + + view.addSubview(stackView) + view.addSubview(pageViewController.view) + addChild(pageViewController) + pageViewController.didMove(toParent: self) + + view.addConstraints([ + stackView.topAnchor.constraint(equalTo: view.topAnchor), + stackView.leadingAnchor.constraint(equalTo: view.leadingAnchor), + stackView.trailingAnchor.constraint(equalTo: view.trailingAnchor), + stackView.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.55), + pageViewController.view.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: -2), + pageViewController.view.topAnchor.constraint(equalTo: stackView.bottomAnchor, constant: 8), + pageViewController.view.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: 2), + pageViewController.view.bottomAnchor.constraint(equalTo: view.bottomAnchor) + ]) + } + + func setPages() { +// pages.append(OrderViewController(item: MenuItem())) + pages.append(DescriptionViewController()) + pages.append(RatingsViewController()) + } + + // MARK: Actions + @objc func valueChanged(_ sender: UISegmentedControl) { + if pagingForward { + pageViewController.setViewControllers([pages[selectedSegmentIndex] as! UIViewController], direction: UIPageViewController.NavigationDirection.forward, animated: true) + } else { + pageViewController.setViewControllers([pages[selectedSegmentIndex] as! UIViewController], direction: UIPageViewController.NavigationDirection.reverse, animated: true) + } + selectedViewController = selectedSegmentIndex + } +} diff --git a/FoodApp/FoodApp/Controllers/PageViewControllers/DescriptionViewController.swift b/FoodApp/FoodApp/Controllers/PageViewControllers/DescriptionViewController.swift new file mode 100644 index 0000000..7ca39fa --- /dev/null +++ b/FoodApp/FoodApp/Controllers/PageViewControllers/DescriptionViewController.swift @@ -0,0 +1,51 @@ +// +// DescriptionViewController.swift +// FoodApp +// +// Created by gnoa001 on 3/21/19. +// Copyright © 2019 SparkDev. All rights reserved. +// + +import UIKit + +class DescriptionViewController: UIViewController, Pages { + + // MARK: Variables + private lazy var descriptionLabel: UITextView = { + let textView = UITextView() + textView.translatesAutoresizingMaskIntoConstraints = false + textView.text = "Our 12-inch special-recipe pizza, featuring our traditional crispy crust, is topped with a blend of mozzarella and cheddar cheese, zesty pepperoni slices and a rich tomato sauce. No artificial flavors. Made with 100% real cheese." + textView.font = UIFont.preferredFont(forTextStyle: .footnote) + let style = NSMutableParagraphStyle() + style.lineSpacing = 12 + let attributes = [NSAttributedString.Key.paragraphStyle : style] + textView.attributedText = NSAttributedString(string: textView.text, attributes: attributes) + return textView + }() + + // MARK: Lifecycle + override func viewDidLoad() { + super.viewDidLoad() + + setupUI() + } + + // MARK: Setup + func setupUI() { + view.backgroundColor = .white + view.addSubview(descriptionLabel) + + let safeArea = view.safeAreaLayoutGuide + view.addConstraints([ + descriptionLabel.topAnchor.constraint(equalTo: safeArea.topAnchor, constant: 8), + descriptionLabel.leadingAnchor.constraint(equalTo: safeArea.leadingAnchor, constant: 16), + descriptionLabel.trailingAnchor.constraint(equalTo: safeArea.trailingAnchor, constant: -16), + descriptionLabel.bottomAnchor.constraint(equalTo: safeArea.bottomAnchor) + ]) + } + + // MARK: Helpers + func configure(description: String) { + descriptionLabel.text = description + } +} diff --git a/FoodApp/FoodApp/Controllers/PageViewControllers/OrderViewController.swift b/FoodApp/FoodApp/Controllers/PageViewControllers/OrderViewController.swift new file mode 100644 index 0000000..b9881fe --- /dev/null +++ b/FoodApp/FoodApp/Controllers/PageViewControllers/OrderViewController.swift @@ -0,0 +1,171 @@ +// +// OrderViewController.swift +// FoodApp +// +// Created by gnoa001 on 3/21/19. +// Copyright © 2019 SparkDev. All rights reserved. +// + +import UIKit + +class OrderViewController: UIViewController, Pages { + + // MARK: Variables + private var menuItem: MenuItem? + + private var isOrderButtonOn = false + + // MARK: UI Elements + private lazy var orderButton: UIButton = { + let button = UIButton() + button.titleLabel?.font = UIFont.preferredFont(forTextStyle: .headline) + button.setTitle("Add to Order", for: .normal) + button.setTitleColor(.darkGray, for: .normal) + + button.layer.borderColor = UIColor.darkGray.cgColor + button.layer.borderWidth = 2.0 + button.layer.cornerRadius = 25 //(view.frame.size.height / 2) + button.addTarget(self, action: #selector(orderButtonTapped(_:)), for: .touchUpInside) + return button + }() + + private lazy var stackView: UIStackView = { + let stackView = UIStackView(arrangedSubviews: [sizeStackView, quantityStackView, orderButton]) + stackView.translatesAutoresizingMaskIntoConstraints = false + stackView.axis = .vertical + stackView.alignment = .center + stackView.distribution = .equalSpacing + stackView.spacing = 8 + return stackView + }() + + // MARK: Size + private lazy var sizeLabel: UILabel = { + let label = UILabel() + label.text = "Choose Size" + return label + }() + + private lazy var sizeControl: UISegmentedControl = { + let segmentedControl = UISegmentedControl(items: ["Small", "Medium", "Large"]) + segmentedControl.selectedSegmentIndex = 0 + return segmentedControl + }() + + private lazy var sizeStackView: UIStackView = { + let stackView = UIStackView(arrangedSubviews: [sizeLabel, sizeControl]) + stackView.axis = .vertical + stackView.alignment = .center + stackView.spacing = 2 + return stackView + }() + + // MARK: Quantity + private lazy var quantityLabel: UILabel = { + let label = UILabel() + label.text = "Choose Quantity" + label.isUserInteractionEnabled = true + return label + }() + + private var stepperValue: Int = 0 { + didSet { + stepperValueLabel.fadeTransition(0.1) + stepperValueLabel.text = String(stepperValue) + } + } + + private lazy var stepperValueLabel: UILabel = { + let label = UILabel() + label.text = "1" + return label + }() + + private lazy var quantityStepper: UIStepper = { + let stepper = UIStepper() + stepper.addTarget(self, action: #selector(stepperValueChanged(_:)), for: .valueChanged) + stepper.stepValue = 1 + stepper.minimumValue = 1 + stepper.maximumValue = 4 + return stepper + }() + + private lazy var stepperStackView: UIStackView = { + let stackView = UIStackView(arrangedSubviews: [stepperValueLabel, quantityStepper]) + stackView.translatesAutoresizingMaskIntoConstraints = false + stackView.setContentCompressionResistancePriority(.required, for: .vertical) + stackView.axis = .horizontal + stackView.alignment = .center + stackView.distribution = .equalSpacing + stackView.spacing = 8 + return stackView + }() + + private lazy var quantityStackView: UIStackView = { + let stackView = UIStackView(arrangedSubviews: [quantityLabel, stepperStackView]) + stackView.axis = .vertical + stackView.alignment = .leading + stackView.distribution = .fillEqually + stackView.spacing = 2 + return stackView + }() + + // MARK: init + init(item: MenuItem) { + menuItem = item + + super.init(nibName: nil, bundle: nil) + } + + required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + // MARK: Lifecycle + override func viewDidLoad() { + super.viewDidLoad() + + view.addSubview(stackView) + setupUI() + view.backgroundColor = .white + } + + // MARK: Setup + func setupUI() { + let layoutGuide = view.safeAreaLayoutGuide + view.addConstraints([ + sizeControl.heightAnchor.constraint(equalToConstant: 30), + stepperValueLabel.widthAnchor.constraint(equalToConstant: 10), + stackView.leadingAnchor.constraint(equalTo: layoutGuide.leadingAnchor), + stackView.trailingAnchor.constraint(equalTo: layoutGuide.trailingAnchor), + stackView.topAnchor.constraint(equalTo: layoutGuide.topAnchor, constant: 16), + stackView.bottomAnchor.constraint(equalTo: layoutGuide.bottomAnchor, constant: -16), + orderButton.heightAnchor.constraint(equalToConstant: 50), + orderButton.widthAnchor.constraint(equalToConstant: (UIScreen.main.bounds.width / 2).rounded()) + ]) + } + + // MARK: Helpers + func activateButton(bool: Bool) { + isOrderButtonOn = bool + let orange = UIColor.customOrange + let color = bool ? orange : UIColor.white + let title = bool ? "Item Added to Order": "Add to Order" + let titleColor = bool ? UIColor.lightText : UIColor.gray + + UIView.animate(withDuration: 0.4) { + self.orderButton.setTitle(title, for: .normal) + self.orderButton.setTitleColor(titleColor, for: .normal) + self.orderButton.backgroundColor = color + } + } + + // MARK: Actions + @objc func stepperValueChanged(_ sender: UIStepper) { + stepperValue = Int(sender.value) + } + + @objc func orderButtonTapped(_ sender: UIButton) { + activateButton(bool: !isOrderButtonOn) + } +} diff --git a/FoodApp/FoodApp/Controllers/PageViewControllers/RatingsViewController.swift b/FoodApp/FoodApp/Controllers/PageViewControllers/RatingsViewController.swift new file mode 100644 index 0000000..3eed155 --- /dev/null +++ b/FoodApp/FoodApp/Controllers/PageViewControllers/RatingsViewController.swift @@ -0,0 +1,48 @@ +// +// RatingsViewController.swift +// FoodApp +// +// Created by gnoa001 on 3/21/19. +// Copyright © 2019 SparkDev. All rights reserved. +// + +import UIKit +import Foundation + +class RatingsViewController: UITableViewController, Pages { + + // MARK: Variables + let text = ["You can't do this – UIStackView is a non-drawing view, meaning that drawRect() is never called ", + "If you desperately want a background color, consider placing the stack view inside another UIView and giving that view a background color.", + "This is part of the Swift Knowledge Base, a free, searchable collection of solutions for common iOS questions.", + "Xcode offers to fix the problem. But you can do it yourself by adjusting one of the name label constraints. Head back to Main.storyboard and select the name label. In the Size Inspector, find the Trailing Space constraint and click Edit." + ] + + // MARK: Lifecycle + override func viewDidLoad() { + super.viewDidLoad() + + setupTableView() + } + + // MARK: Helpers + func setupTableView() { + tableView.register(UINib(nibName: "RatingsTableViewCell", bundle: nil), forCellReuseIdentifier: "RatingsTableViewCell") + tableView.rowHeight = UITableView.automaticDimension + tableView.estimatedRowHeight = 250 + tableView.allowsSelection = false + } +} + +extension RatingsViewController { + //MARK: TableView Methods + override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return 4 + } + + override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let cell = tableView.dequeueReusableCell(withIdentifier: "RatingsTableViewCell", for: indexPath) as! RatingsTableViewCell + cell.textView.text = text[indexPath.row % text.count] + return cell + } +} diff --git a/FoodApp/FoodApp/Controllers/TabBarController.swift b/FoodApp/FoodApp/Controllers/TabBarController.swift new file mode 100644 index 0000000..e2725b2 --- /dev/null +++ b/FoodApp/FoodApp/Controllers/TabBarController.swift @@ -0,0 +1,37 @@ +// +// HomeViewController.swift +// FoodApp +// +// Created by gnoa001 on 2/21/19. +// Copyright © 2019 SparkDev. All rights reserved. +// + +import UIKit + +class TabBarController: UITabBarController { + + // MARK: Lifecycle + override func viewDidLoad() { + super.viewDidLoad() + + setupControllers() + } + + // MARK: Setup + func setupControllers() { + + let home = HomeViewController() + home.tabBarItem.image = UIImage(named: "home") + + let shoppingCart = ShoppingCartViewController() + shoppingCart.tabBarItem.image = UIImage(named: "cart") + + let profile = ProfileViewController() + profile.tabBarItem.image = UIImage(named: "user") + + let viewControllerArray: [UIViewController] = [home, shoppingCart,profile] + + let navigationControllers = viewControllerArray.map { UINavigationController(rootViewController: $0)} + viewControllers = navigationControllers + } +} diff --git a/FoodApp/FoodApp/Controllers/Tabs/HomeViewController.swift b/FoodApp/FoodApp/Controllers/Tabs/HomeViewController.swift new file mode 100644 index 0000000..eff35a5 --- /dev/null +++ b/FoodApp/FoodApp/Controllers/Tabs/HomeViewController.swift @@ -0,0 +1,162 @@ +// +// ViewController.swift +// FoodApp +// +// Created by Cassandra Zuria on 2/12/19. +// Copyright © 2019 SparkDev. All rights reserved. +// + +import UIKit +import Firebase +import UserNotifications + +class HomeViewController: UIViewController { + + var menuCategories = [MenuCategory]() + + var dataSource = [MenuItem]() + + let firestore = FirebaseAPI() + + lazy var categoriesCollectionView: UICollectionView = { // move implementation + var layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout() + layout.minimumLineSpacing = 0 + layout.minimumInteritemSpacing = 0 + layout.estimatedItemSize = CGSize(width: 40, height: 30) + layout.scrollDirection = .horizontal + layout.sectionInset = UIEdgeInsets(top: 0, left: 8, bottom: 0, right: 0) + + var collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout) + collectionView.translatesAutoresizingMaskIntoConstraints = false + collectionView.showsHorizontalScrollIndicator = false + collectionView.backgroundColor = .white + collectionView.delegate = self + collectionView.dataSource = self + collectionView.layer.masksToBounds = false + collectionView.layer.shadowColor = UIColor.black.cgColor + collectionView.layer.shadowOpacity = 0.3 + collectionView.layer.shadowOffset = CGSize(width: 0, height: 3.0) + collectionView.layer.shadowRadius = 5 + return collectionView + }() + + lazy var menuItemsCollectionView: UICollectionView = { + let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout() + layout.scrollDirection = .vertical + layout.sectionInset = UIEdgeInsets(top: 16, left: 16, bottom: 16, right: 16) + layout.minimumLineSpacing = 16 + layout.itemSize = CGSize(width: view.bounds.size.width - 32, height: 240) + + let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout) + collectionView.translatesAutoresizingMaskIntoConstraints = false + collectionView.showsHorizontalScrollIndicator = false + collectionView.backgroundColor = .white + collectionView.delegate = self + collectionView.dataSource = self + return collectionView + }() + + // MARK: init + init() { + super.init(nibName: nil, bundle: nil) + + title = "Home" + } + + required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + // MARK: Lifecycle + override func viewDidLoad() { + super.viewDidLoad() + + setupUI() + + loadCategories() + + loadMenuItems() + } + + private func loadCategories() { + firestore.getMenuCategories(completion: ({(menuItems, error) in + self.menuCategories = menuItems + self.categoriesCollectionView.reloadData() + })) + } + + private func loadMenuItems() { + firestore.getMenuItems(menuCategory: MenuCategory(categoryId: "Dessert")) { (menuItems, error) in + self.dataSource = menuItems + self.menuItemsCollectionView.reloadData() + } + } + + //MARK: Setup + func setupUI() { + view.backgroundColor = .white + + menuItemsCollectionView.register(UINib(nibName: "MenuItemCollectionViewCell", bundle: nil), forCellWithReuseIdentifier: MenuItemCollectionViewCell.reuseID) + categoriesCollectionView.register(CategoriesCollectionViewCell.self, forCellWithReuseIdentifier: CategoriesCollectionViewCell.reuseID) + + view.addSubview(menuItemsCollectionView) + view.addSubview(categoriesCollectionView) + + let layoutGuide = view.safeAreaLayoutGuide + view.addConstraints([ + categoriesCollectionView.topAnchor.constraint(equalTo: layoutGuide.topAnchor), + categoriesCollectionView.leadingAnchor.constraint(equalTo: layoutGuide.leadingAnchor), + categoriesCollectionView.trailingAnchor.constraint(equalTo: layoutGuide.trailingAnchor), + categoriesCollectionView.heightAnchor.constraint(equalToConstant: 64), + menuItemsCollectionView.leadingAnchor.constraint(equalTo: layoutGuide.leadingAnchor), + menuItemsCollectionView.trailingAnchor.constraint(equalTo: layoutGuide.trailingAnchor), + menuItemsCollectionView.topAnchor.constraint(equalTo: categoriesCollectionView.bottomAnchor), + menuItemsCollectionView.bottomAnchor.constraint(equalTo: layoutGuide.bottomAnchor) + ]) + } + + func setupNavBar() { + title = "Home" + navigationItem.title = "ChowDown" + } +} + +extension HomeViewController: UICollectionViewDelegate, UICollectionViewDataSource { + // MARK: CollectionView Methods + func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { + + if collectionView == self.categoriesCollectionView { + return menuCategories.count + } else { + return dataSource.count + } + } + + func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { + + if collectionView == self.menuItemsCollectionView { + let cell = collectionView.dequeueReusableCell(withReuseIdentifier: MenuItemCollectionViewCell.reuseID, for: indexPath) as! MenuItemCollectionViewCell + + let menuItem = dataSource[indexPath.row] + cell.item = menuItem + + return cell + } else { // categoriesCollectionView + let cell = collectionView.dequeueReusableCell(withReuseIdentifier: CategoriesCollectionViewCell.reuseID, for: indexPath) as! CategoriesCollectionViewCell + + let category = menuCategories[indexPath.row] + cell.category = category + + return cell + } + return UICollectionViewCell() + } + + func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { + // let item = dataSource.item(at: indexPath.row) + let detailViewController = MenuItemDetailViewController() + navigationController?.pushViewController(detailViewController, animated: true) + + // else if categories, reload collectionview + } +} diff --git a/FoodApp/FoodApp/Controllers/Tabs/HomeViewController.swift.orig b/FoodApp/FoodApp/Controllers/Tabs/HomeViewController.swift.orig new file mode 100644 index 0000000..d67e6a7 --- /dev/null +++ b/FoodApp/FoodApp/Controllers/Tabs/HomeViewController.swift.orig @@ -0,0 +1,208 @@ +// +// ViewController.swift +// FoodApp +// +// Created by Cassandra Zuria on 2/12/19. +// Copyright © 2019 SparkDev. All rights reserved. +// + +import UIKit +import Firebase +import UserNotifications + +class HomeViewController: UIViewController { + +<<<<<<< HEAD:FoodApp/FoodApp/Controllers/Tabs/HomeViewController.swift + // MARK: Variables + var dataSource = [MenuItem]() +======= + var menuCategories = [MenuCategory]() + + var dataSource = [MenuItem]() + + let firestore = FirebaseAPI() +>>>>>>> e52f18c2553988c046c489e0ecf20b0cf96fe655:FoodApp/FoodApp/Controllers/HomeViewController.swift + + var selectedIndexPath: IndexPath? + + let categories = ["ALL", "BREAKFAST", "LUNCH", "DINNER", "DESSERT", "PASTRIES"] + + // MARK: UI Elements + lazy var categoriesCollectionView: UICollectionView = { + var layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout() + layout.minimumLineSpacing = 0 + layout.minimumInteritemSpacing = 0 + layout.estimatedItemSize = CGSize(width: 40, height: 30) + layout.scrollDirection = .horizontal + layout.sectionInset = UIEdgeInsets(top: 0, left: 8, bottom: 0, right: 0) + + var collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout) + collectionView.translatesAutoresizingMaskIntoConstraints = false + collectionView.showsHorizontalScrollIndicator = false + collectionView.backgroundColor = .white + collectionView.delegate = self + collectionView.dataSource = self + collectionView.layer.masksToBounds = false + collectionView.layer.shadowColor = UIColor.black.cgColor + collectionView.layer.shadowOpacity = 0.3 + collectionView.layer.shadowOffset = CGSize(width: 0, height: 3.0) + collectionView.layer.shadowRadius = 5 + return collectionView + }() + + lazy var menuItemsCollectionView: UICollectionView = { + let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout() + layout.scrollDirection = .vertical + layout.sectionInset = UIEdgeInsets(top: 16, left: 16, bottom: 16, right: 16) + layout.minimumLineSpacing = 16 + layout.itemSize = CGSize(width: view.bounds.size.width - 32, height: 240) + + let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout) + collectionView.translatesAutoresizingMaskIntoConstraints = false + collectionView.showsHorizontalScrollIndicator = false + collectionView.backgroundColor = .white + collectionView.delegate = self + collectionView.dataSource = self + return collectionView + }() + + // MARK: init + init() { + super.init(nibName: nil, bundle: nil) + } + + required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + // MARK: Lifecycle + override func viewDidLoad() { + super.viewDidLoad() + + setupUI() +<<<<<<< HEAD:FoodApp/FoodApp/Controllers/Tabs/HomeViewController.swift + setupNavBar() +======= + + loadCategories() + + loadMenuItems() + } + + private func loadCategories() { + firestore.getMenuCategories(completion: ({(menuItems, error) in + self.menuCategories = menuItems + self.categoriesCollectionView.reloadData() + })) + } + + private func loadMenuItems() { + firestore.getMenuItems(menuCategory: MenuCategory(categoryId: "Dessert")) { (menuItems, error) in +// self.dataSource = menuItems +// self.menuItemsCollectionView.reloadData() + + print(menuItems) + } +>>>>>>> e52f18c2553988c046c489e0ecf20b0cf96fe655:FoodApp/FoodApp/Controllers/HomeViewController.swift + } + + //MARK: Setup + func setupUI() { + view.backgroundColor = .white + + menuItemsCollectionView.register(UINib(nibName: "MenuItemCollectionViewCell", bundle: nil), forCellWithReuseIdentifier: MenuItemCollectionViewCell.reuseID) + categoriesCollectionView.register(CategoriesCollectionViewCell.self, forCellWithReuseIdentifier: CategoriesCollectionViewCell.reuseID) + + view.addSubview(menuItemsCollectionView) + view.addSubview(categoriesCollectionView) + + let layoutGuide = view.safeAreaLayoutGuide + view.addConstraints([ + categoriesCollectionView.topAnchor.constraint(equalTo: layoutGuide.topAnchor), + categoriesCollectionView.leadingAnchor.constraint(equalTo: layoutGuide.leadingAnchor), + categoriesCollectionView.trailingAnchor.constraint(equalTo: layoutGuide.trailingAnchor), + categoriesCollectionView.heightAnchor.constraint(equalToConstant: 64), + menuItemsCollectionView.leadingAnchor.constraint(equalTo: layoutGuide.leadingAnchor), + menuItemsCollectionView.trailingAnchor.constraint(equalTo: layoutGuide.trailingAnchor), + menuItemsCollectionView.topAnchor.constraint(equalTo: categoriesCollectionView.bottomAnchor), + menuItemsCollectionView.bottomAnchor.constraint(equalTo: layoutGuide.bottomAnchor) + ]) + } + + func setupNavBar() { + title = "Home" + navigationItem.title = "ChowDown" + } +} + +extension HomeViewController: UICollectionViewDelegate, UICollectionViewDataSource { + // MARK: CollectionView Methods + func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { +<<<<<<< HEAD:FoodApp/FoodApp/Controllers/Tabs/HomeViewController.swift + return 5 + } + + func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { + if collectionView == self.menuItemsCollectionView { + let cell = collectionView.dequeueReusableCell(withReuseIdentifier: MenuItemCollectionViewCell.reuseID, for: indexPath) as! MenuItemCollectionViewCell + cell.foodItemImageView.image = #imageLiteral(resourceName: "pizzapic") + return cell + } else if collectionView == categoriesCollectionView { // categoriesCollectionView + let cell = collectionView.dequeueReusableCell(withReuseIdentifier: CategoriesCollectionViewCell.reuseID, for: indexPath) as! CategoriesCollectionViewCell + cell.categoryTitleLabel.text = categories[indexPath.row % categories.count] + return cell +======= + + if collectionView == self.categoriesCollectionView { + return menuCategories.count + } else { + return dataSource.count + } + } + + func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { + + if collectionView == self.menuItemsCollectionView { + let cell = collectionView.dequeueReusableCell(withReuseIdentifier: MenuItemCollectionViewCell.reuseID, for: indexPath) as! MenuItemCollectionViewCell + +// let menuItem = dataSource[indexPath.row] +// cell.item = menuItem + + return cell + } else { // categoriesCollectionView + let cell = collectionView.dequeueReusableCell(withReuseIdentifier: CategoriesCollectionViewCell.reuseID, for: indexPath) as! CategoriesCollectionViewCell + + let category = menuCategories[indexPath.row] + cell.category = category + + return cell +>>>>>>> e52f18c2553988c046c489e0ecf20b0cf96fe655:FoodApp/FoodApp/Controllers/HomeViewController.swift + } + return UICollectionViewCell() + } + + func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { +<<<<<<< HEAD:FoodApp/FoodApp/Controllers/Tabs/HomeViewController.swift + if collectionView == menuItemsCollectionView { + let detailViewController = MenuItemDetailViewController() + navigationController?.pushViewController(detailViewController, animated: true) + } else if collectionView == categoriesCollectionView { + + let cell = collectionView.cellForItem(at: indexPath) as! CategoriesCollectionViewCell + cell.contentView.backgroundColor = UIColor.customOrange + + if let selectedIdx = selectedIndexPath, selectedIdx != indexPath { + let selectedCell = collectionView.cellForItem(at: selectedIdx) as! CategoriesCollectionViewCell + selectedCell.contentView.backgroundColor = .clear + } + selectedIndexPath = indexPath + } +======= + // let item = dataSource.item(at: indexPath.row) + let detailViewController = MenuItemDetailViewController() + navigationController?.pushViewController(detailViewController, animated: true) + + // else if categories, reload collectionview +>>>>>>> e52f18c2553988c046c489e0ecf20b0cf96fe655:FoodApp/FoodApp/Controllers/HomeViewController.swift + } +} diff --git a/FoodApp/FoodApp/Controllers/Tabs/HomeViewController_BACKUP_1194.swift b/FoodApp/FoodApp/Controllers/Tabs/HomeViewController_BACKUP_1194.swift new file mode 100644 index 0000000..d180873 --- /dev/null +++ b/FoodApp/FoodApp/Controllers/Tabs/HomeViewController_BACKUP_1194.swift @@ -0,0 +1,155 @@ +// +// ViewController.swift +// FoodApp +// +// Created by Cassandra Zuria on 2/12/19. +// Copyright © 2019 SparkDev. All rights reserved. +// + +import UIKit +import Firebase +import UserNotifications + +class HomeViewController: UIViewController { + +<<<<<<< HEAD:FoodApp/FoodApp/Controllers/HomeViewController.swift + var menuCategories = [MenuCategory]() + +======= + // MARK: Variables +>>>>>>> d01cf9ade0c5aa7373538318283dcc2bd08e55cd:FoodApp/FoodApp/Controllers/Tabs/HomeViewController.swift + var dataSource = [MenuItem]() + + var selectedIndexPath: IndexPath? + + let categories = ["ALL", "BREAKFAST", "LUNCH", "DINNER", "DESSERT", "PASTRIES"] + + // MARK: UI Elements + lazy var categoriesCollectionView: UICollectionView = { + var layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout() + layout.minimumLineSpacing = 0 + layout.minimumInteritemSpacing = 0 + layout.estimatedItemSize = CGSize(width: 40, height: 30) + layout.scrollDirection = .horizontal + layout.sectionInset = UIEdgeInsets(top: 0, left: 8, bottom: 0, right: 0) + + var collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout) + collectionView.translatesAutoresizingMaskIntoConstraints = false + collectionView.showsHorizontalScrollIndicator = false + collectionView.backgroundColor = .white + collectionView.delegate = self + collectionView.dataSource = self + collectionView.layer.masksToBounds = false + collectionView.layer.shadowColor = UIColor.black.cgColor + collectionView.layer.shadowOpacity = 0.3 + collectionView.layer.shadowOffset = CGSize(width: 0, height: 3.0) + collectionView.layer.shadowRadius = 5 + return collectionView + }() + + lazy var menuItemsCollectionView: UICollectionView = { + let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout() + layout.scrollDirection = .vertical + layout.sectionInset = UIEdgeInsets(top: 16, left: 16, bottom: 16, right: 16) + layout.minimumLineSpacing = 16 + layout.itemSize = CGSize(width: view.bounds.size.width - 32, height: 240) + + let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout) + collectionView.translatesAutoresizingMaskIntoConstraints = false + collectionView.showsHorizontalScrollIndicator = false + collectionView.backgroundColor = .white + collectionView.delegate = self + collectionView.dataSource = self + return collectionView + }() + + // MARK: init + init() { + super.init(nibName: nil, bundle: nil) + } + + required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + // MARK: Lifecycle + override func viewDidLoad() { + super.viewDidLoad() + + setupUI() + setupNavBar() + } + + //MARK: Setup + func setupUI() { + view.backgroundColor = .white + + menuItemsCollectionView.register(UINib(nibName: "MenuItemCollectionViewCell", bundle: nil), forCellWithReuseIdentifier: MenuItemCollectionViewCell.reuseID) + categoriesCollectionView.register(CategoriesCollectionViewCell.self, forCellWithReuseIdentifier: CategoriesCollectionViewCell.reuseID) + + view.addSubview(menuItemsCollectionView) + view.addSubview(categoriesCollectionView) + + let layoutGuide = view.safeAreaLayoutGuide + view.addConstraints([ + categoriesCollectionView.topAnchor.constraint(equalTo: layoutGuide.topAnchor), + categoriesCollectionView.leadingAnchor.constraint(equalTo: layoutGuide.leadingAnchor), + categoriesCollectionView.trailingAnchor.constraint(equalTo: layoutGuide.trailingAnchor), + categoriesCollectionView.heightAnchor.constraint(equalToConstant: 64), + menuItemsCollectionView.leadingAnchor.constraint(equalTo: layoutGuide.leadingAnchor), + menuItemsCollectionView.trailingAnchor.constraint(equalTo: layoutGuide.trailingAnchor), + menuItemsCollectionView.topAnchor.constraint(equalTo: categoriesCollectionView.bottomAnchor), + menuItemsCollectionView.bottomAnchor.constraint(equalTo: layoutGuide.bottomAnchor) + ]) + } + + func setupNavBar() { + title = "Home" + navigationItem.title = "ChowDown" + } +} + +extension HomeViewController: UICollectionViewDelegate, UICollectionViewDataSource { + // MARK: CollectionView Methods + func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { + return 5 + } + + func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { + if collectionView == self.menuItemsCollectionView { + let cell = collectionView.dequeueReusableCell(withReuseIdentifier: MenuItemCollectionViewCell.reuseID, for: indexPath) as! MenuItemCollectionViewCell + cell.foodItemImageView.image = #imageLiteral(resourceName: "pizzapic") + return cell + } else if collectionView == categoriesCollectionView { // categoriesCollectionView + let cell = collectionView.dequeueReusableCell(withReuseIdentifier: CategoriesCollectionViewCell.reuseID, for: indexPath) as! CategoriesCollectionViewCell + cell.categoryTitleLabel.text = categories[indexPath.row % categories.count] + return cell + } + return UICollectionViewCell() + } + + func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { +<<<<<<< HEAD:FoodApp/FoodApp/Controllers/HomeViewController.swift + // let item = dataSource.item(at: indexPath.row) + let detailViewController = MenuItemDetailViewController() + navigationController?.pushViewController(detailViewController, animated: true) + + // else if categories, reload collectionview +======= + if collectionView == menuItemsCollectionView { + let detailViewController = MenuItemDetailViewController() + navigationController?.pushViewController(detailViewController, animated: true) + } else if collectionView == categoriesCollectionView { + + let cell = collectionView.cellForItem(at: indexPath) as! CategoriesCollectionViewCell + cell.contentView.backgroundColor = UIColor.customOrange + + if let selectedIdx = selectedIndexPath, selectedIdx != indexPath { + let selectedCell = collectionView.cellForItem(at: selectedIdx) as! CategoriesCollectionViewCell + selectedCell.contentView.backgroundColor = .clear + } + selectedIndexPath = indexPath + } +>>>>>>> d01cf9ade0c5aa7373538318283dcc2bd08e55cd:FoodApp/FoodApp/Controllers/Tabs/HomeViewController.swift + } +} diff --git a/FoodApp/FoodApp/Controllers/Tabs/HomeViewController_BASE_1194.swift b/FoodApp/FoodApp/Controllers/Tabs/HomeViewController_BASE_1194.swift new file mode 100644 index 0000000..249833c --- /dev/null +++ b/FoodApp/FoodApp/Controllers/Tabs/HomeViewController_BASE_1194.swift @@ -0,0 +1,119 @@ +// +// ViewController.swift +// FoodApp +// +// Created by Cassandra Zuria on 2/12/19. +// Copyright © 2019 SparkDev. All rights reserved. +// + +import UIKit + +class HomeViewController: UIViewController { + var dataSource = [MenuItem]() + + + + lazy var categoriesCollectionView: UICollectionView = { // move implementation + var layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout() + layout.scrollDirection = .horizontal + layout.sectionInset = UIEdgeInsets(top: 0, left: 16, bottom: 0, right: 16) + layout.itemSize = CGSize(width: (view.bounds.size.width / 5).rounded(), height: 46) + + var collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout) + collectionView.translatesAutoresizingMaskIntoConstraints = false + collectionView.showsHorizontalScrollIndicator = false + collectionView.backgroundColor = .white + collectionView.delegate = self + collectionView.dataSource = self + collectionView.layer.borderWidth = 0.5 + collectionView.layer.borderColor = UIColor.lightGray.cgColor + collectionView.layer.masksToBounds = false + collectionView.layer.shadowColor = UIColor.black.cgColor + collectionView.layer.shadowOpacity = 0.8 + collectionView.layer.shadowOffset = CGSize(width: 0, height: -3.0) + collectionView.layer.shadowRadius = 5 + return collectionView + }() + + lazy var menuItemsCollectionView: UICollectionView = { // move implementation + let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout() + layout.scrollDirection = .vertical + layout.sectionInset = UIEdgeInsets(top: 8, left: 16, bottom: 8, right: 16) + layout.itemSize = CGSize(width: view.bounds.size.width - 32, height: 200) + + let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout) + collectionView.backgroundColor = .white + collectionView.layer.cornerRadius = 6.0 + collectionView.delegate = self + collectionView.dataSource = self + collectionView.isUserInteractionEnabled = true + collectionView.translatesAutoresizingMaskIntoConstraints = false + return collectionView + }() + + init() { + super.init(nibName: nil, bundle: nil) + + title = "Home" + navigationItem.title = "ChowDown" + } + + required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + override func viewDidLoad() { + super.viewDidLoad() + + setupUI() + } + + func setupUI() { + view.backgroundColor = .white + + menuItemsCollectionView.register(UINib(nibName: "MenuItemCollectionViewCell", bundle: nil), forCellWithReuseIdentifier: MenuItemCollectionViewCell.reuseID) + categoriesCollectionView.register(CategoriesCollectionViewCell.self, forCellWithReuseIdentifier: CategoriesCollectionViewCell.reuseID) +// categoriesCollectionView.register(UINib(nibName: "MenuItemCollectionViewCell", bundle: nil), forCellWithReuseIdentifier: MenuItemCollectionViewCell.reuseID) + + view.addSubview(menuItemsCollectionView) + view.addSubview(categoriesCollectionView) + + let margins = view.layoutMarginsGuide + view.addConstraints([ + categoriesCollectionView.topAnchor.constraint(equalTo: margins.topAnchor), + categoriesCollectionView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: -2), + categoriesCollectionView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: 2), + categoriesCollectionView.heightAnchor.constraint(equalToConstant: 64), + menuItemsCollectionView.leadingAnchor.constraint(equalTo: view.leadingAnchor), + menuItemsCollectionView.trailingAnchor.constraint(equalTo: view.trailingAnchor), + menuItemsCollectionView.topAnchor.constraint(equalTo: categoriesCollectionView.bottomAnchor, constant: 4), + menuItemsCollectionView.bottomAnchor.constraint(equalTo: view.bottomAnchor) + ]) + } +} + +extension HomeViewController: UICollectionViewDelegate, UICollectionViewDataSource { + func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { + return 20 + } + + func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { + + if collectionView == self.menuItemsCollectionView { + let cell = collectionView.dequeueReusableCell(withReuseIdentifier: MenuItemCollectionViewCell.reuseID, for: indexPath) as! MenuItemCollectionViewCell + return cell + } else { // categoriesCollectionView + let cell = collectionView.dequeueReusableCell(withReuseIdentifier: CategoriesCollectionViewCell.reuseID, for: indexPath) as! CategoriesCollectionViewCell +// let cell = collectionView.dequeueReusableCell(withReuseIdentifier: MenuItemCollectionViewCell.reuseID, for: indexPath) as! MenuItemCollectionViewCell + return cell + } + } + + func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { + // let item = dataSource.item(at: indexPath.row) + let detailViewController = MenuItemDetailViewController() + navigationController?.pushViewController(detailViewController, animated: true) + + // else if categories, reload collectionview + } +} diff --git a/FoodApp/FoodApp/Controllers/Tabs/HomeViewController_LOCAL_1194.swift b/FoodApp/FoodApp/Controllers/Tabs/HomeViewController_LOCAL_1194.swift new file mode 100644 index 0000000..2470117 --- /dev/null +++ b/FoodApp/FoodApp/Controllers/Tabs/HomeViewController_LOCAL_1194.swift @@ -0,0 +1,122 @@ +// +// ViewController.swift +// FoodApp +// +// Created by Cassandra Zuria on 2/12/19. +// Copyright © 2019 SparkDev. All rights reserved. +// + +import UIKit +import Firebase +import UserNotifications + +class HomeViewController: UIViewController { + + var menuCategories = [MenuCategory]() + + var dataSource = [MenuItem]() + + lazy var categoriesCollectionView: UICollectionView = { // move implementation + var layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout() + layout.scrollDirection = .horizontal + layout.sectionInset = UIEdgeInsets(top: 0, left: 16, bottom: 0, right: 16) + layout.itemSize = CGSize(width: (view.bounds.size.width / 5).rounded(), height: 46) + + var collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout) + collectionView.translatesAutoresizingMaskIntoConstraints = false + collectionView.showsHorizontalScrollIndicator = false + collectionView.backgroundColor = .white + collectionView.delegate = self + collectionView.dataSource = self + collectionView.layer.borderWidth = 0.5 + collectionView.layer.borderColor = UIColor.lightGray.cgColor + collectionView.layer.masksToBounds = false + collectionView.layer.shadowColor = UIColor.black.cgColor + collectionView.layer.shadowOpacity = 0.8 + collectionView.layer.shadowOffset = CGSize(width: 0, height: -3.0) + collectionView.layer.shadowRadius = 5 + return collectionView + }() + + lazy var menuItemsCollectionView: UICollectionView = { // move implementation + let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout() + layout.scrollDirection = .vertical + layout.sectionInset = UIEdgeInsets(top: 8, left: 16, bottom: 8, right: 16) + layout.itemSize = CGSize(width: view.bounds.size.width - 32, height: 200) + + let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout) + collectionView.backgroundColor = .white + collectionView.layer.cornerRadius = 6.0 + collectionView.delegate = self + collectionView.dataSource = self + collectionView.isUserInteractionEnabled = true + collectionView.translatesAutoresizingMaskIntoConstraints = false + return collectionView + }() + + init() { + super.init(nibName: nil, bundle: nil) + + title = "Home" + navigationItem.title = "ChowDown" + } + + required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + override func viewDidLoad() { + super.viewDidLoad() + + setupUI() + } + + func setupUI() { + view.backgroundColor = .white + + menuItemsCollectionView.register(UINib(nibName: "MenuItemCollectionViewCell", bundle: nil), forCellWithReuseIdentifier: MenuItemCollectionViewCell.reuseID) + categoriesCollectionView.register(CategoriesCollectionViewCell.self, forCellWithReuseIdentifier: CategoriesCollectionViewCell.reuseID) +// categoriesCollectionView.register(UINib(nibName: "MenuItemCollectionViewCell", bundle: nil), forCellWithReuseIdentifier: MenuItemCollectionViewCell.reuseID) + + view.addSubview(menuItemsCollectionView) + view.addSubview(categoriesCollectionView) + + let margins = view.layoutMarginsGuide + view.addConstraints([ + categoriesCollectionView.topAnchor.constraint(equalTo: margins.topAnchor), + categoriesCollectionView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: -2), + categoriesCollectionView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: 2), + categoriesCollectionView.heightAnchor.constraint(equalToConstant: 64), + menuItemsCollectionView.leadingAnchor.constraint(equalTo: view.leadingAnchor), + menuItemsCollectionView.trailingAnchor.constraint(equalTo: view.trailingAnchor), + menuItemsCollectionView.topAnchor.constraint(equalTo: categoriesCollectionView.bottomAnchor, constant: 4), + menuItemsCollectionView.bottomAnchor.constraint(equalTo: view.bottomAnchor) + ]) + } +} + +extension HomeViewController: UICollectionViewDelegate, UICollectionViewDataSource { + func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { + return 20 + } + + func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { + + if collectionView == self.menuItemsCollectionView { + let cell = collectionView.dequeueReusableCell(withReuseIdentifier: MenuItemCollectionViewCell.reuseID, for: indexPath) as! MenuItemCollectionViewCell + return cell + } else { // categoriesCollectionView + let cell = collectionView.dequeueReusableCell(withReuseIdentifier: CategoriesCollectionViewCell.reuseID, for: indexPath) as! CategoriesCollectionViewCell +// let cell = collectionView.dequeueReusableCell(withReuseIdentifier: MenuItemCollectionViewCell.reuseID, for: indexPath) as! MenuItemCollectionViewCell + return cell + } + } + + func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { + // let item = dataSource.item(at: indexPath.row) + let detailViewController = MenuItemDetailViewController() + navigationController?.pushViewController(detailViewController, animated: true) + + // else if categories, reload collectionview + } +} diff --git a/FoodApp/FoodApp/Controllers/Tabs/HomeViewController_REMOTE_1194.swift b/FoodApp/FoodApp/Controllers/Tabs/HomeViewController_REMOTE_1194.swift new file mode 100644 index 0000000..f740f24 --- /dev/null +++ b/FoodApp/FoodApp/Controllers/Tabs/HomeViewController_REMOTE_1194.swift @@ -0,0 +1,140 @@ +// +// ViewController.swift +// FoodApp +// +// Created by Cassandra Zuria on 2/12/19. +// Copyright © 2019 SparkDev. All rights reserved. +// + +import UIKit + +class HomeViewController: UIViewController { + + // MARK: Variables + var dataSource = [MenuItem]() + + var selectedIndexPath: IndexPath? + + let categories = ["ALL", "BREAKFAST", "LUNCH", "DINNER", "DESSERT", "PASTRIES"] + + // MARK: UI Elements + lazy var categoriesCollectionView: UICollectionView = { + var layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout() + layout.minimumLineSpacing = 0 + layout.minimumInteritemSpacing = 0 + layout.estimatedItemSize = CGSize(width: 40, height: 30) + layout.scrollDirection = .horizontal + layout.sectionInset = UIEdgeInsets(top: 0, left: 8, bottom: 0, right: 0) + + var collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout) + collectionView.translatesAutoresizingMaskIntoConstraints = false + collectionView.showsHorizontalScrollIndicator = false + collectionView.backgroundColor = .white + collectionView.delegate = self + collectionView.dataSource = self + collectionView.layer.masksToBounds = false + collectionView.layer.shadowColor = UIColor.black.cgColor + collectionView.layer.shadowOpacity = 0.3 + collectionView.layer.shadowOffset = CGSize(width: 0, height: 3.0) + collectionView.layer.shadowRadius = 5 + return collectionView + }() + + lazy var menuItemsCollectionView: UICollectionView = { + let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout() + layout.scrollDirection = .vertical + layout.sectionInset = UIEdgeInsets(top: 16, left: 16, bottom: 16, right: 16) + layout.minimumLineSpacing = 16 + layout.itemSize = CGSize(width: view.bounds.size.width - 32, height: 240) + + let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout) + collectionView.translatesAutoresizingMaskIntoConstraints = false + collectionView.showsHorizontalScrollIndicator = false + collectionView.backgroundColor = .white + collectionView.delegate = self + collectionView.dataSource = self + return collectionView + }() + + // MARK: init + init() { + super.init(nibName: nil, bundle: nil) + } + + required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + // MARK: Lifecycle + override func viewDidLoad() { + super.viewDidLoad() + + setupUI() + setupNavBar() + } + + //MARK: Setup + func setupUI() { + view.backgroundColor = .white + + menuItemsCollectionView.register(UINib(nibName: "MenuItemCollectionViewCell", bundle: nil), forCellWithReuseIdentifier: MenuItemCollectionViewCell.reuseID) + categoriesCollectionView.register(CategoriesCollectionViewCell.self, forCellWithReuseIdentifier: CategoriesCollectionViewCell.reuseID) + + view.addSubview(menuItemsCollectionView) + view.addSubview(categoriesCollectionView) + + let layoutGuide = view.safeAreaLayoutGuide + view.addConstraints([ + categoriesCollectionView.topAnchor.constraint(equalTo: layoutGuide.topAnchor), + categoriesCollectionView.leadingAnchor.constraint(equalTo: layoutGuide.leadingAnchor), + categoriesCollectionView.trailingAnchor.constraint(equalTo: layoutGuide.trailingAnchor), + categoriesCollectionView.heightAnchor.constraint(equalToConstant: 64), + menuItemsCollectionView.leadingAnchor.constraint(equalTo: layoutGuide.leadingAnchor), + menuItemsCollectionView.trailingAnchor.constraint(equalTo: layoutGuide.trailingAnchor), + menuItemsCollectionView.topAnchor.constraint(equalTo: categoriesCollectionView.bottomAnchor), + menuItemsCollectionView.bottomAnchor.constraint(equalTo: layoutGuide.bottomAnchor) + ]) + } + + func setupNavBar() { + title = "Home" + navigationItem.title = "ChowDown" + } +} + +extension HomeViewController: UICollectionViewDelegate, UICollectionViewDataSource { + // MARK: CollectionView Methods + func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { + return 5 + } + + func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { + if collectionView == self.menuItemsCollectionView { + let cell = collectionView.dequeueReusableCell(withReuseIdentifier: MenuItemCollectionViewCell.reuseID, for: indexPath) as! MenuItemCollectionViewCell + cell.foodItemImageView.image = #imageLiteral(resourceName: "pizzapic") + return cell + } else if collectionView == categoriesCollectionView { // categoriesCollectionView + let cell = collectionView.dequeueReusableCell(withReuseIdentifier: CategoriesCollectionViewCell.reuseID, for: indexPath) as! CategoriesCollectionViewCell + cell.categoryTitleLabel.text = categories[indexPath.row % categories.count] + return cell + } + return UICollectionViewCell() + } + + func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { + if collectionView == menuItemsCollectionView { + let detailViewController = MenuItemDetailViewController() + navigationController?.pushViewController(detailViewController, animated: true) + } else if collectionView == categoriesCollectionView { + + let cell = collectionView.cellForItem(at: indexPath) as! CategoriesCollectionViewCell + cell.contentView.backgroundColor = UIColor.customOrange + + if let selectedIdx = selectedIndexPath, selectedIdx != indexPath { + let selectedCell = collectionView.cellForItem(at: selectedIdx) as! CategoriesCollectionViewCell + selectedCell.contentView.backgroundColor = .clear + } + selectedIndexPath = indexPath + } + } +} diff --git a/FoodApp/FoodApp/Controllers/Tabs/ProfileViewController.swift b/FoodApp/FoodApp/Controllers/Tabs/ProfileViewController.swift new file mode 100644 index 0000000..962ce5f --- /dev/null +++ b/FoodApp/FoodApp/Controllers/Tabs/ProfileViewController.swift @@ -0,0 +1,195 @@ +// +// ProfileViewController.swift +// FoodApp +// +// Created by gnoa001 on 3/15/19. +// Copyright © 2019 SparkDev. All rights reserved. +// + +import UIKit +import SkyFloatingLabelTextField + +class ProfileViewController: UIViewController { + + // MARK: Variables + private lazy var profileImageView: UIImageView = { + let imageView = UIImageView() + imageView.translatesAutoresizingMaskIntoConstraints = false + imageView.contentMode = .scaleAspectFit +// let image = UIImage(named: "woman")! +// imageView.maskCircle(anyImage: image) + imageView.image = #imageLiteral(resourceName: "woman") +// imageView.layer.cornerRadius = (imageView.frame.size.width / 2).rounded() +// imageView.clipsToBounds = true + + return imageView + }() + + // MARK: Label Names + private lazy var firstNameTextField: SkyFloatingLabelTextField = { + let sky = SkyFloatingLabelTextField() + sky.textColor = UIColor.darkGray + sky.placeholder = "First Name" + sky.text = "Michael" + sky.title = "First Name" + sky.placeholderColor = .lightGray + sky.titleColor = .customOrange + sky.lineColor = .darkGray + sky.selectedLineColor = .customOrange + sky.selectedTitleColor = .customOrange + return sky + }() + + private lazy var lastNameTextField: SkyFloatingLabelTextField = { + let textField = SkyFloatingLabelTextField() + textField.textColor = UIColor.darkGray + textField.placeholder = "First Name" + textField.text = "Scott" + textField.title = "Last Name" + textField.placeholderColor = .lightGray + textField.titleColor = .customOrange + textField.lineColor = .darkGray + textField.selectedLineColor = .customOrange + textField.selectedTitleColor = .customOrange + return textField + }() + + private lazy var emailTextField: SkyFloatingLabelTextField = { + let textField = SkyFloatingLabelTextField() + textField.textColor = UIColor.darkGray + textField.adjustsFontSizeToFitWidth = true + textField.placeholder = "Email" + textField.text = "MikeScott@dundermifflin.com" + textField.title = "Email" + textField.placeholderColor = .lightGray + textField.titleColor = .customOrange + textField.lineColor = .darkGray + textField.selectedLineColor = .customOrange + textField.selectedTitleColor = .customOrange + return textField + }() + + private lazy var addressTextField: SkyFloatingLabelTextField = { + let textField = SkyFloatingLabelTextField() + textField.textColor = UIColor.darkGray + textField.adjustsFontSizeToFitWidth = true + textField.placeholder = "Address" + textField.text = "11200 SW 8th St, Miami, FL 33199" + textField.title = "Address" + textField.placeholderColor = .lightGray + textField.titleColor = .customOrange + textField.lineColor = .darkGray + textField.selectedLineColor = .customOrange + textField.selectedTitleColor = .customOrange + return textField + }() + + private lazy var passwordTextField: SkyFloatingLabelTextField = { + let textField = SkyFloatingLabelTextField() + textField.isSecureTextEntry = true + textField.textColor = UIColor.darkGray + textField.adjustsFontSizeToFitWidth = true + textField.placeholder = "Password" + textField.text = "" + textField.title = "Password" + textField.placeholderColor = .lightGray + textField.titleColor = .customOrange + textField.lineColor = .darkGray + textField.selectedLineColor = .customOrange + textField.selectedTitleColor = .customOrange + return textField + }() + + private lazy var saveButton: UIButton = { + let button = UIButton() + button.translatesAutoresizingMaskIntoConstraints = false + button.backgroundColor = .customOrange + button.setTitleColor(.white, for: .normal) + button.layer.cornerRadius = 25 + button.setTitle("Save Changes", for: .normal) + button.addTarget(self, action: #selector(saveButtonTapped(_:)), for: .touchUpInside) + return button + }() + + private lazy var stackView: UIStackView = { + let stackView = UIStackView(arrangedSubviews: [firstNameTextField, lastNameTextField, emailTextField, addressTextField, passwordTextField]) + stackView.translatesAutoresizingMaskIntoConstraints = false + stackView.axis = .vertical + stackView.alignment = .leading + stackView.distribution = .fillEqually + stackView.spacing = 32 + return stackView + }() + + // MARK: init + init() { + super.init(nibName: nil, bundle: nil) + + title = "Profile" + } + + required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + // MARK: Lifecycle + override func viewDidLoad() { + super.viewDidLoad() + + firstNameTextField.delegate = self + lastNameTextField.delegate = self + emailTextField.delegate = self + addressTextField.delegate = self + passwordTextField.delegate = self + setupUI() + } + + // address email pw + + // MARK: Setup + func setupUI() { + view.backgroundColor = .white + + view.addSubview(profileImageView) + view.addSubview(stackView) + view.addSubview(saveButton) + + let safeArea = view.safeAreaLayoutGuide + view.addConstraints([ + //firstNameLabel.heightAnchor.constraint(equalToConstant: 30), + //profileImageView.heightAnchor.constraint(equalToConstant: (view.bounds.height / 4).rounded()), + firstNameTextField.heightAnchor.constraint(equalToConstant: 55), + firstNameTextField.widthAnchor.constraint(equalToConstant: 230), + lastNameTextField.heightAnchor.constraint(equalToConstant: 55), + lastNameTextField.widthAnchor.constraint(equalToConstant: 230), + emailTextField.heightAnchor.constraint(equalToConstant: 55), + emailTextField.widthAnchor.constraint(equalToConstant: 230), + passwordTextField.heightAnchor.constraint(equalToConstant: 55), + passwordTextField.widthAnchor.constraint(equalToConstant: 230), + addressTextField.heightAnchor.constraint(equalToConstant: 55), + addressTextField.widthAnchor.constraint(equalToConstant: 230), + profileImageView.topAnchor.constraint(equalTo: safeArea.topAnchor, constant: 24), + profileImageView.leadingAnchor.constraint(greaterThanOrEqualTo: safeArea.leadingAnchor), + profileImageView.trailingAnchor.constraint(lessThanOrEqualTo: safeArea.trailingAnchor), + profileImageView.centerXAnchor.constraint(equalTo: safeArea.centerXAnchor), + profileImageView.heightAnchor.constraint(equalToConstant: 100), + stackView.topAnchor.constraint(equalTo: profileImageView.bottomAnchor, constant: 16), + stackView.centerXAnchor.constraint(equalTo: view.centerXAnchor), + saveButton.centerXAnchor.constraint(equalTo: view.centerXAnchor), + saveButton.topAnchor.constraint(equalTo: stackView.bottomAnchor, constant: 24), + saveButton.heightAnchor.constraint(equalToConstant: 50), + saveButton.widthAnchor.constraint(equalToConstant: 140) + ]) + } + + @objc func saveButtonTapped(_ sender: UIButton) { + + } +} + +extension ProfileViewController: UITextFieldDelegate { + func textFieldShouldReturn(_ textField: UITextField) -> Bool { + textField.resignFirstResponder() + return true + } +} diff --git a/FoodApp/FoodApp/Controllers/Tabs/ShoppingCartViewController.swift b/FoodApp/FoodApp/Controllers/Tabs/ShoppingCartViewController.swift new file mode 100644 index 0000000..a7defca --- /dev/null +++ b/FoodApp/FoodApp/Controllers/Tabs/ShoppingCartViewController.swift @@ -0,0 +1,105 @@ +// +// ShoppingCartViewController.swift +// FoodApp +// +// Created by gnoa001 on 3/15/19. +// Copyright © 2019 SparkDev. All rights reserved. +// + +import UIKit + +class ShoppingCartViewController: UIViewController { + + lazy var shoppingCart: UITableView = { + let tableView = UITableView(frame: .zero) + tableView.translatesAutoresizingMaskIntoConstraints = false + tableView.allowsSelection = false + tableView.delegate = self + tableView.dataSource = self + + return tableView + }() + + lazy var priceSummary: UIView = { + let view = UIView(frame: .zero) + view.translatesAutoresizingMaskIntoConstraints = false + view.backgroundColor = .white + return view + }() + + lazy var priceTotalLabel: UILabel = { + let text = UILabel(frame: .zero) + text.text = "Total" + text.translatesAutoresizingMaskIntoConstraints = false + return text + }() + + lazy var priceTotal: UILabel = { + let text = UILabel(frame: .zero) + text.text = "$7.59" + text.translatesAutoresizingMaskIntoConstraints = false + return text + }() + + init() { + super.init(nibName: nil, bundle: nil) + + title = "Shopping Cart" +// navigationItem.title = "Shopping Cart" + } + + required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + override func viewDidLoad() { + super.viewDidLoad() + +// view.backgroundColor = .white + + shoppingCart.register(UINib(nibName: ShoppingCartTableViewCell.reuseID, bundle: nil), forCellReuseIdentifier: ShoppingCartTableViewCell.reuseID) + + view.addSubview(shoppingCart) + priceSummary.addSubview(priceTotal) + priceSummary.addSubview(priceTotalLabel) + view.addSubview(priceSummary) + + + view.addConstraints([ + shoppingCart.topAnchor.constraint(equalTo: view.topAnchor), + shoppingCart.bottomAnchor.constraint(equalTo: priceSummary.topAnchor), + shoppingCart.leftAnchor.constraint(equalTo: view.leftAnchor), + shoppingCart.rightAnchor.constraint(equalTo: view.rightAnchor), + priceSummary.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.2), + priceSummary.topAnchor.constraint(equalTo: shoppingCart.bottomAnchor), + priceSummary.bottomAnchor.constraint(equalTo: view.bottomAnchor), + priceSummary.leftAnchor.constraint(equalTo: view.leftAnchor), + priceSummary.rightAnchor.constraint(equalTo: view.rightAnchor), + priceTotal.rightAnchor.constraint(equalTo: priceSummary.rightAnchor, constant: -30), + priceTotal.heightAnchor.constraint(equalToConstant: 30), + priceTotalLabel.leftAnchor.constraint(equalTo: priceSummary.leftAnchor, constant: 30), + priceTotal.heightAnchor.constraint(equalToConstant: 30),]) + + } + +} + +extension ShoppingCartViewController: UITableViewDataSource { + + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return 5 + } + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let cell = tableView.dequeueReusableCell(withIdentifier: ShoppingCartTableViewCell.reuseID, for: indexPath) as! ShoppingCartTableViewCell + + cell.heightAnchor.constraint(equalToConstant: 50) + + return cell + } + +} + +extension ShoppingCartViewController: UITableViewDelegate { + +} diff --git a/FoodApp/FoodApp/Controllers/Tabs/ShoppingCartViewController.swift.orig b/FoodApp/FoodApp/Controllers/Tabs/ShoppingCartViewController.swift.orig new file mode 100644 index 0000000..024a8df --- /dev/null +++ b/FoodApp/FoodApp/Controllers/Tabs/ShoppingCartViewController.swift.orig @@ -0,0 +1,88 @@ +// +// ShoppingCartViewController.swift +// FoodApp +// +// Created by gnoa001 on 3/15/19. +// Copyright © 2019 SparkDev. All rights reserved. +// + +import UIKit + +class ShoppingCartViewController: UIViewController { + + lazy var shoppingCart: UITableView = { + let tableView = UITableView(frame: .zero) + tableView.translatesAutoresizingMaskIntoConstraints = false + tableView.allowsSelection = false + tableView.delegate = self + tableView.dataSource = self + + return tableView + }() + + lazy var priceSummary: UIView = { + let view = UIView(frame: .zero) + view.translatesAutoresizingMaskIntoConstraints = false + view.backgroundColor = .orange + + return view + }() + + init() { + super.init(nibName: nil, bundle: nil) + + title = "Shopping Cart" + navigationItem.title = "Shopping Cart" + } + + required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + override func viewDidLoad() { + super.viewDidLoad() + +// view.backgroundColor = .white + + shoppingCart.register(UINib(nibName: ShoppingCartTableViewCell.reuseID, bundle: nil), forCellReuseIdentifier: ShoppingCartTableViewCell.reuseID) + + view.addSubview(shoppingCart) + view.addSubview(priceSummary) + + view.addConstraints([ + shoppingCart.topAnchor.constraint(equalTo: view.topAnchor), + shoppingCart.bottomAnchor.constraint(equalTo: priceSummary.topAnchor), + shoppingCart.leftAnchor.constraint(equalTo: view.leftAnchor), + shoppingCart.rightAnchor.constraint(equalTo: view.rightAnchor), + priceSummary.heightAnchor.constraint(equalTo: view.heightAnchor, multiplier: 0.2), + priceSummary.topAnchor.constraint(equalTo: shoppingCart.bottomAnchor), + priceSummary.bottomAnchor.constraint(equalTo: view.bottomAnchor), + priceSummary.leftAnchor.constraint(equalTo: view.leftAnchor), + priceSummary.rightAnchor.constraint(equalTo: view.rightAnchor),]) + + } +<<<<<<< HEAD:FoodApp/FoodApp/Controllers/Tabs/ShoppingCartViewController.swift +======= + +} + +extension ShoppingCartViewController: UITableViewDataSource { + + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + return 5 + } + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let cell = tableView.dequeueReusableCell(withIdentifier: ShoppingCartTableViewCell.reuseID, for: indexPath) as! ShoppingCartTableViewCell + + cell.heightAnchor.constraint(equalToConstant: 50) + + return cell + } + +} + +extension ShoppingCartViewController: UITableViewDelegate { + +>>>>>>> e52f18c2553988c046c489e0ecf20b0cf96fe655:FoodApp/FoodApp/Controllers/ShoppingCartViewController.swift +} diff --git a/FoodApp/FoodApp/Extensions.swift b/FoodApp/FoodApp/Extensions.swift new file mode 100644 index 0000000..2ef0d3a --- /dev/null +++ b/FoodApp/FoodApp/Extensions.swift @@ -0,0 +1,42 @@ +// +// Extensions.swift +// FoodApp +// +// Created by gnoa001 on 3/18/19. +// Copyright © 2019 SparkDev. All rights reserved. +// + +import Foundation +import UIKit + +extension UIColor { + static let customGray = UIColor(red: 0.93, green: 0.93, blue: 0.93, alpha: 1) + + static let customOrange = UIColor(red: 241.0 / 255.0, green: 81 / 255.0, blue: 34.0 / 255.0, alpha: 1) + + static let customRed = UIColor(red: 230 / 255.0, green: 0, blue: 0, alpha: 1.0) +} + +extension UIView { + func fadeTransition(_ duration:CFTimeInterval) { + let animation = CATransition() + animation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut) + animation.type = CATransitionType.fade + animation.duration = duration + layer.add(animation, forKey: CATransitionType.fade.rawValue) + } +} + +extension UIImageView { + public func maskCircle(anyImage: UIImage) { + self.contentMode = UIView.ContentMode.scaleAspectFill + self.layer.cornerRadius = self.frame.height / 2 + self.layer.masksToBounds = false + self.clipsToBounds = true + + // make square(* must to make circle), + // resize(reduce the kilobyte) and + // fix rotation. + self.image = anyImage + } +} diff --git a/FoodApp/FoodApp/GoogleService-Info.plist b/FoodApp/FoodApp/GoogleService-Info.plist new file mode 100644 index 0000000..8e0b35c --- /dev/null +++ b/FoodApp/FoodApp/GoogleService-Info.plist @@ -0,0 +1,40 @@ + + + + + AD_UNIT_ID_FOR_BANNER_TEST + ca-app-pub-3940256099942544/2934735716 + AD_UNIT_ID_FOR_INTERSTITIAL_TEST + ca-app-pub-3940256099942544/4411468910 + CLIENT_ID + 469909744406-u7oerhu00uo14d32l545jr0jeo65bks7.apps.googleusercontent.com + REVERSED_CLIENT_ID + com.googleusercontent.apps.469909744406-u7oerhu00uo14d32l545jr0jeo65bks7 + API_KEY + AIzaSyDJW0l91etbaYyIbguESgYPVGG1bAe2Bh4 + GCM_SENDER_ID + 469909744406 + PLIST_VERSION + 1 + BUNDLE_ID + com.SparkDev.FoodApp + PROJECT_ID + foodapp-eeb94 + STORAGE_BUCKET + foodapp-eeb94.appspot.com + IS_ADS_ENABLED + + IS_ANALYTICS_ENABLED + + IS_APPINVITE_ENABLED + + IS_GCM_ENABLED + + IS_SIGNIN_ENABLED + + GOOGLE_APP_ID + 1:469909744406:ios:9a38839a65f73053 + DATABASE_URL + https://foodapp-eeb94.firebaseio.com + + \ No newline at end of file diff --git a/FoodApp/FoodApp/Info.plist b/FoodApp/FoodApp/Info.plist index 16be3b6..154c4d7 100644 --- a/FoodApp/FoodApp/Info.plist +++ b/FoodApp/FoodApp/Info.plist @@ -22,8 +22,6 @@ UILaunchStoryboardName LaunchScreen - UIMainStoryboardFile - Main UIRequiredDeviceCapabilities armv7 @@ -31,8 +29,7 @@ UISupportedInterfaceOrientations UIInterfaceOrientationPortrait - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight + UIInterfaceOrientationPortraitUpsideDown UISupportedInterfaceOrientations~ipad diff --git a/FoodApp/FoodApp/Models/FirebaseAPI.swift b/FoodApp/FoodApp/Models/FirebaseAPI.swift new file mode 100644 index 0000000..4d8b5a9 --- /dev/null +++ b/FoodApp/FoodApp/Models/FirebaseAPI.swift @@ -0,0 +1,143 @@ +// +// FirebaseAPI.swift +// FoodApp +// +// Created by Cassandra Zuria on 3/30/19. +// Copyright © 2019 SparkDev. All rights reserved. +// + +import Foundation +import Firebase +import CodableFirebase + +class FirebaseAPI { + + private let firestore = Firestore.firestore() + + public func loginUser(email: String, password: String, completion: @escaping (Error?, User?) -> Void) { + + Auth.auth().signIn(withEmail: email, password: password) { (authDataResult, error) in + + if error != nil { + completion(error, nil) + return + } + + if let user = authDataResult?.user { + completion(nil, user) + return + } + } + } + + public func registerUser(profile: UserProfile, password: String, completion: @escaping(Error?,User?)-> Void){ + + Auth.auth().createUser(withEmail: profile.email, password: password) { (authResult, error) in + + if error != nil{ + completion(error,nil) + return + } + + if let user = authResult?.user{ + + let documentRef = self.firestore.collection("Users").document(user.uid) + var dictionary = profile.dictionary + dictionary.updateValue(documentRef.documentID, forKey:"id") + documentRef.setData(dictionary) + completion(nil,user) + return + } + } + } + + public func getMenuCategories(completion: @escaping ([MenuCategory], Error?) -> Void) { + + let menuCategoriesRef = firestore.collection("Categories") + + + menuCategoriesRef.getDocuments() { (querySnapshot, err) in + + if err != nil { + + print("Error getting documents: \(err)") + completion([], err) + + } else { + + do { + + var menuCategories = [MenuCategory]() + + for document in querySnapshot!.documents { + + let dict = document.data() + let data = try JSONSerialization.data(withJSONObject: dict, options: []) + let category = try JSONDecoder().decode(MenuCategory.self, from: data) + menuCategories.append(category) + + } + + completion(menuCategories, nil) + + } catch { + + print(err) + + } + + } + } + } + + public func getMenuItems(menuCategory: MenuCategory, completion: @escaping ([MenuItem], Error?) -> Void) { + + let menuItemsRef = firestore.collection("Foods") + + menuItemsRef.whereField("category", arrayContains: menuCategory.categoryId) + .getDocuments() { (querySnapshot, err) in + +// if let err = err { +// print("Error getting documents: \(err)") +// } else { +// for document in querySnapshot!.documents { +// print("\(document.documentID) => \(document.data())") +// } +// } + + if err != nil { + + print("Error getting documents: \(err)") + completion([], err) + + } else { + + do { + + var menuItems = [MenuItem]() + + for document in querySnapshot!.documents { + + let dict = document.data() + + let menuItem = try FirestoreDecoder().decode(MenuItem.self, from: dict) + print("Menu item: \(menuItem)") + + menuItems.append(menuItem) + + } + + completion(menuItems, nil) + + } catch { + + print(err) + + } + + } + } + + } + } + diff --git a/FoodApp/FoodApp/Models/MenuCategory.swift b/FoodApp/FoodApp/Models/MenuCategory.swift new file mode 100644 index 0000000..1cd8806 --- /dev/null +++ b/FoodApp/FoodApp/Models/MenuCategory.swift @@ -0,0 +1,25 @@ +// +// MenuCategory.swift +// FoodApp +// +// Created by Cassandra Zuria on 3/30/19. +// Copyright © 2019 SparkDev. All rights reserved. +// + +import Foundation + +struct MenuCategory: Codable { + + let categoryId: String + var menuItemsId: [String]? + + init(categoryId: String) { + self.categoryId = categoryId + } + + var dictionary: [String: Any] { + var dictionary = [String: Any]() + dictionary["categoryId"] = categoryId + return dictionary + } +} diff --git a/FoodApp/FoodApp/Models/MenuItem.swift b/FoodApp/FoodApp/Models/MenuItem.swift new file mode 100644 index 0000000..2c3f854 --- /dev/null +++ b/FoodApp/FoodApp/Models/MenuItem.swift @@ -0,0 +1,55 @@ +// +// MenuItem.swift +// FoodApp +// +// Created by gnoa001 on 3/15/19. +// Copyright © 2019 SparkDev. All rights reserved. +// + +import Foundation + +struct MenuItem: Codable { + + let id: String + var category: [String]? + var name: String? + var description: String? + var foodImageUrl: String? + var rating: String? + var price: String? + var completionTime: String? + var isVegan: Bool? + var reviewsRefId: String? + var latestReview: Review? + + init(id: String, category: [String], name: String, description: String, foodImageUrl: String, rating: String, price: String, completionTime: String, isVegan: Bool, reviewsRefId: String, latestReview: Review) { + self.id = id + self.category = category + self.name = name + self.description = description + self.foodImageUrl = foodImageUrl + self.rating = rating + self.price = price + self.completionTime = completionTime + self.isVegan = isVegan + self.reviewsRefId = reviewsRefId + self.latestReview = latestReview + } + + var dictionary: [String: Any] { + var dictionary = [String: Any]() + dictionary["id"] = id + dictionary["category"] = category + dictionary["name"] = name + dictionary["description"] = description + dictionary["foodImageUrl"] = foodImageUrl + dictionary["rating"] = rating + dictionary["price"] = price + dictionary["completionTime"] = completionTime + dictionary["isVegan"] = isVegan + dictionary["reviewsRefId"] = reviewsRefId + dictionary["latestReview"] = latestReview + + return dictionary + } +} diff --git a/FoodApp/FoodApp/Models/Review.swift b/FoodApp/FoodApp/Models/Review.swift new file mode 100644 index 0000000..bd531f0 --- /dev/null +++ b/FoodApp/FoodApp/Models/Review.swift @@ -0,0 +1,38 @@ +// +// Review.swift +// FoodApp +// +// Created by Cassandra Zuria on 4/2/19. +// Copyright © 2019 SparkDev. All rights reserved. +// + +import Foundation +import Firebase +import CodableFirebase + +extension Timestamp: TimestampType {} + +struct Review: Codable { + + var timestamp: Timestamp + var reviewMsg: String + var reviewerId: String + var reviewerName: String + var foodId: String + var rating: Double + + + var dictionary: [String: Any] { + do { + let jsonEncoder = JSONEncoder() + jsonEncoder.dateEncodingStrategy = .secondsSince1970 + let jsonData = try jsonEncoder.encode(self) + var json = try JSONSerialization.jsonObject(with: jsonData, options: []) as! [String: Any] + json["timestamp"] = timestamp + return json + } catch { + print("Error converting to json \(error.localizedDescription)") + return [:] + } + } +} diff --git a/FoodApp/FoodApp/Models/UserProfile.swift b/FoodApp/FoodApp/Models/UserProfile.swift new file mode 100644 index 0000000..50ebf7b --- /dev/null +++ b/FoodApp/FoodApp/Models/UserProfile.swift @@ -0,0 +1,41 @@ +// +// UserProfile.swift +// FoodApp +// +// Created by Cassandra Zuria on 3/31/19. +// Copyright © 2019 SparkDev. All rights reserved. +// + +import Foundation + +struct UserProfile: Codable { + var firstName: String + var lastName: String + var email: String + var address: String + var city: String + var state: String + var zipCode: String + var fullAddress: String + var preferences: [String] + var ordersRef: String + var profileImageUrl: String? + + static var currentUserProfile: UserProfile? + + var dictionary: [String: Any] { + var dictionary = [String: Any]() + dictionary["firstName"] = firstName + dictionary["lastName"] = lastName + dictionary["email"] = email + dictionary["address"] = address + dictionary["city"] = city + dictionary["state"] = state + dictionary["zipCode"] = zipCode + dictionary["fullAddress"] = fullAddress + dictionary["preferences"] = preferences + dictionary["profileImageUrl"] = profileImageUrl + return dictionary + } + +} diff --git a/FoodApp/FoodApp/ViewController.swift b/FoodApp/FoodApp/ViewController.swift deleted file mode 100644 index a479f34..0000000 --- a/FoodApp/FoodApp/ViewController.swift +++ /dev/null @@ -1,20 +0,0 @@ -// -// ViewController.swift -// FoodApp -// -// Created by Cassandra Zuria on 2/12/19. -// Copyright © 2019 SparkDev. All rights reserved. -// - -import UIKit - -class ViewController: UIViewController { - - override func viewDidLoad() { - super.viewDidLoad() - // Do any additional setup after loading the view, typically from a nib. - } - - -} - diff --git a/FoodApp/FoodApp/Views/CategoriesCollectionViewCell.swift b/FoodApp/FoodApp/Views/CategoriesCollectionViewCell.swift new file mode 100644 index 0000000..0cb8ca1 --- /dev/null +++ b/FoodApp/FoodApp/Views/CategoriesCollectionViewCell.swift @@ -0,0 +1,58 @@ +// +// CustomCategoriesCell.swift +// FoodApp +// +// Created by gnoa001 on 3/23/19. +// Copyright © 2019 SparkDev. All rights reserved. +// + +import Foundation +import UIKit + +class CategoriesCollectionViewCell: UICollectionViewCell { + + // MARK: Reuse ID + static let reuseID = String(describing: CategoriesCollectionViewCell.self) + + public lazy var categoryTitleLabel: UILabel = { + let label = UILabel() + label.translatesAutoresizingMaskIntoConstraints = false + label.text = "Y" + contentView.addSubview(label) + return label + }() + + // MARK: Lifecycle + override init(frame: CGRect) { + super.init(frame: frame) + + setupUI() + } + + required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + // MARK: Setup + func setupUI() { + let margins = contentView.layoutMarginsGuide + contentView.addConstraints([ + categoryTitleLabel.topAnchor.constraint(equalTo: margins.topAnchor), + categoryTitleLabel.leadingAnchor.constraint(greaterThanOrEqualTo: margins.leadingAnchor), + categoryTitleLabel.trailingAnchor.constraint(lessThanOrEqualTo: margins.trailingAnchor), + categoryTitleLabel.bottomAnchor.constraint(equalTo: margins.bottomAnchor) + ]) + + layer.shadowColor = UIColor.black.cgColor + layer.shadowOffset = CGSize(width: 0, height: 1.0) + layer.shadowRadius = 3.0 + layer.shadowOpacity = 0.3 + } + + var category: MenuCategory? { + didSet { + categoryTitleLabel.text = category?.categoryId + } + } +} + diff --git a/FoodApp/FoodApp/Views/MenuItemCollectionViewCell.swift b/FoodApp/FoodApp/Views/MenuItemCollectionViewCell.swift new file mode 100644 index 0000000..e34d0a2 --- /dev/null +++ b/FoodApp/FoodApp/Views/MenuItemCollectionViewCell.swift @@ -0,0 +1,76 @@ +// +// CustomCollectionViewCell.swift +// FoodApp +// +// Created by gnoa001 on 2/21/19. +// Copyright © 2019 SparkDev. All rights reserved. +// + +import UIKit + +class MenuItemCollectionViewCell: UICollectionViewCell { + + // MARK: Reuse ID + static let reuseID = String(describing: MenuItemCollectionViewCell.self) + + // MARK: Outlets + @IBOutlet weak var foodItemImageView: UIImageView! + @IBOutlet weak var foodTitleLabel: UILabel! + @IBOutlet weak var foodTypeLabel: UILabel! + @IBOutlet weak var estimatedTimeLabel: UILabel! + @IBOutlet weak var ratingLabel: UILabel! + @IBOutlet weak var priceLabel: UILabel! + + // MARK: Lifecycle + override func awakeFromNib() { + super.awakeFromNib() + + setupUI() + } + + // MARK: Setup + func setupUI() { + backgroundColor = .white + + setupImageView() + setupLayer() + setupFonts() + + foodTypeLabel.textColor = UIColor.gray + } + + func setupImageView() { + foodItemImageView.layer.cornerRadius = 16.0 + foodItemImageView.layer.masksToBounds = true + foodItemImageView.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner] + foodItemImageView.contentMode = .scaleAspectFill + } + + func setupLayer() { + layer.shadowColor = UIColor.black.cgColor + layer.shadowOpacity = 0.3 + layer.shadowOffset = CGSize(width: 0, height: 3.0) + layer.shadowRadius = 5 + layer.cornerRadius = 16 + layer.masksToBounds = false + } + + func setupFonts() { + foodTitleLabel.font = UIFont.preferredFont(forTextStyle: .headline) + foodTypeLabel.font = UIFont.preferredFont(forTextStyle: .caption1) + estimatedTimeLabel.font = UIFont.preferredFont(forTextStyle: .footnote) + ratingLabel.font = UIFont.preferredFont(forTextStyle: .footnote) + priceLabel.font = UIFont.preferredFont(forTextStyle: .footnote) + } + + var item: MenuItem? { + didSet { + foodTitleLabel.text = item?.name + foodTypeLabel.text = "Category" + estimatedTimeLabel.text = item?.completionTime + ratingLabel.text = item?.rating + priceLabel.text = item?.price + } + } + +} diff --git a/FoodApp/FoodApp/Views/MenuItemCollectionViewCell.swift.orig b/FoodApp/FoodApp/Views/MenuItemCollectionViewCell.swift.orig new file mode 100644 index 0000000..a799268 --- /dev/null +++ b/FoodApp/FoodApp/Views/MenuItemCollectionViewCell.swift.orig @@ -0,0 +1,78 @@ +// +// CustomCollectionViewCell.swift +// FoodApp +// +// Created by gnoa001 on 2/21/19. +// Copyright © 2019 SparkDev. All rights reserved. +// + +import UIKit + +class MenuItemCollectionViewCell: UICollectionViewCell { + + // MARK: Reuse ID + static let reuseID = String(describing: MenuItemCollectionViewCell.self) + + // MARK: Outlets + @IBOutlet weak var foodItemImageView: UIImageView! + @IBOutlet weak var foodTitleLabel: UILabel! + @IBOutlet weak var foodTypeLabel: UILabel! + @IBOutlet weak var estimatedTimeLabel: UILabel! + @IBOutlet weak var ratingLabel: UILabel! + @IBOutlet weak var priceLabel: UILabel! + + // MARK: Lifecycle + override func awakeFromNib() { + super.awakeFromNib() + + setupUI() + } + + // MARK: Setup + func setupUI() { + backgroundColor = .white + + setupImageView() + setupLayer() + setupFonts() + + foodTypeLabel.textColor = UIColor.gray + } + + func setupImageView() { + foodItemImageView.layer.cornerRadius = 16.0 + foodItemImageView.layer.masksToBounds = true + foodItemImageView.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner] + foodItemImageView.contentMode = .scaleAspectFill + } + + func setupLayer() { + layer.shadowColor = UIColor.black.cgColor + layer.shadowOpacity = 0.3 + layer.shadowOffset = CGSize(width: 0, height: 3.0) + layer.shadowRadius = 5 + layer.cornerRadius = 16 + layer.masksToBounds = false + } + +<<<<<<< HEAD + func setupFonts() { + foodTitleLabel.font = UIFont.preferredFont(forTextStyle: .headline) + foodTypeLabel.font = UIFont.preferredFont(forTextStyle: .caption1) + estimatedTimeLabel.font = UIFont.preferredFont(forTextStyle: .footnote) + ratingLabel.font = UIFont.preferredFont(forTextStyle: .footnote) + priceLabel.font = UIFont.preferredFont(forTextStyle: .footnote) + } +======= + var item: MenuItem? { + didSet { + foodTitleLabel.text = item?.name + foodTypeLabel.text = "Category" + estimatedTimeLabel.text = item?.completionTime + ratingLabel.text = item?.rating + priceLabel.text = item?.price + } + } + +>>>>>>> e52f18c2553988c046c489e0ecf20b0cf96fe655 +} diff --git a/FoodApp/FoodApp/Views/MenuItemCollectionViewCell.xib b/FoodApp/FoodApp/Views/MenuItemCollectionViewCell.xib new file mode 100644 index 0000000..8111862 --- /dev/null +++ b/FoodApp/FoodApp/Views/MenuItemCollectionViewCell.xib @@ -0,0 +1,97 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/FoodApp/FoodApp/Views/RatingsTableViewCell.swift b/FoodApp/FoodApp/Views/RatingsTableViewCell.swift new file mode 100644 index 0000000..9e3f2ab --- /dev/null +++ b/FoodApp/FoodApp/Views/RatingsTableViewCell.swift @@ -0,0 +1,48 @@ +// +// RatingsTableViewCell.swift +// FoodApp +// +// Created by gnoa001 on 3/30/19. +// Copyright © 2019 SparkDev. All rights reserved. +// + +import UIKit + +class RatingsTableViewCell: UITableViewCell { + + // MARK: Outlets + @IBOutlet weak var profileImageView: UIImageView! + @IBOutlet weak var ratingTitleLabel: UILabel! + @IBOutlet weak var ratingLabel: UILabel! + @IBOutlet weak var dateLabel: UILabel! + @IBOutlet weak var nameLabel: UILabel! + @IBOutlet weak var textView: UITextView! + + // MARK: Lifecycle + override func awakeFromNib() { + super.awakeFromNib() + + setupUI() + } + + // MARK: Setup + func setupUI() { + ratingTitleLabel.font = UIFont.preferredFont(forTextStyle: .footnote) + ratingLabel.font = UIFont.preferredFont(forTextStyle: .caption2) + dateLabel.font = UIFont.preferredFont(forTextStyle: .caption2) + nameLabel.font = UIFont.preferredFont(forTextStyle: .caption2) + textView.font = UIFont.preferredFont(forTextStyle: .caption1) + + textView.isUserInteractionEnabled = false + textView.isScrollEnabled = false + + ratingTitleLabel.text = "Amazing!" + ratingLabel.text = "⭐️⭐️⭐️⭐️" + dateLabel.text = "9 Mar" + nameLabel.text = "Quinten Kortum" + profileImageView.image = #imageLiteral(resourceName: "woman") + + dateLabel.textColor = .lightGray + nameLabel.textColor = .lightGray + } +} diff --git a/FoodApp/FoodApp/Views/RatingsTableViewCell.xib b/FoodApp/FoodApp/Views/RatingsTableViewCell.xib new file mode 100644 index 0000000..af16185 --- /dev/null +++ b/FoodApp/FoodApp/Views/RatingsTableViewCell.xib @@ -0,0 +1,98 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/FoodApp/FoodApp/Views/ShoppingCartTableViewCell.swift b/FoodApp/FoodApp/Views/ShoppingCartTableViewCell.swift new file mode 100644 index 0000000..dd71986 --- /dev/null +++ b/FoodApp/FoodApp/Views/ShoppingCartTableViewCell.swift @@ -0,0 +1,28 @@ +// +// ShoppingCartTableViewCell.swift +// FoodApp +// +// Created by Cassandra Zuria on 4/1/19. +// Copyright © 2019 SparkDev. All rights reserved. +// + +import UIKit + +class ShoppingCartTableViewCell: UITableViewCell { + + static let reuseID = String(describing: ShoppingCartTableViewCell.self) + + @IBOutlet weak var menuItemTitle: UILabel! + + override func awakeFromNib() { + super.awakeFromNib() + + } + + override func setSelected(_ selected: Bool, animated: Bool) { + super.setSelected(selected, animated: animated) + + // Configure the view for the selected state + } + +} diff --git a/FoodApp/FoodApp/Views/ShoppingCartTableViewCell.xib b/FoodApp/FoodApp/Views/ShoppingCartTableViewCell.xib new file mode 100644 index 0000000..d3ad1f1 --- /dev/null +++ b/FoodApp/FoodApp/Views/ShoppingCartTableViewCell.xib @@ -0,0 +1,87 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/FoodApp/Podfile b/FoodApp/Podfile index 18acf9d..1cc175e 100644 --- a/FoodApp/Podfile +++ b/FoodApp/Podfile @@ -1,10 +1,16 @@ -# Uncomment the next line to define a global platform for your project -# platform :ios, '9.0' +platform :ios, '12.0' target 'FoodApp' do # Comment the next line if you're not using Swift and don't want to use dynamic frameworks use_frameworks! # Pods for FoodApp + pod 'Firebase/Core' + pod 'Firebase/Auth' + pod 'Firebase/Firestore' + pod 'Firebase/Storage' + pod 'SkyFloatingLabelTextField', '~> 3.0' + pod 'IQKeyboardManagerSwift' + pod 'CodableFirebase' end diff --git a/FoodApp/Podfile.lock b/FoodApp/Podfile.lock new file mode 100644 index 0000000..db5addb --- /dev/null +++ b/FoodApp/Podfile.lock @@ -0,0 +1,171 @@ +PODS: + - BoringSSL-GRPC (0.0.2): + - BoringSSL-GRPC/Implementation (= 0.0.2) + - BoringSSL-GRPC/Interface (= 0.0.2) + - BoringSSL-GRPC/Implementation (0.0.2): + - BoringSSL-GRPC/Interface (= 0.0.2) + - BoringSSL-GRPC/Interface (0.0.2) + - CodableFirebase (0.2.1) + - Firebase/Auth (5.20.1): + - Firebase/CoreOnly + - FirebaseAuth (= 5.4.2) + - Firebase/Core (5.20.1): + - Firebase/CoreOnly + - FirebaseAnalytics (= 5.8.0) + - Firebase/CoreOnly (5.20.1): + - FirebaseCore (= 5.4.1) + - Firebase/Firestore (5.20.1): + - Firebase/CoreOnly + - FirebaseFirestore (= 1.2.1) + - Firebase/Storage (5.20.1): + - Firebase/CoreOnly + - FirebaseStorage (= 3.1.1) + - FirebaseAnalytics (5.8.0): + - FirebaseCore (~> 5.4) + - FirebaseInstanceID (~> 3.8) + - GoogleAppMeasurement (= 5.8.0) + - GoogleUtilities/AppDelegateSwizzler (~> 5.2) + - GoogleUtilities/MethodSwizzler (~> 5.2) + - GoogleUtilities/Network (~> 5.2) + - "GoogleUtilities/NSData+zlib (~> 5.2)" + - nanopb (~> 0.3) + - FirebaseAuth (5.4.2): + - FirebaseAuthInterop (~> 1.0) + - FirebaseCore (~> 5.2) + - GoogleUtilities/Environment (~> 5.2) + - GTMSessionFetcher/Core (~> 1.1) + - FirebaseAuthInterop (1.0.0) + - FirebaseCore (5.4.1): + - GoogleUtilities/Environment (~> 5.2) + - GoogleUtilities/Logger (~> 5.2) + - FirebaseFirestore (1.2.1): + - FirebaseAuthInterop (~> 1.0) + - FirebaseCore (~> 5.2) + - FirebaseFirestore/abseil-cpp (= 1.2.1) + - "gRPC-C++ (= 0.0.6)" + - leveldb-library (~> 1.20) + - nanopb (~> 0.3.901) + - Protobuf (~> 3.1) + - FirebaseFirestore/abseil-cpp (1.2.1): + - FirebaseAuthInterop (~> 1.0) + - FirebaseCore (~> 5.2) + - "gRPC-C++ (= 0.0.6)" + - leveldb-library (~> 1.20) + - nanopb (~> 0.3.901) + - Protobuf (~> 3.1) + - FirebaseInstanceID (3.8.1): + - FirebaseCore (~> 5.2) + - GoogleUtilities/Environment (~> 5.2) + - GoogleUtilities/UserDefaults (~> 5.2) + - FirebaseStorage (3.1.1): + - FirebaseAuthInterop (~> 1.0) + - FirebaseCore (~> 5.2) + - GTMSessionFetcher/Core (~> 1.1) + - GoogleAppMeasurement (5.8.0): + - GoogleUtilities/AppDelegateSwizzler (~> 5.2) + - GoogleUtilities/MethodSwizzler (~> 5.2) + - GoogleUtilities/Network (~> 5.2) + - "GoogleUtilities/NSData+zlib (~> 5.2)" + - nanopb (~> 0.3) + - GoogleUtilities/AppDelegateSwizzler (5.5.0): + - GoogleUtilities/Environment + - GoogleUtilities/Logger + - GoogleUtilities/Network + - GoogleUtilities/Environment (5.5.0) + - GoogleUtilities/Logger (5.5.0): + - GoogleUtilities/Environment + - GoogleUtilities/MethodSwizzler (5.5.0): + - GoogleUtilities/Logger + - GoogleUtilities/Network (5.5.0): + - GoogleUtilities/Logger + - "GoogleUtilities/NSData+zlib" + - GoogleUtilities/Reachability + - "GoogleUtilities/NSData+zlib (5.5.0)" + - GoogleUtilities/Reachability (5.5.0): + - GoogleUtilities/Logger + - GoogleUtilities/UserDefaults (5.5.0): + - GoogleUtilities/Logger + - "gRPC-C++ (0.0.6)": + - "gRPC-C++/Implementation (= 0.0.6)" + - "gRPC-C++/Interface (= 0.0.6)" + - "gRPC-C++/Implementation (0.0.6)": + - "gRPC-C++/Interface (= 0.0.6)" + - gRPC-Core (= 1.17.0) + - nanopb (~> 0.3) + - "gRPC-C++/Interface (0.0.6)" + - gRPC-Core (1.17.0): + - gRPC-Core/Implementation (= 1.17.0) + - gRPC-Core/Interface (= 1.17.0) + - gRPC-Core/Implementation (1.17.0): + - BoringSSL-GRPC (= 0.0.2) + - gRPC-Core/Interface (= 1.17.0) + - nanopb (~> 0.3) + - gRPC-Core/Interface (1.17.0) + - GTMSessionFetcher/Core (1.2.1) + - IQKeyboardManagerSwift (6.2.1) + - leveldb-library (1.20) + - nanopb (0.3.901): + - nanopb/decode (= 0.3.901) + - nanopb/encode (= 0.3.901) + - nanopb/decode (0.3.901) + - nanopb/encode (0.3.901) + - Protobuf (3.7.0) + - SkyFloatingLabelTextField (3.6.0) + +DEPENDENCIES: + - CodableFirebase + - Firebase/Auth + - Firebase/Core + - Firebase/Firestore + - Firebase/Storage + - IQKeyboardManagerSwift + - SkyFloatingLabelTextField (~> 3.0) + +SPEC REPOS: + https://github.com/cocoapods/specs.git: + - BoringSSL-GRPC + - CodableFirebase + - Firebase + - FirebaseAnalytics + - FirebaseAuth + - FirebaseAuthInterop + - FirebaseCore + - FirebaseFirestore + - FirebaseInstanceID + - FirebaseStorage + - GoogleAppMeasurement + - GoogleUtilities + - "gRPC-C++" + - gRPC-Core + - GTMSessionFetcher + - IQKeyboardManagerSwift + - leveldb-library + - nanopb + - Protobuf + - SkyFloatingLabelTextField + +SPEC CHECKSUMS: + BoringSSL-GRPC: 2a230d9cd93e7ce39916044f645cebb31f37dde6 + CodableFirebase: 0bf201991eeec35eb9fcd987d271ea463cf34a80 + Firebase: 2f5235e62f141cb86181c3af0dfe4509706351ac + FirebaseAnalytics: fd72a26bf8dac84cefba2f0864366f718555a5b0 + FirebaseAuth: dd7bbf03a5aee0eafb3a1aee4d2812bd74bac890 + FirebaseAuthInterop: 0ffa57668be100582bb7643d4fcb7615496c41fc + FirebaseCore: f1a9a8be1aee4bf71a2fc0f4096df6788bdfda61 + FirebaseFirestore: faca891c0f0d1d6c10c793473e2f6a29d75014b5 + FirebaseInstanceID: a122b0c258720cf250551bb2bedf48c699f80d90 + FirebaseStorage: 6162ef4322502b818d9de0ec552f5226d283de43 + GoogleAppMeasurement: 1624046ab1bcc5e170061a56ef5679000b079c8e + GoogleUtilities: 6481e6318c5fcabaaa8513ef8120f329055d7c10 + "gRPC-C++": e76441995900ac90e9bd98644ab4733f12521edf + gRPC-Core: 4028031ed2c5267cca0d846c876d8046b1ecb9b6 + GTMSessionFetcher: 32aeca0aa144acea523e1c8e053089dec2cb98ca + IQKeyboardManagerSwift: 0f0ae8935360b4003e6ea1ac7c19898f01e2f7c7 + leveldb-library: 08cba283675b7ed2d99629a4bc5fd052cd2bb6a5 + nanopb: 2901f78ea1b7b4015c860c2fdd1ea2fee1a18d48 + Protobuf: 7a877b7f3e5964e3fce995e2eb323dbc6831bb5a + SkyFloatingLabelTextField: 38164979b79512f9ff9288ad8acfc4bbf5d843e3 + +PODFILE CHECKSUM: f3910444bfcb5d9c18cf782c9ae7dd9de6bb7303 + +COCOAPODS: 1.6.0 diff --git a/FoodApp/Pods/BoringSSL-GRPC/LICENSE b/FoodApp/Pods/BoringSSL-GRPC/LICENSE new file mode 100644 index 0000000..49c41fa --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/LICENSE @@ -0,0 +1,251 @@ +BoringSSL is a fork of OpenSSL. As such, large parts of it fall under OpenSSL +licensing. Files that are completely new have a Google copyright and an ISC +license. This license is reproduced at the bottom of this file. + +Contributors to BoringSSL are required to follow the CLA rules for Chromium: +https://cla.developers.google.com/clas + +Files in third_party/ have their own licenses, as described therein. The MIT +license, for third_party/fiat, which, unlike other third_party directories, is +compiled into non-test libraries, is included below. + +The OpenSSL toolkit stays under a dual license, i.e. both the conditions of the +OpenSSL License and the original SSLeay license apply to the toolkit. See below +for the actual license texts. Actually both licenses are BSD-style Open Source +licenses. In case of any license issues related to OpenSSL please contact +openssl-core@openssl.org. + +The following are Google-internal bug numbers where explicit permission from +some authors is recorded for use of their work. (This is purely for our own +record keeping.) + 27287199 + 27287880 + 27287883 + + OpenSSL License + --------------- + +/* ==================================================================== + * Copyright (c) 1998-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). + * + */ + + Original SSLeay License + ----------------------- + +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] + */ + + +ISC license used for completely new code in BoringSSL: + +/* Copyright (c) 2015, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + + +The code in third_party/fiat carries the MIT license: + +Copyright (c) 2015-2016 the fiat-crypto authors (see +https://github.com/mit-plv/fiat-crypto/blob/master/AUTHORS). + +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. + + +Licenses for support code +------------------------- + +Parts of the TLS test suite are under the Go license. This code is not included +in BoringSSL (i.e. libcrypto and libssl) when compiled, however, so +distributing code linked against BoringSSL does not trigger this license: + +Copyright (c) 2009 The Go Authors. 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 Google Inc. 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 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. + + +BoringSSL uses the Chromium test infrastructure to run a continuous build, +trybots etc. The scripts which manage this, and the script for generating build +metadata, are under the Chromium license. Distributing code linked against +BoringSSL does not trigger this license. + +Copyright 2015 The Chromium Authors. 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 Google Inc. 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 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. diff --git a/FoodApp/Pods/BoringSSL-GRPC/README.md b/FoodApp/Pods/BoringSSL-GRPC/README.md new file mode 100644 index 0000000..b28e721 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/README.md @@ -0,0 +1,33 @@ +# BoringSSL + +BoringSSL is a fork of OpenSSL that is designed to meet Google's needs. + +Although BoringSSL is an open source project, it is not intended for general +use, as OpenSSL is. We don't recommend that third parties depend upon it. Doing +so is likely to be frustrating because there are no guarantees of API or ABI +stability. + +Programs ship their own copies of BoringSSL when they use it and we update +everything as needed when deciding to make API changes. This allows us to +mostly avoid compromises in the name of compatibility. It works for us, but it +may not work for you. + +BoringSSL arose because Google used OpenSSL for many years in various ways and, +over time, built up a large number of patches that were maintained while +tracking upstream OpenSSL. As Google's product portfolio became more complex, +more copies of OpenSSL sprung up and the effort involved in maintaining all +these patches in multiple places was growing steadily. + +Currently BoringSSL is the SSL library in Chrome/Chromium, Android (but it's +not part of the NDK) and a number of other apps/programs. + +There are other files in this directory which might be helpful: + + * [PORTING.md](/PORTING.md): how to port OpenSSL-using code to BoringSSL. + * [BUILDING.md](/BUILDING.md): how to build BoringSSL + * [INCORPORATING.md](/INCORPORATING.md): how to incorporate BoringSSL into a project. + * [API-CONVENTIONS.md](/API-CONVENTIONS.md): general API conventions for BoringSSL consumers and developers. + * [STYLE.md](/STYLE.md): rules and guidelines for coding style. + * include/openssl: public headers with API documentation in comments. Also [available online](https://commondatastorage.googleapis.com/chromium-boringssl-docs/headers.html). + * [FUZZING.md](/FUZZING.md): information about fuzzing BoringSSL. + * [CONTRIBUTING.md](/CONTRIBUTING.md): how to contribute to BoringSSL. diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_bitstr.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_bitstr.c new file mode 100644 index 0000000..b650f49 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_bitstr.c @@ -0,0 +1,271 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 + +#include "../internal.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; + OPENSSL_memcpy(p, d, len); + p += len; + if (len > 0) + 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 padding; + + if (len < 1) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_STRING_TOO_SHORT); + goto err; + } + + if (len > INT_MAX) { + OPENSSL_PUT_ERROR(ASN1, 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; + padding = *(p++); + if (padding > 7) { + OPENSSL_PUT_ERROR(ASN1, 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 | padding); /* set */ + + if (len-- > 1) { /* using one because of the bits left byte */ + s = (unsigned char *)OPENSSL_malloc((int)len); + if (s == NULL) { + OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); + goto err; + } + OPENSSL_memcpy(s, p, (int)len); + s[len - 1] &= (0xff << padding); + 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: + 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(a->data, w + 1); + if (c == NULL) { + OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); + return 0; + } + if (w + 1 - a->length > 0) + OPENSSL_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; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_bitstr.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_bitstr.c.grpc_back new file mode 100644 index 0000000..3942638 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_bitstr.c.grpc_back @@ -0,0 +1,271 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 + +#include "../internal.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; + OPENSSL_memcpy(p, d, len); + p += len; + if (len > 0) + 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 padding; + + if (len < 1) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_STRING_TOO_SHORT); + goto err; + } + + if (len > INT_MAX) { + OPENSSL_PUT_ERROR(ASN1, 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; + padding = *(p++); + if (padding > 7) { + OPENSSL_PUT_ERROR(ASN1, 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 | padding); /* set */ + + if (len-- > 1) { /* using one because of the bits left byte */ + s = (unsigned char *)OPENSSL_malloc((int)len); + if (s == NULL) { + OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); + goto err; + } + OPENSSL_memcpy(s, p, (int)len); + s[len - 1] &= (0xff << padding); + 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: + 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(a->data, w + 1); + if (c == NULL) { + OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); + return 0; + } + if (w + 1 - a->length > 0) + OPENSSL_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; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_bool.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_bool.c new file mode 100644 index 0000000..645c034 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_bool.c @@ -0,0 +1,110 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 + +int i2d_ASN1_BOOLEAN(int a, unsigned char **pp) +{ + int r; + unsigned char *p; + + r = ASN1_object_size(0, 1, V_ASN1_BOOLEAN); + if (pp == NULL) + return (r); + p = *pp; + + ASN1_put_object(&p, 0, 1, V_ASN1_BOOLEAN, V_ASN1_UNIVERSAL); + *(p++) = (unsigned char)a; + *pp = p; + 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: + OPENSSL_PUT_ERROR(ASN1, i); + return (ret); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_bool.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_bool.c.grpc_back new file mode 100644 index 0000000..64a079e --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_bool.c.grpc_back @@ -0,0 +1,110 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 + +int i2d_ASN1_BOOLEAN(int a, unsigned char **pp) +{ + int r; + unsigned char *p; + + r = ASN1_object_size(0, 1, V_ASN1_BOOLEAN); + if (pp == NULL) + return (r); + p = *pp; + + ASN1_put_object(&p, 0, 1, V_ASN1_BOOLEAN, V_ASN1_UNIVERSAL); + *(p++) = (unsigned char)a; + *pp = p; + 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: + OPENSSL_PUT_ERROR(ASN1, i); + return (ret); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_d2i_fp.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_d2i_fp.c new file mode 100644 index 0000000..ab54599 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_d2i_fp.c @@ -0,0 +1,297 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 + +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) { + OPENSSL_PUT_ERROR(ASN1, 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) { + OPENSSL_PUT_ERROR(ASN1, 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 + +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; + +#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) { + OPENSSL_PUT_ERROR(ASN1, 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)) { + OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); + goto err; + } + i = BIO_read(in, &(b->data[len]), want); + if ((i < 0) && ((len - off) == 0)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_NOT_ENOUGH_DATA); + goto err; + } + if (i > 0) { + if (len + i < len) { + OPENSSL_PUT_ERROR(ASN1, 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) { + uint32_t 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) { + OPENSSL_PUT_ERROR(ASN1, 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) { + OPENSSL_PUT_ERROR(ASN1, 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)) { + OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); + goto err; + } + want -= chunk; + while (chunk > 0) { + i = BIO_read(in, &(b->data[len]), chunk); + if (i <= 0) { + OPENSSL_PUT_ERROR(ASN1, 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) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_TOO_LONG); + goto err; + } + off += c.slen; + if (eos <= 0) { + break; + } else + want = HEADER_SIZE; + } + } + + if (off > INT_MAX) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_TOO_LONG); + goto err; + } + + *pb = b; + return off; + err: + if (b != NULL) + BUF_MEM_free(b); + return -1; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_d2i_fp.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_d2i_fp.c.grpc_back new file mode 100644 index 0000000..3da6df9 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_d2i_fp.c.grpc_back @@ -0,0 +1,297 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 + +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) { + OPENSSL_PUT_ERROR(ASN1, 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) { + OPENSSL_PUT_ERROR(ASN1, 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 + +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; + +#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) { + OPENSSL_PUT_ERROR(ASN1, 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)) { + OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); + goto err; + } + i = BIO_read(in, &(b->data[len]), want); + if ((i < 0) && ((len - off) == 0)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_NOT_ENOUGH_DATA); + goto err; + } + if (i > 0) { + if (len + i < len) { + OPENSSL_PUT_ERROR(ASN1, 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) { + uint32_t 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) { + OPENSSL_PUT_ERROR(ASN1, 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) { + OPENSSL_PUT_ERROR(ASN1, 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)) { + OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); + goto err; + } + want -= chunk; + while (chunk > 0) { + i = BIO_read(in, &(b->data[len]), chunk); + if (i <= 0) { + OPENSSL_PUT_ERROR(ASN1, 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) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_TOO_LONG); + goto err; + } + off += c.slen; + if (eos <= 0) { + break; + } else + want = HEADER_SIZE; + } + } + + if (off > INT_MAX) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_TOO_LONG); + goto err; + } + + *pb = b; + return off; + err: + if (b != NULL) + BUF_MEM_free(b); + return -1; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_dup.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_dup.c new file mode 100644 index 0000000..272979c --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_dup.c @@ -0,0 +1,111 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 + +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) { + OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); + return (NULL); + } + p = b; + i = i2d(x, &p); + p2 = b; + ret = d2i(NULL, &p2, i); + OPENSSL_free(b); + return (ret); +} + +/* + * 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) { + OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); + return (NULL); + } + p = b; + ret = ASN1_item_d2i(NULL, &p, i, it); + OPENSSL_free(b); + return (ret); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_dup.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_dup.c.grpc_back new file mode 100644 index 0000000..57394f5 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_dup.c.grpc_back @@ -0,0 +1,111 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 + +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) { + OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); + return (NULL); + } + p = b; + i = i2d(x, &p); + p2 = b; + ret = d2i(NULL, &p2, i); + OPENSSL_free(b); + return (ret); +} + +/* + * 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) { + OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); + return (NULL); + } + p = b; + ret = ASN1_item_d2i(NULL, &p, i, it); + OPENSSL_free(b); + return (ret); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_enum.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_enum.c new file mode 100644 index 0000000..5e1fc7a --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_enum.c @@ -0,0 +1,195 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 + +#include "../internal.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) + OPENSSL_memset((char *)a->data, 0, sizeof(long) + 1); + } + if (a->data == NULL) { + OPENSSL_PUT_ERROR(ASN1, 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; + + if (a == NULL) + return (0L); + i = a->type; + if (i == V_ASN1_NEG_ENUMERATED) + neg = 1; + else if (i != V_ASN1_ENUMERATED) + return -1; + + OPENSSL_COMPILE_ASSERT(sizeof(uint64_t) >= sizeof(long), + long_larger_than_uint64_t); + + if (a->length > (int)sizeof(uint64_t)) { + /* hmm... a bit ugly */ + return -1; + } + + uint64_t r64 = 0; + if (a->data != NULL) { + for (i = 0; i < a->length; i++) { + r64 <<= 8; + r64 |= (unsigned char)a->data[i]; + } + + if (r64 > LONG_MAX) { + return -1; + } + } + + long r = (long) r64; + 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) { + OPENSSL_PUT_ERROR(ASN1, ASN1_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) { + OPENSSL_PUT_ERROR(ASN1, 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) + OPENSSL_PUT_ERROR(ASN1, ASN1_R_BN_LIB); + else if (ai->type == V_ASN1_NEG_ENUMERATED) + BN_set_negative(ret, 1); + return (ret); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_enum.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_enum.c.grpc_back new file mode 100644 index 0000000..4a77971 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_enum.c.grpc_back @@ -0,0 +1,195 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 + +#include "../internal.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) + OPENSSL_memset((char *)a->data, 0, sizeof(long) + 1); + } + if (a->data == NULL) { + OPENSSL_PUT_ERROR(ASN1, 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; + + if (a == NULL) + return (0L); + i = a->type; + if (i == V_ASN1_NEG_ENUMERATED) + neg = 1; + else if (i != V_ASN1_ENUMERATED) + return -1; + + OPENSSL_COMPILE_ASSERT(sizeof(uint64_t) >= sizeof(long), + long_larger_than_uint64_t); + + if (a->length > (int)sizeof(uint64_t)) { + /* hmm... a bit ugly */ + return -1; + } + + uint64_t r64 = 0; + if (a->data != NULL) { + for (i = 0; i < a->length; i++) { + r64 <<= 8; + r64 |= (unsigned char)a->data[i]; + } + + if (r64 > LONG_MAX) { + return -1; + } + } + + long r = (long) r64; + 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) { + OPENSSL_PUT_ERROR(ASN1, ASN1_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) { + OPENSSL_PUT_ERROR(ASN1, 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) + OPENSSL_PUT_ERROR(ASN1, ASN1_R_BN_LIB); + else if (ai->type == V_ASN1_NEG_ENUMERATED) + BN_set_negative(ret, 1); + return (ret); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_gentm.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_gentm.c new file mode 100644 index 0000000..326e4eb --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_gentm.c @@ -0,0 +1,261 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 + +#include "asn1_locl.h" + +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; + ASN1_GENERALIZEDTIME *tmps = NULL; + + if (s == NULL) + tmps = ASN1_GENERALIZEDTIME_new(); + else + tmps = s; + if (tmps == NULL) + return NULL; + + 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; + } + + p = (char *)tmps->data; + if ((p == NULL) || ((size_t)tmps->length < len)) { + p = OPENSSL_malloc(len); + if (p == NULL) { + OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); + goto err; + } + OPENSSL_free(tmps->data); + tmps->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); + tmps->length = strlen(p); + tmps->type = V_ASN1_GENERALIZEDTIME; + return tmps; + err: + if (s == NULL) + ASN1_GENERALIZEDTIME_free(tmps); + return NULL; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_gentm.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_gentm.c.grpc_back new file mode 100644 index 0000000..5fcb65b --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_gentm.c.grpc_back @@ -0,0 +1,261 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 + +#include "asn1_locl.h" + +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; + ASN1_GENERALIZEDTIME *tmps = NULL; + + if (s == NULL) + tmps = ASN1_GENERALIZEDTIME_new(); + else + tmps = s; + if (tmps == NULL) + return NULL; + + 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; + } + + p = (char *)tmps->data; + if ((p == NULL) || ((size_t)tmps->length < len)) { + p = OPENSSL_malloc(len); + if (p == NULL) { + OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); + goto err; + } + OPENSSL_free(tmps->data); + tmps->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); + tmps->length = strlen(p); + tmps->type = V_ASN1_GENERALIZEDTIME; + return tmps; + err: + if (s == NULL) + ASN1_GENERALIZEDTIME_free(tmps); + return NULL; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_i2d_fp.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_i2d_fp.c new file mode 100644 index 0000000..61b6e64 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_i2d_fp.c @@ -0,0 +1,150 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 + +int ASN1_i2d_fp(i2d_of_void *i2d, FILE *out, void *x) +{ + BIO *b; + int ret; + + if ((b = BIO_new(BIO_s_file())) == NULL) { + OPENSSL_PUT_ERROR(ASN1, 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); +} + +int ASN1_i2d_bio(i2d_of_void *i2d, BIO *out, void *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) { + OPENSSL_PUT_ERROR(ASN1, 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); +} + +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) { + OPENSSL_PUT_ERROR(ASN1, 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); +} + +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) { + OPENSSL_PUT_ERROR(ASN1, 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); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_i2d_fp.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_i2d_fp.c.grpc_back new file mode 100644 index 0000000..7b76d0c --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_i2d_fp.c.grpc_back @@ -0,0 +1,150 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 + +int ASN1_i2d_fp(i2d_of_void *i2d, FILE *out, void *x) +{ + BIO *b; + int ret; + + if ((b = BIO_new(BIO_s_file())) == NULL) { + OPENSSL_PUT_ERROR(ASN1, 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); +} + +int ASN1_i2d_bio(i2d_of_void *i2d, BIO *out, void *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) { + OPENSSL_PUT_ERROR(ASN1, 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); +} + +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) { + OPENSSL_PUT_ERROR(ASN1, 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); +} + +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) { + OPENSSL_PUT_ERROR(ASN1, 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); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_int.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_int.c new file mode 100644 index 0000000..f467071 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_int.c @@ -0,0 +1,479 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 + +#include "../internal.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) + OPENSSL_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--; + } + OPENSSL_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: + OPENSSL_PUT_ERROR(ASN1, 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--; + } + OPENSSL_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: + OPENSSL_PUT_ERROR(ASN1, i); + if ((ret != NULL) && ((a == NULL) || (*a != ret))) + M_ASN1_INTEGER_free(ret); + return (NULL); +} + +int ASN1_INTEGER_set(ASN1_INTEGER *a, long v) +{ + if (v >= 0) { + return ASN1_INTEGER_set_uint64(a, (uint64_t) v); + } + + if (!ASN1_INTEGER_set_uint64(a, 0 - (uint64_t) v)) { + return 0; + } + + a->type = V_ASN1_NEG_INTEGER; + return 1; +} + +int ASN1_INTEGER_set_uint64(ASN1_INTEGER *out, uint64_t v) +{ + uint8_t *const newdata = OPENSSL_malloc(sizeof(uint64_t)); + if (newdata == NULL) { + OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); + return 0; + } + + OPENSSL_free(out->data); + out->data = newdata; + v = CRYPTO_bswap8(v); + memcpy(out->data, &v, sizeof(v)); + + out->type = V_ASN1_INTEGER; + + size_t leading_zeros; + for (leading_zeros = 0; leading_zeros < sizeof(uint64_t) - 1; + leading_zeros++) { + if (out->data[leading_zeros] != 0) { + break; + } + } + + out->length = sizeof(uint64_t) - leading_zeros; + OPENSSL_memmove(out->data, out->data + leading_zeros, out->length); + + return 1; +} + +long ASN1_INTEGER_get(const ASN1_INTEGER *a) +{ + int neg = 0, i; + + if (a == NULL) + return (0L); + i = a->type; + if (i == V_ASN1_NEG_INTEGER) + neg = 1; + else if (i != V_ASN1_INTEGER) + return -1; + + OPENSSL_COMPILE_ASSERT(sizeof(uint64_t) >= sizeof(long), + long_larger_than_uint64_t); + + if (a->length > (int)sizeof(uint64_t)) { + /* hmm... a bit ugly, return all ones */ + return -1; + } + + uint64_t r64 = 0; + if (a->data != NULL) { + for (i = 0; i < a->length; i++) { + r64 <<= 8; + r64 |= (unsigned char)a->data[i]; + } + + if (r64 > LONG_MAX) { + return -1; + } + } + + long r = (long) r64; + 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) { + OPENSSL_PUT_ERROR(ASN1, ASN1_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) { + OPENSSL_PUT_ERROR(ASN1, 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) + OPENSSL_PUT_ERROR(ASN1, ASN1_R_BN_LIB); + else if (ai->type == V_ASN1_NEG_INTEGER) + BN_set_negative(ret, 1); + return (ret); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_int.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_int.c.grpc_back new file mode 100644 index 0000000..dd74550 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_int.c.grpc_back @@ -0,0 +1,479 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 + +#include "../internal.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) + OPENSSL_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--; + } + OPENSSL_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: + OPENSSL_PUT_ERROR(ASN1, 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--; + } + OPENSSL_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: + OPENSSL_PUT_ERROR(ASN1, i); + if ((ret != NULL) && ((a == NULL) || (*a != ret))) + M_ASN1_INTEGER_free(ret); + return (NULL); +} + +int ASN1_INTEGER_set(ASN1_INTEGER *a, long v) +{ + if (v >= 0) { + return ASN1_INTEGER_set_uint64(a, (uint64_t) v); + } + + if (!ASN1_INTEGER_set_uint64(a, 0 - (uint64_t) v)) { + return 0; + } + + a->type = V_ASN1_NEG_INTEGER; + return 1; +} + +int ASN1_INTEGER_set_uint64(ASN1_INTEGER *out, uint64_t v) +{ + uint8_t *const newdata = OPENSSL_malloc(sizeof(uint64_t)); + if (newdata == NULL) { + OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); + return 0; + } + + OPENSSL_free(out->data); + out->data = newdata; + v = CRYPTO_bswap8(v); + memcpy(out->data, &v, sizeof(v)); + + out->type = V_ASN1_INTEGER; + + size_t leading_zeros; + for (leading_zeros = 0; leading_zeros < sizeof(uint64_t) - 1; + leading_zeros++) { + if (out->data[leading_zeros] != 0) { + break; + } + } + + out->length = sizeof(uint64_t) - leading_zeros; + OPENSSL_memmove(out->data, out->data + leading_zeros, out->length); + + return 1; +} + +long ASN1_INTEGER_get(const ASN1_INTEGER *a) +{ + int neg = 0, i; + + if (a == NULL) + return (0L); + i = a->type; + if (i == V_ASN1_NEG_INTEGER) + neg = 1; + else if (i != V_ASN1_INTEGER) + return -1; + + OPENSSL_COMPILE_ASSERT(sizeof(uint64_t) >= sizeof(long), + long_larger_than_uint64_t); + + if (a->length > (int)sizeof(uint64_t)) { + /* hmm... a bit ugly, return all ones */ + return -1; + } + + uint64_t r64 = 0; + if (a->data != NULL) { + for (i = 0; i < a->length; i++) { + r64 <<= 8; + r64 |= (unsigned char)a->data[i]; + } + + if (r64 > LONG_MAX) { + return -1; + } + } + + long r = (long) r64; + 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) { + OPENSSL_PUT_ERROR(ASN1, ASN1_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) { + OPENSSL_PUT_ERROR(ASN1, 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) + OPENSSL_PUT_ERROR(ASN1, ASN1_R_BN_LIB); + else if (ai->type == V_ASN1_NEG_INTEGER) + BN_set_negative(ret, 1); + return (ret); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_mbstr.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_mbstr.c new file mode 100644 index 0000000..9bfdeba --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_mbstr.c @@ -0,0 +1,411 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 "asn1_locl.h" + +static int traverse_string(const unsigned char *p, int len, int inform, + int (*rfunc) (uint32_t value, void *in), + void *arg); +static int in_utf8(uint32_t value, void *arg); +static int out_utf8(uint32_t value, void *arg); +static int type_str(uint32_t value, void *arg); +static int cpy_asc(uint32_t value, void *arg); +static int cpy_bmp(uint32_t value, void *arg); +static int cpy_univ(uint32_t value, void *arg); +static int cpy_utf8(uint32_t value, void *arg); +static int is_printable(uint32_t 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) (uint32_t, 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) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_BMPSTRING_LENGTH); + return -1; + } + nchar = len >> 1; + break; + + case MBSTRING_UNIV: + if (len & 3) { + OPENSSL_PUT_ERROR(ASN1, 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) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_UTF8STRING); + return -1; + } + break; + + case MBSTRING_ASC: + nchar = len; + break; + + default: + OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNKNOWN_FORMAT); + return -1; + } + + if ((minsize > 0) && (nchar < minsize)) { + OPENSSL_PUT_ERROR(ASN1, 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)) { + OPENSSL_PUT_ERROR(ASN1, 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) { + OPENSSL_PUT_ERROR(ASN1, 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) { + OPENSSL_PUT_ERROR(ASN1, 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)) { + OPENSSL_PUT_ERROR(ASN1, 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); + OPENSSL_PUT_ERROR(ASN1, 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) (uint32_t value, void *in), + void *arg) +{ + uint32_t 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 = ((uint32_t)*p++) << 24; + value |= ((uint32_t)*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(uint32_t value, void *arg) +{ + int *nchar; + nchar = arg; + (*nchar)++; + return 1; +} + +/* Determine size of output as a UTF8 String */ + +static int out_utf8(uint32_t 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(uint32_t 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(uint32_t 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(uint32_t 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(uint32_t 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(uint32_t 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(uint32_t 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. + */ + 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; + return 0; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_mbstr.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_mbstr.c.grpc_back new file mode 100644 index 0000000..a2789ed --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_mbstr.c.grpc_back @@ -0,0 +1,411 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 "asn1_locl.h" + +static int traverse_string(const unsigned char *p, int len, int inform, + int (*rfunc) (uint32_t value, void *in), + void *arg); +static int in_utf8(uint32_t value, void *arg); +static int out_utf8(uint32_t value, void *arg); +static int type_str(uint32_t value, void *arg); +static int cpy_asc(uint32_t value, void *arg); +static int cpy_bmp(uint32_t value, void *arg); +static int cpy_univ(uint32_t value, void *arg); +static int cpy_utf8(uint32_t value, void *arg); +static int is_printable(uint32_t 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) (uint32_t, 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) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_BMPSTRING_LENGTH); + return -1; + } + nchar = len >> 1; + break; + + case MBSTRING_UNIV: + if (len & 3) { + OPENSSL_PUT_ERROR(ASN1, 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) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_UTF8STRING); + return -1; + } + break; + + case MBSTRING_ASC: + nchar = len; + break; + + default: + OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNKNOWN_FORMAT); + return -1; + } + + if ((minsize > 0) && (nchar < minsize)) { + OPENSSL_PUT_ERROR(ASN1, 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)) { + OPENSSL_PUT_ERROR(ASN1, 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) { + OPENSSL_PUT_ERROR(ASN1, 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) { + OPENSSL_PUT_ERROR(ASN1, 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)) { + OPENSSL_PUT_ERROR(ASN1, 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); + OPENSSL_PUT_ERROR(ASN1, 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) (uint32_t value, void *in), + void *arg) +{ + uint32_t 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 = ((uint32_t)*p++) << 24; + value |= ((uint32_t)*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(uint32_t value, void *arg) +{ + int *nchar; + nchar = arg; + (*nchar)++; + return 1; +} + +/* Determine size of output as a UTF8 String */ + +static int out_utf8(uint32_t 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(uint32_t 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(uint32_t 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(uint32_t 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(uint32_t 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(uint32_t 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(uint32_t 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. + */ + 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; + return 0; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_object.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_object.c new file mode 100644 index 0000000..d5e59e2 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_object.c @@ -0,0 +1,275 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 +#include + +#include "../internal.h" + + +int i2d_ASN1_OBJECT(ASN1_OBJECT *a, unsigned char **pp) +{ + unsigned char *p; + 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; + + p = *pp; + ASN1_put_object(&p, 0, a->length, V_ASN1_OBJECT, V_ASN1_UNIVERSAL); + OPENSSL_memcpy(p, a->data, a->length); + p += a->length; + + *pp = p; + return (objsize); +} + +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: + OPENSSL_PUT_ERROR(ASN1, 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) { + OPENSSL_PUT_ERROR(ASN1, 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))) { + OPENSSL_PUT_ERROR(ASN1, 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; + } + OPENSSL_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: + OPENSSL_PUT_ERROR(ASN1, 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) { + OPENSSL_PUT_ERROR(ASN1, 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)); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_object.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_object.c.grpc_back new file mode 100644 index 0000000..005e37d --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_object.c.grpc_back @@ -0,0 +1,275 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 +#include + +#include "../internal.h" + + +int i2d_ASN1_OBJECT(ASN1_OBJECT *a, unsigned char **pp) +{ + unsigned char *p; + 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; + + p = *pp; + ASN1_put_object(&p, 0, a->length, V_ASN1_OBJECT, V_ASN1_UNIVERSAL); + OPENSSL_memcpy(p, a->data, a->length); + p += a->length; + + *pp = p; + return (objsize); +} + +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: + OPENSSL_PUT_ERROR(ASN1, 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) { + OPENSSL_PUT_ERROR(ASN1, 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))) { + OPENSSL_PUT_ERROR(ASN1, 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; + } + OPENSSL_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: + OPENSSL_PUT_ERROR(ASN1, 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) { + OPENSSL_PUT_ERROR(ASN1, 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)); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_octet.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_octet.c new file mode 100644 index 0000000..c3f9212 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_octet.c @@ -0,0 +1,77 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 + +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); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_octet.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_octet.c.grpc_back new file mode 100644 index 0000000..2e74d6b --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_octet.c.grpc_back @@ -0,0 +1,77 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 + +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); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_print.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_print.c new file mode 100644 index 0000000..d2532f6 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_print.c @@ -0,0 +1,93 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 + +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++); + 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; + } + if (t61) + return (V_ASN1_T61STRING); + if (ia5) + return (V_ASN1_IA5STRING); + return (V_ASN1_PRINTABLESTRING); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_print.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_print.c.grpc_back new file mode 100644 index 0000000..2104521 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_print.c.grpc_back @@ -0,0 +1,93 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 + +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++); + 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; + } + if (t61) + return (V_ASN1_T61STRING); + if (ia5) + return (V_ASN1_IA5STRING); + return (V_ASN1_PRINTABLESTRING); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_strnid.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_strnid.c new file mode 100644 index 0000000..addbd7d --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_strnid.c @@ -0,0 +1,312 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include /* For bsearch */ +#include + +#include +#include +#include +#include + +DEFINE_STACK_OF(ASN1_STRING_TABLE) + +static STACK_OF(ASN1_STRING_TABLE) *stable = NULL; +static void st_free(ASN1_STRING_TABLE *tbl); + +/* + * 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} +}; + +static int sk_table_cmp(const ASN1_STRING_TABLE **a, + const ASN1_STRING_TABLE **b) +{ + return (*a)->nid - (*b)->nid; +} + +static int table_cmp(const void *in_a, const void *in_b) +{ + const ASN1_STRING_TABLE *a = in_a; + const ASN1_STRING_TABLE *b = in_b; + return a->nid - b->nid; +} + +ASN1_STRING_TABLE *ASN1_STRING_TABLE_get(int nid) +{ + int found; + size_t idx; + ASN1_STRING_TABLE *ttmp; + ASN1_STRING_TABLE fnd; + fnd.nid = nid; + + ttmp = + bsearch(&fnd, tbl_standard, + sizeof(tbl_standard) / sizeof(ASN1_STRING_TABLE), + sizeof(ASN1_STRING_TABLE), table_cmp); + if (ttmp) + return ttmp; + if (!stable) + return NULL; + found = sk_ASN1_STRING_TABLE_find(stable, &idx, &fnd); + if (!found) + 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) { + OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); + return 0; + } + if (!(tmp = ASN1_STRING_TABLE_get(nid))) { + tmp = OPENSSL_malloc(sizeof(ASN1_STRING_TABLE)); + if (!tmp) { + OPENSSL_PUT_ERROR(ASN1, 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); +} + +#ifdef STRING_TABLE_TEST + +int main(void) +{ + 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)); + + return 0; +} + +#endif diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_strnid.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_strnid.c.grpc_back new file mode 100644 index 0000000..379a79f --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_strnid.c.grpc_back @@ -0,0 +1,312 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include /* For bsearch */ +#include + +#include +#include +#include +#include + +DEFINE_STACK_OF(ASN1_STRING_TABLE) + +static STACK_OF(ASN1_STRING_TABLE) *stable = NULL; +static void st_free(ASN1_STRING_TABLE *tbl); + +/* + * 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} +}; + +static int sk_table_cmp(const ASN1_STRING_TABLE **a, + const ASN1_STRING_TABLE **b) +{ + return (*a)->nid - (*b)->nid; +} + +static int table_cmp(const void *in_a, const void *in_b) +{ + const ASN1_STRING_TABLE *a = in_a; + const ASN1_STRING_TABLE *b = in_b; + return a->nid - b->nid; +} + +ASN1_STRING_TABLE *ASN1_STRING_TABLE_get(int nid) +{ + int found; + size_t idx; + ASN1_STRING_TABLE *ttmp; + ASN1_STRING_TABLE fnd; + fnd.nid = nid; + + ttmp = + bsearch(&fnd, tbl_standard, + sizeof(tbl_standard) / sizeof(ASN1_STRING_TABLE), + sizeof(ASN1_STRING_TABLE), table_cmp); + if (ttmp) + return ttmp; + if (!stable) + return NULL; + found = sk_ASN1_STRING_TABLE_find(stable, &idx, &fnd); + if (!found) + 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) { + OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); + return 0; + } + if (!(tmp = ASN1_STRING_TABLE_get(nid))) { + tmp = OPENSSL_malloc(sizeof(ASN1_STRING_TABLE)); + if (!tmp) { + OPENSSL_PUT_ERROR(ASN1, 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); +} + +#ifdef STRING_TABLE_TEST + +int main(void) +{ + 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)); + + return 0; +} + +#endif diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_time.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_time.c new file mode 100644 index 0000000..feb2443 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_time.c @@ -0,0 +1,213 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 +#include +#include + +#include "asn1_locl.h" + +/* + * This is an implementation of the ASN1 Time structure which is: Time ::= + * CHOICE { utcTime UTCTime, generalTime GeneralizedTime } written by Steve + * Henson. + */ + +IMPLEMENT_ASN1_MSTRING(ASN1_TIME, B_ASN1_TIME) + +IMPLEMENT_ASN1_FUNCTIONS(ASN1_TIME) + +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) { + OPENSSL_PUT_ERROR(ASN1, 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); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_time.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_time.c.grpc_back new file mode 100644 index 0000000..c962c0b --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_time.c.grpc_back @@ -0,0 +1,213 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 +#include +#include + +#include "asn1_locl.h" + +/* + * This is an implementation of the ASN1 Time structure which is: Time ::= + * CHOICE { utcTime UTCTime, generalTime GeneralizedTime } written by Steve + * Henson. + */ + +IMPLEMENT_ASN1_MSTRING(ASN1_TIME, B_ASN1_TIME) + +IMPLEMENT_ASN1_FUNCTIONS(ASN1_TIME) + +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) { + OPENSSL_PUT_ERROR(ASN1, 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); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_type.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_type.c new file mode 100644 index 0000000..9e4461d --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_type.c @@ -0,0 +1,151 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 + +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; +} + +/* 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_NULL: + result = 0; /* They do not have content. */ + break; + case V_ASN1_BOOLEAN: + result = a->value.boolean - b->value.boolean; + 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; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_type.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_type.c.grpc_back new file mode 100644 index 0000000..734ff8b --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_type.c.grpc_back @@ -0,0 +1,151 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 + +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; +} + +/* 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_NULL: + result = 0; /* They do not have content. */ + break; + case V_ASN1_BOOLEAN: + result = a->value.boolean - b->value.boolean; + 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; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_utctm.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_utctm.c new file mode 100644 index 0000000..c005f81 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_utctm.c @@ -0,0 +1,303 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 + +#include "asn1_locl.h" + + +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) { + OPENSSL_PUT_ERROR(ASN1, 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; + 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; + + OPENSSL_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 + + return mktime(&tm) - offset * 60; /* 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. */ +} +#endif diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_utctm.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_utctm.c.grpc_back new file mode 100644 index 0000000..f7519df --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_utctm.c.grpc_back @@ -0,0 +1,303 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 + +#include "asn1_locl.h" + + +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) { + OPENSSL_PUT_ERROR(ASN1, 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; + 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; + + OPENSSL_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 + + return mktime(&tm) - offset * 60; /* 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. */ +} +#endif diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_utf8.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_utf8.c new file mode 100644 index 0000000..59328d8 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_utf8.c @@ -0,0 +1,236 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 "asn1_locl.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, uint32_t *val) +{ + const unsigned char *p; + uint32_t 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 = ((uint32_t)(*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 = ((uint32_t)(*p++ & 0x3)) << 24; + value |= ((uint32_t)(*p++ & 0x3f)) << 18; + value |= ((uint32_t)(*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 = ((uint32_t)(*p++ & 0x1)) << 30; + value |= ((uint32_t)(*p++ & 0x3f)) << 24; + value |= ((uint32_t)(*p++ & 0x3f)) << 18; + value |= ((uint32_t)(*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, uint32_t 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; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_utf8.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_utf8.c.grpc_back new file mode 100644 index 0000000..119ccf9 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/a_utf8.c.grpc_back @@ -0,0 +1,236 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 "asn1_locl.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, uint32_t *val) +{ + const unsigned char *p; + uint32_t 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 = ((uint32_t)(*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 = ((uint32_t)(*p++ & 0x3)) << 24; + value |= ((uint32_t)(*p++ & 0x3f)) << 18; + value |= ((uint32_t)(*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 = ((uint32_t)(*p++ & 0x1)) << 30; + value |= ((uint32_t)(*p++ & 0x3f)) << 24; + value |= ((uint32_t)(*p++ & 0x3f)) << 18; + value |= ((uint32_t)(*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, uint32_t 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; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/asn1_lib.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/asn1_lib.c new file mode 100644 index 0000000..8585302 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/asn1_lib.c @@ -0,0 +1,442 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 +#include + +#include "../internal.h" + + +/* Cross-module errors from crypto/x509/i2d_pr.c. */ +OPENSSL_DECLARE_ERROR_REASON(ASN1, UNSUPPORTED_PUBLIC_KEY_TYPE) + +/* Cross-module errors from crypto/x509/algorithm.c. */ +OPENSSL_DECLARE_ERROR_REASON(ASN1, CONTEXT_NOT_INITIALISED) +OPENSSL_DECLARE_ERROR_REASON(ASN1, DIGEST_AND_KEY_TYPE_NOT_SUPPORTED) +OPENSSL_DECLARE_ERROR_REASON(ASN1, UNKNOWN_MESSAGE_DIGEST_ALGORITHM) +OPENSSL_DECLARE_ERROR_REASON(ASN1, UNKNOWN_SIGNATURE_ALGORITHM) +OPENSSL_DECLARE_ERROR_REASON(ASN1, WRONG_PUBLIC_KEY_TYPE) +/* + * Cross-module errors from crypto/x509/asn1_gen.c. TODO(davidben): Remove + * these once asn1_gen.c is gone. + */ +OPENSSL_DECLARE_ERROR_REASON(ASN1, DEPTH_EXCEEDED) +OPENSSL_DECLARE_ERROR_REASON(ASN1, ILLEGAL_BITSTRING_FORMAT) +OPENSSL_DECLARE_ERROR_REASON(ASN1, ILLEGAL_BOOLEAN) +OPENSSL_DECLARE_ERROR_REASON(ASN1, ILLEGAL_FORMAT) +OPENSSL_DECLARE_ERROR_REASON(ASN1, ILLEGAL_HEX) +OPENSSL_DECLARE_ERROR_REASON(ASN1, ILLEGAL_IMPLICIT_TAG) +OPENSSL_DECLARE_ERROR_REASON(ASN1, ILLEGAL_INTEGER) +OPENSSL_DECLARE_ERROR_REASON(ASN1, ILLEGAL_NESTED_TAGGING) +OPENSSL_DECLARE_ERROR_REASON(ASN1, ILLEGAL_NULL_VALUE) +OPENSSL_DECLARE_ERROR_REASON(ASN1, ILLEGAL_OBJECT) +OPENSSL_DECLARE_ERROR_REASON(ASN1, ILLEGAL_TIME_VALUE) +OPENSSL_DECLARE_ERROR_REASON(ASN1, INTEGER_NOT_ASCII_FORMAT) +OPENSSL_DECLARE_ERROR_REASON(ASN1, INVALID_MODIFIER) +OPENSSL_DECLARE_ERROR_REASON(ASN1, INVALID_NUMBER) +OPENSSL_DECLARE_ERROR_REASON(ASN1, LIST_ERROR) +OPENSSL_DECLARE_ERROR_REASON(ASN1, MISSING_VALUE) +OPENSSL_DECLARE_ERROR_REASON(ASN1, NOT_ASCII_FORMAT) +OPENSSL_DECLARE_ERROR_REASON(ASN1, OBJECT_NOT_ASCII_FORMAT) +OPENSSL_DECLARE_ERROR_REASON(ASN1, SEQUENCE_OR_SET_NEEDS_CONFIG) +OPENSSL_DECLARE_ERROR_REASON(ASN1, TIME_NOT_ASCII_FORMAT) +OPENSSL_DECLARE_ERROR_REASON(ASN1, UNKNOWN_FORMAT) +OPENSSL_DECLARE_ERROR_REASON(ASN1, UNKNOWN_TAG) +OPENSSL_DECLARE_ERROR_REASON(ASN1, UNSUPPORTED_TYPE) + +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); + +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; + } + + /* To avoid ambiguity with V_ASN1_NEG, impose a limit on universal tags. */ + if (xclass == V_ASN1_UNIVERSAL && tag > V_ASN1_MAX_UNIVERSAL) + 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))) { + OPENSSL_PUT_ERROR(ASN1, 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: + OPENSSL_PUT_ERROR(ASN1, 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; +} + +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) { + OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); + str->data = c; + return (0); + } + } + str->length = len; + if (data != NULL) { + OPENSSL_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) { + OPENSSL_PUT_ERROR(ASN1, 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); +} + +int ASN1_STRING_cmp(const ASN1_STRING *a, const ASN1_STRING *b) +{ + int i; + + i = (a->length - b->length); + if (i == 0) { + i = OPENSSL_memcmp(a->data, b->data, a->length); + if (i == 0) + return (a->type - b->type); + else + return (i); + } else + return (i); +} + +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); +} + +const unsigned char *ASN1_STRING_get0_data(const ASN1_STRING *x) +{ + return x->data; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/asn1_lib.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/asn1_lib.c.grpc_back new file mode 100644 index 0000000..ea727f3 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/asn1_lib.c.grpc_back @@ -0,0 +1,442 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 +#include + +#include "../internal.h" + + +/* Cross-module errors from crypto/x509/i2d_pr.c. */ +OPENSSL_DECLARE_ERROR_REASON(ASN1, UNSUPPORTED_PUBLIC_KEY_TYPE) + +/* Cross-module errors from crypto/x509/algorithm.c. */ +OPENSSL_DECLARE_ERROR_REASON(ASN1, CONTEXT_NOT_INITIALISED) +OPENSSL_DECLARE_ERROR_REASON(ASN1, DIGEST_AND_KEY_TYPE_NOT_SUPPORTED) +OPENSSL_DECLARE_ERROR_REASON(ASN1, UNKNOWN_MESSAGE_DIGEST_ALGORITHM) +OPENSSL_DECLARE_ERROR_REASON(ASN1, UNKNOWN_SIGNATURE_ALGORITHM) +OPENSSL_DECLARE_ERROR_REASON(ASN1, WRONG_PUBLIC_KEY_TYPE) +/* + * Cross-module errors from crypto/x509/asn1_gen.c. TODO(davidben): Remove + * these once asn1_gen.c is gone. + */ +OPENSSL_DECLARE_ERROR_REASON(ASN1, DEPTH_EXCEEDED) +OPENSSL_DECLARE_ERROR_REASON(ASN1, ILLEGAL_BITSTRING_FORMAT) +OPENSSL_DECLARE_ERROR_REASON(ASN1, ILLEGAL_BOOLEAN) +OPENSSL_DECLARE_ERROR_REASON(ASN1, ILLEGAL_FORMAT) +OPENSSL_DECLARE_ERROR_REASON(ASN1, ILLEGAL_HEX) +OPENSSL_DECLARE_ERROR_REASON(ASN1, ILLEGAL_IMPLICIT_TAG) +OPENSSL_DECLARE_ERROR_REASON(ASN1, ILLEGAL_INTEGER) +OPENSSL_DECLARE_ERROR_REASON(ASN1, ILLEGAL_NESTED_TAGGING) +OPENSSL_DECLARE_ERROR_REASON(ASN1, ILLEGAL_NULL_VALUE) +OPENSSL_DECLARE_ERROR_REASON(ASN1, ILLEGAL_OBJECT) +OPENSSL_DECLARE_ERROR_REASON(ASN1, ILLEGAL_TIME_VALUE) +OPENSSL_DECLARE_ERROR_REASON(ASN1, INTEGER_NOT_ASCII_FORMAT) +OPENSSL_DECLARE_ERROR_REASON(ASN1, INVALID_MODIFIER) +OPENSSL_DECLARE_ERROR_REASON(ASN1, INVALID_NUMBER) +OPENSSL_DECLARE_ERROR_REASON(ASN1, LIST_ERROR) +OPENSSL_DECLARE_ERROR_REASON(ASN1, MISSING_VALUE) +OPENSSL_DECLARE_ERROR_REASON(ASN1, NOT_ASCII_FORMAT) +OPENSSL_DECLARE_ERROR_REASON(ASN1, OBJECT_NOT_ASCII_FORMAT) +OPENSSL_DECLARE_ERROR_REASON(ASN1, SEQUENCE_OR_SET_NEEDS_CONFIG) +OPENSSL_DECLARE_ERROR_REASON(ASN1, TIME_NOT_ASCII_FORMAT) +OPENSSL_DECLARE_ERROR_REASON(ASN1, UNKNOWN_FORMAT) +OPENSSL_DECLARE_ERROR_REASON(ASN1, UNKNOWN_TAG) +OPENSSL_DECLARE_ERROR_REASON(ASN1, UNSUPPORTED_TYPE) + +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); + +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; + } + + /* To avoid ambiguity with V_ASN1_NEG, impose a limit on universal tags. */ + if (xclass == V_ASN1_UNIVERSAL && tag > V_ASN1_MAX_UNIVERSAL) + 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))) { + OPENSSL_PUT_ERROR(ASN1, 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: + OPENSSL_PUT_ERROR(ASN1, 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; +} + +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) { + OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); + str->data = c; + return (0); + } + } + str->length = len; + if (data != NULL) { + OPENSSL_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) { + OPENSSL_PUT_ERROR(ASN1, 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); +} + +int ASN1_STRING_cmp(const ASN1_STRING *a, const ASN1_STRING *b) +{ + int i; + + i = (a->length - b->length); + if (i == 0) { + i = OPENSSL_memcmp(a->data, b->data, a->length); + if (i == 0) + return (a->type - b->type); + else + return (i); + } else + return (i); +} + +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); +} + +const unsigned char *ASN1_STRING_get0_data(const ASN1_STRING *x) +{ + return x->data; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/asn1_locl.h b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/asn1_locl.h new file mode 100644 index 0000000..45405d2 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/asn1_locl.h @@ -0,0 +1,104 @@ +/* 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). + * + */ + +#ifndef OPENSSL_HEADER_ASN1_ASN1_LOCL_H +#define OPENSSL_HEADER_ASN1_ASN1_LOCL_H + +#include + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +/* Wrapper functions for time functions. */ + +/* OPENSSL_gmtime wraps |gmtime_r|. See the manual page for that function. */ +struct tm *OPENSSL_gmtime(const time_t *time, struct tm *result); + +/* OPENSSL_gmtime_adj updates |tm| by adding |offset_day| days and |offset_sec| + * seconds. */ +int OPENSSL_gmtime_adj(struct tm *tm, int offset_day, long offset_sec); + +/* OPENSSL_gmtime_diff calculates the difference between |from| and |to| and + * outputs the difference as a number of days and seconds in |*out_days| and + * |*out_secs|. */ +int OPENSSL_gmtime_diff(int *out_days, int *out_secs, const struct tm *from, + const struct tm *to); + + +/* 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); + +void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it, + int combine); + +int UTF8_getc(const unsigned char *str, int len, uint32_t *val); +int UTF8_putc(unsigned char *str, int len, uint32_t value); + + +#if defined(__cplusplus) +} /* extern C */ +#endif + +#endif /* OPENSSL_HEADER_ASN1_ASN1_LOCL_H */ diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/asn1_locl.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/asn1_locl.h.grpc_back new file mode 100644 index 0000000..8cef246 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/asn1_locl.h.grpc_back @@ -0,0 +1,104 @@ +/* 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). + * + */ + +#ifndef OPENSSL_HEADER_ASN1_ASN1_LOCL_H +#define OPENSSL_HEADER_ASN1_ASN1_LOCL_H + +#include + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +/* Wrapper functions for time functions. */ + +/* OPENSSL_gmtime wraps |gmtime_r|. See the manual page for that function. */ +struct tm *OPENSSL_gmtime(const time_t *time, struct tm *result); + +/* OPENSSL_gmtime_adj updates |tm| by adding |offset_day| days and |offset_sec| + * seconds. */ +int OPENSSL_gmtime_adj(struct tm *tm, int offset_day, long offset_sec); + +/* OPENSSL_gmtime_diff calculates the difference between |from| and |to| and + * outputs the difference as a number of days and seconds in |*out_days| and + * |*out_secs|. */ +int OPENSSL_gmtime_diff(int *out_days, int *out_secs, const struct tm *from, + const struct tm *to); + + +/* 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); + +void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it, + int combine); + +int UTF8_getc(const unsigned char *str, int len, uint32_t *val); +int UTF8_putc(unsigned char *str, int len, uint32_t value); + + +#if defined(__cplusplus) +} /* extern C */ +#endif + +#endif /* OPENSSL_HEADER_ASN1_ASN1_LOCL_H */ diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/asn1_par.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/asn1_par.c new file mode 100644 index 0000000..55812d4 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/asn1_par.c @@ -0,0 +1,80 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + + +const char *ASN1_tag2str(int tag) +{ + static const char *const tag2str[] = { + "EOC", "BOOLEAN", "INTEGER", "BIT STRING", "OCTET STRING", /* 0-4 */ + "NULL", "OBJECT", "OBJECT DESCRIPTOR", "EXTERNAL", "REAL", /* 5-9 */ + "ENUMERATED", "", "UTF8STRING", "", /* 10-13 */ + "", "", "SEQUENCE", "SET", /* 15-17 */ + "NUMERICSTRING", "PRINTABLESTRING", "T61STRING", /* 18-20 */ + "VIDEOTEXSTRING", "IA5STRING", "UTCTIME", "GENERALIZEDTIME", /* 21-24 + */ + "GRAPHICSTRING", "VISIBLESTRING", "GENERALSTRING", /* 25-27 */ + "UNIVERSALSTRING", "", "BMPSTRING" /* 28-30 */ + }; + + 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/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/asn1_par.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/asn1_par.c.grpc_back new file mode 100644 index 0000000..b1a01ed --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/asn1_par.c.grpc_back @@ -0,0 +1,80 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + + +const char *ASN1_tag2str(int tag) +{ + static const char *const tag2str[] = { + "EOC", "BOOLEAN", "INTEGER", "BIT STRING", "OCTET STRING", /* 0-4 */ + "NULL", "OBJECT", "OBJECT DESCRIPTOR", "EXTERNAL", "REAL", /* 5-9 */ + "ENUMERATED", "", "UTF8STRING", "", /* 10-13 */ + "", "", "SEQUENCE", "SET", /* 15-17 */ + "NUMERICSTRING", "PRINTABLESTRING", "T61STRING", /* 18-20 */ + "VIDEOTEXSTRING", "IA5STRING", "UTCTIME", "GENERALIZEDTIME", /* 21-24 + */ + "GRAPHICSTRING", "VISIBLESTRING", "GENERALSTRING", /* 25-27 */ + "UNIVERSALSTRING", "", "BMPSTRING" /* 28-30 */ + }; + + 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/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/asn_pack.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/asn_pack.c new file mode 100644 index 0000000..6b2a1e7 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/asn_pack.c @@ -0,0 +1,105 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 + +/* 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())) { + OPENSSL_PUT_ERROR(ASN1, 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))) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_ENCODE_ERROR); + return NULL; + } + if (!octmp->data) { + OPENSSL_PUT_ERROR(ASN1, 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))) + OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); + return ret; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/asn_pack.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/asn_pack.c.grpc_back new file mode 100644 index 0000000..eff54e5 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/asn_pack.c.grpc_back @@ -0,0 +1,105 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 + +/* 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())) { + OPENSSL_PUT_ERROR(ASN1, 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))) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_ENCODE_ERROR); + return NULL; + } + if (!octmp->data) { + OPENSSL_PUT_ERROR(ASN1, 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))) + OPENSSL_PUT_ERROR(ASN1, ASN1_R_DECODE_ERROR); + return ret; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/f_enum.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/f_enum.c new file mode 100644 index 0000000..84e32b5 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/f_enum.c @@ -0,0 +1,93 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include + +/* 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); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/f_enum.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/f_enum.c.grpc_back new file mode 100644 index 0000000..7ce479d --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/f_enum.c.grpc_back @@ -0,0 +1,93 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include + +/* 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); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/f_int.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/f_int.c new file mode 100644 index 0000000..a7bd709 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/f_int.c @@ -0,0 +1,97 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include + +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); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/f_int.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/f_int.c.grpc_back new file mode 100644 index 0000000..79ea152 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/f_int.c.grpc_back @@ -0,0 +1,97 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include + +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); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/f_string.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/f_string.c new file mode 100644 index 0000000..a6af1a0 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/f_string.c @@ -0,0 +1,91 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include + +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); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/f_string.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/f_string.c.grpc_back new file mode 100644 index 0000000..97c6ae7 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/f_string.c.grpc_back @@ -0,0 +1,91 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include + +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); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/tasn_dec.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/tasn_dec.c new file mode 100644 index 0000000..e205454 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/tasn_dec.c @@ -0,0 +1,1244 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 +#include +#include + +#include "../internal.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] = { + 0, 0, 0, B_ASN1_BIT_STRING, /* tags 0 - 3 */ + B_ASN1_OCTET_STRING, 0, 0, B_ASN1_UNKNOWN, /* tags 4- 7 */ + B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, /* tags + * 8-11 */ + B_ASN1_UTF8STRING, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, /* tags + * 12-15 + */ + B_ASN1_SEQUENCE, 0, B_ASN1_NUMERICSTRING, B_ASN1_PRINTABLESTRING, /* tags + * 16-19 + */ + B_ASN1_T61STRING, B_ASN1_VIDEOTEXSTRING, B_ASN1_IA5STRING, /* tags 20-22 */ + B_ASN1_UTCTIME, B_ASN1_GENERALIZEDTIME, /* tags 23-24 */ + B_ASN1_GRAPHICSTRING, B_ASN1_ISO64STRING, B_ASN1_GENERALSTRING, /* tags + * 25-27 */ + B_ASN1_UNIVERSALSTRING, B_ASN1_UNKNOWN, B_ASN1_BMPSTRING, B_ASN1_UNKNOWN, /* tags + * 28-31 + */ +}; + +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; +} + +/* + * 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; + + /* + * Bound |len| to comfortably fit in an int. Lengths in this module often + * switch between int and long without overflow checks. + */ + if (len > INT_MAX/2) { + len = INT_MAX/2; + } + + if (++depth > ASN1_MAX_CONSTRUCTED_NEST) { + OPENSSL_PUT_ERROR(ASN1, 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) { + OPENSSL_PUT_ERROR(ASN1, + 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) { + OPENSSL_PUT_ERROR(ASN1, ASN1_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; + OPENSSL_PUT_ERROR(ASN1, 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; + OPENSSL_PUT_ERROR(ASN1, 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) { + OPENSSL_PUT_ERROR(ASN1, ASN1_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) { + OPENSSL_PUT_ERROR(ASN1, ASN1_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; + + OPENSSL_PUT_ERROR(ASN1, ASN1_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)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_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; + OPENSSL_PUT_ERROR(ASN1, ASN1_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; + } + OPENSSL_PUT_ERROR(ASN1, 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) { + OPENSSL_PUT_ERROR(ASN1, ASN1_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) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_SEQUENCE_NOT_CONSTRUCTED); + goto err; + } + + if (!*pval && !ASN1_item_ex_new(pval, it)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_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) { + OPENSSL_PUT_ERROR(ASN1, 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)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_MISSING_EOC); + goto err; + } + /* Check all data read */ + if (!seq_nolen && len) { + OPENSSL_PUT_ERROR(ASN1, 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; + OPENSSL_PUT_ERROR(ASN1, 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: + OPENSSL_PUT_ERROR(ASN1, 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) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR); + return 0; + } else if (ret == -1) + return -1; + if (!cst) { + OPENSSL_PUT_ERROR(ASN1, 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) { + OPENSSL_PUT_ERROR(ASN1, ASN1_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)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_MISSING_EOC); + goto err; + } + } else { + /* + * Otherwise we must hit the EXPLICIT tag end or its an error + */ + if (len) { + OPENSSL_PUT_ERROR(ASN1, 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; + if (!val) + return 0; + flags = tt->flags; + aclass = flags & ASN1_TFLG_TAG_CLASS; + + p = *in; + + 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) { + OPENSSL_PUT_ERROR(ASN1, ASN1_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) { + OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); + goto err; + } + + /* Read as many items as we can */ + while (len > 0) { + ASN1_VALUE *skfield; + const unsigned char *q = p; + /* See if EOC found */ + if (asn1_check_eoc(&p, len)) { + if (!sk_eoc) { + OPENSSL_PUT_ERROR(ASN1, 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)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_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)); + OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); + goto err; + } + } + if (sk_eoc) { + OPENSSL_PUT_ERROR(ASN1, 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) { + OPENSSL_PUT_ERROR(ASN1, ASN1_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) { + OPENSSL_PUT_ERROR(ASN1, ASN1_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) { + OPENSSL_PUT_ERROR(ASN1, 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) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_TAGGED_ANY); + return 0; + } + if (opt) { + OPENSSL_PUT_ERROR(ASN1, 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) { + OPENSSL_PUT_ERROR(ASN1, ASN1_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) { + OPENSSL_PUT_ERROR(ASN1, ASN1_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) { + OPENSSL_PUT_ERROR(ASN1, 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) { + /* These types only have primitive encodings. */ + OPENSSL_PUT_ERROR(ASN1, 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)) { + OPENSSL_PUT_ERROR(ASN1, 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) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_NULL_IS_WRONG_LENGTH); + goto err; + } + *pval = (ASN1_VALUE *)1; + break; + + case V_ASN1_BOOLEAN: + if (len != 1) { + OPENSSL_PUT_ERROR(ASN1, 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)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_BMPSTRING_IS_WRONG_LENGTH); + goto err; + } + if (utype == V_ASN1_UNIVERSALSTRING && (len & 3)) { + OPENSSL_PUT_ERROR(ASN1, 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) { + OPENSSL_PUT_ERROR(ASN1, 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)) { + OPENSSL_PUT_ERROR(ASN1, 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)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR); + return 0; + } + if (inf) + expected_eoc++; + else + p += plen; + len -= p - q; + } + if (expected_eoc) { + OPENSSL_PUT_ERROR(ASN1, 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) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNEXPECTED_EOC); + return 0; + } + inf = 0; + break; + } + + if (!asn1_check_tlen(&plen, NULL, NULL, &ininf, &cst, &p, + len, tag, aclass, 0, NULL)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR); + return 0; + } + + /* If indefinite length constructed update max length */ + if (cst) { + if (depth >= ASN1_MAX_STRING_NEST) { + OPENSSL_PUT_ERROR(ASN1, 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) { + OPENSSL_PUT_ERROR(ASN1, 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)) { + OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); + return 0; + } + OPENSSL_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)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_TOO_LONG); + asn1_tlc_clear(ctx); + return 0; + } + } + } + + if (i & 0x80) { + OPENSSL_PUT_ERROR(ASN1, 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); + OPENSSL_PUT_ERROR(ASN1, 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; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/tasn_dec.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/tasn_dec.c.grpc_back new file mode 100644 index 0000000..32aba0b --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/tasn_dec.c.grpc_back @@ -0,0 +1,1244 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 +#include +#include + +#include "../internal.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] = { + 0, 0, 0, B_ASN1_BIT_STRING, /* tags 0 - 3 */ + B_ASN1_OCTET_STRING, 0, 0, B_ASN1_UNKNOWN, /* tags 4- 7 */ + B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, /* tags + * 8-11 */ + B_ASN1_UTF8STRING, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, B_ASN1_UNKNOWN, /* tags + * 12-15 + */ + B_ASN1_SEQUENCE, 0, B_ASN1_NUMERICSTRING, B_ASN1_PRINTABLESTRING, /* tags + * 16-19 + */ + B_ASN1_T61STRING, B_ASN1_VIDEOTEXSTRING, B_ASN1_IA5STRING, /* tags 20-22 */ + B_ASN1_UTCTIME, B_ASN1_GENERALIZEDTIME, /* tags 23-24 */ + B_ASN1_GRAPHICSTRING, B_ASN1_ISO64STRING, B_ASN1_GENERALSTRING, /* tags + * 25-27 */ + B_ASN1_UNIVERSALSTRING, B_ASN1_UNKNOWN, B_ASN1_BMPSTRING, B_ASN1_UNKNOWN, /* tags + * 28-31 + */ +}; + +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; +} + +/* + * 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; + + /* + * Bound |len| to comfortably fit in an int. Lengths in this module often + * switch between int and long without overflow checks. + */ + if (len > INT_MAX/2) { + len = INT_MAX/2; + } + + if (++depth > ASN1_MAX_CONSTRUCTED_NEST) { + OPENSSL_PUT_ERROR(ASN1, 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) { + OPENSSL_PUT_ERROR(ASN1, + 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) { + OPENSSL_PUT_ERROR(ASN1, ASN1_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; + OPENSSL_PUT_ERROR(ASN1, 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; + OPENSSL_PUT_ERROR(ASN1, 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) { + OPENSSL_PUT_ERROR(ASN1, ASN1_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) { + OPENSSL_PUT_ERROR(ASN1, ASN1_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; + + OPENSSL_PUT_ERROR(ASN1, ASN1_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)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_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; + OPENSSL_PUT_ERROR(ASN1, ASN1_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; + } + OPENSSL_PUT_ERROR(ASN1, 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) { + OPENSSL_PUT_ERROR(ASN1, ASN1_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) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_SEQUENCE_NOT_CONSTRUCTED); + goto err; + } + + if (!*pval && !ASN1_item_ex_new(pval, it)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_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) { + OPENSSL_PUT_ERROR(ASN1, 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)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_MISSING_EOC); + goto err; + } + /* Check all data read */ + if (!seq_nolen && len) { + OPENSSL_PUT_ERROR(ASN1, 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; + OPENSSL_PUT_ERROR(ASN1, 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: + OPENSSL_PUT_ERROR(ASN1, 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) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR); + return 0; + } else if (ret == -1) + return -1; + if (!cst) { + OPENSSL_PUT_ERROR(ASN1, 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) { + OPENSSL_PUT_ERROR(ASN1, ASN1_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)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_MISSING_EOC); + goto err; + } + } else { + /* + * Otherwise we must hit the EXPLICIT tag end or its an error + */ + if (len) { + OPENSSL_PUT_ERROR(ASN1, 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; + if (!val) + return 0; + flags = tt->flags; + aclass = flags & ASN1_TFLG_TAG_CLASS; + + p = *in; + + 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) { + OPENSSL_PUT_ERROR(ASN1, ASN1_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) { + OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); + goto err; + } + + /* Read as many items as we can */ + while (len > 0) { + ASN1_VALUE *skfield; + const unsigned char *q = p; + /* See if EOC found */ + if (asn1_check_eoc(&p, len)) { + if (!sk_eoc) { + OPENSSL_PUT_ERROR(ASN1, 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)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_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)); + OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); + goto err; + } + } + if (sk_eoc) { + OPENSSL_PUT_ERROR(ASN1, 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) { + OPENSSL_PUT_ERROR(ASN1, ASN1_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) { + OPENSSL_PUT_ERROR(ASN1, ASN1_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) { + OPENSSL_PUT_ERROR(ASN1, 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) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_TAGGED_ANY); + return 0; + } + if (opt) { + OPENSSL_PUT_ERROR(ASN1, 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) { + OPENSSL_PUT_ERROR(ASN1, ASN1_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) { + OPENSSL_PUT_ERROR(ASN1, ASN1_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) { + OPENSSL_PUT_ERROR(ASN1, 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) { + /* These types only have primitive encodings. */ + OPENSSL_PUT_ERROR(ASN1, 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)) { + OPENSSL_PUT_ERROR(ASN1, 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) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_NULL_IS_WRONG_LENGTH); + goto err; + } + *pval = (ASN1_VALUE *)1; + break; + + case V_ASN1_BOOLEAN: + if (len != 1) { + OPENSSL_PUT_ERROR(ASN1, 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)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_BMPSTRING_IS_WRONG_LENGTH); + goto err; + } + if (utype == V_ASN1_UNIVERSALSTRING && (len & 3)) { + OPENSSL_PUT_ERROR(ASN1, 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) { + OPENSSL_PUT_ERROR(ASN1, 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)) { + OPENSSL_PUT_ERROR(ASN1, 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)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR); + return 0; + } + if (inf) + expected_eoc++; + else + p += plen; + len -= p - q; + } + if (expected_eoc) { + OPENSSL_PUT_ERROR(ASN1, 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) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNEXPECTED_EOC); + return 0; + } + inf = 0; + break; + } + + if (!asn1_check_tlen(&plen, NULL, NULL, &ininf, &cst, &p, + len, tag, aclass, 0, NULL)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_NESTED_ASN1_ERROR); + return 0; + } + + /* If indefinite length constructed update max length */ + if (cst) { + if (depth >= ASN1_MAX_STRING_NEST) { + OPENSSL_PUT_ERROR(ASN1, 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) { + OPENSSL_PUT_ERROR(ASN1, 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)) { + OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); + return 0; + } + OPENSSL_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)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_TOO_LONG); + asn1_tlc_clear(ctx); + return 0; + } + } + } + + if (i & 0x80) { + OPENSSL_PUT_ERROR(ASN1, 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); + OPENSSL_PUT_ERROR(ASN1, 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; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/tasn_enc.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/tasn_enc.c new file mode 100644 index 0000000..74b5f9c --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/tasn_enc.c @@ -0,0 +1,662 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 + +#include "../internal.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; +} + +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; + size_t j; + 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 (j = 0; j < sk_ASN1_VALUE_num(sk); j++) { + int tmplen; + skitem = sk_ASN1_VALUE_value(sk, j); + 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 = OPENSSL_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) +{ + size_t 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++) { + OPENSSL_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; + 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) + OPENSSL_memcpy(cout, cont, len); + return len; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/tasn_enc.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/tasn_enc.c.grpc_back new file mode 100644 index 0000000..cc87d34 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/tasn_enc.c.grpc_back @@ -0,0 +1,662 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 + +#include "../internal.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; +} + +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; + size_t j; + 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 (j = 0; j < sk_ASN1_VALUE_num(sk); j++) { + int tmplen; + skitem = sk_ASN1_VALUE_value(sk, j); + 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 = OPENSSL_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) +{ + size_t 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++) { + OPENSSL_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; + 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) + OPENSSL_memcpy(cout, cont, len); + return len; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/tasn_fre.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/tasn_fre.c new file mode 100644 index 0000000..65bea9a --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/tasn_fre.c @@ -0,0 +1,244 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 "asn1_locl.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_refcount_dec_and_test_zero(pval, it)) + 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) +{ + size_t 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; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/tasn_fre.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/tasn_fre.c.grpc_back new file mode 100644 index 0000000..eabc0fb --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/tasn_fre.c.grpc_back @@ -0,0 +1,244 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 "asn1_locl.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_refcount_dec_and_test_zero(pval, it)) + 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) +{ + size_t 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; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/tasn_new.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/tasn_new.c new file mode 100644 index 0000000..c1a4e63 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/tasn_new.c @@ -0,0 +1,387 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 +#include + +#include "asn1_locl.h" +#include "../internal.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; + OPENSSL_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; + OPENSSL_memset(*pval, 0, it->size); + asn1_refcount_set_one(pval, 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: + OPENSSL_PUT_ERROR(ASN1, 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: + OPENSSL_PUT_ERROR(ASN1, 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) { + OPENSSL_PUT_ERROR(ASN1, 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; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/tasn_new.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/tasn_new.c.grpc_back new file mode 100644 index 0000000..5db38be --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/tasn_new.c.grpc_back @@ -0,0 +1,387 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 +#include + +#include "asn1_locl.h" +#include "../internal.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; + OPENSSL_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; + OPENSSL_memset(*pval, 0, it->size); + asn1_refcount_set_one(pval, 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: + OPENSSL_PUT_ERROR(ASN1, 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: + OPENSSL_PUT_ERROR(ASN1, 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) { + OPENSSL_PUT_ERROR(ASN1, 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; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/tasn_typ.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/tasn_typ.c new file mode 100644 index 0000000..6817240 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/tasn_typ.c @@ -0,0 +1,131 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include + +/* Declarations for string types */ + +#define IMPLEMENT_ASN1_STRING_FUNCTIONS(sname) \ + IMPLEMENT_ASN1_TYPE(sname) \ + IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(sname, sname, sname) \ + sname *sname##_new(void) \ + { \ + return ASN1_STRING_type_new(V_##sname); \ + } \ + void sname##_free(sname *x) \ + { \ + ASN1_STRING_free(x); \ + } + +IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_OCTET_STRING) +IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_INTEGER) +IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_ENUMERATED) +IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_BIT_STRING) +IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_UTF8STRING) +IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_PRINTABLESTRING) +IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_T61STRING) +IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_IA5STRING) +IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_GENERALSTRING) +IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_UTCTIME) +IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_GENERALIZEDTIME) +IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_VISIBLESTRING) +IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_UNIVERSALSTRING) +IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_BMPSTRING) + +IMPLEMENT_ASN1_TYPE(ASN1_NULL) +IMPLEMENT_ASN1_FUNCTIONS(ASN1_NULL) + +IMPLEMENT_ASN1_TYPE(ASN1_OBJECT) + +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) diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/tasn_typ.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/tasn_typ.c.grpc_back new file mode 100644 index 0000000..7c5bfd5 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/tasn_typ.c.grpc_back @@ -0,0 +1,131 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include + +/* Declarations for string types */ + +#define IMPLEMENT_ASN1_STRING_FUNCTIONS(sname) \ + IMPLEMENT_ASN1_TYPE(sname) \ + IMPLEMENT_ASN1_ENCODE_FUNCTIONS_fname(sname, sname, sname) \ + sname *sname##_new(void) \ + { \ + return ASN1_STRING_type_new(V_##sname); \ + } \ + void sname##_free(sname *x) \ + { \ + ASN1_STRING_free(x); \ + } + +IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_OCTET_STRING) +IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_INTEGER) +IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_ENUMERATED) +IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_BIT_STRING) +IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_UTF8STRING) +IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_PRINTABLESTRING) +IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_T61STRING) +IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_IA5STRING) +IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_GENERALSTRING) +IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_UTCTIME) +IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_GENERALIZEDTIME) +IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_VISIBLESTRING) +IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_UNIVERSALSTRING) +IMPLEMENT_ASN1_STRING_FUNCTIONS(ASN1_BMPSTRING) + +IMPLEMENT_ASN1_TYPE(ASN1_NULL) +IMPLEMENT_ASN1_FUNCTIONS(ASN1_NULL) + +IMPLEMENT_ASN1_TYPE(ASN1_OBJECT) + +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) diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/tasn_utl.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/tasn_utl.c new file mode 100644 index 0000000..341ed5e --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/tasn_utl.c @@ -0,0 +1,280 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 +#include +#include +#include + +#include "../internal.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; +} + +static CRYPTO_refcount_t *asn1_get_references(ASN1_VALUE **pval, + const ASN1_ITEM *it) { + if (it->itype != ASN1_ITYPE_SEQUENCE && + it->itype != ASN1_ITYPE_NDEF_SEQUENCE) { + return NULL; + } + const ASN1_AUX *aux = it->funcs; + if (!aux || !(aux->flags & ASN1_AFLG_REFCOUNT)) { + return NULL; + } + return offset2ptr(*pval, aux->ref_offset); +} + +void asn1_refcount_set_one(ASN1_VALUE **pval, const ASN1_ITEM *it) { + CRYPTO_refcount_t *references = asn1_get_references(pval, it); + if (references != NULL) { + *references = 1; + } +} + +int asn1_refcount_dec_and_test_zero(ASN1_VALUE **pval, const ASN1_ITEM *it) { + CRYPTO_refcount_t *references = asn1_get_references(pval, it); + if (references != NULL) { + return CRYPTO_refcount_dec_and_test_zero(references); + } + return 1; +} + +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->alias_only = 0; + enc->alias_only_on_next_parse = 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 && !enc->alias_only) { + OPENSSL_free(enc->enc); + } + enc->enc = NULL; + enc->len = 0; + enc->alias_only = 0; + enc->alias_only_on_next_parse = 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->alias_only) { + OPENSSL_free(enc->enc); + } + + enc->alias_only = enc->alias_only_on_next_parse; + enc->alias_only_on_next_parse = 0; + + if (enc->alias_only) { + enc->enc = (uint8_t *) in; + } else { + enc->enc = OPENSSL_malloc(inlen); + if (!enc->enc) { + return 0; + } + OPENSSL_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) { + OPENSSL_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) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE); + } + return NULL; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/tasn_utl.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/tasn_utl.c.grpc_back new file mode 100644 index 0000000..a7516f6 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/tasn_utl.c.grpc_back @@ -0,0 +1,280 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 +#include +#include +#include + +#include "../internal.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; +} + +static CRYPTO_refcount_t *asn1_get_references(ASN1_VALUE **pval, + const ASN1_ITEM *it) { + if (it->itype != ASN1_ITYPE_SEQUENCE && + it->itype != ASN1_ITYPE_NDEF_SEQUENCE) { + return NULL; + } + const ASN1_AUX *aux = it->funcs; + if (!aux || !(aux->flags & ASN1_AFLG_REFCOUNT)) { + return NULL; + } + return offset2ptr(*pval, aux->ref_offset); +} + +void asn1_refcount_set_one(ASN1_VALUE **pval, const ASN1_ITEM *it) { + CRYPTO_refcount_t *references = asn1_get_references(pval, it); + if (references != NULL) { + *references = 1; + } +} + +int asn1_refcount_dec_and_test_zero(ASN1_VALUE **pval, const ASN1_ITEM *it) { + CRYPTO_refcount_t *references = asn1_get_references(pval, it); + if (references != NULL) { + return CRYPTO_refcount_dec_and_test_zero(references); + } + return 1; +} + +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->alias_only = 0; + enc->alias_only_on_next_parse = 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 && !enc->alias_only) { + OPENSSL_free(enc->enc); + } + enc->enc = NULL; + enc->len = 0; + enc->alias_only = 0; + enc->alias_only_on_next_parse = 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->alias_only) { + OPENSSL_free(enc->enc); + } + + enc->alias_only = enc->alias_only_on_next_parse; + enc->alias_only_on_next_parse = 0; + + if (enc->alias_only) { + enc->enc = (uint8_t *) in; + } else { + enc->enc = OPENSSL_malloc(inlen); + if (!enc->enc) { + return 0; + } + OPENSSL_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) { + OPENSSL_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) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE); + } + return NULL; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/time_support.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/time_support.c new file mode 100644 index 0000000..3efd43e --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/time_support.c @@ -0,0 +1,206 @@ +/* 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 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH 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(_POSIX_C_SOURCE) +#define _POSIX_C_SOURCE 201410L /* for gmtime_r */ +#endif + +#include "asn1_locl.h" + +#include + + +#define SECS_PER_DAY (24 * 60 * 60) + +struct tm *OPENSSL_gmtime(const time_t *time, struct tm *result) { +#if defined(OPENSSL_WINDOWS) + if (gmtime_s(result, time)) { + return NULL; + } + return result; +#else + return gmtime_r(time, result); +#endif +} + +/* 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; +} + +/* 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; +} + +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 *out_days, int *out_secs, 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 (out_days) { + *out_days = (int)diff_day; + } + if (out_secs) { + *out_secs = diff_sec; + } + + return 1; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/time_support.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/time_support.c.grpc_back new file mode 100644 index 0000000..3efd43e --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/asn1/time_support.c.grpc_back @@ -0,0 +1,206 @@ +/* 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 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * licensing@OpenSSL.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH 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(_POSIX_C_SOURCE) +#define _POSIX_C_SOURCE 201410L /* for gmtime_r */ +#endif + +#include "asn1_locl.h" + +#include + + +#define SECS_PER_DAY (24 * 60 * 60) + +struct tm *OPENSSL_gmtime(const time_t *time, struct tm *result) { +#if defined(OPENSSL_WINDOWS) + if (gmtime_s(result, time)) { + return NULL; + } + return result; +#else + return gmtime_r(time, result); +#endif +} + +/* 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; +} + +/* 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; +} + +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 *out_days, int *out_secs, 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 (out_days) { + *out_days = (int)diff_day; + } + if (out_secs) { + *out_secs = diff_sec; + } + + return 1; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/base64/base64.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/base64/base64.c new file mode 100644 index 0000000..648527d --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/base64/base64.c @@ -0,0 +1,466 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 + +#include "../internal.h" + + +// constant_time_lt_args_8 behaves like |constant_time_lt_8| but takes |uint8_t| +// arguments for a slightly simpler implementation. +static inline uint8_t constant_time_lt_args_8(uint8_t a, uint8_t b) { + crypto_word_t aw = a; + crypto_word_t bw = b; + // |crypto_word_t| is larger than |uint8_t|, so |aw| and |bw| have the same + // MSB. |aw| < |bw| iff MSB(|aw| - |bw|) is 1. + return constant_time_msb_w(aw - bw); +} + +// constant_time_in_range_8 returns |CONSTTIME_TRUE_8| if |min| <= |a| <= |max| +// and |CONSTTIME_FALSE_8| otherwise. +static inline uint8_t constant_time_in_range_8(uint8_t a, uint8_t min, + uint8_t max) { + a -= min; + return constant_time_lt_args_8(a, max - min + 1); +} + +// Encoding. + +static uint8_t conv_bin2ascii(uint8_t a) { + // Since PEM is sometimes used to carry private keys, we encode base64 data + // itself in constant-time. + a &= 0x3f; + uint8_t ret = constant_time_select_8(constant_time_eq_8(a, 62), '+', '/'); + ret = + constant_time_select_8(constant_time_lt_args_8(a, 62), a - 52 + '0', ret); + ret = + constant_time_select_8(constant_time_lt_args_8(a, 52), a - 26 + 'a', ret); + ret = constant_time_select_8(constant_time_lt_args_8(a, 26), a + 'A', ret); + return ret; +} + +OPENSSL_COMPILE_ASSERT(sizeof(((EVP_ENCODE_CTX *)(NULL))->data) % 3 == 0, + data_length_must_be_multiple_of_base64_chunk_size); + +int EVP_EncodedLength(size_t *out_len, size_t len) { + if (len + 2 < len) { + return 0; + } + len += 2; + len /= 3; + + if (((len << 2) >> 2) != len) { + return 0; + } + len <<= 2; + + if (len + 1 < len) { + return 0; + } + len++; + + *out_len = len; + return 1; +} + +void EVP_EncodeInit(EVP_ENCODE_CTX *ctx) { + OPENSSL_memset(ctx, 0, sizeof(EVP_ENCODE_CTX)); +} + +void EVP_EncodeUpdate(EVP_ENCODE_CTX *ctx, uint8_t *out, int *out_len, + const uint8_t *in, size_t in_len) { + size_t total = 0; + + *out_len = 0; + if (in_len == 0) { + return; + } + + assert(ctx->data_used < sizeof(ctx->data)); + + if (sizeof(ctx->data) - ctx->data_used > in_len) { + OPENSSL_memcpy(&ctx->data[ctx->data_used], in, in_len); + ctx->data_used += (unsigned)in_len; + return; + } + + if (ctx->data_used != 0) { + const size_t todo = sizeof(ctx->data) - ctx->data_used; + OPENSSL_memcpy(&ctx->data[ctx->data_used], in, todo); + in += todo; + in_len -= todo; + + size_t encoded = EVP_EncodeBlock(out, ctx->data, sizeof(ctx->data)); + ctx->data_used = 0; + + out += encoded; + *(out++) = '\n'; + *out = '\0'; + + total = encoded + 1; + } + + while (in_len >= sizeof(ctx->data)) { + size_t encoded = EVP_EncodeBlock(out, in, sizeof(ctx->data)); + in += sizeof(ctx->data); + in_len -= sizeof(ctx->data); + + out += encoded; + *(out++) = '\n'; + *out = '\0'; + + if (total + encoded + 1 < total) { + *out_len = 0; + return; + } + + total += encoded + 1; + } + + if (in_len != 0) { + OPENSSL_memcpy(ctx->data, in, in_len); + } + + ctx->data_used = (unsigned)in_len; + + if (total > INT_MAX) { + // We cannot signal an error, but we can at least avoid making *out_len + // negative. + total = 0; + } + *out_len = (int)total; +} + +void EVP_EncodeFinal(EVP_ENCODE_CTX *ctx, uint8_t *out, int *out_len) { + if (ctx->data_used == 0) { + *out_len = 0; + return; + } + + size_t encoded = EVP_EncodeBlock(out, ctx->data, ctx->data_used); + out[encoded++] = '\n'; + out[encoded] = '\0'; + ctx->data_used = 0; + + // ctx->data_used is bounded by sizeof(ctx->data), so this does not + // overflow. + assert(encoded <= INT_MAX); + *out_len = (int)encoded; +} + +size_t EVP_EncodeBlock(uint8_t *dst, const uint8_t *src, size_t src_len) { + uint32_t l; + size_t remaining = src_len, ret = 0; + + while (remaining) { + if (remaining >= 3) { + l = (((uint32_t)src[0]) << 16L) | (((uint32_t)src[1]) << 8L) | src[2]; + *(dst++) = conv_bin2ascii(l >> 18L); + *(dst++) = conv_bin2ascii(l >> 12L); + *(dst++) = conv_bin2ascii(l >> 6L); + *(dst++) = conv_bin2ascii(l); + remaining -= 3; + } else { + l = ((uint32_t)src[0]) << 16L; + if (remaining == 2) { + l |= ((uint32_t)src[1] << 8L); + } + + *(dst++) = conv_bin2ascii(l >> 18L); + *(dst++) = conv_bin2ascii(l >> 12L); + *(dst++) = (remaining == 1) ? '=' : conv_bin2ascii(l >> 6L); + *(dst++) = '='; + remaining = 0; + } + ret += 4; + src += 3; + } + + *dst = '\0'; + return ret; +} + + +// Decoding. + +int EVP_DecodedLength(size_t *out_len, size_t len) { + if (len % 4 != 0) { + return 0; + } + + *out_len = (len / 4) * 3; + return 1; +} + +void EVP_DecodeInit(EVP_ENCODE_CTX *ctx) { + OPENSSL_memset(ctx, 0, sizeof(EVP_ENCODE_CTX)); +} + +static uint8_t base64_ascii_to_bin(uint8_t a) { + // Since PEM is sometimes used to carry private keys, we decode base64 data + // itself in constant-time. + const uint8_t is_upper = constant_time_in_range_8(a, 'A', 'Z'); + const uint8_t is_lower = constant_time_in_range_8(a, 'a', 'z'); + const uint8_t is_digit = constant_time_in_range_8(a, '0', '9'); + const uint8_t is_plus = constant_time_eq_8(a, '+'); + const uint8_t is_slash = constant_time_eq_8(a, '/'); + const uint8_t is_equals = constant_time_eq_8(a, '='); + + uint8_t ret = 0xff; // 0xff signals invalid. + ret = constant_time_select_8(is_upper, a - 'A', ret); // [0,26) + ret = constant_time_select_8(is_lower, a - 'a' + 26, ret); // [26,52) + ret = constant_time_select_8(is_digit, a - '0' + 52, ret); // [52,62) + ret = constant_time_select_8(is_plus, 62, ret); + ret = constant_time_select_8(is_slash, 63, ret); + // Padding maps to zero, to be further handled by the caller. + ret = constant_time_select_8(is_equals, 0, ret); + return ret; +} + +// base64_decode_quad decodes a single “quad” (i.e. four characters) of base64 +// data and writes up to three bytes to |out|. It sets |*out_num_bytes| to the +// number of bytes written, which will be less than three if the quad ended +// with padding. It returns one on success or zero on error. +static int base64_decode_quad(uint8_t *out, size_t *out_num_bytes, + const uint8_t *in) { + const uint8_t a = base64_ascii_to_bin(in[0]); + const uint8_t b = base64_ascii_to_bin(in[1]); + const uint8_t c = base64_ascii_to_bin(in[2]); + const uint8_t d = base64_ascii_to_bin(in[3]); + if (a == 0xff || b == 0xff || c == 0xff || d == 0xff) { + return 0; + } + + const uint32_t v = ((uint32_t)a) << 18 | ((uint32_t)b) << 12 | + ((uint32_t)c) << 6 | (uint32_t)d; + + const unsigned padding_pattern = (in[0] == '=') << 3 | + (in[1] == '=') << 2 | + (in[2] == '=') << 1 | + (in[3] == '='); + + switch (padding_pattern) { + case 0: + // The common case of no padding. + *out_num_bytes = 3; + out[0] = v >> 16; + out[1] = v >> 8; + out[2] = v; + break; + + case 1: // xxx= + *out_num_bytes = 2; + out[0] = v >> 16; + out[1] = v >> 8; + break; + + case 3: // xx== + *out_num_bytes = 1; + out[0] = v >> 16; + break; + + default: + return 0; + } + + return 1; +} + +int EVP_DecodeUpdate(EVP_ENCODE_CTX *ctx, uint8_t *out, int *out_len, + const uint8_t *in, size_t in_len) { + *out_len = 0; + + if (ctx->error_encountered) { + return -1; + } + + size_t bytes_out = 0, i; + for (i = 0; i < in_len; i++) { + const char c = in[i]; + switch (c) { + case ' ': + case '\t': + case '\r': + case '\n': + continue; + } + + if (ctx->eof_seen) { + ctx->error_encountered = 1; + return -1; + } + + ctx->data[ctx->data_used++] = c; + if (ctx->data_used == 4) { + size_t num_bytes_resulting; + if (!base64_decode_quad(out, &num_bytes_resulting, ctx->data)) { + ctx->error_encountered = 1; + return -1; + } + + ctx->data_used = 0; + bytes_out += num_bytes_resulting; + out += num_bytes_resulting; + + if (num_bytes_resulting < 3) { + ctx->eof_seen = 1; + } + } + } + + if (bytes_out > INT_MAX) { + ctx->error_encountered = 1; + *out_len = 0; + return -1; + } + *out_len = (int)bytes_out; + + if (ctx->eof_seen) { + return 0; + } + + return 1; +} + +int EVP_DecodeFinal(EVP_ENCODE_CTX *ctx, uint8_t *out, int *out_len) { + *out_len = 0; + if (ctx->error_encountered || ctx->data_used != 0) { + return -1; + } + + return 1; +} + +int EVP_DecodeBase64(uint8_t *out, size_t *out_len, size_t max_out, + const uint8_t *in, size_t in_len) { + *out_len = 0; + + if (in_len % 4 != 0) { + return 0; + } + + size_t max_len; + if (!EVP_DecodedLength(&max_len, in_len) || + max_out < max_len) { + return 0; + } + + size_t i, bytes_out = 0; + for (i = 0; i < in_len; i += 4) { + size_t num_bytes_resulting; + + if (!base64_decode_quad(out, &num_bytes_resulting, &in[i])) { + return 0; + } + + bytes_out += num_bytes_resulting; + out += num_bytes_resulting; + if (num_bytes_resulting != 3 && i != in_len - 4) { + return 0; + } + } + + *out_len = bytes_out; + return 1; +} + +int EVP_DecodeBlock(uint8_t *dst, const uint8_t *src, size_t src_len) { + // Trim spaces and tabs from the beginning of the input. + while (src_len > 0) { + if (src[0] != ' ' && src[0] != '\t') { + break; + } + + src++; + src_len--; + } + + // Trim newlines, spaces and tabs from the end of the line. + while (src_len > 0) { + switch (src[src_len-1]) { + case ' ': + case '\t': + case '\r': + case '\n': + src_len--; + continue; + } + + break; + } + + size_t dst_len; + if (!EVP_DecodedLength(&dst_len, src_len) || + dst_len > INT_MAX || + !EVP_DecodeBase64(dst, &dst_len, dst_len, src, src_len)) { + return -1; + } + + // EVP_DecodeBlock does not take padding into account, so put the + // NULs back in... so the caller can strip them back out. + while (dst_len % 3 != 0) { + dst[dst_len++] = '\0'; + } + assert(dst_len <= INT_MAX); + + return (int)dst_len; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/base64/base64.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/base64/base64.c.grpc_back new file mode 100644 index 0000000..b701b0d --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/base64/base64.c.grpc_back @@ -0,0 +1,466 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 + +#include "../internal.h" + + +// constant_time_lt_args_8 behaves like |constant_time_lt_8| but takes |uint8_t| +// arguments for a slightly simpler implementation. +static inline uint8_t constant_time_lt_args_8(uint8_t a, uint8_t b) { + crypto_word_t aw = a; + crypto_word_t bw = b; + // |crypto_word_t| is larger than |uint8_t|, so |aw| and |bw| have the same + // MSB. |aw| < |bw| iff MSB(|aw| - |bw|) is 1. + return constant_time_msb_w(aw - bw); +} + +// constant_time_in_range_8 returns |CONSTTIME_TRUE_8| if |min| <= |a| <= |max| +// and |CONSTTIME_FALSE_8| otherwise. +static inline uint8_t constant_time_in_range_8(uint8_t a, uint8_t min, + uint8_t max) { + a -= min; + return constant_time_lt_args_8(a, max - min + 1); +} + +// Encoding. + +static uint8_t conv_bin2ascii(uint8_t a) { + // Since PEM is sometimes used to carry private keys, we encode base64 data + // itself in constant-time. + a &= 0x3f; + uint8_t ret = constant_time_select_8(constant_time_eq_8(a, 62), '+', '/'); + ret = + constant_time_select_8(constant_time_lt_args_8(a, 62), a - 52 + '0', ret); + ret = + constant_time_select_8(constant_time_lt_args_8(a, 52), a - 26 + 'a', ret); + ret = constant_time_select_8(constant_time_lt_args_8(a, 26), a + 'A', ret); + return ret; +} + +OPENSSL_COMPILE_ASSERT(sizeof(((EVP_ENCODE_CTX *)(NULL))->data) % 3 == 0, + data_length_must_be_multiple_of_base64_chunk_size); + +int EVP_EncodedLength(size_t *out_len, size_t len) { + if (len + 2 < len) { + return 0; + } + len += 2; + len /= 3; + + if (((len << 2) >> 2) != len) { + return 0; + } + len <<= 2; + + if (len + 1 < len) { + return 0; + } + len++; + + *out_len = len; + return 1; +} + +void EVP_EncodeInit(EVP_ENCODE_CTX *ctx) { + OPENSSL_memset(ctx, 0, sizeof(EVP_ENCODE_CTX)); +} + +void EVP_EncodeUpdate(EVP_ENCODE_CTX *ctx, uint8_t *out, int *out_len, + const uint8_t *in, size_t in_len) { + size_t total = 0; + + *out_len = 0; + if (in_len == 0) { + return; + } + + assert(ctx->data_used < sizeof(ctx->data)); + + if (sizeof(ctx->data) - ctx->data_used > in_len) { + OPENSSL_memcpy(&ctx->data[ctx->data_used], in, in_len); + ctx->data_used += (unsigned)in_len; + return; + } + + if (ctx->data_used != 0) { + const size_t todo = sizeof(ctx->data) - ctx->data_used; + OPENSSL_memcpy(&ctx->data[ctx->data_used], in, todo); + in += todo; + in_len -= todo; + + size_t encoded = EVP_EncodeBlock(out, ctx->data, sizeof(ctx->data)); + ctx->data_used = 0; + + out += encoded; + *(out++) = '\n'; + *out = '\0'; + + total = encoded + 1; + } + + while (in_len >= sizeof(ctx->data)) { + size_t encoded = EVP_EncodeBlock(out, in, sizeof(ctx->data)); + in += sizeof(ctx->data); + in_len -= sizeof(ctx->data); + + out += encoded; + *(out++) = '\n'; + *out = '\0'; + + if (total + encoded + 1 < total) { + *out_len = 0; + return; + } + + total += encoded + 1; + } + + if (in_len != 0) { + OPENSSL_memcpy(ctx->data, in, in_len); + } + + ctx->data_used = (unsigned)in_len; + + if (total > INT_MAX) { + // We cannot signal an error, but we can at least avoid making *out_len + // negative. + total = 0; + } + *out_len = (int)total; +} + +void EVP_EncodeFinal(EVP_ENCODE_CTX *ctx, uint8_t *out, int *out_len) { + if (ctx->data_used == 0) { + *out_len = 0; + return; + } + + size_t encoded = EVP_EncodeBlock(out, ctx->data, ctx->data_used); + out[encoded++] = '\n'; + out[encoded] = '\0'; + ctx->data_used = 0; + + // ctx->data_used is bounded by sizeof(ctx->data), so this does not + // overflow. + assert(encoded <= INT_MAX); + *out_len = (int)encoded; +} + +size_t EVP_EncodeBlock(uint8_t *dst, const uint8_t *src, size_t src_len) { + uint32_t l; + size_t remaining = src_len, ret = 0; + + while (remaining) { + if (remaining >= 3) { + l = (((uint32_t)src[0]) << 16L) | (((uint32_t)src[1]) << 8L) | src[2]; + *(dst++) = conv_bin2ascii(l >> 18L); + *(dst++) = conv_bin2ascii(l >> 12L); + *(dst++) = conv_bin2ascii(l >> 6L); + *(dst++) = conv_bin2ascii(l); + remaining -= 3; + } else { + l = ((uint32_t)src[0]) << 16L; + if (remaining == 2) { + l |= ((uint32_t)src[1] << 8L); + } + + *(dst++) = conv_bin2ascii(l >> 18L); + *(dst++) = conv_bin2ascii(l >> 12L); + *(dst++) = (remaining == 1) ? '=' : conv_bin2ascii(l >> 6L); + *(dst++) = '='; + remaining = 0; + } + ret += 4; + src += 3; + } + + *dst = '\0'; + return ret; +} + + +// Decoding. + +int EVP_DecodedLength(size_t *out_len, size_t len) { + if (len % 4 != 0) { + return 0; + } + + *out_len = (len / 4) * 3; + return 1; +} + +void EVP_DecodeInit(EVP_ENCODE_CTX *ctx) { + OPENSSL_memset(ctx, 0, sizeof(EVP_ENCODE_CTX)); +} + +static uint8_t base64_ascii_to_bin(uint8_t a) { + // Since PEM is sometimes used to carry private keys, we decode base64 data + // itself in constant-time. + const uint8_t is_upper = constant_time_in_range_8(a, 'A', 'Z'); + const uint8_t is_lower = constant_time_in_range_8(a, 'a', 'z'); + const uint8_t is_digit = constant_time_in_range_8(a, '0', '9'); + const uint8_t is_plus = constant_time_eq_8(a, '+'); + const uint8_t is_slash = constant_time_eq_8(a, '/'); + const uint8_t is_equals = constant_time_eq_8(a, '='); + + uint8_t ret = 0xff; // 0xff signals invalid. + ret = constant_time_select_8(is_upper, a - 'A', ret); // [0,26) + ret = constant_time_select_8(is_lower, a - 'a' + 26, ret); // [26,52) + ret = constant_time_select_8(is_digit, a - '0' + 52, ret); // [52,62) + ret = constant_time_select_8(is_plus, 62, ret); + ret = constant_time_select_8(is_slash, 63, ret); + // Padding maps to zero, to be further handled by the caller. + ret = constant_time_select_8(is_equals, 0, ret); + return ret; +} + +// base64_decode_quad decodes a single “quad” (i.e. four characters) of base64 +// data and writes up to three bytes to |out|. It sets |*out_num_bytes| to the +// number of bytes written, which will be less than three if the quad ended +// with padding. It returns one on success or zero on error. +static int base64_decode_quad(uint8_t *out, size_t *out_num_bytes, + const uint8_t *in) { + const uint8_t a = base64_ascii_to_bin(in[0]); + const uint8_t b = base64_ascii_to_bin(in[1]); + const uint8_t c = base64_ascii_to_bin(in[2]); + const uint8_t d = base64_ascii_to_bin(in[3]); + if (a == 0xff || b == 0xff || c == 0xff || d == 0xff) { + return 0; + } + + const uint32_t v = ((uint32_t)a) << 18 | ((uint32_t)b) << 12 | + ((uint32_t)c) << 6 | (uint32_t)d; + + const unsigned padding_pattern = (in[0] == '=') << 3 | + (in[1] == '=') << 2 | + (in[2] == '=') << 1 | + (in[3] == '='); + + switch (padding_pattern) { + case 0: + // The common case of no padding. + *out_num_bytes = 3; + out[0] = v >> 16; + out[1] = v >> 8; + out[2] = v; + break; + + case 1: // xxx= + *out_num_bytes = 2; + out[0] = v >> 16; + out[1] = v >> 8; + break; + + case 3: // xx== + *out_num_bytes = 1; + out[0] = v >> 16; + break; + + default: + return 0; + } + + return 1; +} + +int EVP_DecodeUpdate(EVP_ENCODE_CTX *ctx, uint8_t *out, int *out_len, + const uint8_t *in, size_t in_len) { + *out_len = 0; + + if (ctx->error_encountered) { + return -1; + } + + size_t bytes_out = 0, i; + for (i = 0; i < in_len; i++) { + const char c = in[i]; + switch (c) { + case ' ': + case '\t': + case '\r': + case '\n': + continue; + } + + if (ctx->eof_seen) { + ctx->error_encountered = 1; + return -1; + } + + ctx->data[ctx->data_used++] = c; + if (ctx->data_used == 4) { + size_t num_bytes_resulting; + if (!base64_decode_quad(out, &num_bytes_resulting, ctx->data)) { + ctx->error_encountered = 1; + return -1; + } + + ctx->data_used = 0; + bytes_out += num_bytes_resulting; + out += num_bytes_resulting; + + if (num_bytes_resulting < 3) { + ctx->eof_seen = 1; + } + } + } + + if (bytes_out > INT_MAX) { + ctx->error_encountered = 1; + *out_len = 0; + return -1; + } + *out_len = (int)bytes_out; + + if (ctx->eof_seen) { + return 0; + } + + return 1; +} + +int EVP_DecodeFinal(EVP_ENCODE_CTX *ctx, uint8_t *out, int *out_len) { + *out_len = 0; + if (ctx->error_encountered || ctx->data_used != 0) { + return -1; + } + + return 1; +} + +int EVP_DecodeBase64(uint8_t *out, size_t *out_len, size_t max_out, + const uint8_t *in, size_t in_len) { + *out_len = 0; + + if (in_len % 4 != 0) { + return 0; + } + + size_t max_len; + if (!EVP_DecodedLength(&max_len, in_len) || + max_out < max_len) { + return 0; + } + + size_t i, bytes_out = 0; + for (i = 0; i < in_len; i += 4) { + size_t num_bytes_resulting; + + if (!base64_decode_quad(out, &num_bytes_resulting, &in[i])) { + return 0; + } + + bytes_out += num_bytes_resulting; + out += num_bytes_resulting; + if (num_bytes_resulting != 3 && i != in_len - 4) { + return 0; + } + } + + *out_len = bytes_out; + return 1; +} + +int EVP_DecodeBlock(uint8_t *dst, const uint8_t *src, size_t src_len) { + // Trim spaces and tabs from the beginning of the input. + while (src_len > 0) { + if (src[0] != ' ' && src[0] != '\t') { + break; + } + + src++; + src_len--; + } + + // Trim newlines, spaces and tabs from the end of the line. + while (src_len > 0) { + switch (src[src_len-1]) { + case ' ': + case '\t': + case '\r': + case '\n': + src_len--; + continue; + } + + break; + } + + size_t dst_len; + if (!EVP_DecodedLength(&dst_len, src_len) || + dst_len > INT_MAX || + !EVP_DecodeBase64(dst, &dst_len, dst_len, src, src_len)) { + return -1; + } + + // EVP_DecodeBlock does not take padding into account, so put the + // NULs back in... so the caller can strip them back out. + while (dst_len % 3 != 0) { + dst[dst_len++] = '\0'; + } + assert(dst_len <= INT_MAX); + + return (int)dst_len; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/bio/bio.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/bio/bio.c new file mode 100644 index 0000000..0df245d --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/bio/bio.c @@ -0,0 +1,636 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 + +#include +#include +#include + +#include "../internal.h" + + +BIO *BIO_new(const BIO_METHOD *method) { + BIO *ret = OPENSSL_malloc(sizeof(BIO)); + if (ret == NULL) { + OPENSSL_PUT_ERROR(BIO, ERR_R_MALLOC_FAILURE); + return NULL; + } + + OPENSSL_memset(ret, 0, sizeof(BIO)); + ret->method = method; + ret->shutdown = 1; + ret->references = 1; + + if (method->create != NULL && !method->create(ret)) { + OPENSSL_free(ret); + return NULL; + } + + return ret; +} + +int BIO_free(BIO *bio) { + BIO *next_bio; + + for (; bio != NULL; bio = next_bio) { + if (!CRYPTO_refcount_dec_and_test_zero(&bio->references)) { + return 0; + } + + next_bio = BIO_pop(bio); + + if (bio->method != NULL && bio->method->destroy != NULL) { + bio->method->destroy(bio); + } + + OPENSSL_free(bio); + } + return 1; +} + +int BIO_up_ref(BIO *bio) { + CRYPTO_refcount_inc(&bio->references); + return 1; +} + +void BIO_vfree(BIO *bio) { + BIO_free(bio); +} + +void BIO_free_all(BIO *bio) { + BIO_free(bio); +} + +int BIO_read(BIO *bio, void *buf, int len) { + if (bio == NULL || bio->method == NULL || bio->method->bread == NULL) { + OPENSSL_PUT_ERROR(BIO, BIO_R_UNSUPPORTED_METHOD); + return -2; + } + if (!bio->init) { + OPENSSL_PUT_ERROR(BIO, BIO_R_UNINITIALIZED); + return -2; + } + if (len <= 0) { + return 0; + } + int ret = bio->method->bread(bio, buf, len); + if (ret > 0) { + bio->num_read += ret; + } + return ret; +} + +int BIO_gets(BIO *bio, char *buf, int len) { + if (bio == NULL || bio->method == NULL || bio->method->bgets == NULL) { + OPENSSL_PUT_ERROR(BIO, BIO_R_UNSUPPORTED_METHOD); + return -2; + } + if (!bio->init) { + OPENSSL_PUT_ERROR(BIO, BIO_R_UNINITIALIZED); + return -2; + } + if (len <= 0) { + return 0; + } + int ret = bio->method->bgets(bio, buf, len); + if (ret > 0) { + bio->num_read += ret; + } + return ret; +} + +int BIO_write(BIO *bio, const void *in, int inl) { + if (bio == NULL || bio->method == NULL || bio->method->bwrite == NULL) { + OPENSSL_PUT_ERROR(BIO, BIO_R_UNSUPPORTED_METHOD); + return -2; + } + if (!bio->init) { + OPENSSL_PUT_ERROR(BIO, BIO_R_UNINITIALIZED); + return -2; + } + if (inl <= 0) { + return 0; + } + int ret = bio->method->bwrite(bio, in, inl); + if (ret > 0) { + bio->num_write += ret; + } + return ret; +} + +int BIO_puts(BIO *bio, const char *in) { + return BIO_write(bio, in, strlen(in)); +} + +int BIO_flush(BIO *bio) { + return BIO_ctrl(bio, BIO_CTRL_FLUSH, 0, NULL); +} + +long BIO_ctrl(BIO *bio, int cmd, long larg, void *parg) { + if (bio == NULL) { + return 0; + } + + if (bio->method == NULL || bio->method->ctrl == NULL) { + OPENSSL_PUT_ERROR(BIO, BIO_R_UNSUPPORTED_METHOD); + return -2; + } + + return bio->method->ctrl(bio, cmd, larg, parg); +} + +char *BIO_ptr_ctrl(BIO *b, int cmd, long larg) { + char *p = NULL; + + if (BIO_ctrl(b, cmd, larg, (void *)&p) <= 0) { + return NULL; + } + + return p; +} + +long BIO_int_ctrl(BIO *b, int cmd, long larg, int iarg) { + int i = iarg; + + return BIO_ctrl(b, cmd, larg, (void *)&i); +} + +int BIO_reset(BIO *bio) { + return BIO_ctrl(bio, BIO_CTRL_RESET, 0, NULL); +} + +int BIO_eof(BIO *bio) { + return BIO_ctrl(bio, BIO_CTRL_EOF, 0, NULL); +} + +void BIO_set_flags(BIO *bio, int flags) { + bio->flags |= flags; +} + +int BIO_test_flags(const BIO *bio, int flags) { + return bio->flags & flags; +} + +int BIO_should_read(const BIO *bio) { + return BIO_test_flags(bio, BIO_FLAGS_READ); +} + +int BIO_should_write(const BIO *bio) { + return BIO_test_flags(bio, BIO_FLAGS_WRITE); +} + +int BIO_should_retry(const BIO *bio) { + return BIO_test_flags(bio, BIO_FLAGS_SHOULD_RETRY); +} + +int BIO_should_io_special(const BIO *bio) { + return BIO_test_flags(bio, BIO_FLAGS_IO_SPECIAL); +} + +int BIO_get_retry_reason(const BIO *bio) { return bio->retry_reason; } + +void BIO_clear_flags(BIO *bio, int flags) { + bio->flags &= ~flags; +} + +void BIO_set_retry_read(BIO *bio) { + bio->flags |= BIO_FLAGS_READ | BIO_FLAGS_SHOULD_RETRY; +} + +void BIO_set_retry_write(BIO *bio) { + bio->flags |= BIO_FLAGS_WRITE | BIO_FLAGS_SHOULD_RETRY; +} + +static const int kRetryFlags = BIO_FLAGS_RWS | BIO_FLAGS_SHOULD_RETRY; + +int BIO_get_retry_flags(BIO *bio) { + return bio->flags & kRetryFlags; +} + +void BIO_clear_retry_flags(BIO *bio) { + bio->flags &= ~kRetryFlags; + bio->retry_reason = 0; +} + +int BIO_method_type(const BIO *bio) { return bio->method->type; } + +void BIO_copy_next_retry(BIO *bio) { + BIO_clear_retry_flags(bio); + BIO_set_flags(bio, BIO_get_retry_flags(bio->next_bio)); + bio->retry_reason = bio->next_bio->retry_reason; +} + +long BIO_callback_ctrl(BIO *bio, int cmd, bio_info_cb fp) { + if (bio == NULL) { + return 0; + } + + if (bio->method == NULL || bio->method->callback_ctrl == NULL) { + OPENSSL_PUT_ERROR(BIO, BIO_R_UNSUPPORTED_METHOD); + return 0; + } + + return bio->method->callback_ctrl(bio, cmd, fp); +} + +size_t BIO_pending(const BIO *bio) { + const long r = BIO_ctrl((BIO *) bio, BIO_CTRL_PENDING, 0, NULL); + assert(r >= 0); + + if (r < 0) { + return 0; + } + return r; +} + +size_t BIO_ctrl_pending(const BIO *bio) { + return BIO_pending(bio); +} + +size_t BIO_wpending(const BIO *bio) { + const long r = BIO_ctrl((BIO *) bio, BIO_CTRL_WPENDING, 0, NULL); + assert(r >= 0); + + if (r < 0) { + return 0; + } + return r; +} + +int BIO_set_close(BIO *bio, int close_flag) { + return BIO_ctrl(bio, BIO_CTRL_SET_CLOSE, close_flag, NULL); +} + +OPENSSL_EXPORT size_t BIO_number_read(const BIO *bio) { + return bio->num_read; +} + +OPENSSL_EXPORT size_t BIO_number_written(const BIO *bio) { + return bio->num_write; +} + +BIO *BIO_push(BIO *bio, BIO *appended_bio) { + BIO *last_bio; + + if (bio == NULL) { + return bio; + } + + last_bio = bio; + while (last_bio->next_bio != NULL) { + last_bio = last_bio->next_bio; + } + + last_bio->next_bio = appended_bio; + return bio; +} + +BIO *BIO_pop(BIO *bio) { + BIO *ret; + + if (bio == NULL) { + return NULL; + } + ret = bio->next_bio; + bio->next_bio = NULL; + return ret; +} + +BIO *BIO_next(BIO *bio) { + if (!bio) { + return NULL; + } + return bio->next_bio; +} + +BIO *BIO_find_type(BIO *bio, int type) { + int method_type, mask; + + if (!bio) { + return NULL; + } + mask = type & 0xff; + + do { + if (bio->method != NULL) { + method_type = bio->method->type; + + if (!mask) { + if (method_type & type) { + return bio; + } + } else if (method_type == type) { + return bio; + } + } + bio = bio->next_bio; + } while (bio != NULL); + + return NULL; +} + +int BIO_indent(BIO *bio, unsigned indent, unsigned max_indent) { + if (indent > max_indent) { + indent = max_indent; + } + + while (indent--) { + if (BIO_puts(bio, " ") != 1) { + return 0; + } + } + return 1; +} + +static int print_bio(const char *str, size_t len, void *bio) { + return BIO_write((BIO *)bio, str, len); +} + +void ERR_print_errors(BIO *bio) { + ERR_print_errors_cb(print_bio, bio); +} + +// bio_read_all reads everything from |bio| and prepends |prefix| to it. On +// success, |*out| is set to an allocated buffer (which should be freed with +// |OPENSSL_free|), |*out_len| is set to its length and one is returned. The +// buffer will contain |prefix| followed by the contents of |bio|. On failure, +// zero is returned. +// +// The function will fail if the size of the output would equal or exceed +// |max_len|. +static int bio_read_all(BIO *bio, uint8_t **out, size_t *out_len, + const uint8_t *prefix, size_t prefix_len, + size_t max_len) { + static const size_t kChunkSize = 4096; + + size_t len = prefix_len + kChunkSize; + if (len > max_len) { + len = max_len; + } + if (len < prefix_len) { + return 0; + } + *out = OPENSSL_malloc(len); + if (*out == NULL) { + return 0; + } + OPENSSL_memcpy(*out, prefix, prefix_len); + size_t done = prefix_len; + + for (;;) { + if (done == len) { + OPENSSL_free(*out); + return 0; + } + const size_t todo = len - done; + assert(todo < INT_MAX); + const int n = BIO_read(bio, *out + done, todo); + if (n == 0) { + *out_len = done; + return 1; + } else if (n == -1) { + OPENSSL_free(*out); + return 0; + } + + done += n; + if (len < max_len && len - done < kChunkSize / 2) { + len += kChunkSize; + if (len < kChunkSize || len > max_len) { + len = max_len; + } + uint8_t *new_buf = OPENSSL_realloc(*out, len); + if (new_buf == NULL) { + OPENSSL_free(*out); + return 0; + } + *out = new_buf; + } + } +} + +int BIO_read_asn1(BIO *bio, uint8_t **out, size_t *out_len, size_t max_len) { + uint8_t header[6]; + + static const size_t kInitialHeaderLen = 2; + if (BIO_read(bio, header, kInitialHeaderLen) != (int) kInitialHeaderLen) { + return 0; + } + + const uint8_t tag = header[0]; + const uint8_t length_byte = header[1]; + + if ((tag & 0x1f) == 0x1f) { + // Long form tags are not supported. + return 0; + } + + size_t len, header_len; + if ((length_byte & 0x80) == 0) { + // Short form length. + len = length_byte; + header_len = kInitialHeaderLen; + } else { + const size_t num_bytes = length_byte & 0x7f; + + if ((tag & 0x20 /* constructed */) != 0 && num_bytes == 0) { + // indefinite length. + return bio_read_all(bio, out, out_len, header, kInitialHeaderLen, + max_len); + } + + if (num_bytes == 0 || num_bytes > 4) { + return 0; + } + + if (BIO_read(bio, header + kInitialHeaderLen, num_bytes) != + (int)num_bytes) { + return 0; + } + header_len = kInitialHeaderLen + num_bytes; + + uint32_t len32 = 0; + unsigned i; + for (i = 0; i < num_bytes; i++) { + len32 <<= 8; + len32 |= header[kInitialHeaderLen + i]; + } + + if (len32 < 128) { + // Length should have used short-form encoding. + return 0; + } + + if ((len32 >> ((num_bytes-1)*8)) == 0) { + // Length should have been at least one byte shorter. + return 0; + } + + len = len32; + } + + if (len + header_len < len || + len + header_len > max_len || + len > INT_MAX) { + return 0; + } + len += header_len; + *out_len = len; + + *out = OPENSSL_malloc(len); + if (*out == NULL) { + return 0; + } + OPENSSL_memcpy(*out, header, header_len); + if (BIO_read(bio, (*out) + header_len, len - header_len) != + (int) (len - header_len)) { + OPENSSL_free(*out); + return 0; + } + + return 1; +} + +void BIO_set_retry_special(BIO *bio) { + bio->flags |= BIO_FLAGS_READ | BIO_FLAGS_IO_SPECIAL; +} + +int BIO_set_write_buffer_size(BIO *bio, int buffer_size) { return 0; } + +static struct CRYPTO_STATIC_MUTEX g_index_lock = CRYPTO_STATIC_MUTEX_INIT; +static int g_index = BIO_TYPE_START; + +int BIO_get_new_index(void) { + CRYPTO_STATIC_MUTEX_lock_write(&g_index_lock); + // If |g_index| exceeds 255, it will collide with the flags bits. + int ret = g_index > 255 ? -1 : g_index++; + CRYPTO_STATIC_MUTEX_unlock_write(&g_index_lock); + return ret; +} + +BIO_METHOD *BIO_meth_new(int type, const char *name) { + BIO_METHOD *method = OPENSSL_malloc(sizeof(BIO_METHOD)); + if (method == NULL) { + return NULL; + } + OPENSSL_memset(method, 0, sizeof(BIO_METHOD)); + method->type = type; + method->name = name; + return method; +} + +void BIO_meth_free(BIO_METHOD *method) { + OPENSSL_free(method); +} + +int BIO_meth_set_create(BIO_METHOD *method, + int (*create)(BIO *)) { + method->create = create; + return 1; +} + +int BIO_meth_set_destroy(BIO_METHOD *method, + int (*destroy)(BIO *)) { + method->destroy = destroy; + return 1; +} + +int BIO_meth_set_write(BIO_METHOD *method, + int (*write)(BIO *, const char *, int)) { + method->bwrite = write; + return 1; +} + +int BIO_meth_set_read(BIO_METHOD *method, + int (*read)(BIO *, char *, int)) { + method->bread = read; + return 1; +} + +int BIO_meth_set_gets(BIO_METHOD *method, + int (*gets)(BIO *, char *, int)) { + method->bgets = gets; + return 1; +} + +int BIO_meth_set_ctrl(BIO_METHOD *method, + long (*ctrl)(BIO *, int, long, void *)) { + method->ctrl = ctrl; + return 1; +} + +void BIO_set_data(BIO *bio, void *ptr) { bio->ptr = ptr; } + +void *BIO_get_data(BIO *bio) { return bio->ptr; } + +void BIO_set_init(BIO *bio, int init) { bio->init = init; } + +int BIO_get_init(BIO *bio) { return bio->init; } + +void BIO_set_shutdown(BIO *bio, int shutdown) { bio->shutdown = shutdown; } + +int BIO_get_shutdown(BIO *bio) { return bio->shutdown; } + +int BIO_meth_set_puts(BIO_METHOD *method, int (*puts)(BIO *, const char *)) { + // Ignore the parameter. We implement |BIO_puts| using |BIO_write|. + return 1; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/bio/bio.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/bio/bio.c.grpc_back new file mode 100644 index 0000000..3e788b8 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/bio/bio.c.grpc_back @@ -0,0 +1,636 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 + +#include +#include +#include + +#include "../internal.h" + + +BIO *BIO_new(const BIO_METHOD *method) { + BIO *ret = OPENSSL_malloc(sizeof(BIO)); + if (ret == NULL) { + OPENSSL_PUT_ERROR(BIO, ERR_R_MALLOC_FAILURE); + return NULL; + } + + OPENSSL_memset(ret, 0, sizeof(BIO)); + ret->method = method; + ret->shutdown = 1; + ret->references = 1; + + if (method->create != NULL && !method->create(ret)) { + OPENSSL_free(ret); + return NULL; + } + + return ret; +} + +int BIO_free(BIO *bio) { + BIO *next_bio; + + for (; bio != NULL; bio = next_bio) { + if (!CRYPTO_refcount_dec_and_test_zero(&bio->references)) { + return 0; + } + + next_bio = BIO_pop(bio); + + if (bio->method != NULL && bio->method->destroy != NULL) { + bio->method->destroy(bio); + } + + OPENSSL_free(bio); + } + return 1; +} + +int BIO_up_ref(BIO *bio) { + CRYPTO_refcount_inc(&bio->references); + return 1; +} + +void BIO_vfree(BIO *bio) { + BIO_free(bio); +} + +void BIO_free_all(BIO *bio) { + BIO_free(bio); +} + +int BIO_read(BIO *bio, void *buf, int len) { + if (bio == NULL || bio->method == NULL || bio->method->bread == NULL) { + OPENSSL_PUT_ERROR(BIO, BIO_R_UNSUPPORTED_METHOD); + return -2; + } + if (!bio->init) { + OPENSSL_PUT_ERROR(BIO, BIO_R_UNINITIALIZED); + return -2; + } + if (len <= 0) { + return 0; + } + int ret = bio->method->bread(bio, buf, len); + if (ret > 0) { + bio->num_read += ret; + } + return ret; +} + +int BIO_gets(BIO *bio, char *buf, int len) { + if (bio == NULL || bio->method == NULL || bio->method->bgets == NULL) { + OPENSSL_PUT_ERROR(BIO, BIO_R_UNSUPPORTED_METHOD); + return -2; + } + if (!bio->init) { + OPENSSL_PUT_ERROR(BIO, BIO_R_UNINITIALIZED); + return -2; + } + if (len <= 0) { + return 0; + } + int ret = bio->method->bgets(bio, buf, len); + if (ret > 0) { + bio->num_read += ret; + } + return ret; +} + +int BIO_write(BIO *bio, const void *in, int inl) { + if (bio == NULL || bio->method == NULL || bio->method->bwrite == NULL) { + OPENSSL_PUT_ERROR(BIO, BIO_R_UNSUPPORTED_METHOD); + return -2; + } + if (!bio->init) { + OPENSSL_PUT_ERROR(BIO, BIO_R_UNINITIALIZED); + return -2; + } + if (inl <= 0) { + return 0; + } + int ret = bio->method->bwrite(bio, in, inl); + if (ret > 0) { + bio->num_write += ret; + } + return ret; +} + +int BIO_puts(BIO *bio, const char *in) { + return BIO_write(bio, in, strlen(in)); +} + +int BIO_flush(BIO *bio) { + return BIO_ctrl(bio, BIO_CTRL_FLUSH, 0, NULL); +} + +long BIO_ctrl(BIO *bio, int cmd, long larg, void *parg) { + if (bio == NULL) { + return 0; + } + + if (bio->method == NULL || bio->method->ctrl == NULL) { + OPENSSL_PUT_ERROR(BIO, BIO_R_UNSUPPORTED_METHOD); + return -2; + } + + return bio->method->ctrl(bio, cmd, larg, parg); +} + +char *BIO_ptr_ctrl(BIO *b, int cmd, long larg) { + char *p = NULL; + + if (BIO_ctrl(b, cmd, larg, (void *)&p) <= 0) { + return NULL; + } + + return p; +} + +long BIO_int_ctrl(BIO *b, int cmd, long larg, int iarg) { + int i = iarg; + + return BIO_ctrl(b, cmd, larg, (void *)&i); +} + +int BIO_reset(BIO *bio) { + return BIO_ctrl(bio, BIO_CTRL_RESET, 0, NULL); +} + +int BIO_eof(BIO *bio) { + return BIO_ctrl(bio, BIO_CTRL_EOF, 0, NULL); +} + +void BIO_set_flags(BIO *bio, int flags) { + bio->flags |= flags; +} + +int BIO_test_flags(const BIO *bio, int flags) { + return bio->flags & flags; +} + +int BIO_should_read(const BIO *bio) { + return BIO_test_flags(bio, BIO_FLAGS_READ); +} + +int BIO_should_write(const BIO *bio) { + return BIO_test_flags(bio, BIO_FLAGS_WRITE); +} + +int BIO_should_retry(const BIO *bio) { + return BIO_test_flags(bio, BIO_FLAGS_SHOULD_RETRY); +} + +int BIO_should_io_special(const BIO *bio) { + return BIO_test_flags(bio, BIO_FLAGS_IO_SPECIAL); +} + +int BIO_get_retry_reason(const BIO *bio) { return bio->retry_reason; } + +void BIO_clear_flags(BIO *bio, int flags) { + bio->flags &= ~flags; +} + +void BIO_set_retry_read(BIO *bio) { + bio->flags |= BIO_FLAGS_READ | BIO_FLAGS_SHOULD_RETRY; +} + +void BIO_set_retry_write(BIO *bio) { + bio->flags |= BIO_FLAGS_WRITE | BIO_FLAGS_SHOULD_RETRY; +} + +static const int kRetryFlags = BIO_FLAGS_RWS | BIO_FLAGS_SHOULD_RETRY; + +int BIO_get_retry_flags(BIO *bio) { + return bio->flags & kRetryFlags; +} + +void BIO_clear_retry_flags(BIO *bio) { + bio->flags &= ~kRetryFlags; + bio->retry_reason = 0; +} + +int BIO_method_type(const BIO *bio) { return bio->method->type; } + +void BIO_copy_next_retry(BIO *bio) { + BIO_clear_retry_flags(bio); + BIO_set_flags(bio, BIO_get_retry_flags(bio->next_bio)); + bio->retry_reason = bio->next_bio->retry_reason; +} + +long BIO_callback_ctrl(BIO *bio, int cmd, bio_info_cb fp) { + if (bio == NULL) { + return 0; + } + + if (bio->method == NULL || bio->method->callback_ctrl == NULL) { + OPENSSL_PUT_ERROR(BIO, BIO_R_UNSUPPORTED_METHOD); + return 0; + } + + return bio->method->callback_ctrl(bio, cmd, fp); +} + +size_t BIO_pending(const BIO *bio) { + const long r = BIO_ctrl((BIO *) bio, BIO_CTRL_PENDING, 0, NULL); + assert(r >= 0); + + if (r < 0) { + return 0; + } + return r; +} + +size_t BIO_ctrl_pending(const BIO *bio) { + return BIO_pending(bio); +} + +size_t BIO_wpending(const BIO *bio) { + const long r = BIO_ctrl((BIO *) bio, BIO_CTRL_WPENDING, 0, NULL); + assert(r >= 0); + + if (r < 0) { + return 0; + } + return r; +} + +int BIO_set_close(BIO *bio, int close_flag) { + return BIO_ctrl(bio, BIO_CTRL_SET_CLOSE, close_flag, NULL); +} + +OPENSSL_EXPORT size_t BIO_number_read(const BIO *bio) { + return bio->num_read; +} + +OPENSSL_EXPORT size_t BIO_number_written(const BIO *bio) { + return bio->num_write; +} + +BIO *BIO_push(BIO *bio, BIO *appended_bio) { + BIO *last_bio; + + if (bio == NULL) { + return bio; + } + + last_bio = bio; + while (last_bio->next_bio != NULL) { + last_bio = last_bio->next_bio; + } + + last_bio->next_bio = appended_bio; + return bio; +} + +BIO *BIO_pop(BIO *bio) { + BIO *ret; + + if (bio == NULL) { + return NULL; + } + ret = bio->next_bio; + bio->next_bio = NULL; + return ret; +} + +BIO *BIO_next(BIO *bio) { + if (!bio) { + return NULL; + } + return bio->next_bio; +} + +BIO *BIO_find_type(BIO *bio, int type) { + int method_type, mask; + + if (!bio) { + return NULL; + } + mask = type & 0xff; + + do { + if (bio->method != NULL) { + method_type = bio->method->type; + + if (!mask) { + if (method_type & type) { + return bio; + } + } else if (method_type == type) { + return bio; + } + } + bio = bio->next_bio; + } while (bio != NULL); + + return NULL; +} + +int BIO_indent(BIO *bio, unsigned indent, unsigned max_indent) { + if (indent > max_indent) { + indent = max_indent; + } + + while (indent--) { + if (BIO_puts(bio, " ") != 1) { + return 0; + } + } + return 1; +} + +static int print_bio(const char *str, size_t len, void *bio) { + return BIO_write((BIO *)bio, str, len); +} + +void ERR_print_errors(BIO *bio) { + ERR_print_errors_cb(print_bio, bio); +} + +// bio_read_all reads everything from |bio| and prepends |prefix| to it. On +// success, |*out| is set to an allocated buffer (which should be freed with +// |OPENSSL_free|), |*out_len| is set to its length and one is returned. The +// buffer will contain |prefix| followed by the contents of |bio|. On failure, +// zero is returned. +// +// The function will fail if the size of the output would equal or exceed +// |max_len|. +static int bio_read_all(BIO *bio, uint8_t **out, size_t *out_len, + const uint8_t *prefix, size_t prefix_len, + size_t max_len) { + static const size_t kChunkSize = 4096; + + size_t len = prefix_len + kChunkSize; + if (len > max_len) { + len = max_len; + } + if (len < prefix_len) { + return 0; + } + *out = OPENSSL_malloc(len); + if (*out == NULL) { + return 0; + } + OPENSSL_memcpy(*out, prefix, prefix_len); + size_t done = prefix_len; + + for (;;) { + if (done == len) { + OPENSSL_free(*out); + return 0; + } + const size_t todo = len - done; + assert(todo < INT_MAX); + const int n = BIO_read(bio, *out + done, todo); + if (n == 0) { + *out_len = done; + return 1; + } else if (n == -1) { + OPENSSL_free(*out); + return 0; + } + + done += n; + if (len < max_len && len - done < kChunkSize / 2) { + len += kChunkSize; + if (len < kChunkSize || len > max_len) { + len = max_len; + } + uint8_t *new_buf = OPENSSL_realloc(*out, len); + if (new_buf == NULL) { + OPENSSL_free(*out); + return 0; + } + *out = new_buf; + } + } +} + +int BIO_read_asn1(BIO *bio, uint8_t **out, size_t *out_len, size_t max_len) { + uint8_t header[6]; + + static const size_t kInitialHeaderLen = 2; + if (BIO_read(bio, header, kInitialHeaderLen) != (int) kInitialHeaderLen) { + return 0; + } + + const uint8_t tag = header[0]; + const uint8_t length_byte = header[1]; + + if ((tag & 0x1f) == 0x1f) { + // Long form tags are not supported. + return 0; + } + + size_t len, header_len; + if ((length_byte & 0x80) == 0) { + // Short form length. + len = length_byte; + header_len = kInitialHeaderLen; + } else { + const size_t num_bytes = length_byte & 0x7f; + + if ((tag & 0x20 /* constructed */) != 0 && num_bytes == 0) { + // indefinite length. + return bio_read_all(bio, out, out_len, header, kInitialHeaderLen, + max_len); + } + + if (num_bytes == 0 || num_bytes > 4) { + return 0; + } + + if (BIO_read(bio, header + kInitialHeaderLen, num_bytes) != + (int)num_bytes) { + return 0; + } + header_len = kInitialHeaderLen + num_bytes; + + uint32_t len32 = 0; + unsigned i; + for (i = 0; i < num_bytes; i++) { + len32 <<= 8; + len32 |= header[kInitialHeaderLen + i]; + } + + if (len32 < 128) { + // Length should have used short-form encoding. + return 0; + } + + if ((len32 >> ((num_bytes-1)*8)) == 0) { + // Length should have been at least one byte shorter. + return 0; + } + + len = len32; + } + + if (len + header_len < len || + len + header_len > max_len || + len > INT_MAX) { + return 0; + } + len += header_len; + *out_len = len; + + *out = OPENSSL_malloc(len); + if (*out == NULL) { + return 0; + } + OPENSSL_memcpy(*out, header, header_len); + if (BIO_read(bio, (*out) + header_len, len - header_len) != + (int) (len - header_len)) { + OPENSSL_free(*out); + return 0; + } + + return 1; +} + +void BIO_set_retry_special(BIO *bio) { + bio->flags |= BIO_FLAGS_READ | BIO_FLAGS_IO_SPECIAL; +} + +int BIO_set_write_buffer_size(BIO *bio, int buffer_size) { return 0; } + +static struct CRYPTO_STATIC_MUTEX g_index_lock = CRYPTO_STATIC_MUTEX_INIT; +static int g_index = BIO_TYPE_START; + +int BIO_get_new_index(void) { + CRYPTO_STATIC_MUTEX_lock_write(&g_index_lock); + // If |g_index| exceeds 255, it will collide with the flags bits. + int ret = g_index > 255 ? -1 : g_index++; + CRYPTO_STATIC_MUTEX_unlock_write(&g_index_lock); + return ret; +} + +BIO_METHOD *BIO_meth_new(int type, const char *name) { + BIO_METHOD *method = OPENSSL_malloc(sizeof(BIO_METHOD)); + if (method == NULL) { + return NULL; + } + OPENSSL_memset(method, 0, sizeof(BIO_METHOD)); + method->type = type; + method->name = name; + return method; +} + +void BIO_meth_free(BIO_METHOD *method) { + OPENSSL_free(method); +} + +int BIO_meth_set_create(BIO_METHOD *method, + int (*create)(BIO *)) { + method->create = create; + return 1; +} + +int BIO_meth_set_destroy(BIO_METHOD *method, + int (*destroy)(BIO *)) { + method->destroy = destroy; + return 1; +} + +int BIO_meth_set_write(BIO_METHOD *method, + int (*write)(BIO *, const char *, int)) { + method->bwrite = write; + return 1; +} + +int BIO_meth_set_read(BIO_METHOD *method, + int (*read)(BIO *, char *, int)) { + method->bread = read; + return 1; +} + +int BIO_meth_set_gets(BIO_METHOD *method, + int (*gets)(BIO *, char *, int)) { + method->bgets = gets; + return 1; +} + +int BIO_meth_set_ctrl(BIO_METHOD *method, + long (*ctrl)(BIO *, int, long, void *)) { + method->ctrl = ctrl; + return 1; +} + +void BIO_set_data(BIO *bio, void *ptr) { bio->ptr = ptr; } + +void *BIO_get_data(BIO *bio) { return bio->ptr; } + +void BIO_set_init(BIO *bio, int init) { bio->init = init; } + +int BIO_get_init(BIO *bio) { return bio->init; } + +void BIO_set_shutdown(BIO *bio, int shutdown) { bio->shutdown = shutdown; } + +int BIO_get_shutdown(BIO *bio) { return bio->shutdown; } + +int BIO_meth_set_puts(BIO_METHOD *method, int (*puts)(BIO *, const char *)) { + // Ignore the parameter. We implement |BIO_puts| using |BIO_write|. + return 1; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/bio/bio_mem.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/bio/bio_mem.c new file mode 100644 index 0000000..f30fb47 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/bio/bio_mem.c @@ -0,0 +1,330 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 +#include + +#include "../internal.h" + + +BIO *BIO_new_mem_buf(const void *buf, int len) { + BIO *ret; + BUF_MEM *b; + const size_t size = len < 0 ? strlen((char *)buf) : (size_t)len; + + if (!buf && len != 0) { + OPENSSL_PUT_ERROR(BIO, BIO_R_NULL_PARAMETER); + return NULL; + } + + ret = BIO_new(BIO_s_mem()); + if (ret == NULL) { + return NULL; + } + + b = (BUF_MEM *)ret->ptr; + // BIO_FLAGS_MEM_RDONLY ensures |b->data| is not written to. + b->data = (void *)buf; + b->length = size; + b->max = size; + + ret->flags |= BIO_FLAGS_MEM_RDONLY; + + // |num| is used to store the value that this BIO will return when it runs + // out of data. If it's negative then the retry flags will also be set. Since + // this is static data, retrying wont help + ret->num = 0; + + return ret; +} + +static int mem_new(BIO *bio) { + BUF_MEM *b; + + b = BUF_MEM_new(); + if (b == NULL) { + return 0; + } + + // |shutdown| is used to store the close flag: whether the BIO has ownership + // of the BUF_MEM. + bio->shutdown = 1; + bio->init = 1; + bio->num = -1; + bio->ptr = (char *)b; + + return 1; +} + +static int mem_free(BIO *bio) { + BUF_MEM *b; + + if (bio == NULL) { + return 0; + } + + if (!bio->shutdown || !bio->init || bio->ptr == NULL) { + return 1; + } + + b = (BUF_MEM *)bio->ptr; + if (bio->flags & BIO_FLAGS_MEM_RDONLY) { + b->data = NULL; + } + BUF_MEM_free(b); + bio->ptr = NULL; + return 1; +} + +static int mem_read(BIO *bio, char *out, int outl) { + int ret; + BUF_MEM *b = (BUF_MEM*) bio->ptr; + + BIO_clear_retry_flags(bio); + ret = outl; + if (b->length < INT_MAX && ret > (int)b->length) { + ret = b->length; + } + + if (ret > 0) { + OPENSSL_memcpy(out, b->data, ret); + b->length -= ret; + if (bio->flags & BIO_FLAGS_MEM_RDONLY) { + b->data += ret; + } else { + OPENSSL_memmove(b->data, &b->data[ret], b->length); + } + } else if (b->length == 0) { + ret = bio->num; + if (ret != 0) { + BIO_set_retry_read(bio); + } + } + return ret; +} + +static int mem_write(BIO *bio, const char *in, int inl) { + int ret = -1; + int blen; + BUF_MEM *b; + + b = (BUF_MEM *)bio->ptr; + + if (bio->flags & BIO_FLAGS_MEM_RDONLY) { + OPENSSL_PUT_ERROR(BIO, BIO_R_WRITE_TO_READ_ONLY_BIO); + goto err; + } + + BIO_clear_retry_flags(bio); + blen = b->length; + if (INT_MAX - blen < inl) { + goto err; + } + if (BUF_MEM_grow_clean(b, blen + inl) != ((size_t) blen) + inl) { + goto err; + } + OPENSSL_memcpy(&b->data[blen], in, inl); + ret = inl; + +err: + return ret; +} + +static int mem_gets(BIO *bio, char *buf, int size) { + int i, j; + char *p; + BUF_MEM *b = (BUF_MEM *)bio->ptr; + + BIO_clear_retry_flags(bio); + j = b->length; + if (size - 1 < j) { + j = size - 1; + } + if (j <= 0) { + if (size > 0) { + *buf = 0; + } + return 0; + } + + p = b->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(bio, buf, i); + if (i > 0) { + buf[i] = '\0'; + } + return i; +} + +static long mem_ctrl(BIO *bio, int cmd, long num, void *ptr) { + long ret = 1; + char **pptr; + + BUF_MEM *b = (BUF_MEM *)bio->ptr; + + switch (cmd) { + case BIO_CTRL_RESET: + if (b->data != NULL) { + // For read only case reset to the start again + if (bio->flags & BIO_FLAGS_MEM_RDONLY) { + b->data -= b->max - b->length; + b->length = b->max; + } else { + OPENSSL_memset(b->data, 0, b->max); + b->length = 0; + } + } + break; + case BIO_CTRL_EOF: + ret = (long)(b->length == 0); + break; + case BIO_C_SET_BUF_MEM_EOF_RETURN: + bio->num = (int)num; + break; + case BIO_CTRL_INFO: + ret = (long)b->length; + if (ptr != NULL) { + pptr = (char **)ptr; + *pptr = (char *)&b->data[0]; + } + break; + case BIO_C_SET_BUF_MEM: + mem_free(bio); + bio->shutdown = (int)num; + bio->ptr = ptr; + break; + case BIO_C_GET_BUF_MEM_PTR: + if (ptr != NULL) { + pptr = (char **)ptr; + *pptr = (char *)b; + } + break; + case BIO_CTRL_GET_CLOSE: + ret = (long)bio->shutdown; + break; + case BIO_CTRL_SET_CLOSE: + bio->shutdown = (int)num; + break; + + case BIO_CTRL_WPENDING: + ret = 0L; + break; + case BIO_CTRL_PENDING: + ret = (long)b->length; + break; + case BIO_CTRL_FLUSH: + ret = 1; + break; + default: + ret = 0; + break; + } + return ret; +} + +static const BIO_METHOD mem_method = { + BIO_TYPE_MEM, "memory buffer", + mem_write, mem_read, + NULL /* puts */, mem_gets, + mem_ctrl, mem_new, + mem_free, NULL /* callback_ctrl */, +}; + +const BIO_METHOD *BIO_s_mem(void) { return &mem_method; } + +int BIO_mem_contents(const BIO *bio, const uint8_t **out_contents, + size_t *out_len) { + const BUF_MEM *b; + if (bio->method != &mem_method) { + return 0; + } + + b = (BUF_MEM *)bio->ptr; + *out_contents = (uint8_t *)b->data; + *out_len = b->length; + return 1; +} + +long BIO_get_mem_data(BIO *bio, char **contents) { + return BIO_ctrl(bio, BIO_CTRL_INFO, 0, (char *) contents); +} + +int BIO_get_mem_ptr(BIO *bio, BUF_MEM **out) { + return BIO_ctrl(bio, BIO_C_GET_BUF_MEM_PTR, 0, (char *) out); +} + +int BIO_set_mem_buf(BIO *bio, BUF_MEM *b, int take_ownership) { + return BIO_ctrl(bio, BIO_C_SET_BUF_MEM, take_ownership, (char *) b); +} + +int BIO_set_mem_eof_return(BIO *bio, int eof_value) { + return BIO_ctrl(bio, BIO_C_SET_BUF_MEM_EOF_RETURN, eof_value, NULL); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/bio/bio_mem.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/bio/bio_mem.c.grpc_back new file mode 100644 index 0000000..08dd6e9 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/bio/bio_mem.c.grpc_back @@ -0,0 +1,330 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 +#include + +#include "../internal.h" + + +BIO *BIO_new_mem_buf(const void *buf, int len) { + BIO *ret; + BUF_MEM *b; + const size_t size = len < 0 ? strlen((char *)buf) : (size_t)len; + + if (!buf && len != 0) { + OPENSSL_PUT_ERROR(BIO, BIO_R_NULL_PARAMETER); + return NULL; + } + + ret = BIO_new(BIO_s_mem()); + if (ret == NULL) { + return NULL; + } + + b = (BUF_MEM *)ret->ptr; + // BIO_FLAGS_MEM_RDONLY ensures |b->data| is not written to. + b->data = (void *)buf; + b->length = size; + b->max = size; + + ret->flags |= BIO_FLAGS_MEM_RDONLY; + + // |num| is used to store the value that this BIO will return when it runs + // out of data. If it's negative then the retry flags will also be set. Since + // this is static data, retrying wont help + ret->num = 0; + + return ret; +} + +static int mem_new(BIO *bio) { + BUF_MEM *b; + + b = BUF_MEM_new(); + if (b == NULL) { + return 0; + } + + // |shutdown| is used to store the close flag: whether the BIO has ownership + // of the BUF_MEM. + bio->shutdown = 1; + bio->init = 1; + bio->num = -1; + bio->ptr = (char *)b; + + return 1; +} + +static int mem_free(BIO *bio) { + BUF_MEM *b; + + if (bio == NULL) { + return 0; + } + + if (!bio->shutdown || !bio->init || bio->ptr == NULL) { + return 1; + } + + b = (BUF_MEM *)bio->ptr; + if (bio->flags & BIO_FLAGS_MEM_RDONLY) { + b->data = NULL; + } + BUF_MEM_free(b); + bio->ptr = NULL; + return 1; +} + +static int mem_read(BIO *bio, char *out, int outl) { + int ret; + BUF_MEM *b = (BUF_MEM*) bio->ptr; + + BIO_clear_retry_flags(bio); + ret = outl; + if (b->length < INT_MAX && ret > (int)b->length) { + ret = b->length; + } + + if (ret > 0) { + OPENSSL_memcpy(out, b->data, ret); + b->length -= ret; + if (bio->flags & BIO_FLAGS_MEM_RDONLY) { + b->data += ret; + } else { + OPENSSL_memmove(b->data, &b->data[ret], b->length); + } + } else if (b->length == 0) { + ret = bio->num; + if (ret != 0) { + BIO_set_retry_read(bio); + } + } + return ret; +} + +static int mem_write(BIO *bio, const char *in, int inl) { + int ret = -1; + int blen; + BUF_MEM *b; + + b = (BUF_MEM *)bio->ptr; + + if (bio->flags & BIO_FLAGS_MEM_RDONLY) { + OPENSSL_PUT_ERROR(BIO, BIO_R_WRITE_TO_READ_ONLY_BIO); + goto err; + } + + BIO_clear_retry_flags(bio); + blen = b->length; + if (INT_MAX - blen < inl) { + goto err; + } + if (BUF_MEM_grow_clean(b, blen + inl) != ((size_t) blen) + inl) { + goto err; + } + OPENSSL_memcpy(&b->data[blen], in, inl); + ret = inl; + +err: + return ret; +} + +static int mem_gets(BIO *bio, char *buf, int size) { + int i, j; + char *p; + BUF_MEM *b = (BUF_MEM *)bio->ptr; + + BIO_clear_retry_flags(bio); + j = b->length; + if (size - 1 < j) { + j = size - 1; + } + if (j <= 0) { + if (size > 0) { + *buf = 0; + } + return 0; + } + + p = b->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(bio, buf, i); + if (i > 0) { + buf[i] = '\0'; + } + return i; +} + +static long mem_ctrl(BIO *bio, int cmd, long num, void *ptr) { + long ret = 1; + char **pptr; + + BUF_MEM *b = (BUF_MEM *)bio->ptr; + + switch (cmd) { + case BIO_CTRL_RESET: + if (b->data != NULL) { + // For read only case reset to the start again + if (bio->flags & BIO_FLAGS_MEM_RDONLY) { + b->data -= b->max - b->length; + b->length = b->max; + } else { + OPENSSL_memset(b->data, 0, b->max); + b->length = 0; + } + } + break; + case BIO_CTRL_EOF: + ret = (long)(b->length == 0); + break; + case BIO_C_SET_BUF_MEM_EOF_RETURN: + bio->num = (int)num; + break; + case BIO_CTRL_INFO: + ret = (long)b->length; + if (ptr != NULL) { + pptr = (char **)ptr; + *pptr = (char *)&b->data[0]; + } + break; + case BIO_C_SET_BUF_MEM: + mem_free(bio); + bio->shutdown = (int)num; + bio->ptr = ptr; + break; + case BIO_C_GET_BUF_MEM_PTR: + if (ptr != NULL) { + pptr = (char **)ptr; + *pptr = (char *)b; + } + break; + case BIO_CTRL_GET_CLOSE: + ret = (long)bio->shutdown; + break; + case BIO_CTRL_SET_CLOSE: + bio->shutdown = (int)num; + break; + + case BIO_CTRL_WPENDING: + ret = 0L; + break; + case BIO_CTRL_PENDING: + ret = (long)b->length; + break; + case BIO_CTRL_FLUSH: + ret = 1; + break; + default: + ret = 0; + break; + } + return ret; +} + +static const BIO_METHOD mem_method = { + BIO_TYPE_MEM, "memory buffer", + mem_write, mem_read, + NULL /* puts */, mem_gets, + mem_ctrl, mem_new, + mem_free, NULL /* callback_ctrl */, +}; + +const BIO_METHOD *BIO_s_mem(void) { return &mem_method; } + +int BIO_mem_contents(const BIO *bio, const uint8_t **out_contents, + size_t *out_len) { + const BUF_MEM *b; + if (bio->method != &mem_method) { + return 0; + } + + b = (BUF_MEM *)bio->ptr; + *out_contents = (uint8_t *)b->data; + *out_len = b->length; + return 1; +} + +long BIO_get_mem_data(BIO *bio, char **contents) { + return BIO_ctrl(bio, BIO_CTRL_INFO, 0, (char *) contents); +} + +int BIO_get_mem_ptr(BIO *bio, BUF_MEM **out) { + return BIO_ctrl(bio, BIO_C_GET_BUF_MEM_PTR, 0, (char *) out); +} + +int BIO_set_mem_buf(BIO *bio, BUF_MEM *b, int take_ownership) { + return BIO_ctrl(bio, BIO_C_SET_BUF_MEM, take_ownership, (char *) b); +} + +int BIO_set_mem_eof_return(BIO *bio, int eof_value) { + return BIO_ctrl(bio, BIO_C_SET_BUF_MEM_EOF_RETURN, eof_value, NULL); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/bio/connect.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/bio/connect.c new file mode 100644 index 0000000..5bc3600 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/bio/connect.c @@ -0,0 +1,542 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 + +#if !defined(OPENSSL_WINDOWS) +#include +#include +#include +#include +#else +OPENSSL_MSVC_PRAGMA(warning(push, 3)) +#include +#include +OPENSSL_MSVC_PRAGMA(warning(pop)) +#endif + +#include +#include +#include + +#include "internal.h" +#include "../internal.h" + + +enum { + BIO_CONN_S_BEFORE, + BIO_CONN_S_BLOCKED_CONNECT, + BIO_CONN_S_OK, +}; + +typedef struct bio_connect_st { + int state; + + char *param_hostname; + char *param_port; + int nbio; + + unsigned short port; + + struct sockaddr_storage them; + socklen_t them_length; + + // the file descriptor is kept in bio->num in order to match the socket + // BIO. + + // info_callback is 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; + +#if !defined(OPENSSL_WINDOWS) +static int closesocket(int sock) { + return close(sock); +} +#endif + +// split_host_and_port sets |*out_host| and |*out_port| to the host and port +// parsed from |name|. It returns one on success or zero on error. Even when +// successful, |*out_port| may be NULL on return if no port was specified. +static int split_host_and_port(char **out_host, char **out_port, const char *name) { + const char *host, *port = NULL; + size_t host_len = 0; + + *out_host = NULL; + *out_port = NULL; + + if (name[0] == '[') { // bracketed IPv6 address + const char *close = strchr(name, ']'); + if (close == NULL) { + return 0; + } + host = name + 1; + host_len = close - host; + if (close[1] == ':') { // [IP]:port + port = close + 2; + } else if (close[1] != 0) { + return 0; + } + } else { + const char *colon = strchr(name, ':'); + if (colon == NULL || strchr(colon + 1, ':') != NULL) { // IPv6 address + host = name; + host_len = strlen(name); + } else { // host:port + host = name; + host_len = colon - name; + port = colon + 1; + } + } + + *out_host = BUF_strndup(host, host_len); + if (*out_host == NULL) { + return 0; + } + if (port == NULL) { + *out_port = NULL; + return 1; + } + *out_port = OPENSSL_strdup(port); + if (*out_port == NULL) { + OPENSSL_free(*out_host); + *out_host = NULL; + return 0; + } + return 1; +} + +static int conn_state(BIO *bio, BIO_CONNECT *c) { + int ret = -1, i; + 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: + // If there's a hostname and a port, assume that both are + // exactly what they say. If there is only a hostname, try + // (just once) to split it into a hostname and port. + + if (c->param_hostname == NULL) { + OPENSSL_PUT_ERROR(BIO, BIO_R_NO_HOSTNAME_SPECIFIED); + goto exit_loop; + } + + if (c->param_port == NULL) { + char *host, *port; + if (!split_host_and_port(&host, &port, c->param_hostname) || + port == NULL) { + OPENSSL_free(host); + OPENSSL_free(port); + OPENSSL_PUT_ERROR(BIO, BIO_R_NO_PORT_SPECIFIED); + ERR_add_error_data(2, "host=", c->param_hostname); + goto exit_loop; + } + + OPENSSL_free(c->param_port); + c->param_port = port; + OPENSSL_free(c->param_hostname); + c->param_hostname = host; + } + + if (!bio_ip_and_port_to_socket_and_addr( + &bio->num, &c->them, &c->them_length, c->param_hostname, + c->param_port)) { + OPENSSL_PUT_ERROR(BIO, BIO_R_UNABLE_TO_CREATE_SOCKET); + ERR_add_error_data(4, "host=", c->param_hostname, ":", c->param_port); + goto exit_loop; + } + + if (c->nbio) { + if (!bio_socket_nbio(bio->num, 1)) { + OPENSSL_PUT_ERROR(BIO, BIO_R_ERROR_SETTING_NBIO); + ERR_add_error_data(4, "host=", c->param_hostname, ":", + c->param_port); + goto exit_loop; + } + } + + i = 1; + ret = setsockopt(bio->num, SOL_SOCKET, SO_KEEPALIVE, (char *)&i, + sizeof(i)); + if (ret < 0) { + OPENSSL_PUT_SYSTEM_ERROR(); + OPENSSL_PUT_ERROR(BIO, BIO_R_KEEPALIVE); + ERR_add_error_data(4, "host=", c->param_hostname, ":", c->param_port); + goto exit_loop; + } + + BIO_clear_retry_flags(bio); + ret = connect(bio->num, (struct sockaddr*) &c->them, c->them_length); + if (ret < 0) { + if (bio_fd_should_retry(ret)) { + BIO_set_flags(bio, (BIO_FLAGS_IO_SPECIAL | BIO_FLAGS_SHOULD_RETRY)); + c->state = BIO_CONN_S_BLOCKED_CONNECT; + bio->retry_reason = BIO_RR_CONNECT; + } else { + OPENSSL_PUT_SYSTEM_ERROR(); + OPENSSL_PUT_ERROR(BIO, BIO_R_CONNECT_ERROR); + ERR_add_error_data(4, "host=", c->param_hostname, ":", + c->param_port); + } + goto exit_loop; + } else { + c->state = BIO_CONN_S_OK; + } + break; + + case BIO_CONN_S_BLOCKED_CONNECT: + i = bio_sock_error(bio->num); + if (i) { + if (bio_fd_should_retry(ret)) { + BIO_set_flags(bio, (BIO_FLAGS_IO_SPECIAL | BIO_FLAGS_SHOULD_RETRY)); + c->state = BIO_CONN_S_BLOCKED_CONNECT; + bio->retry_reason = BIO_RR_CONNECT; + ret = -1; + } else { + BIO_clear_retry_flags(bio); + OPENSSL_PUT_SYSTEM_ERROR(); + OPENSSL_PUT_ERROR(BIO, BIO_R_NBIO_CONNECT_ERROR); + ERR_add_error_data(4, "host=", c->param_hostname, ":", c->param_port); + ret = 0; + } + goto exit_loop; + } else { + c->state = BIO_CONN_S_OK; + } + break; + + case BIO_CONN_S_OK: + ret = 1; + goto exit_loop; + default: + assert(0); + goto exit_loop; + } + + if (cb != NULL) { + ret = cb((BIO *)bio, c->state, ret); + if (ret == 0) { + goto end; + } + } + } + +exit_loop: + if (cb != NULL) { + ret = cb((BIO *)bio, c->state, ret); + } + +end: + return ret; +} + +static BIO_CONNECT *BIO_CONNECT_new(void) { + BIO_CONNECT *ret = OPENSSL_malloc(sizeof(BIO_CONNECT)); + + if (ret == NULL) { + return NULL; + } + OPENSSL_memset(ret, 0, sizeof(BIO_CONNECT)); + + ret->state = BIO_CONN_S_BEFORE; + return ret; +} + +static void BIO_CONNECT_free(BIO_CONNECT *c) { + if (c == NULL) { + return; + } + + OPENSSL_free(c->param_hostname); + OPENSSL_free(c->param_port); + OPENSSL_free(c); +} + +static int conn_new(BIO *bio) { + bio->init = 0; + bio->num = -1; + bio->flags = 0; + bio->ptr = (char *)BIO_CONNECT_new(); + return bio->ptr != NULL; +} + +static void conn_close_socket(BIO *bio) { + BIO_CONNECT *c = (BIO_CONNECT *) bio->ptr; + + if (bio->num == -1) { + return; + } + + // Only do a shutdown if things were established + if (c->state == BIO_CONN_S_OK) { + shutdown(bio->num, 2); + } + closesocket(bio->num); + bio->num = -1; +} + +static int conn_free(BIO *bio) { + if (bio == NULL) { + return 0; + } + + if (bio->shutdown) { + conn_close_socket(bio); + } + + BIO_CONNECT_free((BIO_CONNECT*) bio->ptr); + + return 1; +} + +static int conn_read(BIO *bio, char *out, int out_len) { + int ret = 0; + BIO_CONNECT *data; + + data = (BIO_CONNECT *)bio->ptr; + if (data->state != BIO_CONN_S_OK) { + ret = conn_state(bio, data); + if (ret <= 0) { + return ret; + } + } + + bio_clear_socket_error(); + ret = recv(bio->num, out, out_len, 0); + BIO_clear_retry_flags(bio); + if (ret <= 0) { + if (bio_fd_should_retry(ret)) { + BIO_set_retry_read(bio); + } + } + + return ret; +} + +static int conn_write(BIO *bio, const char *in, int in_len) { + int ret; + BIO_CONNECT *data; + + data = (BIO_CONNECT *)bio->ptr; + if (data->state != BIO_CONN_S_OK) { + ret = conn_state(bio, data); + if (ret <= 0) { + return ret; + } + } + + bio_clear_socket_error(); + ret = send(bio->num, in, in_len, 0); + BIO_clear_retry_flags(bio); + if (ret <= 0) { + if (bio_fd_should_retry(ret)) { + BIO_set_retry_write(bio); + } + } + + return ret; +} + +static long conn_ctrl(BIO *bio, int cmd, long num, void *ptr) { + int *ip; + long ret = 1; + BIO_CONNECT *data; + + data = (BIO_CONNECT *)bio->ptr; + + switch (cmd) { + case BIO_CTRL_RESET: + ret = 0; + data->state = BIO_CONN_S_BEFORE; + conn_close_socket(bio); + bio->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(bio, data); + } else { + ret = 1; + } + break; + case BIO_C_SET_CONNECT: + if (ptr != NULL) { + bio->init = 1; + if (num == 0) { + OPENSSL_free(data->param_hostname); + data->param_hostname = BUF_strdup(ptr); + if (data->param_hostname == NULL) { + ret = 0; + } + } else if (num == 1) { + OPENSSL_free(data->param_port); + data->param_port = BUF_strdup(ptr); + if (data->param_port == NULL) { + ret = 0; + } + } else { + ret = 0; + } + } + break; + case BIO_C_SET_NBIO: + data->nbio = (int)num; + break; + case BIO_C_GET_FD: + if (bio->init) { + ip = (int *)ptr; + if (ip != NULL) { + *ip = bio->num; + } + ret = bio->num; + } else { + ret = -1; + } + break; + case BIO_CTRL_GET_CLOSE: + ret = bio->shutdown; + break; + case BIO_CTRL_SET_CLOSE: + bio->shutdown = (int)num; + break; + case BIO_CTRL_PENDING: + case BIO_CTRL_WPENDING: + ret = 0; + break; + case BIO_CTRL_FLUSH: + 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 *bio, int cmd, bio_info_cb fp) { + long ret = 1; + BIO_CONNECT *data; + + data = (BIO_CONNECT *)bio->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; +} + +BIO *BIO_new_connect(const char *hostname) { + BIO *ret; + + ret = BIO_new(BIO_s_connect()); + if (ret == NULL) { + return NULL; + } + if (!BIO_set_conn_hostname(ret, hostname)) { + BIO_free(ret); + return NULL; + } + return ret; +} + +static const BIO_METHOD methods_connectp = { + BIO_TYPE_CONNECT, "socket connect", conn_write, conn_read, + NULL /* puts */, NULL /* gets */, conn_ctrl, conn_new, + conn_free, conn_callback_ctrl, +}; + +const BIO_METHOD *BIO_s_connect(void) { return &methods_connectp; } + +int BIO_set_conn_hostname(BIO *bio, const char *name) { + return BIO_ctrl(bio, BIO_C_SET_CONNECT, 0, (void*) name); +} + +int BIO_set_conn_port(BIO *bio, const char *port_str) { + return BIO_ctrl(bio, BIO_C_SET_CONNECT, 1, (void*) port_str); +} + +int BIO_set_conn_int_port(BIO *bio, const int *port) { + char buf[DECIMAL_SIZE(int) + 1]; + BIO_snprintf(buf, sizeof(buf), "%d", *port); + return BIO_set_conn_port(bio, buf); +} + +int BIO_set_nbio(BIO *bio, int on) { + return BIO_ctrl(bio, BIO_C_SET_NBIO, on, NULL); +} + +int BIO_do_connect(BIO *bio) { + return BIO_ctrl(bio, BIO_C_DO_STATE_MACHINE, 0, NULL); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/bio/connect.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/bio/connect.c.grpc_back new file mode 100644 index 0000000..0b60f6a --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/bio/connect.c.grpc_back @@ -0,0 +1,542 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 + +#if !defined(OPENSSL_WINDOWS) +#include +#include +#include +#include +#else +OPENSSL_MSVC_PRAGMA(warning(push, 3)) +#include +#include +OPENSSL_MSVC_PRAGMA(warning(pop)) +#endif + +#include +#include +#include + +#include "internal.h" +#include "../internal.h" + + +enum { + BIO_CONN_S_BEFORE, + BIO_CONN_S_BLOCKED_CONNECT, + BIO_CONN_S_OK, +}; + +typedef struct bio_connect_st { + int state; + + char *param_hostname; + char *param_port; + int nbio; + + unsigned short port; + + struct sockaddr_storage them; + socklen_t them_length; + + // the file descriptor is kept in bio->num in order to match the socket + // BIO. + + // info_callback is 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; + +#if !defined(OPENSSL_WINDOWS) +static int closesocket(int sock) { + return close(sock); +} +#endif + +// split_host_and_port sets |*out_host| and |*out_port| to the host and port +// parsed from |name|. It returns one on success or zero on error. Even when +// successful, |*out_port| may be NULL on return if no port was specified. +static int split_host_and_port(char **out_host, char **out_port, const char *name) { + const char *host, *port = NULL; + size_t host_len = 0; + + *out_host = NULL; + *out_port = NULL; + + if (name[0] == '[') { // bracketed IPv6 address + const char *close = strchr(name, ']'); + if (close == NULL) { + return 0; + } + host = name + 1; + host_len = close - host; + if (close[1] == ':') { // [IP]:port + port = close + 2; + } else if (close[1] != 0) { + return 0; + } + } else { + const char *colon = strchr(name, ':'); + if (colon == NULL || strchr(colon + 1, ':') != NULL) { // IPv6 address + host = name; + host_len = strlen(name); + } else { // host:port + host = name; + host_len = colon - name; + port = colon + 1; + } + } + + *out_host = BUF_strndup(host, host_len); + if (*out_host == NULL) { + return 0; + } + if (port == NULL) { + *out_port = NULL; + return 1; + } + *out_port = OPENSSL_strdup(port); + if (*out_port == NULL) { + OPENSSL_free(*out_host); + *out_host = NULL; + return 0; + } + return 1; +} + +static int conn_state(BIO *bio, BIO_CONNECT *c) { + int ret = -1, i; + 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: + // If there's a hostname and a port, assume that both are + // exactly what they say. If there is only a hostname, try + // (just once) to split it into a hostname and port. + + if (c->param_hostname == NULL) { + OPENSSL_PUT_ERROR(BIO, BIO_R_NO_HOSTNAME_SPECIFIED); + goto exit_loop; + } + + if (c->param_port == NULL) { + char *host, *port; + if (!split_host_and_port(&host, &port, c->param_hostname) || + port == NULL) { + OPENSSL_free(host); + OPENSSL_free(port); + OPENSSL_PUT_ERROR(BIO, BIO_R_NO_PORT_SPECIFIED); + ERR_add_error_data(2, "host=", c->param_hostname); + goto exit_loop; + } + + OPENSSL_free(c->param_port); + c->param_port = port; + OPENSSL_free(c->param_hostname); + c->param_hostname = host; + } + + if (!bio_ip_and_port_to_socket_and_addr( + &bio->num, &c->them, &c->them_length, c->param_hostname, + c->param_port)) { + OPENSSL_PUT_ERROR(BIO, BIO_R_UNABLE_TO_CREATE_SOCKET); + ERR_add_error_data(4, "host=", c->param_hostname, ":", c->param_port); + goto exit_loop; + } + + if (c->nbio) { + if (!bio_socket_nbio(bio->num, 1)) { + OPENSSL_PUT_ERROR(BIO, BIO_R_ERROR_SETTING_NBIO); + ERR_add_error_data(4, "host=", c->param_hostname, ":", + c->param_port); + goto exit_loop; + } + } + + i = 1; + ret = setsockopt(bio->num, SOL_SOCKET, SO_KEEPALIVE, (char *)&i, + sizeof(i)); + if (ret < 0) { + OPENSSL_PUT_SYSTEM_ERROR(); + OPENSSL_PUT_ERROR(BIO, BIO_R_KEEPALIVE); + ERR_add_error_data(4, "host=", c->param_hostname, ":", c->param_port); + goto exit_loop; + } + + BIO_clear_retry_flags(bio); + ret = connect(bio->num, (struct sockaddr*) &c->them, c->them_length); + if (ret < 0) { + if (bio_fd_should_retry(ret)) { + BIO_set_flags(bio, (BIO_FLAGS_IO_SPECIAL | BIO_FLAGS_SHOULD_RETRY)); + c->state = BIO_CONN_S_BLOCKED_CONNECT; + bio->retry_reason = BIO_RR_CONNECT; + } else { + OPENSSL_PUT_SYSTEM_ERROR(); + OPENSSL_PUT_ERROR(BIO, BIO_R_CONNECT_ERROR); + ERR_add_error_data(4, "host=", c->param_hostname, ":", + c->param_port); + } + goto exit_loop; + } else { + c->state = BIO_CONN_S_OK; + } + break; + + case BIO_CONN_S_BLOCKED_CONNECT: + i = bio_sock_error(bio->num); + if (i) { + if (bio_fd_should_retry(ret)) { + BIO_set_flags(bio, (BIO_FLAGS_IO_SPECIAL | BIO_FLAGS_SHOULD_RETRY)); + c->state = BIO_CONN_S_BLOCKED_CONNECT; + bio->retry_reason = BIO_RR_CONNECT; + ret = -1; + } else { + BIO_clear_retry_flags(bio); + OPENSSL_PUT_SYSTEM_ERROR(); + OPENSSL_PUT_ERROR(BIO, BIO_R_NBIO_CONNECT_ERROR); + ERR_add_error_data(4, "host=", c->param_hostname, ":", c->param_port); + ret = 0; + } + goto exit_loop; + } else { + c->state = BIO_CONN_S_OK; + } + break; + + case BIO_CONN_S_OK: + ret = 1; + goto exit_loop; + default: + assert(0); + goto exit_loop; + } + + if (cb != NULL) { + ret = cb((BIO *)bio, c->state, ret); + if (ret == 0) { + goto end; + } + } + } + +exit_loop: + if (cb != NULL) { + ret = cb((BIO *)bio, c->state, ret); + } + +end: + return ret; +} + +static BIO_CONNECT *BIO_CONNECT_new(void) { + BIO_CONNECT *ret = OPENSSL_malloc(sizeof(BIO_CONNECT)); + + if (ret == NULL) { + return NULL; + } + OPENSSL_memset(ret, 0, sizeof(BIO_CONNECT)); + + ret->state = BIO_CONN_S_BEFORE; + return ret; +} + +static void BIO_CONNECT_free(BIO_CONNECT *c) { + if (c == NULL) { + return; + } + + OPENSSL_free(c->param_hostname); + OPENSSL_free(c->param_port); + OPENSSL_free(c); +} + +static int conn_new(BIO *bio) { + bio->init = 0; + bio->num = -1; + bio->flags = 0; + bio->ptr = (char *)BIO_CONNECT_new(); + return bio->ptr != NULL; +} + +static void conn_close_socket(BIO *bio) { + BIO_CONNECT *c = (BIO_CONNECT *) bio->ptr; + + if (bio->num == -1) { + return; + } + + // Only do a shutdown if things were established + if (c->state == BIO_CONN_S_OK) { + shutdown(bio->num, 2); + } + closesocket(bio->num); + bio->num = -1; +} + +static int conn_free(BIO *bio) { + if (bio == NULL) { + return 0; + } + + if (bio->shutdown) { + conn_close_socket(bio); + } + + BIO_CONNECT_free((BIO_CONNECT*) bio->ptr); + + return 1; +} + +static int conn_read(BIO *bio, char *out, int out_len) { + int ret = 0; + BIO_CONNECT *data; + + data = (BIO_CONNECT *)bio->ptr; + if (data->state != BIO_CONN_S_OK) { + ret = conn_state(bio, data); + if (ret <= 0) { + return ret; + } + } + + bio_clear_socket_error(); + ret = recv(bio->num, out, out_len, 0); + BIO_clear_retry_flags(bio); + if (ret <= 0) { + if (bio_fd_should_retry(ret)) { + BIO_set_retry_read(bio); + } + } + + return ret; +} + +static int conn_write(BIO *bio, const char *in, int in_len) { + int ret; + BIO_CONNECT *data; + + data = (BIO_CONNECT *)bio->ptr; + if (data->state != BIO_CONN_S_OK) { + ret = conn_state(bio, data); + if (ret <= 0) { + return ret; + } + } + + bio_clear_socket_error(); + ret = send(bio->num, in, in_len, 0); + BIO_clear_retry_flags(bio); + if (ret <= 0) { + if (bio_fd_should_retry(ret)) { + BIO_set_retry_write(bio); + } + } + + return ret; +} + +static long conn_ctrl(BIO *bio, int cmd, long num, void *ptr) { + int *ip; + long ret = 1; + BIO_CONNECT *data; + + data = (BIO_CONNECT *)bio->ptr; + + switch (cmd) { + case BIO_CTRL_RESET: + ret = 0; + data->state = BIO_CONN_S_BEFORE; + conn_close_socket(bio); + bio->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(bio, data); + } else { + ret = 1; + } + break; + case BIO_C_SET_CONNECT: + if (ptr != NULL) { + bio->init = 1; + if (num == 0) { + OPENSSL_free(data->param_hostname); + data->param_hostname = BUF_strdup(ptr); + if (data->param_hostname == NULL) { + ret = 0; + } + } else if (num == 1) { + OPENSSL_free(data->param_port); + data->param_port = BUF_strdup(ptr); + if (data->param_port == NULL) { + ret = 0; + } + } else { + ret = 0; + } + } + break; + case BIO_C_SET_NBIO: + data->nbio = (int)num; + break; + case BIO_C_GET_FD: + if (bio->init) { + ip = (int *)ptr; + if (ip != NULL) { + *ip = bio->num; + } + ret = bio->num; + } else { + ret = -1; + } + break; + case BIO_CTRL_GET_CLOSE: + ret = bio->shutdown; + break; + case BIO_CTRL_SET_CLOSE: + bio->shutdown = (int)num; + break; + case BIO_CTRL_PENDING: + case BIO_CTRL_WPENDING: + ret = 0; + break; + case BIO_CTRL_FLUSH: + 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 *bio, int cmd, bio_info_cb fp) { + long ret = 1; + BIO_CONNECT *data; + + data = (BIO_CONNECT *)bio->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; +} + +BIO *BIO_new_connect(const char *hostname) { + BIO *ret; + + ret = BIO_new(BIO_s_connect()); + if (ret == NULL) { + return NULL; + } + if (!BIO_set_conn_hostname(ret, hostname)) { + BIO_free(ret); + return NULL; + } + return ret; +} + +static const BIO_METHOD methods_connectp = { + BIO_TYPE_CONNECT, "socket connect", conn_write, conn_read, + NULL /* puts */, NULL /* gets */, conn_ctrl, conn_new, + conn_free, conn_callback_ctrl, +}; + +const BIO_METHOD *BIO_s_connect(void) { return &methods_connectp; } + +int BIO_set_conn_hostname(BIO *bio, const char *name) { + return BIO_ctrl(bio, BIO_C_SET_CONNECT, 0, (void*) name); +} + +int BIO_set_conn_port(BIO *bio, const char *port_str) { + return BIO_ctrl(bio, BIO_C_SET_CONNECT, 1, (void*) port_str); +} + +int BIO_set_conn_int_port(BIO *bio, const int *port) { + char buf[DECIMAL_SIZE(int) + 1]; + BIO_snprintf(buf, sizeof(buf), "%d", *port); + return BIO_set_conn_port(bio, buf); +} + +int BIO_set_nbio(BIO *bio, int on) { + return BIO_ctrl(bio, BIO_C_SET_NBIO, on, NULL); +} + +int BIO_do_connect(BIO *bio) { + return BIO_ctrl(bio, BIO_C_DO_STATE_MACHINE, 0, NULL); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/bio/fd.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/bio/fd.c new file mode 100644 index 0000000..5dfccd8 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/bio/fd.c @@ -0,0 +1,276 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 !defined(OPENSSL_WINDOWS) +#include +#else +#include +OPENSSL_MSVC_PRAGMA(warning(push, 3)) +#include +OPENSSL_MSVC_PRAGMA(warning(pop)) +#endif + +#include +#include +#include + +#include "internal.h" +#include "../internal.h" + + +static int bio_fd_non_fatal_error(int err) { + if ( +#ifdef EWOULDBLOCK + err == EWOULDBLOCK || +#endif +#ifdef WSAEWOULDBLOCK + err == WSAEWOULDBLOCK || +#endif +#ifdef ENOTCONN + err == ENOTCONN || +#endif +#ifdef EINTR + err == EINTR || +#endif +#ifdef EAGAIN + err == EAGAIN || +#endif +#ifdef EPROTO + err == EPROTO || +#endif +#ifdef EINPROGRESS + err == EINPROGRESS || +#endif +#ifdef EALREADY + err == EALREADY || +#endif + 0) { + return 1; + } + return 0; +} + +#if defined(OPENSSL_WINDOWS) + #define BORINGSSL_ERRNO (int)GetLastError() + #define BORINGSSL_CLOSE _close + #define BORINGSSL_LSEEK _lseek + #define BORINGSSL_READ _read + #define BORINGSSL_WRITE _write +#else + #define BORINGSSL_ERRNO errno + #define BORINGSSL_CLOSE close + #define BORINGSSL_LSEEK lseek + #define BORINGSSL_READ read + #define BORINGSSL_WRITE write +#endif + +int bio_fd_should_retry(int i) { + if (i == -1) { + return bio_fd_non_fatal_error(BORINGSSL_ERRNO); + } + return 0; +} + +BIO *BIO_new_fd(int fd, int close_flag) { + BIO *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 *bio) { + // num is used to store the file descriptor. + bio->num = -1; + return 1; +} + +static int fd_free(BIO *bio) { + if (bio == NULL) { + return 0; + } + + if (bio->shutdown) { + if (bio->init) { + BORINGSSL_CLOSE(bio->num); + } + bio->init = 0; + } + return 1; +} + +static int fd_read(BIO *b, char *out, int outl) { + int ret = 0; + + ret = BORINGSSL_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 = BORINGSSL_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; + OPENSSL_FALLTHROUGH; + case BIO_C_FILE_SEEK: + ret = 0; + if (b->init) { + ret = (long)BORINGSSL_LSEEK(b->num, num, SEEK_SET); + } + break; + case BIO_C_FILE_TELL: + case BIO_CTRL_INFO: + ret = 0; + if (b->init) { + ret = (long)BORINGSSL_LSEEK(b->num, 0, SEEK_CUR); + } + 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; + } + return 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: + ret = 1; + break; + default: + ret = 0; + break; + } + + return ret; +} + +static int fd_gets(BIO *bp, char *buf, int size) { + char *ptr = buf; + char *end = buf + size - 1; + + if (size <= 0) { + return 0; + } + + while (ptr < end && fd_read(bp, ptr, 1) > 0 && ptr[0] != '\n') { + ptr++; + } + + ptr[0] = '\0'; + + return ptr - buf; +} + +static const BIO_METHOD methods_fdp = { + BIO_TYPE_FD, "file descriptor", fd_write, fd_read, NULL /* puts */, + fd_gets, fd_ctrl, fd_new, fd_free, NULL /* callback_ctrl */, +}; + +const BIO_METHOD *BIO_s_fd(void) { return &methods_fdp; } + +int BIO_set_fd(BIO *bio, int fd, int close_flag) { + return BIO_int_ctrl(bio, BIO_C_SET_FD, close_flag, fd); +} + +int BIO_get_fd(BIO *bio, int *out_fd) { + return BIO_ctrl(bio, BIO_C_GET_FD, 0, (char *) out_fd); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/bio/fd.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/bio/fd.c.grpc_back new file mode 100644 index 0000000..fed5228 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/bio/fd.c.grpc_back @@ -0,0 +1,276 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 !defined(OPENSSL_WINDOWS) +#include +#else +#include +OPENSSL_MSVC_PRAGMA(warning(push, 3)) +#include +OPENSSL_MSVC_PRAGMA(warning(pop)) +#endif + +#include +#include +#include + +#include "internal.h" +#include "../internal.h" + + +static int bio_fd_non_fatal_error(int err) { + if ( +#ifdef EWOULDBLOCK + err == EWOULDBLOCK || +#endif +#ifdef WSAEWOULDBLOCK + err == WSAEWOULDBLOCK || +#endif +#ifdef ENOTCONN + err == ENOTCONN || +#endif +#ifdef EINTR + err == EINTR || +#endif +#ifdef EAGAIN + err == EAGAIN || +#endif +#ifdef EPROTO + err == EPROTO || +#endif +#ifdef EINPROGRESS + err == EINPROGRESS || +#endif +#ifdef EALREADY + err == EALREADY || +#endif + 0) { + return 1; + } + return 0; +} + +#if defined(OPENSSL_WINDOWS) + #define BORINGSSL_ERRNO (int)GetLastError() + #define BORINGSSL_CLOSE _close + #define BORINGSSL_LSEEK _lseek + #define BORINGSSL_READ _read + #define BORINGSSL_WRITE _write +#else + #define BORINGSSL_ERRNO errno + #define BORINGSSL_CLOSE close + #define BORINGSSL_LSEEK lseek + #define BORINGSSL_READ read + #define BORINGSSL_WRITE write +#endif + +int bio_fd_should_retry(int i) { + if (i == -1) { + return bio_fd_non_fatal_error(BORINGSSL_ERRNO); + } + return 0; +} + +BIO *BIO_new_fd(int fd, int close_flag) { + BIO *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 *bio) { + // num is used to store the file descriptor. + bio->num = -1; + return 1; +} + +static int fd_free(BIO *bio) { + if (bio == NULL) { + return 0; + } + + if (bio->shutdown) { + if (bio->init) { + BORINGSSL_CLOSE(bio->num); + } + bio->init = 0; + } + return 1; +} + +static int fd_read(BIO *b, char *out, int outl) { + int ret = 0; + + ret = BORINGSSL_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 = BORINGSSL_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; + OPENSSL_FALLTHROUGH; + case BIO_C_FILE_SEEK: + ret = 0; + if (b->init) { + ret = (long)BORINGSSL_LSEEK(b->num, num, SEEK_SET); + } + break; + case BIO_C_FILE_TELL: + case BIO_CTRL_INFO: + ret = 0; + if (b->init) { + ret = (long)BORINGSSL_LSEEK(b->num, 0, SEEK_CUR); + } + 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; + } + return 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: + ret = 1; + break; + default: + ret = 0; + break; + } + + return ret; +} + +static int fd_gets(BIO *bp, char *buf, int size) { + char *ptr = buf; + char *end = buf + size - 1; + + if (size <= 0) { + return 0; + } + + while (ptr < end && fd_read(bp, ptr, 1) > 0 && ptr[0] != '\n') { + ptr++; + } + + ptr[0] = '\0'; + + return ptr - buf; +} + +static const BIO_METHOD methods_fdp = { + BIO_TYPE_FD, "file descriptor", fd_write, fd_read, NULL /* puts */, + fd_gets, fd_ctrl, fd_new, fd_free, NULL /* callback_ctrl */, +}; + +const BIO_METHOD *BIO_s_fd(void) { return &methods_fdp; } + +int BIO_set_fd(BIO *bio, int fd, int close_flag) { + return BIO_int_ctrl(bio, BIO_C_SET_FD, close_flag, fd); +} + +int BIO_get_fd(BIO *bio, int *out_fd) { + return BIO_ctrl(bio, BIO_C_GET_FD, 0, (char *) out_fd); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/bio/file.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/bio/file.c new file mode 100644 index 0000000..fbad20b --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/bio/file.c @@ -0,0 +1,315 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#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 +#include + +#include +#include +#include + +#include "../internal.h" + + +#define BIO_FP_READ 0x02 +#define BIO_FP_WRITE 0x04 +#define BIO_FP_APPEND 0x08 + +BIO *BIO_new_file(const char *filename, const char *mode) { + BIO *ret; + FILE *file; + + file = fopen(filename, mode); + if (file == NULL) { + OPENSSL_PUT_SYSTEM_ERROR(); + + ERR_add_error_data(5, "fopen('", filename, "','", mode, "')"); + if (errno == ENOENT) { + OPENSSL_PUT_ERROR(BIO, BIO_R_NO_SUCH_FILE); + } else { + OPENSSL_PUT_ERROR(BIO, BIO_R_SYS_LIB); + } + return NULL; + } + + ret = BIO_new(BIO_s_file()); + if (ret == NULL) { + fclose(file); + return NULL; + } + + BIO_set_fp(ret, file, BIO_CLOSE); + return ret; +} + +BIO *BIO_new_fp(FILE *stream, int close_flag) { + BIO *ret = BIO_new(BIO_s_file()); + + if (ret == NULL) { + return NULL; + } + + BIO_set_fp(ret, stream, close_flag); + return ret; +} + +static int file_new(BIO *bio) { return 1; } + +static int file_free(BIO *bio) { + if (bio == NULL) { + return 0; + } + + if (!bio->shutdown) { + return 1; + } + + if (bio->init && bio->ptr != NULL) { + fclose(bio->ptr); + bio->ptr = NULL; + } + bio->init = 0; + + return 1; +} + +static int file_read(BIO *b, char *out, int outl) { + if (!b->init) { + return 0; + } + + size_t ret = fread(out, 1, outl, (FILE *)b->ptr); + if (ret == 0 && ferror((FILE *)b->ptr)) { + OPENSSL_PUT_SYSTEM_ERROR(); + OPENSSL_PUT_ERROR(BIO, ERR_R_SYS_LIB); + return -1; + } + + // fread reads at most |outl| bytes, so |ret| fits in an int. + return (int)ret; +} + +static int file_write(BIO *b, const char *in, int inl) { + int ret = 0; + + if (!b->init) { + return 0; + } + + ret = fwrite(in, inl, 1, (FILE *)b->ptr); + if (ret > 0) { + ret = inl; + } + return ret; +} + +static long file_ctrl(BIO *b, int cmd, long num, void *ptr) { + long ret = 1; + FILE *fp = (FILE *)b->ptr; + FILE **fpp; + char p[4]; + + switch (cmd) { + case BIO_CTRL_RESET: + num = 0; + OPENSSL_FALLTHROUGH; + case BIO_C_FILE_SEEK: + ret = (long)fseek(fp, num, 0); + break; + case BIO_CTRL_EOF: + ret = (long)feof(fp); + break; + case BIO_C_FILE_TELL: + case BIO_CTRL_INFO: + 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; + 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 { + OPENSSL_PUT_ERROR(BIO, BIO_R_BAD_FOPEN_MODE); + ret = 0; + break; + } + fp = fopen(ptr, p); + if (fp == NULL) { + OPENSSL_PUT_SYSTEM_ERROR(); + ERR_add_error_data(5, "fopen('", ptr, "','", p, "')"); + OPENSSL_PUT_ERROR(BIO, ERR_R_SYS_LIB); + ret = 0; + break; + } + b->ptr = fp; + b->init = 1; + 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: + ret = 0 == fflush((FILE *)b->ptr); + break; + case BIO_CTRL_WPENDING: + case BIO_CTRL_PENDING: + default: + ret = 0; + break; + } + return ret; +} + +static int file_gets(BIO *bp, char *buf, int size) { + int ret = 0; + + if (size == 0) { + return 0; + } + + if (!fgets(buf, size, (FILE *)bp->ptr)) { + buf[0] = 0; + goto err; + } + ret = strlen(buf); + +err: + return ret; +} + +static const BIO_METHOD methods_filep = { + BIO_TYPE_FILE, "FILE pointer", + file_write, file_read, + NULL /* puts */, file_gets, + file_ctrl, file_new, + file_free, NULL /* callback_ctrl */, +}; + +const BIO_METHOD *BIO_s_file(void) { return &methods_filep; } + + +int BIO_get_fp(BIO *bio, FILE **out_file) { + return BIO_ctrl(bio, BIO_C_GET_FILE_PTR, 0, (char*) out_file); +} + +int BIO_set_fp(BIO *bio, FILE *file, int close_flag) { + return BIO_ctrl(bio, BIO_C_SET_FILE_PTR, close_flag, (char *) file); +} + +int BIO_read_filename(BIO *bio, const char *filename) { + return BIO_ctrl(bio, BIO_C_SET_FILENAME, BIO_CLOSE | BIO_FP_READ, + (char *)filename); +} + +int BIO_write_filename(BIO *bio, const char *filename) { + return BIO_ctrl(bio, BIO_C_SET_FILENAME, BIO_CLOSE | BIO_FP_WRITE, + (char *)filename); +} + +int BIO_append_filename(BIO *bio, const char *filename) { + return BIO_ctrl(bio, BIO_C_SET_FILENAME, BIO_CLOSE | BIO_FP_APPEND, + (char *)filename); +} + +int BIO_rw_filename(BIO *bio, const char *filename) { + return BIO_ctrl(bio, BIO_C_SET_FILENAME, + BIO_CLOSE | BIO_FP_READ | BIO_FP_WRITE, (char *)filename); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/bio/file.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/bio/file.c.grpc_back new file mode 100644 index 0000000..f61dbe4 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/bio/file.c.grpc_back @@ -0,0 +1,315 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#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 +#include + +#include +#include +#include + +#include "../internal.h" + + +#define BIO_FP_READ 0x02 +#define BIO_FP_WRITE 0x04 +#define BIO_FP_APPEND 0x08 + +BIO *BIO_new_file(const char *filename, const char *mode) { + BIO *ret; + FILE *file; + + file = fopen(filename, mode); + if (file == NULL) { + OPENSSL_PUT_SYSTEM_ERROR(); + + ERR_add_error_data(5, "fopen('", filename, "','", mode, "')"); + if (errno == ENOENT) { + OPENSSL_PUT_ERROR(BIO, BIO_R_NO_SUCH_FILE); + } else { + OPENSSL_PUT_ERROR(BIO, BIO_R_SYS_LIB); + } + return NULL; + } + + ret = BIO_new(BIO_s_file()); + if (ret == NULL) { + fclose(file); + return NULL; + } + + BIO_set_fp(ret, file, BIO_CLOSE); + return ret; +} + +BIO *BIO_new_fp(FILE *stream, int close_flag) { + BIO *ret = BIO_new(BIO_s_file()); + + if (ret == NULL) { + return NULL; + } + + BIO_set_fp(ret, stream, close_flag); + return ret; +} + +static int file_new(BIO *bio) { return 1; } + +static int file_free(BIO *bio) { + if (bio == NULL) { + return 0; + } + + if (!bio->shutdown) { + return 1; + } + + if (bio->init && bio->ptr != NULL) { + fclose(bio->ptr); + bio->ptr = NULL; + } + bio->init = 0; + + return 1; +} + +static int file_read(BIO *b, char *out, int outl) { + if (!b->init) { + return 0; + } + + size_t ret = fread(out, 1, outl, (FILE *)b->ptr); + if (ret == 0 && ferror((FILE *)b->ptr)) { + OPENSSL_PUT_SYSTEM_ERROR(); + OPENSSL_PUT_ERROR(BIO, ERR_R_SYS_LIB); + return -1; + } + + // fread reads at most |outl| bytes, so |ret| fits in an int. + return (int)ret; +} + +static int file_write(BIO *b, const char *in, int inl) { + int ret = 0; + + if (!b->init) { + return 0; + } + + ret = fwrite(in, inl, 1, (FILE *)b->ptr); + if (ret > 0) { + ret = inl; + } + return ret; +} + +static long file_ctrl(BIO *b, int cmd, long num, void *ptr) { + long ret = 1; + FILE *fp = (FILE *)b->ptr; + FILE **fpp; + char p[4]; + + switch (cmd) { + case BIO_CTRL_RESET: + num = 0; + OPENSSL_FALLTHROUGH; + case BIO_C_FILE_SEEK: + ret = (long)fseek(fp, num, 0); + break; + case BIO_CTRL_EOF: + ret = (long)feof(fp); + break; + case BIO_C_FILE_TELL: + case BIO_CTRL_INFO: + 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; + 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 { + OPENSSL_PUT_ERROR(BIO, BIO_R_BAD_FOPEN_MODE); + ret = 0; + break; + } + fp = fopen(ptr, p); + if (fp == NULL) { + OPENSSL_PUT_SYSTEM_ERROR(); + ERR_add_error_data(5, "fopen('", ptr, "','", p, "')"); + OPENSSL_PUT_ERROR(BIO, ERR_R_SYS_LIB); + ret = 0; + break; + } + b->ptr = fp; + b->init = 1; + 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: + ret = 0 == fflush((FILE *)b->ptr); + break; + case BIO_CTRL_WPENDING: + case BIO_CTRL_PENDING: + default: + ret = 0; + break; + } + return ret; +} + +static int file_gets(BIO *bp, char *buf, int size) { + int ret = 0; + + if (size == 0) { + return 0; + } + + if (!fgets(buf, size, (FILE *)bp->ptr)) { + buf[0] = 0; + goto err; + } + ret = strlen(buf); + +err: + return ret; +} + +static const BIO_METHOD methods_filep = { + BIO_TYPE_FILE, "FILE pointer", + file_write, file_read, + NULL /* puts */, file_gets, + file_ctrl, file_new, + file_free, NULL /* callback_ctrl */, +}; + +const BIO_METHOD *BIO_s_file(void) { return &methods_filep; } + + +int BIO_get_fp(BIO *bio, FILE **out_file) { + return BIO_ctrl(bio, BIO_C_GET_FILE_PTR, 0, (char*) out_file); +} + +int BIO_set_fp(BIO *bio, FILE *file, int close_flag) { + return BIO_ctrl(bio, BIO_C_SET_FILE_PTR, close_flag, (char *) file); +} + +int BIO_read_filename(BIO *bio, const char *filename) { + return BIO_ctrl(bio, BIO_C_SET_FILENAME, BIO_CLOSE | BIO_FP_READ, + (char *)filename); +} + +int BIO_write_filename(BIO *bio, const char *filename) { + return BIO_ctrl(bio, BIO_C_SET_FILENAME, BIO_CLOSE | BIO_FP_WRITE, + (char *)filename); +} + +int BIO_append_filename(BIO *bio, const char *filename) { + return BIO_ctrl(bio, BIO_C_SET_FILENAME, BIO_CLOSE | BIO_FP_APPEND, + (char *)filename); +} + +int BIO_rw_filename(BIO *bio, const char *filename) { + return BIO_ctrl(bio, BIO_C_SET_FILENAME, + BIO_CLOSE | BIO_FP_READ | BIO_FP_WRITE, (char *)filename); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/bio/hexdump.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/bio/hexdump.c new file mode 100644 index 0000000..e3c45f0 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/bio/hexdump.c @@ -0,0 +1,192 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 "../internal.h" + + +// hexdump_ctx contains the state of a hexdump. +struct hexdump_ctx { + BIO *bio; + char right_chars[18]; // the contents of the right-hand side, ASCII dump. + unsigned used; // number of bytes in the current line. + size_t n; // number of bytes total. + unsigned indent; +}; + +static void hexbyte(char *out, uint8_t b) { + static const char hextable[] = "0123456789abcdef"; + out[0] = hextable[b>>4]; + out[1] = hextable[b&0x0f]; +} + +static char to_char(uint8_t b) { + if (b < 32 || b > 126) { + return '.'; + } + return b; +} + +// hexdump_write adds |len| bytes of |data| to the current hex dump described by +// |ctx|. +static int hexdump_write(struct hexdump_ctx *ctx, const uint8_t *data, + size_t len) { + char buf[10]; + unsigned l; + + // Output lines look like: + // 00000010 2e 2f 30 31 32 33 34 35 36 37 38 ... 3c 3d // |./0123456789:;<=| + // ^ offset ^ extra space ^ ASCII of line + + for (size_t i = 0; i < len; i++) { + if (ctx->used == 0) { + // The beginning of a line. + BIO_indent(ctx->bio, ctx->indent, UINT_MAX); + + hexbyte(&buf[0], ctx->n >> 24); + hexbyte(&buf[2], ctx->n >> 16); + hexbyte(&buf[4], ctx->n >> 8); + hexbyte(&buf[6], ctx->n); + buf[8] = buf[9] = ' '; + if (BIO_write(ctx->bio, buf, 10) < 0) { + return 0; + } + } + + hexbyte(buf, data[i]); + buf[2] = ' '; + l = 3; + if (ctx->used == 7) { + // There's an additional space after the 8th byte. + buf[3] = ' '; + l = 4; + } else if (ctx->used == 15) { + // At the end of the line there's an extra space and the bar for the + // right column. + buf[3] = ' '; + buf[4] = '|'; + l = 5; + } + + if (BIO_write(ctx->bio, buf, l) < 0) { + return 0; + } + ctx->right_chars[ctx->used] = to_char(data[i]); + ctx->used++; + ctx->n++; + if (ctx->used == 16) { + ctx->right_chars[16] = '|'; + ctx->right_chars[17] = '\n'; + if (BIO_write(ctx->bio, ctx->right_chars, sizeof(ctx->right_chars)) < 0) { + return 0; + } + ctx->used = 0; + } + } + + return 1; +} + +// finish flushes any buffered data in |ctx|. +static int finish(struct hexdump_ctx *ctx) { + // See the comments in |hexdump| for the details of this format. + const unsigned n_bytes = ctx->used; + unsigned l; + char buf[5]; + + if (n_bytes == 0) { + return 1; + } + + OPENSSL_memset(buf, ' ', 4); + buf[4] = '|'; + + for (; ctx->used < 16; ctx->used++) { + l = 3; + if (ctx->used == 7) { + l = 4; + } else if (ctx->used == 15) { + l = 5; + } + if (BIO_write(ctx->bio, buf, l) < 0) { + return 0; + } + } + + ctx->right_chars[n_bytes] = '|'; + ctx->right_chars[n_bytes + 1] = '\n'; + if (BIO_write(ctx->bio, ctx->right_chars, n_bytes + 2) < 0) { + return 0; + } + return 1; +} + +int BIO_hexdump(BIO *bio, const uint8_t *data, size_t len, unsigned indent) { + struct hexdump_ctx ctx; + OPENSSL_memset(&ctx, 0, sizeof(ctx)); + ctx.bio = bio; + ctx.indent = indent; + + if (!hexdump_write(&ctx, data, len) || !finish(&ctx)) { + return 0; + } + + return 1; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/bio/hexdump.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/bio/hexdump.c.grpc_back new file mode 100644 index 0000000..6d928bc --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/bio/hexdump.c.grpc_back @@ -0,0 +1,192 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 "../internal.h" + + +// hexdump_ctx contains the state of a hexdump. +struct hexdump_ctx { + BIO *bio; + char right_chars[18]; // the contents of the right-hand side, ASCII dump. + unsigned used; // number of bytes in the current line. + size_t n; // number of bytes total. + unsigned indent; +}; + +static void hexbyte(char *out, uint8_t b) { + static const char hextable[] = "0123456789abcdef"; + out[0] = hextable[b>>4]; + out[1] = hextable[b&0x0f]; +} + +static char to_char(uint8_t b) { + if (b < 32 || b > 126) { + return '.'; + } + return b; +} + +// hexdump_write adds |len| bytes of |data| to the current hex dump described by +// |ctx|. +static int hexdump_write(struct hexdump_ctx *ctx, const uint8_t *data, + size_t len) { + char buf[10]; + unsigned l; + + // Output lines look like: + // 00000010 2e 2f 30 31 32 33 34 35 36 37 38 ... 3c 3d // |./0123456789:;<=| + // ^ offset ^ extra space ^ ASCII of line + + for (size_t i = 0; i < len; i++) { + if (ctx->used == 0) { + // The beginning of a line. + BIO_indent(ctx->bio, ctx->indent, UINT_MAX); + + hexbyte(&buf[0], ctx->n >> 24); + hexbyte(&buf[2], ctx->n >> 16); + hexbyte(&buf[4], ctx->n >> 8); + hexbyte(&buf[6], ctx->n); + buf[8] = buf[9] = ' '; + if (BIO_write(ctx->bio, buf, 10) < 0) { + return 0; + } + } + + hexbyte(buf, data[i]); + buf[2] = ' '; + l = 3; + if (ctx->used == 7) { + // There's an additional space after the 8th byte. + buf[3] = ' '; + l = 4; + } else if (ctx->used == 15) { + // At the end of the line there's an extra space and the bar for the + // right column. + buf[3] = ' '; + buf[4] = '|'; + l = 5; + } + + if (BIO_write(ctx->bio, buf, l) < 0) { + return 0; + } + ctx->right_chars[ctx->used] = to_char(data[i]); + ctx->used++; + ctx->n++; + if (ctx->used == 16) { + ctx->right_chars[16] = '|'; + ctx->right_chars[17] = '\n'; + if (BIO_write(ctx->bio, ctx->right_chars, sizeof(ctx->right_chars)) < 0) { + return 0; + } + ctx->used = 0; + } + } + + return 1; +} + +// finish flushes any buffered data in |ctx|. +static int finish(struct hexdump_ctx *ctx) { + // See the comments in |hexdump| for the details of this format. + const unsigned n_bytes = ctx->used; + unsigned l; + char buf[5]; + + if (n_bytes == 0) { + return 1; + } + + OPENSSL_memset(buf, ' ', 4); + buf[4] = '|'; + + for (; ctx->used < 16; ctx->used++) { + l = 3; + if (ctx->used == 7) { + l = 4; + } else if (ctx->used == 15) { + l = 5; + } + if (BIO_write(ctx->bio, buf, l) < 0) { + return 0; + } + } + + ctx->right_chars[n_bytes] = '|'; + ctx->right_chars[n_bytes + 1] = '\n'; + if (BIO_write(ctx->bio, ctx->right_chars, n_bytes + 2) < 0) { + return 0; + } + return 1; +} + +int BIO_hexdump(BIO *bio, const uint8_t *data, size_t len, unsigned indent) { + struct hexdump_ctx ctx; + OPENSSL_memset(&ctx, 0, sizeof(ctx)); + ctx.bio = bio; + ctx.indent = indent; + + if (!hexdump_write(&ctx, data, len) || !finish(&ctx)) { + return 0; + } + + return 1; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/bio/internal.h b/FoodApp/Pods/BoringSSL-GRPC/crypto/bio/internal.h new file mode 100644 index 0000000..36cc921 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/bio/internal.h @@ -0,0 +1,111 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 OPENSSL_HEADER_BIO_INTERNAL_H +#define OPENSSL_HEADER_BIO_INTERNAL_H + +#include + +#if !defined(OPENSSL_WINDOWS) +#if defined(OPENSSL_PNACL) +// newlib uses u_short in socket.h without defining it. +typedef unsigned short u_short; +#endif +#include +#include +#else +OPENSSL_MSVC_PRAGMA(warning(push, 3)) +#include +OPENSSL_MSVC_PRAGMA(warning(pop)) +typedef int socklen_t; +#endif + +#if defined(__cplusplus) +extern "C" { +#endif + + +// BIO_ip_and_port_to_socket_and_addr creates a socket and fills in |*out_addr| +// and |*out_addr_length| with the correct values for connecting to |hostname| +// on |port_str|. It returns one on success or zero on error. +int bio_ip_and_port_to_socket_and_addr(int *out_sock, + struct sockaddr_storage *out_addr, + socklen_t *out_addr_length, + const char *hostname, + const char *port_str); + +// BIO_socket_nbio sets whether |sock| is non-blocking. It returns one on +// success and zero otherwise. +int bio_socket_nbio(int sock, int on); + +// BIO_clear_socket_error clears the last system socket error. +// +// TODO(fork): remove all callers of this. +void bio_clear_socket_error(void); + +// BIO_sock_error returns the last socket error on |sock|. +int bio_sock_error(int sock); + +// BIO_fd_should_retry returns non-zero if |return_value| indicates an error +// and |errno| indicates that it's non-fatal. +int bio_fd_should_retry(int return_value); + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_BIO_INTERNAL_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/bio/internal.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/bio/internal.h.grpc_back new file mode 100644 index 0000000..8ed27da --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/bio/internal.h.grpc_back @@ -0,0 +1,111 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 OPENSSL_HEADER_BIO_INTERNAL_H +#define OPENSSL_HEADER_BIO_INTERNAL_H + +#include + +#if !defined(OPENSSL_WINDOWS) +#if defined(OPENSSL_PNACL) +// newlib uses u_short in socket.h without defining it. +typedef unsigned short u_short; +#endif +#include +#include +#else +OPENSSL_MSVC_PRAGMA(warning(push, 3)) +#include +OPENSSL_MSVC_PRAGMA(warning(pop)) +typedef int socklen_t; +#endif + +#if defined(__cplusplus) +extern "C" { +#endif + + +// BIO_ip_and_port_to_socket_and_addr creates a socket and fills in |*out_addr| +// and |*out_addr_length| with the correct values for connecting to |hostname| +// on |port_str|. It returns one on success or zero on error. +int bio_ip_and_port_to_socket_and_addr(int *out_sock, + struct sockaddr_storage *out_addr, + socklen_t *out_addr_length, + const char *hostname, + const char *port_str); + +// BIO_socket_nbio sets whether |sock| is non-blocking. It returns one on +// success and zero otherwise. +int bio_socket_nbio(int sock, int on); + +// BIO_clear_socket_error clears the last system socket error. +// +// TODO(fork): remove all callers of this. +void bio_clear_socket_error(void); + +// BIO_sock_error returns the last socket error on |sock|. +int bio_sock_error(int sock); + +// BIO_fd_should_retry returns non-zero if |return_value| indicates an error +// and |errno| indicates that it's non-fatal. +int bio_fd_should_retry(int return_value); + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_BIO_INTERNAL_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/bio/pair.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/bio/pair.c new file mode 100644 index 0000000..7d9d82c --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/bio/pair.c @@ -0,0 +1,489 @@ +/* ==================================================================== + * 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 + +#include +#include +#include + +#include "../internal.h" + + +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; + uint8_t *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; + } + OPENSSL_memset(b, 0, sizeof(struct bio_bio_st)); + + b->size = 17 * 1024; // enough for one TLS record (just a default) + bio->ptr = b; + return 1; +} + +static void bio_destroy_pair(BIO *bio) { + struct bio_bio_st *b = bio->ptr; + BIO *peer_bio; + struct bio_bio_st *peer_b; + + if (b == NULL) { + return; + } + + peer_bio = b->peer; + if (peer_bio == NULL) { + return; + } + + 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; +} + +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); + } + + 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); + // one or two iterations + do { + 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); + + OPENSSL_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; +} + +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 + OPENSSL_PUT_ERROR(BIO, 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); + // one or two iterations + do { + 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; + } + + OPENSSL_memcpy(b->buf + write_offset, buf, chunk); + + b->len += chunk; + + assert(b->len <= b->size); + + rest -= chunk; + buf += chunk; + } while (rest); + + return num; +} + +static int bio_make_pair(BIO *bio1, BIO *bio2, size_t writebuf1_len, + size_t writebuf2_len) { + 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) { + OPENSSL_PUT_ERROR(BIO, BIO_R_IN_USE); + return 0; + } + + if (b1->buf == NULL) { + if (writebuf1_len) { + b1->size = writebuf1_len; + } + b1->buf = OPENSSL_malloc(b1->size); + if (b1->buf == NULL) { + OPENSSL_PUT_ERROR(BIO, ERR_R_MALLOC_FAILURE); + return 0; + } + b1->len = 0; + b1->offset = 0; + } + + if (b2->buf == NULL) { + if (writebuf2_len) { + b2->size = writebuf2_len; + } + b2->buf = OPENSSL_malloc(b2->size); + if (b2->buf == NULL) { + OPENSSL_PUT_ERROR(BIO, 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 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_GET_WRITE_BUF_SIZE: + ret = (long)b->size; + 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; + + // standard CTRL codes follow + + 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: + ret = 0; + if (b->buf != NULL) { + ret = (long)b->len; + } + break; + + case BIO_CTRL_FLUSH: + ret = 1; + break; + + case BIO_CTRL_EOF: { + BIO *other_bio = ptr; + + if (other_bio) { + struct bio_bio_st *other_b = other_bio->ptr; + assert(other_b != NULL); + ret = other_b->len == 0 && other_b->closed; + } else { + ret = 1; + } + } break; + + default: + ret = 0; + } + return ret; +} + + +static const BIO_METHOD methods_biop = { + BIO_TYPE_BIO, "BIO pair", bio_write, bio_read, NULL /* puts */, + NULL /* gets */, bio_ctrl, bio_new, bio_free, NULL /* callback_ctrl */, +}; + +static const BIO_METHOD *bio_s_bio(void) { return &methods_biop; } + +int BIO_new_bio_pair(BIO** bio1_p, size_t writebuf1_len, + BIO** bio2_p, size_t writebuf2_len) { + BIO *bio1 = BIO_new(bio_s_bio()); + BIO *bio2 = BIO_new(bio_s_bio()); + if (bio1 == NULL || bio2 == NULL || + !bio_make_pair(bio1, bio2, writebuf1_len, writebuf2_len)) { + BIO_free(bio1); + BIO_free(bio2); + *bio1_p = NULL; + *bio2_p = NULL; + return 0; + } + + *bio1_p = bio1; + *bio2_p = bio2; + return 1; +} + +size_t BIO_ctrl_get_read_request(BIO *bio) { + return BIO_ctrl(bio, BIO_C_GET_READ_REQUEST, 0, NULL); +} + +size_t BIO_ctrl_get_write_guarantee(BIO *bio) { + return BIO_ctrl(bio, BIO_C_GET_WRITE_GUARANTEE, 0, NULL); +} + +int BIO_shutdown_wr(BIO *bio) { + return BIO_ctrl(bio, BIO_C_SHUTDOWN_WR, 0, NULL); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/bio/pair.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/bio/pair.c.grpc_back new file mode 100644 index 0000000..f5057ed --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/bio/pair.c.grpc_back @@ -0,0 +1,489 @@ +/* ==================================================================== + * 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 + +#include +#include +#include + +#include "../internal.h" + + +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; + uint8_t *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; + } + OPENSSL_memset(b, 0, sizeof(struct bio_bio_st)); + + b->size = 17 * 1024; // enough for one TLS record (just a default) + bio->ptr = b; + return 1; +} + +static void bio_destroy_pair(BIO *bio) { + struct bio_bio_st *b = bio->ptr; + BIO *peer_bio; + struct bio_bio_st *peer_b; + + if (b == NULL) { + return; + } + + peer_bio = b->peer; + if (peer_bio == NULL) { + return; + } + + 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; +} + +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); + } + + 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); + // one or two iterations + do { + 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); + + OPENSSL_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; +} + +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 + OPENSSL_PUT_ERROR(BIO, 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); + // one or two iterations + do { + 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; + } + + OPENSSL_memcpy(b->buf + write_offset, buf, chunk); + + b->len += chunk; + + assert(b->len <= b->size); + + rest -= chunk; + buf += chunk; + } while (rest); + + return num; +} + +static int bio_make_pair(BIO *bio1, BIO *bio2, size_t writebuf1_len, + size_t writebuf2_len) { + 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) { + OPENSSL_PUT_ERROR(BIO, BIO_R_IN_USE); + return 0; + } + + if (b1->buf == NULL) { + if (writebuf1_len) { + b1->size = writebuf1_len; + } + b1->buf = OPENSSL_malloc(b1->size); + if (b1->buf == NULL) { + OPENSSL_PUT_ERROR(BIO, ERR_R_MALLOC_FAILURE); + return 0; + } + b1->len = 0; + b1->offset = 0; + } + + if (b2->buf == NULL) { + if (writebuf2_len) { + b2->size = writebuf2_len; + } + b2->buf = OPENSSL_malloc(b2->size); + if (b2->buf == NULL) { + OPENSSL_PUT_ERROR(BIO, 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 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_GET_WRITE_BUF_SIZE: + ret = (long)b->size; + 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; + + // standard CTRL codes follow + + 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: + ret = 0; + if (b->buf != NULL) { + ret = (long)b->len; + } + break; + + case BIO_CTRL_FLUSH: + ret = 1; + break; + + case BIO_CTRL_EOF: { + BIO *other_bio = ptr; + + if (other_bio) { + struct bio_bio_st *other_b = other_bio->ptr; + assert(other_b != NULL); + ret = other_b->len == 0 && other_b->closed; + } else { + ret = 1; + } + } break; + + default: + ret = 0; + } + return ret; +} + + +static const BIO_METHOD methods_biop = { + BIO_TYPE_BIO, "BIO pair", bio_write, bio_read, NULL /* puts */, + NULL /* gets */, bio_ctrl, bio_new, bio_free, NULL /* callback_ctrl */, +}; + +static const BIO_METHOD *bio_s_bio(void) { return &methods_biop; } + +int BIO_new_bio_pair(BIO** bio1_p, size_t writebuf1_len, + BIO** bio2_p, size_t writebuf2_len) { + BIO *bio1 = BIO_new(bio_s_bio()); + BIO *bio2 = BIO_new(bio_s_bio()); + if (bio1 == NULL || bio2 == NULL || + !bio_make_pair(bio1, bio2, writebuf1_len, writebuf2_len)) { + BIO_free(bio1); + BIO_free(bio2); + *bio1_p = NULL; + *bio2_p = NULL; + return 0; + } + + *bio1_p = bio1; + *bio2_p = bio2; + return 1; +} + +size_t BIO_ctrl_get_read_request(BIO *bio) { + return BIO_ctrl(bio, BIO_C_GET_READ_REQUEST, 0, NULL); +} + +size_t BIO_ctrl_get_write_guarantee(BIO *bio) { + return BIO_ctrl(bio, BIO_C_GET_WRITE_GUARANTEE, 0, NULL); +} + +int BIO_shutdown_wr(BIO *bio) { + return BIO_ctrl(bio, BIO_C_SHUTDOWN_WR, 0, NULL); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/bio/printf.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/bio/printf.c new file mode 100644 index 0000000..d33814f --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/bio/printf.c @@ -0,0 +1,115 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 +#include + +int BIO_printf(BIO *bio, const char *format, ...) { + va_list args; + char buf[256], *out, out_malloced = 0; + int out_len, ret; + + va_start(args, format); + out_len = vsnprintf(buf, sizeof(buf), format, args); + va_end(args); + +#if defined(OPENSSL_WINDOWS) + // On Windows, vsnprintf returns -1 rather than the requested length on + // truncation + if (out_len < 0) { + va_start(args, format); + out_len = _vscprintf(format, args); + va_end(args); + assert(out_len >= (int)sizeof(buf)); + } +#endif + + if (out_len < 0) { + return -1; + } + + if ((size_t) out_len >= sizeof(buf)) { + const int requested_len = out_len; + // The output was truncated. Note that vsnprintf's return value + // does not include a trailing NUL, but the buffer must be sized + // for it. + out = OPENSSL_malloc(requested_len + 1); + out_malloced = 1; + if (out == NULL) { + OPENSSL_PUT_ERROR(BIO, ERR_R_MALLOC_FAILURE); + return -1; + } + va_start(args, format); + out_len = vsnprintf(out, requested_len + 1, format, args); + va_end(args); + assert(out_len == requested_len); + } else { + out = buf; + } + + ret = BIO_write(bio, out, out_len); + if (out_malloced) { + OPENSSL_free(out); + } + + return ret; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/bio/printf.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/bio/printf.c.grpc_back new file mode 100644 index 0000000..4f9d8a1 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/bio/printf.c.grpc_back @@ -0,0 +1,115 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 +#include + +int BIO_printf(BIO *bio, const char *format, ...) { + va_list args; + char buf[256], *out, out_malloced = 0; + int out_len, ret; + + va_start(args, format); + out_len = vsnprintf(buf, sizeof(buf), format, args); + va_end(args); + +#if defined(OPENSSL_WINDOWS) + // On Windows, vsnprintf returns -1 rather than the requested length on + // truncation + if (out_len < 0) { + va_start(args, format); + out_len = _vscprintf(format, args); + va_end(args); + assert(out_len >= (int)sizeof(buf)); + } +#endif + + if (out_len < 0) { + return -1; + } + + if ((size_t) out_len >= sizeof(buf)) { + const int requested_len = out_len; + // The output was truncated. Note that vsnprintf's return value + // does not include a trailing NUL, but the buffer must be sized + // for it. + out = OPENSSL_malloc(requested_len + 1); + out_malloced = 1; + if (out == NULL) { + OPENSSL_PUT_ERROR(BIO, ERR_R_MALLOC_FAILURE); + return -1; + } + va_start(args, format); + out_len = vsnprintf(out, requested_len + 1, format, args); + va_end(args); + assert(out_len == requested_len); + } else { + out = buf; + } + + ret = BIO_write(bio, out, out_len); + if (out_malloced) { + OPENSSL_free(out); + } + + return ret; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/bio/socket.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/bio/socket.c new file mode 100644 index 0000000..5961170 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/bio/socket.c @@ -0,0 +1,202 @@ +/* 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 +#include + +#if !defined(OPENSSL_WINDOWS) +#include +#else +OPENSSL_MSVC_PRAGMA(warning(push, 3)) +#include +OPENSSL_MSVC_PRAGMA(warning(pop)) + +OPENSSL_MSVC_PRAGMA(comment(lib, "Ws2_32.lib")) +#endif + +#include "internal.h" + + +#if !defined(OPENSSL_WINDOWS) +static int closesocket(int sock) { + return close(sock); +} +#endif + +static int sock_new(BIO *bio) { + bio->init = 0; + bio->num = 0; + bio->ptr = NULL; + bio->flags = 0; + return 1; +} + +static int sock_free(BIO *bio) { + if (bio == NULL) { + return 0; + } + + if (bio->shutdown) { + if (bio->init) { + closesocket(bio->num); + } + bio->init = 0; + bio->flags = 0; + } + return 1; +} + +static int sock_read(BIO *b, char *out, int outl) { + int ret = 0; + + if (out == NULL) { + return 0; + } + + bio_clear_socket_error(); +#if defined(OPENSSL_WINDOWS) + ret = recv(b->num, out, outl, 0); +#else + ret = read(b->num, out, outl); +#endif + BIO_clear_retry_flags(b); + if (ret <= 0) { + if (bio_fd_should_retry(ret)) { + BIO_set_retry_read(b); + } + } + return ret; +} + +static int sock_write(BIO *b, const char *in, int inl) { + int ret; + + bio_clear_socket_error(); +#if defined(OPENSSL_WINDOWS) + ret = send(b->num, in, inl, 0); +#else + ret = write(b->num, in, inl); +#endif + BIO_clear_retry_flags(b); + if (ret <= 0) { + if (bio_fd_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_FLUSH: + ret = 1; + break; + default: + ret = 0; + break; + } + return ret; +} + +static const BIO_METHOD methods_sockp = { + BIO_TYPE_SOCKET, "socket", + sock_write, sock_read, + NULL /* puts */, NULL /* gets, */, + sock_ctrl, sock_new, + sock_free, NULL /* callback_ctrl */, +}; + +const 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; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/bio/socket.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/bio/socket.c.grpc_back new file mode 100644 index 0000000..111761f --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/bio/socket.c.grpc_back @@ -0,0 +1,202 @@ +/* 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 +#include + +#if !defined(OPENSSL_WINDOWS) +#include +#else +OPENSSL_MSVC_PRAGMA(warning(push, 3)) +#include +OPENSSL_MSVC_PRAGMA(warning(pop)) + +OPENSSL_MSVC_PRAGMA(comment(lib, "Ws2_32.lib")) +#endif + +#include "internal.h" + + +#if !defined(OPENSSL_WINDOWS) +static int closesocket(int sock) { + return close(sock); +} +#endif + +static int sock_new(BIO *bio) { + bio->init = 0; + bio->num = 0; + bio->ptr = NULL; + bio->flags = 0; + return 1; +} + +static int sock_free(BIO *bio) { + if (bio == NULL) { + return 0; + } + + if (bio->shutdown) { + if (bio->init) { + closesocket(bio->num); + } + bio->init = 0; + bio->flags = 0; + } + return 1; +} + +static int sock_read(BIO *b, char *out, int outl) { + int ret = 0; + + if (out == NULL) { + return 0; + } + + bio_clear_socket_error(); +#if defined(OPENSSL_WINDOWS) + ret = recv(b->num, out, outl, 0); +#else + ret = read(b->num, out, outl); +#endif + BIO_clear_retry_flags(b); + if (ret <= 0) { + if (bio_fd_should_retry(ret)) { + BIO_set_retry_read(b); + } + } + return ret; +} + +static int sock_write(BIO *b, const char *in, int inl) { + int ret; + + bio_clear_socket_error(); +#if defined(OPENSSL_WINDOWS) + ret = send(b->num, in, inl, 0); +#else + ret = write(b->num, in, inl); +#endif + BIO_clear_retry_flags(b); + if (ret <= 0) { + if (bio_fd_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_FLUSH: + ret = 1; + break; + default: + ret = 0; + break; + } + return ret; +} + +static const BIO_METHOD methods_sockp = { + BIO_TYPE_SOCKET, "socket", + sock_write, sock_read, + NULL /* puts */, NULL /* gets, */, + sock_ctrl, sock_new, + sock_free, NULL /* callback_ctrl */, +}; + +const 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; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/bio/socket_helper.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/bio/socket_helper.c new file mode 100644 index 0000000..8101c83 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/bio/socket_helper.c @@ -0,0 +1,114 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#undef _POSIX_C_SOURCE +#define _POSIX_C_SOURCE 200112L + +#include +#include + +#include +#include +#include + +#if !defined(OPENSSL_WINDOWS) +#include +#include +#else +OPENSSL_MSVC_PRAGMA(warning(push, 3)) +#include +#include +OPENSSL_MSVC_PRAGMA(warning(pop)) +#endif + +#include "internal.h" +#include "../internal.h" + + +int bio_ip_and_port_to_socket_and_addr(int *out_sock, + struct sockaddr_storage *out_addr, + socklen_t *out_addr_length, + const char *hostname, + const char *port_str) { + struct addrinfo hint, *result, *cur; + int ret; + + *out_sock = -1; + + OPENSSL_memset(&hint, 0, sizeof(hint)); + hint.ai_family = AF_UNSPEC; + hint.ai_socktype = SOCK_STREAM; + + ret = getaddrinfo(hostname, port_str, &hint, &result); + if (ret != 0) { + OPENSSL_PUT_ERROR(SYS, 0); + ERR_add_error_data(1, gai_strerror(ret)); + return 0; + } + + ret = 0; + + for (cur = result; cur; cur = cur->ai_next) { + if ((size_t) cur->ai_addrlen > sizeof(struct sockaddr_storage)) { + continue; + } + OPENSSL_memset(out_addr, 0, sizeof(struct sockaddr_storage)); + OPENSSL_memcpy(out_addr, cur->ai_addr, cur->ai_addrlen); + *out_addr_length = cur->ai_addrlen; + + *out_sock = socket(cur->ai_family, cur->ai_socktype, cur->ai_protocol); + if (*out_sock < 0) { + OPENSSL_PUT_SYSTEM_ERROR(); + goto out; + } + + ret = 1; + break; + } + +out: + freeaddrinfo(result); + return ret; +} + +int bio_socket_nbio(int sock, int on) { +#if defined(OPENSSL_WINDOWS) + u_long arg = on; + + return 0 == ioctlsocket(sock, FIONBIO, &arg); +#else + int flags = fcntl(sock, F_GETFL, 0); + if (flags < 0) { + return 0; + } + if (!on) { + flags &= ~O_NONBLOCK; + } else { + flags |= O_NONBLOCK; + } + return fcntl(sock, F_SETFL, flags) == 0; +#endif +} + +void bio_clear_socket_error(void) {} + +int bio_sock_error(int sock) { + int error; + socklen_t error_size = sizeof(error); + + if (getsockopt(sock, SOL_SOCKET, SO_ERROR, (char *)&error, &error_size) < 0) { + return 1; + } + return error; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/bio/socket_helper.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/bio/socket_helper.c.grpc_back new file mode 100644 index 0000000..268405a --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/bio/socket_helper.c.grpc_back @@ -0,0 +1,114 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#undef _POSIX_C_SOURCE +#define _POSIX_C_SOURCE 200112L + +#include +#include + +#include +#include +#include + +#if !defined(OPENSSL_WINDOWS) +#include +#include +#else +OPENSSL_MSVC_PRAGMA(warning(push, 3)) +#include +#include +OPENSSL_MSVC_PRAGMA(warning(pop)) +#endif + +#include "internal.h" +#include "../internal.h" + + +int bio_ip_and_port_to_socket_and_addr(int *out_sock, + struct sockaddr_storage *out_addr, + socklen_t *out_addr_length, + const char *hostname, + const char *port_str) { + struct addrinfo hint, *result, *cur; + int ret; + + *out_sock = -1; + + OPENSSL_memset(&hint, 0, sizeof(hint)); + hint.ai_family = AF_UNSPEC; + hint.ai_socktype = SOCK_STREAM; + + ret = getaddrinfo(hostname, port_str, &hint, &result); + if (ret != 0) { + OPENSSL_PUT_ERROR(SYS, 0); + ERR_add_error_data(1, gai_strerror(ret)); + return 0; + } + + ret = 0; + + for (cur = result; cur; cur = cur->ai_next) { + if ((size_t) cur->ai_addrlen > sizeof(struct sockaddr_storage)) { + continue; + } + OPENSSL_memset(out_addr, 0, sizeof(struct sockaddr_storage)); + OPENSSL_memcpy(out_addr, cur->ai_addr, cur->ai_addrlen); + *out_addr_length = cur->ai_addrlen; + + *out_sock = socket(cur->ai_family, cur->ai_socktype, cur->ai_protocol); + if (*out_sock < 0) { + OPENSSL_PUT_SYSTEM_ERROR(); + goto out; + } + + ret = 1; + break; + } + +out: + freeaddrinfo(result); + return ret; +} + +int bio_socket_nbio(int sock, int on) { +#if defined(OPENSSL_WINDOWS) + u_long arg = on; + + return 0 == ioctlsocket(sock, FIONBIO, &arg); +#else + int flags = fcntl(sock, F_GETFL, 0); + if (flags < 0) { + return 0; + } + if (!on) { + flags &= ~O_NONBLOCK; + } else { + flags |= O_NONBLOCK; + } + return fcntl(sock, F_SETFL, flags) == 0; +#endif +} + +void bio_clear_socket_error(void) {} + +int bio_sock_error(int sock) { + int error; + socklen_t error_size = sizeof(error); + + if (getsockopt(sock, SOL_SOCKET, SO_ERROR, (char *)&error, &error_size) < 0) { + return 1; + } + return error; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/bn_extra/bn_asn1.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/bn_extra/bn_asn1.c new file mode 100644 index 0000000..ce08c53 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/bn_extra/bn_asn1.c @@ -0,0 +1,64 @@ +/* Copyright (c) 2015, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include +#include + + +int BN_parse_asn1_unsigned(CBS *cbs, BIGNUM *ret) { + CBS child; + if (!CBS_get_asn1(cbs, &child, CBS_ASN1_INTEGER) || + CBS_len(&child) == 0) { + OPENSSL_PUT_ERROR(BN, BN_R_BAD_ENCODING); + return 0; + } + + if (CBS_data(&child)[0] & 0x80) { + OPENSSL_PUT_ERROR(BN, BN_R_NEGATIVE_NUMBER); + return 0; + } + + // INTEGERs must be minimal. + if (CBS_data(&child)[0] == 0x00 && + CBS_len(&child) > 1 && + !(CBS_data(&child)[1] & 0x80)) { + OPENSSL_PUT_ERROR(BN, BN_R_BAD_ENCODING); + return 0; + } + + return BN_bin2bn(CBS_data(&child), CBS_len(&child), ret) != NULL; +} + +int BN_marshal_asn1(CBB *cbb, const BIGNUM *bn) { + // Negative numbers are unsupported. + if (BN_is_negative(bn)) { + OPENSSL_PUT_ERROR(BN, BN_R_NEGATIVE_NUMBER); + return 0; + } + + CBB child; + if (!CBB_add_asn1(cbb, &child, CBS_ASN1_INTEGER) || + // The number must be padded with a leading zero if the high bit would + // otherwise be set or if |bn| is zero. + (BN_num_bits(bn) % 8 == 0 && !CBB_add_u8(&child, 0x00)) || + !BN_bn2cbb_padded(&child, BN_num_bytes(bn), bn) || + !CBB_flush(cbb)) { + OPENSSL_PUT_ERROR(BN, BN_R_ENCODE_ERROR); + return 0; + } + + return 1; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/bn_extra/bn_asn1.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/bn_extra/bn_asn1.c.grpc_back new file mode 100644 index 0000000..0d96573 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/bn_extra/bn_asn1.c.grpc_back @@ -0,0 +1,64 @@ +/* Copyright (c) 2015, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include +#include + + +int BN_parse_asn1_unsigned(CBS *cbs, BIGNUM *ret) { + CBS child; + if (!CBS_get_asn1(cbs, &child, CBS_ASN1_INTEGER) || + CBS_len(&child) == 0) { + OPENSSL_PUT_ERROR(BN, BN_R_BAD_ENCODING); + return 0; + } + + if (CBS_data(&child)[0] & 0x80) { + OPENSSL_PUT_ERROR(BN, BN_R_NEGATIVE_NUMBER); + return 0; + } + + // INTEGERs must be minimal. + if (CBS_data(&child)[0] == 0x00 && + CBS_len(&child) > 1 && + !(CBS_data(&child)[1] & 0x80)) { + OPENSSL_PUT_ERROR(BN, BN_R_BAD_ENCODING); + return 0; + } + + return BN_bin2bn(CBS_data(&child), CBS_len(&child), ret) != NULL; +} + +int BN_marshal_asn1(CBB *cbb, const BIGNUM *bn) { + // Negative numbers are unsupported. + if (BN_is_negative(bn)) { + OPENSSL_PUT_ERROR(BN, BN_R_NEGATIVE_NUMBER); + return 0; + } + + CBB child; + if (!CBB_add_asn1(cbb, &child, CBS_ASN1_INTEGER) || + // The number must be padded with a leading zero if the high bit would + // otherwise be set or if |bn| is zero. + (BN_num_bits(bn) % 8 == 0 && !CBB_add_u8(&child, 0x00)) || + !BN_bn2cbb_padded(&child, BN_num_bytes(bn), bn) || + !CBB_flush(cbb)) { + OPENSSL_PUT_ERROR(BN, BN_R_ENCODE_ERROR); + return 0; + } + + return 1; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/bn_extra/convert.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/bn_extra/convert.c new file mode 100644 index 0000000..2610ae5 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/bn_extra/convert.c @@ -0,0 +1,466 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 + +#include +#include +#include +#include + +#include "../fipsmodule/bn/internal.h" + + +int BN_bn2cbb_padded(CBB *out, size_t len, const BIGNUM *in) { + uint8_t *ptr; + return CBB_add_space(out, &ptr, len) && BN_bn2bin_padded(ptr, len, in); +} + +static const char hextable[] = "0123456789abcdef"; + +char *BN_bn2hex(const BIGNUM *bn) { + int width = bn_minimal_width(bn); + char *buf = OPENSSL_malloc(1 /* leading '-' */ + 1 /* zero is non-empty */ + + width * BN_BYTES * 2 + 1 /* trailing NUL */); + if (buf == NULL) { + OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE); + return NULL; + } + + char *p = buf; + if (bn->neg) { + *(p++) = '-'; + } + + if (BN_is_zero(bn)) { + *(p++) = '0'; + } + + int z = 0; + for (int i = width - 1; i >= 0; i--) { + for (int j = BN_BITS2 - 8; j >= 0; j -= 8) { + // strip leading zeros + int v = ((int)(bn->d[i] >> (long)j)) & 0xff; + if (z || v != 0) { + *(p++) = hextable[v >> 4]; + *(p++) = hextable[v & 0x0f]; + z = 1; + } + } + } + *p = '\0'; + + return buf; +} + +// decode_hex decodes |in_len| bytes of hex data from |in| and updates |bn|. +static int decode_hex(BIGNUM *bn, const char *in, int in_len) { + if (in_len > INT_MAX/4) { + OPENSSL_PUT_ERROR(BN, BN_R_BIGNUM_TOO_LONG); + return 0; + } + // |in_len| is the number of hex digits. + if (!bn_expand(bn, in_len * 4)) { + return 0; + } + + int i = 0; + while (in_len > 0) { + // Decode one |BN_ULONG| at a time. + int todo = BN_BYTES * 2; + if (todo > in_len) { + todo = in_len; + } + + BN_ULONG word = 0; + int j; + for (j = todo; j > 0; j--) { + char c = in[in_len - j]; + + BN_ULONG hex; + if (c >= '0' && c <= '9') { + hex = c - '0'; + } else if (c >= 'a' && c <= 'f') { + hex = c - 'a' + 10; + } else if (c >= 'A' && c <= 'F') { + hex = c - 'A' + 10; + } else { + hex = 0; + // This shouldn't happen. The caller checks |isxdigit|. + assert(0); + } + word = (word << 4) | hex; + } + + bn->d[i++] = word; + in_len -= todo; + } + assert(i <= bn->dmax); + bn->width = i; + return 1; +} + +// decode_dec decodes |in_len| bytes of decimal data from |in| and updates |bn|. +static int decode_dec(BIGNUM *bn, const char *in, int in_len) { + int i, j; + BN_ULONG l = 0; + + // Decode |BN_DEC_NUM| digits at a time. + j = BN_DEC_NUM - (in_len % BN_DEC_NUM); + if (j == BN_DEC_NUM) { + j = 0; + } + l = 0; + for (i = 0; i < in_len; i++) { + l *= 10; + l += in[i] - '0'; + if (++j == BN_DEC_NUM) { + if (!BN_mul_word(bn, BN_DEC_CONV) || + !BN_add_word(bn, l)) { + return 0; + } + l = 0; + j = 0; + } + } + return 1; +} + +typedef int (*decode_func) (BIGNUM *bn, const char *in, int in_len); +typedef int (*char_test_func) (int c); + +static int bn_x2bn(BIGNUM **outp, const char *in, decode_func decode, char_test_func want_char) { + BIGNUM *ret = NULL; + int neg = 0, i; + int num; + + if (in == NULL || *in == 0) { + return 0; + } + + if (*in == '-') { + neg = 1; + in++; + } + + for (i = 0; want_char((unsigned char)in[i]) && i + neg < INT_MAX; i++) {} + + num = i + neg; + if (outp == NULL) { + return num; + } + + // in is the start of the hex digits, and it is 'i' long + if (*outp == NULL) { + ret = BN_new(); + if (ret == NULL) { + return 0; + } + } else { + ret = *outp; + BN_zero(ret); + } + + if (!decode(ret, in, i)) { + goto err; + } + + bn_set_minimal_width(ret); + if (!BN_is_zero(ret)) { + ret->neg = neg; + } + + *outp = ret; + return num; + +err: + if (*outp == NULL) { + BN_free(ret); + } + + return 0; +} + +int BN_hex2bn(BIGNUM **outp, const char *in) { + return bn_x2bn(outp, in, decode_hex, isxdigit); +} + +char *BN_bn2dec(const BIGNUM *a) { + // It is easier to print strings little-endian, so we assemble it in reverse + // and fix at the end. + BIGNUM *copy = NULL; + CBB cbb; + if (!CBB_init(&cbb, 16) || + !CBB_add_u8(&cbb, 0 /* trailing NUL */)) { + goto cbb_err; + } + + if (BN_is_zero(a)) { + if (!CBB_add_u8(&cbb, '0')) { + goto cbb_err; + } + } else { + copy = BN_dup(a); + if (copy == NULL) { + goto err; + } + + while (!BN_is_zero(copy)) { + BN_ULONG word = BN_div_word(copy, BN_DEC_CONV); + if (word == (BN_ULONG)-1) { + goto err; + } + + const int add_leading_zeros = !BN_is_zero(copy); + for (int i = 0; i < BN_DEC_NUM && (add_leading_zeros || word != 0); i++) { + if (!CBB_add_u8(&cbb, '0' + word % 10)) { + goto cbb_err; + } + word /= 10; + } + assert(word == 0); + } + } + + if (BN_is_negative(a) && + !CBB_add_u8(&cbb, '-')) { + goto cbb_err; + } + + uint8_t *data; + size_t len; + if (!CBB_finish(&cbb, &data, &len)) { + goto cbb_err; + } + + // Reverse the buffer. + for (size_t i = 0; i < len/2; i++) { + uint8_t tmp = data[i]; + data[i] = data[len - 1 - i]; + data[len - 1 - i] = tmp; + } + + BN_free(copy); + return (char *)data; + +cbb_err: + OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE); +err: + BN_free(copy); + CBB_cleanup(&cbb); + return NULL; +} + +int BN_dec2bn(BIGNUM **outp, const char *in) { + return bn_x2bn(outp, in, decode_dec, isdigit); +} + +int BN_asc2bn(BIGNUM **outp, const char *in) { + const char *const orig_in = in; + if (*in == '-') { + in++; + } + + if (in[0] == '0' && (in[1] == 'X' || in[1] == 'x')) { + if (!BN_hex2bn(outp, in+2)) { + return 0; + } + } else { + if (!BN_dec2bn(outp, in)) { + return 0; + } + } + + if (*orig_in == '-' && !BN_is_zero(*outp)) { + (*outp)->neg = 1; + } + + return 1; +} + +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 = bn_minimal_width(a) - 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, &hextable[v], 1) != 1) { + goto end; + } + z = 1; + } + } + } + ret = 1; + +end: + return ret; +} + +int BN_print_fp(FILE *fp, const BIGNUM *a) { + BIO *b; + int ret; + + b = BIO_new(BIO_s_file()); + if (b == NULL) { + return 0; + } + BIO_set_fp(b, fp, BIO_NOCLOSE); + ret = BN_print(b, a); + BIO_free(b); + + return ret; +} + + +size_t BN_bn2mpi(const BIGNUM *in, uint8_t *out) { + const size_t bits = BN_num_bits(in); + const size_t bytes = (bits + 7) / 8; + // If the number of bits is a multiple of 8, i.e. if the MSB is set, + // prefix with a zero byte. + int extend = 0; + if (bytes != 0 && (bits & 0x07) == 0) { + extend = 1; + } + + const size_t len = bytes + extend; + if (len < bytes || + 4 + len < len || + (len & 0xffffffff) != len) { + // If we cannot represent the number then we emit zero as the interface + // doesn't allow an error to be signalled. + if (out) { + OPENSSL_memset(out, 0, 4); + } + return 4; + } + + if (out == NULL) { + return 4 + len; + } + + out[0] = len >> 24; + out[1] = len >> 16; + out[2] = len >> 8; + out[3] = len; + if (extend) { + out[4] = 0; + } + BN_bn2bin(in, out + 4 + extend); + if (in->neg && len > 0) { + out[4] |= 0x80; + } + return len + 4; +} + +BIGNUM *BN_mpi2bn(const uint8_t *in, size_t len, BIGNUM *out) { + if (len < 4) { + OPENSSL_PUT_ERROR(BN, BN_R_BAD_ENCODING); + return NULL; + } + const size_t in_len = ((size_t)in[0] << 24) | + ((size_t)in[1] << 16) | + ((size_t)in[2] << 8) | + ((size_t)in[3]); + if (in_len != len - 4) { + OPENSSL_PUT_ERROR(BN, BN_R_BAD_ENCODING); + return NULL; + } + + int out_is_alloced = 0; + if (out == NULL) { + out = BN_new(); + if (out == NULL) { + OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE); + return NULL; + } + out_is_alloced = 1; + } + + if (in_len == 0) { + BN_zero(out); + return out; + } + + in += 4; + if (BN_bin2bn(in, in_len, out) == NULL) { + if (out_is_alloced) { + BN_free(out); + } + return NULL; + } + out->neg = ((*in) & 0x80) != 0; + if (out->neg) { + BN_clear_bit(out, BN_num_bits(out) - 1); + } + return out; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/bn_extra/convert.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/bn_extra/convert.c.grpc_back new file mode 100644 index 0000000..c70ff8b --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/bn_extra/convert.c.grpc_back @@ -0,0 +1,466 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 + +#include +#include +#include +#include + +#include "../fipsmodule/bn/internal.h" + + +int BN_bn2cbb_padded(CBB *out, size_t len, const BIGNUM *in) { + uint8_t *ptr; + return CBB_add_space(out, &ptr, len) && BN_bn2bin_padded(ptr, len, in); +} + +static const char hextable[] = "0123456789abcdef"; + +char *BN_bn2hex(const BIGNUM *bn) { + int width = bn_minimal_width(bn); + char *buf = OPENSSL_malloc(1 /* leading '-' */ + 1 /* zero is non-empty */ + + width * BN_BYTES * 2 + 1 /* trailing NUL */); + if (buf == NULL) { + OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE); + return NULL; + } + + char *p = buf; + if (bn->neg) { + *(p++) = '-'; + } + + if (BN_is_zero(bn)) { + *(p++) = '0'; + } + + int z = 0; + for (int i = width - 1; i >= 0; i--) { + for (int j = BN_BITS2 - 8; j >= 0; j -= 8) { + // strip leading zeros + int v = ((int)(bn->d[i] >> (long)j)) & 0xff; + if (z || v != 0) { + *(p++) = hextable[v >> 4]; + *(p++) = hextable[v & 0x0f]; + z = 1; + } + } + } + *p = '\0'; + + return buf; +} + +// decode_hex decodes |in_len| bytes of hex data from |in| and updates |bn|. +static int decode_hex(BIGNUM *bn, const char *in, int in_len) { + if (in_len > INT_MAX/4) { + OPENSSL_PUT_ERROR(BN, BN_R_BIGNUM_TOO_LONG); + return 0; + } + // |in_len| is the number of hex digits. + if (!bn_expand(bn, in_len * 4)) { + return 0; + } + + int i = 0; + while (in_len > 0) { + // Decode one |BN_ULONG| at a time. + int todo = BN_BYTES * 2; + if (todo > in_len) { + todo = in_len; + } + + BN_ULONG word = 0; + int j; + for (j = todo; j > 0; j--) { + char c = in[in_len - j]; + + BN_ULONG hex; + if (c >= '0' && c <= '9') { + hex = c - '0'; + } else if (c >= 'a' && c <= 'f') { + hex = c - 'a' + 10; + } else if (c >= 'A' && c <= 'F') { + hex = c - 'A' + 10; + } else { + hex = 0; + // This shouldn't happen. The caller checks |isxdigit|. + assert(0); + } + word = (word << 4) | hex; + } + + bn->d[i++] = word; + in_len -= todo; + } + assert(i <= bn->dmax); + bn->width = i; + return 1; +} + +// decode_dec decodes |in_len| bytes of decimal data from |in| and updates |bn|. +static int decode_dec(BIGNUM *bn, const char *in, int in_len) { + int i, j; + BN_ULONG l = 0; + + // Decode |BN_DEC_NUM| digits at a time. + j = BN_DEC_NUM - (in_len % BN_DEC_NUM); + if (j == BN_DEC_NUM) { + j = 0; + } + l = 0; + for (i = 0; i < in_len; i++) { + l *= 10; + l += in[i] - '0'; + if (++j == BN_DEC_NUM) { + if (!BN_mul_word(bn, BN_DEC_CONV) || + !BN_add_word(bn, l)) { + return 0; + } + l = 0; + j = 0; + } + } + return 1; +} + +typedef int (*decode_func) (BIGNUM *bn, const char *in, int in_len); +typedef int (*char_test_func) (int c); + +static int bn_x2bn(BIGNUM **outp, const char *in, decode_func decode, char_test_func want_char) { + BIGNUM *ret = NULL; + int neg = 0, i; + int num; + + if (in == NULL || *in == 0) { + return 0; + } + + if (*in == '-') { + neg = 1; + in++; + } + + for (i = 0; want_char((unsigned char)in[i]) && i + neg < INT_MAX; i++) {} + + num = i + neg; + if (outp == NULL) { + return num; + } + + // in is the start of the hex digits, and it is 'i' long + if (*outp == NULL) { + ret = BN_new(); + if (ret == NULL) { + return 0; + } + } else { + ret = *outp; + BN_zero(ret); + } + + if (!decode(ret, in, i)) { + goto err; + } + + bn_set_minimal_width(ret); + if (!BN_is_zero(ret)) { + ret->neg = neg; + } + + *outp = ret; + return num; + +err: + if (*outp == NULL) { + BN_free(ret); + } + + return 0; +} + +int BN_hex2bn(BIGNUM **outp, const char *in) { + return bn_x2bn(outp, in, decode_hex, isxdigit); +} + +char *BN_bn2dec(const BIGNUM *a) { + // It is easier to print strings little-endian, so we assemble it in reverse + // and fix at the end. + BIGNUM *copy = NULL; + CBB cbb; + if (!CBB_init(&cbb, 16) || + !CBB_add_u8(&cbb, 0 /* trailing NUL */)) { + goto cbb_err; + } + + if (BN_is_zero(a)) { + if (!CBB_add_u8(&cbb, '0')) { + goto cbb_err; + } + } else { + copy = BN_dup(a); + if (copy == NULL) { + goto err; + } + + while (!BN_is_zero(copy)) { + BN_ULONG word = BN_div_word(copy, BN_DEC_CONV); + if (word == (BN_ULONG)-1) { + goto err; + } + + const int add_leading_zeros = !BN_is_zero(copy); + for (int i = 0; i < BN_DEC_NUM && (add_leading_zeros || word != 0); i++) { + if (!CBB_add_u8(&cbb, '0' + word % 10)) { + goto cbb_err; + } + word /= 10; + } + assert(word == 0); + } + } + + if (BN_is_negative(a) && + !CBB_add_u8(&cbb, '-')) { + goto cbb_err; + } + + uint8_t *data; + size_t len; + if (!CBB_finish(&cbb, &data, &len)) { + goto cbb_err; + } + + // Reverse the buffer. + for (size_t i = 0; i < len/2; i++) { + uint8_t tmp = data[i]; + data[i] = data[len - 1 - i]; + data[len - 1 - i] = tmp; + } + + BN_free(copy); + return (char *)data; + +cbb_err: + OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE); +err: + BN_free(copy); + CBB_cleanup(&cbb); + return NULL; +} + +int BN_dec2bn(BIGNUM **outp, const char *in) { + return bn_x2bn(outp, in, decode_dec, isdigit); +} + +int BN_asc2bn(BIGNUM **outp, const char *in) { + const char *const orig_in = in; + if (*in == '-') { + in++; + } + + if (in[0] == '0' && (in[1] == 'X' || in[1] == 'x')) { + if (!BN_hex2bn(outp, in+2)) { + return 0; + } + } else { + if (!BN_dec2bn(outp, in)) { + return 0; + } + } + + if (*orig_in == '-' && !BN_is_zero(*outp)) { + (*outp)->neg = 1; + } + + return 1; +} + +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 = bn_minimal_width(a) - 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, &hextable[v], 1) != 1) { + goto end; + } + z = 1; + } + } + } + ret = 1; + +end: + return ret; +} + +int BN_print_fp(FILE *fp, const BIGNUM *a) { + BIO *b; + int ret; + + b = BIO_new(BIO_s_file()); + if (b == NULL) { + return 0; + } + BIO_set_fp(b, fp, BIO_NOCLOSE); + ret = BN_print(b, a); + BIO_free(b); + + return ret; +} + + +size_t BN_bn2mpi(const BIGNUM *in, uint8_t *out) { + const size_t bits = BN_num_bits(in); + const size_t bytes = (bits + 7) / 8; + // If the number of bits is a multiple of 8, i.e. if the MSB is set, + // prefix with a zero byte. + int extend = 0; + if (bytes != 0 && (bits & 0x07) == 0) { + extend = 1; + } + + const size_t len = bytes + extend; + if (len < bytes || + 4 + len < len || + (len & 0xffffffff) != len) { + // If we cannot represent the number then we emit zero as the interface + // doesn't allow an error to be signalled. + if (out) { + OPENSSL_memset(out, 0, 4); + } + return 4; + } + + if (out == NULL) { + return 4 + len; + } + + out[0] = len >> 24; + out[1] = len >> 16; + out[2] = len >> 8; + out[3] = len; + if (extend) { + out[4] = 0; + } + BN_bn2bin(in, out + 4 + extend); + if (in->neg && len > 0) { + out[4] |= 0x80; + } + return len + 4; +} + +BIGNUM *BN_mpi2bn(const uint8_t *in, size_t len, BIGNUM *out) { + if (len < 4) { + OPENSSL_PUT_ERROR(BN, BN_R_BAD_ENCODING); + return NULL; + } + const size_t in_len = ((size_t)in[0] << 24) | + ((size_t)in[1] << 16) | + ((size_t)in[2] << 8) | + ((size_t)in[3]); + if (in_len != len - 4) { + OPENSSL_PUT_ERROR(BN, BN_R_BAD_ENCODING); + return NULL; + } + + int out_is_alloced = 0; + if (out == NULL) { + out = BN_new(); + if (out == NULL) { + OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE); + return NULL; + } + out_is_alloced = 1; + } + + if (in_len == 0) { + BN_zero(out); + return out; + } + + in += 4; + if (BN_bin2bn(in, in_len, out) == NULL) { + if (out_is_alloced) { + BN_free(out); + } + return NULL; + } + out->neg = ((*in) & 0x80) != 0; + if (out->neg) { + BN_clear_bit(out, BN_num_bits(out) - 1); + } + return out; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/buf/buf.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/buf/buf.c new file mode 100644 index 0000000..52d39df --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/buf/buf.c @@ -0,0 +1,231 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 "../internal.h" + + +BUF_MEM *BUF_MEM_new(void) { + BUF_MEM *ret; + + ret = OPENSSL_malloc(sizeof(BUF_MEM)); + if (ret == NULL) { + OPENSSL_PUT_ERROR(BUF, ERR_R_MALLOC_FAILURE); + return NULL; + } + + OPENSSL_memset(ret, 0, sizeof(BUF_MEM)); + return ret; +} + +void BUF_MEM_free(BUF_MEM *buf) { + if (buf == NULL) { + return; + } + + OPENSSL_free(buf->data); + OPENSSL_free(buf); +} + +int BUF_MEM_reserve(BUF_MEM *buf, size_t cap) { + if (buf->max >= cap) { + return 1; + } + + size_t n = cap + 3; + if (n < cap) { + // overflow + OPENSSL_PUT_ERROR(BUF, ERR_R_MALLOC_FAILURE); + return 0; + } + n = n / 3; + size_t alloc_size = n * 4; + if (alloc_size / 4 != n) { + // overflow + OPENSSL_PUT_ERROR(BUF, ERR_R_MALLOC_FAILURE); + return 0; + } + + char *new_buf = OPENSSL_realloc(buf->data, alloc_size); + if (new_buf == NULL) { + OPENSSL_PUT_ERROR(BUF, ERR_R_MALLOC_FAILURE); + return 0; + } + + buf->data = new_buf; + buf->max = alloc_size; + return 1; +} + +size_t BUF_MEM_grow(BUF_MEM *buf, size_t len) { + if (!BUF_MEM_reserve(buf, len)) { + return 0; + } + if (buf->length < len) { + OPENSSL_memset(&buf->data[buf->length], 0, len - buf->length); + } + buf->length = len; + return len; +} + +size_t BUF_MEM_grow_clean(BUF_MEM *buf, size_t len) { + return BUF_MEM_grow(buf, len); +} + +int BUF_MEM_append(BUF_MEM *buf, const void *in, size_t len) { + size_t new_len = buf->length + len; + if (new_len < len) { + OPENSSL_PUT_ERROR(BUF, ERR_R_OVERFLOW); + return 0; + } + if (!BUF_MEM_reserve(buf, new_len)) { + return 0; + } + OPENSSL_memcpy(buf->data + buf->length, in, len); + buf->length = new_len; + return 1; +} + +char *BUF_strdup(const char *str) { + if (str == NULL) { + return NULL; + } + + return BUF_strndup(str, strlen(str)); +} + +size_t BUF_strnlen(const char *str, size_t max_len) { + size_t i; + + for (i = 0; i < max_len; i++) { + if (str[i] == 0) { + break; + } + } + + return i; +} + +char *BUF_strndup(const char *str, size_t size) { + char *ret; + size_t alloc_size; + + if (str == NULL) { + return NULL; + } + + size = BUF_strnlen(str, size); + + alloc_size = size + 1; + if (alloc_size < size) { + // overflow + OPENSSL_PUT_ERROR(BUF, ERR_R_MALLOC_FAILURE); + return NULL; + } + ret = OPENSSL_malloc(alloc_size); + if (ret == NULL) { + OPENSSL_PUT_ERROR(BUF, ERR_R_MALLOC_FAILURE); + return NULL; + } + + OPENSSL_memcpy(ret, str, size); + ret[size] = '\0'; + return ret; +} + +size_t BUF_strlcpy(char *dst, const char *src, size_t dst_size) { + size_t l = 0; + + for (; dst_size > 1 && *src; dst_size--) { + *dst++ = *src++; + l++; + } + + if (dst_size) { + *dst = 0; + } + + return l + strlen(src); +} + +size_t BUF_strlcat(char *dst, const char *src, size_t dst_size) { + size_t l = 0; + for (; dst_size > 0 && *dst; dst_size--, dst++) { + l++; + } + return l + BUF_strlcpy(dst, src, dst_size); +} + +void *BUF_memdup(const void *data, size_t size) { + if (size == 0) { + return NULL; + } + + void *ret = OPENSSL_malloc(size); + if (ret == NULL) { + OPENSSL_PUT_ERROR(BUF, ERR_R_MALLOC_FAILURE); + return NULL; + } + + OPENSSL_memcpy(ret, data, size); + return ret; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/buf/buf.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/buf/buf.c.grpc_back new file mode 100644 index 0000000..146b1e0 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/buf/buf.c.grpc_back @@ -0,0 +1,231 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 "../internal.h" + + +BUF_MEM *BUF_MEM_new(void) { + BUF_MEM *ret; + + ret = OPENSSL_malloc(sizeof(BUF_MEM)); + if (ret == NULL) { + OPENSSL_PUT_ERROR(BUF, ERR_R_MALLOC_FAILURE); + return NULL; + } + + OPENSSL_memset(ret, 0, sizeof(BUF_MEM)); + return ret; +} + +void BUF_MEM_free(BUF_MEM *buf) { + if (buf == NULL) { + return; + } + + OPENSSL_free(buf->data); + OPENSSL_free(buf); +} + +int BUF_MEM_reserve(BUF_MEM *buf, size_t cap) { + if (buf->max >= cap) { + return 1; + } + + size_t n = cap + 3; + if (n < cap) { + // overflow + OPENSSL_PUT_ERROR(BUF, ERR_R_MALLOC_FAILURE); + return 0; + } + n = n / 3; + size_t alloc_size = n * 4; + if (alloc_size / 4 != n) { + // overflow + OPENSSL_PUT_ERROR(BUF, ERR_R_MALLOC_FAILURE); + return 0; + } + + char *new_buf = OPENSSL_realloc(buf->data, alloc_size); + if (new_buf == NULL) { + OPENSSL_PUT_ERROR(BUF, ERR_R_MALLOC_FAILURE); + return 0; + } + + buf->data = new_buf; + buf->max = alloc_size; + return 1; +} + +size_t BUF_MEM_grow(BUF_MEM *buf, size_t len) { + if (!BUF_MEM_reserve(buf, len)) { + return 0; + } + if (buf->length < len) { + OPENSSL_memset(&buf->data[buf->length], 0, len - buf->length); + } + buf->length = len; + return len; +} + +size_t BUF_MEM_grow_clean(BUF_MEM *buf, size_t len) { + return BUF_MEM_grow(buf, len); +} + +int BUF_MEM_append(BUF_MEM *buf, const void *in, size_t len) { + size_t new_len = buf->length + len; + if (new_len < len) { + OPENSSL_PUT_ERROR(BUF, ERR_R_OVERFLOW); + return 0; + } + if (!BUF_MEM_reserve(buf, new_len)) { + return 0; + } + OPENSSL_memcpy(buf->data + buf->length, in, len); + buf->length = new_len; + return 1; +} + +char *BUF_strdup(const char *str) { + if (str == NULL) { + return NULL; + } + + return BUF_strndup(str, strlen(str)); +} + +size_t BUF_strnlen(const char *str, size_t max_len) { + size_t i; + + for (i = 0; i < max_len; i++) { + if (str[i] == 0) { + break; + } + } + + return i; +} + +char *BUF_strndup(const char *str, size_t size) { + char *ret; + size_t alloc_size; + + if (str == NULL) { + return NULL; + } + + size = BUF_strnlen(str, size); + + alloc_size = size + 1; + if (alloc_size < size) { + // overflow + OPENSSL_PUT_ERROR(BUF, ERR_R_MALLOC_FAILURE); + return NULL; + } + ret = OPENSSL_malloc(alloc_size); + if (ret == NULL) { + OPENSSL_PUT_ERROR(BUF, ERR_R_MALLOC_FAILURE); + return NULL; + } + + OPENSSL_memcpy(ret, str, size); + ret[size] = '\0'; + return ret; +} + +size_t BUF_strlcpy(char *dst, const char *src, size_t dst_size) { + size_t l = 0; + + for (; dst_size > 1 && *src; dst_size--) { + *dst++ = *src++; + l++; + } + + if (dst_size) { + *dst = 0; + } + + return l + strlen(src); +} + +size_t BUF_strlcat(char *dst, const char *src, size_t dst_size) { + size_t l = 0; + for (; dst_size > 0 && *dst; dst_size--, dst++) { + l++; + } + return l + BUF_strlcpy(dst, src, dst_size); +} + +void *BUF_memdup(const void *data, size_t size) { + if (size == 0) { + return NULL; + } + + void *ret = OPENSSL_malloc(size); + if (ret == NULL) { + OPENSSL_PUT_ERROR(BUF, ERR_R_MALLOC_FAILURE); + return NULL; + } + + OPENSSL_memcpy(ret, data, size); + return ret; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/bytestring/asn1_compat.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/bytestring/asn1_compat.c new file mode 100644 index 0000000..43696a7 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/bytestring/asn1_compat.c @@ -0,0 +1,52 @@ +/* Copyright (c) 2016, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + + +#include + +#include +#include +#include + +#include + +#include "internal.h" +#include "../internal.h" + + +int CBB_finish_i2d(CBB *cbb, uint8_t **outp) { + assert(cbb->base->can_resize); + + uint8_t *der; + size_t der_len; + if (!CBB_finish(cbb, &der, &der_len)) { + CBB_cleanup(cbb); + return -1; + } + if (der_len > INT_MAX) { + OPENSSL_free(der); + return -1; + } + if (outp != NULL) { + if (*outp == NULL) { + *outp = der; + der = NULL; + } else { + OPENSSL_memcpy(*outp, der, der_len); + *outp += der_len; + } + } + OPENSSL_free(der); + return (int)der_len; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/bytestring/asn1_compat.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/bytestring/asn1_compat.c.grpc_back new file mode 100644 index 0000000..50df9cc --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/bytestring/asn1_compat.c.grpc_back @@ -0,0 +1,52 @@ +/* Copyright (c) 2016, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + + +#include + +#include +#include +#include + +#include + +#include "internal.h" +#include "../internal.h" + + +int CBB_finish_i2d(CBB *cbb, uint8_t **outp) { + assert(cbb->base->can_resize); + + uint8_t *der; + size_t der_len; + if (!CBB_finish(cbb, &der, &der_len)) { + CBB_cleanup(cbb); + return -1; + } + if (der_len > INT_MAX) { + OPENSSL_free(der); + return -1; + } + if (outp != NULL) { + if (*outp == NULL) { + *outp = der; + der = NULL; + } else { + OPENSSL_memcpy(*outp, der, der_len); + *outp += der_len; + } + } + OPENSSL_free(der); + return (int)der_len; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/bytestring/ber.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/bytestring/ber.c new file mode 100644 index 0000000..47c2598 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/bytestring/ber.c @@ -0,0 +1,261 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include +#include + +#include "internal.h" +#include "../internal.h" + + +// kMaxDepth is a just a sanity limit. The code should be such that the length +// of the input being processes always decreases. None the less, a very large +// input could otherwise cause the stack to overflow. +static const unsigned kMaxDepth = 2048; + +// is_string_type returns one if |tag| is a string type and zero otherwise. It +// ignores the constructed bit. +static int is_string_type(unsigned tag) { + switch (tag & ~CBS_ASN1_CONSTRUCTED) { + case CBS_ASN1_BITSTRING: + case CBS_ASN1_OCTETSTRING: + case CBS_ASN1_UTF8STRING: + case CBS_ASN1_NUMERICSTRING: + case CBS_ASN1_PRINTABLESTRING: + case CBS_ASN1_T61STRING: + case CBS_ASN1_VIDEOTEXSTRING: + case CBS_ASN1_IA5STRING: + case CBS_ASN1_GRAPHICSTRING: + case CBS_ASN1_VISIBLESTRING: + case CBS_ASN1_GENERALSTRING: + case CBS_ASN1_UNIVERSALSTRING: + case CBS_ASN1_BMPSTRING: + return 1; + default: + return 0; + } +} + +// cbs_find_ber walks an ASN.1 structure in |orig_in| and sets |*ber_found| +// depending on whether an indefinite length element or constructed string was +// found. The value of |orig_in| is not changed. It returns one on success (i.e. +// |*ber_found| was set) and zero on error. +static int cbs_find_ber(const CBS *orig_in, char *ber_found, unsigned depth) { + CBS in; + + if (depth > kMaxDepth) { + return 0; + } + + CBS_init(&in, CBS_data(orig_in), CBS_len(orig_in)); + *ber_found = 0; + + while (CBS_len(&in) > 0) { + CBS contents; + unsigned tag; + size_t header_len; + + if (!CBS_get_any_ber_asn1_element(&in, &contents, &tag, &header_len)) { + return 0; + } + if (CBS_len(&contents) == header_len && + header_len > 0 && + CBS_data(&contents)[header_len-1] == 0x80) { + // Found an indefinite-length element. + *ber_found = 1; + return 1; + } + if (tag & CBS_ASN1_CONSTRUCTED) { + if (is_string_type(tag)) { + // Constructed strings are only legal in BER and require conversion. + *ber_found = 1; + return 1; + } + if (!CBS_skip(&contents, header_len) || + !cbs_find_ber(&contents, ber_found, depth + 1)) { + return 0; + } + } + } + + return 1; +} + +// is_eoc returns true if |header_len| and |contents|, as returned by +// |CBS_get_any_ber_asn1_element|, indicate an "end of contents" (EOC) value. +static char is_eoc(size_t header_len, CBS *contents) { + return header_len == 2 && CBS_len(contents) == 2 && + OPENSSL_memcmp(CBS_data(contents), "\x00\x00", 2) == 0; +} + +// cbs_convert_ber reads BER data from |in| and writes DER data to |out|. If +// |string_tag| is non-zero, then all elements must match |string_tag| up to the +// constructed bit and primitive element bodies are written to |out| without +// element headers. This is used when concatenating the fragments of a +// constructed string. If |looking_for_eoc| is set then any EOC elements found +// will cause the function to return after consuming it. It returns one on +// success and zero on error. +static int cbs_convert_ber(CBS *in, CBB *out, unsigned string_tag, + char looking_for_eoc, unsigned depth) { + assert(!(string_tag & CBS_ASN1_CONSTRUCTED)); + + if (depth > kMaxDepth) { + return 0; + } + + while (CBS_len(in) > 0) { + CBS contents; + unsigned tag, child_string_tag = string_tag; + size_t header_len; + CBB *out_contents, out_contents_storage; + + if (!CBS_get_any_ber_asn1_element(in, &contents, &tag, &header_len)) { + return 0; + } + + if (is_eoc(header_len, &contents)) { + return looking_for_eoc; + } + + if (string_tag != 0) { + // This is part of a constructed string. All elements must match + // |string_tag| up to the constructed bit and get appended to |out| + // without a child element. + if ((tag & ~CBS_ASN1_CONSTRUCTED) != string_tag) { + return 0; + } + out_contents = out; + } else { + unsigned out_tag = tag; + if ((tag & CBS_ASN1_CONSTRUCTED) && is_string_type(tag)) { + // If a constructed string, clear the constructed bit and inform + // children to concatenate bodies. + out_tag &= ~CBS_ASN1_CONSTRUCTED; + child_string_tag = out_tag; + } + if (!CBB_add_asn1(out, &out_contents_storage, out_tag)) { + return 0; + } + out_contents = &out_contents_storage; + } + + if (CBS_len(&contents) == header_len && header_len > 0 && + CBS_data(&contents)[header_len - 1] == 0x80) { + // This is an indefinite length element. + if (!cbs_convert_ber(in, out_contents, child_string_tag, + 1 /* looking for eoc */, depth + 1) || + !CBB_flush(out)) { + return 0; + } + continue; + } + + if (!CBS_skip(&contents, header_len)) { + return 0; + } + + if (tag & CBS_ASN1_CONSTRUCTED) { + // Recurse into children. + if (!cbs_convert_ber(&contents, out_contents, child_string_tag, + 0 /* not looking for eoc */, depth + 1)) { + return 0; + } + } else { + // Copy primitive contents as-is. + if (!CBB_add_bytes(out_contents, CBS_data(&contents), + CBS_len(&contents))) { + return 0; + } + } + + if (!CBB_flush(out)) { + return 0; + } + } + + return looking_for_eoc == 0; +} + +int CBS_asn1_ber_to_der(CBS *in, uint8_t **out, size_t *out_len) { + CBB cbb; + + // First, do a quick walk to find any indefinite-length elements. Most of the + // time we hope that there aren't any and thus we can quickly return. + char conversion_needed; + if (!cbs_find_ber(in, &conversion_needed, 0)) { + return 0; + } + + if (!conversion_needed) { + *out = NULL; + *out_len = 0; + return 1; + } + + if (!CBB_init(&cbb, CBS_len(in)) || + !cbs_convert_ber(in, &cbb, 0, 0, 0) || + !CBB_finish(&cbb, out, out_len)) { + CBB_cleanup(&cbb); + return 0; + } + + return 1; +} + +int CBS_get_asn1_implicit_string(CBS *in, CBS *out, uint8_t **out_storage, + unsigned outer_tag, unsigned inner_tag) { + assert(!(outer_tag & CBS_ASN1_CONSTRUCTED)); + assert(!(inner_tag & CBS_ASN1_CONSTRUCTED)); + assert(is_string_type(inner_tag)); + + if (CBS_peek_asn1_tag(in, outer_tag)) { + // Normal implicitly-tagged string. + *out_storage = NULL; + return CBS_get_asn1(in, out, outer_tag); + } + + // Otherwise, try to parse an implicitly-tagged constructed string. + // |CBS_asn1_ber_to_der| is assumed to have run, so only allow one level deep + // of nesting. + CBB result; + CBS child; + if (!CBB_init(&result, CBS_len(in)) || + !CBS_get_asn1(in, &child, outer_tag | CBS_ASN1_CONSTRUCTED)) { + goto err; + } + + while (CBS_len(&child) > 0) { + CBS chunk; + if (!CBS_get_asn1(&child, &chunk, inner_tag) || + !CBB_add_bytes(&result, CBS_data(&chunk), CBS_len(&chunk))) { + goto err; + } + } + + uint8_t *data; + size_t len; + if (!CBB_finish(&result, &data, &len)) { + goto err; + } + + CBS_init(out, data, len); + *out_storage = data; + return 1; + +err: + CBB_cleanup(&result); + return 0; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/bytestring/ber.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/bytestring/ber.c.grpc_back new file mode 100644 index 0000000..bb5e17c --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/bytestring/ber.c.grpc_back @@ -0,0 +1,261 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include +#include + +#include "internal.h" +#include "../internal.h" + + +// kMaxDepth is a just a sanity limit. The code should be such that the length +// of the input being processes always decreases. None the less, a very large +// input could otherwise cause the stack to overflow. +static const unsigned kMaxDepth = 2048; + +// is_string_type returns one if |tag| is a string type and zero otherwise. It +// ignores the constructed bit. +static int is_string_type(unsigned tag) { + switch (tag & ~CBS_ASN1_CONSTRUCTED) { + case CBS_ASN1_BITSTRING: + case CBS_ASN1_OCTETSTRING: + case CBS_ASN1_UTF8STRING: + case CBS_ASN1_NUMERICSTRING: + case CBS_ASN1_PRINTABLESTRING: + case CBS_ASN1_T61STRING: + case CBS_ASN1_VIDEOTEXSTRING: + case CBS_ASN1_IA5STRING: + case CBS_ASN1_GRAPHICSTRING: + case CBS_ASN1_VISIBLESTRING: + case CBS_ASN1_GENERALSTRING: + case CBS_ASN1_UNIVERSALSTRING: + case CBS_ASN1_BMPSTRING: + return 1; + default: + return 0; + } +} + +// cbs_find_ber walks an ASN.1 structure in |orig_in| and sets |*ber_found| +// depending on whether an indefinite length element or constructed string was +// found. The value of |orig_in| is not changed. It returns one on success (i.e. +// |*ber_found| was set) and zero on error. +static int cbs_find_ber(const CBS *orig_in, char *ber_found, unsigned depth) { + CBS in; + + if (depth > kMaxDepth) { + return 0; + } + + CBS_init(&in, CBS_data(orig_in), CBS_len(orig_in)); + *ber_found = 0; + + while (CBS_len(&in) > 0) { + CBS contents; + unsigned tag; + size_t header_len; + + if (!CBS_get_any_ber_asn1_element(&in, &contents, &tag, &header_len)) { + return 0; + } + if (CBS_len(&contents) == header_len && + header_len > 0 && + CBS_data(&contents)[header_len-1] == 0x80) { + // Found an indefinite-length element. + *ber_found = 1; + return 1; + } + if (tag & CBS_ASN1_CONSTRUCTED) { + if (is_string_type(tag)) { + // Constructed strings are only legal in BER and require conversion. + *ber_found = 1; + return 1; + } + if (!CBS_skip(&contents, header_len) || + !cbs_find_ber(&contents, ber_found, depth + 1)) { + return 0; + } + } + } + + return 1; +} + +// is_eoc returns true if |header_len| and |contents|, as returned by +// |CBS_get_any_ber_asn1_element|, indicate an "end of contents" (EOC) value. +static char is_eoc(size_t header_len, CBS *contents) { + return header_len == 2 && CBS_len(contents) == 2 && + OPENSSL_memcmp(CBS_data(contents), "\x00\x00", 2) == 0; +} + +// cbs_convert_ber reads BER data from |in| and writes DER data to |out|. If +// |string_tag| is non-zero, then all elements must match |string_tag| up to the +// constructed bit and primitive element bodies are written to |out| without +// element headers. This is used when concatenating the fragments of a +// constructed string. If |looking_for_eoc| is set then any EOC elements found +// will cause the function to return after consuming it. It returns one on +// success and zero on error. +static int cbs_convert_ber(CBS *in, CBB *out, unsigned string_tag, + char looking_for_eoc, unsigned depth) { + assert(!(string_tag & CBS_ASN1_CONSTRUCTED)); + + if (depth > kMaxDepth) { + return 0; + } + + while (CBS_len(in) > 0) { + CBS contents; + unsigned tag, child_string_tag = string_tag; + size_t header_len; + CBB *out_contents, out_contents_storage; + + if (!CBS_get_any_ber_asn1_element(in, &contents, &tag, &header_len)) { + return 0; + } + + if (is_eoc(header_len, &contents)) { + return looking_for_eoc; + } + + if (string_tag != 0) { + // This is part of a constructed string. All elements must match + // |string_tag| up to the constructed bit and get appended to |out| + // without a child element. + if ((tag & ~CBS_ASN1_CONSTRUCTED) != string_tag) { + return 0; + } + out_contents = out; + } else { + unsigned out_tag = tag; + if ((tag & CBS_ASN1_CONSTRUCTED) && is_string_type(tag)) { + // If a constructed string, clear the constructed bit and inform + // children to concatenate bodies. + out_tag &= ~CBS_ASN1_CONSTRUCTED; + child_string_tag = out_tag; + } + if (!CBB_add_asn1(out, &out_contents_storage, out_tag)) { + return 0; + } + out_contents = &out_contents_storage; + } + + if (CBS_len(&contents) == header_len && header_len > 0 && + CBS_data(&contents)[header_len - 1] == 0x80) { + // This is an indefinite length element. + if (!cbs_convert_ber(in, out_contents, child_string_tag, + 1 /* looking for eoc */, depth + 1) || + !CBB_flush(out)) { + return 0; + } + continue; + } + + if (!CBS_skip(&contents, header_len)) { + return 0; + } + + if (tag & CBS_ASN1_CONSTRUCTED) { + // Recurse into children. + if (!cbs_convert_ber(&contents, out_contents, child_string_tag, + 0 /* not looking for eoc */, depth + 1)) { + return 0; + } + } else { + // Copy primitive contents as-is. + if (!CBB_add_bytes(out_contents, CBS_data(&contents), + CBS_len(&contents))) { + return 0; + } + } + + if (!CBB_flush(out)) { + return 0; + } + } + + return looking_for_eoc == 0; +} + +int CBS_asn1_ber_to_der(CBS *in, uint8_t **out, size_t *out_len) { + CBB cbb; + + // First, do a quick walk to find any indefinite-length elements. Most of the + // time we hope that there aren't any and thus we can quickly return. + char conversion_needed; + if (!cbs_find_ber(in, &conversion_needed, 0)) { + return 0; + } + + if (!conversion_needed) { + *out = NULL; + *out_len = 0; + return 1; + } + + if (!CBB_init(&cbb, CBS_len(in)) || + !cbs_convert_ber(in, &cbb, 0, 0, 0) || + !CBB_finish(&cbb, out, out_len)) { + CBB_cleanup(&cbb); + return 0; + } + + return 1; +} + +int CBS_get_asn1_implicit_string(CBS *in, CBS *out, uint8_t **out_storage, + unsigned outer_tag, unsigned inner_tag) { + assert(!(outer_tag & CBS_ASN1_CONSTRUCTED)); + assert(!(inner_tag & CBS_ASN1_CONSTRUCTED)); + assert(is_string_type(inner_tag)); + + if (CBS_peek_asn1_tag(in, outer_tag)) { + // Normal implicitly-tagged string. + *out_storage = NULL; + return CBS_get_asn1(in, out, outer_tag); + } + + // Otherwise, try to parse an implicitly-tagged constructed string. + // |CBS_asn1_ber_to_der| is assumed to have run, so only allow one level deep + // of nesting. + CBB result; + CBS child; + if (!CBB_init(&result, CBS_len(in)) || + !CBS_get_asn1(in, &child, outer_tag | CBS_ASN1_CONSTRUCTED)) { + goto err; + } + + while (CBS_len(&child) > 0) { + CBS chunk; + if (!CBS_get_asn1(&child, &chunk, inner_tag) || + !CBB_add_bytes(&result, CBS_data(&chunk), CBS_len(&chunk))) { + goto err; + } + } + + uint8_t *data; + size_t len; + if (!CBB_finish(&result, &data, &len)) { + goto err; + } + + CBS_init(out, data, len); + *out_storage = data; + return 1; + +err: + CBB_cleanup(&result); + return 0; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/bytestring/cbb.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/bytestring/cbb.c new file mode 100644 index 0000000..f8c4899 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/bytestring/cbb.c @@ -0,0 +1,668 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include +#include +#include + +#include +#include + +#include "../internal.h" + + +void CBB_zero(CBB *cbb) { + OPENSSL_memset(cbb, 0, sizeof(CBB)); +} + +static int cbb_init(CBB *cbb, uint8_t *buf, size_t cap) { + // This assumes that |cbb| has already been zeroed. + struct cbb_buffer_st *base; + + base = OPENSSL_malloc(sizeof(struct cbb_buffer_st)); + if (base == NULL) { + return 0; + } + + base->buf = buf; + base->len = 0; + base->cap = cap; + base->can_resize = 1; + base->error = 0; + + cbb->base = base; + cbb->is_top_level = 1; + return 1; +} + +int CBB_init(CBB *cbb, size_t initial_capacity) { + CBB_zero(cbb); + + uint8_t *buf = OPENSSL_malloc(initial_capacity); + if (initial_capacity > 0 && buf == NULL) { + return 0; + } + + if (!cbb_init(cbb, buf, initial_capacity)) { + OPENSSL_free(buf); + return 0; + } + + return 1; +} + +int CBB_init_fixed(CBB *cbb, uint8_t *buf, size_t len) { + CBB_zero(cbb); + + if (!cbb_init(cbb, buf, len)) { + return 0; + } + + cbb->base->can_resize = 0; + return 1; +} + +void CBB_cleanup(CBB *cbb) { + if (cbb->base) { + // Only top-level |CBB|s are cleaned up. Child |CBB|s are non-owning. They + // are implicitly discarded when the parent is flushed or cleaned up. + assert(cbb->is_top_level); + + if (cbb->base->can_resize) { + OPENSSL_free(cbb->base->buf); + } + OPENSSL_free(cbb->base); + } + cbb->base = NULL; +} + +static int cbb_buffer_reserve(struct cbb_buffer_st *base, uint8_t **out, + size_t len) { + size_t newlen; + + if (base == NULL) { + return 0; + } + + newlen = base->len + len; + if (newlen < base->len) { + // Overflow + goto err; + } + + if (newlen > base->cap) { + size_t newcap = base->cap * 2; + uint8_t *newbuf; + + if (!base->can_resize) { + goto err; + } + + if (newcap < base->cap || newcap < newlen) { + newcap = newlen; + } + newbuf = OPENSSL_realloc(base->buf, newcap); + if (newbuf == NULL) { + goto err; + } + + base->buf = newbuf; + base->cap = newcap; + } + + if (out) { + *out = base->buf + base->len; + } + + return 1; + +err: + base->error = 1; + return 0; +} + +static int cbb_buffer_add(struct cbb_buffer_st *base, uint8_t **out, + size_t len) { + if (!cbb_buffer_reserve(base, out, len)) { + return 0; + } + // This will not overflow or |cbb_buffer_reserve| would have failed. + base->len += len; + return 1; +} + +static int cbb_buffer_add_u(struct cbb_buffer_st *base, uint32_t v, + size_t len_len) { + if (len_len == 0) { + return 1; + } + + uint8_t *buf; + if (!cbb_buffer_add(base, &buf, len_len)) { + return 0; + } + + for (size_t i = len_len - 1; i < len_len; i--) { + buf[i] = v; + v >>= 8; + } + + if (v != 0) { + base->error = 1; + return 0; + } + + return 1; +} + +int CBB_finish(CBB *cbb, uint8_t **out_data, size_t *out_len) { + if (!cbb->is_top_level) { + return 0; + } + + if (!CBB_flush(cbb)) { + return 0; + } + + if (cbb->base->can_resize && (out_data == NULL || out_len == NULL)) { + // |out_data| and |out_len| can only be NULL if the CBB is fixed. + return 0; + } + + if (out_data != NULL) { + *out_data = cbb->base->buf; + } + if (out_len != NULL) { + *out_len = cbb->base->len; + } + cbb->base->buf = NULL; + CBB_cleanup(cbb); + return 1; +} + +// CBB_flush recurses and then writes out any pending length prefix. The +// current length of the underlying base is taken to be the length of the +// length-prefixed data. +int CBB_flush(CBB *cbb) { + size_t child_start, i, len; + + // If |cbb->base| has hit an error, the buffer is in an undefined state, so + // fail all following calls. In particular, |cbb->child| may point to invalid + // memory. + if (cbb->base == NULL || cbb->base->error) { + return 0; + } + + if (cbb->child == NULL || cbb->child->pending_len_len == 0) { + return 1; + } + + child_start = cbb->child->offset + cbb->child->pending_len_len; + + if (!CBB_flush(cbb->child) || + child_start < cbb->child->offset || + cbb->base->len < child_start) { + goto err; + } + + len = cbb->base->len - child_start; + + if (cbb->child->pending_is_asn1) { + // For ASN.1 we assume that we'll only need a single byte for the length. + // If that turned out to be incorrect, we have to move the contents along + // in order to make space. + uint8_t len_len; + uint8_t initial_length_byte; + + assert (cbb->child->pending_len_len == 1); + + if (len > 0xfffffffe) { + // Too large. + goto err; + } else if (len > 0xffffff) { + len_len = 5; + initial_length_byte = 0x80 | 4; + } else if (len > 0xffff) { + len_len = 4; + initial_length_byte = 0x80 | 3; + } else if (len > 0xff) { + len_len = 3; + initial_length_byte = 0x80 | 2; + } else if (len > 0x7f) { + len_len = 2; + initial_length_byte = 0x80 | 1; + } else { + len_len = 1; + initial_length_byte = (uint8_t)len; + len = 0; + } + + if (len_len != 1) { + // We need to move the contents along in order to make space. + size_t extra_bytes = len_len - 1; + if (!cbb_buffer_add(cbb->base, NULL, extra_bytes)) { + goto err; + } + OPENSSL_memmove(cbb->base->buf + child_start + extra_bytes, + cbb->base->buf + child_start, len); + } + cbb->base->buf[cbb->child->offset++] = initial_length_byte; + cbb->child->pending_len_len = len_len - 1; + } + + for (i = cbb->child->pending_len_len - 1; i < cbb->child->pending_len_len; + i--) { + cbb->base->buf[cbb->child->offset + i] = (uint8_t)len; + len >>= 8; + } + if (len != 0) { + goto err; + } + + cbb->child->base = NULL; + cbb->child = NULL; + + return 1; + +err: + cbb->base->error = 1; + return 0; +} + +const uint8_t *CBB_data(const CBB *cbb) { + assert(cbb->child == NULL); + return cbb->base->buf + cbb->offset + cbb->pending_len_len; +} + +size_t CBB_len(const CBB *cbb) { + assert(cbb->child == NULL); + assert(cbb->offset + cbb->pending_len_len <= cbb->base->len); + + return cbb->base->len - cbb->offset - cbb->pending_len_len; +} + +static int cbb_add_length_prefixed(CBB *cbb, CBB *out_contents, + uint8_t len_len) { + uint8_t *prefix_bytes; + + if (!CBB_flush(cbb)) { + return 0; + } + + size_t offset = cbb->base->len; + if (!cbb_buffer_add(cbb->base, &prefix_bytes, len_len)) { + return 0; + } + + OPENSSL_memset(prefix_bytes, 0, len_len); + OPENSSL_memset(out_contents, 0, sizeof(CBB)); + out_contents->base = cbb->base; + cbb->child = out_contents; + cbb->child->offset = offset; + cbb->child->pending_len_len = len_len; + cbb->child->pending_is_asn1 = 0; + + return 1; +} + +int CBB_add_u8_length_prefixed(CBB *cbb, CBB *out_contents) { + return cbb_add_length_prefixed(cbb, out_contents, 1); +} + +int CBB_add_u16_length_prefixed(CBB *cbb, CBB *out_contents) { + return cbb_add_length_prefixed(cbb, out_contents, 2); +} + +int CBB_add_u24_length_prefixed(CBB *cbb, CBB *out_contents) { + return cbb_add_length_prefixed(cbb, out_contents, 3); +} + +// add_base128_integer encodes |v| as a big-endian base-128 integer where the +// high bit of each byte indicates where there is more data. This is the +// encoding used in DER for both high tag number form and OID components. +static int add_base128_integer(CBB *cbb, uint64_t v) { + unsigned len_len = 0; + uint64_t copy = v; + while (copy > 0) { + len_len++; + copy >>= 7; + } + if (len_len == 0) { + len_len = 1; // Zero is encoded with one byte. + } + for (unsigned i = len_len - 1; i < len_len; i--) { + uint8_t byte = (v >> (7 * i)) & 0x7f; + if (i != 0) { + // The high bit denotes whether there is more data. + byte |= 0x80; + } + if (!CBB_add_u8(cbb, byte)) { + return 0; + } + } + return 1; +} + +int CBB_add_asn1(CBB *cbb, CBB *out_contents, unsigned tag) { + if (!CBB_flush(cbb)) { + return 0; + } + + // Split the tag into leading bits and tag number. + uint8_t tag_bits = (tag >> CBS_ASN1_TAG_SHIFT) & 0xe0; + unsigned tag_number = tag & CBS_ASN1_TAG_NUMBER_MASK; + if (tag_number >= 0x1f) { + // Set all the bits in the tag number to signal high tag number form. + if (!CBB_add_u8(cbb, tag_bits | 0x1f) || + !add_base128_integer(cbb, tag_number)) { + return 0; + } + } else if (!CBB_add_u8(cbb, tag_bits | tag_number)) { + return 0; + } + + size_t offset = cbb->base->len; + if (!CBB_add_u8(cbb, 0)) { + return 0; + } + + OPENSSL_memset(out_contents, 0, sizeof(CBB)); + out_contents->base = cbb->base; + cbb->child = out_contents; + cbb->child->offset = offset; + cbb->child->pending_len_len = 1; + cbb->child->pending_is_asn1 = 1; + + return 1; +} + +int CBB_add_bytes(CBB *cbb, const uint8_t *data, size_t len) { + uint8_t *dest; + + if (!CBB_flush(cbb) || + !cbb_buffer_add(cbb->base, &dest, len)) { + return 0; + } + OPENSSL_memcpy(dest, data, len); + return 1; +} + +int CBB_add_space(CBB *cbb, uint8_t **out_data, size_t len) { + if (!CBB_flush(cbb) || + !cbb_buffer_add(cbb->base, out_data, len)) { + return 0; + } + return 1; +} + +int CBB_reserve(CBB *cbb, uint8_t **out_data, size_t len) { + if (!CBB_flush(cbb) || + !cbb_buffer_reserve(cbb->base, out_data, len)) { + return 0; + } + return 1; +} + +int CBB_did_write(CBB *cbb, size_t len) { + size_t newlen = cbb->base->len + len; + if (cbb->child != NULL || + newlen < cbb->base->len || + newlen > cbb->base->cap) { + return 0; + } + cbb->base->len = newlen; + return 1; +} + +int CBB_add_u8(CBB *cbb, uint8_t value) { + if (!CBB_flush(cbb)) { + return 0; + } + + return cbb_buffer_add_u(cbb->base, value, 1); +} + +int CBB_add_u16(CBB *cbb, uint16_t value) { + if (!CBB_flush(cbb)) { + return 0; + } + + return cbb_buffer_add_u(cbb->base, value, 2); +} + +int CBB_add_u24(CBB *cbb, uint32_t value) { + if (!CBB_flush(cbb)) { + return 0; + } + + return cbb_buffer_add_u(cbb->base, value, 3); +} + +int CBB_add_u32(CBB *cbb, uint32_t value) { + if (!CBB_flush(cbb)) { + return 0; + } + + return cbb_buffer_add_u(cbb->base, value, 4); +} + +void CBB_discard_child(CBB *cbb) { + if (cbb->child == NULL) { + return; + } + + cbb->base->len = cbb->child->offset; + + cbb->child->base = NULL; + cbb->child = NULL; +} + +int CBB_add_asn1_uint64(CBB *cbb, uint64_t value) { + CBB child; + int started = 0; + + if (!CBB_add_asn1(cbb, &child, CBS_ASN1_INTEGER)) { + return 0; + } + + for (size_t i = 0; i < 8; i++) { + uint8_t byte = (value >> 8*(7-i)) & 0xff; + if (!started) { + if (byte == 0) { + // Don't encode leading zeros. + continue; + } + // If the high bit is set, add a padding byte to make it + // unsigned. + if ((byte & 0x80) && !CBB_add_u8(&child, 0)) { + return 0; + } + started = 1; + } + if (!CBB_add_u8(&child, byte)) { + return 0; + } + } + + // 0 is encoded as a single 0, not the empty string. + if (!started && !CBB_add_u8(&child, 0)) { + return 0; + } + + return CBB_flush(cbb); +} + +int CBB_add_asn1_octet_string(CBB *cbb, const uint8_t *data, size_t data_len) { + CBB child; + if (!CBB_add_asn1(cbb, &child, CBS_ASN1_OCTETSTRING) || + !CBB_add_bytes(&child, data, data_len) || + !CBB_flush(cbb)) { + return 0; + } + + return 1; +} + +int CBB_add_asn1_bool(CBB *cbb, int value) { + CBB child; + if (!CBB_add_asn1(cbb, &child, CBS_ASN1_BOOLEAN) || + !CBB_add_u8(&child, value != 0 ? 0xff : 0) || + !CBB_flush(cbb)) { + return 0; + } + + return 1; +} + +// parse_dotted_decimal parses one decimal component from |cbs|, where |cbs| is +// an OID literal, e.g., "1.2.840.113554.4.1.72585". It consumes both the +// component and the dot, so |cbs| may be passed into the function again for the +// next value. +static int parse_dotted_decimal(CBS *cbs, uint64_t *out) { + *out = 0; + int seen_digit = 0; + for (;;) { + // Valid terminators for a component are the end of the string or a + // non-terminal dot. If the string ends with a dot, this is not a valid OID + // string. + uint8_t u; + if (!CBS_get_u8(cbs, &u) || + (u == '.' && CBS_len(cbs) > 0)) { + break; + } + if (u < '0' || u > '9' || + // Forbid stray leading zeros. + (seen_digit && *out == 0) || + // Check for overflow. + *out > UINT64_MAX / 10 || + *out * 10 > UINT64_MAX - (u - '0')) { + return 0; + } + *out = *out * 10 + (u - '0'); + seen_digit = 1; + } + // The empty string is not a legal OID component. + return seen_digit; +} + +int CBB_add_asn1_oid_from_text(CBB *cbb, const char *text, size_t len) { + if (!CBB_flush(cbb)) { + return 0; + } + + CBS cbs; + CBS_init(&cbs, (const uint8_t *)text, len); + + // OIDs must have at least two components. + uint64_t a, b; + if (!parse_dotted_decimal(&cbs, &a) || + !parse_dotted_decimal(&cbs, &b)) { + return 0; + } + + // The first component is encoded as 40 * |a| + |b|. This assumes that |a| is + // 0, 1, or 2 and that, when it is 0 or 1, |b| is at most 39. + if (a > 2 || + (a < 2 && b > 39) || + b > UINT64_MAX - 80 || + !add_base128_integer(cbb, 40u * a + b)) { + return 0; + } + + // The remaining components are encoded unmodified. + while (CBS_len(&cbs) > 0) { + if (!parse_dotted_decimal(&cbs, &a) || + !add_base128_integer(cbb, a)) { + return 0; + } + } + + return 1; +} + +static int compare_set_of_element(const void *a_ptr, const void *b_ptr) { + // See X.690, section 11.6 for the ordering. They are sorted in ascending + // order by their DER encoding. + const CBS *a = a_ptr, *b = b_ptr; + size_t a_len = CBS_len(a), b_len = CBS_len(b); + size_t min_len = a_len < b_len ? a_len : b_len; + int ret = OPENSSL_memcmp(CBS_data(a), CBS_data(b), min_len); + if (ret != 0) { + return ret; + } + if (a_len == b_len) { + return 0; + } + // If one is a prefix of the other, the shorter one sorts first. (This is not + // actually reachable. No DER encoding is a prefix of another DER encoding.) + return a_len < b_len ? -1 : 1; +} + +int CBB_flush_asn1_set_of(CBB *cbb) { + if (!CBB_flush(cbb)) { + return 0; + } + + CBS cbs; + size_t num_children = 0; + CBS_init(&cbs, CBB_data(cbb), CBB_len(cbb)); + while (CBS_len(&cbs) != 0) { + if (!CBS_get_any_asn1_element(&cbs, NULL, NULL, NULL)) { + return 0; + } + num_children++; + } + + if (num_children < 2) { + return 1; // Nothing to do. This is the common case for X.509. + } + if (num_children > ((size_t)-1) / sizeof(CBS)) { + return 0; // Overflow. + } + + // Parse out the children and sort. We alias them into a copy of so they + // remain valid as we rewrite |cbb|. + int ret = 0; + size_t buf_len = CBB_len(cbb); + uint8_t *buf = BUF_memdup(CBB_data(cbb), buf_len); + CBS *children = OPENSSL_malloc(num_children * sizeof(CBS)); + if (buf == NULL || children == NULL) { + goto err; + } + CBS_init(&cbs, buf, buf_len); + for (size_t i = 0; i < num_children; i++) { + if (!CBS_get_any_asn1_element(&cbs, &children[i], NULL, NULL)) { + goto err; + } + } + qsort(children, num_children, sizeof(CBS), compare_set_of_element); + + // Rewind |cbb| and write the contents back in the new order. + cbb->base->len = cbb->offset + cbb->pending_len_len; + for (size_t i = 0; i < num_children; i++) { + if (!CBB_add_bytes(cbb, CBS_data(&children[i]), CBS_len(&children[i]))) { + goto err; + } + } + assert(CBB_len(cbb) == buf_len); + + ret = 1; + +err: + OPENSSL_free(buf); + OPENSSL_free(children); + return ret; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/bytestring/cbb.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/bytestring/cbb.c.grpc_back new file mode 100644 index 0000000..38e9a83 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/bytestring/cbb.c.grpc_back @@ -0,0 +1,668 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include +#include +#include + +#include +#include + +#include "../internal.h" + + +void CBB_zero(CBB *cbb) { + OPENSSL_memset(cbb, 0, sizeof(CBB)); +} + +static int cbb_init(CBB *cbb, uint8_t *buf, size_t cap) { + // This assumes that |cbb| has already been zeroed. + struct cbb_buffer_st *base; + + base = OPENSSL_malloc(sizeof(struct cbb_buffer_st)); + if (base == NULL) { + return 0; + } + + base->buf = buf; + base->len = 0; + base->cap = cap; + base->can_resize = 1; + base->error = 0; + + cbb->base = base; + cbb->is_top_level = 1; + return 1; +} + +int CBB_init(CBB *cbb, size_t initial_capacity) { + CBB_zero(cbb); + + uint8_t *buf = OPENSSL_malloc(initial_capacity); + if (initial_capacity > 0 && buf == NULL) { + return 0; + } + + if (!cbb_init(cbb, buf, initial_capacity)) { + OPENSSL_free(buf); + return 0; + } + + return 1; +} + +int CBB_init_fixed(CBB *cbb, uint8_t *buf, size_t len) { + CBB_zero(cbb); + + if (!cbb_init(cbb, buf, len)) { + return 0; + } + + cbb->base->can_resize = 0; + return 1; +} + +void CBB_cleanup(CBB *cbb) { + if (cbb->base) { + // Only top-level |CBB|s are cleaned up. Child |CBB|s are non-owning. They + // are implicitly discarded when the parent is flushed or cleaned up. + assert(cbb->is_top_level); + + if (cbb->base->can_resize) { + OPENSSL_free(cbb->base->buf); + } + OPENSSL_free(cbb->base); + } + cbb->base = NULL; +} + +static int cbb_buffer_reserve(struct cbb_buffer_st *base, uint8_t **out, + size_t len) { + size_t newlen; + + if (base == NULL) { + return 0; + } + + newlen = base->len + len; + if (newlen < base->len) { + // Overflow + goto err; + } + + if (newlen > base->cap) { + size_t newcap = base->cap * 2; + uint8_t *newbuf; + + if (!base->can_resize) { + goto err; + } + + if (newcap < base->cap || newcap < newlen) { + newcap = newlen; + } + newbuf = OPENSSL_realloc(base->buf, newcap); + if (newbuf == NULL) { + goto err; + } + + base->buf = newbuf; + base->cap = newcap; + } + + if (out) { + *out = base->buf + base->len; + } + + return 1; + +err: + base->error = 1; + return 0; +} + +static int cbb_buffer_add(struct cbb_buffer_st *base, uint8_t **out, + size_t len) { + if (!cbb_buffer_reserve(base, out, len)) { + return 0; + } + // This will not overflow or |cbb_buffer_reserve| would have failed. + base->len += len; + return 1; +} + +static int cbb_buffer_add_u(struct cbb_buffer_st *base, uint32_t v, + size_t len_len) { + if (len_len == 0) { + return 1; + } + + uint8_t *buf; + if (!cbb_buffer_add(base, &buf, len_len)) { + return 0; + } + + for (size_t i = len_len - 1; i < len_len; i--) { + buf[i] = v; + v >>= 8; + } + + if (v != 0) { + base->error = 1; + return 0; + } + + return 1; +} + +int CBB_finish(CBB *cbb, uint8_t **out_data, size_t *out_len) { + if (!cbb->is_top_level) { + return 0; + } + + if (!CBB_flush(cbb)) { + return 0; + } + + if (cbb->base->can_resize && (out_data == NULL || out_len == NULL)) { + // |out_data| and |out_len| can only be NULL if the CBB is fixed. + return 0; + } + + if (out_data != NULL) { + *out_data = cbb->base->buf; + } + if (out_len != NULL) { + *out_len = cbb->base->len; + } + cbb->base->buf = NULL; + CBB_cleanup(cbb); + return 1; +} + +// CBB_flush recurses and then writes out any pending length prefix. The +// current length of the underlying base is taken to be the length of the +// length-prefixed data. +int CBB_flush(CBB *cbb) { + size_t child_start, i, len; + + // If |cbb->base| has hit an error, the buffer is in an undefined state, so + // fail all following calls. In particular, |cbb->child| may point to invalid + // memory. + if (cbb->base == NULL || cbb->base->error) { + return 0; + } + + if (cbb->child == NULL || cbb->child->pending_len_len == 0) { + return 1; + } + + child_start = cbb->child->offset + cbb->child->pending_len_len; + + if (!CBB_flush(cbb->child) || + child_start < cbb->child->offset || + cbb->base->len < child_start) { + goto err; + } + + len = cbb->base->len - child_start; + + if (cbb->child->pending_is_asn1) { + // For ASN.1 we assume that we'll only need a single byte for the length. + // If that turned out to be incorrect, we have to move the contents along + // in order to make space. + uint8_t len_len; + uint8_t initial_length_byte; + + assert (cbb->child->pending_len_len == 1); + + if (len > 0xfffffffe) { + // Too large. + goto err; + } else if (len > 0xffffff) { + len_len = 5; + initial_length_byte = 0x80 | 4; + } else if (len > 0xffff) { + len_len = 4; + initial_length_byte = 0x80 | 3; + } else if (len > 0xff) { + len_len = 3; + initial_length_byte = 0x80 | 2; + } else if (len > 0x7f) { + len_len = 2; + initial_length_byte = 0x80 | 1; + } else { + len_len = 1; + initial_length_byte = (uint8_t)len; + len = 0; + } + + if (len_len != 1) { + // We need to move the contents along in order to make space. + size_t extra_bytes = len_len - 1; + if (!cbb_buffer_add(cbb->base, NULL, extra_bytes)) { + goto err; + } + OPENSSL_memmove(cbb->base->buf + child_start + extra_bytes, + cbb->base->buf + child_start, len); + } + cbb->base->buf[cbb->child->offset++] = initial_length_byte; + cbb->child->pending_len_len = len_len - 1; + } + + for (i = cbb->child->pending_len_len - 1; i < cbb->child->pending_len_len; + i--) { + cbb->base->buf[cbb->child->offset + i] = (uint8_t)len; + len >>= 8; + } + if (len != 0) { + goto err; + } + + cbb->child->base = NULL; + cbb->child = NULL; + + return 1; + +err: + cbb->base->error = 1; + return 0; +} + +const uint8_t *CBB_data(const CBB *cbb) { + assert(cbb->child == NULL); + return cbb->base->buf + cbb->offset + cbb->pending_len_len; +} + +size_t CBB_len(const CBB *cbb) { + assert(cbb->child == NULL); + assert(cbb->offset + cbb->pending_len_len <= cbb->base->len); + + return cbb->base->len - cbb->offset - cbb->pending_len_len; +} + +static int cbb_add_length_prefixed(CBB *cbb, CBB *out_contents, + uint8_t len_len) { + uint8_t *prefix_bytes; + + if (!CBB_flush(cbb)) { + return 0; + } + + size_t offset = cbb->base->len; + if (!cbb_buffer_add(cbb->base, &prefix_bytes, len_len)) { + return 0; + } + + OPENSSL_memset(prefix_bytes, 0, len_len); + OPENSSL_memset(out_contents, 0, sizeof(CBB)); + out_contents->base = cbb->base; + cbb->child = out_contents; + cbb->child->offset = offset; + cbb->child->pending_len_len = len_len; + cbb->child->pending_is_asn1 = 0; + + return 1; +} + +int CBB_add_u8_length_prefixed(CBB *cbb, CBB *out_contents) { + return cbb_add_length_prefixed(cbb, out_contents, 1); +} + +int CBB_add_u16_length_prefixed(CBB *cbb, CBB *out_contents) { + return cbb_add_length_prefixed(cbb, out_contents, 2); +} + +int CBB_add_u24_length_prefixed(CBB *cbb, CBB *out_contents) { + return cbb_add_length_prefixed(cbb, out_contents, 3); +} + +// add_base128_integer encodes |v| as a big-endian base-128 integer where the +// high bit of each byte indicates where there is more data. This is the +// encoding used in DER for both high tag number form and OID components. +static int add_base128_integer(CBB *cbb, uint64_t v) { + unsigned len_len = 0; + uint64_t copy = v; + while (copy > 0) { + len_len++; + copy >>= 7; + } + if (len_len == 0) { + len_len = 1; // Zero is encoded with one byte. + } + for (unsigned i = len_len - 1; i < len_len; i--) { + uint8_t byte = (v >> (7 * i)) & 0x7f; + if (i != 0) { + // The high bit denotes whether there is more data. + byte |= 0x80; + } + if (!CBB_add_u8(cbb, byte)) { + return 0; + } + } + return 1; +} + +int CBB_add_asn1(CBB *cbb, CBB *out_contents, unsigned tag) { + if (!CBB_flush(cbb)) { + return 0; + } + + // Split the tag into leading bits and tag number. + uint8_t tag_bits = (tag >> CBS_ASN1_TAG_SHIFT) & 0xe0; + unsigned tag_number = tag & CBS_ASN1_TAG_NUMBER_MASK; + if (tag_number >= 0x1f) { + // Set all the bits in the tag number to signal high tag number form. + if (!CBB_add_u8(cbb, tag_bits | 0x1f) || + !add_base128_integer(cbb, tag_number)) { + return 0; + } + } else if (!CBB_add_u8(cbb, tag_bits | tag_number)) { + return 0; + } + + size_t offset = cbb->base->len; + if (!CBB_add_u8(cbb, 0)) { + return 0; + } + + OPENSSL_memset(out_contents, 0, sizeof(CBB)); + out_contents->base = cbb->base; + cbb->child = out_contents; + cbb->child->offset = offset; + cbb->child->pending_len_len = 1; + cbb->child->pending_is_asn1 = 1; + + return 1; +} + +int CBB_add_bytes(CBB *cbb, const uint8_t *data, size_t len) { + uint8_t *dest; + + if (!CBB_flush(cbb) || + !cbb_buffer_add(cbb->base, &dest, len)) { + return 0; + } + OPENSSL_memcpy(dest, data, len); + return 1; +} + +int CBB_add_space(CBB *cbb, uint8_t **out_data, size_t len) { + if (!CBB_flush(cbb) || + !cbb_buffer_add(cbb->base, out_data, len)) { + return 0; + } + return 1; +} + +int CBB_reserve(CBB *cbb, uint8_t **out_data, size_t len) { + if (!CBB_flush(cbb) || + !cbb_buffer_reserve(cbb->base, out_data, len)) { + return 0; + } + return 1; +} + +int CBB_did_write(CBB *cbb, size_t len) { + size_t newlen = cbb->base->len + len; + if (cbb->child != NULL || + newlen < cbb->base->len || + newlen > cbb->base->cap) { + return 0; + } + cbb->base->len = newlen; + return 1; +} + +int CBB_add_u8(CBB *cbb, uint8_t value) { + if (!CBB_flush(cbb)) { + return 0; + } + + return cbb_buffer_add_u(cbb->base, value, 1); +} + +int CBB_add_u16(CBB *cbb, uint16_t value) { + if (!CBB_flush(cbb)) { + return 0; + } + + return cbb_buffer_add_u(cbb->base, value, 2); +} + +int CBB_add_u24(CBB *cbb, uint32_t value) { + if (!CBB_flush(cbb)) { + return 0; + } + + return cbb_buffer_add_u(cbb->base, value, 3); +} + +int CBB_add_u32(CBB *cbb, uint32_t value) { + if (!CBB_flush(cbb)) { + return 0; + } + + return cbb_buffer_add_u(cbb->base, value, 4); +} + +void CBB_discard_child(CBB *cbb) { + if (cbb->child == NULL) { + return; + } + + cbb->base->len = cbb->child->offset; + + cbb->child->base = NULL; + cbb->child = NULL; +} + +int CBB_add_asn1_uint64(CBB *cbb, uint64_t value) { + CBB child; + int started = 0; + + if (!CBB_add_asn1(cbb, &child, CBS_ASN1_INTEGER)) { + return 0; + } + + for (size_t i = 0; i < 8; i++) { + uint8_t byte = (value >> 8*(7-i)) & 0xff; + if (!started) { + if (byte == 0) { + // Don't encode leading zeros. + continue; + } + // If the high bit is set, add a padding byte to make it + // unsigned. + if ((byte & 0x80) && !CBB_add_u8(&child, 0)) { + return 0; + } + started = 1; + } + if (!CBB_add_u8(&child, byte)) { + return 0; + } + } + + // 0 is encoded as a single 0, not the empty string. + if (!started && !CBB_add_u8(&child, 0)) { + return 0; + } + + return CBB_flush(cbb); +} + +int CBB_add_asn1_octet_string(CBB *cbb, const uint8_t *data, size_t data_len) { + CBB child; + if (!CBB_add_asn1(cbb, &child, CBS_ASN1_OCTETSTRING) || + !CBB_add_bytes(&child, data, data_len) || + !CBB_flush(cbb)) { + return 0; + } + + return 1; +} + +int CBB_add_asn1_bool(CBB *cbb, int value) { + CBB child; + if (!CBB_add_asn1(cbb, &child, CBS_ASN1_BOOLEAN) || + !CBB_add_u8(&child, value != 0 ? 0xff : 0) || + !CBB_flush(cbb)) { + return 0; + } + + return 1; +} + +// parse_dotted_decimal parses one decimal component from |cbs|, where |cbs| is +// an OID literal, e.g., "1.2.840.113554.4.1.72585". It consumes both the +// component and the dot, so |cbs| may be passed into the function again for the +// next value. +static int parse_dotted_decimal(CBS *cbs, uint64_t *out) { + *out = 0; + int seen_digit = 0; + for (;;) { + // Valid terminators for a component are the end of the string or a + // non-terminal dot. If the string ends with a dot, this is not a valid OID + // string. + uint8_t u; + if (!CBS_get_u8(cbs, &u) || + (u == '.' && CBS_len(cbs) > 0)) { + break; + } + if (u < '0' || u > '9' || + // Forbid stray leading zeros. + (seen_digit && *out == 0) || + // Check for overflow. + *out > UINT64_MAX / 10 || + *out * 10 > UINT64_MAX - (u - '0')) { + return 0; + } + *out = *out * 10 + (u - '0'); + seen_digit = 1; + } + // The empty string is not a legal OID component. + return seen_digit; +} + +int CBB_add_asn1_oid_from_text(CBB *cbb, const char *text, size_t len) { + if (!CBB_flush(cbb)) { + return 0; + } + + CBS cbs; + CBS_init(&cbs, (const uint8_t *)text, len); + + // OIDs must have at least two components. + uint64_t a, b; + if (!parse_dotted_decimal(&cbs, &a) || + !parse_dotted_decimal(&cbs, &b)) { + return 0; + } + + // The first component is encoded as 40 * |a| + |b|. This assumes that |a| is + // 0, 1, or 2 and that, when it is 0 or 1, |b| is at most 39. + if (a > 2 || + (a < 2 && b > 39) || + b > UINT64_MAX - 80 || + !add_base128_integer(cbb, 40u * a + b)) { + return 0; + } + + // The remaining components are encoded unmodified. + while (CBS_len(&cbs) > 0) { + if (!parse_dotted_decimal(&cbs, &a) || + !add_base128_integer(cbb, a)) { + return 0; + } + } + + return 1; +} + +static int compare_set_of_element(const void *a_ptr, const void *b_ptr) { + // See X.690, section 11.6 for the ordering. They are sorted in ascending + // order by their DER encoding. + const CBS *a = a_ptr, *b = b_ptr; + size_t a_len = CBS_len(a), b_len = CBS_len(b); + size_t min_len = a_len < b_len ? a_len : b_len; + int ret = OPENSSL_memcmp(CBS_data(a), CBS_data(b), min_len); + if (ret != 0) { + return ret; + } + if (a_len == b_len) { + return 0; + } + // If one is a prefix of the other, the shorter one sorts first. (This is not + // actually reachable. No DER encoding is a prefix of another DER encoding.) + return a_len < b_len ? -1 : 1; +} + +int CBB_flush_asn1_set_of(CBB *cbb) { + if (!CBB_flush(cbb)) { + return 0; + } + + CBS cbs; + size_t num_children = 0; + CBS_init(&cbs, CBB_data(cbb), CBB_len(cbb)); + while (CBS_len(&cbs) != 0) { + if (!CBS_get_any_asn1_element(&cbs, NULL, NULL, NULL)) { + return 0; + } + num_children++; + } + + if (num_children < 2) { + return 1; // Nothing to do. This is the common case for X.509. + } + if (num_children > ((size_t)-1) / sizeof(CBS)) { + return 0; // Overflow. + } + + // Parse out the children and sort. We alias them into a copy of so they + // remain valid as we rewrite |cbb|. + int ret = 0; + size_t buf_len = CBB_len(cbb); + uint8_t *buf = BUF_memdup(CBB_data(cbb), buf_len); + CBS *children = OPENSSL_malloc(num_children * sizeof(CBS)); + if (buf == NULL || children == NULL) { + goto err; + } + CBS_init(&cbs, buf, buf_len); + for (size_t i = 0; i < num_children; i++) { + if (!CBS_get_any_asn1_element(&cbs, &children[i], NULL, NULL)) { + goto err; + } + } + qsort(children, num_children, sizeof(CBS), compare_set_of_element); + + // Rewind |cbb| and write the contents back in the new order. + cbb->base->len = cbb->offset + cbb->pending_len_len; + for (size_t i = 0; i < num_children; i++) { + if (!CBB_add_bytes(cbb, CBS_data(&children[i]), CBS_len(&children[i]))) { + goto err; + } + } + assert(CBB_len(cbb) == buf_len); + + ret = 1; + +err: + OPENSSL_free(buf); + OPENSSL_free(children); + return ret; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/bytestring/cbs.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/bytestring/cbs.c new file mode 100644 index 0000000..e56eaf9 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/bytestring/cbs.c @@ -0,0 +1,618 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#if !defined(__STDC_FORMAT_MACROS) +#define __STDC_FORMAT_MACROS +#endif + +#include +#include +#include + +#include +#include +#include + +#include "internal.h" +#include "../internal.h" + + +void CBS_init(CBS *cbs, const uint8_t *data, size_t len) { + cbs->data = data; + cbs->len = len; +} + +static int cbs_get(CBS *cbs, const uint8_t **p, size_t n) { + if (cbs->len < n) { + return 0; + } + + *p = cbs->data; + cbs->data += n; + cbs->len -= n; + return 1; +} + +int CBS_skip(CBS *cbs, size_t len) { + const uint8_t *dummy; + return cbs_get(cbs, &dummy, len); +} + +const uint8_t *CBS_data(const CBS *cbs) { + return cbs->data; +} + +size_t CBS_len(const CBS *cbs) { + return cbs->len; +} + +int CBS_stow(const CBS *cbs, uint8_t **out_ptr, size_t *out_len) { + OPENSSL_free(*out_ptr); + *out_ptr = NULL; + *out_len = 0; + + if (cbs->len == 0) { + return 1; + } + *out_ptr = BUF_memdup(cbs->data, cbs->len); + if (*out_ptr == NULL) { + return 0; + } + *out_len = cbs->len; + return 1; +} + +int CBS_strdup(const CBS *cbs, char **out_ptr) { + if (*out_ptr != NULL) { + OPENSSL_free(*out_ptr); + } + *out_ptr = BUF_strndup((const char*)cbs->data, cbs->len); + return (*out_ptr != NULL); +} + +int CBS_contains_zero_byte(const CBS *cbs) { + return OPENSSL_memchr(cbs->data, 0, cbs->len) != NULL; +} + +int CBS_mem_equal(const CBS *cbs, const uint8_t *data, size_t len) { + if (len != cbs->len) { + return 0; + } + return CRYPTO_memcmp(cbs->data, data, len) == 0; +} + +static int cbs_get_u(CBS *cbs, uint32_t *out, size_t len) { + uint32_t result = 0; + const uint8_t *data; + + if (!cbs_get(cbs, &data, len)) { + return 0; + } + for (size_t i = 0; i < len; i++) { + result <<= 8; + result |= data[i]; + } + *out = result; + return 1; +} + +int CBS_get_u8(CBS *cbs, uint8_t *out) { + const uint8_t *v; + if (!cbs_get(cbs, &v, 1)) { + return 0; + } + *out = *v; + return 1; +} + +int CBS_get_u16(CBS *cbs, uint16_t *out) { + uint32_t v; + if (!cbs_get_u(cbs, &v, 2)) { + return 0; + } + *out = v; + return 1; +} + +int CBS_get_u24(CBS *cbs, uint32_t *out) { + return cbs_get_u(cbs, out, 3); +} + +int CBS_get_u32(CBS *cbs, uint32_t *out) { + return cbs_get_u(cbs, out, 4); +} + +int CBS_get_last_u8(CBS *cbs, uint8_t *out) { + if (cbs->len == 0) { + return 0; + } + *out = cbs->data[cbs->len - 1]; + cbs->len--; + return 1; +} + +int CBS_get_bytes(CBS *cbs, CBS *out, size_t len) { + const uint8_t *v; + if (!cbs_get(cbs, &v, len)) { + return 0; + } + CBS_init(out, v, len); + return 1; +} + +int CBS_copy_bytes(CBS *cbs, uint8_t *out, size_t len) { + const uint8_t *v; + if (!cbs_get(cbs, &v, len)) { + return 0; + } + OPENSSL_memcpy(out, v, len); + return 1; +} + +static int cbs_get_length_prefixed(CBS *cbs, CBS *out, size_t len_len) { + uint32_t len; + if (!cbs_get_u(cbs, &len, len_len)) { + return 0; + } + return CBS_get_bytes(cbs, out, len); +} + +int CBS_get_u8_length_prefixed(CBS *cbs, CBS *out) { + return cbs_get_length_prefixed(cbs, out, 1); +} + +int CBS_get_u16_length_prefixed(CBS *cbs, CBS *out) { + return cbs_get_length_prefixed(cbs, out, 2); +} + +int CBS_get_u24_length_prefixed(CBS *cbs, CBS *out) { + return cbs_get_length_prefixed(cbs, out, 3); +} + +// parse_base128_integer reads a big-endian base-128 integer from |cbs| and sets +// |*out| to the result. This is the encoding used in DER for both high tag +// number form and OID components. +static int parse_base128_integer(CBS *cbs, uint64_t *out) { + uint64_t v = 0; + uint8_t b; + do { + if (!CBS_get_u8(cbs, &b)) { + return 0; + } + if ((v >> (64 - 7)) != 0) { + // The value is too large. + return 0; + } + if (v == 0 && b == 0x80) { + // The value must be minimally encoded. + return 0; + } + v = (v << 7) | (b & 0x7f); + + // Values end at an octet with the high bit cleared. + } while (b & 0x80); + + *out = v; + return 1; +} + +static int parse_asn1_tag(CBS *cbs, unsigned *out) { + uint8_t tag_byte; + if (!CBS_get_u8(cbs, &tag_byte)) { + return 0; + } + + // ITU-T X.690 section 8.1.2.3 specifies the format for identifiers with a tag + // number no greater than 30. + // + // If the number portion is 31 (0x1f, the largest value that fits in the + // allotted bits), then the tag is more than one byte long and the + // continuation bytes contain the tag number. This parser only supports tag + // numbers less than 31 (and thus single-byte tags). + unsigned tag = ((unsigned)tag_byte & 0xe0) << CBS_ASN1_TAG_SHIFT; + unsigned tag_number = tag_byte & 0x1f; + if (tag_number == 0x1f) { + uint64_t v; + if (!parse_base128_integer(cbs, &v) || + // Check the tag number is within our supported bounds. + v > CBS_ASN1_TAG_NUMBER_MASK || + // Small tag numbers should have used low tag number form. + v < 0x1f) { + return 0; + } + tag_number = (unsigned)v; + } + + tag |= tag_number; + + *out = tag; + return 1; +} + +static int cbs_get_any_asn1_element(CBS *cbs, CBS *out, unsigned *out_tag, + size_t *out_header_len, int ber_ok) { + CBS header = *cbs; + CBS throwaway; + + if (out == NULL) { + out = &throwaway; + } + + unsigned tag; + if (!parse_asn1_tag(&header, &tag)) { + return 0; + } + if (out_tag != NULL) { + *out_tag = tag; + } + + uint8_t length_byte; + if (!CBS_get_u8(&header, &length_byte)) { + return 0; + } + + size_t header_len = CBS_len(cbs) - CBS_len(&header); + + size_t len; + // The format for the length encoding is specified in ITU-T X.690 section + // 8.1.3. + if ((length_byte & 0x80) == 0) { + // Short form length. + len = ((size_t) length_byte) + header_len; + if (out_header_len != NULL) { + *out_header_len = header_len; + } + } else { + // The high bit indicate that this is the long form, while the next 7 bits + // encode the number of subsequent octets used to encode the length (ITU-T + // X.690 clause 8.1.3.5.b). + const size_t num_bytes = length_byte & 0x7f; + uint32_t len32; + + if (ber_ok && (tag & CBS_ASN1_CONSTRUCTED) != 0 && num_bytes == 0) { + // indefinite length + if (out_header_len != NULL) { + *out_header_len = header_len; + } + return CBS_get_bytes(cbs, out, header_len); + } + + // ITU-T X.690 clause 8.1.3.5.c specifies that the value 0xff shall not be + // used as the first byte of the length. If this parser encounters that + // value, num_bytes will be parsed as 127, which will fail the check below. + if (num_bytes == 0 || num_bytes > 4) { + return 0; + } + if (!cbs_get_u(&header, &len32, num_bytes)) { + return 0; + } + // ITU-T X.690 section 10.1 (DER length forms) requires encoding the length + // with the minimum number of octets. + if (len32 < 128) { + // Length should have used short-form encoding. + return 0; + } + if ((len32 >> ((num_bytes-1)*8)) == 0) { + // Length should have been at least one byte shorter. + return 0; + } + len = len32; + if (len + header_len + num_bytes < len) { + // Overflow. + return 0; + } + len += header_len + num_bytes; + if (out_header_len != NULL) { + *out_header_len = header_len + num_bytes; + } + } + + return CBS_get_bytes(cbs, out, len); +} + +int CBS_get_any_asn1(CBS *cbs, CBS *out, unsigned *out_tag) { + size_t header_len; + if (!CBS_get_any_asn1_element(cbs, out, out_tag, &header_len)) { + return 0; + } + + if (!CBS_skip(out, header_len)) { + assert(0); + return 0; + } + + return 1; +} + +int CBS_get_any_asn1_element(CBS *cbs, CBS *out, unsigned *out_tag, + size_t *out_header_len) { + return cbs_get_any_asn1_element(cbs, out, out_tag, out_header_len, + 0 /* DER only */); +} + +int CBS_get_any_ber_asn1_element(CBS *cbs, CBS *out, unsigned *out_tag, + size_t *out_header_len) { + return cbs_get_any_asn1_element(cbs, out, out_tag, out_header_len, + 1 /* BER allowed */); +} + +static int cbs_get_asn1(CBS *cbs, CBS *out, unsigned tag_value, + int skip_header) { + size_t header_len; + unsigned tag; + CBS throwaway; + + if (out == NULL) { + out = &throwaway; + } + + if (!CBS_get_any_asn1_element(cbs, out, &tag, &header_len) || + tag != tag_value) { + return 0; + } + + if (skip_header && !CBS_skip(out, header_len)) { + assert(0); + return 0; + } + + return 1; +} + +int CBS_get_asn1(CBS *cbs, CBS *out, unsigned tag_value) { + return cbs_get_asn1(cbs, out, tag_value, 1 /* skip header */); +} + +int CBS_get_asn1_element(CBS *cbs, CBS *out, unsigned tag_value) { + return cbs_get_asn1(cbs, out, tag_value, 0 /* include header */); +} + +int CBS_peek_asn1_tag(const CBS *cbs, unsigned tag_value) { + if (CBS_len(cbs) < 1) { + return 0; + } + + CBS copy = *cbs; + unsigned actual_tag; + return parse_asn1_tag(©, &actual_tag) && tag_value == actual_tag; +} + +int CBS_get_asn1_uint64(CBS *cbs, uint64_t *out) { + CBS bytes; + if (!CBS_get_asn1(cbs, &bytes, CBS_ASN1_INTEGER)) { + return 0; + } + + *out = 0; + const uint8_t *data = CBS_data(&bytes); + size_t len = CBS_len(&bytes); + + if (len == 0) { + // An INTEGER is encoded with at least one octet. + return 0; + } + + if ((data[0] & 0x80) != 0) { + // Negative number. + return 0; + } + + if (data[0] == 0 && len > 1 && (data[1] & 0x80) == 0) { + // Extra leading zeros. + return 0; + } + + for (size_t i = 0; i < len; i++) { + if ((*out >> 56) != 0) { + // Too large to represent as a uint64_t. + return 0; + } + *out <<= 8; + *out |= data[i]; + } + + return 1; +} + +int CBS_get_asn1_bool(CBS *cbs, int *out) { + CBS bytes; + if (!CBS_get_asn1(cbs, &bytes, CBS_ASN1_BOOLEAN) || + CBS_len(&bytes) != 1) { + return 0; + } + + const uint8_t value = *CBS_data(&bytes); + if (value != 0 && value != 0xff) { + return 0; + } + + *out = !!value; + return 1; +} + +int CBS_get_optional_asn1(CBS *cbs, CBS *out, int *out_present, unsigned tag) { + int present = 0; + + if (CBS_peek_asn1_tag(cbs, tag)) { + if (!CBS_get_asn1(cbs, out, tag)) { + return 0; + } + present = 1; + } + + if (out_present != NULL) { + *out_present = present; + } + + return 1; +} + +int CBS_get_optional_asn1_octet_string(CBS *cbs, CBS *out, int *out_present, + unsigned tag) { + CBS child; + int present; + if (!CBS_get_optional_asn1(cbs, &child, &present, tag)) { + return 0; + } + if (present) { + assert(out); + if (!CBS_get_asn1(&child, out, CBS_ASN1_OCTETSTRING) || + CBS_len(&child) != 0) { + return 0; + } + } else { + CBS_init(out, NULL, 0); + } + if (out_present) { + *out_present = present; + } + return 1; +} + +int CBS_get_optional_asn1_uint64(CBS *cbs, uint64_t *out, unsigned tag, + uint64_t default_value) { + CBS child; + int present; + if (!CBS_get_optional_asn1(cbs, &child, &present, tag)) { + return 0; + } + if (present) { + if (!CBS_get_asn1_uint64(&child, out) || + CBS_len(&child) != 0) { + return 0; + } + } else { + *out = default_value; + } + return 1; +} + +int CBS_get_optional_asn1_bool(CBS *cbs, int *out, unsigned tag, + int default_value) { + CBS child, child2; + int present; + if (!CBS_get_optional_asn1(cbs, &child, &present, tag)) { + return 0; + } + if (present) { + uint8_t boolean; + + if (!CBS_get_asn1(&child, &child2, CBS_ASN1_BOOLEAN) || + CBS_len(&child2) != 1 || + CBS_len(&child) != 0) { + return 0; + } + + boolean = CBS_data(&child2)[0]; + if (boolean == 0) { + *out = 0; + } else if (boolean == 0xff) { + *out = 1; + } else { + return 0; + } + } else { + *out = default_value; + } + return 1; +} + +int CBS_is_valid_asn1_bitstring(const CBS *cbs) { + CBS in = *cbs; + uint8_t num_unused_bits; + if (!CBS_get_u8(&in, &num_unused_bits) || + num_unused_bits > 7) { + return 0; + } + + if (num_unused_bits == 0) { + return 1; + } + + // All num_unused_bits bits must exist and be zeros. + uint8_t last; + if (!CBS_get_last_u8(&in, &last) || + (last & ((1 << num_unused_bits) - 1)) != 0) { + return 0; + } + + return 1; +} + +int CBS_asn1_bitstring_has_bit(const CBS *cbs, unsigned bit) { + if (!CBS_is_valid_asn1_bitstring(cbs)) { + return 0; + } + + const unsigned byte_num = (bit >> 3) + 1; + const unsigned bit_num = 7 - (bit & 7); + + // Unused bits are zero, and this function does not distinguish between + // missing and unset bits. Thus it is sufficient to do a byte-level length + // check. + return byte_num < CBS_len(cbs) && + (CBS_data(cbs)[byte_num] & (1 << bit_num)) != 0; +} + +static int add_decimal(CBB *out, uint64_t v) { + char buf[DECIMAL_SIZE(uint64_t) + 1]; + BIO_snprintf(buf, sizeof(buf), "%" PRIu64, v); + return CBB_add_bytes(out, (const uint8_t *)buf, strlen(buf)); +} + +char *CBS_asn1_oid_to_text(const CBS *cbs) { + CBB cbb; + if (!CBB_init(&cbb, 32)) { + goto err; + } + + CBS copy = *cbs; + // The first component is 40 * value1 + value2, where value1 is 0, 1, or 2. + uint64_t v; + if (!parse_base128_integer(©, &v)) { + goto err; + } + + if (v >= 80) { + if (!CBB_add_bytes(&cbb, (const uint8_t *)"2.", 2) || + !add_decimal(&cbb, v - 80)) { + goto err; + } + } else if (!add_decimal(&cbb, v / 40) || + !CBB_add_u8(&cbb, '.') || + !add_decimal(&cbb, v % 40)) { + goto err; + } + + while (CBS_len(©) != 0) { + if (!parse_base128_integer(©, &v) || + !CBB_add_u8(&cbb, '.') || + !add_decimal(&cbb, v)) { + goto err; + } + } + + uint8_t *txt; + size_t txt_len; + if (!CBB_add_u8(&cbb, '\0') || + !CBB_finish(&cbb, &txt, &txt_len)) { + goto err; + } + + return (char *)txt; + +err: + CBB_cleanup(&cbb); + return NULL; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/bytestring/cbs.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/bytestring/cbs.c.grpc_back new file mode 100644 index 0000000..458af38 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/bytestring/cbs.c.grpc_back @@ -0,0 +1,618 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#if !defined(__STDC_FORMAT_MACROS) +#define __STDC_FORMAT_MACROS +#endif + +#include +#include +#include + +#include +#include +#include + +#include "internal.h" +#include "../internal.h" + + +void CBS_init(CBS *cbs, const uint8_t *data, size_t len) { + cbs->data = data; + cbs->len = len; +} + +static int cbs_get(CBS *cbs, const uint8_t **p, size_t n) { + if (cbs->len < n) { + return 0; + } + + *p = cbs->data; + cbs->data += n; + cbs->len -= n; + return 1; +} + +int CBS_skip(CBS *cbs, size_t len) { + const uint8_t *dummy; + return cbs_get(cbs, &dummy, len); +} + +const uint8_t *CBS_data(const CBS *cbs) { + return cbs->data; +} + +size_t CBS_len(const CBS *cbs) { + return cbs->len; +} + +int CBS_stow(const CBS *cbs, uint8_t **out_ptr, size_t *out_len) { + OPENSSL_free(*out_ptr); + *out_ptr = NULL; + *out_len = 0; + + if (cbs->len == 0) { + return 1; + } + *out_ptr = BUF_memdup(cbs->data, cbs->len); + if (*out_ptr == NULL) { + return 0; + } + *out_len = cbs->len; + return 1; +} + +int CBS_strdup(const CBS *cbs, char **out_ptr) { + if (*out_ptr != NULL) { + OPENSSL_free(*out_ptr); + } + *out_ptr = BUF_strndup((const char*)cbs->data, cbs->len); + return (*out_ptr != NULL); +} + +int CBS_contains_zero_byte(const CBS *cbs) { + return OPENSSL_memchr(cbs->data, 0, cbs->len) != NULL; +} + +int CBS_mem_equal(const CBS *cbs, const uint8_t *data, size_t len) { + if (len != cbs->len) { + return 0; + } + return CRYPTO_memcmp(cbs->data, data, len) == 0; +} + +static int cbs_get_u(CBS *cbs, uint32_t *out, size_t len) { + uint32_t result = 0; + const uint8_t *data; + + if (!cbs_get(cbs, &data, len)) { + return 0; + } + for (size_t i = 0; i < len; i++) { + result <<= 8; + result |= data[i]; + } + *out = result; + return 1; +} + +int CBS_get_u8(CBS *cbs, uint8_t *out) { + const uint8_t *v; + if (!cbs_get(cbs, &v, 1)) { + return 0; + } + *out = *v; + return 1; +} + +int CBS_get_u16(CBS *cbs, uint16_t *out) { + uint32_t v; + if (!cbs_get_u(cbs, &v, 2)) { + return 0; + } + *out = v; + return 1; +} + +int CBS_get_u24(CBS *cbs, uint32_t *out) { + return cbs_get_u(cbs, out, 3); +} + +int CBS_get_u32(CBS *cbs, uint32_t *out) { + return cbs_get_u(cbs, out, 4); +} + +int CBS_get_last_u8(CBS *cbs, uint8_t *out) { + if (cbs->len == 0) { + return 0; + } + *out = cbs->data[cbs->len - 1]; + cbs->len--; + return 1; +} + +int CBS_get_bytes(CBS *cbs, CBS *out, size_t len) { + const uint8_t *v; + if (!cbs_get(cbs, &v, len)) { + return 0; + } + CBS_init(out, v, len); + return 1; +} + +int CBS_copy_bytes(CBS *cbs, uint8_t *out, size_t len) { + const uint8_t *v; + if (!cbs_get(cbs, &v, len)) { + return 0; + } + OPENSSL_memcpy(out, v, len); + return 1; +} + +static int cbs_get_length_prefixed(CBS *cbs, CBS *out, size_t len_len) { + uint32_t len; + if (!cbs_get_u(cbs, &len, len_len)) { + return 0; + } + return CBS_get_bytes(cbs, out, len); +} + +int CBS_get_u8_length_prefixed(CBS *cbs, CBS *out) { + return cbs_get_length_prefixed(cbs, out, 1); +} + +int CBS_get_u16_length_prefixed(CBS *cbs, CBS *out) { + return cbs_get_length_prefixed(cbs, out, 2); +} + +int CBS_get_u24_length_prefixed(CBS *cbs, CBS *out) { + return cbs_get_length_prefixed(cbs, out, 3); +} + +// parse_base128_integer reads a big-endian base-128 integer from |cbs| and sets +// |*out| to the result. This is the encoding used in DER for both high tag +// number form and OID components. +static int parse_base128_integer(CBS *cbs, uint64_t *out) { + uint64_t v = 0; + uint8_t b; + do { + if (!CBS_get_u8(cbs, &b)) { + return 0; + } + if ((v >> (64 - 7)) != 0) { + // The value is too large. + return 0; + } + if (v == 0 && b == 0x80) { + // The value must be minimally encoded. + return 0; + } + v = (v << 7) | (b & 0x7f); + + // Values end at an octet with the high bit cleared. + } while (b & 0x80); + + *out = v; + return 1; +} + +static int parse_asn1_tag(CBS *cbs, unsigned *out) { + uint8_t tag_byte; + if (!CBS_get_u8(cbs, &tag_byte)) { + return 0; + } + + // ITU-T X.690 section 8.1.2.3 specifies the format for identifiers with a tag + // number no greater than 30. + // + // If the number portion is 31 (0x1f, the largest value that fits in the + // allotted bits), then the tag is more than one byte long and the + // continuation bytes contain the tag number. This parser only supports tag + // numbers less than 31 (and thus single-byte tags). + unsigned tag = ((unsigned)tag_byte & 0xe0) << CBS_ASN1_TAG_SHIFT; + unsigned tag_number = tag_byte & 0x1f; + if (tag_number == 0x1f) { + uint64_t v; + if (!parse_base128_integer(cbs, &v) || + // Check the tag number is within our supported bounds. + v > CBS_ASN1_TAG_NUMBER_MASK || + // Small tag numbers should have used low tag number form. + v < 0x1f) { + return 0; + } + tag_number = (unsigned)v; + } + + tag |= tag_number; + + *out = tag; + return 1; +} + +static int cbs_get_any_asn1_element(CBS *cbs, CBS *out, unsigned *out_tag, + size_t *out_header_len, int ber_ok) { + CBS header = *cbs; + CBS throwaway; + + if (out == NULL) { + out = &throwaway; + } + + unsigned tag; + if (!parse_asn1_tag(&header, &tag)) { + return 0; + } + if (out_tag != NULL) { + *out_tag = tag; + } + + uint8_t length_byte; + if (!CBS_get_u8(&header, &length_byte)) { + return 0; + } + + size_t header_len = CBS_len(cbs) - CBS_len(&header); + + size_t len; + // The format for the length encoding is specified in ITU-T X.690 section + // 8.1.3. + if ((length_byte & 0x80) == 0) { + // Short form length. + len = ((size_t) length_byte) + header_len; + if (out_header_len != NULL) { + *out_header_len = header_len; + } + } else { + // The high bit indicate that this is the long form, while the next 7 bits + // encode the number of subsequent octets used to encode the length (ITU-T + // X.690 clause 8.1.3.5.b). + const size_t num_bytes = length_byte & 0x7f; + uint32_t len32; + + if (ber_ok && (tag & CBS_ASN1_CONSTRUCTED) != 0 && num_bytes == 0) { + // indefinite length + if (out_header_len != NULL) { + *out_header_len = header_len; + } + return CBS_get_bytes(cbs, out, header_len); + } + + // ITU-T X.690 clause 8.1.3.5.c specifies that the value 0xff shall not be + // used as the first byte of the length. If this parser encounters that + // value, num_bytes will be parsed as 127, which will fail the check below. + if (num_bytes == 0 || num_bytes > 4) { + return 0; + } + if (!cbs_get_u(&header, &len32, num_bytes)) { + return 0; + } + // ITU-T X.690 section 10.1 (DER length forms) requires encoding the length + // with the minimum number of octets. + if (len32 < 128) { + // Length should have used short-form encoding. + return 0; + } + if ((len32 >> ((num_bytes-1)*8)) == 0) { + // Length should have been at least one byte shorter. + return 0; + } + len = len32; + if (len + header_len + num_bytes < len) { + // Overflow. + return 0; + } + len += header_len + num_bytes; + if (out_header_len != NULL) { + *out_header_len = header_len + num_bytes; + } + } + + return CBS_get_bytes(cbs, out, len); +} + +int CBS_get_any_asn1(CBS *cbs, CBS *out, unsigned *out_tag) { + size_t header_len; + if (!CBS_get_any_asn1_element(cbs, out, out_tag, &header_len)) { + return 0; + } + + if (!CBS_skip(out, header_len)) { + assert(0); + return 0; + } + + return 1; +} + +int CBS_get_any_asn1_element(CBS *cbs, CBS *out, unsigned *out_tag, + size_t *out_header_len) { + return cbs_get_any_asn1_element(cbs, out, out_tag, out_header_len, + 0 /* DER only */); +} + +int CBS_get_any_ber_asn1_element(CBS *cbs, CBS *out, unsigned *out_tag, + size_t *out_header_len) { + return cbs_get_any_asn1_element(cbs, out, out_tag, out_header_len, + 1 /* BER allowed */); +} + +static int cbs_get_asn1(CBS *cbs, CBS *out, unsigned tag_value, + int skip_header) { + size_t header_len; + unsigned tag; + CBS throwaway; + + if (out == NULL) { + out = &throwaway; + } + + if (!CBS_get_any_asn1_element(cbs, out, &tag, &header_len) || + tag != tag_value) { + return 0; + } + + if (skip_header && !CBS_skip(out, header_len)) { + assert(0); + return 0; + } + + return 1; +} + +int CBS_get_asn1(CBS *cbs, CBS *out, unsigned tag_value) { + return cbs_get_asn1(cbs, out, tag_value, 1 /* skip header */); +} + +int CBS_get_asn1_element(CBS *cbs, CBS *out, unsigned tag_value) { + return cbs_get_asn1(cbs, out, tag_value, 0 /* include header */); +} + +int CBS_peek_asn1_tag(const CBS *cbs, unsigned tag_value) { + if (CBS_len(cbs) < 1) { + return 0; + } + + CBS copy = *cbs; + unsigned actual_tag; + return parse_asn1_tag(©, &actual_tag) && tag_value == actual_tag; +} + +int CBS_get_asn1_uint64(CBS *cbs, uint64_t *out) { + CBS bytes; + if (!CBS_get_asn1(cbs, &bytes, CBS_ASN1_INTEGER)) { + return 0; + } + + *out = 0; + const uint8_t *data = CBS_data(&bytes); + size_t len = CBS_len(&bytes); + + if (len == 0) { + // An INTEGER is encoded with at least one octet. + return 0; + } + + if ((data[0] & 0x80) != 0) { + // Negative number. + return 0; + } + + if (data[0] == 0 && len > 1 && (data[1] & 0x80) == 0) { + // Extra leading zeros. + return 0; + } + + for (size_t i = 0; i < len; i++) { + if ((*out >> 56) != 0) { + // Too large to represent as a uint64_t. + return 0; + } + *out <<= 8; + *out |= data[i]; + } + + return 1; +} + +int CBS_get_asn1_bool(CBS *cbs, int *out) { + CBS bytes; + if (!CBS_get_asn1(cbs, &bytes, CBS_ASN1_BOOLEAN) || + CBS_len(&bytes) != 1) { + return 0; + } + + const uint8_t value = *CBS_data(&bytes); + if (value != 0 && value != 0xff) { + return 0; + } + + *out = !!value; + return 1; +} + +int CBS_get_optional_asn1(CBS *cbs, CBS *out, int *out_present, unsigned tag) { + int present = 0; + + if (CBS_peek_asn1_tag(cbs, tag)) { + if (!CBS_get_asn1(cbs, out, tag)) { + return 0; + } + present = 1; + } + + if (out_present != NULL) { + *out_present = present; + } + + return 1; +} + +int CBS_get_optional_asn1_octet_string(CBS *cbs, CBS *out, int *out_present, + unsigned tag) { + CBS child; + int present; + if (!CBS_get_optional_asn1(cbs, &child, &present, tag)) { + return 0; + } + if (present) { + assert(out); + if (!CBS_get_asn1(&child, out, CBS_ASN1_OCTETSTRING) || + CBS_len(&child) != 0) { + return 0; + } + } else { + CBS_init(out, NULL, 0); + } + if (out_present) { + *out_present = present; + } + return 1; +} + +int CBS_get_optional_asn1_uint64(CBS *cbs, uint64_t *out, unsigned tag, + uint64_t default_value) { + CBS child; + int present; + if (!CBS_get_optional_asn1(cbs, &child, &present, tag)) { + return 0; + } + if (present) { + if (!CBS_get_asn1_uint64(&child, out) || + CBS_len(&child) != 0) { + return 0; + } + } else { + *out = default_value; + } + return 1; +} + +int CBS_get_optional_asn1_bool(CBS *cbs, int *out, unsigned tag, + int default_value) { + CBS child, child2; + int present; + if (!CBS_get_optional_asn1(cbs, &child, &present, tag)) { + return 0; + } + if (present) { + uint8_t boolean; + + if (!CBS_get_asn1(&child, &child2, CBS_ASN1_BOOLEAN) || + CBS_len(&child2) != 1 || + CBS_len(&child) != 0) { + return 0; + } + + boolean = CBS_data(&child2)[0]; + if (boolean == 0) { + *out = 0; + } else if (boolean == 0xff) { + *out = 1; + } else { + return 0; + } + } else { + *out = default_value; + } + return 1; +} + +int CBS_is_valid_asn1_bitstring(const CBS *cbs) { + CBS in = *cbs; + uint8_t num_unused_bits; + if (!CBS_get_u8(&in, &num_unused_bits) || + num_unused_bits > 7) { + return 0; + } + + if (num_unused_bits == 0) { + return 1; + } + + // All num_unused_bits bits must exist and be zeros. + uint8_t last; + if (!CBS_get_last_u8(&in, &last) || + (last & ((1 << num_unused_bits) - 1)) != 0) { + return 0; + } + + return 1; +} + +int CBS_asn1_bitstring_has_bit(const CBS *cbs, unsigned bit) { + if (!CBS_is_valid_asn1_bitstring(cbs)) { + return 0; + } + + const unsigned byte_num = (bit >> 3) + 1; + const unsigned bit_num = 7 - (bit & 7); + + // Unused bits are zero, and this function does not distinguish between + // missing and unset bits. Thus it is sufficient to do a byte-level length + // check. + return byte_num < CBS_len(cbs) && + (CBS_data(cbs)[byte_num] & (1 << bit_num)) != 0; +} + +static int add_decimal(CBB *out, uint64_t v) { + char buf[DECIMAL_SIZE(uint64_t) + 1]; + BIO_snprintf(buf, sizeof(buf), "%" PRIu64, v); + return CBB_add_bytes(out, (const uint8_t *)buf, strlen(buf)); +} + +char *CBS_asn1_oid_to_text(const CBS *cbs) { + CBB cbb; + if (!CBB_init(&cbb, 32)) { + goto err; + } + + CBS copy = *cbs; + // The first component is 40 * value1 + value2, where value1 is 0, 1, or 2. + uint64_t v; + if (!parse_base128_integer(©, &v)) { + goto err; + } + + if (v >= 80) { + if (!CBB_add_bytes(&cbb, (const uint8_t *)"2.", 2) || + !add_decimal(&cbb, v - 80)) { + goto err; + } + } else if (!add_decimal(&cbb, v / 40) || + !CBB_add_u8(&cbb, '.') || + !add_decimal(&cbb, v % 40)) { + goto err; + } + + while (CBS_len(©) != 0) { + if (!parse_base128_integer(©, &v) || + !CBB_add_u8(&cbb, '.') || + !add_decimal(&cbb, v)) { + goto err; + } + } + + uint8_t *txt; + size_t txt_len; + if (!CBB_add_u8(&cbb, '\0') || + !CBB_finish(&cbb, &txt, &txt_len)) { + goto err; + } + + return (char *)txt; + +err: + CBB_cleanup(&cbb); + return NULL; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/bytestring/internal.h b/FoodApp/Pods/BoringSSL-GRPC/crypto/bytestring/internal.h new file mode 100644 index 0000000..d46dfa9 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/bytestring/internal.h @@ -0,0 +1,75 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_BYTESTRING_INTERNAL_H +#define OPENSSL_HEADER_BYTESTRING_INTERNAL_H + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// CBS_asn1_ber_to_der reads a BER element from |in|. If it finds +// indefinite-length elements or constructed strings then it converts the BER +// data to DER and sets |*out| and |*out_length| to describe a malloced buffer +// containing the DER data. Additionally, |*in| will be advanced over the BER +// element. +// +// If it doesn't find any indefinite-length elements or constructed strings then +// it sets |*out| to NULL and |*in| is unmodified. +// +// This function should successfully process any valid BER input, however it +// will not convert all of BER's deviations from DER. BER is ambiguous between +// implicitly-tagged SEQUENCEs of strings and implicitly-tagged constructed +// strings. Implicitly-tagged strings must be parsed with +// |CBS_get_ber_implicitly_tagged_string| instead of |CBS_get_asn1|. The caller +// must also account for BER variations in the contents of a primitive. +// +// It returns one on success and zero otherwise. +OPENSSL_EXPORT int CBS_asn1_ber_to_der(CBS *in, uint8_t **out, size_t *out_len); + +// CBS_get_asn1_implicit_string parses a BER string of primitive type +// |inner_tag| implicitly-tagged with |outer_tag|. It sets |out| to the +// contents. If concatenation was needed, it sets |*out_storage| to a buffer +// which the caller must release with |OPENSSL_free|. Otherwise, it sets +// |*out_storage| to NULL. +// +// This function does not parse all of BER. It requires the string be +// definite-length. Constructed strings are allowed, but all children of the +// outermost element must be primitive. The caller should use +// |CBS_asn1_ber_to_der| before running this function. +// +// It returns one on success and zero otherwise. +OPENSSL_EXPORT int CBS_get_asn1_implicit_string(CBS *in, CBS *out, + uint8_t **out_storage, + unsigned outer_tag, + unsigned inner_tag); + +// CBB_finish_i2d calls |CBB_finish| on |cbb| which must have been initialized +// with |CBB_init|. If |outp| is not NULL then the result is written to |*outp| +// and |*outp| is advanced just past the output. It returns the number of bytes +// in the result, whether written or not, or a negative value on error. On +// error, it calls |CBB_cleanup| on |cbb|. +// +// This function may be used to help implement legacy i2d ASN.1 functions. +int CBB_finish_i2d(CBB *cbb, uint8_t **outp); + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_BYTESTRING_INTERNAL_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/bytestring/internal.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/bytestring/internal.h.grpc_back new file mode 100644 index 0000000..f6ac32c --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/bytestring/internal.h.grpc_back @@ -0,0 +1,75 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_BYTESTRING_INTERNAL_H +#define OPENSSL_HEADER_BYTESTRING_INTERNAL_H + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// CBS_asn1_ber_to_der reads a BER element from |in|. If it finds +// indefinite-length elements or constructed strings then it converts the BER +// data to DER and sets |*out| and |*out_length| to describe a malloced buffer +// containing the DER data. Additionally, |*in| will be advanced over the BER +// element. +// +// If it doesn't find any indefinite-length elements or constructed strings then +// it sets |*out| to NULL and |*in| is unmodified. +// +// This function should successfully process any valid BER input, however it +// will not convert all of BER's deviations from DER. BER is ambiguous between +// implicitly-tagged SEQUENCEs of strings and implicitly-tagged constructed +// strings. Implicitly-tagged strings must be parsed with +// |CBS_get_ber_implicitly_tagged_string| instead of |CBS_get_asn1|. The caller +// must also account for BER variations in the contents of a primitive. +// +// It returns one on success and zero otherwise. +OPENSSL_EXPORT int CBS_asn1_ber_to_der(CBS *in, uint8_t **out, size_t *out_len); + +// CBS_get_asn1_implicit_string parses a BER string of primitive type +// |inner_tag| implicitly-tagged with |outer_tag|. It sets |out| to the +// contents. If concatenation was needed, it sets |*out_storage| to a buffer +// which the caller must release with |OPENSSL_free|. Otherwise, it sets +// |*out_storage| to NULL. +// +// This function does not parse all of BER. It requires the string be +// definite-length. Constructed strings are allowed, but all children of the +// outermost element must be primitive. The caller should use +// |CBS_asn1_ber_to_der| before running this function. +// +// It returns one on success and zero otherwise. +OPENSSL_EXPORT int CBS_get_asn1_implicit_string(CBS *in, CBS *out, + uint8_t **out_storage, + unsigned outer_tag, + unsigned inner_tag); + +// CBB_finish_i2d calls |CBB_finish| on |cbb| which must have been initialized +// with |CBB_init|. If |outp| is not NULL then the result is written to |*outp| +// and |*outp| is advanced just past the output. It returns the number of bytes +// in the result, whether written or not, or a negative value on error. On +// error, it calls |CBB_cleanup| on |cbb|. +// +// This function may be used to help implement legacy i2d ASN.1 functions. +int CBB_finish_i2d(CBB *cbb, uint8_t **outp); + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_BYTESTRING_INTERNAL_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/chacha/chacha.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/chacha/chacha.c new file mode 100644 index 0000000..6bbc087 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/chacha/chacha.c @@ -0,0 +1,167 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +// Adapted from the public domain, estream code by D. Bernstein. + +#include + +#include +#include + +#include + +#include "../internal.h" + + +#define U8TO32_LITTLE(p) \ + (((uint32_t)((p)[0])) | ((uint32_t)((p)[1]) << 8) | \ + ((uint32_t)((p)[2]) << 16) | ((uint32_t)((p)[3]) << 24)) + +#if !defined(OPENSSL_NO_ASM) && \ + (defined(OPENSSL_X86) || defined(OPENSSL_X86_64) || \ + defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)) + +// ChaCha20_ctr32 is defined in asm/chacha-*.pl. +void ChaCha20_ctr32(uint8_t *out, const uint8_t *in, size_t in_len, + const uint32_t key[8], const uint32_t counter[4]); + +void CRYPTO_chacha_20(uint8_t *out, const uint8_t *in, size_t in_len, + const uint8_t key[32], const uint8_t nonce[12], + uint32_t counter) { + assert(!buffers_alias(out, in_len, in, in_len) || in == out); + + uint32_t counter_nonce[4]; counter_nonce[0] = counter; + counter_nonce[1] = U8TO32_LITTLE(nonce + 0); + counter_nonce[2] = U8TO32_LITTLE(nonce + 4); + counter_nonce[3] = U8TO32_LITTLE(nonce + 8); + + const uint32_t *key_ptr = (const uint32_t *)key; +#if !defined(OPENSSL_X86) && !defined(OPENSSL_X86_64) + // The assembly expects the key to be four-byte aligned. + uint32_t key_u32[8]; + if ((((uintptr_t)key) & 3) != 0) { + key_u32[0] = U8TO32_LITTLE(key + 0); + key_u32[1] = U8TO32_LITTLE(key + 4); + key_u32[2] = U8TO32_LITTLE(key + 8); + key_u32[3] = U8TO32_LITTLE(key + 12); + key_u32[4] = U8TO32_LITTLE(key + 16); + key_u32[5] = U8TO32_LITTLE(key + 20); + key_u32[6] = U8TO32_LITTLE(key + 24); + key_u32[7] = U8TO32_LITTLE(key + 28); + + key_ptr = key_u32; + } +#endif + + ChaCha20_ctr32(out, in, in_len, key_ptr, counter_nonce); +} + +#else + +// sigma contains the ChaCha constants, which happen to be an ASCII string. +static const uint8_t sigma[16] = { 'e', 'x', 'p', 'a', 'n', 'd', ' ', '3', + '2', '-', 'b', 'y', 't', 'e', ' ', 'k' }; + +#define ROTATE(v, n) (((v) << (n)) | ((v) >> (32 - (n)))) + +#define U32TO8_LITTLE(p, v) \ + { \ + (p)[0] = (v >> 0) & 0xff; \ + (p)[1] = (v >> 8) & 0xff; \ + (p)[2] = (v >> 16) & 0xff; \ + (p)[3] = (v >> 24) & 0xff; \ + } + +// QUARTERROUND updates a, b, c, d with a ChaCha "quarter" round. +#define QUARTERROUND(a, b, c, d) \ + x[a] += x[b]; x[d] = ROTATE(x[d] ^ x[a], 16); \ + x[c] += x[d]; x[b] = ROTATE(x[b] ^ x[c], 12); \ + x[a] += x[b]; x[d] = ROTATE(x[d] ^ x[a], 8); \ + x[c] += x[d]; x[b] = ROTATE(x[b] ^ x[c], 7); + +// chacha_core performs 20 rounds of ChaCha on the input words in +// |input| and writes the 64 output bytes to |output|. +static void chacha_core(uint8_t output[64], const uint32_t input[16]) { + uint32_t x[16]; + int i; + + OPENSSL_memcpy(x, input, sizeof(uint32_t) * 16); + for (i = 20; i > 0; i -= 2) { + QUARTERROUND(0, 4, 8, 12) + QUARTERROUND(1, 5, 9, 13) + QUARTERROUND(2, 6, 10, 14) + QUARTERROUND(3, 7, 11, 15) + QUARTERROUND(0, 5, 10, 15) + QUARTERROUND(1, 6, 11, 12) + QUARTERROUND(2, 7, 8, 13) + QUARTERROUND(3, 4, 9, 14) + } + + for (i = 0; i < 16; ++i) { + x[i] += input[i]; + } + for (i = 0; i < 16; ++i) { + U32TO8_LITTLE(output + 4 * i, x[i]); + } +} + +void CRYPTO_chacha_20(uint8_t *out, const uint8_t *in, size_t in_len, + const uint8_t key[32], const uint8_t nonce[12], + uint32_t counter) { + assert(!buffers_alias(out, in_len, in, in_len) || in == out); + + uint32_t input[16]; + uint8_t buf[64]; + size_t todo, i; + + input[0] = U8TO32_LITTLE(sigma + 0); + input[1] = U8TO32_LITTLE(sigma + 4); + input[2] = U8TO32_LITTLE(sigma + 8); + input[3] = U8TO32_LITTLE(sigma + 12); + + input[4] = U8TO32_LITTLE(key + 0); + input[5] = U8TO32_LITTLE(key + 4); + input[6] = U8TO32_LITTLE(key + 8); + input[7] = U8TO32_LITTLE(key + 12); + + input[8] = U8TO32_LITTLE(key + 16); + input[9] = U8TO32_LITTLE(key + 20); + input[10] = U8TO32_LITTLE(key + 24); + input[11] = U8TO32_LITTLE(key + 28); + + input[12] = counter; + input[13] = U8TO32_LITTLE(nonce + 0); + input[14] = U8TO32_LITTLE(nonce + 4); + input[15] = U8TO32_LITTLE(nonce + 8); + + while (in_len > 0) { + todo = sizeof(buf); + if (in_len < todo) { + todo = in_len; + } + + chacha_core(buf, input); + for (i = 0; i < todo; i++) { + out[i] = in[i] ^ buf[i]; + } + + out += todo; + in += todo; + in_len -= todo; + + input[12]++; + } +} + +#endif diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/chacha/chacha.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/chacha/chacha.c.grpc_back new file mode 100644 index 0000000..646ef7a --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/chacha/chacha.c.grpc_back @@ -0,0 +1,167 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +// Adapted from the public domain, estream code by D. Bernstein. + +#include + +#include +#include + +#include + +#include "../internal.h" + + +#define U8TO32_LITTLE(p) \ + (((uint32_t)((p)[0])) | ((uint32_t)((p)[1]) << 8) | \ + ((uint32_t)((p)[2]) << 16) | ((uint32_t)((p)[3]) << 24)) + +#if !defined(OPENSSL_NO_ASM) && \ + (defined(OPENSSL_X86) || defined(OPENSSL_X86_64) || \ + defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)) + +// ChaCha20_ctr32 is defined in asm/chacha-*.pl. +void ChaCha20_ctr32(uint8_t *out, const uint8_t *in, size_t in_len, + const uint32_t key[8], const uint32_t counter[4]); + +void CRYPTO_chacha_20(uint8_t *out, const uint8_t *in, size_t in_len, + const uint8_t key[32], const uint8_t nonce[12], + uint32_t counter) { + assert(!buffers_alias(out, in_len, in, in_len) || in == out); + + uint32_t counter_nonce[4]; counter_nonce[0] = counter; + counter_nonce[1] = U8TO32_LITTLE(nonce + 0); + counter_nonce[2] = U8TO32_LITTLE(nonce + 4); + counter_nonce[3] = U8TO32_LITTLE(nonce + 8); + + const uint32_t *key_ptr = (const uint32_t *)key; +#if !defined(OPENSSL_X86) && !defined(OPENSSL_X86_64) + // The assembly expects the key to be four-byte aligned. + uint32_t key_u32[8]; + if ((((uintptr_t)key) & 3) != 0) { + key_u32[0] = U8TO32_LITTLE(key + 0); + key_u32[1] = U8TO32_LITTLE(key + 4); + key_u32[2] = U8TO32_LITTLE(key + 8); + key_u32[3] = U8TO32_LITTLE(key + 12); + key_u32[4] = U8TO32_LITTLE(key + 16); + key_u32[5] = U8TO32_LITTLE(key + 20); + key_u32[6] = U8TO32_LITTLE(key + 24); + key_u32[7] = U8TO32_LITTLE(key + 28); + + key_ptr = key_u32; + } +#endif + + ChaCha20_ctr32(out, in, in_len, key_ptr, counter_nonce); +} + +#else + +// sigma contains the ChaCha constants, which happen to be an ASCII string. +static const uint8_t sigma[16] = { 'e', 'x', 'p', 'a', 'n', 'd', ' ', '3', + '2', '-', 'b', 'y', 't', 'e', ' ', 'k' }; + +#define ROTATE(v, n) (((v) << (n)) | ((v) >> (32 - (n)))) + +#define U32TO8_LITTLE(p, v) \ + { \ + (p)[0] = (v >> 0) & 0xff; \ + (p)[1] = (v >> 8) & 0xff; \ + (p)[2] = (v >> 16) & 0xff; \ + (p)[3] = (v >> 24) & 0xff; \ + } + +// QUARTERROUND updates a, b, c, d with a ChaCha "quarter" round. +#define QUARTERROUND(a, b, c, d) \ + x[a] += x[b]; x[d] = ROTATE(x[d] ^ x[a], 16); \ + x[c] += x[d]; x[b] = ROTATE(x[b] ^ x[c], 12); \ + x[a] += x[b]; x[d] = ROTATE(x[d] ^ x[a], 8); \ + x[c] += x[d]; x[b] = ROTATE(x[b] ^ x[c], 7); + +// chacha_core performs 20 rounds of ChaCha on the input words in +// |input| and writes the 64 output bytes to |output|. +static void chacha_core(uint8_t output[64], const uint32_t input[16]) { + uint32_t x[16]; + int i; + + OPENSSL_memcpy(x, input, sizeof(uint32_t) * 16); + for (i = 20; i > 0; i -= 2) { + QUARTERROUND(0, 4, 8, 12) + QUARTERROUND(1, 5, 9, 13) + QUARTERROUND(2, 6, 10, 14) + QUARTERROUND(3, 7, 11, 15) + QUARTERROUND(0, 5, 10, 15) + QUARTERROUND(1, 6, 11, 12) + QUARTERROUND(2, 7, 8, 13) + QUARTERROUND(3, 4, 9, 14) + } + + for (i = 0; i < 16; ++i) { + x[i] += input[i]; + } + for (i = 0; i < 16; ++i) { + U32TO8_LITTLE(output + 4 * i, x[i]); + } +} + +void CRYPTO_chacha_20(uint8_t *out, const uint8_t *in, size_t in_len, + const uint8_t key[32], const uint8_t nonce[12], + uint32_t counter) { + assert(!buffers_alias(out, in_len, in, in_len) || in == out); + + uint32_t input[16]; + uint8_t buf[64]; + size_t todo, i; + + input[0] = U8TO32_LITTLE(sigma + 0); + input[1] = U8TO32_LITTLE(sigma + 4); + input[2] = U8TO32_LITTLE(sigma + 8); + input[3] = U8TO32_LITTLE(sigma + 12); + + input[4] = U8TO32_LITTLE(key + 0); + input[5] = U8TO32_LITTLE(key + 4); + input[6] = U8TO32_LITTLE(key + 8); + input[7] = U8TO32_LITTLE(key + 12); + + input[8] = U8TO32_LITTLE(key + 16); + input[9] = U8TO32_LITTLE(key + 20); + input[10] = U8TO32_LITTLE(key + 24); + input[11] = U8TO32_LITTLE(key + 28); + + input[12] = counter; + input[13] = U8TO32_LITTLE(nonce + 0); + input[14] = U8TO32_LITTLE(nonce + 4); + input[15] = U8TO32_LITTLE(nonce + 8); + + while (in_len > 0) { + todo = sizeof(buf); + if (in_len < todo) { + todo = in_len; + } + + chacha_core(buf, input); + for (i = 0; i < todo; i++) { + out[i] = in[i] ^ buf[i]; + } + + out += todo; + in += todo; + in_len -= todo; + + input[12]++; + } +} + +#endif diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/cipher_extra/cipher_extra.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/cipher_extra/cipher_extra.c new file mode 100644 index 0000000..d322dc6 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/cipher_extra/cipher_extra.c @@ -0,0 +1,114 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 +#include + +#include "internal.h" +#include "../internal.h" + + +const EVP_CIPHER *EVP_get_cipherbynid(int nid) { + switch (nid) { + case NID_rc2_cbc: + return EVP_rc2_cbc(); + case NID_rc2_40_cbc: + return EVP_rc2_40_cbc(); + case NID_des_ede3_cbc: + return EVP_des_ede3_cbc(); + case NID_des_ede_cbc: + return EVP_des_cbc(); + case NID_aes_128_cbc: + return EVP_aes_128_cbc(); + case NID_aes_192_cbc: + return EVP_aes_192_cbc(); + case NID_aes_256_cbc: + return EVP_aes_256_cbc(); + default: + return NULL; + } +} + +const EVP_CIPHER *EVP_get_cipherbyname(const char *name) { + if (OPENSSL_strcasecmp(name, "rc4") == 0) { + return EVP_rc4(); + } else if (OPENSSL_strcasecmp(name, "des-cbc") == 0) { + return EVP_des_cbc(); + } else if (OPENSSL_strcasecmp(name, "des-ede3-cbc") == 0 || + OPENSSL_strcasecmp(name, "3des") == 0) { + return EVP_des_ede3_cbc(); + } else if (OPENSSL_strcasecmp(name, "aes-128-cbc") == 0) { + return EVP_aes_128_cbc(); + } else if (OPENSSL_strcasecmp(name, "aes-256-cbc") == 0) { + return EVP_aes_256_cbc(); + } else if (OPENSSL_strcasecmp(name, "aes-128-ctr") == 0) { + return EVP_aes_128_ctr(); + } else if (OPENSSL_strcasecmp(name, "aes-256-ctr") == 0) { + return EVP_aes_256_ctr(); + } else if (OPENSSL_strcasecmp(name, "aes-128-ecb") == 0) { + return EVP_aes_128_ecb(); + } else if (OPENSSL_strcasecmp(name, "aes-256-ecb") == 0) { + return EVP_aes_256_ecb(); + } + + return NULL; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/cipher_extra/cipher_extra.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/cipher_extra/cipher_extra.c.grpc_back new file mode 100644 index 0000000..fc8e24b --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/cipher_extra/cipher_extra.c.grpc_back @@ -0,0 +1,114 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 +#include + +#include "internal.h" +#include "../internal.h" + + +const EVP_CIPHER *EVP_get_cipherbynid(int nid) { + switch (nid) { + case NID_rc2_cbc: + return EVP_rc2_cbc(); + case NID_rc2_40_cbc: + return EVP_rc2_40_cbc(); + case NID_des_ede3_cbc: + return EVP_des_ede3_cbc(); + case NID_des_ede_cbc: + return EVP_des_cbc(); + case NID_aes_128_cbc: + return EVP_aes_128_cbc(); + case NID_aes_192_cbc: + return EVP_aes_192_cbc(); + case NID_aes_256_cbc: + return EVP_aes_256_cbc(); + default: + return NULL; + } +} + +const EVP_CIPHER *EVP_get_cipherbyname(const char *name) { + if (OPENSSL_strcasecmp(name, "rc4") == 0) { + return EVP_rc4(); + } else if (OPENSSL_strcasecmp(name, "des-cbc") == 0) { + return EVP_des_cbc(); + } else if (OPENSSL_strcasecmp(name, "des-ede3-cbc") == 0 || + OPENSSL_strcasecmp(name, "3des") == 0) { + return EVP_des_ede3_cbc(); + } else if (OPENSSL_strcasecmp(name, "aes-128-cbc") == 0) { + return EVP_aes_128_cbc(); + } else if (OPENSSL_strcasecmp(name, "aes-256-cbc") == 0) { + return EVP_aes_256_cbc(); + } else if (OPENSSL_strcasecmp(name, "aes-128-ctr") == 0) { + return EVP_aes_128_ctr(); + } else if (OPENSSL_strcasecmp(name, "aes-256-ctr") == 0) { + return EVP_aes_256_ctr(); + } else if (OPENSSL_strcasecmp(name, "aes-128-ecb") == 0) { + return EVP_aes_128_ecb(); + } else if (OPENSSL_strcasecmp(name, "aes-256-ecb") == 0) { + return EVP_aes_256_ecb(); + } + + return NULL; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/cipher_extra/derive_key.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/cipher_extra/derive_key.c new file mode 100644 index 0000000..05d2435 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/cipher_extra/derive_key.c @@ -0,0 +1,152 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 + + +#define PKCS5_SALT_LEN 8 + +int EVP_BytesToKey(const EVP_CIPHER *type, const EVP_MD *md, + const uint8_t *salt, const uint8_t *data, size_t data_len, + unsigned count, uint8_t *key, uint8_t *iv) { + EVP_MD_CTX c; + uint8_t md_buf[EVP_MAX_MD_SIZE]; + unsigned niv, nkey, addmd = 0; + unsigned mds = 0, i; + int rv = 0; + + nkey = type->key_len; + niv = type->iv_len; + + assert(nkey <= EVP_MAX_KEY_LENGTH); + assert(niv <= EVP_MAX_IV_LENGTH); + + if (data == NULL) { + return nkey; + } + + EVP_MD_CTX_init(&c); + for (;;) { + if (!EVP_DigestInit_ex(&c, md, NULL)) { + return 0; + } + if (addmd++) { + if (!EVP_DigestUpdate(&c, md_buf, mds)) { + goto err; + } + } + if (!EVP_DigestUpdate(&c, data, data_len)) { + goto err; + } + if (salt != NULL) { + if (!EVP_DigestUpdate(&c, salt, PKCS5_SALT_LEN)) { + goto err; + } + } + if (!EVP_DigestFinal_ex(&c, md_buf, &mds)) { + goto err; + } + + for (i = 1; i < count; i++) { + if (!EVP_DigestInit_ex(&c, md, NULL) || + !EVP_DigestUpdate(&c, md_buf, mds) || + !EVP_DigestFinal_ex(&c, md_buf, &mds)) { + goto err; + } + } + + i = 0; + if (nkey) { + for (;;) { + if (nkey == 0 || i == mds) { + break; + } + if (key != NULL) { + *(key++) = md_buf[i]; + } + nkey--; + i++; + } + } + + if (niv && i != mds) { + for (;;) { + if (niv == 0 || 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, EVP_MAX_MD_SIZE); + return rv; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/cipher_extra/derive_key.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/cipher_extra/derive_key.c.grpc_back new file mode 100644 index 0000000..ff5ae06 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/cipher_extra/derive_key.c.grpc_back @@ -0,0 +1,152 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 + + +#define PKCS5_SALT_LEN 8 + +int EVP_BytesToKey(const EVP_CIPHER *type, const EVP_MD *md, + const uint8_t *salt, const uint8_t *data, size_t data_len, + unsigned count, uint8_t *key, uint8_t *iv) { + EVP_MD_CTX c; + uint8_t md_buf[EVP_MAX_MD_SIZE]; + unsigned niv, nkey, addmd = 0; + unsigned mds = 0, i; + int rv = 0; + + nkey = type->key_len; + niv = type->iv_len; + + assert(nkey <= EVP_MAX_KEY_LENGTH); + assert(niv <= EVP_MAX_IV_LENGTH); + + if (data == NULL) { + return nkey; + } + + EVP_MD_CTX_init(&c); + for (;;) { + if (!EVP_DigestInit_ex(&c, md, NULL)) { + return 0; + } + if (addmd++) { + if (!EVP_DigestUpdate(&c, md_buf, mds)) { + goto err; + } + } + if (!EVP_DigestUpdate(&c, data, data_len)) { + goto err; + } + if (salt != NULL) { + if (!EVP_DigestUpdate(&c, salt, PKCS5_SALT_LEN)) { + goto err; + } + } + if (!EVP_DigestFinal_ex(&c, md_buf, &mds)) { + goto err; + } + + for (i = 1; i < count; i++) { + if (!EVP_DigestInit_ex(&c, md, NULL) || + !EVP_DigestUpdate(&c, md_buf, mds) || + !EVP_DigestFinal_ex(&c, md_buf, &mds)) { + goto err; + } + } + + i = 0; + if (nkey) { + for (;;) { + if (nkey == 0 || i == mds) { + break; + } + if (key != NULL) { + *(key++) = md_buf[i]; + } + nkey--; + i++; + } + } + + if (niv && i != mds) { + for (;;) { + if (niv == 0 || 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, EVP_MAX_MD_SIZE); + return rv; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/cipher_extra/e_aesccm.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/cipher_extra/e_aesccm.c new file mode 100644 index 0000000..2adbc01 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/cipher_extra/e_aesccm.c @@ -0,0 +1,203 @@ +/* Copyright (c) 2018, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include + +#include +#include +#include + +#include "../fipsmodule/cipher/internal.h" + + +#define EVP_AEAD_AES_CCM_MAX_TAG_LEN 16 + +struct aead_aes_ccm_ctx { + union { + double align; + AES_KEY ks; + } ks; + CCM128_CONTEXT ccm; +}; + +static int aead_aes_ccm_init(EVP_AEAD_CTX *ctx, const uint8_t *key, + size_t key_len, size_t tag_len, unsigned M, + unsigned L) { + assert(M == EVP_AEAD_max_overhead(ctx->aead)); + assert(M == EVP_AEAD_max_tag_len(ctx->aead)); + assert(15 - L == EVP_AEAD_nonce_length(ctx->aead)); + + if (key_len != EVP_AEAD_key_length(ctx->aead)) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_KEY_LENGTH); + return 0; // EVP_AEAD_CTX_init should catch this. + } + + if (tag_len == EVP_AEAD_DEFAULT_TAG_LENGTH) { + tag_len = M; + } + + if (tag_len != M) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TAG_TOO_LARGE); + return 0; + } + + struct aead_aes_ccm_ctx *ccm_ctx = + OPENSSL_malloc(sizeof(struct aead_aes_ccm_ctx)); + if (ccm_ctx == NULL) { + OPENSSL_PUT_ERROR(CIPHER, ERR_R_MALLOC_FAILURE); + return 0; + } + + block128_f block; + ctr128_f ctr = aes_ctr_set_key(&ccm_ctx->ks.ks, NULL, &block, key, key_len); + ctx->tag_len = tag_len; + if (!CRYPTO_ccm128_init(&ccm_ctx->ccm, &ccm_ctx->ks.ks, block, ctr, M, L)) { + OPENSSL_PUT_ERROR(CIPHER, ERR_R_INTERNAL_ERROR); + OPENSSL_free(ccm_ctx); + return 0; + } + + ctx->aead_state = ccm_ctx; + return 1; +} + +static void aead_aes_ccm_cleanup(EVP_AEAD_CTX *ctx) { + OPENSSL_free(ctx->aead_state); +} + +static int aead_aes_ccm_seal_scatter( + const EVP_AEAD_CTX *ctx, uint8_t *out, uint8_t *out_tag, + size_t *out_tag_len, size_t max_out_tag_len, const uint8_t *nonce, + size_t nonce_len, const uint8_t *in, size_t in_len, const uint8_t *extra_in, + size_t extra_in_len, const uint8_t *ad, size_t ad_len) { + const struct aead_aes_ccm_ctx *ccm_ctx = ctx->aead_state; + + if (in_len > CRYPTO_ccm128_max_input(&ccm_ctx->ccm)) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE); + return 0; + } + + if (max_out_tag_len < ctx->tag_len) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL); + return 0; + } + + if (nonce_len != EVP_AEAD_nonce_length(ctx->aead)) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_NONCE_SIZE); + return 0; + } + + if (!CRYPTO_ccm128_encrypt(&ccm_ctx->ccm, &ccm_ctx->ks.ks, out, out_tag, + ctx->tag_len, nonce, nonce_len, in, in_len, ad, + ad_len)) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE); + return 0; + } + + *out_tag_len = ctx->tag_len; + return 1; +} + +static int aead_aes_ccm_open_gather(const EVP_AEAD_CTX *ctx, uint8_t *out, + const uint8_t *nonce, size_t nonce_len, + const uint8_t *in, size_t in_len, + const uint8_t *in_tag, size_t in_tag_len, + const uint8_t *ad, size_t ad_len) { + const struct aead_aes_ccm_ctx *ccm_ctx = ctx->aead_state; + + if (in_len > CRYPTO_ccm128_max_input(&ccm_ctx->ccm)) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE); + return 0; + } + + if (nonce_len != EVP_AEAD_nonce_length(ctx->aead)) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_NONCE_SIZE); + return 0; + } + + if (in_tag_len != ctx->tag_len) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT); + return 0; + } + + uint8_t tag[EVP_AEAD_AES_CCM_MAX_TAG_LEN]; + assert(ctx->tag_len <= EVP_AEAD_AES_CCM_MAX_TAG_LEN); + if (!CRYPTO_ccm128_decrypt(&ccm_ctx->ccm, &ccm_ctx->ks.ks, out, tag, + ctx->tag_len, nonce, nonce_len, in, in_len, ad, + ad_len)) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE); + return 0; + } + + if (CRYPTO_memcmp(tag, in_tag, ctx->tag_len) != 0) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT); + return 0; + } + + return 1; +} + +static int aead_aes_ccm_bluetooth_init(EVP_AEAD_CTX *ctx, const uint8_t *key, + size_t key_len, size_t tag_len) { + return aead_aes_ccm_init(ctx, key, key_len, tag_len, 4, 2); +} + +static const EVP_AEAD aead_aes_128_ccm_bluetooth = { + 16, // key length (AES-128) + 13, // nonce length + 4, // overhead + 4, // max tag length + 0, // seal_scatter_supports_extra_in + + aead_aes_ccm_bluetooth_init, + NULL /* init_with_direction */, + aead_aes_ccm_cleanup, + NULL /* open */, + aead_aes_ccm_seal_scatter, + aead_aes_ccm_open_gather, + NULL /* get_iv */, + NULL /* tag_len */, +}; + +const EVP_AEAD *EVP_aead_aes_128_ccm_bluetooth(void) { + return &aead_aes_128_ccm_bluetooth; +} + +static int aead_aes_ccm_bluetooth_8_init(EVP_AEAD_CTX *ctx, const uint8_t *key, + size_t key_len, size_t tag_len) { + return aead_aes_ccm_init(ctx, key, key_len, tag_len, 8, 2); +} + +static const EVP_AEAD aead_aes_128_ccm_bluetooth_8 = { + 16, // key length (AES-128) + 13, // nonce length + 8, // overhead + 8, // max tag length + 0, // seal_scatter_supports_extra_in + + aead_aes_ccm_bluetooth_8_init, + NULL /* init_with_direction */, + aead_aes_ccm_cleanup, + NULL /* open */, + aead_aes_ccm_seal_scatter, + aead_aes_ccm_open_gather, + NULL /* get_iv */, + NULL /* tag_len */, +}; + +const EVP_AEAD *EVP_aead_aes_128_ccm_bluetooth_8(void) { + return &aead_aes_128_ccm_bluetooth_8; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/cipher_extra/e_aesccm.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/cipher_extra/e_aesccm.c.grpc_back new file mode 100644 index 0000000..87f16dc --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/cipher_extra/e_aesccm.c.grpc_back @@ -0,0 +1,203 @@ +/* Copyright (c) 2018, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include + +#include +#include +#include + +#include "../fipsmodule/cipher/internal.h" + + +#define EVP_AEAD_AES_CCM_MAX_TAG_LEN 16 + +struct aead_aes_ccm_ctx { + union { + double align; + AES_KEY ks; + } ks; + CCM128_CONTEXT ccm; +}; + +static int aead_aes_ccm_init(EVP_AEAD_CTX *ctx, const uint8_t *key, + size_t key_len, size_t tag_len, unsigned M, + unsigned L) { + assert(M == EVP_AEAD_max_overhead(ctx->aead)); + assert(M == EVP_AEAD_max_tag_len(ctx->aead)); + assert(15 - L == EVP_AEAD_nonce_length(ctx->aead)); + + if (key_len != EVP_AEAD_key_length(ctx->aead)) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_KEY_LENGTH); + return 0; // EVP_AEAD_CTX_init should catch this. + } + + if (tag_len == EVP_AEAD_DEFAULT_TAG_LENGTH) { + tag_len = M; + } + + if (tag_len != M) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TAG_TOO_LARGE); + return 0; + } + + struct aead_aes_ccm_ctx *ccm_ctx = + OPENSSL_malloc(sizeof(struct aead_aes_ccm_ctx)); + if (ccm_ctx == NULL) { + OPENSSL_PUT_ERROR(CIPHER, ERR_R_MALLOC_FAILURE); + return 0; + } + + block128_f block; + ctr128_f ctr = aes_ctr_set_key(&ccm_ctx->ks.ks, NULL, &block, key, key_len); + ctx->tag_len = tag_len; + if (!CRYPTO_ccm128_init(&ccm_ctx->ccm, &ccm_ctx->ks.ks, block, ctr, M, L)) { + OPENSSL_PUT_ERROR(CIPHER, ERR_R_INTERNAL_ERROR); + OPENSSL_free(ccm_ctx); + return 0; + } + + ctx->aead_state = ccm_ctx; + return 1; +} + +static void aead_aes_ccm_cleanup(EVP_AEAD_CTX *ctx) { + OPENSSL_free(ctx->aead_state); +} + +static int aead_aes_ccm_seal_scatter( + const EVP_AEAD_CTX *ctx, uint8_t *out, uint8_t *out_tag, + size_t *out_tag_len, size_t max_out_tag_len, const uint8_t *nonce, + size_t nonce_len, const uint8_t *in, size_t in_len, const uint8_t *extra_in, + size_t extra_in_len, const uint8_t *ad, size_t ad_len) { + const struct aead_aes_ccm_ctx *ccm_ctx = ctx->aead_state; + + if (in_len > CRYPTO_ccm128_max_input(&ccm_ctx->ccm)) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE); + return 0; + } + + if (max_out_tag_len < ctx->tag_len) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL); + return 0; + } + + if (nonce_len != EVP_AEAD_nonce_length(ctx->aead)) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_NONCE_SIZE); + return 0; + } + + if (!CRYPTO_ccm128_encrypt(&ccm_ctx->ccm, &ccm_ctx->ks.ks, out, out_tag, + ctx->tag_len, nonce, nonce_len, in, in_len, ad, + ad_len)) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE); + return 0; + } + + *out_tag_len = ctx->tag_len; + return 1; +} + +static int aead_aes_ccm_open_gather(const EVP_AEAD_CTX *ctx, uint8_t *out, + const uint8_t *nonce, size_t nonce_len, + const uint8_t *in, size_t in_len, + const uint8_t *in_tag, size_t in_tag_len, + const uint8_t *ad, size_t ad_len) { + const struct aead_aes_ccm_ctx *ccm_ctx = ctx->aead_state; + + if (in_len > CRYPTO_ccm128_max_input(&ccm_ctx->ccm)) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE); + return 0; + } + + if (nonce_len != EVP_AEAD_nonce_length(ctx->aead)) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_NONCE_SIZE); + return 0; + } + + if (in_tag_len != ctx->tag_len) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT); + return 0; + } + + uint8_t tag[EVP_AEAD_AES_CCM_MAX_TAG_LEN]; + assert(ctx->tag_len <= EVP_AEAD_AES_CCM_MAX_TAG_LEN); + if (!CRYPTO_ccm128_decrypt(&ccm_ctx->ccm, &ccm_ctx->ks.ks, out, tag, + ctx->tag_len, nonce, nonce_len, in, in_len, ad, + ad_len)) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE); + return 0; + } + + if (CRYPTO_memcmp(tag, in_tag, ctx->tag_len) != 0) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT); + return 0; + } + + return 1; +} + +static int aead_aes_ccm_bluetooth_init(EVP_AEAD_CTX *ctx, const uint8_t *key, + size_t key_len, size_t tag_len) { + return aead_aes_ccm_init(ctx, key, key_len, tag_len, 4, 2); +} + +static const EVP_AEAD aead_aes_128_ccm_bluetooth = { + 16, // key length (AES-128) + 13, // nonce length + 4, // overhead + 4, // max tag length + 0, // seal_scatter_supports_extra_in + + aead_aes_ccm_bluetooth_init, + NULL /* init_with_direction */, + aead_aes_ccm_cleanup, + NULL /* open */, + aead_aes_ccm_seal_scatter, + aead_aes_ccm_open_gather, + NULL /* get_iv */, + NULL /* tag_len */, +}; + +const EVP_AEAD *EVP_aead_aes_128_ccm_bluetooth(void) { + return &aead_aes_128_ccm_bluetooth; +} + +static int aead_aes_ccm_bluetooth_8_init(EVP_AEAD_CTX *ctx, const uint8_t *key, + size_t key_len, size_t tag_len) { + return aead_aes_ccm_init(ctx, key, key_len, tag_len, 8, 2); +} + +static const EVP_AEAD aead_aes_128_ccm_bluetooth_8 = { + 16, // key length (AES-128) + 13, // nonce length + 8, // overhead + 8, // max tag length + 0, // seal_scatter_supports_extra_in + + aead_aes_ccm_bluetooth_8_init, + NULL /* init_with_direction */, + aead_aes_ccm_cleanup, + NULL /* open */, + aead_aes_ccm_seal_scatter, + aead_aes_ccm_open_gather, + NULL /* get_iv */, + NULL /* tag_len */, +}; + +const EVP_AEAD *EVP_aead_aes_128_ccm_bluetooth_8(void) { + return &aead_aes_128_ccm_bluetooth_8; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/cipher_extra/e_aesctrhmac.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/cipher_extra/e_aesctrhmac.c new file mode 100644 index 0000000..fc8125e --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/cipher_extra/e_aesctrhmac.c @@ -0,0 +1,281 @@ +/* Copyright (c) 2017, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include +#include +#include +#include +#include + +#include "../fipsmodule/cipher/internal.h" + + +#define EVP_AEAD_AES_CTR_HMAC_SHA256_TAG_LEN SHA256_DIGEST_LENGTH +#define EVP_AEAD_AES_CTR_HMAC_SHA256_NONCE_LEN 12 + +struct aead_aes_ctr_hmac_sha256_ctx { + union { + double align; + AES_KEY ks; + } ks; + ctr128_f ctr; + block128_f block; + SHA256_CTX inner_init_state; + SHA256_CTX outer_init_state; +}; + +static void hmac_init(SHA256_CTX *out_inner, SHA256_CTX *out_outer, + const uint8_t hmac_key[32]) { + static const size_t hmac_key_len = 32; + uint8_t block[SHA256_CBLOCK]; + OPENSSL_memcpy(block, hmac_key, hmac_key_len); + OPENSSL_memset(block + hmac_key_len, 0x36, sizeof(block) - hmac_key_len); + + unsigned i; + for (i = 0; i < hmac_key_len; i++) { + block[i] ^= 0x36; + } + + SHA256_Init(out_inner); + SHA256_Update(out_inner, block, sizeof(block)); + + OPENSSL_memset(block + hmac_key_len, 0x5c, sizeof(block) - hmac_key_len); + for (i = 0; i < hmac_key_len; i++) { + block[i] ^= (0x36 ^ 0x5c); + } + + SHA256_Init(out_outer); + SHA256_Update(out_outer, block, sizeof(block)); +} + +static int aead_aes_ctr_hmac_sha256_init(EVP_AEAD_CTX *ctx, const uint8_t *key, + size_t key_len, size_t tag_len) { + struct aead_aes_ctr_hmac_sha256_ctx *aes_ctx; + static const size_t hmac_key_len = 32; + + if (key_len < hmac_key_len) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_KEY_LENGTH); + return 0; // EVP_AEAD_CTX_init should catch this. + } + + const size_t aes_key_len = key_len - hmac_key_len; + if (aes_key_len != 16 && aes_key_len != 32) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_KEY_LENGTH); + return 0; // EVP_AEAD_CTX_init should catch this. + } + + if (tag_len == EVP_AEAD_DEFAULT_TAG_LENGTH) { + tag_len = EVP_AEAD_AES_CTR_HMAC_SHA256_TAG_LEN; + } + + if (tag_len > EVP_AEAD_AES_CTR_HMAC_SHA256_TAG_LEN) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TAG_TOO_LARGE); + return 0; + } + + aes_ctx = OPENSSL_malloc(sizeof(struct aead_aes_ctr_hmac_sha256_ctx)); + if (aes_ctx == NULL) { + OPENSSL_PUT_ERROR(CIPHER, ERR_R_MALLOC_FAILURE); + return 0; + } + + aes_ctx->ctr = + aes_ctr_set_key(&aes_ctx->ks.ks, NULL, &aes_ctx->block, key, aes_key_len); + ctx->tag_len = tag_len; + hmac_init(&aes_ctx->inner_init_state, &aes_ctx->outer_init_state, + key + aes_key_len); + + ctx->aead_state = aes_ctx; + + return 1; +} + +static void aead_aes_ctr_hmac_sha256_cleanup(EVP_AEAD_CTX *ctx) { + OPENSSL_free(ctx->aead_state); +} + +static void hmac_update_uint64(SHA256_CTX *sha256, uint64_t value) { + unsigned i; + uint8_t bytes[8]; + + for (i = 0; i < sizeof(bytes); i++) { + bytes[i] = value & 0xff; + value >>= 8; + } + SHA256_Update(sha256, bytes, sizeof(bytes)); +} + +static void hmac_calculate(uint8_t out[SHA256_DIGEST_LENGTH], + const SHA256_CTX *inner_init_state, + const SHA256_CTX *outer_init_state, + const uint8_t *ad, size_t ad_len, + const uint8_t *nonce, const uint8_t *ciphertext, + size_t ciphertext_len) { + SHA256_CTX sha256; + OPENSSL_memcpy(&sha256, inner_init_state, sizeof(sha256)); + hmac_update_uint64(&sha256, ad_len); + hmac_update_uint64(&sha256, ciphertext_len); + SHA256_Update(&sha256, nonce, EVP_AEAD_AES_CTR_HMAC_SHA256_NONCE_LEN); + SHA256_Update(&sha256, ad, ad_len); + + // Pad with zeros to the end of the SHA-256 block. + const unsigned num_padding = + (SHA256_CBLOCK - ((sizeof(uint64_t)*2 + + EVP_AEAD_AES_CTR_HMAC_SHA256_NONCE_LEN + ad_len) % + SHA256_CBLOCK)) % + SHA256_CBLOCK; + uint8_t padding[SHA256_CBLOCK]; + OPENSSL_memset(padding, 0, num_padding); + SHA256_Update(&sha256, padding, num_padding); + + SHA256_Update(&sha256, ciphertext, ciphertext_len); + + uint8_t inner_digest[SHA256_DIGEST_LENGTH]; + SHA256_Final(inner_digest, &sha256); + + OPENSSL_memcpy(&sha256, outer_init_state, sizeof(sha256)); + SHA256_Update(&sha256, inner_digest, sizeof(inner_digest)); + SHA256_Final(out, &sha256); +} + +static void aead_aes_ctr_hmac_sha256_crypt( + const struct aead_aes_ctr_hmac_sha256_ctx *aes_ctx, uint8_t *out, + const uint8_t *in, size_t len, const uint8_t *nonce) { + // Since the AEAD operation is one-shot, keeping a buffer of unused keystream + // bytes is pointless. However, |CRYPTO_ctr128_encrypt| requires it. + uint8_t partial_block_buffer[AES_BLOCK_SIZE]; + unsigned partial_block_offset = 0; + OPENSSL_memset(partial_block_buffer, 0, sizeof(partial_block_buffer)); + + uint8_t counter[AES_BLOCK_SIZE]; + OPENSSL_memcpy(counter, nonce, EVP_AEAD_AES_CTR_HMAC_SHA256_NONCE_LEN); + OPENSSL_memset(counter + EVP_AEAD_AES_CTR_HMAC_SHA256_NONCE_LEN, 0, 4); + + if (aes_ctx->ctr) { + CRYPTO_ctr128_encrypt_ctr32(in, out, len, &aes_ctx->ks.ks, counter, + partial_block_buffer, &partial_block_offset, + aes_ctx->ctr); + } else { + CRYPTO_ctr128_encrypt(in, out, len, &aes_ctx->ks.ks, counter, + partial_block_buffer, &partial_block_offset, + aes_ctx->block); + } +} + +static int aead_aes_ctr_hmac_sha256_seal_scatter( + const EVP_AEAD_CTX *ctx, uint8_t *out, uint8_t *out_tag, + size_t *out_tag_len, size_t max_out_tag_len, const uint8_t *nonce, + size_t nonce_len, const uint8_t *in, size_t in_len, const uint8_t *extra_in, + size_t extra_in_len, const uint8_t *ad, size_t ad_len) { + const struct aead_aes_ctr_hmac_sha256_ctx *aes_ctx = ctx->aead_state; + const uint64_t in_len_64 = in_len; + + if (in_len_64 >= (UINT64_C(1) << 32) * AES_BLOCK_SIZE) { + // This input is so large it would overflow the 32-bit block counter. + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE); + return 0; + } + + if (max_out_tag_len < ctx->tag_len) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL); + return 0; + } + + if (nonce_len != EVP_AEAD_AES_CTR_HMAC_SHA256_NONCE_LEN) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE); + return 0; + } + + aead_aes_ctr_hmac_sha256_crypt(aes_ctx, out, in, in_len, nonce); + + uint8_t hmac_result[SHA256_DIGEST_LENGTH]; + hmac_calculate(hmac_result, &aes_ctx->inner_init_state, + &aes_ctx->outer_init_state, ad, ad_len, nonce, out, in_len); + OPENSSL_memcpy(out_tag, hmac_result, ctx->tag_len); + *out_tag_len = ctx->tag_len; + + return 1; +} + +static int aead_aes_ctr_hmac_sha256_open_gather( + const EVP_AEAD_CTX *ctx, uint8_t *out, const uint8_t *nonce, + size_t nonce_len, const uint8_t *in, size_t in_len, const uint8_t *in_tag, + size_t in_tag_len, const uint8_t *ad, size_t ad_len) { + const struct aead_aes_ctr_hmac_sha256_ctx *aes_ctx = ctx->aead_state; + + if (in_tag_len != ctx->tag_len) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT); + return 0; + } + + if (nonce_len != EVP_AEAD_AES_CTR_HMAC_SHA256_NONCE_LEN) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE); + return 0; + } + + uint8_t hmac_result[SHA256_DIGEST_LENGTH]; + hmac_calculate(hmac_result, &aes_ctx->inner_init_state, + &aes_ctx->outer_init_state, ad, ad_len, nonce, in, + in_len); + if (CRYPTO_memcmp(hmac_result, in_tag, ctx->tag_len) != 0) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT); + return 0; + } + + aead_aes_ctr_hmac_sha256_crypt(aes_ctx, out, in, in_len, nonce); + + return 1; +} + +static const EVP_AEAD aead_aes_128_ctr_hmac_sha256 = { + 16 /* AES key */ + 32 /* HMAC key */, + 12, // nonce length + EVP_AEAD_AES_CTR_HMAC_SHA256_TAG_LEN, // overhead + EVP_AEAD_AES_CTR_HMAC_SHA256_TAG_LEN, // max tag length + 0, // seal_scatter_supports_extra_in + + aead_aes_ctr_hmac_sha256_init, + NULL /* init_with_direction */, + aead_aes_ctr_hmac_sha256_cleanup, + NULL /* open */, + aead_aes_ctr_hmac_sha256_seal_scatter, + aead_aes_ctr_hmac_sha256_open_gather, + NULL /* get_iv */, + NULL /* tag_len */, +}; + +static const EVP_AEAD aead_aes_256_ctr_hmac_sha256 = { + 32 /* AES key */ + 32 /* HMAC key */, + 12, // nonce length + EVP_AEAD_AES_CTR_HMAC_SHA256_TAG_LEN, // overhead + EVP_AEAD_AES_CTR_HMAC_SHA256_TAG_LEN, // max tag length + 0, // seal_scatter_supports_extra_in + + aead_aes_ctr_hmac_sha256_init, + NULL /* init_with_direction */, + aead_aes_ctr_hmac_sha256_cleanup, + NULL /* open */, + aead_aes_ctr_hmac_sha256_seal_scatter, + aead_aes_ctr_hmac_sha256_open_gather, + NULL /* get_iv */, + NULL /* tag_len */, +}; + +const EVP_AEAD *EVP_aead_aes_128_ctr_hmac_sha256(void) { + return &aead_aes_128_ctr_hmac_sha256; +} + +const EVP_AEAD *EVP_aead_aes_256_ctr_hmac_sha256(void) { + return &aead_aes_256_ctr_hmac_sha256; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/cipher_extra/e_aesctrhmac.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/cipher_extra/e_aesctrhmac.c.grpc_back new file mode 100644 index 0000000..3a0de9b --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/cipher_extra/e_aesctrhmac.c.grpc_back @@ -0,0 +1,281 @@ +/* Copyright (c) 2017, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include +#include +#include +#include +#include + +#include "../fipsmodule/cipher/internal.h" + + +#define EVP_AEAD_AES_CTR_HMAC_SHA256_TAG_LEN SHA256_DIGEST_LENGTH +#define EVP_AEAD_AES_CTR_HMAC_SHA256_NONCE_LEN 12 + +struct aead_aes_ctr_hmac_sha256_ctx { + union { + double align; + AES_KEY ks; + } ks; + ctr128_f ctr; + block128_f block; + SHA256_CTX inner_init_state; + SHA256_CTX outer_init_state; +}; + +static void hmac_init(SHA256_CTX *out_inner, SHA256_CTX *out_outer, + const uint8_t hmac_key[32]) { + static const size_t hmac_key_len = 32; + uint8_t block[SHA256_CBLOCK]; + OPENSSL_memcpy(block, hmac_key, hmac_key_len); + OPENSSL_memset(block + hmac_key_len, 0x36, sizeof(block) - hmac_key_len); + + unsigned i; + for (i = 0; i < hmac_key_len; i++) { + block[i] ^= 0x36; + } + + SHA256_Init(out_inner); + SHA256_Update(out_inner, block, sizeof(block)); + + OPENSSL_memset(block + hmac_key_len, 0x5c, sizeof(block) - hmac_key_len); + for (i = 0; i < hmac_key_len; i++) { + block[i] ^= (0x36 ^ 0x5c); + } + + SHA256_Init(out_outer); + SHA256_Update(out_outer, block, sizeof(block)); +} + +static int aead_aes_ctr_hmac_sha256_init(EVP_AEAD_CTX *ctx, const uint8_t *key, + size_t key_len, size_t tag_len) { + struct aead_aes_ctr_hmac_sha256_ctx *aes_ctx; + static const size_t hmac_key_len = 32; + + if (key_len < hmac_key_len) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_KEY_LENGTH); + return 0; // EVP_AEAD_CTX_init should catch this. + } + + const size_t aes_key_len = key_len - hmac_key_len; + if (aes_key_len != 16 && aes_key_len != 32) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_KEY_LENGTH); + return 0; // EVP_AEAD_CTX_init should catch this. + } + + if (tag_len == EVP_AEAD_DEFAULT_TAG_LENGTH) { + tag_len = EVP_AEAD_AES_CTR_HMAC_SHA256_TAG_LEN; + } + + if (tag_len > EVP_AEAD_AES_CTR_HMAC_SHA256_TAG_LEN) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TAG_TOO_LARGE); + return 0; + } + + aes_ctx = OPENSSL_malloc(sizeof(struct aead_aes_ctr_hmac_sha256_ctx)); + if (aes_ctx == NULL) { + OPENSSL_PUT_ERROR(CIPHER, ERR_R_MALLOC_FAILURE); + return 0; + } + + aes_ctx->ctr = + aes_ctr_set_key(&aes_ctx->ks.ks, NULL, &aes_ctx->block, key, aes_key_len); + ctx->tag_len = tag_len; + hmac_init(&aes_ctx->inner_init_state, &aes_ctx->outer_init_state, + key + aes_key_len); + + ctx->aead_state = aes_ctx; + + return 1; +} + +static void aead_aes_ctr_hmac_sha256_cleanup(EVP_AEAD_CTX *ctx) { + OPENSSL_free(ctx->aead_state); +} + +static void hmac_update_uint64(SHA256_CTX *sha256, uint64_t value) { + unsigned i; + uint8_t bytes[8]; + + for (i = 0; i < sizeof(bytes); i++) { + bytes[i] = value & 0xff; + value >>= 8; + } + SHA256_Update(sha256, bytes, sizeof(bytes)); +} + +static void hmac_calculate(uint8_t out[SHA256_DIGEST_LENGTH], + const SHA256_CTX *inner_init_state, + const SHA256_CTX *outer_init_state, + const uint8_t *ad, size_t ad_len, + const uint8_t *nonce, const uint8_t *ciphertext, + size_t ciphertext_len) { + SHA256_CTX sha256; + OPENSSL_memcpy(&sha256, inner_init_state, sizeof(sha256)); + hmac_update_uint64(&sha256, ad_len); + hmac_update_uint64(&sha256, ciphertext_len); + SHA256_Update(&sha256, nonce, EVP_AEAD_AES_CTR_HMAC_SHA256_NONCE_LEN); + SHA256_Update(&sha256, ad, ad_len); + + // Pad with zeros to the end of the SHA-256 block. + const unsigned num_padding = + (SHA256_CBLOCK - ((sizeof(uint64_t)*2 + + EVP_AEAD_AES_CTR_HMAC_SHA256_NONCE_LEN + ad_len) % + SHA256_CBLOCK)) % + SHA256_CBLOCK; + uint8_t padding[SHA256_CBLOCK]; + OPENSSL_memset(padding, 0, num_padding); + SHA256_Update(&sha256, padding, num_padding); + + SHA256_Update(&sha256, ciphertext, ciphertext_len); + + uint8_t inner_digest[SHA256_DIGEST_LENGTH]; + SHA256_Final(inner_digest, &sha256); + + OPENSSL_memcpy(&sha256, outer_init_state, sizeof(sha256)); + SHA256_Update(&sha256, inner_digest, sizeof(inner_digest)); + SHA256_Final(out, &sha256); +} + +static void aead_aes_ctr_hmac_sha256_crypt( + const struct aead_aes_ctr_hmac_sha256_ctx *aes_ctx, uint8_t *out, + const uint8_t *in, size_t len, const uint8_t *nonce) { + // Since the AEAD operation is one-shot, keeping a buffer of unused keystream + // bytes is pointless. However, |CRYPTO_ctr128_encrypt| requires it. + uint8_t partial_block_buffer[AES_BLOCK_SIZE]; + unsigned partial_block_offset = 0; + OPENSSL_memset(partial_block_buffer, 0, sizeof(partial_block_buffer)); + + uint8_t counter[AES_BLOCK_SIZE]; + OPENSSL_memcpy(counter, nonce, EVP_AEAD_AES_CTR_HMAC_SHA256_NONCE_LEN); + OPENSSL_memset(counter + EVP_AEAD_AES_CTR_HMAC_SHA256_NONCE_LEN, 0, 4); + + if (aes_ctx->ctr) { + CRYPTO_ctr128_encrypt_ctr32(in, out, len, &aes_ctx->ks.ks, counter, + partial_block_buffer, &partial_block_offset, + aes_ctx->ctr); + } else { + CRYPTO_ctr128_encrypt(in, out, len, &aes_ctx->ks.ks, counter, + partial_block_buffer, &partial_block_offset, + aes_ctx->block); + } +} + +static int aead_aes_ctr_hmac_sha256_seal_scatter( + const EVP_AEAD_CTX *ctx, uint8_t *out, uint8_t *out_tag, + size_t *out_tag_len, size_t max_out_tag_len, const uint8_t *nonce, + size_t nonce_len, const uint8_t *in, size_t in_len, const uint8_t *extra_in, + size_t extra_in_len, const uint8_t *ad, size_t ad_len) { + const struct aead_aes_ctr_hmac_sha256_ctx *aes_ctx = ctx->aead_state; + const uint64_t in_len_64 = in_len; + + if (in_len_64 >= (UINT64_C(1) << 32) * AES_BLOCK_SIZE) { + // This input is so large it would overflow the 32-bit block counter. + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE); + return 0; + } + + if (max_out_tag_len < ctx->tag_len) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL); + return 0; + } + + if (nonce_len != EVP_AEAD_AES_CTR_HMAC_SHA256_NONCE_LEN) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE); + return 0; + } + + aead_aes_ctr_hmac_sha256_crypt(aes_ctx, out, in, in_len, nonce); + + uint8_t hmac_result[SHA256_DIGEST_LENGTH]; + hmac_calculate(hmac_result, &aes_ctx->inner_init_state, + &aes_ctx->outer_init_state, ad, ad_len, nonce, out, in_len); + OPENSSL_memcpy(out_tag, hmac_result, ctx->tag_len); + *out_tag_len = ctx->tag_len; + + return 1; +} + +static int aead_aes_ctr_hmac_sha256_open_gather( + const EVP_AEAD_CTX *ctx, uint8_t *out, const uint8_t *nonce, + size_t nonce_len, const uint8_t *in, size_t in_len, const uint8_t *in_tag, + size_t in_tag_len, const uint8_t *ad, size_t ad_len) { + const struct aead_aes_ctr_hmac_sha256_ctx *aes_ctx = ctx->aead_state; + + if (in_tag_len != ctx->tag_len) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT); + return 0; + } + + if (nonce_len != EVP_AEAD_AES_CTR_HMAC_SHA256_NONCE_LEN) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE); + return 0; + } + + uint8_t hmac_result[SHA256_DIGEST_LENGTH]; + hmac_calculate(hmac_result, &aes_ctx->inner_init_state, + &aes_ctx->outer_init_state, ad, ad_len, nonce, in, + in_len); + if (CRYPTO_memcmp(hmac_result, in_tag, ctx->tag_len) != 0) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT); + return 0; + } + + aead_aes_ctr_hmac_sha256_crypt(aes_ctx, out, in, in_len, nonce); + + return 1; +} + +static const EVP_AEAD aead_aes_128_ctr_hmac_sha256 = { + 16 /* AES key */ + 32 /* HMAC key */, + 12, // nonce length + EVP_AEAD_AES_CTR_HMAC_SHA256_TAG_LEN, // overhead + EVP_AEAD_AES_CTR_HMAC_SHA256_TAG_LEN, // max tag length + 0, // seal_scatter_supports_extra_in + + aead_aes_ctr_hmac_sha256_init, + NULL /* init_with_direction */, + aead_aes_ctr_hmac_sha256_cleanup, + NULL /* open */, + aead_aes_ctr_hmac_sha256_seal_scatter, + aead_aes_ctr_hmac_sha256_open_gather, + NULL /* get_iv */, + NULL /* tag_len */, +}; + +static const EVP_AEAD aead_aes_256_ctr_hmac_sha256 = { + 32 /* AES key */ + 32 /* HMAC key */, + 12, // nonce length + EVP_AEAD_AES_CTR_HMAC_SHA256_TAG_LEN, // overhead + EVP_AEAD_AES_CTR_HMAC_SHA256_TAG_LEN, // max tag length + 0, // seal_scatter_supports_extra_in + + aead_aes_ctr_hmac_sha256_init, + NULL /* init_with_direction */, + aead_aes_ctr_hmac_sha256_cleanup, + NULL /* open */, + aead_aes_ctr_hmac_sha256_seal_scatter, + aead_aes_ctr_hmac_sha256_open_gather, + NULL /* get_iv */, + NULL /* tag_len */, +}; + +const EVP_AEAD *EVP_aead_aes_128_ctr_hmac_sha256(void) { + return &aead_aes_128_ctr_hmac_sha256; +} + +const EVP_AEAD *EVP_aead_aes_256_ctr_hmac_sha256(void) { + return &aead_aes_256_ctr_hmac_sha256; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/cipher_extra/e_aesgcmsiv.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/cipher_extra/e_aesgcmsiv.c new file mode 100644 index 0000000..b1021f7 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/cipher_extra/e_aesgcmsiv.c @@ -0,0 +1,867 @@ +/* Copyright (c) 2017, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include + +#include +#include +#include +#include + +#include "../fipsmodule/cipher/internal.h" + + +#define EVP_AEAD_AES_GCM_SIV_NONCE_LEN 12 +#define EVP_AEAD_AES_GCM_SIV_TAG_LEN 16 + +#if defined(OPENSSL_X86_64) && !defined(OPENSSL_NO_ASM) + +// Optimised AES-GCM-SIV + +struct aead_aes_gcm_siv_asm_ctx { + alignas(16) uint8_t key[16*15]; + int is_128_bit; + // ptr contains the original pointer from |OPENSSL_malloc|, which may only be + // 8-byte aligned. When freeing this structure, actually call |OPENSSL_free| + // on this pointer. + void *ptr; +}; + +// aes128gcmsiv_aes_ks writes an AES-128 key schedule for |key| to +// |out_expanded_key|. +extern void aes128gcmsiv_aes_ks( + const uint8_t key[16], uint8_t out_expanded_key[16*15]); + +// aes128gcmsiv_aes_ks writes an AES-128 key schedule for |key| to +// |out_expanded_key|. +extern void aes256gcmsiv_aes_ks( + const uint8_t key[16], uint8_t out_expanded_key[16*15]); + +static int aead_aes_gcm_siv_asm_init(EVP_AEAD_CTX *ctx, const uint8_t *key, + size_t key_len, size_t tag_len) { + const size_t key_bits = key_len * 8; + + if (key_bits != 128 && key_bits != 256) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_KEY_LENGTH); + return 0; // EVP_AEAD_CTX_init should catch this. + } + + if (tag_len == EVP_AEAD_DEFAULT_TAG_LENGTH) { + tag_len = EVP_AEAD_AES_GCM_SIV_TAG_LEN; + } + + if (tag_len != EVP_AEAD_AES_GCM_SIV_TAG_LEN) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TAG_TOO_LARGE); + return 0; + } + + char *ptr = OPENSSL_malloc(sizeof(struct aead_aes_gcm_siv_asm_ctx) + 8); + if (ptr == NULL) { + return 0; + } + assert((((uintptr_t)ptr) & 7) == 0); + + // gcm_siv_ctx needs to be 16-byte aligned in a cross-platform way. + struct aead_aes_gcm_siv_asm_ctx *gcm_siv_ctx = + (struct aead_aes_gcm_siv_asm_ctx *)(ptr + (((uintptr_t)ptr) & 8)); + + assert((((uintptr_t)gcm_siv_ctx) & 15) == 0); + gcm_siv_ctx->ptr = ptr; + + if (key_bits == 128) { + aes128gcmsiv_aes_ks(key, &gcm_siv_ctx->key[0]); + gcm_siv_ctx->is_128_bit = 1; + } else { + aes256gcmsiv_aes_ks(key, &gcm_siv_ctx->key[0]); + gcm_siv_ctx->is_128_bit = 0; + } + ctx->aead_state = gcm_siv_ctx; + ctx->tag_len = tag_len; + + return 1; +} + +static void aead_aes_gcm_siv_asm_cleanup(EVP_AEAD_CTX *ctx) { + const struct aead_aes_gcm_siv_asm_ctx *gcm_siv_ctx = ctx->aead_state; + OPENSSL_free(gcm_siv_ctx->ptr); +} + +// aesgcmsiv_polyval_horner updates the POLYVAL value in |in_out_poly| to +// include a number (|in_blocks|) of 16-byte blocks of data from |in|, given +// the POLYVAL key in |key|. +extern void aesgcmsiv_polyval_horner(const uint8_t in_out_poly[16], + const uint8_t key[16], const uint8_t *in, + size_t in_blocks); + +// aesgcmsiv_htable_init writes powers 1..8 of |auth_key| to |out_htable|. +extern void aesgcmsiv_htable_init(uint8_t out_htable[16 * 8], + const uint8_t auth_key[16]); + +// aesgcmsiv_htable6_init writes powers 1..6 of |auth_key| to |out_htable|. +extern void aesgcmsiv_htable6_init(uint8_t out_htable[16 * 6], + const uint8_t auth_key[16]); + +// aesgcmsiv_htable_polyval updates the POLYVAL value in |in_out_poly| to +// include |in_len| bytes of data from |in|. (Where |in_len| must be a multiple +// of 16.) It uses the precomputed powers of the key given in |htable|. +extern void aesgcmsiv_htable_polyval(const uint8_t htable[16 * 8], + const uint8_t *in, size_t in_len, + uint8_t in_out_poly[16]); + +// aes128gcmsiv_dec decrypts |in_len| & ~15 bytes from |out| and writes them to +// |in|. (The full value of |in_len| is still used to find the authentication +// tag appended to the ciphertext, however, so must not be pre-masked.) +// +// |in| and |out| may be equal, but must not otherwise overlap. +// +// While decrypting, it updates the POLYVAL value found at the beginning of +// |in_out_calculated_tag_and_scratch| and writes the updated value back before +// return. During executation, it may use the whole of this space for other +// purposes. In order to decrypt and update the POLYVAL value, it uses the +// expanded key from |key| and the table of powers in |htable|. +extern void aes128gcmsiv_dec(const uint8_t *in, uint8_t *out, + uint8_t in_out_calculated_tag_and_scratch[16 * 8], + const uint8_t htable[16 * 6], + const struct aead_aes_gcm_siv_asm_ctx *key, + size_t in_len); + +// aes256gcmsiv_dec acts like |aes128gcmsiv_dec|, but for AES-256. +extern void aes256gcmsiv_dec(const uint8_t *in, uint8_t *out, + uint8_t in_out_calculated_tag_and_scratch[16 * 8], + const uint8_t htable[16 * 6], + const struct aead_aes_gcm_siv_asm_ctx *key, + size_t in_len); + +// aes128gcmsiv_kdf performs the AES-GCM-SIV KDF given the expanded key from +// |key_schedule| and the nonce in |nonce|. Note that, while only 12 bytes of +// the nonce are used, 16 bytes are read and so the value must be +// right-padded. +extern void aes128gcmsiv_kdf(const uint8_t nonce[16], + uint64_t out_key_material[8], + const uint8_t *key_schedule); + +// aes256gcmsiv_kdf acts like |aes128gcmsiv_kdf|, but for AES-256. +extern void aes256gcmsiv_kdf(const uint8_t nonce[16], + uint64_t out_key_material[12], + const uint8_t *key_schedule); + +// aes128gcmsiv_aes_ks_enc_x1 performs a key expansion of the AES-128 key in +// |key|, writes the expanded key to |out_expanded_key| and encrypts a single +// block from |in| to |out|. +extern void aes128gcmsiv_aes_ks_enc_x1(const uint8_t in[16], uint8_t out[16], + uint8_t out_expanded_key[16 * 15], + const uint64_t key[2]); + +// aes256gcmsiv_aes_ks_enc_x1 acts like |aes128gcmsiv_aes_ks_enc_x1|, but for +// AES-256. +extern void aes256gcmsiv_aes_ks_enc_x1(const uint8_t in[16], uint8_t out[16], + uint8_t out_expanded_key[16 * 15], + const uint64_t key[4]); + +// aes128gcmsiv_ecb_enc_block encrypts a single block from |in| to |out| using +// the expanded key in |expanded_key|. +extern void aes128gcmsiv_ecb_enc_block( + const uint8_t in[16], uint8_t out[16], + const struct aead_aes_gcm_siv_asm_ctx *expanded_key); + +// aes256gcmsiv_ecb_enc_block acts like |aes128gcmsiv_ecb_enc_block|, but for +// AES-256. +extern void aes256gcmsiv_ecb_enc_block( + const uint8_t in[16], uint8_t out[16], + const struct aead_aes_gcm_siv_asm_ctx *expanded_key); + +// aes128gcmsiv_enc_msg_x4 encrypts |in_len| bytes from |in| to |out| using the +// expanded key from |key|. (The value of |in_len| must be a multiple of 16.) +// The |in| and |out| buffers may be equal but must not otherwise overlap. The +// initial counter is constructed from the given |tag| as required by +// AES-GCM-SIV. +extern void aes128gcmsiv_enc_msg_x4(const uint8_t *in, uint8_t *out, + const uint8_t *tag, + const struct aead_aes_gcm_siv_asm_ctx *key, + size_t in_len); + +// aes256gcmsiv_enc_msg_x4 acts like |aes128gcmsiv_enc_msg_x4|, but for +// AES-256. +extern void aes256gcmsiv_enc_msg_x4(const uint8_t *in, uint8_t *out, + const uint8_t *tag, + const struct aead_aes_gcm_siv_asm_ctx *key, + size_t in_len); + +// aes128gcmsiv_enc_msg_x8 acts like |aes128gcmsiv_enc_msg_x4|, but is +// optimised for longer messages. +extern void aes128gcmsiv_enc_msg_x8(const uint8_t *in, uint8_t *out, + const uint8_t *tag, + const struct aead_aes_gcm_siv_asm_ctx *key, + size_t in_len); + +// aes256gcmsiv_enc_msg_x8 acts like |aes256gcmsiv_enc_msg_x4|, but is +// optimised for longer messages. +extern void aes256gcmsiv_enc_msg_x8(const uint8_t *in, uint8_t *out, + const uint8_t *tag, + const struct aead_aes_gcm_siv_asm_ctx *key, + size_t in_len); + +// gcm_siv_asm_polyval evaluates POLYVAL at |auth_key| on the given plaintext +// and AD. The result is written to |out_tag|. +static void gcm_siv_asm_polyval(uint8_t out_tag[16], const uint8_t *in, + size_t in_len, const uint8_t *ad, size_t ad_len, + const uint8_t auth_key[16], + const uint8_t nonce[12]) { + OPENSSL_memset(out_tag, 0, 16); + const size_t ad_blocks = ad_len / 16; + const size_t in_blocks = in_len / 16; + int htable_init = 0; + alignas(16) uint8_t htable[16*8]; + + if (ad_blocks > 8 || in_blocks > 8) { + htable_init = 1; + aesgcmsiv_htable_init(htable, auth_key); + } + + if (htable_init) { + aesgcmsiv_htable_polyval(htable, ad, ad_len & ~15, out_tag); + } else { + aesgcmsiv_polyval_horner(out_tag, auth_key, ad, ad_blocks); + } + + uint8_t scratch[16]; + if (ad_len & 15) { + OPENSSL_memset(scratch, 0, sizeof(scratch)); + OPENSSL_memcpy(scratch, &ad[ad_len & ~15], ad_len & 15); + aesgcmsiv_polyval_horner(out_tag, auth_key, scratch, 1); + } + + if (htable_init) { + aesgcmsiv_htable_polyval(htable, in, in_len & ~15, out_tag); + } else { + aesgcmsiv_polyval_horner(out_tag, auth_key, in, in_blocks); + } + + if (in_len & 15) { + OPENSSL_memset(scratch, 0, sizeof(scratch)); + OPENSSL_memcpy(scratch, &in[in_len & ~15], in_len & 15); + aesgcmsiv_polyval_horner(out_tag, auth_key, scratch, 1); + } + + union { + uint8_t c[16]; + struct { + uint64_t ad; + uint64_t in; + } bitlens; + } length_block; + + length_block.bitlens.ad = ad_len * 8; + length_block.bitlens.in = in_len * 8; + aesgcmsiv_polyval_horner(out_tag, auth_key, length_block.c, 1); + + for (size_t i = 0; i < 12; i++) { + out_tag[i] ^= nonce[i]; + } + + out_tag[15] &= 0x7f; +} + +// aead_aes_gcm_siv_asm_crypt_last_block handles the encryption/decryption +// (same thing in CTR mode) of the final block of a plaintext/ciphertext. It +// writes |in_len| & 15 bytes to |out| + |in_len|, based on an initial counter +// derived from |tag|. +static void aead_aes_gcm_siv_asm_crypt_last_block( + int is_128_bit, uint8_t *out, const uint8_t *in, size_t in_len, + const uint8_t tag[16], + const struct aead_aes_gcm_siv_asm_ctx *enc_key_expanded) { + alignas(16) union { + uint8_t c[16]; + uint32_t u32[4]; + } counter; + OPENSSL_memcpy(&counter, tag, sizeof(counter)); + counter.c[15] |= 0x80; + counter.u32[0] += in_len / 16; + + if (is_128_bit) { + aes128gcmsiv_ecb_enc_block(&counter.c[0], &counter.c[0], enc_key_expanded); + } else { + aes256gcmsiv_ecb_enc_block(&counter.c[0], &counter.c[0], enc_key_expanded); + } + + const size_t last_bytes_offset = in_len & ~15; + const size_t last_bytes_len = in_len & 15; + uint8_t *last_bytes_out = &out[last_bytes_offset]; + const uint8_t *last_bytes_in = &in[last_bytes_offset]; + for (size_t i = 0; i < last_bytes_len; i++) { + last_bytes_out[i] = last_bytes_in[i] ^ counter.c[i]; + } +} + +// aead_aes_gcm_siv_kdf calculates the record encryption and authentication +// keys given the |nonce|. +static void aead_aes_gcm_siv_kdf( + int is_128_bit, const struct aead_aes_gcm_siv_asm_ctx *gcm_siv_ctx, + uint64_t out_record_auth_key[2], uint64_t out_record_enc_key[4], + const uint8_t nonce[12]) { + alignas(16) uint8_t padded_nonce[16]; + OPENSSL_memcpy(padded_nonce, nonce, 12); + + alignas(16) uint64_t key_material[12]; + if (is_128_bit) { + aes128gcmsiv_kdf(padded_nonce, key_material, &gcm_siv_ctx->key[0]); + out_record_enc_key[0] = key_material[4]; + out_record_enc_key[1] = key_material[6]; + } else { + aes256gcmsiv_kdf(padded_nonce, key_material, &gcm_siv_ctx->key[0]); + out_record_enc_key[0] = key_material[4]; + out_record_enc_key[1] = key_material[6]; + out_record_enc_key[2] = key_material[8]; + out_record_enc_key[3] = key_material[10]; + } + + out_record_auth_key[0] = key_material[0]; + out_record_auth_key[1] = key_material[2]; +} + +static int aead_aes_gcm_siv_asm_seal_scatter( + const EVP_AEAD_CTX *ctx, uint8_t *out, uint8_t *out_tag, + size_t *out_tag_len, size_t max_out_tag_len, const uint8_t *nonce, + size_t nonce_len, const uint8_t *in, size_t in_len, const uint8_t *extra_in, + size_t extra_in_len, const uint8_t *ad, size_t ad_len) { + const struct aead_aes_gcm_siv_asm_ctx *gcm_siv_ctx = ctx->aead_state; + const uint64_t in_len_64 = in_len; + const uint64_t ad_len_64 = ad_len; + + if (in_len_64 > (UINT64_C(1) << 36) || + ad_len_64 >= (UINT64_C(1) << 61)) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE); + return 0; + } + + if (max_out_tag_len < EVP_AEAD_AES_GCM_SIV_TAG_LEN) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL); + return 0; + } + + if (nonce_len != EVP_AEAD_AES_GCM_SIV_NONCE_LEN) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE); + return 0; + } + + alignas(16) uint64_t record_auth_key[2]; + alignas(16) uint64_t record_enc_key[4]; + aead_aes_gcm_siv_kdf(gcm_siv_ctx->is_128_bit, gcm_siv_ctx, record_auth_key, + record_enc_key, nonce); + + alignas(16) uint8_t tag[16] = {0}; + gcm_siv_asm_polyval(tag, in, in_len, ad, ad_len, + (const uint8_t *)record_auth_key, nonce); + + struct aead_aes_gcm_siv_asm_ctx enc_key_expanded; + + if (gcm_siv_ctx->is_128_bit) { + aes128gcmsiv_aes_ks_enc_x1(tag, tag, &enc_key_expanded.key[0], + record_enc_key); + + if (in_len < 128) { + aes128gcmsiv_enc_msg_x4(in, out, tag, &enc_key_expanded, in_len & ~15); + } else { + aes128gcmsiv_enc_msg_x8(in, out, tag, &enc_key_expanded, in_len & ~15); + } + } else { + aes256gcmsiv_aes_ks_enc_x1(tag, tag, &enc_key_expanded.key[0], + record_enc_key); + + if (in_len < 128) { + aes256gcmsiv_enc_msg_x4(in, out, tag, &enc_key_expanded, in_len & ~15); + } else { + aes256gcmsiv_enc_msg_x8(in, out, tag, &enc_key_expanded, in_len & ~15); + } + } + + if (in_len & 15) { + aead_aes_gcm_siv_asm_crypt_last_block(gcm_siv_ctx->is_128_bit, out, in, + in_len, tag, &enc_key_expanded); + } + + OPENSSL_memcpy(out_tag, tag, sizeof(tag)); + *out_tag_len = EVP_AEAD_AES_GCM_SIV_TAG_LEN; + + return 1; +} + +// TODO(martinkr): Add aead_aes_gcm_siv_asm_open_gather. N.B. aes128gcmsiv_dec +// expects ciphertext and tag in a contiguous buffer. + +static int aead_aes_gcm_siv_asm_open(const EVP_AEAD_CTX *ctx, uint8_t *out, + size_t *out_len, size_t max_out_len, + const uint8_t *nonce, size_t nonce_len, + const uint8_t *in, size_t in_len, + const uint8_t *ad, size_t ad_len) { + const uint64_t ad_len_64 = ad_len; + if (ad_len_64 >= (UINT64_C(1) << 61)) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE); + return 0; + } + + const uint64_t in_len_64 = in_len; + if (in_len < EVP_AEAD_AES_GCM_SIV_TAG_LEN || + in_len_64 > (UINT64_C(1) << 36) + AES_BLOCK_SIZE) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT); + return 0; + } + + const struct aead_aes_gcm_siv_asm_ctx *gcm_siv_ctx = ctx->aead_state; + const size_t plaintext_len = in_len - EVP_AEAD_AES_GCM_SIV_TAG_LEN; + const uint8_t *const given_tag = in + plaintext_len; + + if (max_out_len < plaintext_len) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL); + return 0; + } + + alignas(16) uint64_t record_auth_key[2]; + alignas(16) uint64_t record_enc_key[4]; + aead_aes_gcm_siv_kdf(gcm_siv_ctx->is_128_bit, gcm_siv_ctx, record_auth_key, + record_enc_key, nonce); + + struct aead_aes_gcm_siv_asm_ctx expanded_key; + if (gcm_siv_ctx->is_128_bit) { + aes128gcmsiv_aes_ks((const uint8_t *) record_enc_key, &expanded_key.key[0]); + } else { + aes256gcmsiv_aes_ks((const uint8_t *) record_enc_key, &expanded_key.key[0]); + } + // calculated_tag is 16*8 bytes, rather than 16 bytes, because + // aes[128|256]gcmsiv_dec uses the extra as scratch space. + alignas(16) uint8_t calculated_tag[16 * 8] = {0}; + + OPENSSL_memset(calculated_tag, 0, EVP_AEAD_AES_GCM_SIV_TAG_LEN); + const size_t ad_blocks = ad_len / 16; + aesgcmsiv_polyval_horner(calculated_tag, (const uint8_t *)record_auth_key, ad, + ad_blocks); + + uint8_t scratch[16]; + if (ad_len & 15) { + OPENSSL_memset(scratch, 0, sizeof(scratch)); + OPENSSL_memcpy(scratch, &ad[ad_len & ~15], ad_len & 15); + aesgcmsiv_polyval_horner(calculated_tag, (const uint8_t *)record_auth_key, + scratch, 1); + } + + alignas(16) uint8_t htable[16 * 6]; + aesgcmsiv_htable6_init(htable, (const uint8_t *)record_auth_key); + + if (gcm_siv_ctx->is_128_bit) { + aes128gcmsiv_dec(in, out, calculated_tag, htable, &expanded_key, + plaintext_len); + } else { + aes256gcmsiv_dec(in, out, calculated_tag, htable, &expanded_key, + plaintext_len); + } + + if (plaintext_len & 15) { + aead_aes_gcm_siv_asm_crypt_last_block(gcm_siv_ctx->is_128_bit, out, in, + plaintext_len, given_tag, + &expanded_key); + OPENSSL_memset(scratch, 0, sizeof(scratch)); + OPENSSL_memcpy(scratch, out + (plaintext_len & ~15), plaintext_len & 15); + aesgcmsiv_polyval_horner(calculated_tag, (const uint8_t *)record_auth_key, + scratch, 1); + } + + union { + uint8_t c[16]; + struct { + uint64_t ad; + uint64_t in; + } bitlens; + } length_block; + + length_block.bitlens.ad = ad_len * 8; + length_block.bitlens.in = plaintext_len * 8; + aesgcmsiv_polyval_horner(calculated_tag, (const uint8_t *)record_auth_key, + length_block.c, 1); + + for (size_t i = 0; i < 12; i++) { + calculated_tag[i] ^= nonce[i]; + } + + calculated_tag[15] &= 0x7f; + + if (gcm_siv_ctx->is_128_bit) { + aes128gcmsiv_ecb_enc_block(calculated_tag, calculated_tag, &expanded_key); + } else { + aes256gcmsiv_ecb_enc_block(calculated_tag, calculated_tag, &expanded_key); + } + + if (CRYPTO_memcmp(calculated_tag, given_tag, EVP_AEAD_AES_GCM_SIV_TAG_LEN) != + 0) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT); + return 0; + } + + *out_len = in_len - EVP_AEAD_AES_GCM_SIV_TAG_LEN; + return 1; +} + +static const EVP_AEAD aead_aes_128_gcm_siv_asm = { + 16, // key length + EVP_AEAD_AES_GCM_SIV_NONCE_LEN, // nonce length + EVP_AEAD_AES_GCM_SIV_TAG_LEN, // overhead + EVP_AEAD_AES_GCM_SIV_TAG_LEN, // max tag length + 0, // seal_scatter_supports_extra_in + + aead_aes_gcm_siv_asm_init, + NULL /* init_with_direction */, + aead_aes_gcm_siv_asm_cleanup, + aead_aes_gcm_siv_asm_open, + aead_aes_gcm_siv_asm_seal_scatter, + NULL /* open_gather */, + NULL /* get_iv */, + NULL /* tag_len */, +}; + +static const EVP_AEAD aead_aes_256_gcm_siv_asm = { + 32, // key length + EVP_AEAD_AES_GCM_SIV_NONCE_LEN, // nonce length + EVP_AEAD_AES_GCM_SIV_TAG_LEN, // overhead + EVP_AEAD_AES_GCM_SIV_TAG_LEN, // max tag length + 0, // seal_scatter_supports_extra_in + + aead_aes_gcm_siv_asm_init, + NULL /* init_with_direction */, + aead_aes_gcm_siv_asm_cleanup, + aead_aes_gcm_siv_asm_open, + aead_aes_gcm_siv_asm_seal_scatter, + NULL /* open_gather */, + NULL /* get_iv */, + NULL /* tag_len */, +}; + +#endif // X86_64 && !NO_ASM + +struct aead_aes_gcm_siv_ctx { + union { + double align; + AES_KEY ks; + } ks; + block128_f kgk_block; + unsigned is_256:1; +}; + +static int aead_aes_gcm_siv_init(EVP_AEAD_CTX *ctx, const uint8_t *key, + size_t key_len, size_t tag_len) { + const size_t key_bits = key_len * 8; + + if (key_bits != 128 && key_bits != 256) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_KEY_LENGTH); + return 0; // EVP_AEAD_CTX_init should catch this. + } + + if (tag_len == EVP_AEAD_DEFAULT_TAG_LENGTH) { + tag_len = EVP_AEAD_AES_GCM_SIV_TAG_LEN; + } + if (tag_len != EVP_AEAD_AES_GCM_SIV_TAG_LEN) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TAG_TOO_LARGE); + return 0; + } + + struct aead_aes_gcm_siv_ctx *gcm_siv_ctx = + OPENSSL_malloc(sizeof(struct aead_aes_gcm_siv_ctx)); + if (gcm_siv_ctx == NULL) { + return 0; + } + OPENSSL_memset(gcm_siv_ctx, 0, sizeof(struct aead_aes_gcm_siv_ctx)); + + aes_ctr_set_key(&gcm_siv_ctx->ks.ks, NULL, &gcm_siv_ctx->kgk_block, key, + key_len); + gcm_siv_ctx->is_256 = (key_len == 32); + ctx->aead_state = gcm_siv_ctx; + ctx->tag_len = tag_len; + + return 1; +} + +static void aead_aes_gcm_siv_cleanup(EVP_AEAD_CTX *ctx) { + OPENSSL_free(ctx->aead_state); +} + +// gcm_siv_crypt encrypts (or decrypts—it's the same thing) |in_len| bytes from +// |in| to |out|, using the block function |enc_block| with |key| in counter +// mode, starting at |initial_counter|. This differs from the traditional +// counter mode code in that the counter is handled little-endian, only the +// first four bytes are used and the GCM-SIV tweak to the final byte is +// applied. The |in| and |out| pointers may be equal but otherwise must not +// alias. +static void gcm_siv_crypt(uint8_t *out, const uint8_t *in, size_t in_len, + const uint8_t initial_counter[AES_BLOCK_SIZE], + block128_f enc_block, const AES_KEY *key) { + union { + uint32_t w[4]; + uint8_t c[16]; + } counter; + + OPENSSL_memcpy(counter.c, initial_counter, AES_BLOCK_SIZE); + counter.c[15] |= 0x80; + + for (size_t done = 0; done < in_len;) { + uint8_t keystream[AES_BLOCK_SIZE]; + enc_block(counter.c, keystream, key); + counter.w[0]++; + + size_t todo = AES_BLOCK_SIZE; + if (in_len - done < todo) { + todo = in_len - done; + } + + for (size_t i = 0; i < todo; i++) { + out[done + i] = keystream[i] ^ in[done + i]; + } + + done += todo; + } +} + +// gcm_siv_polyval evaluates POLYVAL at |auth_key| on the given plaintext and +// AD. The result is written to |out_tag|. +static void gcm_siv_polyval( + uint8_t out_tag[16], const uint8_t *in, size_t in_len, const uint8_t *ad, + size_t ad_len, const uint8_t auth_key[16], + const uint8_t nonce[EVP_AEAD_AES_GCM_SIV_NONCE_LEN]) { + struct polyval_ctx polyval_ctx; + CRYPTO_POLYVAL_init(&polyval_ctx, auth_key); + + CRYPTO_POLYVAL_update_blocks(&polyval_ctx, ad, ad_len & ~15); + + uint8_t scratch[16]; + if (ad_len & 15) { + OPENSSL_memset(scratch, 0, sizeof(scratch)); + OPENSSL_memcpy(scratch, &ad[ad_len & ~15], ad_len & 15); + CRYPTO_POLYVAL_update_blocks(&polyval_ctx, scratch, sizeof(scratch)); + } + + CRYPTO_POLYVAL_update_blocks(&polyval_ctx, in, in_len & ~15); + if (in_len & 15) { + OPENSSL_memset(scratch, 0, sizeof(scratch)); + OPENSSL_memcpy(scratch, &in[in_len & ~15], in_len & 15); + CRYPTO_POLYVAL_update_blocks(&polyval_ctx, scratch, sizeof(scratch)); + } + + union { + uint8_t c[16]; + struct { + uint64_t ad; + uint64_t in; + } bitlens; + } length_block; + + length_block.bitlens.ad = ad_len * 8; + length_block.bitlens.in = in_len * 8; + CRYPTO_POLYVAL_update_blocks(&polyval_ctx, length_block.c, + sizeof(length_block)); + + CRYPTO_POLYVAL_finish(&polyval_ctx, out_tag); + for (size_t i = 0; i < EVP_AEAD_AES_GCM_SIV_NONCE_LEN; i++) { + out_tag[i] ^= nonce[i]; + } + out_tag[15] &= 0x7f; +} + +// gcm_siv_record_keys contains the keys used for a specific GCM-SIV record. +struct gcm_siv_record_keys { + uint8_t auth_key[16]; + union { + double align; + AES_KEY ks; + } enc_key; + block128_f enc_block; +}; + +// gcm_siv_keys calculates the keys for a specific GCM-SIV record with the +// given nonce and writes them to |*out_keys|. +static void gcm_siv_keys( + const struct aead_aes_gcm_siv_ctx *gcm_siv_ctx, + struct gcm_siv_record_keys *out_keys, + const uint8_t nonce[EVP_AEAD_AES_GCM_SIV_NONCE_LEN]) { + const AES_KEY *const key = &gcm_siv_ctx->ks.ks; + uint8_t key_material[(128 /* POLYVAL key */ + 256 /* max AES key */) / 8]; + const size_t blocks_needed = gcm_siv_ctx->is_256 ? 6 : 4; + + uint8_t counter[AES_BLOCK_SIZE]; + OPENSSL_memset(counter, 0, AES_BLOCK_SIZE - EVP_AEAD_AES_GCM_SIV_NONCE_LEN); + OPENSSL_memcpy(counter + AES_BLOCK_SIZE - EVP_AEAD_AES_GCM_SIV_NONCE_LEN, + nonce, EVP_AEAD_AES_GCM_SIV_NONCE_LEN); + for (size_t i = 0; i < blocks_needed; i++) { + counter[0] = i; + + uint8_t ciphertext[AES_BLOCK_SIZE]; + gcm_siv_ctx->kgk_block(counter, ciphertext, key); + OPENSSL_memcpy(&key_material[i * 8], ciphertext, 8); + } + + OPENSSL_memcpy(out_keys->auth_key, key_material, 16); + aes_ctr_set_key(&out_keys->enc_key.ks, NULL, &out_keys->enc_block, + key_material + 16, gcm_siv_ctx->is_256 ? 32 : 16); +} + +static int aead_aes_gcm_siv_seal_scatter( + const EVP_AEAD_CTX *ctx, uint8_t *out, uint8_t *out_tag, + size_t *out_tag_len, size_t max_out_tag_len, const uint8_t *nonce, + size_t nonce_len, const uint8_t *in, size_t in_len, const uint8_t *extra_in, + size_t extra_in_len, const uint8_t *ad, size_t ad_len) { + const struct aead_aes_gcm_siv_ctx *gcm_siv_ctx = ctx->aead_state; + const uint64_t in_len_64 = in_len; + const uint64_t ad_len_64 = ad_len; + + if (in_len + EVP_AEAD_AES_GCM_SIV_TAG_LEN < in_len || + in_len_64 > (UINT64_C(1) << 36) || + ad_len_64 >= (UINT64_C(1) << 61)) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE); + return 0; + } + + if (max_out_tag_len < EVP_AEAD_AES_GCM_SIV_TAG_LEN) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL); + return 0; + } + + if (nonce_len != EVP_AEAD_AES_GCM_SIV_NONCE_LEN) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE); + return 0; + } + + struct gcm_siv_record_keys keys; + gcm_siv_keys(gcm_siv_ctx, &keys, nonce); + + uint8_t tag[16]; + gcm_siv_polyval(tag, in, in_len, ad, ad_len, keys.auth_key, nonce); + keys.enc_block(tag, tag, &keys.enc_key.ks); + + gcm_siv_crypt(out, in, in_len, tag, keys.enc_block, &keys.enc_key.ks); + + OPENSSL_memcpy(out_tag, tag, EVP_AEAD_AES_GCM_SIV_TAG_LEN); + *out_tag_len = EVP_AEAD_AES_GCM_SIV_TAG_LEN; + + return 1; +} + +static int aead_aes_gcm_siv_open_gather(const EVP_AEAD_CTX *ctx, uint8_t *out, + const uint8_t *nonce, size_t nonce_len, + const uint8_t *in, size_t in_len, + const uint8_t *in_tag, + size_t in_tag_len, const uint8_t *ad, + size_t ad_len) { + const uint64_t ad_len_64 = ad_len; + if (ad_len_64 >= (UINT64_C(1) << 61)) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE); + return 0; + } + + const uint64_t in_len_64 = in_len; + if (in_tag_len != EVP_AEAD_AES_GCM_SIV_TAG_LEN || + in_len_64 > (UINT64_C(1) << 36) + AES_BLOCK_SIZE) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT); + return 0; + } + + if (nonce_len != EVP_AEAD_AES_GCM_SIV_NONCE_LEN) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE); + return 0; + } + + const struct aead_aes_gcm_siv_ctx *gcm_siv_ctx = ctx->aead_state; + + struct gcm_siv_record_keys keys; + gcm_siv_keys(gcm_siv_ctx, &keys, nonce); + + gcm_siv_crypt(out, in, in_len, in_tag, keys.enc_block, &keys.enc_key.ks); + + uint8_t expected_tag[EVP_AEAD_AES_GCM_SIV_TAG_LEN]; + gcm_siv_polyval(expected_tag, out, in_len, ad, ad_len, keys.auth_key, nonce); + keys.enc_block(expected_tag, expected_tag, &keys.enc_key.ks); + + if (CRYPTO_memcmp(expected_tag, in_tag, sizeof(expected_tag)) != 0) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT); + return 0; + } + + return 1; +} + +static const EVP_AEAD aead_aes_128_gcm_siv = { + 16, // key length + EVP_AEAD_AES_GCM_SIV_NONCE_LEN, // nonce length + EVP_AEAD_AES_GCM_SIV_TAG_LEN, // overhead + EVP_AEAD_AES_GCM_SIV_TAG_LEN, // max tag length + 0, // seal_scatter_supports_extra_in + + aead_aes_gcm_siv_init, + NULL /* init_with_direction */, + aead_aes_gcm_siv_cleanup, + NULL /* open */, + aead_aes_gcm_siv_seal_scatter, + aead_aes_gcm_siv_open_gather, + NULL /* get_iv */, + NULL /* tag_len */, +}; + +static const EVP_AEAD aead_aes_256_gcm_siv = { + 32, // key length + EVP_AEAD_AES_GCM_SIV_NONCE_LEN, // nonce length + EVP_AEAD_AES_GCM_SIV_TAG_LEN, // overhead + EVP_AEAD_AES_GCM_SIV_TAG_LEN, // max tag length + 0, // seal_scatter_supports_extra_in + + aead_aes_gcm_siv_init, + NULL /* init_with_direction */, + aead_aes_gcm_siv_cleanup, + NULL /* open */, + aead_aes_gcm_siv_seal_scatter, + aead_aes_gcm_siv_open_gather, + NULL /* get_iv */, + NULL /* tag_len */, +}; + +#if defined(OPENSSL_X86_64) && !defined(OPENSSL_NO_ASM) + +static char avx_aesni_capable(void) { + const uint32_t ecx = OPENSSL_ia32cap_P[1]; + + return (ecx & (1 << (57 - 32))) != 0 /* AESNI */ && + (ecx & (1 << 28)) != 0 /* AVX */; +} + +const EVP_AEAD *EVP_aead_aes_128_gcm_siv(void) { + if (avx_aesni_capable()) { + return &aead_aes_128_gcm_siv_asm; + } + return &aead_aes_128_gcm_siv; +} + +const EVP_AEAD *EVP_aead_aes_256_gcm_siv(void) { + if (avx_aesni_capable()) { + return &aead_aes_256_gcm_siv_asm; + } + return &aead_aes_256_gcm_siv; +} + +#else + +const EVP_AEAD *EVP_aead_aes_128_gcm_siv(void) { + return &aead_aes_128_gcm_siv; +} + +const EVP_AEAD *EVP_aead_aes_256_gcm_siv(void) { + return &aead_aes_256_gcm_siv; +} + +#endif // X86_64 && !NO_ASM diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/cipher_extra/e_aesgcmsiv.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/cipher_extra/e_aesgcmsiv.c.grpc_back new file mode 100644 index 0000000..9de2300 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/cipher_extra/e_aesgcmsiv.c.grpc_back @@ -0,0 +1,867 @@ +/* Copyright (c) 2017, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include + +#include +#include +#include +#include + +#include "../fipsmodule/cipher/internal.h" + + +#define EVP_AEAD_AES_GCM_SIV_NONCE_LEN 12 +#define EVP_AEAD_AES_GCM_SIV_TAG_LEN 16 + +#if defined(OPENSSL_X86_64) && !defined(OPENSSL_NO_ASM) + +// Optimised AES-GCM-SIV + +struct aead_aes_gcm_siv_asm_ctx { + alignas(16) uint8_t key[16*15]; + int is_128_bit; + // ptr contains the original pointer from |OPENSSL_malloc|, which may only be + // 8-byte aligned. When freeing this structure, actually call |OPENSSL_free| + // on this pointer. + void *ptr; +}; + +// aes128gcmsiv_aes_ks writes an AES-128 key schedule for |key| to +// |out_expanded_key|. +extern void aes128gcmsiv_aes_ks( + const uint8_t key[16], uint8_t out_expanded_key[16*15]); + +// aes128gcmsiv_aes_ks writes an AES-128 key schedule for |key| to +// |out_expanded_key|. +extern void aes256gcmsiv_aes_ks( + const uint8_t key[16], uint8_t out_expanded_key[16*15]); + +static int aead_aes_gcm_siv_asm_init(EVP_AEAD_CTX *ctx, const uint8_t *key, + size_t key_len, size_t tag_len) { + const size_t key_bits = key_len * 8; + + if (key_bits != 128 && key_bits != 256) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_KEY_LENGTH); + return 0; // EVP_AEAD_CTX_init should catch this. + } + + if (tag_len == EVP_AEAD_DEFAULT_TAG_LENGTH) { + tag_len = EVP_AEAD_AES_GCM_SIV_TAG_LEN; + } + + if (tag_len != EVP_AEAD_AES_GCM_SIV_TAG_LEN) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TAG_TOO_LARGE); + return 0; + } + + char *ptr = OPENSSL_malloc(sizeof(struct aead_aes_gcm_siv_asm_ctx) + 8); + if (ptr == NULL) { + return 0; + } + assert((((uintptr_t)ptr) & 7) == 0); + + // gcm_siv_ctx needs to be 16-byte aligned in a cross-platform way. + struct aead_aes_gcm_siv_asm_ctx *gcm_siv_ctx = + (struct aead_aes_gcm_siv_asm_ctx *)(ptr + (((uintptr_t)ptr) & 8)); + + assert((((uintptr_t)gcm_siv_ctx) & 15) == 0); + gcm_siv_ctx->ptr = ptr; + + if (key_bits == 128) { + aes128gcmsiv_aes_ks(key, &gcm_siv_ctx->key[0]); + gcm_siv_ctx->is_128_bit = 1; + } else { + aes256gcmsiv_aes_ks(key, &gcm_siv_ctx->key[0]); + gcm_siv_ctx->is_128_bit = 0; + } + ctx->aead_state = gcm_siv_ctx; + ctx->tag_len = tag_len; + + return 1; +} + +static void aead_aes_gcm_siv_asm_cleanup(EVP_AEAD_CTX *ctx) { + const struct aead_aes_gcm_siv_asm_ctx *gcm_siv_ctx = ctx->aead_state; + OPENSSL_free(gcm_siv_ctx->ptr); +} + +// aesgcmsiv_polyval_horner updates the POLYVAL value in |in_out_poly| to +// include a number (|in_blocks|) of 16-byte blocks of data from |in|, given +// the POLYVAL key in |key|. +extern void aesgcmsiv_polyval_horner(const uint8_t in_out_poly[16], + const uint8_t key[16], const uint8_t *in, + size_t in_blocks); + +// aesgcmsiv_htable_init writes powers 1..8 of |auth_key| to |out_htable|. +extern void aesgcmsiv_htable_init(uint8_t out_htable[16 * 8], + const uint8_t auth_key[16]); + +// aesgcmsiv_htable6_init writes powers 1..6 of |auth_key| to |out_htable|. +extern void aesgcmsiv_htable6_init(uint8_t out_htable[16 * 6], + const uint8_t auth_key[16]); + +// aesgcmsiv_htable_polyval updates the POLYVAL value in |in_out_poly| to +// include |in_len| bytes of data from |in|. (Where |in_len| must be a multiple +// of 16.) It uses the precomputed powers of the key given in |htable|. +extern void aesgcmsiv_htable_polyval(const uint8_t htable[16 * 8], + const uint8_t *in, size_t in_len, + uint8_t in_out_poly[16]); + +// aes128gcmsiv_dec decrypts |in_len| & ~15 bytes from |out| and writes them to +// |in|. (The full value of |in_len| is still used to find the authentication +// tag appended to the ciphertext, however, so must not be pre-masked.) +// +// |in| and |out| may be equal, but must not otherwise overlap. +// +// While decrypting, it updates the POLYVAL value found at the beginning of +// |in_out_calculated_tag_and_scratch| and writes the updated value back before +// return. During executation, it may use the whole of this space for other +// purposes. In order to decrypt and update the POLYVAL value, it uses the +// expanded key from |key| and the table of powers in |htable|. +extern void aes128gcmsiv_dec(const uint8_t *in, uint8_t *out, + uint8_t in_out_calculated_tag_and_scratch[16 * 8], + const uint8_t htable[16 * 6], + const struct aead_aes_gcm_siv_asm_ctx *key, + size_t in_len); + +// aes256gcmsiv_dec acts like |aes128gcmsiv_dec|, but for AES-256. +extern void aes256gcmsiv_dec(const uint8_t *in, uint8_t *out, + uint8_t in_out_calculated_tag_and_scratch[16 * 8], + const uint8_t htable[16 * 6], + const struct aead_aes_gcm_siv_asm_ctx *key, + size_t in_len); + +// aes128gcmsiv_kdf performs the AES-GCM-SIV KDF given the expanded key from +// |key_schedule| and the nonce in |nonce|. Note that, while only 12 bytes of +// the nonce are used, 16 bytes are read and so the value must be +// right-padded. +extern void aes128gcmsiv_kdf(const uint8_t nonce[16], + uint64_t out_key_material[8], + const uint8_t *key_schedule); + +// aes256gcmsiv_kdf acts like |aes128gcmsiv_kdf|, but for AES-256. +extern void aes256gcmsiv_kdf(const uint8_t nonce[16], + uint64_t out_key_material[12], + const uint8_t *key_schedule); + +// aes128gcmsiv_aes_ks_enc_x1 performs a key expansion of the AES-128 key in +// |key|, writes the expanded key to |out_expanded_key| and encrypts a single +// block from |in| to |out|. +extern void aes128gcmsiv_aes_ks_enc_x1(const uint8_t in[16], uint8_t out[16], + uint8_t out_expanded_key[16 * 15], + const uint64_t key[2]); + +// aes256gcmsiv_aes_ks_enc_x1 acts like |aes128gcmsiv_aes_ks_enc_x1|, but for +// AES-256. +extern void aes256gcmsiv_aes_ks_enc_x1(const uint8_t in[16], uint8_t out[16], + uint8_t out_expanded_key[16 * 15], + const uint64_t key[4]); + +// aes128gcmsiv_ecb_enc_block encrypts a single block from |in| to |out| using +// the expanded key in |expanded_key|. +extern void aes128gcmsiv_ecb_enc_block( + const uint8_t in[16], uint8_t out[16], + const struct aead_aes_gcm_siv_asm_ctx *expanded_key); + +// aes256gcmsiv_ecb_enc_block acts like |aes128gcmsiv_ecb_enc_block|, but for +// AES-256. +extern void aes256gcmsiv_ecb_enc_block( + const uint8_t in[16], uint8_t out[16], + const struct aead_aes_gcm_siv_asm_ctx *expanded_key); + +// aes128gcmsiv_enc_msg_x4 encrypts |in_len| bytes from |in| to |out| using the +// expanded key from |key|. (The value of |in_len| must be a multiple of 16.) +// The |in| and |out| buffers may be equal but must not otherwise overlap. The +// initial counter is constructed from the given |tag| as required by +// AES-GCM-SIV. +extern void aes128gcmsiv_enc_msg_x4(const uint8_t *in, uint8_t *out, + const uint8_t *tag, + const struct aead_aes_gcm_siv_asm_ctx *key, + size_t in_len); + +// aes256gcmsiv_enc_msg_x4 acts like |aes128gcmsiv_enc_msg_x4|, but for +// AES-256. +extern void aes256gcmsiv_enc_msg_x4(const uint8_t *in, uint8_t *out, + const uint8_t *tag, + const struct aead_aes_gcm_siv_asm_ctx *key, + size_t in_len); + +// aes128gcmsiv_enc_msg_x8 acts like |aes128gcmsiv_enc_msg_x4|, but is +// optimised for longer messages. +extern void aes128gcmsiv_enc_msg_x8(const uint8_t *in, uint8_t *out, + const uint8_t *tag, + const struct aead_aes_gcm_siv_asm_ctx *key, + size_t in_len); + +// aes256gcmsiv_enc_msg_x8 acts like |aes256gcmsiv_enc_msg_x4|, but is +// optimised for longer messages. +extern void aes256gcmsiv_enc_msg_x8(const uint8_t *in, uint8_t *out, + const uint8_t *tag, + const struct aead_aes_gcm_siv_asm_ctx *key, + size_t in_len); + +// gcm_siv_asm_polyval evaluates POLYVAL at |auth_key| on the given plaintext +// and AD. The result is written to |out_tag|. +static void gcm_siv_asm_polyval(uint8_t out_tag[16], const uint8_t *in, + size_t in_len, const uint8_t *ad, size_t ad_len, + const uint8_t auth_key[16], + const uint8_t nonce[12]) { + OPENSSL_memset(out_tag, 0, 16); + const size_t ad_blocks = ad_len / 16; + const size_t in_blocks = in_len / 16; + int htable_init = 0; + alignas(16) uint8_t htable[16*8]; + + if (ad_blocks > 8 || in_blocks > 8) { + htable_init = 1; + aesgcmsiv_htable_init(htable, auth_key); + } + + if (htable_init) { + aesgcmsiv_htable_polyval(htable, ad, ad_len & ~15, out_tag); + } else { + aesgcmsiv_polyval_horner(out_tag, auth_key, ad, ad_blocks); + } + + uint8_t scratch[16]; + if (ad_len & 15) { + OPENSSL_memset(scratch, 0, sizeof(scratch)); + OPENSSL_memcpy(scratch, &ad[ad_len & ~15], ad_len & 15); + aesgcmsiv_polyval_horner(out_tag, auth_key, scratch, 1); + } + + if (htable_init) { + aesgcmsiv_htable_polyval(htable, in, in_len & ~15, out_tag); + } else { + aesgcmsiv_polyval_horner(out_tag, auth_key, in, in_blocks); + } + + if (in_len & 15) { + OPENSSL_memset(scratch, 0, sizeof(scratch)); + OPENSSL_memcpy(scratch, &in[in_len & ~15], in_len & 15); + aesgcmsiv_polyval_horner(out_tag, auth_key, scratch, 1); + } + + union { + uint8_t c[16]; + struct { + uint64_t ad; + uint64_t in; + } bitlens; + } length_block; + + length_block.bitlens.ad = ad_len * 8; + length_block.bitlens.in = in_len * 8; + aesgcmsiv_polyval_horner(out_tag, auth_key, length_block.c, 1); + + for (size_t i = 0; i < 12; i++) { + out_tag[i] ^= nonce[i]; + } + + out_tag[15] &= 0x7f; +} + +// aead_aes_gcm_siv_asm_crypt_last_block handles the encryption/decryption +// (same thing in CTR mode) of the final block of a plaintext/ciphertext. It +// writes |in_len| & 15 bytes to |out| + |in_len|, based on an initial counter +// derived from |tag|. +static void aead_aes_gcm_siv_asm_crypt_last_block( + int is_128_bit, uint8_t *out, const uint8_t *in, size_t in_len, + const uint8_t tag[16], + const struct aead_aes_gcm_siv_asm_ctx *enc_key_expanded) { + alignas(16) union { + uint8_t c[16]; + uint32_t u32[4]; + } counter; + OPENSSL_memcpy(&counter, tag, sizeof(counter)); + counter.c[15] |= 0x80; + counter.u32[0] += in_len / 16; + + if (is_128_bit) { + aes128gcmsiv_ecb_enc_block(&counter.c[0], &counter.c[0], enc_key_expanded); + } else { + aes256gcmsiv_ecb_enc_block(&counter.c[0], &counter.c[0], enc_key_expanded); + } + + const size_t last_bytes_offset = in_len & ~15; + const size_t last_bytes_len = in_len & 15; + uint8_t *last_bytes_out = &out[last_bytes_offset]; + const uint8_t *last_bytes_in = &in[last_bytes_offset]; + for (size_t i = 0; i < last_bytes_len; i++) { + last_bytes_out[i] = last_bytes_in[i] ^ counter.c[i]; + } +} + +// aead_aes_gcm_siv_kdf calculates the record encryption and authentication +// keys given the |nonce|. +static void aead_aes_gcm_siv_kdf( + int is_128_bit, const struct aead_aes_gcm_siv_asm_ctx *gcm_siv_ctx, + uint64_t out_record_auth_key[2], uint64_t out_record_enc_key[4], + const uint8_t nonce[12]) { + alignas(16) uint8_t padded_nonce[16]; + OPENSSL_memcpy(padded_nonce, nonce, 12); + + alignas(16) uint64_t key_material[12]; + if (is_128_bit) { + aes128gcmsiv_kdf(padded_nonce, key_material, &gcm_siv_ctx->key[0]); + out_record_enc_key[0] = key_material[4]; + out_record_enc_key[1] = key_material[6]; + } else { + aes256gcmsiv_kdf(padded_nonce, key_material, &gcm_siv_ctx->key[0]); + out_record_enc_key[0] = key_material[4]; + out_record_enc_key[1] = key_material[6]; + out_record_enc_key[2] = key_material[8]; + out_record_enc_key[3] = key_material[10]; + } + + out_record_auth_key[0] = key_material[0]; + out_record_auth_key[1] = key_material[2]; +} + +static int aead_aes_gcm_siv_asm_seal_scatter( + const EVP_AEAD_CTX *ctx, uint8_t *out, uint8_t *out_tag, + size_t *out_tag_len, size_t max_out_tag_len, const uint8_t *nonce, + size_t nonce_len, const uint8_t *in, size_t in_len, const uint8_t *extra_in, + size_t extra_in_len, const uint8_t *ad, size_t ad_len) { + const struct aead_aes_gcm_siv_asm_ctx *gcm_siv_ctx = ctx->aead_state; + const uint64_t in_len_64 = in_len; + const uint64_t ad_len_64 = ad_len; + + if (in_len_64 > (UINT64_C(1) << 36) || + ad_len_64 >= (UINT64_C(1) << 61)) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE); + return 0; + } + + if (max_out_tag_len < EVP_AEAD_AES_GCM_SIV_TAG_LEN) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL); + return 0; + } + + if (nonce_len != EVP_AEAD_AES_GCM_SIV_NONCE_LEN) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE); + return 0; + } + + alignas(16) uint64_t record_auth_key[2]; + alignas(16) uint64_t record_enc_key[4]; + aead_aes_gcm_siv_kdf(gcm_siv_ctx->is_128_bit, gcm_siv_ctx, record_auth_key, + record_enc_key, nonce); + + alignas(16) uint8_t tag[16] = {0}; + gcm_siv_asm_polyval(tag, in, in_len, ad, ad_len, + (const uint8_t *)record_auth_key, nonce); + + struct aead_aes_gcm_siv_asm_ctx enc_key_expanded; + + if (gcm_siv_ctx->is_128_bit) { + aes128gcmsiv_aes_ks_enc_x1(tag, tag, &enc_key_expanded.key[0], + record_enc_key); + + if (in_len < 128) { + aes128gcmsiv_enc_msg_x4(in, out, tag, &enc_key_expanded, in_len & ~15); + } else { + aes128gcmsiv_enc_msg_x8(in, out, tag, &enc_key_expanded, in_len & ~15); + } + } else { + aes256gcmsiv_aes_ks_enc_x1(tag, tag, &enc_key_expanded.key[0], + record_enc_key); + + if (in_len < 128) { + aes256gcmsiv_enc_msg_x4(in, out, tag, &enc_key_expanded, in_len & ~15); + } else { + aes256gcmsiv_enc_msg_x8(in, out, tag, &enc_key_expanded, in_len & ~15); + } + } + + if (in_len & 15) { + aead_aes_gcm_siv_asm_crypt_last_block(gcm_siv_ctx->is_128_bit, out, in, + in_len, tag, &enc_key_expanded); + } + + OPENSSL_memcpy(out_tag, tag, sizeof(tag)); + *out_tag_len = EVP_AEAD_AES_GCM_SIV_TAG_LEN; + + return 1; +} + +// TODO(martinkr): Add aead_aes_gcm_siv_asm_open_gather. N.B. aes128gcmsiv_dec +// expects ciphertext and tag in a contiguous buffer. + +static int aead_aes_gcm_siv_asm_open(const EVP_AEAD_CTX *ctx, uint8_t *out, + size_t *out_len, size_t max_out_len, + const uint8_t *nonce, size_t nonce_len, + const uint8_t *in, size_t in_len, + const uint8_t *ad, size_t ad_len) { + const uint64_t ad_len_64 = ad_len; + if (ad_len_64 >= (UINT64_C(1) << 61)) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE); + return 0; + } + + const uint64_t in_len_64 = in_len; + if (in_len < EVP_AEAD_AES_GCM_SIV_TAG_LEN || + in_len_64 > (UINT64_C(1) << 36) + AES_BLOCK_SIZE) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT); + return 0; + } + + const struct aead_aes_gcm_siv_asm_ctx *gcm_siv_ctx = ctx->aead_state; + const size_t plaintext_len = in_len - EVP_AEAD_AES_GCM_SIV_TAG_LEN; + const uint8_t *const given_tag = in + plaintext_len; + + if (max_out_len < plaintext_len) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL); + return 0; + } + + alignas(16) uint64_t record_auth_key[2]; + alignas(16) uint64_t record_enc_key[4]; + aead_aes_gcm_siv_kdf(gcm_siv_ctx->is_128_bit, gcm_siv_ctx, record_auth_key, + record_enc_key, nonce); + + struct aead_aes_gcm_siv_asm_ctx expanded_key; + if (gcm_siv_ctx->is_128_bit) { + aes128gcmsiv_aes_ks((const uint8_t *) record_enc_key, &expanded_key.key[0]); + } else { + aes256gcmsiv_aes_ks((const uint8_t *) record_enc_key, &expanded_key.key[0]); + } + // calculated_tag is 16*8 bytes, rather than 16 bytes, because + // aes[128|256]gcmsiv_dec uses the extra as scratch space. + alignas(16) uint8_t calculated_tag[16 * 8] = {0}; + + OPENSSL_memset(calculated_tag, 0, EVP_AEAD_AES_GCM_SIV_TAG_LEN); + const size_t ad_blocks = ad_len / 16; + aesgcmsiv_polyval_horner(calculated_tag, (const uint8_t *)record_auth_key, ad, + ad_blocks); + + uint8_t scratch[16]; + if (ad_len & 15) { + OPENSSL_memset(scratch, 0, sizeof(scratch)); + OPENSSL_memcpy(scratch, &ad[ad_len & ~15], ad_len & 15); + aesgcmsiv_polyval_horner(calculated_tag, (const uint8_t *)record_auth_key, + scratch, 1); + } + + alignas(16) uint8_t htable[16 * 6]; + aesgcmsiv_htable6_init(htable, (const uint8_t *)record_auth_key); + + if (gcm_siv_ctx->is_128_bit) { + aes128gcmsiv_dec(in, out, calculated_tag, htable, &expanded_key, + plaintext_len); + } else { + aes256gcmsiv_dec(in, out, calculated_tag, htable, &expanded_key, + plaintext_len); + } + + if (plaintext_len & 15) { + aead_aes_gcm_siv_asm_crypt_last_block(gcm_siv_ctx->is_128_bit, out, in, + plaintext_len, given_tag, + &expanded_key); + OPENSSL_memset(scratch, 0, sizeof(scratch)); + OPENSSL_memcpy(scratch, out + (plaintext_len & ~15), plaintext_len & 15); + aesgcmsiv_polyval_horner(calculated_tag, (const uint8_t *)record_auth_key, + scratch, 1); + } + + union { + uint8_t c[16]; + struct { + uint64_t ad; + uint64_t in; + } bitlens; + } length_block; + + length_block.bitlens.ad = ad_len * 8; + length_block.bitlens.in = plaintext_len * 8; + aesgcmsiv_polyval_horner(calculated_tag, (const uint8_t *)record_auth_key, + length_block.c, 1); + + for (size_t i = 0; i < 12; i++) { + calculated_tag[i] ^= nonce[i]; + } + + calculated_tag[15] &= 0x7f; + + if (gcm_siv_ctx->is_128_bit) { + aes128gcmsiv_ecb_enc_block(calculated_tag, calculated_tag, &expanded_key); + } else { + aes256gcmsiv_ecb_enc_block(calculated_tag, calculated_tag, &expanded_key); + } + + if (CRYPTO_memcmp(calculated_tag, given_tag, EVP_AEAD_AES_GCM_SIV_TAG_LEN) != + 0) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT); + return 0; + } + + *out_len = in_len - EVP_AEAD_AES_GCM_SIV_TAG_LEN; + return 1; +} + +static const EVP_AEAD aead_aes_128_gcm_siv_asm = { + 16, // key length + EVP_AEAD_AES_GCM_SIV_NONCE_LEN, // nonce length + EVP_AEAD_AES_GCM_SIV_TAG_LEN, // overhead + EVP_AEAD_AES_GCM_SIV_TAG_LEN, // max tag length + 0, // seal_scatter_supports_extra_in + + aead_aes_gcm_siv_asm_init, + NULL /* init_with_direction */, + aead_aes_gcm_siv_asm_cleanup, + aead_aes_gcm_siv_asm_open, + aead_aes_gcm_siv_asm_seal_scatter, + NULL /* open_gather */, + NULL /* get_iv */, + NULL /* tag_len */, +}; + +static const EVP_AEAD aead_aes_256_gcm_siv_asm = { + 32, // key length + EVP_AEAD_AES_GCM_SIV_NONCE_LEN, // nonce length + EVP_AEAD_AES_GCM_SIV_TAG_LEN, // overhead + EVP_AEAD_AES_GCM_SIV_TAG_LEN, // max tag length + 0, // seal_scatter_supports_extra_in + + aead_aes_gcm_siv_asm_init, + NULL /* init_with_direction */, + aead_aes_gcm_siv_asm_cleanup, + aead_aes_gcm_siv_asm_open, + aead_aes_gcm_siv_asm_seal_scatter, + NULL /* open_gather */, + NULL /* get_iv */, + NULL /* tag_len */, +}; + +#endif // X86_64 && !NO_ASM + +struct aead_aes_gcm_siv_ctx { + union { + double align; + AES_KEY ks; + } ks; + block128_f kgk_block; + unsigned is_256:1; +}; + +static int aead_aes_gcm_siv_init(EVP_AEAD_CTX *ctx, const uint8_t *key, + size_t key_len, size_t tag_len) { + const size_t key_bits = key_len * 8; + + if (key_bits != 128 && key_bits != 256) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_KEY_LENGTH); + return 0; // EVP_AEAD_CTX_init should catch this. + } + + if (tag_len == EVP_AEAD_DEFAULT_TAG_LENGTH) { + tag_len = EVP_AEAD_AES_GCM_SIV_TAG_LEN; + } + if (tag_len != EVP_AEAD_AES_GCM_SIV_TAG_LEN) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TAG_TOO_LARGE); + return 0; + } + + struct aead_aes_gcm_siv_ctx *gcm_siv_ctx = + OPENSSL_malloc(sizeof(struct aead_aes_gcm_siv_ctx)); + if (gcm_siv_ctx == NULL) { + return 0; + } + OPENSSL_memset(gcm_siv_ctx, 0, sizeof(struct aead_aes_gcm_siv_ctx)); + + aes_ctr_set_key(&gcm_siv_ctx->ks.ks, NULL, &gcm_siv_ctx->kgk_block, key, + key_len); + gcm_siv_ctx->is_256 = (key_len == 32); + ctx->aead_state = gcm_siv_ctx; + ctx->tag_len = tag_len; + + return 1; +} + +static void aead_aes_gcm_siv_cleanup(EVP_AEAD_CTX *ctx) { + OPENSSL_free(ctx->aead_state); +} + +// gcm_siv_crypt encrypts (or decrypts—it's the same thing) |in_len| bytes from +// |in| to |out|, using the block function |enc_block| with |key| in counter +// mode, starting at |initial_counter|. This differs from the traditional +// counter mode code in that the counter is handled little-endian, only the +// first four bytes are used and the GCM-SIV tweak to the final byte is +// applied. The |in| and |out| pointers may be equal but otherwise must not +// alias. +static void gcm_siv_crypt(uint8_t *out, const uint8_t *in, size_t in_len, + const uint8_t initial_counter[AES_BLOCK_SIZE], + block128_f enc_block, const AES_KEY *key) { + union { + uint32_t w[4]; + uint8_t c[16]; + } counter; + + OPENSSL_memcpy(counter.c, initial_counter, AES_BLOCK_SIZE); + counter.c[15] |= 0x80; + + for (size_t done = 0; done < in_len;) { + uint8_t keystream[AES_BLOCK_SIZE]; + enc_block(counter.c, keystream, key); + counter.w[0]++; + + size_t todo = AES_BLOCK_SIZE; + if (in_len - done < todo) { + todo = in_len - done; + } + + for (size_t i = 0; i < todo; i++) { + out[done + i] = keystream[i] ^ in[done + i]; + } + + done += todo; + } +} + +// gcm_siv_polyval evaluates POLYVAL at |auth_key| on the given plaintext and +// AD. The result is written to |out_tag|. +static void gcm_siv_polyval( + uint8_t out_tag[16], const uint8_t *in, size_t in_len, const uint8_t *ad, + size_t ad_len, const uint8_t auth_key[16], + const uint8_t nonce[EVP_AEAD_AES_GCM_SIV_NONCE_LEN]) { + struct polyval_ctx polyval_ctx; + CRYPTO_POLYVAL_init(&polyval_ctx, auth_key); + + CRYPTO_POLYVAL_update_blocks(&polyval_ctx, ad, ad_len & ~15); + + uint8_t scratch[16]; + if (ad_len & 15) { + OPENSSL_memset(scratch, 0, sizeof(scratch)); + OPENSSL_memcpy(scratch, &ad[ad_len & ~15], ad_len & 15); + CRYPTO_POLYVAL_update_blocks(&polyval_ctx, scratch, sizeof(scratch)); + } + + CRYPTO_POLYVAL_update_blocks(&polyval_ctx, in, in_len & ~15); + if (in_len & 15) { + OPENSSL_memset(scratch, 0, sizeof(scratch)); + OPENSSL_memcpy(scratch, &in[in_len & ~15], in_len & 15); + CRYPTO_POLYVAL_update_blocks(&polyval_ctx, scratch, sizeof(scratch)); + } + + union { + uint8_t c[16]; + struct { + uint64_t ad; + uint64_t in; + } bitlens; + } length_block; + + length_block.bitlens.ad = ad_len * 8; + length_block.bitlens.in = in_len * 8; + CRYPTO_POLYVAL_update_blocks(&polyval_ctx, length_block.c, + sizeof(length_block)); + + CRYPTO_POLYVAL_finish(&polyval_ctx, out_tag); + for (size_t i = 0; i < EVP_AEAD_AES_GCM_SIV_NONCE_LEN; i++) { + out_tag[i] ^= nonce[i]; + } + out_tag[15] &= 0x7f; +} + +// gcm_siv_record_keys contains the keys used for a specific GCM-SIV record. +struct gcm_siv_record_keys { + uint8_t auth_key[16]; + union { + double align; + AES_KEY ks; + } enc_key; + block128_f enc_block; +}; + +// gcm_siv_keys calculates the keys for a specific GCM-SIV record with the +// given nonce and writes them to |*out_keys|. +static void gcm_siv_keys( + const struct aead_aes_gcm_siv_ctx *gcm_siv_ctx, + struct gcm_siv_record_keys *out_keys, + const uint8_t nonce[EVP_AEAD_AES_GCM_SIV_NONCE_LEN]) { + const AES_KEY *const key = &gcm_siv_ctx->ks.ks; + uint8_t key_material[(128 /* POLYVAL key */ + 256 /* max AES key */) / 8]; + const size_t blocks_needed = gcm_siv_ctx->is_256 ? 6 : 4; + + uint8_t counter[AES_BLOCK_SIZE]; + OPENSSL_memset(counter, 0, AES_BLOCK_SIZE - EVP_AEAD_AES_GCM_SIV_NONCE_LEN); + OPENSSL_memcpy(counter + AES_BLOCK_SIZE - EVP_AEAD_AES_GCM_SIV_NONCE_LEN, + nonce, EVP_AEAD_AES_GCM_SIV_NONCE_LEN); + for (size_t i = 0; i < blocks_needed; i++) { + counter[0] = i; + + uint8_t ciphertext[AES_BLOCK_SIZE]; + gcm_siv_ctx->kgk_block(counter, ciphertext, key); + OPENSSL_memcpy(&key_material[i * 8], ciphertext, 8); + } + + OPENSSL_memcpy(out_keys->auth_key, key_material, 16); + aes_ctr_set_key(&out_keys->enc_key.ks, NULL, &out_keys->enc_block, + key_material + 16, gcm_siv_ctx->is_256 ? 32 : 16); +} + +static int aead_aes_gcm_siv_seal_scatter( + const EVP_AEAD_CTX *ctx, uint8_t *out, uint8_t *out_tag, + size_t *out_tag_len, size_t max_out_tag_len, const uint8_t *nonce, + size_t nonce_len, const uint8_t *in, size_t in_len, const uint8_t *extra_in, + size_t extra_in_len, const uint8_t *ad, size_t ad_len) { + const struct aead_aes_gcm_siv_ctx *gcm_siv_ctx = ctx->aead_state; + const uint64_t in_len_64 = in_len; + const uint64_t ad_len_64 = ad_len; + + if (in_len + EVP_AEAD_AES_GCM_SIV_TAG_LEN < in_len || + in_len_64 > (UINT64_C(1) << 36) || + ad_len_64 >= (UINT64_C(1) << 61)) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE); + return 0; + } + + if (max_out_tag_len < EVP_AEAD_AES_GCM_SIV_TAG_LEN) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL); + return 0; + } + + if (nonce_len != EVP_AEAD_AES_GCM_SIV_NONCE_LEN) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE); + return 0; + } + + struct gcm_siv_record_keys keys; + gcm_siv_keys(gcm_siv_ctx, &keys, nonce); + + uint8_t tag[16]; + gcm_siv_polyval(tag, in, in_len, ad, ad_len, keys.auth_key, nonce); + keys.enc_block(tag, tag, &keys.enc_key.ks); + + gcm_siv_crypt(out, in, in_len, tag, keys.enc_block, &keys.enc_key.ks); + + OPENSSL_memcpy(out_tag, tag, EVP_AEAD_AES_GCM_SIV_TAG_LEN); + *out_tag_len = EVP_AEAD_AES_GCM_SIV_TAG_LEN; + + return 1; +} + +static int aead_aes_gcm_siv_open_gather(const EVP_AEAD_CTX *ctx, uint8_t *out, + const uint8_t *nonce, size_t nonce_len, + const uint8_t *in, size_t in_len, + const uint8_t *in_tag, + size_t in_tag_len, const uint8_t *ad, + size_t ad_len) { + const uint64_t ad_len_64 = ad_len; + if (ad_len_64 >= (UINT64_C(1) << 61)) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE); + return 0; + } + + const uint64_t in_len_64 = in_len; + if (in_tag_len != EVP_AEAD_AES_GCM_SIV_TAG_LEN || + in_len_64 > (UINT64_C(1) << 36) + AES_BLOCK_SIZE) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT); + return 0; + } + + if (nonce_len != EVP_AEAD_AES_GCM_SIV_NONCE_LEN) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE); + return 0; + } + + const struct aead_aes_gcm_siv_ctx *gcm_siv_ctx = ctx->aead_state; + + struct gcm_siv_record_keys keys; + gcm_siv_keys(gcm_siv_ctx, &keys, nonce); + + gcm_siv_crypt(out, in, in_len, in_tag, keys.enc_block, &keys.enc_key.ks); + + uint8_t expected_tag[EVP_AEAD_AES_GCM_SIV_TAG_LEN]; + gcm_siv_polyval(expected_tag, out, in_len, ad, ad_len, keys.auth_key, nonce); + keys.enc_block(expected_tag, expected_tag, &keys.enc_key.ks); + + if (CRYPTO_memcmp(expected_tag, in_tag, sizeof(expected_tag)) != 0) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT); + return 0; + } + + return 1; +} + +static const EVP_AEAD aead_aes_128_gcm_siv = { + 16, // key length + EVP_AEAD_AES_GCM_SIV_NONCE_LEN, // nonce length + EVP_AEAD_AES_GCM_SIV_TAG_LEN, // overhead + EVP_AEAD_AES_GCM_SIV_TAG_LEN, // max tag length + 0, // seal_scatter_supports_extra_in + + aead_aes_gcm_siv_init, + NULL /* init_with_direction */, + aead_aes_gcm_siv_cleanup, + NULL /* open */, + aead_aes_gcm_siv_seal_scatter, + aead_aes_gcm_siv_open_gather, + NULL /* get_iv */, + NULL /* tag_len */, +}; + +static const EVP_AEAD aead_aes_256_gcm_siv = { + 32, // key length + EVP_AEAD_AES_GCM_SIV_NONCE_LEN, // nonce length + EVP_AEAD_AES_GCM_SIV_TAG_LEN, // overhead + EVP_AEAD_AES_GCM_SIV_TAG_LEN, // max tag length + 0, // seal_scatter_supports_extra_in + + aead_aes_gcm_siv_init, + NULL /* init_with_direction */, + aead_aes_gcm_siv_cleanup, + NULL /* open */, + aead_aes_gcm_siv_seal_scatter, + aead_aes_gcm_siv_open_gather, + NULL /* get_iv */, + NULL /* tag_len */, +}; + +#if defined(OPENSSL_X86_64) && !defined(OPENSSL_NO_ASM) + +static char avx_aesni_capable(void) { + const uint32_t ecx = OPENSSL_ia32cap_P[1]; + + return (ecx & (1 << (57 - 32))) != 0 /* AESNI */ && + (ecx & (1 << 28)) != 0 /* AVX */; +} + +const EVP_AEAD *EVP_aead_aes_128_gcm_siv(void) { + if (avx_aesni_capable()) { + return &aead_aes_128_gcm_siv_asm; + } + return &aead_aes_128_gcm_siv; +} + +const EVP_AEAD *EVP_aead_aes_256_gcm_siv(void) { + if (avx_aesni_capable()) { + return &aead_aes_256_gcm_siv_asm; + } + return &aead_aes_256_gcm_siv; +} + +#else + +const EVP_AEAD *EVP_aead_aes_128_gcm_siv(void) { + return &aead_aes_128_gcm_siv; +} + +const EVP_AEAD *EVP_aead_aes_256_gcm_siv(void) { + return &aead_aes_256_gcm_siv; +} + +#endif // X86_64 && !NO_ASM diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/cipher_extra/e_chacha20poly1305.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/cipher_extra/e_chacha20poly1305.c new file mode 100644 index 0000000..fb81ba0 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/cipher_extra/e_chacha20poly1305.c @@ -0,0 +1,326 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "../fipsmodule/cipher/internal.h" +#include "../internal.h" + + +#define POLY1305_TAG_LEN 16 + +struct aead_chacha20_poly1305_ctx { + uint8_t key[32]; +}; + +// For convenience (the x86_64 calling convention allows only six parameters in +// registers), the final parameter for the assembly functions is both an input +// and output parameter. +union open_data { + struct { + alignas(16) uint8_t key[32]; + uint32_t counter; + uint8_t nonce[12]; + } in; + struct { + uint8_t tag[POLY1305_TAG_LEN]; + } out; +}; + +union seal_data { + struct { + alignas(16) uint8_t key[32]; + uint32_t counter; + uint8_t nonce[12]; + const uint8_t *extra_ciphertext; + size_t extra_ciphertext_len; + } in; + struct { + uint8_t tag[POLY1305_TAG_LEN]; + } out; +}; + +#if defined(OPENSSL_X86_64) && !defined(OPENSSL_NO_ASM) && \ + !defined(OPENSSL_WINDOWS) +static int asm_capable(void) { + const int sse41_capable = (OPENSSL_ia32cap_P[1] & (1 << 19)) != 0; + return sse41_capable; +} + +OPENSSL_COMPILE_ASSERT(sizeof(union open_data) == 48, wrong_open_data_size); +OPENSSL_COMPILE_ASSERT(sizeof(union seal_data) == 48 + 8 + 8, + wrong_seal_data_size); + +// chacha20_poly1305_open is defined in chacha20_poly1305_x86_64.pl. It decrypts +// |plaintext_len| bytes from |ciphertext| and writes them to |out_plaintext|. +// Additional input parameters are passed in |aead_data->in|. On exit, it will +// write calculated tag value to |aead_data->out.tag|, which the caller must +// check. +extern void chacha20_poly1305_open(uint8_t *out_plaintext, + const uint8_t *ciphertext, + size_t plaintext_len, const uint8_t *ad, + size_t ad_len, union open_data *aead_data); + +// chacha20_poly1305_open is defined in chacha20_poly1305_x86_64.pl. It encrypts +// |plaintext_len| bytes from |plaintext| and writes them to |out_ciphertext|. +// Additional input parameters are passed in |aead_data->in|. The calculated tag +// value is over the computed ciphertext concatenated with |extra_ciphertext| +// and written to |aead_data->out.tag|. +extern void chacha20_poly1305_seal(uint8_t *out_ciphertext, + const uint8_t *plaintext, + size_t plaintext_len, const uint8_t *ad, + size_t ad_len, union seal_data *aead_data); +#else +static int asm_capable(void) { return 0; } + + +static void chacha20_poly1305_open(uint8_t *out_plaintext, + const uint8_t *ciphertext, + size_t plaintext_len, const uint8_t *ad, + size_t ad_len, union open_data *aead_data) {} + +static void chacha20_poly1305_seal(uint8_t *out_ciphertext, + const uint8_t *plaintext, + size_t plaintext_len, const uint8_t *ad, + size_t ad_len, union seal_data *aead_data) {} +#endif + +static int aead_chacha20_poly1305_init(EVP_AEAD_CTX *ctx, const uint8_t *key, + size_t key_len, size_t tag_len) { + struct aead_chacha20_poly1305_ctx *c20_ctx; + + if (tag_len == 0) { + tag_len = POLY1305_TAG_LEN; + } + + if (tag_len > POLY1305_TAG_LEN) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE); + return 0; + } + + if (key_len != sizeof(c20_ctx->key)) { + return 0; // internal error - EVP_AEAD_CTX_init should catch this. + } + + c20_ctx = OPENSSL_malloc(sizeof(struct aead_chacha20_poly1305_ctx)); + if (c20_ctx == NULL) { + return 0; + } + + OPENSSL_memcpy(c20_ctx->key, key, key_len); + ctx->aead_state = c20_ctx; + ctx->tag_len = tag_len; + + return 1; +} + +static void aead_chacha20_poly1305_cleanup(EVP_AEAD_CTX *ctx) { + OPENSSL_free(ctx->aead_state); +} + +static void poly1305_update_length(poly1305_state *poly1305, size_t data_len) { + uint8_t length_bytes[8]; + + for (unsigned i = 0; i < sizeof(length_bytes); i++) { + length_bytes[i] = data_len; + data_len >>= 8; + } + + CRYPTO_poly1305_update(poly1305, length_bytes, sizeof(length_bytes)); +} + +// calc_tag fills |tag| with the authentication tag for the given inputs. +static void calc_tag(uint8_t tag[POLY1305_TAG_LEN], + const struct aead_chacha20_poly1305_ctx *c20_ctx, + const uint8_t nonce[12], const uint8_t *ad, size_t ad_len, + const uint8_t *ciphertext, size_t ciphertext_len, + const uint8_t *ciphertext_extra, + size_t ciphertext_extra_len) { + alignas(16) uint8_t poly1305_key[32]; + OPENSSL_memset(poly1305_key, 0, sizeof(poly1305_key)); + CRYPTO_chacha_20(poly1305_key, poly1305_key, sizeof(poly1305_key), + c20_ctx->key, nonce, 0); + + static const uint8_t padding[16] = { 0 }; // Padding is all zeros. + poly1305_state ctx; + CRYPTO_poly1305_init(&ctx, poly1305_key); + CRYPTO_poly1305_update(&ctx, ad, ad_len); + if (ad_len % 16 != 0) { + CRYPTO_poly1305_update(&ctx, padding, sizeof(padding) - (ad_len % 16)); + } + CRYPTO_poly1305_update(&ctx, ciphertext, ciphertext_len); + CRYPTO_poly1305_update(&ctx, ciphertext_extra, ciphertext_extra_len); + const size_t ciphertext_total = ciphertext_len + ciphertext_extra_len; + if (ciphertext_total % 16 != 0) { + CRYPTO_poly1305_update(&ctx, padding, + sizeof(padding) - (ciphertext_total % 16)); + } + poly1305_update_length(&ctx, ad_len); + poly1305_update_length(&ctx, ciphertext_total); + CRYPTO_poly1305_finish(&ctx, tag); +} + +static int aead_chacha20_poly1305_seal_scatter( + const EVP_AEAD_CTX *ctx, uint8_t *out, uint8_t *out_tag, + size_t *out_tag_len, size_t max_out_tag_len, const uint8_t *nonce, + size_t nonce_len, const uint8_t *in, size_t in_len, const uint8_t *extra_in, + size_t extra_in_len, const uint8_t *ad, size_t ad_len) { + const struct aead_chacha20_poly1305_ctx *c20_ctx = ctx->aead_state; + + if (extra_in_len + ctx->tag_len < ctx->tag_len) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE); + return 0; + } + if (max_out_tag_len < ctx->tag_len + extra_in_len) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL); + return 0; + } + if (nonce_len != 12) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE); + return 0; + } + + // |CRYPTO_chacha_20| uses a 32-bit block counter. Therefore we disallow + // individual operations that work on more than 256GB at a time. + // |in_len_64| is needed because, on 32-bit platforms, size_t is only + // 32-bits and this produces a warning because it's always false. + // Casting to uint64_t inside the conditional is not sufficient to stop + // the warning. + const uint64_t in_len_64 = in_len; + if (in_len_64 >= (UINT64_C(1) << 32) * 64 - 64) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE); + return 0; + } + + if (max_out_tag_len < ctx->tag_len) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL); + return 0; + } + + // The the extra input is given, it is expected to be very short and so is + // encrypted byte-by-byte first. + if (extra_in_len) { + static const size_t kChaChaBlockSize = 64; + uint32_t block_counter = 1 + (in_len / kChaChaBlockSize); + size_t offset = in_len % kChaChaBlockSize; + uint8_t block[64 /* kChaChaBlockSize */]; + + for (size_t done = 0; done < extra_in_len; block_counter++) { + memset(block, 0, sizeof(block)); + CRYPTO_chacha_20(block, block, sizeof(block), c20_ctx->key, nonce, + block_counter); + for (size_t i = offset; i < sizeof(block) && done < extra_in_len; + i++, done++) { + out_tag[done] = extra_in[done] ^ block[i]; + } + offset = 0; + } + } + + union seal_data data; + if (asm_capable()) { + OPENSSL_memcpy(data.in.key, c20_ctx->key, 32); + data.in.counter = 0; + OPENSSL_memcpy(data.in.nonce, nonce, 12); + data.in.extra_ciphertext = out_tag; + data.in.extra_ciphertext_len = extra_in_len; + chacha20_poly1305_seal(out, in, in_len, ad, ad_len, &data); + } else { + CRYPTO_chacha_20(out, in, in_len, c20_ctx->key, nonce, 1); + calc_tag(data.out.tag, c20_ctx, nonce, ad, ad_len, out, in_len, out_tag, + extra_in_len); + } + + OPENSSL_memcpy(out_tag + extra_in_len, data.out.tag, ctx->tag_len); + *out_tag_len = extra_in_len + ctx->tag_len; + return 1; +} + +static int aead_chacha20_poly1305_open_gather( + const EVP_AEAD_CTX *ctx, uint8_t *out, const uint8_t *nonce, + size_t nonce_len, const uint8_t *in, size_t in_len, const uint8_t *in_tag, + size_t in_tag_len, const uint8_t *ad, size_t ad_len) { + const struct aead_chacha20_poly1305_ctx *c20_ctx = ctx->aead_state; + + if (nonce_len != 12) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE); + return 0; + } + + if (in_tag_len != ctx->tag_len) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT); + return 0; + } + + // |CRYPTO_chacha_20| uses a 32-bit block counter. Therefore we disallow + // individual operations that work on more than 256GB at a time. + // |in_len_64| is needed because, on 32-bit platforms, size_t is only + // 32-bits and this produces a warning because it's always false. + // Casting to uint64_t inside the conditional is not sufficient to stop + // the warning. + const uint64_t in_len_64 = in_len; + if (in_len_64 >= (UINT64_C(1) << 32) * 64 - 64) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE); + return 0; + } + + union open_data data; + if (asm_capable()) { + OPENSSL_memcpy(data.in.key, c20_ctx->key, 32); + data.in.counter = 0; + OPENSSL_memcpy(data.in.nonce, nonce, 12); + chacha20_poly1305_open(out, in, in_len, ad, ad_len, &data); + } else { + calc_tag(data.out.tag, c20_ctx, nonce, ad, ad_len, in, in_len, NULL, 0); + CRYPTO_chacha_20(out, in, in_len, c20_ctx->key, nonce, 1); + } + + if (CRYPTO_memcmp(data.out.tag, in_tag, ctx->tag_len) != 0) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT); + return 0; + } + + return 1; +} + +static const EVP_AEAD aead_chacha20_poly1305 = { + 32, // key len + 12, // nonce len + POLY1305_TAG_LEN, // overhead + POLY1305_TAG_LEN, // max tag length + 1, // seal_scatter_supports_extra_in + + aead_chacha20_poly1305_init, + NULL, // init_with_direction + aead_chacha20_poly1305_cleanup, + NULL /* open */, + aead_chacha20_poly1305_seal_scatter, + aead_chacha20_poly1305_open_gather, + NULL, // get_iv + NULL, // tag_len +}; + +const EVP_AEAD *EVP_aead_chacha20_poly1305(void) { + return &aead_chacha20_poly1305; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/cipher_extra/e_chacha20poly1305.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/cipher_extra/e_chacha20poly1305.c.grpc_back new file mode 100644 index 0000000..64ab457 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/cipher_extra/e_chacha20poly1305.c.grpc_back @@ -0,0 +1,326 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "../fipsmodule/cipher/internal.h" +#include "../internal.h" + + +#define POLY1305_TAG_LEN 16 + +struct aead_chacha20_poly1305_ctx { + uint8_t key[32]; +}; + +// For convenience (the x86_64 calling convention allows only six parameters in +// registers), the final parameter for the assembly functions is both an input +// and output parameter. +union open_data { + struct { + alignas(16) uint8_t key[32]; + uint32_t counter; + uint8_t nonce[12]; + } in; + struct { + uint8_t tag[POLY1305_TAG_LEN]; + } out; +}; + +union seal_data { + struct { + alignas(16) uint8_t key[32]; + uint32_t counter; + uint8_t nonce[12]; + const uint8_t *extra_ciphertext; + size_t extra_ciphertext_len; + } in; + struct { + uint8_t tag[POLY1305_TAG_LEN]; + } out; +}; + +#if defined(OPENSSL_X86_64) && !defined(OPENSSL_NO_ASM) && \ + !defined(OPENSSL_WINDOWS) +static int asm_capable(void) { + const int sse41_capable = (OPENSSL_ia32cap_P[1] & (1 << 19)) != 0; + return sse41_capable; +} + +OPENSSL_COMPILE_ASSERT(sizeof(union open_data) == 48, wrong_open_data_size); +OPENSSL_COMPILE_ASSERT(sizeof(union seal_data) == 48 + 8 + 8, + wrong_seal_data_size); + +// chacha20_poly1305_open is defined in chacha20_poly1305_x86_64.pl. It decrypts +// |plaintext_len| bytes from |ciphertext| and writes them to |out_plaintext|. +// Additional input parameters are passed in |aead_data->in|. On exit, it will +// write calculated tag value to |aead_data->out.tag|, which the caller must +// check. +extern void chacha20_poly1305_open(uint8_t *out_plaintext, + const uint8_t *ciphertext, + size_t plaintext_len, const uint8_t *ad, + size_t ad_len, union open_data *aead_data); + +// chacha20_poly1305_open is defined in chacha20_poly1305_x86_64.pl. It encrypts +// |plaintext_len| bytes from |plaintext| and writes them to |out_ciphertext|. +// Additional input parameters are passed in |aead_data->in|. The calculated tag +// value is over the computed ciphertext concatenated with |extra_ciphertext| +// and written to |aead_data->out.tag|. +extern void chacha20_poly1305_seal(uint8_t *out_ciphertext, + const uint8_t *plaintext, + size_t plaintext_len, const uint8_t *ad, + size_t ad_len, union seal_data *aead_data); +#else +static int asm_capable(void) { return 0; } + + +static void chacha20_poly1305_open(uint8_t *out_plaintext, + const uint8_t *ciphertext, + size_t plaintext_len, const uint8_t *ad, + size_t ad_len, union open_data *aead_data) {} + +static void chacha20_poly1305_seal(uint8_t *out_ciphertext, + const uint8_t *plaintext, + size_t plaintext_len, const uint8_t *ad, + size_t ad_len, union seal_data *aead_data) {} +#endif + +static int aead_chacha20_poly1305_init(EVP_AEAD_CTX *ctx, const uint8_t *key, + size_t key_len, size_t tag_len) { + struct aead_chacha20_poly1305_ctx *c20_ctx; + + if (tag_len == 0) { + tag_len = POLY1305_TAG_LEN; + } + + if (tag_len > POLY1305_TAG_LEN) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE); + return 0; + } + + if (key_len != sizeof(c20_ctx->key)) { + return 0; // internal error - EVP_AEAD_CTX_init should catch this. + } + + c20_ctx = OPENSSL_malloc(sizeof(struct aead_chacha20_poly1305_ctx)); + if (c20_ctx == NULL) { + return 0; + } + + OPENSSL_memcpy(c20_ctx->key, key, key_len); + ctx->aead_state = c20_ctx; + ctx->tag_len = tag_len; + + return 1; +} + +static void aead_chacha20_poly1305_cleanup(EVP_AEAD_CTX *ctx) { + OPENSSL_free(ctx->aead_state); +} + +static void poly1305_update_length(poly1305_state *poly1305, size_t data_len) { + uint8_t length_bytes[8]; + + for (unsigned i = 0; i < sizeof(length_bytes); i++) { + length_bytes[i] = data_len; + data_len >>= 8; + } + + CRYPTO_poly1305_update(poly1305, length_bytes, sizeof(length_bytes)); +} + +// calc_tag fills |tag| with the authentication tag for the given inputs. +static void calc_tag(uint8_t tag[POLY1305_TAG_LEN], + const struct aead_chacha20_poly1305_ctx *c20_ctx, + const uint8_t nonce[12], const uint8_t *ad, size_t ad_len, + const uint8_t *ciphertext, size_t ciphertext_len, + const uint8_t *ciphertext_extra, + size_t ciphertext_extra_len) { + alignas(16) uint8_t poly1305_key[32]; + OPENSSL_memset(poly1305_key, 0, sizeof(poly1305_key)); + CRYPTO_chacha_20(poly1305_key, poly1305_key, sizeof(poly1305_key), + c20_ctx->key, nonce, 0); + + static const uint8_t padding[16] = { 0 }; // Padding is all zeros. + poly1305_state ctx; + CRYPTO_poly1305_init(&ctx, poly1305_key); + CRYPTO_poly1305_update(&ctx, ad, ad_len); + if (ad_len % 16 != 0) { + CRYPTO_poly1305_update(&ctx, padding, sizeof(padding) - (ad_len % 16)); + } + CRYPTO_poly1305_update(&ctx, ciphertext, ciphertext_len); + CRYPTO_poly1305_update(&ctx, ciphertext_extra, ciphertext_extra_len); + const size_t ciphertext_total = ciphertext_len + ciphertext_extra_len; + if (ciphertext_total % 16 != 0) { + CRYPTO_poly1305_update(&ctx, padding, + sizeof(padding) - (ciphertext_total % 16)); + } + poly1305_update_length(&ctx, ad_len); + poly1305_update_length(&ctx, ciphertext_total); + CRYPTO_poly1305_finish(&ctx, tag); +} + +static int aead_chacha20_poly1305_seal_scatter( + const EVP_AEAD_CTX *ctx, uint8_t *out, uint8_t *out_tag, + size_t *out_tag_len, size_t max_out_tag_len, const uint8_t *nonce, + size_t nonce_len, const uint8_t *in, size_t in_len, const uint8_t *extra_in, + size_t extra_in_len, const uint8_t *ad, size_t ad_len) { + const struct aead_chacha20_poly1305_ctx *c20_ctx = ctx->aead_state; + + if (extra_in_len + ctx->tag_len < ctx->tag_len) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE); + return 0; + } + if (max_out_tag_len < ctx->tag_len + extra_in_len) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL); + return 0; + } + if (nonce_len != 12) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE); + return 0; + } + + // |CRYPTO_chacha_20| uses a 32-bit block counter. Therefore we disallow + // individual operations that work on more than 256GB at a time. + // |in_len_64| is needed because, on 32-bit platforms, size_t is only + // 32-bits and this produces a warning because it's always false. + // Casting to uint64_t inside the conditional is not sufficient to stop + // the warning. + const uint64_t in_len_64 = in_len; + if (in_len_64 >= (UINT64_C(1) << 32) * 64 - 64) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE); + return 0; + } + + if (max_out_tag_len < ctx->tag_len) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL); + return 0; + } + + // The the extra input is given, it is expected to be very short and so is + // encrypted byte-by-byte first. + if (extra_in_len) { + static const size_t kChaChaBlockSize = 64; + uint32_t block_counter = 1 + (in_len / kChaChaBlockSize); + size_t offset = in_len % kChaChaBlockSize; + uint8_t block[64 /* kChaChaBlockSize */]; + + for (size_t done = 0; done < extra_in_len; block_counter++) { + memset(block, 0, sizeof(block)); + CRYPTO_chacha_20(block, block, sizeof(block), c20_ctx->key, nonce, + block_counter); + for (size_t i = offset; i < sizeof(block) && done < extra_in_len; + i++, done++) { + out_tag[done] = extra_in[done] ^ block[i]; + } + offset = 0; + } + } + + union seal_data data; + if (asm_capable()) { + OPENSSL_memcpy(data.in.key, c20_ctx->key, 32); + data.in.counter = 0; + OPENSSL_memcpy(data.in.nonce, nonce, 12); + data.in.extra_ciphertext = out_tag; + data.in.extra_ciphertext_len = extra_in_len; + chacha20_poly1305_seal(out, in, in_len, ad, ad_len, &data); + } else { + CRYPTO_chacha_20(out, in, in_len, c20_ctx->key, nonce, 1); + calc_tag(data.out.tag, c20_ctx, nonce, ad, ad_len, out, in_len, out_tag, + extra_in_len); + } + + OPENSSL_memcpy(out_tag + extra_in_len, data.out.tag, ctx->tag_len); + *out_tag_len = extra_in_len + ctx->tag_len; + return 1; +} + +static int aead_chacha20_poly1305_open_gather( + const EVP_AEAD_CTX *ctx, uint8_t *out, const uint8_t *nonce, + size_t nonce_len, const uint8_t *in, size_t in_len, const uint8_t *in_tag, + size_t in_tag_len, const uint8_t *ad, size_t ad_len) { + const struct aead_chacha20_poly1305_ctx *c20_ctx = ctx->aead_state; + + if (nonce_len != 12) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE); + return 0; + } + + if (in_tag_len != ctx->tag_len) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT); + return 0; + } + + // |CRYPTO_chacha_20| uses a 32-bit block counter. Therefore we disallow + // individual operations that work on more than 256GB at a time. + // |in_len_64| is needed because, on 32-bit platforms, size_t is only + // 32-bits and this produces a warning because it's always false. + // Casting to uint64_t inside the conditional is not sufficient to stop + // the warning. + const uint64_t in_len_64 = in_len; + if (in_len_64 >= (UINT64_C(1) << 32) * 64 - 64) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE); + return 0; + } + + union open_data data; + if (asm_capable()) { + OPENSSL_memcpy(data.in.key, c20_ctx->key, 32); + data.in.counter = 0; + OPENSSL_memcpy(data.in.nonce, nonce, 12); + chacha20_poly1305_open(out, in, in_len, ad, ad_len, &data); + } else { + calc_tag(data.out.tag, c20_ctx, nonce, ad, ad_len, in, in_len, NULL, 0); + CRYPTO_chacha_20(out, in, in_len, c20_ctx->key, nonce, 1); + } + + if (CRYPTO_memcmp(data.out.tag, in_tag, ctx->tag_len) != 0) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT); + return 0; + } + + return 1; +} + +static const EVP_AEAD aead_chacha20_poly1305 = { + 32, // key len + 12, // nonce len + POLY1305_TAG_LEN, // overhead + POLY1305_TAG_LEN, // max tag length + 1, // seal_scatter_supports_extra_in + + aead_chacha20_poly1305_init, + NULL, // init_with_direction + aead_chacha20_poly1305_cleanup, + NULL /* open */, + aead_chacha20_poly1305_seal_scatter, + aead_chacha20_poly1305_open_gather, + NULL, // get_iv + NULL, // tag_len +}; + +const EVP_AEAD *EVP_aead_chacha20_poly1305(void) { + return &aead_chacha20_poly1305; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/cipher_extra/e_null.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/cipher_extra/e_null.c new file mode 100644 index 0000000..3822dc3 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/cipher_extra/e_null.c @@ -0,0 +1,85 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 "../internal.h" + + +static int null_init_key(EVP_CIPHER_CTX *ctx, const uint8_t *key, + const uint8_t *iv, int enc) { + return 1; +} + +static int null_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, + const uint8_t *in, size_t in_len) { + if (in != out) { + OPENSSL_memcpy(out, in, in_len); + } + return 1; +} + +static const EVP_CIPHER n_cipher = { + NID_undef, 1 /* block size */, 0 /* key_len */, 0 /* iv_len */, + 0 /* ctx_size */, 0 /* flags */, NULL /* app_data */, null_init_key, + null_cipher, NULL /* cleanup */, NULL /* ctrl */, +}; + +const EVP_CIPHER *EVP_enc_null(void) { return &n_cipher; } diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/cipher_extra/e_null.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/cipher_extra/e_null.c.grpc_back new file mode 100644 index 0000000..f5fe8fb --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/cipher_extra/e_null.c.grpc_back @@ -0,0 +1,85 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 "../internal.h" + + +static int null_init_key(EVP_CIPHER_CTX *ctx, const uint8_t *key, + const uint8_t *iv, int enc) { + return 1; +} + +static int null_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, + const uint8_t *in, size_t in_len) { + if (in != out) { + OPENSSL_memcpy(out, in, in_len); + } + return 1; +} + +static const EVP_CIPHER n_cipher = { + NID_undef, 1 /* block size */, 0 /* key_len */, 0 /* iv_len */, + 0 /* ctx_size */, 0 /* flags */, NULL /* app_data */, null_init_key, + null_cipher, NULL /* cleanup */, NULL /* ctrl */, +}; + +const EVP_CIPHER *EVP_enc_null(void) { return &n_cipher; } diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/cipher_extra/e_rc2.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/cipher_extra/e_rc2.c new file mode 100644 index 0000000..c9f789a --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/cipher_extra/e_rc2.c @@ -0,0 +1,462 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 "../internal.h" + + +#define c2l(c, l) \ + do { \ + (l) = ((uint32_t)(*((c)++))); \ + (l) |= ((uint32_t)(*((c)++))) << 8L; \ + (l) |= ((uint32_t)(*((c)++))) << 16L; \ + (l) |= ((uint32_t)(*((c)++))) << 24L; \ + } while (0) + +#define c2ln(c, l1, l2, n) \ + do { \ + (c) += (n); \ + (l1) = (l2) = 0; \ + switch (n) { \ + case 8: \ + (l2) = ((uint32_t)(*(--(c)))) << 24L; \ + OPENSSL_FALLTHROUGH; \ + case 7: \ + (l2) |= ((uint32_t)(*(--(c)))) << 16L; \ + OPENSSL_FALLTHROUGH; \ + case 6: \ + (l2) |= ((uint32_t)(*(--(c)))) << 8L; \ + OPENSSL_FALLTHROUGH; \ + case 5: \ + (l2) |= ((uint32_t)(*(--(c)))); \ + OPENSSL_FALLTHROUGH; \ + case 4: \ + (l1) = ((uint32_t)(*(--(c)))) << 24L; \ + OPENSSL_FALLTHROUGH; \ + case 3: \ + (l1) |= ((uint32_t)(*(--(c)))) << 16L; \ + OPENSSL_FALLTHROUGH; \ + case 2: \ + (l1) |= ((uint32_t)(*(--(c)))) << 8L; \ + OPENSSL_FALLTHROUGH; \ + case 1: \ + (l1) |= ((uint32_t)(*(--(c)))); \ + } \ + } while (0) + +#define l2c(l, c) \ + do { \ + *((c)++) = (uint8_t)(((l)) & 0xff); \ + *((c)++) = (uint8_t)(((l) >> 8L) & 0xff); \ + *((c)++) = (uint8_t)(((l) >> 16L) & 0xff); \ + *((c)++) = (uint8_t)(((l) >> 24L) & 0xff); \ + } while (0) + +#define l2cn(l1, l2, c, n) \ + do { \ + (c) += (n); \ + switch (n) { \ + case 8: \ + *(--(c)) = (uint8_t)(((l2) >> 24L) & 0xff); \ + OPENSSL_FALLTHROUGH; \ + case 7: \ + *(--(c)) = (uint8_t)(((l2) >> 16L) & 0xff); \ + OPENSSL_FALLTHROUGH; \ + case 6: \ + *(--(c)) = (uint8_t)(((l2) >> 8L) & 0xff); \ + OPENSSL_FALLTHROUGH; \ + case 5: \ + *(--(c)) = (uint8_t)(((l2)) & 0xff); \ + OPENSSL_FALLTHROUGH; \ + case 4: \ + *(--(c)) = (uint8_t)(((l1) >> 24L) & 0xff); \ + OPENSSL_FALLTHROUGH; \ + case 3: \ + *(--(c)) = (uint8_t)(((l1) >> 16L) & 0xff); \ + OPENSSL_FALLTHROUGH; \ + case 2: \ + *(--(c)) = (uint8_t)(((l1) >> 8L) & 0xff); \ + OPENSSL_FALLTHROUGH; \ + case 1: \ + *(--(c)) = (uint8_t)(((l1)) & 0xff); \ + } \ + } while (0) + +typedef struct rc2_key_st { uint16_t data[64]; } RC2_KEY; + +static void RC2_encrypt(uint32_t *d, RC2_KEY *key) { + int i, n; + uint16_t *p0, *p1; + uint16_t x0, x1, x2, x3, t; + uint32_t l; + + l = d[0]; + x0 = (uint16_t)l & 0xffff; + x1 = (uint16_t)(l >> 16L); + l = d[1]; + x2 = (uint16_t)l & 0xffff; + x3 = (uint16_t)(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] = (uint32_t)(x0 & 0xffff) | ((uint32_t)(x1 & 0xffff) << 16L); + d[1] = (uint32_t)(x2 & 0xffff) | ((uint32_t)(x3 & 0xffff) << 16L); +} + +static void RC2_decrypt(uint32_t *d, RC2_KEY *key) { + int i, n; + uint16_t *p0, *p1; + uint16_t x0, x1, x2, x3, t; + uint32_t l; + + l = d[0]; + x0 = (uint16_t)l & 0xffff; + x1 = (uint16_t)(l >> 16L); + l = d[1]; + x2 = (uint16_t)l & 0xffff; + x3 = (uint16_t)(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] = (uint32_t)(x0 & 0xffff) | ((uint32_t)(x1 & 0xffff) << 16L); + d[1] = (uint32_t)(x2 & 0xffff) | ((uint32_t)(x3 & 0xffff) << 16L); +} + +static void RC2_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t length, + RC2_KEY *ks, uint8_t *iv, int encrypt) { + uint32_t tin0, tin1; + uint32_t tout0, tout1, xor0, xor1; + long l = length; + uint32_t 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); + } + tin[0] = tin[1] = 0; +} + +static const uint8_t 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, +}; + +static void RC2_set_key(RC2_KEY *key, int len, const uint8_t *data, int bits) { + int i, j; + uint8_t *k; + uint16_t *ki; + unsigned int c, d; + + k = (uint8_t *)&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 uint16_t's + ki = &(key->data[63]); + for (i = 127; i >= 0; i -= 2) { + *(ki--) = ((k[i] << 8) | k[i - 1]) & 0xffff; + } +} + +typedef struct { + int key_bits; // effective key bits + RC2_KEY ks; // key schedule +} EVP_RC2_KEY; + +static int rc2_init_key(EVP_CIPHER_CTX *ctx, const uint8_t *key, + const uint8_t *iv, int enc) { + EVP_RC2_KEY *rc2_key = (EVP_RC2_KEY *)ctx->cipher_data; + RC2_set_key(&rc2_key->ks, EVP_CIPHER_CTX_key_length(ctx), key, + rc2_key->key_bits); + return 1; +} + +static int rc2_cbc_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in, + size_t inl) { + EVP_RC2_KEY *key = (EVP_RC2_KEY *)ctx->cipher_data; + static const size_t kChunkSize = 0x10000; + + while (inl >= kChunkSize) { + RC2_cbc_encrypt(in, out, kChunkSize, &key->ks, ctx->iv, ctx->encrypt); + inl -= kChunkSize; + in += kChunkSize; + out += kChunkSize; + } + if (inl) { + RC2_cbc_encrypt(in, out, inl, &key->ks, ctx->iv, ctx->encrypt); + } + return 1; +} + +static int rc2_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr) { + EVP_RC2_KEY *key = (EVP_RC2_KEY *)ctx->cipher_data; + + switch (type) { + case EVP_CTRL_INIT: + key->key_bits = EVP_CIPHER_CTX_key_length(ctx) * 8; + return 1; + case EVP_CTRL_SET_RC2_KEY_BITS: + // Should be overridden by later call to |EVP_CTRL_INIT|, but + // people call it, so it may as well work. + key->key_bits = arg; + return 1; + + default: + return -1; + } +} + +static const EVP_CIPHER rc2_40_cbc = { + NID_rc2_40_cbc, + 8 /* block size */, + 5 /* 40 bit */, + 8 /* iv len */, + sizeof(EVP_RC2_KEY), + EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT, + NULL /* app_data */, + rc2_init_key, + rc2_cbc_cipher, + NULL, + rc2_ctrl, +}; + +const EVP_CIPHER *EVP_rc2_40_cbc(void) { + return &rc2_40_cbc; +} + +static const EVP_CIPHER rc2_cbc = { + NID_rc2_cbc, + 8 /* block size */, + 16 /* 128 bit */, + 8 /* iv len */, + sizeof(EVP_RC2_KEY), + EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT, + NULL /* app_data */, + rc2_init_key, + rc2_cbc_cipher, + NULL, + rc2_ctrl, +}; + +const EVP_CIPHER *EVP_rc2_cbc(void) { + return &rc2_cbc; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/cipher_extra/e_rc2.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/cipher_extra/e_rc2.c.grpc_back new file mode 100644 index 0000000..221a9c9 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/cipher_extra/e_rc2.c.grpc_back @@ -0,0 +1,462 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 "../internal.h" + + +#define c2l(c, l) \ + do { \ + (l) = ((uint32_t)(*((c)++))); \ + (l) |= ((uint32_t)(*((c)++))) << 8L; \ + (l) |= ((uint32_t)(*((c)++))) << 16L; \ + (l) |= ((uint32_t)(*((c)++))) << 24L; \ + } while (0) + +#define c2ln(c, l1, l2, n) \ + do { \ + (c) += (n); \ + (l1) = (l2) = 0; \ + switch (n) { \ + case 8: \ + (l2) = ((uint32_t)(*(--(c)))) << 24L; \ + OPENSSL_FALLTHROUGH; \ + case 7: \ + (l2) |= ((uint32_t)(*(--(c)))) << 16L; \ + OPENSSL_FALLTHROUGH; \ + case 6: \ + (l2) |= ((uint32_t)(*(--(c)))) << 8L; \ + OPENSSL_FALLTHROUGH; \ + case 5: \ + (l2) |= ((uint32_t)(*(--(c)))); \ + OPENSSL_FALLTHROUGH; \ + case 4: \ + (l1) = ((uint32_t)(*(--(c)))) << 24L; \ + OPENSSL_FALLTHROUGH; \ + case 3: \ + (l1) |= ((uint32_t)(*(--(c)))) << 16L; \ + OPENSSL_FALLTHROUGH; \ + case 2: \ + (l1) |= ((uint32_t)(*(--(c)))) << 8L; \ + OPENSSL_FALLTHROUGH; \ + case 1: \ + (l1) |= ((uint32_t)(*(--(c)))); \ + } \ + } while (0) + +#define l2c(l, c) \ + do { \ + *((c)++) = (uint8_t)(((l)) & 0xff); \ + *((c)++) = (uint8_t)(((l) >> 8L) & 0xff); \ + *((c)++) = (uint8_t)(((l) >> 16L) & 0xff); \ + *((c)++) = (uint8_t)(((l) >> 24L) & 0xff); \ + } while (0) + +#define l2cn(l1, l2, c, n) \ + do { \ + (c) += (n); \ + switch (n) { \ + case 8: \ + *(--(c)) = (uint8_t)(((l2) >> 24L) & 0xff); \ + OPENSSL_FALLTHROUGH; \ + case 7: \ + *(--(c)) = (uint8_t)(((l2) >> 16L) & 0xff); \ + OPENSSL_FALLTHROUGH; \ + case 6: \ + *(--(c)) = (uint8_t)(((l2) >> 8L) & 0xff); \ + OPENSSL_FALLTHROUGH; \ + case 5: \ + *(--(c)) = (uint8_t)(((l2)) & 0xff); \ + OPENSSL_FALLTHROUGH; \ + case 4: \ + *(--(c)) = (uint8_t)(((l1) >> 24L) & 0xff); \ + OPENSSL_FALLTHROUGH; \ + case 3: \ + *(--(c)) = (uint8_t)(((l1) >> 16L) & 0xff); \ + OPENSSL_FALLTHROUGH; \ + case 2: \ + *(--(c)) = (uint8_t)(((l1) >> 8L) & 0xff); \ + OPENSSL_FALLTHROUGH; \ + case 1: \ + *(--(c)) = (uint8_t)(((l1)) & 0xff); \ + } \ + } while (0) + +typedef struct rc2_key_st { uint16_t data[64]; } RC2_KEY; + +static void RC2_encrypt(uint32_t *d, RC2_KEY *key) { + int i, n; + uint16_t *p0, *p1; + uint16_t x0, x1, x2, x3, t; + uint32_t l; + + l = d[0]; + x0 = (uint16_t)l & 0xffff; + x1 = (uint16_t)(l >> 16L); + l = d[1]; + x2 = (uint16_t)l & 0xffff; + x3 = (uint16_t)(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] = (uint32_t)(x0 & 0xffff) | ((uint32_t)(x1 & 0xffff) << 16L); + d[1] = (uint32_t)(x2 & 0xffff) | ((uint32_t)(x3 & 0xffff) << 16L); +} + +static void RC2_decrypt(uint32_t *d, RC2_KEY *key) { + int i, n; + uint16_t *p0, *p1; + uint16_t x0, x1, x2, x3, t; + uint32_t l; + + l = d[0]; + x0 = (uint16_t)l & 0xffff; + x1 = (uint16_t)(l >> 16L); + l = d[1]; + x2 = (uint16_t)l & 0xffff; + x3 = (uint16_t)(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] = (uint32_t)(x0 & 0xffff) | ((uint32_t)(x1 & 0xffff) << 16L); + d[1] = (uint32_t)(x2 & 0xffff) | ((uint32_t)(x3 & 0xffff) << 16L); +} + +static void RC2_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t length, + RC2_KEY *ks, uint8_t *iv, int encrypt) { + uint32_t tin0, tin1; + uint32_t tout0, tout1, xor0, xor1; + long l = length; + uint32_t 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); + } + tin[0] = tin[1] = 0; +} + +static const uint8_t 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, +}; + +static void RC2_set_key(RC2_KEY *key, int len, const uint8_t *data, int bits) { + int i, j; + uint8_t *k; + uint16_t *ki; + unsigned int c, d; + + k = (uint8_t *)&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 uint16_t's + ki = &(key->data[63]); + for (i = 127; i >= 0; i -= 2) { + *(ki--) = ((k[i] << 8) | k[i - 1]) & 0xffff; + } +} + +typedef struct { + int key_bits; // effective key bits + RC2_KEY ks; // key schedule +} EVP_RC2_KEY; + +static int rc2_init_key(EVP_CIPHER_CTX *ctx, const uint8_t *key, + const uint8_t *iv, int enc) { + EVP_RC2_KEY *rc2_key = (EVP_RC2_KEY *)ctx->cipher_data; + RC2_set_key(&rc2_key->ks, EVP_CIPHER_CTX_key_length(ctx), key, + rc2_key->key_bits); + return 1; +} + +static int rc2_cbc_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in, + size_t inl) { + EVP_RC2_KEY *key = (EVP_RC2_KEY *)ctx->cipher_data; + static const size_t kChunkSize = 0x10000; + + while (inl >= kChunkSize) { + RC2_cbc_encrypt(in, out, kChunkSize, &key->ks, ctx->iv, ctx->encrypt); + inl -= kChunkSize; + in += kChunkSize; + out += kChunkSize; + } + if (inl) { + RC2_cbc_encrypt(in, out, inl, &key->ks, ctx->iv, ctx->encrypt); + } + return 1; +} + +static int rc2_ctrl(EVP_CIPHER_CTX *ctx, int type, int arg, void *ptr) { + EVP_RC2_KEY *key = (EVP_RC2_KEY *)ctx->cipher_data; + + switch (type) { + case EVP_CTRL_INIT: + key->key_bits = EVP_CIPHER_CTX_key_length(ctx) * 8; + return 1; + case EVP_CTRL_SET_RC2_KEY_BITS: + // Should be overridden by later call to |EVP_CTRL_INIT|, but + // people call it, so it may as well work. + key->key_bits = arg; + return 1; + + default: + return -1; + } +} + +static const EVP_CIPHER rc2_40_cbc = { + NID_rc2_40_cbc, + 8 /* block size */, + 5 /* 40 bit */, + 8 /* iv len */, + sizeof(EVP_RC2_KEY), + EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT, + NULL /* app_data */, + rc2_init_key, + rc2_cbc_cipher, + NULL, + rc2_ctrl, +}; + +const EVP_CIPHER *EVP_rc2_40_cbc(void) { + return &rc2_40_cbc; +} + +static const EVP_CIPHER rc2_cbc = { + NID_rc2_cbc, + 8 /* block size */, + 16 /* 128 bit */, + 8 /* iv len */, + sizeof(EVP_RC2_KEY), + EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_CTRL_INIT, + NULL /* app_data */, + rc2_init_key, + rc2_cbc_cipher, + NULL, + rc2_ctrl, +}; + +const EVP_CIPHER *EVP_rc2_cbc(void) { + return &rc2_cbc; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/cipher_extra/e_rc4.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/cipher_extra/e_rc4.c new file mode 100644 index 0000000..47af272 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/cipher_extra/e_rc4.c @@ -0,0 +1,87 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 + + +static int rc4_init_key(EVP_CIPHER_CTX *ctx, const uint8_t *key, + const uint8_t *iv, int enc) { + RC4_KEY *rc4key = (RC4_KEY *)ctx->cipher_data; + + RC4_set_key(rc4key, EVP_CIPHER_CTX_key_length(ctx), key); + return 1; +} + +static int rc4_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in, + size_t in_len) { + RC4_KEY *rc4key = (RC4_KEY *)ctx->cipher_data; + + RC4(rc4key, in_len, in, out); + return 1; +} + +static const EVP_CIPHER rc4 = { + NID_rc4, 1 /* block_size */, 16 /* key_size */, + 0 /* iv_len */, sizeof(RC4_KEY), EVP_CIPH_VARIABLE_LENGTH, + NULL /* app_data */, rc4_init_key, rc4_cipher, + NULL /* cleanup */, NULL /* ctrl */, }; + +const EVP_CIPHER *EVP_rc4(void) { return &rc4; } diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/cipher_extra/e_rc4.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/cipher_extra/e_rc4.c.grpc_back new file mode 100644 index 0000000..e7c2cca --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/cipher_extra/e_rc4.c.grpc_back @@ -0,0 +1,87 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 + + +static int rc4_init_key(EVP_CIPHER_CTX *ctx, const uint8_t *key, + const uint8_t *iv, int enc) { + RC4_KEY *rc4key = (RC4_KEY *)ctx->cipher_data; + + RC4_set_key(rc4key, EVP_CIPHER_CTX_key_length(ctx), key); + return 1; +} + +static int rc4_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in, + size_t in_len) { + RC4_KEY *rc4key = (RC4_KEY *)ctx->cipher_data; + + RC4(rc4key, in_len, in, out); + return 1; +} + +static const EVP_CIPHER rc4 = { + NID_rc4, 1 /* block_size */, 16 /* key_size */, + 0 /* iv_len */, sizeof(RC4_KEY), EVP_CIPH_VARIABLE_LENGTH, + NULL /* app_data */, rc4_init_key, rc4_cipher, + NULL /* cleanup */, NULL /* ctrl */, }; + +const EVP_CIPHER *EVP_rc4(void) { return &rc4; } diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/cipher_extra/e_ssl3.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/cipher_extra/e_ssl3.c new file mode 100644 index 0000000..a4464e8 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/cipher_extra/e_ssl3.c @@ -0,0 +1,460 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "internal.h" +#include "../internal.h" +#include "../fipsmodule/cipher/internal.h" + + +typedef struct { + EVP_CIPHER_CTX cipher_ctx; + EVP_MD_CTX md_ctx; +} AEAD_SSL3_CTX; + +static int ssl3_mac(AEAD_SSL3_CTX *ssl3_ctx, uint8_t *out, unsigned *out_len, + const uint8_t *ad, size_t ad_len, const uint8_t *in, + size_t in_len) { + size_t md_size = EVP_MD_CTX_size(&ssl3_ctx->md_ctx); + size_t pad_len = (md_size == 20) ? 40 : 48; + + // To allow for CBC mode which changes cipher length, |ad| doesn't include the + // length for legacy ciphers. + uint8_t ad_extra[2]; + ad_extra[0] = (uint8_t)(in_len >> 8); + ad_extra[1] = (uint8_t)(in_len & 0xff); + + EVP_MD_CTX md_ctx; + EVP_MD_CTX_init(&md_ctx); + + uint8_t pad[48]; + uint8_t tmp[EVP_MAX_MD_SIZE]; + OPENSSL_memset(pad, 0x36, pad_len); + if (!EVP_MD_CTX_copy_ex(&md_ctx, &ssl3_ctx->md_ctx) || + !EVP_DigestUpdate(&md_ctx, pad, pad_len) || + !EVP_DigestUpdate(&md_ctx, ad, ad_len) || + !EVP_DigestUpdate(&md_ctx, ad_extra, sizeof(ad_extra)) || + !EVP_DigestUpdate(&md_ctx, in, in_len) || + !EVP_DigestFinal_ex(&md_ctx, tmp, NULL)) { + EVP_MD_CTX_cleanup(&md_ctx); + return 0; + } + + OPENSSL_memset(pad, 0x5c, pad_len); + if (!EVP_MD_CTX_copy_ex(&md_ctx, &ssl3_ctx->md_ctx) || + !EVP_DigestUpdate(&md_ctx, pad, pad_len) || + !EVP_DigestUpdate(&md_ctx, tmp, md_size) || + !EVP_DigestFinal_ex(&md_ctx, out, out_len)) { + EVP_MD_CTX_cleanup(&md_ctx); + return 0; + } + EVP_MD_CTX_cleanup(&md_ctx); + return 1; +} + +static void aead_ssl3_cleanup(EVP_AEAD_CTX *ctx) { + AEAD_SSL3_CTX *ssl3_ctx = (AEAD_SSL3_CTX *)ctx->aead_state; + EVP_CIPHER_CTX_cleanup(&ssl3_ctx->cipher_ctx); + EVP_MD_CTX_cleanup(&ssl3_ctx->md_ctx); + OPENSSL_free(ssl3_ctx); + ctx->aead_state = NULL; +} + +static int aead_ssl3_init(EVP_AEAD_CTX *ctx, const uint8_t *key, size_t key_len, + size_t tag_len, enum evp_aead_direction_t dir, + const EVP_CIPHER *cipher, const EVP_MD *md) { + if (tag_len != EVP_AEAD_DEFAULT_TAG_LENGTH && + tag_len != EVP_MD_size(md)) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_TAG_SIZE); + return 0; + } + + if (key_len != EVP_AEAD_key_length(ctx->aead)) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_KEY_LENGTH); + return 0; + } + + size_t mac_key_len = EVP_MD_size(md); + size_t enc_key_len = EVP_CIPHER_key_length(cipher); + assert(mac_key_len + enc_key_len + EVP_CIPHER_iv_length(cipher) == key_len); + + AEAD_SSL3_CTX *ssl3_ctx = OPENSSL_malloc(sizeof(AEAD_SSL3_CTX)); + if (ssl3_ctx == NULL) { + OPENSSL_PUT_ERROR(CIPHER, ERR_R_MALLOC_FAILURE); + return 0; + } + EVP_CIPHER_CTX_init(&ssl3_ctx->cipher_ctx); + EVP_MD_CTX_init(&ssl3_ctx->md_ctx); + + ctx->aead_state = ssl3_ctx; + if (!EVP_CipherInit_ex(&ssl3_ctx->cipher_ctx, cipher, NULL, &key[mac_key_len], + &key[mac_key_len + enc_key_len], + dir == evp_aead_seal) || + !EVP_DigestInit_ex(&ssl3_ctx->md_ctx, md, NULL) || + !EVP_DigestUpdate(&ssl3_ctx->md_ctx, key, mac_key_len)) { + aead_ssl3_cleanup(ctx); + ctx->aead_state = NULL; + return 0; + } + EVP_CIPHER_CTX_set_padding(&ssl3_ctx->cipher_ctx, 0); + + return 1; +} + +static size_t aead_ssl3_tag_len(const EVP_AEAD_CTX *ctx, const size_t in_len, + const size_t extra_in_len) { + assert(extra_in_len == 0); + const AEAD_SSL3_CTX *ssl3_ctx = (AEAD_SSL3_CTX*)ctx->aead_state; + + const size_t digest_len = EVP_MD_CTX_size(&ssl3_ctx->md_ctx); + if (EVP_CIPHER_CTX_mode(&ssl3_ctx->cipher_ctx) != EVP_CIPH_CBC_MODE) { + // The NULL cipher. + return digest_len; + } + + const size_t block_size = EVP_CIPHER_CTX_block_size(&ssl3_ctx->cipher_ctx); + // An overflow of |in_len + digest_len| doesn't affect the result mod + // |block_size|, provided that |block_size| is a smaller power of two. + assert(block_size != 0 && (block_size & (block_size - 1)) == 0); + const size_t pad_len = block_size - ((in_len + digest_len) % block_size); + return digest_len + pad_len; +} + +static int aead_ssl3_seal_scatter(const EVP_AEAD_CTX *ctx, uint8_t *out, + uint8_t *out_tag, size_t *out_tag_len, + const size_t max_out_tag_len, + const uint8_t *nonce, const size_t nonce_len, + const uint8_t *in, const size_t in_len, + const uint8_t *extra_in, + const size_t extra_in_len, const uint8_t *ad, + const size_t ad_len) { + AEAD_SSL3_CTX *ssl3_ctx = (AEAD_SSL3_CTX *)ctx->aead_state; + + if (!ssl3_ctx->cipher_ctx.encrypt) { + // Unlike a normal AEAD, an SSL3 AEAD may only be used in one direction. + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_OPERATION); + return 0; + } + + if (in_len > INT_MAX) { + // EVP_CIPHER takes int as input. + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE); + return 0; + } + + if (max_out_tag_len < aead_ssl3_tag_len(ctx, in_len, extra_in_len)) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL); + return 0; + } + + if (nonce_len != 0) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_IV_TOO_LARGE); + return 0; + } + + if (ad_len != 11 - 2 /* length bytes */) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_AD_SIZE); + return 0; + } + + // Compute the MAC. This must be first in case the operation is being done + // in-place. + uint8_t mac[EVP_MAX_MD_SIZE]; + unsigned mac_len; + if (!ssl3_mac(ssl3_ctx, mac, &mac_len, ad, ad_len, in, in_len)) { + return 0; + } + + // Encrypt the input. + int len; + if (!EVP_EncryptUpdate(&ssl3_ctx->cipher_ctx, out, &len, in, + (int)in_len)) { + return 0; + } + + const size_t block_size = EVP_CIPHER_CTX_block_size(&ssl3_ctx->cipher_ctx); + + // Feed the MAC into the cipher in two steps. First complete the final partial + // block from encrypting the input and split the result between |out| and + // |out_tag|. Then encrypt the remainder. + + size_t early_mac_len = (block_size - (in_len % block_size)) % block_size; + if (early_mac_len != 0) { + assert(len + block_size - early_mac_len == in_len); + uint8_t buf[EVP_MAX_BLOCK_LENGTH]; + int buf_len; + if (!EVP_EncryptUpdate(&ssl3_ctx->cipher_ctx, buf, &buf_len, mac, + (int)early_mac_len)) { + return 0; + } + assert(buf_len == (int)block_size); + OPENSSL_memcpy(out + len, buf, block_size - early_mac_len); + OPENSSL_memcpy(out_tag, buf + block_size - early_mac_len, early_mac_len); + } + size_t tag_len = early_mac_len; + + if (!EVP_EncryptUpdate(&ssl3_ctx->cipher_ctx, out_tag + tag_len, &len, + mac + tag_len, mac_len - tag_len)) { + return 0; + } + tag_len += len; + + if (block_size > 1) { + assert(block_size <= 256); + assert(EVP_CIPHER_CTX_mode(&ssl3_ctx->cipher_ctx) == EVP_CIPH_CBC_MODE); + + // Compute padding and feed that into the cipher. + uint8_t padding[256]; + size_t padding_len = block_size - ((in_len + mac_len) % block_size); + OPENSSL_memset(padding, 0, padding_len - 1); + padding[padding_len - 1] = padding_len - 1; + if (!EVP_EncryptUpdate(&ssl3_ctx->cipher_ctx, out_tag + tag_len, &len, padding, + (int)padding_len)) { + return 0; + } + tag_len += len; + } + + if (!EVP_EncryptFinal_ex(&ssl3_ctx->cipher_ctx, out_tag + tag_len, &len)) { + return 0; + } + tag_len += len; + assert(tag_len == aead_ssl3_tag_len(ctx, in_len, extra_in_len)); + + *out_tag_len = tag_len; + return 1; +} + +static int aead_ssl3_open(const EVP_AEAD_CTX *ctx, uint8_t *out, + size_t *out_len, size_t max_out_len, + const uint8_t *nonce, size_t nonce_len, + const uint8_t *in, size_t in_len, + const uint8_t *ad, size_t ad_len) { + AEAD_SSL3_CTX *ssl3_ctx = (AEAD_SSL3_CTX *)ctx->aead_state; + + if (ssl3_ctx->cipher_ctx.encrypt) { + // Unlike a normal AEAD, an SSL3 AEAD may only be used in one direction. + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_OPERATION); + return 0; + } + + size_t mac_len = EVP_MD_CTX_size(&ssl3_ctx->md_ctx); + if (in_len < mac_len) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT); + return 0; + } + + if (max_out_len < in_len) { + // This requires that the caller provide space for the MAC, even though it + // will always be removed on return. + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL); + return 0; + } + + if (nonce_len != 0) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE); + return 0; + } + + if (ad_len != 11 - 2 /* length bytes */) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_AD_SIZE); + return 0; + } + + if (in_len > INT_MAX) { + // EVP_CIPHER takes int as input. + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE); + return 0; + } + + // Decrypt to get the plaintext + MAC + padding. + size_t total = 0; + int len; + if (!EVP_DecryptUpdate(&ssl3_ctx->cipher_ctx, out, &len, in, (int)in_len)) { + return 0; + } + total += len; + if (!EVP_DecryptFinal_ex(&ssl3_ctx->cipher_ctx, out + total, &len)) { + return 0; + } + total += len; + assert(total == in_len); + + // Remove CBC padding and MAC. This would normally be timing-sensitive, but + // SSLv3 CBC ciphers are already broken. Support will be removed eventually. + // https://www.openssl.org/~bodo/ssl-poodle.pdf + size_t data_len; + if (EVP_CIPHER_CTX_mode(&ssl3_ctx->cipher_ctx) == EVP_CIPH_CBC_MODE) { + unsigned padding_length = out[total - 1]; + if (total < padding_length + 1 + mac_len) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT); + return 0; + } + // The padding must be minimal. + if (padding_length + 1 > EVP_CIPHER_CTX_block_size(&ssl3_ctx->cipher_ctx)) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT); + return 0; + } + data_len = total - padding_length - 1 - mac_len; + } else { + data_len = total - mac_len; + } + + // Compute the MAC and compare against the one in the record. + uint8_t mac[EVP_MAX_MD_SIZE]; + if (!ssl3_mac(ssl3_ctx, mac, NULL, ad, ad_len, out, data_len)) { + return 0; + } + if (CRYPTO_memcmp(&out[data_len], mac, mac_len) != 0) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT); + return 0; + } + + *out_len = data_len; + return 1; +} + +static int aead_ssl3_get_iv(const EVP_AEAD_CTX *ctx, const uint8_t **out_iv, + size_t *out_iv_len) { + AEAD_SSL3_CTX *ssl3_ctx = (AEAD_SSL3_CTX *)ctx->aead_state; + const size_t iv_len = EVP_CIPHER_CTX_iv_length(&ssl3_ctx->cipher_ctx); + if (iv_len <= 1) { + return 0; + } + + *out_iv = ssl3_ctx->cipher_ctx.iv; + *out_iv_len = iv_len; + return 1; +} + +static int aead_aes_128_cbc_sha1_ssl3_init(EVP_AEAD_CTX *ctx, const uint8_t *key, + size_t key_len, size_t tag_len, + enum evp_aead_direction_t dir) { + return aead_ssl3_init(ctx, key, key_len, tag_len, dir, EVP_aes_128_cbc(), + EVP_sha1()); +} + +static int aead_aes_256_cbc_sha1_ssl3_init(EVP_AEAD_CTX *ctx, const uint8_t *key, + size_t key_len, size_t tag_len, + enum evp_aead_direction_t dir) { + return aead_ssl3_init(ctx, key, key_len, tag_len, dir, EVP_aes_256_cbc(), + EVP_sha1()); +} +static int aead_des_ede3_cbc_sha1_ssl3_init(EVP_AEAD_CTX *ctx, + const uint8_t *key, size_t key_len, + size_t tag_len, + enum evp_aead_direction_t dir) { + return aead_ssl3_init(ctx, key, key_len, tag_len, dir, EVP_des_ede3_cbc(), + EVP_sha1()); +} + +static int aead_null_sha1_ssl3_init(EVP_AEAD_CTX *ctx, const uint8_t *key, + size_t key_len, size_t tag_len, + enum evp_aead_direction_t dir) { + return aead_ssl3_init(ctx, key, key_len, tag_len, dir, EVP_enc_null(), + EVP_sha1()); +} + +static const EVP_AEAD aead_aes_128_cbc_sha1_ssl3 = { + SHA_DIGEST_LENGTH + 16 + 16, // key len (SHA1 + AES128 + IV) + 0, // nonce len + 16 + SHA_DIGEST_LENGTH, // overhead (padding + SHA1) + SHA_DIGEST_LENGTH, // max tag length + 0, // seal_scatter_supports_extra_in + + NULL, // init + aead_aes_128_cbc_sha1_ssl3_init, + aead_ssl3_cleanup, + aead_ssl3_open, + aead_ssl3_seal_scatter, + NULL, // open_gather + aead_ssl3_get_iv, + aead_ssl3_tag_len, +}; + +static const EVP_AEAD aead_aes_256_cbc_sha1_ssl3 = { + SHA_DIGEST_LENGTH + 32 + 16, // key len (SHA1 + AES256 + IV) + 0, // nonce len + 16 + SHA_DIGEST_LENGTH, // overhead (padding + SHA1) + SHA_DIGEST_LENGTH, // max tag length + 0, // seal_scatter_supports_extra_in + + NULL, // init + aead_aes_256_cbc_sha1_ssl3_init, + aead_ssl3_cleanup, + aead_ssl3_open, + aead_ssl3_seal_scatter, + NULL, // open_gather + aead_ssl3_get_iv, + aead_ssl3_tag_len, +}; + +static const EVP_AEAD aead_des_ede3_cbc_sha1_ssl3 = { + SHA_DIGEST_LENGTH + 24 + 8, // key len (SHA1 + 3DES + IV) + 0, // nonce len + 8 + SHA_DIGEST_LENGTH, // overhead (padding + SHA1) + SHA_DIGEST_LENGTH, // max tag length + 0, // seal_scatter_supports_extra_in + + NULL, // init + aead_des_ede3_cbc_sha1_ssl3_init, + aead_ssl3_cleanup, + aead_ssl3_open, + aead_ssl3_seal_scatter, + NULL, // open_gather + aead_ssl3_get_iv, + aead_ssl3_tag_len, +}; + +static const EVP_AEAD aead_null_sha1_ssl3 = { + SHA_DIGEST_LENGTH, // key len + 0, // nonce len + SHA_DIGEST_LENGTH, // overhead (SHA1) + SHA_DIGEST_LENGTH, // max tag length + 0, // seal_scatter_supports_extra_in + + NULL, // init + aead_null_sha1_ssl3_init, + aead_ssl3_cleanup, + aead_ssl3_open, + aead_ssl3_seal_scatter, + NULL, // open_gather + NULL, // get_iv + aead_ssl3_tag_len, +}; + +const EVP_AEAD *EVP_aead_aes_128_cbc_sha1_ssl3(void) { + return &aead_aes_128_cbc_sha1_ssl3; +} + +const EVP_AEAD *EVP_aead_aes_256_cbc_sha1_ssl3(void) { + return &aead_aes_256_cbc_sha1_ssl3; +} + +const EVP_AEAD *EVP_aead_des_ede3_cbc_sha1_ssl3(void) { + return &aead_des_ede3_cbc_sha1_ssl3; +} + +const EVP_AEAD *EVP_aead_null_sha1_ssl3(void) { return &aead_null_sha1_ssl3; } diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/cipher_extra/e_ssl3.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/cipher_extra/e_ssl3.c.grpc_back new file mode 100644 index 0000000..61f25ca --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/cipher_extra/e_ssl3.c.grpc_back @@ -0,0 +1,460 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "internal.h" +#include "../internal.h" +#include "../fipsmodule/cipher/internal.h" + + +typedef struct { + EVP_CIPHER_CTX cipher_ctx; + EVP_MD_CTX md_ctx; +} AEAD_SSL3_CTX; + +static int ssl3_mac(AEAD_SSL3_CTX *ssl3_ctx, uint8_t *out, unsigned *out_len, + const uint8_t *ad, size_t ad_len, const uint8_t *in, + size_t in_len) { + size_t md_size = EVP_MD_CTX_size(&ssl3_ctx->md_ctx); + size_t pad_len = (md_size == 20) ? 40 : 48; + + // To allow for CBC mode which changes cipher length, |ad| doesn't include the + // length for legacy ciphers. + uint8_t ad_extra[2]; + ad_extra[0] = (uint8_t)(in_len >> 8); + ad_extra[1] = (uint8_t)(in_len & 0xff); + + EVP_MD_CTX md_ctx; + EVP_MD_CTX_init(&md_ctx); + + uint8_t pad[48]; + uint8_t tmp[EVP_MAX_MD_SIZE]; + OPENSSL_memset(pad, 0x36, pad_len); + if (!EVP_MD_CTX_copy_ex(&md_ctx, &ssl3_ctx->md_ctx) || + !EVP_DigestUpdate(&md_ctx, pad, pad_len) || + !EVP_DigestUpdate(&md_ctx, ad, ad_len) || + !EVP_DigestUpdate(&md_ctx, ad_extra, sizeof(ad_extra)) || + !EVP_DigestUpdate(&md_ctx, in, in_len) || + !EVP_DigestFinal_ex(&md_ctx, tmp, NULL)) { + EVP_MD_CTX_cleanup(&md_ctx); + return 0; + } + + OPENSSL_memset(pad, 0x5c, pad_len); + if (!EVP_MD_CTX_copy_ex(&md_ctx, &ssl3_ctx->md_ctx) || + !EVP_DigestUpdate(&md_ctx, pad, pad_len) || + !EVP_DigestUpdate(&md_ctx, tmp, md_size) || + !EVP_DigestFinal_ex(&md_ctx, out, out_len)) { + EVP_MD_CTX_cleanup(&md_ctx); + return 0; + } + EVP_MD_CTX_cleanup(&md_ctx); + return 1; +} + +static void aead_ssl3_cleanup(EVP_AEAD_CTX *ctx) { + AEAD_SSL3_CTX *ssl3_ctx = (AEAD_SSL3_CTX *)ctx->aead_state; + EVP_CIPHER_CTX_cleanup(&ssl3_ctx->cipher_ctx); + EVP_MD_CTX_cleanup(&ssl3_ctx->md_ctx); + OPENSSL_free(ssl3_ctx); + ctx->aead_state = NULL; +} + +static int aead_ssl3_init(EVP_AEAD_CTX *ctx, const uint8_t *key, size_t key_len, + size_t tag_len, enum evp_aead_direction_t dir, + const EVP_CIPHER *cipher, const EVP_MD *md) { + if (tag_len != EVP_AEAD_DEFAULT_TAG_LENGTH && + tag_len != EVP_MD_size(md)) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_TAG_SIZE); + return 0; + } + + if (key_len != EVP_AEAD_key_length(ctx->aead)) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_KEY_LENGTH); + return 0; + } + + size_t mac_key_len = EVP_MD_size(md); + size_t enc_key_len = EVP_CIPHER_key_length(cipher); + assert(mac_key_len + enc_key_len + EVP_CIPHER_iv_length(cipher) == key_len); + + AEAD_SSL3_CTX *ssl3_ctx = OPENSSL_malloc(sizeof(AEAD_SSL3_CTX)); + if (ssl3_ctx == NULL) { + OPENSSL_PUT_ERROR(CIPHER, ERR_R_MALLOC_FAILURE); + return 0; + } + EVP_CIPHER_CTX_init(&ssl3_ctx->cipher_ctx); + EVP_MD_CTX_init(&ssl3_ctx->md_ctx); + + ctx->aead_state = ssl3_ctx; + if (!EVP_CipherInit_ex(&ssl3_ctx->cipher_ctx, cipher, NULL, &key[mac_key_len], + &key[mac_key_len + enc_key_len], + dir == evp_aead_seal) || + !EVP_DigestInit_ex(&ssl3_ctx->md_ctx, md, NULL) || + !EVP_DigestUpdate(&ssl3_ctx->md_ctx, key, mac_key_len)) { + aead_ssl3_cleanup(ctx); + ctx->aead_state = NULL; + return 0; + } + EVP_CIPHER_CTX_set_padding(&ssl3_ctx->cipher_ctx, 0); + + return 1; +} + +static size_t aead_ssl3_tag_len(const EVP_AEAD_CTX *ctx, const size_t in_len, + const size_t extra_in_len) { + assert(extra_in_len == 0); + const AEAD_SSL3_CTX *ssl3_ctx = (AEAD_SSL3_CTX*)ctx->aead_state; + + const size_t digest_len = EVP_MD_CTX_size(&ssl3_ctx->md_ctx); + if (EVP_CIPHER_CTX_mode(&ssl3_ctx->cipher_ctx) != EVP_CIPH_CBC_MODE) { + // The NULL cipher. + return digest_len; + } + + const size_t block_size = EVP_CIPHER_CTX_block_size(&ssl3_ctx->cipher_ctx); + // An overflow of |in_len + digest_len| doesn't affect the result mod + // |block_size|, provided that |block_size| is a smaller power of two. + assert(block_size != 0 && (block_size & (block_size - 1)) == 0); + const size_t pad_len = block_size - ((in_len + digest_len) % block_size); + return digest_len + pad_len; +} + +static int aead_ssl3_seal_scatter(const EVP_AEAD_CTX *ctx, uint8_t *out, + uint8_t *out_tag, size_t *out_tag_len, + const size_t max_out_tag_len, + const uint8_t *nonce, const size_t nonce_len, + const uint8_t *in, const size_t in_len, + const uint8_t *extra_in, + const size_t extra_in_len, const uint8_t *ad, + const size_t ad_len) { + AEAD_SSL3_CTX *ssl3_ctx = (AEAD_SSL3_CTX *)ctx->aead_state; + + if (!ssl3_ctx->cipher_ctx.encrypt) { + // Unlike a normal AEAD, an SSL3 AEAD may only be used in one direction. + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_OPERATION); + return 0; + } + + if (in_len > INT_MAX) { + // EVP_CIPHER takes int as input. + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE); + return 0; + } + + if (max_out_tag_len < aead_ssl3_tag_len(ctx, in_len, extra_in_len)) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL); + return 0; + } + + if (nonce_len != 0) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_IV_TOO_LARGE); + return 0; + } + + if (ad_len != 11 - 2 /* length bytes */) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_AD_SIZE); + return 0; + } + + // Compute the MAC. This must be first in case the operation is being done + // in-place. + uint8_t mac[EVP_MAX_MD_SIZE]; + unsigned mac_len; + if (!ssl3_mac(ssl3_ctx, mac, &mac_len, ad, ad_len, in, in_len)) { + return 0; + } + + // Encrypt the input. + int len; + if (!EVP_EncryptUpdate(&ssl3_ctx->cipher_ctx, out, &len, in, + (int)in_len)) { + return 0; + } + + const size_t block_size = EVP_CIPHER_CTX_block_size(&ssl3_ctx->cipher_ctx); + + // Feed the MAC into the cipher in two steps. First complete the final partial + // block from encrypting the input and split the result between |out| and + // |out_tag|. Then encrypt the remainder. + + size_t early_mac_len = (block_size - (in_len % block_size)) % block_size; + if (early_mac_len != 0) { + assert(len + block_size - early_mac_len == in_len); + uint8_t buf[EVP_MAX_BLOCK_LENGTH]; + int buf_len; + if (!EVP_EncryptUpdate(&ssl3_ctx->cipher_ctx, buf, &buf_len, mac, + (int)early_mac_len)) { + return 0; + } + assert(buf_len == (int)block_size); + OPENSSL_memcpy(out + len, buf, block_size - early_mac_len); + OPENSSL_memcpy(out_tag, buf + block_size - early_mac_len, early_mac_len); + } + size_t tag_len = early_mac_len; + + if (!EVP_EncryptUpdate(&ssl3_ctx->cipher_ctx, out_tag + tag_len, &len, + mac + tag_len, mac_len - tag_len)) { + return 0; + } + tag_len += len; + + if (block_size > 1) { + assert(block_size <= 256); + assert(EVP_CIPHER_CTX_mode(&ssl3_ctx->cipher_ctx) == EVP_CIPH_CBC_MODE); + + // Compute padding and feed that into the cipher. + uint8_t padding[256]; + size_t padding_len = block_size - ((in_len + mac_len) % block_size); + OPENSSL_memset(padding, 0, padding_len - 1); + padding[padding_len - 1] = padding_len - 1; + if (!EVP_EncryptUpdate(&ssl3_ctx->cipher_ctx, out_tag + tag_len, &len, padding, + (int)padding_len)) { + return 0; + } + tag_len += len; + } + + if (!EVP_EncryptFinal_ex(&ssl3_ctx->cipher_ctx, out_tag + tag_len, &len)) { + return 0; + } + tag_len += len; + assert(tag_len == aead_ssl3_tag_len(ctx, in_len, extra_in_len)); + + *out_tag_len = tag_len; + return 1; +} + +static int aead_ssl3_open(const EVP_AEAD_CTX *ctx, uint8_t *out, + size_t *out_len, size_t max_out_len, + const uint8_t *nonce, size_t nonce_len, + const uint8_t *in, size_t in_len, + const uint8_t *ad, size_t ad_len) { + AEAD_SSL3_CTX *ssl3_ctx = (AEAD_SSL3_CTX *)ctx->aead_state; + + if (ssl3_ctx->cipher_ctx.encrypt) { + // Unlike a normal AEAD, an SSL3 AEAD may only be used in one direction. + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_OPERATION); + return 0; + } + + size_t mac_len = EVP_MD_CTX_size(&ssl3_ctx->md_ctx); + if (in_len < mac_len) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT); + return 0; + } + + if (max_out_len < in_len) { + // This requires that the caller provide space for the MAC, even though it + // will always be removed on return. + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL); + return 0; + } + + if (nonce_len != 0) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE); + return 0; + } + + if (ad_len != 11 - 2 /* length bytes */) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_AD_SIZE); + return 0; + } + + if (in_len > INT_MAX) { + // EVP_CIPHER takes int as input. + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE); + return 0; + } + + // Decrypt to get the plaintext + MAC + padding. + size_t total = 0; + int len; + if (!EVP_DecryptUpdate(&ssl3_ctx->cipher_ctx, out, &len, in, (int)in_len)) { + return 0; + } + total += len; + if (!EVP_DecryptFinal_ex(&ssl3_ctx->cipher_ctx, out + total, &len)) { + return 0; + } + total += len; + assert(total == in_len); + + // Remove CBC padding and MAC. This would normally be timing-sensitive, but + // SSLv3 CBC ciphers are already broken. Support will be removed eventually. + // https://www.openssl.org/~bodo/ssl-poodle.pdf + size_t data_len; + if (EVP_CIPHER_CTX_mode(&ssl3_ctx->cipher_ctx) == EVP_CIPH_CBC_MODE) { + unsigned padding_length = out[total - 1]; + if (total < padding_length + 1 + mac_len) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT); + return 0; + } + // The padding must be minimal. + if (padding_length + 1 > EVP_CIPHER_CTX_block_size(&ssl3_ctx->cipher_ctx)) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT); + return 0; + } + data_len = total - padding_length - 1 - mac_len; + } else { + data_len = total - mac_len; + } + + // Compute the MAC and compare against the one in the record. + uint8_t mac[EVP_MAX_MD_SIZE]; + if (!ssl3_mac(ssl3_ctx, mac, NULL, ad, ad_len, out, data_len)) { + return 0; + } + if (CRYPTO_memcmp(&out[data_len], mac, mac_len) != 0) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT); + return 0; + } + + *out_len = data_len; + return 1; +} + +static int aead_ssl3_get_iv(const EVP_AEAD_CTX *ctx, const uint8_t **out_iv, + size_t *out_iv_len) { + AEAD_SSL3_CTX *ssl3_ctx = (AEAD_SSL3_CTX *)ctx->aead_state; + const size_t iv_len = EVP_CIPHER_CTX_iv_length(&ssl3_ctx->cipher_ctx); + if (iv_len <= 1) { + return 0; + } + + *out_iv = ssl3_ctx->cipher_ctx.iv; + *out_iv_len = iv_len; + return 1; +} + +static int aead_aes_128_cbc_sha1_ssl3_init(EVP_AEAD_CTX *ctx, const uint8_t *key, + size_t key_len, size_t tag_len, + enum evp_aead_direction_t dir) { + return aead_ssl3_init(ctx, key, key_len, tag_len, dir, EVP_aes_128_cbc(), + EVP_sha1()); +} + +static int aead_aes_256_cbc_sha1_ssl3_init(EVP_AEAD_CTX *ctx, const uint8_t *key, + size_t key_len, size_t tag_len, + enum evp_aead_direction_t dir) { + return aead_ssl3_init(ctx, key, key_len, tag_len, dir, EVP_aes_256_cbc(), + EVP_sha1()); +} +static int aead_des_ede3_cbc_sha1_ssl3_init(EVP_AEAD_CTX *ctx, + const uint8_t *key, size_t key_len, + size_t tag_len, + enum evp_aead_direction_t dir) { + return aead_ssl3_init(ctx, key, key_len, tag_len, dir, EVP_des_ede3_cbc(), + EVP_sha1()); +} + +static int aead_null_sha1_ssl3_init(EVP_AEAD_CTX *ctx, const uint8_t *key, + size_t key_len, size_t tag_len, + enum evp_aead_direction_t dir) { + return aead_ssl3_init(ctx, key, key_len, tag_len, dir, EVP_enc_null(), + EVP_sha1()); +} + +static const EVP_AEAD aead_aes_128_cbc_sha1_ssl3 = { + SHA_DIGEST_LENGTH + 16 + 16, // key len (SHA1 + AES128 + IV) + 0, // nonce len + 16 + SHA_DIGEST_LENGTH, // overhead (padding + SHA1) + SHA_DIGEST_LENGTH, // max tag length + 0, // seal_scatter_supports_extra_in + + NULL, // init + aead_aes_128_cbc_sha1_ssl3_init, + aead_ssl3_cleanup, + aead_ssl3_open, + aead_ssl3_seal_scatter, + NULL, // open_gather + aead_ssl3_get_iv, + aead_ssl3_tag_len, +}; + +static const EVP_AEAD aead_aes_256_cbc_sha1_ssl3 = { + SHA_DIGEST_LENGTH + 32 + 16, // key len (SHA1 + AES256 + IV) + 0, // nonce len + 16 + SHA_DIGEST_LENGTH, // overhead (padding + SHA1) + SHA_DIGEST_LENGTH, // max tag length + 0, // seal_scatter_supports_extra_in + + NULL, // init + aead_aes_256_cbc_sha1_ssl3_init, + aead_ssl3_cleanup, + aead_ssl3_open, + aead_ssl3_seal_scatter, + NULL, // open_gather + aead_ssl3_get_iv, + aead_ssl3_tag_len, +}; + +static const EVP_AEAD aead_des_ede3_cbc_sha1_ssl3 = { + SHA_DIGEST_LENGTH + 24 + 8, // key len (SHA1 + 3DES + IV) + 0, // nonce len + 8 + SHA_DIGEST_LENGTH, // overhead (padding + SHA1) + SHA_DIGEST_LENGTH, // max tag length + 0, // seal_scatter_supports_extra_in + + NULL, // init + aead_des_ede3_cbc_sha1_ssl3_init, + aead_ssl3_cleanup, + aead_ssl3_open, + aead_ssl3_seal_scatter, + NULL, // open_gather + aead_ssl3_get_iv, + aead_ssl3_tag_len, +}; + +static const EVP_AEAD aead_null_sha1_ssl3 = { + SHA_DIGEST_LENGTH, // key len + 0, // nonce len + SHA_DIGEST_LENGTH, // overhead (SHA1) + SHA_DIGEST_LENGTH, // max tag length + 0, // seal_scatter_supports_extra_in + + NULL, // init + aead_null_sha1_ssl3_init, + aead_ssl3_cleanup, + aead_ssl3_open, + aead_ssl3_seal_scatter, + NULL, // open_gather + NULL, // get_iv + aead_ssl3_tag_len, +}; + +const EVP_AEAD *EVP_aead_aes_128_cbc_sha1_ssl3(void) { + return &aead_aes_128_cbc_sha1_ssl3; +} + +const EVP_AEAD *EVP_aead_aes_256_cbc_sha1_ssl3(void) { + return &aead_aes_256_cbc_sha1_ssl3; +} + +const EVP_AEAD *EVP_aead_des_ede3_cbc_sha1_ssl3(void) { + return &aead_des_ede3_cbc_sha1_ssl3; +} + +const EVP_AEAD *EVP_aead_null_sha1_ssl3(void) { return &aead_null_sha1_ssl3; } diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/cipher_extra/e_tls.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/cipher_extra/e_tls.c new file mode 100644 index 0000000..48fbccd --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/cipher_extra/e_tls.c @@ -0,0 +1,680 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../fipsmodule/cipher/internal.h" +#include "../internal.h" +#include "internal.h" + + +typedef struct { + EVP_CIPHER_CTX cipher_ctx; + HMAC_CTX hmac_ctx; + // mac_key is the portion of the key used for the MAC. It is retained + // separately for the constant-time CBC code. + uint8_t mac_key[EVP_MAX_MD_SIZE]; + uint8_t mac_key_len; + // implicit_iv is one iff this is a pre-TLS-1.1 CBC cipher without an explicit + // IV. + char implicit_iv; +} AEAD_TLS_CTX; + +OPENSSL_COMPILE_ASSERT(EVP_MAX_MD_SIZE < 256, mac_key_len_fits_in_uint8_t); + +static void aead_tls_cleanup(EVP_AEAD_CTX *ctx) { + AEAD_TLS_CTX *tls_ctx = (AEAD_TLS_CTX *)ctx->aead_state; + EVP_CIPHER_CTX_cleanup(&tls_ctx->cipher_ctx); + HMAC_CTX_cleanup(&tls_ctx->hmac_ctx); + OPENSSL_free(tls_ctx); + ctx->aead_state = NULL; +} + +static int aead_tls_init(EVP_AEAD_CTX *ctx, const uint8_t *key, size_t key_len, + size_t tag_len, enum evp_aead_direction_t dir, + const EVP_CIPHER *cipher, const EVP_MD *md, + char implicit_iv) { + if (tag_len != EVP_AEAD_DEFAULT_TAG_LENGTH && + tag_len != EVP_MD_size(md)) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_TAG_SIZE); + return 0; + } + + if (key_len != EVP_AEAD_key_length(ctx->aead)) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_KEY_LENGTH); + return 0; + } + + size_t mac_key_len = EVP_MD_size(md); + size_t enc_key_len = EVP_CIPHER_key_length(cipher); + assert(mac_key_len + enc_key_len + + (implicit_iv ? EVP_CIPHER_iv_length(cipher) : 0) == key_len); + + AEAD_TLS_CTX *tls_ctx = OPENSSL_malloc(sizeof(AEAD_TLS_CTX)); + if (tls_ctx == NULL) { + OPENSSL_PUT_ERROR(CIPHER, ERR_R_MALLOC_FAILURE); + return 0; + } + EVP_CIPHER_CTX_init(&tls_ctx->cipher_ctx); + HMAC_CTX_init(&tls_ctx->hmac_ctx); + assert(mac_key_len <= EVP_MAX_MD_SIZE); + OPENSSL_memcpy(tls_ctx->mac_key, key, mac_key_len); + tls_ctx->mac_key_len = (uint8_t)mac_key_len; + tls_ctx->implicit_iv = implicit_iv; + + ctx->aead_state = tls_ctx; + if (!EVP_CipherInit_ex(&tls_ctx->cipher_ctx, cipher, NULL, &key[mac_key_len], + implicit_iv ? &key[mac_key_len + enc_key_len] : NULL, + dir == evp_aead_seal) || + !HMAC_Init_ex(&tls_ctx->hmac_ctx, key, mac_key_len, md, NULL)) { + aead_tls_cleanup(ctx); + ctx->aead_state = NULL; + return 0; + } + EVP_CIPHER_CTX_set_padding(&tls_ctx->cipher_ctx, 0); + + return 1; +} + +static size_t aead_tls_tag_len(const EVP_AEAD_CTX *ctx, const size_t in_len, + const size_t extra_in_len) { + assert(extra_in_len == 0); + AEAD_TLS_CTX *tls_ctx = (AEAD_TLS_CTX *)ctx->aead_state; + + const size_t hmac_len = HMAC_size(&tls_ctx->hmac_ctx); + if (EVP_CIPHER_CTX_mode(&tls_ctx->cipher_ctx) != EVP_CIPH_CBC_MODE) { + // The NULL cipher. + return hmac_len; + } + + const size_t block_size = EVP_CIPHER_CTX_block_size(&tls_ctx->cipher_ctx); + // An overflow of |in_len + hmac_len| doesn't affect the result mod + // |block_size|, provided that |block_size| is a smaller power of two. + assert(block_size != 0 && (block_size & (block_size - 1)) == 0); + const size_t pad_len = block_size - (in_len + hmac_len) % block_size; + return hmac_len + pad_len; +} + +static int aead_tls_seal_scatter(const EVP_AEAD_CTX *ctx, uint8_t *out, + uint8_t *out_tag, size_t *out_tag_len, + const size_t max_out_tag_len, + const uint8_t *nonce, const size_t nonce_len, + const uint8_t *in, const size_t in_len, + const uint8_t *extra_in, + const size_t extra_in_len, const uint8_t *ad, + const size_t ad_len) { + AEAD_TLS_CTX *tls_ctx = (AEAD_TLS_CTX *)ctx->aead_state; + + if (!tls_ctx->cipher_ctx.encrypt) { + // Unlike a normal AEAD, a TLS AEAD may only be used in one direction. + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_OPERATION); + return 0; + } + + if (in_len > INT_MAX) { + // EVP_CIPHER takes int as input. + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE); + return 0; + } + + if (max_out_tag_len < aead_tls_tag_len(ctx, in_len, extra_in_len)) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL); + return 0; + } + + if (nonce_len != EVP_AEAD_nonce_length(ctx->aead)) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_NONCE_SIZE); + return 0; + } + + if (ad_len != 13 - 2 /* length bytes */) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_AD_SIZE); + return 0; + } + + // To allow for CBC mode which changes cipher length, |ad| doesn't include the + // length for legacy ciphers. + uint8_t ad_extra[2]; + ad_extra[0] = (uint8_t)(in_len >> 8); + ad_extra[1] = (uint8_t)(in_len & 0xff); + + // Compute the MAC. This must be first in case the operation is being done + // in-place. + uint8_t mac[EVP_MAX_MD_SIZE]; + unsigned mac_len; + if (!HMAC_Init_ex(&tls_ctx->hmac_ctx, NULL, 0, NULL, NULL) || + !HMAC_Update(&tls_ctx->hmac_ctx, ad, ad_len) || + !HMAC_Update(&tls_ctx->hmac_ctx, ad_extra, sizeof(ad_extra)) || + !HMAC_Update(&tls_ctx->hmac_ctx, in, in_len) || + !HMAC_Final(&tls_ctx->hmac_ctx, mac, &mac_len)) { + return 0; + } + + // Configure the explicit IV. + if (EVP_CIPHER_CTX_mode(&tls_ctx->cipher_ctx) == EVP_CIPH_CBC_MODE && + !tls_ctx->implicit_iv && + !EVP_EncryptInit_ex(&tls_ctx->cipher_ctx, NULL, NULL, NULL, nonce)) { + return 0; + } + + // Encrypt the input. + int len; + if (!EVP_EncryptUpdate(&tls_ctx->cipher_ctx, out, &len, in, (int)in_len)) { + return 0; + } + + unsigned block_size = EVP_CIPHER_CTX_block_size(&tls_ctx->cipher_ctx); + + // Feed the MAC into the cipher in two steps. First complete the final partial + // block from encrypting the input and split the result between |out| and + // |out_tag|. Then feed the rest. + + const size_t early_mac_len = (block_size - (in_len % block_size)) % block_size; + if (early_mac_len != 0) { + assert(len + block_size - early_mac_len == in_len); + uint8_t buf[EVP_MAX_BLOCK_LENGTH]; + int buf_len; + if (!EVP_EncryptUpdate(&tls_ctx->cipher_ctx, buf, &buf_len, mac, + (int)early_mac_len)) { + return 0; + } + assert(buf_len == (int)block_size); + OPENSSL_memcpy(out + len, buf, block_size - early_mac_len); + OPENSSL_memcpy(out_tag, buf + block_size - early_mac_len, early_mac_len); + } + size_t tag_len = early_mac_len; + + if (!EVP_EncryptUpdate(&tls_ctx->cipher_ctx, out_tag + tag_len, &len, + mac + tag_len, mac_len - tag_len)) { + return 0; + } + tag_len += len; + + if (block_size > 1) { + assert(block_size <= 256); + assert(EVP_CIPHER_CTX_mode(&tls_ctx->cipher_ctx) == EVP_CIPH_CBC_MODE); + + // Compute padding and feed that into the cipher. + uint8_t padding[256]; + unsigned padding_len = block_size - ((in_len + mac_len) % block_size); + OPENSSL_memset(padding, padding_len - 1, padding_len); + if (!EVP_EncryptUpdate(&tls_ctx->cipher_ctx, out_tag + tag_len, &len, + padding, (int)padding_len)) { + return 0; + } + tag_len += len; + } + + if (!EVP_EncryptFinal_ex(&tls_ctx->cipher_ctx, out_tag + tag_len, &len)) { + return 0; + } + assert(len == 0); // Padding is explicit. + assert(tag_len == aead_tls_tag_len(ctx, in_len, extra_in_len)); + + *out_tag_len = tag_len; + return 1; +} + +static int aead_tls_open(const EVP_AEAD_CTX *ctx, uint8_t *out, size_t *out_len, + size_t max_out_len, const uint8_t *nonce, + size_t nonce_len, const uint8_t *in, size_t in_len, + const uint8_t *ad, size_t ad_len) { + AEAD_TLS_CTX *tls_ctx = (AEAD_TLS_CTX *)ctx->aead_state; + + if (tls_ctx->cipher_ctx.encrypt) { + // Unlike a normal AEAD, a TLS AEAD may only be used in one direction. + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_OPERATION); + return 0; + } + + if (in_len < HMAC_size(&tls_ctx->hmac_ctx)) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT); + return 0; + } + + if (max_out_len < in_len) { + // This requires that the caller provide space for the MAC, even though it + // will always be removed on return. + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL); + return 0; + } + + if (nonce_len != EVP_AEAD_nonce_length(ctx->aead)) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_NONCE_SIZE); + return 0; + } + + if (ad_len != 13 - 2 /* length bytes */) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_AD_SIZE); + return 0; + } + + if (in_len > INT_MAX) { + // EVP_CIPHER takes int as input. + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE); + return 0; + } + + // Configure the explicit IV. + if (EVP_CIPHER_CTX_mode(&tls_ctx->cipher_ctx) == EVP_CIPH_CBC_MODE && + !tls_ctx->implicit_iv && + !EVP_DecryptInit_ex(&tls_ctx->cipher_ctx, NULL, NULL, NULL, nonce)) { + return 0; + } + + // Decrypt to get the plaintext + MAC + padding. + size_t total = 0; + int len; + if (!EVP_DecryptUpdate(&tls_ctx->cipher_ctx, out, &len, in, (int)in_len)) { + return 0; + } + total += len; + if (!EVP_DecryptFinal_ex(&tls_ctx->cipher_ctx, out + total, &len)) { + return 0; + } + total += len; + assert(total == in_len); + + // Remove CBC padding. Code from here on is timing-sensitive with respect to + // |padding_ok| and |data_plus_mac_len| for CBC ciphers. + size_t data_plus_mac_len; + crypto_word_t padding_ok; + if (EVP_CIPHER_CTX_mode(&tls_ctx->cipher_ctx) == EVP_CIPH_CBC_MODE) { + if (!EVP_tls_cbc_remove_padding( + &padding_ok, &data_plus_mac_len, out, total, + EVP_CIPHER_CTX_block_size(&tls_ctx->cipher_ctx), + HMAC_size(&tls_ctx->hmac_ctx))) { + // Publicly invalid. This can be rejected in non-constant time. + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT); + return 0; + } + } else { + padding_ok = CONSTTIME_TRUE_W; + data_plus_mac_len = total; + // |data_plus_mac_len| = |total| = |in_len| at this point. |in_len| has + // already been checked against the MAC size at the top of the function. + assert(data_plus_mac_len >= HMAC_size(&tls_ctx->hmac_ctx)); + } + size_t data_len = data_plus_mac_len - HMAC_size(&tls_ctx->hmac_ctx); + + // At this point, if the padding is valid, the first |data_plus_mac_len| bytes + // after |out| are the plaintext and MAC. Otherwise, |data_plus_mac_len| is + // still large enough to extract a MAC, but it will be irrelevant. + + // To allow for CBC mode which changes cipher length, |ad| doesn't include the + // length for legacy ciphers. + uint8_t ad_fixed[13]; + OPENSSL_memcpy(ad_fixed, ad, 11); + ad_fixed[11] = (uint8_t)(data_len >> 8); + ad_fixed[12] = (uint8_t)(data_len & 0xff); + ad_len += 2; + + // Compute the MAC and extract the one in the record. + uint8_t mac[EVP_MAX_MD_SIZE]; + size_t mac_len; + uint8_t record_mac_tmp[EVP_MAX_MD_SIZE]; + uint8_t *record_mac; + if (EVP_CIPHER_CTX_mode(&tls_ctx->cipher_ctx) == EVP_CIPH_CBC_MODE && + EVP_tls_cbc_record_digest_supported(tls_ctx->hmac_ctx.md)) { + if (!EVP_tls_cbc_digest_record(tls_ctx->hmac_ctx.md, mac, &mac_len, + ad_fixed, out, data_plus_mac_len, total, + tls_ctx->mac_key, tls_ctx->mac_key_len)) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT); + return 0; + } + assert(mac_len == HMAC_size(&tls_ctx->hmac_ctx)); + + record_mac = record_mac_tmp; + EVP_tls_cbc_copy_mac(record_mac, mac_len, out, data_plus_mac_len, total); + } else { + // We should support the constant-time path for all CBC-mode ciphers + // implemented. + assert(EVP_CIPHER_CTX_mode(&tls_ctx->cipher_ctx) != EVP_CIPH_CBC_MODE); + + unsigned mac_len_u; + if (!HMAC_Init_ex(&tls_ctx->hmac_ctx, NULL, 0, NULL, NULL) || + !HMAC_Update(&tls_ctx->hmac_ctx, ad_fixed, ad_len) || + !HMAC_Update(&tls_ctx->hmac_ctx, out, data_len) || + !HMAC_Final(&tls_ctx->hmac_ctx, mac, &mac_len_u)) { + return 0; + } + mac_len = mac_len_u; + + assert(mac_len == HMAC_size(&tls_ctx->hmac_ctx)); + record_mac = &out[data_len]; + } + + // Perform the MAC check and the padding check in constant-time. It should be + // safe to simply perform the padding check first, but it would not be under a + // different choice of MAC location on padding failure. See + // EVP_tls_cbc_remove_padding. + crypto_word_t good = + constant_time_eq_int(CRYPTO_memcmp(record_mac, mac, mac_len), 0); + good &= padding_ok; + if (!good) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT); + return 0; + } + + // End of timing-sensitive code. + + *out_len = data_len; + return 1; +} + +static int aead_aes_128_cbc_sha1_tls_init(EVP_AEAD_CTX *ctx, const uint8_t *key, + size_t key_len, size_t tag_len, + enum evp_aead_direction_t dir) { + return aead_tls_init(ctx, key, key_len, tag_len, dir, EVP_aes_128_cbc(), + EVP_sha1(), 0); +} + +static int aead_aes_128_cbc_sha1_tls_implicit_iv_init( + EVP_AEAD_CTX *ctx, const uint8_t *key, size_t key_len, size_t tag_len, + enum evp_aead_direction_t dir) { + return aead_tls_init(ctx, key, key_len, tag_len, dir, EVP_aes_128_cbc(), + EVP_sha1(), 1); +} + +static int aead_aes_128_cbc_sha256_tls_init(EVP_AEAD_CTX *ctx, + const uint8_t *key, size_t key_len, + size_t tag_len, + enum evp_aead_direction_t dir) { + return aead_tls_init(ctx, key, key_len, tag_len, dir, EVP_aes_128_cbc(), + EVP_sha256(), 0); +} + +static int aead_aes_256_cbc_sha1_tls_init(EVP_AEAD_CTX *ctx, const uint8_t *key, + size_t key_len, size_t tag_len, + enum evp_aead_direction_t dir) { + return aead_tls_init(ctx, key, key_len, tag_len, dir, EVP_aes_256_cbc(), + EVP_sha1(), 0); +} + +static int aead_aes_256_cbc_sha1_tls_implicit_iv_init( + EVP_AEAD_CTX *ctx, const uint8_t *key, size_t key_len, size_t tag_len, + enum evp_aead_direction_t dir) { + return aead_tls_init(ctx, key, key_len, tag_len, dir, EVP_aes_256_cbc(), + EVP_sha1(), 1); +} + +static int aead_aes_256_cbc_sha256_tls_init(EVP_AEAD_CTX *ctx, + const uint8_t *key, size_t key_len, + size_t tag_len, + enum evp_aead_direction_t dir) { + return aead_tls_init(ctx, key, key_len, tag_len, dir, EVP_aes_256_cbc(), + EVP_sha256(), 0); +} + +static int aead_aes_256_cbc_sha384_tls_init(EVP_AEAD_CTX *ctx, + const uint8_t *key, size_t key_len, + size_t tag_len, + enum evp_aead_direction_t dir) { + return aead_tls_init(ctx, key, key_len, tag_len, dir, EVP_aes_256_cbc(), + EVP_sha384(), 0); +} + +static int aead_des_ede3_cbc_sha1_tls_init(EVP_AEAD_CTX *ctx, + const uint8_t *key, size_t key_len, + size_t tag_len, + enum evp_aead_direction_t dir) { + return aead_tls_init(ctx, key, key_len, tag_len, dir, EVP_des_ede3_cbc(), + EVP_sha1(), 0); +} + +static int aead_des_ede3_cbc_sha1_tls_implicit_iv_init( + EVP_AEAD_CTX *ctx, const uint8_t *key, size_t key_len, size_t tag_len, + enum evp_aead_direction_t dir) { + return aead_tls_init(ctx, key, key_len, tag_len, dir, EVP_des_ede3_cbc(), + EVP_sha1(), 1); +} + +static int aead_tls_get_iv(const EVP_AEAD_CTX *ctx, const uint8_t **out_iv, + size_t *out_iv_len) { + const AEAD_TLS_CTX *tls_ctx = (AEAD_TLS_CTX*) ctx->aead_state; + const size_t iv_len = EVP_CIPHER_CTX_iv_length(&tls_ctx->cipher_ctx); + if (iv_len <= 1) { + return 0; + } + + *out_iv = tls_ctx->cipher_ctx.iv; + *out_iv_len = iv_len; + return 1; +} + +static int aead_null_sha1_tls_init(EVP_AEAD_CTX *ctx, const uint8_t *key, + size_t key_len, size_t tag_len, + enum evp_aead_direction_t dir) { + return aead_tls_init(ctx, key, key_len, tag_len, dir, EVP_enc_null(), + EVP_sha1(), 1 /* implicit iv */); +} + +static const EVP_AEAD aead_aes_128_cbc_sha1_tls = { + SHA_DIGEST_LENGTH + 16, // key len (SHA1 + AES128) + 16, // nonce len (IV) + 16 + SHA_DIGEST_LENGTH, // overhead (padding + SHA1) + SHA_DIGEST_LENGTH, // max tag length + 0, // seal_scatter_supports_extra_in + + NULL, // init + aead_aes_128_cbc_sha1_tls_init, + aead_tls_cleanup, + aead_tls_open, + aead_tls_seal_scatter, + NULL, // open_gather + NULL, // get_iv + aead_tls_tag_len, +}; + +static const EVP_AEAD aead_aes_128_cbc_sha1_tls_implicit_iv = { + SHA_DIGEST_LENGTH + 16 + 16, // key len (SHA1 + AES128 + IV) + 0, // nonce len + 16 + SHA_DIGEST_LENGTH, // overhead (padding + SHA1) + SHA_DIGEST_LENGTH, // max tag length + 0, // seal_scatter_supports_extra_in + + NULL, // init + aead_aes_128_cbc_sha1_tls_implicit_iv_init, + aead_tls_cleanup, + aead_tls_open, + aead_tls_seal_scatter, + NULL, // open_gather + aead_tls_get_iv, // get_iv + aead_tls_tag_len, +}; + +static const EVP_AEAD aead_aes_128_cbc_sha256_tls = { + SHA256_DIGEST_LENGTH + 16, // key len (SHA256 + AES128) + 16, // nonce len (IV) + 16 + SHA256_DIGEST_LENGTH, // overhead (padding + SHA256) + SHA256_DIGEST_LENGTH, // max tag length + 0, // seal_scatter_supports_extra_in + + NULL, // init + aead_aes_128_cbc_sha256_tls_init, + aead_tls_cleanup, + aead_tls_open, + aead_tls_seal_scatter, + NULL, // open_gather + NULL, // get_iv + aead_tls_tag_len, +}; + +static const EVP_AEAD aead_aes_256_cbc_sha1_tls = { + SHA_DIGEST_LENGTH + 32, // key len (SHA1 + AES256) + 16, // nonce len (IV) + 16 + SHA_DIGEST_LENGTH, // overhead (padding + SHA1) + SHA_DIGEST_LENGTH, // max tag length + 0, // seal_scatter_supports_extra_in + + NULL, // init + aead_aes_256_cbc_sha1_tls_init, + aead_tls_cleanup, + aead_tls_open, + aead_tls_seal_scatter, + NULL, // open_gather + NULL, // get_iv + aead_tls_tag_len, +}; + +static const EVP_AEAD aead_aes_256_cbc_sha1_tls_implicit_iv = { + SHA_DIGEST_LENGTH + 32 + 16, // key len (SHA1 + AES256 + IV) + 0, // nonce len + 16 + SHA_DIGEST_LENGTH, // overhead (padding + SHA1) + SHA_DIGEST_LENGTH, // max tag length + 0, // seal_scatter_supports_extra_in + + NULL, // init + aead_aes_256_cbc_sha1_tls_implicit_iv_init, + aead_tls_cleanup, + aead_tls_open, + aead_tls_seal_scatter, + NULL, // open_gather + aead_tls_get_iv, // get_iv + aead_tls_tag_len, +}; + +static const EVP_AEAD aead_aes_256_cbc_sha256_tls = { + SHA256_DIGEST_LENGTH + 32, // key len (SHA256 + AES256) + 16, // nonce len (IV) + 16 + SHA256_DIGEST_LENGTH, // overhead (padding + SHA256) + SHA256_DIGEST_LENGTH, // max tag length + 0, // seal_scatter_supports_extra_in + + NULL, // init + aead_aes_256_cbc_sha256_tls_init, + aead_tls_cleanup, + aead_tls_open, + aead_tls_seal_scatter, + NULL, // open_gather + NULL, // get_iv + aead_tls_tag_len, +}; + +static const EVP_AEAD aead_aes_256_cbc_sha384_tls = { + SHA384_DIGEST_LENGTH + 32, // key len (SHA384 + AES256) + 16, // nonce len (IV) + 16 + SHA384_DIGEST_LENGTH, // overhead (padding + SHA384) + SHA384_DIGEST_LENGTH, // max tag length + 0, // seal_scatter_supports_extra_in + + NULL, // init + aead_aes_256_cbc_sha384_tls_init, + aead_tls_cleanup, + aead_tls_open, + aead_tls_seal_scatter, + NULL, // open_gather + NULL, // get_iv + aead_tls_tag_len, +}; + +static const EVP_AEAD aead_des_ede3_cbc_sha1_tls = { + SHA_DIGEST_LENGTH + 24, // key len (SHA1 + 3DES) + 8, // nonce len (IV) + 8 + SHA_DIGEST_LENGTH, // overhead (padding + SHA1) + SHA_DIGEST_LENGTH, // max tag length + 0, // seal_scatter_supports_extra_in + + NULL, // init + aead_des_ede3_cbc_sha1_tls_init, + aead_tls_cleanup, + aead_tls_open, + aead_tls_seal_scatter, + NULL, // open_gather + NULL, // get_iv + aead_tls_tag_len, +}; + +static const EVP_AEAD aead_des_ede3_cbc_sha1_tls_implicit_iv = { + SHA_DIGEST_LENGTH + 24 + 8, // key len (SHA1 + 3DES + IV) + 0, // nonce len + 8 + SHA_DIGEST_LENGTH, // overhead (padding + SHA1) + SHA_DIGEST_LENGTH, // max tag length + 0, // seal_scatter_supports_extra_in + + NULL, // init + aead_des_ede3_cbc_sha1_tls_implicit_iv_init, + aead_tls_cleanup, + aead_tls_open, + aead_tls_seal_scatter, + NULL, // open_gather + aead_tls_get_iv, // get_iv + aead_tls_tag_len, +}; + +static const EVP_AEAD aead_null_sha1_tls = { + SHA_DIGEST_LENGTH, // key len + 0, // nonce len + SHA_DIGEST_LENGTH, // overhead (SHA1) + SHA_DIGEST_LENGTH, // max tag length + 0, // seal_scatter_supports_extra_in + + NULL, // init + aead_null_sha1_tls_init, + aead_tls_cleanup, + aead_tls_open, + aead_tls_seal_scatter, + NULL, // open_gather + NULL, // get_iv + aead_tls_tag_len, +}; + +const EVP_AEAD *EVP_aead_aes_128_cbc_sha1_tls(void) { + return &aead_aes_128_cbc_sha1_tls; +} + +const EVP_AEAD *EVP_aead_aes_128_cbc_sha1_tls_implicit_iv(void) { + return &aead_aes_128_cbc_sha1_tls_implicit_iv; +} + +const EVP_AEAD *EVP_aead_aes_128_cbc_sha256_tls(void) { + return &aead_aes_128_cbc_sha256_tls; +} + +const EVP_AEAD *EVP_aead_aes_256_cbc_sha1_tls(void) { + return &aead_aes_256_cbc_sha1_tls; +} + +const EVP_AEAD *EVP_aead_aes_256_cbc_sha1_tls_implicit_iv(void) { + return &aead_aes_256_cbc_sha1_tls_implicit_iv; +} + +const EVP_AEAD *EVP_aead_aes_256_cbc_sha256_tls(void) { + return &aead_aes_256_cbc_sha256_tls; +} + +const EVP_AEAD *EVP_aead_aes_256_cbc_sha384_tls(void) { + return &aead_aes_256_cbc_sha384_tls; +} + +const EVP_AEAD *EVP_aead_des_ede3_cbc_sha1_tls(void) { + return &aead_des_ede3_cbc_sha1_tls; +} + +const EVP_AEAD *EVP_aead_des_ede3_cbc_sha1_tls_implicit_iv(void) { + return &aead_des_ede3_cbc_sha1_tls_implicit_iv; +} + +const EVP_AEAD *EVP_aead_null_sha1_tls(void) { return &aead_null_sha1_tls; } diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/cipher_extra/e_tls.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/cipher_extra/e_tls.c.grpc_back new file mode 100644 index 0000000..bba22be --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/cipher_extra/e_tls.c.grpc_back @@ -0,0 +1,680 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../fipsmodule/cipher/internal.h" +#include "../internal.h" +#include "internal.h" + + +typedef struct { + EVP_CIPHER_CTX cipher_ctx; + HMAC_CTX hmac_ctx; + // mac_key is the portion of the key used for the MAC. It is retained + // separately for the constant-time CBC code. + uint8_t mac_key[EVP_MAX_MD_SIZE]; + uint8_t mac_key_len; + // implicit_iv is one iff this is a pre-TLS-1.1 CBC cipher without an explicit + // IV. + char implicit_iv; +} AEAD_TLS_CTX; + +OPENSSL_COMPILE_ASSERT(EVP_MAX_MD_SIZE < 256, mac_key_len_fits_in_uint8_t); + +static void aead_tls_cleanup(EVP_AEAD_CTX *ctx) { + AEAD_TLS_CTX *tls_ctx = (AEAD_TLS_CTX *)ctx->aead_state; + EVP_CIPHER_CTX_cleanup(&tls_ctx->cipher_ctx); + HMAC_CTX_cleanup(&tls_ctx->hmac_ctx); + OPENSSL_free(tls_ctx); + ctx->aead_state = NULL; +} + +static int aead_tls_init(EVP_AEAD_CTX *ctx, const uint8_t *key, size_t key_len, + size_t tag_len, enum evp_aead_direction_t dir, + const EVP_CIPHER *cipher, const EVP_MD *md, + char implicit_iv) { + if (tag_len != EVP_AEAD_DEFAULT_TAG_LENGTH && + tag_len != EVP_MD_size(md)) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_TAG_SIZE); + return 0; + } + + if (key_len != EVP_AEAD_key_length(ctx->aead)) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_KEY_LENGTH); + return 0; + } + + size_t mac_key_len = EVP_MD_size(md); + size_t enc_key_len = EVP_CIPHER_key_length(cipher); + assert(mac_key_len + enc_key_len + + (implicit_iv ? EVP_CIPHER_iv_length(cipher) : 0) == key_len); + + AEAD_TLS_CTX *tls_ctx = OPENSSL_malloc(sizeof(AEAD_TLS_CTX)); + if (tls_ctx == NULL) { + OPENSSL_PUT_ERROR(CIPHER, ERR_R_MALLOC_FAILURE); + return 0; + } + EVP_CIPHER_CTX_init(&tls_ctx->cipher_ctx); + HMAC_CTX_init(&tls_ctx->hmac_ctx); + assert(mac_key_len <= EVP_MAX_MD_SIZE); + OPENSSL_memcpy(tls_ctx->mac_key, key, mac_key_len); + tls_ctx->mac_key_len = (uint8_t)mac_key_len; + tls_ctx->implicit_iv = implicit_iv; + + ctx->aead_state = tls_ctx; + if (!EVP_CipherInit_ex(&tls_ctx->cipher_ctx, cipher, NULL, &key[mac_key_len], + implicit_iv ? &key[mac_key_len + enc_key_len] : NULL, + dir == evp_aead_seal) || + !HMAC_Init_ex(&tls_ctx->hmac_ctx, key, mac_key_len, md, NULL)) { + aead_tls_cleanup(ctx); + ctx->aead_state = NULL; + return 0; + } + EVP_CIPHER_CTX_set_padding(&tls_ctx->cipher_ctx, 0); + + return 1; +} + +static size_t aead_tls_tag_len(const EVP_AEAD_CTX *ctx, const size_t in_len, + const size_t extra_in_len) { + assert(extra_in_len == 0); + AEAD_TLS_CTX *tls_ctx = (AEAD_TLS_CTX *)ctx->aead_state; + + const size_t hmac_len = HMAC_size(&tls_ctx->hmac_ctx); + if (EVP_CIPHER_CTX_mode(&tls_ctx->cipher_ctx) != EVP_CIPH_CBC_MODE) { + // The NULL cipher. + return hmac_len; + } + + const size_t block_size = EVP_CIPHER_CTX_block_size(&tls_ctx->cipher_ctx); + // An overflow of |in_len + hmac_len| doesn't affect the result mod + // |block_size|, provided that |block_size| is a smaller power of two. + assert(block_size != 0 && (block_size & (block_size - 1)) == 0); + const size_t pad_len = block_size - (in_len + hmac_len) % block_size; + return hmac_len + pad_len; +} + +static int aead_tls_seal_scatter(const EVP_AEAD_CTX *ctx, uint8_t *out, + uint8_t *out_tag, size_t *out_tag_len, + const size_t max_out_tag_len, + const uint8_t *nonce, const size_t nonce_len, + const uint8_t *in, const size_t in_len, + const uint8_t *extra_in, + const size_t extra_in_len, const uint8_t *ad, + const size_t ad_len) { + AEAD_TLS_CTX *tls_ctx = (AEAD_TLS_CTX *)ctx->aead_state; + + if (!tls_ctx->cipher_ctx.encrypt) { + // Unlike a normal AEAD, a TLS AEAD may only be used in one direction. + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_OPERATION); + return 0; + } + + if (in_len > INT_MAX) { + // EVP_CIPHER takes int as input. + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE); + return 0; + } + + if (max_out_tag_len < aead_tls_tag_len(ctx, in_len, extra_in_len)) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL); + return 0; + } + + if (nonce_len != EVP_AEAD_nonce_length(ctx->aead)) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_NONCE_SIZE); + return 0; + } + + if (ad_len != 13 - 2 /* length bytes */) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_AD_SIZE); + return 0; + } + + // To allow for CBC mode which changes cipher length, |ad| doesn't include the + // length for legacy ciphers. + uint8_t ad_extra[2]; + ad_extra[0] = (uint8_t)(in_len >> 8); + ad_extra[1] = (uint8_t)(in_len & 0xff); + + // Compute the MAC. This must be first in case the operation is being done + // in-place. + uint8_t mac[EVP_MAX_MD_SIZE]; + unsigned mac_len; + if (!HMAC_Init_ex(&tls_ctx->hmac_ctx, NULL, 0, NULL, NULL) || + !HMAC_Update(&tls_ctx->hmac_ctx, ad, ad_len) || + !HMAC_Update(&tls_ctx->hmac_ctx, ad_extra, sizeof(ad_extra)) || + !HMAC_Update(&tls_ctx->hmac_ctx, in, in_len) || + !HMAC_Final(&tls_ctx->hmac_ctx, mac, &mac_len)) { + return 0; + } + + // Configure the explicit IV. + if (EVP_CIPHER_CTX_mode(&tls_ctx->cipher_ctx) == EVP_CIPH_CBC_MODE && + !tls_ctx->implicit_iv && + !EVP_EncryptInit_ex(&tls_ctx->cipher_ctx, NULL, NULL, NULL, nonce)) { + return 0; + } + + // Encrypt the input. + int len; + if (!EVP_EncryptUpdate(&tls_ctx->cipher_ctx, out, &len, in, (int)in_len)) { + return 0; + } + + unsigned block_size = EVP_CIPHER_CTX_block_size(&tls_ctx->cipher_ctx); + + // Feed the MAC into the cipher in two steps. First complete the final partial + // block from encrypting the input and split the result between |out| and + // |out_tag|. Then feed the rest. + + const size_t early_mac_len = (block_size - (in_len % block_size)) % block_size; + if (early_mac_len != 0) { + assert(len + block_size - early_mac_len == in_len); + uint8_t buf[EVP_MAX_BLOCK_LENGTH]; + int buf_len; + if (!EVP_EncryptUpdate(&tls_ctx->cipher_ctx, buf, &buf_len, mac, + (int)early_mac_len)) { + return 0; + } + assert(buf_len == (int)block_size); + OPENSSL_memcpy(out + len, buf, block_size - early_mac_len); + OPENSSL_memcpy(out_tag, buf + block_size - early_mac_len, early_mac_len); + } + size_t tag_len = early_mac_len; + + if (!EVP_EncryptUpdate(&tls_ctx->cipher_ctx, out_tag + tag_len, &len, + mac + tag_len, mac_len - tag_len)) { + return 0; + } + tag_len += len; + + if (block_size > 1) { + assert(block_size <= 256); + assert(EVP_CIPHER_CTX_mode(&tls_ctx->cipher_ctx) == EVP_CIPH_CBC_MODE); + + // Compute padding and feed that into the cipher. + uint8_t padding[256]; + unsigned padding_len = block_size - ((in_len + mac_len) % block_size); + OPENSSL_memset(padding, padding_len - 1, padding_len); + if (!EVP_EncryptUpdate(&tls_ctx->cipher_ctx, out_tag + tag_len, &len, + padding, (int)padding_len)) { + return 0; + } + tag_len += len; + } + + if (!EVP_EncryptFinal_ex(&tls_ctx->cipher_ctx, out_tag + tag_len, &len)) { + return 0; + } + assert(len == 0); // Padding is explicit. + assert(tag_len == aead_tls_tag_len(ctx, in_len, extra_in_len)); + + *out_tag_len = tag_len; + return 1; +} + +static int aead_tls_open(const EVP_AEAD_CTX *ctx, uint8_t *out, size_t *out_len, + size_t max_out_len, const uint8_t *nonce, + size_t nonce_len, const uint8_t *in, size_t in_len, + const uint8_t *ad, size_t ad_len) { + AEAD_TLS_CTX *tls_ctx = (AEAD_TLS_CTX *)ctx->aead_state; + + if (tls_ctx->cipher_ctx.encrypt) { + // Unlike a normal AEAD, a TLS AEAD may only be used in one direction. + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_OPERATION); + return 0; + } + + if (in_len < HMAC_size(&tls_ctx->hmac_ctx)) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT); + return 0; + } + + if (max_out_len < in_len) { + // This requires that the caller provide space for the MAC, even though it + // will always be removed on return. + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL); + return 0; + } + + if (nonce_len != EVP_AEAD_nonce_length(ctx->aead)) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_NONCE_SIZE); + return 0; + } + + if (ad_len != 13 - 2 /* length bytes */) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_AD_SIZE); + return 0; + } + + if (in_len > INT_MAX) { + // EVP_CIPHER takes int as input. + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE); + return 0; + } + + // Configure the explicit IV. + if (EVP_CIPHER_CTX_mode(&tls_ctx->cipher_ctx) == EVP_CIPH_CBC_MODE && + !tls_ctx->implicit_iv && + !EVP_DecryptInit_ex(&tls_ctx->cipher_ctx, NULL, NULL, NULL, nonce)) { + return 0; + } + + // Decrypt to get the plaintext + MAC + padding. + size_t total = 0; + int len; + if (!EVP_DecryptUpdate(&tls_ctx->cipher_ctx, out, &len, in, (int)in_len)) { + return 0; + } + total += len; + if (!EVP_DecryptFinal_ex(&tls_ctx->cipher_ctx, out + total, &len)) { + return 0; + } + total += len; + assert(total == in_len); + + // Remove CBC padding. Code from here on is timing-sensitive with respect to + // |padding_ok| and |data_plus_mac_len| for CBC ciphers. + size_t data_plus_mac_len; + crypto_word_t padding_ok; + if (EVP_CIPHER_CTX_mode(&tls_ctx->cipher_ctx) == EVP_CIPH_CBC_MODE) { + if (!EVP_tls_cbc_remove_padding( + &padding_ok, &data_plus_mac_len, out, total, + EVP_CIPHER_CTX_block_size(&tls_ctx->cipher_ctx), + HMAC_size(&tls_ctx->hmac_ctx))) { + // Publicly invalid. This can be rejected in non-constant time. + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT); + return 0; + } + } else { + padding_ok = CONSTTIME_TRUE_W; + data_plus_mac_len = total; + // |data_plus_mac_len| = |total| = |in_len| at this point. |in_len| has + // already been checked against the MAC size at the top of the function. + assert(data_plus_mac_len >= HMAC_size(&tls_ctx->hmac_ctx)); + } + size_t data_len = data_plus_mac_len - HMAC_size(&tls_ctx->hmac_ctx); + + // At this point, if the padding is valid, the first |data_plus_mac_len| bytes + // after |out| are the plaintext and MAC. Otherwise, |data_plus_mac_len| is + // still large enough to extract a MAC, but it will be irrelevant. + + // To allow for CBC mode which changes cipher length, |ad| doesn't include the + // length for legacy ciphers. + uint8_t ad_fixed[13]; + OPENSSL_memcpy(ad_fixed, ad, 11); + ad_fixed[11] = (uint8_t)(data_len >> 8); + ad_fixed[12] = (uint8_t)(data_len & 0xff); + ad_len += 2; + + // Compute the MAC and extract the one in the record. + uint8_t mac[EVP_MAX_MD_SIZE]; + size_t mac_len; + uint8_t record_mac_tmp[EVP_MAX_MD_SIZE]; + uint8_t *record_mac; + if (EVP_CIPHER_CTX_mode(&tls_ctx->cipher_ctx) == EVP_CIPH_CBC_MODE && + EVP_tls_cbc_record_digest_supported(tls_ctx->hmac_ctx.md)) { + if (!EVP_tls_cbc_digest_record(tls_ctx->hmac_ctx.md, mac, &mac_len, + ad_fixed, out, data_plus_mac_len, total, + tls_ctx->mac_key, tls_ctx->mac_key_len)) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT); + return 0; + } + assert(mac_len == HMAC_size(&tls_ctx->hmac_ctx)); + + record_mac = record_mac_tmp; + EVP_tls_cbc_copy_mac(record_mac, mac_len, out, data_plus_mac_len, total); + } else { + // We should support the constant-time path for all CBC-mode ciphers + // implemented. + assert(EVP_CIPHER_CTX_mode(&tls_ctx->cipher_ctx) != EVP_CIPH_CBC_MODE); + + unsigned mac_len_u; + if (!HMAC_Init_ex(&tls_ctx->hmac_ctx, NULL, 0, NULL, NULL) || + !HMAC_Update(&tls_ctx->hmac_ctx, ad_fixed, ad_len) || + !HMAC_Update(&tls_ctx->hmac_ctx, out, data_len) || + !HMAC_Final(&tls_ctx->hmac_ctx, mac, &mac_len_u)) { + return 0; + } + mac_len = mac_len_u; + + assert(mac_len == HMAC_size(&tls_ctx->hmac_ctx)); + record_mac = &out[data_len]; + } + + // Perform the MAC check and the padding check in constant-time. It should be + // safe to simply perform the padding check first, but it would not be under a + // different choice of MAC location on padding failure. See + // EVP_tls_cbc_remove_padding. + crypto_word_t good = + constant_time_eq_int(CRYPTO_memcmp(record_mac, mac, mac_len), 0); + good &= padding_ok; + if (!good) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT); + return 0; + } + + // End of timing-sensitive code. + + *out_len = data_len; + return 1; +} + +static int aead_aes_128_cbc_sha1_tls_init(EVP_AEAD_CTX *ctx, const uint8_t *key, + size_t key_len, size_t tag_len, + enum evp_aead_direction_t dir) { + return aead_tls_init(ctx, key, key_len, tag_len, dir, EVP_aes_128_cbc(), + EVP_sha1(), 0); +} + +static int aead_aes_128_cbc_sha1_tls_implicit_iv_init( + EVP_AEAD_CTX *ctx, const uint8_t *key, size_t key_len, size_t tag_len, + enum evp_aead_direction_t dir) { + return aead_tls_init(ctx, key, key_len, tag_len, dir, EVP_aes_128_cbc(), + EVP_sha1(), 1); +} + +static int aead_aes_128_cbc_sha256_tls_init(EVP_AEAD_CTX *ctx, + const uint8_t *key, size_t key_len, + size_t tag_len, + enum evp_aead_direction_t dir) { + return aead_tls_init(ctx, key, key_len, tag_len, dir, EVP_aes_128_cbc(), + EVP_sha256(), 0); +} + +static int aead_aes_256_cbc_sha1_tls_init(EVP_AEAD_CTX *ctx, const uint8_t *key, + size_t key_len, size_t tag_len, + enum evp_aead_direction_t dir) { + return aead_tls_init(ctx, key, key_len, tag_len, dir, EVP_aes_256_cbc(), + EVP_sha1(), 0); +} + +static int aead_aes_256_cbc_sha1_tls_implicit_iv_init( + EVP_AEAD_CTX *ctx, const uint8_t *key, size_t key_len, size_t tag_len, + enum evp_aead_direction_t dir) { + return aead_tls_init(ctx, key, key_len, tag_len, dir, EVP_aes_256_cbc(), + EVP_sha1(), 1); +} + +static int aead_aes_256_cbc_sha256_tls_init(EVP_AEAD_CTX *ctx, + const uint8_t *key, size_t key_len, + size_t tag_len, + enum evp_aead_direction_t dir) { + return aead_tls_init(ctx, key, key_len, tag_len, dir, EVP_aes_256_cbc(), + EVP_sha256(), 0); +} + +static int aead_aes_256_cbc_sha384_tls_init(EVP_AEAD_CTX *ctx, + const uint8_t *key, size_t key_len, + size_t tag_len, + enum evp_aead_direction_t dir) { + return aead_tls_init(ctx, key, key_len, tag_len, dir, EVP_aes_256_cbc(), + EVP_sha384(), 0); +} + +static int aead_des_ede3_cbc_sha1_tls_init(EVP_AEAD_CTX *ctx, + const uint8_t *key, size_t key_len, + size_t tag_len, + enum evp_aead_direction_t dir) { + return aead_tls_init(ctx, key, key_len, tag_len, dir, EVP_des_ede3_cbc(), + EVP_sha1(), 0); +} + +static int aead_des_ede3_cbc_sha1_tls_implicit_iv_init( + EVP_AEAD_CTX *ctx, const uint8_t *key, size_t key_len, size_t tag_len, + enum evp_aead_direction_t dir) { + return aead_tls_init(ctx, key, key_len, tag_len, dir, EVP_des_ede3_cbc(), + EVP_sha1(), 1); +} + +static int aead_tls_get_iv(const EVP_AEAD_CTX *ctx, const uint8_t **out_iv, + size_t *out_iv_len) { + const AEAD_TLS_CTX *tls_ctx = (AEAD_TLS_CTX*) ctx->aead_state; + const size_t iv_len = EVP_CIPHER_CTX_iv_length(&tls_ctx->cipher_ctx); + if (iv_len <= 1) { + return 0; + } + + *out_iv = tls_ctx->cipher_ctx.iv; + *out_iv_len = iv_len; + return 1; +} + +static int aead_null_sha1_tls_init(EVP_AEAD_CTX *ctx, const uint8_t *key, + size_t key_len, size_t tag_len, + enum evp_aead_direction_t dir) { + return aead_tls_init(ctx, key, key_len, tag_len, dir, EVP_enc_null(), + EVP_sha1(), 1 /* implicit iv */); +} + +static const EVP_AEAD aead_aes_128_cbc_sha1_tls = { + SHA_DIGEST_LENGTH + 16, // key len (SHA1 + AES128) + 16, // nonce len (IV) + 16 + SHA_DIGEST_LENGTH, // overhead (padding + SHA1) + SHA_DIGEST_LENGTH, // max tag length + 0, // seal_scatter_supports_extra_in + + NULL, // init + aead_aes_128_cbc_sha1_tls_init, + aead_tls_cleanup, + aead_tls_open, + aead_tls_seal_scatter, + NULL, // open_gather + NULL, // get_iv + aead_tls_tag_len, +}; + +static const EVP_AEAD aead_aes_128_cbc_sha1_tls_implicit_iv = { + SHA_DIGEST_LENGTH + 16 + 16, // key len (SHA1 + AES128 + IV) + 0, // nonce len + 16 + SHA_DIGEST_LENGTH, // overhead (padding + SHA1) + SHA_DIGEST_LENGTH, // max tag length + 0, // seal_scatter_supports_extra_in + + NULL, // init + aead_aes_128_cbc_sha1_tls_implicit_iv_init, + aead_tls_cleanup, + aead_tls_open, + aead_tls_seal_scatter, + NULL, // open_gather + aead_tls_get_iv, // get_iv + aead_tls_tag_len, +}; + +static const EVP_AEAD aead_aes_128_cbc_sha256_tls = { + SHA256_DIGEST_LENGTH + 16, // key len (SHA256 + AES128) + 16, // nonce len (IV) + 16 + SHA256_DIGEST_LENGTH, // overhead (padding + SHA256) + SHA256_DIGEST_LENGTH, // max tag length + 0, // seal_scatter_supports_extra_in + + NULL, // init + aead_aes_128_cbc_sha256_tls_init, + aead_tls_cleanup, + aead_tls_open, + aead_tls_seal_scatter, + NULL, // open_gather + NULL, // get_iv + aead_tls_tag_len, +}; + +static const EVP_AEAD aead_aes_256_cbc_sha1_tls = { + SHA_DIGEST_LENGTH + 32, // key len (SHA1 + AES256) + 16, // nonce len (IV) + 16 + SHA_DIGEST_LENGTH, // overhead (padding + SHA1) + SHA_DIGEST_LENGTH, // max tag length + 0, // seal_scatter_supports_extra_in + + NULL, // init + aead_aes_256_cbc_sha1_tls_init, + aead_tls_cleanup, + aead_tls_open, + aead_tls_seal_scatter, + NULL, // open_gather + NULL, // get_iv + aead_tls_tag_len, +}; + +static const EVP_AEAD aead_aes_256_cbc_sha1_tls_implicit_iv = { + SHA_DIGEST_LENGTH + 32 + 16, // key len (SHA1 + AES256 + IV) + 0, // nonce len + 16 + SHA_DIGEST_LENGTH, // overhead (padding + SHA1) + SHA_DIGEST_LENGTH, // max tag length + 0, // seal_scatter_supports_extra_in + + NULL, // init + aead_aes_256_cbc_sha1_tls_implicit_iv_init, + aead_tls_cleanup, + aead_tls_open, + aead_tls_seal_scatter, + NULL, // open_gather + aead_tls_get_iv, // get_iv + aead_tls_tag_len, +}; + +static const EVP_AEAD aead_aes_256_cbc_sha256_tls = { + SHA256_DIGEST_LENGTH + 32, // key len (SHA256 + AES256) + 16, // nonce len (IV) + 16 + SHA256_DIGEST_LENGTH, // overhead (padding + SHA256) + SHA256_DIGEST_LENGTH, // max tag length + 0, // seal_scatter_supports_extra_in + + NULL, // init + aead_aes_256_cbc_sha256_tls_init, + aead_tls_cleanup, + aead_tls_open, + aead_tls_seal_scatter, + NULL, // open_gather + NULL, // get_iv + aead_tls_tag_len, +}; + +static const EVP_AEAD aead_aes_256_cbc_sha384_tls = { + SHA384_DIGEST_LENGTH + 32, // key len (SHA384 + AES256) + 16, // nonce len (IV) + 16 + SHA384_DIGEST_LENGTH, // overhead (padding + SHA384) + SHA384_DIGEST_LENGTH, // max tag length + 0, // seal_scatter_supports_extra_in + + NULL, // init + aead_aes_256_cbc_sha384_tls_init, + aead_tls_cleanup, + aead_tls_open, + aead_tls_seal_scatter, + NULL, // open_gather + NULL, // get_iv + aead_tls_tag_len, +}; + +static const EVP_AEAD aead_des_ede3_cbc_sha1_tls = { + SHA_DIGEST_LENGTH + 24, // key len (SHA1 + 3DES) + 8, // nonce len (IV) + 8 + SHA_DIGEST_LENGTH, // overhead (padding + SHA1) + SHA_DIGEST_LENGTH, // max tag length + 0, // seal_scatter_supports_extra_in + + NULL, // init + aead_des_ede3_cbc_sha1_tls_init, + aead_tls_cleanup, + aead_tls_open, + aead_tls_seal_scatter, + NULL, // open_gather + NULL, // get_iv + aead_tls_tag_len, +}; + +static const EVP_AEAD aead_des_ede3_cbc_sha1_tls_implicit_iv = { + SHA_DIGEST_LENGTH + 24 + 8, // key len (SHA1 + 3DES + IV) + 0, // nonce len + 8 + SHA_DIGEST_LENGTH, // overhead (padding + SHA1) + SHA_DIGEST_LENGTH, // max tag length + 0, // seal_scatter_supports_extra_in + + NULL, // init + aead_des_ede3_cbc_sha1_tls_implicit_iv_init, + aead_tls_cleanup, + aead_tls_open, + aead_tls_seal_scatter, + NULL, // open_gather + aead_tls_get_iv, // get_iv + aead_tls_tag_len, +}; + +static const EVP_AEAD aead_null_sha1_tls = { + SHA_DIGEST_LENGTH, // key len + 0, // nonce len + SHA_DIGEST_LENGTH, // overhead (SHA1) + SHA_DIGEST_LENGTH, // max tag length + 0, // seal_scatter_supports_extra_in + + NULL, // init + aead_null_sha1_tls_init, + aead_tls_cleanup, + aead_tls_open, + aead_tls_seal_scatter, + NULL, // open_gather + NULL, // get_iv + aead_tls_tag_len, +}; + +const EVP_AEAD *EVP_aead_aes_128_cbc_sha1_tls(void) { + return &aead_aes_128_cbc_sha1_tls; +} + +const EVP_AEAD *EVP_aead_aes_128_cbc_sha1_tls_implicit_iv(void) { + return &aead_aes_128_cbc_sha1_tls_implicit_iv; +} + +const EVP_AEAD *EVP_aead_aes_128_cbc_sha256_tls(void) { + return &aead_aes_128_cbc_sha256_tls; +} + +const EVP_AEAD *EVP_aead_aes_256_cbc_sha1_tls(void) { + return &aead_aes_256_cbc_sha1_tls; +} + +const EVP_AEAD *EVP_aead_aes_256_cbc_sha1_tls_implicit_iv(void) { + return &aead_aes_256_cbc_sha1_tls_implicit_iv; +} + +const EVP_AEAD *EVP_aead_aes_256_cbc_sha256_tls(void) { + return &aead_aes_256_cbc_sha256_tls; +} + +const EVP_AEAD *EVP_aead_aes_256_cbc_sha384_tls(void) { + return &aead_aes_256_cbc_sha384_tls; +} + +const EVP_AEAD *EVP_aead_des_ede3_cbc_sha1_tls(void) { + return &aead_des_ede3_cbc_sha1_tls; +} + +const EVP_AEAD *EVP_aead_des_ede3_cbc_sha1_tls_implicit_iv(void) { + return &aead_des_ede3_cbc_sha1_tls_implicit_iv; +} + +const EVP_AEAD *EVP_aead_null_sha1_tls(void) { return &aead_null_sha1_tls; } diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/cipher_extra/internal.h b/FoodApp/Pods/BoringSSL-GRPC/crypto/cipher_extra/internal.h new file mode 100644 index 0000000..9edbf9d --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/cipher_extra/internal.h @@ -0,0 +1,128 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 OPENSSL_HEADER_CIPHER_EXTRA_INTERNAL_H +#define OPENSSL_HEADER_CIPHER_EXTRA_INTERNAL_H + +#include + +#include "../internal.h" + +#if defined(__cplusplus) +extern "C" { +#endif + + +// EVP_tls_cbc_get_padding determines the padding from the decrypted, TLS, CBC +// record in |in|. This decrypted record should not include any "decrypted" +// explicit IV. If the record is publicly invalid, it returns zero. Otherwise, +// it returns one and sets |*out_padding_ok| to all ones (0xfff..f) if the +// padding is valid and zero otherwise. It then sets |*out_len| to the length +// with the padding removed or |in_len| if invalid. +// +// If the function returns one, it runs in time independent of the contents of +// |in|. It is also guaranteed that |*out_len| >= |mac_size|, satisfying +// |EVP_tls_cbc_copy_mac|'s precondition. +int EVP_tls_cbc_remove_padding(crypto_word_t *out_padding_ok, size_t *out_len, + const uint8_t *in, size_t in_len, + size_t block_size, size_t mac_size); + +// EVP_tls_cbc_copy_mac copies |md_size| bytes from the end of the first +// |in_len| bytes of |in| to |out| in constant time (independent of the concrete +// value of |in_len|, which may vary within a 256-byte window). |in| must point +// to a buffer of |orig_len| bytes. +// +// On entry: +// orig_len >= in_len >= md_size +// md_size <= EVP_MAX_MD_SIZE +void EVP_tls_cbc_copy_mac(uint8_t *out, size_t md_size, const uint8_t *in, + size_t in_len, size_t orig_len); + +// EVP_tls_cbc_record_digest_supported returns 1 iff |md| is a hash function +// which EVP_tls_cbc_digest_record supports. +int EVP_tls_cbc_record_digest_supported(const EVP_MD *md); + +// EVP_tls_cbc_digest_record computes the MAC of a decrypted, padded TLS +// record. +// +// md: the hash function used in the HMAC. +// EVP_tls_cbc_record_digest_supported must return true for this hash. +// md_out: the digest output. At most EVP_MAX_MD_SIZE bytes will be written. +// md_out_size: the number of output bytes is written here. +// header: the 13-byte, TLS record header. +// data: the record data itself +// 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. +// +// 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. ) +int EVP_tls_cbc_digest_record(const EVP_MD *md, uint8_t *md_out, + size_t *md_out_size, const uint8_t header[13], + const uint8_t *data, size_t data_plus_mac_size, + size_t data_plus_mac_plus_padding_size, + const uint8_t *mac_secret, + unsigned mac_secret_length); + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_CIPHER_EXTRA_INTERNAL_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/cipher_extra/internal.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/cipher_extra/internal.h.grpc_back new file mode 100644 index 0000000..1d2c4e1 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/cipher_extra/internal.h.grpc_back @@ -0,0 +1,128 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 OPENSSL_HEADER_CIPHER_EXTRA_INTERNAL_H +#define OPENSSL_HEADER_CIPHER_EXTRA_INTERNAL_H + +#include + +#include "../internal.h" + +#if defined(__cplusplus) +extern "C" { +#endif + + +// EVP_tls_cbc_get_padding determines the padding from the decrypted, TLS, CBC +// record in |in|. This decrypted record should not include any "decrypted" +// explicit IV. If the record is publicly invalid, it returns zero. Otherwise, +// it returns one and sets |*out_padding_ok| to all ones (0xfff..f) if the +// padding is valid and zero otherwise. It then sets |*out_len| to the length +// with the padding removed or |in_len| if invalid. +// +// If the function returns one, it runs in time independent of the contents of +// |in|. It is also guaranteed that |*out_len| >= |mac_size|, satisfying +// |EVP_tls_cbc_copy_mac|'s precondition. +int EVP_tls_cbc_remove_padding(crypto_word_t *out_padding_ok, size_t *out_len, + const uint8_t *in, size_t in_len, + size_t block_size, size_t mac_size); + +// EVP_tls_cbc_copy_mac copies |md_size| bytes from the end of the first +// |in_len| bytes of |in| to |out| in constant time (independent of the concrete +// value of |in_len|, which may vary within a 256-byte window). |in| must point +// to a buffer of |orig_len| bytes. +// +// On entry: +// orig_len >= in_len >= md_size +// md_size <= EVP_MAX_MD_SIZE +void EVP_tls_cbc_copy_mac(uint8_t *out, size_t md_size, const uint8_t *in, + size_t in_len, size_t orig_len); + +// EVP_tls_cbc_record_digest_supported returns 1 iff |md| is a hash function +// which EVP_tls_cbc_digest_record supports. +int EVP_tls_cbc_record_digest_supported(const EVP_MD *md); + +// EVP_tls_cbc_digest_record computes the MAC of a decrypted, padded TLS +// record. +// +// md: the hash function used in the HMAC. +// EVP_tls_cbc_record_digest_supported must return true for this hash. +// md_out: the digest output. At most EVP_MAX_MD_SIZE bytes will be written. +// md_out_size: the number of output bytes is written here. +// header: the 13-byte, TLS record header. +// data: the record data itself +// 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. +// +// 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. ) +int EVP_tls_cbc_digest_record(const EVP_MD *md, uint8_t *md_out, + size_t *md_out_size, const uint8_t header[13], + const uint8_t *data, size_t data_plus_mac_size, + size_t data_plus_mac_plus_padding_size, + const uint8_t *mac_secret, + unsigned mac_secret_length); + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_CIPHER_EXTRA_INTERNAL_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/cipher_extra/tls_cbc.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/cipher_extra/tls_cbc.c new file mode 100644 index 0000000..8a7906e --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/cipher_extra/tls_cbc.c @@ -0,0 +1,482 @@ +/* ==================================================================== + * 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 +#include + +#include +#include +#include + +#include "../internal.h" +#include "internal.h" +#include "../fipsmodule/cipher/internal.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 + +int EVP_tls_cbc_remove_padding(crypto_word_t *out_padding_ok, size_t *out_len, + const uint8_t *in, size_t in_len, + size_t block_size, size_t mac_size) { + const size_t overhead = 1 /* padding length byte */ + mac_size; + + // These lengths are all public so we can test them in non-constant time. + if (overhead > in_len) { + return 0; + } + + size_t padding_length = in[in_len - 1]; + + crypto_word_t good = constant_time_ge_w(in_len, 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.) + size_t to_check = 256; // maximum amount of padding, inc length byte. + if (to_check > in_len) { + to_check = in_len; + } + + for (size_t i = 0; i < to_check; i++) { + uint8_t mask = constant_time_ge_8(padding_length, i); + uint8_t b = in[in_len - 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_w(0xff, good & 0xff); + + // Always treat |padding_length| as zero on error. If, assuming block size of + // 16, a padding of [<15 arbitrary bytes> 15] treated |padding_length| as 16 + // and returned -1, distinguishing good MAC and bad padding from bad MAC and + // bad padding would give POODLE's padding oracle. + padding_length = good & (padding_length + 1); + *out_len = in_len - padding_length; + *out_padding_ok = good; + return 1; +} + +void EVP_tls_cbc_copy_mac(uint8_t *out, size_t md_size, const uint8_t *in, + size_t in_len, size_t orig_len) { + uint8_t rotated_mac1[EVP_MAX_MD_SIZE], rotated_mac2[EVP_MAX_MD_SIZE]; + uint8_t *rotated_mac = rotated_mac1; + uint8_t *rotated_mac_tmp = rotated_mac2; + + // mac_end is the index of |in| just after the end of the MAC. + size_t mac_end = in_len; + size_t mac_start = mac_end - md_size; + + assert(orig_len >= in_len); + assert(in_len >= md_size); + assert(md_size <= EVP_MAX_MD_SIZE); + + // scan_start contains the number of bytes that we can ignore because + // the MAC's position can only vary by 255 bytes. + size_t scan_start = 0; + // 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); + } + + size_t rotate_offset = 0; + uint8_t mac_started = 0; + OPENSSL_memset(rotated_mac, 0, md_size); + for (size_t i = scan_start, j = 0; i < orig_len; i++, j++) { + if (j >= md_size) { + j -= md_size; + } + crypto_word_t is_mac_start = constant_time_eq_w(i, mac_start); + mac_started |= is_mac_start; + uint8_t mac_ended = constant_time_ge_8(i, mac_end); + rotated_mac[j] |= in[i] & mac_started & ~mac_ended; + // Save the offset that |mac_start| is mapped to. + rotate_offset |= j & is_mac_start; + } + + // Now rotate the MAC. We rotate in log(md_size) steps, one for each bit + // position. + for (size_t offset = 1; offset < md_size; offset <<= 1, rotate_offset >>= 1) { + // Rotate by |offset| iff the corresponding bit is set in + // |rotate_offset|, placing the result in |rotated_mac_tmp|. + const uint8_t skip_rotate = (rotate_offset & 1) - 1; + for (size_t i = 0, j = offset; i < md_size; i++, j++) { + if (j >= md_size) { + j -= md_size; + } + rotated_mac_tmp[i] = + constant_time_select_8(skip_rotate, rotated_mac[i], rotated_mac[j]); + } + + // Swap pointers so |rotated_mac| contains the (possibly) rotated value. + // Note the number of iterations and thus the identity of these pointers is + // public information. + uint8_t *tmp = rotated_mac; + rotated_mac = rotated_mac_tmp; + rotated_mac_tmp = tmp; + } + + OPENSSL_memcpy(out, rotated_mac, md_size); +} + +// u32toBE serialises an unsigned, 32-bit number (n) as four bytes at (p) in +// big-endian order. The value of p is advanced by four. +#define u32toBE(n, p) \ + do { \ + *((p)++) = (uint8_t)((n) >> 24); \ + *((p)++) = (uint8_t)((n) >> 16); \ + *((p)++) = (uint8_t)((n) >> 8); \ + *((p)++) = (uint8_t)((n)); \ + } while (0) + +// u64toBE serialises an unsigned, 64-bit number (n) as eight bytes at (p) in +// big-endian order. The value of p is advanced by eight. +#define u64toBE(n, p) \ + do { \ + *((p)++) = (uint8_t)((n) >> 56); \ + *((p)++) = (uint8_t)((n) >> 48); \ + *((p)++) = (uint8_t)((n) >> 40); \ + *((p)++) = (uint8_t)((n) >> 32); \ + *((p)++) = (uint8_t)((n) >> 24); \ + *((p)++) = (uint8_t)((n) >> 16); \ + *((p)++) = (uint8_t)((n) >> 8); \ + *((p)++) = (uint8_t)((n)); \ + } while (0) + +typedef union { + SHA_CTX sha1; + SHA256_CTX sha256; + SHA512_CTX sha512; +} HASH_CTX; + +static void tls1_sha1_transform(HASH_CTX *ctx, const uint8_t *block) { + SHA1_Transform(&ctx->sha1, block); +} + +static void tls1_sha256_transform(HASH_CTX *ctx, const uint8_t *block) { + SHA256_Transform(&ctx->sha256, block); +} + +static void tls1_sha512_transform(HASH_CTX *ctx, const uint8_t *block) { + SHA512_Transform(&ctx->sha512, block); +} + +// 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_sha1_final_raw(HASH_CTX *ctx, uint8_t *md_out) { + SHA_CTX *sha1 = &ctx->sha1; + u32toBE(sha1->h[0], md_out); + u32toBE(sha1->h[1], md_out); + u32toBE(sha1->h[2], md_out); + u32toBE(sha1->h[3], md_out); + u32toBE(sha1->h[4], md_out); +} + +static void tls1_sha256_final_raw(HASH_CTX *ctx, uint8_t *md_out) { + SHA256_CTX *sha256 = &ctx->sha256; + for (unsigned i = 0; i < 8; i++) { + u32toBE(sha256->h[i], md_out); + } +} + +static void tls1_sha512_final_raw(HASH_CTX *ctx, uint8_t *md_out) { + SHA512_CTX *sha512 = &ctx->sha512; + for (unsigned i = 0; i < 8; i++) { + u64toBE(sha512->h[i], md_out); + } +} + +int EVP_tls_cbc_record_digest_supported(const EVP_MD *md) { + switch (EVP_MD_type(md)) { + case NID_sha1: + case NID_sha256: + case NID_sha384: + return 1; + + default: + return 0; + } +} + +int EVP_tls_cbc_digest_record(const EVP_MD *md, uint8_t *md_out, + size_t *md_out_size, const uint8_t header[13], + const uint8_t *data, size_t data_plus_mac_size, + size_t data_plus_mac_plus_padding_size, + const uint8_t *mac_secret, + unsigned mac_secret_length) { + HASH_CTX md_state; + void (*md_final_raw)(HASH_CTX *ctx, uint8_t *md_out); + void (*md_transform)(HASH_CTX *ctx, const uint8_t *block); + unsigned md_size, md_block_size = 64; + // md_length_size is the number of bytes in the length field that terminates + // the hash. + unsigned md_length_size = 8; + + // Bound the acceptable input so we can forget about many possible overflows + // later in this function. This is redundant with the record size limits in + // TLS. + if (data_plus_mac_plus_padding_size >= 1024 * 1024) { + assert(0); + return 0; + } + + switch (EVP_MD_type(md)) { + case NID_sha1: + SHA1_Init(&md_state.sha1); + md_final_raw = tls1_sha1_final_raw; + md_transform = tls1_sha1_transform; + md_size = SHA_DIGEST_LENGTH; + break; + + case NID_sha256: + SHA256_Init(&md_state.sha256); + md_final_raw = tls1_sha256_final_raw; + md_transform = tls1_sha256_transform; + md_size = SHA256_DIGEST_LENGTH; + break; + + case NID_sha384: + SHA384_Init(&md_state.sha512); + md_final_raw = tls1_sha512_final_raw; + md_transform = tls1_sha512_transform; + md_size = SHA384_DIGEST_LENGTH; + md_block_size = 128; + md_length_size = 16; + break; + + default: + // EVP_tls_cbc_record_digest_supported should have been called first to + // check that the hash function is supported. + assert(0); + *md_out_size = 0; + return 0; + } + + assert(md_length_size <= MAX_HASH_BIT_COUNT_BYTES); + assert(md_block_size <= MAX_HASH_BLOCK_SIZE); + assert(md_size <= EVP_MAX_MD_SIZE); + + static const size_t kHeaderLength = 13; + + // kVarianceBlocks 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. + // + // 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. + static const size_t kVarianceBlocks = 6; + + // From now on we're dealing with the MAC, which conceptually has 13 + // bytes of `header' before the start of the data. + size_t len = data_plus_mac_plus_padding_size + kHeaderLength; + // max_mac_bytes contains the maximum bytes of bytes in the MAC, including + // |header|, assuming that there's no padding. + size_t max_mac_bytes = len - md_size - 1; + // num_blocks is the maximum number of hash blocks. + size_t 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 |kVarianceBlocks| 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. + size_t num_starting_blocks = 0; + // k is the starting byte offset into the conceptual header||data where + // we start processing. + size_t k = 0; + // mac_end_offset is the index just past the end of the data to be + // MACed. + size_t mac_end_offset = data_plus_mac_size + kHeaderLength - md_size; + // c is the index of the 0x80 byte in the final hash block that + // contains application data. + size_t c = mac_end_offset % md_block_size; + // index_a is the hash block number that contains the 0x80 terminating + // value. + size_t index_a = mac_end_offset / md_block_size; + // index_b is the hash block number that contains the 64-bit hash + // length, in bits. + size_t index_b = (mac_end_offset + md_length_size) / md_block_size; + + if (num_blocks > kVarianceBlocks) { + num_starting_blocks = num_blocks - kVarianceBlocks; + k = md_block_size * num_starting_blocks; + } + + // bits is the hash-length in bits. It includes the additional hash + // block for the masked HMAC key. + size_t bits = 8 * mac_end_offset; // at most 18 bits to represent + + // Compute the initial HMAC block. + bits += 8 * md_block_size; + // hmac_pad is the masked HMAC key. + uint8_t hmac_pad[MAX_HASH_BLOCK_SIZE]; + OPENSSL_memset(hmac_pad, 0, md_block_size); + assert(mac_secret_length <= sizeof(hmac_pad)); + OPENSSL_memcpy(hmac_pad, mac_secret, mac_secret_length); + for (size_t i = 0; i < md_block_size; i++) { + hmac_pad[i] ^= 0x36; + } + + md_transform(&md_state, hmac_pad); + + // The length check means |bits| fits in four bytes. + uint8_t length_bytes[MAX_HASH_BIT_COUNT_BYTES]; + OPENSSL_memset(length_bytes, 0, md_length_size - 4); + length_bytes[md_length_size - 4] = (uint8_t)(bits >> 24); + length_bytes[md_length_size - 3] = (uint8_t)(bits >> 16); + length_bytes[md_length_size - 2] = (uint8_t)(bits >> 8); + length_bytes[md_length_size - 1] = (uint8_t)bits; + + if (k > 0) { + // k is a multiple of md_block_size. + uint8_t first_block[MAX_HASH_BLOCK_SIZE]; + OPENSSL_memcpy(first_block, header, 13); + OPENSSL_memcpy(first_block + 13, data, md_block_size - 13); + md_transform(&md_state, first_block); + for (size_t i = 1; i < k / md_block_size; i++) { + md_transform(&md_state, data + md_block_size * i - 13); + } + } + + uint8_t mac_out[EVP_MAX_MD_SIZE]; + OPENSSL_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 (size_t i = num_starting_blocks; + i <= num_starting_blocks + kVarianceBlocks; i++) { + uint8_t block[MAX_HASH_BLOCK_SIZE]; + uint8_t is_block_a = constant_time_eq_8(i, index_a); + uint8_t is_block_b = constant_time_eq_8(i, index_b); + for (size_t j = 0; j < md_block_size; j++) { + uint8_t b = 0; + if (k < kHeaderLength) { + b = header[k]; + } else if (k < data_plus_mac_plus_padding_size + kHeaderLength) { + b = data[k - kHeaderLength]; + } + k++; + + uint8_t is_past_c = is_block_a & constant_time_ge_8(j, c); + uint8_t 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, block); + md_final_raw(&md_state, block); + // If this is index_b, copy the hash value to |mac_out|. + for (size_t j = 0; j < md_size; j++) { + mac_out[j] |= block[j] & is_block_b; + } + } + + EVP_MD_CTX md_ctx; + EVP_MD_CTX_init(&md_ctx); + if (!EVP_DigestInit_ex(&md_ctx, md, NULL /* engine */)) { + EVP_MD_CTX_cleanup(&md_ctx); + return 0; + } + + // Complete the HMAC in the standard manner. + for (size_t i = 0; i < md_block_size; i++) { + hmac_pad[i] ^= 0x6a; + } + + EVP_DigestUpdate(&md_ctx, hmac_pad, md_block_size); + EVP_DigestUpdate(&md_ctx, mac_out, md_size); + unsigned md_out_size_u; + EVP_DigestFinal(&md_ctx, md_out, &md_out_size_u); + *md_out_size = md_out_size_u; + EVP_MD_CTX_cleanup(&md_ctx); + + return 1; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/cipher_extra/tls_cbc.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/cipher_extra/tls_cbc.c.grpc_back new file mode 100644 index 0000000..6f95130 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/cipher_extra/tls_cbc.c.grpc_back @@ -0,0 +1,482 @@ +/* ==================================================================== + * 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 +#include + +#include +#include +#include + +#include "../internal.h" +#include "internal.h" +#include "../fipsmodule/cipher/internal.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 + +int EVP_tls_cbc_remove_padding(crypto_word_t *out_padding_ok, size_t *out_len, + const uint8_t *in, size_t in_len, + size_t block_size, size_t mac_size) { + const size_t overhead = 1 /* padding length byte */ + mac_size; + + // These lengths are all public so we can test them in non-constant time. + if (overhead > in_len) { + return 0; + } + + size_t padding_length = in[in_len - 1]; + + crypto_word_t good = constant_time_ge_w(in_len, 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.) + size_t to_check = 256; // maximum amount of padding, inc length byte. + if (to_check > in_len) { + to_check = in_len; + } + + for (size_t i = 0; i < to_check; i++) { + uint8_t mask = constant_time_ge_8(padding_length, i); + uint8_t b = in[in_len - 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_w(0xff, good & 0xff); + + // Always treat |padding_length| as zero on error. If, assuming block size of + // 16, a padding of [<15 arbitrary bytes> 15] treated |padding_length| as 16 + // and returned -1, distinguishing good MAC and bad padding from bad MAC and + // bad padding would give POODLE's padding oracle. + padding_length = good & (padding_length + 1); + *out_len = in_len - padding_length; + *out_padding_ok = good; + return 1; +} + +void EVP_tls_cbc_copy_mac(uint8_t *out, size_t md_size, const uint8_t *in, + size_t in_len, size_t orig_len) { + uint8_t rotated_mac1[EVP_MAX_MD_SIZE], rotated_mac2[EVP_MAX_MD_SIZE]; + uint8_t *rotated_mac = rotated_mac1; + uint8_t *rotated_mac_tmp = rotated_mac2; + + // mac_end is the index of |in| just after the end of the MAC. + size_t mac_end = in_len; + size_t mac_start = mac_end - md_size; + + assert(orig_len >= in_len); + assert(in_len >= md_size); + assert(md_size <= EVP_MAX_MD_SIZE); + + // scan_start contains the number of bytes that we can ignore because + // the MAC's position can only vary by 255 bytes. + size_t scan_start = 0; + // 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); + } + + size_t rotate_offset = 0; + uint8_t mac_started = 0; + OPENSSL_memset(rotated_mac, 0, md_size); + for (size_t i = scan_start, j = 0; i < orig_len; i++, j++) { + if (j >= md_size) { + j -= md_size; + } + crypto_word_t is_mac_start = constant_time_eq_w(i, mac_start); + mac_started |= is_mac_start; + uint8_t mac_ended = constant_time_ge_8(i, mac_end); + rotated_mac[j] |= in[i] & mac_started & ~mac_ended; + // Save the offset that |mac_start| is mapped to. + rotate_offset |= j & is_mac_start; + } + + // Now rotate the MAC. We rotate in log(md_size) steps, one for each bit + // position. + for (size_t offset = 1; offset < md_size; offset <<= 1, rotate_offset >>= 1) { + // Rotate by |offset| iff the corresponding bit is set in + // |rotate_offset|, placing the result in |rotated_mac_tmp|. + const uint8_t skip_rotate = (rotate_offset & 1) - 1; + for (size_t i = 0, j = offset; i < md_size; i++, j++) { + if (j >= md_size) { + j -= md_size; + } + rotated_mac_tmp[i] = + constant_time_select_8(skip_rotate, rotated_mac[i], rotated_mac[j]); + } + + // Swap pointers so |rotated_mac| contains the (possibly) rotated value. + // Note the number of iterations and thus the identity of these pointers is + // public information. + uint8_t *tmp = rotated_mac; + rotated_mac = rotated_mac_tmp; + rotated_mac_tmp = tmp; + } + + OPENSSL_memcpy(out, rotated_mac, md_size); +} + +// u32toBE serialises an unsigned, 32-bit number (n) as four bytes at (p) in +// big-endian order. The value of p is advanced by four. +#define u32toBE(n, p) \ + do { \ + *((p)++) = (uint8_t)((n) >> 24); \ + *((p)++) = (uint8_t)((n) >> 16); \ + *((p)++) = (uint8_t)((n) >> 8); \ + *((p)++) = (uint8_t)((n)); \ + } while (0) + +// u64toBE serialises an unsigned, 64-bit number (n) as eight bytes at (p) in +// big-endian order. The value of p is advanced by eight. +#define u64toBE(n, p) \ + do { \ + *((p)++) = (uint8_t)((n) >> 56); \ + *((p)++) = (uint8_t)((n) >> 48); \ + *((p)++) = (uint8_t)((n) >> 40); \ + *((p)++) = (uint8_t)((n) >> 32); \ + *((p)++) = (uint8_t)((n) >> 24); \ + *((p)++) = (uint8_t)((n) >> 16); \ + *((p)++) = (uint8_t)((n) >> 8); \ + *((p)++) = (uint8_t)((n)); \ + } while (0) + +typedef union { + SHA_CTX sha1; + SHA256_CTX sha256; + SHA512_CTX sha512; +} HASH_CTX; + +static void tls1_sha1_transform(HASH_CTX *ctx, const uint8_t *block) { + SHA1_Transform(&ctx->sha1, block); +} + +static void tls1_sha256_transform(HASH_CTX *ctx, const uint8_t *block) { + SHA256_Transform(&ctx->sha256, block); +} + +static void tls1_sha512_transform(HASH_CTX *ctx, const uint8_t *block) { + SHA512_Transform(&ctx->sha512, block); +} + +// 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_sha1_final_raw(HASH_CTX *ctx, uint8_t *md_out) { + SHA_CTX *sha1 = &ctx->sha1; + u32toBE(sha1->h[0], md_out); + u32toBE(sha1->h[1], md_out); + u32toBE(sha1->h[2], md_out); + u32toBE(sha1->h[3], md_out); + u32toBE(sha1->h[4], md_out); +} + +static void tls1_sha256_final_raw(HASH_CTX *ctx, uint8_t *md_out) { + SHA256_CTX *sha256 = &ctx->sha256; + for (unsigned i = 0; i < 8; i++) { + u32toBE(sha256->h[i], md_out); + } +} + +static void tls1_sha512_final_raw(HASH_CTX *ctx, uint8_t *md_out) { + SHA512_CTX *sha512 = &ctx->sha512; + for (unsigned i = 0; i < 8; i++) { + u64toBE(sha512->h[i], md_out); + } +} + +int EVP_tls_cbc_record_digest_supported(const EVP_MD *md) { + switch (EVP_MD_type(md)) { + case NID_sha1: + case NID_sha256: + case NID_sha384: + return 1; + + default: + return 0; + } +} + +int EVP_tls_cbc_digest_record(const EVP_MD *md, uint8_t *md_out, + size_t *md_out_size, const uint8_t header[13], + const uint8_t *data, size_t data_plus_mac_size, + size_t data_plus_mac_plus_padding_size, + const uint8_t *mac_secret, + unsigned mac_secret_length) { + HASH_CTX md_state; + void (*md_final_raw)(HASH_CTX *ctx, uint8_t *md_out); + void (*md_transform)(HASH_CTX *ctx, const uint8_t *block); + unsigned md_size, md_block_size = 64; + // md_length_size is the number of bytes in the length field that terminates + // the hash. + unsigned md_length_size = 8; + + // Bound the acceptable input so we can forget about many possible overflows + // later in this function. This is redundant with the record size limits in + // TLS. + if (data_plus_mac_plus_padding_size >= 1024 * 1024) { + assert(0); + return 0; + } + + switch (EVP_MD_type(md)) { + case NID_sha1: + SHA1_Init(&md_state.sha1); + md_final_raw = tls1_sha1_final_raw; + md_transform = tls1_sha1_transform; + md_size = SHA_DIGEST_LENGTH; + break; + + case NID_sha256: + SHA256_Init(&md_state.sha256); + md_final_raw = tls1_sha256_final_raw; + md_transform = tls1_sha256_transform; + md_size = SHA256_DIGEST_LENGTH; + break; + + case NID_sha384: + SHA384_Init(&md_state.sha512); + md_final_raw = tls1_sha512_final_raw; + md_transform = tls1_sha512_transform; + md_size = SHA384_DIGEST_LENGTH; + md_block_size = 128; + md_length_size = 16; + break; + + default: + // EVP_tls_cbc_record_digest_supported should have been called first to + // check that the hash function is supported. + assert(0); + *md_out_size = 0; + return 0; + } + + assert(md_length_size <= MAX_HASH_BIT_COUNT_BYTES); + assert(md_block_size <= MAX_HASH_BLOCK_SIZE); + assert(md_size <= EVP_MAX_MD_SIZE); + + static const size_t kHeaderLength = 13; + + // kVarianceBlocks 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. + // + // 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. + static const size_t kVarianceBlocks = 6; + + // From now on we're dealing with the MAC, which conceptually has 13 + // bytes of `header' before the start of the data. + size_t len = data_plus_mac_plus_padding_size + kHeaderLength; + // max_mac_bytes contains the maximum bytes of bytes in the MAC, including + // |header|, assuming that there's no padding. + size_t max_mac_bytes = len - md_size - 1; + // num_blocks is the maximum number of hash blocks. + size_t 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 |kVarianceBlocks| 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. + size_t num_starting_blocks = 0; + // k is the starting byte offset into the conceptual header||data where + // we start processing. + size_t k = 0; + // mac_end_offset is the index just past the end of the data to be + // MACed. + size_t mac_end_offset = data_plus_mac_size + kHeaderLength - md_size; + // c is the index of the 0x80 byte in the final hash block that + // contains application data. + size_t c = mac_end_offset % md_block_size; + // index_a is the hash block number that contains the 0x80 terminating + // value. + size_t index_a = mac_end_offset / md_block_size; + // index_b is the hash block number that contains the 64-bit hash + // length, in bits. + size_t index_b = (mac_end_offset + md_length_size) / md_block_size; + + if (num_blocks > kVarianceBlocks) { + num_starting_blocks = num_blocks - kVarianceBlocks; + k = md_block_size * num_starting_blocks; + } + + // bits is the hash-length in bits. It includes the additional hash + // block for the masked HMAC key. + size_t bits = 8 * mac_end_offset; // at most 18 bits to represent + + // Compute the initial HMAC block. + bits += 8 * md_block_size; + // hmac_pad is the masked HMAC key. + uint8_t hmac_pad[MAX_HASH_BLOCK_SIZE]; + OPENSSL_memset(hmac_pad, 0, md_block_size); + assert(mac_secret_length <= sizeof(hmac_pad)); + OPENSSL_memcpy(hmac_pad, mac_secret, mac_secret_length); + for (size_t i = 0; i < md_block_size; i++) { + hmac_pad[i] ^= 0x36; + } + + md_transform(&md_state, hmac_pad); + + // The length check means |bits| fits in four bytes. + uint8_t length_bytes[MAX_HASH_BIT_COUNT_BYTES]; + OPENSSL_memset(length_bytes, 0, md_length_size - 4); + length_bytes[md_length_size - 4] = (uint8_t)(bits >> 24); + length_bytes[md_length_size - 3] = (uint8_t)(bits >> 16); + length_bytes[md_length_size - 2] = (uint8_t)(bits >> 8); + length_bytes[md_length_size - 1] = (uint8_t)bits; + + if (k > 0) { + // k is a multiple of md_block_size. + uint8_t first_block[MAX_HASH_BLOCK_SIZE]; + OPENSSL_memcpy(first_block, header, 13); + OPENSSL_memcpy(first_block + 13, data, md_block_size - 13); + md_transform(&md_state, first_block); + for (size_t i = 1; i < k / md_block_size; i++) { + md_transform(&md_state, data + md_block_size * i - 13); + } + } + + uint8_t mac_out[EVP_MAX_MD_SIZE]; + OPENSSL_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 (size_t i = num_starting_blocks; + i <= num_starting_blocks + kVarianceBlocks; i++) { + uint8_t block[MAX_HASH_BLOCK_SIZE]; + uint8_t is_block_a = constant_time_eq_8(i, index_a); + uint8_t is_block_b = constant_time_eq_8(i, index_b); + for (size_t j = 0; j < md_block_size; j++) { + uint8_t b = 0; + if (k < kHeaderLength) { + b = header[k]; + } else if (k < data_plus_mac_plus_padding_size + kHeaderLength) { + b = data[k - kHeaderLength]; + } + k++; + + uint8_t is_past_c = is_block_a & constant_time_ge_8(j, c); + uint8_t 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, block); + md_final_raw(&md_state, block); + // If this is index_b, copy the hash value to |mac_out|. + for (size_t j = 0; j < md_size; j++) { + mac_out[j] |= block[j] & is_block_b; + } + } + + EVP_MD_CTX md_ctx; + EVP_MD_CTX_init(&md_ctx); + if (!EVP_DigestInit_ex(&md_ctx, md, NULL /* engine */)) { + EVP_MD_CTX_cleanup(&md_ctx); + return 0; + } + + // Complete the HMAC in the standard manner. + for (size_t i = 0; i < md_block_size; i++) { + hmac_pad[i] ^= 0x6a; + } + + EVP_DigestUpdate(&md_ctx, hmac_pad, md_block_size); + EVP_DigestUpdate(&md_ctx, mac_out, md_size); + unsigned md_out_size_u; + EVP_DigestFinal(&md_ctx, md_out, &md_out_size_u); + *md_out_size = md_out_size_u; + EVP_MD_CTX_cleanup(&md_ctx); + + return 1; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/cmac/cmac.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/cmac/cmac.c new file mode 100644 index 0000000..5eed2e8 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/cmac/cmac.c @@ -0,0 +1,241 @@ +/* ==================================================================== + * 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 +#include +#include + +#include "../internal.h" + + +struct cmac_ctx_st { + EVP_CIPHER_CTX cipher_ctx; + // k1 and k2 are the CMAC subkeys. See + // https://tools.ietf.org/html/rfc4493#section-2.3 + uint8_t k1[AES_BLOCK_SIZE]; + uint8_t k2[AES_BLOCK_SIZE]; + // Last (possibly partial) scratch + uint8_t block[AES_BLOCK_SIZE]; + // block_used contains the number of valid bytes in |block|. + unsigned block_used; +}; + +static void CMAC_CTX_init(CMAC_CTX *ctx) { + EVP_CIPHER_CTX_init(&ctx->cipher_ctx); +} + +static void CMAC_CTX_cleanup(CMAC_CTX *ctx) { + EVP_CIPHER_CTX_cleanup(&ctx->cipher_ctx); + OPENSSL_cleanse(ctx->k1, sizeof(ctx->k1)); + OPENSSL_cleanse(ctx->k2, sizeof(ctx->k2)); + OPENSSL_cleanse(ctx->block, sizeof(ctx->block)); +} + +int AES_CMAC(uint8_t out[16], const uint8_t *key, size_t key_len, + const uint8_t *in, size_t in_len) { + const EVP_CIPHER *cipher; + switch (key_len) { + case 16: + cipher = EVP_aes_128_cbc(); + break; + case 32: + cipher = EVP_aes_256_cbc(); + break; + default: + return 0; + } + + size_t scratch_out_len; + CMAC_CTX ctx; + CMAC_CTX_init(&ctx); + + const int ok = CMAC_Init(&ctx, key, key_len, cipher, NULL /* engine */) && + CMAC_Update(&ctx, in, in_len) && + CMAC_Final(&ctx, out, &scratch_out_len); + + CMAC_CTX_cleanup(&ctx); + return ok; +} + +CMAC_CTX *CMAC_CTX_new(void) { + CMAC_CTX *ctx = OPENSSL_malloc(sizeof(*ctx)); + if (ctx != NULL) { + CMAC_CTX_init(ctx); + } + return ctx; +} + +void CMAC_CTX_free(CMAC_CTX *ctx) { + if (ctx == NULL) { + return; + } + + CMAC_CTX_cleanup(ctx); + OPENSSL_free(ctx); +} + +// binary_field_mul_x treats the 128 bits at |in| as an element of GF(2¹²⁸) +// with a hard-coded reduction polynomial and sets |out| as x times the +// input. +// +// See https://tools.ietf.org/html/rfc4493#section-2.3 +static void binary_field_mul_x(uint8_t out[16], const uint8_t in[16]) { + unsigned i; + + // Shift |in| to left, including carry. + for (i = 0; i < 15; i++) { + out[i] = (in[i] << 1) | (in[i+1] >> 7); + } + + // If MSB set fixup with R. + const uint8_t carry = in[0] >> 7; + out[i] = (in[i] << 1) ^ ((0 - carry) & 0x87); +} + +static const uint8_t kZeroIV[AES_BLOCK_SIZE] = {0}; + +int CMAC_Init(CMAC_CTX *ctx, const void *key, size_t key_len, + const EVP_CIPHER *cipher, ENGINE *engine) { + uint8_t scratch[AES_BLOCK_SIZE]; + + if (EVP_CIPHER_block_size(cipher) != AES_BLOCK_SIZE || + EVP_CIPHER_key_length(cipher) != key_len || + !EVP_EncryptInit_ex(&ctx->cipher_ctx, cipher, NULL, key, kZeroIV) || + !EVP_Cipher(&ctx->cipher_ctx, scratch, kZeroIV, AES_BLOCK_SIZE) || + // Reset context again ready for first data. + !EVP_EncryptInit_ex(&ctx->cipher_ctx, NULL, NULL, NULL, kZeroIV)) { + return 0; + } + + binary_field_mul_x(ctx->k1, scratch); + binary_field_mul_x(ctx->k2, ctx->k1); + ctx->block_used = 0; + + return 1; +} + +int CMAC_Reset(CMAC_CTX *ctx) { + ctx->block_used = 0; + return EVP_EncryptInit_ex(&ctx->cipher_ctx, NULL, NULL, NULL, kZeroIV); +} + +int CMAC_Update(CMAC_CTX *ctx, const uint8_t *in, size_t in_len) { + uint8_t scratch[AES_BLOCK_SIZE]; + + if (ctx->block_used > 0) { + size_t todo = AES_BLOCK_SIZE - ctx->block_used; + if (in_len < todo) { + todo = in_len; + } + + OPENSSL_memcpy(ctx->block + ctx->block_used, in, todo); + in += todo; + in_len -= todo; + ctx->block_used += todo; + + // If |in_len| is zero then either |ctx->block_used| is less than + // |AES_BLOCK_SIZE|, in which case we can stop here, or |ctx->block_used| + // is exactly |AES_BLOCK_SIZE| but there's no more data to process. In the + // latter case we don't want to process this block now because it might be + // the last block and that block is treated specially. + if (in_len == 0) { + return 1; + } + + assert(ctx->block_used == AES_BLOCK_SIZE); + + if (!EVP_Cipher(&ctx->cipher_ctx, scratch, ctx->block, AES_BLOCK_SIZE)) { + return 0; + } + } + + // Encrypt all but one of the remaining blocks. + while (in_len > AES_BLOCK_SIZE) { + if (!EVP_Cipher(&ctx->cipher_ctx, scratch, in, AES_BLOCK_SIZE)) { + return 0; + } + in += AES_BLOCK_SIZE; + in_len -= AES_BLOCK_SIZE; + } + + OPENSSL_memcpy(ctx->block, in, in_len); + ctx->block_used = in_len; + + return 1; +} + +int CMAC_Final(CMAC_CTX *ctx, uint8_t *out, size_t *out_len) { + *out_len = AES_BLOCK_SIZE; + if (out == NULL) { + return 1; + } + + const uint8_t *mask = ctx->k1; + + if (ctx->block_used != AES_BLOCK_SIZE) { + // If the last block is incomplete, terminate it with a single 'one' bit + // followed by zeros. + ctx->block[ctx->block_used] = 0x80; + OPENSSL_memset(ctx->block + ctx->block_used + 1, 0, + AES_BLOCK_SIZE - (ctx->block_used + 1)); + + mask = ctx->k2; + } + + unsigned i; + for (i = 0; i < AES_BLOCK_SIZE; i++) { + out[i] = ctx->block[i] ^ mask[i]; + } + + return EVP_Cipher(&ctx->cipher_ctx, out, out, AES_BLOCK_SIZE); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/cmac/cmac.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/cmac/cmac.c.grpc_back new file mode 100644 index 0000000..fb4e69c --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/cmac/cmac.c.grpc_back @@ -0,0 +1,241 @@ +/* ==================================================================== + * 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 +#include +#include + +#include "../internal.h" + + +struct cmac_ctx_st { + EVP_CIPHER_CTX cipher_ctx; + // k1 and k2 are the CMAC subkeys. See + // https://tools.ietf.org/html/rfc4493#section-2.3 + uint8_t k1[AES_BLOCK_SIZE]; + uint8_t k2[AES_BLOCK_SIZE]; + // Last (possibly partial) scratch + uint8_t block[AES_BLOCK_SIZE]; + // block_used contains the number of valid bytes in |block|. + unsigned block_used; +}; + +static void CMAC_CTX_init(CMAC_CTX *ctx) { + EVP_CIPHER_CTX_init(&ctx->cipher_ctx); +} + +static void CMAC_CTX_cleanup(CMAC_CTX *ctx) { + EVP_CIPHER_CTX_cleanup(&ctx->cipher_ctx); + OPENSSL_cleanse(ctx->k1, sizeof(ctx->k1)); + OPENSSL_cleanse(ctx->k2, sizeof(ctx->k2)); + OPENSSL_cleanse(ctx->block, sizeof(ctx->block)); +} + +int AES_CMAC(uint8_t out[16], const uint8_t *key, size_t key_len, + const uint8_t *in, size_t in_len) { + const EVP_CIPHER *cipher; + switch (key_len) { + case 16: + cipher = EVP_aes_128_cbc(); + break; + case 32: + cipher = EVP_aes_256_cbc(); + break; + default: + return 0; + } + + size_t scratch_out_len; + CMAC_CTX ctx; + CMAC_CTX_init(&ctx); + + const int ok = CMAC_Init(&ctx, key, key_len, cipher, NULL /* engine */) && + CMAC_Update(&ctx, in, in_len) && + CMAC_Final(&ctx, out, &scratch_out_len); + + CMAC_CTX_cleanup(&ctx); + return ok; +} + +CMAC_CTX *CMAC_CTX_new(void) { + CMAC_CTX *ctx = OPENSSL_malloc(sizeof(*ctx)); + if (ctx != NULL) { + CMAC_CTX_init(ctx); + } + return ctx; +} + +void CMAC_CTX_free(CMAC_CTX *ctx) { + if (ctx == NULL) { + return; + } + + CMAC_CTX_cleanup(ctx); + OPENSSL_free(ctx); +} + +// binary_field_mul_x treats the 128 bits at |in| as an element of GF(2¹²⁸) +// with a hard-coded reduction polynomial and sets |out| as x times the +// input. +// +// See https://tools.ietf.org/html/rfc4493#section-2.3 +static void binary_field_mul_x(uint8_t out[16], const uint8_t in[16]) { + unsigned i; + + // Shift |in| to left, including carry. + for (i = 0; i < 15; i++) { + out[i] = (in[i] << 1) | (in[i+1] >> 7); + } + + // If MSB set fixup with R. + const uint8_t carry = in[0] >> 7; + out[i] = (in[i] << 1) ^ ((0 - carry) & 0x87); +} + +static const uint8_t kZeroIV[AES_BLOCK_SIZE] = {0}; + +int CMAC_Init(CMAC_CTX *ctx, const void *key, size_t key_len, + const EVP_CIPHER *cipher, ENGINE *engine) { + uint8_t scratch[AES_BLOCK_SIZE]; + + if (EVP_CIPHER_block_size(cipher) != AES_BLOCK_SIZE || + EVP_CIPHER_key_length(cipher) != key_len || + !EVP_EncryptInit_ex(&ctx->cipher_ctx, cipher, NULL, key, kZeroIV) || + !EVP_Cipher(&ctx->cipher_ctx, scratch, kZeroIV, AES_BLOCK_SIZE) || + // Reset context again ready for first data. + !EVP_EncryptInit_ex(&ctx->cipher_ctx, NULL, NULL, NULL, kZeroIV)) { + return 0; + } + + binary_field_mul_x(ctx->k1, scratch); + binary_field_mul_x(ctx->k2, ctx->k1); + ctx->block_used = 0; + + return 1; +} + +int CMAC_Reset(CMAC_CTX *ctx) { + ctx->block_used = 0; + return EVP_EncryptInit_ex(&ctx->cipher_ctx, NULL, NULL, NULL, kZeroIV); +} + +int CMAC_Update(CMAC_CTX *ctx, const uint8_t *in, size_t in_len) { + uint8_t scratch[AES_BLOCK_SIZE]; + + if (ctx->block_used > 0) { + size_t todo = AES_BLOCK_SIZE - ctx->block_used; + if (in_len < todo) { + todo = in_len; + } + + OPENSSL_memcpy(ctx->block + ctx->block_used, in, todo); + in += todo; + in_len -= todo; + ctx->block_used += todo; + + // If |in_len| is zero then either |ctx->block_used| is less than + // |AES_BLOCK_SIZE|, in which case we can stop here, or |ctx->block_used| + // is exactly |AES_BLOCK_SIZE| but there's no more data to process. In the + // latter case we don't want to process this block now because it might be + // the last block and that block is treated specially. + if (in_len == 0) { + return 1; + } + + assert(ctx->block_used == AES_BLOCK_SIZE); + + if (!EVP_Cipher(&ctx->cipher_ctx, scratch, ctx->block, AES_BLOCK_SIZE)) { + return 0; + } + } + + // Encrypt all but one of the remaining blocks. + while (in_len > AES_BLOCK_SIZE) { + if (!EVP_Cipher(&ctx->cipher_ctx, scratch, in, AES_BLOCK_SIZE)) { + return 0; + } + in += AES_BLOCK_SIZE; + in_len -= AES_BLOCK_SIZE; + } + + OPENSSL_memcpy(ctx->block, in, in_len); + ctx->block_used = in_len; + + return 1; +} + +int CMAC_Final(CMAC_CTX *ctx, uint8_t *out, size_t *out_len) { + *out_len = AES_BLOCK_SIZE; + if (out == NULL) { + return 1; + } + + const uint8_t *mask = ctx->k1; + + if (ctx->block_used != AES_BLOCK_SIZE) { + // If the last block is incomplete, terminate it with a single 'one' bit + // followed by zeros. + ctx->block[ctx->block_used] = 0x80; + OPENSSL_memset(ctx->block + ctx->block_used + 1, 0, + AES_BLOCK_SIZE - (ctx->block_used + 1)); + + mask = ctx->k2; + } + + unsigned i; + for (i = 0; i < AES_BLOCK_SIZE; i++) { + out[i] = ctx->block[i] ^ mask[i]; + } + + return EVP_Cipher(&ctx->cipher_ctx, out, out, AES_BLOCK_SIZE); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/conf/conf.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/conf/conf.c new file mode 100644 index 0000000..d16a638 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/conf/conf.c @@ -0,0 +1,803 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 +#include +#include + +#include "conf_def.h" +#include "internal.h" +#include "../internal.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 uint32_t conf_value_hash(const CONF_VALUE *v) { + return (lh_strhash(v->section) << 2) ^ lh_strhash(v->name); +} + +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) { + return strcmp(a->name, b->name); + } else if (a->name == b->name) { + return 0; + } else { + return (a->name == NULL) ? -1 : 1; + } +} + +CONF *NCONF_new(void *method) { + CONF *conf; + + if (method != NULL) { + return NULL; + } + + conf = OPENSSL_malloc(sizeof(CONF)); + if (conf == NULL) { + return NULL; + } + + conf->data = lh_CONF_VALUE_new(conf_value_hash, conf_value_cmp); + if (conf->data == NULL) { + OPENSSL_free(conf); + return NULL; + } + + return conf; +} + +CONF_VALUE *CONF_VALUE_new(void) { + CONF_VALUE *v = OPENSSL_malloc(sizeof(CONF_VALUE)); + if (!v) { + OPENSSL_PUT_ERROR(CONF, ERR_R_MALLOC_FAILURE); + return NULL; + } + OPENSSL_memset(v, 0, sizeof(CONF_VALUE)); + return v; +} + +static void value_free_contents(CONF_VALUE *value) { + if (value->section) { + OPENSSL_free(value->section); + } + if (value->name) { + OPENSSL_free(value->name); + if (value->value) { + OPENSSL_free(value->value); + } + } else { + if (value->value) { + sk_CONF_VALUE_free((STACK_OF(CONF_VALUE)*)value->value); + } + } +} + +static void value_free(CONF_VALUE *value) { + value_free_contents(value); + OPENSSL_free(value); +} + +void NCONF_free(CONF *conf) { + if (conf == NULL || conf->data == NULL) { + return; + } + + lh_CONF_VALUE_doall(conf->data, value_free); + lh_CONF_VALUE_free(conf->data); + OPENSSL_free(conf); +} + +static CONF_VALUE *NCONF_new_section(const CONF *conf, const char *section) { + STACK_OF(CONF_VALUE) *sk = NULL; + int ok = 0; + CONF_VALUE *v = NULL, *old_value; + + sk = sk_CONF_VALUE_new_null(); + v = CONF_VALUE_new(); + if (sk == NULL || v == NULL) { + goto err; + } + v->section = OPENSSL_strdup(section); + if (v->section == NULL) { + goto err; + } + + v->name = NULL; + v->value = (char *)sk; + + if (!lh_CONF_VALUE_insert(conf->data, &old_value, v)) { + goto err; + } + if (old_value) { + value_free(old_value); + } + ok = 1; + +err: + if (!ok) { + if (sk != NULL) { + sk_CONF_VALUE_free(sk); + } + if (v != NULL) { + OPENSSL_free(v); + } + v = NULL; + } + return v; +} + +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, *rrp, *np, *cp, v; + const char *p; + BUF_MEM *buf; + + buf = BUF_MEM_new(); + if (buf == 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 == '$') { + // 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) { + OPENSSL_PUT_ERROR(CONF, 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 = NCONF_get_string(conf, cp, np); + if (rrp != NULL) { + *rrp = rr; + } + *rp = r; + if (p == NULL) { + OPENSSL_PUT_ERROR(CONF, CONF_R_VARIABLE_HAS_NO_VALUE); + goto err; + } + size_t newsize = strlen(p) + buf->length - (e - from); + if (newsize > MAX_CONF_VALUE_LENGTH) { + OPENSSL_PUT_ERROR(CONF, CONF_R_VARIABLE_EXPANSION_TOO_LONG); + goto err; + } + if (!BUF_MEM_grow_clean(buf, newsize)) { + OPENSSL_PUT_ERROR(CONF, 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 CONF_VALUE *get_section(const CONF *conf, const char *section) { + CONF_VALUE template; + + OPENSSL_memset(&template, 0, sizeof(template)); + template.section = (char *) section; + return lh_CONF_VALUE_retrieve(conf->data, &template); +} + +STACK_OF(CONF_VALUE) *NCONF_get_section(const CONF *conf, const char *section) { + CONF_VALUE *section_value = get_section(conf, section); + if (section_value == NULL) { + return NULL; + } + return (STACK_OF(CONF_VALUE)*) section_value->value; +} + +const char *NCONF_get_string(const CONF *conf, const char *section, + const char *name) { + CONF_VALUE template, *value; + + OPENSSL_memset(&template, 0, sizeof(template)); + template.section = (char *) section; + template.name = (char *) name; + value = lh_CONF_VALUE_retrieve(conf->data, &template); + if (value == NULL) { + return NULL; + } + return value->value; +} + +static int add_string(const CONF *conf, CONF_VALUE *section, + CONF_VALUE *value) { + STACK_OF(CONF_VALUE) *section_stack = (STACK_OF(CONF_VALUE)*) section->value; + CONF_VALUE *old_value; + + value->section = OPENSSL_strdup(section->section); + if (!sk_CONF_VALUE_push(section_stack, value)) { + return 0; + } + + if (!lh_CONF_VALUE_insert(conf->data, &old_value, value)) { + return 0; + } + if (old_value != NULL) { + (void)sk_CONF_VALUE_delete_ptr(section_stack, old_value); + value_free(old_value); + } + + return 1; +} + +static char *eat_ws(CONF *conf, char *p) { + while (IS_WS(conf, *p) && !IS_EOF(conf, *p)) { + p++; + } + return p; +} + +#define scan_esc(conf, p) (((IS_EOF((conf), (p)[1])) ? ((p) + 1) : ((p) + 2))) + +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 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 def_load_bio(CONF *conf, BIO *in, long *out_error_line) { + static const size_t 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; + + if ((buff = BUF_MEM_new()) == NULL) { + OPENSSL_PUT_ERROR(CONF, ERR_R_BUF_LIB); + goto err; + } + + section = OPENSSL_strdup("default"); + if (section == NULL) { + OPENSSL_PUT_ERROR(CONF, ERR_R_MALLOC_FAILURE); + goto err; + } + + sv = NCONF_new_section(conf, section); + if (sv == NULL) { + OPENSSL_PUT_ERROR(CONF, CONF_R_UNABLE_TO_CREATE_NEW_SECTION); + goto err; + } + + bufnum = 0; + again = 0; + for (;;) { + if (!BUF_MEM_grow(buff, bufnum + CONFBUFSIZE)) { + OPENSSL_PUT_ERROR(CONF, 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; + } + OPENSSL_PUT_ERROR(CONF, CONF_R_MISSING_CLOSE_SQUARE_BRACKET); + goto err; + } + *end = '\0'; + if (!str_copy(conf, NULL, §ion, start)) { + goto err; + } + if ((sv = get_section(conf, section)) == NULL) { + sv = NCONF_new_section(conf, section); + } + if (sv == NULL) { + OPENSSL_PUT_ERROR(CONF, 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 != '=') { + OPENSSL_PUT_ERROR(CONF, 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_new())) { + goto err; + } + if (psection == NULL) { + psection = section; + } + v->name = OPENSSL_strdup(pname); + if (v->name == NULL) { + OPENSSL_PUT_ERROR(CONF, ERR_R_MALLOC_FAILURE); + goto err; + } + if (!str_copy(conf, psection, &(v->value), start)) { + goto err; + } + + if (strcmp(psection, section) != 0) { + if ((tv = get_section(conf, psection)) == NULL) { + tv = NCONF_new_section(conf, psection); + } + if (tv == NULL) { + OPENSSL_PUT_ERROR(CONF, CONF_R_UNABLE_TO_CREATE_NEW_SECTION); + goto err; + } + } else { + tv = sv; + } + if (add_string(conf, tv, v) == 0) { + OPENSSL_PUT_ERROR(CONF, ERR_R_MALLOC_FAILURE); + goto err; + } + 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 (out_error_line != NULL) { + *out_error_line = eline; + } + BIO_snprintf(btmp, sizeof btmp, "%ld", eline); + ERR_add_error_data(2, "line ", btmp); + + 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; +} + +int NCONF_load(CONF *conf, const char *filename, long *out_error_line) { + BIO *in = BIO_new_file(filename, "rb"); + int ret; + + if (in == NULL) { + OPENSSL_PUT_ERROR(CONF, ERR_R_SYS_LIB); + return 0; + } + + ret = def_load_bio(conf, in, out_error_line); + BIO_free(in); + + return ret; +} + +int NCONF_load_bio(CONF *conf, BIO *bio, long *out_error_line) { + return def_load_bio(conf, bio, out_error_line); +} + +int CONF_parse_list(const char *list, char sep, int remove_whitespace, + int (*list_cb)(const char *elem, int len, void *usr), + void *arg) { + int ret; + const char *lstart, *tmpend, *p; + + if (list == NULL) { + OPENSSL_PUT_ERROR(CONF, CONF_R_LIST_CANNOT_BE_NULL); + return 0; + } + + lstart = list; + for (;;) { + if (remove_whitespace) { + 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 (remove_whitespace) { + 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; + } +} + +int CONF_modules_load_file(const char *filename, const char *appname, + unsigned long flags) { + return 1; +} + +void CONF_modules_free(void) {} + +void OPENSSL_config(const char *config_name) {} + +void OPENSSL_no_config(void) {} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/conf/conf.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/conf/conf.c.grpc_back new file mode 100644 index 0000000..b1982f8 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/conf/conf.c.grpc_back @@ -0,0 +1,803 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 +#include +#include + +#include "conf_def.h" +#include "internal.h" +#include "../internal.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 uint32_t conf_value_hash(const CONF_VALUE *v) { + return (lh_strhash(v->section) << 2) ^ lh_strhash(v->name); +} + +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) { + return strcmp(a->name, b->name); + } else if (a->name == b->name) { + return 0; + } else { + return (a->name == NULL) ? -1 : 1; + } +} + +CONF *NCONF_new(void *method) { + CONF *conf; + + if (method != NULL) { + return NULL; + } + + conf = OPENSSL_malloc(sizeof(CONF)); + if (conf == NULL) { + return NULL; + } + + conf->data = lh_CONF_VALUE_new(conf_value_hash, conf_value_cmp); + if (conf->data == NULL) { + OPENSSL_free(conf); + return NULL; + } + + return conf; +} + +CONF_VALUE *CONF_VALUE_new(void) { + CONF_VALUE *v = OPENSSL_malloc(sizeof(CONF_VALUE)); + if (!v) { + OPENSSL_PUT_ERROR(CONF, ERR_R_MALLOC_FAILURE); + return NULL; + } + OPENSSL_memset(v, 0, sizeof(CONF_VALUE)); + return v; +} + +static void value_free_contents(CONF_VALUE *value) { + if (value->section) { + OPENSSL_free(value->section); + } + if (value->name) { + OPENSSL_free(value->name); + if (value->value) { + OPENSSL_free(value->value); + } + } else { + if (value->value) { + sk_CONF_VALUE_free((STACK_OF(CONF_VALUE)*)value->value); + } + } +} + +static void value_free(CONF_VALUE *value) { + value_free_contents(value); + OPENSSL_free(value); +} + +void NCONF_free(CONF *conf) { + if (conf == NULL || conf->data == NULL) { + return; + } + + lh_CONF_VALUE_doall(conf->data, value_free); + lh_CONF_VALUE_free(conf->data); + OPENSSL_free(conf); +} + +static CONF_VALUE *NCONF_new_section(const CONF *conf, const char *section) { + STACK_OF(CONF_VALUE) *sk = NULL; + int ok = 0; + CONF_VALUE *v = NULL, *old_value; + + sk = sk_CONF_VALUE_new_null(); + v = CONF_VALUE_new(); + if (sk == NULL || v == NULL) { + goto err; + } + v->section = OPENSSL_strdup(section); + if (v->section == NULL) { + goto err; + } + + v->name = NULL; + v->value = (char *)sk; + + if (!lh_CONF_VALUE_insert(conf->data, &old_value, v)) { + goto err; + } + if (old_value) { + value_free(old_value); + } + ok = 1; + +err: + if (!ok) { + if (sk != NULL) { + sk_CONF_VALUE_free(sk); + } + if (v != NULL) { + OPENSSL_free(v); + } + v = NULL; + } + return v; +} + +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, *rrp, *np, *cp, v; + const char *p; + BUF_MEM *buf; + + buf = BUF_MEM_new(); + if (buf == 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 == '$') { + // 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) { + OPENSSL_PUT_ERROR(CONF, 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 = NCONF_get_string(conf, cp, np); + if (rrp != NULL) { + *rrp = rr; + } + *rp = r; + if (p == NULL) { + OPENSSL_PUT_ERROR(CONF, CONF_R_VARIABLE_HAS_NO_VALUE); + goto err; + } + size_t newsize = strlen(p) + buf->length - (e - from); + if (newsize > MAX_CONF_VALUE_LENGTH) { + OPENSSL_PUT_ERROR(CONF, CONF_R_VARIABLE_EXPANSION_TOO_LONG); + goto err; + } + if (!BUF_MEM_grow_clean(buf, newsize)) { + OPENSSL_PUT_ERROR(CONF, 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 CONF_VALUE *get_section(const CONF *conf, const char *section) { + CONF_VALUE template; + + OPENSSL_memset(&template, 0, sizeof(template)); + template.section = (char *) section; + return lh_CONF_VALUE_retrieve(conf->data, &template); +} + +STACK_OF(CONF_VALUE) *NCONF_get_section(const CONF *conf, const char *section) { + CONF_VALUE *section_value = get_section(conf, section); + if (section_value == NULL) { + return NULL; + } + return (STACK_OF(CONF_VALUE)*) section_value->value; +} + +const char *NCONF_get_string(const CONF *conf, const char *section, + const char *name) { + CONF_VALUE template, *value; + + OPENSSL_memset(&template, 0, sizeof(template)); + template.section = (char *) section; + template.name = (char *) name; + value = lh_CONF_VALUE_retrieve(conf->data, &template); + if (value == NULL) { + return NULL; + } + return value->value; +} + +static int add_string(const CONF *conf, CONF_VALUE *section, + CONF_VALUE *value) { + STACK_OF(CONF_VALUE) *section_stack = (STACK_OF(CONF_VALUE)*) section->value; + CONF_VALUE *old_value; + + value->section = OPENSSL_strdup(section->section); + if (!sk_CONF_VALUE_push(section_stack, value)) { + return 0; + } + + if (!lh_CONF_VALUE_insert(conf->data, &old_value, value)) { + return 0; + } + if (old_value != NULL) { + (void)sk_CONF_VALUE_delete_ptr(section_stack, old_value); + value_free(old_value); + } + + return 1; +} + +static char *eat_ws(CONF *conf, char *p) { + while (IS_WS(conf, *p) && !IS_EOF(conf, *p)) { + p++; + } + return p; +} + +#define scan_esc(conf, p) (((IS_EOF((conf), (p)[1])) ? ((p) + 1) : ((p) + 2))) + +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 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 def_load_bio(CONF *conf, BIO *in, long *out_error_line) { + static const size_t 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; + + if ((buff = BUF_MEM_new()) == NULL) { + OPENSSL_PUT_ERROR(CONF, ERR_R_BUF_LIB); + goto err; + } + + section = OPENSSL_strdup("default"); + if (section == NULL) { + OPENSSL_PUT_ERROR(CONF, ERR_R_MALLOC_FAILURE); + goto err; + } + + sv = NCONF_new_section(conf, section); + if (sv == NULL) { + OPENSSL_PUT_ERROR(CONF, CONF_R_UNABLE_TO_CREATE_NEW_SECTION); + goto err; + } + + bufnum = 0; + again = 0; + for (;;) { + if (!BUF_MEM_grow(buff, bufnum + CONFBUFSIZE)) { + OPENSSL_PUT_ERROR(CONF, 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; + } + OPENSSL_PUT_ERROR(CONF, CONF_R_MISSING_CLOSE_SQUARE_BRACKET); + goto err; + } + *end = '\0'; + if (!str_copy(conf, NULL, §ion, start)) { + goto err; + } + if ((sv = get_section(conf, section)) == NULL) { + sv = NCONF_new_section(conf, section); + } + if (sv == NULL) { + OPENSSL_PUT_ERROR(CONF, 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 != '=') { + OPENSSL_PUT_ERROR(CONF, 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_new())) { + goto err; + } + if (psection == NULL) { + psection = section; + } + v->name = OPENSSL_strdup(pname); + if (v->name == NULL) { + OPENSSL_PUT_ERROR(CONF, ERR_R_MALLOC_FAILURE); + goto err; + } + if (!str_copy(conf, psection, &(v->value), start)) { + goto err; + } + + if (strcmp(psection, section) != 0) { + if ((tv = get_section(conf, psection)) == NULL) { + tv = NCONF_new_section(conf, psection); + } + if (tv == NULL) { + OPENSSL_PUT_ERROR(CONF, CONF_R_UNABLE_TO_CREATE_NEW_SECTION); + goto err; + } + } else { + tv = sv; + } + if (add_string(conf, tv, v) == 0) { + OPENSSL_PUT_ERROR(CONF, ERR_R_MALLOC_FAILURE); + goto err; + } + 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 (out_error_line != NULL) { + *out_error_line = eline; + } + BIO_snprintf(btmp, sizeof btmp, "%ld", eline); + ERR_add_error_data(2, "line ", btmp); + + 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; +} + +int NCONF_load(CONF *conf, const char *filename, long *out_error_line) { + BIO *in = BIO_new_file(filename, "rb"); + int ret; + + if (in == NULL) { + OPENSSL_PUT_ERROR(CONF, ERR_R_SYS_LIB); + return 0; + } + + ret = def_load_bio(conf, in, out_error_line); + BIO_free(in); + + return ret; +} + +int NCONF_load_bio(CONF *conf, BIO *bio, long *out_error_line) { + return def_load_bio(conf, bio, out_error_line); +} + +int CONF_parse_list(const char *list, char sep, int remove_whitespace, + int (*list_cb)(const char *elem, int len, void *usr), + void *arg) { + int ret; + const char *lstart, *tmpend, *p; + + if (list == NULL) { + OPENSSL_PUT_ERROR(CONF, CONF_R_LIST_CANNOT_BE_NULL); + return 0; + } + + lstart = list; + for (;;) { + if (remove_whitespace) { + 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 (remove_whitespace) { + 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; + } +} + +int CONF_modules_load_file(const char *filename, const char *appname, + unsigned long flags) { + return 1; +} + +void CONF_modules_free(void) {} + +void OPENSSL_config(const char *config_name) {} + +void OPENSSL_no_config(void) {} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/conf/conf_def.h b/FoodApp/Pods/BoringSSL-GRPC/crypto/conf/conf_def.h new file mode 100644 index 0000000..b1e6ba6 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/conf/conf_def.h @@ -0,0 +1,127 @@ +/* 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) CONF_type_default +#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) + +static const 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, + }; diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/conf/conf_def.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/conf/conf_def.h.grpc_back new file mode 100644 index 0000000..b1e6ba6 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/conf/conf_def.h.grpc_back @@ -0,0 +1,127 @@ +/* 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) CONF_type_default +#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) + +static const 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, + }; diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/conf/internal.h b/FoodApp/Pods/BoringSSL-GRPC/crypto/conf/internal.h new file mode 100644 index 0000000..3e0e57d --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/conf/internal.h @@ -0,0 +1,31 @@ +/* Copyright (c) 2015, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_CRYPTO_CONF_INTERNAL_H +#define OPENSSL_HEADER_CRYPTO_CONF_INTERNAL_H + +#if defined(__cplusplus) +extern "C" { +#endif + + +// CONF_VALUE_new returns a freshly allocated and zeroed |CONF_VALUE|. +CONF_VALUE *CONF_VALUE_new(void); + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_CRYPTO_CONF_INTERNAL_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/conf/internal.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/conf/internal.h.grpc_back new file mode 100644 index 0000000..3e0e57d --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/conf/internal.h.grpc_back @@ -0,0 +1,31 @@ +/* Copyright (c) 2015, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_CRYPTO_CONF_INTERNAL_H +#define OPENSSL_HEADER_CRYPTO_CONF_INTERNAL_H + +#if defined(__cplusplus) +extern "C" { +#endif + + +// CONF_VALUE_new returns a freshly allocated and zeroed |CONF_VALUE|. +CONF_VALUE *CONF_VALUE_new(void); + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_CRYPTO_CONF_INTERNAL_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/cpu-aarch64-fuchsia.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/cpu-aarch64-fuchsia.c new file mode 100644 index 0000000..26d2008 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/cpu-aarch64-fuchsia.c @@ -0,0 +1,55 @@ +/* Copyright (c) 2018, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#if defined(OPENSSL_AARCH64) && defined(OPENSSL_FUCHSIA) && \ + !defined(OPENSSL_STATIC_ARMCAP) + +#include +#include +#include + +#include + +#include "internal.h" + +extern uint32_t OPENSSL_armcap_P; + +void OPENSSL_cpuid_setup(void) { + uint32_t hwcap; + zx_status_t rc = zx_system_get_features(ZX_FEATURE_KIND_CPU, &hwcap); + if (rc != ZX_OK || (hwcap & ZX_ARM64_FEATURE_ISA_ASIMD) == 0) { + // Matching OpenSSL, if NEON/ASIMD is missing, don't report other features + // either. + return; + } + + OPENSSL_armcap_P |= ARMV7_NEON; + + if (hwcap & ZX_ARM64_FEATURE_ISA_AES) { + OPENSSL_armcap_P |= ARMV8_AES; + } + if (hwcap & ZX_ARM64_FEATURE_ISA_PMULL) { + OPENSSL_armcap_P |= ARMV8_PMULL; + } + if (hwcap & ZX_ARM64_FEATURE_ISA_SHA1) { + OPENSSL_armcap_P |= ARMV8_SHA1; + } + if (hwcap & ZX_ARM64_FEATURE_ISA_SHA2) { + OPENSSL_armcap_P |= ARMV8_SHA256; + } +} + +#endif // OPENSSL_AARCH64 && !OPENSSL_STATIC_ARMCAP diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/cpu-aarch64-fuchsia.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/cpu-aarch64-fuchsia.c.grpc_back new file mode 100644 index 0000000..98303a0 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/cpu-aarch64-fuchsia.c.grpc_back @@ -0,0 +1,55 @@ +/* Copyright (c) 2018, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#if defined(OPENSSL_AARCH64) && defined(OPENSSL_FUCHSIA) && \ + !defined(OPENSSL_STATIC_ARMCAP) + +#include +#include +#include + +#include + +#include "internal.h" + +extern uint32_t OPENSSL_armcap_P; + +void OPENSSL_cpuid_setup(void) { + uint32_t hwcap; + zx_status_t rc = zx_system_get_features(ZX_FEATURE_KIND_CPU, &hwcap); + if (rc != ZX_OK || (hwcap & ZX_ARM64_FEATURE_ISA_ASIMD) == 0) { + // Matching OpenSSL, if NEON/ASIMD is missing, don't report other features + // either. + return; + } + + OPENSSL_armcap_P |= ARMV7_NEON; + + if (hwcap & ZX_ARM64_FEATURE_ISA_AES) { + OPENSSL_armcap_P |= ARMV8_AES; + } + if (hwcap & ZX_ARM64_FEATURE_ISA_PMULL) { + OPENSSL_armcap_P |= ARMV8_PMULL; + } + if (hwcap & ZX_ARM64_FEATURE_ISA_SHA1) { + OPENSSL_armcap_P |= ARMV8_SHA1; + } + if (hwcap & ZX_ARM64_FEATURE_ISA_SHA2) { + OPENSSL_armcap_P |= ARMV8_SHA256; + } +} + +#endif // OPENSSL_AARCH64 && !OPENSSL_STATIC_ARMCAP diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/cpu-aarch64-linux.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/cpu-aarch64-linux.c new file mode 100644 index 0000000..d6aa0db --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/cpu-aarch64-linux.c @@ -0,0 +1,62 @@ +/* Copyright (c) 2016, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#if defined(OPENSSL_AARCH64) && defined(OPENSSL_LINUX) && \ + !defined(OPENSSL_STATIC_ARMCAP) + +#include + +#include + +#include "internal.h" + + +extern uint32_t OPENSSL_armcap_P; + +void OPENSSL_cpuid_setup(void) { + unsigned long hwcap = getauxval(AT_HWCAP); + + // See /usr/include/asm/hwcap.h on an aarch64 installation for the source of + // these values. + static const unsigned long kNEON = 1 << 1; + static const unsigned long kAES = 1 << 3; + static const unsigned long kPMULL = 1 << 4; + static const unsigned long kSHA1 = 1 << 5; + static const unsigned long kSHA256 = 1 << 6; + + if ((hwcap & kNEON) == 0) { + // Matching OpenSSL, if NEON is missing, don't report other features + // either. + return; + } + + OPENSSL_armcap_P |= ARMV7_NEON; + + if (hwcap & kAES) { + OPENSSL_armcap_P |= ARMV8_AES; + } + if (hwcap & kPMULL) { + OPENSSL_armcap_P |= ARMV8_PMULL; + } + if (hwcap & kSHA1) { + OPENSSL_armcap_P |= ARMV8_SHA1; + } + if (hwcap & kSHA256) { + OPENSSL_armcap_P |= ARMV8_SHA256; + } +} + +#endif // OPENSSL_AARCH64 && !OPENSSL_STATIC_ARMCAP diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/cpu-aarch64-linux.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/cpu-aarch64-linux.c.grpc_back new file mode 100644 index 0000000..0184dd4 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/cpu-aarch64-linux.c.grpc_back @@ -0,0 +1,62 @@ +/* Copyright (c) 2016, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#if defined(OPENSSL_AARCH64) && defined(OPENSSL_LINUX) && \ + !defined(OPENSSL_STATIC_ARMCAP) + +#include + +#include + +#include "internal.h" + + +extern uint32_t OPENSSL_armcap_P; + +void OPENSSL_cpuid_setup(void) { + unsigned long hwcap = getauxval(AT_HWCAP); + + // See /usr/include/asm/hwcap.h on an aarch64 installation for the source of + // these values. + static const unsigned long kNEON = 1 << 1; + static const unsigned long kAES = 1 << 3; + static const unsigned long kPMULL = 1 << 4; + static const unsigned long kSHA1 = 1 << 5; + static const unsigned long kSHA256 = 1 << 6; + + if ((hwcap & kNEON) == 0) { + // Matching OpenSSL, if NEON is missing, don't report other features + // either. + return; + } + + OPENSSL_armcap_P |= ARMV7_NEON; + + if (hwcap & kAES) { + OPENSSL_armcap_P |= ARMV8_AES; + } + if (hwcap & kPMULL) { + OPENSSL_armcap_P |= ARMV8_PMULL; + } + if (hwcap & kSHA1) { + OPENSSL_armcap_P |= ARMV8_SHA1; + } + if (hwcap & kSHA256) { + OPENSSL_armcap_P |= ARMV8_SHA256; + } +} + +#endif // OPENSSL_AARCH64 && !OPENSSL_STATIC_ARMCAP diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/cpu-arm-linux.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/cpu-arm-linux.c new file mode 100644 index 0000000..5c93d47 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/cpu-arm-linux.c @@ -0,0 +1,363 @@ +/* Copyright (c) 2016, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#if defined(OPENSSL_ARM) && !defined(OPENSSL_STATIC_ARMCAP) + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "internal.h" + + +#define AT_HWCAP 16 +#define AT_HWCAP2 26 + +#define HWCAP_NEON (1 << 12) + +// See /usr/include/asm/hwcap.h on an ARM installation for the source of +// these values. +#define HWCAP2_AES (1 << 0) +#define HWCAP2_PMULL (1 << 1) +#define HWCAP2_SHA1 (1 << 2) +#define HWCAP2_SHA2 (1 << 3) + +// |getauxval| is not available on Android until API level 20. Link it as a weak +// symbol and use other methods as fallback. +unsigned long getauxval(unsigned long type) __attribute__((weak)); + +static int open_eintr(const char *path, int flags) { + int ret; + do { + ret = open(path, flags); + } while (ret < 0 && errno == EINTR); + return ret; +} + +static ssize_t read_eintr(int fd, void *out, size_t len) { + ssize_t ret; + do { + ret = read(fd, out, len); + } while (ret < 0 && errno == EINTR); + return ret; +} + +// read_full reads exactly |len| bytes from |fd| to |out|. On error or end of +// file, it returns zero. +static int read_full(int fd, void *out, size_t len) { + char *outp = out; + while (len > 0) { + ssize_t ret = read_eintr(fd, outp, len); + if (ret <= 0) { + return 0; + } + outp += ret; + len -= ret; + } + return 1; +} + +// read_file opens |path| and reads until end-of-file. On success, it returns +// one and sets |*out_ptr| and |*out_len| to a newly-allocated buffer with the +// contents. Otherwise, it returns zero. +static int read_file(char **out_ptr, size_t *out_len, const char *path) { + int fd = open_eintr(path, O_RDONLY); + if (fd < 0) { + return 0; + } + + static const size_t kReadSize = 1024; + int ret = 0; + size_t cap = kReadSize, len = 0; + char *buf = OPENSSL_malloc(cap); + if (buf == NULL) { + goto err; + } + + for (;;) { + if (cap - len < kReadSize) { + size_t new_cap = cap * 2; + if (new_cap < cap) { + goto err; + } + char *new_buf = OPENSSL_realloc(buf, new_cap); + if (new_buf == NULL) { + goto err; + } + buf = new_buf; + cap = new_cap; + } + + ssize_t bytes_read = read_eintr(fd, buf + len, kReadSize); + if (bytes_read < 0) { + goto err; + } + if (bytes_read == 0) { + break; + } + len += bytes_read; + } + + *out_ptr = buf; + *out_len = len; + ret = 1; + buf = NULL; + +err: + OPENSSL_free(buf); + close(fd); + return ret; +} + +// getauxval_proc behaves like |getauxval| but reads from /proc/self/auxv. +static unsigned long getauxval_proc(unsigned long type) { + int fd = open_eintr("/proc/self/auxv", O_RDONLY); + if (fd < 0) { + return 0; + } + + struct { + unsigned long tag; + unsigned long value; + } entry; + + for (;;) { + if (!read_full(fd, &entry, sizeof(entry)) || + (entry.tag == 0 && entry.value == 0)) { + break; + } + if (entry.tag == type) { + close(fd); + return entry.value; + } + } + close(fd); + return 0; +} + +typedef struct { + const char *data; + size_t len; +} STRING_PIECE; + +static int STRING_PIECE_equals(const STRING_PIECE *a, const char *b) { + size_t b_len = strlen(b); + return a->len == b_len && OPENSSL_memcmp(a->data, b, b_len) == 0; +} + +// STRING_PIECE_split finds the first occurence of |sep| in |in| and, if found, +// sets |*out_left| and |*out_right| to |in| split before and after it. It +// returns one if |sep| was found and zero otherwise. +static int STRING_PIECE_split(STRING_PIECE *out_left, STRING_PIECE *out_right, + const STRING_PIECE *in, char sep) { + const char *p = OPENSSL_memchr(in->data, sep, in->len); + if (p == NULL) { + return 0; + } + // |out_left| or |out_right| may alias |in|, so make a copy. + STRING_PIECE in_copy = *in; + out_left->data = in_copy.data; + out_left->len = p - in_copy.data; + out_right->data = in_copy.data + out_left->len + 1; + out_right->len = in_copy.len - out_left->len - 1; + return 1; +} + +// STRING_PIECE_trim removes leading and trailing whitespace from |s|. +static void STRING_PIECE_trim(STRING_PIECE *s) { + while (s->len != 0 && (s->data[0] == ' ' || s->data[0] == '\t')) { + s->data++; + s->len--; + } + while (s->len != 0 && + (s->data[s->len - 1] == ' ' || s->data[s->len - 1] == '\t')) { + s->len--; + } +} + +// extract_cpuinfo_field extracts a /proc/cpuinfo field named |field| from +// |in|. If found, it sets |*out| to the value and returns one. Otherwise, it +// returns zero. +static int extract_cpuinfo_field(STRING_PIECE *out, const STRING_PIECE *in, + const char *field) { + // Process |in| one line at a time. + STRING_PIECE remaining = *in, line; + while (STRING_PIECE_split(&line, &remaining, &remaining, '\n')) { + STRING_PIECE key, value; + if (!STRING_PIECE_split(&key, &value, &line, ':')) { + continue; + } + STRING_PIECE_trim(&key); + if (STRING_PIECE_equals(&key, field)) { + STRING_PIECE_trim(&value); + *out = value; + return 1; + } + } + + return 0; +} + +static int cpuinfo_field_equals(const STRING_PIECE *cpuinfo, const char *field, + const char *value) { + STRING_PIECE extracted; + return extract_cpuinfo_field(&extracted, cpuinfo, field) && + STRING_PIECE_equals(&extracted, value); +} + +// has_list_item treats |list| as a space-separated list of items and returns +// one if |item| is contained in |list| and zero otherwise. +static int has_list_item(const STRING_PIECE *list, const char *item) { + STRING_PIECE remaining = *list, feature; + while (STRING_PIECE_split(&feature, &remaining, &remaining, ' ')) { + if (STRING_PIECE_equals(&feature, item)) { + return 1; + } + } + return 0; +} + +static unsigned long get_hwcap_cpuinfo(const STRING_PIECE *cpuinfo) { + if (cpuinfo_field_equals(cpuinfo, "CPU architecture", "8")) { + // This is a 32-bit ARM binary running on a 64-bit kernel. NEON is always + // available on ARMv8. Linux omits required features, so reading the + // "Features" line does not work. (For simplicity, use strict equality. We + // assume everything running on future ARM architectures will have a + // working |getauxval|.) + return HWCAP_NEON; + } + + STRING_PIECE features; + if (extract_cpuinfo_field(&features, cpuinfo, "Features") && + has_list_item(&features, "neon")) { + return HWCAP_NEON; + } + return 0; +} + +static unsigned long get_hwcap2_cpuinfo(const STRING_PIECE *cpuinfo) { + STRING_PIECE features; + if (!extract_cpuinfo_field(&features, cpuinfo, "Features")) { + return 0; + } + + unsigned long ret = 0; + if (has_list_item(&features, "aes")) { + ret |= HWCAP2_AES; + } + if (has_list_item(&features, "pmull")) { + ret |= HWCAP2_PMULL; + } + if (has_list_item(&features, "sha1")) { + ret |= HWCAP2_SHA1; + } + if (has_list_item(&features, "sha2")) { + ret |= HWCAP2_SHA2; + } + return ret; +} + +// has_broken_neon returns one if |in| matches a CPU known to have a broken +// NEON unit. See https://crbug.com/341598. +static int has_broken_neon(const STRING_PIECE *cpuinfo) { + return cpuinfo_field_equals(cpuinfo, "CPU implementer", "0x51") && + cpuinfo_field_equals(cpuinfo, "CPU architecture", "7") && + cpuinfo_field_equals(cpuinfo, "CPU variant", "0x1") && + cpuinfo_field_equals(cpuinfo, "CPU part", "0x04d") && + cpuinfo_field_equals(cpuinfo, "CPU revision", "0"); +} + +extern uint32_t OPENSSL_armcap_P; + +static int g_has_broken_neon, g_needs_hwcap2_workaround; + +void OPENSSL_cpuid_setup(void) { + char *cpuinfo_data; + size_t cpuinfo_len; + if (!read_file(&cpuinfo_data, &cpuinfo_len, "/proc/cpuinfo")) { + return; + } + STRING_PIECE cpuinfo; + cpuinfo.data = cpuinfo_data; + cpuinfo.len = cpuinfo_len; + + // |getauxval| is not available on Android until API level 20. If it is + // unavailable, read from /proc/self/auxv as a fallback. This is unreadable + // on some versions of Android, so further fall back to /proc/cpuinfo. + // + // See + // https://android.googlesource.com/platform/ndk/+/882ac8f3392858991a0e1af33b4b7387ec856bd2 + // and b/13679666 (Google-internal) for details. + unsigned long hwcap = 0; + if (getauxval != NULL) { + hwcap = getauxval(AT_HWCAP); + } + if (hwcap == 0) { + hwcap = getauxval_proc(AT_HWCAP); + } + if (hwcap == 0) { + hwcap = get_hwcap_cpuinfo(&cpuinfo); + } + + // Clear NEON support if known broken. + g_has_broken_neon = has_broken_neon(&cpuinfo); + if (g_has_broken_neon) { + hwcap &= ~HWCAP_NEON; + } + + // Matching OpenSSL, only report other features if NEON is present. + if (hwcap & HWCAP_NEON) { + OPENSSL_armcap_P |= ARMV7_NEON; + + // Some ARMv8 Android devices don't expose AT_HWCAP2. Fall back to + // /proc/cpuinfo. See https://crbug.com/596156. + unsigned long hwcap2 = 0; + if (getauxval != NULL) { + hwcap2 = getauxval(AT_HWCAP2); + } + if (hwcap2 == 0) { + hwcap2 = get_hwcap2_cpuinfo(&cpuinfo); + g_needs_hwcap2_workaround = hwcap2 != 0; + } + + if (hwcap2 & HWCAP2_AES) { + OPENSSL_armcap_P |= ARMV8_AES; + } + if (hwcap2 & HWCAP2_PMULL) { + OPENSSL_armcap_P |= ARMV8_PMULL; + } + if (hwcap2 & HWCAP2_SHA1) { + OPENSSL_armcap_P |= ARMV8_SHA1; + } + if (hwcap2 & HWCAP2_SHA2) { + OPENSSL_armcap_P |= ARMV8_SHA256; + } + } + + OPENSSL_free(cpuinfo_data); +} + +int CRYPTO_has_broken_NEON(void) { return g_has_broken_neon; } + +int CRYPTO_needs_hwcap2_workaround(void) { return g_needs_hwcap2_workaround; } + +#endif // OPENSSL_ARM && !OPENSSL_STATIC_ARMCAP diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/cpu-arm-linux.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/cpu-arm-linux.c.grpc_back new file mode 100644 index 0000000..839b632 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/cpu-arm-linux.c.grpc_back @@ -0,0 +1,363 @@ +/* Copyright (c) 2016, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#if defined(OPENSSL_ARM) && !defined(OPENSSL_STATIC_ARMCAP) + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "internal.h" + + +#define AT_HWCAP 16 +#define AT_HWCAP2 26 + +#define HWCAP_NEON (1 << 12) + +// See /usr/include/asm/hwcap.h on an ARM installation for the source of +// these values. +#define HWCAP2_AES (1 << 0) +#define HWCAP2_PMULL (1 << 1) +#define HWCAP2_SHA1 (1 << 2) +#define HWCAP2_SHA2 (1 << 3) + +// |getauxval| is not available on Android until API level 20. Link it as a weak +// symbol and use other methods as fallback. +unsigned long getauxval(unsigned long type) __attribute__((weak)); + +static int open_eintr(const char *path, int flags) { + int ret; + do { + ret = open(path, flags); + } while (ret < 0 && errno == EINTR); + return ret; +} + +static ssize_t read_eintr(int fd, void *out, size_t len) { + ssize_t ret; + do { + ret = read(fd, out, len); + } while (ret < 0 && errno == EINTR); + return ret; +} + +// read_full reads exactly |len| bytes from |fd| to |out|. On error or end of +// file, it returns zero. +static int read_full(int fd, void *out, size_t len) { + char *outp = out; + while (len > 0) { + ssize_t ret = read_eintr(fd, outp, len); + if (ret <= 0) { + return 0; + } + outp += ret; + len -= ret; + } + return 1; +} + +// read_file opens |path| and reads until end-of-file. On success, it returns +// one and sets |*out_ptr| and |*out_len| to a newly-allocated buffer with the +// contents. Otherwise, it returns zero. +static int read_file(char **out_ptr, size_t *out_len, const char *path) { + int fd = open_eintr(path, O_RDONLY); + if (fd < 0) { + return 0; + } + + static const size_t kReadSize = 1024; + int ret = 0; + size_t cap = kReadSize, len = 0; + char *buf = OPENSSL_malloc(cap); + if (buf == NULL) { + goto err; + } + + for (;;) { + if (cap - len < kReadSize) { + size_t new_cap = cap * 2; + if (new_cap < cap) { + goto err; + } + char *new_buf = OPENSSL_realloc(buf, new_cap); + if (new_buf == NULL) { + goto err; + } + buf = new_buf; + cap = new_cap; + } + + ssize_t bytes_read = read_eintr(fd, buf + len, kReadSize); + if (bytes_read < 0) { + goto err; + } + if (bytes_read == 0) { + break; + } + len += bytes_read; + } + + *out_ptr = buf; + *out_len = len; + ret = 1; + buf = NULL; + +err: + OPENSSL_free(buf); + close(fd); + return ret; +} + +// getauxval_proc behaves like |getauxval| but reads from /proc/self/auxv. +static unsigned long getauxval_proc(unsigned long type) { + int fd = open_eintr("/proc/self/auxv", O_RDONLY); + if (fd < 0) { + return 0; + } + + struct { + unsigned long tag; + unsigned long value; + } entry; + + for (;;) { + if (!read_full(fd, &entry, sizeof(entry)) || + (entry.tag == 0 && entry.value == 0)) { + break; + } + if (entry.tag == type) { + close(fd); + return entry.value; + } + } + close(fd); + return 0; +} + +typedef struct { + const char *data; + size_t len; +} STRING_PIECE; + +static int STRING_PIECE_equals(const STRING_PIECE *a, const char *b) { + size_t b_len = strlen(b); + return a->len == b_len && OPENSSL_memcmp(a->data, b, b_len) == 0; +} + +// STRING_PIECE_split finds the first occurence of |sep| in |in| and, if found, +// sets |*out_left| and |*out_right| to |in| split before and after it. It +// returns one if |sep| was found and zero otherwise. +static int STRING_PIECE_split(STRING_PIECE *out_left, STRING_PIECE *out_right, + const STRING_PIECE *in, char sep) { + const char *p = OPENSSL_memchr(in->data, sep, in->len); + if (p == NULL) { + return 0; + } + // |out_left| or |out_right| may alias |in|, so make a copy. + STRING_PIECE in_copy = *in; + out_left->data = in_copy.data; + out_left->len = p - in_copy.data; + out_right->data = in_copy.data + out_left->len + 1; + out_right->len = in_copy.len - out_left->len - 1; + return 1; +} + +// STRING_PIECE_trim removes leading and trailing whitespace from |s|. +static void STRING_PIECE_trim(STRING_PIECE *s) { + while (s->len != 0 && (s->data[0] == ' ' || s->data[0] == '\t')) { + s->data++; + s->len--; + } + while (s->len != 0 && + (s->data[s->len - 1] == ' ' || s->data[s->len - 1] == '\t')) { + s->len--; + } +} + +// extract_cpuinfo_field extracts a /proc/cpuinfo field named |field| from +// |in|. If found, it sets |*out| to the value and returns one. Otherwise, it +// returns zero. +static int extract_cpuinfo_field(STRING_PIECE *out, const STRING_PIECE *in, + const char *field) { + // Process |in| one line at a time. + STRING_PIECE remaining = *in, line; + while (STRING_PIECE_split(&line, &remaining, &remaining, '\n')) { + STRING_PIECE key, value; + if (!STRING_PIECE_split(&key, &value, &line, ':')) { + continue; + } + STRING_PIECE_trim(&key); + if (STRING_PIECE_equals(&key, field)) { + STRING_PIECE_trim(&value); + *out = value; + return 1; + } + } + + return 0; +} + +static int cpuinfo_field_equals(const STRING_PIECE *cpuinfo, const char *field, + const char *value) { + STRING_PIECE extracted; + return extract_cpuinfo_field(&extracted, cpuinfo, field) && + STRING_PIECE_equals(&extracted, value); +} + +// has_list_item treats |list| as a space-separated list of items and returns +// one if |item| is contained in |list| and zero otherwise. +static int has_list_item(const STRING_PIECE *list, const char *item) { + STRING_PIECE remaining = *list, feature; + while (STRING_PIECE_split(&feature, &remaining, &remaining, ' ')) { + if (STRING_PIECE_equals(&feature, item)) { + return 1; + } + } + return 0; +} + +static unsigned long get_hwcap_cpuinfo(const STRING_PIECE *cpuinfo) { + if (cpuinfo_field_equals(cpuinfo, "CPU architecture", "8")) { + // This is a 32-bit ARM binary running on a 64-bit kernel. NEON is always + // available on ARMv8. Linux omits required features, so reading the + // "Features" line does not work. (For simplicity, use strict equality. We + // assume everything running on future ARM architectures will have a + // working |getauxval|.) + return HWCAP_NEON; + } + + STRING_PIECE features; + if (extract_cpuinfo_field(&features, cpuinfo, "Features") && + has_list_item(&features, "neon")) { + return HWCAP_NEON; + } + return 0; +} + +static unsigned long get_hwcap2_cpuinfo(const STRING_PIECE *cpuinfo) { + STRING_PIECE features; + if (!extract_cpuinfo_field(&features, cpuinfo, "Features")) { + return 0; + } + + unsigned long ret = 0; + if (has_list_item(&features, "aes")) { + ret |= HWCAP2_AES; + } + if (has_list_item(&features, "pmull")) { + ret |= HWCAP2_PMULL; + } + if (has_list_item(&features, "sha1")) { + ret |= HWCAP2_SHA1; + } + if (has_list_item(&features, "sha2")) { + ret |= HWCAP2_SHA2; + } + return ret; +} + +// has_broken_neon returns one if |in| matches a CPU known to have a broken +// NEON unit. See https://crbug.com/341598. +static int has_broken_neon(const STRING_PIECE *cpuinfo) { + return cpuinfo_field_equals(cpuinfo, "CPU implementer", "0x51") && + cpuinfo_field_equals(cpuinfo, "CPU architecture", "7") && + cpuinfo_field_equals(cpuinfo, "CPU variant", "0x1") && + cpuinfo_field_equals(cpuinfo, "CPU part", "0x04d") && + cpuinfo_field_equals(cpuinfo, "CPU revision", "0"); +} + +extern uint32_t OPENSSL_armcap_P; + +static int g_has_broken_neon, g_needs_hwcap2_workaround; + +void OPENSSL_cpuid_setup(void) { + char *cpuinfo_data; + size_t cpuinfo_len; + if (!read_file(&cpuinfo_data, &cpuinfo_len, "/proc/cpuinfo")) { + return; + } + STRING_PIECE cpuinfo; + cpuinfo.data = cpuinfo_data; + cpuinfo.len = cpuinfo_len; + + // |getauxval| is not available on Android until API level 20. If it is + // unavailable, read from /proc/self/auxv as a fallback. This is unreadable + // on some versions of Android, so further fall back to /proc/cpuinfo. + // + // See + // https://android.googlesource.com/platform/ndk/+/882ac8f3392858991a0e1af33b4b7387ec856bd2 + // and b/13679666 (Google-internal) for details. + unsigned long hwcap = 0; + if (getauxval != NULL) { + hwcap = getauxval(AT_HWCAP); + } + if (hwcap == 0) { + hwcap = getauxval_proc(AT_HWCAP); + } + if (hwcap == 0) { + hwcap = get_hwcap_cpuinfo(&cpuinfo); + } + + // Clear NEON support if known broken. + g_has_broken_neon = has_broken_neon(&cpuinfo); + if (g_has_broken_neon) { + hwcap &= ~HWCAP_NEON; + } + + // Matching OpenSSL, only report other features if NEON is present. + if (hwcap & HWCAP_NEON) { + OPENSSL_armcap_P |= ARMV7_NEON; + + // Some ARMv8 Android devices don't expose AT_HWCAP2. Fall back to + // /proc/cpuinfo. See https://crbug.com/596156. + unsigned long hwcap2 = 0; + if (getauxval != NULL) { + hwcap2 = getauxval(AT_HWCAP2); + } + if (hwcap2 == 0) { + hwcap2 = get_hwcap2_cpuinfo(&cpuinfo); + g_needs_hwcap2_workaround = hwcap2 != 0; + } + + if (hwcap2 & HWCAP2_AES) { + OPENSSL_armcap_P |= ARMV8_AES; + } + if (hwcap2 & HWCAP2_PMULL) { + OPENSSL_armcap_P |= ARMV8_PMULL; + } + if (hwcap2 & HWCAP2_SHA1) { + OPENSSL_armcap_P |= ARMV8_SHA1; + } + if (hwcap2 & HWCAP2_SHA2) { + OPENSSL_armcap_P |= ARMV8_SHA256; + } + } + + OPENSSL_free(cpuinfo_data); +} + +int CRYPTO_has_broken_NEON(void) { return g_has_broken_neon; } + +int CRYPTO_needs_hwcap2_workaround(void) { return g_needs_hwcap2_workaround; } + +#endif // OPENSSL_ARM && !OPENSSL_STATIC_ARMCAP diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/cpu-arm.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/cpu-arm.c new file mode 100644 index 0000000..256f757 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/cpu-arm.c @@ -0,0 +1,38 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#if (defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)) && \ + !defined(OPENSSL_STATIC_ARMCAP) + +#include + + +extern uint32_t OPENSSL_armcap_P; + +char CRYPTO_is_NEON_capable_at_runtime(void) { + return (OPENSSL_armcap_P & ARMV7_NEON) != 0; +} + +int CRYPTO_is_ARMv8_AES_capable(void) { + return (OPENSSL_armcap_P & ARMV8_AES) != 0; +} + +int CRYPTO_is_ARMv8_PMULL_capable(void) { + return (OPENSSL_armcap_P & ARMV8_PMULL) != 0; +} + +#endif /* (defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)) && + !defined(OPENSSL_STATIC_ARMCAP) */ diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/cpu-arm.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/cpu-arm.c.grpc_back new file mode 100644 index 0000000..ef395ea --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/cpu-arm.c.grpc_back @@ -0,0 +1,38 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#if (defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)) && \ + !defined(OPENSSL_STATIC_ARMCAP) + +#include + + +extern uint32_t OPENSSL_armcap_P; + +char CRYPTO_is_NEON_capable_at_runtime(void) { + return (OPENSSL_armcap_P & ARMV7_NEON) != 0; +} + +int CRYPTO_is_ARMv8_AES_capable(void) { + return (OPENSSL_armcap_P & ARMV8_AES) != 0; +} + +int CRYPTO_is_ARMv8_PMULL_capable(void) { + return (OPENSSL_armcap_P & ARMV8_PMULL) != 0; +} + +#endif /* (defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)) && + !defined(OPENSSL_STATIC_ARMCAP) */ diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/cpu-intel.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/cpu-intel.c new file mode 100644 index 0000000..88c7bac --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/cpu-intel.c @@ -0,0 +1,288 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#if !defined(__STDC_FORMAT_MACROS) +#define __STDC_FORMAT_MACROS +#endif + +#include + + +#if !defined(OPENSSL_NO_ASM) && (defined(OPENSSL_X86) || defined(OPENSSL_X86_64)) + +#include +#include +#include +#include + +#if defined(_MSC_VER) +OPENSSL_MSVC_PRAGMA(warning(push, 3)) +#include +#include +OPENSSL_MSVC_PRAGMA(warning(pop)) +#endif + +#include "internal.h" + + +// OPENSSL_cpuid runs the cpuid instruction. |leaf| is passed in as EAX and ECX +// is set to zero. It writes EAX, EBX, ECX, and EDX to |*out_eax| through +// |*out_edx|. +static void OPENSSL_cpuid(uint32_t *out_eax, uint32_t *out_ebx, + uint32_t *out_ecx, uint32_t *out_edx, uint32_t leaf) { +#if defined(_MSC_VER) + int tmp[4]; + __cpuid(tmp, (int)leaf); + *out_eax = (uint32_t)tmp[0]; + *out_ebx = (uint32_t)tmp[1]; + *out_ecx = (uint32_t)tmp[2]; + *out_edx = (uint32_t)tmp[3]; +#elif defined(__pic__) && defined(OPENSSL_32_BIT) + // Inline assembly may not clobber the PIC register. For 32-bit, this is EBX. + // See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47602. + __asm__ volatile ( + "xor %%ecx, %%ecx\n" + "mov %%ebx, %%edi\n" + "cpuid\n" + "xchg %%edi, %%ebx\n" + : "=a"(*out_eax), "=D"(*out_ebx), "=c"(*out_ecx), "=d"(*out_edx) + : "a"(leaf) + ); +#else + __asm__ volatile ( + "xor %%ecx, %%ecx\n" + "cpuid\n" + : "=a"(*out_eax), "=b"(*out_ebx), "=c"(*out_ecx), "=d"(*out_edx) + : "a"(leaf) + ); +#endif +} + +// OPENSSL_xgetbv returns the value of an Intel Extended Control Register (XCR). +// Currently only XCR0 is defined by Intel so |xcr| should always be zero. +static uint64_t OPENSSL_xgetbv(uint32_t xcr) { +#if defined(_MSC_VER) + return (uint64_t)_xgetbv(xcr); +#else + uint32_t eax, edx; + __asm__ volatile ("xgetbv" : "=a"(eax), "=d"(edx) : "c"(xcr)); + return (((uint64_t)edx) << 32) | eax; +#endif +} + +// handle_cpu_env applies the value from |in| to the CPUID values in |out[0]| +// and |out[1]|. See the comment in |OPENSSL_cpuid_setup| about this. +static void handle_cpu_env(uint32_t *out, const char *in) { + const int invert = in[0] == '~'; + uint64_t v; + + if (!sscanf(in + invert, "%" PRIu64, &v)) { + return; + } + + if (invert) { + out[0] &= ~v; + out[1] &= ~(v >> 32); + } else { + out[0] = v; + out[1] = v >> 32; + } +} + +void OPENSSL_cpuid_setup(void) { + // Determine the vendor and maximum input value. + uint32_t eax, ebx, ecx, edx; + OPENSSL_cpuid(&eax, &ebx, &ecx, &edx, 0); + + uint32_t num_ids = eax; + + int is_intel = ebx == 0x756e6547 /* Genu */ && + edx == 0x49656e69 /* ineI */ && + ecx == 0x6c65746e /* ntel */; + int is_amd = ebx == 0x68747541 /* Auth */ && + edx == 0x69746e65 /* enti */ && + ecx == 0x444d4163 /* cAMD */; + + int has_amd_xop = 0; + if (is_amd) { + // AMD-specific logic. + // See http://developer.amd.com/wordpress/media/2012/10/254811.pdf + OPENSSL_cpuid(&eax, &ebx, &ecx, &edx, 0x80000000); + uint32_t num_extended_ids = eax; + if (num_extended_ids >= 0x80000001) { + OPENSSL_cpuid(&eax, &ebx, &ecx, &edx, 0x80000001); + if (ecx & (1u << 11)) { + has_amd_xop = 1; + } + } + } + + uint32_t extended_features = 0; + if (num_ids >= 7) { + OPENSSL_cpuid(&eax, &ebx, &ecx, &edx, 7); + extended_features = ebx; + } + + // Determine the number of cores sharing an L1 data cache to adjust the + // hyper-threading bit. + uint32_t cores_per_cache = 0; + if (is_amd) { + // AMD CPUs never share an L1 data cache between threads but do set the HTT + // bit on multi-core CPUs. + cores_per_cache = 1; + } else if (num_ids >= 4) { + // TODO(davidben): The Intel manual says this CPUID leaf enumerates all + // caches using ECX and doesn't say which is first. Does this matter? + OPENSSL_cpuid(&eax, &ebx, &ecx, &edx, 4); + cores_per_cache = 1 + ((eax >> 14) & 0xfff); + } + + OPENSSL_cpuid(&eax, &ebx, &ecx, &edx, 1); + + // Adjust the hyper-threading bit. + if (edx & (1u << 28)) { + uint32_t num_logical_cores = (ebx >> 16) & 0xff; + if (cores_per_cache == 1 || num_logical_cores <= 1) { + edx &= ~(1u << 28); + } + } + + // Reserved bit #20 was historically repurposed to control the in-memory + // representation of RC4 state. Always set it to zero. + edx &= ~(1u << 20); + + // Reserved bit #30 is repurposed to signal an Intel CPU. + if (is_intel) { + edx |= (1u << 30); + + // Clear the XSAVE bit on Knights Landing to mimic Silvermont. This enables + // some Silvermont-specific codepaths which perform better. See OpenSSL + // commit 64d92d74985ebb3d0be58a9718f9e080a14a8e7f. + if ((eax & 0x0fff0ff0) == 0x00050670 /* Knights Landing */ || + (eax & 0x0fff0ff0) == 0x00080650 /* Knights Mill (per SDE) */) { + ecx &= ~(1u << 26); + } + } else { + edx &= ~(1u << 30); + } + + // The SDBG bit is repurposed to denote AMD XOP support. + if (has_amd_xop) { + ecx |= (1u << 11); + } else { + ecx &= ~(1u << 11); + } + + uint64_t xcr0 = 0; + if (ecx & (1u << 27)) { + // XCR0 may only be queried if the OSXSAVE bit is set. + xcr0 = OPENSSL_xgetbv(0); + } + // See Intel manual, volume 1, section 14.3. + if ((xcr0 & 6) != 6) { + // YMM registers cannot be used. + ecx &= ~(1u << 28); // AVX + ecx &= ~(1u << 12); // FMA + ecx &= ~(1u << 11); // AMD XOP + // Clear AVX2 and AVX512* bits. + // + // TODO(davidben): Should bits 17 and 26-28 also be cleared? Upstream + // doesn't clear those. + extended_features &= + ~((1u << 5) | (1u << 16) | (1u << 21) | (1u << 30) | (1u << 31)); + } + // See Intel manual, volume 1, section 15.2. + if ((xcr0 & 0xe6) != 0xe6) { + // Clear AVX512F. Note we don't touch other AVX512 extensions because they + // can be used with YMM. + extended_features &= ~(1u << 16); + } + + // Disable ADX instructions on Knights Landing. See OpenSSL commit + // 64d92d74985ebb3d0be58a9718f9e080a14a8e7f. + if ((ecx & (1u << 26)) == 0) { + extended_features &= ~(1u << 19); + } + + OPENSSL_ia32cap_P[0] = edx; + OPENSSL_ia32cap_P[1] = ecx; + OPENSSL_ia32cap_P[2] = extended_features; + OPENSSL_ia32cap_P[3] = 0; + + const char *env1, *env2; + env1 = getenv("OPENSSL_ia32cap"); + if (env1 == NULL) { + return; + } + + // OPENSSL_ia32cap can contain zero, one or two values, separated with a ':'. + // Each value is a 64-bit, unsigned value which may start with "0x" to + // indicate a hex value. Prior to the 64-bit value, a '~' may be given. + // + // If '~' isn't present, then the value is taken as the result of the CPUID. + // Otherwise the value is inverted and ANDed with the probed CPUID result. + // + // The first value determines OPENSSL_ia32cap_P[0] and [1]. The second [2] + // and [3]. + + handle_cpu_env(&OPENSSL_ia32cap_P[0], env1); + env2 = strchr(env1, ':'); + if (env2 != NULL) { + handle_cpu_env(&OPENSSL_ia32cap_P[2], env2 + 1); + } +} + +#endif // !OPENSSL_NO_ASM && (OPENSSL_X86 || OPENSSL_X86_64) diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/cpu-intel.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/cpu-intel.c.grpc_back new file mode 100644 index 0000000..1ac280c --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/cpu-intel.c.grpc_back @@ -0,0 +1,288 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#if !defined(__STDC_FORMAT_MACROS) +#define __STDC_FORMAT_MACROS +#endif + +#include + + +#if !defined(OPENSSL_NO_ASM) && (defined(OPENSSL_X86) || defined(OPENSSL_X86_64)) + +#include +#include +#include +#include + +#if defined(_MSC_VER) +OPENSSL_MSVC_PRAGMA(warning(push, 3)) +#include +#include +OPENSSL_MSVC_PRAGMA(warning(pop)) +#endif + +#include "internal.h" + + +// OPENSSL_cpuid runs the cpuid instruction. |leaf| is passed in as EAX and ECX +// is set to zero. It writes EAX, EBX, ECX, and EDX to |*out_eax| through +// |*out_edx|. +static void OPENSSL_cpuid(uint32_t *out_eax, uint32_t *out_ebx, + uint32_t *out_ecx, uint32_t *out_edx, uint32_t leaf) { +#if defined(_MSC_VER) + int tmp[4]; + __cpuid(tmp, (int)leaf); + *out_eax = (uint32_t)tmp[0]; + *out_ebx = (uint32_t)tmp[1]; + *out_ecx = (uint32_t)tmp[2]; + *out_edx = (uint32_t)tmp[3]; +#elif defined(__pic__) && defined(OPENSSL_32_BIT) + // Inline assembly may not clobber the PIC register. For 32-bit, this is EBX. + // See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47602. + __asm__ volatile ( + "xor %%ecx, %%ecx\n" + "mov %%ebx, %%edi\n" + "cpuid\n" + "xchg %%edi, %%ebx\n" + : "=a"(*out_eax), "=D"(*out_ebx), "=c"(*out_ecx), "=d"(*out_edx) + : "a"(leaf) + ); +#else + __asm__ volatile ( + "xor %%ecx, %%ecx\n" + "cpuid\n" + : "=a"(*out_eax), "=b"(*out_ebx), "=c"(*out_ecx), "=d"(*out_edx) + : "a"(leaf) + ); +#endif +} + +// OPENSSL_xgetbv returns the value of an Intel Extended Control Register (XCR). +// Currently only XCR0 is defined by Intel so |xcr| should always be zero. +static uint64_t OPENSSL_xgetbv(uint32_t xcr) { +#if defined(_MSC_VER) + return (uint64_t)_xgetbv(xcr); +#else + uint32_t eax, edx; + __asm__ volatile ("xgetbv" : "=a"(eax), "=d"(edx) : "c"(xcr)); + return (((uint64_t)edx) << 32) | eax; +#endif +} + +// handle_cpu_env applies the value from |in| to the CPUID values in |out[0]| +// and |out[1]|. See the comment in |OPENSSL_cpuid_setup| about this. +static void handle_cpu_env(uint32_t *out, const char *in) { + const int invert = in[0] == '~'; + uint64_t v; + + if (!sscanf(in + invert, "%" PRIu64, &v)) { + return; + } + + if (invert) { + out[0] &= ~v; + out[1] &= ~(v >> 32); + } else { + out[0] = v; + out[1] = v >> 32; + } +} + +void OPENSSL_cpuid_setup(void) { + // Determine the vendor and maximum input value. + uint32_t eax, ebx, ecx, edx; + OPENSSL_cpuid(&eax, &ebx, &ecx, &edx, 0); + + uint32_t num_ids = eax; + + int is_intel = ebx == 0x756e6547 /* Genu */ && + edx == 0x49656e69 /* ineI */ && + ecx == 0x6c65746e /* ntel */; + int is_amd = ebx == 0x68747541 /* Auth */ && + edx == 0x69746e65 /* enti */ && + ecx == 0x444d4163 /* cAMD */; + + int has_amd_xop = 0; + if (is_amd) { + // AMD-specific logic. + // See http://developer.amd.com/wordpress/media/2012/10/254811.pdf + OPENSSL_cpuid(&eax, &ebx, &ecx, &edx, 0x80000000); + uint32_t num_extended_ids = eax; + if (num_extended_ids >= 0x80000001) { + OPENSSL_cpuid(&eax, &ebx, &ecx, &edx, 0x80000001); + if (ecx & (1u << 11)) { + has_amd_xop = 1; + } + } + } + + uint32_t extended_features = 0; + if (num_ids >= 7) { + OPENSSL_cpuid(&eax, &ebx, &ecx, &edx, 7); + extended_features = ebx; + } + + // Determine the number of cores sharing an L1 data cache to adjust the + // hyper-threading bit. + uint32_t cores_per_cache = 0; + if (is_amd) { + // AMD CPUs never share an L1 data cache between threads but do set the HTT + // bit on multi-core CPUs. + cores_per_cache = 1; + } else if (num_ids >= 4) { + // TODO(davidben): The Intel manual says this CPUID leaf enumerates all + // caches using ECX and doesn't say which is first. Does this matter? + OPENSSL_cpuid(&eax, &ebx, &ecx, &edx, 4); + cores_per_cache = 1 + ((eax >> 14) & 0xfff); + } + + OPENSSL_cpuid(&eax, &ebx, &ecx, &edx, 1); + + // Adjust the hyper-threading bit. + if (edx & (1u << 28)) { + uint32_t num_logical_cores = (ebx >> 16) & 0xff; + if (cores_per_cache == 1 || num_logical_cores <= 1) { + edx &= ~(1u << 28); + } + } + + // Reserved bit #20 was historically repurposed to control the in-memory + // representation of RC4 state. Always set it to zero. + edx &= ~(1u << 20); + + // Reserved bit #30 is repurposed to signal an Intel CPU. + if (is_intel) { + edx |= (1u << 30); + + // Clear the XSAVE bit on Knights Landing to mimic Silvermont. This enables + // some Silvermont-specific codepaths which perform better. See OpenSSL + // commit 64d92d74985ebb3d0be58a9718f9e080a14a8e7f. + if ((eax & 0x0fff0ff0) == 0x00050670 /* Knights Landing */ || + (eax & 0x0fff0ff0) == 0x00080650 /* Knights Mill (per SDE) */) { + ecx &= ~(1u << 26); + } + } else { + edx &= ~(1u << 30); + } + + // The SDBG bit is repurposed to denote AMD XOP support. + if (has_amd_xop) { + ecx |= (1u << 11); + } else { + ecx &= ~(1u << 11); + } + + uint64_t xcr0 = 0; + if (ecx & (1u << 27)) { + // XCR0 may only be queried if the OSXSAVE bit is set. + xcr0 = OPENSSL_xgetbv(0); + } + // See Intel manual, volume 1, section 14.3. + if ((xcr0 & 6) != 6) { + // YMM registers cannot be used. + ecx &= ~(1u << 28); // AVX + ecx &= ~(1u << 12); // FMA + ecx &= ~(1u << 11); // AMD XOP + // Clear AVX2 and AVX512* bits. + // + // TODO(davidben): Should bits 17 and 26-28 also be cleared? Upstream + // doesn't clear those. + extended_features &= + ~((1u << 5) | (1u << 16) | (1u << 21) | (1u << 30) | (1u << 31)); + } + // See Intel manual, volume 1, section 15.2. + if ((xcr0 & 0xe6) != 0xe6) { + // Clear AVX512F. Note we don't touch other AVX512 extensions because they + // can be used with YMM. + extended_features &= ~(1u << 16); + } + + // Disable ADX instructions on Knights Landing. See OpenSSL commit + // 64d92d74985ebb3d0be58a9718f9e080a14a8e7f. + if ((ecx & (1u << 26)) == 0) { + extended_features &= ~(1u << 19); + } + + OPENSSL_ia32cap_P[0] = edx; + OPENSSL_ia32cap_P[1] = ecx; + OPENSSL_ia32cap_P[2] = extended_features; + OPENSSL_ia32cap_P[3] = 0; + + const char *env1, *env2; + env1 = getenv("OPENSSL_ia32cap"); + if (env1 == NULL) { + return; + } + + // OPENSSL_ia32cap can contain zero, one or two values, separated with a ':'. + // Each value is a 64-bit, unsigned value which may start with "0x" to + // indicate a hex value. Prior to the 64-bit value, a '~' may be given. + // + // If '~' isn't present, then the value is taken as the result of the CPUID. + // Otherwise the value is inverted and ANDed with the probed CPUID result. + // + // The first value determines OPENSSL_ia32cap_P[0] and [1]. The second [2] + // and [3]. + + handle_cpu_env(&OPENSSL_ia32cap_P[0], env1); + env2 = strchr(env1, ':'); + if (env2 != NULL) { + handle_cpu_env(&OPENSSL_ia32cap_P[2], env2 + 1); + } +} + +#endif // !OPENSSL_NO_ASM && (OPENSSL_X86 || OPENSSL_X86_64) diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/cpu-ppc64le.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/cpu-ppc64le.c new file mode 100644 index 0000000..eee8ff8 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/cpu-ppc64le.c @@ -0,0 +1,38 @@ +/* Copyright (c) 2016, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#if defined(OPENSSL_PPC64LE) + +#include + +#include "internal.h" + + +#if !defined(PPC_FEATURE2_HAS_VCRYPTO) +// PPC_FEATURE2_HAS_VCRYPTO was taken from section 4.1.2.3 of the “OpenPOWER +// ABI for Linux Supplement”. +#define PPC_FEATURE2_HAS_VCRYPTO 0x02000000 +#endif + +void OPENSSL_cpuid_setup(void) { + OPENSSL_ppc64le_hwcap2 = getauxval(AT_HWCAP2); +} + +int CRYPTO_is_PPC64LE_vcrypto_capable(void) { + return (OPENSSL_ppc64le_hwcap2 & PPC_FEATURE2_HAS_VCRYPTO) != 0; +} + +#endif // OPENSSL_PPC64LE diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/cpu-ppc64le.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/cpu-ppc64le.c.grpc_back new file mode 100644 index 0000000..6cc8aee --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/cpu-ppc64le.c.grpc_back @@ -0,0 +1,38 @@ +/* Copyright (c) 2016, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#if defined(OPENSSL_PPC64LE) + +#include + +#include "internal.h" + + +#if !defined(PPC_FEATURE2_HAS_VCRYPTO) +// PPC_FEATURE2_HAS_VCRYPTO was taken from section 4.1.2.3 of the “OpenPOWER +// ABI for Linux Supplement”. +#define PPC_FEATURE2_HAS_VCRYPTO 0x02000000 +#endif + +void OPENSSL_cpuid_setup(void) { + OPENSSL_ppc64le_hwcap2 = getauxval(AT_HWCAP2); +} + +int CRYPTO_is_PPC64LE_vcrypto_capable(void) { + return (OPENSSL_ppc64le_hwcap2 & PPC_FEATURE2_HAS_VCRYPTO) != 0; +} + +#endif // OPENSSL_PPC64LE diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/crypto.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/crypto.c new file mode 100644 index 0000000..e892bb4 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/crypto.c @@ -0,0 +1,198 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include + +#include "internal.h" + + +#if !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_STATIC_ARMCAP) && \ + (defined(OPENSSL_X86) || defined(OPENSSL_X86_64) || \ + defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64) || \ + defined(OPENSSL_PPC64LE)) +// x86, x86_64, the ARMs and ppc64le need to record the result of a +// cpuid/getauxval call for the asm to work correctly, unless compiled without +// asm code. +#define NEED_CPUID + +#else + +// Otherwise, don't emit a static initialiser. + +#if !defined(BORINGSSL_NO_STATIC_INITIALIZER) +#define BORINGSSL_NO_STATIC_INITIALIZER +#endif + +#endif /* !OPENSSL_NO_ASM && (OPENSSL_X86 || OPENSSL_X86_64 || + OPENSSL_ARM || OPENSSL_AARCH64) */ + + +// Our assembly does not use the GOT to reference symbols, which means +// references to visible symbols will often require a TEXTREL. This is +// undesirable, so all assembly-referenced symbols should be hidden. CPU +// capabilities are the only such symbols defined in C. Explicitly hide them, +// rather than rely on being built with -fvisibility=hidden. +#if defined(OPENSSL_WINDOWS) +#define HIDDEN +#else +#define HIDDEN __attribute__((visibility("hidden"))) +#endif + + +// The capability variables are defined in this file in order to work around a +// linker bug. When linking with a .a, if no symbols in a .o are referenced +// then the .o is discarded, even if it has constructor functions. +// +// This still means that any binaries that don't include some functionality +// that tests the capability values will still skip the constructor but, so +// far, the init constructor function only sets the capability variables. + +#if defined(OPENSSL_X86) || defined(OPENSSL_X86_64) + +// This value must be explicitly initialised to zero in order to work around a +// bug in libtool or the linker on OS X. +// +// If not initialised then it becomes a "common symbol". When put into an +// archive, linking on OS X will fail to resolve common symbols. By +// initialising it to zero, it becomes a "data symbol", which isn't so +// affected. +HIDDEN uint32_t OPENSSL_ia32cap_P[4] = {0}; + +#elif defined(OPENSSL_PPC64LE) + +HIDDEN unsigned long OPENSSL_ppc64le_hwcap2 = 0; + +#elif defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64) + +#include + +#if defined(OPENSSL_STATIC_ARMCAP) + +HIDDEN uint32_t OPENSSL_armcap_P = +#if defined(OPENSSL_STATIC_ARMCAP_NEON) || defined(__ARM_NEON__) + ARMV7_NEON | +#endif +#if defined(OPENSSL_STATIC_ARMCAP_AES) || defined(__ARM_FEATURE_CRYPTO) + ARMV8_AES | +#endif +#if defined(OPENSSL_STATIC_ARMCAP_SHA1) || defined(__ARM_FEATURE_CRYPTO) + ARMV8_SHA1 | +#endif +#if defined(OPENSSL_STATIC_ARMCAP_SHA256) || defined(__ARM_FEATURE_CRYPTO) + ARMV8_SHA256 | +#endif +#if defined(OPENSSL_STATIC_ARMCAP_PMULL) || defined(__ARM_FEATURE_CRYPTO) + ARMV8_PMULL | +#endif + 0; + +#else +HIDDEN uint32_t OPENSSL_armcap_P = 0; +#endif + +#endif + +#if defined(BORINGSSL_FIPS) +// In FIPS mode, the power-on self-test function calls |CRYPTO_library_init| +// because we have to ensure that CPUID detection occurs first. +#define BORINGSSL_NO_STATIC_INITIALIZER +#endif + +#if defined(OPENSSL_WINDOWS) && !defined(BORINGSSL_NO_STATIC_INITIALIZER) +#define OPENSSL_CDECL __cdecl +#else +#define OPENSSL_CDECL +#endif + +#if defined(BORINGSSL_NO_STATIC_INITIALIZER) +static CRYPTO_once_t once = CRYPTO_ONCE_INIT; +#elif defined(_MSC_VER) +#pragma section(".CRT$XCU", read) +static void __cdecl do_library_init(void); +__declspec(allocate(".CRT$XCU")) void(*library_init_constructor)(void) = + do_library_init; +#else +static void do_library_init(void) __attribute__ ((constructor)); +#endif + +// do_library_init is the actual initialization function. If +// BORINGSSL_NO_STATIC_INITIALIZER isn't defined, this is set as a static +// initializer. Otherwise, it is called by CRYPTO_library_init. +static void OPENSSL_CDECL do_library_init(void) { + // WARNING: this function may only configure the capability variables. See the + // note above about the linker bug. +#if defined(NEED_CPUID) + OPENSSL_cpuid_setup(); +#endif +} + +void CRYPTO_library_init(void) { + // TODO(davidben): It would be tidier if this build knob could be replaced + // with an internal lazy-init mechanism that would handle things correctly + // in-library. https://crbug.com/542879 +#if defined(BORINGSSL_NO_STATIC_INITIALIZER) + CRYPTO_once(&once, do_library_init); +#endif +} + +int CRYPTO_is_confidential_build(void) { +#if defined(BORINGSSL_CONFIDENTIAL) + return 1; +#else + return 0; +#endif +} + +int CRYPTO_has_asm(void) { +#if defined(OPENSSL_NO_ASM) + return 0; +#else + return 1; +#endif +} + +const char *SSLeay_version(int unused) { + return "BoringSSL"; +} + +const char *OpenSSL_version(int unused) { + return "BoringSSL"; +} + +unsigned long SSLeay(void) { + return OPENSSL_VERSION_NUMBER; +} + +unsigned long OpenSSL_version_num(void) { + return OPENSSL_VERSION_NUMBER; +} + +int CRYPTO_malloc_init(void) { + return 1; +} + +void ENGINE_load_builtin_engines(void) {} + +int ENGINE_register_all_complete(void) { + return 1; +} + +void OPENSSL_load_builtin_modules(void) {} + +int OPENSSL_init_crypto(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings) { + CRYPTO_library_init(); + return 1; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/crypto.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/crypto.c.grpc_back new file mode 100644 index 0000000..9f4639f --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/crypto.c.grpc_back @@ -0,0 +1,198 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include + +#include "internal.h" + + +#if !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_STATIC_ARMCAP) && \ + (defined(OPENSSL_X86) || defined(OPENSSL_X86_64) || \ + defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64) || \ + defined(OPENSSL_PPC64LE)) +// x86, x86_64, the ARMs and ppc64le need to record the result of a +// cpuid/getauxval call for the asm to work correctly, unless compiled without +// asm code. +#define NEED_CPUID + +#else + +// Otherwise, don't emit a static initialiser. + +#if !defined(BORINGSSL_NO_STATIC_INITIALIZER) +#define BORINGSSL_NO_STATIC_INITIALIZER +#endif + +#endif /* !OPENSSL_NO_ASM && (OPENSSL_X86 || OPENSSL_X86_64 || + OPENSSL_ARM || OPENSSL_AARCH64) */ + + +// Our assembly does not use the GOT to reference symbols, which means +// references to visible symbols will often require a TEXTREL. This is +// undesirable, so all assembly-referenced symbols should be hidden. CPU +// capabilities are the only such symbols defined in C. Explicitly hide them, +// rather than rely on being built with -fvisibility=hidden. +#if defined(OPENSSL_WINDOWS) +#define HIDDEN +#else +#define HIDDEN __attribute__((visibility("hidden"))) +#endif + + +// The capability variables are defined in this file in order to work around a +// linker bug. When linking with a .a, if no symbols in a .o are referenced +// then the .o is discarded, even if it has constructor functions. +// +// This still means that any binaries that don't include some functionality +// that tests the capability values will still skip the constructor but, so +// far, the init constructor function only sets the capability variables. + +#if defined(OPENSSL_X86) || defined(OPENSSL_X86_64) + +// This value must be explicitly initialised to zero in order to work around a +// bug in libtool or the linker on OS X. +// +// If not initialised then it becomes a "common symbol". When put into an +// archive, linking on OS X will fail to resolve common symbols. By +// initialising it to zero, it becomes a "data symbol", which isn't so +// affected. +HIDDEN uint32_t OPENSSL_ia32cap_P[4] = {0}; + +#elif defined(OPENSSL_PPC64LE) + +HIDDEN unsigned long OPENSSL_ppc64le_hwcap2 = 0; + +#elif defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64) + +#include + +#if defined(OPENSSL_STATIC_ARMCAP) + +HIDDEN uint32_t OPENSSL_armcap_P = +#if defined(OPENSSL_STATIC_ARMCAP_NEON) || defined(__ARM_NEON__) + ARMV7_NEON | +#endif +#if defined(OPENSSL_STATIC_ARMCAP_AES) || defined(__ARM_FEATURE_CRYPTO) + ARMV8_AES | +#endif +#if defined(OPENSSL_STATIC_ARMCAP_SHA1) || defined(__ARM_FEATURE_CRYPTO) + ARMV8_SHA1 | +#endif +#if defined(OPENSSL_STATIC_ARMCAP_SHA256) || defined(__ARM_FEATURE_CRYPTO) + ARMV8_SHA256 | +#endif +#if defined(OPENSSL_STATIC_ARMCAP_PMULL) || defined(__ARM_FEATURE_CRYPTO) + ARMV8_PMULL | +#endif + 0; + +#else +HIDDEN uint32_t OPENSSL_armcap_P = 0; +#endif + +#endif + +#if defined(BORINGSSL_FIPS) +// In FIPS mode, the power-on self-test function calls |CRYPTO_library_init| +// because we have to ensure that CPUID detection occurs first. +#define BORINGSSL_NO_STATIC_INITIALIZER +#endif + +#if defined(OPENSSL_WINDOWS) && !defined(BORINGSSL_NO_STATIC_INITIALIZER) +#define OPENSSL_CDECL __cdecl +#else +#define OPENSSL_CDECL +#endif + +#if defined(BORINGSSL_NO_STATIC_INITIALIZER) +static CRYPTO_once_t once = CRYPTO_ONCE_INIT; +#elif defined(_MSC_VER) +#pragma section(".CRT$XCU", read) +static void __cdecl do_library_init(void); +__declspec(allocate(".CRT$XCU")) void(*library_init_constructor)(void) = + do_library_init; +#else +static void do_library_init(void) __attribute__ ((constructor)); +#endif + +// do_library_init is the actual initialization function. If +// BORINGSSL_NO_STATIC_INITIALIZER isn't defined, this is set as a static +// initializer. Otherwise, it is called by CRYPTO_library_init. +static void OPENSSL_CDECL do_library_init(void) { + // WARNING: this function may only configure the capability variables. See the + // note above about the linker bug. +#if defined(NEED_CPUID) + OPENSSL_cpuid_setup(); +#endif +} + +void CRYPTO_library_init(void) { + // TODO(davidben): It would be tidier if this build knob could be replaced + // with an internal lazy-init mechanism that would handle things correctly + // in-library. https://crbug.com/542879 +#if defined(BORINGSSL_NO_STATIC_INITIALIZER) + CRYPTO_once(&once, do_library_init); +#endif +} + +int CRYPTO_is_confidential_build(void) { +#if defined(BORINGSSL_CONFIDENTIAL) + return 1; +#else + return 0; +#endif +} + +int CRYPTO_has_asm(void) { +#if defined(OPENSSL_NO_ASM) + return 0; +#else + return 1; +#endif +} + +const char *SSLeay_version(int unused) { + return "BoringSSL"; +} + +const char *OpenSSL_version(int unused) { + return "BoringSSL"; +} + +unsigned long SSLeay(void) { + return OPENSSL_VERSION_NUMBER; +} + +unsigned long OpenSSL_version_num(void) { + return OPENSSL_VERSION_NUMBER; +} + +int CRYPTO_malloc_init(void) { + return 1; +} + +void ENGINE_load_builtin_engines(void) {} + +int ENGINE_register_all_complete(void) { + return 1; +} + +void OPENSSL_load_builtin_modules(void) {} + +int OPENSSL_init_crypto(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings) { + CRYPTO_library_init(); + return 1; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/curve25519/spake25519.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/curve25519/spake25519.c new file mode 100644 index 0000000..1b54ff3 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/curve25519/spake25519.c @@ -0,0 +1,539 @@ +/* Copyright (c) 2016, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include +#include + +#include +#include +#include +#include + +#include "../internal.h" +#include "../../third_party/fiat/internal.h" + + +// The following precomputation tables are for the following +// points used in the SPAKE2 protocol. +// +// N: +// x: 49918732221787544735331783592030787422991506689877079631459872391322455579424 +// y: 54629554431565467720832445949441049581317094546788069926228343916274969994000 +// encoded: 10e3df0ae37d8e7a99b5fe74b44672103dbddcbd06af680d71329a11693bc778 +// +// M: +// x: 31406539342727633121250288103050113562375374900226415211311216773867585644232 +// y: 21177308356423958466833845032658859666296341766942662650232962324899758529114 +// encoded: 5ada7e4bf6ddd9adb6626d32131c6b5c51a1e347a3478f53cfcf441b88eed12e +// +// These points and their precomputation tables are generated with the +// following Python code. For a description of the precomputation table, +// see curve25519.c in this directory. +// +// Exact copies of the source code are kept in bug 27296743. + +/* +import hashlib +import ed25519 as E # http://ed25519.cr.yp.to/python/ed25519.py + +SEED_N = 'edwards25519 point generation seed (N)' +SEED_M = 'edwards25519 point generation seed (M)' + +def genpoint(seed): + v = hashlib.sha256(seed).digest() + it = 1 + while True: + try: + x,y = E.decodepoint(v) + except Exception, e: + print e + it += 1 + v = hashlib.sha256(v).digest() + continue + print "Found in %d iterations:" % it + print " x = %d" % x + print " y = %d" % y + print " Encoded (hex)" + print E.encodepoint((x,y)).encode('hex') + return (x,y) + +def gentable(P): + t = [] + for i in range(1,16): + k = ((i >> 3 & 1) * (1 << 192) + + (i >> 2 & 1) * (1 << 128) + + (i >> 1 & 1) * (1 << 64) + + (i & 1)) + t.append(E.scalarmult(P, k)) + return ''.join(E.encodeint(x) + E.encodeint(y) for (x,y) in t) + +def printtable(table, name): + print "static const uint8_t %s[15 * 2 * 32] = {" % name, + for i in range(15 * 2 * 32): + if i % 12 == 0: + print "\n ", + print " 0x%02x," % ord(table[i]), + print "\n};" + +if __name__ == "__main__": + print "Searching for N" + N = genpoint(SEED_N) + print "Generating precomputation table for N" + Ntable = gentable(N) + printtable(Ntable, "kSpakeNSmallPrecomp") + + print "Searching for M" + M = genpoint(SEED_M) + print "Generating precomputation table for M" + Mtable = gentable(M) + printtable(Mtable, "kSpakeMSmallPrecomp") +*/ + +static const uint8_t kSpakeNSmallPrecomp[15 * 2 * 32] = { + 0x20, 0x1b, 0xc5, 0xb3, 0x43, 0x17, 0x71, 0x10, 0x44, 0x1e, 0x73, 0xb3, + 0xae, 0x3f, 0xbf, 0x9f, 0xf5, 0x44, 0xc8, 0x13, 0x8f, 0xd1, 0x01, 0xc2, + 0x8a, 0x1a, 0x6d, 0xea, 0x4d, 0x00, 0x5d, 0x6e, 0x10, 0xe3, 0xdf, 0x0a, + 0xe3, 0x7d, 0x8e, 0x7a, 0x99, 0xb5, 0xfe, 0x74, 0xb4, 0x46, 0x72, 0x10, + 0x3d, 0xbd, 0xdc, 0xbd, 0x06, 0xaf, 0x68, 0x0d, 0x71, 0x32, 0x9a, 0x11, + 0x69, 0x3b, 0xc7, 0x78, 0x93, 0xf1, 0x57, 0x97, 0x6e, 0xf0, 0x6e, 0x45, + 0x37, 0x4a, 0xf4, 0x0b, 0x18, 0x51, 0xf5, 0x4f, 0x67, 0x3c, 0xdc, 0xec, + 0x84, 0xed, 0xd0, 0xeb, 0xca, 0xfb, 0xdb, 0xff, 0x7f, 0xeb, 0xa8, 0x23, + 0x68, 0x87, 0x13, 0x64, 0x6a, 0x10, 0xf7, 0x45, 0xe0, 0x0f, 0x32, 0x21, + 0x59, 0x7c, 0x0e, 0x50, 0xad, 0x56, 0xd7, 0x12, 0x69, 0x7b, 0x58, 0xf8, + 0xb9, 0x3b, 0xa5, 0xbb, 0x4d, 0x1b, 0x87, 0x1c, 0x46, 0xa7, 0x17, 0x9d, + 0x6d, 0x84, 0x45, 0xbe, 0x7f, 0x95, 0xd2, 0x34, 0xcd, 0x89, 0x95, 0xc0, + 0xf0, 0xd3, 0xdf, 0x6e, 0x10, 0x4a, 0xe3, 0x7b, 0xce, 0x7f, 0x40, 0x27, + 0xc7, 0x2b, 0xab, 0x66, 0x03, 0x59, 0xb4, 0x7b, 0xc7, 0xc7, 0xf0, 0x39, + 0x9a, 0x33, 0x35, 0xbf, 0xcc, 0x2f, 0xf3, 0x2e, 0x68, 0x9d, 0x53, 0x5c, + 0x88, 0x52, 0xe3, 0x77, 0x90, 0xa1, 0x27, 0x85, 0xc5, 0x74, 0x7f, 0x23, + 0x0e, 0x93, 0x01, 0x3e, 0xe7, 0x2e, 0x2e, 0x95, 0xf3, 0x0d, 0xc2, 0x25, + 0x25, 0x39, 0x39, 0x3d, 0x6e, 0x8e, 0x89, 0xbd, 0xe8, 0xbb, 0x67, 0x5e, + 0x8c, 0x66, 0x8b, 0x63, 0x28, 0x1e, 0x4e, 0x74, 0x85, 0xa8, 0xaf, 0x0f, + 0x12, 0x5d, 0xb6, 0x8a, 0x83, 0x1a, 0x77, 0x76, 0x5e, 0x62, 0x8a, 0xa7, + 0x3c, 0xb8, 0x05, 0x57, 0x2b, 0xaf, 0x36, 0x2e, 0x10, 0x90, 0xb2, 0x39, + 0xb4, 0x3e, 0x75, 0x6d, 0x3a, 0xa8, 0x31, 0x35, 0xc2, 0x1e, 0x8f, 0xc2, + 0x79, 0x89, 0x35, 0x16, 0x26, 0xd1, 0xc7, 0x0b, 0x04, 0x1f, 0x1d, 0xf9, + 0x9c, 0x05, 0xa6, 0x6b, 0xb5, 0x19, 0x5a, 0x24, 0x6d, 0x91, 0xc5, 0x31, + 0xfd, 0xc5, 0xfa, 0xe7, 0xa6, 0xcb, 0x0e, 0x4b, 0x18, 0x0d, 0x94, 0xc7, + 0xee, 0x1d, 0x46, 0x1f, 0x92, 0xb1, 0xb2, 0x4a, 0x2b, 0x43, 0x37, 0xfe, + 0xc2, 0x15, 0x11, 0x89, 0xef, 0x59, 0x73, 0x3c, 0x06, 0x76, 0x78, 0xcb, + 0xa6, 0x0d, 0x79, 0x5f, 0x28, 0x0b, 0x5b, 0x8c, 0x9e, 0xe4, 0xaa, 0x51, + 0x9a, 0x42, 0x6f, 0x11, 0x50, 0x3d, 0x01, 0xd6, 0x21, 0xc0, 0x99, 0x5e, + 0x1a, 0xe8, 0x81, 0x25, 0x80, 0xeb, 0xed, 0x5d, 0x37, 0x47, 0x30, 0x70, + 0xa0, 0x4e, 0x0b, 0x43, 0x17, 0xbe, 0xb6, 0x47, 0xe7, 0x2a, 0x62, 0x9d, + 0x5d, 0xa6, 0xc5, 0x33, 0x62, 0x9d, 0x56, 0x24, 0x9d, 0x1d, 0xb2, 0x13, + 0xbc, 0x17, 0x66, 0x43, 0xd1, 0x68, 0xd5, 0x3b, 0x17, 0x69, 0x17, 0xa6, + 0x06, 0x9e, 0x12, 0xb8, 0x7c, 0xd5, 0xaf, 0x3e, 0x21, 0x1b, 0x31, 0xeb, + 0x0b, 0xa4, 0x98, 0x1c, 0xf2, 0x6a, 0x5e, 0x7c, 0x9b, 0x45, 0x8f, 0xb2, + 0x12, 0x06, 0xd5, 0x8c, 0x1d, 0xb2, 0xa7, 0x57, 0x5f, 0x2f, 0x4f, 0xdb, + 0x52, 0x99, 0x7c, 0x58, 0x01, 0x5f, 0xf2, 0xa5, 0xf6, 0x51, 0x86, 0x21, + 0x2f, 0x5b, 0x8d, 0x6a, 0xae, 0x83, 0x34, 0x6d, 0x58, 0x4b, 0xef, 0xfe, + 0xbf, 0x73, 0x5d, 0xdb, 0xc4, 0x97, 0x2a, 0x85, 0xf3, 0x6c, 0x46, 0x42, + 0xb3, 0x90, 0xc1, 0x57, 0x97, 0x50, 0x35, 0xb1, 0x9d, 0xb7, 0xc7, 0x3c, + 0x85, 0x6d, 0x6c, 0xfd, 0xce, 0xb0, 0xc9, 0xa2, 0x77, 0xee, 0xc3, 0x6b, + 0x0c, 0x37, 0xfa, 0x30, 0x91, 0xd1, 0x2c, 0xb8, 0x5e, 0x7f, 0x81, 0x5f, + 0x87, 0xfd, 0x18, 0x02, 0x5a, 0x30, 0x4e, 0x62, 0xbc, 0x65, 0xc6, 0xce, + 0x1a, 0xcf, 0x2b, 0xaa, 0x56, 0x3e, 0x4d, 0xcf, 0xba, 0x62, 0x5f, 0x9a, + 0xd0, 0x72, 0xff, 0xef, 0x28, 0xbd, 0xbe, 0xd8, 0x57, 0x3d, 0xf5, 0x57, + 0x7d, 0xe9, 0x71, 0x31, 0xec, 0x98, 0x90, 0x94, 0xd9, 0x54, 0xbf, 0x84, + 0x0b, 0xe3, 0x06, 0x47, 0x19, 0x9a, 0x13, 0x1d, 0xef, 0x9d, 0x13, 0xf3, + 0xdb, 0xc3, 0x5c, 0x72, 0x9e, 0xed, 0x24, 0xaa, 0x64, 0xed, 0xe7, 0x0d, + 0xa0, 0x7c, 0x73, 0xba, 0x9b, 0x86, 0xa7, 0x3b, 0x55, 0xab, 0x58, 0x30, + 0xf1, 0x15, 0x81, 0x83, 0x2f, 0xf9, 0x62, 0x84, 0x98, 0x66, 0xf6, 0x55, + 0x21, 0xd8, 0xf2, 0x25, 0x64, 0x71, 0x4b, 0x12, 0x76, 0x59, 0xc5, 0xaa, + 0x93, 0x67, 0xc3, 0x86, 0x25, 0xab, 0x4e, 0x4b, 0xf6, 0xd8, 0x3f, 0x44, + 0x2e, 0x11, 0xe0, 0xbd, 0x6a, 0xf2, 0x5d, 0xf5, 0xf9, 0x53, 0xea, 0xa4, + 0xc8, 0xd9, 0x50, 0x33, 0x81, 0xd9, 0xa8, 0x2d, 0x91, 0x7d, 0x13, 0x2a, + 0x11, 0xcf, 0xde, 0x3f, 0x0a, 0xd2, 0xbc, 0x33, 0xb2, 0x62, 0x53, 0xea, + 0x77, 0x88, 0x43, 0x66, 0x27, 0x43, 0x85, 0xe9, 0x5f, 0x55, 0xf5, 0x2a, + 0x8a, 0xac, 0xdf, 0xff, 0x9b, 0x4c, 0x96, 0x9c, 0xa5, 0x7a, 0xce, 0xd5, + 0x79, 0x18, 0xf1, 0x0b, 0x58, 0x95, 0x7a, 0xe7, 0xd3, 0x74, 0x65, 0x0b, + 0xa4, 0x64, 0x30, 0xe8, 0x5c, 0xfc, 0x55, 0x56, 0xee, 0x14, 0x14, 0xd3, + 0x45, 0x3b, 0xf8, 0xde, 0x05, 0x3e, 0xb9, 0x3c, 0xd7, 0x6a, 0x52, 0x72, + 0x5b, 0x39, 0x09, 0xbe, 0x82, 0x23, 0x10, 0x4a, 0xb7, 0xc3, 0xdc, 0x4c, + 0x5d, 0xc9, 0xf1, 0x14, 0x83, 0xf9, 0x0b, 0x9b, 0xe9, 0x23, 0x84, 0x6a, + 0xc4, 0x08, 0x3d, 0xda, 0x3d, 0x12, 0x95, 0x87, 0x18, 0xa4, 0x7d, 0x3f, + 0x23, 0xde, 0xd4, 0x1e, 0xa8, 0x47, 0xc3, 0x71, 0xdb, 0xf5, 0x03, 0x6c, + 0x57, 0xe7, 0xa4, 0x43, 0x82, 0x33, 0x7b, 0x62, 0x46, 0x7d, 0xf7, 0x10, + 0x69, 0x18, 0x38, 0x27, 0x9a, 0x6f, 0x38, 0xac, 0xfa, 0x92, 0xc5, 0xae, + 0x66, 0xa6, 0x73, 0x95, 0x15, 0x0e, 0x4c, 0x04, 0xb6, 0xfc, 0xf5, 0xc7, + 0x21, 0x3a, 0x99, 0xdb, 0x0e, 0x36, 0xf0, 0x56, 0xbc, 0x75, 0xf9, 0x87, + 0x9b, 0x11, 0x18, 0x92, 0x64, 0x1a, 0xe7, 0xc7, 0xab, 0x5a, 0xc7, 0x26, + 0x7f, 0x13, 0x98, 0x42, 0x52, 0x43, 0xdb, 0xc8, 0x6d, 0x0b, 0xb7, 0x31, + 0x93, 0x24, 0xd6, 0xe8, 0x24, 0x1f, 0x6f, 0x21, 0xa7, 0x8c, 0xeb, 0xdb, + 0x83, 0xb8, 0x89, 0xe3, 0xc1, 0xd7, 0x69, 0x3b, 0x02, 0x6b, 0x54, 0x0f, + 0x84, 0x2f, 0xb5, 0x5c, 0x17, 0x77, 0xbe, 0xe5, 0x61, 0x0d, 0xc5, 0xdf, + 0x3b, 0xcf, 0x3e, 0x93, 0x4f, 0xf5, 0x89, 0xb9, 0x5a, 0xc5, 0x29, 0x31, + 0xc0, 0xc2, 0xff, 0xe5, 0x3f, 0xa6, 0xac, 0x03, 0xca, 0xf5, 0xff, 0xe0, + 0x36, 0xce, 0xf3, 0xe2, 0xb7, 0x9c, 0x02, 0xe9, 0x9e, 0xd2, 0xbc, 0x87, + 0x2f, 0x3d, 0x9a, 0x1d, 0x8f, 0xc5, 0x72, 0xb8, 0xa2, 0x01, 0xd4, 0x68, + 0xb1, 0x84, 0x16, 0x10, 0xf6, 0xf3, 0x52, 0x25, 0xd9, 0xdc, 0x4c, 0xdd, + 0x0f, 0xd6, 0x4a, 0xcf, 0x60, 0x96, 0x7e, 0xcc, 0x42, 0x0f, 0x64, 0x9d, + 0x72, 0x46, 0x04, 0x07, 0xf2, 0x5b, 0xf4, 0x07, 0xd1, 0xf4, 0x59, 0x71, +}; + +static const uint8_t kSpakeMSmallPrecomp[15 * 2 * 32] = { + 0xc8, 0xa6, 0x63, 0xc5, 0x97, 0xf1, 0xee, 0x40, 0xab, 0x62, 0x42, 0xee, + 0x25, 0x6f, 0x32, 0x6c, 0x75, 0x2c, 0xa7, 0xd3, 0xbd, 0x32, 0x3b, 0x1e, + 0x11, 0x9c, 0xbd, 0x04, 0xa9, 0x78, 0x6f, 0x45, 0x5a, 0xda, 0x7e, 0x4b, + 0xf6, 0xdd, 0xd9, 0xad, 0xb6, 0x62, 0x6d, 0x32, 0x13, 0x1c, 0x6b, 0x5c, + 0x51, 0xa1, 0xe3, 0x47, 0xa3, 0x47, 0x8f, 0x53, 0xcf, 0xcf, 0x44, 0x1b, + 0x88, 0xee, 0xd1, 0x2e, 0x03, 0x89, 0xaf, 0xc0, 0x61, 0x2d, 0x9e, 0x35, + 0xeb, 0x0e, 0x03, 0xe0, 0xb7, 0xfb, 0xa5, 0xbc, 0x44, 0xbe, 0x0c, 0x89, + 0x0a, 0x0f, 0xd6, 0x59, 0x47, 0x9e, 0xe6, 0x3d, 0x36, 0x9d, 0xff, 0x44, + 0x5e, 0xac, 0xab, 0xe5, 0x3a, 0xd5, 0xb0, 0x35, 0x9f, 0x6d, 0x7f, 0xba, + 0xc0, 0x85, 0x0e, 0xf4, 0x70, 0x3f, 0x13, 0x90, 0x4c, 0x50, 0x1a, 0xee, + 0xc5, 0xeb, 0x69, 0xfe, 0x98, 0x42, 0x87, 0x1d, 0xce, 0x6c, 0x29, 0xaa, + 0x2b, 0x31, 0xc2, 0x38, 0x7b, 0x6b, 0xee, 0x88, 0x0b, 0xba, 0xce, 0xa8, + 0xca, 0x19, 0x60, 0x1b, 0x16, 0xf1, 0x25, 0x1e, 0xcf, 0x63, 0x66, 0x1e, + 0xbb, 0x63, 0xeb, 0x7d, 0xca, 0xd2, 0xb4, 0x23, 0x5a, 0x01, 0x6f, 0x05, + 0xd1, 0xdc, 0x41, 0x73, 0x75, 0xc0, 0xfd, 0x30, 0x91, 0x52, 0x68, 0x96, + 0x45, 0xb3, 0x66, 0x01, 0x3b, 0x53, 0x89, 0x3c, 0x69, 0xbc, 0x6c, 0x69, + 0xe3, 0x51, 0x8f, 0xe3, 0xd2, 0x84, 0xd5, 0x28, 0x66, 0xb5, 0xe6, 0x06, + 0x09, 0xfe, 0x6d, 0xb0, 0x72, 0x16, 0xe0, 0x8a, 0xce, 0x61, 0x65, 0xa9, + 0x21, 0x32, 0x48, 0xdc, 0x7a, 0x1d, 0xe1, 0x38, 0x7f, 0x8c, 0x75, 0x88, + 0x3d, 0x08, 0xa9, 0x4a, 0x6f, 0x3d, 0x9f, 0x7f, 0x3f, 0xbd, 0x57, 0x6b, + 0x19, 0xce, 0x3f, 0x4a, 0xc9, 0xd3, 0xf9, 0x6e, 0x72, 0x7b, 0x5b, 0x74, + 0xea, 0xbe, 0x9c, 0x7a, 0x6d, 0x9c, 0x40, 0x49, 0xe6, 0xfb, 0x2a, 0x1a, + 0x75, 0x70, 0xe5, 0x4e, 0xed, 0x74, 0xe0, 0x75, 0xac, 0xc0, 0xb1, 0x11, + 0x3e, 0xf2, 0xaf, 0x88, 0x4d, 0x66, 0xb6, 0xf6, 0x15, 0x4f, 0x3c, 0x6c, + 0x77, 0xae, 0x47, 0x51, 0x63, 0x9a, 0xfe, 0xe1, 0xb4, 0x1a, 0x12, 0xdf, + 0xe9, 0x54, 0x8d, 0x3b, 0x30, 0x2a, 0x75, 0xe3, 0xe5, 0x29, 0xb1, 0x4c, + 0xb0, 0x7c, 0x6d, 0xb5, 0xae, 0x85, 0xdb, 0x1e, 0x38, 0x55, 0x96, 0xa5, + 0x5b, 0x9f, 0x15, 0x23, 0x28, 0x36, 0xb8, 0xa2, 0x41, 0xb4, 0xd7, 0x19, + 0x91, 0x8d, 0x26, 0x3e, 0xca, 0x9c, 0x05, 0x7a, 0x2b, 0x60, 0x45, 0x86, + 0x8b, 0xee, 0x64, 0x6f, 0x5c, 0x09, 0x4d, 0x4b, 0x5a, 0x7f, 0xb0, 0xc3, + 0x26, 0x9d, 0x8b, 0xb8, 0x83, 0x69, 0xcf, 0x16, 0x72, 0x62, 0x3e, 0x5e, + 0x53, 0x4f, 0x9c, 0x73, 0x76, 0xfc, 0x19, 0xef, 0xa0, 0x74, 0x3a, 0x11, + 0x1e, 0xd0, 0x4d, 0xb7, 0x87, 0xa1, 0xd6, 0x87, 0x6c, 0x0e, 0x6c, 0x8c, + 0xe9, 0xa0, 0x44, 0xc4, 0x72, 0x3e, 0x73, 0x17, 0x13, 0xd1, 0x4e, 0x3d, + 0x8e, 0x1d, 0x5a, 0x8b, 0x75, 0xcb, 0x59, 0x2c, 0x47, 0x87, 0x15, 0x41, + 0xfe, 0x08, 0xe9, 0xa6, 0x97, 0x17, 0x08, 0x26, 0x6a, 0xb5, 0xbb, 0x73, + 0xaa, 0xb8, 0x5b, 0x65, 0x65, 0x5b, 0x30, 0x9e, 0x62, 0x59, 0x02, 0xf8, + 0xb8, 0x0f, 0x32, 0x10, 0xc1, 0x36, 0x08, 0x52, 0x98, 0x4a, 0x1e, 0xf0, + 0xab, 0x21, 0x5e, 0xde, 0x16, 0x0c, 0xda, 0x09, 0x99, 0x6b, 0x9e, 0xc0, + 0x90, 0xa5, 0x5a, 0xcc, 0xb0, 0xb7, 0xbb, 0xd2, 0x8b, 0x5f, 0xd3, 0x3b, + 0x3e, 0x8c, 0xa5, 0x71, 0x66, 0x06, 0xe3, 0x28, 0xd4, 0xf8, 0x3f, 0xe5, + 0x27, 0xdf, 0xfe, 0x0f, 0x09, 0xb2, 0x8a, 0x09, 0x5a, 0x23, 0x61, 0x0d, + 0x2d, 0xf5, 0x44, 0xf1, 0x5c, 0xf8, 0x82, 0x4e, 0xdc, 0x78, 0x7a, 0xab, + 0xc3, 0x57, 0x91, 0xaf, 0x65, 0x6e, 0x71, 0xf1, 0x44, 0xbf, 0xed, 0x43, + 0x50, 0xb4, 0x67, 0x48, 0xef, 0x5a, 0x10, 0x46, 0x81, 0xb4, 0x0c, 0xc8, + 0x48, 0xed, 0x99, 0x7a, 0x45, 0xa5, 0x92, 0xc3, 0x69, 0xd6, 0xd7, 0x8a, + 0x20, 0x1b, 0xeb, 0x8f, 0xb2, 0xff, 0xec, 0x6d, 0x76, 0x04, 0xf8, 0xc2, + 0x58, 0x9b, 0xf2, 0x20, 0x53, 0xc4, 0x74, 0x91, 0x19, 0xdd, 0x2d, 0x12, + 0x53, 0xc7, 0x6e, 0xd0, 0x02, 0x51, 0x3c, 0xa6, 0x7d, 0x80, 0x75, 0x6b, + 0x1d, 0xdf, 0xf8, 0x6a, 0x52, 0xbb, 0x81, 0xf8, 0x30, 0x45, 0xef, 0x51, + 0x85, 0x36, 0xbe, 0x8e, 0xcf, 0x0b, 0x9a, 0x46, 0xe8, 0x3f, 0x99, 0xfd, + 0xf7, 0xd9, 0x3e, 0x84, 0xe5, 0xe3, 0x37, 0xcf, 0x98, 0x7f, 0xeb, 0x5e, + 0x5a, 0x53, 0x77, 0x1c, 0x20, 0xdc, 0xf1, 0x20, 0x99, 0xec, 0x60, 0x40, + 0x93, 0xef, 0x5c, 0x1c, 0x81, 0xe2, 0xa5, 0xad, 0x2a, 0xc2, 0xdb, 0x6b, + 0xc1, 0x7e, 0x8f, 0xa9, 0x23, 0x5b, 0xd9, 0x0d, 0xfe, 0xa0, 0xac, 0x11, + 0x28, 0xba, 0x8e, 0x92, 0x07, 0x2d, 0x07, 0x40, 0x83, 0x14, 0x4c, 0x35, + 0x8d, 0xd0, 0x11, 0xff, 0x98, 0xdb, 0x00, 0x30, 0x6f, 0x65, 0xb6, 0xa0, + 0x7f, 0x9c, 0x08, 0xb8, 0xce, 0xb3, 0xa8, 0x42, 0xd3, 0x84, 0x45, 0xe1, + 0xe3, 0x8f, 0xa6, 0x89, 0x21, 0xd7, 0x74, 0x02, 0x4d, 0x64, 0xdf, 0x54, + 0x15, 0x9e, 0xba, 0x12, 0x49, 0x09, 0x41, 0xf6, 0x10, 0x24, 0xa1, 0x84, + 0x15, 0xfd, 0x68, 0x6a, 0x57, 0x66, 0xb3, 0x6d, 0x4c, 0xea, 0xbf, 0xbc, + 0x60, 0x3f, 0x52, 0x1c, 0x44, 0x1b, 0xc0, 0x4a, 0x25, 0xe3, 0xd9, 0x4c, + 0x9a, 0x74, 0xad, 0xfc, 0x9e, 0x8d, 0x0b, 0x18, 0x66, 0x24, 0xd1, 0x06, + 0xac, 0x68, 0xc1, 0xae, 0x14, 0xce, 0xb1, 0xf3, 0x86, 0x9f, 0x87, 0x11, + 0xd7, 0x9f, 0x30, 0x92, 0xdb, 0xec, 0x0b, 0x4a, 0xe8, 0xf6, 0x53, 0x36, + 0x68, 0x12, 0x11, 0x5e, 0xe0, 0x34, 0xa4, 0xff, 0x00, 0x0a, 0x26, 0xb8, + 0x62, 0x79, 0x9c, 0x0c, 0xd5, 0xe5, 0xf5, 0x1c, 0x1a, 0x16, 0x84, 0x4d, + 0x8e, 0x5d, 0x31, 0x7e, 0xf7, 0xe2, 0xd3, 0xa1, 0x41, 0x90, 0x61, 0x5d, + 0x04, 0xb2, 0x9a, 0x18, 0x9e, 0x54, 0xfb, 0xd1, 0x61, 0x95, 0x1b, 0x08, + 0xca, 0x7c, 0x49, 0x44, 0x74, 0x1d, 0x2f, 0xca, 0xc4, 0x7a, 0xe1, 0x8b, + 0x2f, 0xbb, 0x96, 0xee, 0x19, 0x8a, 0x5d, 0xfb, 0x3e, 0x82, 0xe7, 0x15, + 0xdb, 0x29, 0x14, 0xee, 0xc9, 0x4d, 0x9a, 0xfb, 0x9f, 0x8a, 0xbb, 0x17, + 0x37, 0x1b, 0x6e, 0x28, 0x6c, 0xf9, 0xff, 0xb5, 0xb5, 0x8b, 0x9d, 0x88, + 0x20, 0x08, 0x10, 0xd7, 0xca, 0x58, 0xf6, 0xe1, 0x32, 0x91, 0x6f, 0x36, + 0xc0, 0xad, 0xc1, 0x57, 0x5d, 0x76, 0x31, 0x43, 0xf3, 0xdd, 0xec, 0xf1, + 0xa9, 0x79, 0xe9, 0xe9, 0x85, 0xd7, 0x91, 0xc7, 0x31, 0x62, 0x3c, 0xd2, + 0x90, 0x2c, 0x9c, 0xa4, 0x56, 0x37, 0x7b, 0xbe, 0x40, 0x58, 0xc0, 0x81, + 0x83, 0x22, 0xe8, 0x13, 0x79, 0x18, 0xdb, 0x3a, 0x1b, 0x31, 0x0d, 0x00, + 0x6c, 0x22, 0x62, 0x75, 0x70, 0xd8, 0x96, 0x59, 0x99, 0x44, 0x79, 0x71, + 0xa6, 0x76, 0x81, 0x28, 0xb2, 0x65, 0xe8, 0x47, 0x14, 0xc6, 0x39, 0x06, +}; + +SPAKE2_CTX *SPAKE2_CTX_new(enum spake2_role_t my_role, + const uint8_t *my_name, size_t my_name_len, + const uint8_t *their_name, size_t their_name_len) { + SPAKE2_CTX *ctx = OPENSSL_malloc(sizeof(SPAKE2_CTX)); + if (ctx == NULL) { + return NULL; + } + + OPENSSL_memset(ctx, 0, sizeof(SPAKE2_CTX)); + ctx->my_role = my_role; + + CBS my_name_cbs, their_name_cbs; + CBS_init(&my_name_cbs, my_name, my_name_len); + CBS_init(&their_name_cbs, their_name, their_name_len); + if (!CBS_stow(&my_name_cbs, &ctx->my_name, &ctx->my_name_len) || + !CBS_stow(&their_name_cbs, &ctx->their_name, &ctx->their_name_len)) { + SPAKE2_CTX_free(ctx); + return NULL; + } + + return ctx; +} + +void SPAKE2_CTX_free(SPAKE2_CTX *ctx) { + if (ctx == NULL) { + return; + } + + OPENSSL_free(ctx->my_name); + OPENSSL_free(ctx->their_name); + OPENSSL_free(ctx); +} + +// left_shift_3 sets |n| to |n|*8, where |n| is represented in little-endian +// order. +static void left_shift_3(uint8_t n[32]) { + uint8_t carry = 0; + unsigned i; + + for (i = 0; i < 32; i++) { + const uint8_t next_carry = n[i] >> 5; + n[i] = (n[i] << 3) | carry; + carry = next_carry; + } +} + +typedef union { + uint8_t bytes[32]; + uint32_t words[8]; +} scalar; + +// kOrder is the order of the prime-order subgroup of curve25519 in +// little-endian order. +static const scalar kOrder = {{0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, + 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}}; + +// scalar_cmov copies |src| to |dest| if |mask| is all ones. +static void scalar_cmov(scalar *dest, const scalar *src, crypto_word_t mask) { + for (size_t i = 0; i < 8; i++) { + dest->words[i] = + constant_time_select_w(mask, src->words[i], dest->words[i]); + } +} + +// scalar_double sets |s| to |2×s|. +static void scalar_double(scalar *s) { + uint32_t carry = 0; + + for (size_t i = 0; i < 8; i++) { + const uint32_t carry_out = s->words[i] >> 31; + s->words[i] = (s->words[i] << 1) | carry; + carry = carry_out; + } +} + +// scalar_add sets |dest| to |dest| plus |src|. +static void scalar_add(scalar *dest, const scalar *src) { + uint32_t carry = 0; + + for (size_t i = 0; i < 8; i++) { + uint64_t tmp = ((uint64_t)dest->words[i] + src->words[i]) + carry; + dest->words[i] = (uint32_t)tmp; + carry = (uint32_t)(tmp >> 32); + } +} + +int SPAKE2_generate_msg(SPAKE2_CTX *ctx, uint8_t *out, size_t *out_len, + size_t max_out_len, const uint8_t *password, + size_t password_len) { + if (ctx->state != spake2_state_init) { + return 0; + } + + if (max_out_len < sizeof(ctx->my_msg)) { + return 0; + } + + uint8_t private_tmp[64]; + RAND_bytes(private_tmp, sizeof(private_tmp)); + x25519_sc_reduce(private_tmp); + // Multiply by the cofactor (eight) so that we'll clear it when operating on + // the peer's point later in the protocol. + left_shift_3(private_tmp); + OPENSSL_memcpy(ctx->private_key, private_tmp, sizeof(ctx->private_key)); + + ge_p3 P; + x25519_ge_scalarmult_base(&P, ctx->private_key); + + // mask = h(password) * . + uint8_t password_tmp[SHA512_DIGEST_LENGTH]; + SHA512(password, password_len, password_tmp); + OPENSSL_memcpy(ctx->password_hash, password_tmp, sizeof(ctx->password_hash)); + x25519_sc_reduce(password_tmp); + + // Due to a copy-paste error, the call to |left_shift_3| was omitted after + // the |x25519_sc_reduce|, just above. This meant that |ctx->password_scalar| + // was not a multiple of eight to clear the cofactor and thus three bits of + // the password hash would leak. In order to fix this in a unilateral way, + // points of small order are added to the mask point such that it is in the + // prime-order subgroup. Since the ephemeral scalar is a multiple of eight, + // these points will cancel out when calculating the shared secret. + // + // Adding points of small order is the same as adding multiples of the prime + // order to the password scalar. Since that's faster, that is what is done + // below. The prime order (kOrder) is a large prime, thus odd, thus the LSB + // is one. So adding it will flip the LSB. Adding twice it will flip the next + // bit and so one for all the bottom three bits. + + scalar password_scalar; + OPENSSL_memcpy(&password_scalar, password_tmp, sizeof(password_scalar)); + + // |password_scalar| is the result of |x25519_sc_reduce| and thus is, at + // most, $l-1$ (where $l$ is |kOrder|, the order of the prime-order subgroup + // of Ed25519). In the following, we may add $l + 2×l + 4×l$ for a max value + // of $8×l-1$. That is < 2**256, as required. + + if (!ctx->disable_password_scalar_hack) { + scalar order = kOrder; + scalar tmp; + + OPENSSL_memset(&tmp, 0, sizeof(tmp)); + scalar_cmov(&tmp, &order, + constant_time_eq_w(password_scalar.bytes[0] & 1, 1)); + scalar_add(&password_scalar, &tmp); + + scalar_double(&order); + OPENSSL_memset(&tmp, 0, sizeof(tmp)); + scalar_cmov(&tmp, &order, + constant_time_eq_w(password_scalar.bytes[0] & 2, 2)); + scalar_add(&password_scalar, &tmp); + + scalar_double(&order); + OPENSSL_memset(&tmp, 0, sizeof(tmp)); + scalar_cmov(&tmp, &order, + constant_time_eq_w(password_scalar.bytes[0] & 4, 4)); + scalar_add(&password_scalar, &tmp); + + assert((password_scalar.bytes[0] & 7) == 0); + } + + OPENSSL_memcpy(ctx->password_scalar, password_scalar.bytes, + sizeof(ctx->password_scalar)); + + ge_p3 mask; + x25519_ge_scalarmult_small_precomp(&mask, ctx->password_scalar, + ctx->my_role == spake2_role_alice + ? kSpakeMSmallPrecomp + : kSpakeNSmallPrecomp); + + // P* = P + mask. + ge_cached mask_cached; + x25519_ge_p3_to_cached(&mask_cached, &mask); + ge_p1p1 Pstar; + x25519_ge_add(&Pstar, &P, &mask_cached); + + // Encode P* + ge_p2 Pstar_proj; + x25519_ge_p1p1_to_p2(&Pstar_proj, &Pstar); + x25519_ge_tobytes(ctx->my_msg, &Pstar_proj); + + OPENSSL_memcpy(out, ctx->my_msg, sizeof(ctx->my_msg)); + *out_len = sizeof(ctx->my_msg); + ctx->state = spake2_state_msg_generated; + + return 1; +} + +static void update_with_length_prefix(SHA512_CTX *sha, const uint8_t *data, + const size_t len) { + uint8_t len_le[8]; + size_t l = len; + unsigned i; + + for (i = 0; i < 8; i++) { + len_le[i] = l & 0xff; + l >>= 8; + } + + SHA512_Update(sha, len_le, sizeof(len_le)); + SHA512_Update(sha, data, len); +} + +int SPAKE2_process_msg(SPAKE2_CTX *ctx, uint8_t *out_key, size_t *out_key_len, + size_t max_out_key_len, const uint8_t *their_msg, + size_t their_msg_len) { + if (ctx->state != spake2_state_msg_generated || + their_msg_len != 32) { + return 0; + } + + ge_p3 Qstar; + if (0 != x25519_ge_frombytes_vartime(&Qstar, their_msg)) { + // Point received from peer was not on the curve. + return 0; + } + + // Unmask peer's value. + ge_p3 peers_mask; + x25519_ge_scalarmult_small_precomp(&peers_mask, ctx->password_scalar, + ctx->my_role == spake2_role_alice + ? kSpakeNSmallPrecomp + : kSpakeMSmallPrecomp); + + ge_cached peers_mask_cached; + x25519_ge_p3_to_cached(&peers_mask_cached, &peers_mask); + + ge_p1p1 Q_compl; + ge_p3 Q_ext; + x25519_ge_sub(&Q_compl, &Qstar, &peers_mask_cached); + x25519_ge_p1p1_to_p3(&Q_ext, &Q_compl); + + ge_p2 dh_shared; + x25519_ge_scalarmult(&dh_shared, ctx->private_key, &Q_ext); + + uint8_t dh_shared_encoded[32]; + x25519_ge_tobytes(dh_shared_encoded, &dh_shared); + + SHA512_CTX sha; + SHA512_Init(&sha); + if (ctx->my_role == spake2_role_alice) { + update_with_length_prefix(&sha, ctx->my_name, ctx->my_name_len); + update_with_length_prefix(&sha, ctx->their_name, ctx->their_name_len); + update_with_length_prefix(&sha, ctx->my_msg, sizeof(ctx->my_msg)); + update_with_length_prefix(&sha, their_msg, 32); + } else { + update_with_length_prefix(&sha, ctx->their_name, ctx->their_name_len); + update_with_length_prefix(&sha, ctx->my_name, ctx->my_name_len); + update_with_length_prefix(&sha, their_msg, 32); + update_with_length_prefix(&sha, ctx->my_msg, sizeof(ctx->my_msg)); + } + update_with_length_prefix(&sha, dh_shared_encoded, sizeof(dh_shared_encoded)); + update_with_length_prefix(&sha, ctx->password_hash, + sizeof(ctx->password_hash)); + + uint8_t key[SHA512_DIGEST_LENGTH]; + SHA512_Final(key, &sha); + + size_t to_copy = max_out_key_len; + if (to_copy > sizeof(key)) { + to_copy = sizeof(key); + } + OPENSSL_memcpy(out_key, key, to_copy); + *out_key_len = to_copy; + ctx->state = spake2_state_key_generated; + + return 1; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/curve25519/spake25519.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/curve25519/spake25519.c.grpc_back new file mode 100644 index 0000000..e0ff9ba --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/curve25519/spake25519.c.grpc_back @@ -0,0 +1,539 @@ +/* Copyright (c) 2016, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include +#include + +#include +#include +#include +#include + +#include "../internal.h" +#include "../../third_party/fiat/internal.h" + + +// The following precomputation tables are for the following +// points used in the SPAKE2 protocol. +// +// N: +// x: 49918732221787544735331783592030787422991506689877079631459872391322455579424 +// y: 54629554431565467720832445949441049581317094546788069926228343916274969994000 +// encoded: 10e3df0ae37d8e7a99b5fe74b44672103dbddcbd06af680d71329a11693bc778 +// +// M: +// x: 31406539342727633121250288103050113562375374900226415211311216773867585644232 +// y: 21177308356423958466833845032658859666296341766942662650232962324899758529114 +// encoded: 5ada7e4bf6ddd9adb6626d32131c6b5c51a1e347a3478f53cfcf441b88eed12e +// +// These points and their precomputation tables are generated with the +// following Python code. For a description of the precomputation table, +// see curve25519.c in this directory. +// +// Exact copies of the source code are kept in bug 27296743. + +/* +import hashlib +import ed25519 as E # http://ed25519.cr.yp.to/python/ed25519.py + +SEED_N = 'edwards25519 point generation seed (N)' +SEED_M = 'edwards25519 point generation seed (M)' + +def genpoint(seed): + v = hashlib.sha256(seed).digest() + it = 1 + while True: + try: + x,y = E.decodepoint(v) + except Exception, e: + print e + it += 1 + v = hashlib.sha256(v).digest() + continue + print "Found in %d iterations:" % it + print " x = %d" % x + print " y = %d" % y + print " Encoded (hex)" + print E.encodepoint((x,y)).encode('hex') + return (x,y) + +def gentable(P): + t = [] + for i in range(1,16): + k = ((i >> 3 & 1) * (1 << 192) + + (i >> 2 & 1) * (1 << 128) + + (i >> 1 & 1) * (1 << 64) + + (i & 1)) + t.append(E.scalarmult(P, k)) + return ''.join(E.encodeint(x) + E.encodeint(y) for (x,y) in t) + +def printtable(table, name): + print "static const uint8_t %s[15 * 2 * 32] = {" % name, + for i in range(15 * 2 * 32): + if i % 12 == 0: + print "\n ", + print " 0x%02x," % ord(table[i]), + print "\n};" + +if __name__ == "__main__": + print "Searching for N" + N = genpoint(SEED_N) + print "Generating precomputation table for N" + Ntable = gentable(N) + printtable(Ntable, "kSpakeNSmallPrecomp") + + print "Searching for M" + M = genpoint(SEED_M) + print "Generating precomputation table for M" + Mtable = gentable(M) + printtable(Mtable, "kSpakeMSmallPrecomp") +*/ + +static const uint8_t kSpakeNSmallPrecomp[15 * 2 * 32] = { + 0x20, 0x1b, 0xc5, 0xb3, 0x43, 0x17, 0x71, 0x10, 0x44, 0x1e, 0x73, 0xb3, + 0xae, 0x3f, 0xbf, 0x9f, 0xf5, 0x44, 0xc8, 0x13, 0x8f, 0xd1, 0x01, 0xc2, + 0x8a, 0x1a, 0x6d, 0xea, 0x4d, 0x00, 0x5d, 0x6e, 0x10, 0xe3, 0xdf, 0x0a, + 0xe3, 0x7d, 0x8e, 0x7a, 0x99, 0xb5, 0xfe, 0x74, 0xb4, 0x46, 0x72, 0x10, + 0x3d, 0xbd, 0xdc, 0xbd, 0x06, 0xaf, 0x68, 0x0d, 0x71, 0x32, 0x9a, 0x11, + 0x69, 0x3b, 0xc7, 0x78, 0x93, 0xf1, 0x57, 0x97, 0x6e, 0xf0, 0x6e, 0x45, + 0x37, 0x4a, 0xf4, 0x0b, 0x18, 0x51, 0xf5, 0x4f, 0x67, 0x3c, 0xdc, 0xec, + 0x84, 0xed, 0xd0, 0xeb, 0xca, 0xfb, 0xdb, 0xff, 0x7f, 0xeb, 0xa8, 0x23, + 0x68, 0x87, 0x13, 0x64, 0x6a, 0x10, 0xf7, 0x45, 0xe0, 0x0f, 0x32, 0x21, + 0x59, 0x7c, 0x0e, 0x50, 0xad, 0x56, 0xd7, 0x12, 0x69, 0x7b, 0x58, 0xf8, + 0xb9, 0x3b, 0xa5, 0xbb, 0x4d, 0x1b, 0x87, 0x1c, 0x46, 0xa7, 0x17, 0x9d, + 0x6d, 0x84, 0x45, 0xbe, 0x7f, 0x95, 0xd2, 0x34, 0xcd, 0x89, 0x95, 0xc0, + 0xf0, 0xd3, 0xdf, 0x6e, 0x10, 0x4a, 0xe3, 0x7b, 0xce, 0x7f, 0x40, 0x27, + 0xc7, 0x2b, 0xab, 0x66, 0x03, 0x59, 0xb4, 0x7b, 0xc7, 0xc7, 0xf0, 0x39, + 0x9a, 0x33, 0x35, 0xbf, 0xcc, 0x2f, 0xf3, 0x2e, 0x68, 0x9d, 0x53, 0x5c, + 0x88, 0x52, 0xe3, 0x77, 0x90, 0xa1, 0x27, 0x85, 0xc5, 0x74, 0x7f, 0x23, + 0x0e, 0x93, 0x01, 0x3e, 0xe7, 0x2e, 0x2e, 0x95, 0xf3, 0x0d, 0xc2, 0x25, + 0x25, 0x39, 0x39, 0x3d, 0x6e, 0x8e, 0x89, 0xbd, 0xe8, 0xbb, 0x67, 0x5e, + 0x8c, 0x66, 0x8b, 0x63, 0x28, 0x1e, 0x4e, 0x74, 0x85, 0xa8, 0xaf, 0x0f, + 0x12, 0x5d, 0xb6, 0x8a, 0x83, 0x1a, 0x77, 0x76, 0x5e, 0x62, 0x8a, 0xa7, + 0x3c, 0xb8, 0x05, 0x57, 0x2b, 0xaf, 0x36, 0x2e, 0x10, 0x90, 0xb2, 0x39, + 0xb4, 0x3e, 0x75, 0x6d, 0x3a, 0xa8, 0x31, 0x35, 0xc2, 0x1e, 0x8f, 0xc2, + 0x79, 0x89, 0x35, 0x16, 0x26, 0xd1, 0xc7, 0x0b, 0x04, 0x1f, 0x1d, 0xf9, + 0x9c, 0x05, 0xa6, 0x6b, 0xb5, 0x19, 0x5a, 0x24, 0x6d, 0x91, 0xc5, 0x31, + 0xfd, 0xc5, 0xfa, 0xe7, 0xa6, 0xcb, 0x0e, 0x4b, 0x18, 0x0d, 0x94, 0xc7, + 0xee, 0x1d, 0x46, 0x1f, 0x92, 0xb1, 0xb2, 0x4a, 0x2b, 0x43, 0x37, 0xfe, + 0xc2, 0x15, 0x11, 0x89, 0xef, 0x59, 0x73, 0x3c, 0x06, 0x76, 0x78, 0xcb, + 0xa6, 0x0d, 0x79, 0x5f, 0x28, 0x0b, 0x5b, 0x8c, 0x9e, 0xe4, 0xaa, 0x51, + 0x9a, 0x42, 0x6f, 0x11, 0x50, 0x3d, 0x01, 0xd6, 0x21, 0xc0, 0x99, 0x5e, + 0x1a, 0xe8, 0x81, 0x25, 0x80, 0xeb, 0xed, 0x5d, 0x37, 0x47, 0x30, 0x70, + 0xa0, 0x4e, 0x0b, 0x43, 0x17, 0xbe, 0xb6, 0x47, 0xe7, 0x2a, 0x62, 0x9d, + 0x5d, 0xa6, 0xc5, 0x33, 0x62, 0x9d, 0x56, 0x24, 0x9d, 0x1d, 0xb2, 0x13, + 0xbc, 0x17, 0x66, 0x43, 0xd1, 0x68, 0xd5, 0x3b, 0x17, 0x69, 0x17, 0xa6, + 0x06, 0x9e, 0x12, 0xb8, 0x7c, 0xd5, 0xaf, 0x3e, 0x21, 0x1b, 0x31, 0xeb, + 0x0b, 0xa4, 0x98, 0x1c, 0xf2, 0x6a, 0x5e, 0x7c, 0x9b, 0x45, 0x8f, 0xb2, + 0x12, 0x06, 0xd5, 0x8c, 0x1d, 0xb2, 0xa7, 0x57, 0x5f, 0x2f, 0x4f, 0xdb, + 0x52, 0x99, 0x7c, 0x58, 0x01, 0x5f, 0xf2, 0xa5, 0xf6, 0x51, 0x86, 0x21, + 0x2f, 0x5b, 0x8d, 0x6a, 0xae, 0x83, 0x34, 0x6d, 0x58, 0x4b, 0xef, 0xfe, + 0xbf, 0x73, 0x5d, 0xdb, 0xc4, 0x97, 0x2a, 0x85, 0xf3, 0x6c, 0x46, 0x42, + 0xb3, 0x90, 0xc1, 0x57, 0x97, 0x50, 0x35, 0xb1, 0x9d, 0xb7, 0xc7, 0x3c, + 0x85, 0x6d, 0x6c, 0xfd, 0xce, 0xb0, 0xc9, 0xa2, 0x77, 0xee, 0xc3, 0x6b, + 0x0c, 0x37, 0xfa, 0x30, 0x91, 0xd1, 0x2c, 0xb8, 0x5e, 0x7f, 0x81, 0x5f, + 0x87, 0xfd, 0x18, 0x02, 0x5a, 0x30, 0x4e, 0x62, 0xbc, 0x65, 0xc6, 0xce, + 0x1a, 0xcf, 0x2b, 0xaa, 0x56, 0x3e, 0x4d, 0xcf, 0xba, 0x62, 0x5f, 0x9a, + 0xd0, 0x72, 0xff, 0xef, 0x28, 0xbd, 0xbe, 0xd8, 0x57, 0x3d, 0xf5, 0x57, + 0x7d, 0xe9, 0x71, 0x31, 0xec, 0x98, 0x90, 0x94, 0xd9, 0x54, 0xbf, 0x84, + 0x0b, 0xe3, 0x06, 0x47, 0x19, 0x9a, 0x13, 0x1d, 0xef, 0x9d, 0x13, 0xf3, + 0xdb, 0xc3, 0x5c, 0x72, 0x9e, 0xed, 0x24, 0xaa, 0x64, 0xed, 0xe7, 0x0d, + 0xa0, 0x7c, 0x73, 0xba, 0x9b, 0x86, 0xa7, 0x3b, 0x55, 0xab, 0x58, 0x30, + 0xf1, 0x15, 0x81, 0x83, 0x2f, 0xf9, 0x62, 0x84, 0x98, 0x66, 0xf6, 0x55, + 0x21, 0xd8, 0xf2, 0x25, 0x64, 0x71, 0x4b, 0x12, 0x76, 0x59, 0xc5, 0xaa, + 0x93, 0x67, 0xc3, 0x86, 0x25, 0xab, 0x4e, 0x4b, 0xf6, 0xd8, 0x3f, 0x44, + 0x2e, 0x11, 0xe0, 0xbd, 0x6a, 0xf2, 0x5d, 0xf5, 0xf9, 0x53, 0xea, 0xa4, + 0xc8, 0xd9, 0x50, 0x33, 0x81, 0xd9, 0xa8, 0x2d, 0x91, 0x7d, 0x13, 0x2a, + 0x11, 0xcf, 0xde, 0x3f, 0x0a, 0xd2, 0xbc, 0x33, 0xb2, 0x62, 0x53, 0xea, + 0x77, 0x88, 0x43, 0x66, 0x27, 0x43, 0x85, 0xe9, 0x5f, 0x55, 0xf5, 0x2a, + 0x8a, 0xac, 0xdf, 0xff, 0x9b, 0x4c, 0x96, 0x9c, 0xa5, 0x7a, 0xce, 0xd5, + 0x79, 0x18, 0xf1, 0x0b, 0x58, 0x95, 0x7a, 0xe7, 0xd3, 0x74, 0x65, 0x0b, + 0xa4, 0x64, 0x30, 0xe8, 0x5c, 0xfc, 0x55, 0x56, 0xee, 0x14, 0x14, 0xd3, + 0x45, 0x3b, 0xf8, 0xde, 0x05, 0x3e, 0xb9, 0x3c, 0xd7, 0x6a, 0x52, 0x72, + 0x5b, 0x39, 0x09, 0xbe, 0x82, 0x23, 0x10, 0x4a, 0xb7, 0xc3, 0xdc, 0x4c, + 0x5d, 0xc9, 0xf1, 0x14, 0x83, 0xf9, 0x0b, 0x9b, 0xe9, 0x23, 0x84, 0x6a, + 0xc4, 0x08, 0x3d, 0xda, 0x3d, 0x12, 0x95, 0x87, 0x18, 0xa4, 0x7d, 0x3f, + 0x23, 0xde, 0xd4, 0x1e, 0xa8, 0x47, 0xc3, 0x71, 0xdb, 0xf5, 0x03, 0x6c, + 0x57, 0xe7, 0xa4, 0x43, 0x82, 0x33, 0x7b, 0x62, 0x46, 0x7d, 0xf7, 0x10, + 0x69, 0x18, 0x38, 0x27, 0x9a, 0x6f, 0x38, 0xac, 0xfa, 0x92, 0xc5, 0xae, + 0x66, 0xa6, 0x73, 0x95, 0x15, 0x0e, 0x4c, 0x04, 0xb6, 0xfc, 0xf5, 0xc7, + 0x21, 0x3a, 0x99, 0xdb, 0x0e, 0x36, 0xf0, 0x56, 0xbc, 0x75, 0xf9, 0x87, + 0x9b, 0x11, 0x18, 0x92, 0x64, 0x1a, 0xe7, 0xc7, 0xab, 0x5a, 0xc7, 0x26, + 0x7f, 0x13, 0x98, 0x42, 0x52, 0x43, 0xdb, 0xc8, 0x6d, 0x0b, 0xb7, 0x31, + 0x93, 0x24, 0xd6, 0xe8, 0x24, 0x1f, 0x6f, 0x21, 0xa7, 0x8c, 0xeb, 0xdb, + 0x83, 0xb8, 0x89, 0xe3, 0xc1, 0xd7, 0x69, 0x3b, 0x02, 0x6b, 0x54, 0x0f, + 0x84, 0x2f, 0xb5, 0x5c, 0x17, 0x77, 0xbe, 0xe5, 0x61, 0x0d, 0xc5, 0xdf, + 0x3b, 0xcf, 0x3e, 0x93, 0x4f, 0xf5, 0x89, 0xb9, 0x5a, 0xc5, 0x29, 0x31, + 0xc0, 0xc2, 0xff, 0xe5, 0x3f, 0xa6, 0xac, 0x03, 0xca, 0xf5, 0xff, 0xe0, + 0x36, 0xce, 0xf3, 0xe2, 0xb7, 0x9c, 0x02, 0xe9, 0x9e, 0xd2, 0xbc, 0x87, + 0x2f, 0x3d, 0x9a, 0x1d, 0x8f, 0xc5, 0x72, 0xb8, 0xa2, 0x01, 0xd4, 0x68, + 0xb1, 0x84, 0x16, 0x10, 0xf6, 0xf3, 0x52, 0x25, 0xd9, 0xdc, 0x4c, 0xdd, + 0x0f, 0xd6, 0x4a, 0xcf, 0x60, 0x96, 0x7e, 0xcc, 0x42, 0x0f, 0x64, 0x9d, + 0x72, 0x46, 0x04, 0x07, 0xf2, 0x5b, 0xf4, 0x07, 0xd1, 0xf4, 0x59, 0x71, +}; + +static const uint8_t kSpakeMSmallPrecomp[15 * 2 * 32] = { + 0xc8, 0xa6, 0x63, 0xc5, 0x97, 0xf1, 0xee, 0x40, 0xab, 0x62, 0x42, 0xee, + 0x25, 0x6f, 0x32, 0x6c, 0x75, 0x2c, 0xa7, 0xd3, 0xbd, 0x32, 0x3b, 0x1e, + 0x11, 0x9c, 0xbd, 0x04, 0xa9, 0x78, 0x6f, 0x45, 0x5a, 0xda, 0x7e, 0x4b, + 0xf6, 0xdd, 0xd9, 0xad, 0xb6, 0x62, 0x6d, 0x32, 0x13, 0x1c, 0x6b, 0x5c, + 0x51, 0xa1, 0xe3, 0x47, 0xa3, 0x47, 0x8f, 0x53, 0xcf, 0xcf, 0x44, 0x1b, + 0x88, 0xee, 0xd1, 0x2e, 0x03, 0x89, 0xaf, 0xc0, 0x61, 0x2d, 0x9e, 0x35, + 0xeb, 0x0e, 0x03, 0xe0, 0xb7, 0xfb, 0xa5, 0xbc, 0x44, 0xbe, 0x0c, 0x89, + 0x0a, 0x0f, 0xd6, 0x59, 0x47, 0x9e, 0xe6, 0x3d, 0x36, 0x9d, 0xff, 0x44, + 0x5e, 0xac, 0xab, 0xe5, 0x3a, 0xd5, 0xb0, 0x35, 0x9f, 0x6d, 0x7f, 0xba, + 0xc0, 0x85, 0x0e, 0xf4, 0x70, 0x3f, 0x13, 0x90, 0x4c, 0x50, 0x1a, 0xee, + 0xc5, 0xeb, 0x69, 0xfe, 0x98, 0x42, 0x87, 0x1d, 0xce, 0x6c, 0x29, 0xaa, + 0x2b, 0x31, 0xc2, 0x38, 0x7b, 0x6b, 0xee, 0x88, 0x0b, 0xba, 0xce, 0xa8, + 0xca, 0x19, 0x60, 0x1b, 0x16, 0xf1, 0x25, 0x1e, 0xcf, 0x63, 0x66, 0x1e, + 0xbb, 0x63, 0xeb, 0x7d, 0xca, 0xd2, 0xb4, 0x23, 0x5a, 0x01, 0x6f, 0x05, + 0xd1, 0xdc, 0x41, 0x73, 0x75, 0xc0, 0xfd, 0x30, 0x91, 0x52, 0x68, 0x96, + 0x45, 0xb3, 0x66, 0x01, 0x3b, 0x53, 0x89, 0x3c, 0x69, 0xbc, 0x6c, 0x69, + 0xe3, 0x51, 0x8f, 0xe3, 0xd2, 0x84, 0xd5, 0x28, 0x66, 0xb5, 0xe6, 0x06, + 0x09, 0xfe, 0x6d, 0xb0, 0x72, 0x16, 0xe0, 0x8a, 0xce, 0x61, 0x65, 0xa9, + 0x21, 0x32, 0x48, 0xdc, 0x7a, 0x1d, 0xe1, 0x38, 0x7f, 0x8c, 0x75, 0x88, + 0x3d, 0x08, 0xa9, 0x4a, 0x6f, 0x3d, 0x9f, 0x7f, 0x3f, 0xbd, 0x57, 0x6b, + 0x19, 0xce, 0x3f, 0x4a, 0xc9, 0xd3, 0xf9, 0x6e, 0x72, 0x7b, 0x5b, 0x74, + 0xea, 0xbe, 0x9c, 0x7a, 0x6d, 0x9c, 0x40, 0x49, 0xe6, 0xfb, 0x2a, 0x1a, + 0x75, 0x70, 0xe5, 0x4e, 0xed, 0x74, 0xe0, 0x75, 0xac, 0xc0, 0xb1, 0x11, + 0x3e, 0xf2, 0xaf, 0x88, 0x4d, 0x66, 0xb6, 0xf6, 0x15, 0x4f, 0x3c, 0x6c, + 0x77, 0xae, 0x47, 0x51, 0x63, 0x9a, 0xfe, 0xe1, 0xb4, 0x1a, 0x12, 0xdf, + 0xe9, 0x54, 0x8d, 0x3b, 0x30, 0x2a, 0x75, 0xe3, 0xe5, 0x29, 0xb1, 0x4c, + 0xb0, 0x7c, 0x6d, 0xb5, 0xae, 0x85, 0xdb, 0x1e, 0x38, 0x55, 0x96, 0xa5, + 0x5b, 0x9f, 0x15, 0x23, 0x28, 0x36, 0xb8, 0xa2, 0x41, 0xb4, 0xd7, 0x19, + 0x91, 0x8d, 0x26, 0x3e, 0xca, 0x9c, 0x05, 0x7a, 0x2b, 0x60, 0x45, 0x86, + 0x8b, 0xee, 0x64, 0x6f, 0x5c, 0x09, 0x4d, 0x4b, 0x5a, 0x7f, 0xb0, 0xc3, + 0x26, 0x9d, 0x8b, 0xb8, 0x83, 0x69, 0xcf, 0x16, 0x72, 0x62, 0x3e, 0x5e, + 0x53, 0x4f, 0x9c, 0x73, 0x76, 0xfc, 0x19, 0xef, 0xa0, 0x74, 0x3a, 0x11, + 0x1e, 0xd0, 0x4d, 0xb7, 0x87, 0xa1, 0xd6, 0x87, 0x6c, 0x0e, 0x6c, 0x8c, + 0xe9, 0xa0, 0x44, 0xc4, 0x72, 0x3e, 0x73, 0x17, 0x13, 0xd1, 0x4e, 0x3d, + 0x8e, 0x1d, 0x5a, 0x8b, 0x75, 0xcb, 0x59, 0x2c, 0x47, 0x87, 0x15, 0x41, + 0xfe, 0x08, 0xe9, 0xa6, 0x97, 0x17, 0x08, 0x26, 0x6a, 0xb5, 0xbb, 0x73, + 0xaa, 0xb8, 0x5b, 0x65, 0x65, 0x5b, 0x30, 0x9e, 0x62, 0x59, 0x02, 0xf8, + 0xb8, 0x0f, 0x32, 0x10, 0xc1, 0x36, 0x08, 0x52, 0x98, 0x4a, 0x1e, 0xf0, + 0xab, 0x21, 0x5e, 0xde, 0x16, 0x0c, 0xda, 0x09, 0x99, 0x6b, 0x9e, 0xc0, + 0x90, 0xa5, 0x5a, 0xcc, 0xb0, 0xb7, 0xbb, 0xd2, 0x8b, 0x5f, 0xd3, 0x3b, + 0x3e, 0x8c, 0xa5, 0x71, 0x66, 0x06, 0xe3, 0x28, 0xd4, 0xf8, 0x3f, 0xe5, + 0x27, 0xdf, 0xfe, 0x0f, 0x09, 0xb2, 0x8a, 0x09, 0x5a, 0x23, 0x61, 0x0d, + 0x2d, 0xf5, 0x44, 0xf1, 0x5c, 0xf8, 0x82, 0x4e, 0xdc, 0x78, 0x7a, 0xab, + 0xc3, 0x57, 0x91, 0xaf, 0x65, 0x6e, 0x71, 0xf1, 0x44, 0xbf, 0xed, 0x43, + 0x50, 0xb4, 0x67, 0x48, 0xef, 0x5a, 0x10, 0x46, 0x81, 0xb4, 0x0c, 0xc8, + 0x48, 0xed, 0x99, 0x7a, 0x45, 0xa5, 0x92, 0xc3, 0x69, 0xd6, 0xd7, 0x8a, + 0x20, 0x1b, 0xeb, 0x8f, 0xb2, 0xff, 0xec, 0x6d, 0x76, 0x04, 0xf8, 0xc2, + 0x58, 0x9b, 0xf2, 0x20, 0x53, 0xc4, 0x74, 0x91, 0x19, 0xdd, 0x2d, 0x12, + 0x53, 0xc7, 0x6e, 0xd0, 0x02, 0x51, 0x3c, 0xa6, 0x7d, 0x80, 0x75, 0x6b, + 0x1d, 0xdf, 0xf8, 0x6a, 0x52, 0xbb, 0x81, 0xf8, 0x30, 0x45, 0xef, 0x51, + 0x85, 0x36, 0xbe, 0x8e, 0xcf, 0x0b, 0x9a, 0x46, 0xe8, 0x3f, 0x99, 0xfd, + 0xf7, 0xd9, 0x3e, 0x84, 0xe5, 0xe3, 0x37, 0xcf, 0x98, 0x7f, 0xeb, 0x5e, + 0x5a, 0x53, 0x77, 0x1c, 0x20, 0xdc, 0xf1, 0x20, 0x99, 0xec, 0x60, 0x40, + 0x93, 0xef, 0x5c, 0x1c, 0x81, 0xe2, 0xa5, 0xad, 0x2a, 0xc2, 0xdb, 0x6b, + 0xc1, 0x7e, 0x8f, 0xa9, 0x23, 0x5b, 0xd9, 0x0d, 0xfe, 0xa0, 0xac, 0x11, + 0x28, 0xba, 0x8e, 0x92, 0x07, 0x2d, 0x07, 0x40, 0x83, 0x14, 0x4c, 0x35, + 0x8d, 0xd0, 0x11, 0xff, 0x98, 0xdb, 0x00, 0x30, 0x6f, 0x65, 0xb6, 0xa0, + 0x7f, 0x9c, 0x08, 0xb8, 0xce, 0xb3, 0xa8, 0x42, 0xd3, 0x84, 0x45, 0xe1, + 0xe3, 0x8f, 0xa6, 0x89, 0x21, 0xd7, 0x74, 0x02, 0x4d, 0x64, 0xdf, 0x54, + 0x15, 0x9e, 0xba, 0x12, 0x49, 0x09, 0x41, 0xf6, 0x10, 0x24, 0xa1, 0x84, + 0x15, 0xfd, 0x68, 0x6a, 0x57, 0x66, 0xb3, 0x6d, 0x4c, 0xea, 0xbf, 0xbc, + 0x60, 0x3f, 0x52, 0x1c, 0x44, 0x1b, 0xc0, 0x4a, 0x25, 0xe3, 0xd9, 0x4c, + 0x9a, 0x74, 0xad, 0xfc, 0x9e, 0x8d, 0x0b, 0x18, 0x66, 0x24, 0xd1, 0x06, + 0xac, 0x68, 0xc1, 0xae, 0x14, 0xce, 0xb1, 0xf3, 0x86, 0x9f, 0x87, 0x11, + 0xd7, 0x9f, 0x30, 0x92, 0xdb, 0xec, 0x0b, 0x4a, 0xe8, 0xf6, 0x53, 0x36, + 0x68, 0x12, 0x11, 0x5e, 0xe0, 0x34, 0xa4, 0xff, 0x00, 0x0a, 0x26, 0xb8, + 0x62, 0x79, 0x9c, 0x0c, 0xd5, 0xe5, 0xf5, 0x1c, 0x1a, 0x16, 0x84, 0x4d, + 0x8e, 0x5d, 0x31, 0x7e, 0xf7, 0xe2, 0xd3, 0xa1, 0x41, 0x90, 0x61, 0x5d, + 0x04, 0xb2, 0x9a, 0x18, 0x9e, 0x54, 0xfb, 0xd1, 0x61, 0x95, 0x1b, 0x08, + 0xca, 0x7c, 0x49, 0x44, 0x74, 0x1d, 0x2f, 0xca, 0xc4, 0x7a, 0xe1, 0x8b, + 0x2f, 0xbb, 0x96, 0xee, 0x19, 0x8a, 0x5d, 0xfb, 0x3e, 0x82, 0xe7, 0x15, + 0xdb, 0x29, 0x14, 0xee, 0xc9, 0x4d, 0x9a, 0xfb, 0x9f, 0x8a, 0xbb, 0x17, + 0x37, 0x1b, 0x6e, 0x28, 0x6c, 0xf9, 0xff, 0xb5, 0xb5, 0x8b, 0x9d, 0x88, + 0x20, 0x08, 0x10, 0xd7, 0xca, 0x58, 0xf6, 0xe1, 0x32, 0x91, 0x6f, 0x36, + 0xc0, 0xad, 0xc1, 0x57, 0x5d, 0x76, 0x31, 0x43, 0xf3, 0xdd, 0xec, 0xf1, + 0xa9, 0x79, 0xe9, 0xe9, 0x85, 0xd7, 0x91, 0xc7, 0x31, 0x62, 0x3c, 0xd2, + 0x90, 0x2c, 0x9c, 0xa4, 0x56, 0x37, 0x7b, 0xbe, 0x40, 0x58, 0xc0, 0x81, + 0x83, 0x22, 0xe8, 0x13, 0x79, 0x18, 0xdb, 0x3a, 0x1b, 0x31, 0x0d, 0x00, + 0x6c, 0x22, 0x62, 0x75, 0x70, 0xd8, 0x96, 0x59, 0x99, 0x44, 0x79, 0x71, + 0xa6, 0x76, 0x81, 0x28, 0xb2, 0x65, 0xe8, 0x47, 0x14, 0xc6, 0x39, 0x06, +}; + +SPAKE2_CTX *SPAKE2_CTX_new(enum spake2_role_t my_role, + const uint8_t *my_name, size_t my_name_len, + const uint8_t *their_name, size_t their_name_len) { + SPAKE2_CTX *ctx = OPENSSL_malloc(sizeof(SPAKE2_CTX)); + if (ctx == NULL) { + return NULL; + } + + OPENSSL_memset(ctx, 0, sizeof(SPAKE2_CTX)); + ctx->my_role = my_role; + + CBS my_name_cbs, their_name_cbs; + CBS_init(&my_name_cbs, my_name, my_name_len); + CBS_init(&their_name_cbs, their_name, their_name_len); + if (!CBS_stow(&my_name_cbs, &ctx->my_name, &ctx->my_name_len) || + !CBS_stow(&their_name_cbs, &ctx->their_name, &ctx->their_name_len)) { + SPAKE2_CTX_free(ctx); + return NULL; + } + + return ctx; +} + +void SPAKE2_CTX_free(SPAKE2_CTX *ctx) { + if (ctx == NULL) { + return; + } + + OPENSSL_free(ctx->my_name); + OPENSSL_free(ctx->their_name); + OPENSSL_free(ctx); +} + +// left_shift_3 sets |n| to |n|*8, where |n| is represented in little-endian +// order. +static void left_shift_3(uint8_t n[32]) { + uint8_t carry = 0; + unsigned i; + + for (i = 0; i < 32; i++) { + const uint8_t next_carry = n[i] >> 5; + n[i] = (n[i] << 3) | carry; + carry = next_carry; + } +} + +typedef union { + uint8_t bytes[32]; + uint32_t words[8]; +} scalar; + +// kOrder is the order of the prime-order subgroup of curve25519 in +// little-endian order. +static const scalar kOrder = {{0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, + 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10}}; + +// scalar_cmov copies |src| to |dest| if |mask| is all ones. +static void scalar_cmov(scalar *dest, const scalar *src, crypto_word_t mask) { + for (size_t i = 0; i < 8; i++) { + dest->words[i] = + constant_time_select_w(mask, src->words[i], dest->words[i]); + } +} + +// scalar_double sets |s| to |2×s|. +static void scalar_double(scalar *s) { + uint32_t carry = 0; + + for (size_t i = 0; i < 8; i++) { + const uint32_t carry_out = s->words[i] >> 31; + s->words[i] = (s->words[i] << 1) | carry; + carry = carry_out; + } +} + +// scalar_add sets |dest| to |dest| plus |src|. +static void scalar_add(scalar *dest, const scalar *src) { + uint32_t carry = 0; + + for (size_t i = 0; i < 8; i++) { + uint64_t tmp = ((uint64_t)dest->words[i] + src->words[i]) + carry; + dest->words[i] = (uint32_t)tmp; + carry = (uint32_t)(tmp >> 32); + } +} + +int SPAKE2_generate_msg(SPAKE2_CTX *ctx, uint8_t *out, size_t *out_len, + size_t max_out_len, const uint8_t *password, + size_t password_len) { + if (ctx->state != spake2_state_init) { + return 0; + } + + if (max_out_len < sizeof(ctx->my_msg)) { + return 0; + } + + uint8_t private_tmp[64]; + RAND_bytes(private_tmp, sizeof(private_tmp)); + x25519_sc_reduce(private_tmp); + // Multiply by the cofactor (eight) so that we'll clear it when operating on + // the peer's point later in the protocol. + left_shift_3(private_tmp); + OPENSSL_memcpy(ctx->private_key, private_tmp, sizeof(ctx->private_key)); + + ge_p3 P; + x25519_ge_scalarmult_base(&P, ctx->private_key); + + // mask = h(password) * . + uint8_t password_tmp[SHA512_DIGEST_LENGTH]; + SHA512(password, password_len, password_tmp); + OPENSSL_memcpy(ctx->password_hash, password_tmp, sizeof(ctx->password_hash)); + x25519_sc_reduce(password_tmp); + + // Due to a copy-paste error, the call to |left_shift_3| was omitted after + // the |x25519_sc_reduce|, just above. This meant that |ctx->password_scalar| + // was not a multiple of eight to clear the cofactor and thus three bits of + // the password hash would leak. In order to fix this in a unilateral way, + // points of small order are added to the mask point such that it is in the + // prime-order subgroup. Since the ephemeral scalar is a multiple of eight, + // these points will cancel out when calculating the shared secret. + // + // Adding points of small order is the same as adding multiples of the prime + // order to the password scalar. Since that's faster, that is what is done + // below. The prime order (kOrder) is a large prime, thus odd, thus the LSB + // is one. So adding it will flip the LSB. Adding twice it will flip the next + // bit and so one for all the bottom three bits. + + scalar password_scalar; + OPENSSL_memcpy(&password_scalar, password_tmp, sizeof(password_scalar)); + + // |password_scalar| is the result of |x25519_sc_reduce| and thus is, at + // most, $l-1$ (where $l$ is |kOrder|, the order of the prime-order subgroup + // of Ed25519). In the following, we may add $l + 2×l + 4×l$ for a max value + // of $8×l-1$. That is < 2**256, as required. + + if (!ctx->disable_password_scalar_hack) { + scalar order = kOrder; + scalar tmp; + + OPENSSL_memset(&tmp, 0, sizeof(tmp)); + scalar_cmov(&tmp, &order, + constant_time_eq_w(password_scalar.bytes[0] & 1, 1)); + scalar_add(&password_scalar, &tmp); + + scalar_double(&order); + OPENSSL_memset(&tmp, 0, sizeof(tmp)); + scalar_cmov(&tmp, &order, + constant_time_eq_w(password_scalar.bytes[0] & 2, 2)); + scalar_add(&password_scalar, &tmp); + + scalar_double(&order); + OPENSSL_memset(&tmp, 0, sizeof(tmp)); + scalar_cmov(&tmp, &order, + constant_time_eq_w(password_scalar.bytes[0] & 4, 4)); + scalar_add(&password_scalar, &tmp); + + assert((password_scalar.bytes[0] & 7) == 0); + } + + OPENSSL_memcpy(ctx->password_scalar, password_scalar.bytes, + sizeof(ctx->password_scalar)); + + ge_p3 mask; + x25519_ge_scalarmult_small_precomp(&mask, ctx->password_scalar, + ctx->my_role == spake2_role_alice + ? kSpakeMSmallPrecomp + : kSpakeNSmallPrecomp); + + // P* = P + mask. + ge_cached mask_cached; + x25519_ge_p3_to_cached(&mask_cached, &mask); + ge_p1p1 Pstar; + x25519_ge_add(&Pstar, &P, &mask_cached); + + // Encode P* + ge_p2 Pstar_proj; + x25519_ge_p1p1_to_p2(&Pstar_proj, &Pstar); + x25519_ge_tobytes(ctx->my_msg, &Pstar_proj); + + OPENSSL_memcpy(out, ctx->my_msg, sizeof(ctx->my_msg)); + *out_len = sizeof(ctx->my_msg); + ctx->state = spake2_state_msg_generated; + + return 1; +} + +static void update_with_length_prefix(SHA512_CTX *sha, const uint8_t *data, + const size_t len) { + uint8_t len_le[8]; + size_t l = len; + unsigned i; + + for (i = 0; i < 8; i++) { + len_le[i] = l & 0xff; + l >>= 8; + } + + SHA512_Update(sha, len_le, sizeof(len_le)); + SHA512_Update(sha, data, len); +} + +int SPAKE2_process_msg(SPAKE2_CTX *ctx, uint8_t *out_key, size_t *out_key_len, + size_t max_out_key_len, const uint8_t *their_msg, + size_t their_msg_len) { + if (ctx->state != spake2_state_msg_generated || + their_msg_len != 32) { + return 0; + } + + ge_p3 Qstar; + if (0 != x25519_ge_frombytes_vartime(&Qstar, their_msg)) { + // Point received from peer was not on the curve. + return 0; + } + + // Unmask peer's value. + ge_p3 peers_mask; + x25519_ge_scalarmult_small_precomp(&peers_mask, ctx->password_scalar, + ctx->my_role == spake2_role_alice + ? kSpakeNSmallPrecomp + : kSpakeMSmallPrecomp); + + ge_cached peers_mask_cached; + x25519_ge_p3_to_cached(&peers_mask_cached, &peers_mask); + + ge_p1p1 Q_compl; + ge_p3 Q_ext; + x25519_ge_sub(&Q_compl, &Qstar, &peers_mask_cached); + x25519_ge_p1p1_to_p3(&Q_ext, &Q_compl); + + ge_p2 dh_shared; + x25519_ge_scalarmult(&dh_shared, ctx->private_key, &Q_ext); + + uint8_t dh_shared_encoded[32]; + x25519_ge_tobytes(dh_shared_encoded, &dh_shared); + + SHA512_CTX sha; + SHA512_Init(&sha); + if (ctx->my_role == spake2_role_alice) { + update_with_length_prefix(&sha, ctx->my_name, ctx->my_name_len); + update_with_length_prefix(&sha, ctx->their_name, ctx->their_name_len); + update_with_length_prefix(&sha, ctx->my_msg, sizeof(ctx->my_msg)); + update_with_length_prefix(&sha, their_msg, 32); + } else { + update_with_length_prefix(&sha, ctx->their_name, ctx->their_name_len); + update_with_length_prefix(&sha, ctx->my_name, ctx->my_name_len); + update_with_length_prefix(&sha, their_msg, 32); + update_with_length_prefix(&sha, ctx->my_msg, sizeof(ctx->my_msg)); + } + update_with_length_prefix(&sha, dh_shared_encoded, sizeof(dh_shared_encoded)); + update_with_length_prefix(&sha, ctx->password_hash, + sizeof(ctx->password_hash)); + + uint8_t key[SHA512_DIGEST_LENGTH]; + SHA512_Final(key, &sha); + + size_t to_copy = max_out_key_len; + if (to_copy > sizeof(key)) { + to_copy = sizeof(key); + } + OPENSSL_memcpy(out_key, key, to_copy); + *out_key_len = to_copy; + ctx->state = spake2_state_key_generated; + + return 1; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/dh/check.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/dh/check.c new file mode 100644 index 0000000..f5ece41 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/dh/check.c @@ -0,0 +1,217 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include + + +int DH_check_pub_key(const DH *dh, const BIGNUM *pub_key, int *out_flags) { + *out_flags = 0; + + BN_CTX *ctx = BN_CTX_new(); + if (ctx == NULL) { + return 0; + } + BN_CTX_start(ctx); + + int ok = 0; + + // Check |pub_key| is greater than 1. + BIGNUM *tmp = BN_CTX_get(ctx); + if (tmp == NULL || + !BN_set_word(tmp, 1)) { + goto err; + } + if (BN_cmp(pub_key, tmp) <= 0) { + *out_flags |= DH_CHECK_PUBKEY_TOO_SMALL; + } + + // Check |pub_key| is less than |dh->p| - 1. + if (!BN_copy(tmp, dh->p) || + !BN_sub_word(tmp, 1)) { + goto err; + } + if (BN_cmp(pub_key, tmp) >= 0) { + *out_flags |= DH_CHECK_PUBKEY_TOO_LARGE; + } + + if (dh->q != NULL) { + // Check |pub_key|^|dh->q| is 1 mod |dh->p|. This is necessary for RFC 5114 + // groups which are not safe primes but pick a generator on a prime-order + // subgroup of size |dh->q|. + if (!BN_mod_exp_mont(tmp, pub_key, dh->q, dh->p, ctx, NULL)) { + goto err; + } + if (!BN_is_one(tmp)) { + *out_flags |= DH_CHECK_PUBKEY_INVALID; + } + } + + ok = 1; + +err: + BN_CTX_end(ctx); + BN_CTX_free(ctx); + return ok; +} + + +int DH_check(const DH *dh, int *out_flags) { + // 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 ok = 0, r; + BN_CTX *ctx = NULL; + BN_ULONG l; + BIGNUM *t1 = NULL, *t2 = NULL; + + *out_flags = 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) { + *out_flags |= DH_CHECK_NOT_SUITABLE_GENERATOR; + } else if (BN_cmp(dh->g, dh->p) >= 0) { + *out_flags |= DH_CHECK_NOT_SUITABLE_GENERATOR; + } else { + // Check g^q == 1 mod p + if (!BN_mod_exp_mont(t1, dh->g, dh->q, dh->p, ctx, NULL)) { + goto err; + } + if (!BN_is_one(t1)) { + *out_flags |= DH_CHECK_NOT_SUITABLE_GENERATOR; + } + } + r = BN_is_prime_ex(dh->q, BN_prime_checks, ctx, NULL); + if (r < 0) { + goto err; + } + if (!r) { + *out_flags |= 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)) { + *out_flags |= DH_CHECK_INVALID_Q_VALUE; + } + if (dh->j && BN_cmp(dh->j, t1)) { + *out_flags |= DH_CHECK_INVALID_J_VALUE; + } + } else if (BN_is_word(dh->g, DH_GENERATOR_2)) { + l = BN_mod_word(dh->p, 24); + if (l == (BN_ULONG)-1) { + goto err; + } + if (l != 11) { + *out_flags |= DH_CHECK_NOT_SUITABLE_GENERATOR; + } + } else if (BN_is_word(dh->g, DH_GENERATOR_5)) { + l = BN_mod_word(dh->p, 10); + if (l == (BN_ULONG)-1) { + goto err; + } + if (l != 3 && l != 7) { + *out_flags |= DH_CHECK_NOT_SUITABLE_GENERATOR; + } + } else { + *out_flags |= DH_CHECK_UNABLE_TO_CHECK_GENERATOR; + } + + r = BN_is_prime_ex(dh->p, BN_prime_checks, ctx, NULL); + if (r < 0) { + goto err; + } + if (!r) { + *out_flags |= DH_CHECK_P_NOT_PRIME; + } else if (!dh->q) { + if (!BN_rshift1(t1, dh->p)) { + goto err; + } + r = BN_is_prime_ex(t1, BN_prime_checks, ctx, NULL); + if (r < 0) { + goto err; + } + if (!r) { + *out_flags |= DH_CHECK_P_NOT_SAFE_PRIME; + } + } + ok = 1; + +err: + if (ctx != NULL) { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + return ok; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/dh/check.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/dh/check.c.grpc_back new file mode 100644 index 0000000..454ad44 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/dh/check.c.grpc_back @@ -0,0 +1,217 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include + + +int DH_check_pub_key(const DH *dh, const BIGNUM *pub_key, int *out_flags) { + *out_flags = 0; + + BN_CTX *ctx = BN_CTX_new(); + if (ctx == NULL) { + return 0; + } + BN_CTX_start(ctx); + + int ok = 0; + + // Check |pub_key| is greater than 1. + BIGNUM *tmp = BN_CTX_get(ctx); + if (tmp == NULL || + !BN_set_word(tmp, 1)) { + goto err; + } + if (BN_cmp(pub_key, tmp) <= 0) { + *out_flags |= DH_CHECK_PUBKEY_TOO_SMALL; + } + + // Check |pub_key| is less than |dh->p| - 1. + if (!BN_copy(tmp, dh->p) || + !BN_sub_word(tmp, 1)) { + goto err; + } + if (BN_cmp(pub_key, tmp) >= 0) { + *out_flags |= DH_CHECK_PUBKEY_TOO_LARGE; + } + + if (dh->q != NULL) { + // Check |pub_key|^|dh->q| is 1 mod |dh->p|. This is necessary for RFC 5114 + // groups which are not safe primes but pick a generator on a prime-order + // subgroup of size |dh->q|. + if (!BN_mod_exp_mont(tmp, pub_key, dh->q, dh->p, ctx, NULL)) { + goto err; + } + if (!BN_is_one(tmp)) { + *out_flags |= DH_CHECK_PUBKEY_INVALID; + } + } + + ok = 1; + +err: + BN_CTX_end(ctx); + BN_CTX_free(ctx); + return ok; +} + + +int DH_check(const DH *dh, int *out_flags) { + // 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 ok = 0, r; + BN_CTX *ctx = NULL; + BN_ULONG l; + BIGNUM *t1 = NULL, *t2 = NULL; + + *out_flags = 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) { + *out_flags |= DH_CHECK_NOT_SUITABLE_GENERATOR; + } else if (BN_cmp(dh->g, dh->p) >= 0) { + *out_flags |= DH_CHECK_NOT_SUITABLE_GENERATOR; + } else { + // Check g^q == 1 mod p + if (!BN_mod_exp_mont(t1, dh->g, dh->q, dh->p, ctx, NULL)) { + goto err; + } + if (!BN_is_one(t1)) { + *out_flags |= DH_CHECK_NOT_SUITABLE_GENERATOR; + } + } + r = BN_is_prime_ex(dh->q, BN_prime_checks, ctx, NULL); + if (r < 0) { + goto err; + } + if (!r) { + *out_flags |= 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)) { + *out_flags |= DH_CHECK_INVALID_Q_VALUE; + } + if (dh->j && BN_cmp(dh->j, t1)) { + *out_flags |= DH_CHECK_INVALID_J_VALUE; + } + } else if (BN_is_word(dh->g, DH_GENERATOR_2)) { + l = BN_mod_word(dh->p, 24); + if (l == (BN_ULONG)-1) { + goto err; + } + if (l != 11) { + *out_flags |= DH_CHECK_NOT_SUITABLE_GENERATOR; + } + } else if (BN_is_word(dh->g, DH_GENERATOR_5)) { + l = BN_mod_word(dh->p, 10); + if (l == (BN_ULONG)-1) { + goto err; + } + if (l != 3 && l != 7) { + *out_flags |= DH_CHECK_NOT_SUITABLE_GENERATOR; + } + } else { + *out_flags |= DH_CHECK_UNABLE_TO_CHECK_GENERATOR; + } + + r = BN_is_prime_ex(dh->p, BN_prime_checks, ctx, NULL); + if (r < 0) { + goto err; + } + if (!r) { + *out_flags |= DH_CHECK_P_NOT_PRIME; + } else if (!dh->q) { + if (!BN_rshift1(t1, dh->p)) { + goto err; + } + r = BN_is_prime_ex(t1, BN_prime_checks, ctx, NULL); + if (r < 0) { + goto err; + } + if (!r) { + *out_flags |= DH_CHECK_P_NOT_SAFE_PRIME; + } + } + ok = 1; + +err: + if (ctx != NULL) { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + return ok; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/dh/dh.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/dh/dh.c new file mode 100644 index 0000000..e2166ce --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/dh/dh.c @@ -0,0 +1,519 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 +#include +#include +#include + +#include "../internal.h" + + +#define OPENSSL_DH_MAX_MODULUS_BITS 10000 + +static CRYPTO_EX_DATA_CLASS g_ex_data_class = CRYPTO_EX_DATA_CLASS_INIT; + +DH *DH_new(void) { + DH *dh = OPENSSL_malloc(sizeof(DH)); + if (dh == NULL) { + OPENSSL_PUT_ERROR(DH, ERR_R_MALLOC_FAILURE); + return NULL; + } + + OPENSSL_memset(dh, 0, sizeof(DH)); + + CRYPTO_MUTEX_init(&dh->method_mont_p_lock); + + dh->references = 1; + CRYPTO_new_ex_data(&dh->ex_data); + + return dh; +} + +void DH_free(DH *dh) { + if (dh == NULL) { + return; + } + + if (!CRYPTO_refcount_dec_and_test_zero(&dh->references)) { + return; + } + + CRYPTO_free_ex_data(&g_ex_data_class, dh, &dh->ex_data); + + BN_MONT_CTX_free(dh->method_mont_p); + BN_clear_free(dh->p); + BN_clear_free(dh->g); + BN_clear_free(dh->q); + BN_clear_free(dh->j); + OPENSSL_free(dh->seed); + BN_clear_free(dh->counter); + BN_clear_free(dh->pub_key); + BN_clear_free(dh->priv_key); + CRYPTO_MUTEX_cleanup(&dh->method_mont_p_lock); + + OPENSSL_free(dh); +} + +void DH_get0_key(const DH *dh, const BIGNUM **out_pub_key, + const BIGNUM **out_priv_key) { + if (out_pub_key != NULL) { + *out_pub_key = dh->pub_key; + } + if (out_priv_key != NULL) { + *out_priv_key = dh->priv_key; + } +} + +int DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key) { + 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; +} + +void DH_get0_pqg(const DH *dh, const BIGNUM **out_p, const BIGNUM **out_q, + const BIGNUM **out_g) { + if (out_p != NULL) { + *out_p = dh->p; + } + if (out_q != NULL) { + *out_q = dh->q; + } + if (out_g != NULL) { + *out_g = dh->g; + } +} + +int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g) { + 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; + } + + return 1; +} + +int DH_generate_parameters_ex(DH *dh, int prime_bits, int generator, BN_GENCB *cb) { + // We generate DH parameters as follows + // find a prime q which is prime_bits/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. + + BIGNUM *t1, *t2; + int g, ok = 0; + 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 |dh| has the necessary elements + if (dh->p == NULL) { + dh->p = BN_new(); + if (dh->p == NULL) { + goto err; + } + } + if (dh->g == NULL) { + dh->g = BN_new(); + if (dh->g == NULL) { + goto err; + } + } + + if (generator <= 1) { + OPENSSL_PUT_ERROR(DH, 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; + } 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(dh->p, prime_bits, 1, t1, t2, cb)) { + goto err; + } + if (!BN_GENCB_call(cb, 3, 0)) { + goto err; + } + if (!BN_set_word(dh->g, g)) { + goto err; + } + ok = 1; + +err: + if (!ok) { + OPENSSL_PUT_ERROR(DH, ERR_R_BN_LIB); + } + + if (ctx != NULL) { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + return ok; +} + +int DH_generate_key(DH *dh) { + int ok = 0; + int generate_new_key = 0; + BN_CTX *ctx = NULL; + BIGNUM *pub_key = NULL, *priv_key = NULL; + + if (BN_num_bits(dh->p) > OPENSSL_DH_MAX_MODULUS_BITS) { + OPENSSL_PUT_ERROR(DH, DH_R_MODULUS_TOO_LARGE); + goto err; + } + + 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 (!BN_MONT_CTX_set_locked(&dh->method_mont_p, &dh->method_mont_p_lock, + dh->p, ctx)) { + goto err; + } + + if (generate_new_key) { + if (dh->q) { + if (!BN_rand_range_ex(priv_key, 2, dh->q)) { + goto err; + } + } else { + // secret exponent length + unsigned priv_bits = dh->priv_length; + if (priv_bits == 0) { + const unsigned p_bits = BN_num_bits(dh->p); + if (p_bits == 0) { + goto err; + } + + priv_bits = p_bits - 1; + } + + if (!BN_rand(priv_key, priv_bits, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ANY)) { + goto err; + } + } + } + + if (!BN_mod_exp_mont_consttime(pub_key, dh->g, priv_key, dh->p, ctx, + dh->method_mont_p)) { + goto err; + } + + dh->pub_key = pub_key; + dh->priv_key = priv_key; + ok = 1; + +err: + if (ok != 1) { + OPENSSL_PUT_ERROR(DH, ERR_R_BN_LIB); + } + + if (dh->pub_key == NULL) { + BN_free(pub_key); + } + if (dh->priv_key == NULL) { + BN_free(priv_key); + } + BN_CTX_free(ctx); + return ok; +} + +int DH_compute_key(unsigned char *out, const BIGNUM *peers_key, DH *dh) { + BN_CTX *ctx = NULL; + BIGNUM *shared_key; + int ret = -1; + int check_result; + + if (BN_num_bits(dh->p) > OPENSSL_DH_MAX_MODULUS_BITS) { + OPENSSL_PUT_ERROR(DH, DH_R_MODULUS_TOO_LARGE); + goto err; + } + + ctx = BN_CTX_new(); + if (ctx == NULL) { + goto err; + } + BN_CTX_start(ctx); + shared_key = BN_CTX_get(ctx); + if (shared_key == NULL) { + goto err; + } + + if (dh->priv_key == NULL) { + OPENSSL_PUT_ERROR(DH, DH_R_NO_PRIVATE_VALUE); + goto err; + } + + if (!BN_MONT_CTX_set_locked(&dh->method_mont_p, &dh->method_mont_p_lock, + dh->p, ctx)) { + goto err; + } + + if (!DH_check_pub_key(dh, peers_key, &check_result) || check_result) { + OPENSSL_PUT_ERROR(DH, DH_R_INVALID_PUBKEY); + goto err; + } + + if (!BN_mod_exp_mont_consttime(shared_key, peers_key, dh->priv_key, dh->p, + ctx, dh->method_mont_p)) { + OPENSSL_PUT_ERROR(DH, ERR_R_BN_LIB); + goto err; + } + + ret = BN_bn2bin(shared_key, out); + +err: + if (ctx != NULL) { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + + return ret; +} + +int DH_size(const DH *dh) { return BN_num_bytes(dh->p); } + +unsigned DH_num_bits(const DH *dh) { return BN_num_bits(dh->p); } + +int DH_up_ref(DH *dh) { + CRYPTO_refcount_inc(&dh->references); + return 1; +} + +static int int_dh_bn_cpy(BIGNUM **dst, const BIGNUM *src) { + BIGNUM *a = NULL; + + if (src) { + a = BN_dup(src); + if (!a) { + return 0; + } + } + + 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) || + !int_dh_bn_cpy(&to->g, from->g)) { + return 0; + } + + if (!is_x942) { + return 1; + } + + if (!int_dh_bn_cpy(&to->q, from->q) || + !int_dh_bn_cpy(&to->j, from->j)) { + return 0; + } + + 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; + } + + return 1; +} + +DH *DHparams_dup(const DH *dh) { + DH *ret = DH_new(); + if (!ret) { + return NULL; + } + + if (!int_dh_param_copy(ret, dh, -1)) { + DH_free(ret); + return NULL; + } + + return ret; +} + +int DH_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused *unused, + CRYPTO_EX_dup *dup_unused, CRYPTO_EX_free *free_func) { + int index; + if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp, + free_func)) { + return -1; + } + return index; +} + +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); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/dh/dh.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/dh/dh.c.grpc_back new file mode 100644 index 0000000..7b7b833 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/dh/dh.c.grpc_back @@ -0,0 +1,519 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 +#include +#include +#include + +#include "../internal.h" + + +#define OPENSSL_DH_MAX_MODULUS_BITS 10000 + +static CRYPTO_EX_DATA_CLASS g_ex_data_class = CRYPTO_EX_DATA_CLASS_INIT; + +DH *DH_new(void) { + DH *dh = OPENSSL_malloc(sizeof(DH)); + if (dh == NULL) { + OPENSSL_PUT_ERROR(DH, ERR_R_MALLOC_FAILURE); + return NULL; + } + + OPENSSL_memset(dh, 0, sizeof(DH)); + + CRYPTO_MUTEX_init(&dh->method_mont_p_lock); + + dh->references = 1; + CRYPTO_new_ex_data(&dh->ex_data); + + return dh; +} + +void DH_free(DH *dh) { + if (dh == NULL) { + return; + } + + if (!CRYPTO_refcount_dec_and_test_zero(&dh->references)) { + return; + } + + CRYPTO_free_ex_data(&g_ex_data_class, dh, &dh->ex_data); + + BN_MONT_CTX_free(dh->method_mont_p); + BN_clear_free(dh->p); + BN_clear_free(dh->g); + BN_clear_free(dh->q); + BN_clear_free(dh->j); + OPENSSL_free(dh->seed); + BN_clear_free(dh->counter); + BN_clear_free(dh->pub_key); + BN_clear_free(dh->priv_key); + CRYPTO_MUTEX_cleanup(&dh->method_mont_p_lock); + + OPENSSL_free(dh); +} + +void DH_get0_key(const DH *dh, const BIGNUM **out_pub_key, + const BIGNUM **out_priv_key) { + if (out_pub_key != NULL) { + *out_pub_key = dh->pub_key; + } + if (out_priv_key != NULL) { + *out_priv_key = dh->priv_key; + } +} + +int DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key) { + 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; +} + +void DH_get0_pqg(const DH *dh, const BIGNUM **out_p, const BIGNUM **out_q, + const BIGNUM **out_g) { + if (out_p != NULL) { + *out_p = dh->p; + } + if (out_q != NULL) { + *out_q = dh->q; + } + if (out_g != NULL) { + *out_g = dh->g; + } +} + +int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g) { + 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; + } + + return 1; +} + +int DH_generate_parameters_ex(DH *dh, int prime_bits, int generator, BN_GENCB *cb) { + // We generate DH parameters as follows + // find a prime q which is prime_bits/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. + + BIGNUM *t1, *t2; + int g, ok = 0; + 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 |dh| has the necessary elements + if (dh->p == NULL) { + dh->p = BN_new(); + if (dh->p == NULL) { + goto err; + } + } + if (dh->g == NULL) { + dh->g = BN_new(); + if (dh->g == NULL) { + goto err; + } + } + + if (generator <= 1) { + OPENSSL_PUT_ERROR(DH, 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; + } 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(dh->p, prime_bits, 1, t1, t2, cb)) { + goto err; + } + if (!BN_GENCB_call(cb, 3, 0)) { + goto err; + } + if (!BN_set_word(dh->g, g)) { + goto err; + } + ok = 1; + +err: + if (!ok) { + OPENSSL_PUT_ERROR(DH, ERR_R_BN_LIB); + } + + if (ctx != NULL) { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + return ok; +} + +int DH_generate_key(DH *dh) { + int ok = 0; + int generate_new_key = 0; + BN_CTX *ctx = NULL; + BIGNUM *pub_key = NULL, *priv_key = NULL; + + if (BN_num_bits(dh->p) > OPENSSL_DH_MAX_MODULUS_BITS) { + OPENSSL_PUT_ERROR(DH, DH_R_MODULUS_TOO_LARGE); + goto err; + } + + 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 (!BN_MONT_CTX_set_locked(&dh->method_mont_p, &dh->method_mont_p_lock, + dh->p, ctx)) { + goto err; + } + + if (generate_new_key) { + if (dh->q) { + if (!BN_rand_range_ex(priv_key, 2, dh->q)) { + goto err; + } + } else { + // secret exponent length + unsigned priv_bits = dh->priv_length; + if (priv_bits == 0) { + const unsigned p_bits = BN_num_bits(dh->p); + if (p_bits == 0) { + goto err; + } + + priv_bits = p_bits - 1; + } + + if (!BN_rand(priv_key, priv_bits, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ANY)) { + goto err; + } + } + } + + if (!BN_mod_exp_mont_consttime(pub_key, dh->g, priv_key, dh->p, ctx, + dh->method_mont_p)) { + goto err; + } + + dh->pub_key = pub_key; + dh->priv_key = priv_key; + ok = 1; + +err: + if (ok != 1) { + OPENSSL_PUT_ERROR(DH, ERR_R_BN_LIB); + } + + if (dh->pub_key == NULL) { + BN_free(pub_key); + } + if (dh->priv_key == NULL) { + BN_free(priv_key); + } + BN_CTX_free(ctx); + return ok; +} + +int DH_compute_key(unsigned char *out, const BIGNUM *peers_key, DH *dh) { + BN_CTX *ctx = NULL; + BIGNUM *shared_key; + int ret = -1; + int check_result; + + if (BN_num_bits(dh->p) > OPENSSL_DH_MAX_MODULUS_BITS) { + OPENSSL_PUT_ERROR(DH, DH_R_MODULUS_TOO_LARGE); + goto err; + } + + ctx = BN_CTX_new(); + if (ctx == NULL) { + goto err; + } + BN_CTX_start(ctx); + shared_key = BN_CTX_get(ctx); + if (shared_key == NULL) { + goto err; + } + + if (dh->priv_key == NULL) { + OPENSSL_PUT_ERROR(DH, DH_R_NO_PRIVATE_VALUE); + goto err; + } + + if (!BN_MONT_CTX_set_locked(&dh->method_mont_p, &dh->method_mont_p_lock, + dh->p, ctx)) { + goto err; + } + + if (!DH_check_pub_key(dh, peers_key, &check_result) || check_result) { + OPENSSL_PUT_ERROR(DH, DH_R_INVALID_PUBKEY); + goto err; + } + + if (!BN_mod_exp_mont_consttime(shared_key, peers_key, dh->priv_key, dh->p, + ctx, dh->method_mont_p)) { + OPENSSL_PUT_ERROR(DH, ERR_R_BN_LIB); + goto err; + } + + ret = BN_bn2bin(shared_key, out); + +err: + if (ctx != NULL) { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + + return ret; +} + +int DH_size(const DH *dh) { return BN_num_bytes(dh->p); } + +unsigned DH_num_bits(const DH *dh) { return BN_num_bits(dh->p); } + +int DH_up_ref(DH *dh) { + CRYPTO_refcount_inc(&dh->references); + return 1; +} + +static int int_dh_bn_cpy(BIGNUM **dst, const BIGNUM *src) { + BIGNUM *a = NULL; + + if (src) { + a = BN_dup(src); + if (!a) { + return 0; + } + } + + 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) || + !int_dh_bn_cpy(&to->g, from->g)) { + return 0; + } + + if (!is_x942) { + return 1; + } + + if (!int_dh_bn_cpy(&to->q, from->q) || + !int_dh_bn_cpy(&to->j, from->j)) { + return 0; + } + + 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; + } + + return 1; +} + +DH *DHparams_dup(const DH *dh) { + DH *ret = DH_new(); + if (!ret) { + return NULL; + } + + if (!int_dh_param_copy(ret, dh, -1)) { + DH_free(ret); + return NULL; + } + + return ret; +} + +int DH_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused *unused, + CRYPTO_EX_dup *dup_unused, CRYPTO_EX_free *free_func) { + int index; + if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp, + free_func)) { + return -1; + } + return index; +} + +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); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/dh/dh_asn1.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/dh/dh_asn1.c new file mode 100644 index 0000000..2f40cd4 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/dh/dh_asn1.c @@ -0,0 +1,160 @@ +/* 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 +#include + +#include +#include +#include + +#include "../bytestring/internal.h" + + +static int parse_integer(CBS *cbs, BIGNUM **out) { + assert(*out == NULL); + *out = BN_new(); + if (*out == NULL) { + return 0; + } + return BN_parse_asn1_unsigned(cbs, *out); +} + +static int marshal_integer(CBB *cbb, BIGNUM *bn) { + if (bn == NULL) { + // A DH object may be missing some components. + OPENSSL_PUT_ERROR(DH, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + return BN_marshal_asn1(cbb, bn); +} + +DH *DH_parse_parameters(CBS *cbs) { + DH *ret = DH_new(); + if (ret == NULL) { + return NULL; + } + + CBS child; + if (!CBS_get_asn1(cbs, &child, CBS_ASN1_SEQUENCE) || + !parse_integer(&child, &ret->p) || + !parse_integer(&child, &ret->g)) { + goto err; + } + + uint64_t priv_length; + if (CBS_len(&child) != 0) { + if (!CBS_get_asn1_uint64(&child, &priv_length) || + priv_length > UINT_MAX) { + goto err; + } + ret->priv_length = (unsigned)priv_length; + } + + if (CBS_len(&child) != 0) { + goto err; + } + + return ret; + +err: + OPENSSL_PUT_ERROR(DH, DH_R_DECODE_ERROR); + DH_free(ret); + return NULL; +} + +int DH_marshal_parameters(CBB *cbb, const DH *dh) { + CBB child; + if (!CBB_add_asn1(cbb, &child, CBS_ASN1_SEQUENCE) || + !marshal_integer(&child, dh->p) || + !marshal_integer(&child, dh->g) || + (dh->priv_length != 0 && + !CBB_add_asn1_uint64(&child, dh->priv_length)) || + !CBB_flush(cbb)) { + OPENSSL_PUT_ERROR(DH, DH_R_ENCODE_ERROR); + return 0; + } + return 1; +} + +DH *d2i_DHparams(DH **out, const uint8_t **inp, long len) { + if (len < 0) { + return NULL; + } + CBS cbs; + CBS_init(&cbs, *inp, (size_t)len); + DH *ret = DH_parse_parameters(&cbs); + if (ret == NULL) { + return NULL; + } + if (out != NULL) { + DH_free(*out); + *out = ret; + } + *inp = CBS_data(&cbs); + return ret; +} + +int i2d_DHparams(const DH *in, uint8_t **outp) { + CBB cbb; + if (!CBB_init(&cbb, 0) || + !DH_marshal_parameters(&cbb, in)) { + CBB_cleanup(&cbb); + return -1; + } + return CBB_finish_i2d(&cbb, outp); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/dh/dh_asn1.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/dh/dh_asn1.c.grpc_back new file mode 100644 index 0000000..9d32180 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/dh/dh_asn1.c.grpc_back @@ -0,0 +1,160 @@ +/* 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 +#include + +#include +#include +#include + +#include "../bytestring/internal.h" + + +static int parse_integer(CBS *cbs, BIGNUM **out) { + assert(*out == NULL); + *out = BN_new(); + if (*out == NULL) { + return 0; + } + return BN_parse_asn1_unsigned(cbs, *out); +} + +static int marshal_integer(CBB *cbb, BIGNUM *bn) { + if (bn == NULL) { + // A DH object may be missing some components. + OPENSSL_PUT_ERROR(DH, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + return BN_marshal_asn1(cbb, bn); +} + +DH *DH_parse_parameters(CBS *cbs) { + DH *ret = DH_new(); + if (ret == NULL) { + return NULL; + } + + CBS child; + if (!CBS_get_asn1(cbs, &child, CBS_ASN1_SEQUENCE) || + !parse_integer(&child, &ret->p) || + !parse_integer(&child, &ret->g)) { + goto err; + } + + uint64_t priv_length; + if (CBS_len(&child) != 0) { + if (!CBS_get_asn1_uint64(&child, &priv_length) || + priv_length > UINT_MAX) { + goto err; + } + ret->priv_length = (unsigned)priv_length; + } + + if (CBS_len(&child) != 0) { + goto err; + } + + return ret; + +err: + OPENSSL_PUT_ERROR(DH, DH_R_DECODE_ERROR); + DH_free(ret); + return NULL; +} + +int DH_marshal_parameters(CBB *cbb, const DH *dh) { + CBB child; + if (!CBB_add_asn1(cbb, &child, CBS_ASN1_SEQUENCE) || + !marshal_integer(&child, dh->p) || + !marshal_integer(&child, dh->g) || + (dh->priv_length != 0 && + !CBB_add_asn1_uint64(&child, dh->priv_length)) || + !CBB_flush(cbb)) { + OPENSSL_PUT_ERROR(DH, DH_R_ENCODE_ERROR); + return 0; + } + return 1; +} + +DH *d2i_DHparams(DH **out, const uint8_t **inp, long len) { + if (len < 0) { + return NULL; + } + CBS cbs; + CBS_init(&cbs, *inp, (size_t)len); + DH *ret = DH_parse_parameters(&cbs); + if (ret == NULL) { + return NULL; + } + if (out != NULL) { + DH_free(*out); + *out = ret; + } + *inp = CBS_data(&cbs); + return ret; +} + +int i2d_DHparams(const DH *in, uint8_t **outp) { + CBB cbb; + if (!CBB_init(&cbb, 0) || + !DH_marshal_parameters(&cbb, in)) { + CBB_cleanup(&cbb); + return -1; + } + return CBB_finish_i2d(&cbb, outp); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/dh/params.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/dh/params.c new file mode 100644 index 0000000..c583653 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/dh/params.c @@ -0,0 +1,93 @@ +/* ==================================================================== + * 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 + +#include "../fipsmodule/bn/internal.h" + + +BIGNUM *BN_get_rfc3526_prime_1536(BIGNUM *ret) { + static const BN_ULONG kPrime1536Data[] = { + TOBN(0xffffffff, 0xffffffff), TOBN(0xf1746c08, 0xca237327), + TOBN(0x670c354e, 0x4abc9804), TOBN(0x9ed52907, 0x7096966d), + TOBN(0x1c62f356, 0x208552bb), TOBN(0x83655d23, 0xdca3ad96), + TOBN(0x69163fa8, 0xfd24cf5f), TOBN(0x98da4836, 0x1c55d39a), + TOBN(0xc2007cb8, 0xa163bf05), TOBN(0x49286651, 0xece45b3d), + TOBN(0xae9f2411, 0x7c4b1fe6), TOBN(0xee386bfb, 0x5a899fa5), + TOBN(0x0bff5cb6, 0xf406b7ed), TOBN(0xf44c42e9, 0xa637ed6b), + TOBN(0xe485b576, 0x625e7ec6), TOBN(0x4fe1356d, 0x6d51c245), + TOBN(0x302b0a6d, 0xf25f1437), TOBN(0xef9519b3, 0xcd3a431b), + TOBN(0x514a0879, 0x8e3404dd), TOBN(0x020bbea6, 0x3b139b22), + TOBN(0x29024e08, 0x8a67cc74), TOBN(0xc4c6628b, 0x80dc1cd1), + TOBN(0xc90fdaa2, 0x2168c234), TOBN(0xffffffff, 0xffffffff), + }; + + static const BIGNUM kPrime1536BN = STATIC_BIGNUM(kPrime1536Data); + + BIGNUM *alloc = NULL; + if (ret == NULL) { + alloc = BN_new(); + if (alloc == NULL) { + return NULL; + } + ret = alloc; + } + + if (!BN_copy(ret, &kPrime1536BN)) { + BN_free(alloc); + return NULL; + } + + return ret; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/dh/params.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/dh/params.c.grpc_back new file mode 100644 index 0000000..3336029 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/dh/params.c.grpc_back @@ -0,0 +1,93 @@ +/* ==================================================================== + * 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 + +#include "../fipsmodule/bn/internal.h" + + +BIGNUM *BN_get_rfc3526_prime_1536(BIGNUM *ret) { + static const BN_ULONG kPrime1536Data[] = { + TOBN(0xffffffff, 0xffffffff), TOBN(0xf1746c08, 0xca237327), + TOBN(0x670c354e, 0x4abc9804), TOBN(0x9ed52907, 0x7096966d), + TOBN(0x1c62f356, 0x208552bb), TOBN(0x83655d23, 0xdca3ad96), + TOBN(0x69163fa8, 0xfd24cf5f), TOBN(0x98da4836, 0x1c55d39a), + TOBN(0xc2007cb8, 0xa163bf05), TOBN(0x49286651, 0xece45b3d), + TOBN(0xae9f2411, 0x7c4b1fe6), TOBN(0xee386bfb, 0x5a899fa5), + TOBN(0x0bff5cb6, 0xf406b7ed), TOBN(0xf44c42e9, 0xa637ed6b), + TOBN(0xe485b576, 0x625e7ec6), TOBN(0x4fe1356d, 0x6d51c245), + TOBN(0x302b0a6d, 0xf25f1437), TOBN(0xef9519b3, 0xcd3a431b), + TOBN(0x514a0879, 0x8e3404dd), TOBN(0x020bbea6, 0x3b139b22), + TOBN(0x29024e08, 0x8a67cc74), TOBN(0xc4c6628b, 0x80dc1cd1), + TOBN(0xc90fdaa2, 0x2168c234), TOBN(0xffffffff, 0xffffffff), + }; + + static const BIGNUM kPrime1536BN = STATIC_BIGNUM(kPrime1536Data); + + BIGNUM *alloc = NULL; + if (ret == NULL) { + alloc = BN_new(); + if (alloc == NULL) { + return NULL; + } + ret = alloc; + } + + if (!BN_copy(ret, &kPrime1536BN)) { + BN_free(alloc); + return NULL; + } + + return ret; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/digest_extra/digest_extra.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/digest_extra/digest_extra.c new file mode 100644 index 0000000..1f49263 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/digest_extra/digest_extra.c @@ -0,0 +1,240 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 + +#include "../internal.h" + + +struct nid_to_digest { + int nid; + const EVP_MD* (*md_func)(void); + const char *short_name; + const char *long_name; +}; + +static const struct nid_to_digest nid_to_digest_mapping[] = { + {NID_md4, EVP_md4, SN_md4, LN_md4}, + {NID_md5, EVP_md5, SN_md5, LN_md5}, + {NID_sha1, EVP_sha1, SN_sha1, LN_sha1}, + {NID_sha224, EVP_sha224, SN_sha224, LN_sha224}, + {NID_sha256, EVP_sha256, SN_sha256, LN_sha256}, + {NID_sha384, EVP_sha384, SN_sha384, LN_sha384}, + {NID_sha512, EVP_sha512, SN_sha512, LN_sha512}, + {NID_md5_sha1, EVP_md5_sha1, SN_md5_sha1, LN_md5_sha1}, + // As a remnant of signing |EVP_MD|s, OpenSSL returned the corresponding + // hash function when given a signature OID. To avoid unintended lax parsing + // of hash OIDs, this is no longer supported for lookup by OID or NID. + // Node.js, however, exposes |EVP_get_digestbyname|'s full behavior to + // consumers so we retain it there. + {NID_undef, EVP_sha1, SN_dsaWithSHA, LN_dsaWithSHA}, + {NID_undef, EVP_sha1, SN_dsaWithSHA1, LN_dsaWithSHA1}, + {NID_undef, EVP_sha1, SN_ecdsa_with_SHA1, NULL}, + {NID_undef, EVP_md5, SN_md5WithRSAEncryption, LN_md5WithRSAEncryption}, + {NID_undef, EVP_sha1, SN_sha1WithRSAEncryption, LN_sha1WithRSAEncryption}, + {NID_undef, EVP_sha224, SN_sha224WithRSAEncryption, + LN_sha224WithRSAEncryption}, + {NID_undef, EVP_sha256, SN_sha256WithRSAEncryption, + LN_sha256WithRSAEncryption}, + {NID_undef, EVP_sha384, SN_sha384WithRSAEncryption, + LN_sha384WithRSAEncryption}, + {NID_undef, EVP_sha512, SN_sha512WithRSAEncryption, + LN_sha512WithRSAEncryption}, +}; + +const EVP_MD* EVP_get_digestbynid(int nid) { + if (nid == NID_undef) { + // Skip the |NID_undef| entries in |nid_to_digest_mapping|. + return NULL; + } + + for (unsigned i = 0; i < OPENSSL_ARRAY_SIZE(nid_to_digest_mapping); i++) { + if (nid_to_digest_mapping[i].nid == nid) { + return nid_to_digest_mapping[i].md_func(); + } + } + + return NULL; +} + +static const struct { + uint8_t oid[9]; + uint8_t oid_len; + int nid; +} kMDOIDs[] = { + // 1.2.840.113549.2.4 + { {0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x04}, 8, NID_md4 }, + // 1.2.840.113549.2.5 + { {0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05}, 8, NID_md5 }, + // 1.3.14.3.2.26 + { {0x2b, 0x0e, 0x03, 0x02, 0x1a}, 5, NID_sha1 }, + // 2.16.840.1.101.3.4.2.1 + { {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01}, 9, NID_sha256 }, + // 2.16.840.1.101.3.4.2.2 + { {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02}, 9, NID_sha384 }, + // 2.16.840.1.101.3.4.2.3 + { {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03}, 9, NID_sha512 }, + // 2.16.840.1.101.3.4.2.4 + { {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04}, 9, NID_sha224 }, +}; + +static const EVP_MD *cbs_to_md(const CBS *cbs) { + for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kMDOIDs); i++) { + if (CBS_len(cbs) == kMDOIDs[i].oid_len && + OPENSSL_memcmp(CBS_data(cbs), kMDOIDs[i].oid, kMDOIDs[i].oid_len) == + 0) { + return EVP_get_digestbynid(kMDOIDs[i].nid); + } + } + + return NULL; +} + +const EVP_MD *EVP_get_digestbyobj(const ASN1_OBJECT *obj) { + // Handle objects with no corresponding OID. + if (obj->nid != NID_undef) { + return EVP_get_digestbynid(obj->nid); + } + + CBS cbs; + CBS_init(&cbs, obj->data, obj->length); + return cbs_to_md(&cbs); +} + +const EVP_MD *EVP_parse_digest_algorithm(CBS *cbs) { + CBS algorithm, oid; + if (!CBS_get_asn1(cbs, &algorithm, CBS_ASN1_SEQUENCE) || + !CBS_get_asn1(&algorithm, &oid, CBS_ASN1_OBJECT)) { + OPENSSL_PUT_ERROR(DIGEST, DIGEST_R_DECODE_ERROR); + return NULL; + } + + const EVP_MD *ret = cbs_to_md(&oid); + if (ret == NULL) { + OPENSSL_PUT_ERROR(DIGEST, DIGEST_R_UNKNOWN_HASH); + return NULL; + } + + // The parameters, if present, must be NULL. Historically, whether the NULL + // was included or omitted was not well-specified. When parsing an + // AlgorithmIdentifier, we allow both. (Note this code is not used when + // verifying RSASSA-PKCS1-v1_5 signatures.) + if (CBS_len(&algorithm) > 0) { + CBS param; + if (!CBS_get_asn1(&algorithm, ¶m, CBS_ASN1_NULL) || + CBS_len(¶m) != 0 || + CBS_len(&algorithm) != 0) { + OPENSSL_PUT_ERROR(DIGEST, DIGEST_R_DECODE_ERROR); + return NULL; + } + } + + return ret; +} + +int EVP_marshal_digest_algorithm(CBB *cbb, const EVP_MD *md) { + CBB algorithm, oid, null; + if (!CBB_add_asn1(cbb, &algorithm, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1(&algorithm, &oid, CBS_ASN1_OBJECT)) { + OPENSSL_PUT_ERROR(DIGEST, ERR_R_MALLOC_FAILURE); + return 0; + } + + int found = 0; + int nid = EVP_MD_type(md); + for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kMDOIDs); i++) { + if (nid == kMDOIDs[i].nid) { + if (!CBB_add_bytes(&oid, kMDOIDs[i].oid, kMDOIDs[i].oid_len)) { + OPENSSL_PUT_ERROR(DIGEST, ERR_R_MALLOC_FAILURE); + return 0; + } + found = 1; + break; + } + } + + if (!found) { + OPENSSL_PUT_ERROR(DIGEST, DIGEST_R_UNKNOWN_HASH); + return 0; + } + + if (!CBB_add_asn1(&algorithm, &null, CBS_ASN1_NULL) || + !CBB_flush(cbb)) { + OPENSSL_PUT_ERROR(DIGEST, ERR_R_MALLOC_FAILURE); + return 0; + } + + return 1; +} + +const EVP_MD *EVP_get_digestbyname(const char *name) { + for (unsigned i = 0; i < OPENSSL_ARRAY_SIZE(nid_to_digest_mapping); i++) { + const char *short_name = nid_to_digest_mapping[i].short_name; + const char *long_name = nid_to_digest_mapping[i].long_name; + if ((short_name && strcmp(short_name, name) == 0) || + (long_name && strcmp(long_name, name) == 0)) { + return nid_to_digest_mapping[i].md_func(); + } + } + + return NULL; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/digest_extra/digest_extra.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/digest_extra/digest_extra.c.grpc_back new file mode 100644 index 0000000..4b4bb38 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/digest_extra/digest_extra.c.grpc_back @@ -0,0 +1,240 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 + +#include "../internal.h" + + +struct nid_to_digest { + int nid; + const EVP_MD* (*md_func)(void); + const char *short_name; + const char *long_name; +}; + +static const struct nid_to_digest nid_to_digest_mapping[] = { + {NID_md4, EVP_md4, SN_md4, LN_md4}, + {NID_md5, EVP_md5, SN_md5, LN_md5}, + {NID_sha1, EVP_sha1, SN_sha1, LN_sha1}, + {NID_sha224, EVP_sha224, SN_sha224, LN_sha224}, + {NID_sha256, EVP_sha256, SN_sha256, LN_sha256}, + {NID_sha384, EVP_sha384, SN_sha384, LN_sha384}, + {NID_sha512, EVP_sha512, SN_sha512, LN_sha512}, + {NID_md5_sha1, EVP_md5_sha1, SN_md5_sha1, LN_md5_sha1}, + // As a remnant of signing |EVP_MD|s, OpenSSL returned the corresponding + // hash function when given a signature OID. To avoid unintended lax parsing + // of hash OIDs, this is no longer supported for lookup by OID or NID. + // Node.js, however, exposes |EVP_get_digestbyname|'s full behavior to + // consumers so we retain it there. + {NID_undef, EVP_sha1, SN_dsaWithSHA, LN_dsaWithSHA}, + {NID_undef, EVP_sha1, SN_dsaWithSHA1, LN_dsaWithSHA1}, + {NID_undef, EVP_sha1, SN_ecdsa_with_SHA1, NULL}, + {NID_undef, EVP_md5, SN_md5WithRSAEncryption, LN_md5WithRSAEncryption}, + {NID_undef, EVP_sha1, SN_sha1WithRSAEncryption, LN_sha1WithRSAEncryption}, + {NID_undef, EVP_sha224, SN_sha224WithRSAEncryption, + LN_sha224WithRSAEncryption}, + {NID_undef, EVP_sha256, SN_sha256WithRSAEncryption, + LN_sha256WithRSAEncryption}, + {NID_undef, EVP_sha384, SN_sha384WithRSAEncryption, + LN_sha384WithRSAEncryption}, + {NID_undef, EVP_sha512, SN_sha512WithRSAEncryption, + LN_sha512WithRSAEncryption}, +}; + +const EVP_MD* EVP_get_digestbynid(int nid) { + if (nid == NID_undef) { + // Skip the |NID_undef| entries in |nid_to_digest_mapping|. + return NULL; + } + + for (unsigned i = 0; i < OPENSSL_ARRAY_SIZE(nid_to_digest_mapping); i++) { + if (nid_to_digest_mapping[i].nid == nid) { + return nid_to_digest_mapping[i].md_func(); + } + } + + return NULL; +} + +static const struct { + uint8_t oid[9]; + uint8_t oid_len; + int nid; +} kMDOIDs[] = { + // 1.2.840.113549.2.4 + { {0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x04}, 8, NID_md4 }, + // 1.2.840.113549.2.5 + { {0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05}, 8, NID_md5 }, + // 1.3.14.3.2.26 + { {0x2b, 0x0e, 0x03, 0x02, 0x1a}, 5, NID_sha1 }, + // 2.16.840.1.101.3.4.2.1 + { {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01}, 9, NID_sha256 }, + // 2.16.840.1.101.3.4.2.2 + { {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02}, 9, NID_sha384 }, + // 2.16.840.1.101.3.4.2.3 + { {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03}, 9, NID_sha512 }, + // 2.16.840.1.101.3.4.2.4 + { {0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04}, 9, NID_sha224 }, +}; + +static const EVP_MD *cbs_to_md(const CBS *cbs) { + for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kMDOIDs); i++) { + if (CBS_len(cbs) == kMDOIDs[i].oid_len && + OPENSSL_memcmp(CBS_data(cbs), kMDOIDs[i].oid, kMDOIDs[i].oid_len) == + 0) { + return EVP_get_digestbynid(kMDOIDs[i].nid); + } + } + + return NULL; +} + +const EVP_MD *EVP_get_digestbyobj(const ASN1_OBJECT *obj) { + // Handle objects with no corresponding OID. + if (obj->nid != NID_undef) { + return EVP_get_digestbynid(obj->nid); + } + + CBS cbs; + CBS_init(&cbs, obj->data, obj->length); + return cbs_to_md(&cbs); +} + +const EVP_MD *EVP_parse_digest_algorithm(CBS *cbs) { + CBS algorithm, oid; + if (!CBS_get_asn1(cbs, &algorithm, CBS_ASN1_SEQUENCE) || + !CBS_get_asn1(&algorithm, &oid, CBS_ASN1_OBJECT)) { + OPENSSL_PUT_ERROR(DIGEST, DIGEST_R_DECODE_ERROR); + return NULL; + } + + const EVP_MD *ret = cbs_to_md(&oid); + if (ret == NULL) { + OPENSSL_PUT_ERROR(DIGEST, DIGEST_R_UNKNOWN_HASH); + return NULL; + } + + // The parameters, if present, must be NULL. Historically, whether the NULL + // was included or omitted was not well-specified. When parsing an + // AlgorithmIdentifier, we allow both. (Note this code is not used when + // verifying RSASSA-PKCS1-v1_5 signatures.) + if (CBS_len(&algorithm) > 0) { + CBS param; + if (!CBS_get_asn1(&algorithm, ¶m, CBS_ASN1_NULL) || + CBS_len(¶m) != 0 || + CBS_len(&algorithm) != 0) { + OPENSSL_PUT_ERROR(DIGEST, DIGEST_R_DECODE_ERROR); + return NULL; + } + } + + return ret; +} + +int EVP_marshal_digest_algorithm(CBB *cbb, const EVP_MD *md) { + CBB algorithm, oid, null; + if (!CBB_add_asn1(cbb, &algorithm, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1(&algorithm, &oid, CBS_ASN1_OBJECT)) { + OPENSSL_PUT_ERROR(DIGEST, ERR_R_MALLOC_FAILURE); + return 0; + } + + int found = 0; + int nid = EVP_MD_type(md); + for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kMDOIDs); i++) { + if (nid == kMDOIDs[i].nid) { + if (!CBB_add_bytes(&oid, kMDOIDs[i].oid, kMDOIDs[i].oid_len)) { + OPENSSL_PUT_ERROR(DIGEST, ERR_R_MALLOC_FAILURE); + return 0; + } + found = 1; + break; + } + } + + if (!found) { + OPENSSL_PUT_ERROR(DIGEST, DIGEST_R_UNKNOWN_HASH); + return 0; + } + + if (!CBB_add_asn1(&algorithm, &null, CBS_ASN1_NULL) || + !CBB_flush(cbb)) { + OPENSSL_PUT_ERROR(DIGEST, ERR_R_MALLOC_FAILURE); + return 0; + } + + return 1; +} + +const EVP_MD *EVP_get_digestbyname(const char *name) { + for (unsigned i = 0; i < OPENSSL_ARRAY_SIZE(nid_to_digest_mapping); i++) { + const char *short_name = nid_to_digest_mapping[i].short_name; + const char *long_name = nid_to_digest_mapping[i].long_name; + if ((short_name && strcmp(short_name, name) == 0) || + (long_name && strcmp(long_name, name) == 0)) { + return nid_to_digest_mapping[i].md_func(); + } + } + + return NULL; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/dsa/dsa.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/dsa/dsa.c new file mode 100644 index 0000000..a3f8535 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/dsa/dsa.c @@ -0,0 +1,946 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 . */ + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../fipsmodule/bn/internal.h" +#include "../internal.h" + + +#define OPENSSL_DSA_MAX_MODULUS_BITS 10000 + +// Primality test according to FIPS PUB 186[-1], Appendix 2.1: 50 rounds of +// Rabin-Miller +#define DSS_prime_checks 50 + +static int dsa_sign_setup(const DSA *dsa, BN_CTX *ctx_in, BIGNUM **out_kinv, + BIGNUM **out_r); + +static CRYPTO_EX_DATA_CLASS g_ex_data_class = CRYPTO_EX_DATA_CLASS_INIT; + +DSA *DSA_new(void) { + DSA *dsa = OPENSSL_malloc(sizeof(DSA)); + if (dsa == NULL) { + OPENSSL_PUT_ERROR(DSA, ERR_R_MALLOC_FAILURE); + return NULL; + } + + OPENSSL_memset(dsa, 0, sizeof(DSA)); + + dsa->references = 1; + + CRYPTO_MUTEX_init(&dsa->method_mont_lock); + CRYPTO_new_ex_data(&dsa->ex_data); + + return dsa; +} + +void DSA_free(DSA *dsa) { + if (dsa == NULL) { + return; + } + + if (!CRYPTO_refcount_dec_and_test_zero(&dsa->references)) { + return; + } + + CRYPTO_free_ex_data(&g_ex_data_class, dsa, &dsa->ex_data); + + BN_clear_free(dsa->p); + BN_clear_free(dsa->q); + BN_clear_free(dsa->g); + BN_clear_free(dsa->pub_key); + BN_clear_free(dsa->priv_key); + BN_MONT_CTX_free(dsa->method_mont_p); + BN_MONT_CTX_free(dsa->method_mont_q); + CRYPTO_MUTEX_cleanup(&dsa->method_mont_lock); + OPENSSL_free(dsa); +} + +int DSA_up_ref(DSA *dsa) { + CRYPTO_refcount_inc(&dsa->references); + return 1; +} + +void DSA_get0_key(const DSA *dsa, const BIGNUM **out_pub_key, + const BIGNUM **out_priv_key) { + if (out_pub_key != NULL) { + *out_pub_key = dsa->pub_key; + } + if (out_priv_key != NULL) { + *out_priv_key = dsa->priv_key; + } +} + +void DSA_get0_pqg(const DSA *dsa, const BIGNUM **out_p, const BIGNUM **out_q, + const BIGNUM **out_g) { + if (out_p != NULL) { + *out_p = dsa->p; + } + if (out_q != NULL) { + *out_q = dsa->q; + } + if (out_g != NULL) { + *out_g = dsa->g; + } +} + +int DSA_set0_key(DSA *dsa, BIGNUM *pub_key, BIGNUM *priv_key) { + if (dsa->pub_key == NULL && pub_key == NULL) { + return 0; + } + + if (pub_key != NULL) { + BN_free(dsa->pub_key); + dsa->pub_key = pub_key; + } + if (priv_key != NULL) { + BN_free(dsa->priv_key); + dsa->priv_key = priv_key; + } + + return 1; +} + +int DSA_set0_pqg(DSA *dsa, BIGNUM *p, BIGNUM *q, BIGNUM *g) { + if ((dsa->p == NULL && p == NULL) || + (dsa->q == NULL && q == NULL) || + (dsa->g == NULL && g == NULL)) { + return 0; + } + + if (p != NULL) { + BN_free(dsa->p); + dsa->p = p; + } + if (q != NULL) { + BN_free(dsa->q); + dsa->q = q; + } + if (g != NULL) { + BN_free(dsa->g); + dsa->g = g; + } + + return 1; +} + +int DSA_generate_parameters_ex(DSA *dsa, unsigned bits, const uint8_t *seed_in, + size_t seed_len, int *out_counter, + unsigned long *out_h, 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 k, n = 0, m = 0; + unsigned i; + int counter = 0; + int r = 0; + BN_CTX *ctx = NULL; + unsigned int h = 2; + unsigned qsize; + const EVP_MD *evpmd; + + evpmd = (bits >= 2048) ? EVP_sha256() : EVP_sha1(); + qsize = EVP_MD_size(evpmd); + + if (bits < 512) { + bits = 512; + } + + bits = (bits + 63) / 64 * 64; + + if (seed_in != NULL) { + if (seed_len < (size_t)qsize) { + return 0; + } + if (seed_len > (size_t)qsize) { + // Only consume as much seed as is expected. + seed_len = qsize; + } + OPENSSL_memcpy(seed, seed_in, seed_len); + } + + ctx = BN_CTX_new(); + if (ctx == 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 || !BN_lshift(test, BN_value_one(), bits - 1)) { + goto err; + } + + for (;;) { + // Find q. + for (;;) { + // step 1 + if (!BN_GENCB_call(cb, 0, m++)) { + goto err; + } + + int use_random_seed = (seed_in == NULL); + if (use_random_seed) { + if (!RAND_bytes(seed, qsize)) { + goto err; + } + } else { + // If we come back through, use random seed next time. + seed_in = NULL; + } + OPENSSL_memcpy(buf, seed, qsize); + OPENSSL_memcpy(buf2, seed, qsize); + // precompute "SEED + 1" for step 7: + for (i = qsize - 1; i < qsize; i--) { + buf[i]++; + if (buf[i] != 0) { + break; + } + } + + // step 2 + if (!EVP_Digest(seed, qsize, md, NULL, evpmd, NULL) || + !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, use_random_seed, cb); + if (r > 0) { + break; + } + if (r != 0) { + goto err; + } + + // do a callback call + // step 5 + } + + if (!BN_GENCB_call(cb, 2, 0) || !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 < qsize; 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) || + !BN_lshift(r0, r0, (qsize << 3) * k) || + !BN_add(W, W, r0)) { + goto err; + } + } + + // more of step 8 + if (!BN_mask_bits(W, bits - 1) || + !BN_copy(X, W) || + !BN_add(X, X, test)) { + goto err; + } + + // step 9 + if (!BN_lshift1(r0, q) || + !BN_mod(c, X, r0, ctx) || + !BN_sub(r0, c, BN_value_one()) || + !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()) || + !BN_div(r0, NULL, test, q, ctx)) { + goto err; + } + + mont = BN_MONT_CTX_new_for_modulus(p, ctx); + if (mont == NULL || + !BN_set_word(test, h)) { + 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) { + BN_free(dsa->p); + BN_free(dsa->q); + BN_free(dsa->g); + dsa->p = BN_dup(p); + dsa->q = BN_dup(q); + dsa->g = BN_dup(g); + if (dsa->p == NULL || dsa->q == NULL || dsa->g == NULL) { + ok = 0; + goto err; + } + if (out_counter != NULL) { + *out_counter = counter; + } + if (out_h != NULL) { + *out_h = h; + } + } + + if (ctx) { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + + BN_MONT_CTX_free(mont); + + return ok; +} + +DSA *DSAparams_dup(const DSA *dsa) { + DSA *ret = DSA_new(); + if (ret == NULL) { + return NULL; + } + ret->p = BN_dup(dsa->p); + ret->q = BN_dup(dsa->q); + ret->g = BN_dup(dsa->g); + if (ret->p == NULL || ret->q == NULL || ret->g == NULL) { + DSA_free(ret); + return NULL; + } + return ret; +} + +int DSA_generate_key(DSA *dsa) { + int ok = 0; + BN_CTX *ctx = NULL; + BIGNUM *pub_key = NULL, *priv_key = NULL; + + ctx = BN_CTX_new(); + if (ctx == NULL) { + goto err; + } + + priv_key = dsa->priv_key; + if (priv_key == NULL) { + priv_key = BN_new(); + if (priv_key == NULL) { + goto err; + } + } + + if (!BN_rand_range_ex(priv_key, 1, dsa->q)) { + goto err; + } + + pub_key = dsa->pub_key; + if (pub_key == NULL) { + pub_key = BN_new(); + if (pub_key == NULL) { + goto err; + } + } + + if (!BN_MONT_CTX_set_locked(&dsa->method_mont_p, &dsa->method_mont_lock, + dsa->p, ctx) || + !BN_mod_exp_mont_consttime(pub_key, dsa->g, priv_key, dsa->p, ctx, + dsa->method_mont_p)) { + goto err; + } + + dsa->priv_key = priv_key; + dsa->pub_key = pub_key; + ok = 1; + +err: + if (dsa->pub_key == NULL) { + BN_free(pub_key); + } + if (dsa->priv_key == NULL) { + BN_free(priv_key); + } + BN_CTX_free(ctx); + + return ok; +} + +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) { + return; + } + + BN_free(sig->r); + BN_free(sig->s); + OPENSSL_free(sig); +} + +DSA_SIG *DSA_do_sign(const uint8_t *digest, size_t digest_len, const DSA *dsa) { + BIGNUM *kinv = NULL, *r = NULL, *s = NULL; + BIGNUM m; + BIGNUM xr; + BN_CTX *ctx = NULL; + int reason = ERR_R_BN_LIB; + DSA_SIG *ret = NULL; + + BN_init(&m); + BN_init(&xr); + + if (!dsa->p || !dsa->q || !dsa->g) { + reason = DSA_R_MISSING_PARAMETERS; + goto err; + } + + s = BN_new(); + if (s == NULL) { + goto err; + } + ctx = BN_CTX_new(); + if (ctx == NULL) { + goto err; + } + +redo: + if (!dsa_sign_setup(dsa, ctx, &kinv, &r)) { + goto err; + } + + if (digest_len > 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 + digest_len = BN_num_bytes(dsa->q); + } + + if (BN_bin2bn(digest, digest_len, &m) == NULL) { + goto err; + } + + // Compute s = inv(k) (m + xr) mod q + if (!BN_mod_mul(&xr, dsa->priv_key, r, dsa->q, ctx)) { + goto err; // s = xr + } + if (!BN_add(s, &xr, &m)) { + goto err; // s = m + xr + } + if (BN_cmp(s, dsa->q) > 0) { + if (!BN_sub(s, s, dsa->q)) { + goto err; + } + } + if (!BN_mod_mul(s, s, kinv, 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)) { + goto redo; + } + ret = DSA_SIG_new(); + if (ret == NULL) { + goto err; + } + ret->r = r; + ret->s = s; + +err: + if (ret == NULL) { + OPENSSL_PUT_ERROR(DSA, reason); + BN_free(r); + BN_free(s); + } + BN_CTX_free(ctx); + BN_clear_free(&m); + BN_clear_free(&xr); + BN_clear_free(kinv); + + return ret; +} + +int DSA_do_verify(const uint8_t *digest, size_t digest_len, DSA_SIG *sig, + const DSA *dsa) { + int valid; + if (!DSA_do_check_signature(&valid, digest, digest_len, sig, dsa)) { + return -1; + } + return valid; +} + +int DSA_do_check_signature(int *out_valid, const uint8_t *digest, + size_t digest_len, DSA_SIG *sig, const DSA *dsa) { + BN_CTX *ctx; + BIGNUM u1, u2, t1; + int ret = 0; + unsigned i; + + *out_valid = 0; + + if (!dsa->p || !dsa->q || !dsa->g) { + OPENSSL_PUT_ERROR(DSA, DSA_R_MISSING_PARAMETERS); + return 0; + } + + i = BN_num_bits(dsa->q); + // fips 186-3 allows only different sizes for q + if (i != 160 && i != 224 && i != 256) { + OPENSSL_PUT_ERROR(DSA, DSA_R_BAD_Q_VALUE); + return 0; + } + + if (BN_num_bits(dsa->p) > OPENSSL_DSA_MAX_MODULUS_BITS) { + OPENSSL_PUT_ERROR(DSA, DSA_R_MODULUS_TOO_LARGE); + return 0; + } + + BN_init(&u1); + BN_init(&u2); + BN_init(&t1); + + ctx = BN_CTX_new(); + if (ctx == NULL) { + goto err; + } + + if (BN_is_zero(sig->r) || BN_is_negative(sig->r) || + BN_ucmp(sig->r, dsa->q) >= 0) { + ret = 1; + goto err; + } + if (BN_is_zero(sig->s) || BN_is_negative(sig->s) || + BN_ucmp(sig->s, dsa->q) >= 0) { + ret = 1; + 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 (digest_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 + digest_len = (i >> 3); + } + + if (BN_bin2bn(digest, digest_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 (!BN_MONT_CTX_set_locked((BN_MONT_CTX **)&dsa->method_mont_p, + (CRYPTO_MUTEX *)&dsa->method_mont_lock, dsa->p, + ctx)) { + goto err; + } + + if (!BN_mod_exp2_mont(&t1, dsa->g, &u1, dsa->pub_key, &u2, dsa->p, ctx, + dsa->method_mont_p)) { + goto err; + } + + // 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. + *out_valid = BN_ucmp(&u1, sig->r) == 0; + ret = 1; + +err: + if (ret != 1) { + OPENSSL_PUT_ERROR(DSA, ERR_R_BN_LIB); + } + BN_CTX_free(ctx); + BN_free(&u1); + BN_free(&u2); + BN_free(&t1); + + return ret; +} + +int DSA_sign(int type, const uint8_t *digest, size_t digest_len, + uint8_t *out_sig, unsigned int *out_siglen, const DSA *dsa) { + DSA_SIG *s; + + s = DSA_do_sign(digest, digest_len, dsa); + if (s == NULL) { + *out_siglen = 0; + return 0; + } + + *out_siglen = i2d_DSA_SIG(s, &out_sig); + DSA_SIG_free(s); + return 1; +} + +int DSA_verify(int type, const uint8_t *digest, size_t digest_len, + const uint8_t *sig, size_t sig_len, const DSA *dsa) { + int valid; + if (!DSA_check_signature(&valid, digest, digest_len, sig, sig_len, dsa)) { + return -1; + } + return valid; +} + +int DSA_check_signature(int *out_valid, const uint8_t *digest, + size_t digest_len, const uint8_t *sig, size_t sig_len, + const DSA *dsa) { + DSA_SIG *s = NULL; + int ret = 0; + uint8_t *der = NULL; + + s = DSA_SIG_new(); + if (s == NULL) { + goto err; + } + + const uint8_t *sigp = sig; + if (d2i_DSA_SIG(&s, &sigp, sig_len) == NULL || sigp != sig + sig_len) { + goto err; + } + + // Ensure that the signature uses DER and doesn't have trailing garbage. + int der_len = i2d_DSA_SIG(s, &der); + if (der_len < 0 || (size_t)der_len != sig_len || + OPENSSL_memcmp(sig, der, sig_len)) { + goto err; + } + + ret = DSA_do_check_signature(out_valid, digest, digest_len, s, dsa); + +err: + OPENSSL_free(der); + DSA_SIG_free(s); + return ret; +} + +// der_len_len returns the number of bytes needed to represent a length of |len| +// in DER. +static size_t der_len_len(size_t len) { + if (len < 0x80) { + return 1; + } + size_t ret = 1; + while (len > 0) { + ret++; + len >>= 8; + } + return ret; +} + +int DSA_size(const DSA *dsa) { + size_t order_len = BN_num_bytes(dsa->q); + // Compute the maximum length of an |order_len| byte integer. Defensively + // assume that the leading 0x00 is included. + size_t integer_len = 1 /* tag */ + der_len_len(order_len + 1) + 1 + order_len; + if (integer_len < order_len) { + return 0; + } + // A DSA signature is two INTEGERs. + size_t value_len = 2 * integer_len; + if (value_len < integer_len) { + return 0; + } + // Add the header. + size_t ret = 1 /* tag */ + der_len_len(value_len) + value_len; + if (ret < value_len) { + return 0; + } + return ret; +} + +static int dsa_sign_setup(const DSA *dsa, BN_CTX *ctx_in, BIGNUM **out_kinv, + BIGNUM **out_r) { + BN_CTX *ctx; + BIGNUM k, *kinv = NULL, *r = NULL; + int ret = 0; + + if (!dsa->p || !dsa->q || !dsa->g) { + OPENSSL_PUT_ERROR(DSA, DSA_R_MISSING_PARAMETERS); + return 0; + } + + BN_init(&k); + + ctx = ctx_in; + if (ctx == NULL) { + ctx = BN_CTX_new(); + if (ctx == NULL) { + goto err; + } + } + + r = BN_new(); + kinv = BN_new(); + if (r == NULL || kinv == NULL || + // Get random k + !BN_rand_range_ex(&k, 1, dsa->q) || + !BN_MONT_CTX_set_locked((BN_MONT_CTX **)&dsa->method_mont_p, + (CRYPTO_MUTEX *)&dsa->method_mont_lock, dsa->p, + ctx) || + !BN_MONT_CTX_set_locked((BN_MONT_CTX **)&dsa->method_mont_q, + (CRYPTO_MUTEX *)&dsa->method_mont_lock, dsa->q, + ctx) || + // Compute r = (g^k mod p) mod q + !BN_mod_exp_mont_consttime(r, dsa->g, &k, dsa->p, ctx, + dsa->method_mont_p) || + !BN_mod(r, r, dsa->q, ctx) || + // Compute part of 's = inv(k) (m + xr) mod q' using Fermat's Little + // Theorem. + !bn_mod_inverse_prime(kinv, &k, dsa->q, ctx, dsa->method_mont_q)) { + goto err; + } + + BN_clear_free(*out_kinv); + *out_kinv = kinv; + kinv = NULL; + BN_clear_free(*out_r); + *out_r = r; + ret = 1; + +err: + if (!ret) { + OPENSSL_PUT_ERROR(DSA, 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(kinv); + return ret; +} + +int DSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused *unused, + CRYPTO_EX_dup *dup_unused, CRYPTO_EX_free *free_func) { + int index; + if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp, + free_func)) { + return -1; + } + return index; +} + +int DSA_set_ex_data(DSA *dsa, int idx, void *arg) { + return CRYPTO_set_ex_data(&dsa->ex_data, idx, arg); +} + +void *DSA_get_ex_data(const DSA *dsa, int idx) { + return CRYPTO_get_ex_data(&dsa->ex_data, idx); +} + +DH *DSA_dup_DH(const DSA *dsa) { + if (dsa == NULL) { + return NULL; + } + + DH *ret = DH_new(); + if (ret == NULL) { + goto err; + } + if (dsa->q != NULL) { + ret->priv_length = BN_num_bits(dsa->q); + if ((ret->q = BN_dup(dsa->q)) == NULL) { + goto err; + } + } + if ((dsa->p != NULL && (ret->p = BN_dup(dsa->p)) == NULL) || + (dsa->g != NULL && (ret->g = BN_dup(dsa->g)) == NULL) || + (dsa->pub_key != NULL && (ret->pub_key = BN_dup(dsa->pub_key)) == NULL) || + (dsa->priv_key != NULL && + (ret->priv_key = BN_dup(dsa->priv_key)) == NULL)) { + goto err; + } + + return ret; + +err: + DH_free(ret); + return NULL; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/dsa/dsa.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/dsa/dsa.c.grpc_back new file mode 100644 index 0000000..b97806b --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/dsa/dsa.c.grpc_back @@ -0,0 +1,946 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 . */ + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../fipsmodule/bn/internal.h" +#include "../internal.h" + + +#define OPENSSL_DSA_MAX_MODULUS_BITS 10000 + +// Primality test according to FIPS PUB 186[-1], Appendix 2.1: 50 rounds of +// Rabin-Miller +#define DSS_prime_checks 50 + +static int dsa_sign_setup(const DSA *dsa, BN_CTX *ctx_in, BIGNUM **out_kinv, + BIGNUM **out_r); + +static CRYPTO_EX_DATA_CLASS g_ex_data_class = CRYPTO_EX_DATA_CLASS_INIT; + +DSA *DSA_new(void) { + DSA *dsa = OPENSSL_malloc(sizeof(DSA)); + if (dsa == NULL) { + OPENSSL_PUT_ERROR(DSA, ERR_R_MALLOC_FAILURE); + return NULL; + } + + OPENSSL_memset(dsa, 0, sizeof(DSA)); + + dsa->references = 1; + + CRYPTO_MUTEX_init(&dsa->method_mont_lock); + CRYPTO_new_ex_data(&dsa->ex_data); + + return dsa; +} + +void DSA_free(DSA *dsa) { + if (dsa == NULL) { + return; + } + + if (!CRYPTO_refcount_dec_and_test_zero(&dsa->references)) { + return; + } + + CRYPTO_free_ex_data(&g_ex_data_class, dsa, &dsa->ex_data); + + BN_clear_free(dsa->p); + BN_clear_free(dsa->q); + BN_clear_free(dsa->g); + BN_clear_free(dsa->pub_key); + BN_clear_free(dsa->priv_key); + BN_MONT_CTX_free(dsa->method_mont_p); + BN_MONT_CTX_free(dsa->method_mont_q); + CRYPTO_MUTEX_cleanup(&dsa->method_mont_lock); + OPENSSL_free(dsa); +} + +int DSA_up_ref(DSA *dsa) { + CRYPTO_refcount_inc(&dsa->references); + return 1; +} + +void DSA_get0_key(const DSA *dsa, const BIGNUM **out_pub_key, + const BIGNUM **out_priv_key) { + if (out_pub_key != NULL) { + *out_pub_key = dsa->pub_key; + } + if (out_priv_key != NULL) { + *out_priv_key = dsa->priv_key; + } +} + +void DSA_get0_pqg(const DSA *dsa, const BIGNUM **out_p, const BIGNUM **out_q, + const BIGNUM **out_g) { + if (out_p != NULL) { + *out_p = dsa->p; + } + if (out_q != NULL) { + *out_q = dsa->q; + } + if (out_g != NULL) { + *out_g = dsa->g; + } +} + +int DSA_set0_key(DSA *dsa, BIGNUM *pub_key, BIGNUM *priv_key) { + if (dsa->pub_key == NULL && pub_key == NULL) { + return 0; + } + + if (pub_key != NULL) { + BN_free(dsa->pub_key); + dsa->pub_key = pub_key; + } + if (priv_key != NULL) { + BN_free(dsa->priv_key); + dsa->priv_key = priv_key; + } + + return 1; +} + +int DSA_set0_pqg(DSA *dsa, BIGNUM *p, BIGNUM *q, BIGNUM *g) { + if ((dsa->p == NULL && p == NULL) || + (dsa->q == NULL && q == NULL) || + (dsa->g == NULL && g == NULL)) { + return 0; + } + + if (p != NULL) { + BN_free(dsa->p); + dsa->p = p; + } + if (q != NULL) { + BN_free(dsa->q); + dsa->q = q; + } + if (g != NULL) { + BN_free(dsa->g); + dsa->g = g; + } + + return 1; +} + +int DSA_generate_parameters_ex(DSA *dsa, unsigned bits, const uint8_t *seed_in, + size_t seed_len, int *out_counter, + unsigned long *out_h, 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 k, n = 0, m = 0; + unsigned i; + int counter = 0; + int r = 0; + BN_CTX *ctx = NULL; + unsigned int h = 2; + unsigned qsize; + const EVP_MD *evpmd; + + evpmd = (bits >= 2048) ? EVP_sha256() : EVP_sha1(); + qsize = EVP_MD_size(evpmd); + + if (bits < 512) { + bits = 512; + } + + bits = (bits + 63) / 64 * 64; + + if (seed_in != NULL) { + if (seed_len < (size_t)qsize) { + return 0; + } + if (seed_len > (size_t)qsize) { + // Only consume as much seed as is expected. + seed_len = qsize; + } + OPENSSL_memcpy(seed, seed_in, seed_len); + } + + ctx = BN_CTX_new(); + if (ctx == 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 || !BN_lshift(test, BN_value_one(), bits - 1)) { + goto err; + } + + for (;;) { + // Find q. + for (;;) { + // step 1 + if (!BN_GENCB_call(cb, 0, m++)) { + goto err; + } + + int use_random_seed = (seed_in == NULL); + if (use_random_seed) { + if (!RAND_bytes(seed, qsize)) { + goto err; + } + } else { + // If we come back through, use random seed next time. + seed_in = NULL; + } + OPENSSL_memcpy(buf, seed, qsize); + OPENSSL_memcpy(buf2, seed, qsize); + // precompute "SEED + 1" for step 7: + for (i = qsize - 1; i < qsize; i--) { + buf[i]++; + if (buf[i] != 0) { + break; + } + } + + // step 2 + if (!EVP_Digest(seed, qsize, md, NULL, evpmd, NULL) || + !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, use_random_seed, cb); + if (r > 0) { + break; + } + if (r != 0) { + goto err; + } + + // do a callback call + // step 5 + } + + if (!BN_GENCB_call(cb, 2, 0) || !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 < qsize; 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) || + !BN_lshift(r0, r0, (qsize << 3) * k) || + !BN_add(W, W, r0)) { + goto err; + } + } + + // more of step 8 + if (!BN_mask_bits(W, bits - 1) || + !BN_copy(X, W) || + !BN_add(X, X, test)) { + goto err; + } + + // step 9 + if (!BN_lshift1(r0, q) || + !BN_mod(c, X, r0, ctx) || + !BN_sub(r0, c, BN_value_one()) || + !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()) || + !BN_div(r0, NULL, test, q, ctx)) { + goto err; + } + + mont = BN_MONT_CTX_new_for_modulus(p, ctx); + if (mont == NULL || + !BN_set_word(test, h)) { + 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) { + BN_free(dsa->p); + BN_free(dsa->q); + BN_free(dsa->g); + dsa->p = BN_dup(p); + dsa->q = BN_dup(q); + dsa->g = BN_dup(g); + if (dsa->p == NULL || dsa->q == NULL || dsa->g == NULL) { + ok = 0; + goto err; + } + if (out_counter != NULL) { + *out_counter = counter; + } + if (out_h != NULL) { + *out_h = h; + } + } + + if (ctx) { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + + BN_MONT_CTX_free(mont); + + return ok; +} + +DSA *DSAparams_dup(const DSA *dsa) { + DSA *ret = DSA_new(); + if (ret == NULL) { + return NULL; + } + ret->p = BN_dup(dsa->p); + ret->q = BN_dup(dsa->q); + ret->g = BN_dup(dsa->g); + if (ret->p == NULL || ret->q == NULL || ret->g == NULL) { + DSA_free(ret); + return NULL; + } + return ret; +} + +int DSA_generate_key(DSA *dsa) { + int ok = 0; + BN_CTX *ctx = NULL; + BIGNUM *pub_key = NULL, *priv_key = NULL; + + ctx = BN_CTX_new(); + if (ctx == NULL) { + goto err; + } + + priv_key = dsa->priv_key; + if (priv_key == NULL) { + priv_key = BN_new(); + if (priv_key == NULL) { + goto err; + } + } + + if (!BN_rand_range_ex(priv_key, 1, dsa->q)) { + goto err; + } + + pub_key = dsa->pub_key; + if (pub_key == NULL) { + pub_key = BN_new(); + if (pub_key == NULL) { + goto err; + } + } + + if (!BN_MONT_CTX_set_locked(&dsa->method_mont_p, &dsa->method_mont_lock, + dsa->p, ctx) || + !BN_mod_exp_mont_consttime(pub_key, dsa->g, priv_key, dsa->p, ctx, + dsa->method_mont_p)) { + goto err; + } + + dsa->priv_key = priv_key; + dsa->pub_key = pub_key; + ok = 1; + +err: + if (dsa->pub_key == NULL) { + BN_free(pub_key); + } + if (dsa->priv_key == NULL) { + BN_free(priv_key); + } + BN_CTX_free(ctx); + + return ok; +} + +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) { + return; + } + + BN_free(sig->r); + BN_free(sig->s); + OPENSSL_free(sig); +} + +DSA_SIG *DSA_do_sign(const uint8_t *digest, size_t digest_len, const DSA *dsa) { + BIGNUM *kinv = NULL, *r = NULL, *s = NULL; + BIGNUM m; + BIGNUM xr; + BN_CTX *ctx = NULL; + int reason = ERR_R_BN_LIB; + DSA_SIG *ret = NULL; + + BN_init(&m); + BN_init(&xr); + + if (!dsa->p || !dsa->q || !dsa->g) { + reason = DSA_R_MISSING_PARAMETERS; + goto err; + } + + s = BN_new(); + if (s == NULL) { + goto err; + } + ctx = BN_CTX_new(); + if (ctx == NULL) { + goto err; + } + +redo: + if (!dsa_sign_setup(dsa, ctx, &kinv, &r)) { + goto err; + } + + if (digest_len > 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 + digest_len = BN_num_bytes(dsa->q); + } + + if (BN_bin2bn(digest, digest_len, &m) == NULL) { + goto err; + } + + // Compute s = inv(k) (m + xr) mod q + if (!BN_mod_mul(&xr, dsa->priv_key, r, dsa->q, ctx)) { + goto err; // s = xr + } + if (!BN_add(s, &xr, &m)) { + goto err; // s = m + xr + } + if (BN_cmp(s, dsa->q) > 0) { + if (!BN_sub(s, s, dsa->q)) { + goto err; + } + } + if (!BN_mod_mul(s, s, kinv, 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)) { + goto redo; + } + ret = DSA_SIG_new(); + if (ret == NULL) { + goto err; + } + ret->r = r; + ret->s = s; + +err: + if (ret == NULL) { + OPENSSL_PUT_ERROR(DSA, reason); + BN_free(r); + BN_free(s); + } + BN_CTX_free(ctx); + BN_clear_free(&m); + BN_clear_free(&xr); + BN_clear_free(kinv); + + return ret; +} + +int DSA_do_verify(const uint8_t *digest, size_t digest_len, DSA_SIG *sig, + const DSA *dsa) { + int valid; + if (!DSA_do_check_signature(&valid, digest, digest_len, sig, dsa)) { + return -1; + } + return valid; +} + +int DSA_do_check_signature(int *out_valid, const uint8_t *digest, + size_t digest_len, DSA_SIG *sig, const DSA *dsa) { + BN_CTX *ctx; + BIGNUM u1, u2, t1; + int ret = 0; + unsigned i; + + *out_valid = 0; + + if (!dsa->p || !dsa->q || !dsa->g) { + OPENSSL_PUT_ERROR(DSA, DSA_R_MISSING_PARAMETERS); + return 0; + } + + i = BN_num_bits(dsa->q); + // fips 186-3 allows only different sizes for q + if (i != 160 && i != 224 && i != 256) { + OPENSSL_PUT_ERROR(DSA, DSA_R_BAD_Q_VALUE); + return 0; + } + + if (BN_num_bits(dsa->p) > OPENSSL_DSA_MAX_MODULUS_BITS) { + OPENSSL_PUT_ERROR(DSA, DSA_R_MODULUS_TOO_LARGE); + return 0; + } + + BN_init(&u1); + BN_init(&u2); + BN_init(&t1); + + ctx = BN_CTX_new(); + if (ctx == NULL) { + goto err; + } + + if (BN_is_zero(sig->r) || BN_is_negative(sig->r) || + BN_ucmp(sig->r, dsa->q) >= 0) { + ret = 1; + goto err; + } + if (BN_is_zero(sig->s) || BN_is_negative(sig->s) || + BN_ucmp(sig->s, dsa->q) >= 0) { + ret = 1; + 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 (digest_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 + digest_len = (i >> 3); + } + + if (BN_bin2bn(digest, digest_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 (!BN_MONT_CTX_set_locked((BN_MONT_CTX **)&dsa->method_mont_p, + (CRYPTO_MUTEX *)&dsa->method_mont_lock, dsa->p, + ctx)) { + goto err; + } + + if (!BN_mod_exp2_mont(&t1, dsa->g, &u1, dsa->pub_key, &u2, dsa->p, ctx, + dsa->method_mont_p)) { + goto err; + } + + // 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. + *out_valid = BN_ucmp(&u1, sig->r) == 0; + ret = 1; + +err: + if (ret != 1) { + OPENSSL_PUT_ERROR(DSA, ERR_R_BN_LIB); + } + BN_CTX_free(ctx); + BN_free(&u1); + BN_free(&u2); + BN_free(&t1); + + return ret; +} + +int DSA_sign(int type, const uint8_t *digest, size_t digest_len, + uint8_t *out_sig, unsigned int *out_siglen, const DSA *dsa) { + DSA_SIG *s; + + s = DSA_do_sign(digest, digest_len, dsa); + if (s == NULL) { + *out_siglen = 0; + return 0; + } + + *out_siglen = i2d_DSA_SIG(s, &out_sig); + DSA_SIG_free(s); + return 1; +} + +int DSA_verify(int type, const uint8_t *digest, size_t digest_len, + const uint8_t *sig, size_t sig_len, const DSA *dsa) { + int valid; + if (!DSA_check_signature(&valid, digest, digest_len, sig, sig_len, dsa)) { + return -1; + } + return valid; +} + +int DSA_check_signature(int *out_valid, const uint8_t *digest, + size_t digest_len, const uint8_t *sig, size_t sig_len, + const DSA *dsa) { + DSA_SIG *s = NULL; + int ret = 0; + uint8_t *der = NULL; + + s = DSA_SIG_new(); + if (s == NULL) { + goto err; + } + + const uint8_t *sigp = sig; + if (d2i_DSA_SIG(&s, &sigp, sig_len) == NULL || sigp != sig + sig_len) { + goto err; + } + + // Ensure that the signature uses DER and doesn't have trailing garbage. + int der_len = i2d_DSA_SIG(s, &der); + if (der_len < 0 || (size_t)der_len != sig_len || + OPENSSL_memcmp(sig, der, sig_len)) { + goto err; + } + + ret = DSA_do_check_signature(out_valid, digest, digest_len, s, dsa); + +err: + OPENSSL_free(der); + DSA_SIG_free(s); + return ret; +} + +// der_len_len returns the number of bytes needed to represent a length of |len| +// in DER. +static size_t der_len_len(size_t len) { + if (len < 0x80) { + return 1; + } + size_t ret = 1; + while (len > 0) { + ret++; + len >>= 8; + } + return ret; +} + +int DSA_size(const DSA *dsa) { + size_t order_len = BN_num_bytes(dsa->q); + // Compute the maximum length of an |order_len| byte integer. Defensively + // assume that the leading 0x00 is included. + size_t integer_len = 1 /* tag */ + der_len_len(order_len + 1) + 1 + order_len; + if (integer_len < order_len) { + return 0; + } + // A DSA signature is two INTEGERs. + size_t value_len = 2 * integer_len; + if (value_len < integer_len) { + return 0; + } + // Add the header. + size_t ret = 1 /* tag */ + der_len_len(value_len) + value_len; + if (ret < value_len) { + return 0; + } + return ret; +} + +static int dsa_sign_setup(const DSA *dsa, BN_CTX *ctx_in, BIGNUM **out_kinv, + BIGNUM **out_r) { + BN_CTX *ctx; + BIGNUM k, *kinv = NULL, *r = NULL; + int ret = 0; + + if (!dsa->p || !dsa->q || !dsa->g) { + OPENSSL_PUT_ERROR(DSA, DSA_R_MISSING_PARAMETERS); + return 0; + } + + BN_init(&k); + + ctx = ctx_in; + if (ctx == NULL) { + ctx = BN_CTX_new(); + if (ctx == NULL) { + goto err; + } + } + + r = BN_new(); + kinv = BN_new(); + if (r == NULL || kinv == NULL || + // Get random k + !BN_rand_range_ex(&k, 1, dsa->q) || + !BN_MONT_CTX_set_locked((BN_MONT_CTX **)&dsa->method_mont_p, + (CRYPTO_MUTEX *)&dsa->method_mont_lock, dsa->p, + ctx) || + !BN_MONT_CTX_set_locked((BN_MONT_CTX **)&dsa->method_mont_q, + (CRYPTO_MUTEX *)&dsa->method_mont_lock, dsa->q, + ctx) || + // Compute r = (g^k mod p) mod q + !BN_mod_exp_mont_consttime(r, dsa->g, &k, dsa->p, ctx, + dsa->method_mont_p) || + !BN_mod(r, r, dsa->q, ctx) || + // Compute part of 's = inv(k) (m + xr) mod q' using Fermat's Little + // Theorem. + !bn_mod_inverse_prime(kinv, &k, dsa->q, ctx, dsa->method_mont_q)) { + goto err; + } + + BN_clear_free(*out_kinv); + *out_kinv = kinv; + kinv = NULL; + BN_clear_free(*out_r); + *out_r = r; + ret = 1; + +err: + if (!ret) { + OPENSSL_PUT_ERROR(DSA, 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(kinv); + return ret; +} + +int DSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused *unused, + CRYPTO_EX_dup *dup_unused, CRYPTO_EX_free *free_func) { + int index; + if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp, + free_func)) { + return -1; + } + return index; +} + +int DSA_set_ex_data(DSA *dsa, int idx, void *arg) { + return CRYPTO_set_ex_data(&dsa->ex_data, idx, arg); +} + +void *DSA_get_ex_data(const DSA *dsa, int idx) { + return CRYPTO_get_ex_data(&dsa->ex_data, idx); +} + +DH *DSA_dup_DH(const DSA *dsa) { + if (dsa == NULL) { + return NULL; + } + + DH *ret = DH_new(); + if (ret == NULL) { + goto err; + } + if (dsa->q != NULL) { + ret->priv_length = BN_num_bits(dsa->q); + if ((ret->q = BN_dup(dsa->q)) == NULL) { + goto err; + } + } + if ((dsa->p != NULL && (ret->p = BN_dup(dsa->p)) == NULL) || + (dsa->g != NULL && (ret->g = BN_dup(dsa->g)) == NULL) || + (dsa->pub_key != NULL && (ret->pub_key = BN_dup(dsa->pub_key)) == NULL) || + (dsa->priv_key != NULL && + (ret->priv_key = BN_dup(dsa->priv_key)) == NULL)) { + goto err; + } + + return ret; + +err: + DH_free(ret); + return NULL; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/dsa/dsa_asn1.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/dsa/dsa_asn1.c new file mode 100644 index 0000000..2f62503 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/dsa/dsa_asn1.c @@ -0,0 +1,339 @@ +/* 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 + +#include +#include +#include +#include + +#include "../bytestring/internal.h" + + +static int parse_integer(CBS *cbs, BIGNUM **out) { + assert(*out == NULL); + *out = BN_new(); + if (*out == NULL) { + return 0; + } + return BN_parse_asn1_unsigned(cbs, *out); +} + +static int marshal_integer(CBB *cbb, BIGNUM *bn) { + if (bn == NULL) { + // A DSA object may be missing some components. + OPENSSL_PUT_ERROR(DSA, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + return BN_marshal_asn1(cbb, bn); +} + +DSA_SIG *DSA_SIG_parse(CBS *cbs) { + DSA_SIG *ret = DSA_SIG_new(); + if (ret == NULL) { + return NULL; + } + CBS child; + if (!CBS_get_asn1(cbs, &child, CBS_ASN1_SEQUENCE) || + !parse_integer(&child, &ret->r) || + !parse_integer(&child, &ret->s) || + CBS_len(&child) != 0) { + OPENSSL_PUT_ERROR(DSA, DSA_R_DECODE_ERROR); + DSA_SIG_free(ret); + return NULL; + } + return ret; +} + +int DSA_SIG_marshal(CBB *cbb, const DSA_SIG *sig) { + CBB child; + if (!CBB_add_asn1(cbb, &child, CBS_ASN1_SEQUENCE) || + !marshal_integer(&child, sig->r) || + !marshal_integer(&child, sig->s) || + !CBB_flush(cbb)) { + OPENSSL_PUT_ERROR(DSA, DSA_R_ENCODE_ERROR); + return 0; + } + return 1; +} + +DSA *DSA_parse_public_key(CBS *cbs) { + DSA *ret = DSA_new(); + if (ret == NULL) { + return NULL; + } + CBS child; + if (!CBS_get_asn1(cbs, &child, CBS_ASN1_SEQUENCE) || + !parse_integer(&child, &ret->pub_key) || + !parse_integer(&child, &ret->p) || + !parse_integer(&child, &ret->q) || + !parse_integer(&child, &ret->g) || + CBS_len(&child) != 0) { + OPENSSL_PUT_ERROR(DSA, DSA_R_DECODE_ERROR); + DSA_free(ret); + return NULL; + } + return ret; +} + +int DSA_marshal_public_key(CBB *cbb, const DSA *dsa) { + CBB child; + if (!CBB_add_asn1(cbb, &child, CBS_ASN1_SEQUENCE) || + !marshal_integer(&child, dsa->pub_key) || + !marshal_integer(&child, dsa->p) || + !marshal_integer(&child, dsa->q) || + !marshal_integer(&child, dsa->g) || + !CBB_flush(cbb)) { + OPENSSL_PUT_ERROR(DSA, DSA_R_ENCODE_ERROR); + return 0; + } + return 1; +} + +DSA *DSA_parse_parameters(CBS *cbs) { + DSA *ret = DSA_new(); + if (ret == NULL) { + return NULL; + } + CBS child; + if (!CBS_get_asn1(cbs, &child, CBS_ASN1_SEQUENCE) || + !parse_integer(&child, &ret->p) || + !parse_integer(&child, &ret->q) || + !parse_integer(&child, &ret->g) || + CBS_len(&child) != 0) { + OPENSSL_PUT_ERROR(DSA, DSA_R_DECODE_ERROR); + DSA_free(ret); + return NULL; + } + return ret; +} + +int DSA_marshal_parameters(CBB *cbb, const DSA *dsa) { + CBB child; + if (!CBB_add_asn1(cbb, &child, CBS_ASN1_SEQUENCE) || + !marshal_integer(&child, dsa->p) || + !marshal_integer(&child, dsa->q) || + !marshal_integer(&child, dsa->g) || + !CBB_flush(cbb)) { + OPENSSL_PUT_ERROR(DSA, DSA_R_ENCODE_ERROR); + return 0; + } + return 1; +} + +DSA *DSA_parse_private_key(CBS *cbs) { + DSA *ret = DSA_new(); + if (ret == NULL) { + return NULL; + } + + CBS child; + uint64_t version; + if (!CBS_get_asn1(cbs, &child, CBS_ASN1_SEQUENCE) || + !CBS_get_asn1_uint64(&child, &version)) { + OPENSSL_PUT_ERROR(DSA, DSA_R_DECODE_ERROR); + goto err; + } + + if (version != 0) { + OPENSSL_PUT_ERROR(DSA, DSA_R_BAD_VERSION); + goto err; + } + + if (!parse_integer(&child, &ret->p) || + !parse_integer(&child, &ret->q) || + !parse_integer(&child, &ret->g) || + !parse_integer(&child, &ret->pub_key) || + !parse_integer(&child, &ret->priv_key) || + CBS_len(&child) != 0) { + OPENSSL_PUT_ERROR(DSA, DSA_R_DECODE_ERROR); + goto err; + } + return ret; + +err: + DSA_free(ret); + return NULL; +} + +int DSA_marshal_private_key(CBB *cbb, const DSA *dsa) { + CBB child; + if (!CBB_add_asn1(cbb, &child, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1_uint64(&child, 0 /* version */) || + !marshal_integer(&child, dsa->p) || + !marshal_integer(&child, dsa->q) || + !marshal_integer(&child, dsa->g) || + !marshal_integer(&child, dsa->pub_key) || + !marshal_integer(&child, dsa->priv_key) || + !CBB_flush(cbb)) { + OPENSSL_PUT_ERROR(DSA, DSA_R_ENCODE_ERROR); + return 0; + } + return 1; +} + +DSA_SIG *d2i_DSA_SIG(DSA_SIG **out_sig, const uint8_t **inp, long len) { + if (len < 0) { + return NULL; + } + CBS cbs; + CBS_init(&cbs, *inp, (size_t)len); + DSA_SIG *ret = DSA_SIG_parse(&cbs); + if (ret == NULL) { + return NULL; + } + if (out_sig != NULL) { + DSA_SIG_free(*out_sig); + *out_sig = ret; + } + *inp = CBS_data(&cbs); + return ret; +} + +int i2d_DSA_SIG(const DSA_SIG *in, uint8_t **outp) { + CBB cbb; + if (!CBB_init(&cbb, 0) || + !DSA_SIG_marshal(&cbb, in)) { + CBB_cleanup(&cbb); + return -1; + } + return CBB_finish_i2d(&cbb, outp); +} + +DSA *d2i_DSAPublicKey(DSA **out, const uint8_t **inp, long len) { + if (len < 0) { + return NULL; + } + CBS cbs; + CBS_init(&cbs, *inp, (size_t)len); + DSA *ret = DSA_parse_public_key(&cbs); + if (ret == NULL) { + return NULL; + } + if (out != NULL) { + DSA_free(*out); + *out = ret; + } + *inp = CBS_data(&cbs); + return ret; +} + +int i2d_DSAPublicKey(const DSA *in, uint8_t **outp) { + CBB cbb; + if (!CBB_init(&cbb, 0) || + !DSA_marshal_public_key(&cbb, in)) { + CBB_cleanup(&cbb); + return -1; + } + return CBB_finish_i2d(&cbb, outp); +} + +DSA *d2i_DSAPrivateKey(DSA **out, const uint8_t **inp, long len) { + if (len < 0) { + return NULL; + } + CBS cbs; + CBS_init(&cbs, *inp, (size_t)len); + DSA *ret = DSA_parse_private_key(&cbs); + if (ret == NULL) { + return NULL; + } + if (out != NULL) { + DSA_free(*out); + *out = ret; + } + *inp = CBS_data(&cbs); + return ret; +} + +int i2d_DSAPrivateKey(const DSA *in, uint8_t **outp) { + CBB cbb; + if (!CBB_init(&cbb, 0) || + !DSA_marshal_private_key(&cbb, in)) { + CBB_cleanup(&cbb); + return -1; + } + return CBB_finish_i2d(&cbb, outp); +} + +DSA *d2i_DSAparams(DSA **out, const uint8_t **inp, long len) { + if (len < 0) { + return NULL; + } + CBS cbs; + CBS_init(&cbs, *inp, (size_t)len); + DSA *ret = DSA_parse_parameters(&cbs); + if (ret == NULL) { + return NULL; + } + if (out != NULL) { + DSA_free(*out); + *out = ret; + } + *inp = CBS_data(&cbs); + return ret; +} + +int i2d_DSAparams(const DSA *in, uint8_t **outp) { + CBB cbb; + if (!CBB_init(&cbb, 0) || + !DSA_marshal_parameters(&cbb, in)) { + CBB_cleanup(&cbb); + return -1; + } + return CBB_finish_i2d(&cbb, outp); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/dsa/dsa_asn1.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/dsa/dsa_asn1.c.grpc_back new file mode 100644 index 0000000..97fd07f --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/dsa/dsa_asn1.c.grpc_back @@ -0,0 +1,339 @@ +/* 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 + +#include +#include +#include +#include + +#include "../bytestring/internal.h" + + +static int parse_integer(CBS *cbs, BIGNUM **out) { + assert(*out == NULL); + *out = BN_new(); + if (*out == NULL) { + return 0; + } + return BN_parse_asn1_unsigned(cbs, *out); +} + +static int marshal_integer(CBB *cbb, BIGNUM *bn) { + if (bn == NULL) { + // A DSA object may be missing some components. + OPENSSL_PUT_ERROR(DSA, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + return BN_marshal_asn1(cbb, bn); +} + +DSA_SIG *DSA_SIG_parse(CBS *cbs) { + DSA_SIG *ret = DSA_SIG_new(); + if (ret == NULL) { + return NULL; + } + CBS child; + if (!CBS_get_asn1(cbs, &child, CBS_ASN1_SEQUENCE) || + !parse_integer(&child, &ret->r) || + !parse_integer(&child, &ret->s) || + CBS_len(&child) != 0) { + OPENSSL_PUT_ERROR(DSA, DSA_R_DECODE_ERROR); + DSA_SIG_free(ret); + return NULL; + } + return ret; +} + +int DSA_SIG_marshal(CBB *cbb, const DSA_SIG *sig) { + CBB child; + if (!CBB_add_asn1(cbb, &child, CBS_ASN1_SEQUENCE) || + !marshal_integer(&child, sig->r) || + !marshal_integer(&child, sig->s) || + !CBB_flush(cbb)) { + OPENSSL_PUT_ERROR(DSA, DSA_R_ENCODE_ERROR); + return 0; + } + return 1; +} + +DSA *DSA_parse_public_key(CBS *cbs) { + DSA *ret = DSA_new(); + if (ret == NULL) { + return NULL; + } + CBS child; + if (!CBS_get_asn1(cbs, &child, CBS_ASN1_SEQUENCE) || + !parse_integer(&child, &ret->pub_key) || + !parse_integer(&child, &ret->p) || + !parse_integer(&child, &ret->q) || + !parse_integer(&child, &ret->g) || + CBS_len(&child) != 0) { + OPENSSL_PUT_ERROR(DSA, DSA_R_DECODE_ERROR); + DSA_free(ret); + return NULL; + } + return ret; +} + +int DSA_marshal_public_key(CBB *cbb, const DSA *dsa) { + CBB child; + if (!CBB_add_asn1(cbb, &child, CBS_ASN1_SEQUENCE) || + !marshal_integer(&child, dsa->pub_key) || + !marshal_integer(&child, dsa->p) || + !marshal_integer(&child, dsa->q) || + !marshal_integer(&child, dsa->g) || + !CBB_flush(cbb)) { + OPENSSL_PUT_ERROR(DSA, DSA_R_ENCODE_ERROR); + return 0; + } + return 1; +} + +DSA *DSA_parse_parameters(CBS *cbs) { + DSA *ret = DSA_new(); + if (ret == NULL) { + return NULL; + } + CBS child; + if (!CBS_get_asn1(cbs, &child, CBS_ASN1_SEQUENCE) || + !parse_integer(&child, &ret->p) || + !parse_integer(&child, &ret->q) || + !parse_integer(&child, &ret->g) || + CBS_len(&child) != 0) { + OPENSSL_PUT_ERROR(DSA, DSA_R_DECODE_ERROR); + DSA_free(ret); + return NULL; + } + return ret; +} + +int DSA_marshal_parameters(CBB *cbb, const DSA *dsa) { + CBB child; + if (!CBB_add_asn1(cbb, &child, CBS_ASN1_SEQUENCE) || + !marshal_integer(&child, dsa->p) || + !marshal_integer(&child, dsa->q) || + !marshal_integer(&child, dsa->g) || + !CBB_flush(cbb)) { + OPENSSL_PUT_ERROR(DSA, DSA_R_ENCODE_ERROR); + return 0; + } + return 1; +} + +DSA *DSA_parse_private_key(CBS *cbs) { + DSA *ret = DSA_new(); + if (ret == NULL) { + return NULL; + } + + CBS child; + uint64_t version; + if (!CBS_get_asn1(cbs, &child, CBS_ASN1_SEQUENCE) || + !CBS_get_asn1_uint64(&child, &version)) { + OPENSSL_PUT_ERROR(DSA, DSA_R_DECODE_ERROR); + goto err; + } + + if (version != 0) { + OPENSSL_PUT_ERROR(DSA, DSA_R_BAD_VERSION); + goto err; + } + + if (!parse_integer(&child, &ret->p) || + !parse_integer(&child, &ret->q) || + !parse_integer(&child, &ret->g) || + !parse_integer(&child, &ret->pub_key) || + !parse_integer(&child, &ret->priv_key) || + CBS_len(&child) != 0) { + OPENSSL_PUT_ERROR(DSA, DSA_R_DECODE_ERROR); + goto err; + } + return ret; + +err: + DSA_free(ret); + return NULL; +} + +int DSA_marshal_private_key(CBB *cbb, const DSA *dsa) { + CBB child; + if (!CBB_add_asn1(cbb, &child, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1_uint64(&child, 0 /* version */) || + !marshal_integer(&child, dsa->p) || + !marshal_integer(&child, dsa->q) || + !marshal_integer(&child, dsa->g) || + !marshal_integer(&child, dsa->pub_key) || + !marshal_integer(&child, dsa->priv_key) || + !CBB_flush(cbb)) { + OPENSSL_PUT_ERROR(DSA, DSA_R_ENCODE_ERROR); + return 0; + } + return 1; +} + +DSA_SIG *d2i_DSA_SIG(DSA_SIG **out_sig, const uint8_t **inp, long len) { + if (len < 0) { + return NULL; + } + CBS cbs; + CBS_init(&cbs, *inp, (size_t)len); + DSA_SIG *ret = DSA_SIG_parse(&cbs); + if (ret == NULL) { + return NULL; + } + if (out_sig != NULL) { + DSA_SIG_free(*out_sig); + *out_sig = ret; + } + *inp = CBS_data(&cbs); + return ret; +} + +int i2d_DSA_SIG(const DSA_SIG *in, uint8_t **outp) { + CBB cbb; + if (!CBB_init(&cbb, 0) || + !DSA_SIG_marshal(&cbb, in)) { + CBB_cleanup(&cbb); + return -1; + } + return CBB_finish_i2d(&cbb, outp); +} + +DSA *d2i_DSAPublicKey(DSA **out, const uint8_t **inp, long len) { + if (len < 0) { + return NULL; + } + CBS cbs; + CBS_init(&cbs, *inp, (size_t)len); + DSA *ret = DSA_parse_public_key(&cbs); + if (ret == NULL) { + return NULL; + } + if (out != NULL) { + DSA_free(*out); + *out = ret; + } + *inp = CBS_data(&cbs); + return ret; +} + +int i2d_DSAPublicKey(const DSA *in, uint8_t **outp) { + CBB cbb; + if (!CBB_init(&cbb, 0) || + !DSA_marshal_public_key(&cbb, in)) { + CBB_cleanup(&cbb); + return -1; + } + return CBB_finish_i2d(&cbb, outp); +} + +DSA *d2i_DSAPrivateKey(DSA **out, const uint8_t **inp, long len) { + if (len < 0) { + return NULL; + } + CBS cbs; + CBS_init(&cbs, *inp, (size_t)len); + DSA *ret = DSA_parse_private_key(&cbs); + if (ret == NULL) { + return NULL; + } + if (out != NULL) { + DSA_free(*out); + *out = ret; + } + *inp = CBS_data(&cbs); + return ret; +} + +int i2d_DSAPrivateKey(const DSA *in, uint8_t **outp) { + CBB cbb; + if (!CBB_init(&cbb, 0) || + !DSA_marshal_private_key(&cbb, in)) { + CBB_cleanup(&cbb); + return -1; + } + return CBB_finish_i2d(&cbb, outp); +} + +DSA *d2i_DSAparams(DSA **out, const uint8_t **inp, long len) { + if (len < 0) { + return NULL; + } + CBS cbs; + CBS_init(&cbs, *inp, (size_t)len); + DSA *ret = DSA_parse_parameters(&cbs); + if (ret == NULL) { + return NULL; + } + if (out != NULL) { + DSA_free(*out); + *out = ret; + } + *inp = CBS_data(&cbs); + return ret; +} + +int i2d_DSAparams(const DSA *in, uint8_t **outp) { + CBB cbb; + if (!CBB_init(&cbb, 0) || + !DSA_marshal_parameters(&cbb, in)) { + CBB_cleanup(&cbb); + return -1; + } + return CBB_finish_i2d(&cbb, outp); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/ec_extra/ec_asn1.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/ec_extra/ec_asn1.c new file mode 100644 index 0000000..31b6c5f --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/ec_extra/ec_asn1.c @@ -0,0 +1,562 @@ +/* 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 +#include + +#include +#include +#include +#include +#include + +#include "../fipsmodule/ec/internal.h" +#include "../bytestring/internal.h" +#include "../internal.h" + + +static const unsigned kParametersTag = + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 0; +static const unsigned kPublicKeyTag = + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 1; + +EC_KEY *EC_KEY_parse_private_key(CBS *cbs, const EC_GROUP *group) { + CBS ec_private_key, private_key; + uint64_t version; + if (!CBS_get_asn1(cbs, &ec_private_key, CBS_ASN1_SEQUENCE) || + !CBS_get_asn1_uint64(&ec_private_key, &version) || + version != 1 || + !CBS_get_asn1(&ec_private_key, &private_key, CBS_ASN1_OCTETSTRING)) { + OPENSSL_PUT_ERROR(EC, EC_R_DECODE_ERROR); + return NULL; + } + + // Parse the optional parameters field. + EC_GROUP *inner_group = NULL; + EC_KEY *ret = NULL; + BIGNUM *priv_key = NULL; + if (CBS_peek_asn1_tag(&ec_private_key, kParametersTag)) { + // Per SEC 1, as an alternative to omitting it, one is allowed to specify + // this field and put in a NULL to mean inheriting this value. This was + // omitted in a previous version of this logic without problems, so leave it + // unimplemented. + CBS child; + if (!CBS_get_asn1(&ec_private_key, &child, kParametersTag)) { + OPENSSL_PUT_ERROR(EC, EC_R_DECODE_ERROR); + goto err; + } + inner_group = EC_KEY_parse_parameters(&child); + if (inner_group == NULL) { + goto err; + } + if (group == NULL) { + group = inner_group; + } else if (EC_GROUP_cmp(group, inner_group, NULL) != 0) { + // If a group was supplied externally, it must match. + OPENSSL_PUT_ERROR(EC, EC_R_GROUP_MISMATCH); + goto err; + } + if (CBS_len(&child) != 0) { + OPENSSL_PUT_ERROR(EC, EC_R_DECODE_ERROR); + goto err; + } + } + + if (group == NULL) { + OPENSSL_PUT_ERROR(EC, EC_R_MISSING_PARAMETERS); + goto err; + } + + ret = EC_KEY_new(); + if (ret == NULL || !EC_KEY_set_group(ret, group)) { + goto err; + } + + // Although RFC 5915 specifies the length of the key, OpenSSL historically + // got this wrong, so accept any length. See upstream's + // 30cd4ff294252c4b6a4b69cbef6a5b4117705d22. + priv_key = BN_bin2bn(CBS_data(&private_key), CBS_len(&private_key), NULL); + ret->pub_key = EC_POINT_new(group); + if (priv_key == NULL || ret->pub_key == NULL || + !EC_KEY_set_private_key(ret, priv_key)) { + goto err; + } + + if (CBS_peek_asn1_tag(&ec_private_key, kPublicKeyTag)) { + CBS child, public_key; + uint8_t padding; + if (!CBS_get_asn1(&ec_private_key, &child, kPublicKeyTag) || + !CBS_get_asn1(&child, &public_key, CBS_ASN1_BITSTRING) || + // As in a SubjectPublicKeyInfo, the byte-encoded public key is then + // encoded as a BIT STRING with bits ordered as in the DER encoding. + !CBS_get_u8(&public_key, &padding) || + padding != 0 || + // Explicitly check |public_key| is non-empty to save the conversion + // form later. + CBS_len(&public_key) == 0 || + !EC_POINT_oct2point(group, ret->pub_key, CBS_data(&public_key), + CBS_len(&public_key), NULL) || + CBS_len(&child) != 0) { + OPENSSL_PUT_ERROR(EC, EC_R_DECODE_ERROR); + goto err; + } + + // Save the point conversion form. + // TODO(davidben): Consider removing this. + ret->conv_form = + (point_conversion_form_t)(CBS_data(&public_key)[0] & ~0x01); + } else { + // Compute the public key instead. + if (!ec_point_mul_scalar(group, ret->pub_key, &ret->priv_key->scalar, NULL, + NULL, NULL)) { + goto err; + } + // Remember the original private-key-only encoding. + // TODO(davidben): Consider removing this. + ret->enc_flag |= EC_PKEY_NO_PUBKEY; + } + + if (CBS_len(&ec_private_key) != 0) { + OPENSSL_PUT_ERROR(EC, EC_R_DECODE_ERROR); + goto err; + } + + // Ensure the resulting key is valid. + if (!EC_KEY_check_key(ret)) { + goto err; + } + + BN_free(priv_key); + EC_GROUP_free(inner_group); + return ret; + +err: + EC_KEY_free(ret); + BN_free(priv_key); + EC_GROUP_free(inner_group); + return NULL; +} + +int EC_KEY_marshal_private_key(CBB *cbb, const EC_KEY *key, + unsigned enc_flags) { + if (key == NULL || key->group == NULL || key->priv_key == NULL) { + OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + CBB ec_private_key, private_key; + if (!CBB_add_asn1(cbb, &ec_private_key, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1_uint64(&ec_private_key, 1 /* version */) || + !CBB_add_asn1(&ec_private_key, &private_key, CBS_ASN1_OCTETSTRING) || + !BN_bn2cbb_padded(&private_key, + BN_num_bytes(EC_GROUP_get0_order(key->group)), + EC_KEY_get0_private_key(key))) { + OPENSSL_PUT_ERROR(EC, EC_R_ENCODE_ERROR); + return 0; + } + + if (!(enc_flags & EC_PKEY_NO_PARAMETERS)) { + CBB child; + if (!CBB_add_asn1(&ec_private_key, &child, kParametersTag) || + !EC_KEY_marshal_curve_name(&child, key->group) || + !CBB_flush(&ec_private_key)) { + OPENSSL_PUT_ERROR(EC, EC_R_ENCODE_ERROR); + return 0; + } + } + + // TODO(fork): replace this flexibility with sensible default? + if (!(enc_flags & EC_PKEY_NO_PUBKEY) && key->pub_key != NULL) { + CBB child, public_key; + if (!CBB_add_asn1(&ec_private_key, &child, kPublicKeyTag) || + !CBB_add_asn1(&child, &public_key, CBS_ASN1_BITSTRING) || + // As in a SubjectPublicKeyInfo, the byte-encoded public key is then + // encoded as a BIT STRING with bits ordered as in the DER encoding. + !CBB_add_u8(&public_key, 0 /* padding */) || + !EC_POINT_point2cbb(&public_key, key->group, key->pub_key, + key->conv_form, NULL) || + !CBB_flush(&ec_private_key)) { + OPENSSL_PUT_ERROR(EC, EC_R_ENCODE_ERROR); + return 0; + } + } + + if (!CBB_flush(cbb)) { + OPENSSL_PUT_ERROR(EC, EC_R_ENCODE_ERROR); + return 0; + } + + return 1; +} + +// is_unsigned_integer returns one if |cbs| is a valid unsigned DER INTEGER and +// zero otherwise. +static int is_unsigned_integer(const CBS *cbs) { + if (CBS_len(cbs) == 0) { + return 0; + } + uint8_t byte = CBS_data(cbs)[0]; + if ((byte & 0x80) || + (byte == 0 && CBS_len(cbs) > 1 && (CBS_data(cbs)[1] & 0x80) == 0)) { + // Negative or not minimally-encoded. + return 0; + } + return 1; +} + +// kPrimeFieldOID is the encoding of 1.2.840.10045.1.1. +static const uint8_t kPrimeField[] = {0x2a, 0x86, 0x48, 0xce, 0x3d, 0x01, 0x01}; + +static int parse_explicit_prime_curve(CBS *in, CBS *out_prime, CBS *out_a, + CBS *out_b, CBS *out_base_x, + CBS *out_base_y, CBS *out_order) { + // See RFC 3279, section 2.3.5. Note that RFC 3279 calls this structure an + // ECParameters while RFC 5480 calls it a SpecifiedECDomain. + CBS params, field_id, field_type, curve, base; + uint64_t version; + if (!CBS_get_asn1(in, ¶ms, CBS_ASN1_SEQUENCE) || + !CBS_get_asn1_uint64(¶ms, &version) || + version != 1 || + !CBS_get_asn1(¶ms, &field_id, CBS_ASN1_SEQUENCE) || + !CBS_get_asn1(&field_id, &field_type, CBS_ASN1_OBJECT) || + CBS_len(&field_type) != sizeof(kPrimeField) || + OPENSSL_memcmp(CBS_data(&field_type), kPrimeField, sizeof(kPrimeField)) != 0 || + !CBS_get_asn1(&field_id, out_prime, CBS_ASN1_INTEGER) || + !is_unsigned_integer(out_prime) || + CBS_len(&field_id) != 0 || + !CBS_get_asn1(¶ms, &curve, CBS_ASN1_SEQUENCE) || + !CBS_get_asn1(&curve, out_a, CBS_ASN1_OCTETSTRING) || + !CBS_get_asn1(&curve, out_b, CBS_ASN1_OCTETSTRING) || + // |curve| has an optional BIT STRING seed which we ignore. + !CBS_get_asn1(¶ms, &base, CBS_ASN1_OCTETSTRING) || + !CBS_get_asn1(¶ms, out_order, CBS_ASN1_INTEGER) || + !is_unsigned_integer(out_order)) { + OPENSSL_PUT_ERROR(EC, EC_R_DECODE_ERROR); + return 0; + } + + // |params| has an optional cofactor which we ignore. With the optional seed + // in |curve|, a group already has arbitrarily many encodings. Parse enough to + // uniquely determine the curve. + + // Require that the base point use uncompressed form. + uint8_t form; + if (!CBS_get_u8(&base, &form) || form != POINT_CONVERSION_UNCOMPRESSED) { + OPENSSL_PUT_ERROR(EC, EC_R_INVALID_FORM); + return 0; + } + + if (CBS_len(&base) % 2 != 0) { + OPENSSL_PUT_ERROR(EC, EC_R_DECODE_ERROR); + return 0; + } + size_t field_len = CBS_len(&base) / 2; + CBS_init(out_base_x, CBS_data(&base), field_len); + CBS_init(out_base_y, CBS_data(&base) + field_len, field_len); + + return 1; +} + +// integers_equal returns one if |a| and |b| are equal, up to leading zeros, and +// zero otherwise. +static int integers_equal(const CBS *a, const uint8_t *b, size_t b_len) { + // Remove leading zeros from |a| and |b|. + CBS a_copy = *a; + while (CBS_len(&a_copy) > 0 && CBS_data(&a_copy)[0] == 0) { + CBS_skip(&a_copy, 1); + } + while (b_len > 0 && b[0] == 0) { + b++; + b_len--; + } + return CBS_mem_equal(&a_copy, b, b_len); +} + +EC_GROUP *EC_KEY_parse_curve_name(CBS *cbs) { + CBS named_curve; + if (!CBS_get_asn1(cbs, &named_curve, CBS_ASN1_OBJECT)) { + OPENSSL_PUT_ERROR(EC, EC_R_DECODE_ERROR); + return NULL; + } + + // Look for a matching curve. + const struct built_in_curves *const curves = OPENSSL_built_in_curves(); + for (size_t i = 0; i < OPENSSL_NUM_BUILT_IN_CURVES; i++) { + const struct built_in_curve *curve = &curves->curves[i]; + if (CBS_len(&named_curve) == curve->oid_len && + OPENSSL_memcmp(CBS_data(&named_curve), curve->oid, curve->oid_len) == + 0) { + return EC_GROUP_new_by_curve_name(curve->nid); + } + } + + OPENSSL_PUT_ERROR(EC, EC_R_UNKNOWN_GROUP); + return NULL; +} + +int EC_KEY_marshal_curve_name(CBB *cbb, const EC_GROUP *group) { + int nid = EC_GROUP_get_curve_name(group); + if (nid == NID_undef) { + OPENSSL_PUT_ERROR(EC, EC_R_UNKNOWN_GROUP); + return 0; + } + + const struct built_in_curves *const curves = OPENSSL_built_in_curves(); + for (size_t i = 0; i < OPENSSL_NUM_BUILT_IN_CURVES; i++) { + const struct built_in_curve *curve = &curves->curves[i]; + if (curve->nid == nid) { + CBB child; + return CBB_add_asn1(cbb, &child, CBS_ASN1_OBJECT) && + CBB_add_bytes(&child, curve->oid, curve->oid_len) && + CBB_flush(cbb); + } + } + + OPENSSL_PUT_ERROR(EC, EC_R_UNKNOWN_GROUP); + return 0; +} + +EC_GROUP *EC_KEY_parse_parameters(CBS *cbs) { + if (!CBS_peek_asn1_tag(cbs, CBS_ASN1_SEQUENCE)) { + return EC_KEY_parse_curve_name(cbs); + } + + // OpenSSL sometimes produces ECPrivateKeys with explicitly-encoded versions + // of named curves. + // + // TODO(davidben): Remove support for this. + CBS prime, a, b, base_x, base_y, order; + if (!parse_explicit_prime_curve(cbs, &prime, &a, &b, &base_x, &base_y, + &order)) { + return NULL; + } + + // Look for a matching prime curve. + const struct built_in_curves *const curves = OPENSSL_built_in_curves(); + for (size_t i = 0; i < OPENSSL_NUM_BUILT_IN_CURVES; i++) { + const struct built_in_curve *curve = &curves->curves[i]; + const unsigned param_len = curve->param_len; + // |curve->params| is ordered p, a, b, x, y, order, each component + // zero-padded up to the field length. Although SEC 1 states that the + // Field-Element-to-Octet-String conversion also pads, OpenSSL mis-encodes + // |a| and |b|, so this comparison must allow omitting leading zeros. (This + // is relevant for P-521 whose |b| has a leading 0.) + if (integers_equal(&prime, curve->params, param_len) && + integers_equal(&a, curve->params + param_len, param_len) && + integers_equal(&b, curve->params + param_len * 2, param_len) && + integers_equal(&base_x, curve->params + param_len * 3, param_len) && + integers_equal(&base_y, curve->params + param_len * 4, param_len) && + integers_equal(&order, curve->params + param_len * 5, param_len)) { + return EC_GROUP_new_by_curve_name(curve->nid); + } + } + + OPENSSL_PUT_ERROR(EC, EC_R_UNKNOWN_GROUP); + return NULL; +} + +int EC_POINT_point2cbb(CBB *out, const EC_GROUP *group, const EC_POINT *point, + point_conversion_form_t form, BN_CTX *ctx) { + size_t len = EC_POINT_point2oct(group, point, form, NULL, 0, ctx); + if (len == 0) { + return 0; + } + uint8_t *p; + return CBB_add_space(out, &p, len) && + EC_POINT_point2oct(group, point, form, p, len, ctx) == len; +} + +EC_KEY *d2i_ECPrivateKey(EC_KEY **out, const uint8_t **inp, long len) { + // This function treats its |out| parameter differently from other |d2i| + // functions. If supplied, take the group from |*out|. + const EC_GROUP *group = NULL; + if (out != NULL && *out != NULL) { + group = EC_KEY_get0_group(*out); + } + + if (len < 0) { + OPENSSL_PUT_ERROR(EC, EC_R_DECODE_ERROR); + return NULL; + } + CBS cbs; + CBS_init(&cbs, *inp, (size_t)len); + EC_KEY *ret = EC_KEY_parse_private_key(&cbs, group); + if (ret == NULL) { + return NULL; + } + if (out != NULL) { + EC_KEY_free(*out); + *out = ret; + } + *inp = CBS_data(&cbs); + return ret; +} + +int i2d_ECPrivateKey(const EC_KEY *key, uint8_t **outp) { + CBB cbb; + if (!CBB_init(&cbb, 0) || + !EC_KEY_marshal_private_key(&cbb, key, EC_KEY_get_enc_flags(key))) { + CBB_cleanup(&cbb); + return -1; + } + return CBB_finish_i2d(&cbb, outp); +} + +EC_KEY *d2i_ECParameters(EC_KEY **out_key, const uint8_t **inp, long len) { + if (len < 0) { + return NULL; + } + + CBS cbs; + CBS_init(&cbs, *inp, (size_t)len); + EC_GROUP *group = EC_KEY_parse_parameters(&cbs); + if (group == NULL) { + return NULL; + } + + EC_KEY *ret = EC_KEY_new(); + if (ret == NULL || !EC_KEY_set_group(ret, group)) { + EC_GROUP_free(group); + EC_KEY_free(ret); + return NULL; + } + EC_GROUP_free(group); + + if (out_key != NULL) { + EC_KEY_free(*out_key); + *out_key = ret; + } + *inp = CBS_data(&cbs); + return ret; +} + +int i2d_ECParameters(const EC_KEY *key, uint8_t **outp) { + if (key == NULL || key->group == NULL) { + OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER); + return -1; + } + + CBB cbb; + if (!CBB_init(&cbb, 0) || + !EC_KEY_marshal_curve_name(&cbb, key->group)) { + CBB_cleanup(&cbb); + return -1; + } + return CBB_finish_i2d(&cbb, outp); +} + +EC_KEY *o2i_ECPublicKey(EC_KEY **keyp, const uint8_t **inp, long len) { + EC_KEY *ret = NULL; + + if (keyp == NULL || *keyp == NULL || (*keyp)->group == NULL) { + OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER); + return NULL; + } + ret = *keyp; + if (ret->pub_key == NULL && + (ret->pub_key = EC_POINT_new(ret->group)) == NULL) { + OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE); + return NULL; + } + if (!EC_POINT_oct2point(ret->group, ret->pub_key, *inp, len, NULL)) { + OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB); + return NULL; + } + // save the point conversion form + ret->conv_form = (point_conversion_form_t)(*inp[0] & ~0x01); + *inp += len; + return ret; +} + +int i2o_ECPublicKey(const EC_KEY *key, uint8_t **outp) { + size_t buf_len = 0; + int new_buffer = 0; + + if (key == NULL) { + OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + buf_len = EC_POINT_point2oct(key->group, key->pub_key, key->conv_form, NULL, + 0, NULL); + + if (outp == NULL || buf_len == 0) { + // out == NULL => just return the length of the octet string + return buf_len; + } + + if (*outp == NULL) { + *outp = OPENSSL_malloc(buf_len); + if (*outp == NULL) { + OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE); + return 0; + } + new_buffer = 1; + } + if (!EC_POINT_point2oct(key->group, key->pub_key, key->conv_form, *outp, + buf_len, NULL)) { + OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB); + if (new_buffer) { + OPENSSL_free(*outp); + *outp = NULL; + } + return 0; + } + + if (!new_buffer) { + *outp += buf_len; + } + return buf_len; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/ec_extra/ec_asn1.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/ec_extra/ec_asn1.c.grpc_back new file mode 100644 index 0000000..bde6d0b --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/ec_extra/ec_asn1.c.grpc_back @@ -0,0 +1,562 @@ +/* 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 +#include + +#include +#include +#include +#include +#include + +#include "../fipsmodule/ec/internal.h" +#include "../bytestring/internal.h" +#include "../internal.h" + + +static const unsigned kParametersTag = + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 0; +static const unsigned kPublicKeyTag = + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 1; + +EC_KEY *EC_KEY_parse_private_key(CBS *cbs, const EC_GROUP *group) { + CBS ec_private_key, private_key; + uint64_t version; + if (!CBS_get_asn1(cbs, &ec_private_key, CBS_ASN1_SEQUENCE) || + !CBS_get_asn1_uint64(&ec_private_key, &version) || + version != 1 || + !CBS_get_asn1(&ec_private_key, &private_key, CBS_ASN1_OCTETSTRING)) { + OPENSSL_PUT_ERROR(EC, EC_R_DECODE_ERROR); + return NULL; + } + + // Parse the optional parameters field. + EC_GROUP *inner_group = NULL; + EC_KEY *ret = NULL; + BIGNUM *priv_key = NULL; + if (CBS_peek_asn1_tag(&ec_private_key, kParametersTag)) { + // Per SEC 1, as an alternative to omitting it, one is allowed to specify + // this field and put in a NULL to mean inheriting this value. This was + // omitted in a previous version of this logic without problems, so leave it + // unimplemented. + CBS child; + if (!CBS_get_asn1(&ec_private_key, &child, kParametersTag)) { + OPENSSL_PUT_ERROR(EC, EC_R_DECODE_ERROR); + goto err; + } + inner_group = EC_KEY_parse_parameters(&child); + if (inner_group == NULL) { + goto err; + } + if (group == NULL) { + group = inner_group; + } else if (EC_GROUP_cmp(group, inner_group, NULL) != 0) { + // If a group was supplied externally, it must match. + OPENSSL_PUT_ERROR(EC, EC_R_GROUP_MISMATCH); + goto err; + } + if (CBS_len(&child) != 0) { + OPENSSL_PUT_ERROR(EC, EC_R_DECODE_ERROR); + goto err; + } + } + + if (group == NULL) { + OPENSSL_PUT_ERROR(EC, EC_R_MISSING_PARAMETERS); + goto err; + } + + ret = EC_KEY_new(); + if (ret == NULL || !EC_KEY_set_group(ret, group)) { + goto err; + } + + // Although RFC 5915 specifies the length of the key, OpenSSL historically + // got this wrong, so accept any length. See upstream's + // 30cd4ff294252c4b6a4b69cbef6a5b4117705d22. + priv_key = BN_bin2bn(CBS_data(&private_key), CBS_len(&private_key), NULL); + ret->pub_key = EC_POINT_new(group); + if (priv_key == NULL || ret->pub_key == NULL || + !EC_KEY_set_private_key(ret, priv_key)) { + goto err; + } + + if (CBS_peek_asn1_tag(&ec_private_key, kPublicKeyTag)) { + CBS child, public_key; + uint8_t padding; + if (!CBS_get_asn1(&ec_private_key, &child, kPublicKeyTag) || + !CBS_get_asn1(&child, &public_key, CBS_ASN1_BITSTRING) || + // As in a SubjectPublicKeyInfo, the byte-encoded public key is then + // encoded as a BIT STRING with bits ordered as in the DER encoding. + !CBS_get_u8(&public_key, &padding) || + padding != 0 || + // Explicitly check |public_key| is non-empty to save the conversion + // form later. + CBS_len(&public_key) == 0 || + !EC_POINT_oct2point(group, ret->pub_key, CBS_data(&public_key), + CBS_len(&public_key), NULL) || + CBS_len(&child) != 0) { + OPENSSL_PUT_ERROR(EC, EC_R_DECODE_ERROR); + goto err; + } + + // Save the point conversion form. + // TODO(davidben): Consider removing this. + ret->conv_form = + (point_conversion_form_t)(CBS_data(&public_key)[0] & ~0x01); + } else { + // Compute the public key instead. + if (!ec_point_mul_scalar(group, ret->pub_key, &ret->priv_key->scalar, NULL, + NULL, NULL)) { + goto err; + } + // Remember the original private-key-only encoding. + // TODO(davidben): Consider removing this. + ret->enc_flag |= EC_PKEY_NO_PUBKEY; + } + + if (CBS_len(&ec_private_key) != 0) { + OPENSSL_PUT_ERROR(EC, EC_R_DECODE_ERROR); + goto err; + } + + // Ensure the resulting key is valid. + if (!EC_KEY_check_key(ret)) { + goto err; + } + + BN_free(priv_key); + EC_GROUP_free(inner_group); + return ret; + +err: + EC_KEY_free(ret); + BN_free(priv_key); + EC_GROUP_free(inner_group); + return NULL; +} + +int EC_KEY_marshal_private_key(CBB *cbb, const EC_KEY *key, + unsigned enc_flags) { + if (key == NULL || key->group == NULL || key->priv_key == NULL) { + OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + CBB ec_private_key, private_key; + if (!CBB_add_asn1(cbb, &ec_private_key, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1_uint64(&ec_private_key, 1 /* version */) || + !CBB_add_asn1(&ec_private_key, &private_key, CBS_ASN1_OCTETSTRING) || + !BN_bn2cbb_padded(&private_key, + BN_num_bytes(EC_GROUP_get0_order(key->group)), + EC_KEY_get0_private_key(key))) { + OPENSSL_PUT_ERROR(EC, EC_R_ENCODE_ERROR); + return 0; + } + + if (!(enc_flags & EC_PKEY_NO_PARAMETERS)) { + CBB child; + if (!CBB_add_asn1(&ec_private_key, &child, kParametersTag) || + !EC_KEY_marshal_curve_name(&child, key->group) || + !CBB_flush(&ec_private_key)) { + OPENSSL_PUT_ERROR(EC, EC_R_ENCODE_ERROR); + return 0; + } + } + + // TODO(fork): replace this flexibility with sensible default? + if (!(enc_flags & EC_PKEY_NO_PUBKEY) && key->pub_key != NULL) { + CBB child, public_key; + if (!CBB_add_asn1(&ec_private_key, &child, kPublicKeyTag) || + !CBB_add_asn1(&child, &public_key, CBS_ASN1_BITSTRING) || + // As in a SubjectPublicKeyInfo, the byte-encoded public key is then + // encoded as a BIT STRING with bits ordered as in the DER encoding. + !CBB_add_u8(&public_key, 0 /* padding */) || + !EC_POINT_point2cbb(&public_key, key->group, key->pub_key, + key->conv_form, NULL) || + !CBB_flush(&ec_private_key)) { + OPENSSL_PUT_ERROR(EC, EC_R_ENCODE_ERROR); + return 0; + } + } + + if (!CBB_flush(cbb)) { + OPENSSL_PUT_ERROR(EC, EC_R_ENCODE_ERROR); + return 0; + } + + return 1; +} + +// is_unsigned_integer returns one if |cbs| is a valid unsigned DER INTEGER and +// zero otherwise. +static int is_unsigned_integer(const CBS *cbs) { + if (CBS_len(cbs) == 0) { + return 0; + } + uint8_t byte = CBS_data(cbs)[0]; + if ((byte & 0x80) || + (byte == 0 && CBS_len(cbs) > 1 && (CBS_data(cbs)[1] & 0x80) == 0)) { + // Negative or not minimally-encoded. + return 0; + } + return 1; +} + +// kPrimeFieldOID is the encoding of 1.2.840.10045.1.1. +static const uint8_t kPrimeField[] = {0x2a, 0x86, 0x48, 0xce, 0x3d, 0x01, 0x01}; + +static int parse_explicit_prime_curve(CBS *in, CBS *out_prime, CBS *out_a, + CBS *out_b, CBS *out_base_x, + CBS *out_base_y, CBS *out_order) { + // See RFC 3279, section 2.3.5. Note that RFC 3279 calls this structure an + // ECParameters while RFC 5480 calls it a SpecifiedECDomain. + CBS params, field_id, field_type, curve, base; + uint64_t version; + if (!CBS_get_asn1(in, ¶ms, CBS_ASN1_SEQUENCE) || + !CBS_get_asn1_uint64(¶ms, &version) || + version != 1 || + !CBS_get_asn1(¶ms, &field_id, CBS_ASN1_SEQUENCE) || + !CBS_get_asn1(&field_id, &field_type, CBS_ASN1_OBJECT) || + CBS_len(&field_type) != sizeof(kPrimeField) || + OPENSSL_memcmp(CBS_data(&field_type), kPrimeField, sizeof(kPrimeField)) != 0 || + !CBS_get_asn1(&field_id, out_prime, CBS_ASN1_INTEGER) || + !is_unsigned_integer(out_prime) || + CBS_len(&field_id) != 0 || + !CBS_get_asn1(¶ms, &curve, CBS_ASN1_SEQUENCE) || + !CBS_get_asn1(&curve, out_a, CBS_ASN1_OCTETSTRING) || + !CBS_get_asn1(&curve, out_b, CBS_ASN1_OCTETSTRING) || + // |curve| has an optional BIT STRING seed which we ignore. + !CBS_get_asn1(¶ms, &base, CBS_ASN1_OCTETSTRING) || + !CBS_get_asn1(¶ms, out_order, CBS_ASN1_INTEGER) || + !is_unsigned_integer(out_order)) { + OPENSSL_PUT_ERROR(EC, EC_R_DECODE_ERROR); + return 0; + } + + // |params| has an optional cofactor which we ignore. With the optional seed + // in |curve|, a group already has arbitrarily many encodings. Parse enough to + // uniquely determine the curve. + + // Require that the base point use uncompressed form. + uint8_t form; + if (!CBS_get_u8(&base, &form) || form != POINT_CONVERSION_UNCOMPRESSED) { + OPENSSL_PUT_ERROR(EC, EC_R_INVALID_FORM); + return 0; + } + + if (CBS_len(&base) % 2 != 0) { + OPENSSL_PUT_ERROR(EC, EC_R_DECODE_ERROR); + return 0; + } + size_t field_len = CBS_len(&base) / 2; + CBS_init(out_base_x, CBS_data(&base), field_len); + CBS_init(out_base_y, CBS_data(&base) + field_len, field_len); + + return 1; +} + +// integers_equal returns one if |a| and |b| are equal, up to leading zeros, and +// zero otherwise. +static int integers_equal(const CBS *a, const uint8_t *b, size_t b_len) { + // Remove leading zeros from |a| and |b|. + CBS a_copy = *a; + while (CBS_len(&a_copy) > 0 && CBS_data(&a_copy)[0] == 0) { + CBS_skip(&a_copy, 1); + } + while (b_len > 0 && b[0] == 0) { + b++; + b_len--; + } + return CBS_mem_equal(&a_copy, b, b_len); +} + +EC_GROUP *EC_KEY_parse_curve_name(CBS *cbs) { + CBS named_curve; + if (!CBS_get_asn1(cbs, &named_curve, CBS_ASN1_OBJECT)) { + OPENSSL_PUT_ERROR(EC, EC_R_DECODE_ERROR); + return NULL; + } + + // Look for a matching curve. + const struct built_in_curves *const curves = OPENSSL_built_in_curves(); + for (size_t i = 0; i < OPENSSL_NUM_BUILT_IN_CURVES; i++) { + const struct built_in_curve *curve = &curves->curves[i]; + if (CBS_len(&named_curve) == curve->oid_len && + OPENSSL_memcmp(CBS_data(&named_curve), curve->oid, curve->oid_len) == + 0) { + return EC_GROUP_new_by_curve_name(curve->nid); + } + } + + OPENSSL_PUT_ERROR(EC, EC_R_UNKNOWN_GROUP); + return NULL; +} + +int EC_KEY_marshal_curve_name(CBB *cbb, const EC_GROUP *group) { + int nid = EC_GROUP_get_curve_name(group); + if (nid == NID_undef) { + OPENSSL_PUT_ERROR(EC, EC_R_UNKNOWN_GROUP); + return 0; + } + + const struct built_in_curves *const curves = OPENSSL_built_in_curves(); + for (size_t i = 0; i < OPENSSL_NUM_BUILT_IN_CURVES; i++) { + const struct built_in_curve *curve = &curves->curves[i]; + if (curve->nid == nid) { + CBB child; + return CBB_add_asn1(cbb, &child, CBS_ASN1_OBJECT) && + CBB_add_bytes(&child, curve->oid, curve->oid_len) && + CBB_flush(cbb); + } + } + + OPENSSL_PUT_ERROR(EC, EC_R_UNKNOWN_GROUP); + return 0; +} + +EC_GROUP *EC_KEY_parse_parameters(CBS *cbs) { + if (!CBS_peek_asn1_tag(cbs, CBS_ASN1_SEQUENCE)) { + return EC_KEY_parse_curve_name(cbs); + } + + // OpenSSL sometimes produces ECPrivateKeys with explicitly-encoded versions + // of named curves. + // + // TODO(davidben): Remove support for this. + CBS prime, a, b, base_x, base_y, order; + if (!parse_explicit_prime_curve(cbs, &prime, &a, &b, &base_x, &base_y, + &order)) { + return NULL; + } + + // Look for a matching prime curve. + const struct built_in_curves *const curves = OPENSSL_built_in_curves(); + for (size_t i = 0; i < OPENSSL_NUM_BUILT_IN_CURVES; i++) { + const struct built_in_curve *curve = &curves->curves[i]; + const unsigned param_len = curve->param_len; + // |curve->params| is ordered p, a, b, x, y, order, each component + // zero-padded up to the field length. Although SEC 1 states that the + // Field-Element-to-Octet-String conversion also pads, OpenSSL mis-encodes + // |a| and |b|, so this comparison must allow omitting leading zeros. (This + // is relevant for P-521 whose |b| has a leading 0.) + if (integers_equal(&prime, curve->params, param_len) && + integers_equal(&a, curve->params + param_len, param_len) && + integers_equal(&b, curve->params + param_len * 2, param_len) && + integers_equal(&base_x, curve->params + param_len * 3, param_len) && + integers_equal(&base_y, curve->params + param_len * 4, param_len) && + integers_equal(&order, curve->params + param_len * 5, param_len)) { + return EC_GROUP_new_by_curve_name(curve->nid); + } + } + + OPENSSL_PUT_ERROR(EC, EC_R_UNKNOWN_GROUP); + return NULL; +} + +int EC_POINT_point2cbb(CBB *out, const EC_GROUP *group, const EC_POINT *point, + point_conversion_form_t form, BN_CTX *ctx) { + size_t len = EC_POINT_point2oct(group, point, form, NULL, 0, ctx); + if (len == 0) { + return 0; + } + uint8_t *p; + return CBB_add_space(out, &p, len) && + EC_POINT_point2oct(group, point, form, p, len, ctx) == len; +} + +EC_KEY *d2i_ECPrivateKey(EC_KEY **out, const uint8_t **inp, long len) { + // This function treats its |out| parameter differently from other |d2i| + // functions. If supplied, take the group from |*out|. + const EC_GROUP *group = NULL; + if (out != NULL && *out != NULL) { + group = EC_KEY_get0_group(*out); + } + + if (len < 0) { + OPENSSL_PUT_ERROR(EC, EC_R_DECODE_ERROR); + return NULL; + } + CBS cbs; + CBS_init(&cbs, *inp, (size_t)len); + EC_KEY *ret = EC_KEY_parse_private_key(&cbs, group); + if (ret == NULL) { + return NULL; + } + if (out != NULL) { + EC_KEY_free(*out); + *out = ret; + } + *inp = CBS_data(&cbs); + return ret; +} + +int i2d_ECPrivateKey(const EC_KEY *key, uint8_t **outp) { + CBB cbb; + if (!CBB_init(&cbb, 0) || + !EC_KEY_marshal_private_key(&cbb, key, EC_KEY_get_enc_flags(key))) { + CBB_cleanup(&cbb); + return -1; + } + return CBB_finish_i2d(&cbb, outp); +} + +EC_KEY *d2i_ECParameters(EC_KEY **out_key, const uint8_t **inp, long len) { + if (len < 0) { + return NULL; + } + + CBS cbs; + CBS_init(&cbs, *inp, (size_t)len); + EC_GROUP *group = EC_KEY_parse_parameters(&cbs); + if (group == NULL) { + return NULL; + } + + EC_KEY *ret = EC_KEY_new(); + if (ret == NULL || !EC_KEY_set_group(ret, group)) { + EC_GROUP_free(group); + EC_KEY_free(ret); + return NULL; + } + EC_GROUP_free(group); + + if (out_key != NULL) { + EC_KEY_free(*out_key); + *out_key = ret; + } + *inp = CBS_data(&cbs); + return ret; +} + +int i2d_ECParameters(const EC_KEY *key, uint8_t **outp) { + if (key == NULL || key->group == NULL) { + OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER); + return -1; + } + + CBB cbb; + if (!CBB_init(&cbb, 0) || + !EC_KEY_marshal_curve_name(&cbb, key->group)) { + CBB_cleanup(&cbb); + return -1; + } + return CBB_finish_i2d(&cbb, outp); +} + +EC_KEY *o2i_ECPublicKey(EC_KEY **keyp, const uint8_t **inp, long len) { + EC_KEY *ret = NULL; + + if (keyp == NULL || *keyp == NULL || (*keyp)->group == NULL) { + OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER); + return NULL; + } + ret = *keyp; + if (ret->pub_key == NULL && + (ret->pub_key = EC_POINT_new(ret->group)) == NULL) { + OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE); + return NULL; + } + if (!EC_POINT_oct2point(ret->group, ret->pub_key, *inp, len, NULL)) { + OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB); + return NULL; + } + // save the point conversion form + ret->conv_form = (point_conversion_form_t)(*inp[0] & ~0x01); + *inp += len; + return ret; +} + +int i2o_ECPublicKey(const EC_KEY *key, uint8_t **outp) { + size_t buf_len = 0; + int new_buffer = 0; + + if (key == NULL) { + OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + buf_len = EC_POINT_point2oct(key->group, key->pub_key, key->conv_form, NULL, + 0, NULL); + + if (outp == NULL || buf_len == 0) { + // out == NULL => just return the length of the octet string + return buf_len; + } + + if (*outp == NULL) { + *outp = OPENSSL_malloc(buf_len); + if (*outp == NULL) { + OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE); + return 0; + } + new_buffer = 1; + } + if (!EC_POINT_point2oct(key->group, key->pub_key, key->conv_form, *outp, + buf_len, NULL)) { + OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB); + if (new_buffer) { + OPENSSL_free(*outp); + *outp = NULL; + } + return 0; + } + + if (!new_buffer) { + *outp += buf_len; + } + return buf_len; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/ecdh/ecdh.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/ecdh/ecdh.c new file mode 100644 index 0000000..4ad46e1 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/ecdh/ecdh.c @@ -0,0 +1,162 @@ +/* ==================================================================== + * 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). */ + +#include + +#include +#include + +#include +#include +#include +#include + +#include "../fipsmodule/ec/internal.h" +#include "../internal.h" + + +int ECDH_compute_key(void *out, size_t outlen, const EC_POINT *pub_key, + const EC_KEY *priv_key, + void *(*kdf)(const void *in, size_t inlen, void *out, + size_t *outlen)) { + if (priv_key->priv_key == NULL) { + OPENSSL_PUT_ERROR(ECDH, ECDH_R_NO_PRIVATE_VALUE); + return -1; + } + const EC_SCALAR *const priv = &priv_key->priv_key->scalar; + + BN_CTX *ctx = BN_CTX_new(); + if (ctx == NULL) { + return -1; + } + BN_CTX_start(ctx); + + int ret = -1; + size_t buflen = 0; + uint8_t *buf = NULL; + + const EC_GROUP *const group = EC_KEY_get0_group(priv_key); + EC_POINT *tmp = EC_POINT_new(group); + if (tmp == NULL) { + OPENSSL_PUT_ERROR(ECDH, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (!ec_point_mul_scalar(group, tmp, NULL, pub_key, priv, ctx)) { + OPENSSL_PUT_ERROR(ECDH, ECDH_R_POINT_ARITHMETIC_FAILURE); + goto err; + } + + BIGNUM *x = BN_CTX_get(ctx); + if (!x) { + OPENSSL_PUT_ERROR(ECDH, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (!EC_POINT_get_affine_coordinates_GFp(group, tmp, x, NULL, ctx)) { + OPENSSL_PUT_ERROR(ECDH, ECDH_R_POINT_ARITHMETIC_FAILURE); + goto err; + } + + buflen = (EC_GROUP_get_degree(group) + 7) / 8; + buf = OPENSSL_malloc(buflen); + if (buf == NULL) { + OPENSSL_PUT_ERROR(ECDH, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (!BN_bn2bin_padded(buf, buflen, x)) { + OPENSSL_PUT_ERROR(ECDH, ERR_R_INTERNAL_ERROR); + goto err; + } + + if (kdf != NULL) { + if (kdf(buf, buflen, out, &outlen) == NULL) { + OPENSSL_PUT_ERROR(ECDH, ECDH_R_KDF_FAILED); + goto err; + } + } else { + // no KDF, just copy as much as we can + if (buflen < outlen) { + outlen = buflen; + } + OPENSSL_memcpy(out, buf, outlen); + } + + if (outlen > INT_MAX) { + OPENSSL_PUT_ERROR(ECDH, ERR_R_OVERFLOW); + goto err; + } + + ret = (int)outlen; + +err: + OPENSSL_free(buf); + EC_POINT_free(tmp); + BN_CTX_end(ctx); + BN_CTX_free(ctx); + return ret; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/ecdh/ecdh.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/ecdh/ecdh.c.grpc_back new file mode 100644 index 0000000..7634ba5 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/ecdh/ecdh.c.grpc_back @@ -0,0 +1,162 @@ +/* ==================================================================== + * 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). */ + +#include + +#include +#include + +#include +#include +#include +#include + +#include "../fipsmodule/ec/internal.h" +#include "../internal.h" + + +int ECDH_compute_key(void *out, size_t outlen, const EC_POINT *pub_key, + const EC_KEY *priv_key, + void *(*kdf)(const void *in, size_t inlen, void *out, + size_t *outlen)) { + if (priv_key->priv_key == NULL) { + OPENSSL_PUT_ERROR(ECDH, ECDH_R_NO_PRIVATE_VALUE); + return -1; + } + const EC_SCALAR *const priv = &priv_key->priv_key->scalar; + + BN_CTX *ctx = BN_CTX_new(); + if (ctx == NULL) { + return -1; + } + BN_CTX_start(ctx); + + int ret = -1; + size_t buflen = 0; + uint8_t *buf = NULL; + + const EC_GROUP *const group = EC_KEY_get0_group(priv_key); + EC_POINT *tmp = EC_POINT_new(group); + if (tmp == NULL) { + OPENSSL_PUT_ERROR(ECDH, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (!ec_point_mul_scalar(group, tmp, NULL, pub_key, priv, ctx)) { + OPENSSL_PUT_ERROR(ECDH, ECDH_R_POINT_ARITHMETIC_FAILURE); + goto err; + } + + BIGNUM *x = BN_CTX_get(ctx); + if (!x) { + OPENSSL_PUT_ERROR(ECDH, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (!EC_POINT_get_affine_coordinates_GFp(group, tmp, x, NULL, ctx)) { + OPENSSL_PUT_ERROR(ECDH, ECDH_R_POINT_ARITHMETIC_FAILURE); + goto err; + } + + buflen = (EC_GROUP_get_degree(group) + 7) / 8; + buf = OPENSSL_malloc(buflen); + if (buf == NULL) { + OPENSSL_PUT_ERROR(ECDH, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (!BN_bn2bin_padded(buf, buflen, x)) { + OPENSSL_PUT_ERROR(ECDH, ERR_R_INTERNAL_ERROR); + goto err; + } + + if (kdf != NULL) { + if (kdf(buf, buflen, out, &outlen) == NULL) { + OPENSSL_PUT_ERROR(ECDH, ECDH_R_KDF_FAILED); + goto err; + } + } else { + // no KDF, just copy as much as we can + if (buflen < outlen) { + outlen = buflen; + } + OPENSSL_memcpy(out, buf, outlen); + } + + if (outlen > INT_MAX) { + OPENSSL_PUT_ERROR(ECDH, ERR_R_OVERFLOW); + goto err; + } + + ret = (int)outlen; + +err: + OPENSSL_free(buf); + EC_POINT_free(tmp); + BN_CTX_end(ctx); + BN_CTX_free(ctx); + return ret; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/ecdsa_extra/ecdsa_asn1.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/ecdsa_extra/ecdsa_asn1.c new file mode 100644 index 0000000..cd467c0 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/ecdsa_extra/ecdsa_asn1.c @@ -0,0 +1,275 @@ +/* ==================================================================== + * 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 +#include + +#include +#include +#include +#include +#include + +#include "../bytestring/internal.h" +#include "../fipsmodule/ec/internal.h" +#include "../internal.h" + + +int ECDSA_sign(int type, const uint8_t *digest, size_t digest_len, uint8_t *sig, + unsigned int *sig_len, const EC_KEY *eckey) { + if (eckey->ecdsa_meth && eckey->ecdsa_meth->sign) { + return eckey->ecdsa_meth->sign(digest, digest_len, sig, sig_len, + (EC_KEY*) eckey /* cast away const */); + } + + int ret = 0; + ECDSA_SIG *s = NULL; + + if (eckey->ecdsa_meth && eckey->ecdsa_meth->sign) { + OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_NOT_IMPLEMENTED); + *sig_len = 0; + goto err; + } + + s = ECDSA_do_sign(digest, digest_len, eckey); + if (s == NULL) { + *sig_len = 0; + goto err; + } + + CBB cbb; + CBB_zero(&cbb); + size_t len; + if (!CBB_init_fixed(&cbb, sig, ECDSA_size(eckey)) || + !ECDSA_SIG_marshal(&cbb, s) || + !CBB_finish(&cbb, NULL, &len)) { + OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_ENCODE_ERROR); + CBB_cleanup(&cbb); + *sig_len = 0; + goto err; + } + *sig_len = (unsigned)len; + ret = 1; + +err: + ECDSA_SIG_free(s); + return ret; +} + +int ECDSA_verify(int type, const uint8_t *digest, size_t digest_len, + const uint8_t *sig, size_t sig_len, const EC_KEY *eckey) { + ECDSA_SIG *s; + int ret = 0; + uint8_t *der = NULL; + + // Decode the ECDSA signature. + s = ECDSA_SIG_from_bytes(sig, sig_len); + if (s == NULL) { + goto err; + } + + // Defend against potential laxness in the DER parser. + size_t der_len; + if (!ECDSA_SIG_to_bytes(&der, &der_len, s) || + der_len != sig_len || OPENSSL_memcmp(sig, der, sig_len) != 0) { + // This should never happen. crypto/bytestring is strictly DER. + OPENSSL_PUT_ERROR(ECDSA, ERR_R_INTERNAL_ERROR); + goto err; + } + + ret = ECDSA_do_verify(digest, digest_len, s, eckey); + +err: + OPENSSL_free(der); + ECDSA_SIG_free(s); + return ret; +} + + +size_t ECDSA_size(const EC_KEY *key) { + if (key == NULL) { + return 0; + } + + size_t group_order_size; + if (key->ecdsa_meth && key->ecdsa_meth->group_order_size) { + group_order_size = key->ecdsa_meth->group_order_size(key); + } else { + const EC_GROUP *group = EC_KEY_get0_group(key); + if (group == NULL) { + return 0; + } + + group_order_size = BN_num_bytes(EC_GROUP_get0_order(group)); + } + + return ECDSA_SIG_max_len(group_order_size); +} + +ECDSA_SIG *ECDSA_SIG_parse(CBS *cbs) { + ECDSA_SIG *ret = ECDSA_SIG_new(); + if (ret == NULL) { + return NULL; + } + CBS child; + if (!CBS_get_asn1(cbs, &child, CBS_ASN1_SEQUENCE) || + !BN_parse_asn1_unsigned(&child, ret->r) || + !BN_parse_asn1_unsigned(&child, ret->s) || + CBS_len(&child) != 0) { + OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_BAD_SIGNATURE); + ECDSA_SIG_free(ret); + return NULL; + } + return ret; +} + +ECDSA_SIG *ECDSA_SIG_from_bytes(const uint8_t *in, size_t in_len) { + CBS cbs; + CBS_init(&cbs, in, in_len); + ECDSA_SIG *ret = ECDSA_SIG_parse(&cbs); + if (ret == NULL || CBS_len(&cbs) != 0) { + OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_BAD_SIGNATURE); + ECDSA_SIG_free(ret); + return NULL; + } + return ret; +} + +int ECDSA_SIG_marshal(CBB *cbb, const ECDSA_SIG *sig) { + CBB child; + if (!CBB_add_asn1(cbb, &child, CBS_ASN1_SEQUENCE) || + !BN_marshal_asn1(&child, sig->r) || + !BN_marshal_asn1(&child, sig->s) || + !CBB_flush(cbb)) { + OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_ENCODE_ERROR); + return 0; + } + return 1; +} + +int ECDSA_SIG_to_bytes(uint8_t **out_bytes, size_t *out_len, + const ECDSA_SIG *sig) { + CBB cbb; + CBB_zero(&cbb); + if (!CBB_init(&cbb, 0) || + !ECDSA_SIG_marshal(&cbb, sig) || + !CBB_finish(&cbb, out_bytes, out_len)) { + OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_ENCODE_ERROR); + CBB_cleanup(&cbb); + return 0; + } + return 1; +} + +// der_len_len returns the number of bytes needed to represent a length of |len| +// in DER. +static size_t der_len_len(size_t len) { + if (len < 0x80) { + return 1; + } + size_t ret = 1; + while (len > 0) { + ret++; + len >>= 8; + } + return ret; +} + +size_t ECDSA_SIG_max_len(size_t order_len) { + // Compute the maximum length of an |order_len| byte integer. Defensively + // assume that the leading 0x00 is included. + size_t integer_len = 1 /* tag */ + der_len_len(order_len + 1) + 1 + order_len; + if (integer_len < order_len) { + return 0; + } + // An ECDSA signature is two INTEGERs. + size_t value_len = 2 * integer_len; + if (value_len < integer_len) { + return 0; + } + // Add the header. + size_t ret = 1 /* tag */ + der_len_len(value_len) + value_len; + if (ret < value_len) { + return 0; + } + return ret; +} + +ECDSA_SIG *d2i_ECDSA_SIG(ECDSA_SIG **out, const uint8_t **inp, long len) { + if (len < 0) { + return NULL; + } + CBS cbs; + CBS_init(&cbs, *inp, (size_t)len); + ECDSA_SIG *ret = ECDSA_SIG_parse(&cbs); + if (ret == NULL) { + return NULL; + } + if (out != NULL) { + ECDSA_SIG_free(*out); + *out = ret; + } + *inp = CBS_data(&cbs); + return ret; +} + +int i2d_ECDSA_SIG(const ECDSA_SIG *sig, uint8_t **outp) { + CBB cbb; + if (!CBB_init(&cbb, 0) || + !ECDSA_SIG_marshal(&cbb, sig)) { + CBB_cleanup(&cbb); + return -1; + } + return CBB_finish_i2d(&cbb, outp); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/ecdsa_extra/ecdsa_asn1.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/ecdsa_extra/ecdsa_asn1.c.grpc_back new file mode 100644 index 0000000..fbf4cca --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/ecdsa_extra/ecdsa_asn1.c.grpc_back @@ -0,0 +1,275 @@ +/* ==================================================================== + * 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 +#include + +#include +#include +#include +#include +#include + +#include "../bytestring/internal.h" +#include "../fipsmodule/ec/internal.h" +#include "../internal.h" + + +int ECDSA_sign(int type, const uint8_t *digest, size_t digest_len, uint8_t *sig, + unsigned int *sig_len, const EC_KEY *eckey) { + if (eckey->ecdsa_meth && eckey->ecdsa_meth->sign) { + return eckey->ecdsa_meth->sign(digest, digest_len, sig, sig_len, + (EC_KEY*) eckey /* cast away const */); + } + + int ret = 0; + ECDSA_SIG *s = NULL; + + if (eckey->ecdsa_meth && eckey->ecdsa_meth->sign) { + OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_NOT_IMPLEMENTED); + *sig_len = 0; + goto err; + } + + s = ECDSA_do_sign(digest, digest_len, eckey); + if (s == NULL) { + *sig_len = 0; + goto err; + } + + CBB cbb; + CBB_zero(&cbb); + size_t len; + if (!CBB_init_fixed(&cbb, sig, ECDSA_size(eckey)) || + !ECDSA_SIG_marshal(&cbb, s) || + !CBB_finish(&cbb, NULL, &len)) { + OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_ENCODE_ERROR); + CBB_cleanup(&cbb); + *sig_len = 0; + goto err; + } + *sig_len = (unsigned)len; + ret = 1; + +err: + ECDSA_SIG_free(s); + return ret; +} + +int ECDSA_verify(int type, const uint8_t *digest, size_t digest_len, + const uint8_t *sig, size_t sig_len, const EC_KEY *eckey) { + ECDSA_SIG *s; + int ret = 0; + uint8_t *der = NULL; + + // Decode the ECDSA signature. + s = ECDSA_SIG_from_bytes(sig, sig_len); + if (s == NULL) { + goto err; + } + + // Defend against potential laxness in the DER parser. + size_t der_len; + if (!ECDSA_SIG_to_bytes(&der, &der_len, s) || + der_len != sig_len || OPENSSL_memcmp(sig, der, sig_len) != 0) { + // This should never happen. crypto/bytestring is strictly DER. + OPENSSL_PUT_ERROR(ECDSA, ERR_R_INTERNAL_ERROR); + goto err; + } + + ret = ECDSA_do_verify(digest, digest_len, s, eckey); + +err: + OPENSSL_free(der); + ECDSA_SIG_free(s); + return ret; +} + + +size_t ECDSA_size(const EC_KEY *key) { + if (key == NULL) { + return 0; + } + + size_t group_order_size; + if (key->ecdsa_meth && key->ecdsa_meth->group_order_size) { + group_order_size = key->ecdsa_meth->group_order_size(key); + } else { + const EC_GROUP *group = EC_KEY_get0_group(key); + if (group == NULL) { + return 0; + } + + group_order_size = BN_num_bytes(EC_GROUP_get0_order(group)); + } + + return ECDSA_SIG_max_len(group_order_size); +} + +ECDSA_SIG *ECDSA_SIG_parse(CBS *cbs) { + ECDSA_SIG *ret = ECDSA_SIG_new(); + if (ret == NULL) { + return NULL; + } + CBS child; + if (!CBS_get_asn1(cbs, &child, CBS_ASN1_SEQUENCE) || + !BN_parse_asn1_unsigned(&child, ret->r) || + !BN_parse_asn1_unsigned(&child, ret->s) || + CBS_len(&child) != 0) { + OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_BAD_SIGNATURE); + ECDSA_SIG_free(ret); + return NULL; + } + return ret; +} + +ECDSA_SIG *ECDSA_SIG_from_bytes(const uint8_t *in, size_t in_len) { + CBS cbs; + CBS_init(&cbs, in, in_len); + ECDSA_SIG *ret = ECDSA_SIG_parse(&cbs); + if (ret == NULL || CBS_len(&cbs) != 0) { + OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_BAD_SIGNATURE); + ECDSA_SIG_free(ret); + return NULL; + } + return ret; +} + +int ECDSA_SIG_marshal(CBB *cbb, const ECDSA_SIG *sig) { + CBB child; + if (!CBB_add_asn1(cbb, &child, CBS_ASN1_SEQUENCE) || + !BN_marshal_asn1(&child, sig->r) || + !BN_marshal_asn1(&child, sig->s) || + !CBB_flush(cbb)) { + OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_ENCODE_ERROR); + return 0; + } + return 1; +} + +int ECDSA_SIG_to_bytes(uint8_t **out_bytes, size_t *out_len, + const ECDSA_SIG *sig) { + CBB cbb; + CBB_zero(&cbb); + if (!CBB_init(&cbb, 0) || + !ECDSA_SIG_marshal(&cbb, sig) || + !CBB_finish(&cbb, out_bytes, out_len)) { + OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_ENCODE_ERROR); + CBB_cleanup(&cbb); + return 0; + } + return 1; +} + +// der_len_len returns the number of bytes needed to represent a length of |len| +// in DER. +static size_t der_len_len(size_t len) { + if (len < 0x80) { + return 1; + } + size_t ret = 1; + while (len > 0) { + ret++; + len >>= 8; + } + return ret; +} + +size_t ECDSA_SIG_max_len(size_t order_len) { + // Compute the maximum length of an |order_len| byte integer. Defensively + // assume that the leading 0x00 is included. + size_t integer_len = 1 /* tag */ + der_len_len(order_len + 1) + 1 + order_len; + if (integer_len < order_len) { + return 0; + } + // An ECDSA signature is two INTEGERs. + size_t value_len = 2 * integer_len; + if (value_len < integer_len) { + return 0; + } + // Add the header. + size_t ret = 1 /* tag */ + der_len_len(value_len) + value_len; + if (ret < value_len) { + return 0; + } + return ret; +} + +ECDSA_SIG *d2i_ECDSA_SIG(ECDSA_SIG **out, const uint8_t **inp, long len) { + if (len < 0) { + return NULL; + } + CBS cbs; + CBS_init(&cbs, *inp, (size_t)len); + ECDSA_SIG *ret = ECDSA_SIG_parse(&cbs); + if (ret == NULL) { + return NULL; + } + if (out != NULL) { + ECDSA_SIG_free(*out); + *out = ret; + } + *inp = CBS_data(&cbs); + return ret; +} + +int i2d_ECDSA_SIG(const ECDSA_SIG *sig, uint8_t **outp) { + CBB cbb; + if (!CBB_init(&cbb, 0) || + !ECDSA_SIG_marshal(&cbb, sig)) { + CBB_cleanup(&cbb); + return -1; + } + return CBB_finish_i2d(&cbb, outp); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/engine/engine.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/engine/engine.c new file mode 100644 index 0000000..5d92eab --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/engine/engine.c @@ -0,0 +1,98 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include "../internal.h" + + +struct engine_st { + RSA_METHOD *rsa_method; + ECDSA_METHOD *ecdsa_method; +}; + +ENGINE *ENGINE_new(void) { + ENGINE *engine = OPENSSL_malloc(sizeof(ENGINE)); + if (engine == NULL) { + return NULL; + } + + OPENSSL_memset(engine, 0, sizeof(ENGINE)); + return engine; +} + +void ENGINE_free(ENGINE *engine) { + // Methods are currently required to be static so are not unref'ed. + OPENSSL_free(engine); +} + +// set_method takes a pointer to a method and its given size and sets +// |*out_member| to point to it. This function might want to be extended in the +// future to support making a copy of the method so that a stable ABI for +// ENGINEs can be supported. But, for the moment, all *_METHODS must be +// static. +static int set_method(void **out_member, const void *method, size_t method_size, + size_t compiled_size) { + const struct openssl_method_common_st *common = method; + if (method_size != compiled_size || !common->is_static) { + return 0; + } + + *out_member = (void*) method; + return 1; +} + +int ENGINE_set_RSA_method(ENGINE *engine, const RSA_METHOD *method, + size_t method_size) { + return set_method((void **)&engine->rsa_method, method, method_size, + sizeof(RSA_METHOD)); +} + +RSA_METHOD *ENGINE_get_RSA_method(const ENGINE *engine) { + return engine->rsa_method; +} + +int ENGINE_set_ECDSA_method(ENGINE *engine, const ECDSA_METHOD *method, + size_t method_size) { + return set_method((void **)&engine->ecdsa_method, method, method_size, + sizeof(ECDSA_METHOD)); +} + +ECDSA_METHOD *ENGINE_get_ECDSA_method(const ENGINE *engine) { + return engine->ecdsa_method; +} + +void METHOD_ref(void *method_in) { + assert(((struct openssl_method_common_st*) method_in)->is_static); +} + +void METHOD_unref(void *method_in) { + struct openssl_method_common_st *method = method_in; + + if (method == NULL) { + return; + } + assert(method->is_static); +} + +OPENSSL_DECLARE_ERROR_REASON(ENGINE, OPERATION_NOT_SUPPORTED) diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/engine/engine.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/engine/engine.c.grpc_back new file mode 100644 index 0000000..875f148 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/engine/engine.c.grpc_back @@ -0,0 +1,98 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include "../internal.h" + + +struct engine_st { + RSA_METHOD *rsa_method; + ECDSA_METHOD *ecdsa_method; +}; + +ENGINE *ENGINE_new(void) { + ENGINE *engine = OPENSSL_malloc(sizeof(ENGINE)); + if (engine == NULL) { + return NULL; + } + + OPENSSL_memset(engine, 0, sizeof(ENGINE)); + return engine; +} + +void ENGINE_free(ENGINE *engine) { + // Methods are currently required to be static so are not unref'ed. + OPENSSL_free(engine); +} + +// set_method takes a pointer to a method and its given size and sets +// |*out_member| to point to it. This function might want to be extended in the +// future to support making a copy of the method so that a stable ABI for +// ENGINEs can be supported. But, for the moment, all *_METHODS must be +// static. +static int set_method(void **out_member, const void *method, size_t method_size, + size_t compiled_size) { + const struct openssl_method_common_st *common = method; + if (method_size != compiled_size || !common->is_static) { + return 0; + } + + *out_member = (void*) method; + return 1; +} + +int ENGINE_set_RSA_method(ENGINE *engine, const RSA_METHOD *method, + size_t method_size) { + return set_method((void **)&engine->rsa_method, method, method_size, + sizeof(RSA_METHOD)); +} + +RSA_METHOD *ENGINE_get_RSA_method(const ENGINE *engine) { + return engine->rsa_method; +} + +int ENGINE_set_ECDSA_method(ENGINE *engine, const ECDSA_METHOD *method, + size_t method_size) { + return set_method((void **)&engine->ecdsa_method, method, method_size, + sizeof(ECDSA_METHOD)); +} + +ECDSA_METHOD *ENGINE_get_ECDSA_method(const ENGINE *engine) { + return engine->ecdsa_method; +} + +void METHOD_ref(void *method_in) { + assert(((struct openssl_method_common_st*) method_in)->is_static); +} + +void METHOD_unref(void *method_in) { + struct openssl_method_common_st *method = method_in; + + if (method == NULL) { + return; + } + assert(method->is_static); +} + +OPENSSL_DECLARE_ERROR_REASON(ENGINE, OPERATION_NOT_SUPPORTED) diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/err/err.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/err/err.c new file mode 100644 index 0000000..1236c58 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/err/err.c @@ -0,0 +1,847 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 +#include + +#if defined(OPENSSL_WINDOWS) +OPENSSL_MSVC_PRAGMA(warning(push, 3)) +#include +OPENSSL_MSVC_PRAGMA(warning(pop)) +#endif + +#include +#include + +#include "../internal.h" +#include "./internal.h" + + +struct err_error_st { + // file contains the filename where the error occurred. + const char *file; + // data contains a NUL-terminated string with optional data. It must be freed + // with |OPENSSL_free|. + char *data; + // packed contains the error library and reason, as packed by ERR_PACK. + uint32_t packed; + // line contains the line number where the error occurred. + uint16_t line; + // mark indicates a reversion point in the queue. See |ERR_pop_to_mark|. + unsigned mark : 1; +}; + +// ERR_STATE contains the per-thread, error queue. +typedef struct err_state_st { + // errors contains the ERR_NUM_ERRORS most recent errors, organised as a ring + // buffer. + struct err_error_st errors[ERR_NUM_ERRORS]; + // top contains the index one past the most recent error. If |top| equals + // |bottom| then the queue is empty. + unsigned top; + // bottom contains the index of the last error in the queue. + unsigned bottom; + + // to_free, if not NULL, contains a pointer owned by this structure that was + // previously a |data| pointer of one of the elements of |errors|. + void *to_free; +} ERR_STATE; + +extern const uint32_t kOpenSSLReasonValues[]; +extern const size_t kOpenSSLReasonValuesLen; +extern const char kOpenSSLReasonStringData[]; + +// err_clear clears the given queued error. +static void err_clear(struct err_error_st *error) { + OPENSSL_free(error->data); + OPENSSL_memset(error, 0, sizeof(struct err_error_st)); +} + +static void err_copy(struct err_error_st *dst, const struct err_error_st *src) { + err_clear(dst); + dst->file = src->file; + if (src->data != NULL) { + dst->data = OPENSSL_strdup(src->data); + } + dst->packed = src->packed; + dst->line = src->line; +} + +// global_next_library contains the next custom library value to return. +static int global_next_library = ERR_NUM_LIBS; + +// global_next_library_mutex protects |global_next_library| from concurrent +// updates. +static struct CRYPTO_STATIC_MUTEX global_next_library_mutex = + CRYPTO_STATIC_MUTEX_INIT; + +static void err_state_free(void *statep) { + ERR_STATE *state = statep; + + if (state == NULL) { + return; + } + + for (unsigned i = 0; i < ERR_NUM_ERRORS; i++) { + err_clear(&state->errors[i]); + } + OPENSSL_free(state->to_free); + OPENSSL_free(state); +} + +// err_get_state gets the ERR_STATE object for the current thread. +static ERR_STATE *err_get_state(void) { + ERR_STATE *state = CRYPTO_get_thread_local(OPENSSL_THREAD_LOCAL_ERR); + if (state == NULL) { + state = OPENSSL_malloc(sizeof(ERR_STATE)); + if (state == NULL) { + return NULL; + } + OPENSSL_memset(state, 0, sizeof(ERR_STATE)); + if (!CRYPTO_set_thread_local(OPENSSL_THREAD_LOCAL_ERR, state, + err_state_free)) { + return NULL; + } + } + + return state; +} + +static uint32_t get_error_values(int inc, int top, const char **file, int *line, + const char **data, int *flags) { + unsigned i = 0; + ERR_STATE *state; + struct err_error_st *error; + uint32_t ret; + + state = err_get_state(); + if (state == NULL || state->bottom == state->top) { + return 0; + } + + if (top) { + assert(!inc); + // last error + i = state->top; + } else { + i = (state->bottom + 1) % ERR_NUM_ERRORS; + } + + error = &state->errors[i]; + ret = error->packed; + + if (file != NULL && line != NULL) { + if (error->file == NULL) { + *file = "NA"; + *line = 0; + } else { + *file = error->file; + *line = error->line; + } + } + + if (data != NULL) { + if (error->data == NULL) { + *data = ""; + if (flags != NULL) { + *flags = 0; + } + } else { + *data = error->data; + if (flags != NULL) { + *flags = ERR_FLAG_STRING; + } + // If this error is being removed, take ownership of data from + // the error. The semantics are such that the caller doesn't + // take ownership either. Instead the error system takes + // ownership and retains it until the next call that affects the + // error queue. + if (inc) { + if (error->data != NULL) { + OPENSSL_free(state->to_free); + state->to_free = error->data; + } + error->data = NULL; + } + } + } + + if (inc) { + assert(!top); + err_clear(error); + state->bottom = i; + } + + return ret; +} + +uint32_t ERR_get_error(void) { + return get_error_values(1 /* inc */, 0 /* bottom */, NULL, NULL, NULL, NULL); +} + +uint32_t ERR_get_error_line(const char **file, int *line) { + return get_error_values(1 /* inc */, 0 /* bottom */, file, line, NULL, NULL); +} + +uint32_t ERR_get_error_line_data(const char **file, int *line, + const char **data, int *flags) { + return get_error_values(1 /* inc */, 0 /* bottom */, file, line, data, flags); +} + +uint32_t ERR_peek_error(void) { + return get_error_values(0 /* peek */, 0 /* bottom */, NULL, NULL, NULL, NULL); +} + +uint32_t ERR_peek_error_line(const char **file, int *line) { + return get_error_values(0 /* peek */, 0 /* bottom */, file, line, NULL, NULL); +} + +uint32_t ERR_peek_error_line_data(const char **file, int *line, + const char **data, int *flags) { + return get_error_values(0 /* peek */, 0 /* bottom */, file, line, data, + flags); +} + +uint32_t ERR_peek_last_error(void) { + return get_error_values(0 /* peek */, 1 /* top */, NULL, NULL, NULL, NULL); +} + +uint32_t ERR_peek_last_error_line(const char **file, int *line) { + return get_error_values(0 /* peek */, 1 /* top */, file, line, NULL, NULL); +} + +uint32_t ERR_peek_last_error_line_data(const char **file, int *line, + const char **data, int *flags) { + return get_error_values(0 /* peek */, 1 /* top */, file, line, data, flags); +} + +void ERR_clear_error(void) { + ERR_STATE *const state = err_get_state(); + unsigned i; + + if (state == NULL) { + return; + } + + for (i = 0; i < ERR_NUM_ERRORS; i++) { + err_clear(&state->errors[i]); + } + OPENSSL_free(state->to_free); + state->to_free = NULL; + + state->top = state->bottom = 0; +} + +void ERR_remove_thread_state(const CRYPTO_THREADID *tid) { + if (tid != NULL) { + assert(0); + return; + } + + ERR_clear_error(); +} + +int ERR_get_next_error_library(void) { + int ret; + + CRYPTO_STATIC_MUTEX_lock_write(&global_next_library_mutex); + ret = global_next_library++; + CRYPTO_STATIC_MUTEX_unlock_write(&global_next_library_mutex); + + return ret; +} + +void ERR_remove_state(unsigned long pid) { + ERR_clear_error(); +} + +void ERR_clear_system_error(void) { + errno = 0; +} + +char *ERR_error_string(uint32_t packed_error, char *ret) { + static char buf[ERR_ERROR_STRING_BUF_LEN]; + + if (ret == NULL) { + // TODO(fork): remove this. + ret = buf; + } + +#if !defined(NDEBUG) + // This is aimed to help catch callers who don't provide + // |ERR_ERROR_STRING_BUF_LEN| bytes of space. + OPENSSL_memset(ret, 0, ERR_ERROR_STRING_BUF_LEN); +#endif + + ERR_error_string_n(packed_error, ret, ERR_ERROR_STRING_BUF_LEN); + + return ret; +} + +void ERR_error_string_n(uint32_t packed_error, char *buf, size_t len) { + char lib_buf[64], reason_buf[64]; + const char *lib_str, *reason_str; + unsigned lib, reason; + + if (len == 0) { + return; + } + + lib = ERR_GET_LIB(packed_error); + reason = ERR_GET_REASON(packed_error); + + lib_str = ERR_lib_error_string(packed_error); + reason_str = ERR_reason_error_string(packed_error); + + if (lib_str == NULL) { + BIO_snprintf(lib_buf, sizeof(lib_buf), "lib(%u)", lib); + lib_str = lib_buf; + } + + if (reason_str == NULL) { + BIO_snprintf(reason_buf, sizeof(reason_buf), "reason(%u)", reason); + reason_str = reason_buf; + } + + BIO_snprintf(buf, len, "error:%08" PRIx32 ":%s:OPENSSL_internal:%s", + packed_error, lib_str, reason_str); + + if (strlen(buf) == len - 1) { + // output may be truncated; make sure we always have 5 colon-separated + // fields, i.e. 4 colons. + static const unsigned num_colons = 4; + unsigned i; + char *s = buf; + + if (len <= num_colons) { + // In this situation it's not possible to ensure that the correct number + // of colons are included in the output. + return; + } + + for (i = 0; i < num_colons; i++) { + char *colon = strchr(s, ':'); + char *last_pos = &buf[len - 1] - num_colons + i; + + if (colon == NULL || colon > last_pos) { + // set colon |i| at last possible position (buf[len-1] is the + // terminating 0). If we're setting this colon, then all whole of the + // rest of the string must be colons in order to have the correct + // number. + OPENSSL_memset(last_pos, ':', num_colons - i); + break; + } + + s = colon + 1; + } + } +} + +// err_string_cmp is a compare function for searching error values with +// |bsearch| in |err_string_lookup|. +static int err_string_cmp(const void *a, const void *b) { + const uint32_t a_key = *((const uint32_t*) a) >> 15; + const uint32_t b_key = *((const uint32_t*) b) >> 15; + + if (a_key < b_key) { + return -1; + } else if (a_key > b_key) { + return 1; + } else { + return 0; + } +} + +// err_string_lookup looks up the string associated with |lib| and |key| in +// |values| and |string_data|. It returns the string or NULL if not found. +static const char *err_string_lookup(uint32_t lib, uint32_t key, + const uint32_t *values, + size_t num_values, + const char *string_data) { + // |values| points to data in err_data.h, which is generated by + // err_data_generate.go. It's an array of uint32_t values. Each value has the + // following structure: + // | lib | key | offset | + // |6 bits| 11 bits | 15 bits | + // + // The |lib| value is a library identifier: one of the |ERR_LIB_*| values. + // The |key| is a reason code, depending on the context. + // The |offset| is the number of bytes from the start of |string_data| where + // the (NUL terminated) string for this value can be found. + // + // Values are sorted based on treating the |lib| and |key| part as an + // unsigned integer. + if (lib >= (1 << 6) || key >= (1 << 11)) { + return NULL; + } + uint32_t search_key = lib << 26 | key << 15; + const uint32_t *result = bsearch(&search_key, values, num_values, + sizeof(uint32_t), err_string_cmp); + if (result == NULL) { + return NULL; + } + + return &string_data[(*result) & 0x7fff]; +} + +static const char *const kLibraryNames[ERR_NUM_LIBS] = { + "invalid library (0)", + "unknown library", // ERR_LIB_NONE + "system library", // ERR_LIB_SYS + "bignum routines", // ERR_LIB_BN + "RSA routines", // ERR_LIB_RSA + "Diffie-Hellman routines", // ERR_LIB_DH + "public key routines", // ERR_LIB_EVP + "memory buffer routines", // ERR_LIB_BUF + "object identifier routines", // ERR_LIB_OBJ + "PEM routines", // ERR_LIB_PEM + "DSA routines", // ERR_LIB_DSA + "X.509 certificate routines", // ERR_LIB_X509 + "ASN.1 encoding routines", // ERR_LIB_ASN1 + "configuration file routines", // ERR_LIB_CONF + "common libcrypto routines", // ERR_LIB_CRYPTO + "elliptic curve routines", // ERR_LIB_EC + "SSL routines", // ERR_LIB_SSL + "BIO routines", // ERR_LIB_BIO + "PKCS7 routines", // ERR_LIB_PKCS7 + "PKCS8 routines", // ERR_LIB_PKCS8 + "X509 V3 routines", // ERR_LIB_X509V3 + "random number generator", // ERR_LIB_RAND + "ENGINE routines", // ERR_LIB_ENGINE + "OCSP routines", // ERR_LIB_OCSP + "UI routines", // ERR_LIB_UI + "COMP routines", // ERR_LIB_COMP + "ECDSA routines", // ERR_LIB_ECDSA + "ECDH routines", // ERR_LIB_ECDH + "HMAC routines", // ERR_LIB_HMAC + "Digest functions", // ERR_LIB_DIGEST + "Cipher functions", // ERR_LIB_CIPHER + "HKDF functions", // ERR_LIB_HKDF + "User defined functions", // ERR_LIB_USER +}; + +const char *ERR_lib_error_string(uint32_t packed_error) { + const uint32_t lib = ERR_GET_LIB(packed_error); + + if (lib >= ERR_NUM_LIBS) { + return NULL; + } + return kLibraryNames[lib]; +} + +const char *ERR_func_error_string(uint32_t packed_error) { + return "OPENSSL_internal"; +} + +const char *ERR_reason_error_string(uint32_t packed_error) { + const uint32_t lib = ERR_GET_LIB(packed_error); + const uint32_t reason = ERR_GET_REASON(packed_error); + + if (lib == ERR_LIB_SYS) { + if (reason < 127) { + return strerror(reason); + } + return NULL; + } + + if (reason < ERR_NUM_LIBS) { + return kLibraryNames[reason]; + } + + if (reason < 100) { + switch (reason) { + case ERR_R_MALLOC_FAILURE: + return "malloc failure"; + case ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED: + return "function should not have been called"; + case ERR_R_PASSED_NULL_PARAMETER: + return "passed a null parameter"; + case ERR_R_INTERNAL_ERROR: + return "internal error"; + case ERR_R_OVERFLOW: + return "overflow"; + default: + return NULL; + } + } + + return err_string_lookup(lib, reason, kOpenSSLReasonValues, + kOpenSSLReasonValuesLen, kOpenSSLReasonStringData); +} + +void ERR_print_errors_cb(ERR_print_errors_callback_t callback, void *ctx) { + char buf[ERR_ERROR_STRING_BUF_LEN]; + char buf2[1024]; + const char *file, *data; + int line, flags; + uint32_t packed_error; + + // thread_hash is the least-significant bits of the |ERR_STATE| pointer value + // for this thread. + const unsigned long thread_hash = (uintptr_t) err_get_state(); + + for (;;) { + packed_error = ERR_get_error_line_data(&file, &line, &data, &flags); + if (packed_error == 0) { + break; + } + + ERR_error_string_n(packed_error, buf, sizeof(buf)); + BIO_snprintf(buf2, sizeof(buf2), "%lu:%s:%s:%d:%s\n", thread_hash, buf, + file, line, (flags & ERR_FLAG_STRING) ? data : ""); + if (callback(buf2, strlen(buf2), ctx) <= 0) { + break; + } + } +} + +static int print_errors_to_file(const char* msg, size_t msg_len, void* ctx) { + assert(msg[msg_len] == '\0'); + FILE* fp = ctx; + int res = fputs(msg, fp); + return res < 0 ? 0 : 1; +} + +void ERR_print_errors_fp(FILE *file) { + ERR_print_errors_cb(print_errors_to_file, file); +} + +// err_set_error_data sets the data on the most recent error. +static void err_set_error_data(char *data) { + ERR_STATE *const state = err_get_state(); + struct err_error_st *error; + + if (state == NULL || state->top == state->bottom) { + OPENSSL_free(data); + return; + } + + error = &state->errors[state->top]; + + OPENSSL_free(error->data); + error->data = data; +} + +void ERR_put_error(int library, int unused, int reason, const char *file, + unsigned line) { + ERR_STATE *const state = err_get_state(); + struct err_error_st *error; + + if (state == NULL) { + return; + } + + if (library == ERR_LIB_SYS && reason == 0) { +#if defined(OPENSSL_WINDOWS) + reason = GetLastError(); +#else + reason = errno; +#endif + } + + state->top = (state->top + 1) % ERR_NUM_ERRORS; + if (state->top == state->bottom) { + state->bottom = (state->bottom + 1) % ERR_NUM_ERRORS; + } + + error = &state->errors[state->top]; + err_clear(error); + error->file = file; + error->line = line; + error->packed = ERR_PACK(library, reason); +} + +// ERR_add_error_data_vdata takes a variable number of const char* pointers, +// concatenates them and sets the result as the data on the most recent +// error. +static void err_add_error_vdata(unsigned num, va_list args) { + size_t alloced, new_len, len = 0, substr_len; + char *buf; + const char *substr; + unsigned i; + + alloced = 80; + buf = OPENSSL_malloc(alloced + 1); + if (buf == NULL) { + return; + } + + for (i = 0; i < num; i++) { + substr = va_arg(args, const char *); + if (substr == NULL) { + continue; + } + + substr_len = strlen(substr); + new_len = len + substr_len; + if (new_len > alloced) { + char *new_buf; + + if (alloced + 20 + 1 < alloced) { + // overflow. + OPENSSL_free(buf); + return; + } + + alloced = new_len + 20; + new_buf = OPENSSL_realloc(buf, alloced + 1); + if (new_buf == NULL) { + OPENSSL_free(buf); + return; + } + buf = new_buf; + } + + OPENSSL_memcpy(buf + len, substr, substr_len); + len = new_len; + } + + buf[len] = 0; + err_set_error_data(buf); +} + +void ERR_add_error_data(unsigned count, ...) { + va_list args; + va_start(args, count); + err_add_error_vdata(count, args); + va_end(args); +} + +void ERR_add_error_dataf(const char *format, ...) { + va_list ap; + char *buf; + static const unsigned buf_len = 256; + + // A fixed-size buffer is used because va_copy (which would be needed in + // order to call vsnprintf twice and measure the buffer) wasn't defined until + // C99. + buf = OPENSSL_malloc(buf_len + 1); + if (buf == NULL) { + return; + } + + va_start(ap, format); + BIO_vsnprintf(buf, buf_len, format, ap); + buf[buf_len] = 0; + va_end(ap); + + err_set_error_data(buf); +} + +int ERR_set_mark(void) { + ERR_STATE *const state = err_get_state(); + + if (state == NULL || state->bottom == state->top) { + return 0; + } + state->errors[state->top].mark = 1; + return 1; +} + +int ERR_pop_to_mark(void) { + ERR_STATE *const state = err_get_state(); + + if (state == NULL) { + return 0; + } + + while (state->bottom != state->top) { + struct err_error_st *error = &state->errors[state->top]; + + if (error->mark) { + error->mark = 0; + return 1; + } + + err_clear(error); + if (state->top == 0) { + state->top = ERR_NUM_ERRORS - 1; + } else { + state->top--; + } + } + + return 0; +} + +void ERR_load_crypto_strings(void) {} + +void ERR_free_strings(void) {} + +void ERR_load_BIO_strings(void) {} + +void ERR_load_ERR_strings(void) {} + +struct err_save_state_st { + struct err_error_st *errors; + size_t num_errors; +}; + +void ERR_SAVE_STATE_free(ERR_SAVE_STATE *state) { + if (state == NULL) { + return; + } + for (size_t i = 0; i < state->num_errors; i++) { + err_clear(&state->errors[i]); + } + OPENSSL_free(state->errors); + OPENSSL_free(state); +} + +ERR_SAVE_STATE *ERR_save_state(void) { + ERR_STATE *const state = err_get_state(); + if (state == NULL || state->top == state->bottom) { + return NULL; + } + + ERR_SAVE_STATE *ret = OPENSSL_malloc(sizeof(ERR_SAVE_STATE)); + if (ret == NULL) { + return NULL; + } + + // Errors are stored in the range (bottom, top]. + size_t num_errors = state->top >= state->bottom + ? state->top - state->bottom + : ERR_NUM_ERRORS + state->top - state->bottom; + assert(num_errors < ERR_NUM_ERRORS); + ret->errors = OPENSSL_malloc(num_errors * sizeof(struct err_error_st)); + if (ret->errors == NULL) { + OPENSSL_free(ret); + return NULL; + } + OPENSSL_memset(ret->errors, 0, num_errors * sizeof(struct err_error_st)); + ret->num_errors = num_errors; + + for (size_t i = 0; i < num_errors; i++) { + size_t j = (state->bottom + i + 1) % ERR_NUM_ERRORS; + err_copy(&ret->errors[i], &state->errors[j]); + } + return ret; +} + +void ERR_restore_state(const ERR_SAVE_STATE *state) { + if (state == NULL || state->num_errors == 0) { + ERR_clear_error(); + return; + } + + ERR_STATE *const dst = err_get_state(); + if (dst == NULL) { + return; + } + + for (size_t i = 0; i < state->num_errors; i++) { + err_copy(&dst->errors[i], &state->errors[i]); + } + dst->top = state->num_errors - 1; + dst->bottom = ERR_NUM_ERRORS - 1; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/err/err.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/err/err.c.grpc_back new file mode 100644 index 0000000..c7bff16 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/err/err.c.grpc_back @@ -0,0 +1,847 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 +#include + +#if defined(OPENSSL_WINDOWS) +OPENSSL_MSVC_PRAGMA(warning(push, 3)) +#include +OPENSSL_MSVC_PRAGMA(warning(pop)) +#endif + +#include +#include + +#include "../internal.h" +#include "./internal.h" + + +struct err_error_st { + // file contains the filename where the error occurred. + const char *file; + // data contains a NUL-terminated string with optional data. It must be freed + // with |OPENSSL_free|. + char *data; + // packed contains the error library and reason, as packed by ERR_PACK. + uint32_t packed; + // line contains the line number where the error occurred. + uint16_t line; + // mark indicates a reversion point in the queue. See |ERR_pop_to_mark|. + unsigned mark : 1; +}; + +// ERR_STATE contains the per-thread, error queue. +typedef struct err_state_st { + // errors contains the ERR_NUM_ERRORS most recent errors, organised as a ring + // buffer. + struct err_error_st errors[ERR_NUM_ERRORS]; + // top contains the index one past the most recent error. If |top| equals + // |bottom| then the queue is empty. + unsigned top; + // bottom contains the index of the last error in the queue. + unsigned bottom; + + // to_free, if not NULL, contains a pointer owned by this structure that was + // previously a |data| pointer of one of the elements of |errors|. + void *to_free; +} ERR_STATE; + +extern const uint32_t kOpenSSLReasonValues[]; +extern const size_t kOpenSSLReasonValuesLen; +extern const char kOpenSSLReasonStringData[]; + +// err_clear clears the given queued error. +static void err_clear(struct err_error_st *error) { + OPENSSL_free(error->data); + OPENSSL_memset(error, 0, sizeof(struct err_error_st)); +} + +static void err_copy(struct err_error_st *dst, const struct err_error_st *src) { + err_clear(dst); + dst->file = src->file; + if (src->data != NULL) { + dst->data = OPENSSL_strdup(src->data); + } + dst->packed = src->packed; + dst->line = src->line; +} + +// global_next_library contains the next custom library value to return. +static int global_next_library = ERR_NUM_LIBS; + +// global_next_library_mutex protects |global_next_library| from concurrent +// updates. +static struct CRYPTO_STATIC_MUTEX global_next_library_mutex = + CRYPTO_STATIC_MUTEX_INIT; + +static void err_state_free(void *statep) { + ERR_STATE *state = statep; + + if (state == NULL) { + return; + } + + for (unsigned i = 0; i < ERR_NUM_ERRORS; i++) { + err_clear(&state->errors[i]); + } + OPENSSL_free(state->to_free); + OPENSSL_free(state); +} + +// err_get_state gets the ERR_STATE object for the current thread. +static ERR_STATE *err_get_state(void) { + ERR_STATE *state = CRYPTO_get_thread_local(OPENSSL_THREAD_LOCAL_ERR); + if (state == NULL) { + state = OPENSSL_malloc(sizeof(ERR_STATE)); + if (state == NULL) { + return NULL; + } + OPENSSL_memset(state, 0, sizeof(ERR_STATE)); + if (!CRYPTO_set_thread_local(OPENSSL_THREAD_LOCAL_ERR, state, + err_state_free)) { + return NULL; + } + } + + return state; +} + +static uint32_t get_error_values(int inc, int top, const char **file, int *line, + const char **data, int *flags) { + unsigned i = 0; + ERR_STATE *state; + struct err_error_st *error; + uint32_t ret; + + state = err_get_state(); + if (state == NULL || state->bottom == state->top) { + return 0; + } + + if (top) { + assert(!inc); + // last error + i = state->top; + } else { + i = (state->bottom + 1) % ERR_NUM_ERRORS; + } + + error = &state->errors[i]; + ret = error->packed; + + if (file != NULL && line != NULL) { + if (error->file == NULL) { + *file = "NA"; + *line = 0; + } else { + *file = error->file; + *line = error->line; + } + } + + if (data != NULL) { + if (error->data == NULL) { + *data = ""; + if (flags != NULL) { + *flags = 0; + } + } else { + *data = error->data; + if (flags != NULL) { + *flags = ERR_FLAG_STRING; + } + // If this error is being removed, take ownership of data from + // the error. The semantics are such that the caller doesn't + // take ownership either. Instead the error system takes + // ownership and retains it until the next call that affects the + // error queue. + if (inc) { + if (error->data != NULL) { + OPENSSL_free(state->to_free); + state->to_free = error->data; + } + error->data = NULL; + } + } + } + + if (inc) { + assert(!top); + err_clear(error); + state->bottom = i; + } + + return ret; +} + +uint32_t ERR_get_error(void) { + return get_error_values(1 /* inc */, 0 /* bottom */, NULL, NULL, NULL, NULL); +} + +uint32_t ERR_get_error_line(const char **file, int *line) { + return get_error_values(1 /* inc */, 0 /* bottom */, file, line, NULL, NULL); +} + +uint32_t ERR_get_error_line_data(const char **file, int *line, + const char **data, int *flags) { + return get_error_values(1 /* inc */, 0 /* bottom */, file, line, data, flags); +} + +uint32_t ERR_peek_error(void) { + return get_error_values(0 /* peek */, 0 /* bottom */, NULL, NULL, NULL, NULL); +} + +uint32_t ERR_peek_error_line(const char **file, int *line) { + return get_error_values(0 /* peek */, 0 /* bottom */, file, line, NULL, NULL); +} + +uint32_t ERR_peek_error_line_data(const char **file, int *line, + const char **data, int *flags) { + return get_error_values(0 /* peek */, 0 /* bottom */, file, line, data, + flags); +} + +uint32_t ERR_peek_last_error(void) { + return get_error_values(0 /* peek */, 1 /* top */, NULL, NULL, NULL, NULL); +} + +uint32_t ERR_peek_last_error_line(const char **file, int *line) { + return get_error_values(0 /* peek */, 1 /* top */, file, line, NULL, NULL); +} + +uint32_t ERR_peek_last_error_line_data(const char **file, int *line, + const char **data, int *flags) { + return get_error_values(0 /* peek */, 1 /* top */, file, line, data, flags); +} + +void ERR_clear_error(void) { + ERR_STATE *const state = err_get_state(); + unsigned i; + + if (state == NULL) { + return; + } + + for (i = 0; i < ERR_NUM_ERRORS; i++) { + err_clear(&state->errors[i]); + } + OPENSSL_free(state->to_free); + state->to_free = NULL; + + state->top = state->bottom = 0; +} + +void ERR_remove_thread_state(const CRYPTO_THREADID *tid) { + if (tid != NULL) { + assert(0); + return; + } + + ERR_clear_error(); +} + +int ERR_get_next_error_library(void) { + int ret; + + CRYPTO_STATIC_MUTEX_lock_write(&global_next_library_mutex); + ret = global_next_library++; + CRYPTO_STATIC_MUTEX_unlock_write(&global_next_library_mutex); + + return ret; +} + +void ERR_remove_state(unsigned long pid) { + ERR_clear_error(); +} + +void ERR_clear_system_error(void) { + errno = 0; +} + +char *ERR_error_string(uint32_t packed_error, char *ret) { + static char buf[ERR_ERROR_STRING_BUF_LEN]; + + if (ret == NULL) { + // TODO(fork): remove this. + ret = buf; + } + +#if !defined(NDEBUG) + // This is aimed to help catch callers who don't provide + // |ERR_ERROR_STRING_BUF_LEN| bytes of space. + OPENSSL_memset(ret, 0, ERR_ERROR_STRING_BUF_LEN); +#endif + + ERR_error_string_n(packed_error, ret, ERR_ERROR_STRING_BUF_LEN); + + return ret; +} + +void ERR_error_string_n(uint32_t packed_error, char *buf, size_t len) { + char lib_buf[64], reason_buf[64]; + const char *lib_str, *reason_str; + unsigned lib, reason; + + if (len == 0) { + return; + } + + lib = ERR_GET_LIB(packed_error); + reason = ERR_GET_REASON(packed_error); + + lib_str = ERR_lib_error_string(packed_error); + reason_str = ERR_reason_error_string(packed_error); + + if (lib_str == NULL) { + BIO_snprintf(lib_buf, sizeof(lib_buf), "lib(%u)", lib); + lib_str = lib_buf; + } + + if (reason_str == NULL) { + BIO_snprintf(reason_buf, sizeof(reason_buf), "reason(%u)", reason); + reason_str = reason_buf; + } + + BIO_snprintf(buf, len, "error:%08" PRIx32 ":%s:OPENSSL_internal:%s", + packed_error, lib_str, reason_str); + + if (strlen(buf) == len - 1) { + // output may be truncated; make sure we always have 5 colon-separated + // fields, i.e. 4 colons. + static const unsigned num_colons = 4; + unsigned i; + char *s = buf; + + if (len <= num_colons) { + // In this situation it's not possible to ensure that the correct number + // of colons are included in the output. + return; + } + + for (i = 0; i < num_colons; i++) { + char *colon = strchr(s, ':'); + char *last_pos = &buf[len - 1] - num_colons + i; + + if (colon == NULL || colon > last_pos) { + // set colon |i| at last possible position (buf[len-1] is the + // terminating 0). If we're setting this colon, then all whole of the + // rest of the string must be colons in order to have the correct + // number. + OPENSSL_memset(last_pos, ':', num_colons - i); + break; + } + + s = colon + 1; + } + } +} + +// err_string_cmp is a compare function for searching error values with +// |bsearch| in |err_string_lookup|. +static int err_string_cmp(const void *a, const void *b) { + const uint32_t a_key = *((const uint32_t*) a) >> 15; + const uint32_t b_key = *((const uint32_t*) b) >> 15; + + if (a_key < b_key) { + return -1; + } else if (a_key > b_key) { + return 1; + } else { + return 0; + } +} + +// err_string_lookup looks up the string associated with |lib| and |key| in +// |values| and |string_data|. It returns the string or NULL if not found. +static const char *err_string_lookup(uint32_t lib, uint32_t key, + const uint32_t *values, + size_t num_values, + const char *string_data) { + // |values| points to data in err_data.h, which is generated by + // err_data_generate.go. It's an array of uint32_t values. Each value has the + // following structure: + // | lib | key | offset | + // |6 bits| 11 bits | 15 bits | + // + // The |lib| value is a library identifier: one of the |ERR_LIB_*| values. + // The |key| is a reason code, depending on the context. + // The |offset| is the number of bytes from the start of |string_data| where + // the (NUL terminated) string for this value can be found. + // + // Values are sorted based on treating the |lib| and |key| part as an + // unsigned integer. + if (lib >= (1 << 6) || key >= (1 << 11)) { + return NULL; + } + uint32_t search_key = lib << 26 | key << 15; + const uint32_t *result = bsearch(&search_key, values, num_values, + sizeof(uint32_t), err_string_cmp); + if (result == NULL) { + return NULL; + } + + return &string_data[(*result) & 0x7fff]; +} + +static const char *const kLibraryNames[ERR_NUM_LIBS] = { + "invalid library (0)", + "unknown library", // ERR_LIB_NONE + "system library", // ERR_LIB_SYS + "bignum routines", // ERR_LIB_BN + "RSA routines", // ERR_LIB_RSA + "Diffie-Hellman routines", // ERR_LIB_DH + "public key routines", // ERR_LIB_EVP + "memory buffer routines", // ERR_LIB_BUF + "object identifier routines", // ERR_LIB_OBJ + "PEM routines", // ERR_LIB_PEM + "DSA routines", // ERR_LIB_DSA + "X.509 certificate routines", // ERR_LIB_X509 + "ASN.1 encoding routines", // ERR_LIB_ASN1 + "configuration file routines", // ERR_LIB_CONF + "common libcrypto routines", // ERR_LIB_CRYPTO + "elliptic curve routines", // ERR_LIB_EC + "SSL routines", // ERR_LIB_SSL + "BIO routines", // ERR_LIB_BIO + "PKCS7 routines", // ERR_LIB_PKCS7 + "PKCS8 routines", // ERR_LIB_PKCS8 + "X509 V3 routines", // ERR_LIB_X509V3 + "random number generator", // ERR_LIB_RAND + "ENGINE routines", // ERR_LIB_ENGINE + "OCSP routines", // ERR_LIB_OCSP + "UI routines", // ERR_LIB_UI + "COMP routines", // ERR_LIB_COMP + "ECDSA routines", // ERR_LIB_ECDSA + "ECDH routines", // ERR_LIB_ECDH + "HMAC routines", // ERR_LIB_HMAC + "Digest functions", // ERR_LIB_DIGEST + "Cipher functions", // ERR_LIB_CIPHER + "HKDF functions", // ERR_LIB_HKDF + "User defined functions", // ERR_LIB_USER +}; + +const char *ERR_lib_error_string(uint32_t packed_error) { + const uint32_t lib = ERR_GET_LIB(packed_error); + + if (lib >= ERR_NUM_LIBS) { + return NULL; + } + return kLibraryNames[lib]; +} + +const char *ERR_func_error_string(uint32_t packed_error) { + return "OPENSSL_internal"; +} + +const char *ERR_reason_error_string(uint32_t packed_error) { + const uint32_t lib = ERR_GET_LIB(packed_error); + const uint32_t reason = ERR_GET_REASON(packed_error); + + if (lib == ERR_LIB_SYS) { + if (reason < 127) { + return strerror(reason); + } + return NULL; + } + + if (reason < ERR_NUM_LIBS) { + return kLibraryNames[reason]; + } + + if (reason < 100) { + switch (reason) { + case ERR_R_MALLOC_FAILURE: + return "malloc failure"; + case ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED: + return "function should not have been called"; + case ERR_R_PASSED_NULL_PARAMETER: + return "passed a null parameter"; + case ERR_R_INTERNAL_ERROR: + return "internal error"; + case ERR_R_OVERFLOW: + return "overflow"; + default: + return NULL; + } + } + + return err_string_lookup(lib, reason, kOpenSSLReasonValues, + kOpenSSLReasonValuesLen, kOpenSSLReasonStringData); +} + +void ERR_print_errors_cb(ERR_print_errors_callback_t callback, void *ctx) { + char buf[ERR_ERROR_STRING_BUF_LEN]; + char buf2[1024]; + const char *file, *data; + int line, flags; + uint32_t packed_error; + + // thread_hash is the least-significant bits of the |ERR_STATE| pointer value + // for this thread. + const unsigned long thread_hash = (uintptr_t) err_get_state(); + + for (;;) { + packed_error = ERR_get_error_line_data(&file, &line, &data, &flags); + if (packed_error == 0) { + break; + } + + ERR_error_string_n(packed_error, buf, sizeof(buf)); + BIO_snprintf(buf2, sizeof(buf2), "%lu:%s:%s:%d:%s\n", thread_hash, buf, + file, line, (flags & ERR_FLAG_STRING) ? data : ""); + if (callback(buf2, strlen(buf2), ctx) <= 0) { + break; + } + } +} + +static int print_errors_to_file(const char* msg, size_t msg_len, void* ctx) { + assert(msg[msg_len] == '\0'); + FILE* fp = ctx; + int res = fputs(msg, fp); + return res < 0 ? 0 : 1; +} + +void ERR_print_errors_fp(FILE *file) { + ERR_print_errors_cb(print_errors_to_file, file); +} + +// err_set_error_data sets the data on the most recent error. +static void err_set_error_data(char *data) { + ERR_STATE *const state = err_get_state(); + struct err_error_st *error; + + if (state == NULL || state->top == state->bottom) { + OPENSSL_free(data); + return; + } + + error = &state->errors[state->top]; + + OPENSSL_free(error->data); + error->data = data; +} + +void ERR_put_error(int library, int unused, int reason, const char *file, + unsigned line) { + ERR_STATE *const state = err_get_state(); + struct err_error_st *error; + + if (state == NULL) { + return; + } + + if (library == ERR_LIB_SYS && reason == 0) { +#if defined(OPENSSL_WINDOWS) + reason = GetLastError(); +#else + reason = errno; +#endif + } + + state->top = (state->top + 1) % ERR_NUM_ERRORS; + if (state->top == state->bottom) { + state->bottom = (state->bottom + 1) % ERR_NUM_ERRORS; + } + + error = &state->errors[state->top]; + err_clear(error); + error->file = file; + error->line = line; + error->packed = ERR_PACK(library, reason); +} + +// ERR_add_error_data_vdata takes a variable number of const char* pointers, +// concatenates them and sets the result as the data on the most recent +// error. +static void err_add_error_vdata(unsigned num, va_list args) { + size_t alloced, new_len, len = 0, substr_len; + char *buf; + const char *substr; + unsigned i; + + alloced = 80; + buf = OPENSSL_malloc(alloced + 1); + if (buf == NULL) { + return; + } + + for (i = 0; i < num; i++) { + substr = va_arg(args, const char *); + if (substr == NULL) { + continue; + } + + substr_len = strlen(substr); + new_len = len + substr_len; + if (new_len > alloced) { + char *new_buf; + + if (alloced + 20 + 1 < alloced) { + // overflow. + OPENSSL_free(buf); + return; + } + + alloced = new_len + 20; + new_buf = OPENSSL_realloc(buf, alloced + 1); + if (new_buf == NULL) { + OPENSSL_free(buf); + return; + } + buf = new_buf; + } + + OPENSSL_memcpy(buf + len, substr, substr_len); + len = new_len; + } + + buf[len] = 0; + err_set_error_data(buf); +} + +void ERR_add_error_data(unsigned count, ...) { + va_list args; + va_start(args, count); + err_add_error_vdata(count, args); + va_end(args); +} + +void ERR_add_error_dataf(const char *format, ...) { + va_list ap; + char *buf; + static const unsigned buf_len = 256; + + // A fixed-size buffer is used because va_copy (which would be needed in + // order to call vsnprintf twice and measure the buffer) wasn't defined until + // C99. + buf = OPENSSL_malloc(buf_len + 1); + if (buf == NULL) { + return; + } + + va_start(ap, format); + BIO_vsnprintf(buf, buf_len, format, ap); + buf[buf_len] = 0; + va_end(ap); + + err_set_error_data(buf); +} + +int ERR_set_mark(void) { + ERR_STATE *const state = err_get_state(); + + if (state == NULL || state->bottom == state->top) { + return 0; + } + state->errors[state->top].mark = 1; + return 1; +} + +int ERR_pop_to_mark(void) { + ERR_STATE *const state = err_get_state(); + + if (state == NULL) { + return 0; + } + + while (state->bottom != state->top) { + struct err_error_st *error = &state->errors[state->top]; + + if (error->mark) { + error->mark = 0; + return 1; + } + + err_clear(error); + if (state->top == 0) { + state->top = ERR_NUM_ERRORS - 1; + } else { + state->top--; + } + } + + return 0; +} + +void ERR_load_crypto_strings(void) {} + +void ERR_free_strings(void) {} + +void ERR_load_BIO_strings(void) {} + +void ERR_load_ERR_strings(void) {} + +struct err_save_state_st { + struct err_error_st *errors; + size_t num_errors; +}; + +void ERR_SAVE_STATE_free(ERR_SAVE_STATE *state) { + if (state == NULL) { + return; + } + for (size_t i = 0; i < state->num_errors; i++) { + err_clear(&state->errors[i]); + } + OPENSSL_free(state->errors); + OPENSSL_free(state); +} + +ERR_SAVE_STATE *ERR_save_state(void) { + ERR_STATE *const state = err_get_state(); + if (state == NULL || state->top == state->bottom) { + return NULL; + } + + ERR_SAVE_STATE *ret = OPENSSL_malloc(sizeof(ERR_SAVE_STATE)); + if (ret == NULL) { + return NULL; + } + + // Errors are stored in the range (bottom, top]. + size_t num_errors = state->top >= state->bottom + ? state->top - state->bottom + : ERR_NUM_ERRORS + state->top - state->bottom; + assert(num_errors < ERR_NUM_ERRORS); + ret->errors = OPENSSL_malloc(num_errors * sizeof(struct err_error_st)); + if (ret->errors == NULL) { + OPENSSL_free(ret); + return NULL; + } + OPENSSL_memset(ret->errors, 0, num_errors * sizeof(struct err_error_st)); + ret->num_errors = num_errors; + + for (size_t i = 0; i < num_errors; i++) { + size_t j = (state->bottom + i + 1) % ERR_NUM_ERRORS; + err_copy(&ret->errors[i], &state->errors[j]); + } + return ret; +} + +void ERR_restore_state(const ERR_SAVE_STATE *state) { + if (state == NULL || state->num_errors == 0) { + ERR_clear_error(); + return; + } + + ERR_STATE *const dst = err_get_state(); + if (dst == NULL) { + return; + } + + for (size_t i = 0; i < state->num_errors; i++) { + err_copy(&dst->errors[i], &state->errors[i]); + } + dst->top = state->num_errors - 1; + dst->bottom = ERR_NUM_ERRORS - 1; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/err/internal.h b/FoodApp/Pods/BoringSSL-GRPC/crypto/err/internal.h new file mode 100644 index 0000000..0945792 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/err/internal.h @@ -0,0 +1,58 @@ +/* Copyright (c) 2017, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_CRYPTO_ERR_INTERNAL_H +#define OPENSSL_HEADER_CRYPTO_ERR_INTERNAL_H + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// Private error queue functions. + +// ERR_SAVE_STATE contains a saved representation of the error queue. It is +// slightly more compact than |ERR_STATE| as the error queue will typically not +// contain |ERR_NUM_ERRORS| entries. +typedef struct err_save_state_st ERR_SAVE_STATE; + +// ERR_SAVE_STATE_free releases all memory associated with |state|. +OPENSSL_EXPORT void ERR_SAVE_STATE_free(ERR_SAVE_STATE *state); + +// ERR_save_state returns a newly-allocated |ERR_SAVE_STATE| structure +// containing the current state of the error queue or NULL on allocation +// error. It should be released with |ERR_SAVE_STATE_free|. +OPENSSL_EXPORT ERR_SAVE_STATE *ERR_save_state(void); + +// ERR_restore_state clears the error queue and replaces it with |state|. +OPENSSL_EXPORT void ERR_restore_state(const ERR_SAVE_STATE *state); + + +#if defined(__cplusplus) +} // extern C + +extern "C++" { + +namespace bssl { + +BORINGSSL_MAKE_DELETER(ERR_SAVE_STATE, ERR_SAVE_STATE_free) + +} // namespace bssl + +} // extern C++ +#endif + +#endif // OPENSSL_HEADER_CRYPTO_ERR_INTERNAL_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/err/internal.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/err/internal.h.grpc_back new file mode 100644 index 0000000..3f2397c --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/err/internal.h.grpc_back @@ -0,0 +1,58 @@ +/* Copyright (c) 2017, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_CRYPTO_ERR_INTERNAL_H +#define OPENSSL_HEADER_CRYPTO_ERR_INTERNAL_H + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// Private error queue functions. + +// ERR_SAVE_STATE contains a saved representation of the error queue. It is +// slightly more compact than |ERR_STATE| as the error queue will typically not +// contain |ERR_NUM_ERRORS| entries. +typedef struct err_save_state_st ERR_SAVE_STATE; + +// ERR_SAVE_STATE_free releases all memory associated with |state|. +OPENSSL_EXPORT void ERR_SAVE_STATE_free(ERR_SAVE_STATE *state); + +// ERR_save_state returns a newly-allocated |ERR_SAVE_STATE| structure +// containing the current state of the error queue or NULL on allocation +// error. It should be released with |ERR_SAVE_STATE_free|. +OPENSSL_EXPORT ERR_SAVE_STATE *ERR_save_state(void); + +// ERR_restore_state clears the error queue and replaces it with |state|. +OPENSSL_EXPORT void ERR_restore_state(const ERR_SAVE_STATE *state); + + +#if defined(__cplusplus) +} // extern C + +extern "C++" { + +namespace bssl { + +BORINGSSL_MAKE_DELETER(ERR_SAVE_STATE, ERR_SAVE_STATE_free) + +} // namespace bssl + +} // extern C++ +#endif + +#endif // OPENSSL_HEADER_CRYPTO_ERR_INTERNAL_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/digestsign.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/digestsign.c new file mode 100644 index 0000000..614da35 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/digestsign.c @@ -0,0 +1,231 @@ +/* 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 + +#include "internal.h" +#include "../fipsmodule/digest/internal.h" + + +enum evp_sign_verify_t { + evp_sign, + evp_verify, +}; + +static const struct evp_md_pctx_ops md_pctx_ops = { + EVP_PKEY_CTX_free, + EVP_PKEY_CTX_dup, +}; + +static int uses_prehash(EVP_MD_CTX *ctx, enum evp_sign_verify_t op) { + return (op == evp_sign) ? (ctx->pctx->pmeth->sign != NULL) + : (ctx->pctx->pmeth->verify != NULL); +} + +static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, + const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey, + enum evp_sign_verify_t op) { + if (ctx->pctx == NULL) { + ctx->pctx = EVP_PKEY_CTX_new(pkey, e); + } + if (ctx->pctx == NULL) { + return 0; + } + ctx->pctx_ops = &md_pctx_ops; + + if (op == evp_verify) { + if (!EVP_PKEY_verify_init(ctx->pctx)) { + return 0; + } + } else { + if (!EVP_PKEY_sign_init(ctx->pctx)) { + return 0; + } + } + + if (type != NULL && + !EVP_PKEY_CTX_set_signature_md(ctx->pctx, type)) { + return 0; + } + + if (uses_prehash(ctx, op)) { + if (type == NULL) { + OPENSSL_PUT_ERROR(EVP, EVP_R_NO_DEFAULT_DIGEST); + return 0; + } + if (!EVP_DigestInit_ex(ctx, type, e)) { + return 0; + } + } + + if (pctx) { + *pctx = ctx->pctx; + } + 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, evp_sign); +} + +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, evp_verify); +} + +int EVP_DigestSignUpdate(EVP_MD_CTX *ctx, const void *data, size_t len) { + if (!uses_prehash(ctx, evp_sign)) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return 0; + } + + return EVP_DigestUpdate(ctx, data, len); +} + +int EVP_DigestVerifyUpdate(EVP_MD_CTX *ctx, const void *data, size_t len) { + if (!uses_prehash(ctx, evp_verify)) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return 0; + } + + return EVP_DigestUpdate(ctx, data, len); +} + +int EVP_DigestSignFinal(EVP_MD_CTX *ctx, uint8_t *out_sig, + size_t *out_sig_len) { + if (!uses_prehash(ctx, evp_sign)) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return 0; + } + + if (out_sig) { + EVP_MD_CTX tmp_ctx; + int ret; + uint8_t md[EVP_MAX_MD_SIZE]; + unsigned int mdlen; + + EVP_MD_CTX_init(&tmp_ctx); + ret = EVP_MD_CTX_copy_ex(&tmp_ctx, ctx) && + EVP_DigestFinal_ex(&tmp_ctx, md, &mdlen) && + EVP_PKEY_sign(ctx->pctx, out_sig, out_sig_len, md, mdlen); + EVP_MD_CTX_cleanup(&tmp_ctx); + + return ret; + } else { + size_t s = EVP_MD_size(ctx->digest); + return EVP_PKEY_sign(ctx->pctx, out_sig, out_sig_len, NULL, s); + } +} + +int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const uint8_t *sig, + size_t sig_len) { + if (!uses_prehash(ctx, evp_verify)) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return 0; + } + + EVP_MD_CTX tmp_ctx; + int ret; + uint8_t md[EVP_MAX_MD_SIZE]; + unsigned int mdlen; + + EVP_MD_CTX_init(&tmp_ctx); + ret = EVP_MD_CTX_copy_ex(&tmp_ctx, ctx) && + EVP_DigestFinal_ex(&tmp_ctx, md, &mdlen) && + EVP_PKEY_verify(ctx->pctx, sig, sig_len, md, mdlen); + EVP_MD_CTX_cleanup(&tmp_ctx); + + return ret; +} + +int EVP_DigestSign(EVP_MD_CTX *ctx, uint8_t *out_sig, size_t *out_sig_len, + const uint8_t *data, size_t data_len) { + if (uses_prehash(ctx, evp_sign)) { + // If |out_sig| is NULL, the caller is only querying the maximum output + // length. |data| should only be incorporated in the final call. + if (out_sig != NULL && + !EVP_DigestSignUpdate(ctx, data, data_len)) { + return 0; + } + + return EVP_DigestSignFinal(ctx, out_sig, out_sig_len); + } + + if (ctx->pctx->pmeth->sign_message == NULL) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return 0; + } + + return ctx->pctx->pmeth->sign_message(ctx->pctx, out_sig, out_sig_len, data, + data_len); +} + +int EVP_DigestVerify(EVP_MD_CTX *ctx, const uint8_t *sig, size_t sig_len, + const uint8_t *data, size_t len) { + if (uses_prehash(ctx, evp_verify)) { + return EVP_DigestVerifyUpdate(ctx, data, len) && + EVP_DigestVerifyFinal(ctx, sig, sig_len); + } + + if (ctx->pctx->pmeth->verify_message == NULL) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return 0; + } + + return ctx->pctx->pmeth->verify_message(ctx->pctx, sig, sig_len, data, len); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/digestsign.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/digestsign.c.grpc_back new file mode 100644 index 0000000..6e4d305 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/digestsign.c.grpc_back @@ -0,0 +1,231 @@ +/* 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 + +#include "internal.h" +#include "../fipsmodule/digest/internal.h" + + +enum evp_sign_verify_t { + evp_sign, + evp_verify, +}; + +static const struct evp_md_pctx_ops md_pctx_ops = { + EVP_PKEY_CTX_free, + EVP_PKEY_CTX_dup, +}; + +static int uses_prehash(EVP_MD_CTX *ctx, enum evp_sign_verify_t op) { + return (op == evp_sign) ? (ctx->pctx->pmeth->sign != NULL) + : (ctx->pctx->pmeth->verify != NULL); +} + +static int do_sigver_init(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, + const EVP_MD *type, ENGINE *e, EVP_PKEY *pkey, + enum evp_sign_verify_t op) { + if (ctx->pctx == NULL) { + ctx->pctx = EVP_PKEY_CTX_new(pkey, e); + } + if (ctx->pctx == NULL) { + return 0; + } + ctx->pctx_ops = &md_pctx_ops; + + if (op == evp_verify) { + if (!EVP_PKEY_verify_init(ctx->pctx)) { + return 0; + } + } else { + if (!EVP_PKEY_sign_init(ctx->pctx)) { + return 0; + } + } + + if (type != NULL && + !EVP_PKEY_CTX_set_signature_md(ctx->pctx, type)) { + return 0; + } + + if (uses_prehash(ctx, op)) { + if (type == NULL) { + OPENSSL_PUT_ERROR(EVP, EVP_R_NO_DEFAULT_DIGEST); + return 0; + } + if (!EVP_DigestInit_ex(ctx, type, e)) { + return 0; + } + } + + if (pctx) { + *pctx = ctx->pctx; + } + 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, evp_sign); +} + +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, evp_verify); +} + +int EVP_DigestSignUpdate(EVP_MD_CTX *ctx, const void *data, size_t len) { + if (!uses_prehash(ctx, evp_sign)) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return 0; + } + + return EVP_DigestUpdate(ctx, data, len); +} + +int EVP_DigestVerifyUpdate(EVP_MD_CTX *ctx, const void *data, size_t len) { + if (!uses_prehash(ctx, evp_verify)) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return 0; + } + + return EVP_DigestUpdate(ctx, data, len); +} + +int EVP_DigestSignFinal(EVP_MD_CTX *ctx, uint8_t *out_sig, + size_t *out_sig_len) { + if (!uses_prehash(ctx, evp_sign)) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return 0; + } + + if (out_sig) { + EVP_MD_CTX tmp_ctx; + int ret; + uint8_t md[EVP_MAX_MD_SIZE]; + unsigned int mdlen; + + EVP_MD_CTX_init(&tmp_ctx); + ret = EVP_MD_CTX_copy_ex(&tmp_ctx, ctx) && + EVP_DigestFinal_ex(&tmp_ctx, md, &mdlen) && + EVP_PKEY_sign(ctx->pctx, out_sig, out_sig_len, md, mdlen); + EVP_MD_CTX_cleanup(&tmp_ctx); + + return ret; + } else { + size_t s = EVP_MD_size(ctx->digest); + return EVP_PKEY_sign(ctx->pctx, out_sig, out_sig_len, NULL, s); + } +} + +int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const uint8_t *sig, + size_t sig_len) { + if (!uses_prehash(ctx, evp_verify)) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return 0; + } + + EVP_MD_CTX tmp_ctx; + int ret; + uint8_t md[EVP_MAX_MD_SIZE]; + unsigned int mdlen; + + EVP_MD_CTX_init(&tmp_ctx); + ret = EVP_MD_CTX_copy_ex(&tmp_ctx, ctx) && + EVP_DigestFinal_ex(&tmp_ctx, md, &mdlen) && + EVP_PKEY_verify(ctx->pctx, sig, sig_len, md, mdlen); + EVP_MD_CTX_cleanup(&tmp_ctx); + + return ret; +} + +int EVP_DigestSign(EVP_MD_CTX *ctx, uint8_t *out_sig, size_t *out_sig_len, + const uint8_t *data, size_t data_len) { + if (uses_prehash(ctx, evp_sign)) { + // If |out_sig| is NULL, the caller is only querying the maximum output + // length. |data| should only be incorporated in the final call. + if (out_sig != NULL && + !EVP_DigestSignUpdate(ctx, data, data_len)) { + return 0; + } + + return EVP_DigestSignFinal(ctx, out_sig, out_sig_len); + } + + if (ctx->pctx->pmeth->sign_message == NULL) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return 0; + } + + return ctx->pctx->pmeth->sign_message(ctx->pctx, out_sig, out_sig_len, data, + data_len); +} + +int EVP_DigestVerify(EVP_MD_CTX *ctx, const uint8_t *sig, size_t sig_len, + const uint8_t *data, size_t len) { + if (uses_prehash(ctx, evp_verify)) { + return EVP_DigestVerifyUpdate(ctx, data, len) && + EVP_DigestVerifyFinal(ctx, sig, sig_len); + } + + if (ctx->pctx->pmeth->verify_message == NULL) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return 0; + } + + return ctx->pctx->pmeth->verify_message(ctx->pctx, sig, sig_len, data, len); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/evp.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/evp.c new file mode 100644 index 0000000..6911771 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/evp.c @@ -0,0 +1,362 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 +#include +#include +#include +#include +#include + +#include "internal.h" +#include "../internal.h" + + +EVP_PKEY *EVP_PKEY_new(void) { + EVP_PKEY *ret; + + ret = OPENSSL_malloc(sizeof(EVP_PKEY)); + if (ret == NULL) { + OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); + return NULL; + } + + OPENSSL_memset(ret, 0, sizeof(EVP_PKEY)); + ret->type = EVP_PKEY_NONE; + ret->references = 1; + + return ret; +} + +static void free_it(EVP_PKEY *pkey) { + if (pkey->ameth && pkey->ameth->pkey_free) { + pkey->ameth->pkey_free(pkey); + pkey->pkey.ptr = NULL; + pkey->type = EVP_PKEY_NONE; + } +} + +void EVP_PKEY_free(EVP_PKEY *pkey) { + if (pkey == NULL) { + return; + } + + if (!CRYPTO_refcount_dec_and_test_zero(&pkey->references)) { + return; + } + + free_it(pkey); + OPENSSL_free(pkey); +} + +int EVP_PKEY_up_ref(EVP_PKEY *pkey) { + CRYPTO_refcount_inc(&pkey->references); + return 1; +} + +int EVP_PKEY_is_opaque(const EVP_PKEY *pkey) { + if (pkey->ameth && pkey->ameth->pkey_opaque) { + return pkey->ameth->pkey_opaque(pkey); + } + return 0; +} + +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; +} + +int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from) { + if (to->type != from->type) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DIFFERENT_KEY_TYPES); + goto err; + } + + if (EVP_PKEY_missing_parameters(from)) { + OPENSSL_PUT_ERROR(EVP, EVP_R_MISSING_PARAMETERS); + goto err; + } + + 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_size(const EVP_PKEY *pkey) { + if (pkey && pkey->ameth && pkey->ameth->pkey_size) { + return pkey->ameth->pkey_size(pkey); + } + return 0; +} + +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_id(const EVP_PKEY *pkey) { + return pkey->type; +} + +// evp_pkey_asn1_find returns the ASN.1 method table for the given |nid|, which +// should be one of the |EVP_PKEY_*| values. It returns NULL if |nid| is +// unknown. +static const EVP_PKEY_ASN1_METHOD *evp_pkey_asn1_find(int nid) { + switch (nid) { + case EVP_PKEY_RSA: + return &rsa_asn1_meth; + case EVP_PKEY_EC: + return &ec_asn1_meth; + case EVP_PKEY_DSA: + return &dsa_asn1_meth; + case EVP_PKEY_ED25519: + return &ed25519_asn1_meth; + default: + return NULL; + } +} + +int EVP_PKEY_type(int nid) { + const EVP_PKEY_ASN1_METHOD *meth = evp_pkey_asn1_find(nid); + if (meth == NULL) { + return NID_undef; + } + return meth->pkey_id; +} + +int EVP_PKEY_set1_RSA(EVP_PKEY *pkey, RSA *key) { + if (EVP_PKEY_assign_RSA(pkey, key)) { + RSA_up_ref(key); + return 1; + } + return 0; +} + +int EVP_PKEY_assign_RSA(EVP_PKEY *pkey, RSA *key) { + return EVP_PKEY_assign(pkey, EVP_PKEY_RSA, key); +} + +RSA *EVP_PKEY_get0_RSA(EVP_PKEY *pkey) { + if (pkey->type != EVP_PKEY_RSA) { + OPENSSL_PUT_ERROR(EVP, EVP_R_EXPECTING_AN_RSA_KEY); + return NULL; + } + return pkey->pkey.rsa; +} + +RSA *EVP_PKEY_get1_RSA(EVP_PKEY *pkey) { + RSA *rsa = EVP_PKEY_get0_RSA(pkey); + if (rsa != NULL) { + RSA_up_ref(rsa); + } + return rsa; +} + +int EVP_PKEY_set1_DSA(EVP_PKEY *pkey, DSA *key) { + if (EVP_PKEY_assign_DSA(pkey, key)) { + DSA_up_ref(key); + return 1; + } + return 0; +} + +int EVP_PKEY_assign_DSA(EVP_PKEY *pkey, DSA *key) { + return EVP_PKEY_assign(pkey, EVP_PKEY_DSA, key); +} + +DSA *EVP_PKEY_get0_DSA(EVP_PKEY *pkey) { + if (pkey->type != EVP_PKEY_DSA) { + OPENSSL_PUT_ERROR(EVP, EVP_R_EXPECTING_A_DSA_KEY); + return NULL; + } + return pkey->pkey.dsa; +} + +DSA *EVP_PKEY_get1_DSA(EVP_PKEY *pkey) { + DSA *dsa = EVP_PKEY_get0_DSA(pkey); + if (dsa != NULL) { + DSA_up_ref(dsa); + } + return dsa; +} + +int EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey, EC_KEY *key) { + if (EVP_PKEY_assign_EC_KEY(pkey, key)) { + EC_KEY_up_ref(key); + return 1; + } + return 0; +} + +int EVP_PKEY_assign_EC_KEY(EVP_PKEY *pkey, EC_KEY *key) { + return EVP_PKEY_assign(pkey, EVP_PKEY_EC, key); +} + +EC_KEY *EVP_PKEY_get0_EC_KEY(EVP_PKEY *pkey) { + if (pkey->type != EVP_PKEY_EC) { + OPENSSL_PUT_ERROR(EVP, EVP_R_EXPECTING_AN_EC_KEY_KEY); + return NULL; + } + return pkey->pkey.ec; +} + +EC_KEY *EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey) { + EC_KEY *ec_key = EVP_PKEY_get0_EC_KEY(pkey); + if (ec_key != NULL) { + EC_KEY_up_ref(ec_key); + } + return ec_key; +} + +DH *EVP_PKEY_get0_DH(EVP_PKEY *pkey) { return NULL; } + +int EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key) { + if (!EVP_PKEY_set_type(pkey, type)) { + return 0; + } + pkey->pkey.ptr = key; + return key != NULL; +} + +int EVP_PKEY_set_type(EVP_PKEY *pkey, int type) { + const EVP_PKEY_ASN1_METHOD *ameth; + + if (pkey && pkey->pkey.ptr) { + free_it(pkey); + } + + ameth = evp_pkey_asn1_find(type); + if (ameth == NULL) { + OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM); + ERR_add_error_dataf("algorithm %d", type); + return 0; + } + + if (pkey) { + pkey->ameth = ameth; + pkey->type = pkey->ameth->pkey_id; + } + + return 1; +} + + + +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_CTX_set_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD *md) { + return EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_TYPE_SIG, EVP_PKEY_CTRL_MD, 0, + (void *)md); +} + +int EVP_PKEY_CTX_get_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD **out_md) { + return EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_TYPE_SIG, EVP_PKEY_CTRL_GET_MD, + 0, (void *)out_md); +} + +void OpenSSL_add_all_algorithms(void) {} + +void OPENSSL_add_all_algorithms_conf(void) {} + +void OpenSSL_add_all_ciphers(void) {} + +void OpenSSL_add_all_digests(void) {} + +void EVP_cleanup(void) {} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/evp.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/evp.c.grpc_back new file mode 100644 index 0000000..ad5f85b --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/evp.c.grpc_back @@ -0,0 +1,362 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 +#include +#include +#include +#include +#include + +#include "internal.h" +#include "../internal.h" + + +EVP_PKEY *EVP_PKEY_new(void) { + EVP_PKEY *ret; + + ret = OPENSSL_malloc(sizeof(EVP_PKEY)); + if (ret == NULL) { + OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); + return NULL; + } + + OPENSSL_memset(ret, 0, sizeof(EVP_PKEY)); + ret->type = EVP_PKEY_NONE; + ret->references = 1; + + return ret; +} + +static void free_it(EVP_PKEY *pkey) { + if (pkey->ameth && pkey->ameth->pkey_free) { + pkey->ameth->pkey_free(pkey); + pkey->pkey.ptr = NULL; + pkey->type = EVP_PKEY_NONE; + } +} + +void EVP_PKEY_free(EVP_PKEY *pkey) { + if (pkey == NULL) { + return; + } + + if (!CRYPTO_refcount_dec_and_test_zero(&pkey->references)) { + return; + } + + free_it(pkey); + OPENSSL_free(pkey); +} + +int EVP_PKEY_up_ref(EVP_PKEY *pkey) { + CRYPTO_refcount_inc(&pkey->references); + return 1; +} + +int EVP_PKEY_is_opaque(const EVP_PKEY *pkey) { + if (pkey->ameth && pkey->ameth->pkey_opaque) { + return pkey->ameth->pkey_opaque(pkey); + } + return 0; +} + +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; +} + +int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from) { + if (to->type != from->type) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DIFFERENT_KEY_TYPES); + goto err; + } + + if (EVP_PKEY_missing_parameters(from)) { + OPENSSL_PUT_ERROR(EVP, EVP_R_MISSING_PARAMETERS); + goto err; + } + + 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_size(const EVP_PKEY *pkey) { + if (pkey && pkey->ameth && pkey->ameth->pkey_size) { + return pkey->ameth->pkey_size(pkey); + } + return 0; +} + +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_id(const EVP_PKEY *pkey) { + return pkey->type; +} + +// evp_pkey_asn1_find returns the ASN.1 method table for the given |nid|, which +// should be one of the |EVP_PKEY_*| values. It returns NULL if |nid| is +// unknown. +static const EVP_PKEY_ASN1_METHOD *evp_pkey_asn1_find(int nid) { + switch (nid) { + case EVP_PKEY_RSA: + return &rsa_asn1_meth; + case EVP_PKEY_EC: + return &ec_asn1_meth; + case EVP_PKEY_DSA: + return &dsa_asn1_meth; + case EVP_PKEY_ED25519: + return &ed25519_asn1_meth; + default: + return NULL; + } +} + +int EVP_PKEY_type(int nid) { + const EVP_PKEY_ASN1_METHOD *meth = evp_pkey_asn1_find(nid); + if (meth == NULL) { + return NID_undef; + } + return meth->pkey_id; +} + +int EVP_PKEY_set1_RSA(EVP_PKEY *pkey, RSA *key) { + if (EVP_PKEY_assign_RSA(pkey, key)) { + RSA_up_ref(key); + return 1; + } + return 0; +} + +int EVP_PKEY_assign_RSA(EVP_PKEY *pkey, RSA *key) { + return EVP_PKEY_assign(pkey, EVP_PKEY_RSA, key); +} + +RSA *EVP_PKEY_get0_RSA(EVP_PKEY *pkey) { + if (pkey->type != EVP_PKEY_RSA) { + OPENSSL_PUT_ERROR(EVP, EVP_R_EXPECTING_AN_RSA_KEY); + return NULL; + } + return pkey->pkey.rsa; +} + +RSA *EVP_PKEY_get1_RSA(EVP_PKEY *pkey) { + RSA *rsa = EVP_PKEY_get0_RSA(pkey); + if (rsa != NULL) { + RSA_up_ref(rsa); + } + return rsa; +} + +int EVP_PKEY_set1_DSA(EVP_PKEY *pkey, DSA *key) { + if (EVP_PKEY_assign_DSA(pkey, key)) { + DSA_up_ref(key); + return 1; + } + return 0; +} + +int EVP_PKEY_assign_DSA(EVP_PKEY *pkey, DSA *key) { + return EVP_PKEY_assign(pkey, EVP_PKEY_DSA, key); +} + +DSA *EVP_PKEY_get0_DSA(EVP_PKEY *pkey) { + if (pkey->type != EVP_PKEY_DSA) { + OPENSSL_PUT_ERROR(EVP, EVP_R_EXPECTING_A_DSA_KEY); + return NULL; + } + return pkey->pkey.dsa; +} + +DSA *EVP_PKEY_get1_DSA(EVP_PKEY *pkey) { + DSA *dsa = EVP_PKEY_get0_DSA(pkey); + if (dsa != NULL) { + DSA_up_ref(dsa); + } + return dsa; +} + +int EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey, EC_KEY *key) { + if (EVP_PKEY_assign_EC_KEY(pkey, key)) { + EC_KEY_up_ref(key); + return 1; + } + return 0; +} + +int EVP_PKEY_assign_EC_KEY(EVP_PKEY *pkey, EC_KEY *key) { + return EVP_PKEY_assign(pkey, EVP_PKEY_EC, key); +} + +EC_KEY *EVP_PKEY_get0_EC_KEY(EVP_PKEY *pkey) { + if (pkey->type != EVP_PKEY_EC) { + OPENSSL_PUT_ERROR(EVP, EVP_R_EXPECTING_AN_EC_KEY_KEY); + return NULL; + } + return pkey->pkey.ec; +} + +EC_KEY *EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey) { + EC_KEY *ec_key = EVP_PKEY_get0_EC_KEY(pkey); + if (ec_key != NULL) { + EC_KEY_up_ref(ec_key); + } + return ec_key; +} + +DH *EVP_PKEY_get0_DH(EVP_PKEY *pkey) { return NULL; } + +int EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key) { + if (!EVP_PKEY_set_type(pkey, type)) { + return 0; + } + pkey->pkey.ptr = key; + return key != NULL; +} + +int EVP_PKEY_set_type(EVP_PKEY *pkey, int type) { + const EVP_PKEY_ASN1_METHOD *ameth; + + if (pkey && pkey->pkey.ptr) { + free_it(pkey); + } + + ameth = evp_pkey_asn1_find(type); + if (ameth == NULL) { + OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM); + ERR_add_error_dataf("algorithm %d", type); + return 0; + } + + if (pkey) { + pkey->ameth = ameth; + pkey->type = pkey->ameth->pkey_id; + } + + return 1; +} + + + +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_CTX_set_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD *md) { + return EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_TYPE_SIG, EVP_PKEY_CTRL_MD, 0, + (void *)md); +} + +int EVP_PKEY_CTX_get_signature_md(EVP_PKEY_CTX *ctx, const EVP_MD **out_md) { + return EVP_PKEY_CTX_ctrl(ctx, -1, EVP_PKEY_OP_TYPE_SIG, EVP_PKEY_CTRL_GET_MD, + 0, (void *)out_md); +} + +void OpenSSL_add_all_algorithms(void) {} + +void OPENSSL_add_all_algorithms_conf(void) {} + +void OpenSSL_add_all_ciphers(void) {} + +void OpenSSL_add_all_digests(void) {} + +void EVP_cleanup(void) {} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/evp_asn1.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/evp_asn1.c new file mode 100644 index 0000000..7d86fbc --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/evp_asn1.c @@ -0,0 +1,337 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 +#include +#include + +#include "internal.h" +#include "../internal.h" + + +static const EVP_PKEY_ASN1_METHOD *const kASN1Methods[] = { + &rsa_asn1_meth, + &ec_asn1_meth, + &dsa_asn1_meth, + &ed25519_asn1_meth, +}; + +static int parse_key_type(CBS *cbs, int *out_type) { + CBS oid; + if (!CBS_get_asn1(cbs, &oid, CBS_ASN1_OBJECT)) { + return 0; + } + + for (unsigned i = 0; i < OPENSSL_ARRAY_SIZE(kASN1Methods); i++) { + const EVP_PKEY_ASN1_METHOD *method = kASN1Methods[i]; + if (CBS_len(&oid) == method->oid_len && + OPENSSL_memcmp(CBS_data(&oid), method->oid, method->oid_len) == 0) { + *out_type = method->pkey_id; + return 1; + } + } + + return 0; +} + +EVP_PKEY *EVP_parse_public_key(CBS *cbs) { + // Parse the SubjectPublicKeyInfo. + CBS spki, algorithm, key; + int type; + uint8_t padding; + if (!CBS_get_asn1(cbs, &spki, CBS_ASN1_SEQUENCE) || + !CBS_get_asn1(&spki, &algorithm, CBS_ASN1_SEQUENCE) || + !parse_key_type(&algorithm, &type) || + !CBS_get_asn1(&spki, &key, CBS_ASN1_BITSTRING) || + CBS_len(&spki) != 0 || + // Every key type defined encodes the key as a byte string with the same + // conversion to BIT STRING. + !CBS_get_u8(&key, &padding) || + padding != 0) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + return NULL; + } + + // Set up an |EVP_PKEY| of the appropriate type. + EVP_PKEY *ret = EVP_PKEY_new(); + if (ret == NULL || + !EVP_PKEY_set_type(ret, type)) { + goto err; + } + + // Call into the type-specific SPKI decoding function. + if (ret->ameth->pub_decode == NULL) { + OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM); + goto err; + } + if (!ret->ameth->pub_decode(ret, &algorithm, &key)) { + goto err; + } + + return ret; + +err: + EVP_PKEY_free(ret); + return NULL; +} + +int EVP_marshal_public_key(CBB *cbb, const EVP_PKEY *key) { + if (key->ameth == NULL || key->ameth->pub_encode == NULL) { + OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM); + return 0; + } + + return key->ameth->pub_encode(cbb, key); +} + +EVP_PKEY *EVP_parse_private_key(CBS *cbs) { + // Parse the PrivateKeyInfo. + CBS pkcs8, algorithm, key; + uint64_t version; + int type; + if (!CBS_get_asn1(cbs, &pkcs8, CBS_ASN1_SEQUENCE) || + !CBS_get_asn1_uint64(&pkcs8, &version) || + version != 0 || + !CBS_get_asn1(&pkcs8, &algorithm, CBS_ASN1_SEQUENCE) || + !parse_key_type(&algorithm, &type) || + !CBS_get_asn1(&pkcs8, &key, CBS_ASN1_OCTETSTRING)) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + return NULL; + } + + // A PrivateKeyInfo ends with a SET of Attributes which we ignore. + + // Set up an |EVP_PKEY| of the appropriate type. + EVP_PKEY *ret = EVP_PKEY_new(); + if (ret == NULL || + !EVP_PKEY_set_type(ret, type)) { + goto err; + } + + // Call into the type-specific PrivateKeyInfo decoding function. + if (ret->ameth->priv_decode == NULL) { + OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM); + goto err; + } + if (!ret->ameth->priv_decode(ret, &algorithm, &key)) { + goto err; + } + + return ret; + +err: + EVP_PKEY_free(ret); + return NULL; +} + +int EVP_marshal_private_key(CBB *cbb, const EVP_PKEY *key) { + if (key->ameth == NULL || key->ameth->priv_encode == NULL) { + OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM); + return 0; + } + + return key->ameth->priv_encode(cbb, key); +} + +static EVP_PKEY *old_priv_decode(CBS *cbs, int type) { + EVP_PKEY *ret = EVP_PKEY_new(); + if (ret == NULL) { + return NULL; + } + + switch (type) { + case EVP_PKEY_EC: { + EC_KEY *ec_key = EC_KEY_parse_private_key(cbs, NULL); + if (ec_key == NULL || !EVP_PKEY_assign_EC_KEY(ret, ec_key)) { + EC_KEY_free(ec_key); + goto err; + } + return ret; + } + case EVP_PKEY_DSA: { + DSA *dsa = DSA_parse_private_key(cbs); + if (dsa == NULL || !EVP_PKEY_assign_DSA(ret, dsa)) { + DSA_free(dsa); + goto err; + } + return ret; + } + case EVP_PKEY_RSA: { + RSA *rsa = RSA_parse_private_key(cbs); + if (rsa == NULL || !EVP_PKEY_assign_RSA(ret, rsa)) { + RSA_free(rsa); + goto err; + } + return ret; + } + default: + OPENSSL_PUT_ERROR(EVP, EVP_R_UNKNOWN_PUBLIC_KEY_TYPE); + goto err; + } + +err: + EVP_PKEY_free(ret); + return NULL; +} + +EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **out, const uint8_t **inp, + long len) { + if (len < 0) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + return NULL; + } + + // Parse with the legacy format. + CBS cbs; + CBS_init(&cbs, *inp, (size_t)len); + EVP_PKEY *ret = old_priv_decode(&cbs, type); + if (ret == NULL) { + // Try again with PKCS#8. + ERR_clear_error(); + CBS_init(&cbs, *inp, (size_t)len); + ret = EVP_parse_private_key(&cbs); + if (ret == NULL) { + return NULL; + } + if (ret->type != type) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DIFFERENT_KEY_TYPES); + EVP_PKEY_free(ret); + return NULL; + } + } + + if (out != NULL) { + EVP_PKEY_free(*out); + *out = ret; + } + *inp = CBS_data(&cbs); + return ret; +} + +// num_elements parses one SEQUENCE from |in| and returns the number of elements +// in it. On parse error, it returns zero. +static size_t num_elements(const uint8_t *in, size_t in_len) { + CBS cbs, sequence; + CBS_init(&cbs, in, (size_t)in_len); + + if (!CBS_get_asn1(&cbs, &sequence, CBS_ASN1_SEQUENCE)) { + return 0; + } + + size_t count = 0; + while (CBS_len(&sequence) > 0) { + if (!CBS_get_any_asn1_element(&sequence, NULL, NULL, NULL)) { + return 0; + } + + count++; + } + + return count; +} + +EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **out, const uint8_t **inp, long len) { + if (len < 0) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + return NULL; + } + + // Parse the input as a PKCS#8 PrivateKeyInfo. + CBS cbs; + CBS_init(&cbs, *inp, (size_t)len); + EVP_PKEY *ret = EVP_parse_private_key(&cbs); + if (ret != NULL) { + if (out != NULL) { + EVP_PKEY_free(*out); + *out = ret; + } + *inp = CBS_data(&cbs); + return ret; + } + ERR_clear_error(); + + // Count the elements to determine the legacy key format. + switch (num_elements(*inp, (size_t)len)) { + case 4: + return d2i_PrivateKey(EVP_PKEY_EC, out, inp, len); + + case 6: + return d2i_PrivateKey(EVP_PKEY_DSA, out, inp, len); + + default: + return d2i_PrivateKey(EVP_PKEY_RSA, out, inp, len); + } +} + +int i2d_PublicKey(EVP_PKEY *key, uint8_t **outp) { + switch (key->type) { + case EVP_PKEY_RSA: + return i2d_RSAPublicKey(key->pkey.rsa, outp); + case EVP_PKEY_DSA: + return i2d_DSAPublicKey(key->pkey.dsa, outp); + case EVP_PKEY_EC: + return i2o_ECPublicKey(key->pkey.ec, outp); + default: + OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_PUBLIC_KEY_TYPE); + return -1; + } +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/evp_asn1.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/evp_asn1.c.grpc_back new file mode 100644 index 0000000..bcb86d7 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/evp_asn1.c.grpc_back @@ -0,0 +1,337 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 +#include +#include + +#include "internal.h" +#include "../internal.h" + + +static const EVP_PKEY_ASN1_METHOD *const kASN1Methods[] = { + &rsa_asn1_meth, + &ec_asn1_meth, + &dsa_asn1_meth, + &ed25519_asn1_meth, +}; + +static int parse_key_type(CBS *cbs, int *out_type) { + CBS oid; + if (!CBS_get_asn1(cbs, &oid, CBS_ASN1_OBJECT)) { + return 0; + } + + for (unsigned i = 0; i < OPENSSL_ARRAY_SIZE(kASN1Methods); i++) { + const EVP_PKEY_ASN1_METHOD *method = kASN1Methods[i]; + if (CBS_len(&oid) == method->oid_len && + OPENSSL_memcmp(CBS_data(&oid), method->oid, method->oid_len) == 0) { + *out_type = method->pkey_id; + return 1; + } + } + + return 0; +} + +EVP_PKEY *EVP_parse_public_key(CBS *cbs) { + // Parse the SubjectPublicKeyInfo. + CBS spki, algorithm, key; + int type; + uint8_t padding; + if (!CBS_get_asn1(cbs, &spki, CBS_ASN1_SEQUENCE) || + !CBS_get_asn1(&spki, &algorithm, CBS_ASN1_SEQUENCE) || + !parse_key_type(&algorithm, &type) || + !CBS_get_asn1(&spki, &key, CBS_ASN1_BITSTRING) || + CBS_len(&spki) != 0 || + // Every key type defined encodes the key as a byte string with the same + // conversion to BIT STRING. + !CBS_get_u8(&key, &padding) || + padding != 0) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + return NULL; + } + + // Set up an |EVP_PKEY| of the appropriate type. + EVP_PKEY *ret = EVP_PKEY_new(); + if (ret == NULL || + !EVP_PKEY_set_type(ret, type)) { + goto err; + } + + // Call into the type-specific SPKI decoding function. + if (ret->ameth->pub_decode == NULL) { + OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM); + goto err; + } + if (!ret->ameth->pub_decode(ret, &algorithm, &key)) { + goto err; + } + + return ret; + +err: + EVP_PKEY_free(ret); + return NULL; +} + +int EVP_marshal_public_key(CBB *cbb, const EVP_PKEY *key) { + if (key->ameth == NULL || key->ameth->pub_encode == NULL) { + OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM); + return 0; + } + + return key->ameth->pub_encode(cbb, key); +} + +EVP_PKEY *EVP_parse_private_key(CBS *cbs) { + // Parse the PrivateKeyInfo. + CBS pkcs8, algorithm, key; + uint64_t version; + int type; + if (!CBS_get_asn1(cbs, &pkcs8, CBS_ASN1_SEQUENCE) || + !CBS_get_asn1_uint64(&pkcs8, &version) || + version != 0 || + !CBS_get_asn1(&pkcs8, &algorithm, CBS_ASN1_SEQUENCE) || + !parse_key_type(&algorithm, &type) || + !CBS_get_asn1(&pkcs8, &key, CBS_ASN1_OCTETSTRING)) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + return NULL; + } + + // A PrivateKeyInfo ends with a SET of Attributes which we ignore. + + // Set up an |EVP_PKEY| of the appropriate type. + EVP_PKEY *ret = EVP_PKEY_new(); + if (ret == NULL || + !EVP_PKEY_set_type(ret, type)) { + goto err; + } + + // Call into the type-specific PrivateKeyInfo decoding function. + if (ret->ameth->priv_decode == NULL) { + OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM); + goto err; + } + if (!ret->ameth->priv_decode(ret, &algorithm, &key)) { + goto err; + } + + return ret; + +err: + EVP_PKEY_free(ret); + return NULL; +} + +int EVP_marshal_private_key(CBB *cbb, const EVP_PKEY *key) { + if (key->ameth == NULL || key->ameth->priv_encode == NULL) { + OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM); + return 0; + } + + return key->ameth->priv_encode(cbb, key); +} + +static EVP_PKEY *old_priv_decode(CBS *cbs, int type) { + EVP_PKEY *ret = EVP_PKEY_new(); + if (ret == NULL) { + return NULL; + } + + switch (type) { + case EVP_PKEY_EC: { + EC_KEY *ec_key = EC_KEY_parse_private_key(cbs, NULL); + if (ec_key == NULL || !EVP_PKEY_assign_EC_KEY(ret, ec_key)) { + EC_KEY_free(ec_key); + goto err; + } + return ret; + } + case EVP_PKEY_DSA: { + DSA *dsa = DSA_parse_private_key(cbs); + if (dsa == NULL || !EVP_PKEY_assign_DSA(ret, dsa)) { + DSA_free(dsa); + goto err; + } + return ret; + } + case EVP_PKEY_RSA: { + RSA *rsa = RSA_parse_private_key(cbs); + if (rsa == NULL || !EVP_PKEY_assign_RSA(ret, rsa)) { + RSA_free(rsa); + goto err; + } + return ret; + } + default: + OPENSSL_PUT_ERROR(EVP, EVP_R_UNKNOWN_PUBLIC_KEY_TYPE); + goto err; + } + +err: + EVP_PKEY_free(ret); + return NULL; +} + +EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **out, const uint8_t **inp, + long len) { + if (len < 0) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + return NULL; + } + + // Parse with the legacy format. + CBS cbs; + CBS_init(&cbs, *inp, (size_t)len); + EVP_PKEY *ret = old_priv_decode(&cbs, type); + if (ret == NULL) { + // Try again with PKCS#8. + ERR_clear_error(); + CBS_init(&cbs, *inp, (size_t)len); + ret = EVP_parse_private_key(&cbs); + if (ret == NULL) { + return NULL; + } + if (ret->type != type) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DIFFERENT_KEY_TYPES); + EVP_PKEY_free(ret); + return NULL; + } + } + + if (out != NULL) { + EVP_PKEY_free(*out); + *out = ret; + } + *inp = CBS_data(&cbs); + return ret; +} + +// num_elements parses one SEQUENCE from |in| and returns the number of elements +// in it. On parse error, it returns zero. +static size_t num_elements(const uint8_t *in, size_t in_len) { + CBS cbs, sequence; + CBS_init(&cbs, in, (size_t)in_len); + + if (!CBS_get_asn1(&cbs, &sequence, CBS_ASN1_SEQUENCE)) { + return 0; + } + + size_t count = 0; + while (CBS_len(&sequence) > 0) { + if (!CBS_get_any_asn1_element(&sequence, NULL, NULL, NULL)) { + return 0; + } + + count++; + } + + return count; +} + +EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **out, const uint8_t **inp, long len) { + if (len < 0) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + return NULL; + } + + // Parse the input as a PKCS#8 PrivateKeyInfo. + CBS cbs; + CBS_init(&cbs, *inp, (size_t)len); + EVP_PKEY *ret = EVP_parse_private_key(&cbs); + if (ret != NULL) { + if (out != NULL) { + EVP_PKEY_free(*out); + *out = ret; + } + *inp = CBS_data(&cbs); + return ret; + } + ERR_clear_error(); + + // Count the elements to determine the legacy key format. + switch (num_elements(*inp, (size_t)len)) { + case 4: + return d2i_PrivateKey(EVP_PKEY_EC, out, inp, len); + + case 6: + return d2i_PrivateKey(EVP_PKEY_DSA, out, inp, len); + + default: + return d2i_PrivateKey(EVP_PKEY_RSA, out, inp, len); + } +} + +int i2d_PublicKey(EVP_PKEY *key, uint8_t **outp) { + switch (key->type) { + case EVP_PKEY_RSA: + return i2d_RSAPublicKey(key->pkey.rsa, outp); + case EVP_PKEY_DSA: + return i2d_DSAPublicKey(key->pkey.dsa, outp); + case EVP_PKEY_EC: + return i2o_ECPublicKey(key->pkey.ec, outp); + default: + OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_PUBLIC_KEY_TYPE); + return -1; + } +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/evp_ctx.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/evp_ctx.c new file mode 100644 index 0000000..05cf46f --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/evp_ctx.c @@ -0,0 +1,446 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 + +#include "../internal.h" +#include "internal.h" + + +static const EVP_PKEY_METHOD *const evp_methods[] = { + &rsa_pkey_meth, + &ec_pkey_meth, + &ed25519_pkey_meth, +}; + +static const EVP_PKEY_METHOD *evp_pkey_meth_find(int type) { + unsigned i; + + for (i = 0; i < sizeof(evp_methods)/sizeof(EVP_PKEY_METHOD*); i++) { + if (evp_methods[i]->pkey_id == type) { + return evp_methods[i]; + } + } + + return NULL; +} + +static EVP_PKEY_CTX *evp_pkey_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; + } + + pmeth = evp_pkey_meth_find(id); + + if (pmeth == NULL) { + OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM); + ERR_add_error_dataf("algorithm %d", id); + return NULL; + } + + ret = OPENSSL_malloc(sizeof(EVP_PKEY_CTX)); + if (!ret) { + OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); + return NULL; + } + OPENSSL_memset(ret, 0, sizeof(EVP_PKEY_CTX)); + + ret->engine = e; + ret->pmeth = pmeth; + ret->operation = EVP_PKEY_OP_UNDEFINED; + + if (pkey) { + EVP_PKEY_up_ref(pkey); + ret->pkey = pkey; + } + + if (pmeth->init) { + if (pmeth->init(ret) <= 0) { + EVP_PKEY_free(ret->pkey); + OPENSSL_free(ret); + return NULL; + } + } + + return ret; +} + +EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e) { + return evp_pkey_ctx_new(pkey, e, -1); +} + +EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int id, ENGINE *e) { + return evp_pkey_ctx_new(NULL, e, id); +} + +void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx) { + if (ctx == NULL) { + return; + } + if (ctx->pmeth && ctx->pmeth->cleanup) { + ctx->pmeth->cleanup(ctx); + } + EVP_PKEY_free(ctx->pkey); + EVP_PKEY_free(ctx->peerkey); + OPENSSL_free(ctx); +} + +EVP_PKEY_CTX *EVP_PKEY_CTX_dup(EVP_PKEY_CTX *ctx) { + if (!ctx->pmeth || !ctx->pmeth->copy) { + return NULL; + } + + EVP_PKEY_CTX *ret = OPENSSL_malloc(sizeof(EVP_PKEY_CTX)); + if (!ret) { + return NULL; + } + + OPENSSL_memset(ret, 0, sizeof(EVP_PKEY_CTX)); + + ret->pmeth = ctx->pmeth; + ret->engine = ctx->engine; + ret->operation = ctx->operation; + + if (ctx->pkey != NULL) { + EVP_PKEY_up_ref(ctx->pkey); + ret->pkey = ctx->pkey; + } + + if (ctx->peerkey != NULL) { + EVP_PKEY_up_ref(ctx->peerkey); + ret->peerkey = ctx->peerkey; + } + + if (ctx->pmeth->copy(ret, ctx) <= 0) { + ret->pmeth = NULL; + EVP_PKEY_CTX_free(ret); + OPENSSL_PUT_ERROR(EVP, ERR_LIB_EVP); + return NULL; + } + + return ret; +} + +EVP_PKEY *EVP_PKEY_CTX_get0_pkey(EVP_PKEY_CTX *ctx) { return ctx->pkey; } + +int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype, int cmd, + int p1, void *p2) { + if (!ctx || !ctx->pmeth || !ctx->pmeth->ctrl) { + OPENSSL_PUT_ERROR(EVP, EVP_R_COMMAND_NOT_SUPPORTED); + return 0; + } + if (keytype != -1 && ctx->pmeth->pkey_id != keytype) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return 0; + } + + if (ctx->operation == EVP_PKEY_OP_UNDEFINED) { + OPENSSL_PUT_ERROR(EVP, EVP_R_NO_OPERATION_SET); + return 0; + } + + if (optype != -1 && !(ctx->operation & optype)) { + OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_OPERATION); + return 0; + } + + return ctx->pmeth->ctrl(ctx, cmd, p1, p2); +} + +int EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx) { + if (ctx == NULL || ctx->pmeth == NULL || + (ctx->pmeth->sign == NULL && ctx->pmeth->sign_message == NULL)) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return 0; + } + + ctx->operation = EVP_PKEY_OP_SIGN; + return 1; +} + +int EVP_PKEY_sign(EVP_PKEY_CTX *ctx, uint8_t *sig, size_t *sig_len, + const uint8_t *digest, size_t digest_len) { + if (!ctx || !ctx->pmeth || !ctx->pmeth->sign) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return 0; + } + if (ctx->operation != EVP_PKEY_OP_SIGN) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATON_NOT_INITIALIZED); + return 0; + } + return ctx->pmeth->sign(ctx, sig, sig_len, digest, digest_len); +} + +int EVP_PKEY_verify_init(EVP_PKEY_CTX *ctx) { + if (ctx == NULL || ctx->pmeth == NULL || + (ctx->pmeth->verify == NULL && ctx->pmeth->verify_message == NULL)) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return 0; + } + ctx->operation = EVP_PKEY_OP_VERIFY; + return 1; +} + +int EVP_PKEY_verify(EVP_PKEY_CTX *ctx, const uint8_t *sig, size_t sig_len, + const uint8_t *digest, size_t digest_len) { + if (!ctx || !ctx->pmeth || !ctx->pmeth->verify) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return 0; + } + if (ctx->operation != EVP_PKEY_OP_VERIFY) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATON_NOT_INITIALIZED); + return 0; + } + return ctx->pmeth->verify(ctx, sig, sig_len, digest, digest_len); +} + +int EVP_PKEY_encrypt_init(EVP_PKEY_CTX *ctx) { + if (!ctx || !ctx->pmeth || !ctx->pmeth->encrypt) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return 0; + } + ctx->operation = EVP_PKEY_OP_ENCRYPT; + return 1; +} + +int EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx, uint8_t *out, size_t *outlen, + const uint8_t *in, size_t inlen) { + if (!ctx || !ctx->pmeth || !ctx->pmeth->encrypt) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return 0; + } + if (ctx->operation != EVP_PKEY_OP_ENCRYPT) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATON_NOT_INITIALIZED); + return 0; + } + return ctx->pmeth->encrypt(ctx, out, outlen, in, inlen); +} + +int EVP_PKEY_decrypt_init(EVP_PKEY_CTX *ctx) { + if (!ctx || !ctx->pmeth || !ctx->pmeth->decrypt) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return 0; + } + ctx->operation = EVP_PKEY_OP_DECRYPT; + return 1; +} + +int EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx, uint8_t *out, size_t *outlen, + const uint8_t *in, size_t inlen) { + if (!ctx || !ctx->pmeth || !ctx->pmeth->decrypt) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return 0; + } + if (ctx->operation != EVP_PKEY_OP_DECRYPT) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATON_NOT_INITIALIZED); + return 0; + } + return ctx->pmeth->decrypt(ctx, out, outlen, in, inlen); +} + +int EVP_PKEY_verify_recover_init(EVP_PKEY_CTX *ctx) { + if (!ctx || !ctx->pmeth || !ctx->pmeth->verify_recover) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return 0; + } + ctx->operation = EVP_PKEY_OP_VERIFYRECOVER; + return 1; +} + +int EVP_PKEY_verify_recover(EVP_PKEY_CTX *ctx, uint8_t *out, size_t *out_len, + const uint8_t *sig, size_t sig_len) { + if (!ctx || !ctx->pmeth || !ctx->pmeth->verify_recover) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return 0; + } + if (ctx->operation != EVP_PKEY_OP_VERIFYRECOVER) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATON_NOT_INITIALIZED); + return 0; + } + return ctx->pmeth->verify_recover(ctx, out, out_len, sig, sig_len); +} + +int EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx) { + if (!ctx || !ctx->pmeth || !ctx->pmeth->derive) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return 0; + } + ctx->operation = EVP_PKEY_OP_DERIVE; + return 1; +} + +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) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return 0; + } + if (ctx->operation != EVP_PKEY_OP_DERIVE && + ctx->operation != EVP_PKEY_OP_ENCRYPT && + ctx->operation != EVP_PKEY_OP_DECRYPT) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATON_NOT_INITIALIZED); + return 0; + } + + ret = ctx->pmeth->ctrl(ctx, EVP_PKEY_CTRL_PEER_KEY, 0, peer); + + if (ret <= 0) { + return 0; + } + + if (ret == 2) { + return 1; + } + + if (!ctx->pkey) { + OPENSSL_PUT_ERROR(EVP, EVP_R_NO_KEY_SET); + return 0; + } + + if (ctx->pkey->type != peer->type) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DIFFERENT_KEY_TYPES); + return 0; + } + + // 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)) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DIFFERENT_PARAMETERS); + return 0; + } + + 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 0; + } + + EVP_PKEY_up_ref(peer); + return 1; +} + +int EVP_PKEY_derive(EVP_PKEY_CTX *ctx, uint8_t *key, size_t *out_key_len) { + if (!ctx || !ctx->pmeth || !ctx->pmeth->derive) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return 0; + } + if (ctx->operation != EVP_PKEY_OP_DERIVE) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATON_NOT_INITIALIZED); + return 0; + } + return ctx->pmeth->derive(ctx, key, out_key_len); +} + +int EVP_PKEY_keygen_init(EVP_PKEY_CTX *ctx) { + if (!ctx || !ctx->pmeth || !ctx->pmeth->keygen) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return 0; + } + ctx->operation = EVP_PKEY_OP_KEYGEN; + return 1; +} + +int EVP_PKEY_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey) { + if (!ctx || !ctx->pmeth || !ctx->pmeth->keygen) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return 0; + } + if (ctx->operation != EVP_PKEY_OP_KEYGEN) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATON_NOT_INITIALIZED); + return 0; + } + + if (!ppkey) { + return 0; + } + + if (!*ppkey) { + *ppkey = EVP_PKEY_new(); + if (!*ppkey) { + OPENSSL_PUT_ERROR(EVP, ERR_LIB_EVP); + return 0; + } + } + + if (!ctx->pmeth->keygen(ctx, *ppkey)) { + EVP_PKEY_free(*ppkey); + *ppkey = NULL; + return 0; + } + return 1; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/evp_ctx.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/evp_ctx.c.grpc_back new file mode 100644 index 0000000..3599f77 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/evp_ctx.c.grpc_back @@ -0,0 +1,446 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 + +#include "../internal.h" +#include "internal.h" + + +static const EVP_PKEY_METHOD *const evp_methods[] = { + &rsa_pkey_meth, + &ec_pkey_meth, + &ed25519_pkey_meth, +}; + +static const EVP_PKEY_METHOD *evp_pkey_meth_find(int type) { + unsigned i; + + for (i = 0; i < sizeof(evp_methods)/sizeof(EVP_PKEY_METHOD*); i++) { + if (evp_methods[i]->pkey_id == type) { + return evp_methods[i]; + } + } + + return NULL; +} + +static EVP_PKEY_CTX *evp_pkey_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; + } + + pmeth = evp_pkey_meth_find(id); + + if (pmeth == NULL) { + OPENSSL_PUT_ERROR(EVP, EVP_R_UNSUPPORTED_ALGORITHM); + ERR_add_error_dataf("algorithm %d", id); + return NULL; + } + + ret = OPENSSL_malloc(sizeof(EVP_PKEY_CTX)); + if (!ret) { + OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); + return NULL; + } + OPENSSL_memset(ret, 0, sizeof(EVP_PKEY_CTX)); + + ret->engine = e; + ret->pmeth = pmeth; + ret->operation = EVP_PKEY_OP_UNDEFINED; + + if (pkey) { + EVP_PKEY_up_ref(pkey); + ret->pkey = pkey; + } + + if (pmeth->init) { + if (pmeth->init(ret) <= 0) { + EVP_PKEY_free(ret->pkey); + OPENSSL_free(ret); + return NULL; + } + } + + return ret; +} + +EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e) { + return evp_pkey_ctx_new(pkey, e, -1); +} + +EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int id, ENGINE *e) { + return evp_pkey_ctx_new(NULL, e, id); +} + +void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx) { + if (ctx == NULL) { + return; + } + if (ctx->pmeth && ctx->pmeth->cleanup) { + ctx->pmeth->cleanup(ctx); + } + EVP_PKEY_free(ctx->pkey); + EVP_PKEY_free(ctx->peerkey); + OPENSSL_free(ctx); +} + +EVP_PKEY_CTX *EVP_PKEY_CTX_dup(EVP_PKEY_CTX *ctx) { + if (!ctx->pmeth || !ctx->pmeth->copy) { + return NULL; + } + + EVP_PKEY_CTX *ret = OPENSSL_malloc(sizeof(EVP_PKEY_CTX)); + if (!ret) { + return NULL; + } + + OPENSSL_memset(ret, 0, sizeof(EVP_PKEY_CTX)); + + ret->pmeth = ctx->pmeth; + ret->engine = ctx->engine; + ret->operation = ctx->operation; + + if (ctx->pkey != NULL) { + EVP_PKEY_up_ref(ctx->pkey); + ret->pkey = ctx->pkey; + } + + if (ctx->peerkey != NULL) { + EVP_PKEY_up_ref(ctx->peerkey); + ret->peerkey = ctx->peerkey; + } + + if (ctx->pmeth->copy(ret, ctx) <= 0) { + ret->pmeth = NULL; + EVP_PKEY_CTX_free(ret); + OPENSSL_PUT_ERROR(EVP, ERR_LIB_EVP); + return NULL; + } + + return ret; +} + +EVP_PKEY *EVP_PKEY_CTX_get0_pkey(EVP_PKEY_CTX *ctx) { return ctx->pkey; } + +int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype, int cmd, + int p1, void *p2) { + if (!ctx || !ctx->pmeth || !ctx->pmeth->ctrl) { + OPENSSL_PUT_ERROR(EVP, EVP_R_COMMAND_NOT_SUPPORTED); + return 0; + } + if (keytype != -1 && ctx->pmeth->pkey_id != keytype) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return 0; + } + + if (ctx->operation == EVP_PKEY_OP_UNDEFINED) { + OPENSSL_PUT_ERROR(EVP, EVP_R_NO_OPERATION_SET); + return 0; + } + + if (optype != -1 && !(ctx->operation & optype)) { + OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_OPERATION); + return 0; + } + + return ctx->pmeth->ctrl(ctx, cmd, p1, p2); +} + +int EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx) { + if (ctx == NULL || ctx->pmeth == NULL || + (ctx->pmeth->sign == NULL && ctx->pmeth->sign_message == NULL)) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return 0; + } + + ctx->operation = EVP_PKEY_OP_SIGN; + return 1; +} + +int EVP_PKEY_sign(EVP_PKEY_CTX *ctx, uint8_t *sig, size_t *sig_len, + const uint8_t *digest, size_t digest_len) { + if (!ctx || !ctx->pmeth || !ctx->pmeth->sign) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return 0; + } + if (ctx->operation != EVP_PKEY_OP_SIGN) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATON_NOT_INITIALIZED); + return 0; + } + return ctx->pmeth->sign(ctx, sig, sig_len, digest, digest_len); +} + +int EVP_PKEY_verify_init(EVP_PKEY_CTX *ctx) { + if (ctx == NULL || ctx->pmeth == NULL || + (ctx->pmeth->verify == NULL && ctx->pmeth->verify_message == NULL)) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return 0; + } + ctx->operation = EVP_PKEY_OP_VERIFY; + return 1; +} + +int EVP_PKEY_verify(EVP_PKEY_CTX *ctx, const uint8_t *sig, size_t sig_len, + const uint8_t *digest, size_t digest_len) { + if (!ctx || !ctx->pmeth || !ctx->pmeth->verify) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return 0; + } + if (ctx->operation != EVP_PKEY_OP_VERIFY) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATON_NOT_INITIALIZED); + return 0; + } + return ctx->pmeth->verify(ctx, sig, sig_len, digest, digest_len); +} + +int EVP_PKEY_encrypt_init(EVP_PKEY_CTX *ctx) { + if (!ctx || !ctx->pmeth || !ctx->pmeth->encrypt) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return 0; + } + ctx->operation = EVP_PKEY_OP_ENCRYPT; + return 1; +} + +int EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx, uint8_t *out, size_t *outlen, + const uint8_t *in, size_t inlen) { + if (!ctx || !ctx->pmeth || !ctx->pmeth->encrypt) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return 0; + } + if (ctx->operation != EVP_PKEY_OP_ENCRYPT) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATON_NOT_INITIALIZED); + return 0; + } + return ctx->pmeth->encrypt(ctx, out, outlen, in, inlen); +} + +int EVP_PKEY_decrypt_init(EVP_PKEY_CTX *ctx) { + if (!ctx || !ctx->pmeth || !ctx->pmeth->decrypt) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return 0; + } + ctx->operation = EVP_PKEY_OP_DECRYPT; + return 1; +} + +int EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx, uint8_t *out, size_t *outlen, + const uint8_t *in, size_t inlen) { + if (!ctx || !ctx->pmeth || !ctx->pmeth->decrypt) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return 0; + } + if (ctx->operation != EVP_PKEY_OP_DECRYPT) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATON_NOT_INITIALIZED); + return 0; + } + return ctx->pmeth->decrypt(ctx, out, outlen, in, inlen); +} + +int EVP_PKEY_verify_recover_init(EVP_PKEY_CTX *ctx) { + if (!ctx || !ctx->pmeth || !ctx->pmeth->verify_recover) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return 0; + } + ctx->operation = EVP_PKEY_OP_VERIFYRECOVER; + return 1; +} + +int EVP_PKEY_verify_recover(EVP_PKEY_CTX *ctx, uint8_t *out, size_t *out_len, + const uint8_t *sig, size_t sig_len) { + if (!ctx || !ctx->pmeth || !ctx->pmeth->verify_recover) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return 0; + } + if (ctx->operation != EVP_PKEY_OP_VERIFYRECOVER) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATON_NOT_INITIALIZED); + return 0; + } + return ctx->pmeth->verify_recover(ctx, out, out_len, sig, sig_len); +} + +int EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx) { + if (!ctx || !ctx->pmeth || !ctx->pmeth->derive) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return 0; + } + ctx->operation = EVP_PKEY_OP_DERIVE; + return 1; +} + +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) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return 0; + } + if (ctx->operation != EVP_PKEY_OP_DERIVE && + ctx->operation != EVP_PKEY_OP_ENCRYPT && + ctx->operation != EVP_PKEY_OP_DECRYPT) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATON_NOT_INITIALIZED); + return 0; + } + + ret = ctx->pmeth->ctrl(ctx, EVP_PKEY_CTRL_PEER_KEY, 0, peer); + + if (ret <= 0) { + return 0; + } + + if (ret == 2) { + return 1; + } + + if (!ctx->pkey) { + OPENSSL_PUT_ERROR(EVP, EVP_R_NO_KEY_SET); + return 0; + } + + if (ctx->pkey->type != peer->type) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DIFFERENT_KEY_TYPES); + return 0; + } + + // 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)) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DIFFERENT_PARAMETERS); + return 0; + } + + 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 0; + } + + EVP_PKEY_up_ref(peer); + return 1; +} + +int EVP_PKEY_derive(EVP_PKEY_CTX *ctx, uint8_t *key, size_t *out_key_len) { + if (!ctx || !ctx->pmeth || !ctx->pmeth->derive) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return 0; + } + if (ctx->operation != EVP_PKEY_OP_DERIVE) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATON_NOT_INITIALIZED); + return 0; + } + return ctx->pmeth->derive(ctx, key, out_key_len); +} + +int EVP_PKEY_keygen_init(EVP_PKEY_CTX *ctx) { + if (!ctx || !ctx->pmeth || !ctx->pmeth->keygen) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return 0; + } + ctx->operation = EVP_PKEY_OP_KEYGEN; + return 1; +} + +int EVP_PKEY_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey) { + if (!ctx || !ctx->pmeth || !ctx->pmeth->keygen) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE); + return 0; + } + if (ctx->operation != EVP_PKEY_OP_KEYGEN) { + OPENSSL_PUT_ERROR(EVP, EVP_R_OPERATON_NOT_INITIALIZED); + return 0; + } + + if (!ppkey) { + return 0; + } + + if (!*ppkey) { + *ppkey = EVP_PKEY_new(); + if (!*ppkey) { + OPENSSL_PUT_ERROR(EVP, ERR_LIB_EVP); + return 0; + } + } + + if (!ctx->pmeth->keygen(ctx, *ppkey)) { + EVP_PKEY_free(*ppkey); + *ppkey = NULL; + return 0; + } + return 1; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/internal.h b/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/internal.h new file mode 100644 index 0000000..cc92a2c --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/internal.h @@ -0,0 +1,252 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 OPENSSL_HEADER_EVP_INTERNAL_H +#define OPENSSL_HEADER_EVP_INTERNAL_H + +#include + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +struct evp_pkey_asn1_method_st { + int pkey_id; + uint8_t oid[9]; + uint8_t oid_len; + + // pub_decode decodes |params| and |key| as a SubjectPublicKeyInfo + // and writes the result into |out|. It returns one on success and zero on + // error. |params| is the AlgorithmIdentifier after the OBJECT IDENTIFIER + // type field, and |key| is the contents of the subjectPublicKey with the + // leading padding byte checked and removed. Although X.509 uses BIT STRINGs + // to represent SubjectPublicKeyInfo, every key type defined encodes the key + // as a byte string with the same conversion to BIT STRING. + int (*pub_decode)(EVP_PKEY *out, CBS *params, CBS *key); + + // pub_encode encodes |key| as a SubjectPublicKeyInfo and appends the result + // to |out|. It returns one on success and zero on error. + int (*pub_encode)(CBB *out, const EVP_PKEY *key); + + int (*pub_cmp)(const EVP_PKEY *a, const EVP_PKEY *b); + + // priv_decode decodes |params| and |key| as a PrivateKeyInfo and writes the + // result into |out|. It returns one on success and zero on error. |params| is + // the AlgorithmIdentifier after the OBJECT IDENTIFIER type field, and |key| + // is the contents of the OCTET STRING privateKey field. + int (*priv_decode)(EVP_PKEY *out, CBS *params, CBS *key); + + // priv_encode encodes |key| as a PrivateKeyInfo and appends the result to + // |out|. It returns one on success and zero on error. + int (*priv_encode)(CBB *out, const EVP_PKEY *key); + + // pkey_opaque returns 1 if the |pk| is opaque. Opaque keys are backed by + // custom implementations which do not expose key material and parameters. + int (*pkey_opaque)(const EVP_PKEY *pk); + + int (*pkey_size)(const EVP_PKEY *pk); + int (*pkey_bits)(const EVP_PKEY *pk); + + 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); + + void (*pkey_free)(EVP_PKEY *pkey); +} /* EVP_PKEY_ASN1_METHOD */; + + +#define EVP_PKEY_OP_UNDEFINED 0 +#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_ENCRYPT (1 << 6) +#define EVP_PKEY_OP_DECRYPT (1 << 7) +#define EVP_PKEY_OP_DERIVE (1 << 8) + +#define EVP_PKEY_OP_TYPE_SIG \ + (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY | EVP_PKEY_OP_VERIFYRECOVER) + +#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_KEYGEN + +// EVP_PKEY_CTX_ctrl performs |cmd| on |ctx|. The |keytype| and |optype| +// arguments can be -1 to specify that any type and operation are acceptable, +// otherwise |keytype| must match the type of |ctx| and the bits of |optype| +// must intersect the operation flags set on |ctx|. +// +// The |p1| and |p2| arguments depend on the value of |cmd|. +// +// It returns one on success and zero on error. +OPENSSL_EXPORT int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype, + int cmd, int p1, void *p2); + +#define EVP_PKEY_CTRL_MD 1 +#define EVP_PKEY_CTRL_GET_MD 2 + +// EVP_PKEY_CTRL_PEER_KEY is called with different values of |p1|: +// 0: Is called from |EVP_PKEY_derive_set_peer| and |p2| contains a peer key. +// If the return value is <= 0, the key is rejected. +// 1: Is called at the end of |EVP_PKEY_derive_set_peer| and |p2| contains a +// peer key. If the return value is <= 0, the key is rejected. +// 2: Is called with |p2| == NULL to test whether the peer's key was used. +// (EC)DH always return one in this case. +// 3: Is called with |p2| == NULL to set whether the peer's key was used. +// (EC)DH always return one in this case. This was only used for GOST. +#define EVP_PKEY_CTRL_PEER_KEY 3 + +// EVP_PKEY_ALG_CTRL is the base value from which key-type specific ctrl +// commands are numbered. +#define EVP_PKEY_ALG_CTRL 0x1000 + +#define EVP_PKEY_CTRL_RSA_PADDING (EVP_PKEY_ALG_CTRL + 1) +#define EVP_PKEY_CTRL_GET_RSA_PADDING (EVP_PKEY_ALG_CTRL + 2) +#define EVP_PKEY_CTRL_RSA_PSS_SALTLEN (EVP_PKEY_ALG_CTRL + 3) +#define EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN (EVP_PKEY_ALG_CTRL + 4) +#define EVP_PKEY_CTRL_RSA_KEYGEN_BITS (EVP_PKEY_ALG_CTRL + 5) +#define EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP (EVP_PKEY_ALG_CTRL + 6) +#define EVP_PKEY_CTRL_RSA_OAEP_MD (EVP_PKEY_ALG_CTRL + 7) +#define EVP_PKEY_CTRL_GET_RSA_OAEP_MD (EVP_PKEY_ALG_CTRL + 8) +#define EVP_PKEY_CTRL_RSA_MGF1_MD (EVP_PKEY_ALG_CTRL + 9) +#define EVP_PKEY_CTRL_GET_RSA_MGF1_MD (EVP_PKEY_ALG_CTRL + 10) +#define EVP_PKEY_CTRL_RSA_OAEP_LABEL (EVP_PKEY_ALG_CTRL + 11) +#define EVP_PKEY_CTRL_GET_RSA_OAEP_LABEL (EVP_PKEY_ALG_CTRL + 12) + +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; + // operation contains one of the |EVP_PKEY_OP_*| values. + int operation; + // Algorithm specific data + void *data; +} /* EVP_PKEY_CTX */; + +struct evp_pkey_method_st { + int pkey_id; + + int (*init)(EVP_PKEY_CTX *ctx); + int (*copy)(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src); + void (*cleanup)(EVP_PKEY_CTX *ctx); + + int (*keygen)(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey); + + int (*sign)(EVP_PKEY_CTX *ctx, uint8_t *sig, size_t *siglen, + const uint8_t *tbs, size_t tbslen); + + int (*sign_message)(EVP_PKEY_CTX *ctx, uint8_t *sig, size_t *siglen, + const uint8_t *tbs, size_t tbslen); + + int (*verify)(EVP_PKEY_CTX *ctx, const uint8_t *sig, size_t siglen, + const uint8_t *tbs, size_t tbslen); + + int (*verify_message)(EVP_PKEY_CTX *ctx, const uint8_t *sig, size_t siglen, + const uint8_t *tbs, size_t tbslen); + + int (*verify_recover)(EVP_PKEY_CTX *ctx, uint8_t *out, size_t *out_len, + const uint8_t *sig, size_t sig_len); + + int (*encrypt)(EVP_PKEY_CTX *ctx, uint8_t *out, size_t *outlen, + const uint8_t *in, size_t inlen); + + int (*decrypt)(EVP_PKEY_CTX *ctx, uint8_t *out, size_t *outlen, + const uint8_t *in, size_t inlen); + + int (*derive)(EVP_PKEY_CTX *ctx, uint8_t *key, size_t *keylen); + + int (*ctrl)(EVP_PKEY_CTX *ctx, int type, int p1, void *p2); +} /* EVP_PKEY_METHOD */; + +typedef struct { + union { + uint8_t priv[64]; + struct { + // Shift the location of the public key to align with where it is in the + // private key representation. + uint8_t pad[32]; + uint8_t value[32]; + } pub; + } key; + char has_private; +} ED25519_KEY; + +extern const EVP_PKEY_ASN1_METHOD dsa_asn1_meth; +extern const EVP_PKEY_ASN1_METHOD ec_asn1_meth; +extern const EVP_PKEY_ASN1_METHOD rsa_asn1_meth; +extern const EVP_PKEY_ASN1_METHOD ed25519_asn1_meth; + +extern const EVP_PKEY_METHOD rsa_pkey_meth; +extern const EVP_PKEY_METHOD ec_pkey_meth; +extern const EVP_PKEY_METHOD ed25519_pkey_meth; + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_EVP_INTERNAL_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/internal.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/internal.h.grpc_back new file mode 100644 index 0000000..4aefa35 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/internal.h.grpc_back @@ -0,0 +1,252 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 OPENSSL_HEADER_EVP_INTERNAL_H +#define OPENSSL_HEADER_EVP_INTERNAL_H + +#include + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +struct evp_pkey_asn1_method_st { + int pkey_id; + uint8_t oid[9]; + uint8_t oid_len; + + // pub_decode decodes |params| and |key| as a SubjectPublicKeyInfo + // and writes the result into |out|. It returns one on success and zero on + // error. |params| is the AlgorithmIdentifier after the OBJECT IDENTIFIER + // type field, and |key| is the contents of the subjectPublicKey with the + // leading padding byte checked and removed. Although X.509 uses BIT STRINGs + // to represent SubjectPublicKeyInfo, every key type defined encodes the key + // as a byte string with the same conversion to BIT STRING. + int (*pub_decode)(EVP_PKEY *out, CBS *params, CBS *key); + + // pub_encode encodes |key| as a SubjectPublicKeyInfo and appends the result + // to |out|. It returns one on success and zero on error. + int (*pub_encode)(CBB *out, const EVP_PKEY *key); + + int (*pub_cmp)(const EVP_PKEY *a, const EVP_PKEY *b); + + // priv_decode decodes |params| and |key| as a PrivateKeyInfo and writes the + // result into |out|. It returns one on success and zero on error. |params| is + // the AlgorithmIdentifier after the OBJECT IDENTIFIER type field, and |key| + // is the contents of the OCTET STRING privateKey field. + int (*priv_decode)(EVP_PKEY *out, CBS *params, CBS *key); + + // priv_encode encodes |key| as a PrivateKeyInfo and appends the result to + // |out|. It returns one on success and zero on error. + int (*priv_encode)(CBB *out, const EVP_PKEY *key); + + // pkey_opaque returns 1 if the |pk| is opaque. Opaque keys are backed by + // custom implementations which do not expose key material and parameters. + int (*pkey_opaque)(const EVP_PKEY *pk); + + int (*pkey_size)(const EVP_PKEY *pk); + int (*pkey_bits)(const EVP_PKEY *pk); + + 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); + + void (*pkey_free)(EVP_PKEY *pkey); +} /* EVP_PKEY_ASN1_METHOD */; + + +#define EVP_PKEY_OP_UNDEFINED 0 +#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_ENCRYPT (1 << 6) +#define EVP_PKEY_OP_DECRYPT (1 << 7) +#define EVP_PKEY_OP_DERIVE (1 << 8) + +#define EVP_PKEY_OP_TYPE_SIG \ + (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY | EVP_PKEY_OP_VERIFYRECOVER) + +#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_KEYGEN + +// EVP_PKEY_CTX_ctrl performs |cmd| on |ctx|. The |keytype| and |optype| +// arguments can be -1 to specify that any type and operation are acceptable, +// otherwise |keytype| must match the type of |ctx| and the bits of |optype| +// must intersect the operation flags set on |ctx|. +// +// The |p1| and |p2| arguments depend on the value of |cmd|. +// +// It returns one on success and zero on error. +OPENSSL_EXPORT int EVP_PKEY_CTX_ctrl(EVP_PKEY_CTX *ctx, int keytype, int optype, + int cmd, int p1, void *p2); + +#define EVP_PKEY_CTRL_MD 1 +#define EVP_PKEY_CTRL_GET_MD 2 + +// EVP_PKEY_CTRL_PEER_KEY is called with different values of |p1|: +// 0: Is called from |EVP_PKEY_derive_set_peer| and |p2| contains a peer key. +// If the return value is <= 0, the key is rejected. +// 1: Is called at the end of |EVP_PKEY_derive_set_peer| and |p2| contains a +// peer key. If the return value is <= 0, the key is rejected. +// 2: Is called with |p2| == NULL to test whether the peer's key was used. +// (EC)DH always return one in this case. +// 3: Is called with |p2| == NULL to set whether the peer's key was used. +// (EC)DH always return one in this case. This was only used for GOST. +#define EVP_PKEY_CTRL_PEER_KEY 3 + +// EVP_PKEY_ALG_CTRL is the base value from which key-type specific ctrl +// commands are numbered. +#define EVP_PKEY_ALG_CTRL 0x1000 + +#define EVP_PKEY_CTRL_RSA_PADDING (EVP_PKEY_ALG_CTRL + 1) +#define EVP_PKEY_CTRL_GET_RSA_PADDING (EVP_PKEY_ALG_CTRL + 2) +#define EVP_PKEY_CTRL_RSA_PSS_SALTLEN (EVP_PKEY_ALG_CTRL + 3) +#define EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN (EVP_PKEY_ALG_CTRL + 4) +#define EVP_PKEY_CTRL_RSA_KEYGEN_BITS (EVP_PKEY_ALG_CTRL + 5) +#define EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP (EVP_PKEY_ALG_CTRL + 6) +#define EVP_PKEY_CTRL_RSA_OAEP_MD (EVP_PKEY_ALG_CTRL + 7) +#define EVP_PKEY_CTRL_GET_RSA_OAEP_MD (EVP_PKEY_ALG_CTRL + 8) +#define EVP_PKEY_CTRL_RSA_MGF1_MD (EVP_PKEY_ALG_CTRL + 9) +#define EVP_PKEY_CTRL_GET_RSA_MGF1_MD (EVP_PKEY_ALG_CTRL + 10) +#define EVP_PKEY_CTRL_RSA_OAEP_LABEL (EVP_PKEY_ALG_CTRL + 11) +#define EVP_PKEY_CTRL_GET_RSA_OAEP_LABEL (EVP_PKEY_ALG_CTRL + 12) + +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; + // operation contains one of the |EVP_PKEY_OP_*| values. + int operation; + // Algorithm specific data + void *data; +} /* EVP_PKEY_CTX */; + +struct evp_pkey_method_st { + int pkey_id; + + int (*init)(EVP_PKEY_CTX *ctx); + int (*copy)(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src); + void (*cleanup)(EVP_PKEY_CTX *ctx); + + int (*keygen)(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey); + + int (*sign)(EVP_PKEY_CTX *ctx, uint8_t *sig, size_t *siglen, + const uint8_t *tbs, size_t tbslen); + + int (*sign_message)(EVP_PKEY_CTX *ctx, uint8_t *sig, size_t *siglen, + const uint8_t *tbs, size_t tbslen); + + int (*verify)(EVP_PKEY_CTX *ctx, const uint8_t *sig, size_t siglen, + const uint8_t *tbs, size_t tbslen); + + int (*verify_message)(EVP_PKEY_CTX *ctx, const uint8_t *sig, size_t siglen, + const uint8_t *tbs, size_t tbslen); + + int (*verify_recover)(EVP_PKEY_CTX *ctx, uint8_t *out, size_t *out_len, + const uint8_t *sig, size_t sig_len); + + int (*encrypt)(EVP_PKEY_CTX *ctx, uint8_t *out, size_t *outlen, + const uint8_t *in, size_t inlen); + + int (*decrypt)(EVP_PKEY_CTX *ctx, uint8_t *out, size_t *outlen, + const uint8_t *in, size_t inlen); + + int (*derive)(EVP_PKEY_CTX *ctx, uint8_t *key, size_t *keylen); + + int (*ctrl)(EVP_PKEY_CTX *ctx, int type, int p1, void *p2); +} /* EVP_PKEY_METHOD */; + +typedef struct { + union { + uint8_t priv[64]; + struct { + // Shift the location of the public key to align with where it is in the + // private key representation. + uint8_t pad[32]; + uint8_t value[32]; + } pub; + } key; + char has_private; +} ED25519_KEY; + +extern const EVP_PKEY_ASN1_METHOD dsa_asn1_meth; +extern const EVP_PKEY_ASN1_METHOD ec_asn1_meth; +extern const EVP_PKEY_ASN1_METHOD rsa_asn1_meth; +extern const EVP_PKEY_ASN1_METHOD ed25519_asn1_meth; + +extern const EVP_PKEY_METHOD rsa_pkey_meth; +extern const EVP_PKEY_METHOD ec_pkey_meth; +extern const EVP_PKEY_METHOD ed25519_pkey_meth; + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_EVP_INTERNAL_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/p_dsa_asn1.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/p_dsa_asn1.c new file mode 100644 index 0000000..80b996b --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/p_dsa_asn1.c @@ -0,0 +1,268 @@ +/* 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 +#include + +#include "internal.h" + + +static int dsa_pub_decode(EVP_PKEY *out, CBS *params, CBS *key) { + // See RFC 3279, section 2.3.2. + + // Parameters may or may not be present. + DSA *dsa; + if (CBS_len(params) == 0) { + dsa = DSA_new(); + if (dsa == NULL) { + return 0; + } + } else { + dsa = DSA_parse_parameters(params); + if (dsa == NULL || CBS_len(params) != 0) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + goto err; + } + } + + dsa->pub_key = BN_new(); + if (dsa->pub_key == NULL) { + goto err; + } + + if (!BN_parse_asn1_unsigned(key, dsa->pub_key) || + CBS_len(key) != 0) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + goto err; + } + + EVP_PKEY_assign_DSA(out, dsa); + return 1; + +err: + DSA_free(dsa); + return 0; +} + +static int dsa_pub_encode(CBB *out, const EVP_PKEY *key) { + const DSA *dsa = key->pkey.dsa; + const int has_params = dsa->p != NULL && dsa->q != NULL && dsa->g != NULL; + + // See RFC 5480, section 2. + CBB spki, algorithm, oid, key_bitstring; + if (!CBB_add_asn1(out, &spki, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1(&spki, &algorithm, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) || + !CBB_add_bytes(&oid, dsa_asn1_meth.oid, dsa_asn1_meth.oid_len) || + (has_params && + !DSA_marshal_parameters(&algorithm, dsa)) || + !CBB_add_asn1(&spki, &key_bitstring, CBS_ASN1_BITSTRING) || + !CBB_add_u8(&key_bitstring, 0 /* padding */) || + !BN_marshal_asn1(&key_bitstring, dsa->pub_key) || + !CBB_flush(out)) { + OPENSSL_PUT_ERROR(EVP, EVP_R_ENCODE_ERROR); + return 0; + } + + return 1; +} + +static int dsa_priv_decode(EVP_PKEY *out, CBS *params, CBS *key) { + // See PKCS#11, v2.40, section 2.5. + + // Decode parameters. + BN_CTX *ctx = NULL; + DSA *dsa = DSA_parse_parameters(params); + if (dsa == NULL || CBS_len(params) != 0) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + goto err; + } + + dsa->priv_key = BN_new(); + dsa->pub_key = BN_new(); + if (dsa->priv_key == NULL || dsa->pub_key == NULL) { + goto err; + } + + // Decode the key. + if (!BN_parse_asn1_unsigned(key, dsa->priv_key) || + CBS_len(key) != 0) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + goto err; + } + + // Calculate the public key. + ctx = BN_CTX_new(); + if (ctx == NULL || + !BN_mod_exp_mont_consttime(dsa->pub_key, dsa->g, dsa->priv_key, dsa->p, + ctx, NULL)) { + goto err; + } + + BN_CTX_free(ctx); + EVP_PKEY_assign_DSA(out, dsa); + return 1; + +err: + BN_CTX_free(ctx); + DSA_free(dsa); + return 0; +} + +static int dsa_priv_encode(CBB *out, const EVP_PKEY *key) { + const DSA *dsa = key->pkey.dsa; + if (dsa == NULL || dsa->priv_key == NULL) { + OPENSSL_PUT_ERROR(EVP, EVP_R_MISSING_PARAMETERS); + return 0; + } + + // See PKCS#11, v2.40, section 2.5. + CBB pkcs8, algorithm, oid, private_key; + if (!CBB_add_asn1(out, &pkcs8, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1_uint64(&pkcs8, 0 /* version */) || + !CBB_add_asn1(&pkcs8, &algorithm, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) || + !CBB_add_bytes(&oid, dsa_asn1_meth.oid, dsa_asn1_meth.oid_len) || + !DSA_marshal_parameters(&algorithm, dsa) || + !CBB_add_asn1(&pkcs8, &private_key, CBS_ASN1_OCTETSTRING) || + !BN_marshal_asn1(&private_key, dsa->priv_key) || + !CBB_flush(out)) { + OPENSSL_PUT_ERROR(EVP, EVP_R_ENCODE_ERROR); + return 0; + } + + return 1; +} + +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->p == NULL || dsa->q == NULL || dsa->g == NULL) { + return 1; + } + return 0; +} + +static int dup_bn_into(BIGNUM **out, BIGNUM *src) { + BIGNUM *a; + + a = BN_dup(src); + if (a == NULL) { + return 0; + } + BN_free(*out); + *out = a; + + return 1; +} + +static int dsa_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from) { + if (!dup_bn_into(&to->pkey.dsa->p, from->pkey.dsa->p) || + !dup_bn_into(&to->pkey.dsa->q, from->pkey.dsa->q) || + !dup_bn_into(&to->pkey.dsa->g, from->pkey.dsa->g)) { + return 0; + } + + return 1; +} + +static int dsa_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b) { + return BN_cmp(a->pkey.dsa->p, b->pkey.dsa->p) == 0 && + BN_cmp(a->pkey.dsa->q, b->pkey.dsa->q) == 0 && + BN_cmp(a->pkey.dsa->g, b->pkey.dsa->g) == 0; +} + +static int dsa_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) { + return BN_cmp(b->pkey.dsa->pub_key, a->pkey.dsa->pub_key) == 0; +} + +static void int_dsa_free(EVP_PKEY *pkey) { DSA_free(pkey->pkey.dsa); } + +const EVP_PKEY_ASN1_METHOD dsa_asn1_meth = { + EVP_PKEY_DSA, + // 1.2.840.10040.4.1 + {0x2a, 0x86, 0x48, 0xce, 0x38, 0x04, 0x01}, 7, + + dsa_pub_decode, + dsa_pub_encode, + dsa_pub_cmp, + + dsa_priv_decode, + dsa_priv_encode, + + NULL /* pkey_opaque */, + + int_dsa_size, + dsa_bits, + + dsa_missing_parameters, + dsa_copy_parameters, + dsa_cmp_parameters, + + int_dsa_free, +}; diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/p_dsa_asn1.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/p_dsa_asn1.c.grpc_back new file mode 100644 index 0000000..34b2e70 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/p_dsa_asn1.c.grpc_back @@ -0,0 +1,268 @@ +/* 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 +#include + +#include "internal.h" + + +static int dsa_pub_decode(EVP_PKEY *out, CBS *params, CBS *key) { + // See RFC 3279, section 2.3.2. + + // Parameters may or may not be present. + DSA *dsa; + if (CBS_len(params) == 0) { + dsa = DSA_new(); + if (dsa == NULL) { + return 0; + } + } else { + dsa = DSA_parse_parameters(params); + if (dsa == NULL || CBS_len(params) != 0) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + goto err; + } + } + + dsa->pub_key = BN_new(); + if (dsa->pub_key == NULL) { + goto err; + } + + if (!BN_parse_asn1_unsigned(key, dsa->pub_key) || + CBS_len(key) != 0) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + goto err; + } + + EVP_PKEY_assign_DSA(out, dsa); + return 1; + +err: + DSA_free(dsa); + return 0; +} + +static int dsa_pub_encode(CBB *out, const EVP_PKEY *key) { + const DSA *dsa = key->pkey.dsa; + const int has_params = dsa->p != NULL && dsa->q != NULL && dsa->g != NULL; + + // See RFC 5480, section 2. + CBB spki, algorithm, oid, key_bitstring; + if (!CBB_add_asn1(out, &spki, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1(&spki, &algorithm, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) || + !CBB_add_bytes(&oid, dsa_asn1_meth.oid, dsa_asn1_meth.oid_len) || + (has_params && + !DSA_marshal_parameters(&algorithm, dsa)) || + !CBB_add_asn1(&spki, &key_bitstring, CBS_ASN1_BITSTRING) || + !CBB_add_u8(&key_bitstring, 0 /* padding */) || + !BN_marshal_asn1(&key_bitstring, dsa->pub_key) || + !CBB_flush(out)) { + OPENSSL_PUT_ERROR(EVP, EVP_R_ENCODE_ERROR); + return 0; + } + + return 1; +} + +static int dsa_priv_decode(EVP_PKEY *out, CBS *params, CBS *key) { + // See PKCS#11, v2.40, section 2.5. + + // Decode parameters. + BN_CTX *ctx = NULL; + DSA *dsa = DSA_parse_parameters(params); + if (dsa == NULL || CBS_len(params) != 0) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + goto err; + } + + dsa->priv_key = BN_new(); + dsa->pub_key = BN_new(); + if (dsa->priv_key == NULL || dsa->pub_key == NULL) { + goto err; + } + + // Decode the key. + if (!BN_parse_asn1_unsigned(key, dsa->priv_key) || + CBS_len(key) != 0) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + goto err; + } + + // Calculate the public key. + ctx = BN_CTX_new(); + if (ctx == NULL || + !BN_mod_exp_mont_consttime(dsa->pub_key, dsa->g, dsa->priv_key, dsa->p, + ctx, NULL)) { + goto err; + } + + BN_CTX_free(ctx); + EVP_PKEY_assign_DSA(out, dsa); + return 1; + +err: + BN_CTX_free(ctx); + DSA_free(dsa); + return 0; +} + +static int dsa_priv_encode(CBB *out, const EVP_PKEY *key) { + const DSA *dsa = key->pkey.dsa; + if (dsa == NULL || dsa->priv_key == NULL) { + OPENSSL_PUT_ERROR(EVP, EVP_R_MISSING_PARAMETERS); + return 0; + } + + // See PKCS#11, v2.40, section 2.5. + CBB pkcs8, algorithm, oid, private_key; + if (!CBB_add_asn1(out, &pkcs8, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1_uint64(&pkcs8, 0 /* version */) || + !CBB_add_asn1(&pkcs8, &algorithm, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) || + !CBB_add_bytes(&oid, dsa_asn1_meth.oid, dsa_asn1_meth.oid_len) || + !DSA_marshal_parameters(&algorithm, dsa) || + !CBB_add_asn1(&pkcs8, &private_key, CBS_ASN1_OCTETSTRING) || + !BN_marshal_asn1(&private_key, dsa->priv_key) || + !CBB_flush(out)) { + OPENSSL_PUT_ERROR(EVP, EVP_R_ENCODE_ERROR); + return 0; + } + + return 1; +} + +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->p == NULL || dsa->q == NULL || dsa->g == NULL) { + return 1; + } + return 0; +} + +static int dup_bn_into(BIGNUM **out, BIGNUM *src) { + BIGNUM *a; + + a = BN_dup(src); + if (a == NULL) { + return 0; + } + BN_free(*out); + *out = a; + + return 1; +} + +static int dsa_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from) { + if (!dup_bn_into(&to->pkey.dsa->p, from->pkey.dsa->p) || + !dup_bn_into(&to->pkey.dsa->q, from->pkey.dsa->q) || + !dup_bn_into(&to->pkey.dsa->g, from->pkey.dsa->g)) { + return 0; + } + + return 1; +} + +static int dsa_cmp_parameters(const EVP_PKEY *a, const EVP_PKEY *b) { + return BN_cmp(a->pkey.dsa->p, b->pkey.dsa->p) == 0 && + BN_cmp(a->pkey.dsa->q, b->pkey.dsa->q) == 0 && + BN_cmp(a->pkey.dsa->g, b->pkey.dsa->g) == 0; +} + +static int dsa_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) { + return BN_cmp(b->pkey.dsa->pub_key, a->pkey.dsa->pub_key) == 0; +} + +static void int_dsa_free(EVP_PKEY *pkey) { DSA_free(pkey->pkey.dsa); } + +const EVP_PKEY_ASN1_METHOD dsa_asn1_meth = { + EVP_PKEY_DSA, + // 1.2.840.10040.4.1 + {0x2a, 0x86, 0x48, 0xce, 0x38, 0x04, 0x01}, 7, + + dsa_pub_decode, + dsa_pub_encode, + dsa_pub_cmp, + + dsa_priv_decode, + dsa_priv_encode, + + NULL /* pkey_opaque */, + + int_dsa_size, + dsa_bits, + + dsa_missing_parameters, + dsa_copy_parameters, + dsa_cmp_parameters, + + int_dsa_free, +}; diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/p_ec.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/p_ec.c new file mode 100644 index 0000000..a45d37f --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/p_ec.c @@ -0,0 +1,239 @@ +/* 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 +#include +#include +#include +#include +#include +#include +#include + +#include "internal.h" +#include "../fipsmodule/ec/internal.h" +#include "../internal.h" + + +typedef struct { + // message digest + const EVP_MD *md; +} 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; + } + OPENSSL_memset(dctx, 0, sizeof(EC_PKEY_CTX)); + + 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; + + dctx->md = sctx->md; + + return 1; +} + +static void pkey_ec_cleanup(EVP_PKEY_CTX *ctx) { + EC_PKEY_CTX *dctx = ctx->data; + if (!dctx) { + return; + } + + OPENSSL_free(dctx); +} + +static int pkey_ec_sign(EVP_PKEY_CTX *ctx, uint8_t *sig, size_t *siglen, + const uint8_t *tbs, size_t tbslen) { + unsigned int sltmp; + EC_KEY *ec = ctx->pkey->pkey.ec; + + if (!sig) { + *siglen = ECDSA_size(ec); + return 1; + } else if (*siglen < (size_t)ECDSA_size(ec)) { + OPENSSL_PUT_ERROR(EVP, EVP_R_BUFFER_TOO_SMALL); + return 0; + } + + if (!ECDSA_sign(0, tbs, tbslen, sig, &sltmp, ec)) { + return 0; + } + *siglen = (size_t)sltmp; + return 1; +} + +static int pkey_ec_verify(EVP_PKEY_CTX *ctx, const uint8_t *sig, size_t siglen, + const uint8_t *tbs, size_t tbslen) { + return ECDSA_verify(0, tbs, tbslen, sig, siglen, ctx->pkey->pkey.ec); +} + +static int pkey_ec_derive(EVP_PKEY_CTX *ctx, uint8_t *key, + size_t *keylen) { + int ret; + size_t outlen; + const EC_POINT *pubkey = NULL; + EC_KEY *eckey; + + if (!ctx->pkey || !ctx->peerkey) { + OPENSSL_PUT_ERROR(EVP, EVP_R_KEYS_NOT_SET); + return 0; + } + + eckey = 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_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) { + EC_PKEY_CTX *dctx = ctx->data; + + switch (type) { + 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) { + OPENSSL_PUT_ERROR(EVP, EVP_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 + return 1; + + default: + OPENSSL_PUT_ERROR(EVP, EVP_R_COMMAND_NOT_SUPPORTED); + return 0; + } +} + +static int pkey_ec_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) { + if (ctx->pkey == NULL) { + OPENSSL_PUT_ERROR(EVP, EVP_R_NO_PARAMETERS_SET); + return 0; + } + EC_KEY *ec = EC_KEY_new(); + if (ec == NULL || + !EC_KEY_set_group(ec, EC_KEY_get0_group(ctx->pkey->pkey.ec)) || + !EC_KEY_generate_key(ec)) { + EC_KEY_free(ec); + return 0; + } + EVP_PKEY_assign_EC_KEY(pkey, ec); + return 1; +} + +const EVP_PKEY_METHOD ec_pkey_meth = { + EVP_PKEY_EC, + pkey_ec_init, + pkey_ec_copy, + pkey_ec_cleanup, + pkey_ec_keygen, + pkey_ec_sign, + NULL /* sign_message */, + pkey_ec_verify, + NULL /* verify_message */, + NULL /* verify_recover */, + NULL /* encrypt */, + NULL /* decrypt */, + pkey_ec_derive, + pkey_ec_ctrl, +}; diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/p_ec.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/p_ec.c.grpc_back new file mode 100644 index 0000000..d311d22 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/p_ec.c.grpc_back @@ -0,0 +1,239 @@ +/* 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 +#include +#include +#include +#include +#include +#include +#include + +#include "internal.h" +#include "../fipsmodule/ec/internal.h" +#include "../internal.h" + + +typedef struct { + // message digest + const EVP_MD *md; +} 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; + } + OPENSSL_memset(dctx, 0, sizeof(EC_PKEY_CTX)); + + 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; + + dctx->md = sctx->md; + + return 1; +} + +static void pkey_ec_cleanup(EVP_PKEY_CTX *ctx) { + EC_PKEY_CTX *dctx = ctx->data; + if (!dctx) { + return; + } + + OPENSSL_free(dctx); +} + +static int pkey_ec_sign(EVP_PKEY_CTX *ctx, uint8_t *sig, size_t *siglen, + const uint8_t *tbs, size_t tbslen) { + unsigned int sltmp; + EC_KEY *ec = ctx->pkey->pkey.ec; + + if (!sig) { + *siglen = ECDSA_size(ec); + return 1; + } else if (*siglen < (size_t)ECDSA_size(ec)) { + OPENSSL_PUT_ERROR(EVP, EVP_R_BUFFER_TOO_SMALL); + return 0; + } + + if (!ECDSA_sign(0, tbs, tbslen, sig, &sltmp, ec)) { + return 0; + } + *siglen = (size_t)sltmp; + return 1; +} + +static int pkey_ec_verify(EVP_PKEY_CTX *ctx, const uint8_t *sig, size_t siglen, + const uint8_t *tbs, size_t tbslen) { + return ECDSA_verify(0, tbs, tbslen, sig, siglen, ctx->pkey->pkey.ec); +} + +static int pkey_ec_derive(EVP_PKEY_CTX *ctx, uint8_t *key, + size_t *keylen) { + int ret; + size_t outlen; + const EC_POINT *pubkey = NULL; + EC_KEY *eckey; + + if (!ctx->pkey || !ctx->peerkey) { + OPENSSL_PUT_ERROR(EVP, EVP_R_KEYS_NOT_SET); + return 0; + } + + eckey = 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_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2) { + EC_PKEY_CTX *dctx = ctx->data; + + switch (type) { + 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) { + OPENSSL_PUT_ERROR(EVP, EVP_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 + return 1; + + default: + OPENSSL_PUT_ERROR(EVP, EVP_R_COMMAND_NOT_SUPPORTED); + return 0; + } +} + +static int pkey_ec_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) { + if (ctx->pkey == NULL) { + OPENSSL_PUT_ERROR(EVP, EVP_R_NO_PARAMETERS_SET); + return 0; + } + EC_KEY *ec = EC_KEY_new(); + if (ec == NULL || + !EC_KEY_set_group(ec, EC_KEY_get0_group(ctx->pkey->pkey.ec)) || + !EC_KEY_generate_key(ec)) { + EC_KEY_free(ec); + return 0; + } + EVP_PKEY_assign_EC_KEY(pkey, ec); + return 1; +} + +const EVP_PKEY_METHOD ec_pkey_meth = { + EVP_PKEY_EC, + pkey_ec_init, + pkey_ec_copy, + pkey_ec_cleanup, + pkey_ec_keygen, + pkey_ec_sign, + NULL /* sign_message */, + pkey_ec_verify, + NULL /* verify_message */, + NULL /* verify_recover */, + NULL /* encrypt */, + NULL /* decrypt */, + pkey_ec_derive, + pkey_ec_ctrl, +}; diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/p_ec_asn1.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/p_ec_asn1.c new file mode 100644 index 0000000..4130a51 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/p_ec_asn1.c @@ -0,0 +1,256 @@ +/* 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 +#include +#include + +#include "internal.h" + + +static int eckey_pub_encode(CBB *out, const EVP_PKEY *key) { + const EC_KEY *ec_key = key->pkey.ec; + const EC_GROUP *group = EC_KEY_get0_group(ec_key); + const EC_POINT *public_key = EC_KEY_get0_public_key(ec_key); + + // See RFC 5480, section 2. + CBB spki, algorithm, oid, key_bitstring; + if (!CBB_add_asn1(out, &spki, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1(&spki, &algorithm, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) || + !CBB_add_bytes(&oid, ec_asn1_meth.oid, ec_asn1_meth.oid_len) || + !EC_KEY_marshal_curve_name(&algorithm, group) || + !CBB_add_asn1(&spki, &key_bitstring, CBS_ASN1_BITSTRING) || + !CBB_add_u8(&key_bitstring, 0 /* padding */) || + !EC_POINT_point2cbb(&key_bitstring, group, public_key, + POINT_CONVERSION_UNCOMPRESSED, NULL) || + !CBB_flush(out)) { + OPENSSL_PUT_ERROR(EVP, EVP_R_ENCODE_ERROR); + return 0; + } + + return 1; +} + +static int eckey_pub_decode(EVP_PKEY *out, CBS *params, CBS *key) { + // See RFC 5480, section 2. + + // The parameters are a named curve. + EC_POINT *point = NULL; + EC_KEY *eckey = NULL; + EC_GROUP *group = EC_KEY_parse_curve_name(params); + if (group == NULL || CBS_len(params) != 0) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + goto err; + } + + eckey = EC_KEY_new(); + if (eckey == NULL || !EC_KEY_set_group(eckey, group)) { + goto err; + } + + point = EC_POINT_new(group); + if (point == NULL || + !EC_POINT_oct2point(group, point, CBS_data(key), CBS_len(key), NULL) || + !EC_KEY_set_public_key(eckey, point)) { + goto err; + } + + EC_GROUP_free(group); + EC_POINT_free(point); + EVP_PKEY_assign_EC_KEY(out, eckey); + return 1; + +err: + EC_GROUP_free(group); + EC_POINT_free(point); + 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); + r = EC_POINT_cmp(group, pa, pb, NULL); + if (r == 0) { + return 1; + } else if (r == 1) { + return 0; + } else { + return -2; + } +} + +static int eckey_priv_decode(EVP_PKEY *out, CBS *params, CBS *key) { + // See RFC 5915. + EC_GROUP *group = EC_KEY_parse_parameters(params); + if (group == NULL || CBS_len(params) != 0) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + EC_GROUP_free(group); + return 0; + } + + EC_KEY *ec_key = EC_KEY_parse_private_key(key, group); + EC_GROUP_free(group); + if (ec_key == NULL || CBS_len(key) != 0) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + EC_KEY_free(ec_key); + return 0; + } + + EVP_PKEY_assign_EC_KEY(out, ec_key); + return 1; +} + +static int eckey_priv_encode(CBB *out, const EVP_PKEY *key) { + const EC_KEY *ec_key = key->pkey.ec; + + // Omit the redundant copy of the curve name. This contradicts RFC 5915 but + // aligns with PKCS #11. SEC 1 only says they may be omitted if known by other + // means. Both OpenSSL and NSS omit the redundant parameters, so we omit them + // as well. + unsigned enc_flags = EC_KEY_get_enc_flags(ec_key) | EC_PKEY_NO_PARAMETERS; + + // See RFC 5915. + CBB pkcs8, algorithm, oid, private_key; + if (!CBB_add_asn1(out, &pkcs8, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1_uint64(&pkcs8, 0 /* version */) || + !CBB_add_asn1(&pkcs8, &algorithm, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) || + !CBB_add_bytes(&oid, ec_asn1_meth.oid, ec_asn1_meth.oid_len) || + !EC_KEY_marshal_curve_name(&algorithm, EC_KEY_get0_group(ec_key)) || + !CBB_add_asn1(&pkcs8, &private_key, CBS_ASN1_OCTETSTRING) || + !EC_KEY_marshal_private_key(&private_key, ec_key, enc_flags) || + !CBB_flush(out)) { + OPENSSL_PUT_ERROR(EVP, EVP_R_ENCODE_ERROR); + 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) { + const EC_GROUP *group = EC_KEY_get0_group(pkey->pkey.ec); + if (group == NULL) { + ERR_clear_error(); + return 0; + } + return BN_num_bits(EC_GROUP_get0_order(group)); +} + +static int ec_missing_parameters(const EVP_PKEY *pkey) { + return EC_KEY_get0_group(pkey->pkey.ec) == NULL; +} + +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 || + 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 (EC_GROUP_cmp(group_a, group_b, NULL) != 0) { + // mismatch + return 0; + } + return 1; +} + +static void int_ec_free(EVP_PKEY *pkey) { EC_KEY_free(pkey->pkey.ec); } + +static int eckey_opaque(const EVP_PKEY *pkey) { + return EC_KEY_is_opaque(pkey->pkey.ec); +} + +const EVP_PKEY_ASN1_METHOD ec_asn1_meth = { + EVP_PKEY_EC, + // 1.2.840.10045.2.1 + {0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01}, 7, + + eckey_pub_decode, + eckey_pub_encode, + eckey_pub_cmp, + + eckey_priv_decode, + eckey_priv_encode, + + eckey_opaque, + + int_ec_size, + ec_bits, + + ec_missing_parameters, + ec_copy_parameters, + ec_cmp_parameters, + + int_ec_free, +}; diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/p_ec_asn1.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/p_ec_asn1.c.grpc_back new file mode 100644 index 0000000..c5828d9 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/p_ec_asn1.c.grpc_back @@ -0,0 +1,256 @@ +/* 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 +#include +#include + +#include "internal.h" + + +static int eckey_pub_encode(CBB *out, const EVP_PKEY *key) { + const EC_KEY *ec_key = key->pkey.ec; + const EC_GROUP *group = EC_KEY_get0_group(ec_key); + const EC_POINT *public_key = EC_KEY_get0_public_key(ec_key); + + // See RFC 5480, section 2. + CBB spki, algorithm, oid, key_bitstring; + if (!CBB_add_asn1(out, &spki, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1(&spki, &algorithm, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) || + !CBB_add_bytes(&oid, ec_asn1_meth.oid, ec_asn1_meth.oid_len) || + !EC_KEY_marshal_curve_name(&algorithm, group) || + !CBB_add_asn1(&spki, &key_bitstring, CBS_ASN1_BITSTRING) || + !CBB_add_u8(&key_bitstring, 0 /* padding */) || + !EC_POINT_point2cbb(&key_bitstring, group, public_key, + POINT_CONVERSION_UNCOMPRESSED, NULL) || + !CBB_flush(out)) { + OPENSSL_PUT_ERROR(EVP, EVP_R_ENCODE_ERROR); + return 0; + } + + return 1; +} + +static int eckey_pub_decode(EVP_PKEY *out, CBS *params, CBS *key) { + // See RFC 5480, section 2. + + // The parameters are a named curve. + EC_POINT *point = NULL; + EC_KEY *eckey = NULL; + EC_GROUP *group = EC_KEY_parse_curve_name(params); + if (group == NULL || CBS_len(params) != 0) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + goto err; + } + + eckey = EC_KEY_new(); + if (eckey == NULL || !EC_KEY_set_group(eckey, group)) { + goto err; + } + + point = EC_POINT_new(group); + if (point == NULL || + !EC_POINT_oct2point(group, point, CBS_data(key), CBS_len(key), NULL) || + !EC_KEY_set_public_key(eckey, point)) { + goto err; + } + + EC_GROUP_free(group); + EC_POINT_free(point); + EVP_PKEY_assign_EC_KEY(out, eckey); + return 1; + +err: + EC_GROUP_free(group); + EC_POINT_free(point); + 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); + r = EC_POINT_cmp(group, pa, pb, NULL); + if (r == 0) { + return 1; + } else if (r == 1) { + return 0; + } else { + return -2; + } +} + +static int eckey_priv_decode(EVP_PKEY *out, CBS *params, CBS *key) { + // See RFC 5915. + EC_GROUP *group = EC_KEY_parse_parameters(params); + if (group == NULL || CBS_len(params) != 0) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + EC_GROUP_free(group); + return 0; + } + + EC_KEY *ec_key = EC_KEY_parse_private_key(key, group); + EC_GROUP_free(group); + if (ec_key == NULL || CBS_len(key) != 0) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + EC_KEY_free(ec_key); + return 0; + } + + EVP_PKEY_assign_EC_KEY(out, ec_key); + return 1; +} + +static int eckey_priv_encode(CBB *out, const EVP_PKEY *key) { + const EC_KEY *ec_key = key->pkey.ec; + + // Omit the redundant copy of the curve name. This contradicts RFC 5915 but + // aligns with PKCS #11. SEC 1 only says they may be omitted if known by other + // means. Both OpenSSL and NSS omit the redundant parameters, so we omit them + // as well. + unsigned enc_flags = EC_KEY_get_enc_flags(ec_key) | EC_PKEY_NO_PARAMETERS; + + // See RFC 5915. + CBB pkcs8, algorithm, oid, private_key; + if (!CBB_add_asn1(out, &pkcs8, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1_uint64(&pkcs8, 0 /* version */) || + !CBB_add_asn1(&pkcs8, &algorithm, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) || + !CBB_add_bytes(&oid, ec_asn1_meth.oid, ec_asn1_meth.oid_len) || + !EC_KEY_marshal_curve_name(&algorithm, EC_KEY_get0_group(ec_key)) || + !CBB_add_asn1(&pkcs8, &private_key, CBS_ASN1_OCTETSTRING) || + !EC_KEY_marshal_private_key(&private_key, ec_key, enc_flags) || + !CBB_flush(out)) { + OPENSSL_PUT_ERROR(EVP, EVP_R_ENCODE_ERROR); + 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) { + const EC_GROUP *group = EC_KEY_get0_group(pkey->pkey.ec); + if (group == NULL) { + ERR_clear_error(); + return 0; + } + return BN_num_bits(EC_GROUP_get0_order(group)); +} + +static int ec_missing_parameters(const EVP_PKEY *pkey) { + return EC_KEY_get0_group(pkey->pkey.ec) == NULL; +} + +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 || + 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 (EC_GROUP_cmp(group_a, group_b, NULL) != 0) { + // mismatch + return 0; + } + return 1; +} + +static void int_ec_free(EVP_PKEY *pkey) { EC_KEY_free(pkey->pkey.ec); } + +static int eckey_opaque(const EVP_PKEY *pkey) { + return EC_KEY_is_opaque(pkey->pkey.ec); +} + +const EVP_PKEY_ASN1_METHOD ec_asn1_meth = { + EVP_PKEY_EC, + // 1.2.840.10045.2.1 + {0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01}, 7, + + eckey_pub_decode, + eckey_pub_encode, + eckey_pub_cmp, + + eckey_priv_decode, + eckey_priv_encode, + + eckey_opaque, + + int_ec_size, + ec_bits, + + ec_missing_parameters, + ec_copy_parameters, + ec_cmp_parameters, + + int_ec_free, +}; diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/p_ed25519.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/p_ed25519.c new file mode 100644 index 0000000..9f4c72f --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/p_ed25519.c @@ -0,0 +1,71 @@ +/* Copyright (c) 2017, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include +#include + +#include "internal.h" + + +// Ed25519 has no parameters to copy. +static int pkey_ed25519_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) { return 1; } + +static int pkey_ed25519_sign_message(EVP_PKEY_CTX *ctx, uint8_t *sig, + size_t *siglen, const uint8_t *tbs, + size_t tbslen) { + ED25519_KEY *key = ctx->pkey->pkey.ptr; + if (!key->has_private) { + OPENSSL_PUT_ERROR(EVP, EVP_R_NOT_A_PRIVATE_KEY); + return 0; + } + + *siglen = 64; + if (sig == NULL) { + return 1; + } + + return ED25519_sign(sig, tbs, tbslen, key->key.priv); +} + +static int pkey_ed25519_verify_message(EVP_PKEY_CTX *ctx, const uint8_t *sig, + size_t siglen, const uint8_t *tbs, + size_t tbslen) { + ED25519_KEY *key = ctx->pkey->pkey.ptr; + if (siglen != 64 || + !ED25519_verify(tbs, tbslen, sig, key->key.pub.value)) { + OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_SIGNATURE); + return 0; + } + + return 1; +} + +const EVP_PKEY_METHOD ed25519_pkey_meth = { + EVP_PKEY_ED25519, + NULL /* init */, + pkey_ed25519_copy, + NULL /* cleanup */, + NULL /* keygen */, + NULL /* sign */, + pkey_ed25519_sign_message, + NULL /* verify */, + pkey_ed25519_verify_message, + NULL /* verify_recover */, + NULL /* encrypt */, + NULL /* decrypt */, + NULL /* derive */, + NULL /* ctrl */, +}; diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/p_ed25519.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/p_ed25519.c.grpc_back new file mode 100644 index 0000000..554a379 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/p_ed25519.c.grpc_back @@ -0,0 +1,71 @@ +/* Copyright (c) 2017, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include +#include + +#include "internal.h" + + +// Ed25519 has no parameters to copy. +static int pkey_ed25519_copy(EVP_PKEY_CTX *dst, EVP_PKEY_CTX *src) { return 1; } + +static int pkey_ed25519_sign_message(EVP_PKEY_CTX *ctx, uint8_t *sig, + size_t *siglen, const uint8_t *tbs, + size_t tbslen) { + ED25519_KEY *key = ctx->pkey->pkey.ptr; + if (!key->has_private) { + OPENSSL_PUT_ERROR(EVP, EVP_R_NOT_A_PRIVATE_KEY); + return 0; + } + + *siglen = 64; + if (sig == NULL) { + return 1; + } + + return ED25519_sign(sig, tbs, tbslen, key->key.priv); +} + +static int pkey_ed25519_verify_message(EVP_PKEY_CTX *ctx, const uint8_t *sig, + size_t siglen, const uint8_t *tbs, + size_t tbslen) { + ED25519_KEY *key = ctx->pkey->pkey.ptr; + if (siglen != 64 || + !ED25519_verify(tbs, tbslen, sig, key->key.pub.value)) { + OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_SIGNATURE); + return 0; + } + + return 1; +} + +const EVP_PKEY_METHOD ed25519_pkey_meth = { + EVP_PKEY_ED25519, + NULL /* init */, + pkey_ed25519_copy, + NULL /* cleanup */, + NULL /* keygen */, + NULL /* sign */, + pkey_ed25519_sign_message, + NULL /* verify */, + pkey_ed25519_verify_message, + NULL /* verify_recover */, + NULL /* encrypt */, + NULL /* decrypt */, + NULL /* derive */, + NULL /* ctrl */, +}; diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/p_ed25519_asn1.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/p_ed25519_asn1.c new file mode 100644 index 0000000..3c88971 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/p_ed25519_asn1.c @@ -0,0 +1,190 @@ +/* Copyright (c) 2017, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include +#include +#include +#include + +#include "internal.h" +#include "../internal.h" + + +static void ed25519_free(EVP_PKEY *pkey) { + OPENSSL_free(pkey->pkey.ptr); + pkey->pkey.ptr = NULL; +} + +static int set_pubkey(EVP_PKEY *pkey, const uint8_t pubkey[32]) { + ED25519_KEY *key = OPENSSL_malloc(sizeof(ED25519_KEY)); + if (key == NULL) { + OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); + return 0; + } + key->has_private = 0; + OPENSSL_memcpy(key->key.pub.value, pubkey, 32); + + ed25519_free(pkey); + pkey->pkey.ptr = key; + return 1; +} + +static int set_privkey(EVP_PKEY *pkey, const uint8_t privkey[64]) { + ED25519_KEY *key = OPENSSL_malloc(sizeof(ED25519_KEY)); + if (key == NULL) { + OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); + return 0; + } + key->has_private = 1; + OPENSSL_memcpy(key->key.priv, privkey, 64); + + ed25519_free(pkey); + pkey->pkey.ptr = key; + return 1; +} + +static int ed25519_pub_decode(EVP_PKEY *out, CBS *params, CBS *key) { + // See draft-ietf-curdle-pkix-04, section 4. + + // The parameters must be omitted. Public keys have length 32. + if (CBS_len(params) != 0 || + CBS_len(key) != 32) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + return 0; + } + + return set_pubkey(out, CBS_data(key)); +} + +static int ed25519_pub_encode(CBB *out, const EVP_PKEY *pkey) { + const ED25519_KEY *key = pkey->pkey.ptr; + + // See draft-ietf-curdle-pkix-04, section 4. + CBB spki, algorithm, oid, key_bitstring; + if (!CBB_add_asn1(out, &spki, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1(&spki, &algorithm, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) || + !CBB_add_bytes(&oid, ed25519_asn1_meth.oid, ed25519_asn1_meth.oid_len) || + !CBB_add_asn1(&spki, &key_bitstring, CBS_ASN1_BITSTRING) || + !CBB_add_u8(&key_bitstring, 0 /* padding */) || + !CBB_add_bytes(&key_bitstring, key->key.pub.value, 32) || + !CBB_flush(out)) { + OPENSSL_PUT_ERROR(EVP, EVP_R_ENCODE_ERROR); + return 0; + } + + return 1; +} + +static int ed25519_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) { + const ED25519_KEY *a_key = a->pkey.ptr; + const ED25519_KEY *b_key = b->pkey.ptr; + return OPENSSL_memcmp(a_key->key.pub.value, b_key->key.pub.value, 32) == 0; +} + +static int ed25519_priv_decode(EVP_PKEY *out, CBS *params, CBS *key) { + // See draft-ietf-curdle-pkix-04, section 7. + + // Parameters must be empty. The key is a 32-byte value wrapped in an extra + // OCTET STRING layer. + CBS inner; + if (CBS_len(params) != 0 || + !CBS_get_asn1(key, &inner, CBS_ASN1_OCTETSTRING) || + CBS_len(key) != 0 || + CBS_len(&inner) != 32) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + return 0; + } + + // The PKCS#8 encoding stores only the 32-byte seed, so we must recover the + // full representation which we use from it. + uint8_t pubkey[32], privkey[64]; + ED25519_keypair_from_seed(pubkey, privkey, CBS_data(&inner)); + return set_privkey(out, privkey); +} + +static int ed25519_priv_encode(CBB *out, const EVP_PKEY *pkey) { + ED25519_KEY *key = pkey->pkey.ptr; + if (!key->has_private) { + OPENSSL_PUT_ERROR(EVP, EVP_R_NOT_A_PRIVATE_KEY); + return 0; + } + + // See draft-ietf-curdle-pkix-04, section 7. + CBB pkcs8, algorithm, oid, private_key, inner; + if (!CBB_add_asn1(out, &pkcs8, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1_uint64(&pkcs8, 0 /* version */) || + !CBB_add_asn1(&pkcs8, &algorithm, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) || + !CBB_add_bytes(&oid, ed25519_asn1_meth.oid, ed25519_asn1_meth.oid_len) || + !CBB_add_asn1(&pkcs8, &private_key, CBS_ASN1_OCTETSTRING) || + !CBB_add_asn1(&private_key, &inner, CBS_ASN1_OCTETSTRING) || + // The PKCS#8 encoding stores only the 32-byte seed which is the first 32 + // bytes of the private key. + !CBB_add_bytes(&inner, key->key.priv, 32) || + !CBB_flush(out)) { + OPENSSL_PUT_ERROR(EVP, EVP_R_ENCODE_ERROR); + return 0; + } + + return 1; +} + +static int ed25519_size(const EVP_PKEY *pkey) { return 64; } + +static int ed25519_bits(const EVP_PKEY *pkey) { return 256; } + +const EVP_PKEY_ASN1_METHOD ed25519_asn1_meth = { + EVP_PKEY_ED25519, + {0x2b, 0x65, 0x70}, + 3, + ed25519_pub_decode, + ed25519_pub_encode, + ed25519_pub_cmp, + ed25519_priv_decode, + ed25519_priv_encode, + NULL /* pkey_opaque */, + ed25519_size, + ed25519_bits, + NULL /* param_missing */, + NULL /* param_copy */, + NULL /* param_cmp */, + ed25519_free, +}; + +EVP_PKEY *EVP_PKEY_new_ed25519_public(const uint8_t public_key[32]) { + EVP_PKEY *ret = EVP_PKEY_new(); + if (ret == NULL || + !EVP_PKEY_set_type(ret, EVP_PKEY_ED25519) || + !set_pubkey(ret, public_key)) { + EVP_PKEY_free(ret); + return NULL; + } + + return ret; +} + +EVP_PKEY *EVP_PKEY_new_ed25519_private(const uint8_t private_key[64]) { + EVP_PKEY *ret = EVP_PKEY_new(); + if (ret == NULL || + !EVP_PKEY_set_type(ret, EVP_PKEY_ED25519) || + !set_privkey(ret, private_key)) { + EVP_PKEY_free(ret); + return NULL; + } + + return ret; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/p_ed25519_asn1.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/p_ed25519_asn1.c.grpc_back new file mode 100644 index 0000000..65b4112 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/p_ed25519_asn1.c.grpc_back @@ -0,0 +1,190 @@ +/* Copyright (c) 2017, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include +#include +#include +#include + +#include "internal.h" +#include "../internal.h" + + +static void ed25519_free(EVP_PKEY *pkey) { + OPENSSL_free(pkey->pkey.ptr); + pkey->pkey.ptr = NULL; +} + +static int set_pubkey(EVP_PKEY *pkey, const uint8_t pubkey[32]) { + ED25519_KEY *key = OPENSSL_malloc(sizeof(ED25519_KEY)); + if (key == NULL) { + OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); + return 0; + } + key->has_private = 0; + OPENSSL_memcpy(key->key.pub.value, pubkey, 32); + + ed25519_free(pkey); + pkey->pkey.ptr = key; + return 1; +} + +static int set_privkey(EVP_PKEY *pkey, const uint8_t privkey[64]) { + ED25519_KEY *key = OPENSSL_malloc(sizeof(ED25519_KEY)); + if (key == NULL) { + OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); + return 0; + } + key->has_private = 1; + OPENSSL_memcpy(key->key.priv, privkey, 64); + + ed25519_free(pkey); + pkey->pkey.ptr = key; + return 1; +} + +static int ed25519_pub_decode(EVP_PKEY *out, CBS *params, CBS *key) { + // See draft-ietf-curdle-pkix-04, section 4. + + // The parameters must be omitted. Public keys have length 32. + if (CBS_len(params) != 0 || + CBS_len(key) != 32) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + return 0; + } + + return set_pubkey(out, CBS_data(key)); +} + +static int ed25519_pub_encode(CBB *out, const EVP_PKEY *pkey) { + const ED25519_KEY *key = pkey->pkey.ptr; + + // See draft-ietf-curdle-pkix-04, section 4. + CBB spki, algorithm, oid, key_bitstring; + if (!CBB_add_asn1(out, &spki, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1(&spki, &algorithm, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) || + !CBB_add_bytes(&oid, ed25519_asn1_meth.oid, ed25519_asn1_meth.oid_len) || + !CBB_add_asn1(&spki, &key_bitstring, CBS_ASN1_BITSTRING) || + !CBB_add_u8(&key_bitstring, 0 /* padding */) || + !CBB_add_bytes(&key_bitstring, key->key.pub.value, 32) || + !CBB_flush(out)) { + OPENSSL_PUT_ERROR(EVP, EVP_R_ENCODE_ERROR); + return 0; + } + + return 1; +} + +static int ed25519_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) { + const ED25519_KEY *a_key = a->pkey.ptr; + const ED25519_KEY *b_key = b->pkey.ptr; + return OPENSSL_memcmp(a_key->key.pub.value, b_key->key.pub.value, 32) == 0; +} + +static int ed25519_priv_decode(EVP_PKEY *out, CBS *params, CBS *key) { + // See draft-ietf-curdle-pkix-04, section 7. + + // Parameters must be empty. The key is a 32-byte value wrapped in an extra + // OCTET STRING layer. + CBS inner; + if (CBS_len(params) != 0 || + !CBS_get_asn1(key, &inner, CBS_ASN1_OCTETSTRING) || + CBS_len(key) != 0 || + CBS_len(&inner) != 32) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + return 0; + } + + // The PKCS#8 encoding stores only the 32-byte seed, so we must recover the + // full representation which we use from it. + uint8_t pubkey[32], privkey[64]; + ED25519_keypair_from_seed(pubkey, privkey, CBS_data(&inner)); + return set_privkey(out, privkey); +} + +static int ed25519_priv_encode(CBB *out, const EVP_PKEY *pkey) { + ED25519_KEY *key = pkey->pkey.ptr; + if (!key->has_private) { + OPENSSL_PUT_ERROR(EVP, EVP_R_NOT_A_PRIVATE_KEY); + return 0; + } + + // See draft-ietf-curdle-pkix-04, section 7. + CBB pkcs8, algorithm, oid, private_key, inner; + if (!CBB_add_asn1(out, &pkcs8, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1_uint64(&pkcs8, 0 /* version */) || + !CBB_add_asn1(&pkcs8, &algorithm, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) || + !CBB_add_bytes(&oid, ed25519_asn1_meth.oid, ed25519_asn1_meth.oid_len) || + !CBB_add_asn1(&pkcs8, &private_key, CBS_ASN1_OCTETSTRING) || + !CBB_add_asn1(&private_key, &inner, CBS_ASN1_OCTETSTRING) || + // The PKCS#8 encoding stores only the 32-byte seed which is the first 32 + // bytes of the private key. + !CBB_add_bytes(&inner, key->key.priv, 32) || + !CBB_flush(out)) { + OPENSSL_PUT_ERROR(EVP, EVP_R_ENCODE_ERROR); + return 0; + } + + return 1; +} + +static int ed25519_size(const EVP_PKEY *pkey) { return 64; } + +static int ed25519_bits(const EVP_PKEY *pkey) { return 256; } + +const EVP_PKEY_ASN1_METHOD ed25519_asn1_meth = { + EVP_PKEY_ED25519, + {0x2b, 0x65, 0x70}, + 3, + ed25519_pub_decode, + ed25519_pub_encode, + ed25519_pub_cmp, + ed25519_priv_decode, + ed25519_priv_encode, + NULL /* pkey_opaque */, + ed25519_size, + ed25519_bits, + NULL /* param_missing */, + NULL /* param_copy */, + NULL /* param_cmp */, + ed25519_free, +}; + +EVP_PKEY *EVP_PKEY_new_ed25519_public(const uint8_t public_key[32]) { + EVP_PKEY *ret = EVP_PKEY_new(); + if (ret == NULL || + !EVP_PKEY_set_type(ret, EVP_PKEY_ED25519) || + !set_pubkey(ret, public_key)) { + EVP_PKEY_free(ret); + return NULL; + } + + return ret; +} + +EVP_PKEY *EVP_PKEY_new_ed25519_private(const uint8_t private_key[64]) { + EVP_PKEY *ret = EVP_PKEY_new(); + if (ret == NULL || + !EVP_PKEY_set_type(ret, EVP_PKEY_ED25519) || + !set_privkey(ret, private_key)) { + EVP_PKEY_free(ret); + return NULL; + } + + return ret; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/p_rsa.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/p_rsa.c new file mode 100644 index 0000000..b5f7271 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/p_rsa.c @@ -0,0 +1,634 @@ +/* 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 +#include +#include +#include +#include +#include +#include + +#include "../internal.h" +#include "../fipsmodule/rsa/internal.h" +#include "internal.h" + + +typedef struct { + // Key gen parameters + int nbits; + BIGNUM *pub_exp; + // 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; + // tbuf is a buffer which is either NULL, or is the size of the RSA modulus. + // It's used to store the output of RSA operations. + uint8_t *tbuf; + // OAEP label + uint8_t *oaep_label; + size_t oaep_labellen; +} RSA_PKEY_CTX; + +typedef struct { + uint8_t *data; + size_t len; +} RSA_OAEP_LABEL_PARAMS; + +static int pkey_rsa_init(EVP_PKEY_CTX *ctx) { + RSA_PKEY_CTX *rctx; + rctx = OPENSSL_malloc(sizeof(RSA_PKEY_CTX)); + if (!rctx) { + return 0; + } + OPENSSL_memset(rctx, 0, sizeof(RSA_PKEY_CTX)); + + rctx->nbits = 2048; + rctx->pad_mode = RSA_PKCS1_PADDING; + rctx->saltlen = -2; + + ctx->data = rctx; + + 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) { + 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 void pkey_rsa_cleanup(EVP_PKEY_CTX *ctx) { + RSA_PKEY_CTX *rctx = ctx->data; + + if (rctx == NULL) { + return; + } + + BN_free(rctx->pub_exp); + OPENSSL_free(rctx->tbuf); + OPENSSL_free(rctx->oaep_label); + OPENSSL_free(rctx); +} + +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 int pkey_rsa_sign(EVP_PKEY_CTX *ctx, uint8_t *sig, size_t *siglen, + const uint8_t *tbs, size_t tbslen) { + RSA_PKEY_CTX *rctx = ctx->data; + RSA *rsa = ctx->pkey->pkey.rsa; + const size_t key_len = EVP_PKEY_size(ctx->pkey); + + if (!sig) { + *siglen = key_len; + return 1; + } + + if (*siglen < key_len) { + OPENSSL_PUT_ERROR(EVP, EVP_R_BUFFER_TOO_SMALL); + return 0; + } + + if (rctx->md) { + unsigned out_len; + switch (rctx->pad_mode) { + case RSA_PKCS1_PADDING: + if (!RSA_sign(EVP_MD_type(rctx->md), tbs, tbslen, sig, &out_len, rsa)) { + return 0; + } + *siglen = out_len; + return 1; + + case RSA_PKCS1_PSS_PADDING: + return RSA_sign_pss_mgf1(rsa, siglen, sig, *siglen, tbs, tbslen, + rctx->md, rctx->mgf1md, rctx->saltlen); + + default: + return 0; + } + } + + return RSA_sign_raw(rsa, siglen, sig, *siglen, tbs, tbslen, rctx->pad_mode); +} + +static int pkey_rsa_verify(EVP_PKEY_CTX *ctx, const uint8_t *sig, + size_t siglen, const uint8_t *tbs, + size_t tbslen) { + RSA_PKEY_CTX *rctx = ctx->data; + RSA *rsa = ctx->pkey->pkey.rsa; + + if (rctx->md) { + switch (rctx->pad_mode) { + case RSA_PKCS1_PADDING: + return RSA_verify(EVP_MD_type(rctx->md), tbs, tbslen, sig, siglen, rsa); + + case RSA_PKCS1_PSS_PADDING: + return RSA_verify_pss_mgf1(rsa, tbs, tbslen, rctx->md, rctx->mgf1md, + rctx->saltlen, sig, siglen); + + default: + return 0; + } + } + + size_t rslen; + const size_t key_len = EVP_PKEY_size(ctx->pkey); + if (!setup_tbuf(rctx, ctx) || + !RSA_verify_raw(rsa, &rslen, rctx->tbuf, key_len, sig, siglen, + rctx->pad_mode) || + rslen != tbslen || + CRYPTO_memcmp(tbs, rctx->tbuf, rslen) != 0) { + return 0; + } + + return 1; +} + +static int pkey_rsa_verify_recover(EVP_PKEY_CTX *ctx, uint8_t *out, + size_t *out_len, const uint8_t *sig, + size_t sig_len) { + RSA_PKEY_CTX *rctx = ctx->data; + RSA *rsa = ctx->pkey->pkey.rsa; + const size_t key_len = EVP_PKEY_size(ctx->pkey); + + if (out == NULL) { + *out_len = key_len; + return 1; + } + + if (*out_len < key_len) { + OPENSSL_PUT_ERROR(EVP, EVP_R_BUFFER_TOO_SMALL); + return 0; + } + + if (rctx->md == NULL) { + return RSA_verify_raw(rsa, out_len, out, *out_len, sig, sig_len, + rctx->pad_mode); + } + + if (rctx->pad_mode != RSA_PKCS1_PADDING) { + return 0; + } + + // Assemble the encoded hash, using a placeholder hash value. + static const uint8_t kDummyHash[EVP_MAX_MD_SIZE] = {0}; + const size_t hash_len = EVP_MD_size(rctx->md); + uint8_t *asn1_prefix; + size_t asn1_prefix_len; + int asn1_prefix_allocated; + if (!setup_tbuf(rctx, ctx) || + !RSA_add_pkcs1_prefix(&asn1_prefix, &asn1_prefix_len, + &asn1_prefix_allocated, EVP_MD_type(rctx->md), + kDummyHash, hash_len)) { + return 0; + } + + size_t rslen; + int ok = 1; + if (!RSA_verify_raw(rsa, &rslen, rctx->tbuf, key_len, sig, sig_len, + RSA_PKCS1_PADDING) || + rslen != asn1_prefix_len || + // Compare all but the hash suffix. + CRYPTO_memcmp(rctx->tbuf, asn1_prefix, asn1_prefix_len - hash_len) != 0) { + ok = 0; + } + + if (asn1_prefix_allocated) { + OPENSSL_free(asn1_prefix); + } + + if (!ok) { + return 0; + } + + if (out != NULL) { + OPENSSL_memcpy(out, rctx->tbuf + rslen - hash_len, hash_len); + } + *out_len = hash_len; + + return 1; +} + +static int pkey_rsa_encrypt(EVP_PKEY_CTX *ctx, uint8_t *out, size_t *outlen, + const uint8_t *in, size_t inlen) { + RSA_PKEY_CTX *rctx = ctx->data; + RSA *rsa = ctx->pkey->pkey.rsa; + const size_t key_len = EVP_PKEY_size(ctx->pkey); + + if (!out) { + *outlen = key_len; + return 1; + } + + if (*outlen < key_len) { + OPENSSL_PUT_ERROR(EVP, EVP_R_BUFFER_TOO_SMALL); + return 0; + } + + if (rctx->pad_mode == RSA_PKCS1_OAEP_PADDING) { + if (!setup_tbuf(rctx, ctx) || + !RSA_padding_add_PKCS1_OAEP_mgf1(rctx->tbuf, key_len, in, inlen, + rctx->oaep_label, rctx->oaep_labellen, + rctx->md, rctx->mgf1md) || + !RSA_encrypt(rsa, outlen, out, *outlen, rctx->tbuf, key_len, + RSA_NO_PADDING)) { + return 0; + } + return 1; + } + + return RSA_encrypt(rsa, outlen, out, *outlen, in, inlen, rctx->pad_mode); +} + +static int pkey_rsa_decrypt(EVP_PKEY_CTX *ctx, uint8_t *out, + size_t *outlen, const uint8_t *in, + size_t inlen) { + RSA_PKEY_CTX *rctx = ctx->data; + RSA *rsa = ctx->pkey->pkey.rsa; + const size_t key_len = EVP_PKEY_size(ctx->pkey); + + if (!out) { + *outlen = key_len; + return 1; + } + + if (*outlen < key_len) { + OPENSSL_PUT_ERROR(EVP, EVP_R_BUFFER_TOO_SMALL); + return 0; + } + + if (rctx->pad_mode == RSA_PKCS1_OAEP_PADDING) { + size_t padded_len; + if (!setup_tbuf(rctx, ctx) || + !RSA_decrypt(rsa, &padded_len, rctx->tbuf, key_len, in, inlen, + RSA_NO_PADDING) || + !RSA_padding_check_PKCS1_OAEP_mgf1( + out, outlen, key_len, rctx->tbuf, padded_len, rctx->oaep_label, + rctx->oaep_labellen, rctx->md, rctx->mgf1md)) { + return 0; + } + return 1; + } + + return RSA_decrypt(rsa, outlen, out, key_len, in, inlen, rctx->pad_mode); +} + +static int check_padding_md(const EVP_MD *md, int padding) { + if (!md) { + return 1; + } + + if (padding == RSA_NO_PADDING) { + OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_PADDING_MODE); + return 0; + } + + return 1; +} + +static int is_known_padding(int padding_mode) { + switch (padding_mode) { + case RSA_PKCS1_PADDING: + case RSA_NO_PADDING: + case RSA_PKCS1_OAEP_PADDING: + case RSA_PKCS1_PSS_PADDING: + return 1; + default: + return 0; + } +} + +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 (!is_known_padding(p1) || !check_padding_md(rctx->md, p1) || + (p1 == RSA_PKCS1_PSS_PADDING && + 0 == (ctx->operation & (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY))) || + (p1 == RSA_PKCS1_OAEP_PADDING && + 0 == (ctx->operation & EVP_PKEY_OP_TYPE_CRYPT))) { + OPENSSL_PUT_ERROR(EVP, EVP_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE); + return 0; + } + if ((p1 == RSA_PKCS1_PSS_PADDING || p1 == RSA_PKCS1_OAEP_PADDING) && + rctx->md == NULL) { + rctx->md = EVP_sha1(); + } + rctx->pad_mode = p1; + return 1; + + 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) { + OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_PSS_SALTLEN); + return 0; + } + if (type == EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN) { + *(int *)p2 = rctx->saltlen; + } else { + if (p1 < -2) { + return 0; + } + rctx->saltlen = p1; + } + return 1; + + case EVP_PKEY_CTRL_RSA_KEYGEN_BITS: + if (p1 < 256) { + OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_KEYBITS); + return 0; + } + rctx->nbits = p1; + return 1; + + case EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP: + if (!p2) { + return 0; + } + 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) { + OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_PADDING_MODE); + return 0; + } + 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) { + OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_MGF1_MD); + return 0; + } + 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) { + OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_PADDING_MODE); + return 0; + } + OPENSSL_free(rctx->oaep_label); + RSA_OAEP_LABEL_PARAMS *params = p2; + rctx->oaep_label = params->data; + rctx->oaep_labellen = params->len; + return 1; + } + + case EVP_PKEY_CTRL_GET_RSA_OAEP_LABEL: + if (rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) { + OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_PADDING_MODE); + return 0; + } + CBS_init((CBS *)p2, rctx->oaep_label, rctx->oaep_labellen); + return 1; + + default: + OPENSSL_PUT_ERROR(EVP, EVP_R_COMMAND_NOT_SUPPORTED); + return 0; + } +} + +static int pkey_rsa_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) { + RSA *rsa = NULL; + RSA_PKEY_CTX *rctx = ctx->data; + + 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 (!RSA_generate_key_ex(rsa, rctx->nbits, rctx->pub_exp, NULL)) { + RSA_free(rsa); + return 0; + } + + EVP_PKEY_assign_RSA(pkey, rsa); + return 1; +} + +const EVP_PKEY_METHOD rsa_pkey_meth = { + EVP_PKEY_RSA, + pkey_rsa_init, + pkey_rsa_copy, + pkey_rsa_cleanup, + pkey_rsa_keygen, + pkey_rsa_sign, + NULL /* sign_message */, + pkey_rsa_verify, + NULL /* verify_message */, + pkey_rsa_verify_recover, + pkey_rsa_encrypt, + pkey_rsa_decrypt, + 0 /* derive */, + pkey_rsa_ctrl, +}; + +int EVP_PKEY_CTX_set_rsa_padding(EVP_PKEY_CTX *ctx, int padding) { + return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, -1, EVP_PKEY_CTRL_RSA_PADDING, + padding, NULL); +} + +int EVP_PKEY_CTX_get_rsa_padding(EVP_PKEY_CTX *ctx, int *out_padding) { + return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, -1, EVP_PKEY_CTRL_GET_RSA_PADDING, + 0, out_padding); +} + +int EVP_PKEY_CTX_set_rsa_pss_saltlen(EVP_PKEY_CTX *ctx, int salt_len) { + return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, + (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY), + EVP_PKEY_CTRL_RSA_PSS_SALTLEN, salt_len, NULL); +} + +int EVP_PKEY_CTX_get_rsa_pss_saltlen(EVP_PKEY_CTX *ctx, int *out_salt_len) { + return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, + (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY), + EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN, 0, out_salt_len); +} + +int EVP_PKEY_CTX_set_rsa_keygen_bits(EVP_PKEY_CTX *ctx, int bits) { + return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_KEYGEN, + EVP_PKEY_CTRL_RSA_KEYGEN_BITS, bits, NULL); +} + +int EVP_PKEY_CTX_set_rsa_keygen_pubexp(EVP_PKEY_CTX *ctx, BIGNUM *e) { + return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_KEYGEN, + EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP, 0, e); +} + +int EVP_PKEY_CTX_set_rsa_oaep_md(EVP_PKEY_CTX *ctx, const EVP_MD *md) { + return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT, + EVP_PKEY_CTRL_RSA_OAEP_MD, 0, (void *)md); +} + +int EVP_PKEY_CTX_get_rsa_oaep_md(EVP_PKEY_CTX *ctx, const EVP_MD **out_md) { + return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT, + EVP_PKEY_CTRL_GET_RSA_OAEP_MD, 0, (void*) out_md); +} + +int EVP_PKEY_CTX_set_rsa_mgf1_md(EVP_PKEY_CTX *ctx, const EVP_MD *md) { + return 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); +} + +int EVP_PKEY_CTX_get_rsa_mgf1_md(EVP_PKEY_CTX *ctx, const EVP_MD **out_md) { + return 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*) out_md); +} + +int EVP_PKEY_CTX_set0_rsa_oaep_label(EVP_PKEY_CTX *ctx, uint8_t *label, + size_t label_len) { + RSA_OAEP_LABEL_PARAMS params = {label, label_len}; + return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT, + EVP_PKEY_CTRL_RSA_OAEP_LABEL, 0, ¶ms); +} + +int EVP_PKEY_CTX_get0_rsa_oaep_label(EVP_PKEY_CTX *ctx, + const uint8_t **out_label) { + CBS label; + if (!EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT, + EVP_PKEY_CTRL_GET_RSA_OAEP_LABEL, 0, &label)) { + return -1; + } + if (CBS_len(&label) > INT_MAX) { + OPENSSL_PUT_ERROR(EVP, ERR_R_OVERFLOW); + return -1; + } + *out_label = CBS_data(&label); + return (int)CBS_len(&label); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/p_rsa.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/p_rsa.c.grpc_back new file mode 100644 index 0000000..cfc6bea --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/p_rsa.c.grpc_back @@ -0,0 +1,634 @@ +/* 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 +#include +#include +#include +#include +#include +#include + +#include "../internal.h" +#include "../fipsmodule/rsa/internal.h" +#include "internal.h" + + +typedef struct { + // Key gen parameters + int nbits; + BIGNUM *pub_exp; + // 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; + // tbuf is a buffer which is either NULL, or is the size of the RSA modulus. + // It's used to store the output of RSA operations. + uint8_t *tbuf; + // OAEP label + uint8_t *oaep_label; + size_t oaep_labellen; +} RSA_PKEY_CTX; + +typedef struct { + uint8_t *data; + size_t len; +} RSA_OAEP_LABEL_PARAMS; + +static int pkey_rsa_init(EVP_PKEY_CTX *ctx) { + RSA_PKEY_CTX *rctx; + rctx = OPENSSL_malloc(sizeof(RSA_PKEY_CTX)); + if (!rctx) { + return 0; + } + OPENSSL_memset(rctx, 0, sizeof(RSA_PKEY_CTX)); + + rctx->nbits = 2048; + rctx->pad_mode = RSA_PKCS1_PADDING; + rctx->saltlen = -2; + + ctx->data = rctx; + + 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) { + 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 void pkey_rsa_cleanup(EVP_PKEY_CTX *ctx) { + RSA_PKEY_CTX *rctx = ctx->data; + + if (rctx == NULL) { + return; + } + + BN_free(rctx->pub_exp); + OPENSSL_free(rctx->tbuf); + OPENSSL_free(rctx->oaep_label); + OPENSSL_free(rctx); +} + +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 int pkey_rsa_sign(EVP_PKEY_CTX *ctx, uint8_t *sig, size_t *siglen, + const uint8_t *tbs, size_t tbslen) { + RSA_PKEY_CTX *rctx = ctx->data; + RSA *rsa = ctx->pkey->pkey.rsa; + const size_t key_len = EVP_PKEY_size(ctx->pkey); + + if (!sig) { + *siglen = key_len; + return 1; + } + + if (*siglen < key_len) { + OPENSSL_PUT_ERROR(EVP, EVP_R_BUFFER_TOO_SMALL); + return 0; + } + + if (rctx->md) { + unsigned out_len; + switch (rctx->pad_mode) { + case RSA_PKCS1_PADDING: + if (!RSA_sign(EVP_MD_type(rctx->md), tbs, tbslen, sig, &out_len, rsa)) { + return 0; + } + *siglen = out_len; + return 1; + + case RSA_PKCS1_PSS_PADDING: + return RSA_sign_pss_mgf1(rsa, siglen, sig, *siglen, tbs, tbslen, + rctx->md, rctx->mgf1md, rctx->saltlen); + + default: + return 0; + } + } + + return RSA_sign_raw(rsa, siglen, sig, *siglen, tbs, tbslen, rctx->pad_mode); +} + +static int pkey_rsa_verify(EVP_PKEY_CTX *ctx, const uint8_t *sig, + size_t siglen, const uint8_t *tbs, + size_t tbslen) { + RSA_PKEY_CTX *rctx = ctx->data; + RSA *rsa = ctx->pkey->pkey.rsa; + + if (rctx->md) { + switch (rctx->pad_mode) { + case RSA_PKCS1_PADDING: + return RSA_verify(EVP_MD_type(rctx->md), tbs, tbslen, sig, siglen, rsa); + + case RSA_PKCS1_PSS_PADDING: + return RSA_verify_pss_mgf1(rsa, tbs, tbslen, rctx->md, rctx->mgf1md, + rctx->saltlen, sig, siglen); + + default: + return 0; + } + } + + size_t rslen; + const size_t key_len = EVP_PKEY_size(ctx->pkey); + if (!setup_tbuf(rctx, ctx) || + !RSA_verify_raw(rsa, &rslen, rctx->tbuf, key_len, sig, siglen, + rctx->pad_mode) || + rslen != tbslen || + CRYPTO_memcmp(tbs, rctx->tbuf, rslen) != 0) { + return 0; + } + + return 1; +} + +static int pkey_rsa_verify_recover(EVP_PKEY_CTX *ctx, uint8_t *out, + size_t *out_len, const uint8_t *sig, + size_t sig_len) { + RSA_PKEY_CTX *rctx = ctx->data; + RSA *rsa = ctx->pkey->pkey.rsa; + const size_t key_len = EVP_PKEY_size(ctx->pkey); + + if (out == NULL) { + *out_len = key_len; + return 1; + } + + if (*out_len < key_len) { + OPENSSL_PUT_ERROR(EVP, EVP_R_BUFFER_TOO_SMALL); + return 0; + } + + if (rctx->md == NULL) { + return RSA_verify_raw(rsa, out_len, out, *out_len, sig, sig_len, + rctx->pad_mode); + } + + if (rctx->pad_mode != RSA_PKCS1_PADDING) { + return 0; + } + + // Assemble the encoded hash, using a placeholder hash value. + static const uint8_t kDummyHash[EVP_MAX_MD_SIZE] = {0}; + const size_t hash_len = EVP_MD_size(rctx->md); + uint8_t *asn1_prefix; + size_t asn1_prefix_len; + int asn1_prefix_allocated; + if (!setup_tbuf(rctx, ctx) || + !RSA_add_pkcs1_prefix(&asn1_prefix, &asn1_prefix_len, + &asn1_prefix_allocated, EVP_MD_type(rctx->md), + kDummyHash, hash_len)) { + return 0; + } + + size_t rslen; + int ok = 1; + if (!RSA_verify_raw(rsa, &rslen, rctx->tbuf, key_len, sig, sig_len, + RSA_PKCS1_PADDING) || + rslen != asn1_prefix_len || + // Compare all but the hash suffix. + CRYPTO_memcmp(rctx->tbuf, asn1_prefix, asn1_prefix_len - hash_len) != 0) { + ok = 0; + } + + if (asn1_prefix_allocated) { + OPENSSL_free(asn1_prefix); + } + + if (!ok) { + return 0; + } + + if (out != NULL) { + OPENSSL_memcpy(out, rctx->tbuf + rslen - hash_len, hash_len); + } + *out_len = hash_len; + + return 1; +} + +static int pkey_rsa_encrypt(EVP_PKEY_CTX *ctx, uint8_t *out, size_t *outlen, + const uint8_t *in, size_t inlen) { + RSA_PKEY_CTX *rctx = ctx->data; + RSA *rsa = ctx->pkey->pkey.rsa; + const size_t key_len = EVP_PKEY_size(ctx->pkey); + + if (!out) { + *outlen = key_len; + return 1; + } + + if (*outlen < key_len) { + OPENSSL_PUT_ERROR(EVP, EVP_R_BUFFER_TOO_SMALL); + return 0; + } + + if (rctx->pad_mode == RSA_PKCS1_OAEP_PADDING) { + if (!setup_tbuf(rctx, ctx) || + !RSA_padding_add_PKCS1_OAEP_mgf1(rctx->tbuf, key_len, in, inlen, + rctx->oaep_label, rctx->oaep_labellen, + rctx->md, rctx->mgf1md) || + !RSA_encrypt(rsa, outlen, out, *outlen, rctx->tbuf, key_len, + RSA_NO_PADDING)) { + return 0; + } + return 1; + } + + return RSA_encrypt(rsa, outlen, out, *outlen, in, inlen, rctx->pad_mode); +} + +static int pkey_rsa_decrypt(EVP_PKEY_CTX *ctx, uint8_t *out, + size_t *outlen, const uint8_t *in, + size_t inlen) { + RSA_PKEY_CTX *rctx = ctx->data; + RSA *rsa = ctx->pkey->pkey.rsa; + const size_t key_len = EVP_PKEY_size(ctx->pkey); + + if (!out) { + *outlen = key_len; + return 1; + } + + if (*outlen < key_len) { + OPENSSL_PUT_ERROR(EVP, EVP_R_BUFFER_TOO_SMALL); + return 0; + } + + if (rctx->pad_mode == RSA_PKCS1_OAEP_PADDING) { + size_t padded_len; + if (!setup_tbuf(rctx, ctx) || + !RSA_decrypt(rsa, &padded_len, rctx->tbuf, key_len, in, inlen, + RSA_NO_PADDING) || + !RSA_padding_check_PKCS1_OAEP_mgf1( + out, outlen, key_len, rctx->tbuf, padded_len, rctx->oaep_label, + rctx->oaep_labellen, rctx->md, rctx->mgf1md)) { + return 0; + } + return 1; + } + + return RSA_decrypt(rsa, outlen, out, key_len, in, inlen, rctx->pad_mode); +} + +static int check_padding_md(const EVP_MD *md, int padding) { + if (!md) { + return 1; + } + + if (padding == RSA_NO_PADDING) { + OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_PADDING_MODE); + return 0; + } + + return 1; +} + +static int is_known_padding(int padding_mode) { + switch (padding_mode) { + case RSA_PKCS1_PADDING: + case RSA_NO_PADDING: + case RSA_PKCS1_OAEP_PADDING: + case RSA_PKCS1_PSS_PADDING: + return 1; + default: + return 0; + } +} + +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 (!is_known_padding(p1) || !check_padding_md(rctx->md, p1) || + (p1 == RSA_PKCS1_PSS_PADDING && + 0 == (ctx->operation & (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY))) || + (p1 == RSA_PKCS1_OAEP_PADDING && + 0 == (ctx->operation & EVP_PKEY_OP_TYPE_CRYPT))) { + OPENSSL_PUT_ERROR(EVP, EVP_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE); + return 0; + } + if ((p1 == RSA_PKCS1_PSS_PADDING || p1 == RSA_PKCS1_OAEP_PADDING) && + rctx->md == NULL) { + rctx->md = EVP_sha1(); + } + rctx->pad_mode = p1; + return 1; + + 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) { + OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_PSS_SALTLEN); + return 0; + } + if (type == EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN) { + *(int *)p2 = rctx->saltlen; + } else { + if (p1 < -2) { + return 0; + } + rctx->saltlen = p1; + } + return 1; + + case EVP_PKEY_CTRL_RSA_KEYGEN_BITS: + if (p1 < 256) { + OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_KEYBITS); + return 0; + } + rctx->nbits = p1; + return 1; + + case EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP: + if (!p2) { + return 0; + } + 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) { + OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_PADDING_MODE); + return 0; + } + 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) { + OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_MGF1_MD); + return 0; + } + 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) { + OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_PADDING_MODE); + return 0; + } + OPENSSL_free(rctx->oaep_label); + RSA_OAEP_LABEL_PARAMS *params = p2; + rctx->oaep_label = params->data; + rctx->oaep_labellen = params->len; + return 1; + } + + case EVP_PKEY_CTRL_GET_RSA_OAEP_LABEL: + if (rctx->pad_mode != RSA_PKCS1_OAEP_PADDING) { + OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_PADDING_MODE); + return 0; + } + CBS_init((CBS *)p2, rctx->oaep_label, rctx->oaep_labellen); + return 1; + + default: + OPENSSL_PUT_ERROR(EVP, EVP_R_COMMAND_NOT_SUPPORTED); + return 0; + } +} + +static int pkey_rsa_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey) { + RSA *rsa = NULL; + RSA_PKEY_CTX *rctx = ctx->data; + + 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 (!RSA_generate_key_ex(rsa, rctx->nbits, rctx->pub_exp, NULL)) { + RSA_free(rsa); + return 0; + } + + EVP_PKEY_assign_RSA(pkey, rsa); + return 1; +} + +const EVP_PKEY_METHOD rsa_pkey_meth = { + EVP_PKEY_RSA, + pkey_rsa_init, + pkey_rsa_copy, + pkey_rsa_cleanup, + pkey_rsa_keygen, + pkey_rsa_sign, + NULL /* sign_message */, + pkey_rsa_verify, + NULL /* verify_message */, + pkey_rsa_verify_recover, + pkey_rsa_encrypt, + pkey_rsa_decrypt, + 0 /* derive */, + pkey_rsa_ctrl, +}; + +int EVP_PKEY_CTX_set_rsa_padding(EVP_PKEY_CTX *ctx, int padding) { + return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, -1, EVP_PKEY_CTRL_RSA_PADDING, + padding, NULL); +} + +int EVP_PKEY_CTX_get_rsa_padding(EVP_PKEY_CTX *ctx, int *out_padding) { + return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, -1, EVP_PKEY_CTRL_GET_RSA_PADDING, + 0, out_padding); +} + +int EVP_PKEY_CTX_set_rsa_pss_saltlen(EVP_PKEY_CTX *ctx, int salt_len) { + return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, + (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY), + EVP_PKEY_CTRL_RSA_PSS_SALTLEN, salt_len, NULL); +} + +int EVP_PKEY_CTX_get_rsa_pss_saltlen(EVP_PKEY_CTX *ctx, int *out_salt_len) { + return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, + (EVP_PKEY_OP_SIGN | EVP_PKEY_OP_VERIFY), + EVP_PKEY_CTRL_GET_RSA_PSS_SALTLEN, 0, out_salt_len); +} + +int EVP_PKEY_CTX_set_rsa_keygen_bits(EVP_PKEY_CTX *ctx, int bits) { + return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_KEYGEN, + EVP_PKEY_CTRL_RSA_KEYGEN_BITS, bits, NULL); +} + +int EVP_PKEY_CTX_set_rsa_keygen_pubexp(EVP_PKEY_CTX *ctx, BIGNUM *e) { + return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_KEYGEN, + EVP_PKEY_CTRL_RSA_KEYGEN_PUBEXP, 0, e); +} + +int EVP_PKEY_CTX_set_rsa_oaep_md(EVP_PKEY_CTX *ctx, const EVP_MD *md) { + return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT, + EVP_PKEY_CTRL_RSA_OAEP_MD, 0, (void *)md); +} + +int EVP_PKEY_CTX_get_rsa_oaep_md(EVP_PKEY_CTX *ctx, const EVP_MD **out_md) { + return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT, + EVP_PKEY_CTRL_GET_RSA_OAEP_MD, 0, (void*) out_md); +} + +int EVP_PKEY_CTX_set_rsa_mgf1_md(EVP_PKEY_CTX *ctx, const EVP_MD *md) { + return 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); +} + +int EVP_PKEY_CTX_get_rsa_mgf1_md(EVP_PKEY_CTX *ctx, const EVP_MD **out_md) { + return 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*) out_md); +} + +int EVP_PKEY_CTX_set0_rsa_oaep_label(EVP_PKEY_CTX *ctx, uint8_t *label, + size_t label_len) { + RSA_OAEP_LABEL_PARAMS params = {label, label_len}; + return EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT, + EVP_PKEY_CTRL_RSA_OAEP_LABEL, 0, ¶ms); +} + +int EVP_PKEY_CTX_get0_rsa_oaep_label(EVP_PKEY_CTX *ctx, + const uint8_t **out_label) { + CBS label; + if (!EVP_PKEY_CTX_ctrl(ctx, EVP_PKEY_RSA, EVP_PKEY_OP_TYPE_CRYPT, + EVP_PKEY_CTRL_GET_RSA_OAEP_LABEL, 0, &label)) { + return -1; + } + if (CBS_len(&label) > INT_MAX) { + OPENSSL_PUT_ERROR(EVP, ERR_R_OVERFLOW); + return -1; + } + *out_label = CBS_data(&label); + return (int)CBS_len(&label); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/p_rsa_asn1.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/p_rsa_asn1.c new file mode 100644 index 0000000..b10c36f --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/p_rsa_asn1.c @@ -0,0 +1,189 @@ +/* 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 +#include +#include + +#include "../fipsmodule/rsa/internal.h" +#include "internal.h" + + +static int rsa_pub_encode(CBB *out, const EVP_PKEY *key) { + // See RFC 3279, section 2.3.1. + CBB spki, algorithm, oid, null, key_bitstring; + if (!CBB_add_asn1(out, &spki, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1(&spki, &algorithm, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) || + !CBB_add_bytes(&oid, rsa_asn1_meth.oid, rsa_asn1_meth.oid_len) || + !CBB_add_asn1(&algorithm, &null, CBS_ASN1_NULL) || + !CBB_add_asn1(&spki, &key_bitstring, CBS_ASN1_BITSTRING) || + !CBB_add_u8(&key_bitstring, 0 /* padding */) || + !RSA_marshal_public_key(&key_bitstring, key->pkey.rsa) || + !CBB_flush(out)) { + OPENSSL_PUT_ERROR(EVP, EVP_R_ENCODE_ERROR); + return 0; + } + + return 1; +} + +static int rsa_pub_decode(EVP_PKEY *out, CBS *params, CBS *key) { + // See RFC 3279, section 2.3.1. + + // The parameters must be NULL. + CBS null; + if (!CBS_get_asn1(params, &null, CBS_ASN1_NULL) || + CBS_len(&null) != 0 || + CBS_len(params) != 0) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + return 0; + } + + RSA *rsa = RSA_parse_public_key(key); + if (rsa == NULL || CBS_len(key) != 0) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + RSA_free(rsa); + return 0; + } + + EVP_PKEY_assign_RSA(out, rsa); + return 1; +} + +static int rsa_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) { + return BN_cmp(b->pkey.rsa->n, a->pkey.rsa->n) == 0 && + BN_cmp(b->pkey.rsa->e, a->pkey.rsa->e) == 0; +} + +static int rsa_priv_encode(CBB *out, const EVP_PKEY *key) { + CBB pkcs8, algorithm, oid, null, private_key; + if (!CBB_add_asn1(out, &pkcs8, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1_uint64(&pkcs8, 0 /* version */) || + !CBB_add_asn1(&pkcs8, &algorithm, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) || + !CBB_add_bytes(&oid, rsa_asn1_meth.oid, rsa_asn1_meth.oid_len) || + !CBB_add_asn1(&algorithm, &null, CBS_ASN1_NULL) || + !CBB_add_asn1(&pkcs8, &private_key, CBS_ASN1_OCTETSTRING) || + !RSA_marshal_private_key(&private_key, key->pkey.rsa) || + !CBB_flush(out)) { + OPENSSL_PUT_ERROR(EVP, EVP_R_ENCODE_ERROR); + return 0; + } + + return 1; +} + +static int rsa_priv_decode(EVP_PKEY *out, CBS *params, CBS *key) { + // Per RFC 3447, A.1, the parameters have type NULL. + CBS null; + if (!CBS_get_asn1(params, &null, CBS_ASN1_NULL) || + CBS_len(&null) != 0 || + CBS_len(params) != 0) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + return 0; + } + + RSA *rsa = RSA_parse_private_key(key); + if (rsa == NULL || CBS_len(key) != 0) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + RSA_free(rsa); + return 0; + } + + EVP_PKEY_assign_RSA(out, rsa); + return 1; +} + +static int rsa_opaque(const EVP_PKEY *pkey) { + return RSA_is_opaque(pkey->pkey.rsa); +} + +static int int_rsa_size(const EVP_PKEY *pkey) { + return RSA_size(pkey->pkey.rsa); +} + +static int rsa_bits(const EVP_PKEY *pkey) { + return RSA_bits(pkey->pkey.rsa); +} + +static void int_rsa_free(EVP_PKEY *pkey) { RSA_free(pkey->pkey.rsa); } + +const EVP_PKEY_ASN1_METHOD rsa_asn1_meth = { + EVP_PKEY_RSA, + // 1.2.840.113549.1.1.1 + {0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01}, 9, + + rsa_pub_decode, + rsa_pub_encode, + rsa_pub_cmp, + + rsa_priv_decode, + rsa_priv_encode, + + rsa_opaque, + + int_rsa_size, + rsa_bits, + + 0,0,0, + + int_rsa_free, +}; diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/p_rsa_asn1.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/p_rsa_asn1.c.grpc_back new file mode 100644 index 0000000..85f6fc8 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/p_rsa_asn1.c.grpc_back @@ -0,0 +1,189 @@ +/* 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 +#include +#include + +#include "../fipsmodule/rsa/internal.h" +#include "internal.h" + + +static int rsa_pub_encode(CBB *out, const EVP_PKEY *key) { + // See RFC 3279, section 2.3.1. + CBB spki, algorithm, oid, null, key_bitstring; + if (!CBB_add_asn1(out, &spki, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1(&spki, &algorithm, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) || + !CBB_add_bytes(&oid, rsa_asn1_meth.oid, rsa_asn1_meth.oid_len) || + !CBB_add_asn1(&algorithm, &null, CBS_ASN1_NULL) || + !CBB_add_asn1(&spki, &key_bitstring, CBS_ASN1_BITSTRING) || + !CBB_add_u8(&key_bitstring, 0 /* padding */) || + !RSA_marshal_public_key(&key_bitstring, key->pkey.rsa) || + !CBB_flush(out)) { + OPENSSL_PUT_ERROR(EVP, EVP_R_ENCODE_ERROR); + return 0; + } + + return 1; +} + +static int rsa_pub_decode(EVP_PKEY *out, CBS *params, CBS *key) { + // See RFC 3279, section 2.3.1. + + // The parameters must be NULL. + CBS null; + if (!CBS_get_asn1(params, &null, CBS_ASN1_NULL) || + CBS_len(&null) != 0 || + CBS_len(params) != 0) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + return 0; + } + + RSA *rsa = RSA_parse_public_key(key); + if (rsa == NULL || CBS_len(key) != 0) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + RSA_free(rsa); + return 0; + } + + EVP_PKEY_assign_RSA(out, rsa); + return 1; +} + +static int rsa_pub_cmp(const EVP_PKEY *a, const EVP_PKEY *b) { + return BN_cmp(b->pkey.rsa->n, a->pkey.rsa->n) == 0 && + BN_cmp(b->pkey.rsa->e, a->pkey.rsa->e) == 0; +} + +static int rsa_priv_encode(CBB *out, const EVP_PKEY *key) { + CBB pkcs8, algorithm, oid, null, private_key; + if (!CBB_add_asn1(out, &pkcs8, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1_uint64(&pkcs8, 0 /* version */) || + !CBB_add_asn1(&pkcs8, &algorithm, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) || + !CBB_add_bytes(&oid, rsa_asn1_meth.oid, rsa_asn1_meth.oid_len) || + !CBB_add_asn1(&algorithm, &null, CBS_ASN1_NULL) || + !CBB_add_asn1(&pkcs8, &private_key, CBS_ASN1_OCTETSTRING) || + !RSA_marshal_private_key(&private_key, key->pkey.rsa) || + !CBB_flush(out)) { + OPENSSL_PUT_ERROR(EVP, EVP_R_ENCODE_ERROR); + return 0; + } + + return 1; +} + +static int rsa_priv_decode(EVP_PKEY *out, CBS *params, CBS *key) { + // Per RFC 3447, A.1, the parameters have type NULL. + CBS null; + if (!CBS_get_asn1(params, &null, CBS_ASN1_NULL) || + CBS_len(&null) != 0 || + CBS_len(params) != 0) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + return 0; + } + + RSA *rsa = RSA_parse_private_key(key); + if (rsa == NULL || CBS_len(key) != 0) { + OPENSSL_PUT_ERROR(EVP, EVP_R_DECODE_ERROR); + RSA_free(rsa); + return 0; + } + + EVP_PKEY_assign_RSA(out, rsa); + return 1; +} + +static int rsa_opaque(const EVP_PKEY *pkey) { + return RSA_is_opaque(pkey->pkey.rsa); +} + +static int int_rsa_size(const EVP_PKEY *pkey) { + return RSA_size(pkey->pkey.rsa); +} + +static int rsa_bits(const EVP_PKEY *pkey) { + return RSA_bits(pkey->pkey.rsa); +} + +static void int_rsa_free(EVP_PKEY *pkey) { RSA_free(pkey->pkey.rsa); } + +const EVP_PKEY_ASN1_METHOD rsa_asn1_meth = { + EVP_PKEY_RSA, + // 1.2.840.113549.1.1.1 + {0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01}, 9, + + rsa_pub_decode, + rsa_pub_encode, + rsa_pub_cmp, + + rsa_priv_decode, + rsa_priv_encode, + + rsa_opaque, + + int_rsa_size, + rsa_bits, + + 0,0,0, + + int_rsa_free, +}; diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/pbkdf.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/pbkdf.c new file mode 100644 index 0000000..19bcad4 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/pbkdf.c @@ -0,0 +1,146 @@ +/* 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 "../internal.h" + + +int PKCS5_PBKDF2_HMAC(const char *password, size_t password_len, + const uint8_t *salt, size_t salt_len, unsigned iterations, + const EVP_MD *digest, size_t key_len, uint8_t *out_key) { + // See RFC 8018, section 5.2. + int ret = 0; + size_t md_len = EVP_MD_size(digest); + uint32_t i = 1; + HMAC_CTX hctx; + HMAC_CTX_init(&hctx); + + if (!HMAC_Init_ex(&hctx, password, password_len, digest, NULL)) { + goto err; + } + + while (key_len > 0) { + size_t todo = md_len; + if (todo > key_len) { + todo = key_len; + } + + uint8_t i_buf[4]; + i_buf[0] = (uint8_t)((i >> 24) & 0xff); + i_buf[1] = (uint8_t)((i >> 16) & 0xff); + i_buf[2] = (uint8_t)((i >> 8) & 0xff); + i_buf[3] = (uint8_t)(i & 0xff); + + // Compute U_1. + uint8_t digest_tmp[EVP_MAX_MD_SIZE]; + if (!HMAC_Init_ex(&hctx, NULL, 0, NULL, NULL) || + !HMAC_Update(&hctx, salt, salt_len) || + !HMAC_Update(&hctx, i_buf, 4) || + !HMAC_Final(&hctx, digest_tmp, NULL)) { + goto err; + } + + OPENSSL_memcpy(out_key, digest_tmp, todo); + for (unsigned j = 1; j < iterations; j++) { + // Compute the remaining U_* values and XOR. + if (!HMAC_Init_ex(&hctx, NULL, 0, NULL, NULL) || + !HMAC_Update(&hctx, digest_tmp, md_len) || + !HMAC_Final(&hctx, digest_tmp, NULL)) { + goto err; + } + for (size_t k = 0; k < todo; k++) { + out_key[k] ^= digest_tmp[k]; + } + } + + key_len -= todo; + out_key += todo; + i++; + } + + // RFC 8018 describes iterations (c) as being a "positive integer", so a + // value of 0 is an error. + // + // Unfortunately not all consumers of PKCS5_PBKDF2_HMAC() check their return + // value, expecting it to succeed and unconditionally using |out_key|. As a + // precaution for such callsites in external code, the old behavior of + // iterations < 1 being treated as iterations == 1 is preserved, but + // additionally an error result is returned. + // + // TODO(eroman): Figure out how to remove this compatibility hack, or change + // the default to something more sensible like 2048. + if (iterations == 0) { + goto err; + } + + ret = 1; + +err: + HMAC_CTX_cleanup(&hctx); + return ret; +} + +int PKCS5_PBKDF2_HMAC_SHA1(const char *password, size_t password_len, + const uint8_t *salt, size_t salt_len, + unsigned iterations, size_t key_len, + uint8_t *out_key) { + return PKCS5_PBKDF2_HMAC(password, password_len, salt, salt_len, iterations, + EVP_sha1(), key_len, out_key); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/pbkdf.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/pbkdf.c.grpc_back new file mode 100644 index 0000000..f23a74b --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/pbkdf.c.grpc_back @@ -0,0 +1,146 @@ +/* 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 "../internal.h" + + +int PKCS5_PBKDF2_HMAC(const char *password, size_t password_len, + const uint8_t *salt, size_t salt_len, unsigned iterations, + const EVP_MD *digest, size_t key_len, uint8_t *out_key) { + // See RFC 8018, section 5.2. + int ret = 0; + size_t md_len = EVP_MD_size(digest); + uint32_t i = 1; + HMAC_CTX hctx; + HMAC_CTX_init(&hctx); + + if (!HMAC_Init_ex(&hctx, password, password_len, digest, NULL)) { + goto err; + } + + while (key_len > 0) { + size_t todo = md_len; + if (todo > key_len) { + todo = key_len; + } + + uint8_t i_buf[4]; + i_buf[0] = (uint8_t)((i >> 24) & 0xff); + i_buf[1] = (uint8_t)((i >> 16) & 0xff); + i_buf[2] = (uint8_t)((i >> 8) & 0xff); + i_buf[3] = (uint8_t)(i & 0xff); + + // Compute U_1. + uint8_t digest_tmp[EVP_MAX_MD_SIZE]; + if (!HMAC_Init_ex(&hctx, NULL, 0, NULL, NULL) || + !HMAC_Update(&hctx, salt, salt_len) || + !HMAC_Update(&hctx, i_buf, 4) || + !HMAC_Final(&hctx, digest_tmp, NULL)) { + goto err; + } + + OPENSSL_memcpy(out_key, digest_tmp, todo); + for (unsigned j = 1; j < iterations; j++) { + // Compute the remaining U_* values and XOR. + if (!HMAC_Init_ex(&hctx, NULL, 0, NULL, NULL) || + !HMAC_Update(&hctx, digest_tmp, md_len) || + !HMAC_Final(&hctx, digest_tmp, NULL)) { + goto err; + } + for (size_t k = 0; k < todo; k++) { + out_key[k] ^= digest_tmp[k]; + } + } + + key_len -= todo; + out_key += todo; + i++; + } + + // RFC 8018 describes iterations (c) as being a "positive integer", so a + // value of 0 is an error. + // + // Unfortunately not all consumers of PKCS5_PBKDF2_HMAC() check their return + // value, expecting it to succeed and unconditionally using |out_key|. As a + // precaution for such callsites in external code, the old behavior of + // iterations < 1 being treated as iterations == 1 is preserved, but + // additionally an error result is returned. + // + // TODO(eroman): Figure out how to remove this compatibility hack, or change + // the default to something more sensible like 2048. + if (iterations == 0) { + goto err; + } + + ret = 1; + +err: + HMAC_CTX_cleanup(&hctx); + return ret; +} + +int PKCS5_PBKDF2_HMAC_SHA1(const char *password, size_t password_len, + const uint8_t *salt, size_t salt_len, + unsigned iterations, size_t key_len, + uint8_t *out_key) { + return PKCS5_PBKDF2_HMAC(password, password_len, salt, salt_len, iterations, + EVP_sha1(), key_len, out_key); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/print.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/print.c new file mode 100644 index 0000000..c60a020 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/print.c @@ -0,0 +1,489 @@ +/* ==================================================================== + * 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 +#include +#include +#include + +#include "../internal.h" +#include "../fipsmodule/rsa/internal.h" + + +static int bn_print(BIO *bp, const char *number, const BIGNUM *num, + uint8_t *buf, int off) { + if (num == NULL) { + return 1; + } + + 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) <= sizeof(long)) { + const char *neg = BN_is_negative(num) ? "-" : ""; + 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, + (BN_is_negative(num)) ? " (Negative)" : "") <= 0) { + return 0; + } + int n = BN_bn2bin(num, &buf[1]); + + if (buf[1] & 0x80) { + n++; + } else { + buf++; + } + + int i; + 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; +} + +static void update_buflen(const BIGNUM *b, size_t *pbuflen) { + if (!b) { + return; + } + + size_t len = BN_num_bytes(b); + if (*pbuflen < len) { + *pbuflen = len; + } +} + +// RSA keys. + +static int do_rsa_print(BIO *out, const RSA *rsa, int off, + int include_private) { + const char *s, *str; + uint8_t *m = NULL; + int ret = 0, mod_len = 0; + size_t buf_len = 0; + + update_buflen(rsa->n, &buf_len); + update_buflen(rsa->e, &buf_len); + + if (include_private) { + update_buflen(rsa->d, &buf_len); + update_buflen(rsa->p, &buf_len); + update_buflen(rsa->q, &buf_len); + update_buflen(rsa->dmp1, &buf_len); + update_buflen(rsa->dmq1, &buf_len); + update_buflen(rsa->iqmp, &buf_len); + } + + m = (uint8_t *)OPENSSL_malloc(buf_len + 10); + if (m == NULL) { + OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (rsa->n != NULL) { + mod_len = BN_num_bits(rsa->n); + } + + if (!BIO_indent(out, off, 128)) { + goto err; + } + + if (include_private && rsa->d) { + if (BIO_printf(out, "Private-Key: (%d bit)\n", mod_len) <= 0) { + goto err; + } + str = "modulus:"; + s = "publicExponent:"; + } else { + if (BIO_printf(out, "Public-Key: (%d bit)\n", mod_len) <= 0) { + goto err; + } + str = "Modulus:"; + s = "Exponent:"; + } + if (!bn_print(out, str, rsa->n, m, off) || + !bn_print(out, s, rsa->e, m, off)) { + goto err; + } + + if (include_private) { + if (!bn_print(out, "privateExponent:", rsa->d, m, off) || + !bn_print(out, "prime1:", rsa->p, m, off) || + !bn_print(out, "prime2:", rsa->q, m, off) || + !bn_print(out, "exponent1:", rsa->dmp1, m, off) || + !bn_print(out, "exponent2:", rsa->dmq1, m, off) || + !bn_print(out, "coefficient:", rsa->iqmp, m, off)) { + goto err; + } + } + ret = 1; + +err: + 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); +} + + +// DSA keys. + +static int do_dsa_print(BIO *bp, const DSA *x, int off, int ptype) { + uint8_t *m = NULL; + int ret = 0; + size_t buf_len = 0; + const char *ktype = NULL; + + const BIGNUM *priv_key, *pub_key; + + priv_key = NULL; + if (ptype == 2) { + priv_key = x->priv_key; + } + + pub_key = NULL; + if (ptype > 0) { + pub_key = x->pub_key; + } + + ktype = "DSA-Parameters"; + if (ptype == 2) { + ktype = "Private-Key"; + } else if (ptype == 1) { + ktype = "Public-Key"; + } + + 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 = (uint8_t *)OPENSSL_malloc(buf_len + 10); + if (m == NULL) { + OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (priv_key) { + if (!BIO_indent(bp, off, 128) || + BIO_printf(bp, "%s: (%d bit)\n", ktype, BN_num_bits(x->p)) <= 0) { + goto err; + } + } + + if (!bn_print(bp, "priv:", priv_key, m, off) || + !bn_print(bp, "pub: ", pub_key, m, off) || + !bn_print(bp, "P: ", x->p, m, off) || + !bn_print(bp, "Q: ", x->q, m, off) || + !bn_print(bp, "G: ", x->g, m, off)) { + goto err; + } + ret = 1; + +err: + OPENSSL_free(m); + return ret; +} + +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); +} + + +// EC keys. + +static int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, int ktype) { + uint8_t *buffer = NULL; + const char *ecstr; + size_t buf_len = 0, i; + int ret = 0, reason = ERR_R_BIO_LIB; + BIGNUM *order = NULL; + BN_CTX *ctx = NULL; + const EC_GROUP *group; + const EC_POINT *public_key; + const BIGNUM *priv_key; + uint8_t *pub_key_bytes = NULL; + size_t pub_key_bytes_len = 0; + + 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) { + pub_key_bytes_len = EC_POINT_point2oct( + group, public_key, EC_KEY_get_conv_form(x), NULL, 0, ctx); + if (pub_key_bytes_len == 0) { + reason = ERR_R_MALLOC_FAILURE; + goto err; + } + pub_key_bytes = OPENSSL_malloc(pub_key_bytes_len); + if (pub_key_bytes == NULL) { + reason = ERR_R_MALLOC_FAILURE; + goto err; + } + pub_key_bytes_len = + EC_POINT_point2oct(group, public_key, EC_KEY_get_conv_form(x), + pub_key_bytes, pub_key_bytes_len, ctx); + if (pub_key_bytes_len == 0) { + reason = ERR_R_MALLOC_FAILURE; + goto err; + } + buf_len = pub_key_bytes_len; + } + } + + 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; + } + order = BN_new(); + if (order == NULL || !EC_GROUP_get_order(group, order, NULL) || + BIO_printf(bp, "%s: (%d bit)\n", ecstr, BN_num_bits(order)) <= 0) { + goto err; + } + + if ((priv_key != NULL) && + !bn_print(bp, "priv:", priv_key, buffer, off)) { + goto err; + } + if (pub_key_bytes != NULL) { + BIO_hexdump(bp, pub_key_bytes, pub_key_bytes_len, off); + } + // TODO(fork): implement + /* + if (!ECPKParameters_print(bp, group, off)) + goto err; */ + ret = 1; + +err: + if (!ret) { + OPENSSL_PUT_ERROR(EVP, reason); + } + OPENSSL_free(pub_key_bytes); + BN_free(order); + BN_CTX_free(ctx); + OPENSSL_free(buffer); + return ret; +} + +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); +} + + +typedef struct { + int type; + int (*pub_print)(BIO *out, const EVP_PKEY *pkey, int indent, ASN1_PCTX *pctx); + int (*priv_print)(BIO *out, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *pctx); + int (*param_print)(BIO *out, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *pctx); +} EVP_PKEY_PRINT_METHOD; + +static EVP_PKEY_PRINT_METHOD kPrintMethods[] = { + { + EVP_PKEY_RSA, + rsa_pub_print, + rsa_priv_print, + NULL /* param_print */, + }, + { + EVP_PKEY_DSA, + dsa_pub_print, + dsa_priv_print, + dsa_param_print, + }, + { + EVP_PKEY_EC, + eckey_pub_print, + eckey_priv_print, + eckey_param_print, + }, +}; + +static size_t kPrintMethodsLen = OPENSSL_ARRAY_SIZE(kPrintMethods); + +static EVP_PKEY_PRINT_METHOD *find_method(int type) { + for (size_t i = 0; i < kPrintMethodsLen; i++) { + if (kPrintMethods[i].type == type) { + return &kPrintMethods[i]; + } + } + return NULL; +} + +static int print_unsupported(BIO *out, const EVP_PKEY *pkey, int indent, + const char *kstr) { + BIO_indent(out, indent, 128); + BIO_printf(out, "%s algorithm unsupported\n", kstr); + return 1; +} + +int EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *pctx) { + EVP_PKEY_PRINT_METHOD *method = find_method(pkey->type); + if (method != NULL && method->pub_print != NULL) { + return method->pub_print(out, pkey, indent, pctx); + } + return print_unsupported(out, pkey, indent, "Public Key"); +} + +int EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *pctx) { + EVP_PKEY_PRINT_METHOD *method = find_method(pkey->type); + if (method != NULL && method->priv_print != NULL) { + return method->priv_print(out, pkey, indent, pctx); + } + return print_unsupported(out, pkey, indent, "Private Key"); +} + +int EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *pctx) { + EVP_PKEY_PRINT_METHOD *method = find_method(pkey->type); + if (method != NULL && method->param_print != NULL) { + return method->param_print(out, pkey, indent, pctx); + } + return print_unsupported(out, pkey, indent, "Parameters"); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/print.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/print.c.grpc_back new file mode 100644 index 0000000..3621d5f --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/print.c.grpc_back @@ -0,0 +1,489 @@ +/* ==================================================================== + * 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 +#include +#include +#include + +#include "../internal.h" +#include "../fipsmodule/rsa/internal.h" + + +static int bn_print(BIO *bp, const char *number, const BIGNUM *num, + uint8_t *buf, int off) { + if (num == NULL) { + return 1; + } + + 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) <= sizeof(long)) { + const char *neg = BN_is_negative(num) ? "-" : ""; + 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, + (BN_is_negative(num)) ? " (Negative)" : "") <= 0) { + return 0; + } + int n = BN_bn2bin(num, &buf[1]); + + if (buf[1] & 0x80) { + n++; + } else { + buf++; + } + + int i; + 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; +} + +static void update_buflen(const BIGNUM *b, size_t *pbuflen) { + if (!b) { + return; + } + + size_t len = BN_num_bytes(b); + if (*pbuflen < len) { + *pbuflen = len; + } +} + +// RSA keys. + +static int do_rsa_print(BIO *out, const RSA *rsa, int off, + int include_private) { + const char *s, *str; + uint8_t *m = NULL; + int ret = 0, mod_len = 0; + size_t buf_len = 0; + + update_buflen(rsa->n, &buf_len); + update_buflen(rsa->e, &buf_len); + + if (include_private) { + update_buflen(rsa->d, &buf_len); + update_buflen(rsa->p, &buf_len); + update_buflen(rsa->q, &buf_len); + update_buflen(rsa->dmp1, &buf_len); + update_buflen(rsa->dmq1, &buf_len); + update_buflen(rsa->iqmp, &buf_len); + } + + m = (uint8_t *)OPENSSL_malloc(buf_len + 10); + if (m == NULL) { + OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (rsa->n != NULL) { + mod_len = BN_num_bits(rsa->n); + } + + if (!BIO_indent(out, off, 128)) { + goto err; + } + + if (include_private && rsa->d) { + if (BIO_printf(out, "Private-Key: (%d bit)\n", mod_len) <= 0) { + goto err; + } + str = "modulus:"; + s = "publicExponent:"; + } else { + if (BIO_printf(out, "Public-Key: (%d bit)\n", mod_len) <= 0) { + goto err; + } + str = "Modulus:"; + s = "Exponent:"; + } + if (!bn_print(out, str, rsa->n, m, off) || + !bn_print(out, s, rsa->e, m, off)) { + goto err; + } + + if (include_private) { + if (!bn_print(out, "privateExponent:", rsa->d, m, off) || + !bn_print(out, "prime1:", rsa->p, m, off) || + !bn_print(out, "prime2:", rsa->q, m, off) || + !bn_print(out, "exponent1:", rsa->dmp1, m, off) || + !bn_print(out, "exponent2:", rsa->dmq1, m, off) || + !bn_print(out, "coefficient:", rsa->iqmp, m, off)) { + goto err; + } + } + ret = 1; + +err: + 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); +} + + +// DSA keys. + +static int do_dsa_print(BIO *bp, const DSA *x, int off, int ptype) { + uint8_t *m = NULL; + int ret = 0; + size_t buf_len = 0; + const char *ktype = NULL; + + const BIGNUM *priv_key, *pub_key; + + priv_key = NULL; + if (ptype == 2) { + priv_key = x->priv_key; + } + + pub_key = NULL; + if (ptype > 0) { + pub_key = x->pub_key; + } + + ktype = "DSA-Parameters"; + if (ptype == 2) { + ktype = "Private-Key"; + } else if (ptype == 1) { + ktype = "Public-Key"; + } + + 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 = (uint8_t *)OPENSSL_malloc(buf_len + 10); + if (m == NULL) { + OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (priv_key) { + if (!BIO_indent(bp, off, 128) || + BIO_printf(bp, "%s: (%d bit)\n", ktype, BN_num_bits(x->p)) <= 0) { + goto err; + } + } + + if (!bn_print(bp, "priv:", priv_key, m, off) || + !bn_print(bp, "pub: ", pub_key, m, off) || + !bn_print(bp, "P: ", x->p, m, off) || + !bn_print(bp, "Q: ", x->q, m, off) || + !bn_print(bp, "G: ", x->g, m, off)) { + goto err; + } + ret = 1; + +err: + OPENSSL_free(m); + return ret; +} + +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); +} + + +// EC keys. + +static int do_EC_KEY_print(BIO *bp, const EC_KEY *x, int off, int ktype) { + uint8_t *buffer = NULL; + const char *ecstr; + size_t buf_len = 0, i; + int ret = 0, reason = ERR_R_BIO_LIB; + BIGNUM *order = NULL; + BN_CTX *ctx = NULL; + const EC_GROUP *group; + const EC_POINT *public_key; + const BIGNUM *priv_key; + uint8_t *pub_key_bytes = NULL; + size_t pub_key_bytes_len = 0; + + 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) { + pub_key_bytes_len = EC_POINT_point2oct( + group, public_key, EC_KEY_get_conv_form(x), NULL, 0, ctx); + if (pub_key_bytes_len == 0) { + reason = ERR_R_MALLOC_FAILURE; + goto err; + } + pub_key_bytes = OPENSSL_malloc(pub_key_bytes_len); + if (pub_key_bytes == NULL) { + reason = ERR_R_MALLOC_FAILURE; + goto err; + } + pub_key_bytes_len = + EC_POINT_point2oct(group, public_key, EC_KEY_get_conv_form(x), + pub_key_bytes, pub_key_bytes_len, ctx); + if (pub_key_bytes_len == 0) { + reason = ERR_R_MALLOC_FAILURE; + goto err; + } + buf_len = pub_key_bytes_len; + } + } + + 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; + } + order = BN_new(); + if (order == NULL || !EC_GROUP_get_order(group, order, NULL) || + BIO_printf(bp, "%s: (%d bit)\n", ecstr, BN_num_bits(order)) <= 0) { + goto err; + } + + if ((priv_key != NULL) && + !bn_print(bp, "priv:", priv_key, buffer, off)) { + goto err; + } + if (pub_key_bytes != NULL) { + BIO_hexdump(bp, pub_key_bytes, pub_key_bytes_len, off); + } + // TODO(fork): implement + /* + if (!ECPKParameters_print(bp, group, off)) + goto err; */ + ret = 1; + +err: + if (!ret) { + OPENSSL_PUT_ERROR(EVP, reason); + } + OPENSSL_free(pub_key_bytes); + BN_free(order); + BN_CTX_free(ctx); + OPENSSL_free(buffer); + return ret; +} + +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); +} + + +typedef struct { + int type; + int (*pub_print)(BIO *out, const EVP_PKEY *pkey, int indent, ASN1_PCTX *pctx); + int (*priv_print)(BIO *out, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *pctx); + int (*param_print)(BIO *out, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *pctx); +} EVP_PKEY_PRINT_METHOD; + +static EVP_PKEY_PRINT_METHOD kPrintMethods[] = { + { + EVP_PKEY_RSA, + rsa_pub_print, + rsa_priv_print, + NULL /* param_print */, + }, + { + EVP_PKEY_DSA, + dsa_pub_print, + dsa_priv_print, + dsa_param_print, + }, + { + EVP_PKEY_EC, + eckey_pub_print, + eckey_priv_print, + eckey_param_print, + }, +}; + +static size_t kPrintMethodsLen = OPENSSL_ARRAY_SIZE(kPrintMethods); + +static EVP_PKEY_PRINT_METHOD *find_method(int type) { + for (size_t i = 0; i < kPrintMethodsLen; i++) { + if (kPrintMethods[i].type == type) { + return &kPrintMethods[i]; + } + } + return NULL; +} + +static int print_unsupported(BIO *out, const EVP_PKEY *pkey, int indent, + const char *kstr) { + BIO_indent(out, indent, 128); + BIO_printf(out, "%s algorithm unsupported\n", kstr); + return 1; +} + +int EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *pctx) { + EVP_PKEY_PRINT_METHOD *method = find_method(pkey->type); + if (method != NULL && method->pub_print != NULL) { + return method->pub_print(out, pkey, indent, pctx); + } + return print_unsupported(out, pkey, indent, "Public Key"); +} + +int EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *pctx) { + EVP_PKEY_PRINT_METHOD *method = find_method(pkey->type); + if (method != NULL && method->priv_print != NULL) { + return method->priv_print(out, pkey, indent, pctx); + } + return print_unsupported(out, pkey, indent, "Private Key"); +} + +int EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey, int indent, + ASN1_PCTX *pctx) { + EVP_PKEY_PRINT_METHOD *method = find_method(pkey->type); + if (method != NULL && method->param_print != NULL) { + return method->param_print(out, pkey, indent, pctx); + } + return print_unsupported(out, pkey, indent, "Parameters"); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/scrypt.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/scrypt.c new file mode 100644 index 0000000..7b50200 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/scrypt.c @@ -0,0 +1,209 @@ +/* + * Copyright 2015-2016 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 + */ + +#include + +#include + +#include +#include +#include + +#include "../internal.h" + + +// This file implements scrypt, described in RFC 7914. +// +// Note scrypt refers to both "blocks" and a "block size" parameter, r. These +// are two different notions of blocks. A Salsa20 block is 64 bytes long, +// represented in this implementation by 16 |uint32_t|s. |r| determines the +// number of 64-byte Salsa20 blocks in a scryptBlockMix block, which is 2 * |r| +// Salsa20 blocks. This implementation refers to them as Salsa20 blocks and +// scrypt blocks, respectively. + +// A block_t is a Salsa20 block. +typedef struct { uint32_t words[16]; } block_t; + +OPENSSL_COMPILE_ASSERT(sizeof(block_t) == 64, block_t_has_padding); + +#define R(a, b) (((a) << (b)) | ((a) >> (32 - (b)))) + +// salsa208_word_specification implements the Salsa20/8 core function, also +// described in RFC 7914, section 3. It modifies the block at |inout| +// in-place. +static void salsa208_word_specification(block_t *inout) { + block_t x; + OPENSSL_memcpy(&x, inout, sizeof(x)); + + for (int i = 8; i > 0; i -= 2) { + x.words[4] ^= R(x.words[0] + x.words[12], 7); + x.words[8] ^= R(x.words[4] + x.words[0], 9); + x.words[12] ^= R(x.words[8] + x.words[4], 13); + x.words[0] ^= R(x.words[12] + x.words[8], 18); + x.words[9] ^= R(x.words[5] + x.words[1], 7); + x.words[13] ^= R(x.words[9] + x.words[5], 9); + x.words[1] ^= R(x.words[13] + x.words[9], 13); + x.words[5] ^= R(x.words[1] + x.words[13], 18); + x.words[14] ^= R(x.words[10] + x.words[6], 7); + x.words[2] ^= R(x.words[14] + x.words[10], 9); + x.words[6] ^= R(x.words[2] + x.words[14], 13); + x.words[10] ^= R(x.words[6] + x.words[2], 18); + x.words[3] ^= R(x.words[15] + x.words[11], 7); + x.words[7] ^= R(x.words[3] + x.words[15], 9); + x.words[11] ^= R(x.words[7] + x.words[3], 13); + x.words[15] ^= R(x.words[11] + x.words[7], 18); + x.words[1] ^= R(x.words[0] + x.words[3], 7); + x.words[2] ^= R(x.words[1] + x.words[0], 9); + x.words[3] ^= R(x.words[2] + x.words[1], 13); + x.words[0] ^= R(x.words[3] + x.words[2], 18); + x.words[6] ^= R(x.words[5] + x.words[4], 7); + x.words[7] ^= R(x.words[6] + x.words[5], 9); + x.words[4] ^= R(x.words[7] + x.words[6], 13); + x.words[5] ^= R(x.words[4] + x.words[7], 18); + x.words[11] ^= R(x.words[10] + x.words[9], 7); + x.words[8] ^= R(x.words[11] + x.words[10], 9); + x.words[9] ^= R(x.words[8] + x.words[11], 13); + x.words[10] ^= R(x.words[9] + x.words[8], 18); + x.words[12] ^= R(x.words[15] + x.words[14], 7); + x.words[13] ^= R(x.words[12] + x.words[15], 9); + x.words[14] ^= R(x.words[13] + x.words[12], 13); + x.words[15] ^= R(x.words[14] + x.words[13], 18); + } + + for (int i = 0; i < 16; ++i) { + inout->words[i] += x.words[i]; + } +} + +// xor_block sets |*out| to be |*a| XOR |*b|. +static void xor_block(block_t *out, const block_t *a, const block_t *b) { + for (size_t i = 0; i < 16; i++) { + out->words[i] = a->words[i] ^ b->words[i]; + } +} + +// scryptBlockMix implements the function described in RFC 7914, section 4. B' +// is written to |out|. |out| and |B| may not alias and must be each one scrypt +// block (2 * |r| Salsa20 blocks) long. +static void scryptBlockMix(block_t *out, const block_t *B, uint64_t r) { + assert(out != B); + + block_t X; + OPENSSL_memcpy(&X, &B[r * 2 - 1], sizeof(X)); + for (uint64_t i = 0; i < r * 2; i++) { + xor_block(&X, &X, &B[i]); + salsa208_word_specification(&X); + + // This implements the permutation in step 3. + OPENSSL_memcpy(&out[i / 2 + (i & 1) * r], &X, sizeof(X)); + } +} + +// scryptROMix implements the function described in RFC 7914, section 5. |B| is +// an scrypt block (2 * |r| Salsa20 blocks) and is modified in-place. |T| and +// |V| are scratch space allocated by the caller. |T| must have space for one +// scrypt block (2 * |r| Salsa20 blocks). |V| must have space for |N| scrypt +// blocks (2 * |r| * |N| Salsa20 blocks). +static void scryptROMix(block_t *B, uint64_t r, uint64_t N, block_t *T, + block_t *V) { + // Steps 1 and 2. + OPENSSL_memcpy(V, B, 2 * r * sizeof(block_t)); + for (uint64_t i = 1; i < N; i++) { + scryptBlockMix(&V[2 * r * i /* scrypt block i */], + &V[2 * r * (i - 1) /* scrypt block i-1 */], r); + } + scryptBlockMix(B, &V[2 * r * (N - 1) /* scrypt block N-1 */], r); + + // Step 3. + for (uint64_t i = 0; i < N; i++) { + // Note this assumes |N| <= 2^32 and is a power of 2. + uint32_t j = B[2 * r - 1].words[0] & (N - 1); + for (size_t k = 0; k < 2 * r; k++) { + xor_block(&T[k], &B[k], &V[2 * r * j + k]); + } + scryptBlockMix(B, T, r); + } +} + +// SCRYPT_PR_MAX is the maximum value of p * r. This is equivalent to the +// bounds on p in section 6: +// +// p <= ((2^32-1) * hLen) / MFLen iff +// p <= ((2^32-1) * 32) / (128 * r) iff +// p * r <= (2^30-1) +#define SCRYPT_PR_MAX ((1 << 30) - 1) + +// SCRYPT_MAX_MEM is the default maximum memory that may be allocated by +// |EVP_PBE_scrypt|. +#define SCRYPT_MAX_MEM (1024 * 1024 * 32) + +int EVP_PBE_scrypt(const char *password, size_t password_len, + const uint8_t *salt, size_t salt_len, uint64_t N, uint64_t r, + uint64_t p, size_t max_mem, uint8_t *out_key, + size_t key_len) { + if (r == 0 || p == 0 || p > SCRYPT_PR_MAX / r || + // |N| must be a power of two. + N < 2 || (N & (N - 1)) || + // We only support |N| <= 2^32 in |scryptROMix|. + N > UINT64_C(1) << 32 || + // Check that |N| < 2^(128×r / 8). + (16 * r <= 63 && N >= UINT64_C(1) << (16 * r))) { + OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_PARAMETERS); + return 0; + } + + // Determine the amount of memory needed. B, T, and V are |p|, 1, and |N| + // scrypt blocks, respectively. Each scrypt block is 2*|r| |block_t|s. + if (max_mem == 0) { + max_mem = SCRYPT_MAX_MEM; + } + + size_t max_scrypt_blocks = max_mem / (2 * r * sizeof(block_t)); + if (max_scrypt_blocks < p + 1 || + max_scrypt_blocks - p - 1 < N) { + OPENSSL_PUT_ERROR(EVP, EVP_R_MEMORY_LIMIT_EXCEEDED); + return 0; + } + + // Allocate and divide up the scratch space. |max_mem| fits in a size_t, which + // is no bigger than uint64_t, so none of these operations may overflow. + OPENSSL_COMPILE_ASSERT(UINT64_MAX >= ((size_t)-1), size_t_exceeds_u64); + size_t B_blocks = p * 2 * r; + size_t B_bytes = B_blocks * sizeof(block_t); + size_t T_blocks = 2 * r; + size_t V_blocks = N * 2 * r; + block_t *B = OPENSSL_malloc((B_blocks + T_blocks + V_blocks) * sizeof(block_t)); + if (B == NULL) { + OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); + return 0; + } + + int ret = 0; + block_t *T = B + B_blocks; + block_t *V = T + T_blocks; + if (!PKCS5_PBKDF2_HMAC(password, password_len, salt, salt_len, 1, + EVP_sha256(), B_bytes, (uint8_t *)B)) { + goto err; + } + + for (uint64_t i = 0; i < p; i++) { + scryptROMix(B + 2 * r * i, r, N, T, V); + } + + if (!PKCS5_PBKDF2_HMAC(password, password_len, (const uint8_t *)B, B_bytes, 1, + EVP_sha256(), key_len, out_key)) { + goto err; + } + + ret = 1; + +err: + OPENSSL_free(B); + return ret; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/scrypt.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/scrypt.c.grpc_back new file mode 100644 index 0000000..ed186ee --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/scrypt.c.grpc_back @@ -0,0 +1,209 @@ +/* + * Copyright 2015-2016 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 + */ + +#include + +#include + +#include +#include +#include + +#include "../internal.h" + + +// This file implements scrypt, described in RFC 7914. +// +// Note scrypt refers to both "blocks" and a "block size" parameter, r. These +// are two different notions of blocks. A Salsa20 block is 64 bytes long, +// represented in this implementation by 16 |uint32_t|s. |r| determines the +// number of 64-byte Salsa20 blocks in a scryptBlockMix block, which is 2 * |r| +// Salsa20 blocks. This implementation refers to them as Salsa20 blocks and +// scrypt blocks, respectively. + +// A block_t is a Salsa20 block. +typedef struct { uint32_t words[16]; } block_t; + +OPENSSL_COMPILE_ASSERT(sizeof(block_t) == 64, block_t_has_padding); + +#define R(a, b) (((a) << (b)) | ((a) >> (32 - (b)))) + +// salsa208_word_specification implements the Salsa20/8 core function, also +// described in RFC 7914, section 3. It modifies the block at |inout| +// in-place. +static void salsa208_word_specification(block_t *inout) { + block_t x; + OPENSSL_memcpy(&x, inout, sizeof(x)); + + for (int i = 8; i > 0; i -= 2) { + x.words[4] ^= R(x.words[0] + x.words[12], 7); + x.words[8] ^= R(x.words[4] + x.words[0], 9); + x.words[12] ^= R(x.words[8] + x.words[4], 13); + x.words[0] ^= R(x.words[12] + x.words[8], 18); + x.words[9] ^= R(x.words[5] + x.words[1], 7); + x.words[13] ^= R(x.words[9] + x.words[5], 9); + x.words[1] ^= R(x.words[13] + x.words[9], 13); + x.words[5] ^= R(x.words[1] + x.words[13], 18); + x.words[14] ^= R(x.words[10] + x.words[6], 7); + x.words[2] ^= R(x.words[14] + x.words[10], 9); + x.words[6] ^= R(x.words[2] + x.words[14], 13); + x.words[10] ^= R(x.words[6] + x.words[2], 18); + x.words[3] ^= R(x.words[15] + x.words[11], 7); + x.words[7] ^= R(x.words[3] + x.words[15], 9); + x.words[11] ^= R(x.words[7] + x.words[3], 13); + x.words[15] ^= R(x.words[11] + x.words[7], 18); + x.words[1] ^= R(x.words[0] + x.words[3], 7); + x.words[2] ^= R(x.words[1] + x.words[0], 9); + x.words[3] ^= R(x.words[2] + x.words[1], 13); + x.words[0] ^= R(x.words[3] + x.words[2], 18); + x.words[6] ^= R(x.words[5] + x.words[4], 7); + x.words[7] ^= R(x.words[6] + x.words[5], 9); + x.words[4] ^= R(x.words[7] + x.words[6], 13); + x.words[5] ^= R(x.words[4] + x.words[7], 18); + x.words[11] ^= R(x.words[10] + x.words[9], 7); + x.words[8] ^= R(x.words[11] + x.words[10], 9); + x.words[9] ^= R(x.words[8] + x.words[11], 13); + x.words[10] ^= R(x.words[9] + x.words[8], 18); + x.words[12] ^= R(x.words[15] + x.words[14], 7); + x.words[13] ^= R(x.words[12] + x.words[15], 9); + x.words[14] ^= R(x.words[13] + x.words[12], 13); + x.words[15] ^= R(x.words[14] + x.words[13], 18); + } + + for (int i = 0; i < 16; ++i) { + inout->words[i] += x.words[i]; + } +} + +// xor_block sets |*out| to be |*a| XOR |*b|. +static void xor_block(block_t *out, const block_t *a, const block_t *b) { + for (size_t i = 0; i < 16; i++) { + out->words[i] = a->words[i] ^ b->words[i]; + } +} + +// scryptBlockMix implements the function described in RFC 7914, section 4. B' +// is written to |out|. |out| and |B| may not alias and must be each one scrypt +// block (2 * |r| Salsa20 blocks) long. +static void scryptBlockMix(block_t *out, const block_t *B, uint64_t r) { + assert(out != B); + + block_t X; + OPENSSL_memcpy(&X, &B[r * 2 - 1], sizeof(X)); + for (uint64_t i = 0; i < r * 2; i++) { + xor_block(&X, &X, &B[i]); + salsa208_word_specification(&X); + + // This implements the permutation in step 3. + OPENSSL_memcpy(&out[i / 2 + (i & 1) * r], &X, sizeof(X)); + } +} + +// scryptROMix implements the function described in RFC 7914, section 5. |B| is +// an scrypt block (2 * |r| Salsa20 blocks) and is modified in-place. |T| and +// |V| are scratch space allocated by the caller. |T| must have space for one +// scrypt block (2 * |r| Salsa20 blocks). |V| must have space for |N| scrypt +// blocks (2 * |r| * |N| Salsa20 blocks). +static void scryptROMix(block_t *B, uint64_t r, uint64_t N, block_t *T, + block_t *V) { + // Steps 1 and 2. + OPENSSL_memcpy(V, B, 2 * r * sizeof(block_t)); + for (uint64_t i = 1; i < N; i++) { + scryptBlockMix(&V[2 * r * i /* scrypt block i */], + &V[2 * r * (i - 1) /* scrypt block i-1 */], r); + } + scryptBlockMix(B, &V[2 * r * (N - 1) /* scrypt block N-1 */], r); + + // Step 3. + for (uint64_t i = 0; i < N; i++) { + // Note this assumes |N| <= 2^32 and is a power of 2. + uint32_t j = B[2 * r - 1].words[0] & (N - 1); + for (size_t k = 0; k < 2 * r; k++) { + xor_block(&T[k], &B[k], &V[2 * r * j + k]); + } + scryptBlockMix(B, T, r); + } +} + +// SCRYPT_PR_MAX is the maximum value of p * r. This is equivalent to the +// bounds on p in section 6: +// +// p <= ((2^32-1) * hLen) / MFLen iff +// p <= ((2^32-1) * 32) / (128 * r) iff +// p * r <= (2^30-1) +#define SCRYPT_PR_MAX ((1 << 30) - 1) + +// SCRYPT_MAX_MEM is the default maximum memory that may be allocated by +// |EVP_PBE_scrypt|. +#define SCRYPT_MAX_MEM (1024 * 1024 * 32) + +int EVP_PBE_scrypt(const char *password, size_t password_len, + const uint8_t *salt, size_t salt_len, uint64_t N, uint64_t r, + uint64_t p, size_t max_mem, uint8_t *out_key, + size_t key_len) { + if (r == 0 || p == 0 || p > SCRYPT_PR_MAX / r || + // |N| must be a power of two. + N < 2 || (N & (N - 1)) || + // We only support |N| <= 2^32 in |scryptROMix|. + N > UINT64_C(1) << 32 || + // Check that |N| < 2^(128×r / 8). + (16 * r <= 63 && N >= UINT64_C(1) << (16 * r))) { + OPENSSL_PUT_ERROR(EVP, EVP_R_INVALID_PARAMETERS); + return 0; + } + + // Determine the amount of memory needed. B, T, and V are |p|, 1, and |N| + // scrypt blocks, respectively. Each scrypt block is 2*|r| |block_t|s. + if (max_mem == 0) { + max_mem = SCRYPT_MAX_MEM; + } + + size_t max_scrypt_blocks = max_mem / (2 * r * sizeof(block_t)); + if (max_scrypt_blocks < p + 1 || + max_scrypt_blocks - p - 1 < N) { + OPENSSL_PUT_ERROR(EVP, EVP_R_MEMORY_LIMIT_EXCEEDED); + return 0; + } + + // Allocate and divide up the scratch space. |max_mem| fits in a size_t, which + // is no bigger than uint64_t, so none of these operations may overflow. + OPENSSL_COMPILE_ASSERT(UINT64_MAX >= ((size_t)-1), size_t_exceeds_u64); + size_t B_blocks = p * 2 * r; + size_t B_bytes = B_blocks * sizeof(block_t); + size_t T_blocks = 2 * r; + size_t V_blocks = N * 2 * r; + block_t *B = OPENSSL_malloc((B_blocks + T_blocks + V_blocks) * sizeof(block_t)); + if (B == NULL) { + OPENSSL_PUT_ERROR(EVP, ERR_R_MALLOC_FAILURE); + return 0; + } + + int ret = 0; + block_t *T = B + B_blocks; + block_t *V = T + T_blocks; + if (!PKCS5_PBKDF2_HMAC(password, password_len, salt, salt_len, 1, + EVP_sha256(), B_bytes, (uint8_t *)B)) { + goto err; + } + + for (uint64_t i = 0; i < p; i++) { + scryptROMix(B + 2 * r * i, r, N, T, V); + } + + if (!PKCS5_PBKDF2_HMAC(password, password_len, (const uint8_t *)B, B_bytes, 1, + EVP_sha256(), key_len, out_key)) { + goto err; + } + + ret = 1; + +err: + OPENSSL_free(B); + return ret; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/sign.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/sign.c new file mode 100644 index 0000000..046b50c --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/sign.c @@ -0,0 +1,151 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 "internal.h" + + +int EVP_SignInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl) { + return EVP_DigestInit_ex(ctx, type, impl); +} + +int EVP_SignInit(EVP_MD_CTX *ctx, const EVP_MD *type) { + return EVP_DigestInit(ctx, type); +} + +int EVP_SignUpdate(EVP_MD_CTX *ctx, const void *data, size_t len) { + return EVP_DigestUpdate(ctx, data, len); +} + +int EVP_SignFinal(const EVP_MD_CTX *ctx, uint8_t *sig, + unsigned int *out_sig_len, EVP_PKEY *pkey) { + uint8_t m[EVP_MAX_MD_SIZE]; + unsigned int m_len; + int ret = 0; + EVP_MD_CTX tmp_ctx; + EVP_PKEY_CTX *pkctx = NULL; + size_t sig_len = EVP_PKEY_size(pkey); + + *out_sig_len = 0; + EVP_MD_CTX_init(&tmp_ctx); + if (!EVP_MD_CTX_copy_ex(&tmp_ctx, ctx) || + !EVP_DigestFinal_ex(&tmp_ctx, m, &m_len)) { + goto out; + } + EVP_MD_CTX_cleanup(&tmp_ctx); + + pkctx = EVP_PKEY_CTX_new(pkey, NULL); + if (!pkctx || !EVP_PKEY_sign_init(pkctx) || + !EVP_PKEY_CTX_set_signature_md(pkctx, ctx->digest) || + !EVP_PKEY_sign(pkctx, sig, &sig_len, m, m_len)) { + goto out; + } + *out_sig_len = sig_len; + ret = 1; + +out: + if (pkctx) { + EVP_PKEY_CTX_free(pkctx); + } + + return ret; +} + +int EVP_VerifyInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl) { + return EVP_DigestInit_ex(ctx, type, impl); +} + +int EVP_VerifyInit(EVP_MD_CTX *ctx, const EVP_MD *type) { + return EVP_DigestInit(ctx, type); +} + +int EVP_VerifyUpdate(EVP_MD_CTX *ctx, const void *data, size_t len) { + return EVP_DigestUpdate(ctx, data, len); +} + +int EVP_VerifyFinal(EVP_MD_CTX *ctx, const uint8_t *sig, size_t sig_len, + EVP_PKEY *pkey) { + uint8_t m[EVP_MAX_MD_SIZE]; + unsigned int m_len; + int ret = 0; + 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) || + !EVP_DigestFinal_ex(&tmp_ctx, m, &m_len)) { + EVP_MD_CTX_cleanup(&tmp_ctx); + goto out; + } + EVP_MD_CTX_cleanup(&tmp_ctx); + + pkctx = EVP_PKEY_CTX_new(pkey, NULL); + if (!pkctx || + !EVP_PKEY_verify_init(pkctx) || + !EVP_PKEY_CTX_set_signature_md(pkctx, ctx->digest)) { + goto out; + } + ret = EVP_PKEY_verify(pkctx, sig, sig_len, m, m_len); + +out: + EVP_PKEY_CTX_free(pkctx); + return ret; +} + diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/sign.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/sign.c.grpc_back new file mode 100644 index 0000000..ced86bd --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/evp/sign.c.grpc_back @@ -0,0 +1,151 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 "internal.h" + + +int EVP_SignInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl) { + return EVP_DigestInit_ex(ctx, type, impl); +} + +int EVP_SignInit(EVP_MD_CTX *ctx, const EVP_MD *type) { + return EVP_DigestInit(ctx, type); +} + +int EVP_SignUpdate(EVP_MD_CTX *ctx, const void *data, size_t len) { + return EVP_DigestUpdate(ctx, data, len); +} + +int EVP_SignFinal(const EVP_MD_CTX *ctx, uint8_t *sig, + unsigned int *out_sig_len, EVP_PKEY *pkey) { + uint8_t m[EVP_MAX_MD_SIZE]; + unsigned int m_len; + int ret = 0; + EVP_MD_CTX tmp_ctx; + EVP_PKEY_CTX *pkctx = NULL; + size_t sig_len = EVP_PKEY_size(pkey); + + *out_sig_len = 0; + EVP_MD_CTX_init(&tmp_ctx); + if (!EVP_MD_CTX_copy_ex(&tmp_ctx, ctx) || + !EVP_DigestFinal_ex(&tmp_ctx, m, &m_len)) { + goto out; + } + EVP_MD_CTX_cleanup(&tmp_ctx); + + pkctx = EVP_PKEY_CTX_new(pkey, NULL); + if (!pkctx || !EVP_PKEY_sign_init(pkctx) || + !EVP_PKEY_CTX_set_signature_md(pkctx, ctx->digest) || + !EVP_PKEY_sign(pkctx, sig, &sig_len, m, m_len)) { + goto out; + } + *out_sig_len = sig_len; + ret = 1; + +out: + if (pkctx) { + EVP_PKEY_CTX_free(pkctx); + } + + return ret; +} + +int EVP_VerifyInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *impl) { + return EVP_DigestInit_ex(ctx, type, impl); +} + +int EVP_VerifyInit(EVP_MD_CTX *ctx, const EVP_MD *type) { + return EVP_DigestInit(ctx, type); +} + +int EVP_VerifyUpdate(EVP_MD_CTX *ctx, const void *data, size_t len) { + return EVP_DigestUpdate(ctx, data, len); +} + +int EVP_VerifyFinal(EVP_MD_CTX *ctx, const uint8_t *sig, size_t sig_len, + EVP_PKEY *pkey) { + uint8_t m[EVP_MAX_MD_SIZE]; + unsigned int m_len; + int ret = 0; + 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) || + !EVP_DigestFinal_ex(&tmp_ctx, m, &m_len)) { + EVP_MD_CTX_cleanup(&tmp_ctx); + goto out; + } + EVP_MD_CTX_cleanup(&tmp_ctx); + + pkctx = EVP_PKEY_CTX_new(pkey, NULL); + if (!pkctx || + !EVP_PKEY_verify_init(pkctx) || + !EVP_PKEY_CTX_set_signature_md(pkctx, ctx->digest)) { + goto out; + } + ret = EVP_PKEY_verify(pkctx, sig, sig_len, m, m_len); + +out: + EVP_PKEY_CTX_free(pkctx); + return ret; +} + diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/ex_data.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/ex_data.c new file mode 100644 index 0000000..6191a6f --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/ex_data.c @@ -0,0 +1,261 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 + +#include +#include +#include +#include +#include + +#include "internal.h" + + +DEFINE_STACK_OF(CRYPTO_EX_DATA_FUNCS) + +struct crypto_ex_data_func_st { + long argl; // Arbitary long + void *argp; // Arbitary void pointer + CRYPTO_EX_free *free_func; +}; + +int CRYPTO_get_ex_new_index(CRYPTO_EX_DATA_CLASS *ex_data_class, int *out_index, + long argl, void *argp, CRYPTO_EX_free *free_func) { + CRYPTO_EX_DATA_FUNCS *funcs; + int ret = 0; + + funcs = OPENSSL_malloc(sizeof(CRYPTO_EX_DATA_FUNCS)); + if (funcs == NULL) { + OPENSSL_PUT_ERROR(CRYPTO, ERR_R_MALLOC_FAILURE); + return 0; + } + + funcs->argl = argl; + funcs->argp = argp; + funcs->free_func = free_func; + + CRYPTO_STATIC_MUTEX_lock_write(&ex_data_class->lock); + + if (ex_data_class->meth == NULL) { + ex_data_class->meth = sk_CRYPTO_EX_DATA_FUNCS_new_null(); + } + + if (ex_data_class->meth == NULL || + !sk_CRYPTO_EX_DATA_FUNCS_push(ex_data_class->meth, funcs)) { + OPENSSL_PUT_ERROR(CRYPTO, ERR_R_MALLOC_FAILURE); + OPENSSL_free(funcs); + goto err; + } + + *out_index = sk_CRYPTO_EX_DATA_FUNCS_num(ex_data_class->meth) - 1 + + ex_data_class->num_reserved; + ret = 1; + +err: + CRYPTO_STATIC_MUTEX_unlock_write(&ex_data_class->lock); + return ret; +} + +int CRYPTO_set_ex_data(CRYPTO_EX_DATA *ad, int index, void *val) { + int n, i; + + if (ad->sk == NULL) { + ad->sk = sk_void_new_null(); + if (ad->sk == NULL) { + OPENSSL_PUT_ERROR(CRYPTO, ERR_R_MALLOC_FAILURE); + return 0; + } + } + + n = sk_void_num(ad->sk); + + // Add NULL values until the stack is long enough. + for (i = n; i <= index; i++) { + if (!sk_void_push(ad->sk, NULL)) { + OPENSSL_PUT_ERROR(CRYPTO, ERR_R_MALLOC_FAILURE); + return 0; + } + } + + sk_void_set(ad->sk, index, val); + return 1; +} + +void *CRYPTO_get_ex_data(const CRYPTO_EX_DATA *ad, int idx) { + if (ad->sk == NULL || idx < 0 || (size_t)idx >= sk_void_num(ad->sk)) { + return NULL; + } + return sk_void_value(ad->sk, idx); +} + +// get_func_pointers takes a copy of the CRYPTO_EX_DATA_FUNCS pointers, if any, +// for the given class. If there are some pointers, it sets |*out| to point to +// a fresh stack of them. Otherwise it sets |*out| to NULL. It returns one on +// success or zero on error. +static int get_func_pointers(STACK_OF(CRYPTO_EX_DATA_FUNCS) **out, + CRYPTO_EX_DATA_CLASS *ex_data_class) { + size_t n; + + *out = NULL; + + // CRYPTO_EX_DATA_FUNCS structures are static once set, so we can take a + // shallow copy of the list under lock and then use the structures without + // the lock held. + CRYPTO_STATIC_MUTEX_lock_read(&ex_data_class->lock); + n = sk_CRYPTO_EX_DATA_FUNCS_num(ex_data_class->meth); + if (n > 0) { + *out = sk_CRYPTO_EX_DATA_FUNCS_dup(ex_data_class->meth); + } + CRYPTO_STATIC_MUTEX_unlock_read(&ex_data_class->lock); + + if (n > 0 && *out == NULL) { + OPENSSL_PUT_ERROR(CRYPTO, ERR_R_MALLOC_FAILURE); + return 0; + } + + return 1; +} + +void CRYPTO_new_ex_data(CRYPTO_EX_DATA *ad) { + ad->sk = NULL; +} + +void CRYPTO_free_ex_data(CRYPTO_EX_DATA_CLASS *ex_data_class, void *obj, + CRYPTO_EX_DATA *ad) { + if (ad->sk == NULL) { + // Nothing to do. + return; + } + + STACK_OF(CRYPTO_EX_DATA_FUNCS) *func_pointers; + if (!get_func_pointers(&func_pointers, ex_data_class)) { + // TODO(davidben): This leaks memory on malloc error. + return; + } + + for (size_t i = 0; i < sk_CRYPTO_EX_DATA_FUNCS_num(func_pointers); i++) { + CRYPTO_EX_DATA_FUNCS *func_pointer = + sk_CRYPTO_EX_DATA_FUNCS_value(func_pointers, i); + if (func_pointer->free_func) { + void *ptr = CRYPTO_get_ex_data(ad, i + ex_data_class->num_reserved); + func_pointer->free_func(obj, ptr, ad, i + ex_data_class->num_reserved, + func_pointer->argl, func_pointer->argp); + } + } + + sk_CRYPTO_EX_DATA_FUNCS_free(func_pointers); + + sk_void_free(ad->sk); + ad->sk = NULL; +} + +void CRYPTO_cleanup_all_ex_data(void) {} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/ex_data.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/ex_data.c.grpc_back new file mode 100644 index 0000000..71d60a5 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/ex_data.c.grpc_back @@ -0,0 +1,261 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 + +#include +#include +#include +#include +#include + +#include "internal.h" + + +DEFINE_STACK_OF(CRYPTO_EX_DATA_FUNCS) + +struct crypto_ex_data_func_st { + long argl; // Arbitary long + void *argp; // Arbitary void pointer + CRYPTO_EX_free *free_func; +}; + +int CRYPTO_get_ex_new_index(CRYPTO_EX_DATA_CLASS *ex_data_class, int *out_index, + long argl, void *argp, CRYPTO_EX_free *free_func) { + CRYPTO_EX_DATA_FUNCS *funcs; + int ret = 0; + + funcs = OPENSSL_malloc(sizeof(CRYPTO_EX_DATA_FUNCS)); + if (funcs == NULL) { + OPENSSL_PUT_ERROR(CRYPTO, ERR_R_MALLOC_FAILURE); + return 0; + } + + funcs->argl = argl; + funcs->argp = argp; + funcs->free_func = free_func; + + CRYPTO_STATIC_MUTEX_lock_write(&ex_data_class->lock); + + if (ex_data_class->meth == NULL) { + ex_data_class->meth = sk_CRYPTO_EX_DATA_FUNCS_new_null(); + } + + if (ex_data_class->meth == NULL || + !sk_CRYPTO_EX_DATA_FUNCS_push(ex_data_class->meth, funcs)) { + OPENSSL_PUT_ERROR(CRYPTO, ERR_R_MALLOC_FAILURE); + OPENSSL_free(funcs); + goto err; + } + + *out_index = sk_CRYPTO_EX_DATA_FUNCS_num(ex_data_class->meth) - 1 + + ex_data_class->num_reserved; + ret = 1; + +err: + CRYPTO_STATIC_MUTEX_unlock_write(&ex_data_class->lock); + return ret; +} + +int CRYPTO_set_ex_data(CRYPTO_EX_DATA *ad, int index, void *val) { + int n, i; + + if (ad->sk == NULL) { + ad->sk = sk_void_new_null(); + if (ad->sk == NULL) { + OPENSSL_PUT_ERROR(CRYPTO, ERR_R_MALLOC_FAILURE); + return 0; + } + } + + n = sk_void_num(ad->sk); + + // Add NULL values until the stack is long enough. + for (i = n; i <= index; i++) { + if (!sk_void_push(ad->sk, NULL)) { + OPENSSL_PUT_ERROR(CRYPTO, ERR_R_MALLOC_FAILURE); + return 0; + } + } + + sk_void_set(ad->sk, index, val); + return 1; +} + +void *CRYPTO_get_ex_data(const CRYPTO_EX_DATA *ad, int idx) { + if (ad->sk == NULL || idx < 0 || (size_t)idx >= sk_void_num(ad->sk)) { + return NULL; + } + return sk_void_value(ad->sk, idx); +} + +// get_func_pointers takes a copy of the CRYPTO_EX_DATA_FUNCS pointers, if any, +// for the given class. If there are some pointers, it sets |*out| to point to +// a fresh stack of them. Otherwise it sets |*out| to NULL. It returns one on +// success or zero on error. +static int get_func_pointers(STACK_OF(CRYPTO_EX_DATA_FUNCS) **out, + CRYPTO_EX_DATA_CLASS *ex_data_class) { + size_t n; + + *out = NULL; + + // CRYPTO_EX_DATA_FUNCS structures are static once set, so we can take a + // shallow copy of the list under lock and then use the structures without + // the lock held. + CRYPTO_STATIC_MUTEX_lock_read(&ex_data_class->lock); + n = sk_CRYPTO_EX_DATA_FUNCS_num(ex_data_class->meth); + if (n > 0) { + *out = sk_CRYPTO_EX_DATA_FUNCS_dup(ex_data_class->meth); + } + CRYPTO_STATIC_MUTEX_unlock_read(&ex_data_class->lock); + + if (n > 0 && *out == NULL) { + OPENSSL_PUT_ERROR(CRYPTO, ERR_R_MALLOC_FAILURE); + return 0; + } + + return 1; +} + +void CRYPTO_new_ex_data(CRYPTO_EX_DATA *ad) { + ad->sk = NULL; +} + +void CRYPTO_free_ex_data(CRYPTO_EX_DATA_CLASS *ex_data_class, void *obj, + CRYPTO_EX_DATA *ad) { + if (ad->sk == NULL) { + // Nothing to do. + return; + } + + STACK_OF(CRYPTO_EX_DATA_FUNCS) *func_pointers; + if (!get_func_pointers(&func_pointers, ex_data_class)) { + // TODO(davidben): This leaks memory on malloc error. + return; + } + + for (size_t i = 0; i < sk_CRYPTO_EX_DATA_FUNCS_num(func_pointers); i++) { + CRYPTO_EX_DATA_FUNCS *func_pointer = + sk_CRYPTO_EX_DATA_FUNCS_value(func_pointers, i); + if (func_pointer->free_func) { + void *ptr = CRYPTO_get_ex_data(ad, i + ex_data_class->num_reserved); + func_pointer->free_func(obj, ptr, ad, i + ex_data_class->num_reserved, + func_pointer->argl, func_pointer->argp); + } + } + + sk_CRYPTO_EX_DATA_FUNCS_free(func_pointers); + + sk_void_free(ad->sk); + ad->sk = NULL; +} + +void CRYPTO_cleanup_all_ex_data(void) {} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/aes/aes.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/aes/aes.c new file mode 100644 index 0000000..af00089 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/aes/aes.c @@ -0,0 +1,1100 @@ +/* ==================================================================== + * 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 + +#include + +#include + +#include "internal.h" +#include "../modes/internal.h" + + +#if defined(OPENSSL_NO_ASM) || \ + (!defined(OPENSSL_X86) && !defined(OPENSSL_X86_64) && !defined(OPENSSL_ARM)) + +// 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 uint32_t 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 uint32_t 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 uint32_t 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 uint32_t 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 uint32_t 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 uint32_t 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 uint32_t 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 uint32_t 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 uint8_t 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 uint32_t rcon[] = { + 0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000, + 0x20000000, 0x40000000, 0x80000000, 0x1B000000, 0x36000000, + // for 128-bit blocks, Rijndael never uses more than 10 rcon values +}; + +int AES_set_encrypt_key(const uint8_t *key, unsigned bits, AES_KEY *aeskey) { + uint32_t *rk; + int i = 0; + uint32_t temp; + + if (!key || !aeskey) { + return -1; + } + + switch (bits) { + case 128: + aeskey->rounds = 10; + break; + case 192: + aeskey->rounds = 12; + break; + case 256: + aeskey->rounds = 14; + break; + default: + return -2; + } + + rk = aeskey->rd_key; + + rk[0] = GETU32(key); + rk[1] = GETU32(key + 4); + rk[2] = GETU32(key + 8); + rk[3] = GETU32(key + 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(key + 16); + rk[5] = GETU32(key + 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(key + 24); + rk[7] = GETU32(key + 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; +} + +int AES_set_decrypt_key(const uint8_t *key, unsigned bits, AES_KEY *aeskey) { + uint32_t *rk; + int i, j, status; + uint32_t temp; + + // first, start with an encryption schedule + status = AES_set_encrypt_key(key, bits, aeskey); + if (status < 0) { + return status; + } + + rk = aeskey->rd_key; + + // invert the order of the round keys: + for (i = 0, j = 4 * aeskey->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 < (int)aeskey->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; +} + +void AES_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key) { + const uint32_t *rk; + uint32_t 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); +} + +void AES_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key) { + const uint32_t *rk; + uint32_t 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 = ((uint32_t)Td4[(t0 >> 24)] << 24) ^ + ((uint32_t)Td4[(t3 >> 16) & 0xff] << 16) ^ + ((uint32_t)Td4[(t2 >> 8) & 0xff] << 8) ^ + ((uint32_t)Td4[(t1) & 0xff]) ^ rk[0]; + PUTU32(out, s0); + s1 = ((uint32_t)Td4[(t1 >> 24)] << 24) ^ + ((uint32_t)Td4[(t0 >> 16) & 0xff] << 16) ^ + ((uint32_t)Td4[(t3 >> 8) & 0xff] << 8) ^ + ((uint32_t)Td4[(t2) & 0xff]) ^ rk[1]; + PUTU32(out + 4, s1); + s2 = ((uint32_t)Td4[(t2 >> 24)] << 24) ^ + ((uint32_t)Td4[(t1 >> 16) & 0xff] << 16) ^ + ((uint32_t)Td4[(t0 >> 8) & 0xff] << 8) ^ + ((uint32_t)Td4[(t3) & 0xff]) ^ rk[2]; + PUTU32(out + 8, s2); + s3 = ((uint32_t)Td4[(t3 >> 24)] << 24) ^ + ((uint32_t)Td4[(t2 >> 16) & 0xff] << 16) ^ + ((uint32_t)Td4[(t1 >> 8) & 0xff] << 8) ^ + ((uint32_t)Td4[(t0) & 0xff]) ^ rk[3]; + PUTU32(out + 12, s3); +} + +#else + +// In this case several functions are provided by asm code. However, one cannot +// control asm symbol visibility with command line flags and such so they are +// always hidden and wrapped by these C functions, which can be so +// controlled. + +void asm_AES_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key); +void AES_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key) { + if (hwaes_capable()) { + aes_hw_encrypt(in, out, key); + } else { + asm_AES_encrypt(in, out, key); + } +} + +void asm_AES_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key); +void AES_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key) { + if (hwaes_capable()) { + aes_hw_decrypt(in, out, key); + } else { + asm_AES_decrypt(in, out, key); + } +} + +int asm_AES_set_encrypt_key(const uint8_t *key, unsigned bits, AES_KEY *aeskey); +int AES_set_encrypt_key(const uint8_t *key, unsigned bits, AES_KEY *aeskey) { + if (hwaes_capable()) { + return aes_hw_set_encrypt_key(key, bits, aeskey); + } else { + return asm_AES_set_encrypt_key(key, bits, aeskey); + } +} + +int asm_AES_set_decrypt_key(const uint8_t *key, unsigned bits, AES_KEY *aeskey); +int AES_set_decrypt_key(const uint8_t *key, unsigned bits, AES_KEY *aeskey) { + if (hwaes_capable()) { + return aes_hw_set_decrypt_key(key, bits, aeskey); + } else { + return asm_AES_set_decrypt_key(key, bits, aeskey); + } +} + +#endif // OPENSSL_NO_ASM || (!OPENSSL_X86 && !OPENSSL_X86_64 && !OPENSSL_ARM) diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/aes/aes.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/aes/aes.c.grpc_back new file mode 100644 index 0000000..a988b39 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/aes/aes.c.grpc_back @@ -0,0 +1,1100 @@ +/* ==================================================================== + * 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 + +#include + +#include + +#include "internal.h" +#include "../modes/internal.h" + + +#if defined(OPENSSL_NO_ASM) || \ + (!defined(OPENSSL_X86) && !defined(OPENSSL_X86_64) && !defined(OPENSSL_ARM)) + +// 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 uint32_t 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 uint32_t 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 uint32_t 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 uint32_t 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 uint32_t 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 uint32_t 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 uint32_t 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 uint32_t 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 uint8_t 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 uint32_t rcon[] = { + 0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000, + 0x20000000, 0x40000000, 0x80000000, 0x1B000000, 0x36000000, + // for 128-bit blocks, Rijndael never uses more than 10 rcon values +}; + +int AES_set_encrypt_key(const uint8_t *key, unsigned bits, AES_KEY *aeskey) { + uint32_t *rk; + int i = 0; + uint32_t temp; + + if (!key || !aeskey) { + return -1; + } + + switch (bits) { + case 128: + aeskey->rounds = 10; + break; + case 192: + aeskey->rounds = 12; + break; + case 256: + aeskey->rounds = 14; + break; + default: + return -2; + } + + rk = aeskey->rd_key; + + rk[0] = GETU32(key); + rk[1] = GETU32(key + 4); + rk[2] = GETU32(key + 8); + rk[3] = GETU32(key + 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(key + 16); + rk[5] = GETU32(key + 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(key + 24); + rk[7] = GETU32(key + 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; +} + +int AES_set_decrypt_key(const uint8_t *key, unsigned bits, AES_KEY *aeskey) { + uint32_t *rk; + int i, j, status; + uint32_t temp; + + // first, start with an encryption schedule + status = AES_set_encrypt_key(key, bits, aeskey); + if (status < 0) { + return status; + } + + rk = aeskey->rd_key; + + // invert the order of the round keys: + for (i = 0, j = 4 * aeskey->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 < (int)aeskey->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; +} + +void AES_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key) { + const uint32_t *rk; + uint32_t 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); +} + +void AES_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key) { + const uint32_t *rk; + uint32_t 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 = ((uint32_t)Td4[(t0 >> 24)] << 24) ^ + ((uint32_t)Td4[(t3 >> 16) & 0xff] << 16) ^ + ((uint32_t)Td4[(t2 >> 8) & 0xff] << 8) ^ + ((uint32_t)Td4[(t1) & 0xff]) ^ rk[0]; + PUTU32(out, s0); + s1 = ((uint32_t)Td4[(t1 >> 24)] << 24) ^ + ((uint32_t)Td4[(t0 >> 16) & 0xff] << 16) ^ + ((uint32_t)Td4[(t3 >> 8) & 0xff] << 8) ^ + ((uint32_t)Td4[(t2) & 0xff]) ^ rk[1]; + PUTU32(out + 4, s1); + s2 = ((uint32_t)Td4[(t2 >> 24)] << 24) ^ + ((uint32_t)Td4[(t1 >> 16) & 0xff] << 16) ^ + ((uint32_t)Td4[(t0 >> 8) & 0xff] << 8) ^ + ((uint32_t)Td4[(t3) & 0xff]) ^ rk[2]; + PUTU32(out + 8, s2); + s3 = ((uint32_t)Td4[(t3 >> 24)] << 24) ^ + ((uint32_t)Td4[(t2 >> 16) & 0xff] << 16) ^ + ((uint32_t)Td4[(t1 >> 8) & 0xff] << 8) ^ + ((uint32_t)Td4[(t0) & 0xff]) ^ rk[3]; + PUTU32(out + 12, s3); +} + +#else + +// In this case several functions are provided by asm code. However, one cannot +// control asm symbol visibility with command line flags and such so they are +// always hidden and wrapped by these C functions, which can be so +// controlled. + +void asm_AES_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key); +void AES_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key) { + if (hwaes_capable()) { + aes_hw_encrypt(in, out, key); + } else { + asm_AES_encrypt(in, out, key); + } +} + +void asm_AES_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key); +void AES_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key) { + if (hwaes_capable()) { + aes_hw_decrypt(in, out, key); + } else { + asm_AES_decrypt(in, out, key); + } +} + +int asm_AES_set_encrypt_key(const uint8_t *key, unsigned bits, AES_KEY *aeskey); +int AES_set_encrypt_key(const uint8_t *key, unsigned bits, AES_KEY *aeskey) { + if (hwaes_capable()) { + return aes_hw_set_encrypt_key(key, bits, aeskey); + } else { + return asm_AES_set_encrypt_key(key, bits, aeskey); + } +} + +int asm_AES_set_decrypt_key(const uint8_t *key, unsigned bits, AES_KEY *aeskey); +int AES_set_decrypt_key(const uint8_t *key, unsigned bits, AES_KEY *aeskey) { + if (hwaes_capable()) { + return aes_hw_set_decrypt_key(key, bits, aeskey); + } else { + return asm_AES_set_decrypt_key(key, bits, aeskey); + } +} + +#endif // OPENSSL_NO_ASM || (!OPENSSL_X86 && !OPENSSL_X86_64 && !OPENSSL_ARM) diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/aes/internal.h b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/aes/internal.h new file mode 100644 index 0000000..d72c738 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/aes/internal.h @@ -0,0 +1,100 @@ +/* Copyright (c) 2017, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_AES_INTERNAL_H +#define OPENSSL_HEADER_AES_INTERNAL_H + +#include + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +#if !defined(OPENSSL_NO_ASM) && (defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)) +#define HWAES + +static int hwaes_capable(void) { + return CRYPTO_is_ARMv8_AES_capable(); +} +#endif // !NO_ASM && (AES || AARCH64) + +#if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_PPC64LE) +#define HWAES + +static int hwaes_capable(void) { + return CRYPTO_is_PPC64LE_vcrypto_capable(); +} +#endif // !NO_ASM && PPC64LE + + +#if defined(HWAES) + +int aes_hw_set_encrypt_key(const uint8_t *user_key, const int bits, + AES_KEY *key); +int aes_hw_set_decrypt_key(const uint8_t *user_key, const int bits, + AES_KEY *key); +void aes_hw_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key); +void aes_hw_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key); +void aes_hw_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t length, + const AES_KEY *key, uint8_t *ivec, const int enc); +void aes_hw_ctr32_encrypt_blocks(const uint8_t *in, uint8_t *out, size_t len, + const AES_KEY *key, const uint8_t ivec[16]); + +#else + +// If HWAES isn't defined then we provide dummy functions for each of the hwaes +// functions. +static int hwaes_capable(void) { return 0; } + +static int aes_hw_set_encrypt_key(const uint8_t *user_key, int bits, + AES_KEY *key) { + abort(); +} + +static int aes_hw_set_decrypt_key(const uint8_t *user_key, int bits, + AES_KEY *key) { + abort(); +} + +static void aes_hw_encrypt(const uint8_t *in, uint8_t *out, + const AES_KEY *key) { + abort(); +} + +static void aes_hw_decrypt(const uint8_t *in, uint8_t *out, + const AES_KEY *key) { + abort(); +} + +static void aes_hw_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t length, + const AES_KEY *key, uint8_t *ivec, int enc) { + abort(); +} + +static void aes_hw_ctr32_encrypt_blocks(const uint8_t *in, uint8_t *out, + size_t len, const AES_KEY *key, + const uint8_t ivec[16]) { + abort(); +} + +#endif // !HWAES + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_AES_INTERNAL_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/aes/internal.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/aes/internal.h.grpc_back new file mode 100644 index 0000000..45db9ee --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/aes/internal.h.grpc_back @@ -0,0 +1,100 @@ +/* Copyright (c) 2017, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_AES_INTERNAL_H +#define OPENSSL_HEADER_AES_INTERNAL_H + +#include + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +#if !defined(OPENSSL_NO_ASM) && (defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)) +#define HWAES + +static int hwaes_capable(void) { + return CRYPTO_is_ARMv8_AES_capable(); +} +#endif // !NO_ASM && (AES || AARCH64) + +#if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_PPC64LE) +#define HWAES + +static int hwaes_capable(void) { + return CRYPTO_is_PPC64LE_vcrypto_capable(); +} +#endif // !NO_ASM && PPC64LE + + +#if defined(HWAES) + +int aes_hw_set_encrypt_key(const uint8_t *user_key, const int bits, + AES_KEY *key); +int aes_hw_set_decrypt_key(const uint8_t *user_key, const int bits, + AES_KEY *key); +void aes_hw_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key); +void aes_hw_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key); +void aes_hw_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t length, + const AES_KEY *key, uint8_t *ivec, const int enc); +void aes_hw_ctr32_encrypt_blocks(const uint8_t *in, uint8_t *out, size_t len, + const AES_KEY *key, const uint8_t ivec[16]); + +#else + +// If HWAES isn't defined then we provide dummy functions for each of the hwaes +// functions. +static int hwaes_capable(void) { return 0; } + +static int aes_hw_set_encrypt_key(const uint8_t *user_key, int bits, + AES_KEY *key) { + abort(); +} + +static int aes_hw_set_decrypt_key(const uint8_t *user_key, int bits, + AES_KEY *key) { + abort(); +} + +static void aes_hw_encrypt(const uint8_t *in, uint8_t *out, + const AES_KEY *key) { + abort(); +} + +static void aes_hw_decrypt(const uint8_t *in, uint8_t *out, + const AES_KEY *key) { + abort(); +} + +static void aes_hw_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t length, + const AES_KEY *key, uint8_t *ivec, int enc) { + abort(); +} + +static void aes_hw_ctr32_encrypt_blocks(const uint8_t *in, uint8_t *out, + size_t len, const AES_KEY *key, + const uint8_t ivec[16]) { + abort(); +} + +#endif // !HWAES + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_AES_INTERNAL_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/aes/key_wrap.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/aes/key_wrap.c new file mode 100644 index 0000000..a19cfbe --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/aes/key_wrap.c @@ -0,0 +1,138 @@ +/* ==================================================================== + * Copyright (c) 2001-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 + +#include +#include + +#include + +#include "../../internal.h" + + +// kDefaultIV is the default IV value given in RFC 3394, 2.2.3.1. +static const uint8_t kDefaultIV[] = { + 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, +}; + +static const unsigned kBound = 6; + +int AES_wrap_key(const AES_KEY *key, const uint8_t *iv, uint8_t *out, + const uint8_t *in, size_t in_len) { + // See RFC 3394, section 2.2.1. + + if (in_len > INT_MAX - 8 || in_len < 8 || in_len % 8 != 0) { + return -1; + } + + if (iv == NULL) { + iv = kDefaultIV; + } + + OPENSSL_memmove(out + 8, in, in_len); + uint8_t A[AES_BLOCK_SIZE]; + OPENSSL_memcpy(A, iv, 8); + + size_t n = in_len / 8; + + for (unsigned j = 0; j < kBound; j++) { + for (size_t i = 1; i <= n; i++) { + OPENSSL_memcpy(A + 8, out + 8 * i, 8); + AES_encrypt(A, A, key); + + uint32_t t = (uint32_t)(n * j + i); + A[7] ^= t & 0xff; + A[6] ^= (t >> 8) & 0xff; + A[5] ^= (t >> 16) & 0xff; + A[4] ^= (t >> 24) & 0xff; + OPENSSL_memcpy(out + 8 * i, A + 8, 8); + } + } + + OPENSSL_memcpy(out, A, 8); + return (int)in_len + 8; +} + +int AES_unwrap_key(const AES_KEY *key, const uint8_t *iv, uint8_t *out, + const uint8_t *in, size_t in_len) { + // See RFC 3394, section 2.2.2. + + if (in_len > INT_MAX || in_len < 16 || in_len % 8 != 0) { + return -1; + } + + if (iv == NULL) { + iv = kDefaultIV; + } + + uint8_t A[AES_BLOCK_SIZE]; + OPENSSL_memcpy(A, in, 8); + OPENSSL_memmove(out, in + 8, in_len - 8); + + size_t n = (in_len / 8) - 1; + + for (unsigned j = kBound - 1; j < kBound; j--) { + for (size_t i = n; i > 0; i--) { + uint32_t t = (uint32_t)(n * j + i); + A[7] ^= t & 0xff; + A[6] ^= (t >> 8) & 0xff; + A[5] ^= (t >> 16) & 0xff; + A[4] ^= (t >> 24) & 0xff; + OPENSSL_memcpy(A + 8, out + 8 * (i - 1), 8); + AES_decrypt(A, A, key); + OPENSSL_memcpy(out + 8 * (i - 1), A + 8, 8); + } + } + + if (CRYPTO_memcmp(A, iv, 8) != 0) { + return -1; + } + + return (int)in_len - 8; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/aes/key_wrap.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/aes/key_wrap.c.grpc_back new file mode 100644 index 0000000..feee0c7 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/aes/key_wrap.c.grpc_back @@ -0,0 +1,138 @@ +/* ==================================================================== + * Copyright (c) 2001-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 + +#include +#include + +#include + +#include "../../internal.h" + + +// kDefaultIV is the default IV value given in RFC 3394, 2.2.3.1. +static const uint8_t kDefaultIV[] = { + 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, 0xa6, +}; + +static const unsigned kBound = 6; + +int AES_wrap_key(const AES_KEY *key, const uint8_t *iv, uint8_t *out, + const uint8_t *in, size_t in_len) { + // See RFC 3394, section 2.2.1. + + if (in_len > INT_MAX - 8 || in_len < 8 || in_len % 8 != 0) { + return -1; + } + + if (iv == NULL) { + iv = kDefaultIV; + } + + OPENSSL_memmove(out + 8, in, in_len); + uint8_t A[AES_BLOCK_SIZE]; + OPENSSL_memcpy(A, iv, 8); + + size_t n = in_len / 8; + + for (unsigned j = 0; j < kBound; j++) { + for (size_t i = 1; i <= n; i++) { + OPENSSL_memcpy(A + 8, out + 8 * i, 8); + AES_encrypt(A, A, key); + + uint32_t t = (uint32_t)(n * j + i); + A[7] ^= t & 0xff; + A[6] ^= (t >> 8) & 0xff; + A[5] ^= (t >> 16) & 0xff; + A[4] ^= (t >> 24) & 0xff; + OPENSSL_memcpy(out + 8 * i, A + 8, 8); + } + } + + OPENSSL_memcpy(out, A, 8); + return (int)in_len + 8; +} + +int AES_unwrap_key(const AES_KEY *key, const uint8_t *iv, uint8_t *out, + const uint8_t *in, size_t in_len) { + // See RFC 3394, section 2.2.2. + + if (in_len > INT_MAX || in_len < 16 || in_len % 8 != 0) { + return -1; + } + + if (iv == NULL) { + iv = kDefaultIV; + } + + uint8_t A[AES_BLOCK_SIZE]; + OPENSSL_memcpy(A, in, 8); + OPENSSL_memmove(out, in + 8, in_len - 8); + + size_t n = (in_len / 8) - 1; + + for (unsigned j = kBound - 1; j < kBound; j--) { + for (size_t i = n; i > 0; i--) { + uint32_t t = (uint32_t)(n * j + i); + A[7] ^= t & 0xff; + A[6] ^= (t >> 8) & 0xff; + A[5] ^= (t >> 16) & 0xff; + A[4] ^= (t >> 24) & 0xff; + OPENSSL_memcpy(A + 8, out + 8 * (i - 1), 8); + AES_decrypt(A, A, key); + OPENSSL_memcpy(out + 8 * (i - 1), A + 8, 8); + } + } + + if (CRYPTO_memcmp(A, iv, 8) != 0) { + return -1; + } + + return (int)in_len - 8; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/aes/mode_wrappers.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/aes/mode_wrappers.c new file mode 100644 index 0000000..c3d299f --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/aes/mode_wrappers.c @@ -0,0 +1,112 @@ +/* ==================================================================== + * 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 + +#include + +#include "../modes/internal.h" + + +void AES_ctr128_encrypt(const uint8_t *in, uint8_t *out, size_t len, + const AES_KEY *key, uint8_t ivec[AES_BLOCK_SIZE], + uint8_t ecount_buf[AES_BLOCK_SIZE], unsigned int *num) { + CRYPTO_ctr128_encrypt(in, out, len, key, ivec, ecount_buf, num, + (block128_f)AES_encrypt); +} + +void AES_ecb_encrypt(const uint8_t *in, uint8_t *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); + } +} + +#if defined(OPENSSL_NO_ASM) || \ + (!defined(OPENSSL_X86_64) && !defined(OPENSSL_X86)) +void AES_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t len, + const AES_KEY *key, uint8_t *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); + } +} +#else + +void asm_AES_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t len, + const AES_KEY *key, uint8_t *ivec, const int enc); +void AES_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t len, + const AES_KEY *key, uint8_t *ivec, const int enc) { + asm_AES_cbc_encrypt(in, out, len, key, ivec, enc); +} + +#endif // OPENSSL_NO_ASM || (!OPENSSL_X86_64 && !OPENSSL_X86) + +void AES_ofb128_encrypt(const uint8_t *in, uint8_t *out, size_t length, + const AES_KEY *key, uint8_t *ivec, int *num) { + unsigned num_u = (unsigned)(*num); + CRYPTO_ofb128_encrypt(in, out, length, key, ivec, &num_u, + (block128_f)AES_encrypt); + *num = (int)num_u; +} + +void AES_cfb128_encrypt(const uint8_t *in, uint8_t *out, size_t length, + const AES_KEY *key, uint8_t *ivec, int *num, + int enc) { + unsigned num_u = (unsigned)(*num); + CRYPTO_cfb128_encrypt(in, out, length, key, ivec, &num_u, enc, + (block128_f)AES_encrypt); + *num = (int)num_u; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/aes/mode_wrappers.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/aes/mode_wrappers.c.grpc_back new file mode 100644 index 0000000..34514db --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/aes/mode_wrappers.c.grpc_back @@ -0,0 +1,112 @@ +/* ==================================================================== + * 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 + +#include + +#include "../modes/internal.h" + + +void AES_ctr128_encrypt(const uint8_t *in, uint8_t *out, size_t len, + const AES_KEY *key, uint8_t ivec[AES_BLOCK_SIZE], + uint8_t ecount_buf[AES_BLOCK_SIZE], unsigned int *num) { + CRYPTO_ctr128_encrypt(in, out, len, key, ivec, ecount_buf, num, + (block128_f)AES_encrypt); +} + +void AES_ecb_encrypt(const uint8_t *in, uint8_t *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); + } +} + +#if defined(OPENSSL_NO_ASM) || \ + (!defined(OPENSSL_X86_64) && !defined(OPENSSL_X86)) +void AES_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t len, + const AES_KEY *key, uint8_t *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); + } +} +#else + +void asm_AES_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t len, + const AES_KEY *key, uint8_t *ivec, const int enc); +void AES_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t len, + const AES_KEY *key, uint8_t *ivec, const int enc) { + asm_AES_cbc_encrypt(in, out, len, key, ivec, enc); +} + +#endif // OPENSSL_NO_ASM || (!OPENSSL_X86_64 && !OPENSSL_X86) + +void AES_ofb128_encrypt(const uint8_t *in, uint8_t *out, size_t length, + const AES_KEY *key, uint8_t *ivec, int *num) { + unsigned num_u = (unsigned)(*num); + CRYPTO_ofb128_encrypt(in, out, length, key, ivec, &num_u, + (block128_f)AES_encrypt); + *num = (int)num_u; +} + +void AES_cfb128_encrypt(const uint8_t *in, uint8_t *out, size_t length, + const AES_KEY *key, uint8_t *ivec, int *num, + int enc) { + unsigned num_u = (unsigned)(*num); + CRYPTO_cfb128_encrypt(in, out, length, key, ivec, &num_u, enc, + (block128_f)AES_encrypt); + *num = (int)num_u; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/add.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/add.c new file mode 100644 index 0000000..8c19670 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/add.c @@ -0,0 +1,316 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 "internal.h" + + +int BN_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) { + const BIGNUM *tmp; + int a_neg = a->neg, ret; + + // 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; + return ret; +} + +int bn_uadd_consttime(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) { + // Widths are public, so we normalize to make |a| the larger one. + if (a->width < b->width) { + const BIGNUM *tmp = a; + a = b; + b = tmp; + } + + int max = a->width; + int min = b->width; + if (!bn_wexpand(r, max + 1)) { + return 0; + } + r->width = max + 1; + + BN_ULONG carry = bn_add_words(r->d, a->d, b->d, min); + for (int i = min; i < max; i++) { + // |r| and |a| may alias, so use a temporary. + BN_ULONG tmp = carry + a->d[i]; + carry = tmp < a->d[i]; + r->d[i] = tmp; + } + + r->d[max] = carry; + return 1; +} + +int BN_uadd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) { + if (!bn_uadd_consttime(r, a, b)) { + return 0; + } + bn_set_minimal_width(r); + return 1; +} + +int BN_add_word(BIGNUM *a, BN_ULONG w) { + BN_ULONG l; + int i; + + // 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->width; i++) { + a->d[i] = l = a->d[i] + w; + w = (w > l) ? 1 : 0; + } + + if (w && i == a->width) { + if (!bn_wexpand(a, a->width + 1)) { + return 0; + } + a->width++; + a->d[i] = w; + } + + return 1; +} + +int BN_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) { + int add = 0, neg = 0; + const BIGNUM *tmp; + + // 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; + } + + 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; +} + +int bn_usub_consttime(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) { + // |b| may have more words than |a| given non-minimal inputs, but all words + // beyond |a->width| must then be zero. + int b_width = b->width; + if (b_width > a->width) { + if (!bn_fits_in_words(b, a->width)) { + OPENSSL_PUT_ERROR(BN, BN_R_ARG2_LT_ARG3); + return 0; + } + b_width = a->width; + } + + if (!bn_wexpand(r, a->width)) { + return 0; + } + + BN_ULONG borrow = bn_sub_words(r->d, a->d, b->d, b_width); + for (int i = b_width; i < a->width; i++) { + // |r| and |a| may alias, so use a temporary. + BN_ULONG tmp = a->d[i]; + r->d[i] = a->d[i] - borrow; + borrow = tmp < r->d[i]; + } + + if (borrow) { + OPENSSL_PUT_ERROR(BN, BN_R_ARG2_LT_ARG3); + return 0; + } + + r->width = a->width; + r->neg = 0; + return 1; +} + +int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) { + if (!bn_usub_consttime(r, a, b)) { + return 0; + } + bn_set_minimal_width(r); + return 1; +} + +int BN_sub_word(BIGNUM *a, BN_ULONG w) { + int i; + + // 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 ((bn_minimal_width(a) == 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] -= w; + i++; + w = 1; + } + } + + if ((a->d[i] == 0) && (i == (a->width - 1))) { + a->width--; + } + + return 1; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/add.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/add.c.grpc_back new file mode 100644 index 0000000..38a8450 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/add.c.grpc_back @@ -0,0 +1,316 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 "internal.h" + + +int BN_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) { + const BIGNUM *tmp; + int a_neg = a->neg, ret; + + // 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; + return ret; +} + +int bn_uadd_consttime(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) { + // Widths are public, so we normalize to make |a| the larger one. + if (a->width < b->width) { + const BIGNUM *tmp = a; + a = b; + b = tmp; + } + + int max = a->width; + int min = b->width; + if (!bn_wexpand(r, max + 1)) { + return 0; + } + r->width = max + 1; + + BN_ULONG carry = bn_add_words(r->d, a->d, b->d, min); + for (int i = min; i < max; i++) { + // |r| and |a| may alias, so use a temporary. + BN_ULONG tmp = carry + a->d[i]; + carry = tmp < a->d[i]; + r->d[i] = tmp; + } + + r->d[max] = carry; + return 1; +} + +int BN_uadd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) { + if (!bn_uadd_consttime(r, a, b)) { + return 0; + } + bn_set_minimal_width(r); + return 1; +} + +int BN_add_word(BIGNUM *a, BN_ULONG w) { + BN_ULONG l; + int i; + + // 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->width; i++) { + a->d[i] = l = a->d[i] + w; + w = (w > l) ? 1 : 0; + } + + if (w && i == a->width) { + if (!bn_wexpand(a, a->width + 1)) { + return 0; + } + a->width++; + a->d[i] = w; + } + + return 1; +} + +int BN_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) { + int add = 0, neg = 0; + const BIGNUM *tmp; + + // 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; + } + + 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; +} + +int bn_usub_consttime(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) { + // |b| may have more words than |a| given non-minimal inputs, but all words + // beyond |a->width| must then be zero. + int b_width = b->width; + if (b_width > a->width) { + if (!bn_fits_in_words(b, a->width)) { + OPENSSL_PUT_ERROR(BN, BN_R_ARG2_LT_ARG3); + return 0; + } + b_width = a->width; + } + + if (!bn_wexpand(r, a->width)) { + return 0; + } + + BN_ULONG borrow = bn_sub_words(r->d, a->d, b->d, b_width); + for (int i = b_width; i < a->width; i++) { + // |r| and |a| may alias, so use a temporary. + BN_ULONG tmp = a->d[i]; + r->d[i] = a->d[i] - borrow; + borrow = tmp < r->d[i]; + } + + if (borrow) { + OPENSSL_PUT_ERROR(BN, BN_R_ARG2_LT_ARG3); + return 0; + } + + r->width = a->width; + r->neg = 0; + return 1; +} + +int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b) { + if (!bn_usub_consttime(r, a, b)) { + return 0; + } + bn_set_minimal_width(r); + return 1; +} + +int BN_sub_word(BIGNUM *a, BN_ULONG w) { + int i; + + // 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 ((bn_minimal_width(a) == 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] -= w; + i++; + w = 1; + } + } + + if ((a->d[i] == 0) && (i == (a->width - 1))) { + a->width--; + } + + return 1; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/asm/x86_64-gcc.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/asm/x86_64-gcc.c new file mode 100644 index 0000000..6034b61 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/asm/x86_64-gcc.c @@ -0,0 +1,541 @@ +/* x86_64 BIGNUM accelerator version 0.1, December 2002. + * + * Implemented by Andy Polyakov for the OpenSSL + * project. + * + * Rights for redistribution and usage in source and binary forms are + * granted according to the OpenSSL license. Warranty of any kind is + * disclaimed. + * + * Q. Version 0.1? It doesn't sound like Andy, he used to assign real + * versions, like 1.0... + * A. Well, that's because this code is basically a quick-n-dirty + * proof-of-concept hack. As you can see it's implemented with + * inline assembler, which means that you're bound to GCC and that + * there might be enough room for further improvement. + * + * Q. Why inline assembler? + * A. x86_64 features own ABI which I'm not familiar with. This is + * why I decided to let the compiler take care of subroutine + * prologue/epilogue as well as register allocation. For reference. + * Win64 implements different ABI for AMD64, different from Linux. + * + * Q. How much faster does it get? + * A. 'apps/openssl speed rsa dsa' output with no-asm: + * + * sign verify sign/s verify/s + * rsa 512 bits 0.0006s 0.0001s 1683.8 18456.2 + * rsa 1024 bits 0.0028s 0.0002s 356.0 6407.0 + * rsa 2048 bits 0.0172s 0.0005s 58.0 1957.8 + * rsa 4096 bits 0.1155s 0.0018s 8.7 555.6 + * sign verify sign/s verify/s + * dsa 512 bits 0.0005s 0.0006s 2100.8 1768.3 + * dsa 1024 bits 0.0014s 0.0018s 692.3 559.2 + * dsa 2048 bits 0.0049s 0.0061s 204.7 165.0 + * + * 'apps/openssl speed rsa dsa' output with this module: + * + * sign verify sign/s verify/s + * rsa 512 bits 0.0004s 0.0000s 2767.1 33297.9 + * rsa 1024 bits 0.0012s 0.0001s 867.4 14674.7 + * rsa 2048 bits 0.0061s 0.0002s 164.0 5270.0 + * rsa 4096 bits 0.0384s 0.0006s 26.1 1650.8 + * sign verify sign/s verify/s + * dsa 512 bits 0.0002s 0.0003s 4442.2 3786.3 + * dsa 1024 bits 0.0005s 0.0007s 1835.1 1497.4 + * dsa 2048 bits 0.0016s 0.0020s 620.4 504.6 + * + * For the reference. IA-32 assembler implementation performs + * very much like 64-bit code compiled with no-asm on the same + * machine. + */ + +#include + +// TODO(davidben): Get this file working on MSVC x64. +#if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64) && \ + (defined(__GNUC__) || defined(__clang__)) + +#include "../internal.h" + + +#undef mul +#undef mul_add + +// "m"(a), "+m"(r) is the way to favor DirectPath µ-code; +// "g"(0) let the compiler to decide where does it +// want to keep the value of zero; +#define mul_add(r, a, word, carry) \ + do { \ + register BN_ULONG high, low; \ + __asm__("mulq %3" : "=a"(low), "=d"(high) : "a"(word), "m"(a) : "cc"); \ + __asm__("addq %2,%0; adcq %3,%1" \ + : "+r"(carry), "+d"(high) \ + : "a"(low), "g"(0) \ + : "cc"); \ + __asm__("addq %2,%0; adcq %3,%1" \ + : "+m"(r), "+d"(high) \ + : "r"(carry), "g"(0) \ + : "cc"); \ + (carry) = high; \ + } while (0) + +#define mul(r, a, word, carry) \ + do { \ + register BN_ULONG high, low; \ + __asm__("mulq %3" : "=a"(low), "=d"(high) : "a"(word), "g"(a) : "cc"); \ + __asm__("addq %2,%0; adcq %3,%1" \ + : "+r"(carry), "+d"(high) \ + : "a"(low), "g"(0) \ + : "cc"); \ + (r) = (carry); \ + (carry) = high; \ + } while (0) +#undef sqr +#define sqr(r0, r1, a) __asm__("mulq %2" : "=a"(r0), "=d"(r1) : "a"(a) : "cc"); + +BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, size_t num, + BN_ULONG w) { + BN_ULONG c1 = 0; + + if (num == 0) { + return (c1); + } + + 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; + } + if (num) { + mul_add(rp[0], ap[0], w, c1); + if (--num == 0) { + return c1; + } + mul_add(rp[1], ap[1], w, c1); + if (--num == 0) { + return c1; + } + mul_add(rp[2], ap[2], w, c1); + return c1; + } + + return c1; +} + +BN_ULONG bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, size_t num, + BN_ULONG w) { + BN_ULONG c1 = 0; + + if (num == 0) { + return c1; + } + + 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; + } + if (num) { + mul(rp[0], ap[0], w, c1); + if (--num == 0) { + return c1; + } + mul(rp[1], ap[1], w, c1); + if (--num == 0) { + return c1; + } + mul(rp[2], ap[2], w, c1); + } + return c1; +} + +void bn_sqr_words(BN_ULONG *r, const BN_ULONG *a, size_t n) { + if (n == 0) { + return; + } + + 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; + } + if (n) { + sqr(r[0], r[1], a[0]); + if (--n == 0) { + return; + } + sqr(r[2], r[3], a[1]); + if (--n == 0) { + return; + } + sqr(r[4], r[5], a[2]); + } +} + +BN_ULONG bn_add_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, + size_t n) { + BN_ULONG ret; + size_t i = 0; + + if (n == 0) { + return 0; + } + + __asm__ volatile ( + " subq %0,%0 \n" // clear carry + " jmp 1f \n" + ".p2align 4 \n" + "1:" + " movq (%4,%2,8),%0 \n" + " adcq (%5,%2,8),%0 \n" + " movq %0,(%3,%2,8) \n" + " lea 1(%2),%2 \n" + " dec %1 \n" + " jnz 1b \n" + " sbbq %0,%0 \n" + : "=&r"(ret), "+c"(n), "+r"(i) + : "r"(rp), "r"(ap), "r"(bp) + : "cc", "memory"); + + return ret & 1; +} + +BN_ULONG bn_sub_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, + size_t n) { + BN_ULONG ret; + size_t i = 0; + + if (n == 0) { + return 0; + } + + __asm__ volatile ( + " subq %0,%0 \n" // clear borrow + " jmp 1f \n" + ".p2align 4 \n" + "1:" + " movq (%4,%2,8),%0 \n" + " sbbq (%5,%2,8),%0 \n" + " movq %0,(%3,%2,8) \n" + " lea 1(%2),%2 \n" + " dec %1 \n" + " jnz 1b \n" + " sbbq %0,%0 \n" + : "=&r"(ret), "+c"(n), "+r"(i) + : "r"(rp), "r"(ap), "r"(bp) + : "cc", "memory"); + + return ret & 1; +} + +// 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) + +// Keep in mind that carrying into high part of multiplication result can not +// overflow, because it cannot be all-ones. +#define mul_add_c(a, b, c0, c1, c2) \ + do { \ + BN_ULONG t1, t2; \ + __asm__("mulq %3" : "=a"(t1), "=d"(t2) : "a"(a), "m"(b) : "cc"); \ + __asm__("addq %3,%0; adcq %4,%1; adcq %5,%2" \ + : "+r"(c0), "+r"(c1), "+r"(c2) \ + : "r"(t1), "r"(t2), "g"(0) \ + : "cc"); \ + } while (0) + +#define sqr_add_c(a, i, c0, c1, c2) \ + do { \ + BN_ULONG t1, t2; \ + __asm__("mulq %2" : "=a"(t1), "=d"(t2) : "a"((a)[i]) : "cc"); \ + __asm__("addq %3,%0; adcq %4,%1; adcq %5,%2" \ + : "+r"(c0), "+r"(c1), "+r"(c2) \ + : "r"(t1), "r"(t2), "g"(0) \ + : "cc"); \ + } while (0) + +#define mul_add_c2(a, b, c0, c1, c2) \ + do { \ + BN_ULONG t1, t2; \ + __asm__("mulq %3" : "=a"(t1), "=d"(t2) : "a"(a), "m"(b) : "cc"); \ + __asm__("addq %3,%0; adcq %4,%1; adcq %5,%2" \ + : "+r"(c0), "+r"(c1), "+r"(c2) \ + : "r"(t1), "r"(t2), "g"(0) \ + : "cc"); \ + __asm__("addq %3,%0; adcq %4,%1; adcq %5,%2" \ + : "+r"(c0), "+r"(c1), "+r"(c2) \ + : "r"(t1), "r"(t2), "g"(0) \ + : "cc"); \ + } while (0) + +#define sqr_add_c2(a, i, j, c0, c1, c2) mul_add_c2((a)[i], (a)[j], c0, c1, c2) + +void bn_mul_comba8(BN_ULONG r[16], const BN_ULONG a[8], const BN_ULONG b[8]) { + BN_ULONG c1, c2, c3; + + c1 = 0; + c2 = 0; + c3 = 0; + mul_add_c(a[0], b[0], c1, c2, c3); + r[0] = c1; + c1 = 0; + mul_add_c(a[0], b[1], c2, c3, c1); + mul_add_c(a[1], b[0], c2, c3, c1); + r[1] = c2; + c2 = 0; + mul_add_c(a[2], b[0], c3, c1, c2); + mul_add_c(a[1], b[1], c3, c1, c2); + mul_add_c(a[0], b[2], c3, c1, c2); + r[2] = c3; + c3 = 0; + mul_add_c(a[0], b[3], c1, c2, c3); + mul_add_c(a[1], b[2], c1, c2, c3); + mul_add_c(a[2], b[1], c1, c2, c3); + mul_add_c(a[3], b[0], c1, c2, c3); + r[3] = c1; + c1 = 0; + mul_add_c(a[4], b[0], c2, c3, c1); + mul_add_c(a[3], b[1], c2, c3, c1); + mul_add_c(a[2], b[2], c2, c3, c1); + mul_add_c(a[1], b[3], c2, c3, c1); + mul_add_c(a[0], b[4], c2, c3, c1); + r[4] = c2; + c2 = 0; + mul_add_c(a[0], b[5], c3, c1, c2); + mul_add_c(a[1], b[4], c3, c1, c2); + mul_add_c(a[2], b[3], c3, c1, c2); + mul_add_c(a[3], b[2], c3, c1, c2); + mul_add_c(a[4], b[1], c3, c1, c2); + mul_add_c(a[5], b[0], c3, c1, c2); + r[5] = c3; + c3 = 0; + mul_add_c(a[6], b[0], c1, c2, c3); + mul_add_c(a[5], b[1], c1, c2, c3); + mul_add_c(a[4], b[2], c1, c2, c3); + mul_add_c(a[3], b[3], c1, c2, c3); + mul_add_c(a[2], b[4], c1, c2, c3); + mul_add_c(a[1], b[5], c1, c2, c3); + mul_add_c(a[0], b[6], c1, c2, c3); + r[6] = c1; + c1 = 0; + mul_add_c(a[0], b[7], c2, c3, c1); + mul_add_c(a[1], b[6], c2, c3, c1); + mul_add_c(a[2], b[5], c2, c3, c1); + mul_add_c(a[3], b[4], c2, c3, c1); + mul_add_c(a[4], b[3], c2, c3, c1); + mul_add_c(a[5], b[2], c2, c3, c1); + mul_add_c(a[6], b[1], c2, c3, c1); + mul_add_c(a[7], b[0], c2, c3, c1); + r[7] = c2; + c2 = 0; + mul_add_c(a[7], b[1], c3, c1, c2); + mul_add_c(a[6], b[2], c3, c1, c2); + mul_add_c(a[5], b[3], c3, c1, c2); + mul_add_c(a[4], b[4], c3, c1, c2); + mul_add_c(a[3], b[5], c3, c1, c2); + mul_add_c(a[2], b[6], c3, c1, c2); + mul_add_c(a[1], b[7], c3, c1, c2); + r[8] = c3; + c3 = 0; + mul_add_c(a[2], b[7], c1, c2, c3); + mul_add_c(a[3], b[6], c1, c2, c3); + mul_add_c(a[4], b[5], c1, c2, c3); + mul_add_c(a[5], b[4], c1, c2, c3); + mul_add_c(a[6], b[3], c1, c2, c3); + mul_add_c(a[7], b[2], c1, c2, c3); + r[9] = c1; + c1 = 0; + mul_add_c(a[7], b[3], c2, c3, c1); + mul_add_c(a[6], b[4], c2, c3, c1); + mul_add_c(a[5], b[5], c2, c3, c1); + mul_add_c(a[4], b[6], c2, c3, c1); + mul_add_c(a[3], b[7], c2, c3, c1); + r[10] = c2; + c2 = 0; + mul_add_c(a[4], b[7], c3, c1, c2); + mul_add_c(a[5], b[6], c3, c1, c2); + mul_add_c(a[6], b[5], c3, c1, c2); + mul_add_c(a[7], b[4], c3, c1, c2); + r[11] = c3; + c3 = 0; + mul_add_c(a[7], b[5], c1, c2, c3); + mul_add_c(a[6], b[6], c1, c2, c3); + mul_add_c(a[5], b[7], c1, c2, c3); + r[12] = c1; + c1 = 0; + mul_add_c(a[6], b[7], c2, c3, c1); + mul_add_c(a[7], b[6], c2, c3, c1); + r[13] = c2; + c2 = 0; + mul_add_c(a[7], b[7], c3, c1, c2); + r[14] = c3; + r[15] = c1; +} + +void bn_mul_comba4(BN_ULONG r[8], const BN_ULONG a[4], const BN_ULONG b[4]) { + BN_ULONG c1, c2, c3; + + c1 = 0; + c2 = 0; + c3 = 0; + mul_add_c(a[0], b[0], c1, c2, c3); + r[0] = c1; + c1 = 0; + mul_add_c(a[0], b[1], c2, c3, c1); + mul_add_c(a[1], b[0], c2, c3, c1); + r[1] = c2; + c2 = 0; + mul_add_c(a[2], b[0], c3, c1, c2); + mul_add_c(a[1], b[1], c3, c1, c2); + mul_add_c(a[0], b[2], c3, c1, c2); + r[2] = c3; + c3 = 0; + mul_add_c(a[0], b[3], c1, c2, c3); + mul_add_c(a[1], b[2], c1, c2, c3); + mul_add_c(a[2], b[1], c1, c2, c3); + mul_add_c(a[3], b[0], c1, c2, c3); + r[3] = c1; + c1 = 0; + mul_add_c(a[3], b[1], c2, c3, c1); + mul_add_c(a[2], b[2], c2, c3, c1); + mul_add_c(a[1], b[3], c2, c3, c1); + r[4] = c2; + c2 = 0; + mul_add_c(a[2], b[3], c3, c1, c2); + mul_add_c(a[3], b[2], c3, c1, c2); + r[5] = c3; + c3 = 0; + mul_add_c(a[3], b[3], c1, c2, c3); + r[6] = c1; + r[7] = c2; +} + +void bn_sqr_comba8(BN_ULONG r[16], const BN_ULONG a[8]) { + BN_ULONG c1, c2, c3; + + c1 = 0; + c2 = 0; + c3 = 0; + sqr_add_c(a, 0, c1, c2, c3); + r[0] = c1; + c1 = 0; + sqr_add_c2(a, 1, 0, c2, c3, c1); + r[1] = c2; + c2 = 0; + sqr_add_c(a, 1, c3, c1, c2); + sqr_add_c2(a, 2, 0, c3, c1, c2); + r[2] = c3; + c3 = 0; + sqr_add_c2(a, 3, 0, c1, c2, c3); + sqr_add_c2(a, 2, 1, c1, c2, c3); + r[3] = c1; + c1 = 0; + sqr_add_c(a, 2, c2, c3, c1); + sqr_add_c2(a, 3, 1, c2, c3, c1); + sqr_add_c2(a, 4, 0, c2, c3, c1); + r[4] = c2; + c2 = 0; + sqr_add_c2(a, 5, 0, c3, c1, c2); + sqr_add_c2(a, 4, 1, c3, c1, c2); + sqr_add_c2(a, 3, 2, c3, c1, c2); + r[5] = c3; + c3 = 0; + sqr_add_c(a, 3, c1, c2, c3); + sqr_add_c2(a, 4, 2, c1, c2, c3); + sqr_add_c2(a, 5, 1, c1, c2, c3); + sqr_add_c2(a, 6, 0, c1, c2, c3); + r[6] = c1; + c1 = 0; + sqr_add_c2(a, 7, 0, c2, c3, c1); + sqr_add_c2(a, 6, 1, c2, c3, c1); + sqr_add_c2(a, 5, 2, c2, c3, c1); + sqr_add_c2(a, 4, 3, c2, c3, c1); + r[7] = c2; + c2 = 0; + sqr_add_c(a, 4, c3, c1, c2); + sqr_add_c2(a, 5, 3, c3, c1, c2); + sqr_add_c2(a, 6, 2, c3, c1, c2); + sqr_add_c2(a, 7, 1, c3, c1, c2); + r[8] = c3; + c3 = 0; + sqr_add_c2(a, 7, 2, c1, c2, c3); + sqr_add_c2(a, 6, 3, c1, c2, c3); + sqr_add_c2(a, 5, 4, c1, c2, c3); + r[9] = c1; + c1 = 0; + sqr_add_c(a, 5, c2, c3, c1); + sqr_add_c2(a, 6, 4, c2, c3, c1); + sqr_add_c2(a, 7, 3, c2, c3, c1); + r[10] = c2; + c2 = 0; + sqr_add_c2(a, 7, 4, c3, c1, c2); + sqr_add_c2(a, 6, 5, c3, c1, c2); + r[11] = c3; + c3 = 0; + sqr_add_c(a, 6, c1, c2, c3); + sqr_add_c2(a, 7, 5, c1, c2, c3); + r[12] = c1; + c1 = 0; + sqr_add_c2(a, 7, 6, c2, c3, c1); + r[13] = c2; + c2 = 0; + sqr_add_c(a, 7, c3, c1, c2); + r[14] = c3; + r[15] = c1; +} + +void bn_sqr_comba4(BN_ULONG r[8], const BN_ULONG a[4]) { + BN_ULONG c1, c2, c3; + + c1 = 0; + c2 = 0; + c3 = 0; + sqr_add_c(a, 0, c1, c2, c3); + r[0] = c1; + c1 = 0; + sqr_add_c2(a, 1, 0, c2, c3, c1); + r[1] = c2; + c2 = 0; + sqr_add_c(a, 1, c3, c1, c2); + sqr_add_c2(a, 2, 0, c3, c1, c2); + r[2] = c3; + c3 = 0; + sqr_add_c2(a, 3, 0, c1, c2, c3); + sqr_add_c2(a, 2, 1, c1, c2, c3); + r[3] = c1; + c1 = 0; + sqr_add_c(a, 2, c2, c3, c1); + sqr_add_c2(a, 3, 1, c2, c3, c1); + r[4] = c2; + c2 = 0; + sqr_add_c2(a, 3, 2, c3, c1, c2); + r[5] = c3; + c3 = 0; + sqr_add_c(a, 3, c1, c2, c3); + r[6] = c1; + r[7] = c2; +} + +#undef mul_add +#undef mul +#undef sqr +#undef mul_add_c +#undef sqr_add_c +#undef mul_add_c2 +#undef sqr_add_c2 + +#endif // !NO_ASM && X86_64 && (__GNUC__ || __clang__) diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/asm/x86_64-gcc.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/asm/x86_64-gcc.c.grpc_back new file mode 100644 index 0000000..30fff21 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/asm/x86_64-gcc.c.grpc_back @@ -0,0 +1,541 @@ +/* x86_64 BIGNUM accelerator version 0.1, December 2002. + * + * Implemented by Andy Polyakov for the OpenSSL + * project. + * + * Rights for redistribution and usage in source and binary forms are + * granted according to the OpenSSL license. Warranty of any kind is + * disclaimed. + * + * Q. Version 0.1? It doesn't sound like Andy, he used to assign real + * versions, like 1.0... + * A. Well, that's because this code is basically a quick-n-dirty + * proof-of-concept hack. As you can see it's implemented with + * inline assembler, which means that you're bound to GCC and that + * there might be enough room for further improvement. + * + * Q. Why inline assembler? + * A. x86_64 features own ABI which I'm not familiar with. This is + * why I decided to let the compiler take care of subroutine + * prologue/epilogue as well as register allocation. For reference. + * Win64 implements different ABI for AMD64, different from Linux. + * + * Q. How much faster does it get? + * A. 'apps/openssl speed rsa dsa' output with no-asm: + * + * sign verify sign/s verify/s + * rsa 512 bits 0.0006s 0.0001s 1683.8 18456.2 + * rsa 1024 bits 0.0028s 0.0002s 356.0 6407.0 + * rsa 2048 bits 0.0172s 0.0005s 58.0 1957.8 + * rsa 4096 bits 0.1155s 0.0018s 8.7 555.6 + * sign verify sign/s verify/s + * dsa 512 bits 0.0005s 0.0006s 2100.8 1768.3 + * dsa 1024 bits 0.0014s 0.0018s 692.3 559.2 + * dsa 2048 bits 0.0049s 0.0061s 204.7 165.0 + * + * 'apps/openssl speed rsa dsa' output with this module: + * + * sign verify sign/s verify/s + * rsa 512 bits 0.0004s 0.0000s 2767.1 33297.9 + * rsa 1024 bits 0.0012s 0.0001s 867.4 14674.7 + * rsa 2048 bits 0.0061s 0.0002s 164.0 5270.0 + * rsa 4096 bits 0.0384s 0.0006s 26.1 1650.8 + * sign verify sign/s verify/s + * dsa 512 bits 0.0002s 0.0003s 4442.2 3786.3 + * dsa 1024 bits 0.0005s 0.0007s 1835.1 1497.4 + * dsa 2048 bits 0.0016s 0.0020s 620.4 504.6 + * + * For the reference. IA-32 assembler implementation performs + * very much like 64-bit code compiled with no-asm on the same + * machine. + */ + +#include + +// TODO(davidben): Get this file working on MSVC x64. +#if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64) && \ + (defined(__GNUC__) || defined(__clang__)) + +#include "../internal.h" + + +#undef mul +#undef mul_add + +// "m"(a), "+m"(r) is the way to favor DirectPath µ-code; +// "g"(0) let the compiler to decide where does it +// want to keep the value of zero; +#define mul_add(r, a, word, carry) \ + do { \ + register BN_ULONG high, low; \ + __asm__("mulq %3" : "=a"(low), "=d"(high) : "a"(word), "m"(a) : "cc"); \ + __asm__("addq %2,%0; adcq %3,%1" \ + : "+r"(carry), "+d"(high) \ + : "a"(low), "g"(0) \ + : "cc"); \ + __asm__("addq %2,%0; adcq %3,%1" \ + : "+m"(r), "+d"(high) \ + : "r"(carry), "g"(0) \ + : "cc"); \ + (carry) = high; \ + } while (0) + +#define mul(r, a, word, carry) \ + do { \ + register BN_ULONG high, low; \ + __asm__("mulq %3" : "=a"(low), "=d"(high) : "a"(word), "g"(a) : "cc"); \ + __asm__("addq %2,%0; adcq %3,%1" \ + : "+r"(carry), "+d"(high) \ + : "a"(low), "g"(0) \ + : "cc"); \ + (r) = (carry); \ + (carry) = high; \ + } while (0) +#undef sqr +#define sqr(r0, r1, a) __asm__("mulq %2" : "=a"(r0), "=d"(r1) : "a"(a) : "cc"); + +BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, size_t num, + BN_ULONG w) { + BN_ULONG c1 = 0; + + if (num == 0) { + return (c1); + } + + 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; + } + if (num) { + mul_add(rp[0], ap[0], w, c1); + if (--num == 0) { + return c1; + } + mul_add(rp[1], ap[1], w, c1); + if (--num == 0) { + return c1; + } + mul_add(rp[2], ap[2], w, c1); + return c1; + } + + return c1; +} + +BN_ULONG bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, size_t num, + BN_ULONG w) { + BN_ULONG c1 = 0; + + if (num == 0) { + return c1; + } + + 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; + } + if (num) { + mul(rp[0], ap[0], w, c1); + if (--num == 0) { + return c1; + } + mul(rp[1], ap[1], w, c1); + if (--num == 0) { + return c1; + } + mul(rp[2], ap[2], w, c1); + } + return c1; +} + +void bn_sqr_words(BN_ULONG *r, const BN_ULONG *a, size_t n) { + if (n == 0) { + return; + } + + 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; + } + if (n) { + sqr(r[0], r[1], a[0]); + if (--n == 0) { + return; + } + sqr(r[2], r[3], a[1]); + if (--n == 0) { + return; + } + sqr(r[4], r[5], a[2]); + } +} + +BN_ULONG bn_add_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, + size_t n) { + BN_ULONG ret; + size_t i = 0; + + if (n == 0) { + return 0; + } + + __asm__ volatile ( + " subq %0,%0 \n" // clear carry + " jmp 1f \n" + ".p2align 4 \n" + "1:" + " movq (%4,%2,8),%0 \n" + " adcq (%5,%2,8),%0 \n" + " movq %0,(%3,%2,8) \n" + " lea 1(%2),%2 \n" + " dec %1 \n" + " jnz 1b \n" + " sbbq %0,%0 \n" + : "=&r"(ret), "+c"(n), "+r"(i) + : "r"(rp), "r"(ap), "r"(bp) + : "cc", "memory"); + + return ret & 1; +} + +BN_ULONG bn_sub_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, + size_t n) { + BN_ULONG ret; + size_t i = 0; + + if (n == 0) { + return 0; + } + + __asm__ volatile ( + " subq %0,%0 \n" // clear borrow + " jmp 1f \n" + ".p2align 4 \n" + "1:" + " movq (%4,%2,8),%0 \n" + " sbbq (%5,%2,8),%0 \n" + " movq %0,(%3,%2,8) \n" + " lea 1(%2),%2 \n" + " dec %1 \n" + " jnz 1b \n" + " sbbq %0,%0 \n" + : "=&r"(ret), "+c"(n), "+r"(i) + : "r"(rp), "r"(ap), "r"(bp) + : "cc", "memory"); + + return ret & 1; +} + +// 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) + +// Keep in mind that carrying into high part of multiplication result can not +// overflow, because it cannot be all-ones. +#define mul_add_c(a, b, c0, c1, c2) \ + do { \ + BN_ULONG t1, t2; \ + __asm__("mulq %3" : "=a"(t1), "=d"(t2) : "a"(a), "m"(b) : "cc"); \ + __asm__("addq %3,%0; adcq %4,%1; adcq %5,%2" \ + : "+r"(c0), "+r"(c1), "+r"(c2) \ + : "r"(t1), "r"(t2), "g"(0) \ + : "cc"); \ + } while (0) + +#define sqr_add_c(a, i, c0, c1, c2) \ + do { \ + BN_ULONG t1, t2; \ + __asm__("mulq %2" : "=a"(t1), "=d"(t2) : "a"((a)[i]) : "cc"); \ + __asm__("addq %3,%0; adcq %4,%1; adcq %5,%2" \ + : "+r"(c0), "+r"(c1), "+r"(c2) \ + : "r"(t1), "r"(t2), "g"(0) \ + : "cc"); \ + } while (0) + +#define mul_add_c2(a, b, c0, c1, c2) \ + do { \ + BN_ULONG t1, t2; \ + __asm__("mulq %3" : "=a"(t1), "=d"(t2) : "a"(a), "m"(b) : "cc"); \ + __asm__("addq %3,%0; adcq %4,%1; adcq %5,%2" \ + : "+r"(c0), "+r"(c1), "+r"(c2) \ + : "r"(t1), "r"(t2), "g"(0) \ + : "cc"); \ + __asm__("addq %3,%0; adcq %4,%1; adcq %5,%2" \ + : "+r"(c0), "+r"(c1), "+r"(c2) \ + : "r"(t1), "r"(t2), "g"(0) \ + : "cc"); \ + } while (0) + +#define sqr_add_c2(a, i, j, c0, c1, c2) mul_add_c2((a)[i], (a)[j], c0, c1, c2) + +void bn_mul_comba8(BN_ULONG r[16], const BN_ULONG a[8], const BN_ULONG b[8]) { + BN_ULONG c1, c2, c3; + + c1 = 0; + c2 = 0; + c3 = 0; + mul_add_c(a[0], b[0], c1, c2, c3); + r[0] = c1; + c1 = 0; + mul_add_c(a[0], b[1], c2, c3, c1); + mul_add_c(a[1], b[0], c2, c3, c1); + r[1] = c2; + c2 = 0; + mul_add_c(a[2], b[0], c3, c1, c2); + mul_add_c(a[1], b[1], c3, c1, c2); + mul_add_c(a[0], b[2], c3, c1, c2); + r[2] = c3; + c3 = 0; + mul_add_c(a[0], b[3], c1, c2, c3); + mul_add_c(a[1], b[2], c1, c2, c3); + mul_add_c(a[2], b[1], c1, c2, c3); + mul_add_c(a[3], b[0], c1, c2, c3); + r[3] = c1; + c1 = 0; + mul_add_c(a[4], b[0], c2, c3, c1); + mul_add_c(a[3], b[1], c2, c3, c1); + mul_add_c(a[2], b[2], c2, c3, c1); + mul_add_c(a[1], b[3], c2, c3, c1); + mul_add_c(a[0], b[4], c2, c3, c1); + r[4] = c2; + c2 = 0; + mul_add_c(a[0], b[5], c3, c1, c2); + mul_add_c(a[1], b[4], c3, c1, c2); + mul_add_c(a[2], b[3], c3, c1, c2); + mul_add_c(a[3], b[2], c3, c1, c2); + mul_add_c(a[4], b[1], c3, c1, c2); + mul_add_c(a[5], b[0], c3, c1, c2); + r[5] = c3; + c3 = 0; + mul_add_c(a[6], b[0], c1, c2, c3); + mul_add_c(a[5], b[1], c1, c2, c3); + mul_add_c(a[4], b[2], c1, c2, c3); + mul_add_c(a[3], b[3], c1, c2, c3); + mul_add_c(a[2], b[4], c1, c2, c3); + mul_add_c(a[1], b[5], c1, c2, c3); + mul_add_c(a[0], b[6], c1, c2, c3); + r[6] = c1; + c1 = 0; + mul_add_c(a[0], b[7], c2, c3, c1); + mul_add_c(a[1], b[6], c2, c3, c1); + mul_add_c(a[2], b[5], c2, c3, c1); + mul_add_c(a[3], b[4], c2, c3, c1); + mul_add_c(a[4], b[3], c2, c3, c1); + mul_add_c(a[5], b[2], c2, c3, c1); + mul_add_c(a[6], b[1], c2, c3, c1); + mul_add_c(a[7], b[0], c2, c3, c1); + r[7] = c2; + c2 = 0; + mul_add_c(a[7], b[1], c3, c1, c2); + mul_add_c(a[6], b[2], c3, c1, c2); + mul_add_c(a[5], b[3], c3, c1, c2); + mul_add_c(a[4], b[4], c3, c1, c2); + mul_add_c(a[3], b[5], c3, c1, c2); + mul_add_c(a[2], b[6], c3, c1, c2); + mul_add_c(a[1], b[7], c3, c1, c2); + r[8] = c3; + c3 = 0; + mul_add_c(a[2], b[7], c1, c2, c3); + mul_add_c(a[3], b[6], c1, c2, c3); + mul_add_c(a[4], b[5], c1, c2, c3); + mul_add_c(a[5], b[4], c1, c2, c3); + mul_add_c(a[6], b[3], c1, c2, c3); + mul_add_c(a[7], b[2], c1, c2, c3); + r[9] = c1; + c1 = 0; + mul_add_c(a[7], b[3], c2, c3, c1); + mul_add_c(a[6], b[4], c2, c3, c1); + mul_add_c(a[5], b[5], c2, c3, c1); + mul_add_c(a[4], b[6], c2, c3, c1); + mul_add_c(a[3], b[7], c2, c3, c1); + r[10] = c2; + c2 = 0; + mul_add_c(a[4], b[7], c3, c1, c2); + mul_add_c(a[5], b[6], c3, c1, c2); + mul_add_c(a[6], b[5], c3, c1, c2); + mul_add_c(a[7], b[4], c3, c1, c2); + r[11] = c3; + c3 = 0; + mul_add_c(a[7], b[5], c1, c2, c3); + mul_add_c(a[6], b[6], c1, c2, c3); + mul_add_c(a[5], b[7], c1, c2, c3); + r[12] = c1; + c1 = 0; + mul_add_c(a[6], b[7], c2, c3, c1); + mul_add_c(a[7], b[6], c2, c3, c1); + r[13] = c2; + c2 = 0; + mul_add_c(a[7], b[7], c3, c1, c2); + r[14] = c3; + r[15] = c1; +} + +void bn_mul_comba4(BN_ULONG r[8], const BN_ULONG a[4], const BN_ULONG b[4]) { + BN_ULONG c1, c2, c3; + + c1 = 0; + c2 = 0; + c3 = 0; + mul_add_c(a[0], b[0], c1, c2, c3); + r[0] = c1; + c1 = 0; + mul_add_c(a[0], b[1], c2, c3, c1); + mul_add_c(a[1], b[0], c2, c3, c1); + r[1] = c2; + c2 = 0; + mul_add_c(a[2], b[0], c3, c1, c2); + mul_add_c(a[1], b[1], c3, c1, c2); + mul_add_c(a[0], b[2], c3, c1, c2); + r[2] = c3; + c3 = 0; + mul_add_c(a[0], b[3], c1, c2, c3); + mul_add_c(a[1], b[2], c1, c2, c3); + mul_add_c(a[2], b[1], c1, c2, c3); + mul_add_c(a[3], b[0], c1, c2, c3); + r[3] = c1; + c1 = 0; + mul_add_c(a[3], b[1], c2, c3, c1); + mul_add_c(a[2], b[2], c2, c3, c1); + mul_add_c(a[1], b[3], c2, c3, c1); + r[4] = c2; + c2 = 0; + mul_add_c(a[2], b[3], c3, c1, c2); + mul_add_c(a[3], b[2], c3, c1, c2); + r[5] = c3; + c3 = 0; + mul_add_c(a[3], b[3], c1, c2, c3); + r[6] = c1; + r[7] = c2; +} + +void bn_sqr_comba8(BN_ULONG r[16], const BN_ULONG a[8]) { + BN_ULONG c1, c2, c3; + + c1 = 0; + c2 = 0; + c3 = 0; + sqr_add_c(a, 0, c1, c2, c3); + r[0] = c1; + c1 = 0; + sqr_add_c2(a, 1, 0, c2, c3, c1); + r[1] = c2; + c2 = 0; + sqr_add_c(a, 1, c3, c1, c2); + sqr_add_c2(a, 2, 0, c3, c1, c2); + r[2] = c3; + c3 = 0; + sqr_add_c2(a, 3, 0, c1, c2, c3); + sqr_add_c2(a, 2, 1, c1, c2, c3); + r[3] = c1; + c1 = 0; + sqr_add_c(a, 2, c2, c3, c1); + sqr_add_c2(a, 3, 1, c2, c3, c1); + sqr_add_c2(a, 4, 0, c2, c3, c1); + r[4] = c2; + c2 = 0; + sqr_add_c2(a, 5, 0, c3, c1, c2); + sqr_add_c2(a, 4, 1, c3, c1, c2); + sqr_add_c2(a, 3, 2, c3, c1, c2); + r[5] = c3; + c3 = 0; + sqr_add_c(a, 3, c1, c2, c3); + sqr_add_c2(a, 4, 2, c1, c2, c3); + sqr_add_c2(a, 5, 1, c1, c2, c3); + sqr_add_c2(a, 6, 0, c1, c2, c3); + r[6] = c1; + c1 = 0; + sqr_add_c2(a, 7, 0, c2, c3, c1); + sqr_add_c2(a, 6, 1, c2, c3, c1); + sqr_add_c2(a, 5, 2, c2, c3, c1); + sqr_add_c2(a, 4, 3, c2, c3, c1); + r[7] = c2; + c2 = 0; + sqr_add_c(a, 4, c3, c1, c2); + sqr_add_c2(a, 5, 3, c3, c1, c2); + sqr_add_c2(a, 6, 2, c3, c1, c2); + sqr_add_c2(a, 7, 1, c3, c1, c2); + r[8] = c3; + c3 = 0; + sqr_add_c2(a, 7, 2, c1, c2, c3); + sqr_add_c2(a, 6, 3, c1, c2, c3); + sqr_add_c2(a, 5, 4, c1, c2, c3); + r[9] = c1; + c1 = 0; + sqr_add_c(a, 5, c2, c3, c1); + sqr_add_c2(a, 6, 4, c2, c3, c1); + sqr_add_c2(a, 7, 3, c2, c3, c1); + r[10] = c2; + c2 = 0; + sqr_add_c2(a, 7, 4, c3, c1, c2); + sqr_add_c2(a, 6, 5, c3, c1, c2); + r[11] = c3; + c3 = 0; + sqr_add_c(a, 6, c1, c2, c3); + sqr_add_c2(a, 7, 5, c1, c2, c3); + r[12] = c1; + c1 = 0; + sqr_add_c2(a, 7, 6, c2, c3, c1); + r[13] = c2; + c2 = 0; + sqr_add_c(a, 7, c3, c1, c2); + r[14] = c3; + r[15] = c1; +} + +void bn_sqr_comba4(BN_ULONG r[8], const BN_ULONG a[4]) { + BN_ULONG c1, c2, c3; + + c1 = 0; + c2 = 0; + c3 = 0; + sqr_add_c(a, 0, c1, c2, c3); + r[0] = c1; + c1 = 0; + sqr_add_c2(a, 1, 0, c2, c3, c1); + r[1] = c2; + c2 = 0; + sqr_add_c(a, 1, c3, c1, c2); + sqr_add_c2(a, 2, 0, c3, c1, c2); + r[2] = c3; + c3 = 0; + sqr_add_c2(a, 3, 0, c1, c2, c3); + sqr_add_c2(a, 2, 1, c1, c2, c3); + r[3] = c1; + c1 = 0; + sqr_add_c(a, 2, c2, c3, c1); + sqr_add_c2(a, 3, 1, c2, c3, c1); + r[4] = c2; + c2 = 0; + sqr_add_c2(a, 3, 2, c3, c1, c2); + r[5] = c3; + c3 = 0; + sqr_add_c(a, 3, c1, c2, c3); + r[6] = c1; + r[7] = c2; +} + +#undef mul_add +#undef mul +#undef sqr +#undef mul_add_c +#undef sqr_add_c +#undef mul_add_c2 +#undef sqr_add_c2 + +#endif // !NO_ASM && X86_64 && (__GNUC__ || __clang__) diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/bn.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/bn.c new file mode 100644 index 0000000..27c2ee5 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/bn.c @@ -0,0 +1,428 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 + +#include "internal.h" +#include "../delocate.h" + + +BIGNUM *BN_new(void) { + BIGNUM *bn = OPENSSL_malloc(sizeof(BIGNUM)); + + if (bn == NULL) { + OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE); + return NULL; + } + + OPENSSL_memset(bn, 0, sizeof(BIGNUM)); + bn->flags = BN_FLG_MALLOCED; + + return bn; +} + +void BN_init(BIGNUM *bn) { + OPENSSL_memset(bn, 0, sizeof(BIGNUM)); +} + +void BN_free(BIGNUM *bn) { + if (bn == NULL) { + return; + } + + if ((bn->flags & BN_FLG_STATIC_DATA) == 0) { + OPENSSL_free(bn->d); + } + + if (bn->flags & BN_FLG_MALLOCED) { + OPENSSL_free(bn); + } else { + bn->d = NULL; + } +} + +void BN_clear_free(BIGNUM *bn) { + char should_free; + + if (bn == NULL) { + return; + } + + if (bn->d != NULL) { + if ((bn->flags & BN_FLG_STATIC_DATA) == 0) { + OPENSSL_free(bn->d); + } else { + OPENSSL_cleanse(bn->d, bn->dmax * sizeof(bn->d[0])); + } + } + + should_free = (bn->flags & BN_FLG_MALLOCED) != 0; + if (should_free) { + OPENSSL_free(bn); + } else { + OPENSSL_cleanse(bn, sizeof(BIGNUM)); + } +} + +BIGNUM *BN_dup(const BIGNUM *src) { + BIGNUM *copy; + + if (src == NULL) { + return NULL; + } + + copy = BN_new(); + if (copy == NULL) { + return NULL; + } + + if (!BN_copy(copy, src)) { + BN_free(copy); + return NULL; + } + + return copy; +} + +BIGNUM *BN_copy(BIGNUM *dest, const BIGNUM *src) { + if (src == dest) { + return dest; + } + + if (!bn_wexpand(dest, src->width)) { + return NULL; + } + + OPENSSL_memcpy(dest->d, src->d, sizeof(src->d[0]) * src->width); + + dest->width = src->width; + dest->neg = src->neg; + return dest; +} + +void BN_clear(BIGNUM *bn) { + if (bn->d != NULL) { + OPENSSL_memset(bn->d, 0, bn->dmax * sizeof(bn->d[0])); + } + + bn->width = 0; + bn->neg = 0; +} + +DEFINE_METHOD_FUNCTION(BIGNUM, BN_value_one) { + static const BN_ULONG kOneLimbs[1] = { 1 }; + out->d = (BN_ULONG*) kOneLimbs; + out->width = 1; + out->dmax = 1; + out->neg = 0; + out->flags = BN_FLG_STATIC_DATA; +} + +// BN_num_bits_word returns the minimum number of bits needed to represent the +// value in |l|. +unsigned BN_num_bits_word(BN_ULONG l) { + // |BN_num_bits| is often called on RSA prime factors. These have public bit + // lengths, but all bits beyond the high bit are secret, so count bits in + // constant time. + BN_ULONG x, mask; + int bits = (l != 0); + +#if BN_BITS2 > 32 + // Look at the upper half of |x|. |x| is at most 64 bits long. + x = l >> 32; + // Set |mask| to all ones if |x| (the top 32 bits of |l|) is non-zero and all + // all zeros otherwise. + mask = 0u - x; + mask = (0u - (mask >> (BN_BITS2 - 1))); + // If |x| is non-zero, the lower half is included in the bit count in full, + // and we count the upper half. Otherwise, we count the lower half. + bits += 32 & mask; + l ^= (x ^ l) & mask; // |l| is |x| if |mask| and remains |l| otherwise. +#endif + + // The remaining blocks are analogous iterations at lower powers of two. + x = l >> 16; + mask = 0u - x; + mask = (0u - (mask >> (BN_BITS2 - 1))); + bits += 16 & mask; + l ^= (x ^ l) & mask; + + x = l >> 8; + mask = 0u - x; + mask = (0u - (mask >> (BN_BITS2 - 1))); + bits += 8 & mask; + l ^= (x ^ l) & mask; + + x = l >> 4; + mask = 0u - x; + mask = (0u - (mask >> (BN_BITS2 - 1))); + bits += 4 & mask; + l ^= (x ^ l) & mask; + + x = l >> 2; + mask = 0u - x; + mask = (0u - (mask >> (BN_BITS2 - 1))); + bits += 2 & mask; + l ^= (x ^ l) & mask; + + x = l >> 1; + mask = 0u - x; + mask = (0u - (mask >> (BN_BITS2 - 1))); + bits += 1 & mask; + + return bits; +} + +unsigned BN_num_bits(const BIGNUM *bn) { + const int width = bn_minimal_width(bn); + if (width == 0) { + return 0; + } + + return (width - 1) * BN_BITS2 + BN_num_bits_word(bn->d[width - 1]); +} + +unsigned BN_num_bytes(const BIGNUM *bn) { + return (BN_num_bits(bn) + 7) / 8; +} + +void BN_zero(BIGNUM *bn) { + bn->width = bn->neg = 0; +} + +int BN_one(BIGNUM *bn) { + return BN_set_word(bn, 1); +} + +int BN_set_word(BIGNUM *bn, BN_ULONG value) { + if (value == 0) { + BN_zero(bn); + return 1; + } + + if (!bn_wexpand(bn, 1)) { + return 0; + } + + bn->neg = 0; + bn->d[0] = value; + bn->width = 1; + return 1; +} + +int BN_set_u64(BIGNUM *bn, uint64_t value) { +#if BN_BITS2 == 64 + return BN_set_word(bn, value); +#elif BN_BITS2 == 32 + if (value <= BN_MASK2) { + return BN_set_word(bn, (BN_ULONG)value); + } + + if (!bn_wexpand(bn, 2)) { + return 0; + } + + bn->neg = 0; + bn->d[0] = (BN_ULONG)value; + bn->d[1] = (BN_ULONG)(value >> 32); + bn->width = 2; + return 1; +#else +#error "BN_BITS2 must be 32 or 64." +#endif +} + +int bn_set_words(BIGNUM *bn, const BN_ULONG *words, size_t num) { + if (!bn_wexpand(bn, num)) { + return 0; + } + OPENSSL_memmove(bn->d, words, num * sizeof(BN_ULONG)); + // |bn_wexpand| verified that |num| isn't too large. + bn->width = (int)num; + bn->neg = 0; + return 1; +} + +int bn_fits_in_words(const BIGNUM *bn, size_t num) { + // All words beyond |num| must be zero. + BN_ULONG mask = 0; + for (size_t i = num; i < (size_t)bn->width; i++) { + mask |= bn->d[i]; + } + return mask == 0; +} + +int bn_copy_words(BN_ULONG *out, size_t num, const BIGNUM *bn) { + if (bn->neg) { + OPENSSL_PUT_ERROR(BN, BN_R_NEGATIVE_NUMBER); + return 0; + } + + size_t width = (size_t)bn->width; + if (width > num) { + if (!bn_fits_in_words(bn, num)) { + OPENSSL_PUT_ERROR(BN, BN_R_BIGNUM_TOO_LONG); + return 0; + } + width = num; + } + + OPENSSL_memset(out, 0, sizeof(BN_ULONG) * num); + OPENSSL_memcpy(out, bn->d, sizeof(BN_ULONG) * width); + return 1; +} + +int BN_is_negative(const BIGNUM *bn) { + return bn->neg != 0; +} + +void BN_set_negative(BIGNUM *bn, int sign) { + if (sign && !BN_is_zero(bn)) { + bn->neg = 1; + } else { + bn->neg = 0; + } +} + +int bn_wexpand(BIGNUM *bn, size_t words) { + BN_ULONG *a; + + if (words <= (size_t)bn->dmax) { + return 1; + } + + if (words > (INT_MAX / (4 * BN_BITS2))) { + OPENSSL_PUT_ERROR(BN, BN_R_BIGNUM_TOO_LONG); + return 0; + } + + if (bn->flags & BN_FLG_STATIC_DATA) { + OPENSSL_PUT_ERROR(BN, BN_R_EXPAND_ON_STATIC_BIGNUM_DATA); + return 0; + } + + a = OPENSSL_malloc(sizeof(BN_ULONG) * words); + if (a == NULL) { + OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE); + return 0; + } + + OPENSSL_memcpy(a, bn->d, sizeof(BN_ULONG) * bn->width); + + OPENSSL_free(bn->d); + bn->d = a; + bn->dmax = (int)words; + + return 1; +} + +int bn_expand(BIGNUM *bn, size_t bits) { + if (bits + BN_BITS2 - 1 < bits) { + OPENSSL_PUT_ERROR(BN, BN_R_BIGNUM_TOO_LONG); + return 0; + } + return bn_wexpand(bn, (bits+BN_BITS2-1)/BN_BITS2); +} + +int bn_resize_words(BIGNUM *bn, size_t words) { + if ((size_t)bn->width <= words) { + if (!bn_wexpand(bn, words)) { + return 0; + } + OPENSSL_memset(bn->d + bn->width, 0, + (words - bn->width) * sizeof(BN_ULONG)); + bn->width = words; + return 1; + } + + // All words beyond the new width must be zero. + if (!bn_fits_in_words(bn, words)) { + OPENSSL_PUT_ERROR(BN, BN_R_BIGNUM_TOO_LONG); + return 0; + } + bn->width = words; + return 1; +} + +void bn_select_words(BN_ULONG *r, BN_ULONG mask, const BN_ULONG *a, + const BN_ULONG *b, size_t num) { + for (size_t i = 0; i < num; i++) { + OPENSSL_COMPILE_ASSERT(sizeof(BN_ULONG) <= sizeof(crypto_word_t), + crypto_word_t_too_small); + r[i] = constant_time_select_w(mask, a[i], b[i]); + } +} + +int bn_minimal_width(const BIGNUM *bn) { + int ret = bn->width; + while (ret > 0 && bn->d[ret - 1] == 0) { + ret--; + } + return ret; +} + +void bn_set_minimal_width(BIGNUM *bn) { + bn->width = bn_minimal_width(bn); + if (bn->width == 0) { + bn->neg = 0; + } +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/bn.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/bn.c.grpc_back new file mode 100644 index 0000000..c020d96 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/bn.c.grpc_back @@ -0,0 +1,428 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 + +#include "internal.h" +#include "../delocate.h" + + +BIGNUM *BN_new(void) { + BIGNUM *bn = OPENSSL_malloc(sizeof(BIGNUM)); + + if (bn == NULL) { + OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE); + return NULL; + } + + OPENSSL_memset(bn, 0, sizeof(BIGNUM)); + bn->flags = BN_FLG_MALLOCED; + + return bn; +} + +void BN_init(BIGNUM *bn) { + OPENSSL_memset(bn, 0, sizeof(BIGNUM)); +} + +void BN_free(BIGNUM *bn) { + if (bn == NULL) { + return; + } + + if ((bn->flags & BN_FLG_STATIC_DATA) == 0) { + OPENSSL_free(bn->d); + } + + if (bn->flags & BN_FLG_MALLOCED) { + OPENSSL_free(bn); + } else { + bn->d = NULL; + } +} + +void BN_clear_free(BIGNUM *bn) { + char should_free; + + if (bn == NULL) { + return; + } + + if (bn->d != NULL) { + if ((bn->flags & BN_FLG_STATIC_DATA) == 0) { + OPENSSL_free(bn->d); + } else { + OPENSSL_cleanse(bn->d, bn->dmax * sizeof(bn->d[0])); + } + } + + should_free = (bn->flags & BN_FLG_MALLOCED) != 0; + if (should_free) { + OPENSSL_free(bn); + } else { + OPENSSL_cleanse(bn, sizeof(BIGNUM)); + } +} + +BIGNUM *BN_dup(const BIGNUM *src) { + BIGNUM *copy; + + if (src == NULL) { + return NULL; + } + + copy = BN_new(); + if (copy == NULL) { + return NULL; + } + + if (!BN_copy(copy, src)) { + BN_free(copy); + return NULL; + } + + return copy; +} + +BIGNUM *BN_copy(BIGNUM *dest, const BIGNUM *src) { + if (src == dest) { + return dest; + } + + if (!bn_wexpand(dest, src->width)) { + return NULL; + } + + OPENSSL_memcpy(dest->d, src->d, sizeof(src->d[0]) * src->width); + + dest->width = src->width; + dest->neg = src->neg; + return dest; +} + +void BN_clear(BIGNUM *bn) { + if (bn->d != NULL) { + OPENSSL_memset(bn->d, 0, bn->dmax * sizeof(bn->d[0])); + } + + bn->width = 0; + bn->neg = 0; +} + +DEFINE_METHOD_FUNCTION(BIGNUM, BN_value_one) { + static const BN_ULONG kOneLimbs[1] = { 1 }; + out->d = (BN_ULONG*) kOneLimbs; + out->width = 1; + out->dmax = 1; + out->neg = 0; + out->flags = BN_FLG_STATIC_DATA; +} + +// BN_num_bits_word returns the minimum number of bits needed to represent the +// value in |l|. +unsigned BN_num_bits_word(BN_ULONG l) { + // |BN_num_bits| is often called on RSA prime factors. These have public bit + // lengths, but all bits beyond the high bit are secret, so count bits in + // constant time. + BN_ULONG x, mask; + int bits = (l != 0); + +#if BN_BITS2 > 32 + // Look at the upper half of |x|. |x| is at most 64 bits long. + x = l >> 32; + // Set |mask| to all ones if |x| (the top 32 bits of |l|) is non-zero and all + // all zeros otherwise. + mask = 0u - x; + mask = (0u - (mask >> (BN_BITS2 - 1))); + // If |x| is non-zero, the lower half is included in the bit count in full, + // and we count the upper half. Otherwise, we count the lower half. + bits += 32 & mask; + l ^= (x ^ l) & mask; // |l| is |x| if |mask| and remains |l| otherwise. +#endif + + // The remaining blocks are analogous iterations at lower powers of two. + x = l >> 16; + mask = 0u - x; + mask = (0u - (mask >> (BN_BITS2 - 1))); + bits += 16 & mask; + l ^= (x ^ l) & mask; + + x = l >> 8; + mask = 0u - x; + mask = (0u - (mask >> (BN_BITS2 - 1))); + bits += 8 & mask; + l ^= (x ^ l) & mask; + + x = l >> 4; + mask = 0u - x; + mask = (0u - (mask >> (BN_BITS2 - 1))); + bits += 4 & mask; + l ^= (x ^ l) & mask; + + x = l >> 2; + mask = 0u - x; + mask = (0u - (mask >> (BN_BITS2 - 1))); + bits += 2 & mask; + l ^= (x ^ l) & mask; + + x = l >> 1; + mask = 0u - x; + mask = (0u - (mask >> (BN_BITS2 - 1))); + bits += 1 & mask; + + return bits; +} + +unsigned BN_num_bits(const BIGNUM *bn) { + const int width = bn_minimal_width(bn); + if (width == 0) { + return 0; + } + + return (width - 1) * BN_BITS2 + BN_num_bits_word(bn->d[width - 1]); +} + +unsigned BN_num_bytes(const BIGNUM *bn) { + return (BN_num_bits(bn) + 7) / 8; +} + +void BN_zero(BIGNUM *bn) { + bn->width = bn->neg = 0; +} + +int BN_one(BIGNUM *bn) { + return BN_set_word(bn, 1); +} + +int BN_set_word(BIGNUM *bn, BN_ULONG value) { + if (value == 0) { + BN_zero(bn); + return 1; + } + + if (!bn_wexpand(bn, 1)) { + return 0; + } + + bn->neg = 0; + bn->d[0] = value; + bn->width = 1; + return 1; +} + +int BN_set_u64(BIGNUM *bn, uint64_t value) { +#if BN_BITS2 == 64 + return BN_set_word(bn, value); +#elif BN_BITS2 == 32 + if (value <= BN_MASK2) { + return BN_set_word(bn, (BN_ULONG)value); + } + + if (!bn_wexpand(bn, 2)) { + return 0; + } + + bn->neg = 0; + bn->d[0] = (BN_ULONG)value; + bn->d[1] = (BN_ULONG)(value >> 32); + bn->width = 2; + return 1; +#else +#error "BN_BITS2 must be 32 or 64." +#endif +} + +int bn_set_words(BIGNUM *bn, const BN_ULONG *words, size_t num) { + if (!bn_wexpand(bn, num)) { + return 0; + } + OPENSSL_memmove(bn->d, words, num * sizeof(BN_ULONG)); + // |bn_wexpand| verified that |num| isn't too large. + bn->width = (int)num; + bn->neg = 0; + return 1; +} + +int bn_fits_in_words(const BIGNUM *bn, size_t num) { + // All words beyond |num| must be zero. + BN_ULONG mask = 0; + for (size_t i = num; i < (size_t)bn->width; i++) { + mask |= bn->d[i]; + } + return mask == 0; +} + +int bn_copy_words(BN_ULONG *out, size_t num, const BIGNUM *bn) { + if (bn->neg) { + OPENSSL_PUT_ERROR(BN, BN_R_NEGATIVE_NUMBER); + return 0; + } + + size_t width = (size_t)bn->width; + if (width > num) { + if (!bn_fits_in_words(bn, num)) { + OPENSSL_PUT_ERROR(BN, BN_R_BIGNUM_TOO_LONG); + return 0; + } + width = num; + } + + OPENSSL_memset(out, 0, sizeof(BN_ULONG) * num); + OPENSSL_memcpy(out, bn->d, sizeof(BN_ULONG) * width); + return 1; +} + +int BN_is_negative(const BIGNUM *bn) { + return bn->neg != 0; +} + +void BN_set_negative(BIGNUM *bn, int sign) { + if (sign && !BN_is_zero(bn)) { + bn->neg = 1; + } else { + bn->neg = 0; + } +} + +int bn_wexpand(BIGNUM *bn, size_t words) { + BN_ULONG *a; + + if (words <= (size_t)bn->dmax) { + return 1; + } + + if (words > (INT_MAX / (4 * BN_BITS2))) { + OPENSSL_PUT_ERROR(BN, BN_R_BIGNUM_TOO_LONG); + return 0; + } + + if (bn->flags & BN_FLG_STATIC_DATA) { + OPENSSL_PUT_ERROR(BN, BN_R_EXPAND_ON_STATIC_BIGNUM_DATA); + return 0; + } + + a = OPENSSL_malloc(sizeof(BN_ULONG) * words); + if (a == NULL) { + OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE); + return 0; + } + + OPENSSL_memcpy(a, bn->d, sizeof(BN_ULONG) * bn->width); + + OPENSSL_free(bn->d); + bn->d = a; + bn->dmax = (int)words; + + return 1; +} + +int bn_expand(BIGNUM *bn, size_t bits) { + if (bits + BN_BITS2 - 1 < bits) { + OPENSSL_PUT_ERROR(BN, BN_R_BIGNUM_TOO_LONG); + return 0; + } + return bn_wexpand(bn, (bits+BN_BITS2-1)/BN_BITS2); +} + +int bn_resize_words(BIGNUM *bn, size_t words) { + if ((size_t)bn->width <= words) { + if (!bn_wexpand(bn, words)) { + return 0; + } + OPENSSL_memset(bn->d + bn->width, 0, + (words - bn->width) * sizeof(BN_ULONG)); + bn->width = words; + return 1; + } + + // All words beyond the new width must be zero. + if (!bn_fits_in_words(bn, words)) { + OPENSSL_PUT_ERROR(BN, BN_R_BIGNUM_TOO_LONG); + return 0; + } + bn->width = words; + return 1; +} + +void bn_select_words(BN_ULONG *r, BN_ULONG mask, const BN_ULONG *a, + const BN_ULONG *b, size_t num) { + for (size_t i = 0; i < num; i++) { + OPENSSL_COMPILE_ASSERT(sizeof(BN_ULONG) <= sizeof(crypto_word_t), + crypto_word_t_too_small); + r[i] = constant_time_select_w(mask, a[i], b[i]); + } +} + +int bn_minimal_width(const BIGNUM *bn) { + int ret = bn->width; + while (ret > 0 && bn->d[ret - 1] == 0) { + ret--; + } + return ret; +} + +void bn_set_minimal_width(BIGNUM *bn) { + bn->width = bn_minimal_width(bn); + if (bn->width == 0) { + bn->neg = 0; + } +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/bytes.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/bytes.c new file mode 100644 index 0000000..a2fde19 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/bytes.c @@ -0,0 +1,230 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 "internal.h" + + +BIGNUM *BN_bin2bn(const uint8_t *in, size_t len, BIGNUM *ret) { + size_t num_words; + unsigned m; + BN_ULONG word = 0; + BIGNUM *bn = NULL; + + if (ret == NULL) { + ret = bn = BN_new(); + } + + if (ret == NULL) { + return NULL; + } + + if (len == 0) { + ret->width = 0; + return ret; + } + + num_words = ((len - 1) / BN_BYTES) + 1; + m = (len - 1) % BN_BYTES; + if (!bn_wexpand(ret, num_words)) { + if (bn) { + BN_free(bn); + } + return NULL; + } + + // |bn_wexpand| must check bounds on |num_words| to write it into + // |ret->dmax|. + assert(num_words <= INT_MAX); + ret->width = (int)num_words; + ret->neg = 0; + + while (len--) { + word = (word << 8) | *(in++); + if (m-- == 0) { + ret->d[--num_words] = word; + word = 0; + m = BN_BYTES - 1; + } + } + + return ret; +} + +BIGNUM *BN_le2bn(const uint8_t *in, size_t len, BIGNUM *ret) { + BIGNUM *bn = NULL; + if (ret == NULL) { + bn = BN_new(); + ret = bn; + } + + if (ret == NULL) { + return NULL; + } + + if (len == 0) { + ret->width = 0; + ret->neg = 0; + return ret; + } + + // Reserve enough space in |ret|. + size_t num_words = ((len - 1) / BN_BYTES) + 1; + if (!bn_wexpand(ret, num_words)) { + BN_free(bn); + return NULL; + } + ret->width = num_words; + + // Make sure the top bytes will be zeroed. + ret->d[num_words - 1] = 0; + + // We only support little-endian platforms, so we can simply memcpy the + // internal representation. + OPENSSL_memcpy(ret->d, in, len); + return ret; +} + +size_t BN_bn2bin(const BIGNUM *in, uint8_t *out) { + size_t n, i; + BN_ULONG l; + + n = i = BN_num_bytes(in); + while (i--) { + l = in->d[i / BN_BYTES]; + *(out++) = (unsigned char)(l >> (8 * (i % BN_BYTES))) & 0xff; + } + return n; +} + +static int fits_in_bytes(const uint8_t *bytes, size_t num_bytes, size_t len) { + uint8_t mask = 0; + for (size_t i = len; i < num_bytes; i++) { + mask |= bytes[i]; + } + return mask == 0; +} + +int BN_bn2le_padded(uint8_t *out, size_t len, const BIGNUM *in) { + const uint8_t *bytes = (const uint8_t *)in->d; + size_t num_bytes = in->width * BN_BYTES; + if (len < num_bytes) { + if (!fits_in_bytes(bytes, num_bytes, len)) { + return 0; + } + num_bytes = len; + } + + // We only support little-endian platforms, so we can simply memcpy into the + // internal representation. + OPENSSL_memcpy(out, bytes, num_bytes); + // Pad out the rest of the buffer with zeroes. + OPENSSL_memset(out + num_bytes, 0, len - num_bytes); + return 1; +} + +int BN_bn2bin_padded(uint8_t *out, size_t len, const BIGNUM *in) { + const uint8_t *bytes = (const uint8_t *)in->d; + size_t num_bytes = in->width * BN_BYTES; + if (len < num_bytes) { + if (!fits_in_bytes(bytes, num_bytes, len)) { + return 0; + } + num_bytes = len; + } + + // We only support little-endian platforms, so we can simply write the buffer + // in reverse. + for (size_t i = 0; i < num_bytes; i++) { + out[len - i - 1] = bytes[i]; + } + // Pad out the rest of the buffer with zeroes. + OPENSSL_memset(out, 0, len - num_bytes); + return 1; +} + +BN_ULONG BN_get_word(const BIGNUM *bn) { + switch (bn_minimal_width(bn)) { + case 0: + return 0; + case 1: + return bn->d[0]; + default: + return BN_MASK2; + } +} + +int BN_get_u64(const BIGNUM *bn, uint64_t *out) { + switch (bn_minimal_width(bn)) { + case 0: + *out = 0; + return 1; + case 1: + *out = bn->d[0]; + return 1; +#if defined(OPENSSL_32_BIT) + case 2: + *out = (uint64_t) bn->d[0] | (((uint64_t) bn->d[1]) << 32); + return 1; +#endif + default: + return 0; + } +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/bytes.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/bytes.c.grpc_back new file mode 100644 index 0000000..56241e3 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/bytes.c.grpc_back @@ -0,0 +1,230 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 "internal.h" + + +BIGNUM *BN_bin2bn(const uint8_t *in, size_t len, BIGNUM *ret) { + size_t num_words; + unsigned m; + BN_ULONG word = 0; + BIGNUM *bn = NULL; + + if (ret == NULL) { + ret = bn = BN_new(); + } + + if (ret == NULL) { + return NULL; + } + + if (len == 0) { + ret->width = 0; + return ret; + } + + num_words = ((len - 1) / BN_BYTES) + 1; + m = (len - 1) % BN_BYTES; + if (!bn_wexpand(ret, num_words)) { + if (bn) { + BN_free(bn); + } + return NULL; + } + + // |bn_wexpand| must check bounds on |num_words| to write it into + // |ret->dmax|. + assert(num_words <= INT_MAX); + ret->width = (int)num_words; + ret->neg = 0; + + while (len--) { + word = (word << 8) | *(in++); + if (m-- == 0) { + ret->d[--num_words] = word; + word = 0; + m = BN_BYTES - 1; + } + } + + return ret; +} + +BIGNUM *BN_le2bn(const uint8_t *in, size_t len, BIGNUM *ret) { + BIGNUM *bn = NULL; + if (ret == NULL) { + bn = BN_new(); + ret = bn; + } + + if (ret == NULL) { + return NULL; + } + + if (len == 0) { + ret->width = 0; + ret->neg = 0; + return ret; + } + + // Reserve enough space in |ret|. + size_t num_words = ((len - 1) / BN_BYTES) + 1; + if (!bn_wexpand(ret, num_words)) { + BN_free(bn); + return NULL; + } + ret->width = num_words; + + // Make sure the top bytes will be zeroed. + ret->d[num_words - 1] = 0; + + // We only support little-endian platforms, so we can simply memcpy the + // internal representation. + OPENSSL_memcpy(ret->d, in, len); + return ret; +} + +size_t BN_bn2bin(const BIGNUM *in, uint8_t *out) { + size_t n, i; + BN_ULONG l; + + n = i = BN_num_bytes(in); + while (i--) { + l = in->d[i / BN_BYTES]; + *(out++) = (unsigned char)(l >> (8 * (i % BN_BYTES))) & 0xff; + } + return n; +} + +static int fits_in_bytes(const uint8_t *bytes, size_t num_bytes, size_t len) { + uint8_t mask = 0; + for (size_t i = len; i < num_bytes; i++) { + mask |= bytes[i]; + } + return mask == 0; +} + +int BN_bn2le_padded(uint8_t *out, size_t len, const BIGNUM *in) { + const uint8_t *bytes = (const uint8_t *)in->d; + size_t num_bytes = in->width * BN_BYTES; + if (len < num_bytes) { + if (!fits_in_bytes(bytes, num_bytes, len)) { + return 0; + } + num_bytes = len; + } + + // We only support little-endian platforms, so we can simply memcpy into the + // internal representation. + OPENSSL_memcpy(out, bytes, num_bytes); + // Pad out the rest of the buffer with zeroes. + OPENSSL_memset(out + num_bytes, 0, len - num_bytes); + return 1; +} + +int BN_bn2bin_padded(uint8_t *out, size_t len, const BIGNUM *in) { + const uint8_t *bytes = (const uint8_t *)in->d; + size_t num_bytes = in->width * BN_BYTES; + if (len < num_bytes) { + if (!fits_in_bytes(bytes, num_bytes, len)) { + return 0; + } + num_bytes = len; + } + + // We only support little-endian platforms, so we can simply write the buffer + // in reverse. + for (size_t i = 0; i < num_bytes; i++) { + out[len - i - 1] = bytes[i]; + } + // Pad out the rest of the buffer with zeroes. + OPENSSL_memset(out, 0, len - num_bytes); + return 1; +} + +BN_ULONG BN_get_word(const BIGNUM *bn) { + switch (bn_minimal_width(bn)) { + case 0: + return 0; + case 1: + return bn->d[0]; + default: + return BN_MASK2; + } +} + +int BN_get_u64(const BIGNUM *bn, uint64_t *out) { + switch (bn_minimal_width(bn)) { + case 0: + *out = 0; + return 1; + case 1: + *out = bn->d[0]; + return 1; +#if defined(OPENSSL_32_BIT) + case 2: + *out = (uint64_t) bn->d[0] | (((uint64_t) bn->d[1]) << 32); + return 1; +#endif + default: + return 0; + } +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/cmp.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/cmp.c new file mode 100644 index 0000000..01f8cbd --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/cmp.c @@ -0,0 +1,200 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 "internal.h" +#include "../../internal.h" + + +static int bn_cmp_words_consttime(const BN_ULONG *a, size_t a_len, + const BN_ULONG *b, size_t b_len) { + OPENSSL_COMPILE_ASSERT(sizeof(BN_ULONG) <= sizeof(crypto_word_t), + crypto_word_t_too_small); + int ret = 0; + // Process the common words in little-endian order. + size_t min = a_len < b_len ? a_len : b_len; + for (size_t i = 0; i < min; i++) { + crypto_word_t eq = constant_time_eq_w(a[i], b[i]); + crypto_word_t lt = constant_time_lt_w(a[i], b[i]); + ret = + constant_time_select_int(eq, ret, constant_time_select_int(lt, -1, 1)); + } + + // If |a| or |b| has non-zero words beyond |min|, they take precedence. + if (a_len < b_len) { + crypto_word_t mask = 0; + for (size_t i = a_len; i < b_len; i++) { + mask |= b[i]; + } + ret = constant_time_select_int(constant_time_is_zero_w(mask), ret, -1); + } else if (b_len < a_len) { + crypto_word_t mask = 0; + for (size_t i = b_len; i < a_len; i++) { + mask |= a[i]; + } + ret = constant_time_select_int(constant_time_is_zero_w(mask), ret, 1); + } + + return ret; +} + +int BN_ucmp(const BIGNUM *a, const BIGNUM *b) { + return bn_cmp_words_consttime(a->d, a->width, b->d, b->width); +} + +int BN_cmp(const BIGNUM *a, const BIGNUM *b) { + if ((a == NULL) || (b == NULL)) { + if (a != NULL) { + return -1; + } else if (b != NULL) { + return 1; + } else { + return 0; + } + } + + // We do not attempt to process the sign bit in constant time. Negative + // |BIGNUM|s should never occur in crypto, only calculators. + if (a->neg != b->neg) { + if (a->neg) { + return -1; + } + return 1; + } + + int ret = BN_ucmp(a, b); + return a->neg ? -ret : ret; +} + +int bn_less_than_words(const BN_ULONG *a, const BN_ULONG *b, size_t len) { + return bn_cmp_words_consttime(a, len, b, len) < 0; +} + +int BN_abs_is_word(const BIGNUM *bn, BN_ULONG w) { + if (bn->width == 0) { + return w == 0; + } + BN_ULONG mask = bn->d[0] ^ w; + for (int i = 1; i < bn->width; i++) { + mask |= bn->d[i]; + } + return mask == 0; +} + +int BN_cmp_word(const BIGNUM *a, BN_ULONG b) { + BIGNUM b_bn; + BN_init(&b_bn); + + b_bn.d = &b; + b_bn.width = b > 0; + b_bn.dmax = 1; + b_bn.flags = BN_FLG_STATIC_DATA; + return BN_cmp(a, &b_bn); +} + +int BN_is_zero(const BIGNUM *bn) { + return bn_fits_in_words(bn, 0); +} + +int BN_is_one(const BIGNUM *bn) { + return bn->neg == 0 && BN_abs_is_word(bn, 1); +} + +int BN_is_word(const BIGNUM *bn, BN_ULONG w) { + return BN_abs_is_word(bn, w) && (w == 0 || bn->neg == 0); +} + +int BN_is_odd(const BIGNUM *bn) { + return bn->width > 0 && (bn->d[0] & 1) == 1; +} + +int BN_is_pow2(const BIGNUM *bn) { + int width = bn_minimal_width(bn); + if (width == 0 || bn->neg) { + return 0; + } + + for (int i = 0; i < width - 1; i++) { + if (bn->d[i] != 0) { + return 0; + } + } + + return 0 == (bn->d[width-1] & (bn->d[width-1] - 1)); +} + +int BN_equal_consttime(const BIGNUM *a, const BIGNUM *b) { + BN_ULONG mask = 0; + // If |a| or |b| has more words than the other, all those words must be zero. + for (int i = a->width; i < b->width; i++) { + mask |= b->d[i]; + } + for (int i = b->width; i < a->width; i++) { + mask |= a->d[i]; + } + // Common words must match. + int min = a->width < b->width ? a->width : b->width; + for (int i = 0; i < min; i++) { + mask |= (a->d[i] ^ b->d[i]); + } + // The sign bit must match. + mask |= (a->neg ^ b->neg); + return mask == 0; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/cmp.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/cmp.c.grpc_back new file mode 100644 index 0000000..692adb5 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/cmp.c.grpc_back @@ -0,0 +1,200 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 "internal.h" +#include "../../internal.h" + + +static int bn_cmp_words_consttime(const BN_ULONG *a, size_t a_len, + const BN_ULONG *b, size_t b_len) { + OPENSSL_COMPILE_ASSERT(sizeof(BN_ULONG) <= sizeof(crypto_word_t), + crypto_word_t_too_small); + int ret = 0; + // Process the common words in little-endian order. + size_t min = a_len < b_len ? a_len : b_len; + for (size_t i = 0; i < min; i++) { + crypto_word_t eq = constant_time_eq_w(a[i], b[i]); + crypto_word_t lt = constant_time_lt_w(a[i], b[i]); + ret = + constant_time_select_int(eq, ret, constant_time_select_int(lt, -1, 1)); + } + + // If |a| or |b| has non-zero words beyond |min|, they take precedence. + if (a_len < b_len) { + crypto_word_t mask = 0; + for (size_t i = a_len; i < b_len; i++) { + mask |= b[i]; + } + ret = constant_time_select_int(constant_time_is_zero_w(mask), ret, -1); + } else if (b_len < a_len) { + crypto_word_t mask = 0; + for (size_t i = b_len; i < a_len; i++) { + mask |= a[i]; + } + ret = constant_time_select_int(constant_time_is_zero_w(mask), ret, 1); + } + + return ret; +} + +int BN_ucmp(const BIGNUM *a, const BIGNUM *b) { + return bn_cmp_words_consttime(a->d, a->width, b->d, b->width); +} + +int BN_cmp(const BIGNUM *a, const BIGNUM *b) { + if ((a == NULL) || (b == NULL)) { + if (a != NULL) { + return -1; + } else if (b != NULL) { + return 1; + } else { + return 0; + } + } + + // We do not attempt to process the sign bit in constant time. Negative + // |BIGNUM|s should never occur in crypto, only calculators. + if (a->neg != b->neg) { + if (a->neg) { + return -1; + } + return 1; + } + + int ret = BN_ucmp(a, b); + return a->neg ? -ret : ret; +} + +int bn_less_than_words(const BN_ULONG *a, const BN_ULONG *b, size_t len) { + return bn_cmp_words_consttime(a, len, b, len) < 0; +} + +int BN_abs_is_word(const BIGNUM *bn, BN_ULONG w) { + if (bn->width == 0) { + return w == 0; + } + BN_ULONG mask = bn->d[0] ^ w; + for (int i = 1; i < bn->width; i++) { + mask |= bn->d[i]; + } + return mask == 0; +} + +int BN_cmp_word(const BIGNUM *a, BN_ULONG b) { + BIGNUM b_bn; + BN_init(&b_bn); + + b_bn.d = &b; + b_bn.width = b > 0; + b_bn.dmax = 1; + b_bn.flags = BN_FLG_STATIC_DATA; + return BN_cmp(a, &b_bn); +} + +int BN_is_zero(const BIGNUM *bn) { + return bn_fits_in_words(bn, 0); +} + +int BN_is_one(const BIGNUM *bn) { + return bn->neg == 0 && BN_abs_is_word(bn, 1); +} + +int BN_is_word(const BIGNUM *bn, BN_ULONG w) { + return BN_abs_is_word(bn, w) && (w == 0 || bn->neg == 0); +} + +int BN_is_odd(const BIGNUM *bn) { + return bn->width > 0 && (bn->d[0] & 1) == 1; +} + +int BN_is_pow2(const BIGNUM *bn) { + int width = bn_minimal_width(bn); + if (width == 0 || bn->neg) { + return 0; + } + + for (int i = 0; i < width - 1; i++) { + if (bn->d[i] != 0) { + return 0; + } + } + + return 0 == (bn->d[width-1] & (bn->d[width-1] - 1)); +} + +int BN_equal_consttime(const BIGNUM *a, const BIGNUM *b) { + BN_ULONG mask = 0; + // If |a| or |b| has more words than the other, all those words must be zero. + for (int i = a->width; i < b->width; i++) { + mask |= b->d[i]; + } + for (int i = b->width; i < a->width; i++) { + mask |= a->d[i]; + } + // Common words must match. + int min = a->width < b->width ? a->width : b->width; + for (int i = 0; i < min; i++) { + mask |= (a->d[i] ^ b->d[i]); + } + // The sign bit must match. + mask |= (a->neg ^ b->neg); + return mask == 0; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/ctx.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/ctx.c new file mode 100644 index 0000000..30d9c87 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/ctx.c @@ -0,0 +1,303 @@ +/* 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). */ + + +#include + +#include + +#include +#include + +#include "../../internal.h" + + +// 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 + +// 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; + + +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 *); +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 *); +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; +}; + +BN_CTX *BN_CTX_new(void) { + BN_CTX *ret = OPENSSL_malloc(sizeof(BN_CTX)); + if (!ret) { + OPENSSL_PUT_ERROR(BN, 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; + } + + BN_STACK_finish(&ctx->stack); + BN_POOL_finish(&ctx->pool); + OPENSSL_free(ctx); +} + +void BN_CTX_start(BN_CTX *ctx) { + // If we're already overflowing ... + if (ctx->err_stack || ctx->too_many) { + ctx->err_stack++; + } else if (!BN_STACK_push(&ctx->stack, ctx->used)) { + // (Try to) get a new frame pointer + OPENSSL_PUT_ERROR(BN, BN_R_TOO_MANY_TEMPORARY_VARIABLES); + ctx->err_stack++; + } +} + +BIGNUM *BN_CTX_get(BN_CTX *ctx) { + BIGNUM *ret; + if (ctx->err_stack || ctx->too_many) { + return NULL; + } + + ret = BN_POOL_get(&ctx->pool); + if (ret == NULL) { + // Setting too_many prevents repeated "get" attempts from + // cluttering the error stack. + ctx->too_many = 1; + OPENSSL_PUT_ERROR(BN, BN_R_TOO_MANY_TEMPORARY_VARIABLES); + return NULL; + } + + // OK, make sure the returned bignum is "zero" + BN_zero(ret); + ctx->used++; + return ret; +} + +void BN_CTX_end(BN_CTX *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; + } +} + + +// 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) { + OPENSSL_free(st->indexes); +} + +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) { + OPENSSL_memcpy(newitems, st->indexes, st->depth * sizeof(unsigned int)); + } + 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)]; +} + + +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) { + for (size_t i = 0; i < BN_CTX_POOL_SIZE; i++) { + BN_clear_free(&p->head->vals[i]); + } + + p->current = p->head->next; + OPENSSL_free(p->head); + p->head = p->current; + } +} + +static BIGNUM *BN_POOL_get(BN_POOL *p) { + if (p->used == p->size) { + BN_POOL_ITEM *item = OPENSSL_malloc(sizeof(BN_POOL_ITEM)); + if (!item) { + return NULL; + } + + // Initialise the structure + for (size_t i = 0; i < BN_CTX_POOL_SIZE; i++) { + BN_init(&item->vals[i]); + } + + 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--) { + if (!offset) { + offset = BN_CTX_POOL_SIZE - 1; + p->current = p->current->prev; + } else { + offset--; + } + } +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/ctx.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/ctx.c.grpc_back new file mode 100644 index 0000000..af50de9 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/ctx.c.grpc_back @@ -0,0 +1,303 @@ +/* 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). */ + + +#include + +#include + +#include +#include + +#include "../../internal.h" + + +// 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 + +// 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; + + +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 *); +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 *); +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; +}; + +BN_CTX *BN_CTX_new(void) { + BN_CTX *ret = OPENSSL_malloc(sizeof(BN_CTX)); + if (!ret) { + OPENSSL_PUT_ERROR(BN, 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; + } + + BN_STACK_finish(&ctx->stack); + BN_POOL_finish(&ctx->pool); + OPENSSL_free(ctx); +} + +void BN_CTX_start(BN_CTX *ctx) { + // If we're already overflowing ... + if (ctx->err_stack || ctx->too_many) { + ctx->err_stack++; + } else if (!BN_STACK_push(&ctx->stack, ctx->used)) { + // (Try to) get a new frame pointer + OPENSSL_PUT_ERROR(BN, BN_R_TOO_MANY_TEMPORARY_VARIABLES); + ctx->err_stack++; + } +} + +BIGNUM *BN_CTX_get(BN_CTX *ctx) { + BIGNUM *ret; + if (ctx->err_stack || ctx->too_many) { + return NULL; + } + + ret = BN_POOL_get(&ctx->pool); + if (ret == NULL) { + // Setting too_many prevents repeated "get" attempts from + // cluttering the error stack. + ctx->too_many = 1; + OPENSSL_PUT_ERROR(BN, BN_R_TOO_MANY_TEMPORARY_VARIABLES); + return NULL; + } + + // OK, make sure the returned bignum is "zero" + BN_zero(ret); + ctx->used++; + return ret; +} + +void BN_CTX_end(BN_CTX *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; + } +} + + +// 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) { + OPENSSL_free(st->indexes); +} + +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) { + OPENSSL_memcpy(newitems, st->indexes, st->depth * sizeof(unsigned int)); + } + 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)]; +} + + +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) { + for (size_t i = 0; i < BN_CTX_POOL_SIZE; i++) { + BN_clear_free(&p->head->vals[i]); + } + + p->current = p->head->next; + OPENSSL_free(p->head); + p->head = p->current; + } +} + +static BIGNUM *BN_POOL_get(BN_POOL *p) { + if (p->used == p->size) { + BN_POOL_ITEM *item = OPENSSL_malloc(sizeof(BN_POOL_ITEM)); + if (!item) { + return NULL; + } + + // Initialise the structure + for (size_t i = 0; i < BN_CTX_POOL_SIZE; i++) { + BN_init(&item->vals[i]); + } + + 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--) { + if (!offset) { + offset = BN_CTX_POOL_SIZE - 1; + p->current = p->current->prev; + } else { + offset--; + } + } +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/div.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/div.c new file mode 100644 index 0000000..0831ad1 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/div.c @@ -0,0 +1,895 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 "internal.h" + + +#if !defined(BN_ULLONG) +// bn_div_words divides a double-width |h|,|l| by |d| and returns the result, +// which must fit in a |BN_ULONG|. +static 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); + l = (l & BN_MASK2l) << BN_BITS4; + } + + ret |= q; + return ret; +} +#endif // !defined(BN_ULLONG) + +static inline void bn_div_rem_words(BN_ULONG *quotient_out, BN_ULONG *rem_out, + BN_ULONG n0, BN_ULONG n1, BN_ULONG d0) { + // GCC and Clang generate function calls to |__udivdi3| and |__umoddi3| when + // the |BN_ULLONG|-based C code is used. + // + // GCC bugs: + // * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=14224 + // * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=43721 + // * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=54183 + // * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58897 + // * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65668 + // + // Clang bugs: + // * https://llvm.org/bugs/show_bug.cgi?id=6397 + // * https://llvm.org/bugs/show_bug.cgi?id=12418 + // + // These issues aren't specific to x86 and x86_64, so it might be worthwhile + // to add more assembly language implementations. +#if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86) && \ + (defined(__GNUC__) || defined(__clang__)) + __asm__ volatile("divl %4" + : "=a"(*quotient_out), "=d"(*rem_out) + : "a"(n1), "d"(n0), "rm"(d0) + : "cc"); +#elif !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64) && \ + (defined(__GNUC__) || defined(__clang__)) + __asm__ volatile("divq %4" + : "=a"(*quotient_out), "=d"(*rem_out) + : "a"(n1), "d"(n0), "rm"(d0) + : "cc"); +#else +#if defined(BN_ULLONG) + BN_ULLONG n = (((BN_ULLONG)n0) << BN_BITS2) | n1; + *quotient_out = (BN_ULONG)(n / d0); +#else + *quotient_out = bn_div_words(n0, n1, d0); +#endif + *rem_out = n1 - (*quotient_out * d0); +#endif +} + +// BN_div computes "quotient := numerator / divisor", rounding towards zero, +// and sets up |rem| such that "quotient * divisor + rem = numerator" holds. +// +// Thus: +// +// quotient->neg == numerator->neg ^ divisor->neg +// (unless the result is zero) +// rem->neg == numerator->neg +// (unless the remainder is zero) +// +// If |quotient| or |rem| is NULL, the respective value is not returned. +// +// This was specifically designed to contain fewer branches that may leak +// sensitive information; see "New Branch Prediction Vulnerabilities in OpenSSL +// and Necessary Software Countermeasures" by Onur Acıçmez, Shay Gueron, and +// Jean-Pierre Seifert. +int BN_div(BIGNUM *quotient, BIGNUM *rem, const BIGNUM *numerator, + const BIGNUM *divisor, BN_CTX *ctx) { + int norm_shift, loop; + BIGNUM wnum; + BN_ULONG *resp, *wnump; + BN_ULONG d0, d1; + int num_n, div_n; + + // This function relies on the historical minimal-width |BIGNUM| invariant. + // It is already not constant-time (constant-time reductions should use + // Montgomery logic), so we shrink all inputs and intermediate values to + // retain the previous behavior. + + // Invalid zero-padding would have particularly bad consequences. + int numerator_width = bn_minimal_width(numerator); + int divisor_width = bn_minimal_width(divisor); + if ((numerator_width > 0 && numerator->d[numerator_width - 1] == 0) || + (divisor_width > 0 && divisor->d[divisor_width - 1] == 0)) { + OPENSSL_PUT_ERROR(BN, BN_R_NOT_INITIALIZED); + return 0; + } + + if (BN_is_zero(divisor)) { + OPENSSL_PUT_ERROR(BN, BN_R_DIV_BY_ZERO); + return 0; + } + + BN_CTX_start(ctx); + BIGNUM *tmp = BN_CTX_get(ctx); + BIGNUM *snum = BN_CTX_get(ctx); + BIGNUM *sdiv = BN_CTX_get(ctx); + BIGNUM *res = NULL; + if (quotient == NULL) { + res = BN_CTX_get(ctx); + } else { + res = quotient; + } + if (sdiv == NULL || res == 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; + } + bn_set_minimal_width(sdiv); + sdiv->neg = 0; + norm_shift += BN_BITS2; + if (!BN_lshift(snum, numerator, norm_shift)) { + goto err; + } + bn_set_minimal_width(snum); + snum->neg = 0; + + // Since we don't want to have special-case logic for the case where snum is + // larger than sdiv, we pad snum with enough zeroes without changing its + // value. + if (snum->width <= sdiv->width + 1) { + if (!bn_wexpand(snum, sdiv->width + 2)) { + goto err; + } + for (int i = snum->width; i < sdiv->width + 2; i++) { + snum->d[i] = 0; + } + snum->width = sdiv->width + 2; + } else { + if (!bn_wexpand(snum, snum->width + 1)) { + goto err; + } + snum->d[snum->width] = 0; + snum->width++; + } + + div_n = sdiv->width; + num_n = snum->width; + 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.width = div_n; + // only needed when BN_ucmp messes up the values between width 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->width; + 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 = (numerator->neg ^ divisor->neg); + if (!bn_wexpand(res, loop + 1)) { + goto err; + } + res->width = loop - 1; + resp = &(res->d[loop - 1]); + + // space for temp + if (!bn_wexpand(tmp, div_n + 1)) { + goto err; + } + + // if res->width == 0 then clear the neg value otherwise decrease + // the resp pointer + if (res->width == 0) { + res->neg = 0; + } else { + resp--; + } + + for (int 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 + BN_ULONG n0, n1, rm = 0; + + n0 = wnump[0]; + n1 = wnump[-1]; + if (n0 == d0) { + q = BN_MASK2; + } else { + // n0 < d0 + bn_div_rem_words(&q, &rm, n0, n1, d0); + +#ifdef BN_ULLONG + BN_ULLONG t2 = (BN_ULLONG)d1 * q; + for (;;) { + if (t2 <= ((((BN_ULLONG)rm) << BN_BITS2) | wnump[-2])) { + break; + } + q--; + rm += d0; + if (rm < d0) { + break; // don't let rm overflow + } + t2 -= d1; + } +#else // !BN_ULLONG + BN_ULONG t2l, t2h; + BN_UMULT_LOHI(t2l, t2h, d1, q); + for (;;) { + if (t2h < rm || + (t2h == rm && t2l <= wnump[-2])) { + break; + } + q--; + rm += d0; + if (rm < d0) { + break; // don't let rm overflow + } + if (t2l < d1) { + t2h--; + } + t2l -= d1; + } +#endif // !BN_ULLONG + } + + 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_set_minimal_width(snum); + + if (rem != NULL) { + // Keep a copy of the neg flag in numerator because if |rem| == |numerator| + // |BN_rshift| will overwrite it. + int neg = numerator->neg; + if (!BN_rshift(rem, snum, norm_shift)) { + goto err; + } + if (!BN_is_zero(rem)) { + rem->neg = neg; + } + } + + bn_set_minimal_width(res); + BN_CTX_end(ctx); + return 1; + +err: + BN_CTX_end(ctx); + return 0; +} + +int BN_nnmod(BIGNUM *r, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx) { + 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); +} + +// bn_mod_sub_words sets |r| to |a| - |b| (mod |m|), using |tmp| as scratch +// space. Each array is |num| words long. |a| and |b| must be < |m|. Any pair of +// |r|, |a|, and |b| may alias. +static void bn_mod_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, + const BN_ULONG *m, BN_ULONG *tmp, size_t num) { + // r = a - b + BN_ULONG borrow = bn_sub_words(r, a, b, num); + // tmp = a - b + m + bn_add_words(tmp, r, m, num); + bn_select_words(r, 0 - borrow, tmp /* r < 0 */, r /* r >= 0 */, num); +} + +// bn_mod_add_words sets |r| to |a| + |b| (mod |m|), using |tmp| as scratch +// space. Each array is |num| words long. |a| and |b| must be < |m|. Any pair of +// |r|, |a|, and |b| may alias. +static void bn_mod_add_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, + const BN_ULONG *m, BN_ULONG *tmp, size_t num) { + // tmp = a + b. Note the result fits in |num|+1 words. We store the extra word + // in |carry|. + BN_ULONG carry = bn_add_words(tmp, a, b, num); + // r = a + b - m. We use |bn_sub_words| to perform the bulk of the + // subtraction, and then apply the borrow to |carry|. + carry -= bn_sub_words(r, tmp, m, num); + // |a| and |b| were both fully-reduced, so we know: + // + // 0 + 0 - m <= r < m + m - m + // -m <= r < m + // + // If 0 <= |r| < |m|, |r| fits in |num| words and |carry| is zero. We then + // wish to select |r| as the answer. Otherwise -m <= r < 0 and we wish to + // return |r| + |m|, or |tmp|. |carry| must then be -1 or all ones. In both + // cases, |carry| is a suitable input to |bn_select_words|. + // + // Although |carry| may be one if |bn_add_words| returns one and + // |bn_sub_words| returns zero, this would give |r| > |m|, which violates are + // input assumptions. + assert(carry == 0 || carry == (BN_ULONG)-1); + bn_select_words(r, carry, tmp /* r < 0 */, r /* r >= 0 */, num); +} + +int bn_div_consttime(BIGNUM *quotient, BIGNUM *remainder, + const BIGNUM *numerator, const BIGNUM *divisor, + BN_CTX *ctx) { + if (BN_is_negative(numerator) || BN_is_negative(divisor)) { + OPENSSL_PUT_ERROR(BN, BN_R_NEGATIVE_NUMBER); + return 0; + } + if (BN_is_zero(divisor)) { + OPENSSL_PUT_ERROR(BN, BN_R_DIV_BY_ZERO); + return 0; + } + + // This function implements long division in binary. It is not very efficient, + // but it is simple, easy to make constant-time, and performant enough for RSA + // key generation. + + int ret = 0; + BN_CTX_start(ctx); + BIGNUM *q = quotient, *r = remainder; + if (quotient == NULL || quotient == numerator || quotient == divisor) { + q = BN_CTX_get(ctx); + } + if (remainder == NULL || remainder == numerator || remainder == divisor) { + r = BN_CTX_get(ctx); + } + BIGNUM *tmp = BN_CTX_get(ctx); + if (q == NULL || r == NULL || tmp == NULL || + !bn_wexpand(q, numerator->width) || + !bn_wexpand(r, divisor->width) || + !bn_wexpand(tmp, divisor->width)) { + goto err; + } + + OPENSSL_memset(q->d, 0, numerator->width * sizeof(BN_ULONG)); + q->width = numerator->width; + q->neg = 0; + + OPENSSL_memset(r->d, 0, divisor->width * sizeof(BN_ULONG)); + r->width = divisor->width; + r->neg = 0; + + // Incorporate |numerator| into |r|, one bit at a time, reducing after each + // step. At the start of each loop iteration, |r| < |divisor| + for (int i = numerator->width - 1; i >= 0; i--) { + for (int bit = BN_BITS2 - 1; bit >= 0; bit--) { + // Incorporate the next bit of the numerator, by computing + // r = 2*r or 2*r + 1. Note the result fits in one more word. We store the + // extra word in |carry|. + BN_ULONG carry = bn_add_words(r->d, r->d, r->d, divisor->width); + r->d[0] |= (numerator->d[i] >> bit) & 1; + // tmp = r - divisor. We use |bn_sub_words| to perform the bulk of the + // subtraction, and then apply the borrow to |carry|. + carry -= bn_sub_words(tmp->d, r->d, divisor->d, divisor->width); + // |r| was previously fully-reduced, so we know: + // + // 2*0 - divisor <= tmp <= 2*(divisor-1) + 1 - divisor + // -divisor <= tmp < divisor + // + // If 0 <= |tmp| < |divisor|, |tmp| fits in |divisor->width| and |carry| + // is zero. We then wish to select |tmp|. Otherwise, + // -|divisor| <= |tmp| < 0 and we wish to select |tmp| + |divisor|, which + // is |r|. |carry| must then be -1 (all ones). In both cases, |carry| is a + // suitable input to |bn_select_words|. + // + // Although |carry| may be one if |bn_add_words| returns one and + // |bn_sub_words| returns zero, this would give |r| > |d|, which violates + // the loop invariant. + bn_select_words(r->d, carry, r->d /* tmp < 0 */, tmp->d /* tmp >= 0 */, + divisor->width); + // The corresponding bit of the quotient is set iff we needed to subtract. + q->d[i] |= (~carry & 1) << bit; + } + } + + if ((quotient != NULL && !BN_copy(quotient, q)) || + (remainder != NULL && !BN_copy(remainder, r))) { + goto err; + } + + ret = 1; + +err: + BN_CTX_end(ctx); + return ret; +} + +static BIGNUM *bn_scratch_space_from_ctx(size_t width, BN_CTX *ctx) { + BIGNUM *ret = BN_CTX_get(ctx); + if (ret == NULL || + !bn_wexpand(ret, width)) { + return NULL; + } + ret->neg = 0; + ret->width = width; + return ret; +} + +// bn_resized_from_ctx returns |bn| with width at least |width| or NULL on +// error. This is so it may be used with low-level "words" functions. If +// necessary, it allocates a new |BIGNUM| with a lifetime of the current scope +// in |ctx|, so the caller does not need to explicitly free it. |bn| must fit in +// |width| words. +static const BIGNUM *bn_resized_from_ctx(const BIGNUM *bn, size_t width, + BN_CTX *ctx) { + if ((size_t)bn->width >= width) { + // Any excess words must be zero. + assert(bn_fits_in_words(bn, width)); + return bn; + } + BIGNUM *ret = bn_scratch_space_from_ctx(width, ctx); + if (ret == NULL || + !BN_copy(ret, bn) || + !bn_resize_words(ret, width)) { + return NULL; + } + return ret; +} + +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); +} + +int BN_mod_add_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const BIGNUM *m) { + BN_CTX *ctx = BN_CTX_new(); + int ok = ctx != NULL && + bn_mod_add_consttime(r, a, b, m, ctx); + BN_CTX_free(ctx); + return ok; +} + +int bn_mod_add_consttime(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const BIGNUM *m, BN_CTX *ctx) { + BN_CTX_start(ctx); + a = bn_resized_from_ctx(a, m->width, ctx); + b = bn_resized_from_ctx(b, m->width, ctx); + BIGNUM *tmp = bn_scratch_space_from_ctx(m->width, ctx); + int ok = a != NULL && b != NULL && tmp != NULL && + bn_wexpand(r, m->width); + if (ok) { + bn_mod_add_words(r->d, a->d, b->d, m->d, tmp->d, m->width); + r->width = m->width; + } + BN_CTX_end(ctx); + return ok; +} + +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); +} + +int bn_mod_sub_consttime(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const BIGNUM *m, BN_CTX *ctx) { + BN_CTX_start(ctx); + a = bn_resized_from_ctx(a, m->width, ctx); + b = bn_resized_from_ctx(b, m->width, ctx); + BIGNUM *tmp = bn_scratch_space_from_ctx(m->width, ctx); + int ok = a != NULL && b != NULL && tmp != NULL && + bn_wexpand(r, m->width); + if (ok) { + bn_mod_sub_words(r->d, a->d, b->d, m->d, tmp->d, m->width); + r->width = m->width; + } + BN_CTX_end(ctx); + return ok; +} + +int BN_mod_sub_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const BIGNUM *m) { + BN_CTX *ctx = BN_CTX_new(); + int ok = ctx != NULL && + bn_mod_sub_consttime(r, a, b, m, ctx); + BN_CTX_free(ctx); + return ok; +} + +int BN_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, + BN_CTX *ctx) { + BIGNUM *t; + int ret = 0; + + BN_CTX_start(ctx); + t = BN_CTX_get(ctx); + if (t == 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; + } + + 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_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_consttime(r, r, n, (abs_m ? abs_m : m), ctx); + + BN_free(abs_m); + return ret; +} + +int bn_mod_lshift_consttime(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m, + BN_CTX *ctx) { + if (!BN_copy(r, a)) { + return 0; + } + for (int i = 0; i < n; i++) { + if (!bn_mod_lshift1_consttime(r, r, m, ctx)) { + return 0; + } + } + return 1; +} + +int BN_mod_lshift_quick(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m) { + BN_CTX *ctx = BN_CTX_new(); + int ok = ctx != NULL && + bn_mod_lshift_consttime(r, a, n, m, ctx); + BN_CTX_free(ctx); + return ok; +} + +int BN_mod_lshift1(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx) { + if (!BN_lshift1(r, a)) { + return 0; + } + + return BN_nnmod(r, r, m, ctx); +} + +int bn_mod_lshift1_consttime(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, + BN_CTX *ctx) { + return bn_mod_add_consttime(r, a, a, m, ctx); +} + +int BN_mod_lshift1_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *m) { + BN_CTX *ctx = BN_CTX_new(); + int ok = ctx != NULL && + bn_mod_lshift1_consttime(r, a, m, ctx); + BN_CTX_free(ctx); + return ok; +} + +BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w) { + BN_ULONG ret = 0; + int i, j; + + if (!w) { + // actually this an error (division by zero) + return (BN_ULONG) - 1; + } + + if (a->width == 0) { + return 0; + } + + // normalize input for |bn_div_rem_words|. + j = BN_BITS2 - BN_num_bits_word(w); + w <<= j; + if (!BN_lshift(a, a, j)) { + return (BN_ULONG) - 1; + } + + for (i = a->width - 1; i >= 0; i--) { + BN_ULONG l = a->d[i]; + BN_ULONG d; + BN_ULONG unused_rem; + bn_div_rem_words(&d, &unused_rem, ret, l, w); + ret = l - (d * w); + a->d[i] = d; + } + + bn_set_minimal_width(a); + ret >>= j; + return ret; +} + +BN_ULONG BN_mod_word(const BIGNUM *a, BN_ULONG w) { +#ifndef BN_CAN_DIVIDE_ULLONG + BN_ULONG ret = 0; +#else + BN_ULLONG ret = 0; +#endif + int i; + + if (w == 0) { + return (BN_ULONG) -1; + } + +#ifndef BN_CAN_DIVIDE_ULLONG + // If |w| is too long and we don't have |BN_ULLONG| division 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 + + for (i = a->width - 1; i >= 0; i--) { +#ifndef BN_CAN_DIVIDE_ULLONG + 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; +} + +int BN_mod_pow2(BIGNUM *r, const BIGNUM *a, size_t e) { + if (e == 0 || a->width == 0) { + BN_zero(r); + return 1; + } + + size_t num_words = 1 + ((e - 1) / BN_BITS2); + + // If |a| definitely has less than |e| bits, just BN_copy. + if ((size_t) a->width < num_words) { + return BN_copy(r, a) != NULL; + } + + // Otherwise, first make sure we have enough space in |r|. + // Note that this will fail if num_words > INT_MAX. + if (!bn_wexpand(r, num_words)) { + return 0; + } + + // Copy the content of |a| into |r|. + OPENSSL_memcpy(r->d, a->d, num_words * sizeof(BN_ULONG)); + + // If |e| isn't word-aligned, we have to mask off some of our bits. + size_t top_word_exponent = e % (sizeof(BN_ULONG) * 8); + if (top_word_exponent != 0) { + r->d[num_words - 1] &= (((BN_ULONG) 1) << top_word_exponent) - 1; + } + + // Fill in the remaining fields of |r|. + r->neg = a->neg; + r->width = (int) num_words; + bn_set_minimal_width(r); + return 1; +} + +int BN_nnmod_pow2(BIGNUM *r, const BIGNUM *a, size_t e) { + if (!BN_mod_pow2(r, a, e)) { + return 0; + } + + // If the returned value was non-negative, we're done. + if (BN_is_zero(r) || !r->neg) { + return 1; + } + + size_t num_words = 1 + (e - 1) / BN_BITS2; + + // Expand |r| to the size of our modulus. + if (!bn_wexpand(r, num_words)) { + return 0; + } + + // Clear the upper words of |r|. + OPENSSL_memset(&r->d[r->width], 0, (num_words - r->width) * BN_BYTES); + + // Set parameters of |r|. + r->neg = 0; + r->width = (int) num_words; + + // Now, invert every word. The idea here is that we want to compute 2^e-|x|, + // which is actually equivalent to the twos-complement representation of |x| + // in |e| bits, which is -x = ~x + 1. + for (int i = 0; i < r->width; i++) { + r->d[i] = ~r->d[i]; + } + + // If our exponent doesn't span the top word, we have to mask the rest. + size_t top_word_exponent = e % BN_BITS2; + if (top_word_exponent != 0) { + r->d[r->width - 1] &= (((BN_ULONG) 1) << top_word_exponent) - 1; + } + + // Keep the minimal-width invariant for |BIGNUM|. + bn_set_minimal_width(r); + + // Finally, add one, for the reason described above. + return BN_add(r, r, BN_value_one()); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/div.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/div.c.grpc_back new file mode 100644 index 0000000..2a3bcdd --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/div.c.grpc_back @@ -0,0 +1,895 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 "internal.h" + + +#if !defined(BN_ULLONG) +// bn_div_words divides a double-width |h|,|l| by |d| and returns the result, +// which must fit in a |BN_ULONG|. +static 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); + l = (l & BN_MASK2l) << BN_BITS4; + } + + ret |= q; + return ret; +} +#endif // !defined(BN_ULLONG) + +static inline void bn_div_rem_words(BN_ULONG *quotient_out, BN_ULONG *rem_out, + BN_ULONG n0, BN_ULONG n1, BN_ULONG d0) { + // GCC and Clang generate function calls to |__udivdi3| and |__umoddi3| when + // the |BN_ULLONG|-based C code is used. + // + // GCC bugs: + // * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=14224 + // * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=43721 + // * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=54183 + // * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58897 + // * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65668 + // + // Clang bugs: + // * https://llvm.org/bugs/show_bug.cgi?id=6397 + // * https://llvm.org/bugs/show_bug.cgi?id=12418 + // + // These issues aren't specific to x86 and x86_64, so it might be worthwhile + // to add more assembly language implementations. +#if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86) && \ + (defined(__GNUC__) || defined(__clang__)) + __asm__ volatile("divl %4" + : "=a"(*quotient_out), "=d"(*rem_out) + : "a"(n1), "d"(n0), "rm"(d0) + : "cc"); +#elif !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64) && \ + (defined(__GNUC__) || defined(__clang__)) + __asm__ volatile("divq %4" + : "=a"(*quotient_out), "=d"(*rem_out) + : "a"(n1), "d"(n0), "rm"(d0) + : "cc"); +#else +#if defined(BN_ULLONG) + BN_ULLONG n = (((BN_ULLONG)n0) << BN_BITS2) | n1; + *quotient_out = (BN_ULONG)(n / d0); +#else + *quotient_out = bn_div_words(n0, n1, d0); +#endif + *rem_out = n1 - (*quotient_out * d0); +#endif +} + +// BN_div computes "quotient := numerator / divisor", rounding towards zero, +// and sets up |rem| such that "quotient * divisor + rem = numerator" holds. +// +// Thus: +// +// quotient->neg == numerator->neg ^ divisor->neg +// (unless the result is zero) +// rem->neg == numerator->neg +// (unless the remainder is zero) +// +// If |quotient| or |rem| is NULL, the respective value is not returned. +// +// This was specifically designed to contain fewer branches that may leak +// sensitive information; see "New Branch Prediction Vulnerabilities in OpenSSL +// and Necessary Software Countermeasures" by Onur Acıçmez, Shay Gueron, and +// Jean-Pierre Seifert. +int BN_div(BIGNUM *quotient, BIGNUM *rem, const BIGNUM *numerator, + const BIGNUM *divisor, BN_CTX *ctx) { + int norm_shift, loop; + BIGNUM wnum; + BN_ULONG *resp, *wnump; + BN_ULONG d0, d1; + int num_n, div_n; + + // This function relies on the historical minimal-width |BIGNUM| invariant. + // It is already not constant-time (constant-time reductions should use + // Montgomery logic), so we shrink all inputs and intermediate values to + // retain the previous behavior. + + // Invalid zero-padding would have particularly bad consequences. + int numerator_width = bn_minimal_width(numerator); + int divisor_width = bn_minimal_width(divisor); + if ((numerator_width > 0 && numerator->d[numerator_width - 1] == 0) || + (divisor_width > 0 && divisor->d[divisor_width - 1] == 0)) { + OPENSSL_PUT_ERROR(BN, BN_R_NOT_INITIALIZED); + return 0; + } + + if (BN_is_zero(divisor)) { + OPENSSL_PUT_ERROR(BN, BN_R_DIV_BY_ZERO); + return 0; + } + + BN_CTX_start(ctx); + BIGNUM *tmp = BN_CTX_get(ctx); + BIGNUM *snum = BN_CTX_get(ctx); + BIGNUM *sdiv = BN_CTX_get(ctx); + BIGNUM *res = NULL; + if (quotient == NULL) { + res = BN_CTX_get(ctx); + } else { + res = quotient; + } + if (sdiv == NULL || res == 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; + } + bn_set_minimal_width(sdiv); + sdiv->neg = 0; + norm_shift += BN_BITS2; + if (!BN_lshift(snum, numerator, norm_shift)) { + goto err; + } + bn_set_minimal_width(snum); + snum->neg = 0; + + // Since we don't want to have special-case logic for the case where snum is + // larger than sdiv, we pad snum with enough zeroes without changing its + // value. + if (snum->width <= sdiv->width + 1) { + if (!bn_wexpand(snum, sdiv->width + 2)) { + goto err; + } + for (int i = snum->width; i < sdiv->width + 2; i++) { + snum->d[i] = 0; + } + snum->width = sdiv->width + 2; + } else { + if (!bn_wexpand(snum, snum->width + 1)) { + goto err; + } + snum->d[snum->width] = 0; + snum->width++; + } + + div_n = sdiv->width; + num_n = snum->width; + 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.width = div_n; + // only needed when BN_ucmp messes up the values between width 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->width; + 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 = (numerator->neg ^ divisor->neg); + if (!bn_wexpand(res, loop + 1)) { + goto err; + } + res->width = loop - 1; + resp = &(res->d[loop - 1]); + + // space for temp + if (!bn_wexpand(tmp, div_n + 1)) { + goto err; + } + + // if res->width == 0 then clear the neg value otherwise decrease + // the resp pointer + if (res->width == 0) { + res->neg = 0; + } else { + resp--; + } + + for (int 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 + BN_ULONG n0, n1, rm = 0; + + n0 = wnump[0]; + n1 = wnump[-1]; + if (n0 == d0) { + q = BN_MASK2; + } else { + // n0 < d0 + bn_div_rem_words(&q, &rm, n0, n1, d0); + +#ifdef BN_ULLONG + BN_ULLONG t2 = (BN_ULLONG)d1 * q; + for (;;) { + if (t2 <= ((((BN_ULLONG)rm) << BN_BITS2) | wnump[-2])) { + break; + } + q--; + rm += d0; + if (rm < d0) { + break; // don't let rm overflow + } + t2 -= d1; + } +#else // !BN_ULLONG + BN_ULONG t2l, t2h; + BN_UMULT_LOHI(t2l, t2h, d1, q); + for (;;) { + if (t2h < rm || + (t2h == rm && t2l <= wnump[-2])) { + break; + } + q--; + rm += d0; + if (rm < d0) { + break; // don't let rm overflow + } + if (t2l < d1) { + t2h--; + } + t2l -= d1; + } +#endif // !BN_ULLONG + } + + 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_set_minimal_width(snum); + + if (rem != NULL) { + // Keep a copy of the neg flag in numerator because if |rem| == |numerator| + // |BN_rshift| will overwrite it. + int neg = numerator->neg; + if (!BN_rshift(rem, snum, norm_shift)) { + goto err; + } + if (!BN_is_zero(rem)) { + rem->neg = neg; + } + } + + bn_set_minimal_width(res); + BN_CTX_end(ctx); + return 1; + +err: + BN_CTX_end(ctx); + return 0; +} + +int BN_nnmod(BIGNUM *r, const BIGNUM *m, const BIGNUM *d, BN_CTX *ctx) { + 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); +} + +// bn_mod_sub_words sets |r| to |a| - |b| (mod |m|), using |tmp| as scratch +// space. Each array is |num| words long. |a| and |b| must be < |m|. Any pair of +// |r|, |a|, and |b| may alias. +static void bn_mod_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, + const BN_ULONG *m, BN_ULONG *tmp, size_t num) { + // r = a - b + BN_ULONG borrow = bn_sub_words(r, a, b, num); + // tmp = a - b + m + bn_add_words(tmp, r, m, num); + bn_select_words(r, 0 - borrow, tmp /* r < 0 */, r /* r >= 0 */, num); +} + +// bn_mod_add_words sets |r| to |a| + |b| (mod |m|), using |tmp| as scratch +// space. Each array is |num| words long. |a| and |b| must be < |m|. Any pair of +// |r|, |a|, and |b| may alias. +static void bn_mod_add_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, + const BN_ULONG *m, BN_ULONG *tmp, size_t num) { + // tmp = a + b. Note the result fits in |num|+1 words. We store the extra word + // in |carry|. + BN_ULONG carry = bn_add_words(tmp, a, b, num); + // r = a + b - m. We use |bn_sub_words| to perform the bulk of the + // subtraction, and then apply the borrow to |carry|. + carry -= bn_sub_words(r, tmp, m, num); + // |a| and |b| were both fully-reduced, so we know: + // + // 0 + 0 - m <= r < m + m - m + // -m <= r < m + // + // If 0 <= |r| < |m|, |r| fits in |num| words and |carry| is zero. We then + // wish to select |r| as the answer. Otherwise -m <= r < 0 and we wish to + // return |r| + |m|, or |tmp|. |carry| must then be -1 or all ones. In both + // cases, |carry| is a suitable input to |bn_select_words|. + // + // Although |carry| may be one if |bn_add_words| returns one and + // |bn_sub_words| returns zero, this would give |r| > |m|, which violates are + // input assumptions. + assert(carry == 0 || carry == (BN_ULONG)-1); + bn_select_words(r, carry, tmp /* r < 0 */, r /* r >= 0 */, num); +} + +int bn_div_consttime(BIGNUM *quotient, BIGNUM *remainder, + const BIGNUM *numerator, const BIGNUM *divisor, + BN_CTX *ctx) { + if (BN_is_negative(numerator) || BN_is_negative(divisor)) { + OPENSSL_PUT_ERROR(BN, BN_R_NEGATIVE_NUMBER); + return 0; + } + if (BN_is_zero(divisor)) { + OPENSSL_PUT_ERROR(BN, BN_R_DIV_BY_ZERO); + return 0; + } + + // This function implements long division in binary. It is not very efficient, + // but it is simple, easy to make constant-time, and performant enough for RSA + // key generation. + + int ret = 0; + BN_CTX_start(ctx); + BIGNUM *q = quotient, *r = remainder; + if (quotient == NULL || quotient == numerator || quotient == divisor) { + q = BN_CTX_get(ctx); + } + if (remainder == NULL || remainder == numerator || remainder == divisor) { + r = BN_CTX_get(ctx); + } + BIGNUM *tmp = BN_CTX_get(ctx); + if (q == NULL || r == NULL || tmp == NULL || + !bn_wexpand(q, numerator->width) || + !bn_wexpand(r, divisor->width) || + !bn_wexpand(tmp, divisor->width)) { + goto err; + } + + OPENSSL_memset(q->d, 0, numerator->width * sizeof(BN_ULONG)); + q->width = numerator->width; + q->neg = 0; + + OPENSSL_memset(r->d, 0, divisor->width * sizeof(BN_ULONG)); + r->width = divisor->width; + r->neg = 0; + + // Incorporate |numerator| into |r|, one bit at a time, reducing after each + // step. At the start of each loop iteration, |r| < |divisor| + for (int i = numerator->width - 1; i >= 0; i--) { + for (int bit = BN_BITS2 - 1; bit >= 0; bit--) { + // Incorporate the next bit of the numerator, by computing + // r = 2*r or 2*r + 1. Note the result fits in one more word. We store the + // extra word in |carry|. + BN_ULONG carry = bn_add_words(r->d, r->d, r->d, divisor->width); + r->d[0] |= (numerator->d[i] >> bit) & 1; + // tmp = r - divisor. We use |bn_sub_words| to perform the bulk of the + // subtraction, and then apply the borrow to |carry|. + carry -= bn_sub_words(tmp->d, r->d, divisor->d, divisor->width); + // |r| was previously fully-reduced, so we know: + // + // 2*0 - divisor <= tmp <= 2*(divisor-1) + 1 - divisor + // -divisor <= tmp < divisor + // + // If 0 <= |tmp| < |divisor|, |tmp| fits in |divisor->width| and |carry| + // is zero. We then wish to select |tmp|. Otherwise, + // -|divisor| <= |tmp| < 0 and we wish to select |tmp| + |divisor|, which + // is |r|. |carry| must then be -1 (all ones). In both cases, |carry| is a + // suitable input to |bn_select_words|. + // + // Although |carry| may be one if |bn_add_words| returns one and + // |bn_sub_words| returns zero, this would give |r| > |d|, which violates + // the loop invariant. + bn_select_words(r->d, carry, r->d /* tmp < 0 */, tmp->d /* tmp >= 0 */, + divisor->width); + // The corresponding bit of the quotient is set iff we needed to subtract. + q->d[i] |= (~carry & 1) << bit; + } + } + + if ((quotient != NULL && !BN_copy(quotient, q)) || + (remainder != NULL && !BN_copy(remainder, r))) { + goto err; + } + + ret = 1; + +err: + BN_CTX_end(ctx); + return ret; +} + +static BIGNUM *bn_scratch_space_from_ctx(size_t width, BN_CTX *ctx) { + BIGNUM *ret = BN_CTX_get(ctx); + if (ret == NULL || + !bn_wexpand(ret, width)) { + return NULL; + } + ret->neg = 0; + ret->width = width; + return ret; +} + +// bn_resized_from_ctx returns |bn| with width at least |width| or NULL on +// error. This is so it may be used with low-level "words" functions. If +// necessary, it allocates a new |BIGNUM| with a lifetime of the current scope +// in |ctx|, so the caller does not need to explicitly free it. |bn| must fit in +// |width| words. +static const BIGNUM *bn_resized_from_ctx(const BIGNUM *bn, size_t width, + BN_CTX *ctx) { + if ((size_t)bn->width >= width) { + // Any excess words must be zero. + assert(bn_fits_in_words(bn, width)); + return bn; + } + BIGNUM *ret = bn_scratch_space_from_ctx(width, ctx); + if (ret == NULL || + !BN_copy(ret, bn) || + !bn_resize_words(ret, width)) { + return NULL; + } + return ret; +} + +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); +} + +int BN_mod_add_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const BIGNUM *m) { + BN_CTX *ctx = BN_CTX_new(); + int ok = ctx != NULL && + bn_mod_add_consttime(r, a, b, m, ctx); + BN_CTX_free(ctx); + return ok; +} + +int bn_mod_add_consttime(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const BIGNUM *m, BN_CTX *ctx) { + BN_CTX_start(ctx); + a = bn_resized_from_ctx(a, m->width, ctx); + b = bn_resized_from_ctx(b, m->width, ctx); + BIGNUM *tmp = bn_scratch_space_from_ctx(m->width, ctx); + int ok = a != NULL && b != NULL && tmp != NULL && + bn_wexpand(r, m->width); + if (ok) { + bn_mod_add_words(r->d, a->d, b->d, m->d, tmp->d, m->width); + r->width = m->width; + } + BN_CTX_end(ctx); + return ok; +} + +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); +} + +int bn_mod_sub_consttime(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const BIGNUM *m, BN_CTX *ctx) { + BN_CTX_start(ctx); + a = bn_resized_from_ctx(a, m->width, ctx); + b = bn_resized_from_ctx(b, m->width, ctx); + BIGNUM *tmp = bn_scratch_space_from_ctx(m->width, ctx); + int ok = a != NULL && b != NULL && tmp != NULL && + bn_wexpand(r, m->width); + if (ok) { + bn_mod_sub_words(r->d, a->d, b->d, m->d, tmp->d, m->width); + r->width = m->width; + } + BN_CTX_end(ctx); + return ok; +} + +int BN_mod_sub_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const BIGNUM *m) { + BN_CTX *ctx = BN_CTX_new(); + int ok = ctx != NULL && + bn_mod_sub_consttime(r, a, b, m, ctx); + BN_CTX_free(ctx); + return ok; +} + +int BN_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, const BIGNUM *m, + BN_CTX *ctx) { + BIGNUM *t; + int ret = 0; + + BN_CTX_start(ctx); + t = BN_CTX_get(ctx); + if (t == 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; + } + + 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_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_consttime(r, r, n, (abs_m ? abs_m : m), ctx); + + BN_free(abs_m); + return ret; +} + +int bn_mod_lshift_consttime(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m, + BN_CTX *ctx) { + if (!BN_copy(r, a)) { + return 0; + } + for (int i = 0; i < n; i++) { + if (!bn_mod_lshift1_consttime(r, r, m, ctx)) { + return 0; + } + } + return 1; +} + +int BN_mod_lshift_quick(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m) { + BN_CTX *ctx = BN_CTX_new(); + int ok = ctx != NULL && + bn_mod_lshift_consttime(r, a, n, m, ctx); + BN_CTX_free(ctx); + return ok; +} + +int BN_mod_lshift1(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, BN_CTX *ctx) { + if (!BN_lshift1(r, a)) { + return 0; + } + + return BN_nnmod(r, r, m, ctx); +} + +int bn_mod_lshift1_consttime(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, + BN_CTX *ctx) { + return bn_mod_add_consttime(r, a, a, m, ctx); +} + +int BN_mod_lshift1_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *m) { + BN_CTX *ctx = BN_CTX_new(); + int ok = ctx != NULL && + bn_mod_lshift1_consttime(r, a, m, ctx); + BN_CTX_free(ctx); + return ok; +} + +BN_ULONG BN_div_word(BIGNUM *a, BN_ULONG w) { + BN_ULONG ret = 0; + int i, j; + + if (!w) { + // actually this an error (division by zero) + return (BN_ULONG) - 1; + } + + if (a->width == 0) { + return 0; + } + + // normalize input for |bn_div_rem_words|. + j = BN_BITS2 - BN_num_bits_word(w); + w <<= j; + if (!BN_lshift(a, a, j)) { + return (BN_ULONG) - 1; + } + + for (i = a->width - 1; i >= 0; i--) { + BN_ULONG l = a->d[i]; + BN_ULONG d; + BN_ULONG unused_rem; + bn_div_rem_words(&d, &unused_rem, ret, l, w); + ret = l - (d * w); + a->d[i] = d; + } + + bn_set_minimal_width(a); + ret >>= j; + return ret; +} + +BN_ULONG BN_mod_word(const BIGNUM *a, BN_ULONG w) { +#ifndef BN_CAN_DIVIDE_ULLONG + BN_ULONG ret = 0; +#else + BN_ULLONG ret = 0; +#endif + int i; + + if (w == 0) { + return (BN_ULONG) -1; + } + +#ifndef BN_CAN_DIVIDE_ULLONG + // If |w| is too long and we don't have |BN_ULLONG| division 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 + + for (i = a->width - 1; i >= 0; i--) { +#ifndef BN_CAN_DIVIDE_ULLONG + 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; +} + +int BN_mod_pow2(BIGNUM *r, const BIGNUM *a, size_t e) { + if (e == 0 || a->width == 0) { + BN_zero(r); + return 1; + } + + size_t num_words = 1 + ((e - 1) / BN_BITS2); + + // If |a| definitely has less than |e| bits, just BN_copy. + if ((size_t) a->width < num_words) { + return BN_copy(r, a) != NULL; + } + + // Otherwise, first make sure we have enough space in |r|. + // Note that this will fail if num_words > INT_MAX. + if (!bn_wexpand(r, num_words)) { + return 0; + } + + // Copy the content of |a| into |r|. + OPENSSL_memcpy(r->d, a->d, num_words * sizeof(BN_ULONG)); + + // If |e| isn't word-aligned, we have to mask off some of our bits. + size_t top_word_exponent = e % (sizeof(BN_ULONG) * 8); + if (top_word_exponent != 0) { + r->d[num_words - 1] &= (((BN_ULONG) 1) << top_word_exponent) - 1; + } + + // Fill in the remaining fields of |r|. + r->neg = a->neg; + r->width = (int) num_words; + bn_set_minimal_width(r); + return 1; +} + +int BN_nnmod_pow2(BIGNUM *r, const BIGNUM *a, size_t e) { + if (!BN_mod_pow2(r, a, e)) { + return 0; + } + + // If the returned value was non-negative, we're done. + if (BN_is_zero(r) || !r->neg) { + return 1; + } + + size_t num_words = 1 + (e - 1) / BN_BITS2; + + // Expand |r| to the size of our modulus. + if (!bn_wexpand(r, num_words)) { + return 0; + } + + // Clear the upper words of |r|. + OPENSSL_memset(&r->d[r->width], 0, (num_words - r->width) * BN_BYTES); + + // Set parameters of |r|. + r->neg = 0; + r->width = (int) num_words; + + // Now, invert every word. The idea here is that we want to compute 2^e-|x|, + // which is actually equivalent to the twos-complement representation of |x| + // in |e| bits, which is -x = ~x + 1. + for (int i = 0; i < r->width; i++) { + r->d[i] = ~r->d[i]; + } + + // If our exponent doesn't span the top word, we have to mask the rest. + size_t top_word_exponent = e % BN_BITS2; + if (top_word_exponent != 0) { + r->d[r->width - 1] &= (((BN_ULONG) 1) << top_word_exponent) - 1; + } + + // Keep the minimal-width invariant for |BIGNUM|. + bn_set_minimal_width(r); + + // Finally, add one, for the reason described above. + return BN_add(r, r, BN_value_one()); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/exponentiation.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/exponentiation.c new file mode 100644 index 0000000..dde75a4 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/exponentiation.c @@ -0,0 +1,1356 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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-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 +#include + +#include +#include +#include + +#include "internal.h" + + +#if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64) +#define OPENSSL_BN_ASM_MONT5 +#define RSAZ_ENABLED + +#include "rsaz_exp.h" + +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_from_montgomery(BN_ULONG *rp, const BN_ULONG *ap, + const BN_ULONG *not_used, const BN_ULONG *np, + const BN_ULONG *n0, int num); +#endif + +int BN_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) { + int i, bits, ret = 0; + BIGNUM *v, *rr; + + 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)) { + goto err; + } + ret = 1; + +err: + BN_CTX_end(ctx); + return ret; +} + +typedef struct bn_recp_ctx_st { + BIGNUM N; // the divisor + BIGNUM Nr; // the reciprocal + int num_bits; + int shift; + int flags; +} BN_RECP_CTX; + +static 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; +} + +static void BN_RECP_CTX_free(BN_RECP_CTX *recp) { + if (recp == NULL) { + return; + } + + BN_free(&recp->N); + BN_free(&recp->Nr); +} + +static 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; +} + +// 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 +static int BN_reciprocal(BIGNUM *r, const BIGNUM *m, int len, BN_CTX *ctx) { + int ret = -1; + BIGNUM *t; + + BN_CTX_start(ctx); + t = BN_CTX_get(ctx); + if (t == 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_CTX_end(ctx); + return ret; +} + +static 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)) { + goto err; + } + 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 returns i, or -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; + + j = 0; + while (BN_ucmp(r, &(recp->N)) >= 0) { + if (j++ > 2) { + OPENSSL_PUT_ERROR(BN, BN_R_BAD_RECIPROCAL); + goto err; + } + if (!BN_usub(r, r, &(recp->N))) { + goto err; + } + if (!BN_add_word(d, 1)) { + goto err; + } + } + + r->neg = BN_is_zero(r) ? 0 : m->neg; + d->neg = m->neg ^ recp->N.neg; + ret = 1; + +err: + BN_CTX_end(ctx); + return ret; +} + +static 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); + a = BN_CTX_get(ctx); + if (a == 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); + return ret; +} + +// BN_window_bits_for_exponent_size returns sliding window size for mod_exp with +// a |b| bit exponent. +// +// 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. +static int BN_window_bits_for_exponent_size(int b) { + if (b > 671) { + return 6; + } + if (b > 239) { + return 5; + } + if (b > 79) { + return 4; + } + if (b > 23) { + return 3; + } + return 1; +} + +// TABLE_SIZE is the maximum precomputation table size for *variable* sliding +// windows. This must be 2^(max_window - 1), where max_window is the largest +// value returned from |BN_window_bits_for_exponent_size|. +#define TABLE_SIZE 32 + +// TABLE_BITS_SMALL is the smallest value returned from +// |BN_window_bits_for_exponent_size| when |b| is at most |BN_BITS2| * +// |BN_SMALL_MAX_WORDS| words. +#define TABLE_BITS_SMALL 5 + +// TABLE_SIZE_SMALL is the same as |TABLE_SIZE|, but when |b| is at most +// |BN_BITS2| * |BN_SMALL_MAX_WORDS|. +#define TABLE_SIZE_SMALL (1 << (TABLE_BITS_SMALL - 1)) + +static int mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx) { + int i, j, bits, ret = 0, wstart, window; + int start = 1; + BIGNUM *aa; + // Table of variables obtained from 'ctx' + BIGNUM *val[TABLE_SIZE]; + BN_RECP_CTX recp; + + bits = BN_num_bits(p); + + if (bits == 0) { + // x**0 mod 1 is still zero. + if (BN_is_one(m)) { + BN_zero(r); + return 1; + } + return BN_one(r); + } + + 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. + wstart = bits - 1; // The top bit of the window + + if (!BN_one(r)) { + goto err; + } + + for (;;) { + int wvalue; // The 'value' of the window + int wend; // The bottom bit of the window + + if (!BN_is_bit_set(p, wstart)) { + 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 + 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; + start = 0; + if (wstart < 0) { + break; + } + } + ret = 1; + +err: + BN_CTX_end(ctx); + BN_RECP_CTX_free(&recp); + return ret; +} + +int BN_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, + BN_CTX *ctx) { + if (BN_is_odd(m)) { + return BN_mod_exp_mont(r, a, p, m, ctx, NULL); + } + + return mod_exp_recp(r, a, p, m, ctx); +} + +int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, const BN_MONT_CTX *mont) { + if (!BN_is_odd(m)) { + OPENSSL_PUT_ERROR(BN, BN_R_CALLED_WITH_EVEN_MODULUS); + return 0; + } + int bits = BN_num_bits(p); + if (bits == 0) { + // x**0 mod 1 is still zero. + if (BN_is_one(m)) { + BN_zero(rr); + return 1; + } + return BN_one(rr); + } + + int ret = 0; + BIGNUM *val[TABLE_SIZE]; + BN_MONT_CTX *new_mont = NULL; + + BN_CTX_start(ctx); + BIGNUM *d = BN_CTX_get(ctx); + BIGNUM *r = BN_CTX_get(ctx); + val[0] = BN_CTX_get(ctx); + if (!d || !r || !val[0]) { + goto err; + } + + // Allocate a montgomery context if it was not supplied by the caller. + if (mont == NULL) { + new_mont = BN_MONT_CTX_new_for_modulus(m, ctx); + if (new_mont == NULL) { + goto err; + } + mont = new_mont; + } + + const BIGNUM *aa; + 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; + } + + // We exponentiate by looking at sliding windows of the exponent and + // precomputing powers of |aa|. Windows may be shifted so they always end on a + // set bit, so only precompute odd powers. We compute val[i] = aa^(2*i + 1) + // for i = 0 to 2^(window-1), all in Montgomery form. + int window = BN_window_bits_for_exponent_size(bits); + if (!BN_to_montgomery(val[0], aa, mont, ctx)) { + goto err; + } + if (window > 1) { + if (!BN_mod_mul_montgomery(d, val[0], val[0], mont, ctx)) { + goto err; + } + for (int i = 1; i < 1 << (window - 1); i++) { + val[i] = BN_CTX_get(ctx); + if (val[i] == NULL || + !BN_mod_mul_montgomery(val[i], val[i - 1], d, mont, ctx)) { + goto err; + } + } + } + + if (!bn_one_to_montgomery(r, mont, ctx)) { + goto err; + } + + int r_is_one = 1; + int wstart = bits - 1; // The top bit of the window. + for (;;) { + if (!BN_is_bit_set(p, wstart)) { + if (!r_is_one && !BN_mod_mul_montgomery(r, r, r, mont, ctx)) { + goto err; + } + if (wstart == 0) { + break; + } + wstart--; + continue; + } + + // We now have wstart on a set bit. Find the largest window we can use. + int wvalue = 1; + int wsize = 0; + for (int i = 1; i < window && i <= wstart; i++) { + if (BN_is_bit_set(p, wstart - i)) { + wvalue <<= (i - wsize); + wvalue |= 1; + wsize = i; + } + } + + // Shift |r| to the end of the window. + if (!r_is_one) { + for (int i = 0; i < wsize + 1; i++) { + if (!BN_mod_mul_montgomery(r, r, r, mont, ctx)) { + goto err; + } + } + } + + assert(wvalue & 1); + assert(wvalue < (1 << window)); + if (!BN_mod_mul_montgomery(r, r, val[wvalue >> 1], mont, ctx)) { + goto err; + } + + r_is_one = 0; + if (wstart == wsize) { + break; + } + wstart -= wsize + 1; + } + + if (!BN_from_montgomery(rr, r, mont, ctx)) { + goto err; + } + ret = 1; + +err: + BN_MONT_CTX_free(new_mont); + BN_CTX_end(ctx); + return ret; +} + +int bn_mod_exp_mont_small(BN_ULONG *r, size_t num_r, const BN_ULONG *a, + size_t num_a, const BN_ULONG *p, size_t num_p, + const BN_MONT_CTX *mont) { + size_t num_n = mont->N.width; + if (num_n != num_a || num_n != num_r || num_n > BN_SMALL_MAX_WORDS) { + OPENSSL_PUT_ERROR(BN, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + if (!BN_is_odd(&mont->N)) { + OPENSSL_PUT_ERROR(BN, BN_R_CALLED_WITH_EVEN_MODULUS); + return 0; + } + unsigned bits = 0; + if (num_p != 0) { + bits = BN_num_bits_word(p[num_p - 1]) + (num_p - 1) * BN_BITS2; + } + if (bits == 0) { + OPENSSL_memset(r, 0, num_r * sizeof(BN_ULONG)); + if (!BN_is_one(&mont->N)) { + r[0] = 1; + } + return 1; + } + + // We exponentiate by looking at sliding windows of the exponent and + // precomputing powers of |a|. Windows may be shifted so they always end on a + // set bit, so only precompute odd powers. We compute val[i] = a^(2*i + 1) for + // i = 0 to 2^(window-1), all in Montgomery form. + unsigned window = BN_window_bits_for_exponent_size(bits); + if (window > TABLE_BITS_SMALL) { + window = TABLE_BITS_SMALL; // Tolerate excessively large |p|. + } + int ret = 0; + BN_ULONG val[TABLE_SIZE_SMALL][BN_SMALL_MAX_WORDS]; + OPENSSL_memcpy(val[0], a, num_n * sizeof(BN_ULONG)); + if (window > 1) { + BN_ULONG d[BN_SMALL_MAX_WORDS]; + if (!bn_mod_mul_montgomery_small(d, num_n, val[0], num_n, val[0], num_n, + mont)) { + goto err; + } + for (unsigned i = 1; i < 1u << (window - 1); i++) { + if (!bn_mod_mul_montgomery_small(val[i], num_n, val[i - 1], num_n, d, + num_n, mont)) { + goto err; + } + } + } + + if (!bn_one_to_montgomery_small(r, num_r, mont)) { + goto err; + } + + int r_is_one = 1; + unsigned wstart = bits - 1; // The top bit of the window. + for (;;) { + if (!bn_is_bit_set_words(p, num_p, wstart)) { + if (!r_is_one && + !bn_mod_mul_montgomery_small(r, num_r, r, num_r, r, num_r, mont)) { + goto err; + } + if (wstart == 0) { + break; + } + wstart--; + continue; + } + + // We now have wstart on a set bit. Find the largest window we can use. + unsigned wvalue = 1; + unsigned wsize = 0; + for (unsigned i = 1; i < window && i <= wstart; i++) { + if (bn_is_bit_set_words(p, num_p, wstart - i)) { + wvalue <<= (i - wsize); + wvalue |= 1; + wsize = i; + } + } + + // Shift |r| to the end of the window. + if (!r_is_one) { + for (unsigned i = 0; i < wsize + 1; i++) { + if (!bn_mod_mul_montgomery_small(r, num_r, r, num_r, r, num_r, mont)) { + goto err; + } + } + } + + assert(wvalue & 1); + assert(wvalue < (1u << window)); + if (!bn_mod_mul_montgomery_small(r, num_r, r, num_r, val[wvalue >> 1], + num_n, mont)) { + goto err; + } + + r_is_one = 0; + if (wstart == wsize) { + break; + } + wstart -= wsize + 1; + } + + ret = 1; + +err: + OPENSSL_cleanse(val, sizeof(val)); + return ret; +} + +int bn_mod_inverse_prime_mont_small(BN_ULONG *r, size_t num_r, + const BN_ULONG *a, size_t num_a, + const BN_MONT_CTX *mont) { + const BN_ULONG *p = mont->N.d; + size_t num_p = mont->N.width; + if (num_p > BN_SMALL_MAX_WORDS || num_p == 0) { + OPENSSL_PUT_ERROR(BN, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + + // Per Fermat's Little Theorem, a^-1 = a^(p-2) (mod p) for p prime. + BN_ULONG p_minus_two[BN_SMALL_MAX_WORDS]; + OPENSSL_memcpy(p_minus_two, p, num_p * sizeof(BN_ULONG)); + if (p_minus_two[0] >= 2) { + p_minus_two[0] -= 2; + } else { + p_minus_two[0] -= 2; + for (size_t i = 1; i < num_p; i++) { + if (p_minus_two[i]-- != 0) { + break; + } + } + } + + return bn_mod_exp_mont_small(r, num_r, a, num_a, p_minus_two, num_p, mont); +} + + +// |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 void copy_to_prebuf(const BIGNUM *b, int top, unsigned char *buf, + int idx, int window) { + int i, j; + const int width = 1 << window; + BN_ULONG *table = (BN_ULONG *) buf; + + if (top > b->width) { + top = b->width; // this works because 'buf' is explicitly zeroed + } + + for (i = 0, j = idx; i < top; i++, j += width) { + table[j] = b->d[i]; + } +} + +static int copy_from_prebuf(BIGNUM *b, int top, unsigned char *buf, int idx, + int window) { + int i, j; + const int width = 1 << window; + volatile BN_ULONG *table = (volatile BN_ULONG *)buf; + + if (!bn_wexpand(b, top)) { + 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->width = top; + return 1; +} + +// 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 + +// 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, + const BN_MONT_CTX *mont) { + int i, ret = 0, window, wvalue; + BN_MONT_CTX *new_mont = NULL; + + int numPowers; + unsigned char *powerbufFree = NULL; + int powerbufLen = 0; + unsigned char *powerbuf = NULL; + BIGNUM tmp, am; + BIGNUM *new_a = NULL; + + if (!BN_is_odd(m)) { + OPENSSL_PUT_ERROR(BN, BN_R_CALLED_WITH_EVEN_MODULUS); + return 0; + } + + // Use all bits stored in |p|, rather than |BN_num_bits|, so we do not leak + // whether the top bits are zero. + int max_bits = p->width * BN_BITS2; + int bits = max_bits; + if (bits == 0) { + // x**0 mod 1 is still zero. + if (BN_is_one(m)) { + BN_zero(rr); + return 1; + } + return BN_one(rr); + } + + // Allocate a montgomery context if it was not supplied by the caller. + if (mont == NULL) { + new_mont = BN_MONT_CTX_new_for_modulus(m, ctx); + if (new_mont == NULL) { + goto err; + } + mont = new_mont; + } + + // Use the width in |mont->N|, rather than the copy in |m|. The assembly + // implementation assumes it can use |top| to size R. + int top = mont->N.width; + + if (a->neg || BN_ucmp(a, m) >= 0) { + new_a = BN_new(); + if (new_a == NULL || + !BN_nnmod(new_a, a, m, ctx)) { + goto err; + } + a = new_a; + } + +#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->width) && (16 == p->width) && (BN_num_bits(m) == 1024) && + rsaz_avx2_eligible()) { + if (!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->width = 16; + rr->neg = 0; + 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(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 + + // 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 = OPENSSL_malloc( + powerbufLen + MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH)) == NULL) { + goto err; + } + } + + powerbuf = MOD_EXP_CTIME_ALIGN(powerbufFree); + OPENSSL_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.width = am.width = 0; + tmp.dmax = am.dmax = top; + tmp.neg = am.neg = 0; + tmp.flags = am.flags = BN_FLG_STATIC_DATA; + + if (!bn_one_to_montgomery(&tmp, mont, ctx)) { + goto err; + } + + // prepare a^1 in Montgomery domain + assert(!a->neg); + assert(BN_ucmp(a, m) < 0); + if (!BN_to_montgomery(&am, a, mont, ctx)) { + goto err; + } + +#if defined(OPENSSL_BN_ASM_MONT5) + // 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... + if (window == 5 && top > 1) { + const BN_ULONG *n0 = mont->n0; + BN_ULONG *np; + + // BN_to_montgomery can contaminate words above .top + // [in BN_DEBUG[_DEBUG] build]... + for (i = am.width; i < top; i++) { + am.d[i] = 0; + } + for (i = tmp.width; 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.width, powerbuf, 1); + bn_mul_mont(tmp.d, am.d, am.d, np, n0, top); + bn_scatter5(tmp.d, top, powerbuf, 2); + + // 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); + } + + 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); + + // At this point |bits| is 4 mod 5 and at least -1. (|bits| is the first bit + // that has not been read yet.) + assert(bits >= -1 && (bits == -1 || bits % 5 == 4)); + + // 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 { + const uint8_t *p_bytes = (const uint8_t *)p->d; + assert(bits < max_bits); + // |p = 0| has been handled as a special case, so |max_bits| is at least + // one word. + assert(max_bits >= 64); + + // If the first bit to be read lands in the last byte, unroll the first + // iteration to avoid reading past the bounds of |p->d|. (After the first + // iteration, we are guaranteed to be past the last byte.) Note |bits| + // here is the top bit, inclusive. + if (bits - 4 >= max_bits - 8) { + // Read five bits from |bits-4| through |bits|, inclusive. + wvalue = p_bytes[p->width * BN_BYTES - 1]; + wvalue >>= (bits - 4) & 7; + wvalue &= 0x1f; + bits -= 5; + bn_power5(tmp.d, tmp.d, powerbuf, np, n0, top, wvalue); + } + while (bits >= 0) { + // Read five bits from |bits-4| through |bits|, inclusive. + int first_bit = bits - 4; + uint16_t val; + OPENSSL_memcpy(&val, p_bytes + (first_bit >> 3), sizeof(val)); + val >>= first_bit & 7; + val &= 0x1f; + bits -= 5; + bn_power5(tmp.d, tmp.d, powerbuf, np, n0, top, val); + } + } + + ret = bn_from_montgomery(tmp.d, tmp.d, NULL, np, n0, top); + tmp.width = top; + if (ret) { + if (!BN_copy(rr, &tmp)) { + ret = 0; + } + goto err; // non-zero ret means it's not error + } + } else +#endif + { + copy_to_prebuf(&tmp, top, powerbuf, 0, window); + copy_to_prebuf(&am, top, powerbuf, 1, window); + + // 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_mod_mul_montgomery(&tmp, &am, &am, mont, ctx)) { + goto err; + } + + copy_to_prebuf(&tmp, top, powerbuf, 2, window); + + for (i = 3; i < numPowers; i++) { + // Calculate a^i = a^(i-1) * a + if (!BN_mod_mul_montgomery(&tmp, &am, &tmp, mont, ctx)) { + goto err; + } + + copy_to_prebuf(&tmp, top, powerbuf, i, window); + } + } + + bits--; + for (wvalue = 0, i = bits % window; i >= 0; i--, bits--) { + wvalue = (wvalue << 1) + BN_is_bit_set(p, bits); + } + if (!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_mod_mul_montgomery(&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 (!copy_from_prebuf(&am, top, powerbuf, wvalue, window)) { + goto err; + } + + // Multiply the result into the intermediate result + if (!BN_mod_mul_montgomery(&tmp, &tmp, &am, mont, ctx)) { + goto err; + } + } + } + + // Convert the final result from montgomery to standard format + if (!BN_from_montgomery(rr, &tmp, mont, ctx)) { + goto err; + } + ret = 1; + +err: + BN_MONT_CTX_free(new_mont); + BN_clear_free(new_a); + OPENSSL_free(powerbufFree); + return (ret); +} + +int BN_mod_exp_mont_word(BIGNUM *rr, BN_ULONG a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, + const BN_MONT_CTX *mont) { + BIGNUM a_bignum; + BN_init(&a_bignum); + + int ret = 0; + + if (!BN_set_word(&a_bignum, a)) { + OPENSSL_PUT_ERROR(BN, ERR_R_INTERNAL_ERROR); + goto err; + } + + ret = BN_mod_exp_mont(rr, &a_bignum, p, m, ctx, mont); + +err: + BN_free(&a_bignum); + + return ret; +} + +#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, const BN_MONT_CTX *mont) { + BIGNUM tmp; + BN_init(&tmp); + + int ret = 0; + BN_MONT_CTX *new_mont = NULL; + + // Allocate a montgomery context if it was not supplied by the caller. + if (mont == NULL) { + new_mont = BN_MONT_CTX_new_for_modulus(m, ctx); + if (new_mont == NULL) { + goto err; + } + mont = new_mont; + } + + // BN_mod_mul_montgomery removes one Montgomery factor, so passing one + // Montgomery-encoded and one non-Montgomery-encoded value gives a + // non-Montgomery-encoded result. + if (!BN_mod_exp_mont(rr, a1, p1, m, ctx, mont) || + !BN_mod_exp_mont(&tmp, a2, p2, m, ctx, mont) || + !BN_to_montgomery(rr, rr, mont, ctx) || + !BN_mod_mul_montgomery(rr, rr, &tmp, mont, ctx)) { + goto err; + } + + ret = 1; + +err: + BN_MONT_CTX_free(new_mont); + BN_free(&tmp); + + return ret; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/exponentiation.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/exponentiation.c.grpc_back new file mode 100644 index 0000000..c85c00b --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/exponentiation.c.grpc_back @@ -0,0 +1,1356 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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-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 +#include + +#include +#include +#include + +#include "internal.h" + + +#if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64) +#define OPENSSL_BN_ASM_MONT5 +#define RSAZ_ENABLED + +#include "rsaz_exp.h" + +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_from_montgomery(BN_ULONG *rp, const BN_ULONG *ap, + const BN_ULONG *not_used, const BN_ULONG *np, + const BN_ULONG *n0, int num); +#endif + +int BN_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) { + int i, bits, ret = 0; + BIGNUM *v, *rr; + + 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)) { + goto err; + } + ret = 1; + +err: + BN_CTX_end(ctx); + return ret; +} + +typedef struct bn_recp_ctx_st { + BIGNUM N; // the divisor + BIGNUM Nr; // the reciprocal + int num_bits; + int shift; + int flags; +} BN_RECP_CTX; + +static 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; +} + +static void BN_RECP_CTX_free(BN_RECP_CTX *recp) { + if (recp == NULL) { + return; + } + + BN_free(&recp->N); + BN_free(&recp->Nr); +} + +static 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; +} + +// 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 +static int BN_reciprocal(BIGNUM *r, const BIGNUM *m, int len, BN_CTX *ctx) { + int ret = -1; + BIGNUM *t; + + BN_CTX_start(ctx); + t = BN_CTX_get(ctx); + if (t == 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_CTX_end(ctx); + return ret; +} + +static 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)) { + goto err; + } + 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 returns i, or -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; + + j = 0; + while (BN_ucmp(r, &(recp->N)) >= 0) { + if (j++ > 2) { + OPENSSL_PUT_ERROR(BN, BN_R_BAD_RECIPROCAL); + goto err; + } + if (!BN_usub(r, r, &(recp->N))) { + goto err; + } + if (!BN_add_word(d, 1)) { + goto err; + } + } + + r->neg = BN_is_zero(r) ? 0 : m->neg; + d->neg = m->neg ^ recp->N.neg; + ret = 1; + +err: + BN_CTX_end(ctx); + return ret; +} + +static 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); + a = BN_CTX_get(ctx); + if (a == 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); + return ret; +} + +// BN_window_bits_for_exponent_size returns sliding window size for mod_exp with +// a |b| bit exponent. +// +// 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. +static int BN_window_bits_for_exponent_size(int b) { + if (b > 671) { + return 6; + } + if (b > 239) { + return 5; + } + if (b > 79) { + return 4; + } + if (b > 23) { + return 3; + } + return 1; +} + +// TABLE_SIZE is the maximum precomputation table size for *variable* sliding +// windows. This must be 2^(max_window - 1), where max_window is the largest +// value returned from |BN_window_bits_for_exponent_size|. +#define TABLE_SIZE 32 + +// TABLE_BITS_SMALL is the smallest value returned from +// |BN_window_bits_for_exponent_size| when |b| is at most |BN_BITS2| * +// |BN_SMALL_MAX_WORDS| words. +#define TABLE_BITS_SMALL 5 + +// TABLE_SIZE_SMALL is the same as |TABLE_SIZE|, but when |b| is at most +// |BN_BITS2| * |BN_SMALL_MAX_WORDS|. +#define TABLE_SIZE_SMALL (1 << (TABLE_BITS_SMALL - 1)) + +static int mod_exp_recp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx) { + int i, j, bits, ret = 0, wstart, window; + int start = 1; + BIGNUM *aa; + // Table of variables obtained from 'ctx' + BIGNUM *val[TABLE_SIZE]; + BN_RECP_CTX recp; + + bits = BN_num_bits(p); + + if (bits == 0) { + // x**0 mod 1 is still zero. + if (BN_is_one(m)) { + BN_zero(r); + return 1; + } + return BN_one(r); + } + + 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. + wstart = bits - 1; // The top bit of the window + + if (!BN_one(r)) { + goto err; + } + + for (;;) { + int wvalue; // The 'value' of the window + int wend; // The bottom bit of the window + + if (!BN_is_bit_set(p, wstart)) { + 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 + 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; + start = 0; + if (wstart < 0) { + break; + } + } + ret = 1; + +err: + BN_CTX_end(ctx); + BN_RECP_CTX_free(&recp); + return ret; +} + +int BN_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, const BIGNUM *m, + BN_CTX *ctx) { + if (BN_is_odd(m)) { + return BN_mod_exp_mont(r, a, p, m, ctx, NULL); + } + + return mod_exp_recp(r, a, p, m, ctx); +} + +int BN_mod_exp_mont(BIGNUM *rr, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, const BN_MONT_CTX *mont) { + if (!BN_is_odd(m)) { + OPENSSL_PUT_ERROR(BN, BN_R_CALLED_WITH_EVEN_MODULUS); + return 0; + } + int bits = BN_num_bits(p); + if (bits == 0) { + // x**0 mod 1 is still zero. + if (BN_is_one(m)) { + BN_zero(rr); + return 1; + } + return BN_one(rr); + } + + int ret = 0; + BIGNUM *val[TABLE_SIZE]; + BN_MONT_CTX *new_mont = NULL; + + BN_CTX_start(ctx); + BIGNUM *d = BN_CTX_get(ctx); + BIGNUM *r = BN_CTX_get(ctx); + val[0] = BN_CTX_get(ctx); + if (!d || !r || !val[0]) { + goto err; + } + + // Allocate a montgomery context if it was not supplied by the caller. + if (mont == NULL) { + new_mont = BN_MONT_CTX_new_for_modulus(m, ctx); + if (new_mont == NULL) { + goto err; + } + mont = new_mont; + } + + const BIGNUM *aa; + 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; + } + + // We exponentiate by looking at sliding windows of the exponent and + // precomputing powers of |aa|. Windows may be shifted so they always end on a + // set bit, so only precompute odd powers. We compute val[i] = aa^(2*i + 1) + // for i = 0 to 2^(window-1), all in Montgomery form. + int window = BN_window_bits_for_exponent_size(bits); + if (!BN_to_montgomery(val[0], aa, mont, ctx)) { + goto err; + } + if (window > 1) { + if (!BN_mod_mul_montgomery(d, val[0], val[0], mont, ctx)) { + goto err; + } + for (int i = 1; i < 1 << (window - 1); i++) { + val[i] = BN_CTX_get(ctx); + if (val[i] == NULL || + !BN_mod_mul_montgomery(val[i], val[i - 1], d, mont, ctx)) { + goto err; + } + } + } + + if (!bn_one_to_montgomery(r, mont, ctx)) { + goto err; + } + + int r_is_one = 1; + int wstart = bits - 1; // The top bit of the window. + for (;;) { + if (!BN_is_bit_set(p, wstart)) { + if (!r_is_one && !BN_mod_mul_montgomery(r, r, r, mont, ctx)) { + goto err; + } + if (wstart == 0) { + break; + } + wstart--; + continue; + } + + // We now have wstart on a set bit. Find the largest window we can use. + int wvalue = 1; + int wsize = 0; + for (int i = 1; i < window && i <= wstart; i++) { + if (BN_is_bit_set(p, wstart - i)) { + wvalue <<= (i - wsize); + wvalue |= 1; + wsize = i; + } + } + + // Shift |r| to the end of the window. + if (!r_is_one) { + for (int i = 0; i < wsize + 1; i++) { + if (!BN_mod_mul_montgomery(r, r, r, mont, ctx)) { + goto err; + } + } + } + + assert(wvalue & 1); + assert(wvalue < (1 << window)); + if (!BN_mod_mul_montgomery(r, r, val[wvalue >> 1], mont, ctx)) { + goto err; + } + + r_is_one = 0; + if (wstart == wsize) { + break; + } + wstart -= wsize + 1; + } + + if (!BN_from_montgomery(rr, r, mont, ctx)) { + goto err; + } + ret = 1; + +err: + BN_MONT_CTX_free(new_mont); + BN_CTX_end(ctx); + return ret; +} + +int bn_mod_exp_mont_small(BN_ULONG *r, size_t num_r, const BN_ULONG *a, + size_t num_a, const BN_ULONG *p, size_t num_p, + const BN_MONT_CTX *mont) { + size_t num_n = mont->N.width; + if (num_n != num_a || num_n != num_r || num_n > BN_SMALL_MAX_WORDS) { + OPENSSL_PUT_ERROR(BN, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + if (!BN_is_odd(&mont->N)) { + OPENSSL_PUT_ERROR(BN, BN_R_CALLED_WITH_EVEN_MODULUS); + return 0; + } + unsigned bits = 0; + if (num_p != 0) { + bits = BN_num_bits_word(p[num_p - 1]) + (num_p - 1) * BN_BITS2; + } + if (bits == 0) { + OPENSSL_memset(r, 0, num_r * sizeof(BN_ULONG)); + if (!BN_is_one(&mont->N)) { + r[0] = 1; + } + return 1; + } + + // We exponentiate by looking at sliding windows of the exponent and + // precomputing powers of |a|. Windows may be shifted so they always end on a + // set bit, so only precompute odd powers. We compute val[i] = a^(2*i + 1) for + // i = 0 to 2^(window-1), all in Montgomery form. + unsigned window = BN_window_bits_for_exponent_size(bits); + if (window > TABLE_BITS_SMALL) { + window = TABLE_BITS_SMALL; // Tolerate excessively large |p|. + } + int ret = 0; + BN_ULONG val[TABLE_SIZE_SMALL][BN_SMALL_MAX_WORDS]; + OPENSSL_memcpy(val[0], a, num_n * sizeof(BN_ULONG)); + if (window > 1) { + BN_ULONG d[BN_SMALL_MAX_WORDS]; + if (!bn_mod_mul_montgomery_small(d, num_n, val[0], num_n, val[0], num_n, + mont)) { + goto err; + } + for (unsigned i = 1; i < 1u << (window - 1); i++) { + if (!bn_mod_mul_montgomery_small(val[i], num_n, val[i - 1], num_n, d, + num_n, mont)) { + goto err; + } + } + } + + if (!bn_one_to_montgomery_small(r, num_r, mont)) { + goto err; + } + + int r_is_one = 1; + unsigned wstart = bits - 1; // The top bit of the window. + for (;;) { + if (!bn_is_bit_set_words(p, num_p, wstart)) { + if (!r_is_one && + !bn_mod_mul_montgomery_small(r, num_r, r, num_r, r, num_r, mont)) { + goto err; + } + if (wstart == 0) { + break; + } + wstart--; + continue; + } + + // We now have wstart on a set bit. Find the largest window we can use. + unsigned wvalue = 1; + unsigned wsize = 0; + for (unsigned i = 1; i < window && i <= wstart; i++) { + if (bn_is_bit_set_words(p, num_p, wstart - i)) { + wvalue <<= (i - wsize); + wvalue |= 1; + wsize = i; + } + } + + // Shift |r| to the end of the window. + if (!r_is_one) { + for (unsigned i = 0; i < wsize + 1; i++) { + if (!bn_mod_mul_montgomery_small(r, num_r, r, num_r, r, num_r, mont)) { + goto err; + } + } + } + + assert(wvalue & 1); + assert(wvalue < (1u << window)); + if (!bn_mod_mul_montgomery_small(r, num_r, r, num_r, val[wvalue >> 1], + num_n, mont)) { + goto err; + } + + r_is_one = 0; + if (wstart == wsize) { + break; + } + wstart -= wsize + 1; + } + + ret = 1; + +err: + OPENSSL_cleanse(val, sizeof(val)); + return ret; +} + +int bn_mod_inverse_prime_mont_small(BN_ULONG *r, size_t num_r, + const BN_ULONG *a, size_t num_a, + const BN_MONT_CTX *mont) { + const BN_ULONG *p = mont->N.d; + size_t num_p = mont->N.width; + if (num_p > BN_SMALL_MAX_WORDS || num_p == 0) { + OPENSSL_PUT_ERROR(BN, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + + // Per Fermat's Little Theorem, a^-1 = a^(p-2) (mod p) for p prime. + BN_ULONG p_minus_two[BN_SMALL_MAX_WORDS]; + OPENSSL_memcpy(p_minus_two, p, num_p * sizeof(BN_ULONG)); + if (p_minus_two[0] >= 2) { + p_minus_two[0] -= 2; + } else { + p_minus_two[0] -= 2; + for (size_t i = 1; i < num_p; i++) { + if (p_minus_two[i]-- != 0) { + break; + } + } + } + + return bn_mod_exp_mont_small(r, num_r, a, num_a, p_minus_two, num_p, mont); +} + + +// |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 void copy_to_prebuf(const BIGNUM *b, int top, unsigned char *buf, + int idx, int window) { + int i, j; + const int width = 1 << window; + BN_ULONG *table = (BN_ULONG *) buf; + + if (top > b->width) { + top = b->width; // this works because 'buf' is explicitly zeroed + } + + for (i = 0, j = idx; i < top; i++, j += width) { + table[j] = b->d[i]; + } +} + +static int copy_from_prebuf(BIGNUM *b, int top, unsigned char *buf, int idx, + int window) { + int i, j; + const int width = 1 << window; + volatile BN_ULONG *table = (volatile BN_ULONG *)buf; + + if (!bn_wexpand(b, top)) { + 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->width = top; + return 1; +} + +// 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 + +// 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, + const BN_MONT_CTX *mont) { + int i, ret = 0, window, wvalue; + BN_MONT_CTX *new_mont = NULL; + + int numPowers; + unsigned char *powerbufFree = NULL; + int powerbufLen = 0; + unsigned char *powerbuf = NULL; + BIGNUM tmp, am; + BIGNUM *new_a = NULL; + + if (!BN_is_odd(m)) { + OPENSSL_PUT_ERROR(BN, BN_R_CALLED_WITH_EVEN_MODULUS); + return 0; + } + + // Use all bits stored in |p|, rather than |BN_num_bits|, so we do not leak + // whether the top bits are zero. + int max_bits = p->width * BN_BITS2; + int bits = max_bits; + if (bits == 0) { + // x**0 mod 1 is still zero. + if (BN_is_one(m)) { + BN_zero(rr); + return 1; + } + return BN_one(rr); + } + + // Allocate a montgomery context if it was not supplied by the caller. + if (mont == NULL) { + new_mont = BN_MONT_CTX_new_for_modulus(m, ctx); + if (new_mont == NULL) { + goto err; + } + mont = new_mont; + } + + // Use the width in |mont->N|, rather than the copy in |m|. The assembly + // implementation assumes it can use |top| to size R. + int top = mont->N.width; + + if (a->neg || BN_ucmp(a, m) >= 0) { + new_a = BN_new(); + if (new_a == NULL || + !BN_nnmod(new_a, a, m, ctx)) { + goto err; + } + a = new_a; + } + +#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->width) && (16 == p->width) && (BN_num_bits(m) == 1024) && + rsaz_avx2_eligible()) { + if (!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->width = 16; + rr->neg = 0; + 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(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 + + // 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 = OPENSSL_malloc( + powerbufLen + MOD_EXP_CTIME_MIN_CACHE_LINE_WIDTH)) == NULL) { + goto err; + } + } + + powerbuf = MOD_EXP_CTIME_ALIGN(powerbufFree); + OPENSSL_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.width = am.width = 0; + tmp.dmax = am.dmax = top; + tmp.neg = am.neg = 0; + tmp.flags = am.flags = BN_FLG_STATIC_DATA; + + if (!bn_one_to_montgomery(&tmp, mont, ctx)) { + goto err; + } + + // prepare a^1 in Montgomery domain + assert(!a->neg); + assert(BN_ucmp(a, m) < 0); + if (!BN_to_montgomery(&am, a, mont, ctx)) { + goto err; + } + +#if defined(OPENSSL_BN_ASM_MONT5) + // 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... + if (window == 5 && top > 1) { + const BN_ULONG *n0 = mont->n0; + BN_ULONG *np; + + // BN_to_montgomery can contaminate words above .top + // [in BN_DEBUG[_DEBUG] build]... + for (i = am.width; i < top; i++) { + am.d[i] = 0; + } + for (i = tmp.width; 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.width, powerbuf, 1); + bn_mul_mont(tmp.d, am.d, am.d, np, n0, top); + bn_scatter5(tmp.d, top, powerbuf, 2); + + // 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); + } + + 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); + + // At this point |bits| is 4 mod 5 and at least -1. (|bits| is the first bit + // that has not been read yet.) + assert(bits >= -1 && (bits == -1 || bits % 5 == 4)); + + // 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 { + const uint8_t *p_bytes = (const uint8_t *)p->d; + assert(bits < max_bits); + // |p = 0| has been handled as a special case, so |max_bits| is at least + // one word. + assert(max_bits >= 64); + + // If the first bit to be read lands in the last byte, unroll the first + // iteration to avoid reading past the bounds of |p->d|. (After the first + // iteration, we are guaranteed to be past the last byte.) Note |bits| + // here is the top bit, inclusive. + if (bits - 4 >= max_bits - 8) { + // Read five bits from |bits-4| through |bits|, inclusive. + wvalue = p_bytes[p->width * BN_BYTES - 1]; + wvalue >>= (bits - 4) & 7; + wvalue &= 0x1f; + bits -= 5; + bn_power5(tmp.d, tmp.d, powerbuf, np, n0, top, wvalue); + } + while (bits >= 0) { + // Read five bits from |bits-4| through |bits|, inclusive. + int first_bit = bits - 4; + uint16_t val; + OPENSSL_memcpy(&val, p_bytes + (first_bit >> 3), sizeof(val)); + val >>= first_bit & 7; + val &= 0x1f; + bits -= 5; + bn_power5(tmp.d, tmp.d, powerbuf, np, n0, top, val); + } + } + + ret = bn_from_montgomery(tmp.d, tmp.d, NULL, np, n0, top); + tmp.width = top; + if (ret) { + if (!BN_copy(rr, &tmp)) { + ret = 0; + } + goto err; // non-zero ret means it's not error + } + } else +#endif + { + copy_to_prebuf(&tmp, top, powerbuf, 0, window); + copy_to_prebuf(&am, top, powerbuf, 1, window); + + // 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_mod_mul_montgomery(&tmp, &am, &am, mont, ctx)) { + goto err; + } + + copy_to_prebuf(&tmp, top, powerbuf, 2, window); + + for (i = 3; i < numPowers; i++) { + // Calculate a^i = a^(i-1) * a + if (!BN_mod_mul_montgomery(&tmp, &am, &tmp, mont, ctx)) { + goto err; + } + + copy_to_prebuf(&tmp, top, powerbuf, i, window); + } + } + + bits--; + for (wvalue = 0, i = bits % window; i >= 0; i--, bits--) { + wvalue = (wvalue << 1) + BN_is_bit_set(p, bits); + } + if (!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_mod_mul_montgomery(&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 (!copy_from_prebuf(&am, top, powerbuf, wvalue, window)) { + goto err; + } + + // Multiply the result into the intermediate result + if (!BN_mod_mul_montgomery(&tmp, &tmp, &am, mont, ctx)) { + goto err; + } + } + } + + // Convert the final result from montgomery to standard format + if (!BN_from_montgomery(rr, &tmp, mont, ctx)) { + goto err; + } + ret = 1; + +err: + BN_MONT_CTX_free(new_mont); + BN_clear_free(new_a); + OPENSSL_free(powerbufFree); + return (ret); +} + +int BN_mod_exp_mont_word(BIGNUM *rr, BN_ULONG a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, + const BN_MONT_CTX *mont) { + BIGNUM a_bignum; + BN_init(&a_bignum); + + int ret = 0; + + if (!BN_set_word(&a_bignum, a)) { + OPENSSL_PUT_ERROR(BN, ERR_R_INTERNAL_ERROR); + goto err; + } + + ret = BN_mod_exp_mont(rr, &a_bignum, p, m, ctx, mont); + +err: + BN_free(&a_bignum); + + return ret; +} + +#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, const BN_MONT_CTX *mont) { + BIGNUM tmp; + BN_init(&tmp); + + int ret = 0; + BN_MONT_CTX *new_mont = NULL; + + // Allocate a montgomery context if it was not supplied by the caller. + if (mont == NULL) { + new_mont = BN_MONT_CTX_new_for_modulus(m, ctx); + if (new_mont == NULL) { + goto err; + } + mont = new_mont; + } + + // BN_mod_mul_montgomery removes one Montgomery factor, so passing one + // Montgomery-encoded and one non-Montgomery-encoded value gives a + // non-Montgomery-encoded result. + if (!BN_mod_exp_mont(rr, a1, p1, m, ctx, mont) || + !BN_mod_exp_mont(&tmp, a2, p2, m, ctx, mont) || + !BN_to_montgomery(rr, rr, mont, ctx) || + !BN_mod_mul_montgomery(rr, rr, &tmp, mont, ctx)) { + goto err; + } + + ret = 1; + +err: + BN_MONT_CTX_free(new_mont); + BN_free(&tmp); + + return ret; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/gcd.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/gcd.c new file mode 100644 index 0000000..7cd752d --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/gcd.c @@ -0,0 +1,683 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 + +#include "internal.h" + + +static BN_ULONG word_is_odd_mask(BN_ULONG a) { return (BN_ULONG)0 - (a & 1); } + +static void maybe_rshift1_words(BN_ULONG *a, BN_ULONG mask, BN_ULONG *tmp, + size_t num) { + bn_rshift1_words(tmp, a, num); + bn_select_words(a, mask, tmp, a, num); +} + +static void maybe_rshift1_words_carry(BN_ULONG *a, BN_ULONG carry, + BN_ULONG mask, BN_ULONG *tmp, + size_t num) { + maybe_rshift1_words(a, mask, tmp, num); + if (num != 0) { + carry &= mask; + a[num - 1] |= carry << (BN_BITS2-1); + } +} + +static BN_ULONG maybe_add_words(BN_ULONG *a, BN_ULONG mask, const BN_ULONG *b, + BN_ULONG *tmp, size_t num) { + BN_ULONG carry = bn_add_words(tmp, a, b, num); + bn_select_words(a, mask, tmp, a, num); + return carry & mask; +} + +static int bn_gcd_consttime(BIGNUM *r, unsigned *out_shift, const BIGNUM *x, + const BIGNUM *y, BN_CTX *ctx) { + size_t width = x->width > y->width ? x->width : y->width; + if (width == 0) { + *out_shift = 0; + BN_zero(r); + return 1; + } + + // This is a constant-time implementation of Stein's algorithm (binary GCD). + int ret = 0; + BN_CTX_start(ctx); + BIGNUM *u = BN_CTX_get(ctx); + BIGNUM *v = BN_CTX_get(ctx); + BIGNUM *tmp = BN_CTX_get(ctx); + if (u == NULL || v == NULL || tmp == NULL || + !BN_copy(u, x) || + !BN_copy(v, y) || + !bn_resize_words(u, width) || + !bn_resize_words(v, width) || + !bn_resize_words(tmp, width)) { + goto err; + } + + // Each loop iteration halves at least one of |u| and |v|. Thus we need at + // most the combined bit width of inputs for at least one value to be zero. + unsigned x_bits = x->width * BN_BITS2, y_bits = y->width * BN_BITS2; + unsigned num_iters = x_bits + y_bits; + if (num_iters < x_bits) { + OPENSSL_PUT_ERROR(BN, BN_R_BIGNUM_TOO_LONG); + goto err; + } + + unsigned shift = 0; + for (unsigned i = 0; i < num_iters; i++) { + BN_ULONG both_odd = word_is_odd_mask(u->d[0]) & word_is_odd_mask(v->d[0]); + + // If both |u| and |v| are odd, subtract the smaller from the larger. + BN_ULONG u_less_than_v = + (BN_ULONG)0 - bn_sub_words(tmp->d, u->d, v->d, width); + bn_select_words(u->d, both_odd & ~u_less_than_v, tmp->d, u->d, width); + bn_sub_words(tmp->d, v->d, u->d, width); + bn_select_words(v->d, both_odd & u_less_than_v, tmp->d, v->d, width); + + // At least one of |u| and |v| is now even. + BN_ULONG u_is_odd = word_is_odd_mask(u->d[0]); + BN_ULONG v_is_odd = word_is_odd_mask(v->d[0]); + assert(!(u_is_odd & v_is_odd)); + + // If both are even, the final GCD gains a factor of two. + shift += 1 & (~u_is_odd & ~v_is_odd); + + // Halve any which are even. + maybe_rshift1_words(u->d, ~u_is_odd, tmp->d, width); + maybe_rshift1_words(v->d, ~v_is_odd, tmp->d, width); + } + + // One of |u| or |v| is zero at this point. The algorithm usually makes |u| + // zero, unless |y| was already zero on input. Fix this by combining the + // values. + assert(BN_is_zero(u) || BN_is_zero(v)); + for (size_t i = 0; i < width; i++) { + v->d[i] |= u->d[i]; + } + + *out_shift = shift; + ret = bn_set_words(r, v->d, width); + +err: + BN_CTX_end(ctx); + return ret; +} + +int BN_gcd(BIGNUM *r, const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx) { + unsigned shift; + return bn_gcd_consttime(r, &shift, x, y, ctx) && + BN_lshift(r, r, shift); +} + +int bn_is_relatively_prime(int *out_relatively_prime, const BIGNUM *x, + const BIGNUM *y, BN_CTX *ctx) { + int ret = 0; + BN_CTX_start(ctx); + unsigned shift; + BIGNUM *gcd = BN_CTX_get(ctx); + if (gcd == NULL || + !bn_gcd_consttime(gcd, &shift, x, y, ctx)) { + goto err; + } + + // Check that 2^|shift| * |gcd| is one. + if (gcd->width == 0) { + *out_relatively_prime = 0; + } else { + BN_ULONG mask = shift | (gcd->d[0] ^ 1); + for (int i = 1; i < gcd->width; i++) { + mask |= gcd->d[i]; + } + *out_relatively_prime = mask == 0; + } + ret = 1; + +err: + BN_CTX_end(ctx); + return ret; +} + +int bn_lcm_consttime(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) { + BN_CTX_start(ctx); + unsigned shift; + BIGNUM *gcd = BN_CTX_get(ctx); + int ret = gcd != NULL && + bn_mul_consttime(r, a, b, ctx) && + bn_gcd_consttime(gcd, &shift, a, b, ctx) && + bn_div_consttime(r, NULL, r, gcd, ctx) && + bn_rshift_secret_shift(r, r, shift, ctx); + BN_CTX_end(ctx); + return ret; +} + +int bn_mod_inverse_consttime(BIGNUM *r, int *out_no_inverse, const BIGNUM *a, + const BIGNUM *n, BN_CTX *ctx) { + *out_no_inverse = 0; + if (BN_is_negative(a) || BN_ucmp(a, n) >= 0) { + OPENSSL_PUT_ERROR(BN, BN_R_INPUT_NOT_REDUCED); + return 0; + } + if (BN_is_zero(a)) { + if (BN_is_one(n)) { + BN_zero(r); + return 1; + } + *out_no_inverse = 1; + OPENSSL_PUT_ERROR(BN, BN_R_NO_INVERSE); + return 0; + } + + // This is a constant-time implementation of the extended binary GCD + // algorithm. It is adapted from the Handbook of Applied Cryptography, section + // 14.4.3, algorithm 14.51, and modified to bound coefficients and avoid + // negative numbers. + // + // For more details and proof of correctness, see + // https://github.com/mit-plv/fiat-crypto/pull/333. In particular, see |step| + // and |mod_inverse_consttime| for the algorithm in Gallina and see + // |mod_inverse_consttime_spec| for the correctness result. + + if (!BN_is_odd(a) && !BN_is_odd(n)) { + *out_no_inverse = 1; + OPENSSL_PUT_ERROR(BN, BN_R_NO_INVERSE); + return 0; + } + + // This function exists to compute the RSA private exponent, where |a| is one + // word. We'll thus use |a_width| when available. + size_t n_width = n->width, a_width = a->width; + if (a_width > n_width) { + a_width = n_width; + } + + int ret = 0; + BN_CTX_start(ctx); + BIGNUM *u = BN_CTX_get(ctx); + BIGNUM *v = BN_CTX_get(ctx); + BIGNUM *A = BN_CTX_get(ctx); + BIGNUM *B = BN_CTX_get(ctx); + BIGNUM *C = BN_CTX_get(ctx); + BIGNUM *D = BN_CTX_get(ctx); + BIGNUM *tmp = BN_CTX_get(ctx); + BIGNUM *tmp2 = BN_CTX_get(ctx); + if (u == NULL || v == NULL || A == NULL || B == NULL || C == NULL || + D == NULL || tmp == NULL || tmp2 == NULL || + !BN_copy(u, a) || + !BN_copy(v, n) || + !BN_one(A) || + !BN_one(D) || + // For convenience, size |u| and |v| equivalently. + !bn_resize_words(u, n_width) || + !bn_resize_words(v, n_width) || + // |A| and |C| are bounded by |m|. + !bn_resize_words(A, n_width) || + !bn_resize_words(C, n_width) || + // |B| and |D| are bounded by |a|. + !bn_resize_words(B, a_width) || + !bn_resize_words(D, a_width) || + // |tmp| and |tmp2| may be used at either size. + !bn_resize_words(tmp, n_width) || + !bn_resize_words(tmp2, n_width)) { + goto err; + } + + // Each loop iteration halves at least one of |u| and |v|. Thus we need at + // most the combined bit width of inputs for at least one value to be zero. + unsigned a_bits = a_width * BN_BITS2, n_bits = n_width * BN_BITS2; + unsigned num_iters = a_bits + n_bits; + if (num_iters < a_bits) { + OPENSSL_PUT_ERROR(BN, BN_R_BIGNUM_TOO_LONG); + goto err; + } + + // Before and after each loop iteration, the following hold: + // + // u = A*a - B*n + // v = D*n - C*a + // 0 < u <= a + // 0 <= v <= n + // 0 <= A < n + // 0 <= B <= a + // 0 <= C < n + // 0 <= D <= a + // + // After each loop iteration, u and v only get smaller, and at least one of + // them shrinks by at least a factor of two. + for (unsigned i = 0; i < num_iters; i++) { + BN_ULONG both_odd = word_is_odd_mask(u->d[0]) & word_is_odd_mask(v->d[0]); + + // If both |u| and |v| are odd, subtract the smaller from the larger. + BN_ULONG v_less_than_u = + (BN_ULONG)0 - bn_sub_words(tmp->d, v->d, u->d, n_width); + bn_select_words(v->d, both_odd & ~v_less_than_u, tmp->d, v->d, n_width); + bn_sub_words(tmp->d, u->d, v->d, n_width); + bn_select_words(u->d, both_odd & v_less_than_u, tmp->d, u->d, n_width); + + // If we updated one of the values, update the corresponding coefficient. + BN_ULONG carry = bn_add_words(tmp->d, A->d, C->d, n_width); + carry -= bn_sub_words(tmp2->d, tmp->d, n->d, n_width); + bn_select_words(tmp->d, carry, tmp->d, tmp2->d, n_width); + bn_select_words(A->d, both_odd & v_less_than_u, tmp->d, A->d, n_width); + bn_select_words(C->d, both_odd & ~v_less_than_u, tmp->d, C->d, n_width); + + bn_add_words(tmp->d, B->d, D->d, a_width); + bn_sub_words(tmp2->d, tmp->d, a->d, a_width); + bn_select_words(tmp->d, carry, tmp->d, tmp2->d, a_width); + bn_select_words(B->d, both_odd & v_less_than_u, tmp->d, B->d, a_width); + bn_select_words(D->d, both_odd & ~v_less_than_u, tmp->d, D->d, a_width); + + // Our loop invariants hold at this point. Additionally, exactly one of |u| + // and |v| is now even. + BN_ULONG u_is_even = ~word_is_odd_mask(u->d[0]); + BN_ULONG v_is_even = ~word_is_odd_mask(v->d[0]); + assert(u_is_even != v_is_even); + + // Halve the even one and adjust the corresponding coefficient. + maybe_rshift1_words(u->d, u_is_even, tmp->d, n_width); + BN_ULONG A_or_B_is_odd = + word_is_odd_mask(A->d[0]) | word_is_odd_mask(B->d[0]); + BN_ULONG A_carry = + maybe_add_words(A->d, A_or_B_is_odd & u_is_even, n->d, tmp->d, n_width); + BN_ULONG B_carry = + maybe_add_words(B->d, A_or_B_is_odd & u_is_even, a->d, tmp->d, a_width); + maybe_rshift1_words_carry(A->d, A_carry, u_is_even, tmp->d, n_width); + maybe_rshift1_words_carry(B->d, B_carry, u_is_even, tmp->d, a_width); + + maybe_rshift1_words(v->d, v_is_even, tmp->d, n_width); + BN_ULONG C_or_D_is_odd = + word_is_odd_mask(C->d[0]) | word_is_odd_mask(D->d[0]); + BN_ULONG C_carry = + maybe_add_words(C->d, C_or_D_is_odd & v_is_even, n->d, tmp->d, n_width); + BN_ULONG D_carry = + maybe_add_words(D->d, C_or_D_is_odd & v_is_even, a->d, tmp->d, a_width); + maybe_rshift1_words_carry(C->d, C_carry, v_is_even, tmp->d, n_width); + maybe_rshift1_words_carry(D->d, D_carry, v_is_even, tmp->d, a_width); + } + + assert(BN_is_zero(v)); + if (!BN_is_one(u)) { + *out_no_inverse = 1; + OPENSSL_PUT_ERROR(BN, BN_R_NO_INVERSE); + goto err; + } + + ret = BN_copy(r, A) != NULL; + +err: + BN_CTX_end(ctx); + return ret; +} + +int BN_mod_inverse_odd(BIGNUM *out, int *out_no_inverse, const BIGNUM *a, + const BIGNUM *n, BN_CTX *ctx) { + *out_no_inverse = 0; + + if (!BN_is_odd(n)) { + OPENSSL_PUT_ERROR(BN, BN_R_CALLED_WITH_EVEN_MODULUS); + return 0; + } + + if (BN_is_negative(a) || BN_cmp(a, n) >= 0) { + OPENSSL_PUT_ERROR(BN, BN_R_INPUT_NOT_REDUCED); + return 0; + } + + BIGNUM *A, *B, *X, *Y; + int ret = 0; + int sign; + + BN_CTX_start(ctx); + A = BN_CTX_get(ctx); + B = BN_CTX_get(ctx); + X = BN_CTX_get(ctx); + Y = BN_CTX_get(ctx); + if (Y == NULL) { + goto err; + } + + BIGNUM *R = out; + + BN_zero(Y); + if (!BN_one(X) || BN_copy(B, a) == NULL || BN_copy(A, n) == NULL) { + goto err; + } + A->neg = 0; + 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|). + + // 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 systems, 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; + } + } + } + + if (!BN_is_one(A)) { + *out_no_inverse = 1; + OPENSSL_PUT_ERROR(BN, BN_R_NO_INVERSE); + goto err; + } + + // 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|). + + // 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; + } + } + + ret = 1; + +err: + BN_CTX_end(ctx); + return ret; +} + +BIGNUM *BN_mod_inverse(BIGNUM *out, const BIGNUM *a, const BIGNUM *n, + BN_CTX *ctx) { + BIGNUM *new_out = NULL; + if (out == NULL) { + new_out = BN_new(); + if (new_out == NULL) { + OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE); + return NULL; + } + out = new_out; + } + + int ok = 0; + BIGNUM *a_reduced = NULL; + if (a->neg || BN_ucmp(a, n) >= 0) { + a_reduced = BN_dup(a); + if (a_reduced == NULL) { + goto err; + } + if (!BN_nnmod(a_reduced, a_reduced, n, ctx)) { + goto err; + } + a = a_reduced; + } + + int no_inverse; + if (!BN_is_odd(n)) { + if (!bn_mod_inverse_consttime(out, &no_inverse, a, n, ctx)) { + goto err; + } + } else if (!BN_mod_inverse_odd(out, &no_inverse, a, n, ctx)) { + goto err; + } + + ok = 1; + +err: + if (!ok) { + BN_free(new_out); + out = NULL; + } + BN_free(a_reduced); + return out; +} + +int BN_mod_inverse_blinded(BIGNUM *out, int *out_no_inverse, const BIGNUM *a, + const BN_MONT_CTX *mont, BN_CTX *ctx) { + *out_no_inverse = 0; + + if (BN_is_negative(a) || BN_cmp(a, &mont->N) >= 0) { + OPENSSL_PUT_ERROR(BN, BN_R_INPUT_NOT_REDUCED); + return 0; + } + + int ret = 0; + BIGNUM blinding_factor; + BN_init(&blinding_factor); + + if (!BN_rand_range_ex(&blinding_factor, 1, &mont->N) || + !BN_mod_mul_montgomery(out, &blinding_factor, a, mont, ctx) || + !BN_mod_inverse_odd(out, out_no_inverse, out, &mont->N, ctx) || + !BN_mod_mul_montgomery(out, &blinding_factor, out, mont, ctx)) { + OPENSSL_PUT_ERROR(BN, ERR_R_BN_LIB); + goto err; + } + + ret = 1; + +err: + BN_free(&blinding_factor); + return ret; +} + +int bn_mod_inverse_prime(BIGNUM *out, const BIGNUM *a, const BIGNUM *p, + BN_CTX *ctx, const BN_MONT_CTX *mont_p) { + BN_CTX_start(ctx); + BIGNUM *p_minus_2 = BN_CTX_get(ctx); + int ok = p_minus_2 != NULL && + BN_copy(p_minus_2, p) && + BN_sub_word(p_minus_2, 2) && + BN_mod_exp_mont(out, a, p_minus_2, p, ctx, mont_p); + BN_CTX_end(ctx); + return ok; +} + +int bn_mod_inverse_secret_prime(BIGNUM *out, const BIGNUM *a, const BIGNUM *p, + BN_CTX *ctx, const BN_MONT_CTX *mont_p) { + BN_CTX_start(ctx); + BIGNUM *p_minus_2 = BN_CTX_get(ctx); + int ok = p_minus_2 != NULL && + BN_copy(p_minus_2, p) && + BN_sub_word(p_minus_2, 2) && + BN_mod_exp_mont_consttime(out, a, p_minus_2, p, ctx, mont_p); + BN_CTX_end(ctx); + return ok; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/gcd.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/gcd.c.grpc_back new file mode 100644 index 0000000..7868b40 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/gcd.c.grpc_back @@ -0,0 +1,683 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 + +#include "internal.h" + + +static BN_ULONG word_is_odd_mask(BN_ULONG a) { return (BN_ULONG)0 - (a & 1); } + +static void maybe_rshift1_words(BN_ULONG *a, BN_ULONG mask, BN_ULONG *tmp, + size_t num) { + bn_rshift1_words(tmp, a, num); + bn_select_words(a, mask, tmp, a, num); +} + +static void maybe_rshift1_words_carry(BN_ULONG *a, BN_ULONG carry, + BN_ULONG mask, BN_ULONG *tmp, + size_t num) { + maybe_rshift1_words(a, mask, tmp, num); + if (num != 0) { + carry &= mask; + a[num - 1] |= carry << (BN_BITS2-1); + } +} + +static BN_ULONG maybe_add_words(BN_ULONG *a, BN_ULONG mask, const BN_ULONG *b, + BN_ULONG *tmp, size_t num) { + BN_ULONG carry = bn_add_words(tmp, a, b, num); + bn_select_words(a, mask, tmp, a, num); + return carry & mask; +} + +static int bn_gcd_consttime(BIGNUM *r, unsigned *out_shift, const BIGNUM *x, + const BIGNUM *y, BN_CTX *ctx) { + size_t width = x->width > y->width ? x->width : y->width; + if (width == 0) { + *out_shift = 0; + BN_zero(r); + return 1; + } + + // This is a constant-time implementation of Stein's algorithm (binary GCD). + int ret = 0; + BN_CTX_start(ctx); + BIGNUM *u = BN_CTX_get(ctx); + BIGNUM *v = BN_CTX_get(ctx); + BIGNUM *tmp = BN_CTX_get(ctx); + if (u == NULL || v == NULL || tmp == NULL || + !BN_copy(u, x) || + !BN_copy(v, y) || + !bn_resize_words(u, width) || + !bn_resize_words(v, width) || + !bn_resize_words(tmp, width)) { + goto err; + } + + // Each loop iteration halves at least one of |u| and |v|. Thus we need at + // most the combined bit width of inputs for at least one value to be zero. + unsigned x_bits = x->width * BN_BITS2, y_bits = y->width * BN_BITS2; + unsigned num_iters = x_bits + y_bits; + if (num_iters < x_bits) { + OPENSSL_PUT_ERROR(BN, BN_R_BIGNUM_TOO_LONG); + goto err; + } + + unsigned shift = 0; + for (unsigned i = 0; i < num_iters; i++) { + BN_ULONG both_odd = word_is_odd_mask(u->d[0]) & word_is_odd_mask(v->d[0]); + + // If both |u| and |v| are odd, subtract the smaller from the larger. + BN_ULONG u_less_than_v = + (BN_ULONG)0 - bn_sub_words(tmp->d, u->d, v->d, width); + bn_select_words(u->d, both_odd & ~u_less_than_v, tmp->d, u->d, width); + bn_sub_words(tmp->d, v->d, u->d, width); + bn_select_words(v->d, both_odd & u_less_than_v, tmp->d, v->d, width); + + // At least one of |u| and |v| is now even. + BN_ULONG u_is_odd = word_is_odd_mask(u->d[0]); + BN_ULONG v_is_odd = word_is_odd_mask(v->d[0]); + assert(!(u_is_odd & v_is_odd)); + + // If both are even, the final GCD gains a factor of two. + shift += 1 & (~u_is_odd & ~v_is_odd); + + // Halve any which are even. + maybe_rshift1_words(u->d, ~u_is_odd, tmp->d, width); + maybe_rshift1_words(v->d, ~v_is_odd, tmp->d, width); + } + + // One of |u| or |v| is zero at this point. The algorithm usually makes |u| + // zero, unless |y| was already zero on input. Fix this by combining the + // values. + assert(BN_is_zero(u) || BN_is_zero(v)); + for (size_t i = 0; i < width; i++) { + v->d[i] |= u->d[i]; + } + + *out_shift = shift; + ret = bn_set_words(r, v->d, width); + +err: + BN_CTX_end(ctx); + return ret; +} + +int BN_gcd(BIGNUM *r, const BIGNUM *x, const BIGNUM *y, BN_CTX *ctx) { + unsigned shift; + return bn_gcd_consttime(r, &shift, x, y, ctx) && + BN_lshift(r, r, shift); +} + +int bn_is_relatively_prime(int *out_relatively_prime, const BIGNUM *x, + const BIGNUM *y, BN_CTX *ctx) { + int ret = 0; + BN_CTX_start(ctx); + unsigned shift; + BIGNUM *gcd = BN_CTX_get(ctx); + if (gcd == NULL || + !bn_gcd_consttime(gcd, &shift, x, y, ctx)) { + goto err; + } + + // Check that 2^|shift| * |gcd| is one. + if (gcd->width == 0) { + *out_relatively_prime = 0; + } else { + BN_ULONG mask = shift | (gcd->d[0] ^ 1); + for (int i = 1; i < gcd->width; i++) { + mask |= gcd->d[i]; + } + *out_relatively_prime = mask == 0; + } + ret = 1; + +err: + BN_CTX_end(ctx); + return ret; +} + +int bn_lcm_consttime(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) { + BN_CTX_start(ctx); + unsigned shift; + BIGNUM *gcd = BN_CTX_get(ctx); + int ret = gcd != NULL && + bn_mul_consttime(r, a, b, ctx) && + bn_gcd_consttime(gcd, &shift, a, b, ctx) && + bn_div_consttime(r, NULL, r, gcd, ctx) && + bn_rshift_secret_shift(r, r, shift, ctx); + BN_CTX_end(ctx); + return ret; +} + +int bn_mod_inverse_consttime(BIGNUM *r, int *out_no_inverse, const BIGNUM *a, + const BIGNUM *n, BN_CTX *ctx) { + *out_no_inverse = 0; + if (BN_is_negative(a) || BN_ucmp(a, n) >= 0) { + OPENSSL_PUT_ERROR(BN, BN_R_INPUT_NOT_REDUCED); + return 0; + } + if (BN_is_zero(a)) { + if (BN_is_one(n)) { + BN_zero(r); + return 1; + } + *out_no_inverse = 1; + OPENSSL_PUT_ERROR(BN, BN_R_NO_INVERSE); + return 0; + } + + // This is a constant-time implementation of the extended binary GCD + // algorithm. It is adapted from the Handbook of Applied Cryptography, section + // 14.4.3, algorithm 14.51, and modified to bound coefficients and avoid + // negative numbers. + // + // For more details and proof of correctness, see + // https://github.com/mit-plv/fiat-crypto/pull/333. In particular, see |step| + // and |mod_inverse_consttime| for the algorithm in Gallina and see + // |mod_inverse_consttime_spec| for the correctness result. + + if (!BN_is_odd(a) && !BN_is_odd(n)) { + *out_no_inverse = 1; + OPENSSL_PUT_ERROR(BN, BN_R_NO_INVERSE); + return 0; + } + + // This function exists to compute the RSA private exponent, where |a| is one + // word. We'll thus use |a_width| when available. + size_t n_width = n->width, a_width = a->width; + if (a_width > n_width) { + a_width = n_width; + } + + int ret = 0; + BN_CTX_start(ctx); + BIGNUM *u = BN_CTX_get(ctx); + BIGNUM *v = BN_CTX_get(ctx); + BIGNUM *A = BN_CTX_get(ctx); + BIGNUM *B = BN_CTX_get(ctx); + BIGNUM *C = BN_CTX_get(ctx); + BIGNUM *D = BN_CTX_get(ctx); + BIGNUM *tmp = BN_CTX_get(ctx); + BIGNUM *tmp2 = BN_CTX_get(ctx); + if (u == NULL || v == NULL || A == NULL || B == NULL || C == NULL || + D == NULL || tmp == NULL || tmp2 == NULL || + !BN_copy(u, a) || + !BN_copy(v, n) || + !BN_one(A) || + !BN_one(D) || + // For convenience, size |u| and |v| equivalently. + !bn_resize_words(u, n_width) || + !bn_resize_words(v, n_width) || + // |A| and |C| are bounded by |m|. + !bn_resize_words(A, n_width) || + !bn_resize_words(C, n_width) || + // |B| and |D| are bounded by |a|. + !bn_resize_words(B, a_width) || + !bn_resize_words(D, a_width) || + // |tmp| and |tmp2| may be used at either size. + !bn_resize_words(tmp, n_width) || + !bn_resize_words(tmp2, n_width)) { + goto err; + } + + // Each loop iteration halves at least one of |u| and |v|. Thus we need at + // most the combined bit width of inputs for at least one value to be zero. + unsigned a_bits = a_width * BN_BITS2, n_bits = n_width * BN_BITS2; + unsigned num_iters = a_bits + n_bits; + if (num_iters < a_bits) { + OPENSSL_PUT_ERROR(BN, BN_R_BIGNUM_TOO_LONG); + goto err; + } + + // Before and after each loop iteration, the following hold: + // + // u = A*a - B*n + // v = D*n - C*a + // 0 < u <= a + // 0 <= v <= n + // 0 <= A < n + // 0 <= B <= a + // 0 <= C < n + // 0 <= D <= a + // + // After each loop iteration, u and v only get smaller, and at least one of + // them shrinks by at least a factor of two. + for (unsigned i = 0; i < num_iters; i++) { + BN_ULONG both_odd = word_is_odd_mask(u->d[0]) & word_is_odd_mask(v->d[0]); + + // If both |u| and |v| are odd, subtract the smaller from the larger. + BN_ULONG v_less_than_u = + (BN_ULONG)0 - bn_sub_words(tmp->d, v->d, u->d, n_width); + bn_select_words(v->d, both_odd & ~v_less_than_u, tmp->d, v->d, n_width); + bn_sub_words(tmp->d, u->d, v->d, n_width); + bn_select_words(u->d, both_odd & v_less_than_u, tmp->d, u->d, n_width); + + // If we updated one of the values, update the corresponding coefficient. + BN_ULONG carry = bn_add_words(tmp->d, A->d, C->d, n_width); + carry -= bn_sub_words(tmp2->d, tmp->d, n->d, n_width); + bn_select_words(tmp->d, carry, tmp->d, tmp2->d, n_width); + bn_select_words(A->d, both_odd & v_less_than_u, tmp->d, A->d, n_width); + bn_select_words(C->d, both_odd & ~v_less_than_u, tmp->d, C->d, n_width); + + bn_add_words(tmp->d, B->d, D->d, a_width); + bn_sub_words(tmp2->d, tmp->d, a->d, a_width); + bn_select_words(tmp->d, carry, tmp->d, tmp2->d, a_width); + bn_select_words(B->d, both_odd & v_less_than_u, tmp->d, B->d, a_width); + bn_select_words(D->d, both_odd & ~v_less_than_u, tmp->d, D->d, a_width); + + // Our loop invariants hold at this point. Additionally, exactly one of |u| + // and |v| is now even. + BN_ULONG u_is_even = ~word_is_odd_mask(u->d[0]); + BN_ULONG v_is_even = ~word_is_odd_mask(v->d[0]); + assert(u_is_even != v_is_even); + + // Halve the even one and adjust the corresponding coefficient. + maybe_rshift1_words(u->d, u_is_even, tmp->d, n_width); + BN_ULONG A_or_B_is_odd = + word_is_odd_mask(A->d[0]) | word_is_odd_mask(B->d[0]); + BN_ULONG A_carry = + maybe_add_words(A->d, A_or_B_is_odd & u_is_even, n->d, tmp->d, n_width); + BN_ULONG B_carry = + maybe_add_words(B->d, A_or_B_is_odd & u_is_even, a->d, tmp->d, a_width); + maybe_rshift1_words_carry(A->d, A_carry, u_is_even, tmp->d, n_width); + maybe_rshift1_words_carry(B->d, B_carry, u_is_even, tmp->d, a_width); + + maybe_rshift1_words(v->d, v_is_even, tmp->d, n_width); + BN_ULONG C_or_D_is_odd = + word_is_odd_mask(C->d[0]) | word_is_odd_mask(D->d[0]); + BN_ULONG C_carry = + maybe_add_words(C->d, C_or_D_is_odd & v_is_even, n->d, tmp->d, n_width); + BN_ULONG D_carry = + maybe_add_words(D->d, C_or_D_is_odd & v_is_even, a->d, tmp->d, a_width); + maybe_rshift1_words_carry(C->d, C_carry, v_is_even, tmp->d, n_width); + maybe_rshift1_words_carry(D->d, D_carry, v_is_even, tmp->d, a_width); + } + + assert(BN_is_zero(v)); + if (!BN_is_one(u)) { + *out_no_inverse = 1; + OPENSSL_PUT_ERROR(BN, BN_R_NO_INVERSE); + goto err; + } + + ret = BN_copy(r, A) != NULL; + +err: + BN_CTX_end(ctx); + return ret; +} + +int BN_mod_inverse_odd(BIGNUM *out, int *out_no_inverse, const BIGNUM *a, + const BIGNUM *n, BN_CTX *ctx) { + *out_no_inverse = 0; + + if (!BN_is_odd(n)) { + OPENSSL_PUT_ERROR(BN, BN_R_CALLED_WITH_EVEN_MODULUS); + return 0; + } + + if (BN_is_negative(a) || BN_cmp(a, n) >= 0) { + OPENSSL_PUT_ERROR(BN, BN_R_INPUT_NOT_REDUCED); + return 0; + } + + BIGNUM *A, *B, *X, *Y; + int ret = 0; + int sign; + + BN_CTX_start(ctx); + A = BN_CTX_get(ctx); + B = BN_CTX_get(ctx); + X = BN_CTX_get(ctx); + Y = BN_CTX_get(ctx); + if (Y == NULL) { + goto err; + } + + BIGNUM *R = out; + + BN_zero(Y); + if (!BN_one(X) || BN_copy(B, a) == NULL || BN_copy(A, n) == NULL) { + goto err; + } + A->neg = 0; + 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|). + + // 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 systems, 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; + } + } + } + + if (!BN_is_one(A)) { + *out_no_inverse = 1; + OPENSSL_PUT_ERROR(BN, BN_R_NO_INVERSE); + goto err; + } + + // 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|). + + // 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; + } + } + + ret = 1; + +err: + BN_CTX_end(ctx); + return ret; +} + +BIGNUM *BN_mod_inverse(BIGNUM *out, const BIGNUM *a, const BIGNUM *n, + BN_CTX *ctx) { + BIGNUM *new_out = NULL; + if (out == NULL) { + new_out = BN_new(); + if (new_out == NULL) { + OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE); + return NULL; + } + out = new_out; + } + + int ok = 0; + BIGNUM *a_reduced = NULL; + if (a->neg || BN_ucmp(a, n) >= 0) { + a_reduced = BN_dup(a); + if (a_reduced == NULL) { + goto err; + } + if (!BN_nnmod(a_reduced, a_reduced, n, ctx)) { + goto err; + } + a = a_reduced; + } + + int no_inverse; + if (!BN_is_odd(n)) { + if (!bn_mod_inverse_consttime(out, &no_inverse, a, n, ctx)) { + goto err; + } + } else if (!BN_mod_inverse_odd(out, &no_inverse, a, n, ctx)) { + goto err; + } + + ok = 1; + +err: + if (!ok) { + BN_free(new_out); + out = NULL; + } + BN_free(a_reduced); + return out; +} + +int BN_mod_inverse_blinded(BIGNUM *out, int *out_no_inverse, const BIGNUM *a, + const BN_MONT_CTX *mont, BN_CTX *ctx) { + *out_no_inverse = 0; + + if (BN_is_negative(a) || BN_cmp(a, &mont->N) >= 0) { + OPENSSL_PUT_ERROR(BN, BN_R_INPUT_NOT_REDUCED); + return 0; + } + + int ret = 0; + BIGNUM blinding_factor; + BN_init(&blinding_factor); + + if (!BN_rand_range_ex(&blinding_factor, 1, &mont->N) || + !BN_mod_mul_montgomery(out, &blinding_factor, a, mont, ctx) || + !BN_mod_inverse_odd(out, out_no_inverse, out, &mont->N, ctx) || + !BN_mod_mul_montgomery(out, &blinding_factor, out, mont, ctx)) { + OPENSSL_PUT_ERROR(BN, ERR_R_BN_LIB); + goto err; + } + + ret = 1; + +err: + BN_free(&blinding_factor); + return ret; +} + +int bn_mod_inverse_prime(BIGNUM *out, const BIGNUM *a, const BIGNUM *p, + BN_CTX *ctx, const BN_MONT_CTX *mont_p) { + BN_CTX_start(ctx); + BIGNUM *p_minus_2 = BN_CTX_get(ctx); + int ok = p_minus_2 != NULL && + BN_copy(p_minus_2, p) && + BN_sub_word(p_minus_2, 2) && + BN_mod_exp_mont(out, a, p_minus_2, p, ctx, mont_p); + BN_CTX_end(ctx); + return ok; +} + +int bn_mod_inverse_secret_prime(BIGNUM *out, const BIGNUM *a, const BIGNUM *p, + BN_CTX *ctx, const BN_MONT_CTX *mont_p) { + BN_CTX_start(ctx); + BIGNUM *p_minus_2 = BN_CTX_get(ctx); + int ok = p_minus_2 != NULL && + BN_copy(p_minus_2, p) && + BN_sub_word(p_minus_2, 2) && + BN_mod_exp_mont_consttime(out, a, p_minus_2, p, ctx, mont_p); + BN_CTX_end(ctx); + return ok; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/generic.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/generic.c new file mode 100644 index 0000000..7d0d0ef --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/generic.c @@ -0,0 +1,711 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 "internal.h" + + +// This file has two other implementations: x86 assembly language in +// asm/bn-586.pl and x86_64 inline assembly in asm/x86_64-gcc.c. +#if defined(OPENSSL_NO_ASM) || \ + !(defined(OPENSSL_X86) || \ + (defined(OPENSSL_X86_64) && (defined(__GNUC__) || defined(__clang__)))) + +#ifdef BN_ULLONG +#define mul_add(r, a, w, c) \ + do { \ + BN_ULLONG t; \ + t = (BN_ULLONG)(w) * (a) + (r) + (c); \ + (r) = Lw(t); \ + (c) = Hw(t); \ + } while (0) + +#define mul(r, a, w, c) \ + do { \ + BN_ULLONG t; \ + t = (BN_ULLONG)(w) * (a) + (c); \ + (r) = Lw(t); \ + (c) = Hw(t); \ + } while (0) + +#define sqr(r0, r1, a) \ + do { \ + BN_ULLONG t; \ + t = (BN_ULLONG)(a) * (a); \ + (r0) = Lw(t); \ + (r1) = Hw(t); \ + } while (0) + +#else + +#define mul_add(r, a, w, c) \ + do { \ + 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 < low) ? 1 : 0; \ + (r) = ret; \ + } while (0) + +#define mul(r, a, w, c) \ + do { \ + BN_ULONG high, low, ret, ta = (a); \ + BN_UMULT_LOHI(low, high, w, ta); \ + ret = low + (c); \ + (c) = high; \ + (c) += (ret < low) ? 1 : 0; \ + (r) = ret; \ + } while (0) + +#define sqr(r0, r1, a) \ + do { \ + BN_ULONG tmp = (a); \ + BN_UMULT_LOHI(r0, r1, tmp, tmp); \ + } while (0) + +#endif // !BN_ULLONG + +BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, size_t num, + BN_ULONG w) { + BN_ULONG c1 = 0; + + if (num == 0) { + return c1; + } + + 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; + } + + 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, size_t num, + BN_ULONG w) { + BN_ULONG c1 = 0; + + if (num == 0) { + return c1; + } + + 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; + } + 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, size_t n) { + if (n == 0) { + return; + } + + 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; + } + while (n) { + sqr(r[0], r[1], a[0]); + a++; + r += 2; + n--; + } +} + +#ifdef BN_ULLONG +BN_ULONG bn_add_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, + size_t n) { + BN_ULLONG ll = 0; + + if (n == 0) { + return 0; + } + + while (n & ~3) { + ll += (BN_ULLONG)a[0] + b[0]; + r[0] = (BN_ULONG)ll; + ll >>= BN_BITS2; + ll += (BN_ULLONG)a[1] + b[1]; + r[1] = (BN_ULONG)ll; + ll >>= BN_BITS2; + ll += (BN_ULLONG)a[2] + b[2]; + r[2] = (BN_ULONG)ll; + ll >>= BN_BITS2; + ll += (BN_ULLONG)a[3] + b[3]; + r[3] = (BN_ULONG)ll; + ll >>= BN_BITS2; + a += 4; + b += 4; + r += 4; + n -= 4; + } + while (n) { + ll += (BN_ULLONG)a[0] + b[0]; + r[0] = (BN_ULONG)ll; + ll >>= BN_BITS2; + a++; + b++; + r++; + n--; + } + return (BN_ULONG)ll; +} + +#else // !BN_ULLONG + +BN_ULONG bn_add_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, + size_t n) { + BN_ULONG c, l, t; + + if (n == 0) { + return (BN_ULONG)0; + } + + c = 0; + while (n & ~3) { + t = a[0]; + t += c; + c = (t < c); + l = t + b[0]; + c += (l < t); + r[0] = l; + t = a[1]; + t += c; + c = (t < c); + l = t + b[1]; + c += (l < t); + r[1] = l; + t = a[2]; + t += c; + c = (t < c); + l = t + b[2]; + c += (l < t); + r[2] = l; + t = a[3]; + t += c; + c = (t < c); + l = t + b[3]; + c += (l < t); + r[3] = l; + a += 4; + b += 4; + r += 4; + n -= 4; + } + while (n) { + t = a[0]; + t += c; + c = (t < c); + l = t + b[0]; + c += (l < t); + r[0] = l; + a++; + b++; + r++; + n--; + } + return (BN_ULONG)c; +} + +#endif // !BN_ULLONG + +BN_ULONG bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, + size_t n) { + BN_ULONG t1, t2; + int c = 0; + + if (n == 0) { + return (BN_ULONG)0; + } + + while (n & ~3) { + t1 = a[0]; + t2 = b[0]; + r[0] = t1 - t2 - c; + if (t1 != t2) { + c = (t1 < t2); + } + t1 = a[1]; + t2 = b[1]; + r[1] = t1 - t2 - c; + if (t1 != t2) { + c = (t1 < t2); + } + t1 = a[2]; + t2 = b[2]; + r[2] = t1 - t2 - c; + if (t1 != t2) { + c = (t1 < t2); + } + t1 = a[3]; + t2 = b[3]; + r[3] = t1 - t2 - c; + if (t1 != t2) { + c = (t1 < t2); + } + a += 4; + b += 4; + r += 4; + n -= 4; + } + while (n) { + t1 = a[0]; + t2 = b[0]; + r[0] = t1 - t2 - c; + if (t1 != t2) { + c = (t1 < t2); + } + a++; + b++; + r++; + n--; + } + return c; +} + +// 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_ULLONG + +// 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) += (hi); \ + if ((c1) < hi) { \ + (c2)++; \ + } \ + } while (0) + +#define mul_add_c2(a, b, c0, c1, c2) \ + do { \ + BN_ULONG hi; \ + BN_ULLONG t = (BN_ULLONG)(a) * (b); \ + BN_ULLONG tt = t + (c0); /* no carry */ \ + (c0) = (BN_ULONG)Lw(tt); \ + hi = (BN_ULONG)Hw(tt); \ + (c1) += hi; \ + if ((c1) < hi) { \ + (c2)++; \ + } \ + t += (c0); /* no carry */ \ + (c0) = (BN_ULONG)Lw(t); \ + hi = (BN_ULONG)Hw(t); \ + (c1) += hi; \ + if ((c1) < hi) { \ + (c2)++; \ + } \ + } while (0) + +#define sqr_add_c(a, i, c0, c1, c2) \ + do { \ + BN_ULONG hi; \ + BN_ULLONG t = (BN_ULLONG)(a)[i] * (a)[i]; \ + t += (c0); /* no carry */ \ + (c0) = (BN_ULONG)Lw(t); \ + hi = (BN_ULONG)Hw(t); \ + (c1) += hi; \ + if ((c1) < hi) { \ + (c2)++; \ + } \ + } while (0) + +#define sqr_add_c2(a, i, j, c0, c1, c2) mul_add_c2((a)[i], (a)[j], c0, c1, c2) + +#else + +// Keep in mind that additions to hi can not overflow, because the high word of +// a multiplication result cannot be all-ones. +#define mul_add_c(a, b, c0, c1, c2) \ + do { \ + BN_ULONG ta = (a), tb = (b); \ + BN_ULONG lo, hi; \ + BN_UMULT_LOHI(lo, hi, ta, tb); \ + (c0) += lo; \ + hi += ((c0) < lo) ? 1 : 0; \ + (c1) += hi; \ + (c2) += ((c1) < hi) ? 1 : 0; \ + } while (0) + +#define mul_add_c2(a, b, c0, c1, c2) \ + do { \ + BN_ULONG ta = (a), tb = (b); \ + BN_ULONG lo, hi, tt; \ + BN_UMULT_LOHI(lo, hi, ta, tb); \ + (c0) += lo; \ + tt = hi + (((c0) < lo) ? 1 : 0); \ + (c1) += tt; \ + (c2) += ((c1) < tt) ? 1 : 0; \ + (c0) += lo; \ + hi += (c0 < lo) ? 1 : 0; \ + (c1) += hi; \ + (c2) += ((c1) < hi) ? 1 : 0; \ + } while (0) + +#define sqr_add_c(a, i, c0, c1, c2) \ + do { \ + BN_ULONG ta = (a)[i]; \ + BN_ULONG lo, hi; \ + BN_UMULT_LOHI(lo, hi, ta, ta); \ + (c0) += lo; \ + hi += (c0 < lo) ? 1 : 0; \ + (c1) += hi; \ + (c2) += ((c1) < hi) ? 1 : 0; \ + } while (0) + +#define sqr_add_c2(a, i, j, c0, c1, c2) mul_add_c2((a)[i], (a)[j], c0, c1, c2) + +#endif // !BN_ULLONG + +void bn_mul_comba8(BN_ULONG r[16], const BN_ULONG a[8], const BN_ULONG b[8]) { + BN_ULONG c1, c2, c3; + + c1 = 0; + c2 = 0; + c3 = 0; + mul_add_c(a[0], b[0], c1, c2, c3); + r[0] = c1; + c1 = 0; + mul_add_c(a[0], b[1], c2, c3, c1); + mul_add_c(a[1], b[0], c2, c3, c1); + r[1] = c2; + c2 = 0; + mul_add_c(a[2], b[0], c3, c1, c2); + mul_add_c(a[1], b[1], c3, c1, c2); + mul_add_c(a[0], b[2], c3, c1, c2); + r[2] = c3; + c3 = 0; + mul_add_c(a[0], b[3], c1, c2, c3); + mul_add_c(a[1], b[2], c1, c2, c3); + mul_add_c(a[2], b[1], c1, c2, c3); + mul_add_c(a[3], b[0], c1, c2, c3); + r[3] = c1; + c1 = 0; + mul_add_c(a[4], b[0], c2, c3, c1); + mul_add_c(a[3], b[1], c2, c3, c1); + mul_add_c(a[2], b[2], c2, c3, c1); + mul_add_c(a[1], b[3], c2, c3, c1); + mul_add_c(a[0], b[4], c2, c3, c1); + r[4] = c2; + c2 = 0; + mul_add_c(a[0], b[5], c3, c1, c2); + mul_add_c(a[1], b[4], c3, c1, c2); + mul_add_c(a[2], b[3], c3, c1, c2); + mul_add_c(a[3], b[2], c3, c1, c2); + mul_add_c(a[4], b[1], c3, c1, c2); + mul_add_c(a[5], b[0], c3, c1, c2); + r[5] = c3; + c3 = 0; + mul_add_c(a[6], b[0], c1, c2, c3); + mul_add_c(a[5], b[1], c1, c2, c3); + mul_add_c(a[4], b[2], c1, c2, c3); + mul_add_c(a[3], b[3], c1, c2, c3); + mul_add_c(a[2], b[4], c1, c2, c3); + mul_add_c(a[1], b[5], c1, c2, c3); + mul_add_c(a[0], b[6], c1, c2, c3); + r[6] = c1; + c1 = 0; + mul_add_c(a[0], b[7], c2, c3, c1); + mul_add_c(a[1], b[6], c2, c3, c1); + mul_add_c(a[2], b[5], c2, c3, c1); + mul_add_c(a[3], b[4], c2, c3, c1); + mul_add_c(a[4], b[3], c2, c3, c1); + mul_add_c(a[5], b[2], c2, c3, c1); + mul_add_c(a[6], b[1], c2, c3, c1); + mul_add_c(a[7], b[0], c2, c3, c1); + r[7] = c2; + c2 = 0; + mul_add_c(a[7], b[1], c3, c1, c2); + mul_add_c(a[6], b[2], c3, c1, c2); + mul_add_c(a[5], b[3], c3, c1, c2); + mul_add_c(a[4], b[4], c3, c1, c2); + mul_add_c(a[3], b[5], c3, c1, c2); + mul_add_c(a[2], b[6], c3, c1, c2); + mul_add_c(a[1], b[7], c3, c1, c2); + r[8] = c3; + c3 = 0; + mul_add_c(a[2], b[7], c1, c2, c3); + mul_add_c(a[3], b[6], c1, c2, c3); + mul_add_c(a[4], b[5], c1, c2, c3); + mul_add_c(a[5], b[4], c1, c2, c3); + mul_add_c(a[6], b[3], c1, c2, c3); + mul_add_c(a[7], b[2], c1, c2, c3); + r[9] = c1; + c1 = 0; + mul_add_c(a[7], b[3], c2, c3, c1); + mul_add_c(a[6], b[4], c2, c3, c1); + mul_add_c(a[5], b[5], c2, c3, c1); + mul_add_c(a[4], b[6], c2, c3, c1); + mul_add_c(a[3], b[7], c2, c3, c1); + r[10] = c2; + c2 = 0; + mul_add_c(a[4], b[7], c3, c1, c2); + mul_add_c(a[5], b[6], c3, c1, c2); + mul_add_c(a[6], b[5], c3, c1, c2); + mul_add_c(a[7], b[4], c3, c1, c2); + r[11] = c3; + c3 = 0; + mul_add_c(a[7], b[5], c1, c2, c3); + mul_add_c(a[6], b[6], c1, c2, c3); + mul_add_c(a[5], b[7], c1, c2, c3); + r[12] = c1; + c1 = 0; + mul_add_c(a[6], b[7], c2, c3, c1); + mul_add_c(a[7], b[6], c2, c3, c1); + r[13] = c2; + c2 = 0; + mul_add_c(a[7], b[7], c3, c1, c2); + r[14] = c3; + r[15] = c1; +} + +void bn_mul_comba4(BN_ULONG r[8], const BN_ULONG a[4], const BN_ULONG b[4]) { + BN_ULONG c1, c2, c3; + + c1 = 0; + c2 = 0; + c3 = 0; + mul_add_c(a[0], b[0], c1, c2, c3); + r[0] = c1; + c1 = 0; + mul_add_c(a[0], b[1], c2, c3, c1); + mul_add_c(a[1], b[0], c2, c3, c1); + r[1] = c2; + c2 = 0; + mul_add_c(a[2], b[0], c3, c1, c2); + mul_add_c(a[1], b[1], c3, c1, c2); + mul_add_c(a[0], b[2], c3, c1, c2); + r[2] = c3; + c3 = 0; + mul_add_c(a[0], b[3], c1, c2, c3); + mul_add_c(a[1], b[2], c1, c2, c3); + mul_add_c(a[2], b[1], c1, c2, c3); + mul_add_c(a[3], b[0], c1, c2, c3); + r[3] = c1; + c1 = 0; + mul_add_c(a[3], b[1], c2, c3, c1); + mul_add_c(a[2], b[2], c2, c3, c1); + mul_add_c(a[1], b[3], c2, c3, c1); + r[4] = c2; + c2 = 0; + mul_add_c(a[2], b[3], c3, c1, c2); + mul_add_c(a[3], b[2], c3, c1, c2); + r[5] = c3; + c3 = 0; + mul_add_c(a[3], b[3], c1, c2, c3); + r[6] = c1; + r[7] = c2; +} + +void bn_sqr_comba8(BN_ULONG r[16], const BN_ULONG a[8]) { + BN_ULONG c1, c2, c3; + + c1 = 0; + c2 = 0; + c3 = 0; + sqr_add_c(a, 0, c1, c2, c3); + r[0] = c1; + c1 = 0; + sqr_add_c2(a, 1, 0, c2, c3, c1); + r[1] = c2; + c2 = 0; + sqr_add_c(a, 1, c3, c1, c2); + sqr_add_c2(a, 2, 0, c3, c1, c2); + r[2] = c3; + c3 = 0; + sqr_add_c2(a, 3, 0, c1, c2, c3); + sqr_add_c2(a, 2, 1, c1, c2, c3); + r[3] = c1; + c1 = 0; + sqr_add_c(a, 2, c2, c3, c1); + sqr_add_c2(a, 3, 1, c2, c3, c1); + sqr_add_c2(a, 4, 0, c2, c3, c1); + r[4] = c2; + c2 = 0; + sqr_add_c2(a, 5, 0, c3, c1, c2); + sqr_add_c2(a, 4, 1, c3, c1, c2); + sqr_add_c2(a, 3, 2, c3, c1, c2); + r[5] = c3; + c3 = 0; + sqr_add_c(a, 3, c1, c2, c3); + sqr_add_c2(a, 4, 2, c1, c2, c3); + sqr_add_c2(a, 5, 1, c1, c2, c3); + sqr_add_c2(a, 6, 0, c1, c2, c3); + r[6] = c1; + c1 = 0; + sqr_add_c2(a, 7, 0, c2, c3, c1); + sqr_add_c2(a, 6, 1, c2, c3, c1); + sqr_add_c2(a, 5, 2, c2, c3, c1); + sqr_add_c2(a, 4, 3, c2, c3, c1); + r[7] = c2; + c2 = 0; + sqr_add_c(a, 4, c3, c1, c2); + sqr_add_c2(a, 5, 3, c3, c1, c2); + sqr_add_c2(a, 6, 2, c3, c1, c2); + sqr_add_c2(a, 7, 1, c3, c1, c2); + r[8] = c3; + c3 = 0; + sqr_add_c2(a, 7, 2, c1, c2, c3); + sqr_add_c2(a, 6, 3, c1, c2, c3); + sqr_add_c2(a, 5, 4, c1, c2, c3); + r[9] = c1; + c1 = 0; + sqr_add_c(a, 5, c2, c3, c1); + sqr_add_c2(a, 6, 4, c2, c3, c1); + sqr_add_c2(a, 7, 3, c2, c3, c1); + r[10] = c2; + c2 = 0; + sqr_add_c2(a, 7, 4, c3, c1, c2); + sqr_add_c2(a, 6, 5, c3, c1, c2); + r[11] = c3; + c3 = 0; + sqr_add_c(a, 6, c1, c2, c3); + sqr_add_c2(a, 7, 5, c1, c2, c3); + r[12] = c1; + c1 = 0; + sqr_add_c2(a, 7, 6, c2, c3, c1); + r[13] = c2; + c2 = 0; + sqr_add_c(a, 7, c3, c1, c2); + r[14] = c3; + r[15] = c1; +} + +void bn_sqr_comba4(BN_ULONG r[8], const BN_ULONG a[4]) { + BN_ULONG c1, c2, c3; + + c1 = 0; + c2 = 0; + c3 = 0; + sqr_add_c(a, 0, c1, c2, c3); + r[0] = c1; + c1 = 0; + sqr_add_c2(a, 1, 0, c2, c3, c1); + r[1] = c2; + c2 = 0; + sqr_add_c(a, 1, c3, c1, c2); + sqr_add_c2(a, 2, 0, c3, c1, c2); + r[2] = c3; + c3 = 0; + sqr_add_c2(a, 3, 0, c1, c2, c3); + sqr_add_c2(a, 2, 1, c1, c2, c3); + r[3] = c1; + c1 = 0; + sqr_add_c(a, 2, c2, c3, c1); + sqr_add_c2(a, 3, 1, c2, c3, c1); + r[4] = c2; + c2 = 0; + sqr_add_c2(a, 3, 2, c3, c1, c2); + r[5] = c3; + c3 = 0; + sqr_add_c(a, 3, c1, c2, c3); + r[6] = c1; + r[7] = c2; +} + +#undef mul_add +#undef mul +#undef sqr +#undef mul_add_c +#undef mul_add_c2 +#undef sqr_add_c +#undef sqr_add_c2 + +#endif diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/generic.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/generic.c.grpc_back new file mode 100644 index 0000000..ee80a3c --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/generic.c.grpc_back @@ -0,0 +1,711 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 "internal.h" + + +// This file has two other implementations: x86 assembly language in +// asm/bn-586.pl and x86_64 inline assembly in asm/x86_64-gcc.c. +#if defined(OPENSSL_NO_ASM) || \ + !(defined(OPENSSL_X86) || \ + (defined(OPENSSL_X86_64) && (defined(__GNUC__) || defined(__clang__)))) + +#ifdef BN_ULLONG +#define mul_add(r, a, w, c) \ + do { \ + BN_ULLONG t; \ + t = (BN_ULLONG)(w) * (a) + (r) + (c); \ + (r) = Lw(t); \ + (c) = Hw(t); \ + } while (0) + +#define mul(r, a, w, c) \ + do { \ + BN_ULLONG t; \ + t = (BN_ULLONG)(w) * (a) + (c); \ + (r) = Lw(t); \ + (c) = Hw(t); \ + } while (0) + +#define sqr(r0, r1, a) \ + do { \ + BN_ULLONG t; \ + t = (BN_ULLONG)(a) * (a); \ + (r0) = Lw(t); \ + (r1) = Hw(t); \ + } while (0) + +#else + +#define mul_add(r, a, w, c) \ + do { \ + 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 < low) ? 1 : 0; \ + (r) = ret; \ + } while (0) + +#define mul(r, a, w, c) \ + do { \ + BN_ULONG high, low, ret, ta = (a); \ + BN_UMULT_LOHI(low, high, w, ta); \ + ret = low + (c); \ + (c) = high; \ + (c) += (ret < low) ? 1 : 0; \ + (r) = ret; \ + } while (0) + +#define sqr(r0, r1, a) \ + do { \ + BN_ULONG tmp = (a); \ + BN_UMULT_LOHI(r0, r1, tmp, tmp); \ + } while (0) + +#endif // !BN_ULLONG + +BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, size_t num, + BN_ULONG w) { + BN_ULONG c1 = 0; + + if (num == 0) { + return c1; + } + + 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; + } + + 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, size_t num, + BN_ULONG w) { + BN_ULONG c1 = 0; + + if (num == 0) { + return c1; + } + + 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; + } + 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, size_t n) { + if (n == 0) { + return; + } + + 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; + } + while (n) { + sqr(r[0], r[1], a[0]); + a++; + r += 2; + n--; + } +} + +#ifdef BN_ULLONG +BN_ULONG bn_add_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, + size_t n) { + BN_ULLONG ll = 0; + + if (n == 0) { + return 0; + } + + while (n & ~3) { + ll += (BN_ULLONG)a[0] + b[0]; + r[0] = (BN_ULONG)ll; + ll >>= BN_BITS2; + ll += (BN_ULLONG)a[1] + b[1]; + r[1] = (BN_ULONG)ll; + ll >>= BN_BITS2; + ll += (BN_ULLONG)a[2] + b[2]; + r[2] = (BN_ULONG)ll; + ll >>= BN_BITS2; + ll += (BN_ULLONG)a[3] + b[3]; + r[3] = (BN_ULONG)ll; + ll >>= BN_BITS2; + a += 4; + b += 4; + r += 4; + n -= 4; + } + while (n) { + ll += (BN_ULLONG)a[0] + b[0]; + r[0] = (BN_ULONG)ll; + ll >>= BN_BITS2; + a++; + b++; + r++; + n--; + } + return (BN_ULONG)ll; +} + +#else // !BN_ULLONG + +BN_ULONG bn_add_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, + size_t n) { + BN_ULONG c, l, t; + + if (n == 0) { + return (BN_ULONG)0; + } + + c = 0; + while (n & ~3) { + t = a[0]; + t += c; + c = (t < c); + l = t + b[0]; + c += (l < t); + r[0] = l; + t = a[1]; + t += c; + c = (t < c); + l = t + b[1]; + c += (l < t); + r[1] = l; + t = a[2]; + t += c; + c = (t < c); + l = t + b[2]; + c += (l < t); + r[2] = l; + t = a[3]; + t += c; + c = (t < c); + l = t + b[3]; + c += (l < t); + r[3] = l; + a += 4; + b += 4; + r += 4; + n -= 4; + } + while (n) { + t = a[0]; + t += c; + c = (t < c); + l = t + b[0]; + c += (l < t); + r[0] = l; + a++; + b++; + r++; + n--; + } + return (BN_ULONG)c; +} + +#endif // !BN_ULLONG + +BN_ULONG bn_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, + size_t n) { + BN_ULONG t1, t2; + int c = 0; + + if (n == 0) { + return (BN_ULONG)0; + } + + while (n & ~3) { + t1 = a[0]; + t2 = b[0]; + r[0] = t1 - t2 - c; + if (t1 != t2) { + c = (t1 < t2); + } + t1 = a[1]; + t2 = b[1]; + r[1] = t1 - t2 - c; + if (t1 != t2) { + c = (t1 < t2); + } + t1 = a[2]; + t2 = b[2]; + r[2] = t1 - t2 - c; + if (t1 != t2) { + c = (t1 < t2); + } + t1 = a[3]; + t2 = b[3]; + r[3] = t1 - t2 - c; + if (t1 != t2) { + c = (t1 < t2); + } + a += 4; + b += 4; + r += 4; + n -= 4; + } + while (n) { + t1 = a[0]; + t2 = b[0]; + r[0] = t1 - t2 - c; + if (t1 != t2) { + c = (t1 < t2); + } + a++; + b++; + r++; + n--; + } + return c; +} + +// 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_ULLONG + +// 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) += (hi); \ + if ((c1) < hi) { \ + (c2)++; \ + } \ + } while (0) + +#define mul_add_c2(a, b, c0, c1, c2) \ + do { \ + BN_ULONG hi; \ + BN_ULLONG t = (BN_ULLONG)(a) * (b); \ + BN_ULLONG tt = t + (c0); /* no carry */ \ + (c0) = (BN_ULONG)Lw(tt); \ + hi = (BN_ULONG)Hw(tt); \ + (c1) += hi; \ + if ((c1) < hi) { \ + (c2)++; \ + } \ + t += (c0); /* no carry */ \ + (c0) = (BN_ULONG)Lw(t); \ + hi = (BN_ULONG)Hw(t); \ + (c1) += hi; \ + if ((c1) < hi) { \ + (c2)++; \ + } \ + } while (0) + +#define sqr_add_c(a, i, c0, c1, c2) \ + do { \ + BN_ULONG hi; \ + BN_ULLONG t = (BN_ULLONG)(a)[i] * (a)[i]; \ + t += (c0); /* no carry */ \ + (c0) = (BN_ULONG)Lw(t); \ + hi = (BN_ULONG)Hw(t); \ + (c1) += hi; \ + if ((c1) < hi) { \ + (c2)++; \ + } \ + } while (0) + +#define sqr_add_c2(a, i, j, c0, c1, c2) mul_add_c2((a)[i], (a)[j], c0, c1, c2) + +#else + +// Keep in mind that additions to hi can not overflow, because the high word of +// a multiplication result cannot be all-ones. +#define mul_add_c(a, b, c0, c1, c2) \ + do { \ + BN_ULONG ta = (a), tb = (b); \ + BN_ULONG lo, hi; \ + BN_UMULT_LOHI(lo, hi, ta, tb); \ + (c0) += lo; \ + hi += ((c0) < lo) ? 1 : 0; \ + (c1) += hi; \ + (c2) += ((c1) < hi) ? 1 : 0; \ + } while (0) + +#define mul_add_c2(a, b, c0, c1, c2) \ + do { \ + BN_ULONG ta = (a), tb = (b); \ + BN_ULONG lo, hi, tt; \ + BN_UMULT_LOHI(lo, hi, ta, tb); \ + (c0) += lo; \ + tt = hi + (((c0) < lo) ? 1 : 0); \ + (c1) += tt; \ + (c2) += ((c1) < tt) ? 1 : 0; \ + (c0) += lo; \ + hi += (c0 < lo) ? 1 : 0; \ + (c1) += hi; \ + (c2) += ((c1) < hi) ? 1 : 0; \ + } while (0) + +#define sqr_add_c(a, i, c0, c1, c2) \ + do { \ + BN_ULONG ta = (a)[i]; \ + BN_ULONG lo, hi; \ + BN_UMULT_LOHI(lo, hi, ta, ta); \ + (c0) += lo; \ + hi += (c0 < lo) ? 1 : 0; \ + (c1) += hi; \ + (c2) += ((c1) < hi) ? 1 : 0; \ + } while (0) + +#define sqr_add_c2(a, i, j, c0, c1, c2) mul_add_c2((a)[i], (a)[j], c0, c1, c2) + +#endif // !BN_ULLONG + +void bn_mul_comba8(BN_ULONG r[16], const BN_ULONG a[8], const BN_ULONG b[8]) { + BN_ULONG c1, c2, c3; + + c1 = 0; + c2 = 0; + c3 = 0; + mul_add_c(a[0], b[0], c1, c2, c3); + r[0] = c1; + c1 = 0; + mul_add_c(a[0], b[1], c2, c3, c1); + mul_add_c(a[1], b[0], c2, c3, c1); + r[1] = c2; + c2 = 0; + mul_add_c(a[2], b[0], c3, c1, c2); + mul_add_c(a[1], b[1], c3, c1, c2); + mul_add_c(a[0], b[2], c3, c1, c2); + r[2] = c3; + c3 = 0; + mul_add_c(a[0], b[3], c1, c2, c3); + mul_add_c(a[1], b[2], c1, c2, c3); + mul_add_c(a[2], b[1], c1, c2, c3); + mul_add_c(a[3], b[0], c1, c2, c3); + r[3] = c1; + c1 = 0; + mul_add_c(a[4], b[0], c2, c3, c1); + mul_add_c(a[3], b[1], c2, c3, c1); + mul_add_c(a[2], b[2], c2, c3, c1); + mul_add_c(a[1], b[3], c2, c3, c1); + mul_add_c(a[0], b[4], c2, c3, c1); + r[4] = c2; + c2 = 0; + mul_add_c(a[0], b[5], c3, c1, c2); + mul_add_c(a[1], b[4], c3, c1, c2); + mul_add_c(a[2], b[3], c3, c1, c2); + mul_add_c(a[3], b[2], c3, c1, c2); + mul_add_c(a[4], b[1], c3, c1, c2); + mul_add_c(a[5], b[0], c3, c1, c2); + r[5] = c3; + c3 = 0; + mul_add_c(a[6], b[0], c1, c2, c3); + mul_add_c(a[5], b[1], c1, c2, c3); + mul_add_c(a[4], b[2], c1, c2, c3); + mul_add_c(a[3], b[3], c1, c2, c3); + mul_add_c(a[2], b[4], c1, c2, c3); + mul_add_c(a[1], b[5], c1, c2, c3); + mul_add_c(a[0], b[6], c1, c2, c3); + r[6] = c1; + c1 = 0; + mul_add_c(a[0], b[7], c2, c3, c1); + mul_add_c(a[1], b[6], c2, c3, c1); + mul_add_c(a[2], b[5], c2, c3, c1); + mul_add_c(a[3], b[4], c2, c3, c1); + mul_add_c(a[4], b[3], c2, c3, c1); + mul_add_c(a[5], b[2], c2, c3, c1); + mul_add_c(a[6], b[1], c2, c3, c1); + mul_add_c(a[7], b[0], c2, c3, c1); + r[7] = c2; + c2 = 0; + mul_add_c(a[7], b[1], c3, c1, c2); + mul_add_c(a[6], b[2], c3, c1, c2); + mul_add_c(a[5], b[3], c3, c1, c2); + mul_add_c(a[4], b[4], c3, c1, c2); + mul_add_c(a[3], b[5], c3, c1, c2); + mul_add_c(a[2], b[6], c3, c1, c2); + mul_add_c(a[1], b[7], c3, c1, c2); + r[8] = c3; + c3 = 0; + mul_add_c(a[2], b[7], c1, c2, c3); + mul_add_c(a[3], b[6], c1, c2, c3); + mul_add_c(a[4], b[5], c1, c2, c3); + mul_add_c(a[5], b[4], c1, c2, c3); + mul_add_c(a[6], b[3], c1, c2, c3); + mul_add_c(a[7], b[2], c1, c2, c3); + r[9] = c1; + c1 = 0; + mul_add_c(a[7], b[3], c2, c3, c1); + mul_add_c(a[6], b[4], c2, c3, c1); + mul_add_c(a[5], b[5], c2, c3, c1); + mul_add_c(a[4], b[6], c2, c3, c1); + mul_add_c(a[3], b[7], c2, c3, c1); + r[10] = c2; + c2 = 0; + mul_add_c(a[4], b[7], c3, c1, c2); + mul_add_c(a[5], b[6], c3, c1, c2); + mul_add_c(a[6], b[5], c3, c1, c2); + mul_add_c(a[7], b[4], c3, c1, c2); + r[11] = c3; + c3 = 0; + mul_add_c(a[7], b[5], c1, c2, c3); + mul_add_c(a[6], b[6], c1, c2, c3); + mul_add_c(a[5], b[7], c1, c2, c3); + r[12] = c1; + c1 = 0; + mul_add_c(a[6], b[7], c2, c3, c1); + mul_add_c(a[7], b[6], c2, c3, c1); + r[13] = c2; + c2 = 0; + mul_add_c(a[7], b[7], c3, c1, c2); + r[14] = c3; + r[15] = c1; +} + +void bn_mul_comba4(BN_ULONG r[8], const BN_ULONG a[4], const BN_ULONG b[4]) { + BN_ULONG c1, c2, c3; + + c1 = 0; + c2 = 0; + c3 = 0; + mul_add_c(a[0], b[0], c1, c2, c3); + r[0] = c1; + c1 = 0; + mul_add_c(a[0], b[1], c2, c3, c1); + mul_add_c(a[1], b[0], c2, c3, c1); + r[1] = c2; + c2 = 0; + mul_add_c(a[2], b[0], c3, c1, c2); + mul_add_c(a[1], b[1], c3, c1, c2); + mul_add_c(a[0], b[2], c3, c1, c2); + r[2] = c3; + c3 = 0; + mul_add_c(a[0], b[3], c1, c2, c3); + mul_add_c(a[1], b[2], c1, c2, c3); + mul_add_c(a[2], b[1], c1, c2, c3); + mul_add_c(a[3], b[0], c1, c2, c3); + r[3] = c1; + c1 = 0; + mul_add_c(a[3], b[1], c2, c3, c1); + mul_add_c(a[2], b[2], c2, c3, c1); + mul_add_c(a[1], b[3], c2, c3, c1); + r[4] = c2; + c2 = 0; + mul_add_c(a[2], b[3], c3, c1, c2); + mul_add_c(a[3], b[2], c3, c1, c2); + r[5] = c3; + c3 = 0; + mul_add_c(a[3], b[3], c1, c2, c3); + r[6] = c1; + r[7] = c2; +} + +void bn_sqr_comba8(BN_ULONG r[16], const BN_ULONG a[8]) { + BN_ULONG c1, c2, c3; + + c1 = 0; + c2 = 0; + c3 = 0; + sqr_add_c(a, 0, c1, c2, c3); + r[0] = c1; + c1 = 0; + sqr_add_c2(a, 1, 0, c2, c3, c1); + r[1] = c2; + c2 = 0; + sqr_add_c(a, 1, c3, c1, c2); + sqr_add_c2(a, 2, 0, c3, c1, c2); + r[2] = c3; + c3 = 0; + sqr_add_c2(a, 3, 0, c1, c2, c3); + sqr_add_c2(a, 2, 1, c1, c2, c3); + r[3] = c1; + c1 = 0; + sqr_add_c(a, 2, c2, c3, c1); + sqr_add_c2(a, 3, 1, c2, c3, c1); + sqr_add_c2(a, 4, 0, c2, c3, c1); + r[4] = c2; + c2 = 0; + sqr_add_c2(a, 5, 0, c3, c1, c2); + sqr_add_c2(a, 4, 1, c3, c1, c2); + sqr_add_c2(a, 3, 2, c3, c1, c2); + r[5] = c3; + c3 = 0; + sqr_add_c(a, 3, c1, c2, c3); + sqr_add_c2(a, 4, 2, c1, c2, c3); + sqr_add_c2(a, 5, 1, c1, c2, c3); + sqr_add_c2(a, 6, 0, c1, c2, c3); + r[6] = c1; + c1 = 0; + sqr_add_c2(a, 7, 0, c2, c3, c1); + sqr_add_c2(a, 6, 1, c2, c3, c1); + sqr_add_c2(a, 5, 2, c2, c3, c1); + sqr_add_c2(a, 4, 3, c2, c3, c1); + r[7] = c2; + c2 = 0; + sqr_add_c(a, 4, c3, c1, c2); + sqr_add_c2(a, 5, 3, c3, c1, c2); + sqr_add_c2(a, 6, 2, c3, c1, c2); + sqr_add_c2(a, 7, 1, c3, c1, c2); + r[8] = c3; + c3 = 0; + sqr_add_c2(a, 7, 2, c1, c2, c3); + sqr_add_c2(a, 6, 3, c1, c2, c3); + sqr_add_c2(a, 5, 4, c1, c2, c3); + r[9] = c1; + c1 = 0; + sqr_add_c(a, 5, c2, c3, c1); + sqr_add_c2(a, 6, 4, c2, c3, c1); + sqr_add_c2(a, 7, 3, c2, c3, c1); + r[10] = c2; + c2 = 0; + sqr_add_c2(a, 7, 4, c3, c1, c2); + sqr_add_c2(a, 6, 5, c3, c1, c2); + r[11] = c3; + c3 = 0; + sqr_add_c(a, 6, c1, c2, c3); + sqr_add_c2(a, 7, 5, c1, c2, c3); + r[12] = c1; + c1 = 0; + sqr_add_c2(a, 7, 6, c2, c3, c1); + r[13] = c2; + c2 = 0; + sqr_add_c(a, 7, c3, c1, c2); + r[14] = c3; + r[15] = c1; +} + +void bn_sqr_comba4(BN_ULONG r[8], const BN_ULONG a[4]) { + BN_ULONG c1, c2, c3; + + c1 = 0; + c2 = 0; + c3 = 0; + sqr_add_c(a, 0, c1, c2, c3); + r[0] = c1; + c1 = 0; + sqr_add_c2(a, 1, 0, c2, c3, c1); + r[1] = c2; + c2 = 0; + sqr_add_c(a, 1, c3, c1, c2); + sqr_add_c2(a, 2, 0, c3, c1, c2); + r[2] = c3; + c3 = 0; + sqr_add_c2(a, 3, 0, c1, c2, c3); + sqr_add_c2(a, 2, 1, c1, c2, c3); + r[3] = c1; + c1 = 0; + sqr_add_c(a, 2, c2, c3, c1); + sqr_add_c2(a, 3, 1, c2, c3, c1); + r[4] = c2; + c2 = 0; + sqr_add_c2(a, 3, 2, c3, c1, c2); + r[5] = c3; + c3 = 0; + sqr_add_c(a, 3, c1, c2, c3); + r[6] = c1; + r[7] = c2; +} + +#undef mul_add +#undef mul +#undef sqr +#undef mul_add_c +#undef mul_add_c2 +#undef sqr_add_c +#undef sqr_add_c2 + +#endif diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/internal.h b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/internal.h new file mode 100644 index 0000000..f02d668 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/internal.h @@ -0,0 +1,573 @@ +/* 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-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 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 OPENSSL_HEADER_BN_INTERNAL_H +#define OPENSSL_HEADER_BN_INTERNAL_H + +#include + +#if defined(OPENSSL_X86_64) && defined(_MSC_VER) +OPENSSL_MSVC_PRAGMA(warning(push, 3)) +#include +OPENSSL_MSVC_PRAGMA(warning(pop)) +#pragma intrinsic(__umulh, _umul128) +#endif + +#include "../../internal.h" + +#if defined(__cplusplus) +extern "C" { +#endif + +#if defined(OPENSSL_64_BIT) + +#if defined(BORINGSSL_HAS_UINT128) +// MSVC doesn't support two-word integers on 64-bit. +#define BN_ULLONG uint128_t +#if defined(BORINGSSL_CAN_DIVIDE_UINT128) +#define BN_CAN_DIVIDE_ULLONG +#endif +#endif + +#define BN_BITS2 64 +#define BN_BYTES 8 +#define BN_BITS4 32 +#define BN_MASK2 (0xffffffffffffffffUL) +#define BN_MASK2l (0xffffffffUL) +#define BN_MASK2h (0xffffffff00000000UL) +#define BN_MASK2h1 (0xffffffff80000000UL) +#define BN_MONT_CTX_N0_LIMBS 1 +#define BN_DEC_CONV (10000000000000000000UL) +#define BN_DEC_NUM 19 +#define TOBN(hi, lo) ((BN_ULONG)(hi) << 32 | (lo)) + +#elif defined(OPENSSL_32_BIT) + +#define BN_ULLONG uint64_t +#define BN_CAN_DIVIDE_ULLONG +#define BN_BITS2 32 +#define BN_BYTES 4 +#define BN_BITS4 16 +#define BN_MASK2 (0xffffffffUL) +#define BN_MASK2l (0xffffUL) +#define BN_MASK2h1 (0xffff8000UL) +#define BN_MASK2h (0xffff0000UL) +// On some 32-bit platforms, Montgomery multiplication is done using 64-bit +// arithmetic with SIMD instructions. On such platforms, |BN_MONT_CTX::n0| +// needs to be two words long. Only certain 32-bit platforms actually make use +// of n0[1] and shorter R value would suffice for the others. However, +// currently only the assembly files know which is which. +#define BN_MONT_CTX_N0_LIMBS 2 +#define BN_DEC_CONV (1000000000UL) +#define BN_DEC_NUM 9 +#define TOBN(hi, lo) (lo), (hi) + +#else +#error "Must define either OPENSSL_32_BIT or OPENSSL_64_BIT" +#endif + + +#define STATIC_BIGNUM(x) \ + { \ + (BN_ULONG *)(x), sizeof(x) / sizeof(BN_ULONG), \ + sizeof(x) / sizeof(BN_ULONG), 0, BN_FLG_STATIC_DATA \ + } + +#if defined(BN_ULLONG) +#define Lw(t) ((BN_ULONG)(t)) +#define Hw(t) ((BN_ULONG)((t) >> BN_BITS2)) +#endif + +// bn_minimal_width returns the minimal value of |bn->top| which fits the +// value of |bn|. +int bn_minimal_width(const BIGNUM *bn); + +// bn_set_minimal_width sets |bn->width| to |bn_minimal_width(bn)|. If |bn| is +// zero, |bn->neg| is set to zero. +void bn_set_minimal_width(BIGNUM *bn); + +// bn_wexpand ensures that |bn| has at least |words| works of space without +// altering its value. It returns one on success or zero on allocation +// failure. +int bn_wexpand(BIGNUM *bn, size_t words); + +// bn_expand acts the same as |bn_wexpand|, but takes a number of bits rather +// than a number of words. +int bn_expand(BIGNUM *bn, size_t bits); + +// bn_resize_words adjusts |bn->top| to be |words|. It returns one on success +// and zero on allocation error or if |bn|'s value is too large. +OPENSSL_EXPORT int bn_resize_words(BIGNUM *bn, size_t words); + +// bn_select_words sets |r| to |a| if |mask| is all ones or |b| if |mask| is +// all zeros. +void bn_select_words(BN_ULONG *r, BN_ULONG mask, const BN_ULONG *a, + const BN_ULONG *b, size_t num); + +// bn_set_words sets |bn| to the value encoded in the |num| words in |words|, +// least significant word first. +int bn_set_words(BIGNUM *bn, const BN_ULONG *words, size_t num); + +// bn_fits_in_words returns one if |bn| may be represented in |num| words, plus +// a sign bit, and zero otherwise. +int bn_fits_in_words(const BIGNUM *bn, size_t num); + +// bn_copy_words copies the value of |bn| to |out| and returns one if the value +// is representable in |num| words. Otherwise, it returns zero. +int bn_copy_words(BN_ULONG *out, size_t num, const BIGNUM *bn); + +// bn_mul_add_words multiples |ap| by |w|, adds the result to |rp|, and places +// the result in |rp|. |ap| and |rp| must both be |num| words long. It returns +// the carry word of the operation. |ap| and |rp| may be equal but otherwise may +// not alias. +BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, size_t num, + BN_ULONG w); + +// bn_mul_words multiples |ap| by |w| and places the result in |rp|. |ap| and +// |rp| must both be |num| words long. It returns the carry word of the +// operation. |ap| and |rp| may be equal but otherwise may not alias. +BN_ULONG bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, size_t num, BN_ULONG w); + +// bn_sqr_words sets |rp[2*i]| and |rp[2*i+1]| to |ap[i]|'s square, for all |i| +// up to |num|. |ap| is an array of |num| words and |rp| an array of |2*num| +// words. |ap| and |rp| may not alias. +// +// This gives the contribution of the |ap[i]*ap[i]| terms when squaring |ap|. +void bn_sqr_words(BN_ULONG *rp, const BN_ULONG *ap, size_t num); + +// bn_add_words adds |ap| to |bp| and places the result in |rp|, each of which +// are |num| words long. It returns the carry bit, which is one if the operation +// overflowed and zero otherwise. Any pair of |ap|, |bp|, and |rp| may be equal +// to each other but otherwise may not alias. +BN_ULONG bn_add_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, + size_t num); + +// bn_sub_words subtracts |bp| from |ap| and places the result in |rp|. It +// returns the borrow bit, which is one if the computation underflowed and zero +// otherwise. Any pair of |ap|, |bp|, and |rp| may be equal to each other but +// otherwise may not alias. +BN_ULONG bn_sub_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, + size_t num); + +// bn_mul_comba4 sets |r| to the product of |a| and |b|. +void bn_mul_comba4(BN_ULONG r[8], const BN_ULONG a[4], const BN_ULONG b[4]); + +// bn_mul_comba8 sets |r| to the product of |a| and |b|. +void bn_mul_comba8(BN_ULONG r[16], const BN_ULONG a[8], const BN_ULONG b[8]); + +// bn_sqr_comba8 sets |r| to |a|^2. +void bn_sqr_comba8(BN_ULONG r[16], const BN_ULONG a[4]); + +// bn_sqr_comba4 sets |r| to |a|^2. +void bn_sqr_comba4(BN_ULONG r[8], const BN_ULONG a[4]); + +// bn_less_than_words returns one if |a| < |b| and zero otherwise, where |a| +// and |b| both are |len| words long. It runs in constant time. +int bn_less_than_words(const BN_ULONG *a, const BN_ULONG *b, size_t len); + +// bn_in_range_words returns one if |min_inclusive| <= |a| < |max_exclusive|, +// where |a| and |max_exclusive| both are |len| words long. |a| and +// |max_exclusive| are treated as secret. +int bn_in_range_words(const BN_ULONG *a, BN_ULONG min_inclusive, + const BN_ULONG *max_exclusive, size_t len); + +// bn_rand_range_words sets |out| to a uniformly distributed random number from +// |min_inclusive| to |max_exclusive|. Both |out| and |max_exclusive| are |len| +// words long. +// +// This function runs in time independent of the result, but |min_inclusive| and +// |max_exclusive| are public data. (Information about the range is unavoidably +// leaked by how many iterations it took to select a number.) +int bn_rand_range_words(BN_ULONG *out, BN_ULONG min_inclusive, + const BN_ULONG *max_exclusive, size_t len, + const uint8_t additional_data[32]); + +// bn_range_secret_range behaves like |BN_rand_range_ex|, but treats +// |max_exclusive| as secret. Because of this constraint, the distribution of +// values returned is more complex. +// +// Rather than repeatedly generating values until one is in range, which would +// leak information, it generates one value. If the value is in range, it sets +// |*out_is_uniform| to one. Otherwise, it sets |*out_is_uniform| to zero, +// fixing up the value to force it in range. +// +// The subset of calls to |bn_rand_secret_range| which set |*out_is_uniform| to +// one are uniformly distributed in the target range. Calls overall are not. +// This function is intended for use in situations where the extra values are +// still usable and where the number of iterations needed to reach the target +// number of uniform outputs may be blinded for negligible probabilities of +// timing leaks. +// +// Although this function treats |max_exclusive| as secret, it treats the number +// of bits in |max_exclusive| as public. +int bn_rand_secret_range(BIGNUM *r, int *out_is_uniform, BN_ULONG min_inclusive, + const BIGNUM *max_exclusive); + +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); + +uint64_t bn_mont_n0(const BIGNUM *n); + +// bn_mod_exp_base_2_consttime calculates r = 2**p (mod n). |p| must be larger +// than log_2(n); i.e. 2**p must be larger than |n|. |n| must be positive and +// odd. |p| and the bit width of |n| are assumed public, but |n| is otherwise +// treated as secret. +int bn_mod_exp_base_2_consttime(BIGNUM *r, unsigned p, const BIGNUM *n, + BN_CTX *ctx); + +#if defined(OPENSSL_X86_64) && defined(_MSC_VER) +#define BN_UMULT_LOHI(low, high, a, b) ((low) = _umul128((a), (b), &(high))) +#endif + +#if !defined(BN_ULLONG) && !defined(BN_UMULT_LOHI) +#error "Either BN_ULLONG or BN_UMULT_LOHI must be defined on every platform." +#endif + +// bn_jacobi returns the Jacobi symbol of |a| and |b| (which is -1, 0 or 1), or +// -2 on error. +int bn_jacobi(const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx); + +// bn_is_bit_set_words returns one if bit |bit| is set in |a| and zero +// otherwise. +int bn_is_bit_set_words(const BN_ULONG *a, size_t num, unsigned bit); + +// bn_one_to_montgomery sets |r| to one in Montgomery form. It returns one on +// success and zero on error. This function treats the bit width of the modulus +// as public. +int bn_one_to_montgomery(BIGNUM *r, const BN_MONT_CTX *mont, BN_CTX *ctx); + +// bn_less_than_montgomery_R returns one if |bn| is less than the Montgomery R +// value for |mont| and zero otherwise. +int bn_less_than_montgomery_R(const BIGNUM *bn, const BN_MONT_CTX *mont); + +// bn_mod_u16_consttime returns |bn| mod |d|, ignoring |bn|'s sign bit. It runs +// in time independent of the value of |bn|, but it treats |d| as public. +OPENSSL_EXPORT uint16_t bn_mod_u16_consttime(const BIGNUM *bn, uint16_t d); + +// bn_odd_number_is_obviously_composite returns one if |bn| is divisible by one +// of the first several odd primes and zero otherwise. +int bn_odd_number_is_obviously_composite(const BIGNUM *bn); + +// bn_rshift1_words sets |r| to |a| >> 1, where both arrays are |num| bits wide. +void bn_rshift1_words(BN_ULONG *r, const BN_ULONG *a, size_t num); + +// bn_rshift_secret_shift behaves like |BN_rshift| but runs in time independent +// of both |a| and |n|. +OPENSSL_EXPORT int bn_rshift_secret_shift(BIGNUM *r, const BIGNUM *a, + unsigned n, BN_CTX *ctx); + + +// Constant-time non-modular arithmetic. +// +// The following functions implement non-modular arithmetic in constant-time +// and pessimally set |r->width| to the largest possible word size. +// +// Note this means that, e.g., repeatedly multiplying by one will cause widths +// to increase without bound. The corresponding public API functions minimize +// their outputs to avoid regressing calculator consumers. + +// bn_uadd_consttime behaves like |BN_uadd|, but it pessimally sets +// |r->width| = |a->width| + |b->width| + 1. +int bn_uadd_consttime(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); + +// bn_usub_consttime behaves like |BN_usub|, but it pessimally sets +// |r->width| = |a->width|. +int bn_usub_consttime(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); + +// bn_abs_sub_consttime sets |r| to the absolute value of |a| - |b|, treating +// both inputs as secret. It returns one on success and zero on error. +OPENSSL_EXPORT int bn_abs_sub_consttime(BIGNUM *r, const BIGNUM *a, + const BIGNUM *b, BN_CTX *ctx); + +// bn_mul_consttime behaves like |BN_mul|, but it rejects negative inputs and +// pessimally sets |r->width| to |a->width| + |b->width|, to avoid leaking +// information about |a| and |b|. +int bn_mul_consttime(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx); + +// bn_sqrt_consttime behaves like |BN_sqrt|, but it pessimally sets |r->width| +// to 2*|a->width|, to avoid leaking information about |a| and |b|. +int bn_sqr_consttime(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx); + +// bn_div_consttime behaves like |BN_div|, but it rejects negative inputs and +// treats both inputs, including their magnitudes, as secret. It is, as a +// result, much slower than |BN_div| and should only be used for rare operations +// where Montgomery reduction is not available. +// +// Note that |quotient->width| will be set pessimally to |numerator->width|. +OPENSSL_EXPORT int bn_div_consttime(BIGNUM *quotient, BIGNUM *remainder, + const BIGNUM *numerator, + const BIGNUM *divisor, BN_CTX *ctx); + +// bn_is_relatively_prime checks whether GCD(|x|, |y|) is one. On success, it +// returns one and sets |*out_relatively_prime| to one if the GCD was one and +// zero otherwise. On error, it returns zero. +OPENSSL_EXPORT int bn_is_relatively_prime(int *out_relatively_prime, + const BIGNUM *x, const BIGNUM *y, + BN_CTX *ctx); + +// bn_lcm_consttime sets |r| to LCM(|a|, |b|). It returns one and success and +// zero on error. |a| and |b| are both treated as secret. +OPENSSL_EXPORT int bn_lcm_consttime(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + BN_CTX *ctx); + + +// Constant-time modular arithmetic. +// +// The following functions implement basic constant-time modular arithmetic. + +// bn_mod_add_consttime acts like |BN_mod_add_quick| but takes a |BN_CTX|. +int bn_mod_add_consttime(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const BIGNUM *m, BN_CTX *ctx); + +// bn_mod_sub_consttime acts like |BN_mod_sub_quick| but takes a |BN_CTX|. +int bn_mod_sub_consttime(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const BIGNUM *m, BN_CTX *ctx); + +// bn_mod_lshift1_consttime acts like |BN_mod_lshift1_quick| but takes a +// |BN_CTX|. +int bn_mod_lshift1_consttime(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, + BN_CTX *ctx); + +// bn_mod_lshift_consttime acts like |BN_mod_lshift_quick| but takes a |BN_CTX|. +int bn_mod_lshift_consttime(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m, + BN_CTX *ctx); + +// bn_mod_inverse_consttime sets |r| to |a|^-1, mod |n|. |a| must be non- +// negative and less than |n|. It returns one on success and zero on error. On +// failure, if the failure was caused by |a| having no inverse mod |n| then +// |*out_no_inverse| will be set to one; otherwise it will be set to zero. +// +// This function treats both |a| and |n| as secret, provided they are both non- +// zero and the inverse exists. It should only be used for even moduli where +// none of the less general implementations are applicable. +OPENSSL_EXPORT int bn_mod_inverse_consttime(BIGNUM *r, int *out_no_inverse, + const BIGNUM *a, const BIGNUM *n, + BN_CTX *ctx); + +// bn_mod_inverse_prime sets |out| to the modular inverse of |a| modulo |p|, +// computed with Fermat's Little Theorem. It returns one on success and zero on +// error. If |mont_p| is NULL, one will be computed temporarily. +int bn_mod_inverse_prime(BIGNUM *out, const BIGNUM *a, const BIGNUM *p, + BN_CTX *ctx, const BN_MONT_CTX *mont_p); + +// bn_mod_inverse_secret_prime behaves like |bn_mod_inverse_prime| but uses +// |BN_mod_exp_mont_consttime| instead of |BN_mod_exp_mont| in hopes of +// protecting the exponent. +int bn_mod_inverse_secret_prime(BIGNUM *out, const BIGNUM *a, const BIGNUM *p, + BN_CTX *ctx, const BN_MONT_CTX *mont_p); + + +// Low-level operations for small numbers. +// +// The following functions implement algorithms suitable for use with scalars +// and field elements in elliptic curves. They rely on the number being small +// both to stack-allocate various temporaries and because they do not implement +// optimizations useful for the larger values used in RSA. + +// BN_SMALL_MAX_WORDS is the largest size input these functions handle. This +// limit allows temporaries to be more easily stack-allocated. This limit is set +// to accommodate P-521. +#if defined(OPENSSL_32_BIT) +#define BN_SMALL_MAX_WORDS 17 +#else +#define BN_SMALL_MAX_WORDS 9 +#endif + +// bn_mul_small sets |r| to |a|*|b|. |num_r| must be |num_a| + |num_b|. |r| may +// not alias with |a| or |b|. This function returns one on success and zero if +// lengths are inconsistent. +int bn_mul_small(BN_ULONG *r, size_t num_r, const BN_ULONG *a, size_t num_a, + const BN_ULONG *b, size_t num_b); + +// bn_sqr_small sets |r| to |a|^2. |num_a| must be at most |BN_SMALL_MAX_WORDS|. +// |num_r| must be |num_a|*2. |r| and |a| may not alias. This function returns +// one on success and zero on programmer error. +int bn_sqr_small(BN_ULONG *r, size_t num_r, const BN_ULONG *a, size_t num_a); + +// In the following functions, the modulus must be at most |BN_SMALL_MAX_WORDS| +// words long. + +// bn_to_montgomery_small sets |r| to |a| translated to the Montgomery domain. +// |num_a| and |num_r| must be the length of the modulus, which is +// |mont->N.top|. |a| must be fully reduced. This function returns one on +// success and zero if lengths are inconsistent. |r| and |a| may alias. +int bn_to_montgomery_small(BN_ULONG *r, size_t num_r, const BN_ULONG *a, + size_t num_a, const BN_MONT_CTX *mont); + +// bn_from_montgomery_small sets |r| to |a| translated out of the Montgomery +// domain. |num_r| must be the length of the modulus, which is |mont->N.top|. +// |a| must be at most |mont->N.top| * R and |num_a| must be at most 2 * +// |mont->N.top|. This function returns one on success and zero if lengths are +// inconsistent. |r| and |a| may alias. +int bn_from_montgomery_small(BN_ULONG *r, size_t num_r, const BN_ULONG *a, + size_t num_a, const BN_MONT_CTX *mont); + +// bn_one_to_montgomery_small sets |r| to one in Montgomery form. It returns one +// on success and zero on error. |num_r| must be the length of the modulus, +// which is |mont->N.top|. This function treats the bit width of the modulus as +// public. +int bn_one_to_montgomery_small(BN_ULONG *r, size_t num_r, + const BN_MONT_CTX *mont); + +// bn_mod_mul_montgomery_small sets |r| to |a| * |b| mod |mont->N|. Both inputs +// and outputs are in the Montgomery domain. |num_r| must be the length of the +// modulus, which is |mont->N.top|. This function returns one on success and +// zero on internal error or inconsistent lengths. Any two of |r|, |a|, and |b| +// may alias. +// +// This function requires |a| * |b| < N * R, where N is the modulus and R is the +// Montgomery divisor, 2^(N.top * BN_BITS2). This should generally be satisfied +// by ensuring |a| and |b| are fully reduced, however ECDSA has one computation +// which requires the more general bound. +int bn_mod_mul_montgomery_small(BN_ULONG *r, size_t num_r, const BN_ULONG *a, + size_t num_a, const BN_ULONG *b, size_t num_b, + const BN_MONT_CTX *mont); + +// bn_mod_exp_mont_small sets |r| to |a|^|p| mod |mont->N|. It returns one on +// success and zero on programmer or internal error. Both inputs and outputs are +// in the Montgomery domain. |num_r| and |num_a| must be |mont->N.top|, which +// must be at most |BN_SMALL_MAX_WORDS|. |a| must be fully-reduced. This +// function runs in time independent of |a|, but |p| and |mont->N| are public +// values. +// +// Note this function differs from |BN_mod_exp_mont| which uses Montgomery +// reduction but takes input and output outside the Montgomery domain. Combine +// this function with |bn_from_montgomery_small| and |bn_to_montgomery_small| +// if necessary. +int bn_mod_exp_mont_small(BN_ULONG *r, size_t num_r, const BN_ULONG *a, + size_t num_a, const BN_ULONG *p, size_t num_p, + const BN_MONT_CTX *mont); + +// bn_mod_inverse_prime_mont_small sets |r| to |a|^-1 mod |mont->N|. |mont->N| +// must be a prime. |num_r| and |num_a| must be |mont->N.top|, which must be at +// most |BN_SMALL_MAX_WORDS|. |a| must be fully-reduced. This function runs in +// time independent of |a|, but |mont->N| is a public value. +int bn_mod_inverse_prime_mont_small(BN_ULONG *r, size_t num_r, + const BN_ULONG *a, size_t num_a, + const BN_MONT_CTX *mont); + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_BN_INTERNAL_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/internal.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/internal.h.grpc_back new file mode 100644 index 0000000..a8ad129 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/internal.h.grpc_back @@ -0,0 +1,573 @@ +/* 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-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 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 OPENSSL_HEADER_BN_INTERNAL_H +#define OPENSSL_HEADER_BN_INTERNAL_H + +#include + +#if defined(OPENSSL_X86_64) && defined(_MSC_VER) +OPENSSL_MSVC_PRAGMA(warning(push, 3)) +#include +OPENSSL_MSVC_PRAGMA(warning(pop)) +#pragma intrinsic(__umulh, _umul128) +#endif + +#include "../../internal.h" + +#if defined(__cplusplus) +extern "C" { +#endif + +#if defined(OPENSSL_64_BIT) + +#if defined(BORINGSSL_HAS_UINT128) +// MSVC doesn't support two-word integers on 64-bit. +#define BN_ULLONG uint128_t +#if defined(BORINGSSL_CAN_DIVIDE_UINT128) +#define BN_CAN_DIVIDE_ULLONG +#endif +#endif + +#define BN_BITS2 64 +#define BN_BYTES 8 +#define BN_BITS4 32 +#define BN_MASK2 (0xffffffffffffffffUL) +#define BN_MASK2l (0xffffffffUL) +#define BN_MASK2h (0xffffffff00000000UL) +#define BN_MASK2h1 (0xffffffff80000000UL) +#define BN_MONT_CTX_N0_LIMBS 1 +#define BN_DEC_CONV (10000000000000000000UL) +#define BN_DEC_NUM 19 +#define TOBN(hi, lo) ((BN_ULONG)(hi) << 32 | (lo)) + +#elif defined(OPENSSL_32_BIT) + +#define BN_ULLONG uint64_t +#define BN_CAN_DIVIDE_ULLONG +#define BN_BITS2 32 +#define BN_BYTES 4 +#define BN_BITS4 16 +#define BN_MASK2 (0xffffffffUL) +#define BN_MASK2l (0xffffUL) +#define BN_MASK2h1 (0xffff8000UL) +#define BN_MASK2h (0xffff0000UL) +// On some 32-bit platforms, Montgomery multiplication is done using 64-bit +// arithmetic with SIMD instructions. On such platforms, |BN_MONT_CTX::n0| +// needs to be two words long. Only certain 32-bit platforms actually make use +// of n0[1] and shorter R value would suffice for the others. However, +// currently only the assembly files know which is which. +#define BN_MONT_CTX_N0_LIMBS 2 +#define BN_DEC_CONV (1000000000UL) +#define BN_DEC_NUM 9 +#define TOBN(hi, lo) (lo), (hi) + +#else +#error "Must define either OPENSSL_32_BIT or OPENSSL_64_BIT" +#endif + + +#define STATIC_BIGNUM(x) \ + { \ + (BN_ULONG *)(x), sizeof(x) / sizeof(BN_ULONG), \ + sizeof(x) / sizeof(BN_ULONG), 0, BN_FLG_STATIC_DATA \ + } + +#if defined(BN_ULLONG) +#define Lw(t) ((BN_ULONG)(t)) +#define Hw(t) ((BN_ULONG)((t) >> BN_BITS2)) +#endif + +// bn_minimal_width returns the minimal value of |bn->top| which fits the +// value of |bn|. +int bn_minimal_width(const BIGNUM *bn); + +// bn_set_minimal_width sets |bn->width| to |bn_minimal_width(bn)|. If |bn| is +// zero, |bn->neg| is set to zero. +void bn_set_minimal_width(BIGNUM *bn); + +// bn_wexpand ensures that |bn| has at least |words| works of space without +// altering its value. It returns one on success or zero on allocation +// failure. +int bn_wexpand(BIGNUM *bn, size_t words); + +// bn_expand acts the same as |bn_wexpand|, but takes a number of bits rather +// than a number of words. +int bn_expand(BIGNUM *bn, size_t bits); + +// bn_resize_words adjusts |bn->top| to be |words|. It returns one on success +// and zero on allocation error or if |bn|'s value is too large. +OPENSSL_EXPORT int bn_resize_words(BIGNUM *bn, size_t words); + +// bn_select_words sets |r| to |a| if |mask| is all ones or |b| if |mask| is +// all zeros. +void bn_select_words(BN_ULONG *r, BN_ULONG mask, const BN_ULONG *a, + const BN_ULONG *b, size_t num); + +// bn_set_words sets |bn| to the value encoded in the |num| words in |words|, +// least significant word first. +int bn_set_words(BIGNUM *bn, const BN_ULONG *words, size_t num); + +// bn_fits_in_words returns one if |bn| may be represented in |num| words, plus +// a sign bit, and zero otherwise. +int bn_fits_in_words(const BIGNUM *bn, size_t num); + +// bn_copy_words copies the value of |bn| to |out| and returns one if the value +// is representable in |num| words. Otherwise, it returns zero. +int bn_copy_words(BN_ULONG *out, size_t num, const BIGNUM *bn); + +// bn_mul_add_words multiples |ap| by |w|, adds the result to |rp|, and places +// the result in |rp|. |ap| and |rp| must both be |num| words long. It returns +// the carry word of the operation. |ap| and |rp| may be equal but otherwise may +// not alias. +BN_ULONG bn_mul_add_words(BN_ULONG *rp, const BN_ULONG *ap, size_t num, + BN_ULONG w); + +// bn_mul_words multiples |ap| by |w| and places the result in |rp|. |ap| and +// |rp| must both be |num| words long. It returns the carry word of the +// operation. |ap| and |rp| may be equal but otherwise may not alias. +BN_ULONG bn_mul_words(BN_ULONG *rp, const BN_ULONG *ap, size_t num, BN_ULONG w); + +// bn_sqr_words sets |rp[2*i]| and |rp[2*i+1]| to |ap[i]|'s square, for all |i| +// up to |num|. |ap| is an array of |num| words and |rp| an array of |2*num| +// words. |ap| and |rp| may not alias. +// +// This gives the contribution of the |ap[i]*ap[i]| terms when squaring |ap|. +void bn_sqr_words(BN_ULONG *rp, const BN_ULONG *ap, size_t num); + +// bn_add_words adds |ap| to |bp| and places the result in |rp|, each of which +// are |num| words long. It returns the carry bit, which is one if the operation +// overflowed and zero otherwise. Any pair of |ap|, |bp|, and |rp| may be equal +// to each other but otherwise may not alias. +BN_ULONG bn_add_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, + size_t num); + +// bn_sub_words subtracts |bp| from |ap| and places the result in |rp|. It +// returns the borrow bit, which is one if the computation underflowed and zero +// otherwise. Any pair of |ap|, |bp|, and |rp| may be equal to each other but +// otherwise may not alias. +BN_ULONG bn_sub_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, + size_t num); + +// bn_mul_comba4 sets |r| to the product of |a| and |b|. +void bn_mul_comba4(BN_ULONG r[8], const BN_ULONG a[4], const BN_ULONG b[4]); + +// bn_mul_comba8 sets |r| to the product of |a| and |b|. +void bn_mul_comba8(BN_ULONG r[16], const BN_ULONG a[8], const BN_ULONG b[8]); + +// bn_sqr_comba8 sets |r| to |a|^2. +void bn_sqr_comba8(BN_ULONG r[16], const BN_ULONG a[4]); + +// bn_sqr_comba4 sets |r| to |a|^2. +void bn_sqr_comba4(BN_ULONG r[8], const BN_ULONG a[4]); + +// bn_less_than_words returns one if |a| < |b| and zero otherwise, where |a| +// and |b| both are |len| words long. It runs in constant time. +int bn_less_than_words(const BN_ULONG *a, const BN_ULONG *b, size_t len); + +// bn_in_range_words returns one if |min_inclusive| <= |a| < |max_exclusive|, +// where |a| and |max_exclusive| both are |len| words long. |a| and +// |max_exclusive| are treated as secret. +int bn_in_range_words(const BN_ULONG *a, BN_ULONG min_inclusive, + const BN_ULONG *max_exclusive, size_t len); + +// bn_rand_range_words sets |out| to a uniformly distributed random number from +// |min_inclusive| to |max_exclusive|. Both |out| and |max_exclusive| are |len| +// words long. +// +// This function runs in time independent of the result, but |min_inclusive| and +// |max_exclusive| are public data. (Information about the range is unavoidably +// leaked by how many iterations it took to select a number.) +int bn_rand_range_words(BN_ULONG *out, BN_ULONG min_inclusive, + const BN_ULONG *max_exclusive, size_t len, + const uint8_t additional_data[32]); + +// bn_range_secret_range behaves like |BN_rand_range_ex|, but treats +// |max_exclusive| as secret. Because of this constraint, the distribution of +// values returned is more complex. +// +// Rather than repeatedly generating values until one is in range, which would +// leak information, it generates one value. If the value is in range, it sets +// |*out_is_uniform| to one. Otherwise, it sets |*out_is_uniform| to zero, +// fixing up the value to force it in range. +// +// The subset of calls to |bn_rand_secret_range| which set |*out_is_uniform| to +// one are uniformly distributed in the target range. Calls overall are not. +// This function is intended for use in situations where the extra values are +// still usable and where the number of iterations needed to reach the target +// number of uniform outputs may be blinded for negligible probabilities of +// timing leaks. +// +// Although this function treats |max_exclusive| as secret, it treats the number +// of bits in |max_exclusive| as public. +int bn_rand_secret_range(BIGNUM *r, int *out_is_uniform, BN_ULONG min_inclusive, + const BIGNUM *max_exclusive); + +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); + +uint64_t bn_mont_n0(const BIGNUM *n); + +// bn_mod_exp_base_2_consttime calculates r = 2**p (mod n). |p| must be larger +// than log_2(n); i.e. 2**p must be larger than |n|. |n| must be positive and +// odd. |p| and the bit width of |n| are assumed public, but |n| is otherwise +// treated as secret. +int bn_mod_exp_base_2_consttime(BIGNUM *r, unsigned p, const BIGNUM *n, + BN_CTX *ctx); + +#if defined(OPENSSL_X86_64) && defined(_MSC_VER) +#define BN_UMULT_LOHI(low, high, a, b) ((low) = _umul128((a), (b), &(high))) +#endif + +#if !defined(BN_ULLONG) && !defined(BN_UMULT_LOHI) +#error "Either BN_ULLONG or BN_UMULT_LOHI must be defined on every platform." +#endif + +// bn_jacobi returns the Jacobi symbol of |a| and |b| (which is -1, 0 or 1), or +// -2 on error. +int bn_jacobi(const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx); + +// bn_is_bit_set_words returns one if bit |bit| is set in |a| and zero +// otherwise. +int bn_is_bit_set_words(const BN_ULONG *a, size_t num, unsigned bit); + +// bn_one_to_montgomery sets |r| to one in Montgomery form. It returns one on +// success and zero on error. This function treats the bit width of the modulus +// as public. +int bn_one_to_montgomery(BIGNUM *r, const BN_MONT_CTX *mont, BN_CTX *ctx); + +// bn_less_than_montgomery_R returns one if |bn| is less than the Montgomery R +// value for |mont| and zero otherwise. +int bn_less_than_montgomery_R(const BIGNUM *bn, const BN_MONT_CTX *mont); + +// bn_mod_u16_consttime returns |bn| mod |d|, ignoring |bn|'s sign bit. It runs +// in time independent of the value of |bn|, but it treats |d| as public. +OPENSSL_EXPORT uint16_t bn_mod_u16_consttime(const BIGNUM *bn, uint16_t d); + +// bn_odd_number_is_obviously_composite returns one if |bn| is divisible by one +// of the first several odd primes and zero otherwise. +int bn_odd_number_is_obviously_composite(const BIGNUM *bn); + +// bn_rshift1_words sets |r| to |a| >> 1, where both arrays are |num| bits wide. +void bn_rshift1_words(BN_ULONG *r, const BN_ULONG *a, size_t num); + +// bn_rshift_secret_shift behaves like |BN_rshift| but runs in time independent +// of both |a| and |n|. +OPENSSL_EXPORT int bn_rshift_secret_shift(BIGNUM *r, const BIGNUM *a, + unsigned n, BN_CTX *ctx); + + +// Constant-time non-modular arithmetic. +// +// The following functions implement non-modular arithmetic in constant-time +// and pessimally set |r->width| to the largest possible word size. +// +// Note this means that, e.g., repeatedly multiplying by one will cause widths +// to increase without bound. The corresponding public API functions minimize +// their outputs to avoid regressing calculator consumers. + +// bn_uadd_consttime behaves like |BN_uadd|, but it pessimally sets +// |r->width| = |a->width| + |b->width| + 1. +int bn_uadd_consttime(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); + +// bn_usub_consttime behaves like |BN_usub|, but it pessimally sets +// |r->width| = |a->width|. +int bn_usub_consttime(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); + +// bn_abs_sub_consttime sets |r| to the absolute value of |a| - |b|, treating +// both inputs as secret. It returns one on success and zero on error. +OPENSSL_EXPORT int bn_abs_sub_consttime(BIGNUM *r, const BIGNUM *a, + const BIGNUM *b, BN_CTX *ctx); + +// bn_mul_consttime behaves like |BN_mul|, but it rejects negative inputs and +// pessimally sets |r->width| to |a->width| + |b->width|, to avoid leaking +// information about |a| and |b|. +int bn_mul_consttime(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx); + +// bn_sqrt_consttime behaves like |BN_sqrt|, but it pessimally sets |r->width| +// to 2*|a->width|, to avoid leaking information about |a| and |b|. +int bn_sqr_consttime(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx); + +// bn_div_consttime behaves like |BN_div|, but it rejects negative inputs and +// treats both inputs, including their magnitudes, as secret. It is, as a +// result, much slower than |BN_div| and should only be used for rare operations +// where Montgomery reduction is not available. +// +// Note that |quotient->width| will be set pessimally to |numerator->width|. +OPENSSL_EXPORT int bn_div_consttime(BIGNUM *quotient, BIGNUM *remainder, + const BIGNUM *numerator, + const BIGNUM *divisor, BN_CTX *ctx); + +// bn_is_relatively_prime checks whether GCD(|x|, |y|) is one. On success, it +// returns one and sets |*out_relatively_prime| to one if the GCD was one and +// zero otherwise. On error, it returns zero. +OPENSSL_EXPORT int bn_is_relatively_prime(int *out_relatively_prime, + const BIGNUM *x, const BIGNUM *y, + BN_CTX *ctx); + +// bn_lcm_consttime sets |r| to LCM(|a|, |b|). It returns one and success and +// zero on error. |a| and |b| are both treated as secret. +OPENSSL_EXPORT int bn_lcm_consttime(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + BN_CTX *ctx); + + +// Constant-time modular arithmetic. +// +// The following functions implement basic constant-time modular arithmetic. + +// bn_mod_add_consttime acts like |BN_mod_add_quick| but takes a |BN_CTX|. +int bn_mod_add_consttime(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const BIGNUM *m, BN_CTX *ctx); + +// bn_mod_sub_consttime acts like |BN_mod_sub_quick| but takes a |BN_CTX|. +int bn_mod_sub_consttime(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const BIGNUM *m, BN_CTX *ctx); + +// bn_mod_lshift1_consttime acts like |BN_mod_lshift1_quick| but takes a +// |BN_CTX|. +int bn_mod_lshift1_consttime(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, + BN_CTX *ctx); + +// bn_mod_lshift_consttime acts like |BN_mod_lshift_quick| but takes a |BN_CTX|. +int bn_mod_lshift_consttime(BIGNUM *r, const BIGNUM *a, int n, const BIGNUM *m, + BN_CTX *ctx); + +// bn_mod_inverse_consttime sets |r| to |a|^-1, mod |n|. |a| must be non- +// negative and less than |n|. It returns one on success and zero on error. On +// failure, if the failure was caused by |a| having no inverse mod |n| then +// |*out_no_inverse| will be set to one; otherwise it will be set to zero. +// +// This function treats both |a| and |n| as secret, provided they are both non- +// zero and the inverse exists. It should only be used for even moduli where +// none of the less general implementations are applicable. +OPENSSL_EXPORT int bn_mod_inverse_consttime(BIGNUM *r, int *out_no_inverse, + const BIGNUM *a, const BIGNUM *n, + BN_CTX *ctx); + +// bn_mod_inverse_prime sets |out| to the modular inverse of |a| modulo |p|, +// computed with Fermat's Little Theorem. It returns one on success and zero on +// error. If |mont_p| is NULL, one will be computed temporarily. +int bn_mod_inverse_prime(BIGNUM *out, const BIGNUM *a, const BIGNUM *p, + BN_CTX *ctx, const BN_MONT_CTX *mont_p); + +// bn_mod_inverse_secret_prime behaves like |bn_mod_inverse_prime| but uses +// |BN_mod_exp_mont_consttime| instead of |BN_mod_exp_mont| in hopes of +// protecting the exponent. +int bn_mod_inverse_secret_prime(BIGNUM *out, const BIGNUM *a, const BIGNUM *p, + BN_CTX *ctx, const BN_MONT_CTX *mont_p); + + +// Low-level operations for small numbers. +// +// The following functions implement algorithms suitable for use with scalars +// and field elements in elliptic curves. They rely on the number being small +// both to stack-allocate various temporaries and because they do not implement +// optimizations useful for the larger values used in RSA. + +// BN_SMALL_MAX_WORDS is the largest size input these functions handle. This +// limit allows temporaries to be more easily stack-allocated. This limit is set +// to accommodate P-521. +#if defined(OPENSSL_32_BIT) +#define BN_SMALL_MAX_WORDS 17 +#else +#define BN_SMALL_MAX_WORDS 9 +#endif + +// bn_mul_small sets |r| to |a|*|b|. |num_r| must be |num_a| + |num_b|. |r| may +// not alias with |a| or |b|. This function returns one on success and zero if +// lengths are inconsistent. +int bn_mul_small(BN_ULONG *r, size_t num_r, const BN_ULONG *a, size_t num_a, + const BN_ULONG *b, size_t num_b); + +// bn_sqr_small sets |r| to |a|^2. |num_a| must be at most |BN_SMALL_MAX_WORDS|. +// |num_r| must be |num_a|*2. |r| and |a| may not alias. This function returns +// one on success and zero on programmer error. +int bn_sqr_small(BN_ULONG *r, size_t num_r, const BN_ULONG *a, size_t num_a); + +// In the following functions, the modulus must be at most |BN_SMALL_MAX_WORDS| +// words long. + +// bn_to_montgomery_small sets |r| to |a| translated to the Montgomery domain. +// |num_a| and |num_r| must be the length of the modulus, which is +// |mont->N.top|. |a| must be fully reduced. This function returns one on +// success and zero if lengths are inconsistent. |r| and |a| may alias. +int bn_to_montgomery_small(BN_ULONG *r, size_t num_r, const BN_ULONG *a, + size_t num_a, const BN_MONT_CTX *mont); + +// bn_from_montgomery_small sets |r| to |a| translated out of the Montgomery +// domain. |num_r| must be the length of the modulus, which is |mont->N.top|. +// |a| must be at most |mont->N.top| * R and |num_a| must be at most 2 * +// |mont->N.top|. This function returns one on success and zero if lengths are +// inconsistent. |r| and |a| may alias. +int bn_from_montgomery_small(BN_ULONG *r, size_t num_r, const BN_ULONG *a, + size_t num_a, const BN_MONT_CTX *mont); + +// bn_one_to_montgomery_small sets |r| to one in Montgomery form. It returns one +// on success and zero on error. |num_r| must be the length of the modulus, +// which is |mont->N.top|. This function treats the bit width of the modulus as +// public. +int bn_one_to_montgomery_small(BN_ULONG *r, size_t num_r, + const BN_MONT_CTX *mont); + +// bn_mod_mul_montgomery_small sets |r| to |a| * |b| mod |mont->N|. Both inputs +// and outputs are in the Montgomery domain. |num_r| must be the length of the +// modulus, which is |mont->N.top|. This function returns one on success and +// zero on internal error or inconsistent lengths. Any two of |r|, |a|, and |b| +// may alias. +// +// This function requires |a| * |b| < N * R, where N is the modulus and R is the +// Montgomery divisor, 2^(N.top * BN_BITS2). This should generally be satisfied +// by ensuring |a| and |b| are fully reduced, however ECDSA has one computation +// which requires the more general bound. +int bn_mod_mul_montgomery_small(BN_ULONG *r, size_t num_r, const BN_ULONG *a, + size_t num_a, const BN_ULONG *b, size_t num_b, + const BN_MONT_CTX *mont); + +// bn_mod_exp_mont_small sets |r| to |a|^|p| mod |mont->N|. It returns one on +// success and zero on programmer or internal error. Both inputs and outputs are +// in the Montgomery domain. |num_r| and |num_a| must be |mont->N.top|, which +// must be at most |BN_SMALL_MAX_WORDS|. |a| must be fully-reduced. This +// function runs in time independent of |a|, but |p| and |mont->N| are public +// values. +// +// Note this function differs from |BN_mod_exp_mont| which uses Montgomery +// reduction but takes input and output outside the Montgomery domain. Combine +// this function with |bn_from_montgomery_small| and |bn_to_montgomery_small| +// if necessary. +int bn_mod_exp_mont_small(BN_ULONG *r, size_t num_r, const BN_ULONG *a, + size_t num_a, const BN_ULONG *p, size_t num_p, + const BN_MONT_CTX *mont); + +// bn_mod_inverse_prime_mont_small sets |r| to |a|^-1 mod |mont->N|. |mont->N| +// must be a prime. |num_r| and |num_a| must be |mont->N.top|, which must be at +// most |BN_SMALL_MAX_WORDS|. |a| must be fully-reduced. This function runs in +// time independent of |a|, but |mont->N| is a public value. +int bn_mod_inverse_prime_mont_small(BN_ULONG *r, size_t num_r, + const BN_ULONG *a, size_t num_a, + const BN_MONT_CTX *mont); + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_BN_INTERNAL_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/jacobi.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/jacobi.c new file mode 100644 index 0000000..8d52e56 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/jacobi.c @@ -0,0 +1,146 @@ +/* ==================================================================== + * 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 "internal.h" + + +// least significant word +#define BN_lsw(n) (((n)->width == 0) ? (BN_ULONG) 0 : (n)->d[0]) + +int bn_jacobi(const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) { + // 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}; + + // The Jacobi symbol is only defined for odd modulus. + if (!BN_is_odd(b)) { + OPENSSL_PUT_ERROR(BN, BN_R_CALLED_WITH_EVEN_MODULUS); + return -2; + } + + // Require b be positive. + if (BN_is_negative(b)) { + OPENSSL_PUT_ERROR(BN, BN_R_NEGATIVE_NUMBER); + return -2; + } + + int ret = -2; + BN_CTX_start(ctx); + BIGNUM *A = BN_CTX_get(ctx); + BIGNUM *B = BN_CTX_get(ctx); + if (B == NULL) { + goto end; + } + + if (!BN_copy(A, a) || + !BN_copy(B, b)) { + goto end; + } + + // Adapted from logic to compute the Kronecker symbol, originally implemented + // according to Henri Cohen, "A Course in Computational Algebraic Number + // Theory" (algorithm 1.4.10). + + ret = 1; + + 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 + int i = 0; + while (!BN_is_bit_set(A, i)) { + i++; + } + if (!BN_rshift(A, A, i)) { + ret = -2; + 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|) + if (!BN_nnmod(B, B, A, ctx)) { + ret = -2; + goto end; + } + BIGNUM *tmp = A; + A = B; + B = tmp; + tmp->neg = 0; + } + +end: + BN_CTX_end(ctx); + return ret; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/jacobi.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/jacobi.c.grpc_back new file mode 100644 index 0000000..d1a9d50 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/jacobi.c.grpc_back @@ -0,0 +1,146 @@ +/* ==================================================================== + * 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 "internal.h" + + +// least significant word +#define BN_lsw(n) (((n)->width == 0) ? (BN_ULONG) 0 : (n)->d[0]) + +int bn_jacobi(const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) { + // 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}; + + // The Jacobi symbol is only defined for odd modulus. + if (!BN_is_odd(b)) { + OPENSSL_PUT_ERROR(BN, BN_R_CALLED_WITH_EVEN_MODULUS); + return -2; + } + + // Require b be positive. + if (BN_is_negative(b)) { + OPENSSL_PUT_ERROR(BN, BN_R_NEGATIVE_NUMBER); + return -2; + } + + int ret = -2; + BN_CTX_start(ctx); + BIGNUM *A = BN_CTX_get(ctx); + BIGNUM *B = BN_CTX_get(ctx); + if (B == NULL) { + goto end; + } + + if (!BN_copy(A, a) || + !BN_copy(B, b)) { + goto end; + } + + // Adapted from logic to compute the Kronecker symbol, originally implemented + // according to Henri Cohen, "A Course in Computational Algebraic Number + // Theory" (algorithm 1.4.10). + + ret = 1; + + 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 + int i = 0; + while (!BN_is_bit_set(A, i)) { + i++; + } + if (!BN_rshift(A, A, i)) { + ret = -2; + 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|) + if (!BN_nnmod(B, B, A, ctx)) { + ret = -2; + goto end; + } + BIGNUM *tmp = A; + A = B; + B = tmp; + tmp->neg = 0; + } + +end: + BN_CTX_end(ctx); + return ret; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/montgomery.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/montgomery.c new file mode 100644 index 0000000..d5c209b --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/montgomery.c @@ -0,0 +1,526 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 +#include +#include +#include + +#include "internal.h" +#include "../../internal.h" + + +#if !defined(OPENSSL_NO_ASM) && \ + (defined(OPENSSL_X86) || defined(OPENSSL_X86_64) || \ + defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)) +#define OPENSSL_BN_ASM_MONT +#endif + + +BN_MONT_CTX *BN_MONT_CTX_new(void) { + BN_MONT_CTX *ret = OPENSSL_malloc(sizeof(BN_MONT_CTX)); + + if (ret == NULL) { + return NULL; + } + + OPENSSL_memset(ret, 0, sizeof(BN_MONT_CTX)); + BN_init(&ret->RR); + BN_init(&ret->N); + + return ret; +} + +void BN_MONT_CTX_free(BN_MONT_CTX *mont) { + if (mont == NULL) { + return; + } + + BN_free(&mont->RR); + BN_free(&mont->N); + OPENSSL_free(mont); +} + +BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to, const BN_MONT_CTX *from) { + if (to == from) { + return to; + } + + if (!BN_copy(&to->RR, &from->RR) || + !BN_copy(&to->N, &from->N)) { + return NULL; + } + to->n0[0] = from->n0[0]; + to->n0[1] = from->n0[1]; + return to; +} + +OPENSSL_COMPILE_ASSERT(BN_MONT_CTX_N0_LIMBS == 1 || BN_MONT_CTX_N0_LIMBS == 2, + BN_MONT_CTX_N0_LIMBS_VALUE_INVALID); +OPENSSL_COMPILE_ASSERT(sizeof(BN_ULONG) * BN_MONT_CTX_N0_LIMBS == + sizeof(uint64_t), BN_MONT_CTX_set_64_bit_mismatch); + +int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx) { + if (BN_is_zero(mod)) { + OPENSSL_PUT_ERROR(BN, BN_R_DIV_BY_ZERO); + return 0; + } + if (!BN_is_odd(mod)) { + OPENSSL_PUT_ERROR(BN, BN_R_CALLED_WITH_EVEN_MODULUS); + return 0; + } + if (BN_is_negative(mod)) { + OPENSSL_PUT_ERROR(BN, BN_R_NEGATIVE_NUMBER); + return 0; + } + + // Save the modulus. + if (!BN_copy(&mont->N, mod)) { + OPENSSL_PUT_ERROR(BN, ERR_R_INTERNAL_ERROR); + return 0; + } + // |mont->N| is always stored minimally. Computing RR efficiently leaks the + // size of the modulus. While the modulus may be private in RSA (one of the + // primes), their sizes are public, so this is fine. + bn_set_minimal_width(&mont->N); + + // Find n0 such that n0 * N == -1 (mod r). + // + // Only certain BN_BITS2<=32 platforms actually make use of n0[1]. For the + // others, we could use a shorter R value and use faster |BN_ULONG|-based + // math instead of |uint64_t|-based math, which would be double-precision. + // However, currently only the assembler files know which is which. + uint64_t n0 = bn_mont_n0(&mont->N); + mont->n0[0] = (BN_ULONG)n0; +#if BN_MONT_CTX_N0_LIMBS == 2 + mont->n0[1] = (BN_ULONG)(n0 >> BN_BITS2); +#else + mont->n0[1] = 0; +#endif + + BN_CTX *new_ctx = NULL; + if (ctx == NULL) { + new_ctx = BN_CTX_new(); + if (new_ctx == NULL) { + return 0; + } + ctx = new_ctx; + } + + // Save RR = R**2 (mod N). R is the smallest power of 2**BN_BITS2 such that R + // > mod. Even though the assembly on some 32-bit platforms works with 64-bit + // values, using |BN_BITS2| here, rather than |BN_MONT_CTX_N0_LIMBS * + // BN_BITS2|, is correct because R**2 will still be a multiple of the latter + // as |BN_MONT_CTX_N0_LIMBS| is either one or two. + unsigned lgBigR = mont->N.width * BN_BITS2; + int ok = bn_mod_exp_base_2_consttime(&mont->RR, lgBigR * 2, &mont->N, ctx); + BN_CTX_free(new_ctx); + return ok; +} + +BN_MONT_CTX *BN_MONT_CTX_new_for_modulus(const BIGNUM *mod, BN_CTX *ctx) { + BN_MONT_CTX *mont = BN_MONT_CTX_new(); + if (mont == NULL || + !BN_MONT_CTX_set(mont, mod, ctx)) { + BN_MONT_CTX_free(mont); + return NULL; + } + return mont; +} + +int BN_MONT_CTX_set_locked(BN_MONT_CTX **pmont, CRYPTO_MUTEX *lock, + const BIGNUM *mod, BN_CTX *bn_ctx) { + CRYPTO_MUTEX_lock_read(lock); + BN_MONT_CTX *ctx = *pmont; + CRYPTO_MUTEX_unlock_read(lock); + + if (ctx) { + return 1; + } + + CRYPTO_MUTEX_lock_write(lock); + if (*pmont == NULL) { + *pmont = BN_MONT_CTX_new_for_modulus(mod, bn_ctx); + } + const int ok = *pmont != NULL; + CRYPTO_MUTEX_unlock_write(lock); + return ok; +} + +int BN_to_montgomery(BIGNUM *ret, const BIGNUM *a, const BN_MONT_CTX *mont, + BN_CTX *ctx) { + return BN_mod_mul_montgomery(ret, a, &mont->RR, mont, ctx); +} + +static int bn_from_montgomery_in_place(BN_ULONG *r, size_t num_r, BN_ULONG *a, + size_t num_a, const BN_MONT_CTX *mont) { + const BN_ULONG *n = mont->N.d; + size_t num_n = mont->N.width; + if (num_r != num_n || num_a != 2 * num_n) { + OPENSSL_PUT_ERROR(BN, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 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. + BN_ULONG n0 = mont->n0[0]; + BN_ULONG carry = 0; + for (size_t i = 0; i < num_n; i++) { + BN_ULONG v = bn_mul_add_words(a + i, n, num_n, a[i] * n0); + v += carry + a[i + num_n]; + carry |= (v != a[i + num_n]); + carry &= (v <= a[i + num_n]); + a[i + num_n] = v; + } + + // Shift |num_n| words to divide by R. We have |a| < 2 * |n|. Note that |a| + // includes |carry| which is stored separately. + a += num_n; + + // |a| thus requires at most one additional subtraction |n| to be reduced. + // Subtract |n| and select the answer in constant time. + OPENSSL_COMPILE_ASSERT(sizeof(BN_ULONG) <= sizeof(crypto_word_t), + crypto_word_t_too_small); + BN_ULONG v = bn_sub_words(r, a, n, num_n) - carry; + // |v| is one if |a| - |n| underflowed or zero if it did not. Note |v| cannot + // be -1. That would imply the subtraction did not fit in |num_n| words, and + // we know at most one subtraction is needed. + v = 0u - v; + for (size_t i = 0; i < num_n; i++) { + r[i] = constant_time_select_w(v, a[i], r[i]); + a[i] = 0; + } + return 1; +} + +static int BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r, + const BN_MONT_CTX *mont) { + if (r->neg) { + OPENSSL_PUT_ERROR(BN, BN_R_NEGATIVE_NUMBER); + return 0; + } + + const BIGNUM *n = &mont->N; + if (n->width == 0) { + ret->width = 0; + return 1; + } + + int max = 2 * n->width; // carry is stored separately + if (!bn_resize_words(r, max) || + !bn_wexpand(ret, n->width)) { + return 0; + } + + ret->width = n->width; + ret->neg = 0; + return bn_from_montgomery_in_place(ret->d, ret->width, r->d, r->width, mont); +} + +int BN_from_montgomery(BIGNUM *r, const BIGNUM *a, const BN_MONT_CTX *mont, + BN_CTX *ctx) { + int ret = 0; + BIGNUM *t; + + BN_CTX_start(ctx); + t = BN_CTX_get(ctx); + if (t == NULL || + !BN_copy(t, a)) { + goto err; + } + + ret = BN_from_montgomery_word(r, t, mont); + +err: + BN_CTX_end(ctx); + + return ret; +} + +int bn_one_to_montgomery(BIGNUM *r, const BN_MONT_CTX *mont, BN_CTX *ctx) { + // If the high bit of |n| is set, R = 2^(width*BN_BITS2) < 2 * |n|, so we + // compute R - |n| rather than perform Montgomery reduction. + const BIGNUM *n = &mont->N; + if (n->width > 0 && (n->d[n->width - 1] >> (BN_BITS2 - 1)) != 0) { + if (!bn_wexpand(r, n->width)) { + return 0; + } + r->d[0] = 0 - n->d[0]; + for (int i = 1; i < n->width; i++) { + r->d[i] = ~n->d[i]; + } + r->width = n->width; + r->neg = 0; + return 1; + } + + return BN_from_montgomery(r, &mont->RR, mont, ctx); +} + +static int bn_mod_mul_montgomery_fallback(BIGNUM *r, const BIGNUM *a, + const BIGNUM *b, + const BN_MONT_CTX *mont, + BN_CTX *ctx) { + int ret = 0; + + BN_CTX_start(ctx); + BIGNUM *tmp = BN_CTX_get(ctx); + if (tmp == NULL) { + goto err; + } + + if (a == b) { + if (!bn_sqr_consttime(tmp, a, ctx)) { + goto err; + } + } else { + if (!bn_mul_consttime(tmp, a, b, ctx)) { + goto err; + } + } + + // reduce from aRR to aR + if (!BN_from_montgomery_word(r, tmp, mont)) { + goto err; + } + + ret = 1; + +err: + BN_CTX_end(ctx); + return ret; +} + +int BN_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const BN_MONT_CTX *mont, BN_CTX *ctx) { + if (a->neg || b->neg) { + OPENSSL_PUT_ERROR(BN, BN_R_NEGATIVE_NUMBER); + return 0; + } + +#if defined(OPENSSL_BN_ASM_MONT) + // |bn_mul_mont| requires at least 128 bits of limbs, at least for x86. + int num = mont->N.width; + if (num >= (128 / BN_BITS2) && + a->width == num && + b->width == num) { + if (!bn_wexpand(r, num)) { + return 0; + } + if (!bn_mul_mont(r->d, a->d, b->d, mont->N.d, mont->n0, num)) { + // The check above ensures this won't happen. + assert(0); + OPENSSL_PUT_ERROR(BN, ERR_R_INTERNAL_ERROR); + return 0; + } + r->neg = 0; + r->width = num; + return 1; + } +#endif + + return bn_mod_mul_montgomery_fallback(r, a, b, mont, ctx); +} + +int bn_less_than_montgomery_R(const BIGNUM *bn, const BN_MONT_CTX *mont) { + return !BN_is_negative(bn) && + bn_fits_in_words(bn, mont->N.width); +} + +int bn_to_montgomery_small(BN_ULONG *r, size_t num_r, const BN_ULONG *a, + size_t num_a, const BN_MONT_CTX *mont) { + return bn_mod_mul_montgomery_small(r, num_r, a, num_a, mont->RR.d, + mont->RR.width, mont); +} + +int bn_from_montgomery_small(BN_ULONG *r, size_t num_r, const BN_ULONG *a, + size_t num_a, const BN_MONT_CTX *mont) { + size_t num_n = mont->N.width; + if (num_a > 2 * num_n || num_r != num_n || num_n > BN_SMALL_MAX_WORDS) { + OPENSSL_PUT_ERROR(BN, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + BN_ULONG tmp[BN_SMALL_MAX_WORDS * 2]; + size_t num_tmp = 2 * num_n; + OPENSSL_memcpy(tmp, a, num_a * sizeof(BN_ULONG)); + OPENSSL_memset(tmp + num_a, 0, (num_tmp - num_a) * sizeof(BN_ULONG)); + int ret = bn_from_montgomery_in_place(r, num_r, tmp, num_tmp, mont); + OPENSSL_cleanse(tmp, num_tmp * sizeof(BN_ULONG)); + return ret; +} + +int bn_one_to_montgomery_small(BN_ULONG *r, size_t num_r, + const BN_MONT_CTX *mont) { + const BN_ULONG *n = mont->N.d; + size_t num_n = mont->N.width; + if (num_n == 0 || num_r != num_n) { + OPENSSL_PUT_ERROR(BN, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + + // If the high bit of |n| is set, R = 2^(num_n*BN_BITS2) < 2 * |n|, so we + // compute R - |n| rather than perform Montgomery reduction. + if (num_n > 0 && (n[num_n - 1] >> (BN_BITS2 - 1)) != 0) { + r[0] = 0 - n[0]; + for (size_t i = 1; i < num_n; i++) { + r[i] = ~n[i]; + } + return 1; + } + + return bn_from_montgomery_small(r, num_r, mont->RR.d, mont->RR.width, mont); +} + +int bn_mod_mul_montgomery_small(BN_ULONG *r, size_t num_r, const BN_ULONG *a, + size_t num_a, const BN_ULONG *b, size_t num_b, + const BN_MONT_CTX *mont) { + size_t num_n = mont->N.width; + if (num_r != num_n || num_a + num_b > 2 * num_n || + num_n > BN_SMALL_MAX_WORDS) { + OPENSSL_PUT_ERROR(BN, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + +#if defined(OPENSSL_BN_ASM_MONT) + // |bn_mul_mont| requires at least 128 bits of limbs, at least for x86. + if (num_n >= (128 / BN_BITS2) && + num_a == num_n && + num_b == num_n) { + if (!bn_mul_mont(r, a, b, mont->N.d, mont->n0, num_n)) { + assert(0); // The check above ensures this won't happen. + OPENSSL_PUT_ERROR(BN, ERR_R_INTERNAL_ERROR); + return 0; + } + return 1; + } +#endif + + // Compute the product. + BN_ULONG tmp[2 * BN_SMALL_MAX_WORDS]; + size_t num_tmp = 2 * num_n; + size_t num_ab = num_a + num_b; + if (a == b && num_a == num_b) { + if (!bn_sqr_small(tmp, num_ab, a, num_a)) { + return 0; + } + } else if (!bn_mul_small(tmp, num_ab, a, num_a, b, num_b)) { + return 0; + } + + // Zero-extend to full width and reduce. + OPENSSL_memset(tmp + num_ab, 0, (num_tmp - num_ab) * sizeof(BN_ULONG)); + int ret = bn_from_montgomery_in_place(r, num_r, tmp, num_tmp, mont); + OPENSSL_cleanse(tmp, num_tmp * sizeof(BN_ULONG)); + return ret; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/montgomery.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/montgomery.c.grpc_back new file mode 100644 index 0000000..d6e2ad5 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/montgomery.c.grpc_back @@ -0,0 +1,526 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 +#include +#include +#include + +#include "internal.h" +#include "../../internal.h" + + +#if !defined(OPENSSL_NO_ASM) && \ + (defined(OPENSSL_X86) || defined(OPENSSL_X86_64) || \ + defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)) +#define OPENSSL_BN_ASM_MONT +#endif + + +BN_MONT_CTX *BN_MONT_CTX_new(void) { + BN_MONT_CTX *ret = OPENSSL_malloc(sizeof(BN_MONT_CTX)); + + if (ret == NULL) { + return NULL; + } + + OPENSSL_memset(ret, 0, sizeof(BN_MONT_CTX)); + BN_init(&ret->RR); + BN_init(&ret->N); + + return ret; +} + +void BN_MONT_CTX_free(BN_MONT_CTX *mont) { + if (mont == NULL) { + return; + } + + BN_free(&mont->RR); + BN_free(&mont->N); + OPENSSL_free(mont); +} + +BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to, const BN_MONT_CTX *from) { + if (to == from) { + return to; + } + + if (!BN_copy(&to->RR, &from->RR) || + !BN_copy(&to->N, &from->N)) { + return NULL; + } + to->n0[0] = from->n0[0]; + to->n0[1] = from->n0[1]; + return to; +} + +OPENSSL_COMPILE_ASSERT(BN_MONT_CTX_N0_LIMBS == 1 || BN_MONT_CTX_N0_LIMBS == 2, + BN_MONT_CTX_N0_LIMBS_VALUE_INVALID); +OPENSSL_COMPILE_ASSERT(sizeof(BN_ULONG) * BN_MONT_CTX_N0_LIMBS == + sizeof(uint64_t), BN_MONT_CTX_set_64_bit_mismatch); + +int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, BN_CTX *ctx) { + if (BN_is_zero(mod)) { + OPENSSL_PUT_ERROR(BN, BN_R_DIV_BY_ZERO); + return 0; + } + if (!BN_is_odd(mod)) { + OPENSSL_PUT_ERROR(BN, BN_R_CALLED_WITH_EVEN_MODULUS); + return 0; + } + if (BN_is_negative(mod)) { + OPENSSL_PUT_ERROR(BN, BN_R_NEGATIVE_NUMBER); + return 0; + } + + // Save the modulus. + if (!BN_copy(&mont->N, mod)) { + OPENSSL_PUT_ERROR(BN, ERR_R_INTERNAL_ERROR); + return 0; + } + // |mont->N| is always stored minimally. Computing RR efficiently leaks the + // size of the modulus. While the modulus may be private in RSA (one of the + // primes), their sizes are public, so this is fine. + bn_set_minimal_width(&mont->N); + + // Find n0 such that n0 * N == -1 (mod r). + // + // Only certain BN_BITS2<=32 platforms actually make use of n0[1]. For the + // others, we could use a shorter R value and use faster |BN_ULONG|-based + // math instead of |uint64_t|-based math, which would be double-precision. + // However, currently only the assembler files know which is which. + uint64_t n0 = bn_mont_n0(&mont->N); + mont->n0[0] = (BN_ULONG)n0; +#if BN_MONT_CTX_N0_LIMBS == 2 + mont->n0[1] = (BN_ULONG)(n0 >> BN_BITS2); +#else + mont->n0[1] = 0; +#endif + + BN_CTX *new_ctx = NULL; + if (ctx == NULL) { + new_ctx = BN_CTX_new(); + if (new_ctx == NULL) { + return 0; + } + ctx = new_ctx; + } + + // Save RR = R**2 (mod N). R is the smallest power of 2**BN_BITS2 such that R + // > mod. Even though the assembly on some 32-bit platforms works with 64-bit + // values, using |BN_BITS2| here, rather than |BN_MONT_CTX_N0_LIMBS * + // BN_BITS2|, is correct because R**2 will still be a multiple of the latter + // as |BN_MONT_CTX_N0_LIMBS| is either one or two. + unsigned lgBigR = mont->N.width * BN_BITS2; + int ok = bn_mod_exp_base_2_consttime(&mont->RR, lgBigR * 2, &mont->N, ctx); + BN_CTX_free(new_ctx); + return ok; +} + +BN_MONT_CTX *BN_MONT_CTX_new_for_modulus(const BIGNUM *mod, BN_CTX *ctx) { + BN_MONT_CTX *mont = BN_MONT_CTX_new(); + if (mont == NULL || + !BN_MONT_CTX_set(mont, mod, ctx)) { + BN_MONT_CTX_free(mont); + return NULL; + } + return mont; +} + +int BN_MONT_CTX_set_locked(BN_MONT_CTX **pmont, CRYPTO_MUTEX *lock, + const BIGNUM *mod, BN_CTX *bn_ctx) { + CRYPTO_MUTEX_lock_read(lock); + BN_MONT_CTX *ctx = *pmont; + CRYPTO_MUTEX_unlock_read(lock); + + if (ctx) { + return 1; + } + + CRYPTO_MUTEX_lock_write(lock); + if (*pmont == NULL) { + *pmont = BN_MONT_CTX_new_for_modulus(mod, bn_ctx); + } + const int ok = *pmont != NULL; + CRYPTO_MUTEX_unlock_write(lock); + return ok; +} + +int BN_to_montgomery(BIGNUM *ret, const BIGNUM *a, const BN_MONT_CTX *mont, + BN_CTX *ctx) { + return BN_mod_mul_montgomery(ret, a, &mont->RR, mont, ctx); +} + +static int bn_from_montgomery_in_place(BN_ULONG *r, size_t num_r, BN_ULONG *a, + size_t num_a, const BN_MONT_CTX *mont) { + const BN_ULONG *n = mont->N.d; + size_t num_n = mont->N.width; + if (num_r != num_n || num_a != 2 * num_n) { + OPENSSL_PUT_ERROR(BN, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 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. + BN_ULONG n0 = mont->n0[0]; + BN_ULONG carry = 0; + for (size_t i = 0; i < num_n; i++) { + BN_ULONG v = bn_mul_add_words(a + i, n, num_n, a[i] * n0); + v += carry + a[i + num_n]; + carry |= (v != a[i + num_n]); + carry &= (v <= a[i + num_n]); + a[i + num_n] = v; + } + + // Shift |num_n| words to divide by R. We have |a| < 2 * |n|. Note that |a| + // includes |carry| which is stored separately. + a += num_n; + + // |a| thus requires at most one additional subtraction |n| to be reduced. + // Subtract |n| and select the answer in constant time. + OPENSSL_COMPILE_ASSERT(sizeof(BN_ULONG) <= sizeof(crypto_word_t), + crypto_word_t_too_small); + BN_ULONG v = bn_sub_words(r, a, n, num_n) - carry; + // |v| is one if |a| - |n| underflowed or zero if it did not. Note |v| cannot + // be -1. That would imply the subtraction did not fit in |num_n| words, and + // we know at most one subtraction is needed. + v = 0u - v; + for (size_t i = 0; i < num_n; i++) { + r[i] = constant_time_select_w(v, a[i], r[i]); + a[i] = 0; + } + return 1; +} + +static int BN_from_montgomery_word(BIGNUM *ret, BIGNUM *r, + const BN_MONT_CTX *mont) { + if (r->neg) { + OPENSSL_PUT_ERROR(BN, BN_R_NEGATIVE_NUMBER); + return 0; + } + + const BIGNUM *n = &mont->N; + if (n->width == 0) { + ret->width = 0; + return 1; + } + + int max = 2 * n->width; // carry is stored separately + if (!bn_resize_words(r, max) || + !bn_wexpand(ret, n->width)) { + return 0; + } + + ret->width = n->width; + ret->neg = 0; + return bn_from_montgomery_in_place(ret->d, ret->width, r->d, r->width, mont); +} + +int BN_from_montgomery(BIGNUM *r, const BIGNUM *a, const BN_MONT_CTX *mont, + BN_CTX *ctx) { + int ret = 0; + BIGNUM *t; + + BN_CTX_start(ctx); + t = BN_CTX_get(ctx); + if (t == NULL || + !BN_copy(t, a)) { + goto err; + } + + ret = BN_from_montgomery_word(r, t, mont); + +err: + BN_CTX_end(ctx); + + return ret; +} + +int bn_one_to_montgomery(BIGNUM *r, const BN_MONT_CTX *mont, BN_CTX *ctx) { + // If the high bit of |n| is set, R = 2^(width*BN_BITS2) < 2 * |n|, so we + // compute R - |n| rather than perform Montgomery reduction. + const BIGNUM *n = &mont->N; + if (n->width > 0 && (n->d[n->width - 1] >> (BN_BITS2 - 1)) != 0) { + if (!bn_wexpand(r, n->width)) { + return 0; + } + r->d[0] = 0 - n->d[0]; + for (int i = 1; i < n->width; i++) { + r->d[i] = ~n->d[i]; + } + r->width = n->width; + r->neg = 0; + return 1; + } + + return BN_from_montgomery(r, &mont->RR, mont, ctx); +} + +static int bn_mod_mul_montgomery_fallback(BIGNUM *r, const BIGNUM *a, + const BIGNUM *b, + const BN_MONT_CTX *mont, + BN_CTX *ctx) { + int ret = 0; + + BN_CTX_start(ctx); + BIGNUM *tmp = BN_CTX_get(ctx); + if (tmp == NULL) { + goto err; + } + + if (a == b) { + if (!bn_sqr_consttime(tmp, a, ctx)) { + goto err; + } + } else { + if (!bn_mul_consttime(tmp, a, b, ctx)) { + goto err; + } + } + + // reduce from aRR to aR + if (!BN_from_montgomery_word(r, tmp, mont)) { + goto err; + } + + ret = 1; + +err: + BN_CTX_end(ctx); + return ret; +} + +int BN_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const BN_MONT_CTX *mont, BN_CTX *ctx) { + if (a->neg || b->neg) { + OPENSSL_PUT_ERROR(BN, BN_R_NEGATIVE_NUMBER); + return 0; + } + +#if defined(OPENSSL_BN_ASM_MONT) + // |bn_mul_mont| requires at least 128 bits of limbs, at least for x86. + int num = mont->N.width; + if (num >= (128 / BN_BITS2) && + a->width == num && + b->width == num) { + if (!bn_wexpand(r, num)) { + return 0; + } + if (!bn_mul_mont(r->d, a->d, b->d, mont->N.d, mont->n0, num)) { + // The check above ensures this won't happen. + assert(0); + OPENSSL_PUT_ERROR(BN, ERR_R_INTERNAL_ERROR); + return 0; + } + r->neg = 0; + r->width = num; + return 1; + } +#endif + + return bn_mod_mul_montgomery_fallback(r, a, b, mont, ctx); +} + +int bn_less_than_montgomery_R(const BIGNUM *bn, const BN_MONT_CTX *mont) { + return !BN_is_negative(bn) && + bn_fits_in_words(bn, mont->N.width); +} + +int bn_to_montgomery_small(BN_ULONG *r, size_t num_r, const BN_ULONG *a, + size_t num_a, const BN_MONT_CTX *mont) { + return bn_mod_mul_montgomery_small(r, num_r, a, num_a, mont->RR.d, + mont->RR.width, mont); +} + +int bn_from_montgomery_small(BN_ULONG *r, size_t num_r, const BN_ULONG *a, + size_t num_a, const BN_MONT_CTX *mont) { + size_t num_n = mont->N.width; + if (num_a > 2 * num_n || num_r != num_n || num_n > BN_SMALL_MAX_WORDS) { + OPENSSL_PUT_ERROR(BN, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + BN_ULONG tmp[BN_SMALL_MAX_WORDS * 2]; + size_t num_tmp = 2 * num_n; + OPENSSL_memcpy(tmp, a, num_a * sizeof(BN_ULONG)); + OPENSSL_memset(tmp + num_a, 0, (num_tmp - num_a) * sizeof(BN_ULONG)); + int ret = bn_from_montgomery_in_place(r, num_r, tmp, num_tmp, mont); + OPENSSL_cleanse(tmp, num_tmp * sizeof(BN_ULONG)); + return ret; +} + +int bn_one_to_montgomery_small(BN_ULONG *r, size_t num_r, + const BN_MONT_CTX *mont) { + const BN_ULONG *n = mont->N.d; + size_t num_n = mont->N.width; + if (num_n == 0 || num_r != num_n) { + OPENSSL_PUT_ERROR(BN, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + + // If the high bit of |n| is set, R = 2^(num_n*BN_BITS2) < 2 * |n|, so we + // compute R - |n| rather than perform Montgomery reduction. + if (num_n > 0 && (n[num_n - 1] >> (BN_BITS2 - 1)) != 0) { + r[0] = 0 - n[0]; + for (size_t i = 1; i < num_n; i++) { + r[i] = ~n[i]; + } + return 1; + } + + return bn_from_montgomery_small(r, num_r, mont->RR.d, mont->RR.width, mont); +} + +int bn_mod_mul_montgomery_small(BN_ULONG *r, size_t num_r, const BN_ULONG *a, + size_t num_a, const BN_ULONG *b, size_t num_b, + const BN_MONT_CTX *mont) { + size_t num_n = mont->N.width; + if (num_r != num_n || num_a + num_b > 2 * num_n || + num_n > BN_SMALL_MAX_WORDS) { + OPENSSL_PUT_ERROR(BN, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + +#if defined(OPENSSL_BN_ASM_MONT) + // |bn_mul_mont| requires at least 128 bits of limbs, at least for x86. + if (num_n >= (128 / BN_BITS2) && + num_a == num_n && + num_b == num_n) { + if (!bn_mul_mont(r, a, b, mont->N.d, mont->n0, num_n)) { + assert(0); // The check above ensures this won't happen. + OPENSSL_PUT_ERROR(BN, ERR_R_INTERNAL_ERROR); + return 0; + } + return 1; + } +#endif + + // Compute the product. + BN_ULONG tmp[2 * BN_SMALL_MAX_WORDS]; + size_t num_tmp = 2 * num_n; + size_t num_ab = num_a + num_b; + if (a == b && num_a == num_b) { + if (!bn_sqr_small(tmp, num_ab, a, num_a)) { + return 0; + } + } else if (!bn_mul_small(tmp, num_ab, a, num_a, b, num_b)) { + return 0; + } + + // Zero-extend to full width and reduce. + OPENSSL_memset(tmp + num_ab, 0, (num_tmp - num_ab) * sizeof(BN_ULONG)); + int ret = bn_from_montgomery_in_place(r, num_r, tmp, num_tmp, mont); + OPENSSL_cleanse(tmp, num_tmp * sizeof(BN_ULONG)); + return ret; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/montgomery_inv.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/montgomery_inv.c new file mode 100644 index 0000000..6489a9b --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/montgomery_inv.c @@ -0,0 +1,185 @@ +/* Copyright 2016 Brian Smith. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include + +#include "internal.h" +#include "../../internal.h" + + +static uint64_t bn_neg_inv_mod_r_u64(uint64_t n); + +OPENSSL_COMPILE_ASSERT(BN_MONT_CTX_N0_LIMBS == 1 || BN_MONT_CTX_N0_LIMBS == 2, + BN_MONT_CTX_N0_LIMBS_VALUE_INVALID_2); +OPENSSL_COMPILE_ASSERT(sizeof(uint64_t) == + BN_MONT_CTX_N0_LIMBS * sizeof(BN_ULONG), + BN_MONT_CTX_N0_LIMBS_DOES_NOT_MATCH_UINT64_T); + +// LG_LITTLE_R is log_2(r). +#define LG_LITTLE_R (BN_MONT_CTX_N0_LIMBS * BN_BITS2) + +uint64_t bn_mont_n0(const BIGNUM *n) { + // These conditions are checked by the caller, |BN_MONT_CTX_set|. + assert(!BN_is_zero(n)); + assert(!BN_is_negative(n)); + assert(BN_is_odd(n)); + + // r == 2**(BN_MONT_CTX_N0_LIMBS * BN_BITS2) and LG_LITTLE_R == lg(r). This + // ensures that we can do integer division by |r| by simply ignoring + // |BN_MONT_CTX_N0_LIMBS| limbs. Similarly, we can calculate values modulo + // |r| by just looking at the lowest |BN_MONT_CTX_N0_LIMBS| limbs. This is + // what makes Montgomery multiplication efficient. + // + // As shown in Algorithm 1 of "Fast Prime Field Elliptic Curve Cryptography + // with 256 Bit Primes" by Shay Gueron and Vlad Krasnov, in the loop of a + // multi-limb Montgomery multiplication of |a * b (mod n)|, given the + // unreduced product |t == a * b|, we repeatedly calculate: + // + // t1 := t % r |t1| is |t|'s lowest limb (see previous paragraph). + // t2 := t1*n0*n + // t3 := t + t2 + // t := t3 / r copy all limbs of |t3| except the lowest to |t|. + // + // In the last step, it would only make sense to ignore the lowest limb of + // |t3| if it were zero. The middle steps ensure that this is the case: + // + // t3 == 0 (mod r) + // t + t2 == 0 (mod r) + // t + t1*n0*n == 0 (mod r) + // t1*n0*n == -t (mod r) + // t*n0*n == -t (mod r) + // n0*n == -1 (mod r) + // n0 == -1/n (mod r) + // + // Thus, in each iteration of the loop, we multiply by the constant factor + // |n0|, the negative inverse of n (mod r). + + // n_mod_r = n % r. As explained above, this is done by taking the lowest + // |BN_MONT_CTX_N0_LIMBS| limbs of |n|. + uint64_t n_mod_r = n->d[0]; +#if BN_MONT_CTX_N0_LIMBS == 2 + if (n->width > 1) { + n_mod_r |= (uint64_t)n->d[1] << BN_BITS2; + } +#endif + + return bn_neg_inv_mod_r_u64(n_mod_r); +} + +// bn_neg_inv_r_mod_n_u64 calculates the -1/n mod r; i.e. it calculates |v| +// such that u*r - v*n == 1. |r| is the constant defined in |bn_mont_n0|. |n| +// must be odd. +// +// This is derived from |xbinGCD| in Henry S. Warren, Jr.'s "Montgomery +// Multiplication" (http://www.hackersdelight.org/MontgomeryMultiplication.pdf). +// It is very similar to the MODULAR-INVERSE function in Stephen R. Dussé's and +// Burton S. Kaliski Jr.'s "A Cryptographic Library for the Motorola DSP56000" +// (http://link.springer.com/chapter/10.1007%2F3-540-46877-3_21). +// +// This is inspired by Joppe W. Bos's "Constant Time Modular Inversion" +// (http://www.joppebos.com/files/CTInversion.pdf) so that the inversion is +// constant-time with respect to |n|. We assume uint64_t additions, +// subtractions, shifts, and bitwise operations are all constant time, which +// may be a large leap of faith on 32-bit targets. We avoid division and +// multiplication, which tend to be the most problematic in terms of timing +// leaks. +// +// Most GCD implementations return values such that |u*r + v*n == 1|, so the +// caller would have to negate the resultant |v| for the purpose of Montgomery +// multiplication. This implementation does the negation implicitly by doing +// the computations as a difference instead of a sum. +static uint64_t bn_neg_inv_mod_r_u64(uint64_t n) { + assert(n % 2 == 1); + + // alpha == 2**(lg r - 1) == r / 2. + static const uint64_t alpha = UINT64_C(1) << (LG_LITTLE_R - 1); + + const uint64_t beta = n; + + uint64_t u = 1; + uint64_t v = 0; + + // The invariant maintained from here on is: + // 2**(lg r - i) == u*2*alpha - v*beta. + for (size_t i = 0; i < LG_LITTLE_R; ++i) { +#if BN_BITS2 == 64 && defined(BN_ULLONG) + assert((BN_ULLONG)(1) << (LG_LITTLE_R - i) == + ((BN_ULLONG)u * 2 * alpha) - ((BN_ULLONG)v * beta)); +#endif + + // Delete a common factor of 2 in u and v if |u| is even. Otherwise, set + // |u = (u + beta) / 2| and |v = (v / 2) + alpha|. + + uint64_t u_is_odd = UINT64_C(0) - (u & 1); // Either 0xff..ff or 0. + + // The addition can overflow, so use Dietz's method for it. + // + // Dietz calculates (x+y)/2 by (x⊕y)>>1 + x&y. This is valid for all + // (unsigned) x and y, even when x+y overflows. Evidence for 32-bit values + // (embedded in 64 bits to so that overflow can be ignored): + // + // (declare-fun x () (_ BitVec 64)) + // (declare-fun y () (_ BitVec 64)) + // (assert (let ( + // (one (_ bv1 64)) + // (thirtyTwo (_ bv32 64))) + // (and + // (bvult x (bvshl one thirtyTwo)) + // (bvult y (bvshl one thirtyTwo)) + // (not (= + // (bvadd (bvlshr (bvxor x y) one) (bvand x y)) + // (bvlshr (bvadd x y) one))) + // ))) + // (check-sat) + uint64_t beta_if_u_is_odd = beta & u_is_odd; // Either |beta| or 0. + u = ((u ^ beta_if_u_is_odd) >> 1) + (u & beta_if_u_is_odd); + + uint64_t alpha_if_u_is_odd = alpha & u_is_odd; // Either |alpha| or 0. + v = (v >> 1) + alpha_if_u_is_odd; + } + + // The invariant now shows that u*r - v*n == 1 since r == 2 * alpha. +#if BN_BITS2 == 64 && defined(BN_ULLONG) + assert(1 == ((BN_ULLONG)u * 2 * alpha) - ((BN_ULLONG)v * beta)); +#endif + + return v; +} + +int bn_mod_exp_base_2_consttime(BIGNUM *r, unsigned p, const BIGNUM *n, + BN_CTX *ctx) { + assert(!BN_is_zero(n)); + assert(!BN_is_negative(n)); + assert(BN_is_odd(n)); + + BN_zero(r); + + unsigned n_bits = BN_num_bits(n); + assert(n_bits != 0); + assert(p > n_bits); + if (n_bits == 1) { + return 1; + } + + // Set |r| to the larger power of two smaller than |n|, then shift with + // reductions the rest of the way. + if (!BN_set_bit(r, n_bits - 1) || + !bn_mod_lshift_consttime(r, r, p - (n_bits - 1), n, ctx)) { + return 0; + } + + return 1; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/montgomery_inv.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/montgomery_inv.c.grpc_back new file mode 100644 index 0000000..a920ca4 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/montgomery_inv.c.grpc_back @@ -0,0 +1,185 @@ +/* Copyright 2016 Brian Smith. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include + +#include "internal.h" +#include "../../internal.h" + + +static uint64_t bn_neg_inv_mod_r_u64(uint64_t n); + +OPENSSL_COMPILE_ASSERT(BN_MONT_CTX_N0_LIMBS == 1 || BN_MONT_CTX_N0_LIMBS == 2, + BN_MONT_CTX_N0_LIMBS_VALUE_INVALID_2); +OPENSSL_COMPILE_ASSERT(sizeof(uint64_t) == + BN_MONT_CTX_N0_LIMBS * sizeof(BN_ULONG), + BN_MONT_CTX_N0_LIMBS_DOES_NOT_MATCH_UINT64_T); + +// LG_LITTLE_R is log_2(r). +#define LG_LITTLE_R (BN_MONT_CTX_N0_LIMBS * BN_BITS2) + +uint64_t bn_mont_n0(const BIGNUM *n) { + // These conditions are checked by the caller, |BN_MONT_CTX_set|. + assert(!BN_is_zero(n)); + assert(!BN_is_negative(n)); + assert(BN_is_odd(n)); + + // r == 2**(BN_MONT_CTX_N0_LIMBS * BN_BITS2) and LG_LITTLE_R == lg(r). This + // ensures that we can do integer division by |r| by simply ignoring + // |BN_MONT_CTX_N0_LIMBS| limbs. Similarly, we can calculate values modulo + // |r| by just looking at the lowest |BN_MONT_CTX_N0_LIMBS| limbs. This is + // what makes Montgomery multiplication efficient. + // + // As shown in Algorithm 1 of "Fast Prime Field Elliptic Curve Cryptography + // with 256 Bit Primes" by Shay Gueron and Vlad Krasnov, in the loop of a + // multi-limb Montgomery multiplication of |a * b (mod n)|, given the + // unreduced product |t == a * b|, we repeatedly calculate: + // + // t1 := t % r |t1| is |t|'s lowest limb (see previous paragraph). + // t2 := t1*n0*n + // t3 := t + t2 + // t := t3 / r copy all limbs of |t3| except the lowest to |t|. + // + // In the last step, it would only make sense to ignore the lowest limb of + // |t3| if it were zero. The middle steps ensure that this is the case: + // + // t3 == 0 (mod r) + // t + t2 == 0 (mod r) + // t + t1*n0*n == 0 (mod r) + // t1*n0*n == -t (mod r) + // t*n0*n == -t (mod r) + // n0*n == -1 (mod r) + // n0 == -1/n (mod r) + // + // Thus, in each iteration of the loop, we multiply by the constant factor + // |n0|, the negative inverse of n (mod r). + + // n_mod_r = n % r. As explained above, this is done by taking the lowest + // |BN_MONT_CTX_N0_LIMBS| limbs of |n|. + uint64_t n_mod_r = n->d[0]; +#if BN_MONT_CTX_N0_LIMBS == 2 + if (n->width > 1) { + n_mod_r |= (uint64_t)n->d[1] << BN_BITS2; + } +#endif + + return bn_neg_inv_mod_r_u64(n_mod_r); +} + +// bn_neg_inv_r_mod_n_u64 calculates the -1/n mod r; i.e. it calculates |v| +// such that u*r - v*n == 1. |r| is the constant defined in |bn_mont_n0|. |n| +// must be odd. +// +// This is derived from |xbinGCD| in Henry S. Warren, Jr.'s "Montgomery +// Multiplication" (http://www.hackersdelight.org/MontgomeryMultiplication.pdf). +// It is very similar to the MODULAR-INVERSE function in Stephen R. Dussé's and +// Burton S. Kaliski Jr.'s "A Cryptographic Library for the Motorola DSP56000" +// (http://link.springer.com/chapter/10.1007%2F3-540-46877-3_21). +// +// This is inspired by Joppe W. Bos's "Constant Time Modular Inversion" +// (http://www.joppebos.com/files/CTInversion.pdf) so that the inversion is +// constant-time with respect to |n|. We assume uint64_t additions, +// subtractions, shifts, and bitwise operations are all constant time, which +// may be a large leap of faith on 32-bit targets. We avoid division and +// multiplication, which tend to be the most problematic in terms of timing +// leaks. +// +// Most GCD implementations return values such that |u*r + v*n == 1|, so the +// caller would have to negate the resultant |v| for the purpose of Montgomery +// multiplication. This implementation does the negation implicitly by doing +// the computations as a difference instead of a sum. +static uint64_t bn_neg_inv_mod_r_u64(uint64_t n) { + assert(n % 2 == 1); + + // alpha == 2**(lg r - 1) == r / 2. + static const uint64_t alpha = UINT64_C(1) << (LG_LITTLE_R - 1); + + const uint64_t beta = n; + + uint64_t u = 1; + uint64_t v = 0; + + // The invariant maintained from here on is: + // 2**(lg r - i) == u*2*alpha - v*beta. + for (size_t i = 0; i < LG_LITTLE_R; ++i) { +#if BN_BITS2 == 64 && defined(BN_ULLONG) + assert((BN_ULLONG)(1) << (LG_LITTLE_R - i) == + ((BN_ULLONG)u * 2 * alpha) - ((BN_ULLONG)v * beta)); +#endif + + // Delete a common factor of 2 in u and v if |u| is even. Otherwise, set + // |u = (u + beta) / 2| and |v = (v / 2) + alpha|. + + uint64_t u_is_odd = UINT64_C(0) - (u & 1); // Either 0xff..ff or 0. + + // The addition can overflow, so use Dietz's method for it. + // + // Dietz calculates (x+y)/2 by (x⊕y)>>1 + x&y. This is valid for all + // (unsigned) x and y, even when x+y overflows. Evidence for 32-bit values + // (embedded in 64 bits to so that overflow can be ignored): + // + // (declare-fun x () (_ BitVec 64)) + // (declare-fun y () (_ BitVec 64)) + // (assert (let ( + // (one (_ bv1 64)) + // (thirtyTwo (_ bv32 64))) + // (and + // (bvult x (bvshl one thirtyTwo)) + // (bvult y (bvshl one thirtyTwo)) + // (not (= + // (bvadd (bvlshr (bvxor x y) one) (bvand x y)) + // (bvlshr (bvadd x y) one))) + // ))) + // (check-sat) + uint64_t beta_if_u_is_odd = beta & u_is_odd; // Either |beta| or 0. + u = ((u ^ beta_if_u_is_odd) >> 1) + (u & beta_if_u_is_odd); + + uint64_t alpha_if_u_is_odd = alpha & u_is_odd; // Either |alpha| or 0. + v = (v >> 1) + alpha_if_u_is_odd; + } + + // The invariant now shows that u*r - v*n == 1 since r == 2 * alpha. +#if BN_BITS2 == 64 && defined(BN_ULLONG) + assert(1 == ((BN_ULLONG)u * 2 * alpha) - ((BN_ULLONG)v * beta)); +#endif + + return v; +} + +int bn_mod_exp_base_2_consttime(BIGNUM *r, unsigned p, const BIGNUM *n, + BN_CTX *ctx) { + assert(!BN_is_zero(n)); + assert(!BN_is_negative(n)); + assert(BN_is_odd(n)); + + BN_zero(r); + + unsigned n_bits = BN_num_bits(n); + assert(n_bits != 0); + assert(p > n_bits); + if (n_bits == 1) { + return 1; + } + + // Set |r| to the larger power of two smaller than |n|, then shift with + // reductions the rest of the way. + if (!BN_set_bit(r, n_bits - 1) || + !bn_mod_lshift_consttime(r, r, p - (n_bits - 1), n, ctx)) { + return 0; + } + + return 1; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/mul.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/mul.c new file mode 100644 index 0000000..e9610da --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/mul.c @@ -0,0 +1,876 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 +#include + +#include "internal.h" +#include "../../internal.h" + + +#define BN_MUL_RECURSIVE_SIZE_NORMAL 16 +#define BN_SQR_RECURSIVE_SIZE_NORMAL BN_MUL_RECURSIVE_SIZE_NORMAL + + +static void bn_abs_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, + size_t num, BN_ULONG *tmp) { + BN_ULONG borrow = bn_sub_words(tmp, a, b, num); + bn_sub_words(r, b, a, num); + bn_select_words(r, 0 - borrow, r /* tmp < 0 */, tmp /* tmp >= 0 */, num); +} + +static void bn_mul_normal(BN_ULONG *r, const BN_ULONG *a, size_t na, + const BN_ULONG *b, size_t nb) { + if (na < nb) { + size_t itmp = na; + na = nb; + nb = itmp; + const BN_ULONG *ltmp = a; + a = b; + b = ltmp; + } + BN_ULONG *rr = &(r[na]); + if (nb == 0) { + OPENSSL_memset(r, 0, na * sizeof(BN_ULONG)); + return; + } + 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; + } +} + +#if !defined(OPENSSL_X86) || defined(OPENSSL_NO_ASM) +// 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. + +static 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) { + for (;;) { + t = b[0]; + r[0] = 0 - t - c; + if (t != 0) { + c = 1; + } + if (++dl >= 0) { + break; + } + + t = b[1]; + r[1] = 0 - t - c; + if (t != 0) { + c = 1; + } + if (++dl >= 0) { + break; + } + + t = b[2]; + r[2] = 0 - t - c; + if (t != 0) { + c = 1; + } + if (++dl >= 0) { + break; + } + + t = b[3]; + r[3] = 0 - t - c; + if (t != 0) { + c = 1; + } + if (++dl >= 0) { + break; + } + + b += 4; + r += 4; + } + } else { + int save_dl = dl; + while (c) { + t = a[0]; + r[0] = t - c; + if (t != 0) { + c = 0; + } + if (--dl <= 0) { + break; + } + + t = a[1]; + r[1] = t - c; + if (t != 0) { + c = 0; + } + if (--dl <= 0) { + break; + } + + t = a[2]; + r[2] = t - c; + if (t != 0) { + c = 0; + } + if (--dl <= 0) { + break; + } + + t = a[3]; + r[3] = t - c; + if (t != 0) { + c = 0; + } + if (--dl <= 0) { + break; + } + + save_dl = dl; + a += 4; + r += 4; + } + if (dl > 0) { + if (save_dl > dl) { + switch (save_dl - dl) { + case 1: + r[1] = a[1]; + if (--dl <= 0) { + break; + } + OPENSSL_FALLTHROUGH; + case 2: + r[2] = a[2]; + if (--dl <= 0) { + break; + } + OPENSSL_FALLTHROUGH; + case 3: + r[3] = a[3]; + if (--dl <= 0) { + break; + } + } + a += 4; + r += 4; + } + } + + if (dl > 0) { + 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; +} +#else +// On other platforms the function is defined in asm. +BN_ULONG bn_sub_part_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, + int cl, int dl); +#endif + +// bn_abs_sub_part_words computes |r| = |a| - |b|, storing the absolute value +// and returning a mask of all ones if the result was negative and all zeros if +// the result was positive. |cl| and |dl| follow the |bn_sub_part_words| calling +// convention. +// +// TODO(davidben): Make this take |size_t|. The |cl| + |dl| calling convention +// is confusing. The trouble is 32-bit x86 implements |bn_sub_part_words| in +// assembly, but we can probably just delete it? +static BN_ULONG bn_abs_sub_part_words(BN_ULONG *r, const BN_ULONG *a, + const BN_ULONG *b, int cl, int dl, + BN_ULONG *tmp) { + BN_ULONG borrow = bn_sub_part_words(tmp, a, b, cl, dl); + bn_sub_part_words(r, b, a, cl, -dl); + int r_len = cl + (dl < 0 ? -dl : dl); + borrow = 0 - borrow; + bn_select_words(r, borrow, r /* tmp < 0 */, tmp /* tmp >= 0 */, r_len); + return borrow; +} + +int bn_abs_sub_consttime(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + BN_CTX *ctx) { + int cl = a->width < b->width ? a->width : b->width; + int dl = a->width - b->width; + int r_len = a->width < b->width ? b->width : a->width; + BN_CTX_start(ctx); + BIGNUM *tmp = BN_CTX_get(ctx); + int ok = tmp != NULL && + bn_wexpand(r, r_len) && + bn_wexpand(tmp, r_len); + if (ok) { + bn_abs_sub_part_words(r->d, a->d, b->d, cl, dl, tmp->d); + r->width = r_len; + } + BN_CTX_end(ctx); + return ok; +} + +// Karatsuba recursive multiplication algorithm +// (cf. Knuth, The Art of Computer Programming, Vol. 2) + +// bn_mul_recursive sets |r| to |a| * |b|, using |t| as scratch space. |r| has +// length 2*|n2|, |a| has length |n2| + |dna|, |b| has length |n2| + |dnb|, and +// |t| has length 4*|n2|. |n2| must be a power of two. Finally, we must have +// -|BN_MUL_RECURSIVE_SIZE_NORMAL|/2 <= |dna| <= 0 and +// -|BN_MUL_RECURSIVE_SIZE_NORMAL|/2 <= |dnb| <= 0. +// +// TODO(davidben): Simplify and |size_t| the calling convention around lengths +// here. +static void bn_mul_recursive(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, + int n2, int dna, int dnb, BN_ULONG *t) { + // |n2| is a power of two. + assert(n2 != 0 && (n2 & (n2 - 1)) == 0); + // Check |dna| and |dnb| are in range. + assert(-BN_MUL_RECURSIVE_SIZE_NORMAL/2 <= dna && dna <= 0); + assert(-BN_MUL_RECURSIVE_SIZE_NORMAL/2 <= dnb && dnb <= 0); + + // 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; + } + + // 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) { + OPENSSL_memset(&r[2 * n2 + dna + dnb], 0, + sizeof(BN_ULONG) * -(dna + dnb)); + } + return; + } + + // Split |a| and |b| into a0,a1 and b0,b1, where a0 and b0 have size |n|. + // Split |t| into t0,t1,t2,t3, each of size |n|, with the remaining 4*|n| used + // for recursive calls. + // Split |r| into r0,r1,r2,r3. We must contribute a0*b0 to r0,r1, a0*a1+b0*b1 + // to r1,r2, and a1*b1 to r2,r3. The middle term we will compute as: + // + // a0*a1 + b0*b1 = (a0 - a1)*(b1 - b0) + a1*b1 + a0*b0 + // + // Note that we know |n| >= |BN_MUL_RECURSIVE_SIZE_NORMAL|/2 above, so + // |tna| and |tnb| are non-negative. + int n = n2 / 2, tna = n + dna, tnb = n + dnb; + + // t0 = a0 - a1 and t1 = b1 - b0. The result will be multiplied, so we XOR + // their sign masks, giving the sign of (a0 - a1)*(b1 - b0). t0 and t1 + // themselves store the absolute value. + BN_ULONG neg = bn_abs_sub_part_words(t, a, &a[n], tna, n - tna, &t[n2]); + neg ^= bn_abs_sub_part_words(&t[n], &b[n], b, tnb, tnb - n, &t[n2]); + + // Compute: + // t2,t3 = t0 * t1 = |(a0 - a1)*(b1 - b0)| + // r0,r1 = a0 * b0 + // r2,r3 = a1 * b1 + if (n == 4 && dna == 0 && dnb == 0) { + bn_mul_comba4(&t[n2], t, &t[n]); + + bn_mul_comba4(r, a, b); + bn_mul_comba4(&r[n2], &a[n], &b[n]); + } else if (n == 8 && dna == 0 && dnb == 0) { + bn_mul_comba8(&t[n2], t, &t[n]); + + bn_mul_comba8(r, a, b); + bn_mul_comba8(&r[n2], &a[n], &b[n]); + } else { + BN_ULONG *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); + bn_mul_recursive(&r[n2], &a[n], &b[n], n, dna, dnb, p); + } + + // t0,t1,c = r0,r1 + r2,r3 = a0*b0 + a1*b1 + BN_ULONG c = bn_add_words(t, r, &r[n2], n2); + + // t2,t3,c = t0,t1,c + neg*t2,t3 = (a0 - a1)*(b1 - b0) + a1*b1 + a0*b0. + // The second term is stored as the absolute value, so we do this with a + // constant-time select. + BN_ULONG c_neg = c - bn_sub_words(&t[n2 * 2], t, &t[n2], n2); + BN_ULONG c_pos = c + bn_add_words(&t[n2], t, &t[n2], n2); + bn_select_words(&t[n2], neg, &t[n2 * 2], &t[n2], n2); + OPENSSL_COMPILE_ASSERT(sizeof(BN_ULONG) <= sizeof(crypto_word_t), + crypto_word_t_too_small); + c = constant_time_select_w(neg, c_neg, c_pos); + + // We now have our three components. Add them together. + // r1,r2,c = r1,r2 + t2,t3,c + c += bn_add_words(&r[n], &r[n], &t[n2], n2); + + // Propagate the carry bit to the end. + for (int i = n + n2; i < n2 + n2; i++) { + BN_ULONG old = r[i]; + r[i] = old + c; + c = r[i] < old; + } + + // The product should fit without carries. + assert(c == 0); +} + +// bn_mul_part_recursive sets |r| to |a| * |b|, using |t| as scratch space. |r| +// has length 4*|n|, |a| has length |n| + |tna|, |b| has length |n| + |tnb|, and +// |t| has length 8*|n|. |n| must be a power of two. Additionally, we must have +// 0 <= tna < n and 0 <= tnb < n, and |tna| and |tnb| must differ by at most +// one. +// +// TODO(davidben): Make this take |size_t| and perhaps the actual lengths of |a| +// and |b|. +static void bn_mul_part_recursive(BN_ULONG *r, const BN_ULONG *a, + const BN_ULONG *b, int n, int tna, int tnb, + BN_ULONG *t) { + // |n| is a power of two. + assert(n != 0 && (n & (n - 1)) == 0); + // Check |tna| and |tnb| are in range. + assert(0 <= tna && tna < n); + assert(0 <= tnb && tnb < n); + assert(-1 <= tna - tnb && tna - tnb <= 1); + + int n2 = n * 2; + if (n < 8) { + bn_mul_normal(r, a, n + tna, b, n + tnb); + OPENSSL_memset(r + n2 + tna + tnb, 0, n2 - tna - tnb); + return; + } + + // Split |a| and |b| into a0,a1 and b0,b1, where a0 and b0 have size |n|. |a1| + // and |b1| have size |tna| and |tnb|, respectively. + // Split |t| into t0,t1,t2,t3, each of size |n|, with the remaining 4*|n| used + // for recursive calls. + // Split |r| into r0,r1,r2,r3. We must contribute a0*b0 to r0,r1, a0*a1+b0*b1 + // to r1,r2, and a1*b1 to r2,r3. The middle term we will compute as: + // + // a0*a1 + b0*b1 = (a0 - a1)*(b1 - b0) + a1*b1 + a0*b0 + + // t0 = a0 - a1 and t1 = b1 - b0. The result will be multiplied, so we XOR + // their sign masks, giving the sign of (a0 - a1)*(b1 - b0). t0 and t1 + // themselves store the absolute value. + BN_ULONG neg = bn_abs_sub_part_words(t, a, &a[n], tna, n - tna, &t[n2]); + neg ^= bn_abs_sub_part_words(&t[n], &b[n], b, tnb, tnb - n, &t[n2]); + + // Compute: + // t2,t3 = t0 * t1 = |(a0 - a1)*(b1 - b0)| + // r0,r1 = a0 * b0 + // r2,r3 = a1 * b1 + 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); + // |bn_mul_normal| only writes |tna| + |tna| words. Zero the rest. + OPENSSL_memset(&r[n2 + tna + tnb], 0, sizeof(BN_ULONG) * (n2 - tna - tnb)); + } else { + BN_ULONG *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); + + OPENSSL_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 { + int i = n; + for (;;) { + i /= 2; + if (i < tna || i < tnb) { + // E.g., n == 16, i == 8 and tna == 11. |tna| and |tnb| are within one + // of each other, so if |tna| is larger and tna > i, then we know + // tnb >= i, and this call is valid. + bn_mul_part_recursive(&r[n2], &a[n], &b[n], i, tna - i, tnb - i, p); + break; + } + if (i == tna || i == tnb) { + // If there is only a bottom half to the number, just do it. We know + // the larger of |tna - i| and |tnb - i| is zero. The other is zero or + // -1 by because of |tna| and |tnb| differ by at most one. + bn_mul_recursive(&r[n2], &a[n], &b[n], i, tna - i, tnb - i, p); + break; + } + + // This loop will eventually terminate when |i| falls below + // |BN_MUL_RECURSIVE_SIZE_NORMAL| because we know one of |tna| and |tnb| + // exceeds that. + } + } + } + + // t0,t1,c = r0,r1 + r2,r3 = a0*b0 + a1*b1 + BN_ULONG c = bn_add_words(t, r, &r[n2], n2); + + // t2,t3,c = t0,t1,c + neg*t2,t3 = (a0 - a1)*(b1 - b0) + a1*b1 + a0*b0. + // The second term is stored as the absolute value, so we do this with a + // constant-time select. + BN_ULONG c_neg = c - bn_sub_words(&t[n2 * 2], t, &t[n2], n2); + BN_ULONG c_pos = c + bn_add_words(&t[n2], t, &t[n2], n2); + bn_select_words(&t[n2], neg, &t[n2 * 2], &t[n2], n2); + OPENSSL_COMPILE_ASSERT(sizeof(BN_ULONG) <= sizeof(crypto_word_t), + crypto_word_t_too_small); + c = constant_time_select_w(neg, c_neg, c_pos); + + // We now have our three components. Add them together. + // r1,r2,c = r1,r2 + t2,t3,c + c += bn_add_words(&r[n], &r[n], &t[n2], n2); + + // Propagate the carry bit to the end. + for (int i = n + n2; i < n2 + n2; i++) { + BN_ULONG old = r[i]; + r[i] = old + c; + c = r[i] < old; + } + + // The product should fit without carries. + assert(c == 0); +} + +// bn_mul_impl implements |BN_mul| and |bn_mul_consttime|. Note this function +// breaks |BIGNUM| invariants and may return a negative zero. This is handled by +// the callers. +static int bn_mul_impl(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + BN_CTX *ctx) { + int al = a->width; + int bl = b->width; + if (al == 0 || bl == 0) { + BN_zero(r); + return 1; + } + + int ret = 0; + BIGNUM *rr; + BN_CTX_start(ctx); + if (r == a || r == b) { + rr = BN_CTX_get(ctx); + if (r == NULL) { + goto err; + } + } else { + rr = r; + } + rr->neg = a->neg ^ b->neg; + + int i = al - bl; + if (i == 0) { + if (al == 8) { + if (!bn_wexpand(rr, 16)) { + goto err; + } + rr->width = 16; + bn_mul_comba8(rr->d, a->d, b->d); + goto end; + } + } + + int top = al + bl; + static const int kMulNormalSize = 16; + if (al >= kMulNormalSize && bl >= kMulNormalSize) { + if (-1 <= i && i <= 1) { + // Find the larger power of two less than or equal to the larger length. + int j; + if (i >= 0) { + j = BN_num_bits_word((BN_ULONG)al); + } else { + j = BN_num_bits_word((BN_ULONG)bl); + } + j = 1 << (j - 1); + assert(j <= al || j <= bl); + BIGNUM *t = BN_CTX_get(ctx); + if (t == NULL) { + goto err; + } + if (al > j || bl > j) { + // We know |al| and |bl| are at most one from each other, so if al > j, + // bl >= j, and vice versa. Thus we can use |bn_mul_part_recursive|. + assert(al >= j && bl >= j); + if (!bn_wexpand(t, j * 8) || + !bn_wexpand(rr, j * 4)) { + goto err; + } + bn_mul_part_recursive(rr->d, a->d, b->d, j, al - j, bl - j, t->d); + } else { + // al <= j && bl <= j. Additionally, we know j <= al or j <= bl, so one + // of al - j or bl - j is zero. The other, by the bound on |i| above, is + // zero or -1. Thus, we can use |bn_mul_recursive|. + if (!bn_wexpand(t, j * 4) || + !bn_wexpand(rr, j * 2)) { + goto err; + } + bn_mul_recursive(rr->d, a->d, b->d, j, al - j, bl - j, t->d); + } + rr->width = top; + goto end; + } + } + + if (!bn_wexpand(rr, top)) { + goto err; + } + rr->width = top; + bn_mul_normal(rr->d, a->d, al, b->d, bl); + +end: + if (r != rr && !BN_copy(r, rr)) { + goto err; + } + ret = 1; + +err: + BN_CTX_end(ctx); + return ret; +} + +int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) { + if (!bn_mul_impl(r, a, b, ctx)) { + return 0; + } + + // This additionally fixes any negative zeros created by |bn_mul_impl|. + bn_set_minimal_width(r); + return 1; +} + +int bn_mul_consttime(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) { + // Prevent negative zeros. + if (a->neg || b->neg) { + OPENSSL_PUT_ERROR(BN, BN_R_NEGATIVE_NUMBER); + return 0; + } + + return bn_mul_impl(r, a, b, ctx); +} + +int bn_mul_small(BN_ULONG *r, size_t num_r, const BN_ULONG *a, size_t num_a, + const BN_ULONG *b, size_t num_b) { + if (num_r != num_a + num_b) { + OPENSSL_PUT_ERROR(BN, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + // TODO(davidben): Should this call |bn_mul_comba4| too? |BN_mul| does not + // hit that code. + if (num_a == 8 && num_b == 8) { + bn_mul_comba8(r, a, b); + } else { + bn_mul_normal(r, a, num_a, b, num_b); + } + return 1; +} + +// tmp must have 2*n words +static void bn_sqr_normal(BN_ULONG *r, const BN_ULONG *a, size_t n, + BN_ULONG *tmp) { + if (n == 0) { + return; + } + + size_t max = n * 2; + const BN_ULONG *ap = a; + BN_ULONG *rp = r; + rp[0] = rp[max - 1] = 0; + rp++; + + // Compute the contribution of a[i] * a[j] for all i < j. + if (n > 1) { + ap++; + rp[n - 1] = bn_mul_words(rp, ap, n - 1, ap[-1]); + rp += 2; + } + if (n > 2) { + for (size_t i = n - 2; i > 0; i--) { + ap++; + rp[i] = bn_mul_add_words(rp, ap, i, ap[-1]); + rp += 2; + } + } + + // The final result fits in |max| words, so none of the following operations + // will overflow. + + // Double |r|, giving the contribution of a[i] * a[j] for all i != j. + bn_add_words(r, r, r, max); + + // Add in the contribution of a[i] * a[i] for all i. + bn_sqr_words(tmp, a, n); + bn_add_words(r, r, tmp, max); +} + +// bn_sqr_recursive sets |r| to |a|^2, using |t| as scratch space. |r| has +// length 2*|n2|, |a| has length |n2|, and |t| has length 4*|n2|. |n2| must be +// a power of two. +static void bn_sqr_recursive(BN_ULONG *r, const BN_ULONG *a, size_t n2, + BN_ULONG *t) { + // |n2| is a power of two. + assert(n2 != 0 && (n2 & (n2 - 1)) == 0); + + if (n2 == 4) { + bn_sqr_comba4(r, a); + return; + } + if (n2 == 8) { + bn_sqr_comba8(r, a); + return; + } + if (n2 < BN_SQR_RECURSIVE_SIZE_NORMAL) { + bn_sqr_normal(r, a, n2, t); + return; + } + + // Split |a| into a0,a1, each of size |n|. + // Split |t| into t0,t1,t2,t3, each of size |n|, with the remaining 4*|n| used + // for recursive calls. + // Split |r| into r0,r1,r2,r3. We must contribute a0^2 to r0,r1, 2*a0*a1 to + // r1,r2, and a1^2 to r2,r3. + size_t n = n2 / 2; + BN_ULONG *t_recursive = &t[n2 * 2]; + + // t0 = |a0 - a1|. + bn_abs_sub_words(t, a, &a[n], n, &t[n]); + // t2,t3 = t0^2 = |a0 - a1|^2 = a0^2 - 2*a0*a1 + a1^2 + bn_sqr_recursive(&t[n2], t, n, t_recursive); + + // r0,r1 = a0^2 + bn_sqr_recursive(r, a, n, t_recursive); + + // r2,r3 = a1^2 + bn_sqr_recursive(&r[n2], &a[n], n, t_recursive); + + // t0,t1,c = r0,r1 + r2,r3 = a0^2 + a1^2 + BN_ULONG c = bn_add_words(t, r, &r[n2], n2); + // t2,t3,c = t0,t1,c - t2,t3 = 2*a0*a1 + c -= bn_sub_words(&t[n2], t, &t[n2], n2); + + // We now have our three components. Add them together. + // r1,r2,c = r1,r2 + t2,t3,c + c += bn_add_words(&r[n], &r[n], &t[n2], n2); + + // Propagate the carry bit to the end. + for (size_t i = n + n2; i < n2 + n2; i++) { + BN_ULONG old = r[i]; + r[i] = old + c; + c = r[i] < old; + } + + // The square should fit without carries. + assert(c == 0); +} + +int BN_mul_word(BIGNUM *bn, BN_ULONG w) { + if (!bn->width) { + return 1; + } + + if (w == 0) { + BN_zero(bn); + return 1; + } + + BN_ULONG ll = bn_mul_words(bn->d, bn->d, bn->width, w); + if (ll) { + if (!bn_wexpand(bn, bn->width + 1)) { + return 0; + } + bn->d[bn->width++] = ll; + } + + return 1; +} + +int bn_sqr_consttime(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx) { + int al = a->width; + if (al <= 0) { + r->width = 0; + r->neg = 0; + return 1; + } + + int ret = 0; + BN_CTX_start(ctx); + BIGNUM *rr = (a != r) ? r : BN_CTX_get(ctx); + BIGNUM *tmp = BN_CTX_get(ctx); + if (!rr || !tmp) { + goto err; + } + + int max = 2 * al; // Non-zero (from above) + if (!bn_wexpand(rr, max)) { + goto err; + } + + if (al == 4) { + bn_sqr_comba4(rr->d, a->d); + } else if (al == 8) { + bn_sqr_comba8(rr->d, a->d); + } else { + 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 { + // If |al| is a power of two, we can use |bn_sqr_recursive|. + if (al != 0 && (al & (al - 1)) == 0) { + if (!bn_wexpand(tmp, al * 4)) { + goto err; + } + bn_sqr_recursive(rr->d, a->d, al, tmp->d); + } else { + if (!bn_wexpand(tmp, max)) { + goto err; + } + bn_sqr_normal(rr->d, a->d, al, tmp->d); + } + } + } + + rr->neg = 0; + rr->width = max; + + if (rr != r && !BN_copy(r, rr)) { + goto err; + } + ret = 1; + +err: + BN_CTX_end(ctx); + return ret; +} + +int BN_sqr(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx) { + if (!bn_sqr_consttime(r, a, ctx)) { + return 0; + } + + bn_set_minimal_width(r); + return 1; +} + +int bn_sqr_small(BN_ULONG *r, size_t num_r, const BN_ULONG *a, size_t num_a) { + if (num_r != 2 * num_a || num_a > BN_SMALL_MAX_WORDS) { + OPENSSL_PUT_ERROR(BN, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + if (num_a == 4) { + bn_sqr_comba4(r, a); + } else if (num_a == 8) { + bn_sqr_comba8(r, a); + } else { + BN_ULONG tmp[2 * BN_SMALL_MAX_WORDS]; + bn_sqr_normal(r, a, num_a, tmp); + OPENSSL_cleanse(tmp, 2 * num_a * sizeof(BN_ULONG)); + } + return 1; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/mul.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/mul.c.grpc_back new file mode 100644 index 0000000..4a0711d --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/mul.c.grpc_back @@ -0,0 +1,876 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 +#include + +#include "internal.h" +#include "../../internal.h" + + +#define BN_MUL_RECURSIVE_SIZE_NORMAL 16 +#define BN_SQR_RECURSIVE_SIZE_NORMAL BN_MUL_RECURSIVE_SIZE_NORMAL + + +static void bn_abs_sub_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, + size_t num, BN_ULONG *tmp) { + BN_ULONG borrow = bn_sub_words(tmp, a, b, num); + bn_sub_words(r, b, a, num); + bn_select_words(r, 0 - borrow, r /* tmp < 0 */, tmp /* tmp >= 0 */, num); +} + +static void bn_mul_normal(BN_ULONG *r, const BN_ULONG *a, size_t na, + const BN_ULONG *b, size_t nb) { + if (na < nb) { + size_t itmp = na; + na = nb; + nb = itmp; + const BN_ULONG *ltmp = a; + a = b; + b = ltmp; + } + BN_ULONG *rr = &(r[na]); + if (nb == 0) { + OPENSSL_memset(r, 0, na * sizeof(BN_ULONG)); + return; + } + 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; + } +} + +#if !defined(OPENSSL_X86) || defined(OPENSSL_NO_ASM) +// 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. + +static 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) { + for (;;) { + t = b[0]; + r[0] = 0 - t - c; + if (t != 0) { + c = 1; + } + if (++dl >= 0) { + break; + } + + t = b[1]; + r[1] = 0 - t - c; + if (t != 0) { + c = 1; + } + if (++dl >= 0) { + break; + } + + t = b[2]; + r[2] = 0 - t - c; + if (t != 0) { + c = 1; + } + if (++dl >= 0) { + break; + } + + t = b[3]; + r[3] = 0 - t - c; + if (t != 0) { + c = 1; + } + if (++dl >= 0) { + break; + } + + b += 4; + r += 4; + } + } else { + int save_dl = dl; + while (c) { + t = a[0]; + r[0] = t - c; + if (t != 0) { + c = 0; + } + if (--dl <= 0) { + break; + } + + t = a[1]; + r[1] = t - c; + if (t != 0) { + c = 0; + } + if (--dl <= 0) { + break; + } + + t = a[2]; + r[2] = t - c; + if (t != 0) { + c = 0; + } + if (--dl <= 0) { + break; + } + + t = a[3]; + r[3] = t - c; + if (t != 0) { + c = 0; + } + if (--dl <= 0) { + break; + } + + save_dl = dl; + a += 4; + r += 4; + } + if (dl > 0) { + if (save_dl > dl) { + switch (save_dl - dl) { + case 1: + r[1] = a[1]; + if (--dl <= 0) { + break; + } + OPENSSL_FALLTHROUGH; + case 2: + r[2] = a[2]; + if (--dl <= 0) { + break; + } + OPENSSL_FALLTHROUGH; + case 3: + r[3] = a[3]; + if (--dl <= 0) { + break; + } + } + a += 4; + r += 4; + } + } + + if (dl > 0) { + 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; +} +#else +// On other platforms the function is defined in asm. +BN_ULONG bn_sub_part_words(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, + int cl, int dl); +#endif + +// bn_abs_sub_part_words computes |r| = |a| - |b|, storing the absolute value +// and returning a mask of all ones if the result was negative and all zeros if +// the result was positive. |cl| and |dl| follow the |bn_sub_part_words| calling +// convention. +// +// TODO(davidben): Make this take |size_t|. The |cl| + |dl| calling convention +// is confusing. The trouble is 32-bit x86 implements |bn_sub_part_words| in +// assembly, but we can probably just delete it? +static BN_ULONG bn_abs_sub_part_words(BN_ULONG *r, const BN_ULONG *a, + const BN_ULONG *b, int cl, int dl, + BN_ULONG *tmp) { + BN_ULONG borrow = bn_sub_part_words(tmp, a, b, cl, dl); + bn_sub_part_words(r, b, a, cl, -dl); + int r_len = cl + (dl < 0 ? -dl : dl); + borrow = 0 - borrow; + bn_select_words(r, borrow, r /* tmp < 0 */, tmp /* tmp >= 0 */, r_len); + return borrow; +} + +int bn_abs_sub_consttime(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + BN_CTX *ctx) { + int cl = a->width < b->width ? a->width : b->width; + int dl = a->width - b->width; + int r_len = a->width < b->width ? b->width : a->width; + BN_CTX_start(ctx); + BIGNUM *tmp = BN_CTX_get(ctx); + int ok = tmp != NULL && + bn_wexpand(r, r_len) && + bn_wexpand(tmp, r_len); + if (ok) { + bn_abs_sub_part_words(r->d, a->d, b->d, cl, dl, tmp->d); + r->width = r_len; + } + BN_CTX_end(ctx); + return ok; +} + +// Karatsuba recursive multiplication algorithm +// (cf. Knuth, The Art of Computer Programming, Vol. 2) + +// bn_mul_recursive sets |r| to |a| * |b|, using |t| as scratch space. |r| has +// length 2*|n2|, |a| has length |n2| + |dna|, |b| has length |n2| + |dnb|, and +// |t| has length 4*|n2|. |n2| must be a power of two. Finally, we must have +// -|BN_MUL_RECURSIVE_SIZE_NORMAL|/2 <= |dna| <= 0 and +// -|BN_MUL_RECURSIVE_SIZE_NORMAL|/2 <= |dnb| <= 0. +// +// TODO(davidben): Simplify and |size_t| the calling convention around lengths +// here. +static void bn_mul_recursive(BN_ULONG *r, const BN_ULONG *a, const BN_ULONG *b, + int n2, int dna, int dnb, BN_ULONG *t) { + // |n2| is a power of two. + assert(n2 != 0 && (n2 & (n2 - 1)) == 0); + // Check |dna| and |dnb| are in range. + assert(-BN_MUL_RECURSIVE_SIZE_NORMAL/2 <= dna && dna <= 0); + assert(-BN_MUL_RECURSIVE_SIZE_NORMAL/2 <= dnb && dnb <= 0); + + // 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; + } + + // 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) { + OPENSSL_memset(&r[2 * n2 + dna + dnb], 0, + sizeof(BN_ULONG) * -(dna + dnb)); + } + return; + } + + // Split |a| and |b| into a0,a1 and b0,b1, where a0 and b0 have size |n|. + // Split |t| into t0,t1,t2,t3, each of size |n|, with the remaining 4*|n| used + // for recursive calls. + // Split |r| into r0,r1,r2,r3. We must contribute a0*b0 to r0,r1, a0*a1+b0*b1 + // to r1,r2, and a1*b1 to r2,r3. The middle term we will compute as: + // + // a0*a1 + b0*b1 = (a0 - a1)*(b1 - b0) + a1*b1 + a0*b0 + // + // Note that we know |n| >= |BN_MUL_RECURSIVE_SIZE_NORMAL|/2 above, so + // |tna| and |tnb| are non-negative. + int n = n2 / 2, tna = n + dna, tnb = n + dnb; + + // t0 = a0 - a1 and t1 = b1 - b0. The result will be multiplied, so we XOR + // their sign masks, giving the sign of (a0 - a1)*(b1 - b0). t0 and t1 + // themselves store the absolute value. + BN_ULONG neg = bn_abs_sub_part_words(t, a, &a[n], tna, n - tna, &t[n2]); + neg ^= bn_abs_sub_part_words(&t[n], &b[n], b, tnb, tnb - n, &t[n2]); + + // Compute: + // t2,t3 = t0 * t1 = |(a0 - a1)*(b1 - b0)| + // r0,r1 = a0 * b0 + // r2,r3 = a1 * b1 + if (n == 4 && dna == 0 && dnb == 0) { + bn_mul_comba4(&t[n2], t, &t[n]); + + bn_mul_comba4(r, a, b); + bn_mul_comba4(&r[n2], &a[n], &b[n]); + } else if (n == 8 && dna == 0 && dnb == 0) { + bn_mul_comba8(&t[n2], t, &t[n]); + + bn_mul_comba8(r, a, b); + bn_mul_comba8(&r[n2], &a[n], &b[n]); + } else { + BN_ULONG *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); + bn_mul_recursive(&r[n2], &a[n], &b[n], n, dna, dnb, p); + } + + // t0,t1,c = r0,r1 + r2,r3 = a0*b0 + a1*b1 + BN_ULONG c = bn_add_words(t, r, &r[n2], n2); + + // t2,t3,c = t0,t1,c + neg*t2,t3 = (a0 - a1)*(b1 - b0) + a1*b1 + a0*b0. + // The second term is stored as the absolute value, so we do this with a + // constant-time select. + BN_ULONG c_neg = c - bn_sub_words(&t[n2 * 2], t, &t[n2], n2); + BN_ULONG c_pos = c + bn_add_words(&t[n2], t, &t[n2], n2); + bn_select_words(&t[n2], neg, &t[n2 * 2], &t[n2], n2); + OPENSSL_COMPILE_ASSERT(sizeof(BN_ULONG) <= sizeof(crypto_word_t), + crypto_word_t_too_small); + c = constant_time_select_w(neg, c_neg, c_pos); + + // We now have our three components. Add them together. + // r1,r2,c = r1,r2 + t2,t3,c + c += bn_add_words(&r[n], &r[n], &t[n2], n2); + + // Propagate the carry bit to the end. + for (int i = n + n2; i < n2 + n2; i++) { + BN_ULONG old = r[i]; + r[i] = old + c; + c = r[i] < old; + } + + // The product should fit without carries. + assert(c == 0); +} + +// bn_mul_part_recursive sets |r| to |a| * |b|, using |t| as scratch space. |r| +// has length 4*|n|, |a| has length |n| + |tna|, |b| has length |n| + |tnb|, and +// |t| has length 8*|n|. |n| must be a power of two. Additionally, we must have +// 0 <= tna < n and 0 <= tnb < n, and |tna| and |tnb| must differ by at most +// one. +// +// TODO(davidben): Make this take |size_t| and perhaps the actual lengths of |a| +// and |b|. +static void bn_mul_part_recursive(BN_ULONG *r, const BN_ULONG *a, + const BN_ULONG *b, int n, int tna, int tnb, + BN_ULONG *t) { + // |n| is a power of two. + assert(n != 0 && (n & (n - 1)) == 0); + // Check |tna| and |tnb| are in range. + assert(0 <= tna && tna < n); + assert(0 <= tnb && tnb < n); + assert(-1 <= tna - tnb && tna - tnb <= 1); + + int n2 = n * 2; + if (n < 8) { + bn_mul_normal(r, a, n + tna, b, n + tnb); + OPENSSL_memset(r + n2 + tna + tnb, 0, n2 - tna - tnb); + return; + } + + // Split |a| and |b| into a0,a1 and b0,b1, where a0 and b0 have size |n|. |a1| + // and |b1| have size |tna| and |tnb|, respectively. + // Split |t| into t0,t1,t2,t3, each of size |n|, with the remaining 4*|n| used + // for recursive calls. + // Split |r| into r0,r1,r2,r3. We must contribute a0*b0 to r0,r1, a0*a1+b0*b1 + // to r1,r2, and a1*b1 to r2,r3. The middle term we will compute as: + // + // a0*a1 + b0*b1 = (a0 - a1)*(b1 - b0) + a1*b1 + a0*b0 + + // t0 = a0 - a1 and t1 = b1 - b0. The result will be multiplied, so we XOR + // their sign masks, giving the sign of (a0 - a1)*(b1 - b0). t0 and t1 + // themselves store the absolute value. + BN_ULONG neg = bn_abs_sub_part_words(t, a, &a[n], tna, n - tna, &t[n2]); + neg ^= bn_abs_sub_part_words(&t[n], &b[n], b, tnb, tnb - n, &t[n2]); + + // Compute: + // t2,t3 = t0 * t1 = |(a0 - a1)*(b1 - b0)| + // r0,r1 = a0 * b0 + // r2,r3 = a1 * b1 + 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); + // |bn_mul_normal| only writes |tna| + |tna| words. Zero the rest. + OPENSSL_memset(&r[n2 + tna + tnb], 0, sizeof(BN_ULONG) * (n2 - tna - tnb)); + } else { + BN_ULONG *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); + + OPENSSL_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 { + int i = n; + for (;;) { + i /= 2; + if (i < tna || i < tnb) { + // E.g., n == 16, i == 8 and tna == 11. |tna| and |tnb| are within one + // of each other, so if |tna| is larger and tna > i, then we know + // tnb >= i, and this call is valid. + bn_mul_part_recursive(&r[n2], &a[n], &b[n], i, tna - i, tnb - i, p); + break; + } + if (i == tna || i == tnb) { + // If there is only a bottom half to the number, just do it. We know + // the larger of |tna - i| and |tnb - i| is zero. The other is zero or + // -1 by because of |tna| and |tnb| differ by at most one. + bn_mul_recursive(&r[n2], &a[n], &b[n], i, tna - i, tnb - i, p); + break; + } + + // This loop will eventually terminate when |i| falls below + // |BN_MUL_RECURSIVE_SIZE_NORMAL| because we know one of |tna| and |tnb| + // exceeds that. + } + } + } + + // t0,t1,c = r0,r1 + r2,r3 = a0*b0 + a1*b1 + BN_ULONG c = bn_add_words(t, r, &r[n2], n2); + + // t2,t3,c = t0,t1,c + neg*t2,t3 = (a0 - a1)*(b1 - b0) + a1*b1 + a0*b0. + // The second term is stored as the absolute value, so we do this with a + // constant-time select. + BN_ULONG c_neg = c - bn_sub_words(&t[n2 * 2], t, &t[n2], n2); + BN_ULONG c_pos = c + bn_add_words(&t[n2], t, &t[n2], n2); + bn_select_words(&t[n2], neg, &t[n2 * 2], &t[n2], n2); + OPENSSL_COMPILE_ASSERT(sizeof(BN_ULONG) <= sizeof(crypto_word_t), + crypto_word_t_too_small); + c = constant_time_select_w(neg, c_neg, c_pos); + + // We now have our three components. Add them together. + // r1,r2,c = r1,r2 + t2,t3,c + c += bn_add_words(&r[n], &r[n], &t[n2], n2); + + // Propagate the carry bit to the end. + for (int i = n + n2; i < n2 + n2; i++) { + BN_ULONG old = r[i]; + r[i] = old + c; + c = r[i] < old; + } + + // The product should fit without carries. + assert(c == 0); +} + +// bn_mul_impl implements |BN_mul| and |bn_mul_consttime|. Note this function +// breaks |BIGNUM| invariants and may return a negative zero. This is handled by +// the callers. +static int bn_mul_impl(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + BN_CTX *ctx) { + int al = a->width; + int bl = b->width; + if (al == 0 || bl == 0) { + BN_zero(r); + return 1; + } + + int ret = 0; + BIGNUM *rr; + BN_CTX_start(ctx); + if (r == a || r == b) { + rr = BN_CTX_get(ctx); + if (r == NULL) { + goto err; + } + } else { + rr = r; + } + rr->neg = a->neg ^ b->neg; + + int i = al - bl; + if (i == 0) { + if (al == 8) { + if (!bn_wexpand(rr, 16)) { + goto err; + } + rr->width = 16; + bn_mul_comba8(rr->d, a->d, b->d); + goto end; + } + } + + int top = al + bl; + static const int kMulNormalSize = 16; + if (al >= kMulNormalSize && bl >= kMulNormalSize) { + if (-1 <= i && i <= 1) { + // Find the larger power of two less than or equal to the larger length. + int j; + if (i >= 0) { + j = BN_num_bits_word((BN_ULONG)al); + } else { + j = BN_num_bits_word((BN_ULONG)bl); + } + j = 1 << (j - 1); + assert(j <= al || j <= bl); + BIGNUM *t = BN_CTX_get(ctx); + if (t == NULL) { + goto err; + } + if (al > j || bl > j) { + // We know |al| and |bl| are at most one from each other, so if al > j, + // bl >= j, and vice versa. Thus we can use |bn_mul_part_recursive|. + assert(al >= j && bl >= j); + if (!bn_wexpand(t, j * 8) || + !bn_wexpand(rr, j * 4)) { + goto err; + } + bn_mul_part_recursive(rr->d, a->d, b->d, j, al - j, bl - j, t->d); + } else { + // al <= j && bl <= j. Additionally, we know j <= al or j <= bl, so one + // of al - j or bl - j is zero. The other, by the bound on |i| above, is + // zero or -1. Thus, we can use |bn_mul_recursive|. + if (!bn_wexpand(t, j * 4) || + !bn_wexpand(rr, j * 2)) { + goto err; + } + bn_mul_recursive(rr->d, a->d, b->d, j, al - j, bl - j, t->d); + } + rr->width = top; + goto end; + } + } + + if (!bn_wexpand(rr, top)) { + goto err; + } + rr->width = top; + bn_mul_normal(rr->d, a->d, al, b->d, bl); + +end: + if (r != rr && !BN_copy(r, rr)) { + goto err; + } + ret = 1; + +err: + BN_CTX_end(ctx); + return ret; +} + +int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) { + if (!bn_mul_impl(r, a, b, ctx)) { + return 0; + } + + // This additionally fixes any negative zeros created by |bn_mul_impl|. + bn_set_minimal_width(r); + return 1; +} + +int bn_mul_consttime(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, BN_CTX *ctx) { + // Prevent negative zeros. + if (a->neg || b->neg) { + OPENSSL_PUT_ERROR(BN, BN_R_NEGATIVE_NUMBER); + return 0; + } + + return bn_mul_impl(r, a, b, ctx); +} + +int bn_mul_small(BN_ULONG *r, size_t num_r, const BN_ULONG *a, size_t num_a, + const BN_ULONG *b, size_t num_b) { + if (num_r != num_a + num_b) { + OPENSSL_PUT_ERROR(BN, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + // TODO(davidben): Should this call |bn_mul_comba4| too? |BN_mul| does not + // hit that code. + if (num_a == 8 && num_b == 8) { + bn_mul_comba8(r, a, b); + } else { + bn_mul_normal(r, a, num_a, b, num_b); + } + return 1; +} + +// tmp must have 2*n words +static void bn_sqr_normal(BN_ULONG *r, const BN_ULONG *a, size_t n, + BN_ULONG *tmp) { + if (n == 0) { + return; + } + + size_t max = n * 2; + const BN_ULONG *ap = a; + BN_ULONG *rp = r; + rp[0] = rp[max - 1] = 0; + rp++; + + // Compute the contribution of a[i] * a[j] for all i < j. + if (n > 1) { + ap++; + rp[n - 1] = bn_mul_words(rp, ap, n - 1, ap[-1]); + rp += 2; + } + if (n > 2) { + for (size_t i = n - 2; i > 0; i--) { + ap++; + rp[i] = bn_mul_add_words(rp, ap, i, ap[-1]); + rp += 2; + } + } + + // The final result fits in |max| words, so none of the following operations + // will overflow. + + // Double |r|, giving the contribution of a[i] * a[j] for all i != j. + bn_add_words(r, r, r, max); + + // Add in the contribution of a[i] * a[i] for all i. + bn_sqr_words(tmp, a, n); + bn_add_words(r, r, tmp, max); +} + +// bn_sqr_recursive sets |r| to |a|^2, using |t| as scratch space. |r| has +// length 2*|n2|, |a| has length |n2|, and |t| has length 4*|n2|. |n2| must be +// a power of two. +static void bn_sqr_recursive(BN_ULONG *r, const BN_ULONG *a, size_t n2, + BN_ULONG *t) { + // |n2| is a power of two. + assert(n2 != 0 && (n2 & (n2 - 1)) == 0); + + if (n2 == 4) { + bn_sqr_comba4(r, a); + return; + } + if (n2 == 8) { + bn_sqr_comba8(r, a); + return; + } + if (n2 < BN_SQR_RECURSIVE_SIZE_NORMAL) { + bn_sqr_normal(r, a, n2, t); + return; + } + + // Split |a| into a0,a1, each of size |n|. + // Split |t| into t0,t1,t2,t3, each of size |n|, with the remaining 4*|n| used + // for recursive calls. + // Split |r| into r0,r1,r2,r3. We must contribute a0^2 to r0,r1, 2*a0*a1 to + // r1,r2, and a1^2 to r2,r3. + size_t n = n2 / 2; + BN_ULONG *t_recursive = &t[n2 * 2]; + + // t0 = |a0 - a1|. + bn_abs_sub_words(t, a, &a[n], n, &t[n]); + // t2,t3 = t0^2 = |a0 - a1|^2 = a0^2 - 2*a0*a1 + a1^2 + bn_sqr_recursive(&t[n2], t, n, t_recursive); + + // r0,r1 = a0^2 + bn_sqr_recursive(r, a, n, t_recursive); + + // r2,r3 = a1^2 + bn_sqr_recursive(&r[n2], &a[n], n, t_recursive); + + // t0,t1,c = r0,r1 + r2,r3 = a0^2 + a1^2 + BN_ULONG c = bn_add_words(t, r, &r[n2], n2); + // t2,t3,c = t0,t1,c - t2,t3 = 2*a0*a1 + c -= bn_sub_words(&t[n2], t, &t[n2], n2); + + // We now have our three components. Add them together. + // r1,r2,c = r1,r2 + t2,t3,c + c += bn_add_words(&r[n], &r[n], &t[n2], n2); + + // Propagate the carry bit to the end. + for (size_t i = n + n2; i < n2 + n2; i++) { + BN_ULONG old = r[i]; + r[i] = old + c; + c = r[i] < old; + } + + // The square should fit without carries. + assert(c == 0); +} + +int BN_mul_word(BIGNUM *bn, BN_ULONG w) { + if (!bn->width) { + return 1; + } + + if (w == 0) { + BN_zero(bn); + return 1; + } + + BN_ULONG ll = bn_mul_words(bn->d, bn->d, bn->width, w); + if (ll) { + if (!bn_wexpand(bn, bn->width + 1)) { + return 0; + } + bn->d[bn->width++] = ll; + } + + return 1; +} + +int bn_sqr_consttime(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx) { + int al = a->width; + if (al <= 0) { + r->width = 0; + r->neg = 0; + return 1; + } + + int ret = 0; + BN_CTX_start(ctx); + BIGNUM *rr = (a != r) ? r : BN_CTX_get(ctx); + BIGNUM *tmp = BN_CTX_get(ctx); + if (!rr || !tmp) { + goto err; + } + + int max = 2 * al; // Non-zero (from above) + if (!bn_wexpand(rr, max)) { + goto err; + } + + if (al == 4) { + bn_sqr_comba4(rr->d, a->d); + } else if (al == 8) { + bn_sqr_comba8(rr->d, a->d); + } else { + 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 { + // If |al| is a power of two, we can use |bn_sqr_recursive|. + if (al != 0 && (al & (al - 1)) == 0) { + if (!bn_wexpand(tmp, al * 4)) { + goto err; + } + bn_sqr_recursive(rr->d, a->d, al, tmp->d); + } else { + if (!bn_wexpand(tmp, max)) { + goto err; + } + bn_sqr_normal(rr->d, a->d, al, tmp->d); + } + } + } + + rr->neg = 0; + rr->width = max; + + if (rr != r && !BN_copy(r, rr)) { + goto err; + } + ret = 1; + +err: + BN_CTX_end(ctx); + return ret; +} + +int BN_sqr(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx) { + if (!bn_sqr_consttime(r, a, ctx)) { + return 0; + } + + bn_set_minimal_width(r); + return 1; +} + +int bn_sqr_small(BN_ULONG *r, size_t num_r, const BN_ULONG *a, size_t num_a) { + if (num_r != 2 * num_a || num_a > BN_SMALL_MAX_WORDS) { + OPENSSL_PUT_ERROR(BN, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + if (num_a == 4) { + bn_sqr_comba4(r, a); + } else if (num_a == 8) { + bn_sqr_comba8(r, a); + } else { + BN_ULONG tmp[2 * BN_SMALL_MAX_WORDS]; + bn_sqr_normal(r, a, num_a, tmp); + OPENSSL_cleanse(tmp, 2 * num_a * sizeof(BN_ULONG)); + } + return 1; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/prime.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/prime.c new file mode 100644 index 0000000..62f0521 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/prime.c @@ -0,0 +1,1154 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 + +#include "internal.h" +#include "../../internal.h" + + +// 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. + +#define NUMPRIMES 2048 + +// primes contains all the primes that fit into a uint16_t. +static const uint16_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, 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, +}; + +// BN_prime_checks_for_size returns the number of Miller-Rabin iterations +// necessary for a 'bits'-bit prime, in order to maintain an error rate greater +// than the security level for an RSA prime of that many bits (calculated using +// the FIPS SP 800-57 security level and 186-4 Section F.1; original paper: +// Damgaard, Landrock, Pomerance: Average case error estimates for the strong +// probable prime test. -- Math. Comp. 61 (1993) 177-194) +static int BN_prime_checks_for_size(int bits) { + if (bits >= 3747) { + return 3; + } + if (bits >= 1345) { + return 4; + } + if (bits >= 476) { + return 5; + } + if (bits >= 400) { + return 6; + } + if (bits >= 308) { + return 8; + } + if (bits >= 205) { + return 13; + } + if (bits >= 155) { + return 19; + } + return 28; +} + +// BN_PRIME_CHECKS_BLINDED is the iteration count for blinding the constant-time +// primality test. See |BN_primality_test| for details. This number is selected +// so that, for a candidate N-bit RSA prime, picking |BN_PRIME_CHECKS_BLINDED| +// random N-bit numbers will have at least |BN_prime_checks_for_size(N)| values +// in range with high probability. +// +// The following Python script computes the blinding factor needed for the +// corresponding iteration count. +/* +import math + +# We choose candidate RSA primes between sqrt(2)/2 * 2^N and 2^N and select +# witnesses by generating random N-bit numbers. Thus the probability of +# selecting one in range is at least sqrt(2)/2. +p = math.sqrt(2) / 2 + +# Target around 2^-8 probability of the blinding being insufficient given that +# key generation is a one-time, noisy operation. +epsilon = 2**-8 + +def choose(a, b): + r = 1 + for i in xrange(b): + r *= a - i + r /= (i + 1) + return r + +def failure_rate(min_uniform, iterations): + """ Returns the probability that, for |iterations| candidate witnesses, fewer + than |min_uniform| of them will be uniform. """ + prob = 0.0 + for i in xrange(min_uniform): + prob += (choose(iterations, i) * + p**i * (1-p)**(iterations - i)) + return prob + +for min_uniform in (3, 4, 5, 6, 8, 13, 19, 28): + # Find the smallest number of iterations under the target failure rate. + iterations = min_uniform + while True: + prob = failure_rate(min_uniform, iterations) + if prob < epsilon: + print min_uniform, iterations, prob + break + iterations += 1 + +Output: + 3 9 0.00368894873911 + 4 11 0.00363319494662 + 5 13 0.00336215573898 + 6 15 0.00300145783158 + 8 19 0.00225214119331 + 13 27 0.00385610026955 + 19 38 0.0021410539126 + 28 52 0.00325405801769 + +16 iterations suffices for 400-bit primes and larger (6 uniform samples needed), +which is already well below the minimum acceptable key size for RSA. +*/ +#define BN_PRIME_CHECKS_BLINDED 16 + +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); + +void BN_GENCB_set(BN_GENCB *callback, + int (*f)(int event, int n, struct bn_gencb_st *), + void *arg) { + callback->callback = f; + callback->arg = arg; +} + +int BN_GENCB_call(BN_GENCB *callback, int event, int n) { + if (!callback) { + return 1; + } + + return callback->callback(event, n, callback); +} + +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); + + if (bits < 2) { + // There are no prime numbers this small. + OPENSSL_PUT_ERROR(BN, BN_R_BITS_TOO_SMALL); + return 0; + } else if (bits == 2 && safe) { + // The smallest safe prime (7) is three bits. + OPENSSL_PUT_ERROR(BN, BN_R_BITS_TOO_SMALL); + return 0; + } + + 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_GENCB_call(cb, BN_GENCB_GENERATED, c1++)) { + // aborted + goto err; + } + + if (!safe) { + i = BN_is_prime_fasttest_ex(ret, checks, ctx, 0, cb); + if (i == -1) { + goto err; + } else 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, NULL); + if (j == -1) { + goto err; + } else if (j == 0) { + goto loop; + } + + j = BN_is_prime_fasttest_ex(t, 1, ctx, 0, NULL); + if (j == -1) { + goto err; + } else if (j == 0) { + goto loop; + } + + if (!BN_GENCB_call(cb, i, 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); + } + + return found; +} + +// The following functions use a Barrett reduction variant to avoid leaking the +// numerator. See http://ridiculousfish.com/blog/posts/labor-of-division-episode-i.html +// +// We use 32-bit numerator and 16-bit divisor for simplicity. This allows +// computing |m| and |q| without architecture-specific code. + +// mod_u16 returns |n| mod |d|. |p| and |m| are the "magic numbers" for |d| (see +// reference). For proof of correctness in Coq, see +// https://github.com/davidben/fiat-crypto/blob/barrett/src/Arithmetic/BarrettReduction/RidiculousFish.v +// Note the Coq version of |mod_u16| additionally includes the computation of +// |p| and |m| from |bn_mod_u16_consttime| below. +static uint16_t mod_u16(uint32_t n, uint16_t d, uint32_t p, uint32_t m) { + // Compute floor(n/d) per steps 3 through 5. + uint32_t q = ((uint64_t)m * n) >> 32; + // Note there is a typo in the reference. We right-shift by one, not two. + uint32_t t = ((n - q) >> 1) + q; + t = t >> (p - 1); + + // Multiply and subtract to get the remainder. + n -= d * t; + assert(n < d); + return n; +} + +// shift_and_add_mod_u16 returns |r| * 2^32 + |a| mod |d|. |p| and |m| are the +// "magic numbers" for |d| (see reference). +static uint16_t shift_and_add_mod_u16(uint16_t r, uint32_t a, uint16_t d, + uint32_t p, uint32_t m) { + // Incorporate |a| in two 16-bit chunks. + uint32_t t = r; + t <<= 16; + t |= a >> 16; + t = mod_u16(t, d, p, m); + + t <<= 16; + t |= a & 0xffff; + t = mod_u16(t, d, p, m); + return t; +} + +uint16_t bn_mod_u16_consttime(const BIGNUM *bn, uint16_t d) { + if (d <= 1) { + return 0; + } + + // Compute the "magic numbers" for |d|. See steps 1 and 2. + // This computes p = ceil(log_2(d)). + uint32_t p = BN_num_bits_word(d - 1); + // This operation is not constant-time, but |p| and |d| are public values. + // Note that |p| is at most 16, so the computation fits in |uint64_t|. + assert(p <= 16); + uint32_t m = ((UINT64_C(1) << (32 + p)) + d - 1) / d; + + uint16_t ret = 0; + for (int i = bn->width - 1; i >= 0; i--) { +#if BN_BITS2 == 32 + ret = shift_and_add_mod_u16(ret, bn->d[i], d, p, m); +#elif BN_BITS2 == 64 + ret = shift_and_add_mod_u16(ret, bn->d[i] >> 32, d, p, m); + ret = shift_and_add_mod_u16(ret, bn->d[i] & 0xffffffff, d, p, m); +#else +#error "Unknown BN_ULONG size" +#endif + } + return ret; +} + +static int bn_trial_division(uint16_t *out, const BIGNUM *bn) { + for (int i = 1; i < NUMPRIMES; i++) { + if (bn_mod_u16_consttime(bn, primes[i]) == 0) { + *out = primes[i]; + return 1; + } + } + return 0; +} + +int bn_odd_number_is_obviously_composite(const BIGNUM *bn) { + uint16_t prime; + return bn_trial_division(&prime, bn) && !BN_is_word(bn, prime); +} + +int BN_primality_test(int *is_probably_prime, const BIGNUM *w, + int iterations, BN_CTX *ctx, int do_trial_division, + BN_GENCB *cb) { + *is_probably_prime = 0; + + // To support RSA key generation, this function should treat |w| as secret if + // it is a large prime. Composite numbers are discarded, so they may return + // early. + + if (BN_cmp(w, BN_value_one()) <= 0) { + return 1; + } + + if (!BN_is_odd(w)) { + // The only even prime is two. + *is_probably_prime = BN_is_word(w, 2); + return 1; + } + + // Miller-Rabin does not work for three. + if (BN_is_word(w, 3)) { + *is_probably_prime = 1; + return 1; + } + + if (do_trial_division) { + // Perform additional trial division checks to discard small primes. + uint16_t prime; + if (bn_trial_division(&prime, w)) { + *is_probably_prime = BN_is_word(w, prime); + return 1; + } + if (!BN_GENCB_call(cb, 1, -1)) { + return 0; + } + } + + if (iterations == BN_prime_checks) { + iterations = BN_prime_checks_for_size(BN_num_bits(w)); + } + + // See C.3.1 from FIPS 186-4. + int ret = 0; + BN_MONT_CTX *mont = NULL; + BN_CTX_start(ctx); + BIGNUM *w1 = BN_CTX_get(ctx); + if (w1 == NULL || + !bn_usub_consttime(w1, w, BN_value_one())) { + goto err; + } + + // Write w1 as m * 2^a (Steps 1 and 2). + int w_len = BN_num_bits(w); + int a = BN_count_low_zero_bits(w1); + BIGNUM *m = BN_CTX_get(ctx); + if (m == NULL || + !bn_rshift_secret_shift(m, w1, a, ctx)) { + goto err; + } + + // Montgomery setup for computations mod w. Additionally, compute 1 and w - 1 + // in the Montgomery domain for later comparisons. + BIGNUM *b = BN_CTX_get(ctx); + BIGNUM *z = BN_CTX_get(ctx); + BIGNUM *one_mont = BN_CTX_get(ctx); + BIGNUM *w1_mont = BN_CTX_get(ctx); + mont = BN_MONT_CTX_new_for_modulus(w, ctx); + if (b == NULL || z == NULL || one_mont == NULL || w1_mont == NULL || + mont == NULL || + !bn_one_to_montgomery(one_mont, mont, ctx) || + // w - 1 is -1 mod w, so we can compute it in the Montgomery domain, -R, + // with a subtraction. (|one_mont| cannot be zero.) + !bn_usub_consttime(w1_mont, w, one_mont)) { + goto err; + } + + // The following loop performs in inner iteration of the Miller-Rabin + // Primality test (Step 4). + // + // The algorithm as specified in FIPS 186-4 leaks information on |w|, the RSA + // private key. Instead, we run through each iteration unconditionally, + // performing modular multiplications, masking off any effects to behave + // equivalently to the specified algorithm. + // + // We also blind the number of values of |b| we try. Steps 4.1–4.2 say to + // discard out-of-range values. To avoid leaking information on |w|, we use + // |bn_rand_secret_range| which, rather than discarding bad values, adjusts + // them to be in range. Though not uniformly selected, these adjusted values + // are still usable as Rabin-Miller checks. + // + // Rabin-Miller is already probabilistic, so we could reach the desired + // confidence levels by just suitably increasing the iteration count. However, + // to align with FIPS 186-4, we use a more pessimal analysis: we do not count + // the non-uniform values towards the iteration count. As a result, this + // function is more complex and has more timing risk than necessary. + // + // We count both total iterations and uniform ones and iterate until we've + // reached at least |BN_PRIME_CHECKS_BLINDED| and |iterations|, respectively. + // If the latter is large enough, it will be the limiting factor with high + // probability and we won't leak information. + // + // Note this blinding does not impact most calls when picking primes because + // composites are rejected early. Only the two secret primes see extra work. + + crypto_word_t uniform_iterations = 0; + // Using |constant_time_lt_w| seems to prevent the compiler from optimizing + // this into two jumps. + for (int i = 1; (i <= BN_PRIME_CHECKS_BLINDED) | + constant_time_lt_w(uniform_iterations, iterations); + i++) { + int is_uniform; + if (// Step 4.1-4.2 + !bn_rand_secret_range(b, &is_uniform, 2, w1) || + // Step 4.3 + !BN_mod_exp_mont_consttime(z, b, m, w, ctx, mont)) { + goto err; + } + uniform_iterations += is_uniform; + + // loop_done is all ones if the loop has completed and all zeros otherwise. + crypto_word_t loop_done = 0; + // next_iteration is all ones if we should continue to the next iteration + // (|b| is not a composite witness for |w|). This is equivalent to going to + // step 4.7 in the original algorithm. + crypto_word_t next_iteration = 0; + + // Step 4.4. If z = 1 or z = w-1, mask off the loop and continue to the next + // iteration (go to step 4.7). + loop_done = BN_equal_consttime(z, BN_value_one()) | + BN_equal_consttime(z, w1); + loop_done = 0 - loop_done; // Make it all zeros or all ones. + next_iteration = loop_done; // Go to step 4.7 if |loop_done|. + + // Step 4.5. We use Montgomery-encoding for better performance and to avoid + // timing leaks. + if (!BN_to_montgomery(z, z, mont, ctx)) { + goto err; + } + + // To avoid leaking |a|, we run the loop to |w_len| and mask off all + // iterations once |j| = |a|. + for (int j = 1; j < w_len; j++) { + loop_done |= constant_time_eq_int(j, a); + + // Step 4.5.1. + if (!BN_mod_mul_montgomery(z, z, z, mont, ctx)) { + goto err; + } + + // Step 4.5.2. If z = w-1 and the loop is not done, run through the next + // iteration. + crypto_word_t z_is_w1_mont = BN_equal_consttime(z, w1_mont) & ~loop_done; + z_is_w1_mont = 0 - z_is_w1_mont; // Make it all zeros or all ones. + loop_done |= z_is_w1_mont; + next_iteration |= z_is_w1_mont; // Go to step 4.7 if |z_is_w1_mont|. + + // Step 4.5.3. If z = 1 and the loop is not done, w is composite and we + // may exit in variable time. + if (BN_equal_consttime(z, one_mont) & ~loop_done) { + assert(!next_iteration); + break; + } + } + + if (!next_iteration) { + // Step 4.6. We did not see z = w-1 before z = 1, so w must be composite. + // (For any prime, the value of z immediately preceding 1 must be -1. + // There are no non-trivial square roots of 1 modulo a prime.) + *is_probably_prime = 0; + ret = 1; + goto err; + } + + // Step 4.7 + if (!BN_GENCB_call(cb, 1, i)) { + goto err; + } + } + + assert(uniform_iterations >= (crypto_word_t)iterations); + *is_probably_prime = 1; + ret = 1; + +err: + BN_MONT_CTX_free(mont); + BN_CTX_end(ctx); + return ret; +} + +int BN_is_prime_ex(const BIGNUM *candidate, int checks, BN_CTX *ctx, BN_GENCB *cb) { + return BN_is_prime_fasttest_ex(candidate, checks, ctx, 0, cb); +} + +int BN_is_prime_fasttest_ex(const BIGNUM *a, int checks, BN_CTX *ctx, + int do_trial_division, BN_GENCB *cb) { + int is_probably_prime; + if (!BN_primality_test(&is_probably_prime, a, checks, ctx, do_trial_division, + cb)) { + return -1; + } + return is_probably_prime; +} + +int BN_enhanced_miller_rabin_primality_test( + enum bn_primality_result_t *out_result, const BIGNUM *w, int iterations, + BN_CTX *ctx, BN_GENCB *cb) { + // Enhanced Miller-Rabin is only valid on odd integers greater than 3. + if (!BN_is_odd(w) || BN_cmp_word(w, 3) <= 0) { + OPENSSL_PUT_ERROR(BN, BN_R_INVALID_INPUT); + return 0; + } + + if (iterations == BN_prime_checks) { + iterations = BN_prime_checks_for_size(BN_num_bits(w)); + } + + int ret = 0; + BN_MONT_CTX *mont = NULL; + + BN_CTX_start(ctx); + + BIGNUM *w1 = BN_CTX_get(ctx); + if (w1 == NULL || + !BN_copy(w1, w) || + !BN_sub_word(w1, 1)) { + goto err; + } + + // Write w1 as m*2^a (Steps 1 and 2). + int a = 0; + while (!BN_is_bit_set(w1, a)) { + a++; + } + BIGNUM *m = BN_CTX_get(ctx); + if (m == NULL || + !BN_rshift(m, w1, a)) { + goto err; + } + + BIGNUM *b = BN_CTX_get(ctx); + BIGNUM *g = BN_CTX_get(ctx); + BIGNUM *z = BN_CTX_get(ctx); + BIGNUM *x = BN_CTX_get(ctx); + BIGNUM *x1 = BN_CTX_get(ctx); + if (b == NULL || + g == NULL || + z == NULL || + x == NULL || + x1 == NULL) { + goto err; + } + + // Montgomery setup for computations mod w + mont = BN_MONT_CTX_new_for_modulus(w, ctx); + if (mont == NULL) { + goto err; + } + + // The following loop performs in inner iteration of the Enhanced Miller-Rabin + // Primality test (Step 4). + for (int i = 1; i <= iterations; i++) { + // Step 4.1-4.2 + if (!BN_rand_range_ex(b, 2, w1)) { + goto err; + } + + // Step 4.3-4.4 + if (!BN_gcd(g, b, w, ctx)) { + goto err; + } + if (BN_cmp_word(g, 1) > 0) { + *out_result = bn_composite; + ret = 1; + goto err; + } + + // Step 4.5 + if (!BN_mod_exp_mont(z, b, m, w, ctx, mont)) { + goto err; + } + + // Step 4.6 + if (BN_is_one(z) || BN_cmp(z, w1) == 0) { + goto loop; + } + + // Step 4.7 + for (int j = 1; j < a; j++) { + if (!BN_copy(x, z) || !BN_mod_mul(z, x, x, w, ctx)) { + goto err; + } + if (BN_cmp(z, w1) == 0) { + goto loop; + } + if (BN_is_one(z)) { + goto composite; + } + } + + // Step 4.8-4.9 + if (!BN_copy(x, z) || !BN_mod_mul(z, x, x, w, ctx)) { + goto err; + } + + // Step 4.10-4.11 + if (!BN_is_one(z) && !BN_copy(x, z)) { + goto err; + } + + composite: + // Step 4.12-4.14 + if (!BN_copy(x1, x) || + !BN_sub_word(x1, 1) || + !BN_gcd(g, x1, w, ctx)) { + goto err; + } + if (BN_cmp_word(g, 1) > 0) { + *out_result = bn_composite; + } else { + *out_result = bn_non_prime_power_composite; + } + + ret = 1; + goto err; + + loop: + // Step 4.15 + if (!BN_GENCB_call(cb, 1, i)) { + goto err; + } + } + + *out_result = bn_probably_prime; + ret = 1; + +err: + BN_MONT_CTX_free(mont); + BN_CTX_end(ctx); + + return ret; +} + +static int probable_prime(BIGNUM *rnd, int bits) { + int i; + uint16_t mods[NUMPRIMES]; + BN_ULONG delta; + BN_ULONG maxdelta = BN_MASK2 - primes[NUMPRIMES - 1]; + char is_single_word = bits <= BN_BITS2; + +again: + if (!BN_rand(rnd, bits, BN_RAND_TOP_TWO, BN_RAND_BOTTOM_ODD)) { + return 0; + } + + // we now have a random number 'rnd' to test. + for (i = 1; i < NUMPRIMES; i++) { + mods[i] = bn_mod_u16_consttime(rnd, primes[i]); + } + // If bits is so small that it fits into a single word then we + // additionally don't want to exceed that many bits. + if (is_single_word) { + BN_ULONG size_limit; + if (bits == BN_BITS2) { + // Avoid undefined behavior. + size_limit = ~((BN_ULONG)0) - BN_get_word(rnd); + } else { + size_limit = (((BN_ULONG)1) << bits) - BN_get_word(rnd) - 1; + } + if (size_limit < maxdelta) { + maxdelta = size_limit; + } + } + delta = 0; + +loop: + if (is_single_word) { + BN_ULONG rnd_word = BN_get_word(rnd); + + // In the case that the candidate prime is a single word then + // we check that: + // 1) It's greater than primes[i] because we shouldn't reject + // 3 as being a prime number because it's a multiple of + // three. + // 2) That it's not a multiple of a known prime. We don't + // check that rnd-1 is also coprime to all the known + // primes because there aren't many small primes where + // that's true. + for (i = 1; i < NUMPRIMES && primes[i] < rnd_word; i++) { + if ((mods[i] + delta) % primes[i] == 0) { + delta += 2; + if (delta > maxdelta) { + goto again; + } + goto loop; + } + } + } else { + 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; + } + if (BN_num_bits(rnd) != (unsigned)bits) { + goto again; + } + + 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, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ODD)) { + 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_u16_consttime(rnd, primes[i]) <= 1) { + if (!BN_add(rnd, rnd, add)) { + goto err; + } + goto loop; + } + } + + ret = 1; + +err: + BN_CTX_end(ctx); + 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, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ODD)) { + 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_u16_consttime(p, primes[i]) == 0 || + bn_mod_u16_consttime(q, 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); + return ret; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/prime.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/prime.c.grpc_back new file mode 100644 index 0000000..35b1034 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/prime.c.grpc_back @@ -0,0 +1,1154 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 + +#include "internal.h" +#include "../../internal.h" + + +// 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. + +#define NUMPRIMES 2048 + +// primes contains all the primes that fit into a uint16_t. +static const uint16_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, 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, +}; + +// BN_prime_checks_for_size returns the number of Miller-Rabin iterations +// necessary for a 'bits'-bit prime, in order to maintain an error rate greater +// than the security level for an RSA prime of that many bits (calculated using +// the FIPS SP 800-57 security level and 186-4 Section F.1; original paper: +// Damgaard, Landrock, Pomerance: Average case error estimates for the strong +// probable prime test. -- Math. Comp. 61 (1993) 177-194) +static int BN_prime_checks_for_size(int bits) { + if (bits >= 3747) { + return 3; + } + if (bits >= 1345) { + return 4; + } + if (bits >= 476) { + return 5; + } + if (bits >= 400) { + return 6; + } + if (bits >= 308) { + return 8; + } + if (bits >= 205) { + return 13; + } + if (bits >= 155) { + return 19; + } + return 28; +} + +// BN_PRIME_CHECKS_BLINDED is the iteration count for blinding the constant-time +// primality test. See |BN_primality_test| for details. This number is selected +// so that, for a candidate N-bit RSA prime, picking |BN_PRIME_CHECKS_BLINDED| +// random N-bit numbers will have at least |BN_prime_checks_for_size(N)| values +// in range with high probability. +// +// The following Python script computes the blinding factor needed for the +// corresponding iteration count. +/* +import math + +# We choose candidate RSA primes between sqrt(2)/2 * 2^N and 2^N and select +# witnesses by generating random N-bit numbers. Thus the probability of +# selecting one in range is at least sqrt(2)/2. +p = math.sqrt(2) / 2 + +# Target around 2^-8 probability of the blinding being insufficient given that +# key generation is a one-time, noisy operation. +epsilon = 2**-8 + +def choose(a, b): + r = 1 + for i in xrange(b): + r *= a - i + r /= (i + 1) + return r + +def failure_rate(min_uniform, iterations): + """ Returns the probability that, for |iterations| candidate witnesses, fewer + than |min_uniform| of them will be uniform. """ + prob = 0.0 + for i in xrange(min_uniform): + prob += (choose(iterations, i) * + p**i * (1-p)**(iterations - i)) + return prob + +for min_uniform in (3, 4, 5, 6, 8, 13, 19, 28): + # Find the smallest number of iterations under the target failure rate. + iterations = min_uniform + while True: + prob = failure_rate(min_uniform, iterations) + if prob < epsilon: + print min_uniform, iterations, prob + break + iterations += 1 + +Output: + 3 9 0.00368894873911 + 4 11 0.00363319494662 + 5 13 0.00336215573898 + 6 15 0.00300145783158 + 8 19 0.00225214119331 + 13 27 0.00385610026955 + 19 38 0.0021410539126 + 28 52 0.00325405801769 + +16 iterations suffices for 400-bit primes and larger (6 uniform samples needed), +which is already well below the minimum acceptable key size for RSA. +*/ +#define BN_PRIME_CHECKS_BLINDED 16 + +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); + +void BN_GENCB_set(BN_GENCB *callback, + int (*f)(int event, int n, struct bn_gencb_st *), + void *arg) { + callback->callback = f; + callback->arg = arg; +} + +int BN_GENCB_call(BN_GENCB *callback, int event, int n) { + if (!callback) { + return 1; + } + + return callback->callback(event, n, callback); +} + +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); + + if (bits < 2) { + // There are no prime numbers this small. + OPENSSL_PUT_ERROR(BN, BN_R_BITS_TOO_SMALL); + return 0; + } else if (bits == 2 && safe) { + // The smallest safe prime (7) is three bits. + OPENSSL_PUT_ERROR(BN, BN_R_BITS_TOO_SMALL); + return 0; + } + + 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_GENCB_call(cb, BN_GENCB_GENERATED, c1++)) { + // aborted + goto err; + } + + if (!safe) { + i = BN_is_prime_fasttest_ex(ret, checks, ctx, 0, cb); + if (i == -1) { + goto err; + } else 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, NULL); + if (j == -1) { + goto err; + } else if (j == 0) { + goto loop; + } + + j = BN_is_prime_fasttest_ex(t, 1, ctx, 0, NULL); + if (j == -1) { + goto err; + } else if (j == 0) { + goto loop; + } + + if (!BN_GENCB_call(cb, i, 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); + } + + return found; +} + +// The following functions use a Barrett reduction variant to avoid leaking the +// numerator. See http://ridiculousfish.com/blog/posts/labor-of-division-episode-i.html +// +// We use 32-bit numerator and 16-bit divisor for simplicity. This allows +// computing |m| and |q| without architecture-specific code. + +// mod_u16 returns |n| mod |d|. |p| and |m| are the "magic numbers" for |d| (see +// reference). For proof of correctness in Coq, see +// https://github.com/davidben/fiat-crypto/blob/barrett/src/Arithmetic/BarrettReduction/RidiculousFish.v +// Note the Coq version of |mod_u16| additionally includes the computation of +// |p| and |m| from |bn_mod_u16_consttime| below. +static uint16_t mod_u16(uint32_t n, uint16_t d, uint32_t p, uint32_t m) { + // Compute floor(n/d) per steps 3 through 5. + uint32_t q = ((uint64_t)m * n) >> 32; + // Note there is a typo in the reference. We right-shift by one, not two. + uint32_t t = ((n - q) >> 1) + q; + t = t >> (p - 1); + + // Multiply and subtract to get the remainder. + n -= d * t; + assert(n < d); + return n; +} + +// shift_and_add_mod_u16 returns |r| * 2^32 + |a| mod |d|. |p| and |m| are the +// "magic numbers" for |d| (see reference). +static uint16_t shift_and_add_mod_u16(uint16_t r, uint32_t a, uint16_t d, + uint32_t p, uint32_t m) { + // Incorporate |a| in two 16-bit chunks. + uint32_t t = r; + t <<= 16; + t |= a >> 16; + t = mod_u16(t, d, p, m); + + t <<= 16; + t |= a & 0xffff; + t = mod_u16(t, d, p, m); + return t; +} + +uint16_t bn_mod_u16_consttime(const BIGNUM *bn, uint16_t d) { + if (d <= 1) { + return 0; + } + + // Compute the "magic numbers" for |d|. See steps 1 and 2. + // This computes p = ceil(log_2(d)). + uint32_t p = BN_num_bits_word(d - 1); + // This operation is not constant-time, but |p| and |d| are public values. + // Note that |p| is at most 16, so the computation fits in |uint64_t|. + assert(p <= 16); + uint32_t m = ((UINT64_C(1) << (32 + p)) + d - 1) / d; + + uint16_t ret = 0; + for (int i = bn->width - 1; i >= 0; i--) { +#if BN_BITS2 == 32 + ret = shift_and_add_mod_u16(ret, bn->d[i], d, p, m); +#elif BN_BITS2 == 64 + ret = shift_and_add_mod_u16(ret, bn->d[i] >> 32, d, p, m); + ret = shift_and_add_mod_u16(ret, bn->d[i] & 0xffffffff, d, p, m); +#else +#error "Unknown BN_ULONG size" +#endif + } + return ret; +} + +static int bn_trial_division(uint16_t *out, const BIGNUM *bn) { + for (int i = 1; i < NUMPRIMES; i++) { + if (bn_mod_u16_consttime(bn, primes[i]) == 0) { + *out = primes[i]; + return 1; + } + } + return 0; +} + +int bn_odd_number_is_obviously_composite(const BIGNUM *bn) { + uint16_t prime; + return bn_trial_division(&prime, bn) && !BN_is_word(bn, prime); +} + +int BN_primality_test(int *is_probably_prime, const BIGNUM *w, + int iterations, BN_CTX *ctx, int do_trial_division, + BN_GENCB *cb) { + *is_probably_prime = 0; + + // To support RSA key generation, this function should treat |w| as secret if + // it is a large prime. Composite numbers are discarded, so they may return + // early. + + if (BN_cmp(w, BN_value_one()) <= 0) { + return 1; + } + + if (!BN_is_odd(w)) { + // The only even prime is two. + *is_probably_prime = BN_is_word(w, 2); + return 1; + } + + // Miller-Rabin does not work for three. + if (BN_is_word(w, 3)) { + *is_probably_prime = 1; + return 1; + } + + if (do_trial_division) { + // Perform additional trial division checks to discard small primes. + uint16_t prime; + if (bn_trial_division(&prime, w)) { + *is_probably_prime = BN_is_word(w, prime); + return 1; + } + if (!BN_GENCB_call(cb, 1, -1)) { + return 0; + } + } + + if (iterations == BN_prime_checks) { + iterations = BN_prime_checks_for_size(BN_num_bits(w)); + } + + // See C.3.1 from FIPS 186-4. + int ret = 0; + BN_MONT_CTX *mont = NULL; + BN_CTX_start(ctx); + BIGNUM *w1 = BN_CTX_get(ctx); + if (w1 == NULL || + !bn_usub_consttime(w1, w, BN_value_one())) { + goto err; + } + + // Write w1 as m * 2^a (Steps 1 and 2). + int w_len = BN_num_bits(w); + int a = BN_count_low_zero_bits(w1); + BIGNUM *m = BN_CTX_get(ctx); + if (m == NULL || + !bn_rshift_secret_shift(m, w1, a, ctx)) { + goto err; + } + + // Montgomery setup for computations mod w. Additionally, compute 1 and w - 1 + // in the Montgomery domain for later comparisons. + BIGNUM *b = BN_CTX_get(ctx); + BIGNUM *z = BN_CTX_get(ctx); + BIGNUM *one_mont = BN_CTX_get(ctx); + BIGNUM *w1_mont = BN_CTX_get(ctx); + mont = BN_MONT_CTX_new_for_modulus(w, ctx); + if (b == NULL || z == NULL || one_mont == NULL || w1_mont == NULL || + mont == NULL || + !bn_one_to_montgomery(one_mont, mont, ctx) || + // w - 1 is -1 mod w, so we can compute it in the Montgomery domain, -R, + // with a subtraction. (|one_mont| cannot be zero.) + !bn_usub_consttime(w1_mont, w, one_mont)) { + goto err; + } + + // The following loop performs in inner iteration of the Miller-Rabin + // Primality test (Step 4). + // + // The algorithm as specified in FIPS 186-4 leaks information on |w|, the RSA + // private key. Instead, we run through each iteration unconditionally, + // performing modular multiplications, masking off any effects to behave + // equivalently to the specified algorithm. + // + // We also blind the number of values of |b| we try. Steps 4.1–4.2 say to + // discard out-of-range values. To avoid leaking information on |w|, we use + // |bn_rand_secret_range| which, rather than discarding bad values, adjusts + // them to be in range. Though not uniformly selected, these adjusted values + // are still usable as Rabin-Miller checks. + // + // Rabin-Miller is already probabilistic, so we could reach the desired + // confidence levels by just suitably increasing the iteration count. However, + // to align with FIPS 186-4, we use a more pessimal analysis: we do not count + // the non-uniform values towards the iteration count. As a result, this + // function is more complex and has more timing risk than necessary. + // + // We count both total iterations and uniform ones and iterate until we've + // reached at least |BN_PRIME_CHECKS_BLINDED| and |iterations|, respectively. + // If the latter is large enough, it will be the limiting factor with high + // probability and we won't leak information. + // + // Note this blinding does not impact most calls when picking primes because + // composites are rejected early. Only the two secret primes see extra work. + + crypto_word_t uniform_iterations = 0; + // Using |constant_time_lt_w| seems to prevent the compiler from optimizing + // this into two jumps. + for (int i = 1; (i <= BN_PRIME_CHECKS_BLINDED) | + constant_time_lt_w(uniform_iterations, iterations); + i++) { + int is_uniform; + if (// Step 4.1-4.2 + !bn_rand_secret_range(b, &is_uniform, 2, w1) || + // Step 4.3 + !BN_mod_exp_mont_consttime(z, b, m, w, ctx, mont)) { + goto err; + } + uniform_iterations += is_uniform; + + // loop_done is all ones if the loop has completed and all zeros otherwise. + crypto_word_t loop_done = 0; + // next_iteration is all ones if we should continue to the next iteration + // (|b| is not a composite witness for |w|). This is equivalent to going to + // step 4.7 in the original algorithm. + crypto_word_t next_iteration = 0; + + // Step 4.4. If z = 1 or z = w-1, mask off the loop and continue to the next + // iteration (go to step 4.7). + loop_done = BN_equal_consttime(z, BN_value_one()) | + BN_equal_consttime(z, w1); + loop_done = 0 - loop_done; // Make it all zeros or all ones. + next_iteration = loop_done; // Go to step 4.7 if |loop_done|. + + // Step 4.5. We use Montgomery-encoding for better performance and to avoid + // timing leaks. + if (!BN_to_montgomery(z, z, mont, ctx)) { + goto err; + } + + // To avoid leaking |a|, we run the loop to |w_len| and mask off all + // iterations once |j| = |a|. + for (int j = 1; j < w_len; j++) { + loop_done |= constant_time_eq_int(j, a); + + // Step 4.5.1. + if (!BN_mod_mul_montgomery(z, z, z, mont, ctx)) { + goto err; + } + + // Step 4.5.2. If z = w-1 and the loop is not done, run through the next + // iteration. + crypto_word_t z_is_w1_mont = BN_equal_consttime(z, w1_mont) & ~loop_done; + z_is_w1_mont = 0 - z_is_w1_mont; // Make it all zeros or all ones. + loop_done |= z_is_w1_mont; + next_iteration |= z_is_w1_mont; // Go to step 4.7 if |z_is_w1_mont|. + + // Step 4.5.3. If z = 1 and the loop is not done, w is composite and we + // may exit in variable time. + if (BN_equal_consttime(z, one_mont) & ~loop_done) { + assert(!next_iteration); + break; + } + } + + if (!next_iteration) { + // Step 4.6. We did not see z = w-1 before z = 1, so w must be composite. + // (For any prime, the value of z immediately preceding 1 must be -1. + // There are no non-trivial square roots of 1 modulo a prime.) + *is_probably_prime = 0; + ret = 1; + goto err; + } + + // Step 4.7 + if (!BN_GENCB_call(cb, 1, i)) { + goto err; + } + } + + assert(uniform_iterations >= (crypto_word_t)iterations); + *is_probably_prime = 1; + ret = 1; + +err: + BN_MONT_CTX_free(mont); + BN_CTX_end(ctx); + return ret; +} + +int BN_is_prime_ex(const BIGNUM *candidate, int checks, BN_CTX *ctx, BN_GENCB *cb) { + return BN_is_prime_fasttest_ex(candidate, checks, ctx, 0, cb); +} + +int BN_is_prime_fasttest_ex(const BIGNUM *a, int checks, BN_CTX *ctx, + int do_trial_division, BN_GENCB *cb) { + int is_probably_prime; + if (!BN_primality_test(&is_probably_prime, a, checks, ctx, do_trial_division, + cb)) { + return -1; + } + return is_probably_prime; +} + +int BN_enhanced_miller_rabin_primality_test( + enum bn_primality_result_t *out_result, const BIGNUM *w, int iterations, + BN_CTX *ctx, BN_GENCB *cb) { + // Enhanced Miller-Rabin is only valid on odd integers greater than 3. + if (!BN_is_odd(w) || BN_cmp_word(w, 3) <= 0) { + OPENSSL_PUT_ERROR(BN, BN_R_INVALID_INPUT); + return 0; + } + + if (iterations == BN_prime_checks) { + iterations = BN_prime_checks_for_size(BN_num_bits(w)); + } + + int ret = 0; + BN_MONT_CTX *mont = NULL; + + BN_CTX_start(ctx); + + BIGNUM *w1 = BN_CTX_get(ctx); + if (w1 == NULL || + !BN_copy(w1, w) || + !BN_sub_word(w1, 1)) { + goto err; + } + + // Write w1 as m*2^a (Steps 1 and 2). + int a = 0; + while (!BN_is_bit_set(w1, a)) { + a++; + } + BIGNUM *m = BN_CTX_get(ctx); + if (m == NULL || + !BN_rshift(m, w1, a)) { + goto err; + } + + BIGNUM *b = BN_CTX_get(ctx); + BIGNUM *g = BN_CTX_get(ctx); + BIGNUM *z = BN_CTX_get(ctx); + BIGNUM *x = BN_CTX_get(ctx); + BIGNUM *x1 = BN_CTX_get(ctx); + if (b == NULL || + g == NULL || + z == NULL || + x == NULL || + x1 == NULL) { + goto err; + } + + // Montgomery setup for computations mod w + mont = BN_MONT_CTX_new_for_modulus(w, ctx); + if (mont == NULL) { + goto err; + } + + // The following loop performs in inner iteration of the Enhanced Miller-Rabin + // Primality test (Step 4). + for (int i = 1; i <= iterations; i++) { + // Step 4.1-4.2 + if (!BN_rand_range_ex(b, 2, w1)) { + goto err; + } + + // Step 4.3-4.4 + if (!BN_gcd(g, b, w, ctx)) { + goto err; + } + if (BN_cmp_word(g, 1) > 0) { + *out_result = bn_composite; + ret = 1; + goto err; + } + + // Step 4.5 + if (!BN_mod_exp_mont(z, b, m, w, ctx, mont)) { + goto err; + } + + // Step 4.6 + if (BN_is_one(z) || BN_cmp(z, w1) == 0) { + goto loop; + } + + // Step 4.7 + for (int j = 1; j < a; j++) { + if (!BN_copy(x, z) || !BN_mod_mul(z, x, x, w, ctx)) { + goto err; + } + if (BN_cmp(z, w1) == 0) { + goto loop; + } + if (BN_is_one(z)) { + goto composite; + } + } + + // Step 4.8-4.9 + if (!BN_copy(x, z) || !BN_mod_mul(z, x, x, w, ctx)) { + goto err; + } + + // Step 4.10-4.11 + if (!BN_is_one(z) && !BN_copy(x, z)) { + goto err; + } + + composite: + // Step 4.12-4.14 + if (!BN_copy(x1, x) || + !BN_sub_word(x1, 1) || + !BN_gcd(g, x1, w, ctx)) { + goto err; + } + if (BN_cmp_word(g, 1) > 0) { + *out_result = bn_composite; + } else { + *out_result = bn_non_prime_power_composite; + } + + ret = 1; + goto err; + + loop: + // Step 4.15 + if (!BN_GENCB_call(cb, 1, i)) { + goto err; + } + } + + *out_result = bn_probably_prime; + ret = 1; + +err: + BN_MONT_CTX_free(mont); + BN_CTX_end(ctx); + + return ret; +} + +static int probable_prime(BIGNUM *rnd, int bits) { + int i; + uint16_t mods[NUMPRIMES]; + BN_ULONG delta; + BN_ULONG maxdelta = BN_MASK2 - primes[NUMPRIMES - 1]; + char is_single_word = bits <= BN_BITS2; + +again: + if (!BN_rand(rnd, bits, BN_RAND_TOP_TWO, BN_RAND_BOTTOM_ODD)) { + return 0; + } + + // we now have a random number 'rnd' to test. + for (i = 1; i < NUMPRIMES; i++) { + mods[i] = bn_mod_u16_consttime(rnd, primes[i]); + } + // If bits is so small that it fits into a single word then we + // additionally don't want to exceed that many bits. + if (is_single_word) { + BN_ULONG size_limit; + if (bits == BN_BITS2) { + // Avoid undefined behavior. + size_limit = ~((BN_ULONG)0) - BN_get_word(rnd); + } else { + size_limit = (((BN_ULONG)1) << bits) - BN_get_word(rnd) - 1; + } + if (size_limit < maxdelta) { + maxdelta = size_limit; + } + } + delta = 0; + +loop: + if (is_single_word) { + BN_ULONG rnd_word = BN_get_word(rnd); + + // In the case that the candidate prime is a single word then + // we check that: + // 1) It's greater than primes[i] because we shouldn't reject + // 3 as being a prime number because it's a multiple of + // three. + // 2) That it's not a multiple of a known prime. We don't + // check that rnd-1 is also coprime to all the known + // primes because there aren't many small primes where + // that's true. + for (i = 1; i < NUMPRIMES && primes[i] < rnd_word; i++) { + if ((mods[i] + delta) % primes[i] == 0) { + delta += 2; + if (delta > maxdelta) { + goto again; + } + goto loop; + } + } + } else { + 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; + } + if (BN_num_bits(rnd) != (unsigned)bits) { + goto again; + } + + 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, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ODD)) { + 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_u16_consttime(rnd, primes[i]) <= 1) { + if (!BN_add(rnd, rnd, add)) { + goto err; + } + goto loop; + } + } + + ret = 1; + +err: + BN_CTX_end(ctx); + 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, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ODD)) { + 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_u16_consttime(p, primes[i]) == 0 || + bn_mod_u16_consttime(q, 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); + return ret; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/random.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/random.c new file mode 100644 index 0000000..fb39e53 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/random.c @@ -0,0 +1,351 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 +#include +#include +#include + +#include "internal.h" +#include "../../internal.h" +#include "../rand/internal.h" + + +int BN_rand(BIGNUM *rnd, int bits, int top, int bottom) { + uint8_t *buf = NULL; + int ret = 0, bit, bytes, mask; + + if (rnd == NULL) { + return 0; + } + + if (top != BN_RAND_TOP_ANY && top != BN_RAND_TOP_ONE && + top != BN_RAND_TOP_TWO) { + OPENSSL_PUT_ERROR(BN, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + + if (bottom != BN_RAND_BOTTOM_ANY && bottom != BN_RAND_BOTTOM_ODD) { + OPENSSL_PUT_ERROR(BN, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + + if (bits == 0) { + BN_zero(rnd); + return 1; + } + + bytes = (bits + 7) / 8; + bit = (bits - 1) % 8; + mask = 0xff << (bit + 1); + + buf = OPENSSL_malloc(bytes); + if (buf == NULL) { + OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE); + goto err; + } + + // Make a random number and set the top and bottom bits. + RAND_bytes(buf, bytes); + + if (top != BN_RAND_TOP_ANY) { + if (top == BN_RAND_TOP_TWO && bits > 1) { + if (bit == 0) { + buf[0] = 1; + buf[1] |= 0x80; + } else { + buf[0] |= (3 << (bit - 1)); + } + } else { + buf[0] |= (1 << bit); + } + } + + buf[0] &= ~mask; + + // Set the bottom bit if requested, + if (bottom == BN_RAND_BOTTOM_ODD) { + buf[bytes - 1] |= 1; + } + + if (!BN_bin2bn(buf, bytes, rnd)) { + goto err; + } + + ret = 1; + +err: + OPENSSL_free(buf); + return ret; +} + +int BN_pseudo_rand(BIGNUM *rnd, int bits, int top, int bottom) { + return BN_rand(rnd, bits, top, bottom); +} + +// bn_less_than_word_mask returns a mask of all ones if the number represented +// by |len| words at |a| is less than |b| and zero otherwise. It performs this +// computation in time independent of the value of |a|. |b| is assumed public. +static crypto_word_t bn_less_than_word_mask(const BN_ULONG *a, size_t len, + BN_ULONG b) { + if (b == 0) { + return CONSTTIME_FALSE_W; + } + if (len == 0) { + return CONSTTIME_TRUE_W; + } + + // |a| < |b| iff a[1..len-1] are all zero and a[0] < b. + OPENSSL_COMPILE_ASSERT(sizeof(BN_ULONG) <= sizeof(crypto_word_t), + crypto_word_t_too_small); + crypto_word_t mask = 0; + for (size_t i = 1; i < len; i++) { + mask |= a[i]; + } + // |mask| is now zero iff a[1..len-1] are all zero. + mask = constant_time_is_zero_w(mask); + mask &= constant_time_lt_w(a[0], b); + return mask; +} + +int bn_in_range_words(const BN_ULONG *a, BN_ULONG min_inclusive, + const BN_ULONG *max_exclusive, size_t len) { + crypto_word_t mask = ~bn_less_than_word_mask(a, len, min_inclusive); + return mask & bn_less_than_words(a, max_exclusive, len); +} + +static int bn_range_to_mask(size_t *out_words, BN_ULONG *out_mask, + size_t min_inclusive, const BN_ULONG *max_exclusive, + size_t len) { + // The magnitude of |max_exclusive| is assumed public. + size_t words = len; + while (words > 0 && max_exclusive[words - 1] == 0) { + words--; + } + if (words == 0 || + (words == 1 && max_exclusive[0] <= min_inclusive)) { + OPENSSL_PUT_ERROR(BN, BN_R_INVALID_RANGE); + return 0; + } + BN_ULONG mask = max_exclusive[words - 1]; + // This sets all bits in |mask| below the most significant bit. + mask |= mask >> 1; + mask |= mask >> 2; + mask |= mask >> 4; + mask |= mask >> 8; + mask |= mask >> 16; +#if defined(OPENSSL_64_BIT) + mask |= mask >> 32; +#endif + + *out_words = words; + *out_mask = mask; + return 1; +} + +int bn_rand_range_words(BN_ULONG *out, BN_ULONG min_inclusive, + const BN_ULONG *max_exclusive, size_t len, + const uint8_t additional_data[32]) { + // This function implements the equivalent of steps 4 through 7 of FIPS 186-4 + // appendices B.4.2 and B.5.2. When called in those contexts, |max_exclusive| + // is n and |min_inclusive| is one. + + // Compute the bit length of |max_exclusive| (step 1), in terms of a number of + // |words| worth of entropy to fill and a mask of bits to clear in the top + // word. + size_t words; + BN_ULONG mask; + if (!bn_range_to_mask(&words, &mask, min_inclusive, max_exclusive, len)) { + return 0; + } + + // Fill any unused words with zero. + OPENSSL_memset(out + words, 0, (len - words) * sizeof(BN_ULONG)); + + unsigned count = 100; + do { + if (!--count) { + OPENSSL_PUT_ERROR(BN, BN_R_TOO_MANY_ITERATIONS); + return 0; + } + + // Steps 4 and 5. Use |words| and |mask| together to obtain a string of N + // bits, where N is the bit length of |max_exclusive|. + RAND_bytes_with_additional_data((uint8_t *)out, words * sizeof(BN_ULONG), + additional_data); + out[words - 1] &= mask; + + // If out >= max_exclusive or out < min_inclusive, retry. This implements + // the equivalent of steps 6 and 7 without leaking the value of |out|. + } while (!bn_in_range_words(out, min_inclusive, max_exclusive, words)); + return 1; +} + +int BN_rand_range_ex(BIGNUM *r, BN_ULONG min_inclusive, + const BIGNUM *max_exclusive) { + static const uint8_t kDefaultAdditionalData[32] = {0}; + if (!bn_wexpand(r, max_exclusive->width) || + !bn_rand_range_words(r->d, min_inclusive, max_exclusive->d, + max_exclusive->width, kDefaultAdditionalData)) { + return 0; + } + + r->neg = 0; + r->width = max_exclusive->width; + return 1; +} + +int bn_rand_secret_range(BIGNUM *r, int *out_is_uniform, BN_ULONG min_inclusive, + const BIGNUM *max_exclusive) { + size_t words; + BN_ULONG mask; + if (!bn_range_to_mask(&words, &mask, min_inclusive, max_exclusive->d, + max_exclusive->width) || + !bn_wexpand(r, words)) { + return 0; + } + + assert(words > 0); + assert(mask != 0); + // The range must be large enough for bit tricks to fix invalid values. + if (words == 1 && min_inclusive > mask >> 1) { + OPENSSL_PUT_ERROR(BN, BN_R_INVALID_RANGE); + return 0; + } + + // Select a uniform random number with num_bits(max_exclusive) bits. + RAND_bytes((uint8_t *)r->d, words * sizeof(BN_ULONG)); + r->d[words - 1] &= mask; + + // Check, in constant-time, if the value is in range. + *out_is_uniform = + bn_in_range_words(r->d, min_inclusive, max_exclusive->d, words); + crypto_word_t in_range = *out_is_uniform; + in_range = 0 - in_range; + + // If the value is not in range, force it to be in range. + r->d[0] |= constant_time_select_w(in_range, 0, min_inclusive); + r->d[words - 1] &= constant_time_select_w(in_range, BN_MASK2, mask >> 1); + assert(bn_in_range_words(r->d, min_inclusive, max_exclusive->d, words)); + + r->neg = 0; + r->width = words; + return 1; +} + +int BN_rand_range(BIGNUM *r, const BIGNUM *range) { + return BN_rand_range_ex(r, 0, range); +} + +int BN_pseudo_rand_range(BIGNUM *r, const BIGNUM *range) { + return BN_rand_range(r, range); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/random.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/random.c.grpc_back new file mode 100644 index 0000000..5922df4 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/random.c.grpc_back @@ -0,0 +1,351 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 +#include +#include +#include + +#include "internal.h" +#include "../../internal.h" +#include "../rand/internal.h" + + +int BN_rand(BIGNUM *rnd, int bits, int top, int bottom) { + uint8_t *buf = NULL; + int ret = 0, bit, bytes, mask; + + if (rnd == NULL) { + return 0; + } + + if (top != BN_RAND_TOP_ANY && top != BN_RAND_TOP_ONE && + top != BN_RAND_TOP_TWO) { + OPENSSL_PUT_ERROR(BN, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + + if (bottom != BN_RAND_BOTTOM_ANY && bottom != BN_RAND_BOTTOM_ODD) { + OPENSSL_PUT_ERROR(BN, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + + if (bits == 0) { + BN_zero(rnd); + return 1; + } + + bytes = (bits + 7) / 8; + bit = (bits - 1) % 8; + mask = 0xff << (bit + 1); + + buf = OPENSSL_malloc(bytes); + if (buf == NULL) { + OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE); + goto err; + } + + // Make a random number and set the top and bottom bits. + RAND_bytes(buf, bytes); + + if (top != BN_RAND_TOP_ANY) { + if (top == BN_RAND_TOP_TWO && bits > 1) { + if (bit == 0) { + buf[0] = 1; + buf[1] |= 0x80; + } else { + buf[0] |= (3 << (bit - 1)); + } + } else { + buf[0] |= (1 << bit); + } + } + + buf[0] &= ~mask; + + // Set the bottom bit if requested, + if (bottom == BN_RAND_BOTTOM_ODD) { + buf[bytes - 1] |= 1; + } + + if (!BN_bin2bn(buf, bytes, rnd)) { + goto err; + } + + ret = 1; + +err: + OPENSSL_free(buf); + return ret; +} + +int BN_pseudo_rand(BIGNUM *rnd, int bits, int top, int bottom) { + return BN_rand(rnd, bits, top, bottom); +} + +// bn_less_than_word_mask returns a mask of all ones if the number represented +// by |len| words at |a| is less than |b| and zero otherwise. It performs this +// computation in time independent of the value of |a|. |b| is assumed public. +static crypto_word_t bn_less_than_word_mask(const BN_ULONG *a, size_t len, + BN_ULONG b) { + if (b == 0) { + return CONSTTIME_FALSE_W; + } + if (len == 0) { + return CONSTTIME_TRUE_W; + } + + // |a| < |b| iff a[1..len-1] are all zero and a[0] < b. + OPENSSL_COMPILE_ASSERT(sizeof(BN_ULONG) <= sizeof(crypto_word_t), + crypto_word_t_too_small); + crypto_word_t mask = 0; + for (size_t i = 1; i < len; i++) { + mask |= a[i]; + } + // |mask| is now zero iff a[1..len-1] are all zero. + mask = constant_time_is_zero_w(mask); + mask &= constant_time_lt_w(a[0], b); + return mask; +} + +int bn_in_range_words(const BN_ULONG *a, BN_ULONG min_inclusive, + const BN_ULONG *max_exclusive, size_t len) { + crypto_word_t mask = ~bn_less_than_word_mask(a, len, min_inclusive); + return mask & bn_less_than_words(a, max_exclusive, len); +} + +static int bn_range_to_mask(size_t *out_words, BN_ULONG *out_mask, + size_t min_inclusive, const BN_ULONG *max_exclusive, + size_t len) { + // The magnitude of |max_exclusive| is assumed public. + size_t words = len; + while (words > 0 && max_exclusive[words - 1] == 0) { + words--; + } + if (words == 0 || + (words == 1 && max_exclusive[0] <= min_inclusive)) { + OPENSSL_PUT_ERROR(BN, BN_R_INVALID_RANGE); + return 0; + } + BN_ULONG mask = max_exclusive[words - 1]; + // This sets all bits in |mask| below the most significant bit. + mask |= mask >> 1; + mask |= mask >> 2; + mask |= mask >> 4; + mask |= mask >> 8; + mask |= mask >> 16; +#if defined(OPENSSL_64_BIT) + mask |= mask >> 32; +#endif + + *out_words = words; + *out_mask = mask; + return 1; +} + +int bn_rand_range_words(BN_ULONG *out, BN_ULONG min_inclusive, + const BN_ULONG *max_exclusive, size_t len, + const uint8_t additional_data[32]) { + // This function implements the equivalent of steps 4 through 7 of FIPS 186-4 + // appendices B.4.2 and B.5.2. When called in those contexts, |max_exclusive| + // is n and |min_inclusive| is one. + + // Compute the bit length of |max_exclusive| (step 1), in terms of a number of + // |words| worth of entropy to fill and a mask of bits to clear in the top + // word. + size_t words; + BN_ULONG mask; + if (!bn_range_to_mask(&words, &mask, min_inclusive, max_exclusive, len)) { + return 0; + } + + // Fill any unused words with zero. + OPENSSL_memset(out + words, 0, (len - words) * sizeof(BN_ULONG)); + + unsigned count = 100; + do { + if (!--count) { + OPENSSL_PUT_ERROR(BN, BN_R_TOO_MANY_ITERATIONS); + return 0; + } + + // Steps 4 and 5. Use |words| and |mask| together to obtain a string of N + // bits, where N is the bit length of |max_exclusive|. + RAND_bytes_with_additional_data((uint8_t *)out, words * sizeof(BN_ULONG), + additional_data); + out[words - 1] &= mask; + + // If out >= max_exclusive or out < min_inclusive, retry. This implements + // the equivalent of steps 6 and 7 without leaking the value of |out|. + } while (!bn_in_range_words(out, min_inclusive, max_exclusive, words)); + return 1; +} + +int BN_rand_range_ex(BIGNUM *r, BN_ULONG min_inclusive, + const BIGNUM *max_exclusive) { + static const uint8_t kDefaultAdditionalData[32] = {0}; + if (!bn_wexpand(r, max_exclusive->width) || + !bn_rand_range_words(r->d, min_inclusive, max_exclusive->d, + max_exclusive->width, kDefaultAdditionalData)) { + return 0; + } + + r->neg = 0; + r->width = max_exclusive->width; + return 1; +} + +int bn_rand_secret_range(BIGNUM *r, int *out_is_uniform, BN_ULONG min_inclusive, + const BIGNUM *max_exclusive) { + size_t words; + BN_ULONG mask; + if (!bn_range_to_mask(&words, &mask, min_inclusive, max_exclusive->d, + max_exclusive->width) || + !bn_wexpand(r, words)) { + return 0; + } + + assert(words > 0); + assert(mask != 0); + // The range must be large enough for bit tricks to fix invalid values. + if (words == 1 && min_inclusive > mask >> 1) { + OPENSSL_PUT_ERROR(BN, BN_R_INVALID_RANGE); + return 0; + } + + // Select a uniform random number with num_bits(max_exclusive) bits. + RAND_bytes((uint8_t *)r->d, words * sizeof(BN_ULONG)); + r->d[words - 1] &= mask; + + // Check, in constant-time, if the value is in range. + *out_is_uniform = + bn_in_range_words(r->d, min_inclusive, max_exclusive->d, words); + crypto_word_t in_range = *out_is_uniform; + in_range = 0 - in_range; + + // If the value is not in range, force it to be in range. + r->d[0] |= constant_time_select_w(in_range, 0, min_inclusive); + r->d[words - 1] &= constant_time_select_w(in_range, BN_MASK2, mask >> 1); + assert(bn_in_range_words(r->d, min_inclusive, max_exclusive->d, words)); + + r->neg = 0; + r->width = words; + return 1; +} + +int BN_rand_range(BIGNUM *r, const BIGNUM *range) { + return BN_rand_range_ex(r, 0, range); +} + +int BN_pseudo_rand_range(BIGNUM *r, const BIGNUM *range) { + return BN_rand_range(r, range); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/rsaz_exp.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/rsaz_exp.c new file mode 100644 index 0000000..bc90f05 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/rsaz_exp.c @@ -0,0 +1,231 @@ +/* + * Copyright 2013-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright (c) 2012, Intel Corporation. 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 + * + * Originally written by Shay Gueron (1, 2), and Vlad Krasnov (1) + * (1) Intel Corporation, Israel Development Center, Haifa, Israel + * (2) University of Haifa, Israel + */ + +#include + +#if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64) + +#include "rsaz_exp.h" + +#include + +#include "../../internal.h" + + +// 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); + +// one is 1 in RSAZ's representation. +alignas(64) 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}; +// two80 is 2^80 in RSAZ's representation. Note RSAZ uses base 2^29, so this is +// 2^(29*2 + 22) = 2^80, not 2^(64*2 + 22). +alignas(64) 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) { + alignas(64) uint8_t storage[(320 * 3) + (32 * 9 * 16)]; // 5.5KB + unsigned char *a_inv, *m, *result, *table_s = storage + (320 * 3), + *R2 = table_s; // borrow + if (((((uintptr_t)storage & 4095) + 320) >> 12) != 0) { + result = storage; + a_inv = storage + 320; + m = storage + (320 * 2); // should not cross page + } else { + m = storage; // should not cross page + result = storage + 320; + a_inv = storage + (320 * 2); + } + + rsaz_1024_norm2red_avx2(m, m_norm); + rsaz_1024_norm2red_avx2(a_inv, base_norm); + rsaz_1024_norm2red_avx2(R2, RR); + + // Convert |R2| from the usual radix, giving R = 2^1024, to RSAZ's radix, + // giving R = 2^(36*29) = 2^1044. + rsaz_1024_mul_avx2(R2, R2, R2, m, k0); + // R2 = 2^2048 * 2^2048 / 2^1044 = 2^3052 + rsaz_1024_mul_avx2(R2, R2, two80, m, k0); + // R2 = 2^3052 * 2^80 / 2^1044 = 2^2088 = (2^1044)^2 + + // 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 (int 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 + + const uint8_t *p_str = (const uint8_t *)exponent; + + // load first window + int wvalue = p_str[127] >> 3; + rsaz_1024_gather5_avx2(result, table_s, wvalue); + + int index = 1014; + while (index > -1) { // Loop for the remaining 127 windows. + + rsaz_1024_sqr_avx2(result, result, m, k0, 5); + + uint16_t wvalue_16; + memcpy(&wvalue_16, &p_str[index / 8], sizeof(wvalue_16)); + wvalue = wvalue_16; + 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); + + // Convert from Montgomery. + rsaz_1024_mul_avx2(result, result, one, m, k0); + + rsaz_1024_red2norm_avx2(result_norm, result); + + OPENSSL_cleanse(storage, sizeof(storage)); +} + +#endif // OPENSSL_X86_64 diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/rsaz_exp.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/rsaz_exp.c.grpc_back new file mode 100644 index 0000000..97c58ba --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/rsaz_exp.c.grpc_back @@ -0,0 +1,231 @@ +/* + * Copyright 2013-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright (c) 2012, Intel Corporation. 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 + * + * Originally written by Shay Gueron (1, 2), and Vlad Krasnov (1) + * (1) Intel Corporation, Israel Development Center, Haifa, Israel + * (2) University of Haifa, Israel + */ + +#include + +#if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64) + +#include "rsaz_exp.h" + +#include + +#include "../../internal.h" + + +// 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); + +// one is 1 in RSAZ's representation. +alignas(64) 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}; +// two80 is 2^80 in RSAZ's representation. Note RSAZ uses base 2^29, so this is +// 2^(29*2 + 22) = 2^80, not 2^(64*2 + 22). +alignas(64) 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) { + alignas(64) uint8_t storage[(320 * 3) + (32 * 9 * 16)]; // 5.5KB + unsigned char *a_inv, *m, *result, *table_s = storage + (320 * 3), + *R2 = table_s; // borrow + if (((((uintptr_t)storage & 4095) + 320) >> 12) != 0) { + result = storage; + a_inv = storage + 320; + m = storage + (320 * 2); // should not cross page + } else { + m = storage; // should not cross page + result = storage + 320; + a_inv = storage + (320 * 2); + } + + rsaz_1024_norm2red_avx2(m, m_norm); + rsaz_1024_norm2red_avx2(a_inv, base_norm); + rsaz_1024_norm2red_avx2(R2, RR); + + // Convert |R2| from the usual radix, giving R = 2^1024, to RSAZ's radix, + // giving R = 2^(36*29) = 2^1044. + rsaz_1024_mul_avx2(R2, R2, R2, m, k0); + // R2 = 2^2048 * 2^2048 / 2^1044 = 2^3052 + rsaz_1024_mul_avx2(R2, R2, two80, m, k0); + // R2 = 2^3052 * 2^80 / 2^1044 = 2^2088 = (2^1044)^2 + + // 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 (int 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 + + const uint8_t *p_str = (const uint8_t *)exponent; + + // load first window + int wvalue = p_str[127] >> 3; + rsaz_1024_gather5_avx2(result, table_s, wvalue); + + int index = 1014; + while (index > -1) { // Loop for the remaining 127 windows. + + rsaz_1024_sqr_avx2(result, result, m, k0, 5); + + uint16_t wvalue_16; + memcpy(&wvalue_16, &p_str[index / 8], sizeof(wvalue_16)); + wvalue = wvalue_16; + 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); + + // Convert from Montgomery. + rsaz_1024_mul_avx2(result, result, one, m, k0); + + rsaz_1024_red2norm_avx2(result_norm, result); + + OPENSSL_cleanse(storage, sizeof(storage)); +} + +#endif // OPENSSL_X86_64 diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/rsaz_exp.h b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/rsaz_exp.h new file mode 100644 index 0000000..49c5fc0 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/rsaz_exp.h @@ -0,0 +1,33 @@ +/* + * Copyright 2013-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright (c) 2012, Intel Corporation. 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 + * + * Originally written by Shay Gueron (1, 2), and Vlad Krasnov (1) + * (1) Intel Corporation, Israel Development Center, Haifa, Israel + * (2) University of Haifa, Israel + */ + +#ifndef OPENSSL_HEADER_BN_RSAZ_EXP_H +#define OPENSSL_HEADER_BN_RSAZ_EXP_H + +#include + +// RSAZ_1024_mod_exp_avx2 sets |result| to |base_norm| raised to |exponent| +// modulo |m_norm|. |base_norm| must be fully-reduced and |exponent| must have +// the high bit set (it is 1024 bits wide). |RR| and |k0| must be |RR| and |n0|, +// respectively, extracted from |m_norm|'s |BN_MONT_CTX|. +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); + +// rsaz_avx2_eligible returns one if |RSAZ_1024_mod_exp_avx2| should be used and +// zero otherwise. +int rsaz_avx2_eligible(void); + +#endif // OPENSSL_HEADER_BN_RSAZ_EXP_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/rsaz_exp.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/rsaz_exp.h.grpc_back new file mode 100644 index 0000000..af973a5 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/rsaz_exp.h.grpc_back @@ -0,0 +1,33 @@ +/* + * Copyright 2013-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright (c) 2012, Intel Corporation. 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 + * + * Originally written by Shay Gueron (1, 2), and Vlad Krasnov (1) + * (1) Intel Corporation, Israel Development Center, Haifa, Israel + * (2) University of Haifa, Israel + */ + +#ifndef OPENSSL_HEADER_BN_RSAZ_EXP_H +#define OPENSSL_HEADER_BN_RSAZ_EXP_H + +#include + +// RSAZ_1024_mod_exp_avx2 sets |result| to |base_norm| raised to |exponent| +// modulo |m_norm|. |base_norm| must be fully-reduced and |exponent| must have +// the high bit set (it is 1024 bits wide). |RR| and |k0| must be |RR| and |n0|, +// respectively, extracted from |m_norm|'s |BN_MONT_CTX|. +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); + +// rsaz_avx2_eligible returns one if |RSAZ_1024_mod_exp_avx2| should be used and +// zero otherwise. +int rsaz_avx2_eligible(void); + +#endif // OPENSSL_HEADER_BN_RSAZ_EXP_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/shift.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/shift.c new file mode 100644 index 0000000..b250ac0 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/shift.c @@ -0,0 +1,364 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 "internal.h" + + +int BN_lshift(BIGNUM *r, const BIGNUM *a, int n) { + int i, nw, lb, rb; + BN_ULONG *t, *f; + BN_ULONG l; + + if (n < 0) { + OPENSSL_PUT_ERROR(BN, BN_R_NEGATIVE_NUMBER); + return 0; + } + + r->neg = a->neg; + nw = n / BN_BITS2; + if (!bn_wexpand(r, a->width + nw + 1)) { + return 0; + } + lb = n % BN_BITS2; + rb = BN_BITS2 - lb; + f = a->d; + t = r->d; + t[a->width + nw] = 0; + if (lb == 0) { + for (i = a->width - 1; i >= 0; i--) { + t[nw + i] = f[i]; + } + } else { + for (i = a->width - 1; i >= 0; i--) { + l = f[i]; + t[nw + i + 1] |= l >> rb; + t[nw + i] = l << lb; + } + } + OPENSSL_memset(t, 0, nw * sizeof(t[0])); + r->width = a->width + nw + 1; + bn_set_minimal_width(r); + + return 1; +} + +int BN_lshift1(BIGNUM *r, const BIGNUM *a) { + BN_ULONG *ap, *rp, t, c; + int i; + + if (r != a) { + r->neg = a->neg; + if (!bn_wexpand(r, a->width + 1)) { + return 0; + } + r->width = a->width; + } else { + if (!bn_wexpand(r, a->width + 1)) { + return 0; + } + } + ap = a->d; + rp = r->d; + c = 0; + for (i = 0; i < a->width; i++) { + t = *(ap++); + *(rp++) = (t << 1) | c; + c = t >> (BN_BITS2 - 1); + } + if (c) { + *rp = 1; + r->width++; + } + + return 1; +} + +static void bn_rshift_words(BN_ULONG *r, const BN_ULONG *a, unsigned shift, + size_t num) { + unsigned shift_bits = shift % BN_BITS2; + size_t shift_words = shift / BN_BITS2; + if (shift_words >= num) { + OPENSSL_memset(r, 0, num * sizeof(BN_ULONG)); + return; + } + if (shift_bits == 0) { + OPENSSL_memmove(r, a + shift_words, (num - shift_words) * sizeof(BN_ULONG)); + } else { + for (size_t i = shift_words; i < num - 1; i++) { + r[i - shift_words] = + (a[i] >> shift_bits) | (a[i + 1] << (BN_BITS2 - shift_bits)); + } + r[num - 1 - shift_words] = a[num - 1] >> shift_bits; + } + OPENSSL_memset(r + num - shift_words, 0, shift_words * sizeof(BN_ULONG)); +} + +int BN_rshift(BIGNUM *r, const BIGNUM *a, int n) { + if (n < 0) { + OPENSSL_PUT_ERROR(BN, BN_R_NEGATIVE_NUMBER); + return 0; + } + + if (!bn_wexpand(r, a->width)) { + return 0; + } + bn_rshift_words(r->d, a->d, n, a->width); + r->neg = a->neg; + r->width = a->width; + bn_set_minimal_width(r); + return 1; +} + +int bn_rshift_secret_shift(BIGNUM *r, const BIGNUM *a, unsigned n, + BN_CTX *ctx) { + int ret = 0; + BN_CTX_start(ctx); + BIGNUM *tmp = BN_CTX_get(ctx); + if (tmp == NULL || + !BN_copy(r, a) || + !bn_wexpand(tmp, r->width)) { + goto err; + } + + // Shift conditionally by powers of two. + unsigned max_bits = BN_BITS2 * r->width; + for (unsigned i = 0; (max_bits >> i) != 0; i++) { + BN_ULONG mask = (n >> i) & 1; + mask = 0 - mask; + bn_rshift_words(tmp->d, r->d, 1u << i, r->width); + bn_select_words(r->d, mask, tmp->d /* apply shift */, + r->d /* ignore shift */, r->width); + } + + ret = 1; + +err: + BN_CTX_end(ctx); + return ret; +} + +void bn_rshift1_words(BN_ULONG *r, const BN_ULONG *a, size_t num) { + if (num == 0) { + return; + } + for (size_t i = 0; i < num - 1; i++) { + r[i] = (a[i] >> 1) | (a[i + 1] << (BN_BITS2 - 1)); + } + r[num - 1] = a[num - 1] >> 1; +} + +int BN_rshift1(BIGNUM *r, const BIGNUM *a) { + if (!bn_wexpand(r, a->width)) { + return 0; + } + bn_rshift1_words(r->d, a->d, a->width); + r->width = a->width; + r->neg = a->neg; + bn_set_minimal_width(r); + return 1; +} + +int BN_set_bit(BIGNUM *a, int n) { + if (n < 0) { + return 0; + } + + int i = n / BN_BITS2; + int j = n % BN_BITS2; + if (a->width <= i) { + if (!bn_wexpand(a, i + 1)) { + return 0; + } + for (int k = a->width; k < i + 1; k++) { + a->d[k] = 0; + } + a->width = i + 1; + } + + a->d[i] |= (((BN_ULONG)1) << j); + + return 1; +} + +int BN_clear_bit(BIGNUM *a, int n) { + int i, j; + + if (n < 0) { + return 0; + } + + i = n / BN_BITS2; + j = n % BN_BITS2; + if (a->width <= i) { + return 0; + } + + a->d[i] &= (~(((BN_ULONG)1) << j)); + bn_set_minimal_width(a); + return 1; +} + +int bn_is_bit_set_words(const BN_ULONG *a, size_t num, unsigned bit) { + unsigned i = bit / BN_BITS2; + unsigned j = bit % BN_BITS2; + if (i >= num) { + return 0; + } + return (a[i] >> j) & 1; +} + +int BN_is_bit_set(const BIGNUM *a, int n) { + if (n < 0) { + return 0; + } + return bn_is_bit_set_words(a->d, a->width, n); +} + +int BN_mask_bits(BIGNUM *a, int n) { + if (n < 0) { + return 0; + } + + int w = n / BN_BITS2; + int b = n % BN_BITS2; + if (w >= a->width) { + return 1; + } + if (b == 0) { + a->width = w; + } else { + a->width = w + 1; + a->d[w] &= ~(BN_MASK2 << b); + } + + bn_set_minimal_width(a); + return 1; +} + +static int bn_count_low_zero_bits_word(BN_ULONG l) { + OPENSSL_COMPILE_ASSERT(sizeof(BN_ULONG) <= sizeof(crypto_word_t), + crypto_word_t_too_small); + OPENSSL_COMPILE_ASSERT(sizeof(int) <= sizeof(crypto_word_t), + crypto_word_t_too_small_2); + OPENSSL_COMPILE_ASSERT(BN_BITS2 == sizeof(BN_ULONG) * 8, + bn_ulong_has_padding_bits); + // C has very bizarre rules for types smaller than an int. + OPENSSL_COMPILE_ASSERT(sizeof(BN_ULONG) >= sizeof(int), + bn_ulong_is_promoted_to_int); + + crypto_word_t mask; + int bits = 0; + +#if BN_BITS2 > 32 + // Check if the lower half of |x| are all zero. + mask = constant_time_is_zero_w(l << (BN_BITS2 - 32)); + // If the lower half is all zeros, it is included in the bit count and we + // count the upper half. Otherwise, we count the lower half. + bits += 32 & mask; + l = constant_time_select_w(mask, l >> 32, l); +#endif + + // The remaining blocks are analogous iterations at lower powers of two. + mask = constant_time_is_zero_w(l << (BN_BITS2 - 16)); + bits += 16 & mask; + l = constant_time_select_w(mask, l >> 16, l); + + mask = constant_time_is_zero_w(l << (BN_BITS2 - 8)); + bits += 8 & mask; + l = constant_time_select_w(mask, l >> 8, l); + + mask = constant_time_is_zero_w(l << (BN_BITS2 - 4)); + bits += 4 & mask; + l = constant_time_select_w(mask, l >> 4, l); + + mask = constant_time_is_zero_w(l << (BN_BITS2 - 2)); + bits += 2 & mask; + l = constant_time_select_w(mask, l >> 2, l); + + mask = constant_time_is_zero_w(l << (BN_BITS2 - 1)); + bits += 1 & mask; + + return bits; +} + +int BN_count_low_zero_bits(const BIGNUM *bn) { + OPENSSL_COMPILE_ASSERT(sizeof(BN_ULONG) <= sizeof(crypto_word_t), + crypto_word_t_too_small); + OPENSSL_COMPILE_ASSERT(sizeof(int) <= sizeof(crypto_word_t), + crypto_word_t_too_small_2); + + int ret = 0; + crypto_word_t saw_nonzero = 0; + for (int i = 0; i < bn->width; i++) { + crypto_word_t nonzero = ~constant_time_is_zero_w(bn->d[i]); + crypto_word_t first_nonzero = ~saw_nonzero & nonzero; + saw_nonzero |= nonzero; + + int bits = bn_count_low_zero_bits_word(bn->d[i]); + ret |= first_nonzero & (i * BN_BITS2 + bits); + } + + // If got to the end of |bn| and saw no non-zero words, |bn| is zero. |ret| + // will then remain zero. + return ret; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/shift.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/shift.c.grpc_back new file mode 100644 index 0000000..3e71739 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/shift.c.grpc_back @@ -0,0 +1,364 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 "internal.h" + + +int BN_lshift(BIGNUM *r, const BIGNUM *a, int n) { + int i, nw, lb, rb; + BN_ULONG *t, *f; + BN_ULONG l; + + if (n < 0) { + OPENSSL_PUT_ERROR(BN, BN_R_NEGATIVE_NUMBER); + return 0; + } + + r->neg = a->neg; + nw = n / BN_BITS2; + if (!bn_wexpand(r, a->width + nw + 1)) { + return 0; + } + lb = n % BN_BITS2; + rb = BN_BITS2 - lb; + f = a->d; + t = r->d; + t[a->width + nw] = 0; + if (lb == 0) { + for (i = a->width - 1; i >= 0; i--) { + t[nw + i] = f[i]; + } + } else { + for (i = a->width - 1; i >= 0; i--) { + l = f[i]; + t[nw + i + 1] |= l >> rb; + t[nw + i] = l << lb; + } + } + OPENSSL_memset(t, 0, nw * sizeof(t[0])); + r->width = a->width + nw + 1; + bn_set_minimal_width(r); + + return 1; +} + +int BN_lshift1(BIGNUM *r, const BIGNUM *a) { + BN_ULONG *ap, *rp, t, c; + int i; + + if (r != a) { + r->neg = a->neg; + if (!bn_wexpand(r, a->width + 1)) { + return 0; + } + r->width = a->width; + } else { + if (!bn_wexpand(r, a->width + 1)) { + return 0; + } + } + ap = a->d; + rp = r->d; + c = 0; + for (i = 0; i < a->width; i++) { + t = *(ap++); + *(rp++) = (t << 1) | c; + c = t >> (BN_BITS2 - 1); + } + if (c) { + *rp = 1; + r->width++; + } + + return 1; +} + +static void bn_rshift_words(BN_ULONG *r, const BN_ULONG *a, unsigned shift, + size_t num) { + unsigned shift_bits = shift % BN_BITS2; + size_t shift_words = shift / BN_BITS2; + if (shift_words >= num) { + OPENSSL_memset(r, 0, num * sizeof(BN_ULONG)); + return; + } + if (shift_bits == 0) { + OPENSSL_memmove(r, a + shift_words, (num - shift_words) * sizeof(BN_ULONG)); + } else { + for (size_t i = shift_words; i < num - 1; i++) { + r[i - shift_words] = + (a[i] >> shift_bits) | (a[i + 1] << (BN_BITS2 - shift_bits)); + } + r[num - 1 - shift_words] = a[num - 1] >> shift_bits; + } + OPENSSL_memset(r + num - shift_words, 0, shift_words * sizeof(BN_ULONG)); +} + +int BN_rshift(BIGNUM *r, const BIGNUM *a, int n) { + if (n < 0) { + OPENSSL_PUT_ERROR(BN, BN_R_NEGATIVE_NUMBER); + return 0; + } + + if (!bn_wexpand(r, a->width)) { + return 0; + } + bn_rshift_words(r->d, a->d, n, a->width); + r->neg = a->neg; + r->width = a->width; + bn_set_minimal_width(r); + return 1; +} + +int bn_rshift_secret_shift(BIGNUM *r, const BIGNUM *a, unsigned n, + BN_CTX *ctx) { + int ret = 0; + BN_CTX_start(ctx); + BIGNUM *tmp = BN_CTX_get(ctx); + if (tmp == NULL || + !BN_copy(r, a) || + !bn_wexpand(tmp, r->width)) { + goto err; + } + + // Shift conditionally by powers of two. + unsigned max_bits = BN_BITS2 * r->width; + for (unsigned i = 0; (max_bits >> i) != 0; i++) { + BN_ULONG mask = (n >> i) & 1; + mask = 0 - mask; + bn_rshift_words(tmp->d, r->d, 1u << i, r->width); + bn_select_words(r->d, mask, tmp->d /* apply shift */, + r->d /* ignore shift */, r->width); + } + + ret = 1; + +err: + BN_CTX_end(ctx); + return ret; +} + +void bn_rshift1_words(BN_ULONG *r, const BN_ULONG *a, size_t num) { + if (num == 0) { + return; + } + for (size_t i = 0; i < num - 1; i++) { + r[i] = (a[i] >> 1) | (a[i + 1] << (BN_BITS2 - 1)); + } + r[num - 1] = a[num - 1] >> 1; +} + +int BN_rshift1(BIGNUM *r, const BIGNUM *a) { + if (!bn_wexpand(r, a->width)) { + return 0; + } + bn_rshift1_words(r->d, a->d, a->width); + r->width = a->width; + r->neg = a->neg; + bn_set_minimal_width(r); + return 1; +} + +int BN_set_bit(BIGNUM *a, int n) { + if (n < 0) { + return 0; + } + + int i = n / BN_BITS2; + int j = n % BN_BITS2; + if (a->width <= i) { + if (!bn_wexpand(a, i + 1)) { + return 0; + } + for (int k = a->width; k < i + 1; k++) { + a->d[k] = 0; + } + a->width = i + 1; + } + + a->d[i] |= (((BN_ULONG)1) << j); + + return 1; +} + +int BN_clear_bit(BIGNUM *a, int n) { + int i, j; + + if (n < 0) { + return 0; + } + + i = n / BN_BITS2; + j = n % BN_BITS2; + if (a->width <= i) { + return 0; + } + + a->d[i] &= (~(((BN_ULONG)1) << j)); + bn_set_minimal_width(a); + return 1; +} + +int bn_is_bit_set_words(const BN_ULONG *a, size_t num, unsigned bit) { + unsigned i = bit / BN_BITS2; + unsigned j = bit % BN_BITS2; + if (i >= num) { + return 0; + } + return (a[i] >> j) & 1; +} + +int BN_is_bit_set(const BIGNUM *a, int n) { + if (n < 0) { + return 0; + } + return bn_is_bit_set_words(a->d, a->width, n); +} + +int BN_mask_bits(BIGNUM *a, int n) { + if (n < 0) { + return 0; + } + + int w = n / BN_BITS2; + int b = n % BN_BITS2; + if (w >= a->width) { + return 1; + } + if (b == 0) { + a->width = w; + } else { + a->width = w + 1; + a->d[w] &= ~(BN_MASK2 << b); + } + + bn_set_minimal_width(a); + return 1; +} + +static int bn_count_low_zero_bits_word(BN_ULONG l) { + OPENSSL_COMPILE_ASSERT(sizeof(BN_ULONG) <= sizeof(crypto_word_t), + crypto_word_t_too_small); + OPENSSL_COMPILE_ASSERT(sizeof(int) <= sizeof(crypto_word_t), + crypto_word_t_too_small_2); + OPENSSL_COMPILE_ASSERT(BN_BITS2 == sizeof(BN_ULONG) * 8, + bn_ulong_has_padding_bits); + // C has very bizarre rules for types smaller than an int. + OPENSSL_COMPILE_ASSERT(sizeof(BN_ULONG) >= sizeof(int), + bn_ulong_is_promoted_to_int); + + crypto_word_t mask; + int bits = 0; + +#if BN_BITS2 > 32 + // Check if the lower half of |x| are all zero. + mask = constant_time_is_zero_w(l << (BN_BITS2 - 32)); + // If the lower half is all zeros, it is included in the bit count and we + // count the upper half. Otherwise, we count the lower half. + bits += 32 & mask; + l = constant_time_select_w(mask, l >> 32, l); +#endif + + // The remaining blocks are analogous iterations at lower powers of two. + mask = constant_time_is_zero_w(l << (BN_BITS2 - 16)); + bits += 16 & mask; + l = constant_time_select_w(mask, l >> 16, l); + + mask = constant_time_is_zero_w(l << (BN_BITS2 - 8)); + bits += 8 & mask; + l = constant_time_select_w(mask, l >> 8, l); + + mask = constant_time_is_zero_w(l << (BN_BITS2 - 4)); + bits += 4 & mask; + l = constant_time_select_w(mask, l >> 4, l); + + mask = constant_time_is_zero_w(l << (BN_BITS2 - 2)); + bits += 2 & mask; + l = constant_time_select_w(mask, l >> 2, l); + + mask = constant_time_is_zero_w(l << (BN_BITS2 - 1)); + bits += 1 & mask; + + return bits; +} + +int BN_count_low_zero_bits(const BIGNUM *bn) { + OPENSSL_COMPILE_ASSERT(sizeof(BN_ULONG) <= sizeof(crypto_word_t), + crypto_word_t_too_small); + OPENSSL_COMPILE_ASSERT(sizeof(int) <= sizeof(crypto_word_t), + crypto_word_t_too_small_2); + + int ret = 0; + crypto_word_t saw_nonzero = 0; + for (int i = 0; i < bn->width; i++) { + crypto_word_t nonzero = ~constant_time_is_zero_w(bn->d[i]); + crypto_word_t first_nonzero = ~saw_nonzero & nonzero; + saw_nonzero |= nonzero; + + int bits = bn_count_low_zero_bits_word(bn->d[i]); + ret |= first_nonzero & (i * BN_BITS2 + bits); + } + + // If got to the end of |bn| and saw no non-zero words, |bn| is zero. |ret| + // will then remain zero. + return ret; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/sqrt.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/sqrt.c new file mode 100644 index 0000000..6dd88fe --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/sqrt.c @@ -0,0 +1,502 @@ +/* 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 + +#include + +#include "internal.h" + + +BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) { + // Compute a square root of |a| mod |p| using the Tonelli/Shanks algorithm + // (cf. Henri Cohen, "A Course in Algebraic Computational Number Theory", + // algorithm 1.5.1). |p| is assumed to be a 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; + } + return ret; + } + + OPENSSL_PUT_ERROR(BN, 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; + } + 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) || + !BN_mod_exp_mont(ret, A, q, p, ctx, NULL)) { + 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_consttime(t, A, p, ctx)) { + goto end; + } + + // b := (2*a)^((|p|-5)/8) + if (!BN_rshift(q, p, 3)) { + goto end; + } + q->neg = 0; + if (!BN_mod_exp_mont(b, t, q, p, ctx, NULL)) { + 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) || + !BN_sub_word(t, 1)) { + goto end; + } + + // x = a*b*t + if (!BN_mod_mul(x, A, b, p, ctx) || + !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_jacobi(y, q, ctx); // here 'q' is |p| + if (r < -1) { + goto end; + } + if (r == 0) { + // m divides p + OPENSSL_PUT_ERROR(BN, 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. + OPENSSL_PUT_ERROR(BN, 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_mont(y, y, q, p, ctx, NULL)) { + goto end; + } + if (BN_is_one(y)) { + OPENSSL_PUT_ERROR(BN, 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_mont(x, A, t, p, ctx, NULL)) { + 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) || + !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) { + OPENSSL_PUT_ERROR(BN, 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) || + !BN_mod_mul(x, x, t, p, ctx) || + !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)) { + OPENSSL_PUT_ERROR(BN, BN_R_NOT_A_SQUARE); + err = 1; + } + } + +end: + if (err) { + if (ret != in) { + BN_clear_free(ret); + } + ret = NULL; + } + BN_CTX_end(ctx); + return ret; +} + +int BN_sqrt(BIGNUM *out_sqrt, const BIGNUM *in, BN_CTX *ctx) { + BIGNUM *estimate, *tmp, *delta, *last_delta, *tmp2; + int ok = 0, last_delta_valid = 0; + + if (in->neg) { + OPENSSL_PUT_ERROR(BN, BN_R_NEGATIVE_NUMBER); + return 0; + } + if (BN_is_zero(in)) { + BN_zero(out_sqrt); + return 1; + } + + BN_CTX_start(ctx); + if (out_sqrt == in) { + estimate = BN_CTX_get(ctx); + } else { + estimate = out_sqrt; + } + tmp = BN_CTX_get(ctx); + last_delta = BN_CTX_get(ctx); + delta = BN_CTX_get(ctx); + if (estimate == NULL || tmp == NULL || last_delta == NULL || delta == NULL) { + OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE); + goto err; + } + + // We estimate that the square root of an n-bit number is 2^{n/2}. + if (!BN_lshift(estimate, BN_value_one(), BN_num_bits(in)/2)) { + goto err; + } + + // This is Newton's method for finding a root of the equation |estimate|^2 - + // |in| = 0. + for (;;) { + // |estimate| = 1/2 * (|estimate| + |in|/|estimate|) + if (!BN_div(tmp, NULL, in, estimate, ctx) || + !BN_add(tmp, tmp, estimate) || + !BN_rshift1(estimate, tmp) || + // |tmp| = |estimate|^2 + !BN_sqr(tmp, estimate, ctx) || + // |delta| = |in| - |tmp| + !BN_sub(delta, in, tmp)) { + OPENSSL_PUT_ERROR(BN, ERR_R_BN_LIB); + goto err; + } + + delta->neg = 0; + // The difference between |in| and |estimate| squared is required to always + // decrease. This ensures that the loop always terminates, but I don't have + // a proof that it always finds the square root for a given square. + if (last_delta_valid && BN_cmp(delta, last_delta) >= 0) { + break; + } + + last_delta_valid = 1; + + tmp2 = last_delta; + last_delta = delta; + delta = tmp2; + } + + if (BN_cmp(tmp, in) != 0) { + OPENSSL_PUT_ERROR(BN, BN_R_NOT_A_SQUARE); + goto err; + } + + ok = 1; + +err: + if (ok && out_sqrt == in && !BN_copy(out_sqrt, estimate)) { + ok = 0; + } + BN_CTX_end(ctx); + return ok; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/sqrt.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/sqrt.c.grpc_back new file mode 100644 index 0000000..23417d1 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/bn/sqrt.c.grpc_back @@ -0,0 +1,502 @@ +/* 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 + +#include + +#include "internal.h" + + +BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx) { + // Compute a square root of |a| mod |p| using the Tonelli/Shanks algorithm + // (cf. Henri Cohen, "A Course in Algebraic Computational Number Theory", + // algorithm 1.5.1). |p| is assumed to be a 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; + } + return ret; + } + + OPENSSL_PUT_ERROR(BN, 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; + } + 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) || + !BN_mod_exp_mont(ret, A, q, p, ctx, NULL)) { + 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_consttime(t, A, p, ctx)) { + goto end; + } + + // b := (2*a)^((|p|-5)/8) + if (!BN_rshift(q, p, 3)) { + goto end; + } + q->neg = 0; + if (!BN_mod_exp_mont(b, t, q, p, ctx, NULL)) { + 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) || + !BN_sub_word(t, 1)) { + goto end; + } + + // x = a*b*t + if (!BN_mod_mul(x, A, b, p, ctx) || + !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_jacobi(y, q, ctx); // here 'q' is |p| + if (r < -1) { + goto end; + } + if (r == 0) { + // m divides p + OPENSSL_PUT_ERROR(BN, 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. + OPENSSL_PUT_ERROR(BN, 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_mont(y, y, q, p, ctx, NULL)) { + goto end; + } + if (BN_is_one(y)) { + OPENSSL_PUT_ERROR(BN, 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_mont(x, A, t, p, ctx, NULL)) { + 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) || + !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) { + OPENSSL_PUT_ERROR(BN, 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) || + !BN_mod_mul(x, x, t, p, ctx) || + !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)) { + OPENSSL_PUT_ERROR(BN, BN_R_NOT_A_SQUARE); + err = 1; + } + } + +end: + if (err) { + if (ret != in) { + BN_clear_free(ret); + } + ret = NULL; + } + BN_CTX_end(ctx); + return ret; +} + +int BN_sqrt(BIGNUM *out_sqrt, const BIGNUM *in, BN_CTX *ctx) { + BIGNUM *estimate, *tmp, *delta, *last_delta, *tmp2; + int ok = 0, last_delta_valid = 0; + + if (in->neg) { + OPENSSL_PUT_ERROR(BN, BN_R_NEGATIVE_NUMBER); + return 0; + } + if (BN_is_zero(in)) { + BN_zero(out_sqrt); + return 1; + } + + BN_CTX_start(ctx); + if (out_sqrt == in) { + estimate = BN_CTX_get(ctx); + } else { + estimate = out_sqrt; + } + tmp = BN_CTX_get(ctx); + last_delta = BN_CTX_get(ctx); + delta = BN_CTX_get(ctx); + if (estimate == NULL || tmp == NULL || last_delta == NULL || delta == NULL) { + OPENSSL_PUT_ERROR(BN, ERR_R_MALLOC_FAILURE); + goto err; + } + + // We estimate that the square root of an n-bit number is 2^{n/2}. + if (!BN_lshift(estimate, BN_value_one(), BN_num_bits(in)/2)) { + goto err; + } + + // This is Newton's method for finding a root of the equation |estimate|^2 - + // |in| = 0. + for (;;) { + // |estimate| = 1/2 * (|estimate| + |in|/|estimate|) + if (!BN_div(tmp, NULL, in, estimate, ctx) || + !BN_add(tmp, tmp, estimate) || + !BN_rshift1(estimate, tmp) || + // |tmp| = |estimate|^2 + !BN_sqr(tmp, estimate, ctx) || + // |delta| = |in| - |tmp| + !BN_sub(delta, in, tmp)) { + OPENSSL_PUT_ERROR(BN, ERR_R_BN_LIB); + goto err; + } + + delta->neg = 0; + // The difference between |in| and |estimate| squared is required to always + // decrease. This ensures that the loop always terminates, but I don't have + // a proof that it always finds the square root for a given square. + if (last_delta_valid && BN_cmp(delta, last_delta) >= 0) { + break; + } + + last_delta_valid = 1; + + tmp2 = last_delta; + last_delta = delta; + delta = tmp2; + } + + if (BN_cmp(tmp, in) != 0) { + OPENSSL_PUT_ERROR(BN, BN_R_NOT_A_SQUARE); + goto err; + } + + ok = 1; + +err: + if (ok && out_sqrt == in && !BN_copy(out_sqrt, estimate)) { + ok = 0; + } + BN_CTX_end(ctx); + return ok; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/cipher/aead.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/cipher/aead.c new file mode 100644 index 0000000..66956d9 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/cipher/aead.c @@ -0,0 +1,284 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include +#include + +#include +#include +#include + +#include "internal.h" +#include "../../internal.h" + + +size_t EVP_AEAD_key_length(const EVP_AEAD *aead) { return aead->key_len; } + +size_t EVP_AEAD_nonce_length(const EVP_AEAD *aead) { return aead->nonce_len; } + +size_t EVP_AEAD_max_overhead(const EVP_AEAD *aead) { return aead->overhead; } + +size_t EVP_AEAD_max_tag_len(const EVP_AEAD *aead) { return aead->max_tag_len; } + +void EVP_AEAD_CTX_zero(EVP_AEAD_CTX *ctx) { + OPENSSL_memset(ctx, 0, sizeof(EVP_AEAD_CTX)); +} + +EVP_AEAD_CTX *EVP_AEAD_CTX_new(const EVP_AEAD *aead, const uint8_t *key, + size_t key_len, size_t tag_len) { + EVP_AEAD_CTX *ctx = OPENSSL_malloc(sizeof(EVP_AEAD_CTX)); + EVP_AEAD_CTX_zero(ctx); + + if (EVP_AEAD_CTX_init(ctx, aead, key, key_len, tag_len, NULL)) { + return ctx; + } + + EVP_AEAD_CTX_free(ctx); + return NULL; +} + +void EVP_AEAD_CTX_free(EVP_AEAD_CTX *ctx) { + EVP_AEAD_CTX_cleanup(ctx); + OPENSSL_free(ctx); +} + +int EVP_AEAD_CTX_init(EVP_AEAD_CTX *ctx, const EVP_AEAD *aead, + const uint8_t *key, size_t key_len, size_t tag_len, + ENGINE *impl) { + if (!aead->init) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_NO_DIRECTION_SET); + ctx->aead = NULL; + return 0; + } + return EVP_AEAD_CTX_init_with_direction(ctx, aead, key, key_len, tag_len, + evp_aead_open); +} + +int EVP_AEAD_CTX_init_with_direction(EVP_AEAD_CTX *ctx, const EVP_AEAD *aead, + const uint8_t *key, size_t key_len, + size_t tag_len, + enum evp_aead_direction_t dir) { + if (key_len != aead->key_len) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_KEY_SIZE); + ctx->aead = NULL; + return 0; + } + + ctx->aead = aead; + + int ok; + if (aead->init) { + ok = aead->init(ctx, key, key_len, tag_len); + } else { + ok = aead->init_with_direction(ctx, key, key_len, tag_len, dir); + } + + if (!ok) { + ctx->aead = NULL; + } + + return ok; +} + +void EVP_AEAD_CTX_cleanup(EVP_AEAD_CTX *ctx) { + if (ctx->aead == NULL) { + return; + } + ctx->aead->cleanup(ctx); + ctx->aead = NULL; +} + +// check_alias returns 1 if |out| is compatible with |in| and 0 otherwise. If +// |in| and |out| alias, we require that |in| == |out|. +static int check_alias(const uint8_t *in, size_t in_len, const uint8_t *out, + size_t out_len) { + if (!buffers_alias(in, in_len, out, out_len)) { + return 1; + } + + return in == out; +} + +int EVP_AEAD_CTX_seal(const EVP_AEAD_CTX *ctx, uint8_t *out, size_t *out_len, + size_t max_out_len, const uint8_t *nonce, + size_t nonce_len, const uint8_t *in, size_t in_len, + const uint8_t *ad, size_t ad_len) { + if (in_len + ctx->aead->overhead < in_len /* overflow */) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE); + goto error; + } + + if (max_out_len < in_len) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL); + goto error; + } + + if (!check_alias(in, in_len, out, max_out_len)) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_OUTPUT_ALIASES_INPUT); + goto error; + } + + size_t out_tag_len; + if (ctx->aead->seal_scatter(ctx, out, out + in_len, &out_tag_len, + max_out_len - in_len, nonce, nonce_len, in, + in_len, NULL, 0, ad, ad_len)) { + *out_len = in_len + out_tag_len; + return 1; + } + +error: + // In the event of an error, clear the output buffer so that a caller + // that doesn't check the return value doesn't send raw data. + OPENSSL_memset(out, 0, max_out_len); + *out_len = 0; + return 0; +} + +int EVP_AEAD_CTX_seal_scatter( + const EVP_AEAD_CTX *ctx, uint8_t *out, uint8_t *out_tag, size_t + *out_tag_len, size_t max_out_tag_len, const uint8_t *nonce, size_t + nonce_len, const uint8_t *in, size_t in_len, const uint8_t *extra_in, + size_t extra_in_len, const uint8_t *ad, size_t ad_len) { + // |in| and |out| may alias exactly, |out_tag| may not alias. + if (!check_alias(in, in_len, out, in_len) || + buffers_alias(out, in_len, out_tag, max_out_tag_len) || + buffers_alias(in, in_len, out_tag, max_out_tag_len)) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_OUTPUT_ALIASES_INPUT); + goto error; + } + + if (!ctx->aead->seal_scatter_supports_extra_in && extra_in_len) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_OPERATION); + goto error; + } + + if (ctx->aead->seal_scatter(ctx, out, out_tag, out_tag_len, max_out_tag_len, + nonce, nonce_len, in, in_len, extra_in, + extra_in_len, ad, ad_len)) { + return 1; + } + +error: + // In the event of an error, clear the output buffer so that a caller + // that doesn't check the return value doesn't send raw data. + OPENSSL_memset(out, 0, in_len); + OPENSSL_memset(out_tag, 0, max_out_tag_len); + *out_tag_len = 0; + return 0; +} + +int EVP_AEAD_CTX_open(const EVP_AEAD_CTX *ctx, uint8_t *out, size_t *out_len, + size_t max_out_len, const uint8_t *nonce, + size_t nonce_len, const uint8_t *in, size_t in_len, + const uint8_t *ad, size_t ad_len) { + if (!check_alias(in, in_len, out, max_out_len)) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_OUTPUT_ALIASES_INPUT); + goto error; + } + + if (ctx->aead->open) { + if (!ctx->aead->open(ctx, out, out_len, max_out_len, nonce, nonce_len, in, + in_len, ad, ad_len)) { + goto error; + } + return 1; + } + + // AEADs that use the default implementation of open() must set |tag_len| at + // initialization time. + assert(ctx->tag_len); + + if (in_len < ctx->tag_len) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT); + goto error; + } + + size_t plaintext_len = in_len - ctx->tag_len; + if (max_out_len < plaintext_len) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL); + goto error; + } + if (EVP_AEAD_CTX_open_gather(ctx, out, nonce, nonce_len, in, plaintext_len, + in + plaintext_len, ctx->tag_len, ad, ad_len)) { + *out_len = plaintext_len; + return 1; + } + +error: + // In the event of an error, clear the output buffer so that a caller + // that doesn't check the return value doesn't try and process bad + // data. + OPENSSL_memset(out, 0, max_out_len); + *out_len = 0; + return 0; +} + +int EVP_AEAD_CTX_open_gather(const EVP_AEAD_CTX *ctx, uint8_t *out, + const uint8_t *nonce, size_t nonce_len, + const uint8_t *in, size_t in_len, + const uint8_t *in_tag, size_t in_tag_len, + const uint8_t *ad, size_t ad_len) { + if (!check_alias(in, in_len, out, in_len)) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_OUTPUT_ALIASES_INPUT); + goto error; + } + + if (!ctx->aead->open_gather) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_CTRL_NOT_IMPLEMENTED); + goto error; + } + + if (ctx->aead->open_gather(ctx, out, nonce, nonce_len, in, in_len, in_tag, + in_tag_len, ad, ad_len)) { + return 1; + } + +error: + // In the event of an error, clear the output buffer so that a caller + // that doesn't check the return value doesn't try and process bad + // data. + OPENSSL_memset(out, 0, in_len); + return 0; +} + +const EVP_AEAD *EVP_AEAD_CTX_aead(const EVP_AEAD_CTX *ctx) { return ctx->aead; } + +int EVP_AEAD_CTX_get_iv(const EVP_AEAD_CTX *ctx, const uint8_t **out_iv, + size_t *out_len) { + if (ctx->aead->get_iv == NULL) { + return 0; + } + + return ctx->aead->get_iv(ctx, out_iv, out_len); +} + +int EVP_AEAD_CTX_tag_len(const EVP_AEAD_CTX *ctx, size_t *out_tag_len, + const size_t in_len, const size_t extra_in_len) { + assert(ctx->aead->seal_scatter_supports_extra_in || !extra_in_len); + + if (ctx->aead->tag_len) { + *out_tag_len = ctx->aead->tag_len(ctx, in_len, extra_in_len); + return 1; + } + + if (extra_in_len + ctx->tag_len < extra_in_len) { + OPENSSL_PUT_ERROR(CIPHER, ERR_R_OVERFLOW); + *out_tag_len = 0; + return 0; + } + *out_tag_len = extra_in_len + ctx->tag_len; + return 1; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/cipher/aead.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/cipher/aead.c.grpc_back new file mode 100644 index 0000000..8d2ad04 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/cipher/aead.c.grpc_back @@ -0,0 +1,284 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include +#include + +#include +#include +#include + +#include "internal.h" +#include "../../internal.h" + + +size_t EVP_AEAD_key_length(const EVP_AEAD *aead) { return aead->key_len; } + +size_t EVP_AEAD_nonce_length(const EVP_AEAD *aead) { return aead->nonce_len; } + +size_t EVP_AEAD_max_overhead(const EVP_AEAD *aead) { return aead->overhead; } + +size_t EVP_AEAD_max_tag_len(const EVP_AEAD *aead) { return aead->max_tag_len; } + +void EVP_AEAD_CTX_zero(EVP_AEAD_CTX *ctx) { + OPENSSL_memset(ctx, 0, sizeof(EVP_AEAD_CTX)); +} + +EVP_AEAD_CTX *EVP_AEAD_CTX_new(const EVP_AEAD *aead, const uint8_t *key, + size_t key_len, size_t tag_len) { + EVP_AEAD_CTX *ctx = OPENSSL_malloc(sizeof(EVP_AEAD_CTX)); + EVP_AEAD_CTX_zero(ctx); + + if (EVP_AEAD_CTX_init(ctx, aead, key, key_len, tag_len, NULL)) { + return ctx; + } + + EVP_AEAD_CTX_free(ctx); + return NULL; +} + +void EVP_AEAD_CTX_free(EVP_AEAD_CTX *ctx) { + EVP_AEAD_CTX_cleanup(ctx); + OPENSSL_free(ctx); +} + +int EVP_AEAD_CTX_init(EVP_AEAD_CTX *ctx, const EVP_AEAD *aead, + const uint8_t *key, size_t key_len, size_t tag_len, + ENGINE *impl) { + if (!aead->init) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_NO_DIRECTION_SET); + ctx->aead = NULL; + return 0; + } + return EVP_AEAD_CTX_init_with_direction(ctx, aead, key, key_len, tag_len, + evp_aead_open); +} + +int EVP_AEAD_CTX_init_with_direction(EVP_AEAD_CTX *ctx, const EVP_AEAD *aead, + const uint8_t *key, size_t key_len, + size_t tag_len, + enum evp_aead_direction_t dir) { + if (key_len != aead->key_len) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_KEY_SIZE); + ctx->aead = NULL; + return 0; + } + + ctx->aead = aead; + + int ok; + if (aead->init) { + ok = aead->init(ctx, key, key_len, tag_len); + } else { + ok = aead->init_with_direction(ctx, key, key_len, tag_len, dir); + } + + if (!ok) { + ctx->aead = NULL; + } + + return ok; +} + +void EVP_AEAD_CTX_cleanup(EVP_AEAD_CTX *ctx) { + if (ctx->aead == NULL) { + return; + } + ctx->aead->cleanup(ctx); + ctx->aead = NULL; +} + +// check_alias returns 1 if |out| is compatible with |in| and 0 otherwise. If +// |in| and |out| alias, we require that |in| == |out|. +static int check_alias(const uint8_t *in, size_t in_len, const uint8_t *out, + size_t out_len) { + if (!buffers_alias(in, in_len, out, out_len)) { + return 1; + } + + return in == out; +} + +int EVP_AEAD_CTX_seal(const EVP_AEAD_CTX *ctx, uint8_t *out, size_t *out_len, + size_t max_out_len, const uint8_t *nonce, + size_t nonce_len, const uint8_t *in, size_t in_len, + const uint8_t *ad, size_t ad_len) { + if (in_len + ctx->aead->overhead < in_len /* overflow */) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE); + goto error; + } + + if (max_out_len < in_len) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL); + goto error; + } + + if (!check_alias(in, in_len, out, max_out_len)) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_OUTPUT_ALIASES_INPUT); + goto error; + } + + size_t out_tag_len; + if (ctx->aead->seal_scatter(ctx, out, out + in_len, &out_tag_len, + max_out_len - in_len, nonce, nonce_len, in, + in_len, NULL, 0, ad, ad_len)) { + *out_len = in_len + out_tag_len; + return 1; + } + +error: + // In the event of an error, clear the output buffer so that a caller + // that doesn't check the return value doesn't send raw data. + OPENSSL_memset(out, 0, max_out_len); + *out_len = 0; + return 0; +} + +int EVP_AEAD_CTX_seal_scatter( + const EVP_AEAD_CTX *ctx, uint8_t *out, uint8_t *out_tag, size_t + *out_tag_len, size_t max_out_tag_len, const uint8_t *nonce, size_t + nonce_len, const uint8_t *in, size_t in_len, const uint8_t *extra_in, + size_t extra_in_len, const uint8_t *ad, size_t ad_len) { + // |in| and |out| may alias exactly, |out_tag| may not alias. + if (!check_alias(in, in_len, out, in_len) || + buffers_alias(out, in_len, out_tag, max_out_tag_len) || + buffers_alias(in, in_len, out_tag, max_out_tag_len)) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_OUTPUT_ALIASES_INPUT); + goto error; + } + + if (!ctx->aead->seal_scatter_supports_extra_in && extra_in_len) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_OPERATION); + goto error; + } + + if (ctx->aead->seal_scatter(ctx, out, out_tag, out_tag_len, max_out_tag_len, + nonce, nonce_len, in, in_len, extra_in, + extra_in_len, ad, ad_len)) { + return 1; + } + +error: + // In the event of an error, clear the output buffer so that a caller + // that doesn't check the return value doesn't send raw data. + OPENSSL_memset(out, 0, in_len); + OPENSSL_memset(out_tag, 0, max_out_tag_len); + *out_tag_len = 0; + return 0; +} + +int EVP_AEAD_CTX_open(const EVP_AEAD_CTX *ctx, uint8_t *out, size_t *out_len, + size_t max_out_len, const uint8_t *nonce, + size_t nonce_len, const uint8_t *in, size_t in_len, + const uint8_t *ad, size_t ad_len) { + if (!check_alias(in, in_len, out, max_out_len)) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_OUTPUT_ALIASES_INPUT); + goto error; + } + + if (ctx->aead->open) { + if (!ctx->aead->open(ctx, out, out_len, max_out_len, nonce, nonce_len, in, + in_len, ad, ad_len)) { + goto error; + } + return 1; + } + + // AEADs that use the default implementation of open() must set |tag_len| at + // initialization time. + assert(ctx->tag_len); + + if (in_len < ctx->tag_len) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT); + goto error; + } + + size_t plaintext_len = in_len - ctx->tag_len; + if (max_out_len < plaintext_len) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL); + goto error; + } + if (EVP_AEAD_CTX_open_gather(ctx, out, nonce, nonce_len, in, plaintext_len, + in + plaintext_len, ctx->tag_len, ad, ad_len)) { + *out_len = plaintext_len; + return 1; + } + +error: + // In the event of an error, clear the output buffer so that a caller + // that doesn't check the return value doesn't try and process bad + // data. + OPENSSL_memset(out, 0, max_out_len); + *out_len = 0; + return 0; +} + +int EVP_AEAD_CTX_open_gather(const EVP_AEAD_CTX *ctx, uint8_t *out, + const uint8_t *nonce, size_t nonce_len, + const uint8_t *in, size_t in_len, + const uint8_t *in_tag, size_t in_tag_len, + const uint8_t *ad, size_t ad_len) { + if (!check_alias(in, in_len, out, in_len)) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_OUTPUT_ALIASES_INPUT); + goto error; + } + + if (!ctx->aead->open_gather) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_CTRL_NOT_IMPLEMENTED); + goto error; + } + + if (ctx->aead->open_gather(ctx, out, nonce, nonce_len, in, in_len, in_tag, + in_tag_len, ad, ad_len)) { + return 1; + } + +error: + // In the event of an error, clear the output buffer so that a caller + // that doesn't check the return value doesn't try and process bad + // data. + OPENSSL_memset(out, 0, in_len); + return 0; +} + +const EVP_AEAD *EVP_AEAD_CTX_aead(const EVP_AEAD_CTX *ctx) { return ctx->aead; } + +int EVP_AEAD_CTX_get_iv(const EVP_AEAD_CTX *ctx, const uint8_t **out_iv, + size_t *out_len) { + if (ctx->aead->get_iv == NULL) { + return 0; + } + + return ctx->aead->get_iv(ctx, out_iv, out_len); +} + +int EVP_AEAD_CTX_tag_len(const EVP_AEAD_CTX *ctx, size_t *out_tag_len, + const size_t in_len, const size_t extra_in_len) { + assert(ctx->aead->seal_scatter_supports_extra_in || !extra_in_len); + + if (ctx->aead->tag_len) { + *out_tag_len = ctx->aead->tag_len(ctx, in_len, extra_in_len); + return 1; + } + + if (extra_in_len + ctx->tag_len < extra_in_len) { + OPENSSL_PUT_ERROR(CIPHER, ERR_R_OVERFLOW); + *out_tag_len = 0; + return 0; + } + *out_tag_len = extra_in_len + ctx->tag_len; + return 1; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/cipher/cipher.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/cipher/cipher.c new file mode 100644 index 0000000..797391c --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/cipher/cipher.c @@ -0,0 +1,615 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 +#include + +#include "internal.h" +#include "../../internal.h" + + +void EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *ctx) { + OPENSSL_memset(ctx, 0, sizeof(EVP_CIPHER_CTX)); +} + +EVP_CIPHER_CTX *EVP_CIPHER_CTX_new(void) { + EVP_CIPHER_CTX *ctx = OPENSSL_malloc(sizeof(EVP_CIPHER_CTX)); + if (ctx) { + EVP_CIPHER_CTX_init(ctx); + } + return ctx; +} + +int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *c) { + if (c->cipher != NULL && c->cipher->cleanup) { + c->cipher->cleanup(c); + } + OPENSSL_free(c->cipher_data); + + OPENSSL_memset(c, 0, sizeof(EVP_CIPHER_CTX)); + 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_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in) { + if (in == NULL || in->cipher == NULL) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INPUT_NOT_INITIALIZED); + return 0; + } + + EVP_CIPHER_CTX_cleanup(out); + OPENSSL_memcpy(out, in, sizeof(EVP_CIPHER_CTX)); + + if (in->cipher_data && in->cipher->ctx_size) { + out->cipher_data = OPENSSL_malloc(in->cipher->ctx_size); + if (!out->cipher_data) { + out->cipher = NULL; + OPENSSL_PUT_ERROR(CIPHER, ERR_R_MALLOC_FAILURE); + return 0; + } + OPENSSL_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; + return 0; + } + } + + return 1; +} + +void EVP_CIPHER_CTX_reset(EVP_CIPHER_CTX *ctx) { + EVP_CIPHER_CTX_cleanup(ctx); + EVP_CIPHER_CTX_init(ctx); +} + +int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + ENGINE *engine, const uint8_t *key, const uint8_t *iv, + int enc) { + if (enc == -1) { + enc = ctx->encrypt; + } else { + if (enc) { + enc = 1; + } + ctx->encrypt = enc; + } + + if (cipher) { + // Ensure a context left 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) { + EVP_CIPHER_CTX_cleanup(ctx); + // Restore encrypt and flags + ctx->encrypt = enc; + } + + ctx->cipher = cipher; + if (ctx->cipher->ctx_size) { + ctx->cipher_data = OPENSSL_malloc(ctx->cipher->ctx_size); + if (!ctx->cipher_data) { + ctx->cipher = NULL; + OPENSSL_PUT_ERROR(CIPHER, ERR_R_MALLOC_FAILURE); + return 0; + } + } else { + ctx->cipher_data = NULL; + } + + ctx->key_len = cipher->key_len; + ctx->flags = 0; + + if (ctx->cipher->flags & EVP_CIPH_CTRL_INIT) { + if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_INIT, 0, NULL)) { + ctx->cipher = NULL; + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INITIALIZATION_ERROR); + return 0; + } + } + } else if (!ctx->cipher) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_NO_CIPHER_SET); + return 0; + } + + // we assume block size is a power of 2 in *cryptUpdate + assert(ctx->cipher->block_size == 1 || ctx->cipher->block_size == 8 || + ctx->cipher->block_size == 16); + + 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: + ctx->num = 0; + // fall-through + + case EVP_CIPH_CBC_MODE: + assert(EVP_CIPHER_CTX_iv_length(ctx) <= sizeof(ctx->iv)); + if (iv) { + OPENSSL_memcpy(ctx->oiv, iv, EVP_CIPHER_CTX_iv_length(ctx)); + } + OPENSSL_memcpy(ctx->iv, ctx->oiv, EVP_CIPHER_CTX_iv_length(ctx)); + break; + + case EVP_CIPH_CTR_MODE: + case EVP_CIPH_OFB_MODE: + ctx->num = 0; + // Don't reuse IV for CTR mode + if (iv) { + OPENSSL_memcpy(ctx->iv, iv, EVP_CIPHER_CTX_iv_length(ctx)); + } + break; + + default: + return 0; + } + } + + 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_EncryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + ENGINE *impl, const uint8_t *key, const uint8_t *iv) { + return EVP_CipherInit_ex(ctx, cipher, impl, key, iv, 1); +} + +int EVP_DecryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + ENGINE *impl, const uint8_t *key, const uint8_t *iv) { + return EVP_CipherInit_ex(ctx, cipher, impl, key, iv, 0); +} + +int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, uint8_t *out, int *out_len, + const uint8_t *in, int in_len) { + int i, j, bl; + + if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) { + i = ctx->cipher->cipher(ctx, out, in, in_len); + if (i < 0) { + return 0; + } else { + *out_len = i; + } + return 1; + } + + if (in_len <= 0) { + *out_len = 0; + return in_len == 0; + } + + if (ctx->buf_len == 0 && (in_len & ctx->block_mask) == 0) { + if (ctx->cipher->cipher(ctx, out, in, in_len)) { + *out_len = in_len; + return 1; + } else { + *out_len = 0; + return 0; + } + } + + i = ctx->buf_len; + bl = ctx->cipher->block_size; + assert(bl <= (int)sizeof(ctx->buf)); + if (i != 0) { + if (bl - i > in_len) { + OPENSSL_memcpy(&ctx->buf[i], in, in_len); + ctx->buf_len += in_len; + *out_len = 0; + return 1; + } else { + j = bl - i; + OPENSSL_memcpy(&ctx->buf[i], in, j); + if (!ctx->cipher->cipher(ctx, out, ctx->buf, bl)) { + return 0; + } + in_len -= j; + in += j; + out += bl; + *out_len = bl; + } + } else { + *out_len = 0; + } + + i = in_len & ctx->block_mask; + in_len -= i; + if (in_len > 0) { + if (!ctx->cipher->cipher(ctx, out, in, in_len)) { + return 0; + } + *out_len += in_len; + } + + if (i != 0) { + OPENSSL_memcpy(ctx->buf, &in[in_len], i); + } + ctx->buf_len = i; + return 1; +} + +int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, uint8_t *out, int *out_len) { + int n, ret; + unsigned int i, b, bl; + + if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) { + ret = ctx->cipher->cipher(ctx, out, NULL, 0); + if (ret < 0) { + return 0; + } else { + *out_len = ret; + } + return 1; + } + + b = ctx->cipher->block_size; + assert(b <= sizeof(ctx->buf)); + if (b == 1) { + *out_len = 0; + return 1; + } + + bl = ctx->buf_len; + if (ctx->flags & EVP_CIPH_NO_PADDING) { + if (bl) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH); + return 0; + } + *out_len = 0; + return 1; + } + + n = b - bl; + for (i = bl; i < b; i++) { + ctx->buf[i] = n; + } + ret = ctx->cipher->cipher(ctx, out, ctx->buf, b); + + if (ret) { + *out_len = b; + } + + return ret; +} + +int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, uint8_t *out, int *out_len, + const uint8_t *in, int in_len) { + int fix_len; + unsigned int b; + + if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) { + int r = ctx->cipher->cipher(ctx, out, in, in_len); + if (r < 0) { + *out_len = 0; + return 0; + } else { + *out_len = r; + } + return 1; + } + + if (in_len <= 0) { + *out_len = 0; + return in_len == 0; + } + + if (ctx->flags & EVP_CIPH_NO_PADDING) { + return EVP_EncryptUpdate(ctx, out, out_len, in, in_len); + } + + b = ctx->cipher->block_size; + assert(b <= sizeof(ctx->final)); + + if (ctx->final_used) { + OPENSSL_memcpy(out, ctx->final, b); + out += b; + fix_len = 1; + } else { + fix_len = 0; + } + + if (!EVP_EncryptUpdate(ctx, out, out_len, in, in_len)) { + 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) { + *out_len -= b; + ctx->final_used = 1; + OPENSSL_memcpy(ctx->final, &out[*out_len], b); + } else { + ctx->final_used = 0; + } + + if (fix_len) { + *out_len += b; + } + + return 1; +} + +int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *out_len) { + int i, n; + unsigned int b; + *out_len = 0; + + if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) { + i = ctx->cipher->cipher(ctx, out, NULL, 0); + if (i < 0) { + return 0; + } else { + *out_len = i; + } + return 1; + } + + b = ctx->cipher->block_size; + if (ctx->flags & EVP_CIPH_NO_PADDING) { + if (ctx->buf_len) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH); + return 0; + } + *out_len = 0; + return 1; + } + + if (b > 1) { + if (ctx->buf_len || !ctx->final_used) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_WRONG_FINAL_BLOCK_LENGTH); + return 0; + } + 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) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT); + return 0; + } + + for (i = 0; i < n; i++) { + if (ctx->final[--b] != n) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT); + return 0; + } + } + + n = ctx->cipher->block_size - n; + for (i = 0; i < n; i++) { + out[i] = ctx->final[i]; + } + *out_len = n; + } else { + *out_len = 0; + } + + return 1; +} + +int EVP_Cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in, + size_t in_len) { + return ctx->cipher->cipher(ctx, out, in, in_len); +} + +int EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, uint8_t *out, int *out_len, + const uint8_t *in, int in_len) { + if (ctx->encrypt) { + return EVP_EncryptUpdate(ctx, out, out_len, in, in_len); + } else { + return EVP_DecryptUpdate(ctx, out, out_len, in, in_len); + } +} + +int EVP_CipherFinal_ex(EVP_CIPHER_CTX *ctx, uint8_t *out, int *out_len) { + if (ctx->encrypt) { + return EVP_EncryptFinal_ex(ctx, out, out_len); + } else { + return EVP_DecryptFinal_ex(ctx, out, out_len); + } +} + +const EVP_CIPHER *EVP_CIPHER_CTX_cipher(const EVP_CIPHER_CTX *ctx) { + return ctx->cipher; +} + +int EVP_CIPHER_CTX_nid(const EVP_CIPHER_CTX *ctx) { + return ctx->cipher->nid; +} + +unsigned EVP_CIPHER_CTX_block_size(const EVP_CIPHER_CTX *ctx) { + return ctx->cipher->block_size; +} + +unsigned EVP_CIPHER_CTX_key_length(const EVP_CIPHER_CTX *ctx) { + return ctx->key_len; +} + +unsigned EVP_CIPHER_CTX_iv_length(const EVP_CIPHER_CTX *ctx) { + return ctx->cipher->iv_len; +} + +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; +} + +uint32_t EVP_CIPHER_CTX_flags(const EVP_CIPHER_CTX *ctx) { + return ctx->cipher->flags & ~EVP_CIPH_MODE_MASK; +} + +uint32_t EVP_CIPHER_CTX_mode(const EVP_CIPHER_CTX *ctx) { + return ctx->cipher->flags & EVP_CIPH_MODE_MASK; +} + +int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int command, int arg, void *ptr) { + int ret; + if (!ctx->cipher) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_NO_CIPHER_SET); + return 0; + } + + if (!ctx->cipher->ctrl) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_CTRL_NOT_IMPLEMENTED); + return 0; + } + + ret = ctx->cipher->ctrl(ctx, command, arg, ptr); + if (ret == -1) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_CTRL_OPERATION_NOT_IMPLEMENTED); + return 0; + } + + return ret; +} + +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_set_key_length(EVP_CIPHER_CTX *c, unsigned key_len) { + if (c->key_len == key_len) { + return 1; + } + + if (key_len == 0 || !(c->cipher->flags & EVP_CIPH_VARIABLE_LENGTH)) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_KEY_LENGTH); + return 0; + } + + c->key_len = key_len; + return 1; +} + +int EVP_CIPHER_nid(const EVP_CIPHER *cipher) { return cipher->nid; } + +unsigned EVP_CIPHER_block_size(const EVP_CIPHER *cipher) { + return cipher->block_size; +} + +unsigned EVP_CIPHER_key_length(const EVP_CIPHER *cipher) { + return cipher->key_len; +} + +unsigned EVP_CIPHER_iv_length(const EVP_CIPHER *cipher) { + return cipher->iv_len; +} + +uint32_t EVP_CIPHER_flags(const EVP_CIPHER *cipher) { + return cipher->flags & ~EVP_CIPH_MODE_MASK; +} + +uint32_t EVP_CIPHER_mode(const EVP_CIPHER *cipher) { + return cipher->flags & EVP_CIPH_MODE_MASK; +} + +int EVP_CipherInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + const uint8_t *key, const uint8_t *iv, int enc) { + if (cipher) { + EVP_CIPHER_CTX_init(ctx); + } + return EVP_CipherInit_ex(ctx, cipher, NULL, key, iv, enc); +} + +int EVP_EncryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + const uint8_t *key, const uint8_t *iv) { + return EVP_CipherInit(ctx, cipher, key, iv, 1); +} + +int EVP_DecryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + const uint8_t *key, const uint8_t *iv) { + return EVP_CipherInit(ctx, cipher, key, iv, 0); +} + +int EVP_add_cipher_alias(const char *a, const char *b) { + return 1; +} + +void EVP_CIPHER_CTX_set_flags(const EVP_CIPHER_CTX *ctx, uint32_t flags) {} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/cipher/cipher.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/cipher/cipher.c.grpc_back new file mode 100644 index 0000000..f3d4057 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/cipher/cipher.c.grpc_back @@ -0,0 +1,615 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 +#include + +#include "internal.h" +#include "../../internal.h" + + +void EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *ctx) { + OPENSSL_memset(ctx, 0, sizeof(EVP_CIPHER_CTX)); +} + +EVP_CIPHER_CTX *EVP_CIPHER_CTX_new(void) { + EVP_CIPHER_CTX *ctx = OPENSSL_malloc(sizeof(EVP_CIPHER_CTX)); + if (ctx) { + EVP_CIPHER_CTX_init(ctx); + } + return ctx; +} + +int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *c) { + if (c->cipher != NULL && c->cipher->cleanup) { + c->cipher->cleanup(c); + } + OPENSSL_free(c->cipher_data); + + OPENSSL_memset(c, 0, sizeof(EVP_CIPHER_CTX)); + 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_copy(EVP_CIPHER_CTX *out, const EVP_CIPHER_CTX *in) { + if (in == NULL || in->cipher == NULL) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INPUT_NOT_INITIALIZED); + return 0; + } + + EVP_CIPHER_CTX_cleanup(out); + OPENSSL_memcpy(out, in, sizeof(EVP_CIPHER_CTX)); + + if (in->cipher_data && in->cipher->ctx_size) { + out->cipher_data = OPENSSL_malloc(in->cipher->ctx_size); + if (!out->cipher_data) { + out->cipher = NULL; + OPENSSL_PUT_ERROR(CIPHER, ERR_R_MALLOC_FAILURE); + return 0; + } + OPENSSL_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; + return 0; + } + } + + return 1; +} + +void EVP_CIPHER_CTX_reset(EVP_CIPHER_CTX *ctx) { + EVP_CIPHER_CTX_cleanup(ctx); + EVP_CIPHER_CTX_init(ctx); +} + +int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + ENGINE *engine, const uint8_t *key, const uint8_t *iv, + int enc) { + if (enc == -1) { + enc = ctx->encrypt; + } else { + if (enc) { + enc = 1; + } + ctx->encrypt = enc; + } + + if (cipher) { + // Ensure a context left 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) { + EVP_CIPHER_CTX_cleanup(ctx); + // Restore encrypt and flags + ctx->encrypt = enc; + } + + ctx->cipher = cipher; + if (ctx->cipher->ctx_size) { + ctx->cipher_data = OPENSSL_malloc(ctx->cipher->ctx_size); + if (!ctx->cipher_data) { + ctx->cipher = NULL; + OPENSSL_PUT_ERROR(CIPHER, ERR_R_MALLOC_FAILURE); + return 0; + } + } else { + ctx->cipher_data = NULL; + } + + ctx->key_len = cipher->key_len; + ctx->flags = 0; + + if (ctx->cipher->flags & EVP_CIPH_CTRL_INIT) { + if (!EVP_CIPHER_CTX_ctrl(ctx, EVP_CTRL_INIT, 0, NULL)) { + ctx->cipher = NULL; + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INITIALIZATION_ERROR); + return 0; + } + } + } else if (!ctx->cipher) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_NO_CIPHER_SET); + return 0; + } + + // we assume block size is a power of 2 in *cryptUpdate + assert(ctx->cipher->block_size == 1 || ctx->cipher->block_size == 8 || + ctx->cipher->block_size == 16); + + 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: + ctx->num = 0; + // fall-through + + case EVP_CIPH_CBC_MODE: + assert(EVP_CIPHER_CTX_iv_length(ctx) <= sizeof(ctx->iv)); + if (iv) { + OPENSSL_memcpy(ctx->oiv, iv, EVP_CIPHER_CTX_iv_length(ctx)); + } + OPENSSL_memcpy(ctx->iv, ctx->oiv, EVP_CIPHER_CTX_iv_length(ctx)); + break; + + case EVP_CIPH_CTR_MODE: + case EVP_CIPH_OFB_MODE: + ctx->num = 0; + // Don't reuse IV for CTR mode + if (iv) { + OPENSSL_memcpy(ctx->iv, iv, EVP_CIPHER_CTX_iv_length(ctx)); + } + break; + + default: + return 0; + } + } + + 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_EncryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + ENGINE *impl, const uint8_t *key, const uint8_t *iv) { + return EVP_CipherInit_ex(ctx, cipher, impl, key, iv, 1); +} + +int EVP_DecryptInit_ex(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + ENGINE *impl, const uint8_t *key, const uint8_t *iv) { + return EVP_CipherInit_ex(ctx, cipher, impl, key, iv, 0); +} + +int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, uint8_t *out, int *out_len, + const uint8_t *in, int in_len) { + int i, j, bl; + + if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) { + i = ctx->cipher->cipher(ctx, out, in, in_len); + if (i < 0) { + return 0; + } else { + *out_len = i; + } + return 1; + } + + if (in_len <= 0) { + *out_len = 0; + return in_len == 0; + } + + if (ctx->buf_len == 0 && (in_len & ctx->block_mask) == 0) { + if (ctx->cipher->cipher(ctx, out, in, in_len)) { + *out_len = in_len; + return 1; + } else { + *out_len = 0; + return 0; + } + } + + i = ctx->buf_len; + bl = ctx->cipher->block_size; + assert(bl <= (int)sizeof(ctx->buf)); + if (i != 0) { + if (bl - i > in_len) { + OPENSSL_memcpy(&ctx->buf[i], in, in_len); + ctx->buf_len += in_len; + *out_len = 0; + return 1; + } else { + j = bl - i; + OPENSSL_memcpy(&ctx->buf[i], in, j); + if (!ctx->cipher->cipher(ctx, out, ctx->buf, bl)) { + return 0; + } + in_len -= j; + in += j; + out += bl; + *out_len = bl; + } + } else { + *out_len = 0; + } + + i = in_len & ctx->block_mask; + in_len -= i; + if (in_len > 0) { + if (!ctx->cipher->cipher(ctx, out, in, in_len)) { + return 0; + } + *out_len += in_len; + } + + if (i != 0) { + OPENSSL_memcpy(ctx->buf, &in[in_len], i); + } + ctx->buf_len = i; + return 1; +} + +int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, uint8_t *out, int *out_len) { + int n, ret; + unsigned int i, b, bl; + + if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) { + ret = ctx->cipher->cipher(ctx, out, NULL, 0); + if (ret < 0) { + return 0; + } else { + *out_len = ret; + } + return 1; + } + + b = ctx->cipher->block_size; + assert(b <= sizeof(ctx->buf)); + if (b == 1) { + *out_len = 0; + return 1; + } + + bl = ctx->buf_len; + if (ctx->flags & EVP_CIPH_NO_PADDING) { + if (bl) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH); + return 0; + } + *out_len = 0; + return 1; + } + + n = b - bl; + for (i = bl; i < b; i++) { + ctx->buf[i] = n; + } + ret = ctx->cipher->cipher(ctx, out, ctx->buf, b); + + if (ret) { + *out_len = b; + } + + return ret; +} + +int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, uint8_t *out, int *out_len, + const uint8_t *in, int in_len) { + int fix_len; + unsigned int b; + + if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) { + int r = ctx->cipher->cipher(ctx, out, in, in_len); + if (r < 0) { + *out_len = 0; + return 0; + } else { + *out_len = r; + } + return 1; + } + + if (in_len <= 0) { + *out_len = 0; + return in_len == 0; + } + + if (ctx->flags & EVP_CIPH_NO_PADDING) { + return EVP_EncryptUpdate(ctx, out, out_len, in, in_len); + } + + b = ctx->cipher->block_size; + assert(b <= sizeof(ctx->final)); + + if (ctx->final_used) { + OPENSSL_memcpy(out, ctx->final, b); + out += b; + fix_len = 1; + } else { + fix_len = 0; + } + + if (!EVP_EncryptUpdate(ctx, out, out_len, in, in_len)) { + 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) { + *out_len -= b; + ctx->final_used = 1; + OPENSSL_memcpy(ctx->final, &out[*out_len], b); + } else { + ctx->final_used = 0; + } + + if (fix_len) { + *out_len += b; + } + + return 1; +} + +int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, int *out_len) { + int i, n; + unsigned int b; + *out_len = 0; + + if (ctx->cipher->flags & EVP_CIPH_FLAG_CUSTOM_CIPHER) { + i = ctx->cipher->cipher(ctx, out, NULL, 0); + if (i < 0) { + return 0; + } else { + *out_len = i; + } + return 1; + } + + b = ctx->cipher->block_size; + if (ctx->flags & EVP_CIPH_NO_PADDING) { + if (ctx->buf_len) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH); + return 0; + } + *out_len = 0; + return 1; + } + + if (b > 1) { + if (ctx->buf_len || !ctx->final_used) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_WRONG_FINAL_BLOCK_LENGTH); + return 0; + } + 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) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT); + return 0; + } + + for (i = 0; i < n; i++) { + if (ctx->final[--b] != n) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT); + return 0; + } + } + + n = ctx->cipher->block_size - n; + for (i = 0; i < n; i++) { + out[i] = ctx->final[i]; + } + *out_len = n; + } else { + *out_len = 0; + } + + return 1; +} + +int EVP_Cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in, + size_t in_len) { + return ctx->cipher->cipher(ctx, out, in, in_len); +} + +int EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, uint8_t *out, int *out_len, + const uint8_t *in, int in_len) { + if (ctx->encrypt) { + return EVP_EncryptUpdate(ctx, out, out_len, in, in_len); + } else { + return EVP_DecryptUpdate(ctx, out, out_len, in, in_len); + } +} + +int EVP_CipherFinal_ex(EVP_CIPHER_CTX *ctx, uint8_t *out, int *out_len) { + if (ctx->encrypt) { + return EVP_EncryptFinal_ex(ctx, out, out_len); + } else { + return EVP_DecryptFinal_ex(ctx, out, out_len); + } +} + +const EVP_CIPHER *EVP_CIPHER_CTX_cipher(const EVP_CIPHER_CTX *ctx) { + return ctx->cipher; +} + +int EVP_CIPHER_CTX_nid(const EVP_CIPHER_CTX *ctx) { + return ctx->cipher->nid; +} + +unsigned EVP_CIPHER_CTX_block_size(const EVP_CIPHER_CTX *ctx) { + return ctx->cipher->block_size; +} + +unsigned EVP_CIPHER_CTX_key_length(const EVP_CIPHER_CTX *ctx) { + return ctx->key_len; +} + +unsigned EVP_CIPHER_CTX_iv_length(const EVP_CIPHER_CTX *ctx) { + return ctx->cipher->iv_len; +} + +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; +} + +uint32_t EVP_CIPHER_CTX_flags(const EVP_CIPHER_CTX *ctx) { + return ctx->cipher->flags & ~EVP_CIPH_MODE_MASK; +} + +uint32_t EVP_CIPHER_CTX_mode(const EVP_CIPHER_CTX *ctx) { + return ctx->cipher->flags & EVP_CIPH_MODE_MASK; +} + +int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int command, int arg, void *ptr) { + int ret; + if (!ctx->cipher) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_NO_CIPHER_SET); + return 0; + } + + if (!ctx->cipher->ctrl) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_CTRL_NOT_IMPLEMENTED); + return 0; + } + + ret = ctx->cipher->ctrl(ctx, command, arg, ptr); + if (ret == -1) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_CTRL_OPERATION_NOT_IMPLEMENTED); + return 0; + } + + return ret; +} + +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_set_key_length(EVP_CIPHER_CTX *c, unsigned key_len) { + if (c->key_len == key_len) { + return 1; + } + + if (key_len == 0 || !(c->cipher->flags & EVP_CIPH_VARIABLE_LENGTH)) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_KEY_LENGTH); + return 0; + } + + c->key_len = key_len; + return 1; +} + +int EVP_CIPHER_nid(const EVP_CIPHER *cipher) { return cipher->nid; } + +unsigned EVP_CIPHER_block_size(const EVP_CIPHER *cipher) { + return cipher->block_size; +} + +unsigned EVP_CIPHER_key_length(const EVP_CIPHER *cipher) { + return cipher->key_len; +} + +unsigned EVP_CIPHER_iv_length(const EVP_CIPHER *cipher) { + return cipher->iv_len; +} + +uint32_t EVP_CIPHER_flags(const EVP_CIPHER *cipher) { + return cipher->flags & ~EVP_CIPH_MODE_MASK; +} + +uint32_t EVP_CIPHER_mode(const EVP_CIPHER *cipher) { + return cipher->flags & EVP_CIPH_MODE_MASK; +} + +int EVP_CipherInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + const uint8_t *key, const uint8_t *iv, int enc) { + if (cipher) { + EVP_CIPHER_CTX_init(ctx); + } + return EVP_CipherInit_ex(ctx, cipher, NULL, key, iv, enc); +} + +int EVP_EncryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + const uint8_t *key, const uint8_t *iv) { + return EVP_CipherInit(ctx, cipher, key, iv, 1); +} + +int EVP_DecryptInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + const uint8_t *key, const uint8_t *iv) { + return EVP_CipherInit(ctx, cipher, key, iv, 0); +} + +int EVP_add_cipher_alias(const char *a, const char *b) { + return 1; +} + +void EVP_CIPHER_CTX_set_flags(const EVP_CIPHER_CTX *ctx, uint32_t flags) {} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/cipher/e_aes.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/cipher/e_aes.c new file mode 100644 index 0000000..5530788 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/cipher/e_aes.c @@ -0,0 +1,1437 @@ +/* ==================================================================== + * Copyright (c) 2001-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 + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "internal.h" +#include "../../internal.h" +#include "../aes/internal.h" +#include "../modes/internal.h" +#include "../delocate.h" + +#if defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64) +#include +#endif + + +OPENSSL_MSVC_PRAGMA(warning(disable: 4702)) // Unreachable code. + +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; + uint8_t *iv; // Temporary IV store + int ivlen; // IV length + int taglen; + int iv_gen; // It is OK to generate IVs + ctr128_f ctr; +} EVP_AES_GCM_CTX; + +#if !defined(OPENSSL_NO_ASM) && \ + (defined(OPENSSL_X86_64) || defined(OPENSSL_X86)) +#define VPAES +static char vpaes_capable(void) { + return (OPENSSL_ia32cap_P[1] & (1 << (41 - 32))) != 0; +} + +#if defined(OPENSSL_X86_64) +#define BSAES +static char bsaes_capable(void) { + return vpaes_capable(); +} +#endif + +#elif !defined(OPENSSL_NO_ASM) && \ + (defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)) + +#if defined(OPENSSL_ARM) && __ARM_MAX_ARCH__ >= 7 +#define BSAES +static char bsaes_capable(void) { + return CRYPTO_is_NEON_capable(); +} +#endif + +#endif + + +#if defined(BSAES) +// On platforms where BSAES gets defined (just above), then these functions are +// provided by asm. +void bsaes_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t length, + const AES_KEY *key, uint8_t ivec[16], int enc); +void bsaes_ctr32_encrypt_blocks(const uint8_t *in, uint8_t *out, size_t len, + const AES_KEY *key, const uint8_t ivec[16]); +#else +static char bsaes_capable(void) { + return 0; +} + +// On other platforms, bsaes_capable() will always return false and so the +// following will never be called. +static void bsaes_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t length, + const AES_KEY *key, uint8_t ivec[16], int enc) { + abort(); +} + +static void bsaes_ctr32_encrypt_blocks(const uint8_t *in, uint8_t *out, + size_t len, const AES_KEY *key, + const uint8_t ivec[16]) { + abort(); +} +#endif + +#if defined(VPAES) +// On platforms where VPAES gets defined (just above), then these functions are +// provided by asm. +int vpaes_set_encrypt_key(const uint8_t *userKey, int bits, AES_KEY *key); +int vpaes_set_decrypt_key(const uint8_t *userKey, int bits, AES_KEY *key); + +void vpaes_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key); +void vpaes_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key); + +void vpaes_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t length, + const AES_KEY *key, uint8_t *ivec, int enc); +#else +static char vpaes_capable(void) { + return 0; +} + +// On other platforms, vpaes_capable() will always return false and so the +// following will never be called. +static int vpaes_set_encrypt_key(const uint8_t *userKey, int bits, + AES_KEY *key) { + abort(); +} +static int vpaes_set_decrypt_key(const uint8_t *userKey, int bits, + AES_KEY *key) { + abort(); +} +static void vpaes_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key) { + abort(); +} +static void vpaes_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key) { + abort(); +} +static void vpaes_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t length, + const AES_KEY *key, uint8_t *ivec, int enc) { + abort(); +} +#endif + +#if !defined(OPENSSL_NO_ASM) && \ + (defined(OPENSSL_X86_64) || defined(OPENSSL_X86)) +int aesni_set_encrypt_key(const uint8_t *userKey, int bits, AES_KEY *key); +int aesni_set_decrypt_key(const uint8_t *userKey, int bits, AES_KEY *key); + +void aesni_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key); +void aesni_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key); + +void aesni_ecb_encrypt(const uint8_t *in, uint8_t *out, size_t length, + const AES_KEY *key, int enc); +void aesni_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t length, + const AES_KEY *key, uint8_t *ivec, int enc); + +#else + +// On other platforms, aesni_capable() will always return false and so the +// following will never be called. +static void aesni_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key) { + abort(); +} +static int aesni_set_encrypt_key(const uint8_t *userKey, int bits, + AES_KEY *key) { + abort(); +} +static void aesni_ctr32_encrypt_blocks(const uint8_t *in, uint8_t *out, + size_t blocks, const void *key, + const uint8_t *ivec) { + abort(); +} + +#endif + +static int aes_init_key(EVP_CIPHER_CTX *ctx, const uint8_t *key, + const uint8_t *iv, int enc) { + int ret, mode; + EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data; + + mode = ctx->cipher->flags & EVP_CIPH_MODE_MASK; + if ((mode == EVP_CIPH_ECB_MODE || mode == EVP_CIPH_CBC_MODE) && !enc) { + if (hwaes_capable()) { + ret = aes_hw_set_decrypt_key(key, ctx->key_len * 8, &dat->ks.ks); + dat->block = (block128_f)aes_hw_decrypt; + dat->stream.cbc = NULL; + if (mode == EVP_CIPH_CBC_MODE) { + dat->stream.cbc = (cbc128_f)aes_hw_cbc_encrypt; + } + } else 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 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 { + 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 if (hwaes_capable()) { + ret = aes_hw_set_encrypt_key(key, ctx->key_len * 8, &dat->ks.ks); + dat->block = (block128_f)aes_hw_encrypt; + dat->stream.cbc = NULL; + if (mode == EVP_CIPH_CBC_MODE) { + dat->stream.cbc = (cbc128_f)aes_hw_cbc_encrypt; + } else if (mode == EVP_CIPH_CTR_MODE) { + dat->stream.ctr = (ctr128_f)aes_hw_ctr32_encrypt_blocks; + } + } else 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 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 { + 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; + } + + if (ret < 0) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_AES_KEY_SETUP_FAILED); + return 0; + } + + return 1; +} + +static int aes_cbc_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *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, uint8_t *out, const uint8_t *in, + size_t len) { + size_t bl = ctx->cipher->block_size; + EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data; + + if (len < bl) { + return 1; + } + + len -= bl; + for (size_t i = 0; i <= len; i += bl) { + (*dat->block)(in + i, out + i, &dat->ks); + } + + return 1; +} + +static int aes_ctr_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in, + size_t len) { + 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, + &ctx->num, dat->stream.ctr); + } else { + CRYPTO_ctr128_encrypt(in, out, len, &dat->ks, ctx->iv, ctx->buf, &ctx->num, + dat->block); + } + return 1; +} + +static int aes_ofb_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *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 char aesni_capable(void); + +ctr128_f aes_ctr_set_key(AES_KEY *aes_key, GCM128_CONTEXT *gcm_ctx, + block128_f *out_block, const uint8_t *key, + size_t key_bytes) { + if (aesni_capable()) { + aesni_set_encrypt_key(key, key_bytes * 8, aes_key); + if (gcm_ctx != NULL) { + CRYPTO_gcm128_init(gcm_ctx, aes_key, (block128_f)aesni_encrypt, 1); + } + if (out_block) { + *out_block = (block128_f) aesni_encrypt; + } + return (ctr128_f)aesni_ctr32_encrypt_blocks; + } + + if (hwaes_capable()) { + aes_hw_set_encrypt_key(key, key_bytes * 8, aes_key); + if (gcm_ctx != NULL) { + CRYPTO_gcm128_init(gcm_ctx, aes_key, (block128_f)aes_hw_encrypt, 0); + } + if (out_block) { + *out_block = (block128_f) aes_hw_encrypt; + } + return (ctr128_f)aes_hw_ctr32_encrypt_blocks; + } + + if (bsaes_capable()) { + AES_set_encrypt_key(key, key_bytes * 8, aes_key); + if (gcm_ctx != NULL) { + CRYPTO_gcm128_init(gcm_ctx, aes_key, (block128_f)AES_encrypt, 0); + } + if (out_block) { + *out_block = (block128_f) AES_encrypt; + } + return (ctr128_f)bsaes_ctr32_encrypt_blocks; + } + + if (vpaes_capable()) { + vpaes_set_encrypt_key(key, key_bytes * 8, aes_key); + if (out_block) { + *out_block = (block128_f) vpaes_encrypt; + } + if (gcm_ctx != NULL) { + CRYPTO_gcm128_init(gcm_ctx, aes_key, (block128_f)vpaes_encrypt, 0); + } + return NULL; + } + + AES_set_encrypt_key(key, key_bytes * 8, aes_key); + if (gcm_ctx != NULL) { + CRYPTO_gcm128_init(gcm_ctx, aes_key, (block128_f)AES_encrypt, 0); + } + if (out_block) { + *out_block = (block128_f) AES_encrypt; + } + return NULL; +} + +static int aes_gcm_init_key(EVP_CIPHER_CTX *ctx, const uint8_t *key, + const uint8_t *iv, int enc) { + EVP_AES_GCM_CTX *gctx = ctx->cipher_data; + if (!iv && !key) { + return 1; + } + if (key) { + gctx->ctr = + aes_ctr_set_key(&gctx->ks.ks, &gctx->gcm, NULL, key, ctx->key_len); + // 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, &gctx->ks.ks, 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, &gctx->ks.ks, iv, gctx->ivlen); + } else { + OPENSSL_memcpy(gctx->iv, iv, gctx->ivlen); + } + gctx->iv_set = 1; + gctx->iv_gen = 0; + } + return 1; +} + +static void aes_gcm_cleanup(EVP_CIPHER_CTX *c) { + EVP_AES_GCM_CTX *gctx = c->cipher_data; + OPENSSL_cleanse(&gctx->gcm, sizeof(gctx->gcm)); + if (gctx->iv != c->iv) { + OPENSSL_free(gctx->iv); + } +} + +// increment counter (64-bit int) by 1 +static void ctr64_inc(uint8_t *counter) { + int n = 8; + uint8_t 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; + 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; + } + OPENSSL_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; + } + OPENSSL_memcpy(ptr, c->buf, arg); + return 1; + + case EVP_CTRL_GCM_SET_IV_FIXED: + // Special case: -1 length restores whole IV + if (arg == -1) { + OPENSSL_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) { + OPENSSL_memcpy(gctx->iv, ptr, arg); + } + if (c->encrypt && !RAND_bytes(gctx->iv + arg, gctx->ivlen - arg)) { + 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->ks.ks, gctx->iv, gctx->ivlen); + if (arg <= 0 || arg > gctx->ivlen) { + arg = gctx->ivlen; + } + OPENSSL_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; + } + OPENSSL_memcpy(gctx->iv + gctx->ivlen - arg, ptr, arg); + CRYPTO_gcm128_setiv(&gctx->gcm, &gctx->ks.ks, gctx->iv, gctx->ivlen); + gctx->iv_set = 1; + return 1; + + case EVP_CTRL_COPY: { + EVP_CIPHER_CTX *out = ptr; + EVP_AES_GCM_CTX *gctx_out = out->cipher_data; + if (gctx->iv == c->iv) { + gctx_out->iv = out->iv; + } else { + gctx_out->iv = OPENSSL_malloc(gctx->ivlen); + if (!gctx_out->iv) { + return 0; + } + OPENSSL_memcpy(gctx_out->iv, gctx->iv, gctx->ivlen); + } + return 1; + } + + default: + return -1; + } +} + +static int aes_gcm_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *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->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) { + if (!CRYPTO_gcm128_encrypt_ctr32(&gctx->gcm, &gctx->ks.ks, in, out, len, + gctx->ctr)) { + return -1; + } + } else { + if (!CRYPTO_gcm128_encrypt(&gctx->gcm, &gctx->ks.ks, in, out, len)) { + return -1; + } + } + } else { + if (gctx->ctr) { + if (!CRYPTO_gcm128_decrypt_ctr32(&gctx->gcm, &gctx->ks.ks, in, out, len, + gctx->ctr)) { + return -1; + } + } else { + if (!CRYPTO_gcm128_decrypt(&gctx->gcm, &gctx->ks.ks, in, out, len)) { + return -1; + } + } + } + return len; + } else { + if (!ctx->encrypt) { + if (gctx->taglen < 0 || + !CRYPTO_gcm128_finish(&gctx->gcm, ctx->buf, gctx->taglen)) { + 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_LOCAL_DATA(EVP_CIPHER, aes_128_cbc_generic) { + memset(out, 0, sizeof(EVP_CIPHER)); + + out->nid = NID_aes_128_cbc; + out->block_size = 16; + out->key_len = 16; + out->iv_len = 16; + out->ctx_size = sizeof(EVP_AES_KEY); + out->flags = EVP_CIPH_CBC_MODE; + out->init = aes_init_key; + out->cipher = aes_cbc_cipher; +} + +DEFINE_LOCAL_DATA(EVP_CIPHER, aes_128_ctr_generic) { + memset(out, 0, sizeof(EVP_CIPHER)); + + out->nid = NID_aes_128_ctr; + out->block_size = 1; + out->key_len = 16; + out->iv_len = 16; + out->ctx_size = sizeof(EVP_AES_KEY); + out->flags = EVP_CIPH_CTR_MODE; + out->init = aes_init_key; + out->cipher = aes_ctr_cipher; +} + +DEFINE_LOCAL_DATA(EVP_CIPHER, aes_128_ecb_generic) { + memset(out, 0, sizeof(EVP_CIPHER)); + + out->nid = NID_aes_128_ecb; + out->block_size = 16; + out->key_len = 16; + out->ctx_size = sizeof(EVP_AES_KEY); + out->flags = EVP_CIPH_ECB_MODE; + out->init = aes_init_key; + out->cipher = aes_ecb_cipher; +} + +DEFINE_LOCAL_DATA(EVP_CIPHER, aes_128_ofb_generic) { + memset(out, 0, sizeof(EVP_CIPHER)); + + out->nid = NID_aes_128_ofb128; + out->block_size = 1; + out->key_len = 16; + out->iv_len = 16; + out->ctx_size = sizeof(EVP_AES_KEY); + out->flags = EVP_CIPH_OFB_MODE; + out->init = aes_init_key; + out->cipher = aes_ofb_cipher; +} + +DEFINE_LOCAL_DATA(EVP_CIPHER, aes_128_gcm_generic) { + memset(out, 0, sizeof(EVP_CIPHER)); + + out->nid = NID_aes_128_gcm; + out->block_size = 1; + out->key_len = 16; + out->iv_len = 12; + out->ctx_size = sizeof(EVP_AES_GCM_CTX); + out->flags = EVP_CIPH_GCM_MODE | EVP_CIPH_CUSTOM_IV | + EVP_CIPH_FLAG_CUSTOM_CIPHER | EVP_CIPH_ALWAYS_CALL_INIT | + EVP_CIPH_CTRL_INIT | EVP_CIPH_FLAG_AEAD_CIPHER; + out->init = aes_gcm_init_key; + out->cipher = aes_gcm_cipher; + out->cleanup = aes_gcm_cleanup; + out->ctrl = aes_gcm_ctrl; +} + +DEFINE_LOCAL_DATA(EVP_CIPHER, aes_192_cbc_generic) { + memset(out, 0, sizeof(EVP_CIPHER)); + + out->nid = NID_aes_192_cbc; + out->block_size = 16; + out->key_len = 24; + out->iv_len = 16; + out->ctx_size = sizeof(EVP_AES_KEY); + out->flags = EVP_CIPH_CBC_MODE; + out->init = aes_init_key; + out->cipher = aes_cbc_cipher; +} + +DEFINE_LOCAL_DATA(EVP_CIPHER, aes_192_ctr_generic) { + memset(out, 0, sizeof(EVP_CIPHER)); + + out->nid = NID_aes_192_ctr; + out->block_size = 1; + out->key_len = 24; + out->iv_len = 16; + out->ctx_size = sizeof(EVP_AES_KEY); + out->flags = EVP_CIPH_CTR_MODE; + out->init = aes_init_key; + out->cipher = aes_ctr_cipher; +} + +DEFINE_LOCAL_DATA(EVP_CIPHER, aes_192_ecb_generic) { + memset(out, 0, sizeof(EVP_CIPHER)); + + out->nid = NID_aes_192_ecb; + out->block_size = 16; + out->key_len = 24; + out->ctx_size = sizeof(EVP_AES_KEY); + out->flags = EVP_CIPH_ECB_MODE; + out->init = aes_init_key; + out->cipher = aes_ecb_cipher; +} + +DEFINE_LOCAL_DATA(EVP_CIPHER, aes_192_gcm_generic) { + memset(out, 0, sizeof(EVP_CIPHER)); + + out->nid = NID_aes_192_gcm; + out->block_size = 1; + out->key_len = 24; + out->iv_len = 12; + out->ctx_size = sizeof(EVP_AES_GCM_CTX); + out->flags = EVP_CIPH_GCM_MODE | EVP_CIPH_CUSTOM_IV | + EVP_CIPH_FLAG_CUSTOM_CIPHER | EVP_CIPH_ALWAYS_CALL_INIT | + EVP_CIPH_CTRL_INIT | EVP_CIPH_FLAG_AEAD_CIPHER; + out->init = aes_gcm_init_key; + out->cipher = aes_gcm_cipher; + out->cleanup = aes_gcm_cleanup; + out->ctrl = aes_gcm_ctrl; +} + +DEFINE_LOCAL_DATA(EVP_CIPHER, aes_256_cbc_generic) { + memset(out, 0, sizeof(EVP_CIPHER)); + + out->nid = NID_aes_256_cbc; + out->block_size = 16; + out->key_len = 32; + out->iv_len = 16; + out->ctx_size = sizeof(EVP_AES_KEY); + out->flags = EVP_CIPH_CBC_MODE; + out->init = aes_init_key; + out->cipher = aes_cbc_cipher; +} + +DEFINE_LOCAL_DATA(EVP_CIPHER, aes_256_ctr_generic) { + memset(out, 0, sizeof(EVP_CIPHER)); + + out->nid = NID_aes_256_ctr; + out->block_size = 1; + out->key_len = 32; + out->iv_len = 16; + out->ctx_size = sizeof(EVP_AES_KEY); + out->flags = EVP_CIPH_CTR_MODE; + out->init = aes_init_key; + out->cipher = aes_ctr_cipher; +} + +DEFINE_LOCAL_DATA(EVP_CIPHER, aes_256_ecb_generic) { + memset(out, 0, sizeof(EVP_CIPHER)); + + out->nid = NID_aes_256_ecb; + out->block_size = 16; + out->key_len = 32; + out->ctx_size = sizeof(EVP_AES_KEY); + out->flags = EVP_CIPH_ECB_MODE; + out->init = aes_init_key; + out->cipher = aes_ecb_cipher; +} + +DEFINE_LOCAL_DATA(EVP_CIPHER, aes_256_ofb_generic) { + memset(out, 0, sizeof(EVP_CIPHER)); + + out->nid = NID_aes_256_ofb128; + out->block_size = 1; + out->key_len = 32; + out->iv_len = 16; + out->ctx_size = sizeof(EVP_AES_KEY); + out->flags = EVP_CIPH_OFB_MODE; + out->init = aes_init_key; + out->cipher = aes_ofb_cipher; +} + +DEFINE_LOCAL_DATA(EVP_CIPHER, aes_256_gcm_generic) { + memset(out, 0, sizeof(EVP_CIPHER)); + + out->nid = NID_aes_256_gcm; + out->block_size = 1; + out->key_len = 32; + out->iv_len = 12; + out->ctx_size = sizeof(EVP_AES_GCM_CTX); + out->flags = EVP_CIPH_GCM_MODE | EVP_CIPH_CUSTOM_IV | + EVP_CIPH_FLAG_CUSTOM_CIPHER | EVP_CIPH_ALWAYS_CALL_INIT | + EVP_CIPH_CTRL_INIT | EVP_CIPH_FLAG_AEAD_CIPHER; + out->init = aes_gcm_init_key; + out->cipher = aes_gcm_cipher; + out->cleanup = aes_gcm_cleanup; + out->ctrl = aes_gcm_ctrl; +} + +#if !defined(OPENSSL_NO_ASM) && \ + (defined(OPENSSL_X86_64) || defined(OPENSSL_X86)) + +// AES-NI section. + +static char aesni_capable(void) { + return (OPENSSL_ia32cap_P[1] & (1 << (57 - 32))) != 0; +} + +static int aesni_init_key(EVP_CIPHER_CTX *ctx, const uint8_t *key, + const uint8_t *iv, int enc) { + int ret, mode; + EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data; + + mode = ctx->cipher->flags & EVP_CIPH_MODE_MASK; + 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) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_AES_KEY_SETUP_FAILED); + return 0; + } + + return 1; +} + +static int aesni_cbc_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, + const uint8_t *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, uint8_t *out, + const uint8_t *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; +} + +static int aesni_gcm_init_key(EVP_CIPHER_CTX *ctx, const uint8_t *key, + const uint8_t *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, 1); + 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, &gctx->ks.ks, 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, &gctx->ks.ks, iv, gctx->ivlen); + } else { + OPENSSL_memcpy(gctx->iv, iv, gctx->ivlen); + } + gctx->iv_set = 1; + gctx->iv_gen = 0; + } + return 1; +} + +DEFINE_LOCAL_DATA(EVP_CIPHER, aesni_128_cbc) { + memset(out, 0, sizeof(EVP_CIPHER)); + + out->nid = NID_aes_128_cbc; + out->block_size = 16; + out->key_len = 16; + out->iv_len = 16; + out->ctx_size = sizeof(EVP_AES_KEY); + out->flags = EVP_CIPH_CBC_MODE; + out->init = aesni_init_key; + out->cipher = aesni_cbc_cipher; +} + +DEFINE_LOCAL_DATA(EVP_CIPHER, aesni_128_ctr) { + memset(out, 0, sizeof(EVP_CIPHER)); + + out->nid = NID_aes_128_ctr; + out->block_size = 1; + out->key_len = 16; + out->iv_len = 16; + out->ctx_size = sizeof(EVP_AES_KEY); + out->flags = EVP_CIPH_CTR_MODE; + out->init = aesni_init_key; + out->cipher = aes_ctr_cipher; +} + +DEFINE_LOCAL_DATA(EVP_CIPHER, aesni_128_ecb) { + memset(out, 0, sizeof(EVP_CIPHER)); + + out->nid = NID_aes_128_ecb; + out->block_size = 16; + out->key_len = 16; + out->ctx_size = sizeof(EVP_AES_KEY); + out->flags = EVP_CIPH_ECB_MODE; + out->init = aesni_init_key; + out->cipher = aesni_ecb_cipher; +} + +DEFINE_LOCAL_DATA(EVP_CIPHER, aesni_128_ofb) { + memset(out, 0, sizeof(EVP_CIPHER)); + + out->nid = NID_aes_128_ofb128; + out->block_size = 1; + out->key_len = 16; + out->iv_len = 16; + out->ctx_size = sizeof(EVP_AES_KEY); + out->flags = EVP_CIPH_OFB_MODE; + out->init = aesni_init_key; + out->cipher = aes_ofb_cipher; +} + +DEFINE_LOCAL_DATA(EVP_CIPHER, aesni_128_gcm) { + memset(out, 0, sizeof(EVP_CIPHER)); + + out->nid = NID_aes_128_gcm; + out->block_size = 1; + out->key_len = 16; + out->iv_len = 12; + out->ctx_size = sizeof(EVP_AES_GCM_CTX); + out->flags = EVP_CIPH_GCM_MODE | EVP_CIPH_CUSTOM_IV | + EVP_CIPH_FLAG_CUSTOM_CIPHER | EVP_CIPH_ALWAYS_CALL_INIT | + EVP_CIPH_CTRL_INIT | EVP_CIPH_FLAG_AEAD_CIPHER; + out->init = aesni_gcm_init_key; + out->cipher = aes_gcm_cipher; + out->cleanup = aes_gcm_cleanup; + out->ctrl = aes_gcm_ctrl; +} + +DEFINE_LOCAL_DATA(EVP_CIPHER, aesni_192_cbc) { + memset(out, 0, sizeof(EVP_CIPHER)); + + out->nid = NID_aes_192_cbc; + out->block_size = 16; + out->key_len = 24; + out->iv_len = 16; + out->ctx_size = sizeof(EVP_AES_KEY); + out->flags = EVP_CIPH_CBC_MODE; + out->init = aesni_init_key; + out->cipher = aesni_cbc_cipher; +} + +DEFINE_LOCAL_DATA(EVP_CIPHER, aesni_192_ctr) { + memset(out, 0, sizeof(EVP_CIPHER)); + + out->nid = NID_aes_192_ctr; + out->block_size = 1; + out->key_len = 24; + out->iv_len = 16; + out->ctx_size = sizeof(EVP_AES_KEY); + out->flags = EVP_CIPH_CTR_MODE; + out->init = aesni_init_key; + out->cipher = aes_ctr_cipher; +} + +DEFINE_LOCAL_DATA(EVP_CIPHER, aesni_192_ecb) { + memset(out, 0, sizeof(EVP_CIPHER)); + + out->nid = NID_aes_192_ecb; + out->block_size = 16; + out->key_len = 24; + out->ctx_size = sizeof(EVP_AES_KEY); + out->flags = EVP_CIPH_ECB_MODE; + out->init = aesni_init_key; + out->cipher = aesni_ecb_cipher; +} + +DEFINE_LOCAL_DATA(EVP_CIPHER, aesni_192_gcm) { + memset(out, 0, sizeof(EVP_CIPHER)); + + out->nid = NID_aes_192_gcm; + out->block_size = 1; + out->key_len = 24; + out->iv_len = 12; + out->ctx_size = sizeof(EVP_AES_GCM_CTX); + out->flags = EVP_CIPH_GCM_MODE | EVP_CIPH_CUSTOM_IV | + EVP_CIPH_FLAG_CUSTOM_CIPHER | EVP_CIPH_ALWAYS_CALL_INIT | + EVP_CIPH_CTRL_INIT | EVP_CIPH_FLAG_AEAD_CIPHER; + out->init = aesni_gcm_init_key; + out->cipher = aes_gcm_cipher; + out->cleanup = aes_gcm_cleanup; + out->ctrl = aes_gcm_ctrl; +} + +DEFINE_LOCAL_DATA(EVP_CIPHER, aesni_256_cbc) { + memset(out, 0, sizeof(EVP_CIPHER)); + + out->nid = NID_aes_256_cbc; + out->block_size = 16; + out->key_len = 32; + out->iv_len = 16; + out->ctx_size = sizeof(EVP_AES_KEY); + out->flags = EVP_CIPH_CBC_MODE; + out->init = aesni_init_key; + out->cipher = aesni_cbc_cipher; +} + +DEFINE_LOCAL_DATA(EVP_CIPHER, aesni_256_ctr) { + memset(out, 0, sizeof(EVP_CIPHER)); + + out->nid = NID_aes_256_ctr; + out->block_size = 1; + out->key_len = 32; + out->iv_len = 16; + out->ctx_size = sizeof(EVP_AES_KEY); + out->flags = EVP_CIPH_CTR_MODE; + out->init = aesni_init_key; + out->cipher = aes_ctr_cipher; +} + +DEFINE_LOCAL_DATA(EVP_CIPHER, aesni_256_ecb) { + memset(out, 0, sizeof(EVP_CIPHER)); + + out->nid = NID_aes_256_ecb; + out->block_size = 16; + out->key_len = 32; + out->ctx_size = sizeof(EVP_AES_KEY); + out->flags = EVP_CIPH_ECB_MODE; + out->init = aesni_init_key; + out->cipher = aesni_ecb_cipher; +} + +DEFINE_LOCAL_DATA(EVP_CIPHER, aesni_256_ofb) { + memset(out, 0, sizeof(EVP_CIPHER)); + + out->nid = NID_aes_256_ofb128; + out->block_size = 1; + out->key_len = 32; + out->iv_len = 16; + out->ctx_size = sizeof(EVP_AES_KEY); + out->flags = EVP_CIPH_OFB_MODE; + out->init = aesni_init_key; + out->cipher = aes_ofb_cipher; +} + +DEFINE_LOCAL_DATA(EVP_CIPHER, aesni_256_gcm) { + memset(out, 0, sizeof(EVP_CIPHER)); + + out->nid = NID_aes_256_gcm; + out->block_size = 1; + out->key_len = 32; + out->iv_len = 12; + out->ctx_size = sizeof(EVP_AES_GCM_CTX); + out->flags = EVP_CIPH_GCM_MODE | EVP_CIPH_CUSTOM_IV | + EVP_CIPH_FLAG_CUSTOM_CIPHER | EVP_CIPH_ALWAYS_CALL_INIT | + EVP_CIPH_CTRL_INIT | EVP_CIPH_CUSTOM_COPY | + EVP_CIPH_FLAG_AEAD_CIPHER; + out->init = aesni_gcm_init_key; + out->cipher = aes_gcm_cipher; + out->cleanup = aes_gcm_cleanup; + out->ctrl = aes_gcm_ctrl; +} + +#define EVP_CIPHER_FUNCTION(keybits, mode) \ + const EVP_CIPHER *EVP_aes_##keybits##_##mode(void) { \ + if (aesni_capable()) { \ + return aesni_##keybits##_##mode(); \ + } else { \ + return aes_##keybits##_##mode##_generic(); \ + } \ + } + +#else // ^^^ OPENSSL_X86_64 || OPENSSL_X86 + +static char aesni_capable(void) { + return 0; +} + +#define EVP_CIPHER_FUNCTION(keybits, mode) \ + const EVP_CIPHER *EVP_aes_##keybits##_##mode(void) { \ + return aes_##keybits##_##mode##_generic(); \ + } + +#endif + +EVP_CIPHER_FUNCTION(128, cbc) +EVP_CIPHER_FUNCTION(128, ctr) +EVP_CIPHER_FUNCTION(128, ecb) +EVP_CIPHER_FUNCTION(128, ofb) +EVP_CIPHER_FUNCTION(128, gcm) + +EVP_CIPHER_FUNCTION(192, cbc) +EVP_CIPHER_FUNCTION(192, ctr) +EVP_CIPHER_FUNCTION(192, ecb) +EVP_CIPHER_FUNCTION(192, gcm) + +EVP_CIPHER_FUNCTION(256, cbc) +EVP_CIPHER_FUNCTION(256, ctr) +EVP_CIPHER_FUNCTION(256, ecb) +EVP_CIPHER_FUNCTION(256, ofb) +EVP_CIPHER_FUNCTION(256, gcm) + + +#define EVP_AEAD_AES_GCM_TAG_LEN 16 + +struct aead_aes_gcm_ctx { + union { + double align; + AES_KEY ks; + } ks; + GCM128_CONTEXT gcm; + ctr128_f ctr; +}; + +struct aead_aes_gcm_tls12_ctx { + struct aead_aes_gcm_ctx gcm_ctx; + uint64_t min_next_nonce; +}; + +static int aead_aes_gcm_init_impl(struct aead_aes_gcm_ctx *gcm_ctx, + size_t *out_tag_len, const uint8_t *key, + size_t key_len, size_t tag_len) { + const size_t key_bits = key_len * 8; + + if (key_bits != 128 && key_bits != 256) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_KEY_LENGTH); + return 0; // EVP_AEAD_CTX_init should catch this. + } + + if (tag_len == EVP_AEAD_DEFAULT_TAG_LENGTH) { + tag_len = EVP_AEAD_AES_GCM_TAG_LEN; + } + + if (tag_len > EVP_AEAD_AES_GCM_TAG_LEN) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TAG_TOO_LARGE); + return 0; + } + + gcm_ctx->ctr = + aes_ctr_set_key(&gcm_ctx->ks.ks, &gcm_ctx->gcm, NULL, key, key_len); + *out_tag_len = tag_len; + return 1; +} + +static int aead_aes_gcm_init(EVP_AEAD_CTX *ctx, const uint8_t *key, + size_t key_len, size_t requested_tag_len) { + struct aead_aes_gcm_ctx *gcm_ctx; + gcm_ctx = OPENSSL_malloc(sizeof(struct aead_aes_gcm_ctx)); + if (gcm_ctx == NULL) { + return 0; + } + + size_t actual_tag_len; + if (!aead_aes_gcm_init_impl(gcm_ctx, &actual_tag_len, key, key_len, + requested_tag_len)) { + OPENSSL_free(gcm_ctx); + return 0; + } + + ctx->aead_state = gcm_ctx; + ctx->tag_len = actual_tag_len; + return 1; +} + +static void aead_aes_gcm_cleanup(EVP_AEAD_CTX *ctx) { + OPENSSL_free(ctx->aead_state); +} + +static int aead_aes_gcm_seal_scatter(const EVP_AEAD_CTX *ctx, uint8_t *out, + uint8_t *out_tag, size_t *out_tag_len, + size_t max_out_tag_len, + const uint8_t *nonce, size_t nonce_len, + const uint8_t *in, size_t in_len, + const uint8_t *extra_in, + size_t extra_in_len, + const uint8_t *ad, size_t ad_len) { + const struct aead_aes_gcm_ctx *gcm_ctx = ctx->aead_state; + GCM128_CONTEXT gcm; + + if (extra_in_len + ctx->tag_len < ctx->tag_len) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE); + return 0; + } + if (max_out_tag_len < extra_in_len + ctx->tag_len) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL); + return 0; + } + if (nonce_len == 0) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_NONCE_SIZE); + return 0; + } + + const AES_KEY *key = &gcm_ctx->ks.ks; + + OPENSSL_memcpy(&gcm, &gcm_ctx->gcm, sizeof(gcm)); + CRYPTO_gcm128_setiv(&gcm, key, nonce, nonce_len); + + if (ad_len > 0 && !CRYPTO_gcm128_aad(&gcm, ad, ad_len)) { + return 0; + } + + if (gcm_ctx->ctr) { + if (!CRYPTO_gcm128_encrypt_ctr32(&gcm, key, in, out, in_len, + gcm_ctx->ctr)) { + return 0; + } + } else { + if (!CRYPTO_gcm128_encrypt(&gcm, key, in, out, in_len)) { + return 0; + } + } + + if (extra_in_len) { + if (gcm_ctx->ctr) { + if (!CRYPTO_gcm128_encrypt_ctr32(&gcm, key, extra_in, out_tag, + extra_in_len, gcm_ctx->ctr)) { + return 0; + } + } else { + if (!CRYPTO_gcm128_encrypt(&gcm, key, extra_in, out_tag, extra_in_len)) { + return 0; + } + } + } + + CRYPTO_gcm128_tag(&gcm, out_tag + extra_in_len, ctx->tag_len); + *out_tag_len = ctx->tag_len + extra_in_len; + + return 1; +} + +static int aead_aes_gcm_open_gather(const EVP_AEAD_CTX *ctx, uint8_t *out, + const uint8_t *nonce, size_t nonce_len, + const uint8_t *in, size_t in_len, + const uint8_t *in_tag, size_t in_tag_len, + const uint8_t *ad, size_t ad_len) { + const struct aead_aes_gcm_ctx *gcm_ctx = ctx->aead_state; + uint8_t tag[EVP_AEAD_AES_GCM_TAG_LEN]; + GCM128_CONTEXT gcm; + + if (nonce_len == 0) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_NONCE_SIZE); + return 0; + } + + if (in_tag_len != ctx->tag_len) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT); + return 0; + } + + const AES_KEY *key = &gcm_ctx->ks.ks; + + OPENSSL_memcpy(&gcm, &gcm_ctx->gcm, sizeof(gcm)); + CRYPTO_gcm128_setiv(&gcm, key, nonce, nonce_len); + + if (!CRYPTO_gcm128_aad(&gcm, ad, ad_len)) { + return 0; + } + + if (gcm_ctx->ctr) { + if (!CRYPTO_gcm128_decrypt_ctr32(&gcm, key, in, out, in_len, + gcm_ctx->ctr)) { + return 0; + } + } else { + if (!CRYPTO_gcm128_decrypt(&gcm, key, in, out, in_len)) { + return 0; + } + } + + CRYPTO_gcm128_tag(&gcm, tag, ctx->tag_len); + if (CRYPTO_memcmp(tag, in_tag, ctx->tag_len) != 0) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT); + return 0; + } + + return 1; +} + +DEFINE_METHOD_FUNCTION(EVP_AEAD, EVP_aead_aes_128_gcm) { + memset(out, 0, sizeof(EVP_AEAD)); + + out->key_len = 16; + out->nonce_len = 12; + out->overhead = EVP_AEAD_AES_GCM_TAG_LEN; + out->max_tag_len = EVP_AEAD_AES_GCM_TAG_LEN; + out->seal_scatter_supports_extra_in = 1; + + out->init = aead_aes_gcm_init; + out->cleanup = aead_aes_gcm_cleanup; + out->seal_scatter = aead_aes_gcm_seal_scatter; + out->open_gather = aead_aes_gcm_open_gather; +} + +DEFINE_METHOD_FUNCTION(EVP_AEAD, EVP_aead_aes_256_gcm) { + memset(out, 0, sizeof(EVP_AEAD)); + + out->key_len = 32; + out->nonce_len = 12; + out->overhead = EVP_AEAD_AES_GCM_TAG_LEN; + out->max_tag_len = EVP_AEAD_AES_GCM_TAG_LEN; + out->seal_scatter_supports_extra_in = 1; + + out->init = aead_aes_gcm_init; + out->cleanup = aead_aes_gcm_cleanup; + out->seal_scatter = aead_aes_gcm_seal_scatter; + out->open_gather = aead_aes_gcm_open_gather; +} + +static int aead_aes_gcm_tls12_init(EVP_AEAD_CTX *ctx, const uint8_t *key, + size_t key_len, size_t requested_tag_len) { + struct aead_aes_gcm_tls12_ctx *gcm_ctx; + gcm_ctx = OPENSSL_malloc(sizeof(struct aead_aes_gcm_tls12_ctx)); + if (gcm_ctx == NULL) { + return 0; + } + + gcm_ctx->min_next_nonce = 0; + + size_t actual_tag_len; + if (!aead_aes_gcm_init_impl(&gcm_ctx->gcm_ctx, &actual_tag_len, key, key_len, + requested_tag_len)) { + OPENSSL_free(gcm_ctx); + return 0; + } + + ctx->aead_state = gcm_ctx; + ctx->tag_len = actual_tag_len; + return 1; +} + +static void aead_aes_gcm_tls12_cleanup(EVP_AEAD_CTX *ctx) { + OPENSSL_free(ctx->aead_state); +} + +static int aead_aes_gcm_tls12_seal_scatter( + const EVP_AEAD_CTX *ctx, uint8_t *out, uint8_t *out_tag, + size_t *out_tag_len, size_t max_out_tag_len, const uint8_t *nonce, + size_t nonce_len, const uint8_t *in, size_t in_len, const uint8_t *extra_in, + size_t extra_in_len, const uint8_t *ad, size_t ad_len) { + struct aead_aes_gcm_tls12_ctx *gcm_ctx = ctx->aead_state; + if (nonce_len != 12) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE); + return 0; + } + + // The given nonces must be strictly monotonically increasing. + uint64_t given_counter; + OPENSSL_memcpy(&given_counter, nonce + nonce_len - sizeof(given_counter), + sizeof(given_counter)); + given_counter = CRYPTO_bswap8(given_counter); + if (given_counter == UINT64_MAX || + given_counter < gcm_ctx->min_next_nonce) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_NONCE); + return 0; + } + + gcm_ctx->min_next_nonce = given_counter + 1; + + return aead_aes_gcm_seal_scatter(ctx, out, out_tag, out_tag_len, + max_out_tag_len, nonce, nonce_len, in, + in_len, extra_in, extra_in_len, ad, ad_len); +} + +DEFINE_METHOD_FUNCTION(EVP_AEAD, EVP_aead_aes_128_gcm_tls12) { + memset(out, 0, sizeof(EVP_AEAD)); + + out->key_len = 16; + out->nonce_len = 12; + out->overhead = EVP_AEAD_AES_GCM_TAG_LEN; + out->max_tag_len = EVP_AEAD_AES_GCM_TAG_LEN; + out->seal_scatter_supports_extra_in = 1; + + out->init = aead_aes_gcm_tls12_init; + out->cleanup = aead_aes_gcm_tls12_cleanup; + out->seal_scatter = aead_aes_gcm_tls12_seal_scatter; + out->open_gather = aead_aes_gcm_open_gather; +} + +DEFINE_METHOD_FUNCTION(EVP_AEAD, EVP_aead_aes_256_gcm_tls12) { + memset(out, 0, sizeof(EVP_AEAD)); + + out->key_len = 32; + out->nonce_len = 12; + out->overhead = EVP_AEAD_AES_GCM_TAG_LEN; + out->max_tag_len = EVP_AEAD_AES_GCM_TAG_LEN; + out->seal_scatter_supports_extra_in = 1; + + out->init = aead_aes_gcm_tls12_init; + out->cleanup = aead_aes_gcm_tls12_cleanup; + out->seal_scatter = aead_aes_gcm_tls12_seal_scatter; + out->open_gather = aead_aes_gcm_open_gather; +} + +int EVP_has_aes_hardware(void) { +#if defined(OPENSSL_X86) || defined(OPENSSL_X86_64) + return aesni_capable() && crypto_gcm_clmul_enabled(); +#elif defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64) + return hwaes_capable() && CRYPTO_is_ARMv8_PMULL_capable(); +#else + return 0; +#endif +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/cipher/e_aes.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/cipher/e_aes.c.grpc_back new file mode 100644 index 0000000..8377f0c --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/cipher/e_aes.c.grpc_back @@ -0,0 +1,1437 @@ +/* ==================================================================== + * Copyright (c) 2001-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 + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "internal.h" +#include "../../internal.h" +#include "../aes/internal.h" +#include "../modes/internal.h" +#include "../delocate.h" + +#if defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64) +#include +#endif + + +OPENSSL_MSVC_PRAGMA(warning(disable: 4702)) // Unreachable code. + +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; + uint8_t *iv; // Temporary IV store + int ivlen; // IV length + int taglen; + int iv_gen; // It is OK to generate IVs + ctr128_f ctr; +} EVP_AES_GCM_CTX; + +#if !defined(OPENSSL_NO_ASM) && \ + (defined(OPENSSL_X86_64) || defined(OPENSSL_X86)) +#define VPAES +static char vpaes_capable(void) { + return (OPENSSL_ia32cap_P[1] & (1 << (41 - 32))) != 0; +} + +#if defined(OPENSSL_X86_64) +#define BSAES +static char bsaes_capable(void) { + return vpaes_capable(); +} +#endif + +#elif !defined(OPENSSL_NO_ASM) && \ + (defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)) + +#if defined(OPENSSL_ARM) && __ARM_MAX_ARCH__ >= 7 +#define BSAES +static char bsaes_capable(void) { + return CRYPTO_is_NEON_capable(); +} +#endif + +#endif + + +#if defined(BSAES) +// On platforms where BSAES gets defined (just above), then these functions are +// provided by asm. +void bsaes_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t length, + const AES_KEY *key, uint8_t ivec[16], int enc); +void bsaes_ctr32_encrypt_blocks(const uint8_t *in, uint8_t *out, size_t len, + const AES_KEY *key, const uint8_t ivec[16]); +#else +static char bsaes_capable(void) { + return 0; +} + +// On other platforms, bsaes_capable() will always return false and so the +// following will never be called. +static void bsaes_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t length, + const AES_KEY *key, uint8_t ivec[16], int enc) { + abort(); +} + +static void bsaes_ctr32_encrypt_blocks(const uint8_t *in, uint8_t *out, + size_t len, const AES_KEY *key, + const uint8_t ivec[16]) { + abort(); +} +#endif + +#if defined(VPAES) +// On platforms where VPAES gets defined (just above), then these functions are +// provided by asm. +int vpaes_set_encrypt_key(const uint8_t *userKey, int bits, AES_KEY *key); +int vpaes_set_decrypt_key(const uint8_t *userKey, int bits, AES_KEY *key); + +void vpaes_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key); +void vpaes_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key); + +void vpaes_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t length, + const AES_KEY *key, uint8_t *ivec, int enc); +#else +static char vpaes_capable(void) { + return 0; +} + +// On other platforms, vpaes_capable() will always return false and so the +// following will never be called. +static int vpaes_set_encrypt_key(const uint8_t *userKey, int bits, + AES_KEY *key) { + abort(); +} +static int vpaes_set_decrypt_key(const uint8_t *userKey, int bits, + AES_KEY *key) { + abort(); +} +static void vpaes_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key) { + abort(); +} +static void vpaes_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key) { + abort(); +} +static void vpaes_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t length, + const AES_KEY *key, uint8_t *ivec, int enc) { + abort(); +} +#endif + +#if !defined(OPENSSL_NO_ASM) && \ + (defined(OPENSSL_X86_64) || defined(OPENSSL_X86)) +int aesni_set_encrypt_key(const uint8_t *userKey, int bits, AES_KEY *key); +int aesni_set_decrypt_key(const uint8_t *userKey, int bits, AES_KEY *key); + +void aesni_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key); +void aesni_decrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key); + +void aesni_ecb_encrypt(const uint8_t *in, uint8_t *out, size_t length, + const AES_KEY *key, int enc); +void aesni_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t length, + const AES_KEY *key, uint8_t *ivec, int enc); + +#else + +// On other platforms, aesni_capable() will always return false and so the +// following will never be called. +static void aesni_encrypt(const uint8_t *in, uint8_t *out, const AES_KEY *key) { + abort(); +} +static int aesni_set_encrypt_key(const uint8_t *userKey, int bits, + AES_KEY *key) { + abort(); +} +static void aesni_ctr32_encrypt_blocks(const uint8_t *in, uint8_t *out, + size_t blocks, const void *key, + const uint8_t *ivec) { + abort(); +} + +#endif + +static int aes_init_key(EVP_CIPHER_CTX *ctx, const uint8_t *key, + const uint8_t *iv, int enc) { + int ret, mode; + EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data; + + mode = ctx->cipher->flags & EVP_CIPH_MODE_MASK; + if ((mode == EVP_CIPH_ECB_MODE || mode == EVP_CIPH_CBC_MODE) && !enc) { + if (hwaes_capable()) { + ret = aes_hw_set_decrypt_key(key, ctx->key_len * 8, &dat->ks.ks); + dat->block = (block128_f)aes_hw_decrypt; + dat->stream.cbc = NULL; + if (mode == EVP_CIPH_CBC_MODE) { + dat->stream.cbc = (cbc128_f)aes_hw_cbc_encrypt; + } + } else 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 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 { + 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 if (hwaes_capable()) { + ret = aes_hw_set_encrypt_key(key, ctx->key_len * 8, &dat->ks.ks); + dat->block = (block128_f)aes_hw_encrypt; + dat->stream.cbc = NULL; + if (mode == EVP_CIPH_CBC_MODE) { + dat->stream.cbc = (cbc128_f)aes_hw_cbc_encrypt; + } else if (mode == EVP_CIPH_CTR_MODE) { + dat->stream.ctr = (ctr128_f)aes_hw_ctr32_encrypt_blocks; + } + } else 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 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 { + 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; + } + + if (ret < 0) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_AES_KEY_SETUP_FAILED); + return 0; + } + + return 1; +} + +static int aes_cbc_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *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, uint8_t *out, const uint8_t *in, + size_t len) { + size_t bl = ctx->cipher->block_size; + EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data; + + if (len < bl) { + return 1; + } + + len -= bl; + for (size_t i = 0; i <= len; i += bl) { + (*dat->block)(in + i, out + i, &dat->ks); + } + + return 1; +} + +static int aes_ctr_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in, + size_t len) { + 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, + &ctx->num, dat->stream.ctr); + } else { + CRYPTO_ctr128_encrypt(in, out, len, &dat->ks, ctx->iv, ctx->buf, &ctx->num, + dat->block); + } + return 1; +} + +static int aes_ofb_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *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 char aesni_capable(void); + +ctr128_f aes_ctr_set_key(AES_KEY *aes_key, GCM128_CONTEXT *gcm_ctx, + block128_f *out_block, const uint8_t *key, + size_t key_bytes) { + if (aesni_capable()) { + aesni_set_encrypt_key(key, key_bytes * 8, aes_key); + if (gcm_ctx != NULL) { + CRYPTO_gcm128_init(gcm_ctx, aes_key, (block128_f)aesni_encrypt, 1); + } + if (out_block) { + *out_block = (block128_f) aesni_encrypt; + } + return (ctr128_f)aesni_ctr32_encrypt_blocks; + } + + if (hwaes_capable()) { + aes_hw_set_encrypt_key(key, key_bytes * 8, aes_key); + if (gcm_ctx != NULL) { + CRYPTO_gcm128_init(gcm_ctx, aes_key, (block128_f)aes_hw_encrypt, 0); + } + if (out_block) { + *out_block = (block128_f) aes_hw_encrypt; + } + return (ctr128_f)aes_hw_ctr32_encrypt_blocks; + } + + if (bsaes_capable()) { + AES_set_encrypt_key(key, key_bytes * 8, aes_key); + if (gcm_ctx != NULL) { + CRYPTO_gcm128_init(gcm_ctx, aes_key, (block128_f)AES_encrypt, 0); + } + if (out_block) { + *out_block = (block128_f) AES_encrypt; + } + return (ctr128_f)bsaes_ctr32_encrypt_blocks; + } + + if (vpaes_capable()) { + vpaes_set_encrypt_key(key, key_bytes * 8, aes_key); + if (out_block) { + *out_block = (block128_f) vpaes_encrypt; + } + if (gcm_ctx != NULL) { + CRYPTO_gcm128_init(gcm_ctx, aes_key, (block128_f)vpaes_encrypt, 0); + } + return NULL; + } + + AES_set_encrypt_key(key, key_bytes * 8, aes_key); + if (gcm_ctx != NULL) { + CRYPTO_gcm128_init(gcm_ctx, aes_key, (block128_f)AES_encrypt, 0); + } + if (out_block) { + *out_block = (block128_f) AES_encrypt; + } + return NULL; +} + +static int aes_gcm_init_key(EVP_CIPHER_CTX *ctx, const uint8_t *key, + const uint8_t *iv, int enc) { + EVP_AES_GCM_CTX *gctx = ctx->cipher_data; + if (!iv && !key) { + return 1; + } + if (key) { + gctx->ctr = + aes_ctr_set_key(&gctx->ks.ks, &gctx->gcm, NULL, key, ctx->key_len); + // 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, &gctx->ks.ks, 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, &gctx->ks.ks, iv, gctx->ivlen); + } else { + OPENSSL_memcpy(gctx->iv, iv, gctx->ivlen); + } + gctx->iv_set = 1; + gctx->iv_gen = 0; + } + return 1; +} + +static void aes_gcm_cleanup(EVP_CIPHER_CTX *c) { + EVP_AES_GCM_CTX *gctx = c->cipher_data; + OPENSSL_cleanse(&gctx->gcm, sizeof(gctx->gcm)); + if (gctx->iv != c->iv) { + OPENSSL_free(gctx->iv); + } +} + +// increment counter (64-bit int) by 1 +static void ctr64_inc(uint8_t *counter) { + int n = 8; + uint8_t 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; + 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; + } + OPENSSL_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; + } + OPENSSL_memcpy(ptr, c->buf, arg); + return 1; + + case EVP_CTRL_GCM_SET_IV_FIXED: + // Special case: -1 length restores whole IV + if (arg == -1) { + OPENSSL_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) { + OPENSSL_memcpy(gctx->iv, ptr, arg); + } + if (c->encrypt && !RAND_bytes(gctx->iv + arg, gctx->ivlen - arg)) { + 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->ks.ks, gctx->iv, gctx->ivlen); + if (arg <= 0 || arg > gctx->ivlen) { + arg = gctx->ivlen; + } + OPENSSL_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; + } + OPENSSL_memcpy(gctx->iv + gctx->ivlen - arg, ptr, arg); + CRYPTO_gcm128_setiv(&gctx->gcm, &gctx->ks.ks, gctx->iv, gctx->ivlen); + gctx->iv_set = 1; + return 1; + + case EVP_CTRL_COPY: { + EVP_CIPHER_CTX *out = ptr; + EVP_AES_GCM_CTX *gctx_out = out->cipher_data; + if (gctx->iv == c->iv) { + gctx_out->iv = out->iv; + } else { + gctx_out->iv = OPENSSL_malloc(gctx->ivlen); + if (!gctx_out->iv) { + return 0; + } + OPENSSL_memcpy(gctx_out->iv, gctx->iv, gctx->ivlen); + } + return 1; + } + + default: + return -1; + } +} + +static int aes_gcm_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *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->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) { + if (!CRYPTO_gcm128_encrypt_ctr32(&gctx->gcm, &gctx->ks.ks, in, out, len, + gctx->ctr)) { + return -1; + } + } else { + if (!CRYPTO_gcm128_encrypt(&gctx->gcm, &gctx->ks.ks, in, out, len)) { + return -1; + } + } + } else { + if (gctx->ctr) { + if (!CRYPTO_gcm128_decrypt_ctr32(&gctx->gcm, &gctx->ks.ks, in, out, len, + gctx->ctr)) { + return -1; + } + } else { + if (!CRYPTO_gcm128_decrypt(&gctx->gcm, &gctx->ks.ks, in, out, len)) { + return -1; + } + } + } + return len; + } else { + if (!ctx->encrypt) { + if (gctx->taglen < 0 || + !CRYPTO_gcm128_finish(&gctx->gcm, ctx->buf, gctx->taglen)) { + 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_LOCAL_DATA(EVP_CIPHER, aes_128_cbc_generic) { + memset(out, 0, sizeof(EVP_CIPHER)); + + out->nid = NID_aes_128_cbc; + out->block_size = 16; + out->key_len = 16; + out->iv_len = 16; + out->ctx_size = sizeof(EVP_AES_KEY); + out->flags = EVP_CIPH_CBC_MODE; + out->init = aes_init_key; + out->cipher = aes_cbc_cipher; +} + +DEFINE_LOCAL_DATA(EVP_CIPHER, aes_128_ctr_generic) { + memset(out, 0, sizeof(EVP_CIPHER)); + + out->nid = NID_aes_128_ctr; + out->block_size = 1; + out->key_len = 16; + out->iv_len = 16; + out->ctx_size = sizeof(EVP_AES_KEY); + out->flags = EVP_CIPH_CTR_MODE; + out->init = aes_init_key; + out->cipher = aes_ctr_cipher; +} + +DEFINE_LOCAL_DATA(EVP_CIPHER, aes_128_ecb_generic) { + memset(out, 0, sizeof(EVP_CIPHER)); + + out->nid = NID_aes_128_ecb; + out->block_size = 16; + out->key_len = 16; + out->ctx_size = sizeof(EVP_AES_KEY); + out->flags = EVP_CIPH_ECB_MODE; + out->init = aes_init_key; + out->cipher = aes_ecb_cipher; +} + +DEFINE_LOCAL_DATA(EVP_CIPHER, aes_128_ofb_generic) { + memset(out, 0, sizeof(EVP_CIPHER)); + + out->nid = NID_aes_128_ofb128; + out->block_size = 1; + out->key_len = 16; + out->iv_len = 16; + out->ctx_size = sizeof(EVP_AES_KEY); + out->flags = EVP_CIPH_OFB_MODE; + out->init = aes_init_key; + out->cipher = aes_ofb_cipher; +} + +DEFINE_LOCAL_DATA(EVP_CIPHER, aes_128_gcm_generic) { + memset(out, 0, sizeof(EVP_CIPHER)); + + out->nid = NID_aes_128_gcm; + out->block_size = 1; + out->key_len = 16; + out->iv_len = 12; + out->ctx_size = sizeof(EVP_AES_GCM_CTX); + out->flags = EVP_CIPH_GCM_MODE | EVP_CIPH_CUSTOM_IV | + EVP_CIPH_FLAG_CUSTOM_CIPHER | EVP_CIPH_ALWAYS_CALL_INIT | + EVP_CIPH_CTRL_INIT | EVP_CIPH_FLAG_AEAD_CIPHER; + out->init = aes_gcm_init_key; + out->cipher = aes_gcm_cipher; + out->cleanup = aes_gcm_cleanup; + out->ctrl = aes_gcm_ctrl; +} + +DEFINE_LOCAL_DATA(EVP_CIPHER, aes_192_cbc_generic) { + memset(out, 0, sizeof(EVP_CIPHER)); + + out->nid = NID_aes_192_cbc; + out->block_size = 16; + out->key_len = 24; + out->iv_len = 16; + out->ctx_size = sizeof(EVP_AES_KEY); + out->flags = EVP_CIPH_CBC_MODE; + out->init = aes_init_key; + out->cipher = aes_cbc_cipher; +} + +DEFINE_LOCAL_DATA(EVP_CIPHER, aes_192_ctr_generic) { + memset(out, 0, sizeof(EVP_CIPHER)); + + out->nid = NID_aes_192_ctr; + out->block_size = 1; + out->key_len = 24; + out->iv_len = 16; + out->ctx_size = sizeof(EVP_AES_KEY); + out->flags = EVP_CIPH_CTR_MODE; + out->init = aes_init_key; + out->cipher = aes_ctr_cipher; +} + +DEFINE_LOCAL_DATA(EVP_CIPHER, aes_192_ecb_generic) { + memset(out, 0, sizeof(EVP_CIPHER)); + + out->nid = NID_aes_192_ecb; + out->block_size = 16; + out->key_len = 24; + out->ctx_size = sizeof(EVP_AES_KEY); + out->flags = EVP_CIPH_ECB_MODE; + out->init = aes_init_key; + out->cipher = aes_ecb_cipher; +} + +DEFINE_LOCAL_DATA(EVP_CIPHER, aes_192_gcm_generic) { + memset(out, 0, sizeof(EVP_CIPHER)); + + out->nid = NID_aes_192_gcm; + out->block_size = 1; + out->key_len = 24; + out->iv_len = 12; + out->ctx_size = sizeof(EVP_AES_GCM_CTX); + out->flags = EVP_CIPH_GCM_MODE | EVP_CIPH_CUSTOM_IV | + EVP_CIPH_FLAG_CUSTOM_CIPHER | EVP_CIPH_ALWAYS_CALL_INIT | + EVP_CIPH_CTRL_INIT | EVP_CIPH_FLAG_AEAD_CIPHER; + out->init = aes_gcm_init_key; + out->cipher = aes_gcm_cipher; + out->cleanup = aes_gcm_cleanup; + out->ctrl = aes_gcm_ctrl; +} + +DEFINE_LOCAL_DATA(EVP_CIPHER, aes_256_cbc_generic) { + memset(out, 0, sizeof(EVP_CIPHER)); + + out->nid = NID_aes_256_cbc; + out->block_size = 16; + out->key_len = 32; + out->iv_len = 16; + out->ctx_size = sizeof(EVP_AES_KEY); + out->flags = EVP_CIPH_CBC_MODE; + out->init = aes_init_key; + out->cipher = aes_cbc_cipher; +} + +DEFINE_LOCAL_DATA(EVP_CIPHER, aes_256_ctr_generic) { + memset(out, 0, sizeof(EVP_CIPHER)); + + out->nid = NID_aes_256_ctr; + out->block_size = 1; + out->key_len = 32; + out->iv_len = 16; + out->ctx_size = sizeof(EVP_AES_KEY); + out->flags = EVP_CIPH_CTR_MODE; + out->init = aes_init_key; + out->cipher = aes_ctr_cipher; +} + +DEFINE_LOCAL_DATA(EVP_CIPHER, aes_256_ecb_generic) { + memset(out, 0, sizeof(EVP_CIPHER)); + + out->nid = NID_aes_256_ecb; + out->block_size = 16; + out->key_len = 32; + out->ctx_size = sizeof(EVP_AES_KEY); + out->flags = EVP_CIPH_ECB_MODE; + out->init = aes_init_key; + out->cipher = aes_ecb_cipher; +} + +DEFINE_LOCAL_DATA(EVP_CIPHER, aes_256_ofb_generic) { + memset(out, 0, sizeof(EVP_CIPHER)); + + out->nid = NID_aes_256_ofb128; + out->block_size = 1; + out->key_len = 32; + out->iv_len = 16; + out->ctx_size = sizeof(EVP_AES_KEY); + out->flags = EVP_CIPH_OFB_MODE; + out->init = aes_init_key; + out->cipher = aes_ofb_cipher; +} + +DEFINE_LOCAL_DATA(EVP_CIPHER, aes_256_gcm_generic) { + memset(out, 0, sizeof(EVP_CIPHER)); + + out->nid = NID_aes_256_gcm; + out->block_size = 1; + out->key_len = 32; + out->iv_len = 12; + out->ctx_size = sizeof(EVP_AES_GCM_CTX); + out->flags = EVP_CIPH_GCM_MODE | EVP_CIPH_CUSTOM_IV | + EVP_CIPH_FLAG_CUSTOM_CIPHER | EVP_CIPH_ALWAYS_CALL_INIT | + EVP_CIPH_CTRL_INIT | EVP_CIPH_FLAG_AEAD_CIPHER; + out->init = aes_gcm_init_key; + out->cipher = aes_gcm_cipher; + out->cleanup = aes_gcm_cleanup; + out->ctrl = aes_gcm_ctrl; +} + +#if !defined(OPENSSL_NO_ASM) && \ + (defined(OPENSSL_X86_64) || defined(OPENSSL_X86)) + +// AES-NI section. + +static char aesni_capable(void) { + return (OPENSSL_ia32cap_P[1] & (1 << (57 - 32))) != 0; +} + +static int aesni_init_key(EVP_CIPHER_CTX *ctx, const uint8_t *key, + const uint8_t *iv, int enc) { + int ret, mode; + EVP_AES_KEY *dat = (EVP_AES_KEY *)ctx->cipher_data; + + mode = ctx->cipher->flags & EVP_CIPH_MODE_MASK; + 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) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_AES_KEY_SETUP_FAILED); + return 0; + } + + return 1; +} + +static int aesni_cbc_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, + const uint8_t *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, uint8_t *out, + const uint8_t *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; +} + +static int aesni_gcm_init_key(EVP_CIPHER_CTX *ctx, const uint8_t *key, + const uint8_t *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, 1); + 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, &gctx->ks.ks, 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, &gctx->ks.ks, iv, gctx->ivlen); + } else { + OPENSSL_memcpy(gctx->iv, iv, gctx->ivlen); + } + gctx->iv_set = 1; + gctx->iv_gen = 0; + } + return 1; +} + +DEFINE_LOCAL_DATA(EVP_CIPHER, aesni_128_cbc) { + memset(out, 0, sizeof(EVP_CIPHER)); + + out->nid = NID_aes_128_cbc; + out->block_size = 16; + out->key_len = 16; + out->iv_len = 16; + out->ctx_size = sizeof(EVP_AES_KEY); + out->flags = EVP_CIPH_CBC_MODE; + out->init = aesni_init_key; + out->cipher = aesni_cbc_cipher; +} + +DEFINE_LOCAL_DATA(EVP_CIPHER, aesni_128_ctr) { + memset(out, 0, sizeof(EVP_CIPHER)); + + out->nid = NID_aes_128_ctr; + out->block_size = 1; + out->key_len = 16; + out->iv_len = 16; + out->ctx_size = sizeof(EVP_AES_KEY); + out->flags = EVP_CIPH_CTR_MODE; + out->init = aesni_init_key; + out->cipher = aes_ctr_cipher; +} + +DEFINE_LOCAL_DATA(EVP_CIPHER, aesni_128_ecb) { + memset(out, 0, sizeof(EVP_CIPHER)); + + out->nid = NID_aes_128_ecb; + out->block_size = 16; + out->key_len = 16; + out->ctx_size = sizeof(EVP_AES_KEY); + out->flags = EVP_CIPH_ECB_MODE; + out->init = aesni_init_key; + out->cipher = aesni_ecb_cipher; +} + +DEFINE_LOCAL_DATA(EVP_CIPHER, aesni_128_ofb) { + memset(out, 0, sizeof(EVP_CIPHER)); + + out->nid = NID_aes_128_ofb128; + out->block_size = 1; + out->key_len = 16; + out->iv_len = 16; + out->ctx_size = sizeof(EVP_AES_KEY); + out->flags = EVP_CIPH_OFB_MODE; + out->init = aesni_init_key; + out->cipher = aes_ofb_cipher; +} + +DEFINE_LOCAL_DATA(EVP_CIPHER, aesni_128_gcm) { + memset(out, 0, sizeof(EVP_CIPHER)); + + out->nid = NID_aes_128_gcm; + out->block_size = 1; + out->key_len = 16; + out->iv_len = 12; + out->ctx_size = sizeof(EVP_AES_GCM_CTX); + out->flags = EVP_CIPH_GCM_MODE | EVP_CIPH_CUSTOM_IV | + EVP_CIPH_FLAG_CUSTOM_CIPHER | EVP_CIPH_ALWAYS_CALL_INIT | + EVP_CIPH_CTRL_INIT | EVP_CIPH_FLAG_AEAD_CIPHER; + out->init = aesni_gcm_init_key; + out->cipher = aes_gcm_cipher; + out->cleanup = aes_gcm_cleanup; + out->ctrl = aes_gcm_ctrl; +} + +DEFINE_LOCAL_DATA(EVP_CIPHER, aesni_192_cbc) { + memset(out, 0, sizeof(EVP_CIPHER)); + + out->nid = NID_aes_192_cbc; + out->block_size = 16; + out->key_len = 24; + out->iv_len = 16; + out->ctx_size = sizeof(EVP_AES_KEY); + out->flags = EVP_CIPH_CBC_MODE; + out->init = aesni_init_key; + out->cipher = aesni_cbc_cipher; +} + +DEFINE_LOCAL_DATA(EVP_CIPHER, aesni_192_ctr) { + memset(out, 0, sizeof(EVP_CIPHER)); + + out->nid = NID_aes_192_ctr; + out->block_size = 1; + out->key_len = 24; + out->iv_len = 16; + out->ctx_size = sizeof(EVP_AES_KEY); + out->flags = EVP_CIPH_CTR_MODE; + out->init = aesni_init_key; + out->cipher = aes_ctr_cipher; +} + +DEFINE_LOCAL_DATA(EVP_CIPHER, aesni_192_ecb) { + memset(out, 0, sizeof(EVP_CIPHER)); + + out->nid = NID_aes_192_ecb; + out->block_size = 16; + out->key_len = 24; + out->ctx_size = sizeof(EVP_AES_KEY); + out->flags = EVP_CIPH_ECB_MODE; + out->init = aesni_init_key; + out->cipher = aesni_ecb_cipher; +} + +DEFINE_LOCAL_DATA(EVP_CIPHER, aesni_192_gcm) { + memset(out, 0, sizeof(EVP_CIPHER)); + + out->nid = NID_aes_192_gcm; + out->block_size = 1; + out->key_len = 24; + out->iv_len = 12; + out->ctx_size = sizeof(EVP_AES_GCM_CTX); + out->flags = EVP_CIPH_GCM_MODE | EVP_CIPH_CUSTOM_IV | + EVP_CIPH_FLAG_CUSTOM_CIPHER | EVP_CIPH_ALWAYS_CALL_INIT | + EVP_CIPH_CTRL_INIT | EVP_CIPH_FLAG_AEAD_CIPHER; + out->init = aesni_gcm_init_key; + out->cipher = aes_gcm_cipher; + out->cleanup = aes_gcm_cleanup; + out->ctrl = aes_gcm_ctrl; +} + +DEFINE_LOCAL_DATA(EVP_CIPHER, aesni_256_cbc) { + memset(out, 0, sizeof(EVP_CIPHER)); + + out->nid = NID_aes_256_cbc; + out->block_size = 16; + out->key_len = 32; + out->iv_len = 16; + out->ctx_size = sizeof(EVP_AES_KEY); + out->flags = EVP_CIPH_CBC_MODE; + out->init = aesni_init_key; + out->cipher = aesni_cbc_cipher; +} + +DEFINE_LOCAL_DATA(EVP_CIPHER, aesni_256_ctr) { + memset(out, 0, sizeof(EVP_CIPHER)); + + out->nid = NID_aes_256_ctr; + out->block_size = 1; + out->key_len = 32; + out->iv_len = 16; + out->ctx_size = sizeof(EVP_AES_KEY); + out->flags = EVP_CIPH_CTR_MODE; + out->init = aesni_init_key; + out->cipher = aes_ctr_cipher; +} + +DEFINE_LOCAL_DATA(EVP_CIPHER, aesni_256_ecb) { + memset(out, 0, sizeof(EVP_CIPHER)); + + out->nid = NID_aes_256_ecb; + out->block_size = 16; + out->key_len = 32; + out->ctx_size = sizeof(EVP_AES_KEY); + out->flags = EVP_CIPH_ECB_MODE; + out->init = aesni_init_key; + out->cipher = aesni_ecb_cipher; +} + +DEFINE_LOCAL_DATA(EVP_CIPHER, aesni_256_ofb) { + memset(out, 0, sizeof(EVP_CIPHER)); + + out->nid = NID_aes_256_ofb128; + out->block_size = 1; + out->key_len = 32; + out->iv_len = 16; + out->ctx_size = sizeof(EVP_AES_KEY); + out->flags = EVP_CIPH_OFB_MODE; + out->init = aesni_init_key; + out->cipher = aes_ofb_cipher; +} + +DEFINE_LOCAL_DATA(EVP_CIPHER, aesni_256_gcm) { + memset(out, 0, sizeof(EVP_CIPHER)); + + out->nid = NID_aes_256_gcm; + out->block_size = 1; + out->key_len = 32; + out->iv_len = 12; + out->ctx_size = sizeof(EVP_AES_GCM_CTX); + out->flags = EVP_CIPH_GCM_MODE | EVP_CIPH_CUSTOM_IV | + EVP_CIPH_FLAG_CUSTOM_CIPHER | EVP_CIPH_ALWAYS_CALL_INIT | + EVP_CIPH_CTRL_INIT | EVP_CIPH_CUSTOM_COPY | + EVP_CIPH_FLAG_AEAD_CIPHER; + out->init = aesni_gcm_init_key; + out->cipher = aes_gcm_cipher; + out->cleanup = aes_gcm_cleanup; + out->ctrl = aes_gcm_ctrl; +} + +#define EVP_CIPHER_FUNCTION(keybits, mode) \ + const EVP_CIPHER *EVP_aes_##keybits##_##mode(void) { \ + if (aesni_capable()) { \ + return aesni_##keybits##_##mode(); \ + } else { \ + return aes_##keybits##_##mode##_generic(); \ + } \ + } + +#else // ^^^ OPENSSL_X86_64 || OPENSSL_X86 + +static char aesni_capable(void) { + return 0; +} + +#define EVP_CIPHER_FUNCTION(keybits, mode) \ + const EVP_CIPHER *EVP_aes_##keybits##_##mode(void) { \ + return aes_##keybits##_##mode##_generic(); \ + } + +#endif + +EVP_CIPHER_FUNCTION(128, cbc) +EVP_CIPHER_FUNCTION(128, ctr) +EVP_CIPHER_FUNCTION(128, ecb) +EVP_CIPHER_FUNCTION(128, ofb) +EVP_CIPHER_FUNCTION(128, gcm) + +EVP_CIPHER_FUNCTION(192, cbc) +EVP_CIPHER_FUNCTION(192, ctr) +EVP_CIPHER_FUNCTION(192, ecb) +EVP_CIPHER_FUNCTION(192, gcm) + +EVP_CIPHER_FUNCTION(256, cbc) +EVP_CIPHER_FUNCTION(256, ctr) +EVP_CIPHER_FUNCTION(256, ecb) +EVP_CIPHER_FUNCTION(256, ofb) +EVP_CIPHER_FUNCTION(256, gcm) + + +#define EVP_AEAD_AES_GCM_TAG_LEN 16 + +struct aead_aes_gcm_ctx { + union { + double align; + AES_KEY ks; + } ks; + GCM128_CONTEXT gcm; + ctr128_f ctr; +}; + +struct aead_aes_gcm_tls12_ctx { + struct aead_aes_gcm_ctx gcm_ctx; + uint64_t min_next_nonce; +}; + +static int aead_aes_gcm_init_impl(struct aead_aes_gcm_ctx *gcm_ctx, + size_t *out_tag_len, const uint8_t *key, + size_t key_len, size_t tag_len) { + const size_t key_bits = key_len * 8; + + if (key_bits != 128 && key_bits != 256) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_KEY_LENGTH); + return 0; // EVP_AEAD_CTX_init should catch this. + } + + if (tag_len == EVP_AEAD_DEFAULT_TAG_LENGTH) { + tag_len = EVP_AEAD_AES_GCM_TAG_LEN; + } + + if (tag_len > EVP_AEAD_AES_GCM_TAG_LEN) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TAG_TOO_LARGE); + return 0; + } + + gcm_ctx->ctr = + aes_ctr_set_key(&gcm_ctx->ks.ks, &gcm_ctx->gcm, NULL, key, key_len); + *out_tag_len = tag_len; + return 1; +} + +static int aead_aes_gcm_init(EVP_AEAD_CTX *ctx, const uint8_t *key, + size_t key_len, size_t requested_tag_len) { + struct aead_aes_gcm_ctx *gcm_ctx; + gcm_ctx = OPENSSL_malloc(sizeof(struct aead_aes_gcm_ctx)); + if (gcm_ctx == NULL) { + return 0; + } + + size_t actual_tag_len; + if (!aead_aes_gcm_init_impl(gcm_ctx, &actual_tag_len, key, key_len, + requested_tag_len)) { + OPENSSL_free(gcm_ctx); + return 0; + } + + ctx->aead_state = gcm_ctx; + ctx->tag_len = actual_tag_len; + return 1; +} + +static void aead_aes_gcm_cleanup(EVP_AEAD_CTX *ctx) { + OPENSSL_free(ctx->aead_state); +} + +static int aead_aes_gcm_seal_scatter(const EVP_AEAD_CTX *ctx, uint8_t *out, + uint8_t *out_tag, size_t *out_tag_len, + size_t max_out_tag_len, + const uint8_t *nonce, size_t nonce_len, + const uint8_t *in, size_t in_len, + const uint8_t *extra_in, + size_t extra_in_len, + const uint8_t *ad, size_t ad_len) { + const struct aead_aes_gcm_ctx *gcm_ctx = ctx->aead_state; + GCM128_CONTEXT gcm; + + if (extra_in_len + ctx->tag_len < ctx->tag_len) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_TOO_LARGE); + return 0; + } + if (max_out_tag_len < extra_in_len + ctx->tag_len) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BUFFER_TOO_SMALL); + return 0; + } + if (nonce_len == 0) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_NONCE_SIZE); + return 0; + } + + const AES_KEY *key = &gcm_ctx->ks.ks; + + OPENSSL_memcpy(&gcm, &gcm_ctx->gcm, sizeof(gcm)); + CRYPTO_gcm128_setiv(&gcm, key, nonce, nonce_len); + + if (ad_len > 0 && !CRYPTO_gcm128_aad(&gcm, ad, ad_len)) { + return 0; + } + + if (gcm_ctx->ctr) { + if (!CRYPTO_gcm128_encrypt_ctr32(&gcm, key, in, out, in_len, + gcm_ctx->ctr)) { + return 0; + } + } else { + if (!CRYPTO_gcm128_encrypt(&gcm, key, in, out, in_len)) { + return 0; + } + } + + if (extra_in_len) { + if (gcm_ctx->ctr) { + if (!CRYPTO_gcm128_encrypt_ctr32(&gcm, key, extra_in, out_tag, + extra_in_len, gcm_ctx->ctr)) { + return 0; + } + } else { + if (!CRYPTO_gcm128_encrypt(&gcm, key, extra_in, out_tag, extra_in_len)) { + return 0; + } + } + } + + CRYPTO_gcm128_tag(&gcm, out_tag + extra_in_len, ctx->tag_len); + *out_tag_len = ctx->tag_len + extra_in_len; + + return 1; +} + +static int aead_aes_gcm_open_gather(const EVP_AEAD_CTX *ctx, uint8_t *out, + const uint8_t *nonce, size_t nonce_len, + const uint8_t *in, size_t in_len, + const uint8_t *in_tag, size_t in_tag_len, + const uint8_t *ad, size_t ad_len) { + const struct aead_aes_gcm_ctx *gcm_ctx = ctx->aead_state; + uint8_t tag[EVP_AEAD_AES_GCM_TAG_LEN]; + GCM128_CONTEXT gcm; + + if (nonce_len == 0) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_NONCE_SIZE); + return 0; + } + + if (in_tag_len != ctx->tag_len) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT); + return 0; + } + + const AES_KEY *key = &gcm_ctx->ks.ks; + + OPENSSL_memcpy(&gcm, &gcm_ctx->gcm, sizeof(gcm)); + CRYPTO_gcm128_setiv(&gcm, key, nonce, nonce_len); + + if (!CRYPTO_gcm128_aad(&gcm, ad, ad_len)) { + return 0; + } + + if (gcm_ctx->ctr) { + if (!CRYPTO_gcm128_decrypt_ctr32(&gcm, key, in, out, in_len, + gcm_ctx->ctr)) { + return 0; + } + } else { + if (!CRYPTO_gcm128_decrypt(&gcm, key, in, out, in_len)) { + return 0; + } + } + + CRYPTO_gcm128_tag(&gcm, tag, ctx->tag_len); + if (CRYPTO_memcmp(tag, in_tag, ctx->tag_len) != 0) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_BAD_DECRYPT); + return 0; + } + + return 1; +} + +DEFINE_METHOD_FUNCTION(EVP_AEAD, EVP_aead_aes_128_gcm) { + memset(out, 0, sizeof(EVP_AEAD)); + + out->key_len = 16; + out->nonce_len = 12; + out->overhead = EVP_AEAD_AES_GCM_TAG_LEN; + out->max_tag_len = EVP_AEAD_AES_GCM_TAG_LEN; + out->seal_scatter_supports_extra_in = 1; + + out->init = aead_aes_gcm_init; + out->cleanup = aead_aes_gcm_cleanup; + out->seal_scatter = aead_aes_gcm_seal_scatter; + out->open_gather = aead_aes_gcm_open_gather; +} + +DEFINE_METHOD_FUNCTION(EVP_AEAD, EVP_aead_aes_256_gcm) { + memset(out, 0, sizeof(EVP_AEAD)); + + out->key_len = 32; + out->nonce_len = 12; + out->overhead = EVP_AEAD_AES_GCM_TAG_LEN; + out->max_tag_len = EVP_AEAD_AES_GCM_TAG_LEN; + out->seal_scatter_supports_extra_in = 1; + + out->init = aead_aes_gcm_init; + out->cleanup = aead_aes_gcm_cleanup; + out->seal_scatter = aead_aes_gcm_seal_scatter; + out->open_gather = aead_aes_gcm_open_gather; +} + +static int aead_aes_gcm_tls12_init(EVP_AEAD_CTX *ctx, const uint8_t *key, + size_t key_len, size_t requested_tag_len) { + struct aead_aes_gcm_tls12_ctx *gcm_ctx; + gcm_ctx = OPENSSL_malloc(sizeof(struct aead_aes_gcm_tls12_ctx)); + if (gcm_ctx == NULL) { + return 0; + } + + gcm_ctx->min_next_nonce = 0; + + size_t actual_tag_len; + if (!aead_aes_gcm_init_impl(&gcm_ctx->gcm_ctx, &actual_tag_len, key, key_len, + requested_tag_len)) { + OPENSSL_free(gcm_ctx); + return 0; + } + + ctx->aead_state = gcm_ctx; + ctx->tag_len = actual_tag_len; + return 1; +} + +static void aead_aes_gcm_tls12_cleanup(EVP_AEAD_CTX *ctx) { + OPENSSL_free(ctx->aead_state); +} + +static int aead_aes_gcm_tls12_seal_scatter( + const EVP_AEAD_CTX *ctx, uint8_t *out, uint8_t *out_tag, + size_t *out_tag_len, size_t max_out_tag_len, const uint8_t *nonce, + size_t nonce_len, const uint8_t *in, size_t in_len, const uint8_t *extra_in, + size_t extra_in_len, const uint8_t *ad, size_t ad_len) { + struct aead_aes_gcm_tls12_ctx *gcm_ctx = ctx->aead_state; + if (nonce_len != 12) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_UNSUPPORTED_NONCE_SIZE); + return 0; + } + + // The given nonces must be strictly monotonically increasing. + uint64_t given_counter; + OPENSSL_memcpy(&given_counter, nonce + nonce_len - sizeof(given_counter), + sizeof(given_counter)); + given_counter = CRYPTO_bswap8(given_counter); + if (given_counter == UINT64_MAX || + given_counter < gcm_ctx->min_next_nonce) { + OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_NONCE); + return 0; + } + + gcm_ctx->min_next_nonce = given_counter + 1; + + return aead_aes_gcm_seal_scatter(ctx, out, out_tag, out_tag_len, + max_out_tag_len, nonce, nonce_len, in, + in_len, extra_in, extra_in_len, ad, ad_len); +} + +DEFINE_METHOD_FUNCTION(EVP_AEAD, EVP_aead_aes_128_gcm_tls12) { + memset(out, 0, sizeof(EVP_AEAD)); + + out->key_len = 16; + out->nonce_len = 12; + out->overhead = EVP_AEAD_AES_GCM_TAG_LEN; + out->max_tag_len = EVP_AEAD_AES_GCM_TAG_LEN; + out->seal_scatter_supports_extra_in = 1; + + out->init = aead_aes_gcm_tls12_init; + out->cleanup = aead_aes_gcm_tls12_cleanup; + out->seal_scatter = aead_aes_gcm_tls12_seal_scatter; + out->open_gather = aead_aes_gcm_open_gather; +} + +DEFINE_METHOD_FUNCTION(EVP_AEAD, EVP_aead_aes_256_gcm_tls12) { + memset(out, 0, sizeof(EVP_AEAD)); + + out->key_len = 32; + out->nonce_len = 12; + out->overhead = EVP_AEAD_AES_GCM_TAG_LEN; + out->max_tag_len = EVP_AEAD_AES_GCM_TAG_LEN; + out->seal_scatter_supports_extra_in = 1; + + out->init = aead_aes_gcm_tls12_init; + out->cleanup = aead_aes_gcm_tls12_cleanup; + out->seal_scatter = aead_aes_gcm_tls12_seal_scatter; + out->open_gather = aead_aes_gcm_open_gather; +} + +int EVP_has_aes_hardware(void) { +#if defined(OPENSSL_X86) || defined(OPENSSL_X86_64) + return aesni_capable() && crypto_gcm_clmul_enabled(); +#elif defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64) + return hwaes_capable() && CRYPTO_is_ARMv8_PMULL_capable(); +#else + return 0; +#endif +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/cipher/e_des.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/cipher/e_des.c new file mode 100644 index 0000000..0ccdb50 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/cipher/e_des.c @@ -0,0 +1,233 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 "internal.h" +#include "../delocate.h" + + +typedef struct { + union { + double align; + DES_key_schedule ks; + } ks; +} EVP_DES_KEY; + +static int des_init_key(EVP_CIPHER_CTX *ctx, const uint8_t *key, + const uint8_t *iv, int enc) { + DES_cblock *deskey = (DES_cblock *)key; + EVP_DES_KEY *dat = (EVP_DES_KEY *)ctx->cipher_data; + + DES_set_key(deskey, &dat->ks.ks); + return 1; +} + +static int des_cbc_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in, + size_t in_len) { + EVP_DES_KEY *dat = (EVP_DES_KEY *)ctx->cipher_data; + + DES_ncbc_encrypt(in, out, in_len, &dat->ks.ks, (DES_cblock *)ctx->iv, + ctx->encrypt); + + return 1; +} + +DEFINE_METHOD_FUNCTION(EVP_CIPHER, EVP_des_cbc) { + memset(out, 0, sizeof(EVP_CIPHER)); + out->nid = NID_des_cbc; + out->block_size = 8; + out->key_len = 8; + out->iv_len = 8; + out->ctx_size = sizeof(EVP_DES_KEY); + out->flags = EVP_CIPH_CBC_MODE; + out->init = des_init_key; + out->cipher = des_cbc_cipher; +} + +static int des_ecb_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in, + size_t in_len) { + if (in_len < ctx->cipher->block_size) { + return 1; + } + in_len -= ctx->cipher->block_size; + + EVP_DES_KEY *dat = (EVP_DES_KEY *) ctx->cipher_data; + for (size_t i = 0; i <= in_len; i += ctx->cipher->block_size) { + DES_ecb_encrypt((DES_cblock *) (in + i), (DES_cblock *) (out + i), + &dat->ks.ks, ctx->encrypt); + } + return 1; +} + +DEFINE_METHOD_FUNCTION(EVP_CIPHER, EVP_des_ecb) { + memset(out, 0, sizeof(EVP_CIPHER)); + out->nid = NID_des_ecb; + out->block_size = 8; + out->key_len = 8; + out->iv_len = 0; + out->ctx_size = sizeof(EVP_DES_KEY); + out->flags = EVP_CIPH_ECB_MODE; + out->init = des_init_key; + out->cipher = des_ecb_cipher; +} + +typedef struct { + union { + double align; + DES_key_schedule ks[3]; + } ks; +} DES_EDE_KEY; + +static int des_ede3_init_key(EVP_CIPHER_CTX *ctx, const uint8_t *key, + const uint8_t *iv, int enc) { + DES_cblock *deskey = (DES_cblock *)key; + DES_EDE_KEY *dat = (DES_EDE_KEY*) ctx->cipher_data; + + DES_set_key(&deskey[0], &dat->ks.ks[0]); + DES_set_key(&deskey[1], &dat->ks.ks[1]); + DES_set_key(&deskey[2], &dat->ks.ks[2]); + + return 1; +} + +static int des_ede3_cbc_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, + const uint8_t *in, size_t in_len) { + DES_EDE_KEY *dat = (DES_EDE_KEY*) ctx->cipher_data; + + DES_ede3_cbc_encrypt(in, out, in_len, &dat->ks.ks[0], &dat->ks.ks[1], + &dat->ks.ks[2], (DES_cblock *)ctx->iv, ctx->encrypt); + + return 1; +} + +DEFINE_METHOD_FUNCTION(EVP_CIPHER, EVP_des_ede3_cbc) { + memset(out, 0, sizeof(EVP_CIPHER)); + out->nid = NID_des_ede3_cbc; + out->block_size = 8; + out->key_len = 24; + out->iv_len = 8; + out->ctx_size = sizeof(DES_EDE_KEY); + out->flags = EVP_CIPH_CBC_MODE; + out->init = des_ede3_init_key; + out->cipher = des_ede3_cbc_cipher; +} + +static int des_ede_init_key(EVP_CIPHER_CTX *ctx, const uint8_t *key, + const uint8_t *iv, int enc) { + DES_cblock *deskey = (DES_cblock *) key; + DES_EDE_KEY *dat = (DES_EDE_KEY *) ctx->cipher_data; + + DES_set_key(&deskey[0], &dat->ks.ks[0]); + DES_set_key(&deskey[1], &dat->ks.ks[1]); + DES_set_key(&deskey[0], &dat->ks.ks[2]); + + return 1; +} + +DEFINE_METHOD_FUNCTION(EVP_CIPHER, EVP_des_ede_cbc) { + memset(out, 0, sizeof(EVP_CIPHER)); + out->nid = NID_des_ede_cbc; + out->block_size = 8; + out->key_len = 16; + out->iv_len = 8; + out->ctx_size = sizeof(DES_EDE_KEY); + out->flags = EVP_CIPH_CBC_MODE; + out->init = des_ede_init_key; + out->cipher = des_ede3_cbc_cipher; +} + +static int des_ede_ecb_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, + const uint8_t *in, size_t in_len) { + if (in_len < ctx->cipher->block_size) { + return 1; + } + in_len -= ctx->cipher->block_size; + + DES_EDE_KEY *dat = (DES_EDE_KEY *) ctx->cipher_data; + for (size_t i = 0; i <= in_len; i += ctx->cipher->block_size) { + DES_ecb3_encrypt((DES_cblock *) (in + i), (DES_cblock *) (out + i), + &dat->ks.ks[0], &dat->ks.ks[1], &dat->ks.ks[2], + ctx->encrypt); + } + return 1; +} + +DEFINE_METHOD_FUNCTION(EVP_CIPHER, EVP_des_ede) { + memset(out, 0, sizeof(EVP_CIPHER)); + out->nid = NID_des_ede_ecb; + out->block_size = 8; + out->key_len = 16; + out->iv_len = 0; + out->ctx_size = sizeof(DES_EDE_KEY); + out->flags = EVP_CIPH_ECB_MODE; + out->init = des_ede_init_key; + out->cipher = des_ede_ecb_cipher; +} + +DEFINE_METHOD_FUNCTION(EVP_CIPHER, EVP_des_ede3) { + memset(out, 0, sizeof(EVP_CIPHER)); + out->nid = NID_des_ede3_ecb; + out->block_size = 8; + out->key_len = 24; + out->iv_len = 0; + out->ctx_size = sizeof(DES_EDE_KEY); + out->flags = EVP_CIPH_ECB_MODE; + out->init = des_ede3_init_key; + out->cipher = des_ede_ecb_cipher; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/cipher/e_des.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/cipher/e_des.c.grpc_back new file mode 100644 index 0000000..eaba6d7 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/cipher/e_des.c.grpc_back @@ -0,0 +1,233 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 "internal.h" +#include "../delocate.h" + + +typedef struct { + union { + double align; + DES_key_schedule ks; + } ks; +} EVP_DES_KEY; + +static int des_init_key(EVP_CIPHER_CTX *ctx, const uint8_t *key, + const uint8_t *iv, int enc) { + DES_cblock *deskey = (DES_cblock *)key; + EVP_DES_KEY *dat = (EVP_DES_KEY *)ctx->cipher_data; + + DES_set_key(deskey, &dat->ks.ks); + return 1; +} + +static int des_cbc_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in, + size_t in_len) { + EVP_DES_KEY *dat = (EVP_DES_KEY *)ctx->cipher_data; + + DES_ncbc_encrypt(in, out, in_len, &dat->ks.ks, (DES_cblock *)ctx->iv, + ctx->encrypt); + + return 1; +} + +DEFINE_METHOD_FUNCTION(EVP_CIPHER, EVP_des_cbc) { + memset(out, 0, sizeof(EVP_CIPHER)); + out->nid = NID_des_cbc; + out->block_size = 8; + out->key_len = 8; + out->iv_len = 8; + out->ctx_size = sizeof(EVP_DES_KEY); + out->flags = EVP_CIPH_CBC_MODE; + out->init = des_init_key; + out->cipher = des_cbc_cipher; +} + +static int des_ecb_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in, + size_t in_len) { + if (in_len < ctx->cipher->block_size) { + return 1; + } + in_len -= ctx->cipher->block_size; + + EVP_DES_KEY *dat = (EVP_DES_KEY *) ctx->cipher_data; + for (size_t i = 0; i <= in_len; i += ctx->cipher->block_size) { + DES_ecb_encrypt((DES_cblock *) (in + i), (DES_cblock *) (out + i), + &dat->ks.ks, ctx->encrypt); + } + return 1; +} + +DEFINE_METHOD_FUNCTION(EVP_CIPHER, EVP_des_ecb) { + memset(out, 0, sizeof(EVP_CIPHER)); + out->nid = NID_des_ecb; + out->block_size = 8; + out->key_len = 8; + out->iv_len = 0; + out->ctx_size = sizeof(EVP_DES_KEY); + out->flags = EVP_CIPH_ECB_MODE; + out->init = des_init_key; + out->cipher = des_ecb_cipher; +} + +typedef struct { + union { + double align; + DES_key_schedule ks[3]; + } ks; +} DES_EDE_KEY; + +static int des_ede3_init_key(EVP_CIPHER_CTX *ctx, const uint8_t *key, + const uint8_t *iv, int enc) { + DES_cblock *deskey = (DES_cblock *)key; + DES_EDE_KEY *dat = (DES_EDE_KEY*) ctx->cipher_data; + + DES_set_key(&deskey[0], &dat->ks.ks[0]); + DES_set_key(&deskey[1], &dat->ks.ks[1]); + DES_set_key(&deskey[2], &dat->ks.ks[2]); + + return 1; +} + +static int des_ede3_cbc_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, + const uint8_t *in, size_t in_len) { + DES_EDE_KEY *dat = (DES_EDE_KEY*) ctx->cipher_data; + + DES_ede3_cbc_encrypt(in, out, in_len, &dat->ks.ks[0], &dat->ks.ks[1], + &dat->ks.ks[2], (DES_cblock *)ctx->iv, ctx->encrypt); + + return 1; +} + +DEFINE_METHOD_FUNCTION(EVP_CIPHER, EVP_des_ede3_cbc) { + memset(out, 0, sizeof(EVP_CIPHER)); + out->nid = NID_des_ede3_cbc; + out->block_size = 8; + out->key_len = 24; + out->iv_len = 8; + out->ctx_size = sizeof(DES_EDE_KEY); + out->flags = EVP_CIPH_CBC_MODE; + out->init = des_ede3_init_key; + out->cipher = des_ede3_cbc_cipher; +} + +static int des_ede_init_key(EVP_CIPHER_CTX *ctx, const uint8_t *key, + const uint8_t *iv, int enc) { + DES_cblock *deskey = (DES_cblock *) key; + DES_EDE_KEY *dat = (DES_EDE_KEY *) ctx->cipher_data; + + DES_set_key(&deskey[0], &dat->ks.ks[0]); + DES_set_key(&deskey[1], &dat->ks.ks[1]); + DES_set_key(&deskey[0], &dat->ks.ks[2]); + + return 1; +} + +DEFINE_METHOD_FUNCTION(EVP_CIPHER, EVP_des_ede_cbc) { + memset(out, 0, sizeof(EVP_CIPHER)); + out->nid = NID_des_ede_cbc; + out->block_size = 8; + out->key_len = 16; + out->iv_len = 8; + out->ctx_size = sizeof(DES_EDE_KEY); + out->flags = EVP_CIPH_CBC_MODE; + out->init = des_ede_init_key; + out->cipher = des_ede3_cbc_cipher; +} + +static int des_ede_ecb_cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, + const uint8_t *in, size_t in_len) { + if (in_len < ctx->cipher->block_size) { + return 1; + } + in_len -= ctx->cipher->block_size; + + DES_EDE_KEY *dat = (DES_EDE_KEY *) ctx->cipher_data; + for (size_t i = 0; i <= in_len; i += ctx->cipher->block_size) { + DES_ecb3_encrypt((DES_cblock *) (in + i), (DES_cblock *) (out + i), + &dat->ks.ks[0], &dat->ks.ks[1], &dat->ks.ks[2], + ctx->encrypt); + } + return 1; +} + +DEFINE_METHOD_FUNCTION(EVP_CIPHER, EVP_des_ede) { + memset(out, 0, sizeof(EVP_CIPHER)); + out->nid = NID_des_ede_ecb; + out->block_size = 8; + out->key_len = 16; + out->iv_len = 0; + out->ctx_size = sizeof(DES_EDE_KEY); + out->flags = EVP_CIPH_ECB_MODE; + out->init = des_ede_init_key; + out->cipher = des_ede_ecb_cipher; +} + +DEFINE_METHOD_FUNCTION(EVP_CIPHER, EVP_des_ede3) { + memset(out, 0, sizeof(EVP_CIPHER)); + out->nid = NID_des_ede3_ecb; + out->block_size = 8; + out->key_len = 24; + out->iv_len = 0; + out->ctx_size = sizeof(DES_EDE_KEY); + out->flags = EVP_CIPH_ECB_MODE; + out->init = des_ede3_init_key; + out->cipher = des_ede_ecb_cipher; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/cipher/internal.h b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/cipher/internal.h new file mode 100644 index 0000000..806f5b5 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/cipher/internal.h @@ -0,0 +1,129 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 OPENSSL_HEADER_CIPHER_INTERNAL_H +#define OPENSSL_HEADER_CIPHER_INTERNAL_H + +#include + +#include +#include + +#include "../../internal.h" +#include "../modes/internal.h" + +#if defined(__cplusplus) +extern "C" { +#endif + + +// EVP_CIPH_MODE_MASK contains the bits of |flags| that represent the mode. +#define EVP_CIPH_MODE_MASK 0x3f + +// EVP_AEAD represents a specific AEAD algorithm. +struct evp_aead_st { + uint8_t key_len; + uint8_t nonce_len; + uint8_t overhead; + uint8_t max_tag_len; + int seal_scatter_supports_extra_in; + + // init initialises an |EVP_AEAD_CTX|. If this call returns zero then + // |cleanup| will not be called for that context. + int (*init)(EVP_AEAD_CTX *, const uint8_t *key, size_t key_len, + size_t tag_len); + int (*init_with_direction)(EVP_AEAD_CTX *, const uint8_t *key, size_t key_len, + size_t tag_len, enum evp_aead_direction_t dir); + void (*cleanup)(EVP_AEAD_CTX *); + + int (*open)(const EVP_AEAD_CTX *ctx, uint8_t *out, size_t *out_len, + size_t max_out_len, const uint8_t *nonce, size_t nonce_len, + const uint8_t *in, size_t in_len, const uint8_t *ad, + size_t ad_len); + + int (*seal_scatter)(const EVP_AEAD_CTX *ctx, uint8_t *out, uint8_t *out_tag, + size_t *out_tag_len, size_t max_out_tag_len, + const uint8_t *nonce, size_t nonce_len, const uint8_t *in, + size_t in_len, const uint8_t *extra_in, + size_t extra_in_len, const uint8_t *ad, size_t ad_len); + + int (*open_gather)(const EVP_AEAD_CTX *ctx, uint8_t *out, + const uint8_t *nonce, size_t nonce_len, const uint8_t *in, + size_t in_len, const uint8_t *in_tag, size_t in_tag_len, + const uint8_t *ad, size_t ad_len); + + int (*get_iv)(const EVP_AEAD_CTX *ctx, const uint8_t **out_iv, + size_t *out_len); + + size_t (*tag_len)(const EVP_AEAD_CTX *ctx, size_t in_Len, + size_t extra_in_len); +}; + +// aes_ctr_set_key initialises |*aes_key| using |key_bytes| bytes from |key|, +// where |key_bytes| must either be 16, 24 or 32. If not NULL, |*out_block| is +// set to a function that encrypts single blocks. If not NULL, |*gcm_ctx| is +// initialised to do GHASH with the given key. It returns a function for +// optimised CTR-mode, or NULL if CTR-mode should be built using +// |*out_block|. +ctr128_f aes_ctr_set_key(AES_KEY *aes_key, GCM128_CONTEXT *gcm_ctx, + block128_f *out_block, const uint8_t *key, + size_t key_bytes); + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_CIPHER_INTERNAL_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/cipher/internal.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/cipher/internal.h.grpc_back new file mode 100644 index 0000000..7b5f23f --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/cipher/internal.h.grpc_back @@ -0,0 +1,129 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 OPENSSL_HEADER_CIPHER_INTERNAL_H +#define OPENSSL_HEADER_CIPHER_INTERNAL_H + +#include + +#include +#include + +#include "../../internal.h" +#include "../modes/internal.h" + +#if defined(__cplusplus) +extern "C" { +#endif + + +// EVP_CIPH_MODE_MASK contains the bits of |flags| that represent the mode. +#define EVP_CIPH_MODE_MASK 0x3f + +// EVP_AEAD represents a specific AEAD algorithm. +struct evp_aead_st { + uint8_t key_len; + uint8_t nonce_len; + uint8_t overhead; + uint8_t max_tag_len; + int seal_scatter_supports_extra_in; + + // init initialises an |EVP_AEAD_CTX|. If this call returns zero then + // |cleanup| will not be called for that context. + int (*init)(EVP_AEAD_CTX *, const uint8_t *key, size_t key_len, + size_t tag_len); + int (*init_with_direction)(EVP_AEAD_CTX *, const uint8_t *key, size_t key_len, + size_t tag_len, enum evp_aead_direction_t dir); + void (*cleanup)(EVP_AEAD_CTX *); + + int (*open)(const EVP_AEAD_CTX *ctx, uint8_t *out, size_t *out_len, + size_t max_out_len, const uint8_t *nonce, size_t nonce_len, + const uint8_t *in, size_t in_len, const uint8_t *ad, + size_t ad_len); + + int (*seal_scatter)(const EVP_AEAD_CTX *ctx, uint8_t *out, uint8_t *out_tag, + size_t *out_tag_len, size_t max_out_tag_len, + const uint8_t *nonce, size_t nonce_len, const uint8_t *in, + size_t in_len, const uint8_t *extra_in, + size_t extra_in_len, const uint8_t *ad, size_t ad_len); + + int (*open_gather)(const EVP_AEAD_CTX *ctx, uint8_t *out, + const uint8_t *nonce, size_t nonce_len, const uint8_t *in, + size_t in_len, const uint8_t *in_tag, size_t in_tag_len, + const uint8_t *ad, size_t ad_len); + + int (*get_iv)(const EVP_AEAD_CTX *ctx, const uint8_t **out_iv, + size_t *out_len); + + size_t (*tag_len)(const EVP_AEAD_CTX *ctx, size_t in_Len, + size_t extra_in_len); +}; + +// aes_ctr_set_key initialises |*aes_key| using |key_bytes| bytes from |key|, +// where |key_bytes| must either be 16, 24 or 32. If not NULL, |*out_block| is +// set to a function that encrypts single blocks. If not NULL, |*gcm_ctx| is +// initialised to do GHASH with the given key. It returns a function for +// optimised CTR-mode, or NULL if CTR-mode should be built using +// |*out_block|. +ctr128_f aes_ctr_set_key(AES_KEY *aes_key, GCM128_CONTEXT *gcm_ctx, + block128_f *out_block, const uint8_t *key, + size_t key_bytes); + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_CIPHER_INTERNAL_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/delocate.h b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/delocate.h new file mode 100644 index 0000000..66f9527 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/delocate.h @@ -0,0 +1,88 @@ +/* Copyright (c) 2017, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_FIPSMODULE_DELOCATE_H +#define OPENSSL_HEADER_FIPSMODULE_DELOCATE_H + +#include + +#include "../internal.h" + + +#if defined(BORINGSSL_FIPS) && !defined(OPENSSL_ASAN) && !defined(OPENSSL_MSAN) +#define DEFINE_BSS_GET(type, name) \ + static type name __attribute__((used)); \ + type *name##_bss_get(void); +// For FIPS builds we require that CRYPTO_ONCE_INIT be zero. +#define DEFINE_STATIC_ONCE(name) DEFINE_BSS_GET(CRYPTO_once_t, name) +// For FIPS builds we require that CRYPTO_STATIC_MUTEX_INIT be zero. +#define DEFINE_STATIC_MUTEX(name) \ + DEFINE_BSS_GET(struct CRYPTO_STATIC_MUTEX, name) +// For FIPS builds we require that CRYPTO_EX_DATA_CLASS_INIT be zero. +#define DEFINE_STATIC_EX_DATA_CLASS(name) \ + DEFINE_BSS_GET(CRYPTO_EX_DATA_CLASS, name) +#else +#define DEFINE_BSS_GET(type, name) \ + static type name; \ + static type *name##_bss_get(void) { return &name; } +#define DEFINE_STATIC_ONCE(name) \ + static CRYPTO_once_t name = CRYPTO_ONCE_INIT; \ + static CRYPTO_once_t *name##_bss_get(void) { return &name; } +#define DEFINE_STATIC_MUTEX(name) \ + static struct CRYPTO_STATIC_MUTEX name = CRYPTO_STATIC_MUTEX_INIT; \ + static struct CRYPTO_STATIC_MUTEX *name##_bss_get(void) { return &name; } +#define DEFINE_STATIC_EX_DATA_CLASS(name) \ + static CRYPTO_EX_DATA_CLASS name = CRYPTO_EX_DATA_CLASS_INIT; \ + static CRYPTO_EX_DATA_CLASS *name##_bss_get(void) { return &name; } +#endif + +#define DEFINE_DATA(type, name, accessor_decorations) \ + DEFINE_BSS_GET(type, name##_storage) \ + DEFINE_STATIC_ONCE(name##_once) \ + static void name##_do_init(type *out); \ + static void name##_init(void) { name##_do_init(name##_storage_bss_get()); } \ + accessor_decorations type *name(void) { \ + CRYPTO_once(name##_once_bss_get(), name##_init); \ + /* See http://c-faq.com/ansi/constmismatch.html for why the following \ + * cast is needed. */ \ + return (const type *)name##_storage_bss_get(); \ + } \ + static void name##_do_init(type *out) + +// DEFINE_METHOD_FUNCTION defines a function named |name| which returns a +// method table of type const |type|*. In FIPS mode, to avoid rel.ro data, it +// is split into a CRYPTO_once_t-guarded initializer in the module and +// unhashed, non-module accessor functions to space reserved in the BSS. The +// method table is initialized by a caller-supplied function which takes a +// parameter named |out| of type |type|*. The caller should follow the macro +// invocation with the body of this function: +// +// DEFINE_METHOD_FUNCTION(EVP_MD, EVP_md4) { +// out->type = NID_md4; +// out->md_size = MD4_DIGEST_LENGTH; +// out->flags = 0; +// out->init = md4_init; +// out->update = md4_update; +// out->final = md4_final; +// out->block_size = 64; +// out->ctx_size = sizeof(MD4_CTX); +// } +// +// This mechanism does not use a static initializer because their execution +// order is undefined. See FIPS.md for more details. +#define DEFINE_METHOD_FUNCTION(type, name) DEFINE_DATA(type, name, const) + +#define DEFINE_LOCAL_DATA(type, name) DEFINE_DATA(type, name, static const) + +#endif // OPENSSL_HEADER_FIPSMODULE_DELOCATE_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/delocate.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/delocate.h.grpc_back new file mode 100644 index 0000000..065a21c --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/delocate.h.grpc_back @@ -0,0 +1,88 @@ +/* Copyright (c) 2017, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_FIPSMODULE_DELOCATE_H +#define OPENSSL_HEADER_FIPSMODULE_DELOCATE_H + +#include + +#include "../internal.h" + + +#if defined(BORINGSSL_FIPS) && !defined(OPENSSL_ASAN) && !defined(OPENSSL_MSAN) +#define DEFINE_BSS_GET(type, name) \ + static type name __attribute__((used)); \ + type *name##_bss_get(void); +// For FIPS builds we require that CRYPTO_ONCE_INIT be zero. +#define DEFINE_STATIC_ONCE(name) DEFINE_BSS_GET(CRYPTO_once_t, name) +// For FIPS builds we require that CRYPTO_STATIC_MUTEX_INIT be zero. +#define DEFINE_STATIC_MUTEX(name) \ + DEFINE_BSS_GET(struct CRYPTO_STATIC_MUTEX, name) +// For FIPS builds we require that CRYPTO_EX_DATA_CLASS_INIT be zero. +#define DEFINE_STATIC_EX_DATA_CLASS(name) \ + DEFINE_BSS_GET(CRYPTO_EX_DATA_CLASS, name) +#else +#define DEFINE_BSS_GET(type, name) \ + static type name; \ + static type *name##_bss_get(void) { return &name; } +#define DEFINE_STATIC_ONCE(name) \ + static CRYPTO_once_t name = CRYPTO_ONCE_INIT; \ + static CRYPTO_once_t *name##_bss_get(void) { return &name; } +#define DEFINE_STATIC_MUTEX(name) \ + static struct CRYPTO_STATIC_MUTEX name = CRYPTO_STATIC_MUTEX_INIT; \ + static struct CRYPTO_STATIC_MUTEX *name##_bss_get(void) { return &name; } +#define DEFINE_STATIC_EX_DATA_CLASS(name) \ + static CRYPTO_EX_DATA_CLASS name = CRYPTO_EX_DATA_CLASS_INIT; \ + static CRYPTO_EX_DATA_CLASS *name##_bss_get(void) { return &name; } +#endif + +#define DEFINE_DATA(type, name, accessor_decorations) \ + DEFINE_BSS_GET(type, name##_storage) \ + DEFINE_STATIC_ONCE(name##_once) \ + static void name##_do_init(type *out); \ + static void name##_init(void) { name##_do_init(name##_storage_bss_get()); } \ + accessor_decorations type *name(void) { \ + CRYPTO_once(name##_once_bss_get(), name##_init); \ + /* See http://c-faq.com/ansi/constmismatch.html for why the following \ + * cast is needed. */ \ + return (const type *)name##_storage_bss_get(); \ + } \ + static void name##_do_init(type *out) + +// DEFINE_METHOD_FUNCTION defines a function named |name| which returns a +// method table of type const |type|*. In FIPS mode, to avoid rel.ro data, it +// is split into a CRYPTO_once_t-guarded initializer in the module and +// unhashed, non-module accessor functions to space reserved in the BSS. The +// method table is initialized by a caller-supplied function which takes a +// parameter named |out| of type |type|*. The caller should follow the macro +// invocation with the body of this function: +// +// DEFINE_METHOD_FUNCTION(EVP_MD, EVP_md4) { +// out->type = NID_md4; +// out->md_size = MD4_DIGEST_LENGTH; +// out->flags = 0; +// out->init = md4_init; +// out->update = md4_update; +// out->final = md4_final; +// out->block_size = 64; +// out->ctx_size = sizeof(MD4_CTX); +// } +// +// This mechanism does not use a static initializer because their execution +// order is undefined. See FIPS.md for more details. +#define DEFINE_METHOD_FUNCTION(type, name) DEFINE_DATA(type, name, const) + +#define DEFINE_LOCAL_DATA(type, name) DEFINE_DATA(type, name, static const) + +#endif // OPENSSL_HEADER_FIPSMODULE_DELOCATE_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/des/des.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/des/des.c new file mode 100644 index 0000000..359fcf0 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/des/des.c @@ -0,0 +1,785 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 "internal.h" + + +static const uint32_t 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, }}; + +static const uint32_t 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, }}; + +#define HPERM_OP(a, t, n, m) \ + ((t) = ((((a) << (16 - (n))) ^ (a)) & (m)), \ + (a) = (a) ^ (t) ^ ((t) >> (16 - (n)))) + +void DES_set_key(const DES_cblock *key, DES_key_schedule *schedule) { + static const int shifts2[16] = {0, 0, 1, 1, 1, 1, 1, 1, + 0, 1, 1, 1, 1, 1, 1, 0}; + uint32_t c, d, t, s, t2; + const uint8_t *in; + int i; + + in = key->bytes; + + 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; + schedule->subkeys[i][0] = ROTATE(t2, 30) & 0xffffffffL; + + t2 = ((s >> 16L) | (t & 0xffff0000L)); + schedule->subkeys[i][1] = ROTATE(t2, 26) & 0xffffffffL; + } +} + +static const uint8_t kOddParity[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 i; + + for (i = 0; i < DES_KEY_SZ; i++) { + key->bytes[i] = kOddParity[key->bytes[i]]; + } +} + +static void DES_encrypt1(uint32_t *data, const DES_key_schedule *ks, int enc) { + uint32_t l, r, t, u; + + 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; + + // I don't know if it is worth the effort of loop unrolling the + // inner loop + if (enc) { + D_ENCRYPT(ks, l, r, 0); + D_ENCRYPT(ks, r, l, 1); + D_ENCRYPT(ks, l, r, 2); + D_ENCRYPT(ks, r, l, 3); + D_ENCRYPT(ks, l, r, 4); + D_ENCRYPT(ks, r, l, 5); + D_ENCRYPT(ks, l, r, 6); + D_ENCRYPT(ks, r, l, 7); + D_ENCRYPT(ks, l, r, 8); + D_ENCRYPT(ks, r, l, 9); + D_ENCRYPT(ks, l, r, 10); + D_ENCRYPT(ks, r, l, 11); + D_ENCRYPT(ks, l, r, 12); + D_ENCRYPT(ks, r, l, 13); + D_ENCRYPT(ks, l, r, 14); + D_ENCRYPT(ks, r, l, 15); + } else { + D_ENCRYPT(ks, l, r, 15); + D_ENCRYPT(ks, r, l, 14); + D_ENCRYPT(ks, l, r, 13); + D_ENCRYPT(ks, r, l, 12); + D_ENCRYPT(ks, l, r, 11); + D_ENCRYPT(ks, r, l, 10); + D_ENCRYPT(ks, l, r, 9); + D_ENCRYPT(ks, r, l, 8); + D_ENCRYPT(ks, l, r, 7); + D_ENCRYPT(ks, r, l, 6); + D_ENCRYPT(ks, l, r, 5); + D_ENCRYPT(ks, r, l, 4); + D_ENCRYPT(ks, l, r, 3); + D_ENCRYPT(ks, r, l, 2); + D_ENCRYPT(ks, l, r, 1); + D_ENCRYPT(ks, r, l, 0); + } + + // 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; +} + +static void DES_encrypt2(uint32_t *data, const DES_key_schedule *ks, int enc) { + uint32_t l, r, t, u; + + 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; + + // I don't know if it is worth the effort of loop unrolling the + // inner loop + if (enc) { + D_ENCRYPT(ks, l, r, 0); + D_ENCRYPT(ks, r, l, 1); + D_ENCRYPT(ks, l, r, 2); + D_ENCRYPT(ks, r, l, 3); + D_ENCRYPT(ks, l, r, 4); + D_ENCRYPT(ks, r, l, 5); + D_ENCRYPT(ks, l, r, 6); + D_ENCRYPT(ks, r, l, 7); + D_ENCRYPT(ks, l, r, 8); + D_ENCRYPT(ks, r, l, 9); + D_ENCRYPT(ks, l, r, 10); + D_ENCRYPT(ks, r, l, 11); + D_ENCRYPT(ks, l, r, 12); + D_ENCRYPT(ks, r, l, 13); + D_ENCRYPT(ks, l, r, 14); + D_ENCRYPT(ks, r, l, 15); + } else { + D_ENCRYPT(ks, l, r, 15); + D_ENCRYPT(ks, r, l, 14); + D_ENCRYPT(ks, l, r, 13); + D_ENCRYPT(ks, r, l, 12); + D_ENCRYPT(ks, l, r, 11); + D_ENCRYPT(ks, r, l, 10); + D_ENCRYPT(ks, l, r, 9); + D_ENCRYPT(ks, r, l, 8); + D_ENCRYPT(ks, l, r, 7); + D_ENCRYPT(ks, r, l, 6); + D_ENCRYPT(ks, l, r, 5); + D_ENCRYPT(ks, r, l, 4); + D_ENCRYPT(ks, l, r, 3); + D_ENCRYPT(ks, r, l, 2); + D_ENCRYPT(ks, l, r, 1); + D_ENCRYPT(ks, r, l, 0); + } + // rotate and clear the top bits on machines with 8byte longs + data[0] = ROTATE(l, 3) & 0xffffffffL; + data[1] = ROTATE(r, 3) & 0xffffffffL; +} + +void DES_encrypt3(uint32_t *data, const DES_key_schedule *ks1, + const DES_key_schedule *ks2, const DES_key_schedule *ks3) { + uint32_t l, r; + + l = data[0]; + r = data[1]; + IP(l, r); + data[0] = l; + data[1] = r; + DES_encrypt2((uint32_t *)data, ks1, DES_ENCRYPT); + DES_encrypt2((uint32_t *)data, ks2, DES_DECRYPT); + DES_encrypt2((uint32_t *)data, ks3, DES_ENCRYPT); + l = data[0]; + r = data[1]; + FP(r, l); + data[0] = l; + data[1] = r; +} + +void DES_decrypt3(uint32_t *data, const DES_key_schedule *ks1, + const DES_key_schedule *ks2, const DES_key_schedule *ks3) { + uint32_t l, r; + + l = data[0]; + r = data[1]; + IP(l, r); + data[0] = l; + data[1] = r; + DES_encrypt2((uint32_t *)data, ks3, DES_DECRYPT); + DES_encrypt2((uint32_t *)data, ks2, DES_ENCRYPT); + DES_encrypt2((uint32_t *)data, ks1, DES_DECRYPT); + l = data[0]; + r = data[1]; + FP(r, l); + data[0] = l; + data[1] = r; +} + +void DES_ecb_encrypt(const DES_cblock *in_block, DES_cblock *out_block, + const DES_key_schedule *schedule, int is_encrypt) { + uint32_t l; + uint32_t ll[2]; + const uint8_t *in = in_block->bytes; + uint8_t *out = out_block->bytes; + + c2l(in, l); + ll[0] = l; + c2l(in, l); + ll[1] = l; + DES_encrypt1(ll, schedule, is_encrypt); + l = ll[0]; + l2c(l, out); + l = ll[1]; + l2c(l, out); + ll[0] = ll[1] = 0; +} + +void DES_ncbc_encrypt(const uint8_t *in, uint8_t *out, size_t len, + const DES_key_schedule *schedule, DES_cblock *ivec, + int enc) { + uint32_t tin0, tin1; + uint32_t tout0, tout1, xor0, xor1; + uint32_t tin[2]; + unsigned char *iv; + + iv = ivec->bytes; + + if (enc) { + c2l(iv, tout0); + c2l(iv, tout1); + for (; len >= 8; len -= 8) { + c2l(in, tin0); + c2l(in, tin1); + tin0 ^= tout0; + tin[0] = tin0; + tin1 ^= tout1; + tin[1] = tin1; + DES_encrypt1((uint32_t *)tin, schedule, DES_ENCRYPT); + tout0 = tin[0]; + l2c(tout0, out); + tout1 = tin[1]; + l2c(tout1, out); + } + if (len != 0) { + c2ln(in, tin0, tin1, len); + tin0 ^= tout0; + tin[0] = tin0; + tin1 ^= tout1; + tin[1] = tin1; + DES_encrypt1((uint32_t *)tin, schedule, DES_ENCRYPT); + tout0 = tin[0]; + l2c(tout0, out); + tout1 = tin[1]; + l2c(tout1, out); + } + iv = ivec->bytes; + l2c(tout0, iv); + l2c(tout1, iv); + } else { + c2l(iv, xor0); + c2l(iv, xor1); + for (; len >= 8; len -= 8) { + c2l(in, tin0); + tin[0] = tin0; + c2l(in, tin1); + tin[1] = tin1; + DES_encrypt1((uint32_t *)tin, schedule, DES_DECRYPT); + tout0 = tin[0] ^ xor0; + tout1 = tin[1] ^ xor1; + l2c(tout0, out); + l2c(tout1, out); + xor0 = tin0; + xor1 = tin1; + } + if (len != 0) { + c2l(in, tin0); + tin[0] = tin0; + c2l(in, tin1); + tin[1] = tin1; + DES_encrypt1((uint32_t *)tin, schedule, DES_DECRYPT); + tout0 = tin[0] ^ xor0; + tout1 = tin[1] ^ xor1; + l2cn(tout0, tout1, out, len); + xor0 = tin0; + xor1 = tin1; + } + iv = ivec->bytes; + l2c(xor0, iv); + l2c(xor1, iv); + } + tin[0] = tin[1] = 0; +} + +void DES_ecb3_encrypt(const DES_cblock *input, DES_cblock *output, + const DES_key_schedule *ks1, const DES_key_schedule *ks2, + const DES_key_schedule *ks3, int enc) { + uint32_t l0, l1; + uint32_t ll[2]; + const uint8_t *in = input->bytes; + uint8_t *out = output->bytes; + + 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); +} + +void DES_ede3_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t len, + const DES_key_schedule *ks1, + const DES_key_schedule *ks2, + const DES_key_schedule *ks3, DES_cblock *ivec, + int enc) { + uint32_t tin0, tin1; + uint32_t tout0, tout1, xor0, xor1; + uint32_t tin[2]; + uint8_t *iv; + + iv = ivec->bytes; + + if (enc) { + c2l(iv, tout0); + c2l(iv, tout1); + for (; len >= 8; len -= 8) { + c2l(in, tin0); + c2l(in, tin1); + tin0 ^= tout0; + tin1 ^= tout1; + + tin[0] = tin0; + tin[1] = tin1; + DES_encrypt3((uint32_t *)tin, ks1, ks2, ks3); + tout0 = tin[0]; + tout1 = tin[1]; + + l2c(tout0, out); + l2c(tout1, out); + } + if (len != 0) { + c2ln(in, tin0, tin1, len); + tin0 ^= tout0; + tin1 ^= tout1; + + tin[0] = tin0; + tin[1] = tin1; + DES_encrypt3((uint32_t *)tin, ks1, ks2, ks3); + tout0 = tin[0]; + tout1 = tin[1]; + + l2c(tout0, out); + l2c(tout1, out); + } + iv = ivec->bytes; + l2c(tout0, iv); + l2c(tout1, iv); + } else { + uint32_t t0, t1; + + c2l(iv, xor0); + c2l(iv, xor1); + for (; len >= 8; len -= 8) { + c2l(in, tin0); + c2l(in, tin1); + + t0 = tin0; + t1 = tin1; + + tin[0] = tin0; + tin[1] = tin1; + DES_decrypt3((uint32_t *)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 (len != 0) { + c2l(in, tin0); + c2l(in, tin1); + + t0 = tin0; + t1 = tin1; + + tin[0] = tin0; + tin[1] = tin1; + DES_decrypt3((uint32_t *)tin, ks1, ks2, ks3); + tout0 = tin[0]; + tout1 = tin[1]; + + tout0 ^= xor0; + tout1 ^= xor1; + l2cn(tout0, tout1, out, len); + xor0 = t0; + xor1 = t1; + } + + iv = ivec->bytes; + l2c(xor0, iv); + l2c(xor1, iv); + } + + tin[0] = tin[1] = 0; +} + +void DES_ede2_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t len, + const DES_key_schedule *ks1, + const DES_key_schedule *ks2, + DES_cblock *ivec, + int enc) { + DES_ede3_cbc_encrypt(in, out, len, ks1, ks2, ks1, ivec, enc); +} + + +// Deprecated functions. + +void DES_set_key_unchecked(const DES_cblock *key, DES_key_schedule *schedule) { + DES_set_key(key, schedule); +} + +#undef HPERM_OP +#undef c2l +#undef l2c +#undef c2ln +#undef l2cn +#undef PERM_OP +#undef IP +#undef FP +#undef LOAD_DATA +#undef D_ENCRYPT +#undef ITERATIONS +#undef HALF_ITERATIONS +#undef ROTATE diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/des/des.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/des/des.c.grpc_back new file mode 100644 index 0000000..2b0fdcd --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/des/des.c.grpc_back @@ -0,0 +1,785 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 "internal.h" + + +static const uint32_t 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, }}; + +static const uint32_t 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, }}; + +#define HPERM_OP(a, t, n, m) \ + ((t) = ((((a) << (16 - (n))) ^ (a)) & (m)), \ + (a) = (a) ^ (t) ^ ((t) >> (16 - (n)))) + +void DES_set_key(const DES_cblock *key, DES_key_schedule *schedule) { + static const int shifts2[16] = {0, 0, 1, 1, 1, 1, 1, 1, + 0, 1, 1, 1, 1, 1, 1, 0}; + uint32_t c, d, t, s, t2; + const uint8_t *in; + int i; + + in = key->bytes; + + 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; + schedule->subkeys[i][0] = ROTATE(t2, 30) & 0xffffffffL; + + t2 = ((s >> 16L) | (t & 0xffff0000L)); + schedule->subkeys[i][1] = ROTATE(t2, 26) & 0xffffffffL; + } +} + +static const uint8_t kOddParity[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 i; + + for (i = 0; i < DES_KEY_SZ; i++) { + key->bytes[i] = kOddParity[key->bytes[i]]; + } +} + +static void DES_encrypt1(uint32_t *data, const DES_key_schedule *ks, int enc) { + uint32_t l, r, t, u; + + 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; + + // I don't know if it is worth the effort of loop unrolling the + // inner loop + if (enc) { + D_ENCRYPT(ks, l, r, 0); + D_ENCRYPT(ks, r, l, 1); + D_ENCRYPT(ks, l, r, 2); + D_ENCRYPT(ks, r, l, 3); + D_ENCRYPT(ks, l, r, 4); + D_ENCRYPT(ks, r, l, 5); + D_ENCRYPT(ks, l, r, 6); + D_ENCRYPT(ks, r, l, 7); + D_ENCRYPT(ks, l, r, 8); + D_ENCRYPT(ks, r, l, 9); + D_ENCRYPT(ks, l, r, 10); + D_ENCRYPT(ks, r, l, 11); + D_ENCRYPT(ks, l, r, 12); + D_ENCRYPT(ks, r, l, 13); + D_ENCRYPT(ks, l, r, 14); + D_ENCRYPT(ks, r, l, 15); + } else { + D_ENCRYPT(ks, l, r, 15); + D_ENCRYPT(ks, r, l, 14); + D_ENCRYPT(ks, l, r, 13); + D_ENCRYPT(ks, r, l, 12); + D_ENCRYPT(ks, l, r, 11); + D_ENCRYPT(ks, r, l, 10); + D_ENCRYPT(ks, l, r, 9); + D_ENCRYPT(ks, r, l, 8); + D_ENCRYPT(ks, l, r, 7); + D_ENCRYPT(ks, r, l, 6); + D_ENCRYPT(ks, l, r, 5); + D_ENCRYPT(ks, r, l, 4); + D_ENCRYPT(ks, l, r, 3); + D_ENCRYPT(ks, r, l, 2); + D_ENCRYPT(ks, l, r, 1); + D_ENCRYPT(ks, r, l, 0); + } + + // 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; +} + +static void DES_encrypt2(uint32_t *data, const DES_key_schedule *ks, int enc) { + uint32_t l, r, t, u; + + 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; + + // I don't know if it is worth the effort of loop unrolling the + // inner loop + if (enc) { + D_ENCRYPT(ks, l, r, 0); + D_ENCRYPT(ks, r, l, 1); + D_ENCRYPT(ks, l, r, 2); + D_ENCRYPT(ks, r, l, 3); + D_ENCRYPT(ks, l, r, 4); + D_ENCRYPT(ks, r, l, 5); + D_ENCRYPT(ks, l, r, 6); + D_ENCRYPT(ks, r, l, 7); + D_ENCRYPT(ks, l, r, 8); + D_ENCRYPT(ks, r, l, 9); + D_ENCRYPT(ks, l, r, 10); + D_ENCRYPT(ks, r, l, 11); + D_ENCRYPT(ks, l, r, 12); + D_ENCRYPT(ks, r, l, 13); + D_ENCRYPT(ks, l, r, 14); + D_ENCRYPT(ks, r, l, 15); + } else { + D_ENCRYPT(ks, l, r, 15); + D_ENCRYPT(ks, r, l, 14); + D_ENCRYPT(ks, l, r, 13); + D_ENCRYPT(ks, r, l, 12); + D_ENCRYPT(ks, l, r, 11); + D_ENCRYPT(ks, r, l, 10); + D_ENCRYPT(ks, l, r, 9); + D_ENCRYPT(ks, r, l, 8); + D_ENCRYPT(ks, l, r, 7); + D_ENCRYPT(ks, r, l, 6); + D_ENCRYPT(ks, l, r, 5); + D_ENCRYPT(ks, r, l, 4); + D_ENCRYPT(ks, l, r, 3); + D_ENCRYPT(ks, r, l, 2); + D_ENCRYPT(ks, l, r, 1); + D_ENCRYPT(ks, r, l, 0); + } + // rotate and clear the top bits on machines with 8byte longs + data[0] = ROTATE(l, 3) & 0xffffffffL; + data[1] = ROTATE(r, 3) & 0xffffffffL; +} + +void DES_encrypt3(uint32_t *data, const DES_key_schedule *ks1, + const DES_key_schedule *ks2, const DES_key_schedule *ks3) { + uint32_t l, r; + + l = data[0]; + r = data[1]; + IP(l, r); + data[0] = l; + data[1] = r; + DES_encrypt2((uint32_t *)data, ks1, DES_ENCRYPT); + DES_encrypt2((uint32_t *)data, ks2, DES_DECRYPT); + DES_encrypt2((uint32_t *)data, ks3, DES_ENCRYPT); + l = data[0]; + r = data[1]; + FP(r, l); + data[0] = l; + data[1] = r; +} + +void DES_decrypt3(uint32_t *data, const DES_key_schedule *ks1, + const DES_key_schedule *ks2, const DES_key_schedule *ks3) { + uint32_t l, r; + + l = data[0]; + r = data[1]; + IP(l, r); + data[0] = l; + data[1] = r; + DES_encrypt2((uint32_t *)data, ks3, DES_DECRYPT); + DES_encrypt2((uint32_t *)data, ks2, DES_ENCRYPT); + DES_encrypt2((uint32_t *)data, ks1, DES_DECRYPT); + l = data[0]; + r = data[1]; + FP(r, l); + data[0] = l; + data[1] = r; +} + +void DES_ecb_encrypt(const DES_cblock *in_block, DES_cblock *out_block, + const DES_key_schedule *schedule, int is_encrypt) { + uint32_t l; + uint32_t ll[2]; + const uint8_t *in = in_block->bytes; + uint8_t *out = out_block->bytes; + + c2l(in, l); + ll[0] = l; + c2l(in, l); + ll[1] = l; + DES_encrypt1(ll, schedule, is_encrypt); + l = ll[0]; + l2c(l, out); + l = ll[1]; + l2c(l, out); + ll[0] = ll[1] = 0; +} + +void DES_ncbc_encrypt(const uint8_t *in, uint8_t *out, size_t len, + const DES_key_schedule *schedule, DES_cblock *ivec, + int enc) { + uint32_t tin0, tin1; + uint32_t tout0, tout1, xor0, xor1; + uint32_t tin[2]; + unsigned char *iv; + + iv = ivec->bytes; + + if (enc) { + c2l(iv, tout0); + c2l(iv, tout1); + for (; len >= 8; len -= 8) { + c2l(in, tin0); + c2l(in, tin1); + tin0 ^= tout0; + tin[0] = tin0; + tin1 ^= tout1; + tin[1] = tin1; + DES_encrypt1((uint32_t *)tin, schedule, DES_ENCRYPT); + tout0 = tin[0]; + l2c(tout0, out); + tout1 = tin[1]; + l2c(tout1, out); + } + if (len != 0) { + c2ln(in, tin0, tin1, len); + tin0 ^= tout0; + tin[0] = tin0; + tin1 ^= tout1; + tin[1] = tin1; + DES_encrypt1((uint32_t *)tin, schedule, DES_ENCRYPT); + tout0 = tin[0]; + l2c(tout0, out); + tout1 = tin[1]; + l2c(tout1, out); + } + iv = ivec->bytes; + l2c(tout0, iv); + l2c(tout1, iv); + } else { + c2l(iv, xor0); + c2l(iv, xor1); + for (; len >= 8; len -= 8) { + c2l(in, tin0); + tin[0] = tin0; + c2l(in, tin1); + tin[1] = tin1; + DES_encrypt1((uint32_t *)tin, schedule, DES_DECRYPT); + tout0 = tin[0] ^ xor0; + tout1 = tin[1] ^ xor1; + l2c(tout0, out); + l2c(tout1, out); + xor0 = tin0; + xor1 = tin1; + } + if (len != 0) { + c2l(in, tin0); + tin[0] = tin0; + c2l(in, tin1); + tin[1] = tin1; + DES_encrypt1((uint32_t *)tin, schedule, DES_DECRYPT); + tout0 = tin[0] ^ xor0; + tout1 = tin[1] ^ xor1; + l2cn(tout0, tout1, out, len); + xor0 = tin0; + xor1 = tin1; + } + iv = ivec->bytes; + l2c(xor0, iv); + l2c(xor1, iv); + } + tin[0] = tin[1] = 0; +} + +void DES_ecb3_encrypt(const DES_cblock *input, DES_cblock *output, + const DES_key_schedule *ks1, const DES_key_schedule *ks2, + const DES_key_schedule *ks3, int enc) { + uint32_t l0, l1; + uint32_t ll[2]; + const uint8_t *in = input->bytes; + uint8_t *out = output->bytes; + + 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); +} + +void DES_ede3_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t len, + const DES_key_schedule *ks1, + const DES_key_schedule *ks2, + const DES_key_schedule *ks3, DES_cblock *ivec, + int enc) { + uint32_t tin0, tin1; + uint32_t tout0, tout1, xor0, xor1; + uint32_t tin[2]; + uint8_t *iv; + + iv = ivec->bytes; + + if (enc) { + c2l(iv, tout0); + c2l(iv, tout1); + for (; len >= 8; len -= 8) { + c2l(in, tin0); + c2l(in, tin1); + tin0 ^= tout0; + tin1 ^= tout1; + + tin[0] = tin0; + tin[1] = tin1; + DES_encrypt3((uint32_t *)tin, ks1, ks2, ks3); + tout0 = tin[0]; + tout1 = tin[1]; + + l2c(tout0, out); + l2c(tout1, out); + } + if (len != 0) { + c2ln(in, tin0, tin1, len); + tin0 ^= tout0; + tin1 ^= tout1; + + tin[0] = tin0; + tin[1] = tin1; + DES_encrypt3((uint32_t *)tin, ks1, ks2, ks3); + tout0 = tin[0]; + tout1 = tin[1]; + + l2c(tout0, out); + l2c(tout1, out); + } + iv = ivec->bytes; + l2c(tout0, iv); + l2c(tout1, iv); + } else { + uint32_t t0, t1; + + c2l(iv, xor0); + c2l(iv, xor1); + for (; len >= 8; len -= 8) { + c2l(in, tin0); + c2l(in, tin1); + + t0 = tin0; + t1 = tin1; + + tin[0] = tin0; + tin[1] = tin1; + DES_decrypt3((uint32_t *)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 (len != 0) { + c2l(in, tin0); + c2l(in, tin1); + + t0 = tin0; + t1 = tin1; + + tin[0] = tin0; + tin[1] = tin1; + DES_decrypt3((uint32_t *)tin, ks1, ks2, ks3); + tout0 = tin[0]; + tout1 = tin[1]; + + tout0 ^= xor0; + tout1 ^= xor1; + l2cn(tout0, tout1, out, len); + xor0 = t0; + xor1 = t1; + } + + iv = ivec->bytes; + l2c(xor0, iv); + l2c(xor1, iv); + } + + tin[0] = tin[1] = 0; +} + +void DES_ede2_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t len, + const DES_key_schedule *ks1, + const DES_key_schedule *ks2, + DES_cblock *ivec, + int enc) { + DES_ede3_cbc_encrypt(in, out, len, ks1, ks2, ks1, ivec, enc); +} + + +// Deprecated functions. + +void DES_set_key_unchecked(const DES_cblock *key, DES_key_schedule *schedule) { + DES_set_key(key, schedule); +} + +#undef HPERM_OP +#undef c2l +#undef l2c +#undef c2ln +#undef l2cn +#undef PERM_OP +#undef IP +#undef FP +#undef LOAD_DATA +#undef D_ENCRYPT +#undef ITERATIONS +#undef HALF_ITERATIONS +#undef ROTATE diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/des/internal.h b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/des/internal.h new file mode 100644 index 0000000..841812a --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/des/internal.h @@ -0,0 +1,240 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 OPENSSL_HEADER_DES_INTERNAL_H +#define OPENSSL_HEADER_DES_INTERNAL_H + +#include + +#include "../../internal.h" + +#if defined(__cplusplus) +extern "C" { +#endif + + +#define c2l(c, l) \ + do { \ + (l) = ((uint32_t)(*((c)++))); \ + (l) |= ((uint32_t)(*((c)++))) << 8L; \ + (l) |= ((uint32_t)(*((c)++))) << 16L; \ + (l) |= ((uint32_t)(*((c)++))) << 24L; \ + } while (0) + +#define l2c(l, c) \ + do { \ + *((c)++) = (unsigned char)(((l)) & 0xff); \ + *((c)++) = (unsigned char)(((l) >> 8L) & 0xff); \ + *((c)++) = (unsigned char)(((l) >> 16L) & 0xff); \ + *((c)++) = (unsigned char)(((l) >> 24L) & 0xff); \ + } while (0) + +// NOTE - c is not incremented as per c2l +#define c2ln(c, l1, l2, n) \ + do { \ + (c) += (n); \ + (l1) = (l2) = 0; \ + switch (n) { \ + case 8: \ + (l2) = ((uint32_t)(*(--(c)))) << 24L; \ + OPENSSL_FALLTHROUGH; \ + case 7: \ + (l2) |= ((uint32_t)(*(--(c)))) << 16L; \ + OPENSSL_FALLTHROUGH; \ + case 6: \ + (l2) |= ((uint32_t)(*(--(c)))) << 8L; \ + OPENSSL_FALLTHROUGH; \ + case 5: \ + (l2) |= ((uint32_t)(*(--(c)))); \ + OPENSSL_FALLTHROUGH; \ + case 4: \ + (l1) = ((uint32_t)(*(--(c)))) << 24L; \ + OPENSSL_FALLTHROUGH; \ + case 3: \ + (l1) |= ((uint32_t)(*(--(c)))) << 16L; \ + OPENSSL_FALLTHROUGH; \ + case 2: \ + (l1) |= ((uint32_t)(*(--(c)))) << 8L; \ + OPENSSL_FALLTHROUGH; \ + case 1: \ + (l1) |= ((uint32_t)(*(--(c)))); \ + } \ + } while (0) + +// NOTE - c is not incremented as per l2c +#define l2cn(l1, l2, c, n) \ + do { \ + (c) += (n); \ + switch (n) { \ + case 8: \ + *(--(c)) = (unsigned char)(((l2) >> 24L) & 0xff); \ + OPENSSL_FALLTHROUGH; \ + case 7: \ + *(--(c)) = (unsigned char)(((l2) >> 16L) & 0xff); \ + OPENSSL_FALLTHROUGH; \ + case 6: \ + *(--(c)) = (unsigned char)(((l2) >> 8L) & 0xff); \ + OPENSSL_FALLTHROUGH; \ + case 5: \ + *(--(c)) = (unsigned char)(((l2)) & 0xff); \ + OPENSSL_FALLTHROUGH; \ + case 4: \ + *(--(c)) = (unsigned char)(((l1) >> 24L) & 0xff); \ + OPENSSL_FALLTHROUGH; \ + case 3: \ + *(--(c)) = (unsigned char)(((l1) >> 16L) & 0xff); \ + OPENSSL_FALLTHROUGH; \ + case 2: \ + *(--(c)) = (unsigned char)(((l1) >> 8L) & 0xff); \ + OPENSSL_FALLTHROUGH; \ + case 1: \ + *(--(c)) = (unsigned char)(((l1)) & 0xff); \ + } \ + } while (0) + +/* 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)); \ + } while (0) + +#define IP(l, r) \ + do { \ + uint32_t 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); \ + } while (0) + +#define FP(l, r) \ + do { \ + uint32_t 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); \ + } while (0) + +#define LOAD_DATA(ks, R, S, u, t, E0, E1) \ + do { \ + (u) = (R) ^ (ks)->subkeys[S][0]; \ + (t) = (R) ^ (ks)->subkeys[S][1]; \ + } while (0) + +#define D_ENCRYPT(ks, LL, R, S) \ + do { \ + LOAD_DATA(ks, 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]; \ + } while (0) + +#define ITERATIONS 16 +#define HALF_ITERATIONS 8 + +#define ROTATE(a, n) (((a) >> (n)) + ((a) << (32 - (n)))) + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_DES_INTERNAL_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/des/internal.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/des/internal.h.grpc_back new file mode 100644 index 0000000..1ae3f22 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/des/internal.h.grpc_back @@ -0,0 +1,240 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 OPENSSL_HEADER_DES_INTERNAL_H +#define OPENSSL_HEADER_DES_INTERNAL_H + +#include + +#include "../../internal.h" + +#if defined(__cplusplus) +extern "C" { +#endif + + +#define c2l(c, l) \ + do { \ + (l) = ((uint32_t)(*((c)++))); \ + (l) |= ((uint32_t)(*((c)++))) << 8L; \ + (l) |= ((uint32_t)(*((c)++))) << 16L; \ + (l) |= ((uint32_t)(*((c)++))) << 24L; \ + } while (0) + +#define l2c(l, c) \ + do { \ + *((c)++) = (unsigned char)(((l)) & 0xff); \ + *((c)++) = (unsigned char)(((l) >> 8L) & 0xff); \ + *((c)++) = (unsigned char)(((l) >> 16L) & 0xff); \ + *((c)++) = (unsigned char)(((l) >> 24L) & 0xff); \ + } while (0) + +// NOTE - c is not incremented as per c2l +#define c2ln(c, l1, l2, n) \ + do { \ + (c) += (n); \ + (l1) = (l2) = 0; \ + switch (n) { \ + case 8: \ + (l2) = ((uint32_t)(*(--(c)))) << 24L; \ + OPENSSL_FALLTHROUGH; \ + case 7: \ + (l2) |= ((uint32_t)(*(--(c)))) << 16L; \ + OPENSSL_FALLTHROUGH; \ + case 6: \ + (l2) |= ((uint32_t)(*(--(c)))) << 8L; \ + OPENSSL_FALLTHROUGH; \ + case 5: \ + (l2) |= ((uint32_t)(*(--(c)))); \ + OPENSSL_FALLTHROUGH; \ + case 4: \ + (l1) = ((uint32_t)(*(--(c)))) << 24L; \ + OPENSSL_FALLTHROUGH; \ + case 3: \ + (l1) |= ((uint32_t)(*(--(c)))) << 16L; \ + OPENSSL_FALLTHROUGH; \ + case 2: \ + (l1) |= ((uint32_t)(*(--(c)))) << 8L; \ + OPENSSL_FALLTHROUGH; \ + case 1: \ + (l1) |= ((uint32_t)(*(--(c)))); \ + } \ + } while (0) + +// NOTE - c is not incremented as per l2c +#define l2cn(l1, l2, c, n) \ + do { \ + (c) += (n); \ + switch (n) { \ + case 8: \ + *(--(c)) = (unsigned char)(((l2) >> 24L) & 0xff); \ + OPENSSL_FALLTHROUGH; \ + case 7: \ + *(--(c)) = (unsigned char)(((l2) >> 16L) & 0xff); \ + OPENSSL_FALLTHROUGH; \ + case 6: \ + *(--(c)) = (unsigned char)(((l2) >> 8L) & 0xff); \ + OPENSSL_FALLTHROUGH; \ + case 5: \ + *(--(c)) = (unsigned char)(((l2)) & 0xff); \ + OPENSSL_FALLTHROUGH; \ + case 4: \ + *(--(c)) = (unsigned char)(((l1) >> 24L) & 0xff); \ + OPENSSL_FALLTHROUGH; \ + case 3: \ + *(--(c)) = (unsigned char)(((l1) >> 16L) & 0xff); \ + OPENSSL_FALLTHROUGH; \ + case 2: \ + *(--(c)) = (unsigned char)(((l1) >> 8L) & 0xff); \ + OPENSSL_FALLTHROUGH; \ + case 1: \ + *(--(c)) = (unsigned char)(((l1)) & 0xff); \ + } \ + } while (0) + +/* 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)); \ + } while (0) + +#define IP(l, r) \ + do { \ + uint32_t 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); \ + } while (0) + +#define FP(l, r) \ + do { \ + uint32_t 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); \ + } while (0) + +#define LOAD_DATA(ks, R, S, u, t, E0, E1) \ + do { \ + (u) = (R) ^ (ks)->subkeys[S][0]; \ + (t) = (R) ^ (ks)->subkeys[S][1]; \ + } while (0) + +#define D_ENCRYPT(ks, LL, R, S) \ + do { \ + LOAD_DATA(ks, 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]; \ + } while (0) + +#define ITERATIONS 16 +#define HALF_ITERATIONS 8 + +#define ROTATE(a, n) (((a) >> (n)) + ((a) << (32 - (n)))) + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_DES_INTERNAL_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/digest/digest.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/digest/digest.c new file mode 100644 index 0000000..d28ba44 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/digest/digest.c @@ -0,0 +1,256 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 + +#include "internal.h" +#include "../../internal.h" + + +int EVP_MD_type(const EVP_MD *md) { return md->type; } + +uint32_t EVP_MD_flags(const EVP_MD *md) { return md->flags; } + +size_t EVP_MD_size(const EVP_MD *md) { return md->md_size; } + +size_t EVP_MD_block_size(const EVP_MD *md) { return md->block_size; } + + +void EVP_MD_CTX_init(EVP_MD_CTX *ctx) { + OPENSSL_memset(ctx, 0, sizeof(EVP_MD_CTX)); +} + +EVP_MD_CTX *EVP_MD_CTX_new(void) { + EVP_MD_CTX *ctx = OPENSSL_malloc(sizeof(EVP_MD_CTX)); + + if (ctx) { + EVP_MD_CTX_init(ctx); + } + + return ctx; +} + +EVP_MD_CTX *EVP_MD_CTX_create(void) { return EVP_MD_CTX_new(); } + +int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx) { + OPENSSL_free(ctx->md_data); + + assert(ctx->pctx == NULL || ctx->pctx_ops != NULL); + if (ctx->pctx_ops) { + ctx->pctx_ops->free(ctx->pctx); + } + + EVP_MD_CTX_init(ctx); + + return 1; +} + +void EVP_MD_CTX_free(EVP_MD_CTX *ctx) { + if (!ctx) { + return; + } + + EVP_MD_CTX_cleanup(ctx); + OPENSSL_free(ctx); +} + +void EVP_MD_CTX_destroy(EVP_MD_CTX *ctx) { EVP_MD_CTX_free(ctx); } + +int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in) { + if (in == NULL || in->digest == NULL) { + OPENSSL_PUT_ERROR(DIGEST, DIGEST_R_INPUT_NOT_INITIALIZED); + return 0; + } + + EVP_PKEY_CTX *pctx = NULL; + assert(in->pctx == NULL || in->pctx_ops != NULL); + if (in->pctx) { + pctx = in->pctx_ops->dup(in->pctx); + if (!pctx) { + OPENSSL_PUT_ERROR(DIGEST, ERR_R_MALLOC_FAILURE); + return 0; + } + } + + uint8_t *tmp_buf; + if (out->digest != in->digest) { + assert(in->digest->ctx_size != 0); + tmp_buf = OPENSSL_malloc(in->digest->ctx_size); + if (tmp_buf == NULL) { + if (pctx) { + in->pctx_ops->free(pctx); + } + OPENSSL_PUT_ERROR(DIGEST, ERR_R_MALLOC_FAILURE); + return 0; + } + } else { + // |md_data| will be the correct size in this case. It's removed from |out| + // so that |EVP_MD_CTX_cleanup| doesn't free it, and then it's reused. + tmp_buf = out->md_data; + out->md_data = NULL; + } + + EVP_MD_CTX_cleanup(out); + + out->digest = in->digest; + out->md_data = tmp_buf; + OPENSSL_memcpy(out->md_data, in->md_data, in->digest->ctx_size); + out->pctx = pctx; + out->pctx_ops = in->pctx_ops; + assert(out->pctx == NULL || out->pctx_ops != NULL); + + return 1; +} + +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); +} + +void EVP_MD_CTX_reset(EVP_MD_CTX *ctx) { + EVP_MD_CTX_cleanup(ctx); + EVP_MD_CTX_init(ctx); +} + +int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *engine) { + if (ctx->digest != type) { + assert(type->ctx_size != 0); + uint8_t *md_data = OPENSSL_malloc(type->ctx_size); + if (md_data == NULL) { + OPENSSL_PUT_ERROR(DIGEST, ERR_R_MALLOC_FAILURE); + return 0; + } + + OPENSSL_free(ctx->md_data); + ctx->md_data = md_data; + ctx->digest = type; + } + + assert(ctx->pctx == NULL || ctx->pctx_ops != NULL); + + ctx->digest->init(ctx); + return 1; +} + +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_DigestUpdate(EVP_MD_CTX *ctx, const void *data, size_t len) { + ctx->digest->update(ctx, data, len); + return 1; +} + +int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, uint8_t *md_out, unsigned int *size) { + assert(ctx->digest->md_size <= EVP_MAX_MD_SIZE); + ctx->digest->final(ctx, md_out); + if (size != NULL) { + *size = ctx->digest->md_size; + } + OPENSSL_cleanse(ctx->md_data, ctx->digest->ctx_size); + return 1; +} + +int EVP_DigestFinal(EVP_MD_CTX *ctx, uint8_t *md, unsigned int *size) { + (void)EVP_DigestFinal_ex(ctx, md, size); + EVP_MD_CTX_cleanup(ctx); + return 1; +} + +int EVP_Digest(const void *data, size_t count, uint8_t *out_md, + unsigned int *out_size, const EVP_MD *type, ENGINE *impl) { + EVP_MD_CTX ctx; + int ret; + + EVP_MD_CTX_init(&ctx); + ret = EVP_DigestInit_ex(&ctx, type, impl) && + EVP_DigestUpdate(&ctx, data, count) && + EVP_DigestFinal_ex(&ctx, out_md, out_size); + EVP_MD_CTX_cleanup(&ctx); + + return ret; +} + + +const EVP_MD *EVP_MD_CTX_md(const EVP_MD_CTX *ctx) { + if (ctx == NULL) { + return NULL; + } + return ctx->digest; +} + +size_t EVP_MD_CTX_size(const EVP_MD_CTX *ctx) { + return EVP_MD_size(EVP_MD_CTX_md(ctx)); +} + +size_t EVP_MD_CTX_block_size(const EVP_MD_CTX *ctx) { + return EVP_MD_block_size(EVP_MD_CTX_md(ctx)); +} + +int EVP_MD_CTX_type(const EVP_MD_CTX *ctx) { + return EVP_MD_type(EVP_MD_CTX_md(ctx)); +} + +int EVP_add_digest(const EVP_MD *digest) { + return 1; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/digest/digest.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/digest/digest.c.grpc_back new file mode 100644 index 0000000..1c35809 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/digest/digest.c.grpc_back @@ -0,0 +1,256 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 + +#include "internal.h" +#include "../../internal.h" + + +int EVP_MD_type(const EVP_MD *md) { return md->type; } + +uint32_t EVP_MD_flags(const EVP_MD *md) { return md->flags; } + +size_t EVP_MD_size(const EVP_MD *md) { return md->md_size; } + +size_t EVP_MD_block_size(const EVP_MD *md) { return md->block_size; } + + +void EVP_MD_CTX_init(EVP_MD_CTX *ctx) { + OPENSSL_memset(ctx, 0, sizeof(EVP_MD_CTX)); +} + +EVP_MD_CTX *EVP_MD_CTX_new(void) { + EVP_MD_CTX *ctx = OPENSSL_malloc(sizeof(EVP_MD_CTX)); + + if (ctx) { + EVP_MD_CTX_init(ctx); + } + + return ctx; +} + +EVP_MD_CTX *EVP_MD_CTX_create(void) { return EVP_MD_CTX_new(); } + +int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx) { + OPENSSL_free(ctx->md_data); + + assert(ctx->pctx == NULL || ctx->pctx_ops != NULL); + if (ctx->pctx_ops) { + ctx->pctx_ops->free(ctx->pctx); + } + + EVP_MD_CTX_init(ctx); + + return 1; +} + +void EVP_MD_CTX_free(EVP_MD_CTX *ctx) { + if (!ctx) { + return; + } + + EVP_MD_CTX_cleanup(ctx); + OPENSSL_free(ctx); +} + +void EVP_MD_CTX_destroy(EVP_MD_CTX *ctx) { EVP_MD_CTX_free(ctx); } + +int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in) { + if (in == NULL || in->digest == NULL) { + OPENSSL_PUT_ERROR(DIGEST, DIGEST_R_INPUT_NOT_INITIALIZED); + return 0; + } + + EVP_PKEY_CTX *pctx = NULL; + assert(in->pctx == NULL || in->pctx_ops != NULL); + if (in->pctx) { + pctx = in->pctx_ops->dup(in->pctx); + if (!pctx) { + OPENSSL_PUT_ERROR(DIGEST, ERR_R_MALLOC_FAILURE); + return 0; + } + } + + uint8_t *tmp_buf; + if (out->digest != in->digest) { + assert(in->digest->ctx_size != 0); + tmp_buf = OPENSSL_malloc(in->digest->ctx_size); + if (tmp_buf == NULL) { + if (pctx) { + in->pctx_ops->free(pctx); + } + OPENSSL_PUT_ERROR(DIGEST, ERR_R_MALLOC_FAILURE); + return 0; + } + } else { + // |md_data| will be the correct size in this case. It's removed from |out| + // so that |EVP_MD_CTX_cleanup| doesn't free it, and then it's reused. + tmp_buf = out->md_data; + out->md_data = NULL; + } + + EVP_MD_CTX_cleanup(out); + + out->digest = in->digest; + out->md_data = tmp_buf; + OPENSSL_memcpy(out->md_data, in->md_data, in->digest->ctx_size); + out->pctx = pctx; + out->pctx_ops = in->pctx_ops; + assert(out->pctx == NULL || out->pctx_ops != NULL); + + return 1; +} + +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); +} + +void EVP_MD_CTX_reset(EVP_MD_CTX *ctx) { + EVP_MD_CTX_cleanup(ctx); + EVP_MD_CTX_init(ctx); +} + +int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, ENGINE *engine) { + if (ctx->digest != type) { + assert(type->ctx_size != 0); + uint8_t *md_data = OPENSSL_malloc(type->ctx_size); + if (md_data == NULL) { + OPENSSL_PUT_ERROR(DIGEST, ERR_R_MALLOC_FAILURE); + return 0; + } + + OPENSSL_free(ctx->md_data); + ctx->md_data = md_data; + ctx->digest = type; + } + + assert(ctx->pctx == NULL || ctx->pctx_ops != NULL); + + ctx->digest->init(ctx); + return 1; +} + +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_DigestUpdate(EVP_MD_CTX *ctx, const void *data, size_t len) { + ctx->digest->update(ctx, data, len); + return 1; +} + +int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, uint8_t *md_out, unsigned int *size) { + assert(ctx->digest->md_size <= EVP_MAX_MD_SIZE); + ctx->digest->final(ctx, md_out); + if (size != NULL) { + *size = ctx->digest->md_size; + } + OPENSSL_cleanse(ctx->md_data, ctx->digest->ctx_size); + return 1; +} + +int EVP_DigestFinal(EVP_MD_CTX *ctx, uint8_t *md, unsigned int *size) { + (void)EVP_DigestFinal_ex(ctx, md, size); + EVP_MD_CTX_cleanup(ctx); + return 1; +} + +int EVP_Digest(const void *data, size_t count, uint8_t *out_md, + unsigned int *out_size, const EVP_MD *type, ENGINE *impl) { + EVP_MD_CTX ctx; + int ret; + + EVP_MD_CTX_init(&ctx); + ret = EVP_DigestInit_ex(&ctx, type, impl) && + EVP_DigestUpdate(&ctx, data, count) && + EVP_DigestFinal_ex(&ctx, out_md, out_size); + EVP_MD_CTX_cleanup(&ctx); + + return ret; +} + + +const EVP_MD *EVP_MD_CTX_md(const EVP_MD_CTX *ctx) { + if (ctx == NULL) { + return NULL; + } + return ctx->digest; +} + +size_t EVP_MD_CTX_size(const EVP_MD_CTX *ctx) { + return EVP_MD_size(EVP_MD_CTX_md(ctx)); +} + +size_t EVP_MD_CTX_block_size(const EVP_MD_CTX *ctx) { + return EVP_MD_block_size(EVP_MD_CTX_md(ctx)); +} + +int EVP_MD_CTX_type(const EVP_MD_CTX *ctx) { + return EVP_MD_type(EVP_MD_CTX_md(ctx)); +} + +int EVP_add_digest(const EVP_MD *digest) { + return 1; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/digest/digests.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/digest/digests.c new file mode 100644 index 0000000..bda7f78 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/digest/digests.c @@ -0,0 +1,280 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 +#include +#include + +#include "internal.h" +#include "../delocate.h" +#include "../../internal.h" + +#if defined(NDEBUG) +#define CHECK(x) (void) (x) +#else +#define CHECK(x) assert(x) +#endif + + +static void md4_init(EVP_MD_CTX *ctx) { + CHECK(MD4_Init(ctx->md_data)); +} + +static void md4_update(EVP_MD_CTX *ctx, const void *data, size_t count) { + CHECK(MD4_Update(ctx->md_data, data, count)); +} + +static void md4_final(EVP_MD_CTX *ctx, uint8_t *out) { + CHECK(MD4_Final(out, ctx->md_data)); +} + +DEFINE_METHOD_FUNCTION(EVP_MD, EVP_md4) { + out->type = NID_md4; + out->md_size = MD4_DIGEST_LENGTH; + out->flags = 0; + out->init = md4_init; + out->update = md4_update; + out->final = md4_final; + out->block_size = 64; + out->ctx_size = sizeof(MD4_CTX); +} + + +static void md5_init(EVP_MD_CTX *ctx) { + CHECK(MD5_Init(ctx->md_data)); +} + +static void md5_update(EVP_MD_CTX *ctx, const void *data, size_t count) { + CHECK(MD5_Update(ctx->md_data, data, count)); +} + +static void md5_final(EVP_MD_CTX *ctx, uint8_t *out) { + CHECK(MD5_Final(out, ctx->md_data)); +} + +DEFINE_METHOD_FUNCTION(EVP_MD, EVP_md5) { + out->type = NID_md5; + out->md_size = MD5_DIGEST_LENGTH; + out->flags = 0; + out->init = md5_init; + out->update = md5_update; + out->final = md5_final; + out->block_size = 64; + out->ctx_size = sizeof(MD5_CTX); +} + + +static void sha1_init(EVP_MD_CTX *ctx) { + CHECK(SHA1_Init(ctx->md_data)); +} + +static void sha1_update(EVP_MD_CTX *ctx, const void *data, size_t count) { + CHECK(SHA1_Update(ctx->md_data, data, count)); +} + +static void sha1_final(EVP_MD_CTX *ctx, uint8_t *md) { + CHECK(SHA1_Final(md, ctx->md_data)); +} + +DEFINE_METHOD_FUNCTION(EVP_MD, EVP_sha1) { + out->type = NID_sha1; + out->md_size = SHA_DIGEST_LENGTH; + out->flags = 0; + out->init = sha1_init; + out->update = sha1_update; + out->final = sha1_final; + out->block_size = 64; + out->ctx_size = sizeof(SHA_CTX); +} + + +static void sha224_init(EVP_MD_CTX *ctx) { + CHECK(SHA224_Init(ctx->md_data)); +} + +static void sha224_update(EVP_MD_CTX *ctx, const void *data, size_t count) { + CHECK(SHA224_Update(ctx->md_data, data, count)); +} + +static void sha224_final(EVP_MD_CTX *ctx, uint8_t *md) { + CHECK(SHA224_Final(md, ctx->md_data)); +} + +DEFINE_METHOD_FUNCTION(EVP_MD, EVP_sha224) { + out->type = NID_sha224; + out->md_size = SHA224_DIGEST_LENGTH; + out->flags = 0; + out->init = sha224_init; + out->update = sha224_update; + out->final = sha224_final; + out->block_size = 64; + out->ctx_size = sizeof(SHA256_CTX); +} + + +static void sha256_init(EVP_MD_CTX *ctx) { + CHECK(SHA256_Init(ctx->md_data)); +} + +static void sha256_update(EVP_MD_CTX *ctx, const void *data, size_t count) { + CHECK(SHA256_Update(ctx->md_data, data, count)); +} + +static void sha256_final(EVP_MD_CTX *ctx, uint8_t *md) { + CHECK(SHA256_Final(md, ctx->md_data)); +} + +DEFINE_METHOD_FUNCTION(EVP_MD, EVP_sha256) { + out->type = NID_sha256; + out->md_size = SHA256_DIGEST_LENGTH; + out->flags = 0; + out->init = sha256_init; + out->update = sha256_update; + out->final = sha256_final; + out->block_size = 64; + out->ctx_size = sizeof(SHA256_CTX); +} + + +static void sha384_init(EVP_MD_CTX *ctx) { + CHECK(SHA384_Init(ctx->md_data)); +} + +static void sha384_update(EVP_MD_CTX *ctx, const void *data, size_t count) { + CHECK(SHA384_Update(ctx->md_data, data, count)); +} + +static void sha384_final(EVP_MD_CTX *ctx, uint8_t *md) { + CHECK(SHA384_Final(md, ctx->md_data)); +} + +DEFINE_METHOD_FUNCTION(EVP_MD, EVP_sha384) { + out->type = NID_sha384; + out->md_size = SHA384_DIGEST_LENGTH; + out->flags = 0; + out->init = sha384_init; + out->update = sha384_update; + out->final = sha384_final; + out->block_size = 128; + out->ctx_size = sizeof(SHA512_CTX); +} + + +static void sha512_init(EVP_MD_CTX *ctx) { + CHECK(SHA512_Init(ctx->md_data)); +} + +static void sha512_update(EVP_MD_CTX *ctx, const void *data, size_t count) { + CHECK(SHA512_Update(ctx->md_data, data, count)); +} + +static void sha512_final(EVP_MD_CTX *ctx, uint8_t *md) { + CHECK(SHA512_Final(md, ctx->md_data)); +} + +DEFINE_METHOD_FUNCTION(EVP_MD, EVP_sha512) { + out->type = NID_sha512; + out->md_size = SHA512_DIGEST_LENGTH; + out->flags = 0; + out->init = sha512_init; + out->update = sha512_update; + out->final = sha512_final; + out->block_size = 128; + out->ctx_size = sizeof(SHA512_CTX); +} + + +typedef struct { + MD5_CTX md5; + SHA_CTX sha1; +} MD5_SHA1_CTX; + +static void md5_sha1_init(EVP_MD_CTX *md_ctx) { + MD5_SHA1_CTX *ctx = md_ctx->md_data; + CHECK(MD5_Init(&ctx->md5) && SHA1_Init(&ctx->sha1)); +} + +static void md5_sha1_update(EVP_MD_CTX *md_ctx, const void *data, + size_t count) { + MD5_SHA1_CTX *ctx = md_ctx->md_data; + CHECK(MD5_Update(&ctx->md5, data, count) && + SHA1_Update(&ctx->sha1, data, count)); +} + +static void md5_sha1_final(EVP_MD_CTX *md_ctx, uint8_t *out) { + MD5_SHA1_CTX *ctx = md_ctx->md_data; + CHECK(MD5_Final(out, &ctx->md5) && + SHA1_Final(out + MD5_DIGEST_LENGTH, &ctx->sha1)); +} + +DEFINE_METHOD_FUNCTION(EVP_MD, EVP_md5_sha1) { + out->type = NID_md5_sha1; + out->md_size = MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH; + out->flags = 0; + out->init = md5_sha1_init; + out->update = md5_sha1_update; + out->final = md5_sha1_final; + out->block_size = 64; + out->ctx_size = sizeof(MD5_SHA1_CTX); +} + +#undef CHECK diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/digest/digests.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/digest/digests.c.grpc_back new file mode 100644 index 0000000..f2fa349 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/digest/digests.c.grpc_back @@ -0,0 +1,280 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 +#include +#include + +#include "internal.h" +#include "../delocate.h" +#include "../../internal.h" + +#if defined(NDEBUG) +#define CHECK(x) (void) (x) +#else +#define CHECK(x) assert(x) +#endif + + +static void md4_init(EVP_MD_CTX *ctx) { + CHECK(MD4_Init(ctx->md_data)); +} + +static void md4_update(EVP_MD_CTX *ctx, const void *data, size_t count) { + CHECK(MD4_Update(ctx->md_data, data, count)); +} + +static void md4_final(EVP_MD_CTX *ctx, uint8_t *out) { + CHECK(MD4_Final(out, ctx->md_data)); +} + +DEFINE_METHOD_FUNCTION(EVP_MD, EVP_md4) { + out->type = NID_md4; + out->md_size = MD4_DIGEST_LENGTH; + out->flags = 0; + out->init = md4_init; + out->update = md4_update; + out->final = md4_final; + out->block_size = 64; + out->ctx_size = sizeof(MD4_CTX); +} + + +static void md5_init(EVP_MD_CTX *ctx) { + CHECK(MD5_Init(ctx->md_data)); +} + +static void md5_update(EVP_MD_CTX *ctx, const void *data, size_t count) { + CHECK(MD5_Update(ctx->md_data, data, count)); +} + +static void md5_final(EVP_MD_CTX *ctx, uint8_t *out) { + CHECK(MD5_Final(out, ctx->md_data)); +} + +DEFINE_METHOD_FUNCTION(EVP_MD, EVP_md5) { + out->type = NID_md5; + out->md_size = MD5_DIGEST_LENGTH; + out->flags = 0; + out->init = md5_init; + out->update = md5_update; + out->final = md5_final; + out->block_size = 64; + out->ctx_size = sizeof(MD5_CTX); +} + + +static void sha1_init(EVP_MD_CTX *ctx) { + CHECK(SHA1_Init(ctx->md_data)); +} + +static void sha1_update(EVP_MD_CTX *ctx, const void *data, size_t count) { + CHECK(SHA1_Update(ctx->md_data, data, count)); +} + +static void sha1_final(EVP_MD_CTX *ctx, uint8_t *md) { + CHECK(SHA1_Final(md, ctx->md_data)); +} + +DEFINE_METHOD_FUNCTION(EVP_MD, EVP_sha1) { + out->type = NID_sha1; + out->md_size = SHA_DIGEST_LENGTH; + out->flags = 0; + out->init = sha1_init; + out->update = sha1_update; + out->final = sha1_final; + out->block_size = 64; + out->ctx_size = sizeof(SHA_CTX); +} + + +static void sha224_init(EVP_MD_CTX *ctx) { + CHECK(SHA224_Init(ctx->md_data)); +} + +static void sha224_update(EVP_MD_CTX *ctx, const void *data, size_t count) { + CHECK(SHA224_Update(ctx->md_data, data, count)); +} + +static void sha224_final(EVP_MD_CTX *ctx, uint8_t *md) { + CHECK(SHA224_Final(md, ctx->md_data)); +} + +DEFINE_METHOD_FUNCTION(EVP_MD, EVP_sha224) { + out->type = NID_sha224; + out->md_size = SHA224_DIGEST_LENGTH; + out->flags = 0; + out->init = sha224_init; + out->update = sha224_update; + out->final = sha224_final; + out->block_size = 64; + out->ctx_size = sizeof(SHA256_CTX); +} + + +static void sha256_init(EVP_MD_CTX *ctx) { + CHECK(SHA256_Init(ctx->md_data)); +} + +static void sha256_update(EVP_MD_CTX *ctx, const void *data, size_t count) { + CHECK(SHA256_Update(ctx->md_data, data, count)); +} + +static void sha256_final(EVP_MD_CTX *ctx, uint8_t *md) { + CHECK(SHA256_Final(md, ctx->md_data)); +} + +DEFINE_METHOD_FUNCTION(EVP_MD, EVP_sha256) { + out->type = NID_sha256; + out->md_size = SHA256_DIGEST_LENGTH; + out->flags = 0; + out->init = sha256_init; + out->update = sha256_update; + out->final = sha256_final; + out->block_size = 64; + out->ctx_size = sizeof(SHA256_CTX); +} + + +static void sha384_init(EVP_MD_CTX *ctx) { + CHECK(SHA384_Init(ctx->md_data)); +} + +static void sha384_update(EVP_MD_CTX *ctx, const void *data, size_t count) { + CHECK(SHA384_Update(ctx->md_data, data, count)); +} + +static void sha384_final(EVP_MD_CTX *ctx, uint8_t *md) { + CHECK(SHA384_Final(md, ctx->md_data)); +} + +DEFINE_METHOD_FUNCTION(EVP_MD, EVP_sha384) { + out->type = NID_sha384; + out->md_size = SHA384_DIGEST_LENGTH; + out->flags = 0; + out->init = sha384_init; + out->update = sha384_update; + out->final = sha384_final; + out->block_size = 128; + out->ctx_size = sizeof(SHA512_CTX); +} + + +static void sha512_init(EVP_MD_CTX *ctx) { + CHECK(SHA512_Init(ctx->md_data)); +} + +static void sha512_update(EVP_MD_CTX *ctx, const void *data, size_t count) { + CHECK(SHA512_Update(ctx->md_data, data, count)); +} + +static void sha512_final(EVP_MD_CTX *ctx, uint8_t *md) { + CHECK(SHA512_Final(md, ctx->md_data)); +} + +DEFINE_METHOD_FUNCTION(EVP_MD, EVP_sha512) { + out->type = NID_sha512; + out->md_size = SHA512_DIGEST_LENGTH; + out->flags = 0; + out->init = sha512_init; + out->update = sha512_update; + out->final = sha512_final; + out->block_size = 128; + out->ctx_size = sizeof(SHA512_CTX); +} + + +typedef struct { + MD5_CTX md5; + SHA_CTX sha1; +} MD5_SHA1_CTX; + +static void md5_sha1_init(EVP_MD_CTX *md_ctx) { + MD5_SHA1_CTX *ctx = md_ctx->md_data; + CHECK(MD5_Init(&ctx->md5) && SHA1_Init(&ctx->sha1)); +} + +static void md5_sha1_update(EVP_MD_CTX *md_ctx, const void *data, + size_t count) { + MD5_SHA1_CTX *ctx = md_ctx->md_data; + CHECK(MD5_Update(&ctx->md5, data, count) && + SHA1_Update(&ctx->sha1, data, count)); +} + +static void md5_sha1_final(EVP_MD_CTX *md_ctx, uint8_t *out) { + MD5_SHA1_CTX *ctx = md_ctx->md_data; + CHECK(MD5_Final(out, &ctx->md5) && + SHA1_Final(out + MD5_DIGEST_LENGTH, &ctx->sha1)); +} + +DEFINE_METHOD_FUNCTION(EVP_MD, EVP_md5_sha1) { + out->type = NID_md5_sha1; + out->md_size = MD5_DIGEST_LENGTH + SHA_DIGEST_LENGTH; + out->flags = 0; + out->init = md5_sha1_init; + out->update = md5_sha1_update; + out->final = md5_sha1_final; + out->block_size = 64; + out->ctx_size = sizeof(MD5_SHA1_CTX); +} + +#undef CHECK diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/digest/internal.h b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/digest/internal.h new file mode 100644 index 0000000..ebac9ab --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/digest/internal.h @@ -0,0 +1,112 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 OPENSSL_HEADER_DIGEST_INTERNAL_H +#define OPENSSL_HEADER_DIGEST_INTERNAL_H + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +struct env_md_st { + // type contains a NID identifing the digest function. (For example, + // NID_md5.) + int type; + + // md_size contains the size, in bytes, of the resulting digest. + unsigned md_size; + + // flags contains the OR of |EVP_MD_FLAG_*| values. + uint32_t flags; + + // init initialises the state in |ctx->md_data|. + void (*init)(EVP_MD_CTX *ctx); + + // update hashes |len| bytes of |data| into the state in |ctx->md_data|. + void (*update)(EVP_MD_CTX *ctx, const void *data, size_t count); + + // final completes the hash and writes |md_size| bytes of digest to |out|. + void (*final)(EVP_MD_CTX *ctx, uint8_t *out); + + // block_size contains the hash's native block size. + unsigned block_size; + + // ctx_size contains the size, in bytes, of the state of the hash function. + unsigned ctx_size; +}; + +// evp_md_pctx_ops contains function pointers to allow the |pctx| member of +// |EVP_MD_CTX| to be manipulated without breaking layering by calling EVP +// functions. +struct evp_md_pctx_ops { + // free is called when an |EVP_MD_CTX| is being freed and the |pctx| also + // needs to be freed. + void (*free) (EVP_PKEY_CTX *pctx); + + // dup is called when an |EVP_MD_CTX| is copied and so the |pctx| also needs + // to be copied. + EVP_PKEY_CTX* (*dup) (EVP_PKEY_CTX *pctx); +}; + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_DIGEST_INTERNAL diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/digest/internal.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/digest/internal.h.grpc_back new file mode 100644 index 0000000..2d06ed0 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/digest/internal.h.grpc_back @@ -0,0 +1,112 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 OPENSSL_HEADER_DIGEST_INTERNAL_H +#define OPENSSL_HEADER_DIGEST_INTERNAL_H + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +struct env_md_st { + // type contains a NID identifing the digest function. (For example, + // NID_md5.) + int type; + + // md_size contains the size, in bytes, of the resulting digest. + unsigned md_size; + + // flags contains the OR of |EVP_MD_FLAG_*| values. + uint32_t flags; + + // init initialises the state in |ctx->md_data|. + void (*init)(EVP_MD_CTX *ctx); + + // update hashes |len| bytes of |data| into the state in |ctx->md_data|. + void (*update)(EVP_MD_CTX *ctx, const void *data, size_t count); + + // final completes the hash and writes |md_size| bytes of digest to |out|. + void (*final)(EVP_MD_CTX *ctx, uint8_t *out); + + // block_size contains the hash's native block size. + unsigned block_size; + + // ctx_size contains the size, in bytes, of the state of the hash function. + unsigned ctx_size; +}; + +// evp_md_pctx_ops contains function pointers to allow the |pctx| member of +// |EVP_MD_CTX| to be manipulated without breaking layering by calling EVP +// functions. +struct evp_md_pctx_ops { + // free is called when an |EVP_MD_CTX| is being freed and the |pctx| also + // needs to be freed. + void (*free) (EVP_PKEY_CTX *pctx); + + // dup is called when an |EVP_MD_CTX| is copied and so the |pctx| also needs + // to be copied. + EVP_PKEY_CTX* (*dup) (EVP_PKEY_CTX *pctx); +}; + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_DIGEST_INTERNAL diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/digest/md32_common.h b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/digest/md32_common.h new file mode 100644 index 0000000..b187e85 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/digest/md32_common.h @@ -0,0 +1,268 @@ +/* ==================================================================== + * 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. + * ==================================================================== */ + +#include + +#include + +#include "../../internal.h" + +#if defined(__cplusplus) +extern "C" { +#endif + + +// This is a generic 32-bit "collector" for message digest algorithms. It +// collects input character stream into chunks of 32-bit values and invokes the +// block function that performs the actual hash calculations. To make use of +// this mechanism, the following macros must be defined before including +// md32_common.h. +// +// One of |DATA_ORDER_IS_BIG_ENDIAN| or |DATA_ORDER_IS_LITTLE_ENDIAN| must be +// defined to specify the byte order of the input stream. +// +// |HASH_CBLOCK| must be defined as the integer block size, in bytes. +// +// |HASH_CTX| must be defined as the name of the context structure, which must +// have at least the following members: +// +// typedef struct _state_st { +// uint32_t h[ / sizeof(uint32_t)]; +// uint32_t Nl, Nh; +// uint8_t data[HASH_CBLOCK]; +// unsigned num; +// ... +// } _CTX; +// +// is the output length of the hash in bytes, before +// any truncation (e.g. 64 for SHA-224 and SHA-256, 128 for SHA-384 and +// SHA-512). +// +// |HASH_UPDATE| must be defined as the name of the "Update" function to +// generate. +// +// |HASH_TRANSFORM| must be defined as the the name of the "Transform" +// function to generate. +// +// |HASH_FINAL| must be defined as the name of "Final" function to generate. +// +// |HASH_BLOCK_DATA_ORDER| must be defined as the name of the "Block" function. +// That function must be implemented manually. It must be capable of operating +// on *unaligned* input data in its original (data) byte order. It must have +// this signature: +// +// void HASH_BLOCK_DATA_ORDER(uint32_t *state, const uint8_t *data, +// size_t num); +// +// It must update the hash state |state| with |num| blocks of data from |data|, +// where each block is |HASH_CBLOCK| bytes; i.e. |data| points to a array of +// |HASH_CBLOCK * num| bytes. |state| points to the |h| member of a |HASH_CTX|, +// and so will have | / sizeof(uint32_t)| elements. +// +// |HASH_MAKE_STRING(c, s)| must be defined as a block statement that converts +// the hash state |c->h| into the output byte order, storing the result in |s|. + +#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_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 + +#ifndef HASH_MAKE_STRING +#error "HASH_MAKE_STRING must be defined!" +#endif + +#if defined(DATA_ORDER_IS_BIG_ENDIAN) + +#define HOST_c2l(c, l) \ + do { \ + (l) = (((uint32_t)(*((c)++))) << 24); \ + (l) |= (((uint32_t)(*((c)++))) << 16); \ + (l) |= (((uint32_t)(*((c)++))) << 8); \ + (l) |= (((uint32_t)(*((c)++)))); \ + } while (0) + +#define HOST_l2c(l, c) \ + do { \ + *((c)++) = (uint8_t)(((l) >> 24) & 0xff); \ + *((c)++) = (uint8_t)(((l) >> 16) & 0xff); \ + *((c)++) = (uint8_t)(((l) >> 8) & 0xff); \ + *((c)++) = (uint8_t)(((l)) & 0xff); \ + } while (0) + +#elif defined(DATA_ORDER_IS_LITTLE_ENDIAN) + +#define HOST_c2l(c, l) \ + do { \ + (l) = (((uint32_t)(*((c)++)))); \ + (l) |= (((uint32_t)(*((c)++))) << 8); \ + (l) |= (((uint32_t)(*((c)++))) << 16); \ + (l) |= (((uint32_t)(*((c)++))) << 24); \ + } while (0) + +#define HOST_l2c(l, c) \ + do { \ + *((c)++) = (uint8_t)(((l)) & 0xff); \ + *((c)++) = (uint8_t)(((l) >> 8) & 0xff); \ + *((c)++) = (uint8_t)(((l) >> 16) & 0xff); \ + *((c)++) = (uint8_t)(((l) >> 24) & 0xff); \ + } while (0) + +#endif // DATA_ORDER + +int HASH_UPDATE(HASH_CTX *c, const void *data_, size_t len) { + const uint8_t *data = data_; + + if (len == 0) { + return 1; + } + + uint32_t l = c->Nl + (((uint32_t)len) << 3); + if (l < c->Nl) { + // Handle carries. + c->Nh++; + } + c->Nh += (uint32_t)(len >> 29); + c->Nl = l; + + size_t n = c->num; + if (n != 0) { + if (len >= HASH_CBLOCK || len + n >= HASH_CBLOCK) { + OPENSSL_memcpy(c->data + n, data, HASH_CBLOCK - n); + HASH_BLOCK_DATA_ORDER(c->h, c->data, 1); + n = HASH_CBLOCK - n; + data += n; + len -= n; + c->num = 0; + // Keep |c->data| zeroed when unused. + OPENSSL_memset(c->data, 0, HASH_CBLOCK); + } else { + OPENSSL_memcpy(c->data + n, data, len); + c->num += (unsigned)len; + return 1; + } + } + + n = len / HASH_CBLOCK; + if (n > 0) { + HASH_BLOCK_DATA_ORDER(c->h, data, n); + n *= HASH_CBLOCK; + data += n; + len -= n; + } + + if (len != 0) { + c->num = (unsigned)len; + OPENSSL_memcpy(c->data, data, len); + } + return 1; +} + + +void HASH_TRANSFORM(HASH_CTX *c, const uint8_t *data) { + HASH_BLOCK_DATA_ORDER(c->h, data, 1); +} + + +int HASH_FINAL(uint8_t *md, HASH_CTX *c) { + // |c->data| always has room for at least one byte. A full block would have + // been consumed. + size_t n = c->num; + assert(n < HASH_CBLOCK); + c->data[n] = 0x80; + n++; + + // Fill the block with zeros if there isn't room for a 64-bit length. + if (n > (HASH_CBLOCK - 8)) { + OPENSSL_memset(c->data + n, 0, HASH_CBLOCK - n); + n = 0; + HASH_BLOCK_DATA_ORDER(c->h, c->data, 1); + } + OPENSSL_memset(c->data + n, 0, HASH_CBLOCK - 8 - n); + + // Append a 64-bit length to the block and process it. + uint8_t *p = c->data + HASH_CBLOCK - 8; +#if defined(DATA_ORDER_IS_BIG_ENDIAN) + HOST_l2c(c->Nh, p); + HOST_l2c(c->Nl, p); +#elif defined(DATA_ORDER_IS_LITTLE_ENDIAN) + HOST_l2c(c->Nl, p); + HOST_l2c(c->Nh, p); +#endif + assert(p == c->data + HASH_CBLOCK); + HASH_BLOCK_DATA_ORDER(c->h, c->data, 1); + c->num = 0; + OPENSSL_memset(c->data, 0, HASH_CBLOCK); + + HASH_MAKE_STRING(c, md); + return 1; +} + + +#if defined(__cplusplus) +} // extern C +#endif diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/digest/md32_common.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/digest/md32_common.h.grpc_back new file mode 100644 index 0000000..a0c3665 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/digest/md32_common.h.grpc_back @@ -0,0 +1,268 @@ +/* ==================================================================== + * 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. + * ==================================================================== */ + +#include + +#include + +#include "../../internal.h" + +#if defined(__cplusplus) +extern "C" { +#endif + + +// This is a generic 32-bit "collector" for message digest algorithms. It +// collects input character stream into chunks of 32-bit values and invokes the +// block function that performs the actual hash calculations. To make use of +// this mechanism, the following macros must be defined before including +// md32_common.h. +// +// One of |DATA_ORDER_IS_BIG_ENDIAN| or |DATA_ORDER_IS_LITTLE_ENDIAN| must be +// defined to specify the byte order of the input stream. +// +// |HASH_CBLOCK| must be defined as the integer block size, in bytes. +// +// |HASH_CTX| must be defined as the name of the context structure, which must +// have at least the following members: +// +// typedef struct _state_st { +// uint32_t h[ / sizeof(uint32_t)]; +// uint32_t Nl, Nh; +// uint8_t data[HASH_CBLOCK]; +// unsigned num; +// ... +// } _CTX; +// +// is the output length of the hash in bytes, before +// any truncation (e.g. 64 for SHA-224 and SHA-256, 128 for SHA-384 and +// SHA-512). +// +// |HASH_UPDATE| must be defined as the name of the "Update" function to +// generate. +// +// |HASH_TRANSFORM| must be defined as the the name of the "Transform" +// function to generate. +// +// |HASH_FINAL| must be defined as the name of "Final" function to generate. +// +// |HASH_BLOCK_DATA_ORDER| must be defined as the name of the "Block" function. +// That function must be implemented manually. It must be capable of operating +// on *unaligned* input data in its original (data) byte order. It must have +// this signature: +// +// void HASH_BLOCK_DATA_ORDER(uint32_t *state, const uint8_t *data, +// size_t num); +// +// It must update the hash state |state| with |num| blocks of data from |data|, +// where each block is |HASH_CBLOCK| bytes; i.e. |data| points to a array of +// |HASH_CBLOCK * num| bytes. |state| points to the |h| member of a |HASH_CTX|, +// and so will have | / sizeof(uint32_t)| elements. +// +// |HASH_MAKE_STRING(c, s)| must be defined as a block statement that converts +// the hash state |c->h| into the output byte order, storing the result in |s|. + +#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_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 + +#ifndef HASH_MAKE_STRING +#error "HASH_MAKE_STRING must be defined!" +#endif + +#if defined(DATA_ORDER_IS_BIG_ENDIAN) + +#define HOST_c2l(c, l) \ + do { \ + (l) = (((uint32_t)(*((c)++))) << 24); \ + (l) |= (((uint32_t)(*((c)++))) << 16); \ + (l) |= (((uint32_t)(*((c)++))) << 8); \ + (l) |= (((uint32_t)(*((c)++)))); \ + } while (0) + +#define HOST_l2c(l, c) \ + do { \ + *((c)++) = (uint8_t)(((l) >> 24) & 0xff); \ + *((c)++) = (uint8_t)(((l) >> 16) & 0xff); \ + *((c)++) = (uint8_t)(((l) >> 8) & 0xff); \ + *((c)++) = (uint8_t)(((l)) & 0xff); \ + } while (0) + +#elif defined(DATA_ORDER_IS_LITTLE_ENDIAN) + +#define HOST_c2l(c, l) \ + do { \ + (l) = (((uint32_t)(*((c)++)))); \ + (l) |= (((uint32_t)(*((c)++))) << 8); \ + (l) |= (((uint32_t)(*((c)++))) << 16); \ + (l) |= (((uint32_t)(*((c)++))) << 24); \ + } while (0) + +#define HOST_l2c(l, c) \ + do { \ + *((c)++) = (uint8_t)(((l)) & 0xff); \ + *((c)++) = (uint8_t)(((l) >> 8) & 0xff); \ + *((c)++) = (uint8_t)(((l) >> 16) & 0xff); \ + *((c)++) = (uint8_t)(((l) >> 24) & 0xff); \ + } while (0) + +#endif // DATA_ORDER + +int HASH_UPDATE(HASH_CTX *c, const void *data_, size_t len) { + const uint8_t *data = data_; + + if (len == 0) { + return 1; + } + + uint32_t l = c->Nl + (((uint32_t)len) << 3); + if (l < c->Nl) { + // Handle carries. + c->Nh++; + } + c->Nh += (uint32_t)(len >> 29); + c->Nl = l; + + size_t n = c->num; + if (n != 0) { + if (len >= HASH_CBLOCK || len + n >= HASH_CBLOCK) { + OPENSSL_memcpy(c->data + n, data, HASH_CBLOCK - n); + HASH_BLOCK_DATA_ORDER(c->h, c->data, 1); + n = HASH_CBLOCK - n; + data += n; + len -= n; + c->num = 0; + // Keep |c->data| zeroed when unused. + OPENSSL_memset(c->data, 0, HASH_CBLOCK); + } else { + OPENSSL_memcpy(c->data + n, data, len); + c->num += (unsigned)len; + return 1; + } + } + + n = len / HASH_CBLOCK; + if (n > 0) { + HASH_BLOCK_DATA_ORDER(c->h, data, n); + n *= HASH_CBLOCK; + data += n; + len -= n; + } + + if (len != 0) { + c->num = (unsigned)len; + OPENSSL_memcpy(c->data, data, len); + } + return 1; +} + + +void HASH_TRANSFORM(HASH_CTX *c, const uint8_t *data) { + HASH_BLOCK_DATA_ORDER(c->h, data, 1); +} + + +int HASH_FINAL(uint8_t *md, HASH_CTX *c) { + // |c->data| always has room for at least one byte. A full block would have + // been consumed. + size_t n = c->num; + assert(n < HASH_CBLOCK); + c->data[n] = 0x80; + n++; + + // Fill the block with zeros if there isn't room for a 64-bit length. + if (n > (HASH_CBLOCK - 8)) { + OPENSSL_memset(c->data + n, 0, HASH_CBLOCK - n); + n = 0; + HASH_BLOCK_DATA_ORDER(c->h, c->data, 1); + } + OPENSSL_memset(c->data + n, 0, HASH_CBLOCK - 8 - n); + + // Append a 64-bit length to the block and process it. + uint8_t *p = c->data + HASH_CBLOCK - 8; +#if defined(DATA_ORDER_IS_BIG_ENDIAN) + HOST_l2c(c->Nh, p); + HOST_l2c(c->Nl, p); +#elif defined(DATA_ORDER_IS_LITTLE_ENDIAN) + HOST_l2c(c->Nl, p); + HOST_l2c(c->Nh, p); +#endif + assert(p == c->data + HASH_CBLOCK); + HASH_BLOCK_DATA_ORDER(c->h, c->data, 1); + c->num = 0; + OPENSSL_memset(c->data, 0, HASH_CBLOCK); + + HASH_MAKE_STRING(c, md); + return 1; +} + + +#if defined(__cplusplus) +} // extern C +#endif diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/ec/ec.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/ec/ec.c new file mode 100644 index 0000000..50b7dcf --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/ec/ec.c @@ -0,0 +1,974 @@ +/* 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. */ + +#include + +#include +#include + +#include +#include +#include +#include + +#include "internal.h" +#include "../../internal.h" +#include "../bn/internal.h" +#include "../delocate.h" + + +static void ec_point_free(EC_POINT *point, int free_group); + +static const uint8_t kP224Params[6 * 28] = { + // 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 uint8_t kP256Params[6 * 32] = { + // 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, +}; + +static const uint8_t kP384Params[6 * 48] = { + // 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 uint8_t kP521Params[6 * 66] = { + // 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, +}; + +DEFINE_METHOD_FUNCTION(struct built_in_curves, OPENSSL_built_in_curves) { + // 1.3.132.0.35 + static const uint8_t kOIDP521[] = {0x2b, 0x81, 0x04, 0x00, 0x23}; + out->curves[0].nid = NID_secp521r1; + out->curves[0].oid = kOIDP521; + out->curves[0].oid_len = sizeof(kOIDP521); + out->curves[0].comment = "NIST P-521"; + out->curves[0].param_len = 66; + out->curves[0].params = kP521Params; + out->curves[0].method = EC_GFp_mont_method(); + + // 1.3.132.0.34 + static const uint8_t kOIDP384[] = {0x2b, 0x81, 0x04, 0x00, 0x22}; + out->curves[1].nid = NID_secp384r1; + out->curves[1].oid = kOIDP384; + out->curves[1].oid_len = sizeof(kOIDP384); + out->curves[1].comment = "NIST P-384"; + out->curves[1].param_len = 48; + out->curves[1].params = kP384Params; + out->curves[1].method = EC_GFp_mont_method(); + + // 1.2.840.10045.3.1.7 + static const uint8_t kOIDP256[] = {0x2a, 0x86, 0x48, 0xce, + 0x3d, 0x03, 0x01, 0x07}; + out->curves[2].nid = NID_X9_62_prime256v1; + out->curves[2].oid = kOIDP256; + out->curves[2].oid_len = sizeof(kOIDP256); + out->curves[2].comment = "NIST P-256"; + out->curves[2].param_len = 32; + out->curves[2].params = kP256Params; + out->curves[2].method = +#if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64) && \ + !defined(OPENSSL_SMALL) + EC_GFp_nistz256_method(); +#else + EC_GFp_nistp256_method(); +#endif + + // 1.3.132.0.33 + static const uint8_t kOIDP224[] = {0x2b, 0x81, 0x04, 0x00, 0x21}; + out->curves[3].nid = NID_secp224r1; + out->curves[3].oid = kOIDP224; + out->curves[3].oid_len = sizeof(kOIDP224); + out->curves[3].comment = "NIST P-224"; + out->curves[3].param_len = 28; + out->curves[3].params = kP224Params; + out->curves[3].method = +#if defined(BORINGSSL_HAS_UINT128) && !defined(OPENSSL_SMALL) + EC_GFp_nistp224_method(); +#else + EC_GFp_mont_method(); +#endif +} + +EC_GROUP *ec_group_new(const EC_METHOD *meth) { + EC_GROUP *ret; + + if (meth == NULL) { + OPENSSL_PUT_ERROR(EC, EC_R_SLOT_FULL); + return NULL; + } + + if (meth->group_init == 0) { + OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return NULL; + } + + ret = OPENSSL_malloc(sizeof(EC_GROUP)); + if (ret == NULL) { + OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE); + return NULL; + } + OPENSSL_memset(ret, 0, sizeof(EC_GROUP)); + + ret->references = 1; + ret->meth = meth; + BN_init(&ret->order); + + if (!meth->group_init(ret)) { + OPENSSL_free(ret); + return NULL; + } + + return ret; +} + +static void ec_group_set0_generator(EC_GROUP *group, EC_POINT *generator) { + assert(group->generator == NULL); + assert(group == generator->group); + + // Avoid a reference cycle. |group->generator| does not maintain an owning + // pointer to |group|. + group->generator = generator; + int is_zero = CRYPTO_refcount_dec_and_test_zero(&group->references); + + assert(!is_zero); + (void)is_zero; +} + +EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a, + const BIGNUM *b, BN_CTX *ctx) { + if (BN_num_bytes(p) > EC_MAX_SCALAR_BYTES) { + OPENSSL_PUT_ERROR(EC, EC_R_INVALID_FIELD); + return NULL; + } + + EC_GROUP *ret = ec_group_new(EC_GFp_mont_method()); + if (ret == NULL) { + return NULL; + } + + if (ret->meth->group_set_curve == NULL) { + OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + EC_GROUP_free(ret); + return NULL; + } + if (!ret->meth->group_set_curve(ret, p, a, b, ctx)) { + EC_GROUP_free(ret); + return NULL; + } + return ret; +} + +int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator, + const BIGNUM *order, const BIGNUM *cofactor) { + if (group->curve_name != NID_undef || group->generator != NULL || + generator->group != group) { + // |EC_GROUP_set_generator| may only be used with |EC_GROUP|s returned by + // |EC_GROUP_new_curve_GFp| and may only used once on each group. + // Additionally, |generator| must been created from + // |EC_GROUP_new_curve_GFp|, not a copy, so that + // |generator->group->generator| is set correctly. + OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + + if (BN_num_bytes(order) > EC_MAX_SCALAR_BYTES) { + OPENSSL_PUT_ERROR(EC, EC_R_INVALID_FIELD); + return 0; + } + + // Require a cofactor of one for custom curves, which implies prime order. + if (!BN_is_one(cofactor)) { + OPENSSL_PUT_ERROR(EC, EC_R_INVALID_COFACTOR); + return 0; + } + + // Require that p < 2×order. This simplifies some ECDSA operations. + // + // Note any curve which did not satisfy this must have been invalid or use a + // tiny prime (less than 17). See the proof in |field_element_to_scalar| in + // the ECDSA implementation. + BIGNUM *tmp = BN_new(); + if (tmp == NULL || + !BN_lshift1(tmp, order)) { + BN_free(tmp); + return 0; + } + int ok = BN_cmp(tmp, &group->field) > 0; + BN_free(tmp); + if (!ok) { + OPENSSL_PUT_ERROR(EC, EC_R_INVALID_GROUP_ORDER); + return 0; + } + + EC_POINT *copy = EC_POINT_new(group); + if (copy == NULL || + !EC_POINT_copy(copy, generator) || + !BN_copy(&group->order, order)) { + EC_POINT_free(copy); + return 0; + } + // Store the order in minimal form, so it can be used with |BN_ULONG| arrays. + bn_set_minimal_width(&group->order); + + BN_MONT_CTX_free(group->order_mont); + group->order_mont = BN_MONT_CTX_new_for_modulus(&group->order, NULL); + if (group->order_mont == NULL) { + return 0; + } + + ec_group_set0_generator(group, copy); + return 1; +} + +static EC_GROUP *ec_group_new_from_data(const struct built_in_curve *curve) { + EC_GROUP *group = NULL; + EC_POINT *P = NULL; + BIGNUM *p = NULL, *a = NULL, *b = NULL, *x = NULL, *y = NULL; + int ok = 0; + + BN_CTX *ctx = BN_CTX_new(); + if (ctx == NULL) { + OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE); + goto err; + } + + const unsigned param_len = curve->param_len; + const uint8_t *params = curve->params; + + 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))) { + OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB); + goto err; + } + + group = ec_group_new(curve->method); + if (group == NULL || + !group->meth->group_set_curve(group, p, a, b, ctx)) { + OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB); + goto err; + } + + if ((P = EC_POINT_new(group)) == NULL) { + OPENSSL_PUT_ERROR(EC, 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))) { + OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB); + goto err; + } + + if (!EC_POINT_set_affine_coordinates_GFp(group, P, x, y, ctx)) { + OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB); + goto err; + } + if (!BN_bin2bn(params + 5 * param_len, param_len, &group->order)) { + OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB); + goto err; + } + + group->order_mont = BN_MONT_CTX_new_for_modulus(&group->order, ctx); + if (group->order_mont == NULL) { + OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB); + goto err; + } + + ec_group_set0_generator(group, P); + P = NULL; + ok = 1; + +err: + if (!ok) { + EC_GROUP_free(group); + group = NULL; + } + EC_POINT_free(P); + BN_CTX_free(ctx); + BN_free(p); + BN_free(a); + BN_free(b); + BN_free(x); + BN_free(y); + return group; +} + +// Built-in groups are allocated lazily and static once allocated. +// TODO(davidben): Make these actually static. https://crbug.com/boringssl/20. +struct built_in_groups_st { + EC_GROUP *groups[OPENSSL_NUM_BUILT_IN_CURVES]; +}; +DEFINE_BSS_GET(struct built_in_groups_st, built_in_groups); +DEFINE_STATIC_MUTEX(built_in_groups_lock); + +EC_GROUP *EC_GROUP_new_by_curve_name(int nid) { + struct built_in_groups_st *groups = built_in_groups_bss_get(); + EC_GROUP **group_ptr = NULL; + const struct built_in_curves *const curves = OPENSSL_built_in_curves(); + const struct built_in_curve *curve = NULL; + for (size_t i = 0; i < OPENSSL_NUM_BUILT_IN_CURVES; i++) { + if (curves->curves[i].nid == nid) { + curve = &curves->curves[i]; + group_ptr = &groups->groups[i]; + break; + } + } + + if (curve == NULL) { + OPENSSL_PUT_ERROR(EC, EC_R_UNKNOWN_GROUP); + return NULL; + } + + CRYPTO_STATIC_MUTEX_lock_read(built_in_groups_lock_bss_get()); + EC_GROUP *ret = *group_ptr; + CRYPTO_STATIC_MUTEX_unlock_read(built_in_groups_lock_bss_get()); + if (ret != NULL) { + return ret; + } + + ret = ec_group_new_from_data(curve); + if (ret == NULL) { + return NULL; + } + + EC_GROUP *to_free = NULL; + CRYPTO_STATIC_MUTEX_lock_write(built_in_groups_lock_bss_get()); + if (*group_ptr == NULL) { + *group_ptr = ret; + // Filling in |ret->curve_name| makes |EC_GROUP_free| and |EC_GROUP_dup| + // into no-ops. At this point, |ret| is considered static. + ret->curve_name = nid; + } else { + to_free = ret; + ret = *group_ptr; + } + CRYPTO_STATIC_MUTEX_unlock_write(built_in_groups_lock_bss_get()); + + EC_GROUP_free(to_free); + return ret; +} + +void EC_GROUP_free(EC_GROUP *group) { + if (group == NULL || + // Built-in curves are static. + group->curve_name != NID_undef || + !CRYPTO_refcount_dec_and_test_zero(&group->references)) { + return; + } + + if (group->meth->group_finish != NULL) { + group->meth->group_finish(group); + } + + ec_point_free(group->generator, 0 /* don't free group */); + BN_free(&group->order); + BN_MONT_CTX_free(group->order_mont); + + OPENSSL_free(group); +} + +EC_GROUP *EC_GROUP_dup(const EC_GROUP *a) { + if (a == NULL || + // Built-in curves are static. + a->curve_name != NID_undef) { + return (EC_GROUP *)a; + } + + // Groups are logically immutable (but for |EC_GROUP_set_generator| which must + // be called early on), so we simply take a reference. + EC_GROUP *group = (EC_GROUP *)a; + CRYPTO_refcount_inc(&group->references); + return group; +} + +int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ignored) { + // Note this function returns 0 if equal and non-zero otherwise. + if (a == b) { + return 0; + } + if (a->curve_name != b->curve_name) { + return 1; + } + if (a->curve_name != NID_undef) { + // Built-in curves may be compared by curve name alone. + return 0; + } + + // |a| and |b| are both custom curves. We compare the entire curve + // structure. If |a| or |b| is incomplete (due to legacy OpenSSL mistakes, + // custom curve construction is sadly done in two parts) but otherwise not the + // same object, we consider them always unequal. + return a->generator == NULL || + b->generator == NULL || + BN_cmp(&a->order, &b->order) != 0 || + BN_cmp(&a->field, &b->field) != 0 || + BN_cmp(&a->a, &b->a) != 0 || + BN_cmp(&a->b, &b->b) != 0 || + ec_GFp_simple_cmp(a, a->generator, b->generator, NULL) != 0; +} + +const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group) { + return group->generator; +} + +const BIGNUM *EC_GROUP_get0_order(const EC_GROUP *group) { + assert(!BN_is_zero(&group->order)); + return &group->order; +} + +int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx) { + if (BN_copy(order, EC_GROUP_get0_order(group)) == NULL) { + return 0; + } + return 1; +} + +int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor, + BN_CTX *ctx) { + // All |EC_GROUP|s have cofactor 1. + return BN_set_word(cofactor, 1); +} + +int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *out_p, BIGNUM *out_a, + BIGNUM *out_b, BN_CTX *ctx) { + return ec_GFp_simple_group_get_curve(group, out_p, out_a, out_b, ctx); +} + +int EC_GROUP_get_curve_name(const EC_GROUP *group) { return group->curve_name; } + +unsigned EC_GROUP_get_degree(const EC_GROUP *group) { + return ec_GFp_simple_group_get_degree(group); +} + +EC_POINT *EC_POINT_new(const EC_GROUP *group) { + EC_POINT *ret; + + if (group == NULL) { + OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER); + return NULL; + } + + ret = OPENSSL_malloc(sizeof *ret); + if (ret == NULL) { + OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE); + return NULL; + } + + ret->group = EC_GROUP_dup(group); + if (ret->group == NULL || + !ec_GFp_simple_point_init(ret)) { + OPENSSL_free(ret); + return NULL; + } + + return ret; +} + +static void ec_point_free(EC_POINT *point, int free_group) { + if (!point) { + return; + } + ec_GFp_simple_point_finish(point); + if (free_group) { + EC_GROUP_free(point->group); + } + OPENSSL_free(point); +} + +void EC_POINT_free(EC_POINT *point) { + ec_point_free(point, 1 /* free group */); +} + +void EC_POINT_clear_free(EC_POINT *point) { EC_POINT_free(point); } + +int EC_POINT_copy(EC_POINT *dest, const EC_POINT *src) { + if (EC_GROUP_cmp(dest->group, src->group, NULL) != 0) { + OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + if (dest == src) { + return 1; + } + return ec_GFp_simple_point_copy(dest, src); +} + +EC_POINT *EC_POINT_dup(const EC_POINT *a, const EC_GROUP *group) { + if (a == NULL) { + return NULL; + } + + EC_POINT *ret = EC_POINT_new(group); + if (ret == NULL || + !EC_POINT_copy(ret, a)) { + EC_POINT_free(ret); + return NULL; + } + + return ret; +} + +int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point) { + if (EC_GROUP_cmp(group, point->group, NULL) != 0) { + OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + return ec_GFp_simple_point_set_to_infinity(group, point); +} + +int EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *point) { + if (EC_GROUP_cmp(group, point->group, NULL) != 0) { + OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + return ec_GFp_simple_is_at_infinity(group, point); +} + +int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point, + BN_CTX *ctx) { + if (EC_GROUP_cmp(group, point->group, NULL) != 0) { + OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + return ec_GFp_simple_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 (EC_GROUP_cmp(group, a->group, NULL) != 0 || + EC_GROUP_cmp(group, b->group, NULL) != 0) { + OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); + return -1; + } + return ec_GFp_simple_cmp(group, a, b, ctx); +} + +int EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx) { + if (EC_GROUP_cmp(group, point->group, NULL) != 0) { + OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + return ec_GFp_simple_make_affine(group, point, ctx); +} + +int EC_POINTs_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[], + BN_CTX *ctx) { + for (size_t i = 0; i < num; i++) { + if (EC_GROUP_cmp(group, points[i]->group, NULL) != 0) { + OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + } + return ec_GFp_simple_points_make_affine(group, num, points, ctx); +} + +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) { + OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + if (EC_GROUP_cmp(group, point->group, NULL) != 0) { + OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + return group->meth->point_get_affine_coordinates(group, point, x, y, 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 (EC_GROUP_cmp(group, point->group, NULL) != 0) { + OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + if (!ec_GFp_simple_point_set_affine_coordinates(group, point, x, y, ctx)) { + return 0; + } + + if (!EC_POINT_is_on_curve(group, point, ctx)) { + // In the event of an error, defend against the caller not checking the + // return value by setting a known safe value: the base point. + const EC_POINT *generator = EC_GROUP_get0_generator(group); + // The generator can be missing if the caller is in the process of + // constructing an arbitrary group. In this, we give up and hope they're + // checking the return value. + if (generator) { + EC_POINT_copy(point, generator); + } + OPENSSL_PUT_ERROR(EC, EC_R_POINT_IS_NOT_ON_CURVE); + return 0; + } + + return 1; +} + +int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, + const EC_POINT *b, BN_CTX *ctx) { + if (EC_GROUP_cmp(group, r->group, NULL) != 0 || + EC_GROUP_cmp(group, a->group, NULL) != 0 || + EC_GROUP_cmp(group, b->group, NULL) != 0) { + OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + return ec_GFp_simple_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 (EC_GROUP_cmp(group, r->group, NULL) != 0 || + EC_GROUP_cmp(group, a->group, NULL) != 0) { + OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + return ec_GFp_simple_dbl(group, r, a, ctx); +} + + +int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx) { + if (EC_GROUP_cmp(group, a->group, NULL) != 0) { + OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + return ec_GFp_simple_invert(group, a, ctx); +} + +static int arbitrary_bignum_to_scalar(const EC_GROUP *group, EC_SCALAR *out, + const BIGNUM *in, BN_CTX *ctx) { + if (ec_bignum_to_scalar(group, out, in)) { + return 1; + } + + ERR_clear_error(); + + // This is an unusual input, so we do not guarantee constant-time processing. + const BIGNUM *order = &group->order; + BN_CTX_start(ctx); + BIGNUM *tmp = BN_CTX_get(ctx); + int ok = tmp != NULL && + BN_nnmod(tmp, in, order, ctx) && + ec_bignum_to_scalar_unchecked(group, out, tmp); + BN_CTX_end(ctx); + return ok; +} + +int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar, + const EC_POINT *p, const BIGNUM *p_scalar, BN_CTX *ctx) { + // Previously, this function set |r| to the point at infinity if there was + // nothing to multiply. But, nobody should be calling this function with + // nothing to multiply in the first place. + if ((g_scalar == NULL && p_scalar == NULL) || + (p == NULL) != (p_scalar == NULL)) { + OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + int ret = 0; + EC_SCALAR g_scalar_storage, p_scalar_storage; + EC_SCALAR *g_scalar_arg = NULL, *p_scalar_arg = NULL; + BN_CTX *new_ctx = NULL; + if (ctx == NULL) { + new_ctx = BN_CTX_new(); + if (new_ctx == NULL) { + goto err; + } + ctx = new_ctx; + } + + if (g_scalar != NULL) { + if (!arbitrary_bignum_to_scalar(group, &g_scalar_storage, g_scalar, ctx)) { + goto err; + } + g_scalar_arg = &g_scalar_storage; + } + + if (p_scalar != NULL) { + if (!arbitrary_bignum_to_scalar(group, &p_scalar_storage, p_scalar, ctx)) { + goto err; + } + p_scalar_arg = &p_scalar_storage; + } + + ret = ec_point_mul_scalar(group, r, g_scalar_arg, p, p_scalar_arg, ctx); + +err: + BN_CTX_free(new_ctx); + OPENSSL_cleanse(&g_scalar_storage, sizeof(g_scalar_storage)); + OPENSSL_cleanse(&p_scalar_storage, sizeof(p_scalar_storage)); + return ret; +} + +int ec_point_mul_scalar_public(const EC_GROUP *group, EC_POINT *r, + const EC_SCALAR *g_scalar, const EC_POINT *p, + const EC_SCALAR *p_scalar, BN_CTX *ctx) { + if ((g_scalar == NULL && p_scalar == NULL) || + (p == NULL) != (p_scalar == NULL)) { + OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + if (EC_GROUP_cmp(group, r->group, NULL) != 0 || + (p != NULL && EC_GROUP_cmp(group, p->group, NULL) != 0)) { + OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + + return group->meth->mul_public(group, r, g_scalar, p, p_scalar, ctx); +} + +int ec_point_mul_scalar(const EC_GROUP *group, EC_POINT *r, + const EC_SCALAR *g_scalar, const EC_POINT *p, + const EC_SCALAR *p_scalar, BN_CTX *ctx) { + if ((g_scalar == NULL && p_scalar == NULL) || + (p == NULL) != (p_scalar == NULL)) { + OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + if (EC_GROUP_cmp(group, r->group, NULL) != 0 || + (p != NULL && EC_GROUP_cmp(group, p->group, NULL) != 0)) { + OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + + return group->meth->mul(group, r, g_scalar, p, p_scalar, ctx); +} + +void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag) {} + +const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *group) { + return NULL; +} + +int EC_METHOD_get_field_type(const EC_METHOD *meth) { + return NID_X9_62_prime_field; +} + +void EC_GROUP_set_point_conversion_form(EC_GROUP *group, + point_conversion_form_t form) { + if (form != POINT_CONVERSION_UNCOMPRESSED) { + abort(); + } +} + +size_t EC_get_builtin_curves(EC_builtin_curve *out_curves, + size_t max_num_curves) { + const struct built_in_curves *const curves = OPENSSL_built_in_curves(); + + for (size_t i = 0; i < max_num_curves && i < OPENSSL_NUM_BUILT_IN_CURVES; + i++) { + out_curves[i].comment = curves->curves[i].comment; + out_curves[i].nid = curves->curves[i].nid; + } + + return OPENSSL_NUM_BUILT_IN_CURVES; +} + +int ec_bignum_to_scalar(const EC_GROUP *group, EC_SCALAR *out, + const BIGNUM *in) { + if (!ec_bignum_to_scalar_unchecked(group, out, in)) { + return 0; + } + if (!bn_less_than_words(out->words, group->order.d, group->order.width)) { + OPENSSL_PUT_ERROR(EC, EC_R_INVALID_SCALAR); + return 0; + } + return 1; +} + +int ec_bignum_to_scalar_unchecked(const EC_GROUP *group, EC_SCALAR *out, + const BIGNUM *in) { + if (!bn_copy_words(out->words, group->order.width, in)) { + OPENSSL_PUT_ERROR(EC, EC_R_INVALID_SCALAR); + return 0; + } + return 1; +} + +int ec_random_nonzero_scalar(const EC_GROUP *group, EC_SCALAR *out, + const uint8_t additional_data[32]) { + return bn_rand_range_words(out->words, 1, group->order.d, group->order.width, + additional_data); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/ec/ec.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/ec/ec.c.grpc_back new file mode 100644 index 0000000..904466a --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/ec/ec.c.grpc_back @@ -0,0 +1,974 @@ +/* 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. */ + +#include + +#include +#include + +#include +#include +#include +#include + +#include "internal.h" +#include "../../internal.h" +#include "../bn/internal.h" +#include "../delocate.h" + + +static void ec_point_free(EC_POINT *point, int free_group); + +static const uint8_t kP224Params[6 * 28] = { + // 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 uint8_t kP256Params[6 * 32] = { + // 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, +}; + +static const uint8_t kP384Params[6 * 48] = { + // 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 uint8_t kP521Params[6 * 66] = { + // 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, +}; + +DEFINE_METHOD_FUNCTION(struct built_in_curves, OPENSSL_built_in_curves) { + // 1.3.132.0.35 + static const uint8_t kOIDP521[] = {0x2b, 0x81, 0x04, 0x00, 0x23}; + out->curves[0].nid = NID_secp521r1; + out->curves[0].oid = kOIDP521; + out->curves[0].oid_len = sizeof(kOIDP521); + out->curves[0].comment = "NIST P-521"; + out->curves[0].param_len = 66; + out->curves[0].params = kP521Params; + out->curves[0].method = EC_GFp_mont_method(); + + // 1.3.132.0.34 + static const uint8_t kOIDP384[] = {0x2b, 0x81, 0x04, 0x00, 0x22}; + out->curves[1].nid = NID_secp384r1; + out->curves[1].oid = kOIDP384; + out->curves[1].oid_len = sizeof(kOIDP384); + out->curves[1].comment = "NIST P-384"; + out->curves[1].param_len = 48; + out->curves[1].params = kP384Params; + out->curves[1].method = EC_GFp_mont_method(); + + // 1.2.840.10045.3.1.7 + static const uint8_t kOIDP256[] = {0x2a, 0x86, 0x48, 0xce, + 0x3d, 0x03, 0x01, 0x07}; + out->curves[2].nid = NID_X9_62_prime256v1; + out->curves[2].oid = kOIDP256; + out->curves[2].oid_len = sizeof(kOIDP256); + out->curves[2].comment = "NIST P-256"; + out->curves[2].param_len = 32; + out->curves[2].params = kP256Params; + out->curves[2].method = +#if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64) && \ + !defined(OPENSSL_SMALL) + EC_GFp_nistz256_method(); +#else + EC_GFp_nistp256_method(); +#endif + + // 1.3.132.0.33 + static const uint8_t kOIDP224[] = {0x2b, 0x81, 0x04, 0x00, 0x21}; + out->curves[3].nid = NID_secp224r1; + out->curves[3].oid = kOIDP224; + out->curves[3].oid_len = sizeof(kOIDP224); + out->curves[3].comment = "NIST P-224"; + out->curves[3].param_len = 28; + out->curves[3].params = kP224Params; + out->curves[3].method = +#if defined(BORINGSSL_HAS_UINT128) && !defined(OPENSSL_SMALL) + EC_GFp_nistp224_method(); +#else + EC_GFp_mont_method(); +#endif +} + +EC_GROUP *ec_group_new(const EC_METHOD *meth) { + EC_GROUP *ret; + + if (meth == NULL) { + OPENSSL_PUT_ERROR(EC, EC_R_SLOT_FULL); + return NULL; + } + + if (meth->group_init == 0) { + OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return NULL; + } + + ret = OPENSSL_malloc(sizeof(EC_GROUP)); + if (ret == NULL) { + OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE); + return NULL; + } + OPENSSL_memset(ret, 0, sizeof(EC_GROUP)); + + ret->references = 1; + ret->meth = meth; + BN_init(&ret->order); + + if (!meth->group_init(ret)) { + OPENSSL_free(ret); + return NULL; + } + + return ret; +} + +static void ec_group_set0_generator(EC_GROUP *group, EC_POINT *generator) { + assert(group->generator == NULL); + assert(group == generator->group); + + // Avoid a reference cycle. |group->generator| does not maintain an owning + // pointer to |group|. + group->generator = generator; + int is_zero = CRYPTO_refcount_dec_and_test_zero(&group->references); + + assert(!is_zero); + (void)is_zero; +} + +EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, const BIGNUM *a, + const BIGNUM *b, BN_CTX *ctx) { + if (BN_num_bytes(p) > EC_MAX_SCALAR_BYTES) { + OPENSSL_PUT_ERROR(EC, EC_R_INVALID_FIELD); + return NULL; + } + + EC_GROUP *ret = ec_group_new(EC_GFp_mont_method()); + if (ret == NULL) { + return NULL; + } + + if (ret->meth->group_set_curve == NULL) { + OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + EC_GROUP_free(ret); + return NULL; + } + if (!ret->meth->group_set_curve(ret, p, a, b, ctx)) { + EC_GROUP_free(ret); + return NULL; + } + return ret; +} + +int EC_GROUP_set_generator(EC_GROUP *group, const EC_POINT *generator, + const BIGNUM *order, const BIGNUM *cofactor) { + if (group->curve_name != NID_undef || group->generator != NULL || + generator->group != group) { + // |EC_GROUP_set_generator| may only be used with |EC_GROUP|s returned by + // |EC_GROUP_new_curve_GFp| and may only used once on each group. + // Additionally, |generator| must been created from + // |EC_GROUP_new_curve_GFp|, not a copy, so that + // |generator->group->generator| is set correctly. + OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + + if (BN_num_bytes(order) > EC_MAX_SCALAR_BYTES) { + OPENSSL_PUT_ERROR(EC, EC_R_INVALID_FIELD); + return 0; + } + + // Require a cofactor of one for custom curves, which implies prime order. + if (!BN_is_one(cofactor)) { + OPENSSL_PUT_ERROR(EC, EC_R_INVALID_COFACTOR); + return 0; + } + + // Require that p < 2×order. This simplifies some ECDSA operations. + // + // Note any curve which did not satisfy this must have been invalid or use a + // tiny prime (less than 17). See the proof in |field_element_to_scalar| in + // the ECDSA implementation. + BIGNUM *tmp = BN_new(); + if (tmp == NULL || + !BN_lshift1(tmp, order)) { + BN_free(tmp); + return 0; + } + int ok = BN_cmp(tmp, &group->field) > 0; + BN_free(tmp); + if (!ok) { + OPENSSL_PUT_ERROR(EC, EC_R_INVALID_GROUP_ORDER); + return 0; + } + + EC_POINT *copy = EC_POINT_new(group); + if (copy == NULL || + !EC_POINT_copy(copy, generator) || + !BN_copy(&group->order, order)) { + EC_POINT_free(copy); + return 0; + } + // Store the order in minimal form, so it can be used with |BN_ULONG| arrays. + bn_set_minimal_width(&group->order); + + BN_MONT_CTX_free(group->order_mont); + group->order_mont = BN_MONT_CTX_new_for_modulus(&group->order, NULL); + if (group->order_mont == NULL) { + return 0; + } + + ec_group_set0_generator(group, copy); + return 1; +} + +static EC_GROUP *ec_group_new_from_data(const struct built_in_curve *curve) { + EC_GROUP *group = NULL; + EC_POINT *P = NULL; + BIGNUM *p = NULL, *a = NULL, *b = NULL, *x = NULL, *y = NULL; + int ok = 0; + + BN_CTX *ctx = BN_CTX_new(); + if (ctx == NULL) { + OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE); + goto err; + } + + const unsigned param_len = curve->param_len; + const uint8_t *params = curve->params; + + 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))) { + OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB); + goto err; + } + + group = ec_group_new(curve->method); + if (group == NULL || + !group->meth->group_set_curve(group, p, a, b, ctx)) { + OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB); + goto err; + } + + if ((P = EC_POINT_new(group)) == NULL) { + OPENSSL_PUT_ERROR(EC, 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))) { + OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB); + goto err; + } + + if (!EC_POINT_set_affine_coordinates_GFp(group, P, x, y, ctx)) { + OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB); + goto err; + } + if (!BN_bin2bn(params + 5 * param_len, param_len, &group->order)) { + OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB); + goto err; + } + + group->order_mont = BN_MONT_CTX_new_for_modulus(&group->order, ctx); + if (group->order_mont == NULL) { + OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB); + goto err; + } + + ec_group_set0_generator(group, P); + P = NULL; + ok = 1; + +err: + if (!ok) { + EC_GROUP_free(group); + group = NULL; + } + EC_POINT_free(P); + BN_CTX_free(ctx); + BN_free(p); + BN_free(a); + BN_free(b); + BN_free(x); + BN_free(y); + return group; +} + +// Built-in groups are allocated lazily and static once allocated. +// TODO(davidben): Make these actually static. https://crbug.com/boringssl/20. +struct built_in_groups_st { + EC_GROUP *groups[OPENSSL_NUM_BUILT_IN_CURVES]; +}; +DEFINE_BSS_GET(struct built_in_groups_st, built_in_groups); +DEFINE_STATIC_MUTEX(built_in_groups_lock); + +EC_GROUP *EC_GROUP_new_by_curve_name(int nid) { + struct built_in_groups_st *groups = built_in_groups_bss_get(); + EC_GROUP **group_ptr = NULL; + const struct built_in_curves *const curves = OPENSSL_built_in_curves(); + const struct built_in_curve *curve = NULL; + for (size_t i = 0; i < OPENSSL_NUM_BUILT_IN_CURVES; i++) { + if (curves->curves[i].nid == nid) { + curve = &curves->curves[i]; + group_ptr = &groups->groups[i]; + break; + } + } + + if (curve == NULL) { + OPENSSL_PUT_ERROR(EC, EC_R_UNKNOWN_GROUP); + return NULL; + } + + CRYPTO_STATIC_MUTEX_lock_read(built_in_groups_lock_bss_get()); + EC_GROUP *ret = *group_ptr; + CRYPTO_STATIC_MUTEX_unlock_read(built_in_groups_lock_bss_get()); + if (ret != NULL) { + return ret; + } + + ret = ec_group_new_from_data(curve); + if (ret == NULL) { + return NULL; + } + + EC_GROUP *to_free = NULL; + CRYPTO_STATIC_MUTEX_lock_write(built_in_groups_lock_bss_get()); + if (*group_ptr == NULL) { + *group_ptr = ret; + // Filling in |ret->curve_name| makes |EC_GROUP_free| and |EC_GROUP_dup| + // into no-ops. At this point, |ret| is considered static. + ret->curve_name = nid; + } else { + to_free = ret; + ret = *group_ptr; + } + CRYPTO_STATIC_MUTEX_unlock_write(built_in_groups_lock_bss_get()); + + EC_GROUP_free(to_free); + return ret; +} + +void EC_GROUP_free(EC_GROUP *group) { + if (group == NULL || + // Built-in curves are static. + group->curve_name != NID_undef || + !CRYPTO_refcount_dec_and_test_zero(&group->references)) { + return; + } + + if (group->meth->group_finish != NULL) { + group->meth->group_finish(group); + } + + ec_point_free(group->generator, 0 /* don't free group */); + BN_free(&group->order); + BN_MONT_CTX_free(group->order_mont); + + OPENSSL_free(group); +} + +EC_GROUP *EC_GROUP_dup(const EC_GROUP *a) { + if (a == NULL || + // Built-in curves are static. + a->curve_name != NID_undef) { + return (EC_GROUP *)a; + } + + // Groups are logically immutable (but for |EC_GROUP_set_generator| which must + // be called early on), so we simply take a reference. + EC_GROUP *group = (EC_GROUP *)a; + CRYPTO_refcount_inc(&group->references); + return group; +} + +int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, BN_CTX *ignored) { + // Note this function returns 0 if equal and non-zero otherwise. + if (a == b) { + return 0; + } + if (a->curve_name != b->curve_name) { + return 1; + } + if (a->curve_name != NID_undef) { + // Built-in curves may be compared by curve name alone. + return 0; + } + + // |a| and |b| are both custom curves. We compare the entire curve + // structure. If |a| or |b| is incomplete (due to legacy OpenSSL mistakes, + // custom curve construction is sadly done in two parts) but otherwise not the + // same object, we consider them always unequal. + return a->generator == NULL || + b->generator == NULL || + BN_cmp(&a->order, &b->order) != 0 || + BN_cmp(&a->field, &b->field) != 0 || + BN_cmp(&a->a, &b->a) != 0 || + BN_cmp(&a->b, &b->b) != 0 || + ec_GFp_simple_cmp(a, a->generator, b->generator, NULL) != 0; +} + +const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group) { + return group->generator; +} + +const BIGNUM *EC_GROUP_get0_order(const EC_GROUP *group) { + assert(!BN_is_zero(&group->order)); + return &group->order; +} + +int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, BN_CTX *ctx) { + if (BN_copy(order, EC_GROUP_get0_order(group)) == NULL) { + return 0; + } + return 1; +} + +int EC_GROUP_get_cofactor(const EC_GROUP *group, BIGNUM *cofactor, + BN_CTX *ctx) { + // All |EC_GROUP|s have cofactor 1. + return BN_set_word(cofactor, 1); +} + +int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *out_p, BIGNUM *out_a, + BIGNUM *out_b, BN_CTX *ctx) { + return ec_GFp_simple_group_get_curve(group, out_p, out_a, out_b, ctx); +} + +int EC_GROUP_get_curve_name(const EC_GROUP *group) { return group->curve_name; } + +unsigned EC_GROUP_get_degree(const EC_GROUP *group) { + return ec_GFp_simple_group_get_degree(group); +} + +EC_POINT *EC_POINT_new(const EC_GROUP *group) { + EC_POINT *ret; + + if (group == NULL) { + OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER); + return NULL; + } + + ret = OPENSSL_malloc(sizeof *ret); + if (ret == NULL) { + OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE); + return NULL; + } + + ret->group = EC_GROUP_dup(group); + if (ret->group == NULL || + !ec_GFp_simple_point_init(ret)) { + OPENSSL_free(ret); + return NULL; + } + + return ret; +} + +static void ec_point_free(EC_POINT *point, int free_group) { + if (!point) { + return; + } + ec_GFp_simple_point_finish(point); + if (free_group) { + EC_GROUP_free(point->group); + } + OPENSSL_free(point); +} + +void EC_POINT_free(EC_POINT *point) { + ec_point_free(point, 1 /* free group */); +} + +void EC_POINT_clear_free(EC_POINT *point) { EC_POINT_free(point); } + +int EC_POINT_copy(EC_POINT *dest, const EC_POINT *src) { + if (EC_GROUP_cmp(dest->group, src->group, NULL) != 0) { + OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + if (dest == src) { + return 1; + } + return ec_GFp_simple_point_copy(dest, src); +} + +EC_POINT *EC_POINT_dup(const EC_POINT *a, const EC_GROUP *group) { + if (a == NULL) { + return NULL; + } + + EC_POINT *ret = EC_POINT_new(group); + if (ret == NULL || + !EC_POINT_copy(ret, a)) { + EC_POINT_free(ret); + return NULL; + } + + return ret; +} + +int EC_POINT_set_to_infinity(const EC_GROUP *group, EC_POINT *point) { + if (EC_GROUP_cmp(group, point->group, NULL) != 0) { + OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + return ec_GFp_simple_point_set_to_infinity(group, point); +} + +int EC_POINT_is_at_infinity(const EC_GROUP *group, const EC_POINT *point) { + if (EC_GROUP_cmp(group, point->group, NULL) != 0) { + OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + return ec_GFp_simple_is_at_infinity(group, point); +} + +int EC_POINT_is_on_curve(const EC_GROUP *group, const EC_POINT *point, + BN_CTX *ctx) { + if (EC_GROUP_cmp(group, point->group, NULL) != 0) { + OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + return ec_GFp_simple_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 (EC_GROUP_cmp(group, a->group, NULL) != 0 || + EC_GROUP_cmp(group, b->group, NULL) != 0) { + OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); + return -1; + } + return ec_GFp_simple_cmp(group, a, b, ctx); +} + +int EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, BN_CTX *ctx) { + if (EC_GROUP_cmp(group, point->group, NULL) != 0) { + OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + return ec_GFp_simple_make_affine(group, point, ctx); +} + +int EC_POINTs_make_affine(const EC_GROUP *group, size_t num, EC_POINT *points[], + BN_CTX *ctx) { + for (size_t i = 0; i < num; i++) { + if (EC_GROUP_cmp(group, points[i]->group, NULL) != 0) { + OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + } + return ec_GFp_simple_points_make_affine(group, num, points, ctx); +} + +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) { + OPENSSL_PUT_ERROR(EC, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; + } + if (EC_GROUP_cmp(group, point->group, NULL) != 0) { + OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + return group->meth->point_get_affine_coordinates(group, point, x, y, 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 (EC_GROUP_cmp(group, point->group, NULL) != 0) { + OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + if (!ec_GFp_simple_point_set_affine_coordinates(group, point, x, y, ctx)) { + return 0; + } + + if (!EC_POINT_is_on_curve(group, point, ctx)) { + // In the event of an error, defend against the caller not checking the + // return value by setting a known safe value: the base point. + const EC_POINT *generator = EC_GROUP_get0_generator(group); + // The generator can be missing if the caller is in the process of + // constructing an arbitrary group. In this, we give up and hope they're + // checking the return value. + if (generator) { + EC_POINT_copy(point, generator); + } + OPENSSL_PUT_ERROR(EC, EC_R_POINT_IS_NOT_ON_CURVE); + return 0; + } + + return 1; +} + +int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, const EC_POINT *a, + const EC_POINT *b, BN_CTX *ctx) { + if (EC_GROUP_cmp(group, r->group, NULL) != 0 || + EC_GROUP_cmp(group, a->group, NULL) != 0 || + EC_GROUP_cmp(group, b->group, NULL) != 0) { + OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + return ec_GFp_simple_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 (EC_GROUP_cmp(group, r->group, NULL) != 0 || + EC_GROUP_cmp(group, a->group, NULL) != 0) { + OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + return ec_GFp_simple_dbl(group, r, a, ctx); +} + + +int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, BN_CTX *ctx) { + if (EC_GROUP_cmp(group, a->group, NULL) != 0) { + OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + return ec_GFp_simple_invert(group, a, ctx); +} + +static int arbitrary_bignum_to_scalar(const EC_GROUP *group, EC_SCALAR *out, + const BIGNUM *in, BN_CTX *ctx) { + if (ec_bignum_to_scalar(group, out, in)) { + return 1; + } + + ERR_clear_error(); + + // This is an unusual input, so we do not guarantee constant-time processing. + const BIGNUM *order = &group->order; + BN_CTX_start(ctx); + BIGNUM *tmp = BN_CTX_get(ctx); + int ok = tmp != NULL && + BN_nnmod(tmp, in, order, ctx) && + ec_bignum_to_scalar_unchecked(group, out, tmp); + BN_CTX_end(ctx); + return ok; +} + +int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, const BIGNUM *g_scalar, + const EC_POINT *p, const BIGNUM *p_scalar, BN_CTX *ctx) { + // Previously, this function set |r| to the point at infinity if there was + // nothing to multiply. But, nobody should be calling this function with + // nothing to multiply in the first place. + if ((g_scalar == NULL && p_scalar == NULL) || + (p == NULL) != (p_scalar == NULL)) { + OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + int ret = 0; + EC_SCALAR g_scalar_storage, p_scalar_storage; + EC_SCALAR *g_scalar_arg = NULL, *p_scalar_arg = NULL; + BN_CTX *new_ctx = NULL; + if (ctx == NULL) { + new_ctx = BN_CTX_new(); + if (new_ctx == NULL) { + goto err; + } + ctx = new_ctx; + } + + if (g_scalar != NULL) { + if (!arbitrary_bignum_to_scalar(group, &g_scalar_storage, g_scalar, ctx)) { + goto err; + } + g_scalar_arg = &g_scalar_storage; + } + + if (p_scalar != NULL) { + if (!arbitrary_bignum_to_scalar(group, &p_scalar_storage, p_scalar, ctx)) { + goto err; + } + p_scalar_arg = &p_scalar_storage; + } + + ret = ec_point_mul_scalar(group, r, g_scalar_arg, p, p_scalar_arg, ctx); + +err: + BN_CTX_free(new_ctx); + OPENSSL_cleanse(&g_scalar_storage, sizeof(g_scalar_storage)); + OPENSSL_cleanse(&p_scalar_storage, sizeof(p_scalar_storage)); + return ret; +} + +int ec_point_mul_scalar_public(const EC_GROUP *group, EC_POINT *r, + const EC_SCALAR *g_scalar, const EC_POINT *p, + const EC_SCALAR *p_scalar, BN_CTX *ctx) { + if ((g_scalar == NULL && p_scalar == NULL) || + (p == NULL) != (p_scalar == NULL)) { + OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + if (EC_GROUP_cmp(group, r->group, NULL) != 0 || + (p != NULL && EC_GROUP_cmp(group, p->group, NULL) != 0)) { + OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + + return group->meth->mul_public(group, r, g_scalar, p, p_scalar, ctx); +} + +int ec_point_mul_scalar(const EC_GROUP *group, EC_POINT *r, + const EC_SCALAR *g_scalar, const EC_POINT *p, + const EC_SCALAR *p_scalar, BN_CTX *ctx) { + if ((g_scalar == NULL && p_scalar == NULL) || + (p == NULL) != (p_scalar == NULL)) { + OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + if (EC_GROUP_cmp(group, r->group, NULL) != 0 || + (p != NULL && EC_GROUP_cmp(group, p->group, NULL) != 0)) { + OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + + return group->meth->mul(group, r, g_scalar, p, p_scalar, ctx); +} + +void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag) {} + +const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *group) { + return NULL; +} + +int EC_METHOD_get_field_type(const EC_METHOD *meth) { + return NID_X9_62_prime_field; +} + +void EC_GROUP_set_point_conversion_form(EC_GROUP *group, + point_conversion_form_t form) { + if (form != POINT_CONVERSION_UNCOMPRESSED) { + abort(); + } +} + +size_t EC_get_builtin_curves(EC_builtin_curve *out_curves, + size_t max_num_curves) { + const struct built_in_curves *const curves = OPENSSL_built_in_curves(); + + for (size_t i = 0; i < max_num_curves && i < OPENSSL_NUM_BUILT_IN_CURVES; + i++) { + out_curves[i].comment = curves->curves[i].comment; + out_curves[i].nid = curves->curves[i].nid; + } + + return OPENSSL_NUM_BUILT_IN_CURVES; +} + +int ec_bignum_to_scalar(const EC_GROUP *group, EC_SCALAR *out, + const BIGNUM *in) { + if (!ec_bignum_to_scalar_unchecked(group, out, in)) { + return 0; + } + if (!bn_less_than_words(out->words, group->order.d, group->order.width)) { + OPENSSL_PUT_ERROR(EC, EC_R_INVALID_SCALAR); + return 0; + } + return 1; +} + +int ec_bignum_to_scalar_unchecked(const EC_GROUP *group, EC_SCALAR *out, + const BIGNUM *in) { + if (!bn_copy_words(out->words, group->order.width, in)) { + OPENSSL_PUT_ERROR(EC, EC_R_INVALID_SCALAR); + return 0; + } + return 1; +} + +int ec_random_nonzero_scalar(const EC_GROUP *group, EC_SCALAR *out, + const uint8_t additional_data[32]) { + return bn_rand_range_words(out->words, 1, group->order.d, group->order.width, + additional_data); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/ec/ec_key.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/ec/ec_key.c new file mode 100644 index 0000000..b7e7f91 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/ec/ec_key.c @@ -0,0 +1,453 @@ +/* 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. */ + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "internal.h" +#include "../delocate.h" +#include "../../internal.h" + + +DEFINE_STATIC_EX_DATA_CLASS(g_ec_ex_data_class); + +static EC_WRAPPED_SCALAR *ec_wrapped_scalar_new(const EC_GROUP *group) { + EC_WRAPPED_SCALAR *wrapped = OPENSSL_malloc(sizeof(EC_WRAPPED_SCALAR)); + if (wrapped == NULL) { + OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE); + return NULL; + } + + OPENSSL_memset(wrapped, 0, sizeof(EC_WRAPPED_SCALAR)); + wrapped->bignum.d = wrapped->scalar.words; + wrapped->bignum.width = group->order.width; + wrapped->bignum.dmax = group->order.width; + wrapped->bignum.flags = BN_FLG_STATIC_DATA; + return wrapped; +} + +static void ec_wrapped_scalar_free(EC_WRAPPED_SCALAR *scalar) { + OPENSSL_free(scalar); +} + +EC_KEY *EC_KEY_new(void) { return EC_KEY_new_method(NULL); } + +EC_KEY *EC_KEY_new_method(const ENGINE *engine) { + EC_KEY *ret = OPENSSL_malloc(sizeof(EC_KEY)); + if (ret == NULL) { + OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE); + return NULL; + } + + OPENSSL_memset(ret, 0, sizeof(EC_KEY)); + + if (engine) { + ret->ecdsa_meth = ENGINE_get_ECDSA_method(engine); + } + if (ret->ecdsa_meth) { + METHOD_ref(ret->ecdsa_meth); + } + + ret->conv_form = POINT_CONVERSION_UNCOMPRESSED; + ret->references = 1; + + CRYPTO_new_ex_data(&ret->ex_data); + + if (ret->ecdsa_meth && ret->ecdsa_meth->init && !ret->ecdsa_meth->init(ret)) { + CRYPTO_free_ex_data(g_ec_ex_data_class_bss_get(), ret, &ret->ex_data); + if (ret->ecdsa_meth) { + METHOD_unref(ret->ecdsa_meth); + } + OPENSSL_free(ret); + return NULL; + } + + return ret; +} + +EC_KEY *EC_KEY_new_by_curve_name(int nid) { + EC_KEY *ret = EC_KEY_new(); + if (ret == NULL) { + OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE); + 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) { + if (r == NULL) { + return; + } + + if (!CRYPTO_refcount_dec_and_test_zero(&r->references)) { + return; + } + + if (r->ecdsa_meth) { + if (r->ecdsa_meth->finish) { + r->ecdsa_meth->finish(r); + } + METHOD_unref(r->ecdsa_meth); + } + + EC_GROUP_free(r->group); + EC_POINT_free(r->pub_key); + ec_wrapped_scalar_free(r->priv_key); + BN_free(r->fixed_k); + + CRYPTO_free_ex_data(g_ec_ex_data_class_bss_get(), r, &r->ex_data); + + OPENSSL_free(r); +} + +EC_KEY *EC_KEY_dup(const EC_KEY *src) { + if (src == NULL) { + OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER); + return NULL; + } + + EC_KEY *ret = EC_KEY_new(); + if (ret == NULL) { + return NULL; + } + + if ((src->group != NULL && + !EC_KEY_set_group(ret, src->group)) || + (src->pub_key != NULL && + !EC_KEY_set_public_key(ret, src->pub_key)) || + (src->priv_key != NULL && + !EC_KEY_set_private_key(ret, EC_KEY_get0_private_key(src)))) { + EC_KEY_free(ret); + return NULL; + } + + ret->enc_flag = src->enc_flag; + ret->conv_form = src->conv_form; + return ret; +} + +int EC_KEY_up_ref(EC_KEY *r) { + CRYPTO_refcount_inc(&r->references); + return 1; +} + +int EC_KEY_is_opaque(const EC_KEY *key) { + return key->ecdsa_meth && (key->ecdsa_meth->flags & ECDSA_FLAG_OPAQUE); +} + +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| already has a group, it is an error to switch to another one. + if (key->group != NULL) { + if (EC_GROUP_cmp(key->group, group, NULL) != 0) { + OPENSSL_PUT_ERROR(EC, EC_R_GROUP_MISMATCH); + return 0; + } + return 1; + } + + assert(key->priv_key == NULL); + assert(key->pub_key == NULL); + + EC_GROUP_free(key->group); + key->group = EC_GROUP_dup(group); + return key->group != NULL; +} + +const BIGNUM *EC_KEY_get0_private_key(const EC_KEY *key) { + return key->priv_key != NULL ? &key->priv_key->bignum : NULL; +} + +int EC_KEY_set_private_key(EC_KEY *key, const BIGNUM *priv_key) { + if (key->group == NULL) { + OPENSSL_PUT_ERROR(EC, EC_R_MISSING_PARAMETERS); + return 0; + } + + EC_WRAPPED_SCALAR *scalar = ec_wrapped_scalar_new(key->group); + if (scalar == NULL) { + return 0; + } + if (!ec_bignum_to_scalar(key->group, &scalar->scalar, priv_key)) { + OPENSSL_PUT_ERROR(EC, EC_R_WRONG_ORDER); + ec_wrapped_scalar_free(scalar); + return 0; + } + ec_wrapped_scalar_free(key->priv_key); + key->priv_key = scalar; + return 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->group == NULL) { + OPENSSL_PUT_ERROR(EC, EC_R_MISSING_PARAMETERS); + return 0; + } + + if (EC_GROUP_cmp(key->group, pub_key->group, NULL) != 0) { + OPENSSL_PUT_ERROR(EC, EC_R_GROUP_MISMATCH); + return 0; + } + + 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; +} + +int EC_KEY_check_key(const EC_KEY *eckey) { + int ok = 0; + BN_CTX *ctx = NULL; + EC_POINT *point = NULL; + + if (!eckey || !eckey->group || !eckey->pub_key) { + OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + if (EC_POINT_is_at_infinity(eckey->group, eckey->pub_key)) { + OPENSSL_PUT_ERROR(EC, EC_R_POINT_AT_INFINITY); + goto err; + } + + ctx = BN_CTX_new(); + + if (ctx == 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)) { + OPENSSL_PUT_ERROR(EC, EC_R_POINT_IS_NOT_ON_CURVE); + goto err; + } + // in case the priv_key is present : + // check if generator * priv_key == pub_key + if (eckey->priv_key != NULL) { + point = EC_POINT_new(eckey->group); + if (point == NULL || + !ec_point_mul_scalar(eckey->group, point, &eckey->priv_key->scalar, + NULL, NULL, ctx)) { + OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB); + goto err; + } + if (EC_POINT_cmp(eckey->group, point, eckey->pub_key, ctx) != 0) { + OPENSSL_PUT_ERROR(EC, EC_R_INVALID_PRIVATE_KEY); + goto err; + } + } + ok = 1; + +err: + BN_CTX_free(ctx); + EC_POINT_free(point); + return ok; +} + +int EC_KEY_check_fips(const EC_KEY *key) { + if (EC_KEY_is_opaque(key)) { + // Opaque keys can't be checked. + OPENSSL_PUT_ERROR(EC, EC_R_PUBLIC_KEY_VALIDATION_FAILED); + return 0; + } + + if (!EC_KEY_check_key(key)) { + return 0; + } + + if (key->priv_key) { + uint8_t data[16] = {0}; + ECDSA_SIG *sig = ECDSA_do_sign(data, sizeof(data), key); +#if defined(BORINGSSL_FIPS_BREAK_ECDSA_PWCT) + data[0] = ~data[0]; +#endif + int ok = sig != NULL && + ECDSA_do_verify(data, sizeof(data), sig, key); + ECDSA_SIG_free(sig); + if (!ok) { + OPENSSL_PUT_ERROR(EC, EC_R_PUBLIC_KEY_VALIDATION_FAILED); + return 0; + } + } + + return 1; +} + +int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, BIGNUM *x, + BIGNUM *y) { + EC_POINT *point = NULL; + int ok = 0; + + if (!key || !key->group || !x || !y) { + OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + point = EC_POINT_new(key->group); + if (point == NULL || + !EC_POINT_set_affine_coordinates_GFp(key->group, point, x, y, NULL) || + !EC_KEY_set_public_key(key, point) || + !EC_KEY_check_key(key)) { + goto err; + } + + ok = 1; + +err: + EC_POINT_free(point); + return ok; +} + +int EC_KEY_generate_key(EC_KEY *key) { + if (key == NULL || key->group == NULL) { + OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + // Check that the group order is FIPS compliant (FIPS 186-4 B.4.2). + if (BN_num_bits(EC_GROUP_get0_order(key->group)) < 160) { + OPENSSL_PUT_ERROR(EC, EC_R_INVALID_GROUP_ORDER); + return 0; + } + + static const uint8_t kDefaultAdditionalData[32] = {0}; + EC_WRAPPED_SCALAR *priv_key = ec_wrapped_scalar_new(key->group); + EC_POINT *pub_key = EC_POINT_new(key->group); + if (priv_key == NULL || pub_key == NULL || + // Generate the private key by testing candidates (FIPS 186-4 B.4.2). + !ec_random_nonzero_scalar(key->group, &priv_key->scalar, + kDefaultAdditionalData) || + !ec_point_mul_scalar(key->group, pub_key, &priv_key->scalar, NULL, NULL, + NULL)) { + EC_POINT_free(pub_key); + ec_wrapped_scalar_free(priv_key); + return 0; + } + + ec_wrapped_scalar_free(key->priv_key); + key->priv_key = priv_key; + EC_POINT_free(key->pub_key); + key->pub_key = pub_key; + return 1; +} + +int EC_KEY_generate_key_fips(EC_KEY *eckey) { + return EC_KEY_generate_key(eckey) && EC_KEY_check_fips(eckey); +} + +int EC_KEY_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused *unused, + CRYPTO_EX_dup *dup_unused, + CRYPTO_EX_free *free_func) { + int index; + if (!CRYPTO_get_ex_new_index(g_ec_ex_data_class_bss_get(), &index, argl, argp, + free_func)) { + return -1; + } + return index; +} + +int EC_KEY_set_ex_data(EC_KEY *d, int idx, void *arg) { + return CRYPTO_set_ex_data(&d->ex_data, idx, arg); +} + +void *EC_KEY_get_ex_data(const EC_KEY *d, int idx) { + return CRYPTO_get_ex_data(&d->ex_data, idx); +} + +void EC_KEY_set_asn1_flag(EC_KEY *key, int flag) {} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/ec/ec_key.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/ec/ec_key.c.grpc_back new file mode 100644 index 0000000..a6d4697 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/ec/ec_key.c.grpc_back @@ -0,0 +1,453 @@ +/* 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. */ + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "internal.h" +#include "../delocate.h" +#include "../../internal.h" + + +DEFINE_STATIC_EX_DATA_CLASS(g_ec_ex_data_class); + +static EC_WRAPPED_SCALAR *ec_wrapped_scalar_new(const EC_GROUP *group) { + EC_WRAPPED_SCALAR *wrapped = OPENSSL_malloc(sizeof(EC_WRAPPED_SCALAR)); + if (wrapped == NULL) { + OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE); + return NULL; + } + + OPENSSL_memset(wrapped, 0, sizeof(EC_WRAPPED_SCALAR)); + wrapped->bignum.d = wrapped->scalar.words; + wrapped->bignum.width = group->order.width; + wrapped->bignum.dmax = group->order.width; + wrapped->bignum.flags = BN_FLG_STATIC_DATA; + return wrapped; +} + +static void ec_wrapped_scalar_free(EC_WRAPPED_SCALAR *scalar) { + OPENSSL_free(scalar); +} + +EC_KEY *EC_KEY_new(void) { return EC_KEY_new_method(NULL); } + +EC_KEY *EC_KEY_new_method(const ENGINE *engine) { + EC_KEY *ret = OPENSSL_malloc(sizeof(EC_KEY)); + if (ret == NULL) { + OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE); + return NULL; + } + + OPENSSL_memset(ret, 0, sizeof(EC_KEY)); + + if (engine) { + ret->ecdsa_meth = ENGINE_get_ECDSA_method(engine); + } + if (ret->ecdsa_meth) { + METHOD_ref(ret->ecdsa_meth); + } + + ret->conv_form = POINT_CONVERSION_UNCOMPRESSED; + ret->references = 1; + + CRYPTO_new_ex_data(&ret->ex_data); + + if (ret->ecdsa_meth && ret->ecdsa_meth->init && !ret->ecdsa_meth->init(ret)) { + CRYPTO_free_ex_data(g_ec_ex_data_class_bss_get(), ret, &ret->ex_data); + if (ret->ecdsa_meth) { + METHOD_unref(ret->ecdsa_meth); + } + OPENSSL_free(ret); + return NULL; + } + + return ret; +} + +EC_KEY *EC_KEY_new_by_curve_name(int nid) { + EC_KEY *ret = EC_KEY_new(); + if (ret == NULL) { + OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE); + 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) { + if (r == NULL) { + return; + } + + if (!CRYPTO_refcount_dec_and_test_zero(&r->references)) { + return; + } + + if (r->ecdsa_meth) { + if (r->ecdsa_meth->finish) { + r->ecdsa_meth->finish(r); + } + METHOD_unref(r->ecdsa_meth); + } + + EC_GROUP_free(r->group); + EC_POINT_free(r->pub_key); + ec_wrapped_scalar_free(r->priv_key); + BN_free(r->fixed_k); + + CRYPTO_free_ex_data(g_ec_ex_data_class_bss_get(), r, &r->ex_data); + + OPENSSL_free(r); +} + +EC_KEY *EC_KEY_dup(const EC_KEY *src) { + if (src == NULL) { + OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER); + return NULL; + } + + EC_KEY *ret = EC_KEY_new(); + if (ret == NULL) { + return NULL; + } + + if ((src->group != NULL && + !EC_KEY_set_group(ret, src->group)) || + (src->pub_key != NULL && + !EC_KEY_set_public_key(ret, src->pub_key)) || + (src->priv_key != NULL && + !EC_KEY_set_private_key(ret, EC_KEY_get0_private_key(src)))) { + EC_KEY_free(ret); + return NULL; + } + + ret->enc_flag = src->enc_flag; + ret->conv_form = src->conv_form; + return ret; +} + +int EC_KEY_up_ref(EC_KEY *r) { + CRYPTO_refcount_inc(&r->references); + return 1; +} + +int EC_KEY_is_opaque(const EC_KEY *key) { + return key->ecdsa_meth && (key->ecdsa_meth->flags & ECDSA_FLAG_OPAQUE); +} + +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| already has a group, it is an error to switch to another one. + if (key->group != NULL) { + if (EC_GROUP_cmp(key->group, group, NULL) != 0) { + OPENSSL_PUT_ERROR(EC, EC_R_GROUP_MISMATCH); + return 0; + } + return 1; + } + + assert(key->priv_key == NULL); + assert(key->pub_key == NULL); + + EC_GROUP_free(key->group); + key->group = EC_GROUP_dup(group); + return key->group != NULL; +} + +const BIGNUM *EC_KEY_get0_private_key(const EC_KEY *key) { + return key->priv_key != NULL ? &key->priv_key->bignum : NULL; +} + +int EC_KEY_set_private_key(EC_KEY *key, const BIGNUM *priv_key) { + if (key->group == NULL) { + OPENSSL_PUT_ERROR(EC, EC_R_MISSING_PARAMETERS); + return 0; + } + + EC_WRAPPED_SCALAR *scalar = ec_wrapped_scalar_new(key->group); + if (scalar == NULL) { + return 0; + } + if (!ec_bignum_to_scalar(key->group, &scalar->scalar, priv_key)) { + OPENSSL_PUT_ERROR(EC, EC_R_WRONG_ORDER); + ec_wrapped_scalar_free(scalar); + return 0; + } + ec_wrapped_scalar_free(key->priv_key); + key->priv_key = scalar; + return 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->group == NULL) { + OPENSSL_PUT_ERROR(EC, EC_R_MISSING_PARAMETERS); + return 0; + } + + if (EC_GROUP_cmp(key->group, pub_key->group, NULL) != 0) { + OPENSSL_PUT_ERROR(EC, EC_R_GROUP_MISMATCH); + return 0; + } + + 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; +} + +int EC_KEY_check_key(const EC_KEY *eckey) { + int ok = 0; + BN_CTX *ctx = NULL; + EC_POINT *point = NULL; + + if (!eckey || !eckey->group || !eckey->pub_key) { + OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + if (EC_POINT_is_at_infinity(eckey->group, eckey->pub_key)) { + OPENSSL_PUT_ERROR(EC, EC_R_POINT_AT_INFINITY); + goto err; + } + + ctx = BN_CTX_new(); + + if (ctx == 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)) { + OPENSSL_PUT_ERROR(EC, EC_R_POINT_IS_NOT_ON_CURVE); + goto err; + } + // in case the priv_key is present : + // check if generator * priv_key == pub_key + if (eckey->priv_key != NULL) { + point = EC_POINT_new(eckey->group); + if (point == NULL || + !ec_point_mul_scalar(eckey->group, point, &eckey->priv_key->scalar, + NULL, NULL, ctx)) { + OPENSSL_PUT_ERROR(EC, ERR_R_EC_LIB); + goto err; + } + if (EC_POINT_cmp(eckey->group, point, eckey->pub_key, ctx) != 0) { + OPENSSL_PUT_ERROR(EC, EC_R_INVALID_PRIVATE_KEY); + goto err; + } + } + ok = 1; + +err: + BN_CTX_free(ctx); + EC_POINT_free(point); + return ok; +} + +int EC_KEY_check_fips(const EC_KEY *key) { + if (EC_KEY_is_opaque(key)) { + // Opaque keys can't be checked. + OPENSSL_PUT_ERROR(EC, EC_R_PUBLIC_KEY_VALIDATION_FAILED); + return 0; + } + + if (!EC_KEY_check_key(key)) { + return 0; + } + + if (key->priv_key) { + uint8_t data[16] = {0}; + ECDSA_SIG *sig = ECDSA_do_sign(data, sizeof(data), key); +#if defined(BORINGSSL_FIPS_BREAK_ECDSA_PWCT) + data[0] = ~data[0]; +#endif + int ok = sig != NULL && + ECDSA_do_verify(data, sizeof(data), sig, key); + ECDSA_SIG_free(sig); + if (!ok) { + OPENSSL_PUT_ERROR(EC, EC_R_PUBLIC_KEY_VALIDATION_FAILED); + return 0; + } + } + + return 1; +} + +int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, BIGNUM *x, + BIGNUM *y) { + EC_POINT *point = NULL; + int ok = 0; + + if (!key || !key->group || !x || !y) { + OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + point = EC_POINT_new(key->group); + if (point == NULL || + !EC_POINT_set_affine_coordinates_GFp(key->group, point, x, y, NULL) || + !EC_KEY_set_public_key(key, point) || + !EC_KEY_check_key(key)) { + goto err; + } + + ok = 1; + +err: + EC_POINT_free(point); + return ok; +} + +int EC_KEY_generate_key(EC_KEY *key) { + if (key == NULL || key->group == NULL) { + OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + // Check that the group order is FIPS compliant (FIPS 186-4 B.4.2). + if (BN_num_bits(EC_GROUP_get0_order(key->group)) < 160) { + OPENSSL_PUT_ERROR(EC, EC_R_INVALID_GROUP_ORDER); + return 0; + } + + static const uint8_t kDefaultAdditionalData[32] = {0}; + EC_WRAPPED_SCALAR *priv_key = ec_wrapped_scalar_new(key->group); + EC_POINT *pub_key = EC_POINT_new(key->group); + if (priv_key == NULL || pub_key == NULL || + // Generate the private key by testing candidates (FIPS 186-4 B.4.2). + !ec_random_nonzero_scalar(key->group, &priv_key->scalar, + kDefaultAdditionalData) || + !ec_point_mul_scalar(key->group, pub_key, &priv_key->scalar, NULL, NULL, + NULL)) { + EC_POINT_free(pub_key); + ec_wrapped_scalar_free(priv_key); + return 0; + } + + ec_wrapped_scalar_free(key->priv_key); + key->priv_key = priv_key; + EC_POINT_free(key->pub_key); + key->pub_key = pub_key; + return 1; +} + +int EC_KEY_generate_key_fips(EC_KEY *eckey) { + return EC_KEY_generate_key(eckey) && EC_KEY_check_fips(eckey); +} + +int EC_KEY_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused *unused, + CRYPTO_EX_dup *dup_unused, + CRYPTO_EX_free *free_func) { + int index; + if (!CRYPTO_get_ex_new_index(g_ec_ex_data_class_bss_get(), &index, argl, argp, + free_func)) { + return -1; + } + return index; +} + +int EC_KEY_set_ex_data(EC_KEY *d, int idx, void *arg) { + return CRYPTO_set_ex_data(&d->ex_data, idx, arg); +} + +void *EC_KEY_get_ex_data(const EC_KEY *d, int idx) { + return CRYPTO_get_ex_data(&d->ex_data, idx); +} + +void EC_KEY_set_asn1_flag(EC_KEY *key, int flag) {} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/ec/ec_montgomery.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/ec/ec_montgomery.c new file mode 100644 index 0000000..aaa1d9f --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/ec/ec_montgomery.c @@ -0,0 +1,270 @@ +/* Originally written by Bodo Moeller and 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 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 +#include +#include + +#include "../bn/internal.h" +#include "../delocate.h" +#include "internal.h" + + +int ec_GFp_mont_group_init(EC_GROUP *group) { + int ok; + + ok = ec_GFp_simple_group_init(group); + group->mont = NULL; + return ok; +} + +void ec_GFp_mont_group_finish(EC_GROUP *group) { + BN_MONT_CTX_free(group->mont); + group->mont = NULL; + ec_GFp_simple_group_finish(group); +} + +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; + int ret = 0; + + BN_MONT_CTX_free(group->mont); + group->mont = NULL; + + if (ctx == NULL) { + ctx = new_ctx = BN_CTX_new(); + if (ctx == NULL) { + return 0; + } + } + + group->mont = BN_MONT_CTX_new_for_modulus(p, ctx); + if (group->mont == NULL) { + OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB); + goto err; + } + + ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx); + + if (!ret) { + BN_MONT_CTX_free(group->mont); + group->mont = NULL; + } + +err: + BN_CTX_free(new_ctx); + 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->mont == NULL) { + OPENSSL_PUT_ERROR(EC, EC_R_NOT_INITIALIZED); + return 0; + } + + return BN_mod_mul_montgomery(r, a, b, group->mont, ctx); +} + +int ec_GFp_mont_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, + BN_CTX *ctx) { + if (group->mont == NULL) { + OPENSSL_PUT_ERROR(EC, EC_R_NOT_INITIALIZED); + return 0; + } + + return BN_mod_mul_montgomery(r, a, a, group->mont, ctx); +} + +int ec_GFp_mont_field_encode(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, + BN_CTX *ctx) { + if (group->mont == NULL) { + OPENSSL_PUT_ERROR(EC, EC_R_NOT_INITIALIZED); + return 0; + } + + return BN_to_montgomery(r, a, group->mont, ctx); +} + +int ec_GFp_mont_field_decode(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, + BN_CTX *ctx) { + if (group->mont == NULL) { + OPENSSL_PUT_ERROR(EC, EC_R_NOT_INITIALIZED); + return 0; + } + + return BN_from_montgomery(r, a, group->mont, ctx); +} + +static int ec_GFp_mont_point_get_affine_coordinates(const EC_GROUP *group, + const EC_POINT *point, + BIGNUM *x, BIGNUM *y, + BN_CTX *ctx) { + if (EC_POINT_is_at_infinity(group, point)) { + OPENSSL_PUT_ERROR(EC, EC_R_POINT_AT_INFINITY); + return 0; + } + + BN_CTX *new_ctx = NULL; + if (ctx == NULL) { + ctx = new_ctx = BN_CTX_new(); + if (ctx == NULL) { + return 0; + } + } + + int ret = 0; + + BN_CTX_start(ctx); + + if (BN_cmp(&point->Z, &group->one) == 0) { + // |point| is already affine. + if (x != NULL && !BN_from_montgomery(x, &point->X, group->mont, ctx)) { + goto err; + } + if (y != NULL && !BN_from_montgomery(y, &point->Y, group->mont, ctx)) { + goto err; + } + } else { + // transform (X, Y, Z) into (x, y) := (X/Z^2, Y/Z^3) + + BIGNUM *Z_1 = BN_CTX_get(ctx); + BIGNUM *Z_2 = BN_CTX_get(ctx); + BIGNUM *Z_3 = BN_CTX_get(ctx); + if (Z_1 == NULL || + Z_2 == NULL || + Z_3 == NULL) { + goto err; + } + + // The straightforward way to calculate the inverse of a Montgomery-encoded + // value where the result is Montgomery-encoded is: + // + // |BN_from_montgomery| + invert + |BN_to_montgomery|. + // + // This is equivalent, but more efficient, because |BN_from_montgomery| + // is more efficient (at least in theory) than |BN_to_montgomery|, since it + // doesn't have to do the multiplication before the reduction. + // + // Use Fermat's Little Theorem instead of |BN_mod_inverse_odd| since this + // inversion may be done as the final step of private key operations. + // Unfortunately, this is suboptimal for ECDSA verification. + if (!BN_from_montgomery(Z_1, &point->Z, group->mont, ctx) || + !BN_from_montgomery(Z_1, Z_1, group->mont, ctx) || + !bn_mod_inverse_prime(Z_1, Z_1, &group->field, ctx, group->mont)) { + goto err; + } + + if (!BN_mod_mul_montgomery(Z_2, Z_1, Z_1, group->mont, ctx)) { + goto err; + } + + // Instead of using |BN_from_montgomery| to convert the |x| coordinate + // and then calling |BN_from_montgomery| again to convert the |y| + // coordinate below, convert the common factor |Z_2| once now, saving one + // reduction. + if (!BN_from_montgomery(Z_2, Z_2, group->mont, ctx)) { + goto err; + } + + if (x != NULL) { + if (!BN_mod_mul_montgomery(x, &point->X, Z_2, group->mont, ctx)) { + goto err; + } + } + + if (y != NULL) { + if (!BN_mod_mul_montgomery(Z_3, Z_2, Z_1, group->mont, ctx) || + !BN_mod_mul_montgomery(y, &point->Y, Z_3, group->mont, ctx)) { + goto err; + } + } + } + + ret = 1; + +err: + BN_CTX_end(ctx); + BN_CTX_free(new_ctx); + return ret; +} + +DEFINE_METHOD_FUNCTION(EC_METHOD, EC_GFp_mont_method) { + out->group_init = ec_GFp_mont_group_init; + out->group_finish = ec_GFp_mont_group_finish; + out->group_set_curve = ec_GFp_mont_group_set_curve; + out->point_get_affine_coordinates = ec_GFp_mont_point_get_affine_coordinates; + out->mul = ec_wNAF_mul /* XXX: Not constant time. */; + out->mul_public = ec_wNAF_mul; + out->field_mul = ec_GFp_mont_field_mul; + out->field_sqr = ec_GFp_mont_field_sqr; + out->field_encode = ec_GFp_mont_field_encode; + out->field_decode = ec_GFp_mont_field_decode; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/ec/ec_montgomery.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/ec/ec_montgomery.c.grpc_back new file mode 100644 index 0000000..165c06f --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/ec/ec_montgomery.c.grpc_back @@ -0,0 +1,270 @@ +/* Originally written by Bodo Moeller and 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 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 +#include +#include + +#include "../bn/internal.h" +#include "../delocate.h" +#include "internal.h" + + +int ec_GFp_mont_group_init(EC_GROUP *group) { + int ok; + + ok = ec_GFp_simple_group_init(group); + group->mont = NULL; + return ok; +} + +void ec_GFp_mont_group_finish(EC_GROUP *group) { + BN_MONT_CTX_free(group->mont); + group->mont = NULL; + ec_GFp_simple_group_finish(group); +} + +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; + int ret = 0; + + BN_MONT_CTX_free(group->mont); + group->mont = NULL; + + if (ctx == NULL) { + ctx = new_ctx = BN_CTX_new(); + if (ctx == NULL) { + return 0; + } + } + + group->mont = BN_MONT_CTX_new_for_modulus(p, ctx); + if (group->mont == NULL) { + OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB); + goto err; + } + + ret = ec_GFp_simple_group_set_curve(group, p, a, b, ctx); + + if (!ret) { + BN_MONT_CTX_free(group->mont); + group->mont = NULL; + } + +err: + BN_CTX_free(new_ctx); + 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->mont == NULL) { + OPENSSL_PUT_ERROR(EC, EC_R_NOT_INITIALIZED); + return 0; + } + + return BN_mod_mul_montgomery(r, a, b, group->mont, ctx); +} + +int ec_GFp_mont_field_sqr(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, + BN_CTX *ctx) { + if (group->mont == NULL) { + OPENSSL_PUT_ERROR(EC, EC_R_NOT_INITIALIZED); + return 0; + } + + return BN_mod_mul_montgomery(r, a, a, group->mont, ctx); +} + +int ec_GFp_mont_field_encode(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, + BN_CTX *ctx) { + if (group->mont == NULL) { + OPENSSL_PUT_ERROR(EC, EC_R_NOT_INITIALIZED); + return 0; + } + + return BN_to_montgomery(r, a, group->mont, ctx); +} + +int ec_GFp_mont_field_decode(const EC_GROUP *group, BIGNUM *r, const BIGNUM *a, + BN_CTX *ctx) { + if (group->mont == NULL) { + OPENSSL_PUT_ERROR(EC, EC_R_NOT_INITIALIZED); + return 0; + } + + return BN_from_montgomery(r, a, group->mont, ctx); +} + +static int ec_GFp_mont_point_get_affine_coordinates(const EC_GROUP *group, + const EC_POINT *point, + BIGNUM *x, BIGNUM *y, + BN_CTX *ctx) { + if (EC_POINT_is_at_infinity(group, point)) { + OPENSSL_PUT_ERROR(EC, EC_R_POINT_AT_INFINITY); + return 0; + } + + BN_CTX *new_ctx = NULL; + if (ctx == NULL) { + ctx = new_ctx = BN_CTX_new(); + if (ctx == NULL) { + return 0; + } + } + + int ret = 0; + + BN_CTX_start(ctx); + + if (BN_cmp(&point->Z, &group->one) == 0) { + // |point| is already affine. + if (x != NULL && !BN_from_montgomery(x, &point->X, group->mont, ctx)) { + goto err; + } + if (y != NULL && !BN_from_montgomery(y, &point->Y, group->mont, ctx)) { + goto err; + } + } else { + // transform (X, Y, Z) into (x, y) := (X/Z^2, Y/Z^3) + + BIGNUM *Z_1 = BN_CTX_get(ctx); + BIGNUM *Z_2 = BN_CTX_get(ctx); + BIGNUM *Z_3 = BN_CTX_get(ctx); + if (Z_1 == NULL || + Z_2 == NULL || + Z_3 == NULL) { + goto err; + } + + // The straightforward way to calculate the inverse of a Montgomery-encoded + // value where the result is Montgomery-encoded is: + // + // |BN_from_montgomery| + invert + |BN_to_montgomery|. + // + // This is equivalent, but more efficient, because |BN_from_montgomery| + // is more efficient (at least in theory) than |BN_to_montgomery|, since it + // doesn't have to do the multiplication before the reduction. + // + // Use Fermat's Little Theorem instead of |BN_mod_inverse_odd| since this + // inversion may be done as the final step of private key operations. + // Unfortunately, this is suboptimal for ECDSA verification. + if (!BN_from_montgomery(Z_1, &point->Z, group->mont, ctx) || + !BN_from_montgomery(Z_1, Z_1, group->mont, ctx) || + !bn_mod_inverse_prime(Z_1, Z_1, &group->field, ctx, group->mont)) { + goto err; + } + + if (!BN_mod_mul_montgomery(Z_2, Z_1, Z_1, group->mont, ctx)) { + goto err; + } + + // Instead of using |BN_from_montgomery| to convert the |x| coordinate + // and then calling |BN_from_montgomery| again to convert the |y| + // coordinate below, convert the common factor |Z_2| once now, saving one + // reduction. + if (!BN_from_montgomery(Z_2, Z_2, group->mont, ctx)) { + goto err; + } + + if (x != NULL) { + if (!BN_mod_mul_montgomery(x, &point->X, Z_2, group->mont, ctx)) { + goto err; + } + } + + if (y != NULL) { + if (!BN_mod_mul_montgomery(Z_3, Z_2, Z_1, group->mont, ctx) || + !BN_mod_mul_montgomery(y, &point->Y, Z_3, group->mont, ctx)) { + goto err; + } + } + } + + ret = 1; + +err: + BN_CTX_end(ctx); + BN_CTX_free(new_ctx); + return ret; +} + +DEFINE_METHOD_FUNCTION(EC_METHOD, EC_GFp_mont_method) { + out->group_init = ec_GFp_mont_group_init; + out->group_finish = ec_GFp_mont_group_finish; + out->group_set_curve = ec_GFp_mont_group_set_curve; + out->point_get_affine_coordinates = ec_GFp_mont_point_get_affine_coordinates; + out->mul = ec_wNAF_mul /* XXX: Not constant time. */; + out->mul_public = ec_wNAF_mul; + out->field_mul = ec_GFp_mont_field_mul; + out->field_sqr = ec_GFp_mont_field_sqr; + out->field_encode = ec_GFp_mont_field_encode; + out->field_decode = ec_GFp_mont_field_decode; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/ec/internal.h b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/ec/internal.h new file mode 100644 index 0000000..cbd43cc --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/ec/internal.h @@ -0,0 +1,337 @@ +/* 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 OPENSSL_HEADER_EC_INTERNAL_H +#define OPENSSL_HEADER_EC_INTERNAL_H + +#include + +#include +#include +#include +#include + +#include "../bn/internal.h" + +#if defined(__cplusplus) +extern "C" { +#endif + + +// Cap the size of all field elements and scalars, including custom curves, to +// 66 bytes, large enough to fit secp521r1 and brainpoolP512r1, which appear to +// be the largest fields anyone plausibly uses. +#define EC_MAX_SCALAR_BYTES 66 +#define EC_MAX_SCALAR_WORDS ((66 + BN_BYTES - 1) / BN_BYTES) + +OPENSSL_COMPILE_ASSERT(EC_MAX_SCALAR_WORDS <= BN_SMALL_MAX_WORDS, + bn_small_functions_applicable); + +// An EC_SCALAR is an integer fully reduced modulo the order. Only the first +// |order->width| words are used. An |EC_SCALAR| is specific to an |EC_GROUP| +// and must not be mixed between groups. +typedef union { + // bytes is the representation of the scalar in little-endian order. + uint8_t bytes[EC_MAX_SCALAR_BYTES]; + BN_ULONG words[EC_MAX_SCALAR_WORDS]; +} EC_SCALAR; + +struct ec_method_st { + int (*group_init)(EC_GROUP *); + void (*group_finish)(EC_GROUP *); + int (*group_set_curve)(EC_GROUP *, const BIGNUM *p, const BIGNUM *a, + const BIGNUM *b, BN_CTX *); + int (*point_get_affine_coordinates)(const EC_GROUP *, const EC_POINT *, + BIGNUM *x, BIGNUM *y, BN_CTX *); + + // Computes |r = g_scalar*generator + p_scalar*p| if |g_scalar| and |p_scalar| + // are both non-null. Computes |r = g_scalar*generator| if |p_scalar| is null. + // Computes |r = p_scalar*p| if g_scalar is null. At least one of |g_scalar| + // and |p_scalar| must be non-null, and |p| must be non-null if |p_scalar| is + // non-null. + int (*mul)(const EC_GROUP *group, EC_POINT *r, const EC_SCALAR *g_scalar, + const EC_POINT *p, const EC_SCALAR *p_scalar, BN_CTX *ctx); + // mul_public performs the same computation as mul. It further assumes that + // the inputs are public so there is no concern about leaking their values + // through timing. + int (*mul_public)(const EC_GROUP *group, EC_POINT *r, + const EC_SCALAR *g_scalar, const EC_POINT *p, + const EC_SCALAR *p_scalar, BN_CTX *ctx); + + // 'field_mul' and 'field_sqr' 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_encode)(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, + BN_CTX *); // e.g. to Montgomery + int (*field_decode)(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, + BN_CTX *); // e.g. from Montgomery +} /* EC_METHOD */; + +const EC_METHOD *EC_GFp_mont_method(void); + +struct ec_group_st { + const EC_METHOD *meth; + + // Unlike all other |EC_POINT|s, |generator| does not own |generator->group| + // to avoid a reference cycle. + EC_POINT *generator; + BIGNUM order; + + int curve_name; // optional NID for named curve + + BN_MONT_CTX *order_mont; // data for ECDSA inverse + + // The following members are handled by the method functions, + // even if they appear generic + + BIGNUM field; // For curves over GF(p), this is the modulus. + + BIGNUM a, b; // Curve coefficients. + + int a_is_minus3; // enable optimized point arithmetics for special case + + CRYPTO_refcount_t references; + + BN_MONT_CTX *mont; // Montgomery structure. + + BIGNUM one; // The value one. +} /* EC_GROUP */; + +struct ec_point_st { + // group is an owning reference to |group|, unless this is + // |group->generator|. + EC_GROUP *group; + + BIGNUM X; + BIGNUM Y; + BIGNUM Z; // Jacobian projective coordinates: + // (X, Y, Z) represents (X/Z^2, Y/Z^3) if Z != 0 +} /* EC_POINT */; + +EC_GROUP *ec_group_new(const EC_METHOD *meth); + +// ec_bignum_to_scalar converts |in| to an |EC_SCALAR| and writes it to +// |*out|. It returns one on success and zero if |in| is out of range. +OPENSSL_EXPORT int ec_bignum_to_scalar(const EC_GROUP *group, EC_SCALAR *out, + const BIGNUM *in); + +// ec_bignum_to_scalar_unchecked behaves like |ec_bignum_to_scalar| but does not +// check |in| is fully reduced. +int ec_bignum_to_scalar_unchecked(const EC_GROUP *group, EC_SCALAR *out, + const BIGNUM *in); + +// ec_random_nonzero_scalar sets |out| to a uniformly selected random value from +// 1 to |group->order| - 1. It returns one on success and zero on error. +int ec_random_nonzero_scalar(const EC_GROUP *group, EC_SCALAR *out, + const uint8_t additional_data[32]); + +// ec_point_mul_scalar sets |r| to generator * |g_scalar| + |p| * +// |p_scalar|. Unlike other functions which take |EC_SCALAR|, |g_scalar| and +// |p_scalar| need not be fully reduced. They need only contain as many bits as +// the order. +int ec_point_mul_scalar(const EC_GROUP *group, EC_POINT *r, + const EC_SCALAR *g_scalar, const EC_POINT *p, + const EC_SCALAR *p_scalar, BN_CTX *ctx); + +// ec_point_mul_scalar_public performs the same computation as +// ec_point_mul_scalar. It further assumes that the inputs are public so +// there is no concern about leaking their values through timing. +OPENSSL_EXPORT int ec_point_mul_scalar_public( + const EC_GROUP *group, EC_POINT *r, const EC_SCALAR *g_scalar, + const EC_POINT *p, const EC_SCALAR *p_scalar, BN_CTX *ctx); + +// ec_compute_wNAF writes the modified width-(w+1) Non-Adjacent Form (wNAF) of +// |scalar| to |out| and returns one on success or zero on internal error. |out| +// must have room for |bits| + 1 elements, each of which will be either zero or +// odd with an absolute value less than 2^w satisfying +// scalar = \sum_j out[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. +int ec_compute_wNAF(const EC_GROUP *group, int8_t *out, const EC_SCALAR *scalar, + size_t bits, int w); + +int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const EC_SCALAR *g_scalar, + const EC_POINT *p, const EC_SCALAR *p_scalar, BN_CTX *ctx); + +// method functions in simple.c +int ec_GFp_simple_group_init(EC_GROUP *); +void ec_GFp_simple_group_finish(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 *); +unsigned ec_GFp_simple_group_get_degree(const EC_GROUP *); +int ec_GFp_simple_point_init(EC_POINT *); +void ec_GFp_simple_point_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_point_set_affine_coordinates(const EC_GROUP *, EC_POINT *, + const BIGNUM *x, const BIGNUM *y, + 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 montgomery.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 *); +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 *); + +void ec_GFp_nistp_recode_scalar_bits(uint8_t *sign, uint8_t *digit, uint8_t in); + +const EC_METHOD *EC_GFp_nistp224_method(void); +const EC_METHOD *EC_GFp_nistp256_method(void); + +// EC_GFp_nistz256_method is a GFp method using montgomery multiplication, with +// x86-64 optimized P256. See http://eprint.iacr.org/2013/816. +const EC_METHOD *EC_GFp_nistz256_method(void); + +// An EC_WRAPPED_SCALAR is an |EC_SCALAR| with a parallel |BIGNUM| +// representation. It exists to support the |EC_KEY_get0_private_key| API. +typedef struct { + BIGNUM bignum; + EC_SCALAR scalar; +} EC_WRAPPED_SCALAR; + +struct ec_key_st { + EC_GROUP *group; + + EC_POINT *pub_key; + EC_WRAPPED_SCALAR *priv_key; + + // fixed_k may contain a specific value of 'k', to be used in ECDSA signing. + // This is only for the FIPS power-on tests. + BIGNUM *fixed_k; + + unsigned int enc_flag; + point_conversion_form_t conv_form; + + CRYPTO_refcount_t references; + + ECDSA_METHOD *ecdsa_meth; + + CRYPTO_EX_DATA ex_data; +} /* EC_KEY */; + +struct built_in_curve { + int nid; + const uint8_t *oid; + uint8_t oid_len; + // comment is a human-readable string describing the curve. + const char *comment; + // param_len is the number of bytes needed to store a field element. + uint8_t param_len; + // params points to an array of 6*|param_len| bytes which hold the field + // elements of the following (in big-endian order): prime, a, b, generator x, + // generator y, order. + const uint8_t *params; + const EC_METHOD *method; +}; + +#define OPENSSL_NUM_BUILT_IN_CURVES 4 + +struct built_in_curves { + struct built_in_curve curves[OPENSSL_NUM_BUILT_IN_CURVES]; +}; + +// OPENSSL_built_in_curves returns a pointer to static information about +// standard curves. The array is terminated with an entry where |nid| is +// |NID_undef|. +const struct built_in_curves *OPENSSL_built_in_curves(void); + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_EC_INTERNAL_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/ec/internal.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/ec/internal.h.grpc_back new file mode 100644 index 0000000..c198cc2 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/ec/internal.h.grpc_back @@ -0,0 +1,337 @@ +/* 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 OPENSSL_HEADER_EC_INTERNAL_H +#define OPENSSL_HEADER_EC_INTERNAL_H + +#include + +#include +#include +#include +#include + +#include "../bn/internal.h" + +#if defined(__cplusplus) +extern "C" { +#endif + + +// Cap the size of all field elements and scalars, including custom curves, to +// 66 bytes, large enough to fit secp521r1 and brainpoolP512r1, which appear to +// be the largest fields anyone plausibly uses. +#define EC_MAX_SCALAR_BYTES 66 +#define EC_MAX_SCALAR_WORDS ((66 + BN_BYTES - 1) / BN_BYTES) + +OPENSSL_COMPILE_ASSERT(EC_MAX_SCALAR_WORDS <= BN_SMALL_MAX_WORDS, + bn_small_functions_applicable); + +// An EC_SCALAR is an integer fully reduced modulo the order. Only the first +// |order->width| words are used. An |EC_SCALAR| is specific to an |EC_GROUP| +// and must not be mixed between groups. +typedef union { + // bytes is the representation of the scalar in little-endian order. + uint8_t bytes[EC_MAX_SCALAR_BYTES]; + BN_ULONG words[EC_MAX_SCALAR_WORDS]; +} EC_SCALAR; + +struct ec_method_st { + int (*group_init)(EC_GROUP *); + void (*group_finish)(EC_GROUP *); + int (*group_set_curve)(EC_GROUP *, const BIGNUM *p, const BIGNUM *a, + const BIGNUM *b, BN_CTX *); + int (*point_get_affine_coordinates)(const EC_GROUP *, const EC_POINT *, + BIGNUM *x, BIGNUM *y, BN_CTX *); + + // Computes |r = g_scalar*generator + p_scalar*p| if |g_scalar| and |p_scalar| + // are both non-null. Computes |r = g_scalar*generator| if |p_scalar| is null. + // Computes |r = p_scalar*p| if g_scalar is null. At least one of |g_scalar| + // and |p_scalar| must be non-null, and |p| must be non-null if |p_scalar| is + // non-null. + int (*mul)(const EC_GROUP *group, EC_POINT *r, const EC_SCALAR *g_scalar, + const EC_POINT *p, const EC_SCALAR *p_scalar, BN_CTX *ctx); + // mul_public performs the same computation as mul. It further assumes that + // the inputs are public so there is no concern about leaking their values + // through timing. + int (*mul_public)(const EC_GROUP *group, EC_POINT *r, + const EC_SCALAR *g_scalar, const EC_POINT *p, + const EC_SCALAR *p_scalar, BN_CTX *ctx); + + // 'field_mul' and 'field_sqr' 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_encode)(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, + BN_CTX *); // e.g. to Montgomery + int (*field_decode)(const EC_GROUP *, BIGNUM *r, const BIGNUM *a, + BN_CTX *); // e.g. from Montgomery +} /* EC_METHOD */; + +const EC_METHOD *EC_GFp_mont_method(void); + +struct ec_group_st { + const EC_METHOD *meth; + + // Unlike all other |EC_POINT|s, |generator| does not own |generator->group| + // to avoid a reference cycle. + EC_POINT *generator; + BIGNUM order; + + int curve_name; // optional NID for named curve + + BN_MONT_CTX *order_mont; // data for ECDSA inverse + + // The following members are handled by the method functions, + // even if they appear generic + + BIGNUM field; // For curves over GF(p), this is the modulus. + + BIGNUM a, b; // Curve coefficients. + + int a_is_minus3; // enable optimized point arithmetics for special case + + CRYPTO_refcount_t references; + + BN_MONT_CTX *mont; // Montgomery structure. + + BIGNUM one; // The value one. +} /* EC_GROUP */; + +struct ec_point_st { + // group is an owning reference to |group|, unless this is + // |group->generator|. + EC_GROUP *group; + + BIGNUM X; + BIGNUM Y; + BIGNUM Z; // Jacobian projective coordinates: + // (X, Y, Z) represents (X/Z^2, Y/Z^3) if Z != 0 +} /* EC_POINT */; + +EC_GROUP *ec_group_new(const EC_METHOD *meth); + +// ec_bignum_to_scalar converts |in| to an |EC_SCALAR| and writes it to +// |*out|. It returns one on success and zero if |in| is out of range. +OPENSSL_EXPORT int ec_bignum_to_scalar(const EC_GROUP *group, EC_SCALAR *out, + const BIGNUM *in); + +// ec_bignum_to_scalar_unchecked behaves like |ec_bignum_to_scalar| but does not +// check |in| is fully reduced. +int ec_bignum_to_scalar_unchecked(const EC_GROUP *group, EC_SCALAR *out, + const BIGNUM *in); + +// ec_random_nonzero_scalar sets |out| to a uniformly selected random value from +// 1 to |group->order| - 1. It returns one on success and zero on error. +int ec_random_nonzero_scalar(const EC_GROUP *group, EC_SCALAR *out, + const uint8_t additional_data[32]); + +// ec_point_mul_scalar sets |r| to generator * |g_scalar| + |p| * +// |p_scalar|. Unlike other functions which take |EC_SCALAR|, |g_scalar| and +// |p_scalar| need not be fully reduced. They need only contain as many bits as +// the order. +int ec_point_mul_scalar(const EC_GROUP *group, EC_POINT *r, + const EC_SCALAR *g_scalar, const EC_POINT *p, + const EC_SCALAR *p_scalar, BN_CTX *ctx); + +// ec_point_mul_scalar_public performs the same computation as +// ec_point_mul_scalar. It further assumes that the inputs are public so +// there is no concern about leaking their values through timing. +OPENSSL_EXPORT int ec_point_mul_scalar_public( + const EC_GROUP *group, EC_POINT *r, const EC_SCALAR *g_scalar, + const EC_POINT *p, const EC_SCALAR *p_scalar, BN_CTX *ctx); + +// ec_compute_wNAF writes the modified width-(w+1) Non-Adjacent Form (wNAF) of +// |scalar| to |out| and returns one on success or zero on internal error. |out| +// must have room for |bits| + 1 elements, each of which will be either zero or +// odd with an absolute value less than 2^w satisfying +// scalar = \sum_j out[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. +int ec_compute_wNAF(const EC_GROUP *group, int8_t *out, const EC_SCALAR *scalar, + size_t bits, int w); + +int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const EC_SCALAR *g_scalar, + const EC_POINT *p, const EC_SCALAR *p_scalar, BN_CTX *ctx); + +// method functions in simple.c +int ec_GFp_simple_group_init(EC_GROUP *); +void ec_GFp_simple_group_finish(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 *); +unsigned ec_GFp_simple_group_get_degree(const EC_GROUP *); +int ec_GFp_simple_point_init(EC_POINT *); +void ec_GFp_simple_point_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_point_set_affine_coordinates(const EC_GROUP *, EC_POINT *, + const BIGNUM *x, const BIGNUM *y, + 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 montgomery.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 *); +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 *); + +void ec_GFp_nistp_recode_scalar_bits(uint8_t *sign, uint8_t *digit, uint8_t in); + +const EC_METHOD *EC_GFp_nistp224_method(void); +const EC_METHOD *EC_GFp_nistp256_method(void); + +// EC_GFp_nistz256_method is a GFp method using montgomery multiplication, with +// x86-64 optimized P256. See http://eprint.iacr.org/2013/816. +const EC_METHOD *EC_GFp_nistz256_method(void); + +// An EC_WRAPPED_SCALAR is an |EC_SCALAR| with a parallel |BIGNUM| +// representation. It exists to support the |EC_KEY_get0_private_key| API. +typedef struct { + BIGNUM bignum; + EC_SCALAR scalar; +} EC_WRAPPED_SCALAR; + +struct ec_key_st { + EC_GROUP *group; + + EC_POINT *pub_key; + EC_WRAPPED_SCALAR *priv_key; + + // fixed_k may contain a specific value of 'k', to be used in ECDSA signing. + // This is only for the FIPS power-on tests. + BIGNUM *fixed_k; + + unsigned int enc_flag; + point_conversion_form_t conv_form; + + CRYPTO_refcount_t references; + + ECDSA_METHOD *ecdsa_meth; + + CRYPTO_EX_DATA ex_data; +} /* EC_KEY */; + +struct built_in_curve { + int nid; + const uint8_t *oid; + uint8_t oid_len; + // comment is a human-readable string describing the curve. + const char *comment; + // param_len is the number of bytes needed to store a field element. + uint8_t param_len; + // params points to an array of 6*|param_len| bytes which hold the field + // elements of the following (in big-endian order): prime, a, b, generator x, + // generator y, order. + const uint8_t *params; + const EC_METHOD *method; +}; + +#define OPENSSL_NUM_BUILT_IN_CURVES 4 + +struct built_in_curves { + struct built_in_curve curves[OPENSSL_NUM_BUILT_IN_CURVES]; +}; + +// OPENSSL_built_in_curves returns a pointer to static information about +// standard curves. The array is terminated with an entry where |nid| is +// |NID_undef|. +const struct built_in_curves *OPENSSL_built_in_curves(void); + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_EC_INTERNAL_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/ec/oct.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/ec/oct.c new file mode 100644 index 0000000..d4d0837 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/ec/oct.c @@ -0,0 +1,373 @@ +/* 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. */ + +#include + +#include +#include + +#include "internal.h" + + +static size_t ec_GFp_simple_point2oct(const EC_GROUP *group, + const EC_POINT *point, + point_conversion_form_t form, + uint8_t *buf, size_t len, BN_CTX *ctx) { + size_t ret = 0; + BN_CTX *new_ctx = NULL; + int used_ctx = 0; + + if ((form != POINT_CONVERSION_COMPRESSED) && + (form != POINT_CONVERSION_UNCOMPRESSED)) { + OPENSSL_PUT_ERROR(EC, EC_R_INVALID_FORM); + goto err; + } + + if (EC_POINT_is_at_infinity(group, point)) { + OPENSSL_PUT_ERROR(EC, EC_R_POINT_AT_INFINITY); + goto err; + } + + const size_t field_len = BN_num_bytes(&group->field); + size_t output_len = 1 /* type byte */ + field_len; + if (form == POINT_CONVERSION_UNCOMPRESSED) { + // Uncompressed points have a second coordinate. + output_len += field_len; + } + + // if 'buf' is NULL, just return required length + if (buf != NULL) { + if (len < output_len) { + OPENSSL_PUT_ERROR(EC, EC_R_BUFFER_TOO_SMALL); + goto err; + } + + if (ctx == NULL) { + ctx = new_ctx = BN_CTX_new(); + if (ctx == NULL) { + goto err; + } + } + + BN_CTX_start(ctx); + used_ctx = 1; + BIGNUM *x = BN_CTX_get(ctx); + BIGNUM *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) && + BN_is_odd(y)) { + buf[0] = form + 1; + } else { + buf[0] = form; + } + size_t i = 1; + + if (!BN_bn2bin_padded(buf + i, field_len, x)) { + OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR); + goto err; + } + i += field_len; + + if (form == POINT_CONVERSION_UNCOMPRESSED) { + if (!BN_bn2bin_padded(buf + i, field_len, y)) { + OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR); + goto err; + } + i += field_len; + } + + if (i != output_len) { + OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR); + goto err; + } + } + + ret = output_len; + +err: + if (used_ctx) { + BN_CTX_end(ctx); + } + BN_CTX_free(new_ctx); + return ret; +} + +static int ec_GFp_simple_oct2point(const EC_GROUP *group, EC_POINT *point, + const uint8_t *buf, size_t len, + BN_CTX *ctx) { + BN_CTX *new_ctx = NULL; + int ret = 0, used_ctx = 0; + + if (len == 0) { + OPENSSL_PUT_ERROR(EC, EC_R_BUFFER_TOO_SMALL); + goto err; + } + + point_conversion_form_t form = buf[0]; + const int y_bit = form & 1; + form = form & ~1U; + if ((form != POINT_CONVERSION_COMPRESSED && + form != POINT_CONVERSION_UNCOMPRESSED) || + (form == POINT_CONVERSION_UNCOMPRESSED && y_bit)) { + OPENSSL_PUT_ERROR(EC, EC_R_INVALID_ENCODING); + goto err; + } + + const size_t field_len = BN_num_bytes(&group->field); + size_t enc_len = 1 /* type byte */ + field_len; + if (form == POINT_CONVERSION_UNCOMPRESSED) { + // Uncompressed points have a second coordinate. + enc_len += field_len; + } + + if (len != enc_len) { + OPENSSL_PUT_ERROR(EC, EC_R_INVALID_ENCODING); + goto err; + } + + if (ctx == NULL) { + ctx = new_ctx = BN_CTX_new(); + if (ctx == NULL) { + goto err; + } + } + + BN_CTX_start(ctx); + used_ctx = 1; + BIGNUM *x = BN_CTX_get(ctx); + BIGNUM *y = BN_CTX_get(ctx); + if (x == NULL || y == NULL) { + goto err; + } + + if (!BN_bin2bn(buf + 1, field_len, x)) { + goto err; + } + if (BN_ucmp(x, &group->field) >= 0) { + OPENSSL_PUT_ERROR(EC, 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) { + OPENSSL_PUT_ERROR(EC, EC_R_INVALID_ENCODING); + goto err; + } + + if (!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx)) { + goto err; + } + } + + ret = 1; + +err: + if (used_ctx) { + BN_CTX_end(ctx); + } + BN_CTX_free(new_ctx); + return ret; +} + +int EC_POINT_oct2point(const EC_GROUP *group, EC_POINT *point, + const uint8_t *buf, size_t len, BN_CTX *ctx) { + if (EC_GROUP_cmp(group, point->group, NULL) != 0) { + OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + return ec_GFp_simple_oct2point(group, point, buf, len, ctx); +} + +size_t EC_POINT_point2oct(const EC_GROUP *group, const EC_POINT *point, + point_conversion_form_t form, uint8_t *buf, + size_t len, BN_CTX *ctx) { + if (EC_GROUP_cmp(group, point->group, NULL) != 0) { + OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + return ec_GFp_simple_point2oct(group, point, form, buf, len, ctx); +} + +int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *group, + EC_POINT *point, const BIGNUM *x, + int y_bit, BN_CTX *ctx) { + if (EC_GROUP_cmp(group, point->group, NULL) != 0) { + OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + + if (BN_is_negative(x) || BN_cmp(x, &group->field) >= 0) { + OPENSSL_PUT_ERROR(EC, EC_R_INVALID_COMPRESSED_POINT); + return 0; + } + + BN_CTX *new_ctx = NULL; + int ret = 0; + + 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); + BIGNUM *tmp1 = BN_CTX_get(ctx); + BIGNUM *tmp2 = BN_CTX_get(ctx); + BIGNUM *a = BN_CTX_get(ctx); + BIGNUM *b = BN_CTX_get(ctx); + BIGNUM *y = BN_CTX_get(ctx); + if (y == NULL || + !EC_GROUP_get_curve_GFp(group, NULL, a, b, ctx)) { + 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_mod_sqr(tmp2, x, &group->field, ctx) || + !BN_mod_mul(tmp1, tmp2, x, &group->field, ctx)) { + goto err; + } + + // tmp1 := tmp1 + a*x + if (group->a_is_minus3) { + if (!bn_mod_lshift1_consttime(tmp2, x, &group->field, ctx) || + !bn_mod_add_consttime(tmp2, tmp2, x, &group->field, ctx) || + !bn_mod_sub_consttime(tmp1, tmp1, tmp2, &group->field, ctx)) { + goto err; + } + } else { + if (!BN_mod_mul(tmp2, a, x, &group->field, ctx) || + !bn_mod_add_consttime(tmp1, tmp1, tmp2, &group->field, ctx)) { + goto err; + } + } + + // tmp1 := tmp1 + b + if (!bn_mod_add_consttime(tmp1, tmp1, b, &group->field, ctx)) { + 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(); + OPENSSL_PUT_ERROR(EC, EC_R_INVALID_COMPRESSED_POINT); + } else { + OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB); + } + goto err; + } + + if (y_bit != BN_is_odd(y)) { + if (BN_is_zero(y)) { + OPENSSL_PUT_ERROR(EC, EC_R_INVALID_COMPRESSION_BIT); + goto err; + } + if (!BN_usub(y, &group->field, y)) { + goto err; + } + } + if (y_bit != BN_is_odd(y)) { + OPENSSL_PUT_ERROR(EC, 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); + BN_CTX_free(new_ctx); + return ret; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/ec/oct.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/ec/oct.c.grpc_back new file mode 100644 index 0000000..19e17a7 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/ec/oct.c.grpc_back @@ -0,0 +1,373 @@ +/* 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. */ + +#include + +#include +#include + +#include "internal.h" + + +static size_t ec_GFp_simple_point2oct(const EC_GROUP *group, + const EC_POINT *point, + point_conversion_form_t form, + uint8_t *buf, size_t len, BN_CTX *ctx) { + size_t ret = 0; + BN_CTX *new_ctx = NULL; + int used_ctx = 0; + + if ((form != POINT_CONVERSION_COMPRESSED) && + (form != POINT_CONVERSION_UNCOMPRESSED)) { + OPENSSL_PUT_ERROR(EC, EC_R_INVALID_FORM); + goto err; + } + + if (EC_POINT_is_at_infinity(group, point)) { + OPENSSL_PUT_ERROR(EC, EC_R_POINT_AT_INFINITY); + goto err; + } + + const size_t field_len = BN_num_bytes(&group->field); + size_t output_len = 1 /* type byte */ + field_len; + if (form == POINT_CONVERSION_UNCOMPRESSED) { + // Uncompressed points have a second coordinate. + output_len += field_len; + } + + // if 'buf' is NULL, just return required length + if (buf != NULL) { + if (len < output_len) { + OPENSSL_PUT_ERROR(EC, EC_R_BUFFER_TOO_SMALL); + goto err; + } + + if (ctx == NULL) { + ctx = new_ctx = BN_CTX_new(); + if (ctx == NULL) { + goto err; + } + } + + BN_CTX_start(ctx); + used_ctx = 1; + BIGNUM *x = BN_CTX_get(ctx); + BIGNUM *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) && + BN_is_odd(y)) { + buf[0] = form + 1; + } else { + buf[0] = form; + } + size_t i = 1; + + if (!BN_bn2bin_padded(buf + i, field_len, x)) { + OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR); + goto err; + } + i += field_len; + + if (form == POINT_CONVERSION_UNCOMPRESSED) { + if (!BN_bn2bin_padded(buf + i, field_len, y)) { + OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR); + goto err; + } + i += field_len; + } + + if (i != output_len) { + OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR); + goto err; + } + } + + ret = output_len; + +err: + if (used_ctx) { + BN_CTX_end(ctx); + } + BN_CTX_free(new_ctx); + return ret; +} + +static int ec_GFp_simple_oct2point(const EC_GROUP *group, EC_POINT *point, + const uint8_t *buf, size_t len, + BN_CTX *ctx) { + BN_CTX *new_ctx = NULL; + int ret = 0, used_ctx = 0; + + if (len == 0) { + OPENSSL_PUT_ERROR(EC, EC_R_BUFFER_TOO_SMALL); + goto err; + } + + point_conversion_form_t form = buf[0]; + const int y_bit = form & 1; + form = form & ~1U; + if ((form != POINT_CONVERSION_COMPRESSED && + form != POINT_CONVERSION_UNCOMPRESSED) || + (form == POINT_CONVERSION_UNCOMPRESSED && y_bit)) { + OPENSSL_PUT_ERROR(EC, EC_R_INVALID_ENCODING); + goto err; + } + + const size_t field_len = BN_num_bytes(&group->field); + size_t enc_len = 1 /* type byte */ + field_len; + if (form == POINT_CONVERSION_UNCOMPRESSED) { + // Uncompressed points have a second coordinate. + enc_len += field_len; + } + + if (len != enc_len) { + OPENSSL_PUT_ERROR(EC, EC_R_INVALID_ENCODING); + goto err; + } + + if (ctx == NULL) { + ctx = new_ctx = BN_CTX_new(); + if (ctx == NULL) { + goto err; + } + } + + BN_CTX_start(ctx); + used_ctx = 1; + BIGNUM *x = BN_CTX_get(ctx); + BIGNUM *y = BN_CTX_get(ctx); + if (x == NULL || y == NULL) { + goto err; + } + + if (!BN_bin2bn(buf + 1, field_len, x)) { + goto err; + } + if (BN_ucmp(x, &group->field) >= 0) { + OPENSSL_PUT_ERROR(EC, 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) { + OPENSSL_PUT_ERROR(EC, EC_R_INVALID_ENCODING); + goto err; + } + + if (!EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx)) { + goto err; + } + } + + ret = 1; + +err: + if (used_ctx) { + BN_CTX_end(ctx); + } + BN_CTX_free(new_ctx); + return ret; +} + +int EC_POINT_oct2point(const EC_GROUP *group, EC_POINT *point, + const uint8_t *buf, size_t len, BN_CTX *ctx) { + if (EC_GROUP_cmp(group, point->group, NULL) != 0) { + OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + return ec_GFp_simple_oct2point(group, point, buf, len, ctx); +} + +size_t EC_POINT_point2oct(const EC_GROUP *group, const EC_POINT *point, + point_conversion_form_t form, uint8_t *buf, + size_t len, BN_CTX *ctx) { + if (EC_GROUP_cmp(group, point->group, NULL) != 0) { + OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + return ec_GFp_simple_point2oct(group, point, form, buf, len, ctx); +} + +int EC_POINT_set_compressed_coordinates_GFp(const EC_GROUP *group, + EC_POINT *point, const BIGNUM *x, + int y_bit, BN_CTX *ctx) { + if (EC_GROUP_cmp(group, point->group, NULL) != 0) { + OPENSSL_PUT_ERROR(EC, EC_R_INCOMPATIBLE_OBJECTS); + return 0; + } + + if (BN_is_negative(x) || BN_cmp(x, &group->field) >= 0) { + OPENSSL_PUT_ERROR(EC, EC_R_INVALID_COMPRESSED_POINT); + return 0; + } + + BN_CTX *new_ctx = NULL; + int ret = 0; + + 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); + BIGNUM *tmp1 = BN_CTX_get(ctx); + BIGNUM *tmp2 = BN_CTX_get(ctx); + BIGNUM *a = BN_CTX_get(ctx); + BIGNUM *b = BN_CTX_get(ctx); + BIGNUM *y = BN_CTX_get(ctx); + if (y == NULL || + !EC_GROUP_get_curve_GFp(group, NULL, a, b, ctx)) { + 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_mod_sqr(tmp2, x, &group->field, ctx) || + !BN_mod_mul(tmp1, tmp2, x, &group->field, ctx)) { + goto err; + } + + // tmp1 := tmp1 + a*x + if (group->a_is_minus3) { + if (!bn_mod_lshift1_consttime(tmp2, x, &group->field, ctx) || + !bn_mod_add_consttime(tmp2, tmp2, x, &group->field, ctx) || + !bn_mod_sub_consttime(tmp1, tmp1, tmp2, &group->field, ctx)) { + goto err; + } + } else { + if (!BN_mod_mul(tmp2, a, x, &group->field, ctx) || + !bn_mod_add_consttime(tmp1, tmp1, tmp2, &group->field, ctx)) { + goto err; + } + } + + // tmp1 := tmp1 + b + if (!bn_mod_add_consttime(tmp1, tmp1, b, &group->field, ctx)) { + 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(); + OPENSSL_PUT_ERROR(EC, EC_R_INVALID_COMPRESSED_POINT); + } else { + OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB); + } + goto err; + } + + if (y_bit != BN_is_odd(y)) { + if (BN_is_zero(y)) { + OPENSSL_PUT_ERROR(EC, EC_R_INVALID_COMPRESSION_BIT); + goto err; + } + if (!BN_usub(y, &group->field, y)) { + goto err; + } + } + if (y_bit != BN_is_odd(y)) { + OPENSSL_PUT_ERROR(EC, 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); + BN_CTX_free(new_ctx); + return ret; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/ec/p224-64.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/ec/p224-64.c new file mode 100644 index 0000000..0433b08 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/ec/p224-64.c @@ -0,0 +1,1104 @@ +/* Copyright (c) 2015, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +// 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 + +#include +#include +#include +#include + +#include + +#include "internal.h" +#include "../delocate.h" +#include "../../internal.h" + + +#if defined(BORINGSSL_HAS_UINT128) && !defined(OPENSSL_SMALL) + +// 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-p224_limb +// representation is an 'p224_felem'; a 7-p224_widelimb representation is a +// 'p224_widefelem'. Even within felems, bits of adjacent limbs overlap, and we +// don't always reduce the representations: we ensure that inputs to each +// p224_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 p224_felem satisfying a_i < +// 2^57. We only reduce to the unique minimal representation at the end of the +// computation. + +typedef uint64_t p224_limb; +typedef uint128_t p224_widelimb; + +typedef p224_limb p224_felem[4]; +typedef p224_widelimb p224_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 uint8_t p224_felem_bytearray[28]; + +// 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 p224_felem g_p224_pre_comp[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}}}}; + +static uint64_t p224_load_u64(const uint8_t in[8]) { + uint64_t ret; + OPENSSL_memcpy(&ret, in, sizeof(ret)); + return ret; +} + +// Helper functions to convert field elements to/from internal representation +static void p224_bin28_to_felem(p224_felem out, const uint8_t in[28]) { + out[0] = p224_load_u64(in) & 0x00ffffffffffffff; + out[1] = p224_load_u64(in + 7) & 0x00ffffffffffffff; + out[2] = p224_load_u64(in + 14) & 0x00ffffffffffffff; + out[3] = p224_load_u64(in + 20) >> 8; +} + +static void p224_felem_to_bin28(uint8_t out[28], const p224_felem in) { + for (size_t 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 p224_flip_endian(uint8_t *out, const uint8_t *in, size_t len) { + for (size_t i = 0; i < len; ++i) { + out[i] = in[len - 1 - i]; + } +} + +// From OpenSSL BIGNUM to internal representation +static int p224_BN_to_felem(p224_felem out, const BIGNUM *bn) { + // BN_bn2bin eats leading zeroes + p224_felem_bytearray b_out; + OPENSSL_memset(b_out, 0, sizeof(b_out)); + size_t num_bytes = BN_num_bytes(bn); + if (num_bytes > sizeof(b_out) || + BN_is_negative(bn)) { + OPENSSL_PUT_ERROR(EC, EC_R_BIGNUM_OUT_OF_RANGE); + return 0; + } + + p224_felem_bytearray b_in; + num_bytes = BN_bn2bin(bn, b_in); + p224_flip_endian(b_out, b_in, num_bytes); + p224_bin28_to_felem(out, b_out); + return 1; +} + +// From internal representation to OpenSSL BIGNUM +static BIGNUM *p224_felem_to_BN(BIGNUM *out, const p224_felem in) { + p224_felem_bytearray b_in, b_out; + p224_felem_to_bin28(b_in, in); + p224_flip_endian(b_out, b_in, sizeof(b_out)); + return BN_bin2bn(b_out, sizeof(b_out), out); +} + +// 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 p224_felem_assign(p224_felem out, const p224_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 p224_felem_sum(p224_felem out, const p224_felem in) { + out[0] += in[0]; + out[1] += in[1]; + out[2] += in[2]; + out[3] += in[3]; +} + +// Subtract field elements: out -= in +// Assumes in[i] < 2^57 +static void p224_felem_diff(p224_felem out, const p224_felem in) { + static const p224_limb two58p2 = + (((p224_limb)1) << 58) + (((p224_limb)1) << 2); + static const p224_limb two58m2 = + (((p224_limb)1) << 58) - (((p224_limb)1) << 2); + static const p224_limb two58m42m2 = + (((p224_limb)1) << 58) - (((p224_limb)1) << 42) - (((p224_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 p224_widefelem_diff(p224_widefelem out, const p224_widefelem in) { + static const p224_widelimb two120 = ((p224_widelimb)1) << 120; + static const p224_widelimb two120m64 = + (((p224_widelimb)1) << 120) - (((p224_widelimb)1) << 64); + static const p224_widelimb two120m104m64 = (((p224_widelimb)1) << 120) - + (((p224_widelimb)1) << 104) - + (((p224_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 p224_felem_diff_128_64(p224_widefelem out, const p224_felem in) { + static const p224_widelimb two64p8 = + (((p224_widelimb)1) << 64) + (((p224_widelimb)1) << 8); + static const p224_widelimb two64m8 = + (((p224_widelimb)1) << 64) - (((p224_widelimb)1) << 8); + static const p224_widelimb two64m48m8 = (((p224_widelimb)1) << 64) - + (((p224_widelimb)1) << 48) - + (((p224_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 p224_felem_scalar(p224_felem out, const p224_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 p224_widefelem_scalar(p224_widefelem out, + const p224_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 p224_felem_square(p224_widefelem out, const p224_felem in) { + p224_limb tmp0, tmp1, tmp2; + tmp0 = 2 * in[0]; + tmp1 = 2 * in[1]; + tmp2 = 2 * in[2]; + out[0] = ((p224_widelimb)in[0]) * in[0]; + out[1] = ((p224_widelimb)in[0]) * tmp1; + out[2] = ((p224_widelimb)in[0]) * tmp2 + ((p224_widelimb)in[1]) * in[1]; + out[3] = ((p224_widelimb)in[3]) * tmp0 + ((p224_widelimb)in[1]) * tmp2; + out[4] = ((p224_widelimb)in[3]) * tmp1 + ((p224_widelimb)in[2]) * in[2]; + out[5] = ((p224_widelimb)in[3]) * tmp2; + out[6] = ((p224_widelimb)in[3]) * in[3]; +} + +// Multiply two field elements: out = in1 * in2 +static void p224_felem_mul(p224_widefelem out, const p224_felem in1, + const p224_felem in2) { + out[0] = ((p224_widelimb)in1[0]) * in2[0]; + out[1] = ((p224_widelimb)in1[0]) * in2[1] + ((p224_widelimb)in1[1]) * in2[0]; + out[2] = ((p224_widelimb)in1[0]) * in2[2] + ((p224_widelimb)in1[1]) * in2[1] + + ((p224_widelimb)in1[2]) * in2[0]; + out[3] = ((p224_widelimb)in1[0]) * in2[3] + ((p224_widelimb)in1[1]) * in2[2] + + ((p224_widelimb)in1[2]) * in2[1] + ((p224_widelimb)in1[3]) * in2[0]; + out[4] = ((p224_widelimb)in1[1]) * in2[3] + ((p224_widelimb)in1[2]) * in2[2] + + ((p224_widelimb)in1[3]) * in2[1]; + out[5] = ((p224_widelimb)in1[2]) * in2[3] + ((p224_widelimb)in1[3]) * in2[2]; + out[6] = ((p224_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 p224_felem_reduce(p224_felem out, const p224_widefelem in) { + static const p224_widelimb two127p15 = + (((p224_widelimb)1) << 127) + (((p224_widelimb)1) << 15); + static const p224_widelimb two127m71 = + (((p224_widelimb)1) << 127) - (((p224_widelimb)1) << 71); + static const p224_widelimb two127m71m55 = (((p224_widelimb)1) << 127) - + (((p224_widelimb)1) << 71) - + (((p224_widelimb)1) << 55); + p224_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]; +} + +// Reduce to unique minimal representation. +// Requires 0 <= in < 2*p (always call p224_felem_reduce first) +static void p224_felem_contract(p224_felem out, const p224_felem in) { + static const int64_t two56 = ((p224_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]; +} + +// Get negative value: out = -in +// Requires in[i] < 2^63, +// ensures out[0] < 2^56, out[1] < 2^56, out[2] < 2^56, out[3] <= 2^56 + 2^16 +static void p224_felem_neg(p224_felem out, const p224_felem in) { + p224_widefelem tmp = {0}; + p224_felem_diff_128_64(tmp, in); + p224_felem_reduce(out, tmp); +} + +// 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 p224_limb p224_felem_is_zero(const p224_felem in) { + p224_limb zero = in[0] | in[1] | in[2] | in[3]; + zero = (((int64_t)(zero)-1) >> 63) & 1; + + p224_limb two224m96p1 = (in[0] ^ 1) | (in[1] ^ 0x00ffff0000000000) | + (in[2] ^ 0x00ffffffffffffff) | + (in[3] ^ 0x00ffffffffffffff); + two224m96p1 = (((int64_t)(two224m96p1)-1) >> 63) & 1; + p224_limb two225m97p2 = (in[0] ^ 2) | (in[1] ^ 0x00fffe0000000000) | + (in[2] ^ 0x00ffffffffffffff) | + (in[3] ^ 0x01ffffffffffffff); + two225m97p2 = (((int64_t)(two225m97p2)-1) >> 63) & 1; + return (zero | two224m96p1 | two225m97p2); +} + +// Invert a field element +// Computation chain copied from djb's code +static void p224_felem_inv(p224_felem out, const p224_felem in) { + p224_felem ftmp, ftmp2, ftmp3, ftmp4; + p224_widefelem tmp; + + p224_felem_square(tmp, in); + p224_felem_reduce(ftmp, tmp); // 2 + p224_felem_mul(tmp, in, ftmp); + p224_felem_reduce(ftmp, tmp); // 2^2 - 1 + p224_felem_square(tmp, ftmp); + p224_felem_reduce(ftmp, tmp); // 2^3 - 2 + p224_felem_mul(tmp, in, ftmp); + p224_felem_reduce(ftmp, tmp); // 2^3 - 1 + p224_felem_square(tmp, ftmp); + p224_felem_reduce(ftmp2, tmp); // 2^4 - 2 + p224_felem_square(tmp, ftmp2); + p224_felem_reduce(ftmp2, tmp); // 2^5 - 4 + p224_felem_square(tmp, ftmp2); + p224_felem_reduce(ftmp2, tmp); // 2^6 - 8 + p224_felem_mul(tmp, ftmp2, ftmp); + p224_felem_reduce(ftmp, tmp); // 2^6 - 1 + p224_felem_square(tmp, ftmp); + p224_felem_reduce(ftmp2, tmp); // 2^7 - 2 + for (size_t i = 0; i < 5; ++i) { // 2^12 - 2^6 + p224_felem_square(tmp, ftmp2); + p224_felem_reduce(ftmp2, tmp); + } + p224_felem_mul(tmp, ftmp2, ftmp); + p224_felem_reduce(ftmp2, tmp); // 2^12 - 1 + p224_felem_square(tmp, ftmp2); + p224_felem_reduce(ftmp3, tmp); // 2^13 - 2 + for (size_t i = 0; i < 11; ++i) { // 2^24 - 2^12 + p224_felem_square(tmp, ftmp3); + p224_felem_reduce(ftmp3, tmp); + } + p224_felem_mul(tmp, ftmp3, ftmp2); + p224_felem_reduce(ftmp2, tmp); // 2^24 - 1 + p224_felem_square(tmp, ftmp2); + p224_felem_reduce(ftmp3, tmp); // 2^25 - 2 + for (size_t i = 0; i < 23; ++i) { // 2^48 - 2^24 + p224_felem_square(tmp, ftmp3); + p224_felem_reduce(ftmp3, tmp); + } + p224_felem_mul(tmp, ftmp3, ftmp2); + p224_felem_reduce(ftmp3, tmp); // 2^48 - 1 + p224_felem_square(tmp, ftmp3); + p224_felem_reduce(ftmp4, tmp); // 2^49 - 2 + for (size_t i = 0; i < 47; ++i) { // 2^96 - 2^48 + p224_felem_square(tmp, ftmp4); + p224_felem_reduce(ftmp4, tmp); + } + p224_felem_mul(tmp, ftmp3, ftmp4); + p224_felem_reduce(ftmp3, tmp); // 2^96 - 1 + p224_felem_square(tmp, ftmp3); + p224_felem_reduce(ftmp4, tmp); // 2^97 - 2 + for (size_t i = 0; i < 23; ++i) { // 2^120 - 2^24 + p224_felem_square(tmp, ftmp4); + p224_felem_reduce(ftmp4, tmp); + } + p224_felem_mul(tmp, ftmp2, ftmp4); + p224_felem_reduce(ftmp2, tmp); // 2^120 - 1 + for (size_t i = 0; i < 6; ++i) { // 2^126 - 2^6 + p224_felem_square(tmp, ftmp2); + p224_felem_reduce(ftmp2, tmp); + } + p224_felem_mul(tmp, ftmp2, ftmp); + p224_felem_reduce(ftmp, tmp); // 2^126 - 1 + p224_felem_square(tmp, ftmp); + p224_felem_reduce(ftmp, tmp); // 2^127 - 2 + p224_felem_mul(tmp, ftmp, in); + p224_felem_reduce(ftmp, tmp); // 2^127 - 1 + for (size_t i = 0; i < 97; ++i) { // 2^224 - 2^97 + p224_felem_square(tmp, ftmp); + p224_felem_reduce(ftmp, tmp); + } + p224_felem_mul(tmp, ftmp, ftmp3); + p224_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 p224_copy_conditional(p224_felem out, const p224_felem in, + p224_limb icopy) { + // icopy is a (64-bit) 0 or 1, so copy is either all-zero or all-one + const p224_limb copy = -icopy; + for (size_t i = 0; i < 4; ++i) { + const p224_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 p224_point_double(p224_felem x_out, p224_felem y_out, + p224_felem z_out, const p224_felem x_in, + const p224_felem y_in, const p224_felem z_in) { + p224_widefelem tmp, tmp2; + p224_felem delta, gamma, beta, alpha, ftmp, ftmp2; + + p224_felem_assign(ftmp, x_in); + p224_felem_assign(ftmp2, x_in); + + // delta = z^2 + p224_felem_square(tmp, z_in); + p224_felem_reduce(delta, tmp); + + // gamma = y^2 + p224_felem_square(tmp, y_in); + p224_felem_reduce(gamma, tmp); + + // beta = x*gamma + p224_felem_mul(tmp, x_in, gamma); + p224_felem_reduce(beta, tmp); + + // alpha = 3*(x-delta)*(x+delta) + p224_felem_diff(ftmp, delta); + // ftmp[i] < 2^57 + 2^58 + 2 < 2^59 + p224_felem_sum(ftmp2, delta); + // ftmp2[i] < 2^57 + 2^57 = 2^58 + p224_felem_scalar(ftmp2, 3); + // ftmp2[i] < 3 * 2^58 < 2^60 + p224_felem_mul(tmp, ftmp, ftmp2); + // tmp[i] < 2^60 * 2^59 * 4 = 2^121 + p224_felem_reduce(alpha, tmp); + + // x' = alpha^2 - 8*beta + p224_felem_square(tmp, alpha); + // tmp[i] < 4 * 2^57 * 2^57 = 2^116 + p224_felem_assign(ftmp, beta); + p224_felem_scalar(ftmp, 8); + // ftmp[i] < 8 * 2^57 = 2^60 + p224_felem_diff_128_64(tmp, ftmp); + // tmp[i] < 2^116 + 2^64 + 8 < 2^117 + p224_felem_reduce(x_out, tmp); + + // z' = (y + z)^2 - gamma - delta + p224_felem_sum(delta, gamma); + // delta[i] < 2^57 + 2^57 = 2^58 + p224_felem_assign(ftmp, y_in); + p224_felem_sum(ftmp, z_in); + // ftmp[i] < 2^57 + 2^57 = 2^58 + p224_felem_square(tmp, ftmp); + // tmp[i] < 4 * 2^58 * 2^58 = 2^118 + p224_felem_diff_128_64(tmp, delta); + // tmp[i] < 2^118 + 2^64 + 8 < 2^119 + p224_felem_reduce(z_out, tmp); + + // y' = alpha*(4*beta - x') - 8*gamma^2 + p224_felem_scalar(beta, 4); + // beta[i] < 4 * 2^57 = 2^59 + p224_felem_diff(beta, x_out); + // beta[i] < 2^59 + 2^58 + 2 < 2^60 + p224_felem_mul(tmp, alpha, beta); + // tmp[i] < 4 * 2^57 * 2^60 = 2^119 + p224_felem_square(tmp2, gamma); + // tmp2[i] < 4 * 2^57 * 2^57 = 2^116 + p224_widefelem_scalar(tmp2, 8); + // tmp2[i] < 8 * 2^116 = 2^119 + p224_widefelem_diff(tmp, tmp2); + // tmp[i] < 2^119 + 2^120 < 2^121 + p224_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 p224_point_add(p224_felem x3, p224_felem y3, p224_felem z3, + const p224_felem x1, const p224_felem y1, + const p224_felem z1, const int mixed, + const p224_felem x2, const p224_felem y2, + const p224_felem z2) { + p224_felem ftmp, ftmp2, ftmp3, ftmp4, ftmp5, x_out, y_out, z_out; + p224_widefelem tmp, tmp2; + p224_limb z1_is_zero, z2_is_zero, x_equal, y_equal; + + if (!mixed) { + // ftmp2 = z2^2 + p224_felem_square(tmp, z2); + p224_felem_reduce(ftmp2, tmp); + + // ftmp4 = z2^3 + p224_felem_mul(tmp, ftmp2, z2); + p224_felem_reduce(ftmp4, tmp); + + // ftmp4 = z2^3*y1 + p224_felem_mul(tmp2, ftmp4, y1); + p224_felem_reduce(ftmp4, tmp2); + + // ftmp2 = z2^2*x1 + p224_felem_mul(tmp2, ftmp2, x1); + p224_felem_reduce(ftmp2, tmp2); + } else { + // We'll assume z2 = 1 (special case z2 = 0 is handled later) + + // ftmp4 = z2^3*y1 + p224_felem_assign(ftmp4, y1); + + // ftmp2 = z2^2*x1 + p224_felem_assign(ftmp2, x1); + } + + // ftmp = z1^2 + p224_felem_square(tmp, z1); + p224_felem_reduce(ftmp, tmp); + + // ftmp3 = z1^3 + p224_felem_mul(tmp, ftmp, z1); + p224_felem_reduce(ftmp3, tmp); + + // tmp = z1^3*y2 + p224_felem_mul(tmp, ftmp3, y2); + // tmp[i] < 4 * 2^57 * 2^57 = 2^116 + + // ftmp3 = z1^3*y2 - z2^3*y1 + p224_felem_diff_128_64(tmp, ftmp4); + // tmp[i] < 2^116 + 2^64 + 8 < 2^117 + p224_felem_reduce(ftmp3, tmp); + + // tmp = z1^2*x2 + p224_felem_mul(tmp, ftmp, x2); + // tmp[i] < 4 * 2^57 * 2^57 = 2^116 + + // ftmp = z1^2*x2 - z2^2*x1 + p224_felem_diff_128_64(tmp, ftmp2); + // tmp[i] < 2^116 + 2^64 + 8 < 2^117 + p224_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 = p224_felem_is_zero(ftmp); + y_equal = p224_felem_is_zero(ftmp3); + z1_is_zero = p224_felem_is_zero(z1); + z2_is_zero = p224_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) { + p224_point_double(x3, y3, z3, x1, y1, z1); + return; + } + + // ftmp5 = z1*z2 + if (!mixed) { + p224_felem_mul(tmp, z1, z2); + p224_felem_reduce(ftmp5, tmp); + } else { + // special case z2 = 0 is handled later + p224_felem_assign(ftmp5, z1); + } + + // z_out = (z1^2*x2 - z2^2*x1)*(z1*z2) + p224_felem_mul(tmp, ftmp, ftmp5); + p224_felem_reduce(z_out, tmp); + + // ftmp = (z1^2*x2 - z2^2*x1)^2 + p224_felem_assign(ftmp5, ftmp); + p224_felem_square(tmp, ftmp); + p224_felem_reduce(ftmp, tmp); + + // ftmp5 = (z1^2*x2 - z2^2*x1)^3 + p224_felem_mul(tmp, ftmp, ftmp5); + p224_felem_reduce(ftmp5, tmp); + + // ftmp2 = z2^2*x1*(z1^2*x2 - z2^2*x1)^2 + p224_felem_mul(tmp, ftmp2, ftmp); + p224_felem_reduce(ftmp2, tmp); + + // tmp = z2^3*y1*(z1^2*x2 - z2^2*x1)^3 + p224_felem_mul(tmp, ftmp4, ftmp5); + // tmp[i] < 4 * 2^57 * 2^57 = 2^116 + + // tmp2 = (z1^3*y2 - z2^3*y1)^2 + p224_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 + p224_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 + p224_felem_assign(ftmp5, ftmp2); + p224_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 */ + p224_felem_diff_128_64(tmp2, ftmp5); + // tmp2[i] < 2^117 + 2^64 + 8 < 2^118 + p224_felem_reduce(x_out, tmp2); + + // ftmp2 = z2^2*x1*(z1^2*x2 - z2^2*x1)^2 - x_out + p224_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) + p224_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 */ + p224_widefelem_diff(tmp2, tmp); + // tmp2[i] < 2^118 + 2^120 < 2^121 + p224_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 + p224_copy_conditional(x_out, x2, z1_is_zero); + p224_copy_conditional(x_out, x1, z2_is_zero); + p224_copy_conditional(y_out, y2, z1_is_zero); + p224_copy_conditional(y_out, y1, z2_is_zero); + p224_copy_conditional(z_out, z2, z1_is_zero); + p224_copy_conditional(z_out, z1, z2_is_zero); + p224_felem_assign(x3, x_out); + p224_felem_assign(y3, y_out); + p224_felem_assign(z3, z_out); +} + +// p224_select_point selects the |idx|th point from a precomputation table and +// copies it to out. +static void p224_select_point(const uint64_t idx, size_t size, + const p224_felem pre_comp[/*size*/][3], + p224_felem out[3]) { + p224_limb *outlimbs = &out[0][0]; + OPENSSL_memset(outlimbs, 0, 3 * sizeof(p224_felem)); + + for (size_t i = 0; i < size; i++) { + const p224_limb *inlimbs = &pre_comp[i][0][0]; + uint64_t mask = i ^ idx; + mask |= mask >> 4; + mask |= mask >> 2; + mask |= mask >> 1; + mask &= 1; + mask--; + for (size_t j = 0; j < 4 * 3; j++) { + outlimbs[j] |= inlimbs[j] & mask; + } + } +} + +// p224_get_bit returns the |i|th bit in |in| +static char p224_get_bit(const p224_felem_bytearray in, size_t 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 p_pre_comp, the scalars +// in p_scalar, if non-NULL. If g_scalar is non-NULL, we also add this multiple +// of the generator, using certain (large) precomputed multiples in +// g_p224_pre_comp. Output point (X, Y, Z) is stored in x_out, y_out, z_out +static void p224_batch_mul(p224_felem x_out, p224_felem y_out, p224_felem z_out, + const uint8_t *p_scalar, const uint8_t *g_scalar, + const p224_felem p_pre_comp[17][3]) { + p224_felem nq[3], tmp[4]; + uint64_t bits; + uint8_t sign, digit; + + // set nq to the point at infinity + OPENSSL_memset(nq, 0, 3 * sizeof(p224_felem)); + + // Loop over both scalars msb-to-lsb, interleaving additions of multiples of + // the generator (two in each of the last 28 rounds) and additions of p (every + // 5th round). + int skip = 1; // save two point operations in the first round + size_t i = p_scalar != NULL ? 220 : 27; + for (;;) { + // double + if (!skip) { + p224_point_double(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2]); + } + + // add multiples of the generator + if (g_scalar != NULL && i <= 27) { + // first, look 28 bits upwards + bits = p224_get_bit(g_scalar, i + 196) << 3; + bits |= p224_get_bit(g_scalar, i + 140) << 2; + bits |= p224_get_bit(g_scalar, i + 84) << 1; + bits |= p224_get_bit(g_scalar, i + 28); + // select the point to add, in constant time + p224_select_point(bits, 16, g_p224_pre_comp[1], tmp); + + if (!skip) { + p224_point_add(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2], 1 /* mixed */, + tmp[0], tmp[1], tmp[2]); + } else { + OPENSSL_memcpy(nq, tmp, 3 * sizeof(p224_felem)); + skip = 0; + } + + // second, look at the current position + bits = p224_get_bit(g_scalar, i + 168) << 3; + bits |= p224_get_bit(g_scalar, i + 112) << 2; + bits |= p224_get_bit(g_scalar, i + 56) << 1; + bits |= p224_get_bit(g_scalar, i); + // select the point to add, in constant time + p224_select_point(bits, 16, g_p224_pre_comp[0], tmp); + p224_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 (p_scalar != NULL && i % 5 == 0) { + bits = p224_get_bit(p_scalar, i + 4) << 5; + bits |= p224_get_bit(p_scalar, i + 3) << 4; + bits |= p224_get_bit(p_scalar, i + 2) << 3; + bits |= p224_get_bit(p_scalar, i + 1) << 2; + bits |= p224_get_bit(p_scalar, i) << 1; + bits |= p224_get_bit(p_scalar, i - 1); + ec_GFp_nistp_recode_scalar_bits(&sign, &digit, bits); + + // select the point to add or subtract + p224_select_point(digit, 17, p_pre_comp, tmp); + p224_felem_neg(tmp[3], tmp[1]); // (X, -Y, Z) is the negative point + p224_copy_conditional(tmp[1], tmp[3], sign); + + if (!skip) { + p224_point_add(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2], 0 /* mixed */, + tmp[0], tmp[1], tmp[2]); + } else { + OPENSSL_memcpy(nq, tmp, 3 * sizeof(p224_felem)); + skip = 0; + } + } + + if (i == 0) { + break; + } + --i; + } + p224_felem_assign(x_out, nq[0]); + p224_felem_assign(y_out, nq[1]); + p224_felem_assign(z_out, nq[2]); +} + +// Takes the Jacobian coordinates (X, Y, Z) of a point and returns +// (X', Y') = (X/Z^2, Y/Z^3) +static int ec_GFp_nistp224_point_get_affine_coordinates(const EC_GROUP *group, + const EC_POINT *point, + BIGNUM *x, BIGNUM *y, + BN_CTX *ctx) { + p224_felem z1, z2, x_in, y_in, x_out, y_out; + p224_widefelem tmp; + + if (EC_POINT_is_at_infinity(group, point)) { + OPENSSL_PUT_ERROR(EC, EC_R_POINT_AT_INFINITY); + return 0; + } + + if (!p224_BN_to_felem(x_in, &point->X) || + !p224_BN_to_felem(y_in, &point->Y) || + !p224_BN_to_felem(z1, &point->Z)) { + return 0; + } + + p224_felem_inv(z2, z1); + p224_felem_square(tmp, z2); + p224_felem_reduce(z1, tmp); + + if (x != NULL) { + p224_felem_mul(tmp, x_in, z1); + p224_felem_reduce(x_in, tmp); + p224_felem_contract(x_out, x_in); + if (!p224_felem_to_BN(x, x_out)) { + OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB); + return 0; + } + } + + if (y != NULL) { + p224_felem_mul(tmp, z1, z2); + p224_felem_reduce(z1, tmp); + p224_felem_mul(tmp, y_in, z1); + p224_felem_reduce(y_in, tmp); + p224_felem_contract(y_out, y_in); + if (!p224_felem_to_BN(y, y_out)) { + OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB); + return 0; + } + } + + return 1; +} + +static int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r, + const EC_SCALAR *g_scalar, + const EC_POINT *p, + const EC_SCALAR *p_scalar, BN_CTX *ctx) { + p224_felem p_pre_comp[17][3]; + p224_felem x_in, y_in, z_in, x_out, y_out, z_out; + + if (p != NULL && p_scalar != NULL) { + // We treat NULL scalars as 0, and NULL points as points at infinity, i.e., + // they contribute nothing to the linear combination. + OPENSSL_memset(&p_pre_comp, 0, sizeof(p_pre_comp)); + // precompute multiples + if (!p224_BN_to_felem(x_out, &p->X) || + !p224_BN_to_felem(y_out, &p->Y) || + !p224_BN_to_felem(z_out, &p->Z)) { + return 0; + } + + p224_felem_assign(p_pre_comp[1][0], x_out); + p224_felem_assign(p_pre_comp[1][1], y_out); + p224_felem_assign(p_pre_comp[1][2], z_out); + + for (size_t j = 2; j <= 16; ++j) { + if (j & 1) { + p224_point_add(p_pre_comp[j][0], p_pre_comp[j][1], p_pre_comp[j][2], + p_pre_comp[1][0], p_pre_comp[1][1], p_pre_comp[1][2], + 0, p_pre_comp[j - 1][0], p_pre_comp[j - 1][1], + p_pre_comp[j - 1][2]); + } else { + p224_point_double(p_pre_comp[j][0], p_pre_comp[j][1], + p_pre_comp[j][2], p_pre_comp[j / 2][0], + p_pre_comp[j / 2][1], p_pre_comp[j / 2][2]); + } + } + } + + p224_batch_mul(x_out, y_out, z_out, + (p != NULL && p_scalar != NULL) ? p_scalar->bytes : NULL, + g_scalar != NULL ? g_scalar->bytes : NULL, + (const p224_felem(*)[3])p_pre_comp); + + // reduce the output to its unique minimal representation + p224_felem_contract(x_in, x_out); + p224_felem_contract(y_in, y_out); + p224_felem_contract(z_in, z_out); + if (!p224_felem_to_BN(&r->X, x_in) || + !p224_felem_to_BN(&r->Y, y_in) || + !p224_felem_to_BN(&r->Z, z_in)) { + OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB); + return 0; + } + return 1; +} + +DEFINE_METHOD_FUNCTION(EC_METHOD, EC_GFp_nistp224_method) { + out->group_init = ec_GFp_simple_group_init; + out->group_finish = ec_GFp_simple_group_finish; + out->group_set_curve = ec_GFp_simple_group_set_curve; + out->point_get_affine_coordinates = + ec_GFp_nistp224_point_get_affine_coordinates; + out->mul = ec_GFp_nistp224_points_mul; + out->mul_public = ec_GFp_nistp224_points_mul; + out->field_mul = ec_GFp_simple_field_mul; + out->field_sqr = ec_GFp_simple_field_sqr; + out->field_encode = NULL; + out->field_decode = NULL; +}; + +#endif // BORINGSSL_HAS_UINT128 && !SMALL diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/ec/p224-64.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/ec/p224-64.c.grpc_back new file mode 100644 index 0000000..028197b --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/ec/p224-64.c.grpc_back @@ -0,0 +1,1104 @@ +/* Copyright (c) 2015, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +// 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 + +#include +#include +#include +#include + +#include + +#include "internal.h" +#include "../delocate.h" +#include "../../internal.h" + + +#if defined(BORINGSSL_HAS_UINT128) && !defined(OPENSSL_SMALL) + +// 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-p224_limb +// representation is an 'p224_felem'; a 7-p224_widelimb representation is a +// 'p224_widefelem'. Even within felems, bits of adjacent limbs overlap, and we +// don't always reduce the representations: we ensure that inputs to each +// p224_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 p224_felem satisfying a_i < +// 2^57. We only reduce to the unique minimal representation at the end of the +// computation. + +typedef uint64_t p224_limb; +typedef uint128_t p224_widelimb; + +typedef p224_limb p224_felem[4]; +typedef p224_widelimb p224_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 uint8_t p224_felem_bytearray[28]; + +// 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 p224_felem g_p224_pre_comp[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}}}}; + +static uint64_t p224_load_u64(const uint8_t in[8]) { + uint64_t ret; + OPENSSL_memcpy(&ret, in, sizeof(ret)); + return ret; +} + +// Helper functions to convert field elements to/from internal representation +static void p224_bin28_to_felem(p224_felem out, const uint8_t in[28]) { + out[0] = p224_load_u64(in) & 0x00ffffffffffffff; + out[1] = p224_load_u64(in + 7) & 0x00ffffffffffffff; + out[2] = p224_load_u64(in + 14) & 0x00ffffffffffffff; + out[3] = p224_load_u64(in + 20) >> 8; +} + +static void p224_felem_to_bin28(uint8_t out[28], const p224_felem in) { + for (size_t 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 p224_flip_endian(uint8_t *out, const uint8_t *in, size_t len) { + for (size_t i = 0; i < len; ++i) { + out[i] = in[len - 1 - i]; + } +} + +// From OpenSSL BIGNUM to internal representation +static int p224_BN_to_felem(p224_felem out, const BIGNUM *bn) { + // BN_bn2bin eats leading zeroes + p224_felem_bytearray b_out; + OPENSSL_memset(b_out, 0, sizeof(b_out)); + size_t num_bytes = BN_num_bytes(bn); + if (num_bytes > sizeof(b_out) || + BN_is_negative(bn)) { + OPENSSL_PUT_ERROR(EC, EC_R_BIGNUM_OUT_OF_RANGE); + return 0; + } + + p224_felem_bytearray b_in; + num_bytes = BN_bn2bin(bn, b_in); + p224_flip_endian(b_out, b_in, num_bytes); + p224_bin28_to_felem(out, b_out); + return 1; +} + +// From internal representation to OpenSSL BIGNUM +static BIGNUM *p224_felem_to_BN(BIGNUM *out, const p224_felem in) { + p224_felem_bytearray b_in, b_out; + p224_felem_to_bin28(b_in, in); + p224_flip_endian(b_out, b_in, sizeof(b_out)); + return BN_bin2bn(b_out, sizeof(b_out), out); +} + +// 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 p224_felem_assign(p224_felem out, const p224_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 p224_felem_sum(p224_felem out, const p224_felem in) { + out[0] += in[0]; + out[1] += in[1]; + out[2] += in[2]; + out[3] += in[3]; +} + +// Subtract field elements: out -= in +// Assumes in[i] < 2^57 +static void p224_felem_diff(p224_felem out, const p224_felem in) { + static const p224_limb two58p2 = + (((p224_limb)1) << 58) + (((p224_limb)1) << 2); + static const p224_limb two58m2 = + (((p224_limb)1) << 58) - (((p224_limb)1) << 2); + static const p224_limb two58m42m2 = + (((p224_limb)1) << 58) - (((p224_limb)1) << 42) - (((p224_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 p224_widefelem_diff(p224_widefelem out, const p224_widefelem in) { + static const p224_widelimb two120 = ((p224_widelimb)1) << 120; + static const p224_widelimb two120m64 = + (((p224_widelimb)1) << 120) - (((p224_widelimb)1) << 64); + static const p224_widelimb two120m104m64 = (((p224_widelimb)1) << 120) - + (((p224_widelimb)1) << 104) - + (((p224_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 p224_felem_diff_128_64(p224_widefelem out, const p224_felem in) { + static const p224_widelimb two64p8 = + (((p224_widelimb)1) << 64) + (((p224_widelimb)1) << 8); + static const p224_widelimb two64m8 = + (((p224_widelimb)1) << 64) - (((p224_widelimb)1) << 8); + static const p224_widelimb two64m48m8 = (((p224_widelimb)1) << 64) - + (((p224_widelimb)1) << 48) - + (((p224_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 p224_felem_scalar(p224_felem out, const p224_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 p224_widefelem_scalar(p224_widefelem out, + const p224_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 p224_felem_square(p224_widefelem out, const p224_felem in) { + p224_limb tmp0, tmp1, tmp2; + tmp0 = 2 * in[0]; + tmp1 = 2 * in[1]; + tmp2 = 2 * in[2]; + out[0] = ((p224_widelimb)in[0]) * in[0]; + out[1] = ((p224_widelimb)in[0]) * tmp1; + out[2] = ((p224_widelimb)in[0]) * tmp2 + ((p224_widelimb)in[1]) * in[1]; + out[3] = ((p224_widelimb)in[3]) * tmp0 + ((p224_widelimb)in[1]) * tmp2; + out[4] = ((p224_widelimb)in[3]) * tmp1 + ((p224_widelimb)in[2]) * in[2]; + out[5] = ((p224_widelimb)in[3]) * tmp2; + out[6] = ((p224_widelimb)in[3]) * in[3]; +} + +// Multiply two field elements: out = in1 * in2 +static void p224_felem_mul(p224_widefelem out, const p224_felem in1, + const p224_felem in2) { + out[0] = ((p224_widelimb)in1[0]) * in2[0]; + out[1] = ((p224_widelimb)in1[0]) * in2[1] + ((p224_widelimb)in1[1]) * in2[0]; + out[2] = ((p224_widelimb)in1[0]) * in2[2] + ((p224_widelimb)in1[1]) * in2[1] + + ((p224_widelimb)in1[2]) * in2[0]; + out[3] = ((p224_widelimb)in1[0]) * in2[3] + ((p224_widelimb)in1[1]) * in2[2] + + ((p224_widelimb)in1[2]) * in2[1] + ((p224_widelimb)in1[3]) * in2[0]; + out[4] = ((p224_widelimb)in1[1]) * in2[3] + ((p224_widelimb)in1[2]) * in2[2] + + ((p224_widelimb)in1[3]) * in2[1]; + out[5] = ((p224_widelimb)in1[2]) * in2[3] + ((p224_widelimb)in1[3]) * in2[2]; + out[6] = ((p224_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 p224_felem_reduce(p224_felem out, const p224_widefelem in) { + static const p224_widelimb two127p15 = + (((p224_widelimb)1) << 127) + (((p224_widelimb)1) << 15); + static const p224_widelimb two127m71 = + (((p224_widelimb)1) << 127) - (((p224_widelimb)1) << 71); + static const p224_widelimb two127m71m55 = (((p224_widelimb)1) << 127) - + (((p224_widelimb)1) << 71) - + (((p224_widelimb)1) << 55); + p224_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]; +} + +// Reduce to unique minimal representation. +// Requires 0 <= in < 2*p (always call p224_felem_reduce first) +static void p224_felem_contract(p224_felem out, const p224_felem in) { + static const int64_t two56 = ((p224_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]; +} + +// Get negative value: out = -in +// Requires in[i] < 2^63, +// ensures out[0] < 2^56, out[1] < 2^56, out[2] < 2^56, out[3] <= 2^56 + 2^16 +static void p224_felem_neg(p224_felem out, const p224_felem in) { + p224_widefelem tmp = {0}; + p224_felem_diff_128_64(tmp, in); + p224_felem_reduce(out, tmp); +} + +// 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 p224_limb p224_felem_is_zero(const p224_felem in) { + p224_limb zero = in[0] | in[1] | in[2] | in[3]; + zero = (((int64_t)(zero)-1) >> 63) & 1; + + p224_limb two224m96p1 = (in[0] ^ 1) | (in[1] ^ 0x00ffff0000000000) | + (in[2] ^ 0x00ffffffffffffff) | + (in[3] ^ 0x00ffffffffffffff); + two224m96p1 = (((int64_t)(two224m96p1)-1) >> 63) & 1; + p224_limb two225m97p2 = (in[0] ^ 2) | (in[1] ^ 0x00fffe0000000000) | + (in[2] ^ 0x00ffffffffffffff) | + (in[3] ^ 0x01ffffffffffffff); + two225m97p2 = (((int64_t)(two225m97p2)-1) >> 63) & 1; + return (zero | two224m96p1 | two225m97p2); +} + +// Invert a field element +// Computation chain copied from djb's code +static void p224_felem_inv(p224_felem out, const p224_felem in) { + p224_felem ftmp, ftmp2, ftmp3, ftmp4; + p224_widefelem tmp; + + p224_felem_square(tmp, in); + p224_felem_reduce(ftmp, tmp); // 2 + p224_felem_mul(tmp, in, ftmp); + p224_felem_reduce(ftmp, tmp); // 2^2 - 1 + p224_felem_square(tmp, ftmp); + p224_felem_reduce(ftmp, tmp); // 2^3 - 2 + p224_felem_mul(tmp, in, ftmp); + p224_felem_reduce(ftmp, tmp); // 2^3 - 1 + p224_felem_square(tmp, ftmp); + p224_felem_reduce(ftmp2, tmp); // 2^4 - 2 + p224_felem_square(tmp, ftmp2); + p224_felem_reduce(ftmp2, tmp); // 2^5 - 4 + p224_felem_square(tmp, ftmp2); + p224_felem_reduce(ftmp2, tmp); // 2^6 - 8 + p224_felem_mul(tmp, ftmp2, ftmp); + p224_felem_reduce(ftmp, tmp); // 2^6 - 1 + p224_felem_square(tmp, ftmp); + p224_felem_reduce(ftmp2, tmp); // 2^7 - 2 + for (size_t i = 0; i < 5; ++i) { // 2^12 - 2^6 + p224_felem_square(tmp, ftmp2); + p224_felem_reduce(ftmp2, tmp); + } + p224_felem_mul(tmp, ftmp2, ftmp); + p224_felem_reduce(ftmp2, tmp); // 2^12 - 1 + p224_felem_square(tmp, ftmp2); + p224_felem_reduce(ftmp3, tmp); // 2^13 - 2 + for (size_t i = 0; i < 11; ++i) { // 2^24 - 2^12 + p224_felem_square(tmp, ftmp3); + p224_felem_reduce(ftmp3, tmp); + } + p224_felem_mul(tmp, ftmp3, ftmp2); + p224_felem_reduce(ftmp2, tmp); // 2^24 - 1 + p224_felem_square(tmp, ftmp2); + p224_felem_reduce(ftmp3, tmp); // 2^25 - 2 + for (size_t i = 0; i < 23; ++i) { // 2^48 - 2^24 + p224_felem_square(tmp, ftmp3); + p224_felem_reduce(ftmp3, tmp); + } + p224_felem_mul(tmp, ftmp3, ftmp2); + p224_felem_reduce(ftmp3, tmp); // 2^48 - 1 + p224_felem_square(tmp, ftmp3); + p224_felem_reduce(ftmp4, tmp); // 2^49 - 2 + for (size_t i = 0; i < 47; ++i) { // 2^96 - 2^48 + p224_felem_square(tmp, ftmp4); + p224_felem_reduce(ftmp4, tmp); + } + p224_felem_mul(tmp, ftmp3, ftmp4); + p224_felem_reduce(ftmp3, tmp); // 2^96 - 1 + p224_felem_square(tmp, ftmp3); + p224_felem_reduce(ftmp4, tmp); // 2^97 - 2 + for (size_t i = 0; i < 23; ++i) { // 2^120 - 2^24 + p224_felem_square(tmp, ftmp4); + p224_felem_reduce(ftmp4, tmp); + } + p224_felem_mul(tmp, ftmp2, ftmp4); + p224_felem_reduce(ftmp2, tmp); // 2^120 - 1 + for (size_t i = 0; i < 6; ++i) { // 2^126 - 2^6 + p224_felem_square(tmp, ftmp2); + p224_felem_reduce(ftmp2, tmp); + } + p224_felem_mul(tmp, ftmp2, ftmp); + p224_felem_reduce(ftmp, tmp); // 2^126 - 1 + p224_felem_square(tmp, ftmp); + p224_felem_reduce(ftmp, tmp); // 2^127 - 2 + p224_felem_mul(tmp, ftmp, in); + p224_felem_reduce(ftmp, tmp); // 2^127 - 1 + for (size_t i = 0; i < 97; ++i) { // 2^224 - 2^97 + p224_felem_square(tmp, ftmp); + p224_felem_reduce(ftmp, tmp); + } + p224_felem_mul(tmp, ftmp, ftmp3); + p224_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 p224_copy_conditional(p224_felem out, const p224_felem in, + p224_limb icopy) { + // icopy is a (64-bit) 0 or 1, so copy is either all-zero or all-one + const p224_limb copy = -icopy; + for (size_t i = 0; i < 4; ++i) { + const p224_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 p224_point_double(p224_felem x_out, p224_felem y_out, + p224_felem z_out, const p224_felem x_in, + const p224_felem y_in, const p224_felem z_in) { + p224_widefelem tmp, tmp2; + p224_felem delta, gamma, beta, alpha, ftmp, ftmp2; + + p224_felem_assign(ftmp, x_in); + p224_felem_assign(ftmp2, x_in); + + // delta = z^2 + p224_felem_square(tmp, z_in); + p224_felem_reduce(delta, tmp); + + // gamma = y^2 + p224_felem_square(tmp, y_in); + p224_felem_reduce(gamma, tmp); + + // beta = x*gamma + p224_felem_mul(tmp, x_in, gamma); + p224_felem_reduce(beta, tmp); + + // alpha = 3*(x-delta)*(x+delta) + p224_felem_diff(ftmp, delta); + // ftmp[i] < 2^57 + 2^58 + 2 < 2^59 + p224_felem_sum(ftmp2, delta); + // ftmp2[i] < 2^57 + 2^57 = 2^58 + p224_felem_scalar(ftmp2, 3); + // ftmp2[i] < 3 * 2^58 < 2^60 + p224_felem_mul(tmp, ftmp, ftmp2); + // tmp[i] < 2^60 * 2^59 * 4 = 2^121 + p224_felem_reduce(alpha, tmp); + + // x' = alpha^2 - 8*beta + p224_felem_square(tmp, alpha); + // tmp[i] < 4 * 2^57 * 2^57 = 2^116 + p224_felem_assign(ftmp, beta); + p224_felem_scalar(ftmp, 8); + // ftmp[i] < 8 * 2^57 = 2^60 + p224_felem_diff_128_64(tmp, ftmp); + // tmp[i] < 2^116 + 2^64 + 8 < 2^117 + p224_felem_reduce(x_out, tmp); + + // z' = (y + z)^2 - gamma - delta + p224_felem_sum(delta, gamma); + // delta[i] < 2^57 + 2^57 = 2^58 + p224_felem_assign(ftmp, y_in); + p224_felem_sum(ftmp, z_in); + // ftmp[i] < 2^57 + 2^57 = 2^58 + p224_felem_square(tmp, ftmp); + // tmp[i] < 4 * 2^58 * 2^58 = 2^118 + p224_felem_diff_128_64(tmp, delta); + // tmp[i] < 2^118 + 2^64 + 8 < 2^119 + p224_felem_reduce(z_out, tmp); + + // y' = alpha*(4*beta - x') - 8*gamma^2 + p224_felem_scalar(beta, 4); + // beta[i] < 4 * 2^57 = 2^59 + p224_felem_diff(beta, x_out); + // beta[i] < 2^59 + 2^58 + 2 < 2^60 + p224_felem_mul(tmp, alpha, beta); + // tmp[i] < 4 * 2^57 * 2^60 = 2^119 + p224_felem_square(tmp2, gamma); + // tmp2[i] < 4 * 2^57 * 2^57 = 2^116 + p224_widefelem_scalar(tmp2, 8); + // tmp2[i] < 8 * 2^116 = 2^119 + p224_widefelem_diff(tmp, tmp2); + // tmp[i] < 2^119 + 2^120 < 2^121 + p224_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 p224_point_add(p224_felem x3, p224_felem y3, p224_felem z3, + const p224_felem x1, const p224_felem y1, + const p224_felem z1, const int mixed, + const p224_felem x2, const p224_felem y2, + const p224_felem z2) { + p224_felem ftmp, ftmp2, ftmp3, ftmp4, ftmp5, x_out, y_out, z_out; + p224_widefelem tmp, tmp2; + p224_limb z1_is_zero, z2_is_zero, x_equal, y_equal; + + if (!mixed) { + // ftmp2 = z2^2 + p224_felem_square(tmp, z2); + p224_felem_reduce(ftmp2, tmp); + + // ftmp4 = z2^3 + p224_felem_mul(tmp, ftmp2, z2); + p224_felem_reduce(ftmp4, tmp); + + // ftmp4 = z2^3*y1 + p224_felem_mul(tmp2, ftmp4, y1); + p224_felem_reduce(ftmp4, tmp2); + + // ftmp2 = z2^2*x1 + p224_felem_mul(tmp2, ftmp2, x1); + p224_felem_reduce(ftmp2, tmp2); + } else { + // We'll assume z2 = 1 (special case z2 = 0 is handled later) + + // ftmp4 = z2^3*y1 + p224_felem_assign(ftmp4, y1); + + // ftmp2 = z2^2*x1 + p224_felem_assign(ftmp2, x1); + } + + // ftmp = z1^2 + p224_felem_square(tmp, z1); + p224_felem_reduce(ftmp, tmp); + + // ftmp3 = z1^3 + p224_felem_mul(tmp, ftmp, z1); + p224_felem_reduce(ftmp3, tmp); + + // tmp = z1^3*y2 + p224_felem_mul(tmp, ftmp3, y2); + // tmp[i] < 4 * 2^57 * 2^57 = 2^116 + + // ftmp3 = z1^3*y2 - z2^3*y1 + p224_felem_diff_128_64(tmp, ftmp4); + // tmp[i] < 2^116 + 2^64 + 8 < 2^117 + p224_felem_reduce(ftmp3, tmp); + + // tmp = z1^2*x2 + p224_felem_mul(tmp, ftmp, x2); + // tmp[i] < 4 * 2^57 * 2^57 = 2^116 + + // ftmp = z1^2*x2 - z2^2*x1 + p224_felem_diff_128_64(tmp, ftmp2); + // tmp[i] < 2^116 + 2^64 + 8 < 2^117 + p224_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 = p224_felem_is_zero(ftmp); + y_equal = p224_felem_is_zero(ftmp3); + z1_is_zero = p224_felem_is_zero(z1); + z2_is_zero = p224_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) { + p224_point_double(x3, y3, z3, x1, y1, z1); + return; + } + + // ftmp5 = z1*z2 + if (!mixed) { + p224_felem_mul(tmp, z1, z2); + p224_felem_reduce(ftmp5, tmp); + } else { + // special case z2 = 0 is handled later + p224_felem_assign(ftmp5, z1); + } + + // z_out = (z1^2*x2 - z2^2*x1)*(z1*z2) + p224_felem_mul(tmp, ftmp, ftmp5); + p224_felem_reduce(z_out, tmp); + + // ftmp = (z1^2*x2 - z2^2*x1)^2 + p224_felem_assign(ftmp5, ftmp); + p224_felem_square(tmp, ftmp); + p224_felem_reduce(ftmp, tmp); + + // ftmp5 = (z1^2*x2 - z2^2*x1)^3 + p224_felem_mul(tmp, ftmp, ftmp5); + p224_felem_reduce(ftmp5, tmp); + + // ftmp2 = z2^2*x1*(z1^2*x2 - z2^2*x1)^2 + p224_felem_mul(tmp, ftmp2, ftmp); + p224_felem_reduce(ftmp2, tmp); + + // tmp = z2^3*y1*(z1^2*x2 - z2^2*x1)^3 + p224_felem_mul(tmp, ftmp4, ftmp5); + // tmp[i] < 4 * 2^57 * 2^57 = 2^116 + + // tmp2 = (z1^3*y2 - z2^3*y1)^2 + p224_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 + p224_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 + p224_felem_assign(ftmp5, ftmp2); + p224_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 */ + p224_felem_diff_128_64(tmp2, ftmp5); + // tmp2[i] < 2^117 + 2^64 + 8 < 2^118 + p224_felem_reduce(x_out, tmp2); + + // ftmp2 = z2^2*x1*(z1^2*x2 - z2^2*x1)^2 - x_out + p224_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) + p224_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 */ + p224_widefelem_diff(tmp2, tmp); + // tmp2[i] < 2^118 + 2^120 < 2^121 + p224_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 + p224_copy_conditional(x_out, x2, z1_is_zero); + p224_copy_conditional(x_out, x1, z2_is_zero); + p224_copy_conditional(y_out, y2, z1_is_zero); + p224_copy_conditional(y_out, y1, z2_is_zero); + p224_copy_conditional(z_out, z2, z1_is_zero); + p224_copy_conditional(z_out, z1, z2_is_zero); + p224_felem_assign(x3, x_out); + p224_felem_assign(y3, y_out); + p224_felem_assign(z3, z_out); +} + +// p224_select_point selects the |idx|th point from a precomputation table and +// copies it to out. +static void p224_select_point(const uint64_t idx, size_t size, + const p224_felem pre_comp[/*size*/][3], + p224_felem out[3]) { + p224_limb *outlimbs = &out[0][0]; + OPENSSL_memset(outlimbs, 0, 3 * sizeof(p224_felem)); + + for (size_t i = 0; i < size; i++) { + const p224_limb *inlimbs = &pre_comp[i][0][0]; + uint64_t mask = i ^ idx; + mask |= mask >> 4; + mask |= mask >> 2; + mask |= mask >> 1; + mask &= 1; + mask--; + for (size_t j = 0; j < 4 * 3; j++) { + outlimbs[j] |= inlimbs[j] & mask; + } + } +} + +// p224_get_bit returns the |i|th bit in |in| +static char p224_get_bit(const p224_felem_bytearray in, size_t 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 p_pre_comp, the scalars +// in p_scalar, if non-NULL. If g_scalar is non-NULL, we also add this multiple +// of the generator, using certain (large) precomputed multiples in +// g_p224_pre_comp. Output point (X, Y, Z) is stored in x_out, y_out, z_out +static void p224_batch_mul(p224_felem x_out, p224_felem y_out, p224_felem z_out, + const uint8_t *p_scalar, const uint8_t *g_scalar, + const p224_felem p_pre_comp[17][3]) { + p224_felem nq[3], tmp[4]; + uint64_t bits; + uint8_t sign, digit; + + // set nq to the point at infinity + OPENSSL_memset(nq, 0, 3 * sizeof(p224_felem)); + + // Loop over both scalars msb-to-lsb, interleaving additions of multiples of + // the generator (two in each of the last 28 rounds) and additions of p (every + // 5th round). + int skip = 1; // save two point operations in the first round + size_t i = p_scalar != NULL ? 220 : 27; + for (;;) { + // double + if (!skip) { + p224_point_double(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2]); + } + + // add multiples of the generator + if (g_scalar != NULL && i <= 27) { + // first, look 28 bits upwards + bits = p224_get_bit(g_scalar, i + 196) << 3; + bits |= p224_get_bit(g_scalar, i + 140) << 2; + bits |= p224_get_bit(g_scalar, i + 84) << 1; + bits |= p224_get_bit(g_scalar, i + 28); + // select the point to add, in constant time + p224_select_point(bits, 16, g_p224_pre_comp[1], tmp); + + if (!skip) { + p224_point_add(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2], 1 /* mixed */, + tmp[0], tmp[1], tmp[2]); + } else { + OPENSSL_memcpy(nq, tmp, 3 * sizeof(p224_felem)); + skip = 0; + } + + // second, look at the current position + bits = p224_get_bit(g_scalar, i + 168) << 3; + bits |= p224_get_bit(g_scalar, i + 112) << 2; + bits |= p224_get_bit(g_scalar, i + 56) << 1; + bits |= p224_get_bit(g_scalar, i); + // select the point to add, in constant time + p224_select_point(bits, 16, g_p224_pre_comp[0], tmp); + p224_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 (p_scalar != NULL && i % 5 == 0) { + bits = p224_get_bit(p_scalar, i + 4) << 5; + bits |= p224_get_bit(p_scalar, i + 3) << 4; + bits |= p224_get_bit(p_scalar, i + 2) << 3; + bits |= p224_get_bit(p_scalar, i + 1) << 2; + bits |= p224_get_bit(p_scalar, i) << 1; + bits |= p224_get_bit(p_scalar, i - 1); + ec_GFp_nistp_recode_scalar_bits(&sign, &digit, bits); + + // select the point to add or subtract + p224_select_point(digit, 17, p_pre_comp, tmp); + p224_felem_neg(tmp[3], tmp[1]); // (X, -Y, Z) is the negative point + p224_copy_conditional(tmp[1], tmp[3], sign); + + if (!skip) { + p224_point_add(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2], 0 /* mixed */, + tmp[0], tmp[1], tmp[2]); + } else { + OPENSSL_memcpy(nq, tmp, 3 * sizeof(p224_felem)); + skip = 0; + } + } + + if (i == 0) { + break; + } + --i; + } + p224_felem_assign(x_out, nq[0]); + p224_felem_assign(y_out, nq[1]); + p224_felem_assign(z_out, nq[2]); +} + +// Takes the Jacobian coordinates (X, Y, Z) of a point and returns +// (X', Y') = (X/Z^2, Y/Z^3) +static int ec_GFp_nistp224_point_get_affine_coordinates(const EC_GROUP *group, + const EC_POINT *point, + BIGNUM *x, BIGNUM *y, + BN_CTX *ctx) { + p224_felem z1, z2, x_in, y_in, x_out, y_out; + p224_widefelem tmp; + + if (EC_POINT_is_at_infinity(group, point)) { + OPENSSL_PUT_ERROR(EC, EC_R_POINT_AT_INFINITY); + return 0; + } + + if (!p224_BN_to_felem(x_in, &point->X) || + !p224_BN_to_felem(y_in, &point->Y) || + !p224_BN_to_felem(z1, &point->Z)) { + return 0; + } + + p224_felem_inv(z2, z1); + p224_felem_square(tmp, z2); + p224_felem_reduce(z1, tmp); + + if (x != NULL) { + p224_felem_mul(tmp, x_in, z1); + p224_felem_reduce(x_in, tmp); + p224_felem_contract(x_out, x_in); + if (!p224_felem_to_BN(x, x_out)) { + OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB); + return 0; + } + } + + if (y != NULL) { + p224_felem_mul(tmp, z1, z2); + p224_felem_reduce(z1, tmp); + p224_felem_mul(tmp, y_in, z1); + p224_felem_reduce(y_in, tmp); + p224_felem_contract(y_out, y_in); + if (!p224_felem_to_BN(y, y_out)) { + OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB); + return 0; + } + } + + return 1; +} + +static int ec_GFp_nistp224_points_mul(const EC_GROUP *group, EC_POINT *r, + const EC_SCALAR *g_scalar, + const EC_POINT *p, + const EC_SCALAR *p_scalar, BN_CTX *ctx) { + p224_felem p_pre_comp[17][3]; + p224_felem x_in, y_in, z_in, x_out, y_out, z_out; + + if (p != NULL && p_scalar != NULL) { + // We treat NULL scalars as 0, and NULL points as points at infinity, i.e., + // they contribute nothing to the linear combination. + OPENSSL_memset(&p_pre_comp, 0, sizeof(p_pre_comp)); + // precompute multiples + if (!p224_BN_to_felem(x_out, &p->X) || + !p224_BN_to_felem(y_out, &p->Y) || + !p224_BN_to_felem(z_out, &p->Z)) { + return 0; + } + + p224_felem_assign(p_pre_comp[1][0], x_out); + p224_felem_assign(p_pre_comp[1][1], y_out); + p224_felem_assign(p_pre_comp[1][2], z_out); + + for (size_t j = 2; j <= 16; ++j) { + if (j & 1) { + p224_point_add(p_pre_comp[j][0], p_pre_comp[j][1], p_pre_comp[j][2], + p_pre_comp[1][0], p_pre_comp[1][1], p_pre_comp[1][2], + 0, p_pre_comp[j - 1][0], p_pre_comp[j - 1][1], + p_pre_comp[j - 1][2]); + } else { + p224_point_double(p_pre_comp[j][0], p_pre_comp[j][1], + p_pre_comp[j][2], p_pre_comp[j / 2][0], + p_pre_comp[j / 2][1], p_pre_comp[j / 2][2]); + } + } + } + + p224_batch_mul(x_out, y_out, z_out, + (p != NULL && p_scalar != NULL) ? p_scalar->bytes : NULL, + g_scalar != NULL ? g_scalar->bytes : NULL, + (const p224_felem(*)[3])p_pre_comp); + + // reduce the output to its unique minimal representation + p224_felem_contract(x_in, x_out); + p224_felem_contract(y_in, y_out); + p224_felem_contract(z_in, z_out); + if (!p224_felem_to_BN(&r->X, x_in) || + !p224_felem_to_BN(&r->Y, y_in) || + !p224_felem_to_BN(&r->Z, z_in)) { + OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB); + return 0; + } + return 1; +} + +DEFINE_METHOD_FUNCTION(EC_METHOD, EC_GFp_nistp224_method) { + out->group_init = ec_GFp_simple_group_init; + out->group_finish = ec_GFp_simple_group_finish; + out->group_set_curve = ec_GFp_simple_group_set_curve; + out->point_get_affine_coordinates = + ec_GFp_nistp224_point_get_affine_coordinates; + out->mul = ec_GFp_nistp224_points_mul; + out->mul_public = ec_GFp_nistp224_points_mul; + out->field_mul = ec_GFp_simple_field_mul; + out->field_sqr = ec_GFp_simple_field_sqr; + out->field_encode = NULL; + out->field_decode = NULL; +}; + +#endif // BORINGSSL_HAS_UINT128 && !SMALL diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/ec/p256-x86_64-table.h b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/ec/p256-x86_64-table.h new file mode 100644 index 0000000..bcb05f6 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/ec/p256-x86_64-table.h @@ -0,0 +1,9503 @@ +/* Copyright (c) 2015, Intel Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +// This is the precomputed constant time access table for the code in +// p256-x86_64.c, for the default generator. The table consists of 37 +// subtables, each subtable contains 64 affine points. The affine points are +// encoded as eight uint64's, four for the x coordinate and four for the y. +// Both values are in little-endian order. There are 37 tables because a +// signed, 6-bit wNAF form of the scalar is used and ceil(256/(6 + 1)) = 37. +// Within each table there are 64 values because the 6-bit wNAF value can take +// 64 values, ignoring the sign bit, which is implemented by performing a +// negation of the affine point when required. We would like to align it to 2MB +// in order to increase the chances of using a large page but that appears to +// lead to invalid ELF files being produced. + +// This file is generated by make_p256-x86_64-table.go. + +static const alignas(4096) BN_ULONG + ecp_nistz256_precomputed[37][64 * sizeof(P256_POINT_AFFINE) / + sizeof(BN_ULONG)] = { + {TOBN(0x79e730d4, 0x18a9143c), TOBN(0x75ba95fc, 0x5fedb601), + TOBN(0x79fb732b, 0x77622510), TOBN(0x18905f76, 0xa53755c6), + TOBN(0xddf25357, 0xce95560a), TOBN(0x8b4ab8e4, 0xba19e45c), + TOBN(0xd2e88688, 0xdd21f325), TOBN(0x8571ff18, 0x25885d85), + TOBN(0x850046d4, 0x10ddd64d), TOBN(0xaa6ae3c1, 0xa433827d), + TOBN(0x73220503, 0x8d1490d9), TOBN(0xf6bb32e4, 0x3dcf3a3b), + TOBN(0x2f3648d3, 0x61bee1a5), TOBN(0x152cd7cb, 0xeb236ff8), + TOBN(0x19a8fb0e, 0x92042dbe), TOBN(0x78c57751, 0x0a5b8a3b), + TOBN(0xffac3f90, 0x4eebc127), TOBN(0xb027f84a, 0x087d81fb), + TOBN(0x66ad77dd, 0x87cbbc98), TOBN(0x26936a3f, 0xb6ff747e), + TOBN(0xb04c5c1f, 0xc983a7eb), TOBN(0x583e47ad, 0x0861fe1a), + TOBN(0x78820831, 0x1a2ee98e), TOBN(0xd5f06a29, 0xe587cc07), + TOBN(0x74b0b50d, 0x46918dcc), TOBN(0x4650a6ed, 0xc623c173), + TOBN(0x0cdaacac, 0xe8100af2), TOBN(0x577362f5, 0x41b0176b), + TOBN(0x2d96f24c, 0xe4cbaba6), TOBN(0x17628471, 0xfad6f447), + TOBN(0x6b6c36de, 0xe5ddd22e), TOBN(0x84b14c39, 0x4c5ab863), + TOBN(0xbe1b8aae, 0xc45c61f5), TOBN(0x90ec649a, 0x94b9537d), + TOBN(0x941cb5aa, 0xd076c20c), TOBN(0xc9079605, 0x890523c8), + TOBN(0xeb309b4a, 0xe7ba4f10), TOBN(0x73c568ef, 0xe5eb882b), + TOBN(0x3540a987, 0x7e7a1f68), TOBN(0x73a076bb, 0x2dd1e916), + TOBN(0x40394737, 0x3e77664a), TOBN(0x55ae744f, 0x346cee3e), + TOBN(0xd50a961a, 0x5b17a3ad), TOBN(0x13074b59, 0x54213673), + TOBN(0x93d36220, 0xd377e44b), TOBN(0x299c2b53, 0xadff14b5), + TOBN(0xf424d44c, 0xef639f11), TOBN(0xa4c9916d, 0x4a07f75f), + TOBN(0x0746354e, 0xa0173b4f), TOBN(0x2bd20213, 0xd23c00f7), + TOBN(0xf43eaab5, 0x0c23bb08), TOBN(0x13ba5119, 0xc3123e03), + TOBN(0x2847d030, 0x3f5b9d4d), TOBN(0x6742f2f2, 0x5da67bdd), + TOBN(0xef933bdc, 0x77c94195), TOBN(0xeaedd915, 0x6e240867), + TOBN(0x27f14cd1, 0x9499a78f), TOBN(0x462ab5c5, 0x6f9b3455), + TOBN(0x8f90f02a, 0xf02cfc6b), TOBN(0xb763891e, 0xb265230d), + TOBN(0xf59da3a9, 0x532d4977), TOBN(0x21e3327d, 0xcf9eba15), + TOBN(0x123c7b84, 0xbe60bbf0), TOBN(0x56ec12f2, 0x7706df76), + TOBN(0x75c96e8f, 0x264e20e8), TOBN(0xabe6bfed, 0x59a7a841), + TOBN(0x2cc09c04, 0x44c8eb00), TOBN(0xe05b3080, 0xf0c4e16b), + TOBN(0x1eb7777a, 0xa45f3314), TOBN(0x56af7bed, 0xce5d45e3), + TOBN(0x2b6e019a, 0x88b12f1a), TOBN(0x086659cd, 0xfd835f9b), + TOBN(0x2c18dbd1, 0x9dc21ec8), TOBN(0x98f9868a, 0x0fcf8139), + TOBN(0x737d2cd6, 0x48250b49), TOBN(0xcc61c947, 0x24b3428f), + TOBN(0x0c2b4078, 0x80dd9e76), TOBN(0xc43a8991, 0x383fbe08), + TOBN(0x5f7d2d65, 0x779be5d2), TOBN(0x78719a54, 0xeb3b4ab5), + TOBN(0xea7d260a, 0x6245e404), TOBN(0x9de40795, 0x6e7fdfe0), + TOBN(0x1ff3a415, 0x8dac1ab5), TOBN(0x3e7090f1, 0x649c9073), + TOBN(0x1a768561, 0x2b944e88), TOBN(0x250f939e, 0xe57f61c8), + TOBN(0x0c0daa89, 0x1ead643d), TOBN(0x68930023, 0xe125b88e), + TOBN(0x04b71aa7, 0xd2697768), TOBN(0xabdedef5, 0xca345a33), + TOBN(0x2409d29d, 0xee37385e), TOBN(0x4ee1df77, 0xcb83e156), + TOBN(0x0cac12d9, 0x1cbb5b43), TOBN(0x170ed2f6, 0xca895637), + TOBN(0x28228cfa, 0x8ade6d66), TOBN(0x7ff57c95, 0x53238aca), + TOBN(0xccc42563, 0x4b2ed709), TOBN(0x0e356769, 0x856fd30d), + TOBN(0xbcbcd43f, 0x559e9811), TOBN(0x738477ac, 0x5395b759), + TOBN(0x35752b90, 0xc00ee17f), TOBN(0x68748390, 0x742ed2e3), + TOBN(0x7cd06422, 0xbd1f5bc1), TOBN(0xfbc08769, 0xc9e7b797), + TOBN(0xa242a35b, 0xb0cf664a), TOBN(0x126e48f7, 0x7f9707e3), + TOBN(0x1717bf54, 0xc6832660), TOBN(0xfaae7332, 0xfd12c72e), + TOBN(0x27b52db7, 0x995d586b), TOBN(0xbe29569e, 0x832237c2), + TOBN(0xe8e4193e, 0x2a65e7db), TOBN(0x152706dc, 0x2eaa1bbb), + TOBN(0x72bcd8b7, 0xbc60055b), TOBN(0x03cc23ee, 0x56e27e4b), + TOBN(0xee337424, 0xe4819370), TOBN(0xe2aa0e43, 0x0ad3da09), + TOBN(0x40b8524f, 0x6383c45d), TOBN(0xd7663554, 0x42a41b25), + TOBN(0x64efa6de, 0x778a4797), TOBN(0x2042170a, 0x7079adf4), + TOBN(0x808b0b65, 0x0bc6fb80), TOBN(0x5882e075, 0x3ffe2e6b), + TOBN(0xd5ef2f7c, 0x2c83f549), TOBN(0x54d63c80, 0x9103b723), + TOBN(0xf2f11bd6, 0x52a23f9b), TOBN(0x3670c319, 0x4b0b6587), + TOBN(0x55c4623b, 0xb1580e9e), TOBN(0x64edf7b2, 0x01efe220), + TOBN(0x97091dcb, 0xd53c5c9d), TOBN(0xf17624b6, 0xac0a177b), + TOBN(0xb0f13975, 0x2cfe2dff), TOBN(0xc1a35c0a, 0x6c7a574e), + TOBN(0x227d3146, 0x93e79987), TOBN(0x0575bf30, 0xe89cb80e), + TOBN(0x2f4e247f, 0x0d1883bb), TOBN(0xebd51226, 0x3274c3d0), + TOBN(0x5f3e51c8, 0x56ada97a), TOBN(0x4afc964d, 0x8f8b403e), + TOBN(0xa6f247ab, 0x412e2979), TOBN(0x675abd1b, 0x6f80ebda), + TOBN(0x66a2bd72, 0x5e485a1d), TOBN(0x4b2a5caf, 0x8f4f0b3c), + TOBN(0x2626927f, 0x1b847bba), TOBN(0x6c6fc7d9, 0x0502394d), + TOBN(0xfea912ba, 0xa5659ae8), TOBN(0x68363aba, 0x25e1a16e), + TOBN(0xb8842277, 0x752c41ac), TOBN(0xfe545c28, 0x2897c3fc), + TOBN(0x2d36e9e7, 0xdc4c696b), TOBN(0x5806244a, 0xfba977c5), + TOBN(0x85665e9b, 0xe39508c1), TOBN(0xf720ee25, 0x6d12597b), + TOBN(0x8a979129, 0xd2337a31), TOBN(0x5916868f, 0x0f862bdc), + TOBN(0x048099d9, 0x5dd283ba), TOBN(0xe2d1eeb6, 0xfe5bfb4e), + TOBN(0x82ef1c41, 0x7884005d), TOBN(0xa2d4ec17, 0xffffcbae), + TOBN(0x9161c53f, 0x8aa95e66), TOBN(0x5ee104e1, 0xc5fee0d0), + TOBN(0x562e4cec, 0xc135b208), TOBN(0x74e1b265, 0x4783f47d), + TOBN(0x6d2a506c, 0x5a3f3b30), TOBN(0xecead9f4, 0xc16762fc), + TOBN(0xf29dd4b2, 0xe286e5b9), TOBN(0x1b0fadc0, 0x83bb3c61), + TOBN(0x7a75023e, 0x7fac29a4), TOBN(0xc086d5f1, 0xc9477fa3), + TOBN(0x0fc61135, 0x2f6f3076), TOBN(0xc99ffa23, 0xe3912a9a), + TOBN(0x6a0b0685, 0xd2f8ba3d), TOBN(0xfdc777e8, 0xe93358a4), + TOBN(0x94a787bb, 0x35415f04), TOBN(0x640c2d6a, 0x4d23fea4), + TOBN(0x9de917da, 0x153a35b5), TOBN(0x793e8d07, 0x5d5cd074), + TOBN(0xf4f87653, 0x2de45068), TOBN(0x37c7a7e8, 0x9e2e1f6e), + TOBN(0xd0825fa2, 0xa3584069), TOBN(0xaf2cea7c, 0x1727bf42), + TOBN(0x0360a4fb, 0x9e4785a9), TOBN(0xe5fda49c, 0x27299f4a), + TOBN(0x48068e13, 0x71ac2f71), TOBN(0x83d0687b, 0x9077666f), + TOBN(0x6d3883b2, 0x15d02819), TOBN(0x6d0d7550, 0x40dd9a35), + TOBN(0x61d7cbf9, 0x1d2b469f), TOBN(0xf97b232f, 0x2efc3115), + TOBN(0xa551d750, 0xb24bcbc7), TOBN(0x11ea4949, 0x88a1e356), + TOBN(0x7669f031, 0x93cb7501), TOBN(0x595dc55e, 0xca737b8a), + TOBN(0xa4a319ac, 0xd837879f), TOBN(0x6fc1b49e, 0xed6b67b0), + TOBN(0xe3959933, 0x32f1f3af), TOBN(0x966742eb, 0x65432a2e), + TOBN(0x4b8dc9fe, 0xb4966228), TOBN(0x96cc6312, 0x43f43950), + TOBN(0x12068859, 0xc9b731ee), TOBN(0x7b948dc3, 0x56f79968), + TOBN(0x61e4ad32, 0xed1f8008), TOBN(0xe6c9267a, 0xd8b17538), + TOBN(0x1ac7c5eb, 0x857ff6fb), TOBN(0x994baaa8, 0x55f2fb10), + TOBN(0x84cf14e1, 0x1d248018), TOBN(0x5a39898b, 0x628ac508), + TOBN(0x14fde97b, 0x5fa944f5), TOBN(0xed178030, 0xd12e5ac7), + TOBN(0x042c2af4, 0x97e2feb4), TOBN(0xd36a42d7, 0xaebf7313), + TOBN(0x49d2c9eb, 0x084ffdd7), TOBN(0x9f8aa54b, 0x2ef7c76a), + TOBN(0x9200b7ba, 0x09895e70), TOBN(0x3bd0c66f, 0xddb7fb58), + TOBN(0x2d97d108, 0x78eb4cbb), TOBN(0x2d431068, 0xd84bde31), + TOBN(0x4b523eb7, 0x172ccd1f), TOBN(0x7323cb28, 0x30a6a892), + TOBN(0x97082ec0, 0xcfe153eb), TOBN(0xe97f6b6a, 0xf2aadb97), + TOBN(0x1d3d393e, 0xd1a83da1), TOBN(0xa6a7f9c7, 0x804b2a68), + TOBN(0x4a688b48, 0x2d0cb71e), TOBN(0xa9b4cc5f, 0x40585278), + TOBN(0x5e5db46a, 0xcb66e132), TOBN(0xf1be963a, 0x0d925880), + TOBN(0x944a7027, 0x0317b9e2), TOBN(0xe266f959, 0x48603d48), + TOBN(0x98db6673, 0x5c208899), TOBN(0x90472447, 0xa2fb18a3), + TOBN(0x8a966939, 0x777c619f), TOBN(0x3798142a, 0x2a3be21b), + TOBN(0xb4241cb1, 0x3298b343), TOBN(0xa3a14e49, 0xb44f65a1), + TOBN(0xc5f4d6cd, 0x3ac77acd), TOBN(0xd0288cb5, 0x52b6fc3c), + TOBN(0xd5cc8c2f, 0x1c040abc), TOBN(0xb675511e, 0x06bf9b4a), + TOBN(0xd667da37, 0x9b3aa441), TOBN(0x460d45ce, 0x51601f72), + TOBN(0xe2f73c69, 0x6755ff89), TOBN(0xdd3cf7e7, 0x473017e6), + TOBN(0x8ef5689d, 0x3cf7600d), TOBN(0x948dc4f8, 0xb1fc87b4), + TOBN(0xd9e9fe81, 0x4ea53299), TOBN(0x2d921ca2, 0x98eb6028), + TOBN(0xfaecedfd, 0x0c9803fc), TOBN(0xf38ae891, 0x4d7b4745), + TOBN(0xd8c5fccf, 0xc5e3a3d8), TOBN(0xbefd904c, 0x4079dfbf), + TOBN(0xbc6d6a58, 0xfead0197), TOBN(0x39227077, 0x695532a4), + TOBN(0x09e23e6d, 0xdbef42f5), TOBN(0x7e449b64, 0x480a9908), + TOBN(0x7b969c1a, 0xad9a2e40), TOBN(0x6231d792, 0x9591c2a4), + TOBN(0x87151456, 0x0f664534), TOBN(0x85ceae7c, 0x4b68f103), + TOBN(0xac09c4ae, 0x65578ab9), TOBN(0x33ec6868, 0xf044b10c), + TOBN(0x6ac4832b, 0x3a8ec1f1), TOBN(0x5509d128, 0x5847d5ef), + TOBN(0xf909604f, 0x763f1574), TOBN(0xb16c4303, 0xc32f63c4), + TOBN(0xb6ab2014, 0x7ca23cd3), TOBN(0xcaa7a5c6, 0xa391849d), + TOBN(0x5b0673a3, 0x75678d94), TOBN(0xc982ddd4, 0xdd303e64), + TOBN(0xfd7b000b, 0x5db6f971), TOBN(0xbba2cb1f, 0x6f876f92), + TOBN(0xc77332a3, 0x3c569426), TOBN(0xa159100c, 0x570d74f8), + TOBN(0xfd16847f, 0xdec67ef5), TOBN(0x742ee464, 0x233e76b7), + TOBN(0x0b8e4134, 0xefc2b4c8), TOBN(0xca640b86, 0x42a3e521), + TOBN(0x653a0190, 0x8ceb6aa9), TOBN(0x313c300c, 0x547852d5), + TOBN(0x24e4ab12, 0x6b237af7), TOBN(0x2ba90162, 0x8bb47af8), + TOBN(0x3d5e58d6, 0xa8219bb7), TOBN(0xc691d0bd, 0x1b06c57f), + TOBN(0x0ae4cb10, 0xd257576e), TOBN(0x3569656c, 0xd54a3dc3), + TOBN(0xe5ebaebd, 0x94cda03a), TOBN(0x934e82d3, 0x162bfe13), + TOBN(0x450ac0ba, 0xe251a0c6), TOBN(0x480b9e11, 0xdd6da526), + TOBN(0x00467bc5, 0x8cce08b5), TOBN(0xb636458c, 0x7f178d55), + TOBN(0xc5748bae, 0xa677d806), TOBN(0x2763a387, 0xdfa394eb), + TOBN(0xa12b448a, 0x7d3cebb6), TOBN(0xe7adda3e, 0x6f20d850), + TOBN(0xf63ebce5, 0x1558462c), TOBN(0x58b36143, 0x620088a8), + TOBN(0x8a2cc3ca, 0x4d63c0ee), TOBN(0x51233117, 0x0fe948ce), + TOBN(0x7463fd85, 0x222ef33b), TOBN(0xadf0c7dc, 0x7c603d6c), + TOBN(0x0ec32d3b, 0xfe7765e5), TOBN(0xccaab359, 0xbf380409), + TOBN(0xbdaa84d6, 0x8e59319c), TOBN(0xd9a4c280, 0x9c80c34d), + TOBN(0xa9d89488, 0xa059c142), TOBN(0x6f5ae714, 0xff0b9346), + TOBN(0x068f237d, 0x16fb3664), TOBN(0x5853e4c4, 0x363186ac), + TOBN(0xe2d87d23, 0x63c52f98), TOBN(0x2ec4a766, 0x81828876), + TOBN(0x47b864fa, 0xe14e7b1c), TOBN(0x0c0bc0e5, 0x69192408), + TOBN(0xe4d7681d, 0xb82e9f3e), TOBN(0x83200f0b, 0xdf25e13c), + TOBN(0x8909984c, 0x66f27280), TOBN(0x462d7b00, 0x75f73227), + TOBN(0xd90ba188, 0xf2651798), TOBN(0x74c6e18c, 0x36ab1c34), + TOBN(0xab256ea3, 0x5ef54359), TOBN(0x03466612, 0xd1aa702f), + TOBN(0x624d6049, 0x2ed22e91), TOBN(0x6fdfe0b5, 0x6f072822), + TOBN(0xeeca1115, 0x39ce2271), TOBN(0x98100a4f, 0xdb01614f), + TOBN(0xb6b0daa2, 0xa35c628f), TOBN(0xb6f94d2e, 0xc87e9a47), + TOBN(0xc6773259, 0x1d57d9ce), TOBN(0xf70bfeec, 0x03884a7b), + TOBN(0x5fb35ccf, 0xed2bad01), TOBN(0xa155cbe3, 0x1da6a5c7), + TOBN(0xc2e2594c, 0x30a92f8f), TOBN(0x649c89ce, 0x5bfafe43), + TOBN(0xd158667d, 0xe9ff257a), TOBN(0x9b359611, 0xf32c50ae), + TOBN(0x4b00b20b, 0x906014cf), TOBN(0xf3a8cfe3, 0x89bc7d3d), + TOBN(0x4ff23ffd, 0x248a7d06), TOBN(0x80c5bfb4, 0x878873fa), + TOBN(0xb7d9ad90, 0x05745981), TOBN(0x179c85db, 0x3db01994), + TOBN(0xba41b062, 0x61a6966c), TOBN(0x4d82d052, 0xeadce5a8), + TOBN(0x9e91cd3b, 0xa5e6a318), TOBN(0x47795f4f, 0x95b2dda0), + TOBN(0xecfd7c1f, 0xd55a897c), TOBN(0x009194ab, 0xb29110fb), + TOBN(0x5f0e2046, 0xe381d3b0), TOBN(0x5f3425f6, 0xa98dd291), + TOBN(0xbfa06687, 0x730d50da), TOBN(0x0423446c, 0x4b083b7f), + TOBN(0x397a247d, 0xd69d3417), TOBN(0xeb629f90, 0x387ba42a), + TOBN(0x1ee426cc, 0xd5cd79bf), TOBN(0x0032940b, 0x946c6e18), + TOBN(0x1b1e8ae0, 0x57477f58), TOBN(0xe94f7d34, 0x6d823278), + TOBN(0xc747cb96, 0x782ba21a), TOBN(0xc5254469, 0xf72b33a5), + TOBN(0x772ef6de, 0xc7f80c81), TOBN(0xd73acbfe, 0x2cd9e6b5), + TOBN(0x4075b5b1, 0x49ee90d9), TOBN(0x785c339a, 0xa06e9eba), + TOBN(0xa1030d5b, 0xabf825e0), TOBN(0xcec684c3, 0xa42931dc), + TOBN(0x42ab62c9, 0xc1586e63), TOBN(0x45431d66, 0x5ab43f2b), + TOBN(0x57c8b2c0, 0x55f7835d), TOBN(0x033da338, 0xc1b7f865), + TOBN(0x283c7513, 0xcaa76097), TOBN(0x0a624fa9, 0x36c83906), + TOBN(0x6b20afec, 0x715af2c7), TOBN(0x4b969974, 0xeba78bfd), + TOBN(0x220755cc, 0xd921d60e), TOBN(0x9b944e10, 0x7baeca13), + TOBN(0x04819d51, 0x5ded93d4), TOBN(0x9bbff86e, 0x6dddfd27), + TOBN(0x6b344130, 0x77adc612), TOBN(0xa7496529, 0xbbd803a0), + TOBN(0x1a1baaa7, 0x6d8805bd), TOBN(0xc8403902, 0x470343ad), + TOBN(0x39f59f66, 0x175adff1), TOBN(0x0b26d7fb, 0xb7d8c5b7), + TOBN(0xa875f5ce, 0x529d75e3), TOBN(0x85efc7e9, 0x41325cc2), + TOBN(0x21950b42, 0x1ff6acd3), TOBN(0xffe70484, 0x53dc6909), + TOBN(0xff4cd0b2, 0x28766127), TOBN(0xabdbe608, 0x4fb7db2b), + TOBN(0x837c9228, 0x5e1109e8), TOBN(0x26147d27, 0xf4645b5a), + TOBN(0x4d78f592, 0xf7818ed8), TOBN(0xd394077e, 0xf247fa36), + TOBN(0x0fb9c2d0, 0x488c171a), TOBN(0xa78bfbaa, 0x13685278), + TOBN(0xedfbe268, 0xd5b1fa6a), TOBN(0x0dceb8db, 0x2b7eaba7), + TOBN(0xbf9e8089, 0x9ae2b710), TOBN(0xefde7ae6, 0xa4449c96), + TOBN(0x43b7716b, 0xcc143a46), TOBN(0xd7d34194, 0xc3628c13), + TOBN(0x508cec1c, 0x3b3f64c9), TOBN(0xe20bc0ba, 0x1e5edf3f), + TOBN(0xda1deb85, 0x2f4318d4), TOBN(0xd20ebe0d, 0x5c3fa443), + TOBN(0x370b4ea7, 0x73241ea3), TOBN(0x61f1511c, 0x5e1a5f65), + TOBN(0x99a5e23d, 0x82681c62), TOBN(0xd731e383, 0xa2f54c2d), + TOBN(0x2692f36e, 0x83445904), TOBN(0x2e0ec469, 0xaf45f9c0), + TOBN(0x905a3201, 0xc67528b7), TOBN(0x88f77f34, 0xd0e5e542), + TOBN(0xf67a8d29, 0x5864687c), TOBN(0x23b92eae, 0x22df3562), + TOBN(0x5c27014b, 0x9bbec39e), TOBN(0x7ef2f226, 0x9c0f0f8d), + TOBN(0x97359638, 0x546c4d8d), TOBN(0x5f9c3fc4, 0x92f24679), + TOBN(0x912e8bed, 0xa8c8acd9), TOBN(0xec3a318d, 0x306634b0), + TOBN(0x80167f41, 0xc31cb264), TOBN(0x3db82f6f, 0x522113f2), + TOBN(0xb155bcd2, 0xdcafe197), TOBN(0xfba1da59, 0x43465283), + TOBN(0xa0425b8e, 0xb212cf53), TOBN(0x4f2e512e, 0xf8557c5f), + TOBN(0xc1286ff9, 0x25c4d56c), TOBN(0xbb8a0fea, 0xee26c851), + TOBN(0xc28f70d2, 0xe7d6107e), TOBN(0x7ee0c444, 0xe76265aa), + TOBN(0x3df277a4, 0x1d1936b1), TOBN(0x1a556e3f, 0xea9595eb), + TOBN(0x258bbbf9, 0xe7305683), TOBN(0x31eea5bf, 0x07ef5be6), + TOBN(0x0deb0e4a, 0x46c814c1), TOBN(0x5cee8449, 0xa7b730dd), + TOBN(0xeab495c5, 0xa0182bde), TOBN(0xee759f87, 0x9e27a6b4), + TOBN(0xc2cf6a68, 0x80e518ca), TOBN(0x25e8013f, 0xf14cf3f4), + TOBN(0x8fc44140, 0x7e8d7a14), TOBN(0xbb1ff3ca, 0x9556f36a), + TOBN(0x6a844385, 0x14600044), TOBN(0xba3f0c4a, 0x7451ae63), + TOBN(0xdfcac25b, 0x1f9af32a), TOBN(0x01e0db86, 0xb1f2214b), + TOBN(0x4e9a5bc2, 0xa4b596ac), TOBN(0x83927681, 0x026c2c08), + TOBN(0x3ec832e7, 0x7acaca28), TOBN(0x1bfeea57, 0xc7385b29), + TOBN(0x068212e3, 0xfd1eaf38), TOBN(0xc1329830, 0x6acf8ccc), + TOBN(0xb909f2db, 0x2aac9e59), TOBN(0x5748060d, 0xb661782a), + TOBN(0xc5ab2632, 0xc79b7a01), TOBN(0xda44c6c6, 0x00017626), + TOBN(0xf26c00e8, 0xa7ea82f0), TOBN(0x99cac80d, 0xe4299aaf), + TOBN(0xd66fe3b6, 0x7ed78be1), TOBN(0x305f725f, 0x648d02cd), + TOBN(0x33ed1bc4, 0x623fb21b), TOBN(0xfa70533e, 0x7a6319ad), + TOBN(0x17ab562d, 0xbe5ffb3e), TOBN(0x06374994, 0x56674741), + TOBN(0x69d44ed6, 0x5c46aa8e), TOBN(0x2100d5d3, 0xa8d063d1), + TOBN(0xcb9727ea, 0xa2d17c36), TOBN(0x4c2bab1b, 0x8add53b7), + TOBN(0xa084e90c, 0x15426704), TOBN(0x778afcd3, 0xa837ebea), + TOBN(0x6651f701, 0x7ce477f8), TOBN(0xa0624998, 0x46fb7a8b), + TOBN(0xdc1e6828, 0xed8a6e19), TOBN(0x33fc2336, 0x4189d9c7), + TOBN(0x026f8fe2, 0x671c39bc), TOBN(0xd40c4ccd, 0xbc6f9915), + TOBN(0xafa135bb, 0xf80e75ca), TOBN(0x12c651a0, 0x22adff2c), + TOBN(0xc40a04bd, 0x4f51ad96), TOBN(0x04820109, 0xbbe4e832), + TOBN(0x3667eb1a, 0x7f4c04cc), TOBN(0x59556621, 0xa9404f84), + TOBN(0x71cdf653, 0x7eceb50a), TOBN(0x994a44a6, 0x9b8335fa), + TOBN(0xd7faf819, 0xdbeb9b69), TOBN(0x473c5680, 0xeed4350d), + TOBN(0xb6658466, 0xda44bba2), TOBN(0x0d1bc780, 0x872bdbf3), + TOBN(0xe535f175, 0xa1962f91), TOBN(0x6ed7e061, 0xed58f5a7), + TOBN(0x177aa4c0, 0x2089a233), TOBN(0x0dbcb03a, 0xe539b413), + TOBN(0xe3dc424e, 0xbb32e38e), TOBN(0x6472e5ef, 0x6806701e), + TOBN(0xdd47ff98, 0x814be9ee), TOBN(0x6b60cfff, 0x35ace009), + TOBN(0xb8d3d931, 0x9ff91fe5), TOBN(0x039c4800, 0xf0518eed), + TOBN(0x95c37632, 0x9182cb26), TOBN(0x0763a434, 0x82fc568d), + TOBN(0x707c04d5, 0x383e76ba), TOBN(0xac98b930, 0x824e8197), + TOBN(0x92bf7c8f, 0x91230de0), TOBN(0x90876a01, 0x40959b70), + TOBN(0xdb6d96f3, 0x05968b80), TOBN(0x380a0913, 0x089f73b9), + TOBN(0x7da70b83, 0xc2c61e01), TOBN(0x95fb8394, 0x569b38c7), + TOBN(0x9a3c6512, 0x80edfe2f), TOBN(0x8f726bb9, 0x8faeaf82), + TOBN(0x8010a4a0, 0x78424bf8), TOBN(0x29672044, 0x0e844970)}, + {TOBN(0x63c5cb81, 0x7a2ad62a), TOBN(0x7ef2b6b9, 0xac62ff54), + TOBN(0x3749bba4, 0xb3ad9db5), TOBN(0xad311f2c, 0x46d5a617), + TOBN(0xb77a8087, 0xc2ff3b6d), TOBN(0xb46feaf3, 0x367834ff), + TOBN(0xf8aa266d, 0x75d6b138), TOBN(0xfa38d320, 0xec008188), + TOBN(0x486d8ffa, 0x696946fc), TOBN(0x50fbc6d8, 0xb9cba56d), + TOBN(0x7e3d423e, 0x90f35a15), TOBN(0x7c3da195, 0xc0dd962c), + TOBN(0xe673fdb0, 0x3cfd5d8b), TOBN(0x0704b7c2, 0x889dfca5), + TOBN(0xf6ce581f, 0xf52305aa), TOBN(0x399d49eb, 0x914d5e53), + TOBN(0x380a496d, 0x6ec293cd), TOBN(0x733dbda7, 0x8e7051f5), + TOBN(0x037e388d, 0xb849140a), TOBN(0xee4b32b0, 0x5946dbf6), + TOBN(0xb1c4fda9, 0xcae368d1), TOBN(0x5001a7b0, 0xfdb0b2f3), + TOBN(0x6df59374, 0x2e3ac46e), TOBN(0x4af675f2, 0x39b3e656), + TOBN(0x44e38110, 0x39949296), TOBN(0x5b63827b, 0x361db1b5), + TOBN(0x3e5323ed, 0x206eaff5), TOBN(0x942370d2, 0xc21f4290), + TOBN(0xf2caaf2e, 0xe0d985a1), TOBN(0x192cc64b, 0x7239846d), + TOBN(0x7c0b8f47, 0xae6312f8), TOBN(0x7dc61f91, 0x96620108), + TOBN(0xb830fb5b, 0xc2da7de9), TOBN(0xd0e643df, 0x0ff8d3be), + TOBN(0x31ee77ba, 0x188a9641), TOBN(0x4e8aa3aa, 0xbcf6d502), + TOBN(0xf9fb6532, 0x9a49110f), TOBN(0xd18317f6, 0x2dd6b220), + TOBN(0x7e3ced41, 0x52c3ea5a), TOBN(0x0d296a14, 0x7d579c4a), + TOBN(0x35d6a53e, 0xed4c3717), TOBN(0x9f8240cf, 0x3d0ed2a3), + TOBN(0x8c0d4d05, 0xe5543aa5), TOBN(0x45d5bbfb, 0xdd33b4b4), + TOBN(0xfa04cc73, 0x137fd28e), TOBN(0x862ac6ef, 0xc73b3ffd), + TOBN(0x403ff9f5, 0x31f51ef2), TOBN(0x34d5e0fc, 0xbc73f5a2), + TOBN(0xf2526820, 0x08913f4f), TOBN(0xea20ed61, 0xeac93d95), + TOBN(0x51ed38b4, 0x6ca6b26c), TOBN(0x8662dcbc, 0xea4327b0), + TOBN(0x6daf295c, 0x725d2aaa), TOBN(0xbad2752f, 0x8e52dcda), + TOBN(0x2210e721, 0x0b17dacc), TOBN(0xa37f7912, 0xd51e8232), + TOBN(0x4f7081e1, 0x44cc3add), TOBN(0xd5ffa1d6, 0x87be82cf), + TOBN(0x89890b6c, 0x0edd6472), TOBN(0xada26e1a, 0x3ed17863), + TOBN(0x276f2715, 0x63483caa), TOBN(0xe6924cd9, 0x2f6077fd), + TOBN(0x05a7fe98, 0x0a466e3c), TOBN(0xf1c794b0, 0xb1902d1f), + TOBN(0xe5213688, 0x82a8042c), TOBN(0xd931cfaf, 0xcd278298), + TOBN(0x069a0ae0, 0xf597a740), TOBN(0x0adbb3f3, 0xeb59107c), + TOBN(0x983e951e, 0x5eaa8eb8), TOBN(0xe663a8b5, 0x11b48e78), + TOBN(0x1631cc0d, 0x8a03f2c5), TOBN(0x7577c11e, 0x11e271e2), + TOBN(0x33b2385c, 0x08369a90), TOBN(0x2990c59b, 0x190eb4f8), + TOBN(0x819a6145, 0xc68eac80), TOBN(0x7a786d62, 0x2ec4a014), + TOBN(0x33faadbe, 0x20ac3a8d), TOBN(0x31a21781, 0x5aba2d30), + TOBN(0x209d2742, 0xdba4f565), TOBN(0xdb2ce9e3, 0x55aa0fbb), + TOBN(0x8cef334b, 0x168984df), TOBN(0xe81dce17, 0x33879638), + TOBN(0xf6e6949c, 0x263720f0), TOBN(0x5c56feaf, 0xf593cbec), + TOBN(0x8bff5601, 0xfde58c84), TOBN(0x74e24117, 0x2eccb314), + TOBN(0xbcf01b61, 0x4c9a8a78), TOBN(0xa233e35e, 0x544c9868), + TOBN(0xb3156bf3, 0x8bd7aff1), TOBN(0x1b5ee4cb, 0x1d81b146), + TOBN(0x7ba1ac41, 0xd628a915), TOBN(0x8f3a8f9c, 0xfd89699e), + TOBN(0x7329b9c9, 0xa0748be7), TOBN(0x1d391c95, 0xa92e621f), + TOBN(0xe51e6b21, 0x4d10a837), TOBN(0xd255f53a, 0x4947b435), + TOBN(0x07669e04, 0xf1788ee3), TOBN(0xc14f27af, 0xa86938a2), + TOBN(0x8b47a334, 0xe93a01c0), TOBN(0xff627438, 0xd9366808), + TOBN(0x7a0985d8, 0xca2a5965), TOBN(0x3d9a5542, 0xd6e9b9b3), + TOBN(0xc23eb80b, 0x4cf972e8), TOBN(0x5c1c33bb, 0x4fdf72fd), + TOBN(0x0c4a58d4, 0x74a86108), TOBN(0xf8048a8f, 0xee4c5d90), + TOBN(0xe3c7c924, 0xe86d4c80), TOBN(0x28c889de, 0x056a1e60), + TOBN(0x57e2662e, 0xb214a040), TOBN(0xe8c48e98, 0x37e10347), + TOBN(0x87742862, 0x80ac748a), TOBN(0xf1c24022, 0x186b06f2), + TOBN(0xac2dd4c3, 0x5f74040a), TOBN(0x409aeb71, 0xfceac957), + TOBN(0x4fbad782, 0x55c4ec23), TOBN(0xb359ed61, 0x8a7b76ec), + TOBN(0x12744926, 0xed6f4a60), TOBN(0xe21e8d7f, 0x4b912de3), + TOBN(0xe2575a59, 0xfc705a59), TOBN(0x72f1d4de, 0xed2dbc0e), + TOBN(0x3d2b24b9, 0xeb7926b8), TOBN(0xbff88cb3, 0xcdbe5509), + TOBN(0xd0f399af, 0xe4dd640b), TOBN(0x3c5fe130, 0x2f76ed45), + TOBN(0x6f3562f4, 0x3764fb3d), TOBN(0x7b5af318, 0x3151b62d), + TOBN(0xd5bd0bc7, 0xd79ce5f3), TOBN(0xfdaf6b20, 0xec66890f), + TOBN(0x735c67ec, 0x6063540c), TOBN(0x50b259c2, 0xe5f9cb8f), + TOBN(0xb8734f9a, 0x3f99c6ab), TOBN(0xf8cc13d5, 0xa3a7bc85), + TOBN(0x80c1b305, 0xc5217659), TOBN(0xfe5364d4, 0x4ec12a54), + TOBN(0xbd87045e, 0x681345fe), TOBN(0x7f8efeb1, 0x582f897f), + TOBN(0xe8cbf1e5, 0xd5923359), TOBN(0xdb0cea9d, 0x539b9fb0), + TOBN(0x0c5b34cf, 0x49859b98), TOBN(0x5e583c56, 0xa4403cc6), + TOBN(0x11fc1a2d, 0xd48185b7), TOBN(0xc93fbc7e, 0x6e521787), + TOBN(0x47e7a058, 0x05105b8b), TOBN(0x7b4d4d58, 0xdb8260c8), + TOBN(0xe33930b0, 0x46eb842a), TOBN(0x8e844a9a, 0x7bdae56d), + TOBN(0x34ef3a9e, 0x13f7fdfc), TOBN(0xb3768f82, 0x636ca176), + TOBN(0x2821f4e0, 0x4e09e61c), TOBN(0x414dc3a1, 0xa0c7cddc), + TOBN(0xd5379437, 0x54945fcd), TOBN(0x151b6eef, 0xb3555ff1), + TOBN(0xb31bd613, 0x6339c083), TOBN(0x39ff8155, 0xdfb64701), + TOBN(0x7c3388d2, 0xe29604ab), TOBN(0x1e19084b, 0xa6b10442), + TOBN(0x17cf54c0, 0xeccd47ef), TOBN(0x89693385, 0x4a5dfb30), + TOBN(0x69d023fb, 0x47daf9f6), TOBN(0x9222840b, 0x7d91d959), + TOBN(0x439108f5, 0x803bac62), TOBN(0x0b7dd91d, 0x379bd45f), + TOBN(0xd651e827, 0xca63c581), TOBN(0x5c5d75f6, 0x509c104f), + TOBN(0x7d5fc738, 0x1f2dc308), TOBN(0x20faa7bf, 0xd98454be), + TOBN(0x95374bee, 0xa517b031), TOBN(0xf036b9b1, 0x642692ac), + TOBN(0xc5106109, 0x39842194), TOBN(0xb7e2353e, 0x49d05295), + TOBN(0xfc8c1d5c, 0xefb42ee0), TOBN(0xe04884eb, 0x08ce811c), + TOBN(0xf1f75d81, 0x7419f40e), TOBN(0x5b0ac162, 0xa995c241), + TOBN(0x120921bb, 0xc4c55646), TOBN(0x713520c2, 0x8d33cf97), + TOBN(0xb4a65a5c, 0xe98c5100), TOBN(0x6cec871d, 0x2ddd0f5a), + TOBN(0x251f0b7f, 0x9ba2e78b), TOBN(0x224a8434, 0xce3a2a5f), + TOBN(0x26827f61, 0x25f5c46f), TOBN(0x6a22bedc, 0x48545ec0), + TOBN(0x25ae5fa0, 0xb1bb5cdc), TOBN(0xd693682f, 0xfcb9b98f), + TOBN(0x32027fe8, 0x91e5d7d3), TOBN(0xf14b7d17, 0x73a07678), + TOBN(0xf88497b3, 0xc0dfdd61), TOBN(0xf7c2eec0, 0x2a8c4f48), + TOBN(0xaa5573f4, 0x3756e621), TOBN(0xc013a240, 0x1825b948), + TOBN(0x1c03b345, 0x63878572), TOBN(0xa0472bea, 0x653a4184), + TOBN(0xf4222e27, 0x0ac69a80), TOBN(0x34096d25, 0xf51e54f6), + TOBN(0x00a648cb, 0x8fffa591), TOBN(0x4e87acdc, 0x69b6527f), + TOBN(0x0575e037, 0xe285ccb4), TOBN(0x188089e4, 0x50ddcf52), + TOBN(0xaa96c9a8, 0x870ff719), TOBN(0x74a56cd8, 0x1fc7e369), + TOBN(0x41d04ee2, 0x1726931a), TOBN(0x0bbbb2c8, 0x3660ecfd), + TOBN(0xa6ef6de5, 0x24818e18), TOBN(0xe421cc51, 0xe7d57887), + TOBN(0xf127d208, 0xbea87be6), TOBN(0x16a475d3, 0xb1cdd682), + TOBN(0x9db1b684, 0x439b63f7), TOBN(0x5359b3db, 0xf0f113b6), + TOBN(0xdfccf1de, 0x8bf06e31), TOBN(0x1fdf8f44, 0xdd383901), + TOBN(0x10775cad, 0x5017e7d2), TOBN(0xdfc3a597, 0x58d11eef), + TOBN(0x6ec9c8a0, 0xb1ecff10), TOBN(0xee6ed6cc, 0x28400549), + TOBN(0xb5ad7bae, 0x1b4f8d73), TOBN(0x61b4f11d, 0xe00aaab9), + TOBN(0x7b32d69b, 0xd4eff2d7), TOBN(0x88ae6771, 0x4288b60f), + TOBN(0x159461b4, 0x37a1e723), TOBN(0x1f3d4789, 0x570aae8c), + TOBN(0x869118c0, 0x7f9871da), TOBN(0x35fbda78, 0xf635e278), + TOBN(0x738f3641, 0xe1541dac), TOBN(0x6794b13a, 0xc0dae45f), + TOBN(0x065064ac, 0x09cc0917), TOBN(0x27c53729, 0xc68540fd), + TOBN(0x0d2d4c8e, 0xef227671), TOBN(0xd23a9f80, 0xa1785a04), + TOBN(0x98c59528, 0x52650359), TOBN(0xfa09ad01, 0x74a1acad), + TOBN(0x082d5a29, 0x0b55bf5c), TOBN(0xa40f1c67, 0x419b8084), + TOBN(0x3a5c752e, 0xdcc18770), TOBN(0x4baf1f2f, 0x8825c3a5), + TOBN(0xebd63f74, 0x21b153ed), TOBN(0xa2383e47, 0xb2f64723), + TOBN(0xe7bf620a, 0x2646d19a), TOBN(0x56cb44ec, 0x03c83ffd), + TOBN(0xaf7267c9, 0x4f6be9f1), TOBN(0x8b2dfd7b, 0xc06bb5e9), + TOBN(0xb87072f2, 0xa672c5c7), TOBN(0xeacb11c8, 0x0d53c5e2), + TOBN(0x22dac29d, 0xff435932), TOBN(0x37bdb99d, 0x4408693c), + TOBN(0xf6e62fb6, 0x2899c20f), TOBN(0x3535d512, 0x447ece24), + TOBN(0xfbdc6b88, 0xff577ce3), TOBN(0x726693bd, 0x190575f2), + TOBN(0x6772b0e5, 0xab4b35a2), TOBN(0x1d8b6001, 0xf5eeaacf), + TOBN(0x728f7ce4, 0x795b9580), TOBN(0x4a20ed2a, 0x41fb81da), + TOBN(0x9f685cd4, 0x4fec01e6), TOBN(0x3ed7ddcc, 0xa7ff50ad), + TOBN(0x460fd264, 0x0c2d97fd), TOBN(0x3a241426, 0xeb82f4f9), + TOBN(0x17d1df2c, 0x6a8ea820), TOBN(0xb2b50d3b, 0xf22cc254), + TOBN(0x03856cba, 0xb7291426), TOBN(0x87fd26ae, 0x04f5ee39), + TOBN(0x9cb696cc, 0x02bee4ba), TOBN(0x53121804, 0x06820fd6), + TOBN(0xa5dfc269, 0x0212e985), TOBN(0x666f7ffa, 0x160f9a09), + TOBN(0xc503cd33, 0xbccd9617), TOBN(0x365dede4, 0xba7730a3), + TOBN(0x798c6355, 0x5ddb0786), TOBN(0xa6c3200e, 0xfc9cd3bc), + TOBN(0x060ffb2c, 0xe5e35efd), TOBN(0x99a4e25b, 0x5555a1c1), + TOBN(0x11d95375, 0xf70b3751), TOBN(0x0a57354a, 0x160e1bf6), + TOBN(0xecb3ae4b, 0xf8e4b065), TOBN(0x07a834c4, 0x2e53022b), + TOBN(0x1cd300b3, 0x8692ed96), TOBN(0x16a6f792, 0x61ee14ec), + TOBN(0x8f1063c6, 0x6a8649ed), TOBN(0xfbcdfcfe, 0x869f3e14), + TOBN(0x2cfb97c1, 0x00a7b3ec), TOBN(0xcea49b3c, 0x7130c2f1), + TOBN(0x462d044f, 0xe9d96488), TOBN(0x4b53d52e, 0x8182a0c1), + TOBN(0x84b6ddd3, 0x0391e9e9), TOBN(0x80ab7b48, 0xb1741a09), + TOBN(0xec0e15d4, 0x27d3317f), TOBN(0x8dfc1ddb, 0x1a64671e), + TOBN(0x93cc5d5f, 0xd49c5b92), TOBN(0xc995d53d, 0x3674a331), + TOBN(0x302e41ec, 0x090090ae), TOBN(0x2278a0cc, 0xedb06830), + TOBN(0x1d025932, 0xfbc99690), TOBN(0x0c32fbd2, 0xb80d68da), + TOBN(0xd79146da, 0xf341a6c1), TOBN(0xae0ba139, 0x1bef68a0), + TOBN(0xc6b8a563, 0x8d774b3a), TOBN(0x1cf307bd, 0x880ba4d7), + TOBN(0xc033bdc7, 0x19803511), TOBN(0xa9f97b3b, 0x8888c3be), + TOBN(0x3d68aebc, 0x85c6d05e), TOBN(0xc3b88a9d, 0x193919eb), + TOBN(0x2d300748, 0xc48b0ee3), TOBN(0x7506bc7c, 0x07a746c1), + TOBN(0xfc48437c, 0x6e6d57f3), TOBN(0x5bd71587, 0xcfeaa91a), + TOBN(0xa4ed0408, 0xc1bc5225), TOBN(0xd0b946db, 0x2719226d), + TOBN(0x109ecd62, 0x758d2d43), TOBN(0x75c8485a, 0x2751759b), + TOBN(0xb0b75f49, 0x9ce4177a), TOBN(0x4fa61a1e, 0x79c10c3d), + TOBN(0xc062d300, 0xa167fcd7), TOBN(0x4df3874c, 0x750f0fa8), + TOBN(0x29ae2cf9, 0x83dfedc9), TOBN(0xf8437134, 0x8d87631a), + TOBN(0xaf571711, 0x7429c8d2), TOBN(0x18d15867, 0x146d9272), + TOBN(0x83053ecf, 0x69769bb7), TOBN(0xc55eb856, 0xc479ab82), + TOBN(0x5ef7791c, 0x21b0f4b2), TOBN(0xaa5956ba, 0x3d491525), + TOBN(0x407a96c2, 0x9fe20eba), TOBN(0xf27168bb, 0xe52a5ad3), + TOBN(0x43b60ab3, 0xbf1d9d89), TOBN(0xe45c51ef, 0x710e727a), + TOBN(0xdfca5276, 0x099b4221), TOBN(0x8dc6407c, 0x2557a159), + TOBN(0x0ead8335, 0x91035895), TOBN(0x0a9db957, 0x9c55dc32), + TOBN(0xe40736d3, 0xdf61bc76), TOBN(0x13a619c0, 0x3f778cdb), + TOBN(0x6dd921a4, 0xc56ea28f), TOBN(0x76a52433, 0x2fa647b4), + TOBN(0x23591891, 0xac5bdc5d), TOBN(0xff4a1a72, 0xbac7dc01), + TOBN(0x9905e261, 0x62df8453), TOBN(0x3ac045df, 0xe63b265f), + TOBN(0x8a3f341b, 0xad53dba7), TOBN(0x8ec269cc, 0x837b625a), + TOBN(0xd71a2782, 0x3ae31189), TOBN(0x8fb4f9a3, 0x55e96120), + TOBN(0x804af823, 0xff9875cf), TOBN(0x23224f57, 0x5d442a9b), + TOBN(0x1c4d3b9e, 0xecc62679), TOBN(0x91da22fb, 0xa0e7ddb1), + TOBN(0xa370324d, 0x6c04a661), TOBN(0x9710d3b6, 0x5e376d17), + TOBN(0xed8c98f0, 0x3044e357), TOBN(0xc364ebbe, 0x6422701c), + TOBN(0x347f5d51, 0x7733d61c), TOBN(0xd55644b9, 0xcea826c3), + TOBN(0x80c6e0ad, 0x55a25548), TOBN(0x0aa7641d, 0x844220a7), + TOBN(0x1438ec81, 0x31810660), TOBN(0x9dfa6507, 0xde4b4043), + TOBN(0x10b515d8, 0xcc3e0273), TOBN(0x1b6066dd, 0x28d8cfb2), + TOBN(0xd3b04591, 0x9c9efebd), TOBN(0x425d4bdf, 0xa21c1ff4), + TOBN(0x5fe5af19, 0xd57607d3), TOBN(0xbbf773f7, 0x54481084), + TOBN(0x8435bd69, 0x94b03ed1), TOBN(0xd9ad1de3, 0x634cc546), + TOBN(0x2cf423fc, 0x00e420ca), TOBN(0xeed26d80, 0xa03096dd), + TOBN(0xd7f60be7, 0xa4db09d2), TOBN(0xf47f569d, 0x960622f7), + TOBN(0xe5925fd7, 0x7296c729), TOBN(0xeff2db26, 0x26ca2715), + TOBN(0xa6fcd014, 0xb913e759), TOBN(0x53da4786, 0x8ff4de93), + TOBN(0x14616d79, 0xc32068e1), TOBN(0xb187d664, 0xccdf352e), + TOBN(0xf7afb650, 0x1dc90b59), TOBN(0x8170e943, 0x7daa1b26), + TOBN(0xc8e3bdd8, 0x700c0a84), TOBN(0x6e8d345f, 0x6482bdfa), + TOBN(0x84cfbfa1, 0xc5c5ea50), TOBN(0xd3baf14c, 0x67960681), + TOBN(0x26398403, 0x0dd50942), TOBN(0xe4b7839c, 0x4716a663), + TOBN(0xd5f1f794, 0xe7de6dc0), TOBN(0x5cd0f4d4, 0x622aa7ce), + TOBN(0x5295f3f1, 0x59acfeec), TOBN(0x8d933552, 0x953e0607), + TOBN(0xc7db8ec5, 0x776c5722), TOBN(0xdc467e62, 0x2b5f290c), + TOBN(0xd4297e70, 0x4ff425a9), TOBN(0x4be924c1, 0x0cf7bb72), + TOBN(0x0d5dc5ae, 0xa1892131), TOBN(0x8bf8a8e3, 0xa705c992), + TOBN(0x73a0b064, 0x7a305ac5), TOBN(0x00c9ca4e, 0x9a8c77a8), + TOBN(0x5dfee80f, 0x83774bdd), TOBN(0x63131602, 0x85734485), + TOBN(0xa1b524ae, 0x914a69a9), TOBN(0xebc2ffaf, 0xd4e300d7), + TOBN(0x52c93db7, 0x7cfa46a5), TOBN(0x71e6161f, 0x21653b50), + TOBN(0x3574fc57, 0xa4bc580a), TOBN(0xc09015dd, 0xe1bc1253), + TOBN(0x4b7b47b2, 0xd174d7aa), TOBN(0x4072d8e8, 0xf3a15d04), + TOBN(0xeeb7d47f, 0xd6fa07ed), TOBN(0x6f2b9ff9, 0xedbdafb1), + TOBN(0x18c51615, 0x3760fe8a), TOBN(0x7a96e6bf, 0xf06c6c13), + TOBN(0x4d7a0410, 0x0ea2d071), TOBN(0xa1914e9b, 0x0be2a5ce), + TOBN(0x5726e357, 0xd8a3c5cf), TOBN(0x1197ecc3, 0x2abb2b13), + TOBN(0x6c0d7f7f, 0x31ae88dd), TOBN(0x15b20d1a, 0xfdbb3efe), + TOBN(0xcd06aa26, 0x70584039), TOBN(0x2277c969, 0xa7dc9747), + TOBN(0xbca69587, 0x7855d815), TOBN(0x899ea238, 0x5188b32a), + TOBN(0x37d9228b, 0x760c1c9d), TOBN(0xc7efbb11, 0x9b5c18da), + TOBN(0x7f0d1bc8, 0x19f6dbc5), TOBN(0x4875384b, 0x07e6905b), + TOBN(0xc7c50baa, 0x3ba8cd86), TOBN(0xb0ce40fb, 0xc2905de0), + TOBN(0x70840673, 0x7a231952), TOBN(0xa912a262, 0xcf43de26), + TOBN(0x9c38ddcc, 0xeb5b76c1), TOBN(0x746f5285, 0x26fc0ab4), + TOBN(0x52a63a50, 0xd62c269f), TOBN(0x60049c55, 0x99458621), + TOBN(0xe7f48f82, 0x3c2f7c9e), TOBN(0x6bd99043, 0x917d5cf3), + TOBN(0xeb1317a8, 0x8701f469), TOBN(0xbd3fe2ed, 0x9a449fe0), + TOBN(0x421e79ca, 0x12ef3d36), TOBN(0x9ee3c36c, 0x3e7ea5de), + TOBN(0xe48198b5, 0xcdff36f7), TOBN(0xaff4f967, 0xc6b82228), + TOBN(0x15e19dd0, 0xc47adb7e), TOBN(0x45699b23, 0x032e7dfa), + TOBN(0x40680c8b, 0x1fae026a), TOBN(0x5a347a48, 0x550dbf4d), + TOBN(0xe652533b, 0x3cef0d7d), TOBN(0xd94f7b18, 0x2bbb4381), + TOBN(0x838752be, 0x0e80f500), TOBN(0x8e6e2488, 0x9e9c9bfb), + TOBN(0xc9751697, 0x16caca6a), TOBN(0x866c49d8, 0x38531ad9), + TOBN(0xc917e239, 0x7151ade1), TOBN(0x2d016ec1, 0x6037c407), + TOBN(0xa407ccc9, 0x00eac3f9), TOBN(0x835f6280, 0xe2ed4748), + TOBN(0xcc54c347, 0x1cc98e0d), TOBN(0x0e969937, 0xdcb572eb), + TOBN(0x1b16c8e8, 0x8f30c9cb), TOBN(0xa606ae75, 0x373c4661), + TOBN(0x47aa689b, 0x35502cab), TOBN(0xf89014ae, 0x4d9bb64f), + TOBN(0x202f6a9c, 0x31c71f7b), TOBN(0x01f95aa3, 0x296ffe5c), + TOBN(0x5fc06014, 0x53cec3a3), TOBN(0xeb991237, 0x5f498a45), + TOBN(0xae9a935e, 0x5d91ba87), TOBN(0xc6ac6281, 0x0b564a19), + TOBN(0x8a8fe81c, 0x3bd44e69), TOBN(0x7c8b467f, 0x9dd11d45), + TOBN(0xf772251f, 0xea5b8e69), TOBN(0xaeecb3bd, 0xc5b75fbc), + TOBN(0x1aca3331, 0x887ff0e5), TOBN(0xbe5d49ff, 0x19f0a131), + TOBN(0x582c13aa, 0xe5c8646f), TOBN(0xdbaa12e8, 0x20e19980), + TOBN(0x8f40f31a, 0xf7abbd94), TOBN(0x1f13f5a8, 0x1dfc7663), + TOBN(0x5d81f1ee, 0xaceb4fc0), TOBN(0x36256002, 0x5e6f0f42), + TOBN(0x4b67d6d7, 0x751370c8), TOBN(0x2608b698, 0x03e80589), + TOBN(0xcfc0d2fc, 0x05268301), TOBN(0xa6943d39, 0x40309212), + TOBN(0x192a90c2, 0x1fd0e1c2), TOBN(0xb209f113, 0x37f1dc76), + TOBN(0xefcc5e06, 0x97bf1298), TOBN(0xcbdb6730, 0x219d639e), + TOBN(0xd009c116, 0xb81e8c6f), TOBN(0xa3ffdde3, 0x1a7ce2e5), + TOBN(0xc53fbaaa, 0xa914d3ba), TOBN(0x836d500f, 0x88df85ee), + TOBN(0xd98dc71b, 0x66ee0751), TOBN(0x5a3d7005, 0x714516fd), + TOBN(0x21d3634d, 0x39eedbba), TOBN(0x35cd2e68, 0x0455a46d), + TOBN(0xc8cafe65, 0xf9d7eb0c), TOBN(0xbda3ce9e, 0x00cefb3e), + TOBN(0xddc17a60, 0x2c9cf7a4), TOBN(0x01572ee4, 0x7bcb8773), + TOBN(0xa92b2b01, 0x8c7548df), TOBN(0x732fd309, 0xa84600e3), + TOBN(0xe22109c7, 0x16543a40), TOBN(0x9acafd36, 0xfede3c6c), + TOBN(0xfb206852, 0x6824e614), TOBN(0x2a4544a9, 0xda25dca0), + TOBN(0x25985262, 0x91d60b06), TOBN(0x281b7be9, 0x28753545), + TOBN(0xec667b1a, 0x90f13b27), TOBN(0x33a83aff, 0x940e2eb4), + TOBN(0x80009862, 0xd5d721d5), TOBN(0x0c3357a3, 0x5bd3a182), + TOBN(0x27f3a83b, 0x7aa2cda4), TOBN(0xb58ae74e, 0xf6f83085), + TOBN(0x2a911a81, 0x2e6dad6b), TOBN(0xde286051, 0xf43d6c5b), + TOBN(0x4bdccc41, 0xf996c4d8), TOBN(0xe7312ec0, 0x0ae1e24e)}, + {TOBN(0xf8d112e7, 0x6e6485b3), TOBN(0x4d3e24db, 0x771c52f8), + TOBN(0x48e3ee41, 0x684a2f6d), TOBN(0x7161957d, 0x21d95551), + TOBN(0x19631283, 0xcdb12a6c), TOBN(0xbf3fa882, 0x2e50e164), + TOBN(0xf6254b63, 0x3166cc73), TOBN(0x3aefa7ae, 0xaee8cc38), + TOBN(0x79b0fe62, 0x3b36f9fd), TOBN(0x26543b23, 0xfde19fc0), + TOBN(0x136e64a0, 0x958482ef), TOBN(0x23f63771, 0x9b095825), + TOBN(0x14cfd596, 0xb6a1142e), TOBN(0x5ea6aac6, 0x335aac0b), + TOBN(0x86a0e8bd, 0xf3081dd5), TOBN(0x5fb89d79, 0x003dc12a), + TOBN(0xf615c33a, 0xf72e34d4), TOBN(0x0bd9ea40, 0x110eec35), + TOBN(0x1c12bc5b, 0xc1dea34e), TOBN(0x686584c9, 0x49ae4699), + TOBN(0x13ad95d3, 0x8c97b942), TOBN(0x4609561a, 0x4e5c7562), + TOBN(0x9e94a4ae, 0xf2737f89), TOBN(0xf57594c6, 0x371c78b6), + TOBN(0x0f0165fc, 0xe3779ee3), TOBN(0xe00e7f9d, 0xbd495d9e), + TOBN(0x1fa4efa2, 0x20284e7a), TOBN(0x4564bade, 0x47ac6219), + TOBN(0x90e6312a, 0xc4708e8e), TOBN(0x4f5725fb, 0xa71e9adf), + TOBN(0xe95f55ae, 0x3d684b9f), TOBN(0x47f7ccb1, 0x1e94b415), + TOBN(0x7322851b, 0x8d946581), TOBN(0xf0d13133, 0xbdf4a012), + TOBN(0xa3510f69, 0x6584dae0), TOBN(0x03a7c171, 0x3c9f6c6d), + TOBN(0x5be97f38, 0xe475381a), TOBN(0xca1ba422, 0x85823334), + TOBN(0xf83cc5c7, 0x0be17dda), TOBN(0x158b1494, 0x0b918c0f), + TOBN(0xda3a77e5, 0x522e6b69), TOBN(0x69c908c3, 0xbbcd6c18), + TOBN(0x1f1b9e48, 0xd924fd56), TOBN(0x37c64e36, 0xaa4bb3f7), + TOBN(0x5a4fdbdf, 0xee478d7d), TOBN(0xba75c8bc, 0x0193f7a0), + TOBN(0x84bc1e84, 0x56cd16df), TOBN(0x1fb08f08, 0x46fad151), + TOBN(0x8a7cabf9, 0x842e9f30), TOBN(0xa331d4bf, 0x5eab83af), + TOBN(0xd272cfba, 0x017f2a6a), TOBN(0x27560abc, 0x83aba0e3), + TOBN(0x94b83387, 0x0e3a6b75), TOBN(0x25c6aea2, 0x6b9f50f5), + TOBN(0x803d691d, 0xb5fdf6d0), TOBN(0x03b77509, 0xe6333514), + TOBN(0x36178903, 0x61a341c1), TOBN(0x3604dc60, 0x0cfd6142), + TOBN(0x022295eb, 0x8533316c), TOBN(0x3dbde4ac, 0x44af2922), + TOBN(0x898afc5d, 0x1c7eef69), TOBN(0x58896805, 0xd14f4fa1), + TOBN(0x05002160, 0x203c21ca), TOBN(0x6f0d1f30, 0x40ef730b), + TOBN(0x8e8c44d4, 0x196224f8), TOBN(0x75a4ab95, 0x374d079d), + TOBN(0x79085ecc, 0x7d48f123), TOBN(0x56f04d31, 0x1bf65ad8), + TOBN(0xe220bf1c, 0xbda602b2), TOBN(0x73ee1742, 0xf9612c69), + TOBN(0x76008fc8, 0x084fd06b), TOBN(0x4000ef9f, 0xf11380d1), + TOBN(0x48201b4b, 0x12cfe297), TOBN(0x3eee129c, 0x292f74e5), + TOBN(0xe1fe114e, 0xc9e874e8), TOBN(0x899b055c, 0x92c5fc41), + TOBN(0x4e477a64, 0x3a39c8cf), TOBN(0x82f09efe, 0x78963cc9), + TOBN(0x6fd3fd8f, 0xd333f863), TOBN(0x85132b2a, 0xdc949c63), + TOBN(0x7e06a3ab, 0x516eb17b), TOBN(0x73bec06f, 0xd2c7372b), + TOBN(0xe4f74f55, 0xba896da6), TOBN(0xbb4afef8, 0x8e9eb40f), + TOBN(0x2d75bec8, 0xe61d66b0), TOBN(0x02bda4b4, 0xef29300b), + TOBN(0x8bbaa8de, 0x026baa5a), TOBN(0xff54befd, 0xa07f4440), + TOBN(0xbd9b8b1d, 0xbe7a2af3), TOBN(0xec51caa9, 0x4fb74a72), + TOBN(0xb9937a4b, 0x63879697), TOBN(0x7c9a9d20, 0xec2687d5), + TOBN(0x1773e44f, 0x6ef5f014), TOBN(0x8abcf412, 0xe90c6900), + TOBN(0x387bd022, 0x8142161e), TOBN(0x50393755, 0xfcb6ff2a), + TOBN(0x9813fd56, 0xed6def63), TOBN(0x53cf6482, 0x7d53106c), + TOBN(0x991a35bd, 0x431f7ac1), TOBN(0xf1e274dd, 0x63e65faf), + TOBN(0xf63ffa3c, 0x44cc7880), TOBN(0x411a426b, 0x7c256981), + TOBN(0xb698b9fd, 0x93a420e0), TOBN(0x89fdddc0, 0xae53f8fe), + TOBN(0x766e0722, 0x32398baa), TOBN(0x205fee42, 0x5cfca031), + TOBN(0xa49f5341, 0x7a029cf2), TOBN(0xa88c68b8, 0x4023890d), + TOBN(0xbc275041, 0x7337aaa8), TOBN(0x9ed364ad, 0x0eb384f4), + TOBN(0xe0816f85, 0x29aba92f), TOBN(0x2e9e1941, 0x04e38a88), + TOBN(0x57eef44a, 0x3dafd2d5), TOBN(0x35d1fae5, 0x97ed98d8), + TOBN(0x50628c09, 0x2307f9b1), TOBN(0x09d84aae, 0xd6cba5c6), + TOBN(0x67071bc7, 0x88aaa691), TOBN(0x2dea57a9, 0xafe6cb03), + TOBN(0xdfe11bb4, 0x3d78ac01), TOBN(0x7286418c, 0x7fd7aa51), + TOBN(0xfabf7709, 0x77f7195a), TOBN(0x8ec86167, 0xadeb838f), + TOBN(0xea1285a8, 0xbb4f012d), TOBN(0xd6883503, 0x9a3eab3f), + TOBN(0xee5d24f8, 0x309004c2), TOBN(0xa96e4b76, 0x13ffe95e), + TOBN(0x0cdffe12, 0xbd223ea4), TOBN(0x8f5c2ee5, 0xb6739a53), + TOBN(0x5cb4aaa5, 0xdd968198), TOBN(0xfa131c52, 0x72413a6c), + TOBN(0x53d46a90, 0x9536d903), TOBN(0xb270f0d3, 0x48606d8e), + TOBN(0x518c7564, 0xa053a3bc), TOBN(0x088254b7, 0x1a86caef), + TOBN(0xb3ba8cb4, 0x0ab5efd0), TOBN(0x5c59900e, 0x4605945d), + TOBN(0xecace1dd, 0xa1887395), TOBN(0x40960f36, 0x932a65de), + TOBN(0x9611ff5c, 0x3aa95529), TOBN(0xc58215b0, 0x7c1e5a36), + TOBN(0xd48c9b58, 0xf0e1a524), TOBN(0xb406856b, 0xf590dfb8), + TOBN(0xc7605e04, 0x9cd95662), TOBN(0x0dd036ee, 0xa33ecf82), + TOBN(0xa50171ac, 0xc33156b3), TOBN(0xf09d24ea, 0x4a80172e), + TOBN(0x4e1f72c6, 0x76dc8eef), TOBN(0xe60caadc, 0x5e3d44ee), + TOBN(0x006ef8a6, 0x979b1d8f), TOBN(0x60908a1c, 0x97788d26), + TOBN(0x6e08f95b, 0x266feec0), TOBN(0x618427c2, 0x22e8c94e), + TOBN(0x3d613339, 0x59145a65), TOBN(0xcd9bc368, 0xfa406337), + TOBN(0x82d11be3, 0x2d8a52a0), TOBN(0xf6877b27, 0x97a1c590), + TOBN(0x837a819b, 0xf5cbdb25), TOBN(0x2a4fd1d8, 0xde090249), + TOBN(0x622a7de7, 0x74990e5f), TOBN(0x840fa5a0, 0x7945511b), + TOBN(0x30b974be, 0x6558842d), TOBN(0x70df8c64, 0x17f3d0a6), + TOBN(0x7c803520, 0x7542e46d), TOBN(0x7251fe7f, 0xe4ecc823), + TOBN(0xe59134cb, 0x5e9aac9a), TOBN(0x11bb0934, 0xf0045d71), + TOBN(0x53e5d9b5, 0xdbcb1d4e), TOBN(0x8d97a905, 0x92defc91), + TOBN(0xfe289327, 0x7946d3f9), TOBN(0xe132bd24, 0x07472273), + TOBN(0xeeeb510c, 0x1eb6ae86), TOBN(0x777708c5, 0xf0595067), + TOBN(0x18e2c8cd, 0x1297029e), TOBN(0x2c61095c, 0xbbf9305e), + TOBN(0xe466c258, 0x6b85d6d9), TOBN(0x8ac06c36, 0xda1ea530), + TOBN(0xa365dc39, 0xa1304668), TOBN(0xe4a9c885, 0x07f89606), + TOBN(0x65a4898f, 0xacc7228d), TOBN(0x3e2347ff, 0x84ca8303), + TOBN(0xa5f6fb77, 0xea7d23a3), TOBN(0x2fac257d, 0x672a71cd), + TOBN(0x6908bef8, 0x7e6a44d3), TOBN(0x8ff87566, 0x891d3d7a), + TOBN(0xe58e90b3, 0x6b0cf82e), TOBN(0x6438d246, 0x2615b5e7), + TOBN(0x07b1f8fc, 0x669c145a), TOBN(0xb0d8b2da, 0x36f1e1cb), + TOBN(0x54d5dadb, 0xd9184c4d), TOBN(0x3dbb18d5, 0xf93d9976), + TOBN(0x0a3e0f56, 0xd1147d47), TOBN(0x2afa8c8d, 0xa0a48609), + TOBN(0x275353e8, 0xbc36742c), TOBN(0x898f427e, 0xeea0ed90), + TOBN(0x26f4947e, 0x3e477b00), TOBN(0x8ad8848a, 0x308741e3), + TOBN(0x6c703c38, 0xd74a2a46), TOBN(0x5e3e05a9, 0x9ba17ba2), + TOBN(0xc1fa6f66, 0x4ab9a9e4), TOBN(0x474a2d9a, 0x3841d6ec), + TOBN(0x871239ad, 0x653ae326), TOBN(0x14bcf72a, 0xa74cbb43), + TOBN(0x8737650e, 0x20d4c083), TOBN(0x3df86536, 0x110ed4af), + TOBN(0xd2d86fe7, 0xb53ca555), TOBN(0x688cb00d, 0xabd5d538), + TOBN(0xcf81bda3, 0x1ad38468), TOBN(0x7ccfe3cc, 0xf01167b6), + TOBN(0xcf4f47e0, 0x6c4c1fe6), TOBN(0x557e1f1a, 0x298bbb79), + TOBN(0xf93b974f, 0x30d45a14), TOBN(0x174a1d2d, 0x0baf97c4), + TOBN(0x7a003b30, 0xc51fbf53), TOBN(0xd8940991, 0xee68b225), + TOBN(0x5b0aa7b7, 0x1c0f4173), TOBN(0x975797c9, 0xa20a7153), + TOBN(0x26e08c07, 0xe3533d77), TOBN(0xd7222e6a, 0x2e341c99), + TOBN(0x9d60ec3d, 0x8d2dc4ed), TOBN(0xbdfe0d8f, 0x7c476cf8), + TOBN(0x1fe59ab6, 0x1d056605), TOBN(0xa9ea9df6, 0x86a8551f), + TOBN(0x8489941e, 0x47fb8d8c), TOBN(0xfeb874eb, 0x4a7f1b10), + TOBN(0xfe5fea86, 0x7ee0d98f), TOBN(0x201ad34b, 0xdbf61864), + TOBN(0x45d8fe47, 0x37c031d4), TOBN(0xd5f49fae, 0x795f0822), + TOBN(0xdb0fb291, 0xc7f4a40c), TOBN(0x2e69d9c1, 0x730ddd92), + TOBN(0x754e1054, 0x49d76987), TOBN(0x8a24911d, 0x7662db87), + TOBN(0x61fc1810, 0x60a71676), TOBN(0xe852d1a8, 0xf66a8ad1), + TOBN(0x172bbd65, 0x6417231e), TOBN(0x0d6de7bd, 0x3babb11f), + TOBN(0x6fde6f88, 0xc8e347f8), TOBN(0x1c587547, 0x9bd99cc3), + TOBN(0x78e54ed0, 0x34076950), TOBN(0x97f0f334, 0x796e83ba), + TOBN(0xe4dbe1ce, 0x4924867a), TOBN(0xbd5f51b0, 0x60b84917), + TOBN(0x37530040, 0x3cb09a79), TOBN(0xdb3fe0f8, 0xff1743d8), + TOBN(0xed7894d8, 0x556fa9db), TOBN(0xfa262169, 0x23412fbf), + TOBN(0x563be0db, 0xba7b9291), TOBN(0x6ca8b8c0, 0x0c9fb234), + TOBN(0xed406aa9, 0xbd763802), TOBN(0xc21486a0, 0x65303da1), + TOBN(0x61ae291e, 0xc7e62ec4), TOBN(0x622a0492, 0xdf99333e), + TOBN(0x7fd80c9d, 0xbb7a8ee0), TOBN(0xdc2ed3bc, 0x6c01aedb), + TOBN(0x35c35a12, 0x08be74ec), TOBN(0xd540cb1a, 0x469f671f), + TOBN(0xd16ced4e, 0xcf84f6c7), TOBN(0x8561fb9c, 0x2d090f43), + TOBN(0x7e693d79, 0x6f239db4), TOBN(0xa736f928, 0x77bd0d94), + TOBN(0x07b4d929, 0x2c1950ee), TOBN(0xda177543, 0x56dc11b3), + TOBN(0xa5dfbbaa, 0x7a6a878e), TOBN(0x1c70cb29, 0x4decb08a), + TOBN(0xfba28c8b, 0x6f0f7c50), TOBN(0xa8eba2b8, 0x854dcc6d), + TOBN(0x5ff8e89a, 0x36b78642), TOBN(0x070c1c8e, 0xf6873adf), + TOBN(0xbbd3c371, 0x6484d2e4), TOBN(0xfb78318f, 0x0d414129), + TOBN(0x2621a39c, 0x6ad93b0b), TOBN(0x979d74c2, 0xa9e917f7), + TOBN(0xfc195647, 0x61fb0428), TOBN(0x4d78954a, 0xbee624d4), + TOBN(0xb94896e0, 0xb8ae86fd), TOBN(0x6667ac0c, 0xc91c8b13), + TOBN(0x9f180512, 0x43bcf832), TOBN(0xfbadf8b7, 0xa0010137), + TOBN(0xc69b4089, 0xb3ba8aa7), TOBN(0xfac4bacd, 0xe687ce85), + TOBN(0x9164088d, 0x977eab40), TOBN(0x51f4c5b6, 0x2760b390), + TOBN(0xd238238f, 0x340dd553), TOBN(0x358566c3, 0xdb1d31c9), + TOBN(0x3a5ad69e, 0x5068f5ff), TOBN(0xf31435fc, 0xdaff6b06), + TOBN(0xae549a5b, 0xd6debff0), TOBN(0x59e5f0b7, 0x75e01331), + TOBN(0x5d492fb8, 0x98559acf), TOBN(0x96018c2e, 0x4db79b50), + TOBN(0x55f4a48f, 0x609f66aa), TOBN(0x1943b3af, 0x4900a14f), + TOBN(0xc22496df, 0x15a40d39), TOBN(0xb2a44684, 0x4c20f7c5), + TOBN(0x76a35afa, 0x3b98404c), TOBN(0xbec75725, 0xff5d1b77), + TOBN(0xb67aa163, 0xbea06444), TOBN(0x27e95bb2, 0xf724b6f2), + TOBN(0x3c20e3e9, 0xd238c8ab), TOBN(0x1213754e, 0xddd6ae17), + TOBN(0x8c431020, 0x716e0f74), TOBN(0x6679c82e, 0xffc095c2), + TOBN(0x2eb3adf4, 0xd0ac2932), TOBN(0x2cc970d3, 0x01bb7a76), + TOBN(0x70c71f2f, 0x740f0e66), TOBN(0x545c616b, 0x2b6b23cc), + TOBN(0x4528cfcb, 0xb40a8bd7), TOBN(0xff839633, 0x2ab27722), + TOBN(0x049127d9, 0x025ac99a), TOBN(0xd314d4a0, 0x2b63e33b), + TOBN(0xc8c310e7, 0x28d84519), TOBN(0x0fcb8983, 0xb3bc84ba), + TOBN(0x2cc52261, 0x38634818), TOBN(0x501814f4, 0xb44c2e0b), + TOBN(0xf7e181aa, 0x54dfdba3), TOBN(0xcfd58ff0, 0xe759718c), + TOBN(0xf90cdb14, 0xd3b507a8), TOBN(0x57bd478e, 0xc50bdad8), + TOBN(0x29c197e2, 0x50e5f9aa), TOBN(0x4db6eef8, 0xe40bc855), + TOBN(0x2cc8f21a, 0xd1fc0654), TOBN(0xc71cc963, 0x81269d73), + TOBN(0xecfbb204, 0x077f49f9), TOBN(0xdde92571, 0xca56b793), + TOBN(0x9abed6a3, 0xf97ad8f7), TOBN(0xe6c19d3f, 0x924de3bd), + TOBN(0x8dce92f4, 0xa140a800), TOBN(0x85f44d1e, 0x1337af07), + TOBN(0x5953c08b, 0x09d64c52), TOBN(0xa1b5e49f, 0xf5df9749), + TOBN(0x336a8fb8, 0x52735f7d), TOBN(0xb332b6db, 0x9add676b), + TOBN(0x558b88a0, 0xb4511aa4), TOBN(0x09788752, 0xdbd5cc55), + TOBN(0x16b43b9c, 0xd8cd52bd), TOBN(0x7f0bc5a0, 0xc2a2696b), + TOBN(0x146e12d4, 0xc11f61ef), TOBN(0x9ce10754, 0x3a83e79e), + TOBN(0x08ec73d9, 0x6cbfca15), TOBN(0x09ff29ad, 0x5b49653f), + TOBN(0xe31b72bd, 0xe7da946e), TOBN(0xebf9eb3b, 0xee80a4f2), + TOBN(0xd1aabd08, 0x17598ce4), TOBN(0x18b5fef4, 0x53f37e80), + TOBN(0xd5d5cdd3, 0x5958cd79), TOBN(0x3580a1b5, 0x1d373114), + TOBN(0xa36e4c91, 0xfa935726), TOBN(0xa38c534d, 0xef20d760), + TOBN(0x7088e40a, 0x2ff5845b), TOBN(0xe5bb40bd, 0xbd78177f), + TOBN(0x4f06a7a8, 0x857f9920), TOBN(0xe3cc3e50, 0xe968f05d), + TOBN(0x1d68b7fe, 0xe5682d26), TOBN(0x5206f76f, 0xaec7f87c), + TOBN(0x41110530, 0x041951ab), TOBN(0x58ec52c1, 0xd4b5a71a), + TOBN(0xf3488f99, 0x0f75cf9a), TOBN(0xf411951f, 0xba82d0d5), + TOBN(0x27ee75be, 0x618895ab), TOBN(0xeae060d4, 0x6d8aab14), + TOBN(0x9ae1df73, 0x7fb54dc2), TOBN(0x1f3e391b, 0x25963649), + TOBN(0x242ec32a, 0xfe055081), TOBN(0x5bd450ef, 0x8491c9bd), + TOBN(0x367efc67, 0x981eb389), TOBN(0xed7e1928, 0x3a0550d5), + TOBN(0x362e776b, 0xab3ce75c), TOBN(0xe890e308, 0x1f24c523), + TOBN(0xb961b682, 0xfeccef76), TOBN(0x8b8e11f5, 0x8bba6d92), + TOBN(0x8f2ccc4c, 0x2b2375c4), TOBN(0x0d7f7a52, 0xe2f86cfa), + TOBN(0xfd94d30a, 0x9efe5633), TOBN(0x2d8d246b, 0x5451f934), + TOBN(0x2234c6e3, 0x244e6a00), TOBN(0xde2b5b0d, 0xddec8c50), + TOBN(0x2ce53c5a, 0xbf776f5b), TOBN(0x6f724071, 0x60357b05), + TOBN(0xb2593717, 0x71bf3f7a), TOBN(0x87d2501c, 0x440c4a9f), + TOBN(0x440552e1, 0x87b05340), TOBN(0xb7bf7cc8, 0x21624c32), + TOBN(0x4155a6ce, 0x22facddb), TOBN(0x5a4228cb, 0x889837ef), + TOBN(0xef87d6d6, 0xfd4fd671), TOBN(0xa233687e, 0xc2daa10e), + TOBN(0x75622244, 0x03c0eb96), TOBN(0x7632d184, 0x8bf19be6), + TOBN(0x05d0f8e9, 0x40735ff4), TOBN(0x3a3e6e13, 0xc00931f1), + TOBN(0x31ccde6a, 0xdafe3f18), TOBN(0xf381366a, 0xcfe51207), + TOBN(0x24c222a9, 0x60167d92), TOBN(0x62f9d6f8, 0x7529f18c), + TOBN(0x412397c0, 0x0353b114), TOBN(0x334d89dc, 0xef808043), + TOBN(0xd9ec63ba, 0x2a4383ce), TOBN(0xcec8e937, 0x5cf92ba0), + TOBN(0xfb8b4288, 0xc8be74c0), TOBN(0x67d6912f, 0x105d4391), + TOBN(0x7b996c46, 0x1b913149), TOBN(0x36aae2ef, 0x3a4e02da), + TOBN(0xb68aa003, 0x972de594), TOBN(0x284ec70d, 0x4ec6d545), + TOBN(0xf3d2b2d0, 0x61391d54), TOBN(0x69c5d5d6, 0xfe114e92), + TOBN(0xbe0f00b5, 0xb4482dff), TOBN(0xe1596fa5, 0xf5bf33c5), + TOBN(0x10595b56, 0x96a71cba), TOBN(0x944938b2, 0xfdcadeb7), + TOBN(0xa282da4c, 0xfccd8471), TOBN(0x98ec05f3, 0x0d37bfe1), + TOBN(0xe171ce1b, 0x0698304a), TOBN(0x2d691444, 0x21bdf79b), + TOBN(0xd0cd3b74, 0x1b21dec1), TOBN(0x712ecd8b, 0x16a15f71), + TOBN(0x8d4c00a7, 0x00fd56e1), TOBN(0x02ec9692, 0xf9527c18), + TOBN(0x21c44937, 0x4a3e42e1), TOBN(0x9176fbab, 0x1392ae0a), + TOBN(0x8726f1ba, 0x44b7b618), TOBN(0xb4d7aae9, 0xf1de491c), + TOBN(0xf91df7b9, 0x07b582c0), TOBN(0x7e116c30, 0xef60aa3a), + TOBN(0x99270f81, 0x466265d7), TOBN(0xb15b6fe2, 0x4df7adf0), + TOBN(0xfe33b2d3, 0xf9738f7f), TOBN(0x48553ab9, 0xd6d70f95), + TOBN(0x2cc72ac8, 0xc21e94db), TOBN(0x795ac38d, 0xbdc0bbee), + TOBN(0x0a1be449, 0x2e40478f), TOBN(0x81bd3394, 0x052bde55), + TOBN(0x63c8dbe9, 0x56b3c4f2), TOBN(0x017a99cf, 0x904177cc), + TOBN(0x947bbddb, 0x4d010fc1), TOBN(0xacf9b00b, 0xbb2c9b21), + TOBN(0x2970bc8d, 0x47173611), TOBN(0x1a4cbe08, 0xac7d756f), + TOBN(0x06d9f4aa, 0x67d541a2), TOBN(0xa3e8b689, 0x59c2cf44), + TOBN(0xaad066da, 0x4d88f1dd), TOBN(0xc604f165, 0x7ad35dea), + TOBN(0x7edc0720, 0x4478ca67), TOBN(0xa10dfae0, 0xba02ce06), + TOBN(0xeceb1c76, 0xaf36f4e4), TOBN(0x994b2292, 0xaf3f8f48), + TOBN(0xbf9ed77b, 0x77c8a68c), TOBN(0x74f544ea, 0x51744c9d), + TOBN(0x82d05bb9, 0x8113a757), TOBN(0x4ef2d2b4, 0x8a9885e4), + TOBN(0x1e332be5, 0x1aa7865f), TOBN(0x22b76b18, 0x290d1a52), + TOBN(0x308a2310, 0x44351683), TOBN(0x9d861896, 0xa3f22840), + TOBN(0x5959ddcd, 0x841ed947), TOBN(0x0def0c94, 0x154b73bf), + TOBN(0xf0105417, 0x4c7c15e0), TOBN(0x539bfb02, 0x3a277c32), + TOBN(0xe699268e, 0xf9dccf5f), TOBN(0x9f5796a5, 0x0247a3bd), + TOBN(0x8b839de8, 0x4f157269), TOBN(0xc825c1e5, 0x7a30196b), + TOBN(0x6ef0aabc, 0xdc8a5a91), TOBN(0xf4a8ce6c, 0x498b7fe6), + TOBN(0x1cce35a7, 0x70cbac78), TOBN(0x83488e9b, 0xf6b23958), + TOBN(0x0341a070, 0xd76cb011), TOBN(0xda6c9d06, 0xae1b2658), + TOBN(0xb701fb30, 0xdd648c52), TOBN(0x994ca02c, 0x52fb9fd1), + TOBN(0x06933117, 0x6f563086), TOBN(0x3d2b8100, 0x17856bab), + TOBN(0xe89f48c8, 0x5963a46e), TOBN(0x658ab875, 0xa99e61c7), + TOBN(0x6e296f87, 0x4b8517b4), TOBN(0x36c4fcdc, 0xfc1bc656), + TOBN(0xde5227a1, 0xa3906def), TOBN(0x9fe95f57, 0x62418945), + TOBN(0x20c91e81, 0xfdd96cde), TOBN(0x5adbe47e, 0xda4480de), + TOBN(0xa009370f, 0x396de2b6), TOBN(0x98583d4b, 0xf0ecc7bd), + TOBN(0xf44f6b57, 0xe51d0672), TOBN(0x03d6b078, 0x556b1984), + TOBN(0x27dbdd93, 0xb0b64912), TOBN(0x9b3a3434, 0x15687b09), + TOBN(0x0dba6461, 0x51ec20a9), TOBN(0xec93db7f, 0xff28187c), + TOBN(0x00ff8c24, 0x66e48bdd), TOBN(0x2514f2f9, 0x11ccd78e), + TOBN(0xeba11f4f, 0xe1250603), TOBN(0x8a22cd41, 0x243fa156), + TOBN(0xa4e58df4, 0xb283e4c6), TOBN(0x78c29859, 0x8b39783f), + TOBN(0x5235aee2, 0xa5259809), TOBN(0xc16284b5, 0x0e0227dd), + TOBN(0xa5f57916, 0x1338830d), TOBN(0x6d4b8a6b, 0xd2123fca), + TOBN(0x236ea68a, 0xf9c546f8), TOBN(0xc1d36873, 0xfa608d36), + TOBN(0xcd76e495, 0x8d436d13), TOBN(0xd4d9c221, 0x8fb080af), + TOBN(0x665c1728, 0xe8ad3fb5), TOBN(0xcf1ebe4d, 0xb3d572e0), + TOBN(0xa7a8746a, 0x584c5e20), TOBN(0x267e4ea1, 0xb9dc7035), + TOBN(0x593a15cf, 0xb9548c9b), TOBN(0x5e6e2135, 0x4bd012f3), + TOBN(0xdf31cc6a, 0x8c8f936e), TOBN(0x8af84d04, 0xb5c241dc), + TOBN(0x63990a6f, 0x345efb86), TOBN(0x6fef4e61, 0xb9b962cb)}, + {TOBN(0xf6368f09, 0x25722608), TOBN(0x131260db, 0x131cf5c6), + TOBN(0x40eb353b, 0xfab4f7ac), TOBN(0x85c78880, 0x37eee829), + TOBN(0x4c1581ff, 0xc3bdf24e), TOBN(0x5bff75cb, 0xf5c3c5a8), + TOBN(0x35e8c83f, 0xa14e6f40), TOBN(0xb81d1c0f, 0x0295e0ca), + TOBN(0xfcde7cc8, 0xf43a730f), TOBN(0xe89b6f3c, 0x33ab590e), + TOBN(0xc823f529, 0xad03240b), TOBN(0x82b79afe, 0x98bea5db), + TOBN(0x568f2856, 0x962fe5de), TOBN(0x0c590adb, 0x60c591f3), + TOBN(0x1fc74a14, 0x4a28a858), TOBN(0x3b662498, 0xb3203f4c), + TOBN(0x91e3cf0d, 0x6c39765a), TOBN(0xa2db3acd, 0xac3cca0b), + TOBN(0x288f2f08, 0xcb953b50), TOBN(0x2414582c, 0xcf43cf1a), + TOBN(0x8dec8bbc, 0x60eee9a8), TOBN(0x54c79f02, 0x729aa042), + TOBN(0xd81cd5ec, 0x6532f5d5), TOBN(0xa672303a, 0xcf82e15f), + TOBN(0x376aafa8, 0x719c0563), TOBN(0xcd8ad2dc, 0xbc5fc79f), + TOBN(0x303fdb9f, 0xcb750cd3), TOBN(0x14ff052f, 0x4418b08e), + TOBN(0xf75084cf, 0x3e2d6520), TOBN(0x7ebdf0f8, 0x144ed509), + TOBN(0xf43bf0f2, 0xd3f25b98), TOBN(0x86ad71cf, 0xa354d837), + TOBN(0xb827fe92, 0x26f43572), TOBN(0xdfd3ab5b, 0x5d824758), + TOBN(0x315dd23a, 0x539094c1), TOBN(0x85c0e37a, 0x66623d68), + TOBN(0x575c7972, 0x7be19ae0), TOBN(0x616a3396, 0xdf0d36b5), + TOBN(0xa1ebb3c8, 0x26b1ff7e), TOBN(0x635b9485, 0x140ad453), + TOBN(0x92bf3cda, 0xda430c0b), TOBN(0x4702850e, 0x3a96dac6), + TOBN(0xc91cf0a5, 0x15ac326a), TOBN(0x95de4f49, 0xab8c25e4), + TOBN(0xb01bad09, 0xe265c17c), TOBN(0x24e45464, 0x087b3881), + TOBN(0xd43e583c, 0xe1fac5ca), TOBN(0xe17cb318, 0x6ead97a6), + TOBN(0x6cc39243, 0x74dcec46), TOBN(0x33cfc02d, 0x54c2b73f), + TOBN(0x82917844, 0xf26cd99c), TOBN(0x8819dd95, 0xd1773f89), + TOBN(0x09572aa6, 0x0871f427), TOBN(0x8e0cf365, 0xf6f01c34), + TOBN(0x7fa52988, 0xbff1f5af), TOBN(0x4eb357ea, 0xe75e8e50), + TOBN(0xd9d0c8c4, 0x868af75d), TOBN(0xd7325cff, 0x45c8c7ea), + TOBN(0xab471996, 0xcc81ecb0), TOBN(0xff5d55f3, 0x611824ed), + TOBN(0xbe314541, 0x1977a0ee), TOBN(0x5085c4c5, 0x722038c6), + TOBN(0x2d5335bf, 0xf94bb495), TOBN(0x894ad8a6, 0xc8e2a082), + TOBN(0x5c3e2341, 0xada35438), TOBN(0xf4a9fc89, 0x049b8c4e), + TOBN(0xbeeb355a, 0x9f17cf34), TOBN(0x3f311e0e, 0x6c91fe10), + TOBN(0xc2d20038, 0x92ab9891), TOBN(0x257bdcc1, 0x3e8ce9a9), + TOBN(0x1b2d9789, 0x88c53bee), TOBN(0x927ce89a, 0xcdba143a), + TOBN(0xb0a32cca, 0x523db280), TOBN(0x5c889f8a, 0x50d43783), + TOBN(0x503e04b3, 0x4897d16f), TOBN(0x8cdb6e78, 0x08f5f2e8), + TOBN(0x6ab91cf0, 0x179c8e74), TOBN(0xd8874e52, 0x48211d60), + TOBN(0xf948d4d5, 0xea851200), TOBN(0x4076d41e, 0xe6f9840a), + TOBN(0xc20e263c, 0x47b517ea), TOBN(0x79a448fd, 0x30685e5e), + TOBN(0xe55f6f78, 0xf90631a0), TOBN(0x88a790b1, 0xa79e6346), + TOBN(0x62160c7d, 0x80969fe8), TOBN(0x54f92fd4, 0x41491bb9), + TOBN(0xa6645c23, 0x5c957526), TOBN(0xf44cc5ae, 0xbea3ce7b), + TOBN(0xf7628327, 0x8b1e68b7), TOBN(0xc731ad7a, 0x303f29d3), + TOBN(0xfe5a9ca9, 0x57d03ecb), TOBN(0x96c0d50c, 0x41bc97a7), + TOBN(0xc4669fe7, 0x9b4f7f24), TOBN(0xfdd781d8, 0x3d9967ef), + TOBN(0x7892c7c3, 0x5d2c208d), TOBN(0x8bf64f7c, 0xae545cb3), + TOBN(0xc01f862c, 0x467be912), TOBN(0xf4c85ee9, 0xc73d30cc), + TOBN(0x1fa6f4be, 0x6ab83ec7), TOBN(0xa07a3c1c, 0x4e3e3cf9), + TOBN(0x87f8ef45, 0x0c00beb3), TOBN(0x30e2c2b3, 0x000d4c3e), + TOBN(0x1aa00b94, 0xfe08bf5b), TOBN(0x32c133aa, 0x9224ef52), + TOBN(0x38df16bb, 0x32e5685d), TOBN(0x68a9e069, 0x58e6f544), + TOBN(0x495aaff7, 0xcdc5ebc6), TOBN(0xf894a645, 0x378b135f), + TOBN(0xf316350a, 0x09e27ecf), TOBN(0xeced201e, 0x58f7179d), + TOBN(0x2eec273c, 0xe97861ba), TOBN(0x47ec2cae, 0xd693be2e), + TOBN(0xfa4c97c4, 0xf68367ce), TOBN(0xe4f47d0b, 0xbe5a5755), + TOBN(0x17de815d, 0xb298a979), TOBN(0xd7eca659, 0xc177dc7d), + TOBN(0x20fdbb71, 0x49ded0a3), TOBN(0x4cb2aad4, 0xfb34d3c5), + TOBN(0x2cf31d28, 0x60858a33), TOBN(0x3b6873ef, 0xa24aa40f), + TOBN(0x540234b2, 0x2c11bb37), TOBN(0x2d0366dd, 0xed4c74a3), + TOBN(0xf9a968da, 0xeec5f25d), TOBN(0x36601068, 0x67b63142), + TOBN(0x07cd6d2c, 0x68d7b6d4), TOBN(0xa8f74f09, 0x0c842942), + TOBN(0xe2751404, 0x7768b1ee), TOBN(0x4b5f7e89, 0xfe62aee4), + TOBN(0xc6a77177, 0x89070d26), TOBN(0xa1f28e4e, 0xdd1c8bc7), + TOBN(0xea5f4f06, 0x469e1f17), TOBN(0x78fc242a, 0xfbdb78e0), + TOBN(0xc9c7c592, 0x8b0588f1), TOBN(0xb6b7a0fd, 0x1535921e), + TOBN(0xcc5bdb91, 0xbde5ae35), TOBN(0xb42c485e, 0x12ff1864), + TOBN(0xa1113e13, 0xdbab98aa), TOBN(0xde9d469b, 0xa17b1024), + TOBN(0x23f48b37, 0xc0462d3a), TOBN(0x3752e537, 0x7c5c078d), + TOBN(0xe3a86add, 0x15544eb9), TOBN(0xf013aea7, 0x80fba279), + TOBN(0x8b5bb76c, 0xf22001b5), TOBN(0xe617ba14, 0xf02891ab), + TOBN(0xd39182a6, 0x936219d3), TOBN(0x5ce1f194, 0xae51cb19), + TOBN(0xc78f8598, 0xbf07a74c), TOBN(0x6d7158f2, 0x22cbf1bc), + TOBN(0x3b846b21, 0xe300ce18), TOBN(0x35fba630, 0x2d11275d), + TOBN(0x5fe25c36, 0xa0239b9b), TOBN(0xd8beb35d, 0xdf05d940), + TOBN(0x4db02bb0, 0x1f7e320d), TOBN(0x0641c364, 0x6da320ea), + TOBN(0x6d95fa5d, 0x821389a3), TOBN(0x92699748, 0x8fcd8e3d), + TOBN(0x316fef17, 0xceb6c143), TOBN(0x67fcb841, 0xd933762b), + TOBN(0xbb837e35, 0x118b17f8), TOBN(0x4b92552f, 0x9fd24821), + TOBN(0xae6bc70e, 0x46aca793), TOBN(0x1cf0b0e4, 0xe579311b), + TOBN(0x8dc631be, 0x5802f716), TOBN(0x099bdc6f, 0xbddbee4d), + TOBN(0xcc352bb2, 0x0caf8b05), TOBN(0xf74d505a, 0x72d63df2), + TOBN(0xb9876d4b, 0x91c4f408), TOBN(0x1ce18473, 0x9e229b2d), + TOBN(0x49507597, 0x83abdb4a), TOBN(0x850fbcb6, 0xdee84b18), + TOBN(0x6325236e, 0x609e67dc), TOBN(0x04d831d9, 0x9336c6d8), + TOBN(0x8deaae3b, 0xfa12d45d), TOBN(0xe425f8ce, 0x4746e246), + TOBN(0x8004c175, 0x24f5f31e), TOBN(0xaca16d8f, 0xad62c3b7), + TOBN(0x0dc15a6a, 0x9152f934), TOBN(0xf1235e5d, 0xed0e12c1), + TOBN(0xc33c06ec, 0xda477dac), TOBN(0x76be8732, 0xb2ea0006), + TOBN(0xcf3f7831, 0x0c0cd313), TOBN(0x3c524553, 0xa614260d), + TOBN(0x31a756f8, 0xcab22d15), TOBN(0x03ee10d1, 0x77827a20), + TOBN(0xd1e059b2, 0x1994ef20), TOBN(0x2a653b69, 0x638ae318), + TOBN(0x70d5eb58, 0x2f699010), TOBN(0x279739f7, 0x09f5f84a), + TOBN(0x5da4663c, 0x8b799336), TOBN(0xfdfdf14d, 0x203c37eb), + TOBN(0x32d8a9dc, 0xa1dbfb2d), TOBN(0xab40cff0, 0x77d48f9b), + TOBN(0xc018b383, 0xd20b42d5), TOBN(0xf9a810ef, 0x9f78845f), + TOBN(0x40af3753, 0xbdba9df0), TOBN(0xb90bdcfc, 0x131dfdf9), + TOBN(0x18720591, 0xf01ab782), TOBN(0xc823f211, 0x6af12a88), + TOBN(0xa51b80f3, 0x0dc14401), TOBN(0xde248f77, 0xfb2dfbe3), + TOBN(0xef5a44e5, 0x0cafe751), TOBN(0x73997c9c, 0xd4dcd221), + TOBN(0x32fd86d1, 0xde854024), TOBN(0xd5b53adc, 0xa09b84bb), + TOBN(0x008d7a11, 0xdcedd8d1), TOBN(0x406bd1c8, 0x74b32c84), + TOBN(0x5d4472ff, 0x05dde8b1), TOBN(0x2e25f2cd, 0xfce2b32f), + TOBN(0xbec0dd5e, 0x29dfc254), TOBN(0x4455fcf6, 0x2b98b267), + TOBN(0x0b4d43a5, 0xc72df2ad), TOBN(0xea70e6be, 0x48a75397), + TOBN(0x2aad6169, 0x5820f3bf), TOBN(0xf410d2dd, 0x9e37f68f), + TOBN(0x70fb7dba, 0x7be5ac83), TOBN(0x636bb645, 0x36ec3eec), + TOBN(0x27104ea3, 0x9754e21c), TOBN(0xbc87a3e6, 0x8d63c373), + TOBN(0x483351d7, 0x4109db9a), TOBN(0x0fa724e3, 0x60134da7), + TOBN(0x9ff44c29, 0xb0720b16), TOBN(0x2dd0cf13, 0x06aceead), + TOBN(0x5942758c, 0xe26929a6), TOBN(0x96c5db92, 0xb766a92b), + TOBN(0xcec7d4c0, 0x5f18395e), TOBN(0xd3f22744, 0x1f80d032), + TOBN(0x7a68b37a, 0xcb86075b), TOBN(0x074764dd, 0xafef92db), + TOBN(0xded1e950, 0x7bc7f389), TOBN(0xc580c850, 0xb9756460), + TOBN(0xaeeec2a4, 0x7da48157), TOBN(0x3f0b4e7f, 0x82c587b3), + TOBN(0x231c6de8, 0xa9f19c53), TOBN(0x5717bd73, 0x6974e34e), + TOBN(0xd9e1d216, 0xf1508fa9), TOBN(0x9f112361, 0xdadaa124), + TOBN(0x80145e31, 0x823b7348), TOBN(0x4dd8f0d5, 0xac634069), + TOBN(0xe3d82fc7, 0x2297c258), TOBN(0x276fcfee, 0x9cee7431), + TOBN(0x8eb61b5e, 0x2bc0aea9), TOBN(0x4f668fd5, 0xde329431), + TOBN(0x03a32ab1, 0x38e4b87e), TOBN(0xe1374517, 0x73d0ef0b), + TOBN(0x1a46f7e6, 0x853ac983), TOBN(0xc3bdf42e, 0x68e78a57), + TOBN(0xacf20785, 0x2ea96dd1), TOBN(0xa10649b9, 0xf1638460), + TOBN(0xf2369f0b, 0x879fbbed), TOBN(0x0ff0ae86, 0xda9d1869), + TOBN(0x5251d759, 0x56766f45), TOBN(0x4984d8c0, 0x2be8d0fc), + TOBN(0x7ecc95a6, 0xd21008f0), TOBN(0x29bd54a0, 0x3a1a1c49), + TOBN(0xab9828c5, 0xd26c50f3), TOBN(0x32c0087c, 0x51d0d251), + TOBN(0x9bac3ce6, 0x0c1cdb26), TOBN(0xcd94d947, 0x557ca205), + TOBN(0x1b1bd598, 0x9db1fdcd), TOBN(0x0eda0108, 0xa3d8b149), + TOBN(0x95066610, 0x56152fcc), TOBN(0xc2f037e6, 0xe7192b33), + TOBN(0xdeffb41a, 0xc92e05a4), TOBN(0x1105f6c2, 0xc2f6c62e), + TOBN(0x68e73500, 0x8733913c), TOBN(0xcce86163, 0x3f3adc40), + TOBN(0xf407a942, 0x38a278e9), TOBN(0xd13c1b9d, 0x2ab21292), + TOBN(0x93ed7ec7, 0x1c74cf5c), TOBN(0x8887dc48, 0xf1a4c1b4), + TOBN(0x3830ff30, 0x4b3a11f1), TOBN(0x358c5a3c, 0x58937cb6), + TOBN(0x027dc404, 0x89022829), TOBN(0x40e93977, 0x3b798f79), + TOBN(0x90ad3337, 0x38be6ead), TOBN(0x9c23f6bc, 0xf34c0a5d), + TOBN(0xd1711a35, 0xfbffd8bb), TOBN(0x60fcfb49, 0x1949d3dd), + TOBN(0x09c8ef4b, 0x7825d93a), TOBN(0x24233cff, 0xa0a8c968), + TOBN(0x67ade46c, 0xe6d982af), TOBN(0xebb6bf3e, 0xe7544d7c), + TOBN(0xd6b9ba76, 0x3d8bd087), TOBN(0x46fe382d, 0x4dc61280), + TOBN(0xbd39a7e8, 0xb5bdbd75), TOBN(0xab381331, 0xb8f228fe), + TOBN(0x0709a77c, 0xce1c4300), TOBN(0x6a247e56, 0xf337ceac), + TOBN(0x8f34f21b, 0x636288be), TOBN(0x9dfdca74, 0xc8a7c305), + TOBN(0x6decfd1b, 0xea919e04), TOBN(0xcdf2688d, 0x8e1991f8), + TOBN(0xe607df44, 0xd0f8a67e), TOBN(0xd985df4b, 0x0b58d010), + TOBN(0x57f834c5, 0x0c24f8f4), TOBN(0xe976ef56, 0xa0bf01ae), + TOBN(0x536395ac, 0xa1c32373), TOBN(0x351027aa, 0x734c0a13), + TOBN(0xd2f1b5d6, 0x5e6bd5bc), TOBN(0x2b539e24, 0x223debed), + TOBN(0xd4994cec, 0x0eaa1d71), TOBN(0x2a83381d, 0x661dcf65), + TOBN(0x5f1aed2f, 0x7b54c740), TOBN(0x0bea3fa5, 0xd6dda5ee), + TOBN(0x9d4fb684, 0x36cc6134), TOBN(0x8eb9bbf3, 0xc0a443dd), + TOBN(0xfc500e2e, 0x383b7d2a), TOBN(0x7aad621c, 0x5b775257), + TOBN(0x69284d74, 0x0a8f7cc0), TOBN(0xe820c2ce, 0x07562d65), + TOBN(0xbf9531b9, 0x499758ee), TOBN(0x73e95ca5, 0x6ee0cc2d), + TOBN(0xf61790ab, 0xfbaf50a5), TOBN(0xdf55e76b, 0x684e0750), + TOBN(0xec516da7, 0xf176b005), TOBN(0x575553bb, 0x7a2dddc7), + TOBN(0x37c87ca3, 0x553afa73), TOBN(0x315f3ffc, 0x4d55c251), + TOBN(0xe846442a, 0xaf3e5d35), TOBN(0x61b91149, 0x6495ff28), + TOBN(0x23cc95d3, 0xfa326dc3), TOBN(0x1df4da1f, 0x18fc2cea), + TOBN(0x24bf9adc, 0xd0a37d59), TOBN(0xb6710053, 0x320d6e1e), + TOBN(0x96f9667e, 0x618344d1), TOBN(0xcc7ce042, 0xa06445af), + TOBN(0xa02d8514, 0xd68dbc3a), TOBN(0x4ea109e4, 0x280b5a5b), + TOBN(0x5741a7ac, 0xb40961bf), TOBN(0x4ada5937, 0x6aa56bfa), + TOBN(0x7feb9145, 0x02b765d1), TOBN(0x561e97be, 0xe6ad1582), + TOBN(0xbbc4a5b6, 0xda3982f5), TOBN(0x0c2659ed, 0xb546f468), + TOBN(0xb8e7e6aa, 0x59612d20), TOBN(0xd83dfe20, 0xac19e8e0), + TOBN(0x8530c45f, 0xb835398c), TOBN(0x6106a8bf, 0xb38a41c2), + TOBN(0x21e8f9a6, 0x35f5dcdb), TOBN(0x39707137, 0xcae498ed), + TOBN(0x70c23834, 0xd8249f00), TOBN(0x9f14b58f, 0xab2537a0), + TOBN(0xd043c365, 0x5f61c0c2), TOBN(0xdc5926d6, 0x09a194a7), + TOBN(0xddec0339, 0x8e77738a), TOBN(0xd07a63ef, 0xfba46426), + TOBN(0x2e58e79c, 0xee7f6e86), TOBN(0xe59b0459, 0xff32d241), + TOBN(0xc5ec84e5, 0x20fa0338), TOBN(0x97939ac8, 0xeaff5ace), + TOBN(0x0310a4e3, 0xb4a38313), TOBN(0x9115fba2, 0x8f9d9885), + TOBN(0x8dd710c2, 0x5fadf8c3), TOBN(0x66be38a2, 0xce19c0e2), + TOBN(0xd42a279c, 0x4cfe5022), TOBN(0x597bb530, 0x0e24e1b8), + TOBN(0x3cde86b7, 0xc153ca7f), TOBN(0xa8d30fb3, 0x707d63bd), + TOBN(0xac905f92, 0xbd60d21e), TOBN(0x98e7ffb6, 0x7b9a54ab), + TOBN(0xd7147df8, 0xe9726a30), TOBN(0xb5e216ff, 0xafce3533), + TOBN(0xb550b799, 0x2ff1ec40), TOBN(0x6b613b87, 0xa1e953fd), + TOBN(0x87b88dba, 0x792d5610), TOBN(0x2ee1270a, 0xa190fbe1), + TOBN(0x02f4e2dc, 0x2ef581da), TOBN(0x016530e4, 0xeff82a95), + TOBN(0xcbb93dfd, 0x8fd6ee89), TOBN(0x16d3d986, 0x46848fff), + TOBN(0x600eff24, 0x1da47adf), TOBN(0x1b9754a0, 0x0ad47a71), + TOBN(0x8f9266df, 0x70c33b98), TOBN(0xaadc87ae, 0xdf34186e), + TOBN(0x0d2ce8e1, 0x4ad24132), TOBN(0x8a47cbfc, 0x19946eba), + TOBN(0x47feeb66, 0x62b5f3af), TOBN(0xcefab561, 0x0abb3734), + TOBN(0x449de60e, 0x19f35cb1), TOBN(0x39f8db14, 0x157f0eb9), + TOBN(0xffaecc5b, 0x3c61bfd6), TOBN(0xa5a4d41d, 0x41216703), + TOBN(0x7f8fabed, 0x224e1cc2), TOBN(0x0d5a8186, 0x871ad953), + TOBN(0xf10774f7, 0xd22da9a9), TOBN(0x45b8a678, 0xcc8a9b0d), + TOBN(0xd9c2e722, 0xbdc32cff), TOBN(0xbf71b5f5, 0x337202a5), + TOBN(0x95c57f2f, 0x69fc4db9), TOBN(0xb6dad34c, 0x765d01e1), + TOBN(0x7e0bd13f, 0xcb904635), TOBN(0x61751253, 0x763a588c), + TOBN(0xd85c2997, 0x81af2c2d), TOBN(0xc0f7d9c4, 0x81b9d7da), + TOBN(0x838a34ae, 0x08533e8d), TOBN(0x15c4cb08, 0x311d8311), + TOBN(0x97f83285, 0x8e121e14), TOBN(0xeea7dc1e, 0x85000a5f), + TOBN(0x0c6059b6, 0x5d256274), TOBN(0xec9beace, 0xb95075c0), + TOBN(0x173daad7, 0x1df97828), TOBN(0xbf851cb5, 0xa8937877), + TOBN(0xb083c594, 0x01646f3c), TOBN(0x3bad30cf, 0x50c6d352), + TOBN(0xfeb2b202, 0x496bbcea), TOBN(0x3cf9fd4f, 0x18a1e8ba), + TOBN(0xd26de7ff, 0x1c066029), TOBN(0x39c81e9e, 0x4e9ed4f8), + TOBN(0xd8be0cb9, 0x7b390d35), TOBN(0x01df2bbd, 0x964aab27), + TOBN(0x3e8c1a65, 0xc3ef64f8), TOBN(0x567291d1, 0x716ed1dd), + TOBN(0x95499c6c, 0x5f5406d3), TOBN(0x71fdda39, 0x5ba8e23f), + TOBN(0xcfeb320e, 0xd5096ece), TOBN(0xbe7ba92b, 0xca66dd16), + TOBN(0x4608d36b, 0xc6fb5a7d), TOBN(0xe3eea15a, 0x6d2dd0e0), + TOBN(0x75b0a3eb, 0x8f97a36a), TOBN(0xf59814cc, 0x1c83de1e), + TOBN(0x56c9c5b0, 0x1c33c23f), TOBN(0xa96c1da4, 0x6faa4136), + TOBN(0x46bf2074, 0xde316551), TOBN(0x3b866e7b, 0x1f756c8f), + TOBN(0x727727d8, 0x1495ed6b), TOBN(0xb2394243, 0xb682dce7), + TOBN(0x8ab8454e, 0x758610f3), TOBN(0xc243ce84, 0x857d72a4), + TOBN(0x7b320d71, 0xdbbf370f), TOBN(0xff9afa37, 0x78e0f7ca), + TOBN(0x0119d1e0, 0xea7b523f), TOBN(0xb997f8cb, 0x058c7d42), + TOBN(0x285bcd2a, 0x37bbb184), TOBN(0x51dcec49, 0xa45d1fa6), + TOBN(0x6ade3b64, 0xe29634cb), TOBN(0x080c94a7, 0x26b86ef1), + TOBN(0xba583db1, 0x2283fbe3), TOBN(0x902bddc8, 0x5a9315ed), + TOBN(0x07c1ccb3, 0x86964bec), TOBN(0x78f4eacf, 0xb6258301), + TOBN(0x4bdf3a49, 0x56f90823), TOBN(0xba0f5080, 0x741d777b), + TOBN(0x091d71c3, 0xf38bf760), TOBN(0x9633d50f, 0x9b625b02), + TOBN(0x03ecb743, 0xb8c9de61), TOBN(0xb4751254, 0x5de74720), + TOBN(0x9f9defc9, 0x74ce1cb2), TOBN(0x774a4f6a, 0x00bd32ef), + TOBN(0xaca385f7, 0x73848f22), TOBN(0x53dad716, 0xf3f8558e), + TOBN(0xab7b34b0, 0x93c471f9), TOBN(0xf530e069, 0x19644bc7), + TOBN(0x3d9fb1ff, 0xdd59d31a), TOBN(0x4382e0df, 0x08daa795), + TOBN(0x165c6f4b, 0xd5cc88d7), TOBN(0xeaa392d5, 0x4a18c900), + TOBN(0x94203c67, 0x648024ee), TOBN(0x188763f2, 0x8c2fabcd), + TOBN(0xa80f87ac, 0xbbaec835), TOBN(0x632c96e0, 0xf29d8d54), + TOBN(0x29b0a60e, 0x4c00a95e), TOBN(0x2ef17f40, 0xe011e9fa), + TOBN(0xf6c0e1d1, 0x15b77223), TOBN(0xaaec2c62, 0x14b04e32), + TOBN(0xd35688d8, 0x3d84e58c), TOBN(0x2af5094c, 0x958571db), + TOBN(0x4fff7e19, 0x760682a6), TOBN(0x4cb27077, 0xe39a407c), + TOBN(0x0f59c547, 0x4ff0e321), TOBN(0x169f34a6, 0x1b34c8ff), + TOBN(0x2bff1096, 0x52bc1ba7), TOBN(0xa25423b7, 0x83583544), + TOBN(0x5d55d5d5, 0x0ac8b782), TOBN(0xff6622ec, 0x2db3c892), + TOBN(0x48fce741, 0x6b8bb642), TOBN(0x31d6998c, 0x69d7e3dc), + TOBN(0xdbaf8004, 0xcadcaed0), TOBN(0x801b0142, 0xd81d053c), + TOBN(0x94b189fc, 0x59630ec6), TOBN(0x120e9934, 0xaf762c8e), + TOBN(0x53a29aa4, 0xfdc6a404), TOBN(0x19d8e01e, 0xa1909948), + TOBN(0x3cfcabf1, 0xd7e89681), TOBN(0x3321a50d, 0x4e132d37), + TOBN(0xd0496863, 0xe9a86111), TOBN(0x8c0cde61, 0x06a3bc65), + TOBN(0xaf866c49, 0xfc9f8eef), TOBN(0x2066350e, 0xff7f5141), + TOBN(0x4f8a4689, 0xe56ddfbd), TOBN(0xea1b0c07, 0xfe32983a), + TOBN(0x2b317462, 0x873cb8cb), TOBN(0x658deddc, 0x2d93229f), + TOBN(0x65efaf4d, 0x0f64ef58), TOBN(0xfe43287d, 0x730cc7a8), + TOBN(0xaebc0c72, 0x3d047d70), TOBN(0x92efa539, 0xd92d26c9), + TOBN(0x06e78457, 0x94b56526), TOBN(0x415cb80f, 0x0961002d), + TOBN(0x89e5c565, 0x76dcb10f), TOBN(0x8bbb6982, 0xff9259fe), + TOBN(0x4fe8795b, 0x9abc2668), TOBN(0xb5d4f534, 0x1e678fb1), + TOBN(0x6601f3be, 0x7b7da2b9), TOBN(0x98da59e2, 0xa13d6805), + TOBN(0x190d8ea6, 0x01799a52), TOBN(0xa20cec41, 0xb86d2952), + TOBN(0x3062ffb2, 0x7fff2a7c), TOBN(0x741b32e5, 0x79f19d37), + TOBN(0xf80d8181, 0x4eb57d47), TOBN(0x7a2d0ed4, 0x16aef06b), + TOBN(0x09735fb0, 0x1cecb588), TOBN(0x1641caaa, 0xc6061f5b)}, + {TOBN(0x7f99824f, 0x20151427), TOBN(0x206828b6, 0x92430206), + TOBN(0xaa9097d7, 0xe1112357), TOBN(0xacf9a2f2, 0x09e414ec), + TOBN(0xdbdac9da, 0x27915356), TOBN(0x7e0734b7, 0x001efee3), + TOBN(0x54fab5bb, 0xd2b288e2), TOBN(0x4c630fc4, 0xf62dd09c), + TOBN(0x8537107a, 0x1ac2703b), TOBN(0xb49258d8, 0x6bc857b5), + TOBN(0x57df14de, 0xbcdaccd1), TOBN(0x24ab68d7, 0xc4ae8529), + TOBN(0x7ed8b5d4, 0x734e59d0), TOBN(0x5f8740c8, 0xc495cc80), + TOBN(0x84aedd5a, 0x291db9b3), TOBN(0x80b360f8, 0x4fb995be), + TOBN(0xae915f5d, 0x5fa067d1), TOBN(0x4134b57f, 0x9668960c), + TOBN(0xbd3656d6, 0xa48edaac), TOBN(0xdac1e3e4, 0xfc1d7436), + TOBN(0x674ff869, 0xd81fbb26), TOBN(0x449ed3ec, 0xb26c33d4), + TOBN(0x85138705, 0xd94203e8), TOBN(0xccde538b, 0xbeeb6f4a), + TOBN(0x55d5c68d, 0xa61a76fa), TOBN(0x598b441d, 0xca1554dc), + TOBN(0xd39923b9, 0x773b279c), TOBN(0x33331d3c, 0x36bf9efc), + TOBN(0x2d4c848e, 0x298de399), TOBN(0xcfdb8e77, 0xa1a27f56), + TOBN(0x94c855ea, 0x57b8ab70), TOBN(0xdcdb9dae, 0x6f7879ba), + TOBN(0x7bdff8c2, 0x019f2a59), TOBN(0xb3ce5bb3, 0xcb4fbc74), + TOBN(0xea907f68, 0x8a9173dd), TOBN(0x6cd3d0d3, 0x95a75439), + TOBN(0x92ecc4d6, 0xefed021c), TOBN(0x09a9f9b0, 0x6a77339a), + TOBN(0x87ca6b15, 0x7188c64a), TOBN(0x10c29968, 0x44899158), + TOBN(0x5859a229, 0xed6e82ef), TOBN(0x16f338e3, 0x65ebaf4e), + TOBN(0x0cd31387, 0x5ead67ae), TOBN(0x1c73d228, 0x54ef0bb4), + TOBN(0x4cb55131, 0x74a5c8c7), TOBN(0x01cd2970, 0x7f69ad6a), + TOBN(0xa04d00dd, 0xe966f87e), TOBN(0xd96fe447, 0x0b7b0321), + TOBN(0x342ac06e, 0x88fbd381), TOBN(0x02cd4a84, 0x5c35a493), + TOBN(0xe8fa89de, 0x54f1bbcd), TOBN(0x341d6367, 0x2575ed4c), + TOBN(0xebe357fb, 0xd238202b), TOBN(0x600b4d1a, 0xa984ead9), + TOBN(0xc35c9f44, 0x52436ea0), TOBN(0x96fe0a39, 0xa370751b), + TOBN(0x4c4f0736, 0x7f636a38), TOBN(0x9f943fb7, 0x0e76d5cb), + TOBN(0xb03510ba, 0xa8b68b8b), TOBN(0xc246780a, 0x9ed07a1f), + TOBN(0x3c051415, 0x6d549fc2), TOBN(0xc2953f31, 0x607781ca), + TOBN(0x955e2c69, 0xd8d95413), TOBN(0xb300fadc, 0x7bd282e3), + TOBN(0x81fe7b50, 0x87e9189f), TOBN(0xdb17375c, 0xf42dda27), + TOBN(0x22f7d896, 0xcf0a5904), TOBN(0xa0e57c5a, 0xebe348e6), + TOBN(0xa61011d3, 0xf40e3c80), TOBN(0xb1189321, 0x8db705c5), + TOBN(0x4ed9309e, 0x50fedec3), TOBN(0xdcf14a10, 0x4d6d5c1d), + TOBN(0x056c265b, 0x55691342), TOBN(0xe8e08504, 0x91049dc7), + TOBN(0x131329f5, 0xc9bae20a), TOBN(0x96c8b3e8, 0xd9dccdb4), + TOBN(0x8c5ff838, 0xfb4ee6b4), TOBN(0xfc5a9aeb, 0x41e8ccf0), + TOBN(0x7417b764, 0xfae050c6), TOBN(0x0953c3d7, 0x00452080), + TOBN(0x21372682, 0x38dfe7e8), TOBN(0xea417e15, 0x2bb79d4b), + TOBN(0x59641f1c, 0x76e7cf2d), TOBN(0x271e3059, 0xea0bcfcc), + TOBN(0x624c7dfd, 0x7253ecbd), TOBN(0x2f552e25, 0x4fca6186), + TOBN(0xcbf84ecd, 0x4d866e9c), TOBN(0x73967709, 0xf68d4610), + TOBN(0xa14b1163, 0xc27901b4), TOBN(0xfd9236e0, 0x899b8bf3), + TOBN(0x42b091ec, 0xcbc6da0a), TOBN(0xbb1dac6f, 0x5ad1d297), + TOBN(0x80e61d53, 0xa91cf76e), TOBN(0x4110a412, 0xd31f1ee7), + TOBN(0x2d87c3ba, 0x13efcf77), TOBN(0x1f374bb4, 0xdf450d76), + TOBN(0x5e78e2f2, 0x0d188dab), TOBN(0xe3968ed0, 0xf4b885ef), + TOBN(0x46c0568e, 0x7314570f), TOBN(0x31616338, 0x01170521), + TOBN(0x18e1e7e2, 0x4f0c8afe), TOBN(0x4caa75ff, 0xdeea78da), + TOBN(0x82db67f2, 0x7c5d8a51), TOBN(0x36a44d86, 0x6f505370), + TOBN(0xd72c5bda, 0x0333974f), TOBN(0x5db516ae, 0x27a70146), + TOBN(0x34705281, 0x210ef921), TOBN(0xbff17a8f, 0x0c9c38e5), + TOBN(0x78f4814e, 0x12476da1), TOBN(0xc1e16613, 0x33c16980), + TOBN(0x9e5b386f, 0x424d4bca), TOBN(0x4c274e87, 0xc85740de), + TOBN(0xb6a9b88d, 0x6c2f5226), TOBN(0x14d1b944, 0x550d7ca8), + TOBN(0x580c85fc, 0x1fc41709), TOBN(0xc1da368b, 0x54c6d519), + TOBN(0x2b0785ce, 0xd5113cf7), TOBN(0x0670f633, 0x5a34708f), + TOBN(0x46e23767, 0x15cc3f88), TOBN(0x1b480cfa, 0x50c72c8f), + TOBN(0x20288602, 0x4147519a), TOBN(0xd0981eac, 0x26b372f0), + TOBN(0xa9d4a7ca, 0xa785ebc8), TOBN(0xd953c50d, 0xdbdf58e9), + TOBN(0x9d6361cc, 0xfd590f8f), TOBN(0x72e9626b, 0x44e6c917), + TOBN(0x7fd96110, 0x22eb64cf), TOBN(0x863ebb7e, 0x9eb288f3), + TOBN(0x6e6ab761, 0x6aca8ee7), TOBN(0x97d10b39, 0xd7b40358), + TOBN(0x1687d377, 0x1e5feb0d), TOBN(0xc83e50e4, 0x8265a27a), + TOBN(0x8f75a9fe, 0xc954b313), TOBN(0xcc2e8f47, 0x310d1f61), + TOBN(0xf5ba81c5, 0x6557d0e0), TOBN(0x25f9680c, 0x3eaf6207), + TOBN(0xf95c6609, 0x4354080b), TOBN(0x5225bfa5, 0x7bf2fe1c), + TOBN(0xc5c004e2, 0x5c7d98fa), TOBN(0x3561bf1c, 0x019aaf60), + TOBN(0x5e6f9f17, 0xba151474), TOBN(0xdec2f934, 0xb04f6eca), + TOBN(0x64e368a1, 0x269acb1e), TOBN(0x1332d9e4, 0x0cdda493), + TOBN(0x60d6cf69, 0xdf23de05), TOBN(0x66d17da2, 0x009339a0), + TOBN(0x9fcac985, 0x0a693923), TOBN(0xbcf057fc, 0xed7c6a6d), + TOBN(0xc3c5c8c5, 0xf0b5662c), TOBN(0x25318dd8, 0xdcba4f24), + TOBN(0x60e8cb75, 0x082b69ff), TOBN(0x7c23b3ee, 0x1e728c01), + TOBN(0x15e10a0a, 0x097e4403), TOBN(0xcb3d0a86, 0x19854665), + TOBN(0x88d8e211, 0xd67d4826), TOBN(0xb39af66e, 0x0b9d2839), + TOBN(0xa5f94588, 0xbd475ca8), TOBN(0xe06b7966, 0xc077b80b), + TOBN(0xfedb1485, 0xda27c26c), TOBN(0xd290d33a, 0xfe0fd5e0), + TOBN(0xa40bcc47, 0xf34fb0fa), TOBN(0xb4760cc8, 0x1fb1ab09), + TOBN(0x8fca0993, 0xa273bfe3), TOBN(0x13e4fe07, 0xf70b213c), + TOBN(0x3bcdb992, 0xfdb05163), TOBN(0x8c484b11, 0x0c2b19b6), + TOBN(0x1acb815f, 0xaaf2e3e2), TOBN(0xc6905935, 0xb89ff1b4), + TOBN(0xb2ad6f9d, 0x586e74e1), TOBN(0x488883ad, 0x67b80484), + TOBN(0x758aa2c7, 0x369c3ddb), TOBN(0x8ab74e69, 0x9f9afd31), + TOBN(0x10fc2d28, 0x5e21beb1), TOBN(0x3484518a, 0x318c42f9), + TOBN(0x377427dc, 0x53cf40c3), TOBN(0x9de0781a, 0x391bc1d9), + TOBN(0x8faee858, 0x693807e1), TOBN(0xa3865327, 0x4e81ccc7), + TOBN(0x02c30ff2, 0x6f835b84), TOBN(0xb604437b, 0x0d3d38d4), + TOBN(0xb3fc8a98, 0x5ca1823d), TOBN(0xb82f7ec9, 0x03be0324), + TOBN(0xee36d761, 0xcf684a33), TOBN(0x5a01df0e, 0x9f29bf7d), + TOBN(0x686202f3, 0x1306583d), TOBN(0x05b10da0, 0x437c622e), + TOBN(0xbf9aaa0f, 0x076a7bc8), TOBN(0x25e94efb, 0x8f8f4e43), + TOBN(0x8a35c9b7, 0xfa3dc26d), TOBN(0xe0e5fb93, 0x96ff03c5), + TOBN(0xa77e3843, 0xebc394ce), TOBN(0xcede6595, 0x8361de60), + TOBN(0xd27c22f6, 0xa1993545), TOBN(0xab01cc36, 0x24d671ba), + TOBN(0x63fa2877, 0xa169c28e), TOBN(0x925ef904, 0x2eb08376), + TOBN(0x3b2fa3cf, 0x53aa0b32), TOBN(0xb27beb5b, 0x71c49d7a), + TOBN(0xb60e1834, 0xd105e27f), TOBN(0xd6089788, 0x4f68570d), + TOBN(0x23094ce0, 0xd6fbc2ac), TOBN(0x738037a1, 0x815ff551), + TOBN(0xda73b1bb, 0x6bef119c), TOBN(0xdcf6c430, 0xeef506ba), + TOBN(0x00e4fe7b, 0xe3ef104a), TOBN(0xebdd9a2c, 0x0a065628), + TOBN(0x853a81c3, 0x8792043e), TOBN(0x22ad6ece, 0xb3b59108), + TOBN(0x9fb813c0, 0x39cd297d), TOBN(0x8ec7e16e, 0x05bda5d9), + TOBN(0x2834797c, 0x0d104b96), TOBN(0xcc11a2e7, 0x7c511510), + TOBN(0x96ca5a53, 0x96ee6380), TOBN(0x054c8655, 0xcea38742), + TOBN(0xb5946852, 0xd54dfa7d), TOBN(0x97c422e7, 0x1f4ab207), + TOBN(0xbf907509, 0x0c22b540), TOBN(0x2cde42aa, 0xb7c267d4), + TOBN(0xba18f9ed, 0x5ab0d693), TOBN(0x3ba62aa6, 0x6e4660d9), + TOBN(0xb24bf97b, 0xab9ea96a), TOBN(0x5d039642, 0xe3b60e32), + TOBN(0x4e6a4506, 0x7c4d9bd5), TOBN(0x666c5b9e, 0x7ed4a6a4), + TOBN(0xfa3fdcd9, 0x8edbd7cc), TOBN(0x4660bb87, 0xc6ccd753), + TOBN(0x9ae90820, 0x21e6b64f), TOBN(0x8a56a713, 0xb36bfb3f), + TOBN(0xabfce096, 0x5726d47f), TOBN(0x9eed01b2, 0x0b1a9a7f), + TOBN(0x30e9cad4, 0x4eb74a37), TOBN(0x7b2524cc, 0x53e9666d), + TOBN(0x6a29683b, 0x8f4b002f), TOBN(0xc2200d7a, 0x41f4fc20), + TOBN(0xcf3af47a, 0x3a338acc), TOBN(0x6539a4fb, 0xe7128975), + TOBN(0xcec31c14, 0xc33c7fcf), TOBN(0x7eb6799b, 0xc7be322b), + TOBN(0x119ef4e9, 0x6646f623), TOBN(0x7b7a26a5, 0x54d7299b), + TOBN(0xcb37f08d, 0x403f46f2), TOBN(0x94b8fc43, 0x1a0ec0c7), + TOBN(0xbb8514e3, 0xc332142f), TOBN(0xf3ed2c33, 0xe80d2a7a), + TOBN(0x8d2080af, 0xb639126c), TOBN(0xf7b6be60, 0xe3553ade), + TOBN(0x3950aa9f, 0x1c7e2b09), TOBN(0x847ff958, 0x6410f02b), + TOBN(0x877b7cf5, 0x678a31b0), TOBN(0xd50301ae, 0x3998b620), + TOBN(0x734257c5, 0xc00fb396), TOBN(0xf9fb18a0, 0x04e672a6), + TOBN(0xff8bd8eb, 0xe8758851), TOBN(0x1e64e4c6, 0x5d99ba44), + TOBN(0x4b8eaedf, 0x7dfd93b7), TOBN(0xba2f2a98, 0x04e76b8c), + TOBN(0x7d790cba, 0xe8053433), TOBN(0xc8e725a0, 0x3d2c9585), + TOBN(0x58c5c476, 0xcdd8f5ed), TOBN(0xd106b952, 0xefa9fe1d), + TOBN(0x3c5c775b, 0x0eff13a9), TOBN(0x242442ba, 0xe057b930), + TOBN(0xe9f458d4, 0xc9b70cbd), TOBN(0x69b71448, 0xa3cdb89a), + TOBN(0x41ee46f6, 0x0e2ed742), TOBN(0x573f1045, 0x40067493), + TOBN(0xb1e154ff, 0x9d54c304), TOBN(0x2ad0436a, 0x8d3a7502), + TOBN(0xee4aaa2d, 0x431a8121), TOBN(0xcd38b3ab, 0x886f11ed), + TOBN(0x57d49ea6, 0x034a0eb7), TOBN(0xd2b773bd, 0xf7e85e58), + TOBN(0x4a559ac4, 0x9b5c1f14), TOBN(0xc444be1a, 0x3e54df2b), + TOBN(0x13aad704, 0xeda41891), TOBN(0xcd927bec, 0x5eb5c788), + TOBN(0xeb3c8516, 0xe48c8a34), TOBN(0x1b7ac812, 0x4b546669), + TOBN(0x1815f896, 0x594df8ec), TOBN(0x87c6a79c, 0x79227865), + TOBN(0xae02a2f0, 0x9b56ddbd), TOBN(0x1339b5ac, 0x8a2f1cf3), + TOBN(0xf2b569c7, 0x839dff0d), TOBN(0xb0b9e864, 0xfee9a43d), + TOBN(0x4ff8ca41, 0x77bb064e), TOBN(0x145a2812, 0xfd249f63), + TOBN(0x3ab7beac, 0xf86f689a), TOBN(0x9bafec27, 0x01d35f5e), + TOBN(0x28054c65, 0x4265aa91), TOBN(0xa4b18304, 0x035efe42), + TOBN(0x6887b0e6, 0x9639dec7), TOBN(0xf4b8f6ad, 0x3d52aea5), + TOBN(0xfb9293cc, 0x971a8a13), TOBN(0x3f159e5d, 0x4c934d07), + TOBN(0x2c50e9b1, 0x09acbc29), TOBN(0x08eb65e6, 0x7154d129), + TOBN(0x4feff589, 0x30b75c3e), TOBN(0x0bb82fe2, 0x94491c93), + TOBN(0xd8ac377a, 0x89af62bb), TOBN(0xd7b51490, 0x9685e49f), + TOBN(0xabca9a7b, 0x04497f19), TOBN(0x1b35ed0a, 0x1a7ad13f), + TOBN(0x6b601e21, 0x3ec86ed6), TOBN(0xda91fcb9, 0xce0c76f1), + TOBN(0x9e28507b, 0xd7ab27e1), TOBN(0x7c19a555, 0x63945b7b), + TOBN(0x6b43f0a1, 0xaafc9827), TOBN(0x443b4fbd, 0x3aa55b91), + TOBN(0x962b2e65, 0x6962c88f), TOBN(0x139da8d4, 0xce0db0ca), + TOBN(0xb93f05dd, 0x1b8d6c4f), TOBN(0x779cdff7, 0x180b9824), + TOBN(0xbba23fdd, 0xae57c7b7), TOBN(0x345342f2, 0x1b932522), + TOBN(0xfd9c80fe, 0x556d4aa3), TOBN(0xa03907ba, 0x6525bb61), + TOBN(0x38b010e1, 0xff218933), TOBN(0xc066b654, 0xaa52117b), + TOBN(0x8e141920, 0x94f2e6ea), TOBN(0x66a27dca, 0x0d32f2b2), + TOBN(0x69c7f993, 0x048b3717), TOBN(0xbf5a989a, 0xb178ae1c), + TOBN(0x49fa9058, 0x564f1d6b), TOBN(0x27ec6e15, 0xd31fde4e), + TOBN(0x4cce0373, 0x7276e7fc), TOBN(0x64086d79, 0x89d6bf02), + TOBN(0x5a72f046, 0x4ccdd979), TOBN(0x909c3566, 0x47775631), + TOBN(0x1c07bc6b, 0x75dd7125), TOBN(0xb4c6bc97, 0x87a0428d), + TOBN(0x507ece52, 0xfdeb6b9d), TOBN(0xfca56512, 0xb2c95432), + TOBN(0x15d97181, 0xd0e8bd06), TOBN(0x384dd317, 0xc6bb46ea), + TOBN(0x5441ea20, 0x3952b624), TOBN(0xbcf70dee, 0x4e7dc2fb), + TOBN(0x372b016e, 0x6628e8c3), TOBN(0x07a0d667, 0xb60a7522), + TOBN(0xcf05751b, 0x0a344ee2), TOBN(0x0ec09a48, 0x118bdeec), + TOBN(0x6e4b3d4e, 0xd83dce46), TOBN(0x43a6316d, 0x99d2fc6e), + TOBN(0xa99d8989, 0x56cf044c), TOBN(0x7c7f4454, 0xae3e5fb7), + TOBN(0xb2e6b121, 0xfbabbe92), TOBN(0x281850fb, 0xe1330076), + TOBN(0x093581ec, 0x97890015), TOBN(0x69b1dded, 0x75ff77f5), + TOBN(0x7cf0b18f, 0xab105105), TOBN(0x953ced31, 0xa89ccfef), + TOBN(0x3151f85f, 0xeb914009), TOBN(0x3c9f1b87, 0x88ed48ad), + TOBN(0xc9aba1a1, 0x4a7eadcb), TOBN(0x928e7501, 0x522e71cf), + TOBN(0xeaede727, 0x3a2e4f83), TOBN(0x467e10d1, 0x1ce3bbd3), + TOBN(0xf3442ac3, 0xb955dcf0), TOBN(0xba96307d, 0xd3d5e527), + TOBN(0xf763a10e, 0xfd77f474), TOBN(0x5d744bd0, 0x6a6e1ff0), + TOBN(0xd287282a, 0xa777899e), TOBN(0xe20eda8f, 0xd03f3cde), + TOBN(0x6a7e75bb, 0x50b07d31), TOBN(0x0b7e2a94, 0x6f379de4), + TOBN(0x31cb64ad, 0x19f593cf), TOBN(0x7b1a9e4f, 0x1e76ef1d), + TOBN(0xe18c9c9d, 0xb62d609c), TOBN(0x439bad6d, 0xe779a650), + TOBN(0x219d9066, 0xe032f144), TOBN(0x1db632b8, 0xe8b2ec6a), + TOBN(0xff0d0fd4, 0xfda12f78), TOBN(0x56fb4c2d, 0x2a25d265), + TOBN(0x5f4e2ee1, 0x255a03f1), TOBN(0x61cd6af2, 0xe96af176), + TOBN(0xe0317ba8, 0xd068bc97), TOBN(0x927d6bab, 0x264b988e), + TOBN(0xa18f07e0, 0xe90fb21e), TOBN(0x00fd2b80, 0xbba7fca1), + TOBN(0x20387f27, 0x95cd67b5), TOBN(0x5b89a4e7, 0xd39707f7), + TOBN(0x8f83ad3f, 0x894407ce), TOBN(0xa0025b94, 0x6c226132), + TOBN(0xc79563c7, 0xf906c13b), TOBN(0x5f548f31, 0x4e7bb025), + TOBN(0x2b4c6b8f, 0xeac6d113), TOBN(0xa67e3f9c, 0x0e813c76), + TOBN(0x3982717c, 0x3fe1f4b9), TOBN(0x58865819, 0x26d8050e), + TOBN(0x99f3640c, 0xf7f06f20), TOBN(0xdc610216, 0x2a66ebc2), + TOBN(0x52f2c175, 0x767a1e08), TOBN(0x05660e1a, 0x5999871b), + TOBN(0x6b0f1762, 0x6d3c4693), TOBN(0xf0e7d627, 0x37ed7bea), + TOBN(0xc51758c7, 0xb75b226d), TOBN(0x40a88628, 0x1f91613b), + TOBN(0x889dbaa7, 0xbbb38ce0), TOBN(0xe0404b65, 0xbddcad81), + TOBN(0xfebccd3a, 0x8bc9671f), TOBN(0xfbf9a357, 0xee1f5375), + TOBN(0x5dc169b0, 0x28f33398), TOBN(0xb07ec11d, 0x72e90f65), + TOBN(0xae7f3b4a, 0xfaab1eb1), TOBN(0xd970195e, 0x5f17538a), + TOBN(0x52b05cbe, 0x0181e640), TOBN(0xf5debd62, 0x2643313d), + TOBN(0x76148154, 0x5df31f82), TOBN(0x23e03b33, 0x3a9e13c5), + TOBN(0xff758949, 0x4fde0c1f), TOBN(0xbf8a1abe, 0xe5b6ec20), + TOBN(0x702278fb, 0x87e1db6c), TOBN(0xc447ad7a, 0x35ed658f), + TOBN(0x48d4aa38, 0x03d0ccf2), TOBN(0x80acb338, 0x819a7c03), + TOBN(0x9bc7c89e, 0x6e17cecc), TOBN(0x46736b8b, 0x03be1d82), + TOBN(0xd65d7b60, 0xc0432f96), TOBN(0xddebe7a3, 0xdeb5442f), + TOBN(0x79a25307, 0x7dff69a2), TOBN(0x37a56d94, 0x02cf3122), + TOBN(0x8bab8aed, 0xf2350d0a), TOBN(0x13c3f276, 0x037b0d9a), + TOBN(0xc664957c, 0x44c65cae), TOBN(0x88b44089, 0xc2e71a88), + TOBN(0xdb88e5a3, 0x5cb02664), TOBN(0x5d4c0bf1, 0x8686c72e), + TOBN(0xea3d9b62, 0xa682d53e), TOBN(0x9b605ef4, 0x0b2ad431), + TOBN(0x71bac202, 0xc69645d0), TOBN(0xa115f03a, 0x6a1b66e7), + TOBN(0xfe2c563a, 0x158f4dc4), TOBN(0xf715b3a0, 0x4d12a78c), + TOBN(0x8f7f0a48, 0xd413213a), TOBN(0x2035806d, 0xc04becdb), + TOBN(0xecd34a99, 0x5d8587f5), TOBN(0x4d8c3079, 0x9f6d3a71), + TOBN(0x1b2a2a67, 0x8d95a8f6), TOBN(0xc58c9d7d, 0xf2110d0d), + TOBN(0xdeee81d5, 0xcf8fba3f), TOBN(0xa42be3c0, 0x0c7cdf68), + TOBN(0x2126f742, 0xd43b5eaa), TOBN(0x054a0766, 0xdfa59b85), + TOBN(0x9d0d5e36, 0x126bfd45), TOBN(0xa1f8fbd7, 0x384f8a8f), + TOBN(0x317680f5, 0xd563fccc), TOBN(0x48ca5055, 0xf280a928), + TOBN(0xe00b81b2, 0x27b578cf), TOBN(0x10aad918, 0x2994a514), + TOBN(0xd9e07b62, 0xb7bdc953), TOBN(0x9f0f6ff2, 0x5bc086dd), + TOBN(0x09d1ccff, 0x655eee77), TOBN(0x45475f79, 0x5bef7df1), + TOBN(0x3faa28fa, 0x86f702cc), TOBN(0x92e60905, 0x0f021f07), + TOBN(0xe9e62968, 0x7f8fa8c6), TOBN(0xbd71419a, 0xf036ea2c), + TOBN(0x171ee1cc, 0x6028da9a), TOBN(0x5352fe1a, 0xc251f573), + TOBN(0xf8ff236e, 0x3fa997f4), TOBN(0xd831b6c9, 0xa5749d5f), + TOBN(0x7c872e1d, 0xe350e2c2), TOBN(0xc56240d9, 0x1e0ce403), + TOBN(0xf9deb077, 0x6974f5cb), TOBN(0x7d50ba87, 0x961c3728), + TOBN(0xd6f89426, 0x5a3a2518), TOBN(0xcf817799, 0xc6303d43), + TOBN(0x510a0471, 0x619e5696), TOBN(0xab049ff6, 0x3a5e307b), + TOBN(0xe4cdf9b0, 0xfeb13ec7), TOBN(0xd5e97117, 0x9d8ff90c), + TOBN(0xf6f64d06, 0x9afa96af), TOBN(0x00d0bf5e, 0x9d2012a2), + TOBN(0xe63f301f, 0x358bcdc0), TOBN(0x07689e99, 0x0a9d47f8), + TOBN(0x1f689e2f, 0x4f43d43a), TOBN(0x4d542a16, 0x90920904), + TOBN(0xaea293d5, 0x9ca0a707), TOBN(0xd061fe45, 0x8ac68065), + TOBN(0x1033bf1b, 0x0090008c), TOBN(0x29749558, 0xc08a6db6), + TOBN(0x74b5fc59, 0xc1d5d034), TOBN(0xf712e9f6, 0x67e215e0), + TOBN(0xfd520cbd, 0x860200e6), TOBN(0x0229acb4, 0x3ea22588), + TOBN(0x9cd1e14c, 0xfff0c82e), TOBN(0x87684b62, 0x59c69e73), + TOBN(0xda85e61c, 0x96ccb989), TOBN(0x2d5dbb02, 0xa3d06493), + TOBN(0xf22ad33a, 0xe86b173c), TOBN(0xe8e41ea5, 0xa79ff0e3), + TOBN(0x01d2d725, 0xdd0d0c10), TOBN(0x31f39088, 0x032d28f9), + TOBN(0x7b3f71e1, 0x7829839e), TOBN(0x0cf691b4, 0x4502ae58), + TOBN(0xef658dbd, 0xbefc6115), TOBN(0xa5cd6ee5, 0xb3ab5314), + TOBN(0x206c8d7b, 0x5f1d2347), TOBN(0x794645ba, 0x4cc2253a), + TOBN(0xd517d8ff, 0x58389e08), TOBN(0x4fa20dee, 0x9f847288), + TOBN(0xeba072d8, 0xd797770a), TOBN(0x7360c91d, 0xbf429e26), + TOBN(0x7200a3b3, 0x80af8279), TOBN(0x6a1c9150, 0x82dadce3), + TOBN(0x0ee6d3a7, 0xc35d8794), TOBN(0x042e6558, 0x0356bae5), + TOBN(0x9f59698d, 0x643322fd), TOBN(0x9379ae15, 0x50a61967), + TOBN(0x64b9ae62, 0xfcc9981e), TOBN(0xaed3d631, 0x6d2934c6), + TOBN(0x2454b302, 0x5e4e65eb), TOBN(0xab09f647, 0xf9950428)}, + {TOBN(0xb2083a12, 0x22248acc), TOBN(0x1f6ec0ef, 0x3264e366), + TOBN(0x5659b704, 0x5afdee28), TOBN(0x7a823a40, 0xe6430bb5), + TOBN(0x24592a04, 0xe1900a79), TOBN(0xcde09d4a, 0xc9ee6576), + TOBN(0x52b6463f, 0x4b5ea54a), TOBN(0x1efe9ed3, 0xd3ca65a7), + TOBN(0xe27a6dbe, 0x305406dd), TOBN(0x8eb7dc7f, 0xdd5d1957), + TOBN(0xf54a6876, 0x387d4d8f), TOBN(0x9c479409, 0xc7762de4), + TOBN(0xbe4d5b5d, 0x99b30778), TOBN(0x25380c56, 0x6e793682), + TOBN(0x602d37f3, 0xdac740e3), TOBN(0x140deabe, 0x1566e4ae), + TOBN(0x4481d067, 0xafd32acf), TOBN(0xd8f0fcca, 0xe1f71ccf), + TOBN(0xd208dd0c, 0xb596f2da), TOBN(0xd049d730, 0x9aad93f9), + TOBN(0xc79f263d, 0x42ab580e), TOBN(0x09411bb1, 0x23f707b4), + TOBN(0x8cfde1ff, 0x835e0eda), TOBN(0x72707490, 0x90f03402), + TOBN(0xeaee6126, 0xc49a861e), TOBN(0x024f3b65, 0xe14f0d06), + TOBN(0x51a3f1e8, 0xc69bfc17), TOBN(0xc3c3a8e9, 0xa7686381), + TOBN(0x3400752c, 0xb103d4c8), TOBN(0x02bc4613, 0x9218b36b), + TOBN(0xc67f75eb, 0x7651504a), TOBN(0xd6848b56, 0xd02aebfa), + TOBN(0xbd9802e6, 0xc30fa92b), TOBN(0x5a70d96d, 0x9a552784), + TOBN(0x9085c4ea, 0x3f83169b), TOBN(0xfa9423bb, 0x06908228), + TOBN(0x2ffebe12, 0xfe97a5b9), TOBN(0x85da6049, 0x71b99118), + TOBN(0x9cbc2f7f, 0x63178846), TOBN(0xfd96bc70, 0x9153218e), + TOBN(0x958381db, 0x1782269b), TOBN(0xae34bf79, 0x2597e550), + TOBN(0xbb5c6064, 0x5f385153), TOBN(0x6f0e96af, 0xe3088048), + TOBN(0xbf6a0215, 0x77884456), TOBN(0xb3b5688c, 0x69310ea7), + TOBN(0x17c94295, 0x04fad2de), TOBN(0xe020f0e5, 0x17896d4d), + TOBN(0x730ba0ab, 0x0976505f), TOBN(0x567f6813, 0x095e2ec5), + TOBN(0x47062010, 0x6331ab71), TOBN(0x72cfa977, 0x41d22b9f), + TOBN(0x33e55ead, 0x8a2373da), TOBN(0xa8d0d5f4, 0x7ba45a68), + TOBN(0xba1d8f9c, 0x03029d15), TOBN(0x8f34f1cc, 0xfc55b9f3), + TOBN(0xcca4428d, 0xbbe5a1a9), TOBN(0x8187fd5f, 0x3126bd67), + TOBN(0x0036973a, 0x48105826), TOBN(0xa39b6663, 0xb8bd61a0), + TOBN(0x6d42deef, 0x2d65a808), TOBN(0x4969044f, 0x94636b19), + TOBN(0xf611ee47, 0xdd5d564c), TOBN(0x7b2f3a49, 0xd2873077), + TOBN(0x94157d45, 0x300eb294), TOBN(0x2b2a656e, 0x169c1494), + TOBN(0xc000dd76, 0xd3a47aa9), TOBN(0xa2864e4f, 0xa6243ea4), + TOBN(0x82716c47, 0xdb89842e), TOBN(0x12dfd7d7, 0x61479fb7), + TOBN(0x3b9a2c56, 0xe0b2f6dc), TOBN(0x46be862a, 0xd7f85d67), + TOBN(0x03b0d8dd, 0x0f82b214), TOBN(0x460c34f9, 0xf103cbc6), + TOBN(0xf32e5c03, 0x18d79e19), TOBN(0x8b8888ba, 0xa84117f8), + TOBN(0x8f3c37dc, 0xc0722677), TOBN(0x10d21be9, 0x1c1c0f27), + TOBN(0xd47c8468, 0xe0f7a0c6), TOBN(0x9bf02213, 0xadecc0e0), + TOBN(0x0baa7d12, 0x42b48b99), TOBN(0x1bcb665d, 0x48424096), + TOBN(0x8b847cd6, 0xebfb5cfb), TOBN(0x87c2ae56, 0x9ad4d10d), + TOBN(0xf1cbb122, 0x0de36726), TOBN(0xe7043c68, 0x3fdfbd21), + TOBN(0x4bd0826a, 0x4e79d460), TOBN(0x11f5e598, 0x4bd1a2cb), + TOBN(0x97554160, 0xb7fe7b6e), TOBN(0x7d16189a, 0x400a3fb2), + TOBN(0xd73e9bea, 0xe328ca1e), TOBN(0x0dd04b97, 0xe793d8cc), + TOBN(0xa9c83c9b, 0x506db8cc), TOBN(0x5cd47aae, 0xcf38814c), + TOBN(0x26fc430d, 0xb64b45e6), TOBN(0x079b5499, 0xd818ea84), + TOBN(0xebb01102, 0xc1c24a3b), TOBN(0xca24e568, 0x1c161c1a), + TOBN(0x103eea69, 0x36f00a4a), TOBN(0x9ad76ee8, 0x76176c7b), + TOBN(0x97451fc2, 0x538e0ff7), TOBN(0x94f89809, 0x6604b3b0), + TOBN(0x6311436e, 0x3249cfd7), TOBN(0x27b4a7bd, 0x41224f69), + TOBN(0x03b5d21a, 0xe0ac2941), TOBN(0x279b0254, 0xc2d31937), + TOBN(0x3307c052, 0xcac992d0), TOBN(0x6aa7cb92, 0xefa8b1f3), + TOBN(0x5a182580, 0x0d37c7a5), TOBN(0x13380c37, 0x342d5422), + TOBN(0x92ac2d66, 0xd5d2ef92), TOBN(0x035a70c9, 0x030c63c6), + TOBN(0xc16025dd, 0x4ce4f152), TOBN(0x1f419a71, 0xf9df7c06), + TOBN(0x6d5b2214, 0x91e4bb14), TOBN(0xfc43c6cc, 0x839fb4ce), + TOBN(0x49f06591, 0x925d6b2d), TOBN(0x4b37d9d3, 0x62186598), + TOBN(0x8c54a971, 0xd01b1629), TOBN(0xe1a9c29f, 0x51d50e05), + TOBN(0x5109b785, 0x71ba1861), TOBN(0x48b22d5c, 0xd0c8f93d), + TOBN(0xe8fa84a7, 0x8633bb93), TOBN(0x53fba6ba, 0x5aebbd08), + TOBN(0x7ff27df3, 0xe5eea7d8), TOBN(0x521c8796, 0x68ca7158), + TOBN(0xb9d5133b, 0xce6f1a05), TOBN(0x2d50cd53, 0xfd0ebee4), + TOBN(0xc82115d6, 0xc5a3ef16), TOBN(0x993eff9d, 0xba079221), + TOBN(0xe4da2c5e, 0x4b5da81c), TOBN(0x9a89dbdb, 0x8033fd85), + TOBN(0x60819ebf, 0x2b892891), TOBN(0x53902b21, 0x5d14a4d5), + TOBN(0x6ac35051, 0xd7fda421), TOBN(0xcc6ab885, 0x61c83284), + TOBN(0x14eba133, 0xf74cff17), TOBN(0x240aaa03, 0xecb813f2), + TOBN(0xcfbb6540, 0x6f665bee), TOBN(0x084b1fe4, 0xa425ad73), + TOBN(0x009d5d16, 0xd081f6a6), TOBN(0x35304fe8, 0xeef82c90), + TOBN(0xf20346d5, 0xaa9eaa22), TOBN(0x0ada9f07, 0xac1c91e3), + TOBN(0xa6e21678, 0x968a6144), TOBN(0x54c1f77c, 0x07b31a1e), + TOBN(0xd6bb787e, 0x5781fbe1), TOBN(0x61bd2ee0, 0xe31f1c4a), + TOBN(0xf25aa1e9, 0x781105fc), TOBN(0x9cf2971f, 0x7b2f8e80), + TOBN(0x26d15412, 0xcdff919b), TOBN(0x01db4ebe, 0x34bc896e), + TOBN(0x7d9b3e23, 0xb40df1cf), TOBN(0x59337373, 0x94e971b4), + TOBN(0xbf57bd14, 0x669cf921), TOBN(0x865daedf, 0x0c1a1064), + TOBN(0x3eb70bd3, 0x83279125), TOBN(0xbc3d5b9f, 0x34ecdaab), + TOBN(0x91e3ed7e, 0x5f755caf), TOBN(0x49699f54, 0xd41e6f02), + TOBN(0x185770e1, 0xd4a7a15b), TOBN(0x08f3587a, 0xeaac87e7), + TOBN(0x352018db, 0x473133ea), TOBN(0x674ce719, 0x04fd30fc), + TOBN(0x7b8d9835, 0x088b3e0e), TOBN(0x7a0356a9, 0x5d0d47a1), + TOBN(0x9d9e7659, 0x6474a3c4), TOBN(0x61ea48a7, 0xff66966c), + TOBN(0x30417758, 0x0f3e4834), TOBN(0xfdbb21c2, 0x17a9afcb), + TOBN(0x756fa17f, 0x2f9a67b3), TOBN(0x2a6b2421, 0xa245c1a8), + TOBN(0x64be2794, 0x4af02291), TOBN(0xade465c6, 0x2a5804fe), + TOBN(0x8dffbd39, 0xa6f08fd7), TOBN(0xc4efa84c, 0xaa14403b), + TOBN(0xa1b91b2a, 0x442b0f5c), TOBN(0xb748e317, 0xcf997736), + TOBN(0x8d1b62bf, 0xcee90e16), TOBN(0x907ae271, 0x0b2078c0), + TOBN(0xdf31534b, 0x0c9bcddd), TOBN(0x043fb054, 0x39adce83), + TOBN(0x99031043, 0xd826846a), TOBN(0x61a9c0d6, 0xb144f393), + TOBN(0xdab48046, 0x47718427), TOBN(0xdf17ff9b, 0x6e830f8b), + TOBN(0x408d7ee8, 0xe49a1347), TOBN(0x6ac71e23, 0x91c1d4ae), + TOBN(0xc8cbb9fd, 0x1defd73c), TOBN(0x19840657, 0xbbbbfec5), + TOBN(0x39db1cb5, 0x9e7ef8ea), TOBN(0x78aa8296, 0x64105f30), + TOBN(0xa3d9b7f0, 0xa3738c29), TOBN(0x0a2f235a, 0xbc3250a3), + TOBN(0x55e506f6, 0x445e4caf), TOBN(0x0974f73d, 0x33475f7a), + TOBN(0xd37dbba3, 0x5ba2f5a8), TOBN(0x542c6e63, 0x6af40066), + TOBN(0x26d99b53, 0xc5d73e2c), TOBN(0x06060d7d, 0x6c3ca33e), + TOBN(0xcdbef1c2, 0x065fef4a), TOBN(0x77e60f7d, 0xfd5b92e3), + TOBN(0xd7c549f0, 0x26708350), TOBN(0x201b3ad0, 0x34f121bf), + TOBN(0x5fcac2a1, 0x0334fc14), TOBN(0x8a9a9e09, 0x344552f6), + TOBN(0x7dd8a1d3, 0x97653082), TOBN(0x5fc0738f, 0x79d4f289), + TOBN(0x787d244d, 0x17d2d8c3), TOBN(0xeffc6345, 0x70830684), + TOBN(0x5ddb96dd, 0xe4f73ae5), TOBN(0x8efb14b1, 0x172549a5), + TOBN(0x6eb73eee, 0x2245ae7a), TOBN(0xbca4061e, 0xea11f13e), + TOBN(0xb577421d, 0x30b01f5d), TOBN(0xaa688b24, 0x782e152c), + TOBN(0x67608e71, 0xbd3502ba), TOBN(0x4ef41f24, 0xb4de75a0), + TOBN(0xb08dde5e, 0xfd6125e5), TOBN(0xde484825, 0xa409543f), + TOBN(0x1f198d98, 0x65cc2295), TOBN(0x428a3771, 0x6e0edfa2), + TOBN(0x4f9697a2, 0xadf35fc7), TOBN(0x01a43c79, 0xf7cac3c7), + TOBN(0xb05d7059, 0x0fd3659a), TOBN(0x8927f30c, 0xbb7f2d9a), + TOBN(0x4023d1ac, 0x8cf984d3), TOBN(0x32125ed3, 0x02897a45), + TOBN(0xfb572dad, 0x3d414205), TOBN(0x73000ef2, 0xe3fa82a9), + TOBN(0x4c0868e9, 0xf10a5581), TOBN(0x5b61fc67, 0x6b0b3ca5), + TOBN(0xc1258d5b, 0x7cae440c), TOBN(0x21c08b41, 0x402b7531), + TOBN(0xf61a8955, 0xde932321), TOBN(0x3568faf8, 0x2d1408af), + TOBN(0x71b15e99, 0x9ecf965b), TOBN(0xf14ed248, 0xe917276f), + TOBN(0xc6f4caa1, 0x820cf9e2), TOBN(0x681b20b2, 0x18d83c7e), + TOBN(0x6cde738d, 0xc6c01120), TOBN(0x71db0813, 0xae70e0db), + TOBN(0x95fc0644, 0x74afe18c), TOBN(0x34619053, 0x129e2be7), + TOBN(0x80615cea, 0xdb2a3b15), TOBN(0x0a49a19e, 0xdb4c7073), + TOBN(0x0e1b84c8, 0x8fd2d367), TOBN(0xd74bf462, 0x033fb8aa), + TOBN(0x889f6d65, 0x533ef217), TOBN(0x7158c7e4, 0xc3ca2e87), + TOBN(0xfb670dfb, 0xdc2b4167), TOBN(0x75910a01, 0x844c257f), + TOBN(0xf336bf07, 0xcf88577d), TOBN(0x22245250, 0xe45e2ace), + TOBN(0x2ed92e8d, 0x7ca23d85), TOBN(0x29f8be4c, 0x2b812f58), + TOBN(0xdd9ebaa7, 0x076fe12b), TOBN(0x3f2400cb, 0xae1537f9), + TOBN(0x1aa93528, 0x17bdfb46), TOBN(0xc0f98430, 0x67883b41), + TOBN(0x5590ede1, 0x0170911d), TOBN(0x7562f5bb, 0x34d4b17f), + TOBN(0xe1fa1df2, 0x1826b8d2), TOBN(0xb40b796a, 0x6bd80d59), + TOBN(0xd65bf197, 0x3467ba92), TOBN(0x8c9b46db, 0xf70954b0), + TOBN(0x97c8a0f3, 0x0e78f15d), TOBN(0xa8f3a69a, 0x85a4c961), + TOBN(0x4242660f, 0x61e4ce9b), TOBN(0xbf06aab3, 0x6ea6790c), + TOBN(0xc6706f8e, 0xec986416), TOBN(0x9e56dec1, 0x9a9fc225), + TOBN(0x527c46f4, 0x9a9898d9), TOBN(0xd799e77b, 0x5633cdef), + TOBN(0x24eacc16, 0x7d9e4297), TOBN(0xabb61cea, 0x6b1cb734), + TOBN(0xbee2e8a7, 0xf778443c), TOBN(0x3bb42bf1, 0x29de2fe6), + TOBN(0xcbed86a1, 0x3003bb6f), TOBN(0xd3918e6c, 0xd781cdf6), + TOBN(0x4bee3271, 0x9a5103f1), TOBN(0x5243efc6, 0xf50eac06), + TOBN(0xb8e122cb, 0x6adcc119), TOBN(0x1b7faa84, 0xc0b80a08), + TOBN(0x32c3d1bd, 0x6dfcd08c), TOBN(0x129dec4e, 0x0be427de), + TOBN(0x98ab679c, 0x1d263c83), TOBN(0xafc83cb7, 0xcef64eff), + TOBN(0x85eb6088, 0x2fa6be76), TOBN(0x892585fb, 0x1328cbfe), + TOBN(0xc154d3ed, 0xcf618dda), TOBN(0xc44f601b, 0x3abaf26e), + TOBN(0x7bf57d0b, 0x2be1fdfd), TOBN(0xa833bd2d, 0x21137fee), + TOBN(0x9353af36, 0x2db591a8), TOBN(0xc76f26dc, 0x5562a056), + TOBN(0x1d87e47d, 0x3fdf5a51), TOBN(0x7afb5f93, 0x55c9cab0), + TOBN(0x91bbf58f, 0x89e0586e), TOBN(0x7c72c018, 0x0d843709), + TOBN(0xa9a5aafb, 0x99b5c3dc), TOBN(0xa48a0f1d, 0x3844aeb0), + TOBN(0x7178b7dd, 0xb667e482), TOBN(0x453985e9, 0x6e23a59a), + TOBN(0x4a54c860, 0x01b25dd8), TOBN(0x0dd37f48, 0xfb897c8a), + TOBN(0x5f8aa610, 0x0ea90cd9), TOBN(0xc8892c68, 0x16d5830d), + TOBN(0xeb4befc0, 0xef514ca5), TOBN(0x478eb679, 0xe72c9ee6), + TOBN(0x9bca20da, 0xdbc40d5f), TOBN(0xf015de21, 0xdde4f64a), + TOBN(0xaa6a4de0, 0xeaf4b8a5), TOBN(0x68cfd9ca, 0x4bc60e32), + TOBN(0x668a4b01, 0x7fd15e70), TOBN(0xd9f0694a, 0xf27dc09d), + TOBN(0xf6c3cad5, 0xba708bcd), TOBN(0x5cd2ba69, 0x5bb95c2a), + TOBN(0xaa28c1d3, 0x33c0a58f), TOBN(0x23e274e3, 0xabc77870), + TOBN(0x44c3692d, 0xdfd20a4a), TOBN(0x091c5fd3, 0x81a66653), + TOBN(0x6c0bb691, 0x09a0757d), TOBN(0x9072e8b9, 0x667343ea), + TOBN(0x31d40eb0, 0x80848bec), TOBN(0x95bd480a, 0x79fd36cc), + TOBN(0x01a77c61, 0x65ed43f5), TOBN(0xafccd127, 0x2e0d40bf), + TOBN(0xeccfc82d, 0x1cc1884b), TOBN(0xc85ac201, 0x5d4753b4), + TOBN(0xc7a6caac, 0x658e099f), TOBN(0xcf46369e, 0x04b27390), + TOBN(0xe2e7d049, 0x506467ea), TOBN(0x481b63a2, 0x37cdeccc), + TOBN(0x4029abd8, 0xed80143a), TOBN(0x28bfe3c7, 0xbcb00b88), + TOBN(0x3bec1009, 0x0643d84a), TOBN(0x885f3668, 0xabd11041), + TOBN(0xdb02432c, 0xf83a34d6), TOBN(0x32f7b360, 0x719ceebe), + TOBN(0xf06c7837, 0xdad1fe7a), TOBN(0x60a157a9, 0x5441a0b0), + TOBN(0x704970e9, 0xe2d47550), TOBN(0xcd2bd553, 0x271b9020), + TOBN(0xff57f82f, 0x33e24a0b), TOBN(0x9cbee23f, 0xf2565079), + TOBN(0x16353427, 0xeb5f5825), TOBN(0x276feec4, 0xe948d662), + TOBN(0xd1b62bc6, 0xda10032b), TOBN(0x718351dd, 0xf0e72a53), + TOBN(0x93452076, 0x2420e7ba), TOBN(0x96368fff, 0x3a00118d), + TOBN(0x00ce2d26, 0x150a49e4), TOBN(0x0c28b636, 0x3f04706b), + TOBN(0xbad65a46, 0x58b196d0), TOBN(0x6c8455fc, 0xec9f8b7c), + TOBN(0xe90c895f, 0x2d71867e), TOBN(0x5c0be31b, 0xedf9f38c), + TOBN(0x2a37a15e, 0xd8f6ec04), TOBN(0x239639e7, 0x8cd85251), + TOBN(0xd8975315, 0x9c7c4c6b), TOBN(0x603aa3c0, 0xd7409af7), + TOBN(0xb8d53d0c, 0x007132fb), TOBN(0x68d12af7, 0xa6849238), + TOBN(0xbe0607e7, 0xbf5d9279), TOBN(0x9aa50055, 0xaada74ce), + TOBN(0xe81079cb, 0xba7e8ccb), TOBN(0x610c71d1, 0xa5f4ff5e), + TOBN(0x9e2ee1a7, 0x5aa07093), TOBN(0xca84004b, 0xa75da47c), + TOBN(0x074d3951, 0x3de75401), TOBN(0xf938f756, 0xbb311592), + TOBN(0x96197618, 0x00a43421), TOBN(0x39a25362, 0x07bc78c8), + TOBN(0x278f710a, 0x0a171276), TOBN(0xb28446ea, 0x8d1a8f08), + TOBN(0x184781bf, 0xe3b6a661), TOBN(0x7751cb1d, 0xe6d279f7), + TOBN(0xf8ff95d6, 0xc59eb662), TOBN(0x186d90b7, 0x58d3dea7), + TOBN(0x0e4bb6c1, 0xdfb4f754), TOBN(0x5c5cf56b, 0x2b2801dc), + TOBN(0xc561e452, 0x1f54564d), TOBN(0xb4fb8c60, 0xf0dd7f13), + TOBN(0xf8849630, 0x33ff98c7), TOBN(0x9619fffa, 0xcf17769c), + TOBN(0xf8090bf6, 0x1bfdd80a), TOBN(0x14d9a149, 0x422cfe63), + TOBN(0xb354c360, 0x6f6df9ea), TOBN(0xdbcf770d, 0x218f17ea), + TOBN(0x207db7c8, 0x79eb3480), TOBN(0x213dbda8, 0x559b6a26), + TOBN(0xac4c200b, 0x29fc81b3), TOBN(0xebc3e09f, 0x171d87c1), + TOBN(0x91799530, 0x1481aa9e), TOBN(0x051b92e1, 0x92e114fa), + TOBN(0xdf8f92e9, 0xecb5537f), TOBN(0x44b1b2cc, 0x290c7483), + TOBN(0xa711455a, 0x2adeb016), TOBN(0x964b6856, 0x81a10c2c), + TOBN(0x4f159d99, 0xcec03623), TOBN(0x05532225, 0xef3271ea), + TOBN(0xb231bea3, 0xc5ee4849), TOBN(0x57a54f50, 0x7094f103), + TOBN(0x3e2d421d, 0x9598b352), TOBN(0xe865a49c, 0x67412ab4), + TOBN(0xd2998a25, 0x1cc3a912), TOBN(0x5d092808, 0x0c74d65d), + TOBN(0x73f45908, 0x4088567a), TOBN(0xeb6b280e, 0x1f214a61), + TOBN(0x8c9adc34, 0xcaf0c13d), TOBN(0x39d12938, 0xf561fb80), + TOBN(0xb2dc3a5e, 0xbc6edfb4), TOBN(0x7485b1b1, 0xfe4d210e), + TOBN(0x062e0400, 0xe186ae72), TOBN(0x91e32d5c, 0x6eeb3b88), + TOBN(0x6df574d7, 0x4be59224), TOBN(0xebc88ccc, 0x716d55f3), + TOBN(0x26c2e6d0, 0xcad6ed33), TOBN(0xc6e21e7d, 0x0d3e8b10), + TOBN(0x2cc5840e, 0x5bcc36bb), TOBN(0x9292445e, 0x7da74f69), + TOBN(0x8be8d321, 0x4e5193a8), TOBN(0x3ec23629, 0x8df06413), + TOBN(0xc7e9ae85, 0xb134defa), TOBN(0x6073b1d0, 0x1bb2d475), + TOBN(0xb9ad615e, 0x2863c00d), TOBN(0x9e29493d, 0x525f4ac4), + TOBN(0xc32b1dea, 0x4e9acf4f), TOBN(0x3e1f01c8, 0xa50db88d), + TOBN(0xb05d70ea, 0x04da916c), TOBN(0x714b0d0a, 0xd865803e), + TOBN(0x4bd493fc, 0x9920cb5e), TOBN(0x5b44b1f7, 0x92c7a3ac), + TOBN(0xa2a77293, 0xbcec9235), TOBN(0x5ee06e87, 0xcd378553), + TOBN(0xceff8173, 0xda621607), TOBN(0x2bb03e4c, 0x99f5d290), + TOBN(0x2945106a, 0xa6f734ac), TOBN(0xb5056604, 0xd25c4732), + TOBN(0x5945920c, 0xe079afee), TOBN(0x686e17a0, 0x6789831f), + TOBN(0x5966bee8, 0xb74a5ae5), TOBN(0x38a673a2, 0x1e258d46), + TOBN(0xbd1cc1f2, 0x83141c95), TOBN(0x3b2ecf4f, 0x0e96e486), + TOBN(0xcd3aa896, 0x74e5fc78), TOBN(0x415ec10c, 0x2482fa7a), + TOBN(0x15234419, 0x80503380), TOBN(0x513d917a, 0xd314b392), + TOBN(0xb0b52f4e, 0x63caecae), TOBN(0x07bf22ad, 0x2dc7780b), + TOBN(0xe761e8a1, 0xe4306839), TOBN(0x1b3be962, 0x5dd7feaa), + TOBN(0x4fe728de, 0x74c778f1), TOBN(0xf1fa0bda, 0x5e0070f6), + TOBN(0x85205a31, 0x6ec3f510), TOBN(0x2c7e4a14, 0xd2980475), + TOBN(0xde3c19c0, 0x6f30ebfd), TOBN(0xdb1c1f38, 0xd4b7e644), + TOBN(0xfe291a75, 0x5dce364a), TOBN(0xb7b22a3c, 0x058f5be3), + TOBN(0x2cd2c302, 0x37fea38c), TOBN(0x2930967a, 0x2e17be17), + TOBN(0x87f009de, 0x0c061c65), TOBN(0xcb014aac, 0xedc6ed44), + TOBN(0x49bd1cb4, 0x3bafb1eb), TOBN(0x81bd8b5c, 0x282d3688), + TOBN(0x1cdab87e, 0xf01a17af), TOBN(0x21f37ac4, 0xe710063b), + TOBN(0x5a6c5676, 0x42fc8193), TOBN(0xf4753e70, 0x56a6015c), + TOBN(0x020f795e, 0xa15b0a44), TOBN(0x8f37c8d7, 0x8958a958), + TOBN(0x63b7e89b, 0xa4b675b5), TOBN(0xb4fb0c0c, 0x0fc31aea), + TOBN(0xed95e639, 0xa7ff1f2e), TOBN(0x9880f5a3, 0x619614fb), + TOBN(0xdeb6ff02, 0x947151ab), TOBN(0x5bc5118c, 0xa868dcdb), + TOBN(0xd8da2055, 0x4c20cea5), TOBN(0xcac2776e, 0x14c4d69a), + TOBN(0xcccb22c1, 0x622d599b), TOBN(0xa4ddb653, 0x68a9bb50), + TOBN(0x2c4ff151, 0x1b4941b4), TOBN(0xe1ff19b4, 0x6efba588), + TOBN(0x35034363, 0xc48345e0), TOBN(0x45542e3d, 0x1e29dfc4), + TOBN(0xf197cb91, 0x349f7aed), TOBN(0x3b2b5a00, 0x8fca8420), + TOBN(0x7c175ee8, 0x23aaf6d8), TOBN(0x54dcf421, 0x35af32b6), + TOBN(0x0ba14307, 0x27d6561e), TOBN(0x879d5ee4, 0xd175b1e2), + TOBN(0xc7c43673, 0x99807db5), TOBN(0x77a54455, 0x9cd55bcd), + TOBN(0xe6c2ff13, 0x0105c072), TOBN(0x18f7a99f, 0x8dda7da4), + TOBN(0x4c301820, 0x0e2d35c1), TOBN(0x06a53ca0, 0xd9cc6c82), + TOBN(0xaa21cc1e, 0xf1aa1d9e), TOBN(0x32414334, 0x4a75b1e8), + TOBN(0x2a6d1328, 0x0ebe9fdc), TOBN(0x16bd173f, 0x98a4755a), + TOBN(0xfbb9b245, 0x2133ffd9), TOBN(0x39a8b2f1, 0x830f1a20), + TOBN(0x484bc97d, 0xd5a1f52a), TOBN(0xd6aebf56, 0xa40eddf8), + TOBN(0x32257acb, 0x76ccdac6), TOBN(0xaf4d36ec, 0x1586ff27), + TOBN(0x8eaa8863, 0xf8de7dd1), TOBN(0x0045d5cf, 0x88647c16)}, + {TOBN(0xa6f3d574, 0xc005979d), TOBN(0xc2072b42, 0x6a40e350), + TOBN(0xfca5c156, 0x8de2ecf9), TOBN(0xa8c8bf5b, 0xa515344e), + TOBN(0x97aee555, 0x114df14a), TOBN(0xd4374a4d, 0xfdc5ec6b), + TOBN(0x754cc28f, 0x2ca85418), TOBN(0x71cb9e27, 0xd3c41f78), + TOBN(0x89105079, 0x03605c39), TOBN(0xf0843d9e, 0xa142c96c), + TOBN(0xf3744934, 0x16923684), TOBN(0x732caa2f, 0xfa0a2893), + TOBN(0xb2e8c270, 0x61160170), TOBN(0xc32788cc, 0x437fbaa3), + TOBN(0x39cd818e, 0xa6eda3ac), TOBN(0xe2e94239, 0x9e2b2e07), + TOBN(0x6967d39b, 0x0260e52a), TOBN(0xd42585cc, 0x90653325), + TOBN(0x0d9bd605, 0x21ca7954), TOBN(0x4fa20877, 0x81ed57b3), + TOBN(0x60c1eff8, 0xe34a0bbe), TOBN(0x56b0040c, 0x84f6ef64), + TOBN(0x28be2b24, 0xb1af8483), TOBN(0xb2278163, 0xf5531614), + TOBN(0x8df27545, 0x5922ac1c), TOBN(0xa7b3ef5c, 0xa52b3f63), + TOBN(0x8e77b214, 0x71de57c4), TOBN(0x31682c10, 0x834c008b), + TOBN(0xc76824f0, 0x4bd55d31), TOBN(0xb6d1c086, 0x17b61c71), + TOBN(0x31db0903, 0xc2a5089d), TOBN(0x9c092172, 0x184e5d3f), + TOBN(0xdd7ced5b, 0xc00cc638), TOBN(0x1a2015eb, 0x61278fc2), + TOBN(0x2e8e5288, 0x6a37f8d6), TOBN(0xc457786f, 0xe79933ad), + TOBN(0xb3fe4cce, 0x2c51211a), TOBN(0xad9b10b2, 0x24c20498), + TOBN(0x90d87a4f, 0xd28db5e5), TOBN(0x698cd105, 0x3aca2fc3), + TOBN(0x4f112d07, 0xe91b536d), TOBN(0xceb982f2, 0x9eba09d6), + TOBN(0x3c157b2c, 0x197c396f), TOBN(0xe23c2d41, 0x7b66eb24), + TOBN(0x480c57d9, 0x3f330d37), TOBN(0xb3a4c8a1, 0x79108deb), + TOBN(0x702388de, 0xcb199ce5), TOBN(0x0b019211, 0xb944a8d4), + TOBN(0x24f2a692, 0x840bb336), TOBN(0x7c353bdc, 0xa669fa7b), + TOBN(0xda20d6fc, 0xdec9c300), TOBN(0x625fbe2f, 0xa13a4f17), + TOBN(0xa2b1b61a, 0xdbc17328), TOBN(0x008965bf, 0xa9515621), + TOBN(0x49690939, 0xc620ff46), TOBN(0x182dd27d, 0x8717e91c), + TOBN(0x5ace5035, 0xea6c3997), TOBN(0x54259aaa, 0xc2610bef), + TOBN(0xef18bb3f, 0x3c80dd39), TOBN(0x6910b95b, 0x5fc3fa39), + TOBN(0xfce2f510, 0x43e09aee), TOBN(0xced56c9f, 0xa7675665), + TOBN(0x10e265ac, 0xd872db61), TOBN(0x6982812e, 0xae9fce69), + TOBN(0x29be11c6, 0xce800998), TOBN(0x72bb1752, 0xb90360d9), + TOBN(0x2c193197, 0x5a4ad590), TOBN(0x2ba2f548, 0x9fc1dbc0), + TOBN(0x7fe4eebb, 0xe490ebe0), TOBN(0x12a0a4cd, 0x7fae11c0), + TOBN(0x7197cf81, 0xe903ba37), TOBN(0xcf7d4aa8, 0xde1c6dd8), + TOBN(0x92af6bf4, 0x3fd5684c), TOBN(0x2b26eecf, 0x80360aa1), + TOBN(0xbd960f30, 0x00546a82), TOBN(0x407b3c43, 0xf59ad8fe), + TOBN(0x86cae5fe, 0x249c82ba), TOBN(0x9e0faec7, 0x2463744c), + TOBN(0x87f551e8, 0x94916272), TOBN(0x033f9344, 0x6ceb0615), + TOBN(0x1e5eb0d1, 0x8be82e84), TOBN(0x89967f0e, 0x7a582fef), + TOBN(0xbcf687d5, 0xa6e921fa), TOBN(0xdfee4cf3, 0xd37a09ba), + TOBN(0x94f06965, 0xb493c465), TOBN(0x638b9a1c, 0x7635c030), + TOBN(0x76667864, 0x66f05e9f), TOBN(0xccaf6808, 0xc04da725), + TOBN(0xca2eb690, 0x768fccfc), TOBN(0xf402d37d, 0xb835b362), + TOBN(0x0efac0d0, 0xe2fdfcce), TOBN(0xefc9cdef, 0xb638d990), + TOBN(0x2af12b72, 0xd1669a8b), TOBN(0x33c536bc, 0x5774ccbd), + TOBN(0x30b21909, 0xfb34870e), TOBN(0xc38fa2f7, 0x7df25aca), + TOBN(0x74c5f02b, 0xbf81f3f5), TOBN(0x0525a5ae, 0xaf7e4581), + TOBN(0x88d2aaba, 0x433c54ae), TOBN(0xed9775db, 0x806a56c5), + TOBN(0xd320738a, 0xc0edb37d), TOBN(0x25fdb6ee, 0x66cc1f51), + TOBN(0xac661d17, 0x10600d76), TOBN(0x931ec1f3, 0xbdd1ed76), + TOBN(0x65c11d62, 0x19ee43f1), TOBN(0x5cd57c3e, 0x60829d97), + TOBN(0xd26c91a3, 0x984be6e8), TOBN(0xf08d9309, 0x8b0c53bd), + TOBN(0x94bc9e5b, 0xc016e4ea), TOBN(0xd3916839, 0x11d43d2b), + TOBN(0x886c5ad7, 0x73701155), TOBN(0xe0377626, 0x20b00715), + TOBN(0x7f01c9ec, 0xaa80ba59), TOBN(0x3083411a, 0x68538e51), + TOBN(0x970370f1, 0xe88128af), TOBN(0x625cc3db, 0x91dec14b), + TOBN(0xfef9666c, 0x01ac3107), TOBN(0xb2a8d577, 0xd5057ac3), + TOBN(0xb0f26299, 0x92be5df7), TOBN(0xf579c8e5, 0x00353924), + TOBN(0xb8fa3d93, 0x1341ed7a), TOBN(0x4223272c, 0xa7b59d49), + TOBN(0x3dcb1947, 0x83b8c4a4), TOBN(0x4e413c01, 0xed1302e4), + TOBN(0x6d999127, 0xe17e44ce), TOBN(0xee86bf75, 0x33b3adfb), + TOBN(0xf6902fe6, 0x25aa96ca), TOBN(0xb73540e4, 0xe5aae47d), + TOBN(0x32801d7b, 0x1b4a158c), TOBN(0xe571c99e, 0x27e2a369), + TOBN(0x40cb76c0, 0x10d9f197), TOBN(0xc308c289, 0x3167c0ae), + TOBN(0xa6ef9dd3, 0xeb7958f2), TOBN(0xa7226dfc, 0x300879b1), + TOBN(0x6cd0b362, 0x7edf0636), TOBN(0x4efbce6c, 0x7bc37eed), + TOBN(0x75f92a05, 0x8d699021), TOBN(0x586d4c79, 0x772566e3), + TOBN(0x378ca5f1, 0x761ad23a), TOBN(0x650d86fc, 0x1465a8ac), + TOBN(0x7a4ed457, 0x842ba251), TOBN(0x6b65e3e6, 0x42234933), + TOBN(0xaf1543b7, 0x31aad657), TOBN(0xa4cefe98, 0xcbfec369), + TOBN(0xb587da90, 0x9f47befb), TOBN(0x6562e9fb, 0x41312d13), + TOBN(0xa691ea59, 0xeff1cefe), TOBN(0xcc30477a, 0x05fc4cf6), + TOBN(0xa1632461, 0x0b0ffd3d), TOBN(0xa1f16f3b, 0x5b355956), + TOBN(0x5b148d53, 0x4224ec24), TOBN(0xdc834e7b, 0xf977012a), + TOBN(0x7bfc5e75, 0xb2c69dbc), TOBN(0x3aa77a29, 0x03c3da6c), + TOBN(0xde0df03c, 0xca910271), TOBN(0xcbd5ca4a, 0x7806dc55), + TOBN(0xe1ca5807, 0x6db476cb), TOBN(0xfde15d62, 0x5f37a31e), + TOBN(0xf49af520, 0xf41af416), TOBN(0x96c5c5b1, 0x7d342db5), + TOBN(0x155c43b7, 0xeb4ceb9b), TOBN(0x2e993010, 0x4e77371a), + TOBN(0x1d2987da, 0x675d43af), TOBN(0xef2bc1c0, 0x8599fd72), + TOBN(0x96894b7b, 0x9342f6b2), TOBN(0x201eadf2, 0x7c8e71f0), + TOBN(0xf3479d9f, 0x4a1f3efc), TOBN(0xe0f8a742, 0x702a9704), + TOBN(0xeafd44b6, 0xb3eba40c), TOBN(0xf9739f29, 0xc1c1e0d0), + TOBN(0x0091471a, 0x619d505e), TOBN(0xc15f9c96, 0x9d7c263e), + TOBN(0x5be47285, 0x83afbe33), TOBN(0xa3b6d6af, 0x04f1e092), + TOBN(0xe76526b9, 0x751a9d11), TOBN(0x2ec5b26d, 0x9a4ae4d2), + TOBN(0xeb66f4d9, 0x02f6fb8d), TOBN(0x4063c561, 0x96912164), + TOBN(0xeb7050c1, 0x80ef3000), TOBN(0x288d1c33, 0xeaa5b3f0), + TOBN(0xe87c68d6, 0x07806fd8), TOBN(0xb2f7f9d5, 0x4bbbf50f), + TOBN(0x25972f3a, 0xac8d6627), TOBN(0xf8547774, 0x10e8c13b), + TOBN(0xcc50ef6c, 0x872b4a60), TOBN(0xab2a34a4, 0x4613521b), + TOBN(0x39c5c190, 0x983e15d1), TOBN(0x61dde5df, 0x59905512), + TOBN(0xe417f621, 0x9f2275f3), TOBN(0x0750c8b6, 0x451d894b), + TOBN(0x75b04ab9, 0x78b0bdaa), TOBN(0x3bfd9fd4, 0x458589bd), + TOBN(0xf1013e30, 0xee9120b6), TOBN(0x2b51af93, 0x23a4743e), + TOBN(0xea96ffae, 0x48d14d9e), TOBN(0x71dc0dbe, 0x698a1d32), + TOBN(0x914962d2, 0x0180cca4), TOBN(0x1ae60677, 0xc3568963), + TOBN(0x8cf227b1, 0x437bc444), TOBN(0xc650c83b, 0xc9962c7a), + TOBN(0x23c2c7dd, 0xfe7ccfc4), TOBN(0xf925c89d, 0x1b929d48), + TOBN(0x4460f74b, 0x06783c33), TOBN(0xac2c8d49, 0xa590475a), + TOBN(0xfb40b407, 0xb807bba0), TOBN(0x9d1e362d, 0x69ff8f3a), + TOBN(0xa33e9681, 0xcbef64a4), TOBN(0x67ece5fa, 0x332fb4b2), + TOBN(0x6900a99b, 0x739f10e3), TOBN(0xc3341ca9, 0xff525925), + TOBN(0xee18a626, 0xa9e2d041), TOBN(0xa5a83685, 0x29580ddd), + TOBN(0xf3470c81, 0x9d7de3cd), TOBN(0xedf02586, 0x2062cf9c), + TOBN(0xf43522fa, 0xc010edb0), TOBN(0x30314135, 0x13a4b1ae), + TOBN(0xc792e02a, 0xdb22b94b), TOBN(0x993d8ae9, 0xa1eaa45b), + TOBN(0x8aad6cd3, 0xcd1e1c63), TOBN(0x89529ca7, 0xc5ce688a), + TOBN(0x2ccee3aa, 0xe572a253), TOBN(0xe02b6438, 0x02a21efb), + TOBN(0xa7091b6e, 0xc9430358), TOBN(0x06d1b1fa, 0x9d7db504), + TOBN(0x58846d32, 0xc4744733), TOBN(0x40517c71, 0x379f9e34), + TOBN(0x2f65655f, 0x130ef6ca), TOBN(0x526e4488, 0xf1f3503f), + TOBN(0x8467bd17, 0x7ee4a976), TOBN(0x1d9dc913, 0x921363d1), + TOBN(0xd8d24c33, 0xb069e041), TOBN(0x5eb5da0a, 0x2cdf7f51), + TOBN(0x1c0f3cb1, 0x197b994f), TOBN(0x3c95a6c5, 0x2843eae9), + TOBN(0x7766ffc9, 0xa6097ea5), TOBN(0x7bea4093, 0xd723b867), + TOBN(0xb48e1f73, 0x4db378f9), TOBN(0x70025b00, 0xe37b77ac), + TOBN(0x943dc8e7, 0xaf24ad46), TOBN(0xb98a15ac, 0x16d00a85), + TOBN(0x3adc38ba, 0x2743b004), TOBN(0xb1c7f4f7, 0x334415ee), + TOBN(0xea43df8f, 0x1e62d05a), TOBN(0x32618905, 0x9d76a3b6), + TOBN(0x2fbd0bb5, 0xa23a0f46), TOBN(0x5bc971db, 0x6a01918c), + TOBN(0x7801d94a, 0xb4743f94), TOBN(0xb94df65e, 0x676ae22b), + TOBN(0xaafcbfab, 0xaf95894c), TOBN(0x7b9bdc07, 0x276b2241), + TOBN(0xeaf98362, 0x5bdda48b), TOBN(0x5977faf2, 0xa3fcb4df), + TOBN(0xbed042ef, 0x052c4b5b), TOBN(0x9fe87f71, 0x067591f0), + TOBN(0xc89c73ca, 0x22f24ec7), TOBN(0x7d37fa9e, 0xe64a9f1b), + TOBN(0x2710841a, 0x15562627), TOBN(0x2c01a613, 0xc243b034), + TOBN(0x1d135c56, 0x2bc68609), TOBN(0xc2ca1715, 0x8b03f1f6), + TOBN(0xc9966c2d, 0x3eb81d82), TOBN(0xc02abf4a, 0x8f6df13e), + TOBN(0x77b34bd7, 0x8f72b43b), TOBN(0xaff6218f, 0x360c82b0), + TOBN(0x0aa5726c, 0x8d55b9d2), TOBN(0xdc0adbe9, 0x99e9bffb), + TOBN(0x9097549c, 0xefb9e72a), TOBN(0x16755712, 0x9dfb3111), + TOBN(0xdd8bf984, 0xf26847f9), TOBN(0xbcb8e387, 0xdfb30cb7), + TOBN(0xc1fd32a7, 0x5171ef9c), TOBN(0x977f3fc7, 0x389b363f), + TOBN(0x116eaf2b, 0xf4babda0), TOBN(0xfeab68bd, 0xf7113c8e), + TOBN(0xd1e3f064, 0xb7def526), TOBN(0x1ac30885, 0xe0b3fa02), + TOBN(0x1c5a6e7b, 0x40142d9d), TOBN(0x839b5603, 0x30921c0b), + TOBN(0x48f301fa, 0x36a116a3), TOBN(0x380e1107, 0xcfd9ee6d), + TOBN(0x7945ead8, 0x58854be1), TOBN(0x4111c12e, 0xcbd4d49d), + TOBN(0xece3b1ec, 0x3a29c2ef), TOBN(0x6356d404, 0x8d3616f5), + TOBN(0x9f0d6a8f, 0x594d320e), TOBN(0x0989316d, 0xf651ccd2), + TOBN(0x6c32117a, 0x0f8fdde4), TOBN(0x9abe5cc5, 0xa26a9bbc), + TOBN(0xcff560fb, 0x9723f671), TOBN(0x21b2a12d, 0x7f3d593c), + TOBN(0xe4cb18da, 0x24ba0696), TOBN(0x186e2220, 0xc3543384), + TOBN(0x722f64e0, 0x88312c29), TOBN(0x94282a99, 0x17dc7752), + TOBN(0x62467bbf, 0x5a85ee89), TOBN(0xf435c650, 0xf10076a0), + TOBN(0xc9ff1539, 0x43b3a50b), TOBN(0x7132130c, 0x1a53efbc), + TOBN(0x31bfe063, 0xf7b0c5b7), TOBN(0xb0179a7d, 0x4ea994cc), + TOBN(0x12d064b3, 0xc85f455b), TOBN(0x47259328, 0x8f6e0062), + TOBN(0xf64e590b, 0xb875d6d9), TOBN(0x22dd6225, 0xad92bcc7), + TOBN(0xb658038e, 0xb9c3bd6d), TOBN(0x00cdb0d6, 0xfbba27c8), + TOBN(0x0c681337, 0x1062c45d), TOBN(0xd8515b8c, 0x2d33407d), + TOBN(0xcb8f699e, 0x8cbb5ecf), TOBN(0x8c4347f8, 0xc608d7d8), + TOBN(0x2c11850a, 0xbb3e00db), TOBN(0x20a8dafd, 0xecb49d19), + TOBN(0xbd781480, 0x45ee2f40), TOBN(0x75e354af, 0x416b60cf), + TOBN(0xde0b58a1, 0x8d49a8c4), TOBN(0xe40e94e2, 0xfa359536), + TOBN(0xbd4fa59f, 0x62accd76), TOBN(0x05cf466a, 0x8c762837), + TOBN(0xb5abda99, 0x448c277b), TOBN(0x5a9e01bf, 0x48b13740), + TOBN(0x9d457798, 0x326aad8d), TOBN(0xbdef4954, 0xc396f7e7), + TOBN(0x6fb274a2, 0xc253e292), TOBN(0x2800bf0a, 0x1cfe53e7), + TOBN(0x22426d31, 0x44438fd4), TOBN(0xef233923, 0x5e259f9a), + TOBN(0x4188503c, 0x03f66264), TOBN(0x9e5e7f13, 0x7f9fdfab), + TOBN(0x565eb76c, 0x5fcc1aba), TOBN(0xea632548, 0x59b5bff8), + TOBN(0x5587c087, 0xaab6d3fa), TOBN(0x92b639ea, 0x6ce39c1b), + TOBN(0x0706e782, 0x953b135c), TOBN(0x7308912e, 0x425268ef), + TOBN(0x599e92c7, 0x090e7469), TOBN(0x83b90f52, 0x9bc35e75), + TOBN(0x4750b3d0, 0x244975b3), TOBN(0xf3a44358, 0x11965d72), + TOBN(0x179c6774, 0x9c8dc751), TOBN(0xff18cdfe, 0xd23d9ff0), + TOBN(0xc4013833, 0x2028e247), TOBN(0x96e280e2, 0xf3bfbc79), + TOBN(0xf60417bd, 0xd0880a84), TOBN(0x263c9f3d, 0x2a568151), + TOBN(0x36be15b3, 0x2d2ce811), TOBN(0x846dc0c2, 0xf8291d21), + TOBN(0x5cfa0ecb, 0x789fcfdb), TOBN(0x45a0beed, 0xd7535b9a), + TOBN(0xec8e9f07, 0x96d69af1), TOBN(0x31a7c5b8, 0x599ab6dc), + TOBN(0xd36d45ef, 0xf9e2e09f), TOBN(0x3cf49ef1, 0xdcee954b), + TOBN(0x6be34cf3, 0x086cff9b), TOBN(0x88dbd491, 0x39a3360f), + TOBN(0x1e96b8cc, 0x0dbfbd1d), TOBN(0xc1e5f7bf, 0xcb7e2552), + TOBN(0x0547b214, 0x28819d98), TOBN(0xc770dd9c, 0x7aea9dcb), + TOBN(0xaef0d4c7, 0x041d68c8), TOBN(0xcc2b9818, 0x13cb9ba8), + TOBN(0x7fc7bc76, 0xfe86c607), TOBN(0x6b7b9337, 0x502a9a95), + TOBN(0x1948dc27, 0xd14dab63), TOBN(0x249dd198, 0xdae047be), + TOBN(0xe8356584, 0xa981a202), TOBN(0x3531dd18, 0x3a893387), + TOBN(0x1be11f90, 0xc85c7209), TOBN(0x93d2fe1e, 0xe2a52b5a), + TOBN(0x8225bfe2, 0xec6d6b97), TOBN(0x9cf6d6f4, 0xbd0aa5de), + TOBN(0x911459cb, 0x54779f5f), TOBN(0x5649cddb, 0x86aeb1f3), + TOBN(0x32133579, 0x3f26ce5a), TOBN(0xc289a102, 0x550f431e), + TOBN(0x559dcfda, 0x73b84c6f), TOBN(0x84973819, 0xee3ac4d7), + TOBN(0xb51e55e6, 0xf2606a82), TOBN(0xe25f7061, 0x90f2fb57), + TOBN(0xacef6c2a, 0xb1a4e37c), TOBN(0x864e359d, 0x5dcf2706), + TOBN(0x479e6b18, 0x7ce57316), TOBN(0x2cab2500, 0x3a96b23d), + TOBN(0xed489862, 0x8ef16df7), TOBN(0x2056538c, 0xef3758b5), + TOBN(0xa7df865e, 0xf15d3101), TOBN(0x80c5533a, 0x61b553d7), + TOBN(0x366e1997, 0x4ed14294), TOBN(0x6620741f, 0xb3c0bcd6), + TOBN(0x21d1d9c4, 0xedc45418), TOBN(0x005b859e, 0xc1cc4a9d), + TOBN(0xdf01f630, 0xa1c462f0), TOBN(0x15d06cf3, 0xf26820c7), + TOBN(0x9f7f24ee, 0x3484be47), TOBN(0x2ff33e96, 0x4a0c902f), + TOBN(0x00bdf457, 0x5a0bc453), TOBN(0x2378dfaf, 0x1aa238db), + TOBN(0x272420ec, 0x856720f2), TOBN(0x2ad9d95b, 0x96797291), + TOBN(0xd1242cc6, 0x768a1558), TOBN(0x2e287f8b, 0x5cc86aa8), + TOBN(0x796873d0, 0x990cecaa), TOBN(0xade55f81, 0x675d4080), + TOBN(0x2645eea3, 0x21f0cd84), TOBN(0x7a1efa0f, 0xb4e17d02), + TOBN(0xf6858420, 0x037cc061), TOBN(0x682e05f0, 0xd5d43e12), + TOBN(0x59c36994, 0x27218710), TOBN(0x85cbba4d, 0x3f7cd2fc), + TOBN(0x726f9729, 0x7a3cd22a), TOBN(0x9f8cd5dc, 0x4a628397), + TOBN(0x17b93ab9, 0xc23165ed), TOBN(0xff5f5dbf, 0x122823d4), + TOBN(0xc1e4e4b5, 0x654a446d), TOBN(0xd1a9496f, 0x677257ba), + TOBN(0x6387ba94, 0xde766a56), TOBN(0x23608bc8, 0x521ec74a), + TOBN(0x16a522d7, 0x6688c4d4), TOBN(0x9d6b4282, 0x07373abd), + TOBN(0xa62f07ac, 0xb42efaa3), TOBN(0xf73e00f7, 0xe3b90180), + TOBN(0x36175fec, 0x49421c3e), TOBN(0xc4e44f9b, 0x3dcf2678), + TOBN(0x76df436b, 0x7220f09f), TOBN(0x172755fb, 0x3aa8b6cf), + TOBN(0xbab89d57, 0x446139cc), TOBN(0x0a0a6e02, 0x5fe0208f), + TOBN(0xcdbb63e2, 0x11e5d399), TOBN(0x33ecaa12, 0xa8977f0b), + TOBN(0x59598b21, 0xf7c42664), TOBN(0xb3e91b32, 0xab65d08a), + TOBN(0x035822ee, 0xf4502526), TOBN(0x1dcf0176, 0x720a82a9), + TOBN(0x50f8598f, 0x3d589e02), TOBN(0xdf0478ff, 0xb1d63d2c), + TOBN(0x8b8068bd, 0x1571cd07), TOBN(0x30c3aa4f, 0xd79670cd), + TOBN(0x25e8fd4b, 0x941ade7f), TOBN(0x3d1debdc, 0x32790011), + TOBN(0x65b6dcbd, 0x3a3f9ff0), TOBN(0x282736a4, 0x793de69c), + TOBN(0xef69a0c3, 0xd41d3bd3), TOBN(0xb533b8c9, 0x07a26bde), + TOBN(0xe2801d97, 0xdb2edf9f), TOBN(0xdc4a8269, 0xe1877af0), + TOBN(0x6c1c5851, 0x3d590dbe), TOBN(0x84632f6b, 0xee4e9357), + TOBN(0xd36d36b7, 0x79b33374), TOBN(0xb46833e3, 0x9bbca2e6), + TOBN(0x37893913, 0xf7fc0586), TOBN(0x385315f7, 0x66bf4719), + TOBN(0x72c56293, 0xb31855dc), TOBN(0xd1416d4e, 0x849061fe), + TOBN(0xbeb3ab78, 0x51047213), TOBN(0x447f6e61, 0xf040c996), + TOBN(0xd06d310d, 0x638b1d0c), TOBN(0xe28a413f, 0xbad1522e), + TOBN(0x685a76cb, 0x82003f86), TOBN(0x610d07f7, 0x0bcdbca3), + TOBN(0x6ff66021, 0x9ca4c455), TOBN(0x7df39b87, 0xcea10eec), + TOBN(0xb9255f96, 0xe22db218), TOBN(0x8cc6d9eb, 0x08a34c44), + TOBN(0xcd4ffb86, 0x859f9276), TOBN(0x8fa15eb2, 0x50d07335), + TOBN(0xdf553845, 0xcf2c24b5), TOBN(0x89f66a9f, 0x52f9c3ba), + TOBN(0x8f22b5b9, 0xe4a7ceb3), TOBN(0xaffef809, 0x0e134686), + TOBN(0x3e53e1c6, 0x8eb8fac2), TOBN(0x93c1e4eb, 0x28aec98e), + TOBN(0xb6b91ec5, 0x32a43bcb), TOBN(0x2dbfa947, 0xb2d74a51), + TOBN(0xe065d190, 0xca84bad7), TOBN(0xfb13919f, 0xad58e65c), + TOBN(0x3c41718b, 0xf1cb6e31), TOBN(0x688969f0, 0x06d05c3f), + TOBN(0xd4f94ce7, 0x21264d45), TOBN(0xfdfb65e9, 0x7367532b), + TOBN(0x5b1be8b1, 0x0945a39d), TOBN(0x229f789c, 0x2b8baf3b), + TOBN(0xd8f41f3e, 0x6f49f15d), TOBN(0x678ce828, 0x907f0792), + TOBN(0xc69ace82, 0xfca6e867), TOBN(0x106451ae, 0xd01dcc89), + TOBN(0x1bb4f7f0, 0x19fc32d2), TOBN(0x64633dfc, 0xb00c52d2), + TOBN(0x8f13549a, 0xad9ea445), TOBN(0x99a3bf50, 0xfb323705), + TOBN(0x0c9625a2, 0x534d4dbc), TOBN(0x45b8f1d1, 0xc2a2fea3), + TOBN(0x76ec21a1, 0xa530fc1a), TOBN(0x4bac9c2a, 0x9e5bd734), + TOBN(0x5996d76a, 0x7b4e3587), TOBN(0x0045cdee, 0x1182d9e3), + TOBN(0x1aee24b9, 0x1207f13d), TOBN(0x66452e97, 0x97345a41), + TOBN(0x16e5b054, 0x9f950cd0), TOBN(0x9cc72fb1, 0xd7fdd075), + TOBN(0x6edd61e7, 0x66249663), TOBN(0xde4caa4d, 0xf043cccb), + TOBN(0x11b1f57a, 0x55c7ac17), TOBN(0x779cbd44, 0x1a85e24d), + TOBN(0x78030f86, 0xe46081e7), TOBN(0xfd4a6032, 0x8e20f643), + TOBN(0xcc7a6488, 0x0a750c0f), TOBN(0x39bacfe3, 0x4e548e83), + TOBN(0x3d418c76, 0x0c110f05), TOBN(0x3e4daa4c, 0xb1f11588), + TOBN(0x2733e7b5, 0x5ffc69ff), TOBN(0x46f147bc, 0x92053127), + TOBN(0x885b2434, 0xd722df94), TOBN(0x6a444f65, 0xe6fc6b7c)}, + {TOBN(0x7a1a465a, 0xc3f16ea8), TOBN(0x115a461d, 0xb2f1d11c), + TOBN(0x4767dd95, 0x6c68a172), TOBN(0x3392f2eb, 0xd13a4698), + TOBN(0xc7a99ccd, 0xe526cdc7), TOBN(0x8e537fdc, 0x22292b81), + TOBN(0x76d8cf69, 0xa6d39198), TOBN(0xffc5ff43, 0x2446852d), + TOBN(0x97b14f7e, 0xa90567e6), TOBN(0x513257b7, 0xb6ae5cb7), + TOBN(0x85454a3c, 0x9f10903d), TOBN(0xd8d2c9ad, 0x69bc3724), + TOBN(0x38da9324, 0x6b29cb44), TOBN(0xb540a21d, 0x77c8cbac), + TOBN(0x9bbfe435, 0x01918e42), TOBN(0xfffa707a, 0x56c3614e), + TOBN(0x0ce4e3f1, 0xd4e353b7), TOBN(0x062d8a14, 0xef46b0a0), + TOBN(0x6408d5ab, 0x574b73fd), TOBN(0xbc41d1c9, 0xd3273ffd), + TOBN(0x3538e1e7, 0x6be77800), TOBN(0x71fe8b37, 0xc5655031), + TOBN(0x1cd91621, 0x6b9b331a), TOBN(0xad825d0b, 0xbb388f73), + TOBN(0x56c2e05b, 0x1cb76219), TOBN(0x0ec0bf91, 0x71567e7e), + TOBN(0xe7076f86, 0x61c4c910), TOBN(0xd67b085b, 0xbabc04d9), + TOBN(0x9fb90459, 0x5e93a96a), TOBN(0x7526c1ea, 0xfbdc249a), + TOBN(0x0d44d367, 0xecdd0bb7), TOBN(0x95399917, 0x9dc0d695), + TOBN(0x61360ee9, 0x9e240d18), TOBN(0x057cdcac, 0xb4b94466), + TOBN(0xe7667cd1, 0x2fe5325c), TOBN(0x1fa297b5, 0x21974e3b), + TOBN(0xfa4081e7, 0xdb083d76), TOBN(0x31993be6, 0xf206bd15), + TOBN(0x8949269b, 0x14c19f8c), TOBN(0x21468d72, 0xa9d92357), + TOBN(0x2ccbc583, 0xa4c506ec), TOBN(0x957ed188, 0xd1acfe97), + TOBN(0x8baed833, 0x12f1aea2), TOBN(0xef2a6cb4, 0x8325362d), + TOBN(0x130dde42, 0x8e195c43), TOBN(0xc842025a, 0x0e6050c6), + TOBN(0x2da972a7, 0x08686a5d), TOBN(0xb52999a1, 0xe508b4a8), + TOBN(0xd9f090b9, 0x10a5a8bd), TOBN(0xca91d249, 0x096864da), + TOBN(0x8e6a93be, 0x3f67dbc1), TOBN(0xacae6fba, 0xf5f4764c), + TOBN(0x1563c6e0, 0xd21411a0), TOBN(0x28fa787f, 0xda0a4ad8), + TOBN(0xd524491c, 0x908c8030), TOBN(0x1257ba0e, 0x4c795f07), + TOBN(0x83f49167, 0xceca9754), TOBN(0x426d2cf6, 0x4b7939a0), + TOBN(0x2555e355, 0x723fd0bf), TOBN(0xa96e6d06, 0xc4f144e2), + TOBN(0x4768a8dd, 0x87880e61), TOBN(0x15543815, 0xe508e4d5), + TOBN(0x09d7e772, 0xb1b65e15), TOBN(0x63439dd6, 0xac302fa0), + TOBN(0xb93f802f, 0xc14e35c2), TOBN(0x71735b7c, 0x4341333c), + TOBN(0x03a25104, 0x16d4f362), TOBN(0x3f4d069b, 0xbf433c8e), + TOBN(0x0d83ae01, 0xf78f5a7c), TOBN(0x50a8ffbe, 0x7c4eed07), + TOBN(0xc74f8906, 0x76e10f83), TOBN(0x7d080966, 0x9ddaf8e1), + TOBN(0xb11df8e1, 0x698e04cc), TOBN(0x877be203, 0x169005c8), + TOBN(0x32749e8c, 0x4f3c6179), TOBN(0x2dbc9d0a, 0x7853fc05), + TOBN(0x187d4f93, 0x9454d937), TOBN(0xe682ce9d, 0xb4800e1b), + TOBN(0xa9129ad8, 0x165e68e8), TOBN(0x0fe29735, 0xbe7f785b), + TOBN(0x5303f40c, 0x5b9e02b7), TOBN(0xa37c9692, 0x35ee04e8), + TOBN(0x5f46cc20, 0x34d6632b), TOBN(0x55ef72b2, 0x96ac545b), + TOBN(0xabec5c1f, 0x7b91b062), TOBN(0x0a79e1c7, 0xbb33e821), + TOBN(0xbb04b428, 0x3a9f4117), TOBN(0x0de1f28f, 0xfd2a475a), + TOBN(0x31019ccf, 0x3a4434b4), TOBN(0xa3458111, 0x1a7954dc), + TOBN(0xa9dac80d, 0xe34972a7), TOBN(0xb043d054, 0x74f6b8dd), + TOBN(0x021c319e, 0x11137b1a), TOBN(0x00a754ce, 0xed5cc03f), + TOBN(0x0aa2c794, 0xcbea5ad4), TOBN(0x093e67f4, 0x70c015b6), + TOBN(0x72cdfee9, 0xc97e3f6b), TOBN(0xc10bcab4, 0xb6da7461), + TOBN(0x3b02d2fc, 0xb59806b9), TOBN(0x85185e89, 0xa1de6f47), + TOBN(0x39e6931f, 0x0eb6c4d4), TOBN(0x4d4440bd, 0xd4fa5b04), + TOBN(0x5418786e, 0x34be7eb8), TOBN(0x6380e521, 0x9d7259bc), + TOBN(0x20ac0351, 0xd598d710), TOBN(0x272c4166, 0xcb3a4da4), + TOBN(0xdb82fe1a, 0xca71de1f), TOBN(0x746e79f2, 0xd8f54b0f), + TOBN(0x6e7fc736, 0x4b573e9b), TOBN(0x75d03f46, 0xfd4b5040), + TOBN(0x5c1cc36d, 0x0b98d87b), TOBN(0x513ba3f1, 0x1f472da1), + TOBN(0x79d0af26, 0xabb177dd), TOBN(0xf82ab568, 0x7891d564), + TOBN(0x2b6768a9, 0x72232173), TOBN(0xefbb3bb0, 0x8c1f6619), + TOBN(0xb29c11db, 0xa6d18358), TOBN(0x519e2797, 0xb0916d3a), + TOBN(0xd4dc18f0, 0x9188e290), TOBN(0x648e86e3, 0x98b0ca7f), + TOBN(0x859d3145, 0x983c38b5), TOBN(0xb14f176c, 0x637abc8b), + TOBN(0x2793fb9d, 0xcaff7be6), TOBN(0xebe5a55f, 0x35a66a5a), + TOBN(0x7cec1dcd, 0x9f87dc59), TOBN(0x7c595cd3, 0xfbdbf560), + TOBN(0x5b543b22, 0x26eb3257), TOBN(0x69080646, 0xc4c935fd), + TOBN(0x7f2e4403, 0x81e9ede3), TOBN(0x243c3894, 0xcaf6df0a), + TOBN(0x7c605bb1, 0x1c073b11), TOBN(0xcd06a541, 0xba6a4a62), + TOBN(0x29168949, 0x49d4e2e5), TOBN(0x33649d07, 0x4af66880), + TOBN(0xbfc0c885, 0xe9a85035), TOBN(0xb4e52113, 0xfc410f4b), + TOBN(0xdca3b706, 0x78a6513b), TOBN(0x92ea4a2a, 0x9edb1943), + TOBN(0x02642216, 0xdb6e2dd8), TOBN(0x9b45d0b4, 0x9fd57894), + TOBN(0x114e70db, 0xc69d11ae), TOBN(0x1477dd19, 0x4c57595f), + TOBN(0xbc2208b4, 0xec77c272), TOBN(0x95c5b4d7, 0xdb68f59c), + TOBN(0xb8c4fc63, 0x42e532b7), TOBN(0x386ba422, 0x9ae35290), + TOBN(0xfb5dda42, 0xd201ecbc), TOBN(0x2353dc8b, 0xa0e38fd6), + TOBN(0x9a0b85ea, 0x68f7e978), TOBN(0x96ec5682, 0x2ad6d11f), + TOBN(0x5e279d6c, 0xe5f6886d), TOBN(0xd3fe03cd, 0x3cb1914d), + TOBN(0xfe541fa4, 0x7ea67c77), TOBN(0x952bd2af, 0xe3ea810c), + TOBN(0x791fef56, 0x8d01d374), TOBN(0xa3a1c621, 0x0f11336e), + TOBN(0x5ad0d5a9, 0xc7ec6d79), TOBN(0xff7038af, 0x3225c342), + TOBN(0x003c6689, 0xbc69601b), TOBN(0x25059bc7, 0x45e8747d), + TOBN(0xfa4965b2, 0xf2086fbf), TOBN(0xf6840ea6, 0x86916078), + TOBN(0xd7ac7620, 0x70081d6c), TOBN(0xe600da31, 0xb5328645), + TOBN(0x01916f63, 0x529b8a80), TOBN(0xe80e4858, 0x2d7d6f3e), + TOBN(0x29eb0fe8, 0xd664ca7c), TOBN(0xf017637b, 0xe7b43b0c), + TOBN(0x9a75c806, 0x76cb2566), TOBN(0x8f76acb1, 0xb24892d9), + TOBN(0x7ae7b9cc, 0x1f08fe45), TOBN(0x19ef7329, 0x6a4907d8), + TOBN(0x2db4ab71, 0x5f228bf0), TOBN(0xf3cdea39, 0x817032d7), + TOBN(0x0b1f482e, 0xdcabe3c0), TOBN(0x3baf76b4, 0xbb86325c), + TOBN(0xd49065e0, 0x10089465), TOBN(0x3bab5d29, 0x8e77c596), + TOBN(0x7636c3a6, 0x193dbd95), TOBN(0xdef5d294, 0xb246e499), + TOBN(0xb22c58b9, 0x286b2475), TOBN(0xa0b93939, 0xcd80862b), + TOBN(0x3002c83a, 0xf0992388), TOBN(0x6de01f9b, 0xeacbe14c), + TOBN(0x6aac688e, 0xadd70482), TOBN(0x708de92a, 0x7b4a4e8a), + TOBN(0x75b6dd73, 0x758a6eef), TOBN(0xea4bf352, 0x725b3c43), + TOBN(0x10041f2c, 0x87912868), TOBN(0xb1b1be95, 0xef09297a), + TOBN(0x19ae23c5, 0xa9f3860a), TOBN(0xc4f0f839, 0x515dcf4b), + TOBN(0x3c7ecca3, 0x97f6306a), TOBN(0x744c44ae, 0x68a3a4b0), + TOBN(0x69cd13a0, 0xb3a1d8a2), TOBN(0x7cad0a1e, 0x5256b578), + TOBN(0xea653fcd, 0x33791d9e), TOBN(0x9cc2a05d, 0x74b2e05f), + TOBN(0x73b391dc, 0xfd7affa2), TOBN(0xddb7091e, 0xb6b05442), + TOBN(0xc71e27bf, 0x8538a5c6), TOBN(0x195c63dd, 0x89abff17), + TOBN(0xfd315285, 0x1b71e3da), TOBN(0x9cbdfda7, 0xfa680fa0), + TOBN(0x9db876ca, 0x849d7eab), TOBN(0xebe2764b, 0x3c273271), + TOBN(0x663357e3, 0xf208dcea), TOBN(0x8c5bd833, 0x565b1b70), + TOBN(0xccc3b4f5, 0x9837fc0d), TOBN(0x9b641ba8, 0xa79cf00f), + TOBN(0x7428243d, 0xdfdf3990), TOBN(0x83a594c4, 0x020786b1), + TOBN(0xb712451a, 0x526c4502), TOBN(0x9d39438e, 0x6adb3f93), + TOBN(0xfdb261e3, 0xe9ff0ccd), TOBN(0x80344e3c, 0xe07af4c3), + TOBN(0x75900d7c, 0x2fa4f126), TOBN(0x08a3b865, 0x5c99a232), + TOBN(0x2478b6bf, 0xdb25e0c3), TOBN(0x482cc2c2, 0x71db2edf), + TOBN(0x37df7e64, 0x5f321bb8), TOBN(0x8a93821b, 0x9a8005b4), + TOBN(0x3fa2f10c, 0xcc8c1958), TOBN(0x0d332218, 0x2c269d0a), + TOBN(0x20ab8119, 0xe246b0e6), TOBN(0xb39781e4, 0xd349fd17), + TOBN(0xd293231e, 0xb31aa100), TOBN(0x4b779c97, 0xbb032168), + TOBN(0x4b3f19e1, 0xc8470500), TOBN(0x45b7efe9, 0x0c4c869d), + TOBN(0xdb84f38a, 0xa1a6bbcc), TOBN(0x3b59cb15, 0xb2fddbc1), + TOBN(0xba5514df, 0x3fd165e8), TOBN(0x499fd6a9, 0x061f8811), + TOBN(0x72cd1fe0, 0xbfef9f00), TOBN(0x120a4bb9, 0x79ad7e8a), + TOBN(0xf2ffd095, 0x5f4a5ac5), TOBN(0xcfd174f1, 0x95a7a2f0), + TOBN(0xd42301ba, 0x9d17baf1), TOBN(0xd2fa487a, 0x77f22089), + TOBN(0x9cb09efe, 0xb1dc77e1), TOBN(0xe9566939, 0x21c99682), + TOBN(0x8c546901, 0x6c6067bb), TOBN(0xfd378574, 0x61c24456), + TOBN(0x2b6a6cbe, 0x81796b33), TOBN(0x62d550f6, 0x58e87f8b), + TOBN(0x1b763e1c, 0x7f1b01b4), TOBN(0x4b93cfea, 0x1b1b5e12), + TOBN(0xb9345238, 0x1d531696), TOBN(0x57201c00, 0x88cdde69), + TOBN(0xdde92251, 0x9a86afc7), TOBN(0xe3043895, 0xbd35cea8), + TOBN(0x7608c1e1, 0x8555970d), TOBN(0x8267dfa9, 0x2535935e), + TOBN(0xd4c60a57, 0x322ea38b), TOBN(0xe0bf7977, 0x804ef8b5), + TOBN(0x1a0dab28, 0xc06fece4), TOBN(0xd405991e, 0x94e7b49d), + TOBN(0xc542b6d2, 0x706dab28), TOBN(0xcb228da3, 0xa91618fb), + TOBN(0x224e4164, 0x107d1cea), TOBN(0xeb9fdab3, 0xd0f5d8f1), + TOBN(0xc02ba386, 0x0d6e41cd), TOBN(0x676a72c5, 0x9b1f7146), + TOBN(0xffd6dd98, 0x4d6cb00b), TOBN(0xcef9c5ca, 0xde2e8d7c), + TOBN(0xa1bbf5d7, 0x641c7936), TOBN(0x1b95b230, 0xee8f772e), + TOBN(0xf765a92e, 0xe8ac25b1), TOBN(0xceb04cfc, 0x3a18b7c6), + TOBN(0x27944cef, 0x0acc8966), TOBN(0xcbb3c957, 0x434c1004), + TOBN(0x9c9971a1, 0xa43ff93c), TOBN(0x5bc2db17, 0xa1e358a9), + TOBN(0x45b4862e, 0xa8d9bc82), TOBN(0x70ebfbfb, 0x2201e052), + TOBN(0xafdf64c7, 0x92871591), TOBN(0xea5bcae6, 0xb42d0219), + TOBN(0xde536c55, 0x2ad8f03c), TOBN(0xcd6c3f4d, 0xa76aa33c), + TOBN(0xbeb5f623, 0x0bca6de3), TOBN(0xdd20dd99, 0xb1e706fd), + TOBN(0x90b3ff9d, 0xac9059d4), TOBN(0x2d7b2902, 0x7ccccc4e), + TOBN(0x8a090a59, 0xce98840f), TOBN(0xa5d947e0, 0x8410680a), + TOBN(0x49ae346a, 0x923379a5), TOBN(0x7dbc84f9, 0xb28a3156), + TOBN(0xfd40d916, 0x54a1aff2), TOBN(0xabf318ba, 0x3a78fb9b), + TOBN(0x50152ed8, 0x3029f95e), TOBN(0x9fc1dd77, 0xc58ad7fa), + TOBN(0x5fa57915, 0x13595c17), TOBN(0xb9504668, 0x8f62b3a9), + TOBN(0x907b5b24, 0xff3055b0), TOBN(0x2e995e35, 0x9a84f125), + TOBN(0x87dacf69, 0x7e9bbcfb), TOBN(0x95d0c1d6, 0xe86d96e3), + TOBN(0x65726e3c, 0x2d95a75c), TOBN(0x2c3c9001, 0xacd27f21), + TOBN(0x1deab561, 0x6c973f57), TOBN(0x108b7e2c, 0xa5221643), + TOBN(0x5fee9859, 0xc4ef79d4), TOBN(0xbd62b88a, 0x40d4b8c6), + TOBN(0xb4dd29c4, 0x197c75d6), TOBN(0x266a6df2, 0xb7076feb), + TOBN(0x9512d0ea, 0x4bf2df11), TOBN(0x1320c24f, 0x6b0cc9ec), + TOBN(0x6bb1e0e1, 0x01a59596), TOBN(0x8317c5bb, 0xeff9aaac), + TOBN(0x65bb405e, 0x385aa6c9), TOBN(0x613439c1, 0x8f07988f), + TOBN(0xd730049f, 0x16a66e91), TOBN(0xe97f2820, 0xfa1b0e0d), + TOBN(0x4131e003, 0x304c28ea), TOBN(0x820ab732, 0x526bac62), + TOBN(0xb2ac9ef9, 0x28714423), TOBN(0x54ecfffa, 0xadb10cb2), + TOBN(0x8781476e, 0xf886a4cc), TOBN(0x4b2c87b5, 0xdb2f8d49), + TOBN(0xe857cd20, 0x0a44295d), TOBN(0x707d7d21, 0x58c6b044), + TOBN(0xae8521f9, 0xf596757c), TOBN(0x87448f03, 0x67b2b714), + TOBN(0x13a9bc45, 0x5ebcd58d), TOBN(0x79bcced9, 0x9122d3c1), + TOBN(0x3c644247, 0x9e076642), TOBN(0x0cf22778, 0x2df4767d), + TOBN(0x5e61aee4, 0x71d444b6), TOBN(0x211236bf, 0xc5084a1d), + TOBN(0x7e15bc9a, 0x4fd3eaf6), TOBN(0x68df2c34, 0xab622bf5), + TOBN(0x9e674f0f, 0x59bf4f36), TOBN(0xf883669b, 0xd7f34d73), + TOBN(0xc48ac1b8, 0x31497b1d), TOBN(0x323b925d, 0x5106703b), + TOBN(0x22156f42, 0x74082008), TOBN(0xeffc521a, 0xc8482bcb), + TOBN(0x5c6831bf, 0x12173479), TOBN(0xcaa2528f, 0xc4739490), + TOBN(0x84d2102a, 0x8f1b3c4d), TOBN(0xcf64dfc1, 0x2d9bec0d), + TOBN(0x433febad, 0x78a546ef), TOBN(0x1f621ec3, 0x7b73cef1), + TOBN(0x6aecd627, 0x37338615), TOBN(0x162082ab, 0x01d8edf6), + TOBN(0x833a8119, 0x19e86b66), TOBN(0x6023a251, 0xd299b5db), + TOBN(0xf5bb0c3a, 0xbbf04b89), TOBN(0x6735eb69, 0xae749a44), + TOBN(0xd0e058c5, 0x4713de3b), TOBN(0xfdf2593e, 0x2c3d4ccd), + TOBN(0x1b8f414e, 0xfdd23667), TOBN(0xdd52aaca, 0xfa2015ee), + TOBN(0x3e31b517, 0xbd9625ff), TOBN(0x5ec9322d, 0x8db5918c), + TOBN(0xbc73ac85, 0xa96f5294), TOBN(0x82aa5bf3, 0x61a0666a), + TOBN(0x49755810, 0xbf08ac42), TOBN(0xd21cdfd5, 0x891cedfc), + TOBN(0x918cb57b, 0x67f8be10), TOBN(0x365d1a7c, 0x56ffa726), + TOBN(0x2435c504, 0x6532de93), TOBN(0xc0fc5e10, 0x2674cd02), + TOBN(0x6e51fcf8, 0x9cbbb142), TOBN(0x1d436e5a, 0xafc50692), + TOBN(0x766bffff, 0x3fbcae22), TOBN(0x3148c2fd, 0xfd55d3b8), + TOBN(0x52c7fdc9, 0x233222fa), TOBN(0x89ff1092, 0xe419fb6b), + TOBN(0x3cd6db99, 0x25254977), TOBN(0x2e85a161, 0x1cf12ca7), + TOBN(0xadd2547c, 0xdc810bc9), TOBN(0xea3f458f, 0x9d257c22), + TOBN(0x642c1fbe, 0x27d6b19b), TOBN(0xed07e6b5, 0x140481a6), + TOBN(0x6ada1d42, 0x86d2e0f8), TOBN(0xe5920122, 0x0e8a9fd5), + TOBN(0x02c936af, 0x708c1b49), TOBN(0x60f30fee, 0x2b4bfaff), + TOBN(0x6637ad06, 0x858e6a61), TOBN(0xce4c7767, 0x3fd374d0), + TOBN(0x39d54b2d, 0x7188defb), TOBN(0xa8c9d250, 0xf56a6b66), + TOBN(0x58fc0f5e, 0xb24fe1dc), TOBN(0x9eaf9dee, 0x6b73f24c), + TOBN(0xa90d588b, 0x33650705), TOBN(0xde5b62c5, 0xaf2ec729), + TOBN(0x5c72cfae, 0xd3c2b36e), TOBN(0x868c19d5, 0x034435da), + TOBN(0x88605f93, 0xe17ee145), TOBN(0xaa60c4ee, 0x77a5d5b1), + TOBN(0xbcf5bfd2, 0x3b60c472), TOBN(0xaf4ef13c, 0xeb1d3049), + TOBN(0x373f44fc, 0xe13895c9), TOBN(0xf29b382f, 0x0cbc9822), + TOBN(0x1bfcb853, 0x73efaef6), TOBN(0xcf56ac9c, 0xa8c96f40), + TOBN(0xd7adf109, 0x7a191e24), TOBN(0x98035f44, 0xbf8a8dc2), + TOBN(0xf40a71b9, 0x1e750c84), TOBN(0xc57f7b0c, 0x5dc6c469), + TOBN(0x49a0e79c, 0x6fbc19c1), TOBN(0x6b0f5889, 0xa48ebdb8), + TOBN(0x5d3fd084, 0xa07c4e9f), TOBN(0xc3830111, 0xab27de14), + TOBN(0x0e4929fe, 0x33e08dcc), TOBN(0xf4a5ad24, 0x40bb73a3), + TOBN(0xde86c2bf, 0x490f97ca), TOBN(0x288f09c6, 0x67a1ce18), + TOBN(0x364bb886, 0x1844478d), TOBN(0x7840fa42, 0xceedb040), + TOBN(0x1269fdd2, 0x5a631b37), TOBN(0x94761f1e, 0xa47c8b7d), + TOBN(0xfc0c2e17, 0x481c6266), TOBN(0x85e16ea2, 0x3daa5fa7), + TOBN(0xccd86033, 0x92491048), TOBN(0x0c2f6963, 0xf4d402d7), + TOBN(0x6336f7df, 0xdf6a865c), TOBN(0x0a2a463c, 0xb5c02a87), + TOBN(0xb0e29be7, 0xbf2f12ee), TOBN(0xf0a22002, 0x66bad988), + TOBN(0x27f87e03, 0x9123c1d7), TOBN(0x21669c55, 0x328a8c98), + TOBN(0x186b9803, 0x92f14529), TOBN(0xd3d056cc, 0x63954df3), + TOBN(0x2f03fd58, 0x175a46f6), TOBN(0x63e34ebe, 0x11558558), + TOBN(0xe13fedee, 0x5b80cfa5), TOBN(0xe872a120, 0xd401dbd1), + TOBN(0x52657616, 0xe8a9d667), TOBN(0xbc8da4b6, 0xe08d6693), + TOBN(0x370fb9bb, 0x1b703e75), TOBN(0x6773b186, 0xd4338363), + TOBN(0x18dad378, 0xecef7bff), TOBN(0xaac787ed, 0x995677da), + TOBN(0x4801ea8b, 0x0437164b), TOBN(0xf430ad20, 0x73fe795e), + TOBN(0xb164154d, 0x8ee5eb73), TOBN(0x0884ecd8, 0x108f7c0e), + TOBN(0x0e6ec096, 0x5f520698), TOBN(0x640631fe, 0x44f7b8d9), + TOBN(0x92fd34fc, 0xa35a68b9), TOBN(0x9c5a4b66, 0x4d40cf4e), + TOBN(0x949454bf, 0x80b6783d), TOBN(0x80e701fe, 0x3a320a10), + TOBN(0x8d1a564a, 0x1a0a39b2), TOBN(0x1436d53d, 0x320587db), + TOBN(0xf5096e6d, 0x6556c362), TOBN(0xbc23a3c0, 0xe2455d7e), + TOBN(0x3a7aee54, 0x807230f9), TOBN(0x9ba1cfa6, 0x22ae82fd), + TOBN(0x833a057a, 0x99c5d706), TOBN(0x8be85f4b, 0x842315c9), + TOBN(0xd083179a, 0x66a72f12), TOBN(0x2fc77d5d, 0xcdcc73cd), + TOBN(0x22b88a80, 0x5616ee30), TOBN(0xfb09548f, 0xe7ab1083), + TOBN(0x8ad6ab0d, 0x511270cd), TOBN(0x61f6c57a, 0x6924d9ab), + TOBN(0xa0f7bf72, 0x90aecb08), TOBN(0x849f87c9, 0x0df784a4), + TOBN(0x27c79c15, 0xcfaf1d03), TOBN(0xbbf9f675, 0xc463face), + TOBN(0x91502c65, 0x765ba543), TOBN(0x18ce3cac, 0x42ea60dd), + TOBN(0xe5cee6ac, 0x6e43ecb3), TOBN(0x63e4e910, 0x68f2aeeb), + TOBN(0x26234fa3, 0xc85932ee), TOBN(0x96883e8b, 0x4c90c44d), + TOBN(0x29b9e738, 0xa18a50f6), TOBN(0xbfc62b2a, 0x3f0420df), + TOBN(0xd22a7d90, 0x6d3e1fa9), TOBN(0x17115618, 0xfe05b8a3), + TOBN(0x2a0c9926, 0xbb2b9c01), TOBN(0xc739fcc6, 0xe07e76a2), + TOBN(0x540e9157, 0x165e439a), TOBN(0x06353a62, 0x6a9063d8), + TOBN(0x84d95594, 0x61e927a3), TOBN(0x013b9b26, 0xe2e0be7f), + TOBN(0x4feaec3b, 0x973497f1), TOBN(0x15c0f94e, 0x093ebc2d), + TOBN(0x6af5f227, 0x33af0583), TOBN(0x0c2af206, 0xc61f3340), + TOBN(0xd25dbdf1, 0x4457397c), TOBN(0x2e8ed017, 0xcabcbae0), + TOBN(0xe3010938, 0xc2815306), TOBN(0xbaa99337, 0xe8c6cd68), + TOBN(0x08513182, 0x3b0ec7de), TOBN(0x1e1b822b, 0x58df05df), + TOBN(0x5c14842f, 0xa5c3b683), TOBN(0x98fe977e, 0x3eba34ce), + TOBN(0xfd2316c2, 0x0d5e8873), TOBN(0xe48d839a, 0xbd0d427d), + TOBN(0x495b2218, 0x623fc961), TOBN(0x24ee56e7, 0xb46fba5e), + TOBN(0x9184a55b, 0x91e4de58), TOBN(0xa7488ca5, 0xdfdea288), + TOBN(0xa723862e, 0xa8dcc943), TOBN(0x92d762b2, 0x849dc0fc), + TOBN(0x3c444a12, 0x091ff4a9), TOBN(0x581113fa, 0x0cada274), + TOBN(0xb9de0a45, 0x30d8eae2), TOBN(0x5e0fcd85, 0xdf6b41ea), + TOBN(0x6233ea68, 0xc094dbb5), TOBN(0xb77d062e, 0xd968d410), + TOBN(0x3e719bbc, 0x58b3002d), TOBN(0x68e7dd3d, 0x3dc49d58), + TOBN(0x8d825740, 0x013a5e58), TOBN(0x21311747, 0x3c9e3c1b), + TOBN(0x0cb0a2a7, 0x7c99b6ab), TOBN(0x5c48a3b3, 0xc2f888f2)}, + {TOBN(0xc7913e91, 0x991724f3), TOBN(0x5eda799c, 0x39cbd686), + TOBN(0xddb595c7, 0x63d4fc1e), TOBN(0x6b63b80b, 0xac4fed54), + TOBN(0x6ea0fc69, 0x7e5fb516), TOBN(0x737708ba, 0xd0f1c964), + TOBN(0x9628745f, 0x11a92ca5), TOBN(0x61f37958, 0x9a86967a), + TOBN(0x9af39b2c, 0xaa665072), TOBN(0x78322fa4, 0xefd324ef), + TOBN(0x3d153394, 0xc327bd31), TOBN(0x81d5f271, 0x3129dab0), + TOBN(0xc72e0c42, 0xf48027f5), TOBN(0xaa40cdbc, 0x8536e717), + TOBN(0xf45a657a, 0x2d369d0f), TOBN(0xb03bbfc4, 0xea7f74e6), + TOBN(0x46a8c418, 0x0d738ded), TOBN(0x6f1a5bb0, 0xe0de5729), + TOBN(0xf10230b9, 0x8ba81675), TOBN(0x32c6f30c, 0x112b33d4), + TOBN(0x7559129d, 0xd8fffb62), TOBN(0x6a281b47, 0xb459bf05), + TOBN(0x77c1bd3a, 0xfa3b6776), TOBN(0x0709b380, 0x7829973a), + TOBN(0x8c26b232, 0xa3326505), TOBN(0x38d69272, 0xee1d41bf), + TOBN(0x0459453e, 0xffe32afa), TOBN(0xce8143ad, 0x7cb3ea87), + TOBN(0x932ec1fa, 0x7e6ab666), TOBN(0x6cd2d230, 0x22286264), + TOBN(0x459a46fe, 0x6736f8ed), TOBN(0x50bf0d00, 0x9eca85bb), + TOBN(0x0b825852, 0x877a21ec), TOBN(0x300414a7, 0x0f537a94), + TOBN(0x3f1cba40, 0x21a9a6a2), TOBN(0x50824eee, 0x76943c00), + TOBN(0xa0dbfcec, 0xf83cba5d), TOBN(0xf9538148, 0x93b4f3c0), + TOBN(0x61744162, 0x48f24dd7), TOBN(0x5322d64d, 0xe4fb09dd), + TOBN(0x57447384, 0x3d9325f3), TOBN(0xa9bef2d0, 0xf371cb84), + TOBN(0x77d2188b, 0xa61e36c5), TOBN(0xbbd6a7d7, 0xc602df72), + TOBN(0xba3aa902, 0x8f61bc0b), TOBN(0xf49085ed, 0x6ed0b6a1), + TOBN(0x8bc625d6, 0xae6e8298), TOBN(0x832b0b1d, 0xa2e9c01d), + TOBN(0xa337c447, 0xf1f0ced1), TOBN(0x800cc793, 0x9492dd2b), + TOBN(0x4b93151d, 0xbea08efa), TOBN(0x820cf3f8, 0xde0a741e), + TOBN(0xff1982dc, 0x1c0f7d13), TOBN(0xef921960, 0x84dde6ca), + TOBN(0x1ad7d972, 0x45f96ee3), TOBN(0x319c8dbe, 0x29dea0c7), + TOBN(0xd3ea3871, 0x7b82b99b), TOBN(0x75922d4d, 0x470eb624), + TOBN(0x8f66ec54, 0x3b95d466), TOBN(0x66e673cc, 0xbee1e346), + TOBN(0x6afe67c4, 0xb5f2b89a), TOBN(0x3de9c1e6, 0x290e5cd3), + TOBN(0x8c278bb6, 0x310a2ada), TOBN(0x420fa384, 0x0bdb323b), + TOBN(0x0ae1d63b, 0x0eb919b0), TOBN(0xd74ee51d, 0xa74b9620), + TOBN(0x395458d0, 0xa674290c), TOBN(0x324c930f, 0x4620a510), + TOBN(0x2d1f4d19, 0xfbac27d4), TOBN(0x4086e8ca, 0x9bedeeac), + TOBN(0x0cdd211b, 0x9b679ab8), TOBN(0x5970167d, 0x7090fec4), + TOBN(0x3420f2c9, 0xfaf1fc63), TOBN(0x616d333a, 0x328c8bb4), + TOBN(0x7d65364c, 0x57f1fe4a), TOBN(0x9343e877, 0x55e5c73a), + TOBN(0x5795176b, 0xe970e78c), TOBN(0xa36ccebf, 0x60533627), + TOBN(0xfc7c7380, 0x09cdfc1b), TOBN(0xb39a2afe, 0xb3fec326), + TOBN(0xb7ff1ba1, 0x6224408a), TOBN(0xcc856e92, 0x247cfc5e), + TOBN(0x01f102e7, 0xc18bc493), TOBN(0x4613ab74, 0x2091c727), + TOBN(0xaa25e89c, 0xc420bf2b), TOBN(0x00a53176, 0x90337ec2), + TOBN(0xd2be9f43, 0x7d025fc7), TOBN(0x3316fb85, 0x6e6fe3dc), + TOBN(0x27520af5, 0x9ac50814), TOBN(0xfdf95e78, 0x9a8e4223), + TOBN(0xb7e7df2a, 0x56bec5a0), TOBN(0xf7022f7d, 0xdf159e5d), + TOBN(0x93eeeab1, 0xcac1fe8f), TOBN(0x8040188c, 0x37451168), + TOBN(0x7ee8aa8a, 0xd967dce6), TOBN(0xfa0e79e7, 0x3abc9299), + TOBN(0x67332cfc, 0x2064cfd1), TOBN(0x339c31de, 0xb0651934), + TOBN(0x719b28d5, 0x2a3bcbea), TOBN(0xee74c82b, 0x9d6ae5c6), + TOBN(0x0927d05e, 0xbaf28ee6), TOBN(0x82cecf2c, 0x9d719028), + TOBN(0x0b0d353e, 0xddb30289), TOBN(0xfe4bb977, 0xfddb2e29), + TOBN(0xbb5bb990, 0x640bfd9e), TOBN(0xd226e277, 0x82f62108), + TOBN(0x4bf00985, 0x02ffdd56), TOBN(0x7756758a, 0x2ca1b1b5), + TOBN(0xc32b62a3, 0x5285fe91), TOBN(0xedbc546a, 0x8c9cd140), + TOBN(0x1e47a013, 0xaf5cb008), TOBN(0xbca7e720, 0x073ce8f2), + TOBN(0xe10b2ab8, 0x17a91cae), TOBN(0xb89aab65, 0x08e27f63), + TOBN(0x7b3074a7, 0xdba3ddf9), TOBN(0x1c20ce09, 0x330c2972), + TOBN(0x6b9917b4, 0x5fcf7e33), TOBN(0xe6793743, 0x945ceb42), + TOBN(0x18fc2215, 0x5c633d19), TOBN(0xad1adb3c, 0xc7485474), + TOBN(0x646f9679, 0x6424c49b), TOBN(0xf888dfe8, 0x67c241c9), + TOBN(0xe12d4b93, 0x24f68b49), TOBN(0x9a6b62d8, 0xa571df20), + TOBN(0x81b4b26d, 0x179483cb), TOBN(0x666f9632, 0x9511fae2), + TOBN(0xd281b3e4, 0xd53aa51f), TOBN(0x7f96a765, 0x7f3dbd16), + TOBN(0xa7f8b5bf, 0x074a30ce), TOBN(0xd7f52107, 0x005a32e6), + TOBN(0x6f9e0907, 0x50237ed4), TOBN(0x2f21da47, 0x8096fa2b), + TOBN(0xf3e19cb4, 0xeec863a0), TOBN(0xd18f77fd, 0x9527620a), + TOBN(0x9505c81c, 0x407c1cf8), TOBN(0x9998db4e, 0x1b6ec284), + TOBN(0x7e3389e5, 0xc247d44d), TOBN(0x12507141, 0x3f4f3d80), + TOBN(0xd4ba0110, 0x4a78a6c7), TOBN(0x312874a0, 0x767720be), + TOBN(0xded059a6, 0x75944370), TOBN(0xd6123d90, 0x3b2c0bdd), + TOBN(0xa56b717b, 0x51c108e3), TOBN(0x9bb7940e, 0x070623e9), + TOBN(0x794e2d59, 0x84ac066c), TOBN(0xf5954a92, 0xe68c69a0), + TOBN(0x28c52458, 0x4fd99dcc), TOBN(0x60e639fc, 0xb1012517), + TOBN(0xc2e60125, 0x7de79248), TOBN(0xe9ef6404, 0xf12fc6d7), + TOBN(0x4c4f2808, 0x2a3b5d32), TOBN(0x865ad32e, 0xc768eb8a), + TOBN(0xac02331b, 0x13fb70b6), TOBN(0x037b44c1, 0x95599b27), + TOBN(0x1a860fc4, 0x60bd082c), TOBN(0xa2e25745, 0xc980cd01), + TOBN(0xee3387a8, 0x1da0263e), TOBN(0x931bfb95, 0x2d10f3d6), + TOBN(0x5b687270, 0xa1f24a32), TOBN(0xf140e65d, 0xca494b86), + TOBN(0x4f4ddf91, 0xb2f1ac7a), TOBN(0xf99eaabb, 0x760fee27), + TOBN(0x57f4008a, 0x49c228e5), TOBN(0x090be440, 0x1cf713bb), + TOBN(0xac91fbe4, 0x5004f022), TOBN(0xd838c2c2, 0x569e1af6), + TOBN(0xd6c7d20b, 0x0f1daaa5), TOBN(0xaa063ac1, 0x1bbb02c0), + TOBN(0x0938a422, 0x59558a78), TOBN(0x5343c669, 0x8435da2f), + TOBN(0x96f67b18, 0x034410dc), TOBN(0x7cc1e424, 0x84510804), + TOBN(0x86a1543f, 0x16dfbb7d), TOBN(0x921fa942, 0x5b5bd592), + TOBN(0x9dcccb6e, 0xb33dd03c), TOBN(0x8581ddd9, 0xb843f51e), + TOBN(0x54935fcb, 0x81d73c9e), TOBN(0x6d07e979, 0x0a5e97ab), + TOBN(0x4dc7b30a, 0xcf3a6bab), TOBN(0x147ab1f3, 0x170bee11), + TOBN(0x0aaf8e3d, 0x9fafdee4), TOBN(0xfab3dbcb, 0x538a8b95), + TOBN(0x405df4b3, 0x6ef13871), TOBN(0xf1f4e9cb, 0x088d5a49), + TOBN(0x9bcd24d3, 0x66b33f1d), TOBN(0x3b97b820, 0x5ce445c0), + TOBN(0xe2926549, 0xba93ff61), TOBN(0xd9c341ce, 0x4dafe616), + TOBN(0xfb30a76e, 0x16efb6f3), TOBN(0xdf24b8ca, 0x605b953c), + TOBN(0x8bd52afe, 0xc2fffb9f), TOBN(0xbbac5ff7, 0xe19d0b96), + TOBN(0x43c01b87, 0x459afccd), TOBN(0x6bd45143, 0xb7432652), + TOBN(0x84734530, 0x55b5d78e), TOBN(0x81088fdb, 0x1554ba7d), + TOBN(0xada0a52c, 0x1e269375), TOBN(0xf9f037c4, 0x2dc5ec10), + TOBN(0xc0660607, 0x94bfbc11), TOBN(0xc0a630bb, 0xc9c40d2f), + TOBN(0x5efc797e, 0xab64c31e), TOBN(0xffdb1dab, 0x74507144), + TOBN(0xf6124287, 0x1ca6790c), TOBN(0xe9609d81, 0xe69bf1bf), + TOBN(0xdb898595, 0x00d24fc9), TOBN(0x9c750333, 0xe51fb417), + TOBN(0x51830a91, 0xfef7bbde), TOBN(0x0ce67dc8, 0x945f585c), + TOBN(0x9a730ed4, 0x4763eb50), TOBN(0x24a0e221, 0xc1ab0d66), + TOBN(0x643b6393, 0x648748f3), TOBN(0x1982daa1, 0x6d3c6291), + TOBN(0x6f00a9f7, 0x8bbc5549), TOBN(0x7a1783e1, 0x7f36384e), + TOBN(0xe8346323, 0xde977f50), TOBN(0x91ab688d, 0xb245502a), + TOBN(0x331ab6b5, 0x6d0bdd66), TOBN(0x0a6ef32e, 0x64b71229), + TOBN(0x1028150e, 0xfe7c352f), TOBN(0x27e04350, 0xce7b39d3), + TOBN(0x2a3c8acd, 0xc1070c82), TOBN(0xfb2034d3, 0x80c9feef), + TOBN(0x2d729621, 0x709f3729), TOBN(0x8df290bf, 0x62cb4549), + TOBN(0x02f99f33, 0xfc2e4326), TOBN(0x3b30076d, 0x5eddf032), + TOBN(0xbb21f8cf, 0x0c652fb5), TOBN(0x314fb49e, 0xed91cf7b), + TOBN(0xa013eca5, 0x2f700750), TOBN(0x2b9e3c23, 0x712a4575), + TOBN(0xe5355557, 0xaf30fbb0), TOBN(0x1ada3516, 0x7c77e771), + TOBN(0x45f6ecb2, 0x7b135670), TOBN(0xe85d19df, 0x7cfc202e), + TOBN(0x0f1b50c7, 0x58d1be9f), TOBN(0x5ebf2c0a, 0xead2e344), + TOBN(0x1531fe4e, 0xabc199c9), TOBN(0xc7032592, 0x56bab0ae), + TOBN(0x16ab2e48, 0x6c1fec54), TOBN(0x0f87fda8, 0x04280188), + TOBN(0xdc9f46fc, 0x609e4a74), TOBN(0x2a44a143, 0xba667f91), + TOBN(0xbc3d8b95, 0xb4d83436), TOBN(0xa01e4bd0, 0xc7bd2958), + TOBN(0x7b182932, 0x73483c90), TOBN(0xa79c6aa1, 0xa7c7b598), + TOBN(0xbf3983c6, 0xeaaac07e), TOBN(0x8f18181e, 0x96e0d4e6), + TOBN(0x8553d37c, 0x051af62b), TOBN(0xe9a998eb, 0x0bf94496), + TOBN(0xe0844f9f, 0xb0d59aa1), TOBN(0x983fd558, 0xe6afb813), + TOBN(0x9670c0ca, 0x65d69804), TOBN(0x732b22de, 0x6ea5ff2d), + TOBN(0xd7640ba9, 0x5fd8623b), TOBN(0x9f619163, 0xa6351782), + TOBN(0x0bfc27ee, 0xacee5043), TOBN(0xae419e73, 0x2eb10f02), + TOBN(0x19c028d1, 0x8943fb05), TOBN(0x71f01cf7, 0xff13aa2a), + TOBN(0x7790737e, 0x8887a132), TOBN(0x67513309, 0x66318410), + TOBN(0x9819e8a3, 0x7ddb795e), TOBN(0xfecb8ef5, 0xdad100b2), + TOBN(0x59f74a22, 0x3021926a), TOBN(0xb7c28a49, 0x6f9b4c1c), + TOBN(0xed1a733f, 0x912ad0ab), TOBN(0x42a910af, 0x01a5659c), + TOBN(0x3842c6e0, 0x7bd68cab), TOBN(0x2b57fa38, 0x76d70ac8), + TOBN(0x8a6707a8, 0x3c53aaeb), TOBN(0x62c1c510, 0x65b4db18), + TOBN(0x8de2c1fb, 0xb2d09dc7), TOBN(0xc3dfed12, 0x266bd23b), + TOBN(0x927d039b, 0xd5b27db6), TOBN(0x2fb2f0f1, 0x103243da), + TOBN(0xf855a07b, 0x80be7399), TOBN(0xed9327ce, 0x1f9f27a8), + TOBN(0xa0bd99c7, 0x729bdef7), TOBN(0x2b67125e, 0x28250d88), + TOBN(0x784b26e8, 0x8670ced7), TOBN(0xe3dfe41f, 0xc31bd3b4), + TOBN(0x9e353a06, 0xbcc85cbc), TOBN(0x302e2909, 0x60178a9d), + TOBN(0x860abf11, 0xa6eac16e), TOBN(0x76447000, 0xaa2b3aac), + TOBN(0x46ff9d19, 0x850afdab), TOBN(0x35bdd6a5, 0xfdb2d4c1), + TOBN(0xe82594b0, 0x7e5c9ce9), TOBN(0x0f379e53, 0x20af346e), + TOBN(0x608b31e3, 0xbc65ad4a), TOBN(0x710c6b12, 0x267c4826), + TOBN(0x51c966f9, 0x71954cf1), TOBN(0xb1cec793, 0x0d0aa215), + TOBN(0x1f155989, 0x86bd23a8), TOBN(0xae2ff99c, 0xf9452e86), + TOBN(0xd8dd953c, 0x340ceaa2), TOBN(0x26355275, 0x2e2e9333), + TOBN(0x15d4e5f9, 0x8586f06d), TOBN(0xd6bf94a8, 0xf7cab546), + TOBN(0x33c59a0a, 0xb76a9af0), TOBN(0x52740ab3, 0xba095af7), + TOBN(0xc444de8a, 0x24389ca0), TOBN(0xcc6f9863, 0x706da0cb), + TOBN(0xb5a741a7, 0x6b2515cf), TOBN(0x71c41601, 0x9585c749), + TOBN(0x78350d4f, 0xe683de97), TOBN(0x31d61524, 0x63d0b5f5), + TOBN(0x7a0cc5e1, 0xfbce090b), TOBN(0xaac927ed, 0xfbcb2a5b), + TOBN(0xe920de49, 0x20d84c35), TOBN(0x8c06a0b6, 0x22b4de26), + TOBN(0xd34dd58b, 0xafe7ddf3), TOBN(0x55851fed, 0xc1e6e55b), + TOBN(0xd1395616, 0x960696e7), TOBN(0x940304b2, 0x5f22705f), + TOBN(0x6f43f861, 0xb0a2a860), TOBN(0xcf121282, 0x0e7cc981), + TOBN(0x12186212, 0x0ab64a96), TOBN(0x09215b9a, 0xb789383c), + TOBN(0x311eb305, 0x37387c09), TOBN(0xc5832fce, 0xf03ee760), + TOBN(0x30358f58, 0x32f7ea19), TOBN(0xe01d3c34, 0x91d53551), + TOBN(0x1ca5ee41, 0xda48ea80), TOBN(0x34e71e8e, 0xcf4fa4c1), + TOBN(0x312abd25, 0x7af1e1c7), TOBN(0xe3afcdeb, 0x2153f4a5), + TOBN(0x9d5c84d7, 0x00235e9a), TOBN(0x0308d3f4, 0x8c4c836f), + TOBN(0xc0a66b04, 0x89332de5), TOBN(0x610dd399, 0x89e566ef), + TOBN(0xf8eea460, 0xd1ac1635), TOBN(0x84cbb3fb, 0x20a2c0df), + TOBN(0x40afb488, 0xe74a48c5), TOBN(0x29738198, 0xd326b150), + TOBN(0x2a17747f, 0xa6d74081), TOBN(0x60ea4c05, 0x55a26214), + TOBN(0x53514bb4, 0x1f88c5fe), TOBN(0xedd64567, 0x7e83426c), + TOBN(0xd5d6cbec, 0x96460b25), TOBN(0xa12fd0ce, 0x68dc115e), + TOBN(0xc5bc3ed2, 0x697840ea), TOBN(0x969876a8, 0xa6331e31), + TOBN(0x60c36217, 0x472ff580), TOBN(0xf4229705, 0x4ad41393), + TOBN(0x4bd99ef0, 0xa03b8b92), TOBN(0x501c7317, 0xc144f4f6), + TOBN(0x159009b3, 0x18464945), TOBN(0x6d5e594c, 0x74c5c6be), + TOBN(0x2d587011, 0x321a3660), TOBN(0xd1e184b1, 0x3898d022), + TOBN(0x5ba04752, 0x4c6a7e04), TOBN(0x47fa1e2b, 0x45550b65), + TOBN(0x9419daf0, 0x48c0a9a5), TOBN(0x66362953, 0x7c243236), + TOBN(0xcd0744b1, 0x5cb12a88), TOBN(0x561b6f9a, 0x2b646188), + TOBN(0x599415a5, 0x66c2c0c0), TOBN(0xbe3f0859, 0x0f83f09a), + TOBN(0x9141c5be, 0xb92041b8), TOBN(0x01ae38c7, 0x26477d0d), + TOBN(0xca8b71f3, 0xd12c7a94), TOBN(0xfab5b31f, 0x765c70db), + TOBN(0x76ae7492, 0x487443e9), TOBN(0x8595a310, 0x990d1349), + TOBN(0xf8dbeda8, 0x7d460a37), TOBN(0x7f7ad082, 0x1e45a38f), + TOBN(0xed1d4db6, 0x1059705a), TOBN(0xa3dd492a, 0xe6b9c697), + TOBN(0x4b92ee3a, 0x6eb38bd5), TOBN(0xbab2609d, 0x67cc0bb7), + TOBN(0x7fc4fe89, 0x6e70ee82), TOBN(0xeff2c56e, 0x13e6b7e3), + TOBN(0x9b18959e, 0x34d26fca), TOBN(0x2517ab66, 0x889d6b45), + TOBN(0xf167b4e0, 0xbdefdd4f), TOBN(0x69958465, 0xf366e401), + TOBN(0x5aa368ab, 0xa73bbec0), TOBN(0x12148709, 0x7b240c21), + TOBN(0x378c3233, 0x18969006), TOBN(0xcb4d73ce, 0xe1fe53d1), + TOBN(0x5f50a80e, 0x130c4361), TOBN(0xd67f5951, 0x7ef5212b), + TOBN(0xf145e21e, 0x9e70c72e), TOBN(0xb2e52e29, 0x5566d2fb), + TOBN(0x44eaba4a, 0x032397f5), TOBN(0x5e56937b, 0x7e31a7de), + TOBN(0x68dcf517, 0x456c61e1), TOBN(0xbc2e954a, 0xa8b0a388), + TOBN(0xe3552fa7, 0x60a8b755), TOBN(0x03442dae, 0x73ad0cde), + TOBN(0x37ffe747, 0xceb26210), TOBN(0x983545e8, 0x787baef9), + TOBN(0x8b8c8535, 0x86a3de31), TOBN(0xc621dbcb, 0xfacd46db), + TOBN(0x82e442e9, 0x59266fbb), TOBN(0xa3514c37, 0x339d471c), + TOBN(0x3a11b771, 0x62cdad96), TOBN(0xf0cb3b3c, 0xecf9bdf0), + TOBN(0x3fcbdbce, 0x478e2135), TOBN(0x7547b5cf, 0xbda35342), + TOBN(0xa97e81f1, 0x8a677af6), TOBN(0xc8c2bf83, 0x28817987), + TOBN(0xdf07eaaf, 0x45580985), TOBN(0xc68d1f05, 0xc93b45cb), + TOBN(0x106aa2fe, 0xc77b4cac), TOBN(0x4c1d8afc, 0x04a7ae86), + TOBN(0xdb41c3fd, 0x9eb45ab2), TOBN(0x5b234b5b, 0xd4b22e74), + TOBN(0xda253dec, 0xf215958a), TOBN(0x67e0606e, 0xa04edfa0), + TOBN(0xabbbf070, 0xef751b11), TOBN(0xf352f175, 0xf6f06dce), + TOBN(0xdfc4b6af, 0x6839f6b4), TOBN(0x53ddf9a8, 0x9959848e), + TOBN(0xda49c379, 0xc21520b0), TOBN(0x90864ff0, 0xdbd5d1b6), + TOBN(0x2f055d23, 0x5f49c7f7), TOBN(0xe51e4e6a, 0xa796b2d8), + TOBN(0xc361a67f, 0x5c9dc340), TOBN(0x5ad53c37, 0xbca7c620), + TOBN(0xda1d6588, 0x32c756d0), TOBN(0xad60d911, 0x8bb67e13), + TOBN(0xd6c47bdf, 0x0eeec8c6), TOBN(0x4a27fec1, 0x078a1821), + TOBN(0x081f7415, 0xc3099524), TOBN(0x8effdf0b, 0x82cd8060), + TOBN(0xdb70ec1c, 0x65842df8), TOBN(0x8821b358, 0xd319a901), + TOBN(0x72ee56ee, 0xde42b529), TOBN(0x5bb39592, 0x236e4286), + TOBN(0xd1183316, 0xfd6f7140), TOBN(0xf9fadb5b, 0xbd8e81f7), + TOBN(0x701d5e0c, 0x5a02d962), TOBN(0xfdee4dbf, 0x1b601324), + TOBN(0xbed17407, 0x35d7620e), TOBN(0x04e3c2c3, 0xf48c0012), + TOBN(0x9ee29da7, 0x3455449a), TOBN(0x562cdef4, 0x91a836c4), + TOBN(0x8f682a5f, 0x47701097), TOBN(0x617125d8, 0xff88d0c2), + TOBN(0x948fda24, 0x57bb86dd), TOBN(0x348abb8f, 0x289f7286), + TOBN(0xeb10eab5, 0x99d94bbd), TOBN(0xd51ba28e, 0x4684d160), + TOBN(0xabe0e51c, 0x30c8f41a), TOBN(0x66588b45, 0x13254f4a), + TOBN(0x147ebf01, 0xfad097a5), TOBN(0x49883ea8, 0x610e815d), + TOBN(0xe44d60ba, 0x8a11de56), TOBN(0xa970de6e, 0x827a7a6d), + TOBN(0x2be41424, 0x5e17fc19), TOBN(0xd833c657, 0x01214057), + TOBN(0x1375813b, 0x363e723f), TOBN(0x6820bb88, 0xe6a52e9b), + TOBN(0x7e7f6970, 0xd875d56a), TOBN(0xd6a0a9ac, 0x51fbf6bf), + TOBN(0x54ba8790, 0xa3083c12), TOBN(0xebaeb23d, 0x6ae7eb64), + TOBN(0xa8685c3a, 0xb99a907a), TOBN(0xf1e74550, 0x026bf40b), + TOBN(0x7b73a027, 0xc802cd9e), TOBN(0x9a8a927c, 0x4fef4635), + TOBN(0xe1b6f60c, 0x08191224), TOBN(0xc4126ebb, 0xde4ec091), + TOBN(0xe1dff4dc, 0x4ae38d84), TOBN(0xde3f57db, 0x4f2ef985), + TOBN(0x34964337, 0xd446a1dd), TOBN(0x7bf217a0, 0x859e77f6), + TOBN(0x8ff10527, 0x8e1d13f5), TOBN(0xa304ef03, 0x74eeae27), + TOBN(0xfc6f5e47, 0xd19dfa5a), TOBN(0xdb007de3, 0x7fad982b), + TOBN(0x28205ad1, 0x613715f5), TOBN(0x251e6729, 0x7889529e), + TOBN(0x72705184, 0x1ae98e78), TOBN(0xf818537d, 0x271cac32), + TOBN(0xc8a15b7e, 0xb7f410f5), TOBN(0xc474356f, 0x81f62393), + TOBN(0x92dbdc5a, 0xc242316b), TOBN(0xabe060ac, 0xdbf4aff5), + TOBN(0x6e8c38fe, 0x909a8ec6), TOBN(0x43e514e5, 0x6116cb94), + TOBN(0x2078fa38, 0x07d784f9), TOBN(0x1161a880, 0xf4b5b357), + TOBN(0x5283ce79, 0x13adea3d), TOBN(0x0756c3e6, 0xcc6a910b), + TOBN(0x60bcfe01, 0xaaa79697), TOBN(0x04a73b29, 0x56391db1), + TOBN(0xdd8dad47, 0x189b45a0), TOBN(0xbfac0dd0, 0x48d5b8d9), + TOBN(0x34ab3af5, 0x7d3d2ec2), TOBN(0x6fa2fc2d, 0x207bd3af), + TOBN(0x9ff40092, 0x66550ded), TOBN(0x719b3e87, 0x1fd5b913), + TOBN(0xa573a496, 0x6d17fbc7), TOBN(0x0cd1a70a, 0x73d2b24e), + TOBN(0x34e2c5ca, 0xb2676937), TOBN(0xe7050b06, 0xbf669f21), + TOBN(0xfbe948b6, 0x1ede9046), TOBN(0xa0530051, 0x97662659), + TOBN(0x58cbd4ed, 0xf10124c5), TOBN(0xde2646e4, 0xdd6c06c8), + TOBN(0x332f8108, 0x8cad38c0), TOBN(0x471b7e90, 0x6bd68ae2), + TOBN(0x56ac3fb2, 0x0d8e27a3), TOBN(0xb54660db, 0x136b4b0d), + TOBN(0x123a1e11, 0xa6fd8de4), TOBN(0x44dbffea, 0xa37799ef), + TOBN(0x4540b977, 0xce6ac17c), TOBN(0x495173a8, 0xaf60acef)}, + {TOBN(0x9ebb284d, 0x391c2a82), TOBN(0xbcdd4863, 0x158308e8), + TOBN(0x006f16ec, 0x83f1edca), TOBN(0xa13e2c37, 0x695dc6c8), + TOBN(0x2ab756f0, 0x4a057a87), TOBN(0xa8765500, 0xa6b48f98), + TOBN(0x4252face, 0x68651c44), TOBN(0xa52b540b, 0xe1765e02), + TOBN(0x4f922fc5, 0x16a0d2bb), TOBN(0x0d5cc16c, 0x1a623499), + TOBN(0x9241cf3a, 0x57c62c8b), TOBN(0x2f5e6961, 0xfd1b667f), + TOBN(0x5c15c70b, 0xf5a01797), TOBN(0x3d20b44d, 0x60956192), + TOBN(0x04911b37, 0x071fdb52), TOBN(0xf648f916, 0x8d6f0f7b), + TOBN(0x6dc1acaf, 0xe60b7cf7), TOBN(0x25860a50, 0x84a9d869), + TOBN(0x56fc6f09, 0xe7ba8ac4), TOBN(0x828c5bd0, 0x6148d29e), + TOBN(0xac6b435e, 0xdc55ae5f), TOBN(0xa527f56c, 0xc0117411), + TOBN(0x94d5045e, 0xfd24342c), TOBN(0x2c4c0a35, 0x70b67c0d), + TOBN(0x027cc8b8, 0xfac61d9a), TOBN(0x7d25e062, 0xe3c6fe8a), + TOBN(0xe08805bf, 0xe5bff503), TOBN(0x13271e6c, 0x6ff632f7), + TOBN(0x55dca6c0, 0x232f76a5), TOBN(0x8957c32d, 0x701ef426), + TOBN(0xee728bcb, 0xa10a5178), TOBN(0x5ea60411, 0xb62c5173), + TOBN(0xfc4e964e, 0xd0b8892b), TOBN(0x9ea17683, 0x9301bb74), + TOBN(0x6265c5ae, 0xfcc48626), TOBN(0xe60cf82e, 0xbb3e9102), + TOBN(0x57adf797, 0xd4df5531), TOBN(0x235b59a1, 0x8deeefe2), + TOBN(0x60adcf58, 0x3f306eb1), TOBN(0x105c2753, 0x3d09492d), + TOBN(0x4090914b, 0xb5def996), TOBN(0x1cb69c83, 0x233dd1e7), + TOBN(0xc1e9c1d3, 0x9b3d5e76), TOBN(0x1f3338ed, 0xfccf6012), + TOBN(0xb1e95d0d, 0x2f5378a8), TOBN(0xacf4c2c7, 0x2f00cd21), + TOBN(0x6e984240, 0xeb5fe290), TOBN(0xd66c038d, 0x248088ae), + TOBN(0x804d264a, 0xf94d70cf), TOBN(0xbdb802ef, 0x7314bf7e), + TOBN(0x8fb54de2, 0x4333ed02), TOBN(0x740461e0, 0x285635d9), + TOBN(0x4113b2c8, 0x365e9383), TOBN(0xea762c83, 0x3fdef652), + TOBN(0x4eec6e2e, 0x47b956c1), TOBN(0xa3d814be, 0x65620fa4), + TOBN(0x9ad5462b, 0xb4d8bc50), TOBN(0x181c0b16, 0xa9195770), + TOBN(0xebd4fe1c, 0x78412a68), TOBN(0xae0341bc, 0xc0dff48c), + TOBN(0xb6bc45cf, 0x7003e866), TOBN(0xf11a6dea, 0x8a24a41b), + TOBN(0x5407151a, 0xd04c24c2), TOBN(0x62c9d27d, 0xda5b7b68), + TOBN(0x2e964235, 0x88cceff6), TOBN(0x8594c54f, 0x8b07ed69), + TOBN(0x1578e73c, 0xc84d0d0d), TOBN(0x7b4e1055, 0xff532868), + TOBN(0xa348c0d5, 0xb5ec995a), TOBN(0xbf4b9d55, 0x14289a54), + TOBN(0x9ba155a6, 0x58fbd777), TOBN(0x186ed7a8, 0x1a84491d), + TOBN(0xd4992b30, 0x614c0900), TOBN(0xda98d121, 0xbd00c24b), + TOBN(0x7f534dc8, 0x7ec4bfa1), TOBN(0x4a5ff674, 0x37dc34bc), + TOBN(0x68c196b8, 0x1d7ea1d7), TOBN(0x38cf2893, 0x80a6d208), + TOBN(0xfd56cd09, 0xe3cbbd6e), TOBN(0xec72e27e, 0x4205a5b6), + TOBN(0x15ea68f5, 0xa44f77f7), TOBN(0x7aa5f9fd, 0xb43c52bc), + TOBN(0x86ff676f, 0x94f0e609), TOBN(0xa4cde963, 0x2e2d432b), + TOBN(0x8cafa0c0, 0xeee470af), TOBN(0x84137d0e, 0x8a3f5ec8), + TOBN(0xebb40411, 0xfaa31231), TOBN(0xa239c13f, 0x6f7f7ccf), + TOBN(0x32865719, 0xa8afd30b), TOBN(0x86798328, 0x8a826dce), + TOBN(0xdf04e891, 0xc4a8fbe0), TOBN(0xbb6b6e1b, 0xebf56ad3), + TOBN(0x0a695b11, 0x471f1ff0), TOBN(0xd76c3389, 0xbe15baf0), + TOBN(0x018edb95, 0xbe96c43e), TOBN(0xf2beaaf4, 0x90794158), + TOBN(0x152db09e, 0xc3076a27), TOBN(0x5e82908e, 0xe416545d), + TOBN(0xa2c41272, 0x356d6f2e), TOBN(0xdc9c9642, 0x31fd74e1), + TOBN(0x66ceb88d, 0x519bf615), TOBN(0xe29ecd76, 0x05a2274e), + TOBN(0x3a0473c4, 0xbf5e2fa0), TOBN(0x6b6eb671, 0x64284e67), + TOBN(0xe8b97932, 0xb88756dd), TOBN(0xed4e8652, 0xf17e3e61), + TOBN(0xc2dd1499, 0x3ee1c4a4), TOBN(0xc0aaee17, 0x597f8c0e), + TOBN(0x15c4edb9, 0x6c168af3), TOBN(0x6563c7bf, 0xb39ae875), + TOBN(0xadfadb6f, 0x20adb436), TOBN(0xad55e8c9, 0x9a042ac0), + TOBN(0x975a1ed8, 0xb76da1f5), TOBN(0x10dfa466, 0xa58acb94), + TOBN(0x8dd7f7e3, 0xac060282), TOBN(0x6813e66a, 0x572a051e), + TOBN(0xb4ccae1e, 0x350cb901), TOBN(0xb653d656, 0x50cb7822), + TOBN(0x42484710, 0xdfab3b87), TOBN(0xcd7ee537, 0x9b670fd0), + TOBN(0x0a50b12e, 0x523b8bf6), TOBN(0x8009eb5b, 0x8f910c1b), + TOBN(0xf535af82, 0x4a167588), TOBN(0x0f835f9c, 0xfb2a2abd), + TOBN(0xf59b2931, 0x2afceb62), TOBN(0xc797df2a, 0x169d383f), + TOBN(0xeb3f5fb0, 0x66ac02b0), TOBN(0x029d4c6f, 0xdaa2d0ca), + TOBN(0xd4059bc1, 0xafab4bc5), TOBN(0x833f5c6f, 0x56783247), + TOBN(0xb5346630, 0x8d2d3605), TOBN(0x83387891, 0xd34d8433), + TOBN(0xd973b30f, 0xadd9419a), TOBN(0xbcca1099, 0xafe3fce8), + TOBN(0x08178315, 0x0809aac6), TOBN(0x01b7f21a, 0x540f0f11), + TOBN(0x65c29219, 0x909523c8), TOBN(0xa62f648f, 0xa3a1c741), + TOBN(0x88598d4f, 0x60c9e55a), TOBN(0xbce9141b, 0x0e4f347a), + TOBN(0x9af97d84, 0x35f9b988), TOBN(0x0210da62, 0x320475b6), + TOBN(0x3c076e22, 0x9191476c), TOBN(0x7520dbd9, 0x44fc7834), + TOBN(0x6a6b2cfe, 0xc1ab1bbd), TOBN(0xef8a65be, 0xdc650938), + TOBN(0x72855540, 0x805d7bc4), TOBN(0xda389396, 0xed11fdfd), + TOBN(0xa9d5bd36, 0x74660876), TOBN(0x11d67c54, 0xb45dff35), + TOBN(0x6af7d148, 0xa4f5da94), TOBN(0xbb8d4c3f, 0xc0bbeb31), + TOBN(0x87a7ebd1, 0xe0a1b12a), TOBN(0x1e4ef88d, 0x770ba95f), + TOBN(0x8c33345c, 0xdc2ae9cb), TOBN(0xcecf1276, 0x01cc8403), + TOBN(0x687c012e, 0x1b39b80f), TOBN(0xfd90d0ad, 0x35c33ba4), + TOBN(0xa3ef5a67, 0x5c9661c2), TOBN(0x368fc88e, 0xe017429e), + TOBN(0xd30c6761, 0x196a2fa2), TOBN(0x931b9817, 0xbd5b312e), + TOBN(0xba01000c, 0x72f54a31), TOBN(0xa203d2c8, 0x66eaa541), + TOBN(0xf2abdee0, 0x98939db3), TOBN(0xe37d6c2c, 0x3e606c02), + TOBN(0xf2921574, 0x521ff643), TOBN(0x2781b3c4, 0xd7e2fca3), + TOBN(0x664300b0, 0x7850ec06), TOBN(0xac5a38b9, 0x7d3a10cf), + TOBN(0x9233188d, 0xe34ab39d), TOBN(0xe77057e4, 0x5072cbb9), + TOBN(0xbcf0c042, 0xb59e78df), TOBN(0x4cfc91e8, 0x1d97de52), + TOBN(0x4661a26c, 0x3ee0ca4a), TOBN(0x5620a4c1, 0xfb8507bc), + TOBN(0x4b44d4aa, 0x049f842c), TOBN(0xceabc5d5, 0x1540e82b), + TOBN(0x306710fd, 0x15c6f156), TOBN(0xbe5ae52b, 0x63db1d72), + TOBN(0x06f1e7e6, 0x334957f1), TOBN(0x57e388f0, 0x31144a70), + TOBN(0xfb69bb2f, 0xdf96447b), TOBN(0x0f78ebd3, 0x73e38a12), + TOBN(0xb8222605, 0x2b7ce542), TOBN(0xe6d4ce99, 0x7472bde1), + TOBN(0x53e16ebe, 0x09d2f4da), TOBN(0x180ff42e, 0x53b92b2e), + TOBN(0xc59bcc02, 0x2c34a1c6), TOBN(0x3803d6f9, 0x422c46c2), + TOBN(0x18aff74f, 0x5c14a8a2), TOBN(0x55aebf80, 0x10a08b28), + TOBN(0x66097d58, 0x7135593f), TOBN(0x32e6eff7, 0x2be570cd), + TOBN(0x584e6a10, 0x2a8c860d), TOBN(0xcd185890, 0xa2eb4163), + TOBN(0x7ceae99d, 0x6d97e134), TOBN(0xd42c6b70, 0xdd8447ce), + TOBN(0x59ddbb4a, 0xb8c50273), TOBN(0x03c612df, 0x3cf34e1e), + TOBN(0x84b9ca15, 0x04b6c5a0), TOBN(0x35216f39, 0x18f0e3a3), + TOBN(0x3ec2d2bc, 0xbd986c00), TOBN(0x8bf546d9, 0xd19228fe), + TOBN(0xd1c655a4, 0x4cd623c3), TOBN(0x366ce718, 0x502b8e5a), + TOBN(0x2cfc84b4, 0xeea0bfe7), TOBN(0xe01d5cee, 0xcf443e8e), + TOBN(0x8ec045d9, 0x036520f8), TOBN(0xdfb3c3d1, 0x92d40e98), + TOBN(0x0bac4cce, 0xcc559a04), TOBN(0x35eccae5, 0x240ea6b1), + TOBN(0x180b32db, 0xf8a5a0ac), TOBN(0x547972a5, 0xeb699700), + TOBN(0xa3765801, 0xca26bca0), TOBN(0x57e09d0e, 0xa647f25a), + TOBN(0xb956970e, 0x2fdd23cc), TOBN(0xb80288bc, 0x5682e971), + TOBN(0xe6e6d91e, 0x9ae86ebc), TOBN(0x0564c83f, 0x8c9f1939), + TOBN(0x551932a2, 0x39560368), TOBN(0xe893752b, 0x049c28e2), + TOBN(0x0b03cee5, 0xa6a158c3), TOBN(0xe12d656b, 0x04964263), + TOBN(0x4b47554e, 0x63e3bc1d), TOBN(0xc719b6a2, 0x45044ff7), + TOBN(0x4f24d30a, 0xe48daa07), TOBN(0xa3f37556, 0xc8c1edc3), + TOBN(0x9a47bf76, 0x0700d360), TOBN(0xbb1a1824, 0x822ae4e2), + TOBN(0x22e275a3, 0x89f1fb4c), TOBN(0x72b1aa23, 0x9968c5f5), + TOBN(0xa75feaca, 0xbe063f64), TOBN(0x9b392f43, 0xbce47a09), + TOBN(0xd4241509, 0x1ad07aca), TOBN(0x4b0c591b, 0x8d26cd0f), + TOBN(0x2d42ddfd, 0x92f1169a), TOBN(0x63aeb1ac, 0x4cbf2392), + TOBN(0x1de9e877, 0x0691a2af), TOBN(0xebe79af7, 0xd98021da), + TOBN(0xcfdf2a4e, 0x40e50acf), TOBN(0xf0a98ad7, 0xaf01d665), + TOBN(0xefb640bf, 0x1831be1f), TOBN(0x6fe8bd2f, 0x80e9ada0), + TOBN(0x94c103a1, 0x6cafbc91), TOBN(0x170f8759, 0x8308e08c), + TOBN(0x5de2d2ab, 0x9780ff4f), TOBN(0x666466bc, 0x45b201f2), + TOBN(0x58af2010, 0xf5b343bc), TOBN(0x0f2e400a, 0xf2f142fe), + TOBN(0x3483bfde, 0xa85f4bdf), TOBN(0xf0b1d093, 0x03bfeaa9), + TOBN(0x2ea01b95, 0xc7081603), TOBN(0xe943e4c9, 0x3dba1097), + TOBN(0x47be92ad, 0xb438f3a6), TOBN(0x00bb7742, 0xe5bf6636), + TOBN(0x136b7083, 0x824297b4), TOBN(0x9d0e5580, 0x5584455f), + TOBN(0xab48cedc, 0xf1c7d69e), TOBN(0x53a9e481, 0x2a256e76), + TOBN(0x0402b0e0, 0x65eb2413), TOBN(0xdadbbb84, 0x8fc407a7), + TOBN(0xa65cd5a4, 0x8d7f5492), TOBN(0x21d44293, 0x74bae294), + TOBN(0x66917ce6, 0x3b5f1cc4), TOBN(0x37ae52ea, 0xce872e62), + TOBN(0xbb087b72, 0x2905f244), TOBN(0x12077086, 0x1e6af74f), + TOBN(0x4b644e49, 0x1058edea), TOBN(0x827510e3, 0xb638ca1d), + TOBN(0x8cf2b704, 0x6038591c), TOBN(0xffc8b47a, 0xfe635063), + TOBN(0x3ae220e6, 0x1b4d5e63), TOBN(0xbd864742, 0x9d961b4b), + TOBN(0x610c107e, 0x9bd16bed), TOBN(0x4270352a, 0x1127147b), + TOBN(0x7d17ffe6, 0x64cfc50e), TOBN(0x50dee01a, 0x1e36cb42), + TOBN(0x068a7622, 0x35dc5f9a), TOBN(0x9a08d536, 0xdf53f62c), + TOBN(0x4ed71457, 0x6be5f7de), TOBN(0xd93006f8, 0xc2263c9e), + TOBN(0xe073694c, 0xcacacb36), TOBN(0x2ff7a5b4, 0x3ae118ab), + TOBN(0x3cce53f1, 0xcd871236), TOBN(0xf156a39d, 0xc2aa6d52), + TOBN(0x9cc5f271, 0xb198d76d), TOBN(0xbc615b6f, 0x81383d39), + TOBN(0xa54538e8, 0xde3eee6b), TOBN(0x58c77538, 0xab910d91), + TOBN(0x31e5bdbc, 0x58d278bd), TOBN(0x3cde4adf, 0xb963acae), + TOBN(0xb1881fd2, 0x5302169c), TOBN(0x8ca60fa0, 0xa989ed8b), + TOBN(0xa1999458, 0xff96a0ee), TOBN(0xc1141f03, 0xac6c283d), + TOBN(0x7677408d, 0x6dfafed3), TOBN(0x33a01653, 0x39661588), + TOBN(0x3c9c15ec, 0x0b726fa0), TOBN(0x090cfd93, 0x6c9b56da), + TOBN(0xe34f4bae, 0xa3c40af5), TOBN(0x3469eadb, 0xd21129f1), + TOBN(0xcc51674a, 0x1e207ce8), TOBN(0x1e293b24, 0xc83b1ef9), + TOBN(0x17173d13, 0x1e6c0bb4), TOBN(0x19004695, 0x90776d35), + TOBN(0xe7980e34, 0x6de6f922), TOBN(0x873554cb, 0xf4dd9a22), + TOBN(0x0316c627, 0xcbf18a51), TOBN(0x4d93651b, 0x3032c081), + TOBN(0x207f2771, 0x3946834d), TOBN(0x2c08d7b4, 0x30cdbf80), + TOBN(0x137a4fb4, 0x86df2a61), TOBN(0xa1ed9c07, 0xecf7b4a2), + TOBN(0xb2e460e2, 0x7bd042ff), TOBN(0xb7f5e2fa, 0x5f62f5ec), + TOBN(0x7aa6ec6b, 0xcc2423b7), TOBN(0x75ce0a7f, 0xba63eea7), + TOBN(0x67a45fb1, 0xf250a6e1), TOBN(0x93bc919c, 0xe53cdc9f), + TOBN(0x9271f56f, 0x871942df), TOBN(0x2372ff6f, 0x7859ad66), + TOBN(0x5f4c2b96, 0x33cb1a78), TOBN(0xe3e29101, 0x5838aa83), + TOBN(0xa7ed1611, 0xe4e8110c), TOBN(0x2a2d70d5, 0x330198ce), + TOBN(0xbdf132e8, 0x6720efe0), TOBN(0xe61a8962, 0x66a471bf), + TOBN(0x796d3a85, 0x825808bd), TOBN(0x51dc3cb7, 0x3fd6e902), + TOBN(0x643c768a, 0x916219d1), TOBN(0x36cd7685, 0xa2ad7d32), + TOBN(0xe3db9d05, 0xb22922a4), TOBN(0x6494c87e, 0xdba29660), + TOBN(0xf0ac91df, 0xbcd2ebc7), TOBN(0x4deb57a0, 0x45107f8d), + TOBN(0x42271f59, 0xc3d12a73), TOBN(0x5f71687c, 0xa5c2c51d), + TOBN(0xcb1f50c6, 0x05797bcb), TOBN(0x29ed0ed9, 0xd6d34eb0), + TOBN(0xe5fe5b47, 0x4683c2eb), TOBN(0x4956eeb5, 0x97447c46), + TOBN(0x5b163a43, 0x71207167), TOBN(0x93fa2fed, 0x0248c5ef), + TOBN(0x67930af2, 0x31f63950), TOBN(0xa77797c1, 0x14caa2c9), + TOBN(0x526e80ee, 0x27ac7e62), TOBN(0xe1e6e626, 0x58b28aec), + TOBN(0x636178b0, 0xb3c9fef0), TOBN(0xaf7752e0, 0x6d5f90be), + TOBN(0x94ecaf18, 0xeece51cf), TOBN(0x2864d0ed, 0xca806e1f), + TOBN(0x6de2e383, 0x97c69134), TOBN(0x5a42c316, 0xeb291293), + TOBN(0xc7779219, 0x6a60bae0), TOBN(0xa24de346, 0x6b7599d1), + TOBN(0x49d374aa, 0xb75d4941), TOBN(0x98900586, 0x2d501ff0), + TOBN(0x9f16d40e, 0xeb7974cf), TOBN(0x1033860b, 0xcdd8c115), + TOBN(0xb6c69ac8, 0x2094cec3), TOBN(0x9976fb88, 0x403b770c), + TOBN(0x1dea026c, 0x4859590d), TOBN(0xb6acbb46, 0x8562d1fd), + TOBN(0x7cd6c461, 0x44569d85), TOBN(0xc3190a36, 0x97f0891d), + TOBN(0xc6f53195, 0x48d5a17d), TOBN(0x7d919966, 0xd749abc8), + TOBN(0x65104837, 0xdd1c8a20), TOBN(0x7e5410c8, 0x2f683419), + TOBN(0x958c3ca8, 0xbe94022e), TOBN(0x605c3197, 0x6145dac2), + TOBN(0x3fc07501, 0x01683d54), TOBN(0x1d7127c5, 0x595b1234), + TOBN(0x10b8f87c, 0x9481277f), TOBN(0x677db2a8, 0xe65a1adb), + TOBN(0xec2fccaa, 0xddce3345), TOBN(0x2a6811b7, 0x012a4350), + TOBN(0x96760ff1, 0xac598bdc), TOBN(0x054d652a, 0xd1bf4128), + TOBN(0x0a1151d4, 0x92a21005), TOBN(0xad7f3971, 0x33110fdf), + TOBN(0x8c95928c, 0x1960100f), TOBN(0x6c91c825, 0x7bf03362), + TOBN(0xc8c8b2a2, 0xce309f06), TOBN(0xfdb27b59, 0xca27204b), + TOBN(0xd223eaa5, 0x0848e32e), TOBN(0xb93e4b2e, 0xe7bfaf1e), + TOBN(0xc5308ae6, 0x44aa3ded), TOBN(0x317a666a, 0xc015d573), + TOBN(0xc888ce23, 0x1a979707), TOBN(0xf141c1e6, 0x0d5c4958), + TOBN(0xb53b7de5, 0x61906373), TOBN(0x858dbade, 0xeb999595), + TOBN(0x8cbb47b2, 0xa59e5c36), TOBN(0x660318b3, 0xdcf4e842), + TOBN(0xbd161ccd, 0x12ba4b7a), TOBN(0xf399daab, 0xf8c8282a), + TOBN(0x1587633a, 0xeeb2130d), TOBN(0xa465311a, 0xda38dd7d), + TOBN(0x5f75eec8, 0x64d3779b), TOBN(0x3c5d0476, 0xad64c171), + TOBN(0x87410371, 0x2a914428), TOBN(0x8096a891, 0x90e2fc29), + TOBN(0xd3d2ae9d, 0x23b3ebc2), TOBN(0x90bdd6db, 0xa580cfd6), + TOBN(0x52dbb7f3, 0xc5b01f6c), TOBN(0xe68eded4, 0xe102a2dc), + TOBN(0x17785b77, 0x99eb6df0), TOBN(0x26c3cc51, 0x7386b779), + TOBN(0x345ed988, 0x6417a48e), TOBN(0xe990b4e4, 0x07d6ef31), + TOBN(0x0f456b7e, 0x2586abba), TOBN(0x239ca6a5, 0x59c96e9a), + TOBN(0xe327459c, 0xe2eb4206), TOBN(0x3a4c3313, 0xa002b90a), + TOBN(0x2a114806, 0xf6a3f6fb), TOBN(0xad5cad2f, 0x85c251dd), + TOBN(0x92c1f613, 0xf5a784d3), TOBN(0xec7bfacf, 0x349766d5), + TOBN(0x04b3cd33, 0x3e23cb3b), TOBN(0x3979fe84, 0xc5a64b2d), + TOBN(0x192e2720, 0x7e589106), TOBN(0xa60c43d1, 0xa15b527f), + TOBN(0x2dae9082, 0xbe7cf3a6), TOBN(0xcc86ba92, 0xbc967274), + TOBN(0xf28a2ce8, 0xaea0a8a9), TOBN(0x404ca6d9, 0x6ee988b3), + TOBN(0xfd7e9c5d, 0x005921b8), TOBN(0xf56297f1, 0x44e79bf9), + TOBN(0xa163b460, 0x0d75ddc2), TOBN(0x30b23616, 0xa1f2be87), + TOBN(0x4b070d21, 0xbfe50e2b), TOBN(0x7ef8cfd0, 0xe1bfede1), + TOBN(0xadba0011, 0x2aac4ae0), TOBN(0x2a3e7d01, 0xb9ebd033), + TOBN(0x995277ec, 0xe38d9d1c), TOBN(0xb500249e, 0x9c5d2de3), + TOBN(0x8912b820, 0xf13ca8c9), TOBN(0xc8798114, 0x877793af), + TOBN(0x19e6125d, 0xec3f1dec), TOBN(0x07b1f040, 0x911178da), + TOBN(0xd93ededa, 0x904a6738), TOBN(0x55187a5a, 0x0bebedcd), + TOBN(0xf7d04722, 0xeb329d41), TOBN(0xf449099e, 0xf170b391), + TOBN(0xfd317a69, 0xca99f828), TOBN(0x50c3db2b, 0x34a4976d), + TOBN(0xe9ba7784, 0x3757b392), TOBN(0x326caefd, 0xaa3ca05a), + TOBN(0x78e5293b, 0xf1e593d4), TOBN(0x7842a937, 0x0d98fd13), + TOBN(0xe694bf96, 0x5f96b10d), TOBN(0x373a9df6, 0x06a8cd05), + TOBN(0x997d1e51, 0xe8f0c7fc), TOBN(0x1d019790, 0x63fd972e), + TOBN(0x0064d858, 0x5499fb32), TOBN(0x7b67bad9, 0x77a8aeb7), + TOBN(0x1d3eb977, 0x2d08eec5), TOBN(0x5fc047a6, 0xcbabae1d), + TOBN(0x0577d159, 0xe54a64bb), TOBN(0x8862201b, 0xc43497e4), + TOBN(0xad6b4e28, 0x2ce0608d), TOBN(0x8b687b7d, 0x0b167aac), + TOBN(0x6ed4d367, 0x8b2ecfa9), TOBN(0x24dfe62d, 0xa90c3c38), + TOBN(0xa1862e10, 0x3fe5c42b), TOBN(0x1ca73dca, 0xd5732a9f), + TOBN(0x35f038b7, 0x76bb87ad), TOBN(0x674976ab, 0xf242b81f), + TOBN(0x4f2bde7e, 0xb0fd90cd), TOBN(0x6efc172e, 0xa7fdf092), + TOBN(0x3806b69b, 0x92222f1f), TOBN(0x5a2459ca, 0x6cf7ae70), + TOBN(0x6789f69c, 0xa85217ee), TOBN(0x5f232b5e, 0xe3dc85ac), + TOBN(0x660e3ec5, 0x48e9e516), TOBN(0x124b4e47, 0x3197eb31), + TOBN(0x10a0cb13, 0xaafcca23), TOBN(0x7bd63ba4, 0x8213224f), + TOBN(0xaffad7cc, 0x290a7f4f), TOBN(0x6b409c9e, 0x0286b461), + TOBN(0x58ab809f, 0xffa407af), TOBN(0xc3122eed, 0xc68ac073), + TOBN(0x17bf9e50, 0x4ef24d7e), TOBN(0x5d929794, 0x3e2a5811), + TOBN(0x519bc867, 0x02902e01), TOBN(0x76bba5da, 0x39c8a851), + TOBN(0xe9f9669c, 0xda94951e), TOBN(0x4b6af58d, 0x66b8d418), + TOBN(0xfa321074, 0x17d426a4), TOBN(0xc78e66a9, 0x9dde6027), + TOBN(0x0516c083, 0x4a53b964), TOBN(0xfc659d38, 0xff602330), + TOBN(0x0ab55e5c, 0x58c5c897), TOBN(0x985099b2, 0x838bc5df), + TOBN(0x061d9efc, 0xc52fc238), TOBN(0x712b2728, 0x6ac1da3f), + TOBN(0xfb658149, 0x9283fe08), TOBN(0x4954ac94, 0xb8aaa2f7), + TOBN(0x85c0ada4, 0x7fb2e74f), TOBN(0xee8ba98e, 0xb89926b0), + TOBN(0xe4f9d37d, 0x23d1af5b), TOBN(0x14ccdbf9, 0xba9b015e), + TOBN(0xb674481b, 0x7bfe7178), TOBN(0x4e1debae, 0x65405868), + TOBN(0x061b2821, 0xc48c867d), TOBN(0x69c15b35, 0x513b30ea), + TOBN(0x3b4a1666, 0x36871088), TOBN(0xe5e29f5d, 0x1220b1ff), + TOBN(0x4b82bb35, 0x233d9f4d), TOBN(0x4e076333, 0x18cdc675)}, + {TOBN(0x0d53f5c7, 0xa3e6fced), TOBN(0xe8cbbdd5, 0xf45fbdeb), + TOBN(0xf85c01df, 0x13339a70), TOBN(0x0ff71880, 0x142ceb81), + TOBN(0x4c4e8774, 0xbd70437a), TOBN(0x5fb32891, 0xba0bda6a), + TOBN(0x1cdbebd2, 0xf18bd26e), TOBN(0x2f9526f1, 0x03a9d522), + TOBN(0x40ce3051, 0x92c4d684), TOBN(0x8b04d725, 0x7612efcd), + TOBN(0xb9dcda36, 0x6f9cae20), TOBN(0x0edc4d24, 0xf058856c), + TOBN(0x64f2e6bf, 0x85427900), TOBN(0x3de81295, 0xdc09dfea), + TOBN(0xd41b4487, 0x379bf26c), TOBN(0x50b62c6d, 0x6df135a9), + TOBN(0xd4f8e3b4, 0xc72dfe67), TOBN(0xc416b0f6, 0x90e19fdf), + TOBN(0x18b9098d, 0x4c13bd35), TOBN(0xac11118a, 0x15b8cb9e), + TOBN(0xf598a318, 0xf0062841), TOBN(0xbfe0602f, 0x89f356f4), + TOBN(0x7ae3637e, 0x30177a0c), TOBN(0x34097747, 0x61136537), + TOBN(0x0db2fb5e, 0xd005832a), TOBN(0x5f5efd3b, 0x91042e4f), + TOBN(0x8c4ffdc6, 0xed70f8ca), TOBN(0xe4645d0b, 0xb52da9cc), + TOBN(0x9596f58b, 0xc9001d1f), TOBN(0x52c8f0bc, 0x4e117205), + TOBN(0xfd4aa0d2, 0xe398a084), TOBN(0x815bfe3a, 0x104f49de), + TOBN(0x97e5443f, 0x23885e5f), TOBN(0xf72f8f99, 0xe8433aab), + TOBN(0xbd00b154, 0xe4d4e604), TOBN(0xd0b35e6a, 0xe5e173ff), + TOBN(0x57b2a048, 0x9164722d), TOBN(0x3e3c665b, 0x88761ec8), + TOBN(0x6bdd1397, 0x3da83832), TOBN(0x3c8b1a1e, 0x73dafe3b), + TOBN(0x4497ace6, 0x54317cac), TOBN(0xbe600ab9, 0x521771b3), + TOBN(0xb42e409e, 0xb0dfe8b8), TOBN(0x386a67d7, 0x3942310f), + TOBN(0x25548d8d, 0x4431cc28), TOBN(0xa7cff142, 0x985dc524), + TOBN(0x4d60f5a1, 0x93c4be32), TOBN(0x83ebd5c8, 0xd071c6e1), + TOBN(0xba3a80a7, 0xb1fd2b0b), TOBN(0x9b3ad396, 0x5bec33e8), + TOBN(0xb3868d61, 0x79743fb3), TOBN(0xcfd169fc, 0xfdb462fa), + TOBN(0xd3b499d7, 0x9ce0a6af), TOBN(0x55dc1cf1, 0xe42d3ff8), + TOBN(0x04fb9e6c, 0xc6c3e1b2), TOBN(0x47e6961d, 0x6f69a474), + TOBN(0x54eb3acc, 0xe548b37b), TOBN(0xb38e7542, 0x84d40549), + TOBN(0x8c3daa51, 0x7b341b4f), TOBN(0x2f6928ec, 0x690bf7fa), + TOBN(0x0496b323, 0x86ce6c41), TOBN(0x01be1c55, 0x10adadcd), + TOBN(0xc04e67e7, 0x4bb5faf9), TOBN(0x3cbaf678, 0xe15c9985), + TOBN(0x8cd12145, 0x50ca4247), TOBN(0xba1aa47a, 0xe7dd30aa), + TOBN(0x2f81ddf1, 0xe58fee24), TOBN(0x03452936, 0xeec9b0e8), + TOBN(0x8bdc3b81, 0x243aea96), TOBN(0x9a2919af, 0x15c3d0e5), + TOBN(0x9ea640ec, 0x10948361), TOBN(0x5ac86d5b, 0x6e0bcccf), + TOBN(0xf892d918, 0xc36cf440), TOBN(0xaed3e837, 0xc939719c), + TOBN(0xb07b08d2, 0xc0218b64), TOBN(0x6f1bcbba, 0xce9790dd), + TOBN(0x4a84d6ed, 0x60919b8e), TOBN(0xd8900791, 0x8ac1f9eb), + TOBN(0xf84941aa, 0x0dd5daef), TOBN(0xb22fe40a, 0x67fd62c5), + TOBN(0x97e15ba2, 0x157f2db3), TOBN(0xbda2fc8f, 0x8e28ca9c), + TOBN(0x5d050da4, 0x37b9f454), TOBN(0x3d57eb57, 0x2379d72e), + TOBN(0xe9b5eba2, 0xfb5ee997), TOBN(0x01648ca2, 0xe11538ca), + TOBN(0x32bb76f6, 0xf6327974), TOBN(0x338f14b8, 0xff3f4bb7), + TOBN(0x524d226a, 0xd7ab9a2d), TOBN(0x9c00090d, 0x7dfae958), + TOBN(0x0ba5f539, 0x8751d8c2), TOBN(0x8afcbcdd, 0x3ab8262d), + TOBN(0x57392729, 0xe99d043b), TOBN(0xef51263b, 0xaebc943a), + TOBN(0x9feace93, 0x20862935), TOBN(0x639efc03, 0xb06c817b), + TOBN(0x1fe054b3, 0x66b4be7a), TOBN(0x3f25a9de, 0x84a37a1e), + TOBN(0xf39ef1ad, 0x78d75cd9), TOBN(0xd7b58f49, 0x5062c1b5), + TOBN(0x6f74f9a9, 0xff563436), TOBN(0xf718ff29, 0xe8af51e7), + TOBN(0x5234d313, 0x15e97fec), TOBN(0xb6a8e2b1, 0x292f1c0a), + TOBN(0xa7f53aa8, 0x327720c1), TOBN(0x956ca322, 0xba092cc8), + TOBN(0x8f03d64a, 0x28746c4d), TOBN(0x51fe1782, 0x66d0d392), + TOBN(0xd19b34db, 0x3c832c80), TOBN(0x60dccc5c, 0x6da2e3b4), + TOBN(0x245dd62e, 0x0a104ccc), TOBN(0xa7ab1de1, 0x620b21fd), + TOBN(0xb293ae0b, 0x3893d123), TOBN(0xf7b75783, 0xb15ee71c), + TOBN(0x5aa3c614, 0x42a9468b), TOBN(0xd686123c, 0xdb15d744), + TOBN(0x8c616891, 0xa7ab4116), TOBN(0x6fcd72c8, 0xa4e6a459), + TOBN(0xac219110, 0x77e5fad7), TOBN(0xfb6a20e7, 0x704fa46b), + TOBN(0xe839be7d, 0x341d81dc), TOBN(0xcddb6889, 0x32148379), + TOBN(0xda6211a1, 0xf7026ead), TOBN(0xf3b2575f, 0xf4d1cc5e), + TOBN(0x40cfc8f6, 0xa7a73ae6), TOBN(0x83879a5e, 0x61d5b483), + TOBN(0xc5acb1ed, 0x41a50ebc), TOBN(0x59a60cc8, 0x3c07d8fa), + TOBN(0x1b73bdce, 0xb1876262), TOBN(0x2b0d79f0, 0x12af4ee9), + TOBN(0x8bcf3b0b, 0xd46e1d07), TOBN(0x17d6af9d, 0xe45d152f), + TOBN(0x73520461, 0x6d736451), TOBN(0x43cbbd97, 0x56b0bf5a), + TOBN(0xb0833a5b, 0xd5999b9d), TOBN(0x702614f0, 0xeb72e398), + TOBN(0x0aadf01a, 0x59c3e9f8), TOBN(0x40200e77, 0xce6b3d16), + TOBN(0xda22bdd3, 0xdeddafad), TOBN(0x76dedaf4, 0x310d72e1), + TOBN(0x49ef807c, 0x4bc2e88f), TOBN(0x6ba81291, 0x146dd5a5), + TOBN(0xa1a4077a, 0x7d8d59e9), TOBN(0x87b6a2e7, 0x802db349), + TOBN(0xd5679997, 0x1b4e598e), TOBN(0xf499ef1f, 0x06fe4b1d), + TOBN(0x3978d3ae, 0xfcb267c5), TOBN(0xb582b557, 0x235786d0), + TOBN(0x32b3b2ca, 0x1715cb07), TOBN(0x4c3de6a2, 0x8480241d), + TOBN(0x63b5ffed, 0xcb571ecd), TOBN(0xeaf53900, 0xed2fe9a9), + TOBN(0xdec98d4a, 0xc3b81990), TOBN(0x1cb83722, 0x9e0cc8fe), + TOBN(0xfe0b0491, 0xd2b427b9), TOBN(0x0f2386ac, 0xe983a66c), + TOBN(0x930c4d1e, 0xb3291213), TOBN(0xa2f82b2e, 0x59a62ae4), + TOBN(0x77233853, 0xf93e89e3), TOBN(0x7f8063ac, 0x11777c7f), + TOBN(0xff0eb567, 0x59ad2877), TOBN(0x6f454642, 0x9865c754), + TOBN(0xe6fe701a, 0x236e9a84), TOBN(0xc586ef16, 0x06e40fc3), + TOBN(0x3f62b6e0, 0x24bafad9), TOBN(0xc8b42bd2, 0x64da906a), + TOBN(0xc98e1eb4, 0xda3276a0), TOBN(0x30d0e5fc, 0x06cbf852), + TOBN(0x1b6b2ae1, 0xe8b4dfd4), TOBN(0xd754d5c7, 0x8301cbac), + TOBN(0x66097629, 0x112a39ac), TOBN(0xf86b5999, 0x93ba4ab9), + TOBN(0x26c9dea7, 0x99f9d581), TOBN(0x0473b1a8, 0xc2fafeaa), + TOBN(0x1469af55, 0x3b2505a5), TOBN(0x227d16d7, 0xd6a43323), + TOBN(0x3316f73c, 0xad3d97f9), TOBN(0x52bf3bb5, 0x1f137455), + TOBN(0x953eafeb, 0x09954e7c), TOBN(0xa721dfed, 0xdd732411), + TOBN(0xb4929821, 0x141d4579), TOBN(0x3411321c, 0xaa3bd435), + TOBN(0xafb355aa, 0x17fa6015), TOBN(0xb4e7ef4a, 0x18e42f0e), + TOBN(0x604ac97c, 0x59371000), TOBN(0xe1c48c70, 0x7f759c18), + TOBN(0x3f62ecc5, 0xa5db6b65), TOBN(0x0a78b173, 0x38a21495), + TOBN(0x6be1819d, 0xbcc8ad94), TOBN(0x70dc04f6, 0xd89c3400), + TOBN(0x462557b4, 0xa6b4840a), TOBN(0x544c6ade, 0x60bd21c0), + TOBN(0x6a00f24e, 0x907a544b), TOBN(0xa7520dcb, 0x313da210), + TOBN(0xfe939b75, 0x11e4994b), TOBN(0x918b6ba6, 0xbc275d70), + TOBN(0xd3e5e0fc, 0x644be892), TOBN(0x707a9816, 0xfdaf6c42), + TOBN(0x60145567, 0xf15c13fe), TOBN(0x4818ebaa, 0xe130a54a), + TOBN(0x28aad3ad, 0x58d2f767), TOBN(0xdc5267fd, 0xd7e7c773), + TOBN(0x4919cc88, 0xc3afcc98), TOBN(0xaa2e6ab0, 0x2db8cd4b), + TOBN(0xd46fec04, 0xd0c63eaa), TOBN(0xa1cb92c5, 0x19ffa832), + TOBN(0x678dd178, 0xe43a631f), TOBN(0xfb5ae1cd, 0x3dc788b3), + TOBN(0x68b4fb90, 0x6e77de04), TOBN(0x7992bcf0, 0xf06dbb97), + TOBN(0x896e6a13, 0xc417c01d), TOBN(0x8d96332c, 0xb956be01), + TOBN(0x902fc93a, 0x413aa2b9), TOBN(0x99a4d915, 0xfc98c8a5), + TOBN(0x52c29407, 0x565f1137), TOBN(0x4072690f, 0x21e4f281), + TOBN(0x36e607cf, 0x02ff6072), TOBN(0xa47d2ca9, 0x8ad98cdc), + TOBN(0xbf471d1e, 0xf5f56609), TOBN(0xbcf86623, 0xf264ada0), + TOBN(0xb70c0687, 0xaa9e5cb6), TOBN(0xc98124f2, 0x17401c6c), + TOBN(0x8189635f, 0xd4a61435), TOBN(0xd28fb8af, 0xa9d98ea6), + TOBN(0xb9a67c2a, 0x40c251f8), TOBN(0x88cd5d87, 0xa2da44be), + TOBN(0x437deb96, 0xe09b5423), TOBN(0x150467db, 0x64287dc1), + TOBN(0xe161debb, 0xcdabb839), TOBN(0xa79e9742, 0xf1839a3e), + TOBN(0xbb8dd3c2, 0x652d202b), TOBN(0x7b3e67f7, 0xe9f97d96), + TOBN(0x5aa5d78f, 0xb1cb6ac9), TOBN(0xffa13e8e, 0xca1d0d45), + TOBN(0x369295dd, 0x2ba5bf95), TOBN(0xd68bd1f8, 0x39aff05e), + TOBN(0xaf0d86f9, 0x26d783f2), TOBN(0x543a59b3, 0xfc3aafc1), + TOBN(0x3fcf81d2, 0x7b7da97c), TOBN(0xc990a056, 0xd25dee46), + TOBN(0x3e6775b8, 0x519cce2c), TOBN(0xfc9af71f, 0xae13d863), + TOBN(0x774a4a6f, 0x47c1605c), TOBN(0x46ba4245, 0x2fd205e8), + TOBN(0xa06feea4, 0xd3fd524d), TOBN(0x1e724641, 0x6de1acc2), + TOBN(0xf53816f1, 0x334e2b42), TOBN(0x49e5918e, 0x922f0024), + TOBN(0x439530b6, 0x65c7322d), TOBN(0xcf12cc01, 0xb3c1b3fb), + TOBN(0xc70b0186, 0x0172f685), TOBN(0xb915ee22, 0x1b58391d), + TOBN(0x9afdf03b, 0xa317db24), TOBN(0x87dec659, 0x17b8ffc4), + TOBN(0x7f46597b, 0xe4d3d050), TOBN(0x80a1c1ed, 0x006500e7), + TOBN(0x84902a96, 0x78bf030e), TOBN(0xfb5e9c9a, 0x50560148), + TOBN(0x6dae0a92, 0x63362426), TOBN(0xdcaeecf4, 0xa9e30c40), + TOBN(0xc0d887bb, 0x518d0c6b), TOBN(0x99181152, 0xcb985b9d), + TOBN(0xad186898, 0xef7bc381), TOBN(0x18168ffb, 0x9ee46201), + TOBN(0x9a04cdaa, 0x2502753c), TOBN(0xbb279e26, 0x51407c41), + TOBN(0xeacb03aa, 0xf23564e5), TOBN(0x18336582, 0x71e61016), + TOBN(0x8684b8c4, 0xeb809877), TOBN(0xb336e18d, 0xea0e672e), + TOBN(0xefb601f0, 0x34ee5867), TOBN(0x2733edbe, 0x1341cfd1), + TOBN(0xb15e809a, 0x26025c3c), TOBN(0xe6e981a6, 0x9350df88), + TOBN(0x92376237, 0x8502fd8e), TOBN(0x4791f216, 0x0c12be9b), + TOBN(0xb7256789, 0x25f02425), TOBN(0xec863194, 0x7a974443), + TOBN(0x7c0ce882, 0xfb41cc52), TOBN(0xc266ff7e, 0xf25c07f2), + TOBN(0x3d4da8c3, 0x017025f3), TOBN(0xefcf628c, 0xfb9579b4), + TOBN(0x5c4d0016, 0x1f3716ec), TOBN(0x9c27ebc4, 0x6801116e), + TOBN(0x5eba0ea1, 0x1da1767e), TOBN(0xfe151452, 0x47004c57), + TOBN(0x3ace6df6, 0x8c2373b7), TOBN(0x75c3dffe, 0x5dbc37ac), + TOBN(0x3dc32a73, 0xddc925fc), TOBN(0xb679c841, 0x2f65ee0b), + TOBN(0x715a3295, 0x451cbfeb), TOBN(0xd9889768, 0xf76e9a29), + TOBN(0xec20ce7f, 0xb28ad247), TOBN(0xe99146c4, 0x00894d79), + TOBN(0x71457d7c, 0x9f5e3ea7), TOBN(0x097b2662, 0x38030031), + TOBN(0xdb7f6ae6, 0xcf9f82a8), TOBN(0x319decb9, 0x438f473a), + TOBN(0xa63ab386, 0x283856c3), TOBN(0x13e3172f, 0xb06a361b), + TOBN(0x2959f8dc, 0x7d5a006c), TOBN(0x2dbc27c6, 0x75fba752), + TOBN(0xc1227ab2, 0x87c22c9e), TOBN(0x06f61f75, 0x71a268b2), + TOBN(0x1b6bb971, 0x04779ce2), TOBN(0xaca83812, 0x0aadcb1d), + TOBN(0x297ae0bc, 0xaeaab2d5), TOBN(0xa5c14ee7, 0x5bfb9f13), + TOBN(0xaa00c583, 0xf17a62c7), TOBN(0x39eb962c, 0x173759f6), + TOBN(0x1eeba1d4, 0x86c9a88f), TOBN(0x0ab6c37a, 0xdf016c5e), + TOBN(0xa2a147db, 0xa28a0749), TOBN(0x246c20d6, 0xee519165), + TOBN(0x5068d1b1, 0xd3810715), TOBN(0xb1e7018c, 0x748160b9), + TOBN(0x03f5b1fa, 0xf380ff62), TOBN(0xef7fb1dd, 0xf3cb2c1e), + TOBN(0xeab539a8, 0xfc91a7da), TOBN(0x83ddb707, 0xf3f9b561), + TOBN(0xc550e211, 0xfe7df7a4), TOBN(0xa7cd07f2, 0x063f6f40), + TOBN(0xb0de3635, 0x2976879c), TOBN(0xb5f83f85, 0xe55741da), + TOBN(0x4ea9d25e, 0xf3d8ac3d), TOBN(0x6fe2066f, 0x62819f02), + TOBN(0x4ab2b9c2, 0xcef4a564), TOBN(0x1e155d96, 0x5ffa2de3), + TOBN(0x0eb0a19b, 0xc3a72d00), TOBN(0x4037665b, 0x8513c31b), + TOBN(0x2fb2b6bf, 0x04c64637), TOBN(0x45c34d6e, 0x08cdc639), + TOBN(0x56f1e10f, 0xf01fd796), TOBN(0x4dfb8101, 0xfe3667b8), + TOBN(0xe0eda253, 0x9021d0c0), TOBN(0x7a94e9ff, 0x8a06c6ab), + TOBN(0x2d3bb0d9, 0xbb9aa882), TOBN(0xea20e4e5, 0xec05fd10), + TOBN(0xed7eeb5f, 0x1a1ca64e), TOBN(0x2fa6b43c, 0xc6327cbd), + TOBN(0xb577e3cf, 0x3aa91121), TOBN(0x8c6bd5ea, 0x3a34079b), + TOBN(0xd7e5ba39, 0x60e02fc0), TOBN(0xf16dd2c3, 0x90141bf8), + TOBN(0xb57276d9, 0x80101b98), TOBN(0x760883fd, 0xb82f0f66), + TOBN(0x89d7de75, 0x4bc3eff3), TOBN(0x03b60643, 0x5dc2ab40), + TOBN(0xcd6e53df, 0xe05beeac), TOBN(0xf2f1e862, 0xbc3325cd), + TOBN(0xdd0f7921, 0x774f03c3), TOBN(0x97ca7221, 0x4552cc1b), + TOBN(0x5a0d6afe, 0x1cd19f72), TOBN(0xa20915dc, 0xf183fbeb), + TOBN(0x9fda4b40, 0x832c403c), TOBN(0x32738edd, 0xbe425442), + TOBN(0x469a1df6, 0xb5eccf1a), TOBN(0x4b5aff42, 0x28bbe1f0), + TOBN(0x31359d7f, 0x570dfc93), TOBN(0xa18be235, 0xf0088628), + TOBN(0xa5b30fba, 0xb00ed3a9), TOBN(0x34c61374, 0x73cdf8be), + TOBN(0x2c5c5f46, 0xabc56797), TOBN(0x5cecf93d, 0xb82a8ae2), + TOBN(0x7d3dbe41, 0xa968fbf0), TOBN(0xd23d4583, 0x1a5c7f3d), + TOBN(0xf28f69a0, 0xc087a9c7), TOBN(0xc2d75471, 0x474471ca), + TOBN(0x36ec9f4a, 0x4eb732ec), TOBN(0x6c943bbd, 0xb1ca6bed), + TOBN(0xd64535e1, 0xf2457892), TOBN(0x8b84a8ea, 0xf7e2ac06), + TOBN(0xe0936cd3, 0x2499dd5f), TOBN(0x12053d7e, 0x0ed04e57), + TOBN(0x4bdd0076, 0xe4305d9d), TOBN(0x34a527b9, 0x1f67f0a2), + TOBN(0xe79a4af0, 0x9cec46ea), TOBN(0xb15347a1, 0x658b9bc7), + TOBN(0x6bd2796f, 0x35af2f75), TOBN(0xac957990, 0x4051c435), + TOBN(0x2669dda3, 0xc33a655d), TOBN(0x5d503c2e, 0x88514aa3), + TOBN(0xdfa11337, 0x3753dd41), TOBN(0x3f054673, 0x0b754f78), + TOBN(0xbf185677, 0x496125bd), TOBN(0xfb0023c8, 0x3775006c), + TOBN(0xfa0f072f, 0x3a037899), TOBN(0x4222b6eb, 0x0e4aea57), + TOBN(0x3dde5e76, 0x7866d25a), TOBN(0xb6eb04f8, 0x4837aa6f), + TOBN(0x5315591a, 0x2cf1cdb8), TOBN(0x6dfb4f41, 0x2d4e683c), + TOBN(0x7e923ea4, 0x48ee1f3a), TOBN(0x9604d9f7, 0x05a2afd5), + TOBN(0xbe1d4a33, 0x40ea4948), TOBN(0x5b45f1f4, 0xb44cbd2f), + TOBN(0x5faf8376, 0x4acc757e), TOBN(0xa7cf9ab8, 0x63d68ff7), + TOBN(0x8ad62f69, 0xdf0e404b), TOBN(0xd65f33c2, 0x12bdafdf), + TOBN(0xc365de15, 0xa377b14e), TOBN(0x6bf5463b, 0x8e39f60c), + TOBN(0x62030d2d, 0x2ce68148), TOBN(0xd95867ef, 0xe6f843a8), + TOBN(0xd39a0244, 0xef5ab017), TOBN(0x0bd2d8c1, 0x4ab55d12), + TOBN(0xc9503db3, 0x41639169), TOBN(0x2d4e25b0, 0xf7660c8a), + TOBN(0x760cb3b5, 0xe224c5d7), TOBN(0xfa3baf8c, 0x68616919), + TOBN(0x9fbca113, 0x8d142552), TOBN(0x1ab18bf1, 0x7669ebf5), + TOBN(0x55e6f53e, 0x9bdf25dd), TOBN(0x04cc0bf3, 0xcb6cd154), + TOBN(0x595bef49, 0x95e89080), TOBN(0xfe9459a8, 0x104a9ac1), + TOBN(0xad2d89ca, 0xcce9bb32), TOBN(0xddea65e1, 0xf7de8285), + TOBN(0x62ed8c35, 0xb351bd4b), TOBN(0x4150ff36, 0x0c0e19a7), + TOBN(0x86e3c801, 0x345f4e47), TOBN(0x3bf21f71, 0x203a266c), + TOBN(0x7ae110d4, 0x855b1f13), TOBN(0x5d6aaf6a, 0x07262517), + TOBN(0x1e0f12e1, 0x813d28f1), TOBN(0x6000e11d, 0x7ad7a523), + TOBN(0xc7d8deef, 0xc744a17b), TOBN(0x1e990b48, 0x14c05a00), + TOBN(0x68fddaee, 0x93e976d5), TOBN(0x696241d1, 0x46610d63), + TOBN(0xb204e7c3, 0x893dda88), TOBN(0x8bccfa65, 0x6a3a6946), + TOBN(0xb59425b4, 0xc5cd1411), TOBN(0x701b4042, 0xff3658b1), + TOBN(0xe3e56bca, 0x4784cf93), TOBN(0x27de5f15, 0x8fe68d60), + TOBN(0x4ab9cfce, 0xf8d53f19), TOBN(0xddb10311, 0xa40a730d), + TOBN(0x6fa73cd1, 0x4eee0a8a), TOBN(0xfd548748, 0x5249719d), + TOBN(0x49d66316, 0xa8123ef0), TOBN(0x73c32db4, 0xe7f95438), + TOBN(0x2e2ed209, 0x0d9e7854), TOBN(0xf98a9329, 0x9d9f0507), + TOBN(0xc5d33cf6, 0x0c6aa20a), TOBN(0x9a32ba14, 0x75279bb2), + TOBN(0x7e3202cb, 0x774a7307), TOBN(0x64ed4bc4, 0xe8c42dbd), + TOBN(0xc20f1a06, 0xd4caed0d), TOBN(0xb8021407, 0x171d22b3), + TOBN(0xd426ca04, 0xd13268d7), TOBN(0x92377007, 0x25f4d126), + TOBN(0x4204cbc3, 0x71f21a85), TOBN(0x18461b7a, 0xf82369ba), + TOBN(0xc0c07d31, 0x3fc858f9), TOBN(0x5deb5a50, 0xe2bab569), + TOBN(0xd5959d46, 0xd5eea89e), TOBN(0xfdff8424, 0x08437f4b), + TOBN(0xf21071e4, 0x3cfe254f), TOBN(0x72417696, 0x95468321), + TOBN(0x5d8288b9, 0x102cae3e), TOBN(0x2d143e3d, 0xf1965dff), + TOBN(0x00c9a376, 0xa078d847), TOBN(0x6fc0da31, 0x26028731), + TOBN(0xa2baeadf, 0xe45083a2), TOBN(0x66bc7218, 0x5e5b4bcd), + TOBN(0x2c826442, 0xd04b8e7f), TOBN(0xc19f5451, 0x6c4b586b), + TOBN(0x60182c49, 0x5b7eeed5), TOBN(0xd9954ecd, 0x7aa9dfa1), + TOBN(0xa403a8ec, 0xc73884ad), TOBN(0x7fb17de2, 0x9bb39041), + TOBN(0x694b64c5, 0xabb020e8), TOBN(0x3d18c184, 0x19c4eec7), + TOBN(0x9c4673ef, 0x1c4793e5), TOBN(0xc7b8aeb5, 0x056092e6), + TOBN(0x3aa1ca43, 0xf0f8c16b), TOBN(0x224ed5ec, 0xd679b2f6), + TOBN(0x0d56eeaf, 0x55a205c9), TOBN(0xbfe115ba, 0x4b8e028b), + TOBN(0x97e60849, 0x3927f4fe), TOBN(0xf91fbf94, 0x759aa7c5), + TOBN(0x985af769, 0x6be90a51), TOBN(0xc1277b78, 0x78ccb823), + TOBN(0x395b656e, 0xe7a75952), TOBN(0x00df7de0, 0x928da5f5), + TOBN(0x09c23175, 0x4ca4454f), TOBN(0x4ec971f4, 0x7aa2d3c1), + TOBN(0x45c3c507, 0xe75d9ccc), TOBN(0x63b7be8a, 0x3dc90306), + TOBN(0x37e09c66, 0x5db44bdc), TOBN(0x50d60da1, 0x6841c6a2), + TOBN(0x6f9b65ee, 0x08df1b12), TOBN(0x38734879, 0x7ff089df), + TOBN(0x9c331a66, 0x3fe8013d), TOBN(0x017f5de9, 0x5f42fcc8), + TOBN(0x43077866, 0xe8e57567), TOBN(0xc9f781ce, 0xf9fcdb18), + TOBN(0x38131dda, 0x9b12e174), TOBN(0x25d84aa3, 0x8a03752a), + TOBN(0x45e09e09, 0x4d0c0ce2), TOBN(0x1564008b, 0x92bebba5), + TOBN(0xf7e8ad31, 0xa87284c7), TOBN(0xb7c4b46c, 0x97e7bbaa), + TOBN(0x3e22a7b3, 0x97acf4ec), TOBN(0x0426c400, 0x5ea8b640), + TOBN(0x5e3295a6, 0x4e969285), TOBN(0x22aabc59, 0xa6a45670), + TOBN(0xb929714c, 0x5f5942bc), TOBN(0x9a6168bd, 0xfa3182ed), + TOBN(0x2216a665, 0x104152ba), TOBN(0x46908d03, 0xb6926368)}, + {TOBN(0xa9f5d874, 0x5a1251fb), TOBN(0x967747a8, 0xc72725c7), + TOBN(0x195c33e5, 0x31ffe89e), TOBN(0x609d210f, 0xe964935e), + TOBN(0xcafd6ca8, 0x2fe12227), TOBN(0xaf9b5b96, 0x0426469d), + TOBN(0x2e9ee04c, 0x5693183c), TOBN(0x1084a333, 0xc8146fef), + TOBN(0x96649933, 0xaed1d1f7), TOBN(0x566eaff3, 0x50563090), + TOBN(0x345057f0, 0xad2e39cf), TOBN(0x148ff65b, 0x1f832124), + TOBN(0x042e89d4, 0xcf94cf0d), TOBN(0x319bec84, 0x520c58b3), + TOBN(0x2a267626, 0x5361aa0d), TOBN(0xc86fa302, 0x8fbc87ad), + TOBN(0xfc83d2ab, 0x5c8b06d5), TOBN(0xb1a785a2, 0xfe4eac46), + TOBN(0xb99315bc, 0x846f7779), TOBN(0xcf31d816, 0xef9ea505), + TOBN(0x2391fe6a, 0x15d7dc85), TOBN(0x2f132b04, 0xb4016b33), + TOBN(0x29547fe3, 0x181cb4c7), TOBN(0xdb66d8a6, 0x650155a1), + TOBN(0x6b66d7e1, 0xadc1696f), TOBN(0x98ebe593, 0x0acd72d0), + TOBN(0x65f24550, 0xcc1b7435), TOBN(0xce231393, 0xb4b9a5ec), + TOBN(0x234a22d4, 0xdb067df9), TOBN(0x98dda095, 0xcaff9b00), + TOBN(0x1bbc75a0, 0x6100c9c1), TOBN(0x1560a9c8, 0x939cf695), + TOBN(0xcf006d3e, 0x99e0925f), TOBN(0x2dd74a96, 0x6322375a), + TOBN(0xc58b446a, 0xb56af5ba), TOBN(0x50292683, 0xe0b9b4f1), + TOBN(0xe2c34cb4, 0x1aeaffa3), TOBN(0x8b17203f, 0x9b9587c1), + TOBN(0x6d559207, 0xead1350c), TOBN(0x2b66a215, 0xfb7f9604), + TOBN(0x0850325e, 0xfe51bf74), TOBN(0x9c4f579e, 0x5e460094), + TOBN(0x5c87b92a, 0x76da2f25), TOBN(0x889de4e0, 0x6febef33), + TOBN(0x6900ec06, 0x646083ce), TOBN(0xbe2a0335, 0xbfe12773), + TOBN(0xadd1da35, 0xc5344110), TOBN(0x757568b7, 0xb802cd20), + TOBN(0x75559779, 0x00f7e6c8), TOBN(0x38e8b94f, 0x0facd2f0), + TOBN(0xfea1f3af, 0x03fde375), TOBN(0x5e11a1d8, 0x75881dfc), + TOBN(0xb3a6b02e, 0xc1e2f2ef), TOBN(0x193d2bbb, 0xc605a6c5), + TOBN(0x325ffeee, 0x339a0b2d), TOBN(0x27b6a724, 0x9e0c8846), + TOBN(0xe4050f1c, 0xf1c367ca), TOBN(0x9bc85a9b, 0xc90fbc7d), + TOBN(0xa373c4a2, 0xe1a11032), TOBN(0xb64232b7, 0xad0393a9), + TOBN(0xf5577eb0, 0x167dad29), TOBN(0x1604f301, 0x94b78ab2), + TOBN(0x0baa94af, 0xe829348b), TOBN(0x77fbd8dd, 0x41654342), + TOBN(0xdab50ea5, 0xb964e39a), TOBN(0xd4c29e3c, 0xd0d3c76e), + TOBN(0x80dae67c, 0x56d11964), TOBN(0x7307a8bf, 0xe5ffcc2f), + TOBN(0x65bbc1aa, 0x91708c3b), TOBN(0xa151e62c, 0x28bf0eeb), + TOBN(0x6cb53381, 0x6fa34db7), TOBN(0x5139e05c, 0xa29403a8), + TOBN(0x6ff651b4, 0x94a7cd2e), TOBN(0x5671ffd1, 0x0699336c), + TOBN(0x6f5fd2cc, 0x979a896a), TOBN(0x11e893a8, 0xd8148cef), + TOBN(0x988906a1, 0x65cf7b10), TOBN(0x81b67178, 0xc50d8485), + TOBN(0x7c0deb35, 0x8a35b3de), TOBN(0x423ac855, 0xc1d29799), + TOBN(0xaf580d87, 0xdac50b74), TOBN(0x28b2b89f, 0x5869734c), + TOBN(0x99a3b936, 0x874e28fb), TOBN(0xbb2c9190, 0x25f3f73a), + TOBN(0x199f6918, 0x84a9d5b7), TOBN(0x7ebe2325, 0x7e770374), + TOBN(0xf442e107, 0x0738efe2), TOBN(0xcf9f3f56, 0xcf9082d2), + TOBN(0x719f69e1, 0x09618708), TOBN(0xcc9e8364, 0xc183f9b1), + TOBN(0xec203a95, 0x366a21af), TOBN(0x6aec5d6d, 0x068b141f), + TOBN(0xee2df78a, 0x994f04e9), TOBN(0xb39ccae8, 0x271245b0), + TOBN(0xb875a4a9, 0x97e43f4f), TOBN(0x507dfe11, 0xdb2cea98), + TOBN(0x4fbf81cb, 0x489b03e9), TOBN(0xdb86ec5b, 0x6ec414fa), + TOBN(0xfad444f9, 0xf51b3ae5), TOBN(0xca7d33d6, 0x1914e3fe), + TOBN(0xa9c32f5c, 0x0ae6c4d0), TOBN(0xa9ca1d1e, 0x73969568), + TOBN(0x98043c31, 0x1aa7467e), TOBN(0xe832e75c, 0xe21b5ac6), + TOBN(0x314b7aea, 0x5232123d), TOBN(0x08307c8c, 0x65ae86db), + TOBN(0x06e7165c, 0xaa4668ed), TOBN(0xb170458b, 0xb4d3ec39), + TOBN(0x4d2e3ec6, 0xc19bb986), TOBN(0xc5f34846, 0xae0304ed), + TOBN(0x917695a0, 0x6c9f9722), TOBN(0x6c7f7317, 0x4cab1c0a), + TOBN(0x6295940e, 0x9d6d2e8b), TOBN(0xd318b8c1, 0x549f7c97), + TOBN(0x22453204, 0x97713885), TOBN(0x468d834b, 0xa8a440fe), + TOBN(0xd81fe5b2, 0xbfba796e), TOBN(0x152364db, 0x6d71f116), + TOBN(0xbb8c7c59, 0xb5b66e53), TOBN(0x0b12c61b, 0x2641a192), + TOBN(0x31f14802, 0xfcf0a7fd), TOBN(0x42fd0789, 0x5488b01e), + TOBN(0x71d78d6d, 0x9952b498), TOBN(0x8eb572d9, 0x07ac5201), + TOBN(0xe0a2a44c, 0x4d194a88), TOBN(0xd2b63fd9, 0xba017e66), + TOBN(0x78efc6c8, 0xf888aefc), TOBN(0xb76f6bda, 0x4a881a11), + TOBN(0x187f314b, 0xb46c2397), TOBN(0x004cf566, 0x5ded2819), + TOBN(0xa9ea5704, 0x38764d34), TOBN(0xbba45217, 0x78084709), + TOBN(0x06474571, 0x1171121e), TOBN(0xad7b7eb1, 0xe7c9b671), + TOBN(0xdacfbc40, 0x730f7507), TOBN(0x178cd8c6, 0xc7ad7bd1), + TOBN(0xbf0be101, 0xb2a67238), TOBN(0x3556d367, 0xaf9c14f2), + TOBN(0x104b7831, 0xa5662075), TOBN(0x58ca59bb, 0x79d9e60a), + TOBN(0x4bc45392, 0xa569a73b), TOBN(0x517a52e8, 0x5698f6c9), + TOBN(0x85643da5, 0xaeadd755), TOBN(0x1aed0cd5, 0x2a581b84), + TOBN(0xb9b4ff84, 0x80af1372), TOBN(0x244c3113, 0xf1ba5d1f), + TOBN(0x2a5dacbe, 0xf5f98d31), TOBN(0x2c3323e8, 0x4375bc2a), + TOBN(0x17a3ab4a, 0x5594b1dd), TOBN(0xa1928bfb, 0xceb4797e), + TOBN(0xe83af245, 0xe4886a19), TOBN(0x8979d546, 0x72b5a74a), + TOBN(0xa0f726bc, 0x19f9e967), TOBN(0xd9d03152, 0xe8fbbf4e), + TOBN(0xcfd6f51d, 0xb7707d40), TOBN(0x633084d9, 0x63f6e6e0), + TOBN(0xedcd9cdc, 0x55667eaf), TOBN(0x73b7f92b, 0x2e44d56f), + TOBN(0xfb2e39b6, 0x4e962b14), TOBN(0x7d408f6e, 0xf671fcbf), + TOBN(0xcc634ddc, 0x164a89bb), TOBN(0x74a42bb2, 0x3ef3bd05), + TOBN(0x1280dbb2, 0x428decbb), TOBN(0x6103f6bb, 0x402c8596), + TOBN(0xfa2bf581, 0x355a5752), TOBN(0x562f96a8, 0x00946674), + TOBN(0x4e4ca16d, 0x6da0223b), TOBN(0xfe47819f, 0x28d3aa25), + TOBN(0x9eea3075, 0xf8dfcf8a), TOBN(0xa284f0aa, 0x95669825), + TOBN(0xb3fca250, 0x867d3fd8), TOBN(0x20757b5f, 0x269d691e), + TOBN(0xf2c24020, 0x93b8a5de), TOBN(0xd3f93359, 0xebc06da6), + TOBN(0x1178293e, 0xb2739c33), TOBN(0xd2a3e770, 0xbcd686e5), + TOBN(0xa76f49f4, 0xcd941534), TOBN(0x0d37406b, 0xe3c71c0e), + TOBN(0x172d9397, 0x3b97f7e3), TOBN(0xec17e239, 0xbd7fd0de), + TOBN(0xe3290551, 0x6f496ba2), TOBN(0x6a693172, 0x36ad50e7), + TOBN(0xc4e539a2, 0x83e7eff5), TOBN(0x752737e7, 0x18e1b4cf), + TOBN(0xa2f7932c, 0x68af43ee), TOBN(0x5502468e, 0x703d00bd), + TOBN(0xe5dc978f, 0x2fb061f5), TOBN(0xc9a1904a, 0x28c815ad), + TOBN(0xd3af538d, 0x470c56a4), TOBN(0x159abc5f, 0x193d8ced), + TOBN(0x2a37245f, 0x20108ef3), TOBN(0xfa17081e, 0x223f7178), + TOBN(0x27b0fb2b, 0x10c8c0f5), TOBN(0x2102c3ea, 0x40650547), + TOBN(0x594564df, 0x8ac3bfa7), TOBN(0x98102033, 0x509dad96), + TOBN(0x6989643f, 0xf1d18a13), TOBN(0x35eebd91, 0xd7fc5af0), + TOBN(0x078d096a, 0xfaeaafd8), TOBN(0xb7a89341, 0xdef3de98), + TOBN(0x2a206e8d, 0xecf2a73a), TOBN(0x066a6397, 0x8e551994), + TOBN(0x3a6a088a, 0xb98d53a2), TOBN(0x0ce7c67c, 0x2d1124aa), + TOBN(0x48cec671, 0x759a113c), TOBN(0xe3b373d3, 0x4f6f67fa), + TOBN(0x5455d479, 0xfd36727b), TOBN(0xe5a428ee, 0xa13c0d81), + TOBN(0xb853dbc8, 0x1c86682b), TOBN(0xb78d2727, 0xb8d02b2a), + TOBN(0xaaf69bed, 0x8ebc329a), TOBN(0xdb6b40b3, 0x293b2148), + TOBN(0xe42ea77d, 0xb8c4961f), TOBN(0xb1a12f7c, 0x20e5e0ab), + TOBN(0xa0ec5274, 0x79e8b05e), TOBN(0x68027391, 0xfab60a80), + TOBN(0x6bfeea5f, 0x16b1bd5e), TOBN(0xf957e420, 0x4de30ad3), + TOBN(0xcbaf664e, 0x6a353b9e), TOBN(0x5c873312, 0x26d14feb), + TOBN(0x4e87f98c, 0xb65f57cb), TOBN(0xdb60a621, 0x5e0cdd41), + TOBN(0x67c16865, 0xa6881440), TOBN(0x1093ef1a, 0x46ab52aa), + TOBN(0xc095afb5, 0x3f4ece64), TOBN(0x6a6bb02e, 0x7604551a), + TOBN(0x55d44b4e, 0x0b26b8cd), TOBN(0xe5f9a999, 0xf971268a), + TOBN(0xc08ec425, 0x11a7de84), TOBN(0x83568095, 0xfda469dd), + TOBN(0x737bfba1, 0x6c6c90a2), TOBN(0x1cb9c4a0, 0xbe229831), + TOBN(0x93bccbba, 0xbb2eec64), TOBN(0xa0c23b64, 0xda03adbe), + TOBN(0x5f7aa00a, 0xe0e86ac4), TOBN(0x470b941e, 0xfc1401e6), + TOBN(0x5ad8d679, 0x9df43574), TOBN(0x4ccfb8a9, 0x0f65d810), + TOBN(0x1bce80e3, 0xaa7fbd81), TOBN(0x273291ad, 0x9508d20a), + TOBN(0xf5c4b46b, 0x42a92806), TOBN(0x810684ec, 0xa86ab44a), + TOBN(0x4591640b, 0xca0bc9f8), TOBN(0xb5efcdfc, 0x5c4b6054), + TOBN(0x16fc8907, 0x6e9edd12), TOBN(0xe29d0b50, 0xd4d792f9), + TOBN(0xa45fd01c, 0x9b03116d), TOBN(0x85035235, 0xc81765a4), + TOBN(0x1fe2a9b2, 0xb4b4b67c), TOBN(0xc1d10df0, 0xe8020604), + TOBN(0x9d64abfc, 0xbc8058d8), TOBN(0x8943b9b2, 0x712a0fbb), + TOBN(0x90eed914, 0x3b3def04), TOBN(0x85ab3aa2, 0x4ce775ff), + TOBN(0x605fd4ca, 0x7bbc9040), TOBN(0x8b34a564, 0xe2c75dfb), + TOBN(0x41ffc94a, 0x10358560), TOBN(0x2d8a5072, 0x9e5c28aa), + TOBN(0xe915a0fc, 0x4cc7eb15), TOBN(0xe9efab05, 0x8f6d0f5d), + TOBN(0xdbab47a9, 0xd19e9b91), TOBN(0x8cfed745, 0x0276154c), + TOBN(0x154357ae, 0x2cfede0d), TOBN(0x520630df, 0x19f5a4ef), + TOBN(0x25759f7c, 0xe382360f), TOBN(0xb6db05c9, 0x88bf5857), + TOBN(0x2917d61d, 0x6c58d46c), TOBN(0x14f8e491, 0xfd20cb7a), + TOBN(0xb68a727a, 0x11c20340), TOBN(0x0386f86f, 0xaf7ccbb6), + TOBN(0x5c8bc6cc, 0xfee09a20), TOBN(0x7d76ff4a, 0xbb7eea35), + TOBN(0xa7bdebe7, 0xdb15be7a), TOBN(0x67a08054, 0xd89f0302), + TOBN(0x56bf0ea9, 0xc1193364), TOBN(0xc8244467, 0x62837ebe), + TOBN(0x32bd8e8b, 0x20d841b8), TOBN(0x127a0548, 0xdbb8a54f), + TOBN(0x83dd4ca6, 0x63b20236), TOBN(0x87714718, 0x203491fa), + TOBN(0x4dabcaaa, 0xaa8a5288), TOBN(0x91cc0c8a, 0xaf23a1c9), + TOBN(0x34c72c6a, 0x3f220e0c), TOBN(0xbcc20bdf, 0x1232144a), + TOBN(0x6e2f42da, 0xa20ede1b), TOBN(0xc441f00c, 0x74a00515), + TOBN(0xbf46a5b6, 0x734b8c4b), TOBN(0x57409503, 0x7b56c9a4), + TOBN(0x9f735261, 0xe4585d45), TOBN(0x9231faed, 0x6734e642), + TOBN(0x1158a176, 0xbe70ee6c), TOBN(0x35f1068d, 0x7c3501bf), + TOBN(0x6beef900, 0xa2d26115), TOBN(0x649406f2, 0xef0afee3), + TOBN(0x3f43a60a, 0xbc2420a1), TOBN(0x509002a7, 0xd5aee4ac), + TOBN(0xb46836a5, 0x3ff3571b), TOBN(0x24f98b78, 0x837927c1), + TOBN(0x6254256a, 0x4533c716), TOBN(0xf27abb0b, 0xd07ee196), + TOBN(0xd7cf64fc, 0x5c6d5bfd), TOBN(0x6915c751, 0xf0cd7a77), + TOBN(0xd9f59012, 0x8798f534), TOBN(0x772b0da8, 0xf81d8b5f), + TOBN(0x1244260c, 0x2e03fa69), TOBN(0x36cf0e3a, 0x3be1a374), + TOBN(0x6e7c1633, 0xef06b960), TOBN(0xa71a4c55, 0x671f90f6), + TOBN(0x7a941251, 0x33c673db), TOBN(0xc0bea510, 0x73e8c131), + TOBN(0x61a8a699, 0xd4f6c734), TOBN(0x25e78c88, 0x341ed001), + TOBN(0x5c18acf8, 0x8e2f7d90), TOBN(0xfdbf33d7, 0x77be32cd), + TOBN(0x0a085cd7, 0xd2eb5ee9), TOBN(0x2d702cfb, 0xb3201115), + TOBN(0xb6e0ebdb, 0x85c88ce8), TOBN(0x23a3ce3c, 0x1e01d617), + TOBN(0x3041618e, 0x567333ac), TOBN(0x9dd0fd8f, 0x157edb6b), + TOBN(0x27f74702, 0xb57872b8), TOBN(0x2ef26b4f, 0x657d5fe1), + TOBN(0x95426f0a, 0x57cf3d40), TOBN(0x847e2ad1, 0x65a6067a), + TOBN(0xd474d9a0, 0x09996a74), TOBN(0x16a56acd, 0x2a26115c), + TOBN(0x02a615c3, 0xd16f4d43), TOBN(0xcc3fc965, 0xaadb85b7), + TOBN(0x386bda73, 0xce07d1b0), TOBN(0xd82910c2, 0x58ad4178), + TOBN(0x124f82cf, 0xcd2617f4), TOBN(0xcc2f5e8d, 0xef691770), + TOBN(0x82702550, 0xb8c30ccc), TOBN(0x7b856aea, 0x1a8e575a), + TOBN(0xbb822fef, 0xb1ab9459), TOBN(0x085928bc, 0xec24e38e), + TOBN(0x5d0402ec, 0xba8f4b4d), TOBN(0xc07cd4ba, 0x00b4d58b), + TOBN(0x5d8dffd5, 0x29227e7a), TOBN(0x61d44d0c, 0x31bf386f), + TOBN(0xe486dc2b, 0x135e6f4d), TOBN(0x680962eb, 0xe79410ef), + TOBN(0xa61bd343, 0xf10088b5), TOBN(0x6aa76076, 0xe2e28686), + TOBN(0x80463d11, 0x8fb98871), TOBN(0xcb26f5c3, 0xbbc76aff), + TOBN(0xd4ab8edd, 0xfbe03614), TOBN(0xc8eb579b, 0xc0cf2dee), + TOBN(0xcc004c15, 0xc93bae41), TOBN(0x46fbae5d, 0x3aeca3b2), + TOBN(0x671235cf, 0x0f1e9ab1), TOBN(0xadfba934, 0x9ec285c1), + TOBN(0x88ded013, 0xf216c980), TOBN(0xc8ac4fb8, 0xf79e0bc1), + TOBN(0xa29b89c6, 0xfb97a237), TOBN(0xb697b780, 0x9922d8e7), + TOBN(0x3142c639, 0xddb945b5), TOBN(0x447b06c7, 0xe094c3a9), + TOBN(0xcdcb3642, 0x72266c90), TOBN(0x633aad08, 0xa9385046), + TOBN(0xa36c936b, 0xb57c6477), TOBN(0x871f8b64, 0xe94dbcc6), + TOBN(0x28d0fb62, 0xa591a67b), TOBN(0x9d40e081, 0xc1d926f5), + TOBN(0x3111eaf6, 0xf2d84b5a), TOBN(0x228993f9, 0xa565b644), + TOBN(0x0ccbf592, 0x2c83188b), TOBN(0xf87b30ab, 0x3df3e197), + TOBN(0xb8658b31, 0x7642bca8), TOBN(0x1a032d7f, 0x52800f17), + TOBN(0x051dcae5, 0x79bf9445), TOBN(0xeba6b8ee, 0x54a2e253), + TOBN(0x5c8b9cad, 0xd4485692), TOBN(0x84bda40e, 0x8986e9be), + TOBN(0xd16d16a4, 0x2f0db448), TOBN(0x8ec80050, 0xa14d4188), + TOBN(0xb2b26107, 0x98fa7aaa), TOBN(0x41209ee4, 0xf073aa4e), + TOBN(0xf1570359, 0xf2d6b19b), TOBN(0xcbe6868c, 0xfc577caf), + TOBN(0x186c4bdc, 0x32c04dd3), TOBN(0xa6c35fae, 0xcfeee397), + TOBN(0xb4a1b312, 0xf086c0cf), TOBN(0xe0a5ccc6, 0xd9461fe2), + TOBN(0xc32278aa, 0x1536189f), TOBN(0x1126c55f, 0xba6df571), + TOBN(0x0f71a602, 0xb194560e), TOBN(0x8b2d7405, 0x324bd6e1), + TOBN(0x8481939e, 0x3738be71), TOBN(0xb5090b1a, 0x1a4d97a9), + TOBN(0x116c65a3, 0xf05ba915), TOBN(0x21863ad3, 0xaae448aa), + TOBN(0xd24e2679, 0xa7aae5d3), TOBN(0x7076013d, 0x0de5c1c4), + TOBN(0x2d50f8ba, 0xbb05b629), TOBN(0x73c1abe2, 0x6e66efbb), + TOBN(0xefd4b422, 0xf2488af7), TOBN(0xe4105d02, 0x663ba575), + TOBN(0x7eb60a8b, 0x53a69457), TOBN(0x62210008, 0xc945973b), + TOBN(0xfb255478, 0x77a50ec6), TOBN(0xbf0392f7, 0x0a37a72c), + TOBN(0xa0a7a19c, 0x4be18e7a), TOBN(0x90d8ea16, 0x25b1e0af), + TOBN(0x7582a293, 0xef953f57), TOBN(0x90a64d05, 0xbdc5465a), + TOBN(0xca79c497, 0xe2510717), TOBN(0x560dbb7c, 0x18cb641f), + TOBN(0x1d8e3286, 0x4b66abfb), TOBN(0xd26f52e5, 0x59030900), + TOBN(0x1ee3f643, 0x5584941a), TOBN(0x6d3b3730, 0x569f5958), + TOBN(0x9ff2a62f, 0x4789dba5), TOBN(0x91fcb815, 0x72b5c9b7), + TOBN(0xf446cb7d, 0x6c8f9a0e), TOBN(0x48f625c1, 0x39b7ecb5), + TOBN(0xbabae801, 0x1c6219b8), TOBN(0xe7a562d9, 0x28ac2f23), + TOBN(0xe1b48732, 0x26e20588), TOBN(0x06ee1cad, 0x775af051), + TOBN(0xda29ae43, 0xfaff79f7), TOBN(0xc141a412, 0x652ee9e0), + TOBN(0x1e127f6f, 0x195f4bd0), TOBN(0x29c6ab4f, 0x072f34f8), + TOBN(0x7b7c1477, 0x30448112), TOBN(0x82b51af1, 0xe4a38656), + TOBN(0x2bf2028a, 0x2f315010), TOBN(0xc9a4a01f, 0x6ea88cd4), + TOBN(0xf63e95d8, 0x257e5818), TOBN(0xdd8efa10, 0xb4519b16), + TOBN(0xed8973e0, 0x0da910bf), TOBN(0xed49d077, 0x5c0fe4a9), + TOBN(0xac3aac5e, 0xb7caee1e), TOBN(0x1033898d, 0xa7f4da57), + TOBN(0x42145c0e, 0x5c6669b9), TOBN(0x42daa688, 0xc1aa2aa0), + TOBN(0x629cc15c, 0x1a1d885a), TOBN(0x25572ec0, 0xf4b76817), + TOBN(0x8312e435, 0x9c8f8f28), TOBN(0x8107f8cd, 0x81965490), + TOBN(0x516ff3a3, 0x6fa6110c), TOBN(0x74fb1eb1, 0xfb93561f), + TOBN(0x6c0c9047, 0x8457522b), TOBN(0xcfd32104, 0x6bb8bdc6), + TOBN(0x2d6884a2, 0xcc80ad57), TOBN(0x7c27fc35, 0x86a9b637), + TOBN(0x3461baed, 0xadf4e8cd), TOBN(0x1d56251a, 0x617242f0), + TOBN(0x0b80d209, 0xc955bef4), TOBN(0xdf02cad2, 0x06adb047), + TOBN(0xf0d7cb91, 0x5ec74fee), TOBN(0xd2503375, 0x1111ba44), + TOBN(0x9671755e, 0xdf53cb36), TOBN(0x54dcb612, 0x3368551b), + TOBN(0x66d69aac, 0xc8a025a4), TOBN(0x6be946c6, 0xe77ef445), + TOBN(0x719946d1, 0xa995e094), TOBN(0x65e848f6, 0xe51e04d8), + TOBN(0xe62f3300, 0x6a1e3113), TOBN(0x1541c7c1, 0x501de503), + TOBN(0x4daac9fa, 0xf4acfade), TOBN(0x0e585897, 0x44cd0b71), + TOBN(0x544fd869, 0x0a51cd77), TOBN(0x60fc20ed, 0x0031016d), + TOBN(0x58b404ec, 0xa4276867), TOBN(0x46f6c3cc, 0x34f34993), + TOBN(0x477ca007, 0xc636e5bd), TOBN(0x8018f5e5, 0x7c458b47), + TOBN(0xa1202270, 0xe47b668f), TOBN(0xcef48ccd, 0xee14f203), + TOBN(0x23f98bae, 0x62ff9b4d), TOBN(0x55acc035, 0xc589eddd), + TOBN(0x3fe712af, 0x64db4444), TOBN(0x19e9d634, 0xbecdd480), + TOBN(0xe08bc047, 0xa930978a), TOBN(0x2dbf24ec, 0xa1280733), + TOBN(0x3c0ae38c, 0x2cd706b2), TOBN(0x5b012a5b, 0x359017b9), + TOBN(0x3943c38c, 0x72e0f5ae), TOBN(0x786167ea, 0x57176fa3), + TOBN(0xe5f9897d, 0x594881dc), TOBN(0x6b5efad8, 0xcfb820c1), + TOBN(0xb2179093, 0xd55018de), TOBN(0x39ad7d32, 0x0bac56ce), + TOBN(0xb55122e0, 0x2cfc0e81), TOBN(0x117c4661, 0xf6d89daa), + TOBN(0x362d01e1, 0xcb64fa09), TOBN(0x6a309b4e, 0x3e9c4ddd), + TOBN(0xfa979fb7, 0xabea49b1), TOBN(0xb4b1d27d, 0x10e2c6c5), + TOBN(0xbd61c2c4, 0x23afde7a), TOBN(0xeb6614f8, 0x9786d358), + TOBN(0x4a5d816b, 0x7f6f7459), TOBN(0xe431a44f, 0x09360e7b), + TOBN(0x8c27a032, 0xc309914c), TOBN(0xcea5d68a, 0xcaede3d8), + TOBN(0x3668f665, 0x3a0a3f95), TOBN(0x89369416, 0x7ceba27b), + TOBN(0x89981fad, 0xe4728fe9), TOBN(0x7102c8a0, 0x8a093562), + TOBN(0xbb80310e, 0x235d21c8), TOBN(0x505e55d1, 0xbefb7f7b), + TOBN(0xa0a90811, 0x12958a67), TOBN(0xd67e106a, 0x4d851fef), + TOBN(0xb84011a9, 0x431dd80e), TOBN(0xeb7c7cca, 0x73306cd9), + TOBN(0x20fadd29, 0xd1b3b730), TOBN(0x83858b5b, 0xfe37b3d3), + TOBN(0xbf4cd193, 0xb6251d5c), TOBN(0x1cca1fd3, 0x1352d952), + TOBN(0xc66157a4, 0x90fbc051), TOBN(0x7990a638, 0x89b98636)}, + {TOBN(0xe5aa692a, 0x87dec0e1), TOBN(0x010ded8d, 0xf7b39d00), + TOBN(0x7b1b80c8, 0x54cfa0b5), TOBN(0x66beb876, 0xa0f8ea28), + TOBN(0x50d7f531, 0x3476cd0e), TOBN(0xa63d0e65, 0xb08d3949), + TOBN(0x1a09eea9, 0x53479fc6), TOBN(0x82ae9891, 0xf499e742), + TOBN(0xab58b910, 0x5ca7d866), TOBN(0x582967e2, 0x3adb3b34), + TOBN(0x89ae4447, 0xcceac0bc), TOBN(0x919c667c, 0x7bf56af5), + TOBN(0x9aec17b1, 0x60f5dcd7), TOBN(0xec697b9f, 0xddcaadbc), + TOBN(0x0b98f341, 0x463467f5), TOBN(0xb187f1f7, 0xa967132f), + TOBN(0x90fe7a1d, 0x214aeb18), TOBN(0x1506af3c, 0x741432f7), + TOBN(0xbb5565f9, 0xe591a0c4), TOBN(0x10d41a77, 0xb44f1bc3), + TOBN(0xa09d65e4, 0xa84bde96), TOBN(0x42f060d8, 0xf20a6a1c), + TOBN(0x652a3bfd, 0xf27f9ce7), TOBN(0xb6bdb65c, 0x3b3d739f), + TOBN(0xeb5ddcb6, 0xec7fae9f), TOBN(0x995f2714, 0xefb66e5a), + TOBN(0xdee95d8e, 0x69445d52), TOBN(0x1b6c2d46, 0x09e27620), + TOBN(0x32621c31, 0x8129d716), TOBN(0xb03909f1, 0x0958c1aa), + TOBN(0x8c468ef9, 0x1af4af63), TOBN(0x162c429f, 0xfba5cdf6), + TOBN(0x2f682343, 0x753b9371), TOBN(0x29cab45a, 0x5f1f9cd7), + TOBN(0x571623ab, 0xb245db96), TOBN(0xc507db09, 0x3fd79999), + TOBN(0x4e2ef652, 0xaf036c32), TOBN(0x86f0cc78, 0x05018e5c), + TOBN(0xc10a73d4, 0xab8be350), TOBN(0x6519b397, 0x7e826327), + TOBN(0xe8cb5eef, 0x9c053df7), TOBN(0x8de25b37, 0xb300ea6f), + TOBN(0xdb03fa92, 0xc849cffb), TOBN(0x242e43a7, 0xe84169bb), + TOBN(0xe4fa51f4, 0xdd6f958e), TOBN(0x6925a77f, 0xf4445a8d), + TOBN(0xe6e72a50, 0xe90d8949), TOBN(0xc66648e3, 0x2b1f6390), + TOBN(0xb2ab1957, 0x173e460c), TOBN(0x1bbbce75, 0x30704590), + TOBN(0xc0a90dbd, 0xdb1c7162), TOBN(0x505e399e, 0x15cdd65d), + TOBN(0x68434dcb, 0x57797ab7), TOBN(0x60ad35ba, 0x6a2ca8e8), + TOBN(0x4bfdb1e0, 0xde3336c1), TOBN(0xbbef99eb, 0xd8b39015), + TOBN(0x6c3b96f3, 0x1711ebec), TOBN(0x2da40f1f, 0xce98fdc4), + TOBN(0xb99774d3, 0x57b4411f), TOBN(0x87c8bdf4, 0x15b65bb6), + TOBN(0xda3a89e3, 0xc2eef12d), TOBN(0xde95bb9b, 0x3c7471f3), + TOBN(0x600f225b, 0xd812c594), TOBN(0x54907c5d, 0x2b75a56b), + TOBN(0xa93cc5f0, 0x8db60e35), TOBN(0x743e3cd6, 0xfa833319), + TOBN(0x7dad5c41, 0xf81683c9), TOBN(0x70c1e7d9, 0x9c34107e), + TOBN(0x0edc4a39, 0xa6be0907), TOBN(0x36d47035, 0x86d0b7d3), + TOBN(0x8c76da03, 0x272bfa60), TOBN(0x0b4a07ea, 0x0f08a414), + TOBN(0x699e4d29, 0x45c1dd53), TOBN(0xcadc5898, 0x231debb5), + TOBN(0xdf49fcc7, 0xa77f00e0), TOBN(0x93057bbf, 0xa73e5a0e), + TOBN(0x2f8b7ecd, 0x027a4cd1), TOBN(0x114734b3, 0xc614011a), + TOBN(0xe7a01db7, 0x67677c68), TOBN(0x89d9be5e, 0x7e273f4f), + TOBN(0xd225cb2e, 0x089808ef), TOBN(0xf1f7a27d, 0xd59e4107), + TOBN(0x53afc761, 0x8211b9c9), TOBN(0x0361bc67, 0xe6819159), + TOBN(0x2a865d0b, 0x7f071426), TOBN(0x6a3c1810, 0xe7072567), + TOBN(0x3e3bca1e, 0x0d6bcabd), TOBN(0xa1b02bc1, 0x408591bc), + TOBN(0xe0deee59, 0x31fba239), TOBN(0xf47424d3, 0x98bd91d1), + TOBN(0x0f8886f4, 0x071a3c1d), TOBN(0x3f7d41e8, 0xa819233b), + TOBN(0x708623c2, 0xcf6eb998), TOBN(0x86bb49af, 0x609a287f), + TOBN(0x942bb249, 0x63c90762), TOBN(0x0ef6eea5, 0x55a9654b), + TOBN(0x5f6d2d72, 0x36f5defe), TOBN(0xfa9922dc, 0x56f99176), + TOBN(0x6c8c5ece, 0xf78ce0c7), TOBN(0x7b44589d, 0xbe09b55e), + TOBN(0xe11b3bca, 0x9ea83770), TOBN(0xd7fa2c7f, 0x2ab71547), + TOBN(0x2a3dd6fa, 0x2a1ddcc0), TOBN(0x09acb430, 0x5a7b7707), + TOBN(0x4add4a2e, 0x649d4e57), TOBN(0xcd53a2b0, 0x1917526e), + TOBN(0xc5262330, 0x20b44ac4), TOBN(0x4028746a, 0xbaa2c31d), + TOBN(0x51318390, 0x64291d4c), TOBN(0xbf48f151, 0xee5ad909), + TOBN(0xcce57f59, 0x7b185681), TOBN(0x7c3ac1b0, 0x4854d442), + TOBN(0x65587dc3, 0xc093c171), TOBN(0xae7acb24, 0x24f42b65), + TOBN(0x5a338adb, 0x955996cb), TOBN(0xc8e65675, 0x6051f91b), + TOBN(0x66711fba, 0x28b8d0b1), TOBN(0x15d74137, 0xb6c10a90), + TOBN(0x70cdd7eb, 0x3a232a80), TOBN(0xc9e2f07f, 0x6191ed24), + TOBN(0xa80d1db6, 0xf79588c0), TOBN(0xfa52fc69, 0xb55768cc), + TOBN(0x0b4df1ae, 0x7f54438a), TOBN(0x0cadd1a7, 0xf9b46a4f), + TOBN(0xb40ea6b3, 0x1803dd6f), TOBN(0x488e4fa5, 0x55eaae35), + TOBN(0x9f047d55, 0x382e4e16), TOBN(0xc9b5b7e0, 0x2f6e0c98), + TOBN(0x6b1bd2d3, 0x95762649), TOBN(0xa9604ee7, 0xc7aea3f6), + TOBN(0x3646ff27, 0x6dc6f896), TOBN(0x9bf0e7f5, 0x2860bad1), + TOBN(0x2d92c821, 0x7cb44b92), TOBN(0xa2f5ce63, 0xaea9c182), + TOBN(0xd0a2afb1, 0x9154a5fd), TOBN(0x482e474c, 0x95801da6), + TOBN(0xc19972d0, 0xb611c24b), TOBN(0x1d468e65, 0x60a8f351), + TOBN(0xeb758069, 0x7bcf6421), TOBN(0xec9dd0ee, 0x88fbc491), + TOBN(0x5b59d2bf, 0x956c2e32), TOBN(0x73dc6864, 0xdcddf94e), + TOBN(0xfd5e2321, 0xbcee7665), TOBN(0xa7b4f8ef, 0x5e9a06c4), + TOBN(0xfba918dd, 0x7280f855), TOBN(0xbbaac260, 0x8baec688), + TOBN(0xa3b3f00f, 0x33400f42), TOBN(0x3d2dba29, 0x66f2e6e4), + TOBN(0xb6f71a94, 0x98509375), TOBN(0x8f33031f, 0xcea423cc), + TOBN(0x009b8dd0, 0x4807e6fb), TOBN(0x5163cfe5, 0x5cdb954c), + TOBN(0x03cc8f17, 0xcf41c6e8), TOBN(0xf1f03c2a, 0x037b925c), + TOBN(0xc39c19cc, 0x66d2427c), TOBN(0x823d24ba, 0x7b6c18e4), + TOBN(0x32ef9013, 0x901f0b4f), TOBN(0x684360f1, 0xf8941c2e), + TOBN(0x0ebaff52, 0x2c28092e), TOBN(0x7891e4e3, 0x256c932f), + TOBN(0x51264319, 0xac445e3d), TOBN(0x553432e7, 0x8ea74381), + TOBN(0xe6eeaa69, 0x67e9c50a), TOBN(0x27ced284, 0x62e628c7), + TOBN(0x3f96d375, 0x7a4afa57), TOBN(0xde0a14c3, 0xe484c150), + TOBN(0x364a24eb, 0x38bd9923), TOBN(0x1df18da0, 0xe5177422), + TOBN(0x174e8f82, 0xd8d38a9b), TOBN(0x2e97c600, 0xe7de1391), + TOBN(0xc5709850, 0xa1c175dd), TOBN(0x969041a0, 0x32ae5035), + TOBN(0xcbfd533b, 0x76a2086b), TOBN(0xd6bba71b, 0xd7c2e8fe), + TOBN(0xb2d58ee6, 0x099dfb67), TOBN(0x3a8b342d, 0x064a85d9), + TOBN(0x3bc07649, 0x522f9be3), TOBN(0x690c075b, 0xdf1f49a8), + TOBN(0x80e1aee8, 0x3854ec42), TOBN(0x2a7dbf44, 0x17689dc7), + TOBN(0xc004fc0e, 0x3faf4078), TOBN(0xb2f02e9e, 0xdf11862c), + TOBN(0xf10a5e0f, 0xa0a1b7b3), TOBN(0x30aca623, 0x8936ec80), + TOBN(0xf83cbf05, 0x02f40d9a), TOBN(0x4681c468, 0x2c318a4d), + TOBN(0x98575618, 0x0e9c2674), TOBN(0xbe79d046, 0x1847092e), + TOBN(0xaf1e480a, 0x78bd01e0), TOBN(0x6dd359e4, 0x72a51db9), + TOBN(0x62ce3821, 0xe3afbab6), TOBN(0xc5cee5b6, 0x17733199), + TOBN(0xe08b30d4, 0x6ffd9fbb), TOBN(0x6e5bc699, 0x36c610b7), + TOBN(0xf343cff2, 0x9ce262cf), TOBN(0xca2e4e35, 0x68b914c1), + TOBN(0x011d64c0, 0x16de36c5), TOBN(0xe0b10fdd, 0x42e2b829), + TOBN(0x78942981, 0x6685aaf8), TOBN(0xe7511708, 0x230ede97), + TOBN(0x671ed8fc, 0x3b922bf8), TOBN(0xe4d8c0a0, 0x4c29b133), + TOBN(0x87eb1239, 0x3b6e99c4), TOBN(0xaff3974c, 0x8793beba), + TOBN(0x03749405, 0x2c18df9b), TOBN(0xc5c3a293, 0x91007139), + TOBN(0x6a77234f, 0xe37a0b95), TOBN(0x02c29a21, 0xb661c96b), + TOBN(0xc3aaf1d6, 0x141ecf61), TOBN(0x9195509e, 0x3bb22f53), + TOBN(0x29597404, 0x22d51357), TOBN(0x1b083822, 0x537bed60), + TOBN(0xcd7d6e35, 0xe07289f0), TOBN(0x1f94c48c, 0x6dd86eff), + TOBN(0xc8bb1f82, 0xeb0f9cfa), TOBN(0x9ee0b7e6, 0x1b2eb97d), + TOBN(0x5a52fe2e, 0x34d74e31), TOBN(0xa352c310, 0x3bf79ab6), + TOBN(0x97ff6c5a, 0xabfeeb8f), TOBN(0xbfbe8fef, 0xf5c97305), + TOBN(0xd6081ce6, 0xa7904608), TOBN(0x1f812f3a, 0xc4fca249), + TOBN(0x9b24bc9a, 0xb9e5e200), TOBN(0x91022c67, 0x38012ee8), + TOBN(0xe83d9c5d, 0x30a713a1), TOBN(0x4876e3f0, 0x84ef0f93), + TOBN(0xc9777029, 0xc1fbf928), TOBN(0xef7a6bb3, 0xbce7d2a4), + TOBN(0xb8067228, 0xdfa2a659), TOBN(0xd5cd3398, 0xd877a48f), + TOBN(0xbea4fd8f, 0x025d0f3f), TOBN(0xd67d2e35, 0x2eae7c2b), + TOBN(0x184de7d7, 0xcc5f4394), TOBN(0xb5551b5c, 0x4536e142), + TOBN(0x2e89b212, 0xd34aa60a), TOBN(0x14a96fea, 0xf50051d5), + TOBN(0x4e21ef74, 0x0d12bb0b), TOBN(0xc522f020, 0x60b9677e), + TOBN(0x8b12e467, 0x2df7731d), TOBN(0x39f80382, 0x7b326d31), + TOBN(0xdfb8630c, 0x39024a94), TOBN(0xaacb96a8, 0x97319452), + TOBN(0xd68a3961, 0xeda3867c), TOBN(0x0c58e2b0, 0x77c4ffca), + TOBN(0x3d545d63, 0x4da919fa), TOBN(0xef79b69a, 0xf15e2289), + TOBN(0x54bc3d3d, 0x808bab10), TOBN(0xc8ab3007, 0x45f82c37), + TOBN(0xc12738b6, 0x7c4a658a), TOBN(0xb3c47639, 0x40e72182), + TOBN(0x3b77be46, 0x8798e44f), TOBN(0xdc047df2, 0x17a7f85f), + TOBN(0x2439d4c5, 0x5e59d92d), TOBN(0xcedca475, 0xe8e64d8d), + TOBN(0xa724cd0d, 0x87ca9b16), TOBN(0x35e4fd59, 0xa5540dfe), + TOBN(0xf8c1ff18, 0xe4bcf6b1), TOBN(0x856d6285, 0x295018fa), + TOBN(0x433f665c, 0x3263c949), TOBN(0xa6a76dd6, 0xa1f21409), + TOBN(0x17d32334, 0xcc7b4f79), TOBN(0xa1d03122, 0x06720e4a), + TOBN(0xadb6661d, 0x81d9bed5), TOBN(0xf0d6fb02, 0x11db15d1), + TOBN(0x7fd11ad5, 0x1fb747d2), TOBN(0xab50f959, 0x3033762b), + TOBN(0x2a7e711b, 0xfbefaf5a), TOBN(0xc7393278, 0x3fef2bbf), + TOBN(0xe29fa244, 0x0df6f9be), TOBN(0x9092757b, 0x71efd215), + TOBN(0xee60e311, 0x4f3d6fd9), TOBN(0x338542d4, 0x0acfb78b), + TOBN(0x44a23f08, 0x38961a0f), TOBN(0x1426eade, 0x986987ca), + TOBN(0x36e6ee2e, 0x4a863cc6), TOBN(0x48059420, 0x628b8b79), + TOBN(0x30303ad8, 0x7396e1de), TOBN(0x5c8bdc48, 0x38c5aad1), + TOBN(0x3e40e11f, 0x5c8f5066), TOBN(0xabd6e768, 0x8d246bbd), + TOBN(0x68aa40bb, 0x23330a01), TOBN(0xd23f5ee4, 0xc34eafa0), + TOBN(0x3bbee315, 0x5de02c21), TOBN(0x18dd4397, 0xd1d8dd06), + TOBN(0x3ba1939a, 0x122d7b44), TOBN(0xe6d3b40a, 0xa33870d6), + TOBN(0x8e620f70, 0x1c4fe3f8), TOBN(0xf6bba1a5, 0xd3a50cbf), + TOBN(0x4a78bde5, 0xcfc0aee0), TOBN(0x847edc46, 0xc08c50bd), + TOBN(0xbaa2439c, 0xad63c9b2), TOBN(0xceb4a728, 0x10fc2acb), + TOBN(0xa419e40e, 0x26da033d), TOBN(0x6cc3889d, 0x03e02683), + TOBN(0x1cd28559, 0xfdccf725), TOBN(0x0fd7e0f1, 0x8d13d208), + TOBN(0x01b9733b, 0x1f0df9d4), TOBN(0x8cc2c5f3, 0xa2b5e4f3), + TOBN(0x43053bfa, 0x3a304fd4), TOBN(0x8e87665c, 0x0a9f1aa7), + TOBN(0x087f29ec, 0xd73dc965), TOBN(0x15ace455, 0x3e9023db), + TOBN(0x2370e309, 0x2bce28b4), TOBN(0xf9723442, 0xb6b1e84a), + TOBN(0xbeee662e, 0xb72d9f26), TOBN(0xb19396de, 0xf0e47109), + TOBN(0x85b1fa73, 0xe13289d0), TOBN(0x436cf77e, 0x54e58e32), + TOBN(0x0ec833b3, 0xe990ef77), TOBN(0x7373e3ed, 0x1b11fc25), + TOBN(0xbe0eda87, 0x0fc332ce), TOBN(0xced04970, 0x8d7ea856), + TOBN(0xf85ff785, 0x7e977ca0), TOBN(0xb66ee8da, 0xdfdd5d2b), + TOBN(0xf5e37950, 0x905af461), TOBN(0x587b9090, 0x966d487c), + TOBN(0x6a198a1b, 0x32ba0127), TOBN(0xa7720e07, 0x141615ac), + TOBN(0xa23f3499, 0x996ef2f2), TOBN(0xef5f64b4, 0x470bcb3d), + TOBN(0xa526a962, 0x92b8c559), TOBN(0x0c14aac0, 0x69740a0f), + TOBN(0x0d41a9e3, 0xa6bdc0a5), TOBN(0x97d52106, 0x9c48aef4), + TOBN(0xcf16bd30, 0x3e7c253b), TOBN(0xcc834b1a, 0x47fdedc1), + TOBN(0x7362c6e5, 0x373aab2e), TOBN(0x264ed85e, 0xc5f590ff), + TOBN(0x7a46d9c0, 0x66d41870), TOBN(0xa50c20b1, 0x4787ba09), + TOBN(0x185e7e51, 0xe3d44635), TOBN(0xb3b3e080, 0x31e2d8dc), + TOBN(0xbed1e558, 0xa179e9d9), TOBN(0x2daa3f79, 0x74a76781), + TOBN(0x4372baf2, 0x3a40864f), TOBN(0x46900c54, 0x4fe75cb5), + TOBN(0xb95f171e, 0xf76765d0), TOBN(0x4ad726d2, 0x95c87502), + TOBN(0x2ec769da, 0x4d7c99bd), TOBN(0x5e2ddd19, 0xc36cdfa8), + TOBN(0xc22117fc, 0xa93e6dea), TOBN(0xe8a2583b, 0x93771123), + TOBN(0xbe2f6089, 0xfa08a3a2), TOBN(0x4809d5ed, 0x8f0e1112), + TOBN(0x3b414aa3, 0xda7a095e), TOBN(0x9049acf1, 0x26f5aadd), + TOBN(0x78d46a4d, 0x6be8b84a), TOBN(0xd66b1963, 0xb732b9b3), + TOBN(0x5c2ac2a0, 0xde6e9555), TOBN(0xcf52d098, 0xb5bd8770), + TOBN(0x15a15fa6, 0x0fd28921), TOBN(0x56ccb81e, 0x8b27536d), + TOBN(0x0f0d8ab8, 0x9f4ccbb8), TOBN(0xed5f44d2, 0xdb221729), + TOBN(0x43141988, 0x00bed10c), TOBN(0xc94348a4, 0x1d735b8b), + TOBN(0x79f3e9c4, 0x29ef8479), TOBN(0x4c13a4e3, 0x614c693f), + TOBN(0x32c9af56, 0x8e143a14), TOBN(0xbc517799, 0xe29ac5c4), + TOBN(0x05e17992, 0x2774856f), TOBN(0x6e52fb05, 0x6c1bf55f), + TOBN(0xaeda4225, 0xe4f19e16), TOBN(0x70f4728a, 0xaf5ccb26), + TOBN(0x5d2118d1, 0xb2947f22), TOBN(0xc827ea16, 0x281d6fb9), + TOBN(0x8412328d, 0x8cf0eabd), TOBN(0x45ee9fb2, 0x03ef9dcf), + TOBN(0x8e700421, 0xbb937d63), TOBN(0xdf8ff2d5, 0xcc4b37a6), + TOBN(0xa4c0d5b2, 0x5ced7b68), TOBN(0x6537c1ef, 0xc7308f59), + TOBN(0x25ce6a26, 0x3b37f8e8), TOBN(0x170e9a9b, 0xdeebc6ce), + TOBN(0xdd037952, 0x8728d72c), TOBN(0x445b0e55, 0x850154bc), + TOBN(0x4b7d0e06, 0x83a7337b), TOBN(0x1e3416d4, 0xffecf249), + TOBN(0x24840eff, 0x66a2b71f), TOBN(0xd0d9a50a, 0xb37cc26d), + TOBN(0xe2198150, 0x6fe28ef7), TOBN(0x3cc5ef16, 0x23324c7f), + TOBN(0x220f3455, 0x769b5263), TOBN(0xe2ade2f1, 0xa10bf475), + TOBN(0x28cd20fa, 0x458d3671), TOBN(0x1549722c, 0x2dc4847b), + TOBN(0x6dd01e55, 0x591941e3), TOBN(0x0e6fbcea, 0x27128ccb), + TOBN(0xae1a1e6b, 0x3bef0262), TOBN(0xfa8c472c, 0x8f54e103), + TOBN(0x7539c0a8, 0x72c052ec), TOBN(0xd7b27369, 0x5a3490e9), + TOBN(0x143fe1f1, 0x71684349), TOBN(0x36b4722e, 0x32e19b97), + TOBN(0xdc059227, 0x90980aff), TOBN(0x175c9c88, 0x9e13d674), + TOBN(0xa7de5b22, 0x6e6bfdb1), TOBN(0x5ea5b7b2, 0xbedb4b46), + TOBN(0xd5570191, 0xd34a6e44), TOBN(0xfcf60d2e, 0xa24ff7e6), + TOBN(0x614a392d, 0x677819e1), TOBN(0x7be74c7e, 0xaa5a29e8), + TOBN(0xab50fece, 0x63c85f3f), TOBN(0xaca2e2a9, 0x46cab337), + TOBN(0x7f700388, 0x122a6fe3), TOBN(0xdb69f703, 0x882a04a8), + TOBN(0x9a77935d, 0xcf7aed57), TOBN(0xdf16207c, 0x8d91c86f), + TOBN(0x2fca49ab, 0x63ed9998), TOBN(0xa3125c44, 0xa77ddf96), + TOBN(0x05dd8a86, 0x24344072), TOBN(0xa023dda2, 0xfec3fb56), + TOBN(0x421b41fc, 0x0c743032), TOBN(0x4f2120c1, 0x5e438639), + TOBN(0xfb7cae51, 0xc83c1b07), TOBN(0xb2370caa, 0xcac2171a), + TOBN(0x2eb2d962, 0x6cc820fb), TOBN(0x59feee5c, 0xb85a44bf), + TOBN(0x94620fca, 0x5b6598f0), TOBN(0x6b922cae, 0x7e314051), + TOBN(0xff8745ad, 0x106bed4e), TOBN(0x546e71f5, 0xdfa1e9ab), + TOBN(0x935c1e48, 0x1ec29487), TOBN(0x9509216c, 0x4d936530), + TOBN(0xc7ca3067, 0x85c9a2db), TOBN(0xd6ae5152, 0x6be8606f), + TOBN(0x09dbcae6, 0xe14c651d), TOBN(0xc9536e23, 0x9bc32f96), + TOBN(0xa90535a9, 0x34521b03), TOBN(0xf39c526c, 0x878756ff), + TOBN(0x383172ec, 0x8aedf03c), TOBN(0x20a8075e, 0xefe0c034), + TOBN(0xf22f9c62, 0x64026422), TOBN(0x8dd10780, 0x24b9d076), + TOBN(0x944c742a, 0x3bef2950), TOBN(0x55b9502e, 0x88a2b00b), + TOBN(0xa59e14b4, 0x86a09817), TOBN(0xa39dd3ac, 0x47bb4071), + TOBN(0x55137f66, 0x3be0592f), TOBN(0x07fcafd4, 0xc9e63f5b), + TOBN(0x963652ee, 0x346eb226), TOBN(0x7dfab085, 0xec2facb7), + TOBN(0x273bf2b8, 0x691add26), TOBN(0x30d74540, 0xf2b46c44), + TOBN(0x05e8e73e, 0xf2c2d065), TOBN(0xff9b8a00, 0xd42eeac9), + TOBN(0x2fcbd205, 0x97209d22), TOBN(0xeb740ffa, 0xde14ea2c), + TOBN(0xc71ff913, 0xa8aef518), TOBN(0x7bfc74bb, 0xfff4cfa2), + TOBN(0x1716680c, 0xb6b36048), TOBN(0x121b2cce, 0x9ef79af1), + TOBN(0xbff3c836, 0xa01eb3d3), TOBN(0x50eb1c6a, 0x5f79077b), + TOBN(0xa48c32d6, 0xa004bbcf), TOBN(0x47a59316, 0x7d64f61d), + TOBN(0x6068147f, 0x93102016), TOBN(0x12c5f654, 0x94d12576), + TOBN(0xefb071a7, 0xc9bc6b91), TOBN(0x7c2da0c5, 0x6e23ea95), + TOBN(0xf4fd45b6, 0xd4a1dd5d), TOBN(0x3e7ad9b6, 0x9122b13c), + TOBN(0x342ca118, 0xe6f57a48), TOBN(0x1c2e94a7, 0x06f8288f), + TOBN(0x99e68f07, 0x5a97d231), TOBN(0x7c80de97, 0x4d838758), + TOBN(0xbce0f5d0, 0x05872727), TOBN(0xbe5d95c2, 0x19c4d016), + TOBN(0x921d5cb1, 0x9c2492ee), TOBN(0x42192dc1, 0x404d6fb3), + TOBN(0x4c84dcd1, 0x32f988d3), TOBN(0xde26d61f, 0xa17b8e85), + TOBN(0xc466dcb6, 0x137c7408), TOBN(0x9a38d7b6, 0x36a266da), + TOBN(0x7ef5cb06, 0x83bebf1b), TOBN(0xe5cdcbbf, 0x0fd014e3), + TOBN(0x30aa376d, 0xf65965a0), TOBN(0x60fe88c2, 0xebb3e95e), + TOBN(0x33fd0b61, 0x66ee6f20), TOBN(0x8827dcdb, 0x3f41f0a0), + TOBN(0xbf8a9d24, 0x0c56c690), TOBN(0x40265dad, 0xddb7641d), + TOBN(0x522b05bf, 0x3a6b662b), TOBN(0x466d1dfe, 0xb1478c9b), + TOBN(0xaa616962, 0x1484469b), TOBN(0x0db60549, 0x02df8f9f), + TOBN(0xc37bca02, 0x3cb8bf51), TOBN(0x5effe346, 0x21371ce8), + TOBN(0xe8f65264, 0xff112c32), TOBN(0x8a9c736d, 0x7b971fb2), + TOBN(0xa4f19470, 0x7b75080d), TOBN(0xfc3f2c5a, 0x8839c59b), + TOBN(0x1d6c777e, 0x5aeb49c2), TOBN(0xf3db034d, 0xda1addfe), + TOBN(0xd76fee5a, 0x5535affc), TOBN(0x0853ac70, 0xb92251fd), + TOBN(0x37e3d594, 0x8b2a29d5), TOBN(0x28f1f457, 0x4de00ddb), + TOBN(0x8083c1b5, 0xf42c328b), TOBN(0xd8ef1d8f, 0xe493c73b), + TOBN(0x96fb6260, 0x41dc61bd), TOBN(0xf74e8a9d, 0x27ee2f8a), + TOBN(0x7c605a80, 0x2c946a5d), TOBN(0xeed48d65, 0x3839ccfd), + TOBN(0x9894344f, 0x3a29467a), TOBN(0xde81e949, 0xc51eba6d), + TOBN(0xdaea066b, 0xa5e5c2f2), TOBN(0x3fc8a614, 0x08c8c7b3), + TOBN(0x7adff88f, 0x06d0de9f), TOBN(0xbbc11cf5, 0x3b75ce0a), + TOBN(0x9fbb7acc, 0xfbbc87d5), TOBN(0xa1458e26, 0x7badfde2)}, + {TOBN(0x1cb43668, 0xe039c256), TOBN(0x5f26fb8b, 0x7c17fd5d), + TOBN(0xeee426af, 0x79aa062b), TOBN(0x072002d0, 0xd78fbf04), + TOBN(0x4c9ca237, 0xe84fb7e3), TOBN(0xb401d8a1, 0x0c82133d), + TOBN(0xaaa52592, 0x6d7e4181), TOBN(0xe9430833, 0x73dbb152), + TOBN(0xf92dda31, 0xbe24319a), TOBN(0x03f7d28b, 0xe095a8e7), + TOBN(0xa52fe840, 0x98782185), TOBN(0x276ddafe, 0x29c24dbc), + TOBN(0x80cd5496, 0x1d7a64eb), TOBN(0xe4360889, 0x7f1dbe42), + TOBN(0x2f81a877, 0x8438d2d5), TOBN(0x7e4d52a8, 0x85169036), + TOBN(0x19e3d5b1, 0x1d59715d), TOBN(0xc7eaa762, 0xd788983e), + TOBN(0xe5a730b0, 0xabf1f248), TOBN(0xfbab8084, 0xfae3fd83), + TOBN(0x65e50d21, 0x53765b2f), TOBN(0xbdd4e083, 0xfa127f3d), + TOBN(0x9cf3c074, 0x397b1b10), TOBN(0x59f8090c, 0xb1b59fd3), + TOBN(0x7b15fd9d, 0x615faa8f), TOBN(0x8fa1eb40, 0x968554ed), + TOBN(0x7bb4447e, 0x7aa44882), TOBN(0x2bb2d0d1, 0x029fff32), + TOBN(0x075e2a64, 0x6caa6d2f), TOBN(0x8eb879de, 0x22e7351b), + TOBN(0xbcd5624e, 0x9a506c62), TOBN(0x218eaef0, 0xa87e24dc), + TOBN(0x37e56847, 0x44ddfa35), TOBN(0x9ccfc5c5, 0xdab3f747), + TOBN(0x9ac1df3f, 0x1ee96cf4), TOBN(0x0c0571a1, 0x3b480b8f), + TOBN(0x2fbeb3d5, 0x4b3a7b3c), TOBN(0x35c03669, 0x5dcdbb99), + TOBN(0x52a0f5dc, 0xb2415b3a), TOBN(0xd57759b4, 0x4413ed9a), + TOBN(0x1fe647d8, 0x3d30a2c5), TOBN(0x0857f77e, 0xf78a81dc), + TOBN(0x11d5a334, 0x131a4a9b), TOBN(0xc0a94af9, 0x29d393f5), + TOBN(0xbc3a5c0b, 0xdaa6ec1a), TOBN(0xba9fe493, 0x88d2d7ed), + TOBN(0xbb4335b4, 0xbb614797), TOBN(0x991c4d68, 0x72f83533), + TOBN(0x53258c28, 0xd2f01cb3), TOBN(0x93d6eaa3, 0xd75db0b1), + TOBN(0x419a2b0d, 0xe87d0db4), TOBN(0xa1e48f03, 0xd8fe8493), + TOBN(0xf747faf6, 0xc508b23a), TOBN(0xf137571a, 0x35d53549), + TOBN(0x9f5e58e2, 0xfcf9b838), TOBN(0xc7186cee, 0xa7fd3cf5), + TOBN(0x77b868ce, 0xe978a1d3), TOBN(0xe3a68b33, 0x7ab92d04), + TOBN(0x51029794, 0x87a5b862), TOBN(0x5f0606c3, 0x3a61d41d), + TOBN(0x2814be27, 0x6f9326f1), TOBN(0x2f521c14, 0xc6fe3c2e), + TOBN(0x17464d7d, 0xacdf7351), TOBN(0x10f5f9d3, 0x777f7e44), + TOBN(0xce8e616b, 0x269fb37d), TOBN(0xaaf73804, 0x7de62de5), + TOBN(0xaba11175, 0x4fdd4153), TOBN(0x515759ba, 0x3770b49b), + TOBN(0x8b09ebf8, 0xaa423a61), TOBN(0x592245a1, 0xcd41fb92), + TOBN(0x1cba8ec1, 0x9b4c8936), TOBN(0xa87e91e3, 0xaf36710e), + TOBN(0x1fd84ce4, 0x3d34a2e3), TOBN(0xee3759ce, 0xb43b5d61), + TOBN(0x895bc78c, 0x619186c7), TOBN(0xf19c3809, 0xcbb9725a), + TOBN(0xc0be21aa, 0xde744b1f), TOBN(0xa7d222b0, 0x60f8056b), + TOBN(0x74be6157, 0xb23efe11), TOBN(0x6fab2b4f, 0x0cd68253), + TOBN(0xad33ea5f, 0x4bf1d725), TOBN(0x9c1d8ee2, 0x4f6c950f), + TOBN(0x544ee78a, 0xa377af06), TOBN(0x54f489bb, 0x94a113e1), + TOBN(0x8f11d634, 0x992fb7e8), TOBN(0x0169a7aa, 0xa2a44347), + TOBN(0x1d49d4af, 0x95020e00), TOBN(0x95945722, 0xe08e120b), + TOBN(0xb6e33878, 0xa4d32282), TOBN(0xe36e029d, 0x48020ae7), + TOBN(0xe05847fb, 0x37a9b750), TOBN(0xf876812c, 0xb29e3819), + TOBN(0x84ad138e, 0xd23a17f0), TOBN(0x6d7b4480, 0xf0b3950e), + TOBN(0xdfa8aef4, 0x2fd67ae0), TOBN(0x8d3eea24, 0x52333af6), + TOBN(0x0d052075, 0xb15d5acc), TOBN(0xc6d9c79f, 0xbd815bc4), + TOBN(0x8dcafd88, 0xdfa36cf2), TOBN(0x908ccbe2, 0x38aa9070), + TOBN(0x638722c4, 0xba35afce), TOBN(0x5a3da8b0, 0xfd6abf0b), + TOBN(0x2dce252c, 0xc9c335c1), TOBN(0x84e7f0de, 0x65aa799b), + TOBN(0x2101a522, 0xb99a72cb), TOBN(0x06de6e67, 0x87618016), + TOBN(0x5ff8c7cd, 0xe6f3653e), TOBN(0x0a821ab5, 0xc7a6754a), + TOBN(0x7e3fa52b, 0x7cb0b5a2), TOBN(0xa7fb121c, 0xc9048790), + TOBN(0x1a725020, 0x06ce053a), TOBN(0xb490a31f, 0x04e929b0), + TOBN(0xe17be47d, 0x62dd61ad), TOBN(0x781a961c, 0x6be01371), + TOBN(0x1063bfd3, 0xdae3cbba), TOBN(0x35647406, 0x7f73c9ba), + TOBN(0xf50e957b, 0x2736a129), TOBN(0xa6313702, 0xed13f256), + TOBN(0x9436ee65, 0x3a19fcc5), TOBN(0xcf2bdb29, 0xe7a4c8b6), + TOBN(0xb06b1244, 0xc5f95cd8), TOBN(0xda8c8af0, 0xf4ab95f4), + TOBN(0x1bae59c2, 0xb9e5836d), TOBN(0x07d51e7e, 0x3acffffc), + TOBN(0x01e15e6a, 0xc2ccbcda), TOBN(0x3bc1923f, 0x8528c3e0), + TOBN(0x43324577, 0xa49fead4), TOBN(0x61a1b884, 0x2aa7a711), + TOBN(0xf9a86e08, 0x700230ef), TOBN(0x0af585a1, 0xbd19adf8), + TOBN(0x7645f361, 0xf55ad8f2), TOBN(0x6e676223, 0x46c3614c), + TOBN(0x23cb257c, 0x4e774d3f), TOBN(0x82a38513, 0xac102d1b), + TOBN(0x9bcddd88, 0x7b126aa5), TOBN(0xe716998b, 0xeefd3ee4), + TOBN(0x4239d571, 0xfb167583), TOBN(0xdd011c78, 0xd16c8f8a), + TOBN(0x271c2895, 0x69a27519), TOBN(0x9ce0a3b7, 0xd2d64b6a), + TOBN(0x8c977289, 0xd5ec6738), TOBN(0xa3b49f9a, 0x8840ef6b), + TOBN(0x808c14c9, 0x9a453419), TOBN(0x5c00295b, 0x0cf0a2d5), + TOBN(0x524414fb, 0x1d4bcc76), TOBN(0xb07691d2, 0x459a88f1), + TOBN(0x77f43263, 0xf70d110f), TOBN(0x64ada5e0, 0xb7abf9f3), + TOBN(0xafd0f94e, 0x5b544cf5), TOBN(0xb4a13a15, 0xfd2713fe), + TOBN(0xb99b7d6e, 0x250c74f4), TOBN(0x097f2f73, 0x20324e45), + TOBN(0x994b37d8, 0xaffa8208), TOBN(0xc3c31b0b, 0xdc29aafc), + TOBN(0x3da74651, 0x7a3a607f), TOBN(0xd8e1b8c1, 0xfe6955d6), + TOBN(0x716e1815, 0xc8418682), TOBN(0x541d487f, 0x7dc91d97), + TOBN(0x48a04669, 0xc6996982), TOBN(0xf39cab15, 0x83a6502e), + TOBN(0x025801a0, 0xe68db055), TOBN(0xf3569758, 0xba3338d5), + TOBN(0xb0c8c0aa, 0xee2afa84), TOBN(0x4f6985d3, 0xfb6562d1), + TOBN(0x351f1f15, 0x132ed17a), TOBN(0x510ed0b4, 0xc04365fe), + TOBN(0xa3f98138, 0xe5b1f066), TOBN(0xbc9d95d6, 0x32df03dc), + TOBN(0xa83ccf6e, 0x19abd09e), TOBN(0x0b4097c1, 0x4ff17edb), + TOBN(0x58a5c478, 0xd64a06ce), TOBN(0x2ddcc3fd, 0x544a58fd), + TOBN(0xd449503d, 0x9e8153b8), TOBN(0x3324fd02, 0x7774179b), + TOBN(0xaf5d47c8, 0xdbd9120c), TOBN(0xeb860162, 0x34fa94db), + TOBN(0x5817bdd1, 0x972f07f4), TOBN(0xe5579e2e, 0xd27bbceb), + TOBN(0x86847a1f, 0x5f11e5a6), TOBN(0xb39ed255, 0x7c3cf048), + TOBN(0xe1076417, 0xa2f62e55), TOBN(0x6b9ab38f, 0x1bcf82a2), + TOBN(0x4bb7c319, 0x7aeb29f9), TOBN(0xf6d17da3, 0x17227a46), + TOBN(0xab53ddbd, 0x0f968c00), TOBN(0xa03da7ec, 0x000c880b), + TOBN(0x7b239624, 0x6a9ad24d), TOBN(0x612c0401, 0x01ec60d0), + TOBN(0x70d10493, 0x109f5df1), TOBN(0xfbda4030, 0x80af7550), + TOBN(0x30b93f95, 0xc6b9a9b3), TOBN(0x0c74ec71, 0x007d9418), + TOBN(0x94175564, 0x6edb951f), TOBN(0x5f4a9d78, 0x7f22c282), + TOBN(0xb7870895, 0xb38d1196), TOBN(0xbc593df3, 0xa228ce7c), + TOBN(0xc78c5bd4, 0x6af3641a), TOBN(0x7802200b, 0x3d9b3dcc), + TOBN(0x0dc73f32, 0x8be33304), TOBN(0x847ed87d, 0x61ffb79a), + TOBN(0xf85c974e, 0x6d671192), TOBN(0x1e14100a, 0xde16f60f), + TOBN(0x45cb0d5a, 0x95c38797), TOBN(0x18923bba, 0x9b022da4), + TOBN(0xef2be899, 0xbbe7e86e), TOBN(0x4a1510ee, 0x216067bf), + TOBN(0xd98c8154, 0x84d5ce3e), TOBN(0x1af777f0, 0xf92a2b90), + TOBN(0x9fbcb400, 0x4ef65724), TOBN(0x3e04a4c9, 0x3c0ca6fe), + TOBN(0xfb3e2cb5, 0x55002994), TOBN(0x1f3a93c5, 0x5363ecab), + TOBN(0x1fe00efe, 0x3923555b), TOBN(0x744bedd9, 0x1e1751ea), + TOBN(0x3fb2db59, 0x6ab69357), TOBN(0x8dbd7365, 0xf5e6618b), + TOBN(0x99d53099, 0xdf1ea40e), TOBN(0xb3f24a0b, 0x57d61e64), + TOBN(0xd088a198, 0x596eb812), TOBN(0x22c8361b, 0x5762940b), + TOBN(0x66f01f97, 0xf9c0d95c), TOBN(0x88461172, 0x8e43cdae), + TOBN(0x11599a7f, 0xb72b15c3), TOBN(0x135a7536, 0x420d95cc), + TOBN(0x2dcdf0f7, 0x5f7ae2f6), TOBN(0x15fc6e1d, 0xd7fa6da2), + TOBN(0x81ca829a, 0xd1d441b6), TOBN(0x84c10cf8, 0x04a106b6), + TOBN(0xa9b26c95, 0xa73fbbd0), TOBN(0x7f24e0cb, 0x4d8f6ee8), + TOBN(0x48b45937, 0x1e25a043), TOBN(0xf8a74fca, 0x036f3dfe), + TOBN(0x1ed46585, 0xc9f84296), TOBN(0x7fbaa8fb, 0x3bc278b0), + TOBN(0xa8e96cd4, 0x6c4fcbd0), TOBN(0x940a1202, 0x73b60a5f), + TOBN(0x34aae120, 0x55a4aec8), TOBN(0x550e9a74, 0xdbd742f0), + TOBN(0x794456d7, 0x228c68ab), TOBN(0x492f8868, 0xa4e25ec6), + TOBN(0x682915ad, 0xb2d8f398), TOBN(0xf13b51cc, 0x5b84c953), + TOBN(0xcda90ab8, 0x5bb917d6), TOBN(0x4b615560, 0x4ea3dee1), + TOBN(0x578b4e85, 0x0a52c1c8), TOBN(0xeab1a695, 0x20b75fc4), + TOBN(0x60c14f3c, 0xaa0bb3c6), TOBN(0x220f448a, 0xb8216094), + TOBN(0x4fe7ee31, 0xb0e63d34), TOBN(0xf4600572, 0xa9e54fab), + TOBN(0xc0493334, 0xd5e7b5a4), TOBN(0x8589fb92, 0x06d54831), + TOBN(0xaa70f5cc, 0x6583553a), TOBN(0x0879094a, 0xe25649e5), + TOBN(0xcc904507, 0x10044652), TOBN(0xebb0696d, 0x02541c4f), + TOBN(0x5a171fde, 0xb9718710), TOBN(0x38f1bed8, 0xf374a9f5), + TOBN(0xc8c582e1, 0xba39bdc1), TOBN(0xfc457b0a, 0x908cc0ce), + TOBN(0x9a187fd4, 0x883841e2), TOBN(0x8ec25b39, 0x38725381), + TOBN(0x2553ed05, 0x96f84395), TOBN(0x095c7661, 0x6f6c6897), + TOBN(0x917ac85c, 0x4bdc5610), TOBN(0xb2885fe4, 0x179eb301), + TOBN(0x5fc65547, 0x8b78bdcc), TOBN(0x4a9fc893, 0xe59e4699), + TOBN(0xbb7ff0cd, 0x3ce299af), TOBN(0x195be9b3, 0xadf38b20), + TOBN(0x6a929c87, 0xd38ddb8f), TOBN(0x55fcc99c, 0xb21a51b9), + TOBN(0x2b695b4c, 0x721a4593), TOBN(0xed1e9a15, 0x768eaac2), + TOBN(0xfb63d71c, 0x7489f914), TOBN(0xf98ba31c, 0x78118910), + TOBN(0x80291373, 0x9b128eb4), TOBN(0x7801214e, 0xd448af4a), + TOBN(0xdbd2e22b, 0x55418dd3), TOBN(0xeffb3c0d, 0xd3998242), + TOBN(0xdfa6077c, 0xc7bf3827), TOBN(0xf2165bcb, 0x47f8238f), + TOBN(0xfe37cf68, 0x8564d554), TOBN(0xe5f825c4, 0x0a81fb98), + TOBN(0x43cc4f67, 0xffed4d6f), TOBN(0xbc609578, 0xb50a34b0), + TOBN(0x8aa8fcf9, 0x5041faf1), TOBN(0x5659f053, 0x651773b6), + TOBN(0xe87582c3, 0x6044d63b), TOBN(0xa6089409, 0x0cdb0ca0), + TOBN(0x8c993e0f, 0xbfb2bcf6), TOBN(0xfc64a719, 0x45985cfc), + TOBN(0x15c4da80, 0x83dbedba), TOBN(0x804ae112, 0x2be67df7), + TOBN(0xda4c9658, 0xa23defde), TOBN(0x12002ddd, 0x5156e0d3), + TOBN(0xe68eae89, 0x5dd21b96), TOBN(0x8b99f28b, 0xcf44624d), + TOBN(0x0ae00808, 0x1ec8897a), TOBN(0xdd0a9303, 0x6712f76e), + TOBN(0x96237522, 0x4e233de4), TOBN(0x192445b1, 0x2b36a8a5), + TOBN(0xabf9ff74, 0x023993d9), TOBN(0x21f37bf4, 0x2aad4a8f), + TOBN(0x340a4349, 0xf8bd2bbd), TOBN(0x1d902cd9, 0x4868195d), + TOBN(0x3d27bbf1, 0xe5fdb6f1), TOBN(0x7a5ab088, 0x124f9f1c), + TOBN(0xc466ab06, 0xf7a09e03), TOBN(0x2f8a1977, 0x31f2c123), + TOBN(0xda355dc7, 0x041b6657), TOBN(0xcb840d12, 0x8ece2a7c), + TOBN(0xb600ad9f, 0x7db32675), TOBN(0x78fea133, 0x07a06f1b), + TOBN(0x5d032269, 0xb31f6094), TOBN(0x07753ef5, 0x83ec37aa), + TOBN(0x03485aed, 0x9c0bea78), TOBN(0x41bb3989, 0xbc3f4524), + TOBN(0x09403761, 0x697f726d), TOBN(0x6109beb3, 0xdf394820), + TOBN(0x804111ea, 0x3b6d1145), TOBN(0xb6271ea9, 0xa8582654), + TOBN(0x619615e6, 0x24e66562), TOBN(0xa2554945, 0xd7b6ad9c), + TOBN(0xd9c4985e, 0x99bfe35f), TOBN(0x9770ccc0, 0x7b51cdf6), + TOBN(0x7c327013, 0x92881832), TOBN(0x8777d45f, 0x286b26d1), + TOBN(0x9bbeda22, 0xd847999d), TOBN(0x03aa33b6, 0xc3525d32), + TOBN(0x4b7b96d4, 0x28a959a1), TOBN(0xbb3786e5, 0x31e5d234), + TOBN(0xaeb5d3ce, 0x6961f247), TOBN(0x20aa85af, 0x02f93d3f), + TOBN(0x9cd1ad3d, 0xd7a7ae4f), TOBN(0xbf6688f0, 0x781adaa8), + TOBN(0xb1b40e86, 0x7469cead), TOBN(0x1904c524, 0x309fca48), + TOBN(0x9b7312af, 0x4b54bbc7), TOBN(0xbe24bf8f, 0x593affa2), + TOBN(0xbe5e0790, 0xbd98764b), TOBN(0xa0f45f17, 0xa26e299e), + TOBN(0x4af0d2c2, 0x6b8fe4c7), TOBN(0xef170db1, 0x8ae8a3e6), + TOBN(0x0e8d61a0, 0x29e0ccc1), TOBN(0xcd53e87e, 0x60ad36ca), + TOBN(0x328c6623, 0xc8173822), TOBN(0x7ee1767d, 0xa496be55), + TOBN(0x89f13259, 0x648945af), TOBN(0x9e45a5fd, 0x25c8009c), + TOBN(0xaf2febd9, 0x1f61ab8c), TOBN(0x43f6bc86, 0x8a275385), + TOBN(0x87792348, 0xf2142e79), TOBN(0x17d89259, 0xc6e6238a), + TOBN(0x7536d2f6, 0x4a839d9b), TOBN(0x1f428fce, 0x76a1fbdc), + TOBN(0x1c109601, 0x0db06dfe), TOBN(0xbfc16bc1, 0x50a3a3cc), + TOBN(0xf9cbd9ec, 0x9b30f41b), TOBN(0x5b5da0d6, 0x00138cce), + TOBN(0xec1d0a48, 0x56ef96a7), TOBN(0xb47eb848, 0x982bf842), + TOBN(0x66deae32, 0xec3f700d), TOBN(0x4e43c42c, 0xaa1181e0), + TOBN(0xa1d72a31, 0xd1a4aa2a), TOBN(0x440d4668, 0xc004f3ce), + TOBN(0x0d6a2d3b, 0x45fe8a7a), TOBN(0x820e52e2, 0xfb128365), + TOBN(0x29ac5fcf, 0x25e51b09), TOBN(0x180cd2bf, 0x2023d159), + TOBN(0xa9892171, 0xa1ebf90e), TOBN(0xf97c4c87, 0x7c132181), + TOBN(0x9f1dc724, 0xc03dbb7e), TOBN(0xae043765, 0x018cbbe4), + TOBN(0xfb0b2a36, 0x0767d153), TOBN(0xa8e2f4d6, 0x249cbaeb), + TOBN(0x172a5247, 0xd95ea168), TOBN(0x1758fada, 0x2970764a), + TOBN(0xac803a51, 0x1d978169), TOBN(0x299cfe2e, 0xde77e01b), + TOBN(0x652a1e17, 0xb0a98927), TOBN(0x2e26e1d1, 0x20014495), + TOBN(0x7ae0af9f, 0x7175b56a), TOBN(0xc2e22a80, 0xd64b9f95), + TOBN(0x4d0ff9fb, 0xd90a060a), TOBN(0x496a27db, 0xbaf38085), + TOBN(0x32305401, 0xda776bcf), TOBN(0xb8cdcef6, 0x725f209e), + TOBN(0x61ba0f37, 0x436a0bba), TOBN(0x263fa108, 0x76860049), + TOBN(0x92beb98e, 0xda3542cf), TOBN(0xa2d4d14a, 0xd5849538), + TOBN(0x989b9d68, 0x12e9a1bc), TOBN(0x61d9075c, 0x5f6e3268), + TOBN(0x352c6aa9, 0x99ace638), TOBN(0xde4e4a55, 0x920f43ff), + TOBN(0xe5e4144a, 0xd673c017), TOBN(0x667417ae, 0x6f6e05ea), + TOBN(0x613416ae, 0xdcd1bd56), TOBN(0x5eb36201, 0x86693711), + TOBN(0x2d7bc504, 0x3a1aa914), TOBN(0x175a1299, 0x76dc5975), + TOBN(0xe900e0f2, 0x3fc8125c), TOBN(0x569ef68c, 0x11198875), + TOBN(0x9012db63, 0x63a113b4), TOBN(0xe3bd3f56, 0x98835766), + TOBN(0xa5c94a52, 0x76412dea), TOBN(0xad9e2a09, 0xaa735e5c), + TOBN(0x405a984c, 0x508b65e9), TOBN(0xbde4a1d1, 0x6df1a0d1), + TOBN(0x1a9433a1, 0xdfba80da), TOBN(0xe9192ff9, 0x9440ad2e), + TOBN(0x9f649696, 0x5099fe92), TOBN(0x25ddb65c, 0x0b27a54a), + TOBN(0x178279dd, 0xc590da61), TOBN(0x5479a999, 0xfbde681a), + TOBN(0xd0e84e05, 0x013fe162), TOBN(0xbe11dc92, 0x632d471b), + TOBN(0xdf0b0c45, 0xfc0e089f), TOBN(0x04fb15b0, 0x4c144025), + TOBN(0xa61d5fc2, 0x13c99927), TOBN(0xa033e9e0, 0x3de2eb35), + TOBN(0xf8185d5c, 0xb8dacbb4), TOBN(0x9a88e265, 0x8644549d), + TOBN(0xf717af62, 0x54671ff6), TOBN(0x4bd4241b, 0x5fa58603), + TOBN(0x06fba40b, 0xe67773c0), TOBN(0xc1d933d2, 0x6a2847e9), + TOBN(0xf4f5acf3, 0x689e2c70), TOBN(0x92aab0e7, 0x46bafd31), + TOBN(0x798d76aa, 0x3473f6e5), TOBN(0xcc6641db, 0x93141934), + TOBN(0xcae27757, 0xd31e535e), TOBN(0x04cc43b6, 0x87c2ee11), + TOBN(0x8d1f9675, 0x2e029ffa), TOBN(0xc2150672, 0xe4cc7a2c), + TOBN(0x3b03c1e0, 0x8d68b013), TOBN(0xa9d6816f, 0xedf298f3), + TOBN(0x1bfbb529, 0xa2804464), TOBN(0x95a52fae, 0x5db22125), + TOBN(0x55b32160, 0x0e1cb64e), TOBN(0x004828f6, 0x7e7fc9fe), + TOBN(0x13394b82, 0x1bb0fb93), TOBN(0xb6293a2d, 0x35f1a920), + TOBN(0xde35ef21, 0xd145d2d9), TOBN(0xbe6225b3, 0xbb8fa603), + TOBN(0x00fc8f6b, 0x32cf252d), TOBN(0xa28e52e6, 0x117cf8c2), + TOBN(0x9d1dc89b, 0x4c371e6d), TOBN(0xcebe0675, 0x36ef0f28), + TOBN(0x5de05d09, 0xa4292f81), TOBN(0xa8303593, 0x353e3083), + TOBN(0xa1715b0a, 0x7e37a9bb), TOBN(0x8c56f61e, 0x2b8faec3), + TOBN(0x52507431, 0x33c9b102), TOBN(0x0130cefc, 0xa44431f0), + TOBN(0x56039fa0, 0xbd865cfb), TOBN(0x4b03e578, 0xbc5f1dd7), + TOBN(0x40edf2e4, 0xbabe7224), TOBN(0xc752496d, 0x3a1988f6), + TOBN(0xd1572d3b, 0x564beb6b), TOBN(0x0db1d110, 0x39a1c608), + TOBN(0x568d1934, 0x16f60126), TOBN(0x05ae9668, 0xf354af33), + TOBN(0x19de6d37, 0xc92544f2), TOBN(0xcc084353, 0xa35837d5), + TOBN(0xcbb6869c, 0x1a514ece), TOBN(0xb633e728, 0x2e1d1066), + TOBN(0xf15dd69f, 0x936c581c), TOBN(0x96e7b8ce, 0x7439c4f9), + TOBN(0x5e676f48, 0x2e448a5b), TOBN(0xb2ca7d5b, 0xfd916bbb), + TOBN(0xd55a2541, 0xf5024025), TOBN(0x47bc5769, 0xe4c2d937), + TOBN(0x7d31b92a, 0x0362189f), TOBN(0x83f3086e, 0xef7816f9), + TOBN(0xf9f46d94, 0xb587579a), TOBN(0xec2d22d8, 0x30e76c5f), + TOBN(0x27d57461, 0xb000ffcf), TOBN(0xbb7e65f9, 0x364ffc2c), + TOBN(0x7c7c9477, 0x6652a220), TOBN(0x61618f89, 0xd696c981), + TOBN(0x5021701d, 0x89effff3), TOBN(0xf2c8ff8e, 0x7c314163), + TOBN(0x2da413ad, 0x8efb4d3e), TOBN(0x937b5adf, 0xce176d95), + TOBN(0x22867d34, 0x2a67d51c), TOBN(0x262b9b10, 0x18eb3ac9), + TOBN(0x4e314fe4, 0xc43ff28b), TOBN(0x76476627, 0x6a664e7a), + TOBN(0x3e90e40b, 0xb7a565c2), TOBN(0x8588993a, 0xc1acf831), + TOBN(0xd7b501d6, 0x8f938829), TOBN(0x996627ee, 0x3edd7d4c), + TOBN(0x37d44a62, 0x90cd34c7), TOBN(0xa8327499, 0xf3833e8d), + TOBN(0x2e18917d, 0x4bf50353), TOBN(0x85dd726b, 0x556765fb), + TOBN(0x54fe65d6, 0x93d5ab66), TOBN(0x3ddbaced, 0x915c25fe), + TOBN(0xa799d9a4, 0x12f22e85), TOBN(0xe2a24867, 0x6d06f6bc), + TOBN(0xf4f1ee56, 0x43ca1637), TOBN(0xfda2828b, 0x61ece30a), + TOBN(0x758c1a3e, 0xa2dee7a6), TOBN(0xdcde2f3c, 0x734b2284), + TOBN(0xaba445d2, 0x4eaba6ad), TOBN(0x35aaf668, 0x76cee0a7), + TOBN(0x7e0b04a9, 0xe5aa049a), TOBN(0xe74083ad, 0x91103e84), + TOBN(0xbeb183ce, 0x40afecc3), TOBN(0x6b89de9f, 0xea043f7a)}, + {TOBN(0x0e299d23, 0xfe67ba66), TOBN(0x91450760, 0x93cf2f34), + TOBN(0xf45b5ea9, 0x97fcf913), TOBN(0x5be00843, 0x8bd7ddda), + TOBN(0x358c3e05, 0xd53ff04d), TOBN(0xbf7ccdc3, 0x5de91ef7), + TOBN(0xad684dbf, 0xb69ec1a0), TOBN(0x367e7cf2, 0x801fd997), + TOBN(0x0ca1f3b7, 0xb0dc8595), TOBN(0x27de4608, 0x9f1d9f2e), + TOBN(0x1af3bf39, 0xbadd82a7), TOBN(0x79356a79, 0x65862448), + TOBN(0xc0602345, 0xf5f9a052), TOBN(0x1a8b0f89, 0x139a42f9), + TOBN(0xb53eee42, 0x844d40fc), TOBN(0x93b0bfe5, 0x4e5b6368), + TOBN(0x5434dd02, 0xc024789c), TOBN(0x90dca9ea, 0x41b57bfc), + TOBN(0x8aa898e2, 0x243398df), TOBN(0xf607c834, 0x894a94bb), + TOBN(0xbb07be97, 0xc2c99b76), TOBN(0x6576ba67, 0x18c29302), + TOBN(0x3d79efcc, 0xe703a88c), TOBN(0xf259ced7, 0xb6a0d106), + TOBN(0x0f893a5d, 0xc8de610b), TOBN(0xe8c515fb, 0x67e223ce), + TOBN(0x7774bfa6, 0x4ead6dc5), TOBN(0x89d20f95, 0x925c728f), + TOBN(0x7a1e0966, 0x098583ce), TOBN(0xa2eedb94, 0x93f2a7d7), + TOBN(0x1b282097, 0x4c304d4a), TOBN(0x0842e3da, 0xc077282d), + TOBN(0xe4d972a3, 0x3b9e2d7b), TOBN(0x7cc60b27, 0xc48218ff), + TOBN(0x8fc70838, 0x84149d91), TOBN(0x5c04346f, 0x2f461ecc), + TOBN(0xebe9fdf2, 0x614650a9), TOBN(0x5e35b537, 0xc1f666ac), + TOBN(0x645613d1, 0x88babc83), TOBN(0x88cace3a, 0xc5e1c93e), + TOBN(0x209ca375, 0x3de92e23), TOBN(0xccb03cc8, 0x5fbbb6e3), + TOBN(0xccb90f03, 0xd7b1487e), TOBN(0xfa9c2a38, 0xc710941f), + TOBN(0x756c3823, 0x6724ceed), TOBN(0x3a902258, 0x192d0323), + TOBN(0xb150e519, 0xea5e038e), TOBN(0xdcba2865, 0xc7427591), + TOBN(0xe549237f, 0x78890732), TOBN(0xc443bef9, 0x53fcb4d9), + TOBN(0x9884d8a6, 0xeb3480d6), TOBN(0x8a35b6a1, 0x3048b186), + TOBN(0xb4e44716, 0x65e9a90a), TOBN(0x45bf380d, 0x653006c0), + TOBN(0x8f3f820d, 0x4fe9ae3b), TOBN(0x244a35a0, 0x979a3b71), + TOBN(0xa1010e9d, 0x74cd06ff), TOBN(0x9c17c7df, 0xaca3eeac), + TOBN(0x74c86cd3, 0x8063aa2b), TOBN(0x8595c4b3, 0x734614ff), + TOBN(0xa3de00ca, 0x990f62cc), TOBN(0xd9bed213, 0xca0c3be5), + TOBN(0x7886078a, 0xdf8ce9f5), TOBN(0xddb27ce3, 0x5cd44444), + TOBN(0xed374a66, 0x58926ddd), TOBN(0x138b2d49, 0x908015b8), + TOBN(0x886c6579, 0xde1f7ab8), TOBN(0x888b9aa0, 0xc3020b7a), + TOBN(0xd3ec034e, 0x3a96e355), TOBN(0xba65b0b8, 0xf30fbe9a), + TOBN(0x064c8e50, 0xff21367a), TOBN(0x1f508ea4, 0x0b04b46e), + TOBN(0x98561a49, 0x747c866c), TOBN(0xbbb1e5fe, 0x0518a062), + TOBN(0x20ff4e8b, 0xecdc3608), TOBN(0x7f55cded, 0x20184027), + TOBN(0x8d73ec95, 0xf38c85f0), TOBN(0x5b589fdf, 0x8bc3b8c3), + TOBN(0xbe95dd98, 0x0f12b66f), TOBN(0xf5bd1a09, 0x0e338e01), + TOBN(0x65163ae5, 0x5e915918), TOBN(0x6158d6d9, 0x86f8a46b), + TOBN(0x8466b538, 0xeeebf99c), TOBN(0xca8761f6, 0xbca477ef), + TOBN(0xaf3449c2, 0x9ebbc601), TOBN(0xef3b0f41, 0xe0c3ae2f), + TOBN(0xaa6c577d, 0x5de63752), TOBN(0xe9166601, 0x64682a51), + TOBN(0x5a3097be, 0xfc15aa1e), TOBN(0x40d12548, 0xb54b0745), + TOBN(0x5bad4706, 0x519a5f12), TOBN(0xed03f717, 0xa439dee6), + TOBN(0x0794bb6c, 0x4a02c499), TOBN(0xf725083d, 0xcffe71d2), + TOBN(0x2cad7519, 0x0f3adcaf), TOBN(0x7f68ea1c, 0x43729310), + TOBN(0xe747c8c7, 0xb7ffd977), TOBN(0xec104c35, 0x80761a22), + TOBN(0x8395ebaf, 0x5a3ffb83), TOBN(0xfb3261f4, 0xe4b63db7), + TOBN(0x53544960, 0xd883e544), TOBN(0x13520d70, 0x8cc2eeb8), + TOBN(0x08f6337b, 0xd3d65f99), TOBN(0x83997db2, 0x781cf95b), + TOBN(0xce6ff106, 0x0dbd2c01), TOBN(0x4f8eea6b, 0x1f9ce934), + TOBN(0x546f7c4b, 0x0e993921), TOBN(0x6236a324, 0x5e753fc7), + TOBN(0x65a41f84, 0xa16022e9), TOBN(0x0c18d878, 0x43d1dbb2), + TOBN(0x73c55640, 0x2d4cef9c), TOBN(0xa0428108, 0x70444c74), + TOBN(0x68e4f15e, 0x9afdfb3c), TOBN(0x49a56143, 0x5bdfb6df), + TOBN(0xa9bc1bd4, 0x5f823d97), TOBN(0xbceb5970, 0xea111c2a), + TOBN(0x366b455f, 0xb269bbc4), TOBN(0x7cd85e1e, 0xe9bc5d62), + TOBN(0xc743c41c, 0x4f18b086), TOBN(0xa4b40990, 0x95294fb9), + TOBN(0x9c7c581d, 0x26ee8382), TOBN(0xcf17dcc5, 0x359d638e), + TOBN(0xee8273ab, 0xb728ae3d), TOBN(0x1d112926, 0xf821f047), + TOBN(0x11498477, 0x50491a74), TOBN(0x687fa761, 0xfde0dfb9), + TOBN(0x2c258022, 0x7ea435ab), TOBN(0x6b8bdb94, 0x91ce7e3f), + TOBN(0x4c5b5dc9, 0x3bf834aa), TOBN(0x04371819, 0x4f6c7e4b), + TOBN(0xc284e00a, 0x3736bcad), TOBN(0x0d881118, 0x21ae8f8d), + TOBN(0xf9cf0f82, 0xf48c8e33), TOBN(0xa11fd075, 0xa1bf40db), + TOBN(0xdceab0de, 0xdc2733e5), TOBN(0xc560a8b5, 0x8e986bd7), + TOBN(0x48dd1fe2, 0x3929d097), TOBN(0x3885b290, 0x92f188f1), + TOBN(0x0f2ae613, 0xda6fcdac), TOBN(0x9054303e, 0xb662a46c), + TOBN(0xb6871e44, 0x0738042a), TOBN(0x98e6a977, 0xbdaf6449), + TOBN(0xd8bc0650, 0xd1c9df1b), TOBN(0xef3d6451, 0x36e098f9), + TOBN(0x03fbae82, 0xb6d72d28), TOBN(0x77ca9db1, 0xf5d84080), + TOBN(0x8a112cff, 0xa58efc1c), TOBN(0x518d761c, 0xc564cb4a), + TOBN(0x69b5740e, 0xf0d1b5ce), TOBN(0x717039cc, 0xe9eb1785), + TOBN(0x3fe29f90, 0x22f53382), TOBN(0x8e54ba56, 0x6bc7c95c), + TOBN(0x9c806d8a, 0xf7f91d0f), TOBN(0x3b61b0f1, 0xa82a5728), + TOBN(0x4640032d, 0x94d76754), TOBN(0x273eb5de, 0x47d834c6), + TOBN(0x2988abf7, 0x7b4e4d53), TOBN(0xb7ce66bf, 0xde401777), + TOBN(0x9fba6b32, 0x715071b3), TOBN(0x82413c24, 0xad3a1a98), + TOBN(0x5b7fc8c4, 0xe0e8ad93), TOBN(0xb5679aee, 0x5fab868d), + TOBN(0xb1f9d2fa, 0x2b3946f3), TOBN(0x458897dc, 0x5685b50a), + TOBN(0x1e98c930, 0x89d0caf3), TOBN(0x39564c5f, 0x78642e92), + TOBN(0x1b77729a, 0x0dbdaf18), TOBN(0xf9170722, 0x579e82e6), + TOBN(0x680c0317, 0xe4515fa5), TOBN(0xf85cff84, 0xfb0c790f), + TOBN(0xc7a82aab, 0x6d2e0765), TOBN(0x7446bca9, 0x35c82b32), + TOBN(0x5de607aa, 0x6d63184f), TOBN(0x7c1a46a8, 0x262803a6), + TOBN(0xd218313d, 0xaebe8035), TOBN(0x92113ffd, 0xc73c51f8), + TOBN(0x4b38e083, 0x12e7e46c), TOBN(0x69d0a37a, 0x56126bd5), + TOBN(0xfb3f324b, 0x73c07e04), TOBN(0xa0c22f67, 0x8fda7267), + TOBN(0x8f2c0051, 0x4d2c7d8f), TOBN(0xbc45ced3, 0xcbe2cae5), + TOBN(0xe1c6cf07, 0xa8f0f277), TOBN(0xbc392312, 0x1eb99a98), + TOBN(0x75537b7e, 0x3cc8ac85), TOBN(0x8d725f57, 0xdd02753b), + TOBN(0xfd05ff64, 0xb737df2f), TOBN(0x55fe8712, 0xf6d2531d), + TOBN(0x57ce04a9, 0x6ab6b01c), TOBN(0x69a02a89, 0x7cd93724), + TOBN(0x4f82ac35, 0xcf86699b), TOBN(0x8242d3ad, 0x9cb4b232), + TOBN(0x713d0f65, 0xd62105e5), TOBN(0xbb222bfa, 0x2d29be61), + TOBN(0xf2f9a79e, 0x6cfbef09), TOBN(0xfc24d8d3, 0xd5d6782f), + TOBN(0x5db77085, 0xd4129967), TOBN(0xdb81c3cc, 0xdc3c2a43), + TOBN(0x9d655fc0, 0x05d8d9a3), TOBN(0x3f5d057a, 0x54298026), + TOBN(0x1157f56d, 0x88c54694), TOBN(0xb26baba5, 0x9b09573e), + TOBN(0x2cab03b0, 0x22adffd1), TOBN(0x60a412c8, 0xdd69f383), + TOBN(0xed76e98b, 0x54b25039), TOBN(0xd4ee67d3, 0x687e714d), + TOBN(0x87739648, 0x7b00b594), TOBN(0xce419775, 0xc9ef709b), + TOBN(0x40f76f85, 0x1c203a40), TOBN(0x30d352d6, 0xeafd8f91), + TOBN(0xaf196d3d, 0x95578dd2), TOBN(0xea4bb3d7, 0x77cc3f3d), + TOBN(0x42a5bd03, 0xb98e782b), TOBN(0xac958c40, 0x0624920d), + TOBN(0xb838134c, 0xfc56fcc8), TOBN(0x86ec4ccf, 0x89572e5e), + TOBN(0x69c43526, 0x9be47be0), TOBN(0x323b7dd8, 0xcb28fea1), + TOBN(0xfa5538ba, 0x3a6c67e5), TOBN(0xef921d70, 0x1d378e46), + TOBN(0xf92961fc, 0x3c4b880e), TOBN(0x3f6f914e, 0x98940a67), + TOBN(0xa990eb0a, 0xfef0ff39), TOBN(0xa6c2920f, 0xf0eeff9c), + TOBN(0xca804166, 0x51b8d9a3), TOBN(0x42531bc9, 0x0ffb0db1), + TOBN(0x72ce4718, 0xaa82e7ce), TOBN(0x6e199913, 0xdf574741), + TOBN(0xd5f1b13d, 0xd5d36946), TOBN(0x8255dc65, 0xf68f0194), + TOBN(0xdc9df4cd, 0x8710d230), TOBN(0x3453c20f, 0x138c1988), + TOBN(0x9af98dc0, 0x89a6ef01), TOBN(0x4dbcc3f0, 0x9857df85), + TOBN(0x34805601, 0x5c1ad924), TOBN(0x40448da5, 0xd0493046), + TOBN(0xf629926d, 0x4ee343e2), TOBN(0x6343f1bd, 0x90e8a301), + TOBN(0xefc93491, 0x40815b3f), TOBN(0xf882a423, 0xde8f66fb), + TOBN(0x3a12d5f4, 0xe7db9f57), TOBN(0x7dfba38a, 0x3c384c27), + TOBN(0x7a904bfd, 0x6fc660b1), TOBN(0xeb6c5db3, 0x2773b21c), + TOBN(0xc350ee66, 0x1cdfe049), TOBN(0x9baac0ce, 0x44540f29), + TOBN(0xbc57b6ab, 0xa5ec6aad), TOBN(0x167ce8c3, 0x0a7c1baa), + TOBN(0xb23a03a5, 0x53fb2b56), TOBN(0x6ce141e7, 0x4e057f78), + TOBN(0x796525c3, 0x89e490d9), TOBN(0x0bc95725, 0xa31a7e75), + TOBN(0x1ec56791, 0x1220fd06), TOBN(0x716e3a3c, 0x408b0bd6), + TOBN(0x31cd6bf7, 0xe8ebeba9), TOBN(0xa7326ca6, 0xbee6b670), + TOBN(0x3d9f851c, 0xcd090c43), TOBN(0x561e8f13, 0xf12c3988), + TOBN(0x50490b6a, 0x904b7be4), TOBN(0x61690ce1, 0x0410737b), + TOBN(0x299e9a37, 0x0f009052), TOBN(0x258758f0, 0xf026092e), + TOBN(0x9fa255f3, 0xfdfcdc0f), TOBN(0xdbc9fb1f, 0xc0e1bcd2), + TOBN(0x35f9dd6e, 0x24651840), TOBN(0xdca45a84, 0xa5c59abc), + TOBN(0x103d396f, 0xecca4938), TOBN(0x4532da0a, 0xb97b3f29), + TOBN(0xc4135ea5, 0x1999a6bf), TOBN(0x3aa9505a, 0x5e6bf2ee), + TOBN(0xf77cef06, 0x3f5be093), TOBN(0x97d1a0f8, 0xa943152e), + TOBN(0x2cb0ebba, 0x2e1c21dd), TOBN(0xf41b29fc, 0x2c6797c4), + TOBN(0xc6e17321, 0xb300101f), TOBN(0x4422b0e9, 0xd0d79a89), + TOBN(0x49e4901c, 0x92f1bfc4), TOBN(0x06ab1f8f, 0xe1e10ed9), + TOBN(0x84d35577, 0xdb2926b8), TOBN(0xca349d39, 0x356e8ec2), + TOBN(0x70b63d32, 0x343bf1a9), TOBN(0x8fd3bd28, 0x37d1a6b1), + TOBN(0x0454879c, 0x316865b4), TOBN(0xee959ff6, 0xc458efa2), + TOBN(0x0461dcf8, 0x9706dc3f), TOBN(0x737db0e2, 0x164e4b2e), + TOBN(0x09262680, 0x2f8843c8), TOBN(0x54498bbc, 0x7745e6f6), + TOBN(0x359473fa, 0xa29e24af), TOBN(0xfcc3c454, 0x70aa87a1), + TOBN(0xfd2c4bf5, 0x00573ace), TOBN(0xb65b514e, 0x28dd1965), + TOBN(0xe46ae7cf, 0x2193e393), TOBN(0x60e9a4e1, 0xf5444d97), + TOBN(0xe7594e96, 0x00ff38ed), TOBN(0x43d84d2f, 0x0a0e0f02), + TOBN(0x8b6db141, 0xee398a21), TOBN(0xb88a56ae, 0xe3bcc5be), + TOBN(0x0a1aa52f, 0x373460ea), TOBN(0x20da1a56, 0x160bb19b), + TOBN(0xfb54999d, 0x65bf0384), TOBN(0x71a14d24, 0x5d5a180e), + TOBN(0xbc44db7b, 0x21737b04), TOBN(0xd84fcb18, 0x01dd8e92), + TOBN(0x80de937b, 0xfa44b479), TOBN(0x53505499, 0x5c98fd4f), + TOBN(0x1edb12ab, 0x28f08727), TOBN(0x4c58b582, 0xa5f3ef53), + TOBN(0xbfb236d8, 0x8327f246), TOBN(0xc3a3bfaa, 0x4d7df320), + TOBN(0xecd96c59, 0xb96024f2), TOBN(0xfc293a53, 0x7f4e0433), + TOBN(0x5341352b, 0x5acf6e10), TOBN(0xc50343fd, 0xafe652c3), + TOBN(0x4af3792d, 0x18577a7f), TOBN(0xe1a4c617, 0xaf16823d), + TOBN(0x9b26d0cd, 0x33425d0a), TOBN(0x306399ed, 0x9b7bc47f), + TOBN(0x2a792f33, 0x706bb20b), TOBN(0x31219614, 0x98111055), + TOBN(0x864ec064, 0x87f5d28b), TOBN(0x11392d91, 0x962277fd), + TOBN(0xb5aa7942, 0xbb6aed5f), TOBN(0x080094dc, 0x47e799d9), + TOBN(0x4afa588c, 0x208ba19b), TOBN(0xd3e7570f, 0x8512f284), + TOBN(0xcbae64e6, 0x02f5799a), TOBN(0xdeebe7ef, 0x514b9492), + TOBN(0x30300f98, 0xe5c298ff), TOBN(0x17f561be, 0x3678361f), + TOBN(0xf52ff312, 0x98cb9a16), TOBN(0x6233c3bc, 0x5562d490), + TOBN(0x7bfa15a1, 0x92e3a2cb), TOBN(0x961bcfd1, 0xe6365119), + TOBN(0x3bdd29bf, 0x2c8c53b1), TOBN(0x739704df, 0x822844ba), + TOBN(0x7dacfb58, 0x7e7b754b), TOBN(0x23360791, 0xa806c9b9), + TOBN(0xe7eb88c9, 0x23504452), TOBN(0x2983e996, 0x852c1783), + TOBN(0xdd4ae529, 0x958d881d), TOBN(0x026bae03, 0x262c7b3c), + TOBN(0x3a6f9193, 0x960b52d1), TOBN(0xd0980f90, 0x92696cfb), + TOBN(0x4c1f428c, 0xd5f30851), TOBN(0x94dfed27, 0x2a4f6630), + TOBN(0x4df53772, 0xfc5d48a4), TOBN(0xdd2d5a2f, 0x933260ce), + TOBN(0x574115bd, 0xd44cc7a5), TOBN(0x4ba6b20d, 0xbd12533a), + TOBN(0x30e93cb8, 0x243057c9), TOBN(0x794c486a, 0x14de320e), + TOBN(0xe925d4ce, 0xf21496e4), TOBN(0xf951d198, 0xec696331), + TOBN(0x9810e2de, 0x3e8d812f), TOBN(0xd0a47259, 0x389294ab), + TOBN(0x513ba2b5, 0x0e3bab66), TOBN(0x462caff5, 0xabad306f), + TOBN(0xe2dc6d59, 0xaf04c49e), TOBN(0x1aeb8750, 0xe0b84b0b), + TOBN(0xc034f12f, 0x2f7d0ca2), TOBN(0x6d2e8128, 0xe06acf2f), + TOBN(0x801f4f83, 0x21facc2f), TOBN(0xa1170c03, 0xf40ef607), + TOBN(0xfe0a1d4f, 0x7805a99c), TOBN(0xbde56a36, 0xcc26aba5), + TOBN(0x5b1629d0, 0x35531f40), TOBN(0xac212c2b, 0x9afa6108), + TOBN(0x30a06bf3, 0x15697be5), TOBN(0x6f0545dc, 0x2c63c7c1), + TOBN(0x5d8cb842, 0x7ccdadaf), TOBN(0xd52e379b, 0xac7015bb), + TOBN(0xc4f56147, 0xf462c23e), TOBN(0xd44a4298, 0x46bc24b0), + TOBN(0xbc73d23a, 0xe2856d4f), TOBN(0x61cedd8c, 0x0832bcdf), + TOBN(0x60953556, 0x99f241d7), TOBN(0xee4adbd7, 0x001a349d), + TOBN(0x0b35bf6a, 0xaa89e491), TOBN(0x7f0076f4, 0x136f7546), + TOBN(0xd19a18ba, 0x9264da3d), TOBN(0x6eb2d2cd, 0x62a7a28b), + TOBN(0xcdba941f, 0x8761c971), TOBN(0x1550518b, 0xa3be4a5d), + TOBN(0xd0e8e2f0, 0x57d0b70c), TOBN(0xeea8612e, 0xcd133ba3), + TOBN(0x814670f0, 0x44416aec), TOBN(0x424db6c3, 0x30775061), + TOBN(0xd96039d1, 0x16213fd1), TOBN(0xc61e7fa5, 0x18a3478f), + TOBN(0xa805bdcc, 0xcb0c5021), TOBN(0xbdd6f3a8, 0x0cc616dd), + TOBN(0x06009667, 0x5d97f7e2), TOBN(0x31db0fc1, 0xaf0bf4b6), + TOBN(0x23680ed4, 0x5491627a), TOBN(0xb99a3c66, 0x7d741fb1), + TOBN(0xe9bb5f55, 0x36b1ff92), TOBN(0x29738577, 0x512b388d), + TOBN(0xdb8a2ce7, 0x50fcf263), TOBN(0x385346d4, 0x6c4f7b47), + TOBN(0xbe86c5ef, 0x31631f9e), TOBN(0xbf91da21, 0x03a57a29), + TOBN(0xc3b1f796, 0x7b23f821), TOBN(0x0f7d00d2, 0x770db354), + TOBN(0x8ffc6c3b, 0xd8fe79da), TOBN(0xcc5e8c40, 0xd525c996), + TOBN(0x4640991d, 0xcfff632a), TOBN(0x64d97e8c, 0x67112528), + TOBN(0xc232d973, 0x02f1cd1e), TOBN(0xce87eacb, 0x1dd212a4), + TOBN(0x6e4c8c73, 0xe69802f7), TOBN(0x12ef0290, 0x1fffddbd), + TOBN(0x941ec74e, 0x1bcea6e2), TOBN(0xd0b54024, 0x3cb92cbb), + TOBN(0x809fb9d4, 0x7e8f9d05), TOBN(0x3bf16159, 0xf2992aae), + TOBN(0xad40f279, 0xf8a7a838), TOBN(0x11aea631, 0x05615660), + TOBN(0xbf52e6f1, 0xa01f6fa1), TOBN(0xef046995, 0x3dc2aec9), + TOBN(0x785dbec9, 0xd8080711), TOBN(0xe1aec60a, 0x9fdedf76), + TOBN(0xece797b5, 0xfa21c126), TOBN(0xc66e898f, 0x05e52732), + TOBN(0x39bb69c4, 0x08811fdb), TOBN(0x8bfe1ef8, 0x2fc7f082), + TOBN(0xc8e7a393, 0x174f4138), TOBN(0xfba8ad1d, 0xd58d1f98), + TOBN(0xbc21d0ce, 0xbfd2fd5b), TOBN(0x0b839a82, 0x6ee60d61), + TOBN(0xaacf7658, 0xafd22253), TOBN(0xb526bed8, 0xaae396b3), + TOBN(0xccc1bbc2, 0x38564464), TOBN(0x9e3ff947, 0x8c45bc73), + TOBN(0xcde9bca3, 0x58188a78), TOBN(0x138b8ee0, 0xd73bf8f7), + TOBN(0x5c7e234c, 0x4123c489), TOBN(0x66e69368, 0xfa643297), + TOBN(0x0629eeee, 0x39a15fa3), TOBN(0x95fab881, 0xa9e2a927), + TOBN(0xb2497007, 0xeafbb1e1), TOBN(0xd75c9ce6, 0xe75b7a93), + TOBN(0x3558352d, 0xefb68d78), TOBN(0xa2f26699, 0x223f6396), + TOBN(0xeb911ecf, 0xe469b17a), TOBN(0x62545779, 0xe72d3ec2), + TOBN(0x8ea47de7, 0x82cb113f), TOBN(0xebe4b086, 0x4e1fa98d), + TOBN(0xec2d5ed7, 0x8cdfedb1), TOBN(0xa535c077, 0xfe211a74), + TOBN(0x9678109b, 0x11d244c5), TOBN(0xf17c8bfb, 0xbe299a76), + TOBN(0xb651412e, 0xfb11fbc4), TOBN(0xea0b5482, 0x94ab3f65), + TOBN(0xd8dffd95, 0x0cf78243), TOBN(0x2e719e57, 0xce0361d4), + TOBN(0x9007f085, 0x304ddc5b), TOBN(0x095e8c6d, 0x4daba2ea), + TOBN(0x5a33cdb4, 0x3f9d28a9), TOBN(0x85b95cd8, 0xe2283003), + TOBN(0xbcd6c819, 0xb9744733), TOBN(0x29c5f538, 0xfc7f5783), + TOBN(0x6c49b2fa, 0xd59038e4), TOBN(0x68349cc1, 0x3bbe1018), + TOBN(0xcc490c1d, 0x21830ee5), TOBN(0x36f9c4ee, 0xe9bfa297), + TOBN(0x58fd7294, 0x48de1a94), TOBN(0xaadb13a8, 0x4e8f2cdc), + TOBN(0x515eaaa0, 0x81313dba), TOBN(0xc76bb468, 0xc2152dd8), + TOBN(0x357f8d75, 0xa653dbf8), TOBN(0xe4d8c4d1, 0xb14ac143), + TOBN(0xbdb8e675, 0xb055cb40), TOBN(0x898f8e7b, 0x977b5167), + TOBN(0xecc65651, 0xb82fb863), TOBN(0x56544814, 0x6d88f01f), + TOBN(0xb0928e95, 0x263a75a9), TOBN(0xcfb6836f, 0x1a22fcda), + TOBN(0x651d14db, 0x3f3bd37c), TOBN(0x1d3837fb, 0xb6ad4664), + TOBN(0x7c5fb538, 0xff4f94ab), TOBN(0x7243c712, 0x6d7fb8f2), + TOBN(0xef13d60c, 0xa85c5287), TOBN(0x18cfb7c7, 0x4bb8dd1b), + TOBN(0x82f9bfe6, 0x72908219), TOBN(0x35c4592b, 0x9d5144ab), + TOBN(0x52734f37, 0x9cf4b42f), TOBN(0x6bac55e7, 0x8c60ddc4), + TOBN(0xb5cd811e, 0x94dea0f6), TOBN(0x259ecae4, 0xe18cc1a3), + TOBN(0x6a0e836e, 0x15e660f8), TOBN(0x6c639ea6, 0x0e02bff2), + TOBN(0x8721b8cb, 0x7e1026fd), TOBN(0x9e73b50b, 0x63261942), + TOBN(0xb8c70974, 0x77f01da3), TOBN(0x1839e6a6, 0x8268f57f), + TOBN(0x571b9415, 0x5150b805), TOBN(0x1892389e, 0xf92c7097), + TOBN(0x8d69c18e, 0x4a084b95), TOBN(0x7014c512, 0xbe5b495c), + TOBN(0x4780db36, 0x1b07523c), TOBN(0x2f6219ce, 0x2c1c64fa), + TOBN(0xc38b81b0, 0x602c105a), TOBN(0xab4f4f20, 0x5dc8e360), + TOBN(0x20d3c982, 0xcf7d62d2), TOBN(0x1f36e29d, 0x23ba8150), + TOBN(0x48ae0bf0, 0x92763f9e), TOBN(0x7a527e6b, 0x1d3a7007), + TOBN(0xb4a89097, 0x581a85e3), TOBN(0x1f1a520f, 0xdc158be5), + TOBN(0xf98db37d, 0x167d726e), TOBN(0x8802786e, 0x1113e862)}, + {TOBN(0xefb2149e, 0x36f09ab0), TOBN(0x03f163ca, 0x4a10bb5b), + TOBN(0xd0297045, 0x06e20998), TOBN(0x56f0af00, 0x1b5a3bab), + TOBN(0x7af4cfec, 0x70880e0d), TOBN(0x7332a66f, 0xbe3d913f), + TOBN(0x32e6c84a, 0x7eceb4bd), TOBN(0xedc4a79a, 0x9c228f55), + TOBN(0xc37c7dd0, 0xc55c4496), TOBN(0xa6a96357, 0x25bbabd2), + TOBN(0x5b7e63f2, 0xadd7f363), TOBN(0x9dce3782, 0x2e73f1df), + TOBN(0xe1e5a16a, 0xb2b91f71), TOBN(0xe4489823, 0x5ba0163c), + TOBN(0xf2759c32, 0xf6e515ad), TOBN(0xa5e2f1f8, 0x8615eecf), + TOBN(0x74519be7, 0xabded551), TOBN(0x03d358b8, 0xc8b74410), + TOBN(0x4d00b10b, 0x0e10d9a9), TOBN(0x6392b0b1, 0x28da52b7), + TOBN(0x6744a298, 0x0b75c904), TOBN(0xc305b0ae, 0xa8f7f96c), + TOBN(0x042e421d, 0x182cf932), TOBN(0xf6fc5d50, 0x9e4636ca), + TOBN(0x795847c9, 0xd64cc78c), TOBN(0x6c50621b, 0x9b6cb27b), + TOBN(0x07099bf8, 0xdf8022ab), TOBN(0x48f862eb, 0xc04eda1d), + TOBN(0xd12732ed, 0xe1603c16), TOBN(0x19a80e0f, 0x5c9a9450), + TOBN(0xe2257f54, 0xb429b4fc), TOBN(0x66d3b2c6, 0x45460515), + TOBN(0x6ca4f87e, 0x822e37be), TOBN(0x73f237b4, 0x253bda4e), + TOBN(0xf747f3a2, 0x41190aeb), TOBN(0xf06fa36f, 0x804cf284), + TOBN(0x0a6bbb6e, 0xfc621c12), TOBN(0x5d624b64, 0x40b80ec6), + TOBN(0x4b072425, 0x7ba556f3), TOBN(0x7fa0c354, 0x3e2d20a8), + TOBN(0xe921fa31, 0xe3229d41), TOBN(0xa929c652, 0x94531bd4), + TOBN(0x84156027, 0xa6d38209), TOBN(0xf3d69f73, 0x6bdb97bd), + TOBN(0x8906d19a, 0x16833631), TOBN(0x68a34c2e, 0x03d51be3), + TOBN(0xcb59583b, 0x0e511cd8), TOBN(0x99ce6bfd, 0xfdc132a8), + TOBN(0x3facdaaa, 0xffcdb463), TOBN(0x658bbc1a, 0x34a38b08), + TOBN(0x12a801f8, 0xf1a9078d), TOBN(0x1567bcf9, 0x6ab855de), + TOBN(0xe08498e0, 0x3572359b), TOBN(0xcf0353e5, 0x8659e68b), + TOBN(0xbb86e9c8, 0x7d23807c), TOBN(0xbc08728d, 0x2198e8a2), + TOBN(0x8de2b7bc, 0x453cadd6), TOBN(0x203900a7, 0xbc0bc1f8), + TOBN(0xbcd86e47, 0xa6abd3af), TOBN(0x911cac12, 0x8502effb), + TOBN(0x2d550242, 0xec965469), TOBN(0x0e9f7692, 0x29e0017e), + TOBN(0x633f078f, 0x65979885), TOBN(0xfb87d449, 0x4cf751ef), + TOBN(0xe1790e4b, 0xfc25419a), TOBN(0x36467203, 0x4bff3cfd), + TOBN(0xc8db6386, 0x25b6e83f), TOBN(0x6cc69f23, 0x6cad6fd2), + TOBN(0x0219e45a, 0x6bc68bb9), TOBN(0xe43d79b6, 0x297f7334), + TOBN(0x7d445368, 0x465dc97c), TOBN(0x4b9eea32, 0x2a0b949a), + TOBN(0x1b96c6ba, 0x6102d021), TOBN(0xeaafac78, 0x2f4461ea), + TOBN(0xd4b85c41, 0xc49f19a8), TOBN(0x275c28e4, 0xcf538875), + TOBN(0x35451a9d, 0xdd2e54e0), TOBN(0x6991adb5, 0x0605618b), + TOBN(0x5b8b4bcd, 0x7b36cd24), TOBN(0x372a4f8c, 0x56f37216), + TOBN(0xc890bd73, 0xa6a5da60), TOBN(0x6f083da0, 0xdc4c9ff0), + TOBN(0xf4e14d94, 0xf0536e57), TOBN(0xf9ee1eda, 0xaaec8243), + TOBN(0x571241ec, 0x8bdcf8e7), TOBN(0xa5db8271, 0x0b041e26), + TOBN(0x9a0b9a99, 0xe3fff040), TOBN(0xcaaf21dd, 0x7c271202), + TOBN(0xb4e2b2e1, 0x4f0dd2e8), TOBN(0xe77e7c4f, 0x0a377ac7), + TOBN(0x69202c3f, 0x0d7a2198), TOBN(0xf759b7ff, 0x28200eb8), + TOBN(0xc87526ed, 0xdcfe314e), TOBN(0xeb84c524, 0x53d5cf99), + TOBN(0xb1b52ace, 0x515138b6), TOBN(0x5aa7ff8c, 0x23fca3f4), + TOBN(0xff0b13c3, 0xb9791a26), TOBN(0x960022da, 0xcdd58b16), + TOBN(0xdbd55c92, 0x57aad2de), TOBN(0x3baaaaa3, 0xf30fe619), + TOBN(0x9a4b2346, 0x0d881efd), TOBN(0x506416c0, 0x46325e2a), + TOBN(0x91381e76, 0x035c18d4), TOBN(0xb3bb68be, 0xf27817b0), + TOBN(0x15bfb8bf, 0x5116f937), TOBN(0x7c64a586, 0xc1268943), + TOBN(0x71e25cc3, 0x8419a2c8), TOBN(0x9fd6b0c4, 0x8335f463), + TOBN(0x4bf0ba3c, 0xe8ee0e0e), TOBN(0x6f6fba60, 0x298c21fa), + TOBN(0x57d57b39, 0xae66bee0), TOBN(0x292d5130, 0x22672544), + TOBN(0xf451105d, 0xbab093b3), TOBN(0x012f59b9, 0x02839986), + TOBN(0x8a915802, 0x3474a89c), TOBN(0x048c919c, 0x2de03e97), + TOBN(0xc476a2b5, 0x91071cd5), TOBN(0x791ed89a, 0x034970a5), + TOBN(0x89bd9042, 0xe1b7994b), TOBN(0x8eaf5179, 0xa1057ffd), + TOBN(0x6066e2a2, 0xd551ee10), TOBN(0x87a8f1d8, 0x727e09a6), + TOBN(0x00d08bab, 0x2c01148d), TOBN(0x6da8e4f1, 0x424f33fe), + TOBN(0x466d17f0, 0xcf9a4e71), TOBN(0xff502010, 0x3bf5cb19), + TOBN(0xdccf97d8, 0xd062ecc0), TOBN(0x80c0d9af, 0x81d80ac4), + TOBN(0xe87771d8, 0x033f2876), TOBN(0xb0186ec6, 0x7d5cc3db), + TOBN(0x58e8bb80, 0x3bc9bc1d), TOBN(0x4d1395cc, 0x6f6ef60e), + TOBN(0xa73c62d6, 0x186244a0), TOBN(0x918e5f23, 0x110a5b53), + TOBN(0xed4878ca, 0x741b7eab), TOBN(0x3038d71a, 0xdbe03e51), + TOBN(0x840204b7, 0xa93c3246), TOBN(0x21ab6069, 0xa0b9b4cd), + TOBN(0xf5fa6e2b, 0xb1d64218), TOBN(0x1de6ad0e, 0xf3d56191), + TOBN(0x570aaa88, 0xff1929c7), TOBN(0xc6df4c6b, 0x640e87b5), + TOBN(0xde8a74f2, 0xc65f0ccc), TOBN(0x8b972fd5, 0xe6f6cc01), + TOBN(0x3fff36b6, 0x0b846531), TOBN(0xba7e45e6, 0x10a5e475), + TOBN(0x84a1d10e, 0x4145b6c5), TOBN(0xf1f7f91a, 0x5e046d9d), + TOBN(0x0317a692, 0x44de90d7), TOBN(0x951a1d4a, 0xf199c15e), + TOBN(0x91f78046, 0xc9d73deb), TOBN(0x74c82828, 0xfab8224f), + TOBN(0xaa6778fc, 0xe7560b90), TOBN(0xb4073e61, 0xa7e824ce), + TOBN(0xff0d693c, 0xd642eba8), TOBN(0x7ce2e57a, 0x5dccef38), + TOBN(0x89c2c789, 0x1df1ad46), TOBN(0x83a06922, 0x098346fd), + TOBN(0x2d715d72, 0xda2fc177), TOBN(0x7b6dd71d, 0x85b6cf1d), + TOBN(0xc60a6d0a, 0x73fa9cb0), TOBN(0xedd3992e, 0x328bf5a9), + TOBN(0xc380ddd0, 0x832c8c82), TOBN(0xd182d410, 0xa2a0bf50), + TOBN(0x7d9d7438, 0xd9a528db), TOBN(0xe8b1a0e9, 0xcaf53994), + TOBN(0xddd6e5fe, 0x0e19987c), TOBN(0xacb8df03, 0x190b059d), + TOBN(0x53703a32, 0x8300129f), TOBN(0x1f637662, 0x68c43bfd), + TOBN(0xbcbd1913, 0x00e54051), TOBN(0x812fcc62, 0x7bf5a8c5), + TOBN(0x3f969d5f, 0x29fb85da), TOBN(0x72f4e00a, 0x694759e8), + TOBN(0x426b6e52, 0x790726b7), TOBN(0x617bbc87, 0x3bdbb209), + TOBN(0x511f8bb9, 0x97aee317), TOBN(0x812a4096, 0xe81536a8), + TOBN(0x137dfe59, 0x3ac09b9b), TOBN(0x0682238f, 0xba8c9a7a), + TOBN(0x7072ead6, 0xaeccb4bd), TOBN(0x6a34e9aa, 0x692ba633), + TOBN(0xc82eaec2, 0x6fff9d33), TOBN(0xfb753512, 0x1d4d2b62), + TOBN(0x1a0445ff, 0x1d7aadab), TOBN(0x65d38260, 0xd5f6a67c), + TOBN(0x6e62fb08, 0x91cfb26f), TOBN(0xef1e0fa5, 0x5c7d91d6), + TOBN(0x47e7c7ba, 0x33db72cd), TOBN(0x017cbc09, 0xfa7c74b2), + TOBN(0x3c931590, 0xf50a503c), TOBN(0xcac54f60, 0x616baa42), + TOBN(0x9b6cd380, 0xb2369f0f), TOBN(0x97d3a70d, 0x23c76151), + TOBN(0x5f9dd6fc, 0x9862a9c6), TOBN(0x044c4ab2, 0x12312f51), + TOBN(0x035ea0fd, 0x834a2ddc), TOBN(0x49e6b862, 0xcc7b826d), + TOBN(0xb03d6883, 0x62fce490), TOBN(0x62f2497a, 0xb37e36e9), + TOBN(0x04b005b6, 0xc6458293), TOBN(0x36bb5276, 0xe8d10af7), + TOBN(0xacf2dc13, 0x8ee617b8), TOBN(0x470d2d35, 0xb004b3d4), + TOBN(0x06790832, 0xfeeb1b77), TOBN(0x2bb75c39, 0x85657f9c), + TOBN(0xd70bd4ed, 0xc0f60004), TOBN(0xfe797ecc, 0x219b018b), + TOBN(0x9b5bec2a, 0x753aebcc), TOBN(0xdaf9f3dc, 0xc939eca5), + TOBN(0xd6bc6833, 0xd095ad09), TOBN(0x98abdd51, 0xdaa4d2fc), + TOBN(0xd9840a31, 0x8d168be5), TOBN(0xcf7c10e0, 0x2325a23c), + TOBN(0xa5c02aa0, 0x7e6ecfaf), TOBN(0x2462e7e6, 0xb5bfdf18), + TOBN(0xab2d8a8b, 0xa0cc3f12), TOBN(0x68dd485d, 0xbc672a29), + TOBN(0x72039752, 0x596f2cd3), TOBN(0x5d3eea67, 0xa0cf3d8d), + TOBN(0x810a1a81, 0xe6602671), TOBN(0x8f144a40, 0x14026c0c), + TOBN(0xbc753a6d, 0x76b50f85), TOBN(0xc4dc21e8, 0x645cd4a4), + TOBN(0xc5262dea, 0x521d0378), TOBN(0x802b8e0e, 0x05011c6f), + TOBN(0x1ba19cbb, 0x0b4c19ea), TOBN(0x21db64b5, 0xebf0aaec), + TOBN(0x1f394ee9, 0x70342f9d), TOBN(0x93a10aee, 0x1bc44a14), + TOBN(0xa7eed31b, 0x3efd0baa), TOBN(0x6e7c824e, 0x1d154e65), + TOBN(0xee23fa81, 0x9966e7ee), TOBN(0x64ec4aa8, 0x05b7920d), + TOBN(0x2d44462d, 0x2d90aad4), TOBN(0xf44dd195, 0xdf277ad5), + TOBN(0x8d6471f1, 0xbb46b6a1), TOBN(0x1e65d313, 0xfd885090), + TOBN(0x33a800f5, 0x13a977b4), TOBN(0xaca9d721, 0x0797e1ef), + TOBN(0x9a5a85a0, 0xfcff6a17), TOBN(0x9970a3f3, 0x1eca7cee), + TOBN(0xbb9f0d6b, 0xc9504be3), TOBN(0xe0c504be, 0xadd24ee2), + TOBN(0x7e09d956, 0x77fcc2f4), TOBN(0xef1a5227, 0x65bb5fc4), + TOBN(0x145d4fb1, 0x8b9286aa), TOBN(0x66fd0c5d, 0x6649028b), + TOBN(0x98857ceb, 0x1bf4581c), TOBN(0xe635e186, 0xaca7b166), + TOBN(0x278ddd22, 0x659722ac), TOBN(0xa0903c4c, 0x1db68007), + TOBN(0x366e4589, 0x48f21402), TOBN(0x31b49c14, 0xb96abda2), + TOBN(0x329c4b09, 0xe0403190), TOBN(0x97197ca3, 0xd29f43fe), + TOBN(0x8073dd1e, 0x274983d8), TOBN(0xda1a3bde, 0x55717c8f), + TOBN(0xfd3d4da2, 0x0361f9d1), TOBN(0x1332d081, 0x4c7de1ce), + TOBN(0x9b7ef7a3, 0xaa6d0e10), TOBN(0x17db2e73, 0xf54f1c4a), + TOBN(0xaf3dffae, 0x4cd35567), TOBN(0xaaa2f406, 0xe56f4e71), + TOBN(0x8966759e, 0x7ace3fc7), TOBN(0x9594eacf, 0x45a8d8c6), + TOBN(0x8de3bd8b, 0x91834e0e), TOBN(0xafe4ca53, 0x548c0421), + TOBN(0xfdd7e856, 0xe6ee81c6), TOBN(0x8f671beb, 0x6b891a3a), + TOBN(0xf7a58f2b, 0xfae63829), TOBN(0x9ab186fb, 0x9c11ac9f), + TOBN(0x8d6eb369, 0x10b5be76), TOBN(0x046b7739, 0xfb040bcd), + TOBN(0xccb4529f, 0xcb73de88), TOBN(0x1df0fefc, 0xcf26be03), + TOBN(0xad7757a6, 0xbcfcd027), TOBN(0xa8786c75, 0xbb3165ca), + TOBN(0xe9db1e34, 0x7e99a4d9), TOBN(0x99ee86df, 0xb06c504b), + TOBN(0x5b7c2ddd, 0xc15c9f0a), TOBN(0xdf87a734, 0x4295989e), + TOBN(0x59ece47c, 0x03d08fda), TOBN(0xb074d3dd, 0xad5fc702), + TOBN(0x20407903, 0x51a03776), TOBN(0x2bb1f77b, 0x2a608007), + TOBN(0x25c58f4f, 0xe1153185), TOBN(0xe6df62f6, 0x766e6447), + TOBN(0xefb3d1be, 0xed51275a), TOBN(0x5de47dc7, 0x2f0f483f), + TOBN(0x7932d98e, 0x97c2bedf), TOBN(0xd5c11927, 0x0219f8a1), + TOBN(0x9d751200, 0xa73a294e), TOBN(0x5f88434a, 0x9dc20172), + TOBN(0xd28d9fd3, 0xa26f506a), TOBN(0xa890cd31, 0x9d1dcd48), + TOBN(0x0aebaec1, 0x70f4d3b4), TOBN(0xfd1a1369, 0x0ffc8d00), + TOBN(0xb9d9c240, 0x57d57838), TOBN(0x45929d26, 0x68bac361), + TOBN(0x5a2cd060, 0x25b15ca6), TOBN(0x4b3c83e1, 0x6e474446), + TOBN(0x1aac7578, 0xee1e5134), TOBN(0xa418f5d6, 0xc91e2f41), + TOBN(0x6936fc8a, 0x213ed68b), TOBN(0x860ae7ed, 0x510a5224), + TOBN(0x63660335, 0xdef09b53), TOBN(0x641b2897, 0xcd79c98d), + TOBN(0x29bd38e1, 0x01110f35), TOBN(0x79c26f42, 0x648b1937), + TOBN(0x64dae519, 0x9d9164f4), TOBN(0xd85a2310, 0x0265c273), + TOBN(0x7173dd5d, 0x4b07e2b1), TOBN(0xd144c4cb, 0x8d9ea221), + TOBN(0xe8b04ea4, 0x1105ab14), TOBN(0x92dda542, 0xfe80d8f1), + TOBN(0xe9982fa8, 0xcf03dce6), TOBN(0x8b5ea965, 0x1a22cffc), + TOBN(0xf7f4ea7f, 0x3fad88c4), TOBN(0x62db773e, 0x6a5ba95c), + TOBN(0xd20f02fb, 0x93f24567), TOBN(0xfd46c69a, 0x315257ca), + TOBN(0x0ac74cc7, 0x8bcab987), TOBN(0x46f31c01, 0x5ceca2f5), + TOBN(0x40aedb59, 0x888b219e), TOBN(0xe50ecc37, 0xe1fccd02), + TOBN(0x1bcd9dad, 0x911f816c), TOBN(0x583cc1ec, 0x8db9b00c), + TOBN(0xf3cd2e66, 0xa483bf11), TOBN(0xfa08a6f5, 0xb1b2c169), + TOBN(0xf375e245, 0x4be9fa28), TOBN(0x99a7ffec, 0x5b6d011f), + TOBN(0x6a3ebddb, 0xc4ae62da), TOBN(0x6cea00ae, 0x374aef5d), + TOBN(0xab5fb98d, 0x9d4d05bc), TOBN(0x7cba1423, 0xd560f252), + TOBN(0x49b2cc21, 0x208490de), TOBN(0x1ca66ec3, 0xbcfb2879), + TOBN(0x7f1166b7, 0x1b6fb16f), TOBN(0xfff63e08, 0x65fe5db3), + TOBN(0xb8345abe, 0x8b2610be), TOBN(0xb732ed80, 0x39de3df4), + TOBN(0x0e24ed50, 0x211c32b4), TOBN(0xd10d8a69, 0x848ff27d), + TOBN(0xc1074398, 0xed4de248), TOBN(0xd7cedace, 0x10488927), + TOBN(0xa4aa6bf8, 0x85673e13), TOBN(0xb46bae91, 0x6daf30af), + TOBN(0x07088472, 0xfcef7ad8), TOBN(0x61151608, 0xd4b35e97), + TOBN(0xbcfe8f26, 0xdde29986), TOBN(0xeb84c4c7, 0xd5a34c79), + TOBN(0xc1eec55c, 0x164e1214), TOBN(0x891be86d, 0xa147bb03), + TOBN(0x9fab4d10, 0x0ba96835), TOBN(0xbf01e9b8, 0xa5c1ae9f), + TOBN(0x6b4de139, 0xb186ebc0), TOBN(0xd5c74c26, 0x85b91bca), + TOBN(0x5086a99c, 0xc2d93854), TOBN(0xeed62a7b, 0xa7a9dfbc), + TOBN(0x8778ed6f, 0x76b7618a), TOBN(0xbff750a5, 0x03b66062), + TOBN(0x4cb7be22, 0xb65186db), TOBN(0x369dfbf0, 0xcc3a6d13), + TOBN(0xc7dab26c, 0x7191a321), TOBN(0x9edac3f9, 0x40ed718e), + TOBN(0xbc142b36, 0xd0cfd183), TOBN(0xc8af82f6, 0x7c991693), + TOBN(0xb3d1e4d8, 0x97ce0b2a), TOBN(0xe6d7c87f, 0xc3a55cdf), + TOBN(0x35846b95, 0x68b81afe), TOBN(0x018d12af, 0xd3c239d8), + TOBN(0x2b2c6208, 0x01206e15), TOBN(0xe0e42453, 0xa3b882c6), + TOBN(0x854470a3, 0xa50162d5), TOBN(0x08157478, 0x7017a62a), + TOBN(0x18bd3fb4, 0x820357c7), TOBN(0x992039ae, 0x6f1458ad), + TOBN(0x9a1df3c5, 0x25b44aa1), TOBN(0x2d780357, 0xed3d5281), + TOBN(0x58cf7e4d, 0xc77ad4d4), TOBN(0xd49a7998, 0xf9df4fc4), + TOBN(0x4465a8b5, 0x1d71205e), TOBN(0xa0ee0ea6, 0x649254aa), + TOBN(0x4b5eeecf, 0xab7bd771), TOBN(0x6c873073, 0x35c262b9), + TOBN(0xdc5bd648, 0x3c9d61e7), TOBN(0x233d6d54, 0x321460d2), + TOBN(0xd20c5626, 0xfc195bcc), TOBN(0x25445958, 0x04d78b63), + TOBN(0xe03fcb3d, 0x17ec8ef3), TOBN(0x54b690d1, 0x46b8f781), + TOBN(0x82fa2c8a, 0x21230646), TOBN(0xf51aabb9, 0x084f418c), + TOBN(0xff4fbec1, 0x1a30ba43), TOBN(0x6a5acf73, 0x743c9df7), + TOBN(0x1da2b357, 0xd635b4d5), TOBN(0xc3de68dd, 0xecd5c1da), + TOBN(0xa689080b, 0xd61af0dd), TOBN(0xdea5938a, 0xd665bf99), + TOBN(0x0231d71a, 0xfe637294), TOBN(0x01968aa6, 0xa5a81cd8), + TOBN(0x11252d50, 0x048e63b5), TOBN(0xc446bc52, 0x6ca007e9), + TOBN(0xef8c50a6, 0x96d6134b), TOBN(0x9361fbf5, 0x9e09a05c), + TOBN(0xf17f85a6, 0xdca3291a), TOBN(0xb178d548, 0xff251a21), + TOBN(0x87f6374b, 0xa4df3915), TOBN(0x566ce1bf, 0x2fd5d608), + TOBN(0x425cba4d, 0x7de35102), TOBN(0x6b745f8f, 0x58c5d5e2), + TOBN(0x88402af6, 0x63122edf), TOBN(0x3190f9ed, 0x3b989a89), + TOBN(0x4ad3d387, 0xebba3156), TOBN(0xef385ad9, 0xc7c469a5), + TOBN(0xb08281de, 0x3f642c29), TOBN(0x20be0888, 0x910ffb88), + TOBN(0xf353dd4a, 0xd5292546), TOBN(0x3f1627de, 0x8377a262), + TOBN(0xa5faa013, 0xeefcd638), TOBN(0x8f3bf626, 0x74cc77c3), + TOBN(0x32618f65, 0xa348f55e), TOBN(0x5787c0dc, 0x9fefeb9e), + TOBN(0xf1673aa2, 0xd9a23e44), TOBN(0x88dfa993, 0x4e10690d), + TOBN(0x1ced1b36, 0x2bf91108), TOBN(0x9193ceca, 0x3af48649), + TOBN(0xfb34327d, 0x2d738fc5), TOBN(0x6697b037, 0x975fee6c), + TOBN(0x2f485da0, 0xc04079a5), TOBN(0x2cdf5735, 0x2feaa1ac), + TOBN(0x76944420, 0xbd55659e), TOBN(0x7973e32b, 0x4376090c), + TOBN(0x86bb4fe1, 0x163b591a), TOBN(0x10441aed, 0xc196f0ca), + TOBN(0x3b431f4a, 0x045ad915), TOBN(0x6c11b437, 0xa4afacb1), + TOBN(0x30b0c7db, 0x71fdbbd8), TOBN(0xb642931f, 0xeda65acd), + TOBN(0x4baae6e8, 0x9c92b235), TOBN(0xa73bbd0e, 0x6b3993a1), + TOBN(0xd06d60ec, 0x693dd031), TOBN(0x03cab91b, 0x7156881c), + TOBN(0xd615862f, 0x1db3574b), TOBN(0x485b0185, 0x64bb061a), + TOBN(0x27434988, 0xa0181e06), TOBN(0x2cd61ad4, 0xc1c0c757), + TOBN(0x3effed5a, 0x2ff9f403), TOBN(0x8dc98d8b, 0x62239029), + TOBN(0x2206021e, 0x1f17b70d), TOBN(0xafbec0ca, 0xbf510015), + TOBN(0x9fed7164, 0x80130dfa), TOBN(0x306dc2b5, 0x8a02dcf5), + TOBN(0x48f06620, 0xfeb10fc0), TOBN(0x78d1e1d5, 0x5a57cf51), + TOBN(0xadef8c5a, 0x192ef710), TOBN(0x88afbd4b, 0x3b7431f9), + TOBN(0x7e1f7407, 0x64250c9e), TOBN(0x6e31318d, 0xb58bec07), + TOBN(0xfd4fc4b8, 0x24f89b4e), TOBN(0x65a5dd88, 0x48c36a2a), + TOBN(0x4f1eccff, 0xf024baa7), TOBN(0x22a21cf2, 0xcba94650), + TOBN(0x95d29dee, 0x42a554f7), TOBN(0x828983a5, 0x002ec4ba), + TOBN(0x8112a1f7, 0x8badb73d), TOBN(0x79ea8897, 0xa27c1839), + TOBN(0x8969a5a7, 0xd065fd83), TOBN(0xf49af791, 0xb262a0bc), + TOBN(0xfcdea8b6, 0xaf2b5127), TOBN(0x10e913e1, 0x564c2dbc), + TOBN(0x51239d14, 0xbc21ef51), TOBN(0xe51c3ceb, 0x4ce57292), + TOBN(0x795ff068, 0x47bbcc3b), TOBN(0x86b46e1e, 0xbd7e11e6), + TOBN(0x0ea6ba23, 0x80041ef4), TOBN(0xd72fe505, 0x6262342e), + TOBN(0x8abc6dfd, 0x31d294d4), TOBN(0xbbe017a2, 0x1278c2c9), + TOBN(0xb1fcfa09, 0xb389328a), TOBN(0x322fbc62, 0xd01771b5), + TOBN(0x04c0d063, 0x60b045bf), TOBN(0xdb652edc, 0x10e52d01), + TOBN(0x50ef932c, 0x03ec6627), TOBN(0xde1b3b2d, 0xc1ee50e3), + TOBN(0x5ab7bdc5, 0xdc37a90d), TOBN(0xfea67213, 0x31e33a96), + TOBN(0x6482b5cb, 0x4f2999aa), TOBN(0x38476cc6, 0xb8cbf0dd), + TOBN(0x93ebfacb, 0x173405bb), TOBN(0x15cdafe7, 0xe52369ec), + TOBN(0xd42d5ba4, 0xd935b7db), TOBN(0x648b6004, 0x1c99a4cd), + TOBN(0x785101bd, 0xa3b5545b), TOBN(0x4bf2c38a, 0x9dd67faf), + TOBN(0xb1aadc63, 0x4442449c), TOBN(0xe0e9921a, 0x33ad4fb8), + TOBN(0x5c552313, 0xaa686d82), TOBN(0xdee635fa, 0x465d866c), + TOBN(0xbc3c224a, 0x18ee6e8a), TOBN(0xeed748a6, 0xed42e02f), + TOBN(0xe70f930a, 0xd474cd08), TOBN(0x774ea6ec, 0xfff24adf), + TOBN(0x03e2de1c, 0xf3480d4a), TOBN(0xf0d8edc7, 0xbc8acf1a), + TOBN(0xf23e3303, 0x68295a9c), TOBN(0xfadd5f68, 0xc546a97d), + TOBN(0x895597ad, 0x96f8acb1), TOBN(0xbddd49d5, 0x671bdae2), + TOBN(0x16fcd528, 0x21dd43f4), TOBN(0xa5a45412, 0x6619141a)}, + {TOBN(0x8ce9b6bf, 0xc360e25a), TOBN(0xe6425195, 0x075a1a78), + TOBN(0x9dc756a8, 0x481732f4), TOBN(0x83c0440f, 0x5432b57a), + TOBN(0xc670b3f1, 0xd720281f), TOBN(0x2205910e, 0xd135e051), + TOBN(0xded14b0e, 0xdb052be7), TOBN(0x697b3d27, 0xc568ea39), + TOBN(0x2e599b9a, 0xfb3ff9ed), TOBN(0x28c2e0ab, 0x17f6515c), + TOBN(0x1cbee4fd, 0x474da449), TOBN(0x071279a4, 0x4f364452), + TOBN(0x97abff66, 0x01fbe855), TOBN(0x3ee394e8, 0x5fda51c4), + TOBN(0x190385f6, 0x67597c0b), TOBN(0x6e9fccc6, 0xa27ee34b), + TOBN(0x0b89de93, 0x14092ebb), TOBN(0xf17256bd, 0x428e240c), + TOBN(0xcf89a7f3, 0x93d2f064), TOBN(0x4f57841e, 0xe1ed3b14), + TOBN(0x4ee14405, 0xe708d855), TOBN(0x856aae72, 0x03f1c3d0), + TOBN(0xc8e5424f, 0xbdd7eed5), TOBN(0x3333e4ef, 0x73ab4270), + TOBN(0x3bc77ade, 0xdda492f8), TOBN(0xc11a3aea, 0x78297205), + TOBN(0x5e89a3e7, 0x34931b4c), TOBN(0x17512e2e, 0x9f5694bb), + TOBN(0x5dc349f3, 0x177bf8b6), TOBN(0x232ea4ba, 0x08c7ff3e), + TOBN(0x9c4f9d16, 0xf511145d), TOBN(0xccf109a3, 0x33b379c3), + TOBN(0xe75e7a88, 0xa1f25897), TOBN(0x7ac6961f, 0xa1b5d4d8), + TOBN(0xe3e10773, 0x08f3ed5c), TOBN(0x208a54ec, 0x0a892dfb), + TOBN(0xbe826e19, 0x78660710), TOBN(0x0cf70a97, 0x237df2c8), + TOBN(0x418a7340, 0xed704da5), TOBN(0xa3eeb9a9, 0x08ca33fd), + TOBN(0x49d96233, 0x169bca96), TOBN(0x04d286d4, 0x2da6aafb), + TOBN(0xc09606ec, 0xa0c2fa94), TOBN(0x8869d0d5, 0x23ff0fb3), + TOBN(0xa99937e5, 0xd0150d65), TOBN(0xa92e2503, 0x240c14c9), + TOBN(0x656bf945, 0x108e2d49), TOBN(0x152a733a, 0xa2f59e2b), + TOBN(0xb4323d58, 0x8434a920), TOBN(0xc0af8e93, 0x622103c5), + TOBN(0x667518ef, 0x938dbf9a), TOBN(0xa1843073, 0x83a9cdf2), + TOBN(0x350a94aa, 0x5447ab80), TOBN(0xe5e5a325, 0xc75a3d61), + TOBN(0x74ba507f, 0x68411a9e), TOBN(0x10581fc1, 0x594f70c5), + TOBN(0x60e28570, 0x80eb24a9), TOBN(0x7bedfb4d, 0x488e0cfd), + TOBN(0x721ebbd7, 0xc259cdb8), TOBN(0x0b0da855, 0xbc6390a9), + TOBN(0x2b4d04db, 0xde314c70), TOBN(0xcdbf1fbc, 0x6c32e846), + TOBN(0x33833eab, 0xb162fc9e), TOBN(0x9939b48b, 0xb0dd3ab7), + TOBN(0x5aaa98a7, 0xcb0c9c8c), TOBN(0x75105f30, 0x81c4375c), + TOBN(0xceee5057, 0x5ef1c90f), TOBN(0xb31e065f, 0xc23a17bf), + TOBN(0x5364d275, 0xd4b6d45a), TOBN(0xd363f3ad, 0x62ec8996), + TOBN(0xb5d21239, 0x4391c65b), TOBN(0x84564765, 0xebb41b47), + TOBN(0x20d18ecc, 0x37107c78), TOBN(0xacff3b6b, 0x570c2a66), + TOBN(0x22f975d9, 0x9bd0d845), TOBN(0xef0a0c46, 0xba178fa0), + TOBN(0x1a419651, 0x76b6028e), TOBN(0xc49ec674, 0x248612d4), + TOBN(0x5b6ac4f2, 0x7338af55), TOBN(0x06145e62, 0x7bee5a36), + TOBN(0x33e95d07, 0xe75746b5), TOBN(0x1c1e1f6d, 0xc40c78be), + TOBN(0x967833ef, 0x222ff8e2), TOBN(0x4bedcf6a, 0xb49180ad), + TOBN(0x6b37e9c1, 0x3d7a4c8a), TOBN(0x2748887c, 0x6ddfe760), + TOBN(0xf7055123, 0xaa3a5bbc), TOBN(0x954ff225, 0x7bbb8e74), + TOBN(0xc42b8ab1, 0x97c3dfb9), TOBN(0x55a549b0, 0xcf168154), + TOBN(0xad6748e7, 0xc1b50692), TOBN(0x2775780f, 0x6fc5cbcb), + TOBN(0x4eab80b8, 0xe1c9d7c8), TOBN(0x8c69dae1, 0x3fdbcd56), + TOBN(0x47e6b4fb, 0x9969eace), TOBN(0x002f1085, 0xa705cb5a), + TOBN(0x4e23ca44, 0x6d3fea55), TOBN(0xb4ae9c86, 0xf4810568), + TOBN(0x47bfb91b, 0x2a62f27d), TOBN(0x60deb4c9, 0xd9bac28c), + TOBN(0xa892d894, 0x7de6c34c), TOBN(0x4ee68259, 0x4494587d), + TOBN(0x914ee14e, 0x1a3f8a5b), TOBN(0xbb113eaa, 0x28700385), + TOBN(0x81ca03b9, 0x2115b4c9), TOBN(0x7c163d38, 0x8908cad1), + TOBN(0xc912a118, 0xaa18179a), TOBN(0xe09ed750, 0x886e3081), + TOBN(0xa676e3fa, 0x26f516ca), TOBN(0x753cacf7, 0x8e732f91), + TOBN(0x51592aea, 0x833da8b4), TOBN(0xc626f42f, 0x4cbea8aa), + TOBN(0xef9dc899, 0xa7b56eaf), TOBN(0x00c0e52c, 0x34ef7316), + TOBN(0x5b1e4e24, 0xfe818a86), TOBN(0x9d31e20d, 0xc538be47), + TOBN(0x22eb932d, 0x3ed68974), TOBN(0xe44bbc08, 0x7c4e87c4), + TOBN(0x4121086e, 0x0dde9aef), TOBN(0x8e6b9cff, 0x134f4345), + TOBN(0x96892c1f, 0x711b0eb9), TOBN(0xb905f2c8, 0x780ab954), + TOBN(0xace26309, 0xa20792db), TOBN(0xec8ac9b3, 0x0684e126), + TOBN(0x486ad8b6, 0xb40a2447), TOBN(0x60121fc1, 0x9fe3fb24), + TOBN(0x5626fccf, 0x1a8e3b3f), TOBN(0x4e568622, 0x6ad1f394), + TOBN(0xda7aae0d, 0x196aa5a1), TOBN(0xe0df8c77, 0x1041b5fb), + TOBN(0x451465d9, 0x26b318b7), TOBN(0xc29b6e55, 0x7ab136e9), + TOBN(0x2c2ab48b, 0x71148463), TOBN(0xb5738de3, 0x64454a76), + TOBN(0x54ccf9a0, 0x5a03abe4), TOBN(0x377c0296, 0x0427d58e), + TOBN(0x73f5f0b9, 0x2bb39c1f), TOBN(0x14373f2c, 0xe608d8c5), + TOBN(0xdcbfd314, 0x00fbb805), TOBN(0xdf18fb20, 0x83afdcfb), + TOBN(0x81a57f42, 0x42b3523f), TOBN(0xe958532d, 0x87f650fb), + TOBN(0xaa8dc8b6, 0x8b0a7d7c), TOBN(0x1b75dfb7, 0x150166be), + TOBN(0x90e4f7c9, 0x2d7d1413), TOBN(0x67e2d6b5, 0x9834f597), + TOBN(0x4fd4f4f9, 0xa808c3e8), TOBN(0xaf8237e0, 0xd5281ec1), + TOBN(0x25ab5fdc, 0x84687cee), TOBN(0xc5ded6b1, 0xa5b26c09), + TOBN(0x8e4a5aec, 0xc8ea7650), TOBN(0x23b73e5c, 0x14cc417f), + TOBN(0x2bfb4318, 0x3037bf52), TOBN(0xb61e6db5, 0x78c725d7), + TOBN(0x8efd4060, 0xbbb3e5d7), TOBN(0x2e014701, 0xdbac488e), + TOBN(0xac75cf9a, 0x360aa449), TOBN(0xb70cfd05, 0x79634d08), + TOBN(0xa591536d, 0xfffb15ef), TOBN(0xb2c37582, 0xd07c106c), + TOBN(0xb4293fdc, 0xf50225f9), TOBN(0xc52e175c, 0xb0e12b03), + TOBN(0xf649c3ba, 0xd0a8bf64), TOBN(0x745a8fef, 0xeb8ae3c6), + TOBN(0x30d7e5a3, 0x58321bc3), TOBN(0xb1732be7, 0x0bc4df48), + TOBN(0x1f217993, 0xe9ea5058), TOBN(0xf7a71cde, 0x3e4fd745), + TOBN(0x86cc533e, 0x894c5bbb), TOBN(0x6915c7d9, 0x69d83082), + TOBN(0xa6aa2d05, 0x5815c244), TOBN(0xaeeee592, 0x49b22ce5), + TOBN(0x89e39d13, 0x78135486), TOBN(0x3a275c1f, 0x16b76f2f), + TOBN(0xdb6bcc1b, 0xe036e8f5), TOBN(0x4df69b21, 0x5e4709f5), + TOBN(0xa188b250, 0x2d0f39aa), TOBN(0x622118bb, 0x15a85947), + TOBN(0x2ebf520f, 0xfde0f4fa), TOBN(0xa40e9f29, 0x4860e539), + TOBN(0x7b6a51eb, 0x22b57f0f), TOBN(0x849a33b9, 0x7e80644a), + TOBN(0x50e5d16f, 0x1cf095fe), TOBN(0xd754b54e, 0xec55f002), + TOBN(0x5cfbbb22, 0x236f4a98), TOBN(0x0b0c59e9, 0x066800bb), + TOBN(0x4ac69a8f, 0x5a9a7774), TOBN(0x2b33f804, 0xd6bec948), + TOBN(0xb3729295, 0x32e6c466), TOBN(0x68956d0f, 0x4e599c73), + TOBN(0xa47a249f, 0x155c31cc), TOBN(0x24d80f0d, 0xe1ce284e), + TOBN(0xcd821dfb, 0x988baf01), TOBN(0xe6331a7d, 0xdbb16647), + TOBN(0x1eb8ad33, 0x094cb960), TOBN(0x593cca38, 0xc91bbca5), + TOBN(0x384aac8d, 0x26567456), TOBN(0x40fa0309, 0xc04b6490), + TOBN(0x97834cd6, 0xdab6c8f6), TOBN(0x68a7318d, 0x3f91e55f), + TOBN(0xa00fd04e, 0xfc4d3157), TOBN(0xb56f8ab2, 0x2bf3bdea), + TOBN(0x014f5648, 0x4fa57172), TOBN(0x948c5860, 0x450abdb3), + TOBN(0x342b5df0, 0x0ebd4f08), TOBN(0x3e5168cd, 0x0e82938e), + TOBN(0x7aedc1ce, 0xb0df5dd0), TOBN(0x6bbbc6d9, 0xe5732516), + TOBN(0xc7bfd486, 0x605daaa6), TOBN(0x46fd72b7, 0xbb9a6c9e), + TOBN(0xe4847fb1, 0xa124fb89), TOBN(0x75959cbd, 0xa2d8ffbc), + TOBN(0x42579f65, 0xc8a588ee), TOBN(0x368c92e6, 0xb80b499d), + TOBN(0xea4ef6cd, 0x999a5df1), TOBN(0xaa73bb7f, 0x936fe604), + TOBN(0xf347a70d, 0x6457d188), TOBN(0x86eda86b, 0x8b7a388b), + TOBN(0xb7cdff06, 0x0ccd6013), TOBN(0xbeb1b6c7, 0xd0053fb2), + TOBN(0x0b022387, 0x99240a9f), TOBN(0x1bbb384f, 0x776189b2), + TOBN(0x8695e71e, 0x9066193a), TOBN(0x2eb50097, 0x06ffac7e), + TOBN(0x0654a9c0, 0x4a7d2caa), TOBN(0x6f3fb3d1, 0xa5aaa290), + TOBN(0x835db041, 0xff476e8f), TOBN(0x540b8b0b, 0xc42295e4), + TOBN(0xa5c73ac9, 0x05e214f5), TOBN(0x9a74075a, 0x56a0b638), + TOBN(0x2e4b1090, 0xce9e680b), TOBN(0x57a5b479, 0x6b8d9afa), + TOBN(0x0dca48e7, 0x26bfe65c), TOBN(0x097e391c, 0x7290c307), + TOBN(0x683c462e, 0x6669e72e), TOBN(0xf505be1e, 0x062559ac), + TOBN(0x5fbe3ea1, 0xe3a3035a), TOBN(0x6431ebf6, 0x9cd50da8), + TOBN(0xfd169d5c, 0x1f6407f2), TOBN(0x8d838a95, 0x60fce6b8), + TOBN(0x2a2bfa7f, 0x650006f0), TOBN(0xdfd7dad3, 0x50c0fbb2), + TOBN(0x92452495, 0xccf9ad96), TOBN(0x183bf494, 0xd95635f9), + TOBN(0x02d5df43, 0x4a7bd989), TOBN(0x505385cc, 0xa5431095), + TOBN(0xdd98e67d, 0xfd43f53e), TOBN(0xd61e1a6c, 0x500c34a9), + TOBN(0x5a4b46c6, 0x4a8a3d62), TOBN(0x8469c4d0, 0x247743d2), + TOBN(0x2bb3a13d, 0x88f7e433), TOBN(0x62b23a10, 0x01be5849), + TOBN(0xe83596b4, 0xa63d1a4c), TOBN(0x454e7fea, 0x7d183f3e), + TOBN(0x643fce61, 0x17afb01c), TOBN(0x4e65e5e6, 0x1c4c3638), + TOBN(0x41d85ea1, 0xef74c45b), TOBN(0x2cfbfa66, 0xae328506), + TOBN(0x98b078f5, 0x3ada7da9), TOBN(0xd985fe37, 0xec752fbb), + TOBN(0xeece68fe, 0x5a0148b4), TOBN(0x6f9a55c7, 0x2d78136d), + TOBN(0x232dccc4, 0xd2b729ce), TOBN(0xa27e0dfd, 0x90aafbc4), + TOBN(0x96474452, 0x12b4603e), TOBN(0xa876c551, 0x6b706d14), + TOBN(0xdf145fcf, 0x69a9d412), TOBN(0xe2ab75b7, 0x2d479c34), + TOBN(0x12df9a76, 0x1a23ff97), TOBN(0xc6138992, 0x5d359d10), + TOBN(0x6e51c7ae, 0xfa835f22), TOBN(0x69a79cb1, 0xc0fcc4d9), + TOBN(0xf57f350d, 0x594cc7e1), TOBN(0x3079ca63, 0x3350ab79), + TOBN(0x226fb614, 0x9aff594a), TOBN(0x35afec02, 0x6d59a62b), + TOBN(0x9bee46f4, 0x06ed2c6e), TOBN(0x58da1735, 0x7d939a57), + TOBN(0x44c50402, 0x8fd1797e), TOBN(0xd8853e7c, 0x5ccea6ca), + TOBN(0x4065508d, 0xa35fcd5f), TOBN(0x8965df8c, 0x495ccaeb), + TOBN(0x0f2da850, 0x12e1a962), TOBN(0xee471b94, 0xc1cf1cc4), + TOBN(0xcef19bc8, 0x0a08fb75), TOBN(0x704958f5, 0x81de3591), + TOBN(0x2867f8b2, 0x3aef4f88), TOBN(0x8d749384, 0xea9f9a5f), + TOBN(0x1b385537, 0x8c9049f4), TOBN(0x5be948f3, 0x7b92d8b6), + TOBN(0xd96f725d, 0xb6e2bd6b), TOBN(0x37a222bc, 0x958c454d), + TOBN(0xe7c61abb, 0x8809bf61), TOBN(0x46f07fbc, 0x1346f18d), + TOBN(0xfb567a7a, 0xe87c0d1c), TOBN(0x84a461c8, 0x7ef3d07a), + TOBN(0x0a5adce6, 0xd9278d98), TOBN(0x24d94813, 0x9dfc73e1), + TOBN(0x4f3528b6, 0x054321c3), TOBN(0x2e03fdde, 0x692ea706), + TOBN(0x10e60619, 0x47b533c0), TOBN(0x1a8bc73f, 0x2ca3c055), + TOBN(0xae58d4b2, 0x1bb62b8f), TOBN(0xb2045a73, 0x584a24e3), + TOBN(0x3ab3d5af, 0xbd76e195), TOBN(0x478dd1ad, 0x6938a810), + TOBN(0x6ffab393, 0x6ee3d5cb), TOBN(0xdfb693db, 0x22b361e4), + TOBN(0xf9694496, 0x51dbf1a7), TOBN(0xcab4b4ef, 0x08a2e762), + TOBN(0xe8c92f25, 0xd39bba9a), TOBN(0x850e61bc, 0xf1464d96), + TOBN(0xb7e830e3, 0xdc09508b), TOBN(0xfaf6d2cf, 0x74317655), + TOBN(0x72606ceb, 0xdf690355), TOBN(0x48bb92b3, 0xd0c3ded6), + TOBN(0x65b75484, 0x5c7cf892), TOBN(0xf6cd7ac9, 0xd5d5f01f), + TOBN(0xc2c30a59, 0x96401d69), TOBN(0x91268650, 0xed921878), + TOBN(0x380bf913, 0xb78c558f), TOBN(0x43c0baeb, 0xc8afdaa9), + TOBN(0x377f61d5, 0x54f169d3), TOBN(0xf8da07e3, 0xae5ff20b), + TOBN(0xb676c49d, 0xa8a90ea8), TOBN(0x81c1ff2b, 0x83a29b21), + TOBN(0x383297ac, 0x2ad8d276), TOBN(0x3001122f, 0xba89f982), + TOBN(0xe1d794be, 0x6718e448), TOBN(0x246c1482, 0x7c3e6e13), + TOBN(0x56646ef8, 0x5d26b5ef), TOBN(0x80f5091e, 0x88069cdd), + TOBN(0xc5992e2f, 0x724bdd38), TOBN(0x02e915b4, 0x8471e8c7), + TOBN(0x96ff320a, 0x0d0ff2a9), TOBN(0xbf886487, 0x4384d1a0), + TOBN(0xbbe1e6a6, 0xc93f72d6), TOBN(0xd5f75d12, 0xcad800ea), + TOBN(0xfa40a09f, 0xe7acf117), TOBN(0x32c8cdd5, 0x7581a355), + TOBN(0x74221992, 0x7023c499), TOBN(0xa8afe5d7, 0x38ec3901), + TOBN(0x5691afcb, 0xa90e83f0), TOBN(0x41bcaa03, 0x0b8f8eac), + TOBN(0xe38b5ff9, 0x8d2668d5), TOBN(0x0715281a, 0x7ad81965), + TOBN(0x1bc8fc7c, 0x03c6ce11), TOBN(0xcbbee6e2, 0x8b650436), + TOBN(0x06b00fe8, 0x0cdb9808), TOBN(0x17d6e066, 0xfe3ed315), + TOBN(0x2e9d38c6, 0x4d0b5018), TOBN(0xab8bfd56, 0x844dcaef), + TOBN(0x42894a59, 0x513aed8b), TOBN(0xf77f3b6d, 0x314bd07a), + TOBN(0xbbdecb8f, 0x8e42b582), TOBN(0xf10e2fa8, 0xd2390fe6), + TOBN(0xefb95022, 0x62a2f201), TOBN(0x4d59ea50, 0x50ee32b0), + TOBN(0xd87f7728, 0x6da789a8), TOBN(0xcf98a2cf, 0xf79492c4), + TOBN(0xf9577239, 0x720943c2), TOBN(0xba044cf5, 0x3990b9d0), + TOBN(0x5aa8e823, 0x95f2884a), TOBN(0x834de6ed, 0x0278a0af), + TOBN(0xc8e1ee9a, 0x5f25bd12), TOBN(0x9259ceaa, 0x6f7ab271), + TOBN(0x7e6d97a2, 0x77d00b76), TOBN(0x5c0c6eea, 0xa437832a), + TOBN(0x5232c20f, 0x5606b81d), TOBN(0xabd7b375, 0x0d991ee5), + TOBN(0x4d2bfe35, 0x8632d951), TOBN(0x78f85146, 0x98ed9364), + TOBN(0x951873f0, 0xf30c3282), TOBN(0x0da8ac80, 0xa789230b), + TOBN(0x3ac7789c, 0x5398967f), TOBN(0xa69b8f7f, 0xbdda0fb5), + TOBN(0xe5db7717, 0x6add8545), TOBN(0x1b71cb66, 0x72c49b66), + TOBN(0xd8560739, 0x68421d77), TOBN(0x03840fe8, 0x83e3afea), + TOBN(0xb391dad5, 0x1ec69977), TOBN(0xae243fb9, 0x307f6726), + TOBN(0xc88ac87b, 0xe8ca160c), TOBN(0x5174cced, 0x4ce355f4), + TOBN(0x98a35966, 0xe58ba37d), TOBN(0xfdcc8da2, 0x7817335d), + TOBN(0x5b752830, 0x83fbc7bf), TOBN(0x68e419d4, 0xd9c96984), + TOBN(0x409a39f4, 0x02a40380), TOBN(0x88940faf, 0x1fe977bc), + TOBN(0xc640a94b, 0x8f8edea6), TOBN(0x1e22cd17, 0xed11547d), + TOBN(0xe28568ce, 0x59ffc3e2), TOBN(0x60aa1b55, 0xc1dee4e7), + TOBN(0xc67497c8, 0x837cb363), TOBN(0x06fb438a, 0x105a2bf2), + TOBN(0x30357ec4, 0x500d8e20), TOBN(0x1ad9095d, 0x0670db10), + TOBN(0x7f589a05, 0xc73b7cfd), TOBN(0xf544607d, 0x880d6d28), + TOBN(0x17ba93b1, 0xa20ef103), TOBN(0xad859130, 0x6ba6577b), + TOBN(0x65c91cf6, 0x6fa214a0), TOBN(0xd7d49c6c, 0x27990da5), + TOBN(0xecd9ec8d, 0x20bb569d), TOBN(0xbd4b2502, 0xeeffbc33), + TOBN(0x2056ca5a, 0x6bed0467), TOBN(0x7916a1f7, 0x5b63728c), + TOBN(0xd4f9497d, 0x53a4f566), TOBN(0x89734664, 0x97b56810), + TOBN(0xf8e1da74, 0x0494a621), TOBN(0x82546a93, 0x8d011c68), + TOBN(0x1f3acb19, 0xc61ac162), TOBN(0x52f8fa9c, 0xabad0d3e), + TOBN(0x15356523, 0xb4b7ea43), TOBN(0x5a16ad61, 0xae608125), + TOBN(0xb0bcb87f, 0x4faed184), TOBN(0x5f236b1d, 0x5029f45f), + TOBN(0xd42c7607, 0x0bc6b1fc), TOBN(0xc644324e, 0x68aefce3), + TOBN(0x8e191d59, 0x5c5d8446), TOBN(0xc0208077, 0x13ae1979), + TOBN(0xadcaee55, 0x3ba59cc7), TOBN(0x20ed6d6b, 0xa2cb81ba), + TOBN(0x0952ba19, 0xb6efcffc), TOBN(0x60f12d68, 0x97c0b87c), + TOBN(0x4ee2c7c4, 0x9caa30bc), TOBN(0x767238b7, 0x97fbff4e), + TOBN(0xebc73921, 0x501b5d92), TOBN(0x3279e3df, 0xc2a37737), + TOBN(0x9fc12bc8, 0x6d197543), TOBN(0xfa94dc6f, 0x0a40db4e), + TOBN(0x7392b41a, 0x530ccbbd), TOBN(0x87c82146, 0xea823525), + TOBN(0xa52f984c, 0x05d98d0c), TOBN(0x2ae57d73, 0x5ef6974c), + TOBN(0x9377f7bf, 0x3042a6dd), TOBN(0xb1a007c0, 0x19647a64), + TOBN(0xfaa9079a, 0x0cca9767), TOBN(0x3d81a25b, 0xf68f72d5), + TOBN(0x752067f8, 0xff81578e), TOBN(0x78622150, 0x9045447d), + TOBN(0xc0c22fcf, 0x0505aa6f), TOBN(0x1030f0a6, 0x6bed1c77), + TOBN(0x31f29f15, 0x1f0bd739), TOBN(0x2d7989c7, 0xe6debe85), + TOBN(0x5c070e72, 0x8e677e98), TOBN(0x0a817bd3, 0x06e81fd5), + TOBN(0xc110d830, 0xb0f2ac95), TOBN(0x48d0995a, 0xab20e64e), + TOBN(0x0f3e00e1, 0x7729cd9a), TOBN(0x2a570c20, 0xdd556946), + TOBN(0x912dbcfd, 0x4e86214d), TOBN(0x2d014ee2, 0xcf615498), + TOBN(0x55e2b1e6, 0x3530d76e), TOBN(0xc5135ae4, 0xfd0fd6d1), + TOBN(0x0066273a, 0xd4f3049f), TOBN(0xbb8e9893, 0xe7087477), + TOBN(0x2dba1ddb, 0x14c6e5fd), TOBN(0xdba37886, 0x51f57e6c), + TOBN(0x5aaee0a6, 0x5a72f2cf), TOBN(0x1208bfbf, 0x7bea5642), + TOBN(0xf5c6aa3b, 0x67872c37), TOBN(0xd726e083, 0x43f93224), + TOBN(0x1854daa5, 0x061f1658), TOBN(0xc0016df1, 0xdf0cd2b3), + TOBN(0xc2a3f23e, 0x833d50de), TOBN(0x73b681d2, 0xbbbd3017), + TOBN(0x2f046dc4, 0x3ac343c0), TOBN(0x9c847e7d, 0x85716421), + TOBN(0xe1e13c91, 0x0917eed4), TOBN(0x3fc9eebd, 0x63a1b9c6), + TOBN(0x0f816a72, 0x7fe02299), TOBN(0x6335ccc2, 0x294f3319), + TOBN(0x3820179f, 0x4745c5be), TOBN(0xe647b782, 0x922f066e), + TOBN(0xc22e49de, 0x02cafb8a), TOBN(0x299bc2ff, 0xfcc2eccc), + TOBN(0x9a8feea2, 0x6e0e8282), TOBN(0xa627278b, 0xfe893205), + TOBN(0xa7e19733, 0x7933e47b), TOBN(0xf4ff6b13, 0x2e766402), + TOBN(0xa4d8be0a, 0x98440d9f), TOBN(0x658f5c2f, 0x38938808), + TOBN(0x90b75677, 0xc95b3b3e), TOBN(0xfa044269, 0x3137b6ff), + TOBN(0x077b039b, 0x43c47c29), TOBN(0xcca95dd3, 0x8a6445b2), + TOBN(0x0b498ba4, 0x2333fc4c), TOBN(0x274f8e68, 0xf736a1b1), + TOBN(0x6ca348fd, 0x5f1d4b2e), TOBN(0x24d3be78, 0xa8f10199), + TOBN(0x8535f858, 0xca14f530), TOBN(0xa6e7f163, 0x5b982e51), + TOBN(0x847c8512, 0x36e1bf62), TOBN(0xf6a7c58e, 0x03448418), + TOBN(0x583f3703, 0xf9374ab6), TOBN(0x864f9195, 0x6e564145), + TOBN(0x33bc3f48, 0x22526d50), TOBN(0x9f323c80, 0x1262a496), + TOBN(0xaa97a7ae, 0x3f046a9a), TOBN(0x70da183e, 0xdf8a039a), + TOBN(0x5b68f71c, 0x52aa0ba6), TOBN(0x9be0fe51, 0x21459c2d), + TOBN(0xc1e17eb6, 0xcbc613e5), TOBN(0x33131d55, 0x497ea61c), + TOBN(0x2f69d39e, 0xaf7eded5), TOBN(0x73c2f434, 0xde6af11b), + TOBN(0x4ca52493, 0xa4a375fa), TOBN(0x5f06787c, 0xb833c5c2), + TOBN(0x814e091f, 0x3e6e71cf), TOBN(0x76451f57, 0x8b746666)}, + {TOBN(0x80f9bdef, 0x694db7e0), TOBN(0xedca8787, 0xb9fcddc6), + TOBN(0x51981c34, 0x03b8dce1), TOBN(0x4274dcf1, 0x70e10ba1), + TOBN(0xf72743b8, 0x6def6d1a), TOBN(0xd25b1670, 0xebdb1866), + TOBN(0xc4491e8c, 0x050c6f58), TOBN(0x2be2b2ab, 0x87fbd7f5), + TOBN(0x3e0e5c9d, 0xd111f8ec), TOBN(0xbcc33f8d, 0xb7c4e760), + TOBN(0x702f9a91, 0xbd392a51), TOBN(0x7da4a795, 0xc132e92d), + TOBN(0x1a0b0ae3, 0x0bb1151b), TOBN(0x54febac8, 0x02e32251), + TOBN(0xea3a5082, 0x694e9e78), TOBN(0xe58ffec1, 0xe4fe40b8), + TOBN(0xf85592fc, 0xd1e0cf9e), TOBN(0xdea75f0d, 0xc0e7b2e8), + TOBN(0xc04215cf, 0xc135584e), TOBN(0x174fc727, 0x2f57092a), + TOBN(0xe7277877, 0xeb930bea), TOBN(0x504caccb, 0x5eb02a5a), + TOBN(0xf9fe08f7, 0xf5241b9b), TOBN(0xe7fb62f4, 0x8d5ca954), + TOBN(0xfbb8349d, 0x29c4120b), TOBN(0x9f94391f, 0xc0d0d915), + TOBN(0xc4074fa7, 0x5410ba51), TOBN(0xa66adbf6, 0x150a5911), + TOBN(0xc164543c, 0x34bfca38), TOBN(0xe0f27560, 0xb9e1ccfc), + TOBN(0x99da0f53, 0xe820219c), TOBN(0xe8234498, 0xc6b4997a), + TOBN(0xcfb88b76, 0x9d4c5423), TOBN(0x9e56eb10, 0xb0521c49), + TOBN(0x418e0b5e, 0xbe8700a1), TOBN(0x00cbaad6, 0xf93cb58a), + TOBN(0xe923fbde, 0xd92a5e67), TOBN(0xca4979ac, 0x1f347f11), + TOBN(0x89162d85, 0x6bc0585b), TOBN(0xdd6254af, 0xac3c70e3), + TOBN(0x7b23c513, 0x516e19e4), TOBN(0x56e2e847, 0xc5c4d593), + TOBN(0x9f727d73, 0x5ce71ef6), TOBN(0x5b6304a6, 0xf79a44c5), + TOBN(0x6638a736, 0x3ab7e433), TOBN(0x1adea470, 0xfe742f83), + TOBN(0xe054b854, 0x5b7fc19f), TOBN(0xf935381a, 0xba1d0698), + TOBN(0x546eab2d, 0x799e9a74), TOBN(0x96239e0e, 0xa949f729), + TOBN(0xca274c6b, 0x7090055a), TOBN(0x835142c3, 0x9020c9b0), + TOBN(0xa405667a, 0xa2e8807f), TOBN(0x29f2c085, 0x1aa3d39e), + TOBN(0xcc555d64, 0x42fc72f5), TOBN(0xe856e0e7, 0xfbeacb3c), + TOBN(0xb5504f9d, 0x918e4936), TOBN(0x65035ef6, 0xb2513982), + TOBN(0x0553a0c2, 0x6f4d9cb9), TOBN(0x6cb10d56, 0xbea85509), + TOBN(0x48d957b7, 0xa242da11), TOBN(0x16a4d3dd, 0x672b7268), + TOBN(0x3d7e637c, 0x8502a96b), TOBN(0x27c7032b, 0x730d463b), + TOBN(0xbdc02b18, 0xe4136a14), TOBN(0xbacf969d, 0x678e32bf), + TOBN(0xc98d89a3, 0xdd9c3c03), TOBN(0x7b92420a, 0x23becc4f), + TOBN(0xd4b41f78, 0xc64d565c), TOBN(0x9f969d00, 0x10f28295), + TOBN(0xec7f7f76, 0xb13d051a), TOBN(0x08945e1e, 0xa92da585), + TOBN(0x55366b7d, 0x5846426f), TOBN(0xe7d09e89, 0x247d441d), + TOBN(0x510b404d, 0x736fbf48), TOBN(0x7fa003d0, 0xe784bd7d), + TOBN(0x25f7614f, 0x17fd9596), TOBN(0x49e0e0a1, 0x35cb98db), + TOBN(0x2c65957b, 0x2e83a76a), TOBN(0x5d40da8d, 0xcddbe0f8), + TOBN(0xf2b8c405, 0x050bad24), TOBN(0x8918426d, 0xc2aa4823), + TOBN(0x2aeab3dd, 0xa38365a7), TOBN(0x72031717, 0x7c91b690), + TOBN(0x8b00d699, 0x60a94120), TOBN(0x478a255d, 0xe99eaeec), + TOBN(0xbf656a5f, 0x6f60aafd), TOBN(0xdfd7cb75, 0x5dee77b3), + TOBN(0x37f68bb4, 0xa595939d), TOBN(0x03556479, 0x28740217), + TOBN(0x8e740e7c, 0x84ad7612), TOBN(0xd89bc843, 0x9044695f), + TOBN(0xf7f3da5d, 0x85a9184d), TOBN(0x562563bb, 0x9fc0b074), + TOBN(0x06d2e6aa, 0xf88a888e), TOBN(0x612d8643, 0x161fbe7c), + TOBN(0x465edba7, 0xf64085e7), TOBN(0xb230f304, 0x29aa8511), + TOBN(0x53388426, 0xcda2d188), TOBN(0x90885735, 0x4b666649), + TOBN(0x6f02ff9a, 0x652f54f6), TOBN(0x65c82294, 0x5fae2bf0), + TOBN(0x7816ade0, 0x62f5eee3), TOBN(0xdcdbdf43, 0xfcc56d70), + TOBN(0x9fb3bba3, 0x54530bb2), TOBN(0xbde3ef77, 0xcb0869ea), + TOBN(0x89bc9046, 0x0b431163), TOBN(0x4d03d7d2, 0xe4819a35), + TOBN(0x33ae4f9e, 0x43b6a782), TOBN(0x216db307, 0x9c88a686), + TOBN(0x91dd88e0, 0x00ffedd9), TOBN(0xb280da9f, 0x12bd4840), + TOBN(0x32a7cb8a, 0x1635e741), TOBN(0xfe14008a, 0x78be02a7), + TOBN(0x3fafb334, 0x1b7ae030), TOBN(0x7fd508e7, 0x5add0ce9), + TOBN(0x72c83219, 0xd607ad51), TOBN(0x0f229c0a, 0x8d40964a), + TOBN(0x1be2c336, 0x1c878da2), TOBN(0xe0c96742, 0xeab2ab86), + TOBN(0x458f8691, 0x3e538cd7), TOBN(0xa7001f6c, 0x8e08ad53), + TOBN(0x52b8c6e6, 0xbf5d15ff), TOBN(0x548234a4, 0x011215dd), + TOBN(0xff5a9d2d, 0x3d5b4045), TOBN(0xb0ffeeb6, 0x4a904190), + TOBN(0x55a3aca4, 0x48607f8b), TOBN(0x8cbd665c, 0x30a0672a), + TOBN(0x87f834e0, 0x42583068), TOBN(0x02da2aeb, 0xf3f6e683), + TOBN(0x6b763e5d, 0x05c12248), TOBN(0x7230378f, 0x65a8aefc), + TOBN(0x93bd80b5, 0x71e8e5ca), TOBN(0x53ab041c, 0xb3b62524), + TOBN(0x1b860513, 0x6c9c552e), TOBN(0xe84d402c, 0xd5524e66), + TOBN(0xa37f3573, 0xf37f5937), TOBN(0xeb0f6c7d, 0xd1e4fca5), + TOBN(0x2965a554, 0xac8ab0fc), TOBN(0x17fbf56c, 0x274676ac), + TOBN(0x2e2f6bd9, 0xacf7d720), TOBN(0x41fc8f88, 0x10224766), + TOBN(0x517a14b3, 0x85d53bef), TOBN(0xdae327a5, 0x7d76a7d1), + TOBN(0x6ad0a065, 0xc4818267), TOBN(0x33aa189b, 0x37c1bbc1), + TOBN(0x64970b52, 0x27392a92), TOBN(0x21699a1c, 0x2d1535ea), + TOBN(0xcd20779c, 0xc2d7a7fd), TOBN(0xe3186059, 0x99c83cf2), + TOBN(0x9b69440b, 0x72c0b8c7), TOBN(0xa81497d7, 0x7b9e0e4d), + TOBN(0x515d5c89, 0x1f5f82dc), TOBN(0x9a7f67d7, 0x6361079e), + TOBN(0xa8da81e3, 0x11a35330), TOBN(0xe44990c4, 0x4b18be1b), + TOBN(0xc7d5ed95, 0xaf103e59), TOBN(0xece8aba7, 0x8dac9261), + TOBN(0xbe82b099, 0x9394b8d3), TOBN(0x6830f09a, 0x16adfe83), + TOBN(0x250a29b4, 0x88172d01), TOBN(0x8b20bd65, 0xcaff9e02), + TOBN(0xb8a7661e, 0xe8a6329a), TOBN(0x4520304d, 0xd3fce920), + TOBN(0xae45da1f, 0x2b47f7ef), TOBN(0xe07f5288, 0x5bffc540), + TOBN(0xf7997009, 0x3464f874), TOBN(0x2244c2cd, 0xa6fa1f38), + TOBN(0x43c41ac1, 0x94d7d9b1), TOBN(0x5bafdd82, 0xc82e7f17), + TOBN(0xdf0614c1, 0x5fda0fca), TOBN(0x74b043a7, 0xa8ae37ad), + TOBN(0x3ba6afa1, 0x9e71734c), TOBN(0x15d5437e, 0x9c450f2e), + TOBN(0x4a5883fe, 0x67e242b1), TOBN(0x5143bdc2, 0x2c1953c2), + TOBN(0x542b8b53, 0xfc5e8920), TOBN(0x363bf9a8, 0x9a9cee08), + TOBN(0x02375f10, 0xc3486e08), TOBN(0x2037543b, 0x8c5e70d2), + TOBN(0x7109bccc, 0x625640b4), TOBN(0xcbc1051e, 0x8bc62c3b), + TOBN(0xf8455fed, 0x803f26ea), TOBN(0x6badceab, 0xeb372424), + TOBN(0xa2a9ce7c, 0x6b53f5f9), TOBN(0x64246595, 0x1b176d99), + TOBN(0xb1298d36, 0xb95c081b), TOBN(0x53505bb8, 0x1d9a9ee6), + TOBN(0x3f6f9e61, 0xf2ba70b0), TOBN(0xd07e16c9, 0x8afad453), + TOBN(0x9f1694bb, 0xe7eb4a6a), TOBN(0xdfebced9, 0x3cb0bc8e), + TOBN(0x92d3dcdc, 0x53868c8b), TOBN(0x174311a2, 0x386107a6), + TOBN(0x4109e07c, 0x689b4e64), TOBN(0x30e4587f, 0x2df3dcb6), + TOBN(0x841aea31, 0x0811b3b2), TOBN(0x6144d41d, 0x0cce43ea), + TOBN(0x464c4581, 0x2a9a7803), TOBN(0xd03d371f, 0x3e158930), + TOBN(0xc676d7f2, 0xb1f3390b), TOBN(0x9f7a1b8c, 0xa5b61272), + TOBN(0x4ebebfc9, 0xc2e127a9), TOBN(0x4602500c, 0x5dd997bf), + TOBN(0x7f09771c, 0x4711230f), TOBN(0x058eb37c, 0x020f09c1), + TOBN(0xab693d4b, 0xfee5e38b), TOBN(0x9289eb1f, 0x4653cbc0), + TOBN(0xbecf46ab, 0xd51b9cf5), TOBN(0xd2aa9c02, 0x9f0121af), + TOBN(0x36aaf7d2, 0xe90dc274), TOBN(0x909e4ea0, 0x48b95a3c), + TOBN(0xe6b70496, 0x6f32dbdb), TOBN(0x672188a0, 0x8b030b3e), + TOBN(0xeeffe5b3, 0xcfb617e2), TOBN(0x87e947de, 0x7c82709e), + TOBN(0xa44d2b39, 0x1770f5a7), TOBN(0xe4d4d791, 0x0e44eb82), + TOBN(0x42e69d1e, 0x3f69712a), TOBN(0xbf11c4d6, 0xac6a820e), + TOBN(0xb5e7f3e5, 0x42c4224c), TOBN(0xd6b4e81c, 0x449d941c), + TOBN(0x5d72bd16, 0x5450e878), TOBN(0x6a61e28a, 0xee25ac54), + TOBN(0x33272094, 0xe6f1cd95), TOBN(0x7512f30d, 0x0d18673f), + TOBN(0x32f7a4ca, 0x5afc1464), TOBN(0x2f095656, 0x6bbb977b), + TOBN(0x586f47ca, 0xa8226200), TOBN(0x02c868ad, 0x1ac07369), + TOBN(0x4ef2b845, 0xc613acbe), TOBN(0x43d7563e, 0x0386054c), + TOBN(0x54da9dc7, 0xab952578), TOBN(0xb5423df2, 0x26e84d0b), + TOBN(0xa8b64eeb, 0x9b872042), TOBN(0xac205782, 0x5990f6df), + TOBN(0x4ff696eb, 0x21f4c77a), TOBN(0x1a79c3e4, 0xaab273af), + TOBN(0x29bc922e, 0x9436b3f1), TOBN(0xff807ef8, 0xd6d9a27a), + TOBN(0x82acea3d, 0x778f22a0), TOBN(0xfb10b2e8, 0x5b5e7469), + TOBN(0xc0b16980, 0x2818ee7d), TOBN(0x011afff4, 0xc91c1a2f), + TOBN(0x95a6d126, 0xad124418), TOBN(0x31c081a5, 0xe72e295f), + TOBN(0x36bb283a, 0xf2f4db75), TOBN(0xd115540f, 0x7acef462), + TOBN(0xc7f3a8f8, 0x33f6746c), TOBN(0x21e46f65, 0xfea990ca), + TOBN(0x915fd5c5, 0xcaddb0a9), TOBN(0xbd41f016, 0x78614555), + TOBN(0x346f4434, 0x426ffb58), TOBN(0x80559436, 0x14dbc204), + TOBN(0xf3dd20fe, 0x5a969b7f), TOBN(0x9d59e956, 0xe899a39a), + TOBN(0xf1b0971c, 0x8ad4cf4b), TOBN(0x03448860, 0x2ffb8fb8), + TOBN(0xf071ac3c, 0x65340ba4), TOBN(0x408d0596, 0xb27fd758), + TOBN(0xe7c78ea4, 0x98c364b0), TOBN(0xa4aac4a5, 0x051e8ab5), + TOBN(0xb9e1d560, 0x485d9002), TOBN(0x9acd518a, 0x88844455), + TOBN(0xe4ca688f, 0xd06f56c0), TOBN(0xa48af70d, 0xdf027972), + TOBN(0x691f0f04, 0x5e9a609d), TOBN(0xa9dd82cd, 0xee61270e), + TOBN(0x8903ca63, 0xa0ef18d3), TOBN(0x9fb7ee35, 0x3d6ca3bd), + TOBN(0xa7b4a09c, 0xabf47d03), TOBN(0x4cdada01, 0x1c67de8e), + TOBN(0x52003749, 0x9355a244), TOBN(0xe77fd2b6, 0x4f2151a9), + TOBN(0x695d6cf6, 0x66b4efcb), TOBN(0xc5a0cacf, 0xda2cfe25), + TOBN(0x104efe5c, 0xef811865), TOBN(0xf52813e8, 0x9ea5cc3d), + TOBN(0x855683dc, 0x40b58dbc), TOBN(0x0338ecde, 0x175fcb11), + TOBN(0xf9a05637, 0x74921592), TOBN(0xb4f1261d, 0xb9bb9d31), + TOBN(0x551429b7, 0x4e9c5459), TOBN(0xbe182e6f, 0x6ea71f53), + TOBN(0xd3a3b07c, 0xdfc50573), TOBN(0x9ba1afda, 0x62be8d44), + TOBN(0x9bcfd2cb, 0x52ab65d3), TOBN(0xdf11d547, 0xa9571802), + TOBN(0x099403ee, 0x02a2404a), TOBN(0x497406f4, 0x21088a71), + TOBN(0x99479409, 0x5004ae71), TOBN(0xbdb42078, 0xa812c362), + TOBN(0x2b72a30f, 0xd8828442), TOBN(0x283add27, 0xfcb5ed1c), + TOBN(0xf7c0e200, 0x66a40015), TOBN(0x3e3be641, 0x08b295ef), + TOBN(0xac127dc1, 0xe038a675), TOBN(0x729deff3, 0x8c5c6320), + TOBN(0xb7df8fd4, 0xa90d2c53), TOBN(0x9b74b0ec, 0x681e7cd3), + TOBN(0x5cb5a623, 0xdab407e5), TOBN(0xcdbd3615, 0x76b340c6), + TOBN(0xa184415a, 0x7d28392c), TOBN(0xc184c1d8, 0xe96f7830), + TOBN(0xc3204f19, 0x81d3a80f), TOBN(0xfde0c841, 0xc8e02432), + TOBN(0x78203b3e, 0x8149e0c1), TOBN(0x5904bdbb, 0x08053a73), + TOBN(0x30fc1dd1, 0x101b6805), TOBN(0x43c223bc, 0x49aa6d49), + TOBN(0x9ed67141, 0x7a174087), TOBN(0x311469a0, 0xd5997008), + TOBN(0xb189b684, 0x5e43fc61), TOBN(0xf3282375, 0xe0d3ab57), + TOBN(0x4fa34b67, 0xb1181da8), TOBN(0x621ed0b2, 0x99ee52b8), + TOBN(0x9b178de1, 0xad990676), TOBN(0xd51de67b, 0x56d54065), + TOBN(0x2a2c27c4, 0x7538c201), TOBN(0x33856ec8, 0x38a40f5c), + TOBN(0x2522fc15, 0xbe6cdcde), TOBN(0x1e603f33, 0x9f0c6f89), + TOBN(0x7994edc3, 0x103e30a6), TOBN(0x033a00db, 0x220c853e), + TOBN(0xd3cfa409, 0xf7bb7fd7), TOBN(0x70f8781e, 0x462d18f6), + TOBN(0xbbd82980, 0x687fe295), TOBN(0x6eef4c32, 0x595669f3), + TOBN(0x86a9303b, 0x2f7e85c3), TOBN(0x5fce4621, 0x71988f9b), + TOBN(0x5b935bf6, 0xc138acb5), TOBN(0x30ea7d67, 0x25661212), + TOBN(0xef1eb5f4, 0xe51ab9a2), TOBN(0x0587c98a, 0xae067c78), + TOBN(0xb3ce1b3c, 0x77ca9ca6), TOBN(0x2a553d4d, 0x54b5f057), + TOBN(0xc7898236, 0x4da29ec2), TOBN(0xdbdd5d13, 0xb9c57316), + TOBN(0xc57d6e6b, 0x2cd80d47), TOBN(0x80b460cf, 0xfe9e7391), + TOBN(0x98648cab, 0xf963c31e), TOBN(0x67f9f633, 0xcc4d32fd), + TOBN(0x0af42a9d, 0xfdf7c687), TOBN(0x55f292a3, 0x0b015ea7), + TOBN(0x89e468b2, 0xcd21ab3d), TOBN(0xe504f022, 0xc393d392), + TOBN(0xab21e1d4, 0xa5013af9), TOBN(0xe3283f78, 0xc2c28acb), + TOBN(0xf38b35f6, 0x226bf99f), TOBN(0xe8354274, 0x0e291e69), + TOBN(0x61673a15, 0xb20c162d), TOBN(0xc101dc75, 0xb04fbdbe), + TOBN(0x8323b4c2, 0x255bd617), TOBN(0x6c969693, 0x6c2a9154), + TOBN(0xc6e65860, 0x62679387), TOBN(0x8e01db0c, 0xb8c88e23), + TOBN(0x33c42873, 0x893a5559), TOBN(0x7630f04b, 0x47a3e149), + TOBN(0xb5d80805, 0xddcf35f8), TOBN(0x582ca080, 0x77dfe732), + TOBN(0x2c7156e1, 0x0b1894a0), TOBN(0x92034001, 0xd81c68c0), + TOBN(0xed225d00, 0xc8b115b5), TOBN(0x237f9c22, 0x83b907f2), + TOBN(0x0ea2f32f, 0x4470e2c0), TOBN(0xb725f7c1, 0x58be4e95), + TOBN(0x0f1dcafa, 0xb1ae5463), TOBN(0x59ed5187, 0x1ba2fc04), + TOBN(0xf6e0f316, 0xd0115d4d), TOBN(0x5180b12f, 0xd3691599), + TOBN(0x157e32c9, 0x527f0a41), TOBN(0x7b0b081d, 0xa8e0ecc0), + TOBN(0x6dbaaa8a, 0xbf4f0dd0), TOBN(0x99b289c7, 0x4d252696), + TOBN(0x79b7755e, 0xdbf864fe), TOBN(0x6974e2b1, 0x76cad3ab), + TOBN(0x35dbbee2, 0x06ddd657), TOBN(0xe7cbdd11, 0x2ff3a96d), + TOBN(0x88381968, 0x076be758), TOBN(0x2d737e72, 0x08c91f5d), + TOBN(0x5f83ab62, 0x86ec3776), TOBN(0x98aa649d, 0x945fa7a1), + TOBN(0xf477ec37, 0x72ef0933), TOBN(0x66f52b1e, 0x098c17b1), + TOBN(0x9eec58fb, 0xd803738b), TOBN(0x91aaade7, 0xe4e86aa4), + TOBN(0x6b1ae617, 0xa5b51492), TOBN(0x63272121, 0xbbc45974), + TOBN(0x7e0e28f0, 0x862c5129), TOBN(0x0a8f79a9, 0x3321a4a0), + TOBN(0xe26d1664, 0x5041c88f), TOBN(0x0571b805, 0x53233e3a), + TOBN(0xd1b0ccde, 0xc9520711), TOBN(0x55a9e4ed, 0x3c8b84bf), + TOBN(0x9426bd39, 0xa1fef314), TOBN(0x4f5f638e, 0x6eb93f2b), + TOBN(0xba2a1ed3, 0x2bf9341b), TOBN(0xd63c1321, 0x4d42d5a9), + TOBN(0xd2964a89, 0x316dc7c5), TOBN(0xd1759606, 0xca511851), + TOBN(0xd8a9201f, 0xf9e6ed35), TOBN(0xb7b5ee45, 0x6736925a), + TOBN(0x0a83fbbc, 0x99581af7), TOBN(0x3076bc40, 0x64eeb051), + TOBN(0x5511c98c, 0x02dec312), TOBN(0x270de898, 0x238dcb78), + TOBN(0x2cf4cf9c, 0x539c08c9), TOBN(0xa70cb65e, 0x38d3b06e), + TOBN(0xb12ec10e, 0xcfe57bbd), TOBN(0x82c7b656, 0x35a0c2b5), + TOBN(0xddc7d5cd, 0x161c67bd), TOBN(0xe32e8985, 0xae3a32cc), + TOBN(0x7aba9444, 0xd11a5529), TOBN(0xe964ed02, 0x2427fa1a), + TOBN(0x1528392d, 0x24a1770a), TOBN(0xa152ce2c, 0x12c72fcd), + TOBN(0x714553a4, 0x8ec07649), TOBN(0x18b4c290, 0x459dd453), + TOBN(0xea32b714, 0x7b64b110), TOBN(0xb871bfa5, 0x2e6f07a2), + TOBN(0xb67112e5, 0x9e2e3c9b), TOBN(0xfbf250e5, 0x44aa90f6), + TOBN(0xf77aedb8, 0xbd539006), TOBN(0x3b0cdf9a, 0xd172a66f), + TOBN(0xedf69fea, 0xf8c51187), TOBN(0x05bb67ec, 0x741e4da7), + TOBN(0x47df0f32, 0x08114345), TOBN(0x56facb07, 0xbb9792b1), + TOBN(0xf3e007e9, 0x8f6229e4), TOBN(0x62d103f4, 0x526fba0f), + TOBN(0x4f33bef7, 0xb0339d79), TOBN(0x9841357b, 0xb59bfec1), + TOBN(0xfa8dbb59, 0xc34e6705), TOBN(0xc3c7180b, 0x7fdaa84c), + TOBN(0xf95872fc, 0xa4108537), TOBN(0x8750cc3b, 0x932a3e5a), + TOBN(0xb61cc69d, 0xb7275d7d), TOBN(0xffa0168b, 0x2e59b2e9), + TOBN(0xca032abc, 0x6ecbb493), TOBN(0x1d86dbd3, 0x2c9082d8), + TOBN(0xae1e0b67, 0xe28ef5ba), TOBN(0x2c9a4699, 0xcb18e169), + TOBN(0x0ecd0e33, 0x1e6bbd20), TOBN(0x571b360e, 0xaf5e81d2), + TOBN(0xcd9fea58, 0x101c1d45), TOBN(0x6651788e, 0x18880452), + TOBN(0xa9972635, 0x1f8dd446), TOBN(0x44bed022, 0xe37281d0), + TOBN(0x094b2b2d, 0x33da525d), TOBN(0xf193678e, 0x13144fd8), + TOBN(0xb8ab5ba4, 0xf4c1061d), TOBN(0x4343b5fa, 0xdccbe0f4), + TOBN(0xa8702371, 0x63812713), TOBN(0x47bf6d2d, 0xf7611d93), + TOBN(0x46729b8c, 0xbd21e1d7), TOBN(0x7484d4e0, 0xd629e77d), + TOBN(0x830e6eea, 0x60dbac1f), TOBN(0x23d8c484, 0xda06a2f7), + TOBN(0x896714b0, 0x50ca535b), TOBN(0xdc8d3644, 0xebd97a9b), + TOBN(0x106ef9fa, 0xb12177b4), TOBN(0xf79bf464, 0x534d5d9c), + TOBN(0x2537a349, 0xa6ab360b), TOBN(0xc7c54253, 0xa00c744f), + TOBN(0xb3c7a047, 0xe5911a76), TOBN(0x61ffa5c8, 0x647f1ee7), + TOBN(0x15aed36f, 0x8f56ab42), TOBN(0x6a0d41b0, 0xa3ff9ac9), + TOBN(0x68f469f5, 0xcc30d357), TOBN(0xbe9adf81, 0x6b72be96), + TOBN(0x1cd926fe, 0x903ad461), TOBN(0x7e89e38f, 0xcaca441b), + TOBN(0xf0f82de5, 0xfacf69d4), TOBN(0x363b7e76, 0x4775344c), + TOBN(0x6894f312, 0xb2e36d04), TOBN(0x3c6cb4fe, 0x11d1c9a5), + TOBN(0x85d9c339, 0x4008e1f2), TOBN(0x5e9a85ea, 0x249f326c), + TOBN(0xdc35c60a, 0x678c5e06), TOBN(0xc08b944f, 0x9f86fba9), + TOBN(0xde40c02c, 0x89f71f0f), TOBN(0xad8f3e31, 0xff3da3c0), + TOBN(0x3ea5096b, 0x42125ded), TOBN(0x13879cbf, 0xa7379183), + TOBN(0x6f4714a5, 0x6b306a0b), TOBN(0x359c2ea6, 0x67646c5e), + TOBN(0xfacf8943, 0x07726368), TOBN(0x07a58935, 0x65ff431e), + TOBN(0x24d661d1, 0x68754ab0), TOBN(0x801fce1d, 0x6f429a76), + TOBN(0xc068a85f, 0xa58ce769), TOBN(0xedc35c54, 0x5d5eca2b), + TOBN(0xea31276f, 0xa3f660d1), TOBN(0xa0184ebe, 0xb8fc7167), + TOBN(0x0f20f21a, 0x1d8db0ae), TOBN(0xd96d095f, 0x56c35e12), + TOBN(0xedf402b5, 0xf8c2a25b), TOBN(0x1bb772b9, 0x059204b6), + TOBN(0x50cbeae2, 0x19b4e34c), TOBN(0x93109d80, 0x3fa0845a), + TOBN(0x54f7ccf7, 0x8ef59fb5), TOBN(0x3b438fe2, 0x88070963), + TOBN(0x9e28c659, 0x31f3ba9b), TOBN(0x9cc31b46, 0xead9da92), + TOBN(0x3c2f0ba9, 0xb733aa5f), TOBN(0xdece47cb, 0xf05af235), + TOBN(0xf8e3f715, 0xa2ac82a5), TOBN(0xc97ba641, 0x2203f18a), + TOBN(0xc3af5504, 0x09c11060), TOBN(0x56ea2c05, 0x46af512d), + TOBN(0xfac28daf, 0xf3f28146), TOBN(0x87fab43a, 0x959ef494)}, + {TOBN(0x09891641, 0xd4c5105f), TOBN(0x1ae80f8e, 0x6d7fbd65), + TOBN(0x9d67225f, 0xbee6bdb0), TOBN(0x3b433b59, 0x7fc4d860), + TOBN(0x44e66db6, 0x93e85638), TOBN(0xf7b59252, 0xe3e9862f), + TOBN(0xdb785157, 0x665c32ec), TOBN(0x702fefd7, 0xae362f50), + TOBN(0x3754475d, 0x0fefb0c3), TOBN(0xd48fb56b, 0x46d7c35d), + TOBN(0xa070b633, 0x363798a4), TOBN(0xae89f3d2, 0x8fdb98e6), + TOBN(0x970b89c8, 0x6363d14c), TOBN(0x89817521, 0x67abd27d), + TOBN(0x9bf7d474, 0x44d5a021), TOBN(0xb3083baf, 0xcac72aee), + TOBN(0x389741de, 0xbe949a44), TOBN(0x638e9388, 0x546a4fa5), + TOBN(0x3fe6419c, 0xa0047bdc), TOBN(0x7047f648, 0xaaea57ca), + TOBN(0x54e48a90, 0x41fbab17), TOBN(0xda8e0b28, 0x576bdba2), + TOBN(0xe807eebc, 0xc72afddc), TOBN(0x07d3336d, 0xf42577bf), + TOBN(0x62a8c244, 0xbfe20925), TOBN(0x91c19ac3, 0x8fdce867), + TOBN(0x5a96a5d5, 0xdd387063), TOBN(0x61d587d4, 0x21d324f6), + TOBN(0xe87673a2, 0xa37173ea), TOBN(0x23848008, 0x53778b65), + TOBN(0x10f8441e, 0x05bab43e), TOBN(0xfa11fe12, 0x4621efbe), + TOBN(0x047b772e, 0x81685d7b), TOBN(0x23f27d81, 0xbf34a976), + TOBN(0xc27608e2, 0x915f48ef), TOBN(0x3b0b43fa, 0xa521d5c3), + TOBN(0x7613fb26, 0x63ca7284), TOBN(0x7f5729b4, 0x1d4db837), + TOBN(0x87b14898, 0x583b526b), TOBN(0x00b732a6, 0xbbadd3d1), + TOBN(0x8e02f426, 0x2048e396), TOBN(0x436b50b6, 0x383d9de4), + TOBN(0xf78d3481, 0x471e85ad), TOBN(0x8b01ea6a, 0xd005c8d6), + TOBN(0xd3c7afee, 0x97015c07), TOBN(0x46cdf1a9, 0x4e3ba2ae), + TOBN(0x7a42e501, 0x83d3a1d2), TOBN(0xd54b5268, 0xb541dff4), + TOBN(0x3f24cf30, 0x4e23e9bc), TOBN(0x4387f816, 0x126e3624), + TOBN(0x26a46a03, 0x3b0b6d61), TOBN(0xaf1bc845, 0x8b2d777c), + TOBN(0x25c401ba, 0x527de79c), TOBN(0x0e1346d4, 0x4261bbb6), + TOBN(0x4b96c44b, 0x287b4bc7), TOBN(0x658493c7, 0x5254562f), + TOBN(0x23f949fe, 0xb8a24a20), TOBN(0x17ebfed1, 0xf52ca53f), + TOBN(0x9b691bbe, 0xbcfb4853), TOBN(0x5617ff6b, 0x6278a05d), + TOBN(0x241b34c5, 0xe3c99ebd), TOBN(0xfc64242e, 0x1784156a), + TOBN(0x4206482f, 0x695d67df), TOBN(0xb967ce0e, 0xee27c011), + TOBN(0x65db3751, 0x21c80b5d), TOBN(0x2e7a563c, 0xa31ecca0), + TOBN(0xe56ffc4e, 0x5238a07e), TOBN(0x3d6c2966, 0x32ced854), + TOBN(0xe99d7d1a, 0xaf70b885), TOBN(0xafc3bad9, 0x2d686459), + TOBN(0x9c78bf46, 0x0cc8ba5b), TOBN(0x5a439519, 0x18955aa3), + TOBN(0xf8b517a8, 0x5fe4e314), TOBN(0xe60234d0, 0xfcb8906f), + TOBN(0xffe542ac, 0xf2061b23), TOBN(0x287e191f, 0x6b4cb59c), + TOBN(0x21857ddc, 0x09d877d8), TOBN(0x1c23478c, 0x14678941), + TOBN(0xbbf0c056, 0xb6e05ea4), TOBN(0x82da4b53, 0xb01594fe), + TOBN(0xf7526791, 0xfadb8608), TOBN(0x049e832d, 0x7b74cdf6), + TOBN(0xa43581cc, 0xc2b90a34), TOBN(0x73639eb8, 0x9360b10c), + TOBN(0x4fba331f, 0xe1e4a71b), TOBN(0x6ffd6b93, 0x8072f919), + TOBN(0x6e53271c, 0x65679032), TOBN(0x67206444, 0xf14272ce), + TOBN(0xc0f734a3, 0xb2335834), TOBN(0x9526205a, 0x90ef6860), + TOBN(0xcb8be717, 0x04e2bb0d), TOBN(0x2418871e, 0x02f383fa), + TOBN(0xd7177681, 0x4082c157), TOBN(0xcc914ad0, 0x29c20073), + TOBN(0xf186c1eb, 0xe587e728), TOBN(0x6fdb3c22, 0x61bcd5fd), + TOBN(0x30d014a6, 0xf2f9f8e9), TOBN(0x963ece23, 0x4fec49d2), + TOBN(0x862025c5, 0x9605a8d9), TOBN(0x39874445, 0x19f8929a), + TOBN(0x01b6ff65, 0x12bf476a), TOBN(0x598a64d8, 0x09cf7d91), + TOBN(0xd7ec7749, 0x93be56ca), TOBN(0x10899785, 0xcbb33615), + TOBN(0xb8a092fd, 0x02eee3ad), TOBN(0xa86b3d35, 0x30145270), + TOBN(0x323d98c6, 0x8512b675), TOBN(0x4b8bc785, 0x62ebb40f), + TOBN(0x7d301f54, 0x413f9cde), TOBN(0xa5e4fb4f, 0x2bab5664), + TOBN(0x1d2b252d, 0x1cbfec23), TOBN(0xfcd576bb, 0xe177120d), + TOBN(0x04427d3e, 0x83731a34), TOBN(0x2bb9028e, 0xed836e8e), + TOBN(0xb36acff8, 0xb612ca7c), TOBN(0xb88fe5ef, 0xd3d9c73a), + TOBN(0xbe2a6bc6, 0xedea4eb3), TOBN(0x43b93133, 0x488eec77), + TOBN(0xf41ff566, 0xb17106e1), TOBN(0x469e9172, 0x654efa32), + TOBN(0xb4480f04, 0x41c23fa3), TOBN(0xb4712eb0, 0xc1989a2e), + TOBN(0x3ccbba0f, 0x93a29ca7), TOBN(0x6e205c14, 0xd619428c), + TOBN(0x90db7957, 0xb3641686), TOBN(0x0432691d, 0x45ac8b4e), + TOBN(0x07a759ac, 0xf64e0350), TOBN(0x0514d89c, 0x9c972517), + TOBN(0x1701147f, 0xa8e67fc3), TOBN(0x9e2e0b8b, 0xab2085be), + TOBN(0xd5651824, 0xac284e57), TOBN(0x890d4325, 0x74893664), + TOBN(0x8a7c5e6e, 0xc55e68a3), TOBN(0xbf12e90b, 0x4339c85a), + TOBN(0x31846b85, 0xf922b655), TOBN(0x9a54ce4d, 0x0bf4d700), + TOBN(0xd7f4e83a, 0xf1a14295), TOBN(0x916f955c, 0xb285d4f9), + TOBN(0xe57bb0e0, 0x99ffdaba), TOBN(0x28a43034, 0xeab0d152), + TOBN(0x0a36ffa2, 0xb8a9cef8), TOBN(0x5517407e, 0xb9ec051a), + TOBN(0x9c796096, 0xea68e672), TOBN(0x853db5fb, 0xfb3c77fb), + TOBN(0x21474ba9, 0xe864a51a), TOBN(0x6c267699, 0x6e8a1b8b), + TOBN(0x7c823626, 0x94120a28), TOBN(0xe61e9a48, 0x8383a5db), + TOBN(0x7dd75003, 0x9f84216d), TOBN(0xab020d07, 0xad43cd85), + TOBN(0x9437ae48, 0xda12c659), TOBN(0x6449c2eb, 0xe65452ad), + TOBN(0xcc7c4c1c, 0x2cf9d7c1), TOBN(0x1320886a, 0xee95e5ab), + TOBN(0xbb7b9056, 0xbeae170c), TOBN(0xc8a5b250, 0xdbc0d662), + TOBN(0x4ed81432, 0xc11d2303), TOBN(0x7da66912, 0x1f03769f), + TOBN(0x3ac7a5fd, 0x84539828), TOBN(0x14dada94, 0x3bccdd02), + TOBN(0x8b84c321, 0x7ef6b0d1), TOBN(0x52a9477a, 0x7c933f22), + TOBN(0x5ef6728a, 0xfd440b82), TOBN(0x5c3bd859, 0x6ce4bd5e), + TOBN(0x918b80f5, 0xf22c2d3e), TOBN(0x368d5040, 0xb7bb6cc5), + TOBN(0xb66142a1, 0x2695a11c), TOBN(0x60ac583a, 0xeb19ea70), + TOBN(0x317cbb98, 0x0eab2437), TOBN(0x8cc08c55, 0x5e2654c8), + TOBN(0xfe2d6520, 0xe6d8307f), TOBN(0xe9f147f3, 0x57428993), + TOBN(0x5f9c7d14, 0xd2fd6cf1), TOBN(0xa3ecd064, 0x2d4fcbb0), + TOBN(0xad83fef0, 0x8e7341f7), TOBN(0x643f23a0, 0x3a63115c), + TOBN(0xd38a78ab, 0xe65ab743), TOBN(0xbf7c75b1, 0x35edc89c), + TOBN(0x3dd8752e, 0x530df568), TOBN(0xf85c4a76, 0xe308c682), + TOBN(0x4c9955b2, 0xe68acf37), TOBN(0xa544df3d, 0xab32af85), + TOBN(0x4b8ec3f5, 0xa25cf493), TOBN(0x4d8f2764, 0x1a622feb), + TOBN(0x7bb4f7aa, 0xf0dcbc49), TOBN(0x7de551f9, 0x70bbb45b), + TOBN(0xcfd0f3e4, 0x9f2ca2e5), TOBN(0xece58709, 0x1f5c76ef), + TOBN(0x32920edd, 0x167d79ae), TOBN(0x039df8a2, 0xfa7d7ec1), + TOBN(0xf46206c0, 0xbb30af91), TOBN(0x1ff5e2f5, 0x22676b59), + TOBN(0x11f4a039, 0x6ea51d66), TOBN(0x506c1445, 0x807d7a26), + TOBN(0x60da5705, 0x755a9b24), TOBN(0x8fc8cc32, 0x1f1a319e), + TOBN(0x83642d4d, 0x9433d67d), TOBN(0x7fa5cb8f, 0x6a7dd296), + TOBN(0x576591db, 0x9b7bde07), TOBN(0x13173d25, 0x419716fb), + TOBN(0xea30599d, 0xd5b340ff), TOBN(0xfc6b5297, 0xb0fe76c5), + TOBN(0x1c6968c8, 0xab8f5adc), TOBN(0xf723c7f5, 0x901c928d), + TOBN(0x4203c321, 0x9773d402), TOBN(0xdf7c6aa3, 0x1b51dd47), + TOBN(0x3d49e37a, 0x552be23c), TOBN(0x57febee8, 0x0b5a6e87), + TOBN(0xc5ecbee4, 0x7bd8e739), TOBN(0x79d44994, 0xae63bf75), + TOBN(0x168bd00f, 0x38fb8923), TOBN(0x75d48ee4, 0xd0533130), + TOBN(0x554f77aa, 0xdb5cdf33), TOBN(0x3396e896, 0x3c696769), + TOBN(0x2fdddbf2, 0xd3fd674e), TOBN(0xbbb8f6ee, 0x99d0e3e5), + TOBN(0x51b90651, 0xcbae2f70), TOBN(0xefc4bc05, 0x93aaa8eb), + TOBN(0x8ecd8689, 0xdd1df499), TOBN(0x1aee99a8, 0x22f367a5), + TOBN(0x95d485b9, 0xae8274c5), TOBN(0x6c14d445, 0x7d30b39c), + TOBN(0xbafea90b, 0xbcc1ef81), TOBN(0x7c5f317a, 0xa459a2ed), + TOBN(0x01211075, 0x4ef44227), TOBN(0xa17bed6e, 0xdc20f496), + TOBN(0x0cdfe424, 0x819853cd), TOBN(0x13793298, 0xf71e2ce7), + TOBN(0x3c1f3078, 0xdbbe307b), TOBN(0x6dd1c20e, 0x76ee9936), + TOBN(0x23ee4b57, 0x423caa20), TOBN(0x4ac3793b, 0x8efb840e), + TOBN(0x934438eb, 0xed1f8ca0), TOBN(0x3e546658, 0x4ebb25a2), + TOBN(0xc415af0e, 0xc069896f), TOBN(0xc13eddb0, 0x9a5aa43d), + TOBN(0x7a04204f, 0xd49eb8f6), TOBN(0xd0d5bdfc, 0xd74f1670), + TOBN(0x3697e286, 0x56fc0558), TOBN(0x10207371, 0x01cebade), + TOBN(0x5f87e690, 0x0647a82b), TOBN(0x908e0ed4, 0x8f40054f), + TOBN(0xa9f633d4, 0x79853803), TOBN(0x8ed13c9a, 0x4a28b252), + TOBN(0x3e2ef676, 0x1f460f64), TOBN(0x53930b9b, 0x36d06336), + TOBN(0x347073ac, 0x8fc4979b), TOBN(0x84380e0e, 0x5ecd5597), + TOBN(0xe3b22c6b, 0xc4fe3c39), TOBN(0xba4a8153, 0x6c7bebdf), + TOBN(0xf23ab6b7, 0x25693459), TOBN(0x53bc3770, 0x14922b11), + TOBN(0x4645c8ab, 0x5afc60db), TOBN(0xaa022355, 0x20b9f2a3), + TOBN(0x52a2954c, 0xce0fc507), TOBN(0x8c2731bb, 0x7ce1c2e7), + TOBN(0xf39608ab, 0x18a0339d), TOBN(0xac7a658d, 0x3735436c), + TOBN(0xb22c2b07, 0xcd992b4f), TOBN(0x4e83daec, 0xf40dcfd4), + TOBN(0x8a34c7be, 0x2f39ea3e), TOBN(0xef0c005f, 0xb0a56d2e), + TOBN(0x62731f6a, 0x6edd8038), TOBN(0x5721d740, 0x4e3cb075), + TOBN(0x1ea41511, 0xfbeeee1b), TOBN(0xd1ef5e73, 0xef1d0c05), + TOBN(0x42feefd1, 0x73c07d35), TOBN(0xe530a00a, 0x8a329493), + TOBN(0x5d55b7fe, 0xf15ebfb0), TOBN(0x549de03c, 0xd322491a), + TOBN(0xf7b5f602, 0x745b3237), TOBN(0x3632a3a2, 0x1ab6e2b6), + TOBN(0x0d3bba89, 0x0ef59f78), TOBN(0x0dfc6443, 0xc9e52b9a), + TOBN(0x1dc79699, 0x72631447), TOBN(0xef033917, 0xb3be20b1), + TOBN(0x0c92735d, 0xb1383948), TOBN(0xc1fc29a2, 0xc0dd7d7d), + TOBN(0x6485b697, 0x403ed068), TOBN(0x13bfaab3, 0xaac93bdc), + TOBN(0x410dc6a9, 0x0deeaf52), TOBN(0xb003fb02, 0x4c641c15), + TOBN(0x1384978c, 0x5bc504c4), TOBN(0x37640487, 0x864a6a77), + TOBN(0x05991bc6, 0x222a77da), TOBN(0x62260a57, 0x5e47eb11), + TOBN(0xc7af6613, 0xf21b432c), TOBN(0x22f3acc9, 0xab4953e9), + TOBN(0x52934922, 0x8e41d155), TOBN(0x4d024568, 0x3ac059ef), + TOBN(0xb0201755, 0x4d884411), TOBN(0xce8055cf, 0xa59a178f), + TOBN(0xcd77d1af, 0xf6204549), TOBN(0xa0a00a3e, 0xc7066759), + TOBN(0x471071ef, 0x0272c229), TOBN(0x009bcf6b, 0xd3c4b6b0), + TOBN(0x2a2638a8, 0x22305177), TOBN(0xd51d59df, 0x41645bbf), + TOBN(0xa81142fd, 0xc0a7a3c0), TOBN(0xa17eca6d, 0x4c7063ee), + TOBN(0x0bb887ed, 0x60d9dcec), TOBN(0xd6d28e51, 0x20ad2455), + TOBN(0xebed6308, 0xa67102ba), TOBN(0x042c3114, 0x8bffa408), + TOBN(0xfd099ac5, 0x8aa68e30), TOBN(0x7a6a3d7c, 0x1483513e), + TOBN(0xffcc6b75, 0xba2d8f0c), TOBN(0x54dacf96, 0x1e78b954), + TOBN(0xf645696f, 0xa4a9af89), TOBN(0x3a411940, 0x06ac98ec), + TOBN(0x41b8b3f6, 0x22a67a20), TOBN(0x2d0b1e0f, 0x99dec626), + TOBN(0x27c89192, 0x40be34e8), TOBN(0xc7162b37, 0x91907f35), + TOBN(0x90188ec1, 0xa956702b), TOBN(0xca132f7d, 0xdf93769c), + TOBN(0x3ece44f9, 0x0e2025b4), TOBN(0x67aaec69, 0x0c62f14c), + TOBN(0xad741418, 0x22e3cc11), TOBN(0xcf9b75c3, 0x7ff9a50e), + TOBN(0x02fa2b16, 0x4d348272), TOBN(0xbd99d61a, 0x9959d56d), + TOBN(0xbc4f19db, 0x18762916), TOBN(0xcc7cce50, 0x49c1ac80), + TOBN(0x4d59ebaa, 0xd846bd83), TOBN(0x8775a9dc, 0xa9202849), + TOBN(0x07ec4ae1, 0x6e1f4ca9), TOBN(0x27eb5875, 0xba893f11), + TOBN(0x00284d51, 0x662cc565), TOBN(0x82353a6b, 0x0db4138d), + TOBN(0xd9c7aaaa, 0xaa32a594), TOBN(0xf5528b5e, 0xa5669c47), + TOBN(0xf3220231, 0x2f23c5ff), TOBN(0xe3e8147a, 0x6affa3a1), + TOBN(0xfb423d5c, 0x202ddda0), TOBN(0x3d6414ac, 0x6b871bd4), + TOBN(0x586f82e1, 0xa51a168a), TOBN(0xb712c671, 0x48ae5448), + TOBN(0x9a2e4bd1, 0x76233eb8), TOBN(0x0188223a, 0x78811ca9), + TOBN(0x553c5e21, 0xf7c18de1), TOBN(0x7682e451, 0xb27bb286), + TOBN(0x3ed036b3, 0x0e51e929), TOBN(0xf487211b, 0xec9cb34f), + TOBN(0x0d094277, 0x0c24efc8), TOBN(0x0349fd04, 0xbef737a4), + TOBN(0x6d1c9dd2, 0x514cdd28), TOBN(0x29c135ff, 0x30da9521), + TOBN(0xea6e4508, 0xf78b0b6f), TOBN(0x176f5dd2, 0x678c143c), + TOBN(0x08148418, 0x4be21e65), TOBN(0x27f7525c, 0xe7df38c4), + TOBN(0x1fb70e09, 0x748ab1a4), TOBN(0x9cba50a0, 0x5efe4433), + TOBN(0x7846c7a6, 0x15f75af2), TOBN(0x2a7c2c57, 0x5ee73ea8), + TOBN(0x42e566a4, 0x3f0a449a), TOBN(0x45474c3b, 0xad90fc3d), + TOBN(0x7447be3d, 0x8b61d057), TOBN(0x3e9d1cf1, 0x3a4ec092), + TOBN(0x1603e453, 0xf380a6e6), TOBN(0x0b86e431, 0x9b1437c2), + TOBN(0x7a4173f2, 0xef29610a), TOBN(0x8fa729a7, 0xf03d57f7), + TOBN(0x3e186f6e, 0x6c9c217e), TOBN(0xbe1d3079, 0x91919524), + TOBN(0x92a62a70, 0x153d4fb1), TOBN(0x32ed3e34, 0xd68c2f71), + TOBN(0xd785027f, 0x9eb1a8b7), TOBN(0xbc37eb77, 0xc5b22fe8), + TOBN(0x466b34f0, 0xb9d6a191), TOBN(0x008a89af, 0x9a05f816), + TOBN(0x19b028fb, 0x7d42c10a), TOBN(0x7fe8c92f, 0x49b3f6b8), + TOBN(0x58907cc0, 0xa5a0ade3), TOBN(0xb3154f51, 0x559d1a7c), + TOBN(0x5066efb6, 0xd9790ed6), TOBN(0xa77a0cbc, 0xa6aa793b), + TOBN(0x1a915f3c, 0x223e042e), TOBN(0x1c5def04, 0x69c5874b), + TOBN(0x0e830078, 0x73b6c1da), TOBN(0x55cf85d2, 0xfcd8557a), + TOBN(0x0f7c7c76, 0x0460f3b1), TOBN(0x87052acb, 0x46e58063), + TOBN(0x09212b80, 0x907eae66), TOBN(0x3cb068e0, 0x4d721c89), + TOBN(0xa87941ae, 0xdd45ac1c), TOBN(0xde8d5c0d, 0x0daa0dbb), + TOBN(0xda421fdc, 0xe3502e6e), TOBN(0xc8944201, 0x4d89a084), + TOBN(0x7307ba5e, 0xf0c24bfb), TOBN(0xda212beb, 0x20bde0ef), + TOBN(0xea2da24b, 0xf82ce682), TOBN(0x058d3816, 0x07f71fe4), + TOBN(0x35a02462, 0x5ffad8de), TOBN(0xcd7b05dc, 0xaadcefab), + TOBN(0xd442f8ed, 0x1d9f54ec), TOBN(0x8be3d618, 0xb2d3b5ca), + TOBN(0xe2220ed0, 0xe06b2ce2), TOBN(0x82699a5f, 0x1b0da4c0), + TOBN(0x3ff106f5, 0x71c0c3a7), TOBN(0x8f580f5a, 0x0d34180c), + TOBN(0x4ebb120e, 0x22d7d375), TOBN(0x5e5782cc, 0xe9513675), + TOBN(0x2275580c, 0x99c82a70), TOBN(0xe8359fbf, 0x15ea8c4c), + TOBN(0x53b48db8, 0x7b415e70), TOBN(0xaacf2240, 0x100c6014), + TOBN(0x9faaccf5, 0xe4652f1d), TOBN(0xbd6fdd2a, 0xd56157b2), + TOBN(0xa4f4fb1f, 0x6261ec50), TOBN(0x244e55ad, 0x476bcd52), + TOBN(0x881c9305, 0x047d320b), TOBN(0x1ca983d5, 0x6181263f), + TOBN(0x354e9a44, 0x278fb8ee), TOBN(0xad2dbc0f, 0x396e4964), + TOBN(0x723f3aa2, 0x9268b3de), TOBN(0x0d1ca29a, 0xe6e0609a), + TOBN(0x794866aa, 0x6cf44252), TOBN(0x0b59f3e3, 0x01af87ed), + TOBN(0xe234e5ff, 0x7f4a6c51), TOBN(0xa8768fd2, 0x61dc2f7e), + TOBN(0xdafc7332, 0x0a94d81f), TOBN(0xd7f84282, 0x06938ce1), + TOBN(0xae0b3c0e, 0x0546063e), TOBN(0x7fbadcb2, 0x5d61abc6), + TOBN(0xd5d7a2c9, 0x369ac400), TOBN(0xa5978d09, 0xae67d10c), + TOBN(0x290f211e, 0x4f85eaac), TOBN(0xe61e2ad1, 0xfacac681), + TOBN(0xae125225, 0x388384cd), TOBN(0xa7fb68e9, 0xccfde30f), + TOBN(0x7a59b936, 0x3daed4c2), TOBN(0x80a9aa40, 0x2606f789), + TOBN(0xb40c1ea5, 0xf6a6d90a), TOBN(0x948364d3, 0x514d5885), + TOBN(0x062ebc60, 0x70985182), TOBN(0xa6db5b0e, 0x33310895), + TOBN(0x64a12175, 0xe329c2f5), TOBN(0xc5f25bd2, 0x90ea237e), + TOBN(0x7915c524, 0x2d0a4c23), TOBN(0xeb5d26e4, 0x6bb3cc52), + TOBN(0x369a9116, 0xc09e2c92), TOBN(0x0c527f92, 0xcf182cf8), + TOBN(0x9e591938, 0x2aede0ac), TOBN(0xb2922208, 0x6cc34939), + TOBN(0x3c9d8962, 0x99a34361), TOBN(0x3c81836d, 0xc1905fe6), + TOBN(0x4bfeb57f, 0xa001ec5a), TOBN(0xe993f5bb, 0xa0dc5dba), + TOBN(0x47884109, 0x724a1380), TOBN(0x8a0369ab, 0x32fe9a04), + TOBN(0xea068d60, 0x8c927db8), TOBN(0xbf5f37cf, 0x94655741), + TOBN(0x47d402a2, 0x04b6c7ea), TOBN(0x4551c295, 0x6af259cb), + TOBN(0x698b71e7, 0xed77ee8b), TOBN(0xbddf7bd0, 0xf309d5c7), + TOBN(0x6201c22c, 0x34e780ca), TOBN(0xab04f7d8, 0x4c295ef4), + TOBN(0x1c947294, 0x4313a8ce), TOBN(0xe532e4ac, 0x92ca4cfe), + TOBN(0x89738f80, 0xd0a7a97a), TOBN(0xec088c88, 0xa580fd5b), + TOBN(0x612b1ecc, 0x42ce9e51), TOBN(0x8f9840fd, 0xb25fdd2a), + TOBN(0x3cda78c0, 0x01e7f839), TOBN(0x546b3d3a, 0xece05480), + TOBN(0x271719a9, 0x80d30916), TOBN(0x45497107, 0x584c20c4), + TOBN(0xaf8f9478, 0x5bc78608), TOBN(0x28c7d484, 0x277e2a4c), + TOBN(0xfce01767, 0x88a2ffe4), TOBN(0xdc506a35, 0x28e169a5), + TOBN(0x0ea10861, 0x7af9c93a), TOBN(0x1ed24361, 0x03fa0e08), + TOBN(0x96eaaa92, 0xa3d694e7), TOBN(0xc0f43b4d, 0xef50bc74), + TOBN(0xce6aa58c, 0x64114db4), TOBN(0x8218e8ea, 0x7c000fd4), + TOBN(0xac815dfb, 0x185f8844), TOBN(0xcd7e90cb, 0x1557abfb), + TOBN(0x23d16655, 0xafbfecdf), TOBN(0x80f3271f, 0x085cac4a), + TOBN(0x7fc39aa7, 0xd0e62f47), TOBN(0x88d519d1, 0x460a48e5), + TOBN(0x59559ac4, 0xd28f101e), TOBN(0x7981d9e9, 0xca9ae816), + TOBN(0x5c38652c, 0x9ac38203), TOBN(0x86eaf87f, 0x57657fe5), + TOBN(0x568fc472, 0xe21f5416), TOBN(0x2afff39c, 0xe7e597b5), + TOBN(0x3adbbb07, 0x256d4eab), TOBN(0x22598692, 0x8285ab89), + TOBN(0x35f8112a, 0x041caefe), TOBN(0x95df02e3, 0xa5064c8b), + TOBN(0x4d63356e, 0xc7004bf3), TOBN(0x230a08f4, 0xdb83c7de), + TOBN(0xca27b270, 0x8709a7b7), TOBN(0x0d1c4cc4, 0xcb9abd2d), + TOBN(0x8a0bc66e, 0x7550fee8), TOBN(0x369cd4c7, 0x9cf7247e), + TOBN(0x75562e84, 0x92b5b7e7), TOBN(0x8fed0da0, 0x5802af7b), + TOBN(0x6a7091c2, 0xe48fb889), TOBN(0x26882c13, 0x7b8a9d06), + TOBN(0xa2498663, 0x1b82a0e2), TOBN(0x844ed736, 0x3518152d), + TOBN(0x282f476f, 0xd86e27c7), TOBN(0xa04edaca, 0x04afefdc), + TOBN(0x8b256ebc, 0x6119e34d), TOBN(0x56a413e9, 0x0787d78b)}, + {TOBN(0x82ee061d, 0x5a74be50), TOBN(0xe41781c4, 0xdea16ff5), + TOBN(0xe0b0c81e, 0x99bfc8a2), TOBN(0x624f4d69, 0x0b547e2d), + TOBN(0x3a83545d, 0xbdcc9ae4), TOBN(0x2573dbb6, 0x409b1e8e), + TOBN(0x482960c4, 0xa6c93539), TOBN(0xf01059ad, 0x5ae18798), + TOBN(0x715c9f97, 0x3112795f), TOBN(0xe8244437, 0x984e6ee1), + TOBN(0x55cb4858, 0xecb66bcd), TOBN(0x7c136735, 0xabaffbee), + TOBN(0x54661595, 0x5dbec38e), TOBN(0x51c0782c, 0x388ad153), + TOBN(0x9ba4c53a, 0xc6e0952f), TOBN(0x27e6782a, 0x1b21dfa8), + TOBN(0x682f903d, 0x4ed2dbc2), TOBN(0x0eba59c8, 0x7c3b2d83), + TOBN(0x8e9dc84d, 0x9c7e9335), TOBN(0x5f9b21b0, 0x0eb226d7), + TOBN(0xe33bd394, 0xaf267bae), TOBN(0xaa86cc25, 0xbe2e15ae), + TOBN(0x4f0bf67d, 0x6a8ec500), TOBN(0x5846aa44, 0xf9630658), + TOBN(0xfeb09740, 0xe2c2bf15), TOBN(0x627a2205, 0xa9e99704), + TOBN(0xec8d73d0, 0xc2fbc565), TOBN(0x223eed8f, 0xc20c8de8), + TOBN(0x1ee32583, 0xa8363b49), TOBN(0x1a0b6cb9, 0xc9c2b0a6), + TOBN(0x49f7c3d2, 0x90dbc85c), TOBN(0xa8dfbb97, 0x1ef4c1ac), + TOBN(0xafb34d4c, 0x65c7c2ab), TOBN(0x1d4610e7, 0xe2c5ea84), + TOBN(0x893f6d1b, 0x973c4ab5), TOBN(0xa3cdd7e9, 0x945ba5c4), + TOBN(0x60514983, 0x064417ee), TOBN(0x1459b23c, 0xad6bdf2b), + TOBN(0x23b2c341, 0x5cf726c3), TOBN(0x3a829635, 0x32d6354a), + TOBN(0x294f901f, 0xab192c18), TOBN(0xec5fcbfe, 0x7030164f), + TOBN(0xe2e2fcb7, 0xe2246ba6), TOBN(0x1e7c88b3, 0x221a1a0c), + TOBN(0x72c7dd93, 0xc92d88c5), TOBN(0x41c2148e, 0x1106fb59), + TOBN(0x547dd4f5, 0xa0f60f14), TOBN(0xed9b52b2, 0x63960f31), + TOBN(0x6c8349eb, 0xb0a5b358), TOBN(0xb154c5c2, 0x9e7e2ed6), + TOBN(0xcad5eccf, 0xeda462db), TOBN(0xf2d6dbe4, 0x2de66b69), + TOBN(0x426aedf3, 0x8665e5b2), TOBN(0x488a8513, 0x7b7f5723), + TOBN(0x15cc43b3, 0x8bcbb386), TOBN(0x27ad0af3, 0xd791d879), + TOBN(0xc16c236e, 0x846e364f), TOBN(0x7f33527c, 0xdea50ca0), + TOBN(0xc4810775, 0x0926b86d), TOBN(0x6c2a3609, 0x0598e70c), + TOBN(0xa6755e52, 0xf024e924), TOBN(0xe0fa07a4, 0x9db4afca), + TOBN(0x15c3ce7d, 0x66831790), TOBN(0x5b4ef350, 0xa6cbb0d6), + TOBN(0x2c4aafc4, 0xb6205969), TOBN(0x42563f02, 0xf6c7854f), + TOBN(0x016aced5, 0x1d983b48), TOBN(0xfeb356d8, 0x99949755), + TOBN(0x8c2a2c81, 0xd1a39bd7), TOBN(0x8f44340f, 0xe6934ae9), + TOBN(0x148cf91c, 0x447904da), TOBN(0x7340185f, 0x0f51a926), + TOBN(0x2f8f00fb, 0x7409ab46), TOBN(0x057e78e6, 0x80e289b2), + TOBN(0x03e5022c, 0xa888e5d1), TOBN(0x3c87111a, 0x9dede4e2), + TOBN(0x5b9b0e1c, 0x7809460b), TOBN(0xe751c852, 0x71c9abc7), + TOBN(0x8b944e28, 0xc7cc1dc9), TOBN(0x4f201ffa, 0x1d3cfa08), + TOBN(0x02fc905c, 0x3e6721ce), TOBN(0xd52d70da, 0xd0b3674c), + TOBN(0x5dc2e5ca, 0x18810da4), TOBN(0xa984b273, 0x5c69dd99), + TOBN(0x63b92527, 0x84de5ca4), TOBN(0x2f1c9872, 0xc852dec4), + TOBN(0x18b03593, 0xc2e3de09), TOBN(0x19d70b01, 0x9813dc2f), + TOBN(0x42806b2d, 0xa6dc1d29), TOBN(0xd3030009, 0xf871e144), + TOBN(0xa1feb333, 0xaaf49276), TOBN(0xb5583b9e, 0xc70bc04b), + TOBN(0x1db0be78, 0x95695f20), TOBN(0xfc841811, 0x89d012b5), + TOBN(0x6409f272, 0x05f61643), TOBN(0x40d34174, 0xd5883128), + TOBN(0xd79196f5, 0x67419833), TOBN(0x6059e252, 0x863b7b08), + TOBN(0x84da1817, 0x1c56700c), TOBN(0x5758ee56, 0xb28d3ec4), + TOBN(0x7da2771d, 0x013b0ea6), TOBN(0xfddf524b, 0x54c5e9b9), + TOBN(0x7df4faf8, 0x24305d80), TOBN(0x58f5c1bf, 0x3a97763f), + TOBN(0xa5af37f1, 0x7c696042), TOBN(0xd4cba22c, 0x4a2538de), + TOBN(0x211cb995, 0x9ea42600), TOBN(0xcd105f41, 0x7b069889), + TOBN(0xb1e1cf19, 0xddb81e74), TOBN(0x472f2d89, 0x5157b8ca), + TOBN(0x086fb008, 0xee9db885), TOBN(0x365cd570, 0x0f26d131), + TOBN(0x284b02bb, 0xa2be7053), TOBN(0xdcbbf7c6, 0x7ab9a6d6), + TOBN(0x4425559c, 0x20f7a530), TOBN(0x961f2dfa, 0x188767c8), + TOBN(0xe2fd9435, 0x70dc80c4), TOBN(0x104d6b63, 0xf0784120), + TOBN(0x7f592bc1, 0x53567122), TOBN(0xf6bc1246, 0xf688ad77), + TOBN(0x05214c05, 0x0f15dde9), TOBN(0xa47a76a8, 0x0d5f2b82), + TOBN(0xbb254d30, 0x62e82b62), TOBN(0x11a05fe0, 0x3ec955ee), + TOBN(0x7eaff46e, 0x9d529b36), TOBN(0x55ab1301, 0x8f9e3df6), + TOBN(0xc463e371, 0x99317698), TOBN(0xfd251438, 0xccda47ad), + TOBN(0xca9c3547, 0x23d695ea), TOBN(0x48ce626e, 0x16e589b5), + TOBN(0x6b5b64c7, 0xb187d086), TOBN(0xd02e1794, 0xb2207948), + TOBN(0x8b58e98f, 0x7198111d), TOBN(0x90ca6305, 0xdcf9c3cc), + TOBN(0x5691fe72, 0xf34089b0), TOBN(0x60941af1, 0xfc7c80ff), + TOBN(0xa09bc0a2, 0x22eb51e5), TOBN(0xc0bb7244, 0xaa9cf09a), + TOBN(0x36a8077f, 0x80159f06), TOBN(0x8b5c989e, 0xdddc560e), + TOBN(0x19d2f316, 0x512e1f43), TOBN(0x02eac554, 0xad08ff62), + TOBN(0x012ab84c, 0x07d20b4e), TOBN(0x37d1e115, 0xd6d4e4e1), + TOBN(0xb6443e1a, 0xab7b19a8), TOBN(0xf08d067e, 0xdef8cd45), + TOBN(0x63adf3e9, 0x685e03da), TOBN(0xcf15a10e, 0x4792b916), + TOBN(0xf44bcce5, 0xb738a425), TOBN(0xebe131d5, 0x9636b2fd), + TOBN(0x94068841, 0x7850d605), TOBN(0x09684eaa, 0xb40d749d), + TOBN(0x8c3c669c, 0x72ba075b), TOBN(0x89f78b55, 0xba469015), + TOBN(0x5706aade, 0x3e9f8ba8), TOBN(0x6d8bd565, 0xb32d7ed7), + TOBN(0x25f4e63b, 0x805f08d6), TOBN(0x7f48200d, 0xc3bcc1b5), + TOBN(0x4e801968, 0xb025d847), TOBN(0x74afac04, 0x87cbe0a8), + TOBN(0x43ed2c2b, 0x7e63d690), TOBN(0xefb6bbf0, 0x0223cdb8), + TOBN(0x4fec3cae, 0x2884d3fe), TOBN(0x065ecce6, 0xd75e25a4), + TOBN(0x6c2294ce, 0x69f79071), TOBN(0x0d9a8e5f, 0x044b8666), + TOBN(0x5009f238, 0x17b69d8f), TOBN(0x3c29f8fe, 0xc5dfdaf7), + TOBN(0x9067528f, 0xebae68c4), TOBN(0x5b385632, 0x30c5ba21), + TOBN(0x540df119, 0x1fdd1aec), TOBN(0xcf37825b, 0xcfba4c78), + TOBN(0x77eff980, 0xbeb11454), TOBN(0x40a1a991, 0x60c1b066), + TOBN(0xe8018980, 0xf889a1c7), TOBN(0xb9c52ae9, 0x76c24be0), + TOBN(0x05fbbcce, 0x45650ef4), TOBN(0xae000f10, 0x8aa29ac7), + TOBN(0x884b7172, 0x4f04c470), TOBN(0x7cd4fde2, 0x19bb5c25), + TOBN(0x6477b22a, 0xe8840869), TOBN(0xa8868859, 0x5fbd0686), + TOBN(0xf23cc02e, 0x1116dfba), TOBN(0x76cd563f, 0xd87d7776), + TOBN(0xe2a37598, 0xa9d82abf), TOBN(0x5f188ccb, 0xe6c170f5), + TOBN(0x81682200, 0x5066b087), TOBN(0xda22c212, 0xc7155ada), + TOBN(0x151e5d3a, 0xfbddb479), TOBN(0x4b606b84, 0x6d715b99), + TOBN(0x4a73b54b, 0xf997cb2e), TOBN(0x9a1bfe43, 0x3ecd8b66), + TOBN(0x1c312809, 0x2a67d48a), TOBN(0xcd6a671e, 0x031fa9e2), + TOBN(0xbec3312a, 0x0e43a34a), TOBN(0x1d935639, 0x55ef47d3), + TOBN(0x5ea02489, 0x8fea73ea), TOBN(0x8247b364, 0xa035afb2), + TOBN(0xb58300a6, 0x5265b54c), TOBN(0x3286662f, 0x722c7148), + TOBN(0xb77fd76b, 0xb4ec4c20), TOBN(0xf0a12fa7, 0x0f3fe3fd), + TOBN(0xf845bbf5, 0x41d8c7e8), TOBN(0xe4d969ca, 0x5ec10aa8), + TOBN(0x4c0053b7, 0x43e232a3), TOBN(0xdc7a3fac, 0x37f8a45a), + TOBN(0x3c4261c5, 0x20d81c8f), TOBN(0xfd4b3453, 0xb00eab00), + TOBN(0x76d48f86, 0xd36e3062), TOBN(0x626c5277, 0xa143ff02), + TOBN(0x538174de, 0xaf76f42e), TOBN(0x2267aa86, 0x6407ceac), + TOBN(0xfad76351, 0x72e572d5), TOBN(0xab861af7, 0xba7330eb), + TOBN(0xa0a1c8c7, 0x418d8657), TOBN(0x988821cb, 0x20289a52), + TOBN(0x79732522, 0xcccc18ad), TOBN(0xaadf3f8d, 0xf1a6e027), + TOBN(0xf7382c93, 0x17c2354d), TOBN(0x5ce1680c, 0xd818b689), + TOBN(0x359ebbfc, 0xd9ecbee9), TOBN(0x4330689c, 0x1cae62ac), + TOBN(0xb55ce5b4, 0xc51ac38a), TOBN(0x7921dfea, 0xfe238ee8), + TOBN(0x3972bef8, 0x271d1ca5), TOBN(0x3e423bc7, 0xe8aabd18), + TOBN(0x57b09f3f, 0x44a3e5e3), TOBN(0x5da886ae, 0x7b444d66), + TOBN(0x68206634, 0xa9964375), TOBN(0x356a2fa3, 0x699cd0ff), + TOBN(0xaf0faa24, 0xdba515e9), TOBN(0x536e1f5c, 0xb321d79a), + TOBN(0xd3b9913a, 0x5c04e4ea), TOBN(0xd549dcfe, 0xd6f11513), + TOBN(0xee227bf5, 0x79fd1d94), TOBN(0x9f35afee, 0xb43f2c67), + TOBN(0xd2638d24, 0xf1314f53), TOBN(0x62baf948, 0xcabcd822), + TOBN(0x5542de29, 0x4ef48db0), TOBN(0xb3eb6a04, 0xfc5f6bb2), + TOBN(0x23c110ae, 0x1208e16a), TOBN(0x1a4d15b5, 0xf8363e24), + TOBN(0x30716844, 0x164be00b), TOBN(0xa8e24824, 0xf6f4690d), + TOBN(0x548773a2, 0x90b170cf), TOBN(0xa1bef331, 0x42f191f4), + TOBN(0x70f418d0, 0x9247aa97), TOBN(0xea06028e, 0x48be9147), + TOBN(0xe13122f3, 0xdbfb894e), TOBN(0xbe9b79f6, 0xce274b18), + TOBN(0x85a49de5, 0xca58aadf), TOBN(0x24957758, 0x11487351), + TOBN(0x111def61, 0xbb939099), TOBN(0x1d6a974a, 0x26d13694), + TOBN(0x4474b4ce, 0xd3fc253b), TOBN(0x3a1485e6, 0x4c5db15e), + TOBN(0xe79667b4, 0x147c15b4), TOBN(0xe34f553b, 0x7bc61301), + TOBN(0x032b80f8, 0x17094381), TOBN(0x55d8bafd, 0x723eaa21), + TOBN(0x5a987995, 0xf1c0e74e), TOBN(0x5a9b292e, 0xebba289c), + TOBN(0x413cd4b2, 0xeb4c8251), TOBN(0x98b5d243, 0xd162db0a), + TOBN(0xbb47bf66, 0x68342520), TOBN(0x08d68949, 0xbaa862d1), + TOBN(0x11f349c7, 0xe906abcd), TOBN(0x454ce985, 0xed7bf00e), + TOBN(0xacab5c9e, 0xb55b803b), TOBN(0xb03468ea, 0x31e3c16d), + TOBN(0x5c24213d, 0xd273bf12), TOBN(0x211538eb, 0x71587887), + TOBN(0x198e4a2f, 0x731dea2d), TOBN(0xd5856cf2, 0x74ed7b2a), + TOBN(0x86a632eb, 0x13a664fe), TOBN(0x932cd909, 0xbda41291), + TOBN(0x850e95d4, 0xc0c4ddc0), TOBN(0xc0f422f8, 0x347fc2c9), + TOBN(0xe68cbec4, 0x86076bcb), TOBN(0xf9e7c0c0, 0xcd6cd286), + TOBN(0x65994ddb, 0x0f5f27ca), TOBN(0xe85461fb, 0xa80d59ff), + TOBN(0xff05481a, 0x66601023), TOBN(0xc665427a, 0xfc9ebbfb), + TOBN(0xb0571a69, 0x7587fd52), TOBN(0x935289f8, 0x8d49efce), + TOBN(0x61becc60, 0xea420688), TOBN(0xb22639d9, 0x13a786af), + TOBN(0x1a8e6220, 0x361ecf90), TOBN(0x001f23e0, 0x25506463), + TOBN(0xe4ae9b5d, 0x0a5c2b79), TOBN(0xebc9cdad, 0xd8149db5), + TOBN(0xb33164a1, 0x934aa728), TOBN(0x750eb00e, 0xae9b60f3), + TOBN(0x5a91615b, 0x9b9cfbfd), TOBN(0x97015cbf, 0xef45f7f6), + TOBN(0xb462c4a5, 0xbf5151df), TOBN(0x21adcc41, 0xb07118f2), + TOBN(0xd60c545b, 0x043fa42c), TOBN(0xfc21aa54, 0xe96be1ab), + TOBN(0xe84bc32f, 0x4e51ea80), TOBN(0x3dae45f0, 0x259b5d8d), + TOBN(0xbb73c7eb, 0xc38f1b5e), TOBN(0xe405a74a, 0xe8ae617d), + TOBN(0xbb1ae9c6, 0x9f1c56bd), TOBN(0x8c176b98, 0x49f196a4), + TOBN(0xc448f311, 0x6875092b), TOBN(0xb5afe3de, 0x9f976033), + TOBN(0xa8dafd49, 0x145813e5), TOBN(0x687fc4d9, 0xe2b34226), + TOBN(0xf2dfc92d, 0x4c7ff57f), TOBN(0x004e3fc1, 0x401f1b46), + TOBN(0x5afddab6, 0x1430c9ab), TOBN(0x0bdd41d3, 0x2238e997), + TOBN(0xf0947430, 0x418042ae), TOBN(0x71f9adda, 0xcdddc4cb), + TOBN(0x7090c016, 0xc52dd907), TOBN(0xd9bdf44d, 0x29e2047f), + TOBN(0xe6f1fe80, 0x1b1011a6), TOBN(0xb63accbc, 0xd9acdc78), + TOBN(0xcfc7e235, 0x1272a95b), TOBN(0x0c667717, 0xa6276ac8), + TOBN(0x3c0d3709, 0xe2d7eef7), TOBN(0x5add2b06, 0x9a685b3e), + TOBN(0x363ad32d, 0x14ea5d65), TOBN(0xf8e01f06, 0x8d7dd506), + TOBN(0xc9ea2213, 0x75b4aac6), TOBN(0xed2a2bf9, 0x0d353466), + TOBN(0x439d79b5, 0xe9d3a7c3), TOBN(0x8e0ee5a6, 0x81b7f34b), + TOBN(0xcf3dacf5, 0x1dc4ba75), TOBN(0x1d3d1773, 0xeb3310c7), + TOBN(0xa8e67112, 0x7747ae83), TOBN(0x31f43160, 0x197d6b40), + TOBN(0x0521ccee, 0xcd961400), TOBN(0x67246f11, 0xf6535768), + TOBN(0x702fcc5a, 0xef0c3133), TOBN(0x247cc45d, 0x7e16693b), + TOBN(0xfd484e49, 0xc729b749), TOBN(0x522cef7d, 0xb218320f), + TOBN(0xe56ef405, 0x59ab93b3), TOBN(0x225fba11, 0x9f181071), + TOBN(0x33bd6595, 0x15330ed0), TOBN(0xc4be69d5, 0x1ddb32f7), + TOBN(0x264c7668, 0x0448087c), TOBN(0xac30903f, 0x71432dae), + TOBN(0x3851b266, 0x00f9bf47), TOBN(0x400ed311, 0x6cdd6d03), + TOBN(0x045e79fe, 0xf8fd2424), TOBN(0xfdfd974a, 0xfa6da98b), + TOBN(0x45c9f641, 0x0c1e673a), TOBN(0x76f2e733, 0x5b2c5168), + TOBN(0x1adaebb5, 0x2a601753), TOBN(0xb286514c, 0xc57c2d49), + TOBN(0xd8769670, 0x1e0bfd24), TOBN(0x950c547e, 0x04478922), + TOBN(0xd1d41969, 0xe5d32bfe), TOBN(0x30bc1472, 0x750d6c3e), + TOBN(0x8f3679fe, 0xe0e27f3a), TOBN(0x8f64a7dc, 0xa4a6ee0c), + TOBN(0x2fe59937, 0x633dfb1f), TOBN(0xea82c395, 0x977f2547), + TOBN(0xcbdfdf1a, 0x661ea646), TOBN(0xc7ccc591, 0xb9085451), + TOBN(0x82177962, 0x81761e13), TOBN(0xda57596f, 0x9196885c), + TOBN(0xbc17e849, 0x28ffbd70), TOBN(0x1e6e0a41, 0x2671d36f), + TOBN(0x61ae872c, 0x4152fcf5), TOBN(0x441c87b0, 0x9e77e754), + TOBN(0xd0799dd5, 0xa34dff09), TOBN(0x766b4e44, 0x88a6b171), + TOBN(0xdc06a512, 0x11f1c792), TOBN(0xea02ae93, 0x4be35c3e), + TOBN(0xe5ca4d6d, 0xe90c469e), TOBN(0x4df4368e, 0x56e4ff5c), + TOBN(0x7817acab, 0x4baef62e), TOBN(0x9f5a2202, 0xa85b91e8), + TOBN(0x9666ebe6, 0x6ce57610), TOBN(0x32ad31f3, 0xf73bfe03), + TOBN(0x628330a4, 0x25bcf4d6), TOBN(0xea950593, 0x515056e6), + TOBN(0x59811c89, 0xe1332156), TOBN(0xc89cf1fe, 0x8c11b2d7), + TOBN(0x75b63913, 0x04e60cc0), TOBN(0xce811e8d, 0x4625d375), + TOBN(0x030e43fc, 0x2d26e562), TOBN(0xfbb30b4b, 0x608d36a0), + TOBN(0x634ff82c, 0x48528118), TOBN(0x7c6fe085, 0xcd285911), + TOBN(0x7f2830c0, 0x99358f28), TOBN(0x2e60a95e, 0x665e6c09), + TOBN(0x08407d3d, 0x9b785dbf), TOBN(0x530889ab, 0xa759bce7), + TOBN(0xf228e0e6, 0x52f61239), TOBN(0x2b6d1461, 0x6879be3c), + TOBN(0xe6902c04, 0x51a7bbf7), TOBN(0x30ad99f0, 0x76f24a64), + TOBN(0x66d9317a, 0x98bc6da0), TOBN(0xf4f877f3, 0xcb596ac0), + TOBN(0xb05ff62d, 0x4c44f119), TOBN(0x4555f536, 0xe9b77416), + TOBN(0xc7c0d059, 0x8caed63b), TOBN(0x0cd2b7ce, 0xc358b2a9), + TOBN(0x3f33287b, 0x46945fa3), TOBN(0xf8785b20, 0xd67c8791), + TOBN(0xc54a7a61, 0x9637bd08), TOBN(0x54d4598c, 0x18be79d7), + TOBN(0x889e5acb, 0xc46d7ce1), TOBN(0x9a515bb7, 0x8b085877), + TOBN(0xfac1a03d, 0x0b7a5050), TOBN(0x7d3e738a, 0xf2926035), + TOBN(0x861cc2ce, 0x2a6cb0eb), TOBN(0x6f2e2955, 0x8f7adc79), + TOBN(0x61c4d451, 0x33016376), TOBN(0xd9fd2c80, 0x5ad59090), + TOBN(0xe5a83738, 0xb2b836a1), TOBN(0x855b41a0, 0x7c0d6622), + TOBN(0x186fe317, 0x7cc19af1), TOBN(0x6465c1ff, 0xfdd99acb), + TOBN(0x46e5c23f, 0x6974b99e), TOBN(0x75a7cf8b, 0xa2717cbe), + TOBN(0x4d2ebc3f, 0x062be658), TOBN(0x094b4447, 0x5f209c98), + TOBN(0x4af285ed, 0xb940cb5a), TOBN(0x6706d792, 0x7cc82f10), + TOBN(0xc8c8776c, 0x030526fa), TOBN(0xfa8e6f76, 0xa0da9140), + TOBN(0x77ea9d34, 0x591ee4f0), TOBN(0x5f46e337, 0x40274166), + TOBN(0x1bdf98bb, 0xea671457), TOBN(0xd7c08b46, 0x862a1fe2), + TOBN(0x46cc303c, 0x1c08ad63), TOBN(0x99543440, 0x4c845e7b), + TOBN(0x1b8fbdb5, 0x48f36bf7), TOBN(0x5b82c392, 0x8c8273a7), + TOBN(0x08f712c4, 0x928435d5), TOBN(0x071cf0f1, 0x79330380), + TOBN(0xc74c2d24, 0xa8da054a), TOBN(0xcb0e7201, 0x43c46b5c), + TOBN(0x0ad7337a, 0xc0b7eff3), TOBN(0x8552225e, 0xc5e48b3c), + TOBN(0xe6f78b0c, 0x73f13a5f), TOBN(0x5e70062e, 0x82349cbe), + TOBN(0x6b8d5048, 0xe7073969), TOBN(0x392d2a29, 0xc33cb3d2), + TOBN(0xee4f727c, 0x4ecaa20f), TOBN(0xa068c99e, 0x2ccde707), + TOBN(0xfcd5651f, 0xb87a2913), TOBN(0xea3e3c15, 0x3cc252f0), + TOBN(0x777d92df, 0x3b6cd3e4), TOBN(0x7a414143, 0xc5a732e7), + TOBN(0xa895951a, 0xa71ff493), TOBN(0xfe980c92, 0xbbd37cf6), + TOBN(0x45bd5e64, 0xdecfeeff), TOBN(0x910dc2a9, 0xa44c43e9), + TOBN(0xcb403f26, 0xcca9f54d), TOBN(0x928bbdfb, 0x9303f6db), + TOBN(0x3c37951e, 0xa9eee67c), TOBN(0x3bd61a52, 0xf79961c3), + TOBN(0x09a238e6, 0x395c9a79), TOBN(0x6940ca2d, 0x61eb352d), + TOBN(0x7d1e5c5e, 0xc1875631), TOBN(0x1e19742c, 0x1e1b20d1), + TOBN(0x4633d908, 0x23fc2e6e), TOBN(0xa76e29a9, 0x08959149), + TOBN(0x61069d9c, 0x84ed7da5), TOBN(0x0baa11cf, 0x5dbcad51), + TOBN(0xd01eec64, 0x961849da), TOBN(0x93b75f1f, 0xaf3d8c28), + TOBN(0x57bc4f9f, 0x1ca2ee44), TOBN(0x5a26322d, 0x00e00558), + TOBN(0x1888d658, 0x61a023ef), TOBN(0x1d72aab4, 0xb9e5246e), + TOBN(0xa9a26348, 0xe5563ec0), TOBN(0xa0971963, 0xc3439a43), + TOBN(0x567dd54b, 0xadb9b5b7), TOBN(0x73fac1a1, 0xc45a524b), + TOBN(0x8fe97ef7, 0xfe38e608), TOBN(0x608748d2, 0x3f384f48), + TOBN(0xb0571794, 0xc486094f), TOBN(0x869254a3, 0x8bf3a8d6), + TOBN(0x148a8dd1, 0x310b0e25), TOBN(0x99ab9f3f, 0x9aa3f7d8), + TOBN(0x0927c68a, 0x6706c02e), TOBN(0x22b5e76c, 0x69790e6c), + TOBN(0x6c325260, 0x6c71376c), TOBN(0x53a57690, 0x09ef6657), + TOBN(0x8d63f852, 0xedffcf3a), TOBN(0xb4d2ed04, 0x3c0a6f55), + TOBN(0xdb3aa8de, 0x12519b9e), TOBN(0x5d38e9c4, 0x1e0a569a), + TOBN(0x871528bf, 0x303747e2), TOBN(0xa208e77c, 0xf5b5c18d), + TOBN(0x9d129c88, 0xca6bf923), TOBN(0xbcbf197f, 0xbf02839f), + TOBN(0x9b9bf030, 0x27323194), TOBN(0x3b055a8b, 0x339ca59d), + TOBN(0xb46b2312, 0x0f669520), TOBN(0x19789f1f, 0x497e5f24), + TOBN(0x9c499468, 0xaaf01801), TOBN(0x72ee1190, 0x8b69d59c), + TOBN(0x8bd39595, 0xacf4c079), TOBN(0x3ee11ece, 0x8e0cd048), + TOBN(0xebde86ec, 0x1ed66f18), TOBN(0x225d906b, 0xd61fce43), + TOBN(0x5cab07d6, 0xe8bed74d), TOBN(0x16e4617f, 0x27855ab7), + TOBN(0x6568aadd, 0xb2fbc3dd), TOBN(0xedb5484f, 0x8aeddf5b), + TOBN(0x878f20e8, 0x6dcf2fad), TOBN(0x3516497c, 0x615f5699)}, + {TOBN(0xef0a3fec, 0xfa181e69), TOBN(0x9ea02f81, 0x30d69a98), + TOBN(0xb2e9cf8e, 0x66eab95d), TOBN(0x520f2beb, 0x24720021), + TOBN(0x621c540a, 0x1df84361), TOBN(0x12037721, 0x71fa6d5d), + TOBN(0x6e3c7b51, 0x0ff5f6ff), TOBN(0x817a069b, 0xabb2bef3), + TOBN(0x83572fb6, 0xb294cda6), TOBN(0x6ce9bf75, 0xb9039f34), + TOBN(0x20e012f0, 0x095cbb21), TOBN(0xa0aecc1b, 0xd063f0da), + TOBN(0x57c21c3a, 0xf02909e5), TOBN(0xc7d59ecf, 0x48ce9cdc), + TOBN(0x2732b844, 0x8ae336f8), TOBN(0x056e3723, 0x3f4f85f4), + TOBN(0x8a10b531, 0x89e800ca), TOBN(0x50fe0c17, 0x145208fd), + TOBN(0x9e43c0d3, 0xb714ba37), TOBN(0x427d200e, 0x34189acc), + TOBN(0x05dee24f, 0xe616e2c0), TOBN(0x9c25f4c8, 0xee1854c1), + TOBN(0x4d3222a5, 0x8f342a73), TOBN(0x0807804f, 0xa027c952), + TOBN(0xc222653a, 0x4f0d56f3), TOBN(0x961e4047, 0xca28b805), + TOBN(0x2c03f8b0, 0x4a73434b), TOBN(0x4c966787, 0xab712a19), + TOBN(0xcc196c42, 0x864fee42), TOBN(0xc1be93da, 0x5b0ece5c), + TOBN(0xa87d9f22, 0xc131c159), TOBN(0x2bb6d593, 0xdce45655), + TOBN(0x22c49ec9, 0xb809b7ce), TOBN(0x8a41486b, 0xe2c72c2c), + TOBN(0x813b9420, 0xfea0bf36), TOBN(0xb3d36ee9, 0xa66dac69), + TOBN(0x6fddc08a, 0x328cc987), TOBN(0x0a3bcd2c, 0x3a326461), + TOBN(0x7103c49d, 0xd810dbba), TOBN(0xf9d81a28, 0x4b78a4c4), + TOBN(0x3de865ad, 0xe4d55941), TOBN(0xdedafa5e, 0x30384087), + TOBN(0x6f414abb, 0x4ef18b9b), TOBN(0x9ee9ea42, 0xfaee5268), + TOBN(0x260faa16, 0x37a55a4a), TOBN(0xeb19a514, 0x015f93b9), + TOBN(0x51d7ebd2, 0x9e9c3598), TOBN(0x523fc56d, 0x1932178e), + TOBN(0x501d070c, 0xb98fe684), TOBN(0xd60fbe9a, 0x124a1458), + TOBN(0xa45761c8, 0x92bc6b3f), TOBN(0xf5384858, 0xfe6f27cb), + TOBN(0x4b0271f7, 0xb59e763b), TOBN(0x3d4606a9, 0x5b5a8e5e), + TOBN(0x1eda5d9b, 0x05a48292), TOBN(0xda7731d0, 0xe6fec446), + TOBN(0xa3e33693, 0x90d45871), TOBN(0xe9764040, 0x06166d8d), + TOBN(0xb5c33682, 0x89a90403), TOBN(0x4bd17983, 0x72f1d637), + TOBN(0xa616679e, 0xd5d2c53a), TOBN(0x5ec4bcd8, 0xfdcf3b87), + TOBN(0xae6d7613, 0xb66a694e), TOBN(0x7460fc76, 0xe3fc27e5), + TOBN(0x70469b82, 0x95caabee), TOBN(0xde024ca5, 0x889501e3), + TOBN(0x6bdadc06, 0x076ed265), TOBN(0x0cb1236b, 0x5a0ef8b2), + TOBN(0x4065ddbf, 0x0972ebf9), TOBN(0xf1dd3875, 0x22aca432), + TOBN(0xa88b97cf, 0x744aff76), TOBN(0xd1359afd, 0xfe8e3d24), + TOBN(0x52a3ba2b, 0x91502cf3), TOBN(0x2c3832a8, 0x084db75d), + TOBN(0x04a12ddd, 0xde30b1c9), TOBN(0x7802eabc, 0xe31fd60c), + TOBN(0x33707327, 0xa37fddab), TOBN(0x65d6f2ab, 0xfaafa973), + TOBN(0x3525c5b8, 0x11e6f91a), TOBN(0x76aeb0c9, 0x5f46530b), + TOBN(0xe8815ff6, 0x2f93a675), TOBN(0xa6ec9684, 0x05f48679), + TOBN(0x6dcbb556, 0x358ae884), TOBN(0x0af61472, 0xe19e3873), + TOBN(0x72334372, 0xa5f696be), TOBN(0xc65e57ea, 0x6f22fb70), + TOBN(0x268da30c, 0x946cea90), TOBN(0x136a8a87, 0x65681b2a), + TOBN(0xad5e81dc, 0x0f9f44d4), TOBN(0xf09a6960, 0x2c46585a), + TOBN(0xd1649164, 0xc447d1b1), TOBN(0x3b4b36c8, 0x879dc8b1), + TOBN(0x20d4177b, 0x3b6b234c), TOBN(0x096a2505, 0x1730d9d0), + TOBN(0x0611b9b8, 0xef80531d), TOBN(0xba904b3b, 0x64bb495d), + TOBN(0x1192d9d4, 0x93a3147a), TOBN(0x9f30a5dc, 0x9a565545), + TOBN(0x90b1f9cb, 0x6ef07212), TOBN(0x29958546, 0x0d87fc13), + TOBN(0xd3323eff, 0xc17db9ba), TOBN(0xcb18548c, 0xcb1644a8), + TOBN(0x18a306d4, 0x4f49ffbc), TOBN(0x28d658f1, 0x4c2e8684), + TOBN(0x44ba60cd, 0xa99f8c71), TOBN(0x67b7abdb, 0x4bf742ff), + TOBN(0x66310f9c, 0x914b3f99), TOBN(0xae430a32, 0xf412c161), + TOBN(0x1e6776d3, 0x88ace52f), TOBN(0x4bc0fa24, 0x52d7067d), + TOBN(0x03c286aa, 0x8f07cd1b), TOBN(0x4cb8f38c, 0xa985b2c1), + TOBN(0x83ccbe80, 0x8c3bff36), TOBN(0x005a0bd2, 0x5263e575), + TOBN(0x460d7dda, 0x259bdcd1), TOBN(0x4a1c5642, 0xfa5cab6b), + TOBN(0x2b7bdbb9, 0x9fe4fc88), TOBN(0x09418e28, 0xcc97bbb5), + TOBN(0xd8274fb4, 0xa12321ae), TOBN(0xb137007d, 0x5c87b64e), + TOBN(0x80531fe1, 0xc63c4962), TOBN(0x50541e89, 0x981fdb25), + TOBN(0xdc1291a1, 0xfd4c2b6b), TOBN(0xc0693a17, 0xa6df4fca), + TOBN(0xb2c4604e, 0x0117f203), TOBN(0x245f1963, 0x0a99b8d0), + TOBN(0xaedc20aa, 0xc6212c44), TOBN(0xb1ed4e56, 0x520f52a8), + TOBN(0xfe48f575, 0xf8547be3), TOBN(0x0a7033cd, 0xa9e45f98), + TOBN(0x4b45d3a9, 0x18c50100), TOBN(0xb2a6cd6a, 0xa61d41da), + TOBN(0x60bbb4f5, 0x57933c6b), TOBN(0xa7538ebd, 0x2b0d7ffc), + TOBN(0x9ea3ab8d, 0x8cd626b6), TOBN(0x8273a484, 0x3601625a), + TOBN(0x88859845, 0x0168e508), TOBN(0x8cbc9bb2, 0x99a94abd), + TOBN(0x713ac792, 0xfab0a671), TOBN(0xa3995b19, 0x6c9ebffc), + TOBN(0xe711668e, 0x1239e152), TOBN(0x56892558, 0xbbb8dff4), + TOBN(0x8bfc7dab, 0xdbf17963), TOBN(0x5b59fe5a, 0xb3de1253), + TOBN(0x7e3320eb, 0x34a9f7ae), TOBN(0xe5e8cf72, 0xd751efe4), + TOBN(0x7ea003bc, 0xd9be2f37), TOBN(0xc0f551a0, 0xb6c08ef7), + TOBN(0x56606268, 0x038f6725), TOBN(0x1dd38e35, 0x6d92d3b6), + TOBN(0x07dfce7c, 0xc3cbd686), TOBN(0x4e549e04, 0x651c5da8), + TOBN(0x4058f93b, 0x08b19340), TOBN(0xc2fae6f4, 0xcac6d89d), + TOBN(0x4bad8a8c, 0x8f159cc7), TOBN(0x0ddba4b3, 0xcb0b601c), + TOBN(0xda4fc7b5, 0x1dd95f8c), TOBN(0x1d163cd7, 0xcea5c255), + TOBN(0x30707d06, 0x274a8c4c), TOBN(0x79d9e008, 0x2802e9ce), + TOBN(0x02a29ebf, 0xe6ddd505), TOBN(0x37064e74, 0xb50bed1a), + TOBN(0x3f6bae65, 0xa7327d57), TOBN(0x3846f5f1, 0xf83920bc), + TOBN(0x87c37491, 0x60df1b9b), TOBN(0x4cfb2895, 0x2d1da29f), + TOBN(0x10a478ca, 0x4ed1743c), TOBN(0x390c6030, 0x3edd47c6), + TOBN(0x8f3e5312, 0x8c0a78de), TOBN(0xccd02bda, 0x1e85df70), + TOBN(0xd6c75c03, 0xa61b6582), TOBN(0x0762921c, 0xfc0eebd1), + TOBN(0xd34d0823, 0xd85010c0), TOBN(0xd73aaacb, 0x0044cf1f), + TOBN(0xfb4159bb, 0xa3b5e78a), TOBN(0x2287c7f7, 0xe5826f3f), + TOBN(0x4aeaf742, 0x580b1a01), TOBN(0xf080415d, 0x60423b79), + TOBN(0xe12622cd, 0xa7dea144), TOBN(0x49ea4996, 0x59d62472), + TOBN(0xb42991ef, 0x571f3913), TOBN(0x0610f214, 0xf5b25a8a), + TOBN(0x47adc585, 0x30b79e8f), TOBN(0xf90e3df6, 0x07a065a2), + TOBN(0x5d0a5deb, 0x43e2e034), TOBN(0x53fb5a34, 0x444024aa), + TOBN(0xa8628c68, 0x6b0c9f7f), TOBN(0x9c69c29c, 0xac563656), + TOBN(0x5a231feb, 0xbace47b6), TOBN(0xbdce0289, 0x9ea5a2ec), + TOBN(0x05da1fac, 0x9463853e), TOBN(0x96812c52, 0x509e78aa), + TOBN(0xd3fb5771, 0x57151692), TOBN(0xeb2721f8, 0xd98e1c44), + TOBN(0xc0506087, 0x32399be1), TOBN(0xda5a5511, 0xd979d8b8), + TOBN(0x737ed55d, 0xc6f56780), TOBN(0xe20d3004, 0x0dc7a7f4), + TOBN(0x02ce7301, 0xf5941a03), TOBN(0x91ef5215, 0xed30f83a), + TOBN(0x28727fc1, 0x4092d85f), TOBN(0x72d223c6, 0x5c49e41a), + TOBN(0xa7cf30a2, 0xba6a4d81), TOBN(0x7c086209, 0xb030d87d), + TOBN(0x04844c7d, 0xfc588b09), TOBN(0x728cd499, 0x5874bbb0), + TOBN(0xcc1281ee, 0xe84c0495), TOBN(0x0769b5ba, 0xec31958f), + TOBN(0x665c228b, 0xf99c2471), TOBN(0xf2d8a11b, 0x191eb110), + TOBN(0x4594f494, 0xd36d7024), TOBN(0x482ded8b, 0xcdcb25a1), + TOBN(0xc958a9d8, 0xdadd4885), TOBN(0x7004477e, 0xf1d2b547), + TOBN(0x0a45f6ef, 0x2a0af550), TOBN(0x4fc739d6, 0x2f8d6351), + TOBN(0x75cdaf27, 0x786f08a9), TOBN(0x8700bb26, 0x42c2737f), + TOBN(0x855a7141, 0x1c4e2670), TOBN(0x810188c1, 0x15076fef), + TOBN(0xc251d0c9, 0xabcd3297), TOBN(0xae4c8967, 0xf48108eb), + TOBN(0xbd146de7, 0x18ceed30), TOBN(0xf9d4f07a, 0xc986bced), + TOBN(0x5ad98ed5, 0x83fa1e08), TOBN(0x7780d33e, 0xbeabd1fb), + TOBN(0xe330513c, 0x903b1196), TOBN(0xba11de9e, 0xa47bc8c4), + TOBN(0x684334da, 0x02c2d064), TOBN(0x7ecf360d, 0xa48de23b), + TOBN(0x57a1b474, 0x0a9089d8), TOBN(0xf28fa439, 0xff36734c), + TOBN(0xf2a482cb, 0xea4570b3), TOBN(0xee65d68b, 0xa5ebcee9), + TOBN(0x988d0036, 0xb9694cd5), TOBN(0x53edd0e9, 0x37885d32), + TOBN(0xe37e3307, 0xbeb9bc6d), TOBN(0xe9abb907, 0x9f5c6768), + TOBN(0x4396ccd5, 0x51f2160f), TOBN(0x2500888c, 0x47336da6), + TOBN(0x383f9ed9, 0x926fce43), TOBN(0x809dd1c7, 0x04da2930), + TOBN(0x30f6f596, 0x8a4cb227), TOBN(0x0d700c7f, 0x73a56b38), + TOBN(0x1825ea33, 0xab64a065), TOBN(0xaab9b735, 0x1338df80), + TOBN(0x1516100d, 0x9b63f57f), TOBN(0x2574395a, 0x27a6a634), + TOBN(0xb5560fb6, 0x700a1acd), TOBN(0xe823fd73, 0xfd999681), + TOBN(0xda915d1f, 0x6cb4e1ba), TOBN(0x0d030118, 0x6ebe00a3), + TOBN(0x744fb0c9, 0x89fca8cd), TOBN(0x970d01db, 0xf9da0e0b), + TOBN(0x0ad8c564, 0x7931d76f), TOBN(0xb15737bf, 0xf659b96a), + TOBN(0xdc9933e8, 0xa8b484e7), TOBN(0xb2fdbdf9, 0x7a26dec7), + TOBN(0x2349e9a4, 0x9f1f0136), TOBN(0x7860368e, 0x70fddddb), + TOBN(0xd93d2c1c, 0xf9ad3e18), TOBN(0x6d6c5f17, 0x689f4e79), + TOBN(0x7a544d91, 0xb24ff1b6), TOBN(0x3e12a5eb, 0xfe16cd8c), + TOBN(0x543574e9, 0xa56b872f), TOBN(0xa1ad550c, 0xfcf68ea2), + TOBN(0x689e37d2, 0x3f560ef7), TOBN(0x8c54b9ca, 0xc9d47a8b), + TOBN(0x46d40a4a, 0x088ac342), TOBN(0xec450c7c, 0x1576c6d0), + TOBN(0xb589e31c, 0x1f9689e9), TOBN(0xdacf2602, 0xb8781718), + TOBN(0xa89237c6, 0xc8cb6b42), TOBN(0x1326fc93, 0xb96ef381), + TOBN(0x55d56c6d, 0xb5f07825), TOBN(0xacba2eea, 0x7449e22d), + TOBN(0x74e0887a, 0x633c3000), TOBN(0xcb6cd172, 0xd7cbcf71), + TOBN(0x309e81de, 0xc36cf1be), TOBN(0x07a18a6d, 0x60ae399b), + TOBN(0xb36c2679, 0x9edce57e), TOBN(0x52b892f4, 0xdf001d41), + TOBN(0xd884ae5d, 0x16a1f2c6), TOBN(0x9b329424, 0xefcc370a), + TOBN(0x3120daf2, 0xbd2e21df), TOBN(0x55298d2d, 0x02470a99), + TOBN(0x0b78af6c, 0xa05db32e), TOBN(0x5c76a331, 0x601f5636), + TOBN(0xaae861ff, 0xf8a4f29c), TOBN(0x70dc9240, 0xd68f8d49), + TOBN(0x960e649f, 0x81b1321c), TOBN(0x3d2c801b, 0x8792e4ce), + TOBN(0xf479f772, 0x42521876), TOBN(0x0bed93bc, 0x416c79b1), + TOBN(0xa67fbc05, 0x263e5bc9), TOBN(0x01e8e630, 0x521db049), + TOBN(0x76f26738, 0xc6f3431e), TOBN(0xe609cb02, 0xe3267541), + TOBN(0xb10cff2d, 0x818c877c), TOBN(0x1f0e75ce, 0x786a13cb), + TOBN(0xf4fdca64, 0x1158544d), TOBN(0x5d777e89, 0x6cb71ed0), + TOBN(0x3c233737, 0xa9aa4755), TOBN(0x7b453192, 0xe527ab40), + TOBN(0xdb59f688, 0x39f05ffe), TOBN(0x8f4f4be0, 0x6d82574e), + TOBN(0xcce3450c, 0xee292d1b), TOBN(0xaa448a12, 0x61ccd086), + TOBN(0xabce91b3, 0xf7914967), TOBN(0x4537f09b, 0x1908a5ed), + TOBN(0xa812421e, 0xf51042e7), TOBN(0xfaf5cebc, 0xec0b3a34), + TOBN(0x730ffd87, 0x4ca6b39a), TOBN(0x70fb72ed, 0x02efd342), + TOBN(0xeb4735f9, 0xd75c8edb), TOBN(0xc11f2157, 0xc278aa51), + TOBN(0xc459f635, 0xbf3bfebf), TOBN(0x3a1ff0b4, 0x6bd9601f), + TOBN(0xc9d12823, 0xc420cb73), TOBN(0x3e9af3e2, 0x3c2915a3), + TOBN(0xe0c82c72, 0xb41c3440), TOBN(0x175239e5, 0xe3039a5f), + TOBN(0xe1084b8a, 0x558795a3), TOBN(0x328d0a1d, 0xd01e5c60), + TOBN(0x0a495f2e, 0xd3788a04), TOBN(0x25d8ff16, 0x66c11a9f), + TOBN(0xf5155f05, 0x9ed692d6), TOBN(0x954fa107, 0x4f425fe4), + TOBN(0xd16aabf2, 0xe98aaa99), TOBN(0x90cd8ba0, 0x96b0f88a), + TOBN(0x957f4782, 0xc154026a), TOBN(0x54ee0734, 0x52af56d2), + TOBN(0xbcf89e54, 0x45b4147a), TOBN(0x3d102f21, 0x9a52816c), + TOBN(0x6808517e, 0x39b62e77), TOBN(0x92e25421, 0x69169ad8), + TOBN(0xd721d871, 0xbb608558), TOBN(0x60e4ebae, 0xf6d4ff9b), + TOBN(0x0ba10819, 0x41f2763e), TOBN(0xca2e45be, 0x51ee3247), + TOBN(0x66d172ec, 0x2bfd7a5f), TOBN(0x528a8f2f, 0x74d0b12d), + TOBN(0xe17f1e38, 0xdabe70dc), TOBN(0x1d5d7316, 0x9f93983c), + TOBN(0x51b2184a, 0xdf423e31), TOBN(0xcb417291, 0xaedb1a10), + TOBN(0x2054ca93, 0x625bcab9), TOBN(0x54396860, 0xa98998f0), + TOBN(0x4e53f6c4, 0xa54ae57e), TOBN(0x0ffeb590, 0xee648e9d), + TOBN(0xfbbdaadc, 0x6afaf6bc), TOBN(0xf88ae796, 0xaa3bfb8a), + TOBN(0x209f1d44, 0xd2359ed9), TOBN(0xac68dd03, 0xf3544ce2), + TOBN(0xf378da47, 0xfd51e569), TOBN(0xe1abd860, 0x2cc80097), + TOBN(0x23ca18d9, 0x343b6e3a), TOBN(0x480797e8, 0xb40a1bae), + TOBN(0xd1f0c717, 0x533f3e67), TOBN(0x44896970, 0x06e6cdfc), + TOBN(0x8ca21055, 0x52a82e8d), TOBN(0xb2caf785, 0x78460cdc), + TOBN(0x4c1b7b62, 0xe9037178), TOBN(0xefc09d2c, 0xdb514b58), + TOBN(0x5f2df9ee, 0x9113be5c), TOBN(0x2fbda78f, 0xb3f9271c), + TOBN(0xe09a81af, 0x8f83fc54), TOBN(0x06b13866, 0x8afb5141), + TOBN(0x38f6480f, 0x43e3865d), TOBN(0x72dd77a8, 0x1ddf47d9), + TOBN(0xf2a8e971, 0x4c205ff7), TOBN(0x46d449d8, 0x9d088ad8), + TOBN(0x926619ea, 0x185d706f), TOBN(0xe47e02eb, 0xc7dd7f62), + TOBN(0xe7f120a7, 0x8cbc2031), TOBN(0xc18bef00, 0x998d4ac9), + TOBN(0x18f37a9c, 0x6bdf22da), TOBN(0xefbc432f, 0x90dc82df), + TOBN(0xc52cef8e, 0x5d703651), TOBN(0x82887ba0, 0xd99881a5), + TOBN(0x7cec9dda, 0xb920ec1d), TOBN(0xd0d7e8c3, 0xec3e8d3b), + TOBN(0x445bc395, 0x4ca88747), TOBN(0xedeaa2e0, 0x9fd53535), + TOBN(0x461b1d93, 0x6cc87475), TOBN(0xd92a52e2, 0x6d2383bd), + TOBN(0xfabccb59, 0xd7903546), TOBN(0x6111a761, 0x3d14b112), + TOBN(0x0ae584fe, 0xb3d5f612), TOBN(0x5ea69b8d, 0x60e828ec), + TOBN(0x6c078985, 0x54087030), TOBN(0x649cab04, 0xac4821fe), + TOBN(0x25ecedcf, 0x8bdce214), TOBN(0xb5622f72, 0x86af7361), + TOBN(0x0e1227aa, 0x7038b9e2), TOBN(0xd0efb273, 0xac20fa77), + TOBN(0x817ff88b, 0x79df975b), TOBN(0x856bf286, 0x1999503e), + TOBN(0xb4d5351f, 0x5038ec46), TOBN(0x740a52c5, 0xfc42af6e), + TOBN(0x2e38bb15, 0x2cbb1a3f), TOBN(0xc3eb99fe, 0x17a83429), + TOBN(0xca4fcbf1, 0xdd66bb74), TOBN(0x880784d6, 0xcde5e8fc), + TOBN(0xddc84c1c, 0xb4e7a0be), TOBN(0x8780510d, 0xbd15a72f), + TOBN(0x44bcf1af, 0x81ec30e1), TOBN(0x141e50a8, 0x0a61073e), + TOBN(0x0d955718, 0x47be87ae), TOBN(0x68a61417, 0xf76a4372), + TOBN(0xf57e7e87, 0xc607c3d3), TOBN(0x043afaf8, 0x5252f332), + TOBN(0xcc14e121, 0x1552a4d2), TOBN(0xb6dee692, 0xbb4d4ab4), + TOBN(0xb6ab74c8, 0xa03816a4), TOBN(0x84001ae4, 0x6f394a29), + TOBN(0x5bed8344, 0xd795fb45), TOBN(0x57326e7d, 0xb79f55a5), + TOBN(0xc9533ce0, 0x4accdffc), TOBN(0x53473caf, 0x3993fa04), + TOBN(0x7906eb93, 0xa13df4c8), TOBN(0xa73e51f6, 0x97cbe46f), + TOBN(0xd1ab3ae1, 0x0ae4ccf8), TOBN(0x25614508, 0x8a5b3dbc), + TOBN(0x61eff962, 0x11a71b27), TOBN(0xdf71412b, 0x6bb7fa39), + TOBN(0xb31ba6b8, 0x2bd7f3ef), TOBN(0xb0b9c415, 0x69180d29), + TOBN(0xeec14552, 0x014cdde5), TOBN(0x702c624b, 0x227b4bbb), + TOBN(0x2b15e8c2, 0xd3e988f3), TOBN(0xee3bcc6d, 0xa4f7fd04), + TOBN(0x9d00822a, 0x42ac6c85), TOBN(0x2db0cea6, 0x1df9f2b7), + TOBN(0xd7cad2ab, 0x42de1e58), TOBN(0x346ed526, 0x2d6fbb61), + TOBN(0xb3962995, 0x1a2faf09), TOBN(0x2fa8a580, 0x7c25612e), + TOBN(0x30ae04da, 0x7cf56490), TOBN(0x75662908, 0x0eea3961), + TOBN(0x3609f5c5, 0x3d080847), TOBN(0xcb081d39, 0x5241d4f6), + TOBN(0xb4fb3810, 0x77961a63), TOBN(0xc20c5984, 0x2abb66fc), + TOBN(0x3d40aa7c, 0xf902f245), TOBN(0x9cb12736, 0x4e536b1e), + TOBN(0x5eda24da, 0x99b3134f), TOBN(0xafbd9c69, 0x5cd011af), + TOBN(0x9a16e30a, 0xc7088c7d), TOBN(0x5ab65710, 0x3207389f), + TOBN(0x1b09547f, 0xe7407a53), TOBN(0x2322f9d7, 0x4fdc6eab), + TOBN(0xc0f2f22d, 0x7430de4d), TOBN(0x19382696, 0xe68ca9a9), + TOBN(0x17f1eff1, 0x918e5868), TOBN(0xe3b5b635, 0x586f4204), + TOBN(0x146ef980, 0x3fbc4341), TOBN(0x359f2c80, 0x5b5eed4e), + TOBN(0x9f35744e, 0x7482e41d), TOBN(0x9a9ac3ec, 0xf3b224c2), + TOBN(0x9161a6fe, 0x91fc50ae), TOBN(0x89ccc66b, 0xc613fa7c), + TOBN(0x89268b14, 0xc732f15a), TOBN(0x7cd6f4e2, 0xb467ed03), + TOBN(0xfbf79869, 0xce56b40e), TOBN(0xf93e094c, 0xc02dde98), + TOBN(0xefe0c3a8, 0xedee2cd7), TOBN(0x90f3ffc0, 0xb268fd42), + TOBN(0x81a7fd56, 0x08241aed), TOBN(0x95ab7ad8, 0x00b1afe8), + TOBN(0x40127056, 0x3e310d52), TOBN(0xd3ffdeb1, 0x09d9fc43), + TOBN(0xc8f85c91, 0xd11a8594), TOBN(0x2e74d258, 0x31cf6db8), + TOBN(0x829c7ca3, 0x02b5dfd0), TOBN(0xe389cfbe, 0x69143c86), + TOBN(0xd01b6405, 0x941768d8), TOBN(0x45103995, 0x03bf825d), + TOBN(0xcc4ee166, 0x56cd17e2), TOBN(0xbea3c283, 0xba037e79), + TOBN(0x4e1ac06e, 0xd9a47520), TOBN(0xfbfe18aa, 0xaf852404), + TOBN(0x5615f8e2, 0x8087648a), TOBN(0x7301e47e, 0xb9d150d9), + TOBN(0x79f9f9dd, 0xb299b977), TOBN(0x76697a7b, 0xa5b78314), + TOBN(0x10d67468, 0x7d7c90e7), TOBN(0x7afffe03, 0x937210b5), + TOBN(0x5aef3e4b, 0x28c22cee), TOBN(0xefb0ecd8, 0x09fd55ae), + TOBN(0x4cea7132, 0x0d2a5d6a), TOBN(0x9cfb5fa1, 0x01db6357), + TOBN(0x395e0b57, 0xf36e1ac5), TOBN(0x008fa9ad, 0x36cafb7d), + TOBN(0x8f6cdf70, 0x5308c4db), TOBN(0x51527a37, 0x95ed2477), + TOBN(0xba0dee30, 0x5bd21311), TOBN(0x6ed41b22, 0x909c90d7), + TOBN(0xc5f6b758, 0x7c8696d3), TOBN(0x0db8eaa8, 0x3ce83a80), + TOBN(0xd297fe37, 0xb24b4b6f), TOBN(0xfe58afe8, 0x522d1f0d), + TOBN(0x97358736, 0x8c98dbd9), TOBN(0x6bc226ca, 0x9454a527), + TOBN(0xa12b384e, 0xce53c2d0), TOBN(0x779d897d, 0x5e4606da), + TOBN(0xa53e47b0, 0x73ec12b0), TOBN(0x462dbbba, 0x5756f1ad), + TOBN(0x69fe09f2, 0xcafe37b6), TOBN(0x273d1ebf, 0xecce2e17), + TOBN(0x8ac1d538, 0x3cf607fd), TOBN(0x8035f7ff, 0x12e10c25)}, + {TOBN(0x854d34c7, 0x7e6c5520), TOBN(0xc27df9ef, 0xdcb9ea58), + TOBN(0x405f2369, 0xd686666d), TOBN(0x29d1febf, 0x0417aa85), + TOBN(0x9846819e, 0x93470afe), TOBN(0x3e6a9669, 0xe2a27f9e), + TOBN(0x24d008a2, 0xe31e6504), TOBN(0xdba7cecf, 0x9cb7680a), + TOBN(0xecaff541, 0x338d6e43), TOBN(0x56f7dd73, 0x4541d5cc), + TOBN(0xb5d426de, 0x96bc88ca), TOBN(0x48d94f6b, 0x9ed3a2c3), + TOBN(0x6354a3bb, 0x2ef8279c), TOBN(0xd575465b, 0x0b1867f2), + TOBN(0xef99b0ff, 0x95225151), TOBN(0xf3e19d88, 0xf94500d8), + TOBN(0x92a83268, 0xe32dd620), TOBN(0x913ec99f, 0x627849a2), + TOBN(0xedd8fdfa, 0x2c378882), TOBN(0xaf96f33e, 0xee6f8cfe), + TOBN(0xc06737e5, 0xdc3fa8a5), TOBN(0x236bb531, 0xb0b03a1d), + TOBN(0x33e59f29, 0x89f037b0), TOBN(0x13f9b5a7, 0xd9a12a53), + TOBN(0x0d0df6ce, 0x51efb310), TOBN(0xcb5b2eb4, 0x958df5be), + TOBN(0xd6459e29, 0x36158e59), TOBN(0x82aae2b9, 0x1466e336), + TOBN(0xfb658a39, 0x411aa636), TOBN(0x7152ecc5, 0xd4c0a933), + TOBN(0xf10c758a, 0x49f026b7), TOBN(0xf4837f97, 0xcb09311f), + TOBN(0xddfb02c4, 0xc753c45f), TOBN(0x18ca81b6, 0xf9c840fe), + TOBN(0x846fd09a, 0xb0f8a3e6), TOBN(0xb1162add, 0xe7733dbc), + TOBN(0x7070ad20, 0x236e3ab6), TOBN(0xf88cdaf5, 0xb2a56326), + TOBN(0x05fc8719, 0x997cbc7a), TOBN(0x442cd452, 0x4b665272), + TOBN(0x7807f364, 0xb71698f5), TOBN(0x6ba418d2, 0x9f7b605e), + TOBN(0xfd20b00f, 0xa03b2cbb), TOBN(0x883eca37, 0xda54386f), + TOBN(0xff0be43f, 0xf3437f24), TOBN(0xe910b432, 0xa48bb33c), + TOBN(0x4963a128, 0x329df765), TOBN(0xac1dd556, 0xbe2fe6f7), + TOBN(0x557610f9, 0x24a0a3fc), TOBN(0x38e17bf4, 0xe881c3f9), + TOBN(0x6ba84faf, 0xed0dac99), TOBN(0xd4a222c3, 0x59eeb918), + TOBN(0xc79c1dbe, 0x13f542b6), TOBN(0x1fc65e0d, 0xe425d457), + TOBN(0xeffb754f, 0x1debb779), TOBN(0x638d8fd0, 0x9e08af60), + TOBN(0x994f523a, 0x626332d5), TOBN(0x7bc38833, 0x5561bb44), + TOBN(0x005ed4b0, 0x3d845ea2), TOBN(0xd39d3ee1, 0xc2a1f08a), + TOBN(0x6561fdd3, 0xe7676b0d), TOBN(0x620e35ff, 0xfb706017), + TOBN(0x36ce424f, 0xf264f9a8), TOBN(0xc4c3419f, 0xda2681f7), + TOBN(0xfb6afd2f, 0x69beb6e8), TOBN(0x3a50b993, 0x6d700d03), + TOBN(0xc840b2ad, 0x0c83a14f), TOBN(0x573207be, 0x54085bef), + TOBN(0x5af882e3, 0x09fe7e5b), TOBN(0x957678a4, 0x3b40a7e1), + TOBN(0x172d4bdd, 0x543056e2), TOBN(0x9c1b26b4, 0x0df13c0a), + TOBN(0x1c30861c, 0xf405ff06), TOBN(0xebac86bd, 0x486e828b), + TOBN(0xe791a971, 0x636933fc), TOBN(0x50e7c2be, 0x7aeee947), + TOBN(0xc3d4a095, 0xfa90d767), TOBN(0xae60eb7b, 0xe670ab7b), + TOBN(0x17633a64, 0x397b056d), TOBN(0x93a21f33, 0x105012aa), + TOBN(0x663c370b, 0xabb88643), TOBN(0x91df36d7, 0x22e21599), + TOBN(0x183ba835, 0x8b761671), TOBN(0x381eea1d, 0x728f3bf1), + TOBN(0xb9b2f1ba, 0x39966e6c), TOBN(0x7c464a28, 0xe7295492), + TOBN(0x0fd5f70a, 0x09b26b7f), TOBN(0xa9aba1f9, 0xfbe009df), + TOBN(0x857c1f22, 0x369b87ad), TOBN(0x3c00e5d9, 0x32fca556), + TOBN(0x1ad74cab, 0x90b06466), TOBN(0xa7112386, 0x550faaf2), + TOBN(0x7435e198, 0x6d9bd5f5), TOBN(0x2dcc7e38, 0x59c3463f), + TOBN(0xdc7df748, 0xca7bd4b2), TOBN(0x13cd4c08, 0x9dec2f31), + TOBN(0x0d3b5df8, 0xe3237710), TOBN(0x0dadb26e, 0xcbd2f7b0), + TOBN(0x9f5966ab, 0xe4aa082b), TOBN(0x666ec8de, 0x350e966e), + TOBN(0x1bfd1ed5, 0xee524216), TOBN(0xcd93c59b, 0x41dab0b6), + TOBN(0x658a8435, 0xd186d6ba), TOBN(0x1b7d34d2, 0x159d1195), + TOBN(0x5936e460, 0x22caf46b), TOBN(0x6a45dd8f, 0x9a96fe4f), + TOBN(0xf7925434, 0xb98f474e), TOBN(0x41410412, 0x0053ef15), + TOBN(0x71cf8d12, 0x41de97bf), TOBN(0xb8547b61, 0xbd80bef4), + TOBN(0xb47d3970, 0xc4db0037), TOBN(0xf1bcd328, 0xfef20dff), + TOBN(0x31a92e09, 0x10caad67), TOBN(0x1f591960, 0x5531a1e1), + TOBN(0x3bb852e0, 0x5f4fc840), TOBN(0x63e297ca, 0x93a72c6c), + TOBN(0x3c2b0b2e, 0x49abad67), TOBN(0x6ec405fc, 0xed3db0d9), + TOBN(0xdc14a530, 0x7fef1d40), TOBN(0xccd19846, 0x280896fc), + TOBN(0x00f83176, 0x9bb81648), TOBN(0xd69eb485, 0x653120d0), + TOBN(0xd17d75f4, 0x4ccabc62), TOBN(0x34a07f82, 0xb749fcb1), + TOBN(0x2c3af787, 0xbbfb5554), TOBN(0xb06ed4d0, 0x62e283f8), + TOBN(0x5722889f, 0xa19213a0), TOBN(0x162b085e, 0xdcf3c7b4), + TOBN(0xbcaecb31, 0xe0dd3eca), TOBN(0xc6237fbc, 0xe52f13a5), + TOBN(0xcc2b6b03, 0x27bac297), TOBN(0x2ae1cac5, 0xb917f54a), + TOBN(0x474807d4, 0x7845ae4f), TOBN(0xfec7dd92, 0xce5972e0), + TOBN(0xc3bd2541, 0x1d7915bb), TOBN(0x66f85dc4, 0xd94907ca), + TOBN(0xd981b888, 0xbdbcf0ca), TOBN(0xd75f5da6, 0xdf279e9f), + TOBN(0x128bbf24, 0x7054e934), TOBN(0x3c6ff6e5, 0x81db134b), + TOBN(0x795b7cf4, 0x047d26e4), TOBN(0xf370f7b8, 0x5049ec37), + TOBN(0xc6712d4d, 0xced945af), TOBN(0xdf30b5ec, 0x095642bc), + TOBN(0x9b034c62, 0x4896246e), TOBN(0x5652c016, 0xee90bbd1), + TOBN(0xeb38636f, 0x87fedb73), TOBN(0x5e32f847, 0x0135a613), + TOBN(0x0703b312, 0xcf933c83), TOBN(0xd05bb76e, 0x1a7f47e6), + TOBN(0x825e4f0c, 0x949c2415), TOBN(0x569e5622, 0x7250d6f8), + TOBN(0xbbe9eb3a, 0x6568013e), TOBN(0x8dbd203f, 0x22f243fc), + TOBN(0x9dbd7694, 0xb342734a), TOBN(0x8f6d12f8, 0x46afa984), + TOBN(0xb98610a2, 0xc9eade29), TOBN(0xbab4f323, 0x47dd0f18), + TOBN(0x5779737b, 0x671c0d46), TOBN(0x10b6a7c6, 0xd3e0a42a), + TOBN(0xfb19ddf3, 0x3035b41c), TOBN(0xd336343f, 0x99c45895), + TOBN(0x61fe4938, 0x54c857e5), TOBN(0xc4d506be, 0xae4e57d5), + TOBN(0x3cd8c8cb, 0xbbc33f75), TOBN(0x7281f08a, 0x9262c77d), + TOBN(0x083f4ea6, 0xf11a2823), TOBN(0x8895041e, 0x9fba2e33), + TOBN(0xfcdfea49, 0x9c438edf), TOBN(0x7678dcc3, 0x91edba44), + TOBN(0xf07b3b87, 0xe2ba50f0), TOBN(0xc13888ef, 0x43948c1b), + TOBN(0xc2135ad4, 0x1140af42), TOBN(0x8e5104f3, 0x926ed1a7), + TOBN(0xf24430cb, 0x88f6695f), TOBN(0x0ce0637b, 0x6d73c120), + TOBN(0xb2db01e6, 0xfe631e8f), TOBN(0x1c5563d7, 0xd7bdd24b), + TOBN(0x8daea3ba, 0x369ad44f), TOBN(0x000c81b6, 0x8187a9f9), + TOBN(0x5f48a951, 0xaae1fd9a), TOBN(0xe35626c7, 0x8d5aed8a), + TOBN(0x20952763, 0x0498c622), TOBN(0x76d17634, 0x773aa504), + TOBN(0x36d90dda, 0xeb300f7a), TOBN(0x9dcf7dfc, 0xedb5e801), + TOBN(0x645cb268, 0x74d5244c), TOBN(0xa127ee79, 0x348e3aa2), + TOBN(0x488acc53, 0x575f1dbb), TOBN(0x95037e85, 0x80e6161e), + TOBN(0x57e59283, 0x292650d0), TOBN(0xabe67d99, 0x14938216), + TOBN(0x3c7f944b, 0x3f8e1065), TOBN(0xed908cb6, 0x330e8924), + TOBN(0x08ee8fd5, 0x6f530136), TOBN(0x2227b7d5, 0xd7ffc169), + TOBN(0x4f55c893, 0xb5cd6dd5), TOBN(0x82225e11, 0xa62796e8), + TOBN(0x5c6cead1, 0xcb18e12c), TOBN(0x4381ae0c, 0x84f5a51a), + TOBN(0x345913d3, 0x7fafa4c8), TOBN(0x3d918082, 0x0491aac0), + TOBN(0x9347871f, 0x3e69264c), TOBN(0xbea9dd3c, 0xb4f4f0cd), + TOBN(0xbda5d067, 0x3eadd3e7), TOBN(0x0033c1b8, 0x0573bcd8), + TOBN(0x25589379, 0x5da2486c), TOBN(0xcb89ee5b, 0x86abbee7), + TOBN(0x8fe0a8f3, 0x22532e5d), TOBN(0xb6410ff0, 0x727dfc4c), + TOBN(0x619b9d58, 0x226726db), TOBN(0x5ec25669, 0x7a2b2dc7), + TOBN(0xaf4d2e06, 0x4c3beb01), TOBN(0x852123d0, 0x7acea556), + TOBN(0x0e9470fa, 0xf783487a), TOBN(0x75a7ea04, 0x5664b3eb), + TOBN(0x4ad78f35, 0x6798e4ba), TOBN(0x9214e6e5, 0xc7d0e091), + TOBN(0xc420b488, 0xb1290403), TOBN(0x64049e0a, 0xfc295749), + TOBN(0x03ef5af1, 0x3ae9841f), TOBN(0xdbe4ca19, 0xb0b662a6), + TOBN(0x46845c5f, 0xfa453458), TOBN(0xf8dabf19, 0x10b66722), + TOBN(0xb650f0aa, 0xcce2793b), TOBN(0x71db851e, 0xc5ec47c1), + TOBN(0x3eb78f3e, 0x3b234fa9), TOBN(0xb0c60f35, 0xfc0106ce), + TOBN(0x05427121, 0x774eadbd), TOBN(0x25367faf, 0xce323863), + TOBN(0x7541b5c9, 0xcd086976), TOBN(0x4ff069e2, 0xdc507ad1), + TOBN(0x74145256, 0x8776e667), TOBN(0x6e76142c, 0xb23c6bb5), + TOBN(0xdbf30712, 0x1b3a8a87), TOBN(0x60e7363e, 0x98450836), + TOBN(0x5741450e, 0xb7366d80), TOBN(0xe4ee14ca, 0x4837dbdf), + TOBN(0xa765eb9b, 0x69d4316f), TOBN(0x04548dca, 0x8ef43825), + TOBN(0x9c9f4e4c, 0x5ae888eb), TOBN(0x733abb51, 0x56e9ac99), + TOBN(0xdaad3c20, 0xba6ac029), TOBN(0x9b8dd3d3, 0x2ba3e38e), + TOBN(0xa9bb4c92, 0x0bc5d11a), TOBN(0xf20127a7, 0x9c5f88a3), + TOBN(0x4f52b06e, 0x161d3cb8), TOBN(0x26c1ff09, 0x6afaf0a6), + TOBN(0x32670d2f, 0x7189e71f), TOBN(0xc6438748, 0x5ecf91e7), + TOBN(0x15758e57, 0xdb757a21), TOBN(0x427d09f8, 0x290a9ce5), + TOBN(0x846a308f, 0x38384a7a), TOBN(0xaac3acb4, 0xb0732b99), + TOBN(0x9e941009, 0x17845819), TOBN(0x95cba111, 0xa7ce5e03), + TOBN(0x6f3d4f7f, 0xb00009c4), TOBN(0xb8396c27, 0x8ff28b5f), + TOBN(0xb1a9ae43, 0x1c97975d), TOBN(0x9d7ba8af, 0xe5d9fed5), + TOBN(0x338cf09f, 0x34f485b6), TOBN(0xbc0ddacc, 0x64122516), + TOBN(0xa450da12, 0x05d471fe), TOBN(0x4c3a6250, 0x628dd8c9), + TOBN(0x69c7d103, 0xd1295837), TOBN(0xa2893e50, 0x3807eb2f), + TOBN(0xd6e1e1de, 0xbdb41491), TOBN(0xc630745b, 0x5e138235), + TOBN(0xc892109e, 0x48661ae1), TOBN(0x8d17e7eb, 0xea2b2674), + TOBN(0x00ec0f87, 0xc328d6b5), TOBN(0x6d858645, 0xf079ff9e), + TOBN(0x6cdf243e, 0x19115ead), TOBN(0x1ce1393e, 0x4bac4fcf), + TOBN(0x2c960ed0, 0x9c29f25b), TOBN(0x59be4d8e, 0x9d388a05), + TOBN(0x0d46e06c, 0xd0def72b), TOBN(0xb923db5d, 0xe0342748), + TOBN(0xf7d3aacd, 0x936d4a3d), TOBN(0x558519cc, 0x0b0b099e), + TOBN(0x3ea8ebf8, 0x827097ef), TOBN(0x259353db, 0xd054f55d), + TOBN(0x84c89abc, 0x6d2ed089), TOBN(0x5c548b69, 0x8e096a7c), + TOBN(0xd587f616, 0x994b995d), TOBN(0x4d1531f6, 0xa5845601), + TOBN(0x792ab31e, 0x451fd9f0), TOBN(0xc8b57bb2, 0x65adf6ca), + TOBN(0x68440fcb, 0x1cd5ad73), TOBN(0xb9c860e6, 0x6144da4f), + TOBN(0x2ab286aa, 0x8462beb8), TOBN(0xcc6b8fff, 0xef46797f), + TOBN(0xac820da4, 0x20c8a471), TOBN(0x69ae05a1, 0x77ff7faf), + TOBN(0xb9163f39, 0xbfb5da77), TOBN(0xbd03e590, 0x2c73ab7a), + TOBN(0x7e862b5e, 0xb2940d9e), TOBN(0x3c663d86, 0x4b9af564), + TOBN(0xd8309031, 0xbde3033d), TOBN(0x298231b2, 0xd42c5bc6), + TOBN(0x42090d2c, 0x552ad093), TOBN(0xa4799d1c, 0xff854695), + TOBN(0x0a88b5d6, 0xd31f0d00), TOBN(0xf8b40825, 0xa2f26b46), + TOBN(0xec29b1ed, 0xf1bd7218), TOBN(0xd491c53b, 0x4b24c86e), + TOBN(0xd2fe588f, 0x3395ea65), TOBN(0x6f3764f7, 0x4456ef15), + TOBN(0xdb43116d, 0xcdc34800), TOBN(0xcdbcd456, 0xc1e33955), + TOBN(0xefdb5540, 0x74ab286b), TOBN(0x948c7a51, 0xd18c5d7c), + TOBN(0xeb81aa37, 0x7378058e), TOBN(0x41c746a1, 0x04411154), + TOBN(0xa10c73bc, 0xfb828ac7), TOBN(0x6439be91, 0x9d972b29), + TOBN(0x4bf3b4b0, 0x43a2fbad), TOBN(0x39e6dadf, 0x82b5e840), + TOBN(0x4f716408, 0x6397bd4c), TOBN(0x0f7de568, 0x7f1eeccb), + TOBN(0x5865c5a1, 0xd2ffbfc1), TOBN(0xf74211fa, 0x4ccb6451), + TOBN(0x66368a88, 0xc0b32558), TOBN(0x5b539dc2, 0x9ad7812e), + TOBN(0x579483d0, 0x2f3af6f6), TOBN(0x52132078, 0x99934ece), + TOBN(0x50b9650f, 0xdcc9e983), TOBN(0xca989ec9, 0xaee42b8a), + TOBN(0x6a44c829, 0xd6f62f99), TOBN(0x8f06a309, 0x4c2a7c0c), + TOBN(0x4ea2b3a0, 0x98a0cb0a), TOBN(0x5c547b70, 0xbeee8364), + TOBN(0x461d40e1, 0x682afe11), TOBN(0x9e0fc77a, 0x7b41c0a8), + TOBN(0x79e4aefd, 0xe20d5d36), TOBN(0x2916e520, 0x32dd9f63), + TOBN(0xf59e52e8, 0x3f883faf), TOBN(0x396f9639, 0x2b868d35), + TOBN(0xc902a9df, 0x4ca19881), TOBN(0x0fc96822, 0xdb2401a6), + TOBN(0x41237587, 0x66f1c68d), TOBN(0x10fc6de3, 0xfb476c0d), + TOBN(0xf8b6b579, 0x841f5d90), TOBN(0x2ba8446c, 0xfa24f44a), + TOBN(0xa237b920, 0xef4a9975), TOBN(0x60bb6004, 0x2330435f), + TOBN(0xd6f4ab5a, 0xcfb7e7b5), TOBN(0xb2ac5097, 0x83435391), + TOBN(0xf036ee2f, 0xb0d1ea67), TOBN(0xae779a6a, 0x74c56230), + TOBN(0x59bff8c8, 0xab838ae6), TOBN(0xcd83ca99, 0x9b38e6f0), + TOBN(0xbb27bef5, 0xe33deed3), TOBN(0xe6356f6f, 0x001892a8), + TOBN(0xbf3be6cc, 0x7adfbd3e), TOBN(0xaecbc81c, 0x33d1ac9d), + TOBN(0xe4feb909, 0xe6e861dc), TOBN(0x90a247a4, 0x53f5f801), + TOBN(0x01c50acb, 0x27346e57), TOBN(0xce29242e, 0x461acc1b), + TOBN(0x04dd214a, 0x2f998a91), TOBN(0x271ee9b1, 0xd4baf27b), + TOBN(0x7e3027d1, 0xe8c26722), TOBN(0x21d1645c, 0x1820dce5), + TOBN(0x086f242c, 0x7501779c), TOBN(0xf0061407, 0xfa0e8009), + TOBN(0xf23ce477, 0x60187129), TOBN(0x05bbdedb, 0x0fde9bd0), + TOBN(0x682f4832, 0x25d98473), TOBN(0xf207fe85, 0x5c658427), + TOBN(0xb6fdd7ba, 0x4166ffa1), TOBN(0x0c314056, 0x9eed799d), + TOBN(0x0db8048f, 0x4107e28f), TOBN(0x74ed3871, 0x41216840), + TOBN(0x74489f8f, 0x56a3c06e), TOBN(0x1e1c005b, 0x12777134), + TOBN(0xdb332a73, 0xf37ec3c3), TOBN(0xc65259bd, 0xdd59eba0), + TOBN(0x2291709c, 0xdb4d3257), TOBN(0x9a793b25, 0xbd389390), + TOBN(0xf39fe34b, 0xe43756f0), TOBN(0x2f76bdce, 0x9afb56c9), + TOBN(0x9f37867a, 0x61208b27), TOBN(0xea1d4307, 0x089972c3), + TOBN(0x8c595330, 0x8bdf623a), TOBN(0x5f5accda, 0x8441fb7d), + TOBN(0xfafa9418, 0x32ddfd95), TOBN(0x6ad40c5a, 0x0fde9be7), + TOBN(0x43faba89, 0xaeca8709), TOBN(0xc64a7cf1, 0x2c248a9d), + TOBN(0x16620252, 0x72637a76), TOBN(0xaee1c791, 0x22b8d1bb), + TOBN(0xf0f798fd, 0x21a843b2), TOBN(0x56e4ed4d, 0x8d005cb1), + TOBN(0x355f7780, 0x1f0d8abe), TOBN(0x197b04cf, 0x34522326), + TOBN(0x41f9b31f, 0xfd42c13f), TOBN(0x5ef7feb2, 0xb40f933d), + TOBN(0x27326f42, 0x5d60bad4), TOBN(0x027ecdb2, 0x8c92cf89), + TOBN(0x04aae4d1, 0x4e3352fe), TOBN(0x08414d2f, 0x73591b90), + TOBN(0x5ed6124e, 0xb7da7d60), TOBN(0xb985b931, 0x4d13d4ec), + TOBN(0xa592d3ab, 0x96bf36f9), TOBN(0x012dbed5, 0xbbdf51df), + TOBN(0xa57963c0, 0xdf6c177d), TOBN(0x010ec869, 0x87ca29cf), + TOBN(0xba1700f6, 0xbf926dff), TOBN(0x7c9fdbd1, 0xf4bf6bc2), + TOBN(0xdc18dc8f, 0x64da11f5), TOBN(0xa6074b7a, 0xd938ae75), + TOBN(0x14270066, 0xe84f44a4), TOBN(0x99998d38, 0xd27b954e), + TOBN(0xc1be8ab2, 0xb4f38e9a), TOBN(0x8bb55bbf, 0x15c01016), + TOBN(0xf73472b4, 0x0ea2ab30), TOBN(0xd365a340, 0xf73d68dd), + TOBN(0xc01a7168, 0x19c2e1eb), TOBN(0x32f49e37, 0x34061719), + TOBN(0xb73c57f1, 0x01d8b4d6), TOBN(0x03c8423c, 0x26b47700), + TOBN(0x321d0bc8, 0xa4d8826a), TOBN(0x6004213c, 0x4bc0e638), + TOBN(0xf78c64a1, 0xc1c06681), TOBN(0x16e0a16f, 0xef018e50), + TOBN(0x31cbdf91, 0xdb42b2b3), TOBN(0xf8f4ffce, 0xe0d36f58), + TOBN(0xcdcc71cd, 0x4cc5e3e0), TOBN(0xd55c7cfa, 0xa129e3e0), + TOBN(0xccdb6ba0, 0x0fb2cbf1), TOBN(0x6aba0005, 0xc4bce3cb), + TOBN(0x501cdb30, 0xd232cfc4), TOBN(0x9ddcf12e, 0xd58a3cef), + TOBN(0x02d2cf9c, 0x87e09149), TOBN(0xdc5d7ec7, 0x2c976257), + TOBN(0x6447986e, 0x0b50d7dd), TOBN(0x88fdbaf7, 0x807f112a), + TOBN(0x58c9822a, 0xb00ae9f6), TOBN(0x6abfb950, 0x6d3d27e0), + TOBN(0xd0a74487, 0x8a429f4f), TOBN(0x0649712b, 0xdb516609), + TOBN(0xb826ba57, 0xe769b5df), TOBN(0x82335df2, 0x1fc7aaf2), + TOBN(0x2389f067, 0x5c93d995), TOBN(0x59ac367a, 0x68677be6), + TOBN(0xa77985ff, 0x21d9951b), TOBN(0x038956fb, 0x85011cce), + TOBN(0x608e48cb, 0xbb734e37), TOBN(0xc08c0bf2, 0x2be5b26f), + TOBN(0x17bbdd3b, 0xf9b1a0d9), TOBN(0xeac7d898, 0x10483319), + TOBN(0xc95c4baf, 0xbc1a6dea), TOBN(0xfdd0e2bf, 0x172aafdb), + TOBN(0x40373cbc, 0x8235c41a), TOBN(0x14303f21, 0xfb6f41d5), + TOBN(0xba063621, 0x0408f237), TOBN(0xcad3b09a, 0xecd2d1ed), + TOBN(0x4667855a, 0x52abb6a2), TOBN(0xba9157dc, 0xaa8b417b), + TOBN(0xfe7f3507, 0x4f013efb), TOBN(0x1b112c4b, 0xaa38c4a2), + TOBN(0xa1406a60, 0x9ba64345), TOBN(0xe53cba33, 0x6993c80b), + TOBN(0x45466063, 0xded40d23), TOBN(0x3d5f1f4d, 0x54908e25), + TOBN(0x9ebefe62, 0x403c3c31), TOBN(0x274ea0b5, 0x0672a624), + TOBN(0xff818d99, 0x451d1b71), TOBN(0x80e82643, 0x8f79cf79), + TOBN(0xa165df13, 0x73ce37f5), TOBN(0xa744ef4f, 0xfe3a21fd), + TOBN(0x73f1e7f5, 0xcf551396), TOBN(0xc616898e, 0x868c676b), + TOBN(0x671c28c7, 0x8c442c36), TOBN(0xcfe5e558, 0x5e0a317d), + TOBN(0x1242d818, 0x7051f476), TOBN(0x56fad2a6, 0x14f03442), + TOBN(0x262068bc, 0x0a44d0f6), TOBN(0xdfa2cd6e, 0xce6edf4e), + TOBN(0x0f43813a, 0xd15d1517), TOBN(0x61214cb2, 0x377d44f5), + TOBN(0xd399aa29, 0xc639b35f), TOBN(0x42136d71, 0x54c51c19), + TOBN(0x9774711b, 0x08417221), TOBN(0x0a5546b3, 0x52545a57), + TOBN(0x80624c41, 0x1150582d), TOBN(0x9ec5c418, 0xfbc555bc), + TOBN(0x2c87dcad, 0x771849f1), TOBN(0xb0c932c5, 0x01d7bf6f), + TOBN(0x6aa5cd3e, 0x89116eb2), TOBN(0xd378c25a, 0x51ca7bd3), + TOBN(0xc612a0da, 0x9e6e3e31), TOBN(0x0417a54d, 0xb68ad5d0), + TOBN(0x00451e4a, 0x22c6edb8), TOBN(0x9fbfe019, 0xb42827ce), + TOBN(0x2fa92505, 0xba9384a2), TOBN(0x21b8596e, 0x64ad69c1), + TOBN(0x8f4fcc49, 0x983b35a6), TOBN(0xde093760, 0x72754672), + TOBN(0x2f14ccc8, 0xf7bffe6d), TOBN(0x27566bff, 0x5d94263d), + TOBN(0xb5b4e9c6, 0x2df3ec30), TOBN(0x94f1d7d5, 0x3e6ea6ba), + TOBN(0x97b7851a, 0xaaca5e9b), TOBN(0x518aa521, 0x56713b97), + TOBN(0x3357e8c7, 0x150a61f6), TOBN(0x7842e7e2, 0xec2c2b69), + TOBN(0x8dffaf65, 0x6868a548), TOBN(0xd963bd82, 0xe068fc81), + TOBN(0x64da5c8b, 0x65917733), TOBN(0x927090ff, 0x7b247328)}, + {TOBN(0x214bc9a7, 0xd298c241), TOBN(0xe3b697ba, 0x56807cfd), + TOBN(0xef1c7802, 0x4564eadb), TOBN(0xdde8cdcf, 0xb48149c5), + TOBN(0x946bf0a7, 0x5a4d2604), TOBN(0x27154d7f, 0x6c1538af), + TOBN(0x95cc9230, 0xde5b1fcc), TOBN(0xd88519e9, 0x66864f82), + TOBN(0xb828dd1a, 0x7cb1282c), TOBN(0xa08d7626, 0xbe46973a), + TOBN(0x6baf8d40, 0xe708d6b2), TOBN(0x72571fa1, 0x4daeb3f3), + TOBN(0x85b1732f, 0xf22dfd98), TOBN(0x87ab01a7, 0x0087108d), + TOBN(0xaaaafea8, 0x5988207a), TOBN(0xccc832f8, 0x69f00755), + TOBN(0x964d950e, 0x36ff3bf0), TOBN(0x8ad20f6f, 0xf0b34638), + TOBN(0x4d9177b3, 0xb5d7585f), TOBN(0xcf839760, 0xef3f019f), + TOBN(0x582fc5b3, 0x8288c545), TOBN(0x2f8e4e9b, 0x13116bd1), + TOBN(0xf91e1b2f, 0x332120ef), TOBN(0xcf568724, 0x2a17dd23), + TOBN(0x488f1185, 0xca8d9d1a), TOBN(0xadf2c77d, 0xd987ded2), + TOBN(0x5f3039f0, 0x60c46124), TOBN(0xe5d70b75, 0x71e095f4), + TOBN(0x82d58650, 0x6260e70f), TOBN(0x39d75ea7, 0xf750d105), + TOBN(0x8cf3d0b1, 0x75bac364), TOBN(0xf3a7564d, 0x21d01329), + TOBN(0x182f04cd, 0x2f52d2a7), TOBN(0x4fde149a, 0xe2df565a), + TOBN(0xb80c5eec, 0xa79fb2f7), TOBN(0xab491d7b, 0x22ddc897), + TOBN(0x99d76c18, 0xc6312c7f), TOBN(0xca0d5f3d, 0x6aa41a57), + TOBN(0x71207325, 0xd15363a0), TOBN(0xe82aa265, 0xbeb252c2), + TOBN(0x94ab4700, 0xec3128c2), TOBN(0x6c76d862, 0x8e383f49), + TOBN(0xdc36b150, 0xc03024eb), TOBN(0xfb439477, 0x53daac69), + TOBN(0xfc68764a, 0x8dc79623), TOBN(0x5b86995d, 0xb440fbb2), + TOBN(0xd66879bf, 0xccc5ee0d), TOBN(0x05228942, 0x95aa8bd3), + TOBN(0xb51a40a5, 0x1e6a75c1), TOBN(0x24327c76, 0x0ea7d817), + TOBN(0x06630182, 0x07774597), TOBN(0xd6fdbec3, 0x97fa7164), + TOBN(0x20c99dfb, 0x13c90f48), TOBN(0xd6ac5273, 0x686ef263), + TOBN(0xc6a50bdc, 0xfef64eeb), TOBN(0xcd87b281, 0x86fdfc32), + TOBN(0xb24aa43e, 0x3fcd3efc), TOBN(0xdd26c034, 0xb8088e9a), + TOBN(0xa5ef4dc9, 0xbd3d46ea), TOBN(0xa2f99d58, 0x8a4c6a6f), + TOBN(0xddabd355, 0x2f1da46c), TOBN(0x72c3f8ce, 0x1afacdd1), + TOBN(0xd90c4eee, 0x92d40578), TOBN(0xd28bb41f, 0xca623b94), + TOBN(0x50fc0711, 0x745edc11), TOBN(0x9dd9ad7d, 0x3dc87558), + TOBN(0xce6931fb, 0xb49d1e64), TOBN(0x6c77a0a2, 0xc98bd0f9), + TOBN(0x62b9a629, 0x6baf7cb1), TOBN(0xcf065f91, 0xccf72d22), + TOBN(0x7203cce9, 0x79639071), TOBN(0x09ae4885, 0xf9cb732f), + TOBN(0x5e7c3bec, 0xee8314f3), TOBN(0x1c068aed, 0xdbea298f), + TOBN(0x08d381f1, 0x7c80acec), TOBN(0x03b56be8, 0xe330495b), + TOBN(0xaeffb8f2, 0x9222882d), TOBN(0x95ff38f6, 0xc4af8bf7), + TOBN(0x50e32d35, 0x1fc57d8c), TOBN(0x6635be52, 0x17b444f0), + TOBN(0x04d15276, 0xa5177900), TOBN(0x4e1dbb47, 0xf6858752), + TOBN(0x5b475622, 0xc615796c), TOBN(0xa6fa0387, 0x691867bf), + TOBN(0xed7f5d56, 0x2844c6d0), TOBN(0xc633cf9b, 0x03a2477d), + TOBN(0xf6be5c40, 0x2d3721d6), TOBN(0xaf312eb7, 0xe9fd68e6), + TOBN(0x242792d2, 0xe7417ce1), TOBN(0xff42bc71, 0x970ee7f5), + TOBN(0x1ff4dc6d, 0x5c67a41e), TOBN(0x77709b7b, 0x20882a58), + TOBN(0x3554731d, 0xbe217f2c), TOBN(0x2af2a8cd, 0x5bb72177), + TOBN(0x58eee769, 0x591dd059), TOBN(0xbb2930c9, 0x4bba6477), + TOBN(0x863ee047, 0x7d930cfc), TOBN(0x4c262ad1, 0x396fd1f4), + TOBN(0xf4765bc8, 0x039af7e1), TOBN(0x2519834b, 0x5ba104f6), + TOBN(0x7cd61b4c, 0xd105f961), TOBN(0xa5415da5, 0xd63bca54), + TOBN(0x778280a0, 0x88a1f17c), TOBN(0xc4968949, 0x2329512c), + TOBN(0x174a9126, 0xcecdaa7a), TOBN(0xfc8c7e0e, 0x0b13247b), + TOBN(0x29c110d2, 0x3484c1c4), TOBN(0xf8eb8757, 0x831dfc3b), + TOBN(0x022f0212, 0xc0067452), TOBN(0x3f6f69ee, 0x7b9b926c), + TOBN(0x09032da0, 0xef42daf4), TOBN(0x79f00ade, 0x83f80de4), + TOBN(0x6210db71, 0x81236c97), TOBN(0x74f7685b, 0x3ee0781f), + TOBN(0x4df7da7b, 0xa3e41372), TOBN(0x2aae38b1, 0xb1a1553e), + TOBN(0x1688e222, 0xf6dd9d1b), TOBN(0x57695448, 0x5b8b6487), + TOBN(0x478d2127, 0x4b2edeaa), TOBN(0xb2818fa5, 0x1e85956a), + TOBN(0x1e6addda, 0xf176f2c0), TOBN(0x01ca4604, 0xe2572658), + TOBN(0x0a404ded, 0x85342ffb), TOBN(0x8cf60f96, 0x441838d6), + TOBN(0x9bbc691c, 0xc9071c4a), TOBN(0xfd588744, 0x34442803), + TOBN(0x97101c85, 0x809c0d81), TOBN(0xa7fb754c, 0x8c456f7f), + TOBN(0xc95f3c5c, 0xd51805e1), TOBN(0xab4ccd39, 0xb299dca8), + TOBN(0x3e03d20b, 0x47eaf500), TOBN(0xfa3165c1, 0xd7b80893), + TOBN(0x005e8b54, 0xe160e552), TOBN(0xdc4972ba, 0x9019d11f), + TOBN(0x21a6972e, 0x0c9a4a7a), TOBN(0xa52c258f, 0x37840fd7), + TOBN(0xf8559ff4, 0xc1e99d81), TOBN(0x08e1a7d6, 0xa3c617c0), + TOBN(0xb398fd43, 0x248c6ba7), TOBN(0x6ffedd91, 0xd1283794), + TOBN(0x8a6a59d2, 0xd629d208), TOBN(0xa9d141d5, 0x3490530e), + TOBN(0x42f6fc18, 0x38505989), TOBN(0x09bf250d, 0x479d94ee), + TOBN(0x223ad3b1, 0xb3822790), TOBN(0x6c5926c0, 0x93b8971c), + TOBN(0x609efc7e, 0x75f7fa62), TOBN(0x45d66a6d, 0x1ec2d989), + TOBN(0x4422d663, 0x987d2792), TOBN(0x4a73caad, 0x3eb31d2b), + TOBN(0xf06c2ac1, 0xa32cb9e6), TOBN(0xd9445c5f, 0x91aeba84), + TOBN(0x6af7a1d5, 0xaf71013f), TOBN(0xe68216e5, 0x0bedc946), + TOBN(0xf4cba30b, 0xd27370a0), TOBN(0x7981afbf, 0x870421cc), + TOBN(0x02496a67, 0x9449f0e1), TOBN(0x86cfc4be, 0x0a47edae), + TOBN(0x3073c936, 0xb1feca22), TOBN(0xf5694612, 0x03f8f8fb), + TOBN(0xd063b723, 0x901515ea), TOBN(0x4c6c77a5, 0x749cf038), + TOBN(0x6361e360, 0xab9e5059), TOBN(0x596cf171, 0xa76a37c0), + TOBN(0x800f53fa, 0x6530ae7a), TOBN(0x0f5e631e, 0x0792a7a6), + TOBN(0x5cc29c24, 0xefdb81c9), TOBN(0xa269e868, 0x3f9c40ba), + TOBN(0xec14f9e1, 0x2cb7191e), TOBN(0x78ea1bd8, 0xe5b08ea6), + TOBN(0x3c65aa9b, 0x46332bb9), TOBN(0x84cc22b3, 0xbf80ce25), + TOBN(0x0098e9e9, 0xd49d5bf1), TOBN(0xcd4ec1c6, 0x19087da4), + TOBN(0x3c9d07c5, 0xaef6e357), TOBN(0x839a0268, 0x9f8f64b8), + TOBN(0xc5e9eb62, 0xc6d8607f), TOBN(0x759689f5, 0x6aa995e4), + TOBN(0x70464669, 0xbbb48317), TOBN(0x921474bf, 0xe402417d), + TOBN(0xcabe135b, 0x2a354c8c), TOBN(0xd51e52d2, 0x812fa4b5), + TOBN(0xec741096, 0x53311fe8), TOBN(0x4f774535, 0xb864514b), + TOBN(0xbcadd671, 0x5bde48f8), TOBN(0xc9703873, 0x2189bc7d), + TOBN(0x5d45299e, 0xc709ee8a), TOBN(0xd1287ee2, 0x845aaff8), + TOBN(0x7d1f8874, 0xdb1dbf1f), TOBN(0xea46588b, 0x990c88d6), + TOBN(0x60ba649a, 0x84368313), TOBN(0xd5fdcbce, 0x60d543ae), + TOBN(0x90b46d43, 0x810d5ab0), TOBN(0x6739d8f9, 0x04d7e5cc), + TOBN(0x021c1a58, 0x0d337c33), TOBN(0x00a61162, 0x68e67c40), + TOBN(0x95ef413b, 0x379f0a1f), TOBN(0xfe126605, 0xe9e2ab95), + TOBN(0x67578b85, 0x2f5f199c), TOBN(0xf5c00329, 0x2cb84913), + TOBN(0xf7956430, 0x37577dd8), TOBN(0x83b82af4, 0x29c5fe88), + TOBN(0x9c1bea26, 0xcdbdc132), TOBN(0x589fa086, 0x9c04339e), + TOBN(0x033e9538, 0xb13799df), TOBN(0x85fa8b21, 0xd295d034), + TOBN(0xdf17f73f, 0xbd9ddcca), TOBN(0xf32bd122, 0xddb66334), + TOBN(0x55ef88a7, 0x858b044c), TOBN(0x1f0d69c2, 0x5aa9e397), + TOBN(0x55fd9cc3, 0x40d85559), TOBN(0xc774df72, 0x7785ddb2), + TOBN(0x5dcce9f6, 0xd3bd2e1c), TOBN(0xeb30da20, 0xa85dfed0), + TOBN(0x5ed7f5bb, 0xd3ed09c4), TOBN(0x7d42a35c, 0x82a9c1bd), + TOBN(0xcf3de995, 0x9890272d), TOBN(0x75f3432a, 0x3e713a10), + TOBN(0x5e13479f, 0xe28227b8), TOBN(0xb8561ea9, 0xfefacdc8), + TOBN(0xa6a297a0, 0x8332aafd), TOBN(0x9b0d8bb5, 0x73809b62), + TOBN(0xd2fa1cfd, 0x0c63036f), TOBN(0x7a16eb55, 0xbd64bda8), + TOBN(0x3f5cf5f6, 0x78e62ddc), TOBN(0x2267c454, 0x07fd752b), + TOBN(0x5e361b6b, 0x5e437bbe), TOBN(0x95c59501, 0x8354e075), + TOBN(0xec725f85, 0xf2b254d9), TOBN(0x844b617d, 0x2cb52b4e), + TOBN(0xed8554f5, 0xcf425fb5), TOBN(0xab67703e, 0x2af9f312), + TOBN(0x4cc34ec1, 0x3cf48283), TOBN(0xb09daa25, 0x9c8a705e), + TOBN(0xd1e9d0d0, 0x5b7d4f84), TOBN(0x4df6ef64, 0xdb38929d), + TOBN(0xe16b0763, 0xaa21ba46), TOBN(0xc6b1d178, 0xa293f8fb), + TOBN(0x0ff5b602, 0xd520aabf), TOBN(0x94d671bd, 0xc339397a), + TOBN(0x7c7d98cf, 0x4f5792fa), TOBN(0x7c5e0d67, 0x11215261), + TOBN(0x9b19a631, 0xa7c5a6d4), TOBN(0xc8511a62, 0x7a45274d), + TOBN(0x0c16621c, 0xa5a60d99), TOBN(0xf7fbab88, 0xcf5e48cb), + TOBN(0xab1e6ca2, 0xf7ddee08), TOBN(0x83bd08ce, 0xe7867f3c), + TOBN(0xf7e48e8a, 0x2ac13e27), TOBN(0x4494f6df, 0x4eb1a9f5), + TOBN(0xedbf84eb, 0x981f0a62), TOBN(0x49badc32, 0x536438f0), + TOBN(0x50bea541, 0x004f7571), TOBN(0xbac67d10, 0xdf1c94ee), + TOBN(0x253d73a1, 0xb727bc31), TOBN(0xb3d01cf2, 0x30686e28), + TOBN(0x51b77b1b, 0x55fd0b8b), TOBN(0xa099d183, 0xfeec3173), + TOBN(0x202b1fb7, 0x670e72b7), TOBN(0xadc88b33, 0xa8e1635f), + TOBN(0x34e8216a, 0xf989d905), TOBN(0xc2e68d20, 0x29b58d01), + TOBN(0x11f81c92, 0x6fe55a93), TOBN(0x15f1462a, 0x8f296f40), + TOBN(0x1915d375, 0xea3d62f2), TOBN(0xa17765a3, 0x01c8977d), + TOBN(0x7559710a, 0xe47b26f6), TOBN(0xe0bd29c8, 0x535077a5), + TOBN(0x615f976d, 0x08d84858), TOBN(0x370dfe85, 0x69ced5c1), + TOBN(0xbbc7503c, 0xa734fa56), TOBN(0xfbb9f1ec, 0x91ac4574), + TOBN(0x95d7ec53, 0x060dd7ef), TOBN(0xeef2dacd, 0x6e657979), + TOBN(0x54511af3, 0xe2a08235), TOBN(0x1e324aa4, 0x1f4aea3d), + TOBN(0x550e7e71, 0xe6e67671), TOBN(0xbccd5190, 0xbf52faf7), + TOBN(0xf880d316, 0x223cc62a), TOBN(0x0d402c7e, 0x2b32eb5d), + TOBN(0xa40bc039, 0x306a5a3b), TOBN(0x4e0a41fd, 0x96783a1b), + TOBN(0xa1e8d39a, 0x0253cdd4), TOBN(0x6480be26, 0xc7388638), + TOBN(0xee365e1d, 0x2285f382), TOBN(0x188d8d8f, 0xec0b5c36), + TOBN(0x34ef1a48, 0x1f0f4d82), TOBN(0x1a8f43e1, 0xa487d29a), + TOBN(0x8168226d, 0x77aefb3a), TOBN(0xf69a751e, 0x1e72c253), + TOBN(0x8e04359a, 0xe9594df1), TOBN(0x475ffd7d, 0xd14c0467), + TOBN(0xb5a2c2b1, 0x3844e95c), TOBN(0x85caf647, 0xdd12ef94), + TOBN(0x1ecd2a9f, 0xf1063d00), TOBN(0x1dd2e229, 0x23843311), + TOBN(0x38f0e09d, 0x73d17244), TOBN(0x3ede7746, 0x8fc653f1), + TOBN(0xae4459f5, 0xdc20e21c), TOBN(0x00db2ffa, 0x6a8599ea), + TOBN(0x11682c39, 0x30cfd905), TOBN(0x4934d074, 0xa5c112a6), + TOBN(0xbdf063c5, 0x568bfe95), TOBN(0x779a440a, 0x016c441a), + TOBN(0x0c23f218, 0x97d6fbdc), TOBN(0xd3a5cd87, 0xe0776aac), + TOBN(0xcee37f72, 0xd712e8db), TOBN(0xfb28c70d, 0x26f74e8d), + TOBN(0xffe0c728, 0xb61301a0), TOBN(0xa6282168, 0xd3724354), + TOBN(0x7ff4cb00, 0x768ffedc), TOBN(0xc51b3088, 0x03b02de9), + TOBN(0xa5a8147c, 0x3902dda5), TOBN(0x35d2f706, 0xfe6973b4), + TOBN(0x5ac2efcf, 0xc257457e), TOBN(0x933f48d4, 0x8700611b), + TOBN(0xc365af88, 0x4912beb2), TOBN(0x7f5a4de6, 0x162edf94), + TOBN(0xc646ba7c, 0x0c32f34b), TOBN(0x632c6af3, 0xb2091074), + TOBN(0x58d4f2e3, 0x753e43a9), TOBN(0x70e1d217, 0x24d4e23f), + TOBN(0xb24bf729, 0xafede6a6), TOBN(0x7f4a94d8, 0x710c8b60), + TOBN(0xaad90a96, 0x8d4faa6a), TOBN(0xd9ed0b32, 0xb066b690), + TOBN(0x52fcd37b, 0x78b6dbfd), TOBN(0x0b64615e, 0x8bd2b431), + TOBN(0x228e2048, 0xcfb9fad5), TOBN(0xbeaa386d, 0x240b76bd), + TOBN(0x2d6681c8, 0x90dad7bc), TOBN(0x3e553fc3, 0x06d38f5e), + TOBN(0xf27cdb9b, 0x9d5f9750), TOBN(0x3e85c52a, 0xd28c5b0e), + TOBN(0x190795af, 0x5247c39b), TOBN(0x547831eb, 0xbddd6828), + TOBN(0xf327a227, 0x4a82f424), TOBN(0x36919c78, 0x7e47f89d), + TOBN(0xe4783919, 0x43c7392c), TOBN(0xf101b9aa, 0x2316fefe), + TOBN(0xbcdc9e9c, 0x1c5009d2), TOBN(0xfb55ea13, 0x9cd18345), + TOBN(0xf5b5e231, 0xa3ce77c7), TOBN(0xde6b4527, 0xd2f2cb3d), + TOBN(0x10f6a333, 0x9bb26f5f), TOBN(0x1e85db8e, 0x044d85b6), + TOBN(0xc3697a08, 0x94197e54), TOBN(0x65e18cc0, 0xa7cb4ea8), + TOBN(0xa38c4f50, 0xa471fe6e), TOBN(0xf031747a, 0x2f13439c), + TOBN(0x53c4a6ba, 0xc007318b), TOBN(0xa8da3ee5, 0x1deccb3d), + TOBN(0x0555b31c, 0x558216b1), TOBN(0x90c7810c, 0x2f79e6c2), + TOBN(0x9b669f4d, 0xfe8eed3c), TOBN(0x70398ec8, 0xe0fac126), + TOBN(0xa96a449e, 0xf701b235), TOBN(0x0ceecdb3, 0xeb94f395), + TOBN(0x285fc368, 0xd0cb7431), TOBN(0x0d37bb52, 0x16a18c64), + TOBN(0x05110d38, 0xb880d2dd), TOBN(0xa60f177b, 0x65930d57), + TOBN(0x7da34a67, 0xf36235f5), TOBN(0x47f5e17c, 0x183816b9), + TOBN(0xc7664b57, 0xdb394af4), TOBN(0x39ba215d, 0x7036f789), + TOBN(0x46d2ca0e, 0x2f27b472), TOBN(0xc42647ee, 0xf73a84b7), + TOBN(0x44bc7545, 0x64488f1d), TOBN(0xaa922708, 0xf4cf85d5), + TOBN(0x721a01d5, 0x53e4df63), TOBN(0x649c0c51, 0x5db46ced), + TOBN(0x6bf0d64e, 0x3cffcb6c), TOBN(0xe3bf93fe, 0x50f71d96), + TOBN(0x75044558, 0xbcc194a0), TOBN(0x16ae3372, 0x6afdc554), + TOBN(0xbfc01adf, 0x5ca48f3f), TOBN(0x64352f06, 0xe22a9b84), + TOBN(0xcee54da1, 0xc1099e4a), TOBN(0xbbda54e8, 0xfa1b89c0), + TOBN(0x166a3df5, 0x6f6e55fb), TOBN(0x1ca44a24, 0x20176f88), + TOBN(0x936afd88, 0xdfb7b5ff), TOBN(0xe34c2437, 0x8611d4a0), + TOBN(0x7effbb75, 0x86142103), TOBN(0x6704ba1b, 0x1f34fc4d), + TOBN(0x7c2a468f, 0x10c1b122), TOBN(0x36b3a610, 0x8c6aace9), + TOBN(0xabfcc0a7, 0x75a0d050), TOBN(0x066f9197, 0x3ce33e32), + TOBN(0xce905ef4, 0x29fe09be), TOBN(0x89ee25ba, 0xa8376351), + TOBN(0x2a3ede22, 0xfd29dc76), TOBN(0x7fd32ed9, 0x36f17260), + TOBN(0x0cadcf68, 0x284b4126), TOBN(0x63422f08, 0xa7951fc8), + TOBN(0x562b24f4, 0x0807e199), TOBN(0xfe9ce5d1, 0x22ad4490), + TOBN(0xc2f51b10, 0x0db2b1b4), TOBN(0xeb3613ff, 0xe4541d0d), + TOBN(0xbd2c4a05, 0x2680813b), TOBN(0x527aa55d, 0x561b08d6), + TOBN(0xa9f8a40e, 0xa7205558), TOBN(0xe3eea56f, 0x243d0bec), + TOBN(0x7b853817, 0xa0ff58b3), TOBN(0xb67d3f65, 0x1a69e627), + TOBN(0x0b76bbb9, 0xa869b5d6), TOBN(0xa3afeb82, 0x546723ed), + TOBN(0x5f24416d, 0x3e554892), TOBN(0x8413b53d, 0x430e2a45), + TOBN(0x99c56aee, 0x9032a2a0), TOBN(0x09432bf6, 0xeec367b1), + TOBN(0x552850c6, 0xdaf0ecc1), TOBN(0x49ebce55, 0x5bc92048), + TOBN(0xdfb66ba6, 0x54811307), TOBN(0x1b84f797, 0x6f298597), + TOBN(0x79590481, 0x8d1d7a0d), TOBN(0xd9fabe03, 0x3a6fa556), + TOBN(0xa40f9c59, 0xba9e5d35), TOBN(0xcb1771c1, 0xf6247577), + TOBN(0x542a47ca, 0xe9a6312b), TOBN(0xa34b3560, 0x552dd8c5), + TOBN(0xfdf94de0, 0x0d794716), TOBN(0xd46124a9, 0x9c623094), + TOBN(0x56b7435d, 0x68afe8b4), TOBN(0x27f20540, 0x6c0d8ea1), + TOBN(0x12b77e14, 0x73186898), TOBN(0xdbc3dd46, 0x7479490f), + TOBN(0x951a9842, 0xc03b0c05), TOBN(0x8b1b3bb3, 0x7921bc96), + TOBN(0xa573b346, 0x2b202e0a), TOBN(0x77e4665d, 0x47254d56), + TOBN(0x08b70dfc, 0xd23e3984), TOBN(0xab86e8bc, 0xebd14236), + TOBN(0xaa3e07f8, 0x57114ba7), TOBN(0x5ac71689, 0xab0ef4f2), + TOBN(0x88fca384, 0x0139d9af), TOBN(0x72733f88, 0x76644af0), + TOBN(0xf122f72a, 0x65d74f4a), TOBN(0x13931577, 0xa5626c7a), + TOBN(0xd5b5d9eb, 0x70f8d5a4), TOBN(0x375adde7, 0xd7bbb228), + TOBN(0x31e88b86, 0x0c1c0b32), TOBN(0xd1f568c4, 0x173edbaa), + TOBN(0x1592fc83, 0x5459df02), TOBN(0x2beac0fb, 0x0fcd9a7e), + TOBN(0xb0a6fdb8, 0x1b473b0a), TOBN(0xe3224c6f, 0x0fe8fc48), + TOBN(0x680bd00e, 0xe87edf5b), TOBN(0x30385f02, 0x20e77cf5), + TOBN(0xe9ab98c0, 0x4d42d1b2), TOBN(0x72d191d2, 0xd3816d77), + TOBN(0x1564daca, 0x0917d9e5), TOBN(0x394eab59, 0x1f8fed7f), + TOBN(0xa209aa8d, 0x7fbb3896), TOBN(0x5564f3b9, 0xbe6ac98e), + TOBN(0xead21d05, 0xd73654ef), TOBN(0x68d1a9c4, 0x13d78d74), + TOBN(0x61e01708, 0x6d4973a0), TOBN(0x83da3500, 0x46e6d32a), + TOBN(0x6a3dfca4, 0x68ae0118), TOBN(0xa1b9a4c9, 0xd02da069), + TOBN(0x0b2ff9c7, 0xebab8302), TOBN(0x98af07c3, 0x944ba436), + TOBN(0x85997326, 0x995f0f9f), TOBN(0x467fade0, 0x71b58bc6), + TOBN(0x47e4495a, 0xbd625a2b), TOBN(0xfdd2d01d, 0x33c3b8cd), + TOBN(0x2c38ae28, 0xc693f9fa), TOBN(0x48622329, 0x348f7999), + TOBN(0x97bf738e, 0x2161f583), TOBN(0x15ee2fa7, 0x565e8cc9), + TOBN(0xa1a5c845, 0x5777e189), TOBN(0xcc10bee0, 0x456f2829), + TOBN(0x8ad95c56, 0xda762bd5), TOBN(0x152e2214, 0xe9d91da8), + TOBN(0x975b0e72, 0x7cb23c74), TOBN(0xfd5d7670, 0xa90c66df), + TOBN(0xb5b5b8ad, 0x225ffc53), TOBN(0xab6dff73, 0xfaded2ae), + TOBN(0xebd56781, 0x6f4cbe9d), TOBN(0x0ed8b249, 0x6a574bd7), + TOBN(0x41c246fe, 0x81a881fa), TOBN(0x91564805, 0xc3db9c70), + TOBN(0xd7c12b08, 0x5b862809), TOBN(0x1facd1f1, 0x55858d7b), + TOBN(0x7693747c, 0xaf09e92a), TOBN(0x3b69dcba, 0x189a425f), + TOBN(0x0be28e9f, 0x967365ef), TOBN(0x57300eb2, 0xe801f5c9), + TOBN(0x93b8ac6a, 0xd583352f), TOBN(0xa2cf1f89, 0xcd05b2b7), + TOBN(0x7c0c9b74, 0x4dcc40cc), TOBN(0xfee38c45, 0xada523fb), + TOBN(0xb49a4dec, 0x1099cc4d), TOBN(0x325c377f, 0x69f069c6), + TOBN(0xe12458ce, 0x476cc9ff), TOBN(0x580e0b6c, 0xc6d4cb63), + TOBN(0xd561c8b7, 0x9072289b), TOBN(0x0377f264, 0xa619e6da), + TOBN(0x26685362, 0x88e591a5), TOBN(0xa453a7bd, 0x7523ca2b), + TOBN(0x8a9536d2, 0xc1df4533), TOBN(0xc8e50f2f, 0xbe972f79), + TOBN(0xd433e50f, 0x6d3549cf), TOBN(0x6f33696f, 0xfacd665e), + TOBN(0x695bfdac, 0xce11fcb4), TOBN(0x810ee252, 0xaf7c9860), + TOBN(0x65450fe1, 0x7159bb2c), TOBN(0xf7dfbebe, 0x758b357b), + TOBN(0x2b057e74, 0xd69fea72), TOBN(0xd485717a, 0x92731745)}, + {TOBN(0x896c42e8, 0xee36860c), TOBN(0xdaf04dfd, 0x4113c22d), + TOBN(0x1adbb7b7, 0x44104213), TOBN(0xe5fd5fa1, 0x1fd394ea), + TOBN(0x68235d94, 0x1a4e0551), TOBN(0x6772cfbe, 0x18d10151), + TOBN(0x276071e3, 0x09984523), TOBN(0xe4e879de, 0x5a56ba98), + TOBN(0xaaafafb0, 0x285b9491), TOBN(0x01a0be88, 0x1e4c705e), + TOBN(0xff1d4f5d, 0x2ad9caab), TOBN(0x6e349a4a, 0xc37a233f), + TOBN(0xcf1c1246, 0x4a1c6a16), TOBN(0xd99e6b66, 0x29383260), + TOBN(0xea3d4366, 0x5f6d5471), TOBN(0x36974d04, 0xff8cc89b), + TOBN(0xc26c49a1, 0xcfe89d80), TOBN(0xb42c026d, 0xda9c8371), + TOBN(0xca6c013a, 0xdad066d2), TOBN(0xfb8f7228, 0x56a4f3ee), + TOBN(0x08b579ec, 0xd850935b), TOBN(0x34c1a74c, 0xd631e1b3), + TOBN(0xcb5fe596, 0xac198534), TOBN(0x39ff21f6, 0xe1f24f25), + TOBN(0x27f29e14, 0x8f929057), TOBN(0x7a64ae06, 0xc0c853df), + TOBN(0x256cd183, 0x58e9c5ce), TOBN(0x9d9cce82, 0xded092a5), + TOBN(0xcc6e5979, 0x6e93b7c7), TOBN(0xe1e47092, 0x31bb9e27), + TOBN(0xb70b3083, 0xaa9e29a0), TOBN(0xbf181a75, 0x3785e644), + TOBN(0xf53f2c65, 0x8ead09f7), TOBN(0x1335e1d5, 0x9780d14d), + TOBN(0x69cc20e0, 0xcd1b66bc), TOBN(0x9b670a37, 0xbbe0bfc8), + TOBN(0xce53dc81, 0x28efbeed), TOBN(0x0c74e77c, 0x8326a6e5), + TOBN(0x3604e0d2, 0xb88e9a63), TOBN(0xbab38fca, 0x13dc2248), + TOBN(0x8ed6e8c8, 0x5c0a3f1e), TOBN(0xbcad2492, 0x7c87c37f), + TOBN(0xfdfb62bb, 0x9ee3b78d), TOBN(0xeba8e477, 0xcbceba46), + TOBN(0x37d38cb0, 0xeeaede4b), TOBN(0x0bc498e8, 0x7976deb6), + TOBN(0xb2944c04, 0x6b6147fb), TOBN(0x8b123f35, 0xf71f9609), + TOBN(0xa155dcc7, 0xde79dc24), TOBN(0xf1168a32, 0x558f69cd), + TOBN(0xbac21595, 0x0d1850df), TOBN(0x15c8295b, 0xb204c848), + TOBN(0xf661aa36, 0x7d8184ff), TOBN(0xc396228e, 0x30447bdb), + TOBN(0x11cd5143, 0xbde4a59e), TOBN(0xe3a26e3b, 0x6beab5e6), + TOBN(0xd3b3a13f, 0x1402b9d0), TOBN(0x573441c3, 0x2c7bc863), + TOBN(0x4b301ec4, 0x578c3e6e), TOBN(0xc26fc9c4, 0x0adaf57e), + TOBN(0x96e71bfd, 0x7493cea3), TOBN(0xd05d4b3f, 0x1af81456), + TOBN(0xdaca2a8a, 0x6a8c608f), TOBN(0x53ef07f6, 0x0725b276), + TOBN(0x07a5fbd2, 0x7824fc56), TOBN(0x34675218, 0x13289077), + TOBN(0x5bf69fd5, 0xe0c48349), TOBN(0xa613ddd3, 0xb6aa7875), + TOBN(0x7f78c19c, 0x5450d866), TOBN(0x46f4409c, 0x8f84a481), + TOBN(0x9f1d1928, 0x90fce239), TOBN(0x016c4168, 0xb2ce44b9), + TOBN(0xbae023f0, 0xc7435978), TOBN(0xb152c888, 0x20e30e19), + TOBN(0x9c241645, 0xe3fa6faf), TOBN(0x735d95c1, 0x84823e60), + TOBN(0x03197573, 0x03955317), TOBN(0x0b4b02a9, 0xf03b4995), + TOBN(0x076bf559, 0x70274600), TOBN(0x32c5cc53, 0xaaf57508), + TOBN(0xe8af6d1f, 0x60624129), TOBN(0xb7bc5d64, 0x9a5e2b5e), + TOBN(0x3814b048, 0x5f082d72), TOBN(0x76f267f2, 0xce19677a), + TOBN(0x626c630f, 0xb36eed93), TOBN(0x55230cd7, 0x3bf56803), + TOBN(0x78837949, 0xce2736a0), TOBN(0x0d792d60, 0xaa6c55f1), + TOBN(0x0318dbfd, 0xd5c7c5d2), TOBN(0xb38f8da7, 0x072b342d), + TOBN(0x3569bddc, 0x7b8de38a), TOBN(0xf25b5887, 0xa1c94842), + TOBN(0xb2d5b284, 0x2946ad60), TOBN(0x854f29ad, 0xe9d1707e), + TOBN(0xaa5159dc, 0x2c6a4509), TOBN(0x899f94c0, 0x57189837), + TOBN(0xcf6adc51, 0xf4a55b03), TOBN(0x261762de, 0x35e3b2d5), + TOBN(0x4cc43012, 0x04827b51), TOBN(0xcd22a113, 0xc6021442), + TOBN(0xce2fd61a, 0x247c9569), TOBN(0x59a50973, 0xd152beca), + TOBN(0x6c835a11, 0x63a716d4), TOBN(0xc26455ed, 0x187dedcf), + TOBN(0x27f536e0, 0x49ce89e7), TOBN(0x18908539, 0xcc890cb5), + TOBN(0x308909ab, 0xd83c2aa1), TOBN(0xecd3142b, 0x1ab73bd3), + TOBN(0x6a85bf59, 0xb3f5ab84), TOBN(0x3c320a68, 0xf2bea4c6), + TOBN(0xad8dc538, 0x6da4541f), TOBN(0xeaf34eb0, 0xb7c41186), + TOBN(0x1c780129, 0x977c97c4), TOBN(0x5ff9beeb, 0xc57eb9fa), + TOBN(0xa24d0524, 0xc822c478), TOBN(0xfd8eec2a, 0x461cd415), + TOBN(0xfbde194e, 0xf027458c), TOBN(0xb4ff5319, 0x1d1be115), + TOBN(0x63f874d9, 0x4866d6f4), TOBN(0x35c75015, 0xb21ad0c9), + TOBN(0xa6b5c9d6, 0x46ac49d2), TOBN(0x42c77c0b, 0x83137aa9), + TOBN(0x24d000fc, 0x68225a38), TOBN(0x0f63cfc8, 0x2fe1e907), + TOBN(0x22d1b01b, 0xc6441f95), TOBN(0x7d38f719, 0xec8e448f), + TOBN(0x9b33fa5f, 0x787fb1ba), TOBN(0x94dcfda1, 0x190158df), + TOBN(0xc47cb339, 0x5f6d4a09), TOBN(0x6b4f355c, 0xee52b826), + TOBN(0x3d100f5d, 0xf51b930a), TOBN(0xf4512fac, 0x9f668f69), + TOBN(0x546781d5, 0x206c4c74), TOBN(0xd021d4d4, 0xcb4d2e48), + TOBN(0x494a54c2, 0xca085c2d), TOBN(0xf1dbaca4, 0x520850a8), + TOBN(0x63c79326, 0x490a1aca), TOBN(0xcb64dd9c, 0x41526b02), + TOBN(0xbb772591, 0xa2979258), TOBN(0x3f582970, 0x48d97846), + TOBN(0xd66b70d1, 0x7c213ba7), TOBN(0xc28febb5, 0xe8a0ced4), + TOBN(0x6b911831, 0xc10338c1), TOBN(0x0d54e389, 0xbf0126f3), + TOBN(0x7048d460, 0x4af206ee), TOBN(0x786c88f6, 0x77e97cb9), + TOBN(0xd4375ae1, 0xac64802e), TOBN(0x469bcfe1, 0xd53ec11c), + TOBN(0xfc9b340d, 0x47062230), TOBN(0xe743bb57, 0xc5b4a3ac), + TOBN(0xfe00b4aa, 0x59ef45ac), TOBN(0x29a4ef23, 0x59edf188), + TOBN(0x40242efe, 0xb483689b), TOBN(0x2575d3f6, 0x513ac262), + TOBN(0xf30037c8, 0x0ca6db72), TOBN(0xc9fcce82, 0x98864be2), + TOBN(0x84a112ff, 0x0149362d), TOBN(0x95e57582, 0x1c4ae971), + TOBN(0x1fa4b1a8, 0x945cf86c), TOBN(0x4525a734, 0x0b024a2f), + TOBN(0xe76c8b62, 0x8f338360), TOBN(0x483ff593, 0x28edf32b), + TOBN(0x67e8e90a, 0x298b1aec), TOBN(0x9caab338, 0x736d9a21), + TOBN(0x5c09d2fd, 0x66892709), TOBN(0x2496b4dc, 0xb55a1d41), + TOBN(0x93f5fb1a, 0xe24a4394), TOBN(0x08c75049, 0x6fa8f6c1), + TOBN(0xcaead1c2, 0xc905d85f), TOBN(0xe9d7f790, 0x0733ae57), + TOBN(0x24c9a65c, 0xf07cdd94), TOBN(0x7389359c, 0xa4b55931), + TOBN(0xf58709b7, 0x367e45f7), TOBN(0x1f203067, 0xcb7e7adc), + TOBN(0x82444bff, 0xc7b72818), TOBN(0x07303b35, 0xbaac8033), + TOBN(0x1e1ee4e4, 0xd13b7ea1), TOBN(0xe6489b24, 0xe0e74180), + TOBN(0xa5f2c610, 0x7e70ef70), TOBN(0xa1655412, 0xbdd10894), + TOBN(0x555ebefb, 0x7af4194e), TOBN(0x533c1c3c, 0x8e89bd9c), + TOBN(0x735b9b57, 0x89895856), TOBN(0x15fb3cd2, 0x567f5c15), + TOBN(0x057fed45, 0x526f09fd), TOBN(0xe8a4f10c, 0x8128240a), + TOBN(0x9332efc4, 0xff2bfd8d), TOBN(0x214e77a0, 0xbd35aa31), + TOBN(0x32896d73, 0x14faa40e), TOBN(0x767867ec, 0x01e5f186), + TOBN(0xc9adf8f1, 0x17a1813e), TOBN(0xcb6cda78, 0x54741795), + TOBN(0xb7521b6d, 0x349d51aa), TOBN(0xf56b5a9e, 0xe3c7b8e9), + TOBN(0xc6f1e5c9, 0x32a096df), TOBN(0x083667c4, 0xa3635024), + TOBN(0x365ea135, 0x18087f2f), TOBN(0xf1b8eaac, 0xd136e45d), + TOBN(0xc8a0e484, 0x73aec989), TOBN(0xd75a324b, 0x142c9259), + TOBN(0xb7b4d001, 0x01dae185), TOBN(0x45434e0b, 0x9b7a94bc), + TOBN(0xf54339af, 0xfbd8cb0b), TOBN(0xdcc4569e, 0xe98ef49e), + TOBN(0x7789318a, 0x09a51299), TOBN(0x81b4d206, 0xb2b025d8), + TOBN(0xf64aa418, 0xfae85792), TOBN(0x3e50258f, 0xacd7baf7), + TOBN(0xdce84cdb, 0x2996864b), TOBN(0xa2e67089, 0x1f485fa4), + TOBN(0xb28b2bb6, 0x534c6a5a), TOBN(0x31a7ec6b, 0xc94b9d39), + TOBN(0x1d217766, 0xd6bc20da), TOBN(0x4acdb5ec, 0x86761190), + TOBN(0x68726328, 0x73701063), TOBN(0x4d24ee7c, 0x2128c29b), + TOBN(0xc072ebd3, 0xa19fd868), TOBN(0x612e481c, 0xdb8ddd3b), + TOBN(0xb4e1d754, 0x1a64d852), TOBN(0x00ef95ac, 0xc4c6c4ab), + TOBN(0x1536d2ed, 0xaa0a6c46), TOBN(0x61294086, 0x43774790), + TOBN(0x54af25e8, 0x343fda10), TOBN(0x9ff9d98d, 0xfd25d6f2), + TOBN(0x0746af7c, 0x468b8835), TOBN(0x977a31cb, 0x730ecea7), + TOBN(0xa5096b80, 0xc2cf4a81), TOBN(0xaa986833, 0x6458c37a), + TOBN(0x6af29bf3, 0xa6bd9d34), TOBN(0x6a62fe9b, 0x33c5d854), + TOBN(0x50e6c304, 0xb7133b5e), TOBN(0x04b60159, 0x7d6e6848), + TOBN(0x4cd296df, 0x5579bea4), TOBN(0x10e35ac8, 0x5ceedaf1), + TOBN(0x04c4c5fd, 0xe3bcc5b1), TOBN(0x95f9ee8a, 0x89412cf9), + TOBN(0x2c9459ee, 0x82b6eb0f), TOBN(0x2e845765, 0x95c2aadd), + TOBN(0x774a84ae, 0xd327fcfe), TOBN(0xd8c93722, 0x0368d476), + TOBN(0x0dbd5748, 0xf83e8a3b), TOBN(0xa579aa96, 0x8d2495f3), + TOBN(0x535996a0, 0xae496e9b), TOBN(0x07afbfe9, 0xb7f9bcc2), + TOBN(0x3ac1dc6d, 0x5b7bd293), TOBN(0x3b592cff, 0x7022323d), + TOBN(0xba0deb98, 0x9c0a3e76), TOBN(0x18e78e9f, 0x4b197acb), + TOBN(0x211cde10, 0x296c36ef), TOBN(0x7ee89672, 0x82c4da77), + TOBN(0xb617d270, 0xa57836da), TOBN(0xf0cd9c31, 0x9cb7560b), + TOBN(0x01fdcbf7, 0xe455fe90), TOBN(0x3fb53cbb, 0x7e7334f3), + TOBN(0x781e2ea4, 0x4e7de4ec), TOBN(0x8adab3ad, 0x0b384fd0), + TOBN(0x129eee2f, 0x53d64829), TOBN(0x7a471e17, 0xa261492b), + TOBN(0xe4f9adb9, 0xe4cb4a2c), TOBN(0x3d359f6f, 0x97ba2c2d), + TOBN(0x346c6786, 0x0aacd697), TOBN(0x92b444c3, 0x75c2f8a8), + TOBN(0xc79fa117, 0xd85df44e), TOBN(0x56782372, 0x398ddf31), + TOBN(0x60e690f2, 0xbbbab3b8), TOBN(0x4851f8ae, 0x8b04816b), + TOBN(0xc72046ab, 0x9c92e4d2), TOBN(0x518c74a1, 0x7cf3136b), + TOBN(0xff4eb50a, 0xf9877d4c), TOBN(0x14578d90, 0xa919cabb), + TOBN(0x8218f8c4, 0xac5eb2b6), TOBN(0xa3ccc547, 0x542016e4), + TOBN(0x025bf48e, 0x327f8349), TOBN(0xf3e97346, 0xf43cb641), + TOBN(0xdc2bafdf, 0x500f1085), TOBN(0x57167876, 0x2f063055), + TOBN(0x5bd914b9, 0x411925a6), TOBN(0x7c078d48, 0xa1123de5), + TOBN(0xee6bf835, 0x182b165d), TOBN(0xb11b5e5b, 0xba519727), + TOBN(0xe33ea76c, 0x1eea7b85), TOBN(0x2352b461, 0x92d4f85e), + TOBN(0xf101d334, 0xafe115bb), TOBN(0xfabc1294, 0x889175a3), + TOBN(0x7f6bcdc0, 0x5233f925), TOBN(0xe0a802db, 0xe77fec55), + TOBN(0xbdb47b75, 0x8069b659), TOBN(0x1c5e12de, 0xf98fbd74), + TOBN(0x869c58c6, 0x4b8457ee), TOBN(0xa5360f69, 0x4f7ea9f7), + TOBN(0xe576c09f, 0xf460b38f), TOBN(0x6b70d548, 0x22b7fb36), + TOBN(0x3fd237f1, 0x3bfae315), TOBN(0x33797852, 0xcbdff369), + TOBN(0x97df25f5, 0x25b516f9), TOBN(0x46f388f2, 0xba38ad2d), + TOBN(0x656c4658, 0x89d8ddbb), TOBN(0x8830b26e, 0x70f38ee8), + TOBN(0x4320fd5c, 0xde1212b0), TOBN(0xc34f30cf, 0xe4a2edb2), + TOBN(0xabb131a3, 0x56ab64b8), TOBN(0x7f77f0cc, 0xd99c5d26), + TOBN(0x66856a37, 0xbf981d94), TOBN(0x19e76d09, 0x738bd76e), + TOBN(0xe76c8ac3, 0x96238f39), TOBN(0xc0a482be, 0xa830b366), + TOBN(0xb7b8eaff, 0x0b4eb499), TOBN(0x8ecd83bc, 0x4bfb4865), + TOBN(0x971b2cb7, 0xa2f3776f), TOBN(0xb42176a4, 0xf4b88adf), + TOBN(0xb9617df5, 0xbe1fa446), TOBN(0x8b32d508, 0xcd031bd2), + TOBN(0x1c6bd47d, 0x53b618c0), TOBN(0xc424f46c, 0x6a227923), + TOBN(0x7303ffde, 0xdd92d964), TOBN(0xe9712878, 0x71b5abf2), + TOBN(0x8f48a632, 0xf815561d), TOBN(0x85f48ff5, 0xd3c055d1), + TOBN(0x222a1427, 0x7525684f), TOBN(0xd0d841a0, 0x67360cc3), + TOBN(0x4245a926, 0x0b9267c6), TOBN(0xc78913f1, 0xcf07f863), + TOBN(0xaa844c8e, 0x4d0d9e24), TOBN(0xa42ad522, 0x3d5f9017), + TOBN(0xbd371749, 0xa2c989d5), TOBN(0x928292df, 0xe1f5e78e), + TOBN(0x493b383e, 0x0a1ea6da), TOBN(0x5136fd8d, 0x13aee529), + TOBN(0x860c44b1, 0xf2c34a99), TOBN(0x3b00aca4, 0xbf5855ac), + TOBN(0xabf6aaa0, 0xfaaf37be), TOBN(0x65f43682, 0x2a53ec08), + TOBN(0x1d9a5801, 0xa11b12e1), TOBN(0x78a7ab2c, 0xe20ed475), + TOBN(0x0de1067e, 0x9a41e0d5), TOBN(0x30473f5f, 0x305023ea), + TOBN(0xdd3ae09d, 0x169c7d97), TOBN(0x5cd5baa4, 0xcfaef9cd), + TOBN(0x5cd7440b, 0x65a44803), TOBN(0xdc13966a, 0x47f364de), + TOBN(0x077b2be8, 0x2b8357c1), TOBN(0x0cb1b4c5, 0xe9d57c2a), + TOBN(0x7a4ceb32, 0x05ff363e), TOBN(0xf310fa4d, 0xca35a9ef), + TOBN(0xdbb7b352, 0xf97f68c6), TOBN(0x0c773b50, 0x0b02cf58), + TOBN(0xea2e4821, 0x3c1f96d9), TOBN(0xffb357b0, 0xeee01815), + TOBN(0xb9c924cd, 0xe0f28039), TOBN(0x0b36c95a, 0x46a3fbe4), + TOBN(0x1faaaea4, 0x5e46db6c), TOBN(0xcae575c3, 0x1928aaff), + TOBN(0x7f671302, 0xa70dab86), TOBN(0xfcbd12a9, 0x71c58cfc), + TOBN(0xcbef9acf, 0xbee0cb92), TOBN(0x573da0b9, 0xf8c1b583), + TOBN(0x4752fcfe, 0x0d41d550), TOBN(0xe7eec0e3, 0x2155cffe), + TOBN(0x0fc39fcb, 0x545ae248), TOBN(0x522cb8d1, 0x8065f44e), + TOBN(0x263c962a, 0x70cbb96c), TOBN(0xe034362a, 0xbcd124a9), + TOBN(0xf120db28, 0x3c2ae58d), TOBN(0xb9a38d49, 0xfef6d507), + TOBN(0xb1fd2a82, 0x1ff140fd), TOBN(0xbd162f30, 0x20aee7e0), + TOBN(0x4e17a5d4, 0xcb251949), TOBN(0x2aebcb83, 0x4f7e1c3d), + TOBN(0x608eb25f, 0x937b0527), TOBN(0xf42e1e47, 0xeb7d9997), + TOBN(0xeba699c4, 0xb8a53a29), TOBN(0x1f921c71, 0xe091b536), + TOBN(0xcce29e7b, 0x5b26bbd5), TOBN(0x7a8ef5ed, 0x3b61a680), + TOBN(0xe5ef8043, 0xba1f1c7e), TOBN(0x16ea8217, 0x18158dda), + TOBN(0x01778a2b, 0x599ff0f9), TOBN(0x68a923d7, 0x8104fc6b), + TOBN(0x5bfa44df, 0xda694ff3), TOBN(0x4f7199db, 0xf7667f12), + TOBN(0xc06d8ff6, 0xe46f2a79), TOBN(0x08b5dead, 0xe9f8131d), + TOBN(0x02519a59, 0xabb4ce7c), TOBN(0xc4f710bc, 0xb42aec3e), + TOBN(0x3d77b057, 0x78bde41a), TOBN(0x6474bf80, 0xb4186b5a), + TOBN(0x048b3f67, 0x88c65741), TOBN(0xc64519de, 0x03c7c154), + TOBN(0xdf073846, 0x0edfcc4f), TOBN(0x319aa737, 0x48f1aa6b), + TOBN(0x8b9f8a02, 0xca909f77), TOBN(0x90258139, 0x7580bfef), + TOBN(0xd8bfd3ca, 0xc0c22719), TOBN(0xc60209e4, 0xc9ca151e), + TOBN(0x7a744ab5, 0xd9a1a69c), TOBN(0x6de5048b, 0x14937f8f), + TOBN(0x171938d8, 0xe115ac04), TOBN(0x7df70940, 0x1c6b16d2), + TOBN(0xa6aeb663, 0x7f8e94e7), TOBN(0xc130388e, 0x2a2cf094), + TOBN(0x1850be84, 0x77f54e6e), TOBN(0x9f258a72, 0x65d60fe5), + TOBN(0xff7ff0c0, 0x6c9146d6), TOBN(0x039aaf90, 0xe63a830b), + TOBN(0x38f27a73, 0x9460342f), TOBN(0x4703148c, 0x3f795f8a), + TOBN(0x1bb5467b, 0x9681a97e), TOBN(0x00931ba5, 0xecaeb594), + TOBN(0xcdb6719d, 0x786f337c), TOBN(0xd9c01cd2, 0xe704397d), + TOBN(0x0f4a3f20, 0x555c2fef), TOBN(0x00452509, 0x7c0af223), + TOBN(0x54a58047, 0x84db8e76), TOBN(0x3bacf1aa, 0x93c8aa06), + TOBN(0x11ca957c, 0xf7919422), TOBN(0x50641053, 0x78cdaa40), + TOBN(0x7a303874, 0x9f7144ae), TOBN(0x170c963f, 0x43d4acfd), + TOBN(0x5e148149, 0x58ddd3ef), TOBN(0xa7bde582, 0x9e72dba8), + TOBN(0x0769da8b, 0x6fa68750), TOBN(0xfa64e532, 0x572e0249), + TOBN(0xfcaadf9d, 0x2619ad31), TOBN(0x87882daa, 0xa7b349cd), + TOBN(0x9f6eb731, 0x6c67a775), TOBN(0xcb10471a, 0xefc5d0b1), + TOBN(0xb433750c, 0xe1b806b2), TOBN(0x19c5714d, 0x57b1ae7e), + TOBN(0xc0dc8b7b, 0xed03fd3f), TOBN(0xdd03344f, 0x31bc194e), + TOBN(0xa66c52a7, 0x8c6320b5), TOBN(0x8bc82ce3, 0xd0b6fd93), + TOBN(0xf8e13501, 0xb35f1341), TOBN(0xe53156dd, 0x25a43e42), + TOBN(0xd3adf27e, 0x4daeb85c), TOBN(0xb81d8379, 0xbbeddeb5), + TOBN(0x1b0b546e, 0x2e435867), TOBN(0x9020eb94, 0xeba5dd60), + TOBN(0x37d91161, 0x8210cb9d), TOBN(0x4c596b31, 0x5c91f1cf), + TOBN(0xb228a90f, 0x0e0b040d), TOBN(0xbaf02d82, 0x45ff897f), + TOBN(0x2aac79e6, 0x00fa6122), TOBN(0x24828817, 0x8e36f557), + TOBN(0xb9521d31, 0x113ec356), TOBN(0x9e48861e, 0x15eff1f8), + TOBN(0x2aa1d412, 0xe0d41715), TOBN(0x71f86203, 0x53f131b8), + TOBN(0xf60da8da, 0x3fd19408), TOBN(0x4aa716dc, 0x278d9d99), + TOBN(0x394531f7, 0xa8c51c90), TOBN(0xb560b0e8, 0xf59db51c), + TOBN(0xa28fc992, 0xfa34bdad), TOBN(0xf024fa14, 0x9cd4f8bd), + TOBN(0x5cf530f7, 0x23a9d0d3), TOBN(0x615ca193, 0xe28c9b56), + TOBN(0x6d2a483d, 0x6f73c51e), TOBN(0xa4cb2412, 0xea0dc2dd), + TOBN(0x50663c41, 0x1eb917ff), TOBN(0x3d3a74cf, 0xeade299e), + TOBN(0x29b3990f, 0x4a7a9202), TOBN(0xa9bccf59, 0xa7b15c3d), + TOBN(0x66a3ccdc, 0xa5df9208), TOBN(0x48027c14, 0x43f2f929), + TOBN(0xd385377c, 0x40b557f0), TOBN(0xe001c366, 0xcd684660), + TOBN(0x1b18ed6b, 0xe2183a27), TOBN(0x879738d8, 0x63210329), + TOBN(0xa687c74b, 0xbda94882), TOBN(0xd1bbcc48, 0xa684b299), + TOBN(0xaf6f1112, 0x863b3724), TOBN(0x6943d1b4, 0x2c8ce9f8), + TOBN(0xe044a3bb, 0x098cafb4), TOBN(0x27ed2310, 0x60d48caf), + TOBN(0x542b5675, 0x3a31b84d), TOBN(0xcbf3dd50, 0xfcddbed7), + TOBN(0x25031f16, 0x41b1d830), TOBN(0xa7ec851d, 0xcb0c1e27), + TOBN(0xac1c8fe0, 0xb5ae75db), TOBN(0xb24c7557, 0x08c52120), + TOBN(0x57f811dc, 0x1d4636c3), TOBN(0xf8436526, 0x681a9939), + TOBN(0x1f6bc6d9, 0x9c81adb3), TOBN(0x840f8ac3, 0x5b7d80d4), + TOBN(0x731a9811, 0xf4387f1a), TOBN(0x7c501cd3, 0xb5156880), + TOBN(0xa5ca4a07, 0xdfe68867), TOBN(0xf123d8f0, 0x5fcea120), + TOBN(0x1fbb0e71, 0xd607039e), TOBN(0x2b70e215, 0xcd3a4546), + TOBN(0x32d2f01d, 0x53324091), TOBN(0xb796ff08, 0x180ab19b), + TOBN(0x32d87a86, 0x3c57c4aa), TOBN(0x2aed9caf, 0xb7c49a27), + TOBN(0x9fb35eac, 0x31630d98), TOBN(0x338e8cdf, 0x5c3e20a3), + TOBN(0x80f16182, 0x66cde8db), TOBN(0x4e159980, 0x2d72fd36), + TOBN(0xd7b8f13b, 0x9b6e5072), TOBN(0xf5213907, 0x3b7b5dc1), + TOBN(0x4d431f1d, 0x8ce4396e), TOBN(0x37a1a680, 0xa7ed2142), + TOBN(0xbf375696, 0xd01aaf6b), TOBN(0xaa1c0c54, 0xe63aab66), + TOBN(0x3014368b, 0x4ed80940), TOBN(0x67e6d056, 0x7a6fcedd), + TOBN(0x7c208c49, 0xca97579f), TOBN(0xfe3d7a81, 0xa23597f6), + TOBN(0x5e203202, 0x7e096ae2), TOBN(0xb1f3e1e7, 0x24b39366), + TOBN(0x26da26f3, 0x2fdcdffc), TOBN(0x79422f1d, 0x6097be83)}, + {TOBN(0x263a2cfb, 0x9db3b381), TOBN(0x9c3a2dee, 0xd4df0a4b), + TOBN(0x728d06e9, 0x7d04e61f), TOBN(0x8b1adfbc, 0x42449325), + TOBN(0x6ec1d939, 0x7e053a1b), TOBN(0xee2be5c7, 0x66daf707), + TOBN(0x80ba1e14, 0x810ac7ab), TOBN(0xdd2ae778, 0xf530f174), + TOBN(0x0435d97a, 0x205b9d8b), TOBN(0x6eb8f064, 0x056756d4), + TOBN(0xd5e88a8b, 0xb6f8210e), TOBN(0x070ef12d, 0xec9fd9ea), + TOBN(0x4d849505, 0x3bcc876a), TOBN(0x12a75338, 0xa7404ce3), + TOBN(0xd22b49e1, 0xb8a1db5e), TOBN(0xec1f2051, 0x14bfa5ad), + TOBN(0xadbaeb79, 0xb6828f36), TOBN(0x9d7a0258, 0x01bd5b9e), + TOBN(0xeda01e0d, 0x1e844b0c), TOBN(0x4b625175, 0x887edfc9), + TOBN(0x14109fdd, 0x9669b621), TOBN(0x88a2ca56, 0xf6f87b98), + TOBN(0xfe2eb788, 0x170df6bc), TOBN(0x0cea06f4, 0xffa473f9), + TOBN(0x43ed81b5, 0xc4e83d33), TOBN(0xd9f35879, 0x5efd488b), + TOBN(0x164a620f, 0x9deb4d0f), TOBN(0xc6927bdb, 0xac6a7394), + TOBN(0x45c28df7, 0x9f9e0f03), TOBN(0x2868661e, 0xfcd7e1a9), + TOBN(0x7cf4e8d0, 0xffa348f1), TOBN(0x6bd4c284, 0x398538e0), + TOBN(0x2618a091, 0x289a8619), TOBN(0xef796e60, 0x6671b173), + TOBN(0x664e46e5, 0x9090c632), TOBN(0xa38062d4, 0x1e66f8fb), + TOBN(0x6c744a20, 0x0573274e), TOBN(0xd07b67e4, 0xa9271394), + TOBN(0x391223b2, 0x6bdc0e20), TOBN(0xbe2d93f1, 0xeb0a05a7), + TOBN(0xf23e2e53, 0x3f36d141), TOBN(0xe84bb3d4, 0x4dfca442), + TOBN(0xb804a48d, 0x6b7c023a), TOBN(0x1e16a8fa, 0x76431c3b), + TOBN(0x1b5452ad, 0xddd472e0), TOBN(0x7d405ee7, 0x0d1ee127), + TOBN(0x50fc6f1d, 0xffa27599), TOBN(0x351ac53c, 0xbf391b35), + TOBN(0x7efa14b8, 0x4444896b), TOBN(0x64974d2f, 0xf94027fb), + TOBN(0xefdcd0e8, 0xde84487d), TOBN(0x8c45b260, 0x2b48989b), + TOBN(0xa8fcbbc2, 0xd8463487), TOBN(0xd1b2b3f7, 0x3fbc476c), + TOBN(0x21d005b7, 0xc8f443c0), TOBN(0x518f2e67, 0x40c0139c), + TOBN(0x56036e8c, 0x06d75fc1), TOBN(0x2dcf7bb7, 0x3249a89f), + TOBN(0x81dd1d3d, 0xe245e7dd), TOBN(0xf578dc4b, 0xebd6e2a7), + TOBN(0x4c028903, 0xdf2ce7a0), TOBN(0xaee36288, 0x9c39afac), + TOBN(0xdc847c31, 0x146404ab), TOBN(0x6304c0d8, 0xa4e97818), + TOBN(0xae51dca2, 0xa91f6791), TOBN(0x2abe4190, 0x9baa9efc), + TOBN(0xd9d2e2f4, 0x559c7ac1), TOBN(0xe82f4b51, 0xfc9f773a), + TOBN(0xa7713027, 0x4073e81c), TOBN(0xc0276fac, 0xfbb596fc), + TOBN(0x1d819fc9, 0xa684f70c), TOBN(0x29b47fdd, 0xc9f7b1e0), + TOBN(0x358de103, 0x459b1940), TOBN(0xec881c59, 0x5b013e93), + TOBN(0x51574c93, 0x49532ad3), TOBN(0x2db1d445, 0xb37b46de), + TOBN(0xc6445b87, 0xdf239fd8), TOBN(0xc718af75, 0x151d24ee), + TOBN(0xaea1c4a4, 0xf43c6259), TOBN(0x40c0e5d7, 0x70be02f7), + TOBN(0x6a4590f4, 0x721b33f2), TOBN(0x2124f1fb, 0xfedf04ea), + TOBN(0xf8e53cde, 0x9745efe7), TOBN(0xe7e10432, 0x65f046d9), + TOBN(0xc3fca28e, 0xe4d0c7e6), TOBN(0x847e339a, 0x87253b1b), + TOBN(0x9b595348, 0x3743e643), TOBN(0xcb6a0a0b, 0x4fd12fc5), + TOBN(0xfb6836c3, 0x27d02dcc), TOBN(0x5ad00982, 0x7a68bcc2), + TOBN(0x1b24b44c, 0x005e912d), TOBN(0xcc83d20f, 0x811fdcfe), + TOBN(0x36527ec1, 0x666fba0c), TOBN(0x69948197, 0x14754635), + TOBN(0xfcdcb1a8, 0x556da9c2), TOBN(0xa5934267, 0x81a732b2), + TOBN(0xec1214ed, 0xa714181d), TOBN(0x609ac13b, 0x6067b341), + TOBN(0xff4b4c97, 0xa545df1f), TOBN(0xa1240501, 0x34d2076b), + TOBN(0x6efa0c23, 0x1409ca97), TOBN(0x254cc1a8, 0x20638c43), + TOBN(0xd4e363af, 0xdcfb46cd), TOBN(0x62c2adc3, 0x03942a27), + TOBN(0xc67b9df0, 0x56e46483), TOBN(0xa55abb20, 0x63736356), + TOBN(0xab93c098, 0xc551bc52), TOBN(0x382b49f9, 0xb15fe64b), + TOBN(0x9ec221ad, 0x4dff8d47), TOBN(0x79caf615, 0x437df4d6), + TOBN(0x5f13dc64, 0xbb456509), TOBN(0xe4c589d9, 0x191f0714), + TOBN(0x27b6a8ab, 0x3fd40e09), TOBN(0xe455842e, 0x77313ea9), + TOBN(0x8b51d1e2, 0x1f55988b), TOBN(0x5716dd73, 0x062bbbfc), + TOBN(0x633c11e5, 0x4e8bf3de), TOBN(0x9a0e77b6, 0x1b85be3b), + TOBN(0x56510729, 0x0911cca6), TOBN(0x27e76495, 0xefa6590f), + TOBN(0xe4ac8b33, 0x070d3aab), TOBN(0x2643672b, 0x9a2cd5e5), + TOBN(0x52eff79b, 0x1cfc9173), TOBN(0x665ca49b, 0x90a7c13f), + TOBN(0x5a8dda59, 0xb3efb998), TOBN(0x8a5b922d, 0x052f1341), + TOBN(0xae9ebbab, 0x3cf9a530), TOBN(0x35986e7b, 0xf56da4d7), + TOBN(0x3a636b5c, 0xff3513cc), TOBN(0xbb0cf8ba, 0x3198f7dd), + TOBN(0xb8d40522, 0x41f16f86), TOBN(0x760575d8, 0xde13a7bf), + TOBN(0x36f74e16, 0x9f7aa181), TOBN(0x163a3ecf, 0xf509ed1c), + TOBN(0x6aead61f, 0x3c40a491), TOBN(0x158c95fc, 0xdfe8fcaa), + TOBN(0xa3991b6e, 0x13cda46f), TOBN(0x79482415, 0x342faed0), + TOBN(0xf3ba5bde, 0x666b5970), TOBN(0x1d52e6bc, 0xb26ab6dd), + TOBN(0x768ba1e7, 0x8608dd3d), TOBN(0x4930db2a, 0xea076586), + TOBN(0xd9575714, 0xe7dc1afa), TOBN(0x1fc7bf7d, 0xf7c58817), + TOBN(0x6b47accd, 0xd9eee96c), TOBN(0x0ca277fb, 0xe58cec37), + TOBN(0x113fe413, 0xe702c42a), TOBN(0xdd1764ee, 0xc47cbe51), + TOBN(0x041e7cde, 0x7b3ed739), TOBN(0x50cb7459, 0x5ce9e1c0), + TOBN(0x35568513, 0x2925b212), TOBN(0x7cff95c4, 0x001b081c), + TOBN(0x63ee4cbd, 0x8088b454), TOBN(0xdb7f32f7, 0x9a9e0c8a), + TOBN(0xb377d418, 0x6b2447cb), TOBN(0xe3e982aa, 0xd370219b), + TOBN(0x06ccc1e4, 0xc2a2a593), TOBN(0x72c36865, 0x0773f24f), + TOBN(0xa13b4da7, 0x95859423), TOBN(0x8bbf1d33, 0x75040c8f), + TOBN(0x726f0973, 0xda50c991), TOBN(0x48afcd5b, 0x822d6ee2), + TOBN(0xe5fc718b, 0x20fd7771), TOBN(0xb9e8e77d, 0xfd0807a1), + TOBN(0x7f5e0f44, 0x99a7703d), TOBN(0x6972930e, 0x618e36f3), + TOBN(0x2b7c77b8, 0x23807bbe), TOBN(0xe5b82405, 0xcb27ff50), + TOBN(0xba8b8be3, 0xbd379062), TOBN(0xd64b7a1d, 0x2dce4a92), + TOBN(0x040a73c5, 0xb2952e37), TOBN(0x0a9e252e, 0xd438aeca), + TOBN(0xdd43956b, 0xc39d3bcb), TOBN(0x1a31ca00, 0xb32b2d63), + TOBN(0xd67133b8, 0x5c417a18), TOBN(0xd08e4790, 0x2ef442c8), + TOBN(0x98cb1ae9, 0x255c0980), TOBN(0x4bd86381, 0x2b4a739f), + TOBN(0x5a5c31e1, 0x1e4a45a1), TOBN(0x1e5d55fe, 0x9cb0db2f), + TOBN(0x74661b06, 0x8ff5cc29), TOBN(0x026b389f, 0x0eb8a4f4), + TOBN(0x536b21a4, 0x58848c24), TOBN(0x2e5bf8ec, 0x81dc72b0), + TOBN(0x03c187d0, 0xad886aac), TOBN(0x5c16878a, 0xb771b645), + TOBN(0xb07dfc6f, 0xc74045ab), TOBN(0x2c6360bf, 0x7800caed), + TOBN(0x24295bb5, 0xb9c972a3), TOBN(0xc9e6f88e, 0x7c9a6dba), + TOBN(0x90ffbf24, 0x92a79aa6), TOBN(0xde29d50a, 0x41c26ac2), + TOBN(0x9f0af483, 0xd309cbe6), TOBN(0x5b020d8a, 0xe0bced4f), + TOBN(0x606e986d, 0xb38023e3), TOBN(0xad8f2c9d, 0x1abc6933), + TOBN(0x19292e1d, 0xe7400e93), TOBN(0xfe3e18a9, 0x52be5e4d), + TOBN(0xe8e9771d, 0x2e0680bf), TOBN(0x8c5bec98, 0xc54db063), + TOBN(0x2af9662a, 0x74a55d1f), TOBN(0xe3fbf28f, 0x046f66d8), + TOBN(0xa3a72ab4, 0xd4dc4794), TOBN(0x09779f45, 0x5c7c2dd8), + TOBN(0xd893bdaf, 0xc3d19d8d), TOBN(0xd5a75094, 0x57d6a6df), + TOBN(0x8cf8fef9, 0x952e6255), TOBN(0x3da67cfb, 0xda9a8aff), + TOBN(0x4c23f62a, 0x2c160dcd), TOBN(0x34e6c5e3, 0x8f90eaef), + TOBN(0x35865519, 0xa9a65d5a), TOBN(0x07c48aae, 0x8fd38a3d), + TOBN(0xb7e7aeda, 0x50068527), TOBN(0x2c09ef23, 0x1c90936a), + TOBN(0x31ecfeb6, 0xe879324c), TOBN(0xa0871f6b, 0xfb0ec938), + TOBN(0xb1f0fb68, 0xd84d835d), TOBN(0xc90caf39, 0x861dc1e6), + TOBN(0x12e5b046, 0x7594f8d7), TOBN(0x26897ae2, 0x65012b92), + TOBN(0xbcf68a08, 0xa4d6755d), TOBN(0x403ee41c, 0x0991fbda), + TOBN(0x733e343e, 0x3bbf17e8), TOBN(0xd2c7980d, 0x679b3d65), + TOBN(0x33056232, 0xd2e11305), TOBN(0x966be492, 0xf3c07a6f), + TOBN(0x6a8878ff, 0xbb15509d), TOBN(0xff221101, 0x0a9b59a4), + TOBN(0x6c9f564a, 0xabe30129), TOBN(0xc6f2c940, 0x336e64cf), + TOBN(0x0fe75262, 0x8b0c8022), TOBN(0xbe0267e9, 0x6ae8db87), + TOBN(0x22e192f1, 0x93bc042b), TOBN(0xf085b534, 0xb237c458), + TOBN(0xa0d192bd, 0x832c4168), TOBN(0x7a76e9e3, 0xbdf6271d), + TOBN(0x52a882fa, 0xb88911b5), TOBN(0xc85345e4, 0xb4db0eb5), + TOBN(0xa3be02a6, 0x81a7c3ff), TOBN(0x51889c8c, 0xf0ec0469), + TOBN(0x9d031369, 0xa5e829e5), TOBN(0xcbb4c6fc, 0x1607aa41), + TOBN(0x75ac59a6, 0x241d84c1), TOBN(0xc043f2bf, 0x8829e0ee), + TOBN(0x82a38f75, 0x8ea5e185), TOBN(0x8bda40b9, 0xd87cbd9f), + TOBN(0x9e65e75e, 0x2d8fc601), TOBN(0x3d515f74, 0xa35690b3), + TOBN(0x534acf4f, 0xda79e5ac), TOBN(0x68b83b3a, 0x8630215f), + TOBN(0x5c748b2e, 0xd085756e), TOBN(0xb0317258, 0xe5d37cb2), + TOBN(0x6735841a, 0xc5ccc2c4), TOBN(0x7d7dc96b, 0x3d9d5069), + TOBN(0xa147e410, 0xfd1754bd), TOBN(0x65296e94, 0xd399ddd5), + TOBN(0xf6b5b2d0, 0xbc8fa5bc), TOBN(0x8a5ead67, 0x500c277b), + TOBN(0x214625e6, 0xdfa08a5d), TOBN(0x51fdfedc, 0x959cf047), + TOBN(0x6bc9430b, 0x289fca32), TOBN(0xe36ff0cf, 0x9d9bdc3f), + TOBN(0x2fe187cb, 0x58ea0ede), TOBN(0xed66af20, 0x5a900b3f), + TOBN(0x00e0968b, 0x5fa9f4d6), TOBN(0x2d4066ce, 0x37a362e7), + TOBN(0xa99a9748, 0xbd07e772), TOBN(0x710989c0, 0x06a4f1d0), + TOBN(0xd5dedf35, 0xce40cbd8), TOBN(0xab55c5f0, 0x1743293d), + TOBN(0x766f1144, 0x8aa24e2c), TOBN(0x94d874f8, 0x605fbcb4), + TOBN(0xa365f0e8, 0xa518001b), TOBN(0xee605eb6, 0x9d04ef0f), + TOBN(0x5a3915cd, 0xba8d4d25), TOBN(0x44c0e1b8, 0xb5113472), + TOBN(0xcbb024e8, 0x8b6740dc), TOBN(0x89087a53, 0xee1d4f0c), + TOBN(0xa88fa05c, 0x1fc4e372), TOBN(0x8bf395cb, 0xaf8b3af2), + TOBN(0x1e71c9a1, 0xdeb8568b), TOBN(0xa35daea0, 0x80fb3d32), + TOBN(0xe8b6f266, 0x2cf8fb81), TOBN(0x6d51afe8, 0x9490696a), + TOBN(0x81beac6e, 0x51803a19), TOBN(0xe3d24b7f, 0x86219080), + TOBN(0x727cfd9d, 0xdf6f463c), TOBN(0x8c6865ca, 0x72284ee8), + TOBN(0x32c88b7d, 0xb743f4ef), TOBN(0x3793909b, 0xe7d11dce), + TOBN(0xd398f922, 0x2ff2ebe8), TOBN(0x2c70ca44, 0xe5e49796), + TOBN(0xdf4d9929, 0xcb1131b1), TOBN(0x7826f298, 0x25888e79), + TOBN(0x4d3a112c, 0xf1d8740a), TOBN(0x00384cb6, 0x270afa8b), + TOBN(0xcb64125b, 0x3ab48095), TOBN(0x3451c256, 0x62d05106), + TOBN(0xd73d577d, 0xa4955845), TOBN(0x39570c16, 0xbf9f4433), + TOBN(0xd7dfaad3, 0xadecf263), TOBN(0xf1c3d8d1, 0xdc76e102), + TOBN(0x5e774a58, 0x54c6a836), TOBN(0xdad4b672, 0x3e92d47b), + TOBN(0xbe7e990f, 0xf0d796a0), TOBN(0x5fc62478, 0xdf0e8b02), + TOBN(0x8aae8bf4, 0x030c00ad), TOBN(0x3d2db93b, 0x9004ba0f), + TOBN(0xe48c8a79, 0xd85d5ddc), TOBN(0xe907caa7, 0x6bb07f34), + TOBN(0x58db343a, 0xa39eaed5), TOBN(0x0ea6e007, 0xadaf5724), + TOBN(0xe00df169, 0xd23233f3), TOBN(0x3e322796, 0x77cb637f), + TOBN(0x1f897c0e, 0x1da0cf6c), TOBN(0xa651f5d8, 0x31d6bbdd), + TOBN(0xdd61af19, 0x1a230c76), TOBN(0xbd527272, 0xcdaa5e4a), + TOBN(0xca753636, 0xd0abcd7e), TOBN(0x78bdd37c, 0x370bd8dc), + TOBN(0xc23916c2, 0x17cd93fe), TOBN(0x65b97a4d, 0xdadce6e2), + TOBN(0xe04ed4eb, 0x174e42f8), TOBN(0x1491ccaa, 0xbb21480a), + TOBN(0x145a8280, 0x23196332), TOBN(0x3c3862d7, 0x587b479a), + TOBN(0x9f4a88a3, 0x01dcd0ed), TOBN(0x4da2b7ef, 0x3ea12f1f), + TOBN(0xf8e7ae33, 0xb126e48e), TOBN(0x404a0b32, 0xf494e237), + TOBN(0x9beac474, 0xc55acadb), TOBN(0x4ee5cf3b, 0xcbec9fd9), + TOBN(0x336b33b9, 0x7df3c8c3), TOBN(0xbd905fe3, 0xb76808fd), + TOBN(0x8f436981, 0xaa45c16a), TOBN(0x255c5bfa, 0x3dd27b62), + TOBN(0x71965cbf, 0xc3dd9b4d), TOBN(0xce23edbf, 0xfc068a87), + TOBN(0xb78d4725, 0x745b029b), TOBN(0x74610713, 0xcefdd9bd), + TOBN(0x7116f75f, 0x1266bf52), TOBN(0x02046722, 0x18e49bb6), + TOBN(0xdf43df9f, 0x3d6f19e3), TOBN(0xef1bc7d0, 0xe685cb2f), + TOBN(0xcddb27c1, 0x7078c432), TOBN(0xe1961b9c, 0xb77fedb7), + TOBN(0x1edc2f5c, 0xc2290570), TOBN(0x2c3fefca, 0x19cbd886), + TOBN(0xcf880a36, 0xc2af389a), TOBN(0x96c610fd, 0xbda71cea), + TOBN(0xf03977a9, 0x32aa8463), TOBN(0x8eb7763f, 0x8586d90a), + TOBN(0x3f342454, 0x2a296e77), TOBN(0xc8718683, 0x42837a35), + TOBN(0x7dc71090, 0x6a09c731), TOBN(0x54778ffb, 0x51b816db), + TOBN(0x6b33bfec, 0xaf06defd), TOBN(0xfe3c105f, 0x8592b70b), + TOBN(0xf937fda4, 0x61da6114), TOBN(0x3c13e651, 0x4c266ad7), + TOBN(0xe363a829, 0x855938e8), TOBN(0x2eeb5d9e, 0x9de54b72), + TOBN(0xbeb93b0e, 0x20ccfab9), TOBN(0x3dffbb5f, 0x25e61a25), + TOBN(0x7f655e43, 0x1acc093d), TOBN(0x0cb6cc3d, 0x3964ce61), + TOBN(0x6ab283a1, 0xe5e9b460), TOBN(0x55d787c5, 0xa1c7e72d), + TOBN(0x4d2efd47, 0xdeadbf02), TOBN(0x11e80219, 0xac459068), + TOBN(0x810c7626, 0x71f311f0), TOBN(0xfa17ef8d, 0x4ab6ef53), + TOBN(0xaf47fd25, 0x93e43bff), TOBN(0x5cb5ff3f, 0x0be40632), + TOBN(0x54687106, 0x8ee61da3), TOBN(0x7764196e, 0xb08afd0f), + TOBN(0x831ab3ed, 0xf0290a8f), TOBN(0xcae81966, 0xcb47c387), + TOBN(0xaad7dece, 0x184efb4f), TOBN(0xdcfc53b3, 0x4749110e), + TOBN(0x6698f23c, 0x4cb632f9), TOBN(0xc42a1ad6, 0xb91f8067), + TOBN(0xb116a81d, 0x6284180a), TOBN(0xebedf5f8, 0xe901326f), + TOBN(0xf2274c9f, 0x97e3e044), TOBN(0x42018520, 0x11d09fc9), + TOBN(0x56a65f17, 0xd18e6e23), TOBN(0x2ea61e2a, 0x352b683c), + TOBN(0x27d291bc, 0x575eaa94), TOBN(0x9e7bc721, 0xb8ff522d), + TOBN(0x5f7268bf, 0xa7f04d6f), TOBN(0x5868c73f, 0xaba41748), + TOBN(0x9f85c2db, 0x7be0eead), TOBN(0x511e7842, 0xff719135), + TOBN(0x5a06b1e9, 0xc5ea90d7), TOBN(0x0c19e283, 0x26fab631), + TOBN(0x8af8f0cf, 0xe9206c55), TOBN(0x89389cb4, 0x3553c06a), + TOBN(0x39dbed97, 0xf65f8004), TOBN(0x0621b037, 0xc508991d), + TOBN(0x1c52e635, 0x96e78cc4), TOBN(0x5385c8b2, 0x0c06b4a8), + TOBN(0xd84ddfdb, 0xb0e87d03), TOBN(0xc49dfb66, 0x934bafad), + TOBN(0x7071e170, 0x59f70772), TOBN(0x3a073a84, 0x3a1db56b), + TOBN(0x03494903, 0x3b8af190), TOBN(0x7d882de3, 0xd32920f0), + TOBN(0x91633f0a, 0xb2cf8940), TOBN(0x72b0b178, 0x6f948f51), + TOBN(0x2d28dc30, 0x782653c8), TOBN(0x88829849, 0xdb903a05), + TOBN(0xb8095d0c, 0x6a19d2bb), TOBN(0x4b9e7f0c, 0x86f782cb), + TOBN(0x7af73988, 0x2d907064), TOBN(0xd12be0fe, 0x8b32643c), + TOBN(0x358ed23d, 0x0e165dc3), TOBN(0x3d47ce62, 0x4e2378ce), + TOBN(0x7e2bb0b9, 0xfeb8a087), TOBN(0x3246e8ae, 0xe29e10b9), + TOBN(0x459f4ec7, 0x03ce2b4d), TOBN(0xe9b4ca1b, 0xbbc077cf), + TOBN(0x2613b4f2, 0x0e9940c1), TOBN(0xfc598bb9, 0x047d1eb1), + TOBN(0x9744c62b, 0x45036099), TOBN(0xa9dee742, 0x167c65d8), + TOBN(0x0c511525, 0xdabe1943), TOBN(0xda110554, 0x93c6c624), + TOBN(0xae00a52c, 0x651a3be2), TOBN(0xcda5111d, 0x884449a6), + TOBN(0x063c06f4, 0xff33bed1), TOBN(0x73baaf9a, 0x0d3d76b4), + TOBN(0x52fb0c9d, 0x7fc63668), TOBN(0x6886c9dd, 0x0c039cde), + TOBN(0x602bd599, 0x55b22351), TOBN(0xb00cab02, 0x360c7c13), + TOBN(0x8cb616bc, 0x81b69442), TOBN(0x41486700, 0xb55c3cee), + TOBN(0x71093281, 0xf49ba278), TOBN(0xad956d9c, 0x64a50710), + TOBN(0x9561f28b, 0x638a7e81), TOBN(0x54155cdf, 0x5980ddc3), + TOBN(0xb2db4a96, 0xd26f247a), TOBN(0x9d774e4e, 0x4787d100), + TOBN(0x1a9e6e2e, 0x078637d2), TOBN(0x1c363e2d, 0x5e0ae06a), + TOBN(0x7493483e, 0xe9cfa354), TOBN(0x76843cb3, 0x7f74b98d), + TOBN(0xbaca6591, 0xd4b66947), TOBN(0xb452ce98, 0x04460a8c), + TOBN(0x6830d246, 0x43768f55), TOBN(0xf4197ed8, 0x7dff12df), + TOBN(0x6521b472, 0x400dd0f7), TOBN(0x59f5ca8f, 0x4b1e7093), + TOBN(0x6feff11b, 0x080338ae), TOBN(0x0ada31f6, 0xa29ca3c6), + TOBN(0x24794eb6, 0x94a2c215), TOBN(0xd83a43ab, 0x05a57ab4), + TOBN(0x264a543a, 0x2a6f89fe), TOBN(0x2c2a3868, 0xdd5ec7c2), + TOBN(0xd3373940, 0x8439d9b2), TOBN(0x715ea672, 0x0acd1f11), + TOBN(0x42c1d235, 0xe7e6cc19), TOBN(0x81ce6e96, 0xb990585c), + TOBN(0x04e5dfe0, 0xd809c7bd), TOBN(0xd7b2580c, 0x8f1050ab), + TOBN(0x6d91ad78, 0xd8a4176f), TOBN(0x0af556ee, 0x4e2e897c), + TOBN(0x162a8b73, 0x921de0ac), TOBN(0x52ac9c22, 0x7ea78400), + TOBN(0xee2a4eea, 0xefce2174), TOBN(0xbe61844e, 0x6d637f79), + TOBN(0x0491f1bc, 0x789a283b), TOBN(0x72d3ac3d, 0x880836f4), + TOBN(0xaa1c5ea3, 0x88e5402d), TOBN(0x1b192421, 0xd5cc473d), + TOBN(0x5c0b9998, 0x9dc84cac), TOBN(0xb0a8482d, 0x9c6e75b8), + TOBN(0x639961d0, 0x3a191ce2), TOBN(0xda3bc865, 0x6d837930), + TOBN(0xca990653, 0x056e6f8f), TOBN(0x84861c41, 0x64d133a7), + TOBN(0x8b403276, 0x746abe40), TOBN(0xb7b4d51a, 0xebf8e303), + TOBN(0x05b43211, 0x220a255d), TOBN(0xc997152c, 0x02419e6e), + TOBN(0x76ff47b6, 0x630c2fea), TOBN(0x50518677, 0x281fdade), + TOBN(0x3283b8ba, 0xcf902b0b), TOBN(0x8d4b4eb5, 0x37db303b), + TOBN(0xcc89f42d, 0x755011bc), TOBN(0xb43d74bb, 0xdd09d19b), + TOBN(0x65746bc9, 0x8adba350), TOBN(0x364eaf8c, 0xb51c1927), + TOBN(0x13c76596, 0x10ad72ec), TOBN(0x30045121, 0xf8d40c20), + TOBN(0x6d2d99b7, 0xea7b979b), TOBN(0xcd78cd74, 0xe6fb3bcd), + TOBN(0x11e45a9e, 0x86cffbfe), TOBN(0x78a61cf4, 0x637024f6), + TOBN(0xd06bc872, 0x3d502295), TOBN(0xf1376854, 0x458cb288), + TOBN(0xb9db26a1, 0x342f8586), TOBN(0xf33effcf, 0x4beee09e), + TOBN(0xd7e0c4cd, 0xb30cfb3a), TOBN(0x6d09b8c1, 0x6c9db4c8), + TOBN(0x40ba1a42, 0x07c8d9df), TOBN(0x6fd495f7, 0x1c52c66d), + TOBN(0xfb0e169f, 0x275264da), TOBN(0x80c2b746, 0xe57d8362), + TOBN(0xedd987f7, 0x49ad7222), TOBN(0xfdc229af, 0x4398ec7b)}, + {TOBN(0xb0d1ed84, 0x52666a58), TOBN(0x4bcb6e00, 0xe6a9c3c2), + TOBN(0x3c57411c, 0x26906408), TOBN(0xcfc20755, 0x13556400), + TOBN(0xa08b1c50, 0x5294dba3), TOBN(0xa30ba286, 0x8b7dd31e), + TOBN(0xd70ba90e, 0x991eca74), TOBN(0x094e142c, 0xe762c2b9), + TOBN(0xb81d783e, 0x979f3925), TOBN(0x1efd130a, 0xaf4c89a7), + TOBN(0x525c2144, 0xfd1bf7fa), TOBN(0x4b296904, 0x1b265a9e), + TOBN(0xed8e9634, 0xb9db65b6), TOBN(0x35c82e32, 0x03599d8a), + TOBN(0xdaa7a54f, 0x403563f3), TOBN(0x9df088ad, 0x022c38ab), + TOBN(0xe5cfb066, 0xbb3fd30a), TOBN(0x429169da, 0xeff0354e), + TOBN(0x809cf852, 0x3524e36c), TOBN(0x136f4fb3, 0x0155be1d), + TOBN(0x4826af01, 0x1fbba712), TOBN(0x6ef0f0b4, 0x506ba1a1), + TOBN(0xd9928b31, 0x77aea73e), TOBN(0xe2bf6af2, 0x5eaa244e), + TOBN(0x8d084f12, 0x4237b64b), TOBN(0x688ebe99, 0xe3ecfd07), + TOBN(0x57b8a70c, 0xf6845dd8), TOBN(0x808fc59c, 0x5da4a325), + TOBN(0xa9032b2b, 0xa3585862), TOBN(0xb66825d5, 0xedf29386), + TOBN(0xb5a5a8db, 0x431ec29b), TOBN(0xbb143a98, 0x3a1e8dc8), + TOBN(0x35ee94ce, 0x12ae381b), TOBN(0x3a7f176c, 0x86ccda90), + TOBN(0xc63a657e, 0x4606eaca), TOBN(0x9ae5a380, 0x43cd04df), + TOBN(0x9bec8d15, 0xed251b46), TOBN(0x1f5d6d30, 0xcaca5e64), + TOBN(0x347b3b35, 0x9ff20f07), TOBN(0x4d65f034, 0xf7e4b286), + TOBN(0x9e93ba24, 0xf111661e), TOBN(0xedced484, 0xb105eb04), + TOBN(0x96dc9ba1, 0xf424b578), TOBN(0xbf8f66b7, 0xe83e9069), + TOBN(0x872d4df4, 0xd7ed8216), TOBN(0xbf07f377, 0x8e2cbecf), + TOBN(0x4281d899, 0x98e73754), TOBN(0xfec85fbb, 0x8aab8708), + TOBN(0x9a3c0dee, 0xa5ba5b0b), TOBN(0xe6a116ce, 0x42d05299), + TOBN(0xae9775fe, 0xe9b02d42), TOBN(0x72b05200, 0xa1545cb6), + TOBN(0xbc506f7d, 0x31a3b4ea), TOBN(0xe5893078, 0x8bbd9b32), + TOBN(0xc8bc5f37, 0xe4b12a97), TOBN(0x6b000c06, 0x4a73b671), + TOBN(0x13b5bf22, 0x765fa7d0), TOBN(0x59805bf0, 0x1d6a5370), + TOBN(0x67a5e29d, 0x4280db98), TOBN(0x4f53916f, 0x776b1ce3), + TOBN(0x714ff61f, 0x33ddf626), TOBN(0x4206238e, 0xa085d103), + TOBN(0x1c50d4b7, 0xe5809ee3), TOBN(0x999f450d, 0x85f8eb1d), + TOBN(0x658a6051, 0xe4c79e9b), TOBN(0x1394cb73, 0xc66a9fea), + TOBN(0x27f31ed5, 0xc6be7b23), TOBN(0xf4c88f36, 0x5aa6f8fe), + TOBN(0x0fb0721f, 0x4aaa499e), TOBN(0x68b3a7d5, 0xe3fb2a6b), + TOBN(0xa788097d, 0x3a92851d), TOBN(0x060e7f8a, 0xe96f4913), + TOBN(0x82eebe73, 0x1a3a93bc), TOBN(0x42bbf465, 0xa21adc1a), + TOBN(0xc10b6fa4, 0xef030efd), TOBN(0x247aa4c7, 0x87b097bb), + TOBN(0x8b8dc632, 0xf60c77da), TOBN(0x6ffbc26a, 0xc223523e), + TOBN(0xa4f6ff11, 0x344579cf), TOBN(0x5825653c, 0x980250f6), + TOBN(0xb2dd097e, 0xbc1aa2b9), TOBN(0x07889393, 0x37a0333a), + TOBN(0x1cf55e71, 0x37a0db38), TOBN(0x2648487f, 0x792c1613), + TOBN(0xdad01336, 0x3fcef261), TOBN(0x6239c81d, 0x0eabf129), + TOBN(0x8ee761de, 0x9d276be2), TOBN(0x406a7a34, 0x1eda6ad3), + TOBN(0x4bf367ba, 0x4a493b31), TOBN(0x54f20a52, 0x9bf7f026), + TOBN(0xb696e062, 0x9795914b), TOBN(0xcddab96d, 0x8bf236ac), + TOBN(0x4ff2c70a, 0xed25ea13), TOBN(0xfa1d09eb, 0x81cbbbe7), + TOBN(0x88fc8c87, 0x468544c5), TOBN(0x847a670d, 0x696b3317), + TOBN(0xf133421e, 0x64bcb626), TOBN(0xaea638c8, 0x26dee0b5), + TOBN(0xd6e7680b, 0xb310346c), TOBN(0xe06f4097, 0xd5d4ced3), + TOBN(0x09961452, 0x7512a30b), TOBN(0xf3d867fd, 0xe589a59a), + TOBN(0x2e73254f, 0x52d0c180), TOBN(0x9063d8a3, 0x333c74ac), + TOBN(0xeda6c595, 0xd314e7bc), TOBN(0x2ee7464b, 0x467899ed), + TOBN(0x1cef423c, 0x0a1ed5d3), TOBN(0x217e76ea, 0x69cc7613), + TOBN(0x27ccce1f, 0xe7cda917), TOBN(0x12d8016b, 0x8a893f16), + TOBN(0xbcd6de84, 0x9fc74f6b), TOBN(0xfa5817e2, 0xf3144e61), + TOBN(0x1f354164, 0x0821ee4c), TOBN(0x1583eab4, 0x0bc61992), + TOBN(0x7490caf6, 0x1d72879f), TOBN(0x998ad9f3, 0xf76ae7b2), + TOBN(0x1e181950, 0xa41157f7), TOBN(0xa9d7e1e6, 0xe8da3a7e), + TOBN(0x963784eb, 0x8426b95f), TOBN(0x0ee4ed6e, 0x542e2a10), + TOBN(0xb79d4cc5, 0xac751e7b), TOBN(0x93f96472, 0xfd4211bd), + TOBN(0x8c72d3d2, 0xc8de4fc6), TOBN(0x7b69cbf5, 0xdf44f064), + TOBN(0x3da90ca2, 0xf4bf94e1), TOBN(0x1a5325f8, 0xf12894e2), + TOBN(0x0a437f6c, 0x7917d60b), TOBN(0x9be70486, 0x96c9cb5d), + TOBN(0xb4d880bf, 0xe1dc5c05), TOBN(0xd738adda, 0xeebeeb57), + TOBN(0x6f0119d3, 0xdf0fe6a3), TOBN(0x5c686e55, 0x66eaaf5a), + TOBN(0x9cb10b50, 0xdfd0b7ec), TOBN(0xbdd0264b, 0x6a497c21), + TOBN(0xfc093514, 0x8c546c96), TOBN(0x58a947fa, 0x79dbf42a), + TOBN(0xc0b48d4e, 0x49ccd6d7), TOBN(0xff8fb02c, 0x88bd5580), + TOBN(0xc75235e9, 0x07d473b2), TOBN(0x4fab1ac5, 0xa2188af3), + TOBN(0x030fa3bc, 0x97576ec0), TOBN(0xe8c946e8, 0x0b7e7d2f), + TOBN(0x40a5c9cc, 0x70305600), TOBN(0x6d8260a9, 0xc8b013b4), + TOBN(0x0368304f, 0x70bba85c), TOBN(0xad090da1, 0xa4a0d311), + TOBN(0x7170e870, 0x2415eec1), TOBN(0xbfba35fe, 0x8461ea47), + TOBN(0x6279019a, 0xc1e91938), TOBN(0xa47638f3, 0x1afc415f), + TOBN(0x36c65cbb, 0xbcba0e0f), TOBN(0x02160efb, 0x034e2c48), + TOBN(0xe6c51073, 0x615cd9e4), TOBN(0x498ec047, 0xf1243c06), + TOBN(0x3e5a8809, 0xb17b3d8c), TOBN(0x5cd99e61, 0x0cc565f1), + TOBN(0x81e312df, 0x7851dafe), TOBN(0xf156f5ba, 0xa79061e2), + TOBN(0x80d62b71, 0x880c590e), TOBN(0xbec9746f, 0x0a39faa1), + TOBN(0x1d98a9c1, 0xc8ed1f7a), TOBN(0x09e43bb5, 0xa81d5ff2), + TOBN(0xd5f00f68, 0x0da0794a), TOBN(0x412050d9, 0x661aa836), + TOBN(0xa89f7c4e, 0x90747e40), TOBN(0x6dc05ebb, 0xb62a3686), + TOBN(0xdf4de847, 0x308e3353), TOBN(0x53868fbb, 0x9fb53bb9), + TOBN(0x2b09d2c3, 0xcfdcf7dd), TOBN(0x41a9fce3, 0x723fcab4), + TOBN(0x73d905f7, 0x07f57ca3), TOBN(0x080f9fb1, 0xac8e1555), + TOBN(0x7c088e84, 0x9ba7a531), TOBN(0x07d35586, 0xed9a147f), + TOBN(0x602846ab, 0xaf48c336), TOBN(0x7320fd32, 0x0ccf0e79), + TOBN(0xaa780798, 0xb18bd1ff), TOBN(0x52c2e300, 0xafdd2905), + TOBN(0xf27ea3d6, 0x434267cd), TOBN(0x8b96d16d, 0x15605b5f), + TOBN(0x7bb31049, 0x4b45706b), TOBN(0xe7f58b8e, 0x743d25f8), + TOBN(0xe9b5e45b, 0x87f30076), TOBN(0xd19448d6, 0x5d053d5a), + TOBN(0x1ecc8cb9, 0xd3210a04), TOBN(0x6bc7d463, 0xdafb5269), + TOBN(0x3e59b10a, 0x67c3489f), TOBN(0x1769788c, 0x65641e1b), + TOBN(0x8a53b82d, 0xbd6cb838), TOBN(0x7066d6e6, 0x236d5f22), + TOBN(0x03aa1c61, 0x6908536e), TOBN(0xc971da0d, 0x66ae9809), + TOBN(0x01b3a86b, 0xc49a2fac), TOBN(0x3b8420c0, 0x3092e77a), + TOBN(0x02057300, 0x7d6fb556), TOBN(0x6941b2a1, 0xbff40a87), + TOBN(0x140b6308, 0x0658ff2a), TOBN(0x87804363, 0x3424ab36), + TOBN(0x0253bd51, 0x5751e299), TOBN(0xc75bcd76, 0x449c3e3a), + TOBN(0x92eb4090, 0x7f8f875d), TOBN(0x9c9d754e, 0x56c26bbf), + TOBN(0x158cea61, 0x8110bbe7), TOBN(0x62a6b802, 0x745f91ea), + TOBN(0xa79c41aa, 0xc6e7394b), TOBN(0x445b6a83, 0xad57ef10), + TOBN(0x0c5277eb, 0x6ea6f40c), TOBN(0x319fe96b, 0x88633365), + TOBN(0x0b0fc61f, 0x385f63cb), TOBN(0x41250c84, 0x22bdd127), + TOBN(0x67d153f1, 0x09e942c2), TOBN(0x60920d08, 0xc021ad5d), + TOBN(0x229f5746, 0x724d81a5), TOBN(0xb7ffb892, 0x5bba3299), + TOBN(0x518c51a1, 0xde413032), TOBN(0x2a9bfe77, 0x3c2fd94c), + TOBN(0xcbcde239, 0x3191f4fd), TOBN(0x43093e16, 0xd3d6ada1), + TOBN(0x184579f3, 0x58769606), TOBN(0x2c94a8b3, 0xd236625c), + TOBN(0x6922b9c0, 0x5c437d8e), TOBN(0x3d4ae423, 0xd8d9f3c8), + TOBN(0xf72c31c1, 0x2e7090a2), TOBN(0x4ac3f5f3, 0xd76a55bd), + TOBN(0x342508fc, 0x6b6af991), TOBN(0x0d527100, 0x1b5cebbd), + TOBN(0xb84740d0, 0xdd440dd7), TOBN(0x748ef841, 0x780162fd), + TOBN(0xa8dbfe0e, 0xdfc6fafb), TOBN(0xeadfdf05, 0xf7300f27), + TOBN(0x7d06555f, 0xfeba4ec9), TOBN(0x12c56f83, 0x9e25fa97), + TOBN(0x77f84203, 0xd39b8c34), TOBN(0xed8b1be6, 0x3125eddb), + TOBN(0x5bbf2441, 0xf6e39dc5), TOBN(0xb00f6ee6, 0x6a5d678a), + TOBN(0xba456ecf, 0x57d0ea99), TOBN(0xdcae0f58, 0x17e06c43), + TOBN(0x01643de4, 0x0f5b4baa), TOBN(0x2c324341, 0xd161b9be), + TOBN(0x80177f55, 0xe126d468), TOBN(0xed325f1f, 0x76748e09), + TOBN(0x6116004a, 0xcfa9bdc2), TOBN(0x2d8607e6, 0x3a9fb468), + TOBN(0x0e573e27, 0x6009d660), TOBN(0x3a525d2e, 0x8d10c5a1), + TOBN(0xd26cb45c, 0x3b9009a0), TOBN(0xb6b0cdc0, 0xde9d7448), + TOBN(0x949c9976, 0xe1337c26), TOBN(0x6faadebd, 0xd73d68e5), + TOBN(0x9e158614, 0xf1b768d9), TOBN(0x22dfa557, 0x9cc4f069), + TOBN(0xccd6da17, 0xbe93c6d6), TOBN(0x24866c61, 0xa504f5b9), + TOBN(0x2121353c, 0x8d694da1), TOBN(0x1c6ca580, 0x0140b8c6), + TOBN(0xc245ad8c, 0xe964021e), TOBN(0xb83bffba, 0x032b82b3), + TOBN(0xfaa220c6, 0x47ef9898), TOBN(0x7e8d3ac6, 0x982c948a), + TOBN(0x1faa2091, 0xbc2d124a), TOBN(0xbd54c3dd, 0x05b15ff4), + TOBN(0x386bf3ab, 0xc87c6fb7), TOBN(0xfb2b0563, 0xfdeb6f66), + TOBN(0x4e77c557, 0x5b45afb4), TOBN(0xe9ded649, 0xefb8912d), + TOBN(0x7ec9bbf5, 0x42f6e557), TOBN(0x2570dfff, 0x62671f00), + TOBN(0x2b3bfb78, 0x88e084bd), TOBN(0xa024b238, 0xf37fe5b4), + TOBN(0x44e7dc04, 0x95649aee), TOBN(0x498ca255, 0x5e7ec1d8), + TOBN(0x3bc766ea, 0xaaa07e86), TOBN(0x0db6facb, 0xf3608586), + TOBN(0xbadd2549, 0xbdc259c8), TOBN(0x95af3c6e, 0x041c649f), + TOBN(0xb36a928c, 0x02e30afb), TOBN(0x9b5356ad, 0x008a88b8), + TOBN(0x4b67a5f1, 0xcf1d9e9d), TOBN(0xc6542e47, 0xa5d8d8ce), + TOBN(0x73061fe8, 0x7adfb6cc), TOBN(0xcc826fd3, 0x98678141), + TOBN(0x00e758b1, 0x3c80515a), TOBN(0x6afe3247, 0x41485083), + TOBN(0x0fcb08b9, 0xb6ae8a75), TOBN(0xb8cf388d, 0x4acf51e1), + TOBN(0x344a5560, 0x6961b9d6), TOBN(0x1a6778b8, 0x6a97fd0c), + TOBN(0xd840fdc1, 0xecc4c7e3), TOBN(0xde9fe47d, 0x16db68cc), + TOBN(0xe95f89de, 0xa3e216aa), TOBN(0x84f1a6a4, 0x9594a8be), + TOBN(0x7ddc7d72, 0x5a7b162b), TOBN(0xc5cfda19, 0xadc817a3), + TOBN(0x80a5d350, 0x78b58d46), TOBN(0x93365b13, 0x82978f19), + TOBN(0x2e44d225, 0x26a1fc90), TOBN(0x0d6d10d2, 0x4d70705d), + TOBN(0xd94b6b10, 0xd70c45f4), TOBN(0x0f201022, 0xb216c079), + TOBN(0xcec966c5, 0x658fde41), TOBN(0xa8d2bc7d, 0x7e27601d), + TOBN(0xbfcce3e1, 0xff230be7), TOBN(0x3394ff6b, 0x0033ffb5), + TOBN(0xd890c509, 0x8132c9af), TOBN(0xaac4b0eb, 0x361e7868), + TOBN(0x5194ded3, 0xe82d15aa), TOBN(0x4550bd2e, 0x23ae6b7d), + TOBN(0x3fda318e, 0xea5399d4), TOBN(0xd989bffa, 0x91638b80), + TOBN(0x5ea124d0, 0xa14aa12d), TOBN(0x1fb1b899, 0x3667b944), + TOBN(0x95ec7969, 0x44c44d6a), TOBN(0x91df144a, 0x57e86137), + TOBN(0x915fd620, 0x73adac44), TOBN(0x8f01732d, 0x59a83801), + TOBN(0xec579d25, 0x3aa0a633), TOBN(0x06de5e7c, 0xc9d6d59c), + TOBN(0xc132f958, 0xb1ef8010), TOBN(0x29476f96, 0xe65c1a02), + TOBN(0x336a77c0, 0xd34c3565), TOBN(0xef1105b2, 0x1b9f1e9e), + TOBN(0x63e6d08b, 0xf9e08002), TOBN(0x9aff2f21, 0xc613809e), + TOBN(0xb5754f85, 0x3a80e75d), TOBN(0xde71853e, 0x6bbda681), + TOBN(0x86f041df, 0x8197fd7a), TOBN(0x8b332e08, 0x127817fa), + TOBN(0x05d99be8, 0xb9c20cda), TOBN(0x89f7aad5, 0xd5cd0c98), + TOBN(0x7ef936fe, 0x5bb94183), TOBN(0x92ca0753, 0xb05cd7f2), + TOBN(0x9d65db11, 0x74a1e035), TOBN(0x02628cc8, 0x13eaea92), + TOBN(0xf2d9e242, 0x49e4fbf2), TOBN(0x94fdfd9b, 0xe384f8b7), + TOBN(0x65f56054, 0x63428c6b), TOBN(0x2f7205b2, 0x90b409a5), + TOBN(0xf778bb78, 0xff45ae11), TOBN(0xa13045be, 0xc5ee53b2), + TOBN(0xe00a14ff, 0x03ef77fe), TOBN(0x689cd59f, 0xffef8bef), + TOBN(0x3578f0ed, 0x1e9ade22), TOBN(0xe99f3ec0, 0x6268b6a8), + TOBN(0xa2057d91, 0xea1b3c3e), TOBN(0x2d1a7053, 0xb8823a4a), + TOBN(0xabbb336a, 0x2cca451e), TOBN(0xcd2466e3, 0x2218bb5d), + TOBN(0x3ac1f42f, 0xc8cb762d), TOBN(0x7e312aae, 0x7690211f), + TOBN(0xebb9bd73, 0x45d07450), TOBN(0x207c4b82, 0x46c2213f), + TOBN(0x99d425c1, 0x375913ec), TOBN(0x94e45e96, 0x67908220), + TOBN(0xc08f3087, 0xcd67dbf6), TOBN(0xa5670fbe, 0xc0887056), + TOBN(0x6717b64a, 0x66f5b8fc), TOBN(0xd5a56aea, 0x786fec28), + TOBN(0xa8c3f55f, 0xc0ff4952), TOBN(0xa77fefae, 0x457ac49b), + TOBN(0x29882d7c, 0x98379d44), TOBN(0xd000bdfb, 0x509edc8a), + TOBN(0xc6f95979, 0xe66fe464), TOBN(0x504a6115, 0xfa61bde0), + TOBN(0x56b3b871, 0xeffea31a), TOBN(0x2d3de26d, 0xf0c21a54), + TOBN(0x21dbff31, 0x834753bf), TOBN(0xe67ecf49, 0x69269d86), + TOBN(0x7a176952, 0x151fe690), TOBN(0x03515804, 0x7f2adb5f), + TOBN(0xee794b15, 0xd1b62a8d), TOBN(0xf004ceec, 0xaae454e6), + TOBN(0x0897ea7c, 0xf0386fac), TOBN(0x3b62ff12, 0xd1fca751), + TOBN(0x154181df, 0x1b7a04ec), TOBN(0x2008e04a, 0xfb5847ec), + TOBN(0xd147148e, 0x41dbd772), TOBN(0x2b419f73, 0x22942654), + TOBN(0x669f30d3, 0xe9c544f7), TOBN(0x52a2c223, 0xc8540149), + TOBN(0x5da9ee14, 0x634dfb02), TOBN(0x5f074ff0, 0xf47869f3), + TOBN(0x74ee878d, 0xa3933acc), TOBN(0xe6510651, 0x4fe35ed1), + TOBN(0xb3eb9482, 0xf1012e7a), TOBN(0x51013cc0, 0xa8a566ae), + TOBN(0xdd5e9243, 0x47c00d3b), TOBN(0x7fde089d, 0x946bb0e5), + TOBN(0x030754fe, 0xc731b4b3), TOBN(0x12a136a4, 0x99fda062), + TOBN(0x7c1064b8, 0x5a1a35bc), TOBN(0xbf1f5763, 0x446c84ef), + TOBN(0xed29a56d, 0xa16d4b34), TOBN(0x7fba9d09, 0xdca21c4f), + TOBN(0x66d7ac00, 0x6d8de486), TOBN(0x60061987, 0x73a2a5e1), + TOBN(0x8b400f86, 0x9da28ff0), TOBN(0x3133f708, 0x43c4599c), + TOBN(0x9911c9b8, 0xee28cb0d), TOBN(0xcd7e2874, 0x8e0af61d), + TOBN(0x5a85f0f2, 0x72ed91fc), TOBN(0x85214f31, 0x9cd4a373), + TOBN(0x881fe5be, 0x1925253c), TOBN(0xd8dc98e0, 0x91e8bc76), + TOBN(0x7120affe, 0x585cc3a2), TOBN(0x724952ed, 0x735bf97a), + TOBN(0x5581e7dc, 0x3eb34581), TOBN(0x5cbff4f2, 0xe52ee57d), + TOBN(0x8d320a0e, 0x87d8cc7b), TOBN(0x9beaa7f3, 0xf1d280d0), + TOBN(0x7a0b9571, 0x9beec704), TOBN(0x9126332e, 0x5b7f0057), + TOBN(0x01fbc1b4, 0x8ed3bd6d), TOBN(0x35bb2c12, 0xd945eb24), + TOBN(0x6404694e, 0x9a8ae255), TOBN(0xb6092eec, 0x8d6abfb3), + TOBN(0x4d76143f, 0xcc058865), TOBN(0x7b0a5af2, 0x6e249922), + TOBN(0x8aef9440, 0x6a50d353), TOBN(0xe11e4bcc, 0x64f0e07a), + TOBN(0x4472993a, 0xa14a90fa), TOBN(0x7706e20c, 0xba0c51d4), + TOBN(0xf403292f, 0x1532672d), TOBN(0x52573bfa, 0x21829382), + TOBN(0x6a7bb6a9, 0x3b5bdb83), TOBN(0x08da65c0, 0xa4a72318), + TOBN(0xc58d22aa, 0x63eb065f), TOBN(0x1717596c, 0x1b15d685), + TOBN(0x112df0d0, 0xb266d88b), TOBN(0xf688ae97, 0x5941945a), + TOBN(0x487386e3, 0x7c292cac), TOBN(0x42f3b50d, 0x57d6985c), + TOBN(0x6da4f998, 0x6a90fc34), TOBN(0xc8f257d3, 0x65ca8a8d), + TOBN(0xc2feabca, 0x6951f762), TOBN(0xe1bc81d0, 0x74c323ac), + TOBN(0x1bc68f67, 0x251a2a12), TOBN(0x10d86587, 0xbe8a70dc), + TOBN(0xd648af7f, 0xf0f84d2e), TOBN(0xf0aa9ebc, 0x6a43ac92), + TOBN(0x69e3be04, 0x27596893), TOBN(0xb6bb02a6, 0x45bf452b), + TOBN(0x0875c11a, 0xf4c698c8), TOBN(0x6652b5c7, 0xbece3794), + TOBN(0x7b3755fd, 0x4f5c0499), TOBN(0x6ea16558, 0xb5532b38), + TOBN(0xd1c69889, 0xa2e96ef7), TOBN(0x9c773c3a, 0x61ed8f48), + TOBN(0x2b653a40, 0x9b323abc), TOBN(0xe26605e1, 0xf0e1d791), + TOBN(0x45d41064, 0x4a87157a), TOBN(0x8f9a78b7, 0xcbbce616), + TOBN(0xcf1e44aa, 0xc407eddd), TOBN(0x81ddd1d8, 0xa35b964f), + TOBN(0x473e339e, 0xfd083999), TOBN(0x6c94bdde, 0x8e796802), + TOBN(0x5a304ada, 0x8545d185), TOBN(0x82ae44ea, 0x738bb8cb), + TOBN(0x628a35e3, 0xdf87e10e), TOBN(0xd3624f3d, 0xa15b9fe3), + TOBN(0xcc44209b, 0x14be4254), TOBN(0x7d0efcbc, 0xbdbc2ea5), + TOBN(0x1f603362, 0x04c37bbe), TOBN(0x21f363f5, 0x56a5852c), + TOBN(0xa1503d1c, 0xa8501550), TOBN(0x2251e0e1, 0xd8ab10bb), + TOBN(0xde129c96, 0x6961c51c), TOBN(0x1f7246a4, 0x81910f68), + TOBN(0x2eb744ee, 0x5f2591f2), TOBN(0x3c47d33f, 0x5e627157), + TOBN(0x4d6d62c9, 0x22f3bd68), TOBN(0x6120a64b, 0xcb8df856), + TOBN(0x3a9ac6c0, 0x7b5d07df), TOBN(0xa92b9558, 0x7ef39783), + TOBN(0xe128a134, 0xab3a9b4f), TOBN(0x41c18807, 0xb1252f05), + TOBN(0xfc7ed089, 0x80ba9b1c), TOBN(0xac8dc6de, 0xc532a9dd), + TOBN(0xbf829cef, 0x55246809), TOBN(0x101b784f, 0x5b4ee80f), + TOBN(0xc09945bb, 0xb6f11603), TOBN(0x57b09dbe, 0x41d2801e), + TOBN(0xfba5202f, 0xa97534a8), TOBN(0x7fd8ae5f, 0xc17b9614), + TOBN(0xa50ba666, 0x78308435), TOBN(0x9572f77c, 0xd3868c4d), + TOBN(0x0cef7bfd, 0x2dd7aab0), TOBN(0xe7958e08, 0x2c7c79ff), + TOBN(0x81262e42, 0x25346689), TOBN(0x716da290, 0xb07c7004), + TOBN(0x35f911ea, 0xb7950ee3), TOBN(0x6fd72969, 0x261d21b5), + TOBN(0x52389803, 0x08b640d3), TOBN(0x5b0026ee, 0x887f12a1), + TOBN(0x20e21660, 0x742e9311), TOBN(0x0ef6d541, 0x5ff77ff7), + TOBN(0x969127f0, 0xf9c41135), TOBN(0xf21d60c9, 0x68a64993), + TOBN(0x656e5d0c, 0xe541875c), TOBN(0xf1e0f84e, 0xa1d3c233), + TOBN(0x9bcca359, 0x06002d60), TOBN(0xbe2da60c, 0x06191552), + TOBN(0x5da8bbae, 0x61181ec3), TOBN(0x9f04b823, 0x65806f19), + TOBN(0xf1604a7d, 0xd4b79bb8), TOBN(0xaee806fb, 0x52c878c8), + TOBN(0x34144f11, 0x8d47b8e8), TOBN(0x72edf52b, 0x949f9054), + TOBN(0xebfca84e, 0x2127015a), TOBN(0x9051d0c0, 0x9cb7cef3), + TOBN(0x86e8fe58, 0x296deec8), TOBN(0x33b28188, 0x41010d74)}, + {TOBN(0x01079383, 0x171b445f), TOBN(0x9bcf21e3, 0x8131ad4c), + TOBN(0x8cdfe205, 0xc93987e8), TOBN(0xe63f4152, 0xc92e8c8f), + TOBN(0x729462a9, 0x30add43d), TOBN(0x62ebb143, 0xc980f05a), + TOBN(0x4f3954e5, 0x3b06e968), TOBN(0xfe1d75ad, 0x242cf6b1), + TOBN(0x5f95c6c7, 0xaf8685c8), TOBN(0xd4c1c8ce, 0x2f8f01aa), + TOBN(0xc44bbe32, 0x2574692a), TOBN(0xb8003478, 0xd4a4a068), + TOBN(0x7c8fc6e5, 0x2eca3cdb), TOBN(0xea1db16b, 0xec04d399), + TOBN(0xb05bc82e, 0x8f2bc5cf), TOBN(0x763d517f, 0xf44793d2), + TOBN(0x4451c1b8, 0x08bd98d0), TOBN(0x644b1cd4, 0x6575f240), + TOBN(0x6907eb33, 0x7375d270), TOBN(0x56c8bebd, 0xfa2286bd), + TOBN(0xc713d2ac, 0xc4632b46), TOBN(0x17da427a, 0xafd60242), + TOBN(0x313065b7, 0xc95c7546), TOBN(0xf8239898, 0xbf17a3de), + TOBN(0xf3b7963f, 0x4c830320), TOBN(0x842c7aa0, 0x903203e3), + TOBN(0xaf22ca0a, 0xe7327afb), TOBN(0x38e13092, 0x967609b6), + TOBN(0x73b8fb62, 0x757558f1), TOBN(0x3cc3e831, 0xf7eca8c1), + TOBN(0xe4174474, 0xf6331627), TOBN(0xa77989ca, 0xc3c40234), + TOBN(0xe5fd17a1, 0x44a081e0), TOBN(0xd797fb7d, 0xb70e296a), + TOBN(0x2b472b30, 0x481f719c), TOBN(0x0e632a98, 0xfe6f8c52), + TOBN(0x89ccd116, 0xc5f0c284), TOBN(0xf51088af, 0x2d987c62), + TOBN(0x2a2bccda, 0x4c2de6cf), TOBN(0x810f9efe, 0xf679f0f9), + TOBN(0xb0f394b9, 0x7ffe4b3e), TOBN(0x0b691d21, 0xe5fa5d21), + TOBN(0xb0bd7747, 0x9dfbbc75), TOBN(0xd2830fda, 0xfaf78b00), + TOBN(0xf78c249c, 0x52434f57), TOBN(0x4b1f7545, 0x98096dab), + TOBN(0x73bf6f94, 0x8ff8c0b3), TOBN(0x34aef03d, 0x454e134c), + TOBN(0xf8d151f4, 0xb7ac7ec5), TOBN(0xd6ceb95a, 0xe50da7d5), + TOBN(0xa1b492b0, 0xdc3a0eb8), TOBN(0x75157b69, 0xb3dd2863), + TOBN(0xe2c4c74e, 0xc5413d62), TOBN(0xbe329ff7, 0xbc5fc4c7), + TOBN(0x835a2aea, 0x60fa9dda), TOBN(0xf117f5ad, 0x7445cb87), + TOBN(0xae8317f4, 0xb0166f7a), TOBN(0xfbd3e3f7, 0xceec74e6), + TOBN(0xfdb516ac, 0xe0874bfd), TOBN(0x3d846019, 0xc681f3a3), + TOBN(0x0b12ee5c, 0x7c1620b0), TOBN(0xba68b4dd, 0x2b63c501), + TOBN(0xac03cd32, 0x6668c51e), TOBN(0x2a6279f7, 0x4e0bcb5b), + TOBN(0x17bd69b0, 0x6ae85c10), TOBN(0x72946979, 0x1dfdd3a6), + TOBN(0xd9a03268, 0x2c078bec), TOBN(0x41c6a658, 0xbfd68a52), + TOBN(0xcdea1024, 0x0e023900), TOBN(0xbaeec121, 0xb10d144d), + TOBN(0x5a600e74, 0x058ab8dc), TOBN(0x1333af21, 0xbb89ccdd), + TOBN(0xdf25eae0, 0x3aaba1f1), TOBN(0x2cada16e, 0x3b7144cf), + TOBN(0x657ee27d, 0x71ab98bc), TOBN(0x99088b4c, 0x7a6fc96e), + TOBN(0x05d5c0a0, 0x3549dbd4), TOBN(0x42cbdf8f, 0xf158c3ac), + TOBN(0x3fb6b3b0, 0x87edd685), TOBN(0x22071cf6, 0x86f064d0), + TOBN(0xd2d6721f, 0xff2811e5), TOBN(0xdb81b703, 0xfe7fae8c), + TOBN(0x3cfb74ef, 0xd3f1f7bb), TOBN(0x0cdbcd76, 0x16cdeb5d), + TOBN(0x4f39642a, 0x566a808c), TOBN(0x02b74454, 0x340064d6), + TOBN(0xfabbadca, 0x0528fa6f), TOBN(0xe4c3074c, 0xd3fc0bb6), + TOBN(0xb32cb8b0, 0xb796d219), TOBN(0xc3e95f4f, 0x34741dd9), + TOBN(0x87212125, 0x68edf6f5), TOBN(0x7a03aee4, 0xa2b9cb8e), + TOBN(0x0cd3c376, 0xf53a89aa), TOBN(0x0d8af9b1, 0x948a28dc), + TOBN(0xcf86a3f4, 0x902ab04f), TOBN(0x8aacb62a, 0x7f42002d), + TOBN(0x106985eb, 0xf62ffd52), TOBN(0xe670b54e, 0x5797bf10), + TOBN(0x4b405209, 0xc5e30aef), TOBN(0x12c97a20, 0x4365b5e9), + TOBN(0x104646ce, 0x1fe32093), TOBN(0x13cb4ff6, 0x3907a8c9), + TOBN(0x8b9f30d1, 0xd46e726b), TOBN(0xe1985e21, 0xaba0f499), + TOBN(0xc573dea9, 0x10a230cd), TOBN(0x24f46a93, 0xcd30f947), + TOBN(0xf2623fcf, 0xabe2010a), TOBN(0x3f278cb2, 0x73f00e4f), + TOBN(0xed55c67d, 0x50b920eb), TOBN(0xf1cb9a2d, 0x8e760571), + TOBN(0x7c50d109, 0x0895b709), TOBN(0x4207cf07, 0x190d4369), + TOBN(0x3b027e81, 0xc4127fe1), TOBN(0xa9f8b9ad, 0x3ae9c566), + TOBN(0x5ab10851, 0xacbfbba5), TOBN(0xa747d648, 0x569556f5), + TOBN(0xcc172b5c, 0x2ba97bf7), TOBN(0x15e0f77d, 0xbcfa3324), + TOBN(0xa345b797, 0x7686279d), TOBN(0x5a723480, 0xe38003d3), + TOBN(0xfd8e139f, 0x8f5fcda8), TOBN(0xf3e558c4, 0xbdee5bfd), + TOBN(0xd76cbaf4, 0xe33f9f77), TOBN(0x3a4c97a4, 0x71771969), + TOBN(0xda27e84b, 0xf6dce6a7), TOBN(0xff373d96, 0x13e6c2d1), + TOBN(0xf115193c, 0xd759a6e9), TOBN(0x3f9b7025, 0x63d2262c), + TOBN(0xd9764a31, 0x317cd062), TOBN(0x30779d8e, 0x199f8332), + TOBN(0xd8074106, 0x16b11b0b), TOBN(0x7917ab9f, 0x78aeaed8), + TOBN(0xb67a9cbe, 0x28fb1d8e), TOBN(0x2e313563, 0x136eda33), + TOBN(0x010b7069, 0xa371a86c), TOBN(0x44d90fa2, 0x6744e6b7), + TOBN(0x68190867, 0xd6b3e243), TOBN(0x9fe6cd9d, 0x59048c48), + TOBN(0xb900b028, 0x95731538), TOBN(0xa012062f, 0x32cae04f), + TOBN(0x8107c8bc, 0x9399d082), TOBN(0x47e8c54a, 0x41df12e2), + TOBN(0x14ba5117, 0xb6ef3f73), TOBN(0x22260bea, 0x81362f0b), + TOBN(0x90ea261e, 0x1a18cc20), TOBN(0x2192999f, 0x2321d636), + TOBN(0xef64d314, 0xe311b6a0), TOBN(0xd7401e4c, 0x3b54a1f5), + TOBN(0x19019983, 0x6fbca2ba), TOBN(0x46ad3293, 0x8fbffc4b), + TOBN(0xa142d3f6, 0x3786bf40), TOBN(0xeb5cbc26, 0xb67039fc), + TOBN(0x9cb0ae6c, 0x252bd479), TOBN(0x05e0f88a, 0x12b5848f), + TOBN(0x78f6d2b2, 0xa5c97663), TOBN(0x6f6e149b, 0xc162225c), + TOBN(0xe602235c, 0xde601a89), TOBN(0xd17bbe98, 0xf373be1f), + TOBN(0xcaf49a5b, 0xa8471827), TOBN(0x7e1a0a85, 0x18aaa116), + TOBN(0x6c833196, 0x270580c3), TOBN(0x1e233839, 0xf1c98a14), + TOBN(0x67b2f7b4, 0xae34e0a5), TOBN(0x47ac8745, 0xd8ce7289), + TOBN(0x2b74779a, 0x100dd467), TOBN(0x274a4337, 0x4ee50d09), + TOBN(0x603dcf13, 0x83608bc9), TOBN(0xcd9da6c3, 0xc89e8388), + TOBN(0x2660199f, 0x355116ac), TOBN(0xcc38bb59, 0xb6d18eed), + TOBN(0x3075f31f, 0x2f4bc071), TOBN(0x9774457f, 0x265dc57e), + TOBN(0x06a6a9c8, 0xc6db88bb), TOBN(0x6429d07f, 0x4ec98e04), + TOBN(0x8d05e57b, 0x05ecaa8b), TOBN(0x20f140b1, 0x7872ea7b), + TOBN(0xdf8c0f09, 0xca494693), TOBN(0x48d3a020, 0xf252e909), + TOBN(0x4c5c29af, 0x57b14b12), TOBN(0x7e6fa37d, 0xbf47ad1c), + TOBN(0x66e7b506, 0x49a0c938), TOBN(0xb72c0d48, 0x6be5f41f), + TOBN(0x6a6242b8, 0xb2359412), TOBN(0xcd35c774, 0x8e859480), + TOBN(0x12536fea, 0x87baa627), TOBN(0x58c1fec1, 0xf72aa680), + TOBN(0x6c29b637, 0x601e5dc9), TOBN(0x9e3c3c1c, 0xde9e01b9), + TOBN(0xefc8127b, 0x2bcfe0b0), TOBN(0x35107102, 0x2a12f50d), + TOBN(0x6ccd6cb1, 0x4879b397), TOBN(0xf792f804, 0xf8a82f21), + TOBN(0x509d4804, 0xa9b46402), TOBN(0xedddf85d, 0xc10f0850), + TOBN(0x928410dc, 0x4b6208aa), TOBN(0xf6229c46, 0x391012dc), + TOBN(0xc5a7c41e, 0x7727b9b6), TOBN(0x289e4e4b, 0xaa444842), + TOBN(0x049ba1d9, 0xe9a947ea), TOBN(0x44f9e47f, 0x83c8debc), + TOBN(0xfa77a1fe, 0x611f8b8e), TOBN(0xfd2e416a, 0xf518f427), + TOBN(0xc5fffa70, 0x114ebac3), TOBN(0xfe57c4e9, 0x5d89697b), + TOBN(0xfdd053ac, 0xb1aaf613), TOBN(0x31df210f, 0xea585a45), + TOBN(0x318cc10e, 0x24985034), TOBN(0x1a38efd1, 0x5f1d6130), + TOBN(0xbf86f237, 0x0b1e9e21), TOBN(0xb258514d, 0x1dbe88aa), + TOBN(0x1e38a588, 0x90c1baf9), TOBN(0x2936a01e, 0xbdb9b692), + TOBN(0xd576de98, 0x6dd5b20c), TOBN(0xb586bf71, 0x70f98ecf), + TOBN(0xcccf0f12, 0xc42d2fd7), TOBN(0x8717e61c, 0xfb35bd7b), + TOBN(0x8b1e5722, 0x35e6fc06), TOBN(0x3477728f, 0x0b3e13d5), + TOBN(0x150c294d, 0xaa8a7372), TOBN(0xc0291d43, 0x3bfa528a), + TOBN(0xc6c8bc67, 0xcec5a196), TOBN(0xdeeb31e4, 0x5c2e8a7c), + TOBN(0xba93e244, 0xfb6e1c51), TOBN(0xb9f8b71b, 0x2e28e156), + TOBN(0xce65a287, 0x968a2ab9), TOBN(0xe3c5ce69, 0x46bbcb1f), + TOBN(0xf8c835b9, 0xe7ae3f30), TOBN(0x16bbee26, 0xff72b82b), + TOBN(0x665e2017, 0xfd42cd22), TOBN(0x1e139970, 0xf8b1d2a0), + TOBN(0x125cda29, 0x79204932), TOBN(0x7aee94a5, 0x49c3bee5), + TOBN(0x68c70160, 0x89821a66), TOBN(0xf7c37678, 0x8f981669), + TOBN(0xd90829fc, 0x48cc3645), TOBN(0x346af049, 0xd70addfc), + TOBN(0x2057b232, 0x370bf29c), TOBN(0xf90c73ce, 0x42e650ee), + TOBN(0xe03386ea, 0xa126ab90), TOBN(0x0e266e7e, 0x975a087b), + TOBN(0x80578eb9, 0x0fca65d9), TOBN(0x7e2989ea, 0x16af45b8), + TOBN(0x7438212d, 0xcac75a4e), TOBN(0x38c7ca39, 0x4fef36b8), + TOBN(0x8650c494, 0xd402676a), TOBN(0x26ab5a66, 0xf72c7c48), + TOBN(0x4e6cb426, 0xce3a464e), TOBN(0xf8f99896, 0x2b72f841), + TOBN(0x8c318491, 0x1a335cc8), TOBN(0x563459ba, 0x6a5913e4), + TOBN(0x1b920d61, 0xc7b32919), TOBN(0x805ab8b6, 0xa02425ad), + TOBN(0x2ac512da, 0x8d006086), TOBN(0x6ca4846a, 0xbcf5c0fd), + TOBN(0xafea51d8, 0xac2138d7), TOBN(0xcb647545, 0x344cd443), + TOBN(0x0429ee8f, 0xbd7d9040), TOBN(0xee66a2de, 0x819b9c96), + TOBN(0x54f9ec25, 0xdea7d744), TOBN(0x2ffea642, 0x671721bb), + TOBN(0x4f19dbd1, 0x114344ea), TOBN(0x04304536, 0xfd0dbc8b), + TOBN(0x014b50aa, 0x29ec7f91), TOBN(0xb5fc22fe, 0xbb06014d), + TOBN(0x60d963a9, 0x1ee682e0), TOBN(0xdf48abc0, 0xfe85c727), + TOBN(0x0cadba13, 0x2e707c2d), TOBN(0xde608d3a, 0xa645aeff), + TOBN(0x05f1c28b, 0xedafd883), TOBN(0x3c362ede, 0xbd94de1f), + TOBN(0x8dd0629d, 0x13593e41), TOBN(0x0a5e736f, 0x766d6eaf), + TOBN(0xbfa92311, 0xf68cf9d1), TOBN(0xa4f9ef87, 0xc1797556), + TOBN(0x10d75a1f, 0x5601c209), TOBN(0x651c374c, 0x09b07361), + TOBN(0x49950b58, 0x88b5cead), TOBN(0x0ef00058, 0x6fa9dbaa), + TOBN(0xf51ddc26, 0x4e15f33a), TOBN(0x1f8b5ca6, 0x2ef46140), + TOBN(0x343ac0a3, 0xee9523f0), TOBN(0xbb75eab2, 0x975ea978), + TOBN(0x1bccf332, 0x107387f4), TOBN(0x790f9259, 0x9ab0062e), + TOBN(0xf1a363ad, 0x1e4f6a5f), TOBN(0x06e08b84, 0x62519a50), + TOBN(0x60915187, 0x7265f1ee), TOBN(0x6a80ca34, 0x93ae985e), + TOBN(0x81b29768, 0xaaba4864), TOBN(0xb13cabf2, 0x8d52a7d6), + TOBN(0xb5c36348, 0x8ead03f1), TOBN(0xc932ad95, 0x81c7c1c0), + TOBN(0x5452708e, 0xcae1e27b), TOBN(0x9dac4269, 0x1b0df648), + TOBN(0x233e3f0c, 0xdfcdb8bc), TOBN(0xe6ceccdf, 0xec540174), + TOBN(0xbd0d845e, 0x95081181), TOBN(0xcc8a7920, 0x699355d5), + TOBN(0x111c0f6d, 0xc3b375a8), TOBN(0xfd95bc6b, 0xfd51e0dc), + TOBN(0x4a106a26, 0x6888523a), TOBN(0x4d142bd6, 0xcb01a06d), + TOBN(0x79bfd289, 0xadb9b397), TOBN(0x0bdbfb94, 0xe9863914), + TOBN(0x29d8a229, 0x1660f6a6), TOBN(0x7f6abcd6, 0x551c042d), + TOBN(0x13039deb, 0x0ac3ffe8), TOBN(0xa01be628, 0xec8523fb), + TOBN(0x6ea34103, 0x0ca1c328), TOBN(0xc74114bd, 0xb903928e), + TOBN(0x8aa4ff4e, 0x9e9144b0), TOBN(0x7064091f, 0x7f9a4b17), + TOBN(0xa3f4f521, 0xe447f2c4), TOBN(0x81b8da7a, 0x604291f0), + TOBN(0xd680bc46, 0x7d5926de), TOBN(0x84f21fd5, 0x34a1202f), + TOBN(0x1d1e3181, 0x4e9df3d8), TOBN(0x1ca4861a, 0x39ab8d34), + TOBN(0x809ddeec, 0x5b19aa4a), TOBN(0x59f72f7e, 0x4d329366), + TOBN(0xa2f93f41, 0x386d5087), TOBN(0x40bf739c, 0xdd67d64f), + TOBN(0xb4494205, 0x66702158), TOBN(0xc33c65be, 0x73b1e178), + TOBN(0xcdcd657c, 0x38ca6153), TOBN(0x97f4519a, 0xdc791976), + TOBN(0xcc7c7f29, 0xcd6e1f39), TOBN(0x38de9cfb, 0x7e3c3932), + TOBN(0xe448eba3, 0x7b793f85), TOBN(0xe9f8dbf9, 0xf067e914), + TOBN(0xc0390266, 0xf114ae87), TOBN(0x39ed75a7, 0xcd6a8e2a), + TOBN(0xadb14848, 0x7ffba390), TOBN(0x67f8cb8b, 0x6af9bc09), + TOBN(0x322c3848, 0x9c7476db), TOBN(0xa320fecf, 0x52a538d6), + TOBN(0xe0493002, 0xb2aced2b), TOBN(0xdfba1809, 0x616bd430), + TOBN(0x531c4644, 0xc331be70), TOBN(0xbc04d32e, 0x90d2e450), + TOBN(0x1805a0d1, 0x0f9f142d), TOBN(0x2c44a0c5, 0x47ee5a23), + TOBN(0x31875a43, 0x3989b4e3), TOBN(0x6b1949fd, 0x0c063481), + TOBN(0x2dfb9e08, 0xbe0f4492), TOBN(0x3ff0da03, 0xe9d5e517), + TOBN(0x03dbe9a1, 0xf79466a8), TOBN(0x0b87bcd0, 0x15ea9932), + TOBN(0xeb64fc83, 0xab1f58ab), TOBN(0x6d9598da, 0x817edc8a), + TOBN(0x699cff66, 0x1d3b67e5), TOBN(0x645c0f29, 0x92635853), + TOBN(0x253cdd82, 0xeabaf21c), TOBN(0x82b9602a, 0x2241659e), + TOBN(0x2cae07ec, 0x2d9f7091), TOBN(0xbe4c720c, 0x8b48cd9b), + TOBN(0x6ce5bc03, 0x6f08d6c9), TOBN(0x36e8a997, 0xaf10bf40), + TOBN(0x83422d21, 0x3e10ff12), TOBN(0x7b26d3eb, 0xbcc12494), + TOBN(0xb240d2d0, 0xc9469ad6), TOBN(0xc4a11b4d, 0x30afa05b), + TOBN(0x4b604ace, 0xdd6ba286), TOBN(0x18486600, 0x3ee2864c), + TOBN(0x5869d6ba, 0x8d9ce5be), TOBN(0x0d8f68c5, 0xff4bfb0d), + TOBN(0xb69f210b, 0x5700cf73), TOBN(0x61f6653a, 0x6d37c135), + TOBN(0xff3d432b, 0x5aff5a48), TOBN(0x0d81c4b9, 0x72ba3a69), + TOBN(0xee879ae9, 0xfa1899ef), TOBN(0xbac7e2a0, 0x2d6acafd), + TOBN(0xd6d93f6c, 0x1c664399), TOBN(0x4c288de1, 0x5bcb135d), + TOBN(0x83031dab, 0x9dab7cbf), TOBN(0xfe23feb0, 0x3abbf5f0), + TOBN(0x9f1b2466, 0xcdedca85), TOBN(0x140bb710, 0x1a09538c), + TOBN(0xac8ae851, 0x5e11115d), TOBN(0x0d63ff67, 0x6f03f59e), + TOBN(0x755e5551, 0x7d234afb), TOBN(0x61c2db4e, 0x7e208fc1), + TOBN(0xaa9859ce, 0xf28a4b5d), TOBN(0xbdd6d4fc, 0x34af030f), + TOBN(0xd1c4a26d, 0x3be01cb1), TOBN(0x9ba14ffc, 0x243aa07c), + TOBN(0xf95cd3a9, 0xb2503502), TOBN(0xe379bc06, 0x7d2a93ab), + TOBN(0x3efc18e9, 0xd4ca8d68), TOBN(0x083558ec, 0x80bb412a), + TOBN(0xd903b940, 0x9645a968), TOBN(0xa499f0b6, 0x9ba6054f), + TOBN(0x208b573c, 0xb8349abe), TOBN(0x3baab3e5, 0x30b4fc1c), + TOBN(0x87e978ba, 0xcb524990), TOBN(0x3524194e, 0xccdf0e80), + TOBN(0x62711725, 0x7d4bcc42), TOBN(0xe90a3d9b, 0xb90109ba), + TOBN(0x3b1bdd57, 0x1323e1e0), TOBN(0xb78e9bd5, 0x5eae1599), + TOBN(0x0794b746, 0x9e03d278), TOBN(0x80178605, 0xd70e6297), + TOBN(0x171792f8, 0x99c97855), TOBN(0x11b393ee, 0xf5a86b5c), + TOBN(0x48ef6582, 0xd8884f27), TOBN(0xbd44737a, 0xbf19ba5f), + TOBN(0x8698de4c, 0xa42062c6), TOBN(0x8975eb80, 0x61ce9c54), + TOBN(0xd50e57c7, 0xd7fe71f3), TOBN(0x15342190, 0xbc97ce38), + TOBN(0x51bda2de, 0x4df07b63), TOBN(0xba12aeae, 0x200eb87d), + TOBN(0xabe135d2, 0xa9b4f8f6), TOBN(0x04619d65, 0xfad6d99c), + TOBN(0x4a6683a7, 0x7994937c), TOBN(0x7a778c8b, 0x6f94f09a), + TOBN(0x8c508623, 0x20a71b89), TOBN(0x241a2aed, 0x1c229165), + TOBN(0x352be595, 0xaaf83a99), TOBN(0x9fbfee7f, 0x1562bac8), + TOBN(0xeaf658b9, 0x5c4017e3), TOBN(0x1dc7f9e0, 0x15120b86), + TOBN(0xd84f13dd, 0x4c034d6f), TOBN(0x283dd737, 0xeaea3038), + TOBN(0x197f2609, 0xcd85d6a2), TOBN(0x6ebbc345, 0xfae60177), + TOBN(0xb80f031b, 0x4e12fede), TOBN(0xde55d0c2, 0x07a2186b), + TOBN(0x1fb3e37f, 0x24dcdd5a), TOBN(0x8d602da5, 0x7ed191fb), + TOBN(0x108fb056, 0x76023e0d), TOBN(0x70178c71, 0x459c20c0), + TOBN(0xfad5a386, 0x3fe54cf0), TOBN(0xa4a3ec4f, 0x02bbb475), + TOBN(0x1aa5ec20, 0x919d94d7), TOBN(0x5d3b63b5, 0xa81e4ab3), + TOBN(0x7fa733d8, 0x5ad3d2af), TOBN(0xfbc586dd, 0xd1ac7a37), + TOBN(0x282925de, 0x40779614), TOBN(0xfe0ffffb, 0xe74a242a), + TOBN(0x3f39e67f, 0x906151e5), TOBN(0xcea27f5f, 0x55e10649), + TOBN(0xdca1d4e1, 0xc17cf7b7), TOBN(0x0c326d12, 0x2fe2362d), + TOBN(0x05f7ac33, 0x7dd35df3), TOBN(0x0c3b7639, 0xc396dbdf), + TOBN(0x0912f5ac, 0x03b7db1c), TOBN(0x9dea4b70, 0x5c9ed4a9), + TOBN(0x475e6e53, 0xaae3f639), TOBN(0xfaba0e7c, 0xfc278bac), + TOBN(0x16f9e221, 0x9490375f), TOBN(0xaebf9746, 0xa5a7ed0a), + TOBN(0x45f9af3f, 0xf41ad5d6), TOBN(0x03c4623c, 0xb2e99224), + TOBN(0x82c5bb5c, 0xb3cf56aa), TOBN(0x64311819, 0x34567ed3), + TOBN(0xec57f211, 0x8be489ac), TOBN(0x2821895d, 0xb9a1104b), + TOBN(0x610dc875, 0x6064e007), TOBN(0x8e526f3f, 0x5b20d0fe), + TOBN(0x6e71ca77, 0x5b645aee), TOBN(0x3d1dcb9f, 0x800e10ff), + TOBN(0x36b51162, 0x189cf6de), TOBN(0x2c5a3e30, 0x6bb17353), + TOBN(0xc186cd3e, 0x2a6c6fbf), TOBN(0xa74516fa, 0x4bf97906), + TOBN(0x5b4b8f4b, 0x279d6901), TOBN(0x0c4e57b4, 0x2b573743), + TOBN(0x75fdb229, 0xb6e386b6), TOBN(0xb46793fd, 0x99deac27), + TOBN(0xeeec47ea, 0xcf712629), TOBN(0xe965f3c4, 0xcbc3b2dd), + TOBN(0x8dd1fb83, 0x425c6559), TOBN(0x7fc00ee6, 0x0af06fda), + TOBN(0xe98c9225, 0x33d956df), TOBN(0x0f1ef335, 0x4fbdc8a2), + TOBN(0x2abb5145, 0xb79b8ea2), TOBN(0x40fd2945, 0xbdbff288), + TOBN(0x6a814ac4, 0xd7185db7), TOBN(0xc4329d6f, 0xc084609a), + TOBN(0xc9ba7b52, 0xed1be45d), TOBN(0x891dd20d, 0xe4cd2c74), + TOBN(0x5a4d4a7f, 0x824139b1), TOBN(0x66c17716, 0xb873c710), + TOBN(0x5e5bc141, 0x2843c4e0), TOBN(0xd5ac4817, 0xb97eb5bf), + TOBN(0xc0f8af54, 0x450c95c7), TOBN(0xc91b3fa0, 0x318406c5), + TOBN(0x360c340a, 0xab9d97f8), TOBN(0xfb57bd07, 0x90a2d611), + TOBN(0x4339ae3c, 0xa6a6f7e5), TOBN(0x9c1fcd2a, 0x2feb8a10), + TOBN(0x972bcca9, 0xc7ea7432), TOBN(0x1b0b924c, 0x308076f6), + TOBN(0x80b2814a, 0x2a5b4ca5), TOBN(0x2f78f55b, 0x61ef3b29), + TOBN(0xf838744a, 0xc18a414f), TOBN(0xc611eaae, 0x903d0a86), + TOBN(0x94dabc16, 0x2a453f55), TOBN(0xe6f2e3da, 0x14efb279), + TOBN(0x5b7a6017, 0x9320dc3c), TOBN(0x692e382f, 0x8df6b5a4), + TOBN(0x3f5e15e0, 0x2d40fa90), TOBN(0xc87883ae, 0x643dd318), + TOBN(0x511053e4, 0x53544774), TOBN(0x834d0ecc, 0x3adba2bc), + TOBN(0x4215d7f7, 0xbae371f5), TOBN(0xfcfd57bf, 0x6c8663bc), + TOBN(0xded2383d, 0xd6901b1d), TOBN(0x3b49fbb4, 0xb5587dc3), + TOBN(0xfd44a08d, 0x07625f62), TOBN(0x3ee4d65b, 0x9de9b762)}, + {TOBN(0x64e5137d, 0x0d63d1fa), TOBN(0x658fc052, 0x02a9d89f), + TOBN(0x48894874, 0x50436309), TOBN(0xe9ae30f8, 0xd598da61), + TOBN(0x2ed710d1, 0x818baf91), TOBN(0xe27e9e06, 0x8b6a0c20), + TOBN(0x1e28dcfb, 0x1c1a6b44), TOBN(0x883acb64, 0xd6ac57dc), + TOBN(0x8735728d, 0xc2c6ff70), TOBN(0x79d6122f, 0xc5dc2235), + TOBN(0x23f5d003, 0x19e277f9), TOBN(0x7ee84e25, 0xdded8cc7), + TOBN(0x91a8afb0, 0x63cd880a), TOBN(0x3f3ea7c6, 0x3574af60), + TOBN(0x0cfcdc84, 0x02de7f42), TOBN(0x62d0792f, 0xb31aa152), + TOBN(0x8e1b4e43, 0x8a5807ce), TOBN(0xad283893, 0xe4109a7e), + TOBN(0xc30cc9cb, 0xafd59dda), TOBN(0xf65f36c6, 0x3d8d8093), + TOBN(0xdf31469e, 0xa60d32b2), TOBN(0xee93df4b, 0x3e8191c8), + TOBN(0x9c1017c5, 0x355bdeb5), TOBN(0xd2623185, 0x8616aa28), + TOBN(0xb02c83f9, 0xdec31a21), TOBN(0x988c8b23, 0x6ad9d573), + TOBN(0x53e983ae, 0xa57be365), TOBN(0xe968734d, 0x646f834e), + TOBN(0x9137ea8f, 0x5da6309b), TOBN(0x10f3a624, 0xc1f1ce16), + TOBN(0x782a9ea2, 0xca440921), TOBN(0xdf94739e, 0x5b46f1b5), + TOBN(0x9f9be006, 0xcce85c9b), TOBN(0x360e70d6, 0xa4c7c2d3), + TOBN(0x2cd5beea, 0xaefa1e60), TOBN(0x64cf63c0, 0x8c3d2b6d), + TOBN(0xfb107fa3, 0xe1cf6f90), TOBN(0xb7e937c6, 0xd5e044e6), + TOBN(0x74e8ca78, 0xce34db9f), TOBN(0x4f8b36c1, 0x3e210bd0), + TOBN(0x1df165a4, 0x34a35ea8), TOBN(0x3418e0f7, 0x4d4412f6), + TOBN(0x5af1f8af, 0x518836c3), TOBN(0x42ceef4d, 0x130e1965), + TOBN(0x5560ca0b, 0x543a1957), TOBN(0xc33761e5, 0x886cb123), + TOBN(0x66624b1f, 0xfe98ed30), TOBN(0xf772f4bf, 0x1090997d), + TOBN(0xf4e540bb, 0x4885d410), TOBN(0x7287f810, 0x9ba5f8d7), + TOBN(0x22d0d865, 0xde98dfb1), TOBN(0x49ff51a1, 0xbcfbb8a3), + TOBN(0xb6b6fa53, 0x6bc3012e), TOBN(0x3d31fd72, 0x170d541d), + TOBN(0x8018724f, 0x4b0f4966), TOBN(0x79e7399f, 0x87dbde07), + TOBN(0x56f8410e, 0xf4f8b16a), TOBN(0x97241afe, 0xc47b266a), + TOBN(0x0a406b8e, 0x6d9c87c1), TOBN(0x803f3e02, 0xcd42ab1b), + TOBN(0x7f0309a8, 0x04dbec69), TOBN(0xa83b85f7, 0x3bbad05f), + TOBN(0xc6097273, 0xad8e197f), TOBN(0xc097440e, 0x5067adc1), + TOBN(0x730eafb6, 0x3524ff16), TOBN(0xd7f9b51e, 0x823fc6ce), + TOBN(0x27bd0d32, 0x443e4ac0), TOBN(0x40c59ad9, 0x4d66f217), + TOBN(0x6c33136f, 0x17c387a4), TOBN(0x5043b8d5, 0xeb86804d), + TOBN(0x74970312, 0x675a73c9), TOBN(0x838fdb31, 0xf16669b6), + TOBN(0xc507b6dd, 0x418e7ddd), TOBN(0x39888d93, 0x472f19d6), + TOBN(0x7eae26be, 0x0c27eb4d), TOBN(0x17b53ed3, 0xfbabb884), + TOBN(0xfc27021b, 0x2b01ae4f), TOBN(0x88462e87, 0xcf488682), + TOBN(0xbee096ec, 0x215e2d87), TOBN(0xeb2fea9a, 0xd242e29b), + TOBN(0x5d985b5f, 0xb821fc28), TOBN(0x89d2e197, 0xdc1e2ad2), + TOBN(0x55b566b8, 0x9030ba62), TOBN(0xe3fd41b5, 0x4f41b1c6), + TOBN(0xb738ac2e, 0xb9a96d61), TOBN(0x7f8567ca, 0x369443f4), + TOBN(0x8698622d, 0xf803a440), TOBN(0x2b586236, 0x8fe2f4dc), + TOBN(0xbbcc00c7, 0x56b95bce), TOBN(0x5ec03906, 0x616da680), + TOBN(0x79162ee6, 0x72214252), TOBN(0x43132b63, 0x86a892d2), + TOBN(0x4bdd3ff2, 0x2f3263bf), TOBN(0xd5b3733c, 0x9cd0a142), + TOBN(0x592eaa82, 0x44415ccb), TOBN(0x663e8924, 0x8d5474ea), + TOBN(0x8058a25e, 0x5236344e), TOBN(0x82e8df9d, 0xbda76ee6), + TOBN(0xdcf6efd8, 0x11cc3d22), TOBN(0x00089cda, 0x3b4ab529), + TOBN(0x91d3a071, 0xbd38a3db), TOBN(0x4ea97fc0, 0xef72b925), + TOBN(0x0c9fc15b, 0xea3edf75), TOBN(0x5a6297cd, 0xa4348ed3), + TOBN(0x0d38ab35, 0xce7c42d4), TOBN(0x9fd493ef, 0x82feab10), + TOBN(0x46056b6d, 0x82111b45), TOBN(0xda11dae1, 0x73efc5c3), + TOBN(0xdc740278, 0x5545a7fb), TOBN(0xbdb2601c, 0x40d507e6), + TOBN(0x121dfeeb, 0x7066fa58), TOBN(0x214369a8, 0x39ae8c2a), + TOBN(0x195709cb, 0x06e0956c), TOBN(0x4c9d254f, 0x010cd34b), + TOBN(0xf51e13f7, 0x0471a532), TOBN(0xe19d6791, 0x1e73054d), + TOBN(0xf702a628, 0xdb5c7be3), TOBN(0xc7141218, 0xb24dde05), + TOBN(0xdc18233c, 0xf29b2e2e), TOBN(0x3a6bd1e8, 0x85342dba), + TOBN(0x3f747fa0, 0xb311898c), TOBN(0xe2a272e4, 0xcd0eac65), + TOBN(0x4bba5851, 0xf914d0bc), TOBN(0x7a1a9660, 0xc4a43ee3), + TOBN(0xe5a367ce, 0xa1c8cde9), TOBN(0x9d958ba9, 0x7271abe3), + TOBN(0xf3ff7eb6, 0x3d1615cd), TOBN(0xa2280dce, 0xf5ae20b0), + TOBN(0x56dba5c1, 0xcf640147), TOBN(0xea5a2e3d, 0x5e83d118), + TOBN(0x04cd6b6d, 0xda24c511), TOBN(0x1c0f4671, 0xe854d214), + TOBN(0x91a6b7a9, 0x69565381), TOBN(0xdc966240, 0xdecf1f5b), + TOBN(0x1b22d21c, 0xfcf5d009), TOBN(0x2a05f641, 0x9021dbd5), + TOBN(0x8c0ed566, 0xd4312483), TOBN(0x5179a95d, 0x643e216f), + TOBN(0xcc185fec, 0x17044493), TOBN(0xb3063339, 0x54991a21), + TOBN(0xd801ecdb, 0x0081a726), TOBN(0x0149b0c6, 0x4fa89bbb), + TOBN(0xafe9065a, 0x4391b6b9), TOBN(0xedc92786, 0xd633f3a3), + TOBN(0xe408c24a, 0xae6a8e13), TOBN(0x85833fde, 0x9f3897ab), + TOBN(0x43800e7e, 0xd81a0715), TOBN(0xde08e346, 0xb44ffc5f), + TOBN(0x7094184c, 0xcdeff2e0), TOBN(0x49f9387b, 0x165eaed1), + TOBN(0x635d6129, 0x777c468a), TOBN(0x8c0dcfd1, 0x538c2dd8), + TOBN(0xd6d9d9e3, 0x7a6a308b), TOBN(0x62375830, 0x4c2767d3), + TOBN(0x874a8bc6, 0xf38cbeb6), TOBN(0xd94d3f1a, 0xccb6fd9e), + TOBN(0x92a9735b, 0xba21f248), TOBN(0x272ad0e5, 0x6cd1efb0), + TOBN(0x7437b69c, 0x05b03284), TOBN(0xe7f04702, 0x6948c225), + TOBN(0x8a56c04a, 0xcba2ecec), TOBN(0x0c181270, 0xe3a73e41), + TOBN(0x6cb34e9d, 0x03e93725), TOBN(0xf77c8713, 0x496521a9), + TOBN(0x94569183, 0xfa7f9f90), TOBN(0xf2e7aa4c, 0x8c9707ad), + TOBN(0xced2c9ba, 0x26c1c9a3), TOBN(0x9109fe96, 0x40197507), + TOBN(0x9ae868a9, 0xe9adfe1c), TOBN(0x3984403d, 0x314e39bb), + TOBN(0xb5875720, 0xf2fe378f), TOBN(0x33f901e0, 0xba44a628), + TOBN(0xea1125fe, 0x3652438c), TOBN(0xae9ec4e6, 0x9dd1f20b), + TOBN(0x1e740d9e, 0xbebf7fbd), TOBN(0x6dbd3ddc, 0x42dbe79c), + TOBN(0x62082aec, 0xedd36776), TOBN(0xf612c478, 0xe9859039), + TOBN(0xa493b201, 0x032f7065), TOBN(0xebd4d8f2, 0x4ff9b211), + TOBN(0x3f23a0aa, 0xaac4cb32), TOBN(0xea3aadb7, 0x15ed4005), + TOBN(0xacf17ea4, 0xafa27e63), TOBN(0x56125c1a, 0xc11fd66c), + TOBN(0x266344a4, 0x3794f8dc), TOBN(0xdcca923a, 0x483c5c36), + TOBN(0x2d6b6bbf, 0x3f9d10a0), TOBN(0xb320c5ca, 0x81d9bdf3), + TOBN(0x620e28ff, 0x47b50a95), TOBN(0x933e3b01, 0xcef03371), + TOBN(0xf081bf85, 0x99100153), TOBN(0x183be9a0, 0xc3a8c8d6), + TOBN(0x4e3ddc5a, 0xd6bbe24d), TOBN(0xc6c74630, 0x53843795), + TOBN(0x78193dd7, 0x65ec2d4c), TOBN(0xb8df26cc, 0xcd3c89b2), + TOBN(0x98dbe399, 0x5a483f8d), TOBN(0x72d8a957, 0x7dd3313a), + TOBN(0x65087294, 0xab0bd375), TOBN(0xfcd89248, 0x7c259d16), + TOBN(0x8a9443d7, 0x7613aa81), TOBN(0x80100800, 0x85fe6584), + TOBN(0x70fc4dbc, 0x7fb10288), TOBN(0xf58280d3, 0xe86beee8), + TOBN(0x14fdd82f, 0x7c978c38), TOBN(0xdf1204c1, 0x0de44d7b), + TOBN(0xa08a1c84, 0x4160252f), TOBN(0x591554ca, 0xc17646a5), + TOBN(0x214a37d6, 0xa05bd525), TOBN(0x48d5f09b, 0x07957b3c), + TOBN(0x0247cdcb, 0xd7109bc9), TOBN(0x40f9e4bb, 0x30599ce7), + TOBN(0xc325fa03, 0xf46ad2ec), TOBN(0x00f766cf, 0xc3e3f9ee), + TOBN(0xab556668, 0xd43a4577), TOBN(0x68d30a61, 0x3ee03b93), + TOBN(0x7ddc81ea, 0x77b46a08), TOBN(0xcf5a6477, 0xc7480699), + TOBN(0x43a8cb34, 0x6633f683), TOBN(0x1b867e6b, 0x92363c60), + TOBN(0x43921114, 0x1f60558e), TOBN(0xcdbcdd63, 0x2f41450e), + TOBN(0x7fc04601, 0xcc630e8b), TOBN(0xea7c66d5, 0x97038b43), + TOBN(0x7259b8a5, 0x04e99fd8), TOBN(0x98a8dd12, 0x4785549a), + TOBN(0x0e459a7c, 0x840552e1), TOBN(0xcdfcf4d0, 0x4bb0909e), + TOBN(0x34a86db2, 0x53758da7), TOBN(0xe643bb83, 0xeac997e1), + TOBN(0x96400bd7, 0x530c5b7e), TOBN(0x9f97af87, 0xb41c8b52), + TOBN(0x34fc8820, 0xfbeee3f9), TOBN(0x93e53490, 0x49091afd), + TOBN(0x764b9be5, 0x9a31f35c), TOBN(0x71f37864, 0x57e3d924), + TOBN(0x02fb34e0, 0x943aa75e), TOBN(0xa18c9c58, 0xab8ff6e4), + TOBN(0x080f31b1, 0x33cf0d19), TOBN(0x5c9682db, 0x083518a7), + TOBN(0x873d4ca6, 0xb709c3de), TOBN(0x64a84262, 0x3575b8f0), + TOBN(0x6275da1f, 0x020154bb), TOBN(0x97678caa, 0xd17cf1ab), + TOBN(0x8779795f, 0x951a95c3), TOBN(0xdd35b163, 0x50fccc08), + TOBN(0x32709627, 0x33d8f031), TOBN(0x3c5ab10a, 0x498dd85c), + TOBN(0xb6c185c3, 0x41dca566), TOBN(0x7de7feda, 0xd8622aa3), + TOBN(0x99e84d92, 0x901b6dfb), TOBN(0x30a02b0e, 0x7c4ad288), + TOBN(0xc7c81daa, 0x2fd3cf36), TOBN(0xd1319547, 0xdf89e59f), + TOBN(0xb2be8184, 0xcd496733), TOBN(0xd5f449eb, 0x93d3412b), + TOBN(0x7ea41b1b, 0x25fe531d), TOBN(0xf9797432, 0x6a1d5646), + TOBN(0x86067f72, 0x2bde501a), TOBN(0xf91481c0, 0x0c85e89c), + TOBN(0xca8ee465, 0xf8b05bc6), TOBN(0x1844e1cf, 0x02e83cda), + TOBN(0xca82114a, 0xb4dbe33b), TOBN(0x0f9f8769, 0x4eabfde2), + TOBN(0x4936b1c0, 0x38b27fe2), TOBN(0x63b6359b, 0xaba402df), + TOBN(0x40c0ea2f, 0x656bdbab), TOBN(0x9c992a89, 0x6580c39c), + TOBN(0x600e8f15, 0x2a60aed1), TOBN(0xeb089ca4, 0xe0bf49df), + TOBN(0x9c233d7d, 0x2d42d99a), TOBN(0x648d3f95, 0x4c6bc2fa), + TOBN(0xdcc383a8, 0xe1add3f3), TOBN(0xf42c0c6a, 0x4f64a348), + TOBN(0x2abd176f, 0x0030dbdb), TOBN(0x4de501a3, 0x7d6c215e), + TOBN(0x4a107c1f, 0x4b9a64bc), TOBN(0xa77f0ad3, 0x2496cd59), + TOBN(0xfb78ac62, 0x7688dffb), TOBN(0x7025a2ca, 0x67937d8e), + TOBN(0xfde8b2d1, 0xd1a8f4e7), TOBN(0xf5b3da47, 0x7354927c), + TOBN(0xe48606a3, 0xd9205735), TOBN(0xac477cc6, 0xe177b917), + TOBN(0xfb1f73d2, 0xa883239a), TOBN(0xe12572f6, 0xcc8b8357), + TOBN(0x9d355e9c, 0xfb1f4f86), TOBN(0x89b795f8, 0xd9f3ec6e), + TOBN(0x27be56f1, 0xb54398dc), TOBN(0x1890efd7, 0x3fedeed5), + TOBN(0x62f77f1f, 0x9c6d0140), TOBN(0x7ef0e314, 0x596f0ee4), + TOBN(0x50ca6631, 0xcc61dab3), TOBN(0x4a39801d, 0xf4866e4f), + TOBN(0x66c8d032, 0xae363b39), TOBN(0x22c591e5, 0x2ead66aa), + TOBN(0x954ba308, 0xde02a53e), TOBN(0x2a6c060f, 0xd389f357), + TOBN(0xe6cfcde8, 0xfbf40b66), TOBN(0x8e02fc56, 0xc6340ce1), + TOBN(0xe4957795, 0x73adb4ba), TOBN(0x7b86122c, 0xa7b03805), + TOBN(0x63f83512, 0x0c8e6fa6), TOBN(0x83660ea0, 0x057d7804), + TOBN(0xbad79105, 0x21ba473c), TOBN(0xb6c50bee, 0xded5389d), + TOBN(0xee2caf4d, 0xaa7c9bc0), TOBN(0xd97b8de4, 0x8c4e98a7), + TOBN(0xa9f63e70, 0xab3bbddb), TOBN(0x3898aabf, 0x2597815a), + TOBN(0x7659af89, 0xac15b3d9), TOBN(0xedf7725b, 0x703ce784), + TOBN(0x25470fab, 0xe085116b), TOBN(0x04a43375, 0x87285310), + TOBN(0x4e39187e, 0xe2bfd52f), TOBN(0x36166b44, 0x7d9ebc74), + TOBN(0x92ad433c, 0xfd4b322c), TOBN(0x726aa817, 0xba79ab51), + TOBN(0xf96eacd8, 0xc1db15eb), TOBN(0xfaf71e91, 0x0476be63), + TOBN(0xdd69a640, 0x641fad98), TOBN(0xb7995918, 0x29622559), + TOBN(0x03c6daa5, 0xde4199dc), TOBN(0x92cadc97, 0xad545eb4), + TOBN(0x1028238b, 0x256534e4), TOBN(0x73e80ce6, 0x8595409a), + TOBN(0x690d4c66, 0xd05dc59b), TOBN(0xc95f7b8f, 0x981dee80), + TOBN(0xf4337014, 0xd856ac25), TOBN(0x441bd9dd, 0xac524dca), + TOBN(0x640b3d85, 0x5f0499f5), TOBN(0x39cf84a9, 0xd5fda182), + TOBN(0x04e7b055, 0xb2aa95a0), TOBN(0x29e33f0a, 0x0ddf1860), + TOBN(0x082e74b5, 0x423f6b43), TOBN(0x217edeb9, 0x0aaa2b0f), + TOBN(0x58b83f35, 0x83cbea55), TOBN(0xc485ee4d, 0xbc185d70), + TOBN(0x833ff03b, 0x1e5f6992), TOBN(0xb5b9b9cc, 0xcf0c0dd5), + TOBN(0x7caaee8e, 0x4e9e8a50), TOBN(0x462e907b, 0x6269dafd), + TOBN(0x6ed5cee9, 0xfbe791c6), TOBN(0x68ca3259, 0xed430790), + TOBN(0x2b72bdf2, 0x13b5ba88), TOBN(0x60294c8a, 0x35ef0ac4), + TOBN(0x9c3230ed, 0x19b99b08), TOBN(0x560fff17, 0x6c2589aa), + TOBN(0x552b8487, 0xd6770374), TOBN(0xa373202d, 0x9a56f685), + TOBN(0xd3e7f907, 0x45f175d9), TOBN(0x3c2f315f, 0xd080d810), + TOBN(0x1130e9dd, 0x7b9520e8), TOBN(0xc078f9e2, 0x0af037b5), + TOBN(0x38cd2ec7, 0x1e9c104c), TOBN(0x0f684368, 0xc472fe92), + TOBN(0xd3f1b5ed, 0x6247e7ef), TOBN(0xb32d33a9, 0x396dfe21), + TOBN(0x46f59cf4, 0x4a9aa2c2), TOBN(0x69cd5168, 0xff0f7e41), + TOBN(0x3f59da0f, 0x4b3234da), TOBN(0xcf0b0235, 0xb4579ebe), + TOBN(0x6d1cbb25, 0x6d2476c7), TOBN(0x4f0837e6, 0x9dc30f08), + TOBN(0x9a4075bb, 0x906f6e98), TOBN(0x253bb434, 0xc761e7d1), + TOBN(0xde2e645f, 0x6e73af10), TOBN(0xb89a4060, 0x0c5f131c), + TOBN(0xd12840c5, 0xb8cc037f), TOBN(0x3d093a5b, 0x7405bb47), + TOBN(0x6202c253, 0x206348b8), TOBN(0xbf5d57fc, 0xc55a3ca7), + TOBN(0x89f6c90c, 0x8c3bef48), TOBN(0x23ac7623, 0x5a0a960a), + TOBN(0xdfbd3d6b, 0x552b42ab), TOBN(0x3ef22458, 0x132061f6), + TOBN(0xd74e9bda, 0xc97e6516), TOBN(0x88779360, 0xc230f49e), + TOBN(0xa6ec1de3, 0x1e74ea49), TOBN(0x581dcee5, 0x3fb645a2), + TOBN(0xbaef2391, 0x8f483f14), TOBN(0x6d2dddfc, 0xd137d13b), + TOBN(0x54cde50e, 0xd2743a42), TOBN(0x89a34fc5, 0xe4d97e67), + TOBN(0x13f1f5b3, 0x12e08ce5), TOBN(0xa80540b8, 0xa7f0b2ca), + TOBN(0x854bcf77, 0x01982805), TOBN(0xb8653ffd, 0x233bea04), + TOBN(0x8e7b8787, 0x02b0b4c9), TOBN(0x2675261f, 0x9acb170a), + TOBN(0x061a9d90, 0x930c14e5), TOBN(0xb59b30e0, 0xdef0abea), + TOBN(0x1dc19ea6, 0x0200ec7d), TOBN(0xb6f4a3f9, 0x0bce132b), + TOBN(0xb8d5de90, 0xf13e27e0), TOBN(0xbaee5ef0, 0x1fade16f), + TOBN(0x6f406aaa, 0xe4c6cf38), TOBN(0xab4cfe06, 0xd1369815), + TOBN(0x0dcffe87, 0xefd550c6), TOBN(0x9d4f59c7, 0x75ff7d39), + TOBN(0xb02553b1, 0x51deb6ad), TOBN(0x812399a4, 0xb1877749), + TOBN(0xce90f71f, 0xca6006e1), TOBN(0xc32363a6, 0xb02b6e77), + TOBN(0x02284fbe, 0xdc36c64d), TOBN(0x86c81e31, 0xa7e1ae61), + TOBN(0x2576c7e5, 0xb909d94a), TOBN(0x8b6f7d02, 0x818b2bb0), + TOBN(0xeca3ed07, 0x56faa38a), TOBN(0xa3790e6c, 0x9305bb54), + TOBN(0xd784eeda, 0x7bc73061), TOBN(0xbd56d369, 0x6dd50614), + TOBN(0xd6575949, 0x229a8aa9), TOBN(0xdcca8f47, 0x4595ec28), + TOBN(0x814305c1, 0x06ab4fe6), TOBN(0xc8c39768, 0x24f43f16), + TOBN(0xe2a45f36, 0x523f2b36), TOBN(0x995c6493, 0x920d93bb), + TOBN(0xf8afdab7, 0x90f1632b), TOBN(0x79ebbecd, 0x1c295954), + TOBN(0xc7bb3ddb, 0x79592f48), TOBN(0x67216a7b, 0x5f88e998), + TOBN(0xd91f098b, 0xbc01193e), TOBN(0xf7d928a5, 0xb1db83fc), + TOBN(0x55e38417, 0xe991f600), TOBN(0x2a91113e, 0x2981a934), + TOBN(0xcbc9d648, 0x06b13bde), TOBN(0xb011b6ac, 0x0755ff44), + TOBN(0x6f4cb518, 0x045ec613), TOBN(0x522d2d31, 0xc2f5930a), + TOBN(0x5acae1af, 0x382e65de), TOBN(0x57643067, 0x27bc966f), + TOBN(0x5e12705d, 0x1c7193f0), TOBN(0xf0f32f47, 0x3be8858e), + TOBN(0x785c3d7d, 0x96c6dfc7), TOBN(0xd75b4a20, 0xbf31795d), + TOBN(0x91acf17b, 0x342659d4), TOBN(0xe596ea34, 0x44f0378f), + TOBN(0x4515708f, 0xce52129d), TOBN(0x17387e1e, 0x79f2f585), + TOBN(0x72cfd2e9, 0x49dee168), TOBN(0x1ae05223, 0x3e2af239), + TOBN(0x009e75be, 0x1d94066a), TOBN(0x6cca31c7, 0x38abf413), + TOBN(0xb50bd61d, 0x9bc49908), TOBN(0x4a9b4a8c, 0xf5e2bc1e), + TOBN(0xeb6cc5f7, 0x946f83ac), TOBN(0x27da93fc, 0xebffab28), + TOBN(0xea314c96, 0x4821c8c5), TOBN(0x8de49ded, 0xa83c15f4), + TOBN(0x7a64cf20, 0x7af33004), TOBN(0x45f1bfeb, 0xc9627e10), + TOBN(0x878b0626, 0x54b9df60), TOBN(0x5e4fdc3c, 0xa95c0b33), + TOBN(0xe54a37ca, 0xc2035d8e), TOBN(0x9087cda9, 0x80f20b8c), + TOBN(0x36f61c23, 0x8319ade4), TOBN(0x766f287a, 0xde8cfdf8), + TOBN(0x48821948, 0x346f3705), TOBN(0x49a7b853, 0x16e4f4a2), + TOBN(0xb9b3f8a7, 0x5cedadfd), TOBN(0x8f562815, 0x8db2a815), + TOBN(0xc0b7d554, 0x01f68f95), TOBN(0x12971e27, 0x688a208e), + TOBN(0xc9f8b696, 0xd0ff34fc), TOBN(0x20824de2, 0x1222718c), + TOBN(0x7213cf9f, 0x0c95284d), TOBN(0xe2ad741b, 0xdc158240), + TOBN(0x0ee3a6df, 0x54043ccf), TOBN(0x16ff479b, 0xd84412b3), + TOBN(0xf6c74ee0, 0xdfc98af0), TOBN(0xa78a169f, 0x52fcd2fb), + TOBN(0xd8ae8746, 0x99c930e9), TOBN(0x1d33e858, 0x49e117a5), + TOBN(0x7581fcb4, 0x6624759f), TOBN(0xde50644f, 0x5bedc01d), + TOBN(0xbeec5d00, 0xcaf3155e), TOBN(0x672d66ac, 0xbc73e75f), + TOBN(0x86b9d8c6, 0x270b01db), TOBN(0xd249ef83, 0x50f55b79), + TOBN(0x6131d6d4, 0x73978fe3), TOBN(0xcc4e4542, 0x754b00a1), + TOBN(0x4e05df05, 0x57dfcfe9), TOBN(0x94b29cdd, 0x51ef6bf0), + TOBN(0xe4530cff, 0x9bc7edf2), TOBN(0x8ac236fd, 0xd3da65f3), + TOBN(0x0faf7d5f, 0xc8eb0b48), TOBN(0x4d2de14c, 0x660eb039), + TOBN(0xc006bba7, 0x60430e54), TOBN(0x10a2d0d6, 0xda3289ab), + TOBN(0x9c037a5d, 0xd7979c59), TOBN(0x04d1f3d3, 0xa116d944), + TOBN(0x9ff22473, 0x8a0983cd), TOBN(0x28e25b38, 0xc883cabb), + TOBN(0xe968dba5, 0x47a58995), TOBN(0x2c80b505, 0x774eebdf), + TOBN(0xee763b71, 0x4a953beb), TOBN(0x502e223f, 0x1642e7f6), + TOBN(0x6fe4b641, 0x61d5e722), TOBN(0x9d37c5b0, 0xdbef5316), + TOBN(0x0115ed70, 0xf8330bc7), TOBN(0x139850e6, 0x75a72789), + TOBN(0x27d7faec, 0xffceccc2), TOBN(0x3016a860, 0x4fd9f7f6), + TOBN(0xc492ec64, 0x4cd8f64c), TOBN(0x58a2d790, 0x279d7b51), + TOBN(0x0ced1fc5, 0x1fc75256), TOBN(0x3e658aed, 0x8f433017), + TOBN(0x0b61942e, 0x05da59eb), TOBN(0xba3d60a3, 0x0ddc3722), + TOBN(0x7c311cd1, 0x742e7f87), TOBN(0x6473ffee, 0xf6b01b6e)}, + {TOBN(0x8303604f, 0x692ac542), TOBN(0xf079ffe1, 0x227b91d3), + TOBN(0x19f63e63, 0x15aaf9bd), TOBN(0xf99ee565, 0xf1f344fb), + TOBN(0x8a1d661f, 0xd6219199), TOBN(0x8c883bc6, 0xd48ce41c), + TOBN(0x1065118f, 0x3c74d904), TOBN(0x713889ee, 0x0faf8b1b), + TOBN(0x972b3f8f, 0x81a1b3be), TOBN(0x4f3ce145, 0xce2764a0), + TOBN(0xe2d0f1cc, 0x28c4f5f7), TOBN(0xdeee0c0d, 0xc7f3985b), + TOBN(0x7df4adc0, 0xd39e25c3), TOBN(0x40619820, 0xc467a080), + TOBN(0x440ebc93, 0x61cf5a58), TOBN(0x527729a6, 0x422ad600), + TOBN(0xca6c0937, 0xb1b76ba6), TOBN(0x1a2eab85, 0x4d2026dc), + TOBN(0xb1715e15, 0x19d9ae0a), TOBN(0xf1ad9199, 0xbac4a026), + TOBN(0x35b3dfb8, 0x07ea7b0e), TOBN(0xedf5496f, 0x3ed9eb89), + TOBN(0x8932e5ff, 0x2d6d08ab), TOBN(0xf314874e, 0x25bd2731), + TOBN(0xefb26a75, 0x3f73f449), TOBN(0x1d1c94f8, 0x8d44fc79), + TOBN(0x49f0fbc5, 0x3bc0dc4d), TOBN(0xb747ea0b, 0x3698a0d0), + TOBN(0x5218c3fe, 0x228d291e), TOBN(0x35b804b5, 0x43c129d6), + TOBN(0xfac859b8, 0xd1acc516), TOBN(0x6c10697d, 0x95d6e668), + TOBN(0xc38e438f, 0x0876fd4e), TOBN(0x45f0c307, 0x83d2f383), + TOBN(0x203cc2ec, 0xb10934cb), TOBN(0x6a8f2439, 0x2c9d46ee), + TOBN(0xf16b431b, 0x65ccde7b), TOBN(0x41e2cd18, 0x27e76a6f), + TOBN(0xb9c8cf8f, 0x4e3484d7), TOBN(0x64426efd, 0x8315244a), + TOBN(0x1c0a8e44, 0xfc94dea3), TOBN(0x34c8cdbf, 0xdad6a0b0), + TOBN(0x919c3840, 0x04113cef), TOBN(0xfd32fba4, 0x15490ffa), + TOBN(0x58d190f6, 0x795dcfb7), TOBN(0xfef01b03, 0x83588baf), + TOBN(0x9e6d1d63, 0xca1fc1c0), TOBN(0x53173f96, 0xf0a41ac9), + TOBN(0x2b1d402a, 0xba16f73b), TOBN(0x2fb31014, 0x8cf9b9fc), + TOBN(0x2d51e60e, 0x446ef7bf), TOBN(0xc731021b, 0xb91e1745), + TOBN(0x9d3b4724, 0x4fee99d4), TOBN(0x4bca48b6, 0xfac5c1ea), + TOBN(0x70f5f514, 0xbbea9af7), TOBN(0x751f55a5, 0x974c283a), + TOBN(0x6e30251a, 0xcb452fdb), TOBN(0x31ee6965, 0x50f30650), + TOBN(0xb0b3e508, 0x933548d9), TOBN(0xb8949a4f, 0xf4b0ef5b), + TOBN(0x208b8326, 0x3c88f3bd), TOBN(0xab147c30, 0xdb1d9989), + TOBN(0xed6515fd, 0x44d4df03), TOBN(0x17a12f75, 0xe72eb0c5), + TOBN(0x3b59796d, 0x36cf69db), TOBN(0x1219eee9, 0x56670c18), + TOBN(0xfe3341f7, 0x7a070d8e), TOBN(0x9b70130b, 0xa327f90c), + TOBN(0x36a32462, 0x0ae18e0e), TOBN(0x2021a623, 0x46c0a638), + TOBN(0x251b5817, 0xc62eb0d4), TOBN(0x87bfbcdf, 0x4c762293), + TOBN(0xf78ab505, 0xcdd61d64), TOBN(0x8c7a53fc, 0xc8c18857), + TOBN(0xa653ce6f, 0x16147515), TOBN(0x9c923aa5, 0xea7d52d5), + TOBN(0xc24709cb, 0x5c18871f), TOBN(0x7d53bec8, 0x73b3cc74), + TOBN(0x59264aff, 0xfdd1d4c4), TOBN(0x5555917e, 0x240da582), + TOBN(0xcae8bbda, 0x548f5a0e), TOBN(0x1910eaba, 0x3bbfbbe1), + TOBN(0xae579685, 0x7677afc3), TOBN(0x49ea61f1, 0x73ff0b5c), + TOBN(0x78655478, 0x4f7c3922), TOBN(0x95d337cd, 0x20c68eef), + TOBN(0x68f1e1e5, 0xdf779ab9), TOBN(0x14b491b0, 0xb5cf69a8), + TOBN(0x7a6cbbe0, 0x28e3fe89), TOBN(0xe7e1fee4, 0xc5aac0eb), + TOBN(0x7f47eda5, 0x697e5140), TOBN(0x4f450137, 0xb454921f), + TOBN(0xdb625f84, 0x95cd8185), TOBN(0x74be0ba1, 0xcdb2e583), + TOBN(0xaee4fd7c, 0xdd5e6de4), TOBN(0x4251437d, 0xe8101739), + TOBN(0x686d72a0, 0xac620366), TOBN(0x4be3fb9c, 0xb6d59344), + TOBN(0x6e8b44e7, 0xa1eb75b9), TOBN(0x84e39da3, 0x91a5c10c), + TOBN(0x37cc1490, 0xb38f0409), TOBN(0x02951943, 0x2c2ade82), + TOBN(0x9b688783, 0x1190a2d8), TOBN(0x25627d14, 0x231182ba), + TOBN(0x6eb550aa, 0x658a6d87), TOBN(0x1405aaa7, 0xcf9c7325), + TOBN(0xd147142e, 0x5c8748c9), TOBN(0x7f637e4f, 0x53ede0e0), + TOBN(0xf8ca2776, 0x14ffad2c), TOBN(0xe58fb1bd, 0xbafb6791), + TOBN(0x17158c23, 0xbf8f93fc), TOBN(0x7f15b373, 0x0a4a4655), + TOBN(0x39d4add2, 0xd842ca72), TOBN(0xa71e4391, 0x3ed96305), + TOBN(0x5bb09cbe, 0x6700be14), TOBN(0x68d69d54, 0xd8befcf6), + TOBN(0xa45f5367, 0x37183bcf), TOBN(0x7152b7bb, 0x3370dff7), + TOBN(0xcf887baa, 0xbf12525b), TOBN(0xe7ac7bdd, 0xd6d1e3cd), + TOBN(0x25914f78, 0x81fdad90), TOBN(0xcf638f56, 0x0d2cf6ab), + TOBN(0xb90bc03f, 0xcc054de5), TOBN(0x932811a7, 0x18b06350), + TOBN(0x2f00b330, 0x9bbd11ff), TOBN(0x76108a6f, 0xb4044974), + TOBN(0x801bb9e0, 0xa851d266), TOBN(0x0dd099be, 0xbf8990c1), + TOBN(0x58c5aaaa, 0xabe32986), TOBN(0x0fe9dd2a, 0x50d59c27), + TOBN(0x84951ff4, 0x8d307305), TOBN(0x6c23f829, 0x86529b78), + TOBN(0x50bb2218, 0x0b136a79), TOBN(0x7e2174de, 0x77a20996), + TOBN(0x6f00a4b9, 0xc0bb4da6), TOBN(0x89a25a17, 0xefdde8da), + TOBN(0xf728a27e, 0xc11ee01d), TOBN(0xf900553a, 0xe5f10dfb), + TOBN(0x189a83c8, 0x02ec893c), TOBN(0x3ca5bdc1, 0x23f66d77), + TOBN(0x98781537, 0x97eada9f), TOBN(0x59c50ab3, 0x10256230), + TOBN(0x346042d9, 0x323c69b3), TOBN(0x1b715a6d, 0x2c460449), + TOBN(0xa41dd476, 0x6ae06e0b), TOBN(0xcdd7888e, 0x9d42e25f), + TOBN(0x0f395f74, 0x56b25a20), TOBN(0xeadfe0ae, 0x8700e27e), + TOBN(0xb09d52a9, 0x69950093), TOBN(0x3525d9cb, 0x327f8d40), + TOBN(0xb8235a94, 0x67df886a), TOBN(0x77e4b0dd, 0x035faec2), + TOBN(0x115eb20a, 0x517d7061), TOBN(0x77fe3433, 0x6c2df683), + TOBN(0x6870ddc7, 0xcdc6fc67), TOBN(0xb1610588, 0x0b87de83), + TOBN(0x343584ca, 0xd9c4ddbe), TOBN(0xb3164f1c, 0x3d754be2), + TOBN(0x0731ed3a, 0xc1e6c894), TOBN(0x26327dec, 0x4f6b904c), + TOBN(0x9d49c6de, 0x97b5cd32), TOBN(0x40835dae, 0xb5eceecd), + TOBN(0xc66350ed, 0xd9ded7fe), TOBN(0x8aeebb5c, 0x7a678804), + TOBN(0x51d42fb7, 0x5b8ee9ec), TOBN(0xd7a17bdd, 0x8e3ca118), + TOBN(0x40d7511a, 0x2ef4400e), TOBN(0xc48990ac, 0x875a66f4), + TOBN(0x8de07d2a, 0x2199e347), TOBN(0xbee75556, 0x2a39e051), + TOBN(0x56918786, 0x916e51dc), TOBN(0xeb191313, 0x4a2d89ec), + TOBN(0x6679610d, 0x37d341ed), TOBN(0x434fbb41, 0x56d51c2b), + TOBN(0xe54b7ee7, 0xd7492dba), TOBN(0xaa33a79a, 0x59021493), + TOBN(0x49fc5054, 0xe4bd6d3d), TOBN(0x09540f04, 0x5ab551d0), + TOBN(0x8acc9085, 0x4942d3a6), TOBN(0x231af02f, 0x2d28323b), + TOBN(0x93458cac, 0x0992c163), TOBN(0x1fef8e71, 0x888e3bb4), + TOBN(0x27578da5, 0xbe8c268c), TOBN(0xcc8be792, 0xe805ec00), + TOBN(0x29267bae, 0xc61c3855), TOBN(0xebff429d, 0x58c1fd3b), + TOBN(0x22d886c0, 0x8c0b93b8), TOBN(0xca5e00b2, 0x2ddb8953), + TOBN(0xcf330117, 0xc3fed8b7), TOBN(0xd49ac6fa, 0x819c01f6), + TOBN(0x6ddaa6bd, 0x3c0fbd54), TOBN(0x91743068, 0x8049a2cf), + TOBN(0xd67f981e, 0xaff2ef81), TOBN(0xc3654d35, 0x2818ae80), + TOBN(0x81d05044, 0x1b2aa892), TOBN(0x2db067bf, 0x3d099328), + TOBN(0xe7c79e86, 0x703dcc97), TOBN(0xe66f9b37, 0xe133e215), + TOBN(0xcdf119a6, 0xe39a7a5c), TOBN(0x47c60de3, 0x876f1b61), + TOBN(0x6e405939, 0xd860f1b2), TOBN(0x3e9a1dbc, 0xf5ed4d4a), + TOBN(0x3f23619e, 0xc9b6bcbd), TOBN(0x5ee790cf, 0x734e4497), + TOBN(0xf0a834b1, 0x5bdaf9bb), TOBN(0x02cedda7, 0x4ca295f0), + TOBN(0x4619aa2b, 0xcb8e378c), TOBN(0xe5613244, 0xcc987ea4), + TOBN(0x0bc022cc, 0x76b23a50), TOBN(0x4a2793ad, 0x0a6c21ce), + TOBN(0x38328780, 0x89cac3f5), TOBN(0x29176f1b, 0xcba26d56), + TOBN(0x06296187, 0x4f6f59eb), TOBN(0x86e9bca9, 0x8bdc658e), + TOBN(0x2ca9c4d3, 0x57e30402), TOBN(0x5438b216, 0x516a09bb), + TOBN(0x0a6a063c, 0x7672765a), TOBN(0x37a3ce64, 0x0547b9bf), + TOBN(0x42c099c8, 0x98b1a633), TOBN(0xb5ab800d, 0x05ee6961), + TOBN(0xf1963f59, 0x11a5acd6), TOBN(0xbaee6157, 0x46201063), + TOBN(0x36d9a649, 0xa596210a), TOBN(0xaed04363, 0x1ba7138c), + TOBN(0xcf817d1c, 0xa4a82b76), TOBN(0x5586960e, 0xf3806be9), + TOBN(0x7ab67c89, 0x09dc6bb5), TOBN(0x52ace7a0, 0x114fe7eb), + TOBN(0xcd987618, 0xcbbc9b70), TOBN(0x4f06fd5a, 0x604ca5e1), + TOBN(0x90af14ca, 0x6dbde133), TOBN(0x1afe4322, 0x948a3264), + TOBN(0xa70d2ca6, 0xc44b2c6c), TOBN(0xab726799, 0x0ef87dfe), + TOBN(0x310f64dc, 0x2e696377), TOBN(0x49b42e68, 0x4c8126a0), + TOBN(0x0ea444c3, 0xcea0b176), TOBN(0x53a8ddf7, 0xcb269182), + TOBN(0xf3e674eb, 0xbbba9dcb), TOBN(0x0d2878a8, 0xd8669d33), + TOBN(0x04b935d5, 0xd019b6a3), TOBN(0xbb5cf88e, 0x406f1e46), + TOBN(0xa1912d16, 0x5b57c111), TOBN(0x9803fc21, 0x19ebfd78), + TOBN(0x4f231c9e, 0xc07764a9), TOBN(0xd93286ee, 0xb75bd055), + TOBN(0x83a9457d, 0x8ee6c9de), TOBN(0x04695915, 0x6087ec90), + TOBN(0x14c6dd8a, 0x58d6cd46), TOBN(0x9cb633b5, 0x8e6634d2), + TOBN(0xc1305047, 0xf81bc328), TOBN(0x12ede0e2, 0x26a177e5), + TOBN(0x332cca62, 0x065a6f4f), TOBN(0xc3a47ecd, 0x67be487b), + TOBN(0x741eb187, 0x0f47ed1c), TOBN(0x99e66e58, 0xe7598b14), + TOBN(0x6f0544ca, 0x63d0ff12), TOBN(0xe5efc784, 0xb610a05f), + TOBN(0xf72917b1, 0x7cad7b47), TOBN(0x3ff6ea20, 0xf2cac0c0), + TOBN(0xcc23791b, 0xf21db8b7), TOBN(0x7dac70b1, 0xd7d93565), + TOBN(0x682cda1d, 0x694bdaad), TOBN(0xeb88bb8c, 0x1023516d), + TOBN(0xc4c634b4, 0xdfdbeb1b), TOBN(0x22f5ca72, 0xb4ee4dea), + TOBN(0x1045a368, 0xe6524821), TOBN(0xed9e8a3f, 0x052b18b2), + TOBN(0x9b7f2cb1, 0xb961f49a), TOBN(0x7fee2ec1, 0x7b009670), + TOBN(0x350d8754, 0x22507a6d), TOBN(0x561bd711, 0x4db55f1d), + TOBN(0x4c189ccc, 0x320bbcaf), TOBN(0x568434cf, 0xdf1de48c), + TOBN(0x6af1b00e, 0x0fa8f128), TOBN(0xf0ba9d02, 0x8907583c), + TOBN(0x735a4004, 0x32ff9f60), TOBN(0x3dd8e4b6, 0xc25dcf33), + TOBN(0xf2230f16, 0x42c74cef), TOBN(0xd8117623, 0x013fa8ad), + TOBN(0x36822876, 0xf51fe76e), TOBN(0x8a6811cc, 0x11d62589), + TOBN(0xc3fc7e65, 0x46225718), TOBN(0xb7df2c9f, 0xc82fdbcd), + TOBN(0x3b1d4e52, 0xdd7b205b), TOBN(0xb6959478, 0x47a2e414), + TOBN(0x05e4d793, 0xefa91148), TOBN(0xb47ed446, 0xfd2e9675), + TOBN(0x1a7098b9, 0x04c9d9bf), TOBN(0x661e2881, 0x1b793048), + TOBN(0xb1a16966, 0xb01ee461), TOBN(0xbc521308, 0x2954746f), + TOBN(0xc909a0fc, 0x2477de50), TOBN(0xd80bb41c, 0x7dbd51ef), + TOBN(0xa85be7ec, 0x53294905), TOBN(0x6d465b18, 0x83958f97), + TOBN(0x16f6f330, 0xfb6840fd), TOBN(0xfaaeb214, 0x3401e6c8), + TOBN(0xaf83d30f, 0xccb5b4f8), TOBN(0x22885739, 0x266dec4b), + TOBN(0x51b4367c, 0x7bc467df), TOBN(0x926562e3, 0xd842d27a), + TOBN(0xdfcb6614, 0x0fea14a6), TOBN(0xeb394dae, 0xf2734cd9), + TOBN(0x3eeae5d2, 0x11c0be98), TOBN(0xb1e6ed11, 0x814e8165), + TOBN(0x191086bc, 0xe52bce1c), TOBN(0x14b74cc6, 0xa75a04da), + TOBN(0x63cf1186, 0x8c060985), TOBN(0x071047de, 0x2dbd7f7c), + TOBN(0x4e433b8b, 0xce0942ca), TOBN(0xecbac447, 0xd8fec61d), + TOBN(0x8f0ed0e2, 0xebf3232f), TOBN(0xfff80f9e, 0xc52a2edd), + TOBN(0xad9ab433, 0x75b55fdb), TOBN(0x73ca7820, 0xe42e0c11), + TOBN(0x6dace0a0, 0xe6251b46), TOBN(0x89bc6b5c, 0x4c0d932d), + TOBN(0x3438cd77, 0x095da19a), TOBN(0x2f24a939, 0x8d48bdfb), + TOBN(0x99b47e46, 0x766561b7), TOBN(0x736600e6, 0x0ed0322a), + TOBN(0x06a47cb1, 0x638e1865), TOBN(0x927c1c2d, 0xcb136000), + TOBN(0x29542337, 0x0cc5df69), TOBN(0x99b37c02, 0x09d649a9), + TOBN(0xc5f0043c, 0x6aefdb27), TOBN(0x6cdd9987, 0x1be95c27), + TOBN(0x69850931, 0x390420d2), TOBN(0x299c40ac, 0x0983efa4), + TOBN(0x3a05e778, 0xaf39aead), TOBN(0x84274408, 0x43a45193), + TOBN(0x6bcd0fb9, 0x91a711a0), TOBN(0x461592c8, 0x9f52ab17), + TOBN(0xb49302b4, 0xda3c6ed6), TOBN(0xc51fddc7, 0x330d7067), + TOBN(0x94babeb6, 0xda50d531), TOBN(0x521b840d, 0xa6a7b9da), + TOBN(0x5305151e, 0x404bdc89), TOBN(0x1bcde201, 0xd0d07449), + TOBN(0xf427a78b, 0x3b76a59a), TOBN(0xf84841ce, 0x07791a1b), + TOBN(0xebd314be, 0xbf91ed1c), TOBN(0x8e61d34c, 0xbf172943), + TOBN(0x1d5dc451, 0x5541b892), TOBN(0xb186ee41, 0xfc9d9e54), + TOBN(0x9d9f345e, 0xd5bf610d), TOBN(0x3e7ba65d, 0xf6acca9f), + TOBN(0x9dda787a, 0xa8369486), TOBN(0x09f9dab7, 0x8eb5ba53), + TOBN(0x5afb2033, 0xd6481bc3), TOBN(0x76f4ce30, 0xafa62104), + TOBN(0xa8fa00cf, 0xf4f066b5), TOBN(0x89ab5143, 0x461dafc2), + TOBN(0x44339ed7, 0xa3389998), TOBN(0x2ff862f1, 0xbc214903), + TOBN(0x2c88f985, 0xb05556e3), TOBN(0xcd96058e, 0x3467081e), + TOBN(0x7d6a4176, 0xedc637ea), TOBN(0xe1743d09, 0x36a5acdc), + TOBN(0x66fd72e2, 0x7eb37726), TOBN(0xf7fa264e, 0x1481a037), + TOBN(0x9fbd3bde, 0x45f4aa79), TOBN(0xed1e0147, 0x767c3e22), + TOBN(0x7621f979, 0x82e7abe2), TOBN(0x19eedc72, 0x45f633f8), + TOBN(0xe69b155e, 0x6137bf3a), TOBN(0xa0ad13ce, 0x414ee94e), + TOBN(0x93e3d524, 0x1c0e651a), TOBN(0xab1a6e2a, 0x02ce227e), + TOBN(0xe7af1797, 0x4ab27eca), TOBN(0x245446de, 0xbd444f39), + TOBN(0x59e22a21, 0x56c07613), TOBN(0x43deafce, 0xf4275498), + TOBN(0x10834ccb, 0x67fd0946), TOBN(0xa75841e5, 0x47406edf), + TOBN(0xebd6a677, 0x7b0ac93d), TOBN(0xa6e37b0d, 0x78f5e0d7), + TOBN(0x2516c096, 0x76f5492b), TOBN(0x1e4bf888, 0x9ac05f3a), + TOBN(0xcdb42ce0, 0x4df0ba2b), TOBN(0x935d5cfd, 0x5062341b), + TOBN(0x8a303333, 0x82acac20), TOBN(0x429438c4, 0x5198b00e), + TOBN(0x1d083bc9, 0x049d33fa), TOBN(0x58b82dda, 0x946f67ff), + TOBN(0xac3e2db8, 0x67a1d6a3), TOBN(0x62e6bead, 0x1798aac8), + TOBN(0xfc85980f, 0xde46c58c), TOBN(0xa7f69379, 0x69c8d7be), + TOBN(0x23557927, 0x837b35ec), TOBN(0x06a933d8, 0xe0790c0c), + TOBN(0x827c0e9b, 0x077ff55d), TOBN(0x53977798, 0xbb26e680), + TOBN(0x59530874, 0x1d9cb54f), TOBN(0xcca3f449, 0x4aac53ef), + TOBN(0x11dc5c87, 0xa07eda0f), TOBN(0xc138bccf, 0xfd6400c8), + TOBN(0x549680d3, 0x13e5da72), TOBN(0xc93eed82, 0x4540617e), + TOBN(0xfd3db157, 0x4d0b75c0), TOBN(0x9716eb42, 0x6386075b), + TOBN(0x0639605c, 0x817b2c16), TOBN(0x09915109, 0xf1e4f201), + TOBN(0x35c9a928, 0x5cca6c3b), TOBN(0xb25f7d1a, 0x3505c900), + TOBN(0xeb9f7d20, 0x630480c4), TOBN(0xc3c7b8c6, 0x2a1a501c), + TOBN(0x3f99183c, 0x5a1f8e24), TOBN(0xfdb118fa, 0x9dd255f0), + TOBN(0xb9b18b90, 0xc27f62a6), TOBN(0xe8f732f7, 0x396ec191), + TOBN(0x524a2d91, 0x0be786ab), TOBN(0x5d32adef, 0x0ac5a0f5), + TOBN(0x9b53d4d6, 0x9725f694), TOBN(0x032a76c6, 0x0510ba89), + TOBN(0x840391a3, 0xebeb1544), TOBN(0x44b7b88c, 0x3ed73ac3), + TOBN(0xd24bae7a, 0x256cb8b3), TOBN(0x7ceb151a, 0xe394cb12), + TOBN(0xbd6b66d0, 0x5bc1e6a8), TOBN(0xec70cecb, 0x090f07bf), + TOBN(0x270644ed, 0x7d937589), TOBN(0xee9e1a3d, 0x5f1dccfe), + TOBN(0xb0d40a84, 0x745b98d2), TOBN(0xda429a21, 0x2556ed40), + TOBN(0xf676eced, 0x85148cb9), TOBN(0x5a22d40c, 0xded18936), + TOBN(0x3bc4b9e5, 0x70e8a4ce), TOBN(0xbfd1445b, 0x9eae0379), + TOBN(0xf23f2c0c, 0x1a0bd47e), TOBN(0xa9c0bb31, 0xe1845531), + TOBN(0x9ddc4d60, 0x0a4c3f6b), TOBN(0xbdfaad79, 0x2c15ef44), + TOBN(0xce55a236, 0x7f484acc), TOBN(0x08653ca7, 0x055b1f15), + TOBN(0x2efa8724, 0x538873a3), TOBN(0x09299e5d, 0xace1c7e7), + TOBN(0x07afab66, 0xade332ba), TOBN(0x9be1fdf6, 0x92dd71b7), + TOBN(0xa49b5d59, 0x5758b11c), TOBN(0x0b852893, 0xc8654f40), + TOBN(0xb63ef6f4, 0x52379447), TOBN(0xd4957d29, 0x105e690c), + TOBN(0x7d484363, 0x646559b0), TOBN(0xf4a8273c, 0x49788a8e), + TOBN(0xee406cb8, 0x34ce54a9), TOBN(0x1e1c260f, 0xf86fda9b), + TOBN(0xe150e228, 0xcf6a4a81), TOBN(0x1fa3b6a3, 0x1b488772), + TOBN(0x1e6ff110, 0xc5a9c15b), TOBN(0xc6133b91, 0x8ad6aa47), + TOBN(0x8ac5d55c, 0x9dffa978), TOBN(0xba1d1c1d, 0x5f3965f2), + TOBN(0xf969f4e0, 0x7732b52f), TOBN(0xfceecdb5, 0xa5172a07), + TOBN(0xb0120a5f, 0x10f2b8f5), TOBN(0xc83a6cdf, 0x5c4c2f63), + TOBN(0x4d47a491, 0xf8f9c213), TOBN(0xd9e1cce5, 0xd3f1bbd5), + TOBN(0x0d91bc7c, 0xaba7e372), TOBN(0xfcdc74c8, 0xdfd1a2db), + TOBN(0x05efa800, 0x374618e5), TOBN(0x11216969, 0x15a7925e), + TOBN(0xd4c89823, 0xf6021c5d), TOBN(0x880d5e84, 0xeff14423), + TOBN(0x6523bc5a, 0x6dcd1396), TOBN(0xd1acfdfc, 0x113c978b), + TOBN(0xb0c164e8, 0xbbb66840), TOBN(0xf7f4301e, 0x72b58459), + TOBN(0xc29ad4a6, 0xa638e8ec), TOBN(0xf5ab8961, 0x46b78699), + TOBN(0x9dbd7974, 0x0e954750), TOBN(0x0121de88, 0x64f9d2c6), + TOBN(0x2e597b42, 0xd985232e), TOBN(0x55b6c3c5, 0x53451777), + TOBN(0xbb53e547, 0x519cb9fb), TOBN(0xf134019f, 0x8428600d), + TOBN(0x5a473176, 0xe081791a), TOBN(0x2f3e2263, 0x35fb0c08), + TOBN(0xb28c3017, 0x73d273b0), TOBN(0xccd21076, 0x7721ef9a), + TOBN(0x054cc292, 0xb650dc39), TOBN(0x662246de, 0x6188045e), + TOBN(0x904b52fa, 0x6b83c0d1), TOBN(0xa72df267, 0x97e9cd46), + TOBN(0x886b43cd, 0x899725e4), TOBN(0x2b651688, 0xd849ff22), + TOBN(0x60479b79, 0x02f34533), TOBN(0x5e354c14, 0x0c77c148), + TOBN(0xb4bb7581, 0xa8537c78), TOBN(0x188043d7, 0xefe1495f), + TOBN(0x9ba12f42, 0x8c1d5026), TOBN(0x2e0c8a26, 0x93d4aaab), + TOBN(0xbdba7b8b, 0xaa57c450), TOBN(0x140c9ad6, 0x9bbdafef), + TOBN(0x2067aa42, 0x25ac0f18), TOBN(0xf7b1295b, 0x04d1fbf3), + TOBN(0x14829111, 0xa4b04824), TOBN(0x2ce3f192, 0x33bd5e91), + TOBN(0x9c7a1d55, 0x8f2e1b72), TOBN(0xfe932286, 0x302aa243), + TOBN(0x497ca7b4, 0xd4be9554), TOBN(0xb8e821b8, 0xe0547a6e), + TOBN(0xfb2838be, 0x67e573e0), TOBN(0x05891db9, 0x4084c44b), + TOBN(0x91311373, 0x96c1c2c5), TOBN(0x6aebfa3f, 0xd958444b), + TOBN(0xac9cdce9, 0xe56e55c1), TOBN(0x7148ced3, 0x2caa46d0), + TOBN(0x2e10c7ef, 0xb61fe8eb), TOBN(0x9fd835da, 0xff97cf4d)}, + {TOBN(0xa36da109, 0x081e9387), TOBN(0xfb9780d7, 0x8c935828), + TOBN(0xd5940332, 0xe540b015), TOBN(0xc9d7b51b, 0xe0f466fa), + TOBN(0xfaadcd41, 0xd6d9f671), TOBN(0xba6c1e28, 0xb1a2ac17), + TOBN(0x066a7833, 0xed201e5f), TOBN(0x19d99719, 0xf90f462b), + TOBN(0xf431f462, 0x060b5f61), TOBN(0xa56f46b4, 0x7bd057c2), + TOBN(0x348dca6c, 0x47e1bf65), TOBN(0x9a38783e, 0x41bcf1ff), + TOBN(0x7a5d33a9, 0xda710718), TOBN(0x5a779987, 0x2e0aeaf6), + TOBN(0xca87314d, 0x2d29d187), TOBN(0xfa0edc3e, 0xc687d733), + TOBN(0x9df33621, 0x6a31e09b), TOBN(0xde89e44d, 0xc1350e35), + TOBN(0x29214871, 0x4ca0cf52), TOBN(0xdf379672, 0x0b88a538), + TOBN(0xc92a510a, 0x2591d61b), TOBN(0x79aa87d7, 0x585b447b), + TOBN(0xf67db604, 0xe5287f77), TOBN(0x1697c8bf, 0x5efe7a80), + TOBN(0x1c894849, 0xcb198ac7), TOBN(0xa884a93d, 0x0f264665), + TOBN(0x2da964ef, 0x9b200678), TOBN(0x3c351b87, 0x009834e6), + TOBN(0xafb2ef9f, 0xe2c4b44b), TOBN(0x580f6c47, 0x3326790c), + TOBN(0xb8480521, 0x0b02264a), TOBN(0x8ba6f9e2, 0x42a194e2), + TOBN(0xfc87975f, 0x8fb54738), TOBN(0x35160788, 0x27c3ead3), + TOBN(0x834116d2, 0xb74a085a), TOBN(0x53c99a73, 0xa62fe996), + TOBN(0x87585be0, 0x5b81c51b), TOBN(0x925bafa8, 0xbe0852b7), + TOBN(0x76a4fafd, 0xa84d19a7), TOBN(0x39a45982, 0x585206d4), + TOBN(0x499b6ab6, 0x5eb03c0e), TOBN(0xf19b7954, 0x72bc3fde), + TOBN(0xa86b5b9c, 0x6e3a80d2), TOBN(0xe4377508, 0x6d42819f), + TOBN(0xc1663650, 0xbb3ee8a3), TOBN(0x75eb14fc, 0xb132075f), + TOBN(0xa8ccc906, 0x7ad834f6), TOBN(0xea6a2474, 0xe6e92ffd), + TOBN(0x9d72fd95, 0x0f8d6758), TOBN(0xcb84e101, 0x408c07dd), + TOBN(0xb9114bfd, 0xa5e23221), TOBN(0x358b5fe2, 0xe94e742c), + TOBN(0x1c0577ec, 0x95f40e75), TOBN(0xf0155451, 0x3d73f3d6), + TOBN(0x9d55cd67, 0xbd1b9b66), TOBN(0x63e86e78, 0xaf8d63c7), + TOBN(0x39d934ab, 0xd3c095f1), TOBN(0x04b261be, 0xe4b76d71), + TOBN(0x1d2e6970, 0xe73e6984), TOBN(0x879fb23b, 0x5e5fcb11), + TOBN(0x11506c72, 0xdfd75490), TOBN(0x3a97d085, 0x61bcf1c1), + TOBN(0x43201d82, 0xbf5e7007), TOBN(0x7f0ac52f, 0x798232a7), + TOBN(0x2715cbc4, 0x6eb564d4), TOBN(0x8d6c752c, 0x9e570e29), + TOBN(0xf80247c8, 0x9ef5fd5d), TOBN(0xc3c66b46, 0xd53eb514), + TOBN(0x9666b401, 0x0f87de56), TOBN(0xce62c06f, 0xc6c603b5), + TOBN(0xae7b4c60, 0x7e4fc942), TOBN(0x38ac0b77, 0x663a9c19), + TOBN(0xcb4d20ee, 0x4b049136), TOBN(0x8b63bf12, 0x356a4613), + TOBN(0x1221aef6, 0x70e08128), TOBN(0xe62d8c51, 0x4acb6b16), + TOBN(0x71f64a67, 0x379e7896), TOBN(0xb25237a2, 0xcafd7fa5), + TOBN(0xf077bd98, 0x3841ba6a), TOBN(0xc4ac0244, 0x3cd16e7e), + TOBN(0x548ba869, 0x21fea4ca), TOBN(0xd36d0817, 0xf3dfdac1), + TOBN(0x09d8d71f, 0xf4685faf), TOBN(0x8eff66be, 0xc52c459a), + TOBN(0x182faee7, 0x0b57235e), TOBN(0xee3c39b1, 0x0106712b), + TOBN(0x5107331f, 0xc0fcdcb0), TOBN(0x669fb9dc, 0xa51054ba), + TOBN(0xb25101fb, 0x319d7682), TOBN(0xb0293129, 0x0a982fee), + TOBN(0x51c1c9b9, 0x0261b344), TOBN(0x0e008c5b, 0xbfd371fa), + TOBN(0xd866dd1c, 0x0278ca33), TOBN(0x666f76a6, 0xe5aa53b1), + TOBN(0xe5cfb779, 0x6013a2cf), TOBN(0x1d3a1aad, 0xa3521836), + TOBN(0xcedd2531, 0x73faa485), TOBN(0xc8ee6c4f, 0xc0a76878), + TOBN(0xddbccfc9, 0x2a11667d), TOBN(0x1a418ea9, 0x1c2f695a), + TOBN(0xdb11bd92, 0x51f73971), TOBN(0x3e4b3c82, 0xda2ed89f), + TOBN(0x9a44f3f4, 0xe73e0319), TOBN(0xd1e3de0f, 0x303431af), + TOBN(0x3c5604ff, 0x50f75f9c), TOBN(0x1d8eddf3, 0x7e752b22), + TOBN(0x0ef074dd, 0x3c9a1118), TOBN(0xd0ffc172, 0xccb86d7b), + TOBN(0xabd1ece3, 0x037d90f2), TOBN(0xe3f307d6, 0x6055856c), + TOBN(0x422f9328, 0x7e4c6daf), TOBN(0x902aac66, 0x334879a0), + TOBN(0xb6a1e7bf, 0x94cdfade), TOBN(0x6c97e1ed, 0x7fc6d634), + TOBN(0x662ad24d, 0xa2fb63f8), TOBN(0xf81be1b9, 0xa5928405), + TOBN(0x86d765e4, 0xd14b4206), TOBN(0xbecc2e0e, 0x8fa0db65), + TOBN(0xa28838e0, 0xb17fc76c), TOBN(0xe49a602a, 0xe37cf24e), + TOBN(0x76b4131a, 0x567193ec), TOBN(0xaf3c305a, 0xe5f6e70b), + TOBN(0x9587bd39, 0x031eebdd), TOBN(0x5709def8, 0x71bbe831), + TOBN(0x57059983, 0x0eb2b669), TOBN(0x4d80ce1b, 0x875b7029), + TOBN(0x838a7da8, 0x0364ac16), TOBN(0x2f431d23, 0xbe1c83ab), + TOBN(0xe56812a6, 0xf9294dd3), TOBN(0xb448d01f, 0x9b4b0d77), + TOBN(0xf3ae6061, 0x04e8305c), TOBN(0x2bead645, 0x94d8c63e), + TOBN(0x0a85434d, 0x84fd8b07), TOBN(0x537b983f, 0xf7a9dee5), + TOBN(0xedcc5f18, 0xef55bd85), TOBN(0x2041af62, 0x21c6cf8b), + TOBN(0x8e52874c, 0xb940c71e), TOBN(0x211935a9, 0xdb5f4b3a), + TOBN(0x94350492, 0x301b1dc3), TOBN(0x33d2646d, 0x29958620), + TOBN(0x16b0d64b, 0xef911404), TOBN(0x9d1f25ea, 0x9a3c5ef4), + TOBN(0x20f200eb, 0x4a352c78), TOBN(0x43929f2c, 0x4bd0b428), + TOBN(0xa5656667, 0xc7196e29), TOBN(0x7992c2f0, 0x9391be48), + TOBN(0xaaa97cbd, 0x9ee0cd6e), TOBN(0x51b0310c, 0x3dc8c9bf), + TOBN(0x237f8acf, 0xdd9f22cb), TOBN(0xbb1d81a1, 0xb585d584), + TOBN(0x8d5d85f5, 0x8c416388), TOBN(0x0d6e5a5a, 0x42fe474f), + TOBN(0xe7812766, 0x38235d4e), TOBN(0x1c62bd67, 0x496e3298), + TOBN(0x8378660c, 0x3f175bc8), TOBN(0x4d04e189, 0x17afdd4d), + TOBN(0x32a81601, 0x85a8068c), TOBN(0xdb58e4e1, 0x92b29a85), + TOBN(0xe8a65b86, 0xc70d8a3b), TOBN(0x5f0e6f4e, 0x98a0403b), + TOBN(0x08129684, 0x69ed2370), TOBN(0x34dc30bd, 0x0871ee26), + TOBN(0x3a5ce948, 0x7c9c5b05), TOBN(0x7d487b80, 0x43a90c87), + TOBN(0x4089ba37, 0xdd0e7179), TOBN(0x45f80191, 0xb4041811), + TOBN(0x1c3e1058, 0x98747ba5), TOBN(0x98c4e13a, 0x6e1ae592), + TOBN(0xd44636e6, 0xe82c9f9e), TOBN(0x711db87c, 0xc33a1043), + TOBN(0x6f431263, 0xaa8aec05), TOBN(0x43ff120d, 0x2744a4aa), + TOBN(0xd3bd892f, 0xae77779b), TOBN(0xf0fe0cc9, 0x8cdc9f82), + TOBN(0xca5f7fe6, 0xf1c5b1bc), TOBN(0xcc63a682, 0x44929a72), + TOBN(0xc7eaba0c, 0x09dbe19a), TOBN(0x2f3585ad, 0x6b5c73c2), + TOBN(0x8ab8924b, 0x0ae50c30), TOBN(0x17fcd27a, 0x638b30ba), + TOBN(0xaf414d34, 0x10b3d5a5), TOBN(0x09c107d2, 0x2a9accf1), + TOBN(0x15dac49f, 0x946a6242), TOBN(0xaec3df2a, 0xd707d642), + TOBN(0x2c2492b7, 0x3f894ae0), TOBN(0xf59df3e5, 0xb75f18ce), + TOBN(0x7cb740d2, 0x8f53cad0), TOBN(0x3eb585fb, 0xc4f01294), + TOBN(0x17da0c86, 0x32c7f717), TOBN(0xeb8c795b, 0xaf943f4c), + TOBN(0x4ee23fb5, 0xf67c51d2), TOBN(0xef187575, 0x68889949), + TOBN(0xa6b4bdb2, 0x0389168b), TOBN(0xc4ecd258, 0xea577d03), + TOBN(0x3a63782b, 0x55743082), TOBN(0x6f678f4c, 0xc72f08cd), + TOBN(0x553511cf, 0x65e58dd8), TOBN(0xd53b4e3e, 0xd402c0cd), + TOBN(0x37de3e29, 0xa037c14c), TOBN(0x86b6c516, 0xc05712aa), + TOBN(0x2834da3e, 0xb38dff6f), TOBN(0xbe012c52, 0xea636be8), + TOBN(0x292d238c, 0x61dd37f8), TOBN(0x0e54523f, 0x8f8142db), + TOBN(0xe31eb436, 0x036a05d8), TOBN(0x83e3cdff, 0x1e93c0ff), + TOBN(0x3fd2fe0f, 0x50821ddf), TOBN(0xc8e19b0d, 0xff9eb33b), + TOBN(0xc8cc943f, 0xb569a5fe), TOBN(0xad0090d4, 0xd4342d75), + TOBN(0x82090b4b, 0xcaeca000), TOBN(0xca39687f, 0x1bd410eb), + TOBN(0xe7bb0df7, 0x65959d77), TOBN(0x39d78218, 0x9c964999), + TOBN(0xd87f62e8, 0xb2415451), TOBN(0xe5efb774, 0xbed76108), + TOBN(0x3ea011a4, 0xe822f0d0), TOBN(0xbc647ad1, 0x5a8704f8), + TOBN(0xbb315b35, 0x50c6820f), TOBN(0x863dec3d, 0xb7e76bec), + TOBN(0x01ff5d3a, 0xf017bfc7), TOBN(0x20054439, 0x976b8229), + TOBN(0x067fca37, 0x0bbd0d3b), TOBN(0xf63dde64, 0x7f5e3d0f), + TOBN(0x22dbefb3, 0x2a4c94e9), TOBN(0xafbff0fe, 0x96f8278a), + TOBN(0x80aea0b1, 0x3503793d), TOBN(0xb2238029, 0x5f06cd29), + TOBN(0x65703e57, 0x8ec3feca), TOBN(0x06c38314, 0x393e7053), + TOBN(0xa0b751eb, 0x7c6734c4), TOBN(0xd2e8a435, 0xc59f0f1e), + TOBN(0x147d9052, 0x5e9ca895), TOBN(0x2f4dd31e, 0x972072df), + TOBN(0xa16fda8e, 0xe6c6755c), TOBN(0xc66826ff, 0xcf196558), + TOBN(0x1f1a76a3, 0x0cf43895), TOBN(0xa9d604e0, 0x83c3097b), + TOBN(0xe1908309, 0x66390e0e), TOBN(0xa50bf753, 0xb3c85eff), + TOBN(0x0696bdde, 0xf6a70251), TOBN(0x548b801b, 0x3c6ab16a), + TOBN(0x37fcf704, 0xa4d08762), TOBN(0x090b3def, 0xdff76c4e), + TOBN(0x87e8cb89, 0x69cb9158), TOBN(0x44a90744, 0x995ece43), + TOBN(0xf85395f4, 0x0ad9fbf5), TOBN(0x49b0f6c5, 0x4fb0c82d), + TOBN(0x75d9bc15, 0xadf7cccf), TOBN(0x81a3e5d6, 0xdfa1e1b0), + TOBN(0x8c39e444, 0x249bc17e), TOBN(0xf37dccb2, 0x8ea7fd43), + TOBN(0xda654873, 0x907fba12), TOBN(0x35daa6da, 0x4a372904), + TOBN(0x0564cfc6, 0x6283a6c5), TOBN(0xd09fa4f6, 0x4a9395bf), + TOBN(0x688e9ec9, 0xaeb19a36), TOBN(0xd913f1ce, 0xc7bfbfb4), + TOBN(0x797b9a3c, 0x61c2faa6), TOBN(0x2f979bec, 0x6a0a9c12), + TOBN(0xb5969d0f, 0x359679ec), TOBN(0xebcf523d, 0x079b0460), + TOBN(0xfd6b0008, 0x10fab870), TOBN(0x3f2edcda, 0x9373a39c), + TOBN(0x0d64f9a7, 0x6f568431), TOBN(0xf848c27c, 0x02f8898c), + TOBN(0xf418ade1, 0x260b5bd5), TOBN(0xc1f3e323, 0x6973dee8), + TOBN(0x46e9319c, 0x26c185dd), TOBN(0x6d85b7d8, 0x546f0ac4), + TOBN(0x427965f2, 0x247f9d57), TOBN(0xb519b636, 0xb0035f48), + TOBN(0x6b6163a9, 0xab87d59c), TOBN(0xff9f58c3, 0x39caaa11), + TOBN(0x4ac39cde, 0x3177387b), TOBN(0x5f6557c2, 0x873e77f9), + TOBN(0x67504006, 0x36a83041), TOBN(0x9b1c96ca, 0x75ef196c), + TOBN(0xf34283de, 0xb08c7940), TOBN(0x7ea09644, 0x1128c316), + TOBN(0xb510b3b5, 0x6aa39dff), TOBN(0x59b43da2, 0x9f8e4d8c), + TOBN(0xa8ce31fd, 0x9e4c4b9f), TOBN(0x0e20be26, 0xc1303c01), + TOBN(0x18187182, 0xe8ee47c9), TOBN(0xd9687cdb, 0x7db98101), + TOBN(0x7a520e4d, 0xa1e14ff6), TOBN(0x429808ba, 0x8836d572), + TOBN(0xa37ca60d, 0x4944b663), TOBN(0xf901f7a9, 0xa3f91ae5), + TOBN(0xe4e3e76e, 0x9e36e3b1), TOBN(0x9aa219cf, 0x29d93250), + TOBN(0x347fe275, 0x056a2512), TOBN(0xa4d643d9, 0xde65d95c), + TOBN(0x9669d396, 0x699fc3ed), TOBN(0xb598dee2, 0xcf8c6bbe), + TOBN(0x682ac1e5, 0xdda9e5c6), TOBN(0x4e0d3c72, 0xcaa9fc95), + TOBN(0x17faaade, 0x772bea44), TOBN(0x5ef8428c, 0xab0009c8), + TOBN(0xcc4ce47a, 0x460ff016), TOBN(0xda6d12bf, 0x725281cb), + TOBN(0x44c67848, 0x0223aad2), TOBN(0x6e342afa, 0x36256e28), + TOBN(0x1400bb0b, 0x93a37c04), TOBN(0x62b1bc9b, 0xdd10bd96), + TOBN(0x7251adeb, 0x0dac46b7), TOBN(0x7d33b92e, 0x7be4ef51), + TOBN(0x28b2a94b, 0xe61fa29a), TOBN(0x4b2be13f, 0x06422233), + TOBN(0x36d6d062, 0x330d8d37), TOBN(0x5ef80e1e, 0xb28ca005), + TOBN(0x174d4699, 0x6d16768e), TOBN(0x9fc4ff6a, 0x628bf217), + TOBN(0x77705a94, 0x154e490d), TOBN(0x9d96dd28, 0x8d2d997a), + TOBN(0x77e2d9d8, 0xce5d72c4), TOBN(0x9d06c5a4, 0xc11c714f), + TOBN(0x02aa5136, 0x79e4a03e), TOBN(0x1386b3c2, 0x030ff28b), + TOBN(0xfe82e8a6, 0xfb283f61), TOBN(0x7df203e5, 0xf3abc3fb), + TOBN(0xeec7c351, 0x3a4d3622), TOBN(0xf7d17dbf, 0xdf762761), + TOBN(0xc3956e44, 0x522055f0), TOBN(0xde3012db, 0x8fa748db), + TOBN(0xca9fcb63, 0xbf1dcc14), TOBN(0xa56d9dcf, 0xbe4e2f3a), + TOBN(0xb86186b6, 0x8bcec9c2), TOBN(0x7cf24df9, 0x680b9f06), + TOBN(0xc46b45ea, 0xc0d29281), TOBN(0xfff42bc5, 0x07b10e12), + TOBN(0x12263c40, 0x4d289427), TOBN(0x3d5f1899, 0xb4848ec4), + TOBN(0x11f97010, 0xd040800c), TOBN(0xb4c5f529, 0x300feb20), + TOBN(0xcc543f8f, 0xde94fdcb), TOBN(0xe96af739, 0xc7c2f05e), + TOBN(0xaa5e0036, 0x882692e1), TOBN(0x09c75b68, 0x950d4ae9), + TOBN(0x62f63df2, 0xb5932a7a), TOBN(0x2658252e, 0xde0979ad), + TOBN(0x2a19343f, 0xb5e69631), TOBN(0x718c7501, 0x525b666b), + TOBN(0x26a42d69, 0xea40dc3a), TOBN(0xdc84ad22, 0xaecc018f), + TOBN(0x25c36c7b, 0x3270f04a), TOBN(0x46ba6d47, 0x50fa72ed), + TOBN(0x6c37d1c5, 0x93e58a8e), TOBN(0xa2394731, 0x120c088c), + TOBN(0xc3be4263, 0xcb6e86da), TOBN(0x2c417d36, 0x7126d038), + TOBN(0x5b70f9c5, 0x8b6f8efa), TOBN(0x671a2faa, 0x37718536), + TOBN(0xd3ced3c6, 0xb539c92b), TOBN(0xe56f1bd9, 0xa31203c2), + TOBN(0x8b096ec4, 0x9ff3c8eb), TOBN(0x2deae432, 0x43491cea), + TOBN(0x2465c6eb, 0x17943794), TOBN(0x5d267e66, 0x20586843), + TOBN(0x9d3d116d, 0xb07159d0), TOBN(0xae07a67f, 0xc1896210), + TOBN(0x8fc84d87, 0xbb961579), TOBN(0x30009e49, 0x1c1f8dd6), + TOBN(0x8a8caf22, 0xe3132819), TOBN(0xcffa197c, 0xf23ab4ff), + TOBN(0x58103a44, 0x205dd687), TOBN(0x57b796c3, 0x0ded67a2), + TOBN(0x0b9c3a6c, 0xa1779ad7), TOBN(0xa33cfe2e, 0x357c09c5), + TOBN(0x2ea29315, 0x3db4a57e), TOBN(0x91959695, 0x8ebeb52e), + TOBN(0x118db9a6, 0xe546c879), TOBN(0x8e996df4, 0x6295c8d6), + TOBN(0xdd990484, 0x55ec806b), TOBN(0x24f291ca, 0x165c1035), + TOBN(0xcca523bb, 0x440e2229), TOBN(0x324673a2, 0x73ef4d04), + TOBN(0xaf3adf34, 0x3e11ec39), TOBN(0x6136d7f1, 0xdc5968d3), + TOBN(0x7a7b2899, 0xb053a927), TOBN(0x3eaa2661, 0xae067ecd), + TOBN(0x8549b9c8, 0x02779cd9), TOBN(0x061d7940, 0xc53385ea), + TOBN(0x3e0ba883, 0xf06d18bd), TOBN(0x4ba6de53, 0xb2700843), + TOBN(0xb966b668, 0x591a9e4d), TOBN(0x93f67567, 0x7f4fa0ed), + TOBN(0x5a02711b, 0x4347237b), TOBN(0xbc041e2f, 0xe794608e), + TOBN(0x55af10f5, 0x70f73d8c), TOBN(0xd2d4d4f7, 0xbb7564f7), + TOBN(0xd7d27a89, 0xb3e93ce7), TOBN(0xf7b5a875, 0x5d3a2c1b), + TOBN(0xb29e68a0, 0x255b218a), TOBN(0xb533837e, 0x8af76754), + TOBN(0xd1b05a73, 0x579fab2e), TOBN(0xb41055a1, 0xecd74385), + TOBN(0xb2369274, 0x445e9115), TOBN(0x2972a7c4, 0xf520274e), + TOBN(0x6c08334e, 0xf678e68a), TOBN(0x4e4160f0, 0x99b057ed), + TOBN(0x3cfe11b8, 0x52ccb69a), TOBN(0x2fd1823a, 0x21c8f772), + TOBN(0xdf7f072f, 0x3298f055), TOBN(0x8c0566f9, 0xfec74a6e), + TOBN(0xe549e019, 0x5bb4d041), TOBN(0x7c3930ba, 0x9208d850), + TOBN(0xe07141fc, 0xaaa2902b), TOBN(0x539ad799, 0xe4f69ad3), + TOBN(0xa6453f94, 0x813f9ffd), TOBN(0xc58d3c48, 0x375bc2f7), + TOBN(0xb3326fad, 0x5dc64e96), TOBN(0x3aafcaa9, 0xb240e354), + TOBN(0x1d1b0903, 0xaca1e7a9), TOBN(0x4ceb9767, 0x1211b8a0), + TOBN(0xeca83e49, 0xe32a858e), TOBN(0x4c32892e, 0xae907bad), + TOBN(0xd5b42ab6, 0x2eb9b494), TOBN(0x7fde3ee2, 0x1eabae1b), + TOBN(0x13b5ab09, 0xcaf54957), TOBN(0xbfb028be, 0xe5f5d5d5), + TOBN(0x928a0650, 0x2003e2c0), TOBN(0x90793aac, 0x67476843), + TOBN(0x5e942e79, 0xc81710a0), TOBN(0x557e4a36, 0x27ccadd4), + TOBN(0x72a2bc56, 0x4bcf6d0c), TOBN(0x09ee5f43, 0x26d7b80c), + TOBN(0x6b70dbe9, 0xd4292f19), TOBN(0x56f74c26, 0x63f16b18), + TOBN(0xc23db0f7, 0x35fbb42a), TOBN(0xb606bdf6, 0x6ae10040), + TOBN(0x1eb15d4d, 0x044573ac), TOBN(0x7dc3cf86, 0x556b0ba4), + TOBN(0x97af9a33, 0xc60df6f7), TOBN(0x0b1ef85c, 0xa716ce8c), + TOBN(0x2922f884, 0xc96958be), TOBN(0x7c32fa94, 0x35690963), + TOBN(0x2d7f667c, 0xeaa00061), TOBN(0xeaaf7c17, 0x3547365c), + TOBN(0x1eb4de46, 0x87032d58), TOBN(0xc54f3d83, 0x5e2c79e0), + TOBN(0x07818df4, 0x5d04ef23), TOBN(0x55faa9c8, 0x673d41b4), + TOBN(0xced64f6f, 0x89b95355), TOBN(0x4860d2ea, 0xb7415c84), + TOBN(0x5fdb9bd2, 0x050ebad3), TOBN(0xdb53e0cc, 0x6685a5bf), + TOBN(0xb830c031, 0x9feb6593), TOBN(0xdd87f310, 0x6accff17), + TOBN(0x2303ebab, 0x9f555c10), TOBN(0x94603695, 0x287e7065), + TOBN(0xf88311c3, 0x2e83358c), TOBN(0x508dd9b4, 0xeefb0178), + TOBN(0x7ca23706, 0x2dba8652), TOBN(0x62aac5a3, 0x0047abe5), + TOBN(0x9a61d2a0, 0x8b1ea7b3), TOBN(0xd495ab63, 0xae8b1485), + TOBN(0x38740f84, 0x87052f99), TOBN(0x178ebe5b, 0xb2974eea), + TOBN(0x030bbcca, 0x5b36d17f), TOBN(0xb5e4cce3, 0xaaf86eea), + TOBN(0xb51a0220, 0x68f8e9e0), TOBN(0xa4348796, 0x09eb3e75), + TOBN(0xbe592309, 0xeef1a752), TOBN(0x5d7162d7, 0x6f2aa1ed), + TOBN(0xaebfb5ed, 0x0f007dd2), TOBN(0x255e14b2, 0xc89edd22), + TOBN(0xba85e072, 0x0303b697), TOBN(0xc5d17e25, 0xf05720ff), + TOBN(0x02b58d6e, 0x5128ebb6), TOBN(0x2c80242d, 0xd754e113), + TOBN(0x919fca5f, 0xabfae1ca), TOBN(0x937afaac, 0x1a21459b), + TOBN(0x9e0ca91c, 0x1f66a4d2), TOBN(0x194cc7f3, 0x23ec1331), + TOBN(0xad25143a, 0x8aa11690), TOBN(0xbe40ad8d, 0x09b59e08), + TOBN(0x37d60d9b, 0xe750860a), TOBN(0x6c53b008, 0xc6bf434c), + TOBN(0xb572415d, 0x1356eb80), TOBN(0xb8bf9da3, 0x9578ded8), + TOBN(0x22658e36, 0x5e8fb38b), TOBN(0x9b70ce22, 0x5af8cb22), + TOBN(0x7c00018a, 0x829a8180), TOBN(0x84329f93, 0xb81ed295), + TOBN(0x7c343ea2, 0x5f3cea83), TOBN(0x38f8655f, 0x67586536), + TOBN(0xa661a0d0, 0x1d3ec517), TOBN(0x98744652, 0x512321ae), + TOBN(0x084ca591, 0xeca92598), TOBN(0xa9bb9dc9, 0x1dcb3feb), + TOBN(0x14c54355, 0x78b4c240), TOBN(0x5ed62a3b, 0x610cafdc), + TOBN(0x07512f37, 0x1b38846b), TOBN(0x571bb70a, 0xb0e38161), + TOBN(0xb556b95b, 0x2da705d2), TOBN(0x3ef8ada6, 0xb1a08f98), + TOBN(0x85302ca7, 0xddecfbe5), TOBN(0x0e530573, 0x943105cd), + TOBN(0x60554d55, 0x21a9255d), TOBN(0x63a32fa1, 0xf2f3802a), + TOBN(0x35c8c5b0, 0xcd477875), TOBN(0x97f458ea, 0x6ad42da1), + TOBN(0x832d7080, 0xeb6b242d), TOBN(0xd30bd023, 0x3b71e246), + TOBN(0x7027991b, 0xbe31139d), TOBN(0x68797e91, 0x462e4e53), + TOBN(0x423fe20a, 0x6b4e185a), TOBN(0x82f2c67e, 0x42d9b707), + TOBN(0x25c81768, 0x4cf7811b), TOBN(0xbd53005e, 0x045bb95d)}, + {TOBN(0xe5f649be, 0x9d8e68fd), TOBN(0xdb0f0533, 0x1b044320), + TOBN(0xf6fde9b3, 0xe0c33398), TOBN(0x92f4209b, 0x66c8cfae), + TOBN(0xe9d1afcc, 0x1a739d4b), TOBN(0x09aea75f, 0xa28ab8de), + TOBN(0x14375fb5, 0xeac6f1d0), TOBN(0x6420b560, 0x708f7aa5), + TOBN(0x9eae499c, 0x6254dc41), TOBN(0x7e293924, 0x7a837e7e), + TOBN(0x74aec08c, 0x090524a7), TOBN(0xf82b9219, 0x8d6f55f2), + TOBN(0x493c962e, 0x1402cec5), TOBN(0x9f17ca17, 0xfa2f30e7), + TOBN(0xbcd783e8, 0xe9b879cb), TOBN(0xea3d8c14, 0x5a6f145f), + TOBN(0xdede15e7, 0x5e0dee6e), TOBN(0x74f24872, 0xdc628aa2), + TOBN(0xd3e9c4fe, 0x7861bb93), TOBN(0x56d4822a, 0x6187b2e0), + TOBN(0xb66417cf, 0xc59826f9), TOBN(0xca260969, 0x2408169e), + TOBN(0xedf69d06, 0xc79ef885), TOBN(0x00031f8a, 0xdc7d138f), + TOBN(0x103c46e6, 0x0ebcf726), TOBN(0x4482b831, 0x6231470e), + TOBN(0x6f6dfaca, 0x487c2109), TOBN(0x2e0ace97, 0x62e666ef), + TOBN(0x3246a9d3, 0x1f8d1f42), TOBN(0x1b1e83f1, 0x574944d2), + TOBN(0x13dfa63a, 0xa57f334b), TOBN(0x0cf8daed, 0x9f025d81), + TOBN(0x30d78ea8, 0x00ee11c1), TOBN(0xeb053cd4, 0xb5e3dd75), + TOBN(0x9b65b13e, 0xd58c43c5), TOBN(0xc3ad49bd, 0xbd151663), + TOBN(0x99fd8e41, 0xb6427990), TOBN(0x12cf15bd, 0x707eae1e), + TOBN(0x29ad4f1b, 0x1aabb71e), TOBN(0x5143e74d, 0x07545d0e), + TOBN(0x30266336, 0xc88bdee1), TOBN(0x25f29306, 0x5876767c), + TOBN(0x9c078571, 0xc6731996), TOBN(0xc88690b2, 0xed552951), + TOBN(0x274f2c2d, 0x852705b4), TOBN(0xb0bf8d44, 0x4e09552d), + TOBN(0x7628beeb, 0x986575d1), TOBN(0x407be238, 0x7f864651), + TOBN(0x0e5e3049, 0xa639fc6b), TOBN(0xe75c35d9, 0x86003625), + TOBN(0x0cf35bd8, 0x5dcc1646), TOBN(0x8bcaced2, 0x6c26273a), + TOBN(0xe22ecf1d, 0xb5536742), TOBN(0x013dd897, 0x1a9e068b), + TOBN(0x17f411cb, 0x8a7909c5), TOBN(0x5757ac98, 0x861dd506), + TOBN(0x85de1f0d, 0x1e935abb), TOBN(0xdefd10b4, 0x154de37a), + TOBN(0xb8d9e392, 0x369cebb5), TOBN(0x54d5ef9b, 0x761324be), + TOBN(0x4d6341ba, 0x74f17e26), TOBN(0xc0a0e3c8, 0x78c1dde4), + TOBN(0xa6d77581, 0x87d918fd), TOBN(0x66876015, 0x02ca3a13), + TOBN(0xc7313e9c, 0xf36658f0), TOBN(0xc433ef1c, 0x71f8057e), + TOBN(0x85326246, 0x1b6a835a), TOBN(0xc8f05398, 0x7c86394c), + TOBN(0xff398cdf, 0xe983c4a1), TOBN(0xbf5e8162, 0x03b7b931), + TOBN(0x93193c46, 0xb7b9045b), TOBN(0x1e4ebf5d, 0xa4a6e46b), + TOBN(0xf9942a60, 0x43a24fe7), TOBN(0x29c1191e, 0xffb3492b), + TOBN(0x9f662449, 0x902fde05), TOBN(0xc792a7ac, 0x6713c32d), + TOBN(0x2fd88ad8, 0xb737982c), TOBN(0x7e3a0319, 0xa21e60e3), + TOBN(0x09b0de44, 0x7383591a), TOBN(0x6df141ee, 0x8310a456), + TOBN(0xaec1a039, 0xe6d6f471), TOBN(0x14b2ba0f, 0x1198d12e), + TOBN(0xebc1a160, 0x3aeee5ac), TOBN(0x401f4836, 0xe0b964ce), + TOBN(0x2ee43796, 0x4fd03f66), TOBN(0x3fdb4e49, 0xdd8f3f12), + TOBN(0x6ef267f6, 0x29380f18), TOBN(0x3e8e9670, 0x8da64d16), + TOBN(0xbc19180c, 0x207674f1), TOBN(0x112e09a7, 0x33ae8fdb), + TOBN(0x99667554, 0x6aaeb71e), TOBN(0x79432af1, 0xe101b1c7), + TOBN(0xd5eb558f, 0xde2ddec6), TOBN(0x81392d1f, 0x5357753f), + TOBN(0xa7a76b97, 0x3ae1158a), TOBN(0x416fbbff, 0x4a899991), + TOBN(0x9e65fdfd, 0x0d4a9dcf), TOBN(0x7bc29e48, 0x944ddf12), + TOBN(0xbc1a92d9, 0x3c856866), TOBN(0x273c6905, 0x6e98dfe2), + TOBN(0x69fce418, 0xcdfaa6b8), TOBN(0x606bd823, 0x5061c69f), + TOBN(0x42d495a0, 0x6af75e27), TOBN(0x8ed3d505, 0x6d873a1f), + TOBN(0xaf552841, 0x6ab25b6a), TOBN(0xc6c0ffc7, 0x2b1a4523), + TOBN(0xab18827b, 0x21c99e03), TOBN(0x060e8648, 0x9034691b), + TOBN(0x5207f90f, 0x93c7f398), TOBN(0x9f4a96cb, 0x82f8d10b), + TOBN(0xdd71cd79, 0x3ad0f9e3), TOBN(0x84f435d2, 0xfc3a54f5), + TOBN(0x4b03c55b, 0x8e33787f), TOBN(0xef42f975, 0xa6384673), + TOBN(0xff7304f7, 0x5051b9f0), TOBN(0x18aca1dc, 0x741c87c2), + TOBN(0x56f120a7, 0x2d4bfe80), TOBN(0xfd823b3d, 0x053e732c), + TOBN(0x11bccfe4, 0x7537ca16), TOBN(0xdf6c9c74, 0x1b5a996b), + TOBN(0xee7332c7, 0x904fc3fa), TOBN(0x14a23f45, 0xc7e3636a), + TOBN(0xc38659c3, 0xf091d9aa), TOBN(0x4a995e5d, 0xb12d8540), + TOBN(0x20a53bec, 0xf3a5598a), TOBN(0x56534b17, 0xb1eaa995), + TOBN(0x9ed3dca4, 0xbf04e03c), TOBN(0x716c563a, 0xd8d56268), + TOBN(0x27ba77a4, 0x1d6178e7), TOBN(0xe4c80c40, 0x68a1ff8e), + TOBN(0x75011099, 0x0a13f63d), TOBN(0x7bf33521, 0xa61d46f3), + TOBN(0x0aff218e, 0x10b365bb), TOBN(0x81021804, 0x0fd7ea75), + TOBN(0x05a3fd8a, 0xa4b3a925), TOBN(0xb829e75f, 0x9b3db4e6), + TOBN(0x6bdc75a5, 0x4d53e5fb), TOBN(0x04a5dc02, 0xd52717e3), + TOBN(0x86af502f, 0xe9a42ec2), TOBN(0x8867e8fb, 0x2630e382), + TOBN(0xbf845c6e, 0xbec9889b), TOBN(0x54f491f2, 0xcb47c98d), + TOBN(0xa3091fba, 0x790c2a12), TOBN(0xd7f6fd78, 0xc20f708b), + TOBN(0xa569ac30, 0xacde5e17), TOBN(0xd0f996d0, 0x6852b4d7), + TOBN(0xe51d4bb5, 0x4609ae54), TOBN(0x3fa37d17, 0x0daed061), + TOBN(0x62a88684, 0x34b8fb41), TOBN(0x99a2acbd, 0x9efb64f1), + TOBN(0xb75c1a5e, 0x6448e1f2), TOBN(0xfa99951a, 0x42b5a069), + TOBN(0x6d956e89, 0x2f3b26e7), TOBN(0xf4709860, 0xda875247), + TOBN(0x3ad15179, 0x2482dda3), TOBN(0xd64110e3, 0x017d82f0), + TOBN(0x14928d2c, 0xfad414e4), TOBN(0x2b155f58, 0x2ed02b24), + TOBN(0x481a141b, 0xcb821bf1), TOBN(0x12e3c770, 0x4f81f5da), + TOBN(0xe49c5de5, 0x9fff8381), TOBN(0x11053232, 0x5bbec894), + TOBN(0xa0d051cc, 0x454d88c4), TOBN(0x4f6db89c, 0x1f8e531b), + TOBN(0x34fe3fd6, 0xca563a44), TOBN(0x7f5c2215, 0x58da8ab9), + TOBN(0x8445016d, 0x9474f0a1), TOBN(0x17d34d61, 0xcb7d8a0a), + TOBN(0x8e9d3910, 0x1c474019), TOBN(0xcaff2629, 0xd52ceefb), + TOBN(0xf9cf3e32, 0xc1622c2b), TOBN(0xd4b95e3c, 0xe9071a05), + TOBN(0xfbbca61f, 0x1594438c), TOBN(0x1eb6e6a6, 0x04aadedf), + TOBN(0x853027f4, 0x68e14940), TOBN(0x221d322a, 0xdfabda9c), + TOBN(0xed8ea9f6, 0xb7cb179a), TOBN(0xdc7b764d, 0xb7934dcc), + TOBN(0xfcb13940, 0x5e09180d), TOBN(0x6629a6bf, 0xb47dc2dd), + TOBN(0xbfc55e4e, 0x9f5a915e), TOBN(0xb1db9d37, 0x6204441e), + TOBN(0xf82d68cf, 0x930c5f53), TOBN(0x17d3a142, 0xcbb605b1), + TOBN(0xdd5944ea, 0x308780f2), TOBN(0xdc8de761, 0x3845f5e4), + TOBN(0x6beaba7d, 0x7624d7a3), TOBN(0x1e709afd, 0x304df11e), + TOBN(0x95364376, 0x02170456), TOBN(0xbf204b3a, 0xc8f94b64), + TOBN(0x4e53af7c, 0x5680ca68), TOBN(0x0526074a, 0xe0c67574), + TOBN(0x95d8cef8, 0xecd92af6), TOBN(0xe6b9fa7a, 0x6cd1745a), + TOBN(0x3d546d3d, 0xa325c3e4), TOBN(0x1f57691d, 0x9ae93aae), + TOBN(0xe891f3fe, 0x9d2e1a33), TOBN(0xd430093f, 0xac063d35), + TOBN(0xeda59b12, 0x5513a327), TOBN(0xdc2134f3, 0x5536f18f), + TOBN(0xaa51fe2c, 0x5c210286), TOBN(0x3f68aaee, 0x1cab658c), + TOBN(0x5a23a00b, 0xf9357292), TOBN(0x9a626f39, 0x7efdabed), + TOBN(0xfe2b3bf3, 0x199d78e3), TOBN(0xb7a2af77, 0x71bbc345), + TOBN(0x3d19827a, 0x1e59802c), TOBN(0x823bbc15, 0xb487a51c), + TOBN(0x856139f2, 0x99d0a422), TOBN(0x9ac3df65, 0xf456c6fb), + TOBN(0xaddf65c6, 0x701f8bd6), TOBN(0x149f321e, 0x3758df87), + TOBN(0xb1ecf714, 0x721b7eba), TOBN(0xe17df098, 0x31a3312a), + TOBN(0xdb2fd6ec, 0xd5c4d581), TOBN(0xfd02996f, 0x8fcea1b3), + TOBN(0xe29fa63e, 0x7882f14f), TOBN(0xc9f6dc35, 0x07c6cadc), + TOBN(0x46f22d6f, 0xb882bed0), TOBN(0x1a45755b, 0xd118e52c), + TOBN(0x9f2c7c27, 0x7c4608cf), TOBN(0x7ccbdf32, 0x568012c2), + TOBN(0xfcb0aedd, 0x61729b0e), TOBN(0x7ca2ca9e, 0xf7d75dbf), + TOBN(0xf58fecb1, 0x6f640f62), TOBN(0xe274b92b, 0x39f51946), + TOBN(0x7f4dfc04, 0x6288af44), TOBN(0x0a91f32a, 0xeac329e5), + TOBN(0x43ad274b, 0xd6aaba31), TOBN(0x719a1640, 0x0f6884f9), + TOBN(0x685d29f6, 0xdaf91e20), TOBN(0x5ec1cc33, 0x27e49d52), + TOBN(0x38f4de96, 0x3b54a059), TOBN(0x0e0015e5, 0xefbcfdb3), + TOBN(0x177d23d9, 0x4dbb8da6), TOBN(0x98724aa2, 0x97a617ad), + TOBN(0x30f0885b, 0xfdb6558e), TOBN(0xf9f7a28a, 0xc7899a96), + TOBN(0xd2ae8ac8, 0x872dc112), TOBN(0xfa0642ca, 0x73c3c459), + TOBN(0x15296981, 0xe7dfc8d6), TOBN(0x67cd4450, 0x1fb5b94a), + TOBN(0x0ec71cf1, 0x0eddfd37), TOBN(0xc7e5eeb3, 0x9a8eddc7), + TOBN(0x02ac8e3d, 0x81d95028), TOBN(0x0088f172, 0x70b0e35d), + TOBN(0xec041fab, 0xe1881fe3), TOBN(0x62cf71b8, 0xd99e7faa), + TOBN(0x5043dea7, 0xe0f222c2), TOBN(0x309d42ac, 0x72e65142), + TOBN(0x94fe9ddd, 0x9216cd30), TOBN(0xd6539c7d, 0x0f87feec), + TOBN(0x03c5a57c, 0x432ac7d7), TOBN(0x72692cf0, 0x327fda10), + TOBN(0xec28c85f, 0x280698de), TOBN(0x2331fb46, 0x7ec283b1), + TOBN(0xd34bfa32, 0x2867e633), TOBN(0x78709a82, 0x0a9cc815), + TOBN(0xb7fe6964, 0x875e2fa5), TOBN(0x25cc064f, 0x9e98bfb5), + TOBN(0x9eb0151c, 0x493a65c5), TOBN(0x5fb5d941, 0x53182464), + TOBN(0x69e6f130, 0xf04618e2), TOBN(0xa8ecec22, 0xf89c8ab6), + TOBN(0xcd6ac88b, 0xb96209bd), TOBN(0x65fa8cdb, 0xb3e1c9e0), + TOBN(0xa47d22f5, 0x4a8d8eac), TOBN(0x83895cdf, 0x8d33f963), + TOBN(0xa8adca59, 0xb56cd3d1), TOBN(0x10c8350b, 0xdaf38232), + TOBN(0x2b161fb3, 0xa5080a9f), TOBN(0xbe7f5c64, 0x3af65b3a), + TOBN(0x2c754039, 0x97403a11), TOBN(0x94626cf7, 0x121b96af), + TOBN(0x431de7c4, 0x6a983ec2), TOBN(0x3780dd3a, 0x52cc3df7), + TOBN(0xe28a0e46, 0x2baf8e3b), TOBN(0xabe68aad, 0x51d299ae), + TOBN(0x603eb8f9, 0x647a2408), TOBN(0x14c61ed6, 0x5c750981), + TOBN(0x88b34414, 0xc53352e7), TOBN(0x5a34889c, 0x1337d46e), + TOBN(0x612c1560, 0xf95f2bc8), TOBN(0x8a3f8441, 0xd4807a3a), + TOBN(0x680d9e97, 0x5224da68), TOBN(0x60cd6e88, 0xc3eb00e9), + TOBN(0x3875a98e, 0x9a6bc375), TOBN(0xdc80f924, 0x4fd554c2), + TOBN(0x6c4b3415, 0x6ac77407), TOBN(0xa1e5ea8f, 0x25420681), + TOBN(0x541bfa14, 0x4607a458), TOBN(0x5dbc7e7a, 0x96d7fbf9), + TOBN(0x646a851b, 0x31590a47), TOBN(0x039e85ba, 0x15ee6df8), + TOBN(0xd19fa231, 0xd7b43fc0), TOBN(0x84bc8be8, 0x299a0e04), + TOBN(0x2b9d2936, 0xf20df03a), TOBN(0x24054382, 0x8608d472), + TOBN(0x76b6ba04, 0x9149202a), TOBN(0xb21c3831, 0x3670e7b7), + TOBN(0xddd93059, 0xd6fdee10), TOBN(0x9da47ad3, 0x78488e71), + TOBN(0x99cc1dfd, 0xa0fcfb25), TOBN(0x42abde10, 0x64696954), + TOBN(0x14cc15fc, 0x17eab9fe), TOBN(0xd6e863e4, 0xd3e70972), + TOBN(0x29a7765c, 0x6432112c), TOBN(0x88660001, 0x5b0774d8), + TOBN(0x3729175a, 0x2c088eae), TOBN(0x13afbcae, 0x8230b8d4), + TOBN(0x44768151, 0x915f4379), TOBN(0xf086431a, 0xd8d22812), + TOBN(0x37461955, 0xc298b974), TOBN(0x905fb5f0, 0xf8711e04), + TOBN(0x787abf3a, 0xfe969d18), TOBN(0x392167c2, 0x6f6a494e), + TOBN(0xfc7a0d2d, 0x28c511da), TOBN(0xf127c7dc, 0xb66a262d), + TOBN(0xf9c4bb95, 0xfd63fdf0), TOBN(0x90016589, 0x3913ef46), + TOBN(0x74d2a73c, 0x11aa600d), TOBN(0x2f5379bd, 0x9fb5ab52), + TOBN(0xe49e53a4, 0x7fb70068), TOBN(0x68dd39e5, 0x404aa9a7), + TOBN(0xb9b0cf57, 0x2ecaa9c3), TOBN(0xba0e103b, 0xe824826b), + TOBN(0x60c2198b, 0x4631a3c4), TOBN(0xc5ff84ab, 0xfa8966a2), + TOBN(0x2d6ebe22, 0xac95aff8), TOBN(0x1c9bb6db, 0xb5a46d09), + TOBN(0x419062da, 0x53ee4f8d), TOBN(0x7b9042d0, 0xbb97efef), + TOBN(0x0f87f080, 0x830cf6bd), TOBN(0x4861d19a, 0x6ec8a6c6), + TOBN(0xd3a0daa1, 0x202f01aa), TOBN(0xb0111674, 0xf25afbd5), + TOBN(0x6d00d6cf, 0x1afb20d9), TOBN(0x13695000, 0x40671bc5), + TOBN(0x913ab0dc, 0x2485ea9b), TOBN(0x1f2bed06, 0x9eef61ac), + TOBN(0x850c8217, 0x6d799e20), TOBN(0x93415f37, 0x3271c2de), + TOBN(0x5afb06e9, 0x6c4f5910), TOBN(0x688a52df, 0xc4e9e421), + TOBN(0x30495ba3, 0xe2a9a6db), TOBN(0x4601303d, 0x58f9268b), + TOBN(0xbe3b0dad, 0x7eb0f04f), TOBN(0x4ea47250, 0x4456936d), + TOBN(0x8caf8798, 0xd33fd3e7), TOBN(0x1ccd8a89, 0xeb433708), + TOBN(0x9effe3e8, 0x87fd50ad), TOBN(0xbe240a56, 0x6b29c4df), + TOBN(0xec4ffd98, 0xca0e7ebd), TOBN(0xf586783a, 0xe748616e), + TOBN(0xa5b00d8f, 0xc77baa99), TOBN(0x0acada29, 0xb4f34c9c), + TOBN(0x36dad67d, 0x0fe723ac), TOBN(0x1d8e53a5, 0x39c36c1e), + TOBN(0xe4dd342d, 0x1f4bea41), TOBN(0x64fd5e35, 0xebc9e4e0), + TOBN(0x96f01f90, 0x57908805), TOBN(0xb5b9ea3d, 0x5ed480dd), + TOBN(0x366c5dc2, 0x3efd2dd0), TOBN(0xed2fe305, 0x6e9dfa27), + TOBN(0x4575e892, 0x6e9197e2), TOBN(0x11719c09, 0xab502a5d), + TOBN(0x264c7bec, 0xe81f213f), TOBN(0x741b9241, 0x55f5c457), + TOBN(0x78ac7b68, 0x49a5f4f4), TOBN(0xf91d70a2, 0x9fc45b7d), + TOBN(0x39b05544, 0xb0f5f355), TOBN(0x11f06bce, 0xeef930d9), + TOBN(0xdb84d25d, 0x038d05e1), TOBN(0x04838ee5, 0xbacc1d51), + TOBN(0x9da3ce86, 0x9e8ee00b), TOBN(0xc3412057, 0xc36eda1f), + TOBN(0xae80b913, 0x64d9c2f4), TOBN(0x7468bac3, 0xa010a8ff), + TOBN(0xdfd20037, 0x37359d41), TOBN(0x1a0f5ab8, 0x15efeacc), + TOBN(0x7c25ad2f, 0x659d0ce0), TOBN(0x4011bcbb, 0x6785cff1), + TOBN(0x128b9912, 0x7e2192c7), TOBN(0xa549d8e1, 0x13ccb0e8), + TOBN(0x805588d8, 0xc85438b1), TOBN(0x5680332d, 0xbc25cb27), + TOBN(0xdcd1bc96, 0x1a4bfdf4), TOBN(0x779ff428, 0x706f6566), + TOBN(0x8bbee998, 0xf059987a), TOBN(0xf6ce8cf2, 0xcc686de7), + TOBN(0xf8ad3c4a, 0x953cfdb2), TOBN(0xd1d426d9, 0x2205da36), + TOBN(0xb3c0f13f, 0xc781a241), TOBN(0x3e89360e, 0xd75362a8), + TOBN(0xccd05863, 0xc8a91184), TOBN(0x9bd0c9b7, 0xefa8a7f4), + TOBN(0x97ee4d53, 0x8a912a4b), TOBN(0xde5e15f8, 0xbcf518fd), + TOBN(0x6a055bf8, 0xc467e1e0), TOBN(0x10be4b4b, 0x1587e256), + TOBN(0xd90c14f2, 0x668621c9), TOBN(0xd5518f51, 0xab9c92c1), + TOBN(0x8e6a0100, 0xd6d47b3c), TOBN(0xcbe980dd, 0x66716175), + TOBN(0x500d3f10, 0xddd83683), TOBN(0x3b6cb35d, 0x99cac73c), + TOBN(0x53730c8b, 0x6083d550), TOBN(0xcf159767, 0xdf0a1987), + TOBN(0x84bfcf53, 0x43ad73b3), TOBN(0x1b528c20, 0x4f035a94), + TOBN(0x4294edf7, 0x33eeac69), TOBN(0xb6283e83, 0x817f3240), + TOBN(0xc3fdc959, 0x0a5f25b1), TOBN(0xefaf8aa5, 0x5844ee22), + TOBN(0xde269ba5, 0xdbdde4de), TOBN(0xe3347160, 0xc56133bf), + TOBN(0xc1184219, 0x8d9ea9f8), TOBN(0x090de5db, 0xf3fc1ab5), + TOBN(0x404c37b1, 0x0bf22cda), TOBN(0x7de20ec8, 0xf5618894), + TOBN(0x754c588e, 0xecdaecab), TOBN(0x6ca4b0ed, 0x88342743), + TOBN(0x76f08bdd, 0xf4a938ec), TOBN(0xd182de89, 0x91493ccb), + TOBN(0xd652c53e, 0xc8a4186a), TOBN(0xb3e878db, 0x946d8e33), + TOBN(0x088453c0, 0x5f37663c), TOBN(0x5cd9daaa, 0xb407748b), + TOBN(0xa1f5197f, 0x586d5e72), TOBN(0x47500be8, 0xc443ca59), + TOBN(0x78ef35b2, 0xe2652424), TOBN(0x09c5d26f, 0x6dd7767d), + TOBN(0x7175a79a, 0xa74d3f7b), TOBN(0x0428fd8d, 0xcf5ea459), + TOBN(0x511cb97c, 0xa5d1746d), TOBN(0x36363939, 0xe71d1278), + TOBN(0xcf2df955, 0x10350bf4), TOBN(0xb3817439, 0x60aae782), + TOBN(0xa748c0e4, 0x3e688809), TOBN(0x98021fbf, 0xd7a5a006), + TOBN(0x9076a70c, 0x0e367a98), TOBN(0xbea1bc15, 0x0f62b7c2), + TOBN(0x2645a68c, 0x30fe0343), TOBN(0xacaffa78, 0x699dc14f), + TOBN(0xf4469964, 0x457bf9c4), TOBN(0x0db6407b, 0x0d2ead83), + TOBN(0x68d56cad, 0xb2c6f3eb), TOBN(0x3b512e73, 0xf376356c), + TOBN(0xe43b0e1f, 0xfce10408), TOBN(0x89ddc003, 0x5a5e257d), + TOBN(0xb0ae0d12, 0x0362e5b3), TOBN(0x07f983c7, 0xb0519161), + TOBN(0xc2e94d15, 0x5d5231e7), TOBN(0xcff22aed, 0x0b4f9513), + TOBN(0xb02588dd, 0x6ad0b0b5), TOBN(0xb967d1ac, 0x11d0dcd5), + TOBN(0x8dac6bc6, 0xcf777b6c), TOBN(0x0062bdbd, 0x4c6d1959), + TOBN(0x53da71b5, 0x0ef5cc85), TOBN(0x07012c7d, 0x4006f14f), + TOBN(0x4617f962, 0xac47800d), TOBN(0x53365f2b, 0xc102ed75), + TOBN(0xb422efcb, 0x4ab8c9d3), TOBN(0x195cb26b, 0x34af31c9), + TOBN(0x3a926e29, 0x05f2c4ce), TOBN(0xbd2bdecb, 0x9856966c), + TOBN(0x5d16ab3a, 0x85527015), TOBN(0x9f81609e, 0x4486c231), + TOBN(0xd8b96b2c, 0xda350002), TOBN(0xbd054690, 0xfa1b7d36), + TOBN(0xdc90ebf5, 0xe71d79bc), TOBN(0xf241b6f9, 0x08964e4e), + TOBN(0x7c838643, 0x2fe3cd4c), TOBN(0xe0f33acb, 0xb4bc633c), + TOBN(0xb4a9ecec, 0x3d139f1f), TOBN(0x05ce69cd, 0xdc4a1f49), + TOBN(0xa19d1b16, 0xf5f98aaf), TOBN(0x45bb71d6, 0x6f23e0ef), + TOBN(0x33789fcd, 0x46cdfdd3), TOBN(0x9b8e2978, 0xcee040ca), + TOBN(0x9c69b246, 0xae0a6828), TOBN(0xba533d24, 0x7078d5aa), + TOBN(0x7a2e42c0, 0x7bb4fbdb), TOBN(0xcfb4879a, 0x7035385c), + TOBN(0x8c3dd30b, 0x3281705b), TOBN(0x7e361c6c, 0x404fe081), + TOBN(0x7b21649c, 0x3f604edf), TOBN(0x5dbf6a3f, 0xe52ffe47), + TOBN(0xc41b7c23, 0x4b54d9bf), TOBN(0x1374e681, 0x3511c3d9), + TOBN(0x1863bf16, 0xc1b2b758), TOBN(0x90e78507, 0x1e9e6a96), + TOBN(0xab4bf98d, 0x5d86f174), TOBN(0xd74e0bd3, 0x85e96fe4), + TOBN(0x8afde39f, 0xcac5d344), TOBN(0x90946dbc, 0xbd91b847), + TOBN(0xf5b42358, 0xfe1a838c), TOBN(0x05aae6c5, 0x620ac9d8), + TOBN(0x8e193bd8, 0xa1ce5a0b), TOBN(0x8f710571, 0x4dabfd72), + TOBN(0x8d8fdd48, 0x182caaac), TOBN(0x8c4aeefa, 0x040745cf), + TOBN(0x73c6c30a, 0xf3b93e6d), TOBN(0x991241f3, 0x16f42011), + TOBN(0xa0158eea, 0xe457a477), TOBN(0xd19857db, 0xee6ddc05), + TOBN(0xb3265224, 0x18c41671), TOBN(0x3ffdfc7e, 0x3c2c0d58), + TOBN(0x3a3a5254, 0x26ee7cda), TOBN(0x341b0869, 0xdf02c3a8), + TOBN(0xa023bf42, 0x723bbfc8), TOBN(0x3d15002a, 0x14452691)}, + {TOBN(0x5ef7324c, 0x85edfa30), TOBN(0x25976554, 0x87d4f3da), + TOBN(0x352f5bc0, 0xdcb50c86), TOBN(0x8f6927b0, 0x4832a96c), + TOBN(0xd08ee1ba, 0x55f2f94c), TOBN(0x6a996f99, 0x344b45fa), + TOBN(0xe133cb8d, 0xa8aa455d), TOBN(0x5d0721ec, 0x758dc1f7), + TOBN(0x6ba7a920, 0x79e5fb67), TOBN(0xe1331feb, 0x70aa725e), + TOBN(0x5080ccf5, 0x7df5d837), TOBN(0xe4cae01d, 0x7ff72e21), + TOBN(0xd9243ee6, 0x0412a77d), TOBN(0x06ff7cac, 0xdf449025), + TOBN(0xbe75f7cd, 0x23ef5a31), TOBN(0xbc957822, 0x0ddef7a8), + TOBN(0x8cf7230c, 0xb0ce1c55), TOBN(0x5b534d05, 0x0bbfb607), + TOBN(0xee1ef113, 0x0e16363b), TOBN(0x27e0aa7a, 0xb4999e82), + TOBN(0xce1dac2d, 0x79362c41), TOBN(0x67920c90, 0x91bb6cb0), + TOBN(0x1e648d63, 0x2223df24), TOBN(0x0f7d9eef, 0xe32e8f28), + TOBN(0x6943f39a, 0xfa833834), TOBN(0x22951722, 0xa6328562), + TOBN(0x81d63dd5, 0x4170fc10), TOBN(0x9f5fa58f, 0xaecc2e6d), + TOBN(0xb66c8725, 0xe77d9a3b), TOBN(0x11235cea, 0x6384ebe0), + TOBN(0x06a8c118, 0x5845e24a), TOBN(0x0137b286, 0xebd093b1), + TOBN(0xc589e1ce, 0x44ace150), TOBN(0xe0f8d3d9, 0x4381e97c), + TOBN(0x59e99b11, 0x62c5a4b8), TOBN(0x90d262f7, 0xfd0ec9f9), + TOBN(0xfbc854c9, 0x283e13c9), TOBN(0x2d04fde7, 0xaedc7085), + TOBN(0x057d7765, 0x47dcbecb), TOBN(0x8dbdf591, 0x9a76fa5f), + TOBN(0xd0150695, 0x0de1e578), TOBN(0x2e1463e7, 0xe9f72bc6), + TOBN(0xffa68441, 0x1b39eca5), TOBN(0x673c8530, 0x7c037f2f), + TOBN(0xd0d6a600, 0x747f91da), TOBN(0xb08d43e1, 0xc9cb78e9), + TOBN(0x0fc0c644, 0x27b5cef5), TOBN(0x5c1d160a, 0xa60a2fd6), + TOBN(0xf98cae53, 0x28c8e13b), TOBN(0x375f10c4, 0xb2eddcd1), + TOBN(0xd4eb8b7f, 0x5cce06ad), TOBN(0xb4669f45, 0x80a2e1ef), + TOBN(0xd593f9d0, 0x5bbd8699), TOBN(0x5528a4c9, 0xe7976d13), + TOBN(0x3923e095, 0x1c7e28d3), TOBN(0xb9293790, 0x3f6bb577), + TOBN(0xdb567d6a, 0xc42bd6d2), TOBN(0x6df86468, 0xbb1f96ae), + TOBN(0x0efe5b1a, 0x4843b28e), TOBN(0x961bbb05, 0x6379b240), + TOBN(0xb6caf5f0, 0x70a6a26b), TOBN(0x70686c0d, 0x328e6e39), + TOBN(0x80da06cf, 0x895fc8d3), TOBN(0x804d8810, 0xb363fdc9), + TOBN(0xbe22877b, 0x207f1670), TOBN(0x9b0dd188, 0x4e615291), + TOBN(0x625ae8dc, 0x97a3c2bf), TOBN(0x08584ef7, 0x439b86e8), + TOBN(0xde7190a5, 0xdcd898ff), TOBN(0x26286c40, 0x2058ee3d), + TOBN(0x3db0b217, 0x5f87b1c1), TOBN(0xcc334771, 0x102a6db5), + TOBN(0xd99de954, 0x2f770fb1), TOBN(0x97c1c620, 0x4cd7535e), + TOBN(0xd3b6c448, 0x3f09cefc), TOBN(0xd725af15, 0x5a63b4f8), + TOBN(0x0c95d24f, 0xc01e20ec), TOBN(0xdfd37494, 0x9ae7121f), + TOBN(0x7d6ddb72, 0xec77b7ec), TOBN(0xfe079d3b, 0x0353a4ae), + TOBN(0x3066e70a, 0x2e6ac8d2), TOBN(0x9c6b5a43, 0x106e5c05), + TOBN(0x52d3c6f5, 0xede59b8c), TOBN(0x30d6a5c3, 0xfccec9ae), + TOBN(0xedec7c22, 0x4fc0a9ef), TOBN(0x190ff083, 0x95c16ced), + TOBN(0xbe12ec8f, 0x94de0fde), TOBN(0x0d131ab8, 0x852d3433), + TOBN(0x42ace07e, 0x85701291), TOBN(0x94793ed9, 0x194061a8), + TOBN(0x30e83ed6, 0xd7f4a485), TOBN(0x9eec7269, 0xf9eeff4d), + TOBN(0x90acba59, 0x0c9d8005), TOBN(0x5feca458, 0x1e79b9d1), + TOBN(0x8fbe5427, 0x1d506a1e), TOBN(0xa32b2c8e, 0x2439cfa7), + TOBN(0x1671c173, 0x73dd0b4e), TOBN(0x37a28214, 0x44a054c6), + TOBN(0x81760a1b, 0x4e8b53f1), TOBN(0xa6c04224, 0xf9f93b9e), + TOBN(0x18784b34, 0xcf671e3c), TOBN(0x81bbecd2, 0xcda9b994), + TOBN(0x38831979, 0xb2ab3848), TOBN(0xef54feb7, 0xf2e03c2d), + TOBN(0xcf197ca7, 0xfb8088fa), TOBN(0x01427247, 0x4ddc96c5), + TOBN(0xa2d2550a, 0x30777176), TOBN(0x53469898, 0x4d0cf71d), + TOBN(0x6ce937b8, 0x3a2aaac6), TOBN(0xe9f91dc3, 0x5af38d9b), + TOBN(0x2598ad83, 0xc8bf2899), TOBN(0x8e706ac9, 0xb5536c16), + TOBN(0x40dc7495, 0xf688dc98), TOBN(0x26490cd7, 0x124c4afc), + TOBN(0xe651ec84, 0x1f18775c), TOBN(0x393ea6c3, 0xb4fdaf4a), + TOBN(0x1e1f3343, 0x7f338e0d), TOBN(0x39fb832b, 0x6053e7b5), + TOBN(0x46e702da, 0x619e14d5), TOBN(0x859cacd1, 0xcdeef6e0), + TOBN(0x63b99ce7, 0x4462007d), TOBN(0xb8ab48a5, 0x4cb5f5b7), + TOBN(0x9ec673d2, 0xf55edde7), TOBN(0xd1567f74, 0x8cfaefda), + TOBN(0x46381b6b, 0x0887bcec), TOBN(0x694497ce, 0xe178f3c2), + TOBN(0x5e6525e3, 0x1e6266cb), TOBN(0x5931de26, 0x697d6413), + TOBN(0x87f8df7c, 0x0e58d493), TOBN(0xb1ae5ed0, 0x58b73f12), + TOBN(0xc368f784, 0xdea0c34d), TOBN(0x9bd0a120, 0x859a91a0), + TOBN(0xb00d88b7, 0xcc863c68), TOBN(0x3a1cc11e, 0x3d1f4d65), + TOBN(0xea38e0e7, 0x0aa85593), TOBN(0x37f13e98, 0x7dc4aee8), + TOBN(0x10d38667, 0xbc947bad), TOBN(0x738e07ce, 0x2a36ee2e), + TOBN(0xc93470cd, 0xc577fcac), TOBN(0xdee1b616, 0x2782470d), + TOBN(0x36a25e67, 0x2e793d12), TOBN(0xd6aa6cae, 0xe0f186da), + TOBN(0x474d0fd9, 0x80e07af7), TOBN(0xf7cdc47d, 0xba8a5cd4), + TOBN(0x28af6d9d, 0xab15247f), TOBN(0x7c789c10, 0x493a537f), + TOBN(0x7ac9b110, 0x23a334e7), TOBN(0x0236ac09, 0x12c9c277), + TOBN(0xa7e5bd25, 0x1d7a5144), TOBN(0x098b9c2a, 0xf13ec4ec), + TOBN(0x3639daca, 0xd3f0abca), TOBN(0x642da81a, 0xa23960f9), + TOBN(0x7d2e5c05, 0x4f7269b1), TOBN(0xfcf30777, 0xe287c385), + TOBN(0x10edc84f, 0xf2a46f21), TOBN(0x35441757, 0x4f43fa36), + TOBN(0xf1327899, 0xfd703431), TOBN(0xa438d7a6, 0x16dd587a), + TOBN(0x65c34c57, 0xe9c8352d), TOBN(0xa728edab, 0x5cc5a24e), + TOBN(0xaed78abc, 0x42531689), TOBN(0x0a51a0e8, 0x010963ef), + TOBN(0x5776fa0a, 0xd717d9b3), TOBN(0xf356c239, 0x7dd3428b), + TOBN(0x29903fff, 0x8d3a3dac), TOBN(0x409597fa, 0x3d94491f), + TOBN(0x4cd7a5ff, 0xbf4a56a4), TOBN(0xe5096474, 0x8adab462), + TOBN(0xa97b5126, 0x5c3427b0), TOBN(0x6401405c, 0xd282c9bd), + TOBN(0x3629f8d7, 0x222c5c45), TOBN(0xb1c02c16, 0xe8d50aed), + TOBN(0xbea2ed75, 0xd9635bc9), TOBN(0x226790c7, 0x6e24552f), + TOBN(0x3c33f2a3, 0x65f1d066), TOBN(0x2a43463e, 0x6dfccc2e), + TOBN(0x8cc3453a, 0xdb483761), TOBN(0xe7cc6085, 0x65d5672b), + TOBN(0x277ed6cb, 0xde3efc87), TOBN(0x19f2f368, 0x69234eaf), + TOBN(0x9aaf4317, 0x5c0b800b), TOBN(0x1f1e7c89, 0x8b6da6e2), + TOBN(0x6cfb4715, 0xb94ec75e), TOBN(0xd590dd5f, 0x453118c2), + TOBN(0x14e49da1, 0x1f17a34c), TOBN(0x5420ab39, 0x235a1456), + TOBN(0xb7637241, 0x2f50363b), TOBN(0x7b15d623, 0xc3fabb6e), + TOBN(0xa0ef40b1, 0xe274e49c), TOBN(0x5cf50744, 0x96b1860a), + TOBN(0xd6583fbf, 0x66afe5a4), TOBN(0x44240510, 0xf47e3e9a), + TOBN(0x99254343, 0x11b2d595), TOBN(0xf1367499, 0xeec8df57), + TOBN(0x3cb12c61, 0x3e73dd05), TOBN(0xd248c033, 0x7dac102a), + TOBN(0xcf154f13, 0xa77739f5), TOBN(0xbf4288cb, 0x23d2af42), + TOBN(0xaa64c9b6, 0x32e4a1cf), TOBN(0xee8c07a8, 0xc8a208f3), + TOBN(0xe10d4999, 0x6fe8393f), TOBN(0x0f809a3f, 0xe91f3a32), + TOBN(0x61096d1c, 0x802f63c8), TOBN(0x289e1462, 0x57750d3d), + TOBN(0xed06167e, 0x9889feea), TOBN(0xd5c9c0e2, 0xe0993909), + TOBN(0x46fca0d8, 0x56508ac6), TOBN(0x91826047, 0x4f1b8e83), + TOBN(0x4f2c877a, 0x9a4a2751), TOBN(0x71bd0072, 0xcae6fead), + TOBN(0x38df8dcc, 0x06aa1941), TOBN(0x5a074b4c, 0x63beeaa8), + TOBN(0xd6d65934, 0xc1cec8ed), TOBN(0xa6ecb49e, 0xaabc03bd), + TOBN(0xaade91c2, 0xde8a8415), TOBN(0xcfb0efdf, 0x691136e0), + TOBN(0x11af45ee, 0x23ab3495), TOBN(0xa132df88, 0x0b77463d), + TOBN(0x8923c15c, 0x815d06f4), TOBN(0xc3ceb3f5, 0x0d61a436), + TOBN(0xaf52291d, 0xe88fb1da), TOBN(0xea057974, 0x1da12179), + TOBN(0xb0d7218c, 0xd2fef720), TOBN(0x6c0899c9, 0x8e1d8845), + TOBN(0x98157504, 0x752ddad7), TOBN(0xd60bd74f, 0xa1a68a97), + TOBN(0x7047a3a9, 0xf658fb99), TOBN(0x1f5d86d6, 0x5f8511e4), + TOBN(0xb8a4bc42, 0x4b5a6d88), TOBN(0x69eb2c33, 0x1abefa7d), + TOBN(0x95bf39e8, 0x13c9c510), TOBN(0xf571960a, 0xd48aab43), + TOBN(0x7e8cfbcf, 0x704e23c6), TOBN(0xc71b7d22, 0x28aaa65b), + TOBN(0xa041b2bd, 0x245e3c83), TOBN(0x69b98834, 0xd21854ff), + TOBN(0x89d227a3, 0x963bfeec), TOBN(0x99947aaa, 0xde7da7cb), + TOBN(0x1d9ee9db, 0xee68a9b1), TOBN(0x0a08f003, 0x698ec368), + TOBN(0xe9ea4094, 0x78ef2487), TOBN(0xc8d2d415, 0x02cfec26), + TOBN(0xc52f9a6e, 0xb7dcf328), TOBN(0x0ed489e3, 0x85b6a937), + TOBN(0x9b94986b, 0xbef3366e), TOBN(0x0de59c70, 0xedddddb8), + TOBN(0xffdb748c, 0xeadddbe2), TOBN(0x9b9784bb, 0x8266ea40), + TOBN(0x142b5502, 0x1a93507a), TOBN(0xb4cd1187, 0x8d3c06cf), + TOBN(0xdf70e76a, 0x91ec3f40), TOBN(0x484e81ad, 0x4e7553c2), + TOBN(0x830f87b5, 0x272e9d6e), TOBN(0xea1c93e5, 0xc6ff514a), + TOBN(0x67cc2adc, 0xc4192a8e), TOBN(0xc77e27e2, 0x42f4535a), + TOBN(0x9cdbab36, 0xd2b713c5), TOBN(0x86274ea0, 0xcf7b0cd3), + TOBN(0x784680f3, 0x09af826b), TOBN(0xbfcc837a, 0x0c72dea3), + TOBN(0xa8bdfe9d, 0xd6529b73), TOBN(0x708aa228, 0x63a88002), + TOBN(0x6c7a9a54, 0xc91d45b9), TOBN(0xdf1a38bb, 0xfd004f56), + TOBN(0x2e8c9a26, 0xb8bad853), TOBN(0x2d52cea3, 0x3723eae7), + TOBN(0x054d6d81, 0x56ca2830), TOBN(0xa3317d14, 0x9a8dc411), + TOBN(0xa08662fe, 0xfd4ddeda), TOBN(0xed2a153a, 0xb55d792b), + TOBN(0x7035c16a, 0xbfc6e944), TOBN(0xb6bc5834, 0x00171cf3), + TOBN(0xe27152b3, 0x83d102b6), TOBN(0xfe695a47, 0x0646b848), + TOBN(0xa5bb09d8, 0x916e6d37), TOBN(0xb4269d64, 0x0d17015e), + TOBN(0x8d8156a1, 0x0a1d2285), TOBN(0xfeef6c51, 0x46d26d72), + TOBN(0x9dac57c8, 0x4c5434a7), TOBN(0x0282e5be, 0x59d39e31), + TOBN(0xedfff181, 0x721c486d), TOBN(0x301baf10, 0xbc58824e), + TOBN(0x8136a6aa, 0x00570031), TOBN(0x55aaf78c, 0x1cddde68), + TOBN(0x26829371, 0x59c63952), TOBN(0x3a3bd274, 0x8bc25baf), + TOBN(0xecdf8657, 0xb7e52dc3), TOBN(0x2dd8c087, 0xfd78e6c8), + TOBN(0x20553274, 0xf5531461), TOBN(0x8b4a1281, 0x5d95499b), + TOBN(0xe2c8763a, 0x1a80f9d2), TOBN(0xd1dbe32b, 0x4ddec758), + TOBN(0xaf12210d, 0x30c34169), TOBN(0xba74a953, 0x78baa533), + TOBN(0x3d133c6e, 0xa438f254), TOBN(0xa431531a, 0x201bef5b), + TOBN(0x15295e22, 0xf669d7ec), TOBN(0xca374f64, 0x357fb515), + TOBN(0x8a8406ff, 0xeaa3fdb3), TOBN(0x106ae448, 0xdf3f2da8), + TOBN(0x8f9b0a90, 0x33c8e9a1), TOBN(0x234645e2, 0x71ad5885), + TOBN(0x3d083224, 0x1c0aed14), TOBN(0xf10a7d3e, 0x7a942d46), + TOBN(0x7c11deee, 0x40d5c9be), TOBN(0xb2bae7ff, 0xba84ed98), + TOBN(0x93e97139, 0xaad58ddd), TOBN(0x3d872796, 0x3f6d1fa3), + TOBN(0x483aca81, 0x8569ff13), TOBN(0x8b89a5fb, 0x9a600f72), + TOBN(0x4cbc27c3, 0xc06f2b86), TOBN(0x22130713, 0x63ad9c0b), + TOBN(0xb5358b1e, 0x48ac2840), TOBN(0x18311294, 0xecba9477), + TOBN(0xda58f990, 0xa6946b43), TOBN(0x3098baf9, 0x9ab41819), + TOBN(0x66c4c158, 0x4198da52), TOBN(0xab4fc17c, 0x146bfd1b), + TOBN(0x2f0a4c3c, 0xbf36a908), TOBN(0x2ae9e34b, 0x58cf7838), + TOBN(0xf411529e, 0x3fa11b1f), TOBN(0x21e43677, 0x974af2b4), + TOBN(0x7c20958e, 0xc230793b), TOBN(0x710ea885, 0x16e840f3), + TOBN(0xfc0b21fc, 0xc5dc67cf), TOBN(0x08d51647, 0x88405718), + TOBN(0xd955c21f, 0xcfe49eb7), TOBN(0x9722a5d5, 0x56dd4a1f), + TOBN(0xc9ef50e2, 0xc861baa5), TOBN(0xc0c21a5d, 0x9505ac3e), + TOBN(0xaf6b9a33, 0x8b7c063f), TOBN(0xc6370339, 0x2f4779c1), + TOBN(0x22df99c7, 0x638167c3), TOBN(0xfe6ffe76, 0x795db30c), + TOBN(0x2b822d33, 0xa4854989), TOBN(0xfef031dd, 0x30563aa5), + TOBN(0x16b09f82, 0xd57c667f), TOBN(0xc70312ce, 0xcc0b76f1), + TOBN(0xbf04a9e6, 0xc9118aec), TOBN(0x82fcb419, 0x3409d133), + TOBN(0x1a8ab385, 0xab45d44d), TOBN(0xfba07222, 0x617b83a3), + TOBN(0xb05f50dd, 0x58e81b52), TOBN(0x1d8db553, 0x21ce5aff), + TOBN(0x3097b8d4, 0xe344a873), TOBN(0x7d8d116d, 0xfe36d53e), + TOBN(0x6db22f58, 0x7875e750), TOBN(0x2dc5e373, 0x43e144ea), + TOBN(0xc05f32e6, 0xe799eb95), TOBN(0xe9e5f4df, 0x6899e6ec), + TOBN(0xbdc3bd68, 0x1fab23d5), TOBN(0xb72b8ab7, 0x73af60e6), + TOBN(0x8db27ae0, 0x2cecc84a), TOBN(0x600016d8, 0x7bdb871c), + TOBN(0x42a44b13, 0xd7c46f58), TOBN(0xb8919727, 0xc3a77d39), + TOBN(0xcfc6bbbd, 0xdafd6088), TOBN(0x1a740146, 0x6bd20d39), + TOBN(0x8c747abd, 0x98c41072), TOBN(0x4c91e765, 0xbdf68ea1), + TOBN(0x7c95e5ca, 0x08819a78), TOBN(0xcf48b729, 0xc9587921), + TOBN(0x091c7c5f, 0xdebbcc7d), TOBN(0x6f287404, 0xf0e05149), + TOBN(0xf83b5ac2, 0x26cd44ec), TOBN(0x88ae32a6, 0xcfea250e), + TOBN(0x6ac5047a, 0x1d06ebc5), TOBN(0xc7e550b4, 0xd434f781), + TOBN(0x61ab1cf2, 0x5c727bd2), TOBN(0x2e4badb1, 0x1cf915b0), + TOBN(0x1b4dadec, 0xf69d3920), TOBN(0xe61b1ca6, 0xf14c1dfe), + TOBN(0x90b479cc, 0xbd6bd51f), TOBN(0x8024e401, 0x8045ec30), + TOBN(0xcab29ca3, 0x25ef0e62), TOBN(0x4f2e9416, 0x49e4ebc0), + TOBN(0x45eb40ec, 0x0ccced58), TOBN(0x25cd4b9c, 0x0da44f98), + TOBN(0x43e06458, 0x871812c6), TOBN(0x99f80d55, 0x16cef651), + TOBN(0x571340c9, 0xce6dc153), TOBN(0x138d5117, 0xd8665521), + TOBN(0xacdb45bc, 0x4e07014d), TOBN(0x2f34bb38, 0x84b60b91), + TOBN(0xf44a4fd2, 0x2ae8921e), TOBN(0xb039288e, 0x892ba1e2), + TOBN(0x9da50174, 0xb1c180b2), TOBN(0x6b70ab66, 0x1693dc87), + TOBN(0x7e9babc9, 0xe7057481), TOBN(0x4581ddef, 0x9c80dc41), + TOBN(0x0c890da9, 0x51294682), TOBN(0x0b5629d3, 0x3f4736e5), + TOBN(0x2340c79e, 0xb06f5b41), TOBN(0xa42e84ce, 0x4e243469), + TOBN(0xf9a20135, 0x045a71a9), TOBN(0xefbfb415, 0xd27b6fb6), + TOBN(0x25ebea23, 0x9d33cd6f), TOBN(0x9caedb88, 0xaa6c0af8), + TOBN(0x53dc7e9a, 0xd9ce6f96), TOBN(0x3897f9fd, 0x51e0b15a), + TOBN(0xf51cb1f8, 0x8e5d788e), TOBN(0x1aec7ba8, 0xe1d490ee), + TOBN(0x265991e0, 0xcc58cb3c), TOBN(0x9f306e8c, 0x9fc3ad31), + TOBN(0x5fed006e, 0x5040a0ac), TOBN(0xca9d5043, 0xfb476f2e), + TOBN(0xa19c06e8, 0xbeea7a23), TOBN(0xd2865801, 0x0edabb63), + TOBN(0xdb92293f, 0x6967469a), TOBN(0x2894d839, 0x8d8a8ed8), + TOBN(0x87c9e406, 0xbbc77122), TOBN(0x8671c6f1, 0x2ea3a26a), + TOBN(0xe42df8d6, 0xd7de9853), TOBN(0x2e3ce346, 0xb1f2bcc7), + TOBN(0xda601dfc, 0x899d50cf), TOBN(0xbfc913de, 0xfb1b598f), + TOBN(0x81c4909f, 0xe61f7908), TOBN(0x192e304f, 0x9bbc7b29), + TOBN(0xc3ed8738, 0xc104b338), TOBN(0xedbe9e47, 0x783f5d61), + TOBN(0x0c06e9be, 0x2db30660), TOBN(0xda3e613f, 0xc0eb7d8e), + TOBN(0xd8fa3e97, 0x322e096e), TOBN(0xfebd91e8, 0xd336e247), + TOBN(0x8f13ccc4, 0xdf655a49), TOBN(0xa9e00dfc, 0x5eb20210), + TOBN(0x84631d0f, 0xc656b6ea), TOBN(0x93a058cd, 0xd8c0d947), + TOBN(0x6846904a, 0x67bd3448), TOBN(0x4a3d4e1a, 0xf394fd5c), + TOBN(0xc102c1a5, 0xdb225f52), TOBN(0xe3455bba, 0xfc4f5e9a), + TOBN(0x6b36985b, 0x4b9ad1ce), TOBN(0xa9818536, 0x5bb7f793), + TOBN(0x6c25e1d0, 0x48b1a416), TOBN(0x1381dd53, 0x3c81bee7), + TOBN(0xd2a30d61, 0x7a4a7620), TOBN(0xc8412926, 0x39b8944c), + TOBN(0x3c1c6fbe, 0x7a97c33a), TOBN(0x941e541d, 0x938664e7), + TOBN(0x417499e8, 0x4a34f239), TOBN(0x15fdb83c, 0xb90402d5), + TOBN(0xb75f46bf, 0x433aa832), TOBN(0xb61e15af, 0x63215db1), + TOBN(0xaabe59d4, 0xa127f89a), TOBN(0x5d541e0c, 0x07e816da), + TOBN(0xaaba0659, 0xa618b692), TOBN(0x55327733, 0x17266026), + TOBN(0xaf53a0fc, 0x95f57552), TOBN(0x32947650, 0x6cacb0c9), + TOBN(0x253ff58d, 0xc821be01), TOBN(0xb0309531, 0xa06f1146), + TOBN(0x59bbbdf5, 0x05c2e54d), TOBN(0x158f27ad, 0x26e8dd22), + TOBN(0xcc5b7ffb, 0x397e1e53), TOBN(0xae03f65b, 0x7fc1e50d), + TOBN(0xa9784ebd, 0x9c95f0f9), TOBN(0x5ed9deb2, 0x24640771), + TOBN(0x31244af7, 0x035561c4), TOBN(0x87332f3a, 0x7ee857de), + TOBN(0x09e16e9e, 0x2b9e0d88), TOBN(0x52d910f4, 0x56a06049), + TOBN(0x507ed477, 0xa9592f48), TOBN(0x85cb917b, 0x2365d678), + TOBN(0xf8511c93, 0x4c8998d1), TOBN(0x2186a3f1, 0x730ea58f), + TOBN(0x50189626, 0xb2029db0), TOBN(0x9137a6d9, 0x02ceb75a), + TOBN(0x2fe17f37, 0x748bc82c), TOBN(0x87c2e931, 0x80469f8c), + TOBN(0x850f71cd, 0xbf891aa2), TOBN(0x0ca1b89b, 0x75ec3d8d), + TOBN(0x516c43aa, 0x5e1cd3cd), TOBN(0x89397808, 0x9a887c28), + TOBN(0x0059c699, 0xddea1f9f), TOBN(0x7737d6fa, 0x8e6868f7), + TOBN(0x6d93746a, 0x60f1524b), TOBN(0x36985e55, 0xba052aa7), + TOBN(0x41b1d322, 0xed923ea5), TOBN(0x3429759f, 0x25852a11), + TOBN(0xbeca6ec3, 0x092e9f41), TOBN(0x3a238c66, 0x62256bbd), + TOBN(0xd82958ea, 0x70ad487d), TOBN(0x4ac8aaf9, 0x65610d93), + TOBN(0x3fa101b1, 0x5e4ccab0), TOBN(0x9bf430f2, 0x9de14bfb), + TOBN(0xa10f5cc6, 0x6531899d), TOBN(0x590005fb, 0xea8ce17d), + TOBN(0xc437912f, 0x24544cb6), TOBN(0x9987b71a, 0xd79ac2e3), + TOBN(0x13e3d9dd, 0xc058a212), TOBN(0x00075aac, 0xd2de9606), + TOBN(0x80ab508b, 0x6cac8369), TOBN(0x87842be7, 0xf54f6c89), + TOBN(0xa7ad663d, 0x6bc532a4), TOBN(0x67813de7, 0x78a91bc8), + TOBN(0x5dcb61ce, 0xc3427239), TOBN(0x5f3c7cf0, 0xc56934d9), + TOBN(0xc079e0fb, 0xe3191591), TOBN(0xe40896bd, 0xb01aada7), + TOBN(0x8d466791, 0x0492d25f), TOBN(0x8aeb30c9, 0xe7408276), + TOBN(0xe9437495, 0x9287aacc), TOBN(0x23d4708d, 0x79fe03d4), + TOBN(0x8cda9cf2, 0xd0c05199), TOBN(0x502fbc22, 0xfae78454), + TOBN(0xc0bda9df, 0xf572a182), TOBN(0x5f9b71b8, 0x6158b372), + TOBN(0xe0f33a59, 0x2b82dd07), TOBN(0x76302735, 0x9523032e), + TOBN(0x7fe1a721, 0xc4505a32), TOBN(0x7b6e3e82, 0xf796409f)}, + {TOBN(0xe3417bc0, 0x35d0b34a), TOBN(0x440b386b, 0x8327c0a7), + TOBN(0x8fb7262d, 0xac0362d1), TOBN(0x2c41114c, 0xe0cdf943), + TOBN(0x2ba5cef1, 0xad95a0b1), TOBN(0xc09b37a8, 0x67d54362), + TOBN(0x26d6cdd2, 0x01e486c9), TOBN(0x20477abf, 0x42ff9297), + TOBN(0xa004dcb3, 0x292a9287), TOBN(0xddc15cf6, 0x77b092c7), + TOBN(0x083a8464, 0x806c0605), TOBN(0x4a68df70, 0x3db997b0), + TOBN(0x9c134e45, 0x05bf7dd0), TOBN(0xa4e63d39, 0x8ccf7f8c), + TOBN(0xa6e6517f, 0x41b5f8af), TOBN(0xaa8b9342, 0xad7bc1cc), + TOBN(0x126f35b5, 0x1e706ad9), TOBN(0xb99cebb4, 0xc3a9ebdf), + TOBN(0xa75389af, 0xbf608d90), TOBN(0x76113c4f, 0xc6c89858), + TOBN(0x80de8eb0, 0x97e2b5aa), TOBN(0x7e1022cc, 0x63b91304), + TOBN(0x3bdab605, 0x6ccc066c), TOBN(0x33cbb144, 0xb2edf900), + TOBN(0xc4176471, 0x7af715d2), TOBN(0xe2f7f594, 0xd0134a96), + TOBN(0x2c1873ef, 0xa41ec956), TOBN(0xe4e7b4f6, 0x77821304), + TOBN(0xe5c8ff97, 0x88d5374a), TOBN(0x2b915e63, 0x80823d5b), + TOBN(0xea6bc755, 0xb2ee8fe2), TOBN(0x6657624c, 0xe7112651), + TOBN(0x157af101, 0xdace5aca), TOBN(0xc4fdbcf2, 0x11a6a267), + TOBN(0xdaddf340, 0xc49c8609), TOBN(0x97e49f52, 0xe9604a65), + TOBN(0x9be8e790, 0x937e2ad5), TOBN(0x846e2508, 0x326e17f1), + TOBN(0x3f38007a, 0x0bbbc0dc), TOBN(0xcf03603f, 0xb11e16d6), + TOBN(0xd6f800e0, 0x7442f1d5), TOBN(0x475607d1, 0x66e0e3ab), + TOBN(0x82807f16, 0xb7c64047), TOBN(0x8858e1e3, 0xa749883d), + TOBN(0x5859120b, 0x8231ee10), TOBN(0x1b80e7eb, 0x638a1ece), + TOBN(0xcb72525a, 0xc6aa73a4), TOBN(0xa7cdea3d, 0x844423ac), + TOBN(0x5ed0c007, 0xf8ae7c38), TOBN(0x6db07a5c, 0x3d740192), + TOBN(0xbe5e9c2a, 0x5fe36db3), TOBN(0xd5b9d57a, 0x76e95046), + TOBN(0x54ac32e7, 0x8eba20f2), TOBN(0xef11ca8f, 0x71b9a352), + TOBN(0x305e373e, 0xff98a658), TOBN(0xffe5a100, 0x823eb667), + TOBN(0x57477b11, 0xe51732d2), TOBN(0xdfd6eb28, 0x2538fc0e), + TOBN(0x5c43b0cc, 0x3b39eec5), TOBN(0x6af12778, 0xcb36cc57), + TOBN(0x70b0852d, 0x06c425ae), TOBN(0x6df92f8c, 0x5c221b9b), + TOBN(0x6c8d4f9e, 0xce826d9c), TOBN(0xf59aba7b, 0xb49359c3), + TOBN(0x5c8ed8d5, 0xda64309d), TOBN(0x61a6de56, 0x91b30704), + TOBN(0xd6b52f6a, 0x2f9b5808), TOBN(0x0eee4194, 0x98c958a7), + TOBN(0xcddd9aab, 0x771e4caa), TOBN(0x83965dfd, 0x78bc21be), + TOBN(0x02affce3, 0xb3b504f5), TOBN(0x30847a21, 0x561c8291), + TOBN(0xd2eb2cf1, 0x52bfda05), TOBN(0xe0e4c4e9, 0x6197b98c), + TOBN(0x1d35076c, 0xf8a1726f), TOBN(0x6c06085b, 0x2db11e3d), + TOBN(0x15c0c4d7, 0x4463ba14), TOBN(0x9d292f83, 0x0030238c), + TOBN(0x1311ee8b, 0x3727536d), TOBN(0xfeea86ef, 0xbeaedc1e), + TOBN(0xb9d18cd3, 0x66131e2e), TOBN(0xf31d974f, 0x80fe2682), + TOBN(0xb6e49e0f, 0xe4160289), TOBN(0x7c48ec0b, 0x08e92799), + TOBN(0x818111d8, 0xd1989aa7), TOBN(0xb34fa0aa, 0xebf926f9), + TOBN(0xdb5fe2f5, 0xa245474a), TOBN(0xf80a6ebb, 0x3c7ca756), + TOBN(0xa7f96054, 0xafa05dd8), TOBN(0x26dfcf21, 0xfcaf119e), + TOBN(0xe20ef2e3, 0x0564bb59), TOBN(0xef4dca50, 0x61cb02b8), + TOBN(0xcda7838a, 0x65d30672), TOBN(0x8b08d534, 0xfd657e86), + TOBN(0x4c5b4395, 0x46d595c8), TOBN(0x39b58725, 0x425cb836), + TOBN(0x8ea61059, 0x3de9abe3), TOBN(0x40434881, 0x9cdc03be), + TOBN(0x9b261245, 0xcfedce8c), TOBN(0x78c318b4, 0xcf5234a1), + TOBN(0x510bcf16, 0xfde24c99), TOBN(0x2a77cb75, 0xa2c2ff5d), + TOBN(0x9c895c2b, 0x27960fb4), TOBN(0xd30ce975, 0xb0eda42b), + TOBN(0xfda85393, 0x1a62cc26), TOBN(0x23c69b96, 0x50c0e052), + TOBN(0xa227df15, 0xbfc633f3), TOBN(0x2ac78848, 0x1bae7d48), + TOBN(0x487878f9, 0x187d073d), TOBN(0x6c2be919, 0x967f807d), + TOBN(0x765861d8, 0x336e6d8f), TOBN(0x88b8974c, 0xce528a43), + TOBN(0x09521177, 0xff57d051), TOBN(0x2ff38037, 0xfb6a1961), + TOBN(0xfc0aba74, 0xa3d76ad4), TOBN(0x7c764803, 0x25a7ec17), + TOBN(0x7532d75f, 0x48879bc8), TOBN(0xea7eacc0, 0x58ce6bc1), + TOBN(0xc82176b4, 0x8e896c16), TOBN(0x9a30e0b2, 0x2c750fed), + TOBN(0xc37e2c2e, 0x421d3aa4), TOBN(0xf926407c, 0xe84fa840), + TOBN(0x18abc03d, 0x1454e41c), TOBN(0x26605ecd, 0x3f7af644), + TOBN(0x242341a6, 0xd6a5eabf), TOBN(0x1edb84f4, 0x216b668e), + TOBN(0xd836edb8, 0x04010102), TOBN(0x5b337ce7, 0x945e1d8c), + TOBN(0xd2075c77, 0xc055dc14), TOBN(0x2a0ffa25, 0x81d89cdf), + TOBN(0x8ce815ea, 0x6ffdcbaf), TOBN(0xa3428878, 0xfb648867), + TOBN(0x277699cf, 0x884655fb), TOBN(0xfa5b5bd6, 0x364d3e41), + TOBN(0x01f680c6, 0x441e1cb7), TOBN(0x3fd61e66, 0xb70a7d67), + TOBN(0x666ba2dc, 0xcc78cf66), TOBN(0xb3018174, 0x6fdbff77), + TOBN(0x8d4dd0db, 0x168d4668), TOBN(0x259455d0, 0x1dab3a2a), + TOBN(0xf58564c5, 0xcde3acec), TOBN(0x77141925, 0x13adb276), + TOBN(0x527d725d, 0x8a303f65), TOBN(0x55deb6c9, 0xe6f38f7b), + TOBN(0xfd5bb657, 0xb1fa70fb), TOBN(0xfa07f50f, 0xd8073a00), + TOBN(0xf72e3aa7, 0xbca02500), TOBN(0xf68f895d, 0x9975740d), + TOBN(0x30112060, 0x5cae2a6a), TOBN(0x01bd7218, 0x02874842), + TOBN(0x3d423891, 0x7ce47bd3), TOBN(0xa66663c1, 0x789544f6), + TOBN(0x864d05d7, 0x3272d838), TOBN(0xe22924f9, 0xfa6295c5), + TOBN(0x8189593f, 0x6c2fda32), TOBN(0x330d7189, 0xb184b544), + TOBN(0x79efa62c, 0xbde1f714), TOBN(0x35771c94, 0xe5cb1a63), + TOBN(0x2f4826b8, 0x641c8332), TOBN(0x00a894fb, 0xc8cee854), + TOBN(0xb4b9a39b, 0x36194d40), TOBN(0xe857a7c5, 0x77612601), + TOBN(0xf4209dd2, 0x4ecf2f58), TOBN(0x82b9e66d, 0x5a033487), + TOBN(0xc1e36934, 0xe4e8b9dd), TOBN(0xd2372c9d, 0xa42377d7), + TOBN(0x51dc94c7, 0x0e3ae43b), TOBN(0x4c57761e, 0x04474f6f), + TOBN(0xdcdacd0a, 0x1058a318), TOBN(0x369cf3f5, 0x78053a9a), + TOBN(0xc6c3de50, 0x31c68de2), TOBN(0x4653a576, 0x3c4b6d9f), + TOBN(0x1688dd5a, 0xaa4e5c97), TOBN(0x5be80aa1, 0xb7ab3c74), + TOBN(0x70cefe7c, 0xbc65c283), TOBN(0x57f95f13, 0x06867091), + TOBN(0xa39114e2, 0x4415503b), TOBN(0xc08ff7c6, 0x4cbb17e9), + TOBN(0x1eff674d, 0xd7dec966), TOBN(0x6d4690af, 0x53376f63), + TOBN(0xff6fe32e, 0xea74237b), TOBN(0xc436d17e, 0xcd57508e), + TOBN(0x15aa28e1, 0xedcc40fe), TOBN(0x0d769c04, 0x581bbb44), + TOBN(0xc240b6de, 0x34eaacda), TOBN(0xd9e116e8, 0x2ba0f1de), + TOBN(0xcbe45ec7, 0x79438e55), TOBN(0x91787c9d, 0x96f752d7), + TOBN(0x897f532b, 0xf129ac2f), TOBN(0xd307b7c8, 0x5a36e22c), + TOBN(0x91940675, 0x749fb8f3), TOBN(0xd14f95d0, 0x157fdb28), + TOBN(0xfe51d029, 0x6ae55043), TOBN(0x8931e98f, 0x44a87de1), + TOBN(0xe57f1cc6, 0x09e4fee2), TOBN(0x0d063b67, 0x4e072d92), + TOBN(0x70a998b9, 0xed0e4316), TOBN(0xe74a736b, 0x306aca46), + TOBN(0xecf0fbf2, 0x4fda97c7), TOBN(0xa40f65cb, 0x3e178d93), + TOBN(0x16253604, 0x16df4285), TOBN(0xb0c9babb, 0xd0c56ae2), + TOBN(0x73032b19, 0xcfc5cfc3), TOBN(0xe497e5c3, 0x09752056), + TOBN(0x12096bb4, 0x164bda96), TOBN(0x1ee42419, 0xa0b74da1), + TOBN(0x8fc36243, 0x403826ba), TOBN(0x0c8f0069, 0xdc09e660), + TOBN(0x8667e981, 0xc27253c9), TOBN(0x05a6aefb, 0x92b36a45), + TOBN(0xa62c4b36, 0x9cb7bb46), TOBN(0x8394f375, 0x11f7027b), + TOBN(0x747bc79c, 0x5f109d0f), TOBN(0xcad88a76, 0x5b8cc60a), + TOBN(0x80c5a66b, 0x58f09e68), TOBN(0xe753d451, 0xf6127eac), + TOBN(0xc44b74a1, 0x5b0ec6f5), TOBN(0x47989fe4, 0x5289b2b8), + TOBN(0x745f8484, 0x58d6fc73), TOBN(0xec362a6f, 0xf61c70ab), + TOBN(0x070c98a7, 0xb3a8ad41), TOBN(0x73a20fc0, 0x7b63db51), + TOBN(0xed2c2173, 0xf44c35f4), TOBN(0x8a56149d, 0x9acc9dca), + TOBN(0x98f17881, 0x9ac6e0f4), TOBN(0x360fdeaf, 0xa413b5ed), + TOBN(0x0625b8f4, 0xa300b0fd), TOBN(0xf1f4d76a, 0x5b3222d3), + TOBN(0x9d6f5109, 0x587f76b8), TOBN(0x8b4ee08d, 0x2317fdb5), + TOBN(0x88089bb7, 0x8c68b095), TOBN(0x95570e9a, 0x5808d9b9), + TOBN(0xa395c36f, 0x35d33ae7), TOBN(0x200ea123, 0x50bb5a94), + TOBN(0x20c789bd, 0x0bafe84b), TOBN(0x243ef52d, 0x0919276a), + TOBN(0x3934c577, 0xe23ae233), TOBN(0xb93807af, 0xa460d1ec), + TOBN(0xb72a53b1, 0xf8fa76a4), TOBN(0xd8914cb0, 0xc3ca4491), + TOBN(0x2e128494, 0x3fb42622), TOBN(0x3b2700ac, 0x500907d5), + TOBN(0xf370fb09, 0x1a95ec63), TOBN(0xf8f30be2, 0x31b6dfbd), + TOBN(0xf2b2f8d2, 0x69e55f15), TOBN(0x1fead851, 0xcc1323e9), + TOBN(0xfa366010, 0xd9e5eef6), TOBN(0x64d487b0, 0xe316107e), + TOBN(0x4c076b86, 0xd23ddc82), TOBN(0x03fd344c, 0x7e0143f0), + TOBN(0xa95362ff, 0x317af2c5), TOBN(0x0add3db7, 0xe18b7a4f), + TOBN(0x9c673e3f, 0x8260e01b), TOBN(0xfbeb49e5, 0x54a1cc91), + TOBN(0x91351bf2, 0x92f2e433), TOBN(0xc755e7ec, 0x851141eb), + TOBN(0xc9a95139, 0x29607745), TOBN(0x0ca07420, 0xa26f2b28), + TOBN(0xcb2790e7, 0x4bc6f9dd), TOBN(0x345bbb58, 0xadcaffc0), + TOBN(0xc65ea38c, 0xbe0f27a2), TOBN(0x67c24d7c, 0x641fcb56), + TOBN(0x2c25f0a7, 0xa9e2c757), TOBN(0x93f5cdb0, 0x16f16c49), + TOBN(0x2ca5a9d7, 0xc5ee30a1), TOBN(0xd1593635, 0xb909b729), + TOBN(0x804ce9f3, 0xdadeff48), TOBN(0xec464751, 0xb07c30c3), + TOBN(0x89d65ff3, 0x9e49af6a), TOBN(0xf2d6238a, 0x6f3d01bc), + TOBN(0x1095561e, 0x0bced843), TOBN(0x51789e12, 0xc8a13fd8), + TOBN(0xd633f929, 0x763231df), TOBN(0x46df9f7d, 0xe7cbddef), + TOBN(0x01c889c0, 0xcb265da8), TOBN(0xfce1ad10, 0xaf4336d2), + TOBN(0x8d110df6, 0xfc6a0a7e), TOBN(0xdd431b98, 0x6da425dc), + TOBN(0xcdc4aeab, 0x1834aabe), TOBN(0x84deb124, 0x8439b7fc), + TOBN(0x8796f169, 0x3c2a5998), TOBN(0x9b9247b4, 0x7947190d), + TOBN(0x55b9d9a5, 0x11597014), TOBN(0x7e9dd70d, 0x7b1566ee), + TOBN(0x94ad78f7, 0xcbcd5e64), TOBN(0x0359ac17, 0x9bd4c032), + TOBN(0x3b11baaf, 0x7cc222ae), TOBN(0xa6a6e284, 0xba78e812), + TOBN(0x8392053f, 0x24cea1a0), TOBN(0xc97bce4a, 0x33621491), + TOBN(0x7eb1db34, 0x35399ee9), TOBN(0x473f78ef, 0xece81ad1), + TOBN(0x41d72fe0, 0xf63d3d0d), TOBN(0xe620b880, 0xafab62fc), + TOBN(0x92096bc9, 0x93158383), TOBN(0x41a21357, 0x8f896f6c), + TOBN(0x1b5ee2fa, 0xc7dcfcab), TOBN(0x650acfde, 0x9546e007), + TOBN(0xc081b749, 0xb1b02e07), TOBN(0xda9e41a0, 0xf9eca03d), + TOBN(0x013ba727, 0x175a54ab), TOBN(0xca0cd190, 0xea5d8d10), + TOBN(0x85ea52c0, 0x95fd96a9), TOBN(0x2c591b9f, 0xbc5c3940), + TOBN(0x6fb4d4e4, 0x2bad4d5f), TOBN(0xfa4c3590, 0xfef0059b), + TOBN(0x6a10218a, 0xf5122294), TOBN(0x9a78a81a, 0xa85751d1), + TOBN(0x04f20579, 0xa98e84e7), TOBN(0xfe1242c0, 0x4997e5b5), + TOBN(0xe77a273b, 0xca21e1e4), TOBN(0xfcc8b1ef, 0x9411939d), + TOBN(0xe20ea302, 0x92d0487a), TOBN(0x1442dbec, 0x294b91fe), + TOBN(0x1f7a4afe, 0xbb6b0e8f), TOBN(0x1700ef74, 0x6889c318), + TOBN(0xf5bbffc3, 0x70f1fc62), TOBN(0x3b31d4b6, 0x69c79cca), + TOBN(0xe8bc2aab, 0xa7f6340d), TOBN(0xb0b08ab4, 0xa725e10a), + TOBN(0x44f05701, 0xae340050), TOBN(0xba4b3016, 0x1cf0c569), + TOBN(0x5aa29f83, 0xfbe19a51), TOBN(0x1b9ed428, 0xb71d752e), + TOBN(0x1666e54e, 0xeb4819f5), TOBN(0x616cdfed, 0x9e18b75b), + TOBN(0x112ed5be, 0x3ee27b0b), TOBN(0xfbf28319, 0x44c7de4d), + TOBN(0xd685ec85, 0xe0e60d84), TOBN(0x68037e30, 0x1db7ee78), + TOBN(0x5b65bdcd, 0x003c4d6e), TOBN(0x33e7363a, 0x93e29a6a), + TOBN(0x995b3a61, 0x08d0756c), TOBN(0xd727f85c, 0x2faf134b), + TOBN(0xfac6edf7, 0x1d337823), TOBN(0x99b9aa50, 0x0439b8b4), + TOBN(0x722eb104, 0xe2b4e075), TOBN(0x49987295, 0x437c4926), + TOBN(0xb1e4c0e4, 0x46a9b82d), TOBN(0xd0cb3197, 0x57a006f5), + TOBN(0xf3de0f7d, 0xd7808c56), TOBN(0xb5c54d8f, 0x51f89772), + TOBN(0x500a114a, 0xadbd31aa), TOBN(0x9afaaaa6, 0x295f6cab), + TOBN(0x94705e21, 0x04cf667a), TOBN(0xfc2a811b, 0x9d3935d7), + TOBN(0x560b0280, 0x6d09267c), TOBN(0xf19ed119, 0xf780e53b), + TOBN(0xf0227c09, 0x067b6269), TOBN(0x967b8533, 0x5caef599), + TOBN(0x155b9243, 0x68efeebc), TOBN(0xcd6d34f5, 0xc497bae6), + TOBN(0x1dd8d5d3, 0x6cceb370), TOBN(0x2aeac579, 0xa78d7bf9), + TOBN(0x5d65017d, 0x70b67a62), TOBN(0x70c8e44f, 0x17c53f67), + TOBN(0xd1fc0950, 0x86a34d09), TOBN(0xe0fca256, 0xe7134907), + TOBN(0xe24fa29c, 0x80fdd315), TOBN(0x2c4acd03, 0xd87499ad), + TOBN(0xbaaf7517, 0x3b5a9ba6), TOBN(0xb9cbe1f6, 0x12e51a51), + TOBN(0xd88edae3, 0x5e154897), TOBN(0xe4309c3c, 0x77b66ca0), + TOBN(0xf5555805, 0xf67f3746), TOBN(0x85fc37ba, 0xa36401ff), + TOBN(0xdf86e2ca, 0xd9499a53), TOBN(0x6270b2a3, 0xecbc955b), + TOBN(0xafae64f5, 0x974ad33b), TOBN(0x04d85977, 0xfe7b2df1), + TOBN(0x2a3db3ff, 0x4ab03f73), TOBN(0x0b87878a, 0x8702740a), + TOBN(0x6d263f01, 0x5a061732), TOBN(0xc25430ce, 0xa32a1901), + TOBN(0xf7ebab3d, 0xdb155018), TOBN(0x3a86f693, 0x63a9b78e), + TOBN(0x349ae368, 0xda9f3804), TOBN(0x470f07fe, 0xa164349c), + TOBN(0xd52f4cc9, 0x8562baa5), TOBN(0xc74a9e86, 0x2b290df3), + TOBN(0xd3a1aa35, 0x43471a24), TOBN(0x239446be, 0xb8194511), + TOBN(0xbec2dd00, 0x81dcd44d), TOBN(0xca3d7f0f, 0xc42ac82d), + TOBN(0x1f3db085, 0xfdaf4520), TOBN(0xbb6d3e80, 0x4549daf2), + TOBN(0xf5969d8a, 0x19ad5c42), TOBN(0x7052b13d, 0xdbfd1511), + TOBN(0x11890d1b, 0x682b9060), TOBN(0xa71d3883, 0xac34452c), + TOBN(0xa438055b, 0x783805b4), TOBN(0x43241277, 0x4725b23e), + TOBN(0xf20cf96e, 0x4901bbed), TOBN(0x6419c710, 0xf432a2bb), + TOBN(0x57a0fbb9, 0xdfa9cd7d), TOBN(0x589111e4, 0x00daa249), + TOBN(0x19809a33, 0x7b60554e), TOBN(0xea5f8887, 0xede283a4), + TOBN(0x2d713802, 0x503bfd35), TOBN(0x151bb0af, 0x585d2a53), + TOBN(0x40b08f74, 0x43b30ca8), TOBN(0xe10b5bba, 0xd9934583), + TOBN(0xe8a546d6, 0xb51110ad), TOBN(0x1dd50e66, 0x28e0b6c5), + TOBN(0x292e9d54, 0xcff2b821), TOBN(0x3882555d, 0x47281760), + TOBN(0x134838f8, 0x3724d6e3), TOBN(0xf2c679e0, 0x22ddcda1), + TOBN(0x40ee8815, 0x6d2a5768), TOBN(0x7f227bd2, 0x1c1e7e2d), + TOBN(0x487ba134, 0xd04ff443), TOBN(0x76e2ff3d, 0xc614e54b), + TOBN(0x36b88d6f, 0xa3177ec7), TOBN(0xbf731d51, 0x2328fff5), + TOBN(0x758caea2, 0x49ba158e), TOBN(0x5ab8ff4c, 0x02938188), + TOBN(0x33e16056, 0x35edc56d), TOBN(0x5a69d349, 0x7e940d79), + TOBN(0x6c4fd001, 0x03866dcb), TOBN(0x20a38f57, 0x4893cdef), + TOBN(0xfbf3e790, 0xfac3a15b), TOBN(0x6ed7ea2e, 0x7a4f8e6b), + TOBN(0xa663eb4f, 0xbc3aca86), TOBN(0x22061ea5, 0x080d53f7), + TOBN(0x2480dfe6, 0xf546783f), TOBN(0xd38bc6da, 0x5a0a641e), + TOBN(0xfb093cd1, 0x2ede8965), TOBN(0x89654db4, 0xacb455cf), + TOBN(0x413cbf9a, 0x26e1adee), TOBN(0x291f3764, 0x373294d4), + TOBN(0x00797257, 0x648083fe), TOBN(0x25f504d3, 0x208cc341), + TOBN(0x635a8e5e, 0xc3a0ee43), TOBN(0x70aaebca, 0x679898ff), + TOBN(0x9ee9f547, 0x5dc63d56), TOBN(0xce987966, 0xffb34d00), + TOBN(0xf9f86b19, 0x5e26310a), TOBN(0x9e435484, 0x382a8ca8), + TOBN(0x253bcb81, 0xc2352fe4), TOBN(0xa4eac8b0, 0x4474b571), + TOBN(0xc1b97512, 0xc1ad8cf8), TOBN(0x193b4e9e, 0x99e0b697), + TOBN(0x939d2716, 0x01e85df0), TOBN(0x4fb265b3, 0xcd44eafd), + TOBN(0x321e7dcd, 0xe51e1ae2), TOBN(0x8e3a8ca6, 0xe3d8b096), + TOBN(0x8de46cb0, 0x52604998), TOBN(0x91099ad8, 0x39072aa7), + TOBN(0x2617f91c, 0x93aa96b8), TOBN(0x0fc8716b, 0x7fca2e13), + TOBN(0xa7106f5e, 0x95328723), TOBN(0xd1c9c40b, 0x262e6522), + TOBN(0xb9bafe86, 0x42b7c094), TOBN(0x1873439d, 0x1543c021), + TOBN(0xe1baa5de, 0x5cbefd5d), TOBN(0xa363fc5e, 0x521e8aff), + TOBN(0xefe6320d, 0xf862eaac), TOBN(0x14419c63, 0x22c647dc), + TOBN(0x0e06707c, 0x4e46d428), TOBN(0xcb6c834f, 0x4a178f8f), + TOBN(0x0f993a45, 0xd30f917c), TOBN(0xd4c4b049, 0x9879afee), + TOBN(0xb6142a1e, 0x70500063), TOBN(0x7c9b41c3, 0xa5d9d605), + TOBN(0xbc00fc2f, 0x2f8ba2c7), TOBN(0x0966eb2f, 0x7c67aa28), + TOBN(0x13f7b516, 0x5a786972), TOBN(0x3bfb7557, 0x8a2fbba0), + TOBN(0x131c4f23, 0x5a2b9620), TOBN(0xbff3ed27, 0x6faf46be), + TOBN(0x9b4473d1, 0x7e172323), TOBN(0x421e8878, 0x339f6246), + TOBN(0x0fa8587a, 0x25a41632), TOBN(0xc0814124, 0xa35b6c93), + TOBN(0x2b18a9f5, 0x59ebb8db), TOBN(0x264e3357, 0x76edb29c), + TOBN(0xaf245ccd, 0xc87c51e2), TOBN(0x16b3015b, 0x501e6214), + TOBN(0xbb31c560, 0x0a3882ce), TOBN(0x6961bb94, 0xfec11e04), + TOBN(0x3b825b8d, 0xeff7a3a0), TOBN(0xbec33738, 0xb1df7326), + TOBN(0x68ad747c, 0x99604a1f), TOBN(0xd154c934, 0x9a3bd499), + TOBN(0xac33506f, 0x1cc7a906), TOBN(0x73bb5392, 0x6c560e8f), + TOBN(0x6428fcbe, 0x263e3944), TOBN(0xc11828d5, 0x1c387434), + TOBN(0x3cd04be1, 0x3e4b12ff), TOBN(0xc3aad9f9, 0x2d88667c), + TOBN(0xc52ddcf8, 0x248120cf), TOBN(0x985a892e, 0x2a389532), + TOBN(0xfbb4b21b, 0x3bb85fa0), TOBN(0xf95375e0, 0x8dfc6269), + TOBN(0xfb4fb06c, 0x7ee2acea), TOBN(0x6785426e, 0x309c4d1f), + TOBN(0x659b17c8, 0xd8ceb147), TOBN(0x9b649eee, 0xb70a5554), + TOBN(0x6b7fa0b5, 0xac6bc634), TOBN(0xd99fe2c7, 0x1d6e732f), + TOBN(0x30e6e762, 0x8d3abba2), TOBN(0x18fee6e7, 0xa797b799), + TOBN(0x5c9d360d, 0xc696464d), TOBN(0xe3baeb48, 0x27bfde12), + TOBN(0x2bf5db47, 0xf23206d5), TOBN(0x2f6d3420, 0x1d260152), + TOBN(0x17b87653, 0x3f8ff89a), TOBN(0x5157c30c, 0x378fa458), + TOBN(0x7517c5c5, 0x2d4fb936), TOBN(0xef22f7ac, 0xe6518cdc), + TOBN(0xdeb483e6, 0xbf847a64), TOBN(0xf5084558, 0x92e0fa89)}, + {TOBN(0xab9659d8, 0xdf7304d4), TOBN(0xb71bcf1b, 0xff210e8e), + TOBN(0xa9a2438b, 0xd73fbd60), TOBN(0x4595cd1f, 0x5d11b4de), + TOBN(0x9c0d329a, 0x4835859d), TOBN(0x4a0f0d2d, 0x7dbb6e56), + TOBN(0xc6038e5e, 0xdf928a4e), TOBN(0xc9429621, 0x8f5ad154), + TOBN(0x91213462, 0xf23f2d92), TOBN(0x6cab71bd, 0x60b94078), + TOBN(0x6bdd0a63, 0x176cde20), TOBN(0x54c9b20c, 0xee4d54bc), + TOBN(0x3cd2d8aa, 0x9f2ac02f), TOBN(0x03f8e617, 0x206eedb0), + TOBN(0xc7f68e16, 0x93086434), TOBN(0x831469c5, 0x92dd3db9), + TOBN(0x8521df24, 0x8f981354), TOBN(0x587e23ec, 0x3588a259), + TOBN(0xcbedf281, 0xd7a0992c), TOBN(0x06930a55, 0x38961407), + TOBN(0x09320deb, 0xbe5bbe21), TOBN(0xa7ffa5b5, 0x2491817f), + TOBN(0xe6c8b4d9, 0x09065160), TOBN(0xac4f3992, 0xfff6d2a9), + TOBN(0x7aa7a158, 0x3ae9c1bd), TOBN(0xe0af6d98, 0xe37ce240), + TOBN(0xe54342d9, 0x28ab38b4), TOBN(0xe8b75007, 0x0a1c98ca), + TOBN(0xefce86af, 0xe02358f2), TOBN(0x31b8b856, 0xea921228), + TOBN(0x052a1912, 0x0a1c67fc), TOBN(0xb4069ea4, 0xe3aead59), + TOBN(0x3232d6e2, 0x7fa03cb3), TOBN(0xdb938e5b, 0x0fdd7d88), + TOBN(0x04c1d2cd, 0x2ccbfc5d), TOBN(0xd2f45c12, 0xaf3a580f), + TOBN(0x592620b5, 0x7883e614), TOBN(0x5fd27e68, 0xbe7c5f26), + TOBN(0x139e45a9, 0x1567e1e3), TOBN(0x2cc71d2d, 0x44d8aaaf), + TOBN(0x4a9090cd, 0xe36d0757), TOBN(0xf722d7b1, 0xd9a29382), + TOBN(0xfb7fb04c, 0x04b48ddf), TOBN(0x628ad2a7, 0xebe16f43), + TOBN(0xcd3fbfb5, 0x20226040), TOBN(0x6c34ecb1, 0x5104b6c4), + TOBN(0x30c0754e, 0xc903c188), TOBN(0xec336b08, 0x2d23cab0), + TOBN(0x473d62a2, 0x1e206ee5), TOBN(0xf1e27480, 0x8c49a633), + TOBN(0x87ab956c, 0xe9f6b2c3), TOBN(0x61830b48, 0x62b606ea), + TOBN(0x67cd6846, 0xe78e815f), TOBN(0xfe40139f, 0x4c02082a), + TOBN(0x52bbbfcb, 0x952ec365), TOBN(0x74c11642, 0x6b9836ab), + TOBN(0x9f51439e, 0x558df019), TOBN(0x230da4ba, 0xac712b27), + TOBN(0x518919e3, 0x55185a24), TOBN(0x4dcefcdd, 0x84b78f50), + TOBN(0xa7d90fb2, 0xa47d4c5a), TOBN(0x55ac9abf, 0xb30e009e), + TOBN(0xfd2fc359, 0x74eed273), TOBN(0xb72d824c, 0xdbea8faf), + TOBN(0xce721a74, 0x4513e2ca), TOBN(0x0b418612, 0x38240b2c), + TOBN(0x05199968, 0xd5baa450), TOBN(0xeb1757ed, 0x2b0e8c25), + TOBN(0x6ebc3e28, 0x3dfac6d5), TOBN(0xb2431e2e, 0x48a237f5), + TOBN(0x2acb5e23, 0x52f61499), TOBN(0x5558a2a7, 0xe06c936b), + TOBN(0xd213f923, 0xcbb13d1b), TOBN(0x98799f42, 0x5bfb9bfe), + TOBN(0x1ae8ddc9, 0x701144a9), TOBN(0x0b8b3bb6, 0x4c5595ee), + TOBN(0x0ea9ef2e, 0x3ecebb21), TOBN(0x17cb6c4b, 0x3671f9a7), + TOBN(0x47ef464f, 0x726f1d1f), TOBN(0x171b9484, 0x6943a276), + TOBN(0x51a4ae2d, 0x7ef0329c), TOBN(0x08509222, 0x91c4402a), + TOBN(0x64a61d35, 0xafd45bbc), TOBN(0x38f096fe, 0x3035a851), + TOBN(0xc7468b74, 0xa1dec027), TOBN(0xe8cf10e7, 0x4fc7dcba), + TOBN(0xea35ff40, 0xf4a06353), TOBN(0x0b4c0dfa, 0x8b77dd66), + TOBN(0x779b8552, 0xde7e5c19), TOBN(0xfab28609, 0xc1c0256c), + TOBN(0x64f58eee, 0xabd4743d), TOBN(0x4e8ef838, 0x7b6cc93b), + TOBN(0xee650d26, 0x4cb1bf3d), TOBN(0x4c1f9d09, 0x73dedf61), + TOBN(0xaef7c9d7, 0xbfb70ced), TOBN(0x1ec0507e, 0x1641de1e), + TOBN(0xcd7e5cc7, 0xcde45079), TOBN(0xde173c9a, 0x516ac9e4), + TOBN(0x517a8494, 0xc170315c), TOBN(0x438fd905, 0x91d8e8fb), + TOBN(0x5145c506, 0xc7d9630b), TOBN(0x6457a87b, 0xf47d4d75), + TOBN(0xd31646bf, 0x0d9a80e8), TOBN(0x453add2b, 0xcef3aabe), + TOBN(0xc9941109, 0xa607419d), TOBN(0xfaa71e62, 0xbb6bca80), + TOBN(0x34158c13, 0x07c431f3), TOBN(0x594abebc, 0x992bc47a), + TOBN(0x6dfea691, 0xeb78399f), TOBN(0x48aafb35, 0x3f42cba4), + TOBN(0xedcd65af, 0x077c04f0), TOBN(0x1a29a366, 0xe884491a), + TOBN(0x023a40e5, 0x1c21f2bf), TOBN(0xf99a513c, 0xa5057aee), + TOBN(0xa3fe7e25, 0xbcab072e), TOBN(0x8568d2e1, 0x40e32bcf), + TOBN(0x904594eb, 0xd3f69d9f), TOBN(0x181a9733, 0x07affab1), + TOBN(0xe4d68d76, 0xb6e330f4), TOBN(0x87a6dafb, 0xc75a7fc1), + TOBN(0x549db2b5, 0xef7d9289), TOBN(0x2480d4a8, 0x197f015a), + TOBN(0x61d5590b, 0xc40493b6), TOBN(0x3a55b52e, 0x6f780331), + TOBN(0x40eb8115, 0x309eadb0), TOBN(0xdea7de5a, 0x92e5c625), + TOBN(0x64d631f0, 0xcc6a3d5a), TOBN(0x9d5e9d7c, 0x93e8dd61), + TOBN(0xf297bef5, 0x206d3ffc), TOBN(0x23d5e033, 0x7d808bd4), + TOBN(0x4a4f6912, 0xd24cf5ba), TOBN(0xe4d8163b, 0x09cdaa8a), + TOBN(0x0e0de9ef, 0xd3082e8e), TOBN(0x4fe1246c, 0x0192f360), + TOBN(0x1f900150, 0x4b8eee0a), TOBN(0x5219da81, 0xf1da391b), + TOBN(0x7bf6a5c1, 0xf7ea25aa), TOBN(0xd165e6bf, 0xfbb07d5f), + TOBN(0xe3539361, 0x89e78671), TOBN(0xa3fcac89, 0x2bac4219), + TOBN(0xdfab6fd4, 0xf0baa8ab), TOBN(0x5a4adac1, 0xe2c1c2e5), + TOBN(0x6cd75e31, 0x40d85849), TOBN(0xce263fea, 0x19b39181), + TOBN(0xcb6803d3, 0x07032c72), TOBN(0x7f40d5ce, 0x790968c8), + TOBN(0xa6de86bd, 0xdce978f0), TOBN(0x25547c4f, 0x368f751c), + TOBN(0xb1e685fd, 0x65fb2a9e), TOBN(0xce69336f, 0x1eb9179c), + TOBN(0xb15d1c27, 0x12504442), TOBN(0xb7df465c, 0xb911a06b), + TOBN(0xb8d804a3, 0x315980cd), TOBN(0x693bc492, 0xfa3bebf7), + TOBN(0x3578aeee, 0x2253c504), TOBN(0x158de498, 0xcd2474a2), + TOBN(0x1331f5c7, 0xcfda8368), TOBN(0xd2d7bbb3, 0x78d7177e), + TOBN(0xdf61133a, 0xf3c1e46e), TOBN(0x5836ce7d, 0xd30e7be8), + TOBN(0x83084f19, 0x94f834cb), TOBN(0xd35653d4, 0x429ed782), + TOBN(0xa542f16f, 0x59e58243), TOBN(0xc2b52f65, 0x0470a22d), + TOBN(0xe3b6221b, 0x18f23d96), TOBN(0xcb05abac, 0x3f5252b4), + TOBN(0xca00938b, 0x87d61402), TOBN(0x2f186cdd, 0x411933e4), + TOBN(0xe042ece5, 0x9a29a5c5), TOBN(0xb19b3c07, 0x3b6c8402), + TOBN(0xc97667c7, 0x19d92684), TOBN(0xb5624622, 0xebc66372), + TOBN(0x0cb96e65, 0x3c04fa02), TOBN(0x83a7176c, 0x8eaa39aa), + TOBN(0x2033561d, 0xeaa1633f), TOBN(0x45a9d086, 0x4533df73), + TOBN(0xe0542c1d, 0x3dc090bc), TOBN(0x82c996ef, 0xaa59c167), + TOBN(0xe3f735e8, 0x0ee7fc4d), TOBN(0x7b179393, 0x7c35db79), + TOBN(0xb6419e25, 0xf8c5dbfd), TOBN(0x4d9d7a1e, 0x1f327b04), + TOBN(0x979f6f9b, 0x298dfca8), TOBN(0xc7c5dff1, 0x8de9366a), + TOBN(0x1b7a588d, 0x04c82bdd), TOBN(0x68005534, 0xf8319dfd), + TOBN(0xde8a55b5, 0xd8eb9580), TOBN(0x5ea886da, 0x8d5bca81), + TOBN(0xe8530a01, 0x252a0b4d), TOBN(0x1bffb4fe, 0x35eaa0a1), + TOBN(0x2ad828b1, 0xd8e99563), TOBN(0x7de96ef5, 0x95f9cd87), + TOBN(0x4abb2d0c, 0xd77d970c), TOBN(0x03cfb933, 0xd33ef9cb), + TOBN(0xb0547c01, 0x8b211fe9), TOBN(0x2fe64809, 0xa56ed1c6), + TOBN(0xcb7d5624, 0xc2ac98cc), TOBN(0x2a1372c0, 0x1a393e33), + TOBN(0xc8d1ec1c, 0x29660521), TOBN(0xf3d31b04, 0xb37ac3e9), + TOBN(0xa29ae9df, 0x5ece6e7c), TOBN(0x0603ac8f, 0x0facfb55), + TOBN(0xcfe85b7a, 0xdda233a5), TOBN(0xe618919f, 0xbd75f0b8), + TOBN(0xf555a3d2, 0x99bf1603), TOBN(0x1f43afc9, 0xf184255a), + TOBN(0xdcdaf341, 0x319a3e02), TOBN(0xd3b117ef, 0x03903a39), + TOBN(0xe095da13, 0x65d1d131), TOBN(0x86f16367, 0xc37ad03e), + TOBN(0x5f37389e, 0x462cd8dd), TOBN(0xc103fa04, 0xd67a60e6), + TOBN(0x57c34344, 0xf4b478f0), TOBN(0xce91edd8, 0xe117c98d), + TOBN(0x001777b0, 0x231fc12e), TOBN(0x11ae47f2, 0xb207bccb), + TOBN(0xd983cf8d, 0x20f8a242), TOBN(0x7aff5b1d, 0xf22e1ad8), + TOBN(0x68fd11d0, 0x7fc4feb3), TOBN(0x5d53ae90, 0xb0f1c3e1), + TOBN(0x50fb7905, 0xec041803), TOBN(0x85e3c977, 0x14404888), + TOBN(0x0e67faed, 0xac628d8f), TOBN(0x2e865150, 0x6668532c), + TOBN(0x15acaaa4, 0x6a67a6b0), TOBN(0xf4cdee25, 0xb25cec41), + TOBN(0x49ee565a, 0xe4c6701e), TOBN(0x2a04ca66, 0xfc7d63d8), + TOBN(0xeb105018, 0xef0543fb), TOBN(0xf709a4f5, 0xd1b0d81d), + TOBN(0x5b906ee6, 0x2915d333), TOBN(0xf4a87412, 0x96f1f0ab), + TOBN(0xb6b82fa7, 0x4d82f4c2), TOBN(0x90725a60, 0x6804efb3), + TOBN(0xbc82ec46, 0xadc3425e), TOBN(0xb7b80581, 0x2787843e), + TOBN(0xdf46d91c, 0xdd1fc74c), TOBN(0xdc1c62cb, 0xe783a6c4), + TOBN(0x59d1b9f3, 0x1a04cbba), TOBN(0xd87f6f72, 0x95e40764), + TOBN(0x02b4cfc1, 0x317f4a76), TOBN(0x8d2703eb, 0x91036bce), + TOBN(0x98206cc6, 0xa5e72a56), TOBN(0x57be9ed1, 0xcf53fb0f), + TOBN(0x09374571, 0xef0b17ac), TOBN(0x74b2655e, 0xd9181b38), + TOBN(0xc8f80ea8, 0x89935d0e), TOBN(0xc0d9e942, 0x91529936), + TOBN(0x19686041, 0x1e84e0e5), TOBN(0xa5db84d3, 0xaea34c93), + TOBN(0xf9d5bb19, 0x7073a732), TOBN(0xb8d2fe56, 0x6bcfd7c0), + TOBN(0x45775f36, 0xf3eb82fa), TOBN(0x8cb20ccc, 0xfdff8b58), + TOBN(0x1659b65f, 0x8374c110), TOBN(0xb8b4a422, 0x330c789a), + TOBN(0x75e3c3ea, 0x6fe8208b), TOBN(0xbd74b9e4, 0x286e78fe), + TOBN(0x0be2e81b, 0xd7d93a1a), TOBN(0x7ed06e27, 0xdd0a5aae), + TOBN(0x721f5a58, 0x6be8b800), TOBN(0x428299d1, 0xd846db28), + TOBN(0x95cb8e6b, 0x5be88ed3), TOBN(0xc3186b23, 0x1c034e11), + TOBN(0xa6312c9e, 0x8977d99b), TOBN(0xbe944331, 0x83f531e7), + TOBN(0x8232c0c2, 0x18d3b1d4), TOBN(0x617aae8b, 0xe1247b73), + TOBN(0x40153fc4, 0x282aec3b), TOBN(0xc6063d2f, 0xf7b8f823), + TOBN(0x68f10e58, 0x3304f94c), TOBN(0x31efae74, 0xee676346), + TOBN(0xbadb6c6d, 0x40a9b97c), TOBN(0x14702c63, 0x4f666256), + TOBN(0xdeb954f1, 0x5184b2e3), TOBN(0x5184a526, 0x94b6ca40), + TOBN(0xfff05337, 0x003c32ea), TOBN(0x5aa374dd, 0x205974c7), + TOBN(0x9a763854, 0x4b0dd71a), TOBN(0x459cd27f, 0xdeb947ec), + TOBN(0xa6e28161, 0x459c2b92), TOBN(0x2f020fa8, 0x75ee8ef5), + TOBN(0xb132ec2d, 0x30b06310), TOBN(0xc3e15899, 0xbc6a4530), + TOBN(0xdc5f53fe, 0xaa3f451a), TOBN(0x3a3c7f23, 0xc2d9acac), + TOBN(0x2ec2f892, 0x6b27e58b), TOBN(0x68466ee7, 0xd742799f), + TOBN(0x98324dd4, 0x1fa26613), TOBN(0xa2dc6dab, 0xbdc29d63), + TOBN(0xf9675faa, 0xd712d657), TOBN(0x813994be, 0x21fd8d15), + TOBN(0x5ccbb722, 0xfd4f7553), TOBN(0x5135ff8b, 0xf3a36b20), + TOBN(0x44be28af, 0x69559df5), TOBN(0x40b65bed, 0x9d41bf30), + TOBN(0xd98bf2a4, 0x3734e520), TOBN(0x5e3abbe3, 0x209bdcba), + TOBN(0x77c76553, 0xbc945b35), TOBN(0x5331c093, 0xc6ef14aa), + TOBN(0x518ffe29, 0x76b60c80), TOBN(0x2285593b, 0x7ace16f8), + TOBN(0xab1f64cc, 0xbe2b9784), TOBN(0xe8f2c0d9, 0xab2421b6), + TOBN(0x617d7174, 0xc1df065c), TOBN(0xafeeb5ab, 0x5f6578fa), + TOBN(0x16ff1329, 0x263b54a8), TOBN(0x45c55808, 0xc990dce3), + TOBN(0x42eab6c0, 0xecc8c177), TOBN(0x799ea9b5, 0x5982ecaa), + TOBN(0xf65da244, 0xb607ef8e), TOBN(0x8ab226ce, 0x32a3fc2c), + TOBN(0x745741e5, 0x7ea973dc), TOBN(0x5c00ca70, 0x20888f2e), + TOBN(0x7cdce3cf, 0x45fd9cf1), TOBN(0x8a741ef1, 0x5507f872), + TOBN(0x47c51c2f, 0x196b4cec), TOBN(0x70d08e43, 0xc97ea618), + TOBN(0x930da15c, 0x15b18a2b), TOBN(0x33b6c678, 0x2f610514), + TOBN(0xc662e4f8, 0x07ac9794), TOBN(0x1eccf050, 0xba06cb79), + TOBN(0x1ff08623, 0xe7d954e5), TOBN(0x6ef2c5fb, 0x24cf71c3), + TOBN(0xb2c063d2, 0x67978453), TOBN(0xa0cf3796, 0x1d654af8), + TOBN(0x7cb242ea, 0x7ebdaa37), TOBN(0x206e0b10, 0xb86747e0), + TOBN(0x481dae5f, 0xd5ecfefc), TOBN(0x07084fd8, 0xc2bff8fc), + TOBN(0x8040a01a, 0xea324596), TOBN(0x4c646980, 0xd4de4036), + TOBN(0x9eb8ab4e, 0xd65abfc3), TOBN(0xe01cb91f, 0x13541ec7), + TOBN(0x8f029adb, 0xfd695012), TOBN(0x9ae28483, 0x3c7569ec), + TOBN(0xa5614c9e, 0xa66d80a1), TOBN(0x680a3e44, 0x75f5f911), + TOBN(0x0c07b14d, 0xceba4fc1), TOBN(0x891c285b, 0xa13071c1), + TOBN(0xcac67ceb, 0x799ece3c), TOBN(0x29b910a9, 0x41e07e27), + TOBN(0x66bdb409, 0xf2e43123), TOBN(0x06f8b137, 0x7ac9ecbe), + TOBN(0x5981fafd, 0x38547090), TOBN(0x19ab8b9f, 0x85e3415d), + TOBN(0xfc28c194, 0xc7e31b27), TOBN(0x843be0aa, 0x6fbcbb42), + TOBN(0xf3b1ed43, 0xa6db836c), TOBN(0x2a1330e4, 0x01a45c05), + TOBN(0x4f19f3c5, 0x95c1a377), TOBN(0xa85f39d0, 0x44b5ee33), + TOBN(0x3da18e6d, 0x4ae52834), TOBN(0x5a403b39, 0x7423dcb0), + TOBN(0xbb555e0a, 0xf2374aef), TOBN(0x2ad599c4, 0x1e8ca111), + TOBN(0x1b3a2fb9, 0x014b3bf8), TOBN(0x73092684, 0xf66d5007), + TOBN(0x079f1426, 0xc4340102), TOBN(0x1827cf81, 0x8fddf4de), + TOBN(0xc83605f6, 0xf10ff927), TOBN(0xd3871451, 0x23739fc6), + TOBN(0x6d163450, 0xcac1c2cc), TOBN(0x6b521296, 0xa2ec1ac5), + TOBN(0x0606c4f9, 0x6e3cb4a5), TOBN(0xe47d3f41, 0x778abff7), + TOBN(0x425a8d5e, 0xbe8e3a45), TOBN(0x53ea9e97, 0xa6102160), + TOBN(0x477a106e, 0x39cbb688), TOBN(0x532401d2, 0xf3386d32), + TOBN(0x8e564f64, 0xb1b9b421), TOBN(0xca9b8388, 0x81dad33f), + TOBN(0xb1422b4e, 0x2093913e), TOBN(0x533d2f92, 0x69bc8112), + TOBN(0x3fa017be, 0xebe7b2c7), TOBN(0xb2767c4a, 0xcaf197c6), + TOBN(0xc925ff87, 0xaedbae9f), TOBN(0x7daf0eb9, 0x36880a54), + TOBN(0x9284ddf5, 0x9c4d0e71), TOBN(0x1581cf93, 0x316f8cf5), + TOBN(0x3eeca887, 0x3ac1f452), TOBN(0xb417fce9, 0xfb6aeffe), + TOBN(0xa5918046, 0xeefb8dc3), TOBN(0x73d318ac, 0x02209400), + TOBN(0xe800400f, 0x728693e5), TOBN(0xe87d814b, 0x339927ed), + TOBN(0x93e94d3b, 0x57ea9910), TOBN(0xff8a35b6, 0x2245fb69), + TOBN(0x043853d7, 0x7f200d34), TOBN(0x470f1e68, 0x0f653ce1), + TOBN(0x81ac05bd, 0x59a06379), TOBN(0xa14052c2, 0x03930c29), + TOBN(0x6b72fab5, 0x26bc2797), TOBN(0x13670d16, 0x99f16771), + TOBN(0x00170052, 0x1e3e48d1), TOBN(0x978fe401, 0xb7adf678), + TOBN(0x55ecfb92, 0xd41c5dd4), TOBN(0x5ff8e247, 0xc7b27da5), + TOBN(0xe7518272, 0x013fb606), TOBN(0x5768d7e5, 0x2f547a3c), + TOBN(0xbb24eaa3, 0x60017a5f), TOBN(0x6b18e6e4, 0x9c64ce9b), + TOBN(0xc225c655, 0x103dde07), TOBN(0xfc3672ae, 0x7592f7ea), + TOBN(0x9606ad77, 0xd06283a1), TOBN(0x542fc650, 0xe4d59d99), + TOBN(0xabb57c49, 0x2a40e7c2), TOBN(0xac948f13, 0xa8db9f55), + TOBN(0x6d4c9682, 0xb04465c3), TOBN(0xe3d062fa, 0x6468bd15), + TOBN(0xa51729ac, 0x5f318d7e), TOBN(0x1fc87df6, 0x9eb6fc95), + TOBN(0x63d146a8, 0x0591f652), TOBN(0xa861b8f7, 0x589621aa), + TOBN(0x59f5f15a, 0xce31348c), TOBN(0x8f663391, 0x440da6da), + TOBN(0xcfa778ac, 0xb591ffa3), TOBN(0x027ca9c5, 0x4cdfebce), + TOBN(0xbe8e05a5, 0x444ea6b3), TOBN(0x8aab4e69, 0xa78d8254), + TOBN(0x2437f04f, 0xb474d6b8), TOBN(0x6597ffd4, 0x045b3855), + TOBN(0xbb0aea4e, 0xca47ecaa), TOBN(0x568aae83, 0x85c7ebfc), + TOBN(0x0e966e64, 0xc73b2383), TOBN(0x49eb3447, 0xd17d8762), + TOBN(0xde107821, 0x8da05dab), TOBN(0x443d8baa, 0x016b7236), + TOBN(0x163b63a5, 0xea7610d6), TOBN(0xe47e4185, 0xce1ca979), + TOBN(0xae648b65, 0x80baa132), TOBN(0xebf53de2, 0x0e0d5b64), + TOBN(0x8d3bfcb4, 0xd3c8c1ca), TOBN(0x0d914ef3, 0x5d04b309), + TOBN(0x55ef6415, 0x3de7d395), TOBN(0xbde1666f, 0x26b850e8), + TOBN(0xdbe1ca6e, 0xd449ab19), TOBN(0x8902b322, 0xe89a2672), + TOBN(0xb1674b7e, 0xdacb7a53), TOBN(0x8e9faf6e, 0xf52523ff), + TOBN(0x6ba535da, 0x9a85788b), TOBN(0xd21f03ae, 0xbd0626d4), + TOBN(0x099f8c47, 0xe873dc64), TOBN(0xcda8564d, 0x018ec97e), + TOBN(0x3e8d7a5c, 0xde92c68c), TOBN(0x78e035a1, 0x73323cc4), + TOBN(0x3ef26275, 0xf880ff7c), TOBN(0xa4ee3dff, 0x273eedaa), + TOBN(0x58823507, 0xaf4e18f8), TOBN(0x967ec9b5, 0x0672f328), + TOBN(0x9ded19d9, 0x559d3186), TOBN(0x5e2ab3de, 0x6cdce39c), + TOBN(0xabad6e4d, 0x11c226df), TOBN(0xf9783f43, 0x87723014), + TOBN(0x9a49a0cf, 0x1a885719), TOBN(0xfc0c1a5a, 0x90da9dbf), + TOBN(0x8bbaec49, 0x571d92ac), TOBN(0x569e85fe, 0x4692517f), + TOBN(0x8333b014, 0xa14ea4af), TOBN(0x32f2a62f, 0x12e5c5ad), + TOBN(0x98c2ce3a, 0x06d89b85), TOBN(0xb90741aa, 0x2ff77a08), + TOBN(0x2530defc, 0x01f795a2), TOBN(0xd6e5ba0b, 0x84b3c199), + TOBN(0x7d8e8451, 0x12e4c936), TOBN(0xae419f7d, 0xbd0be17b), + TOBN(0xa583fc8c, 0x22262bc9), TOBN(0x6b842ac7, 0x91bfe2bd), + TOBN(0x33cef4e9, 0x440d6827), TOBN(0x5f69f4de, 0xef81fb14), + TOBN(0xf16cf6f6, 0x234fbb92), TOBN(0x76ae3fc3, 0xd9e7e158), + TOBN(0x4e89f6c2, 0xe9740b33), TOBN(0x677bc85d, 0x4962d6a1), + TOBN(0x6c6d8a7f, 0x68d10d15), TOBN(0x5f9a7224, 0x0257b1cd), + TOBN(0x7096b916, 0x4ad85961), TOBN(0x5f8c47f7, 0xe657ab4a), + TOBN(0xde57d7d0, 0xf7461d7e), TOBN(0x7eb6094d, 0x80ce5ee2), + TOBN(0x0b1e1dfd, 0x34190547), TOBN(0x8a394f43, 0xf05dd150), + TOBN(0x0a9eb24d, 0x97df44e6), TOBN(0x78ca06bf, 0x87675719), + TOBN(0x6f0b3462, 0x6ffeec22), TOBN(0x9d91bcea, 0x36cdd8fb), + TOBN(0xac83363c, 0xa105be47), TOBN(0x81ba76c1, 0x069710e3), + TOBN(0x3d1b24cb, 0x28c682c6), TOBN(0x27f25228, 0x8612575b), + TOBN(0xb587c779, 0xe8e66e98), TOBN(0x7b0c03e9, 0x405eb1fe), + TOBN(0xfdf0d030, 0x15b548e7), TOBN(0xa8be76e0, 0x38b36af7), + TOBN(0x4cdab04a, 0x4f310c40), TOBN(0x6287223e, 0xf47ecaec), + TOBN(0x678e6055, 0x8b399320), TOBN(0x61fe3fa6, 0xc01e4646), + TOBN(0xc482866b, 0x03261a5e), TOBN(0xdfcf45b8, 0x5c2f244a), + TOBN(0x8fab9a51, 0x2f684b43), TOBN(0xf796c654, 0xc7220a66), + TOBN(0x1d90707e, 0xf5afa58f), TOBN(0x2c421d97, 0x4fdbe0de), + TOBN(0xc4f4cda3, 0xaf2ebc2f), TOBN(0xa0af843d, 0xcb4efe24), + TOBN(0x53b857c1, 0x9ccd10b1), TOBN(0xddc9d1eb, 0x914d3e04), + TOBN(0x7bdec8bb, 0x62771deb), TOBN(0x829277aa, 0x91c5aa81), + TOBN(0x7af18dd6, 0x832391ae), TOBN(0x1740f316, 0xc71a84ca)}, + {TOBN(0x8928e99a, 0xeeaf8c49), TOBN(0xee7aa73d, 0x6e24d728), + TOBN(0x4c5007c2, 0xe72b156c), TOBN(0x5fcf57c5, 0xed408a1d), + TOBN(0x9f719e39, 0xb6057604), TOBN(0x7d343c01, 0xc2868bbf), + TOBN(0x2cca254b, 0x7e103e2d), TOBN(0xe6eb38a9, 0xf131bea2), + TOBN(0xb33e624f, 0x8be762b4), TOBN(0x2a9ee4d1, 0x058e3413), + TOBN(0x968e6369, 0x67d805fa), TOBN(0x9848949b, 0x7db8bfd7), + TOBN(0x5308d7e5, 0xd23a8417), TOBN(0x892f3b1d, 0xf3e29da5), + TOBN(0xc95c139e, 0x3dee471f), TOBN(0x8631594d, 0xd757e089), + TOBN(0xe0c82a3c, 0xde918dcc), TOBN(0x2e7b5994, 0x26fdcf4b), + TOBN(0x82c50249, 0x32cb1b2d), TOBN(0xea613a9d, 0x7657ae07), + TOBN(0xc2eb5f6c, 0xf1fdc9f7), TOBN(0xb6eae8b8, 0x879fe682), + TOBN(0x253dfee0, 0x591cbc7f), TOBN(0x000da713, 0x3e1290e6), + TOBN(0x1083e2ea, 0x1f095615), TOBN(0x0a28ad77, 0x14e68c33), + TOBN(0x6bfc0252, 0x3d8818be), TOBN(0xb585113a, 0xf35850cd), + TOBN(0x7d935f0b, 0x30df8aa1), TOBN(0xaddda07c, 0x4ab7e3ac), + TOBN(0x92c34299, 0x552f00cb), TOBN(0xc33ed1de, 0x2909df6c), + TOBN(0x22c2195d, 0x80e87766), TOBN(0x9e99e6d8, 0x9ddf4ac0), + TOBN(0x09642e4e, 0x65e74934), TOBN(0x2610ffa2, 0xff1ff241), + TOBN(0x4d1d47d4, 0x751c8159), TOBN(0x697b4985, 0xaf3a9363), + TOBN(0x0318ca46, 0x87477c33), TOBN(0xa90cb565, 0x9441eff3), + TOBN(0x58bb3848, 0x36f024cb), TOBN(0x85be1f77, 0x36016168), + TOBN(0x6c59587c, 0xdc7e07f1), TOBN(0x191be071, 0xaf1d8f02), + TOBN(0xbf169fa5, 0xcca5e55c), TOBN(0x3864ba3c, 0xf7d04eac), + TOBN(0x915e367f, 0x8d7d05db), TOBN(0xb48a876d, 0xa6549e5d), + TOBN(0xef89c656, 0x580e40a2), TOBN(0xf194ed8c, 0x728068bc), + TOBN(0x74528045, 0xa47990c9), TOBN(0xf53fc7d7, 0x5e1a4649), + TOBN(0xbec5ae9b, 0x78593e7d), TOBN(0x2cac4ee3, 0x41db65d7), + TOBN(0xa8c1eb24, 0x04a3d39b), TOBN(0x53b7d634, 0x03f8f3ef), + TOBN(0x2dc40d48, 0x3e07113c), TOBN(0x6e4a5d39, 0x7d8b63ae), + TOBN(0x5582a94b, 0x79684c2b), TOBN(0x932b33d4, 0x622da26c), + TOBN(0xf534f651, 0x0dbbf08d), TOBN(0x211d07c9, 0x64c23a52), + TOBN(0x0eeece0f, 0xee5bdc9b), TOBN(0xdf178168, 0xf7015558), + TOBN(0xd4294635, 0x0a712229), TOBN(0x93cbe448, 0x09273f8c), + TOBN(0x00b095ef, 0x8f13bc83), TOBN(0xbb741972, 0x8798978c), + TOBN(0x9d7309a2, 0x56dbe6e7), TOBN(0xe578ec56, 0x5a5d39ec), + TOBN(0x3961151b, 0x851f9a31), TOBN(0x2da7715d, 0xe5709eb4), + TOBN(0x867f3017, 0x53dfabf0), TOBN(0x728d2078, 0xb8e39259), + TOBN(0x5c75a0cd, 0x815d9958), TOBN(0xf84867a6, 0x16603be1), + TOBN(0xc865b13d, 0x70e35b1c), TOBN(0x02414468, 0x19b03e2c), + TOBN(0xe46041da, 0xac1f3121), TOBN(0x7c9017ad, 0x6f028a7c), + TOBN(0xabc96de9, 0x0a482873), TOBN(0x4265d6b1, 0xb77e54d4), + TOBN(0x68c38e79, 0xa57d88e7), TOBN(0xd461d766, 0x9ce82de3), + TOBN(0x817a9ec5, 0x64a7e489), TOBN(0xcc5675cd, 0xa0def5f2), + TOBN(0x9a00e785, 0x985d494e), TOBN(0xc626833f, 0x1b03514a), + TOBN(0xabe7905a, 0x83cdd60e), TOBN(0x50602fb5, 0xa1170184), + TOBN(0x689886cd, 0xb023642a), TOBN(0xd568d090, 0xa6e1fb00), + TOBN(0x5b1922c7, 0x0259217f), TOBN(0x93831cd9, 0xc43141e4), + TOBN(0xdfca3587, 0x0c95f86e), TOBN(0xdec2057a, 0x568ae828), + TOBN(0xc44ea599, 0xf98a759a), TOBN(0x55a0a7a2, 0xf7c23c1d), + TOBN(0xd5ffb6e6, 0x94c4f687), TOBN(0x3563cce2, 0x12848478), + TOBN(0x812b3517, 0xe7b1fbe1), TOBN(0x8a7dc979, 0x4f7338e0), + TOBN(0x211ecee9, 0x52d048db), TOBN(0x2eea4056, 0xc86ea3b8), + TOBN(0xd8cb68a7, 0xba772b34), TOBN(0xe16ed341, 0x5f4e2541), + TOBN(0x9b32f6a6, 0x0fec14db), TOBN(0xeee376f7, 0x391698be), + TOBN(0xe9a7aa17, 0x83674c02), TOBN(0x65832f97, 0x5843022a), + TOBN(0x29f3a8da, 0x5ba4990f), TOBN(0x79a59c3a, 0xfb8e3216), + TOBN(0x9cdc4d2e, 0xbd19bb16), TOBN(0xc6c7cfd0, 0xb3262d86), + TOBN(0xd4ce14d0, 0x969c0b47), TOBN(0x1fa352b7, 0x13e56128), + TOBN(0x383d55b8, 0x973db6d3), TOBN(0x71836850, 0xe8e5b7bf), + TOBN(0xc7714596, 0xe6bb571f), TOBN(0x259df31f, 0x2d5b2dd2), + TOBN(0x568f8925, 0x913cc16d), TOBN(0x18bc5b6d, 0xe1a26f5a), + TOBN(0xdfa413be, 0xf5f499ae), TOBN(0xf8835dec, 0xc3f0ae84), + TOBN(0xb6e60bd8, 0x65a40ab0), TOBN(0x65596439, 0x194b377e), + TOBN(0xbcd85625, 0x92084a69), TOBN(0x5ce433b9, 0x4f23ede0), + TOBN(0xe8e8f04f, 0x6ad65143), TOBN(0x11511827, 0xd6e14af6), + TOBN(0x3d390a10, 0x8295c0c7), TOBN(0x71e29ee4, 0x621eba16), + TOBN(0xa588fc09, 0x63717b46), TOBN(0x02be02fe, 0xe06ad4a2), + TOBN(0x931558c6, 0x04c22b22), TOBN(0xbb4d4bd6, 0x12f3c849), + TOBN(0x54a4f496, 0x20efd662), TOBN(0x92ba6d20, 0xc5952d14), + TOBN(0x2db8ea1e, 0xcc9784c2), TOBN(0x81cc10ca, 0x4b353644), + TOBN(0x40b570ad, 0x4b4d7f6c), TOBN(0x5c9f1d96, 0x84a1dcd2), + TOBN(0x01379f81, 0x3147e797), TOBN(0xe5c6097b, 0x2bd499f5), + TOBN(0x40dcafa6, 0x328e5e20), TOBN(0xf7b5244a, 0x54815550), + TOBN(0xb9a4f118, 0x47bfc978), TOBN(0x0ea0e79f, 0xd25825b1), + TOBN(0xa50f96eb, 0x646c7ecf), TOBN(0xeb811493, 0x446dea9d), + TOBN(0x2af04677, 0xdfabcf69), TOBN(0xbe3a068f, 0xc713f6e8), + TOBN(0x860d523d, 0x42e06189), TOBN(0xbf077941, 0x4e3aff13), + TOBN(0x0b616dca, 0xc1b20650), TOBN(0xe66dd6d1, 0x2131300d), + TOBN(0xd4a0fd67, 0xff99abde), TOBN(0xc9903550, 0xc7aac50d), + TOBN(0x022ecf8b, 0x7c46b2d7), TOBN(0x3333b1e8, 0x3abf92af), + TOBN(0x11cc113c, 0x6c491c14), TOBN(0x05976688, 0x80dd3f88), + TOBN(0xf5b4d9e7, 0x29d932ed), TOBN(0xe982aad8, 0xa2c38b6d), + TOBN(0x6f925347, 0x8be0dcf0), TOBN(0x700080ae, 0x65ca53f2), + TOBN(0xd8131156, 0x443ca77f), TOBN(0xe92d6942, 0xec51f984), + TOBN(0xd2a08af8, 0x85dfe9ae), TOBN(0xd825d9a5, 0x4d2a86ca), + TOBN(0x2c53988d, 0x39dff020), TOBN(0xf38b135a, 0x430cdc40), + TOBN(0x0c918ae0, 0x62a7150b), TOBN(0xf31fd8de, 0x0c340e9b), + TOBN(0xafa0e7ae, 0x4dbbf02e), TOBN(0x5847fb2a, 0x5eba6239), + TOBN(0x6b1647dc, 0xdccbac8b), TOBN(0xb642aa78, 0x06f485c8), + TOBN(0x873f3765, 0x7038ecdf), TOBN(0x2ce5e865, 0xfa49d3fe), + TOBN(0xea223788, 0xc98c4400), TOBN(0x8104a8cd, 0xf1fa5279), + TOBN(0xbcf7cc7a, 0x06becfd7), TOBN(0x49424316, 0xc8f974ae), + TOBN(0xc0da65e7, 0x84d6365d), TOBN(0xbcb7443f, 0x8f759fb8), + TOBN(0x35c712b1, 0x7ae81930), TOBN(0x80428dff, 0x4c6e08ab), + TOBN(0xf19dafef, 0xa4faf843), TOBN(0xced8538d, 0xffa9855f), + TOBN(0x20ac409c, 0xbe3ac7ce), TOBN(0x358c1fb6, 0x882da71e), + TOBN(0xafa9c0e5, 0xfd349961), TOBN(0x2b2cfa51, 0x8421c2fc), + TOBN(0x2a80db17, 0xf3a28d38), TOBN(0xa8aba539, 0x5d138e7e), + TOBN(0x52012d1d, 0x6e96eb8d), TOBN(0x65d8dea0, 0xcbaf9622), + TOBN(0x57735447, 0xb264f56c), TOBN(0xbeebef3f, 0x1b6c8da2), + TOBN(0xfc346d98, 0xce785254), TOBN(0xd50e8d72, 0xbb64a161), + TOBN(0xc03567c7, 0x49794add), TOBN(0x15a76065, 0x752c7ef6), + TOBN(0x59f3a222, 0x961f23d6), TOBN(0x378e4438, 0x73ecc0b0), + TOBN(0xc74be434, 0x5a82fde4), TOBN(0xae509af2, 0xd8b9cf34), + TOBN(0x4a61ee46, 0x577f44a1), TOBN(0xe09b748c, 0xb611deeb), + TOBN(0xc0481b2c, 0xf5f7b884), TOBN(0x35626678, 0x61acfa6b), + TOBN(0x37f4c518, 0xbf8d21e6), TOBN(0x22d96531, 0xb205a76d), + TOBN(0x37fb85e1, 0x954073c0), TOBN(0xbceafe4f, 0x65b3a567), + TOBN(0xefecdef7, 0xbe42a582), TOBN(0xd3fc6080, 0x65046be6), + TOBN(0xc9af13c8, 0x09e8dba9), TOBN(0x1e6c9847, 0x641491ff), + TOBN(0x3b574925, 0xd30c31f7), TOBN(0xb7eb72ba, 0xac2a2122), + TOBN(0x776a0dac, 0xef0859e7), TOBN(0x06fec314, 0x21900942), + TOBN(0x2464bc10, 0xf8c22049), TOBN(0x9bfbcce7, 0x875ebf69), + TOBN(0xd7a88e2a, 0x4336326b), TOBN(0xda05261c, 0x5bc2acfa), + TOBN(0xc29f5bdc, 0xeba7efc8), TOBN(0x471237ca, 0x25dbbf2e), + TOBN(0xa72773f2, 0x2975f127), TOBN(0xdc744e8e, 0x04d0b326), + TOBN(0x38a7ed16, 0xa56edb73), TOBN(0x64357e37, 0x2c007e70), + TOBN(0xa167d15b, 0x5080b400), TOBN(0x07b41164, 0x23de4be1), + TOBN(0xb2d91e32, 0x74c89883), TOBN(0x3c162821, 0x2882e7ed), + TOBN(0xad6b36ba, 0x7503e482), TOBN(0x48434e8e, 0x0ea34331), + TOBN(0x79f4f24f, 0x2c7ae0b9), TOBN(0xc46fbf81, 0x1939b44a), + TOBN(0x76fefae8, 0x56595eb1), TOBN(0x417b66ab, 0xcd5f29c7), + TOBN(0x5f2332b2, 0xc5ceec20), TOBN(0xd69661ff, 0xe1a1cae2), + TOBN(0x5ede7e52, 0x9b0286e6), TOBN(0x9d062529, 0xe276b993), + TOBN(0x324794b0, 0x7e50122b), TOBN(0xdd744f8b, 0x4af07ca5), + TOBN(0x30a12f08, 0xd63fc97b), TOBN(0x39650f1a, 0x76626d9d), + TOBN(0x101b47f7, 0x1fa38477), TOBN(0x3d815f19, 0xd4dc124f), + TOBN(0x1569ae95, 0xb26eb58a), TOBN(0xc3cde188, 0x95fb1887), + TOBN(0x54e9f37b, 0xf9539a48), TOBN(0xb0100e06, 0x7408c1a5), + TOBN(0x821d9811, 0xea580cbb), TOBN(0x8af52d35, 0x86e50c56), + TOBN(0xdfbd9d47, 0xdbbf698b), TOBN(0x2961a1ea, 0x03dc1c73), + TOBN(0x203d38f8, 0xe76a5df8), TOBN(0x08a53a68, 0x6def707a), + TOBN(0x26eefb48, 0x1bee45d4), TOBN(0xb3cee346, 0x3c688036), + TOBN(0x463c5315, 0xc42f2469), TOBN(0x19d84d2e, 0x81378162), + TOBN(0x22d7c3c5, 0x1c4d349f), TOBN(0x65965844, 0x163d59c5), + TOBN(0xcf198c56, 0xb8abceae), TOBN(0x6fb1fb1b, 0x628559d5), + TOBN(0x8bbffd06, 0x07bf8fe3), TOBN(0x46259c58, 0x3467734b), + TOBN(0xd8953cea, 0x35f7f0d3), TOBN(0x1f0bece2, 0xd65b0ff1), + TOBN(0xf7d5b4b3, 0xf3c72914), TOBN(0x29e8ea95, 0x3cb53389), + TOBN(0x4a365626, 0x836b6d46), TOBN(0xe849f910, 0xea174fde), + TOBN(0x7ec62fbb, 0xf4737f21), TOBN(0xd8dba5ab, 0x6209f5ac), + TOBN(0x24b5d7a9, 0xa5f9adbe), TOBN(0x707d28f7, 0xa61dc768), + TOBN(0x7711460b, 0xcaa999ea), TOBN(0xba7b174d, 0x1c92e4cc), + TOBN(0x3c4bab66, 0x18d4bf2d), TOBN(0xb8f0c980, 0xeb8bd279), + TOBN(0x024bea9a, 0x324b4737), TOBN(0xfba9e423, 0x32a83bca), + TOBN(0x6e635643, 0xa232dced), TOBN(0x99619367, 0x2571c8ba), + TOBN(0xe8c9f357, 0x54b7032b), TOBN(0xf936b3ba, 0x2442d54a), + TOBN(0x2263f0f0, 0x8290c65a), TOBN(0x48989780, 0xee2c7fdb), + TOBN(0xadc5d55a, 0x13d4f95e), TOBN(0x737cff85, 0xad9b8500), + TOBN(0x271c557b, 0x8a73f43d), TOBN(0xbed617a4, 0xe18bc476), + TOBN(0x66245401, 0x7dfd8ab2), TOBN(0xae7b89ae, 0x3a2870aa), + TOBN(0x1b555f53, 0x23a7e545), TOBN(0x6791e247, 0xbe057e4c), + TOBN(0x860136ad, 0x324fa34d), TOBN(0xea111447, 0x4cbeae28), + TOBN(0x023a4270, 0xbedd3299), TOBN(0x3d5c3a7f, 0xc1c35c34), + TOBN(0xb0f6db67, 0x8d0412d2), TOBN(0xd92625e2, 0xfcdc6b9a), + TOBN(0x92ae5ccc, 0x4e28a982), TOBN(0xea251c36, 0x47a3ce7e), + TOBN(0x9d658932, 0x790691bf), TOBN(0xed610589, 0x06b736ae), + TOBN(0x712c2f04, 0xc0d63b6e), TOBN(0x5cf06fd5, 0xc63d488f), + TOBN(0x97363fac, 0xd9588e41), TOBN(0x1f9bf762, 0x2b93257e), + TOBN(0xa9d1ffc4, 0x667acace), TOBN(0x1cf4a1aa, 0x0a061ecf), + TOBN(0x40e48a49, 0xdc1818d0), TOBN(0x0643ff39, 0xa3621ab0), + TOBN(0x5768640c, 0xe39ef639), TOBN(0x1fc099ea, 0x04d86854), + TOBN(0x9130b9c3, 0xeccd28fd), TOBN(0xd743cbd2, 0x7eec54ab), + TOBN(0x052b146f, 0xe5b475b6), TOBN(0x058d9a82, 0x900a7d1f), + TOBN(0x65e02292, 0x91262b72), TOBN(0x96f924f9, 0xbb0edf03), + TOBN(0x5cfa59c8, 0xfe206842), TOBN(0xf6037004, 0x5eafa720), + TOBN(0x5f30699e, 0x18d7dd96), TOBN(0x381e8782, 0xcbab2495), + TOBN(0x91669b46, 0xdd8be949), TOBN(0xb40606f5, 0x26aae8ef), + TOBN(0x2812b839, 0xfc6751a4), TOBN(0x16196214, 0xfba800ef), + TOBN(0x4398d5ca, 0x4c1a2875), TOBN(0x720c00ee, 0x653d8349), + TOBN(0xc2699eb0, 0xd820007c), TOBN(0x880ee660, 0xa39b5825), + TOBN(0x70694694, 0x471f6984), TOBN(0xf7d16ea8, 0xe3dda99a), + TOBN(0x28d675b2, 0xc0519a23), TOBN(0x9ebf94fe, 0x4f6952e3), + TOBN(0xf28bb767, 0xa2294a8a), TOBN(0x85512b4d, 0xfe0af3f5), + TOBN(0x18958ba8, 0x99b16a0d), TOBN(0x95c2430c, 0xba7548a7), + TOBN(0xb30d1b10, 0xa16be615), TOBN(0xe3ebbb97, 0x85bfb74c), + TOBN(0xa3273cfe, 0x18549fdb), TOBN(0xf6e200bf, 0x4fcdb792), + TOBN(0x54a76e18, 0x83aba56c), TOBN(0x73ec66f6, 0x89ef6aa2), + TOBN(0x8d17add7, 0xd1b9a305), TOBN(0xa959c5b9, 0xb7ae1b9d), + TOBN(0x88643522, 0x6bcc094a), TOBN(0xcc5616c4, 0xd7d429b9), + TOBN(0xa6dada01, 0xe6a33f7c), TOBN(0xc6217a07, 0x9d4e70ad), + TOBN(0xd619a818, 0x09c15b7c), TOBN(0xea06b329, 0x0e80c854), + TOBN(0x174811ce, 0xa5f5e7b9), TOBN(0x66dfc310, 0x787c65f4), + TOBN(0x4ea7bd69, 0x3316ab54), TOBN(0xc12c4acb, 0x1dcc0f70), + TOBN(0xe4308d1a, 0x1e407dd9), TOBN(0xe8a3587c, 0x91afa997), + TOBN(0xea296c12, 0xab77b7a5), TOBN(0xb5ad49e4, 0x673c0d52), + TOBN(0x40f9b2b2, 0x7006085a), TOBN(0xa88ff340, 0x87bf6ec2), + TOBN(0x978603b1, 0x4e3066a6), TOBN(0xb3f99fc2, 0xb5e486e2), + TOBN(0x07b53f5e, 0xb2e63645), TOBN(0xbe57e547, 0x84c84232), + TOBN(0xd779c216, 0x7214d5cf), TOBN(0x617969cd, 0x029a3aca), + TOBN(0xd17668cd, 0x8a7017a0), TOBN(0x77b4d19a, 0xbe9b7ee8), + TOBN(0x58fd0e93, 0x9c161776), TOBN(0xa8c4f4ef, 0xd5968a72), + TOBN(0x296071cc, 0x67b3de77), TOBN(0xae3c0b8e, 0x634f7905), + TOBN(0x67e440c2, 0x8a7100c9), TOBN(0xbb8c3c1b, 0xeb4b9b42), + TOBN(0x6d71e8ea, 0xc51b3583), TOBN(0x7591f5af, 0x9525e642), + TOBN(0xf73a2f7b, 0x13f509f3), TOBN(0x618487aa, 0x5619ac9b), + TOBN(0x3a72e5f7, 0x9d61718a), TOBN(0x00413bcc, 0x7592d28c), + TOBN(0x7d9b11d3, 0x963c35cf), TOBN(0x77623bcf, 0xb90a46ed), + TOBN(0xdeef273b, 0xdcdd2a50), TOBN(0x4a741f9b, 0x0601846e), + TOBN(0x33b89e51, 0x0ec6e929), TOBN(0xcb02319f, 0x8b7f22cd), + TOBN(0xbbe1500d, 0x084bae24), TOBN(0x2f0ae8d7, 0x343d2693), + TOBN(0xacffb5f2, 0x7cdef811), TOBN(0xaa0c030a, 0x263fb94f), + TOBN(0x6eef0d61, 0xa0f442de), TOBN(0xf92e1817, 0x27b139d3), + TOBN(0x1ae6deb7, 0x0ad8bc28), TOBN(0xa89e38dc, 0xc0514130), + TOBN(0x81eeb865, 0xd2fdca23), TOBN(0x5a15ee08, 0xcc8ef895), + TOBN(0x768fa10a, 0x01905614), TOBN(0xeff5b8ef, 0x880ee19b), + TOBN(0xf0c0cabb, 0xcb1c8a0e), TOBN(0x2e1ee9cd, 0xb8c838f9), + TOBN(0x0587d8b8, 0x8a4a14c0), TOBN(0xf6f27896, 0x2ff698e5), + TOBN(0xed38ef1c, 0x89ee6256), TOBN(0xf44ee1fe, 0x6b353b45), + TOBN(0x9115c0c7, 0x70e903b3), TOBN(0xc78ec0a1, 0x818f31df), + TOBN(0x6c003324, 0xb7dccbc6), TOBN(0xd96dd1f3, 0x163bbc25), + TOBN(0x33aa82dd, 0x5cedd805), TOBN(0x123aae4f, 0x7f7eb2f1), + TOBN(0x1723fcf5, 0xa26262cd), TOBN(0x1f7f4d5d, 0x0060ebd5), + TOBN(0xf19c5c01, 0xb2eaa3af), TOBN(0x2ccb9b14, 0x9790accf), + TOBN(0x1f9c1cad, 0x52324aa6), TOBN(0x63200526, 0x7247df54), + TOBN(0x5732fe42, 0xbac96f82), TOBN(0x52fe771f, 0x01a1c384), + TOBN(0x546ca13d, 0xb1001684), TOBN(0xb56b4eee, 0xa1709f75), + TOBN(0x266545a9, 0xd5db8672), TOBN(0xed971c90, 0x1e8f3cfb), + TOBN(0x4e7d8691, 0xe3a07b29), TOBN(0x7570d9ec, 0xe4b696b9), + TOBN(0xdc5fa067, 0x7bc7e9ae), TOBN(0x68b44caf, 0xc82c4844), + TOBN(0x519d34b3, 0xbf44da80), TOBN(0x283834f9, 0x5ab32e66), + TOBN(0x6e608797, 0x6278a000), TOBN(0x1e62960e, 0x627312f6), + TOBN(0x9b87b27b, 0xe6901c55), TOBN(0x80e78538, 0x24fdbc1f), + TOBN(0xbbbc0951, 0x2facc27d), TOBN(0x06394239, 0xac143b5a), + TOBN(0x35bb4a40, 0x376c1944), TOBN(0x7cb62694, 0x63da1511), + TOBN(0xafd29161, 0xb7148a3b), TOBN(0xa6f9d9ed, 0x4e2ea2ee), + TOBN(0x15dc2ca2, 0x880dd212), TOBN(0x903c3813, 0xa61139a9), + TOBN(0x2aa7b46d, 0x6c0f8785), TOBN(0x36ce2871, 0x901c60ff), + TOBN(0xc683b028, 0xe10d9c12), TOBN(0x7573baa2, 0x032f33d3), + TOBN(0x87a9b1f6, 0x67a31b58), TOBN(0xfd3ed11a, 0xf4ffae12), + TOBN(0x83dcaa9a, 0x0cb2748e), TOBN(0x8239f018, 0x5d6fdf16), + TOBN(0xba67b49c, 0x72753941), TOBN(0x2beec455, 0xc321cb36), + TOBN(0x88015606, 0x3f8b84ce), TOBN(0x76417083, 0x8d38c86f), + TOBN(0x054f1ca7, 0x598953dd), TOBN(0xc939e110, 0x4e8e7429), + TOBN(0x9b1ac2b3, 0x5a914f2f), TOBN(0x39e35ed3, 0xe74b8f9c), + TOBN(0xd0debdb2, 0x781b2fb0), TOBN(0x1585638f, 0x2d997ba2), + TOBN(0x9c4b646e, 0x9e2fce99), TOBN(0x68a21081, 0x1e80857f), + TOBN(0x06d54e44, 0x3643b52a), TOBN(0xde8d6d63, 0x0d8eb843), + TOBN(0x70321563, 0x42146a0a), TOBN(0x8ba826f2, 0x5eaa3622), + TOBN(0x227a58bd, 0x86138787), TOBN(0x43b6c03c, 0x10281d37), + TOBN(0x6326afbb, 0xb54dde39), TOBN(0x744e5e8a, 0xdb6f2d5f), + TOBN(0x48b2a99a, 0xcff158e1), TOBN(0xa93c8fa0, 0xef87918f), + TOBN(0x2182f956, 0xde058c5c), TOBN(0x216235d2, 0x936f9e7a), + TOBN(0xace0c0db, 0xd2e31e67), TOBN(0xc96449bf, 0xf23ac3e7), + TOBN(0x7e9a2874, 0x170693bd), TOBN(0xa28e14fd, 0xa45e6335), + TOBN(0x5757f6b3, 0x56427344), TOBN(0x822e4556, 0xacf8edf9), + TOBN(0x2b7a6ee2, 0xe6a285cd), TOBN(0x5866f211, 0xa9df3af0), + TOBN(0x40dde2dd, 0xf845b844), TOBN(0x986c3726, 0x110e5e49), + TOBN(0x73680c2a, 0xf7172277), TOBN(0x57b94f0f, 0x0cccb244), + TOBN(0xbdff7267, 0x2d438ca7), TOBN(0xbad1ce11, 0xcf4663fd), + TOBN(0x9813ed9d, 0xd8f71cae), TOBN(0xf43272a6, 0x961fdaa6), + TOBN(0xbeff0119, 0xbd6d1637), TOBN(0xfebc4f91, 0x30361978), + TOBN(0x02b37a95, 0x2f41deff), TOBN(0x0e44a59a, 0xe63b89b7), + TOBN(0x673257dc, 0x143ff951), TOBN(0x19c02205, 0xd752baf4), + TOBN(0x46c23069, 0xc4b7d692), TOBN(0x2e6392c3, 0xfd1502ac), + TOBN(0x6057b1a2, 0x1b220846), TOBN(0xe51ff946, 0x0c1b5b63)}, + {TOBN(0x6e85cb51, 0x566c5c43), TOBN(0xcff9c919, 0x3597f046), + TOBN(0x9354e90c, 0x4994d94a), TOBN(0xe0a39332, 0x2147927d), + TOBN(0x8427fac1, 0x0dc1eb2b), TOBN(0x88cfd8c2, 0x2ff319fa), + TOBN(0xe2d4e684, 0x01965274), TOBN(0xfa2e067d, 0x67aaa746), + TOBN(0xb6d92a7f, 0x3e5f9f11), TOBN(0x9afe153a, 0xd6cb3b8e), + TOBN(0x4d1a6dd7, 0xddf800bd), TOBN(0xf6c13cc0, 0xcaf17e19), + TOBN(0x15f6c58e, 0x325fc3ee), TOBN(0x71095400, 0xa31dc3b2), + TOBN(0x168e7c07, 0xafa3d3e7), TOBN(0x3f8417a1, 0x94c7ae2d), + TOBN(0xec234772, 0x813b230d), TOBN(0x634d0f5f, 0x17344427), + TOBN(0x11548ab1, 0xd77fc56a), TOBN(0x7fab1750, 0xce06af77), + TOBN(0xb62c10a7, 0x4f7c4f83), TOBN(0xa7d2edc4, 0x220a67d9), + TOBN(0x1c404170, 0x921209a0), TOBN(0x0b9815a0, 0xface59f0), + TOBN(0x2842589b, 0x319540c3), TOBN(0x18490f59, 0xa283d6f8), + TOBN(0xa2731f84, 0xdaae9fcb), TOBN(0x3db6d960, 0xc3683ba0), + TOBN(0xc85c63bb, 0x14611069), TOBN(0xb19436af, 0x0788bf05), + TOBN(0x905459df, 0x347460d2), TOBN(0x73f6e094, 0xe11a7db1), + TOBN(0xdc7f938e, 0xb6357f37), TOBN(0xc5d00f79, 0x2bd8aa62), + TOBN(0xc878dcb9, 0x2ca979fc), TOBN(0x37e83ed9, 0xeb023a99), + TOBN(0x6b23e273, 0x1560bf3d), TOBN(0x1086e459, 0x1d0fae61), + TOBN(0x78248316, 0x9a9414bd), TOBN(0x1b956bc0, 0xf0ea9ea1), + TOBN(0x7b85bb91, 0xc31b9c38), TOBN(0x0c5aa90b, 0x48ef57b5), + TOBN(0xdedeb169, 0xaf3bab6f), TOBN(0xe610ad73, 0x2d373685), + TOBN(0xf13870df, 0x02ba8e15), TOBN(0x0337edb6, 0x8ca7f771), + TOBN(0xe4acf747, 0xb62c036c), TOBN(0xd921d576, 0xb6b94e81), + TOBN(0xdbc86439, 0x2c422f7a), TOBN(0xfb635362, 0xed348898), + TOBN(0x83084668, 0xc45bfcd1), TOBN(0xc357c9e3, 0x2b315e11), + TOBN(0xb173b540, 0x5b2e5b8c), TOBN(0x7e946931, 0xe102b9a4), + TOBN(0x17c890eb, 0x7b0fb199), TOBN(0xec225a83, 0xd61b662b), + TOBN(0xf306a3c8, 0xee3c76cb), TOBN(0x3cf11623, 0xd32a1f6e), + TOBN(0xe6d5ab64, 0x6863e956), TOBN(0x3b8a4cbe, 0x5c005c26), + TOBN(0xdcd529a5, 0x9ce6bb27), TOBN(0xc4afaa52, 0x04d4b16f), + TOBN(0xb0624a26, 0x7923798d), TOBN(0x85e56df6, 0x6b307fab), + TOBN(0x0281893c, 0x2bf29698), TOBN(0x91fc19a4, 0xd7ce7603), + TOBN(0x75a5dca3, 0xad9a558f), TOBN(0x40ceb3fa, 0x4d50bf77), + TOBN(0x1baf6060, 0xbc9ba369), TOBN(0x927e1037, 0x597888c2), + TOBN(0xd936bf19, 0x86a34c07), TOBN(0xd4cf10c1, 0xc34ae980), + TOBN(0x3a3e5334, 0x859dd614), TOBN(0x9c475b5b, 0x18d0c8ee), + TOBN(0x63080d1f, 0x07cd51d5), TOBN(0xc9c0d0a6, 0xb88b4326), + TOBN(0x1ac98691, 0xc234296f), TOBN(0x2a0a83a4, 0x94887fb6), + TOBN(0x56511427, 0x0cea9cf2), TOBN(0x5230a6e8, 0xa24802f5), + TOBN(0xf7a2bf0f, 0x72e3d5c1), TOBN(0x37717446, 0x4f21439e), + TOBN(0xfedcbf25, 0x9ce30334), TOBN(0xe0030a78, 0x7ce202f9), + TOBN(0x6f2d9ebf, 0x1202e9ca), TOBN(0xe79dde6c, 0x75e6e591), + TOBN(0xf52072af, 0xf1dac4f8), TOBN(0x6c8d087e, 0xbb9b404d), + TOBN(0xad0fc73d, 0xbce913af), TOBN(0x909e587b, 0x458a07cb), + TOBN(0x1300da84, 0xd4f00c8a), TOBN(0x425cd048, 0xb54466ac), + TOBN(0xb59cb9be, 0x90e9d8bf), TOBN(0x991616db, 0x3e431b0e), + TOBN(0xd3aa117a, 0x531aecff), TOBN(0x91af92d3, 0x59f4dc3b), + TOBN(0x9b1ec292, 0xe93fda29), TOBN(0x76bb6c17, 0xe97d91bc), + TOBN(0x7509d95f, 0xaface1e6), TOBN(0x3653fe47, 0xbe855ae3), + TOBN(0x73180b28, 0x0f680e75), TOBN(0x75eefd1b, 0xeeb6c26c), + TOBN(0xa4cdf29f, 0xb66d4236), TOBN(0x2d70a997, 0x6b5821d8), + TOBN(0x7a3ee207, 0x20445c36), TOBN(0x71d1ac82, 0x59877174), + TOBN(0x0fc539f7, 0x949f73e9), TOBN(0xd05cf3d7, 0x982e3081), + TOBN(0x8758e20b, 0x7b1c7129), TOBN(0xffadcc20, 0x569e61f2), + TOBN(0xb05d3a2f, 0x59544c2d), TOBN(0xbe16f5c1, 0x9fff5e53), + TOBN(0x73cf65b8, 0xaad58135), TOBN(0x622c2119, 0x037aa5be), + TOBN(0x79373b3f, 0x646fd6a0), TOBN(0x0e029db5, 0x0d3978cf), + TOBN(0x8bdfc437, 0x94fba037), TOBN(0xaefbd687, 0x620797a6), + TOBN(0x3fa5382b, 0xbd30d38e), TOBN(0x7627cfbf, 0x585d7464), + TOBN(0xb2330fef, 0x4e4ca463), TOBN(0xbcef7287, 0x3566cc63), + TOBN(0xd161d2ca, 0xcf780900), TOBN(0x135dc539, 0x5b54827d), + TOBN(0x638f052e, 0x27bf1bc6), TOBN(0x10a224f0, 0x07dfa06c), + TOBN(0xe973586d, 0x6d3321da), TOBN(0x8b0c5738, 0x26152c8f), + TOBN(0x07ef4f2a, 0x34606074), TOBN(0x80fe7fe8, 0xa0f7047a), + TOBN(0x3d1a8152, 0xe1a0e306), TOBN(0x32cf43d8, 0x88da5222), + TOBN(0xbf89a95f, 0x5f02ffe6), TOBN(0x3d9eb9a4, 0x806ad3ea), + TOBN(0x012c17bb, 0x79c8e55e), TOBN(0xfdcd1a74, 0x99c81dac), + TOBN(0x7043178b, 0xb9556098), TOBN(0x4090a1df, 0x801c3886), + TOBN(0x759800ff, 0x9b67b912), TOBN(0x3e5c0304, 0x232620c8), + TOBN(0x4b9d3c4b, 0x70dceeca), TOBN(0xbb2d3c15, 0x181f648e), + TOBN(0xf981d837, 0x6e33345c), TOBN(0xb626289b, 0x0cf2297a), + TOBN(0x766ac659, 0x8baebdcf), TOBN(0x1a28ae09, 0x75df01e5), + TOBN(0xb71283da, 0x375876d8), TOBN(0x4865a96d, 0x607b9800), + TOBN(0x25dd1bcd, 0x237936b2), TOBN(0x332f4f4b, 0x60417494), + TOBN(0xd0923d68, 0x370a2147), TOBN(0x497f5dfb, 0xdc842203), + TOBN(0x9dc74cbd, 0x32be5e0f), TOBN(0x7475bcb7, 0x17a01375), + TOBN(0x438477c9, 0x50d872b1), TOBN(0xcec67879, 0xffe1d63d), + TOBN(0x9b006014, 0xd8578c70), TOBN(0xc9ad99a8, 0x78bb6b8b), + TOBN(0x6799008e, 0x11fb3806), TOBN(0xcfe81435, 0xcd44cab3), + TOBN(0xa2ee1582, 0x2f4fb344), TOBN(0xb8823450, 0x483fa6eb), + TOBN(0x622d323d, 0x652c7749), TOBN(0xd8474a98, 0xbeb0a15b), + TOBN(0xe43c154d, 0x5d1c00d0), TOBN(0x7fd581d9, 0x0e3e7aac), + TOBN(0x2b44c619, 0x2525ddf8), TOBN(0x67a033eb, 0xb8ae9739), + TOBN(0x113ffec1, 0x9ef2d2e4), TOBN(0x1bf6767e, 0xd5a0ea7f), + TOBN(0x57fff75e, 0x03714c0a), TOBN(0xa23c422e, 0x0a23e9ee), + TOBN(0xdd5f6b2d, 0x540f83af), TOBN(0xc2c2c27e, 0x55ea46a7), + TOBN(0xeb6b4246, 0x672a1208), TOBN(0xd13599f7, 0xae634f7a), + TOBN(0xcf914b5c, 0xd7b32c6e), TOBN(0x61a5a640, 0xeaf61814), + TOBN(0x8dc3df8b, 0x208a1bbb), TOBN(0xef627fd6, 0xb6d79aa5), + TOBN(0x44232ffc, 0xc4c86bc8), TOBN(0xe6f9231b, 0x061539fe), + TOBN(0x1d04f25a, 0x958b9533), TOBN(0x180cf934, 0x49e8c885), + TOBN(0x89689595, 0x9884aaf7), TOBN(0xb1959be3, 0x07b348a6), + TOBN(0x96250e57, 0x3c147c87), TOBN(0xae0efb3a, 0xdd0c61f8), + TOBN(0xed00745e, 0xca8c325e), TOBN(0x3c911696, 0xecff3f70), + TOBN(0x73acbc65, 0x319ad41d), TOBN(0x7b01a020, 0xf0b1c7ef), + TOBN(0xea32b293, 0x63a1483f), TOBN(0x89eabe71, 0x7a248f96), + TOBN(0x9c6231d3, 0x343157e5), TOBN(0x93a375e5, 0xdf3c546d), + TOBN(0xe76e9343, 0x6a2afe69), TOBN(0xc4f89100, 0xe166c88e), + TOBN(0x248efd0d, 0x4f872093), TOBN(0xae0eb3ea, 0x8fe0ea61), + TOBN(0xaf89790d, 0x9d79046e), TOBN(0x4d650f2d, 0x6cee0976), + TOBN(0xa3935d9a, 0x43071eca), TOBN(0x66fcd2c9, 0x283b0bfe), + TOBN(0x0e665eb5, 0x696605f1), TOBN(0xe77e5d07, 0xa54cd38d), + TOBN(0x90ee050a, 0x43d950cf), TOBN(0x86ddebda, 0xd32e69b5), + TOBN(0x6ad94a3d, 0xfddf7415), TOBN(0xf7fa1309, 0x3f6e8d5a), + TOBN(0xc4831d1d, 0xe9957f75), TOBN(0x7de28501, 0xd5817447), + TOBN(0x6f1d7078, 0x9e2aeb6b), TOBN(0xba2b9ff4, 0xf67a53c2), + TOBN(0x36963767, 0xdf9defc3), TOBN(0x479deed3, 0x0d38022c), + TOBN(0xd2edb89b, 0x3a8631e8), TOBN(0x8de855de, 0x7a213746), + TOBN(0xb2056cb7, 0xb00c5f11), TOBN(0xdeaefbd0, 0x2c9b85e4), + TOBN(0x03f39a8d, 0xd150892d), TOBN(0x37b84686, 0x218b7985), + TOBN(0x36296dd8, 0xb7375f1a), TOBN(0x472cd4b1, 0xb78e898e), + TOBN(0x15dff651, 0xe9f05de9), TOBN(0xd4045069, 0x2ce98ba9), + TOBN(0x8466a7ae, 0x9b38024c), TOBN(0xb910e700, 0xe5a6b5ef), + TOBN(0xae1c56ea, 0xb3aa8f0d), TOBN(0xbab2a507, 0x7eee74a6), + TOBN(0x0dca11e2, 0x4b4c4620), TOBN(0xfd896e2e, 0x4c47d1f4), + TOBN(0xeb45ae53, 0x308fbd93), TOBN(0x46cd5a2e, 0x02c36fda), + TOBN(0x6a3d4e90, 0xbaa48385), TOBN(0xdd55e62e, 0x9dbe9960), + TOBN(0xa1406aa0, 0x2a81ede7), TOBN(0x6860dd14, 0xf9274ea7), + TOBN(0xcfdcb0c2, 0x80414f86), TOBN(0xff410b10, 0x22f94327), + TOBN(0x5a33cc38, 0x49ad467b), TOBN(0xefb48b6c, 0x0a7335f1), + TOBN(0x14fb54a4, 0xb153a360), TOBN(0x604aa9d2, 0xb52469cc), + TOBN(0x5e9dc486, 0x754e48e9), TOBN(0x693cb455, 0x37471e8e), + TOBN(0xfb2fd7cd, 0x8d3b37b6), TOBN(0x63345e16, 0xcf09ff07), + TOBN(0x9910ba6b, 0x23a5d896), TOBN(0x1fe19e35, 0x7fe4364e), + TOBN(0x6e1da8c3, 0x9a33c677), TOBN(0x15b4488b, 0x29fd9fd0), + TOBN(0x1f439254, 0x1a1f22bf), TOBN(0x920a8a70, 0xab8163e8), + TOBN(0x3fd1b249, 0x07e5658e), TOBN(0xf2c4f79c, 0xb6ec839b), + TOBN(0x1abbc3d0, 0x4aa38d1b), TOBN(0x3b0db35c, 0xb5d9510e), + TOBN(0x1754ac78, 0x3e60dec0), TOBN(0x53272fd7, 0xea099b33), + TOBN(0x5fb0494f, 0x07a8e107), TOBN(0x4a89e137, 0x6a8191fa), + TOBN(0xa113b7f6, 0x3c4ad544), TOBN(0x88a2e909, 0x6cb9897b), + TOBN(0x17d55de3, 0xb44a3f84), TOBN(0xacb2f344, 0x17c6c690), + TOBN(0x32088168, 0x10232390), TOBN(0xf2e8a61f, 0x6c733bf7), + TOBN(0xa774aab6, 0x9c2d7652), TOBN(0xfb5307e3, 0xed95c5bc), + TOBN(0xa05c73c2, 0x4981f110), TOBN(0x1baae31c, 0xa39458c9), + TOBN(0x1def185b, 0xcbea62e7), TOBN(0xe8ac9eae, 0xeaf63059), + TOBN(0x098a8cfd, 0x9921851c), TOBN(0xd959c3f1, 0x3abe2f5b), + TOBN(0xa4f19525, 0x20e40ae5), TOBN(0x320789e3, 0x07a24aa1), + TOBN(0x259e6927, 0x7392b2bc), TOBN(0x58f6c667, 0x1918668b), + TOBN(0xce1db2bb, 0xc55d2d8b), TOBN(0x41d58bb7, 0xf4f6ca56), + TOBN(0x7650b680, 0x8f877614), TOBN(0x905e16ba, 0xf4c349ed), + TOBN(0xed415140, 0xf661acac), TOBN(0x3b8784f0, 0xcb2270af), + TOBN(0x3bc280ac, 0x8a402cba), TOBN(0xd53f7146, 0x0937921a), + TOBN(0xc03c8ee5, 0xe5681e83), TOBN(0x62126105, 0xf6ac9e4a), + TOBN(0x9503a53f, 0x936b1a38), TOBN(0x3d45e2d4, 0x782fecbd), + TOBN(0x69a5c439, 0x76e8ae98), TOBN(0xb53b2eeb, 0xbfb4b00e), + TOBN(0xf1674712, 0x72386c89), TOBN(0x30ca34a2, 0x4268bce4), + TOBN(0x7f1ed86c, 0x78341730), TOBN(0x8ef5beb8, 0xb525e248), + TOBN(0xbbc489fd, 0xb74fbf38), TOBN(0x38a92a0e, 0x91a0b382), + TOBN(0x7a77ba3f, 0x22433ccf), TOBN(0xde8362d6, 0xa29f05a9), + TOBN(0x7f6a30ea, 0x61189afc), TOBN(0x693b5505, 0x59ef114f), + TOBN(0x50266bc0, 0xcd1797a1), TOBN(0xea17b47e, 0xf4b7af2d), + TOBN(0xd6c4025c, 0x3df9483e), TOBN(0x8cbb9d9f, 0xa37b18c9), + TOBN(0x91cbfd9c, 0x4d8424cf), TOBN(0xdb7048f1, 0xab1c3506), + TOBN(0x9eaf641f, 0x028206a3), TOBN(0xf986f3f9, 0x25bdf6ce), + TOBN(0x262143b5, 0x224c08dc), TOBN(0x2bbb09b4, 0x81b50c91), + TOBN(0xc16ed709, 0xaca8c84f), TOBN(0xa6210d9d, 0xb2850ca8), + TOBN(0x6d8df67a, 0x09cb54d6), TOBN(0x91eef6e0, 0x500919a4), + TOBN(0x90f61381, 0x0f132857), TOBN(0x9acede47, 0xf8d5028b), + TOBN(0x844d1b71, 0x90b771c3), TOBN(0x563b71e4, 0xba6426be), + TOBN(0x2efa2e83, 0xbdb802ff), TOBN(0x3410cbab, 0xab5b4a41), + TOBN(0x555b2d26, 0x30da84dd), TOBN(0xd0711ae9, 0xee1cc29a), + TOBN(0xcf3e8c60, 0x2f547792), TOBN(0x03d7d5de, 0xdc678b35), + TOBN(0x071a2fa8, 0xced806b8), TOBN(0x222e6134, 0x697f1478), + TOBN(0xdc16fd5d, 0xabfcdbbf), TOBN(0x44912ebf, 0x121b53b8), + TOBN(0xac943674, 0x2496c27c), TOBN(0x8ea3176c, 0x1ffc26b0), + TOBN(0xb6e224ac, 0x13debf2c), TOBN(0x524cc235, 0xf372a832), + TOBN(0xd706e1d8, 0x9f6f1b18), TOBN(0x2552f005, 0x44cce35b), + TOBN(0x8c8326c2, 0xa88e31fc), TOBN(0xb5468b2c, 0xf9552047), + TOBN(0xce683e88, 0x3ff90f2b), TOBN(0x77947bdf, 0x2f0a5423), + TOBN(0xd0a1b28b, 0xed56e328), TOBN(0xaee35253, 0xc20134ac), + TOBN(0x7e98367d, 0x3567962f), TOBN(0x379ed61f, 0x8188bffb), + TOBN(0x73bba348, 0xfaf130a1), TOBN(0x6c1f75e1, 0x904ed734), + TOBN(0x18956642, 0x3b4a79fc), TOBN(0xf20bc83d, 0x54ef4493), + TOBN(0x836d425d, 0x9111eca1), TOBN(0xe5b5c318, 0x009a8dcf), + TOBN(0x3360b25d, 0x13221bc5), TOBN(0x707baad2, 0x6b3eeaf7), + TOBN(0xd7279ed8, 0x743a95a1), TOBN(0x7450a875, 0x969e809f), + TOBN(0x32b6bd53, 0xe5d0338f), TOBN(0x1e77f7af, 0x2b883bbc), + TOBN(0x90da12cc, 0x1063ecd0), TOBN(0xe2697b58, 0xc315be47), + TOBN(0x2771a5bd, 0xda85d534), TOBN(0x53e78c1f, 0xff980eea), + TOBN(0xadf1cf84, 0x900385e7), TOBN(0x7d3b14f6, 0xc9387b62), + TOBN(0x170e74b0, 0xcb8f2bd2), TOBN(0x2d50b486, 0x827fa993), + TOBN(0xcdbe8c9a, 0xf6f32bab), TOBN(0x55e906b0, 0xc3b93ab8), + TOBN(0x747f22fc, 0x8fe280d1), TOBN(0xcd8e0de5, 0xb2e114ab), + TOBN(0x5ab7dbeb, 0xe10b68b0), TOBN(0x9dc63a9c, 0xa480d4b2), + TOBN(0x78d4bc3b, 0x4be1495f), TOBN(0x25eb3db8, 0x9359122d), + TOBN(0x3f8ac05b, 0x0809cbdc), TOBN(0xbf4187bb, 0xd37c702f), + TOBN(0x84cea069, 0x1416a6a5), TOBN(0x8f860c79, 0x43ef881c), + TOBN(0x41311f8a, 0x38038a5d), TOBN(0xe78c2ec0, 0xfc612067), + TOBN(0x494d2e81, 0x5ad73581), TOBN(0xb4cc9e00, 0x59604097), + TOBN(0xff558aec, 0xf3612cba), TOBN(0x35beef7a, 0x9e36c39e), + TOBN(0x1845c7cf, 0xdbcf41b9), TOBN(0x5703662a, 0xaea997c0), + TOBN(0x8b925afe, 0xe402f6d8), TOBN(0xd0a1b1ae, 0x4dd72162), + TOBN(0x9f47b375, 0x03c41c4b), TOBN(0xa023829b, 0x0391d042), + TOBN(0x5f5045c3, 0x503b8b0a), TOBN(0x123c2688, 0x98c010e5), + TOBN(0x324ec0cc, 0x36ba06ee), TOBN(0xface3115, 0x3dd2cc0c), + TOBN(0xb364f3be, 0xf333e91f), TOBN(0xef8aff73, 0x28e832b0), + TOBN(0x1e9bad04, 0x2d05841b), TOBN(0x42f0e3df, 0x356a21e2), + TOBN(0xa3270bcb, 0x4add627e), TOBN(0xb09a8158, 0xd322e711), + TOBN(0x86e326a1, 0x0fee104a), TOBN(0xad7788f8, 0x3703f65d), + TOBN(0x7e765430, 0x47bc4833), TOBN(0x6cee582b, 0x2b9b893a), + TOBN(0x9cd2a167, 0xe8f55a7b), TOBN(0xefbee3c6, 0xd9e4190d), + TOBN(0x33ee7185, 0xd40c2e9d), TOBN(0x844cc9c5, 0xa380b548), + TOBN(0x323f8ecd, 0x66926e04), TOBN(0x0001e38f, 0x8110c1ba), + TOBN(0x8dbcac12, 0xfc6a7f07), TOBN(0xd65e1d58, 0x0cec0827), + TOBN(0xd2cd4141, 0xbe76ca2d), TOBN(0x7895cf5c, 0xe892f33a), + TOBN(0x956d230d, 0x367139d2), TOBN(0xa91abd3e, 0xd012c4c1), + TOBN(0x34fa4883, 0x87eb36bf), TOBN(0xc5f07102, 0x914b8fb4), + TOBN(0x90f0e579, 0xadb9c95f), TOBN(0xfe6ea8cb, 0x28888195), + TOBN(0x7b9b5065, 0xedfa9284), TOBN(0x6c510bd2, 0x2b8c8d65), + TOBN(0xd7b8ebef, 0xcbe8aafd), TOBN(0xedb3af98, 0x96b1da07), + TOBN(0x28ff779d, 0x6295d426), TOBN(0x0c4f6ac7, 0x3fa3ad7b), + TOBN(0xec44d054, 0x8b8e2604), TOBN(0x9b32a66d, 0x8b0050e1), + TOBN(0x1f943366, 0xf0476ce2), TOBN(0x7554d953, 0xa602c7b4), + TOBN(0xbe35aca6, 0x524f2809), TOBN(0xb6881229, 0xfd4edbea), + TOBN(0xe8cd0c8f, 0x508efb63), TOBN(0x9eb5b5c8, 0x6abcefc7), + TOBN(0xf5621f5f, 0xb441ab4f), TOBN(0x79e6c046, 0xb76a2b22), + TOBN(0x74a4792c, 0xe37a1f69), TOBN(0xcbd252cb, 0x03542b60), + TOBN(0x785f65d5, 0xb3c20bd3), TOBN(0x8dea6143, 0x4fabc60c), + TOBN(0x45e21446, 0xde673629), TOBN(0x57f7aa1e, 0x703c2d21), + TOBN(0xa0e99b7f, 0x98c868c7), TOBN(0x4e42f66d, 0x8b641676), + TOBN(0x602884dc, 0x91077896), TOBN(0xa0d690cf, 0xc2c9885b), + TOBN(0xfeb4da33, 0x3b9a5187), TOBN(0x5f789598, 0x153c87ee), + TOBN(0x2192dd47, 0x52b16dba), TOBN(0xdeefc0e6, 0x3524c1b1), + TOBN(0x465ea76e, 0xe4383693), TOBN(0x79401711, 0x361b8d98), + TOBN(0xa5f9ace9, 0xf21a15cb), TOBN(0x73d26163, 0xefee9aeb), + TOBN(0xcca844b3, 0xe677016c), TOBN(0x6c122b07, 0x57eaee06), + TOBN(0xb782dce7, 0x15f09690), TOBN(0x508b9b12, 0x2dfc0fc9), + TOBN(0x9015ab4b, 0x65d89fc6), TOBN(0x5e79dab7, 0xd6d5bb0f), + TOBN(0x64f021f0, 0x6c775aa2), TOBN(0xdf09d8cc, 0x37c7eca1), + TOBN(0x9a761367, 0xef2fa506), TOBN(0xed4ca476, 0x5b81eec6), + TOBN(0x262ede36, 0x10bbb8b5), TOBN(0x0737ce83, 0x0641ada3), + TOBN(0x4c94288a, 0xe9831ccc), TOBN(0x487fc1ce, 0x8065e635), + TOBN(0xb13d7ab3, 0xb8bb3659), TOBN(0xdea5df3e, 0x855e4120), + TOBN(0xb9a18573, 0x85eb0244), TOBN(0x1a1b8ea3, 0xa7cfe0a3), + TOBN(0x3b837119, 0x67b0867c), TOBN(0x8d5e0d08, 0x9d364520), + TOBN(0x52dccc1e, 0xd930f0e3), TOBN(0xefbbcec7, 0xbf20bbaf), + TOBN(0x99cffcab, 0x0263ad10), TOBN(0xd8199e6d, 0xfcd18f8a), + TOBN(0x64e2773f, 0xe9f10617), TOBN(0x0079e8e1, 0x08704848), + TOBN(0x1169989f, 0x8a342283), TOBN(0x8097799c, 0xa83012e6), + TOBN(0xece966cb, 0x8a6a9001), TOBN(0x93b3afef, 0x072ac7fc), + TOBN(0xe6893a2a, 0x2db3d5ba), TOBN(0x263dc462, 0x89bf4fdc), + TOBN(0x8852dfc9, 0xe0396673), TOBN(0x7ac70895, 0x3af362b6), + TOBN(0xbb9cce4d, 0x5c2f342b), TOBN(0xbf80907a, 0xb52d7aae), + TOBN(0x97f3d3cd, 0x2161bcd0), TOBN(0xb25b0834, 0x0962744d), + TOBN(0xc5b18ea5, 0x6c3a1dda), TOBN(0xfe4ec7eb, 0x06c92317), + TOBN(0xb787b890, 0xad1c4afe), TOBN(0xdccd9a92, 0x0ede801a), + TOBN(0x9ac6ddda, 0xdb58da1f), TOBN(0x22bbc12f, 0xb8cae6ee), + TOBN(0xc6f8bced, 0x815c4a43), TOBN(0x8105a92c, 0xf96480c7), + TOBN(0x0dc3dbf3, 0x7a859d51), TOBN(0xe3ec7ce6, 0x3041196b), + TOBN(0xd9f64b25, 0x0d1067c9), TOBN(0xf2321321, 0x3d1f8dd8), + TOBN(0x8b5c619c, 0x76497ee8), TOBN(0x5d2b0ac6, 0xc717370e), + TOBN(0x98204cb6, 0x4fcf68e1), TOBN(0x0bdec211, 0x62bc6792), + TOBN(0x6973ccef, 0xa63b1011), TOBN(0xf9e3fa97, 0xe0de1ac5), + TOBN(0x5efb693e, 0x3d0e0c8b), TOBN(0x037248e9, 0xd2d4fcb4)}, + {TOBN(0x80802dc9, 0x1ec34f9e), TOBN(0xd8772d35, 0x33810603), + TOBN(0x3f06d66c, 0x530cb4f3), TOBN(0x7be5ed0d, 0xc475c129), + TOBN(0xcb9e3c19, 0x31e82b10), TOBN(0xc63d2857, 0xc9ff6b4c), + TOBN(0xb92118c6, 0x92a1b45e), TOBN(0x0aec4414, 0x7285bbca), + TOBN(0xfc189ae7, 0x1e29a3ef), TOBN(0xcbe906f0, 0x4c93302e), + TOBN(0xd0107914, 0xceaae10e), TOBN(0xb7a23f34, 0xb68e19f8), + TOBN(0xe9d875c2, 0xefd2119d), TOBN(0x03198c6e, 0xfcadc9c8), + TOBN(0x65591bf6, 0x4da17113), TOBN(0x3cf0bbf8, 0x3d443038), + TOBN(0xae485bb7, 0x2b724759), TOBN(0x945353e1, 0xb2d4c63a), + TOBN(0x82159d07, 0xde7d6f2c), TOBN(0x389caef3, 0x4ec5b109), + TOBN(0x4a8ebb53, 0xdb65ef14), TOBN(0x2dc2cb7e, 0xdd99de43), + TOBN(0x816fa3ed, 0x83f2405f), TOBN(0x73429bb9, 0xc14208a3), + TOBN(0xb618d590, 0xb01e6e27), TOBN(0x047e2ccd, 0xe180b2dc), + TOBN(0xd1b299b5, 0x04aea4a9), TOBN(0x412c9e1e, 0x9fa403a4), + TOBN(0x88d28a36, 0x79407552), TOBN(0x49c50136, 0xf332b8e3), + TOBN(0x3a1b6fcc, 0xe668de19), TOBN(0x178851bc, 0x75122b97), + TOBN(0xb1e13752, 0xfb85fa4c), TOBN(0xd61257ce, 0x383c8ce9), + TOBN(0xd43da670, 0xd2f74dae), TOBN(0xa35aa23f, 0xbf846bbb), + TOBN(0x5e74235d, 0x4421fc83), TOBN(0xf6df8ee0, 0xc363473b), + TOBN(0x34d7f52a, 0x3c4aa158), TOBN(0x50d05aab, 0x9bc6d22e), + TOBN(0x8c56e735, 0xa64785f4), TOBN(0xbc56637b, 0x5f29cd07), + TOBN(0x53b2bb80, 0x3ee35067), TOBN(0x50235a0f, 0xdc919270), + TOBN(0x191ab6d8, 0xf2c4aa65), TOBN(0xc3475831, 0x8396023b), + TOBN(0x80400ba5, 0xf0f805ba), TOBN(0x8881065b, 0x5ec0f80f), + TOBN(0xc370e522, 0xcc1b5e83), TOBN(0xde2d4ad1, 0x860b8bfb), + TOBN(0xad364df0, 0x67b256df), TOBN(0x8f12502e, 0xe0138997), + TOBN(0x503fa0dc, 0x7783920a), TOBN(0xe80014ad, 0xc0bc866a), + TOBN(0x3f89b744, 0xd3064ba6), TOBN(0x03511dcd, 0xcba5dba5), + TOBN(0x197dd46d, 0x95a7b1a2), TOBN(0x9c4e7ad6, 0x3c6341fb), + TOBN(0x426eca29, 0x484c2ece), TOBN(0x9211e489, 0xde7f4f8a), + TOBN(0x14997f6e, 0xc78ef1f4), TOBN(0x2b2c0910, 0x06574586), + TOBN(0x17286a6e, 0x1c3eede8), TOBN(0x25f92e47, 0x0f60e018), + TOBN(0x805c5646, 0x31890a36), TOBN(0x703ef600, 0x57feea5b), + TOBN(0x389f747c, 0xaf3c3030), TOBN(0xe0e5daeb, 0x54dd3739), + TOBN(0xfe24a4c3, 0xc9c9f155), TOBN(0x7e4bf176, 0xb5393962), + TOBN(0x37183de2, 0xaf20bf29), TOBN(0x4a1bd7b5, 0xf95a8c3b), + TOBN(0xa83b9699, 0x46191d3d), TOBN(0x281fc8dd, 0x7b87f257), + TOBN(0xb18e2c13, 0x54107588), TOBN(0x6372def7, 0x9b2bafe8), + TOBN(0xdaf4bb48, 0x0d8972ca), TOBN(0x3f2dd4b7, 0x56167a3f), + TOBN(0x1eace32d, 0x84310cf4), TOBN(0xe3bcefaf, 0xe42700aa), + TOBN(0x5fe5691e, 0xd785e73d), TOBN(0xa5db5ab6, 0x2ea60467), + TOBN(0x02e23d41, 0xdfc6514a), TOBN(0x35e8048e, 0xe03c3665), + TOBN(0x3f8b118f, 0x1adaa0f8), TOBN(0x28ec3b45, 0x84ce1a5a), + TOBN(0xe8cacc6e, 0x2c6646b8), TOBN(0x1343d185, 0xdbd0e40f), + TOBN(0xe5d7f844, 0xcaaa358c), TOBN(0x1a1db7e4, 0x9924182a), + TOBN(0xd64cd42d, 0x9c875d9a), TOBN(0xb37b515f, 0x042eeec8), + TOBN(0x4d4dd409, 0x7b165fbe), TOBN(0xfc322ed9, 0xe206eff3), + TOBN(0x7dee4102, 0x59b7e17e), TOBN(0x55a481c0, 0x8236ca00), + TOBN(0x8c885312, 0xc23fc975), TOBN(0x15715806, 0x05d6297b), + TOBN(0xa078868e, 0xf78edd39), TOBN(0x956b31e0, 0x03c45e52), + TOBN(0x470275d5, 0xff7b33a6), TOBN(0xc8d5dc3a, 0x0c7e673f), + TOBN(0x419227b4, 0x7e2f2598), TOBN(0x8b37b634, 0x4c14a975), + TOBN(0xd0667ed6, 0x8b11888c), TOBN(0x5e0e8c3e, 0x803e25dc), + TOBN(0x34e5d0dc, 0xb987a24a), TOBN(0x9f40ac3b, 0xae920323), + TOBN(0x5463de95, 0x34e0f63a), TOBN(0xa128bf92, 0x6b6328f9), + TOBN(0x491ccd7c, 0xda64f1b7), TOBN(0x7ef1ec27, 0xc47bde35), + TOBN(0xa857240f, 0xa36a2737), TOBN(0x35dc1366, 0x63621bc1), + TOBN(0x7a3a6453, 0xd4fb6897), TOBN(0x80f1a439, 0xc929319d), + TOBN(0xfc18274b, 0xf8cb0ba0), TOBN(0xb0b53766, 0x8078c5eb), + TOBN(0xfb0d4924, 0x1e01d0ef), TOBN(0x50d7c67d, 0x372ab09c), + TOBN(0xb4e370af, 0x3aeac968), TOBN(0xe4f7fee9, 0xc4b63266), + TOBN(0xb4acd4c2, 0xe3ac5664), TOBN(0xf8910bd2, 0xceb38cbf), + TOBN(0x1c3ae50c, 0xc9c0726e), TOBN(0x15309569, 0xd97b40bf), + TOBN(0x70884b7f, 0xfd5a5a1b), TOBN(0x3890896a, 0xef8314cd), + TOBN(0x58e1515c, 0xa5618c93), TOBN(0xe665432b, 0x77d942d1), + TOBN(0xb32181bf, 0xb6f767a8), TOBN(0x753794e8, 0x3a604110), + TOBN(0x09afeb7c, 0xe8c0dbcc), TOBN(0x31e02613, 0x598673a3), + TOBN(0x5d98e557, 0x7d46db00), TOBN(0xfc21fb8c, 0x9d985b28), + TOBN(0xc9040116, 0xb0843e0b), TOBN(0x53b1b3a8, 0x69b04531), + TOBN(0xdd1649f0, 0x85d7d830), TOBN(0xbb3bcc87, 0xcb7427e8), + TOBN(0x77261100, 0xc93dce83), TOBN(0x7e79da61, 0xa1922a2a), + TOBN(0x587a2b02, 0xf3149ce8), TOBN(0x147e1384, 0xde92ec83), + TOBN(0x484c83d3, 0xaf077f30), TOBN(0xea78f844, 0x0658b53a), + TOBN(0x912076c2, 0x027aec53), TOBN(0xf34714e3, 0x93c8177d), + TOBN(0x37ef5d15, 0xc2376c84), TOBN(0x8315b659, 0x3d1aa783), + TOBN(0x3a75c484, 0xef852a90), TOBN(0x0ba0c58a, 0x16086bd4), + TOBN(0x29688d7a, 0x529a6d48), TOBN(0x9c7f250d, 0xc2f19203), + TOBN(0x123042fb, 0x682e2df9), TOBN(0x2b7587e7, 0xad8121bc), + TOBN(0x30fc0233, 0xe0182a65), TOBN(0xb82ecf87, 0xe3e1128a), + TOBN(0x71682861, 0x93fb098f), TOBN(0x043e21ae, 0x85e9e6a7), + TOBN(0xab5b49d6, 0x66c834ea), TOBN(0x3be43e18, 0x47414287), + TOBN(0xf40fb859, 0x219a2a47), TOBN(0x0e6559e9, 0xcc58df3c), + TOBN(0xfe1dfe8e, 0x0c6615b4), TOBN(0x14abc8fd, 0x56459d70), + TOBN(0x7be0fa8e, 0x05de0386), TOBN(0x8e63ef68, 0xe9035c7c), + TOBN(0x116401b4, 0x53b31e91), TOBN(0x0cba7ad4, 0x4436b4d8), + TOBN(0x9151f9a0, 0x107afd66), TOBN(0xafaca8d0, 0x1f0ee4c4), + TOBN(0x75fe5c1d, 0x9ee9761c), TOBN(0x3497a16b, 0xf0c0588f), + TOBN(0x3ee2bebd, 0x0304804c), TOBN(0xa8fb9a60, 0xc2c990b9), + TOBN(0xd14d32fe, 0x39251114), TOBN(0x36bf25bc, 0xcac73366), + TOBN(0xc9562c66, 0xdba7495c), TOBN(0x324d301b, 0x46ad348b), + TOBN(0x9f46620c, 0xd670407e), TOBN(0x0ea8d4f1, 0xe3733a01), + TOBN(0xd396d532, 0xb0c324e0), TOBN(0x5b211a0e, 0x03c317cd), + TOBN(0x090d7d20, 0x5ffe7b37), TOBN(0x3b7f3efb, 0x1747d2da), + TOBN(0xa2cb525f, 0xb54fc519), TOBN(0x6e220932, 0xf66a971e), + TOBN(0xddc160df, 0xb486d440), TOBN(0x7fcfec46, 0x3fe13465), + TOBN(0x83da7e4e, 0x76e4c151), TOBN(0xd6fa48a1, 0xd8d302b5), + TOBN(0xc6304f26, 0x5872cd88), TOBN(0x806c1d3c, 0x278b90a1), + TOBN(0x3553e725, 0xcaf0bc1c), TOBN(0xff59e603, 0xbb9d8d5c), + TOBN(0xa4550f32, 0x7a0b85dd), TOBN(0xdec5720a, 0x93ecc217), + TOBN(0x0b88b741, 0x69d62213), TOBN(0x7212f245, 0x5b365955), + TOBN(0x20764111, 0xb5cae787), TOBN(0x13cb7f58, 0x1dfd3124), + TOBN(0x2dca77da, 0x1175aefb), TOBN(0xeb75466b, 0xffaae775), + TOBN(0x74d76f3b, 0xdb6cff32), TOBN(0x7440f37a, 0x61fcda9a), + TOBN(0x1bb3ac92, 0xb525028b), TOBN(0x20fbf8f7, 0xa1975f29), + TOBN(0x982692e1, 0xdf83097f), TOBN(0x28738f6c, 0x554b0800), + TOBN(0xdc703717, 0xa2ce2f2f), TOBN(0x7913b93c, 0x40814194), + TOBN(0x04924593, 0x1fe89636), TOBN(0x7b98443f, 0xf78834a6), + TOBN(0x11c6ab01, 0x5114a5a1), TOBN(0x60deb383, 0xffba5f4c), + TOBN(0x4caa54c6, 0x01a982e6), TOBN(0x1dd35e11, 0x3491cd26), + TOBN(0x973c315f, 0x7cbd6b05), TOBN(0xcab00775, 0x52494724), + TOBN(0x04659b1f, 0x6565e15a), TOBN(0xbf30f529, 0x8c8fb026), + TOBN(0xfc21641b, 0xa8a0de37), TOBN(0xe9c7a366, 0xfa5e5114), + TOBN(0xdb849ca5, 0x52f03ad8), TOBN(0xc7e8dbe9, 0x024e35c0), + TOBN(0xa1a2bbac, 0xcfc3c789), TOBN(0xbf733e7d, 0x9c26f262), + TOBN(0x882ffbf5, 0xb8444823), TOBN(0xb7224e88, 0x6bf8483b), + TOBN(0x53023b8b, 0x65bef640), TOBN(0xaabfec91, 0xd4d5f8cd), + TOBN(0xa40e1510, 0x079ea1bd), TOBN(0x1ad9addc, 0xd05d5d26), + TOBN(0xdb3f2eab, 0x13e68d4f), TOBN(0x1cff1ae2, 0x640f803f), + TOBN(0xe0e7b749, 0xd4cee117), TOBN(0x8e9f275b, 0x4036d909), + TOBN(0xce34e31d, 0x8f4d4c38), TOBN(0x22b37f69, 0xd75130fc), + TOBN(0x83e0f1fd, 0xb4014604), TOBN(0xa8ce9919, 0x89415078), + TOBN(0x82375b75, 0x41792efe), TOBN(0x4f59bf5c, 0x97d4515b), + TOBN(0xac4f324f, 0x923a277d), TOBN(0xd9bc9b7d, 0x650f3406), + TOBN(0xc6fa87d1, 0x8a39bc51), TOBN(0x82588530, 0x5ccc108f), + TOBN(0x5ced3c9f, 0x82e4c634), TOBN(0x8efb8314, 0x3a4464f8), + TOBN(0xe706381b, 0x7a1dca25), TOBN(0x6cd15a3c, 0x5a2a412b), + TOBN(0x9347a8fd, 0xbfcd8fb5), TOBN(0x31db2eef, 0x6e54cd22), + TOBN(0xc4aeb11e, 0xf8d8932f), TOBN(0x11e7c1ed, 0x344411af), + TOBN(0x2653050c, 0xdc9a151e), TOBN(0x9edbfc08, 0x3bb0a859), + TOBN(0x926c81c7, 0xfd5691e7), TOBN(0x9c1b2342, 0x6f39019a), + TOBN(0x64a81c8b, 0x7f8474b9), TOBN(0x90657c07, 0x01761819), + TOBN(0x390b3331, 0x55e0375a), TOBN(0xc676c626, 0xb6ebc47d), + TOBN(0x51623247, 0xb7d6dee8), TOBN(0x0948d927, 0x79659313), + TOBN(0x99700161, 0xe9ab35ed), TOBN(0x06cc32b4, 0x8ddde408), + TOBN(0x6f2fd664, 0x061ef338), TOBN(0x1606fa02, 0xc202e9ed), + TOBN(0x55388bc1, 0x929ba99b), TOBN(0xc4428c5e, 0x1e81df69), + TOBN(0xce2028ae, 0xf91b0b2a), TOBN(0xce870a23, 0xf03dfd3f), + TOBN(0x66ec2c87, 0x0affe8ed), TOBN(0xb205fb46, 0x284d0c00), + TOBN(0xbf5dffe7, 0x44cefa48), TOBN(0xb6fc37a8, 0xa19876d7), + TOBN(0xbecfa84c, 0x08b72863), TOBN(0xd7205ff5, 0x2576374f), + TOBN(0x80330d32, 0x8887de41), TOBN(0x5de0df0c, 0x869ea534), + TOBN(0x13f42753, 0x3c56ea17), TOBN(0xeb1f6069, 0x452b1a78), + TOBN(0x50474396, 0xe30ea15c), TOBN(0x575816a1, 0xc1494125), + TOBN(0xbe1ce55b, 0xfe6bb38f), TOBN(0xb901a948, 0x96ae30f7), + TOBN(0xe5af0f08, 0xd8fc3548), TOBN(0x5010b5d0, 0xd73bfd08), + TOBN(0x993d2880, 0x53fe655a), TOBN(0x99f2630b, 0x1c1309fd), + TOBN(0xd8677baf, 0xb4e3b76f), TOBN(0x14e51ddc, 0xb840784b), + TOBN(0x326c750c, 0xbf0092ce), TOBN(0xc83d306b, 0xf528320f), + TOBN(0xc4456715, 0x77d4715c), TOBN(0xd30019f9, 0x6b703235), + TOBN(0x207ccb2e, 0xd669e986), TOBN(0x57c824af, 0xf6dbfc28), + TOBN(0xf0eb532f, 0xd8f92a23), TOBN(0x4a557fd4, 0x9bb98fd2), + TOBN(0xa57acea7, 0xc1e6199a), TOBN(0x0c663820, 0x8b94b1ed), + TOBN(0x9b42be8f, 0xf83a9266), TOBN(0xc7741c97, 0x0101bd45), + TOBN(0x95770c11, 0x07bd9ceb), TOBN(0x1f50250a, 0x8b2e0744), + TOBN(0xf762eec8, 0x1477b654), TOBN(0xc65b900e, 0x15efe59a), + TOBN(0x88c96148, 0x9546a897), TOBN(0x7e8025b3, 0xc30b4d7c), + TOBN(0xae4065ef, 0x12045cf9), TOBN(0x6fcb2caf, 0x9ccce8bd), + TOBN(0x1fa0ba4e, 0xf2cf6525), TOBN(0xf683125d, 0xcb72c312), + TOBN(0xa01da4ea, 0xe312410e), TOBN(0x67e28677, 0x6cd8e830), + TOBN(0xabd95752, 0x98fb3f07), TOBN(0x05f11e11, 0xeef649a5), + TOBN(0xba47faef, 0x9d3472c2), TOBN(0x3adff697, 0xc77d1345), + TOBN(0x4761fa04, 0xdd15afee), TOBN(0x64f1f61a, 0xb9e69462), + TOBN(0xfa691fab, 0x9bfb9093), TOBN(0x3df8ae8f, 0xa1133dfe), + TOBN(0xcd5f8967, 0x58cc710d), TOBN(0xfbb88d50, 0x16c7fe79), + TOBN(0x8e011b4c, 0xe88c50d1), TOBN(0x7532e807, 0xa8771c4f), + TOBN(0x64c78a48, 0xe2278ee4), TOBN(0x0b283e83, 0x3845072a), + TOBN(0x98a6f291, 0x49e69274), TOBN(0xb96e9668, 0x1868b21c), + TOBN(0x38f0adc2, 0xb1a8908e), TOBN(0x90afcff7, 0x1feb829d), + TOBN(0x9915a383, 0x210b0856), TOBN(0xa5a80602, 0xdef04889), + TOBN(0x800e9af9, 0x7c64d509), TOBN(0x81382d0b, 0xb8996f6f), + TOBN(0x490eba53, 0x81927e27), TOBN(0x46c63b32, 0x4af50182), + TOBN(0x784c5fd9, 0xd3ad62ce), TOBN(0xe4fa1870, 0xf8ae8736), + TOBN(0x4ec9d0bc, 0xd7466b25), TOBN(0x84ddbe1a, 0xdb235c65), + TOBN(0x5e2645ee, 0x163c1688), TOBN(0x570bd00e, 0x00eba747), + TOBN(0xfa51b629, 0x128bfa0f), TOBN(0x92fce1bd, 0x6c1d3b68), + TOBN(0x3e7361dc, 0xb66778b1), TOBN(0x9c7d249d, 0x5561d2bb), + TOBN(0xa40b28bf, 0x0bbc6229), TOBN(0x1c83c05e, 0xdfd91497), + TOBN(0x5f9f5154, 0xf083df05), TOBN(0xbac38b3c, 0xeee66c9d), + TOBN(0xf71db7e3, 0xec0dfcfd), TOBN(0xf2ecda8e, 0x8b0a8416), + TOBN(0x52fddd86, 0x7812aa66), TOBN(0x2896ef10, 0x4e6f4272), + TOBN(0xff27186a, 0x0fe9a745), TOBN(0x08249fcd, 0x49ca70db), + TOBN(0x7425a2e6, 0x441cac49), TOBN(0xf4a0885a, 0xece5ff57), + TOBN(0x6e2cb731, 0x7d7ead58), TOBN(0xf96cf7d6, 0x1898d104), + TOBN(0xafe67c9d, 0x4f2c9a89), TOBN(0x89895a50, 0x1c7bf5bc), + TOBN(0xdc7cb8e5, 0x573cecfa), TOBN(0x66497eae, 0xd15f03e6), + TOBN(0x6bc0de69, 0x3f084420), TOBN(0x323b9b36, 0xacd532b0), + TOBN(0xcfed390a, 0x0115a3c1), TOBN(0x9414c40b, 0x2d65ca0e), + TOBN(0x641406bd, 0x2f530c78), TOBN(0x29369a44, 0x833438f2), + TOBN(0x996884f5, 0x903fa271), TOBN(0xe6da0fd2, 0xb9da921e), + TOBN(0xa6f2f269, 0x5db01e54), TOBN(0x1ee3e9bd, 0x6876214e), + TOBN(0xa26e181c, 0xe27a9497), TOBN(0x36d254e4, 0x8e215e04), + TOBN(0x42f32a6c, 0x252cabca), TOBN(0x99481487, 0x80b57614), + TOBN(0x4c4dfe69, 0x40d9cae1), TOBN(0x05869580, 0x11a10f09), + TOBN(0xca287b57, 0x3491b64b), TOBN(0x77862d5d, 0x3fd4a53b), + TOBN(0xbf94856e, 0x50349126), TOBN(0x2be30bd1, 0x71c5268f), + TOBN(0x10393f19, 0xcbb650a6), TOBN(0x639531fe, 0x778cf9fd), + TOBN(0x02556a11, 0xb2935359), TOBN(0xda38aa96, 0xaf8c126e), + TOBN(0x47dbe6c2, 0x0960167f), TOBN(0x37bbabb6, 0x501901cd), + TOBN(0xb6e979e0, 0x2c947778), TOBN(0xd69a5175, 0x7a1a1dc6), + TOBN(0xc3ed5095, 0x9d9faf0c), TOBN(0x4dd9c096, 0x1d5fa5f0), + TOBN(0xa0c4304d, 0x64f16ea8), TOBN(0x8b1cac16, 0x7e718623), + TOBN(0x0b576546, 0x7c67f03e), TOBN(0x559cf5ad, 0xcbd88c01), + TOBN(0x074877bb, 0x0e2af19a), TOBN(0x1f717ec1, 0xa1228c92), + TOBN(0x70bcb800, 0x326e8920), TOBN(0xec6e2c5c, 0x4f312804), + TOBN(0x426aea7d, 0x3fca4752), TOBN(0xf12c0949, 0x2211f62a), + TOBN(0x24beecd8, 0x7be7b6b5), TOBN(0xb77eaf4c, 0x36d7a27d), + TOBN(0x154c2781, 0xfda78fd3), TOBN(0x848a83b0, 0x264eeabe), + TOBN(0x81287ef0, 0x4ffe2bc4), TOBN(0x7b6d88c6, 0xb6b6fc2a), + TOBN(0x805fb947, 0xce417d99), TOBN(0x4b93dcc3, 0x8b916cc4), + TOBN(0x72e65bb3, 0x21273323), TOBN(0xbcc1badd, 0x6ea9886e), + TOBN(0x0e223011, 0x4bc5ee85), TOBN(0xa561be74, 0xc18ee1e4), + TOBN(0x762fd2d4, 0xa6bcf1f1), TOBN(0x50e6a5a4, 0x95231489), + TOBN(0xca96001f, 0xa00b500b), TOBN(0x5c098cfc, 0x5d7dcdf5), + TOBN(0xa64e2d2e, 0x8c446a85), TOBN(0xbae9bcf1, 0x971f3c62), + TOBN(0x4ec22683, 0x8435a2c5), TOBN(0x8ceaed6c, 0x4bad4643), + TOBN(0xe9f8fb47, 0xccccf4e3), TOBN(0xbd4f3fa4, 0x1ce3b21e), + TOBN(0xd79fb110, 0xa3db3292), TOBN(0xe28a37da, 0xb536c66a), + TOBN(0x279ce87b, 0x8e49e6a9), TOBN(0x70ccfe8d, 0xfdcec8e3), + TOBN(0x2193e4e0, 0x3ba464b2), TOBN(0x0f39d60e, 0xaca9a398), + TOBN(0x7d7932af, 0xf82c12ab), TOBN(0xd8ff50ed, 0x91e7e0f7), + TOBN(0xea961058, 0xfa28a7e0), TOBN(0xc726cf25, 0x0bf5ec74), + TOBN(0xe74d55c8, 0xdb229666), TOBN(0x0bd9abbf, 0xa57f5799), + TOBN(0x7479ef07, 0x4dfc47b3), TOBN(0xd9c65fc3, 0x0c52f91d), + TOBN(0x8e0283fe, 0x36a8bde2), TOBN(0xa32a8b5e, 0x7d4b7280), + TOBN(0x6a677c61, 0x12e83233), TOBN(0x0fbb3512, 0xdcc9bf28), + TOBN(0x562e8ea5, 0x0d780f61), TOBN(0x0db8b22b, 0x1dc4e89c), + TOBN(0x0a6fd1fb, 0x89be0144), TOBN(0x8c77d246, 0xca57113b), + TOBN(0x4639075d, 0xff09c91c), TOBN(0x5b47b17f, 0x5060824c), + TOBN(0x58aea2b0, 0x16287b52), TOBN(0xa1343520, 0xd0cd8eb0), + TOBN(0x6148b4d0, 0xc5d58573), TOBN(0xdd2b6170, 0x291c68ae), + TOBN(0xa61b3929, 0x1da3b3b7), TOBN(0x5f946d79, 0x08c4ac10), + TOBN(0x4105d4a5, 0x7217d583), TOBN(0x5061da3d, 0x25e6de5e), + TOBN(0x3113940d, 0xec1b4991), TOBN(0xf12195e1, 0x36f485ae), + TOBN(0xa7507fb2, 0x731a2ee0), TOBN(0x95057a8e, 0x6e9e196e), + TOBN(0xa3c2c911, 0x2e130136), TOBN(0x97dfbb36, 0x33c60d15), + TOBN(0xcaf3c581, 0xb300ee2b), TOBN(0x77f25d90, 0xf4bac8b8), + TOBN(0xdb1c4f98, 0x6d840cd6), TOBN(0x471d62c0, 0xe634288c), + TOBN(0x8ec2f85e, 0xcec8a161), TOBN(0x41f37cbc, 0xfa6f4ae2), + TOBN(0x6793a20f, 0x4b709985), TOBN(0x7a7bd33b, 0xefa8985b), + TOBN(0x2c6a3fbd, 0x938e6446), TOBN(0x19042619, 0x2a8d47c1), + TOBN(0x16848667, 0xcc36975f), TOBN(0x02acf168, 0x9d5f1dfb), + TOBN(0x62d41ad4, 0x613baa94), TOBN(0xb56fbb92, 0x9f684670), + TOBN(0xce610d0d, 0xe9e40569), TOBN(0x7b99c65f, 0x35489fef), + TOBN(0x0c88ad1b, 0x3df18b97), TOBN(0x81b7d9be, 0x5d0e9edb), + TOBN(0xd85218c0, 0xc716cc0a), TOBN(0xf4b5ff90, 0x85691c49), + TOBN(0xa4fd666b, 0xce356ac6), TOBN(0x17c72895, 0x4b327a7a), + TOBN(0xf93d5085, 0xda6be7de), TOBN(0xff71530e, 0x3301d34e), + TOBN(0x4cd96442, 0xd8f448e8), TOBN(0x9283d331, 0x2ed18ffa), + TOBN(0x4d33dd99, 0x2a849870), TOBN(0xa716964b, 0x41576335), + TOBN(0xff5e3a9b, 0x179be0e5), TOBN(0x5b9d6b1b, 0x83b13632), + TOBN(0x3b8bd7d4, 0xa52f313b), TOBN(0xc9dd95a0, 0x637a4660), + TOBN(0x30035962, 0x0b3e218f), TOBN(0xce1481a3, 0xc7b28a3c), + TOBN(0xab41b43a, 0x43228d83), TOBN(0x24ae1c30, 0x4ad63f99), + TOBN(0x8e525f1a, 0x46a51229), TOBN(0x14af860f, 0xcd26d2b4), + TOBN(0xd6baef61, 0x3f714aa1), TOBN(0xf51865ad, 0xeb78795e), + TOBN(0xd3e21fce, 0xe6a9d694), TOBN(0x82ceb1dd, 0x8a37b527)}}; diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/ec/p256-x86_64-table.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/ec/p256-x86_64-table.h.grpc_back new file mode 100644 index 0000000..bcb05f6 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/ec/p256-x86_64-table.h.grpc_back @@ -0,0 +1,9503 @@ +/* Copyright (c) 2015, Intel Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +// This is the precomputed constant time access table for the code in +// p256-x86_64.c, for the default generator. The table consists of 37 +// subtables, each subtable contains 64 affine points. The affine points are +// encoded as eight uint64's, four for the x coordinate and four for the y. +// Both values are in little-endian order. There are 37 tables because a +// signed, 6-bit wNAF form of the scalar is used and ceil(256/(6 + 1)) = 37. +// Within each table there are 64 values because the 6-bit wNAF value can take +// 64 values, ignoring the sign bit, which is implemented by performing a +// negation of the affine point when required. We would like to align it to 2MB +// in order to increase the chances of using a large page but that appears to +// lead to invalid ELF files being produced. + +// This file is generated by make_p256-x86_64-table.go. + +static const alignas(4096) BN_ULONG + ecp_nistz256_precomputed[37][64 * sizeof(P256_POINT_AFFINE) / + sizeof(BN_ULONG)] = { + {TOBN(0x79e730d4, 0x18a9143c), TOBN(0x75ba95fc, 0x5fedb601), + TOBN(0x79fb732b, 0x77622510), TOBN(0x18905f76, 0xa53755c6), + TOBN(0xddf25357, 0xce95560a), TOBN(0x8b4ab8e4, 0xba19e45c), + TOBN(0xd2e88688, 0xdd21f325), TOBN(0x8571ff18, 0x25885d85), + TOBN(0x850046d4, 0x10ddd64d), TOBN(0xaa6ae3c1, 0xa433827d), + TOBN(0x73220503, 0x8d1490d9), TOBN(0xf6bb32e4, 0x3dcf3a3b), + TOBN(0x2f3648d3, 0x61bee1a5), TOBN(0x152cd7cb, 0xeb236ff8), + TOBN(0x19a8fb0e, 0x92042dbe), TOBN(0x78c57751, 0x0a5b8a3b), + TOBN(0xffac3f90, 0x4eebc127), TOBN(0xb027f84a, 0x087d81fb), + TOBN(0x66ad77dd, 0x87cbbc98), TOBN(0x26936a3f, 0xb6ff747e), + TOBN(0xb04c5c1f, 0xc983a7eb), TOBN(0x583e47ad, 0x0861fe1a), + TOBN(0x78820831, 0x1a2ee98e), TOBN(0xd5f06a29, 0xe587cc07), + TOBN(0x74b0b50d, 0x46918dcc), TOBN(0x4650a6ed, 0xc623c173), + TOBN(0x0cdaacac, 0xe8100af2), TOBN(0x577362f5, 0x41b0176b), + TOBN(0x2d96f24c, 0xe4cbaba6), TOBN(0x17628471, 0xfad6f447), + TOBN(0x6b6c36de, 0xe5ddd22e), TOBN(0x84b14c39, 0x4c5ab863), + TOBN(0xbe1b8aae, 0xc45c61f5), TOBN(0x90ec649a, 0x94b9537d), + TOBN(0x941cb5aa, 0xd076c20c), TOBN(0xc9079605, 0x890523c8), + TOBN(0xeb309b4a, 0xe7ba4f10), TOBN(0x73c568ef, 0xe5eb882b), + TOBN(0x3540a987, 0x7e7a1f68), TOBN(0x73a076bb, 0x2dd1e916), + TOBN(0x40394737, 0x3e77664a), TOBN(0x55ae744f, 0x346cee3e), + TOBN(0xd50a961a, 0x5b17a3ad), TOBN(0x13074b59, 0x54213673), + TOBN(0x93d36220, 0xd377e44b), TOBN(0x299c2b53, 0xadff14b5), + TOBN(0xf424d44c, 0xef639f11), TOBN(0xa4c9916d, 0x4a07f75f), + TOBN(0x0746354e, 0xa0173b4f), TOBN(0x2bd20213, 0xd23c00f7), + TOBN(0xf43eaab5, 0x0c23bb08), TOBN(0x13ba5119, 0xc3123e03), + TOBN(0x2847d030, 0x3f5b9d4d), TOBN(0x6742f2f2, 0x5da67bdd), + TOBN(0xef933bdc, 0x77c94195), TOBN(0xeaedd915, 0x6e240867), + TOBN(0x27f14cd1, 0x9499a78f), TOBN(0x462ab5c5, 0x6f9b3455), + TOBN(0x8f90f02a, 0xf02cfc6b), TOBN(0xb763891e, 0xb265230d), + TOBN(0xf59da3a9, 0x532d4977), TOBN(0x21e3327d, 0xcf9eba15), + TOBN(0x123c7b84, 0xbe60bbf0), TOBN(0x56ec12f2, 0x7706df76), + TOBN(0x75c96e8f, 0x264e20e8), TOBN(0xabe6bfed, 0x59a7a841), + TOBN(0x2cc09c04, 0x44c8eb00), TOBN(0xe05b3080, 0xf0c4e16b), + TOBN(0x1eb7777a, 0xa45f3314), TOBN(0x56af7bed, 0xce5d45e3), + TOBN(0x2b6e019a, 0x88b12f1a), TOBN(0x086659cd, 0xfd835f9b), + TOBN(0x2c18dbd1, 0x9dc21ec8), TOBN(0x98f9868a, 0x0fcf8139), + TOBN(0x737d2cd6, 0x48250b49), TOBN(0xcc61c947, 0x24b3428f), + TOBN(0x0c2b4078, 0x80dd9e76), TOBN(0xc43a8991, 0x383fbe08), + TOBN(0x5f7d2d65, 0x779be5d2), TOBN(0x78719a54, 0xeb3b4ab5), + TOBN(0xea7d260a, 0x6245e404), TOBN(0x9de40795, 0x6e7fdfe0), + TOBN(0x1ff3a415, 0x8dac1ab5), TOBN(0x3e7090f1, 0x649c9073), + TOBN(0x1a768561, 0x2b944e88), TOBN(0x250f939e, 0xe57f61c8), + TOBN(0x0c0daa89, 0x1ead643d), TOBN(0x68930023, 0xe125b88e), + TOBN(0x04b71aa7, 0xd2697768), TOBN(0xabdedef5, 0xca345a33), + TOBN(0x2409d29d, 0xee37385e), TOBN(0x4ee1df77, 0xcb83e156), + TOBN(0x0cac12d9, 0x1cbb5b43), TOBN(0x170ed2f6, 0xca895637), + TOBN(0x28228cfa, 0x8ade6d66), TOBN(0x7ff57c95, 0x53238aca), + TOBN(0xccc42563, 0x4b2ed709), TOBN(0x0e356769, 0x856fd30d), + TOBN(0xbcbcd43f, 0x559e9811), TOBN(0x738477ac, 0x5395b759), + TOBN(0x35752b90, 0xc00ee17f), TOBN(0x68748390, 0x742ed2e3), + TOBN(0x7cd06422, 0xbd1f5bc1), TOBN(0xfbc08769, 0xc9e7b797), + TOBN(0xa242a35b, 0xb0cf664a), TOBN(0x126e48f7, 0x7f9707e3), + TOBN(0x1717bf54, 0xc6832660), TOBN(0xfaae7332, 0xfd12c72e), + TOBN(0x27b52db7, 0x995d586b), TOBN(0xbe29569e, 0x832237c2), + TOBN(0xe8e4193e, 0x2a65e7db), TOBN(0x152706dc, 0x2eaa1bbb), + TOBN(0x72bcd8b7, 0xbc60055b), TOBN(0x03cc23ee, 0x56e27e4b), + TOBN(0xee337424, 0xe4819370), TOBN(0xe2aa0e43, 0x0ad3da09), + TOBN(0x40b8524f, 0x6383c45d), TOBN(0xd7663554, 0x42a41b25), + TOBN(0x64efa6de, 0x778a4797), TOBN(0x2042170a, 0x7079adf4), + TOBN(0x808b0b65, 0x0bc6fb80), TOBN(0x5882e075, 0x3ffe2e6b), + TOBN(0xd5ef2f7c, 0x2c83f549), TOBN(0x54d63c80, 0x9103b723), + TOBN(0xf2f11bd6, 0x52a23f9b), TOBN(0x3670c319, 0x4b0b6587), + TOBN(0x55c4623b, 0xb1580e9e), TOBN(0x64edf7b2, 0x01efe220), + TOBN(0x97091dcb, 0xd53c5c9d), TOBN(0xf17624b6, 0xac0a177b), + TOBN(0xb0f13975, 0x2cfe2dff), TOBN(0xc1a35c0a, 0x6c7a574e), + TOBN(0x227d3146, 0x93e79987), TOBN(0x0575bf30, 0xe89cb80e), + TOBN(0x2f4e247f, 0x0d1883bb), TOBN(0xebd51226, 0x3274c3d0), + TOBN(0x5f3e51c8, 0x56ada97a), TOBN(0x4afc964d, 0x8f8b403e), + TOBN(0xa6f247ab, 0x412e2979), TOBN(0x675abd1b, 0x6f80ebda), + TOBN(0x66a2bd72, 0x5e485a1d), TOBN(0x4b2a5caf, 0x8f4f0b3c), + TOBN(0x2626927f, 0x1b847bba), TOBN(0x6c6fc7d9, 0x0502394d), + TOBN(0xfea912ba, 0xa5659ae8), TOBN(0x68363aba, 0x25e1a16e), + TOBN(0xb8842277, 0x752c41ac), TOBN(0xfe545c28, 0x2897c3fc), + TOBN(0x2d36e9e7, 0xdc4c696b), TOBN(0x5806244a, 0xfba977c5), + TOBN(0x85665e9b, 0xe39508c1), TOBN(0xf720ee25, 0x6d12597b), + TOBN(0x8a979129, 0xd2337a31), TOBN(0x5916868f, 0x0f862bdc), + TOBN(0x048099d9, 0x5dd283ba), TOBN(0xe2d1eeb6, 0xfe5bfb4e), + TOBN(0x82ef1c41, 0x7884005d), TOBN(0xa2d4ec17, 0xffffcbae), + TOBN(0x9161c53f, 0x8aa95e66), TOBN(0x5ee104e1, 0xc5fee0d0), + TOBN(0x562e4cec, 0xc135b208), TOBN(0x74e1b265, 0x4783f47d), + TOBN(0x6d2a506c, 0x5a3f3b30), TOBN(0xecead9f4, 0xc16762fc), + TOBN(0xf29dd4b2, 0xe286e5b9), TOBN(0x1b0fadc0, 0x83bb3c61), + TOBN(0x7a75023e, 0x7fac29a4), TOBN(0xc086d5f1, 0xc9477fa3), + TOBN(0x0fc61135, 0x2f6f3076), TOBN(0xc99ffa23, 0xe3912a9a), + TOBN(0x6a0b0685, 0xd2f8ba3d), TOBN(0xfdc777e8, 0xe93358a4), + TOBN(0x94a787bb, 0x35415f04), TOBN(0x640c2d6a, 0x4d23fea4), + TOBN(0x9de917da, 0x153a35b5), TOBN(0x793e8d07, 0x5d5cd074), + TOBN(0xf4f87653, 0x2de45068), TOBN(0x37c7a7e8, 0x9e2e1f6e), + TOBN(0xd0825fa2, 0xa3584069), TOBN(0xaf2cea7c, 0x1727bf42), + TOBN(0x0360a4fb, 0x9e4785a9), TOBN(0xe5fda49c, 0x27299f4a), + TOBN(0x48068e13, 0x71ac2f71), TOBN(0x83d0687b, 0x9077666f), + TOBN(0x6d3883b2, 0x15d02819), TOBN(0x6d0d7550, 0x40dd9a35), + TOBN(0x61d7cbf9, 0x1d2b469f), TOBN(0xf97b232f, 0x2efc3115), + TOBN(0xa551d750, 0xb24bcbc7), TOBN(0x11ea4949, 0x88a1e356), + TOBN(0x7669f031, 0x93cb7501), TOBN(0x595dc55e, 0xca737b8a), + TOBN(0xa4a319ac, 0xd837879f), TOBN(0x6fc1b49e, 0xed6b67b0), + TOBN(0xe3959933, 0x32f1f3af), TOBN(0x966742eb, 0x65432a2e), + TOBN(0x4b8dc9fe, 0xb4966228), TOBN(0x96cc6312, 0x43f43950), + TOBN(0x12068859, 0xc9b731ee), TOBN(0x7b948dc3, 0x56f79968), + TOBN(0x61e4ad32, 0xed1f8008), TOBN(0xe6c9267a, 0xd8b17538), + TOBN(0x1ac7c5eb, 0x857ff6fb), TOBN(0x994baaa8, 0x55f2fb10), + TOBN(0x84cf14e1, 0x1d248018), TOBN(0x5a39898b, 0x628ac508), + TOBN(0x14fde97b, 0x5fa944f5), TOBN(0xed178030, 0xd12e5ac7), + TOBN(0x042c2af4, 0x97e2feb4), TOBN(0xd36a42d7, 0xaebf7313), + TOBN(0x49d2c9eb, 0x084ffdd7), TOBN(0x9f8aa54b, 0x2ef7c76a), + TOBN(0x9200b7ba, 0x09895e70), TOBN(0x3bd0c66f, 0xddb7fb58), + TOBN(0x2d97d108, 0x78eb4cbb), TOBN(0x2d431068, 0xd84bde31), + TOBN(0x4b523eb7, 0x172ccd1f), TOBN(0x7323cb28, 0x30a6a892), + TOBN(0x97082ec0, 0xcfe153eb), TOBN(0xe97f6b6a, 0xf2aadb97), + TOBN(0x1d3d393e, 0xd1a83da1), TOBN(0xa6a7f9c7, 0x804b2a68), + TOBN(0x4a688b48, 0x2d0cb71e), TOBN(0xa9b4cc5f, 0x40585278), + TOBN(0x5e5db46a, 0xcb66e132), TOBN(0xf1be963a, 0x0d925880), + TOBN(0x944a7027, 0x0317b9e2), TOBN(0xe266f959, 0x48603d48), + TOBN(0x98db6673, 0x5c208899), TOBN(0x90472447, 0xa2fb18a3), + TOBN(0x8a966939, 0x777c619f), TOBN(0x3798142a, 0x2a3be21b), + TOBN(0xb4241cb1, 0x3298b343), TOBN(0xa3a14e49, 0xb44f65a1), + TOBN(0xc5f4d6cd, 0x3ac77acd), TOBN(0xd0288cb5, 0x52b6fc3c), + TOBN(0xd5cc8c2f, 0x1c040abc), TOBN(0xb675511e, 0x06bf9b4a), + TOBN(0xd667da37, 0x9b3aa441), TOBN(0x460d45ce, 0x51601f72), + TOBN(0xe2f73c69, 0x6755ff89), TOBN(0xdd3cf7e7, 0x473017e6), + TOBN(0x8ef5689d, 0x3cf7600d), TOBN(0x948dc4f8, 0xb1fc87b4), + TOBN(0xd9e9fe81, 0x4ea53299), TOBN(0x2d921ca2, 0x98eb6028), + TOBN(0xfaecedfd, 0x0c9803fc), TOBN(0xf38ae891, 0x4d7b4745), + TOBN(0xd8c5fccf, 0xc5e3a3d8), TOBN(0xbefd904c, 0x4079dfbf), + TOBN(0xbc6d6a58, 0xfead0197), TOBN(0x39227077, 0x695532a4), + TOBN(0x09e23e6d, 0xdbef42f5), TOBN(0x7e449b64, 0x480a9908), + TOBN(0x7b969c1a, 0xad9a2e40), TOBN(0x6231d792, 0x9591c2a4), + TOBN(0x87151456, 0x0f664534), TOBN(0x85ceae7c, 0x4b68f103), + TOBN(0xac09c4ae, 0x65578ab9), TOBN(0x33ec6868, 0xf044b10c), + TOBN(0x6ac4832b, 0x3a8ec1f1), TOBN(0x5509d128, 0x5847d5ef), + TOBN(0xf909604f, 0x763f1574), TOBN(0xb16c4303, 0xc32f63c4), + TOBN(0xb6ab2014, 0x7ca23cd3), TOBN(0xcaa7a5c6, 0xa391849d), + TOBN(0x5b0673a3, 0x75678d94), TOBN(0xc982ddd4, 0xdd303e64), + TOBN(0xfd7b000b, 0x5db6f971), TOBN(0xbba2cb1f, 0x6f876f92), + TOBN(0xc77332a3, 0x3c569426), TOBN(0xa159100c, 0x570d74f8), + TOBN(0xfd16847f, 0xdec67ef5), TOBN(0x742ee464, 0x233e76b7), + TOBN(0x0b8e4134, 0xefc2b4c8), TOBN(0xca640b86, 0x42a3e521), + TOBN(0x653a0190, 0x8ceb6aa9), TOBN(0x313c300c, 0x547852d5), + TOBN(0x24e4ab12, 0x6b237af7), TOBN(0x2ba90162, 0x8bb47af8), + TOBN(0x3d5e58d6, 0xa8219bb7), TOBN(0xc691d0bd, 0x1b06c57f), + TOBN(0x0ae4cb10, 0xd257576e), TOBN(0x3569656c, 0xd54a3dc3), + TOBN(0xe5ebaebd, 0x94cda03a), TOBN(0x934e82d3, 0x162bfe13), + TOBN(0x450ac0ba, 0xe251a0c6), TOBN(0x480b9e11, 0xdd6da526), + TOBN(0x00467bc5, 0x8cce08b5), TOBN(0xb636458c, 0x7f178d55), + TOBN(0xc5748bae, 0xa677d806), TOBN(0x2763a387, 0xdfa394eb), + TOBN(0xa12b448a, 0x7d3cebb6), TOBN(0xe7adda3e, 0x6f20d850), + TOBN(0xf63ebce5, 0x1558462c), TOBN(0x58b36143, 0x620088a8), + TOBN(0x8a2cc3ca, 0x4d63c0ee), TOBN(0x51233117, 0x0fe948ce), + TOBN(0x7463fd85, 0x222ef33b), TOBN(0xadf0c7dc, 0x7c603d6c), + TOBN(0x0ec32d3b, 0xfe7765e5), TOBN(0xccaab359, 0xbf380409), + TOBN(0xbdaa84d6, 0x8e59319c), TOBN(0xd9a4c280, 0x9c80c34d), + TOBN(0xa9d89488, 0xa059c142), TOBN(0x6f5ae714, 0xff0b9346), + TOBN(0x068f237d, 0x16fb3664), TOBN(0x5853e4c4, 0x363186ac), + TOBN(0xe2d87d23, 0x63c52f98), TOBN(0x2ec4a766, 0x81828876), + TOBN(0x47b864fa, 0xe14e7b1c), TOBN(0x0c0bc0e5, 0x69192408), + TOBN(0xe4d7681d, 0xb82e9f3e), TOBN(0x83200f0b, 0xdf25e13c), + TOBN(0x8909984c, 0x66f27280), TOBN(0x462d7b00, 0x75f73227), + TOBN(0xd90ba188, 0xf2651798), TOBN(0x74c6e18c, 0x36ab1c34), + TOBN(0xab256ea3, 0x5ef54359), TOBN(0x03466612, 0xd1aa702f), + TOBN(0x624d6049, 0x2ed22e91), TOBN(0x6fdfe0b5, 0x6f072822), + TOBN(0xeeca1115, 0x39ce2271), TOBN(0x98100a4f, 0xdb01614f), + TOBN(0xb6b0daa2, 0xa35c628f), TOBN(0xb6f94d2e, 0xc87e9a47), + TOBN(0xc6773259, 0x1d57d9ce), TOBN(0xf70bfeec, 0x03884a7b), + TOBN(0x5fb35ccf, 0xed2bad01), TOBN(0xa155cbe3, 0x1da6a5c7), + TOBN(0xc2e2594c, 0x30a92f8f), TOBN(0x649c89ce, 0x5bfafe43), + TOBN(0xd158667d, 0xe9ff257a), TOBN(0x9b359611, 0xf32c50ae), + TOBN(0x4b00b20b, 0x906014cf), TOBN(0xf3a8cfe3, 0x89bc7d3d), + TOBN(0x4ff23ffd, 0x248a7d06), TOBN(0x80c5bfb4, 0x878873fa), + TOBN(0xb7d9ad90, 0x05745981), TOBN(0x179c85db, 0x3db01994), + TOBN(0xba41b062, 0x61a6966c), TOBN(0x4d82d052, 0xeadce5a8), + TOBN(0x9e91cd3b, 0xa5e6a318), TOBN(0x47795f4f, 0x95b2dda0), + TOBN(0xecfd7c1f, 0xd55a897c), TOBN(0x009194ab, 0xb29110fb), + TOBN(0x5f0e2046, 0xe381d3b0), TOBN(0x5f3425f6, 0xa98dd291), + TOBN(0xbfa06687, 0x730d50da), TOBN(0x0423446c, 0x4b083b7f), + TOBN(0x397a247d, 0xd69d3417), TOBN(0xeb629f90, 0x387ba42a), + TOBN(0x1ee426cc, 0xd5cd79bf), TOBN(0x0032940b, 0x946c6e18), + TOBN(0x1b1e8ae0, 0x57477f58), TOBN(0xe94f7d34, 0x6d823278), + TOBN(0xc747cb96, 0x782ba21a), TOBN(0xc5254469, 0xf72b33a5), + TOBN(0x772ef6de, 0xc7f80c81), TOBN(0xd73acbfe, 0x2cd9e6b5), + TOBN(0x4075b5b1, 0x49ee90d9), TOBN(0x785c339a, 0xa06e9eba), + TOBN(0xa1030d5b, 0xabf825e0), TOBN(0xcec684c3, 0xa42931dc), + TOBN(0x42ab62c9, 0xc1586e63), TOBN(0x45431d66, 0x5ab43f2b), + TOBN(0x57c8b2c0, 0x55f7835d), TOBN(0x033da338, 0xc1b7f865), + TOBN(0x283c7513, 0xcaa76097), TOBN(0x0a624fa9, 0x36c83906), + TOBN(0x6b20afec, 0x715af2c7), TOBN(0x4b969974, 0xeba78bfd), + TOBN(0x220755cc, 0xd921d60e), TOBN(0x9b944e10, 0x7baeca13), + TOBN(0x04819d51, 0x5ded93d4), TOBN(0x9bbff86e, 0x6dddfd27), + TOBN(0x6b344130, 0x77adc612), TOBN(0xa7496529, 0xbbd803a0), + TOBN(0x1a1baaa7, 0x6d8805bd), TOBN(0xc8403902, 0x470343ad), + TOBN(0x39f59f66, 0x175adff1), TOBN(0x0b26d7fb, 0xb7d8c5b7), + TOBN(0xa875f5ce, 0x529d75e3), TOBN(0x85efc7e9, 0x41325cc2), + TOBN(0x21950b42, 0x1ff6acd3), TOBN(0xffe70484, 0x53dc6909), + TOBN(0xff4cd0b2, 0x28766127), TOBN(0xabdbe608, 0x4fb7db2b), + TOBN(0x837c9228, 0x5e1109e8), TOBN(0x26147d27, 0xf4645b5a), + TOBN(0x4d78f592, 0xf7818ed8), TOBN(0xd394077e, 0xf247fa36), + TOBN(0x0fb9c2d0, 0x488c171a), TOBN(0xa78bfbaa, 0x13685278), + TOBN(0xedfbe268, 0xd5b1fa6a), TOBN(0x0dceb8db, 0x2b7eaba7), + TOBN(0xbf9e8089, 0x9ae2b710), TOBN(0xefde7ae6, 0xa4449c96), + TOBN(0x43b7716b, 0xcc143a46), TOBN(0xd7d34194, 0xc3628c13), + TOBN(0x508cec1c, 0x3b3f64c9), TOBN(0xe20bc0ba, 0x1e5edf3f), + TOBN(0xda1deb85, 0x2f4318d4), TOBN(0xd20ebe0d, 0x5c3fa443), + TOBN(0x370b4ea7, 0x73241ea3), TOBN(0x61f1511c, 0x5e1a5f65), + TOBN(0x99a5e23d, 0x82681c62), TOBN(0xd731e383, 0xa2f54c2d), + TOBN(0x2692f36e, 0x83445904), TOBN(0x2e0ec469, 0xaf45f9c0), + TOBN(0x905a3201, 0xc67528b7), TOBN(0x88f77f34, 0xd0e5e542), + TOBN(0xf67a8d29, 0x5864687c), TOBN(0x23b92eae, 0x22df3562), + TOBN(0x5c27014b, 0x9bbec39e), TOBN(0x7ef2f226, 0x9c0f0f8d), + TOBN(0x97359638, 0x546c4d8d), TOBN(0x5f9c3fc4, 0x92f24679), + TOBN(0x912e8bed, 0xa8c8acd9), TOBN(0xec3a318d, 0x306634b0), + TOBN(0x80167f41, 0xc31cb264), TOBN(0x3db82f6f, 0x522113f2), + TOBN(0xb155bcd2, 0xdcafe197), TOBN(0xfba1da59, 0x43465283), + TOBN(0xa0425b8e, 0xb212cf53), TOBN(0x4f2e512e, 0xf8557c5f), + TOBN(0xc1286ff9, 0x25c4d56c), TOBN(0xbb8a0fea, 0xee26c851), + TOBN(0xc28f70d2, 0xe7d6107e), TOBN(0x7ee0c444, 0xe76265aa), + TOBN(0x3df277a4, 0x1d1936b1), TOBN(0x1a556e3f, 0xea9595eb), + TOBN(0x258bbbf9, 0xe7305683), TOBN(0x31eea5bf, 0x07ef5be6), + TOBN(0x0deb0e4a, 0x46c814c1), TOBN(0x5cee8449, 0xa7b730dd), + TOBN(0xeab495c5, 0xa0182bde), TOBN(0xee759f87, 0x9e27a6b4), + TOBN(0xc2cf6a68, 0x80e518ca), TOBN(0x25e8013f, 0xf14cf3f4), + TOBN(0x8fc44140, 0x7e8d7a14), TOBN(0xbb1ff3ca, 0x9556f36a), + TOBN(0x6a844385, 0x14600044), TOBN(0xba3f0c4a, 0x7451ae63), + TOBN(0xdfcac25b, 0x1f9af32a), TOBN(0x01e0db86, 0xb1f2214b), + TOBN(0x4e9a5bc2, 0xa4b596ac), TOBN(0x83927681, 0x026c2c08), + TOBN(0x3ec832e7, 0x7acaca28), TOBN(0x1bfeea57, 0xc7385b29), + TOBN(0x068212e3, 0xfd1eaf38), TOBN(0xc1329830, 0x6acf8ccc), + TOBN(0xb909f2db, 0x2aac9e59), TOBN(0x5748060d, 0xb661782a), + TOBN(0xc5ab2632, 0xc79b7a01), TOBN(0xda44c6c6, 0x00017626), + TOBN(0xf26c00e8, 0xa7ea82f0), TOBN(0x99cac80d, 0xe4299aaf), + TOBN(0xd66fe3b6, 0x7ed78be1), TOBN(0x305f725f, 0x648d02cd), + TOBN(0x33ed1bc4, 0x623fb21b), TOBN(0xfa70533e, 0x7a6319ad), + TOBN(0x17ab562d, 0xbe5ffb3e), TOBN(0x06374994, 0x56674741), + TOBN(0x69d44ed6, 0x5c46aa8e), TOBN(0x2100d5d3, 0xa8d063d1), + TOBN(0xcb9727ea, 0xa2d17c36), TOBN(0x4c2bab1b, 0x8add53b7), + TOBN(0xa084e90c, 0x15426704), TOBN(0x778afcd3, 0xa837ebea), + TOBN(0x6651f701, 0x7ce477f8), TOBN(0xa0624998, 0x46fb7a8b), + TOBN(0xdc1e6828, 0xed8a6e19), TOBN(0x33fc2336, 0x4189d9c7), + TOBN(0x026f8fe2, 0x671c39bc), TOBN(0xd40c4ccd, 0xbc6f9915), + TOBN(0xafa135bb, 0xf80e75ca), TOBN(0x12c651a0, 0x22adff2c), + TOBN(0xc40a04bd, 0x4f51ad96), TOBN(0x04820109, 0xbbe4e832), + TOBN(0x3667eb1a, 0x7f4c04cc), TOBN(0x59556621, 0xa9404f84), + TOBN(0x71cdf653, 0x7eceb50a), TOBN(0x994a44a6, 0x9b8335fa), + TOBN(0xd7faf819, 0xdbeb9b69), TOBN(0x473c5680, 0xeed4350d), + TOBN(0xb6658466, 0xda44bba2), TOBN(0x0d1bc780, 0x872bdbf3), + TOBN(0xe535f175, 0xa1962f91), TOBN(0x6ed7e061, 0xed58f5a7), + TOBN(0x177aa4c0, 0x2089a233), TOBN(0x0dbcb03a, 0xe539b413), + TOBN(0xe3dc424e, 0xbb32e38e), TOBN(0x6472e5ef, 0x6806701e), + TOBN(0xdd47ff98, 0x814be9ee), TOBN(0x6b60cfff, 0x35ace009), + TOBN(0xb8d3d931, 0x9ff91fe5), TOBN(0x039c4800, 0xf0518eed), + TOBN(0x95c37632, 0x9182cb26), TOBN(0x0763a434, 0x82fc568d), + TOBN(0x707c04d5, 0x383e76ba), TOBN(0xac98b930, 0x824e8197), + TOBN(0x92bf7c8f, 0x91230de0), TOBN(0x90876a01, 0x40959b70), + TOBN(0xdb6d96f3, 0x05968b80), TOBN(0x380a0913, 0x089f73b9), + TOBN(0x7da70b83, 0xc2c61e01), TOBN(0x95fb8394, 0x569b38c7), + TOBN(0x9a3c6512, 0x80edfe2f), TOBN(0x8f726bb9, 0x8faeaf82), + TOBN(0x8010a4a0, 0x78424bf8), TOBN(0x29672044, 0x0e844970)}, + {TOBN(0x63c5cb81, 0x7a2ad62a), TOBN(0x7ef2b6b9, 0xac62ff54), + TOBN(0x3749bba4, 0xb3ad9db5), TOBN(0xad311f2c, 0x46d5a617), + TOBN(0xb77a8087, 0xc2ff3b6d), TOBN(0xb46feaf3, 0x367834ff), + TOBN(0xf8aa266d, 0x75d6b138), TOBN(0xfa38d320, 0xec008188), + TOBN(0x486d8ffa, 0x696946fc), TOBN(0x50fbc6d8, 0xb9cba56d), + TOBN(0x7e3d423e, 0x90f35a15), TOBN(0x7c3da195, 0xc0dd962c), + TOBN(0xe673fdb0, 0x3cfd5d8b), TOBN(0x0704b7c2, 0x889dfca5), + TOBN(0xf6ce581f, 0xf52305aa), TOBN(0x399d49eb, 0x914d5e53), + TOBN(0x380a496d, 0x6ec293cd), TOBN(0x733dbda7, 0x8e7051f5), + TOBN(0x037e388d, 0xb849140a), TOBN(0xee4b32b0, 0x5946dbf6), + TOBN(0xb1c4fda9, 0xcae368d1), TOBN(0x5001a7b0, 0xfdb0b2f3), + TOBN(0x6df59374, 0x2e3ac46e), TOBN(0x4af675f2, 0x39b3e656), + TOBN(0x44e38110, 0x39949296), TOBN(0x5b63827b, 0x361db1b5), + TOBN(0x3e5323ed, 0x206eaff5), TOBN(0x942370d2, 0xc21f4290), + TOBN(0xf2caaf2e, 0xe0d985a1), TOBN(0x192cc64b, 0x7239846d), + TOBN(0x7c0b8f47, 0xae6312f8), TOBN(0x7dc61f91, 0x96620108), + TOBN(0xb830fb5b, 0xc2da7de9), TOBN(0xd0e643df, 0x0ff8d3be), + TOBN(0x31ee77ba, 0x188a9641), TOBN(0x4e8aa3aa, 0xbcf6d502), + TOBN(0xf9fb6532, 0x9a49110f), TOBN(0xd18317f6, 0x2dd6b220), + TOBN(0x7e3ced41, 0x52c3ea5a), TOBN(0x0d296a14, 0x7d579c4a), + TOBN(0x35d6a53e, 0xed4c3717), TOBN(0x9f8240cf, 0x3d0ed2a3), + TOBN(0x8c0d4d05, 0xe5543aa5), TOBN(0x45d5bbfb, 0xdd33b4b4), + TOBN(0xfa04cc73, 0x137fd28e), TOBN(0x862ac6ef, 0xc73b3ffd), + TOBN(0x403ff9f5, 0x31f51ef2), TOBN(0x34d5e0fc, 0xbc73f5a2), + TOBN(0xf2526820, 0x08913f4f), TOBN(0xea20ed61, 0xeac93d95), + TOBN(0x51ed38b4, 0x6ca6b26c), TOBN(0x8662dcbc, 0xea4327b0), + TOBN(0x6daf295c, 0x725d2aaa), TOBN(0xbad2752f, 0x8e52dcda), + TOBN(0x2210e721, 0x0b17dacc), TOBN(0xa37f7912, 0xd51e8232), + TOBN(0x4f7081e1, 0x44cc3add), TOBN(0xd5ffa1d6, 0x87be82cf), + TOBN(0x89890b6c, 0x0edd6472), TOBN(0xada26e1a, 0x3ed17863), + TOBN(0x276f2715, 0x63483caa), TOBN(0xe6924cd9, 0x2f6077fd), + TOBN(0x05a7fe98, 0x0a466e3c), TOBN(0xf1c794b0, 0xb1902d1f), + TOBN(0xe5213688, 0x82a8042c), TOBN(0xd931cfaf, 0xcd278298), + TOBN(0x069a0ae0, 0xf597a740), TOBN(0x0adbb3f3, 0xeb59107c), + TOBN(0x983e951e, 0x5eaa8eb8), TOBN(0xe663a8b5, 0x11b48e78), + TOBN(0x1631cc0d, 0x8a03f2c5), TOBN(0x7577c11e, 0x11e271e2), + TOBN(0x33b2385c, 0x08369a90), TOBN(0x2990c59b, 0x190eb4f8), + TOBN(0x819a6145, 0xc68eac80), TOBN(0x7a786d62, 0x2ec4a014), + TOBN(0x33faadbe, 0x20ac3a8d), TOBN(0x31a21781, 0x5aba2d30), + TOBN(0x209d2742, 0xdba4f565), TOBN(0xdb2ce9e3, 0x55aa0fbb), + TOBN(0x8cef334b, 0x168984df), TOBN(0xe81dce17, 0x33879638), + TOBN(0xf6e6949c, 0x263720f0), TOBN(0x5c56feaf, 0xf593cbec), + TOBN(0x8bff5601, 0xfde58c84), TOBN(0x74e24117, 0x2eccb314), + TOBN(0xbcf01b61, 0x4c9a8a78), TOBN(0xa233e35e, 0x544c9868), + TOBN(0xb3156bf3, 0x8bd7aff1), TOBN(0x1b5ee4cb, 0x1d81b146), + TOBN(0x7ba1ac41, 0xd628a915), TOBN(0x8f3a8f9c, 0xfd89699e), + TOBN(0x7329b9c9, 0xa0748be7), TOBN(0x1d391c95, 0xa92e621f), + TOBN(0xe51e6b21, 0x4d10a837), TOBN(0xd255f53a, 0x4947b435), + TOBN(0x07669e04, 0xf1788ee3), TOBN(0xc14f27af, 0xa86938a2), + TOBN(0x8b47a334, 0xe93a01c0), TOBN(0xff627438, 0xd9366808), + TOBN(0x7a0985d8, 0xca2a5965), TOBN(0x3d9a5542, 0xd6e9b9b3), + TOBN(0xc23eb80b, 0x4cf972e8), TOBN(0x5c1c33bb, 0x4fdf72fd), + TOBN(0x0c4a58d4, 0x74a86108), TOBN(0xf8048a8f, 0xee4c5d90), + TOBN(0xe3c7c924, 0xe86d4c80), TOBN(0x28c889de, 0x056a1e60), + TOBN(0x57e2662e, 0xb214a040), TOBN(0xe8c48e98, 0x37e10347), + TOBN(0x87742862, 0x80ac748a), TOBN(0xf1c24022, 0x186b06f2), + TOBN(0xac2dd4c3, 0x5f74040a), TOBN(0x409aeb71, 0xfceac957), + TOBN(0x4fbad782, 0x55c4ec23), TOBN(0xb359ed61, 0x8a7b76ec), + TOBN(0x12744926, 0xed6f4a60), TOBN(0xe21e8d7f, 0x4b912de3), + TOBN(0xe2575a59, 0xfc705a59), TOBN(0x72f1d4de, 0xed2dbc0e), + TOBN(0x3d2b24b9, 0xeb7926b8), TOBN(0xbff88cb3, 0xcdbe5509), + TOBN(0xd0f399af, 0xe4dd640b), TOBN(0x3c5fe130, 0x2f76ed45), + TOBN(0x6f3562f4, 0x3764fb3d), TOBN(0x7b5af318, 0x3151b62d), + TOBN(0xd5bd0bc7, 0xd79ce5f3), TOBN(0xfdaf6b20, 0xec66890f), + TOBN(0x735c67ec, 0x6063540c), TOBN(0x50b259c2, 0xe5f9cb8f), + TOBN(0xb8734f9a, 0x3f99c6ab), TOBN(0xf8cc13d5, 0xa3a7bc85), + TOBN(0x80c1b305, 0xc5217659), TOBN(0xfe5364d4, 0x4ec12a54), + TOBN(0xbd87045e, 0x681345fe), TOBN(0x7f8efeb1, 0x582f897f), + TOBN(0xe8cbf1e5, 0xd5923359), TOBN(0xdb0cea9d, 0x539b9fb0), + TOBN(0x0c5b34cf, 0x49859b98), TOBN(0x5e583c56, 0xa4403cc6), + TOBN(0x11fc1a2d, 0xd48185b7), TOBN(0xc93fbc7e, 0x6e521787), + TOBN(0x47e7a058, 0x05105b8b), TOBN(0x7b4d4d58, 0xdb8260c8), + TOBN(0xe33930b0, 0x46eb842a), TOBN(0x8e844a9a, 0x7bdae56d), + TOBN(0x34ef3a9e, 0x13f7fdfc), TOBN(0xb3768f82, 0x636ca176), + TOBN(0x2821f4e0, 0x4e09e61c), TOBN(0x414dc3a1, 0xa0c7cddc), + TOBN(0xd5379437, 0x54945fcd), TOBN(0x151b6eef, 0xb3555ff1), + TOBN(0xb31bd613, 0x6339c083), TOBN(0x39ff8155, 0xdfb64701), + TOBN(0x7c3388d2, 0xe29604ab), TOBN(0x1e19084b, 0xa6b10442), + TOBN(0x17cf54c0, 0xeccd47ef), TOBN(0x89693385, 0x4a5dfb30), + TOBN(0x69d023fb, 0x47daf9f6), TOBN(0x9222840b, 0x7d91d959), + TOBN(0x439108f5, 0x803bac62), TOBN(0x0b7dd91d, 0x379bd45f), + TOBN(0xd651e827, 0xca63c581), TOBN(0x5c5d75f6, 0x509c104f), + TOBN(0x7d5fc738, 0x1f2dc308), TOBN(0x20faa7bf, 0xd98454be), + TOBN(0x95374bee, 0xa517b031), TOBN(0xf036b9b1, 0x642692ac), + TOBN(0xc5106109, 0x39842194), TOBN(0xb7e2353e, 0x49d05295), + TOBN(0xfc8c1d5c, 0xefb42ee0), TOBN(0xe04884eb, 0x08ce811c), + TOBN(0xf1f75d81, 0x7419f40e), TOBN(0x5b0ac162, 0xa995c241), + TOBN(0x120921bb, 0xc4c55646), TOBN(0x713520c2, 0x8d33cf97), + TOBN(0xb4a65a5c, 0xe98c5100), TOBN(0x6cec871d, 0x2ddd0f5a), + TOBN(0x251f0b7f, 0x9ba2e78b), TOBN(0x224a8434, 0xce3a2a5f), + TOBN(0x26827f61, 0x25f5c46f), TOBN(0x6a22bedc, 0x48545ec0), + TOBN(0x25ae5fa0, 0xb1bb5cdc), TOBN(0xd693682f, 0xfcb9b98f), + TOBN(0x32027fe8, 0x91e5d7d3), TOBN(0xf14b7d17, 0x73a07678), + TOBN(0xf88497b3, 0xc0dfdd61), TOBN(0xf7c2eec0, 0x2a8c4f48), + TOBN(0xaa5573f4, 0x3756e621), TOBN(0xc013a240, 0x1825b948), + TOBN(0x1c03b345, 0x63878572), TOBN(0xa0472bea, 0x653a4184), + TOBN(0xf4222e27, 0x0ac69a80), TOBN(0x34096d25, 0xf51e54f6), + TOBN(0x00a648cb, 0x8fffa591), TOBN(0x4e87acdc, 0x69b6527f), + TOBN(0x0575e037, 0xe285ccb4), TOBN(0x188089e4, 0x50ddcf52), + TOBN(0xaa96c9a8, 0x870ff719), TOBN(0x74a56cd8, 0x1fc7e369), + TOBN(0x41d04ee2, 0x1726931a), TOBN(0x0bbbb2c8, 0x3660ecfd), + TOBN(0xa6ef6de5, 0x24818e18), TOBN(0xe421cc51, 0xe7d57887), + TOBN(0xf127d208, 0xbea87be6), TOBN(0x16a475d3, 0xb1cdd682), + TOBN(0x9db1b684, 0x439b63f7), TOBN(0x5359b3db, 0xf0f113b6), + TOBN(0xdfccf1de, 0x8bf06e31), TOBN(0x1fdf8f44, 0xdd383901), + TOBN(0x10775cad, 0x5017e7d2), TOBN(0xdfc3a597, 0x58d11eef), + TOBN(0x6ec9c8a0, 0xb1ecff10), TOBN(0xee6ed6cc, 0x28400549), + TOBN(0xb5ad7bae, 0x1b4f8d73), TOBN(0x61b4f11d, 0xe00aaab9), + TOBN(0x7b32d69b, 0xd4eff2d7), TOBN(0x88ae6771, 0x4288b60f), + TOBN(0x159461b4, 0x37a1e723), TOBN(0x1f3d4789, 0x570aae8c), + TOBN(0x869118c0, 0x7f9871da), TOBN(0x35fbda78, 0xf635e278), + TOBN(0x738f3641, 0xe1541dac), TOBN(0x6794b13a, 0xc0dae45f), + TOBN(0x065064ac, 0x09cc0917), TOBN(0x27c53729, 0xc68540fd), + TOBN(0x0d2d4c8e, 0xef227671), TOBN(0xd23a9f80, 0xa1785a04), + TOBN(0x98c59528, 0x52650359), TOBN(0xfa09ad01, 0x74a1acad), + TOBN(0x082d5a29, 0x0b55bf5c), TOBN(0xa40f1c67, 0x419b8084), + TOBN(0x3a5c752e, 0xdcc18770), TOBN(0x4baf1f2f, 0x8825c3a5), + TOBN(0xebd63f74, 0x21b153ed), TOBN(0xa2383e47, 0xb2f64723), + TOBN(0xe7bf620a, 0x2646d19a), TOBN(0x56cb44ec, 0x03c83ffd), + TOBN(0xaf7267c9, 0x4f6be9f1), TOBN(0x8b2dfd7b, 0xc06bb5e9), + TOBN(0xb87072f2, 0xa672c5c7), TOBN(0xeacb11c8, 0x0d53c5e2), + TOBN(0x22dac29d, 0xff435932), TOBN(0x37bdb99d, 0x4408693c), + TOBN(0xf6e62fb6, 0x2899c20f), TOBN(0x3535d512, 0x447ece24), + TOBN(0xfbdc6b88, 0xff577ce3), TOBN(0x726693bd, 0x190575f2), + TOBN(0x6772b0e5, 0xab4b35a2), TOBN(0x1d8b6001, 0xf5eeaacf), + TOBN(0x728f7ce4, 0x795b9580), TOBN(0x4a20ed2a, 0x41fb81da), + TOBN(0x9f685cd4, 0x4fec01e6), TOBN(0x3ed7ddcc, 0xa7ff50ad), + TOBN(0x460fd264, 0x0c2d97fd), TOBN(0x3a241426, 0xeb82f4f9), + TOBN(0x17d1df2c, 0x6a8ea820), TOBN(0xb2b50d3b, 0xf22cc254), + TOBN(0x03856cba, 0xb7291426), TOBN(0x87fd26ae, 0x04f5ee39), + TOBN(0x9cb696cc, 0x02bee4ba), TOBN(0x53121804, 0x06820fd6), + TOBN(0xa5dfc269, 0x0212e985), TOBN(0x666f7ffa, 0x160f9a09), + TOBN(0xc503cd33, 0xbccd9617), TOBN(0x365dede4, 0xba7730a3), + TOBN(0x798c6355, 0x5ddb0786), TOBN(0xa6c3200e, 0xfc9cd3bc), + TOBN(0x060ffb2c, 0xe5e35efd), TOBN(0x99a4e25b, 0x5555a1c1), + TOBN(0x11d95375, 0xf70b3751), TOBN(0x0a57354a, 0x160e1bf6), + TOBN(0xecb3ae4b, 0xf8e4b065), TOBN(0x07a834c4, 0x2e53022b), + TOBN(0x1cd300b3, 0x8692ed96), TOBN(0x16a6f792, 0x61ee14ec), + TOBN(0x8f1063c6, 0x6a8649ed), TOBN(0xfbcdfcfe, 0x869f3e14), + TOBN(0x2cfb97c1, 0x00a7b3ec), TOBN(0xcea49b3c, 0x7130c2f1), + TOBN(0x462d044f, 0xe9d96488), TOBN(0x4b53d52e, 0x8182a0c1), + TOBN(0x84b6ddd3, 0x0391e9e9), TOBN(0x80ab7b48, 0xb1741a09), + TOBN(0xec0e15d4, 0x27d3317f), TOBN(0x8dfc1ddb, 0x1a64671e), + TOBN(0x93cc5d5f, 0xd49c5b92), TOBN(0xc995d53d, 0x3674a331), + TOBN(0x302e41ec, 0x090090ae), TOBN(0x2278a0cc, 0xedb06830), + TOBN(0x1d025932, 0xfbc99690), TOBN(0x0c32fbd2, 0xb80d68da), + TOBN(0xd79146da, 0xf341a6c1), TOBN(0xae0ba139, 0x1bef68a0), + TOBN(0xc6b8a563, 0x8d774b3a), TOBN(0x1cf307bd, 0x880ba4d7), + TOBN(0xc033bdc7, 0x19803511), TOBN(0xa9f97b3b, 0x8888c3be), + TOBN(0x3d68aebc, 0x85c6d05e), TOBN(0xc3b88a9d, 0x193919eb), + TOBN(0x2d300748, 0xc48b0ee3), TOBN(0x7506bc7c, 0x07a746c1), + TOBN(0xfc48437c, 0x6e6d57f3), TOBN(0x5bd71587, 0xcfeaa91a), + TOBN(0xa4ed0408, 0xc1bc5225), TOBN(0xd0b946db, 0x2719226d), + TOBN(0x109ecd62, 0x758d2d43), TOBN(0x75c8485a, 0x2751759b), + TOBN(0xb0b75f49, 0x9ce4177a), TOBN(0x4fa61a1e, 0x79c10c3d), + TOBN(0xc062d300, 0xa167fcd7), TOBN(0x4df3874c, 0x750f0fa8), + TOBN(0x29ae2cf9, 0x83dfedc9), TOBN(0xf8437134, 0x8d87631a), + TOBN(0xaf571711, 0x7429c8d2), TOBN(0x18d15867, 0x146d9272), + TOBN(0x83053ecf, 0x69769bb7), TOBN(0xc55eb856, 0xc479ab82), + TOBN(0x5ef7791c, 0x21b0f4b2), TOBN(0xaa5956ba, 0x3d491525), + TOBN(0x407a96c2, 0x9fe20eba), TOBN(0xf27168bb, 0xe52a5ad3), + TOBN(0x43b60ab3, 0xbf1d9d89), TOBN(0xe45c51ef, 0x710e727a), + TOBN(0xdfca5276, 0x099b4221), TOBN(0x8dc6407c, 0x2557a159), + TOBN(0x0ead8335, 0x91035895), TOBN(0x0a9db957, 0x9c55dc32), + TOBN(0xe40736d3, 0xdf61bc76), TOBN(0x13a619c0, 0x3f778cdb), + TOBN(0x6dd921a4, 0xc56ea28f), TOBN(0x76a52433, 0x2fa647b4), + TOBN(0x23591891, 0xac5bdc5d), TOBN(0xff4a1a72, 0xbac7dc01), + TOBN(0x9905e261, 0x62df8453), TOBN(0x3ac045df, 0xe63b265f), + TOBN(0x8a3f341b, 0xad53dba7), TOBN(0x8ec269cc, 0x837b625a), + TOBN(0xd71a2782, 0x3ae31189), TOBN(0x8fb4f9a3, 0x55e96120), + TOBN(0x804af823, 0xff9875cf), TOBN(0x23224f57, 0x5d442a9b), + TOBN(0x1c4d3b9e, 0xecc62679), TOBN(0x91da22fb, 0xa0e7ddb1), + TOBN(0xa370324d, 0x6c04a661), TOBN(0x9710d3b6, 0x5e376d17), + TOBN(0xed8c98f0, 0x3044e357), TOBN(0xc364ebbe, 0x6422701c), + TOBN(0x347f5d51, 0x7733d61c), TOBN(0xd55644b9, 0xcea826c3), + TOBN(0x80c6e0ad, 0x55a25548), TOBN(0x0aa7641d, 0x844220a7), + TOBN(0x1438ec81, 0x31810660), TOBN(0x9dfa6507, 0xde4b4043), + TOBN(0x10b515d8, 0xcc3e0273), TOBN(0x1b6066dd, 0x28d8cfb2), + TOBN(0xd3b04591, 0x9c9efebd), TOBN(0x425d4bdf, 0xa21c1ff4), + TOBN(0x5fe5af19, 0xd57607d3), TOBN(0xbbf773f7, 0x54481084), + TOBN(0x8435bd69, 0x94b03ed1), TOBN(0xd9ad1de3, 0x634cc546), + TOBN(0x2cf423fc, 0x00e420ca), TOBN(0xeed26d80, 0xa03096dd), + TOBN(0xd7f60be7, 0xa4db09d2), TOBN(0xf47f569d, 0x960622f7), + TOBN(0xe5925fd7, 0x7296c729), TOBN(0xeff2db26, 0x26ca2715), + TOBN(0xa6fcd014, 0xb913e759), TOBN(0x53da4786, 0x8ff4de93), + TOBN(0x14616d79, 0xc32068e1), TOBN(0xb187d664, 0xccdf352e), + TOBN(0xf7afb650, 0x1dc90b59), TOBN(0x8170e943, 0x7daa1b26), + TOBN(0xc8e3bdd8, 0x700c0a84), TOBN(0x6e8d345f, 0x6482bdfa), + TOBN(0x84cfbfa1, 0xc5c5ea50), TOBN(0xd3baf14c, 0x67960681), + TOBN(0x26398403, 0x0dd50942), TOBN(0xe4b7839c, 0x4716a663), + TOBN(0xd5f1f794, 0xe7de6dc0), TOBN(0x5cd0f4d4, 0x622aa7ce), + TOBN(0x5295f3f1, 0x59acfeec), TOBN(0x8d933552, 0x953e0607), + TOBN(0xc7db8ec5, 0x776c5722), TOBN(0xdc467e62, 0x2b5f290c), + TOBN(0xd4297e70, 0x4ff425a9), TOBN(0x4be924c1, 0x0cf7bb72), + TOBN(0x0d5dc5ae, 0xa1892131), TOBN(0x8bf8a8e3, 0xa705c992), + TOBN(0x73a0b064, 0x7a305ac5), TOBN(0x00c9ca4e, 0x9a8c77a8), + TOBN(0x5dfee80f, 0x83774bdd), TOBN(0x63131602, 0x85734485), + TOBN(0xa1b524ae, 0x914a69a9), TOBN(0xebc2ffaf, 0xd4e300d7), + TOBN(0x52c93db7, 0x7cfa46a5), TOBN(0x71e6161f, 0x21653b50), + TOBN(0x3574fc57, 0xa4bc580a), TOBN(0xc09015dd, 0xe1bc1253), + TOBN(0x4b7b47b2, 0xd174d7aa), TOBN(0x4072d8e8, 0xf3a15d04), + TOBN(0xeeb7d47f, 0xd6fa07ed), TOBN(0x6f2b9ff9, 0xedbdafb1), + TOBN(0x18c51615, 0x3760fe8a), TOBN(0x7a96e6bf, 0xf06c6c13), + TOBN(0x4d7a0410, 0x0ea2d071), TOBN(0xa1914e9b, 0x0be2a5ce), + TOBN(0x5726e357, 0xd8a3c5cf), TOBN(0x1197ecc3, 0x2abb2b13), + TOBN(0x6c0d7f7f, 0x31ae88dd), TOBN(0x15b20d1a, 0xfdbb3efe), + TOBN(0xcd06aa26, 0x70584039), TOBN(0x2277c969, 0xa7dc9747), + TOBN(0xbca69587, 0x7855d815), TOBN(0x899ea238, 0x5188b32a), + TOBN(0x37d9228b, 0x760c1c9d), TOBN(0xc7efbb11, 0x9b5c18da), + TOBN(0x7f0d1bc8, 0x19f6dbc5), TOBN(0x4875384b, 0x07e6905b), + TOBN(0xc7c50baa, 0x3ba8cd86), TOBN(0xb0ce40fb, 0xc2905de0), + TOBN(0x70840673, 0x7a231952), TOBN(0xa912a262, 0xcf43de26), + TOBN(0x9c38ddcc, 0xeb5b76c1), TOBN(0x746f5285, 0x26fc0ab4), + TOBN(0x52a63a50, 0xd62c269f), TOBN(0x60049c55, 0x99458621), + TOBN(0xe7f48f82, 0x3c2f7c9e), TOBN(0x6bd99043, 0x917d5cf3), + TOBN(0xeb1317a8, 0x8701f469), TOBN(0xbd3fe2ed, 0x9a449fe0), + TOBN(0x421e79ca, 0x12ef3d36), TOBN(0x9ee3c36c, 0x3e7ea5de), + TOBN(0xe48198b5, 0xcdff36f7), TOBN(0xaff4f967, 0xc6b82228), + TOBN(0x15e19dd0, 0xc47adb7e), TOBN(0x45699b23, 0x032e7dfa), + TOBN(0x40680c8b, 0x1fae026a), TOBN(0x5a347a48, 0x550dbf4d), + TOBN(0xe652533b, 0x3cef0d7d), TOBN(0xd94f7b18, 0x2bbb4381), + TOBN(0x838752be, 0x0e80f500), TOBN(0x8e6e2488, 0x9e9c9bfb), + TOBN(0xc9751697, 0x16caca6a), TOBN(0x866c49d8, 0x38531ad9), + TOBN(0xc917e239, 0x7151ade1), TOBN(0x2d016ec1, 0x6037c407), + TOBN(0xa407ccc9, 0x00eac3f9), TOBN(0x835f6280, 0xe2ed4748), + TOBN(0xcc54c347, 0x1cc98e0d), TOBN(0x0e969937, 0xdcb572eb), + TOBN(0x1b16c8e8, 0x8f30c9cb), TOBN(0xa606ae75, 0x373c4661), + TOBN(0x47aa689b, 0x35502cab), TOBN(0xf89014ae, 0x4d9bb64f), + TOBN(0x202f6a9c, 0x31c71f7b), TOBN(0x01f95aa3, 0x296ffe5c), + TOBN(0x5fc06014, 0x53cec3a3), TOBN(0xeb991237, 0x5f498a45), + TOBN(0xae9a935e, 0x5d91ba87), TOBN(0xc6ac6281, 0x0b564a19), + TOBN(0x8a8fe81c, 0x3bd44e69), TOBN(0x7c8b467f, 0x9dd11d45), + TOBN(0xf772251f, 0xea5b8e69), TOBN(0xaeecb3bd, 0xc5b75fbc), + TOBN(0x1aca3331, 0x887ff0e5), TOBN(0xbe5d49ff, 0x19f0a131), + TOBN(0x582c13aa, 0xe5c8646f), TOBN(0xdbaa12e8, 0x20e19980), + TOBN(0x8f40f31a, 0xf7abbd94), TOBN(0x1f13f5a8, 0x1dfc7663), + TOBN(0x5d81f1ee, 0xaceb4fc0), TOBN(0x36256002, 0x5e6f0f42), + TOBN(0x4b67d6d7, 0x751370c8), TOBN(0x2608b698, 0x03e80589), + TOBN(0xcfc0d2fc, 0x05268301), TOBN(0xa6943d39, 0x40309212), + TOBN(0x192a90c2, 0x1fd0e1c2), TOBN(0xb209f113, 0x37f1dc76), + TOBN(0xefcc5e06, 0x97bf1298), TOBN(0xcbdb6730, 0x219d639e), + TOBN(0xd009c116, 0xb81e8c6f), TOBN(0xa3ffdde3, 0x1a7ce2e5), + TOBN(0xc53fbaaa, 0xa914d3ba), TOBN(0x836d500f, 0x88df85ee), + TOBN(0xd98dc71b, 0x66ee0751), TOBN(0x5a3d7005, 0x714516fd), + TOBN(0x21d3634d, 0x39eedbba), TOBN(0x35cd2e68, 0x0455a46d), + TOBN(0xc8cafe65, 0xf9d7eb0c), TOBN(0xbda3ce9e, 0x00cefb3e), + TOBN(0xddc17a60, 0x2c9cf7a4), TOBN(0x01572ee4, 0x7bcb8773), + TOBN(0xa92b2b01, 0x8c7548df), TOBN(0x732fd309, 0xa84600e3), + TOBN(0xe22109c7, 0x16543a40), TOBN(0x9acafd36, 0xfede3c6c), + TOBN(0xfb206852, 0x6824e614), TOBN(0x2a4544a9, 0xda25dca0), + TOBN(0x25985262, 0x91d60b06), TOBN(0x281b7be9, 0x28753545), + TOBN(0xec667b1a, 0x90f13b27), TOBN(0x33a83aff, 0x940e2eb4), + TOBN(0x80009862, 0xd5d721d5), TOBN(0x0c3357a3, 0x5bd3a182), + TOBN(0x27f3a83b, 0x7aa2cda4), TOBN(0xb58ae74e, 0xf6f83085), + TOBN(0x2a911a81, 0x2e6dad6b), TOBN(0xde286051, 0xf43d6c5b), + TOBN(0x4bdccc41, 0xf996c4d8), TOBN(0xe7312ec0, 0x0ae1e24e)}, + {TOBN(0xf8d112e7, 0x6e6485b3), TOBN(0x4d3e24db, 0x771c52f8), + TOBN(0x48e3ee41, 0x684a2f6d), TOBN(0x7161957d, 0x21d95551), + TOBN(0x19631283, 0xcdb12a6c), TOBN(0xbf3fa882, 0x2e50e164), + TOBN(0xf6254b63, 0x3166cc73), TOBN(0x3aefa7ae, 0xaee8cc38), + TOBN(0x79b0fe62, 0x3b36f9fd), TOBN(0x26543b23, 0xfde19fc0), + TOBN(0x136e64a0, 0x958482ef), TOBN(0x23f63771, 0x9b095825), + TOBN(0x14cfd596, 0xb6a1142e), TOBN(0x5ea6aac6, 0x335aac0b), + TOBN(0x86a0e8bd, 0xf3081dd5), TOBN(0x5fb89d79, 0x003dc12a), + TOBN(0xf615c33a, 0xf72e34d4), TOBN(0x0bd9ea40, 0x110eec35), + TOBN(0x1c12bc5b, 0xc1dea34e), TOBN(0x686584c9, 0x49ae4699), + TOBN(0x13ad95d3, 0x8c97b942), TOBN(0x4609561a, 0x4e5c7562), + TOBN(0x9e94a4ae, 0xf2737f89), TOBN(0xf57594c6, 0x371c78b6), + TOBN(0x0f0165fc, 0xe3779ee3), TOBN(0xe00e7f9d, 0xbd495d9e), + TOBN(0x1fa4efa2, 0x20284e7a), TOBN(0x4564bade, 0x47ac6219), + TOBN(0x90e6312a, 0xc4708e8e), TOBN(0x4f5725fb, 0xa71e9adf), + TOBN(0xe95f55ae, 0x3d684b9f), TOBN(0x47f7ccb1, 0x1e94b415), + TOBN(0x7322851b, 0x8d946581), TOBN(0xf0d13133, 0xbdf4a012), + TOBN(0xa3510f69, 0x6584dae0), TOBN(0x03a7c171, 0x3c9f6c6d), + TOBN(0x5be97f38, 0xe475381a), TOBN(0xca1ba422, 0x85823334), + TOBN(0xf83cc5c7, 0x0be17dda), TOBN(0x158b1494, 0x0b918c0f), + TOBN(0xda3a77e5, 0x522e6b69), TOBN(0x69c908c3, 0xbbcd6c18), + TOBN(0x1f1b9e48, 0xd924fd56), TOBN(0x37c64e36, 0xaa4bb3f7), + TOBN(0x5a4fdbdf, 0xee478d7d), TOBN(0xba75c8bc, 0x0193f7a0), + TOBN(0x84bc1e84, 0x56cd16df), TOBN(0x1fb08f08, 0x46fad151), + TOBN(0x8a7cabf9, 0x842e9f30), TOBN(0xa331d4bf, 0x5eab83af), + TOBN(0xd272cfba, 0x017f2a6a), TOBN(0x27560abc, 0x83aba0e3), + TOBN(0x94b83387, 0x0e3a6b75), TOBN(0x25c6aea2, 0x6b9f50f5), + TOBN(0x803d691d, 0xb5fdf6d0), TOBN(0x03b77509, 0xe6333514), + TOBN(0x36178903, 0x61a341c1), TOBN(0x3604dc60, 0x0cfd6142), + TOBN(0x022295eb, 0x8533316c), TOBN(0x3dbde4ac, 0x44af2922), + TOBN(0x898afc5d, 0x1c7eef69), TOBN(0x58896805, 0xd14f4fa1), + TOBN(0x05002160, 0x203c21ca), TOBN(0x6f0d1f30, 0x40ef730b), + TOBN(0x8e8c44d4, 0x196224f8), TOBN(0x75a4ab95, 0x374d079d), + TOBN(0x79085ecc, 0x7d48f123), TOBN(0x56f04d31, 0x1bf65ad8), + TOBN(0xe220bf1c, 0xbda602b2), TOBN(0x73ee1742, 0xf9612c69), + TOBN(0x76008fc8, 0x084fd06b), TOBN(0x4000ef9f, 0xf11380d1), + TOBN(0x48201b4b, 0x12cfe297), TOBN(0x3eee129c, 0x292f74e5), + TOBN(0xe1fe114e, 0xc9e874e8), TOBN(0x899b055c, 0x92c5fc41), + TOBN(0x4e477a64, 0x3a39c8cf), TOBN(0x82f09efe, 0x78963cc9), + TOBN(0x6fd3fd8f, 0xd333f863), TOBN(0x85132b2a, 0xdc949c63), + TOBN(0x7e06a3ab, 0x516eb17b), TOBN(0x73bec06f, 0xd2c7372b), + TOBN(0xe4f74f55, 0xba896da6), TOBN(0xbb4afef8, 0x8e9eb40f), + TOBN(0x2d75bec8, 0xe61d66b0), TOBN(0x02bda4b4, 0xef29300b), + TOBN(0x8bbaa8de, 0x026baa5a), TOBN(0xff54befd, 0xa07f4440), + TOBN(0xbd9b8b1d, 0xbe7a2af3), TOBN(0xec51caa9, 0x4fb74a72), + TOBN(0xb9937a4b, 0x63879697), TOBN(0x7c9a9d20, 0xec2687d5), + TOBN(0x1773e44f, 0x6ef5f014), TOBN(0x8abcf412, 0xe90c6900), + TOBN(0x387bd022, 0x8142161e), TOBN(0x50393755, 0xfcb6ff2a), + TOBN(0x9813fd56, 0xed6def63), TOBN(0x53cf6482, 0x7d53106c), + TOBN(0x991a35bd, 0x431f7ac1), TOBN(0xf1e274dd, 0x63e65faf), + TOBN(0xf63ffa3c, 0x44cc7880), TOBN(0x411a426b, 0x7c256981), + TOBN(0xb698b9fd, 0x93a420e0), TOBN(0x89fdddc0, 0xae53f8fe), + TOBN(0x766e0722, 0x32398baa), TOBN(0x205fee42, 0x5cfca031), + TOBN(0xa49f5341, 0x7a029cf2), TOBN(0xa88c68b8, 0x4023890d), + TOBN(0xbc275041, 0x7337aaa8), TOBN(0x9ed364ad, 0x0eb384f4), + TOBN(0xe0816f85, 0x29aba92f), TOBN(0x2e9e1941, 0x04e38a88), + TOBN(0x57eef44a, 0x3dafd2d5), TOBN(0x35d1fae5, 0x97ed98d8), + TOBN(0x50628c09, 0x2307f9b1), TOBN(0x09d84aae, 0xd6cba5c6), + TOBN(0x67071bc7, 0x88aaa691), TOBN(0x2dea57a9, 0xafe6cb03), + TOBN(0xdfe11bb4, 0x3d78ac01), TOBN(0x7286418c, 0x7fd7aa51), + TOBN(0xfabf7709, 0x77f7195a), TOBN(0x8ec86167, 0xadeb838f), + TOBN(0xea1285a8, 0xbb4f012d), TOBN(0xd6883503, 0x9a3eab3f), + TOBN(0xee5d24f8, 0x309004c2), TOBN(0xa96e4b76, 0x13ffe95e), + TOBN(0x0cdffe12, 0xbd223ea4), TOBN(0x8f5c2ee5, 0xb6739a53), + TOBN(0x5cb4aaa5, 0xdd968198), TOBN(0xfa131c52, 0x72413a6c), + TOBN(0x53d46a90, 0x9536d903), TOBN(0xb270f0d3, 0x48606d8e), + TOBN(0x518c7564, 0xa053a3bc), TOBN(0x088254b7, 0x1a86caef), + TOBN(0xb3ba8cb4, 0x0ab5efd0), TOBN(0x5c59900e, 0x4605945d), + TOBN(0xecace1dd, 0xa1887395), TOBN(0x40960f36, 0x932a65de), + TOBN(0x9611ff5c, 0x3aa95529), TOBN(0xc58215b0, 0x7c1e5a36), + TOBN(0xd48c9b58, 0xf0e1a524), TOBN(0xb406856b, 0xf590dfb8), + TOBN(0xc7605e04, 0x9cd95662), TOBN(0x0dd036ee, 0xa33ecf82), + TOBN(0xa50171ac, 0xc33156b3), TOBN(0xf09d24ea, 0x4a80172e), + TOBN(0x4e1f72c6, 0x76dc8eef), TOBN(0xe60caadc, 0x5e3d44ee), + TOBN(0x006ef8a6, 0x979b1d8f), TOBN(0x60908a1c, 0x97788d26), + TOBN(0x6e08f95b, 0x266feec0), TOBN(0x618427c2, 0x22e8c94e), + TOBN(0x3d613339, 0x59145a65), TOBN(0xcd9bc368, 0xfa406337), + TOBN(0x82d11be3, 0x2d8a52a0), TOBN(0xf6877b27, 0x97a1c590), + TOBN(0x837a819b, 0xf5cbdb25), TOBN(0x2a4fd1d8, 0xde090249), + TOBN(0x622a7de7, 0x74990e5f), TOBN(0x840fa5a0, 0x7945511b), + TOBN(0x30b974be, 0x6558842d), TOBN(0x70df8c64, 0x17f3d0a6), + TOBN(0x7c803520, 0x7542e46d), TOBN(0x7251fe7f, 0xe4ecc823), + TOBN(0xe59134cb, 0x5e9aac9a), TOBN(0x11bb0934, 0xf0045d71), + TOBN(0x53e5d9b5, 0xdbcb1d4e), TOBN(0x8d97a905, 0x92defc91), + TOBN(0xfe289327, 0x7946d3f9), TOBN(0xe132bd24, 0x07472273), + TOBN(0xeeeb510c, 0x1eb6ae86), TOBN(0x777708c5, 0xf0595067), + TOBN(0x18e2c8cd, 0x1297029e), TOBN(0x2c61095c, 0xbbf9305e), + TOBN(0xe466c258, 0x6b85d6d9), TOBN(0x8ac06c36, 0xda1ea530), + TOBN(0xa365dc39, 0xa1304668), TOBN(0xe4a9c885, 0x07f89606), + TOBN(0x65a4898f, 0xacc7228d), TOBN(0x3e2347ff, 0x84ca8303), + TOBN(0xa5f6fb77, 0xea7d23a3), TOBN(0x2fac257d, 0x672a71cd), + TOBN(0x6908bef8, 0x7e6a44d3), TOBN(0x8ff87566, 0x891d3d7a), + TOBN(0xe58e90b3, 0x6b0cf82e), TOBN(0x6438d246, 0x2615b5e7), + TOBN(0x07b1f8fc, 0x669c145a), TOBN(0xb0d8b2da, 0x36f1e1cb), + TOBN(0x54d5dadb, 0xd9184c4d), TOBN(0x3dbb18d5, 0xf93d9976), + TOBN(0x0a3e0f56, 0xd1147d47), TOBN(0x2afa8c8d, 0xa0a48609), + TOBN(0x275353e8, 0xbc36742c), TOBN(0x898f427e, 0xeea0ed90), + TOBN(0x26f4947e, 0x3e477b00), TOBN(0x8ad8848a, 0x308741e3), + TOBN(0x6c703c38, 0xd74a2a46), TOBN(0x5e3e05a9, 0x9ba17ba2), + TOBN(0xc1fa6f66, 0x4ab9a9e4), TOBN(0x474a2d9a, 0x3841d6ec), + TOBN(0x871239ad, 0x653ae326), TOBN(0x14bcf72a, 0xa74cbb43), + TOBN(0x8737650e, 0x20d4c083), TOBN(0x3df86536, 0x110ed4af), + TOBN(0xd2d86fe7, 0xb53ca555), TOBN(0x688cb00d, 0xabd5d538), + TOBN(0xcf81bda3, 0x1ad38468), TOBN(0x7ccfe3cc, 0xf01167b6), + TOBN(0xcf4f47e0, 0x6c4c1fe6), TOBN(0x557e1f1a, 0x298bbb79), + TOBN(0xf93b974f, 0x30d45a14), TOBN(0x174a1d2d, 0x0baf97c4), + TOBN(0x7a003b30, 0xc51fbf53), TOBN(0xd8940991, 0xee68b225), + TOBN(0x5b0aa7b7, 0x1c0f4173), TOBN(0x975797c9, 0xa20a7153), + TOBN(0x26e08c07, 0xe3533d77), TOBN(0xd7222e6a, 0x2e341c99), + TOBN(0x9d60ec3d, 0x8d2dc4ed), TOBN(0xbdfe0d8f, 0x7c476cf8), + TOBN(0x1fe59ab6, 0x1d056605), TOBN(0xa9ea9df6, 0x86a8551f), + TOBN(0x8489941e, 0x47fb8d8c), TOBN(0xfeb874eb, 0x4a7f1b10), + TOBN(0xfe5fea86, 0x7ee0d98f), TOBN(0x201ad34b, 0xdbf61864), + TOBN(0x45d8fe47, 0x37c031d4), TOBN(0xd5f49fae, 0x795f0822), + TOBN(0xdb0fb291, 0xc7f4a40c), TOBN(0x2e69d9c1, 0x730ddd92), + TOBN(0x754e1054, 0x49d76987), TOBN(0x8a24911d, 0x7662db87), + TOBN(0x61fc1810, 0x60a71676), TOBN(0xe852d1a8, 0xf66a8ad1), + TOBN(0x172bbd65, 0x6417231e), TOBN(0x0d6de7bd, 0x3babb11f), + TOBN(0x6fde6f88, 0xc8e347f8), TOBN(0x1c587547, 0x9bd99cc3), + TOBN(0x78e54ed0, 0x34076950), TOBN(0x97f0f334, 0x796e83ba), + TOBN(0xe4dbe1ce, 0x4924867a), TOBN(0xbd5f51b0, 0x60b84917), + TOBN(0x37530040, 0x3cb09a79), TOBN(0xdb3fe0f8, 0xff1743d8), + TOBN(0xed7894d8, 0x556fa9db), TOBN(0xfa262169, 0x23412fbf), + TOBN(0x563be0db, 0xba7b9291), TOBN(0x6ca8b8c0, 0x0c9fb234), + TOBN(0xed406aa9, 0xbd763802), TOBN(0xc21486a0, 0x65303da1), + TOBN(0x61ae291e, 0xc7e62ec4), TOBN(0x622a0492, 0xdf99333e), + TOBN(0x7fd80c9d, 0xbb7a8ee0), TOBN(0xdc2ed3bc, 0x6c01aedb), + TOBN(0x35c35a12, 0x08be74ec), TOBN(0xd540cb1a, 0x469f671f), + TOBN(0xd16ced4e, 0xcf84f6c7), TOBN(0x8561fb9c, 0x2d090f43), + TOBN(0x7e693d79, 0x6f239db4), TOBN(0xa736f928, 0x77bd0d94), + TOBN(0x07b4d929, 0x2c1950ee), TOBN(0xda177543, 0x56dc11b3), + TOBN(0xa5dfbbaa, 0x7a6a878e), TOBN(0x1c70cb29, 0x4decb08a), + TOBN(0xfba28c8b, 0x6f0f7c50), TOBN(0xa8eba2b8, 0x854dcc6d), + TOBN(0x5ff8e89a, 0x36b78642), TOBN(0x070c1c8e, 0xf6873adf), + TOBN(0xbbd3c371, 0x6484d2e4), TOBN(0xfb78318f, 0x0d414129), + TOBN(0x2621a39c, 0x6ad93b0b), TOBN(0x979d74c2, 0xa9e917f7), + TOBN(0xfc195647, 0x61fb0428), TOBN(0x4d78954a, 0xbee624d4), + TOBN(0xb94896e0, 0xb8ae86fd), TOBN(0x6667ac0c, 0xc91c8b13), + TOBN(0x9f180512, 0x43bcf832), TOBN(0xfbadf8b7, 0xa0010137), + TOBN(0xc69b4089, 0xb3ba8aa7), TOBN(0xfac4bacd, 0xe687ce85), + TOBN(0x9164088d, 0x977eab40), TOBN(0x51f4c5b6, 0x2760b390), + TOBN(0xd238238f, 0x340dd553), TOBN(0x358566c3, 0xdb1d31c9), + TOBN(0x3a5ad69e, 0x5068f5ff), TOBN(0xf31435fc, 0xdaff6b06), + TOBN(0xae549a5b, 0xd6debff0), TOBN(0x59e5f0b7, 0x75e01331), + TOBN(0x5d492fb8, 0x98559acf), TOBN(0x96018c2e, 0x4db79b50), + TOBN(0x55f4a48f, 0x609f66aa), TOBN(0x1943b3af, 0x4900a14f), + TOBN(0xc22496df, 0x15a40d39), TOBN(0xb2a44684, 0x4c20f7c5), + TOBN(0x76a35afa, 0x3b98404c), TOBN(0xbec75725, 0xff5d1b77), + TOBN(0xb67aa163, 0xbea06444), TOBN(0x27e95bb2, 0xf724b6f2), + TOBN(0x3c20e3e9, 0xd238c8ab), TOBN(0x1213754e, 0xddd6ae17), + TOBN(0x8c431020, 0x716e0f74), TOBN(0x6679c82e, 0xffc095c2), + TOBN(0x2eb3adf4, 0xd0ac2932), TOBN(0x2cc970d3, 0x01bb7a76), + TOBN(0x70c71f2f, 0x740f0e66), TOBN(0x545c616b, 0x2b6b23cc), + TOBN(0x4528cfcb, 0xb40a8bd7), TOBN(0xff839633, 0x2ab27722), + TOBN(0x049127d9, 0x025ac99a), TOBN(0xd314d4a0, 0x2b63e33b), + TOBN(0xc8c310e7, 0x28d84519), TOBN(0x0fcb8983, 0xb3bc84ba), + TOBN(0x2cc52261, 0x38634818), TOBN(0x501814f4, 0xb44c2e0b), + TOBN(0xf7e181aa, 0x54dfdba3), TOBN(0xcfd58ff0, 0xe759718c), + TOBN(0xf90cdb14, 0xd3b507a8), TOBN(0x57bd478e, 0xc50bdad8), + TOBN(0x29c197e2, 0x50e5f9aa), TOBN(0x4db6eef8, 0xe40bc855), + TOBN(0x2cc8f21a, 0xd1fc0654), TOBN(0xc71cc963, 0x81269d73), + TOBN(0xecfbb204, 0x077f49f9), TOBN(0xdde92571, 0xca56b793), + TOBN(0x9abed6a3, 0xf97ad8f7), TOBN(0xe6c19d3f, 0x924de3bd), + TOBN(0x8dce92f4, 0xa140a800), TOBN(0x85f44d1e, 0x1337af07), + TOBN(0x5953c08b, 0x09d64c52), TOBN(0xa1b5e49f, 0xf5df9749), + TOBN(0x336a8fb8, 0x52735f7d), TOBN(0xb332b6db, 0x9add676b), + TOBN(0x558b88a0, 0xb4511aa4), TOBN(0x09788752, 0xdbd5cc55), + TOBN(0x16b43b9c, 0xd8cd52bd), TOBN(0x7f0bc5a0, 0xc2a2696b), + TOBN(0x146e12d4, 0xc11f61ef), TOBN(0x9ce10754, 0x3a83e79e), + TOBN(0x08ec73d9, 0x6cbfca15), TOBN(0x09ff29ad, 0x5b49653f), + TOBN(0xe31b72bd, 0xe7da946e), TOBN(0xebf9eb3b, 0xee80a4f2), + TOBN(0xd1aabd08, 0x17598ce4), TOBN(0x18b5fef4, 0x53f37e80), + TOBN(0xd5d5cdd3, 0x5958cd79), TOBN(0x3580a1b5, 0x1d373114), + TOBN(0xa36e4c91, 0xfa935726), TOBN(0xa38c534d, 0xef20d760), + TOBN(0x7088e40a, 0x2ff5845b), TOBN(0xe5bb40bd, 0xbd78177f), + TOBN(0x4f06a7a8, 0x857f9920), TOBN(0xe3cc3e50, 0xe968f05d), + TOBN(0x1d68b7fe, 0xe5682d26), TOBN(0x5206f76f, 0xaec7f87c), + TOBN(0x41110530, 0x041951ab), TOBN(0x58ec52c1, 0xd4b5a71a), + TOBN(0xf3488f99, 0x0f75cf9a), TOBN(0xf411951f, 0xba82d0d5), + TOBN(0x27ee75be, 0x618895ab), TOBN(0xeae060d4, 0x6d8aab14), + TOBN(0x9ae1df73, 0x7fb54dc2), TOBN(0x1f3e391b, 0x25963649), + TOBN(0x242ec32a, 0xfe055081), TOBN(0x5bd450ef, 0x8491c9bd), + TOBN(0x367efc67, 0x981eb389), TOBN(0xed7e1928, 0x3a0550d5), + TOBN(0x362e776b, 0xab3ce75c), TOBN(0xe890e308, 0x1f24c523), + TOBN(0xb961b682, 0xfeccef76), TOBN(0x8b8e11f5, 0x8bba6d92), + TOBN(0x8f2ccc4c, 0x2b2375c4), TOBN(0x0d7f7a52, 0xe2f86cfa), + TOBN(0xfd94d30a, 0x9efe5633), TOBN(0x2d8d246b, 0x5451f934), + TOBN(0x2234c6e3, 0x244e6a00), TOBN(0xde2b5b0d, 0xddec8c50), + TOBN(0x2ce53c5a, 0xbf776f5b), TOBN(0x6f724071, 0x60357b05), + TOBN(0xb2593717, 0x71bf3f7a), TOBN(0x87d2501c, 0x440c4a9f), + TOBN(0x440552e1, 0x87b05340), TOBN(0xb7bf7cc8, 0x21624c32), + TOBN(0x4155a6ce, 0x22facddb), TOBN(0x5a4228cb, 0x889837ef), + TOBN(0xef87d6d6, 0xfd4fd671), TOBN(0xa233687e, 0xc2daa10e), + TOBN(0x75622244, 0x03c0eb96), TOBN(0x7632d184, 0x8bf19be6), + TOBN(0x05d0f8e9, 0x40735ff4), TOBN(0x3a3e6e13, 0xc00931f1), + TOBN(0x31ccde6a, 0xdafe3f18), TOBN(0xf381366a, 0xcfe51207), + TOBN(0x24c222a9, 0x60167d92), TOBN(0x62f9d6f8, 0x7529f18c), + TOBN(0x412397c0, 0x0353b114), TOBN(0x334d89dc, 0xef808043), + TOBN(0xd9ec63ba, 0x2a4383ce), TOBN(0xcec8e937, 0x5cf92ba0), + TOBN(0xfb8b4288, 0xc8be74c0), TOBN(0x67d6912f, 0x105d4391), + TOBN(0x7b996c46, 0x1b913149), TOBN(0x36aae2ef, 0x3a4e02da), + TOBN(0xb68aa003, 0x972de594), TOBN(0x284ec70d, 0x4ec6d545), + TOBN(0xf3d2b2d0, 0x61391d54), TOBN(0x69c5d5d6, 0xfe114e92), + TOBN(0xbe0f00b5, 0xb4482dff), TOBN(0xe1596fa5, 0xf5bf33c5), + TOBN(0x10595b56, 0x96a71cba), TOBN(0x944938b2, 0xfdcadeb7), + TOBN(0xa282da4c, 0xfccd8471), TOBN(0x98ec05f3, 0x0d37bfe1), + TOBN(0xe171ce1b, 0x0698304a), TOBN(0x2d691444, 0x21bdf79b), + TOBN(0xd0cd3b74, 0x1b21dec1), TOBN(0x712ecd8b, 0x16a15f71), + TOBN(0x8d4c00a7, 0x00fd56e1), TOBN(0x02ec9692, 0xf9527c18), + TOBN(0x21c44937, 0x4a3e42e1), TOBN(0x9176fbab, 0x1392ae0a), + TOBN(0x8726f1ba, 0x44b7b618), TOBN(0xb4d7aae9, 0xf1de491c), + TOBN(0xf91df7b9, 0x07b582c0), TOBN(0x7e116c30, 0xef60aa3a), + TOBN(0x99270f81, 0x466265d7), TOBN(0xb15b6fe2, 0x4df7adf0), + TOBN(0xfe33b2d3, 0xf9738f7f), TOBN(0x48553ab9, 0xd6d70f95), + TOBN(0x2cc72ac8, 0xc21e94db), TOBN(0x795ac38d, 0xbdc0bbee), + TOBN(0x0a1be449, 0x2e40478f), TOBN(0x81bd3394, 0x052bde55), + TOBN(0x63c8dbe9, 0x56b3c4f2), TOBN(0x017a99cf, 0x904177cc), + TOBN(0x947bbddb, 0x4d010fc1), TOBN(0xacf9b00b, 0xbb2c9b21), + TOBN(0x2970bc8d, 0x47173611), TOBN(0x1a4cbe08, 0xac7d756f), + TOBN(0x06d9f4aa, 0x67d541a2), TOBN(0xa3e8b689, 0x59c2cf44), + TOBN(0xaad066da, 0x4d88f1dd), TOBN(0xc604f165, 0x7ad35dea), + TOBN(0x7edc0720, 0x4478ca67), TOBN(0xa10dfae0, 0xba02ce06), + TOBN(0xeceb1c76, 0xaf36f4e4), TOBN(0x994b2292, 0xaf3f8f48), + TOBN(0xbf9ed77b, 0x77c8a68c), TOBN(0x74f544ea, 0x51744c9d), + TOBN(0x82d05bb9, 0x8113a757), TOBN(0x4ef2d2b4, 0x8a9885e4), + TOBN(0x1e332be5, 0x1aa7865f), TOBN(0x22b76b18, 0x290d1a52), + TOBN(0x308a2310, 0x44351683), TOBN(0x9d861896, 0xa3f22840), + TOBN(0x5959ddcd, 0x841ed947), TOBN(0x0def0c94, 0x154b73bf), + TOBN(0xf0105417, 0x4c7c15e0), TOBN(0x539bfb02, 0x3a277c32), + TOBN(0xe699268e, 0xf9dccf5f), TOBN(0x9f5796a5, 0x0247a3bd), + TOBN(0x8b839de8, 0x4f157269), TOBN(0xc825c1e5, 0x7a30196b), + TOBN(0x6ef0aabc, 0xdc8a5a91), TOBN(0xf4a8ce6c, 0x498b7fe6), + TOBN(0x1cce35a7, 0x70cbac78), TOBN(0x83488e9b, 0xf6b23958), + TOBN(0x0341a070, 0xd76cb011), TOBN(0xda6c9d06, 0xae1b2658), + TOBN(0xb701fb30, 0xdd648c52), TOBN(0x994ca02c, 0x52fb9fd1), + TOBN(0x06933117, 0x6f563086), TOBN(0x3d2b8100, 0x17856bab), + TOBN(0xe89f48c8, 0x5963a46e), TOBN(0x658ab875, 0xa99e61c7), + TOBN(0x6e296f87, 0x4b8517b4), TOBN(0x36c4fcdc, 0xfc1bc656), + TOBN(0xde5227a1, 0xa3906def), TOBN(0x9fe95f57, 0x62418945), + TOBN(0x20c91e81, 0xfdd96cde), TOBN(0x5adbe47e, 0xda4480de), + TOBN(0xa009370f, 0x396de2b6), TOBN(0x98583d4b, 0xf0ecc7bd), + TOBN(0xf44f6b57, 0xe51d0672), TOBN(0x03d6b078, 0x556b1984), + TOBN(0x27dbdd93, 0xb0b64912), TOBN(0x9b3a3434, 0x15687b09), + TOBN(0x0dba6461, 0x51ec20a9), TOBN(0xec93db7f, 0xff28187c), + TOBN(0x00ff8c24, 0x66e48bdd), TOBN(0x2514f2f9, 0x11ccd78e), + TOBN(0xeba11f4f, 0xe1250603), TOBN(0x8a22cd41, 0x243fa156), + TOBN(0xa4e58df4, 0xb283e4c6), TOBN(0x78c29859, 0x8b39783f), + TOBN(0x5235aee2, 0xa5259809), TOBN(0xc16284b5, 0x0e0227dd), + TOBN(0xa5f57916, 0x1338830d), TOBN(0x6d4b8a6b, 0xd2123fca), + TOBN(0x236ea68a, 0xf9c546f8), TOBN(0xc1d36873, 0xfa608d36), + TOBN(0xcd76e495, 0x8d436d13), TOBN(0xd4d9c221, 0x8fb080af), + TOBN(0x665c1728, 0xe8ad3fb5), TOBN(0xcf1ebe4d, 0xb3d572e0), + TOBN(0xa7a8746a, 0x584c5e20), TOBN(0x267e4ea1, 0xb9dc7035), + TOBN(0x593a15cf, 0xb9548c9b), TOBN(0x5e6e2135, 0x4bd012f3), + TOBN(0xdf31cc6a, 0x8c8f936e), TOBN(0x8af84d04, 0xb5c241dc), + TOBN(0x63990a6f, 0x345efb86), TOBN(0x6fef4e61, 0xb9b962cb)}, + {TOBN(0xf6368f09, 0x25722608), TOBN(0x131260db, 0x131cf5c6), + TOBN(0x40eb353b, 0xfab4f7ac), TOBN(0x85c78880, 0x37eee829), + TOBN(0x4c1581ff, 0xc3bdf24e), TOBN(0x5bff75cb, 0xf5c3c5a8), + TOBN(0x35e8c83f, 0xa14e6f40), TOBN(0xb81d1c0f, 0x0295e0ca), + TOBN(0xfcde7cc8, 0xf43a730f), TOBN(0xe89b6f3c, 0x33ab590e), + TOBN(0xc823f529, 0xad03240b), TOBN(0x82b79afe, 0x98bea5db), + TOBN(0x568f2856, 0x962fe5de), TOBN(0x0c590adb, 0x60c591f3), + TOBN(0x1fc74a14, 0x4a28a858), TOBN(0x3b662498, 0xb3203f4c), + TOBN(0x91e3cf0d, 0x6c39765a), TOBN(0xa2db3acd, 0xac3cca0b), + TOBN(0x288f2f08, 0xcb953b50), TOBN(0x2414582c, 0xcf43cf1a), + TOBN(0x8dec8bbc, 0x60eee9a8), TOBN(0x54c79f02, 0x729aa042), + TOBN(0xd81cd5ec, 0x6532f5d5), TOBN(0xa672303a, 0xcf82e15f), + TOBN(0x376aafa8, 0x719c0563), TOBN(0xcd8ad2dc, 0xbc5fc79f), + TOBN(0x303fdb9f, 0xcb750cd3), TOBN(0x14ff052f, 0x4418b08e), + TOBN(0xf75084cf, 0x3e2d6520), TOBN(0x7ebdf0f8, 0x144ed509), + TOBN(0xf43bf0f2, 0xd3f25b98), TOBN(0x86ad71cf, 0xa354d837), + TOBN(0xb827fe92, 0x26f43572), TOBN(0xdfd3ab5b, 0x5d824758), + TOBN(0x315dd23a, 0x539094c1), TOBN(0x85c0e37a, 0x66623d68), + TOBN(0x575c7972, 0x7be19ae0), TOBN(0x616a3396, 0xdf0d36b5), + TOBN(0xa1ebb3c8, 0x26b1ff7e), TOBN(0x635b9485, 0x140ad453), + TOBN(0x92bf3cda, 0xda430c0b), TOBN(0x4702850e, 0x3a96dac6), + TOBN(0xc91cf0a5, 0x15ac326a), TOBN(0x95de4f49, 0xab8c25e4), + TOBN(0xb01bad09, 0xe265c17c), TOBN(0x24e45464, 0x087b3881), + TOBN(0xd43e583c, 0xe1fac5ca), TOBN(0xe17cb318, 0x6ead97a6), + TOBN(0x6cc39243, 0x74dcec46), TOBN(0x33cfc02d, 0x54c2b73f), + TOBN(0x82917844, 0xf26cd99c), TOBN(0x8819dd95, 0xd1773f89), + TOBN(0x09572aa6, 0x0871f427), TOBN(0x8e0cf365, 0xf6f01c34), + TOBN(0x7fa52988, 0xbff1f5af), TOBN(0x4eb357ea, 0xe75e8e50), + TOBN(0xd9d0c8c4, 0x868af75d), TOBN(0xd7325cff, 0x45c8c7ea), + TOBN(0xab471996, 0xcc81ecb0), TOBN(0xff5d55f3, 0x611824ed), + TOBN(0xbe314541, 0x1977a0ee), TOBN(0x5085c4c5, 0x722038c6), + TOBN(0x2d5335bf, 0xf94bb495), TOBN(0x894ad8a6, 0xc8e2a082), + TOBN(0x5c3e2341, 0xada35438), TOBN(0xf4a9fc89, 0x049b8c4e), + TOBN(0xbeeb355a, 0x9f17cf34), TOBN(0x3f311e0e, 0x6c91fe10), + TOBN(0xc2d20038, 0x92ab9891), TOBN(0x257bdcc1, 0x3e8ce9a9), + TOBN(0x1b2d9789, 0x88c53bee), TOBN(0x927ce89a, 0xcdba143a), + TOBN(0xb0a32cca, 0x523db280), TOBN(0x5c889f8a, 0x50d43783), + TOBN(0x503e04b3, 0x4897d16f), TOBN(0x8cdb6e78, 0x08f5f2e8), + TOBN(0x6ab91cf0, 0x179c8e74), TOBN(0xd8874e52, 0x48211d60), + TOBN(0xf948d4d5, 0xea851200), TOBN(0x4076d41e, 0xe6f9840a), + TOBN(0xc20e263c, 0x47b517ea), TOBN(0x79a448fd, 0x30685e5e), + TOBN(0xe55f6f78, 0xf90631a0), TOBN(0x88a790b1, 0xa79e6346), + TOBN(0x62160c7d, 0x80969fe8), TOBN(0x54f92fd4, 0x41491bb9), + TOBN(0xa6645c23, 0x5c957526), TOBN(0xf44cc5ae, 0xbea3ce7b), + TOBN(0xf7628327, 0x8b1e68b7), TOBN(0xc731ad7a, 0x303f29d3), + TOBN(0xfe5a9ca9, 0x57d03ecb), TOBN(0x96c0d50c, 0x41bc97a7), + TOBN(0xc4669fe7, 0x9b4f7f24), TOBN(0xfdd781d8, 0x3d9967ef), + TOBN(0x7892c7c3, 0x5d2c208d), TOBN(0x8bf64f7c, 0xae545cb3), + TOBN(0xc01f862c, 0x467be912), TOBN(0xf4c85ee9, 0xc73d30cc), + TOBN(0x1fa6f4be, 0x6ab83ec7), TOBN(0xa07a3c1c, 0x4e3e3cf9), + TOBN(0x87f8ef45, 0x0c00beb3), TOBN(0x30e2c2b3, 0x000d4c3e), + TOBN(0x1aa00b94, 0xfe08bf5b), TOBN(0x32c133aa, 0x9224ef52), + TOBN(0x38df16bb, 0x32e5685d), TOBN(0x68a9e069, 0x58e6f544), + TOBN(0x495aaff7, 0xcdc5ebc6), TOBN(0xf894a645, 0x378b135f), + TOBN(0xf316350a, 0x09e27ecf), TOBN(0xeced201e, 0x58f7179d), + TOBN(0x2eec273c, 0xe97861ba), TOBN(0x47ec2cae, 0xd693be2e), + TOBN(0xfa4c97c4, 0xf68367ce), TOBN(0xe4f47d0b, 0xbe5a5755), + TOBN(0x17de815d, 0xb298a979), TOBN(0xd7eca659, 0xc177dc7d), + TOBN(0x20fdbb71, 0x49ded0a3), TOBN(0x4cb2aad4, 0xfb34d3c5), + TOBN(0x2cf31d28, 0x60858a33), TOBN(0x3b6873ef, 0xa24aa40f), + TOBN(0x540234b2, 0x2c11bb37), TOBN(0x2d0366dd, 0xed4c74a3), + TOBN(0xf9a968da, 0xeec5f25d), TOBN(0x36601068, 0x67b63142), + TOBN(0x07cd6d2c, 0x68d7b6d4), TOBN(0xa8f74f09, 0x0c842942), + TOBN(0xe2751404, 0x7768b1ee), TOBN(0x4b5f7e89, 0xfe62aee4), + TOBN(0xc6a77177, 0x89070d26), TOBN(0xa1f28e4e, 0xdd1c8bc7), + TOBN(0xea5f4f06, 0x469e1f17), TOBN(0x78fc242a, 0xfbdb78e0), + TOBN(0xc9c7c592, 0x8b0588f1), TOBN(0xb6b7a0fd, 0x1535921e), + TOBN(0xcc5bdb91, 0xbde5ae35), TOBN(0xb42c485e, 0x12ff1864), + TOBN(0xa1113e13, 0xdbab98aa), TOBN(0xde9d469b, 0xa17b1024), + TOBN(0x23f48b37, 0xc0462d3a), TOBN(0x3752e537, 0x7c5c078d), + TOBN(0xe3a86add, 0x15544eb9), TOBN(0xf013aea7, 0x80fba279), + TOBN(0x8b5bb76c, 0xf22001b5), TOBN(0xe617ba14, 0xf02891ab), + TOBN(0xd39182a6, 0x936219d3), TOBN(0x5ce1f194, 0xae51cb19), + TOBN(0xc78f8598, 0xbf07a74c), TOBN(0x6d7158f2, 0x22cbf1bc), + TOBN(0x3b846b21, 0xe300ce18), TOBN(0x35fba630, 0x2d11275d), + TOBN(0x5fe25c36, 0xa0239b9b), TOBN(0xd8beb35d, 0xdf05d940), + TOBN(0x4db02bb0, 0x1f7e320d), TOBN(0x0641c364, 0x6da320ea), + TOBN(0x6d95fa5d, 0x821389a3), TOBN(0x92699748, 0x8fcd8e3d), + TOBN(0x316fef17, 0xceb6c143), TOBN(0x67fcb841, 0xd933762b), + TOBN(0xbb837e35, 0x118b17f8), TOBN(0x4b92552f, 0x9fd24821), + TOBN(0xae6bc70e, 0x46aca793), TOBN(0x1cf0b0e4, 0xe579311b), + TOBN(0x8dc631be, 0x5802f716), TOBN(0x099bdc6f, 0xbddbee4d), + TOBN(0xcc352bb2, 0x0caf8b05), TOBN(0xf74d505a, 0x72d63df2), + TOBN(0xb9876d4b, 0x91c4f408), TOBN(0x1ce18473, 0x9e229b2d), + TOBN(0x49507597, 0x83abdb4a), TOBN(0x850fbcb6, 0xdee84b18), + TOBN(0x6325236e, 0x609e67dc), TOBN(0x04d831d9, 0x9336c6d8), + TOBN(0x8deaae3b, 0xfa12d45d), TOBN(0xe425f8ce, 0x4746e246), + TOBN(0x8004c175, 0x24f5f31e), TOBN(0xaca16d8f, 0xad62c3b7), + TOBN(0x0dc15a6a, 0x9152f934), TOBN(0xf1235e5d, 0xed0e12c1), + TOBN(0xc33c06ec, 0xda477dac), TOBN(0x76be8732, 0xb2ea0006), + TOBN(0xcf3f7831, 0x0c0cd313), TOBN(0x3c524553, 0xa614260d), + TOBN(0x31a756f8, 0xcab22d15), TOBN(0x03ee10d1, 0x77827a20), + TOBN(0xd1e059b2, 0x1994ef20), TOBN(0x2a653b69, 0x638ae318), + TOBN(0x70d5eb58, 0x2f699010), TOBN(0x279739f7, 0x09f5f84a), + TOBN(0x5da4663c, 0x8b799336), TOBN(0xfdfdf14d, 0x203c37eb), + TOBN(0x32d8a9dc, 0xa1dbfb2d), TOBN(0xab40cff0, 0x77d48f9b), + TOBN(0xc018b383, 0xd20b42d5), TOBN(0xf9a810ef, 0x9f78845f), + TOBN(0x40af3753, 0xbdba9df0), TOBN(0xb90bdcfc, 0x131dfdf9), + TOBN(0x18720591, 0xf01ab782), TOBN(0xc823f211, 0x6af12a88), + TOBN(0xa51b80f3, 0x0dc14401), TOBN(0xde248f77, 0xfb2dfbe3), + TOBN(0xef5a44e5, 0x0cafe751), TOBN(0x73997c9c, 0xd4dcd221), + TOBN(0x32fd86d1, 0xde854024), TOBN(0xd5b53adc, 0xa09b84bb), + TOBN(0x008d7a11, 0xdcedd8d1), TOBN(0x406bd1c8, 0x74b32c84), + TOBN(0x5d4472ff, 0x05dde8b1), TOBN(0x2e25f2cd, 0xfce2b32f), + TOBN(0xbec0dd5e, 0x29dfc254), TOBN(0x4455fcf6, 0x2b98b267), + TOBN(0x0b4d43a5, 0xc72df2ad), TOBN(0xea70e6be, 0x48a75397), + TOBN(0x2aad6169, 0x5820f3bf), TOBN(0xf410d2dd, 0x9e37f68f), + TOBN(0x70fb7dba, 0x7be5ac83), TOBN(0x636bb645, 0x36ec3eec), + TOBN(0x27104ea3, 0x9754e21c), TOBN(0xbc87a3e6, 0x8d63c373), + TOBN(0x483351d7, 0x4109db9a), TOBN(0x0fa724e3, 0x60134da7), + TOBN(0x9ff44c29, 0xb0720b16), TOBN(0x2dd0cf13, 0x06aceead), + TOBN(0x5942758c, 0xe26929a6), TOBN(0x96c5db92, 0xb766a92b), + TOBN(0xcec7d4c0, 0x5f18395e), TOBN(0xd3f22744, 0x1f80d032), + TOBN(0x7a68b37a, 0xcb86075b), TOBN(0x074764dd, 0xafef92db), + TOBN(0xded1e950, 0x7bc7f389), TOBN(0xc580c850, 0xb9756460), + TOBN(0xaeeec2a4, 0x7da48157), TOBN(0x3f0b4e7f, 0x82c587b3), + TOBN(0x231c6de8, 0xa9f19c53), TOBN(0x5717bd73, 0x6974e34e), + TOBN(0xd9e1d216, 0xf1508fa9), TOBN(0x9f112361, 0xdadaa124), + TOBN(0x80145e31, 0x823b7348), TOBN(0x4dd8f0d5, 0xac634069), + TOBN(0xe3d82fc7, 0x2297c258), TOBN(0x276fcfee, 0x9cee7431), + TOBN(0x8eb61b5e, 0x2bc0aea9), TOBN(0x4f668fd5, 0xde329431), + TOBN(0x03a32ab1, 0x38e4b87e), TOBN(0xe1374517, 0x73d0ef0b), + TOBN(0x1a46f7e6, 0x853ac983), TOBN(0xc3bdf42e, 0x68e78a57), + TOBN(0xacf20785, 0x2ea96dd1), TOBN(0xa10649b9, 0xf1638460), + TOBN(0xf2369f0b, 0x879fbbed), TOBN(0x0ff0ae86, 0xda9d1869), + TOBN(0x5251d759, 0x56766f45), TOBN(0x4984d8c0, 0x2be8d0fc), + TOBN(0x7ecc95a6, 0xd21008f0), TOBN(0x29bd54a0, 0x3a1a1c49), + TOBN(0xab9828c5, 0xd26c50f3), TOBN(0x32c0087c, 0x51d0d251), + TOBN(0x9bac3ce6, 0x0c1cdb26), TOBN(0xcd94d947, 0x557ca205), + TOBN(0x1b1bd598, 0x9db1fdcd), TOBN(0x0eda0108, 0xa3d8b149), + TOBN(0x95066610, 0x56152fcc), TOBN(0xc2f037e6, 0xe7192b33), + TOBN(0xdeffb41a, 0xc92e05a4), TOBN(0x1105f6c2, 0xc2f6c62e), + TOBN(0x68e73500, 0x8733913c), TOBN(0xcce86163, 0x3f3adc40), + TOBN(0xf407a942, 0x38a278e9), TOBN(0xd13c1b9d, 0x2ab21292), + TOBN(0x93ed7ec7, 0x1c74cf5c), TOBN(0x8887dc48, 0xf1a4c1b4), + TOBN(0x3830ff30, 0x4b3a11f1), TOBN(0x358c5a3c, 0x58937cb6), + TOBN(0x027dc404, 0x89022829), TOBN(0x40e93977, 0x3b798f79), + TOBN(0x90ad3337, 0x38be6ead), TOBN(0x9c23f6bc, 0xf34c0a5d), + TOBN(0xd1711a35, 0xfbffd8bb), TOBN(0x60fcfb49, 0x1949d3dd), + TOBN(0x09c8ef4b, 0x7825d93a), TOBN(0x24233cff, 0xa0a8c968), + TOBN(0x67ade46c, 0xe6d982af), TOBN(0xebb6bf3e, 0xe7544d7c), + TOBN(0xd6b9ba76, 0x3d8bd087), TOBN(0x46fe382d, 0x4dc61280), + TOBN(0xbd39a7e8, 0xb5bdbd75), TOBN(0xab381331, 0xb8f228fe), + TOBN(0x0709a77c, 0xce1c4300), TOBN(0x6a247e56, 0xf337ceac), + TOBN(0x8f34f21b, 0x636288be), TOBN(0x9dfdca74, 0xc8a7c305), + TOBN(0x6decfd1b, 0xea919e04), TOBN(0xcdf2688d, 0x8e1991f8), + TOBN(0xe607df44, 0xd0f8a67e), TOBN(0xd985df4b, 0x0b58d010), + TOBN(0x57f834c5, 0x0c24f8f4), TOBN(0xe976ef56, 0xa0bf01ae), + TOBN(0x536395ac, 0xa1c32373), TOBN(0x351027aa, 0x734c0a13), + TOBN(0xd2f1b5d6, 0x5e6bd5bc), TOBN(0x2b539e24, 0x223debed), + TOBN(0xd4994cec, 0x0eaa1d71), TOBN(0x2a83381d, 0x661dcf65), + TOBN(0x5f1aed2f, 0x7b54c740), TOBN(0x0bea3fa5, 0xd6dda5ee), + TOBN(0x9d4fb684, 0x36cc6134), TOBN(0x8eb9bbf3, 0xc0a443dd), + TOBN(0xfc500e2e, 0x383b7d2a), TOBN(0x7aad621c, 0x5b775257), + TOBN(0x69284d74, 0x0a8f7cc0), TOBN(0xe820c2ce, 0x07562d65), + TOBN(0xbf9531b9, 0x499758ee), TOBN(0x73e95ca5, 0x6ee0cc2d), + TOBN(0xf61790ab, 0xfbaf50a5), TOBN(0xdf55e76b, 0x684e0750), + TOBN(0xec516da7, 0xf176b005), TOBN(0x575553bb, 0x7a2dddc7), + TOBN(0x37c87ca3, 0x553afa73), TOBN(0x315f3ffc, 0x4d55c251), + TOBN(0xe846442a, 0xaf3e5d35), TOBN(0x61b91149, 0x6495ff28), + TOBN(0x23cc95d3, 0xfa326dc3), TOBN(0x1df4da1f, 0x18fc2cea), + TOBN(0x24bf9adc, 0xd0a37d59), TOBN(0xb6710053, 0x320d6e1e), + TOBN(0x96f9667e, 0x618344d1), TOBN(0xcc7ce042, 0xa06445af), + TOBN(0xa02d8514, 0xd68dbc3a), TOBN(0x4ea109e4, 0x280b5a5b), + TOBN(0x5741a7ac, 0xb40961bf), TOBN(0x4ada5937, 0x6aa56bfa), + TOBN(0x7feb9145, 0x02b765d1), TOBN(0x561e97be, 0xe6ad1582), + TOBN(0xbbc4a5b6, 0xda3982f5), TOBN(0x0c2659ed, 0xb546f468), + TOBN(0xb8e7e6aa, 0x59612d20), TOBN(0xd83dfe20, 0xac19e8e0), + TOBN(0x8530c45f, 0xb835398c), TOBN(0x6106a8bf, 0xb38a41c2), + TOBN(0x21e8f9a6, 0x35f5dcdb), TOBN(0x39707137, 0xcae498ed), + TOBN(0x70c23834, 0xd8249f00), TOBN(0x9f14b58f, 0xab2537a0), + TOBN(0xd043c365, 0x5f61c0c2), TOBN(0xdc5926d6, 0x09a194a7), + TOBN(0xddec0339, 0x8e77738a), TOBN(0xd07a63ef, 0xfba46426), + TOBN(0x2e58e79c, 0xee7f6e86), TOBN(0xe59b0459, 0xff32d241), + TOBN(0xc5ec84e5, 0x20fa0338), TOBN(0x97939ac8, 0xeaff5ace), + TOBN(0x0310a4e3, 0xb4a38313), TOBN(0x9115fba2, 0x8f9d9885), + TOBN(0x8dd710c2, 0x5fadf8c3), TOBN(0x66be38a2, 0xce19c0e2), + TOBN(0xd42a279c, 0x4cfe5022), TOBN(0x597bb530, 0x0e24e1b8), + TOBN(0x3cde86b7, 0xc153ca7f), TOBN(0xa8d30fb3, 0x707d63bd), + TOBN(0xac905f92, 0xbd60d21e), TOBN(0x98e7ffb6, 0x7b9a54ab), + TOBN(0xd7147df8, 0xe9726a30), TOBN(0xb5e216ff, 0xafce3533), + TOBN(0xb550b799, 0x2ff1ec40), TOBN(0x6b613b87, 0xa1e953fd), + TOBN(0x87b88dba, 0x792d5610), TOBN(0x2ee1270a, 0xa190fbe1), + TOBN(0x02f4e2dc, 0x2ef581da), TOBN(0x016530e4, 0xeff82a95), + TOBN(0xcbb93dfd, 0x8fd6ee89), TOBN(0x16d3d986, 0x46848fff), + TOBN(0x600eff24, 0x1da47adf), TOBN(0x1b9754a0, 0x0ad47a71), + TOBN(0x8f9266df, 0x70c33b98), TOBN(0xaadc87ae, 0xdf34186e), + TOBN(0x0d2ce8e1, 0x4ad24132), TOBN(0x8a47cbfc, 0x19946eba), + TOBN(0x47feeb66, 0x62b5f3af), TOBN(0xcefab561, 0x0abb3734), + TOBN(0x449de60e, 0x19f35cb1), TOBN(0x39f8db14, 0x157f0eb9), + TOBN(0xffaecc5b, 0x3c61bfd6), TOBN(0xa5a4d41d, 0x41216703), + TOBN(0x7f8fabed, 0x224e1cc2), TOBN(0x0d5a8186, 0x871ad953), + TOBN(0xf10774f7, 0xd22da9a9), TOBN(0x45b8a678, 0xcc8a9b0d), + TOBN(0xd9c2e722, 0xbdc32cff), TOBN(0xbf71b5f5, 0x337202a5), + TOBN(0x95c57f2f, 0x69fc4db9), TOBN(0xb6dad34c, 0x765d01e1), + TOBN(0x7e0bd13f, 0xcb904635), TOBN(0x61751253, 0x763a588c), + TOBN(0xd85c2997, 0x81af2c2d), TOBN(0xc0f7d9c4, 0x81b9d7da), + TOBN(0x838a34ae, 0x08533e8d), TOBN(0x15c4cb08, 0x311d8311), + TOBN(0x97f83285, 0x8e121e14), TOBN(0xeea7dc1e, 0x85000a5f), + TOBN(0x0c6059b6, 0x5d256274), TOBN(0xec9beace, 0xb95075c0), + TOBN(0x173daad7, 0x1df97828), TOBN(0xbf851cb5, 0xa8937877), + TOBN(0xb083c594, 0x01646f3c), TOBN(0x3bad30cf, 0x50c6d352), + TOBN(0xfeb2b202, 0x496bbcea), TOBN(0x3cf9fd4f, 0x18a1e8ba), + TOBN(0xd26de7ff, 0x1c066029), TOBN(0x39c81e9e, 0x4e9ed4f8), + TOBN(0xd8be0cb9, 0x7b390d35), TOBN(0x01df2bbd, 0x964aab27), + TOBN(0x3e8c1a65, 0xc3ef64f8), TOBN(0x567291d1, 0x716ed1dd), + TOBN(0x95499c6c, 0x5f5406d3), TOBN(0x71fdda39, 0x5ba8e23f), + TOBN(0xcfeb320e, 0xd5096ece), TOBN(0xbe7ba92b, 0xca66dd16), + TOBN(0x4608d36b, 0xc6fb5a7d), TOBN(0xe3eea15a, 0x6d2dd0e0), + TOBN(0x75b0a3eb, 0x8f97a36a), TOBN(0xf59814cc, 0x1c83de1e), + TOBN(0x56c9c5b0, 0x1c33c23f), TOBN(0xa96c1da4, 0x6faa4136), + TOBN(0x46bf2074, 0xde316551), TOBN(0x3b866e7b, 0x1f756c8f), + TOBN(0x727727d8, 0x1495ed6b), TOBN(0xb2394243, 0xb682dce7), + TOBN(0x8ab8454e, 0x758610f3), TOBN(0xc243ce84, 0x857d72a4), + TOBN(0x7b320d71, 0xdbbf370f), TOBN(0xff9afa37, 0x78e0f7ca), + TOBN(0x0119d1e0, 0xea7b523f), TOBN(0xb997f8cb, 0x058c7d42), + TOBN(0x285bcd2a, 0x37bbb184), TOBN(0x51dcec49, 0xa45d1fa6), + TOBN(0x6ade3b64, 0xe29634cb), TOBN(0x080c94a7, 0x26b86ef1), + TOBN(0xba583db1, 0x2283fbe3), TOBN(0x902bddc8, 0x5a9315ed), + TOBN(0x07c1ccb3, 0x86964bec), TOBN(0x78f4eacf, 0xb6258301), + TOBN(0x4bdf3a49, 0x56f90823), TOBN(0xba0f5080, 0x741d777b), + TOBN(0x091d71c3, 0xf38bf760), TOBN(0x9633d50f, 0x9b625b02), + TOBN(0x03ecb743, 0xb8c9de61), TOBN(0xb4751254, 0x5de74720), + TOBN(0x9f9defc9, 0x74ce1cb2), TOBN(0x774a4f6a, 0x00bd32ef), + TOBN(0xaca385f7, 0x73848f22), TOBN(0x53dad716, 0xf3f8558e), + TOBN(0xab7b34b0, 0x93c471f9), TOBN(0xf530e069, 0x19644bc7), + TOBN(0x3d9fb1ff, 0xdd59d31a), TOBN(0x4382e0df, 0x08daa795), + TOBN(0x165c6f4b, 0xd5cc88d7), TOBN(0xeaa392d5, 0x4a18c900), + TOBN(0x94203c67, 0x648024ee), TOBN(0x188763f2, 0x8c2fabcd), + TOBN(0xa80f87ac, 0xbbaec835), TOBN(0x632c96e0, 0xf29d8d54), + TOBN(0x29b0a60e, 0x4c00a95e), TOBN(0x2ef17f40, 0xe011e9fa), + TOBN(0xf6c0e1d1, 0x15b77223), TOBN(0xaaec2c62, 0x14b04e32), + TOBN(0xd35688d8, 0x3d84e58c), TOBN(0x2af5094c, 0x958571db), + TOBN(0x4fff7e19, 0x760682a6), TOBN(0x4cb27077, 0xe39a407c), + TOBN(0x0f59c547, 0x4ff0e321), TOBN(0x169f34a6, 0x1b34c8ff), + TOBN(0x2bff1096, 0x52bc1ba7), TOBN(0xa25423b7, 0x83583544), + TOBN(0x5d55d5d5, 0x0ac8b782), TOBN(0xff6622ec, 0x2db3c892), + TOBN(0x48fce741, 0x6b8bb642), TOBN(0x31d6998c, 0x69d7e3dc), + TOBN(0xdbaf8004, 0xcadcaed0), TOBN(0x801b0142, 0xd81d053c), + TOBN(0x94b189fc, 0x59630ec6), TOBN(0x120e9934, 0xaf762c8e), + TOBN(0x53a29aa4, 0xfdc6a404), TOBN(0x19d8e01e, 0xa1909948), + TOBN(0x3cfcabf1, 0xd7e89681), TOBN(0x3321a50d, 0x4e132d37), + TOBN(0xd0496863, 0xe9a86111), TOBN(0x8c0cde61, 0x06a3bc65), + TOBN(0xaf866c49, 0xfc9f8eef), TOBN(0x2066350e, 0xff7f5141), + TOBN(0x4f8a4689, 0xe56ddfbd), TOBN(0xea1b0c07, 0xfe32983a), + TOBN(0x2b317462, 0x873cb8cb), TOBN(0x658deddc, 0x2d93229f), + TOBN(0x65efaf4d, 0x0f64ef58), TOBN(0xfe43287d, 0x730cc7a8), + TOBN(0xaebc0c72, 0x3d047d70), TOBN(0x92efa539, 0xd92d26c9), + TOBN(0x06e78457, 0x94b56526), TOBN(0x415cb80f, 0x0961002d), + TOBN(0x89e5c565, 0x76dcb10f), TOBN(0x8bbb6982, 0xff9259fe), + TOBN(0x4fe8795b, 0x9abc2668), TOBN(0xb5d4f534, 0x1e678fb1), + TOBN(0x6601f3be, 0x7b7da2b9), TOBN(0x98da59e2, 0xa13d6805), + TOBN(0x190d8ea6, 0x01799a52), TOBN(0xa20cec41, 0xb86d2952), + TOBN(0x3062ffb2, 0x7fff2a7c), TOBN(0x741b32e5, 0x79f19d37), + TOBN(0xf80d8181, 0x4eb57d47), TOBN(0x7a2d0ed4, 0x16aef06b), + TOBN(0x09735fb0, 0x1cecb588), TOBN(0x1641caaa, 0xc6061f5b)}, + {TOBN(0x7f99824f, 0x20151427), TOBN(0x206828b6, 0x92430206), + TOBN(0xaa9097d7, 0xe1112357), TOBN(0xacf9a2f2, 0x09e414ec), + TOBN(0xdbdac9da, 0x27915356), TOBN(0x7e0734b7, 0x001efee3), + TOBN(0x54fab5bb, 0xd2b288e2), TOBN(0x4c630fc4, 0xf62dd09c), + TOBN(0x8537107a, 0x1ac2703b), TOBN(0xb49258d8, 0x6bc857b5), + TOBN(0x57df14de, 0xbcdaccd1), TOBN(0x24ab68d7, 0xc4ae8529), + TOBN(0x7ed8b5d4, 0x734e59d0), TOBN(0x5f8740c8, 0xc495cc80), + TOBN(0x84aedd5a, 0x291db9b3), TOBN(0x80b360f8, 0x4fb995be), + TOBN(0xae915f5d, 0x5fa067d1), TOBN(0x4134b57f, 0x9668960c), + TOBN(0xbd3656d6, 0xa48edaac), TOBN(0xdac1e3e4, 0xfc1d7436), + TOBN(0x674ff869, 0xd81fbb26), TOBN(0x449ed3ec, 0xb26c33d4), + TOBN(0x85138705, 0xd94203e8), TOBN(0xccde538b, 0xbeeb6f4a), + TOBN(0x55d5c68d, 0xa61a76fa), TOBN(0x598b441d, 0xca1554dc), + TOBN(0xd39923b9, 0x773b279c), TOBN(0x33331d3c, 0x36bf9efc), + TOBN(0x2d4c848e, 0x298de399), TOBN(0xcfdb8e77, 0xa1a27f56), + TOBN(0x94c855ea, 0x57b8ab70), TOBN(0xdcdb9dae, 0x6f7879ba), + TOBN(0x7bdff8c2, 0x019f2a59), TOBN(0xb3ce5bb3, 0xcb4fbc74), + TOBN(0xea907f68, 0x8a9173dd), TOBN(0x6cd3d0d3, 0x95a75439), + TOBN(0x92ecc4d6, 0xefed021c), TOBN(0x09a9f9b0, 0x6a77339a), + TOBN(0x87ca6b15, 0x7188c64a), TOBN(0x10c29968, 0x44899158), + TOBN(0x5859a229, 0xed6e82ef), TOBN(0x16f338e3, 0x65ebaf4e), + TOBN(0x0cd31387, 0x5ead67ae), TOBN(0x1c73d228, 0x54ef0bb4), + TOBN(0x4cb55131, 0x74a5c8c7), TOBN(0x01cd2970, 0x7f69ad6a), + TOBN(0xa04d00dd, 0xe966f87e), TOBN(0xd96fe447, 0x0b7b0321), + TOBN(0x342ac06e, 0x88fbd381), TOBN(0x02cd4a84, 0x5c35a493), + TOBN(0xe8fa89de, 0x54f1bbcd), TOBN(0x341d6367, 0x2575ed4c), + TOBN(0xebe357fb, 0xd238202b), TOBN(0x600b4d1a, 0xa984ead9), + TOBN(0xc35c9f44, 0x52436ea0), TOBN(0x96fe0a39, 0xa370751b), + TOBN(0x4c4f0736, 0x7f636a38), TOBN(0x9f943fb7, 0x0e76d5cb), + TOBN(0xb03510ba, 0xa8b68b8b), TOBN(0xc246780a, 0x9ed07a1f), + TOBN(0x3c051415, 0x6d549fc2), TOBN(0xc2953f31, 0x607781ca), + TOBN(0x955e2c69, 0xd8d95413), TOBN(0xb300fadc, 0x7bd282e3), + TOBN(0x81fe7b50, 0x87e9189f), TOBN(0xdb17375c, 0xf42dda27), + TOBN(0x22f7d896, 0xcf0a5904), TOBN(0xa0e57c5a, 0xebe348e6), + TOBN(0xa61011d3, 0xf40e3c80), TOBN(0xb1189321, 0x8db705c5), + TOBN(0x4ed9309e, 0x50fedec3), TOBN(0xdcf14a10, 0x4d6d5c1d), + TOBN(0x056c265b, 0x55691342), TOBN(0xe8e08504, 0x91049dc7), + TOBN(0x131329f5, 0xc9bae20a), TOBN(0x96c8b3e8, 0xd9dccdb4), + TOBN(0x8c5ff838, 0xfb4ee6b4), TOBN(0xfc5a9aeb, 0x41e8ccf0), + TOBN(0x7417b764, 0xfae050c6), TOBN(0x0953c3d7, 0x00452080), + TOBN(0x21372682, 0x38dfe7e8), TOBN(0xea417e15, 0x2bb79d4b), + TOBN(0x59641f1c, 0x76e7cf2d), TOBN(0x271e3059, 0xea0bcfcc), + TOBN(0x624c7dfd, 0x7253ecbd), TOBN(0x2f552e25, 0x4fca6186), + TOBN(0xcbf84ecd, 0x4d866e9c), TOBN(0x73967709, 0xf68d4610), + TOBN(0xa14b1163, 0xc27901b4), TOBN(0xfd9236e0, 0x899b8bf3), + TOBN(0x42b091ec, 0xcbc6da0a), TOBN(0xbb1dac6f, 0x5ad1d297), + TOBN(0x80e61d53, 0xa91cf76e), TOBN(0x4110a412, 0xd31f1ee7), + TOBN(0x2d87c3ba, 0x13efcf77), TOBN(0x1f374bb4, 0xdf450d76), + TOBN(0x5e78e2f2, 0x0d188dab), TOBN(0xe3968ed0, 0xf4b885ef), + TOBN(0x46c0568e, 0x7314570f), TOBN(0x31616338, 0x01170521), + TOBN(0x18e1e7e2, 0x4f0c8afe), TOBN(0x4caa75ff, 0xdeea78da), + TOBN(0x82db67f2, 0x7c5d8a51), TOBN(0x36a44d86, 0x6f505370), + TOBN(0xd72c5bda, 0x0333974f), TOBN(0x5db516ae, 0x27a70146), + TOBN(0x34705281, 0x210ef921), TOBN(0xbff17a8f, 0x0c9c38e5), + TOBN(0x78f4814e, 0x12476da1), TOBN(0xc1e16613, 0x33c16980), + TOBN(0x9e5b386f, 0x424d4bca), TOBN(0x4c274e87, 0xc85740de), + TOBN(0xb6a9b88d, 0x6c2f5226), TOBN(0x14d1b944, 0x550d7ca8), + TOBN(0x580c85fc, 0x1fc41709), TOBN(0xc1da368b, 0x54c6d519), + TOBN(0x2b0785ce, 0xd5113cf7), TOBN(0x0670f633, 0x5a34708f), + TOBN(0x46e23767, 0x15cc3f88), TOBN(0x1b480cfa, 0x50c72c8f), + TOBN(0x20288602, 0x4147519a), TOBN(0xd0981eac, 0x26b372f0), + TOBN(0xa9d4a7ca, 0xa785ebc8), TOBN(0xd953c50d, 0xdbdf58e9), + TOBN(0x9d6361cc, 0xfd590f8f), TOBN(0x72e9626b, 0x44e6c917), + TOBN(0x7fd96110, 0x22eb64cf), TOBN(0x863ebb7e, 0x9eb288f3), + TOBN(0x6e6ab761, 0x6aca8ee7), TOBN(0x97d10b39, 0xd7b40358), + TOBN(0x1687d377, 0x1e5feb0d), TOBN(0xc83e50e4, 0x8265a27a), + TOBN(0x8f75a9fe, 0xc954b313), TOBN(0xcc2e8f47, 0x310d1f61), + TOBN(0xf5ba81c5, 0x6557d0e0), TOBN(0x25f9680c, 0x3eaf6207), + TOBN(0xf95c6609, 0x4354080b), TOBN(0x5225bfa5, 0x7bf2fe1c), + TOBN(0xc5c004e2, 0x5c7d98fa), TOBN(0x3561bf1c, 0x019aaf60), + TOBN(0x5e6f9f17, 0xba151474), TOBN(0xdec2f934, 0xb04f6eca), + TOBN(0x64e368a1, 0x269acb1e), TOBN(0x1332d9e4, 0x0cdda493), + TOBN(0x60d6cf69, 0xdf23de05), TOBN(0x66d17da2, 0x009339a0), + TOBN(0x9fcac985, 0x0a693923), TOBN(0xbcf057fc, 0xed7c6a6d), + TOBN(0xc3c5c8c5, 0xf0b5662c), TOBN(0x25318dd8, 0xdcba4f24), + TOBN(0x60e8cb75, 0x082b69ff), TOBN(0x7c23b3ee, 0x1e728c01), + TOBN(0x15e10a0a, 0x097e4403), TOBN(0xcb3d0a86, 0x19854665), + TOBN(0x88d8e211, 0xd67d4826), TOBN(0xb39af66e, 0x0b9d2839), + TOBN(0xa5f94588, 0xbd475ca8), TOBN(0xe06b7966, 0xc077b80b), + TOBN(0xfedb1485, 0xda27c26c), TOBN(0xd290d33a, 0xfe0fd5e0), + TOBN(0xa40bcc47, 0xf34fb0fa), TOBN(0xb4760cc8, 0x1fb1ab09), + TOBN(0x8fca0993, 0xa273bfe3), TOBN(0x13e4fe07, 0xf70b213c), + TOBN(0x3bcdb992, 0xfdb05163), TOBN(0x8c484b11, 0x0c2b19b6), + TOBN(0x1acb815f, 0xaaf2e3e2), TOBN(0xc6905935, 0xb89ff1b4), + TOBN(0xb2ad6f9d, 0x586e74e1), TOBN(0x488883ad, 0x67b80484), + TOBN(0x758aa2c7, 0x369c3ddb), TOBN(0x8ab74e69, 0x9f9afd31), + TOBN(0x10fc2d28, 0x5e21beb1), TOBN(0x3484518a, 0x318c42f9), + TOBN(0x377427dc, 0x53cf40c3), TOBN(0x9de0781a, 0x391bc1d9), + TOBN(0x8faee858, 0x693807e1), TOBN(0xa3865327, 0x4e81ccc7), + TOBN(0x02c30ff2, 0x6f835b84), TOBN(0xb604437b, 0x0d3d38d4), + TOBN(0xb3fc8a98, 0x5ca1823d), TOBN(0xb82f7ec9, 0x03be0324), + TOBN(0xee36d761, 0xcf684a33), TOBN(0x5a01df0e, 0x9f29bf7d), + TOBN(0x686202f3, 0x1306583d), TOBN(0x05b10da0, 0x437c622e), + TOBN(0xbf9aaa0f, 0x076a7bc8), TOBN(0x25e94efb, 0x8f8f4e43), + TOBN(0x8a35c9b7, 0xfa3dc26d), TOBN(0xe0e5fb93, 0x96ff03c5), + TOBN(0xa77e3843, 0xebc394ce), TOBN(0xcede6595, 0x8361de60), + TOBN(0xd27c22f6, 0xa1993545), TOBN(0xab01cc36, 0x24d671ba), + TOBN(0x63fa2877, 0xa169c28e), TOBN(0x925ef904, 0x2eb08376), + TOBN(0x3b2fa3cf, 0x53aa0b32), TOBN(0xb27beb5b, 0x71c49d7a), + TOBN(0xb60e1834, 0xd105e27f), TOBN(0xd6089788, 0x4f68570d), + TOBN(0x23094ce0, 0xd6fbc2ac), TOBN(0x738037a1, 0x815ff551), + TOBN(0xda73b1bb, 0x6bef119c), TOBN(0xdcf6c430, 0xeef506ba), + TOBN(0x00e4fe7b, 0xe3ef104a), TOBN(0xebdd9a2c, 0x0a065628), + TOBN(0x853a81c3, 0x8792043e), TOBN(0x22ad6ece, 0xb3b59108), + TOBN(0x9fb813c0, 0x39cd297d), TOBN(0x8ec7e16e, 0x05bda5d9), + TOBN(0x2834797c, 0x0d104b96), TOBN(0xcc11a2e7, 0x7c511510), + TOBN(0x96ca5a53, 0x96ee6380), TOBN(0x054c8655, 0xcea38742), + TOBN(0xb5946852, 0xd54dfa7d), TOBN(0x97c422e7, 0x1f4ab207), + TOBN(0xbf907509, 0x0c22b540), TOBN(0x2cde42aa, 0xb7c267d4), + TOBN(0xba18f9ed, 0x5ab0d693), TOBN(0x3ba62aa6, 0x6e4660d9), + TOBN(0xb24bf97b, 0xab9ea96a), TOBN(0x5d039642, 0xe3b60e32), + TOBN(0x4e6a4506, 0x7c4d9bd5), TOBN(0x666c5b9e, 0x7ed4a6a4), + TOBN(0xfa3fdcd9, 0x8edbd7cc), TOBN(0x4660bb87, 0xc6ccd753), + TOBN(0x9ae90820, 0x21e6b64f), TOBN(0x8a56a713, 0xb36bfb3f), + TOBN(0xabfce096, 0x5726d47f), TOBN(0x9eed01b2, 0x0b1a9a7f), + TOBN(0x30e9cad4, 0x4eb74a37), TOBN(0x7b2524cc, 0x53e9666d), + TOBN(0x6a29683b, 0x8f4b002f), TOBN(0xc2200d7a, 0x41f4fc20), + TOBN(0xcf3af47a, 0x3a338acc), TOBN(0x6539a4fb, 0xe7128975), + TOBN(0xcec31c14, 0xc33c7fcf), TOBN(0x7eb6799b, 0xc7be322b), + TOBN(0x119ef4e9, 0x6646f623), TOBN(0x7b7a26a5, 0x54d7299b), + TOBN(0xcb37f08d, 0x403f46f2), TOBN(0x94b8fc43, 0x1a0ec0c7), + TOBN(0xbb8514e3, 0xc332142f), TOBN(0xf3ed2c33, 0xe80d2a7a), + TOBN(0x8d2080af, 0xb639126c), TOBN(0xf7b6be60, 0xe3553ade), + TOBN(0x3950aa9f, 0x1c7e2b09), TOBN(0x847ff958, 0x6410f02b), + TOBN(0x877b7cf5, 0x678a31b0), TOBN(0xd50301ae, 0x3998b620), + TOBN(0x734257c5, 0xc00fb396), TOBN(0xf9fb18a0, 0x04e672a6), + TOBN(0xff8bd8eb, 0xe8758851), TOBN(0x1e64e4c6, 0x5d99ba44), + TOBN(0x4b8eaedf, 0x7dfd93b7), TOBN(0xba2f2a98, 0x04e76b8c), + TOBN(0x7d790cba, 0xe8053433), TOBN(0xc8e725a0, 0x3d2c9585), + TOBN(0x58c5c476, 0xcdd8f5ed), TOBN(0xd106b952, 0xefa9fe1d), + TOBN(0x3c5c775b, 0x0eff13a9), TOBN(0x242442ba, 0xe057b930), + TOBN(0xe9f458d4, 0xc9b70cbd), TOBN(0x69b71448, 0xa3cdb89a), + TOBN(0x41ee46f6, 0x0e2ed742), TOBN(0x573f1045, 0x40067493), + TOBN(0xb1e154ff, 0x9d54c304), TOBN(0x2ad0436a, 0x8d3a7502), + TOBN(0xee4aaa2d, 0x431a8121), TOBN(0xcd38b3ab, 0x886f11ed), + TOBN(0x57d49ea6, 0x034a0eb7), TOBN(0xd2b773bd, 0xf7e85e58), + TOBN(0x4a559ac4, 0x9b5c1f14), TOBN(0xc444be1a, 0x3e54df2b), + TOBN(0x13aad704, 0xeda41891), TOBN(0xcd927bec, 0x5eb5c788), + TOBN(0xeb3c8516, 0xe48c8a34), TOBN(0x1b7ac812, 0x4b546669), + TOBN(0x1815f896, 0x594df8ec), TOBN(0x87c6a79c, 0x79227865), + TOBN(0xae02a2f0, 0x9b56ddbd), TOBN(0x1339b5ac, 0x8a2f1cf3), + TOBN(0xf2b569c7, 0x839dff0d), TOBN(0xb0b9e864, 0xfee9a43d), + TOBN(0x4ff8ca41, 0x77bb064e), TOBN(0x145a2812, 0xfd249f63), + TOBN(0x3ab7beac, 0xf86f689a), TOBN(0x9bafec27, 0x01d35f5e), + TOBN(0x28054c65, 0x4265aa91), TOBN(0xa4b18304, 0x035efe42), + TOBN(0x6887b0e6, 0x9639dec7), TOBN(0xf4b8f6ad, 0x3d52aea5), + TOBN(0xfb9293cc, 0x971a8a13), TOBN(0x3f159e5d, 0x4c934d07), + TOBN(0x2c50e9b1, 0x09acbc29), TOBN(0x08eb65e6, 0x7154d129), + TOBN(0x4feff589, 0x30b75c3e), TOBN(0x0bb82fe2, 0x94491c93), + TOBN(0xd8ac377a, 0x89af62bb), TOBN(0xd7b51490, 0x9685e49f), + TOBN(0xabca9a7b, 0x04497f19), TOBN(0x1b35ed0a, 0x1a7ad13f), + TOBN(0x6b601e21, 0x3ec86ed6), TOBN(0xda91fcb9, 0xce0c76f1), + TOBN(0x9e28507b, 0xd7ab27e1), TOBN(0x7c19a555, 0x63945b7b), + TOBN(0x6b43f0a1, 0xaafc9827), TOBN(0x443b4fbd, 0x3aa55b91), + TOBN(0x962b2e65, 0x6962c88f), TOBN(0x139da8d4, 0xce0db0ca), + TOBN(0xb93f05dd, 0x1b8d6c4f), TOBN(0x779cdff7, 0x180b9824), + TOBN(0xbba23fdd, 0xae57c7b7), TOBN(0x345342f2, 0x1b932522), + TOBN(0xfd9c80fe, 0x556d4aa3), TOBN(0xa03907ba, 0x6525bb61), + TOBN(0x38b010e1, 0xff218933), TOBN(0xc066b654, 0xaa52117b), + TOBN(0x8e141920, 0x94f2e6ea), TOBN(0x66a27dca, 0x0d32f2b2), + TOBN(0x69c7f993, 0x048b3717), TOBN(0xbf5a989a, 0xb178ae1c), + TOBN(0x49fa9058, 0x564f1d6b), TOBN(0x27ec6e15, 0xd31fde4e), + TOBN(0x4cce0373, 0x7276e7fc), TOBN(0x64086d79, 0x89d6bf02), + TOBN(0x5a72f046, 0x4ccdd979), TOBN(0x909c3566, 0x47775631), + TOBN(0x1c07bc6b, 0x75dd7125), TOBN(0xb4c6bc97, 0x87a0428d), + TOBN(0x507ece52, 0xfdeb6b9d), TOBN(0xfca56512, 0xb2c95432), + TOBN(0x15d97181, 0xd0e8bd06), TOBN(0x384dd317, 0xc6bb46ea), + TOBN(0x5441ea20, 0x3952b624), TOBN(0xbcf70dee, 0x4e7dc2fb), + TOBN(0x372b016e, 0x6628e8c3), TOBN(0x07a0d667, 0xb60a7522), + TOBN(0xcf05751b, 0x0a344ee2), TOBN(0x0ec09a48, 0x118bdeec), + TOBN(0x6e4b3d4e, 0xd83dce46), TOBN(0x43a6316d, 0x99d2fc6e), + TOBN(0xa99d8989, 0x56cf044c), TOBN(0x7c7f4454, 0xae3e5fb7), + TOBN(0xb2e6b121, 0xfbabbe92), TOBN(0x281850fb, 0xe1330076), + TOBN(0x093581ec, 0x97890015), TOBN(0x69b1dded, 0x75ff77f5), + TOBN(0x7cf0b18f, 0xab105105), TOBN(0x953ced31, 0xa89ccfef), + TOBN(0x3151f85f, 0xeb914009), TOBN(0x3c9f1b87, 0x88ed48ad), + TOBN(0xc9aba1a1, 0x4a7eadcb), TOBN(0x928e7501, 0x522e71cf), + TOBN(0xeaede727, 0x3a2e4f83), TOBN(0x467e10d1, 0x1ce3bbd3), + TOBN(0xf3442ac3, 0xb955dcf0), TOBN(0xba96307d, 0xd3d5e527), + TOBN(0xf763a10e, 0xfd77f474), TOBN(0x5d744bd0, 0x6a6e1ff0), + TOBN(0xd287282a, 0xa777899e), TOBN(0xe20eda8f, 0xd03f3cde), + TOBN(0x6a7e75bb, 0x50b07d31), TOBN(0x0b7e2a94, 0x6f379de4), + TOBN(0x31cb64ad, 0x19f593cf), TOBN(0x7b1a9e4f, 0x1e76ef1d), + TOBN(0xe18c9c9d, 0xb62d609c), TOBN(0x439bad6d, 0xe779a650), + TOBN(0x219d9066, 0xe032f144), TOBN(0x1db632b8, 0xe8b2ec6a), + TOBN(0xff0d0fd4, 0xfda12f78), TOBN(0x56fb4c2d, 0x2a25d265), + TOBN(0x5f4e2ee1, 0x255a03f1), TOBN(0x61cd6af2, 0xe96af176), + TOBN(0xe0317ba8, 0xd068bc97), TOBN(0x927d6bab, 0x264b988e), + TOBN(0xa18f07e0, 0xe90fb21e), TOBN(0x00fd2b80, 0xbba7fca1), + TOBN(0x20387f27, 0x95cd67b5), TOBN(0x5b89a4e7, 0xd39707f7), + TOBN(0x8f83ad3f, 0x894407ce), TOBN(0xa0025b94, 0x6c226132), + TOBN(0xc79563c7, 0xf906c13b), TOBN(0x5f548f31, 0x4e7bb025), + TOBN(0x2b4c6b8f, 0xeac6d113), TOBN(0xa67e3f9c, 0x0e813c76), + TOBN(0x3982717c, 0x3fe1f4b9), TOBN(0x58865819, 0x26d8050e), + TOBN(0x99f3640c, 0xf7f06f20), TOBN(0xdc610216, 0x2a66ebc2), + TOBN(0x52f2c175, 0x767a1e08), TOBN(0x05660e1a, 0x5999871b), + TOBN(0x6b0f1762, 0x6d3c4693), TOBN(0xf0e7d627, 0x37ed7bea), + TOBN(0xc51758c7, 0xb75b226d), TOBN(0x40a88628, 0x1f91613b), + TOBN(0x889dbaa7, 0xbbb38ce0), TOBN(0xe0404b65, 0xbddcad81), + TOBN(0xfebccd3a, 0x8bc9671f), TOBN(0xfbf9a357, 0xee1f5375), + TOBN(0x5dc169b0, 0x28f33398), TOBN(0xb07ec11d, 0x72e90f65), + TOBN(0xae7f3b4a, 0xfaab1eb1), TOBN(0xd970195e, 0x5f17538a), + TOBN(0x52b05cbe, 0x0181e640), TOBN(0xf5debd62, 0x2643313d), + TOBN(0x76148154, 0x5df31f82), TOBN(0x23e03b33, 0x3a9e13c5), + TOBN(0xff758949, 0x4fde0c1f), TOBN(0xbf8a1abe, 0xe5b6ec20), + TOBN(0x702278fb, 0x87e1db6c), TOBN(0xc447ad7a, 0x35ed658f), + TOBN(0x48d4aa38, 0x03d0ccf2), TOBN(0x80acb338, 0x819a7c03), + TOBN(0x9bc7c89e, 0x6e17cecc), TOBN(0x46736b8b, 0x03be1d82), + TOBN(0xd65d7b60, 0xc0432f96), TOBN(0xddebe7a3, 0xdeb5442f), + TOBN(0x79a25307, 0x7dff69a2), TOBN(0x37a56d94, 0x02cf3122), + TOBN(0x8bab8aed, 0xf2350d0a), TOBN(0x13c3f276, 0x037b0d9a), + TOBN(0xc664957c, 0x44c65cae), TOBN(0x88b44089, 0xc2e71a88), + TOBN(0xdb88e5a3, 0x5cb02664), TOBN(0x5d4c0bf1, 0x8686c72e), + TOBN(0xea3d9b62, 0xa682d53e), TOBN(0x9b605ef4, 0x0b2ad431), + TOBN(0x71bac202, 0xc69645d0), TOBN(0xa115f03a, 0x6a1b66e7), + TOBN(0xfe2c563a, 0x158f4dc4), TOBN(0xf715b3a0, 0x4d12a78c), + TOBN(0x8f7f0a48, 0xd413213a), TOBN(0x2035806d, 0xc04becdb), + TOBN(0xecd34a99, 0x5d8587f5), TOBN(0x4d8c3079, 0x9f6d3a71), + TOBN(0x1b2a2a67, 0x8d95a8f6), TOBN(0xc58c9d7d, 0xf2110d0d), + TOBN(0xdeee81d5, 0xcf8fba3f), TOBN(0xa42be3c0, 0x0c7cdf68), + TOBN(0x2126f742, 0xd43b5eaa), TOBN(0x054a0766, 0xdfa59b85), + TOBN(0x9d0d5e36, 0x126bfd45), TOBN(0xa1f8fbd7, 0x384f8a8f), + TOBN(0x317680f5, 0xd563fccc), TOBN(0x48ca5055, 0xf280a928), + TOBN(0xe00b81b2, 0x27b578cf), TOBN(0x10aad918, 0x2994a514), + TOBN(0xd9e07b62, 0xb7bdc953), TOBN(0x9f0f6ff2, 0x5bc086dd), + TOBN(0x09d1ccff, 0x655eee77), TOBN(0x45475f79, 0x5bef7df1), + TOBN(0x3faa28fa, 0x86f702cc), TOBN(0x92e60905, 0x0f021f07), + TOBN(0xe9e62968, 0x7f8fa8c6), TOBN(0xbd71419a, 0xf036ea2c), + TOBN(0x171ee1cc, 0x6028da9a), TOBN(0x5352fe1a, 0xc251f573), + TOBN(0xf8ff236e, 0x3fa997f4), TOBN(0xd831b6c9, 0xa5749d5f), + TOBN(0x7c872e1d, 0xe350e2c2), TOBN(0xc56240d9, 0x1e0ce403), + TOBN(0xf9deb077, 0x6974f5cb), TOBN(0x7d50ba87, 0x961c3728), + TOBN(0xd6f89426, 0x5a3a2518), TOBN(0xcf817799, 0xc6303d43), + TOBN(0x510a0471, 0x619e5696), TOBN(0xab049ff6, 0x3a5e307b), + TOBN(0xe4cdf9b0, 0xfeb13ec7), TOBN(0xd5e97117, 0x9d8ff90c), + TOBN(0xf6f64d06, 0x9afa96af), TOBN(0x00d0bf5e, 0x9d2012a2), + TOBN(0xe63f301f, 0x358bcdc0), TOBN(0x07689e99, 0x0a9d47f8), + TOBN(0x1f689e2f, 0x4f43d43a), TOBN(0x4d542a16, 0x90920904), + TOBN(0xaea293d5, 0x9ca0a707), TOBN(0xd061fe45, 0x8ac68065), + TOBN(0x1033bf1b, 0x0090008c), TOBN(0x29749558, 0xc08a6db6), + TOBN(0x74b5fc59, 0xc1d5d034), TOBN(0xf712e9f6, 0x67e215e0), + TOBN(0xfd520cbd, 0x860200e6), TOBN(0x0229acb4, 0x3ea22588), + TOBN(0x9cd1e14c, 0xfff0c82e), TOBN(0x87684b62, 0x59c69e73), + TOBN(0xda85e61c, 0x96ccb989), TOBN(0x2d5dbb02, 0xa3d06493), + TOBN(0xf22ad33a, 0xe86b173c), TOBN(0xe8e41ea5, 0xa79ff0e3), + TOBN(0x01d2d725, 0xdd0d0c10), TOBN(0x31f39088, 0x032d28f9), + TOBN(0x7b3f71e1, 0x7829839e), TOBN(0x0cf691b4, 0x4502ae58), + TOBN(0xef658dbd, 0xbefc6115), TOBN(0xa5cd6ee5, 0xb3ab5314), + TOBN(0x206c8d7b, 0x5f1d2347), TOBN(0x794645ba, 0x4cc2253a), + TOBN(0xd517d8ff, 0x58389e08), TOBN(0x4fa20dee, 0x9f847288), + TOBN(0xeba072d8, 0xd797770a), TOBN(0x7360c91d, 0xbf429e26), + TOBN(0x7200a3b3, 0x80af8279), TOBN(0x6a1c9150, 0x82dadce3), + TOBN(0x0ee6d3a7, 0xc35d8794), TOBN(0x042e6558, 0x0356bae5), + TOBN(0x9f59698d, 0x643322fd), TOBN(0x9379ae15, 0x50a61967), + TOBN(0x64b9ae62, 0xfcc9981e), TOBN(0xaed3d631, 0x6d2934c6), + TOBN(0x2454b302, 0x5e4e65eb), TOBN(0xab09f647, 0xf9950428)}, + {TOBN(0xb2083a12, 0x22248acc), TOBN(0x1f6ec0ef, 0x3264e366), + TOBN(0x5659b704, 0x5afdee28), TOBN(0x7a823a40, 0xe6430bb5), + TOBN(0x24592a04, 0xe1900a79), TOBN(0xcde09d4a, 0xc9ee6576), + TOBN(0x52b6463f, 0x4b5ea54a), TOBN(0x1efe9ed3, 0xd3ca65a7), + TOBN(0xe27a6dbe, 0x305406dd), TOBN(0x8eb7dc7f, 0xdd5d1957), + TOBN(0xf54a6876, 0x387d4d8f), TOBN(0x9c479409, 0xc7762de4), + TOBN(0xbe4d5b5d, 0x99b30778), TOBN(0x25380c56, 0x6e793682), + TOBN(0x602d37f3, 0xdac740e3), TOBN(0x140deabe, 0x1566e4ae), + TOBN(0x4481d067, 0xafd32acf), TOBN(0xd8f0fcca, 0xe1f71ccf), + TOBN(0xd208dd0c, 0xb596f2da), TOBN(0xd049d730, 0x9aad93f9), + TOBN(0xc79f263d, 0x42ab580e), TOBN(0x09411bb1, 0x23f707b4), + TOBN(0x8cfde1ff, 0x835e0eda), TOBN(0x72707490, 0x90f03402), + TOBN(0xeaee6126, 0xc49a861e), TOBN(0x024f3b65, 0xe14f0d06), + TOBN(0x51a3f1e8, 0xc69bfc17), TOBN(0xc3c3a8e9, 0xa7686381), + TOBN(0x3400752c, 0xb103d4c8), TOBN(0x02bc4613, 0x9218b36b), + TOBN(0xc67f75eb, 0x7651504a), TOBN(0xd6848b56, 0xd02aebfa), + TOBN(0xbd9802e6, 0xc30fa92b), TOBN(0x5a70d96d, 0x9a552784), + TOBN(0x9085c4ea, 0x3f83169b), TOBN(0xfa9423bb, 0x06908228), + TOBN(0x2ffebe12, 0xfe97a5b9), TOBN(0x85da6049, 0x71b99118), + TOBN(0x9cbc2f7f, 0x63178846), TOBN(0xfd96bc70, 0x9153218e), + TOBN(0x958381db, 0x1782269b), TOBN(0xae34bf79, 0x2597e550), + TOBN(0xbb5c6064, 0x5f385153), TOBN(0x6f0e96af, 0xe3088048), + TOBN(0xbf6a0215, 0x77884456), TOBN(0xb3b5688c, 0x69310ea7), + TOBN(0x17c94295, 0x04fad2de), TOBN(0xe020f0e5, 0x17896d4d), + TOBN(0x730ba0ab, 0x0976505f), TOBN(0x567f6813, 0x095e2ec5), + TOBN(0x47062010, 0x6331ab71), TOBN(0x72cfa977, 0x41d22b9f), + TOBN(0x33e55ead, 0x8a2373da), TOBN(0xa8d0d5f4, 0x7ba45a68), + TOBN(0xba1d8f9c, 0x03029d15), TOBN(0x8f34f1cc, 0xfc55b9f3), + TOBN(0xcca4428d, 0xbbe5a1a9), TOBN(0x8187fd5f, 0x3126bd67), + TOBN(0x0036973a, 0x48105826), TOBN(0xa39b6663, 0xb8bd61a0), + TOBN(0x6d42deef, 0x2d65a808), TOBN(0x4969044f, 0x94636b19), + TOBN(0xf611ee47, 0xdd5d564c), TOBN(0x7b2f3a49, 0xd2873077), + TOBN(0x94157d45, 0x300eb294), TOBN(0x2b2a656e, 0x169c1494), + TOBN(0xc000dd76, 0xd3a47aa9), TOBN(0xa2864e4f, 0xa6243ea4), + TOBN(0x82716c47, 0xdb89842e), TOBN(0x12dfd7d7, 0x61479fb7), + TOBN(0x3b9a2c56, 0xe0b2f6dc), TOBN(0x46be862a, 0xd7f85d67), + TOBN(0x03b0d8dd, 0x0f82b214), TOBN(0x460c34f9, 0xf103cbc6), + TOBN(0xf32e5c03, 0x18d79e19), TOBN(0x8b8888ba, 0xa84117f8), + TOBN(0x8f3c37dc, 0xc0722677), TOBN(0x10d21be9, 0x1c1c0f27), + TOBN(0xd47c8468, 0xe0f7a0c6), TOBN(0x9bf02213, 0xadecc0e0), + TOBN(0x0baa7d12, 0x42b48b99), TOBN(0x1bcb665d, 0x48424096), + TOBN(0x8b847cd6, 0xebfb5cfb), TOBN(0x87c2ae56, 0x9ad4d10d), + TOBN(0xf1cbb122, 0x0de36726), TOBN(0xe7043c68, 0x3fdfbd21), + TOBN(0x4bd0826a, 0x4e79d460), TOBN(0x11f5e598, 0x4bd1a2cb), + TOBN(0x97554160, 0xb7fe7b6e), TOBN(0x7d16189a, 0x400a3fb2), + TOBN(0xd73e9bea, 0xe328ca1e), TOBN(0x0dd04b97, 0xe793d8cc), + TOBN(0xa9c83c9b, 0x506db8cc), TOBN(0x5cd47aae, 0xcf38814c), + TOBN(0x26fc430d, 0xb64b45e6), TOBN(0x079b5499, 0xd818ea84), + TOBN(0xebb01102, 0xc1c24a3b), TOBN(0xca24e568, 0x1c161c1a), + TOBN(0x103eea69, 0x36f00a4a), TOBN(0x9ad76ee8, 0x76176c7b), + TOBN(0x97451fc2, 0x538e0ff7), TOBN(0x94f89809, 0x6604b3b0), + TOBN(0x6311436e, 0x3249cfd7), TOBN(0x27b4a7bd, 0x41224f69), + TOBN(0x03b5d21a, 0xe0ac2941), TOBN(0x279b0254, 0xc2d31937), + TOBN(0x3307c052, 0xcac992d0), TOBN(0x6aa7cb92, 0xefa8b1f3), + TOBN(0x5a182580, 0x0d37c7a5), TOBN(0x13380c37, 0x342d5422), + TOBN(0x92ac2d66, 0xd5d2ef92), TOBN(0x035a70c9, 0x030c63c6), + TOBN(0xc16025dd, 0x4ce4f152), TOBN(0x1f419a71, 0xf9df7c06), + TOBN(0x6d5b2214, 0x91e4bb14), TOBN(0xfc43c6cc, 0x839fb4ce), + TOBN(0x49f06591, 0x925d6b2d), TOBN(0x4b37d9d3, 0x62186598), + TOBN(0x8c54a971, 0xd01b1629), TOBN(0xe1a9c29f, 0x51d50e05), + TOBN(0x5109b785, 0x71ba1861), TOBN(0x48b22d5c, 0xd0c8f93d), + TOBN(0xe8fa84a7, 0x8633bb93), TOBN(0x53fba6ba, 0x5aebbd08), + TOBN(0x7ff27df3, 0xe5eea7d8), TOBN(0x521c8796, 0x68ca7158), + TOBN(0xb9d5133b, 0xce6f1a05), TOBN(0x2d50cd53, 0xfd0ebee4), + TOBN(0xc82115d6, 0xc5a3ef16), TOBN(0x993eff9d, 0xba079221), + TOBN(0xe4da2c5e, 0x4b5da81c), TOBN(0x9a89dbdb, 0x8033fd85), + TOBN(0x60819ebf, 0x2b892891), TOBN(0x53902b21, 0x5d14a4d5), + TOBN(0x6ac35051, 0xd7fda421), TOBN(0xcc6ab885, 0x61c83284), + TOBN(0x14eba133, 0xf74cff17), TOBN(0x240aaa03, 0xecb813f2), + TOBN(0xcfbb6540, 0x6f665bee), TOBN(0x084b1fe4, 0xa425ad73), + TOBN(0x009d5d16, 0xd081f6a6), TOBN(0x35304fe8, 0xeef82c90), + TOBN(0xf20346d5, 0xaa9eaa22), TOBN(0x0ada9f07, 0xac1c91e3), + TOBN(0xa6e21678, 0x968a6144), TOBN(0x54c1f77c, 0x07b31a1e), + TOBN(0xd6bb787e, 0x5781fbe1), TOBN(0x61bd2ee0, 0xe31f1c4a), + TOBN(0xf25aa1e9, 0x781105fc), TOBN(0x9cf2971f, 0x7b2f8e80), + TOBN(0x26d15412, 0xcdff919b), TOBN(0x01db4ebe, 0x34bc896e), + TOBN(0x7d9b3e23, 0xb40df1cf), TOBN(0x59337373, 0x94e971b4), + TOBN(0xbf57bd14, 0x669cf921), TOBN(0x865daedf, 0x0c1a1064), + TOBN(0x3eb70bd3, 0x83279125), TOBN(0xbc3d5b9f, 0x34ecdaab), + TOBN(0x91e3ed7e, 0x5f755caf), TOBN(0x49699f54, 0xd41e6f02), + TOBN(0x185770e1, 0xd4a7a15b), TOBN(0x08f3587a, 0xeaac87e7), + TOBN(0x352018db, 0x473133ea), TOBN(0x674ce719, 0x04fd30fc), + TOBN(0x7b8d9835, 0x088b3e0e), TOBN(0x7a0356a9, 0x5d0d47a1), + TOBN(0x9d9e7659, 0x6474a3c4), TOBN(0x61ea48a7, 0xff66966c), + TOBN(0x30417758, 0x0f3e4834), TOBN(0xfdbb21c2, 0x17a9afcb), + TOBN(0x756fa17f, 0x2f9a67b3), TOBN(0x2a6b2421, 0xa245c1a8), + TOBN(0x64be2794, 0x4af02291), TOBN(0xade465c6, 0x2a5804fe), + TOBN(0x8dffbd39, 0xa6f08fd7), TOBN(0xc4efa84c, 0xaa14403b), + TOBN(0xa1b91b2a, 0x442b0f5c), TOBN(0xb748e317, 0xcf997736), + TOBN(0x8d1b62bf, 0xcee90e16), TOBN(0x907ae271, 0x0b2078c0), + TOBN(0xdf31534b, 0x0c9bcddd), TOBN(0x043fb054, 0x39adce83), + TOBN(0x99031043, 0xd826846a), TOBN(0x61a9c0d6, 0xb144f393), + TOBN(0xdab48046, 0x47718427), TOBN(0xdf17ff9b, 0x6e830f8b), + TOBN(0x408d7ee8, 0xe49a1347), TOBN(0x6ac71e23, 0x91c1d4ae), + TOBN(0xc8cbb9fd, 0x1defd73c), TOBN(0x19840657, 0xbbbbfec5), + TOBN(0x39db1cb5, 0x9e7ef8ea), TOBN(0x78aa8296, 0x64105f30), + TOBN(0xa3d9b7f0, 0xa3738c29), TOBN(0x0a2f235a, 0xbc3250a3), + TOBN(0x55e506f6, 0x445e4caf), TOBN(0x0974f73d, 0x33475f7a), + TOBN(0xd37dbba3, 0x5ba2f5a8), TOBN(0x542c6e63, 0x6af40066), + TOBN(0x26d99b53, 0xc5d73e2c), TOBN(0x06060d7d, 0x6c3ca33e), + TOBN(0xcdbef1c2, 0x065fef4a), TOBN(0x77e60f7d, 0xfd5b92e3), + TOBN(0xd7c549f0, 0x26708350), TOBN(0x201b3ad0, 0x34f121bf), + TOBN(0x5fcac2a1, 0x0334fc14), TOBN(0x8a9a9e09, 0x344552f6), + TOBN(0x7dd8a1d3, 0x97653082), TOBN(0x5fc0738f, 0x79d4f289), + TOBN(0x787d244d, 0x17d2d8c3), TOBN(0xeffc6345, 0x70830684), + TOBN(0x5ddb96dd, 0xe4f73ae5), TOBN(0x8efb14b1, 0x172549a5), + TOBN(0x6eb73eee, 0x2245ae7a), TOBN(0xbca4061e, 0xea11f13e), + TOBN(0xb577421d, 0x30b01f5d), TOBN(0xaa688b24, 0x782e152c), + TOBN(0x67608e71, 0xbd3502ba), TOBN(0x4ef41f24, 0xb4de75a0), + TOBN(0xb08dde5e, 0xfd6125e5), TOBN(0xde484825, 0xa409543f), + TOBN(0x1f198d98, 0x65cc2295), TOBN(0x428a3771, 0x6e0edfa2), + TOBN(0x4f9697a2, 0xadf35fc7), TOBN(0x01a43c79, 0xf7cac3c7), + TOBN(0xb05d7059, 0x0fd3659a), TOBN(0x8927f30c, 0xbb7f2d9a), + TOBN(0x4023d1ac, 0x8cf984d3), TOBN(0x32125ed3, 0x02897a45), + TOBN(0xfb572dad, 0x3d414205), TOBN(0x73000ef2, 0xe3fa82a9), + TOBN(0x4c0868e9, 0xf10a5581), TOBN(0x5b61fc67, 0x6b0b3ca5), + TOBN(0xc1258d5b, 0x7cae440c), TOBN(0x21c08b41, 0x402b7531), + TOBN(0xf61a8955, 0xde932321), TOBN(0x3568faf8, 0x2d1408af), + TOBN(0x71b15e99, 0x9ecf965b), TOBN(0xf14ed248, 0xe917276f), + TOBN(0xc6f4caa1, 0x820cf9e2), TOBN(0x681b20b2, 0x18d83c7e), + TOBN(0x6cde738d, 0xc6c01120), TOBN(0x71db0813, 0xae70e0db), + TOBN(0x95fc0644, 0x74afe18c), TOBN(0x34619053, 0x129e2be7), + TOBN(0x80615cea, 0xdb2a3b15), TOBN(0x0a49a19e, 0xdb4c7073), + TOBN(0x0e1b84c8, 0x8fd2d367), TOBN(0xd74bf462, 0x033fb8aa), + TOBN(0x889f6d65, 0x533ef217), TOBN(0x7158c7e4, 0xc3ca2e87), + TOBN(0xfb670dfb, 0xdc2b4167), TOBN(0x75910a01, 0x844c257f), + TOBN(0xf336bf07, 0xcf88577d), TOBN(0x22245250, 0xe45e2ace), + TOBN(0x2ed92e8d, 0x7ca23d85), TOBN(0x29f8be4c, 0x2b812f58), + TOBN(0xdd9ebaa7, 0x076fe12b), TOBN(0x3f2400cb, 0xae1537f9), + TOBN(0x1aa93528, 0x17bdfb46), TOBN(0xc0f98430, 0x67883b41), + TOBN(0x5590ede1, 0x0170911d), TOBN(0x7562f5bb, 0x34d4b17f), + TOBN(0xe1fa1df2, 0x1826b8d2), TOBN(0xb40b796a, 0x6bd80d59), + TOBN(0xd65bf197, 0x3467ba92), TOBN(0x8c9b46db, 0xf70954b0), + TOBN(0x97c8a0f3, 0x0e78f15d), TOBN(0xa8f3a69a, 0x85a4c961), + TOBN(0x4242660f, 0x61e4ce9b), TOBN(0xbf06aab3, 0x6ea6790c), + TOBN(0xc6706f8e, 0xec986416), TOBN(0x9e56dec1, 0x9a9fc225), + TOBN(0x527c46f4, 0x9a9898d9), TOBN(0xd799e77b, 0x5633cdef), + TOBN(0x24eacc16, 0x7d9e4297), TOBN(0xabb61cea, 0x6b1cb734), + TOBN(0xbee2e8a7, 0xf778443c), TOBN(0x3bb42bf1, 0x29de2fe6), + TOBN(0xcbed86a1, 0x3003bb6f), TOBN(0xd3918e6c, 0xd781cdf6), + TOBN(0x4bee3271, 0x9a5103f1), TOBN(0x5243efc6, 0xf50eac06), + TOBN(0xb8e122cb, 0x6adcc119), TOBN(0x1b7faa84, 0xc0b80a08), + TOBN(0x32c3d1bd, 0x6dfcd08c), TOBN(0x129dec4e, 0x0be427de), + TOBN(0x98ab679c, 0x1d263c83), TOBN(0xafc83cb7, 0xcef64eff), + TOBN(0x85eb6088, 0x2fa6be76), TOBN(0x892585fb, 0x1328cbfe), + TOBN(0xc154d3ed, 0xcf618dda), TOBN(0xc44f601b, 0x3abaf26e), + TOBN(0x7bf57d0b, 0x2be1fdfd), TOBN(0xa833bd2d, 0x21137fee), + TOBN(0x9353af36, 0x2db591a8), TOBN(0xc76f26dc, 0x5562a056), + TOBN(0x1d87e47d, 0x3fdf5a51), TOBN(0x7afb5f93, 0x55c9cab0), + TOBN(0x91bbf58f, 0x89e0586e), TOBN(0x7c72c018, 0x0d843709), + TOBN(0xa9a5aafb, 0x99b5c3dc), TOBN(0xa48a0f1d, 0x3844aeb0), + TOBN(0x7178b7dd, 0xb667e482), TOBN(0x453985e9, 0x6e23a59a), + TOBN(0x4a54c860, 0x01b25dd8), TOBN(0x0dd37f48, 0xfb897c8a), + TOBN(0x5f8aa610, 0x0ea90cd9), TOBN(0xc8892c68, 0x16d5830d), + TOBN(0xeb4befc0, 0xef514ca5), TOBN(0x478eb679, 0xe72c9ee6), + TOBN(0x9bca20da, 0xdbc40d5f), TOBN(0xf015de21, 0xdde4f64a), + TOBN(0xaa6a4de0, 0xeaf4b8a5), TOBN(0x68cfd9ca, 0x4bc60e32), + TOBN(0x668a4b01, 0x7fd15e70), TOBN(0xd9f0694a, 0xf27dc09d), + TOBN(0xf6c3cad5, 0xba708bcd), TOBN(0x5cd2ba69, 0x5bb95c2a), + TOBN(0xaa28c1d3, 0x33c0a58f), TOBN(0x23e274e3, 0xabc77870), + TOBN(0x44c3692d, 0xdfd20a4a), TOBN(0x091c5fd3, 0x81a66653), + TOBN(0x6c0bb691, 0x09a0757d), TOBN(0x9072e8b9, 0x667343ea), + TOBN(0x31d40eb0, 0x80848bec), TOBN(0x95bd480a, 0x79fd36cc), + TOBN(0x01a77c61, 0x65ed43f5), TOBN(0xafccd127, 0x2e0d40bf), + TOBN(0xeccfc82d, 0x1cc1884b), TOBN(0xc85ac201, 0x5d4753b4), + TOBN(0xc7a6caac, 0x658e099f), TOBN(0xcf46369e, 0x04b27390), + TOBN(0xe2e7d049, 0x506467ea), TOBN(0x481b63a2, 0x37cdeccc), + TOBN(0x4029abd8, 0xed80143a), TOBN(0x28bfe3c7, 0xbcb00b88), + TOBN(0x3bec1009, 0x0643d84a), TOBN(0x885f3668, 0xabd11041), + TOBN(0xdb02432c, 0xf83a34d6), TOBN(0x32f7b360, 0x719ceebe), + TOBN(0xf06c7837, 0xdad1fe7a), TOBN(0x60a157a9, 0x5441a0b0), + TOBN(0x704970e9, 0xe2d47550), TOBN(0xcd2bd553, 0x271b9020), + TOBN(0xff57f82f, 0x33e24a0b), TOBN(0x9cbee23f, 0xf2565079), + TOBN(0x16353427, 0xeb5f5825), TOBN(0x276feec4, 0xe948d662), + TOBN(0xd1b62bc6, 0xda10032b), TOBN(0x718351dd, 0xf0e72a53), + TOBN(0x93452076, 0x2420e7ba), TOBN(0x96368fff, 0x3a00118d), + TOBN(0x00ce2d26, 0x150a49e4), TOBN(0x0c28b636, 0x3f04706b), + TOBN(0xbad65a46, 0x58b196d0), TOBN(0x6c8455fc, 0xec9f8b7c), + TOBN(0xe90c895f, 0x2d71867e), TOBN(0x5c0be31b, 0xedf9f38c), + TOBN(0x2a37a15e, 0xd8f6ec04), TOBN(0x239639e7, 0x8cd85251), + TOBN(0xd8975315, 0x9c7c4c6b), TOBN(0x603aa3c0, 0xd7409af7), + TOBN(0xb8d53d0c, 0x007132fb), TOBN(0x68d12af7, 0xa6849238), + TOBN(0xbe0607e7, 0xbf5d9279), TOBN(0x9aa50055, 0xaada74ce), + TOBN(0xe81079cb, 0xba7e8ccb), TOBN(0x610c71d1, 0xa5f4ff5e), + TOBN(0x9e2ee1a7, 0x5aa07093), TOBN(0xca84004b, 0xa75da47c), + TOBN(0x074d3951, 0x3de75401), TOBN(0xf938f756, 0xbb311592), + TOBN(0x96197618, 0x00a43421), TOBN(0x39a25362, 0x07bc78c8), + TOBN(0x278f710a, 0x0a171276), TOBN(0xb28446ea, 0x8d1a8f08), + TOBN(0x184781bf, 0xe3b6a661), TOBN(0x7751cb1d, 0xe6d279f7), + TOBN(0xf8ff95d6, 0xc59eb662), TOBN(0x186d90b7, 0x58d3dea7), + TOBN(0x0e4bb6c1, 0xdfb4f754), TOBN(0x5c5cf56b, 0x2b2801dc), + TOBN(0xc561e452, 0x1f54564d), TOBN(0xb4fb8c60, 0xf0dd7f13), + TOBN(0xf8849630, 0x33ff98c7), TOBN(0x9619fffa, 0xcf17769c), + TOBN(0xf8090bf6, 0x1bfdd80a), TOBN(0x14d9a149, 0x422cfe63), + TOBN(0xb354c360, 0x6f6df9ea), TOBN(0xdbcf770d, 0x218f17ea), + TOBN(0x207db7c8, 0x79eb3480), TOBN(0x213dbda8, 0x559b6a26), + TOBN(0xac4c200b, 0x29fc81b3), TOBN(0xebc3e09f, 0x171d87c1), + TOBN(0x91799530, 0x1481aa9e), TOBN(0x051b92e1, 0x92e114fa), + TOBN(0xdf8f92e9, 0xecb5537f), TOBN(0x44b1b2cc, 0x290c7483), + TOBN(0xa711455a, 0x2adeb016), TOBN(0x964b6856, 0x81a10c2c), + TOBN(0x4f159d99, 0xcec03623), TOBN(0x05532225, 0xef3271ea), + TOBN(0xb231bea3, 0xc5ee4849), TOBN(0x57a54f50, 0x7094f103), + TOBN(0x3e2d421d, 0x9598b352), TOBN(0xe865a49c, 0x67412ab4), + TOBN(0xd2998a25, 0x1cc3a912), TOBN(0x5d092808, 0x0c74d65d), + TOBN(0x73f45908, 0x4088567a), TOBN(0xeb6b280e, 0x1f214a61), + TOBN(0x8c9adc34, 0xcaf0c13d), TOBN(0x39d12938, 0xf561fb80), + TOBN(0xb2dc3a5e, 0xbc6edfb4), TOBN(0x7485b1b1, 0xfe4d210e), + TOBN(0x062e0400, 0xe186ae72), TOBN(0x91e32d5c, 0x6eeb3b88), + TOBN(0x6df574d7, 0x4be59224), TOBN(0xebc88ccc, 0x716d55f3), + TOBN(0x26c2e6d0, 0xcad6ed33), TOBN(0xc6e21e7d, 0x0d3e8b10), + TOBN(0x2cc5840e, 0x5bcc36bb), TOBN(0x9292445e, 0x7da74f69), + TOBN(0x8be8d321, 0x4e5193a8), TOBN(0x3ec23629, 0x8df06413), + TOBN(0xc7e9ae85, 0xb134defa), TOBN(0x6073b1d0, 0x1bb2d475), + TOBN(0xb9ad615e, 0x2863c00d), TOBN(0x9e29493d, 0x525f4ac4), + TOBN(0xc32b1dea, 0x4e9acf4f), TOBN(0x3e1f01c8, 0xa50db88d), + TOBN(0xb05d70ea, 0x04da916c), TOBN(0x714b0d0a, 0xd865803e), + TOBN(0x4bd493fc, 0x9920cb5e), TOBN(0x5b44b1f7, 0x92c7a3ac), + TOBN(0xa2a77293, 0xbcec9235), TOBN(0x5ee06e87, 0xcd378553), + TOBN(0xceff8173, 0xda621607), TOBN(0x2bb03e4c, 0x99f5d290), + TOBN(0x2945106a, 0xa6f734ac), TOBN(0xb5056604, 0xd25c4732), + TOBN(0x5945920c, 0xe079afee), TOBN(0x686e17a0, 0x6789831f), + TOBN(0x5966bee8, 0xb74a5ae5), TOBN(0x38a673a2, 0x1e258d46), + TOBN(0xbd1cc1f2, 0x83141c95), TOBN(0x3b2ecf4f, 0x0e96e486), + TOBN(0xcd3aa896, 0x74e5fc78), TOBN(0x415ec10c, 0x2482fa7a), + TOBN(0x15234419, 0x80503380), TOBN(0x513d917a, 0xd314b392), + TOBN(0xb0b52f4e, 0x63caecae), TOBN(0x07bf22ad, 0x2dc7780b), + TOBN(0xe761e8a1, 0xe4306839), TOBN(0x1b3be962, 0x5dd7feaa), + TOBN(0x4fe728de, 0x74c778f1), TOBN(0xf1fa0bda, 0x5e0070f6), + TOBN(0x85205a31, 0x6ec3f510), TOBN(0x2c7e4a14, 0xd2980475), + TOBN(0xde3c19c0, 0x6f30ebfd), TOBN(0xdb1c1f38, 0xd4b7e644), + TOBN(0xfe291a75, 0x5dce364a), TOBN(0xb7b22a3c, 0x058f5be3), + TOBN(0x2cd2c302, 0x37fea38c), TOBN(0x2930967a, 0x2e17be17), + TOBN(0x87f009de, 0x0c061c65), TOBN(0xcb014aac, 0xedc6ed44), + TOBN(0x49bd1cb4, 0x3bafb1eb), TOBN(0x81bd8b5c, 0x282d3688), + TOBN(0x1cdab87e, 0xf01a17af), TOBN(0x21f37ac4, 0xe710063b), + TOBN(0x5a6c5676, 0x42fc8193), TOBN(0xf4753e70, 0x56a6015c), + TOBN(0x020f795e, 0xa15b0a44), TOBN(0x8f37c8d7, 0x8958a958), + TOBN(0x63b7e89b, 0xa4b675b5), TOBN(0xb4fb0c0c, 0x0fc31aea), + TOBN(0xed95e639, 0xa7ff1f2e), TOBN(0x9880f5a3, 0x619614fb), + TOBN(0xdeb6ff02, 0x947151ab), TOBN(0x5bc5118c, 0xa868dcdb), + TOBN(0xd8da2055, 0x4c20cea5), TOBN(0xcac2776e, 0x14c4d69a), + TOBN(0xcccb22c1, 0x622d599b), TOBN(0xa4ddb653, 0x68a9bb50), + TOBN(0x2c4ff151, 0x1b4941b4), TOBN(0xe1ff19b4, 0x6efba588), + TOBN(0x35034363, 0xc48345e0), TOBN(0x45542e3d, 0x1e29dfc4), + TOBN(0xf197cb91, 0x349f7aed), TOBN(0x3b2b5a00, 0x8fca8420), + TOBN(0x7c175ee8, 0x23aaf6d8), TOBN(0x54dcf421, 0x35af32b6), + TOBN(0x0ba14307, 0x27d6561e), TOBN(0x879d5ee4, 0xd175b1e2), + TOBN(0xc7c43673, 0x99807db5), TOBN(0x77a54455, 0x9cd55bcd), + TOBN(0xe6c2ff13, 0x0105c072), TOBN(0x18f7a99f, 0x8dda7da4), + TOBN(0x4c301820, 0x0e2d35c1), TOBN(0x06a53ca0, 0xd9cc6c82), + TOBN(0xaa21cc1e, 0xf1aa1d9e), TOBN(0x32414334, 0x4a75b1e8), + TOBN(0x2a6d1328, 0x0ebe9fdc), TOBN(0x16bd173f, 0x98a4755a), + TOBN(0xfbb9b245, 0x2133ffd9), TOBN(0x39a8b2f1, 0x830f1a20), + TOBN(0x484bc97d, 0xd5a1f52a), TOBN(0xd6aebf56, 0xa40eddf8), + TOBN(0x32257acb, 0x76ccdac6), TOBN(0xaf4d36ec, 0x1586ff27), + TOBN(0x8eaa8863, 0xf8de7dd1), TOBN(0x0045d5cf, 0x88647c16)}, + {TOBN(0xa6f3d574, 0xc005979d), TOBN(0xc2072b42, 0x6a40e350), + TOBN(0xfca5c156, 0x8de2ecf9), TOBN(0xa8c8bf5b, 0xa515344e), + TOBN(0x97aee555, 0x114df14a), TOBN(0xd4374a4d, 0xfdc5ec6b), + TOBN(0x754cc28f, 0x2ca85418), TOBN(0x71cb9e27, 0xd3c41f78), + TOBN(0x89105079, 0x03605c39), TOBN(0xf0843d9e, 0xa142c96c), + TOBN(0xf3744934, 0x16923684), TOBN(0x732caa2f, 0xfa0a2893), + TOBN(0xb2e8c270, 0x61160170), TOBN(0xc32788cc, 0x437fbaa3), + TOBN(0x39cd818e, 0xa6eda3ac), TOBN(0xe2e94239, 0x9e2b2e07), + TOBN(0x6967d39b, 0x0260e52a), TOBN(0xd42585cc, 0x90653325), + TOBN(0x0d9bd605, 0x21ca7954), TOBN(0x4fa20877, 0x81ed57b3), + TOBN(0x60c1eff8, 0xe34a0bbe), TOBN(0x56b0040c, 0x84f6ef64), + TOBN(0x28be2b24, 0xb1af8483), TOBN(0xb2278163, 0xf5531614), + TOBN(0x8df27545, 0x5922ac1c), TOBN(0xa7b3ef5c, 0xa52b3f63), + TOBN(0x8e77b214, 0x71de57c4), TOBN(0x31682c10, 0x834c008b), + TOBN(0xc76824f0, 0x4bd55d31), TOBN(0xb6d1c086, 0x17b61c71), + TOBN(0x31db0903, 0xc2a5089d), TOBN(0x9c092172, 0x184e5d3f), + TOBN(0xdd7ced5b, 0xc00cc638), TOBN(0x1a2015eb, 0x61278fc2), + TOBN(0x2e8e5288, 0x6a37f8d6), TOBN(0xc457786f, 0xe79933ad), + TOBN(0xb3fe4cce, 0x2c51211a), TOBN(0xad9b10b2, 0x24c20498), + TOBN(0x90d87a4f, 0xd28db5e5), TOBN(0x698cd105, 0x3aca2fc3), + TOBN(0x4f112d07, 0xe91b536d), TOBN(0xceb982f2, 0x9eba09d6), + TOBN(0x3c157b2c, 0x197c396f), TOBN(0xe23c2d41, 0x7b66eb24), + TOBN(0x480c57d9, 0x3f330d37), TOBN(0xb3a4c8a1, 0x79108deb), + TOBN(0x702388de, 0xcb199ce5), TOBN(0x0b019211, 0xb944a8d4), + TOBN(0x24f2a692, 0x840bb336), TOBN(0x7c353bdc, 0xa669fa7b), + TOBN(0xda20d6fc, 0xdec9c300), TOBN(0x625fbe2f, 0xa13a4f17), + TOBN(0xa2b1b61a, 0xdbc17328), TOBN(0x008965bf, 0xa9515621), + TOBN(0x49690939, 0xc620ff46), TOBN(0x182dd27d, 0x8717e91c), + TOBN(0x5ace5035, 0xea6c3997), TOBN(0x54259aaa, 0xc2610bef), + TOBN(0xef18bb3f, 0x3c80dd39), TOBN(0x6910b95b, 0x5fc3fa39), + TOBN(0xfce2f510, 0x43e09aee), TOBN(0xced56c9f, 0xa7675665), + TOBN(0x10e265ac, 0xd872db61), TOBN(0x6982812e, 0xae9fce69), + TOBN(0x29be11c6, 0xce800998), TOBN(0x72bb1752, 0xb90360d9), + TOBN(0x2c193197, 0x5a4ad590), TOBN(0x2ba2f548, 0x9fc1dbc0), + TOBN(0x7fe4eebb, 0xe490ebe0), TOBN(0x12a0a4cd, 0x7fae11c0), + TOBN(0x7197cf81, 0xe903ba37), TOBN(0xcf7d4aa8, 0xde1c6dd8), + TOBN(0x92af6bf4, 0x3fd5684c), TOBN(0x2b26eecf, 0x80360aa1), + TOBN(0xbd960f30, 0x00546a82), TOBN(0x407b3c43, 0xf59ad8fe), + TOBN(0x86cae5fe, 0x249c82ba), TOBN(0x9e0faec7, 0x2463744c), + TOBN(0x87f551e8, 0x94916272), TOBN(0x033f9344, 0x6ceb0615), + TOBN(0x1e5eb0d1, 0x8be82e84), TOBN(0x89967f0e, 0x7a582fef), + TOBN(0xbcf687d5, 0xa6e921fa), TOBN(0xdfee4cf3, 0xd37a09ba), + TOBN(0x94f06965, 0xb493c465), TOBN(0x638b9a1c, 0x7635c030), + TOBN(0x76667864, 0x66f05e9f), TOBN(0xccaf6808, 0xc04da725), + TOBN(0xca2eb690, 0x768fccfc), TOBN(0xf402d37d, 0xb835b362), + TOBN(0x0efac0d0, 0xe2fdfcce), TOBN(0xefc9cdef, 0xb638d990), + TOBN(0x2af12b72, 0xd1669a8b), TOBN(0x33c536bc, 0x5774ccbd), + TOBN(0x30b21909, 0xfb34870e), TOBN(0xc38fa2f7, 0x7df25aca), + TOBN(0x74c5f02b, 0xbf81f3f5), TOBN(0x0525a5ae, 0xaf7e4581), + TOBN(0x88d2aaba, 0x433c54ae), TOBN(0xed9775db, 0x806a56c5), + TOBN(0xd320738a, 0xc0edb37d), TOBN(0x25fdb6ee, 0x66cc1f51), + TOBN(0xac661d17, 0x10600d76), TOBN(0x931ec1f3, 0xbdd1ed76), + TOBN(0x65c11d62, 0x19ee43f1), TOBN(0x5cd57c3e, 0x60829d97), + TOBN(0xd26c91a3, 0x984be6e8), TOBN(0xf08d9309, 0x8b0c53bd), + TOBN(0x94bc9e5b, 0xc016e4ea), TOBN(0xd3916839, 0x11d43d2b), + TOBN(0x886c5ad7, 0x73701155), TOBN(0xe0377626, 0x20b00715), + TOBN(0x7f01c9ec, 0xaa80ba59), TOBN(0x3083411a, 0x68538e51), + TOBN(0x970370f1, 0xe88128af), TOBN(0x625cc3db, 0x91dec14b), + TOBN(0xfef9666c, 0x01ac3107), TOBN(0xb2a8d577, 0xd5057ac3), + TOBN(0xb0f26299, 0x92be5df7), TOBN(0xf579c8e5, 0x00353924), + TOBN(0xb8fa3d93, 0x1341ed7a), TOBN(0x4223272c, 0xa7b59d49), + TOBN(0x3dcb1947, 0x83b8c4a4), TOBN(0x4e413c01, 0xed1302e4), + TOBN(0x6d999127, 0xe17e44ce), TOBN(0xee86bf75, 0x33b3adfb), + TOBN(0xf6902fe6, 0x25aa96ca), TOBN(0xb73540e4, 0xe5aae47d), + TOBN(0x32801d7b, 0x1b4a158c), TOBN(0xe571c99e, 0x27e2a369), + TOBN(0x40cb76c0, 0x10d9f197), TOBN(0xc308c289, 0x3167c0ae), + TOBN(0xa6ef9dd3, 0xeb7958f2), TOBN(0xa7226dfc, 0x300879b1), + TOBN(0x6cd0b362, 0x7edf0636), TOBN(0x4efbce6c, 0x7bc37eed), + TOBN(0x75f92a05, 0x8d699021), TOBN(0x586d4c79, 0x772566e3), + TOBN(0x378ca5f1, 0x761ad23a), TOBN(0x650d86fc, 0x1465a8ac), + TOBN(0x7a4ed457, 0x842ba251), TOBN(0x6b65e3e6, 0x42234933), + TOBN(0xaf1543b7, 0x31aad657), TOBN(0xa4cefe98, 0xcbfec369), + TOBN(0xb587da90, 0x9f47befb), TOBN(0x6562e9fb, 0x41312d13), + TOBN(0xa691ea59, 0xeff1cefe), TOBN(0xcc30477a, 0x05fc4cf6), + TOBN(0xa1632461, 0x0b0ffd3d), TOBN(0xa1f16f3b, 0x5b355956), + TOBN(0x5b148d53, 0x4224ec24), TOBN(0xdc834e7b, 0xf977012a), + TOBN(0x7bfc5e75, 0xb2c69dbc), TOBN(0x3aa77a29, 0x03c3da6c), + TOBN(0xde0df03c, 0xca910271), TOBN(0xcbd5ca4a, 0x7806dc55), + TOBN(0xe1ca5807, 0x6db476cb), TOBN(0xfde15d62, 0x5f37a31e), + TOBN(0xf49af520, 0xf41af416), TOBN(0x96c5c5b1, 0x7d342db5), + TOBN(0x155c43b7, 0xeb4ceb9b), TOBN(0x2e993010, 0x4e77371a), + TOBN(0x1d2987da, 0x675d43af), TOBN(0xef2bc1c0, 0x8599fd72), + TOBN(0x96894b7b, 0x9342f6b2), TOBN(0x201eadf2, 0x7c8e71f0), + TOBN(0xf3479d9f, 0x4a1f3efc), TOBN(0xe0f8a742, 0x702a9704), + TOBN(0xeafd44b6, 0xb3eba40c), TOBN(0xf9739f29, 0xc1c1e0d0), + TOBN(0x0091471a, 0x619d505e), TOBN(0xc15f9c96, 0x9d7c263e), + TOBN(0x5be47285, 0x83afbe33), TOBN(0xa3b6d6af, 0x04f1e092), + TOBN(0xe76526b9, 0x751a9d11), TOBN(0x2ec5b26d, 0x9a4ae4d2), + TOBN(0xeb66f4d9, 0x02f6fb8d), TOBN(0x4063c561, 0x96912164), + TOBN(0xeb7050c1, 0x80ef3000), TOBN(0x288d1c33, 0xeaa5b3f0), + TOBN(0xe87c68d6, 0x07806fd8), TOBN(0xb2f7f9d5, 0x4bbbf50f), + TOBN(0x25972f3a, 0xac8d6627), TOBN(0xf8547774, 0x10e8c13b), + TOBN(0xcc50ef6c, 0x872b4a60), TOBN(0xab2a34a4, 0x4613521b), + TOBN(0x39c5c190, 0x983e15d1), TOBN(0x61dde5df, 0x59905512), + TOBN(0xe417f621, 0x9f2275f3), TOBN(0x0750c8b6, 0x451d894b), + TOBN(0x75b04ab9, 0x78b0bdaa), TOBN(0x3bfd9fd4, 0x458589bd), + TOBN(0xf1013e30, 0xee9120b6), TOBN(0x2b51af93, 0x23a4743e), + TOBN(0xea96ffae, 0x48d14d9e), TOBN(0x71dc0dbe, 0x698a1d32), + TOBN(0x914962d2, 0x0180cca4), TOBN(0x1ae60677, 0xc3568963), + TOBN(0x8cf227b1, 0x437bc444), TOBN(0xc650c83b, 0xc9962c7a), + TOBN(0x23c2c7dd, 0xfe7ccfc4), TOBN(0xf925c89d, 0x1b929d48), + TOBN(0x4460f74b, 0x06783c33), TOBN(0xac2c8d49, 0xa590475a), + TOBN(0xfb40b407, 0xb807bba0), TOBN(0x9d1e362d, 0x69ff8f3a), + TOBN(0xa33e9681, 0xcbef64a4), TOBN(0x67ece5fa, 0x332fb4b2), + TOBN(0x6900a99b, 0x739f10e3), TOBN(0xc3341ca9, 0xff525925), + TOBN(0xee18a626, 0xa9e2d041), TOBN(0xa5a83685, 0x29580ddd), + TOBN(0xf3470c81, 0x9d7de3cd), TOBN(0xedf02586, 0x2062cf9c), + TOBN(0xf43522fa, 0xc010edb0), TOBN(0x30314135, 0x13a4b1ae), + TOBN(0xc792e02a, 0xdb22b94b), TOBN(0x993d8ae9, 0xa1eaa45b), + TOBN(0x8aad6cd3, 0xcd1e1c63), TOBN(0x89529ca7, 0xc5ce688a), + TOBN(0x2ccee3aa, 0xe572a253), TOBN(0xe02b6438, 0x02a21efb), + TOBN(0xa7091b6e, 0xc9430358), TOBN(0x06d1b1fa, 0x9d7db504), + TOBN(0x58846d32, 0xc4744733), TOBN(0x40517c71, 0x379f9e34), + TOBN(0x2f65655f, 0x130ef6ca), TOBN(0x526e4488, 0xf1f3503f), + TOBN(0x8467bd17, 0x7ee4a976), TOBN(0x1d9dc913, 0x921363d1), + TOBN(0xd8d24c33, 0xb069e041), TOBN(0x5eb5da0a, 0x2cdf7f51), + TOBN(0x1c0f3cb1, 0x197b994f), TOBN(0x3c95a6c5, 0x2843eae9), + TOBN(0x7766ffc9, 0xa6097ea5), TOBN(0x7bea4093, 0xd723b867), + TOBN(0xb48e1f73, 0x4db378f9), TOBN(0x70025b00, 0xe37b77ac), + TOBN(0x943dc8e7, 0xaf24ad46), TOBN(0xb98a15ac, 0x16d00a85), + TOBN(0x3adc38ba, 0x2743b004), TOBN(0xb1c7f4f7, 0x334415ee), + TOBN(0xea43df8f, 0x1e62d05a), TOBN(0x32618905, 0x9d76a3b6), + TOBN(0x2fbd0bb5, 0xa23a0f46), TOBN(0x5bc971db, 0x6a01918c), + TOBN(0x7801d94a, 0xb4743f94), TOBN(0xb94df65e, 0x676ae22b), + TOBN(0xaafcbfab, 0xaf95894c), TOBN(0x7b9bdc07, 0x276b2241), + TOBN(0xeaf98362, 0x5bdda48b), TOBN(0x5977faf2, 0xa3fcb4df), + TOBN(0xbed042ef, 0x052c4b5b), TOBN(0x9fe87f71, 0x067591f0), + TOBN(0xc89c73ca, 0x22f24ec7), TOBN(0x7d37fa9e, 0xe64a9f1b), + TOBN(0x2710841a, 0x15562627), TOBN(0x2c01a613, 0xc243b034), + TOBN(0x1d135c56, 0x2bc68609), TOBN(0xc2ca1715, 0x8b03f1f6), + TOBN(0xc9966c2d, 0x3eb81d82), TOBN(0xc02abf4a, 0x8f6df13e), + TOBN(0x77b34bd7, 0x8f72b43b), TOBN(0xaff6218f, 0x360c82b0), + TOBN(0x0aa5726c, 0x8d55b9d2), TOBN(0xdc0adbe9, 0x99e9bffb), + TOBN(0x9097549c, 0xefb9e72a), TOBN(0x16755712, 0x9dfb3111), + TOBN(0xdd8bf984, 0xf26847f9), TOBN(0xbcb8e387, 0xdfb30cb7), + TOBN(0xc1fd32a7, 0x5171ef9c), TOBN(0x977f3fc7, 0x389b363f), + TOBN(0x116eaf2b, 0xf4babda0), TOBN(0xfeab68bd, 0xf7113c8e), + TOBN(0xd1e3f064, 0xb7def526), TOBN(0x1ac30885, 0xe0b3fa02), + TOBN(0x1c5a6e7b, 0x40142d9d), TOBN(0x839b5603, 0x30921c0b), + TOBN(0x48f301fa, 0x36a116a3), TOBN(0x380e1107, 0xcfd9ee6d), + TOBN(0x7945ead8, 0x58854be1), TOBN(0x4111c12e, 0xcbd4d49d), + TOBN(0xece3b1ec, 0x3a29c2ef), TOBN(0x6356d404, 0x8d3616f5), + TOBN(0x9f0d6a8f, 0x594d320e), TOBN(0x0989316d, 0xf651ccd2), + TOBN(0x6c32117a, 0x0f8fdde4), TOBN(0x9abe5cc5, 0xa26a9bbc), + TOBN(0xcff560fb, 0x9723f671), TOBN(0x21b2a12d, 0x7f3d593c), + TOBN(0xe4cb18da, 0x24ba0696), TOBN(0x186e2220, 0xc3543384), + TOBN(0x722f64e0, 0x88312c29), TOBN(0x94282a99, 0x17dc7752), + TOBN(0x62467bbf, 0x5a85ee89), TOBN(0xf435c650, 0xf10076a0), + TOBN(0xc9ff1539, 0x43b3a50b), TOBN(0x7132130c, 0x1a53efbc), + TOBN(0x31bfe063, 0xf7b0c5b7), TOBN(0xb0179a7d, 0x4ea994cc), + TOBN(0x12d064b3, 0xc85f455b), TOBN(0x47259328, 0x8f6e0062), + TOBN(0xf64e590b, 0xb875d6d9), TOBN(0x22dd6225, 0xad92bcc7), + TOBN(0xb658038e, 0xb9c3bd6d), TOBN(0x00cdb0d6, 0xfbba27c8), + TOBN(0x0c681337, 0x1062c45d), TOBN(0xd8515b8c, 0x2d33407d), + TOBN(0xcb8f699e, 0x8cbb5ecf), TOBN(0x8c4347f8, 0xc608d7d8), + TOBN(0x2c11850a, 0xbb3e00db), TOBN(0x20a8dafd, 0xecb49d19), + TOBN(0xbd781480, 0x45ee2f40), TOBN(0x75e354af, 0x416b60cf), + TOBN(0xde0b58a1, 0x8d49a8c4), TOBN(0xe40e94e2, 0xfa359536), + TOBN(0xbd4fa59f, 0x62accd76), TOBN(0x05cf466a, 0x8c762837), + TOBN(0xb5abda99, 0x448c277b), TOBN(0x5a9e01bf, 0x48b13740), + TOBN(0x9d457798, 0x326aad8d), TOBN(0xbdef4954, 0xc396f7e7), + TOBN(0x6fb274a2, 0xc253e292), TOBN(0x2800bf0a, 0x1cfe53e7), + TOBN(0x22426d31, 0x44438fd4), TOBN(0xef233923, 0x5e259f9a), + TOBN(0x4188503c, 0x03f66264), TOBN(0x9e5e7f13, 0x7f9fdfab), + TOBN(0x565eb76c, 0x5fcc1aba), TOBN(0xea632548, 0x59b5bff8), + TOBN(0x5587c087, 0xaab6d3fa), TOBN(0x92b639ea, 0x6ce39c1b), + TOBN(0x0706e782, 0x953b135c), TOBN(0x7308912e, 0x425268ef), + TOBN(0x599e92c7, 0x090e7469), TOBN(0x83b90f52, 0x9bc35e75), + TOBN(0x4750b3d0, 0x244975b3), TOBN(0xf3a44358, 0x11965d72), + TOBN(0x179c6774, 0x9c8dc751), TOBN(0xff18cdfe, 0xd23d9ff0), + TOBN(0xc4013833, 0x2028e247), TOBN(0x96e280e2, 0xf3bfbc79), + TOBN(0xf60417bd, 0xd0880a84), TOBN(0x263c9f3d, 0x2a568151), + TOBN(0x36be15b3, 0x2d2ce811), TOBN(0x846dc0c2, 0xf8291d21), + TOBN(0x5cfa0ecb, 0x789fcfdb), TOBN(0x45a0beed, 0xd7535b9a), + TOBN(0xec8e9f07, 0x96d69af1), TOBN(0x31a7c5b8, 0x599ab6dc), + TOBN(0xd36d45ef, 0xf9e2e09f), TOBN(0x3cf49ef1, 0xdcee954b), + TOBN(0x6be34cf3, 0x086cff9b), TOBN(0x88dbd491, 0x39a3360f), + TOBN(0x1e96b8cc, 0x0dbfbd1d), TOBN(0xc1e5f7bf, 0xcb7e2552), + TOBN(0x0547b214, 0x28819d98), TOBN(0xc770dd9c, 0x7aea9dcb), + TOBN(0xaef0d4c7, 0x041d68c8), TOBN(0xcc2b9818, 0x13cb9ba8), + TOBN(0x7fc7bc76, 0xfe86c607), TOBN(0x6b7b9337, 0x502a9a95), + TOBN(0x1948dc27, 0xd14dab63), TOBN(0x249dd198, 0xdae047be), + TOBN(0xe8356584, 0xa981a202), TOBN(0x3531dd18, 0x3a893387), + TOBN(0x1be11f90, 0xc85c7209), TOBN(0x93d2fe1e, 0xe2a52b5a), + TOBN(0x8225bfe2, 0xec6d6b97), TOBN(0x9cf6d6f4, 0xbd0aa5de), + TOBN(0x911459cb, 0x54779f5f), TOBN(0x5649cddb, 0x86aeb1f3), + TOBN(0x32133579, 0x3f26ce5a), TOBN(0xc289a102, 0x550f431e), + TOBN(0x559dcfda, 0x73b84c6f), TOBN(0x84973819, 0xee3ac4d7), + TOBN(0xb51e55e6, 0xf2606a82), TOBN(0xe25f7061, 0x90f2fb57), + TOBN(0xacef6c2a, 0xb1a4e37c), TOBN(0x864e359d, 0x5dcf2706), + TOBN(0x479e6b18, 0x7ce57316), TOBN(0x2cab2500, 0x3a96b23d), + TOBN(0xed489862, 0x8ef16df7), TOBN(0x2056538c, 0xef3758b5), + TOBN(0xa7df865e, 0xf15d3101), TOBN(0x80c5533a, 0x61b553d7), + TOBN(0x366e1997, 0x4ed14294), TOBN(0x6620741f, 0xb3c0bcd6), + TOBN(0x21d1d9c4, 0xedc45418), TOBN(0x005b859e, 0xc1cc4a9d), + TOBN(0xdf01f630, 0xa1c462f0), TOBN(0x15d06cf3, 0xf26820c7), + TOBN(0x9f7f24ee, 0x3484be47), TOBN(0x2ff33e96, 0x4a0c902f), + TOBN(0x00bdf457, 0x5a0bc453), TOBN(0x2378dfaf, 0x1aa238db), + TOBN(0x272420ec, 0x856720f2), TOBN(0x2ad9d95b, 0x96797291), + TOBN(0xd1242cc6, 0x768a1558), TOBN(0x2e287f8b, 0x5cc86aa8), + TOBN(0x796873d0, 0x990cecaa), TOBN(0xade55f81, 0x675d4080), + TOBN(0x2645eea3, 0x21f0cd84), TOBN(0x7a1efa0f, 0xb4e17d02), + TOBN(0xf6858420, 0x037cc061), TOBN(0x682e05f0, 0xd5d43e12), + TOBN(0x59c36994, 0x27218710), TOBN(0x85cbba4d, 0x3f7cd2fc), + TOBN(0x726f9729, 0x7a3cd22a), TOBN(0x9f8cd5dc, 0x4a628397), + TOBN(0x17b93ab9, 0xc23165ed), TOBN(0xff5f5dbf, 0x122823d4), + TOBN(0xc1e4e4b5, 0x654a446d), TOBN(0xd1a9496f, 0x677257ba), + TOBN(0x6387ba94, 0xde766a56), TOBN(0x23608bc8, 0x521ec74a), + TOBN(0x16a522d7, 0x6688c4d4), TOBN(0x9d6b4282, 0x07373abd), + TOBN(0xa62f07ac, 0xb42efaa3), TOBN(0xf73e00f7, 0xe3b90180), + TOBN(0x36175fec, 0x49421c3e), TOBN(0xc4e44f9b, 0x3dcf2678), + TOBN(0x76df436b, 0x7220f09f), TOBN(0x172755fb, 0x3aa8b6cf), + TOBN(0xbab89d57, 0x446139cc), TOBN(0x0a0a6e02, 0x5fe0208f), + TOBN(0xcdbb63e2, 0x11e5d399), TOBN(0x33ecaa12, 0xa8977f0b), + TOBN(0x59598b21, 0xf7c42664), TOBN(0xb3e91b32, 0xab65d08a), + TOBN(0x035822ee, 0xf4502526), TOBN(0x1dcf0176, 0x720a82a9), + TOBN(0x50f8598f, 0x3d589e02), TOBN(0xdf0478ff, 0xb1d63d2c), + TOBN(0x8b8068bd, 0x1571cd07), TOBN(0x30c3aa4f, 0xd79670cd), + TOBN(0x25e8fd4b, 0x941ade7f), TOBN(0x3d1debdc, 0x32790011), + TOBN(0x65b6dcbd, 0x3a3f9ff0), TOBN(0x282736a4, 0x793de69c), + TOBN(0xef69a0c3, 0xd41d3bd3), TOBN(0xb533b8c9, 0x07a26bde), + TOBN(0xe2801d97, 0xdb2edf9f), TOBN(0xdc4a8269, 0xe1877af0), + TOBN(0x6c1c5851, 0x3d590dbe), TOBN(0x84632f6b, 0xee4e9357), + TOBN(0xd36d36b7, 0x79b33374), TOBN(0xb46833e3, 0x9bbca2e6), + TOBN(0x37893913, 0xf7fc0586), TOBN(0x385315f7, 0x66bf4719), + TOBN(0x72c56293, 0xb31855dc), TOBN(0xd1416d4e, 0x849061fe), + TOBN(0xbeb3ab78, 0x51047213), TOBN(0x447f6e61, 0xf040c996), + TOBN(0xd06d310d, 0x638b1d0c), TOBN(0xe28a413f, 0xbad1522e), + TOBN(0x685a76cb, 0x82003f86), TOBN(0x610d07f7, 0x0bcdbca3), + TOBN(0x6ff66021, 0x9ca4c455), TOBN(0x7df39b87, 0xcea10eec), + TOBN(0xb9255f96, 0xe22db218), TOBN(0x8cc6d9eb, 0x08a34c44), + TOBN(0xcd4ffb86, 0x859f9276), TOBN(0x8fa15eb2, 0x50d07335), + TOBN(0xdf553845, 0xcf2c24b5), TOBN(0x89f66a9f, 0x52f9c3ba), + TOBN(0x8f22b5b9, 0xe4a7ceb3), TOBN(0xaffef809, 0x0e134686), + TOBN(0x3e53e1c6, 0x8eb8fac2), TOBN(0x93c1e4eb, 0x28aec98e), + TOBN(0xb6b91ec5, 0x32a43bcb), TOBN(0x2dbfa947, 0xb2d74a51), + TOBN(0xe065d190, 0xca84bad7), TOBN(0xfb13919f, 0xad58e65c), + TOBN(0x3c41718b, 0xf1cb6e31), TOBN(0x688969f0, 0x06d05c3f), + TOBN(0xd4f94ce7, 0x21264d45), TOBN(0xfdfb65e9, 0x7367532b), + TOBN(0x5b1be8b1, 0x0945a39d), TOBN(0x229f789c, 0x2b8baf3b), + TOBN(0xd8f41f3e, 0x6f49f15d), TOBN(0x678ce828, 0x907f0792), + TOBN(0xc69ace82, 0xfca6e867), TOBN(0x106451ae, 0xd01dcc89), + TOBN(0x1bb4f7f0, 0x19fc32d2), TOBN(0x64633dfc, 0xb00c52d2), + TOBN(0x8f13549a, 0xad9ea445), TOBN(0x99a3bf50, 0xfb323705), + TOBN(0x0c9625a2, 0x534d4dbc), TOBN(0x45b8f1d1, 0xc2a2fea3), + TOBN(0x76ec21a1, 0xa530fc1a), TOBN(0x4bac9c2a, 0x9e5bd734), + TOBN(0x5996d76a, 0x7b4e3587), TOBN(0x0045cdee, 0x1182d9e3), + TOBN(0x1aee24b9, 0x1207f13d), TOBN(0x66452e97, 0x97345a41), + TOBN(0x16e5b054, 0x9f950cd0), TOBN(0x9cc72fb1, 0xd7fdd075), + TOBN(0x6edd61e7, 0x66249663), TOBN(0xde4caa4d, 0xf043cccb), + TOBN(0x11b1f57a, 0x55c7ac17), TOBN(0x779cbd44, 0x1a85e24d), + TOBN(0x78030f86, 0xe46081e7), TOBN(0xfd4a6032, 0x8e20f643), + TOBN(0xcc7a6488, 0x0a750c0f), TOBN(0x39bacfe3, 0x4e548e83), + TOBN(0x3d418c76, 0x0c110f05), TOBN(0x3e4daa4c, 0xb1f11588), + TOBN(0x2733e7b5, 0x5ffc69ff), TOBN(0x46f147bc, 0x92053127), + TOBN(0x885b2434, 0xd722df94), TOBN(0x6a444f65, 0xe6fc6b7c)}, + {TOBN(0x7a1a465a, 0xc3f16ea8), TOBN(0x115a461d, 0xb2f1d11c), + TOBN(0x4767dd95, 0x6c68a172), TOBN(0x3392f2eb, 0xd13a4698), + TOBN(0xc7a99ccd, 0xe526cdc7), TOBN(0x8e537fdc, 0x22292b81), + TOBN(0x76d8cf69, 0xa6d39198), TOBN(0xffc5ff43, 0x2446852d), + TOBN(0x97b14f7e, 0xa90567e6), TOBN(0x513257b7, 0xb6ae5cb7), + TOBN(0x85454a3c, 0x9f10903d), TOBN(0xd8d2c9ad, 0x69bc3724), + TOBN(0x38da9324, 0x6b29cb44), TOBN(0xb540a21d, 0x77c8cbac), + TOBN(0x9bbfe435, 0x01918e42), TOBN(0xfffa707a, 0x56c3614e), + TOBN(0x0ce4e3f1, 0xd4e353b7), TOBN(0x062d8a14, 0xef46b0a0), + TOBN(0x6408d5ab, 0x574b73fd), TOBN(0xbc41d1c9, 0xd3273ffd), + TOBN(0x3538e1e7, 0x6be77800), TOBN(0x71fe8b37, 0xc5655031), + TOBN(0x1cd91621, 0x6b9b331a), TOBN(0xad825d0b, 0xbb388f73), + TOBN(0x56c2e05b, 0x1cb76219), TOBN(0x0ec0bf91, 0x71567e7e), + TOBN(0xe7076f86, 0x61c4c910), TOBN(0xd67b085b, 0xbabc04d9), + TOBN(0x9fb90459, 0x5e93a96a), TOBN(0x7526c1ea, 0xfbdc249a), + TOBN(0x0d44d367, 0xecdd0bb7), TOBN(0x95399917, 0x9dc0d695), + TOBN(0x61360ee9, 0x9e240d18), TOBN(0x057cdcac, 0xb4b94466), + TOBN(0xe7667cd1, 0x2fe5325c), TOBN(0x1fa297b5, 0x21974e3b), + TOBN(0xfa4081e7, 0xdb083d76), TOBN(0x31993be6, 0xf206bd15), + TOBN(0x8949269b, 0x14c19f8c), TOBN(0x21468d72, 0xa9d92357), + TOBN(0x2ccbc583, 0xa4c506ec), TOBN(0x957ed188, 0xd1acfe97), + TOBN(0x8baed833, 0x12f1aea2), TOBN(0xef2a6cb4, 0x8325362d), + TOBN(0x130dde42, 0x8e195c43), TOBN(0xc842025a, 0x0e6050c6), + TOBN(0x2da972a7, 0x08686a5d), TOBN(0xb52999a1, 0xe508b4a8), + TOBN(0xd9f090b9, 0x10a5a8bd), TOBN(0xca91d249, 0x096864da), + TOBN(0x8e6a93be, 0x3f67dbc1), TOBN(0xacae6fba, 0xf5f4764c), + TOBN(0x1563c6e0, 0xd21411a0), TOBN(0x28fa787f, 0xda0a4ad8), + TOBN(0xd524491c, 0x908c8030), TOBN(0x1257ba0e, 0x4c795f07), + TOBN(0x83f49167, 0xceca9754), TOBN(0x426d2cf6, 0x4b7939a0), + TOBN(0x2555e355, 0x723fd0bf), TOBN(0xa96e6d06, 0xc4f144e2), + TOBN(0x4768a8dd, 0x87880e61), TOBN(0x15543815, 0xe508e4d5), + TOBN(0x09d7e772, 0xb1b65e15), TOBN(0x63439dd6, 0xac302fa0), + TOBN(0xb93f802f, 0xc14e35c2), TOBN(0x71735b7c, 0x4341333c), + TOBN(0x03a25104, 0x16d4f362), TOBN(0x3f4d069b, 0xbf433c8e), + TOBN(0x0d83ae01, 0xf78f5a7c), TOBN(0x50a8ffbe, 0x7c4eed07), + TOBN(0xc74f8906, 0x76e10f83), TOBN(0x7d080966, 0x9ddaf8e1), + TOBN(0xb11df8e1, 0x698e04cc), TOBN(0x877be203, 0x169005c8), + TOBN(0x32749e8c, 0x4f3c6179), TOBN(0x2dbc9d0a, 0x7853fc05), + TOBN(0x187d4f93, 0x9454d937), TOBN(0xe682ce9d, 0xb4800e1b), + TOBN(0xa9129ad8, 0x165e68e8), TOBN(0x0fe29735, 0xbe7f785b), + TOBN(0x5303f40c, 0x5b9e02b7), TOBN(0xa37c9692, 0x35ee04e8), + TOBN(0x5f46cc20, 0x34d6632b), TOBN(0x55ef72b2, 0x96ac545b), + TOBN(0xabec5c1f, 0x7b91b062), TOBN(0x0a79e1c7, 0xbb33e821), + TOBN(0xbb04b428, 0x3a9f4117), TOBN(0x0de1f28f, 0xfd2a475a), + TOBN(0x31019ccf, 0x3a4434b4), TOBN(0xa3458111, 0x1a7954dc), + TOBN(0xa9dac80d, 0xe34972a7), TOBN(0xb043d054, 0x74f6b8dd), + TOBN(0x021c319e, 0x11137b1a), TOBN(0x00a754ce, 0xed5cc03f), + TOBN(0x0aa2c794, 0xcbea5ad4), TOBN(0x093e67f4, 0x70c015b6), + TOBN(0x72cdfee9, 0xc97e3f6b), TOBN(0xc10bcab4, 0xb6da7461), + TOBN(0x3b02d2fc, 0xb59806b9), TOBN(0x85185e89, 0xa1de6f47), + TOBN(0x39e6931f, 0x0eb6c4d4), TOBN(0x4d4440bd, 0xd4fa5b04), + TOBN(0x5418786e, 0x34be7eb8), TOBN(0x6380e521, 0x9d7259bc), + TOBN(0x20ac0351, 0xd598d710), TOBN(0x272c4166, 0xcb3a4da4), + TOBN(0xdb82fe1a, 0xca71de1f), TOBN(0x746e79f2, 0xd8f54b0f), + TOBN(0x6e7fc736, 0x4b573e9b), TOBN(0x75d03f46, 0xfd4b5040), + TOBN(0x5c1cc36d, 0x0b98d87b), TOBN(0x513ba3f1, 0x1f472da1), + TOBN(0x79d0af26, 0xabb177dd), TOBN(0xf82ab568, 0x7891d564), + TOBN(0x2b6768a9, 0x72232173), TOBN(0xefbb3bb0, 0x8c1f6619), + TOBN(0xb29c11db, 0xa6d18358), TOBN(0x519e2797, 0xb0916d3a), + TOBN(0xd4dc18f0, 0x9188e290), TOBN(0x648e86e3, 0x98b0ca7f), + TOBN(0x859d3145, 0x983c38b5), TOBN(0xb14f176c, 0x637abc8b), + TOBN(0x2793fb9d, 0xcaff7be6), TOBN(0xebe5a55f, 0x35a66a5a), + TOBN(0x7cec1dcd, 0x9f87dc59), TOBN(0x7c595cd3, 0xfbdbf560), + TOBN(0x5b543b22, 0x26eb3257), TOBN(0x69080646, 0xc4c935fd), + TOBN(0x7f2e4403, 0x81e9ede3), TOBN(0x243c3894, 0xcaf6df0a), + TOBN(0x7c605bb1, 0x1c073b11), TOBN(0xcd06a541, 0xba6a4a62), + TOBN(0x29168949, 0x49d4e2e5), TOBN(0x33649d07, 0x4af66880), + TOBN(0xbfc0c885, 0xe9a85035), TOBN(0xb4e52113, 0xfc410f4b), + TOBN(0xdca3b706, 0x78a6513b), TOBN(0x92ea4a2a, 0x9edb1943), + TOBN(0x02642216, 0xdb6e2dd8), TOBN(0x9b45d0b4, 0x9fd57894), + TOBN(0x114e70db, 0xc69d11ae), TOBN(0x1477dd19, 0x4c57595f), + TOBN(0xbc2208b4, 0xec77c272), TOBN(0x95c5b4d7, 0xdb68f59c), + TOBN(0xb8c4fc63, 0x42e532b7), TOBN(0x386ba422, 0x9ae35290), + TOBN(0xfb5dda42, 0xd201ecbc), TOBN(0x2353dc8b, 0xa0e38fd6), + TOBN(0x9a0b85ea, 0x68f7e978), TOBN(0x96ec5682, 0x2ad6d11f), + TOBN(0x5e279d6c, 0xe5f6886d), TOBN(0xd3fe03cd, 0x3cb1914d), + TOBN(0xfe541fa4, 0x7ea67c77), TOBN(0x952bd2af, 0xe3ea810c), + TOBN(0x791fef56, 0x8d01d374), TOBN(0xa3a1c621, 0x0f11336e), + TOBN(0x5ad0d5a9, 0xc7ec6d79), TOBN(0xff7038af, 0x3225c342), + TOBN(0x003c6689, 0xbc69601b), TOBN(0x25059bc7, 0x45e8747d), + TOBN(0xfa4965b2, 0xf2086fbf), TOBN(0xf6840ea6, 0x86916078), + TOBN(0xd7ac7620, 0x70081d6c), TOBN(0xe600da31, 0xb5328645), + TOBN(0x01916f63, 0x529b8a80), TOBN(0xe80e4858, 0x2d7d6f3e), + TOBN(0x29eb0fe8, 0xd664ca7c), TOBN(0xf017637b, 0xe7b43b0c), + TOBN(0x9a75c806, 0x76cb2566), TOBN(0x8f76acb1, 0xb24892d9), + TOBN(0x7ae7b9cc, 0x1f08fe45), TOBN(0x19ef7329, 0x6a4907d8), + TOBN(0x2db4ab71, 0x5f228bf0), TOBN(0xf3cdea39, 0x817032d7), + TOBN(0x0b1f482e, 0xdcabe3c0), TOBN(0x3baf76b4, 0xbb86325c), + TOBN(0xd49065e0, 0x10089465), TOBN(0x3bab5d29, 0x8e77c596), + TOBN(0x7636c3a6, 0x193dbd95), TOBN(0xdef5d294, 0xb246e499), + TOBN(0xb22c58b9, 0x286b2475), TOBN(0xa0b93939, 0xcd80862b), + TOBN(0x3002c83a, 0xf0992388), TOBN(0x6de01f9b, 0xeacbe14c), + TOBN(0x6aac688e, 0xadd70482), TOBN(0x708de92a, 0x7b4a4e8a), + TOBN(0x75b6dd73, 0x758a6eef), TOBN(0xea4bf352, 0x725b3c43), + TOBN(0x10041f2c, 0x87912868), TOBN(0xb1b1be95, 0xef09297a), + TOBN(0x19ae23c5, 0xa9f3860a), TOBN(0xc4f0f839, 0x515dcf4b), + TOBN(0x3c7ecca3, 0x97f6306a), TOBN(0x744c44ae, 0x68a3a4b0), + TOBN(0x69cd13a0, 0xb3a1d8a2), TOBN(0x7cad0a1e, 0x5256b578), + TOBN(0xea653fcd, 0x33791d9e), TOBN(0x9cc2a05d, 0x74b2e05f), + TOBN(0x73b391dc, 0xfd7affa2), TOBN(0xddb7091e, 0xb6b05442), + TOBN(0xc71e27bf, 0x8538a5c6), TOBN(0x195c63dd, 0x89abff17), + TOBN(0xfd315285, 0x1b71e3da), TOBN(0x9cbdfda7, 0xfa680fa0), + TOBN(0x9db876ca, 0x849d7eab), TOBN(0xebe2764b, 0x3c273271), + TOBN(0x663357e3, 0xf208dcea), TOBN(0x8c5bd833, 0x565b1b70), + TOBN(0xccc3b4f5, 0x9837fc0d), TOBN(0x9b641ba8, 0xa79cf00f), + TOBN(0x7428243d, 0xdfdf3990), TOBN(0x83a594c4, 0x020786b1), + TOBN(0xb712451a, 0x526c4502), TOBN(0x9d39438e, 0x6adb3f93), + TOBN(0xfdb261e3, 0xe9ff0ccd), TOBN(0x80344e3c, 0xe07af4c3), + TOBN(0x75900d7c, 0x2fa4f126), TOBN(0x08a3b865, 0x5c99a232), + TOBN(0x2478b6bf, 0xdb25e0c3), TOBN(0x482cc2c2, 0x71db2edf), + TOBN(0x37df7e64, 0x5f321bb8), TOBN(0x8a93821b, 0x9a8005b4), + TOBN(0x3fa2f10c, 0xcc8c1958), TOBN(0x0d332218, 0x2c269d0a), + TOBN(0x20ab8119, 0xe246b0e6), TOBN(0xb39781e4, 0xd349fd17), + TOBN(0xd293231e, 0xb31aa100), TOBN(0x4b779c97, 0xbb032168), + TOBN(0x4b3f19e1, 0xc8470500), TOBN(0x45b7efe9, 0x0c4c869d), + TOBN(0xdb84f38a, 0xa1a6bbcc), TOBN(0x3b59cb15, 0xb2fddbc1), + TOBN(0xba5514df, 0x3fd165e8), TOBN(0x499fd6a9, 0x061f8811), + TOBN(0x72cd1fe0, 0xbfef9f00), TOBN(0x120a4bb9, 0x79ad7e8a), + TOBN(0xf2ffd095, 0x5f4a5ac5), TOBN(0xcfd174f1, 0x95a7a2f0), + TOBN(0xd42301ba, 0x9d17baf1), TOBN(0xd2fa487a, 0x77f22089), + TOBN(0x9cb09efe, 0xb1dc77e1), TOBN(0xe9566939, 0x21c99682), + TOBN(0x8c546901, 0x6c6067bb), TOBN(0xfd378574, 0x61c24456), + TOBN(0x2b6a6cbe, 0x81796b33), TOBN(0x62d550f6, 0x58e87f8b), + TOBN(0x1b763e1c, 0x7f1b01b4), TOBN(0x4b93cfea, 0x1b1b5e12), + TOBN(0xb9345238, 0x1d531696), TOBN(0x57201c00, 0x88cdde69), + TOBN(0xdde92251, 0x9a86afc7), TOBN(0xe3043895, 0xbd35cea8), + TOBN(0x7608c1e1, 0x8555970d), TOBN(0x8267dfa9, 0x2535935e), + TOBN(0xd4c60a57, 0x322ea38b), TOBN(0xe0bf7977, 0x804ef8b5), + TOBN(0x1a0dab28, 0xc06fece4), TOBN(0xd405991e, 0x94e7b49d), + TOBN(0xc542b6d2, 0x706dab28), TOBN(0xcb228da3, 0xa91618fb), + TOBN(0x224e4164, 0x107d1cea), TOBN(0xeb9fdab3, 0xd0f5d8f1), + TOBN(0xc02ba386, 0x0d6e41cd), TOBN(0x676a72c5, 0x9b1f7146), + TOBN(0xffd6dd98, 0x4d6cb00b), TOBN(0xcef9c5ca, 0xde2e8d7c), + TOBN(0xa1bbf5d7, 0x641c7936), TOBN(0x1b95b230, 0xee8f772e), + TOBN(0xf765a92e, 0xe8ac25b1), TOBN(0xceb04cfc, 0x3a18b7c6), + TOBN(0x27944cef, 0x0acc8966), TOBN(0xcbb3c957, 0x434c1004), + TOBN(0x9c9971a1, 0xa43ff93c), TOBN(0x5bc2db17, 0xa1e358a9), + TOBN(0x45b4862e, 0xa8d9bc82), TOBN(0x70ebfbfb, 0x2201e052), + TOBN(0xafdf64c7, 0x92871591), TOBN(0xea5bcae6, 0xb42d0219), + TOBN(0xde536c55, 0x2ad8f03c), TOBN(0xcd6c3f4d, 0xa76aa33c), + TOBN(0xbeb5f623, 0x0bca6de3), TOBN(0xdd20dd99, 0xb1e706fd), + TOBN(0x90b3ff9d, 0xac9059d4), TOBN(0x2d7b2902, 0x7ccccc4e), + TOBN(0x8a090a59, 0xce98840f), TOBN(0xa5d947e0, 0x8410680a), + TOBN(0x49ae346a, 0x923379a5), TOBN(0x7dbc84f9, 0xb28a3156), + TOBN(0xfd40d916, 0x54a1aff2), TOBN(0xabf318ba, 0x3a78fb9b), + TOBN(0x50152ed8, 0x3029f95e), TOBN(0x9fc1dd77, 0xc58ad7fa), + TOBN(0x5fa57915, 0x13595c17), TOBN(0xb9504668, 0x8f62b3a9), + TOBN(0x907b5b24, 0xff3055b0), TOBN(0x2e995e35, 0x9a84f125), + TOBN(0x87dacf69, 0x7e9bbcfb), TOBN(0x95d0c1d6, 0xe86d96e3), + TOBN(0x65726e3c, 0x2d95a75c), TOBN(0x2c3c9001, 0xacd27f21), + TOBN(0x1deab561, 0x6c973f57), TOBN(0x108b7e2c, 0xa5221643), + TOBN(0x5fee9859, 0xc4ef79d4), TOBN(0xbd62b88a, 0x40d4b8c6), + TOBN(0xb4dd29c4, 0x197c75d6), TOBN(0x266a6df2, 0xb7076feb), + TOBN(0x9512d0ea, 0x4bf2df11), TOBN(0x1320c24f, 0x6b0cc9ec), + TOBN(0x6bb1e0e1, 0x01a59596), TOBN(0x8317c5bb, 0xeff9aaac), + TOBN(0x65bb405e, 0x385aa6c9), TOBN(0x613439c1, 0x8f07988f), + TOBN(0xd730049f, 0x16a66e91), TOBN(0xe97f2820, 0xfa1b0e0d), + TOBN(0x4131e003, 0x304c28ea), TOBN(0x820ab732, 0x526bac62), + TOBN(0xb2ac9ef9, 0x28714423), TOBN(0x54ecfffa, 0xadb10cb2), + TOBN(0x8781476e, 0xf886a4cc), TOBN(0x4b2c87b5, 0xdb2f8d49), + TOBN(0xe857cd20, 0x0a44295d), TOBN(0x707d7d21, 0x58c6b044), + TOBN(0xae8521f9, 0xf596757c), TOBN(0x87448f03, 0x67b2b714), + TOBN(0x13a9bc45, 0x5ebcd58d), TOBN(0x79bcced9, 0x9122d3c1), + TOBN(0x3c644247, 0x9e076642), TOBN(0x0cf22778, 0x2df4767d), + TOBN(0x5e61aee4, 0x71d444b6), TOBN(0x211236bf, 0xc5084a1d), + TOBN(0x7e15bc9a, 0x4fd3eaf6), TOBN(0x68df2c34, 0xab622bf5), + TOBN(0x9e674f0f, 0x59bf4f36), TOBN(0xf883669b, 0xd7f34d73), + TOBN(0xc48ac1b8, 0x31497b1d), TOBN(0x323b925d, 0x5106703b), + TOBN(0x22156f42, 0x74082008), TOBN(0xeffc521a, 0xc8482bcb), + TOBN(0x5c6831bf, 0x12173479), TOBN(0xcaa2528f, 0xc4739490), + TOBN(0x84d2102a, 0x8f1b3c4d), TOBN(0xcf64dfc1, 0x2d9bec0d), + TOBN(0x433febad, 0x78a546ef), TOBN(0x1f621ec3, 0x7b73cef1), + TOBN(0x6aecd627, 0x37338615), TOBN(0x162082ab, 0x01d8edf6), + TOBN(0x833a8119, 0x19e86b66), TOBN(0x6023a251, 0xd299b5db), + TOBN(0xf5bb0c3a, 0xbbf04b89), TOBN(0x6735eb69, 0xae749a44), + TOBN(0xd0e058c5, 0x4713de3b), TOBN(0xfdf2593e, 0x2c3d4ccd), + TOBN(0x1b8f414e, 0xfdd23667), TOBN(0xdd52aaca, 0xfa2015ee), + TOBN(0x3e31b517, 0xbd9625ff), TOBN(0x5ec9322d, 0x8db5918c), + TOBN(0xbc73ac85, 0xa96f5294), TOBN(0x82aa5bf3, 0x61a0666a), + TOBN(0x49755810, 0xbf08ac42), TOBN(0xd21cdfd5, 0x891cedfc), + TOBN(0x918cb57b, 0x67f8be10), TOBN(0x365d1a7c, 0x56ffa726), + TOBN(0x2435c504, 0x6532de93), TOBN(0xc0fc5e10, 0x2674cd02), + TOBN(0x6e51fcf8, 0x9cbbb142), TOBN(0x1d436e5a, 0xafc50692), + TOBN(0x766bffff, 0x3fbcae22), TOBN(0x3148c2fd, 0xfd55d3b8), + TOBN(0x52c7fdc9, 0x233222fa), TOBN(0x89ff1092, 0xe419fb6b), + TOBN(0x3cd6db99, 0x25254977), TOBN(0x2e85a161, 0x1cf12ca7), + TOBN(0xadd2547c, 0xdc810bc9), TOBN(0xea3f458f, 0x9d257c22), + TOBN(0x642c1fbe, 0x27d6b19b), TOBN(0xed07e6b5, 0x140481a6), + TOBN(0x6ada1d42, 0x86d2e0f8), TOBN(0xe5920122, 0x0e8a9fd5), + TOBN(0x02c936af, 0x708c1b49), TOBN(0x60f30fee, 0x2b4bfaff), + TOBN(0x6637ad06, 0x858e6a61), TOBN(0xce4c7767, 0x3fd374d0), + TOBN(0x39d54b2d, 0x7188defb), TOBN(0xa8c9d250, 0xf56a6b66), + TOBN(0x58fc0f5e, 0xb24fe1dc), TOBN(0x9eaf9dee, 0x6b73f24c), + TOBN(0xa90d588b, 0x33650705), TOBN(0xde5b62c5, 0xaf2ec729), + TOBN(0x5c72cfae, 0xd3c2b36e), TOBN(0x868c19d5, 0x034435da), + TOBN(0x88605f93, 0xe17ee145), TOBN(0xaa60c4ee, 0x77a5d5b1), + TOBN(0xbcf5bfd2, 0x3b60c472), TOBN(0xaf4ef13c, 0xeb1d3049), + TOBN(0x373f44fc, 0xe13895c9), TOBN(0xf29b382f, 0x0cbc9822), + TOBN(0x1bfcb853, 0x73efaef6), TOBN(0xcf56ac9c, 0xa8c96f40), + TOBN(0xd7adf109, 0x7a191e24), TOBN(0x98035f44, 0xbf8a8dc2), + TOBN(0xf40a71b9, 0x1e750c84), TOBN(0xc57f7b0c, 0x5dc6c469), + TOBN(0x49a0e79c, 0x6fbc19c1), TOBN(0x6b0f5889, 0xa48ebdb8), + TOBN(0x5d3fd084, 0xa07c4e9f), TOBN(0xc3830111, 0xab27de14), + TOBN(0x0e4929fe, 0x33e08dcc), TOBN(0xf4a5ad24, 0x40bb73a3), + TOBN(0xde86c2bf, 0x490f97ca), TOBN(0x288f09c6, 0x67a1ce18), + TOBN(0x364bb886, 0x1844478d), TOBN(0x7840fa42, 0xceedb040), + TOBN(0x1269fdd2, 0x5a631b37), TOBN(0x94761f1e, 0xa47c8b7d), + TOBN(0xfc0c2e17, 0x481c6266), TOBN(0x85e16ea2, 0x3daa5fa7), + TOBN(0xccd86033, 0x92491048), TOBN(0x0c2f6963, 0xf4d402d7), + TOBN(0x6336f7df, 0xdf6a865c), TOBN(0x0a2a463c, 0xb5c02a87), + TOBN(0xb0e29be7, 0xbf2f12ee), TOBN(0xf0a22002, 0x66bad988), + TOBN(0x27f87e03, 0x9123c1d7), TOBN(0x21669c55, 0x328a8c98), + TOBN(0x186b9803, 0x92f14529), TOBN(0xd3d056cc, 0x63954df3), + TOBN(0x2f03fd58, 0x175a46f6), TOBN(0x63e34ebe, 0x11558558), + TOBN(0xe13fedee, 0x5b80cfa5), TOBN(0xe872a120, 0xd401dbd1), + TOBN(0x52657616, 0xe8a9d667), TOBN(0xbc8da4b6, 0xe08d6693), + TOBN(0x370fb9bb, 0x1b703e75), TOBN(0x6773b186, 0xd4338363), + TOBN(0x18dad378, 0xecef7bff), TOBN(0xaac787ed, 0x995677da), + TOBN(0x4801ea8b, 0x0437164b), TOBN(0xf430ad20, 0x73fe795e), + TOBN(0xb164154d, 0x8ee5eb73), TOBN(0x0884ecd8, 0x108f7c0e), + TOBN(0x0e6ec096, 0x5f520698), TOBN(0x640631fe, 0x44f7b8d9), + TOBN(0x92fd34fc, 0xa35a68b9), TOBN(0x9c5a4b66, 0x4d40cf4e), + TOBN(0x949454bf, 0x80b6783d), TOBN(0x80e701fe, 0x3a320a10), + TOBN(0x8d1a564a, 0x1a0a39b2), TOBN(0x1436d53d, 0x320587db), + TOBN(0xf5096e6d, 0x6556c362), TOBN(0xbc23a3c0, 0xe2455d7e), + TOBN(0x3a7aee54, 0x807230f9), TOBN(0x9ba1cfa6, 0x22ae82fd), + TOBN(0x833a057a, 0x99c5d706), TOBN(0x8be85f4b, 0x842315c9), + TOBN(0xd083179a, 0x66a72f12), TOBN(0x2fc77d5d, 0xcdcc73cd), + TOBN(0x22b88a80, 0x5616ee30), TOBN(0xfb09548f, 0xe7ab1083), + TOBN(0x8ad6ab0d, 0x511270cd), TOBN(0x61f6c57a, 0x6924d9ab), + TOBN(0xa0f7bf72, 0x90aecb08), TOBN(0x849f87c9, 0x0df784a4), + TOBN(0x27c79c15, 0xcfaf1d03), TOBN(0xbbf9f675, 0xc463face), + TOBN(0x91502c65, 0x765ba543), TOBN(0x18ce3cac, 0x42ea60dd), + TOBN(0xe5cee6ac, 0x6e43ecb3), TOBN(0x63e4e910, 0x68f2aeeb), + TOBN(0x26234fa3, 0xc85932ee), TOBN(0x96883e8b, 0x4c90c44d), + TOBN(0x29b9e738, 0xa18a50f6), TOBN(0xbfc62b2a, 0x3f0420df), + TOBN(0xd22a7d90, 0x6d3e1fa9), TOBN(0x17115618, 0xfe05b8a3), + TOBN(0x2a0c9926, 0xbb2b9c01), TOBN(0xc739fcc6, 0xe07e76a2), + TOBN(0x540e9157, 0x165e439a), TOBN(0x06353a62, 0x6a9063d8), + TOBN(0x84d95594, 0x61e927a3), TOBN(0x013b9b26, 0xe2e0be7f), + TOBN(0x4feaec3b, 0x973497f1), TOBN(0x15c0f94e, 0x093ebc2d), + TOBN(0x6af5f227, 0x33af0583), TOBN(0x0c2af206, 0xc61f3340), + TOBN(0xd25dbdf1, 0x4457397c), TOBN(0x2e8ed017, 0xcabcbae0), + TOBN(0xe3010938, 0xc2815306), TOBN(0xbaa99337, 0xe8c6cd68), + TOBN(0x08513182, 0x3b0ec7de), TOBN(0x1e1b822b, 0x58df05df), + TOBN(0x5c14842f, 0xa5c3b683), TOBN(0x98fe977e, 0x3eba34ce), + TOBN(0xfd2316c2, 0x0d5e8873), TOBN(0xe48d839a, 0xbd0d427d), + TOBN(0x495b2218, 0x623fc961), TOBN(0x24ee56e7, 0xb46fba5e), + TOBN(0x9184a55b, 0x91e4de58), TOBN(0xa7488ca5, 0xdfdea288), + TOBN(0xa723862e, 0xa8dcc943), TOBN(0x92d762b2, 0x849dc0fc), + TOBN(0x3c444a12, 0x091ff4a9), TOBN(0x581113fa, 0x0cada274), + TOBN(0xb9de0a45, 0x30d8eae2), TOBN(0x5e0fcd85, 0xdf6b41ea), + TOBN(0x6233ea68, 0xc094dbb5), TOBN(0xb77d062e, 0xd968d410), + TOBN(0x3e719bbc, 0x58b3002d), TOBN(0x68e7dd3d, 0x3dc49d58), + TOBN(0x8d825740, 0x013a5e58), TOBN(0x21311747, 0x3c9e3c1b), + TOBN(0x0cb0a2a7, 0x7c99b6ab), TOBN(0x5c48a3b3, 0xc2f888f2)}, + {TOBN(0xc7913e91, 0x991724f3), TOBN(0x5eda799c, 0x39cbd686), + TOBN(0xddb595c7, 0x63d4fc1e), TOBN(0x6b63b80b, 0xac4fed54), + TOBN(0x6ea0fc69, 0x7e5fb516), TOBN(0x737708ba, 0xd0f1c964), + TOBN(0x9628745f, 0x11a92ca5), TOBN(0x61f37958, 0x9a86967a), + TOBN(0x9af39b2c, 0xaa665072), TOBN(0x78322fa4, 0xefd324ef), + TOBN(0x3d153394, 0xc327bd31), TOBN(0x81d5f271, 0x3129dab0), + TOBN(0xc72e0c42, 0xf48027f5), TOBN(0xaa40cdbc, 0x8536e717), + TOBN(0xf45a657a, 0x2d369d0f), TOBN(0xb03bbfc4, 0xea7f74e6), + TOBN(0x46a8c418, 0x0d738ded), TOBN(0x6f1a5bb0, 0xe0de5729), + TOBN(0xf10230b9, 0x8ba81675), TOBN(0x32c6f30c, 0x112b33d4), + TOBN(0x7559129d, 0xd8fffb62), TOBN(0x6a281b47, 0xb459bf05), + TOBN(0x77c1bd3a, 0xfa3b6776), TOBN(0x0709b380, 0x7829973a), + TOBN(0x8c26b232, 0xa3326505), TOBN(0x38d69272, 0xee1d41bf), + TOBN(0x0459453e, 0xffe32afa), TOBN(0xce8143ad, 0x7cb3ea87), + TOBN(0x932ec1fa, 0x7e6ab666), TOBN(0x6cd2d230, 0x22286264), + TOBN(0x459a46fe, 0x6736f8ed), TOBN(0x50bf0d00, 0x9eca85bb), + TOBN(0x0b825852, 0x877a21ec), TOBN(0x300414a7, 0x0f537a94), + TOBN(0x3f1cba40, 0x21a9a6a2), TOBN(0x50824eee, 0x76943c00), + TOBN(0xa0dbfcec, 0xf83cba5d), TOBN(0xf9538148, 0x93b4f3c0), + TOBN(0x61744162, 0x48f24dd7), TOBN(0x5322d64d, 0xe4fb09dd), + TOBN(0x57447384, 0x3d9325f3), TOBN(0xa9bef2d0, 0xf371cb84), + TOBN(0x77d2188b, 0xa61e36c5), TOBN(0xbbd6a7d7, 0xc602df72), + TOBN(0xba3aa902, 0x8f61bc0b), TOBN(0xf49085ed, 0x6ed0b6a1), + TOBN(0x8bc625d6, 0xae6e8298), TOBN(0x832b0b1d, 0xa2e9c01d), + TOBN(0xa337c447, 0xf1f0ced1), TOBN(0x800cc793, 0x9492dd2b), + TOBN(0x4b93151d, 0xbea08efa), TOBN(0x820cf3f8, 0xde0a741e), + TOBN(0xff1982dc, 0x1c0f7d13), TOBN(0xef921960, 0x84dde6ca), + TOBN(0x1ad7d972, 0x45f96ee3), TOBN(0x319c8dbe, 0x29dea0c7), + TOBN(0xd3ea3871, 0x7b82b99b), TOBN(0x75922d4d, 0x470eb624), + TOBN(0x8f66ec54, 0x3b95d466), TOBN(0x66e673cc, 0xbee1e346), + TOBN(0x6afe67c4, 0xb5f2b89a), TOBN(0x3de9c1e6, 0x290e5cd3), + TOBN(0x8c278bb6, 0x310a2ada), TOBN(0x420fa384, 0x0bdb323b), + TOBN(0x0ae1d63b, 0x0eb919b0), TOBN(0xd74ee51d, 0xa74b9620), + TOBN(0x395458d0, 0xa674290c), TOBN(0x324c930f, 0x4620a510), + TOBN(0x2d1f4d19, 0xfbac27d4), TOBN(0x4086e8ca, 0x9bedeeac), + TOBN(0x0cdd211b, 0x9b679ab8), TOBN(0x5970167d, 0x7090fec4), + TOBN(0x3420f2c9, 0xfaf1fc63), TOBN(0x616d333a, 0x328c8bb4), + TOBN(0x7d65364c, 0x57f1fe4a), TOBN(0x9343e877, 0x55e5c73a), + TOBN(0x5795176b, 0xe970e78c), TOBN(0xa36ccebf, 0x60533627), + TOBN(0xfc7c7380, 0x09cdfc1b), TOBN(0xb39a2afe, 0xb3fec326), + TOBN(0xb7ff1ba1, 0x6224408a), TOBN(0xcc856e92, 0x247cfc5e), + TOBN(0x01f102e7, 0xc18bc493), TOBN(0x4613ab74, 0x2091c727), + TOBN(0xaa25e89c, 0xc420bf2b), TOBN(0x00a53176, 0x90337ec2), + TOBN(0xd2be9f43, 0x7d025fc7), TOBN(0x3316fb85, 0x6e6fe3dc), + TOBN(0x27520af5, 0x9ac50814), TOBN(0xfdf95e78, 0x9a8e4223), + TOBN(0xb7e7df2a, 0x56bec5a0), TOBN(0xf7022f7d, 0xdf159e5d), + TOBN(0x93eeeab1, 0xcac1fe8f), TOBN(0x8040188c, 0x37451168), + TOBN(0x7ee8aa8a, 0xd967dce6), TOBN(0xfa0e79e7, 0x3abc9299), + TOBN(0x67332cfc, 0x2064cfd1), TOBN(0x339c31de, 0xb0651934), + TOBN(0x719b28d5, 0x2a3bcbea), TOBN(0xee74c82b, 0x9d6ae5c6), + TOBN(0x0927d05e, 0xbaf28ee6), TOBN(0x82cecf2c, 0x9d719028), + TOBN(0x0b0d353e, 0xddb30289), TOBN(0xfe4bb977, 0xfddb2e29), + TOBN(0xbb5bb990, 0x640bfd9e), TOBN(0xd226e277, 0x82f62108), + TOBN(0x4bf00985, 0x02ffdd56), TOBN(0x7756758a, 0x2ca1b1b5), + TOBN(0xc32b62a3, 0x5285fe91), TOBN(0xedbc546a, 0x8c9cd140), + TOBN(0x1e47a013, 0xaf5cb008), TOBN(0xbca7e720, 0x073ce8f2), + TOBN(0xe10b2ab8, 0x17a91cae), TOBN(0xb89aab65, 0x08e27f63), + TOBN(0x7b3074a7, 0xdba3ddf9), TOBN(0x1c20ce09, 0x330c2972), + TOBN(0x6b9917b4, 0x5fcf7e33), TOBN(0xe6793743, 0x945ceb42), + TOBN(0x18fc2215, 0x5c633d19), TOBN(0xad1adb3c, 0xc7485474), + TOBN(0x646f9679, 0x6424c49b), TOBN(0xf888dfe8, 0x67c241c9), + TOBN(0xe12d4b93, 0x24f68b49), TOBN(0x9a6b62d8, 0xa571df20), + TOBN(0x81b4b26d, 0x179483cb), TOBN(0x666f9632, 0x9511fae2), + TOBN(0xd281b3e4, 0xd53aa51f), TOBN(0x7f96a765, 0x7f3dbd16), + TOBN(0xa7f8b5bf, 0x074a30ce), TOBN(0xd7f52107, 0x005a32e6), + TOBN(0x6f9e0907, 0x50237ed4), TOBN(0x2f21da47, 0x8096fa2b), + TOBN(0xf3e19cb4, 0xeec863a0), TOBN(0xd18f77fd, 0x9527620a), + TOBN(0x9505c81c, 0x407c1cf8), TOBN(0x9998db4e, 0x1b6ec284), + TOBN(0x7e3389e5, 0xc247d44d), TOBN(0x12507141, 0x3f4f3d80), + TOBN(0xd4ba0110, 0x4a78a6c7), TOBN(0x312874a0, 0x767720be), + TOBN(0xded059a6, 0x75944370), TOBN(0xd6123d90, 0x3b2c0bdd), + TOBN(0xa56b717b, 0x51c108e3), TOBN(0x9bb7940e, 0x070623e9), + TOBN(0x794e2d59, 0x84ac066c), TOBN(0xf5954a92, 0xe68c69a0), + TOBN(0x28c52458, 0x4fd99dcc), TOBN(0x60e639fc, 0xb1012517), + TOBN(0xc2e60125, 0x7de79248), TOBN(0xe9ef6404, 0xf12fc6d7), + TOBN(0x4c4f2808, 0x2a3b5d32), TOBN(0x865ad32e, 0xc768eb8a), + TOBN(0xac02331b, 0x13fb70b6), TOBN(0x037b44c1, 0x95599b27), + TOBN(0x1a860fc4, 0x60bd082c), TOBN(0xa2e25745, 0xc980cd01), + TOBN(0xee3387a8, 0x1da0263e), TOBN(0x931bfb95, 0x2d10f3d6), + TOBN(0x5b687270, 0xa1f24a32), TOBN(0xf140e65d, 0xca494b86), + TOBN(0x4f4ddf91, 0xb2f1ac7a), TOBN(0xf99eaabb, 0x760fee27), + TOBN(0x57f4008a, 0x49c228e5), TOBN(0x090be440, 0x1cf713bb), + TOBN(0xac91fbe4, 0x5004f022), TOBN(0xd838c2c2, 0x569e1af6), + TOBN(0xd6c7d20b, 0x0f1daaa5), TOBN(0xaa063ac1, 0x1bbb02c0), + TOBN(0x0938a422, 0x59558a78), TOBN(0x5343c669, 0x8435da2f), + TOBN(0x96f67b18, 0x034410dc), TOBN(0x7cc1e424, 0x84510804), + TOBN(0x86a1543f, 0x16dfbb7d), TOBN(0x921fa942, 0x5b5bd592), + TOBN(0x9dcccb6e, 0xb33dd03c), TOBN(0x8581ddd9, 0xb843f51e), + TOBN(0x54935fcb, 0x81d73c9e), TOBN(0x6d07e979, 0x0a5e97ab), + TOBN(0x4dc7b30a, 0xcf3a6bab), TOBN(0x147ab1f3, 0x170bee11), + TOBN(0x0aaf8e3d, 0x9fafdee4), TOBN(0xfab3dbcb, 0x538a8b95), + TOBN(0x405df4b3, 0x6ef13871), TOBN(0xf1f4e9cb, 0x088d5a49), + TOBN(0x9bcd24d3, 0x66b33f1d), TOBN(0x3b97b820, 0x5ce445c0), + TOBN(0xe2926549, 0xba93ff61), TOBN(0xd9c341ce, 0x4dafe616), + TOBN(0xfb30a76e, 0x16efb6f3), TOBN(0xdf24b8ca, 0x605b953c), + TOBN(0x8bd52afe, 0xc2fffb9f), TOBN(0xbbac5ff7, 0xe19d0b96), + TOBN(0x43c01b87, 0x459afccd), TOBN(0x6bd45143, 0xb7432652), + TOBN(0x84734530, 0x55b5d78e), TOBN(0x81088fdb, 0x1554ba7d), + TOBN(0xada0a52c, 0x1e269375), TOBN(0xf9f037c4, 0x2dc5ec10), + TOBN(0xc0660607, 0x94bfbc11), TOBN(0xc0a630bb, 0xc9c40d2f), + TOBN(0x5efc797e, 0xab64c31e), TOBN(0xffdb1dab, 0x74507144), + TOBN(0xf6124287, 0x1ca6790c), TOBN(0xe9609d81, 0xe69bf1bf), + TOBN(0xdb898595, 0x00d24fc9), TOBN(0x9c750333, 0xe51fb417), + TOBN(0x51830a91, 0xfef7bbde), TOBN(0x0ce67dc8, 0x945f585c), + TOBN(0x9a730ed4, 0x4763eb50), TOBN(0x24a0e221, 0xc1ab0d66), + TOBN(0x643b6393, 0x648748f3), TOBN(0x1982daa1, 0x6d3c6291), + TOBN(0x6f00a9f7, 0x8bbc5549), TOBN(0x7a1783e1, 0x7f36384e), + TOBN(0xe8346323, 0xde977f50), TOBN(0x91ab688d, 0xb245502a), + TOBN(0x331ab6b5, 0x6d0bdd66), TOBN(0x0a6ef32e, 0x64b71229), + TOBN(0x1028150e, 0xfe7c352f), TOBN(0x27e04350, 0xce7b39d3), + TOBN(0x2a3c8acd, 0xc1070c82), TOBN(0xfb2034d3, 0x80c9feef), + TOBN(0x2d729621, 0x709f3729), TOBN(0x8df290bf, 0x62cb4549), + TOBN(0x02f99f33, 0xfc2e4326), TOBN(0x3b30076d, 0x5eddf032), + TOBN(0xbb21f8cf, 0x0c652fb5), TOBN(0x314fb49e, 0xed91cf7b), + TOBN(0xa013eca5, 0x2f700750), TOBN(0x2b9e3c23, 0x712a4575), + TOBN(0xe5355557, 0xaf30fbb0), TOBN(0x1ada3516, 0x7c77e771), + TOBN(0x45f6ecb2, 0x7b135670), TOBN(0xe85d19df, 0x7cfc202e), + TOBN(0x0f1b50c7, 0x58d1be9f), TOBN(0x5ebf2c0a, 0xead2e344), + TOBN(0x1531fe4e, 0xabc199c9), TOBN(0xc7032592, 0x56bab0ae), + TOBN(0x16ab2e48, 0x6c1fec54), TOBN(0x0f87fda8, 0x04280188), + TOBN(0xdc9f46fc, 0x609e4a74), TOBN(0x2a44a143, 0xba667f91), + TOBN(0xbc3d8b95, 0xb4d83436), TOBN(0xa01e4bd0, 0xc7bd2958), + TOBN(0x7b182932, 0x73483c90), TOBN(0xa79c6aa1, 0xa7c7b598), + TOBN(0xbf3983c6, 0xeaaac07e), TOBN(0x8f18181e, 0x96e0d4e6), + TOBN(0x8553d37c, 0x051af62b), TOBN(0xe9a998eb, 0x0bf94496), + TOBN(0xe0844f9f, 0xb0d59aa1), TOBN(0x983fd558, 0xe6afb813), + TOBN(0x9670c0ca, 0x65d69804), TOBN(0x732b22de, 0x6ea5ff2d), + TOBN(0xd7640ba9, 0x5fd8623b), TOBN(0x9f619163, 0xa6351782), + TOBN(0x0bfc27ee, 0xacee5043), TOBN(0xae419e73, 0x2eb10f02), + TOBN(0x19c028d1, 0x8943fb05), TOBN(0x71f01cf7, 0xff13aa2a), + TOBN(0x7790737e, 0x8887a132), TOBN(0x67513309, 0x66318410), + TOBN(0x9819e8a3, 0x7ddb795e), TOBN(0xfecb8ef5, 0xdad100b2), + TOBN(0x59f74a22, 0x3021926a), TOBN(0xb7c28a49, 0x6f9b4c1c), + TOBN(0xed1a733f, 0x912ad0ab), TOBN(0x42a910af, 0x01a5659c), + TOBN(0x3842c6e0, 0x7bd68cab), TOBN(0x2b57fa38, 0x76d70ac8), + TOBN(0x8a6707a8, 0x3c53aaeb), TOBN(0x62c1c510, 0x65b4db18), + TOBN(0x8de2c1fb, 0xb2d09dc7), TOBN(0xc3dfed12, 0x266bd23b), + TOBN(0x927d039b, 0xd5b27db6), TOBN(0x2fb2f0f1, 0x103243da), + TOBN(0xf855a07b, 0x80be7399), TOBN(0xed9327ce, 0x1f9f27a8), + TOBN(0xa0bd99c7, 0x729bdef7), TOBN(0x2b67125e, 0x28250d88), + TOBN(0x784b26e8, 0x8670ced7), TOBN(0xe3dfe41f, 0xc31bd3b4), + TOBN(0x9e353a06, 0xbcc85cbc), TOBN(0x302e2909, 0x60178a9d), + TOBN(0x860abf11, 0xa6eac16e), TOBN(0x76447000, 0xaa2b3aac), + TOBN(0x46ff9d19, 0x850afdab), TOBN(0x35bdd6a5, 0xfdb2d4c1), + TOBN(0xe82594b0, 0x7e5c9ce9), TOBN(0x0f379e53, 0x20af346e), + TOBN(0x608b31e3, 0xbc65ad4a), TOBN(0x710c6b12, 0x267c4826), + TOBN(0x51c966f9, 0x71954cf1), TOBN(0xb1cec793, 0x0d0aa215), + TOBN(0x1f155989, 0x86bd23a8), TOBN(0xae2ff99c, 0xf9452e86), + TOBN(0xd8dd953c, 0x340ceaa2), TOBN(0x26355275, 0x2e2e9333), + TOBN(0x15d4e5f9, 0x8586f06d), TOBN(0xd6bf94a8, 0xf7cab546), + TOBN(0x33c59a0a, 0xb76a9af0), TOBN(0x52740ab3, 0xba095af7), + TOBN(0xc444de8a, 0x24389ca0), TOBN(0xcc6f9863, 0x706da0cb), + TOBN(0xb5a741a7, 0x6b2515cf), TOBN(0x71c41601, 0x9585c749), + TOBN(0x78350d4f, 0xe683de97), TOBN(0x31d61524, 0x63d0b5f5), + TOBN(0x7a0cc5e1, 0xfbce090b), TOBN(0xaac927ed, 0xfbcb2a5b), + TOBN(0xe920de49, 0x20d84c35), TOBN(0x8c06a0b6, 0x22b4de26), + TOBN(0xd34dd58b, 0xafe7ddf3), TOBN(0x55851fed, 0xc1e6e55b), + TOBN(0xd1395616, 0x960696e7), TOBN(0x940304b2, 0x5f22705f), + TOBN(0x6f43f861, 0xb0a2a860), TOBN(0xcf121282, 0x0e7cc981), + TOBN(0x12186212, 0x0ab64a96), TOBN(0x09215b9a, 0xb789383c), + TOBN(0x311eb305, 0x37387c09), TOBN(0xc5832fce, 0xf03ee760), + TOBN(0x30358f58, 0x32f7ea19), TOBN(0xe01d3c34, 0x91d53551), + TOBN(0x1ca5ee41, 0xda48ea80), TOBN(0x34e71e8e, 0xcf4fa4c1), + TOBN(0x312abd25, 0x7af1e1c7), TOBN(0xe3afcdeb, 0x2153f4a5), + TOBN(0x9d5c84d7, 0x00235e9a), TOBN(0x0308d3f4, 0x8c4c836f), + TOBN(0xc0a66b04, 0x89332de5), TOBN(0x610dd399, 0x89e566ef), + TOBN(0xf8eea460, 0xd1ac1635), TOBN(0x84cbb3fb, 0x20a2c0df), + TOBN(0x40afb488, 0xe74a48c5), TOBN(0x29738198, 0xd326b150), + TOBN(0x2a17747f, 0xa6d74081), TOBN(0x60ea4c05, 0x55a26214), + TOBN(0x53514bb4, 0x1f88c5fe), TOBN(0xedd64567, 0x7e83426c), + TOBN(0xd5d6cbec, 0x96460b25), TOBN(0xa12fd0ce, 0x68dc115e), + TOBN(0xc5bc3ed2, 0x697840ea), TOBN(0x969876a8, 0xa6331e31), + TOBN(0x60c36217, 0x472ff580), TOBN(0xf4229705, 0x4ad41393), + TOBN(0x4bd99ef0, 0xa03b8b92), TOBN(0x501c7317, 0xc144f4f6), + TOBN(0x159009b3, 0x18464945), TOBN(0x6d5e594c, 0x74c5c6be), + TOBN(0x2d587011, 0x321a3660), TOBN(0xd1e184b1, 0x3898d022), + TOBN(0x5ba04752, 0x4c6a7e04), TOBN(0x47fa1e2b, 0x45550b65), + TOBN(0x9419daf0, 0x48c0a9a5), TOBN(0x66362953, 0x7c243236), + TOBN(0xcd0744b1, 0x5cb12a88), TOBN(0x561b6f9a, 0x2b646188), + TOBN(0x599415a5, 0x66c2c0c0), TOBN(0xbe3f0859, 0x0f83f09a), + TOBN(0x9141c5be, 0xb92041b8), TOBN(0x01ae38c7, 0x26477d0d), + TOBN(0xca8b71f3, 0xd12c7a94), TOBN(0xfab5b31f, 0x765c70db), + TOBN(0x76ae7492, 0x487443e9), TOBN(0x8595a310, 0x990d1349), + TOBN(0xf8dbeda8, 0x7d460a37), TOBN(0x7f7ad082, 0x1e45a38f), + TOBN(0xed1d4db6, 0x1059705a), TOBN(0xa3dd492a, 0xe6b9c697), + TOBN(0x4b92ee3a, 0x6eb38bd5), TOBN(0xbab2609d, 0x67cc0bb7), + TOBN(0x7fc4fe89, 0x6e70ee82), TOBN(0xeff2c56e, 0x13e6b7e3), + TOBN(0x9b18959e, 0x34d26fca), TOBN(0x2517ab66, 0x889d6b45), + TOBN(0xf167b4e0, 0xbdefdd4f), TOBN(0x69958465, 0xf366e401), + TOBN(0x5aa368ab, 0xa73bbec0), TOBN(0x12148709, 0x7b240c21), + TOBN(0x378c3233, 0x18969006), TOBN(0xcb4d73ce, 0xe1fe53d1), + TOBN(0x5f50a80e, 0x130c4361), TOBN(0xd67f5951, 0x7ef5212b), + TOBN(0xf145e21e, 0x9e70c72e), TOBN(0xb2e52e29, 0x5566d2fb), + TOBN(0x44eaba4a, 0x032397f5), TOBN(0x5e56937b, 0x7e31a7de), + TOBN(0x68dcf517, 0x456c61e1), TOBN(0xbc2e954a, 0xa8b0a388), + TOBN(0xe3552fa7, 0x60a8b755), TOBN(0x03442dae, 0x73ad0cde), + TOBN(0x37ffe747, 0xceb26210), TOBN(0x983545e8, 0x787baef9), + TOBN(0x8b8c8535, 0x86a3de31), TOBN(0xc621dbcb, 0xfacd46db), + TOBN(0x82e442e9, 0x59266fbb), TOBN(0xa3514c37, 0x339d471c), + TOBN(0x3a11b771, 0x62cdad96), TOBN(0xf0cb3b3c, 0xecf9bdf0), + TOBN(0x3fcbdbce, 0x478e2135), TOBN(0x7547b5cf, 0xbda35342), + TOBN(0xa97e81f1, 0x8a677af6), TOBN(0xc8c2bf83, 0x28817987), + TOBN(0xdf07eaaf, 0x45580985), TOBN(0xc68d1f05, 0xc93b45cb), + TOBN(0x106aa2fe, 0xc77b4cac), TOBN(0x4c1d8afc, 0x04a7ae86), + TOBN(0xdb41c3fd, 0x9eb45ab2), TOBN(0x5b234b5b, 0xd4b22e74), + TOBN(0xda253dec, 0xf215958a), TOBN(0x67e0606e, 0xa04edfa0), + TOBN(0xabbbf070, 0xef751b11), TOBN(0xf352f175, 0xf6f06dce), + TOBN(0xdfc4b6af, 0x6839f6b4), TOBN(0x53ddf9a8, 0x9959848e), + TOBN(0xda49c379, 0xc21520b0), TOBN(0x90864ff0, 0xdbd5d1b6), + TOBN(0x2f055d23, 0x5f49c7f7), TOBN(0xe51e4e6a, 0xa796b2d8), + TOBN(0xc361a67f, 0x5c9dc340), TOBN(0x5ad53c37, 0xbca7c620), + TOBN(0xda1d6588, 0x32c756d0), TOBN(0xad60d911, 0x8bb67e13), + TOBN(0xd6c47bdf, 0x0eeec8c6), TOBN(0x4a27fec1, 0x078a1821), + TOBN(0x081f7415, 0xc3099524), TOBN(0x8effdf0b, 0x82cd8060), + TOBN(0xdb70ec1c, 0x65842df8), TOBN(0x8821b358, 0xd319a901), + TOBN(0x72ee56ee, 0xde42b529), TOBN(0x5bb39592, 0x236e4286), + TOBN(0xd1183316, 0xfd6f7140), TOBN(0xf9fadb5b, 0xbd8e81f7), + TOBN(0x701d5e0c, 0x5a02d962), TOBN(0xfdee4dbf, 0x1b601324), + TOBN(0xbed17407, 0x35d7620e), TOBN(0x04e3c2c3, 0xf48c0012), + TOBN(0x9ee29da7, 0x3455449a), TOBN(0x562cdef4, 0x91a836c4), + TOBN(0x8f682a5f, 0x47701097), TOBN(0x617125d8, 0xff88d0c2), + TOBN(0x948fda24, 0x57bb86dd), TOBN(0x348abb8f, 0x289f7286), + TOBN(0xeb10eab5, 0x99d94bbd), TOBN(0xd51ba28e, 0x4684d160), + TOBN(0xabe0e51c, 0x30c8f41a), TOBN(0x66588b45, 0x13254f4a), + TOBN(0x147ebf01, 0xfad097a5), TOBN(0x49883ea8, 0x610e815d), + TOBN(0xe44d60ba, 0x8a11de56), TOBN(0xa970de6e, 0x827a7a6d), + TOBN(0x2be41424, 0x5e17fc19), TOBN(0xd833c657, 0x01214057), + TOBN(0x1375813b, 0x363e723f), TOBN(0x6820bb88, 0xe6a52e9b), + TOBN(0x7e7f6970, 0xd875d56a), TOBN(0xd6a0a9ac, 0x51fbf6bf), + TOBN(0x54ba8790, 0xa3083c12), TOBN(0xebaeb23d, 0x6ae7eb64), + TOBN(0xa8685c3a, 0xb99a907a), TOBN(0xf1e74550, 0x026bf40b), + TOBN(0x7b73a027, 0xc802cd9e), TOBN(0x9a8a927c, 0x4fef4635), + TOBN(0xe1b6f60c, 0x08191224), TOBN(0xc4126ebb, 0xde4ec091), + TOBN(0xe1dff4dc, 0x4ae38d84), TOBN(0xde3f57db, 0x4f2ef985), + TOBN(0x34964337, 0xd446a1dd), TOBN(0x7bf217a0, 0x859e77f6), + TOBN(0x8ff10527, 0x8e1d13f5), TOBN(0xa304ef03, 0x74eeae27), + TOBN(0xfc6f5e47, 0xd19dfa5a), TOBN(0xdb007de3, 0x7fad982b), + TOBN(0x28205ad1, 0x613715f5), TOBN(0x251e6729, 0x7889529e), + TOBN(0x72705184, 0x1ae98e78), TOBN(0xf818537d, 0x271cac32), + TOBN(0xc8a15b7e, 0xb7f410f5), TOBN(0xc474356f, 0x81f62393), + TOBN(0x92dbdc5a, 0xc242316b), TOBN(0xabe060ac, 0xdbf4aff5), + TOBN(0x6e8c38fe, 0x909a8ec6), TOBN(0x43e514e5, 0x6116cb94), + TOBN(0x2078fa38, 0x07d784f9), TOBN(0x1161a880, 0xf4b5b357), + TOBN(0x5283ce79, 0x13adea3d), TOBN(0x0756c3e6, 0xcc6a910b), + TOBN(0x60bcfe01, 0xaaa79697), TOBN(0x04a73b29, 0x56391db1), + TOBN(0xdd8dad47, 0x189b45a0), TOBN(0xbfac0dd0, 0x48d5b8d9), + TOBN(0x34ab3af5, 0x7d3d2ec2), TOBN(0x6fa2fc2d, 0x207bd3af), + TOBN(0x9ff40092, 0x66550ded), TOBN(0x719b3e87, 0x1fd5b913), + TOBN(0xa573a496, 0x6d17fbc7), TOBN(0x0cd1a70a, 0x73d2b24e), + TOBN(0x34e2c5ca, 0xb2676937), TOBN(0xe7050b06, 0xbf669f21), + TOBN(0xfbe948b6, 0x1ede9046), TOBN(0xa0530051, 0x97662659), + TOBN(0x58cbd4ed, 0xf10124c5), TOBN(0xde2646e4, 0xdd6c06c8), + TOBN(0x332f8108, 0x8cad38c0), TOBN(0x471b7e90, 0x6bd68ae2), + TOBN(0x56ac3fb2, 0x0d8e27a3), TOBN(0xb54660db, 0x136b4b0d), + TOBN(0x123a1e11, 0xa6fd8de4), TOBN(0x44dbffea, 0xa37799ef), + TOBN(0x4540b977, 0xce6ac17c), TOBN(0x495173a8, 0xaf60acef)}, + {TOBN(0x9ebb284d, 0x391c2a82), TOBN(0xbcdd4863, 0x158308e8), + TOBN(0x006f16ec, 0x83f1edca), TOBN(0xa13e2c37, 0x695dc6c8), + TOBN(0x2ab756f0, 0x4a057a87), TOBN(0xa8765500, 0xa6b48f98), + TOBN(0x4252face, 0x68651c44), TOBN(0xa52b540b, 0xe1765e02), + TOBN(0x4f922fc5, 0x16a0d2bb), TOBN(0x0d5cc16c, 0x1a623499), + TOBN(0x9241cf3a, 0x57c62c8b), TOBN(0x2f5e6961, 0xfd1b667f), + TOBN(0x5c15c70b, 0xf5a01797), TOBN(0x3d20b44d, 0x60956192), + TOBN(0x04911b37, 0x071fdb52), TOBN(0xf648f916, 0x8d6f0f7b), + TOBN(0x6dc1acaf, 0xe60b7cf7), TOBN(0x25860a50, 0x84a9d869), + TOBN(0x56fc6f09, 0xe7ba8ac4), TOBN(0x828c5bd0, 0x6148d29e), + TOBN(0xac6b435e, 0xdc55ae5f), TOBN(0xa527f56c, 0xc0117411), + TOBN(0x94d5045e, 0xfd24342c), TOBN(0x2c4c0a35, 0x70b67c0d), + TOBN(0x027cc8b8, 0xfac61d9a), TOBN(0x7d25e062, 0xe3c6fe8a), + TOBN(0xe08805bf, 0xe5bff503), TOBN(0x13271e6c, 0x6ff632f7), + TOBN(0x55dca6c0, 0x232f76a5), TOBN(0x8957c32d, 0x701ef426), + TOBN(0xee728bcb, 0xa10a5178), TOBN(0x5ea60411, 0xb62c5173), + TOBN(0xfc4e964e, 0xd0b8892b), TOBN(0x9ea17683, 0x9301bb74), + TOBN(0x6265c5ae, 0xfcc48626), TOBN(0xe60cf82e, 0xbb3e9102), + TOBN(0x57adf797, 0xd4df5531), TOBN(0x235b59a1, 0x8deeefe2), + TOBN(0x60adcf58, 0x3f306eb1), TOBN(0x105c2753, 0x3d09492d), + TOBN(0x4090914b, 0xb5def996), TOBN(0x1cb69c83, 0x233dd1e7), + TOBN(0xc1e9c1d3, 0x9b3d5e76), TOBN(0x1f3338ed, 0xfccf6012), + TOBN(0xb1e95d0d, 0x2f5378a8), TOBN(0xacf4c2c7, 0x2f00cd21), + TOBN(0x6e984240, 0xeb5fe290), TOBN(0xd66c038d, 0x248088ae), + TOBN(0x804d264a, 0xf94d70cf), TOBN(0xbdb802ef, 0x7314bf7e), + TOBN(0x8fb54de2, 0x4333ed02), TOBN(0x740461e0, 0x285635d9), + TOBN(0x4113b2c8, 0x365e9383), TOBN(0xea762c83, 0x3fdef652), + TOBN(0x4eec6e2e, 0x47b956c1), TOBN(0xa3d814be, 0x65620fa4), + TOBN(0x9ad5462b, 0xb4d8bc50), TOBN(0x181c0b16, 0xa9195770), + TOBN(0xebd4fe1c, 0x78412a68), TOBN(0xae0341bc, 0xc0dff48c), + TOBN(0xb6bc45cf, 0x7003e866), TOBN(0xf11a6dea, 0x8a24a41b), + TOBN(0x5407151a, 0xd04c24c2), TOBN(0x62c9d27d, 0xda5b7b68), + TOBN(0x2e964235, 0x88cceff6), TOBN(0x8594c54f, 0x8b07ed69), + TOBN(0x1578e73c, 0xc84d0d0d), TOBN(0x7b4e1055, 0xff532868), + TOBN(0xa348c0d5, 0xb5ec995a), TOBN(0xbf4b9d55, 0x14289a54), + TOBN(0x9ba155a6, 0x58fbd777), TOBN(0x186ed7a8, 0x1a84491d), + TOBN(0xd4992b30, 0x614c0900), TOBN(0xda98d121, 0xbd00c24b), + TOBN(0x7f534dc8, 0x7ec4bfa1), TOBN(0x4a5ff674, 0x37dc34bc), + TOBN(0x68c196b8, 0x1d7ea1d7), TOBN(0x38cf2893, 0x80a6d208), + TOBN(0xfd56cd09, 0xe3cbbd6e), TOBN(0xec72e27e, 0x4205a5b6), + TOBN(0x15ea68f5, 0xa44f77f7), TOBN(0x7aa5f9fd, 0xb43c52bc), + TOBN(0x86ff676f, 0x94f0e609), TOBN(0xa4cde963, 0x2e2d432b), + TOBN(0x8cafa0c0, 0xeee470af), TOBN(0x84137d0e, 0x8a3f5ec8), + TOBN(0xebb40411, 0xfaa31231), TOBN(0xa239c13f, 0x6f7f7ccf), + TOBN(0x32865719, 0xa8afd30b), TOBN(0x86798328, 0x8a826dce), + TOBN(0xdf04e891, 0xc4a8fbe0), TOBN(0xbb6b6e1b, 0xebf56ad3), + TOBN(0x0a695b11, 0x471f1ff0), TOBN(0xd76c3389, 0xbe15baf0), + TOBN(0x018edb95, 0xbe96c43e), TOBN(0xf2beaaf4, 0x90794158), + TOBN(0x152db09e, 0xc3076a27), TOBN(0x5e82908e, 0xe416545d), + TOBN(0xa2c41272, 0x356d6f2e), TOBN(0xdc9c9642, 0x31fd74e1), + TOBN(0x66ceb88d, 0x519bf615), TOBN(0xe29ecd76, 0x05a2274e), + TOBN(0x3a0473c4, 0xbf5e2fa0), TOBN(0x6b6eb671, 0x64284e67), + TOBN(0xe8b97932, 0xb88756dd), TOBN(0xed4e8652, 0xf17e3e61), + TOBN(0xc2dd1499, 0x3ee1c4a4), TOBN(0xc0aaee17, 0x597f8c0e), + TOBN(0x15c4edb9, 0x6c168af3), TOBN(0x6563c7bf, 0xb39ae875), + TOBN(0xadfadb6f, 0x20adb436), TOBN(0xad55e8c9, 0x9a042ac0), + TOBN(0x975a1ed8, 0xb76da1f5), TOBN(0x10dfa466, 0xa58acb94), + TOBN(0x8dd7f7e3, 0xac060282), TOBN(0x6813e66a, 0x572a051e), + TOBN(0xb4ccae1e, 0x350cb901), TOBN(0xb653d656, 0x50cb7822), + TOBN(0x42484710, 0xdfab3b87), TOBN(0xcd7ee537, 0x9b670fd0), + TOBN(0x0a50b12e, 0x523b8bf6), TOBN(0x8009eb5b, 0x8f910c1b), + TOBN(0xf535af82, 0x4a167588), TOBN(0x0f835f9c, 0xfb2a2abd), + TOBN(0xf59b2931, 0x2afceb62), TOBN(0xc797df2a, 0x169d383f), + TOBN(0xeb3f5fb0, 0x66ac02b0), TOBN(0x029d4c6f, 0xdaa2d0ca), + TOBN(0xd4059bc1, 0xafab4bc5), TOBN(0x833f5c6f, 0x56783247), + TOBN(0xb5346630, 0x8d2d3605), TOBN(0x83387891, 0xd34d8433), + TOBN(0xd973b30f, 0xadd9419a), TOBN(0xbcca1099, 0xafe3fce8), + TOBN(0x08178315, 0x0809aac6), TOBN(0x01b7f21a, 0x540f0f11), + TOBN(0x65c29219, 0x909523c8), TOBN(0xa62f648f, 0xa3a1c741), + TOBN(0x88598d4f, 0x60c9e55a), TOBN(0xbce9141b, 0x0e4f347a), + TOBN(0x9af97d84, 0x35f9b988), TOBN(0x0210da62, 0x320475b6), + TOBN(0x3c076e22, 0x9191476c), TOBN(0x7520dbd9, 0x44fc7834), + TOBN(0x6a6b2cfe, 0xc1ab1bbd), TOBN(0xef8a65be, 0xdc650938), + TOBN(0x72855540, 0x805d7bc4), TOBN(0xda389396, 0xed11fdfd), + TOBN(0xa9d5bd36, 0x74660876), TOBN(0x11d67c54, 0xb45dff35), + TOBN(0x6af7d148, 0xa4f5da94), TOBN(0xbb8d4c3f, 0xc0bbeb31), + TOBN(0x87a7ebd1, 0xe0a1b12a), TOBN(0x1e4ef88d, 0x770ba95f), + TOBN(0x8c33345c, 0xdc2ae9cb), TOBN(0xcecf1276, 0x01cc8403), + TOBN(0x687c012e, 0x1b39b80f), TOBN(0xfd90d0ad, 0x35c33ba4), + TOBN(0xa3ef5a67, 0x5c9661c2), TOBN(0x368fc88e, 0xe017429e), + TOBN(0xd30c6761, 0x196a2fa2), TOBN(0x931b9817, 0xbd5b312e), + TOBN(0xba01000c, 0x72f54a31), TOBN(0xa203d2c8, 0x66eaa541), + TOBN(0xf2abdee0, 0x98939db3), TOBN(0xe37d6c2c, 0x3e606c02), + TOBN(0xf2921574, 0x521ff643), TOBN(0x2781b3c4, 0xd7e2fca3), + TOBN(0x664300b0, 0x7850ec06), TOBN(0xac5a38b9, 0x7d3a10cf), + TOBN(0x9233188d, 0xe34ab39d), TOBN(0xe77057e4, 0x5072cbb9), + TOBN(0xbcf0c042, 0xb59e78df), TOBN(0x4cfc91e8, 0x1d97de52), + TOBN(0x4661a26c, 0x3ee0ca4a), TOBN(0x5620a4c1, 0xfb8507bc), + TOBN(0x4b44d4aa, 0x049f842c), TOBN(0xceabc5d5, 0x1540e82b), + TOBN(0x306710fd, 0x15c6f156), TOBN(0xbe5ae52b, 0x63db1d72), + TOBN(0x06f1e7e6, 0x334957f1), TOBN(0x57e388f0, 0x31144a70), + TOBN(0xfb69bb2f, 0xdf96447b), TOBN(0x0f78ebd3, 0x73e38a12), + TOBN(0xb8222605, 0x2b7ce542), TOBN(0xe6d4ce99, 0x7472bde1), + TOBN(0x53e16ebe, 0x09d2f4da), TOBN(0x180ff42e, 0x53b92b2e), + TOBN(0xc59bcc02, 0x2c34a1c6), TOBN(0x3803d6f9, 0x422c46c2), + TOBN(0x18aff74f, 0x5c14a8a2), TOBN(0x55aebf80, 0x10a08b28), + TOBN(0x66097d58, 0x7135593f), TOBN(0x32e6eff7, 0x2be570cd), + TOBN(0x584e6a10, 0x2a8c860d), TOBN(0xcd185890, 0xa2eb4163), + TOBN(0x7ceae99d, 0x6d97e134), TOBN(0xd42c6b70, 0xdd8447ce), + TOBN(0x59ddbb4a, 0xb8c50273), TOBN(0x03c612df, 0x3cf34e1e), + TOBN(0x84b9ca15, 0x04b6c5a0), TOBN(0x35216f39, 0x18f0e3a3), + TOBN(0x3ec2d2bc, 0xbd986c00), TOBN(0x8bf546d9, 0xd19228fe), + TOBN(0xd1c655a4, 0x4cd623c3), TOBN(0x366ce718, 0x502b8e5a), + TOBN(0x2cfc84b4, 0xeea0bfe7), TOBN(0xe01d5cee, 0xcf443e8e), + TOBN(0x8ec045d9, 0x036520f8), TOBN(0xdfb3c3d1, 0x92d40e98), + TOBN(0x0bac4cce, 0xcc559a04), TOBN(0x35eccae5, 0x240ea6b1), + TOBN(0x180b32db, 0xf8a5a0ac), TOBN(0x547972a5, 0xeb699700), + TOBN(0xa3765801, 0xca26bca0), TOBN(0x57e09d0e, 0xa647f25a), + TOBN(0xb956970e, 0x2fdd23cc), TOBN(0xb80288bc, 0x5682e971), + TOBN(0xe6e6d91e, 0x9ae86ebc), TOBN(0x0564c83f, 0x8c9f1939), + TOBN(0x551932a2, 0x39560368), TOBN(0xe893752b, 0x049c28e2), + TOBN(0x0b03cee5, 0xa6a158c3), TOBN(0xe12d656b, 0x04964263), + TOBN(0x4b47554e, 0x63e3bc1d), TOBN(0xc719b6a2, 0x45044ff7), + TOBN(0x4f24d30a, 0xe48daa07), TOBN(0xa3f37556, 0xc8c1edc3), + TOBN(0x9a47bf76, 0x0700d360), TOBN(0xbb1a1824, 0x822ae4e2), + TOBN(0x22e275a3, 0x89f1fb4c), TOBN(0x72b1aa23, 0x9968c5f5), + TOBN(0xa75feaca, 0xbe063f64), TOBN(0x9b392f43, 0xbce47a09), + TOBN(0xd4241509, 0x1ad07aca), TOBN(0x4b0c591b, 0x8d26cd0f), + TOBN(0x2d42ddfd, 0x92f1169a), TOBN(0x63aeb1ac, 0x4cbf2392), + TOBN(0x1de9e877, 0x0691a2af), TOBN(0xebe79af7, 0xd98021da), + TOBN(0xcfdf2a4e, 0x40e50acf), TOBN(0xf0a98ad7, 0xaf01d665), + TOBN(0xefb640bf, 0x1831be1f), TOBN(0x6fe8bd2f, 0x80e9ada0), + TOBN(0x94c103a1, 0x6cafbc91), TOBN(0x170f8759, 0x8308e08c), + TOBN(0x5de2d2ab, 0x9780ff4f), TOBN(0x666466bc, 0x45b201f2), + TOBN(0x58af2010, 0xf5b343bc), TOBN(0x0f2e400a, 0xf2f142fe), + TOBN(0x3483bfde, 0xa85f4bdf), TOBN(0xf0b1d093, 0x03bfeaa9), + TOBN(0x2ea01b95, 0xc7081603), TOBN(0xe943e4c9, 0x3dba1097), + TOBN(0x47be92ad, 0xb438f3a6), TOBN(0x00bb7742, 0xe5bf6636), + TOBN(0x136b7083, 0x824297b4), TOBN(0x9d0e5580, 0x5584455f), + TOBN(0xab48cedc, 0xf1c7d69e), TOBN(0x53a9e481, 0x2a256e76), + TOBN(0x0402b0e0, 0x65eb2413), TOBN(0xdadbbb84, 0x8fc407a7), + TOBN(0xa65cd5a4, 0x8d7f5492), TOBN(0x21d44293, 0x74bae294), + TOBN(0x66917ce6, 0x3b5f1cc4), TOBN(0x37ae52ea, 0xce872e62), + TOBN(0xbb087b72, 0x2905f244), TOBN(0x12077086, 0x1e6af74f), + TOBN(0x4b644e49, 0x1058edea), TOBN(0x827510e3, 0xb638ca1d), + TOBN(0x8cf2b704, 0x6038591c), TOBN(0xffc8b47a, 0xfe635063), + TOBN(0x3ae220e6, 0x1b4d5e63), TOBN(0xbd864742, 0x9d961b4b), + TOBN(0x610c107e, 0x9bd16bed), TOBN(0x4270352a, 0x1127147b), + TOBN(0x7d17ffe6, 0x64cfc50e), TOBN(0x50dee01a, 0x1e36cb42), + TOBN(0x068a7622, 0x35dc5f9a), TOBN(0x9a08d536, 0xdf53f62c), + TOBN(0x4ed71457, 0x6be5f7de), TOBN(0xd93006f8, 0xc2263c9e), + TOBN(0xe073694c, 0xcacacb36), TOBN(0x2ff7a5b4, 0x3ae118ab), + TOBN(0x3cce53f1, 0xcd871236), TOBN(0xf156a39d, 0xc2aa6d52), + TOBN(0x9cc5f271, 0xb198d76d), TOBN(0xbc615b6f, 0x81383d39), + TOBN(0xa54538e8, 0xde3eee6b), TOBN(0x58c77538, 0xab910d91), + TOBN(0x31e5bdbc, 0x58d278bd), TOBN(0x3cde4adf, 0xb963acae), + TOBN(0xb1881fd2, 0x5302169c), TOBN(0x8ca60fa0, 0xa989ed8b), + TOBN(0xa1999458, 0xff96a0ee), TOBN(0xc1141f03, 0xac6c283d), + TOBN(0x7677408d, 0x6dfafed3), TOBN(0x33a01653, 0x39661588), + TOBN(0x3c9c15ec, 0x0b726fa0), TOBN(0x090cfd93, 0x6c9b56da), + TOBN(0xe34f4bae, 0xa3c40af5), TOBN(0x3469eadb, 0xd21129f1), + TOBN(0xcc51674a, 0x1e207ce8), TOBN(0x1e293b24, 0xc83b1ef9), + TOBN(0x17173d13, 0x1e6c0bb4), TOBN(0x19004695, 0x90776d35), + TOBN(0xe7980e34, 0x6de6f922), TOBN(0x873554cb, 0xf4dd9a22), + TOBN(0x0316c627, 0xcbf18a51), TOBN(0x4d93651b, 0x3032c081), + TOBN(0x207f2771, 0x3946834d), TOBN(0x2c08d7b4, 0x30cdbf80), + TOBN(0x137a4fb4, 0x86df2a61), TOBN(0xa1ed9c07, 0xecf7b4a2), + TOBN(0xb2e460e2, 0x7bd042ff), TOBN(0xb7f5e2fa, 0x5f62f5ec), + TOBN(0x7aa6ec6b, 0xcc2423b7), TOBN(0x75ce0a7f, 0xba63eea7), + TOBN(0x67a45fb1, 0xf250a6e1), TOBN(0x93bc919c, 0xe53cdc9f), + TOBN(0x9271f56f, 0x871942df), TOBN(0x2372ff6f, 0x7859ad66), + TOBN(0x5f4c2b96, 0x33cb1a78), TOBN(0xe3e29101, 0x5838aa83), + TOBN(0xa7ed1611, 0xe4e8110c), TOBN(0x2a2d70d5, 0x330198ce), + TOBN(0xbdf132e8, 0x6720efe0), TOBN(0xe61a8962, 0x66a471bf), + TOBN(0x796d3a85, 0x825808bd), TOBN(0x51dc3cb7, 0x3fd6e902), + TOBN(0x643c768a, 0x916219d1), TOBN(0x36cd7685, 0xa2ad7d32), + TOBN(0xe3db9d05, 0xb22922a4), TOBN(0x6494c87e, 0xdba29660), + TOBN(0xf0ac91df, 0xbcd2ebc7), TOBN(0x4deb57a0, 0x45107f8d), + TOBN(0x42271f59, 0xc3d12a73), TOBN(0x5f71687c, 0xa5c2c51d), + TOBN(0xcb1f50c6, 0x05797bcb), TOBN(0x29ed0ed9, 0xd6d34eb0), + TOBN(0xe5fe5b47, 0x4683c2eb), TOBN(0x4956eeb5, 0x97447c46), + TOBN(0x5b163a43, 0x71207167), TOBN(0x93fa2fed, 0x0248c5ef), + TOBN(0x67930af2, 0x31f63950), TOBN(0xa77797c1, 0x14caa2c9), + TOBN(0x526e80ee, 0x27ac7e62), TOBN(0xe1e6e626, 0x58b28aec), + TOBN(0x636178b0, 0xb3c9fef0), TOBN(0xaf7752e0, 0x6d5f90be), + TOBN(0x94ecaf18, 0xeece51cf), TOBN(0x2864d0ed, 0xca806e1f), + TOBN(0x6de2e383, 0x97c69134), TOBN(0x5a42c316, 0xeb291293), + TOBN(0xc7779219, 0x6a60bae0), TOBN(0xa24de346, 0x6b7599d1), + TOBN(0x49d374aa, 0xb75d4941), TOBN(0x98900586, 0x2d501ff0), + TOBN(0x9f16d40e, 0xeb7974cf), TOBN(0x1033860b, 0xcdd8c115), + TOBN(0xb6c69ac8, 0x2094cec3), TOBN(0x9976fb88, 0x403b770c), + TOBN(0x1dea026c, 0x4859590d), TOBN(0xb6acbb46, 0x8562d1fd), + TOBN(0x7cd6c461, 0x44569d85), TOBN(0xc3190a36, 0x97f0891d), + TOBN(0xc6f53195, 0x48d5a17d), TOBN(0x7d919966, 0xd749abc8), + TOBN(0x65104837, 0xdd1c8a20), TOBN(0x7e5410c8, 0x2f683419), + TOBN(0x958c3ca8, 0xbe94022e), TOBN(0x605c3197, 0x6145dac2), + TOBN(0x3fc07501, 0x01683d54), TOBN(0x1d7127c5, 0x595b1234), + TOBN(0x10b8f87c, 0x9481277f), TOBN(0x677db2a8, 0xe65a1adb), + TOBN(0xec2fccaa, 0xddce3345), TOBN(0x2a6811b7, 0x012a4350), + TOBN(0x96760ff1, 0xac598bdc), TOBN(0x054d652a, 0xd1bf4128), + TOBN(0x0a1151d4, 0x92a21005), TOBN(0xad7f3971, 0x33110fdf), + TOBN(0x8c95928c, 0x1960100f), TOBN(0x6c91c825, 0x7bf03362), + TOBN(0xc8c8b2a2, 0xce309f06), TOBN(0xfdb27b59, 0xca27204b), + TOBN(0xd223eaa5, 0x0848e32e), TOBN(0xb93e4b2e, 0xe7bfaf1e), + TOBN(0xc5308ae6, 0x44aa3ded), TOBN(0x317a666a, 0xc015d573), + TOBN(0xc888ce23, 0x1a979707), TOBN(0xf141c1e6, 0x0d5c4958), + TOBN(0xb53b7de5, 0x61906373), TOBN(0x858dbade, 0xeb999595), + TOBN(0x8cbb47b2, 0xa59e5c36), TOBN(0x660318b3, 0xdcf4e842), + TOBN(0xbd161ccd, 0x12ba4b7a), TOBN(0xf399daab, 0xf8c8282a), + TOBN(0x1587633a, 0xeeb2130d), TOBN(0xa465311a, 0xda38dd7d), + TOBN(0x5f75eec8, 0x64d3779b), TOBN(0x3c5d0476, 0xad64c171), + TOBN(0x87410371, 0x2a914428), TOBN(0x8096a891, 0x90e2fc29), + TOBN(0xd3d2ae9d, 0x23b3ebc2), TOBN(0x90bdd6db, 0xa580cfd6), + TOBN(0x52dbb7f3, 0xc5b01f6c), TOBN(0xe68eded4, 0xe102a2dc), + TOBN(0x17785b77, 0x99eb6df0), TOBN(0x26c3cc51, 0x7386b779), + TOBN(0x345ed988, 0x6417a48e), TOBN(0xe990b4e4, 0x07d6ef31), + TOBN(0x0f456b7e, 0x2586abba), TOBN(0x239ca6a5, 0x59c96e9a), + TOBN(0xe327459c, 0xe2eb4206), TOBN(0x3a4c3313, 0xa002b90a), + TOBN(0x2a114806, 0xf6a3f6fb), TOBN(0xad5cad2f, 0x85c251dd), + TOBN(0x92c1f613, 0xf5a784d3), TOBN(0xec7bfacf, 0x349766d5), + TOBN(0x04b3cd33, 0x3e23cb3b), TOBN(0x3979fe84, 0xc5a64b2d), + TOBN(0x192e2720, 0x7e589106), TOBN(0xa60c43d1, 0xa15b527f), + TOBN(0x2dae9082, 0xbe7cf3a6), TOBN(0xcc86ba92, 0xbc967274), + TOBN(0xf28a2ce8, 0xaea0a8a9), TOBN(0x404ca6d9, 0x6ee988b3), + TOBN(0xfd7e9c5d, 0x005921b8), TOBN(0xf56297f1, 0x44e79bf9), + TOBN(0xa163b460, 0x0d75ddc2), TOBN(0x30b23616, 0xa1f2be87), + TOBN(0x4b070d21, 0xbfe50e2b), TOBN(0x7ef8cfd0, 0xe1bfede1), + TOBN(0xadba0011, 0x2aac4ae0), TOBN(0x2a3e7d01, 0xb9ebd033), + TOBN(0x995277ec, 0xe38d9d1c), TOBN(0xb500249e, 0x9c5d2de3), + TOBN(0x8912b820, 0xf13ca8c9), TOBN(0xc8798114, 0x877793af), + TOBN(0x19e6125d, 0xec3f1dec), TOBN(0x07b1f040, 0x911178da), + TOBN(0xd93ededa, 0x904a6738), TOBN(0x55187a5a, 0x0bebedcd), + TOBN(0xf7d04722, 0xeb329d41), TOBN(0xf449099e, 0xf170b391), + TOBN(0xfd317a69, 0xca99f828), TOBN(0x50c3db2b, 0x34a4976d), + TOBN(0xe9ba7784, 0x3757b392), TOBN(0x326caefd, 0xaa3ca05a), + TOBN(0x78e5293b, 0xf1e593d4), TOBN(0x7842a937, 0x0d98fd13), + TOBN(0xe694bf96, 0x5f96b10d), TOBN(0x373a9df6, 0x06a8cd05), + TOBN(0x997d1e51, 0xe8f0c7fc), TOBN(0x1d019790, 0x63fd972e), + TOBN(0x0064d858, 0x5499fb32), TOBN(0x7b67bad9, 0x77a8aeb7), + TOBN(0x1d3eb977, 0x2d08eec5), TOBN(0x5fc047a6, 0xcbabae1d), + TOBN(0x0577d159, 0xe54a64bb), TOBN(0x8862201b, 0xc43497e4), + TOBN(0xad6b4e28, 0x2ce0608d), TOBN(0x8b687b7d, 0x0b167aac), + TOBN(0x6ed4d367, 0x8b2ecfa9), TOBN(0x24dfe62d, 0xa90c3c38), + TOBN(0xa1862e10, 0x3fe5c42b), TOBN(0x1ca73dca, 0xd5732a9f), + TOBN(0x35f038b7, 0x76bb87ad), TOBN(0x674976ab, 0xf242b81f), + TOBN(0x4f2bde7e, 0xb0fd90cd), TOBN(0x6efc172e, 0xa7fdf092), + TOBN(0x3806b69b, 0x92222f1f), TOBN(0x5a2459ca, 0x6cf7ae70), + TOBN(0x6789f69c, 0xa85217ee), TOBN(0x5f232b5e, 0xe3dc85ac), + TOBN(0x660e3ec5, 0x48e9e516), TOBN(0x124b4e47, 0x3197eb31), + TOBN(0x10a0cb13, 0xaafcca23), TOBN(0x7bd63ba4, 0x8213224f), + TOBN(0xaffad7cc, 0x290a7f4f), TOBN(0x6b409c9e, 0x0286b461), + TOBN(0x58ab809f, 0xffa407af), TOBN(0xc3122eed, 0xc68ac073), + TOBN(0x17bf9e50, 0x4ef24d7e), TOBN(0x5d929794, 0x3e2a5811), + TOBN(0x519bc867, 0x02902e01), TOBN(0x76bba5da, 0x39c8a851), + TOBN(0xe9f9669c, 0xda94951e), TOBN(0x4b6af58d, 0x66b8d418), + TOBN(0xfa321074, 0x17d426a4), TOBN(0xc78e66a9, 0x9dde6027), + TOBN(0x0516c083, 0x4a53b964), TOBN(0xfc659d38, 0xff602330), + TOBN(0x0ab55e5c, 0x58c5c897), TOBN(0x985099b2, 0x838bc5df), + TOBN(0x061d9efc, 0xc52fc238), TOBN(0x712b2728, 0x6ac1da3f), + TOBN(0xfb658149, 0x9283fe08), TOBN(0x4954ac94, 0xb8aaa2f7), + TOBN(0x85c0ada4, 0x7fb2e74f), TOBN(0xee8ba98e, 0xb89926b0), + TOBN(0xe4f9d37d, 0x23d1af5b), TOBN(0x14ccdbf9, 0xba9b015e), + TOBN(0xb674481b, 0x7bfe7178), TOBN(0x4e1debae, 0x65405868), + TOBN(0x061b2821, 0xc48c867d), TOBN(0x69c15b35, 0x513b30ea), + TOBN(0x3b4a1666, 0x36871088), TOBN(0xe5e29f5d, 0x1220b1ff), + TOBN(0x4b82bb35, 0x233d9f4d), TOBN(0x4e076333, 0x18cdc675)}, + {TOBN(0x0d53f5c7, 0xa3e6fced), TOBN(0xe8cbbdd5, 0xf45fbdeb), + TOBN(0xf85c01df, 0x13339a70), TOBN(0x0ff71880, 0x142ceb81), + TOBN(0x4c4e8774, 0xbd70437a), TOBN(0x5fb32891, 0xba0bda6a), + TOBN(0x1cdbebd2, 0xf18bd26e), TOBN(0x2f9526f1, 0x03a9d522), + TOBN(0x40ce3051, 0x92c4d684), TOBN(0x8b04d725, 0x7612efcd), + TOBN(0xb9dcda36, 0x6f9cae20), TOBN(0x0edc4d24, 0xf058856c), + TOBN(0x64f2e6bf, 0x85427900), TOBN(0x3de81295, 0xdc09dfea), + TOBN(0xd41b4487, 0x379bf26c), TOBN(0x50b62c6d, 0x6df135a9), + TOBN(0xd4f8e3b4, 0xc72dfe67), TOBN(0xc416b0f6, 0x90e19fdf), + TOBN(0x18b9098d, 0x4c13bd35), TOBN(0xac11118a, 0x15b8cb9e), + TOBN(0xf598a318, 0xf0062841), TOBN(0xbfe0602f, 0x89f356f4), + TOBN(0x7ae3637e, 0x30177a0c), TOBN(0x34097747, 0x61136537), + TOBN(0x0db2fb5e, 0xd005832a), TOBN(0x5f5efd3b, 0x91042e4f), + TOBN(0x8c4ffdc6, 0xed70f8ca), TOBN(0xe4645d0b, 0xb52da9cc), + TOBN(0x9596f58b, 0xc9001d1f), TOBN(0x52c8f0bc, 0x4e117205), + TOBN(0xfd4aa0d2, 0xe398a084), TOBN(0x815bfe3a, 0x104f49de), + TOBN(0x97e5443f, 0x23885e5f), TOBN(0xf72f8f99, 0xe8433aab), + TOBN(0xbd00b154, 0xe4d4e604), TOBN(0xd0b35e6a, 0xe5e173ff), + TOBN(0x57b2a048, 0x9164722d), TOBN(0x3e3c665b, 0x88761ec8), + TOBN(0x6bdd1397, 0x3da83832), TOBN(0x3c8b1a1e, 0x73dafe3b), + TOBN(0x4497ace6, 0x54317cac), TOBN(0xbe600ab9, 0x521771b3), + TOBN(0xb42e409e, 0xb0dfe8b8), TOBN(0x386a67d7, 0x3942310f), + TOBN(0x25548d8d, 0x4431cc28), TOBN(0xa7cff142, 0x985dc524), + TOBN(0x4d60f5a1, 0x93c4be32), TOBN(0x83ebd5c8, 0xd071c6e1), + TOBN(0xba3a80a7, 0xb1fd2b0b), TOBN(0x9b3ad396, 0x5bec33e8), + TOBN(0xb3868d61, 0x79743fb3), TOBN(0xcfd169fc, 0xfdb462fa), + TOBN(0xd3b499d7, 0x9ce0a6af), TOBN(0x55dc1cf1, 0xe42d3ff8), + TOBN(0x04fb9e6c, 0xc6c3e1b2), TOBN(0x47e6961d, 0x6f69a474), + TOBN(0x54eb3acc, 0xe548b37b), TOBN(0xb38e7542, 0x84d40549), + TOBN(0x8c3daa51, 0x7b341b4f), TOBN(0x2f6928ec, 0x690bf7fa), + TOBN(0x0496b323, 0x86ce6c41), TOBN(0x01be1c55, 0x10adadcd), + TOBN(0xc04e67e7, 0x4bb5faf9), TOBN(0x3cbaf678, 0xe15c9985), + TOBN(0x8cd12145, 0x50ca4247), TOBN(0xba1aa47a, 0xe7dd30aa), + TOBN(0x2f81ddf1, 0xe58fee24), TOBN(0x03452936, 0xeec9b0e8), + TOBN(0x8bdc3b81, 0x243aea96), TOBN(0x9a2919af, 0x15c3d0e5), + TOBN(0x9ea640ec, 0x10948361), TOBN(0x5ac86d5b, 0x6e0bcccf), + TOBN(0xf892d918, 0xc36cf440), TOBN(0xaed3e837, 0xc939719c), + TOBN(0xb07b08d2, 0xc0218b64), TOBN(0x6f1bcbba, 0xce9790dd), + TOBN(0x4a84d6ed, 0x60919b8e), TOBN(0xd8900791, 0x8ac1f9eb), + TOBN(0xf84941aa, 0x0dd5daef), TOBN(0xb22fe40a, 0x67fd62c5), + TOBN(0x97e15ba2, 0x157f2db3), TOBN(0xbda2fc8f, 0x8e28ca9c), + TOBN(0x5d050da4, 0x37b9f454), TOBN(0x3d57eb57, 0x2379d72e), + TOBN(0xe9b5eba2, 0xfb5ee997), TOBN(0x01648ca2, 0xe11538ca), + TOBN(0x32bb76f6, 0xf6327974), TOBN(0x338f14b8, 0xff3f4bb7), + TOBN(0x524d226a, 0xd7ab9a2d), TOBN(0x9c00090d, 0x7dfae958), + TOBN(0x0ba5f539, 0x8751d8c2), TOBN(0x8afcbcdd, 0x3ab8262d), + TOBN(0x57392729, 0xe99d043b), TOBN(0xef51263b, 0xaebc943a), + TOBN(0x9feace93, 0x20862935), TOBN(0x639efc03, 0xb06c817b), + TOBN(0x1fe054b3, 0x66b4be7a), TOBN(0x3f25a9de, 0x84a37a1e), + TOBN(0xf39ef1ad, 0x78d75cd9), TOBN(0xd7b58f49, 0x5062c1b5), + TOBN(0x6f74f9a9, 0xff563436), TOBN(0xf718ff29, 0xe8af51e7), + TOBN(0x5234d313, 0x15e97fec), TOBN(0xb6a8e2b1, 0x292f1c0a), + TOBN(0xa7f53aa8, 0x327720c1), TOBN(0x956ca322, 0xba092cc8), + TOBN(0x8f03d64a, 0x28746c4d), TOBN(0x51fe1782, 0x66d0d392), + TOBN(0xd19b34db, 0x3c832c80), TOBN(0x60dccc5c, 0x6da2e3b4), + TOBN(0x245dd62e, 0x0a104ccc), TOBN(0xa7ab1de1, 0x620b21fd), + TOBN(0xb293ae0b, 0x3893d123), TOBN(0xf7b75783, 0xb15ee71c), + TOBN(0x5aa3c614, 0x42a9468b), TOBN(0xd686123c, 0xdb15d744), + TOBN(0x8c616891, 0xa7ab4116), TOBN(0x6fcd72c8, 0xa4e6a459), + TOBN(0xac219110, 0x77e5fad7), TOBN(0xfb6a20e7, 0x704fa46b), + TOBN(0xe839be7d, 0x341d81dc), TOBN(0xcddb6889, 0x32148379), + TOBN(0xda6211a1, 0xf7026ead), TOBN(0xf3b2575f, 0xf4d1cc5e), + TOBN(0x40cfc8f6, 0xa7a73ae6), TOBN(0x83879a5e, 0x61d5b483), + TOBN(0xc5acb1ed, 0x41a50ebc), TOBN(0x59a60cc8, 0x3c07d8fa), + TOBN(0x1b73bdce, 0xb1876262), TOBN(0x2b0d79f0, 0x12af4ee9), + TOBN(0x8bcf3b0b, 0xd46e1d07), TOBN(0x17d6af9d, 0xe45d152f), + TOBN(0x73520461, 0x6d736451), TOBN(0x43cbbd97, 0x56b0bf5a), + TOBN(0xb0833a5b, 0xd5999b9d), TOBN(0x702614f0, 0xeb72e398), + TOBN(0x0aadf01a, 0x59c3e9f8), TOBN(0x40200e77, 0xce6b3d16), + TOBN(0xda22bdd3, 0xdeddafad), TOBN(0x76dedaf4, 0x310d72e1), + TOBN(0x49ef807c, 0x4bc2e88f), TOBN(0x6ba81291, 0x146dd5a5), + TOBN(0xa1a4077a, 0x7d8d59e9), TOBN(0x87b6a2e7, 0x802db349), + TOBN(0xd5679997, 0x1b4e598e), TOBN(0xf499ef1f, 0x06fe4b1d), + TOBN(0x3978d3ae, 0xfcb267c5), TOBN(0xb582b557, 0x235786d0), + TOBN(0x32b3b2ca, 0x1715cb07), TOBN(0x4c3de6a2, 0x8480241d), + TOBN(0x63b5ffed, 0xcb571ecd), TOBN(0xeaf53900, 0xed2fe9a9), + TOBN(0xdec98d4a, 0xc3b81990), TOBN(0x1cb83722, 0x9e0cc8fe), + TOBN(0xfe0b0491, 0xd2b427b9), TOBN(0x0f2386ac, 0xe983a66c), + TOBN(0x930c4d1e, 0xb3291213), TOBN(0xa2f82b2e, 0x59a62ae4), + TOBN(0x77233853, 0xf93e89e3), TOBN(0x7f8063ac, 0x11777c7f), + TOBN(0xff0eb567, 0x59ad2877), TOBN(0x6f454642, 0x9865c754), + TOBN(0xe6fe701a, 0x236e9a84), TOBN(0xc586ef16, 0x06e40fc3), + TOBN(0x3f62b6e0, 0x24bafad9), TOBN(0xc8b42bd2, 0x64da906a), + TOBN(0xc98e1eb4, 0xda3276a0), TOBN(0x30d0e5fc, 0x06cbf852), + TOBN(0x1b6b2ae1, 0xe8b4dfd4), TOBN(0xd754d5c7, 0x8301cbac), + TOBN(0x66097629, 0x112a39ac), TOBN(0xf86b5999, 0x93ba4ab9), + TOBN(0x26c9dea7, 0x99f9d581), TOBN(0x0473b1a8, 0xc2fafeaa), + TOBN(0x1469af55, 0x3b2505a5), TOBN(0x227d16d7, 0xd6a43323), + TOBN(0x3316f73c, 0xad3d97f9), TOBN(0x52bf3bb5, 0x1f137455), + TOBN(0x953eafeb, 0x09954e7c), TOBN(0xa721dfed, 0xdd732411), + TOBN(0xb4929821, 0x141d4579), TOBN(0x3411321c, 0xaa3bd435), + TOBN(0xafb355aa, 0x17fa6015), TOBN(0xb4e7ef4a, 0x18e42f0e), + TOBN(0x604ac97c, 0x59371000), TOBN(0xe1c48c70, 0x7f759c18), + TOBN(0x3f62ecc5, 0xa5db6b65), TOBN(0x0a78b173, 0x38a21495), + TOBN(0x6be1819d, 0xbcc8ad94), TOBN(0x70dc04f6, 0xd89c3400), + TOBN(0x462557b4, 0xa6b4840a), TOBN(0x544c6ade, 0x60bd21c0), + TOBN(0x6a00f24e, 0x907a544b), TOBN(0xa7520dcb, 0x313da210), + TOBN(0xfe939b75, 0x11e4994b), TOBN(0x918b6ba6, 0xbc275d70), + TOBN(0xd3e5e0fc, 0x644be892), TOBN(0x707a9816, 0xfdaf6c42), + TOBN(0x60145567, 0xf15c13fe), TOBN(0x4818ebaa, 0xe130a54a), + TOBN(0x28aad3ad, 0x58d2f767), TOBN(0xdc5267fd, 0xd7e7c773), + TOBN(0x4919cc88, 0xc3afcc98), TOBN(0xaa2e6ab0, 0x2db8cd4b), + TOBN(0xd46fec04, 0xd0c63eaa), TOBN(0xa1cb92c5, 0x19ffa832), + TOBN(0x678dd178, 0xe43a631f), TOBN(0xfb5ae1cd, 0x3dc788b3), + TOBN(0x68b4fb90, 0x6e77de04), TOBN(0x7992bcf0, 0xf06dbb97), + TOBN(0x896e6a13, 0xc417c01d), TOBN(0x8d96332c, 0xb956be01), + TOBN(0x902fc93a, 0x413aa2b9), TOBN(0x99a4d915, 0xfc98c8a5), + TOBN(0x52c29407, 0x565f1137), TOBN(0x4072690f, 0x21e4f281), + TOBN(0x36e607cf, 0x02ff6072), TOBN(0xa47d2ca9, 0x8ad98cdc), + TOBN(0xbf471d1e, 0xf5f56609), TOBN(0xbcf86623, 0xf264ada0), + TOBN(0xb70c0687, 0xaa9e5cb6), TOBN(0xc98124f2, 0x17401c6c), + TOBN(0x8189635f, 0xd4a61435), TOBN(0xd28fb8af, 0xa9d98ea6), + TOBN(0xb9a67c2a, 0x40c251f8), TOBN(0x88cd5d87, 0xa2da44be), + TOBN(0x437deb96, 0xe09b5423), TOBN(0x150467db, 0x64287dc1), + TOBN(0xe161debb, 0xcdabb839), TOBN(0xa79e9742, 0xf1839a3e), + TOBN(0xbb8dd3c2, 0x652d202b), TOBN(0x7b3e67f7, 0xe9f97d96), + TOBN(0x5aa5d78f, 0xb1cb6ac9), TOBN(0xffa13e8e, 0xca1d0d45), + TOBN(0x369295dd, 0x2ba5bf95), TOBN(0xd68bd1f8, 0x39aff05e), + TOBN(0xaf0d86f9, 0x26d783f2), TOBN(0x543a59b3, 0xfc3aafc1), + TOBN(0x3fcf81d2, 0x7b7da97c), TOBN(0xc990a056, 0xd25dee46), + TOBN(0x3e6775b8, 0x519cce2c), TOBN(0xfc9af71f, 0xae13d863), + TOBN(0x774a4a6f, 0x47c1605c), TOBN(0x46ba4245, 0x2fd205e8), + TOBN(0xa06feea4, 0xd3fd524d), TOBN(0x1e724641, 0x6de1acc2), + TOBN(0xf53816f1, 0x334e2b42), TOBN(0x49e5918e, 0x922f0024), + TOBN(0x439530b6, 0x65c7322d), TOBN(0xcf12cc01, 0xb3c1b3fb), + TOBN(0xc70b0186, 0x0172f685), TOBN(0xb915ee22, 0x1b58391d), + TOBN(0x9afdf03b, 0xa317db24), TOBN(0x87dec659, 0x17b8ffc4), + TOBN(0x7f46597b, 0xe4d3d050), TOBN(0x80a1c1ed, 0x006500e7), + TOBN(0x84902a96, 0x78bf030e), TOBN(0xfb5e9c9a, 0x50560148), + TOBN(0x6dae0a92, 0x63362426), TOBN(0xdcaeecf4, 0xa9e30c40), + TOBN(0xc0d887bb, 0x518d0c6b), TOBN(0x99181152, 0xcb985b9d), + TOBN(0xad186898, 0xef7bc381), TOBN(0x18168ffb, 0x9ee46201), + TOBN(0x9a04cdaa, 0x2502753c), TOBN(0xbb279e26, 0x51407c41), + TOBN(0xeacb03aa, 0xf23564e5), TOBN(0x18336582, 0x71e61016), + TOBN(0x8684b8c4, 0xeb809877), TOBN(0xb336e18d, 0xea0e672e), + TOBN(0xefb601f0, 0x34ee5867), TOBN(0x2733edbe, 0x1341cfd1), + TOBN(0xb15e809a, 0x26025c3c), TOBN(0xe6e981a6, 0x9350df88), + TOBN(0x92376237, 0x8502fd8e), TOBN(0x4791f216, 0x0c12be9b), + TOBN(0xb7256789, 0x25f02425), TOBN(0xec863194, 0x7a974443), + TOBN(0x7c0ce882, 0xfb41cc52), TOBN(0xc266ff7e, 0xf25c07f2), + TOBN(0x3d4da8c3, 0x017025f3), TOBN(0xefcf628c, 0xfb9579b4), + TOBN(0x5c4d0016, 0x1f3716ec), TOBN(0x9c27ebc4, 0x6801116e), + TOBN(0x5eba0ea1, 0x1da1767e), TOBN(0xfe151452, 0x47004c57), + TOBN(0x3ace6df6, 0x8c2373b7), TOBN(0x75c3dffe, 0x5dbc37ac), + TOBN(0x3dc32a73, 0xddc925fc), TOBN(0xb679c841, 0x2f65ee0b), + TOBN(0x715a3295, 0x451cbfeb), TOBN(0xd9889768, 0xf76e9a29), + TOBN(0xec20ce7f, 0xb28ad247), TOBN(0xe99146c4, 0x00894d79), + TOBN(0x71457d7c, 0x9f5e3ea7), TOBN(0x097b2662, 0x38030031), + TOBN(0xdb7f6ae6, 0xcf9f82a8), TOBN(0x319decb9, 0x438f473a), + TOBN(0xa63ab386, 0x283856c3), TOBN(0x13e3172f, 0xb06a361b), + TOBN(0x2959f8dc, 0x7d5a006c), TOBN(0x2dbc27c6, 0x75fba752), + TOBN(0xc1227ab2, 0x87c22c9e), TOBN(0x06f61f75, 0x71a268b2), + TOBN(0x1b6bb971, 0x04779ce2), TOBN(0xaca83812, 0x0aadcb1d), + TOBN(0x297ae0bc, 0xaeaab2d5), TOBN(0xa5c14ee7, 0x5bfb9f13), + TOBN(0xaa00c583, 0xf17a62c7), TOBN(0x39eb962c, 0x173759f6), + TOBN(0x1eeba1d4, 0x86c9a88f), TOBN(0x0ab6c37a, 0xdf016c5e), + TOBN(0xa2a147db, 0xa28a0749), TOBN(0x246c20d6, 0xee519165), + TOBN(0x5068d1b1, 0xd3810715), TOBN(0xb1e7018c, 0x748160b9), + TOBN(0x03f5b1fa, 0xf380ff62), TOBN(0xef7fb1dd, 0xf3cb2c1e), + TOBN(0xeab539a8, 0xfc91a7da), TOBN(0x83ddb707, 0xf3f9b561), + TOBN(0xc550e211, 0xfe7df7a4), TOBN(0xa7cd07f2, 0x063f6f40), + TOBN(0xb0de3635, 0x2976879c), TOBN(0xb5f83f85, 0xe55741da), + TOBN(0x4ea9d25e, 0xf3d8ac3d), TOBN(0x6fe2066f, 0x62819f02), + TOBN(0x4ab2b9c2, 0xcef4a564), TOBN(0x1e155d96, 0x5ffa2de3), + TOBN(0x0eb0a19b, 0xc3a72d00), TOBN(0x4037665b, 0x8513c31b), + TOBN(0x2fb2b6bf, 0x04c64637), TOBN(0x45c34d6e, 0x08cdc639), + TOBN(0x56f1e10f, 0xf01fd796), TOBN(0x4dfb8101, 0xfe3667b8), + TOBN(0xe0eda253, 0x9021d0c0), TOBN(0x7a94e9ff, 0x8a06c6ab), + TOBN(0x2d3bb0d9, 0xbb9aa882), TOBN(0xea20e4e5, 0xec05fd10), + TOBN(0xed7eeb5f, 0x1a1ca64e), TOBN(0x2fa6b43c, 0xc6327cbd), + TOBN(0xb577e3cf, 0x3aa91121), TOBN(0x8c6bd5ea, 0x3a34079b), + TOBN(0xd7e5ba39, 0x60e02fc0), TOBN(0xf16dd2c3, 0x90141bf8), + TOBN(0xb57276d9, 0x80101b98), TOBN(0x760883fd, 0xb82f0f66), + TOBN(0x89d7de75, 0x4bc3eff3), TOBN(0x03b60643, 0x5dc2ab40), + TOBN(0xcd6e53df, 0xe05beeac), TOBN(0xf2f1e862, 0xbc3325cd), + TOBN(0xdd0f7921, 0x774f03c3), TOBN(0x97ca7221, 0x4552cc1b), + TOBN(0x5a0d6afe, 0x1cd19f72), TOBN(0xa20915dc, 0xf183fbeb), + TOBN(0x9fda4b40, 0x832c403c), TOBN(0x32738edd, 0xbe425442), + TOBN(0x469a1df6, 0xb5eccf1a), TOBN(0x4b5aff42, 0x28bbe1f0), + TOBN(0x31359d7f, 0x570dfc93), TOBN(0xa18be235, 0xf0088628), + TOBN(0xa5b30fba, 0xb00ed3a9), TOBN(0x34c61374, 0x73cdf8be), + TOBN(0x2c5c5f46, 0xabc56797), TOBN(0x5cecf93d, 0xb82a8ae2), + TOBN(0x7d3dbe41, 0xa968fbf0), TOBN(0xd23d4583, 0x1a5c7f3d), + TOBN(0xf28f69a0, 0xc087a9c7), TOBN(0xc2d75471, 0x474471ca), + TOBN(0x36ec9f4a, 0x4eb732ec), TOBN(0x6c943bbd, 0xb1ca6bed), + TOBN(0xd64535e1, 0xf2457892), TOBN(0x8b84a8ea, 0xf7e2ac06), + TOBN(0xe0936cd3, 0x2499dd5f), TOBN(0x12053d7e, 0x0ed04e57), + TOBN(0x4bdd0076, 0xe4305d9d), TOBN(0x34a527b9, 0x1f67f0a2), + TOBN(0xe79a4af0, 0x9cec46ea), TOBN(0xb15347a1, 0x658b9bc7), + TOBN(0x6bd2796f, 0x35af2f75), TOBN(0xac957990, 0x4051c435), + TOBN(0x2669dda3, 0xc33a655d), TOBN(0x5d503c2e, 0x88514aa3), + TOBN(0xdfa11337, 0x3753dd41), TOBN(0x3f054673, 0x0b754f78), + TOBN(0xbf185677, 0x496125bd), TOBN(0xfb0023c8, 0x3775006c), + TOBN(0xfa0f072f, 0x3a037899), TOBN(0x4222b6eb, 0x0e4aea57), + TOBN(0x3dde5e76, 0x7866d25a), TOBN(0xb6eb04f8, 0x4837aa6f), + TOBN(0x5315591a, 0x2cf1cdb8), TOBN(0x6dfb4f41, 0x2d4e683c), + TOBN(0x7e923ea4, 0x48ee1f3a), TOBN(0x9604d9f7, 0x05a2afd5), + TOBN(0xbe1d4a33, 0x40ea4948), TOBN(0x5b45f1f4, 0xb44cbd2f), + TOBN(0x5faf8376, 0x4acc757e), TOBN(0xa7cf9ab8, 0x63d68ff7), + TOBN(0x8ad62f69, 0xdf0e404b), TOBN(0xd65f33c2, 0x12bdafdf), + TOBN(0xc365de15, 0xa377b14e), TOBN(0x6bf5463b, 0x8e39f60c), + TOBN(0x62030d2d, 0x2ce68148), TOBN(0xd95867ef, 0xe6f843a8), + TOBN(0xd39a0244, 0xef5ab017), TOBN(0x0bd2d8c1, 0x4ab55d12), + TOBN(0xc9503db3, 0x41639169), TOBN(0x2d4e25b0, 0xf7660c8a), + TOBN(0x760cb3b5, 0xe224c5d7), TOBN(0xfa3baf8c, 0x68616919), + TOBN(0x9fbca113, 0x8d142552), TOBN(0x1ab18bf1, 0x7669ebf5), + TOBN(0x55e6f53e, 0x9bdf25dd), TOBN(0x04cc0bf3, 0xcb6cd154), + TOBN(0x595bef49, 0x95e89080), TOBN(0xfe9459a8, 0x104a9ac1), + TOBN(0xad2d89ca, 0xcce9bb32), TOBN(0xddea65e1, 0xf7de8285), + TOBN(0x62ed8c35, 0xb351bd4b), TOBN(0x4150ff36, 0x0c0e19a7), + TOBN(0x86e3c801, 0x345f4e47), TOBN(0x3bf21f71, 0x203a266c), + TOBN(0x7ae110d4, 0x855b1f13), TOBN(0x5d6aaf6a, 0x07262517), + TOBN(0x1e0f12e1, 0x813d28f1), TOBN(0x6000e11d, 0x7ad7a523), + TOBN(0xc7d8deef, 0xc744a17b), TOBN(0x1e990b48, 0x14c05a00), + TOBN(0x68fddaee, 0x93e976d5), TOBN(0x696241d1, 0x46610d63), + TOBN(0xb204e7c3, 0x893dda88), TOBN(0x8bccfa65, 0x6a3a6946), + TOBN(0xb59425b4, 0xc5cd1411), TOBN(0x701b4042, 0xff3658b1), + TOBN(0xe3e56bca, 0x4784cf93), TOBN(0x27de5f15, 0x8fe68d60), + TOBN(0x4ab9cfce, 0xf8d53f19), TOBN(0xddb10311, 0xa40a730d), + TOBN(0x6fa73cd1, 0x4eee0a8a), TOBN(0xfd548748, 0x5249719d), + TOBN(0x49d66316, 0xa8123ef0), TOBN(0x73c32db4, 0xe7f95438), + TOBN(0x2e2ed209, 0x0d9e7854), TOBN(0xf98a9329, 0x9d9f0507), + TOBN(0xc5d33cf6, 0x0c6aa20a), TOBN(0x9a32ba14, 0x75279bb2), + TOBN(0x7e3202cb, 0x774a7307), TOBN(0x64ed4bc4, 0xe8c42dbd), + TOBN(0xc20f1a06, 0xd4caed0d), TOBN(0xb8021407, 0x171d22b3), + TOBN(0xd426ca04, 0xd13268d7), TOBN(0x92377007, 0x25f4d126), + TOBN(0x4204cbc3, 0x71f21a85), TOBN(0x18461b7a, 0xf82369ba), + TOBN(0xc0c07d31, 0x3fc858f9), TOBN(0x5deb5a50, 0xe2bab569), + TOBN(0xd5959d46, 0xd5eea89e), TOBN(0xfdff8424, 0x08437f4b), + TOBN(0xf21071e4, 0x3cfe254f), TOBN(0x72417696, 0x95468321), + TOBN(0x5d8288b9, 0x102cae3e), TOBN(0x2d143e3d, 0xf1965dff), + TOBN(0x00c9a376, 0xa078d847), TOBN(0x6fc0da31, 0x26028731), + TOBN(0xa2baeadf, 0xe45083a2), TOBN(0x66bc7218, 0x5e5b4bcd), + TOBN(0x2c826442, 0xd04b8e7f), TOBN(0xc19f5451, 0x6c4b586b), + TOBN(0x60182c49, 0x5b7eeed5), TOBN(0xd9954ecd, 0x7aa9dfa1), + TOBN(0xa403a8ec, 0xc73884ad), TOBN(0x7fb17de2, 0x9bb39041), + TOBN(0x694b64c5, 0xabb020e8), TOBN(0x3d18c184, 0x19c4eec7), + TOBN(0x9c4673ef, 0x1c4793e5), TOBN(0xc7b8aeb5, 0x056092e6), + TOBN(0x3aa1ca43, 0xf0f8c16b), TOBN(0x224ed5ec, 0xd679b2f6), + TOBN(0x0d56eeaf, 0x55a205c9), TOBN(0xbfe115ba, 0x4b8e028b), + TOBN(0x97e60849, 0x3927f4fe), TOBN(0xf91fbf94, 0x759aa7c5), + TOBN(0x985af769, 0x6be90a51), TOBN(0xc1277b78, 0x78ccb823), + TOBN(0x395b656e, 0xe7a75952), TOBN(0x00df7de0, 0x928da5f5), + TOBN(0x09c23175, 0x4ca4454f), TOBN(0x4ec971f4, 0x7aa2d3c1), + TOBN(0x45c3c507, 0xe75d9ccc), TOBN(0x63b7be8a, 0x3dc90306), + TOBN(0x37e09c66, 0x5db44bdc), TOBN(0x50d60da1, 0x6841c6a2), + TOBN(0x6f9b65ee, 0x08df1b12), TOBN(0x38734879, 0x7ff089df), + TOBN(0x9c331a66, 0x3fe8013d), TOBN(0x017f5de9, 0x5f42fcc8), + TOBN(0x43077866, 0xe8e57567), TOBN(0xc9f781ce, 0xf9fcdb18), + TOBN(0x38131dda, 0x9b12e174), TOBN(0x25d84aa3, 0x8a03752a), + TOBN(0x45e09e09, 0x4d0c0ce2), TOBN(0x1564008b, 0x92bebba5), + TOBN(0xf7e8ad31, 0xa87284c7), TOBN(0xb7c4b46c, 0x97e7bbaa), + TOBN(0x3e22a7b3, 0x97acf4ec), TOBN(0x0426c400, 0x5ea8b640), + TOBN(0x5e3295a6, 0x4e969285), TOBN(0x22aabc59, 0xa6a45670), + TOBN(0xb929714c, 0x5f5942bc), TOBN(0x9a6168bd, 0xfa3182ed), + TOBN(0x2216a665, 0x104152ba), TOBN(0x46908d03, 0xb6926368)}, + {TOBN(0xa9f5d874, 0x5a1251fb), TOBN(0x967747a8, 0xc72725c7), + TOBN(0x195c33e5, 0x31ffe89e), TOBN(0x609d210f, 0xe964935e), + TOBN(0xcafd6ca8, 0x2fe12227), TOBN(0xaf9b5b96, 0x0426469d), + TOBN(0x2e9ee04c, 0x5693183c), TOBN(0x1084a333, 0xc8146fef), + TOBN(0x96649933, 0xaed1d1f7), TOBN(0x566eaff3, 0x50563090), + TOBN(0x345057f0, 0xad2e39cf), TOBN(0x148ff65b, 0x1f832124), + TOBN(0x042e89d4, 0xcf94cf0d), TOBN(0x319bec84, 0x520c58b3), + TOBN(0x2a267626, 0x5361aa0d), TOBN(0xc86fa302, 0x8fbc87ad), + TOBN(0xfc83d2ab, 0x5c8b06d5), TOBN(0xb1a785a2, 0xfe4eac46), + TOBN(0xb99315bc, 0x846f7779), TOBN(0xcf31d816, 0xef9ea505), + TOBN(0x2391fe6a, 0x15d7dc85), TOBN(0x2f132b04, 0xb4016b33), + TOBN(0x29547fe3, 0x181cb4c7), TOBN(0xdb66d8a6, 0x650155a1), + TOBN(0x6b66d7e1, 0xadc1696f), TOBN(0x98ebe593, 0x0acd72d0), + TOBN(0x65f24550, 0xcc1b7435), TOBN(0xce231393, 0xb4b9a5ec), + TOBN(0x234a22d4, 0xdb067df9), TOBN(0x98dda095, 0xcaff9b00), + TOBN(0x1bbc75a0, 0x6100c9c1), TOBN(0x1560a9c8, 0x939cf695), + TOBN(0xcf006d3e, 0x99e0925f), TOBN(0x2dd74a96, 0x6322375a), + TOBN(0xc58b446a, 0xb56af5ba), TOBN(0x50292683, 0xe0b9b4f1), + TOBN(0xe2c34cb4, 0x1aeaffa3), TOBN(0x8b17203f, 0x9b9587c1), + TOBN(0x6d559207, 0xead1350c), TOBN(0x2b66a215, 0xfb7f9604), + TOBN(0x0850325e, 0xfe51bf74), TOBN(0x9c4f579e, 0x5e460094), + TOBN(0x5c87b92a, 0x76da2f25), TOBN(0x889de4e0, 0x6febef33), + TOBN(0x6900ec06, 0x646083ce), TOBN(0xbe2a0335, 0xbfe12773), + TOBN(0xadd1da35, 0xc5344110), TOBN(0x757568b7, 0xb802cd20), + TOBN(0x75559779, 0x00f7e6c8), TOBN(0x38e8b94f, 0x0facd2f0), + TOBN(0xfea1f3af, 0x03fde375), TOBN(0x5e11a1d8, 0x75881dfc), + TOBN(0xb3a6b02e, 0xc1e2f2ef), TOBN(0x193d2bbb, 0xc605a6c5), + TOBN(0x325ffeee, 0x339a0b2d), TOBN(0x27b6a724, 0x9e0c8846), + TOBN(0xe4050f1c, 0xf1c367ca), TOBN(0x9bc85a9b, 0xc90fbc7d), + TOBN(0xa373c4a2, 0xe1a11032), TOBN(0xb64232b7, 0xad0393a9), + TOBN(0xf5577eb0, 0x167dad29), TOBN(0x1604f301, 0x94b78ab2), + TOBN(0x0baa94af, 0xe829348b), TOBN(0x77fbd8dd, 0x41654342), + TOBN(0xdab50ea5, 0xb964e39a), TOBN(0xd4c29e3c, 0xd0d3c76e), + TOBN(0x80dae67c, 0x56d11964), TOBN(0x7307a8bf, 0xe5ffcc2f), + TOBN(0x65bbc1aa, 0x91708c3b), TOBN(0xa151e62c, 0x28bf0eeb), + TOBN(0x6cb53381, 0x6fa34db7), TOBN(0x5139e05c, 0xa29403a8), + TOBN(0x6ff651b4, 0x94a7cd2e), TOBN(0x5671ffd1, 0x0699336c), + TOBN(0x6f5fd2cc, 0x979a896a), TOBN(0x11e893a8, 0xd8148cef), + TOBN(0x988906a1, 0x65cf7b10), TOBN(0x81b67178, 0xc50d8485), + TOBN(0x7c0deb35, 0x8a35b3de), TOBN(0x423ac855, 0xc1d29799), + TOBN(0xaf580d87, 0xdac50b74), TOBN(0x28b2b89f, 0x5869734c), + TOBN(0x99a3b936, 0x874e28fb), TOBN(0xbb2c9190, 0x25f3f73a), + TOBN(0x199f6918, 0x84a9d5b7), TOBN(0x7ebe2325, 0x7e770374), + TOBN(0xf442e107, 0x0738efe2), TOBN(0xcf9f3f56, 0xcf9082d2), + TOBN(0x719f69e1, 0x09618708), TOBN(0xcc9e8364, 0xc183f9b1), + TOBN(0xec203a95, 0x366a21af), TOBN(0x6aec5d6d, 0x068b141f), + TOBN(0xee2df78a, 0x994f04e9), TOBN(0xb39ccae8, 0x271245b0), + TOBN(0xb875a4a9, 0x97e43f4f), TOBN(0x507dfe11, 0xdb2cea98), + TOBN(0x4fbf81cb, 0x489b03e9), TOBN(0xdb86ec5b, 0x6ec414fa), + TOBN(0xfad444f9, 0xf51b3ae5), TOBN(0xca7d33d6, 0x1914e3fe), + TOBN(0xa9c32f5c, 0x0ae6c4d0), TOBN(0xa9ca1d1e, 0x73969568), + TOBN(0x98043c31, 0x1aa7467e), TOBN(0xe832e75c, 0xe21b5ac6), + TOBN(0x314b7aea, 0x5232123d), TOBN(0x08307c8c, 0x65ae86db), + TOBN(0x06e7165c, 0xaa4668ed), TOBN(0xb170458b, 0xb4d3ec39), + TOBN(0x4d2e3ec6, 0xc19bb986), TOBN(0xc5f34846, 0xae0304ed), + TOBN(0x917695a0, 0x6c9f9722), TOBN(0x6c7f7317, 0x4cab1c0a), + TOBN(0x6295940e, 0x9d6d2e8b), TOBN(0xd318b8c1, 0x549f7c97), + TOBN(0x22453204, 0x97713885), TOBN(0x468d834b, 0xa8a440fe), + TOBN(0xd81fe5b2, 0xbfba796e), TOBN(0x152364db, 0x6d71f116), + TOBN(0xbb8c7c59, 0xb5b66e53), TOBN(0x0b12c61b, 0x2641a192), + TOBN(0x31f14802, 0xfcf0a7fd), TOBN(0x42fd0789, 0x5488b01e), + TOBN(0x71d78d6d, 0x9952b498), TOBN(0x8eb572d9, 0x07ac5201), + TOBN(0xe0a2a44c, 0x4d194a88), TOBN(0xd2b63fd9, 0xba017e66), + TOBN(0x78efc6c8, 0xf888aefc), TOBN(0xb76f6bda, 0x4a881a11), + TOBN(0x187f314b, 0xb46c2397), TOBN(0x004cf566, 0x5ded2819), + TOBN(0xa9ea5704, 0x38764d34), TOBN(0xbba45217, 0x78084709), + TOBN(0x06474571, 0x1171121e), TOBN(0xad7b7eb1, 0xe7c9b671), + TOBN(0xdacfbc40, 0x730f7507), TOBN(0x178cd8c6, 0xc7ad7bd1), + TOBN(0xbf0be101, 0xb2a67238), TOBN(0x3556d367, 0xaf9c14f2), + TOBN(0x104b7831, 0xa5662075), TOBN(0x58ca59bb, 0x79d9e60a), + TOBN(0x4bc45392, 0xa569a73b), TOBN(0x517a52e8, 0x5698f6c9), + TOBN(0x85643da5, 0xaeadd755), TOBN(0x1aed0cd5, 0x2a581b84), + TOBN(0xb9b4ff84, 0x80af1372), TOBN(0x244c3113, 0xf1ba5d1f), + TOBN(0x2a5dacbe, 0xf5f98d31), TOBN(0x2c3323e8, 0x4375bc2a), + TOBN(0x17a3ab4a, 0x5594b1dd), TOBN(0xa1928bfb, 0xceb4797e), + TOBN(0xe83af245, 0xe4886a19), TOBN(0x8979d546, 0x72b5a74a), + TOBN(0xa0f726bc, 0x19f9e967), TOBN(0xd9d03152, 0xe8fbbf4e), + TOBN(0xcfd6f51d, 0xb7707d40), TOBN(0x633084d9, 0x63f6e6e0), + TOBN(0xedcd9cdc, 0x55667eaf), TOBN(0x73b7f92b, 0x2e44d56f), + TOBN(0xfb2e39b6, 0x4e962b14), TOBN(0x7d408f6e, 0xf671fcbf), + TOBN(0xcc634ddc, 0x164a89bb), TOBN(0x74a42bb2, 0x3ef3bd05), + TOBN(0x1280dbb2, 0x428decbb), TOBN(0x6103f6bb, 0x402c8596), + TOBN(0xfa2bf581, 0x355a5752), TOBN(0x562f96a8, 0x00946674), + TOBN(0x4e4ca16d, 0x6da0223b), TOBN(0xfe47819f, 0x28d3aa25), + TOBN(0x9eea3075, 0xf8dfcf8a), TOBN(0xa284f0aa, 0x95669825), + TOBN(0xb3fca250, 0x867d3fd8), TOBN(0x20757b5f, 0x269d691e), + TOBN(0xf2c24020, 0x93b8a5de), TOBN(0xd3f93359, 0xebc06da6), + TOBN(0x1178293e, 0xb2739c33), TOBN(0xd2a3e770, 0xbcd686e5), + TOBN(0xa76f49f4, 0xcd941534), TOBN(0x0d37406b, 0xe3c71c0e), + TOBN(0x172d9397, 0x3b97f7e3), TOBN(0xec17e239, 0xbd7fd0de), + TOBN(0xe3290551, 0x6f496ba2), TOBN(0x6a693172, 0x36ad50e7), + TOBN(0xc4e539a2, 0x83e7eff5), TOBN(0x752737e7, 0x18e1b4cf), + TOBN(0xa2f7932c, 0x68af43ee), TOBN(0x5502468e, 0x703d00bd), + TOBN(0xe5dc978f, 0x2fb061f5), TOBN(0xc9a1904a, 0x28c815ad), + TOBN(0xd3af538d, 0x470c56a4), TOBN(0x159abc5f, 0x193d8ced), + TOBN(0x2a37245f, 0x20108ef3), TOBN(0xfa17081e, 0x223f7178), + TOBN(0x27b0fb2b, 0x10c8c0f5), TOBN(0x2102c3ea, 0x40650547), + TOBN(0x594564df, 0x8ac3bfa7), TOBN(0x98102033, 0x509dad96), + TOBN(0x6989643f, 0xf1d18a13), TOBN(0x35eebd91, 0xd7fc5af0), + TOBN(0x078d096a, 0xfaeaafd8), TOBN(0xb7a89341, 0xdef3de98), + TOBN(0x2a206e8d, 0xecf2a73a), TOBN(0x066a6397, 0x8e551994), + TOBN(0x3a6a088a, 0xb98d53a2), TOBN(0x0ce7c67c, 0x2d1124aa), + TOBN(0x48cec671, 0x759a113c), TOBN(0xe3b373d3, 0x4f6f67fa), + TOBN(0x5455d479, 0xfd36727b), TOBN(0xe5a428ee, 0xa13c0d81), + TOBN(0xb853dbc8, 0x1c86682b), TOBN(0xb78d2727, 0xb8d02b2a), + TOBN(0xaaf69bed, 0x8ebc329a), TOBN(0xdb6b40b3, 0x293b2148), + TOBN(0xe42ea77d, 0xb8c4961f), TOBN(0xb1a12f7c, 0x20e5e0ab), + TOBN(0xa0ec5274, 0x79e8b05e), TOBN(0x68027391, 0xfab60a80), + TOBN(0x6bfeea5f, 0x16b1bd5e), TOBN(0xf957e420, 0x4de30ad3), + TOBN(0xcbaf664e, 0x6a353b9e), TOBN(0x5c873312, 0x26d14feb), + TOBN(0x4e87f98c, 0xb65f57cb), TOBN(0xdb60a621, 0x5e0cdd41), + TOBN(0x67c16865, 0xa6881440), TOBN(0x1093ef1a, 0x46ab52aa), + TOBN(0xc095afb5, 0x3f4ece64), TOBN(0x6a6bb02e, 0x7604551a), + TOBN(0x55d44b4e, 0x0b26b8cd), TOBN(0xe5f9a999, 0xf971268a), + TOBN(0xc08ec425, 0x11a7de84), TOBN(0x83568095, 0xfda469dd), + TOBN(0x737bfba1, 0x6c6c90a2), TOBN(0x1cb9c4a0, 0xbe229831), + TOBN(0x93bccbba, 0xbb2eec64), TOBN(0xa0c23b64, 0xda03adbe), + TOBN(0x5f7aa00a, 0xe0e86ac4), TOBN(0x470b941e, 0xfc1401e6), + TOBN(0x5ad8d679, 0x9df43574), TOBN(0x4ccfb8a9, 0x0f65d810), + TOBN(0x1bce80e3, 0xaa7fbd81), TOBN(0x273291ad, 0x9508d20a), + TOBN(0xf5c4b46b, 0x42a92806), TOBN(0x810684ec, 0xa86ab44a), + TOBN(0x4591640b, 0xca0bc9f8), TOBN(0xb5efcdfc, 0x5c4b6054), + TOBN(0x16fc8907, 0x6e9edd12), TOBN(0xe29d0b50, 0xd4d792f9), + TOBN(0xa45fd01c, 0x9b03116d), TOBN(0x85035235, 0xc81765a4), + TOBN(0x1fe2a9b2, 0xb4b4b67c), TOBN(0xc1d10df0, 0xe8020604), + TOBN(0x9d64abfc, 0xbc8058d8), TOBN(0x8943b9b2, 0x712a0fbb), + TOBN(0x90eed914, 0x3b3def04), TOBN(0x85ab3aa2, 0x4ce775ff), + TOBN(0x605fd4ca, 0x7bbc9040), TOBN(0x8b34a564, 0xe2c75dfb), + TOBN(0x41ffc94a, 0x10358560), TOBN(0x2d8a5072, 0x9e5c28aa), + TOBN(0xe915a0fc, 0x4cc7eb15), TOBN(0xe9efab05, 0x8f6d0f5d), + TOBN(0xdbab47a9, 0xd19e9b91), TOBN(0x8cfed745, 0x0276154c), + TOBN(0x154357ae, 0x2cfede0d), TOBN(0x520630df, 0x19f5a4ef), + TOBN(0x25759f7c, 0xe382360f), TOBN(0xb6db05c9, 0x88bf5857), + TOBN(0x2917d61d, 0x6c58d46c), TOBN(0x14f8e491, 0xfd20cb7a), + TOBN(0xb68a727a, 0x11c20340), TOBN(0x0386f86f, 0xaf7ccbb6), + TOBN(0x5c8bc6cc, 0xfee09a20), TOBN(0x7d76ff4a, 0xbb7eea35), + TOBN(0xa7bdebe7, 0xdb15be7a), TOBN(0x67a08054, 0xd89f0302), + TOBN(0x56bf0ea9, 0xc1193364), TOBN(0xc8244467, 0x62837ebe), + TOBN(0x32bd8e8b, 0x20d841b8), TOBN(0x127a0548, 0xdbb8a54f), + TOBN(0x83dd4ca6, 0x63b20236), TOBN(0x87714718, 0x203491fa), + TOBN(0x4dabcaaa, 0xaa8a5288), TOBN(0x91cc0c8a, 0xaf23a1c9), + TOBN(0x34c72c6a, 0x3f220e0c), TOBN(0xbcc20bdf, 0x1232144a), + TOBN(0x6e2f42da, 0xa20ede1b), TOBN(0xc441f00c, 0x74a00515), + TOBN(0xbf46a5b6, 0x734b8c4b), TOBN(0x57409503, 0x7b56c9a4), + TOBN(0x9f735261, 0xe4585d45), TOBN(0x9231faed, 0x6734e642), + TOBN(0x1158a176, 0xbe70ee6c), TOBN(0x35f1068d, 0x7c3501bf), + TOBN(0x6beef900, 0xa2d26115), TOBN(0x649406f2, 0xef0afee3), + TOBN(0x3f43a60a, 0xbc2420a1), TOBN(0x509002a7, 0xd5aee4ac), + TOBN(0xb46836a5, 0x3ff3571b), TOBN(0x24f98b78, 0x837927c1), + TOBN(0x6254256a, 0x4533c716), TOBN(0xf27abb0b, 0xd07ee196), + TOBN(0xd7cf64fc, 0x5c6d5bfd), TOBN(0x6915c751, 0xf0cd7a77), + TOBN(0xd9f59012, 0x8798f534), TOBN(0x772b0da8, 0xf81d8b5f), + TOBN(0x1244260c, 0x2e03fa69), TOBN(0x36cf0e3a, 0x3be1a374), + TOBN(0x6e7c1633, 0xef06b960), TOBN(0xa71a4c55, 0x671f90f6), + TOBN(0x7a941251, 0x33c673db), TOBN(0xc0bea510, 0x73e8c131), + TOBN(0x61a8a699, 0xd4f6c734), TOBN(0x25e78c88, 0x341ed001), + TOBN(0x5c18acf8, 0x8e2f7d90), TOBN(0xfdbf33d7, 0x77be32cd), + TOBN(0x0a085cd7, 0xd2eb5ee9), TOBN(0x2d702cfb, 0xb3201115), + TOBN(0xb6e0ebdb, 0x85c88ce8), TOBN(0x23a3ce3c, 0x1e01d617), + TOBN(0x3041618e, 0x567333ac), TOBN(0x9dd0fd8f, 0x157edb6b), + TOBN(0x27f74702, 0xb57872b8), TOBN(0x2ef26b4f, 0x657d5fe1), + TOBN(0x95426f0a, 0x57cf3d40), TOBN(0x847e2ad1, 0x65a6067a), + TOBN(0xd474d9a0, 0x09996a74), TOBN(0x16a56acd, 0x2a26115c), + TOBN(0x02a615c3, 0xd16f4d43), TOBN(0xcc3fc965, 0xaadb85b7), + TOBN(0x386bda73, 0xce07d1b0), TOBN(0xd82910c2, 0x58ad4178), + TOBN(0x124f82cf, 0xcd2617f4), TOBN(0xcc2f5e8d, 0xef691770), + TOBN(0x82702550, 0xb8c30ccc), TOBN(0x7b856aea, 0x1a8e575a), + TOBN(0xbb822fef, 0xb1ab9459), TOBN(0x085928bc, 0xec24e38e), + TOBN(0x5d0402ec, 0xba8f4b4d), TOBN(0xc07cd4ba, 0x00b4d58b), + TOBN(0x5d8dffd5, 0x29227e7a), TOBN(0x61d44d0c, 0x31bf386f), + TOBN(0xe486dc2b, 0x135e6f4d), TOBN(0x680962eb, 0xe79410ef), + TOBN(0xa61bd343, 0xf10088b5), TOBN(0x6aa76076, 0xe2e28686), + TOBN(0x80463d11, 0x8fb98871), TOBN(0xcb26f5c3, 0xbbc76aff), + TOBN(0xd4ab8edd, 0xfbe03614), TOBN(0xc8eb579b, 0xc0cf2dee), + TOBN(0xcc004c15, 0xc93bae41), TOBN(0x46fbae5d, 0x3aeca3b2), + TOBN(0x671235cf, 0x0f1e9ab1), TOBN(0xadfba934, 0x9ec285c1), + TOBN(0x88ded013, 0xf216c980), TOBN(0xc8ac4fb8, 0xf79e0bc1), + TOBN(0xa29b89c6, 0xfb97a237), TOBN(0xb697b780, 0x9922d8e7), + TOBN(0x3142c639, 0xddb945b5), TOBN(0x447b06c7, 0xe094c3a9), + TOBN(0xcdcb3642, 0x72266c90), TOBN(0x633aad08, 0xa9385046), + TOBN(0xa36c936b, 0xb57c6477), TOBN(0x871f8b64, 0xe94dbcc6), + TOBN(0x28d0fb62, 0xa591a67b), TOBN(0x9d40e081, 0xc1d926f5), + TOBN(0x3111eaf6, 0xf2d84b5a), TOBN(0x228993f9, 0xa565b644), + TOBN(0x0ccbf592, 0x2c83188b), TOBN(0xf87b30ab, 0x3df3e197), + TOBN(0xb8658b31, 0x7642bca8), TOBN(0x1a032d7f, 0x52800f17), + TOBN(0x051dcae5, 0x79bf9445), TOBN(0xeba6b8ee, 0x54a2e253), + TOBN(0x5c8b9cad, 0xd4485692), TOBN(0x84bda40e, 0x8986e9be), + TOBN(0xd16d16a4, 0x2f0db448), TOBN(0x8ec80050, 0xa14d4188), + TOBN(0xb2b26107, 0x98fa7aaa), TOBN(0x41209ee4, 0xf073aa4e), + TOBN(0xf1570359, 0xf2d6b19b), TOBN(0xcbe6868c, 0xfc577caf), + TOBN(0x186c4bdc, 0x32c04dd3), TOBN(0xa6c35fae, 0xcfeee397), + TOBN(0xb4a1b312, 0xf086c0cf), TOBN(0xe0a5ccc6, 0xd9461fe2), + TOBN(0xc32278aa, 0x1536189f), TOBN(0x1126c55f, 0xba6df571), + TOBN(0x0f71a602, 0xb194560e), TOBN(0x8b2d7405, 0x324bd6e1), + TOBN(0x8481939e, 0x3738be71), TOBN(0xb5090b1a, 0x1a4d97a9), + TOBN(0x116c65a3, 0xf05ba915), TOBN(0x21863ad3, 0xaae448aa), + TOBN(0xd24e2679, 0xa7aae5d3), TOBN(0x7076013d, 0x0de5c1c4), + TOBN(0x2d50f8ba, 0xbb05b629), TOBN(0x73c1abe2, 0x6e66efbb), + TOBN(0xefd4b422, 0xf2488af7), TOBN(0xe4105d02, 0x663ba575), + TOBN(0x7eb60a8b, 0x53a69457), TOBN(0x62210008, 0xc945973b), + TOBN(0xfb255478, 0x77a50ec6), TOBN(0xbf0392f7, 0x0a37a72c), + TOBN(0xa0a7a19c, 0x4be18e7a), TOBN(0x90d8ea16, 0x25b1e0af), + TOBN(0x7582a293, 0xef953f57), TOBN(0x90a64d05, 0xbdc5465a), + TOBN(0xca79c497, 0xe2510717), TOBN(0x560dbb7c, 0x18cb641f), + TOBN(0x1d8e3286, 0x4b66abfb), TOBN(0xd26f52e5, 0x59030900), + TOBN(0x1ee3f643, 0x5584941a), TOBN(0x6d3b3730, 0x569f5958), + TOBN(0x9ff2a62f, 0x4789dba5), TOBN(0x91fcb815, 0x72b5c9b7), + TOBN(0xf446cb7d, 0x6c8f9a0e), TOBN(0x48f625c1, 0x39b7ecb5), + TOBN(0xbabae801, 0x1c6219b8), TOBN(0xe7a562d9, 0x28ac2f23), + TOBN(0xe1b48732, 0x26e20588), TOBN(0x06ee1cad, 0x775af051), + TOBN(0xda29ae43, 0xfaff79f7), TOBN(0xc141a412, 0x652ee9e0), + TOBN(0x1e127f6f, 0x195f4bd0), TOBN(0x29c6ab4f, 0x072f34f8), + TOBN(0x7b7c1477, 0x30448112), TOBN(0x82b51af1, 0xe4a38656), + TOBN(0x2bf2028a, 0x2f315010), TOBN(0xc9a4a01f, 0x6ea88cd4), + TOBN(0xf63e95d8, 0x257e5818), TOBN(0xdd8efa10, 0xb4519b16), + TOBN(0xed8973e0, 0x0da910bf), TOBN(0xed49d077, 0x5c0fe4a9), + TOBN(0xac3aac5e, 0xb7caee1e), TOBN(0x1033898d, 0xa7f4da57), + TOBN(0x42145c0e, 0x5c6669b9), TOBN(0x42daa688, 0xc1aa2aa0), + TOBN(0x629cc15c, 0x1a1d885a), TOBN(0x25572ec0, 0xf4b76817), + TOBN(0x8312e435, 0x9c8f8f28), TOBN(0x8107f8cd, 0x81965490), + TOBN(0x516ff3a3, 0x6fa6110c), TOBN(0x74fb1eb1, 0xfb93561f), + TOBN(0x6c0c9047, 0x8457522b), TOBN(0xcfd32104, 0x6bb8bdc6), + TOBN(0x2d6884a2, 0xcc80ad57), TOBN(0x7c27fc35, 0x86a9b637), + TOBN(0x3461baed, 0xadf4e8cd), TOBN(0x1d56251a, 0x617242f0), + TOBN(0x0b80d209, 0xc955bef4), TOBN(0xdf02cad2, 0x06adb047), + TOBN(0xf0d7cb91, 0x5ec74fee), TOBN(0xd2503375, 0x1111ba44), + TOBN(0x9671755e, 0xdf53cb36), TOBN(0x54dcb612, 0x3368551b), + TOBN(0x66d69aac, 0xc8a025a4), TOBN(0x6be946c6, 0xe77ef445), + TOBN(0x719946d1, 0xa995e094), TOBN(0x65e848f6, 0xe51e04d8), + TOBN(0xe62f3300, 0x6a1e3113), TOBN(0x1541c7c1, 0x501de503), + TOBN(0x4daac9fa, 0xf4acfade), TOBN(0x0e585897, 0x44cd0b71), + TOBN(0x544fd869, 0x0a51cd77), TOBN(0x60fc20ed, 0x0031016d), + TOBN(0x58b404ec, 0xa4276867), TOBN(0x46f6c3cc, 0x34f34993), + TOBN(0x477ca007, 0xc636e5bd), TOBN(0x8018f5e5, 0x7c458b47), + TOBN(0xa1202270, 0xe47b668f), TOBN(0xcef48ccd, 0xee14f203), + TOBN(0x23f98bae, 0x62ff9b4d), TOBN(0x55acc035, 0xc589eddd), + TOBN(0x3fe712af, 0x64db4444), TOBN(0x19e9d634, 0xbecdd480), + TOBN(0xe08bc047, 0xa930978a), TOBN(0x2dbf24ec, 0xa1280733), + TOBN(0x3c0ae38c, 0x2cd706b2), TOBN(0x5b012a5b, 0x359017b9), + TOBN(0x3943c38c, 0x72e0f5ae), TOBN(0x786167ea, 0x57176fa3), + TOBN(0xe5f9897d, 0x594881dc), TOBN(0x6b5efad8, 0xcfb820c1), + TOBN(0xb2179093, 0xd55018de), TOBN(0x39ad7d32, 0x0bac56ce), + TOBN(0xb55122e0, 0x2cfc0e81), TOBN(0x117c4661, 0xf6d89daa), + TOBN(0x362d01e1, 0xcb64fa09), TOBN(0x6a309b4e, 0x3e9c4ddd), + TOBN(0xfa979fb7, 0xabea49b1), TOBN(0xb4b1d27d, 0x10e2c6c5), + TOBN(0xbd61c2c4, 0x23afde7a), TOBN(0xeb6614f8, 0x9786d358), + TOBN(0x4a5d816b, 0x7f6f7459), TOBN(0xe431a44f, 0x09360e7b), + TOBN(0x8c27a032, 0xc309914c), TOBN(0xcea5d68a, 0xcaede3d8), + TOBN(0x3668f665, 0x3a0a3f95), TOBN(0x89369416, 0x7ceba27b), + TOBN(0x89981fad, 0xe4728fe9), TOBN(0x7102c8a0, 0x8a093562), + TOBN(0xbb80310e, 0x235d21c8), TOBN(0x505e55d1, 0xbefb7f7b), + TOBN(0xa0a90811, 0x12958a67), TOBN(0xd67e106a, 0x4d851fef), + TOBN(0xb84011a9, 0x431dd80e), TOBN(0xeb7c7cca, 0x73306cd9), + TOBN(0x20fadd29, 0xd1b3b730), TOBN(0x83858b5b, 0xfe37b3d3), + TOBN(0xbf4cd193, 0xb6251d5c), TOBN(0x1cca1fd3, 0x1352d952), + TOBN(0xc66157a4, 0x90fbc051), TOBN(0x7990a638, 0x89b98636)}, + {TOBN(0xe5aa692a, 0x87dec0e1), TOBN(0x010ded8d, 0xf7b39d00), + TOBN(0x7b1b80c8, 0x54cfa0b5), TOBN(0x66beb876, 0xa0f8ea28), + TOBN(0x50d7f531, 0x3476cd0e), TOBN(0xa63d0e65, 0xb08d3949), + TOBN(0x1a09eea9, 0x53479fc6), TOBN(0x82ae9891, 0xf499e742), + TOBN(0xab58b910, 0x5ca7d866), TOBN(0x582967e2, 0x3adb3b34), + TOBN(0x89ae4447, 0xcceac0bc), TOBN(0x919c667c, 0x7bf56af5), + TOBN(0x9aec17b1, 0x60f5dcd7), TOBN(0xec697b9f, 0xddcaadbc), + TOBN(0x0b98f341, 0x463467f5), TOBN(0xb187f1f7, 0xa967132f), + TOBN(0x90fe7a1d, 0x214aeb18), TOBN(0x1506af3c, 0x741432f7), + TOBN(0xbb5565f9, 0xe591a0c4), TOBN(0x10d41a77, 0xb44f1bc3), + TOBN(0xa09d65e4, 0xa84bde96), TOBN(0x42f060d8, 0xf20a6a1c), + TOBN(0x652a3bfd, 0xf27f9ce7), TOBN(0xb6bdb65c, 0x3b3d739f), + TOBN(0xeb5ddcb6, 0xec7fae9f), TOBN(0x995f2714, 0xefb66e5a), + TOBN(0xdee95d8e, 0x69445d52), TOBN(0x1b6c2d46, 0x09e27620), + TOBN(0x32621c31, 0x8129d716), TOBN(0xb03909f1, 0x0958c1aa), + TOBN(0x8c468ef9, 0x1af4af63), TOBN(0x162c429f, 0xfba5cdf6), + TOBN(0x2f682343, 0x753b9371), TOBN(0x29cab45a, 0x5f1f9cd7), + TOBN(0x571623ab, 0xb245db96), TOBN(0xc507db09, 0x3fd79999), + TOBN(0x4e2ef652, 0xaf036c32), TOBN(0x86f0cc78, 0x05018e5c), + TOBN(0xc10a73d4, 0xab8be350), TOBN(0x6519b397, 0x7e826327), + TOBN(0xe8cb5eef, 0x9c053df7), TOBN(0x8de25b37, 0xb300ea6f), + TOBN(0xdb03fa92, 0xc849cffb), TOBN(0x242e43a7, 0xe84169bb), + TOBN(0xe4fa51f4, 0xdd6f958e), TOBN(0x6925a77f, 0xf4445a8d), + TOBN(0xe6e72a50, 0xe90d8949), TOBN(0xc66648e3, 0x2b1f6390), + TOBN(0xb2ab1957, 0x173e460c), TOBN(0x1bbbce75, 0x30704590), + TOBN(0xc0a90dbd, 0xdb1c7162), TOBN(0x505e399e, 0x15cdd65d), + TOBN(0x68434dcb, 0x57797ab7), TOBN(0x60ad35ba, 0x6a2ca8e8), + TOBN(0x4bfdb1e0, 0xde3336c1), TOBN(0xbbef99eb, 0xd8b39015), + TOBN(0x6c3b96f3, 0x1711ebec), TOBN(0x2da40f1f, 0xce98fdc4), + TOBN(0xb99774d3, 0x57b4411f), TOBN(0x87c8bdf4, 0x15b65bb6), + TOBN(0xda3a89e3, 0xc2eef12d), TOBN(0xde95bb9b, 0x3c7471f3), + TOBN(0x600f225b, 0xd812c594), TOBN(0x54907c5d, 0x2b75a56b), + TOBN(0xa93cc5f0, 0x8db60e35), TOBN(0x743e3cd6, 0xfa833319), + TOBN(0x7dad5c41, 0xf81683c9), TOBN(0x70c1e7d9, 0x9c34107e), + TOBN(0x0edc4a39, 0xa6be0907), TOBN(0x36d47035, 0x86d0b7d3), + TOBN(0x8c76da03, 0x272bfa60), TOBN(0x0b4a07ea, 0x0f08a414), + TOBN(0x699e4d29, 0x45c1dd53), TOBN(0xcadc5898, 0x231debb5), + TOBN(0xdf49fcc7, 0xa77f00e0), TOBN(0x93057bbf, 0xa73e5a0e), + TOBN(0x2f8b7ecd, 0x027a4cd1), TOBN(0x114734b3, 0xc614011a), + TOBN(0xe7a01db7, 0x67677c68), TOBN(0x89d9be5e, 0x7e273f4f), + TOBN(0xd225cb2e, 0x089808ef), TOBN(0xf1f7a27d, 0xd59e4107), + TOBN(0x53afc761, 0x8211b9c9), TOBN(0x0361bc67, 0xe6819159), + TOBN(0x2a865d0b, 0x7f071426), TOBN(0x6a3c1810, 0xe7072567), + TOBN(0x3e3bca1e, 0x0d6bcabd), TOBN(0xa1b02bc1, 0x408591bc), + TOBN(0xe0deee59, 0x31fba239), TOBN(0xf47424d3, 0x98bd91d1), + TOBN(0x0f8886f4, 0x071a3c1d), TOBN(0x3f7d41e8, 0xa819233b), + TOBN(0x708623c2, 0xcf6eb998), TOBN(0x86bb49af, 0x609a287f), + TOBN(0x942bb249, 0x63c90762), TOBN(0x0ef6eea5, 0x55a9654b), + TOBN(0x5f6d2d72, 0x36f5defe), TOBN(0xfa9922dc, 0x56f99176), + TOBN(0x6c8c5ece, 0xf78ce0c7), TOBN(0x7b44589d, 0xbe09b55e), + TOBN(0xe11b3bca, 0x9ea83770), TOBN(0xd7fa2c7f, 0x2ab71547), + TOBN(0x2a3dd6fa, 0x2a1ddcc0), TOBN(0x09acb430, 0x5a7b7707), + TOBN(0x4add4a2e, 0x649d4e57), TOBN(0xcd53a2b0, 0x1917526e), + TOBN(0xc5262330, 0x20b44ac4), TOBN(0x4028746a, 0xbaa2c31d), + TOBN(0x51318390, 0x64291d4c), TOBN(0xbf48f151, 0xee5ad909), + TOBN(0xcce57f59, 0x7b185681), TOBN(0x7c3ac1b0, 0x4854d442), + TOBN(0x65587dc3, 0xc093c171), TOBN(0xae7acb24, 0x24f42b65), + TOBN(0x5a338adb, 0x955996cb), TOBN(0xc8e65675, 0x6051f91b), + TOBN(0x66711fba, 0x28b8d0b1), TOBN(0x15d74137, 0xb6c10a90), + TOBN(0x70cdd7eb, 0x3a232a80), TOBN(0xc9e2f07f, 0x6191ed24), + TOBN(0xa80d1db6, 0xf79588c0), TOBN(0xfa52fc69, 0xb55768cc), + TOBN(0x0b4df1ae, 0x7f54438a), TOBN(0x0cadd1a7, 0xf9b46a4f), + TOBN(0xb40ea6b3, 0x1803dd6f), TOBN(0x488e4fa5, 0x55eaae35), + TOBN(0x9f047d55, 0x382e4e16), TOBN(0xc9b5b7e0, 0x2f6e0c98), + TOBN(0x6b1bd2d3, 0x95762649), TOBN(0xa9604ee7, 0xc7aea3f6), + TOBN(0x3646ff27, 0x6dc6f896), TOBN(0x9bf0e7f5, 0x2860bad1), + TOBN(0x2d92c821, 0x7cb44b92), TOBN(0xa2f5ce63, 0xaea9c182), + TOBN(0xd0a2afb1, 0x9154a5fd), TOBN(0x482e474c, 0x95801da6), + TOBN(0xc19972d0, 0xb611c24b), TOBN(0x1d468e65, 0x60a8f351), + TOBN(0xeb758069, 0x7bcf6421), TOBN(0xec9dd0ee, 0x88fbc491), + TOBN(0x5b59d2bf, 0x956c2e32), TOBN(0x73dc6864, 0xdcddf94e), + TOBN(0xfd5e2321, 0xbcee7665), TOBN(0xa7b4f8ef, 0x5e9a06c4), + TOBN(0xfba918dd, 0x7280f855), TOBN(0xbbaac260, 0x8baec688), + TOBN(0xa3b3f00f, 0x33400f42), TOBN(0x3d2dba29, 0x66f2e6e4), + TOBN(0xb6f71a94, 0x98509375), TOBN(0x8f33031f, 0xcea423cc), + TOBN(0x009b8dd0, 0x4807e6fb), TOBN(0x5163cfe5, 0x5cdb954c), + TOBN(0x03cc8f17, 0xcf41c6e8), TOBN(0xf1f03c2a, 0x037b925c), + TOBN(0xc39c19cc, 0x66d2427c), TOBN(0x823d24ba, 0x7b6c18e4), + TOBN(0x32ef9013, 0x901f0b4f), TOBN(0x684360f1, 0xf8941c2e), + TOBN(0x0ebaff52, 0x2c28092e), TOBN(0x7891e4e3, 0x256c932f), + TOBN(0x51264319, 0xac445e3d), TOBN(0x553432e7, 0x8ea74381), + TOBN(0xe6eeaa69, 0x67e9c50a), TOBN(0x27ced284, 0x62e628c7), + TOBN(0x3f96d375, 0x7a4afa57), TOBN(0xde0a14c3, 0xe484c150), + TOBN(0x364a24eb, 0x38bd9923), TOBN(0x1df18da0, 0xe5177422), + TOBN(0x174e8f82, 0xd8d38a9b), TOBN(0x2e97c600, 0xe7de1391), + TOBN(0xc5709850, 0xa1c175dd), TOBN(0x969041a0, 0x32ae5035), + TOBN(0xcbfd533b, 0x76a2086b), TOBN(0xd6bba71b, 0xd7c2e8fe), + TOBN(0xb2d58ee6, 0x099dfb67), TOBN(0x3a8b342d, 0x064a85d9), + TOBN(0x3bc07649, 0x522f9be3), TOBN(0x690c075b, 0xdf1f49a8), + TOBN(0x80e1aee8, 0x3854ec42), TOBN(0x2a7dbf44, 0x17689dc7), + TOBN(0xc004fc0e, 0x3faf4078), TOBN(0xb2f02e9e, 0xdf11862c), + TOBN(0xf10a5e0f, 0xa0a1b7b3), TOBN(0x30aca623, 0x8936ec80), + TOBN(0xf83cbf05, 0x02f40d9a), TOBN(0x4681c468, 0x2c318a4d), + TOBN(0x98575618, 0x0e9c2674), TOBN(0xbe79d046, 0x1847092e), + TOBN(0xaf1e480a, 0x78bd01e0), TOBN(0x6dd359e4, 0x72a51db9), + TOBN(0x62ce3821, 0xe3afbab6), TOBN(0xc5cee5b6, 0x17733199), + TOBN(0xe08b30d4, 0x6ffd9fbb), TOBN(0x6e5bc699, 0x36c610b7), + TOBN(0xf343cff2, 0x9ce262cf), TOBN(0xca2e4e35, 0x68b914c1), + TOBN(0x011d64c0, 0x16de36c5), TOBN(0xe0b10fdd, 0x42e2b829), + TOBN(0x78942981, 0x6685aaf8), TOBN(0xe7511708, 0x230ede97), + TOBN(0x671ed8fc, 0x3b922bf8), TOBN(0xe4d8c0a0, 0x4c29b133), + TOBN(0x87eb1239, 0x3b6e99c4), TOBN(0xaff3974c, 0x8793beba), + TOBN(0x03749405, 0x2c18df9b), TOBN(0xc5c3a293, 0x91007139), + TOBN(0x6a77234f, 0xe37a0b95), TOBN(0x02c29a21, 0xb661c96b), + TOBN(0xc3aaf1d6, 0x141ecf61), TOBN(0x9195509e, 0x3bb22f53), + TOBN(0x29597404, 0x22d51357), TOBN(0x1b083822, 0x537bed60), + TOBN(0xcd7d6e35, 0xe07289f0), TOBN(0x1f94c48c, 0x6dd86eff), + TOBN(0xc8bb1f82, 0xeb0f9cfa), TOBN(0x9ee0b7e6, 0x1b2eb97d), + TOBN(0x5a52fe2e, 0x34d74e31), TOBN(0xa352c310, 0x3bf79ab6), + TOBN(0x97ff6c5a, 0xabfeeb8f), TOBN(0xbfbe8fef, 0xf5c97305), + TOBN(0xd6081ce6, 0xa7904608), TOBN(0x1f812f3a, 0xc4fca249), + TOBN(0x9b24bc9a, 0xb9e5e200), TOBN(0x91022c67, 0x38012ee8), + TOBN(0xe83d9c5d, 0x30a713a1), TOBN(0x4876e3f0, 0x84ef0f93), + TOBN(0xc9777029, 0xc1fbf928), TOBN(0xef7a6bb3, 0xbce7d2a4), + TOBN(0xb8067228, 0xdfa2a659), TOBN(0xd5cd3398, 0xd877a48f), + TOBN(0xbea4fd8f, 0x025d0f3f), TOBN(0xd67d2e35, 0x2eae7c2b), + TOBN(0x184de7d7, 0xcc5f4394), TOBN(0xb5551b5c, 0x4536e142), + TOBN(0x2e89b212, 0xd34aa60a), TOBN(0x14a96fea, 0xf50051d5), + TOBN(0x4e21ef74, 0x0d12bb0b), TOBN(0xc522f020, 0x60b9677e), + TOBN(0x8b12e467, 0x2df7731d), TOBN(0x39f80382, 0x7b326d31), + TOBN(0xdfb8630c, 0x39024a94), TOBN(0xaacb96a8, 0x97319452), + TOBN(0xd68a3961, 0xeda3867c), TOBN(0x0c58e2b0, 0x77c4ffca), + TOBN(0x3d545d63, 0x4da919fa), TOBN(0xef79b69a, 0xf15e2289), + TOBN(0x54bc3d3d, 0x808bab10), TOBN(0xc8ab3007, 0x45f82c37), + TOBN(0xc12738b6, 0x7c4a658a), TOBN(0xb3c47639, 0x40e72182), + TOBN(0x3b77be46, 0x8798e44f), TOBN(0xdc047df2, 0x17a7f85f), + TOBN(0x2439d4c5, 0x5e59d92d), TOBN(0xcedca475, 0xe8e64d8d), + TOBN(0xa724cd0d, 0x87ca9b16), TOBN(0x35e4fd59, 0xa5540dfe), + TOBN(0xf8c1ff18, 0xe4bcf6b1), TOBN(0x856d6285, 0x295018fa), + TOBN(0x433f665c, 0x3263c949), TOBN(0xa6a76dd6, 0xa1f21409), + TOBN(0x17d32334, 0xcc7b4f79), TOBN(0xa1d03122, 0x06720e4a), + TOBN(0xadb6661d, 0x81d9bed5), TOBN(0xf0d6fb02, 0x11db15d1), + TOBN(0x7fd11ad5, 0x1fb747d2), TOBN(0xab50f959, 0x3033762b), + TOBN(0x2a7e711b, 0xfbefaf5a), TOBN(0xc7393278, 0x3fef2bbf), + TOBN(0xe29fa244, 0x0df6f9be), TOBN(0x9092757b, 0x71efd215), + TOBN(0xee60e311, 0x4f3d6fd9), TOBN(0x338542d4, 0x0acfb78b), + TOBN(0x44a23f08, 0x38961a0f), TOBN(0x1426eade, 0x986987ca), + TOBN(0x36e6ee2e, 0x4a863cc6), TOBN(0x48059420, 0x628b8b79), + TOBN(0x30303ad8, 0x7396e1de), TOBN(0x5c8bdc48, 0x38c5aad1), + TOBN(0x3e40e11f, 0x5c8f5066), TOBN(0xabd6e768, 0x8d246bbd), + TOBN(0x68aa40bb, 0x23330a01), TOBN(0xd23f5ee4, 0xc34eafa0), + TOBN(0x3bbee315, 0x5de02c21), TOBN(0x18dd4397, 0xd1d8dd06), + TOBN(0x3ba1939a, 0x122d7b44), TOBN(0xe6d3b40a, 0xa33870d6), + TOBN(0x8e620f70, 0x1c4fe3f8), TOBN(0xf6bba1a5, 0xd3a50cbf), + TOBN(0x4a78bde5, 0xcfc0aee0), TOBN(0x847edc46, 0xc08c50bd), + TOBN(0xbaa2439c, 0xad63c9b2), TOBN(0xceb4a728, 0x10fc2acb), + TOBN(0xa419e40e, 0x26da033d), TOBN(0x6cc3889d, 0x03e02683), + TOBN(0x1cd28559, 0xfdccf725), TOBN(0x0fd7e0f1, 0x8d13d208), + TOBN(0x01b9733b, 0x1f0df9d4), TOBN(0x8cc2c5f3, 0xa2b5e4f3), + TOBN(0x43053bfa, 0x3a304fd4), TOBN(0x8e87665c, 0x0a9f1aa7), + TOBN(0x087f29ec, 0xd73dc965), TOBN(0x15ace455, 0x3e9023db), + TOBN(0x2370e309, 0x2bce28b4), TOBN(0xf9723442, 0xb6b1e84a), + TOBN(0xbeee662e, 0xb72d9f26), TOBN(0xb19396de, 0xf0e47109), + TOBN(0x85b1fa73, 0xe13289d0), TOBN(0x436cf77e, 0x54e58e32), + TOBN(0x0ec833b3, 0xe990ef77), TOBN(0x7373e3ed, 0x1b11fc25), + TOBN(0xbe0eda87, 0x0fc332ce), TOBN(0xced04970, 0x8d7ea856), + TOBN(0xf85ff785, 0x7e977ca0), TOBN(0xb66ee8da, 0xdfdd5d2b), + TOBN(0xf5e37950, 0x905af461), TOBN(0x587b9090, 0x966d487c), + TOBN(0x6a198a1b, 0x32ba0127), TOBN(0xa7720e07, 0x141615ac), + TOBN(0xa23f3499, 0x996ef2f2), TOBN(0xef5f64b4, 0x470bcb3d), + TOBN(0xa526a962, 0x92b8c559), TOBN(0x0c14aac0, 0x69740a0f), + TOBN(0x0d41a9e3, 0xa6bdc0a5), TOBN(0x97d52106, 0x9c48aef4), + TOBN(0xcf16bd30, 0x3e7c253b), TOBN(0xcc834b1a, 0x47fdedc1), + TOBN(0x7362c6e5, 0x373aab2e), TOBN(0x264ed85e, 0xc5f590ff), + TOBN(0x7a46d9c0, 0x66d41870), TOBN(0xa50c20b1, 0x4787ba09), + TOBN(0x185e7e51, 0xe3d44635), TOBN(0xb3b3e080, 0x31e2d8dc), + TOBN(0xbed1e558, 0xa179e9d9), TOBN(0x2daa3f79, 0x74a76781), + TOBN(0x4372baf2, 0x3a40864f), TOBN(0x46900c54, 0x4fe75cb5), + TOBN(0xb95f171e, 0xf76765d0), TOBN(0x4ad726d2, 0x95c87502), + TOBN(0x2ec769da, 0x4d7c99bd), TOBN(0x5e2ddd19, 0xc36cdfa8), + TOBN(0xc22117fc, 0xa93e6dea), TOBN(0xe8a2583b, 0x93771123), + TOBN(0xbe2f6089, 0xfa08a3a2), TOBN(0x4809d5ed, 0x8f0e1112), + TOBN(0x3b414aa3, 0xda7a095e), TOBN(0x9049acf1, 0x26f5aadd), + TOBN(0x78d46a4d, 0x6be8b84a), TOBN(0xd66b1963, 0xb732b9b3), + TOBN(0x5c2ac2a0, 0xde6e9555), TOBN(0xcf52d098, 0xb5bd8770), + TOBN(0x15a15fa6, 0x0fd28921), TOBN(0x56ccb81e, 0x8b27536d), + TOBN(0x0f0d8ab8, 0x9f4ccbb8), TOBN(0xed5f44d2, 0xdb221729), + TOBN(0x43141988, 0x00bed10c), TOBN(0xc94348a4, 0x1d735b8b), + TOBN(0x79f3e9c4, 0x29ef8479), TOBN(0x4c13a4e3, 0x614c693f), + TOBN(0x32c9af56, 0x8e143a14), TOBN(0xbc517799, 0xe29ac5c4), + TOBN(0x05e17992, 0x2774856f), TOBN(0x6e52fb05, 0x6c1bf55f), + TOBN(0xaeda4225, 0xe4f19e16), TOBN(0x70f4728a, 0xaf5ccb26), + TOBN(0x5d2118d1, 0xb2947f22), TOBN(0xc827ea16, 0x281d6fb9), + TOBN(0x8412328d, 0x8cf0eabd), TOBN(0x45ee9fb2, 0x03ef9dcf), + TOBN(0x8e700421, 0xbb937d63), TOBN(0xdf8ff2d5, 0xcc4b37a6), + TOBN(0xa4c0d5b2, 0x5ced7b68), TOBN(0x6537c1ef, 0xc7308f59), + TOBN(0x25ce6a26, 0x3b37f8e8), TOBN(0x170e9a9b, 0xdeebc6ce), + TOBN(0xdd037952, 0x8728d72c), TOBN(0x445b0e55, 0x850154bc), + TOBN(0x4b7d0e06, 0x83a7337b), TOBN(0x1e3416d4, 0xffecf249), + TOBN(0x24840eff, 0x66a2b71f), TOBN(0xd0d9a50a, 0xb37cc26d), + TOBN(0xe2198150, 0x6fe28ef7), TOBN(0x3cc5ef16, 0x23324c7f), + TOBN(0x220f3455, 0x769b5263), TOBN(0xe2ade2f1, 0xa10bf475), + TOBN(0x28cd20fa, 0x458d3671), TOBN(0x1549722c, 0x2dc4847b), + TOBN(0x6dd01e55, 0x591941e3), TOBN(0x0e6fbcea, 0x27128ccb), + TOBN(0xae1a1e6b, 0x3bef0262), TOBN(0xfa8c472c, 0x8f54e103), + TOBN(0x7539c0a8, 0x72c052ec), TOBN(0xd7b27369, 0x5a3490e9), + TOBN(0x143fe1f1, 0x71684349), TOBN(0x36b4722e, 0x32e19b97), + TOBN(0xdc059227, 0x90980aff), TOBN(0x175c9c88, 0x9e13d674), + TOBN(0xa7de5b22, 0x6e6bfdb1), TOBN(0x5ea5b7b2, 0xbedb4b46), + TOBN(0xd5570191, 0xd34a6e44), TOBN(0xfcf60d2e, 0xa24ff7e6), + TOBN(0x614a392d, 0x677819e1), TOBN(0x7be74c7e, 0xaa5a29e8), + TOBN(0xab50fece, 0x63c85f3f), TOBN(0xaca2e2a9, 0x46cab337), + TOBN(0x7f700388, 0x122a6fe3), TOBN(0xdb69f703, 0x882a04a8), + TOBN(0x9a77935d, 0xcf7aed57), TOBN(0xdf16207c, 0x8d91c86f), + TOBN(0x2fca49ab, 0x63ed9998), TOBN(0xa3125c44, 0xa77ddf96), + TOBN(0x05dd8a86, 0x24344072), TOBN(0xa023dda2, 0xfec3fb56), + TOBN(0x421b41fc, 0x0c743032), TOBN(0x4f2120c1, 0x5e438639), + TOBN(0xfb7cae51, 0xc83c1b07), TOBN(0xb2370caa, 0xcac2171a), + TOBN(0x2eb2d962, 0x6cc820fb), TOBN(0x59feee5c, 0xb85a44bf), + TOBN(0x94620fca, 0x5b6598f0), TOBN(0x6b922cae, 0x7e314051), + TOBN(0xff8745ad, 0x106bed4e), TOBN(0x546e71f5, 0xdfa1e9ab), + TOBN(0x935c1e48, 0x1ec29487), TOBN(0x9509216c, 0x4d936530), + TOBN(0xc7ca3067, 0x85c9a2db), TOBN(0xd6ae5152, 0x6be8606f), + TOBN(0x09dbcae6, 0xe14c651d), TOBN(0xc9536e23, 0x9bc32f96), + TOBN(0xa90535a9, 0x34521b03), TOBN(0xf39c526c, 0x878756ff), + TOBN(0x383172ec, 0x8aedf03c), TOBN(0x20a8075e, 0xefe0c034), + TOBN(0xf22f9c62, 0x64026422), TOBN(0x8dd10780, 0x24b9d076), + TOBN(0x944c742a, 0x3bef2950), TOBN(0x55b9502e, 0x88a2b00b), + TOBN(0xa59e14b4, 0x86a09817), TOBN(0xa39dd3ac, 0x47bb4071), + TOBN(0x55137f66, 0x3be0592f), TOBN(0x07fcafd4, 0xc9e63f5b), + TOBN(0x963652ee, 0x346eb226), TOBN(0x7dfab085, 0xec2facb7), + TOBN(0x273bf2b8, 0x691add26), TOBN(0x30d74540, 0xf2b46c44), + TOBN(0x05e8e73e, 0xf2c2d065), TOBN(0xff9b8a00, 0xd42eeac9), + TOBN(0x2fcbd205, 0x97209d22), TOBN(0xeb740ffa, 0xde14ea2c), + TOBN(0xc71ff913, 0xa8aef518), TOBN(0x7bfc74bb, 0xfff4cfa2), + TOBN(0x1716680c, 0xb6b36048), TOBN(0x121b2cce, 0x9ef79af1), + TOBN(0xbff3c836, 0xa01eb3d3), TOBN(0x50eb1c6a, 0x5f79077b), + TOBN(0xa48c32d6, 0xa004bbcf), TOBN(0x47a59316, 0x7d64f61d), + TOBN(0x6068147f, 0x93102016), TOBN(0x12c5f654, 0x94d12576), + TOBN(0xefb071a7, 0xc9bc6b91), TOBN(0x7c2da0c5, 0x6e23ea95), + TOBN(0xf4fd45b6, 0xd4a1dd5d), TOBN(0x3e7ad9b6, 0x9122b13c), + TOBN(0x342ca118, 0xe6f57a48), TOBN(0x1c2e94a7, 0x06f8288f), + TOBN(0x99e68f07, 0x5a97d231), TOBN(0x7c80de97, 0x4d838758), + TOBN(0xbce0f5d0, 0x05872727), TOBN(0xbe5d95c2, 0x19c4d016), + TOBN(0x921d5cb1, 0x9c2492ee), TOBN(0x42192dc1, 0x404d6fb3), + TOBN(0x4c84dcd1, 0x32f988d3), TOBN(0xde26d61f, 0xa17b8e85), + TOBN(0xc466dcb6, 0x137c7408), TOBN(0x9a38d7b6, 0x36a266da), + TOBN(0x7ef5cb06, 0x83bebf1b), TOBN(0xe5cdcbbf, 0x0fd014e3), + TOBN(0x30aa376d, 0xf65965a0), TOBN(0x60fe88c2, 0xebb3e95e), + TOBN(0x33fd0b61, 0x66ee6f20), TOBN(0x8827dcdb, 0x3f41f0a0), + TOBN(0xbf8a9d24, 0x0c56c690), TOBN(0x40265dad, 0xddb7641d), + TOBN(0x522b05bf, 0x3a6b662b), TOBN(0x466d1dfe, 0xb1478c9b), + TOBN(0xaa616962, 0x1484469b), TOBN(0x0db60549, 0x02df8f9f), + TOBN(0xc37bca02, 0x3cb8bf51), TOBN(0x5effe346, 0x21371ce8), + TOBN(0xe8f65264, 0xff112c32), TOBN(0x8a9c736d, 0x7b971fb2), + TOBN(0xa4f19470, 0x7b75080d), TOBN(0xfc3f2c5a, 0x8839c59b), + TOBN(0x1d6c777e, 0x5aeb49c2), TOBN(0xf3db034d, 0xda1addfe), + TOBN(0xd76fee5a, 0x5535affc), TOBN(0x0853ac70, 0xb92251fd), + TOBN(0x37e3d594, 0x8b2a29d5), TOBN(0x28f1f457, 0x4de00ddb), + TOBN(0x8083c1b5, 0xf42c328b), TOBN(0xd8ef1d8f, 0xe493c73b), + TOBN(0x96fb6260, 0x41dc61bd), TOBN(0xf74e8a9d, 0x27ee2f8a), + TOBN(0x7c605a80, 0x2c946a5d), TOBN(0xeed48d65, 0x3839ccfd), + TOBN(0x9894344f, 0x3a29467a), TOBN(0xde81e949, 0xc51eba6d), + TOBN(0xdaea066b, 0xa5e5c2f2), TOBN(0x3fc8a614, 0x08c8c7b3), + TOBN(0x7adff88f, 0x06d0de9f), TOBN(0xbbc11cf5, 0x3b75ce0a), + TOBN(0x9fbb7acc, 0xfbbc87d5), TOBN(0xa1458e26, 0x7badfde2)}, + {TOBN(0x1cb43668, 0xe039c256), TOBN(0x5f26fb8b, 0x7c17fd5d), + TOBN(0xeee426af, 0x79aa062b), TOBN(0x072002d0, 0xd78fbf04), + TOBN(0x4c9ca237, 0xe84fb7e3), TOBN(0xb401d8a1, 0x0c82133d), + TOBN(0xaaa52592, 0x6d7e4181), TOBN(0xe9430833, 0x73dbb152), + TOBN(0xf92dda31, 0xbe24319a), TOBN(0x03f7d28b, 0xe095a8e7), + TOBN(0xa52fe840, 0x98782185), TOBN(0x276ddafe, 0x29c24dbc), + TOBN(0x80cd5496, 0x1d7a64eb), TOBN(0xe4360889, 0x7f1dbe42), + TOBN(0x2f81a877, 0x8438d2d5), TOBN(0x7e4d52a8, 0x85169036), + TOBN(0x19e3d5b1, 0x1d59715d), TOBN(0xc7eaa762, 0xd788983e), + TOBN(0xe5a730b0, 0xabf1f248), TOBN(0xfbab8084, 0xfae3fd83), + TOBN(0x65e50d21, 0x53765b2f), TOBN(0xbdd4e083, 0xfa127f3d), + TOBN(0x9cf3c074, 0x397b1b10), TOBN(0x59f8090c, 0xb1b59fd3), + TOBN(0x7b15fd9d, 0x615faa8f), TOBN(0x8fa1eb40, 0x968554ed), + TOBN(0x7bb4447e, 0x7aa44882), TOBN(0x2bb2d0d1, 0x029fff32), + TOBN(0x075e2a64, 0x6caa6d2f), TOBN(0x8eb879de, 0x22e7351b), + TOBN(0xbcd5624e, 0x9a506c62), TOBN(0x218eaef0, 0xa87e24dc), + TOBN(0x37e56847, 0x44ddfa35), TOBN(0x9ccfc5c5, 0xdab3f747), + TOBN(0x9ac1df3f, 0x1ee96cf4), TOBN(0x0c0571a1, 0x3b480b8f), + TOBN(0x2fbeb3d5, 0x4b3a7b3c), TOBN(0x35c03669, 0x5dcdbb99), + TOBN(0x52a0f5dc, 0xb2415b3a), TOBN(0xd57759b4, 0x4413ed9a), + TOBN(0x1fe647d8, 0x3d30a2c5), TOBN(0x0857f77e, 0xf78a81dc), + TOBN(0x11d5a334, 0x131a4a9b), TOBN(0xc0a94af9, 0x29d393f5), + TOBN(0xbc3a5c0b, 0xdaa6ec1a), TOBN(0xba9fe493, 0x88d2d7ed), + TOBN(0xbb4335b4, 0xbb614797), TOBN(0x991c4d68, 0x72f83533), + TOBN(0x53258c28, 0xd2f01cb3), TOBN(0x93d6eaa3, 0xd75db0b1), + TOBN(0x419a2b0d, 0xe87d0db4), TOBN(0xa1e48f03, 0xd8fe8493), + TOBN(0xf747faf6, 0xc508b23a), TOBN(0xf137571a, 0x35d53549), + TOBN(0x9f5e58e2, 0xfcf9b838), TOBN(0xc7186cee, 0xa7fd3cf5), + TOBN(0x77b868ce, 0xe978a1d3), TOBN(0xe3a68b33, 0x7ab92d04), + TOBN(0x51029794, 0x87a5b862), TOBN(0x5f0606c3, 0x3a61d41d), + TOBN(0x2814be27, 0x6f9326f1), TOBN(0x2f521c14, 0xc6fe3c2e), + TOBN(0x17464d7d, 0xacdf7351), TOBN(0x10f5f9d3, 0x777f7e44), + TOBN(0xce8e616b, 0x269fb37d), TOBN(0xaaf73804, 0x7de62de5), + TOBN(0xaba11175, 0x4fdd4153), TOBN(0x515759ba, 0x3770b49b), + TOBN(0x8b09ebf8, 0xaa423a61), TOBN(0x592245a1, 0xcd41fb92), + TOBN(0x1cba8ec1, 0x9b4c8936), TOBN(0xa87e91e3, 0xaf36710e), + TOBN(0x1fd84ce4, 0x3d34a2e3), TOBN(0xee3759ce, 0xb43b5d61), + TOBN(0x895bc78c, 0x619186c7), TOBN(0xf19c3809, 0xcbb9725a), + TOBN(0xc0be21aa, 0xde744b1f), TOBN(0xa7d222b0, 0x60f8056b), + TOBN(0x74be6157, 0xb23efe11), TOBN(0x6fab2b4f, 0x0cd68253), + TOBN(0xad33ea5f, 0x4bf1d725), TOBN(0x9c1d8ee2, 0x4f6c950f), + TOBN(0x544ee78a, 0xa377af06), TOBN(0x54f489bb, 0x94a113e1), + TOBN(0x8f11d634, 0x992fb7e8), TOBN(0x0169a7aa, 0xa2a44347), + TOBN(0x1d49d4af, 0x95020e00), TOBN(0x95945722, 0xe08e120b), + TOBN(0xb6e33878, 0xa4d32282), TOBN(0xe36e029d, 0x48020ae7), + TOBN(0xe05847fb, 0x37a9b750), TOBN(0xf876812c, 0xb29e3819), + TOBN(0x84ad138e, 0xd23a17f0), TOBN(0x6d7b4480, 0xf0b3950e), + TOBN(0xdfa8aef4, 0x2fd67ae0), TOBN(0x8d3eea24, 0x52333af6), + TOBN(0x0d052075, 0xb15d5acc), TOBN(0xc6d9c79f, 0xbd815bc4), + TOBN(0x8dcafd88, 0xdfa36cf2), TOBN(0x908ccbe2, 0x38aa9070), + TOBN(0x638722c4, 0xba35afce), TOBN(0x5a3da8b0, 0xfd6abf0b), + TOBN(0x2dce252c, 0xc9c335c1), TOBN(0x84e7f0de, 0x65aa799b), + TOBN(0x2101a522, 0xb99a72cb), TOBN(0x06de6e67, 0x87618016), + TOBN(0x5ff8c7cd, 0xe6f3653e), TOBN(0x0a821ab5, 0xc7a6754a), + TOBN(0x7e3fa52b, 0x7cb0b5a2), TOBN(0xa7fb121c, 0xc9048790), + TOBN(0x1a725020, 0x06ce053a), TOBN(0xb490a31f, 0x04e929b0), + TOBN(0xe17be47d, 0x62dd61ad), TOBN(0x781a961c, 0x6be01371), + TOBN(0x1063bfd3, 0xdae3cbba), TOBN(0x35647406, 0x7f73c9ba), + TOBN(0xf50e957b, 0x2736a129), TOBN(0xa6313702, 0xed13f256), + TOBN(0x9436ee65, 0x3a19fcc5), TOBN(0xcf2bdb29, 0xe7a4c8b6), + TOBN(0xb06b1244, 0xc5f95cd8), TOBN(0xda8c8af0, 0xf4ab95f4), + TOBN(0x1bae59c2, 0xb9e5836d), TOBN(0x07d51e7e, 0x3acffffc), + TOBN(0x01e15e6a, 0xc2ccbcda), TOBN(0x3bc1923f, 0x8528c3e0), + TOBN(0x43324577, 0xa49fead4), TOBN(0x61a1b884, 0x2aa7a711), + TOBN(0xf9a86e08, 0x700230ef), TOBN(0x0af585a1, 0xbd19adf8), + TOBN(0x7645f361, 0xf55ad8f2), TOBN(0x6e676223, 0x46c3614c), + TOBN(0x23cb257c, 0x4e774d3f), TOBN(0x82a38513, 0xac102d1b), + TOBN(0x9bcddd88, 0x7b126aa5), TOBN(0xe716998b, 0xeefd3ee4), + TOBN(0x4239d571, 0xfb167583), TOBN(0xdd011c78, 0xd16c8f8a), + TOBN(0x271c2895, 0x69a27519), TOBN(0x9ce0a3b7, 0xd2d64b6a), + TOBN(0x8c977289, 0xd5ec6738), TOBN(0xa3b49f9a, 0x8840ef6b), + TOBN(0x808c14c9, 0x9a453419), TOBN(0x5c00295b, 0x0cf0a2d5), + TOBN(0x524414fb, 0x1d4bcc76), TOBN(0xb07691d2, 0x459a88f1), + TOBN(0x77f43263, 0xf70d110f), TOBN(0x64ada5e0, 0xb7abf9f3), + TOBN(0xafd0f94e, 0x5b544cf5), TOBN(0xb4a13a15, 0xfd2713fe), + TOBN(0xb99b7d6e, 0x250c74f4), TOBN(0x097f2f73, 0x20324e45), + TOBN(0x994b37d8, 0xaffa8208), TOBN(0xc3c31b0b, 0xdc29aafc), + TOBN(0x3da74651, 0x7a3a607f), TOBN(0xd8e1b8c1, 0xfe6955d6), + TOBN(0x716e1815, 0xc8418682), TOBN(0x541d487f, 0x7dc91d97), + TOBN(0x48a04669, 0xc6996982), TOBN(0xf39cab15, 0x83a6502e), + TOBN(0x025801a0, 0xe68db055), TOBN(0xf3569758, 0xba3338d5), + TOBN(0xb0c8c0aa, 0xee2afa84), TOBN(0x4f6985d3, 0xfb6562d1), + TOBN(0x351f1f15, 0x132ed17a), TOBN(0x510ed0b4, 0xc04365fe), + TOBN(0xa3f98138, 0xe5b1f066), TOBN(0xbc9d95d6, 0x32df03dc), + TOBN(0xa83ccf6e, 0x19abd09e), TOBN(0x0b4097c1, 0x4ff17edb), + TOBN(0x58a5c478, 0xd64a06ce), TOBN(0x2ddcc3fd, 0x544a58fd), + TOBN(0xd449503d, 0x9e8153b8), TOBN(0x3324fd02, 0x7774179b), + TOBN(0xaf5d47c8, 0xdbd9120c), TOBN(0xeb860162, 0x34fa94db), + TOBN(0x5817bdd1, 0x972f07f4), TOBN(0xe5579e2e, 0xd27bbceb), + TOBN(0x86847a1f, 0x5f11e5a6), TOBN(0xb39ed255, 0x7c3cf048), + TOBN(0xe1076417, 0xa2f62e55), TOBN(0x6b9ab38f, 0x1bcf82a2), + TOBN(0x4bb7c319, 0x7aeb29f9), TOBN(0xf6d17da3, 0x17227a46), + TOBN(0xab53ddbd, 0x0f968c00), TOBN(0xa03da7ec, 0x000c880b), + TOBN(0x7b239624, 0x6a9ad24d), TOBN(0x612c0401, 0x01ec60d0), + TOBN(0x70d10493, 0x109f5df1), TOBN(0xfbda4030, 0x80af7550), + TOBN(0x30b93f95, 0xc6b9a9b3), TOBN(0x0c74ec71, 0x007d9418), + TOBN(0x94175564, 0x6edb951f), TOBN(0x5f4a9d78, 0x7f22c282), + TOBN(0xb7870895, 0xb38d1196), TOBN(0xbc593df3, 0xa228ce7c), + TOBN(0xc78c5bd4, 0x6af3641a), TOBN(0x7802200b, 0x3d9b3dcc), + TOBN(0x0dc73f32, 0x8be33304), TOBN(0x847ed87d, 0x61ffb79a), + TOBN(0xf85c974e, 0x6d671192), TOBN(0x1e14100a, 0xde16f60f), + TOBN(0x45cb0d5a, 0x95c38797), TOBN(0x18923bba, 0x9b022da4), + TOBN(0xef2be899, 0xbbe7e86e), TOBN(0x4a1510ee, 0x216067bf), + TOBN(0xd98c8154, 0x84d5ce3e), TOBN(0x1af777f0, 0xf92a2b90), + TOBN(0x9fbcb400, 0x4ef65724), TOBN(0x3e04a4c9, 0x3c0ca6fe), + TOBN(0xfb3e2cb5, 0x55002994), TOBN(0x1f3a93c5, 0x5363ecab), + TOBN(0x1fe00efe, 0x3923555b), TOBN(0x744bedd9, 0x1e1751ea), + TOBN(0x3fb2db59, 0x6ab69357), TOBN(0x8dbd7365, 0xf5e6618b), + TOBN(0x99d53099, 0xdf1ea40e), TOBN(0xb3f24a0b, 0x57d61e64), + TOBN(0xd088a198, 0x596eb812), TOBN(0x22c8361b, 0x5762940b), + TOBN(0x66f01f97, 0xf9c0d95c), TOBN(0x88461172, 0x8e43cdae), + TOBN(0x11599a7f, 0xb72b15c3), TOBN(0x135a7536, 0x420d95cc), + TOBN(0x2dcdf0f7, 0x5f7ae2f6), TOBN(0x15fc6e1d, 0xd7fa6da2), + TOBN(0x81ca829a, 0xd1d441b6), TOBN(0x84c10cf8, 0x04a106b6), + TOBN(0xa9b26c95, 0xa73fbbd0), TOBN(0x7f24e0cb, 0x4d8f6ee8), + TOBN(0x48b45937, 0x1e25a043), TOBN(0xf8a74fca, 0x036f3dfe), + TOBN(0x1ed46585, 0xc9f84296), TOBN(0x7fbaa8fb, 0x3bc278b0), + TOBN(0xa8e96cd4, 0x6c4fcbd0), TOBN(0x940a1202, 0x73b60a5f), + TOBN(0x34aae120, 0x55a4aec8), TOBN(0x550e9a74, 0xdbd742f0), + TOBN(0x794456d7, 0x228c68ab), TOBN(0x492f8868, 0xa4e25ec6), + TOBN(0x682915ad, 0xb2d8f398), TOBN(0xf13b51cc, 0x5b84c953), + TOBN(0xcda90ab8, 0x5bb917d6), TOBN(0x4b615560, 0x4ea3dee1), + TOBN(0x578b4e85, 0x0a52c1c8), TOBN(0xeab1a695, 0x20b75fc4), + TOBN(0x60c14f3c, 0xaa0bb3c6), TOBN(0x220f448a, 0xb8216094), + TOBN(0x4fe7ee31, 0xb0e63d34), TOBN(0xf4600572, 0xa9e54fab), + TOBN(0xc0493334, 0xd5e7b5a4), TOBN(0x8589fb92, 0x06d54831), + TOBN(0xaa70f5cc, 0x6583553a), TOBN(0x0879094a, 0xe25649e5), + TOBN(0xcc904507, 0x10044652), TOBN(0xebb0696d, 0x02541c4f), + TOBN(0x5a171fde, 0xb9718710), TOBN(0x38f1bed8, 0xf374a9f5), + TOBN(0xc8c582e1, 0xba39bdc1), TOBN(0xfc457b0a, 0x908cc0ce), + TOBN(0x9a187fd4, 0x883841e2), TOBN(0x8ec25b39, 0x38725381), + TOBN(0x2553ed05, 0x96f84395), TOBN(0x095c7661, 0x6f6c6897), + TOBN(0x917ac85c, 0x4bdc5610), TOBN(0xb2885fe4, 0x179eb301), + TOBN(0x5fc65547, 0x8b78bdcc), TOBN(0x4a9fc893, 0xe59e4699), + TOBN(0xbb7ff0cd, 0x3ce299af), TOBN(0x195be9b3, 0xadf38b20), + TOBN(0x6a929c87, 0xd38ddb8f), TOBN(0x55fcc99c, 0xb21a51b9), + TOBN(0x2b695b4c, 0x721a4593), TOBN(0xed1e9a15, 0x768eaac2), + TOBN(0xfb63d71c, 0x7489f914), TOBN(0xf98ba31c, 0x78118910), + TOBN(0x80291373, 0x9b128eb4), TOBN(0x7801214e, 0xd448af4a), + TOBN(0xdbd2e22b, 0x55418dd3), TOBN(0xeffb3c0d, 0xd3998242), + TOBN(0xdfa6077c, 0xc7bf3827), TOBN(0xf2165bcb, 0x47f8238f), + TOBN(0xfe37cf68, 0x8564d554), TOBN(0xe5f825c4, 0x0a81fb98), + TOBN(0x43cc4f67, 0xffed4d6f), TOBN(0xbc609578, 0xb50a34b0), + TOBN(0x8aa8fcf9, 0x5041faf1), TOBN(0x5659f053, 0x651773b6), + TOBN(0xe87582c3, 0x6044d63b), TOBN(0xa6089409, 0x0cdb0ca0), + TOBN(0x8c993e0f, 0xbfb2bcf6), TOBN(0xfc64a719, 0x45985cfc), + TOBN(0x15c4da80, 0x83dbedba), TOBN(0x804ae112, 0x2be67df7), + TOBN(0xda4c9658, 0xa23defde), TOBN(0x12002ddd, 0x5156e0d3), + TOBN(0xe68eae89, 0x5dd21b96), TOBN(0x8b99f28b, 0xcf44624d), + TOBN(0x0ae00808, 0x1ec8897a), TOBN(0xdd0a9303, 0x6712f76e), + TOBN(0x96237522, 0x4e233de4), TOBN(0x192445b1, 0x2b36a8a5), + TOBN(0xabf9ff74, 0x023993d9), TOBN(0x21f37bf4, 0x2aad4a8f), + TOBN(0x340a4349, 0xf8bd2bbd), TOBN(0x1d902cd9, 0x4868195d), + TOBN(0x3d27bbf1, 0xe5fdb6f1), TOBN(0x7a5ab088, 0x124f9f1c), + TOBN(0xc466ab06, 0xf7a09e03), TOBN(0x2f8a1977, 0x31f2c123), + TOBN(0xda355dc7, 0x041b6657), TOBN(0xcb840d12, 0x8ece2a7c), + TOBN(0xb600ad9f, 0x7db32675), TOBN(0x78fea133, 0x07a06f1b), + TOBN(0x5d032269, 0xb31f6094), TOBN(0x07753ef5, 0x83ec37aa), + TOBN(0x03485aed, 0x9c0bea78), TOBN(0x41bb3989, 0xbc3f4524), + TOBN(0x09403761, 0x697f726d), TOBN(0x6109beb3, 0xdf394820), + TOBN(0x804111ea, 0x3b6d1145), TOBN(0xb6271ea9, 0xa8582654), + TOBN(0x619615e6, 0x24e66562), TOBN(0xa2554945, 0xd7b6ad9c), + TOBN(0xd9c4985e, 0x99bfe35f), TOBN(0x9770ccc0, 0x7b51cdf6), + TOBN(0x7c327013, 0x92881832), TOBN(0x8777d45f, 0x286b26d1), + TOBN(0x9bbeda22, 0xd847999d), TOBN(0x03aa33b6, 0xc3525d32), + TOBN(0x4b7b96d4, 0x28a959a1), TOBN(0xbb3786e5, 0x31e5d234), + TOBN(0xaeb5d3ce, 0x6961f247), TOBN(0x20aa85af, 0x02f93d3f), + TOBN(0x9cd1ad3d, 0xd7a7ae4f), TOBN(0xbf6688f0, 0x781adaa8), + TOBN(0xb1b40e86, 0x7469cead), TOBN(0x1904c524, 0x309fca48), + TOBN(0x9b7312af, 0x4b54bbc7), TOBN(0xbe24bf8f, 0x593affa2), + TOBN(0xbe5e0790, 0xbd98764b), TOBN(0xa0f45f17, 0xa26e299e), + TOBN(0x4af0d2c2, 0x6b8fe4c7), TOBN(0xef170db1, 0x8ae8a3e6), + TOBN(0x0e8d61a0, 0x29e0ccc1), TOBN(0xcd53e87e, 0x60ad36ca), + TOBN(0x328c6623, 0xc8173822), TOBN(0x7ee1767d, 0xa496be55), + TOBN(0x89f13259, 0x648945af), TOBN(0x9e45a5fd, 0x25c8009c), + TOBN(0xaf2febd9, 0x1f61ab8c), TOBN(0x43f6bc86, 0x8a275385), + TOBN(0x87792348, 0xf2142e79), TOBN(0x17d89259, 0xc6e6238a), + TOBN(0x7536d2f6, 0x4a839d9b), TOBN(0x1f428fce, 0x76a1fbdc), + TOBN(0x1c109601, 0x0db06dfe), TOBN(0xbfc16bc1, 0x50a3a3cc), + TOBN(0xf9cbd9ec, 0x9b30f41b), TOBN(0x5b5da0d6, 0x00138cce), + TOBN(0xec1d0a48, 0x56ef96a7), TOBN(0xb47eb848, 0x982bf842), + TOBN(0x66deae32, 0xec3f700d), TOBN(0x4e43c42c, 0xaa1181e0), + TOBN(0xa1d72a31, 0xd1a4aa2a), TOBN(0x440d4668, 0xc004f3ce), + TOBN(0x0d6a2d3b, 0x45fe8a7a), TOBN(0x820e52e2, 0xfb128365), + TOBN(0x29ac5fcf, 0x25e51b09), TOBN(0x180cd2bf, 0x2023d159), + TOBN(0xa9892171, 0xa1ebf90e), TOBN(0xf97c4c87, 0x7c132181), + TOBN(0x9f1dc724, 0xc03dbb7e), TOBN(0xae043765, 0x018cbbe4), + TOBN(0xfb0b2a36, 0x0767d153), TOBN(0xa8e2f4d6, 0x249cbaeb), + TOBN(0x172a5247, 0xd95ea168), TOBN(0x1758fada, 0x2970764a), + TOBN(0xac803a51, 0x1d978169), TOBN(0x299cfe2e, 0xde77e01b), + TOBN(0x652a1e17, 0xb0a98927), TOBN(0x2e26e1d1, 0x20014495), + TOBN(0x7ae0af9f, 0x7175b56a), TOBN(0xc2e22a80, 0xd64b9f95), + TOBN(0x4d0ff9fb, 0xd90a060a), TOBN(0x496a27db, 0xbaf38085), + TOBN(0x32305401, 0xda776bcf), TOBN(0xb8cdcef6, 0x725f209e), + TOBN(0x61ba0f37, 0x436a0bba), TOBN(0x263fa108, 0x76860049), + TOBN(0x92beb98e, 0xda3542cf), TOBN(0xa2d4d14a, 0xd5849538), + TOBN(0x989b9d68, 0x12e9a1bc), TOBN(0x61d9075c, 0x5f6e3268), + TOBN(0x352c6aa9, 0x99ace638), TOBN(0xde4e4a55, 0x920f43ff), + TOBN(0xe5e4144a, 0xd673c017), TOBN(0x667417ae, 0x6f6e05ea), + TOBN(0x613416ae, 0xdcd1bd56), TOBN(0x5eb36201, 0x86693711), + TOBN(0x2d7bc504, 0x3a1aa914), TOBN(0x175a1299, 0x76dc5975), + TOBN(0xe900e0f2, 0x3fc8125c), TOBN(0x569ef68c, 0x11198875), + TOBN(0x9012db63, 0x63a113b4), TOBN(0xe3bd3f56, 0x98835766), + TOBN(0xa5c94a52, 0x76412dea), TOBN(0xad9e2a09, 0xaa735e5c), + TOBN(0x405a984c, 0x508b65e9), TOBN(0xbde4a1d1, 0x6df1a0d1), + TOBN(0x1a9433a1, 0xdfba80da), TOBN(0xe9192ff9, 0x9440ad2e), + TOBN(0x9f649696, 0x5099fe92), TOBN(0x25ddb65c, 0x0b27a54a), + TOBN(0x178279dd, 0xc590da61), TOBN(0x5479a999, 0xfbde681a), + TOBN(0xd0e84e05, 0x013fe162), TOBN(0xbe11dc92, 0x632d471b), + TOBN(0xdf0b0c45, 0xfc0e089f), TOBN(0x04fb15b0, 0x4c144025), + TOBN(0xa61d5fc2, 0x13c99927), TOBN(0xa033e9e0, 0x3de2eb35), + TOBN(0xf8185d5c, 0xb8dacbb4), TOBN(0x9a88e265, 0x8644549d), + TOBN(0xf717af62, 0x54671ff6), TOBN(0x4bd4241b, 0x5fa58603), + TOBN(0x06fba40b, 0xe67773c0), TOBN(0xc1d933d2, 0x6a2847e9), + TOBN(0xf4f5acf3, 0x689e2c70), TOBN(0x92aab0e7, 0x46bafd31), + TOBN(0x798d76aa, 0x3473f6e5), TOBN(0xcc6641db, 0x93141934), + TOBN(0xcae27757, 0xd31e535e), TOBN(0x04cc43b6, 0x87c2ee11), + TOBN(0x8d1f9675, 0x2e029ffa), TOBN(0xc2150672, 0xe4cc7a2c), + TOBN(0x3b03c1e0, 0x8d68b013), TOBN(0xa9d6816f, 0xedf298f3), + TOBN(0x1bfbb529, 0xa2804464), TOBN(0x95a52fae, 0x5db22125), + TOBN(0x55b32160, 0x0e1cb64e), TOBN(0x004828f6, 0x7e7fc9fe), + TOBN(0x13394b82, 0x1bb0fb93), TOBN(0xb6293a2d, 0x35f1a920), + TOBN(0xde35ef21, 0xd145d2d9), TOBN(0xbe6225b3, 0xbb8fa603), + TOBN(0x00fc8f6b, 0x32cf252d), TOBN(0xa28e52e6, 0x117cf8c2), + TOBN(0x9d1dc89b, 0x4c371e6d), TOBN(0xcebe0675, 0x36ef0f28), + TOBN(0x5de05d09, 0xa4292f81), TOBN(0xa8303593, 0x353e3083), + TOBN(0xa1715b0a, 0x7e37a9bb), TOBN(0x8c56f61e, 0x2b8faec3), + TOBN(0x52507431, 0x33c9b102), TOBN(0x0130cefc, 0xa44431f0), + TOBN(0x56039fa0, 0xbd865cfb), TOBN(0x4b03e578, 0xbc5f1dd7), + TOBN(0x40edf2e4, 0xbabe7224), TOBN(0xc752496d, 0x3a1988f6), + TOBN(0xd1572d3b, 0x564beb6b), TOBN(0x0db1d110, 0x39a1c608), + TOBN(0x568d1934, 0x16f60126), TOBN(0x05ae9668, 0xf354af33), + TOBN(0x19de6d37, 0xc92544f2), TOBN(0xcc084353, 0xa35837d5), + TOBN(0xcbb6869c, 0x1a514ece), TOBN(0xb633e728, 0x2e1d1066), + TOBN(0xf15dd69f, 0x936c581c), TOBN(0x96e7b8ce, 0x7439c4f9), + TOBN(0x5e676f48, 0x2e448a5b), TOBN(0xb2ca7d5b, 0xfd916bbb), + TOBN(0xd55a2541, 0xf5024025), TOBN(0x47bc5769, 0xe4c2d937), + TOBN(0x7d31b92a, 0x0362189f), TOBN(0x83f3086e, 0xef7816f9), + TOBN(0xf9f46d94, 0xb587579a), TOBN(0xec2d22d8, 0x30e76c5f), + TOBN(0x27d57461, 0xb000ffcf), TOBN(0xbb7e65f9, 0x364ffc2c), + TOBN(0x7c7c9477, 0x6652a220), TOBN(0x61618f89, 0xd696c981), + TOBN(0x5021701d, 0x89effff3), TOBN(0xf2c8ff8e, 0x7c314163), + TOBN(0x2da413ad, 0x8efb4d3e), TOBN(0x937b5adf, 0xce176d95), + TOBN(0x22867d34, 0x2a67d51c), TOBN(0x262b9b10, 0x18eb3ac9), + TOBN(0x4e314fe4, 0xc43ff28b), TOBN(0x76476627, 0x6a664e7a), + TOBN(0x3e90e40b, 0xb7a565c2), TOBN(0x8588993a, 0xc1acf831), + TOBN(0xd7b501d6, 0x8f938829), TOBN(0x996627ee, 0x3edd7d4c), + TOBN(0x37d44a62, 0x90cd34c7), TOBN(0xa8327499, 0xf3833e8d), + TOBN(0x2e18917d, 0x4bf50353), TOBN(0x85dd726b, 0x556765fb), + TOBN(0x54fe65d6, 0x93d5ab66), TOBN(0x3ddbaced, 0x915c25fe), + TOBN(0xa799d9a4, 0x12f22e85), TOBN(0xe2a24867, 0x6d06f6bc), + TOBN(0xf4f1ee56, 0x43ca1637), TOBN(0xfda2828b, 0x61ece30a), + TOBN(0x758c1a3e, 0xa2dee7a6), TOBN(0xdcde2f3c, 0x734b2284), + TOBN(0xaba445d2, 0x4eaba6ad), TOBN(0x35aaf668, 0x76cee0a7), + TOBN(0x7e0b04a9, 0xe5aa049a), TOBN(0xe74083ad, 0x91103e84), + TOBN(0xbeb183ce, 0x40afecc3), TOBN(0x6b89de9f, 0xea043f7a)}, + {TOBN(0x0e299d23, 0xfe67ba66), TOBN(0x91450760, 0x93cf2f34), + TOBN(0xf45b5ea9, 0x97fcf913), TOBN(0x5be00843, 0x8bd7ddda), + TOBN(0x358c3e05, 0xd53ff04d), TOBN(0xbf7ccdc3, 0x5de91ef7), + TOBN(0xad684dbf, 0xb69ec1a0), TOBN(0x367e7cf2, 0x801fd997), + TOBN(0x0ca1f3b7, 0xb0dc8595), TOBN(0x27de4608, 0x9f1d9f2e), + TOBN(0x1af3bf39, 0xbadd82a7), TOBN(0x79356a79, 0x65862448), + TOBN(0xc0602345, 0xf5f9a052), TOBN(0x1a8b0f89, 0x139a42f9), + TOBN(0xb53eee42, 0x844d40fc), TOBN(0x93b0bfe5, 0x4e5b6368), + TOBN(0x5434dd02, 0xc024789c), TOBN(0x90dca9ea, 0x41b57bfc), + TOBN(0x8aa898e2, 0x243398df), TOBN(0xf607c834, 0x894a94bb), + TOBN(0xbb07be97, 0xc2c99b76), TOBN(0x6576ba67, 0x18c29302), + TOBN(0x3d79efcc, 0xe703a88c), TOBN(0xf259ced7, 0xb6a0d106), + TOBN(0x0f893a5d, 0xc8de610b), TOBN(0xe8c515fb, 0x67e223ce), + TOBN(0x7774bfa6, 0x4ead6dc5), TOBN(0x89d20f95, 0x925c728f), + TOBN(0x7a1e0966, 0x098583ce), TOBN(0xa2eedb94, 0x93f2a7d7), + TOBN(0x1b282097, 0x4c304d4a), TOBN(0x0842e3da, 0xc077282d), + TOBN(0xe4d972a3, 0x3b9e2d7b), TOBN(0x7cc60b27, 0xc48218ff), + TOBN(0x8fc70838, 0x84149d91), TOBN(0x5c04346f, 0x2f461ecc), + TOBN(0xebe9fdf2, 0x614650a9), TOBN(0x5e35b537, 0xc1f666ac), + TOBN(0x645613d1, 0x88babc83), TOBN(0x88cace3a, 0xc5e1c93e), + TOBN(0x209ca375, 0x3de92e23), TOBN(0xccb03cc8, 0x5fbbb6e3), + TOBN(0xccb90f03, 0xd7b1487e), TOBN(0xfa9c2a38, 0xc710941f), + TOBN(0x756c3823, 0x6724ceed), TOBN(0x3a902258, 0x192d0323), + TOBN(0xb150e519, 0xea5e038e), TOBN(0xdcba2865, 0xc7427591), + TOBN(0xe549237f, 0x78890732), TOBN(0xc443bef9, 0x53fcb4d9), + TOBN(0x9884d8a6, 0xeb3480d6), TOBN(0x8a35b6a1, 0x3048b186), + TOBN(0xb4e44716, 0x65e9a90a), TOBN(0x45bf380d, 0x653006c0), + TOBN(0x8f3f820d, 0x4fe9ae3b), TOBN(0x244a35a0, 0x979a3b71), + TOBN(0xa1010e9d, 0x74cd06ff), TOBN(0x9c17c7df, 0xaca3eeac), + TOBN(0x74c86cd3, 0x8063aa2b), TOBN(0x8595c4b3, 0x734614ff), + TOBN(0xa3de00ca, 0x990f62cc), TOBN(0xd9bed213, 0xca0c3be5), + TOBN(0x7886078a, 0xdf8ce9f5), TOBN(0xddb27ce3, 0x5cd44444), + TOBN(0xed374a66, 0x58926ddd), TOBN(0x138b2d49, 0x908015b8), + TOBN(0x886c6579, 0xde1f7ab8), TOBN(0x888b9aa0, 0xc3020b7a), + TOBN(0xd3ec034e, 0x3a96e355), TOBN(0xba65b0b8, 0xf30fbe9a), + TOBN(0x064c8e50, 0xff21367a), TOBN(0x1f508ea4, 0x0b04b46e), + TOBN(0x98561a49, 0x747c866c), TOBN(0xbbb1e5fe, 0x0518a062), + TOBN(0x20ff4e8b, 0xecdc3608), TOBN(0x7f55cded, 0x20184027), + TOBN(0x8d73ec95, 0xf38c85f0), TOBN(0x5b589fdf, 0x8bc3b8c3), + TOBN(0xbe95dd98, 0x0f12b66f), TOBN(0xf5bd1a09, 0x0e338e01), + TOBN(0x65163ae5, 0x5e915918), TOBN(0x6158d6d9, 0x86f8a46b), + TOBN(0x8466b538, 0xeeebf99c), TOBN(0xca8761f6, 0xbca477ef), + TOBN(0xaf3449c2, 0x9ebbc601), TOBN(0xef3b0f41, 0xe0c3ae2f), + TOBN(0xaa6c577d, 0x5de63752), TOBN(0xe9166601, 0x64682a51), + TOBN(0x5a3097be, 0xfc15aa1e), TOBN(0x40d12548, 0xb54b0745), + TOBN(0x5bad4706, 0x519a5f12), TOBN(0xed03f717, 0xa439dee6), + TOBN(0x0794bb6c, 0x4a02c499), TOBN(0xf725083d, 0xcffe71d2), + TOBN(0x2cad7519, 0x0f3adcaf), TOBN(0x7f68ea1c, 0x43729310), + TOBN(0xe747c8c7, 0xb7ffd977), TOBN(0xec104c35, 0x80761a22), + TOBN(0x8395ebaf, 0x5a3ffb83), TOBN(0xfb3261f4, 0xe4b63db7), + TOBN(0x53544960, 0xd883e544), TOBN(0x13520d70, 0x8cc2eeb8), + TOBN(0x08f6337b, 0xd3d65f99), TOBN(0x83997db2, 0x781cf95b), + TOBN(0xce6ff106, 0x0dbd2c01), TOBN(0x4f8eea6b, 0x1f9ce934), + TOBN(0x546f7c4b, 0x0e993921), TOBN(0x6236a324, 0x5e753fc7), + TOBN(0x65a41f84, 0xa16022e9), TOBN(0x0c18d878, 0x43d1dbb2), + TOBN(0x73c55640, 0x2d4cef9c), TOBN(0xa0428108, 0x70444c74), + TOBN(0x68e4f15e, 0x9afdfb3c), TOBN(0x49a56143, 0x5bdfb6df), + TOBN(0xa9bc1bd4, 0x5f823d97), TOBN(0xbceb5970, 0xea111c2a), + TOBN(0x366b455f, 0xb269bbc4), TOBN(0x7cd85e1e, 0xe9bc5d62), + TOBN(0xc743c41c, 0x4f18b086), TOBN(0xa4b40990, 0x95294fb9), + TOBN(0x9c7c581d, 0x26ee8382), TOBN(0xcf17dcc5, 0x359d638e), + TOBN(0xee8273ab, 0xb728ae3d), TOBN(0x1d112926, 0xf821f047), + TOBN(0x11498477, 0x50491a74), TOBN(0x687fa761, 0xfde0dfb9), + TOBN(0x2c258022, 0x7ea435ab), TOBN(0x6b8bdb94, 0x91ce7e3f), + TOBN(0x4c5b5dc9, 0x3bf834aa), TOBN(0x04371819, 0x4f6c7e4b), + TOBN(0xc284e00a, 0x3736bcad), TOBN(0x0d881118, 0x21ae8f8d), + TOBN(0xf9cf0f82, 0xf48c8e33), TOBN(0xa11fd075, 0xa1bf40db), + TOBN(0xdceab0de, 0xdc2733e5), TOBN(0xc560a8b5, 0x8e986bd7), + TOBN(0x48dd1fe2, 0x3929d097), TOBN(0x3885b290, 0x92f188f1), + TOBN(0x0f2ae613, 0xda6fcdac), TOBN(0x9054303e, 0xb662a46c), + TOBN(0xb6871e44, 0x0738042a), TOBN(0x98e6a977, 0xbdaf6449), + TOBN(0xd8bc0650, 0xd1c9df1b), TOBN(0xef3d6451, 0x36e098f9), + TOBN(0x03fbae82, 0xb6d72d28), TOBN(0x77ca9db1, 0xf5d84080), + TOBN(0x8a112cff, 0xa58efc1c), TOBN(0x518d761c, 0xc564cb4a), + TOBN(0x69b5740e, 0xf0d1b5ce), TOBN(0x717039cc, 0xe9eb1785), + TOBN(0x3fe29f90, 0x22f53382), TOBN(0x8e54ba56, 0x6bc7c95c), + TOBN(0x9c806d8a, 0xf7f91d0f), TOBN(0x3b61b0f1, 0xa82a5728), + TOBN(0x4640032d, 0x94d76754), TOBN(0x273eb5de, 0x47d834c6), + TOBN(0x2988abf7, 0x7b4e4d53), TOBN(0xb7ce66bf, 0xde401777), + TOBN(0x9fba6b32, 0x715071b3), TOBN(0x82413c24, 0xad3a1a98), + TOBN(0x5b7fc8c4, 0xe0e8ad93), TOBN(0xb5679aee, 0x5fab868d), + TOBN(0xb1f9d2fa, 0x2b3946f3), TOBN(0x458897dc, 0x5685b50a), + TOBN(0x1e98c930, 0x89d0caf3), TOBN(0x39564c5f, 0x78642e92), + TOBN(0x1b77729a, 0x0dbdaf18), TOBN(0xf9170722, 0x579e82e6), + TOBN(0x680c0317, 0xe4515fa5), TOBN(0xf85cff84, 0xfb0c790f), + TOBN(0xc7a82aab, 0x6d2e0765), TOBN(0x7446bca9, 0x35c82b32), + TOBN(0x5de607aa, 0x6d63184f), TOBN(0x7c1a46a8, 0x262803a6), + TOBN(0xd218313d, 0xaebe8035), TOBN(0x92113ffd, 0xc73c51f8), + TOBN(0x4b38e083, 0x12e7e46c), TOBN(0x69d0a37a, 0x56126bd5), + TOBN(0xfb3f324b, 0x73c07e04), TOBN(0xa0c22f67, 0x8fda7267), + TOBN(0x8f2c0051, 0x4d2c7d8f), TOBN(0xbc45ced3, 0xcbe2cae5), + TOBN(0xe1c6cf07, 0xa8f0f277), TOBN(0xbc392312, 0x1eb99a98), + TOBN(0x75537b7e, 0x3cc8ac85), TOBN(0x8d725f57, 0xdd02753b), + TOBN(0xfd05ff64, 0xb737df2f), TOBN(0x55fe8712, 0xf6d2531d), + TOBN(0x57ce04a9, 0x6ab6b01c), TOBN(0x69a02a89, 0x7cd93724), + TOBN(0x4f82ac35, 0xcf86699b), TOBN(0x8242d3ad, 0x9cb4b232), + TOBN(0x713d0f65, 0xd62105e5), TOBN(0xbb222bfa, 0x2d29be61), + TOBN(0xf2f9a79e, 0x6cfbef09), TOBN(0xfc24d8d3, 0xd5d6782f), + TOBN(0x5db77085, 0xd4129967), TOBN(0xdb81c3cc, 0xdc3c2a43), + TOBN(0x9d655fc0, 0x05d8d9a3), TOBN(0x3f5d057a, 0x54298026), + TOBN(0x1157f56d, 0x88c54694), TOBN(0xb26baba5, 0x9b09573e), + TOBN(0x2cab03b0, 0x22adffd1), TOBN(0x60a412c8, 0xdd69f383), + TOBN(0xed76e98b, 0x54b25039), TOBN(0xd4ee67d3, 0x687e714d), + TOBN(0x87739648, 0x7b00b594), TOBN(0xce419775, 0xc9ef709b), + TOBN(0x40f76f85, 0x1c203a40), TOBN(0x30d352d6, 0xeafd8f91), + TOBN(0xaf196d3d, 0x95578dd2), TOBN(0xea4bb3d7, 0x77cc3f3d), + TOBN(0x42a5bd03, 0xb98e782b), TOBN(0xac958c40, 0x0624920d), + TOBN(0xb838134c, 0xfc56fcc8), TOBN(0x86ec4ccf, 0x89572e5e), + TOBN(0x69c43526, 0x9be47be0), TOBN(0x323b7dd8, 0xcb28fea1), + TOBN(0xfa5538ba, 0x3a6c67e5), TOBN(0xef921d70, 0x1d378e46), + TOBN(0xf92961fc, 0x3c4b880e), TOBN(0x3f6f914e, 0x98940a67), + TOBN(0xa990eb0a, 0xfef0ff39), TOBN(0xa6c2920f, 0xf0eeff9c), + TOBN(0xca804166, 0x51b8d9a3), TOBN(0x42531bc9, 0x0ffb0db1), + TOBN(0x72ce4718, 0xaa82e7ce), TOBN(0x6e199913, 0xdf574741), + TOBN(0xd5f1b13d, 0xd5d36946), TOBN(0x8255dc65, 0xf68f0194), + TOBN(0xdc9df4cd, 0x8710d230), TOBN(0x3453c20f, 0x138c1988), + TOBN(0x9af98dc0, 0x89a6ef01), TOBN(0x4dbcc3f0, 0x9857df85), + TOBN(0x34805601, 0x5c1ad924), TOBN(0x40448da5, 0xd0493046), + TOBN(0xf629926d, 0x4ee343e2), TOBN(0x6343f1bd, 0x90e8a301), + TOBN(0xefc93491, 0x40815b3f), TOBN(0xf882a423, 0xde8f66fb), + TOBN(0x3a12d5f4, 0xe7db9f57), TOBN(0x7dfba38a, 0x3c384c27), + TOBN(0x7a904bfd, 0x6fc660b1), TOBN(0xeb6c5db3, 0x2773b21c), + TOBN(0xc350ee66, 0x1cdfe049), TOBN(0x9baac0ce, 0x44540f29), + TOBN(0xbc57b6ab, 0xa5ec6aad), TOBN(0x167ce8c3, 0x0a7c1baa), + TOBN(0xb23a03a5, 0x53fb2b56), TOBN(0x6ce141e7, 0x4e057f78), + TOBN(0x796525c3, 0x89e490d9), TOBN(0x0bc95725, 0xa31a7e75), + TOBN(0x1ec56791, 0x1220fd06), TOBN(0x716e3a3c, 0x408b0bd6), + TOBN(0x31cd6bf7, 0xe8ebeba9), TOBN(0xa7326ca6, 0xbee6b670), + TOBN(0x3d9f851c, 0xcd090c43), TOBN(0x561e8f13, 0xf12c3988), + TOBN(0x50490b6a, 0x904b7be4), TOBN(0x61690ce1, 0x0410737b), + TOBN(0x299e9a37, 0x0f009052), TOBN(0x258758f0, 0xf026092e), + TOBN(0x9fa255f3, 0xfdfcdc0f), TOBN(0xdbc9fb1f, 0xc0e1bcd2), + TOBN(0x35f9dd6e, 0x24651840), TOBN(0xdca45a84, 0xa5c59abc), + TOBN(0x103d396f, 0xecca4938), TOBN(0x4532da0a, 0xb97b3f29), + TOBN(0xc4135ea5, 0x1999a6bf), TOBN(0x3aa9505a, 0x5e6bf2ee), + TOBN(0xf77cef06, 0x3f5be093), TOBN(0x97d1a0f8, 0xa943152e), + TOBN(0x2cb0ebba, 0x2e1c21dd), TOBN(0xf41b29fc, 0x2c6797c4), + TOBN(0xc6e17321, 0xb300101f), TOBN(0x4422b0e9, 0xd0d79a89), + TOBN(0x49e4901c, 0x92f1bfc4), TOBN(0x06ab1f8f, 0xe1e10ed9), + TOBN(0x84d35577, 0xdb2926b8), TOBN(0xca349d39, 0x356e8ec2), + TOBN(0x70b63d32, 0x343bf1a9), TOBN(0x8fd3bd28, 0x37d1a6b1), + TOBN(0x0454879c, 0x316865b4), TOBN(0xee959ff6, 0xc458efa2), + TOBN(0x0461dcf8, 0x9706dc3f), TOBN(0x737db0e2, 0x164e4b2e), + TOBN(0x09262680, 0x2f8843c8), TOBN(0x54498bbc, 0x7745e6f6), + TOBN(0x359473fa, 0xa29e24af), TOBN(0xfcc3c454, 0x70aa87a1), + TOBN(0xfd2c4bf5, 0x00573ace), TOBN(0xb65b514e, 0x28dd1965), + TOBN(0xe46ae7cf, 0x2193e393), TOBN(0x60e9a4e1, 0xf5444d97), + TOBN(0xe7594e96, 0x00ff38ed), TOBN(0x43d84d2f, 0x0a0e0f02), + TOBN(0x8b6db141, 0xee398a21), TOBN(0xb88a56ae, 0xe3bcc5be), + TOBN(0x0a1aa52f, 0x373460ea), TOBN(0x20da1a56, 0x160bb19b), + TOBN(0xfb54999d, 0x65bf0384), TOBN(0x71a14d24, 0x5d5a180e), + TOBN(0xbc44db7b, 0x21737b04), TOBN(0xd84fcb18, 0x01dd8e92), + TOBN(0x80de937b, 0xfa44b479), TOBN(0x53505499, 0x5c98fd4f), + TOBN(0x1edb12ab, 0x28f08727), TOBN(0x4c58b582, 0xa5f3ef53), + TOBN(0xbfb236d8, 0x8327f246), TOBN(0xc3a3bfaa, 0x4d7df320), + TOBN(0xecd96c59, 0xb96024f2), TOBN(0xfc293a53, 0x7f4e0433), + TOBN(0x5341352b, 0x5acf6e10), TOBN(0xc50343fd, 0xafe652c3), + TOBN(0x4af3792d, 0x18577a7f), TOBN(0xe1a4c617, 0xaf16823d), + TOBN(0x9b26d0cd, 0x33425d0a), TOBN(0x306399ed, 0x9b7bc47f), + TOBN(0x2a792f33, 0x706bb20b), TOBN(0x31219614, 0x98111055), + TOBN(0x864ec064, 0x87f5d28b), TOBN(0x11392d91, 0x962277fd), + TOBN(0xb5aa7942, 0xbb6aed5f), TOBN(0x080094dc, 0x47e799d9), + TOBN(0x4afa588c, 0x208ba19b), TOBN(0xd3e7570f, 0x8512f284), + TOBN(0xcbae64e6, 0x02f5799a), TOBN(0xdeebe7ef, 0x514b9492), + TOBN(0x30300f98, 0xe5c298ff), TOBN(0x17f561be, 0x3678361f), + TOBN(0xf52ff312, 0x98cb9a16), TOBN(0x6233c3bc, 0x5562d490), + TOBN(0x7bfa15a1, 0x92e3a2cb), TOBN(0x961bcfd1, 0xe6365119), + TOBN(0x3bdd29bf, 0x2c8c53b1), TOBN(0x739704df, 0x822844ba), + TOBN(0x7dacfb58, 0x7e7b754b), TOBN(0x23360791, 0xa806c9b9), + TOBN(0xe7eb88c9, 0x23504452), TOBN(0x2983e996, 0x852c1783), + TOBN(0xdd4ae529, 0x958d881d), TOBN(0x026bae03, 0x262c7b3c), + TOBN(0x3a6f9193, 0x960b52d1), TOBN(0xd0980f90, 0x92696cfb), + TOBN(0x4c1f428c, 0xd5f30851), TOBN(0x94dfed27, 0x2a4f6630), + TOBN(0x4df53772, 0xfc5d48a4), TOBN(0xdd2d5a2f, 0x933260ce), + TOBN(0x574115bd, 0xd44cc7a5), TOBN(0x4ba6b20d, 0xbd12533a), + TOBN(0x30e93cb8, 0x243057c9), TOBN(0x794c486a, 0x14de320e), + TOBN(0xe925d4ce, 0xf21496e4), TOBN(0xf951d198, 0xec696331), + TOBN(0x9810e2de, 0x3e8d812f), TOBN(0xd0a47259, 0x389294ab), + TOBN(0x513ba2b5, 0x0e3bab66), TOBN(0x462caff5, 0xabad306f), + TOBN(0xe2dc6d59, 0xaf04c49e), TOBN(0x1aeb8750, 0xe0b84b0b), + TOBN(0xc034f12f, 0x2f7d0ca2), TOBN(0x6d2e8128, 0xe06acf2f), + TOBN(0x801f4f83, 0x21facc2f), TOBN(0xa1170c03, 0xf40ef607), + TOBN(0xfe0a1d4f, 0x7805a99c), TOBN(0xbde56a36, 0xcc26aba5), + TOBN(0x5b1629d0, 0x35531f40), TOBN(0xac212c2b, 0x9afa6108), + TOBN(0x30a06bf3, 0x15697be5), TOBN(0x6f0545dc, 0x2c63c7c1), + TOBN(0x5d8cb842, 0x7ccdadaf), TOBN(0xd52e379b, 0xac7015bb), + TOBN(0xc4f56147, 0xf462c23e), TOBN(0xd44a4298, 0x46bc24b0), + TOBN(0xbc73d23a, 0xe2856d4f), TOBN(0x61cedd8c, 0x0832bcdf), + TOBN(0x60953556, 0x99f241d7), TOBN(0xee4adbd7, 0x001a349d), + TOBN(0x0b35bf6a, 0xaa89e491), TOBN(0x7f0076f4, 0x136f7546), + TOBN(0xd19a18ba, 0x9264da3d), TOBN(0x6eb2d2cd, 0x62a7a28b), + TOBN(0xcdba941f, 0x8761c971), TOBN(0x1550518b, 0xa3be4a5d), + TOBN(0xd0e8e2f0, 0x57d0b70c), TOBN(0xeea8612e, 0xcd133ba3), + TOBN(0x814670f0, 0x44416aec), TOBN(0x424db6c3, 0x30775061), + TOBN(0xd96039d1, 0x16213fd1), TOBN(0xc61e7fa5, 0x18a3478f), + TOBN(0xa805bdcc, 0xcb0c5021), TOBN(0xbdd6f3a8, 0x0cc616dd), + TOBN(0x06009667, 0x5d97f7e2), TOBN(0x31db0fc1, 0xaf0bf4b6), + TOBN(0x23680ed4, 0x5491627a), TOBN(0xb99a3c66, 0x7d741fb1), + TOBN(0xe9bb5f55, 0x36b1ff92), TOBN(0x29738577, 0x512b388d), + TOBN(0xdb8a2ce7, 0x50fcf263), TOBN(0x385346d4, 0x6c4f7b47), + TOBN(0xbe86c5ef, 0x31631f9e), TOBN(0xbf91da21, 0x03a57a29), + TOBN(0xc3b1f796, 0x7b23f821), TOBN(0x0f7d00d2, 0x770db354), + TOBN(0x8ffc6c3b, 0xd8fe79da), TOBN(0xcc5e8c40, 0xd525c996), + TOBN(0x4640991d, 0xcfff632a), TOBN(0x64d97e8c, 0x67112528), + TOBN(0xc232d973, 0x02f1cd1e), TOBN(0xce87eacb, 0x1dd212a4), + TOBN(0x6e4c8c73, 0xe69802f7), TOBN(0x12ef0290, 0x1fffddbd), + TOBN(0x941ec74e, 0x1bcea6e2), TOBN(0xd0b54024, 0x3cb92cbb), + TOBN(0x809fb9d4, 0x7e8f9d05), TOBN(0x3bf16159, 0xf2992aae), + TOBN(0xad40f279, 0xf8a7a838), TOBN(0x11aea631, 0x05615660), + TOBN(0xbf52e6f1, 0xa01f6fa1), TOBN(0xef046995, 0x3dc2aec9), + TOBN(0x785dbec9, 0xd8080711), TOBN(0xe1aec60a, 0x9fdedf76), + TOBN(0xece797b5, 0xfa21c126), TOBN(0xc66e898f, 0x05e52732), + TOBN(0x39bb69c4, 0x08811fdb), TOBN(0x8bfe1ef8, 0x2fc7f082), + TOBN(0xc8e7a393, 0x174f4138), TOBN(0xfba8ad1d, 0xd58d1f98), + TOBN(0xbc21d0ce, 0xbfd2fd5b), TOBN(0x0b839a82, 0x6ee60d61), + TOBN(0xaacf7658, 0xafd22253), TOBN(0xb526bed8, 0xaae396b3), + TOBN(0xccc1bbc2, 0x38564464), TOBN(0x9e3ff947, 0x8c45bc73), + TOBN(0xcde9bca3, 0x58188a78), TOBN(0x138b8ee0, 0xd73bf8f7), + TOBN(0x5c7e234c, 0x4123c489), TOBN(0x66e69368, 0xfa643297), + TOBN(0x0629eeee, 0x39a15fa3), TOBN(0x95fab881, 0xa9e2a927), + TOBN(0xb2497007, 0xeafbb1e1), TOBN(0xd75c9ce6, 0xe75b7a93), + TOBN(0x3558352d, 0xefb68d78), TOBN(0xa2f26699, 0x223f6396), + TOBN(0xeb911ecf, 0xe469b17a), TOBN(0x62545779, 0xe72d3ec2), + TOBN(0x8ea47de7, 0x82cb113f), TOBN(0xebe4b086, 0x4e1fa98d), + TOBN(0xec2d5ed7, 0x8cdfedb1), TOBN(0xa535c077, 0xfe211a74), + TOBN(0x9678109b, 0x11d244c5), TOBN(0xf17c8bfb, 0xbe299a76), + TOBN(0xb651412e, 0xfb11fbc4), TOBN(0xea0b5482, 0x94ab3f65), + TOBN(0xd8dffd95, 0x0cf78243), TOBN(0x2e719e57, 0xce0361d4), + TOBN(0x9007f085, 0x304ddc5b), TOBN(0x095e8c6d, 0x4daba2ea), + TOBN(0x5a33cdb4, 0x3f9d28a9), TOBN(0x85b95cd8, 0xe2283003), + TOBN(0xbcd6c819, 0xb9744733), TOBN(0x29c5f538, 0xfc7f5783), + TOBN(0x6c49b2fa, 0xd59038e4), TOBN(0x68349cc1, 0x3bbe1018), + TOBN(0xcc490c1d, 0x21830ee5), TOBN(0x36f9c4ee, 0xe9bfa297), + TOBN(0x58fd7294, 0x48de1a94), TOBN(0xaadb13a8, 0x4e8f2cdc), + TOBN(0x515eaaa0, 0x81313dba), TOBN(0xc76bb468, 0xc2152dd8), + TOBN(0x357f8d75, 0xa653dbf8), TOBN(0xe4d8c4d1, 0xb14ac143), + TOBN(0xbdb8e675, 0xb055cb40), TOBN(0x898f8e7b, 0x977b5167), + TOBN(0xecc65651, 0xb82fb863), TOBN(0x56544814, 0x6d88f01f), + TOBN(0xb0928e95, 0x263a75a9), TOBN(0xcfb6836f, 0x1a22fcda), + TOBN(0x651d14db, 0x3f3bd37c), TOBN(0x1d3837fb, 0xb6ad4664), + TOBN(0x7c5fb538, 0xff4f94ab), TOBN(0x7243c712, 0x6d7fb8f2), + TOBN(0xef13d60c, 0xa85c5287), TOBN(0x18cfb7c7, 0x4bb8dd1b), + TOBN(0x82f9bfe6, 0x72908219), TOBN(0x35c4592b, 0x9d5144ab), + TOBN(0x52734f37, 0x9cf4b42f), TOBN(0x6bac55e7, 0x8c60ddc4), + TOBN(0xb5cd811e, 0x94dea0f6), TOBN(0x259ecae4, 0xe18cc1a3), + TOBN(0x6a0e836e, 0x15e660f8), TOBN(0x6c639ea6, 0x0e02bff2), + TOBN(0x8721b8cb, 0x7e1026fd), TOBN(0x9e73b50b, 0x63261942), + TOBN(0xb8c70974, 0x77f01da3), TOBN(0x1839e6a6, 0x8268f57f), + TOBN(0x571b9415, 0x5150b805), TOBN(0x1892389e, 0xf92c7097), + TOBN(0x8d69c18e, 0x4a084b95), TOBN(0x7014c512, 0xbe5b495c), + TOBN(0x4780db36, 0x1b07523c), TOBN(0x2f6219ce, 0x2c1c64fa), + TOBN(0xc38b81b0, 0x602c105a), TOBN(0xab4f4f20, 0x5dc8e360), + TOBN(0x20d3c982, 0xcf7d62d2), TOBN(0x1f36e29d, 0x23ba8150), + TOBN(0x48ae0bf0, 0x92763f9e), TOBN(0x7a527e6b, 0x1d3a7007), + TOBN(0xb4a89097, 0x581a85e3), TOBN(0x1f1a520f, 0xdc158be5), + TOBN(0xf98db37d, 0x167d726e), TOBN(0x8802786e, 0x1113e862)}, + {TOBN(0xefb2149e, 0x36f09ab0), TOBN(0x03f163ca, 0x4a10bb5b), + TOBN(0xd0297045, 0x06e20998), TOBN(0x56f0af00, 0x1b5a3bab), + TOBN(0x7af4cfec, 0x70880e0d), TOBN(0x7332a66f, 0xbe3d913f), + TOBN(0x32e6c84a, 0x7eceb4bd), TOBN(0xedc4a79a, 0x9c228f55), + TOBN(0xc37c7dd0, 0xc55c4496), TOBN(0xa6a96357, 0x25bbabd2), + TOBN(0x5b7e63f2, 0xadd7f363), TOBN(0x9dce3782, 0x2e73f1df), + TOBN(0xe1e5a16a, 0xb2b91f71), TOBN(0xe4489823, 0x5ba0163c), + TOBN(0xf2759c32, 0xf6e515ad), TOBN(0xa5e2f1f8, 0x8615eecf), + TOBN(0x74519be7, 0xabded551), TOBN(0x03d358b8, 0xc8b74410), + TOBN(0x4d00b10b, 0x0e10d9a9), TOBN(0x6392b0b1, 0x28da52b7), + TOBN(0x6744a298, 0x0b75c904), TOBN(0xc305b0ae, 0xa8f7f96c), + TOBN(0x042e421d, 0x182cf932), TOBN(0xf6fc5d50, 0x9e4636ca), + TOBN(0x795847c9, 0xd64cc78c), TOBN(0x6c50621b, 0x9b6cb27b), + TOBN(0x07099bf8, 0xdf8022ab), TOBN(0x48f862eb, 0xc04eda1d), + TOBN(0xd12732ed, 0xe1603c16), TOBN(0x19a80e0f, 0x5c9a9450), + TOBN(0xe2257f54, 0xb429b4fc), TOBN(0x66d3b2c6, 0x45460515), + TOBN(0x6ca4f87e, 0x822e37be), TOBN(0x73f237b4, 0x253bda4e), + TOBN(0xf747f3a2, 0x41190aeb), TOBN(0xf06fa36f, 0x804cf284), + TOBN(0x0a6bbb6e, 0xfc621c12), TOBN(0x5d624b64, 0x40b80ec6), + TOBN(0x4b072425, 0x7ba556f3), TOBN(0x7fa0c354, 0x3e2d20a8), + TOBN(0xe921fa31, 0xe3229d41), TOBN(0xa929c652, 0x94531bd4), + TOBN(0x84156027, 0xa6d38209), TOBN(0xf3d69f73, 0x6bdb97bd), + TOBN(0x8906d19a, 0x16833631), TOBN(0x68a34c2e, 0x03d51be3), + TOBN(0xcb59583b, 0x0e511cd8), TOBN(0x99ce6bfd, 0xfdc132a8), + TOBN(0x3facdaaa, 0xffcdb463), TOBN(0x658bbc1a, 0x34a38b08), + TOBN(0x12a801f8, 0xf1a9078d), TOBN(0x1567bcf9, 0x6ab855de), + TOBN(0xe08498e0, 0x3572359b), TOBN(0xcf0353e5, 0x8659e68b), + TOBN(0xbb86e9c8, 0x7d23807c), TOBN(0xbc08728d, 0x2198e8a2), + TOBN(0x8de2b7bc, 0x453cadd6), TOBN(0x203900a7, 0xbc0bc1f8), + TOBN(0xbcd86e47, 0xa6abd3af), TOBN(0x911cac12, 0x8502effb), + TOBN(0x2d550242, 0xec965469), TOBN(0x0e9f7692, 0x29e0017e), + TOBN(0x633f078f, 0x65979885), TOBN(0xfb87d449, 0x4cf751ef), + TOBN(0xe1790e4b, 0xfc25419a), TOBN(0x36467203, 0x4bff3cfd), + TOBN(0xc8db6386, 0x25b6e83f), TOBN(0x6cc69f23, 0x6cad6fd2), + TOBN(0x0219e45a, 0x6bc68bb9), TOBN(0xe43d79b6, 0x297f7334), + TOBN(0x7d445368, 0x465dc97c), TOBN(0x4b9eea32, 0x2a0b949a), + TOBN(0x1b96c6ba, 0x6102d021), TOBN(0xeaafac78, 0x2f4461ea), + TOBN(0xd4b85c41, 0xc49f19a8), TOBN(0x275c28e4, 0xcf538875), + TOBN(0x35451a9d, 0xdd2e54e0), TOBN(0x6991adb5, 0x0605618b), + TOBN(0x5b8b4bcd, 0x7b36cd24), TOBN(0x372a4f8c, 0x56f37216), + TOBN(0xc890bd73, 0xa6a5da60), TOBN(0x6f083da0, 0xdc4c9ff0), + TOBN(0xf4e14d94, 0xf0536e57), TOBN(0xf9ee1eda, 0xaaec8243), + TOBN(0x571241ec, 0x8bdcf8e7), TOBN(0xa5db8271, 0x0b041e26), + TOBN(0x9a0b9a99, 0xe3fff040), TOBN(0xcaaf21dd, 0x7c271202), + TOBN(0xb4e2b2e1, 0x4f0dd2e8), TOBN(0xe77e7c4f, 0x0a377ac7), + TOBN(0x69202c3f, 0x0d7a2198), TOBN(0xf759b7ff, 0x28200eb8), + TOBN(0xc87526ed, 0xdcfe314e), TOBN(0xeb84c524, 0x53d5cf99), + TOBN(0xb1b52ace, 0x515138b6), TOBN(0x5aa7ff8c, 0x23fca3f4), + TOBN(0xff0b13c3, 0xb9791a26), TOBN(0x960022da, 0xcdd58b16), + TOBN(0xdbd55c92, 0x57aad2de), TOBN(0x3baaaaa3, 0xf30fe619), + TOBN(0x9a4b2346, 0x0d881efd), TOBN(0x506416c0, 0x46325e2a), + TOBN(0x91381e76, 0x035c18d4), TOBN(0xb3bb68be, 0xf27817b0), + TOBN(0x15bfb8bf, 0x5116f937), TOBN(0x7c64a586, 0xc1268943), + TOBN(0x71e25cc3, 0x8419a2c8), TOBN(0x9fd6b0c4, 0x8335f463), + TOBN(0x4bf0ba3c, 0xe8ee0e0e), TOBN(0x6f6fba60, 0x298c21fa), + TOBN(0x57d57b39, 0xae66bee0), TOBN(0x292d5130, 0x22672544), + TOBN(0xf451105d, 0xbab093b3), TOBN(0x012f59b9, 0x02839986), + TOBN(0x8a915802, 0x3474a89c), TOBN(0x048c919c, 0x2de03e97), + TOBN(0xc476a2b5, 0x91071cd5), TOBN(0x791ed89a, 0x034970a5), + TOBN(0x89bd9042, 0xe1b7994b), TOBN(0x8eaf5179, 0xa1057ffd), + TOBN(0x6066e2a2, 0xd551ee10), TOBN(0x87a8f1d8, 0x727e09a6), + TOBN(0x00d08bab, 0x2c01148d), TOBN(0x6da8e4f1, 0x424f33fe), + TOBN(0x466d17f0, 0xcf9a4e71), TOBN(0xff502010, 0x3bf5cb19), + TOBN(0xdccf97d8, 0xd062ecc0), TOBN(0x80c0d9af, 0x81d80ac4), + TOBN(0xe87771d8, 0x033f2876), TOBN(0xb0186ec6, 0x7d5cc3db), + TOBN(0x58e8bb80, 0x3bc9bc1d), TOBN(0x4d1395cc, 0x6f6ef60e), + TOBN(0xa73c62d6, 0x186244a0), TOBN(0x918e5f23, 0x110a5b53), + TOBN(0xed4878ca, 0x741b7eab), TOBN(0x3038d71a, 0xdbe03e51), + TOBN(0x840204b7, 0xa93c3246), TOBN(0x21ab6069, 0xa0b9b4cd), + TOBN(0xf5fa6e2b, 0xb1d64218), TOBN(0x1de6ad0e, 0xf3d56191), + TOBN(0x570aaa88, 0xff1929c7), TOBN(0xc6df4c6b, 0x640e87b5), + TOBN(0xde8a74f2, 0xc65f0ccc), TOBN(0x8b972fd5, 0xe6f6cc01), + TOBN(0x3fff36b6, 0x0b846531), TOBN(0xba7e45e6, 0x10a5e475), + TOBN(0x84a1d10e, 0x4145b6c5), TOBN(0xf1f7f91a, 0x5e046d9d), + TOBN(0x0317a692, 0x44de90d7), TOBN(0x951a1d4a, 0xf199c15e), + TOBN(0x91f78046, 0xc9d73deb), TOBN(0x74c82828, 0xfab8224f), + TOBN(0xaa6778fc, 0xe7560b90), TOBN(0xb4073e61, 0xa7e824ce), + TOBN(0xff0d693c, 0xd642eba8), TOBN(0x7ce2e57a, 0x5dccef38), + TOBN(0x89c2c789, 0x1df1ad46), TOBN(0x83a06922, 0x098346fd), + TOBN(0x2d715d72, 0xda2fc177), TOBN(0x7b6dd71d, 0x85b6cf1d), + TOBN(0xc60a6d0a, 0x73fa9cb0), TOBN(0xedd3992e, 0x328bf5a9), + TOBN(0xc380ddd0, 0x832c8c82), TOBN(0xd182d410, 0xa2a0bf50), + TOBN(0x7d9d7438, 0xd9a528db), TOBN(0xe8b1a0e9, 0xcaf53994), + TOBN(0xddd6e5fe, 0x0e19987c), TOBN(0xacb8df03, 0x190b059d), + TOBN(0x53703a32, 0x8300129f), TOBN(0x1f637662, 0x68c43bfd), + TOBN(0xbcbd1913, 0x00e54051), TOBN(0x812fcc62, 0x7bf5a8c5), + TOBN(0x3f969d5f, 0x29fb85da), TOBN(0x72f4e00a, 0x694759e8), + TOBN(0x426b6e52, 0x790726b7), TOBN(0x617bbc87, 0x3bdbb209), + TOBN(0x511f8bb9, 0x97aee317), TOBN(0x812a4096, 0xe81536a8), + TOBN(0x137dfe59, 0x3ac09b9b), TOBN(0x0682238f, 0xba8c9a7a), + TOBN(0x7072ead6, 0xaeccb4bd), TOBN(0x6a34e9aa, 0x692ba633), + TOBN(0xc82eaec2, 0x6fff9d33), TOBN(0xfb753512, 0x1d4d2b62), + TOBN(0x1a0445ff, 0x1d7aadab), TOBN(0x65d38260, 0xd5f6a67c), + TOBN(0x6e62fb08, 0x91cfb26f), TOBN(0xef1e0fa5, 0x5c7d91d6), + TOBN(0x47e7c7ba, 0x33db72cd), TOBN(0x017cbc09, 0xfa7c74b2), + TOBN(0x3c931590, 0xf50a503c), TOBN(0xcac54f60, 0x616baa42), + TOBN(0x9b6cd380, 0xb2369f0f), TOBN(0x97d3a70d, 0x23c76151), + TOBN(0x5f9dd6fc, 0x9862a9c6), TOBN(0x044c4ab2, 0x12312f51), + TOBN(0x035ea0fd, 0x834a2ddc), TOBN(0x49e6b862, 0xcc7b826d), + TOBN(0xb03d6883, 0x62fce490), TOBN(0x62f2497a, 0xb37e36e9), + TOBN(0x04b005b6, 0xc6458293), TOBN(0x36bb5276, 0xe8d10af7), + TOBN(0xacf2dc13, 0x8ee617b8), TOBN(0x470d2d35, 0xb004b3d4), + TOBN(0x06790832, 0xfeeb1b77), TOBN(0x2bb75c39, 0x85657f9c), + TOBN(0xd70bd4ed, 0xc0f60004), TOBN(0xfe797ecc, 0x219b018b), + TOBN(0x9b5bec2a, 0x753aebcc), TOBN(0xdaf9f3dc, 0xc939eca5), + TOBN(0xd6bc6833, 0xd095ad09), TOBN(0x98abdd51, 0xdaa4d2fc), + TOBN(0xd9840a31, 0x8d168be5), TOBN(0xcf7c10e0, 0x2325a23c), + TOBN(0xa5c02aa0, 0x7e6ecfaf), TOBN(0x2462e7e6, 0xb5bfdf18), + TOBN(0xab2d8a8b, 0xa0cc3f12), TOBN(0x68dd485d, 0xbc672a29), + TOBN(0x72039752, 0x596f2cd3), TOBN(0x5d3eea67, 0xa0cf3d8d), + TOBN(0x810a1a81, 0xe6602671), TOBN(0x8f144a40, 0x14026c0c), + TOBN(0xbc753a6d, 0x76b50f85), TOBN(0xc4dc21e8, 0x645cd4a4), + TOBN(0xc5262dea, 0x521d0378), TOBN(0x802b8e0e, 0x05011c6f), + TOBN(0x1ba19cbb, 0x0b4c19ea), TOBN(0x21db64b5, 0xebf0aaec), + TOBN(0x1f394ee9, 0x70342f9d), TOBN(0x93a10aee, 0x1bc44a14), + TOBN(0xa7eed31b, 0x3efd0baa), TOBN(0x6e7c824e, 0x1d154e65), + TOBN(0xee23fa81, 0x9966e7ee), TOBN(0x64ec4aa8, 0x05b7920d), + TOBN(0x2d44462d, 0x2d90aad4), TOBN(0xf44dd195, 0xdf277ad5), + TOBN(0x8d6471f1, 0xbb46b6a1), TOBN(0x1e65d313, 0xfd885090), + TOBN(0x33a800f5, 0x13a977b4), TOBN(0xaca9d721, 0x0797e1ef), + TOBN(0x9a5a85a0, 0xfcff6a17), TOBN(0x9970a3f3, 0x1eca7cee), + TOBN(0xbb9f0d6b, 0xc9504be3), TOBN(0xe0c504be, 0xadd24ee2), + TOBN(0x7e09d956, 0x77fcc2f4), TOBN(0xef1a5227, 0x65bb5fc4), + TOBN(0x145d4fb1, 0x8b9286aa), TOBN(0x66fd0c5d, 0x6649028b), + TOBN(0x98857ceb, 0x1bf4581c), TOBN(0xe635e186, 0xaca7b166), + TOBN(0x278ddd22, 0x659722ac), TOBN(0xa0903c4c, 0x1db68007), + TOBN(0x366e4589, 0x48f21402), TOBN(0x31b49c14, 0xb96abda2), + TOBN(0x329c4b09, 0xe0403190), TOBN(0x97197ca3, 0xd29f43fe), + TOBN(0x8073dd1e, 0x274983d8), TOBN(0xda1a3bde, 0x55717c8f), + TOBN(0xfd3d4da2, 0x0361f9d1), TOBN(0x1332d081, 0x4c7de1ce), + TOBN(0x9b7ef7a3, 0xaa6d0e10), TOBN(0x17db2e73, 0xf54f1c4a), + TOBN(0xaf3dffae, 0x4cd35567), TOBN(0xaaa2f406, 0xe56f4e71), + TOBN(0x8966759e, 0x7ace3fc7), TOBN(0x9594eacf, 0x45a8d8c6), + TOBN(0x8de3bd8b, 0x91834e0e), TOBN(0xafe4ca53, 0x548c0421), + TOBN(0xfdd7e856, 0xe6ee81c6), TOBN(0x8f671beb, 0x6b891a3a), + TOBN(0xf7a58f2b, 0xfae63829), TOBN(0x9ab186fb, 0x9c11ac9f), + TOBN(0x8d6eb369, 0x10b5be76), TOBN(0x046b7739, 0xfb040bcd), + TOBN(0xccb4529f, 0xcb73de88), TOBN(0x1df0fefc, 0xcf26be03), + TOBN(0xad7757a6, 0xbcfcd027), TOBN(0xa8786c75, 0xbb3165ca), + TOBN(0xe9db1e34, 0x7e99a4d9), TOBN(0x99ee86df, 0xb06c504b), + TOBN(0x5b7c2ddd, 0xc15c9f0a), TOBN(0xdf87a734, 0x4295989e), + TOBN(0x59ece47c, 0x03d08fda), TOBN(0xb074d3dd, 0xad5fc702), + TOBN(0x20407903, 0x51a03776), TOBN(0x2bb1f77b, 0x2a608007), + TOBN(0x25c58f4f, 0xe1153185), TOBN(0xe6df62f6, 0x766e6447), + TOBN(0xefb3d1be, 0xed51275a), TOBN(0x5de47dc7, 0x2f0f483f), + TOBN(0x7932d98e, 0x97c2bedf), TOBN(0xd5c11927, 0x0219f8a1), + TOBN(0x9d751200, 0xa73a294e), TOBN(0x5f88434a, 0x9dc20172), + TOBN(0xd28d9fd3, 0xa26f506a), TOBN(0xa890cd31, 0x9d1dcd48), + TOBN(0x0aebaec1, 0x70f4d3b4), TOBN(0xfd1a1369, 0x0ffc8d00), + TOBN(0xb9d9c240, 0x57d57838), TOBN(0x45929d26, 0x68bac361), + TOBN(0x5a2cd060, 0x25b15ca6), TOBN(0x4b3c83e1, 0x6e474446), + TOBN(0x1aac7578, 0xee1e5134), TOBN(0xa418f5d6, 0xc91e2f41), + TOBN(0x6936fc8a, 0x213ed68b), TOBN(0x860ae7ed, 0x510a5224), + TOBN(0x63660335, 0xdef09b53), TOBN(0x641b2897, 0xcd79c98d), + TOBN(0x29bd38e1, 0x01110f35), TOBN(0x79c26f42, 0x648b1937), + TOBN(0x64dae519, 0x9d9164f4), TOBN(0xd85a2310, 0x0265c273), + TOBN(0x7173dd5d, 0x4b07e2b1), TOBN(0xd144c4cb, 0x8d9ea221), + TOBN(0xe8b04ea4, 0x1105ab14), TOBN(0x92dda542, 0xfe80d8f1), + TOBN(0xe9982fa8, 0xcf03dce6), TOBN(0x8b5ea965, 0x1a22cffc), + TOBN(0xf7f4ea7f, 0x3fad88c4), TOBN(0x62db773e, 0x6a5ba95c), + TOBN(0xd20f02fb, 0x93f24567), TOBN(0xfd46c69a, 0x315257ca), + TOBN(0x0ac74cc7, 0x8bcab987), TOBN(0x46f31c01, 0x5ceca2f5), + TOBN(0x40aedb59, 0x888b219e), TOBN(0xe50ecc37, 0xe1fccd02), + TOBN(0x1bcd9dad, 0x911f816c), TOBN(0x583cc1ec, 0x8db9b00c), + TOBN(0xf3cd2e66, 0xa483bf11), TOBN(0xfa08a6f5, 0xb1b2c169), + TOBN(0xf375e245, 0x4be9fa28), TOBN(0x99a7ffec, 0x5b6d011f), + TOBN(0x6a3ebddb, 0xc4ae62da), TOBN(0x6cea00ae, 0x374aef5d), + TOBN(0xab5fb98d, 0x9d4d05bc), TOBN(0x7cba1423, 0xd560f252), + TOBN(0x49b2cc21, 0x208490de), TOBN(0x1ca66ec3, 0xbcfb2879), + TOBN(0x7f1166b7, 0x1b6fb16f), TOBN(0xfff63e08, 0x65fe5db3), + TOBN(0xb8345abe, 0x8b2610be), TOBN(0xb732ed80, 0x39de3df4), + TOBN(0x0e24ed50, 0x211c32b4), TOBN(0xd10d8a69, 0x848ff27d), + TOBN(0xc1074398, 0xed4de248), TOBN(0xd7cedace, 0x10488927), + TOBN(0xa4aa6bf8, 0x85673e13), TOBN(0xb46bae91, 0x6daf30af), + TOBN(0x07088472, 0xfcef7ad8), TOBN(0x61151608, 0xd4b35e97), + TOBN(0xbcfe8f26, 0xdde29986), TOBN(0xeb84c4c7, 0xd5a34c79), + TOBN(0xc1eec55c, 0x164e1214), TOBN(0x891be86d, 0xa147bb03), + TOBN(0x9fab4d10, 0x0ba96835), TOBN(0xbf01e9b8, 0xa5c1ae9f), + TOBN(0x6b4de139, 0xb186ebc0), TOBN(0xd5c74c26, 0x85b91bca), + TOBN(0x5086a99c, 0xc2d93854), TOBN(0xeed62a7b, 0xa7a9dfbc), + TOBN(0x8778ed6f, 0x76b7618a), TOBN(0xbff750a5, 0x03b66062), + TOBN(0x4cb7be22, 0xb65186db), TOBN(0x369dfbf0, 0xcc3a6d13), + TOBN(0xc7dab26c, 0x7191a321), TOBN(0x9edac3f9, 0x40ed718e), + TOBN(0xbc142b36, 0xd0cfd183), TOBN(0xc8af82f6, 0x7c991693), + TOBN(0xb3d1e4d8, 0x97ce0b2a), TOBN(0xe6d7c87f, 0xc3a55cdf), + TOBN(0x35846b95, 0x68b81afe), TOBN(0x018d12af, 0xd3c239d8), + TOBN(0x2b2c6208, 0x01206e15), TOBN(0xe0e42453, 0xa3b882c6), + TOBN(0x854470a3, 0xa50162d5), TOBN(0x08157478, 0x7017a62a), + TOBN(0x18bd3fb4, 0x820357c7), TOBN(0x992039ae, 0x6f1458ad), + TOBN(0x9a1df3c5, 0x25b44aa1), TOBN(0x2d780357, 0xed3d5281), + TOBN(0x58cf7e4d, 0xc77ad4d4), TOBN(0xd49a7998, 0xf9df4fc4), + TOBN(0x4465a8b5, 0x1d71205e), TOBN(0xa0ee0ea6, 0x649254aa), + TOBN(0x4b5eeecf, 0xab7bd771), TOBN(0x6c873073, 0x35c262b9), + TOBN(0xdc5bd648, 0x3c9d61e7), TOBN(0x233d6d54, 0x321460d2), + TOBN(0xd20c5626, 0xfc195bcc), TOBN(0x25445958, 0x04d78b63), + TOBN(0xe03fcb3d, 0x17ec8ef3), TOBN(0x54b690d1, 0x46b8f781), + TOBN(0x82fa2c8a, 0x21230646), TOBN(0xf51aabb9, 0x084f418c), + TOBN(0xff4fbec1, 0x1a30ba43), TOBN(0x6a5acf73, 0x743c9df7), + TOBN(0x1da2b357, 0xd635b4d5), TOBN(0xc3de68dd, 0xecd5c1da), + TOBN(0xa689080b, 0xd61af0dd), TOBN(0xdea5938a, 0xd665bf99), + TOBN(0x0231d71a, 0xfe637294), TOBN(0x01968aa6, 0xa5a81cd8), + TOBN(0x11252d50, 0x048e63b5), TOBN(0xc446bc52, 0x6ca007e9), + TOBN(0xef8c50a6, 0x96d6134b), TOBN(0x9361fbf5, 0x9e09a05c), + TOBN(0xf17f85a6, 0xdca3291a), TOBN(0xb178d548, 0xff251a21), + TOBN(0x87f6374b, 0xa4df3915), TOBN(0x566ce1bf, 0x2fd5d608), + TOBN(0x425cba4d, 0x7de35102), TOBN(0x6b745f8f, 0x58c5d5e2), + TOBN(0x88402af6, 0x63122edf), TOBN(0x3190f9ed, 0x3b989a89), + TOBN(0x4ad3d387, 0xebba3156), TOBN(0xef385ad9, 0xc7c469a5), + TOBN(0xb08281de, 0x3f642c29), TOBN(0x20be0888, 0x910ffb88), + TOBN(0xf353dd4a, 0xd5292546), TOBN(0x3f1627de, 0x8377a262), + TOBN(0xa5faa013, 0xeefcd638), TOBN(0x8f3bf626, 0x74cc77c3), + TOBN(0x32618f65, 0xa348f55e), TOBN(0x5787c0dc, 0x9fefeb9e), + TOBN(0xf1673aa2, 0xd9a23e44), TOBN(0x88dfa993, 0x4e10690d), + TOBN(0x1ced1b36, 0x2bf91108), TOBN(0x9193ceca, 0x3af48649), + TOBN(0xfb34327d, 0x2d738fc5), TOBN(0x6697b037, 0x975fee6c), + TOBN(0x2f485da0, 0xc04079a5), TOBN(0x2cdf5735, 0x2feaa1ac), + TOBN(0x76944420, 0xbd55659e), TOBN(0x7973e32b, 0x4376090c), + TOBN(0x86bb4fe1, 0x163b591a), TOBN(0x10441aed, 0xc196f0ca), + TOBN(0x3b431f4a, 0x045ad915), TOBN(0x6c11b437, 0xa4afacb1), + TOBN(0x30b0c7db, 0x71fdbbd8), TOBN(0xb642931f, 0xeda65acd), + TOBN(0x4baae6e8, 0x9c92b235), TOBN(0xa73bbd0e, 0x6b3993a1), + TOBN(0xd06d60ec, 0x693dd031), TOBN(0x03cab91b, 0x7156881c), + TOBN(0xd615862f, 0x1db3574b), TOBN(0x485b0185, 0x64bb061a), + TOBN(0x27434988, 0xa0181e06), TOBN(0x2cd61ad4, 0xc1c0c757), + TOBN(0x3effed5a, 0x2ff9f403), TOBN(0x8dc98d8b, 0x62239029), + TOBN(0x2206021e, 0x1f17b70d), TOBN(0xafbec0ca, 0xbf510015), + TOBN(0x9fed7164, 0x80130dfa), TOBN(0x306dc2b5, 0x8a02dcf5), + TOBN(0x48f06620, 0xfeb10fc0), TOBN(0x78d1e1d5, 0x5a57cf51), + TOBN(0xadef8c5a, 0x192ef710), TOBN(0x88afbd4b, 0x3b7431f9), + TOBN(0x7e1f7407, 0x64250c9e), TOBN(0x6e31318d, 0xb58bec07), + TOBN(0xfd4fc4b8, 0x24f89b4e), TOBN(0x65a5dd88, 0x48c36a2a), + TOBN(0x4f1eccff, 0xf024baa7), TOBN(0x22a21cf2, 0xcba94650), + TOBN(0x95d29dee, 0x42a554f7), TOBN(0x828983a5, 0x002ec4ba), + TOBN(0x8112a1f7, 0x8badb73d), TOBN(0x79ea8897, 0xa27c1839), + TOBN(0x8969a5a7, 0xd065fd83), TOBN(0xf49af791, 0xb262a0bc), + TOBN(0xfcdea8b6, 0xaf2b5127), TOBN(0x10e913e1, 0x564c2dbc), + TOBN(0x51239d14, 0xbc21ef51), TOBN(0xe51c3ceb, 0x4ce57292), + TOBN(0x795ff068, 0x47bbcc3b), TOBN(0x86b46e1e, 0xbd7e11e6), + TOBN(0x0ea6ba23, 0x80041ef4), TOBN(0xd72fe505, 0x6262342e), + TOBN(0x8abc6dfd, 0x31d294d4), TOBN(0xbbe017a2, 0x1278c2c9), + TOBN(0xb1fcfa09, 0xb389328a), TOBN(0x322fbc62, 0xd01771b5), + TOBN(0x04c0d063, 0x60b045bf), TOBN(0xdb652edc, 0x10e52d01), + TOBN(0x50ef932c, 0x03ec6627), TOBN(0xde1b3b2d, 0xc1ee50e3), + TOBN(0x5ab7bdc5, 0xdc37a90d), TOBN(0xfea67213, 0x31e33a96), + TOBN(0x6482b5cb, 0x4f2999aa), TOBN(0x38476cc6, 0xb8cbf0dd), + TOBN(0x93ebfacb, 0x173405bb), TOBN(0x15cdafe7, 0xe52369ec), + TOBN(0xd42d5ba4, 0xd935b7db), TOBN(0x648b6004, 0x1c99a4cd), + TOBN(0x785101bd, 0xa3b5545b), TOBN(0x4bf2c38a, 0x9dd67faf), + TOBN(0xb1aadc63, 0x4442449c), TOBN(0xe0e9921a, 0x33ad4fb8), + TOBN(0x5c552313, 0xaa686d82), TOBN(0xdee635fa, 0x465d866c), + TOBN(0xbc3c224a, 0x18ee6e8a), TOBN(0xeed748a6, 0xed42e02f), + TOBN(0xe70f930a, 0xd474cd08), TOBN(0x774ea6ec, 0xfff24adf), + TOBN(0x03e2de1c, 0xf3480d4a), TOBN(0xf0d8edc7, 0xbc8acf1a), + TOBN(0xf23e3303, 0x68295a9c), TOBN(0xfadd5f68, 0xc546a97d), + TOBN(0x895597ad, 0x96f8acb1), TOBN(0xbddd49d5, 0x671bdae2), + TOBN(0x16fcd528, 0x21dd43f4), TOBN(0xa5a45412, 0x6619141a)}, + {TOBN(0x8ce9b6bf, 0xc360e25a), TOBN(0xe6425195, 0x075a1a78), + TOBN(0x9dc756a8, 0x481732f4), TOBN(0x83c0440f, 0x5432b57a), + TOBN(0xc670b3f1, 0xd720281f), TOBN(0x2205910e, 0xd135e051), + TOBN(0xded14b0e, 0xdb052be7), TOBN(0x697b3d27, 0xc568ea39), + TOBN(0x2e599b9a, 0xfb3ff9ed), TOBN(0x28c2e0ab, 0x17f6515c), + TOBN(0x1cbee4fd, 0x474da449), TOBN(0x071279a4, 0x4f364452), + TOBN(0x97abff66, 0x01fbe855), TOBN(0x3ee394e8, 0x5fda51c4), + TOBN(0x190385f6, 0x67597c0b), TOBN(0x6e9fccc6, 0xa27ee34b), + TOBN(0x0b89de93, 0x14092ebb), TOBN(0xf17256bd, 0x428e240c), + TOBN(0xcf89a7f3, 0x93d2f064), TOBN(0x4f57841e, 0xe1ed3b14), + TOBN(0x4ee14405, 0xe708d855), TOBN(0x856aae72, 0x03f1c3d0), + TOBN(0xc8e5424f, 0xbdd7eed5), TOBN(0x3333e4ef, 0x73ab4270), + TOBN(0x3bc77ade, 0xdda492f8), TOBN(0xc11a3aea, 0x78297205), + TOBN(0x5e89a3e7, 0x34931b4c), TOBN(0x17512e2e, 0x9f5694bb), + TOBN(0x5dc349f3, 0x177bf8b6), TOBN(0x232ea4ba, 0x08c7ff3e), + TOBN(0x9c4f9d16, 0xf511145d), TOBN(0xccf109a3, 0x33b379c3), + TOBN(0xe75e7a88, 0xa1f25897), TOBN(0x7ac6961f, 0xa1b5d4d8), + TOBN(0xe3e10773, 0x08f3ed5c), TOBN(0x208a54ec, 0x0a892dfb), + TOBN(0xbe826e19, 0x78660710), TOBN(0x0cf70a97, 0x237df2c8), + TOBN(0x418a7340, 0xed704da5), TOBN(0xa3eeb9a9, 0x08ca33fd), + TOBN(0x49d96233, 0x169bca96), TOBN(0x04d286d4, 0x2da6aafb), + TOBN(0xc09606ec, 0xa0c2fa94), TOBN(0x8869d0d5, 0x23ff0fb3), + TOBN(0xa99937e5, 0xd0150d65), TOBN(0xa92e2503, 0x240c14c9), + TOBN(0x656bf945, 0x108e2d49), TOBN(0x152a733a, 0xa2f59e2b), + TOBN(0xb4323d58, 0x8434a920), TOBN(0xc0af8e93, 0x622103c5), + TOBN(0x667518ef, 0x938dbf9a), TOBN(0xa1843073, 0x83a9cdf2), + TOBN(0x350a94aa, 0x5447ab80), TOBN(0xe5e5a325, 0xc75a3d61), + TOBN(0x74ba507f, 0x68411a9e), TOBN(0x10581fc1, 0x594f70c5), + TOBN(0x60e28570, 0x80eb24a9), TOBN(0x7bedfb4d, 0x488e0cfd), + TOBN(0x721ebbd7, 0xc259cdb8), TOBN(0x0b0da855, 0xbc6390a9), + TOBN(0x2b4d04db, 0xde314c70), TOBN(0xcdbf1fbc, 0x6c32e846), + TOBN(0x33833eab, 0xb162fc9e), TOBN(0x9939b48b, 0xb0dd3ab7), + TOBN(0x5aaa98a7, 0xcb0c9c8c), TOBN(0x75105f30, 0x81c4375c), + TOBN(0xceee5057, 0x5ef1c90f), TOBN(0xb31e065f, 0xc23a17bf), + TOBN(0x5364d275, 0xd4b6d45a), TOBN(0xd363f3ad, 0x62ec8996), + TOBN(0xb5d21239, 0x4391c65b), TOBN(0x84564765, 0xebb41b47), + TOBN(0x20d18ecc, 0x37107c78), TOBN(0xacff3b6b, 0x570c2a66), + TOBN(0x22f975d9, 0x9bd0d845), TOBN(0xef0a0c46, 0xba178fa0), + TOBN(0x1a419651, 0x76b6028e), TOBN(0xc49ec674, 0x248612d4), + TOBN(0x5b6ac4f2, 0x7338af55), TOBN(0x06145e62, 0x7bee5a36), + TOBN(0x33e95d07, 0xe75746b5), TOBN(0x1c1e1f6d, 0xc40c78be), + TOBN(0x967833ef, 0x222ff8e2), TOBN(0x4bedcf6a, 0xb49180ad), + TOBN(0x6b37e9c1, 0x3d7a4c8a), TOBN(0x2748887c, 0x6ddfe760), + TOBN(0xf7055123, 0xaa3a5bbc), TOBN(0x954ff225, 0x7bbb8e74), + TOBN(0xc42b8ab1, 0x97c3dfb9), TOBN(0x55a549b0, 0xcf168154), + TOBN(0xad6748e7, 0xc1b50692), TOBN(0x2775780f, 0x6fc5cbcb), + TOBN(0x4eab80b8, 0xe1c9d7c8), TOBN(0x8c69dae1, 0x3fdbcd56), + TOBN(0x47e6b4fb, 0x9969eace), TOBN(0x002f1085, 0xa705cb5a), + TOBN(0x4e23ca44, 0x6d3fea55), TOBN(0xb4ae9c86, 0xf4810568), + TOBN(0x47bfb91b, 0x2a62f27d), TOBN(0x60deb4c9, 0xd9bac28c), + TOBN(0xa892d894, 0x7de6c34c), TOBN(0x4ee68259, 0x4494587d), + TOBN(0x914ee14e, 0x1a3f8a5b), TOBN(0xbb113eaa, 0x28700385), + TOBN(0x81ca03b9, 0x2115b4c9), TOBN(0x7c163d38, 0x8908cad1), + TOBN(0xc912a118, 0xaa18179a), TOBN(0xe09ed750, 0x886e3081), + TOBN(0xa676e3fa, 0x26f516ca), TOBN(0x753cacf7, 0x8e732f91), + TOBN(0x51592aea, 0x833da8b4), TOBN(0xc626f42f, 0x4cbea8aa), + TOBN(0xef9dc899, 0xa7b56eaf), TOBN(0x00c0e52c, 0x34ef7316), + TOBN(0x5b1e4e24, 0xfe818a86), TOBN(0x9d31e20d, 0xc538be47), + TOBN(0x22eb932d, 0x3ed68974), TOBN(0xe44bbc08, 0x7c4e87c4), + TOBN(0x4121086e, 0x0dde9aef), TOBN(0x8e6b9cff, 0x134f4345), + TOBN(0x96892c1f, 0x711b0eb9), TOBN(0xb905f2c8, 0x780ab954), + TOBN(0xace26309, 0xa20792db), TOBN(0xec8ac9b3, 0x0684e126), + TOBN(0x486ad8b6, 0xb40a2447), TOBN(0x60121fc1, 0x9fe3fb24), + TOBN(0x5626fccf, 0x1a8e3b3f), TOBN(0x4e568622, 0x6ad1f394), + TOBN(0xda7aae0d, 0x196aa5a1), TOBN(0xe0df8c77, 0x1041b5fb), + TOBN(0x451465d9, 0x26b318b7), TOBN(0xc29b6e55, 0x7ab136e9), + TOBN(0x2c2ab48b, 0x71148463), TOBN(0xb5738de3, 0x64454a76), + TOBN(0x54ccf9a0, 0x5a03abe4), TOBN(0x377c0296, 0x0427d58e), + TOBN(0x73f5f0b9, 0x2bb39c1f), TOBN(0x14373f2c, 0xe608d8c5), + TOBN(0xdcbfd314, 0x00fbb805), TOBN(0xdf18fb20, 0x83afdcfb), + TOBN(0x81a57f42, 0x42b3523f), TOBN(0xe958532d, 0x87f650fb), + TOBN(0xaa8dc8b6, 0x8b0a7d7c), TOBN(0x1b75dfb7, 0x150166be), + TOBN(0x90e4f7c9, 0x2d7d1413), TOBN(0x67e2d6b5, 0x9834f597), + TOBN(0x4fd4f4f9, 0xa808c3e8), TOBN(0xaf8237e0, 0xd5281ec1), + TOBN(0x25ab5fdc, 0x84687cee), TOBN(0xc5ded6b1, 0xa5b26c09), + TOBN(0x8e4a5aec, 0xc8ea7650), TOBN(0x23b73e5c, 0x14cc417f), + TOBN(0x2bfb4318, 0x3037bf52), TOBN(0xb61e6db5, 0x78c725d7), + TOBN(0x8efd4060, 0xbbb3e5d7), TOBN(0x2e014701, 0xdbac488e), + TOBN(0xac75cf9a, 0x360aa449), TOBN(0xb70cfd05, 0x79634d08), + TOBN(0xa591536d, 0xfffb15ef), TOBN(0xb2c37582, 0xd07c106c), + TOBN(0xb4293fdc, 0xf50225f9), TOBN(0xc52e175c, 0xb0e12b03), + TOBN(0xf649c3ba, 0xd0a8bf64), TOBN(0x745a8fef, 0xeb8ae3c6), + TOBN(0x30d7e5a3, 0x58321bc3), TOBN(0xb1732be7, 0x0bc4df48), + TOBN(0x1f217993, 0xe9ea5058), TOBN(0xf7a71cde, 0x3e4fd745), + TOBN(0x86cc533e, 0x894c5bbb), TOBN(0x6915c7d9, 0x69d83082), + TOBN(0xa6aa2d05, 0x5815c244), TOBN(0xaeeee592, 0x49b22ce5), + TOBN(0x89e39d13, 0x78135486), TOBN(0x3a275c1f, 0x16b76f2f), + TOBN(0xdb6bcc1b, 0xe036e8f5), TOBN(0x4df69b21, 0x5e4709f5), + TOBN(0xa188b250, 0x2d0f39aa), TOBN(0x622118bb, 0x15a85947), + TOBN(0x2ebf520f, 0xfde0f4fa), TOBN(0xa40e9f29, 0x4860e539), + TOBN(0x7b6a51eb, 0x22b57f0f), TOBN(0x849a33b9, 0x7e80644a), + TOBN(0x50e5d16f, 0x1cf095fe), TOBN(0xd754b54e, 0xec55f002), + TOBN(0x5cfbbb22, 0x236f4a98), TOBN(0x0b0c59e9, 0x066800bb), + TOBN(0x4ac69a8f, 0x5a9a7774), TOBN(0x2b33f804, 0xd6bec948), + TOBN(0xb3729295, 0x32e6c466), TOBN(0x68956d0f, 0x4e599c73), + TOBN(0xa47a249f, 0x155c31cc), TOBN(0x24d80f0d, 0xe1ce284e), + TOBN(0xcd821dfb, 0x988baf01), TOBN(0xe6331a7d, 0xdbb16647), + TOBN(0x1eb8ad33, 0x094cb960), TOBN(0x593cca38, 0xc91bbca5), + TOBN(0x384aac8d, 0x26567456), TOBN(0x40fa0309, 0xc04b6490), + TOBN(0x97834cd6, 0xdab6c8f6), TOBN(0x68a7318d, 0x3f91e55f), + TOBN(0xa00fd04e, 0xfc4d3157), TOBN(0xb56f8ab2, 0x2bf3bdea), + TOBN(0x014f5648, 0x4fa57172), TOBN(0x948c5860, 0x450abdb3), + TOBN(0x342b5df0, 0x0ebd4f08), TOBN(0x3e5168cd, 0x0e82938e), + TOBN(0x7aedc1ce, 0xb0df5dd0), TOBN(0x6bbbc6d9, 0xe5732516), + TOBN(0xc7bfd486, 0x605daaa6), TOBN(0x46fd72b7, 0xbb9a6c9e), + TOBN(0xe4847fb1, 0xa124fb89), TOBN(0x75959cbd, 0xa2d8ffbc), + TOBN(0x42579f65, 0xc8a588ee), TOBN(0x368c92e6, 0xb80b499d), + TOBN(0xea4ef6cd, 0x999a5df1), TOBN(0xaa73bb7f, 0x936fe604), + TOBN(0xf347a70d, 0x6457d188), TOBN(0x86eda86b, 0x8b7a388b), + TOBN(0xb7cdff06, 0x0ccd6013), TOBN(0xbeb1b6c7, 0xd0053fb2), + TOBN(0x0b022387, 0x99240a9f), TOBN(0x1bbb384f, 0x776189b2), + TOBN(0x8695e71e, 0x9066193a), TOBN(0x2eb50097, 0x06ffac7e), + TOBN(0x0654a9c0, 0x4a7d2caa), TOBN(0x6f3fb3d1, 0xa5aaa290), + TOBN(0x835db041, 0xff476e8f), TOBN(0x540b8b0b, 0xc42295e4), + TOBN(0xa5c73ac9, 0x05e214f5), TOBN(0x9a74075a, 0x56a0b638), + TOBN(0x2e4b1090, 0xce9e680b), TOBN(0x57a5b479, 0x6b8d9afa), + TOBN(0x0dca48e7, 0x26bfe65c), TOBN(0x097e391c, 0x7290c307), + TOBN(0x683c462e, 0x6669e72e), TOBN(0xf505be1e, 0x062559ac), + TOBN(0x5fbe3ea1, 0xe3a3035a), TOBN(0x6431ebf6, 0x9cd50da8), + TOBN(0xfd169d5c, 0x1f6407f2), TOBN(0x8d838a95, 0x60fce6b8), + TOBN(0x2a2bfa7f, 0x650006f0), TOBN(0xdfd7dad3, 0x50c0fbb2), + TOBN(0x92452495, 0xccf9ad96), TOBN(0x183bf494, 0xd95635f9), + TOBN(0x02d5df43, 0x4a7bd989), TOBN(0x505385cc, 0xa5431095), + TOBN(0xdd98e67d, 0xfd43f53e), TOBN(0xd61e1a6c, 0x500c34a9), + TOBN(0x5a4b46c6, 0x4a8a3d62), TOBN(0x8469c4d0, 0x247743d2), + TOBN(0x2bb3a13d, 0x88f7e433), TOBN(0x62b23a10, 0x01be5849), + TOBN(0xe83596b4, 0xa63d1a4c), TOBN(0x454e7fea, 0x7d183f3e), + TOBN(0x643fce61, 0x17afb01c), TOBN(0x4e65e5e6, 0x1c4c3638), + TOBN(0x41d85ea1, 0xef74c45b), TOBN(0x2cfbfa66, 0xae328506), + TOBN(0x98b078f5, 0x3ada7da9), TOBN(0xd985fe37, 0xec752fbb), + TOBN(0xeece68fe, 0x5a0148b4), TOBN(0x6f9a55c7, 0x2d78136d), + TOBN(0x232dccc4, 0xd2b729ce), TOBN(0xa27e0dfd, 0x90aafbc4), + TOBN(0x96474452, 0x12b4603e), TOBN(0xa876c551, 0x6b706d14), + TOBN(0xdf145fcf, 0x69a9d412), TOBN(0xe2ab75b7, 0x2d479c34), + TOBN(0x12df9a76, 0x1a23ff97), TOBN(0xc6138992, 0x5d359d10), + TOBN(0x6e51c7ae, 0xfa835f22), TOBN(0x69a79cb1, 0xc0fcc4d9), + TOBN(0xf57f350d, 0x594cc7e1), TOBN(0x3079ca63, 0x3350ab79), + TOBN(0x226fb614, 0x9aff594a), TOBN(0x35afec02, 0x6d59a62b), + TOBN(0x9bee46f4, 0x06ed2c6e), TOBN(0x58da1735, 0x7d939a57), + TOBN(0x44c50402, 0x8fd1797e), TOBN(0xd8853e7c, 0x5ccea6ca), + TOBN(0x4065508d, 0xa35fcd5f), TOBN(0x8965df8c, 0x495ccaeb), + TOBN(0x0f2da850, 0x12e1a962), TOBN(0xee471b94, 0xc1cf1cc4), + TOBN(0xcef19bc8, 0x0a08fb75), TOBN(0x704958f5, 0x81de3591), + TOBN(0x2867f8b2, 0x3aef4f88), TOBN(0x8d749384, 0xea9f9a5f), + TOBN(0x1b385537, 0x8c9049f4), TOBN(0x5be948f3, 0x7b92d8b6), + TOBN(0xd96f725d, 0xb6e2bd6b), TOBN(0x37a222bc, 0x958c454d), + TOBN(0xe7c61abb, 0x8809bf61), TOBN(0x46f07fbc, 0x1346f18d), + TOBN(0xfb567a7a, 0xe87c0d1c), TOBN(0x84a461c8, 0x7ef3d07a), + TOBN(0x0a5adce6, 0xd9278d98), TOBN(0x24d94813, 0x9dfc73e1), + TOBN(0x4f3528b6, 0x054321c3), TOBN(0x2e03fdde, 0x692ea706), + TOBN(0x10e60619, 0x47b533c0), TOBN(0x1a8bc73f, 0x2ca3c055), + TOBN(0xae58d4b2, 0x1bb62b8f), TOBN(0xb2045a73, 0x584a24e3), + TOBN(0x3ab3d5af, 0xbd76e195), TOBN(0x478dd1ad, 0x6938a810), + TOBN(0x6ffab393, 0x6ee3d5cb), TOBN(0xdfb693db, 0x22b361e4), + TOBN(0xf9694496, 0x51dbf1a7), TOBN(0xcab4b4ef, 0x08a2e762), + TOBN(0xe8c92f25, 0xd39bba9a), TOBN(0x850e61bc, 0xf1464d96), + TOBN(0xb7e830e3, 0xdc09508b), TOBN(0xfaf6d2cf, 0x74317655), + TOBN(0x72606ceb, 0xdf690355), TOBN(0x48bb92b3, 0xd0c3ded6), + TOBN(0x65b75484, 0x5c7cf892), TOBN(0xf6cd7ac9, 0xd5d5f01f), + TOBN(0xc2c30a59, 0x96401d69), TOBN(0x91268650, 0xed921878), + TOBN(0x380bf913, 0xb78c558f), TOBN(0x43c0baeb, 0xc8afdaa9), + TOBN(0x377f61d5, 0x54f169d3), TOBN(0xf8da07e3, 0xae5ff20b), + TOBN(0xb676c49d, 0xa8a90ea8), TOBN(0x81c1ff2b, 0x83a29b21), + TOBN(0x383297ac, 0x2ad8d276), TOBN(0x3001122f, 0xba89f982), + TOBN(0xe1d794be, 0x6718e448), TOBN(0x246c1482, 0x7c3e6e13), + TOBN(0x56646ef8, 0x5d26b5ef), TOBN(0x80f5091e, 0x88069cdd), + TOBN(0xc5992e2f, 0x724bdd38), TOBN(0x02e915b4, 0x8471e8c7), + TOBN(0x96ff320a, 0x0d0ff2a9), TOBN(0xbf886487, 0x4384d1a0), + TOBN(0xbbe1e6a6, 0xc93f72d6), TOBN(0xd5f75d12, 0xcad800ea), + TOBN(0xfa40a09f, 0xe7acf117), TOBN(0x32c8cdd5, 0x7581a355), + TOBN(0x74221992, 0x7023c499), TOBN(0xa8afe5d7, 0x38ec3901), + TOBN(0x5691afcb, 0xa90e83f0), TOBN(0x41bcaa03, 0x0b8f8eac), + TOBN(0xe38b5ff9, 0x8d2668d5), TOBN(0x0715281a, 0x7ad81965), + TOBN(0x1bc8fc7c, 0x03c6ce11), TOBN(0xcbbee6e2, 0x8b650436), + TOBN(0x06b00fe8, 0x0cdb9808), TOBN(0x17d6e066, 0xfe3ed315), + TOBN(0x2e9d38c6, 0x4d0b5018), TOBN(0xab8bfd56, 0x844dcaef), + TOBN(0x42894a59, 0x513aed8b), TOBN(0xf77f3b6d, 0x314bd07a), + TOBN(0xbbdecb8f, 0x8e42b582), TOBN(0xf10e2fa8, 0xd2390fe6), + TOBN(0xefb95022, 0x62a2f201), TOBN(0x4d59ea50, 0x50ee32b0), + TOBN(0xd87f7728, 0x6da789a8), TOBN(0xcf98a2cf, 0xf79492c4), + TOBN(0xf9577239, 0x720943c2), TOBN(0xba044cf5, 0x3990b9d0), + TOBN(0x5aa8e823, 0x95f2884a), TOBN(0x834de6ed, 0x0278a0af), + TOBN(0xc8e1ee9a, 0x5f25bd12), TOBN(0x9259ceaa, 0x6f7ab271), + TOBN(0x7e6d97a2, 0x77d00b76), TOBN(0x5c0c6eea, 0xa437832a), + TOBN(0x5232c20f, 0x5606b81d), TOBN(0xabd7b375, 0x0d991ee5), + TOBN(0x4d2bfe35, 0x8632d951), TOBN(0x78f85146, 0x98ed9364), + TOBN(0x951873f0, 0xf30c3282), TOBN(0x0da8ac80, 0xa789230b), + TOBN(0x3ac7789c, 0x5398967f), TOBN(0xa69b8f7f, 0xbdda0fb5), + TOBN(0xe5db7717, 0x6add8545), TOBN(0x1b71cb66, 0x72c49b66), + TOBN(0xd8560739, 0x68421d77), TOBN(0x03840fe8, 0x83e3afea), + TOBN(0xb391dad5, 0x1ec69977), TOBN(0xae243fb9, 0x307f6726), + TOBN(0xc88ac87b, 0xe8ca160c), TOBN(0x5174cced, 0x4ce355f4), + TOBN(0x98a35966, 0xe58ba37d), TOBN(0xfdcc8da2, 0x7817335d), + TOBN(0x5b752830, 0x83fbc7bf), TOBN(0x68e419d4, 0xd9c96984), + TOBN(0x409a39f4, 0x02a40380), TOBN(0x88940faf, 0x1fe977bc), + TOBN(0xc640a94b, 0x8f8edea6), TOBN(0x1e22cd17, 0xed11547d), + TOBN(0xe28568ce, 0x59ffc3e2), TOBN(0x60aa1b55, 0xc1dee4e7), + TOBN(0xc67497c8, 0x837cb363), TOBN(0x06fb438a, 0x105a2bf2), + TOBN(0x30357ec4, 0x500d8e20), TOBN(0x1ad9095d, 0x0670db10), + TOBN(0x7f589a05, 0xc73b7cfd), TOBN(0xf544607d, 0x880d6d28), + TOBN(0x17ba93b1, 0xa20ef103), TOBN(0xad859130, 0x6ba6577b), + TOBN(0x65c91cf6, 0x6fa214a0), TOBN(0xd7d49c6c, 0x27990da5), + TOBN(0xecd9ec8d, 0x20bb569d), TOBN(0xbd4b2502, 0xeeffbc33), + TOBN(0x2056ca5a, 0x6bed0467), TOBN(0x7916a1f7, 0x5b63728c), + TOBN(0xd4f9497d, 0x53a4f566), TOBN(0x89734664, 0x97b56810), + TOBN(0xf8e1da74, 0x0494a621), TOBN(0x82546a93, 0x8d011c68), + TOBN(0x1f3acb19, 0xc61ac162), TOBN(0x52f8fa9c, 0xabad0d3e), + TOBN(0x15356523, 0xb4b7ea43), TOBN(0x5a16ad61, 0xae608125), + TOBN(0xb0bcb87f, 0x4faed184), TOBN(0x5f236b1d, 0x5029f45f), + TOBN(0xd42c7607, 0x0bc6b1fc), TOBN(0xc644324e, 0x68aefce3), + TOBN(0x8e191d59, 0x5c5d8446), TOBN(0xc0208077, 0x13ae1979), + TOBN(0xadcaee55, 0x3ba59cc7), TOBN(0x20ed6d6b, 0xa2cb81ba), + TOBN(0x0952ba19, 0xb6efcffc), TOBN(0x60f12d68, 0x97c0b87c), + TOBN(0x4ee2c7c4, 0x9caa30bc), TOBN(0x767238b7, 0x97fbff4e), + TOBN(0xebc73921, 0x501b5d92), TOBN(0x3279e3df, 0xc2a37737), + TOBN(0x9fc12bc8, 0x6d197543), TOBN(0xfa94dc6f, 0x0a40db4e), + TOBN(0x7392b41a, 0x530ccbbd), TOBN(0x87c82146, 0xea823525), + TOBN(0xa52f984c, 0x05d98d0c), TOBN(0x2ae57d73, 0x5ef6974c), + TOBN(0x9377f7bf, 0x3042a6dd), TOBN(0xb1a007c0, 0x19647a64), + TOBN(0xfaa9079a, 0x0cca9767), TOBN(0x3d81a25b, 0xf68f72d5), + TOBN(0x752067f8, 0xff81578e), TOBN(0x78622150, 0x9045447d), + TOBN(0xc0c22fcf, 0x0505aa6f), TOBN(0x1030f0a6, 0x6bed1c77), + TOBN(0x31f29f15, 0x1f0bd739), TOBN(0x2d7989c7, 0xe6debe85), + TOBN(0x5c070e72, 0x8e677e98), TOBN(0x0a817bd3, 0x06e81fd5), + TOBN(0xc110d830, 0xb0f2ac95), TOBN(0x48d0995a, 0xab20e64e), + TOBN(0x0f3e00e1, 0x7729cd9a), TOBN(0x2a570c20, 0xdd556946), + TOBN(0x912dbcfd, 0x4e86214d), TOBN(0x2d014ee2, 0xcf615498), + TOBN(0x55e2b1e6, 0x3530d76e), TOBN(0xc5135ae4, 0xfd0fd6d1), + TOBN(0x0066273a, 0xd4f3049f), TOBN(0xbb8e9893, 0xe7087477), + TOBN(0x2dba1ddb, 0x14c6e5fd), TOBN(0xdba37886, 0x51f57e6c), + TOBN(0x5aaee0a6, 0x5a72f2cf), TOBN(0x1208bfbf, 0x7bea5642), + TOBN(0xf5c6aa3b, 0x67872c37), TOBN(0xd726e083, 0x43f93224), + TOBN(0x1854daa5, 0x061f1658), TOBN(0xc0016df1, 0xdf0cd2b3), + TOBN(0xc2a3f23e, 0x833d50de), TOBN(0x73b681d2, 0xbbbd3017), + TOBN(0x2f046dc4, 0x3ac343c0), TOBN(0x9c847e7d, 0x85716421), + TOBN(0xe1e13c91, 0x0917eed4), TOBN(0x3fc9eebd, 0x63a1b9c6), + TOBN(0x0f816a72, 0x7fe02299), TOBN(0x6335ccc2, 0x294f3319), + TOBN(0x3820179f, 0x4745c5be), TOBN(0xe647b782, 0x922f066e), + TOBN(0xc22e49de, 0x02cafb8a), TOBN(0x299bc2ff, 0xfcc2eccc), + TOBN(0x9a8feea2, 0x6e0e8282), TOBN(0xa627278b, 0xfe893205), + TOBN(0xa7e19733, 0x7933e47b), TOBN(0xf4ff6b13, 0x2e766402), + TOBN(0xa4d8be0a, 0x98440d9f), TOBN(0x658f5c2f, 0x38938808), + TOBN(0x90b75677, 0xc95b3b3e), TOBN(0xfa044269, 0x3137b6ff), + TOBN(0x077b039b, 0x43c47c29), TOBN(0xcca95dd3, 0x8a6445b2), + TOBN(0x0b498ba4, 0x2333fc4c), TOBN(0x274f8e68, 0xf736a1b1), + TOBN(0x6ca348fd, 0x5f1d4b2e), TOBN(0x24d3be78, 0xa8f10199), + TOBN(0x8535f858, 0xca14f530), TOBN(0xa6e7f163, 0x5b982e51), + TOBN(0x847c8512, 0x36e1bf62), TOBN(0xf6a7c58e, 0x03448418), + TOBN(0x583f3703, 0xf9374ab6), TOBN(0x864f9195, 0x6e564145), + TOBN(0x33bc3f48, 0x22526d50), TOBN(0x9f323c80, 0x1262a496), + TOBN(0xaa97a7ae, 0x3f046a9a), TOBN(0x70da183e, 0xdf8a039a), + TOBN(0x5b68f71c, 0x52aa0ba6), TOBN(0x9be0fe51, 0x21459c2d), + TOBN(0xc1e17eb6, 0xcbc613e5), TOBN(0x33131d55, 0x497ea61c), + TOBN(0x2f69d39e, 0xaf7eded5), TOBN(0x73c2f434, 0xde6af11b), + TOBN(0x4ca52493, 0xa4a375fa), TOBN(0x5f06787c, 0xb833c5c2), + TOBN(0x814e091f, 0x3e6e71cf), TOBN(0x76451f57, 0x8b746666)}, + {TOBN(0x80f9bdef, 0x694db7e0), TOBN(0xedca8787, 0xb9fcddc6), + TOBN(0x51981c34, 0x03b8dce1), TOBN(0x4274dcf1, 0x70e10ba1), + TOBN(0xf72743b8, 0x6def6d1a), TOBN(0xd25b1670, 0xebdb1866), + TOBN(0xc4491e8c, 0x050c6f58), TOBN(0x2be2b2ab, 0x87fbd7f5), + TOBN(0x3e0e5c9d, 0xd111f8ec), TOBN(0xbcc33f8d, 0xb7c4e760), + TOBN(0x702f9a91, 0xbd392a51), TOBN(0x7da4a795, 0xc132e92d), + TOBN(0x1a0b0ae3, 0x0bb1151b), TOBN(0x54febac8, 0x02e32251), + TOBN(0xea3a5082, 0x694e9e78), TOBN(0xe58ffec1, 0xe4fe40b8), + TOBN(0xf85592fc, 0xd1e0cf9e), TOBN(0xdea75f0d, 0xc0e7b2e8), + TOBN(0xc04215cf, 0xc135584e), TOBN(0x174fc727, 0x2f57092a), + TOBN(0xe7277877, 0xeb930bea), TOBN(0x504caccb, 0x5eb02a5a), + TOBN(0xf9fe08f7, 0xf5241b9b), TOBN(0xe7fb62f4, 0x8d5ca954), + TOBN(0xfbb8349d, 0x29c4120b), TOBN(0x9f94391f, 0xc0d0d915), + TOBN(0xc4074fa7, 0x5410ba51), TOBN(0xa66adbf6, 0x150a5911), + TOBN(0xc164543c, 0x34bfca38), TOBN(0xe0f27560, 0xb9e1ccfc), + TOBN(0x99da0f53, 0xe820219c), TOBN(0xe8234498, 0xc6b4997a), + TOBN(0xcfb88b76, 0x9d4c5423), TOBN(0x9e56eb10, 0xb0521c49), + TOBN(0x418e0b5e, 0xbe8700a1), TOBN(0x00cbaad6, 0xf93cb58a), + TOBN(0xe923fbde, 0xd92a5e67), TOBN(0xca4979ac, 0x1f347f11), + TOBN(0x89162d85, 0x6bc0585b), TOBN(0xdd6254af, 0xac3c70e3), + TOBN(0x7b23c513, 0x516e19e4), TOBN(0x56e2e847, 0xc5c4d593), + TOBN(0x9f727d73, 0x5ce71ef6), TOBN(0x5b6304a6, 0xf79a44c5), + TOBN(0x6638a736, 0x3ab7e433), TOBN(0x1adea470, 0xfe742f83), + TOBN(0xe054b854, 0x5b7fc19f), TOBN(0xf935381a, 0xba1d0698), + TOBN(0x546eab2d, 0x799e9a74), TOBN(0x96239e0e, 0xa949f729), + TOBN(0xca274c6b, 0x7090055a), TOBN(0x835142c3, 0x9020c9b0), + TOBN(0xa405667a, 0xa2e8807f), TOBN(0x29f2c085, 0x1aa3d39e), + TOBN(0xcc555d64, 0x42fc72f5), TOBN(0xe856e0e7, 0xfbeacb3c), + TOBN(0xb5504f9d, 0x918e4936), TOBN(0x65035ef6, 0xb2513982), + TOBN(0x0553a0c2, 0x6f4d9cb9), TOBN(0x6cb10d56, 0xbea85509), + TOBN(0x48d957b7, 0xa242da11), TOBN(0x16a4d3dd, 0x672b7268), + TOBN(0x3d7e637c, 0x8502a96b), TOBN(0x27c7032b, 0x730d463b), + TOBN(0xbdc02b18, 0xe4136a14), TOBN(0xbacf969d, 0x678e32bf), + TOBN(0xc98d89a3, 0xdd9c3c03), TOBN(0x7b92420a, 0x23becc4f), + TOBN(0xd4b41f78, 0xc64d565c), TOBN(0x9f969d00, 0x10f28295), + TOBN(0xec7f7f76, 0xb13d051a), TOBN(0x08945e1e, 0xa92da585), + TOBN(0x55366b7d, 0x5846426f), TOBN(0xe7d09e89, 0x247d441d), + TOBN(0x510b404d, 0x736fbf48), TOBN(0x7fa003d0, 0xe784bd7d), + TOBN(0x25f7614f, 0x17fd9596), TOBN(0x49e0e0a1, 0x35cb98db), + TOBN(0x2c65957b, 0x2e83a76a), TOBN(0x5d40da8d, 0xcddbe0f8), + TOBN(0xf2b8c405, 0x050bad24), TOBN(0x8918426d, 0xc2aa4823), + TOBN(0x2aeab3dd, 0xa38365a7), TOBN(0x72031717, 0x7c91b690), + TOBN(0x8b00d699, 0x60a94120), TOBN(0x478a255d, 0xe99eaeec), + TOBN(0xbf656a5f, 0x6f60aafd), TOBN(0xdfd7cb75, 0x5dee77b3), + TOBN(0x37f68bb4, 0xa595939d), TOBN(0x03556479, 0x28740217), + TOBN(0x8e740e7c, 0x84ad7612), TOBN(0xd89bc843, 0x9044695f), + TOBN(0xf7f3da5d, 0x85a9184d), TOBN(0x562563bb, 0x9fc0b074), + TOBN(0x06d2e6aa, 0xf88a888e), TOBN(0x612d8643, 0x161fbe7c), + TOBN(0x465edba7, 0xf64085e7), TOBN(0xb230f304, 0x29aa8511), + TOBN(0x53388426, 0xcda2d188), TOBN(0x90885735, 0x4b666649), + TOBN(0x6f02ff9a, 0x652f54f6), TOBN(0x65c82294, 0x5fae2bf0), + TOBN(0x7816ade0, 0x62f5eee3), TOBN(0xdcdbdf43, 0xfcc56d70), + TOBN(0x9fb3bba3, 0x54530bb2), TOBN(0xbde3ef77, 0xcb0869ea), + TOBN(0x89bc9046, 0x0b431163), TOBN(0x4d03d7d2, 0xe4819a35), + TOBN(0x33ae4f9e, 0x43b6a782), TOBN(0x216db307, 0x9c88a686), + TOBN(0x91dd88e0, 0x00ffedd9), TOBN(0xb280da9f, 0x12bd4840), + TOBN(0x32a7cb8a, 0x1635e741), TOBN(0xfe14008a, 0x78be02a7), + TOBN(0x3fafb334, 0x1b7ae030), TOBN(0x7fd508e7, 0x5add0ce9), + TOBN(0x72c83219, 0xd607ad51), TOBN(0x0f229c0a, 0x8d40964a), + TOBN(0x1be2c336, 0x1c878da2), TOBN(0xe0c96742, 0xeab2ab86), + TOBN(0x458f8691, 0x3e538cd7), TOBN(0xa7001f6c, 0x8e08ad53), + TOBN(0x52b8c6e6, 0xbf5d15ff), TOBN(0x548234a4, 0x011215dd), + TOBN(0xff5a9d2d, 0x3d5b4045), TOBN(0xb0ffeeb6, 0x4a904190), + TOBN(0x55a3aca4, 0x48607f8b), TOBN(0x8cbd665c, 0x30a0672a), + TOBN(0x87f834e0, 0x42583068), TOBN(0x02da2aeb, 0xf3f6e683), + TOBN(0x6b763e5d, 0x05c12248), TOBN(0x7230378f, 0x65a8aefc), + TOBN(0x93bd80b5, 0x71e8e5ca), TOBN(0x53ab041c, 0xb3b62524), + TOBN(0x1b860513, 0x6c9c552e), TOBN(0xe84d402c, 0xd5524e66), + TOBN(0xa37f3573, 0xf37f5937), TOBN(0xeb0f6c7d, 0xd1e4fca5), + TOBN(0x2965a554, 0xac8ab0fc), TOBN(0x17fbf56c, 0x274676ac), + TOBN(0x2e2f6bd9, 0xacf7d720), TOBN(0x41fc8f88, 0x10224766), + TOBN(0x517a14b3, 0x85d53bef), TOBN(0xdae327a5, 0x7d76a7d1), + TOBN(0x6ad0a065, 0xc4818267), TOBN(0x33aa189b, 0x37c1bbc1), + TOBN(0x64970b52, 0x27392a92), TOBN(0x21699a1c, 0x2d1535ea), + TOBN(0xcd20779c, 0xc2d7a7fd), TOBN(0xe3186059, 0x99c83cf2), + TOBN(0x9b69440b, 0x72c0b8c7), TOBN(0xa81497d7, 0x7b9e0e4d), + TOBN(0x515d5c89, 0x1f5f82dc), TOBN(0x9a7f67d7, 0x6361079e), + TOBN(0xa8da81e3, 0x11a35330), TOBN(0xe44990c4, 0x4b18be1b), + TOBN(0xc7d5ed95, 0xaf103e59), TOBN(0xece8aba7, 0x8dac9261), + TOBN(0xbe82b099, 0x9394b8d3), TOBN(0x6830f09a, 0x16adfe83), + TOBN(0x250a29b4, 0x88172d01), TOBN(0x8b20bd65, 0xcaff9e02), + TOBN(0xb8a7661e, 0xe8a6329a), TOBN(0x4520304d, 0xd3fce920), + TOBN(0xae45da1f, 0x2b47f7ef), TOBN(0xe07f5288, 0x5bffc540), + TOBN(0xf7997009, 0x3464f874), TOBN(0x2244c2cd, 0xa6fa1f38), + TOBN(0x43c41ac1, 0x94d7d9b1), TOBN(0x5bafdd82, 0xc82e7f17), + TOBN(0xdf0614c1, 0x5fda0fca), TOBN(0x74b043a7, 0xa8ae37ad), + TOBN(0x3ba6afa1, 0x9e71734c), TOBN(0x15d5437e, 0x9c450f2e), + TOBN(0x4a5883fe, 0x67e242b1), TOBN(0x5143bdc2, 0x2c1953c2), + TOBN(0x542b8b53, 0xfc5e8920), TOBN(0x363bf9a8, 0x9a9cee08), + TOBN(0x02375f10, 0xc3486e08), TOBN(0x2037543b, 0x8c5e70d2), + TOBN(0x7109bccc, 0x625640b4), TOBN(0xcbc1051e, 0x8bc62c3b), + TOBN(0xf8455fed, 0x803f26ea), TOBN(0x6badceab, 0xeb372424), + TOBN(0xa2a9ce7c, 0x6b53f5f9), TOBN(0x64246595, 0x1b176d99), + TOBN(0xb1298d36, 0xb95c081b), TOBN(0x53505bb8, 0x1d9a9ee6), + TOBN(0x3f6f9e61, 0xf2ba70b0), TOBN(0xd07e16c9, 0x8afad453), + TOBN(0x9f1694bb, 0xe7eb4a6a), TOBN(0xdfebced9, 0x3cb0bc8e), + TOBN(0x92d3dcdc, 0x53868c8b), TOBN(0x174311a2, 0x386107a6), + TOBN(0x4109e07c, 0x689b4e64), TOBN(0x30e4587f, 0x2df3dcb6), + TOBN(0x841aea31, 0x0811b3b2), TOBN(0x6144d41d, 0x0cce43ea), + TOBN(0x464c4581, 0x2a9a7803), TOBN(0xd03d371f, 0x3e158930), + TOBN(0xc676d7f2, 0xb1f3390b), TOBN(0x9f7a1b8c, 0xa5b61272), + TOBN(0x4ebebfc9, 0xc2e127a9), TOBN(0x4602500c, 0x5dd997bf), + TOBN(0x7f09771c, 0x4711230f), TOBN(0x058eb37c, 0x020f09c1), + TOBN(0xab693d4b, 0xfee5e38b), TOBN(0x9289eb1f, 0x4653cbc0), + TOBN(0xbecf46ab, 0xd51b9cf5), TOBN(0xd2aa9c02, 0x9f0121af), + TOBN(0x36aaf7d2, 0xe90dc274), TOBN(0x909e4ea0, 0x48b95a3c), + TOBN(0xe6b70496, 0x6f32dbdb), TOBN(0x672188a0, 0x8b030b3e), + TOBN(0xeeffe5b3, 0xcfb617e2), TOBN(0x87e947de, 0x7c82709e), + TOBN(0xa44d2b39, 0x1770f5a7), TOBN(0xe4d4d791, 0x0e44eb82), + TOBN(0x42e69d1e, 0x3f69712a), TOBN(0xbf11c4d6, 0xac6a820e), + TOBN(0xb5e7f3e5, 0x42c4224c), TOBN(0xd6b4e81c, 0x449d941c), + TOBN(0x5d72bd16, 0x5450e878), TOBN(0x6a61e28a, 0xee25ac54), + TOBN(0x33272094, 0xe6f1cd95), TOBN(0x7512f30d, 0x0d18673f), + TOBN(0x32f7a4ca, 0x5afc1464), TOBN(0x2f095656, 0x6bbb977b), + TOBN(0x586f47ca, 0xa8226200), TOBN(0x02c868ad, 0x1ac07369), + TOBN(0x4ef2b845, 0xc613acbe), TOBN(0x43d7563e, 0x0386054c), + TOBN(0x54da9dc7, 0xab952578), TOBN(0xb5423df2, 0x26e84d0b), + TOBN(0xa8b64eeb, 0x9b872042), TOBN(0xac205782, 0x5990f6df), + TOBN(0x4ff696eb, 0x21f4c77a), TOBN(0x1a79c3e4, 0xaab273af), + TOBN(0x29bc922e, 0x9436b3f1), TOBN(0xff807ef8, 0xd6d9a27a), + TOBN(0x82acea3d, 0x778f22a0), TOBN(0xfb10b2e8, 0x5b5e7469), + TOBN(0xc0b16980, 0x2818ee7d), TOBN(0x011afff4, 0xc91c1a2f), + TOBN(0x95a6d126, 0xad124418), TOBN(0x31c081a5, 0xe72e295f), + TOBN(0x36bb283a, 0xf2f4db75), TOBN(0xd115540f, 0x7acef462), + TOBN(0xc7f3a8f8, 0x33f6746c), TOBN(0x21e46f65, 0xfea990ca), + TOBN(0x915fd5c5, 0xcaddb0a9), TOBN(0xbd41f016, 0x78614555), + TOBN(0x346f4434, 0x426ffb58), TOBN(0x80559436, 0x14dbc204), + TOBN(0xf3dd20fe, 0x5a969b7f), TOBN(0x9d59e956, 0xe899a39a), + TOBN(0xf1b0971c, 0x8ad4cf4b), TOBN(0x03448860, 0x2ffb8fb8), + TOBN(0xf071ac3c, 0x65340ba4), TOBN(0x408d0596, 0xb27fd758), + TOBN(0xe7c78ea4, 0x98c364b0), TOBN(0xa4aac4a5, 0x051e8ab5), + TOBN(0xb9e1d560, 0x485d9002), TOBN(0x9acd518a, 0x88844455), + TOBN(0xe4ca688f, 0xd06f56c0), TOBN(0xa48af70d, 0xdf027972), + TOBN(0x691f0f04, 0x5e9a609d), TOBN(0xa9dd82cd, 0xee61270e), + TOBN(0x8903ca63, 0xa0ef18d3), TOBN(0x9fb7ee35, 0x3d6ca3bd), + TOBN(0xa7b4a09c, 0xabf47d03), TOBN(0x4cdada01, 0x1c67de8e), + TOBN(0x52003749, 0x9355a244), TOBN(0xe77fd2b6, 0x4f2151a9), + TOBN(0x695d6cf6, 0x66b4efcb), TOBN(0xc5a0cacf, 0xda2cfe25), + TOBN(0x104efe5c, 0xef811865), TOBN(0xf52813e8, 0x9ea5cc3d), + TOBN(0x855683dc, 0x40b58dbc), TOBN(0x0338ecde, 0x175fcb11), + TOBN(0xf9a05637, 0x74921592), TOBN(0xb4f1261d, 0xb9bb9d31), + TOBN(0x551429b7, 0x4e9c5459), TOBN(0xbe182e6f, 0x6ea71f53), + TOBN(0xd3a3b07c, 0xdfc50573), TOBN(0x9ba1afda, 0x62be8d44), + TOBN(0x9bcfd2cb, 0x52ab65d3), TOBN(0xdf11d547, 0xa9571802), + TOBN(0x099403ee, 0x02a2404a), TOBN(0x497406f4, 0x21088a71), + TOBN(0x99479409, 0x5004ae71), TOBN(0xbdb42078, 0xa812c362), + TOBN(0x2b72a30f, 0xd8828442), TOBN(0x283add27, 0xfcb5ed1c), + TOBN(0xf7c0e200, 0x66a40015), TOBN(0x3e3be641, 0x08b295ef), + TOBN(0xac127dc1, 0xe038a675), TOBN(0x729deff3, 0x8c5c6320), + TOBN(0xb7df8fd4, 0xa90d2c53), TOBN(0x9b74b0ec, 0x681e7cd3), + TOBN(0x5cb5a623, 0xdab407e5), TOBN(0xcdbd3615, 0x76b340c6), + TOBN(0xa184415a, 0x7d28392c), TOBN(0xc184c1d8, 0xe96f7830), + TOBN(0xc3204f19, 0x81d3a80f), TOBN(0xfde0c841, 0xc8e02432), + TOBN(0x78203b3e, 0x8149e0c1), TOBN(0x5904bdbb, 0x08053a73), + TOBN(0x30fc1dd1, 0x101b6805), TOBN(0x43c223bc, 0x49aa6d49), + TOBN(0x9ed67141, 0x7a174087), TOBN(0x311469a0, 0xd5997008), + TOBN(0xb189b684, 0x5e43fc61), TOBN(0xf3282375, 0xe0d3ab57), + TOBN(0x4fa34b67, 0xb1181da8), TOBN(0x621ed0b2, 0x99ee52b8), + TOBN(0x9b178de1, 0xad990676), TOBN(0xd51de67b, 0x56d54065), + TOBN(0x2a2c27c4, 0x7538c201), TOBN(0x33856ec8, 0x38a40f5c), + TOBN(0x2522fc15, 0xbe6cdcde), TOBN(0x1e603f33, 0x9f0c6f89), + TOBN(0x7994edc3, 0x103e30a6), TOBN(0x033a00db, 0x220c853e), + TOBN(0xd3cfa409, 0xf7bb7fd7), TOBN(0x70f8781e, 0x462d18f6), + TOBN(0xbbd82980, 0x687fe295), TOBN(0x6eef4c32, 0x595669f3), + TOBN(0x86a9303b, 0x2f7e85c3), TOBN(0x5fce4621, 0x71988f9b), + TOBN(0x5b935bf6, 0xc138acb5), TOBN(0x30ea7d67, 0x25661212), + TOBN(0xef1eb5f4, 0xe51ab9a2), TOBN(0x0587c98a, 0xae067c78), + TOBN(0xb3ce1b3c, 0x77ca9ca6), TOBN(0x2a553d4d, 0x54b5f057), + TOBN(0xc7898236, 0x4da29ec2), TOBN(0xdbdd5d13, 0xb9c57316), + TOBN(0xc57d6e6b, 0x2cd80d47), TOBN(0x80b460cf, 0xfe9e7391), + TOBN(0x98648cab, 0xf963c31e), TOBN(0x67f9f633, 0xcc4d32fd), + TOBN(0x0af42a9d, 0xfdf7c687), TOBN(0x55f292a3, 0x0b015ea7), + TOBN(0x89e468b2, 0xcd21ab3d), TOBN(0xe504f022, 0xc393d392), + TOBN(0xab21e1d4, 0xa5013af9), TOBN(0xe3283f78, 0xc2c28acb), + TOBN(0xf38b35f6, 0x226bf99f), TOBN(0xe8354274, 0x0e291e69), + TOBN(0x61673a15, 0xb20c162d), TOBN(0xc101dc75, 0xb04fbdbe), + TOBN(0x8323b4c2, 0x255bd617), TOBN(0x6c969693, 0x6c2a9154), + TOBN(0xc6e65860, 0x62679387), TOBN(0x8e01db0c, 0xb8c88e23), + TOBN(0x33c42873, 0x893a5559), TOBN(0x7630f04b, 0x47a3e149), + TOBN(0xb5d80805, 0xddcf35f8), TOBN(0x582ca080, 0x77dfe732), + TOBN(0x2c7156e1, 0x0b1894a0), TOBN(0x92034001, 0xd81c68c0), + TOBN(0xed225d00, 0xc8b115b5), TOBN(0x237f9c22, 0x83b907f2), + TOBN(0x0ea2f32f, 0x4470e2c0), TOBN(0xb725f7c1, 0x58be4e95), + TOBN(0x0f1dcafa, 0xb1ae5463), TOBN(0x59ed5187, 0x1ba2fc04), + TOBN(0xf6e0f316, 0xd0115d4d), TOBN(0x5180b12f, 0xd3691599), + TOBN(0x157e32c9, 0x527f0a41), TOBN(0x7b0b081d, 0xa8e0ecc0), + TOBN(0x6dbaaa8a, 0xbf4f0dd0), TOBN(0x99b289c7, 0x4d252696), + TOBN(0x79b7755e, 0xdbf864fe), TOBN(0x6974e2b1, 0x76cad3ab), + TOBN(0x35dbbee2, 0x06ddd657), TOBN(0xe7cbdd11, 0x2ff3a96d), + TOBN(0x88381968, 0x076be758), TOBN(0x2d737e72, 0x08c91f5d), + TOBN(0x5f83ab62, 0x86ec3776), TOBN(0x98aa649d, 0x945fa7a1), + TOBN(0xf477ec37, 0x72ef0933), TOBN(0x66f52b1e, 0x098c17b1), + TOBN(0x9eec58fb, 0xd803738b), TOBN(0x91aaade7, 0xe4e86aa4), + TOBN(0x6b1ae617, 0xa5b51492), TOBN(0x63272121, 0xbbc45974), + TOBN(0x7e0e28f0, 0x862c5129), TOBN(0x0a8f79a9, 0x3321a4a0), + TOBN(0xe26d1664, 0x5041c88f), TOBN(0x0571b805, 0x53233e3a), + TOBN(0xd1b0ccde, 0xc9520711), TOBN(0x55a9e4ed, 0x3c8b84bf), + TOBN(0x9426bd39, 0xa1fef314), TOBN(0x4f5f638e, 0x6eb93f2b), + TOBN(0xba2a1ed3, 0x2bf9341b), TOBN(0xd63c1321, 0x4d42d5a9), + TOBN(0xd2964a89, 0x316dc7c5), TOBN(0xd1759606, 0xca511851), + TOBN(0xd8a9201f, 0xf9e6ed35), TOBN(0xb7b5ee45, 0x6736925a), + TOBN(0x0a83fbbc, 0x99581af7), TOBN(0x3076bc40, 0x64eeb051), + TOBN(0x5511c98c, 0x02dec312), TOBN(0x270de898, 0x238dcb78), + TOBN(0x2cf4cf9c, 0x539c08c9), TOBN(0xa70cb65e, 0x38d3b06e), + TOBN(0xb12ec10e, 0xcfe57bbd), TOBN(0x82c7b656, 0x35a0c2b5), + TOBN(0xddc7d5cd, 0x161c67bd), TOBN(0xe32e8985, 0xae3a32cc), + TOBN(0x7aba9444, 0xd11a5529), TOBN(0xe964ed02, 0x2427fa1a), + TOBN(0x1528392d, 0x24a1770a), TOBN(0xa152ce2c, 0x12c72fcd), + TOBN(0x714553a4, 0x8ec07649), TOBN(0x18b4c290, 0x459dd453), + TOBN(0xea32b714, 0x7b64b110), TOBN(0xb871bfa5, 0x2e6f07a2), + TOBN(0xb67112e5, 0x9e2e3c9b), TOBN(0xfbf250e5, 0x44aa90f6), + TOBN(0xf77aedb8, 0xbd539006), TOBN(0x3b0cdf9a, 0xd172a66f), + TOBN(0xedf69fea, 0xf8c51187), TOBN(0x05bb67ec, 0x741e4da7), + TOBN(0x47df0f32, 0x08114345), TOBN(0x56facb07, 0xbb9792b1), + TOBN(0xf3e007e9, 0x8f6229e4), TOBN(0x62d103f4, 0x526fba0f), + TOBN(0x4f33bef7, 0xb0339d79), TOBN(0x9841357b, 0xb59bfec1), + TOBN(0xfa8dbb59, 0xc34e6705), TOBN(0xc3c7180b, 0x7fdaa84c), + TOBN(0xf95872fc, 0xa4108537), TOBN(0x8750cc3b, 0x932a3e5a), + TOBN(0xb61cc69d, 0xb7275d7d), TOBN(0xffa0168b, 0x2e59b2e9), + TOBN(0xca032abc, 0x6ecbb493), TOBN(0x1d86dbd3, 0x2c9082d8), + TOBN(0xae1e0b67, 0xe28ef5ba), TOBN(0x2c9a4699, 0xcb18e169), + TOBN(0x0ecd0e33, 0x1e6bbd20), TOBN(0x571b360e, 0xaf5e81d2), + TOBN(0xcd9fea58, 0x101c1d45), TOBN(0x6651788e, 0x18880452), + TOBN(0xa9972635, 0x1f8dd446), TOBN(0x44bed022, 0xe37281d0), + TOBN(0x094b2b2d, 0x33da525d), TOBN(0xf193678e, 0x13144fd8), + TOBN(0xb8ab5ba4, 0xf4c1061d), TOBN(0x4343b5fa, 0xdccbe0f4), + TOBN(0xa8702371, 0x63812713), TOBN(0x47bf6d2d, 0xf7611d93), + TOBN(0x46729b8c, 0xbd21e1d7), TOBN(0x7484d4e0, 0xd629e77d), + TOBN(0x830e6eea, 0x60dbac1f), TOBN(0x23d8c484, 0xda06a2f7), + TOBN(0x896714b0, 0x50ca535b), TOBN(0xdc8d3644, 0xebd97a9b), + TOBN(0x106ef9fa, 0xb12177b4), TOBN(0xf79bf464, 0x534d5d9c), + TOBN(0x2537a349, 0xa6ab360b), TOBN(0xc7c54253, 0xa00c744f), + TOBN(0xb3c7a047, 0xe5911a76), TOBN(0x61ffa5c8, 0x647f1ee7), + TOBN(0x15aed36f, 0x8f56ab42), TOBN(0x6a0d41b0, 0xa3ff9ac9), + TOBN(0x68f469f5, 0xcc30d357), TOBN(0xbe9adf81, 0x6b72be96), + TOBN(0x1cd926fe, 0x903ad461), TOBN(0x7e89e38f, 0xcaca441b), + TOBN(0xf0f82de5, 0xfacf69d4), TOBN(0x363b7e76, 0x4775344c), + TOBN(0x6894f312, 0xb2e36d04), TOBN(0x3c6cb4fe, 0x11d1c9a5), + TOBN(0x85d9c339, 0x4008e1f2), TOBN(0x5e9a85ea, 0x249f326c), + TOBN(0xdc35c60a, 0x678c5e06), TOBN(0xc08b944f, 0x9f86fba9), + TOBN(0xde40c02c, 0x89f71f0f), TOBN(0xad8f3e31, 0xff3da3c0), + TOBN(0x3ea5096b, 0x42125ded), TOBN(0x13879cbf, 0xa7379183), + TOBN(0x6f4714a5, 0x6b306a0b), TOBN(0x359c2ea6, 0x67646c5e), + TOBN(0xfacf8943, 0x07726368), TOBN(0x07a58935, 0x65ff431e), + TOBN(0x24d661d1, 0x68754ab0), TOBN(0x801fce1d, 0x6f429a76), + TOBN(0xc068a85f, 0xa58ce769), TOBN(0xedc35c54, 0x5d5eca2b), + TOBN(0xea31276f, 0xa3f660d1), TOBN(0xa0184ebe, 0xb8fc7167), + TOBN(0x0f20f21a, 0x1d8db0ae), TOBN(0xd96d095f, 0x56c35e12), + TOBN(0xedf402b5, 0xf8c2a25b), TOBN(0x1bb772b9, 0x059204b6), + TOBN(0x50cbeae2, 0x19b4e34c), TOBN(0x93109d80, 0x3fa0845a), + TOBN(0x54f7ccf7, 0x8ef59fb5), TOBN(0x3b438fe2, 0x88070963), + TOBN(0x9e28c659, 0x31f3ba9b), TOBN(0x9cc31b46, 0xead9da92), + TOBN(0x3c2f0ba9, 0xb733aa5f), TOBN(0xdece47cb, 0xf05af235), + TOBN(0xf8e3f715, 0xa2ac82a5), TOBN(0xc97ba641, 0x2203f18a), + TOBN(0xc3af5504, 0x09c11060), TOBN(0x56ea2c05, 0x46af512d), + TOBN(0xfac28daf, 0xf3f28146), TOBN(0x87fab43a, 0x959ef494)}, + {TOBN(0x09891641, 0xd4c5105f), TOBN(0x1ae80f8e, 0x6d7fbd65), + TOBN(0x9d67225f, 0xbee6bdb0), TOBN(0x3b433b59, 0x7fc4d860), + TOBN(0x44e66db6, 0x93e85638), TOBN(0xf7b59252, 0xe3e9862f), + TOBN(0xdb785157, 0x665c32ec), TOBN(0x702fefd7, 0xae362f50), + TOBN(0x3754475d, 0x0fefb0c3), TOBN(0xd48fb56b, 0x46d7c35d), + TOBN(0xa070b633, 0x363798a4), TOBN(0xae89f3d2, 0x8fdb98e6), + TOBN(0x970b89c8, 0x6363d14c), TOBN(0x89817521, 0x67abd27d), + TOBN(0x9bf7d474, 0x44d5a021), TOBN(0xb3083baf, 0xcac72aee), + TOBN(0x389741de, 0xbe949a44), TOBN(0x638e9388, 0x546a4fa5), + TOBN(0x3fe6419c, 0xa0047bdc), TOBN(0x7047f648, 0xaaea57ca), + TOBN(0x54e48a90, 0x41fbab17), TOBN(0xda8e0b28, 0x576bdba2), + TOBN(0xe807eebc, 0xc72afddc), TOBN(0x07d3336d, 0xf42577bf), + TOBN(0x62a8c244, 0xbfe20925), TOBN(0x91c19ac3, 0x8fdce867), + TOBN(0x5a96a5d5, 0xdd387063), TOBN(0x61d587d4, 0x21d324f6), + TOBN(0xe87673a2, 0xa37173ea), TOBN(0x23848008, 0x53778b65), + TOBN(0x10f8441e, 0x05bab43e), TOBN(0xfa11fe12, 0x4621efbe), + TOBN(0x047b772e, 0x81685d7b), TOBN(0x23f27d81, 0xbf34a976), + TOBN(0xc27608e2, 0x915f48ef), TOBN(0x3b0b43fa, 0xa521d5c3), + TOBN(0x7613fb26, 0x63ca7284), TOBN(0x7f5729b4, 0x1d4db837), + TOBN(0x87b14898, 0x583b526b), TOBN(0x00b732a6, 0xbbadd3d1), + TOBN(0x8e02f426, 0x2048e396), TOBN(0x436b50b6, 0x383d9de4), + TOBN(0xf78d3481, 0x471e85ad), TOBN(0x8b01ea6a, 0xd005c8d6), + TOBN(0xd3c7afee, 0x97015c07), TOBN(0x46cdf1a9, 0x4e3ba2ae), + TOBN(0x7a42e501, 0x83d3a1d2), TOBN(0xd54b5268, 0xb541dff4), + TOBN(0x3f24cf30, 0x4e23e9bc), TOBN(0x4387f816, 0x126e3624), + TOBN(0x26a46a03, 0x3b0b6d61), TOBN(0xaf1bc845, 0x8b2d777c), + TOBN(0x25c401ba, 0x527de79c), TOBN(0x0e1346d4, 0x4261bbb6), + TOBN(0x4b96c44b, 0x287b4bc7), TOBN(0x658493c7, 0x5254562f), + TOBN(0x23f949fe, 0xb8a24a20), TOBN(0x17ebfed1, 0xf52ca53f), + TOBN(0x9b691bbe, 0xbcfb4853), TOBN(0x5617ff6b, 0x6278a05d), + TOBN(0x241b34c5, 0xe3c99ebd), TOBN(0xfc64242e, 0x1784156a), + TOBN(0x4206482f, 0x695d67df), TOBN(0xb967ce0e, 0xee27c011), + TOBN(0x65db3751, 0x21c80b5d), TOBN(0x2e7a563c, 0xa31ecca0), + TOBN(0xe56ffc4e, 0x5238a07e), TOBN(0x3d6c2966, 0x32ced854), + TOBN(0xe99d7d1a, 0xaf70b885), TOBN(0xafc3bad9, 0x2d686459), + TOBN(0x9c78bf46, 0x0cc8ba5b), TOBN(0x5a439519, 0x18955aa3), + TOBN(0xf8b517a8, 0x5fe4e314), TOBN(0xe60234d0, 0xfcb8906f), + TOBN(0xffe542ac, 0xf2061b23), TOBN(0x287e191f, 0x6b4cb59c), + TOBN(0x21857ddc, 0x09d877d8), TOBN(0x1c23478c, 0x14678941), + TOBN(0xbbf0c056, 0xb6e05ea4), TOBN(0x82da4b53, 0xb01594fe), + TOBN(0xf7526791, 0xfadb8608), TOBN(0x049e832d, 0x7b74cdf6), + TOBN(0xa43581cc, 0xc2b90a34), TOBN(0x73639eb8, 0x9360b10c), + TOBN(0x4fba331f, 0xe1e4a71b), TOBN(0x6ffd6b93, 0x8072f919), + TOBN(0x6e53271c, 0x65679032), TOBN(0x67206444, 0xf14272ce), + TOBN(0xc0f734a3, 0xb2335834), TOBN(0x9526205a, 0x90ef6860), + TOBN(0xcb8be717, 0x04e2bb0d), TOBN(0x2418871e, 0x02f383fa), + TOBN(0xd7177681, 0x4082c157), TOBN(0xcc914ad0, 0x29c20073), + TOBN(0xf186c1eb, 0xe587e728), TOBN(0x6fdb3c22, 0x61bcd5fd), + TOBN(0x30d014a6, 0xf2f9f8e9), TOBN(0x963ece23, 0x4fec49d2), + TOBN(0x862025c5, 0x9605a8d9), TOBN(0x39874445, 0x19f8929a), + TOBN(0x01b6ff65, 0x12bf476a), TOBN(0x598a64d8, 0x09cf7d91), + TOBN(0xd7ec7749, 0x93be56ca), TOBN(0x10899785, 0xcbb33615), + TOBN(0xb8a092fd, 0x02eee3ad), TOBN(0xa86b3d35, 0x30145270), + TOBN(0x323d98c6, 0x8512b675), TOBN(0x4b8bc785, 0x62ebb40f), + TOBN(0x7d301f54, 0x413f9cde), TOBN(0xa5e4fb4f, 0x2bab5664), + TOBN(0x1d2b252d, 0x1cbfec23), TOBN(0xfcd576bb, 0xe177120d), + TOBN(0x04427d3e, 0x83731a34), TOBN(0x2bb9028e, 0xed836e8e), + TOBN(0xb36acff8, 0xb612ca7c), TOBN(0xb88fe5ef, 0xd3d9c73a), + TOBN(0xbe2a6bc6, 0xedea4eb3), TOBN(0x43b93133, 0x488eec77), + TOBN(0xf41ff566, 0xb17106e1), TOBN(0x469e9172, 0x654efa32), + TOBN(0xb4480f04, 0x41c23fa3), TOBN(0xb4712eb0, 0xc1989a2e), + TOBN(0x3ccbba0f, 0x93a29ca7), TOBN(0x6e205c14, 0xd619428c), + TOBN(0x90db7957, 0xb3641686), TOBN(0x0432691d, 0x45ac8b4e), + TOBN(0x07a759ac, 0xf64e0350), TOBN(0x0514d89c, 0x9c972517), + TOBN(0x1701147f, 0xa8e67fc3), TOBN(0x9e2e0b8b, 0xab2085be), + TOBN(0xd5651824, 0xac284e57), TOBN(0x890d4325, 0x74893664), + TOBN(0x8a7c5e6e, 0xc55e68a3), TOBN(0xbf12e90b, 0x4339c85a), + TOBN(0x31846b85, 0xf922b655), TOBN(0x9a54ce4d, 0x0bf4d700), + TOBN(0xd7f4e83a, 0xf1a14295), TOBN(0x916f955c, 0xb285d4f9), + TOBN(0xe57bb0e0, 0x99ffdaba), TOBN(0x28a43034, 0xeab0d152), + TOBN(0x0a36ffa2, 0xb8a9cef8), TOBN(0x5517407e, 0xb9ec051a), + TOBN(0x9c796096, 0xea68e672), TOBN(0x853db5fb, 0xfb3c77fb), + TOBN(0x21474ba9, 0xe864a51a), TOBN(0x6c267699, 0x6e8a1b8b), + TOBN(0x7c823626, 0x94120a28), TOBN(0xe61e9a48, 0x8383a5db), + TOBN(0x7dd75003, 0x9f84216d), TOBN(0xab020d07, 0xad43cd85), + TOBN(0x9437ae48, 0xda12c659), TOBN(0x6449c2eb, 0xe65452ad), + TOBN(0xcc7c4c1c, 0x2cf9d7c1), TOBN(0x1320886a, 0xee95e5ab), + TOBN(0xbb7b9056, 0xbeae170c), TOBN(0xc8a5b250, 0xdbc0d662), + TOBN(0x4ed81432, 0xc11d2303), TOBN(0x7da66912, 0x1f03769f), + TOBN(0x3ac7a5fd, 0x84539828), TOBN(0x14dada94, 0x3bccdd02), + TOBN(0x8b84c321, 0x7ef6b0d1), TOBN(0x52a9477a, 0x7c933f22), + TOBN(0x5ef6728a, 0xfd440b82), TOBN(0x5c3bd859, 0x6ce4bd5e), + TOBN(0x918b80f5, 0xf22c2d3e), TOBN(0x368d5040, 0xb7bb6cc5), + TOBN(0xb66142a1, 0x2695a11c), TOBN(0x60ac583a, 0xeb19ea70), + TOBN(0x317cbb98, 0x0eab2437), TOBN(0x8cc08c55, 0x5e2654c8), + TOBN(0xfe2d6520, 0xe6d8307f), TOBN(0xe9f147f3, 0x57428993), + TOBN(0x5f9c7d14, 0xd2fd6cf1), TOBN(0xa3ecd064, 0x2d4fcbb0), + TOBN(0xad83fef0, 0x8e7341f7), TOBN(0x643f23a0, 0x3a63115c), + TOBN(0xd38a78ab, 0xe65ab743), TOBN(0xbf7c75b1, 0x35edc89c), + TOBN(0x3dd8752e, 0x530df568), TOBN(0xf85c4a76, 0xe308c682), + TOBN(0x4c9955b2, 0xe68acf37), TOBN(0xa544df3d, 0xab32af85), + TOBN(0x4b8ec3f5, 0xa25cf493), TOBN(0x4d8f2764, 0x1a622feb), + TOBN(0x7bb4f7aa, 0xf0dcbc49), TOBN(0x7de551f9, 0x70bbb45b), + TOBN(0xcfd0f3e4, 0x9f2ca2e5), TOBN(0xece58709, 0x1f5c76ef), + TOBN(0x32920edd, 0x167d79ae), TOBN(0x039df8a2, 0xfa7d7ec1), + TOBN(0xf46206c0, 0xbb30af91), TOBN(0x1ff5e2f5, 0x22676b59), + TOBN(0x11f4a039, 0x6ea51d66), TOBN(0x506c1445, 0x807d7a26), + TOBN(0x60da5705, 0x755a9b24), TOBN(0x8fc8cc32, 0x1f1a319e), + TOBN(0x83642d4d, 0x9433d67d), TOBN(0x7fa5cb8f, 0x6a7dd296), + TOBN(0x576591db, 0x9b7bde07), TOBN(0x13173d25, 0x419716fb), + TOBN(0xea30599d, 0xd5b340ff), TOBN(0xfc6b5297, 0xb0fe76c5), + TOBN(0x1c6968c8, 0xab8f5adc), TOBN(0xf723c7f5, 0x901c928d), + TOBN(0x4203c321, 0x9773d402), TOBN(0xdf7c6aa3, 0x1b51dd47), + TOBN(0x3d49e37a, 0x552be23c), TOBN(0x57febee8, 0x0b5a6e87), + TOBN(0xc5ecbee4, 0x7bd8e739), TOBN(0x79d44994, 0xae63bf75), + TOBN(0x168bd00f, 0x38fb8923), TOBN(0x75d48ee4, 0xd0533130), + TOBN(0x554f77aa, 0xdb5cdf33), TOBN(0x3396e896, 0x3c696769), + TOBN(0x2fdddbf2, 0xd3fd674e), TOBN(0xbbb8f6ee, 0x99d0e3e5), + TOBN(0x51b90651, 0xcbae2f70), TOBN(0xefc4bc05, 0x93aaa8eb), + TOBN(0x8ecd8689, 0xdd1df499), TOBN(0x1aee99a8, 0x22f367a5), + TOBN(0x95d485b9, 0xae8274c5), TOBN(0x6c14d445, 0x7d30b39c), + TOBN(0xbafea90b, 0xbcc1ef81), TOBN(0x7c5f317a, 0xa459a2ed), + TOBN(0x01211075, 0x4ef44227), TOBN(0xa17bed6e, 0xdc20f496), + TOBN(0x0cdfe424, 0x819853cd), TOBN(0x13793298, 0xf71e2ce7), + TOBN(0x3c1f3078, 0xdbbe307b), TOBN(0x6dd1c20e, 0x76ee9936), + TOBN(0x23ee4b57, 0x423caa20), TOBN(0x4ac3793b, 0x8efb840e), + TOBN(0x934438eb, 0xed1f8ca0), TOBN(0x3e546658, 0x4ebb25a2), + TOBN(0xc415af0e, 0xc069896f), TOBN(0xc13eddb0, 0x9a5aa43d), + TOBN(0x7a04204f, 0xd49eb8f6), TOBN(0xd0d5bdfc, 0xd74f1670), + TOBN(0x3697e286, 0x56fc0558), TOBN(0x10207371, 0x01cebade), + TOBN(0x5f87e690, 0x0647a82b), TOBN(0x908e0ed4, 0x8f40054f), + TOBN(0xa9f633d4, 0x79853803), TOBN(0x8ed13c9a, 0x4a28b252), + TOBN(0x3e2ef676, 0x1f460f64), TOBN(0x53930b9b, 0x36d06336), + TOBN(0x347073ac, 0x8fc4979b), TOBN(0x84380e0e, 0x5ecd5597), + TOBN(0xe3b22c6b, 0xc4fe3c39), TOBN(0xba4a8153, 0x6c7bebdf), + TOBN(0xf23ab6b7, 0x25693459), TOBN(0x53bc3770, 0x14922b11), + TOBN(0x4645c8ab, 0x5afc60db), TOBN(0xaa022355, 0x20b9f2a3), + TOBN(0x52a2954c, 0xce0fc507), TOBN(0x8c2731bb, 0x7ce1c2e7), + TOBN(0xf39608ab, 0x18a0339d), TOBN(0xac7a658d, 0x3735436c), + TOBN(0xb22c2b07, 0xcd992b4f), TOBN(0x4e83daec, 0xf40dcfd4), + TOBN(0x8a34c7be, 0x2f39ea3e), TOBN(0xef0c005f, 0xb0a56d2e), + TOBN(0x62731f6a, 0x6edd8038), TOBN(0x5721d740, 0x4e3cb075), + TOBN(0x1ea41511, 0xfbeeee1b), TOBN(0xd1ef5e73, 0xef1d0c05), + TOBN(0x42feefd1, 0x73c07d35), TOBN(0xe530a00a, 0x8a329493), + TOBN(0x5d55b7fe, 0xf15ebfb0), TOBN(0x549de03c, 0xd322491a), + TOBN(0xf7b5f602, 0x745b3237), TOBN(0x3632a3a2, 0x1ab6e2b6), + TOBN(0x0d3bba89, 0x0ef59f78), TOBN(0x0dfc6443, 0xc9e52b9a), + TOBN(0x1dc79699, 0x72631447), TOBN(0xef033917, 0xb3be20b1), + TOBN(0x0c92735d, 0xb1383948), TOBN(0xc1fc29a2, 0xc0dd7d7d), + TOBN(0x6485b697, 0x403ed068), TOBN(0x13bfaab3, 0xaac93bdc), + TOBN(0x410dc6a9, 0x0deeaf52), TOBN(0xb003fb02, 0x4c641c15), + TOBN(0x1384978c, 0x5bc504c4), TOBN(0x37640487, 0x864a6a77), + TOBN(0x05991bc6, 0x222a77da), TOBN(0x62260a57, 0x5e47eb11), + TOBN(0xc7af6613, 0xf21b432c), TOBN(0x22f3acc9, 0xab4953e9), + TOBN(0x52934922, 0x8e41d155), TOBN(0x4d024568, 0x3ac059ef), + TOBN(0xb0201755, 0x4d884411), TOBN(0xce8055cf, 0xa59a178f), + TOBN(0xcd77d1af, 0xf6204549), TOBN(0xa0a00a3e, 0xc7066759), + TOBN(0x471071ef, 0x0272c229), TOBN(0x009bcf6b, 0xd3c4b6b0), + TOBN(0x2a2638a8, 0x22305177), TOBN(0xd51d59df, 0x41645bbf), + TOBN(0xa81142fd, 0xc0a7a3c0), TOBN(0xa17eca6d, 0x4c7063ee), + TOBN(0x0bb887ed, 0x60d9dcec), TOBN(0xd6d28e51, 0x20ad2455), + TOBN(0xebed6308, 0xa67102ba), TOBN(0x042c3114, 0x8bffa408), + TOBN(0xfd099ac5, 0x8aa68e30), TOBN(0x7a6a3d7c, 0x1483513e), + TOBN(0xffcc6b75, 0xba2d8f0c), TOBN(0x54dacf96, 0x1e78b954), + TOBN(0xf645696f, 0xa4a9af89), TOBN(0x3a411940, 0x06ac98ec), + TOBN(0x41b8b3f6, 0x22a67a20), TOBN(0x2d0b1e0f, 0x99dec626), + TOBN(0x27c89192, 0x40be34e8), TOBN(0xc7162b37, 0x91907f35), + TOBN(0x90188ec1, 0xa956702b), TOBN(0xca132f7d, 0xdf93769c), + TOBN(0x3ece44f9, 0x0e2025b4), TOBN(0x67aaec69, 0x0c62f14c), + TOBN(0xad741418, 0x22e3cc11), TOBN(0xcf9b75c3, 0x7ff9a50e), + TOBN(0x02fa2b16, 0x4d348272), TOBN(0xbd99d61a, 0x9959d56d), + TOBN(0xbc4f19db, 0x18762916), TOBN(0xcc7cce50, 0x49c1ac80), + TOBN(0x4d59ebaa, 0xd846bd83), TOBN(0x8775a9dc, 0xa9202849), + TOBN(0x07ec4ae1, 0x6e1f4ca9), TOBN(0x27eb5875, 0xba893f11), + TOBN(0x00284d51, 0x662cc565), TOBN(0x82353a6b, 0x0db4138d), + TOBN(0xd9c7aaaa, 0xaa32a594), TOBN(0xf5528b5e, 0xa5669c47), + TOBN(0xf3220231, 0x2f23c5ff), TOBN(0xe3e8147a, 0x6affa3a1), + TOBN(0xfb423d5c, 0x202ddda0), TOBN(0x3d6414ac, 0x6b871bd4), + TOBN(0x586f82e1, 0xa51a168a), TOBN(0xb712c671, 0x48ae5448), + TOBN(0x9a2e4bd1, 0x76233eb8), TOBN(0x0188223a, 0x78811ca9), + TOBN(0x553c5e21, 0xf7c18de1), TOBN(0x7682e451, 0xb27bb286), + TOBN(0x3ed036b3, 0x0e51e929), TOBN(0xf487211b, 0xec9cb34f), + TOBN(0x0d094277, 0x0c24efc8), TOBN(0x0349fd04, 0xbef737a4), + TOBN(0x6d1c9dd2, 0x514cdd28), TOBN(0x29c135ff, 0x30da9521), + TOBN(0xea6e4508, 0xf78b0b6f), TOBN(0x176f5dd2, 0x678c143c), + TOBN(0x08148418, 0x4be21e65), TOBN(0x27f7525c, 0xe7df38c4), + TOBN(0x1fb70e09, 0x748ab1a4), TOBN(0x9cba50a0, 0x5efe4433), + TOBN(0x7846c7a6, 0x15f75af2), TOBN(0x2a7c2c57, 0x5ee73ea8), + TOBN(0x42e566a4, 0x3f0a449a), TOBN(0x45474c3b, 0xad90fc3d), + TOBN(0x7447be3d, 0x8b61d057), TOBN(0x3e9d1cf1, 0x3a4ec092), + TOBN(0x1603e453, 0xf380a6e6), TOBN(0x0b86e431, 0x9b1437c2), + TOBN(0x7a4173f2, 0xef29610a), TOBN(0x8fa729a7, 0xf03d57f7), + TOBN(0x3e186f6e, 0x6c9c217e), TOBN(0xbe1d3079, 0x91919524), + TOBN(0x92a62a70, 0x153d4fb1), TOBN(0x32ed3e34, 0xd68c2f71), + TOBN(0xd785027f, 0x9eb1a8b7), TOBN(0xbc37eb77, 0xc5b22fe8), + TOBN(0x466b34f0, 0xb9d6a191), TOBN(0x008a89af, 0x9a05f816), + TOBN(0x19b028fb, 0x7d42c10a), TOBN(0x7fe8c92f, 0x49b3f6b8), + TOBN(0x58907cc0, 0xa5a0ade3), TOBN(0xb3154f51, 0x559d1a7c), + TOBN(0x5066efb6, 0xd9790ed6), TOBN(0xa77a0cbc, 0xa6aa793b), + TOBN(0x1a915f3c, 0x223e042e), TOBN(0x1c5def04, 0x69c5874b), + TOBN(0x0e830078, 0x73b6c1da), TOBN(0x55cf85d2, 0xfcd8557a), + TOBN(0x0f7c7c76, 0x0460f3b1), TOBN(0x87052acb, 0x46e58063), + TOBN(0x09212b80, 0x907eae66), TOBN(0x3cb068e0, 0x4d721c89), + TOBN(0xa87941ae, 0xdd45ac1c), TOBN(0xde8d5c0d, 0x0daa0dbb), + TOBN(0xda421fdc, 0xe3502e6e), TOBN(0xc8944201, 0x4d89a084), + TOBN(0x7307ba5e, 0xf0c24bfb), TOBN(0xda212beb, 0x20bde0ef), + TOBN(0xea2da24b, 0xf82ce682), TOBN(0x058d3816, 0x07f71fe4), + TOBN(0x35a02462, 0x5ffad8de), TOBN(0xcd7b05dc, 0xaadcefab), + TOBN(0xd442f8ed, 0x1d9f54ec), TOBN(0x8be3d618, 0xb2d3b5ca), + TOBN(0xe2220ed0, 0xe06b2ce2), TOBN(0x82699a5f, 0x1b0da4c0), + TOBN(0x3ff106f5, 0x71c0c3a7), TOBN(0x8f580f5a, 0x0d34180c), + TOBN(0x4ebb120e, 0x22d7d375), TOBN(0x5e5782cc, 0xe9513675), + TOBN(0x2275580c, 0x99c82a70), TOBN(0xe8359fbf, 0x15ea8c4c), + TOBN(0x53b48db8, 0x7b415e70), TOBN(0xaacf2240, 0x100c6014), + TOBN(0x9faaccf5, 0xe4652f1d), TOBN(0xbd6fdd2a, 0xd56157b2), + TOBN(0xa4f4fb1f, 0x6261ec50), TOBN(0x244e55ad, 0x476bcd52), + TOBN(0x881c9305, 0x047d320b), TOBN(0x1ca983d5, 0x6181263f), + TOBN(0x354e9a44, 0x278fb8ee), TOBN(0xad2dbc0f, 0x396e4964), + TOBN(0x723f3aa2, 0x9268b3de), TOBN(0x0d1ca29a, 0xe6e0609a), + TOBN(0x794866aa, 0x6cf44252), TOBN(0x0b59f3e3, 0x01af87ed), + TOBN(0xe234e5ff, 0x7f4a6c51), TOBN(0xa8768fd2, 0x61dc2f7e), + TOBN(0xdafc7332, 0x0a94d81f), TOBN(0xd7f84282, 0x06938ce1), + TOBN(0xae0b3c0e, 0x0546063e), TOBN(0x7fbadcb2, 0x5d61abc6), + TOBN(0xd5d7a2c9, 0x369ac400), TOBN(0xa5978d09, 0xae67d10c), + TOBN(0x290f211e, 0x4f85eaac), TOBN(0xe61e2ad1, 0xfacac681), + TOBN(0xae125225, 0x388384cd), TOBN(0xa7fb68e9, 0xccfde30f), + TOBN(0x7a59b936, 0x3daed4c2), TOBN(0x80a9aa40, 0x2606f789), + TOBN(0xb40c1ea5, 0xf6a6d90a), TOBN(0x948364d3, 0x514d5885), + TOBN(0x062ebc60, 0x70985182), TOBN(0xa6db5b0e, 0x33310895), + TOBN(0x64a12175, 0xe329c2f5), TOBN(0xc5f25bd2, 0x90ea237e), + TOBN(0x7915c524, 0x2d0a4c23), TOBN(0xeb5d26e4, 0x6bb3cc52), + TOBN(0x369a9116, 0xc09e2c92), TOBN(0x0c527f92, 0xcf182cf8), + TOBN(0x9e591938, 0x2aede0ac), TOBN(0xb2922208, 0x6cc34939), + TOBN(0x3c9d8962, 0x99a34361), TOBN(0x3c81836d, 0xc1905fe6), + TOBN(0x4bfeb57f, 0xa001ec5a), TOBN(0xe993f5bb, 0xa0dc5dba), + TOBN(0x47884109, 0x724a1380), TOBN(0x8a0369ab, 0x32fe9a04), + TOBN(0xea068d60, 0x8c927db8), TOBN(0xbf5f37cf, 0x94655741), + TOBN(0x47d402a2, 0x04b6c7ea), TOBN(0x4551c295, 0x6af259cb), + TOBN(0x698b71e7, 0xed77ee8b), TOBN(0xbddf7bd0, 0xf309d5c7), + TOBN(0x6201c22c, 0x34e780ca), TOBN(0xab04f7d8, 0x4c295ef4), + TOBN(0x1c947294, 0x4313a8ce), TOBN(0xe532e4ac, 0x92ca4cfe), + TOBN(0x89738f80, 0xd0a7a97a), TOBN(0xec088c88, 0xa580fd5b), + TOBN(0x612b1ecc, 0x42ce9e51), TOBN(0x8f9840fd, 0xb25fdd2a), + TOBN(0x3cda78c0, 0x01e7f839), TOBN(0x546b3d3a, 0xece05480), + TOBN(0x271719a9, 0x80d30916), TOBN(0x45497107, 0x584c20c4), + TOBN(0xaf8f9478, 0x5bc78608), TOBN(0x28c7d484, 0x277e2a4c), + TOBN(0xfce01767, 0x88a2ffe4), TOBN(0xdc506a35, 0x28e169a5), + TOBN(0x0ea10861, 0x7af9c93a), TOBN(0x1ed24361, 0x03fa0e08), + TOBN(0x96eaaa92, 0xa3d694e7), TOBN(0xc0f43b4d, 0xef50bc74), + TOBN(0xce6aa58c, 0x64114db4), TOBN(0x8218e8ea, 0x7c000fd4), + TOBN(0xac815dfb, 0x185f8844), TOBN(0xcd7e90cb, 0x1557abfb), + TOBN(0x23d16655, 0xafbfecdf), TOBN(0x80f3271f, 0x085cac4a), + TOBN(0x7fc39aa7, 0xd0e62f47), TOBN(0x88d519d1, 0x460a48e5), + TOBN(0x59559ac4, 0xd28f101e), TOBN(0x7981d9e9, 0xca9ae816), + TOBN(0x5c38652c, 0x9ac38203), TOBN(0x86eaf87f, 0x57657fe5), + TOBN(0x568fc472, 0xe21f5416), TOBN(0x2afff39c, 0xe7e597b5), + TOBN(0x3adbbb07, 0x256d4eab), TOBN(0x22598692, 0x8285ab89), + TOBN(0x35f8112a, 0x041caefe), TOBN(0x95df02e3, 0xa5064c8b), + TOBN(0x4d63356e, 0xc7004bf3), TOBN(0x230a08f4, 0xdb83c7de), + TOBN(0xca27b270, 0x8709a7b7), TOBN(0x0d1c4cc4, 0xcb9abd2d), + TOBN(0x8a0bc66e, 0x7550fee8), TOBN(0x369cd4c7, 0x9cf7247e), + TOBN(0x75562e84, 0x92b5b7e7), TOBN(0x8fed0da0, 0x5802af7b), + TOBN(0x6a7091c2, 0xe48fb889), TOBN(0x26882c13, 0x7b8a9d06), + TOBN(0xa2498663, 0x1b82a0e2), TOBN(0x844ed736, 0x3518152d), + TOBN(0x282f476f, 0xd86e27c7), TOBN(0xa04edaca, 0x04afefdc), + TOBN(0x8b256ebc, 0x6119e34d), TOBN(0x56a413e9, 0x0787d78b)}, + {TOBN(0x82ee061d, 0x5a74be50), TOBN(0xe41781c4, 0xdea16ff5), + TOBN(0xe0b0c81e, 0x99bfc8a2), TOBN(0x624f4d69, 0x0b547e2d), + TOBN(0x3a83545d, 0xbdcc9ae4), TOBN(0x2573dbb6, 0x409b1e8e), + TOBN(0x482960c4, 0xa6c93539), TOBN(0xf01059ad, 0x5ae18798), + TOBN(0x715c9f97, 0x3112795f), TOBN(0xe8244437, 0x984e6ee1), + TOBN(0x55cb4858, 0xecb66bcd), TOBN(0x7c136735, 0xabaffbee), + TOBN(0x54661595, 0x5dbec38e), TOBN(0x51c0782c, 0x388ad153), + TOBN(0x9ba4c53a, 0xc6e0952f), TOBN(0x27e6782a, 0x1b21dfa8), + TOBN(0x682f903d, 0x4ed2dbc2), TOBN(0x0eba59c8, 0x7c3b2d83), + TOBN(0x8e9dc84d, 0x9c7e9335), TOBN(0x5f9b21b0, 0x0eb226d7), + TOBN(0xe33bd394, 0xaf267bae), TOBN(0xaa86cc25, 0xbe2e15ae), + TOBN(0x4f0bf67d, 0x6a8ec500), TOBN(0x5846aa44, 0xf9630658), + TOBN(0xfeb09740, 0xe2c2bf15), TOBN(0x627a2205, 0xa9e99704), + TOBN(0xec8d73d0, 0xc2fbc565), TOBN(0x223eed8f, 0xc20c8de8), + TOBN(0x1ee32583, 0xa8363b49), TOBN(0x1a0b6cb9, 0xc9c2b0a6), + TOBN(0x49f7c3d2, 0x90dbc85c), TOBN(0xa8dfbb97, 0x1ef4c1ac), + TOBN(0xafb34d4c, 0x65c7c2ab), TOBN(0x1d4610e7, 0xe2c5ea84), + TOBN(0x893f6d1b, 0x973c4ab5), TOBN(0xa3cdd7e9, 0x945ba5c4), + TOBN(0x60514983, 0x064417ee), TOBN(0x1459b23c, 0xad6bdf2b), + TOBN(0x23b2c341, 0x5cf726c3), TOBN(0x3a829635, 0x32d6354a), + TOBN(0x294f901f, 0xab192c18), TOBN(0xec5fcbfe, 0x7030164f), + TOBN(0xe2e2fcb7, 0xe2246ba6), TOBN(0x1e7c88b3, 0x221a1a0c), + TOBN(0x72c7dd93, 0xc92d88c5), TOBN(0x41c2148e, 0x1106fb59), + TOBN(0x547dd4f5, 0xa0f60f14), TOBN(0xed9b52b2, 0x63960f31), + TOBN(0x6c8349eb, 0xb0a5b358), TOBN(0xb154c5c2, 0x9e7e2ed6), + TOBN(0xcad5eccf, 0xeda462db), TOBN(0xf2d6dbe4, 0x2de66b69), + TOBN(0x426aedf3, 0x8665e5b2), TOBN(0x488a8513, 0x7b7f5723), + TOBN(0x15cc43b3, 0x8bcbb386), TOBN(0x27ad0af3, 0xd791d879), + TOBN(0xc16c236e, 0x846e364f), TOBN(0x7f33527c, 0xdea50ca0), + TOBN(0xc4810775, 0x0926b86d), TOBN(0x6c2a3609, 0x0598e70c), + TOBN(0xa6755e52, 0xf024e924), TOBN(0xe0fa07a4, 0x9db4afca), + TOBN(0x15c3ce7d, 0x66831790), TOBN(0x5b4ef350, 0xa6cbb0d6), + TOBN(0x2c4aafc4, 0xb6205969), TOBN(0x42563f02, 0xf6c7854f), + TOBN(0x016aced5, 0x1d983b48), TOBN(0xfeb356d8, 0x99949755), + TOBN(0x8c2a2c81, 0xd1a39bd7), TOBN(0x8f44340f, 0xe6934ae9), + TOBN(0x148cf91c, 0x447904da), TOBN(0x7340185f, 0x0f51a926), + TOBN(0x2f8f00fb, 0x7409ab46), TOBN(0x057e78e6, 0x80e289b2), + TOBN(0x03e5022c, 0xa888e5d1), TOBN(0x3c87111a, 0x9dede4e2), + TOBN(0x5b9b0e1c, 0x7809460b), TOBN(0xe751c852, 0x71c9abc7), + TOBN(0x8b944e28, 0xc7cc1dc9), TOBN(0x4f201ffa, 0x1d3cfa08), + TOBN(0x02fc905c, 0x3e6721ce), TOBN(0xd52d70da, 0xd0b3674c), + TOBN(0x5dc2e5ca, 0x18810da4), TOBN(0xa984b273, 0x5c69dd99), + TOBN(0x63b92527, 0x84de5ca4), TOBN(0x2f1c9872, 0xc852dec4), + TOBN(0x18b03593, 0xc2e3de09), TOBN(0x19d70b01, 0x9813dc2f), + TOBN(0x42806b2d, 0xa6dc1d29), TOBN(0xd3030009, 0xf871e144), + TOBN(0xa1feb333, 0xaaf49276), TOBN(0xb5583b9e, 0xc70bc04b), + TOBN(0x1db0be78, 0x95695f20), TOBN(0xfc841811, 0x89d012b5), + TOBN(0x6409f272, 0x05f61643), TOBN(0x40d34174, 0xd5883128), + TOBN(0xd79196f5, 0x67419833), TOBN(0x6059e252, 0x863b7b08), + TOBN(0x84da1817, 0x1c56700c), TOBN(0x5758ee56, 0xb28d3ec4), + TOBN(0x7da2771d, 0x013b0ea6), TOBN(0xfddf524b, 0x54c5e9b9), + TOBN(0x7df4faf8, 0x24305d80), TOBN(0x58f5c1bf, 0x3a97763f), + TOBN(0xa5af37f1, 0x7c696042), TOBN(0xd4cba22c, 0x4a2538de), + TOBN(0x211cb995, 0x9ea42600), TOBN(0xcd105f41, 0x7b069889), + TOBN(0xb1e1cf19, 0xddb81e74), TOBN(0x472f2d89, 0x5157b8ca), + TOBN(0x086fb008, 0xee9db885), TOBN(0x365cd570, 0x0f26d131), + TOBN(0x284b02bb, 0xa2be7053), TOBN(0xdcbbf7c6, 0x7ab9a6d6), + TOBN(0x4425559c, 0x20f7a530), TOBN(0x961f2dfa, 0x188767c8), + TOBN(0xe2fd9435, 0x70dc80c4), TOBN(0x104d6b63, 0xf0784120), + TOBN(0x7f592bc1, 0x53567122), TOBN(0xf6bc1246, 0xf688ad77), + TOBN(0x05214c05, 0x0f15dde9), TOBN(0xa47a76a8, 0x0d5f2b82), + TOBN(0xbb254d30, 0x62e82b62), TOBN(0x11a05fe0, 0x3ec955ee), + TOBN(0x7eaff46e, 0x9d529b36), TOBN(0x55ab1301, 0x8f9e3df6), + TOBN(0xc463e371, 0x99317698), TOBN(0xfd251438, 0xccda47ad), + TOBN(0xca9c3547, 0x23d695ea), TOBN(0x48ce626e, 0x16e589b5), + TOBN(0x6b5b64c7, 0xb187d086), TOBN(0xd02e1794, 0xb2207948), + TOBN(0x8b58e98f, 0x7198111d), TOBN(0x90ca6305, 0xdcf9c3cc), + TOBN(0x5691fe72, 0xf34089b0), TOBN(0x60941af1, 0xfc7c80ff), + TOBN(0xa09bc0a2, 0x22eb51e5), TOBN(0xc0bb7244, 0xaa9cf09a), + TOBN(0x36a8077f, 0x80159f06), TOBN(0x8b5c989e, 0xdddc560e), + TOBN(0x19d2f316, 0x512e1f43), TOBN(0x02eac554, 0xad08ff62), + TOBN(0x012ab84c, 0x07d20b4e), TOBN(0x37d1e115, 0xd6d4e4e1), + TOBN(0xb6443e1a, 0xab7b19a8), TOBN(0xf08d067e, 0xdef8cd45), + TOBN(0x63adf3e9, 0x685e03da), TOBN(0xcf15a10e, 0x4792b916), + TOBN(0xf44bcce5, 0xb738a425), TOBN(0xebe131d5, 0x9636b2fd), + TOBN(0x94068841, 0x7850d605), TOBN(0x09684eaa, 0xb40d749d), + TOBN(0x8c3c669c, 0x72ba075b), TOBN(0x89f78b55, 0xba469015), + TOBN(0x5706aade, 0x3e9f8ba8), TOBN(0x6d8bd565, 0xb32d7ed7), + TOBN(0x25f4e63b, 0x805f08d6), TOBN(0x7f48200d, 0xc3bcc1b5), + TOBN(0x4e801968, 0xb025d847), TOBN(0x74afac04, 0x87cbe0a8), + TOBN(0x43ed2c2b, 0x7e63d690), TOBN(0xefb6bbf0, 0x0223cdb8), + TOBN(0x4fec3cae, 0x2884d3fe), TOBN(0x065ecce6, 0xd75e25a4), + TOBN(0x6c2294ce, 0x69f79071), TOBN(0x0d9a8e5f, 0x044b8666), + TOBN(0x5009f238, 0x17b69d8f), TOBN(0x3c29f8fe, 0xc5dfdaf7), + TOBN(0x9067528f, 0xebae68c4), TOBN(0x5b385632, 0x30c5ba21), + TOBN(0x540df119, 0x1fdd1aec), TOBN(0xcf37825b, 0xcfba4c78), + TOBN(0x77eff980, 0xbeb11454), TOBN(0x40a1a991, 0x60c1b066), + TOBN(0xe8018980, 0xf889a1c7), TOBN(0xb9c52ae9, 0x76c24be0), + TOBN(0x05fbbcce, 0x45650ef4), TOBN(0xae000f10, 0x8aa29ac7), + TOBN(0x884b7172, 0x4f04c470), TOBN(0x7cd4fde2, 0x19bb5c25), + TOBN(0x6477b22a, 0xe8840869), TOBN(0xa8868859, 0x5fbd0686), + TOBN(0xf23cc02e, 0x1116dfba), TOBN(0x76cd563f, 0xd87d7776), + TOBN(0xe2a37598, 0xa9d82abf), TOBN(0x5f188ccb, 0xe6c170f5), + TOBN(0x81682200, 0x5066b087), TOBN(0xda22c212, 0xc7155ada), + TOBN(0x151e5d3a, 0xfbddb479), TOBN(0x4b606b84, 0x6d715b99), + TOBN(0x4a73b54b, 0xf997cb2e), TOBN(0x9a1bfe43, 0x3ecd8b66), + TOBN(0x1c312809, 0x2a67d48a), TOBN(0xcd6a671e, 0x031fa9e2), + TOBN(0xbec3312a, 0x0e43a34a), TOBN(0x1d935639, 0x55ef47d3), + TOBN(0x5ea02489, 0x8fea73ea), TOBN(0x8247b364, 0xa035afb2), + TOBN(0xb58300a6, 0x5265b54c), TOBN(0x3286662f, 0x722c7148), + TOBN(0xb77fd76b, 0xb4ec4c20), TOBN(0xf0a12fa7, 0x0f3fe3fd), + TOBN(0xf845bbf5, 0x41d8c7e8), TOBN(0xe4d969ca, 0x5ec10aa8), + TOBN(0x4c0053b7, 0x43e232a3), TOBN(0xdc7a3fac, 0x37f8a45a), + TOBN(0x3c4261c5, 0x20d81c8f), TOBN(0xfd4b3453, 0xb00eab00), + TOBN(0x76d48f86, 0xd36e3062), TOBN(0x626c5277, 0xa143ff02), + TOBN(0x538174de, 0xaf76f42e), TOBN(0x2267aa86, 0x6407ceac), + TOBN(0xfad76351, 0x72e572d5), TOBN(0xab861af7, 0xba7330eb), + TOBN(0xa0a1c8c7, 0x418d8657), TOBN(0x988821cb, 0x20289a52), + TOBN(0x79732522, 0xcccc18ad), TOBN(0xaadf3f8d, 0xf1a6e027), + TOBN(0xf7382c93, 0x17c2354d), TOBN(0x5ce1680c, 0xd818b689), + TOBN(0x359ebbfc, 0xd9ecbee9), TOBN(0x4330689c, 0x1cae62ac), + TOBN(0xb55ce5b4, 0xc51ac38a), TOBN(0x7921dfea, 0xfe238ee8), + TOBN(0x3972bef8, 0x271d1ca5), TOBN(0x3e423bc7, 0xe8aabd18), + TOBN(0x57b09f3f, 0x44a3e5e3), TOBN(0x5da886ae, 0x7b444d66), + TOBN(0x68206634, 0xa9964375), TOBN(0x356a2fa3, 0x699cd0ff), + TOBN(0xaf0faa24, 0xdba515e9), TOBN(0x536e1f5c, 0xb321d79a), + TOBN(0xd3b9913a, 0x5c04e4ea), TOBN(0xd549dcfe, 0xd6f11513), + TOBN(0xee227bf5, 0x79fd1d94), TOBN(0x9f35afee, 0xb43f2c67), + TOBN(0xd2638d24, 0xf1314f53), TOBN(0x62baf948, 0xcabcd822), + TOBN(0x5542de29, 0x4ef48db0), TOBN(0xb3eb6a04, 0xfc5f6bb2), + TOBN(0x23c110ae, 0x1208e16a), TOBN(0x1a4d15b5, 0xf8363e24), + TOBN(0x30716844, 0x164be00b), TOBN(0xa8e24824, 0xf6f4690d), + TOBN(0x548773a2, 0x90b170cf), TOBN(0xa1bef331, 0x42f191f4), + TOBN(0x70f418d0, 0x9247aa97), TOBN(0xea06028e, 0x48be9147), + TOBN(0xe13122f3, 0xdbfb894e), TOBN(0xbe9b79f6, 0xce274b18), + TOBN(0x85a49de5, 0xca58aadf), TOBN(0x24957758, 0x11487351), + TOBN(0x111def61, 0xbb939099), TOBN(0x1d6a974a, 0x26d13694), + TOBN(0x4474b4ce, 0xd3fc253b), TOBN(0x3a1485e6, 0x4c5db15e), + TOBN(0xe79667b4, 0x147c15b4), TOBN(0xe34f553b, 0x7bc61301), + TOBN(0x032b80f8, 0x17094381), TOBN(0x55d8bafd, 0x723eaa21), + TOBN(0x5a987995, 0xf1c0e74e), TOBN(0x5a9b292e, 0xebba289c), + TOBN(0x413cd4b2, 0xeb4c8251), TOBN(0x98b5d243, 0xd162db0a), + TOBN(0xbb47bf66, 0x68342520), TOBN(0x08d68949, 0xbaa862d1), + TOBN(0x11f349c7, 0xe906abcd), TOBN(0x454ce985, 0xed7bf00e), + TOBN(0xacab5c9e, 0xb55b803b), TOBN(0xb03468ea, 0x31e3c16d), + TOBN(0x5c24213d, 0xd273bf12), TOBN(0x211538eb, 0x71587887), + TOBN(0x198e4a2f, 0x731dea2d), TOBN(0xd5856cf2, 0x74ed7b2a), + TOBN(0x86a632eb, 0x13a664fe), TOBN(0x932cd909, 0xbda41291), + TOBN(0x850e95d4, 0xc0c4ddc0), TOBN(0xc0f422f8, 0x347fc2c9), + TOBN(0xe68cbec4, 0x86076bcb), TOBN(0xf9e7c0c0, 0xcd6cd286), + TOBN(0x65994ddb, 0x0f5f27ca), TOBN(0xe85461fb, 0xa80d59ff), + TOBN(0xff05481a, 0x66601023), TOBN(0xc665427a, 0xfc9ebbfb), + TOBN(0xb0571a69, 0x7587fd52), TOBN(0x935289f8, 0x8d49efce), + TOBN(0x61becc60, 0xea420688), TOBN(0xb22639d9, 0x13a786af), + TOBN(0x1a8e6220, 0x361ecf90), TOBN(0x001f23e0, 0x25506463), + TOBN(0xe4ae9b5d, 0x0a5c2b79), TOBN(0xebc9cdad, 0xd8149db5), + TOBN(0xb33164a1, 0x934aa728), TOBN(0x750eb00e, 0xae9b60f3), + TOBN(0x5a91615b, 0x9b9cfbfd), TOBN(0x97015cbf, 0xef45f7f6), + TOBN(0xb462c4a5, 0xbf5151df), TOBN(0x21adcc41, 0xb07118f2), + TOBN(0xd60c545b, 0x043fa42c), TOBN(0xfc21aa54, 0xe96be1ab), + TOBN(0xe84bc32f, 0x4e51ea80), TOBN(0x3dae45f0, 0x259b5d8d), + TOBN(0xbb73c7eb, 0xc38f1b5e), TOBN(0xe405a74a, 0xe8ae617d), + TOBN(0xbb1ae9c6, 0x9f1c56bd), TOBN(0x8c176b98, 0x49f196a4), + TOBN(0xc448f311, 0x6875092b), TOBN(0xb5afe3de, 0x9f976033), + TOBN(0xa8dafd49, 0x145813e5), TOBN(0x687fc4d9, 0xe2b34226), + TOBN(0xf2dfc92d, 0x4c7ff57f), TOBN(0x004e3fc1, 0x401f1b46), + TOBN(0x5afddab6, 0x1430c9ab), TOBN(0x0bdd41d3, 0x2238e997), + TOBN(0xf0947430, 0x418042ae), TOBN(0x71f9adda, 0xcdddc4cb), + TOBN(0x7090c016, 0xc52dd907), TOBN(0xd9bdf44d, 0x29e2047f), + TOBN(0xe6f1fe80, 0x1b1011a6), TOBN(0xb63accbc, 0xd9acdc78), + TOBN(0xcfc7e235, 0x1272a95b), TOBN(0x0c667717, 0xa6276ac8), + TOBN(0x3c0d3709, 0xe2d7eef7), TOBN(0x5add2b06, 0x9a685b3e), + TOBN(0x363ad32d, 0x14ea5d65), TOBN(0xf8e01f06, 0x8d7dd506), + TOBN(0xc9ea2213, 0x75b4aac6), TOBN(0xed2a2bf9, 0x0d353466), + TOBN(0x439d79b5, 0xe9d3a7c3), TOBN(0x8e0ee5a6, 0x81b7f34b), + TOBN(0xcf3dacf5, 0x1dc4ba75), TOBN(0x1d3d1773, 0xeb3310c7), + TOBN(0xa8e67112, 0x7747ae83), TOBN(0x31f43160, 0x197d6b40), + TOBN(0x0521ccee, 0xcd961400), TOBN(0x67246f11, 0xf6535768), + TOBN(0x702fcc5a, 0xef0c3133), TOBN(0x247cc45d, 0x7e16693b), + TOBN(0xfd484e49, 0xc729b749), TOBN(0x522cef7d, 0xb218320f), + TOBN(0xe56ef405, 0x59ab93b3), TOBN(0x225fba11, 0x9f181071), + TOBN(0x33bd6595, 0x15330ed0), TOBN(0xc4be69d5, 0x1ddb32f7), + TOBN(0x264c7668, 0x0448087c), TOBN(0xac30903f, 0x71432dae), + TOBN(0x3851b266, 0x00f9bf47), TOBN(0x400ed311, 0x6cdd6d03), + TOBN(0x045e79fe, 0xf8fd2424), TOBN(0xfdfd974a, 0xfa6da98b), + TOBN(0x45c9f641, 0x0c1e673a), TOBN(0x76f2e733, 0x5b2c5168), + TOBN(0x1adaebb5, 0x2a601753), TOBN(0xb286514c, 0xc57c2d49), + TOBN(0xd8769670, 0x1e0bfd24), TOBN(0x950c547e, 0x04478922), + TOBN(0xd1d41969, 0xe5d32bfe), TOBN(0x30bc1472, 0x750d6c3e), + TOBN(0x8f3679fe, 0xe0e27f3a), TOBN(0x8f64a7dc, 0xa4a6ee0c), + TOBN(0x2fe59937, 0x633dfb1f), TOBN(0xea82c395, 0x977f2547), + TOBN(0xcbdfdf1a, 0x661ea646), TOBN(0xc7ccc591, 0xb9085451), + TOBN(0x82177962, 0x81761e13), TOBN(0xda57596f, 0x9196885c), + TOBN(0xbc17e849, 0x28ffbd70), TOBN(0x1e6e0a41, 0x2671d36f), + TOBN(0x61ae872c, 0x4152fcf5), TOBN(0x441c87b0, 0x9e77e754), + TOBN(0xd0799dd5, 0xa34dff09), TOBN(0x766b4e44, 0x88a6b171), + TOBN(0xdc06a512, 0x11f1c792), TOBN(0xea02ae93, 0x4be35c3e), + TOBN(0xe5ca4d6d, 0xe90c469e), TOBN(0x4df4368e, 0x56e4ff5c), + TOBN(0x7817acab, 0x4baef62e), TOBN(0x9f5a2202, 0xa85b91e8), + TOBN(0x9666ebe6, 0x6ce57610), TOBN(0x32ad31f3, 0xf73bfe03), + TOBN(0x628330a4, 0x25bcf4d6), TOBN(0xea950593, 0x515056e6), + TOBN(0x59811c89, 0xe1332156), TOBN(0xc89cf1fe, 0x8c11b2d7), + TOBN(0x75b63913, 0x04e60cc0), TOBN(0xce811e8d, 0x4625d375), + TOBN(0x030e43fc, 0x2d26e562), TOBN(0xfbb30b4b, 0x608d36a0), + TOBN(0x634ff82c, 0x48528118), TOBN(0x7c6fe085, 0xcd285911), + TOBN(0x7f2830c0, 0x99358f28), TOBN(0x2e60a95e, 0x665e6c09), + TOBN(0x08407d3d, 0x9b785dbf), TOBN(0x530889ab, 0xa759bce7), + TOBN(0xf228e0e6, 0x52f61239), TOBN(0x2b6d1461, 0x6879be3c), + TOBN(0xe6902c04, 0x51a7bbf7), TOBN(0x30ad99f0, 0x76f24a64), + TOBN(0x66d9317a, 0x98bc6da0), TOBN(0xf4f877f3, 0xcb596ac0), + TOBN(0xb05ff62d, 0x4c44f119), TOBN(0x4555f536, 0xe9b77416), + TOBN(0xc7c0d059, 0x8caed63b), TOBN(0x0cd2b7ce, 0xc358b2a9), + TOBN(0x3f33287b, 0x46945fa3), TOBN(0xf8785b20, 0xd67c8791), + TOBN(0xc54a7a61, 0x9637bd08), TOBN(0x54d4598c, 0x18be79d7), + TOBN(0x889e5acb, 0xc46d7ce1), TOBN(0x9a515bb7, 0x8b085877), + TOBN(0xfac1a03d, 0x0b7a5050), TOBN(0x7d3e738a, 0xf2926035), + TOBN(0x861cc2ce, 0x2a6cb0eb), TOBN(0x6f2e2955, 0x8f7adc79), + TOBN(0x61c4d451, 0x33016376), TOBN(0xd9fd2c80, 0x5ad59090), + TOBN(0xe5a83738, 0xb2b836a1), TOBN(0x855b41a0, 0x7c0d6622), + TOBN(0x186fe317, 0x7cc19af1), TOBN(0x6465c1ff, 0xfdd99acb), + TOBN(0x46e5c23f, 0x6974b99e), TOBN(0x75a7cf8b, 0xa2717cbe), + TOBN(0x4d2ebc3f, 0x062be658), TOBN(0x094b4447, 0x5f209c98), + TOBN(0x4af285ed, 0xb940cb5a), TOBN(0x6706d792, 0x7cc82f10), + TOBN(0xc8c8776c, 0x030526fa), TOBN(0xfa8e6f76, 0xa0da9140), + TOBN(0x77ea9d34, 0x591ee4f0), TOBN(0x5f46e337, 0x40274166), + TOBN(0x1bdf98bb, 0xea671457), TOBN(0xd7c08b46, 0x862a1fe2), + TOBN(0x46cc303c, 0x1c08ad63), TOBN(0x99543440, 0x4c845e7b), + TOBN(0x1b8fbdb5, 0x48f36bf7), TOBN(0x5b82c392, 0x8c8273a7), + TOBN(0x08f712c4, 0x928435d5), TOBN(0x071cf0f1, 0x79330380), + TOBN(0xc74c2d24, 0xa8da054a), TOBN(0xcb0e7201, 0x43c46b5c), + TOBN(0x0ad7337a, 0xc0b7eff3), TOBN(0x8552225e, 0xc5e48b3c), + TOBN(0xe6f78b0c, 0x73f13a5f), TOBN(0x5e70062e, 0x82349cbe), + TOBN(0x6b8d5048, 0xe7073969), TOBN(0x392d2a29, 0xc33cb3d2), + TOBN(0xee4f727c, 0x4ecaa20f), TOBN(0xa068c99e, 0x2ccde707), + TOBN(0xfcd5651f, 0xb87a2913), TOBN(0xea3e3c15, 0x3cc252f0), + TOBN(0x777d92df, 0x3b6cd3e4), TOBN(0x7a414143, 0xc5a732e7), + TOBN(0xa895951a, 0xa71ff493), TOBN(0xfe980c92, 0xbbd37cf6), + TOBN(0x45bd5e64, 0xdecfeeff), TOBN(0x910dc2a9, 0xa44c43e9), + TOBN(0xcb403f26, 0xcca9f54d), TOBN(0x928bbdfb, 0x9303f6db), + TOBN(0x3c37951e, 0xa9eee67c), TOBN(0x3bd61a52, 0xf79961c3), + TOBN(0x09a238e6, 0x395c9a79), TOBN(0x6940ca2d, 0x61eb352d), + TOBN(0x7d1e5c5e, 0xc1875631), TOBN(0x1e19742c, 0x1e1b20d1), + TOBN(0x4633d908, 0x23fc2e6e), TOBN(0xa76e29a9, 0x08959149), + TOBN(0x61069d9c, 0x84ed7da5), TOBN(0x0baa11cf, 0x5dbcad51), + TOBN(0xd01eec64, 0x961849da), TOBN(0x93b75f1f, 0xaf3d8c28), + TOBN(0x57bc4f9f, 0x1ca2ee44), TOBN(0x5a26322d, 0x00e00558), + TOBN(0x1888d658, 0x61a023ef), TOBN(0x1d72aab4, 0xb9e5246e), + TOBN(0xa9a26348, 0xe5563ec0), TOBN(0xa0971963, 0xc3439a43), + TOBN(0x567dd54b, 0xadb9b5b7), TOBN(0x73fac1a1, 0xc45a524b), + TOBN(0x8fe97ef7, 0xfe38e608), TOBN(0x608748d2, 0x3f384f48), + TOBN(0xb0571794, 0xc486094f), TOBN(0x869254a3, 0x8bf3a8d6), + TOBN(0x148a8dd1, 0x310b0e25), TOBN(0x99ab9f3f, 0x9aa3f7d8), + TOBN(0x0927c68a, 0x6706c02e), TOBN(0x22b5e76c, 0x69790e6c), + TOBN(0x6c325260, 0x6c71376c), TOBN(0x53a57690, 0x09ef6657), + TOBN(0x8d63f852, 0xedffcf3a), TOBN(0xb4d2ed04, 0x3c0a6f55), + TOBN(0xdb3aa8de, 0x12519b9e), TOBN(0x5d38e9c4, 0x1e0a569a), + TOBN(0x871528bf, 0x303747e2), TOBN(0xa208e77c, 0xf5b5c18d), + TOBN(0x9d129c88, 0xca6bf923), TOBN(0xbcbf197f, 0xbf02839f), + TOBN(0x9b9bf030, 0x27323194), TOBN(0x3b055a8b, 0x339ca59d), + TOBN(0xb46b2312, 0x0f669520), TOBN(0x19789f1f, 0x497e5f24), + TOBN(0x9c499468, 0xaaf01801), TOBN(0x72ee1190, 0x8b69d59c), + TOBN(0x8bd39595, 0xacf4c079), TOBN(0x3ee11ece, 0x8e0cd048), + TOBN(0xebde86ec, 0x1ed66f18), TOBN(0x225d906b, 0xd61fce43), + TOBN(0x5cab07d6, 0xe8bed74d), TOBN(0x16e4617f, 0x27855ab7), + TOBN(0x6568aadd, 0xb2fbc3dd), TOBN(0xedb5484f, 0x8aeddf5b), + TOBN(0x878f20e8, 0x6dcf2fad), TOBN(0x3516497c, 0x615f5699)}, + {TOBN(0xef0a3fec, 0xfa181e69), TOBN(0x9ea02f81, 0x30d69a98), + TOBN(0xb2e9cf8e, 0x66eab95d), TOBN(0x520f2beb, 0x24720021), + TOBN(0x621c540a, 0x1df84361), TOBN(0x12037721, 0x71fa6d5d), + TOBN(0x6e3c7b51, 0x0ff5f6ff), TOBN(0x817a069b, 0xabb2bef3), + TOBN(0x83572fb6, 0xb294cda6), TOBN(0x6ce9bf75, 0xb9039f34), + TOBN(0x20e012f0, 0x095cbb21), TOBN(0xa0aecc1b, 0xd063f0da), + TOBN(0x57c21c3a, 0xf02909e5), TOBN(0xc7d59ecf, 0x48ce9cdc), + TOBN(0x2732b844, 0x8ae336f8), TOBN(0x056e3723, 0x3f4f85f4), + TOBN(0x8a10b531, 0x89e800ca), TOBN(0x50fe0c17, 0x145208fd), + TOBN(0x9e43c0d3, 0xb714ba37), TOBN(0x427d200e, 0x34189acc), + TOBN(0x05dee24f, 0xe616e2c0), TOBN(0x9c25f4c8, 0xee1854c1), + TOBN(0x4d3222a5, 0x8f342a73), TOBN(0x0807804f, 0xa027c952), + TOBN(0xc222653a, 0x4f0d56f3), TOBN(0x961e4047, 0xca28b805), + TOBN(0x2c03f8b0, 0x4a73434b), TOBN(0x4c966787, 0xab712a19), + TOBN(0xcc196c42, 0x864fee42), TOBN(0xc1be93da, 0x5b0ece5c), + TOBN(0xa87d9f22, 0xc131c159), TOBN(0x2bb6d593, 0xdce45655), + TOBN(0x22c49ec9, 0xb809b7ce), TOBN(0x8a41486b, 0xe2c72c2c), + TOBN(0x813b9420, 0xfea0bf36), TOBN(0xb3d36ee9, 0xa66dac69), + TOBN(0x6fddc08a, 0x328cc987), TOBN(0x0a3bcd2c, 0x3a326461), + TOBN(0x7103c49d, 0xd810dbba), TOBN(0xf9d81a28, 0x4b78a4c4), + TOBN(0x3de865ad, 0xe4d55941), TOBN(0xdedafa5e, 0x30384087), + TOBN(0x6f414abb, 0x4ef18b9b), TOBN(0x9ee9ea42, 0xfaee5268), + TOBN(0x260faa16, 0x37a55a4a), TOBN(0xeb19a514, 0x015f93b9), + TOBN(0x51d7ebd2, 0x9e9c3598), TOBN(0x523fc56d, 0x1932178e), + TOBN(0x501d070c, 0xb98fe684), TOBN(0xd60fbe9a, 0x124a1458), + TOBN(0xa45761c8, 0x92bc6b3f), TOBN(0xf5384858, 0xfe6f27cb), + TOBN(0x4b0271f7, 0xb59e763b), TOBN(0x3d4606a9, 0x5b5a8e5e), + TOBN(0x1eda5d9b, 0x05a48292), TOBN(0xda7731d0, 0xe6fec446), + TOBN(0xa3e33693, 0x90d45871), TOBN(0xe9764040, 0x06166d8d), + TOBN(0xb5c33682, 0x89a90403), TOBN(0x4bd17983, 0x72f1d637), + TOBN(0xa616679e, 0xd5d2c53a), TOBN(0x5ec4bcd8, 0xfdcf3b87), + TOBN(0xae6d7613, 0xb66a694e), TOBN(0x7460fc76, 0xe3fc27e5), + TOBN(0x70469b82, 0x95caabee), TOBN(0xde024ca5, 0x889501e3), + TOBN(0x6bdadc06, 0x076ed265), TOBN(0x0cb1236b, 0x5a0ef8b2), + TOBN(0x4065ddbf, 0x0972ebf9), TOBN(0xf1dd3875, 0x22aca432), + TOBN(0xa88b97cf, 0x744aff76), TOBN(0xd1359afd, 0xfe8e3d24), + TOBN(0x52a3ba2b, 0x91502cf3), TOBN(0x2c3832a8, 0x084db75d), + TOBN(0x04a12ddd, 0xde30b1c9), TOBN(0x7802eabc, 0xe31fd60c), + TOBN(0x33707327, 0xa37fddab), TOBN(0x65d6f2ab, 0xfaafa973), + TOBN(0x3525c5b8, 0x11e6f91a), TOBN(0x76aeb0c9, 0x5f46530b), + TOBN(0xe8815ff6, 0x2f93a675), TOBN(0xa6ec9684, 0x05f48679), + TOBN(0x6dcbb556, 0x358ae884), TOBN(0x0af61472, 0xe19e3873), + TOBN(0x72334372, 0xa5f696be), TOBN(0xc65e57ea, 0x6f22fb70), + TOBN(0x268da30c, 0x946cea90), TOBN(0x136a8a87, 0x65681b2a), + TOBN(0xad5e81dc, 0x0f9f44d4), TOBN(0xf09a6960, 0x2c46585a), + TOBN(0xd1649164, 0xc447d1b1), TOBN(0x3b4b36c8, 0x879dc8b1), + TOBN(0x20d4177b, 0x3b6b234c), TOBN(0x096a2505, 0x1730d9d0), + TOBN(0x0611b9b8, 0xef80531d), TOBN(0xba904b3b, 0x64bb495d), + TOBN(0x1192d9d4, 0x93a3147a), TOBN(0x9f30a5dc, 0x9a565545), + TOBN(0x90b1f9cb, 0x6ef07212), TOBN(0x29958546, 0x0d87fc13), + TOBN(0xd3323eff, 0xc17db9ba), TOBN(0xcb18548c, 0xcb1644a8), + TOBN(0x18a306d4, 0x4f49ffbc), TOBN(0x28d658f1, 0x4c2e8684), + TOBN(0x44ba60cd, 0xa99f8c71), TOBN(0x67b7abdb, 0x4bf742ff), + TOBN(0x66310f9c, 0x914b3f99), TOBN(0xae430a32, 0xf412c161), + TOBN(0x1e6776d3, 0x88ace52f), TOBN(0x4bc0fa24, 0x52d7067d), + TOBN(0x03c286aa, 0x8f07cd1b), TOBN(0x4cb8f38c, 0xa985b2c1), + TOBN(0x83ccbe80, 0x8c3bff36), TOBN(0x005a0bd2, 0x5263e575), + TOBN(0x460d7dda, 0x259bdcd1), TOBN(0x4a1c5642, 0xfa5cab6b), + TOBN(0x2b7bdbb9, 0x9fe4fc88), TOBN(0x09418e28, 0xcc97bbb5), + TOBN(0xd8274fb4, 0xa12321ae), TOBN(0xb137007d, 0x5c87b64e), + TOBN(0x80531fe1, 0xc63c4962), TOBN(0x50541e89, 0x981fdb25), + TOBN(0xdc1291a1, 0xfd4c2b6b), TOBN(0xc0693a17, 0xa6df4fca), + TOBN(0xb2c4604e, 0x0117f203), TOBN(0x245f1963, 0x0a99b8d0), + TOBN(0xaedc20aa, 0xc6212c44), TOBN(0xb1ed4e56, 0x520f52a8), + TOBN(0xfe48f575, 0xf8547be3), TOBN(0x0a7033cd, 0xa9e45f98), + TOBN(0x4b45d3a9, 0x18c50100), TOBN(0xb2a6cd6a, 0xa61d41da), + TOBN(0x60bbb4f5, 0x57933c6b), TOBN(0xa7538ebd, 0x2b0d7ffc), + TOBN(0x9ea3ab8d, 0x8cd626b6), TOBN(0x8273a484, 0x3601625a), + TOBN(0x88859845, 0x0168e508), TOBN(0x8cbc9bb2, 0x99a94abd), + TOBN(0x713ac792, 0xfab0a671), TOBN(0xa3995b19, 0x6c9ebffc), + TOBN(0xe711668e, 0x1239e152), TOBN(0x56892558, 0xbbb8dff4), + TOBN(0x8bfc7dab, 0xdbf17963), TOBN(0x5b59fe5a, 0xb3de1253), + TOBN(0x7e3320eb, 0x34a9f7ae), TOBN(0xe5e8cf72, 0xd751efe4), + TOBN(0x7ea003bc, 0xd9be2f37), TOBN(0xc0f551a0, 0xb6c08ef7), + TOBN(0x56606268, 0x038f6725), TOBN(0x1dd38e35, 0x6d92d3b6), + TOBN(0x07dfce7c, 0xc3cbd686), TOBN(0x4e549e04, 0x651c5da8), + TOBN(0x4058f93b, 0x08b19340), TOBN(0xc2fae6f4, 0xcac6d89d), + TOBN(0x4bad8a8c, 0x8f159cc7), TOBN(0x0ddba4b3, 0xcb0b601c), + TOBN(0xda4fc7b5, 0x1dd95f8c), TOBN(0x1d163cd7, 0xcea5c255), + TOBN(0x30707d06, 0x274a8c4c), TOBN(0x79d9e008, 0x2802e9ce), + TOBN(0x02a29ebf, 0xe6ddd505), TOBN(0x37064e74, 0xb50bed1a), + TOBN(0x3f6bae65, 0xa7327d57), TOBN(0x3846f5f1, 0xf83920bc), + TOBN(0x87c37491, 0x60df1b9b), TOBN(0x4cfb2895, 0x2d1da29f), + TOBN(0x10a478ca, 0x4ed1743c), TOBN(0x390c6030, 0x3edd47c6), + TOBN(0x8f3e5312, 0x8c0a78de), TOBN(0xccd02bda, 0x1e85df70), + TOBN(0xd6c75c03, 0xa61b6582), TOBN(0x0762921c, 0xfc0eebd1), + TOBN(0xd34d0823, 0xd85010c0), TOBN(0xd73aaacb, 0x0044cf1f), + TOBN(0xfb4159bb, 0xa3b5e78a), TOBN(0x2287c7f7, 0xe5826f3f), + TOBN(0x4aeaf742, 0x580b1a01), TOBN(0xf080415d, 0x60423b79), + TOBN(0xe12622cd, 0xa7dea144), TOBN(0x49ea4996, 0x59d62472), + TOBN(0xb42991ef, 0x571f3913), TOBN(0x0610f214, 0xf5b25a8a), + TOBN(0x47adc585, 0x30b79e8f), TOBN(0xf90e3df6, 0x07a065a2), + TOBN(0x5d0a5deb, 0x43e2e034), TOBN(0x53fb5a34, 0x444024aa), + TOBN(0xa8628c68, 0x6b0c9f7f), TOBN(0x9c69c29c, 0xac563656), + TOBN(0x5a231feb, 0xbace47b6), TOBN(0xbdce0289, 0x9ea5a2ec), + TOBN(0x05da1fac, 0x9463853e), TOBN(0x96812c52, 0x509e78aa), + TOBN(0xd3fb5771, 0x57151692), TOBN(0xeb2721f8, 0xd98e1c44), + TOBN(0xc0506087, 0x32399be1), TOBN(0xda5a5511, 0xd979d8b8), + TOBN(0x737ed55d, 0xc6f56780), TOBN(0xe20d3004, 0x0dc7a7f4), + TOBN(0x02ce7301, 0xf5941a03), TOBN(0x91ef5215, 0xed30f83a), + TOBN(0x28727fc1, 0x4092d85f), TOBN(0x72d223c6, 0x5c49e41a), + TOBN(0xa7cf30a2, 0xba6a4d81), TOBN(0x7c086209, 0xb030d87d), + TOBN(0x04844c7d, 0xfc588b09), TOBN(0x728cd499, 0x5874bbb0), + TOBN(0xcc1281ee, 0xe84c0495), TOBN(0x0769b5ba, 0xec31958f), + TOBN(0x665c228b, 0xf99c2471), TOBN(0xf2d8a11b, 0x191eb110), + TOBN(0x4594f494, 0xd36d7024), TOBN(0x482ded8b, 0xcdcb25a1), + TOBN(0xc958a9d8, 0xdadd4885), TOBN(0x7004477e, 0xf1d2b547), + TOBN(0x0a45f6ef, 0x2a0af550), TOBN(0x4fc739d6, 0x2f8d6351), + TOBN(0x75cdaf27, 0x786f08a9), TOBN(0x8700bb26, 0x42c2737f), + TOBN(0x855a7141, 0x1c4e2670), TOBN(0x810188c1, 0x15076fef), + TOBN(0xc251d0c9, 0xabcd3297), TOBN(0xae4c8967, 0xf48108eb), + TOBN(0xbd146de7, 0x18ceed30), TOBN(0xf9d4f07a, 0xc986bced), + TOBN(0x5ad98ed5, 0x83fa1e08), TOBN(0x7780d33e, 0xbeabd1fb), + TOBN(0xe330513c, 0x903b1196), TOBN(0xba11de9e, 0xa47bc8c4), + TOBN(0x684334da, 0x02c2d064), TOBN(0x7ecf360d, 0xa48de23b), + TOBN(0x57a1b474, 0x0a9089d8), TOBN(0xf28fa439, 0xff36734c), + TOBN(0xf2a482cb, 0xea4570b3), TOBN(0xee65d68b, 0xa5ebcee9), + TOBN(0x988d0036, 0xb9694cd5), TOBN(0x53edd0e9, 0x37885d32), + TOBN(0xe37e3307, 0xbeb9bc6d), TOBN(0xe9abb907, 0x9f5c6768), + TOBN(0x4396ccd5, 0x51f2160f), TOBN(0x2500888c, 0x47336da6), + TOBN(0x383f9ed9, 0x926fce43), TOBN(0x809dd1c7, 0x04da2930), + TOBN(0x30f6f596, 0x8a4cb227), TOBN(0x0d700c7f, 0x73a56b38), + TOBN(0x1825ea33, 0xab64a065), TOBN(0xaab9b735, 0x1338df80), + TOBN(0x1516100d, 0x9b63f57f), TOBN(0x2574395a, 0x27a6a634), + TOBN(0xb5560fb6, 0x700a1acd), TOBN(0xe823fd73, 0xfd999681), + TOBN(0xda915d1f, 0x6cb4e1ba), TOBN(0x0d030118, 0x6ebe00a3), + TOBN(0x744fb0c9, 0x89fca8cd), TOBN(0x970d01db, 0xf9da0e0b), + TOBN(0x0ad8c564, 0x7931d76f), TOBN(0xb15737bf, 0xf659b96a), + TOBN(0xdc9933e8, 0xa8b484e7), TOBN(0xb2fdbdf9, 0x7a26dec7), + TOBN(0x2349e9a4, 0x9f1f0136), TOBN(0x7860368e, 0x70fddddb), + TOBN(0xd93d2c1c, 0xf9ad3e18), TOBN(0x6d6c5f17, 0x689f4e79), + TOBN(0x7a544d91, 0xb24ff1b6), TOBN(0x3e12a5eb, 0xfe16cd8c), + TOBN(0x543574e9, 0xa56b872f), TOBN(0xa1ad550c, 0xfcf68ea2), + TOBN(0x689e37d2, 0x3f560ef7), TOBN(0x8c54b9ca, 0xc9d47a8b), + TOBN(0x46d40a4a, 0x088ac342), TOBN(0xec450c7c, 0x1576c6d0), + TOBN(0xb589e31c, 0x1f9689e9), TOBN(0xdacf2602, 0xb8781718), + TOBN(0xa89237c6, 0xc8cb6b42), TOBN(0x1326fc93, 0xb96ef381), + TOBN(0x55d56c6d, 0xb5f07825), TOBN(0xacba2eea, 0x7449e22d), + TOBN(0x74e0887a, 0x633c3000), TOBN(0xcb6cd172, 0xd7cbcf71), + TOBN(0x309e81de, 0xc36cf1be), TOBN(0x07a18a6d, 0x60ae399b), + TOBN(0xb36c2679, 0x9edce57e), TOBN(0x52b892f4, 0xdf001d41), + TOBN(0xd884ae5d, 0x16a1f2c6), TOBN(0x9b329424, 0xefcc370a), + TOBN(0x3120daf2, 0xbd2e21df), TOBN(0x55298d2d, 0x02470a99), + TOBN(0x0b78af6c, 0xa05db32e), TOBN(0x5c76a331, 0x601f5636), + TOBN(0xaae861ff, 0xf8a4f29c), TOBN(0x70dc9240, 0xd68f8d49), + TOBN(0x960e649f, 0x81b1321c), TOBN(0x3d2c801b, 0x8792e4ce), + TOBN(0xf479f772, 0x42521876), TOBN(0x0bed93bc, 0x416c79b1), + TOBN(0xa67fbc05, 0x263e5bc9), TOBN(0x01e8e630, 0x521db049), + TOBN(0x76f26738, 0xc6f3431e), TOBN(0xe609cb02, 0xe3267541), + TOBN(0xb10cff2d, 0x818c877c), TOBN(0x1f0e75ce, 0x786a13cb), + TOBN(0xf4fdca64, 0x1158544d), TOBN(0x5d777e89, 0x6cb71ed0), + TOBN(0x3c233737, 0xa9aa4755), TOBN(0x7b453192, 0xe527ab40), + TOBN(0xdb59f688, 0x39f05ffe), TOBN(0x8f4f4be0, 0x6d82574e), + TOBN(0xcce3450c, 0xee292d1b), TOBN(0xaa448a12, 0x61ccd086), + TOBN(0xabce91b3, 0xf7914967), TOBN(0x4537f09b, 0x1908a5ed), + TOBN(0xa812421e, 0xf51042e7), TOBN(0xfaf5cebc, 0xec0b3a34), + TOBN(0x730ffd87, 0x4ca6b39a), TOBN(0x70fb72ed, 0x02efd342), + TOBN(0xeb4735f9, 0xd75c8edb), TOBN(0xc11f2157, 0xc278aa51), + TOBN(0xc459f635, 0xbf3bfebf), TOBN(0x3a1ff0b4, 0x6bd9601f), + TOBN(0xc9d12823, 0xc420cb73), TOBN(0x3e9af3e2, 0x3c2915a3), + TOBN(0xe0c82c72, 0xb41c3440), TOBN(0x175239e5, 0xe3039a5f), + TOBN(0xe1084b8a, 0x558795a3), TOBN(0x328d0a1d, 0xd01e5c60), + TOBN(0x0a495f2e, 0xd3788a04), TOBN(0x25d8ff16, 0x66c11a9f), + TOBN(0xf5155f05, 0x9ed692d6), TOBN(0x954fa107, 0x4f425fe4), + TOBN(0xd16aabf2, 0xe98aaa99), TOBN(0x90cd8ba0, 0x96b0f88a), + TOBN(0x957f4782, 0xc154026a), TOBN(0x54ee0734, 0x52af56d2), + TOBN(0xbcf89e54, 0x45b4147a), TOBN(0x3d102f21, 0x9a52816c), + TOBN(0x6808517e, 0x39b62e77), TOBN(0x92e25421, 0x69169ad8), + TOBN(0xd721d871, 0xbb608558), TOBN(0x60e4ebae, 0xf6d4ff9b), + TOBN(0x0ba10819, 0x41f2763e), TOBN(0xca2e45be, 0x51ee3247), + TOBN(0x66d172ec, 0x2bfd7a5f), TOBN(0x528a8f2f, 0x74d0b12d), + TOBN(0xe17f1e38, 0xdabe70dc), TOBN(0x1d5d7316, 0x9f93983c), + TOBN(0x51b2184a, 0xdf423e31), TOBN(0xcb417291, 0xaedb1a10), + TOBN(0x2054ca93, 0x625bcab9), TOBN(0x54396860, 0xa98998f0), + TOBN(0x4e53f6c4, 0xa54ae57e), TOBN(0x0ffeb590, 0xee648e9d), + TOBN(0xfbbdaadc, 0x6afaf6bc), TOBN(0xf88ae796, 0xaa3bfb8a), + TOBN(0x209f1d44, 0xd2359ed9), TOBN(0xac68dd03, 0xf3544ce2), + TOBN(0xf378da47, 0xfd51e569), TOBN(0xe1abd860, 0x2cc80097), + TOBN(0x23ca18d9, 0x343b6e3a), TOBN(0x480797e8, 0xb40a1bae), + TOBN(0xd1f0c717, 0x533f3e67), TOBN(0x44896970, 0x06e6cdfc), + TOBN(0x8ca21055, 0x52a82e8d), TOBN(0xb2caf785, 0x78460cdc), + TOBN(0x4c1b7b62, 0xe9037178), TOBN(0xefc09d2c, 0xdb514b58), + TOBN(0x5f2df9ee, 0x9113be5c), TOBN(0x2fbda78f, 0xb3f9271c), + TOBN(0xe09a81af, 0x8f83fc54), TOBN(0x06b13866, 0x8afb5141), + TOBN(0x38f6480f, 0x43e3865d), TOBN(0x72dd77a8, 0x1ddf47d9), + TOBN(0xf2a8e971, 0x4c205ff7), TOBN(0x46d449d8, 0x9d088ad8), + TOBN(0x926619ea, 0x185d706f), TOBN(0xe47e02eb, 0xc7dd7f62), + TOBN(0xe7f120a7, 0x8cbc2031), TOBN(0xc18bef00, 0x998d4ac9), + TOBN(0x18f37a9c, 0x6bdf22da), TOBN(0xefbc432f, 0x90dc82df), + TOBN(0xc52cef8e, 0x5d703651), TOBN(0x82887ba0, 0xd99881a5), + TOBN(0x7cec9dda, 0xb920ec1d), TOBN(0xd0d7e8c3, 0xec3e8d3b), + TOBN(0x445bc395, 0x4ca88747), TOBN(0xedeaa2e0, 0x9fd53535), + TOBN(0x461b1d93, 0x6cc87475), TOBN(0xd92a52e2, 0x6d2383bd), + TOBN(0xfabccb59, 0xd7903546), TOBN(0x6111a761, 0x3d14b112), + TOBN(0x0ae584fe, 0xb3d5f612), TOBN(0x5ea69b8d, 0x60e828ec), + TOBN(0x6c078985, 0x54087030), TOBN(0x649cab04, 0xac4821fe), + TOBN(0x25ecedcf, 0x8bdce214), TOBN(0xb5622f72, 0x86af7361), + TOBN(0x0e1227aa, 0x7038b9e2), TOBN(0xd0efb273, 0xac20fa77), + TOBN(0x817ff88b, 0x79df975b), TOBN(0x856bf286, 0x1999503e), + TOBN(0xb4d5351f, 0x5038ec46), TOBN(0x740a52c5, 0xfc42af6e), + TOBN(0x2e38bb15, 0x2cbb1a3f), TOBN(0xc3eb99fe, 0x17a83429), + TOBN(0xca4fcbf1, 0xdd66bb74), TOBN(0x880784d6, 0xcde5e8fc), + TOBN(0xddc84c1c, 0xb4e7a0be), TOBN(0x8780510d, 0xbd15a72f), + TOBN(0x44bcf1af, 0x81ec30e1), TOBN(0x141e50a8, 0x0a61073e), + TOBN(0x0d955718, 0x47be87ae), TOBN(0x68a61417, 0xf76a4372), + TOBN(0xf57e7e87, 0xc607c3d3), TOBN(0x043afaf8, 0x5252f332), + TOBN(0xcc14e121, 0x1552a4d2), TOBN(0xb6dee692, 0xbb4d4ab4), + TOBN(0xb6ab74c8, 0xa03816a4), TOBN(0x84001ae4, 0x6f394a29), + TOBN(0x5bed8344, 0xd795fb45), TOBN(0x57326e7d, 0xb79f55a5), + TOBN(0xc9533ce0, 0x4accdffc), TOBN(0x53473caf, 0x3993fa04), + TOBN(0x7906eb93, 0xa13df4c8), TOBN(0xa73e51f6, 0x97cbe46f), + TOBN(0xd1ab3ae1, 0x0ae4ccf8), TOBN(0x25614508, 0x8a5b3dbc), + TOBN(0x61eff962, 0x11a71b27), TOBN(0xdf71412b, 0x6bb7fa39), + TOBN(0xb31ba6b8, 0x2bd7f3ef), TOBN(0xb0b9c415, 0x69180d29), + TOBN(0xeec14552, 0x014cdde5), TOBN(0x702c624b, 0x227b4bbb), + TOBN(0x2b15e8c2, 0xd3e988f3), TOBN(0xee3bcc6d, 0xa4f7fd04), + TOBN(0x9d00822a, 0x42ac6c85), TOBN(0x2db0cea6, 0x1df9f2b7), + TOBN(0xd7cad2ab, 0x42de1e58), TOBN(0x346ed526, 0x2d6fbb61), + TOBN(0xb3962995, 0x1a2faf09), TOBN(0x2fa8a580, 0x7c25612e), + TOBN(0x30ae04da, 0x7cf56490), TOBN(0x75662908, 0x0eea3961), + TOBN(0x3609f5c5, 0x3d080847), TOBN(0xcb081d39, 0x5241d4f6), + TOBN(0xb4fb3810, 0x77961a63), TOBN(0xc20c5984, 0x2abb66fc), + TOBN(0x3d40aa7c, 0xf902f245), TOBN(0x9cb12736, 0x4e536b1e), + TOBN(0x5eda24da, 0x99b3134f), TOBN(0xafbd9c69, 0x5cd011af), + TOBN(0x9a16e30a, 0xc7088c7d), TOBN(0x5ab65710, 0x3207389f), + TOBN(0x1b09547f, 0xe7407a53), TOBN(0x2322f9d7, 0x4fdc6eab), + TOBN(0xc0f2f22d, 0x7430de4d), TOBN(0x19382696, 0xe68ca9a9), + TOBN(0x17f1eff1, 0x918e5868), TOBN(0xe3b5b635, 0x586f4204), + TOBN(0x146ef980, 0x3fbc4341), TOBN(0x359f2c80, 0x5b5eed4e), + TOBN(0x9f35744e, 0x7482e41d), TOBN(0x9a9ac3ec, 0xf3b224c2), + TOBN(0x9161a6fe, 0x91fc50ae), TOBN(0x89ccc66b, 0xc613fa7c), + TOBN(0x89268b14, 0xc732f15a), TOBN(0x7cd6f4e2, 0xb467ed03), + TOBN(0xfbf79869, 0xce56b40e), TOBN(0xf93e094c, 0xc02dde98), + TOBN(0xefe0c3a8, 0xedee2cd7), TOBN(0x90f3ffc0, 0xb268fd42), + TOBN(0x81a7fd56, 0x08241aed), TOBN(0x95ab7ad8, 0x00b1afe8), + TOBN(0x40127056, 0x3e310d52), TOBN(0xd3ffdeb1, 0x09d9fc43), + TOBN(0xc8f85c91, 0xd11a8594), TOBN(0x2e74d258, 0x31cf6db8), + TOBN(0x829c7ca3, 0x02b5dfd0), TOBN(0xe389cfbe, 0x69143c86), + TOBN(0xd01b6405, 0x941768d8), TOBN(0x45103995, 0x03bf825d), + TOBN(0xcc4ee166, 0x56cd17e2), TOBN(0xbea3c283, 0xba037e79), + TOBN(0x4e1ac06e, 0xd9a47520), TOBN(0xfbfe18aa, 0xaf852404), + TOBN(0x5615f8e2, 0x8087648a), TOBN(0x7301e47e, 0xb9d150d9), + TOBN(0x79f9f9dd, 0xb299b977), TOBN(0x76697a7b, 0xa5b78314), + TOBN(0x10d67468, 0x7d7c90e7), TOBN(0x7afffe03, 0x937210b5), + TOBN(0x5aef3e4b, 0x28c22cee), TOBN(0xefb0ecd8, 0x09fd55ae), + TOBN(0x4cea7132, 0x0d2a5d6a), TOBN(0x9cfb5fa1, 0x01db6357), + TOBN(0x395e0b57, 0xf36e1ac5), TOBN(0x008fa9ad, 0x36cafb7d), + TOBN(0x8f6cdf70, 0x5308c4db), TOBN(0x51527a37, 0x95ed2477), + TOBN(0xba0dee30, 0x5bd21311), TOBN(0x6ed41b22, 0x909c90d7), + TOBN(0xc5f6b758, 0x7c8696d3), TOBN(0x0db8eaa8, 0x3ce83a80), + TOBN(0xd297fe37, 0xb24b4b6f), TOBN(0xfe58afe8, 0x522d1f0d), + TOBN(0x97358736, 0x8c98dbd9), TOBN(0x6bc226ca, 0x9454a527), + TOBN(0xa12b384e, 0xce53c2d0), TOBN(0x779d897d, 0x5e4606da), + TOBN(0xa53e47b0, 0x73ec12b0), TOBN(0x462dbbba, 0x5756f1ad), + TOBN(0x69fe09f2, 0xcafe37b6), TOBN(0x273d1ebf, 0xecce2e17), + TOBN(0x8ac1d538, 0x3cf607fd), TOBN(0x8035f7ff, 0x12e10c25)}, + {TOBN(0x854d34c7, 0x7e6c5520), TOBN(0xc27df9ef, 0xdcb9ea58), + TOBN(0x405f2369, 0xd686666d), TOBN(0x29d1febf, 0x0417aa85), + TOBN(0x9846819e, 0x93470afe), TOBN(0x3e6a9669, 0xe2a27f9e), + TOBN(0x24d008a2, 0xe31e6504), TOBN(0xdba7cecf, 0x9cb7680a), + TOBN(0xecaff541, 0x338d6e43), TOBN(0x56f7dd73, 0x4541d5cc), + TOBN(0xb5d426de, 0x96bc88ca), TOBN(0x48d94f6b, 0x9ed3a2c3), + TOBN(0x6354a3bb, 0x2ef8279c), TOBN(0xd575465b, 0x0b1867f2), + TOBN(0xef99b0ff, 0x95225151), TOBN(0xf3e19d88, 0xf94500d8), + TOBN(0x92a83268, 0xe32dd620), TOBN(0x913ec99f, 0x627849a2), + TOBN(0xedd8fdfa, 0x2c378882), TOBN(0xaf96f33e, 0xee6f8cfe), + TOBN(0xc06737e5, 0xdc3fa8a5), TOBN(0x236bb531, 0xb0b03a1d), + TOBN(0x33e59f29, 0x89f037b0), TOBN(0x13f9b5a7, 0xd9a12a53), + TOBN(0x0d0df6ce, 0x51efb310), TOBN(0xcb5b2eb4, 0x958df5be), + TOBN(0xd6459e29, 0x36158e59), TOBN(0x82aae2b9, 0x1466e336), + TOBN(0xfb658a39, 0x411aa636), TOBN(0x7152ecc5, 0xd4c0a933), + TOBN(0xf10c758a, 0x49f026b7), TOBN(0xf4837f97, 0xcb09311f), + TOBN(0xddfb02c4, 0xc753c45f), TOBN(0x18ca81b6, 0xf9c840fe), + TOBN(0x846fd09a, 0xb0f8a3e6), TOBN(0xb1162add, 0xe7733dbc), + TOBN(0x7070ad20, 0x236e3ab6), TOBN(0xf88cdaf5, 0xb2a56326), + TOBN(0x05fc8719, 0x997cbc7a), TOBN(0x442cd452, 0x4b665272), + TOBN(0x7807f364, 0xb71698f5), TOBN(0x6ba418d2, 0x9f7b605e), + TOBN(0xfd20b00f, 0xa03b2cbb), TOBN(0x883eca37, 0xda54386f), + TOBN(0xff0be43f, 0xf3437f24), TOBN(0xe910b432, 0xa48bb33c), + TOBN(0x4963a128, 0x329df765), TOBN(0xac1dd556, 0xbe2fe6f7), + TOBN(0x557610f9, 0x24a0a3fc), TOBN(0x38e17bf4, 0xe881c3f9), + TOBN(0x6ba84faf, 0xed0dac99), TOBN(0xd4a222c3, 0x59eeb918), + TOBN(0xc79c1dbe, 0x13f542b6), TOBN(0x1fc65e0d, 0xe425d457), + TOBN(0xeffb754f, 0x1debb779), TOBN(0x638d8fd0, 0x9e08af60), + TOBN(0x994f523a, 0x626332d5), TOBN(0x7bc38833, 0x5561bb44), + TOBN(0x005ed4b0, 0x3d845ea2), TOBN(0xd39d3ee1, 0xc2a1f08a), + TOBN(0x6561fdd3, 0xe7676b0d), TOBN(0x620e35ff, 0xfb706017), + TOBN(0x36ce424f, 0xf264f9a8), TOBN(0xc4c3419f, 0xda2681f7), + TOBN(0xfb6afd2f, 0x69beb6e8), TOBN(0x3a50b993, 0x6d700d03), + TOBN(0xc840b2ad, 0x0c83a14f), TOBN(0x573207be, 0x54085bef), + TOBN(0x5af882e3, 0x09fe7e5b), TOBN(0x957678a4, 0x3b40a7e1), + TOBN(0x172d4bdd, 0x543056e2), TOBN(0x9c1b26b4, 0x0df13c0a), + TOBN(0x1c30861c, 0xf405ff06), TOBN(0xebac86bd, 0x486e828b), + TOBN(0xe791a971, 0x636933fc), TOBN(0x50e7c2be, 0x7aeee947), + TOBN(0xc3d4a095, 0xfa90d767), TOBN(0xae60eb7b, 0xe670ab7b), + TOBN(0x17633a64, 0x397b056d), TOBN(0x93a21f33, 0x105012aa), + TOBN(0x663c370b, 0xabb88643), TOBN(0x91df36d7, 0x22e21599), + TOBN(0x183ba835, 0x8b761671), TOBN(0x381eea1d, 0x728f3bf1), + TOBN(0xb9b2f1ba, 0x39966e6c), TOBN(0x7c464a28, 0xe7295492), + TOBN(0x0fd5f70a, 0x09b26b7f), TOBN(0xa9aba1f9, 0xfbe009df), + TOBN(0x857c1f22, 0x369b87ad), TOBN(0x3c00e5d9, 0x32fca556), + TOBN(0x1ad74cab, 0x90b06466), TOBN(0xa7112386, 0x550faaf2), + TOBN(0x7435e198, 0x6d9bd5f5), TOBN(0x2dcc7e38, 0x59c3463f), + TOBN(0xdc7df748, 0xca7bd4b2), TOBN(0x13cd4c08, 0x9dec2f31), + TOBN(0x0d3b5df8, 0xe3237710), TOBN(0x0dadb26e, 0xcbd2f7b0), + TOBN(0x9f5966ab, 0xe4aa082b), TOBN(0x666ec8de, 0x350e966e), + TOBN(0x1bfd1ed5, 0xee524216), TOBN(0xcd93c59b, 0x41dab0b6), + TOBN(0x658a8435, 0xd186d6ba), TOBN(0x1b7d34d2, 0x159d1195), + TOBN(0x5936e460, 0x22caf46b), TOBN(0x6a45dd8f, 0x9a96fe4f), + TOBN(0xf7925434, 0xb98f474e), TOBN(0x41410412, 0x0053ef15), + TOBN(0x71cf8d12, 0x41de97bf), TOBN(0xb8547b61, 0xbd80bef4), + TOBN(0xb47d3970, 0xc4db0037), TOBN(0xf1bcd328, 0xfef20dff), + TOBN(0x31a92e09, 0x10caad67), TOBN(0x1f591960, 0x5531a1e1), + TOBN(0x3bb852e0, 0x5f4fc840), TOBN(0x63e297ca, 0x93a72c6c), + TOBN(0x3c2b0b2e, 0x49abad67), TOBN(0x6ec405fc, 0xed3db0d9), + TOBN(0xdc14a530, 0x7fef1d40), TOBN(0xccd19846, 0x280896fc), + TOBN(0x00f83176, 0x9bb81648), TOBN(0xd69eb485, 0x653120d0), + TOBN(0xd17d75f4, 0x4ccabc62), TOBN(0x34a07f82, 0xb749fcb1), + TOBN(0x2c3af787, 0xbbfb5554), TOBN(0xb06ed4d0, 0x62e283f8), + TOBN(0x5722889f, 0xa19213a0), TOBN(0x162b085e, 0xdcf3c7b4), + TOBN(0xbcaecb31, 0xe0dd3eca), TOBN(0xc6237fbc, 0xe52f13a5), + TOBN(0xcc2b6b03, 0x27bac297), TOBN(0x2ae1cac5, 0xb917f54a), + TOBN(0x474807d4, 0x7845ae4f), TOBN(0xfec7dd92, 0xce5972e0), + TOBN(0xc3bd2541, 0x1d7915bb), TOBN(0x66f85dc4, 0xd94907ca), + TOBN(0xd981b888, 0xbdbcf0ca), TOBN(0xd75f5da6, 0xdf279e9f), + TOBN(0x128bbf24, 0x7054e934), TOBN(0x3c6ff6e5, 0x81db134b), + TOBN(0x795b7cf4, 0x047d26e4), TOBN(0xf370f7b8, 0x5049ec37), + TOBN(0xc6712d4d, 0xced945af), TOBN(0xdf30b5ec, 0x095642bc), + TOBN(0x9b034c62, 0x4896246e), TOBN(0x5652c016, 0xee90bbd1), + TOBN(0xeb38636f, 0x87fedb73), TOBN(0x5e32f847, 0x0135a613), + TOBN(0x0703b312, 0xcf933c83), TOBN(0xd05bb76e, 0x1a7f47e6), + TOBN(0x825e4f0c, 0x949c2415), TOBN(0x569e5622, 0x7250d6f8), + TOBN(0xbbe9eb3a, 0x6568013e), TOBN(0x8dbd203f, 0x22f243fc), + TOBN(0x9dbd7694, 0xb342734a), TOBN(0x8f6d12f8, 0x46afa984), + TOBN(0xb98610a2, 0xc9eade29), TOBN(0xbab4f323, 0x47dd0f18), + TOBN(0x5779737b, 0x671c0d46), TOBN(0x10b6a7c6, 0xd3e0a42a), + TOBN(0xfb19ddf3, 0x3035b41c), TOBN(0xd336343f, 0x99c45895), + TOBN(0x61fe4938, 0x54c857e5), TOBN(0xc4d506be, 0xae4e57d5), + TOBN(0x3cd8c8cb, 0xbbc33f75), TOBN(0x7281f08a, 0x9262c77d), + TOBN(0x083f4ea6, 0xf11a2823), TOBN(0x8895041e, 0x9fba2e33), + TOBN(0xfcdfea49, 0x9c438edf), TOBN(0x7678dcc3, 0x91edba44), + TOBN(0xf07b3b87, 0xe2ba50f0), TOBN(0xc13888ef, 0x43948c1b), + TOBN(0xc2135ad4, 0x1140af42), TOBN(0x8e5104f3, 0x926ed1a7), + TOBN(0xf24430cb, 0x88f6695f), TOBN(0x0ce0637b, 0x6d73c120), + TOBN(0xb2db01e6, 0xfe631e8f), TOBN(0x1c5563d7, 0xd7bdd24b), + TOBN(0x8daea3ba, 0x369ad44f), TOBN(0x000c81b6, 0x8187a9f9), + TOBN(0x5f48a951, 0xaae1fd9a), TOBN(0xe35626c7, 0x8d5aed8a), + TOBN(0x20952763, 0x0498c622), TOBN(0x76d17634, 0x773aa504), + TOBN(0x36d90dda, 0xeb300f7a), TOBN(0x9dcf7dfc, 0xedb5e801), + TOBN(0x645cb268, 0x74d5244c), TOBN(0xa127ee79, 0x348e3aa2), + TOBN(0x488acc53, 0x575f1dbb), TOBN(0x95037e85, 0x80e6161e), + TOBN(0x57e59283, 0x292650d0), TOBN(0xabe67d99, 0x14938216), + TOBN(0x3c7f944b, 0x3f8e1065), TOBN(0xed908cb6, 0x330e8924), + TOBN(0x08ee8fd5, 0x6f530136), TOBN(0x2227b7d5, 0xd7ffc169), + TOBN(0x4f55c893, 0xb5cd6dd5), TOBN(0x82225e11, 0xa62796e8), + TOBN(0x5c6cead1, 0xcb18e12c), TOBN(0x4381ae0c, 0x84f5a51a), + TOBN(0x345913d3, 0x7fafa4c8), TOBN(0x3d918082, 0x0491aac0), + TOBN(0x9347871f, 0x3e69264c), TOBN(0xbea9dd3c, 0xb4f4f0cd), + TOBN(0xbda5d067, 0x3eadd3e7), TOBN(0x0033c1b8, 0x0573bcd8), + TOBN(0x25589379, 0x5da2486c), TOBN(0xcb89ee5b, 0x86abbee7), + TOBN(0x8fe0a8f3, 0x22532e5d), TOBN(0xb6410ff0, 0x727dfc4c), + TOBN(0x619b9d58, 0x226726db), TOBN(0x5ec25669, 0x7a2b2dc7), + TOBN(0xaf4d2e06, 0x4c3beb01), TOBN(0x852123d0, 0x7acea556), + TOBN(0x0e9470fa, 0xf783487a), TOBN(0x75a7ea04, 0x5664b3eb), + TOBN(0x4ad78f35, 0x6798e4ba), TOBN(0x9214e6e5, 0xc7d0e091), + TOBN(0xc420b488, 0xb1290403), TOBN(0x64049e0a, 0xfc295749), + TOBN(0x03ef5af1, 0x3ae9841f), TOBN(0xdbe4ca19, 0xb0b662a6), + TOBN(0x46845c5f, 0xfa453458), TOBN(0xf8dabf19, 0x10b66722), + TOBN(0xb650f0aa, 0xcce2793b), TOBN(0x71db851e, 0xc5ec47c1), + TOBN(0x3eb78f3e, 0x3b234fa9), TOBN(0xb0c60f35, 0xfc0106ce), + TOBN(0x05427121, 0x774eadbd), TOBN(0x25367faf, 0xce323863), + TOBN(0x7541b5c9, 0xcd086976), TOBN(0x4ff069e2, 0xdc507ad1), + TOBN(0x74145256, 0x8776e667), TOBN(0x6e76142c, 0xb23c6bb5), + TOBN(0xdbf30712, 0x1b3a8a87), TOBN(0x60e7363e, 0x98450836), + TOBN(0x5741450e, 0xb7366d80), TOBN(0xe4ee14ca, 0x4837dbdf), + TOBN(0xa765eb9b, 0x69d4316f), TOBN(0x04548dca, 0x8ef43825), + TOBN(0x9c9f4e4c, 0x5ae888eb), TOBN(0x733abb51, 0x56e9ac99), + TOBN(0xdaad3c20, 0xba6ac029), TOBN(0x9b8dd3d3, 0x2ba3e38e), + TOBN(0xa9bb4c92, 0x0bc5d11a), TOBN(0xf20127a7, 0x9c5f88a3), + TOBN(0x4f52b06e, 0x161d3cb8), TOBN(0x26c1ff09, 0x6afaf0a6), + TOBN(0x32670d2f, 0x7189e71f), TOBN(0xc6438748, 0x5ecf91e7), + TOBN(0x15758e57, 0xdb757a21), TOBN(0x427d09f8, 0x290a9ce5), + TOBN(0x846a308f, 0x38384a7a), TOBN(0xaac3acb4, 0xb0732b99), + TOBN(0x9e941009, 0x17845819), TOBN(0x95cba111, 0xa7ce5e03), + TOBN(0x6f3d4f7f, 0xb00009c4), TOBN(0xb8396c27, 0x8ff28b5f), + TOBN(0xb1a9ae43, 0x1c97975d), TOBN(0x9d7ba8af, 0xe5d9fed5), + TOBN(0x338cf09f, 0x34f485b6), TOBN(0xbc0ddacc, 0x64122516), + TOBN(0xa450da12, 0x05d471fe), TOBN(0x4c3a6250, 0x628dd8c9), + TOBN(0x69c7d103, 0xd1295837), TOBN(0xa2893e50, 0x3807eb2f), + TOBN(0xd6e1e1de, 0xbdb41491), TOBN(0xc630745b, 0x5e138235), + TOBN(0xc892109e, 0x48661ae1), TOBN(0x8d17e7eb, 0xea2b2674), + TOBN(0x00ec0f87, 0xc328d6b5), TOBN(0x6d858645, 0xf079ff9e), + TOBN(0x6cdf243e, 0x19115ead), TOBN(0x1ce1393e, 0x4bac4fcf), + TOBN(0x2c960ed0, 0x9c29f25b), TOBN(0x59be4d8e, 0x9d388a05), + TOBN(0x0d46e06c, 0xd0def72b), TOBN(0xb923db5d, 0xe0342748), + TOBN(0xf7d3aacd, 0x936d4a3d), TOBN(0x558519cc, 0x0b0b099e), + TOBN(0x3ea8ebf8, 0x827097ef), TOBN(0x259353db, 0xd054f55d), + TOBN(0x84c89abc, 0x6d2ed089), TOBN(0x5c548b69, 0x8e096a7c), + TOBN(0xd587f616, 0x994b995d), TOBN(0x4d1531f6, 0xa5845601), + TOBN(0x792ab31e, 0x451fd9f0), TOBN(0xc8b57bb2, 0x65adf6ca), + TOBN(0x68440fcb, 0x1cd5ad73), TOBN(0xb9c860e6, 0x6144da4f), + TOBN(0x2ab286aa, 0x8462beb8), TOBN(0xcc6b8fff, 0xef46797f), + TOBN(0xac820da4, 0x20c8a471), TOBN(0x69ae05a1, 0x77ff7faf), + TOBN(0xb9163f39, 0xbfb5da77), TOBN(0xbd03e590, 0x2c73ab7a), + TOBN(0x7e862b5e, 0xb2940d9e), TOBN(0x3c663d86, 0x4b9af564), + TOBN(0xd8309031, 0xbde3033d), TOBN(0x298231b2, 0xd42c5bc6), + TOBN(0x42090d2c, 0x552ad093), TOBN(0xa4799d1c, 0xff854695), + TOBN(0x0a88b5d6, 0xd31f0d00), TOBN(0xf8b40825, 0xa2f26b46), + TOBN(0xec29b1ed, 0xf1bd7218), TOBN(0xd491c53b, 0x4b24c86e), + TOBN(0xd2fe588f, 0x3395ea65), TOBN(0x6f3764f7, 0x4456ef15), + TOBN(0xdb43116d, 0xcdc34800), TOBN(0xcdbcd456, 0xc1e33955), + TOBN(0xefdb5540, 0x74ab286b), TOBN(0x948c7a51, 0xd18c5d7c), + TOBN(0xeb81aa37, 0x7378058e), TOBN(0x41c746a1, 0x04411154), + TOBN(0xa10c73bc, 0xfb828ac7), TOBN(0x6439be91, 0x9d972b29), + TOBN(0x4bf3b4b0, 0x43a2fbad), TOBN(0x39e6dadf, 0x82b5e840), + TOBN(0x4f716408, 0x6397bd4c), TOBN(0x0f7de568, 0x7f1eeccb), + TOBN(0x5865c5a1, 0xd2ffbfc1), TOBN(0xf74211fa, 0x4ccb6451), + TOBN(0x66368a88, 0xc0b32558), TOBN(0x5b539dc2, 0x9ad7812e), + TOBN(0x579483d0, 0x2f3af6f6), TOBN(0x52132078, 0x99934ece), + TOBN(0x50b9650f, 0xdcc9e983), TOBN(0xca989ec9, 0xaee42b8a), + TOBN(0x6a44c829, 0xd6f62f99), TOBN(0x8f06a309, 0x4c2a7c0c), + TOBN(0x4ea2b3a0, 0x98a0cb0a), TOBN(0x5c547b70, 0xbeee8364), + TOBN(0x461d40e1, 0x682afe11), TOBN(0x9e0fc77a, 0x7b41c0a8), + TOBN(0x79e4aefd, 0xe20d5d36), TOBN(0x2916e520, 0x32dd9f63), + TOBN(0xf59e52e8, 0x3f883faf), TOBN(0x396f9639, 0x2b868d35), + TOBN(0xc902a9df, 0x4ca19881), TOBN(0x0fc96822, 0xdb2401a6), + TOBN(0x41237587, 0x66f1c68d), TOBN(0x10fc6de3, 0xfb476c0d), + TOBN(0xf8b6b579, 0x841f5d90), TOBN(0x2ba8446c, 0xfa24f44a), + TOBN(0xa237b920, 0xef4a9975), TOBN(0x60bb6004, 0x2330435f), + TOBN(0xd6f4ab5a, 0xcfb7e7b5), TOBN(0xb2ac5097, 0x83435391), + TOBN(0xf036ee2f, 0xb0d1ea67), TOBN(0xae779a6a, 0x74c56230), + TOBN(0x59bff8c8, 0xab838ae6), TOBN(0xcd83ca99, 0x9b38e6f0), + TOBN(0xbb27bef5, 0xe33deed3), TOBN(0xe6356f6f, 0x001892a8), + TOBN(0xbf3be6cc, 0x7adfbd3e), TOBN(0xaecbc81c, 0x33d1ac9d), + TOBN(0xe4feb909, 0xe6e861dc), TOBN(0x90a247a4, 0x53f5f801), + TOBN(0x01c50acb, 0x27346e57), TOBN(0xce29242e, 0x461acc1b), + TOBN(0x04dd214a, 0x2f998a91), TOBN(0x271ee9b1, 0xd4baf27b), + TOBN(0x7e3027d1, 0xe8c26722), TOBN(0x21d1645c, 0x1820dce5), + TOBN(0x086f242c, 0x7501779c), TOBN(0xf0061407, 0xfa0e8009), + TOBN(0xf23ce477, 0x60187129), TOBN(0x05bbdedb, 0x0fde9bd0), + TOBN(0x682f4832, 0x25d98473), TOBN(0xf207fe85, 0x5c658427), + TOBN(0xb6fdd7ba, 0x4166ffa1), TOBN(0x0c314056, 0x9eed799d), + TOBN(0x0db8048f, 0x4107e28f), TOBN(0x74ed3871, 0x41216840), + TOBN(0x74489f8f, 0x56a3c06e), TOBN(0x1e1c005b, 0x12777134), + TOBN(0xdb332a73, 0xf37ec3c3), TOBN(0xc65259bd, 0xdd59eba0), + TOBN(0x2291709c, 0xdb4d3257), TOBN(0x9a793b25, 0xbd389390), + TOBN(0xf39fe34b, 0xe43756f0), TOBN(0x2f76bdce, 0x9afb56c9), + TOBN(0x9f37867a, 0x61208b27), TOBN(0xea1d4307, 0x089972c3), + TOBN(0x8c595330, 0x8bdf623a), TOBN(0x5f5accda, 0x8441fb7d), + TOBN(0xfafa9418, 0x32ddfd95), TOBN(0x6ad40c5a, 0x0fde9be7), + TOBN(0x43faba89, 0xaeca8709), TOBN(0xc64a7cf1, 0x2c248a9d), + TOBN(0x16620252, 0x72637a76), TOBN(0xaee1c791, 0x22b8d1bb), + TOBN(0xf0f798fd, 0x21a843b2), TOBN(0x56e4ed4d, 0x8d005cb1), + TOBN(0x355f7780, 0x1f0d8abe), TOBN(0x197b04cf, 0x34522326), + TOBN(0x41f9b31f, 0xfd42c13f), TOBN(0x5ef7feb2, 0xb40f933d), + TOBN(0x27326f42, 0x5d60bad4), TOBN(0x027ecdb2, 0x8c92cf89), + TOBN(0x04aae4d1, 0x4e3352fe), TOBN(0x08414d2f, 0x73591b90), + TOBN(0x5ed6124e, 0xb7da7d60), TOBN(0xb985b931, 0x4d13d4ec), + TOBN(0xa592d3ab, 0x96bf36f9), TOBN(0x012dbed5, 0xbbdf51df), + TOBN(0xa57963c0, 0xdf6c177d), TOBN(0x010ec869, 0x87ca29cf), + TOBN(0xba1700f6, 0xbf926dff), TOBN(0x7c9fdbd1, 0xf4bf6bc2), + TOBN(0xdc18dc8f, 0x64da11f5), TOBN(0xa6074b7a, 0xd938ae75), + TOBN(0x14270066, 0xe84f44a4), TOBN(0x99998d38, 0xd27b954e), + TOBN(0xc1be8ab2, 0xb4f38e9a), TOBN(0x8bb55bbf, 0x15c01016), + TOBN(0xf73472b4, 0x0ea2ab30), TOBN(0xd365a340, 0xf73d68dd), + TOBN(0xc01a7168, 0x19c2e1eb), TOBN(0x32f49e37, 0x34061719), + TOBN(0xb73c57f1, 0x01d8b4d6), TOBN(0x03c8423c, 0x26b47700), + TOBN(0x321d0bc8, 0xa4d8826a), TOBN(0x6004213c, 0x4bc0e638), + TOBN(0xf78c64a1, 0xc1c06681), TOBN(0x16e0a16f, 0xef018e50), + TOBN(0x31cbdf91, 0xdb42b2b3), TOBN(0xf8f4ffce, 0xe0d36f58), + TOBN(0xcdcc71cd, 0x4cc5e3e0), TOBN(0xd55c7cfa, 0xa129e3e0), + TOBN(0xccdb6ba0, 0x0fb2cbf1), TOBN(0x6aba0005, 0xc4bce3cb), + TOBN(0x501cdb30, 0xd232cfc4), TOBN(0x9ddcf12e, 0xd58a3cef), + TOBN(0x02d2cf9c, 0x87e09149), TOBN(0xdc5d7ec7, 0x2c976257), + TOBN(0x6447986e, 0x0b50d7dd), TOBN(0x88fdbaf7, 0x807f112a), + TOBN(0x58c9822a, 0xb00ae9f6), TOBN(0x6abfb950, 0x6d3d27e0), + TOBN(0xd0a74487, 0x8a429f4f), TOBN(0x0649712b, 0xdb516609), + TOBN(0xb826ba57, 0xe769b5df), TOBN(0x82335df2, 0x1fc7aaf2), + TOBN(0x2389f067, 0x5c93d995), TOBN(0x59ac367a, 0x68677be6), + TOBN(0xa77985ff, 0x21d9951b), TOBN(0x038956fb, 0x85011cce), + TOBN(0x608e48cb, 0xbb734e37), TOBN(0xc08c0bf2, 0x2be5b26f), + TOBN(0x17bbdd3b, 0xf9b1a0d9), TOBN(0xeac7d898, 0x10483319), + TOBN(0xc95c4baf, 0xbc1a6dea), TOBN(0xfdd0e2bf, 0x172aafdb), + TOBN(0x40373cbc, 0x8235c41a), TOBN(0x14303f21, 0xfb6f41d5), + TOBN(0xba063621, 0x0408f237), TOBN(0xcad3b09a, 0xecd2d1ed), + TOBN(0x4667855a, 0x52abb6a2), TOBN(0xba9157dc, 0xaa8b417b), + TOBN(0xfe7f3507, 0x4f013efb), TOBN(0x1b112c4b, 0xaa38c4a2), + TOBN(0xa1406a60, 0x9ba64345), TOBN(0xe53cba33, 0x6993c80b), + TOBN(0x45466063, 0xded40d23), TOBN(0x3d5f1f4d, 0x54908e25), + TOBN(0x9ebefe62, 0x403c3c31), TOBN(0x274ea0b5, 0x0672a624), + TOBN(0xff818d99, 0x451d1b71), TOBN(0x80e82643, 0x8f79cf79), + TOBN(0xa165df13, 0x73ce37f5), TOBN(0xa744ef4f, 0xfe3a21fd), + TOBN(0x73f1e7f5, 0xcf551396), TOBN(0xc616898e, 0x868c676b), + TOBN(0x671c28c7, 0x8c442c36), TOBN(0xcfe5e558, 0x5e0a317d), + TOBN(0x1242d818, 0x7051f476), TOBN(0x56fad2a6, 0x14f03442), + TOBN(0x262068bc, 0x0a44d0f6), TOBN(0xdfa2cd6e, 0xce6edf4e), + TOBN(0x0f43813a, 0xd15d1517), TOBN(0x61214cb2, 0x377d44f5), + TOBN(0xd399aa29, 0xc639b35f), TOBN(0x42136d71, 0x54c51c19), + TOBN(0x9774711b, 0x08417221), TOBN(0x0a5546b3, 0x52545a57), + TOBN(0x80624c41, 0x1150582d), TOBN(0x9ec5c418, 0xfbc555bc), + TOBN(0x2c87dcad, 0x771849f1), TOBN(0xb0c932c5, 0x01d7bf6f), + TOBN(0x6aa5cd3e, 0x89116eb2), TOBN(0xd378c25a, 0x51ca7bd3), + TOBN(0xc612a0da, 0x9e6e3e31), TOBN(0x0417a54d, 0xb68ad5d0), + TOBN(0x00451e4a, 0x22c6edb8), TOBN(0x9fbfe019, 0xb42827ce), + TOBN(0x2fa92505, 0xba9384a2), TOBN(0x21b8596e, 0x64ad69c1), + TOBN(0x8f4fcc49, 0x983b35a6), TOBN(0xde093760, 0x72754672), + TOBN(0x2f14ccc8, 0xf7bffe6d), TOBN(0x27566bff, 0x5d94263d), + TOBN(0xb5b4e9c6, 0x2df3ec30), TOBN(0x94f1d7d5, 0x3e6ea6ba), + TOBN(0x97b7851a, 0xaaca5e9b), TOBN(0x518aa521, 0x56713b97), + TOBN(0x3357e8c7, 0x150a61f6), TOBN(0x7842e7e2, 0xec2c2b69), + TOBN(0x8dffaf65, 0x6868a548), TOBN(0xd963bd82, 0xe068fc81), + TOBN(0x64da5c8b, 0x65917733), TOBN(0x927090ff, 0x7b247328)}, + {TOBN(0x214bc9a7, 0xd298c241), TOBN(0xe3b697ba, 0x56807cfd), + TOBN(0xef1c7802, 0x4564eadb), TOBN(0xdde8cdcf, 0xb48149c5), + TOBN(0x946bf0a7, 0x5a4d2604), TOBN(0x27154d7f, 0x6c1538af), + TOBN(0x95cc9230, 0xde5b1fcc), TOBN(0xd88519e9, 0x66864f82), + TOBN(0xb828dd1a, 0x7cb1282c), TOBN(0xa08d7626, 0xbe46973a), + TOBN(0x6baf8d40, 0xe708d6b2), TOBN(0x72571fa1, 0x4daeb3f3), + TOBN(0x85b1732f, 0xf22dfd98), TOBN(0x87ab01a7, 0x0087108d), + TOBN(0xaaaafea8, 0x5988207a), TOBN(0xccc832f8, 0x69f00755), + TOBN(0x964d950e, 0x36ff3bf0), TOBN(0x8ad20f6f, 0xf0b34638), + TOBN(0x4d9177b3, 0xb5d7585f), TOBN(0xcf839760, 0xef3f019f), + TOBN(0x582fc5b3, 0x8288c545), TOBN(0x2f8e4e9b, 0x13116bd1), + TOBN(0xf91e1b2f, 0x332120ef), TOBN(0xcf568724, 0x2a17dd23), + TOBN(0x488f1185, 0xca8d9d1a), TOBN(0xadf2c77d, 0xd987ded2), + TOBN(0x5f3039f0, 0x60c46124), TOBN(0xe5d70b75, 0x71e095f4), + TOBN(0x82d58650, 0x6260e70f), TOBN(0x39d75ea7, 0xf750d105), + TOBN(0x8cf3d0b1, 0x75bac364), TOBN(0xf3a7564d, 0x21d01329), + TOBN(0x182f04cd, 0x2f52d2a7), TOBN(0x4fde149a, 0xe2df565a), + TOBN(0xb80c5eec, 0xa79fb2f7), TOBN(0xab491d7b, 0x22ddc897), + TOBN(0x99d76c18, 0xc6312c7f), TOBN(0xca0d5f3d, 0x6aa41a57), + TOBN(0x71207325, 0xd15363a0), TOBN(0xe82aa265, 0xbeb252c2), + TOBN(0x94ab4700, 0xec3128c2), TOBN(0x6c76d862, 0x8e383f49), + TOBN(0xdc36b150, 0xc03024eb), TOBN(0xfb439477, 0x53daac69), + TOBN(0xfc68764a, 0x8dc79623), TOBN(0x5b86995d, 0xb440fbb2), + TOBN(0xd66879bf, 0xccc5ee0d), TOBN(0x05228942, 0x95aa8bd3), + TOBN(0xb51a40a5, 0x1e6a75c1), TOBN(0x24327c76, 0x0ea7d817), + TOBN(0x06630182, 0x07774597), TOBN(0xd6fdbec3, 0x97fa7164), + TOBN(0x20c99dfb, 0x13c90f48), TOBN(0xd6ac5273, 0x686ef263), + TOBN(0xc6a50bdc, 0xfef64eeb), TOBN(0xcd87b281, 0x86fdfc32), + TOBN(0xb24aa43e, 0x3fcd3efc), TOBN(0xdd26c034, 0xb8088e9a), + TOBN(0xa5ef4dc9, 0xbd3d46ea), TOBN(0xa2f99d58, 0x8a4c6a6f), + TOBN(0xddabd355, 0x2f1da46c), TOBN(0x72c3f8ce, 0x1afacdd1), + TOBN(0xd90c4eee, 0x92d40578), TOBN(0xd28bb41f, 0xca623b94), + TOBN(0x50fc0711, 0x745edc11), TOBN(0x9dd9ad7d, 0x3dc87558), + TOBN(0xce6931fb, 0xb49d1e64), TOBN(0x6c77a0a2, 0xc98bd0f9), + TOBN(0x62b9a629, 0x6baf7cb1), TOBN(0xcf065f91, 0xccf72d22), + TOBN(0x7203cce9, 0x79639071), TOBN(0x09ae4885, 0xf9cb732f), + TOBN(0x5e7c3bec, 0xee8314f3), TOBN(0x1c068aed, 0xdbea298f), + TOBN(0x08d381f1, 0x7c80acec), TOBN(0x03b56be8, 0xe330495b), + TOBN(0xaeffb8f2, 0x9222882d), TOBN(0x95ff38f6, 0xc4af8bf7), + TOBN(0x50e32d35, 0x1fc57d8c), TOBN(0x6635be52, 0x17b444f0), + TOBN(0x04d15276, 0xa5177900), TOBN(0x4e1dbb47, 0xf6858752), + TOBN(0x5b475622, 0xc615796c), TOBN(0xa6fa0387, 0x691867bf), + TOBN(0xed7f5d56, 0x2844c6d0), TOBN(0xc633cf9b, 0x03a2477d), + TOBN(0xf6be5c40, 0x2d3721d6), TOBN(0xaf312eb7, 0xe9fd68e6), + TOBN(0x242792d2, 0xe7417ce1), TOBN(0xff42bc71, 0x970ee7f5), + TOBN(0x1ff4dc6d, 0x5c67a41e), TOBN(0x77709b7b, 0x20882a58), + TOBN(0x3554731d, 0xbe217f2c), TOBN(0x2af2a8cd, 0x5bb72177), + TOBN(0x58eee769, 0x591dd059), TOBN(0xbb2930c9, 0x4bba6477), + TOBN(0x863ee047, 0x7d930cfc), TOBN(0x4c262ad1, 0x396fd1f4), + TOBN(0xf4765bc8, 0x039af7e1), TOBN(0x2519834b, 0x5ba104f6), + TOBN(0x7cd61b4c, 0xd105f961), TOBN(0xa5415da5, 0xd63bca54), + TOBN(0x778280a0, 0x88a1f17c), TOBN(0xc4968949, 0x2329512c), + TOBN(0x174a9126, 0xcecdaa7a), TOBN(0xfc8c7e0e, 0x0b13247b), + TOBN(0x29c110d2, 0x3484c1c4), TOBN(0xf8eb8757, 0x831dfc3b), + TOBN(0x022f0212, 0xc0067452), TOBN(0x3f6f69ee, 0x7b9b926c), + TOBN(0x09032da0, 0xef42daf4), TOBN(0x79f00ade, 0x83f80de4), + TOBN(0x6210db71, 0x81236c97), TOBN(0x74f7685b, 0x3ee0781f), + TOBN(0x4df7da7b, 0xa3e41372), TOBN(0x2aae38b1, 0xb1a1553e), + TOBN(0x1688e222, 0xf6dd9d1b), TOBN(0x57695448, 0x5b8b6487), + TOBN(0x478d2127, 0x4b2edeaa), TOBN(0xb2818fa5, 0x1e85956a), + TOBN(0x1e6addda, 0xf176f2c0), TOBN(0x01ca4604, 0xe2572658), + TOBN(0x0a404ded, 0x85342ffb), TOBN(0x8cf60f96, 0x441838d6), + TOBN(0x9bbc691c, 0xc9071c4a), TOBN(0xfd588744, 0x34442803), + TOBN(0x97101c85, 0x809c0d81), TOBN(0xa7fb754c, 0x8c456f7f), + TOBN(0xc95f3c5c, 0xd51805e1), TOBN(0xab4ccd39, 0xb299dca8), + TOBN(0x3e03d20b, 0x47eaf500), TOBN(0xfa3165c1, 0xd7b80893), + TOBN(0x005e8b54, 0xe160e552), TOBN(0xdc4972ba, 0x9019d11f), + TOBN(0x21a6972e, 0x0c9a4a7a), TOBN(0xa52c258f, 0x37840fd7), + TOBN(0xf8559ff4, 0xc1e99d81), TOBN(0x08e1a7d6, 0xa3c617c0), + TOBN(0xb398fd43, 0x248c6ba7), TOBN(0x6ffedd91, 0xd1283794), + TOBN(0x8a6a59d2, 0xd629d208), TOBN(0xa9d141d5, 0x3490530e), + TOBN(0x42f6fc18, 0x38505989), TOBN(0x09bf250d, 0x479d94ee), + TOBN(0x223ad3b1, 0xb3822790), TOBN(0x6c5926c0, 0x93b8971c), + TOBN(0x609efc7e, 0x75f7fa62), TOBN(0x45d66a6d, 0x1ec2d989), + TOBN(0x4422d663, 0x987d2792), TOBN(0x4a73caad, 0x3eb31d2b), + TOBN(0xf06c2ac1, 0xa32cb9e6), TOBN(0xd9445c5f, 0x91aeba84), + TOBN(0x6af7a1d5, 0xaf71013f), TOBN(0xe68216e5, 0x0bedc946), + TOBN(0xf4cba30b, 0xd27370a0), TOBN(0x7981afbf, 0x870421cc), + TOBN(0x02496a67, 0x9449f0e1), TOBN(0x86cfc4be, 0x0a47edae), + TOBN(0x3073c936, 0xb1feca22), TOBN(0xf5694612, 0x03f8f8fb), + TOBN(0xd063b723, 0x901515ea), TOBN(0x4c6c77a5, 0x749cf038), + TOBN(0x6361e360, 0xab9e5059), TOBN(0x596cf171, 0xa76a37c0), + TOBN(0x800f53fa, 0x6530ae7a), TOBN(0x0f5e631e, 0x0792a7a6), + TOBN(0x5cc29c24, 0xefdb81c9), TOBN(0xa269e868, 0x3f9c40ba), + TOBN(0xec14f9e1, 0x2cb7191e), TOBN(0x78ea1bd8, 0xe5b08ea6), + TOBN(0x3c65aa9b, 0x46332bb9), TOBN(0x84cc22b3, 0xbf80ce25), + TOBN(0x0098e9e9, 0xd49d5bf1), TOBN(0xcd4ec1c6, 0x19087da4), + TOBN(0x3c9d07c5, 0xaef6e357), TOBN(0x839a0268, 0x9f8f64b8), + TOBN(0xc5e9eb62, 0xc6d8607f), TOBN(0x759689f5, 0x6aa995e4), + TOBN(0x70464669, 0xbbb48317), TOBN(0x921474bf, 0xe402417d), + TOBN(0xcabe135b, 0x2a354c8c), TOBN(0xd51e52d2, 0x812fa4b5), + TOBN(0xec741096, 0x53311fe8), TOBN(0x4f774535, 0xb864514b), + TOBN(0xbcadd671, 0x5bde48f8), TOBN(0xc9703873, 0x2189bc7d), + TOBN(0x5d45299e, 0xc709ee8a), TOBN(0xd1287ee2, 0x845aaff8), + TOBN(0x7d1f8874, 0xdb1dbf1f), TOBN(0xea46588b, 0x990c88d6), + TOBN(0x60ba649a, 0x84368313), TOBN(0xd5fdcbce, 0x60d543ae), + TOBN(0x90b46d43, 0x810d5ab0), TOBN(0x6739d8f9, 0x04d7e5cc), + TOBN(0x021c1a58, 0x0d337c33), TOBN(0x00a61162, 0x68e67c40), + TOBN(0x95ef413b, 0x379f0a1f), TOBN(0xfe126605, 0xe9e2ab95), + TOBN(0x67578b85, 0x2f5f199c), TOBN(0xf5c00329, 0x2cb84913), + TOBN(0xf7956430, 0x37577dd8), TOBN(0x83b82af4, 0x29c5fe88), + TOBN(0x9c1bea26, 0xcdbdc132), TOBN(0x589fa086, 0x9c04339e), + TOBN(0x033e9538, 0xb13799df), TOBN(0x85fa8b21, 0xd295d034), + TOBN(0xdf17f73f, 0xbd9ddcca), TOBN(0xf32bd122, 0xddb66334), + TOBN(0x55ef88a7, 0x858b044c), TOBN(0x1f0d69c2, 0x5aa9e397), + TOBN(0x55fd9cc3, 0x40d85559), TOBN(0xc774df72, 0x7785ddb2), + TOBN(0x5dcce9f6, 0xd3bd2e1c), TOBN(0xeb30da20, 0xa85dfed0), + TOBN(0x5ed7f5bb, 0xd3ed09c4), TOBN(0x7d42a35c, 0x82a9c1bd), + TOBN(0xcf3de995, 0x9890272d), TOBN(0x75f3432a, 0x3e713a10), + TOBN(0x5e13479f, 0xe28227b8), TOBN(0xb8561ea9, 0xfefacdc8), + TOBN(0xa6a297a0, 0x8332aafd), TOBN(0x9b0d8bb5, 0x73809b62), + TOBN(0xd2fa1cfd, 0x0c63036f), TOBN(0x7a16eb55, 0xbd64bda8), + TOBN(0x3f5cf5f6, 0x78e62ddc), TOBN(0x2267c454, 0x07fd752b), + TOBN(0x5e361b6b, 0x5e437bbe), TOBN(0x95c59501, 0x8354e075), + TOBN(0xec725f85, 0xf2b254d9), TOBN(0x844b617d, 0x2cb52b4e), + TOBN(0xed8554f5, 0xcf425fb5), TOBN(0xab67703e, 0x2af9f312), + TOBN(0x4cc34ec1, 0x3cf48283), TOBN(0xb09daa25, 0x9c8a705e), + TOBN(0xd1e9d0d0, 0x5b7d4f84), TOBN(0x4df6ef64, 0xdb38929d), + TOBN(0xe16b0763, 0xaa21ba46), TOBN(0xc6b1d178, 0xa293f8fb), + TOBN(0x0ff5b602, 0xd520aabf), TOBN(0x94d671bd, 0xc339397a), + TOBN(0x7c7d98cf, 0x4f5792fa), TOBN(0x7c5e0d67, 0x11215261), + TOBN(0x9b19a631, 0xa7c5a6d4), TOBN(0xc8511a62, 0x7a45274d), + TOBN(0x0c16621c, 0xa5a60d99), TOBN(0xf7fbab88, 0xcf5e48cb), + TOBN(0xab1e6ca2, 0xf7ddee08), TOBN(0x83bd08ce, 0xe7867f3c), + TOBN(0xf7e48e8a, 0x2ac13e27), TOBN(0x4494f6df, 0x4eb1a9f5), + TOBN(0xedbf84eb, 0x981f0a62), TOBN(0x49badc32, 0x536438f0), + TOBN(0x50bea541, 0x004f7571), TOBN(0xbac67d10, 0xdf1c94ee), + TOBN(0x253d73a1, 0xb727bc31), TOBN(0xb3d01cf2, 0x30686e28), + TOBN(0x51b77b1b, 0x55fd0b8b), TOBN(0xa099d183, 0xfeec3173), + TOBN(0x202b1fb7, 0x670e72b7), TOBN(0xadc88b33, 0xa8e1635f), + TOBN(0x34e8216a, 0xf989d905), TOBN(0xc2e68d20, 0x29b58d01), + TOBN(0x11f81c92, 0x6fe55a93), TOBN(0x15f1462a, 0x8f296f40), + TOBN(0x1915d375, 0xea3d62f2), TOBN(0xa17765a3, 0x01c8977d), + TOBN(0x7559710a, 0xe47b26f6), TOBN(0xe0bd29c8, 0x535077a5), + TOBN(0x615f976d, 0x08d84858), TOBN(0x370dfe85, 0x69ced5c1), + TOBN(0xbbc7503c, 0xa734fa56), TOBN(0xfbb9f1ec, 0x91ac4574), + TOBN(0x95d7ec53, 0x060dd7ef), TOBN(0xeef2dacd, 0x6e657979), + TOBN(0x54511af3, 0xe2a08235), TOBN(0x1e324aa4, 0x1f4aea3d), + TOBN(0x550e7e71, 0xe6e67671), TOBN(0xbccd5190, 0xbf52faf7), + TOBN(0xf880d316, 0x223cc62a), TOBN(0x0d402c7e, 0x2b32eb5d), + TOBN(0xa40bc039, 0x306a5a3b), TOBN(0x4e0a41fd, 0x96783a1b), + TOBN(0xa1e8d39a, 0x0253cdd4), TOBN(0x6480be26, 0xc7388638), + TOBN(0xee365e1d, 0x2285f382), TOBN(0x188d8d8f, 0xec0b5c36), + TOBN(0x34ef1a48, 0x1f0f4d82), TOBN(0x1a8f43e1, 0xa487d29a), + TOBN(0x8168226d, 0x77aefb3a), TOBN(0xf69a751e, 0x1e72c253), + TOBN(0x8e04359a, 0xe9594df1), TOBN(0x475ffd7d, 0xd14c0467), + TOBN(0xb5a2c2b1, 0x3844e95c), TOBN(0x85caf647, 0xdd12ef94), + TOBN(0x1ecd2a9f, 0xf1063d00), TOBN(0x1dd2e229, 0x23843311), + TOBN(0x38f0e09d, 0x73d17244), TOBN(0x3ede7746, 0x8fc653f1), + TOBN(0xae4459f5, 0xdc20e21c), TOBN(0x00db2ffa, 0x6a8599ea), + TOBN(0x11682c39, 0x30cfd905), TOBN(0x4934d074, 0xa5c112a6), + TOBN(0xbdf063c5, 0x568bfe95), TOBN(0x779a440a, 0x016c441a), + TOBN(0x0c23f218, 0x97d6fbdc), TOBN(0xd3a5cd87, 0xe0776aac), + TOBN(0xcee37f72, 0xd712e8db), TOBN(0xfb28c70d, 0x26f74e8d), + TOBN(0xffe0c728, 0xb61301a0), TOBN(0xa6282168, 0xd3724354), + TOBN(0x7ff4cb00, 0x768ffedc), TOBN(0xc51b3088, 0x03b02de9), + TOBN(0xa5a8147c, 0x3902dda5), TOBN(0x35d2f706, 0xfe6973b4), + TOBN(0x5ac2efcf, 0xc257457e), TOBN(0x933f48d4, 0x8700611b), + TOBN(0xc365af88, 0x4912beb2), TOBN(0x7f5a4de6, 0x162edf94), + TOBN(0xc646ba7c, 0x0c32f34b), TOBN(0x632c6af3, 0xb2091074), + TOBN(0x58d4f2e3, 0x753e43a9), TOBN(0x70e1d217, 0x24d4e23f), + TOBN(0xb24bf729, 0xafede6a6), TOBN(0x7f4a94d8, 0x710c8b60), + TOBN(0xaad90a96, 0x8d4faa6a), TOBN(0xd9ed0b32, 0xb066b690), + TOBN(0x52fcd37b, 0x78b6dbfd), TOBN(0x0b64615e, 0x8bd2b431), + TOBN(0x228e2048, 0xcfb9fad5), TOBN(0xbeaa386d, 0x240b76bd), + TOBN(0x2d6681c8, 0x90dad7bc), TOBN(0x3e553fc3, 0x06d38f5e), + TOBN(0xf27cdb9b, 0x9d5f9750), TOBN(0x3e85c52a, 0xd28c5b0e), + TOBN(0x190795af, 0x5247c39b), TOBN(0x547831eb, 0xbddd6828), + TOBN(0xf327a227, 0x4a82f424), TOBN(0x36919c78, 0x7e47f89d), + TOBN(0xe4783919, 0x43c7392c), TOBN(0xf101b9aa, 0x2316fefe), + TOBN(0xbcdc9e9c, 0x1c5009d2), TOBN(0xfb55ea13, 0x9cd18345), + TOBN(0xf5b5e231, 0xa3ce77c7), TOBN(0xde6b4527, 0xd2f2cb3d), + TOBN(0x10f6a333, 0x9bb26f5f), TOBN(0x1e85db8e, 0x044d85b6), + TOBN(0xc3697a08, 0x94197e54), TOBN(0x65e18cc0, 0xa7cb4ea8), + TOBN(0xa38c4f50, 0xa471fe6e), TOBN(0xf031747a, 0x2f13439c), + TOBN(0x53c4a6ba, 0xc007318b), TOBN(0xa8da3ee5, 0x1deccb3d), + TOBN(0x0555b31c, 0x558216b1), TOBN(0x90c7810c, 0x2f79e6c2), + TOBN(0x9b669f4d, 0xfe8eed3c), TOBN(0x70398ec8, 0xe0fac126), + TOBN(0xa96a449e, 0xf701b235), TOBN(0x0ceecdb3, 0xeb94f395), + TOBN(0x285fc368, 0xd0cb7431), TOBN(0x0d37bb52, 0x16a18c64), + TOBN(0x05110d38, 0xb880d2dd), TOBN(0xa60f177b, 0x65930d57), + TOBN(0x7da34a67, 0xf36235f5), TOBN(0x47f5e17c, 0x183816b9), + TOBN(0xc7664b57, 0xdb394af4), TOBN(0x39ba215d, 0x7036f789), + TOBN(0x46d2ca0e, 0x2f27b472), TOBN(0xc42647ee, 0xf73a84b7), + TOBN(0x44bc7545, 0x64488f1d), TOBN(0xaa922708, 0xf4cf85d5), + TOBN(0x721a01d5, 0x53e4df63), TOBN(0x649c0c51, 0x5db46ced), + TOBN(0x6bf0d64e, 0x3cffcb6c), TOBN(0xe3bf93fe, 0x50f71d96), + TOBN(0x75044558, 0xbcc194a0), TOBN(0x16ae3372, 0x6afdc554), + TOBN(0xbfc01adf, 0x5ca48f3f), TOBN(0x64352f06, 0xe22a9b84), + TOBN(0xcee54da1, 0xc1099e4a), TOBN(0xbbda54e8, 0xfa1b89c0), + TOBN(0x166a3df5, 0x6f6e55fb), TOBN(0x1ca44a24, 0x20176f88), + TOBN(0x936afd88, 0xdfb7b5ff), TOBN(0xe34c2437, 0x8611d4a0), + TOBN(0x7effbb75, 0x86142103), TOBN(0x6704ba1b, 0x1f34fc4d), + TOBN(0x7c2a468f, 0x10c1b122), TOBN(0x36b3a610, 0x8c6aace9), + TOBN(0xabfcc0a7, 0x75a0d050), TOBN(0x066f9197, 0x3ce33e32), + TOBN(0xce905ef4, 0x29fe09be), TOBN(0x89ee25ba, 0xa8376351), + TOBN(0x2a3ede22, 0xfd29dc76), TOBN(0x7fd32ed9, 0x36f17260), + TOBN(0x0cadcf68, 0x284b4126), TOBN(0x63422f08, 0xa7951fc8), + TOBN(0x562b24f4, 0x0807e199), TOBN(0xfe9ce5d1, 0x22ad4490), + TOBN(0xc2f51b10, 0x0db2b1b4), TOBN(0xeb3613ff, 0xe4541d0d), + TOBN(0xbd2c4a05, 0x2680813b), TOBN(0x527aa55d, 0x561b08d6), + TOBN(0xa9f8a40e, 0xa7205558), TOBN(0xe3eea56f, 0x243d0bec), + TOBN(0x7b853817, 0xa0ff58b3), TOBN(0xb67d3f65, 0x1a69e627), + TOBN(0x0b76bbb9, 0xa869b5d6), TOBN(0xa3afeb82, 0x546723ed), + TOBN(0x5f24416d, 0x3e554892), TOBN(0x8413b53d, 0x430e2a45), + TOBN(0x99c56aee, 0x9032a2a0), TOBN(0x09432bf6, 0xeec367b1), + TOBN(0x552850c6, 0xdaf0ecc1), TOBN(0x49ebce55, 0x5bc92048), + TOBN(0xdfb66ba6, 0x54811307), TOBN(0x1b84f797, 0x6f298597), + TOBN(0x79590481, 0x8d1d7a0d), TOBN(0xd9fabe03, 0x3a6fa556), + TOBN(0xa40f9c59, 0xba9e5d35), TOBN(0xcb1771c1, 0xf6247577), + TOBN(0x542a47ca, 0xe9a6312b), TOBN(0xa34b3560, 0x552dd8c5), + TOBN(0xfdf94de0, 0x0d794716), TOBN(0xd46124a9, 0x9c623094), + TOBN(0x56b7435d, 0x68afe8b4), TOBN(0x27f20540, 0x6c0d8ea1), + TOBN(0x12b77e14, 0x73186898), TOBN(0xdbc3dd46, 0x7479490f), + TOBN(0x951a9842, 0xc03b0c05), TOBN(0x8b1b3bb3, 0x7921bc96), + TOBN(0xa573b346, 0x2b202e0a), TOBN(0x77e4665d, 0x47254d56), + TOBN(0x08b70dfc, 0xd23e3984), TOBN(0xab86e8bc, 0xebd14236), + TOBN(0xaa3e07f8, 0x57114ba7), TOBN(0x5ac71689, 0xab0ef4f2), + TOBN(0x88fca384, 0x0139d9af), TOBN(0x72733f88, 0x76644af0), + TOBN(0xf122f72a, 0x65d74f4a), TOBN(0x13931577, 0xa5626c7a), + TOBN(0xd5b5d9eb, 0x70f8d5a4), TOBN(0x375adde7, 0xd7bbb228), + TOBN(0x31e88b86, 0x0c1c0b32), TOBN(0xd1f568c4, 0x173edbaa), + TOBN(0x1592fc83, 0x5459df02), TOBN(0x2beac0fb, 0x0fcd9a7e), + TOBN(0xb0a6fdb8, 0x1b473b0a), TOBN(0xe3224c6f, 0x0fe8fc48), + TOBN(0x680bd00e, 0xe87edf5b), TOBN(0x30385f02, 0x20e77cf5), + TOBN(0xe9ab98c0, 0x4d42d1b2), TOBN(0x72d191d2, 0xd3816d77), + TOBN(0x1564daca, 0x0917d9e5), TOBN(0x394eab59, 0x1f8fed7f), + TOBN(0xa209aa8d, 0x7fbb3896), TOBN(0x5564f3b9, 0xbe6ac98e), + TOBN(0xead21d05, 0xd73654ef), TOBN(0x68d1a9c4, 0x13d78d74), + TOBN(0x61e01708, 0x6d4973a0), TOBN(0x83da3500, 0x46e6d32a), + TOBN(0x6a3dfca4, 0x68ae0118), TOBN(0xa1b9a4c9, 0xd02da069), + TOBN(0x0b2ff9c7, 0xebab8302), TOBN(0x98af07c3, 0x944ba436), + TOBN(0x85997326, 0x995f0f9f), TOBN(0x467fade0, 0x71b58bc6), + TOBN(0x47e4495a, 0xbd625a2b), TOBN(0xfdd2d01d, 0x33c3b8cd), + TOBN(0x2c38ae28, 0xc693f9fa), TOBN(0x48622329, 0x348f7999), + TOBN(0x97bf738e, 0x2161f583), TOBN(0x15ee2fa7, 0x565e8cc9), + TOBN(0xa1a5c845, 0x5777e189), TOBN(0xcc10bee0, 0x456f2829), + TOBN(0x8ad95c56, 0xda762bd5), TOBN(0x152e2214, 0xe9d91da8), + TOBN(0x975b0e72, 0x7cb23c74), TOBN(0xfd5d7670, 0xa90c66df), + TOBN(0xb5b5b8ad, 0x225ffc53), TOBN(0xab6dff73, 0xfaded2ae), + TOBN(0xebd56781, 0x6f4cbe9d), TOBN(0x0ed8b249, 0x6a574bd7), + TOBN(0x41c246fe, 0x81a881fa), TOBN(0x91564805, 0xc3db9c70), + TOBN(0xd7c12b08, 0x5b862809), TOBN(0x1facd1f1, 0x55858d7b), + TOBN(0x7693747c, 0xaf09e92a), TOBN(0x3b69dcba, 0x189a425f), + TOBN(0x0be28e9f, 0x967365ef), TOBN(0x57300eb2, 0xe801f5c9), + TOBN(0x93b8ac6a, 0xd583352f), TOBN(0xa2cf1f89, 0xcd05b2b7), + TOBN(0x7c0c9b74, 0x4dcc40cc), TOBN(0xfee38c45, 0xada523fb), + TOBN(0xb49a4dec, 0x1099cc4d), TOBN(0x325c377f, 0x69f069c6), + TOBN(0xe12458ce, 0x476cc9ff), TOBN(0x580e0b6c, 0xc6d4cb63), + TOBN(0xd561c8b7, 0x9072289b), TOBN(0x0377f264, 0xa619e6da), + TOBN(0x26685362, 0x88e591a5), TOBN(0xa453a7bd, 0x7523ca2b), + TOBN(0x8a9536d2, 0xc1df4533), TOBN(0xc8e50f2f, 0xbe972f79), + TOBN(0xd433e50f, 0x6d3549cf), TOBN(0x6f33696f, 0xfacd665e), + TOBN(0x695bfdac, 0xce11fcb4), TOBN(0x810ee252, 0xaf7c9860), + TOBN(0x65450fe1, 0x7159bb2c), TOBN(0xf7dfbebe, 0x758b357b), + TOBN(0x2b057e74, 0xd69fea72), TOBN(0xd485717a, 0x92731745)}, + {TOBN(0x896c42e8, 0xee36860c), TOBN(0xdaf04dfd, 0x4113c22d), + TOBN(0x1adbb7b7, 0x44104213), TOBN(0xe5fd5fa1, 0x1fd394ea), + TOBN(0x68235d94, 0x1a4e0551), TOBN(0x6772cfbe, 0x18d10151), + TOBN(0x276071e3, 0x09984523), TOBN(0xe4e879de, 0x5a56ba98), + TOBN(0xaaafafb0, 0x285b9491), TOBN(0x01a0be88, 0x1e4c705e), + TOBN(0xff1d4f5d, 0x2ad9caab), TOBN(0x6e349a4a, 0xc37a233f), + TOBN(0xcf1c1246, 0x4a1c6a16), TOBN(0xd99e6b66, 0x29383260), + TOBN(0xea3d4366, 0x5f6d5471), TOBN(0x36974d04, 0xff8cc89b), + TOBN(0xc26c49a1, 0xcfe89d80), TOBN(0xb42c026d, 0xda9c8371), + TOBN(0xca6c013a, 0xdad066d2), TOBN(0xfb8f7228, 0x56a4f3ee), + TOBN(0x08b579ec, 0xd850935b), TOBN(0x34c1a74c, 0xd631e1b3), + TOBN(0xcb5fe596, 0xac198534), TOBN(0x39ff21f6, 0xe1f24f25), + TOBN(0x27f29e14, 0x8f929057), TOBN(0x7a64ae06, 0xc0c853df), + TOBN(0x256cd183, 0x58e9c5ce), TOBN(0x9d9cce82, 0xded092a5), + TOBN(0xcc6e5979, 0x6e93b7c7), TOBN(0xe1e47092, 0x31bb9e27), + TOBN(0xb70b3083, 0xaa9e29a0), TOBN(0xbf181a75, 0x3785e644), + TOBN(0xf53f2c65, 0x8ead09f7), TOBN(0x1335e1d5, 0x9780d14d), + TOBN(0x69cc20e0, 0xcd1b66bc), TOBN(0x9b670a37, 0xbbe0bfc8), + TOBN(0xce53dc81, 0x28efbeed), TOBN(0x0c74e77c, 0x8326a6e5), + TOBN(0x3604e0d2, 0xb88e9a63), TOBN(0xbab38fca, 0x13dc2248), + TOBN(0x8ed6e8c8, 0x5c0a3f1e), TOBN(0xbcad2492, 0x7c87c37f), + TOBN(0xfdfb62bb, 0x9ee3b78d), TOBN(0xeba8e477, 0xcbceba46), + TOBN(0x37d38cb0, 0xeeaede4b), TOBN(0x0bc498e8, 0x7976deb6), + TOBN(0xb2944c04, 0x6b6147fb), TOBN(0x8b123f35, 0xf71f9609), + TOBN(0xa155dcc7, 0xde79dc24), TOBN(0xf1168a32, 0x558f69cd), + TOBN(0xbac21595, 0x0d1850df), TOBN(0x15c8295b, 0xb204c848), + TOBN(0xf661aa36, 0x7d8184ff), TOBN(0xc396228e, 0x30447bdb), + TOBN(0x11cd5143, 0xbde4a59e), TOBN(0xe3a26e3b, 0x6beab5e6), + TOBN(0xd3b3a13f, 0x1402b9d0), TOBN(0x573441c3, 0x2c7bc863), + TOBN(0x4b301ec4, 0x578c3e6e), TOBN(0xc26fc9c4, 0x0adaf57e), + TOBN(0x96e71bfd, 0x7493cea3), TOBN(0xd05d4b3f, 0x1af81456), + TOBN(0xdaca2a8a, 0x6a8c608f), TOBN(0x53ef07f6, 0x0725b276), + TOBN(0x07a5fbd2, 0x7824fc56), TOBN(0x34675218, 0x13289077), + TOBN(0x5bf69fd5, 0xe0c48349), TOBN(0xa613ddd3, 0xb6aa7875), + TOBN(0x7f78c19c, 0x5450d866), TOBN(0x46f4409c, 0x8f84a481), + TOBN(0x9f1d1928, 0x90fce239), TOBN(0x016c4168, 0xb2ce44b9), + TOBN(0xbae023f0, 0xc7435978), TOBN(0xb152c888, 0x20e30e19), + TOBN(0x9c241645, 0xe3fa6faf), TOBN(0x735d95c1, 0x84823e60), + TOBN(0x03197573, 0x03955317), TOBN(0x0b4b02a9, 0xf03b4995), + TOBN(0x076bf559, 0x70274600), TOBN(0x32c5cc53, 0xaaf57508), + TOBN(0xe8af6d1f, 0x60624129), TOBN(0xb7bc5d64, 0x9a5e2b5e), + TOBN(0x3814b048, 0x5f082d72), TOBN(0x76f267f2, 0xce19677a), + TOBN(0x626c630f, 0xb36eed93), TOBN(0x55230cd7, 0x3bf56803), + TOBN(0x78837949, 0xce2736a0), TOBN(0x0d792d60, 0xaa6c55f1), + TOBN(0x0318dbfd, 0xd5c7c5d2), TOBN(0xb38f8da7, 0x072b342d), + TOBN(0x3569bddc, 0x7b8de38a), TOBN(0xf25b5887, 0xa1c94842), + TOBN(0xb2d5b284, 0x2946ad60), TOBN(0x854f29ad, 0xe9d1707e), + TOBN(0xaa5159dc, 0x2c6a4509), TOBN(0x899f94c0, 0x57189837), + TOBN(0xcf6adc51, 0xf4a55b03), TOBN(0x261762de, 0x35e3b2d5), + TOBN(0x4cc43012, 0x04827b51), TOBN(0xcd22a113, 0xc6021442), + TOBN(0xce2fd61a, 0x247c9569), TOBN(0x59a50973, 0xd152beca), + TOBN(0x6c835a11, 0x63a716d4), TOBN(0xc26455ed, 0x187dedcf), + TOBN(0x27f536e0, 0x49ce89e7), TOBN(0x18908539, 0xcc890cb5), + TOBN(0x308909ab, 0xd83c2aa1), TOBN(0xecd3142b, 0x1ab73bd3), + TOBN(0x6a85bf59, 0xb3f5ab84), TOBN(0x3c320a68, 0xf2bea4c6), + TOBN(0xad8dc538, 0x6da4541f), TOBN(0xeaf34eb0, 0xb7c41186), + TOBN(0x1c780129, 0x977c97c4), TOBN(0x5ff9beeb, 0xc57eb9fa), + TOBN(0xa24d0524, 0xc822c478), TOBN(0xfd8eec2a, 0x461cd415), + TOBN(0xfbde194e, 0xf027458c), TOBN(0xb4ff5319, 0x1d1be115), + TOBN(0x63f874d9, 0x4866d6f4), TOBN(0x35c75015, 0xb21ad0c9), + TOBN(0xa6b5c9d6, 0x46ac49d2), TOBN(0x42c77c0b, 0x83137aa9), + TOBN(0x24d000fc, 0x68225a38), TOBN(0x0f63cfc8, 0x2fe1e907), + TOBN(0x22d1b01b, 0xc6441f95), TOBN(0x7d38f719, 0xec8e448f), + TOBN(0x9b33fa5f, 0x787fb1ba), TOBN(0x94dcfda1, 0x190158df), + TOBN(0xc47cb339, 0x5f6d4a09), TOBN(0x6b4f355c, 0xee52b826), + TOBN(0x3d100f5d, 0xf51b930a), TOBN(0xf4512fac, 0x9f668f69), + TOBN(0x546781d5, 0x206c4c74), TOBN(0xd021d4d4, 0xcb4d2e48), + TOBN(0x494a54c2, 0xca085c2d), TOBN(0xf1dbaca4, 0x520850a8), + TOBN(0x63c79326, 0x490a1aca), TOBN(0xcb64dd9c, 0x41526b02), + TOBN(0xbb772591, 0xa2979258), TOBN(0x3f582970, 0x48d97846), + TOBN(0xd66b70d1, 0x7c213ba7), TOBN(0xc28febb5, 0xe8a0ced4), + TOBN(0x6b911831, 0xc10338c1), TOBN(0x0d54e389, 0xbf0126f3), + TOBN(0x7048d460, 0x4af206ee), TOBN(0x786c88f6, 0x77e97cb9), + TOBN(0xd4375ae1, 0xac64802e), TOBN(0x469bcfe1, 0xd53ec11c), + TOBN(0xfc9b340d, 0x47062230), TOBN(0xe743bb57, 0xc5b4a3ac), + TOBN(0xfe00b4aa, 0x59ef45ac), TOBN(0x29a4ef23, 0x59edf188), + TOBN(0x40242efe, 0xb483689b), TOBN(0x2575d3f6, 0x513ac262), + TOBN(0xf30037c8, 0x0ca6db72), TOBN(0xc9fcce82, 0x98864be2), + TOBN(0x84a112ff, 0x0149362d), TOBN(0x95e57582, 0x1c4ae971), + TOBN(0x1fa4b1a8, 0x945cf86c), TOBN(0x4525a734, 0x0b024a2f), + TOBN(0xe76c8b62, 0x8f338360), TOBN(0x483ff593, 0x28edf32b), + TOBN(0x67e8e90a, 0x298b1aec), TOBN(0x9caab338, 0x736d9a21), + TOBN(0x5c09d2fd, 0x66892709), TOBN(0x2496b4dc, 0xb55a1d41), + TOBN(0x93f5fb1a, 0xe24a4394), TOBN(0x08c75049, 0x6fa8f6c1), + TOBN(0xcaead1c2, 0xc905d85f), TOBN(0xe9d7f790, 0x0733ae57), + TOBN(0x24c9a65c, 0xf07cdd94), TOBN(0x7389359c, 0xa4b55931), + TOBN(0xf58709b7, 0x367e45f7), TOBN(0x1f203067, 0xcb7e7adc), + TOBN(0x82444bff, 0xc7b72818), TOBN(0x07303b35, 0xbaac8033), + TOBN(0x1e1ee4e4, 0xd13b7ea1), TOBN(0xe6489b24, 0xe0e74180), + TOBN(0xa5f2c610, 0x7e70ef70), TOBN(0xa1655412, 0xbdd10894), + TOBN(0x555ebefb, 0x7af4194e), TOBN(0x533c1c3c, 0x8e89bd9c), + TOBN(0x735b9b57, 0x89895856), TOBN(0x15fb3cd2, 0x567f5c15), + TOBN(0x057fed45, 0x526f09fd), TOBN(0xe8a4f10c, 0x8128240a), + TOBN(0x9332efc4, 0xff2bfd8d), TOBN(0x214e77a0, 0xbd35aa31), + TOBN(0x32896d73, 0x14faa40e), TOBN(0x767867ec, 0x01e5f186), + TOBN(0xc9adf8f1, 0x17a1813e), TOBN(0xcb6cda78, 0x54741795), + TOBN(0xb7521b6d, 0x349d51aa), TOBN(0xf56b5a9e, 0xe3c7b8e9), + TOBN(0xc6f1e5c9, 0x32a096df), TOBN(0x083667c4, 0xa3635024), + TOBN(0x365ea135, 0x18087f2f), TOBN(0xf1b8eaac, 0xd136e45d), + TOBN(0xc8a0e484, 0x73aec989), TOBN(0xd75a324b, 0x142c9259), + TOBN(0xb7b4d001, 0x01dae185), TOBN(0x45434e0b, 0x9b7a94bc), + TOBN(0xf54339af, 0xfbd8cb0b), TOBN(0xdcc4569e, 0xe98ef49e), + TOBN(0x7789318a, 0x09a51299), TOBN(0x81b4d206, 0xb2b025d8), + TOBN(0xf64aa418, 0xfae85792), TOBN(0x3e50258f, 0xacd7baf7), + TOBN(0xdce84cdb, 0x2996864b), TOBN(0xa2e67089, 0x1f485fa4), + TOBN(0xb28b2bb6, 0x534c6a5a), TOBN(0x31a7ec6b, 0xc94b9d39), + TOBN(0x1d217766, 0xd6bc20da), TOBN(0x4acdb5ec, 0x86761190), + TOBN(0x68726328, 0x73701063), TOBN(0x4d24ee7c, 0x2128c29b), + TOBN(0xc072ebd3, 0xa19fd868), TOBN(0x612e481c, 0xdb8ddd3b), + TOBN(0xb4e1d754, 0x1a64d852), TOBN(0x00ef95ac, 0xc4c6c4ab), + TOBN(0x1536d2ed, 0xaa0a6c46), TOBN(0x61294086, 0x43774790), + TOBN(0x54af25e8, 0x343fda10), TOBN(0x9ff9d98d, 0xfd25d6f2), + TOBN(0x0746af7c, 0x468b8835), TOBN(0x977a31cb, 0x730ecea7), + TOBN(0xa5096b80, 0xc2cf4a81), TOBN(0xaa986833, 0x6458c37a), + TOBN(0x6af29bf3, 0xa6bd9d34), TOBN(0x6a62fe9b, 0x33c5d854), + TOBN(0x50e6c304, 0xb7133b5e), TOBN(0x04b60159, 0x7d6e6848), + TOBN(0x4cd296df, 0x5579bea4), TOBN(0x10e35ac8, 0x5ceedaf1), + TOBN(0x04c4c5fd, 0xe3bcc5b1), TOBN(0x95f9ee8a, 0x89412cf9), + TOBN(0x2c9459ee, 0x82b6eb0f), TOBN(0x2e845765, 0x95c2aadd), + TOBN(0x774a84ae, 0xd327fcfe), TOBN(0xd8c93722, 0x0368d476), + TOBN(0x0dbd5748, 0xf83e8a3b), TOBN(0xa579aa96, 0x8d2495f3), + TOBN(0x535996a0, 0xae496e9b), TOBN(0x07afbfe9, 0xb7f9bcc2), + TOBN(0x3ac1dc6d, 0x5b7bd293), TOBN(0x3b592cff, 0x7022323d), + TOBN(0xba0deb98, 0x9c0a3e76), TOBN(0x18e78e9f, 0x4b197acb), + TOBN(0x211cde10, 0x296c36ef), TOBN(0x7ee89672, 0x82c4da77), + TOBN(0xb617d270, 0xa57836da), TOBN(0xf0cd9c31, 0x9cb7560b), + TOBN(0x01fdcbf7, 0xe455fe90), TOBN(0x3fb53cbb, 0x7e7334f3), + TOBN(0x781e2ea4, 0x4e7de4ec), TOBN(0x8adab3ad, 0x0b384fd0), + TOBN(0x129eee2f, 0x53d64829), TOBN(0x7a471e17, 0xa261492b), + TOBN(0xe4f9adb9, 0xe4cb4a2c), TOBN(0x3d359f6f, 0x97ba2c2d), + TOBN(0x346c6786, 0x0aacd697), TOBN(0x92b444c3, 0x75c2f8a8), + TOBN(0xc79fa117, 0xd85df44e), TOBN(0x56782372, 0x398ddf31), + TOBN(0x60e690f2, 0xbbbab3b8), TOBN(0x4851f8ae, 0x8b04816b), + TOBN(0xc72046ab, 0x9c92e4d2), TOBN(0x518c74a1, 0x7cf3136b), + TOBN(0xff4eb50a, 0xf9877d4c), TOBN(0x14578d90, 0xa919cabb), + TOBN(0x8218f8c4, 0xac5eb2b6), TOBN(0xa3ccc547, 0x542016e4), + TOBN(0x025bf48e, 0x327f8349), TOBN(0xf3e97346, 0xf43cb641), + TOBN(0xdc2bafdf, 0x500f1085), TOBN(0x57167876, 0x2f063055), + TOBN(0x5bd914b9, 0x411925a6), TOBN(0x7c078d48, 0xa1123de5), + TOBN(0xee6bf835, 0x182b165d), TOBN(0xb11b5e5b, 0xba519727), + TOBN(0xe33ea76c, 0x1eea7b85), TOBN(0x2352b461, 0x92d4f85e), + TOBN(0xf101d334, 0xafe115bb), TOBN(0xfabc1294, 0x889175a3), + TOBN(0x7f6bcdc0, 0x5233f925), TOBN(0xe0a802db, 0xe77fec55), + TOBN(0xbdb47b75, 0x8069b659), TOBN(0x1c5e12de, 0xf98fbd74), + TOBN(0x869c58c6, 0x4b8457ee), TOBN(0xa5360f69, 0x4f7ea9f7), + TOBN(0xe576c09f, 0xf460b38f), TOBN(0x6b70d548, 0x22b7fb36), + TOBN(0x3fd237f1, 0x3bfae315), TOBN(0x33797852, 0xcbdff369), + TOBN(0x97df25f5, 0x25b516f9), TOBN(0x46f388f2, 0xba38ad2d), + TOBN(0x656c4658, 0x89d8ddbb), TOBN(0x8830b26e, 0x70f38ee8), + TOBN(0x4320fd5c, 0xde1212b0), TOBN(0xc34f30cf, 0xe4a2edb2), + TOBN(0xabb131a3, 0x56ab64b8), TOBN(0x7f77f0cc, 0xd99c5d26), + TOBN(0x66856a37, 0xbf981d94), TOBN(0x19e76d09, 0x738bd76e), + TOBN(0xe76c8ac3, 0x96238f39), TOBN(0xc0a482be, 0xa830b366), + TOBN(0xb7b8eaff, 0x0b4eb499), TOBN(0x8ecd83bc, 0x4bfb4865), + TOBN(0x971b2cb7, 0xa2f3776f), TOBN(0xb42176a4, 0xf4b88adf), + TOBN(0xb9617df5, 0xbe1fa446), TOBN(0x8b32d508, 0xcd031bd2), + TOBN(0x1c6bd47d, 0x53b618c0), TOBN(0xc424f46c, 0x6a227923), + TOBN(0x7303ffde, 0xdd92d964), TOBN(0xe9712878, 0x71b5abf2), + TOBN(0x8f48a632, 0xf815561d), TOBN(0x85f48ff5, 0xd3c055d1), + TOBN(0x222a1427, 0x7525684f), TOBN(0xd0d841a0, 0x67360cc3), + TOBN(0x4245a926, 0x0b9267c6), TOBN(0xc78913f1, 0xcf07f863), + TOBN(0xaa844c8e, 0x4d0d9e24), TOBN(0xa42ad522, 0x3d5f9017), + TOBN(0xbd371749, 0xa2c989d5), TOBN(0x928292df, 0xe1f5e78e), + TOBN(0x493b383e, 0x0a1ea6da), TOBN(0x5136fd8d, 0x13aee529), + TOBN(0x860c44b1, 0xf2c34a99), TOBN(0x3b00aca4, 0xbf5855ac), + TOBN(0xabf6aaa0, 0xfaaf37be), TOBN(0x65f43682, 0x2a53ec08), + TOBN(0x1d9a5801, 0xa11b12e1), TOBN(0x78a7ab2c, 0xe20ed475), + TOBN(0x0de1067e, 0x9a41e0d5), TOBN(0x30473f5f, 0x305023ea), + TOBN(0xdd3ae09d, 0x169c7d97), TOBN(0x5cd5baa4, 0xcfaef9cd), + TOBN(0x5cd7440b, 0x65a44803), TOBN(0xdc13966a, 0x47f364de), + TOBN(0x077b2be8, 0x2b8357c1), TOBN(0x0cb1b4c5, 0xe9d57c2a), + TOBN(0x7a4ceb32, 0x05ff363e), TOBN(0xf310fa4d, 0xca35a9ef), + TOBN(0xdbb7b352, 0xf97f68c6), TOBN(0x0c773b50, 0x0b02cf58), + TOBN(0xea2e4821, 0x3c1f96d9), TOBN(0xffb357b0, 0xeee01815), + TOBN(0xb9c924cd, 0xe0f28039), TOBN(0x0b36c95a, 0x46a3fbe4), + TOBN(0x1faaaea4, 0x5e46db6c), TOBN(0xcae575c3, 0x1928aaff), + TOBN(0x7f671302, 0xa70dab86), TOBN(0xfcbd12a9, 0x71c58cfc), + TOBN(0xcbef9acf, 0xbee0cb92), TOBN(0x573da0b9, 0xf8c1b583), + TOBN(0x4752fcfe, 0x0d41d550), TOBN(0xe7eec0e3, 0x2155cffe), + TOBN(0x0fc39fcb, 0x545ae248), TOBN(0x522cb8d1, 0x8065f44e), + TOBN(0x263c962a, 0x70cbb96c), TOBN(0xe034362a, 0xbcd124a9), + TOBN(0xf120db28, 0x3c2ae58d), TOBN(0xb9a38d49, 0xfef6d507), + TOBN(0xb1fd2a82, 0x1ff140fd), TOBN(0xbd162f30, 0x20aee7e0), + TOBN(0x4e17a5d4, 0xcb251949), TOBN(0x2aebcb83, 0x4f7e1c3d), + TOBN(0x608eb25f, 0x937b0527), TOBN(0xf42e1e47, 0xeb7d9997), + TOBN(0xeba699c4, 0xb8a53a29), TOBN(0x1f921c71, 0xe091b536), + TOBN(0xcce29e7b, 0x5b26bbd5), TOBN(0x7a8ef5ed, 0x3b61a680), + TOBN(0xe5ef8043, 0xba1f1c7e), TOBN(0x16ea8217, 0x18158dda), + TOBN(0x01778a2b, 0x599ff0f9), TOBN(0x68a923d7, 0x8104fc6b), + TOBN(0x5bfa44df, 0xda694ff3), TOBN(0x4f7199db, 0xf7667f12), + TOBN(0xc06d8ff6, 0xe46f2a79), TOBN(0x08b5dead, 0xe9f8131d), + TOBN(0x02519a59, 0xabb4ce7c), TOBN(0xc4f710bc, 0xb42aec3e), + TOBN(0x3d77b057, 0x78bde41a), TOBN(0x6474bf80, 0xb4186b5a), + TOBN(0x048b3f67, 0x88c65741), TOBN(0xc64519de, 0x03c7c154), + TOBN(0xdf073846, 0x0edfcc4f), TOBN(0x319aa737, 0x48f1aa6b), + TOBN(0x8b9f8a02, 0xca909f77), TOBN(0x90258139, 0x7580bfef), + TOBN(0xd8bfd3ca, 0xc0c22719), TOBN(0xc60209e4, 0xc9ca151e), + TOBN(0x7a744ab5, 0xd9a1a69c), TOBN(0x6de5048b, 0x14937f8f), + TOBN(0x171938d8, 0xe115ac04), TOBN(0x7df70940, 0x1c6b16d2), + TOBN(0xa6aeb663, 0x7f8e94e7), TOBN(0xc130388e, 0x2a2cf094), + TOBN(0x1850be84, 0x77f54e6e), TOBN(0x9f258a72, 0x65d60fe5), + TOBN(0xff7ff0c0, 0x6c9146d6), TOBN(0x039aaf90, 0xe63a830b), + TOBN(0x38f27a73, 0x9460342f), TOBN(0x4703148c, 0x3f795f8a), + TOBN(0x1bb5467b, 0x9681a97e), TOBN(0x00931ba5, 0xecaeb594), + TOBN(0xcdb6719d, 0x786f337c), TOBN(0xd9c01cd2, 0xe704397d), + TOBN(0x0f4a3f20, 0x555c2fef), TOBN(0x00452509, 0x7c0af223), + TOBN(0x54a58047, 0x84db8e76), TOBN(0x3bacf1aa, 0x93c8aa06), + TOBN(0x11ca957c, 0xf7919422), TOBN(0x50641053, 0x78cdaa40), + TOBN(0x7a303874, 0x9f7144ae), TOBN(0x170c963f, 0x43d4acfd), + TOBN(0x5e148149, 0x58ddd3ef), TOBN(0xa7bde582, 0x9e72dba8), + TOBN(0x0769da8b, 0x6fa68750), TOBN(0xfa64e532, 0x572e0249), + TOBN(0xfcaadf9d, 0x2619ad31), TOBN(0x87882daa, 0xa7b349cd), + TOBN(0x9f6eb731, 0x6c67a775), TOBN(0xcb10471a, 0xefc5d0b1), + TOBN(0xb433750c, 0xe1b806b2), TOBN(0x19c5714d, 0x57b1ae7e), + TOBN(0xc0dc8b7b, 0xed03fd3f), TOBN(0xdd03344f, 0x31bc194e), + TOBN(0xa66c52a7, 0x8c6320b5), TOBN(0x8bc82ce3, 0xd0b6fd93), + TOBN(0xf8e13501, 0xb35f1341), TOBN(0xe53156dd, 0x25a43e42), + TOBN(0xd3adf27e, 0x4daeb85c), TOBN(0xb81d8379, 0xbbeddeb5), + TOBN(0x1b0b546e, 0x2e435867), TOBN(0x9020eb94, 0xeba5dd60), + TOBN(0x37d91161, 0x8210cb9d), TOBN(0x4c596b31, 0x5c91f1cf), + TOBN(0xb228a90f, 0x0e0b040d), TOBN(0xbaf02d82, 0x45ff897f), + TOBN(0x2aac79e6, 0x00fa6122), TOBN(0x24828817, 0x8e36f557), + TOBN(0xb9521d31, 0x113ec356), TOBN(0x9e48861e, 0x15eff1f8), + TOBN(0x2aa1d412, 0xe0d41715), TOBN(0x71f86203, 0x53f131b8), + TOBN(0xf60da8da, 0x3fd19408), TOBN(0x4aa716dc, 0x278d9d99), + TOBN(0x394531f7, 0xa8c51c90), TOBN(0xb560b0e8, 0xf59db51c), + TOBN(0xa28fc992, 0xfa34bdad), TOBN(0xf024fa14, 0x9cd4f8bd), + TOBN(0x5cf530f7, 0x23a9d0d3), TOBN(0x615ca193, 0xe28c9b56), + TOBN(0x6d2a483d, 0x6f73c51e), TOBN(0xa4cb2412, 0xea0dc2dd), + TOBN(0x50663c41, 0x1eb917ff), TOBN(0x3d3a74cf, 0xeade299e), + TOBN(0x29b3990f, 0x4a7a9202), TOBN(0xa9bccf59, 0xa7b15c3d), + TOBN(0x66a3ccdc, 0xa5df9208), TOBN(0x48027c14, 0x43f2f929), + TOBN(0xd385377c, 0x40b557f0), TOBN(0xe001c366, 0xcd684660), + TOBN(0x1b18ed6b, 0xe2183a27), TOBN(0x879738d8, 0x63210329), + TOBN(0xa687c74b, 0xbda94882), TOBN(0xd1bbcc48, 0xa684b299), + TOBN(0xaf6f1112, 0x863b3724), TOBN(0x6943d1b4, 0x2c8ce9f8), + TOBN(0xe044a3bb, 0x098cafb4), TOBN(0x27ed2310, 0x60d48caf), + TOBN(0x542b5675, 0x3a31b84d), TOBN(0xcbf3dd50, 0xfcddbed7), + TOBN(0x25031f16, 0x41b1d830), TOBN(0xa7ec851d, 0xcb0c1e27), + TOBN(0xac1c8fe0, 0xb5ae75db), TOBN(0xb24c7557, 0x08c52120), + TOBN(0x57f811dc, 0x1d4636c3), TOBN(0xf8436526, 0x681a9939), + TOBN(0x1f6bc6d9, 0x9c81adb3), TOBN(0x840f8ac3, 0x5b7d80d4), + TOBN(0x731a9811, 0xf4387f1a), TOBN(0x7c501cd3, 0xb5156880), + TOBN(0xa5ca4a07, 0xdfe68867), TOBN(0xf123d8f0, 0x5fcea120), + TOBN(0x1fbb0e71, 0xd607039e), TOBN(0x2b70e215, 0xcd3a4546), + TOBN(0x32d2f01d, 0x53324091), TOBN(0xb796ff08, 0x180ab19b), + TOBN(0x32d87a86, 0x3c57c4aa), TOBN(0x2aed9caf, 0xb7c49a27), + TOBN(0x9fb35eac, 0x31630d98), TOBN(0x338e8cdf, 0x5c3e20a3), + TOBN(0x80f16182, 0x66cde8db), TOBN(0x4e159980, 0x2d72fd36), + TOBN(0xd7b8f13b, 0x9b6e5072), TOBN(0xf5213907, 0x3b7b5dc1), + TOBN(0x4d431f1d, 0x8ce4396e), TOBN(0x37a1a680, 0xa7ed2142), + TOBN(0xbf375696, 0xd01aaf6b), TOBN(0xaa1c0c54, 0xe63aab66), + TOBN(0x3014368b, 0x4ed80940), TOBN(0x67e6d056, 0x7a6fcedd), + TOBN(0x7c208c49, 0xca97579f), TOBN(0xfe3d7a81, 0xa23597f6), + TOBN(0x5e203202, 0x7e096ae2), TOBN(0xb1f3e1e7, 0x24b39366), + TOBN(0x26da26f3, 0x2fdcdffc), TOBN(0x79422f1d, 0x6097be83)}, + {TOBN(0x263a2cfb, 0x9db3b381), TOBN(0x9c3a2dee, 0xd4df0a4b), + TOBN(0x728d06e9, 0x7d04e61f), TOBN(0x8b1adfbc, 0x42449325), + TOBN(0x6ec1d939, 0x7e053a1b), TOBN(0xee2be5c7, 0x66daf707), + TOBN(0x80ba1e14, 0x810ac7ab), TOBN(0xdd2ae778, 0xf530f174), + TOBN(0x0435d97a, 0x205b9d8b), TOBN(0x6eb8f064, 0x056756d4), + TOBN(0xd5e88a8b, 0xb6f8210e), TOBN(0x070ef12d, 0xec9fd9ea), + TOBN(0x4d849505, 0x3bcc876a), TOBN(0x12a75338, 0xa7404ce3), + TOBN(0xd22b49e1, 0xb8a1db5e), TOBN(0xec1f2051, 0x14bfa5ad), + TOBN(0xadbaeb79, 0xb6828f36), TOBN(0x9d7a0258, 0x01bd5b9e), + TOBN(0xeda01e0d, 0x1e844b0c), TOBN(0x4b625175, 0x887edfc9), + TOBN(0x14109fdd, 0x9669b621), TOBN(0x88a2ca56, 0xf6f87b98), + TOBN(0xfe2eb788, 0x170df6bc), TOBN(0x0cea06f4, 0xffa473f9), + TOBN(0x43ed81b5, 0xc4e83d33), TOBN(0xd9f35879, 0x5efd488b), + TOBN(0x164a620f, 0x9deb4d0f), TOBN(0xc6927bdb, 0xac6a7394), + TOBN(0x45c28df7, 0x9f9e0f03), TOBN(0x2868661e, 0xfcd7e1a9), + TOBN(0x7cf4e8d0, 0xffa348f1), TOBN(0x6bd4c284, 0x398538e0), + TOBN(0x2618a091, 0x289a8619), TOBN(0xef796e60, 0x6671b173), + TOBN(0x664e46e5, 0x9090c632), TOBN(0xa38062d4, 0x1e66f8fb), + TOBN(0x6c744a20, 0x0573274e), TOBN(0xd07b67e4, 0xa9271394), + TOBN(0x391223b2, 0x6bdc0e20), TOBN(0xbe2d93f1, 0xeb0a05a7), + TOBN(0xf23e2e53, 0x3f36d141), TOBN(0xe84bb3d4, 0x4dfca442), + TOBN(0xb804a48d, 0x6b7c023a), TOBN(0x1e16a8fa, 0x76431c3b), + TOBN(0x1b5452ad, 0xddd472e0), TOBN(0x7d405ee7, 0x0d1ee127), + TOBN(0x50fc6f1d, 0xffa27599), TOBN(0x351ac53c, 0xbf391b35), + TOBN(0x7efa14b8, 0x4444896b), TOBN(0x64974d2f, 0xf94027fb), + TOBN(0xefdcd0e8, 0xde84487d), TOBN(0x8c45b260, 0x2b48989b), + TOBN(0xa8fcbbc2, 0xd8463487), TOBN(0xd1b2b3f7, 0x3fbc476c), + TOBN(0x21d005b7, 0xc8f443c0), TOBN(0x518f2e67, 0x40c0139c), + TOBN(0x56036e8c, 0x06d75fc1), TOBN(0x2dcf7bb7, 0x3249a89f), + TOBN(0x81dd1d3d, 0xe245e7dd), TOBN(0xf578dc4b, 0xebd6e2a7), + TOBN(0x4c028903, 0xdf2ce7a0), TOBN(0xaee36288, 0x9c39afac), + TOBN(0xdc847c31, 0x146404ab), TOBN(0x6304c0d8, 0xa4e97818), + TOBN(0xae51dca2, 0xa91f6791), TOBN(0x2abe4190, 0x9baa9efc), + TOBN(0xd9d2e2f4, 0x559c7ac1), TOBN(0xe82f4b51, 0xfc9f773a), + TOBN(0xa7713027, 0x4073e81c), TOBN(0xc0276fac, 0xfbb596fc), + TOBN(0x1d819fc9, 0xa684f70c), TOBN(0x29b47fdd, 0xc9f7b1e0), + TOBN(0x358de103, 0x459b1940), TOBN(0xec881c59, 0x5b013e93), + TOBN(0x51574c93, 0x49532ad3), TOBN(0x2db1d445, 0xb37b46de), + TOBN(0xc6445b87, 0xdf239fd8), TOBN(0xc718af75, 0x151d24ee), + TOBN(0xaea1c4a4, 0xf43c6259), TOBN(0x40c0e5d7, 0x70be02f7), + TOBN(0x6a4590f4, 0x721b33f2), TOBN(0x2124f1fb, 0xfedf04ea), + TOBN(0xf8e53cde, 0x9745efe7), TOBN(0xe7e10432, 0x65f046d9), + TOBN(0xc3fca28e, 0xe4d0c7e6), TOBN(0x847e339a, 0x87253b1b), + TOBN(0x9b595348, 0x3743e643), TOBN(0xcb6a0a0b, 0x4fd12fc5), + TOBN(0xfb6836c3, 0x27d02dcc), TOBN(0x5ad00982, 0x7a68bcc2), + TOBN(0x1b24b44c, 0x005e912d), TOBN(0xcc83d20f, 0x811fdcfe), + TOBN(0x36527ec1, 0x666fba0c), TOBN(0x69948197, 0x14754635), + TOBN(0xfcdcb1a8, 0x556da9c2), TOBN(0xa5934267, 0x81a732b2), + TOBN(0xec1214ed, 0xa714181d), TOBN(0x609ac13b, 0x6067b341), + TOBN(0xff4b4c97, 0xa545df1f), TOBN(0xa1240501, 0x34d2076b), + TOBN(0x6efa0c23, 0x1409ca97), TOBN(0x254cc1a8, 0x20638c43), + TOBN(0xd4e363af, 0xdcfb46cd), TOBN(0x62c2adc3, 0x03942a27), + TOBN(0xc67b9df0, 0x56e46483), TOBN(0xa55abb20, 0x63736356), + TOBN(0xab93c098, 0xc551bc52), TOBN(0x382b49f9, 0xb15fe64b), + TOBN(0x9ec221ad, 0x4dff8d47), TOBN(0x79caf615, 0x437df4d6), + TOBN(0x5f13dc64, 0xbb456509), TOBN(0xe4c589d9, 0x191f0714), + TOBN(0x27b6a8ab, 0x3fd40e09), TOBN(0xe455842e, 0x77313ea9), + TOBN(0x8b51d1e2, 0x1f55988b), TOBN(0x5716dd73, 0x062bbbfc), + TOBN(0x633c11e5, 0x4e8bf3de), TOBN(0x9a0e77b6, 0x1b85be3b), + TOBN(0x56510729, 0x0911cca6), TOBN(0x27e76495, 0xefa6590f), + TOBN(0xe4ac8b33, 0x070d3aab), TOBN(0x2643672b, 0x9a2cd5e5), + TOBN(0x52eff79b, 0x1cfc9173), TOBN(0x665ca49b, 0x90a7c13f), + TOBN(0x5a8dda59, 0xb3efb998), TOBN(0x8a5b922d, 0x052f1341), + TOBN(0xae9ebbab, 0x3cf9a530), TOBN(0x35986e7b, 0xf56da4d7), + TOBN(0x3a636b5c, 0xff3513cc), TOBN(0xbb0cf8ba, 0x3198f7dd), + TOBN(0xb8d40522, 0x41f16f86), TOBN(0x760575d8, 0xde13a7bf), + TOBN(0x36f74e16, 0x9f7aa181), TOBN(0x163a3ecf, 0xf509ed1c), + TOBN(0x6aead61f, 0x3c40a491), TOBN(0x158c95fc, 0xdfe8fcaa), + TOBN(0xa3991b6e, 0x13cda46f), TOBN(0x79482415, 0x342faed0), + TOBN(0xf3ba5bde, 0x666b5970), TOBN(0x1d52e6bc, 0xb26ab6dd), + TOBN(0x768ba1e7, 0x8608dd3d), TOBN(0x4930db2a, 0xea076586), + TOBN(0xd9575714, 0xe7dc1afa), TOBN(0x1fc7bf7d, 0xf7c58817), + TOBN(0x6b47accd, 0xd9eee96c), TOBN(0x0ca277fb, 0xe58cec37), + TOBN(0x113fe413, 0xe702c42a), TOBN(0xdd1764ee, 0xc47cbe51), + TOBN(0x041e7cde, 0x7b3ed739), TOBN(0x50cb7459, 0x5ce9e1c0), + TOBN(0x35568513, 0x2925b212), TOBN(0x7cff95c4, 0x001b081c), + TOBN(0x63ee4cbd, 0x8088b454), TOBN(0xdb7f32f7, 0x9a9e0c8a), + TOBN(0xb377d418, 0x6b2447cb), TOBN(0xe3e982aa, 0xd370219b), + TOBN(0x06ccc1e4, 0xc2a2a593), TOBN(0x72c36865, 0x0773f24f), + TOBN(0xa13b4da7, 0x95859423), TOBN(0x8bbf1d33, 0x75040c8f), + TOBN(0x726f0973, 0xda50c991), TOBN(0x48afcd5b, 0x822d6ee2), + TOBN(0xe5fc718b, 0x20fd7771), TOBN(0xb9e8e77d, 0xfd0807a1), + TOBN(0x7f5e0f44, 0x99a7703d), TOBN(0x6972930e, 0x618e36f3), + TOBN(0x2b7c77b8, 0x23807bbe), TOBN(0xe5b82405, 0xcb27ff50), + TOBN(0xba8b8be3, 0xbd379062), TOBN(0xd64b7a1d, 0x2dce4a92), + TOBN(0x040a73c5, 0xb2952e37), TOBN(0x0a9e252e, 0xd438aeca), + TOBN(0xdd43956b, 0xc39d3bcb), TOBN(0x1a31ca00, 0xb32b2d63), + TOBN(0xd67133b8, 0x5c417a18), TOBN(0xd08e4790, 0x2ef442c8), + TOBN(0x98cb1ae9, 0x255c0980), TOBN(0x4bd86381, 0x2b4a739f), + TOBN(0x5a5c31e1, 0x1e4a45a1), TOBN(0x1e5d55fe, 0x9cb0db2f), + TOBN(0x74661b06, 0x8ff5cc29), TOBN(0x026b389f, 0x0eb8a4f4), + TOBN(0x536b21a4, 0x58848c24), TOBN(0x2e5bf8ec, 0x81dc72b0), + TOBN(0x03c187d0, 0xad886aac), TOBN(0x5c16878a, 0xb771b645), + TOBN(0xb07dfc6f, 0xc74045ab), TOBN(0x2c6360bf, 0x7800caed), + TOBN(0x24295bb5, 0xb9c972a3), TOBN(0xc9e6f88e, 0x7c9a6dba), + TOBN(0x90ffbf24, 0x92a79aa6), TOBN(0xde29d50a, 0x41c26ac2), + TOBN(0x9f0af483, 0xd309cbe6), TOBN(0x5b020d8a, 0xe0bced4f), + TOBN(0x606e986d, 0xb38023e3), TOBN(0xad8f2c9d, 0x1abc6933), + TOBN(0x19292e1d, 0xe7400e93), TOBN(0xfe3e18a9, 0x52be5e4d), + TOBN(0xe8e9771d, 0x2e0680bf), TOBN(0x8c5bec98, 0xc54db063), + TOBN(0x2af9662a, 0x74a55d1f), TOBN(0xe3fbf28f, 0x046f66d8), + TOBN(0xa3a72ab4, 0xd4dc4794), TOBN(0x09779f45, 0x5c7c2dd8), + TOBN(0xd893bdaf, 0xc3d19d8d), TOBN(0xd5a75094, 0x57d6a6df), + TOBN(0x8cf8fef9, 0x952e6255), TOBN(0x3da67cfb, 0xda9a8aff), + TOBN(0x4c23f62a, 0x2c160dcd), TOBN(0x34e6c5e3, 0x8f90eaef), + TOBN(0x35865519, 0xa9a65d5a), TOBN(0x07c48aae, 0x8fd38a3d), + TOBN(0xb7e7aeda, 0x50068527), TOBN(0x2c09ef23, 0x1c90936a), + TOBN(0x31ecfeb6, 0xe879324c), TOBN(0xa0871f6b, 0xfb0ec938), + TOBN(0xb1f0fb68, 0xd84d835d), TOBN(0xc90caf39, 0x861dc1e6), + TOBN(0x12e5b046, 0x7594f8d7), TOBN(0x26897ae2, 0x65012b92), + TOBN(0xbcf68a08, 0xa4d6755d), TOBN(0x403ee41c, 0x0991fbda), + TOBN(0x733e343e, 0x3bbf17e8), TOBN(0xd2c7980d, 0x679b3d65), + TOBN(0x33056232, 0xd2e11305), TOBN(0x966be492, 0xf3c07a6f), + TOBN(0x6a8878ff, 0xbb15509d), TOBN(0xff221101, 0x0a9b59a4), + TOBN(0x6c9f564a, 0xabe30129), TOBN(0xc6f2c940, 0x336e64cf), + TOBN(0x0fe75262, 0x8b0c8022), TOBN(0xbe0267e9, 0x6ae8db87), + TOBN(0x22e192f1, 0x93bc042b), TOBN(0xf085b534, 0xb237c458), + TOBN(0xa0d192bd, 0x832c4168), TOBN(0x7a76e9e3, 0xbdf6271d), + TOBN(0x52a882fa, 0xb88911b5), TOBN(0xc85345e4, 0xb4db0eb5), + TOBN(0xa3be02a6, 0x81a7c3ff), TOBN(0x51889c8c, 0xf0ec0469), + TOBN(0x9d031369, 0xa5e829e5), TOBN(0xcbb4c6fc, 0x1607aa41), + TOBN(0x75ac59a6, 0x241d84c1), TOBN(0xc043f2bf, 0x8829e0ee), + TOBN(0x82a38f75, 0x8ea5e185), TOBN(0x8bda40b9, 0xd87cbd9f), + TOBN(0x9e65e75e, 0x2d8fc601), TOBN(0x3d515f74, 0xa35690b3), + TOBN(0x534acf4f, 0xda79e5ac), TOBN(0x68b83b3a, 0x8630215f), + TOBN(0x5c748b2e, 0xd085756e), TOBN(0xb0317258, 0xe5d37cb2), + TOBN(0x6735841a, 0xc5ccc2c4), TOBN(0x7d7dc96b, 0x3d9d5069), + TOBN(0xa147e410, 0xfd1754bd), TOBN(0x65296e94, 0xd399ddd5), + TOBN(0xf6b5b2d0, 0xbc8fa5bc), TOBN(0x8a5ead67, 0x500c277b), + TOBN(0x214625e6, 0xdfa08a5d), TOBN(0x51fdfedc, 0x959cf047), + TOBN(0x6bc9430b, 0x289fca32), TOBN(0xe36ff0cf, 0x9d9bdc3f), + TOBN(0x2fe187cb, 0x58ea0ede), TOBN(0xed66af20, 0x5a900b3f), + TOBN(0x00e0968b, 0x5fa9f4d6), TOBN(0x2d4066ce, 0x37a362e7), + TOBN(0xa99a9748, 0xbd07e772), TOBN(0x710989c0, 0x06a4f1d0), + TOBN(0xd5dedf35, 0xce40cbd8), TOBN(0xab55c5f0, 0x1743293d), + TOBN(0x766f1144, 0x8aa24e2c), TOBN(0x94d874f8, 0x605fbcb4), + TOBN(0xa365f0e8, 0xa518001b), TOBN(0xee605eb6, 0x9d04ef0f), + TOBN(0x5a3915cd, 0xba8d4d25), TOBN(0x44c0e1b8, 0xb5113472), + TOBN(0xcbb024e8, 0x8b6740dc), TOBN(0x89087a53, 0xee1d4f0c), + TOBN(0xa88fa05c, 0x1fc4e372), TOBN(0x8bf395cb, 0xaf8b3af2), + TOBN(0x1e71c9a1, 0xdeb8568b), TOBN(0xa35daea0, 0x80fb3d32), + TOBN(0xe8b6f266, 0x2cf8fb81), TOBN(0x6d51afe8, 0x9490696a), + TOBN(0x81beac6e, 0x51803a19), TOBN(0xe3d24b7f, 0x86219080), + TOBN(0x727cfd9d, 0xdf6f463c), TOBN(0x8c6865ca, 0x72284ee8), + TOBN(0x32c88b7d, 0xb743f4ef), TOBN(0x3793909b, 0xe7d11dce), + TOBN(0xd398f922, 0x2ff2ebe8), TOBN(0x2c70ca44, 0xe5e49796), + TOBN(0xdf4d9929, 0xcb1131b1), TOBN(0x7826f298, 0x25888e79), + TOBN(0x4d3a112c, 0xf1d8740a), TOBN(0x00384cb6, 0x270afa8b), + TOBN(0xcb64125b, 0x3ab48095), TOBN(0x3451c256, 0x62d05106), + TOBN(0xd73d577d, 0xa4955845), TOBN(0x39570c16, 0xbf9f4433), + TOBN(0xd7dfaad3, 0xadecf263), TOBN(0xf1c3d8d1, 0xdc76e102), + TOBN(0x5e774a58, 0x54c6a836), TOBN(0xdad4b672, 0x3e92d47b), + TOBN(0xbe7e990f, 0xf0d796a0), TOBN(0x5fc62478, 0xdf0e8b02), + TOBN(0x8aae8bf4, 0x030c00ad), TOBN(0x3d2db93b, 0x9004ba0f), + TOBN(0xe48c8a79, 0xd85d5ddc), TOBN(0xe907caa7, 0x6bb07f34), + TOBN(0x58db343a, 0xa39eaed5), TOBN(0x0ea6e007, 0xadaf5724), + TOBN(0xe00df169, 0xd23233f3), TOBN(0x3e322796, 0x77cb637f), + TOBN(0x1f897c0e, 0x1da0cf6c), TOBN(0xa651f5d8, 0x31d6bbdd), + TOBN(0xdd61af19, 0x1a230c76), TOBN(0xbd527272, 0xcdaa5e4a), + TOBN(0xca753636, 0xd0abcd7e), TOBN(0x78bdd37c, 0x370bd8dc), + TOBN(0xc23916c2, 0x17cd93fe), TOBN(0x65b97a4d, 0xdadce6e2), + TOBN(0xe04ed4eb, 0x174e42f8), TOBN(0x1491ccaa, 0xbb21480a), + TOBN(0x145a8280, 0x23196332), TOBN(0x3c3862d7, 0x587b479a), + TOBN(0x9f4a88a3, 0x01dcd0ed), TOBN(0x4da2b7ef, 0x3ea12f1f), + TOBN(0xf8e7ae33, 0xb126e48e), TOBN(0x404a0b32, 0xf494e237), + TOBN(0x9beac474, 0xc55acadb), TOBN(0x4ee5cf3b, 0xcbec9fd9), + TOBN(0x336b33b9, 0x7df3c8c3), TOBN(0xbd905fe3, 0xb76808fd), + TOBN(0x8f436981, 0xaa45c16a), TOBN(0x255c5bfa, 0x3dd27b62), + TOBN(0x71965cbf, 0xc3dd9b4d), TOBN(0xce23edbf, 0xfc068a87), + TOBN(0xb78d4725, 0x745b029b), TOBN(0x74610713, 0xcefdd9bd), + TOBN(0x7116f75f, 0x1266bf52), TOBN(0x02046722, 0x18e49bb6), + TOBN(0xdf43df9f, 0x3d6f19e3), TOBN(0xef1bc7d0, 0xe685cb2f), + TOBN(0xcddb27c1, 0x7078c432), TOBN(0xe1961b9c, 0xb77fedb7), + TOBN(0x1edc2f5c, 0xc2290570), TOBN(0x2c3fefca, 0x19cbd886), + TOBN(0xcf880a36, 0xc2af389a), TOBN(0x96c610fd, 0xbda71cea), + TOBN(0xf03977a9, 0x32aa8463), TOBN(0x8eb7763f, 0x8586d90a), + TOBN(0x3f342454, 0x2a296e77), TOBN(0xc8718683, 0x42837a35), + TOBN(0x7dc71090, 0x6a09c731), TOBN(0x54778ffb, 0x51b816db), + TOBN(0x6b33bfec, 0xaf06defd), TOBN(0xfe3c105f, 0x8592b70b), + TOBN(0xf937fda4, 0x61da6114), TOBN(0x3c13e651, 0x4c266ad7), + TOBN(0xe363a829, 0x855938e8), TOBN(0x2eeb5d9e, 0x9de54b72), + TOBN(0xbeb93b0e, 0x20ccfab9), TOBN(0x3dffbb5f, 0x25e61a25), + TOBN(0x7f655e43, 0x1acc093d), TOBN(0x0cb6cc3d, 0x3964ce61), + TOBN(0x6ab283a1, 0xe5e9b460), TOBN(0x55d787c5, 0xa1c7e72d), + TOBN(0x4d2efd47, 0xdeadbf02), TOBN(0x11e80219, 0xac459068), + TOBN(0x810c7626, 0x71f311f0), TOBN(0xfa17ef8d, 0x4ab6ef53), + TOBN(0xaf47fd25, 0x93e43bff), TOBN(0x5cb5ff3f, 0x0be40632), + TOBN(0x54687106, 0x8ee61da3), TOBN(0x7764196e, 0xb08afd0f), + TOBN(0x831ab3ed, 0xf0290a8f), TOBN(0xcae81966, 0xcb47c387), + TOBN(0xaad7dece, 0x184efb4f), TOBN(0xdcfc53b3, 0x4749110e), + TOBN(0x6698f23c, 0x4cb632f9), TOBN(0xc42a1ad6, 0xb91f8067), + TOBN(0xb116a81d, 0x6284180a), TOBN(0xebedf5f8, 0xe901326f), + TOBN(0xf2274c9f, 0x97e3e044), TOBN(0x42018520, 0x11d09fc9), + TOBN(0x56a65f17, 0xd18e6e23), TOBN(0x2ea61e2a, 0x352b683c), + TOBN(0x27d291bc, 0x575eaa94), TOBN(0x9e7bc721, 0xb8ff522d), + TOBN(0x5f7268bf, 0xa7f04d6f), TOBN(0x5868c73f, 0xaba41748), + TOBN(0x9f85c2db, 0x7be0eead), TOBN(0x511e7842, 0xff719135), + TOBN(0x5a06b1e9, 0xc5ea90d7), TOBN(0x0c19e283, 0x26fab631), + TOBN(0x8af8f0cf, 0xe9206c55), TOBN(0x89389cb4, 0x3553c06a), + TOBN(0x39dbed97, 0xf65f8004), TOBN(0x0621b037, 0xc508991d), + TOBN(0x1c52e635, 0x96e78cc4), TOBN(0x5385c8b2, 0x0c06b4a8), + TOBN(0xd84ddfdb, 0xb0e87d03), TOBN(0xc49dfb66, 0x934bafad), + TOBN(0x7071e170, 0x59f70772), TOBN(0x3a073a84, 0x3a1db56b), + TOBN(0x03494903, 0x3b8af190), TOBN(0x7d882de3, 0xd32920f0), + TOBN(0x91633f0a, 0xb2cf8940), TOBN(0x72b0b178, 0x6f948f51), + TOBN(0x2d28dc30, 0x782653c8), TOBN(0x88829849, 0xdb903a05), + TOBN(0xb8095d0c, 0x6a19d2bb), TOBN(0x4b9e7f0c, 0x86f782cb), + TOBN(0x7af73988, 0x2d907064), TOBN(0xd12be0fe, 0x8b32643c), + TOBN(0x358ed23d, 0x0e165dc3), TOBN(0x3d47ce62, 0x4e2378ce), + TOBN(0x7e2bb0b9, 0xfeb8a087), TOBN(0x3246e8ae, 0xe29e10b9), + TOBN(0x459f4ec7, 0x03ce2b4d), TOBN(0xe9b4ca1b, 0xbbc077cf), + TOBN(0x2613b4f2, 0x0e9940c1), TOBN(0xfc598bb9, 0x047d1eb1), + TOBN(0x9744c62b, 0x45036099), TOBN(0xa9dee742, 0x167c65d8), + TOBN(0x0c511525, 0xdabe1943), TOBN(0xda110554, 0x93c6c624), + TOBN(0xae00a52c, 0x651a3be2), TOBN(0xcda5111d, 0x884449a6), + TOBN(0x063c06f4, 0xff33bed1), TOBN(0x73baaf9a, 0x0d3d76b4), + TOBN(0x52fb0c9d, 0x7fc63668), TOBN(0x6886c9dd, 0x0c039cde), + TOBN(0x602bd599, 0x55b22351), TOBN(0xb00cab02, 0x360c7c13), + TOBN(0x8cb616bc, 0x81b69442), TOBN(0x41486700, 0xb55c3cee), + TOBN(0x71093281, 0xf49ba278), TOBN(0xad956d9c, 0x64a50710), + TOBN(0x9561f28b, 0x638a7e81), TOBN(0x54155cdf, 0x5980ddc3), + TOBN(0xb2db4a96, 0xd26f247a), TOBN(0x9d774e4e, 0x4787d100), + TOBN(0x1a9e6e2e, 0x078637d2), TOBN(0x1c363e2d, 0x5e0ae06a), + TOBN(0x7493483e, 0xe9cfa354), TOBN(0x76843cb3, 0x7f74b98d), + TOBN(0xbaca6591, 0xd4b66947), TOBN(0xb452ce98, 0x04460a8c), + TOBN(0x6830d246, 0x43768f55), TOBN(0xf4197ed8, 0x7dff12df), + TOBN(0x6521b472, 0x400dd0f7), TOBN(0x59f5ca8f, 0x4b1e7093), + TOBN(0x6feff11b, 0x080338ae), TOBN(0x0ada31f6, 0xa29ca3c6), + TOBN(0x24794eb6, 0x94a2c215), TOBN(0xd83a43ab, 0x05a57ab4), + TOBN(0x264a543a, 0x2a6f89fe), TOBN(0x2c2a3868, 0xdd5ec7c2), + TOBN(0xd3373940, 0x8439d9b2), TOBN(0x715ea672, 0x0acd1f11), + TOBN(0x42c1d235, 0xe7e6cc19), TOBN(0x81ce6e96, 0xb990585c), + TOBN(0x04e5dfe0, 0xd809c7bd), TOBN(0xd7b2580c, 0x8f1050ab), + TOBN(0x6d91ad78, 0xd8a4176f), TOBN(0x0af556ee, 0x4e2e897c), + TOBN(0x162a8b73, 0x921de0ac), TOBN(0x52ac9c22, 0x7ea78400), + TOBN(0xee2a4eea, 0xefce2174), TOBN(0xbe61844e, 0x6d637f79), + TOBN(0x0491f1bc, 0x789a283b), TOBN(0x72d3ac3d, 0x880836f4), + TOBN(0xaa1c5ea3, 0x88e5402d), TOBN(0x1b192421, 0xd5cc473d), + TOBN(0x5c0b9998, 0x9dc84cac), TOBN(0xb0a8482d, 0x9c6e75b8), + TOBN(0x639961d0, 0x3a191ce2), TOBN(0xda3bc865, 0x6d837930), + TOBN(0xca990653, 0x056e6f8f), TOBN(0x84861c41, 0x64d133a7), + TOBN(0x8b403276, 0x746abe40), TOBN(0xb7b4d51a, 0xebf8e303), + TOBN(0x05b43211, 0x220a255d), TOBN(0xc997152c, 0x02419e6e), + TOBN(0x76ff47b6, 0x630c2fea), TOBN(0x50518677, 0x281fdade), + TOBN(0x3283b8ba, 0xcf902b0b), TOBN(0x8d4b4eb5, 0x37db303b), + TOBN(0xcc89f42d, 0x755011bc), TOBN(0xb43d74bb, 0xdd09d19b), + TOBN(0x65746bc9, 0x8adba350), TOBN(0x364eaf8c, 0xb51c1927), + TOBN(0x13c76596, 0x10ad72ec), TOBN(0x30045121, 0xf8d40c20), + TOBN(0x6d2d99b7, 0xea7b979b), TOBN(0xcd78cd74, 0xe6fb3bcd), + TOBN(0x11e45a9e, 0x86cffbfe), TOBN(0x78a61cf4, 0x637024f6), + TOBN(0xd06bc872, 0x3d502295), TOBN(0xf1376854, 0x458cb288), + TOBN(0xb9db26a1, 0x342f8586), TOBN(0xf33effcf, 0x4beee09e), + TOBN(0xd7e0c4cd, 0xb30cfb3a), TOBN(0x6d09b8c1, 0x6c9db4c8), + TOBN(0x40ba1a42, 0x07c8d9df), TOBN(0x6fd495f7, 0x1c52c66d), + TOBN(0xfb0e169f, 0x275264da), TOBN(0x80c2b746, 0xe57d8362), + TOBN(0xedd987f7, 0x49ad7222), TOBN(0xfdc229af, 0x4398ec7b)}, + {TOBN(0xb0d1ed84, 0x52666a58), TOBN(0x4bcb6e00, 0xe6a9c3c2), + TOBN(0x3c57411c, 0x26906408), TOBN(0xcfc20755, 0x13556400), + TOBN(0xa08b1c50, 0x5294dba3), TOBN(0xa30ba286, 0x8b7dd31e), + TOBN(0xd70ba90e, 0x991eca74), TOBN(0x094e142c, 0xe762c2b9), + TOBN(0xb81d783e, 0x979f3925), TOBN(0x1efd130a, 0xaf4c89a7), + TOBN(0x525c2144, 0xfd1bf7fa), TOBN(0x4b296904, 0x1b265a9e), + TOBN(0xed8e9634, 0xb9db65b6), TOBN(0x35c82e32, 0x03599d8a), + TOBN(0xdaa7a54f, 0x403563f3), TOBN(0x9df088ad, 0x022c38ab), + TOBN(0xe5cfb066, 0xbb3fd30a), TOBN(0x429169da, 0xeff0354e), + TOBN(0x809cf852, 0x3524e36c), TOBN(0x136f4fb3, 0x0155be1d), + TOBN(0x4826af01, 0x1fbba712), TOBN(0x6ef0f0b4, 0x506ba1a1), + TOBN(0xd9928b31, 0x77aea73e), TOBN(0xe2bf6af2, 0x5eaa244e), + TOBN(0x8d084f12, 0x4237b64b), TOBN(0x688ebe99, 0xe3ecfd07), + TOBN(0x57b8a70c, 0xf6845dd8), TOBN(0x808fc59c, 0x5da4a325), + TOBN(0xa9032b2b, 0xa3585862), TOBN(0xb66825d5, 0xedf29386), + TOBN(0xb5a5a8db, 0x431ec29b), TOBN(0xbb143a98, 0x3a1e8dc8), + TOBN(0x35ee94ce, 0x12ae381b), TOBN(0x3a7f176c, 0x86ccda90), + TOBN(0xc63a657e, 0x4606eaca), TOBN(0x9ae5a380, 0x43cd04df), + TOBN(0x9bec8d15, 0xed251b46), TOBN(0x1f5d6d30, 0xcaca5e64), + TOBN(0x347b3b35, 0x9ff20f07), TOBN(0x4d65f034, 0xf7e4b286), + TOBN(0x9e93ba24, 0xf111661e), TOBN(0xedced484, 0xb105eb04), + TOBN(0x96dc9ba1, 0xf424b578), TOBN(0xbf8f66b7, 0xe83e9069), + TOBN(0x872d4df4, 0xd7ed8216), TOBN(0xbf07f377, 0x8e2cbecf), + TOBN(0x4281d899, 0x98e73754), TOBN(0xfec85fbb, 0x8aab8708), + TOBN(0x9a3c0dee, 0xa5ba5b0b), TOBN(0xe6a116ce, 0x42d05299), + TOBN(0xae9775fe, 0xe9b02d42), TOBN(0x72b05200, 0xa1545cb6), + TOBN(0xbc506f7d, 0x31a3b4ea), TOBN(0xe5893078, 0x8bbd9b32), + TOBN(0xc8bc5f37, 0xe4b12a97), TOBN(0x6b000c06, 0x4a73b671), + TOBN(0x13b5bf22, 0x765fa7d0), TOBN(0x59805bf0, 0x1d6a5370), + TOBN(0x67a5e29d, 0x4280db98), TOBN(0x4f53916f, 0x776b1ce3), + TOBN(0x714ff61f, 0x33ddf626), TOBN(0x4206238e, 0xa085d103), + TOBN(0x1c50d4b7, 0xe5809ee3), TOBN(0x999f450d, 0x85f8eb1d), + TOBN(0x658a6051, 0xe4c79e9b), TOBN(0x1394cb73, 0xc66a9fea), + TOBN(0x27f31ed5, 0xc6be7b23), TOBN(0xf4c88f36, 0x5aa6f8fe), + TOBN(0x0fb0721f, 0x4aaa499e), TOBN(0x68b3a7d5, 0xe3fb2a6b), + TOBN(0xa788097d, 0x3a92851d), TOBN(0x060e7f8a, 0xe96f4913), + TOBN(0x82eebe73, 0x1a3a93bc), TOBN(0x42bbf465, 0xa21adc1a), + TOBN(0xc10b6fa4, 0xef030efd), TOBN(0x247aa4c7, 0x87b097bb), + TOBN(0x8b8dc632, 0xf60c77da), TOBN(0x6ffbc26a, 0xc223523e), + TOBN(0xa4f6ff11, 0x344579cf), TOBN(0x5825653c, 0x980250f6), + TOBN(0xb2dd097e, 0xbc1aa2b9), TOBN(0x07889393, 0x37a0333a), + TOBN(0x1cf55e71, 0x37a0db38), TOBN(0x2648487f, 0x792c1613), + TOBN(0xdad01336, 0x3fcef261), TOBN(0x6239c81d, 0x0eabf129), + TOBN(0x8ee761de, 0x9d276be2), TOBN(0x406a7a34, 0x1eda6ad3), + TOBN(0x4bf367ba, 0x4a493b31), TOBN(0x54f20a52, 0x9bf7f026), + TOBN(0xb696e062, 0x9795914b), TOBN(0xcddab96d, 0x8bf236ac), + TOBN(0x4ff2c70a, 0xed25ea13), TOBN(0xfa1d09eb, 0x81cbbbe7), + TOBN(0x88fc8c87, 0x468544c5), TOBN(0x847a670d, 0x696b3317), + TOBN(0xf133421e, 0x64bcb626), TOBN(0xaea638c8, 0x26dee0b5), + TOBN(0xd6e7680b, 0xb310346c), TOBN(0xe06f4097, 0xd5d4ced3), + TOBN(0x09961452, 0x7512a30b), TOBN(0xf3d867fd, 0xe589a59a), + TOBN(0x2e73254f, 0x52d0c180), TOBN(0x9063d8a3, 0x333c74ac), + TOBN(0xeda6c595, 0xd314e7bc), TOBN(0x2ee7464b, 0x467899ed), + TOBN(0x1cef423c, 0x0a1ed5d3), TOBN(0x217e76ea, 0x69cc7613), + TOBN(0x27ccce1f, 0xe7cda917), TOBN(0x12d8016b, 0x8a893f16), + TOBN(0xbcd6de84, 0x9fc74f6b), TOBN(0xfa5817e2, 0xf3144e61), + TOBN(0x1f354164, 0x0821ee4c), TOBN(0x1583eab4, 0x0bc61992), + TOBN(0x7490caf6, 0x1d72879f), TOBN(0x998ad9f3, 0xf76ae7b2), + TOBN(0x1e181950, 0xa41157f7), TOBN(0xa9d7e1e6, 0xe8da3a7e), + TOBN(0x963784eb, 0x8426b95f), TOBN(0x0ee4ed6e, 0x542e2a10), + TOBN(0xb79d4cc5, 0xac751e7b), TOBN(0x93f96472, 0xfd4211bd), + TOBN(0x8c72d3d2, 0xc8de4fc6), TOBN(0x7b69cbf5, 0xdf44f064), + TOBN(0x3da90ca2, 0xf4bf94e1), TOBN(0x1a5325f8, 0xf12894e2), + TOBN(0x0a437f6c, 0x7917d60b), TOBN(0x9be70486, 0x96c9cb5d), + TOBN(0xb4d880bf, 0xe1dc5c05), TOBN(0xd738adda, 0xeebeeb57), + TOBN(0x6f0119d3, 0xdf0fe6a3), TOBN(0x5c686e55, 0x66eaaf5a), + TOBN(0x9cb10b50, 0xdfd0b7ec), TOBN(0xbdd0264b, 0x6a497c21), + TOBN(0xfc093514, 0x8c546c96), TOBN(0x58a947fa, 0x79dbf42a), + TOBN(0xc0b48d4e, 0x49ccd6d7), TOBN(0xff8fb02c, 0x88bd5580), + TOBN(0xc75235e9, 0x07d473b2), TOBN(0x4fab1ac5, 0xa2188af3), + TOBN(0x030fa3bc, 0x97576ec0), TOBN(0xe8c946e8, 0x0b7e7d2f), + TOBN(0x40a5c9cc, 0x70305600), TOBN(0x6d8260a9, 0xc8b013b4), + TOBN(0x0368304f, 0x70bba85c), TOBN(0xad090da1, 0xa4a0d311), + TOBN(0x7170e870, 0x2415eec1), TOBN(0xbfba35fe, 0x8461ea47), + TOBN(0x6279019a, 0xc1e91938), TOBN(0xa47638f3, 0x1afc415f), + TOBN(0x36c65cbb, 0xbcba0e0f), TOBN(0x02160efb, 0x034e2c48), + TOBN(0xe6c51073, 0x615cd9e4), TOBN(0x498ec047, 0xf1243c06), + TOBN(0x3e5a8809, 0xb17b3d8c), TOBN(0x5cd99e61, 0x0cc565f1), + TOBN(0x81e312df, 0x7851dafe), TOBN(0xf156f5ba, 0xa79061e2), + TOBN(0x80d62b71, 0x880c590e), TOBN(0xbec9746f, 0x0a39faa1), + TOBN(0x1d98a9c1, 0xc8ed1f7a), TOBN(0x09e43bb5, 0xa81d5ff2), + TOBN(0xd5f00f68, 0x0da0794a), TOBN(0x412050d9, 0x661aa836), + TOBN(0xa89f7c4e, 0x90747e40), TOBN(0x6dc05ebb, 0xb62a3686), + TOBN(0xdf4de847, 0x308e3353), TOBN(0x53868fbb, 0x9fb53bb9), + TOBN(0x2b09d2c3, 0xcfdcf7dd), TOBN(0x41a9fce3, 0x723fcab4), + TOBN(0x73d905f7, 0x07f57ca3), TOBN(0x080f9fb1, 0xac8e1555), + TOBN(0x7c088e84, 0x9ba7a531), TOBN(0x07d35586, 0xed9a147f), + TOBN(0x602846ab, 0xaf48c336), TOBN(0x7320fd32, 0x0ccf0e79), + TOBN(0xaa780798, 0xb18bd1ff), TOBN(0x52c2e300, 0xafdd2905), + TOBN(0xf27ea3d6, 0x434267cd), TOBN(0x8b96d16d, 0x15605b5f), + TOBN(0x7bb31049, 0x4b45706b), TOBN(0xe7f58b8e, 0x743d25f8), + TOBN(0xe9b5e45b, 0x87f30076), TOBN(0xd19448d6, 0x5d053d5a), + TOBN(0x1ecc8cb9, 0xd3210a04), TOBN(0x6bc7d463, 0xdafb5269), + TOBN(0x3e59b10a, 0x67c3489f), TOBN(0x1769788c, 0x65641e1b), + TOBN(0x8a53b82d, 0xbd6cb838), TOBN(0x7066d6e6, 0x236d5f22), + TOBN(0x03aa1c61, 0x6908536e), TOBN(0xc971da0d, 0x66ae9809), + TOBN(0x01b3a86b, 0xc49a2fac), TOBN(0x3b8420c0, 0x3092e77a), + TOBN(0x02057300, 0x7d6fb556), TOBN(0x6941b2a1, 0xbff40a87), + TOBN(0x140b6308, 0x0658ff2a), TOBN(0x87804363, 0x3424ab36), + TOBN(0x0253bd51, 0x5751e299), TOBN(0xc75bcd76, 0x449c3e3a), + TOBN(0x92eb4090, 0x7f8f875d), TOBN(0x9c9d754e, 0x56c26bbf), + TOBN(0x158cea61, 0x8110bbe7), TOBN(0x62a6b802, 0x745f91ea), + TOBN(0xa79c41aa, 0xc6e7394b), TOBN(0x445b6a83, 0xad57ef10), + TOBN(0x0c5277eb, 0x6ea6f40c), TOBN(0x319fe96b, 0x88633365), + TOBN(0x0b0fc61f, 0x385f63cb), TOBN(0x41250c84, 0x22bdd127), + TOBN(0x67d153f1, 0x09e942c2), TOBN(0x60920d08, 0xc021ad5d), + TOBN(0x229f5746, 0x724d81a5), TOBN(0xb7ffb892, 0x5bba3299), + TOBN(0x518c51a1, 0xde413032), TOBN(0x2a9bfe77, 0x3c2fd94c), + TOBN(0xcbcde239, 0x3191f4fd), TOBN(0x43093e16, 0xd3d6ada1), + TOBN(0x184579f3, 0x58769606), TOBN(0x2c94a8b3, 0xd236625c), + TOBN(0x6922b9c0, 0x5c437d8e), TOBN(0x3d4ae423, 0xd8d9f3c8), + TOBN(0xf72c31c1, 0x2e7090a2), TOBN(0x4ac3f5f3, 0xd76a55bd), + TOBN(0x342508fc, 0x6b6af991), TOBN(0x0d527100, 0x1b5cebbd), + TOBN(0xb84740d0, 0xdd440dd7), TOBN(0x748ef841, 0x780162fd), + TOBN(0xa8dbfe0e, 0xdfc6fafb), TOBN(0xeadfdf05, 0xf7300f27), + TOBN(0x7d06555f, 0xfeba4ec9), TOBN(0x12c56f83, 0x9e25fa97), + TOBN(0x77f84203, 0xd39b8c34), TOBN(0xed8b1be6, 0x3125eddb), + TOBN(0x5bbf2441, 0xf6e39dc5), TOBN(0xb00f6ee6, 0x6a5d678a), + TOBN(0xba456ecf, 0x57d0ea99), TOBN(0xdcae0f58, 0x17e06c43), + TOBN(0x01643de4, 0x0f5b4baa), TOBN(0x2c324341, 0xd161b9be), + TOBN(0x80177f55, 0xe126d468), TOBN(0xed325f1f, 0x76748e09), + TOBN(0x6116004a, 0xcfa9bdc2), TOBN(0x2d8607e6, 0x3a9fb468), + TOBN(0x0e573e27, 0x6009d660), TOBN(0x3a525d2e, 0x8d10c5a1), + TOBN(0xd26cb45c, 0x3b9009a0), TOBN(0xb6b0cdc0, 0xde9d7448), + TOBN(0x949c9976, 0xe1337c26), TOBN(0x6faadebd, 0xd73d68e5), + TOBN(0x9e158614, 0xf1b768d9), TOBN(0x22dfa557, 0x9cc4f069), + TOBN(0xccd6da17, 0xbe93c6d6), TOBN(0x24866c61, 0xa504f5b9), + TOBN(0x2121353c, 0x8d694da1), TOBN(0x1c6ca580, 0x0140b8c6), + TOBN(0xc245ad8c, 0xe964021e), TOBN(0xb83bffba, 0x032b82b3), + TOBN(0xfaa220c6, 0x47ef9898), TOBN(0x7e8d3ac6, 0x982c948a), + TOBN(0x1faa2091, 0xbc2d124a), TOBN(0xbd54c3dd, 0x05b15ff4), + TOBN(0x386bf3ab, 0xc87c6fb7), TOBN(0xfb2b0563, 0xfdeb6f66), + TOBN(0x4e77c557, 0x5b45afb4), TOBN(0xe9ded649, 0xefb8912d), + TOBN(0x7ec9bbf5, 0x42f6e557), TOBN(0x2570dfff, 0x62671f00), + TOBN(0x2b3bfb78, 0x88e084bd), TOBN(0xa024b238, 0xf37fe5b4), + TOBN(0x44e7dc04, 0x95649aee), TOBN(0x498ca255, 0x5e7ec1d8), + TOBN(0x3bc766ea, 0xaaa07e86), TOBN(0x0db6facb, 0xf3608586), + TOBN(0xbadd2549, 0xbdc259c8), TOBN(0x95af3c6e, 0x041c649f), + TOBN(0xb36a928c, 0x02e30afb), TOBN(0x9b5356ad, 0x008a88b8), + TOBN(0x4b67a5f1, 0xcf1d9e9d), TOBN(0xc6542e47, 0xa5d8d8ce), + TOBN(0x73061fe8, 0x7adfb6cc), TOBN(0xcc826fd3, 0x98678141), + TOBN(0x00e758b1, 0x3c80515a), TOBN(0x6afe3247, 0x41485083), + TOBN(0x0fcb08b9, 0xb6ae8a75), TOBN(0xb8cf388d, 0x4acf51e1), + TOBN(0x344a5560, 0x6961b9d6), TOBN(0x1a6778b8, 0x6a97fd0c), + TOBN(0xd840fdc1, 0xecc4c7e3), TOBN(0xde9fe47d, 0x16db68cc), + TOBN(0xe95f89de, 0xa3e216aa), TOBN(0x84f1a6a4, 0x9594a8be), + TOBN(0x7ddc7d72, 0x5a7b162b), TOBN(0xc5cfda19, 0xadc817a3), + TOBN(0x80a5d350, 0x78b58d46), TOBN(0x93365b13, 0x82978f19), + TOBN(0x2e44d225, 0x26a1fc90), TOBN(0x0d6d10d2, 0x4d70705d), + TOBN(0xd94b6b10, 0xd70c45f4), TOBN(0x0f201022, 0xb216c079), + TOBN(0xcec966c5, 0x658fde41), TOBN(0xa8d2bc7d, 0x7e27601d), + TOBN(0xbfcce3e1, 0xff230be7), TOBN(0x3394ff6b, 0x0033ffb5), + TOBN(0xd890c509, 0x8132c9af), TOBN(0xaac4b0eb, 0x361e7868), + TOBN(0x5194ded3, 0xe82d15aa), TOBN(0x4550bd2e, 0x23ae6b7d), + TOBN(0x3fda318e, 0xea5399d4), TOBN(0xd989bffa, 0x91638b80), + TOBN(0x5ea124d0, 0xa14aa12d), TOBN(0x1fb1b899, 0x3667b944), + TOBN(0x95ec7969, 0x44c44d6a), TOBN(0x91df144a, 0x57e86137), + TOBN(0x915fd620, 0x73adac44), TOBN(0x8f01732d, 0x59a83801), + TOBN(0xec579d25, 0x3aa0a633), TOBN(0x06de5e7c, 0xc9d6d59c), + TOBN(0xc132f958, 0xb1ef8010), TOBN(0x29476f96, 0xe65c1a02), + TOBN(0x336a77c0, 0xd34c3565), TOBN(0xef1105b2, 0x1b9f1e9e), + TOBN(0x63e6d08b, 0xf9e08002), TOBN(0x9aff2f21, 0xc613809e), + TOBN(0xb5754f85, 0x3a80e75d), TOBN(0xde71853e, 0x6bbda681), + TOBN(0x86f041df, 0x8197fd7a), TOBN(0x8b332e08, 0x127817fa), + TOBN(0x05d99be8, 0xb9c20cda), TOBN(0x89f7aad5, 0xd5cd0c98), + TOBN(0x7ef936fe, 0x5bb94183), TOBN(0x92ca0753, 0xb05cd7f2), + TOBN(0x9d65db11, 0x74a1e035), TOBN(0x02628cc8, 0x13eaea92), + TOBN(0xf2d9e242, 0x49e4fbf2), TOBN(0x94fdfd9b, 0xe384f8b7), + TOBN(0x65f56054, 0x63428c6b), TOBN(0x2f7205b2, 0x90b409a5), + TOBN(0xf778bb78, 0xff45ae11), TOBN(0xa13045be, 0xc5ee53b2), + TOBN(0xe00a14ff, 0x03ef77fe), TOBN(0x689cd59f, 0xffef8bef), + TOBN(0x3578f0ed, 0x1e9ade22), TOBN(0xe99f3ec0, 0x6268b6a8), + TOBN(0xa2057d91, 0xea1b3c3e), TOBN(0x2d1a7053, 0xb8823a4a), + TOBN(0xabbb336a, 0x2cca451e), TOBN(0xcd2466e3, 0x2218bb5d), + TOBN(0x3ac1f42f, 0xc8cb762d), TOBN(0x7e312aae, 0x7690211f), + TOBN(0xebb9bd73, 0x45d07450), TOBN(0x207c4b82, 0x46c2213f), + TOBN(0x99d425c1, 0x375913ec), TOBN(0x94e45e96, 0x67908220), + TOBN(0xc08f3087, 0xcd67dbf6), TOBN(0xa5670fbe, 0xc0887056), + TOBN(0x6717b64a, 0x66f5b8fc), TOBN(0xd5a56aea, 0x786fec28), + TOBN(0xa8c3f55f, 0xc0ff4952), TOBN(0xa77fefae, 0x457ac49b), + TOBN(0x29882d7c, 0x98379d44), TOBN(0xd000bdfb, 0x509edc8a), + TOBN(0xc6f95979, 0xe66fe464), TOBN(0x504a6115, 0xfa61bde0), + TOBN(0x56b3b871, 0xeffea31a), TOBN(0x2d3de26d, 0xf0c21a54), + TOBN(0x21dbff31, 0x834753bf), TOBN(0xe67ecf49, 0x69269d86), + TOBN(0x7a176952, 0x151fe690), TOBN(0x03515804, 0x7f2adb5f), + TOBN(0xee794b15, 0xd1b62a8d), TOBN(0xf004ceec, 0xaae454e6), + TOBN(0x0897ea7c, 0xf0386fac), TOBN(0x3b62ff12, 0xd1fca751), + TOBN(0x154181df, 0x1b7a04ec), TOBN(0x2008e04a, 0xfb5847ec), + TOBN(0xd147148e, 0x41dbd772), TOBN(0x2b419f73, 0x22942654), + TOBN(0x669f30d3, 0xe9c544f7), TOBN(0x52a2c223, 0xc8540149), + TOBN(0x5da9ee14, 0x634dfb02), TOBN(0x5f074ff0, 0xf47869f3), + TOBN(0x74ee878d, 0xa3933acc), TOBN(0xe6510651, 0x4fe35ed1), + TOBN(0xb3eb9482, 0xf1012e7a), TOBN(0x51013cc0, 0xa8a566ae), + TOBN(0xdd5e9243, 0x47c00d3b), TOBN(0x7fde089d, 0x946bb0e5), + TOBN(0x030754fe, 0xc731b4b3), TOBN(0x12a136a4, 0x99fda062), + TOBN(0x7c1064b8, 0x5a1a35bc), TOBN(0xbf1f5763, 0x446c84ef), + TOBN(0xed29a56d, 0xa16d4b34), TOBN(0x7fba9d09, 0xdca21c4f), + TOBN(0x66d7ac00, 0x6d8de486), TOBN(0x60061987, 0x73a2a5e1), + TOBN(0x8b400f86, 0x9da28ff0), TOBN(0x3133f708, 0x43c4599c), + TOBN(0x9911c9b8, 0xee28cb0d), TOBN(0xcd7e2874, 0x8e0af61d), + TOBN(0x5a85f0f2, 0x72ed91fc), TOBN(0x85214f31, 0x9cd4a373), + TOBN(0x881fe5be, 0x1925253c), TOBN(0xd8dc98e0, 0x91e8bc76), + TOBN(0x7120affe, 0x585cc3a2), TOBN(0x724952ed, 0x735bf97a), + TOBN(0x5581e7dc, 0x3eb34581), TOBN(0x5cbff4f2, 0xe52ee57d), + TOBN(0x8d320a0e, 0x87d8cc7b), TOBN(0x9beaa7f3, 0xf1d280d0), + TOBN(0x7a0b9571, 0x9beec704), TOBN(0x9126332e, 0x5b7f0057), + TOBN(0x01fbc1b4, 0x8ed3bd6d), TOBN(0x35bb2c12, 0xd945eb24), + TOBN(0x6404694e, 0x9a8ae255), TOBN(0xb6092eec, 0x8d6abfb3), + TOBN(0x4d76143f, 0xcc058865), TOBN(0x7b0a5af2, 0x6e249922), + TOBN(0x8aef9440, 0x6a50d353), TOBN(0xe11e4bcc, 0x64f0e07a), + TOBN(0x4472993a, 0xa14a90fa), TOBN(0x7706e20c, 0xba0c51d4), + TOBN(0xf403292f, 0x1532672d), TOBN(0x52573bfa, 0x21829382), + TOBN(0x6a7bb6a9, 0x3b5bdb83), TOBN(0x08da65c0, 0xa4a72318), + TOBN(0xc58d22aa, 0x63eb065f), TOBN(0x1717596c, 0x1b15d685), + TOBN(0x112df0d0, 0xb266d88b), TOBN(0xf688ae97, 0x5941945a), + TOBN(0x487386e3, 0x7c292cac), TOBN(0x42f3b50d, 0x57d6985c), + TOBN(0x6da4f998, 0x6a90fc34), TOBN(0xc8f257d3, 0x65ca8a8d), + TOBN(0xc2feabca, 0x6951f762), TOBN(0xe1bc81d0, 0x74c323ac), + TOBN(0x1bc68f67, 0x251a2a12), TOBN(0x10d86587, 0xbe8a70dc), + TOBN(0xd648af7f, 0xf0f84d2e), TOBN(0xf0aa9ebc, 0x6a43ac92), + TOBN(0x69e3be04, 0x27596893), TOBN(0xb6bb02a6, 0x45bf452b), + TOBN(0x0875c11a, 0xf4c698c8), TOBN(0x6652b5c7, 0xbece3794), + TOBN(0x7b3755fd, 0x4f5c0499), TOBN(0x6ea16558, 0xb5532b38), + TOBN(0xd1c69889, 0xa2e96ef7), TOBN(0x9c773c3a, 0x61ed8f48), + TOBN(0x2b653a40, 0x9b323abc), TOBN(0xe26605e1, 0xf0e1d791), + TOBN(0x45d41064, 0x4a87157a), TOBN(0x8f9a78b7, 0xcbbce616), + TOBN(0xcf1e44aa, 0xc407eddd), TOBN(0x81ddd1d8, 0xa35b964f), + TOBN(0x473e339e, 0xfd083999), TOBN(0x6c94bdde, 0x8e796802), + TOBN(0x5a304ada, 0x8545d185), TOBN(0x82ae44ea, 0x738bb8cb), + TOBN(0x628a35e3, 0xdf87e10e), TOBN(0xd3624f3d, 0xa15b9fe3), + TOBN(0xcc44209b, 0x14be4254), TOBN(0x7d0efcbc, 0xbdbc2ea5), + TOBN(0x1f603362, 0x04c37bbe), TOBN(0x21f363f5, 0x56a5852c), + TOBN(0xa1503d1c, 0xa8501550), TOBN(0x2251e0e1, 0xd8ab10bb), + TOBN(0xde129c96, 0x6961c51c), TOBN(0x1f7246a4, 0x81910f68), + TOBN(0x2eb744ee, 0x5f2591f2), TOBN(0x3c47d33f, 0x5e627157), + TOBN(0x4d6d62c9, 0x22f3bd68), TOBN(0x6120a64b, 0xcb8df856), + TOBN(0x3a9ac6c0, 0x7b5d07df), TOBN(0xa92b9558, 0x7ef39783), + TOBN(0xe128a134, 0xab3a9b4f), TOBN(0x41c18807, 0xb1252f05), + TOBN(0xfc7ed089, 0x80ba9b1c), TOBN(0xac8dc6de, 0xc532a9dd), + TOBN(0xbf829cef, 0x55246809), TOBN(0x101b784f, 0x5b4ee80f), + TOBN(0xc09945bb, 0xb6f11603), TOBN(0x57b09dbe, 0x41d2801e), + TOBN(0xfba5202f, 0xa97534a8), TOBN(0x7fd8ae5f, 0xc17b9614), + TOBN(0xa50ba666, 0x78308435), TOBN(0x9572f77c, 0xd3868c4d), + TOBN(0x0cef7bfd, 0x2dd7aab0), TOBN(0xe7958e08, 0x2c7c79ff), + TOBN(0x81262e42, 0x25346689), TOBN(0x716da290, 0xb07c7004), + TOBN(0x35f911ea, 0xb7950ee3), TOBN(0x6fd72969, 0x261d21b5), + TOBN(0x52389803, 0x08b640d3), TOBN(0x5b0026ee, 0x887f12a1), + TOBN(0x20e21660, 0x742e9311), TOBN(0x0ef6d541, 0x5ff77ff7), + TOBN(0x969127f0, 0xf9c41135), TOBN(0xf21d60c9, 0x68a64993), + TOBN(0x656e5d0c, 0xe541875c), TOBN(0xf1e0f84e, 0xa1d3c233), + TOBN(0x9bcca359, 0x06002d60), TOBN(0xbe2da60c, 0x06191552), + TOBN(0x5da8bbae, 0x61181ec3), TOBN(0x9f04b823, 0x65806f19), + TOBN(0xf1604a7d, 0xd4b79bb8), TOBN(0xaee806fb, 0x52c878c8), + TOBN(0x34144f11, 0x8d47b8e8), TOBN(0x72edf52b, 0x949f9054), + TOBN(0xebfca84e, 0x2127015a), TOBN(0x9051d0c0, 0x9cb7cef3), + TOBN(0x86e8fe58, 0x296deec8), TOBN(0x33b28188, 0x41010d74)}, + {TOBN(0x01079383, 0x171b445f), TOBN(0x9bcf21e3, 0x8131ad4c), + TOBN(0x8cdfe205, 0xc93987e8), TOBN(0xe63f4152, 0xc92e8c8f), + TOBN(0x729462a9, 0x30add43d), TOBN(0x62ebb143, 0xc980f05a), + TOBN(0x4f3954e5, 0x3b06e968), TOBN(0xfe1d75ad, 0x242cf6b1), + TOBN(0x5f95c6c7, 0xaf8685c8), TOBN(0xd4c1c8ce, 0x2f8f01aa), + TOBN(0xc44bbe32, 0x2574692a), TOBN(0xb8003478, 0xd4a4a068), + TOBN(0x7c8fc6e5, 0x2eca3cdb), TOBN(0xea1db16b, 0xec04d399), + TOBN(0xb05bc82e, 0x8f2bc5cf), TOBN(0x763d517f, 0xf44793d2), + TOBN(0x4451c1b8, 0x08bd98d0), TOBN(0x644b1cd4, 0x6575f240), + TOBN(0x6907eb33, 0x7375d270), TOBN(0x56c8bebd, 0xfa2286bd), + TOBN(0xc713d2ac, 0xc4632b46), TOBN(0x17da427a, 0xafd60242), + TOBN(0x313065b7, 0xc95c7546), TOBN(0xf8239898, 0xbf17a3de), + TOBN(0xf3b7963f, 0x4c830320), TOBN(0x842c7aa0, 0x903203e3), + TOBN(0xaf22ca0a, 0xe7327afb), TOBN(0x38e13092, 0x967609b6), + TOBN(0x73b8fb62, 0x757558f1), TOBN(0x3cc3e831, 0xf7eca8c1), + TOBN(0xe4174474, 0xf6331627), TOBN(0xa77989ca, 0xc3c40234), + TOBN(0xe5fd17a1, 0x44a081e0), TOBN(0xd797fb7d, 0xb70e296a), + TOBN(0x2b472b30, 0x481f719c), TOBN(0x0e632a98, 0xfe6f8c52), + TOBN(0x89ccd116, 0xc5f0c284), TOBN(0xf51088af, 0x2d987c62), + TOBN(0x2a2bccda, 0x4c2de6cf), TOBN(0x810f9efe, 0xf679f0f9), + TOBN(0xb0f394b9, 0x7ffe4b3e), TOBN(0x0b691d21, 0xe5fa5d21), + TOBN(0xb0bd7747, 0x9dfbbc75), TOBN(0xd2830fda, 0xfaf78b00), + TOBN(0xf78c249c, 0x52434f57), TOBN(0x4b1f7545, 0x98096dab), + TOBN(0x73bf6f94, 0x8ff8c0b3), TOBN(0x34aef03d, 0x454e134c), + TOBN(0xf8d151f4, 0xb7ac7ec5), TOBN(0xd6ceb95a, 0xe50da7d5), + TOBN(0xa1b492b0, 0xdc3a0eb8), TOBN(0x75157b69, 0xb3dd2863), + TOBN(0xe2c4c74e, 0xc5413d62), TOBN(0xbe329ff7, 0xbc5fc4c7), + TOBN(0x835a2aea, 0x60fa9dda), TOBN(0xf117f5ad, 0x7445cb87), + TOBN(0xae8317f4, 0xb0166f7a), TOBN(0xfbd3e3f7, 0xceec74e6), + TOBN(0xfdb516ac, 0xe0874bfd), TOBN(0x3d846019, 0xc681f3a3), + TOBN(0x0b12ee5c, 0x7c1620b0), TOBN(0xba68b4dd, 0x2b63c501), + TOBN(0xac03cd32, 0x6668c51e), TOBN(0x2a6279f7, 0x4e0bcb5b), + TOBN(0x17bd69b0, 0x6ae85c10), TOBN(0x72946979, 0x1dfdd3a6), + TOBN(0xd9a03268, 0x2c078bec), TOBN(0x41c6a658, 0xbfd68a52), + TOBN(0xcdea1024, 0x0e023900), TOBN(0xbaeec121, 0xb10d144d), + TOBN(0x5a600e74, 0x058ab8dc), TOBN(0x1333af21, 0xbb89ccdd), + TOBN(0xdf25eae0, 0x3aaba1f1), TOBN(0x2cada16e, 0x3b7144cf), + TOBN(0x657ee27d, 0x71ab98bc), TOBN(0x99088b4c, 0x7a6fc96e), + TOBN(0x05d5c0a0, 0x3549dbd4), TOBN(0x42cbdf8f, 0xf158c3ac), + TOBN(0x3fb6b3b0, 0x87edd685), TOBN(0x22071cf6, 0x86f064d0), + TOBN(0xd2d6721f, 0xff2811e5), TOBN(0xdb81b703, 0xfe7fae8c), + TOBN(0x3cfb74ef, 0xd3f1f7bb), TOBN(0x0cdbcd76, 0x16cdeb5d), + TOBN(0x4f39642a, 0x566a808c), TOBN(0x02b74454, 0x340064d6), + TOBN(0xfabbadca, 0x0528fa6f), TOBN(0xe4c3074c, 0xd3fc0bb6), + TOBN(0xb32cb8b0, 0xb796d219), TOBN(0xc3e95f4f, 0x34741dd9), + TOBN(0x87212125, 0x68edf6f5), TOBN(0x7a03aee4, 0xa2b9cb8e), + TOBN(0x0cd3c376, 0xf53a89aa), TOBN(0x0d8af9b1, 0x948a28dc), + TOBN(0xcf86a3f4, 0x902ab04f), TOBN(0x8aacb62a, 0x7f42002d), + TOBN(0x106985eb, 0xf62ffd52), TOBN(0xe670b54e, 0x5797bf10), + TOBN(0x4b405209, 0xc5e30aef), TOBN(0x12c97a20, 0x4365b5e9), + TOBN(0x104646ce, 0x1fe32093), TOBN(0x13cb4ff6, 0x3907a8c9), + TOBN(0x8b9f30d1, 0xd46e726b), TOBN(0xe1985e21, 0xaba0f499), + TOBN(0xc573dea9, 0x10a230cd), TOBN(0x24f46a93, 0xcd30f947), + TOBN(0xf2623fcf, 0xabe2010a), TOBN(0x3f278cb2, 0x73f00e4f), + TOBN(0xed55c67d, 0x50b920eb), TOBN(0xf1cb9a2d, 0x8e760571), + TOBN(0x7c50d109, 0x0895b709), TOBN(0x4207cf07, 0x190d4369), + TOBN(0x3b027e81, 0xc4127fe1), TOBN(0xa9f8b9ad, 0x3ae9c566), + TOBN(0x5ab10851, 0xacbfbba5), TOBN(0xa747d648, 0x569556f5), + TOBN(0xcc172b5c, 0x2ba97bf7), TOBN(0x15e0f77d, 0xbcfa3324), + TOBN(0xa345b797, 0x7686279d), TOBN(0x5a723480, 0xe38003d3), + TOBN(0xfd8e139f, 0x8f5fcda8), TOBN(0xf3e558c4, 0xbdee5bfd), + TOBN(0xd76cbaf4, 0xe33f9f77), TOBN(0x3a4c97a4, 0x71771969), + TOBN(0xda27e84b, 0xf6dce6a7), TOBN(0xff373d96, 0x13e6c2d1), + TOBN(0xf115193c, 0xd759a6e9), TOBN(0x3f9b7025, 0x63d2262c), + TOBN(0xd9764a31, 0x317cd062), TOBN(0x30779d8e, 0x199f8332), + TOBN(0xd8074106, 0x16b11b0b), TOBN(0x7917ab9f, 0x78aeaed8), + TOBN(0xb67a9cbe, 0x28fb1d8e), TOBN(0x2e313563, 0x136eda33), + TOBN(0x010b7069, 0xa371a86c), TOBN(0x44d90fa2, 0x6744e6b7), + TOBN(0x68190867, 0xd6b3e243), TOBN(0x9fe6cd9d, 0x59048c48), + TOBN(0xb900b028, 0x95731538), TOBN(0xa012062f, 0x32cae04f), + TOBN(0x8107c8bc, 0x9399d082), TOBN(0x47e8c54a, 0x41df12e2), + TOBN(0x14ba5117, 0xb6ef3f73), TOBN(0x22260bea, 0x81362f0b), + TOBN(0x90ea261e, 0x1a18cc20), TOBN(0x2192999f, 0x2321d636), + TOBN(0xef64d314, 0xe311b6a0), TOBN(0xd7401e4c, 0x3b54a1f5), + TOBN(0x19019983, 0x6fbca2ba), TOBN(0x46ad3293, 0x8fbffc4b), + TOBN(0xa142d3f6, 0x3786bf40), TOBN(0xeb5cbc26, 0xb67039fc), + TOBN(0x9cb0ae6c, 0x252bd479), TOBN(0x05e0f88a, 0x12b5848f), + TOBN(0x78f6d2b2, 0xa5c97663), TOBN(0x6f6e149b, 0xc162225c), + TOBN(0xe602235c, 0xde601a89), TOBN(0xd17bbe98, 0xf373be1f), + TOBN(0xcaf49a5b, 0xa8471827), TOBN(0x7e1a0a85, 0x18aaa116), + TOBN(0x6c833196, 0x270580c3), TOBN(0x1e233839, 0xf1c98a14), + TOBN(0x67b2f7b4, 0xae34e0a5), TOBN(0x47ac8745, 0xd8ce7289), + TOBN(0x2b74779a, 0x100dd467), TOBN(0x274a4337, 0x4ee50d09), + TOBN(0x603dcf13, 0x83608bc9), TOBN(0xcd9da6c3, 0xc89e8388), + TOBN(0x2660199f, 0x355116ac), TOBN(0xcc38bb59, 0xb6d18eed), + TOBN(0x3075f31f, 0x2f4bc071), TOBN(0x9774457f, 0x265dc57e), + TOBN(0x06a6a9c8, 0xc6db88bb), TOBN(0x6429d07f, 0x4ec98e04), + TOBN(0x8d05e57b, 0x05ecaa8b), TOBN(0x20f140b1, 0x7872ea7b), + TOBN(0xdf8c0f09, 0xca494693), TOBN(0x48d3a020, 0xf252e909), + TOBN(0x4c5c29af, 0x57b14b12), TOBN(0x7e6fa37d, 0xbf47ad1c), + TOBN(0x66e7b506, 0x49a0c938), TOBN(0xb72c0d48, 0x6be5f41f), + TOBN(0x6a6242b8, 0xb2359412), TOBN(0xcd35c774, 0x8e859480), + TOBN(0x12536fea, 0x87baa627), TOBN(0x58c1fec1, 0xf72aa680), + TOBN(0x6c29b637, 0x601e5dc9), TOBN(0x9e3c3c1c, 0xde9e01b9), + TOBN(0xefc8127b, 0x2bcfe0b0), TOBN(0x35107102, 0x2a12f50d), + TOBN(0x6ccd6cb1, 0x4879b397), TOBN(0xf792f804, 0xf8a82f21), + TOBN(0x509d4804, 0xa9b46402), TOBN(0xedddf85d, 0xc10f0850), + TOBN(0x928410dc, 0x4b6208aa), TOBN(0xf6229c46, 0x391012dc), + TOBN(0xc5a7c41e, 0x7727b9b6), TOBN(0x289e4e4b, 0xaa444842), + TOBN(0x049ba1d9, 0xe9a947ea), TOBN(0x44f9e47f, 0x83c8debc), + TOBN(0xfa77a1fe, 0x611f8b8e), TOBN(0xfd2e416a, 0xf518f427), + TOBN(0xc5fffa70, 0x114ebac3), TOBN(0xfe57c4e9, 0x5d89697b), + TOBN(0xfdd053ac, 0xb1aaf613), TOBN(0x31df210f, 0xea585a45), + TOBN(0x318cc10e, 0x24985034), TOBN(0x1a38efd1, 0x5f1d6130), + TOBN(0xbf86f237, 0x0b1e9e21), TOBN(0xb258514d, 0x1dbe88aa), + TOBN(0x1e38a588, 0x90c1baf9), TOBN(0x2936a01e, 0xbdb9b692), + TOBN(0xd576de98, 0x6dd5b20c), TOBN(0xb586bf71, 0x70f98ecf), + TOBN(0xcccf0f12, 0xc42d2fd7), TOBN(0x8717e61c, 0xfb35bd7b), + TOBN(0x8b1e5722, 0x35e6fc06), TOBN(0x3477728f, 0x0b3e13d5), + TOBN(0x150c294d, 0xaa8a7372), TOBN(0xc0291d43, 0x3bfa528a), + TOBN(0xc6c8bc67, 0xcec5a196), TOBN(0xdeeb31e4, 0x5c2e8a7c), + TOBN(0xba93e244, 0xfb6e1c51), TOBN(0xb9f8b71b, 0x2e28e156), + TOBN(0xce65a287, 0x968a2ab9), TOBN(0xe3c5ce69, 0x46bbcb1f), + TOBN(0xf8c835b9, 0xe7ae3f30), TOBN(0x16bbee26, 0xff72b82b), + TOBN(0x665e2017, 0xfd42cd22), TOBN(0x1e139970, 0xf8b1d2a0), + TOBN(0x125cda29, 0x79204932), TOBN(0x7aee94a5, 0x49c3bee5), + TOBN(0x68c70160, 0x89821a66), TOBN(0xf7c37678, 0x8f981669), + TOBN(0xd90829fc, 0x48cc3645), TOBN(0x346af049, 0xd70addfc), + TOBN(0x2057b232, 0x370bf29c), TOBN(0xf90c73ce, 0x42e650ee), + TOBN(0xe03386ea, 0xa126ab90), TOBN(0x0e266e7e, 0x975a087b), + TOBN(0x80578eb9, 0x0fca65d9), TOBN(0x7e2989ea, 0x16af45b8), + TOBN(0x7438212d, 0xcac75a4e), TOBN(0x38c7ca39, 0x4fef36b8), + TOBN(0x8650c494, 0xd402676a), TOBN(0x26ab5a66, 0xf72c7c48), + TOBN(0x4e6cb426, 0xce3a464e), TOBN(0xf8f99896, 0x2b72f841), + TOBN(0x8c318491, 0x1a335cc8), TOBN(0x563459ba, 0x6a5913e4), + TOBN(0x1b920d61, 0xc7b32919), TOBN(0x805ab8b6, 0xa02425ad), + TOBN(0x2ac512da, 0x8d006086), TOBN(0x6ca4846a, 0xbcf5c0fd), + TOBN(0xafea51d8, 0xac2138d7), TOBN(0xcb647545, 0x344cd443), + TOBN(0x0429ee8f, 0xbd7d9040), TOBN(0xee66a2de, 0x819b9c96), + TOBN(0x54f9ec25, 0xdea7d744), TOBN(0x2ffea642, 0x671721bb), + TOBN(0x4f19dbd1, 0x114344ea), TOBN(0x04304536, 0xfd0dbc8b), + TOBN(0x014b50aa, 0x29ec7f91), TOBN(0xb5fc22fe, 0xbb06014d), + TOBN(0x60d963a9, 0x1ee682e0), TOBN(0xdf48abc0, 0xfe85c727), + TOBN(0x0cadba13, 0x2e707c2d), TOBN(0xde608d3a, 0xa645aeff), + TOBN(0x05f1c28b, 0xedafd883), TOBN(0x3c362ede, 0xbd94de1f), + TOBN(0x8dd0629d, 0x13593e41), TOBN(0x0a5e736f, 0x766d6eaf), + TOBN(0xbfa92311, 0xf68cf9d1), TOBN(0xa4f9ef87, 0xc1797556), + TOBN(0x10d75a1f, 0x5601c209), TOBN(0x651c374c, 0x09b07361), + TOBN(0x49950b58, 0x88b5cead), TOBN(0x0ef00058, 0x6fa9dbaa), + TOBN(0xf51ddc26, 0x4e15f33a), TOBN(0x1f8b5ca6, 0x2ef46140), + TOBN(0x343ac0a3, 0xee9523f0), TOBN(0xbb75eab2, 0x975ea978), + TOBN(0x1bccf332, 0x107387f4), TOBN(0x790f9259, 0x9ab0062e), + TOBN(0xf1a363ad, 0x1e4f6a5f), TOBN(0x06e08b84, 0x62519a50), + TOBN(0x60915187, 0x7265f1ee), TOBN(0x6a80ca34, 0x93ae985e), + TOBN(0x81b29768, 0xaaba4864), TOBN(0xb13cabf2, 0x8d52a7d6), + TOBN(0xb5c36348, 0x8ead03f1), TOBN(0xc932ad95, 0x81c7c1c0), + TOBN(0x5452708e, 0xcae1e27b), TOBN(0x9dac4269, 0x1b0df648), + TOBN(0x233e3f0c, 0xdfcdb8bc), TOBN(0xe6ceccdf, 0xec540174), + TOBN(0xbd0d845e, 0x95081181), TOBN(0xcc8a7920, 0x699355d5), + TOBN(0x111c0f6d, 0xc3b375a8), TOBN(0xfd95bc6b, 0xfd51e0dc), + TOBN(0x4a106a26, 0x6888523a), TOBN(0x4d142bd6, 0xcb01a06d), + TOBN(0x79bfd289, 0xadb9b397), TOBN(0x0bdbfb94, 0xe9863914), + TOBN(0x29d8a229, 0x1660f6a6), TOBN(0x7f6abcd6, 0x551c042d), + TOBN(0x13039deb, 0x0ac3ffe8), TOBN(0xa01be628, 0xec8523fb), + TOBN(0x6ea34103, 0x0ca1c328), TOBN(0xc74114bd, 0xb903928e), + TOBN(0x8aa4ff4e, 0x9e9144b0), TOBN(0x7064091f, 0x7f9a4b17), + TOBN(0xa3f4f521, 0xe447f2c4), TOBN(0x81b8da7a, 0x604291f0), + TOBN(0xd680bc46, 0x7d5926de), TOBN(0x84f21fd5, 0x34a1202f), + TOBN(0x1d1e3181, 0x4e9df3d8), TOBN(0x1ca4861a, 0x39ab8d34), + TOBN(0x809ddeec, 0x5b19aa4a), TOBN(0x59f72f7e, 0x4d329366), + TOBN(0xa2f93f41, 0x386d5087), TOBN(0x40bf739c, 0xdd67d64f), + TOBN(0xb4494205, 0x66702158), TOBN(0xc33c65be, 0x73b1e178), + TOBN(0xcdcd657c, 0x38ca6153), TOBN(0x97f4519a, 0xdc791976), + TOBN(0xcc7c7f29, 0xcd6e1f39), TOBN(0x38de9cfb, 0x7e3c3932), + TOBN(0xe448eba3, 0x7b793f85), TOBN(0xe9f8dbf9, 0xf067e914), + TOBN(0xc0390266, 0xf114ae87), TOBN(0x39ed75a7, 0xcd6a8e2a), + TOBN(0xadb14848, 0x7ffba390), TOBN(0x67f8cb8b, 0x6af9bc09), + TOBN(0x322c3848, 0x9c7476db), TOBN(0xa320fecf, 0x52a538d6), + TOBN(0xe0493002, 0xb2aced2b), TOBN(0xdfba1809, 0x616bd430), + TOBN(0x531c4644, 0xc331be70), TOBN(0xbc04d32e, 0x90d2e450), + TOBN(0x1805a0d1, 0x0f9f142d), TOBN(0x2c44a0c5, 0x47ee5a23), + TOBN(0x31875a43, 0x3989b4e3), TOBN(0x6b1949fd, 0x0c063481), + TOBN(0x2dfb9e08, 0xbe0f4492), TOBN(0x3ff0da03, 0xe9d5e517), + TOBN(0x03dbe9a1, 0xf79466a8), TOBN(0x0b87bcd0, 0x15ea9932), + TOBN(0xeb64fc83, 0xab1f58ab), TOBN(0x6d9598da, 0x817edc8a), + TOBN(0x699cff66, 0x1d3b67e5), TOBN(0x645c0f29, 0x92635853), + TOBN(0x253cdd82, 0xeabaf21c), TOBN(0x82b9602a, 0x2241659e), + TOBN(0x2cae07ec, 0x2d9f7091), TOBN(0xbe4c720c, 0x8b48cd9b), + TOBN(0x6ce5bc03, 0x6f08d6c9), TOBN(0x36e8a997, 0xaf10bf40), + TOBN(0x83422d21, 0x3e10ff12), TOBN(0x7b26d3eb, 0xbcc12494), + TOBN(0xb240d2d0, 0xc9469ad6), TOBN(0xc4a11b4d, 0x30afa05b), + TOBN(0x4b604ace, 0xdd6ba286), TOBN(0x18486600, 0x3ee2864c), + TOBN(0x5869d6ba, 0x8d9ce5be), TOBN(0x0d8f68c5, 0xff4bfb0d), + TOBN(0xb69f210b, 0x5700cf73), TOBN(0x61f6653a, 0x6d37c135), + TOBN(0xff3d432b, 0x5aff5a48), TOBN(0x0d81c4b9, 0x72ba3a69), + TOBN(0xee879ae9, 0xfa1899ef), TOBN(0xbac7e2a0, 0x2d6acafd), + TOBN(0xd6d93f6c, 0x1c664399), TOBN(0x4c288de1, 0x5bcb135d), + TOBN(0x83031dab, 0x9dab7cbf), TOBN(0xfe23feb0, 0x3abbf5f0), + TOBN(0x9f1b2466, 0xcdedca85), TOBN(0x140bb710, 0x1a09538c), + TOBN(0xac8ae851, 0x5e11115d), TOBN(0x0d63ff67, 0x6f03f59e), + TOBN(0x755e5551, 0x7d234afb), TOBN(0x61c2db4e, 0x7e208fc1), + TOBN(0xaa9859ce, 0xf28a4b5d), TOBN(0xbdd6d4fc, 0x34af030f), + TOBN(0xd1c4a26d, 0x3be01cb1), TOBN(0x9ba14ffc, 0x243aa07c), + TOBN(0xf95cd3a9, 0xb2503502), TOBN(0xe379bc06, 0x7d2a93ab), + TOBN(0x3efc18e9, 0xd4ca8d68), TOBN(0x083558ec, 0x80bb412a), + TOBN(0xd903b940, 0x9645a968), TOBN(0xa499f0b6, 0x9ba6054f), + TOBN(0x208b573c, 0xb8349abe), TOBN(0x3baab3e5, 0x30b4fc1c), + TOBN(0x87e978ba, 0xcb524990), TOBN(0x3524194e, 0xccdf0e80), + TOBN(0x62711725, 0x7d4bcc42), TOBN(0xe90a3d9b, 0xb90109ba), + TOBN(0x3b1bdd57, 0x1323e1e0), TOBN(0xb78e9bd5, 0x5eae1599), + TOBN(0x0794b746, 0x9e03d278), TOBN(0x80178605, 0xd70e6297), + TOBN(0x171792f8, 0x99c97855), TOBN(0x11b393ee, 0xf5a86b5c), + TOBN(0x48ef6582, 0xd8884f27), TOBN(0xbd44737a, 0xbf19ba5f), + TOBN(0x8698de4c, 0xa42062c6), TOBN(0x8975eb80, 0x61ce9c54), + TOBN(0xd50e57c7, 0xd7fe71f3), TOBN(0x15342190, 0xbc97ce38), + TOBN(0x51bda2de, 0x4df07b63), TOBN(0xba12aeae, 0x200eb87d), + TOBN(0xabe135d2, 0xa9b4f8f6), TOBN(0x04619d65, 0xfad6d99c), + TOBN(0x4a6683a7, 0x7994937c), TOBN(0x7a778c8b, 0x6f94f09a), + TOBN(0x8c508623, 0x20a71b89), TOBN(0x241a2aed, 0x1c229165), + TOBN(0x352be595, 0xaaf83a99), TOBN(0x9fbfee7f, 0x1562bac8), + TOBN(0xeaf658b9, 0x5c4017e3), TOBN(0x1dc7f9e0, 0x15120b86), + TOBN(0xd84f13dd, 0x4c034d6f), TOBN(0x283dd737, 0xeaea3038), + TOBN(0x197f2609, 0xcd85d6a2), TOBN(0x6ebbc345, 0xfae60177), + TOBN(0xb80f031b, 0x4e12fede), TOBN(0xde55d0c2, 0x07a2186b), + TOBN(0x1fb3e37f, 0x24dcdd5a), TOBN(0x8d602da5, 0x7ed191fb), + TOBN(0x108fb056, 0x76023e0d), TOBN(0x70178c71, 0x459c20c0), + TOBN(0xfad5a386, 0x3fe54cf0), TOBN(0xa4a3ec4f, 0x02bbb475), + TOBN(0x1aa5ec20, 0x919d94d7), TOBN(0x5d3b63b5, 0xa81e4ab3), + TOBN(0x7fa733d8, 0x5ad3d2af), TOBN(0xfbc586dd, 0xd1ac7a37), + TOBN(0x282925de, 0x40779614), TOBN(0xfe0ffffb, 0xe74a242a), + TOBN(0x3f39e67f, 0x906151e5), TOBN(0xcea27f5f, 0x55e10649), + TOBN(0xdca1d4e1, 0xc17cf7b7), TOBN(0x0c326d12, 0x2fe2362d), + TOBN(0x05f7ac33, 0x7dd35df3), TOBN(0x0c3b7639, 0xc396dbdf), + TOBN(0x0912f5ac, 0x03b7db1c), TOBN(0x9dea4b70, 0x5c9ed4a9), + TOBN(0x475e6e53, 0xaae3f639), TOBN(0xfaba0e7c, 0xfc278bac), + TOBN(0x16f9e221, 0x9490375f), TOBN(0xaebf9746, 0xa5a7ed0a), + TOBN(0x45f9af3f, 0xf41ad5d6), TOBN(0x03c4623c, 0xb2e99224), + TOBN(0x82c5bb5c, 0xb3cf56aa), TOBN(0x64311819, 0x34567ed3), + TOBN(0xec57f211, 0x8be489ac), TOBN(0x2821895d, 0xb9a1104b), + TOBN(0x610dc875, 0x6064e007), TOBN(0x8e526f3f, 0x5b20d0fe), + TOBN(0x6e71ca77, 0x5b645aee), TOBN(0x3d1dcb9f, 0x800e10ff), + TOBN(0x36b51162, 0x189cf6de), TOBN(0x2c5a3e30, 0x6bb17353), + TOBN(0xc186cd3e, 0x2a6c6fbf), TOBN(0xa74516fa, 0x4bf97906), + TOBN(0x5b4b8f4b, 0x279d6901), TOBN(0x0c4e57b4, 0x2b573743), + TOBN(0x75fdb229, 0xb6e386b6), TOBN(0xb46793fd, 0x99deac27), + TOBN(0xeeec47ea, 0xcf712629), TOBN(0xe965f3c4, 0xcbc3b2dd), + TOBN(0x8dd1fb83, 0x425c6559), TOBN(0x7fc00ee6, 0x0af06fda), + TOBN(0xe98c9225, 0x33d956df), TOBN(0x0f1ef335, 0x4fbdc8a2), + TOBN(0x2abb5145, 0xb79b8ea2), TOBN(0x40fd2945, 0xbdbff288), + TOBN(0x6a814ac4, 0xd7185db7), TOBN(0xc4329d6f, 0xc084609a), + TOBN(0xc9ba7b52, 0xed1be45d), TOBN(0x891dd20d, 0xe4cd2c74), + TOBN(0x5a4d4a7f, 0x824139b1), TOBN(0x66c17716, 0xb873c710), + TOBN(0x5e5bc141, 0x2843c4e0), TOBN(0xd5ac4817, 0xb97eb5bf), + TOBN(0xc0f8af54, 0x450c95c7), TOBN(0xc91b3fa0, 0x318406c5), + TOBN(0x360c340a, 0xab9d97f8), TOBN(0xfb57bd07, 0x90a2d611), + TOBN(0x4339ae3c, 0xa6a6f7e5), TOBN(0x9c1fcd2a, 0x2feb8a10), + TOBN(0x972bcca9, 0xc7ea7432), TOBN(0x1b0b924c, 0x308076f6), + TOBN(0x80b2814a, 0x2a5b4ca5), TOBN(0x2f78f55b, 0x61ef3b29), + TOBN(0xf838744a, 0xc18a414f), TOBN(0xc611eaae, 0x903d0a86), + TOBN(0x94dabc16, 0x2a453f55), TOBN(0xe6f2e3da, 0x14efb279), + TOBN(0x5b7a6017, 0x9320dc3c), TOBN(0x692e382f, 0x8df6b5a4), + TOBN(0x3f5e15e0, 0x2d40fa90), TOBN(0xc87883ae, 0x643dd318), + TOBN(0x511053e4, 0x53544774), TOBN(0x834d0ecc, 0x3adba2bc), + TOBN(0x4215d7f7, 0xbae371f5), TOBN(0xfcfd57bf, 0x6c8663bc), + TOBN(0xded2383d, 0xd6901b1d), TOBN(0x3b49fbb4, 0xb5587dc3), + TOBN(0xfd44a08d, 0x07625f62), TOBN(0x3ee4d65b, 0x9de9b762)}, + {TOBN(0x64e5137d, 0x0d63d1fa), TOBN(0x658fc052, 0x02a9d89f), + TOBN(0x48894874, 0x50436309), TOBN(0xe9ae30f8, 0xd598da61), + TOBN(0x2ed710d1, 0x818baf91), TOBN(0xe27e9e06, 0x8b6a0c20), + TOBN(0x1e28dcfb, 0x1c1a6b44), TOBN(0x883acb64, 0xd6ac57dc), + TOBN(0x8735728d, 0xc2c6ff70), TOBN(0x79d6122f, 0xc5dc2235), + TOBN(0x23f5d003, 0x19e277f9), TOBN(0x7ee84e25, 0xdded8cc7), + TOBN(0x91a8afb0, 0x63cd880a), TOBN(0x3f3ea7c6, 0x3574af60), + TOBN(0x0cfcdc84, 0x02de7f42), TOBN(0x62d0792f, 0xb31aa152), + TOBN(0x8e1b4e43, 0x8a5807ce), TOBN(0xad283893, 0xe4109a7e), + TOBN(0xc30cc9cb, 0xafd59dda), TOBN(0xf65f36c6, 0x3d8d8093), + TOBN(0xdf31469e, 0xa60d32b2), TOBN(0xee93df4b, 0x3e8191c8), + TOBN(0x9c1017c5, 0x355bdeb5), TOBN(0xd2623185, 0x8616aa28), + TOBN(0xb02c83f9, 0xdec31a21), TOBN(0x988c8b23, 0x6ad9d573), + TOBN(0x53e983ae, 0xa57be365), TOBN(0xe968734d, 0x646f834e), + TOBN(0x9137ea8f, 0x5da6309b), TOBN(0x10f3a624, 0xc1f1ce16), + TOBN(0x782a9ea2, 0xca440921), TOBN(0xdf94739e, 0x5b46f1b5), + TOBN(0x9f9be006, 0xcce85c9b), TOBN(0x360e70d6, 0xa4c7c2d3), + TOBN(0x2cd5beea, 0xaefa1e60), TOBN(0x64cf63c0, 0x8c3d2b6d), + TOBN(0xfb107fa3, 0xe1cf6f90), TOBN(0xb7e937c6, 0xd5e044e6), + TOBN(0x74e8ca78, 0xce34db9f), TOBN(0x4f8b36c1, 0x3e210bd0), + TOBN(0x1df165a4, 0x34a35ea8), TOBN(0x3418e0f7, 0x4d4412f6), + TOBN(0x5af1f8af, 0x518836c3), TOBN(0x42ceef4d, 0x130e1965), + TOBN(0x5560ca0b, 0x543a1957), TOBN(0xc33761e5, 0x886cb123), + TOBN(0x66624b1f, 0xfe98ed30), TOBN(0xf772f4bf, 0x1090997d), + TOBN(0xf4e540bb, 0x4885d410), TOBN(0x7287f810, 0x9ba5f8d7), + TOBN(0x22d0d865, 0xde98dfb1), TOBN(0x49ff51a1, 0xbcfbb8a3), + TOBN(0xb6b6fa53, 0x6bc3012e), TOBN(0x3d31fd72, 0x170d541d), + TOBN(0x8018724f, 0x4b0f4966), TOBN(0x79e7399f, 0x87dbde07), + TOBN(0x56f8410e, 0xf4f8b16a), TOBN(0x97241afe, 0xc47b266a), + TOBN(0x0a406b8e, 0x6d9c87c1), TOBN(0x803f3e02, 0xcd42ab1b), + TOBN(0x7f0309a8, 0x04dbec69), TOBN(0xa83b85f7, 0x3bbad05f), + TOBN(0xc6097273, 0xad8e197f), TOBN(0xc097440e, 0x5067adc1), + TOBN(0x730eafb6, 0x3524ff16), TOBN(0xd7f9b51e, 0x823fc6ce), + TOBN(0x27bd0d32, 0x443e4ac0), TOBN(0x40c59ad9, 0x4d66f217), + TOBN(0x6c33136f, 0x17c387a4), TOBN(0x5043b8d5, 0xeb86804d), + TOBN(0x74970312, 0x675a73c9), TOBN(0x838fdb31, 0xf16669b6), + TOBN(0xc507b6dd, 0x418e7ddd), TOBN(0x39888d93, 0x472f19d6), + TOBN(0x7eae26be, 0x0c27eb4d), TOBN(0x17b53ed3, 0xfbabb884), + TOBN(0xfc27021b, 0x2b01ae4f), TOBN(0x88462e87, 0xcf488682), + TOBN(0xbee096ec, 0x215e2d87), TOBN(0xeb2fea9a, 0xd242e29b), + TOBN(0x5d985b5f, 0xb821fc28), TOBN(0x89d2e197, 0xdc1e2ad2), + TOBN(0x55b566b8, 0x9030ba62), TOBN(0xe3fd41b5, 0x4f41b1c6), + TOBN(0xb738ac2e, 0xb9a96d61), TOBN(0x7f8567ca, 0x369443f4), + TOBN(0x8698622d, 0xf803a440), TOBN(0x2b586236, 0x8fe2f4dc), + TOBN(0xbbcc00c7, 0x56b95bce), TOBN(0x5ec03906, 0x616da680), + TOBN(0x79162ee6, 0x72214252), TOBN(0x43132b63, 0x86a892d2), + TOBN(0x4bdd3ff2, 0x2f3263bf), TOBN(0xd5b3733c, 0x9cd0a142), + TOBN(0x592eaa82, 0x44415ccb), TOBN(0x663e8924, 0x8d5474ea), + TOBN(0x8058a25e, 0x5236344e), TOBN(0x82e8df9d, 0xbda76ee6), + TOBN(0xdcf6efd8, 0x11cc3d22), TOBN(0x00089cda, 0x3b4ab529), + TOBN(0x91d3a071, 0xbd38a3db), TOBN(0x4ea97fc0, 0xef72b925), + TOBN(0x0c9fc15b, 0xea3edf75), TOBN(0x5a6297cd, 0xa4348ed3), + TOBN(0x0d38ab35, 0xce7c42d4), TOBN(0x9fd493ef, 0x82feab10), + TOBN(0x46056b6d, 0x82111b45), TOBN(0xda11dae1, 0x73efc5c3), + TOBN(0xdc740278, 0x5545a7fb), TOBN(0xbdb2601c, 0x40d507e6), + TOBN(0x121dfeeb, 0x7066fa58), TOBN(0x214369a8, 0x39ae8c2a), + TOBN(0x195709cb, 0x06e0956c), TOBN(0x4c9d254f, 0x010cd34b), + TOBN(0xf51e13f7, 0x0471a532), TOBN(0xe19d6791, 0x1e73054d), + TOBN(0xf702a628, 0xdb5c7be3), TOBN(0xc7141218, 0xb24dde05), + TOBN(0xdc18233c, 0xf29b2e2e), TOBN(0x3a6bd1e8, 0x85342dba), + TOBN(0x3f747fa0, 0xb311898c), TOBN(0xe2a272e4, 0xcd0eac65), + TOBN(0x4bba5851, 0xf914d0bc), TOBN(0x7a1a9660, 0xc4a43ee3), + TOBN(0xe5a367ce, 0xa1c8cde9), TOBN(0x9d958ba9, 0x7271abe3), + TOBN(0xf3ff7eb6, 0x3d1615cd), TOBN(0xa2280dce, 0xf5ae20b0), + TOBN(0x56dba5c1, 0xcf640147), TOBN(0xea5a2e3d, 0x5e83d118), + TOBN(0x04cd6b6d, 0xda24c511), TOBN(0x1c0f4671, 0xe854d214), + TOBN(0x91a6b7a9, 0x69565381), TOBN(0xdc966240, 0xdecf1f5b), + TOBN(0x1b22d21c, 0xfcf5d009), TOBN(0x2a05f641, 0x9021dbd5), + TOBN(0x8c0ed566, 0xd4312483), TOBN(0x5179a95d, 0x643e216f), + TOBN(0xcc185fec, 0x17044493), TOBN(0xb3063339, 0x54991a21), + TOBN(0xd801ecdb, 0x0081a726), TOBN(0x0149b0c6, 0x4fa89bbb), + TOBN(0xafe9065a, 0x4391b6b9), TOBN(0xedc92786, 0xd633f3a3), + TOBN(0xe408c24a, 0xae6a8e13), TOBN(0x85833fde, 0x9f3897ab), + TOBN(0x43800e7e, 0xd81a0715), TOBN(0xde08e346, 0xb44ffc5f), + TOBN(0x7094184c, 0xcdeff2e0), TOBN(0x49f9387b, 0x165eaed1), + TOBN(0x635d6129, 0x777c468a), TOBN(0x8c0dcfd1, 0x538c2dd8), + TOBN(0xd6d9d9e3, 0x7a6a308b), TOBN(0x62375830, 0x4c2767d3), + TOBN(0x874a8bc6, 0xf38cbeb6), TOBN(0xd94d3f1a, 0xccb6fd9e), + TOBN(0x92a9735b, 0xba21f248), TOBN(0x272ad0e5, 0x6cd1efb0), + TOBN(0x7437b69c, 0x05b03284), TOBN(0xe7f04702, 0x6948c225), + TOBN(0x8a56c04a, 0xcba2ecec), TOBN(0x0c181270, 0xe3a73e41), + TOBN(0x6cb34e9d, 0x03e93725), TOBN(0xf77c8713, 0x496521a9), + TOBN(0x94569183, 0xfa7f9f90), TOBN(0xf2e7aa4c, 0x8c9707ad), + TOBN(0xced2c9ba, 0x26c1c9a3), TOBN(0x9109fe96, 0x40197507), + TOBN(0x9ae868a9, 0xe9adfe1c), TOBN(0x3984403d, 0x314e39bb), + TOBN(0xb5875720, 0xf2fe378f), TOBN(0x33f901e0, 0xba44a628), + TOBN(0xea1125fe, 0x3652438c), TOBN(0xae9ec4e6, 0x9dd1f20b), + TOBN(0x1e740d9e, 0xbebf7fbd), TOBN(0x6dbd3ddc, 0x42dbe79c), + TOBN(0x62082aec, 0xedd36776), TOBN(0xf612c478, 0xe9859039), + TOBN(0xa493b201, 0x032f7065), TOBN(0xebd4d8f2, 0x4ff9b211), + TOBN(0x3f23a0aa, 0xaac4cb32), TOBN(0xea3aadb7, 0x15ed4005), + TOBN(0xacf17ea4, 0xafa27e63), TOBN(0x56125c1a, 0xc11fd66c), + TOBN(0x266344a4, 0x3794f8dc), TOBN(0xdcca923a, 0x483c5c36), + TOBN(0x2d6b6bbf, 0x3f9d10a0), TOBN(0xb320c5ca, 0x81d9bdf3), + TOBN(0x620e28ff, 0x47b50a95), TOBN(0x933e3b01, 0xcef03371), + TOBN(0xf081bf85, 0x99100153), TOBN(0x183be9a0, 0xc3a8c8d6), + TOBN(0x4e3ddc5a, 0xd6bbe24d), TOBN(0xc6c74630, 0x53843795), + TOBN(0x78193dd7, 0x65ec2d4c), TOBN(0xb8df26cc, 0xcd3c89b2), + TOBN(0x98dbe399, 0x5a483f8d), TOBN(0x72d8a957, 0x7dd3313a), + TOBN(0x65087294, 0xab0bd375), TOBN(0xfcd89248, 0x7c259d16), + TOBN(0x8a9443d7, 0x7613aa81), TOBN(0x80100800, 0x85fe6584), + TOBN(0x70fc4dbc, 0x7fb10288), TOBN(0xf58280d3, 0xe86beee8), + TOBN(0x14fdd82f, 0x7c978c38), TOBN(0xdf1204c1, 0x0de44d7b), + TOBN(0xa08a1c84, 0x4160252f), TOBN(0x591554ca, 0xc17646a5), + TOBN(0x214a37d6, 0xa05bd525), TOBN(0x48d5f09b, 0x07957b3c), + TOBN(0x0247cdcb, 0xd7109bc9), TOBN(0x40f9e4bb, 0x30599ce7), + TOBN(0xc325fa03, 0xf46ad2ec), TOBN(0x00f766cf, 0xc3e3f9ee), + TOBN(0xab556668, 0xd43a4577), TOBN(0x68d30a61, 0x3ee03b93), + TOBN(0x7ddc81ea, 0x77b46a08), TOBN(0xcf5a6477, 0xc7480699), + TOBN(0x43a8cb34, 0x6633f683), TOBN(0x1b867e6b, 0x92363c60), + TOBN(0x43921114, 0x1f60558e), TOBN(0xcdbcdd63, 0x2f41450e), + TOBN(0x7fc04601, 0xcc630e8b), TOBN(0xea7c66d5, 0x97038b43), + TOBN(0x7259b8a5, 0x04e99fd8), TOBN(0x98a8dd12, 0x4785549a), + TOBN(0x0e459a7c, 0x840552e1), TOBN(0xcdfcf4d0, 0x4bb0909e), + TOBN(0x34a86db2, 0x53758da7), TOBN(0xe643bb83, 0xeac997e1), + TOBN(0x96400bd7, 0x530c5b7e), TOBN(0x9f97af87, 0xb41c8b52), + TOBN(0x34fc8820, 0xfbeee3f9), TOBN(0x93e53490, 0x49091afd), + TOBN(0x764b9be5, 0x9a31f35c), TOBN(0x71f37864, 0x57e3d924), + TOBN(0x02fb34e0, 0x943aa75e), TOBN(0xa18c9c58, 0xab8ff6e4), + TOBN(0x080f31b1, 0x33cf0d19), TOBN(0x5c9682db, 0x083518a7), + TOBN(0x873d4ca6, 0xb709c3de), TOBN(0x64a84262, 0x3575b8f0), + TOBN(0x6275da1f, 0x020154bb), TOBN(0x97678caa, 0xd17cf1ab), + TOBN(0x8779795f, 0x951a95c3), TOBN(0xdd35b163, 0x50fccc08), + TOBN(0x32709627, 0x33d8f031), TOBN(0x3c5ab10a, 0x498dd85c), + TOBN(0xb6c185c3, 0x41dca566), TOBN(0x7de7feda, 0xd8622aa3), + TOBN(0x99e84d92, 0x901b6dfb), TOBN(0x30a02b0e, 0x7c4ad288), + TOBN(0xc7c81daa, 0x2fd3cf36), TOBN(0xd1319547, 0xdf89e59f), + TOBN(0xb2be8184, 0xcd496733), TOBN(0xd5f449eb, 0x93d3412b), + TOBN(0x7ea41b1b, 0x25fe531d), TOBN(0xf9797432, 0x6a1d5646), + TOBN(0x86067f72, 0x2bde501a), TOBN(0xf91481c0, 0x0c85e89c), + TOBN(0xca8ee465, 0xf8b05bc6), TOBN(0x1844e1cf, 0x02e83cda), + TOBN(0xca82114a, 0xb4dbe33b), TOBN(0x0f9f8769, 0x4eabfde2), + TOBN(0x4936b1c0, 0x38b27fe2), TOBN(0x63b6359b, 0xaba402df), + TOBN(0x40c0ea2f, 0x656bdbab), TOBN(0x9c992a89, 0x6580c39c), + TOBN(0x600e8f15, 0x2a60aed1), TOBN(0xeb089ca4, 0xe0bf49df), + TOBN(0x9c233d7d, 0x2d42d99a), TOBN(0x648d3f95, 0x4c6bc2fa), + TOBN(0xdcc383a8, 0xe1add3f3), TOBN(0xf42c0c6a, 0x4f64a348), + TOBN(0x2abd176f, 0x0030dbdb), TOBN(0x4de501a3, 0x7d6c215e), + TOBN(0x4a107c1f, 0x4b9a64bc), TOBN(0xa77f0ad3, 0x2496cd59), + TOBN(0xfb78ac62, 0x7688dffb), TOBN(0x7025a2ca, 0x67937d8e), + TOBN(0xfde8b2d1, 0xd1a8f4e7), TOBN(0xf5b3da47, 0x7354927c), + TOBN(0xe48606a3, 0xd9205735), TOBN(0xac477cc6, 0xe177b917), + TOBN(0xfb1f73d2, 0xa883239a), TOBN(0xe12572f6, 0xcc8b8357), + TOBN(0x9d355e9c, 0xfb1f4f86), TOBN(0x89b795f8, 0xd9f3ec6e), + TOBN(0x27be56f1, 0xb54398dc), TOBN(0x1890efd7, 0x3fedeed5), + TOBN(0x62f77f1f, 0x9c6d0140), TOBN(0x7ef0e314, 0x596f0ee4), + TOBN(0x50ca6631, 0xcc61dab3), TOBN(0x4a39801d, 0xf4866e4f), + TOBN(0x66c8d032, 0xae363b39), TOBN(0x22c591e5, 0x2ead66aa), + TOBN(0x954ba308, 0xde02a53e), TOBN(0x2a6c060f, 0xd389f357), + TOBN(0xe6cfcde8, 0xfbf40b66), TOBN(0x8e02fc56, 0xc6340ce1), + TOBN(0xe4957795, 0x73adb4ba), TOBN(0x7b86122c, 0xa7b03805), + TOBN(0x63f83512, 0x0c8e6fa6), TOBN(0x83660ea0, 0x057d7804), + TOBN(0xbad79105, 0x21ba473c), TOBN(0xb6c50bee, 0xded5389d), + TOBN(0xee2caf4d, 0xaa7c9bc0), TOBN(0xd97b8de4, 0x8c4e98a7), + TOBN(0xa9f63e70, 0xab3bbddb), TOBN(0x3898aabf, 0x2597815a), + TOBN(0x7659af89, 0xac15b3d9), TOBN(0xedf7725b, 0x703ce784), + TOBN(0x25470fab, 0xe085116b), TOBN(0x04a43375, 0x87285310), + TOBN(0x4e39187e, 0xe2bfd52f), TOBN(0x36166b44, 0x7d9ebc74), + TOBN(0x92ad433c, 0xfd4b322c), TOBN(0x726aa817, 0xba79ab51), + TOBN(0xf96eacd8, 0xc1db15eb), TOBN(0xfaf71e91, 0x0476be63), + TOBN(0xdd69a640, 0x641fad98), TOBN(0xb7995918, 0x29622559), + TOBN(0x03c6daa5, 0xde4199dc), TOBN(0x92cadc97, 0xad545eb4), + TOBN(0x1028238b, 0x256534e4), TOBN(0x73e80ce6, 0x8595409a), + TOBN(0x690d4c66, 0xd05dc59b), TOBN(0xc95f7b8f, 0x981dee80), + TOBN(0xf4337014, 0xd856ac25), TOBN(0x441bd9dd, 0xac524dca), + TOBN(0x640b3d85, 0x5f0499f5), TOBN(0x39cf84a9, 0xd5fda182), + TOBN(0x04e7b055, 0xb2aa95a0), TOBN(0x29e33f0a, 0x0ddf1860), + TOBN(0x082e74b5, 0x423f6b43), TOBN(0x217edeb9, 0x0aaa2b0f), + TOBN(0x58b83f35, 0x83cbea55), TOBN(0xc485ee4d, 0xbc185d70), + TOBN(0x833ff03b, 0x1e5f6992), TOBN(0xb5b9b9cc, 0xcf0c0dd5), + TOBN(0x7caaee8e, 0x4e9e8a50), TOBN(0x462e907b, 0x6269dafd), + TOBN(0x6ed5cee9, 0xfbe791c6), TOBN(0x68ca3259, 0xed430790), + TOBN(0x2b72bdf2, 0x13b5ba88), TOBN(0x60294c8a, 0x35ef0ac4), + TOBN(0x9c3230ed, 0x19b99b08), TOBN(0x560fff17, 0x6c2589aa), + TOBN(0x552b8487, 0xd6770374), TOBN(0xa373202d, 0x9a56f685), + TOBN(0xd3e7f907, 0x45f175d9), TOBN(0x3c2f315f, 0xd080d810), + TOBN(0x1130e9dd, 0x7b9520e8), TOBN(0xc078f9e2, 0x0af037b5), + TOBN(0x38cd2ec7, 0x1e9c104c), TOBN(0x0f684368, 0xc472fe92), + TOBN(0xd3f1b5ed, 0x6247e7ef), TOBN(0xb32d33a9, 0x396dfe21), + TOBN(0x46f59cf4, 0x4a9aa2c2), TOBN(0x69cd5168, 0xff0f7e41), + TOBN(0x3f59da0f, 0x4b3234da), TOBN(0xcf0b0235, 0xb4579ebe), + TOBN(0x6d1cbb25, 0x6d2476c7), TOBN(0x4f0837e6, 0x9dc30f08), + TOBN(0x9a4075bb, 0x906f6e98), TOBN(0x253bb434, 0xc761e7d1), + TOBN(0xde2e645f, 0x6e73af10), TOBN(0xb89a4060, 0x0c5f131c), + TOBN(0xd12840c5, 0xb8cc037f), TOBN(0x3d093a5b, 0x7405bb47), + TOBN(0x6202c253, 0x206348b8), TOBN(0xbf5d57fc, 0xc55a3ca7), + TOBN(0x89f6c90c, 0x8c3bef48), TOBN(0x23ac7623, 0x5a0a960a), + TOBN(0xdfbd3d6b, 0x552b42ab), TOBN(0x3ef22458, 0x132061f6), + TOBN(0xd74e9bda, 0xc97e6516), TOBN(0x88779360, 0xc230f49e), + TOBN(0xa6ec1de3, 0x1e74ea49), TOBN(0x581dcee5, 0x3fb645a2), + TOBN(0xbaef2391, 0x8f483f14), TOBN(0x6d2dddfc, 0xd137d13b), + TOBN(0x54cde50e, 0xd2743a42), TOBN(0x89a34fc5, 0xe4d97e67), + TOBN(0x13f1f5b3, 0x12e08ce5), TOBN(0xa80540b8, 0xa7f0b2ca), + TOBN(0x854bcf77, 0x01982805), TOBN(0xb8653ffd, 0x233bea04), + TOBN(0x8e7b8787, 0x02b0b4c9), TOBN(0x2675261f, 0x9acb170a), + TOBN(0x061a9d90, 0x930c14e5), TOBN(0xb59b30e0, 0xdef0abea), + TOBN(0x1dc19ea6, 0x0200ec7d), TOBN(0xb6f4a3f9, 0x0bce132b), + TOBN(0xb8d5de90, 0xf13e27e0), TOBN(0xbaee5ef0, 0x1fade16f), + TOBN(0x6f406aaa, 0xe4c6cf38), TOBN(0xab4cfe06, 0xd1369815), + TOBN(0x0dcffe87, 0xefd550c6), TOBN(0x9d4f59c7, 0x75ff7d39), + TOBN(0xb02553b1, 0x51deb6ad), TOBN(0x812399a4, 0xb1877749), + TOBN(0xce90f71f, 0xca6006e1), TOBN(0xc32363a6, 0xb02b6e77), + TOBN(0x02284fbe, 0xdc36c64d), TOBN(0x86c81e31, 0xa7e1ae61), + TOBN(0x2576c7e5, 0xb909d94a), TOBN(0x8b6f7d02, 0x818b2bb0), + TOBN(0xeca3ed07, 0x56faa38a), TOBN(0xa3790e6c, 0x9305bb54), + TOBN(0xd784eeda, 0x7bc73061), TOBN(0xbd56d369, 0x6dd50614), + TOBN(0xd6575949, 0x229a8aa9), TOBN(0xdcca8f47, 0x4595ec28), + TOBN(0x814305c1, 0x06ab4fe6), TOBN(0xc8c39768, 0x24f43f16), + TOBN(0xe2a45f36, 0x523f2b36), TOBN(0x995c6493, 0x920d93bb), + TOBN(0xf8afdab7, 0x90f1632b), TOBN(0x79ebbecd, 0x1c295954), + TOBN(0xc7bb3ddb, 0x79592f48), TOBN(0x67216a7b, 0x5f88e998), + TOBN(0xd91f098b, 0xbc01193e), TOBN(0xf7d928a5, 0xb1db83fc), + TOBN(0x55e38417, 0xe991f600), TOBN(0x2a91113e, 0x2981a934), + TOBN(0xcbc9d648, 0x06b13bde), TOBN(0xb011b6ac, 0x0755ff44), + TOBN(0x6f4cb518, 0x045ec613), TOBN(0x522d2d31, 0xc2f5930a), + TOBN(0x5acae1af, 0x382e65de), TOBN(0x57643067, 0x27bc966f), + TOBN(0x5e12705d, 0x1c7193f0), TOBN(0xf0f32f47, 0x3be8858e), + TOBN(0x785c3d7d, 0x96c6dfc7), TOBN(0xd75b4a20, 0xbf31795d), + TOBN(0x91acf17b, 0x342659d4), TOBN(0xe596ea34, 0x44f0378f), + TOBN(0x4515708f, 0xce52129d), TOBN(0x17387e1e, 0x79f2f585), + TOBN(0x72cfd2e9, 0x49dee168), TOBN(0x1ae05223, 0x3e2af239), + TOBN(0x009e75be, 0x1d94066a), TOBN(0x6cca31c7, 0x38abf413), + TOBN(0xb50bd61d, 0x9bc49908), TOBN(0x4a9b4a8c, 0xf5e2bc1e), + TOBN(0xeb6cc5f7, 0x946f83ac), TOBN(0x27da93fc, 0xebffab28), + TOBN(0xea314c96, 0x4821c8c5), TOBN(0x8de49ded, 0xa83c15f4), + TOBN(0x7a64cf20, 0x7af33004), TOBN(0x45f1bfeb, 0xc9627e10), + TOBN(0x878b0626, 0x54b9df60), TOBN(0x5e4fdc3c, 0xa95c0b33), + TOBN(0xe54a37ca, 0xc2035d8e), TOBN(0x9087cda9, 0x80f20b8c), + TOBN(0x36f61c23, 0x8319ade4), TOBN(0x766f287a, 0xde8cfdf8), + TOBN(0x48821948, 0x346f3705), TOBN(0x49a7b853, 0x16e4f4a2), + TOBN(0xb9b3f8a7, 0x5cedadfd), TOBN(0x8f562815, 0x8db2a815), + TOBN(0xc0b7d554, 0x01f68f95), TOBN(0x12971e27, 0x688a208e), + TOBN(0xc9f8b696, 0xd0ff34fc), TOBN(0x20824de2, 0x1222718c), + TOBN(0x7213cf9f, 0x0c95284d), TOBN(0xe2ad741b, 0xdc158240), + TOBN(0x0ee3a6df, 0x54043ccf), TOBN(0x16ff479b, 0xd84412b3), + TOBN(0xf6c74ee0, 0xdfc98af0), TOBN(0xa78a169f, 0x52fcd2fb), + TOBN(0xd8ae8746, 0x99c930e9), TOBN(0x1d33e858, 0x49e117a5), + TOBN(0x7581fcb4, 0x6624759f), TOBN(0xde50644f, 0x5bedc01d), + TOBN(0xbeec5d00, 0xcaf3155e), TOBN(0x672d66ac, 0xbc73e75f), + TOBN(0x86b9d8c6, 0x270b01db), TOBN(0xd249ef83, 0x50f55b79), + TOBN(0x6131d6d4, 0x73978fe3), TOBN(0xcc4e4542, 0x754b00a1), + TOBN(0x4e05df05, 0x57dfcfe9), TOBN(0x94b29cdd, 0x51ef6bf0), + TOBN(0xe4530cff, 0x9bc7edf2), TOBN(0x8ac236fd, 0xd3da65f3), + TOBN(0x0faf7d5f, 0xc8eb0b48), TOBN(0x4d2de14c, 0x660eb039), + TOBN(0xc006bba7, 0x60430e54), TOBN(0x10a2d0d6, 0xda3289ab), + TOBN(0x9c037a5d, 0xd7979c59), TOBN(0x04d1f3d3, 0xa116d944), + TOBN(0x9ff22473, 0x8a0983cd), TOBN(0x28e25b38, 0xc883cabb), + TOBN(0xe968dba5, 0x47a58995), TOBN(0x2c80b505, 0x774eebdf), + TOBN(0xee763b71, 0x4a953beb), TOBN(0x502e223f, 0x1642e7f6), + TOBN(0x6fe4b641, 0x61d5e722), TOBN(0x9d37c5b0, 0xdbef5316), + TOBN(0x0115ed70, 0xf8330bc7), TOBN(0x139850e6, 0x75a72789), + TOBN(0x27d7faec, 0xffceccc2), TOBN(0x3016a860, 0x4fd9f7f6), + TOBN(0xc492ec64, 0x4cd8f64c), TOBN(0x58a2d790, 0x279d7b51), + TOBN(0x0ced1fc5, 0x1fc75256), TOBN(0x3e658aed, 0x8f433017), + TOBN(0x0b61942e, 0x05da59eb), TOBN(0xba3d60a3, 0x0ddc3722), + TOBN(0x7c311cd1, 0x742e7f87), TOBN(0x6473ffee, 0xf6b01b6e)}, + {TOBN(0x8303604f, 0x692ac542), TOBN(0xf079ffe1, 0x227b91d3), + TOBN(0x19f63e63, 0x15aaf9bd), TOBN(0xf99ee565, 0xf1f344fb), + TOBN(0x8a1d661f, 0xd6219199), TOBN(0x8c883bc6, 0xd48ce41c), + TOBN(0x1065118f, 0x3c74d904), TOBN(0x713889ee, 0x0faf8b1b), + TOBN(0x972b3f8f, 0x81a1b3be), TOBN(0x4f3ce145, 0xce2764a0), + TOBN(0xe2d0f1cc, 0x28c4f5f7), TOBN(0xdeee0c0d, 0xc7f3985b), + TOBN(0x7df4adc0, 0xd39e25c3), TOBN(0x40619820, 0xc467a080), + TOBN(0x440ebc93, 0x61cf5a58), TOBN(0x527729a6, 0x422ad600), + TOBN(0xca6c0937, 0xb1b76ba6), TOBN(0x1a2eab85, 0x4d2026dc), + TOBN(0xb1715e15, 0x19d9ae0a), TOBN(0xf1ad9199, 0xbac4a026), + TOBN(0x35b3dfb8, 0x07ea7b0e), TOBN(0xedf5496f, 0x3ed9eb89), + TOBN(0x8932e5ff, 0x2d6d08ab), TOBN(0xf314874e, 0x25bd2731), + TOBN(0xefb26a75, 0x3f73f449), TOBN(0x1d1c94f8, 0x8d44fc79), + TOBN(0x49f0fbc5, 0x3bc0dc4d), TOBN(0xb747ea0b, 0x3698a0d0), + TOBN(0x5218c3fe, 0x228d291e), TOBN(0x35b804b5, 0x43c129d6), + TOBN(0xfac859b8, 0xd1acc516), TOBN(0x6c10697d, 0x95d6e668), + TOBN(0xc38e438f, 0x0876fd4e), TOBN(0x45f0c307, 0x83d2f383), + TOBN(0x203cc2ec, 0xb10934cb), TOBN(0x6a8f2439, 0x2c9d46ee), + TOBN(0xf16b431b, 0x65ccde7b), TOBN(0x41e2cd18, 0x27e76a6f), + TOBN(0xb9c8cf8f, 0x4e3484d7), TOBN(0x64426efd, 0x8315244a), + TOBN(0x1c0a8e44, 0xfc94dea3), TOBN(0x34c8cdbf, 0xdad6a0b0), + TOBN(0x919c3840, 0x04113cef), TOBN(0xfd32fba4, 0x15490ffa), + TOBN(0x58d190f6, 0x795dcfb7), TOBN(0xfef01b03, 0x83588baf), + TOBN(0x9e6d1d63, 0xca1fc1c0), TOBN(0x53173f96, 0xf0a41ac9), + TOBN(0x2b1d402a, 0xba16f73b), TOBN(0x2fb31014, 0x8cf9b9fc), + TOBN(0x2d51e60e, 0x446ef7bf), TOBN(0xc731021b, 0xb91e1745), + TOBN(0x9d3b4724, 0x4fee99d4), TOBN(0x4bca48b6, 0xfac5c1ea), + TOBN(0x70f5f514, 0xbbea9af7), TOBN(0x751f55a5, 0x974c283a), + TOBN(0x6e30251a, 0xcb452fdb), TOBN(0x31ee6965, 0x50f30650), + TOBN(0xb0b3e508, 0x933548d9), TOBN(0xb8949a4f, 0xf4b0ef5b), + TOBN(0x208b8326, 0x3c88f3bd), TOBN(0xab147c30, 0xdb1d9989), + TOBN(0xed6515fd, 0x44d4df03), TOBN(0x17a12f75, 0xe72eb0c5), + TOBN(0x3b59796d, 0x36cf69db), TOBN(0x1219eee9, 0x56670c18), + TOBN(0xfe3341f7, 0x7a070d8e), TOBN(0x9b70130b, 0xa327f90c), + TOBN(0x36a32462, 0x0ae18e0e), TOBN(0x2021a623, 0x46c0a638), + TOBN(0x251b5817, 0xc62eb0d4), TOBN(0x87bfbcdf, 0x4c762293), + TOBN(0xf78ab505, 0xcdd61d64), TOBN(0x8c7a53fc, 0xc8c18857), + TOBN(0xa653ce6f, 0x16147515), TOBN(0x9c923aa5, 0xea7d52d5), + TOBN(0xc24709cb, 0x5c18871f), TOBN(0x7d53bec8, 0x73b3cc74), + TOBN(0x59264aff, 0xfdd1d4c4), TOBN(0x5555917e, 0x240da582), + TOBN(0xcae8bbda, 0x548f5a0e), TOBN(0x1910eaba, 0x3bbfbbe1), + TOBN(0xae579685, 0x7677afc3), TOBN(0x49ea61f1, 0x73ff0b5c), + TOBN(0x78655478, 0x4f7c3922), TOBN(0x95d337cd, 0x20c68eef), + TOBN(0x68f1e1e5, 0xdf779ab9), TOBN(0x14b491b0, 0xb5cf69a8), + TOBN(0x7a6cbbe0, 0x28e3fe89), TOBN(0xe7e1fee4, 0xc5aac0eb), + TOBN(0x7f47eda5, 0x697e5140), TOBN(0x4f450137, 0xb454921f), + TOBN(0xdb625f84, 0x95cd8185), TOBN(0x74be0ba1, 0xcdb2e583), + TOBN(0xaee4fd7c, 0xdd5e6de4), TOBN(0x4251437d, 0xe8101739), + TOBN(0x686d72a0, 0xac620366), TOBN(0x4be3fb9c, 0xb6d59344), + TOBN(0x6e8b44e7, 0xa1eb75b9), TOBN(0x84e39da3, 0x91a5c10c), + TOBN(0x37cc1490, 0xb38f0409), TOBN(0x02951943, 0x2c2ade82), + TOBN(0x9b688783, 0x1190a2d8), TOBN(0x25627d14, 0x231182ba), + TOBN(0x6eb550aa, 0x658a6d87), TOBN(0x1405aaa7, 0xcf9c7325), + TOBN(0xd147142e, 0x5c8748c9), TOBN(0x7f637e4f, 0x53ede0e0), + TOBN(0xf8ca2776, 0x14ffad2c), TOBN(0xe58fb1bd, 0xbafb6791), + TOBN(0x17158c23, 0xbf8f93fc), TOBN(0x7f15b373, 0x0a4a4655), + TOBN(0x39d4add2, 0xd842ca72), TOBN(0xa71e4391, 0x3ed96305), + TOBN(0x5bb09cbe, 0x6700be14), TOBN(0x68d69d54, 0xd8befcf6), + TOBN(0xa45f5367, 0x37183bcf), TOBN(0x7152b7bb, 0x3370dff7), + TOBN(0xcf887baa, 0xbf12525b), TOBN(0xe7ac7bdd, 0xd6d1e3cd), + TOBN(0x25914f78, 0x81fdad90), TOBN(0xcf638f56, 0x0d2cf6ab), + TOBN(0xb90bc03f, 0xcc054de5), TOBN(0x932811a7, 0x18b06350), + TOBN(0x2f00b330, 0x9bbd11ff), TOBN(0x76108a6f, 0xb4044974), + TOBN(0x801bb9e0, 0xa851d266), TOBN(0x0dd099be, 0xbf8990c1), + TOBN(0x58c5aaaa, 0xabe32986), TOBN(0x0fe9dd2a, 0x50d59c27), + TOBN(0x84951ff4, 0x8d307305), TOBN(0x6c23f829, 0x86529b78), + TOBN(0x50bb2218, 0x0b136a79), TOBN(0x7e2174de, 0x77a20996), + TOBN(0x6f00a4b9, 0xc0bb4da6), TOBN(0x89a25a17, 0xefdde8da), + TOBN(0xf728a27e, 0xc11ee01d), TOBN(0xf900553a, 0xe5f10dfb), + TOBN(0x189a83c8, 0x02ec893c), TOBN(0x3ca5bdc1, 0x23f66d77), + TOBN(0x98781537, 0x97eada9f), TOBN(0x59c50ab3, 0x10256230), + TOBN(0x346042d9, 0x323c69b3), TOBN(0x1b715a6d, 0x2c460449), + TOBN(0xa41dd476, 0x6ae06e0b), TOBN(0xcdd7888e, 0x9d42e25f), + TOBN(0x0f395f74, 0x56b25a20), TOBN(0xeadfe0ae, 0x8700e27e), + TOBN(0xb09d52a9, 0x69950093), TOBN(0x3525d9cb, 0x327f8d40), + TOBN(0xb8235a94, 0x67df886a), TOBN(0x77e4b0dd, 0x035faec2), + TOBN(0x115eb20a, 0x517d7061), TOBN(0x77fe3433, 0x6c2df683), + TOBN(0x6870ddc7, 0xcdc6fc67), TOBN(0xb1610588, 0x0b87de83), + TOBN(0x343584ca, 0xd9c4ddbe), TOBN(0xb3164f1c, 0x3d754be2), + TOBN(0x0731ed3a, 0xc1e6c894), TOBN(0x26327dec, 0x4f6b904c), + TOBN(0x9d49c6de, 0x97b5cd32), TOBN(0x40835dae, 0xb5eceecd), + TOBN(0xc66350ed, 0xd9ded7fe), TOBN(0x8aeebb5c, 0x7a678804), + TOBN(0x51d42fb7, 0x5b8ee9ec), TOBN(0xd7a17bdd, 0x8e3ca118), + TOBN(0x40d7511a, 0x2ef4400e), TOBN(0xc48990ac, 0x875a66f4), + TOBN(0x8de07d2a, 0x2199e347), TOBN(0xbee75556, 0x2a39e051), + TOBN(0x56918786, 0x916e51dc), TOBN(0xeb191313, 0x4a2d89ec), + TOBN(0x6679610d, 0x37d341ed), TOBN(0x434fbb41, 0x56d51c2b), + TOBN(0xe54b7ee7, 0xd7492dba), TOBN(0xaa33a79a, 0x59021493), + TOBN(0x49fc5054, 0xe4bd6d3d), TOBN(0x09540f04, 0x5ab551d0), + TOBN(0x8acc9085, 0x4942d3a6), TOBN(0x231af02f, 0x2d28323b), + TOBN(0x93458cac, 0x0992c163), TOBN(0x1fef8e71, 0x888e3bb4), + TOBN(0x27578da5, 0xbe8c268c), TOBN(0xcc8be792, 0xe805ec00), + TOBN(0x29267bae, 0xc61c3855), TOBN(0xebff429d, 0x58c1fd3b), + TOBN(0x22d886c0, 0x8c0b93b8), TOBN(0xca5e00b2, 0x2ddb8953), + TOBN(0xcf330117, 0xc3fed8b7), TOBN(0xd49ac6fa, 0x819c01f6), + TOBN(0x6ddaa6bd, 0x3c0fbd54), TOBN(0x91743068, 0x8049a2cf), + TOBN(0xd67f981e, 0xaff2ef81), TOBN(0xc3654d35, 0x2818ae80), + TOBN(0x81d05044, 0x1b2aa892), TOBN(0x2db067bf, 0x3d099328), + TOBN(0xe7c79e86, 0x703dcc97), TOBN(0xe66f9b37, 0xe133e215), + TOBN(0xcdf119a6, 0xe39a7a5c), TOBN(0x47c60de3, 0x876f1b61), + TOBN(0x6e405939, 0xd860f1b2), TOBN(0x3e9a1dbc, 0xf5ed4d4a), + TOBN(0x3f23619e, 0xc9b6bcbd), TOBN(0x5ee790cf, 0x734e4497), + TOBN(0xf0a834b1, 0x5bdaf9bb), TOBN(0x02cedda7, 0x4ca295f0), + TOBN(0x4619aa2b, 0xcb8e378c), TOBN(0xe5613244, 0xcc987ea4), + TOBN(0x0bc022cc, 0x76b23a50), TOBN(0x4a2793ad, 0x0a6c21ce), + TOBN(0x38328780, 0x89cac3f5), TOBN(0x29176f1b, 0xcba26d56), + TOBN(0x06296187, 0x4f6f59eb), TOBN(0x86e9bca9, 0x8bdc658e), + TOBN(0x2ca9c4d3, 0x57e30402), TOBN(0x5438b216, 0x516a09bb), + TOBN(0x0a6a063c, 0x7672765a), TOBN(0x37a3ce64, 0x0547b9bf), + TOBN(0x42c099c8, 0x98b1a633), TOBN(0xb5ab800d, 0x05ee6961), + TOBN(0xf1963f59, 0x11a5acd6), TOBN(0xbaee6157, 0x46201063), + TOBN(0x36d9a649, 0xa596210a), TOBN(0xaed04363, 0x1ba7138c), + TOBN(0xcf817d1c, 0xa4a82b76), TOBN(0x5586960e, 0xf3806be9), + TOBN(0x7ab67c89, 0x09dc6bb5), TOBN(0x52ace7a0, 0x114fe7eb), + TOBN(0xcd987618, 0xcbbc9b70), TOBN(0x4f06fd5a, 0x604ca5e1), + TOBN(0x90af14ca, 0x6dbde133), TOBN(0x1afe4322, 0x948a3264), + TOBN(0xa70d2ca6, 0xc44b2c6c), TOBN(0xab726799, 0x0ef87dfe), + TOBN(0x310f64dc, 0x2e696377), TOBN(0x49b42e68, 0x4c8126a0), + TOBN(0x0ea444c3, 0xcea0b176), TOBN(0x53a8ddf7, 0xcb269182), + TOBN(0xf3e674eb, 0xbbba9dcb), TOBN(0x0d2878a8, 0xd8669d33), + TOBN(0x04b935d5, 0xd019b6a3), TOBN(0xbb5cf88e, 0x406f1e46), + TOBN(0xa1912d16, 0x5b57c111), TOBN(0x9803fc21, 0x19ebfd78), + TOBN(0x4f231c9e, 0xc07764a9), TOBN(0xd93286ee, 0xb75bd055), + TOBN(0x83a9457d, 0x8ee6c9de), TOBN(0x04695915, 0x6087ec90), + TOBN(0x14c6dd8a, 0x58d6cd46), TOBN(0x9cb633b5, 0x8e6634d2), + TOBN(0xc1305047, 0xf81bc328), TOBN(0x12ede0e2, 0x26a177e5), + TOBN(0x332cca62, 0x065a6f4f), TOBN(0xc3a47ecd, 0x67be487b), + TOBN(0x741eb187, 0x0f47ed1c), TOBN(0x99e66e58, 0xe7598b14), + TOBN(0x6f0544ca, 0x63d0ff12), TOBN(0xe5efc784, 0xb610a05f), + TOBN(0xf72917b1, 0x7cad7b47), TOBN(0x3ff6ea20, 0xf2cac0c0), + TOBN(0xcc23791b, 0xf21db8b7), TOBN(0x7dac70b1, 0xd7d93565), + TOBN(0x682cda1d, 0x694bdaad), TOBN(0xeb88bb8c, 0x1023516d), + TOBN(0xc4c634b4, 0xdfdbeb1b), TOBN(0x22f5ca72, 0xb4ee4dea), + TOBN(0x1045a368, 0xe6524821), TOBN(0xed9e8a3f, 0x052b18b2), + TOBN(0x9b7f2cb1, 0xb961f49a), TOBN(0x7fee2ec1, 0x7b009670), + TOBN(0x350d8754, 0x22507a6d), TOBN(0x561bd711, 0x4db55f1d), + TOBN(0x4c189ccc, 0x320bbcaf), TOBN(0x568434cf, 0xdf1de48c), + TOBN(0x6af1b00e, 0x0fa8f128), TOBN(0xf0ba9d02, 0x8907583c), + TOBN(0x735a4004, 0x32ff9f60), TOBN(0x3dd8e4b6, 0xc25dcf33), + TOBN(0xf2230f16, 0x42c74cef), TOBN(0xd8117623, 0x013fa8ad), + TOBN(0x36822876, 0xf51fe76e), TOBN(0x8a6811cc, 0x11d62589), + TOBN(0xc3fc7e65, 0x46225718), TOBN(0xb7df2c9f, 0xc82fdbcd), + TOBN(0x3b1d4e52, 0xdd7b205b), TOBN(0xb6959478, 0x47a2e414), + TOBN(0x05e4d793, 0xefa91148), TOBN(0xb47ed446, 0xfd2e9675), + TOBN(0x1a7098b9, 0x04c9d9bf), TOBN(0x661e2881, 0x1b793048), + TOBN(0xb1a16966, 0xb01ee461), TOBN(0xbc521308, 0x2954746f), + TOBN(0xc909a0fc, 0x2477de50), TOBN(0xd80bb41c, 0x7dbd51ef), + TOBN(0xa85be7ec, 0x53294905), TOBN(0x6d465b18, 0x83958f97), + TOBN(0x16f6f330, 0xfb6840fd), TOBN(0xfaaeb214, 0x3401e6c8), + TOBN(0xaf83d30f, 0xccb5b4f8), TOBN(0x22885739, 0x266dec4b), + TOBN(0x51b4367c, 0x7bc467df), TOBN(0x926562e3, 0xd842d27a), + TOBN(0xdfcb6614, 0x0fea14a6), TOBN(0xeb394dae, 0xf2734cd9), + TOBN(0x3eeae5d2, 0x11c0be98), TOBN(0xb1e6ed11, 0x814e8165), + TOBN(0x191086bc, 0xe52bce1c), TOBN(0x14b74cc6, 0xa75a04da), + TOBN(0x63cf1186, 0x8c060985), TOBN(0x071047de, 0x2dbd7f7c), + TOBN(0x4e433b8b, 0xce0942ca), TOBN(0xecbac447, 0xd8fec61d), + TOBN(0x8f0ed0e2, 0xebf3232f), TOBN(0xfff80f9e, 0xc52a2edd), + TOBN(0xad9ab433, 0x75b55fdb), TOBN(0x73ca7820, 0xe42e0c11), + TOBN(0x6dace0a0, 0xe6251b46), TOBN(0x89bc6b5c, 0x4c0d932d), + TOBN(0x3438cd77, 0x095da19a), TOBN(0x2f24a939, 0x8d48bdfb), + TOBN(0x99b47e46, 0x766561b7), TOBN(0x736600e6, 0x0ed0322a), + TOBN(0x06a47cb1, 0x638e1865), TOBN(0x927c1c2d, 0xcb136000), + TOBN(0x29542337, 0x0cc5df69), TOBN(0x99b37c02, 0x09d649a9), + TOBN(0xc5f0043c, 0x6aefdb27), TOBN(0x6cdd9987, 0x1be95c27), + TOBN(0x69850931, 0x390420d2), TOBN(0x299c40ac, 0x0983efa4), + TOBN(0x3a05e778, 0xaf39aead), TOBN(0x84274408, 0x43a45193), + TOBN(0x6bcd0fb9, 0x91a711a0), TOBN(0x461592c8, 0x9f52ab17), + TOBN(0xb49302b4, 0xda3c6ed6), TOBN(0xc51fddc7, 0x330d7067), + TOBN(0x94babeb6, 0xda50d531), TOBN(0x521b840d, 0xa6a7b9da), + TOBN(0x5305151e, 0x404bdc89), TOBN(0x1bcde201, 0xd0d07449), + TOBN(0xf427a78b, 0x3b76a59a), TOBN(0xf84841ce, 0x07791a1b), + TOBN(0xebd314be, 0xbf91ed1c), TOBN(0x8e61d34c, 0xbf172943), + TOBN(0x1d5dc451, 0x5541b892), TOBN(0xb186ee41, 0xfc9d9e54), + TOBN(0x9d9f345e, 0xd5bf610d), TOBN(0x3e7ba65d, 0xf6acca9f), + TOBN(0x9dda787a, 0xa8369486), TOBN(0x09f9dab7, 0x8eb5ba53), + TOBN(0x5afb2033, 0xd6481bc3), TOBN(0x76f4ce30, 0xafa62104), + TOBN(0xa8fa00cf, 0xf4f066b5), TOBN(0x89ab5143, 0x461dafc2), + TOBN(0x44339ed7, 0xa3389998), TOBN(0x2ff862f1, 0xbc214903), + TOBN(0x2c88f985, 0xb05556e3), TOBN(0xcd96058e, 0x3467081e), + TOBN(0x7d6a4176, 0xedc637ea), TOBN(0xe1743d09, 0x36a5acdc), + TOBN(0x66fd72e2, 0x7eb37726), TOBN(0xf7fa264e, 0x1481a037), + TOBN(0x9fbd3bde, 0x45f4aa79), TOBN(0xed1e0147, 0x767c3e22), + TOBN(0x7621f979, 0x82e7abe2), TOBN(0x19eedc72, 0x45f633f8), + TOBN(0xe69b155e, 0x6137bf3a), TOBN(0xa0ad13ce, 0x414ee94e), + TOBN(0x93e3d524, 0x1c0e651a), TOBN(0xab1a6e2a, 0x02ce227e), + TOBN(0xe7af1797, 0x4ab27eca), TOBN(0x245446de, 0xbd444f39), + TOBN(0x59e22a21, 0x56c07613), TOBN(0x43deafce, 0xf4275498), + TOBN(0x10834ccb, 0x67fd0946), TOBN(0xa75841e5, 0x47406edf), + TOBN(0xebd6a677, 0x7b0ac93d), TOBN(0xa6e37b0d, 0x78f5e0d7), + TOBN(0x2516c096, 0x76f5492b), TOBN(0x1e4bf888, 0x9ac05f3a), + TOBN(0xcdb42ce0, 0x4df0ba2b), TOBN(0x935d5cfd, 0x5062341b), + TOBN(0x8a303333, 0x82acac20), TOBN(0x429438c4, 0x5198b00e), + TOBN(0x1d083bc9, 0x049d33fa), TOBN(0x58b82dda, 0x946f67ff), + TOBN(0xac3e2db8, 0x67a1d6a3), TOBN(0x62e6bead, 0x1798aac8), + TOBN(0xfc85980f, 0xde46c58c), TOBN(0xa7f69379, 0x69c8d7be), + TOBN(0x23557927, 0x837b35ec), TOBN(0x06a933d8, 0xe0790c0c), + TOBN(0x827c0e9b, 0x077ff55d), TOBN(0x53977798, 0xbb26e680), + TOBN(0x59530874, 0x1d9cb54f), TOBN(0xcca3f449, 0x4aac53ef), + TOBN(0x11dc5c87, 0xa07eda0f), TOBN(0xc138bccf, 0xfd6400c8), + TOBN(0x549680d3, 0x13e5da72), TOBN(0xc93eed82, 0x4540617e), + TOBN(0xfd3db157, 0x4d0b75c0), TOBN(0x9716eb42, 0x6386075b), + TOBN(0x0639605c, 0x817b2c16), TOBN(0x09915109, 0xf1e4f201), + TOBN(0x35c9a928, 0x5cca6c3b), TOBN(0xb25f7d1a, 0x3505c900), + TOBN(0xeb9f7d20, 0x630480c4), TOBN(0xc3c7b8c6, 0x2a1a501c), + TOBN(0x3f99183c, 0x5a1f8e24), TOBN(0xfdb118fa, 0x9dd255f0), + TOBN(0xb9b18b90, 0xc27f62a6), TOBN(0xe8f732f7, 0x396ec191), + TOBN(0x524a2d91, 0x0be786ab), TOBN(0x5d32adef, 0x0ac5a0f5), + TOBN(0x9b53d4d6, 0x9725f694), TOBN(0x032a76c6, 0x0510ba89), + TOBN(0x840391a3, 0xebeb1544), TOBN(0x44b7b88c, 0x3ed73ac3), + TOBN(0xd24bae7a, 0x256cb8b3), TOBN(0x7ceb151a, 0xe394cb12), + TOBN(0xbd6b66d0, 0x5bc1e6a8), TOBN(0xec70cecb, 0x090f07bf), + TOBN(0x270644ed, 0x7d937589), TOBN(0xee9e1a3d, 0x5f1dccfe), + TOBN(0xb0d40a84, 0x745b98d2), TOBN(0xda429a21, 0x2556ed40), + TOBN(0xf676eced, 0x85148cb9), TOBN(0x5a22d40c, 0xded18936), + TOBN(0x3bc4b9e5, 0x70e8a4ce), TOBN(0xbfd1445b, 0x9eae0379), + TOBN(0xf23f2c0c, 0x1a0bd47e), TOBN(0xa9c0bb31, 0xe1845531), + TOBN(0x9ddc4d60, 0x0a4c3f6b), TOBN(0xbdfaad79, 0x2c15ef44), + TOBN(0xce55a236, 0x7f484acc), TOBN(0x08653ca7, 0x055b1f15), + TOBN(0x2efa8724, 0x538873a3), TOBN(0x09299e5d, 0xace1c7e7), + TOBN(0x07afab66, 0xade332ba), TOBN(0x9be1fdf6, 0x92dd71b7), + TOBN(0xa49b5d59, 0x5758b11c), TOBN(0x0b852893, 0xc8654f40), + TOBN(0xb63ef6f4, 0x52379447), TOBN(0xd4957d29, 0x105e690c), + TOBN(0x7d484363, 0x646559b0), TOBN(0xf4a8273c, 0x49788a8e), + TOBN(0xee406cb8, 0x34ce54a9), TOBN(0x1e1c260f, 0xf86fda9b), + TOBN(0xe150e228, 0xcf6a4a81), TOBN(0x1fa3b6a3, 0x1b488772), + TOBN(0x1e6ff110, 0xc5a9c15b), TOBN(0xc6133b91, 0x8ad6aa47), + TOBN(0x8ac5d55c, 0x9dffa978), TOBN(0xba1d1c1d, 0x5f3965f2), + TOBN(0xf969f4e0, 0x7732b52f), TOBN(0xfceecdb5, 0xa5172a07), + TOBN(0xb0120a5f, 0x10f2b8f5), TOBN(0xc83a6cdf, 0x5c4c2f63), + TOBN(0x4d47a491, 0xf8f9c213), TOBN(0xd9e1cce5, 0xd3f1bbd5), + TOBN(0x0d91bc7c, 0xaba7e372), TOBN(0xfcdc74c8, 0xdfd1a2db), + TOBN(0x05efa800, 0x374618e5), TOBN(0x11216969, 0x15a7925e), + TOBN(0xd4c89823, 0xf6021c5d), TOBN(0x880d5e84, 0xeff14423), + TOBN(0x6523bc5a, 0x6dcd1396), TOBN(0xd1acfdfc, 0x113c978b), + TOBN(0xb0c164e8, 0xbbb66840), TOBN(0xf7f4301e, 0x72b58459), + TOBN(0xc29ad4a6, 0xa638e8ec), TOBN(0xf5ab8961, 0x46b78699), + TOBN(0x9dbd7974, 0x0e954750), TOBN(0x0121de88, 0x64f9d2c6), + TOBN(0x2e597b42, 0xd985232e), TOBN(0x55b6c3c5, 0x53451777), + TOBN(0xbb53e547, 0x519cb9fb), TOBN(0xf134019f, 0x8428600d), + TOBN(0x5a473176, 0xe081791a), TOBN(0x2f3e2263, 0x35fb0c08), + TOBN(0xb28c3017, 0x73d273b0), TOBN(0xccd21076, 0x7721ef9a), + TOBN(0x054cc292, 0xb650dc39), TOBN(0x662246de, 0x6188045e), + TOBN(0x904b52fa, 0x6b83c0d1), TOBN(0xa72df267, 0x97e9cd46), + TOBN(0x886b43cd, 0x899725e4), TOBN(0x2b651688, 0xd849ff22), + TOBN(0x60479b79, 0x02f34533), TOBN(0x5e354c14, 0x0c77c148), + TOBN(0xb4bb7581, 0xa8537c78), TOBN(0x188043d7, 0xefe1495f), + TOBN(0x9ba12f42, 0x8c1d5026), TOBN(0x2e0c8a26, 0x93d4aaab), + TOBN(0xbdba7b8b, 0xaa57c450), TOBN(0x140c9ad6, 0x9bbdafef), + TOBN(0x2067aa42, 0x25ac0f18), TOBN(0xf7b1295b, 0x04d1fbf3), + TOBN(0x14829111, 0xa4b04824), TOBN(0x2ce3f192, 0x33bd5e91), + TOBN(0x9c7a1d55, 0x8f2e1b72), TOBN(0xfe932286, 0x302aa243), + TOBN(0x497ca7b4, 0xd4be9554), TOBN(0xb8e821b8, 0xe0547a6e), + TOBN(0xfb2838be, 0x67e573e0), TOBN(0x05891db9, 0x4084c44b), + TOBN(0x91311373, 0x96c1c2c5), TOBN(0x6aebfa3f, 0xd958444b), + TOBN(0xac9cdce9, 0xe56e55c1), TOBN(0x7148ced3, 0x2caa46d0), + TOBN(0x2e10c7ef, 0xb61fe8eb), TOBN(0x9fd835da, 0xff97cf4d)}, + {TOBN(0xa36da109, 0x081e9387), TOBN(0xfb9780d7, 0x8c935828), + TOBN(0xd5940332, 0xe540b015), TOBN(0xc9d7b51b, 0xe0f466fa), + TOBN(0xfaadcd41, 0xd6d9f671), TOBN(0xba6c1e28, 0xb1a2ac17), + TOBN(0x066a7833, 0xed201e5f), TOBN(0x19d99719, 0xf90f462b), + TOBN(0xf431f462, 0x060b5f61), TOBN(0xa56f46b4, 0x7bd057c2), + TOBN(0x348dca6c, 0x47e1bf65), TOBN(0x9a38783e, 0x41bcf1ff), + TOBN(0x7a5d33a9, 0xda710718), TOBN(0x5a779987, 0x2e0aeaf6), + TOBN(0xca87314d, 0x2d29d187), TOBN(0xfa0edc3e, 0xc687d733), + TOBN(0x9df33621, 0x6a31e09b), TOBN(0xde89e44d, 0xc1350e35), + TOBN(0x29214871, 0x4ca0cf52), TOBN(0xdf379672, 0x0b88a538), + TOBN(0xc92a510a, 0x2591d61b), TOBN(0x79aa87d7, 0x585b447b), + TOBN(0xf67db604, 0xe5287f77), TOBN(0x1697c8bf, 0x5efe7a80), + TOBN(0x1c894849, 0xcb198ac7), TOBN(0xa884a93d, 0x0f264665), + TOBN(0x2da964ef, 0x9b200678), TOBN(0x3c351b87, 0x009834e6), + TOBN(0xafb2ef9f, 0xe2c4b44b), TOBN(0x580f6c47, 0x3326790c), + TOBN(0xb8480521, 0x0b02264a), TOBN(0x8ba6f9e2, 0x42a194e2), + TOBN(0xfc87975f, 0x8fb54738), TOBN(0x35160788, 0x27c3ead3), + TOBN(0x834116d2, 0xb74a085a), TOBN(0x53c99a73, 0xa62fe996), + TOBN(0x87585be0, 0x5b81c51b), TOBN(0x925bafa8, 0xbe0852b7), + TOBN(0x76a4fafd, 0xa84d19a7), TOBN(0x39a45982, 0x585206d4), + TOBN(0x499b6ab6, 0x5eb03c0e), TOBN(0xf19b7954, 0x72bc3fde), + TOBN(0xa86b5b9c, 0x6e3a80d2), TOBN(0xe4377508, 0x6d42819f), + TOBN(0xc1663650, 0xbb3ee8a3), TOBN(0x75eb14fc, 0xb132075f), + TOBN(0xa8ccc906, 0x7ad834f6), TOBN(0xea6a2474, 0xe6e92ffd), + TOBN(0x9d72fd95, 0x0f8d6758), TOBN(0xcb84e101, 0x408c07dd), + TOBN(0xb9114bfd, 0xa5e23221), TOBN(0x358b5fe2, 0xe94e742c), + TOBN(0x1c0577ec, 0x95f40e75), TOBN(0xf0155451, 0x3d73f3d6), + TOBN(0x9d55cd67, 0xbd1b9b66), TOBN(0x63e86e78, 0xaf8d63c7), + TOBN(0x39d934ab, 0xd3c095f1), TOBN(0x04b261be, 0xe4b76d71), + TOBN(0x1d2e6970, 0xe73e6984), TOBN(0x879fb23b, 0x5e5fcb11), + TOBN(0x11506c72, 0xdfd75490), TOBN(0x3a97d085, 0x61bcf1c1), + TOBN(0x43201d82, 0xbf5e7007), TOBN(0x7f0ac52f, 0x798232a7), + TOBN(0x2715cbc4, 0x6eb564d4), TOBN(0x8d6c752c, 0x9e570e29), + TOBN(0xf80247c8, 0x9ef5fd5d), TOBN(0xc3c66b46, 0xd53eb514), + TOBN(0x9666b401, 0x0f87de56), TOBN(0xce62c06f, 0xc6c603b5), + TOBN(0xae7b4c60, 0x7e4fc942), TOBN(0x38ac0b77, 0x663a9c19), + TOBN(0xcb4d20ee, 0x4b049136), TOBN(0x8b63bf12, 0x356a4613), + TOBN(0x1221aef6, 0x70e08128), TOBN(0xe62d8c51, 0x4acb6b16), + TOBN(0x71f64a67, 0x379e7896), TOBN(0xb25237a2, 0xcafd7fa5), + TOBN(0xf077bd98, 0x3841ba6a), TOBN(0xc4ac0244, 0x3cd16e7e), + TOBN(0x548ba869, 0x21fea4ca), TOBN(0xd36d0817, 0xf3dfdac1), + TOBN(0x09d8d71f, 0xf4685faf), TOBN(0x8eff66be, 0xc52c459a), + TOBN(0x182faee7, 0x0b57235e), TOBN(0xee3c39b1, 0x0106712b), + TOBN(0x5107331f, 0xc0fcdcb0), TOBN(0x669fb9dc, 0xa51054ba), + TOBN(0xb25101fb, 0x319d7682), TOBN(0xb0293129, 0x0a982fee), + TOBN(0x51c1c9b9, 0x0261b344), TOBN(0x0e008c5b, 0xbfd371fa), + TOBN(0xd866dd1c, 0x0278ca33), TOBN(0x666f76a6, 0xe5aa53b1), + TOBN(0xe5cfb779, 0x6013a2cf), TOBN(0x1d3a1aad, 0xa3521836), + TOBN(0xcedd2531, 0x73faa485), TOBN(0xc8ee6c4f, 0xc0a76878), + TOBN(0xddbccfc9, 0x2a11667d), TOBN(0x1a418ea9, 0x1c2f695a), + TOBN(0xdb11bd92, 0x51f73971), TOBN(0x3e4b3c82, 0xda2ed89f), + TOBN(0x9a44f3f4, 0xe73e0319), TOBN(0xd1e3de0f, 0x303431af), + TOBN(0x3c5604ff, 0x50f75f9c), TOBN(0x1d8eddf3, 0x7e752b22), + TOBN(0x0ef074dd, 0x3c9a1118), TOBN(0xd0ffc172, 0xccb86d7b), + TOBN(0xabd1ece3, 0x037d90f2), TOBN(0xe3f307d6, 0x6055856c), + TOBN(0x422f9328, 0x7e4c6daf), TOBN(0x902aac66, 0x334879a0), + TOBN(0xb6a1e7bf, 0x94cdfade), TOBN(0x6c97e1ed, 0x7fc6d634), + TOBN(0x662ad24d, 0xa2fb63f8), TOBN(0xf81be1b9, 0xa5928405), + TOBN(0x86d765e4, 0xd14b4206), TOBN(0xbecc2e0e, 0x8fa0db65), + TOBN(0xa28838e0, 0xb17fc76c), TOBN(0xe49a602a, 0xe37cf24e), + TOBN(0x76b4131a, 0x567193ec), TOBN(0xaf3c305a, 0xe5f6e70b), + TOBN(0x9587bd39, 0x031eebdd), TOBN(0x5709def8, 0x71bbe831), + TOBN(0x57059983, 0x0eb2b669), TOBN(0x4d80ce1b, 0x875b7029), + TOBN(0x838a7da8, 0x0364ac16), TOBN(0x2f431d23, 0xbe1c83ab), + TOBN(0xe56812a6, 0xf9294dd3), TOBN(0xb448d01f, 0x9b4b0d77), + TOBN(0xf3ae6061, 0x04e8305c), TOBN(0x2bead645, 0x94d8c63e), + TOBN(0x0a85434d, 0x84fd8b07), TOBN(0x537b983f, 0xf7a9dee5), + TOBN(0xedcc5f18, 0xef55bd85), TOBN(0x2041af62, 0x21c6cf8b), + TOBN(0x8e52874c, 0xb940c71e), TOBN(0x211935a9, 0xdb5f4b3a), + TOBN(0x94350492, 0x301b1dc3), TOBN(0x33d2646d, 0x29958620), + TOBN(0x16b0d64b, 0xef911404), TOBN(0x9d1f25ea, 0x9a3c5ef4), + TOBN(0x20f200eb, 0x4a352c78), TOBN(0x43929f2c, 0x4bd0b428), + TOBN(0xa5656667, 0xc7196e29), TOBN(0x7992c2f0, 0x9391be48), + TOBN(0xaaa97cbd, 0x9ee0cd6e), TOBN(0x51b0310c, 0x3dc8c9bf), + TOBN(0x237f8acf, 0xdd9f22cb), TOBN(0xbb1d81a1, 0xb585d584), + TOBN(0x8d5d85f5, 0x8c416388), TOBN(0x0d6e5a5a, 0x42fe474f), + TOBN(0xe7812766, 0x38235d4e), TOBN(0x1c62bd67, 0x496e3298), + TOBN(0x8378660c, 0x3f175bc8), TOBN(0x4d04e189, 0x17afdd4d), + TOBN(0x32a81601, 0x85a8068c), TOBN(0xdb58e4e1, 0x92b29a85), + TOBN(0xe8a65b86, 0xc70d8a3b), TOBN(0x5f0e6f4e, 0x98a0403b), + TOBN(0x08129684, 0x69ed2370), TOBN(0x34dc30bd, 0x0871ee26), + TOBN(0x3a5ce948, 0x7c9c5b05), TOBN(0x7d487b80, 0x43a90c87), + TOBN(0x4089ba37, 0xdd0e7179), TOBN(0x45f80191, 0xb4041811), + TOBN(0x1c3e1058, 0x98747ba5), TOBN(0x98c4e13a, 0x6e1ae592), + TOBN(0xd44636e6, 0xe82c9f9e), TOBN(0x711db87c, 0xc33a1043), + TOBN(0x6f431263, 0xaa8aec05), TOBN(0x43ff120d, 0x2744a4aa), + TOBN(0xd3bd892f, 0xae77779b), TOBN(0xf0fe0cc9, 0x8cdc9f82), + TOBN(0xca5f7fe6, 0xf1c5b1bc), TOBN(0xcc63a682, 0x44929a72), + TOBN(0xc7eaba0c, 0x09dbe19a), TOBN(0x2f3585ad, 0x6b5c73c2), + TOBN(0x8ab8924b, 0x0ae50c30), TOBN(0x17fcd27a, 0x638b30ba), + TOBN(0xaf414d34, 0x10b3d5a5), TOBN(0x09c107d2, 0x2a9accf1), + TOBN(0x15dac49f, 0x946a6242), TOBN(0xaec3df2a, 0xd707d642), + TOBN(0x2c2492b7, 0x3f894ae0), TOBN(0xf59df3e5, 0xb75f18ce), + TOBN(0x7cb740d2, 0x8f53cad0), TOBN(0x3eb585fb, 0xc4f01294), + TOBN(0x17da0c86, 0x32c7f717), TOBN(0xeb8c795b, 0xaf943f4c), + TOBN(0x4ee23fb5, 0xf67c51d2), TOBN(0xef187575, 0x68889949), + TOBN(0xa6b4bdb2, 0x0389168b), TOBN(0xc4ecd258, 0xea577d03), + TOBN(0x3a63782b, 0x55743082), TOBN(0x6f678f4c, 0xc72f08cd), + TOBN(0x553511cf, 0x65e58dd8), TOBN(0xd53b4e3e, 0xd402c0cd), + TOBN(0x37de3e29, 0xa037c14c), TOBN(0x86b6c516, 0xc05712aa), + TOBN(0x2834da3e, 0xb38dff6f), TOBN(0xbe012c52, 0xea636be8), + TOBN(0x292d238c, 0x61dd37f8), TOBN(0x0e54523f, 0x8f8142db), + TOBN(0xe31eb436, 0x036a05d8), TOBN(0x83e3cdff, 0x1e93c0ff), + TOBN(0x3fd2fe0f, 0x50821ddf), TOBN(0xc8e19b0d, 0xff9eb33b), + TOBN(0xc8cc943f, 0xb569a5fe), TOBN(0xad0090d4, 0xd4342d75), + TOBN(0x82090b4b, 0xcaeca000), TOBN(0xca39687f, 0x1bd410eb), + TOBN(0xe7bb0df7, 0x65959d77), TOBN(0x39d78218, 0x9c964999), + TOBN(0xd87f62e8, 0xb2415451), TOBN(0xe5efb774, 0xbed76108), + TOBN(0x3ea011a4, 0xe822f0d0), TOBN(0xbc647ad1, 0x5a8704f8), + TOBN(0xbb315b35, 0x50c6820f), TOBN(0x863dec3d, 0xb7e76bec), + TOBN(0x01ff5d3a, 0xf017bfc7), TOBN(0x20054439, 0x976b8229), + TOBN(0x067fca37, 0x0bbd0d3b), TOBN(0xf63dde64, 0x7f5e3d0f), + TOBN(0x22dbefb3, 0x2a4c94e9), TOBN(0xafbff0fe, 0x96f8278a), + TOBN(0x80aea0b1, 0x3503793d), TOBN(0xb2238029, 0x5f06cd29), + TOBN(0x65703e57, 0x8ec3feca), TOBN(0x06c38314, 0x393e7053), + TOBN(0xa0b751eb, 0x7c6734c4), TOBN(0xd2e8a435, 0xc59f0f1e), + TOBN(0x147d9052, 0x5e9ca895), TOBN(0x2f4dd31e, 0x972072df), + TOBN(0xa16fda8e, 0xe6c6755c), TOBN(0xc66826ff, 0xcf196558), + TOBN(0x1f1a76a3, 0x0cf43895), TOBN(0xa9d604e0, 0x83c3097b), + TOBN(0xe1908309, 0x66390e0e), TOBN(0xa50bf753, 0xb3c85eff), + TOBN(0x0696bdde, 0xf6a70251), TOBN(0x548b801b, 0x3c6ab16a), + TOBN(0x37fcf704, 0xa4d08762), TOBN(0x090b3def, 0xdff76c4e), + TOBN(0x87e8cb89, 0x69cb9158), TOBN(0x44a90744, 0x995ece43), + TOBN(0xf85395f4, 0x0ad9fbf5), TOBN(0x49b0f6c5, 0x4fb0c82d), + TOBN(0x75d9bc15, 0xadf7cccf), TOBN(0x81a3e5d6, 0xdfa1e1b0), + TOBN(0x8c39e444, 0x249bc17e), TOBN(0xf37dccb2, 0x8ea7fd43), + TOBN(0xda654873, 0x907fba12), TOBN(0x35daa6da, 0x4a372904), + TOBN(0x0564cfc6, 0x6283a6c5), TOBN(0xd09fa4f6, 0x4a9395bf), + TOBN(0x688e9ec9, 0xaeb19a36), TOBN(0xd913f1ce, 0xc7bfbfb4), + TOBN(0x797b9a3c, 0x61c2faa6), TOBN(0x2f979bec, 0x6a0a9c12), + TOBN(0xb5969d0f, 0x359679ec), TOBN(0xebcf523d, 0x079b0460), + TOBN(0xfd6b0008, 0x10fab870), TOBN(0x3f2edcda, 0x9373a39c), + TOBN(0x0d64f9a7, 0x6f568431), TOBN(0xf848c27c, 0x02f8898c), + TOBN(0xf418ade1, 0x260b5bd5), TOBN(0xc1f3e323, 0x6973dee8), + TOBN(0x46e9319c, 0x26c185dd), TOBN(0x6d85b7d8, 0x546f0ac4), + TOBN(0x427965f2, 0x247f9d57), TOBN(0xb519b636, 0xb0035f48), + TOBN(0x6b6163a9, 0xab87d59c), TOBN(0xff9f58c3, 0x39caaa11), + TOBN(0x4ac39cde, 0x3177387b), TOBN(0x5f6557c2, 0x873e77f9), + TOBN(0x67504006, 0x36a83041), TOBN(0x9b1c96ca, 0x75ef196c), + TOBN(0xf34283de, 0xb08c7940), TOBN(0x7ea09644, 0x1128c316), + TOBN(0xb510b3b5, 0x6aa39dff), TOBN(0x59b43da2, 0x9f8e4d8c), + TOBN(0xa8ce31fd, 0x9e4c4b9f), TOBN(0x0e20be26, 0xc1303c01), + TOBN(0x18187182, 0xe8ee47c9), TOBN(0xd9687cdb, 0x7db98101), + TOBN(0x7a520e4d, 0xa1e14ff6), TOBN(0x429808ba, 0x8836d572), + TOBN(0xa37ca60d, 0x4944b663), TOBN(0xf901f7a9, 0xa3f91ae5), + TOBN(0xe4e3e76e, 0x9e36e3b1), TOBN(0x9aa219cf, 0x29d93250), + TOBN(0x347fe275, 0x056a2512), TOBN(0xa4d643d9, 0xde65d95c), + TOBN(0x9669d396, 0x699fc3ed), TOBN(0xb598dee2, 0xcf8c6bbe), + TOBN(0x682ac1e5, 0xdda9e5c6), TOBN(0x4e0d3c72, 0xcaa9fc95), + TOBN(0x17faaade, 0x772bea44), TOBN(0x5ef8428c, 0xab0009c8), + TOBN(0xcc4ce47a, 0x460ff016), TOBN(0xda6d12bf, 0x725281cb), + TOBN(0x44c67848, 0x0223aad2), TOBN(0x6e342afa, 0x36256e28), + TOBN(0x1400bb0b, 0x93a37c04), TOBN(0x62b1bc9b, 0xdd10bd96), + TOBN(0x7251adeb, 0x0dac46b7), TOBN(0x7d33b92e, 0x7be4ef51), + TOBN(0x28b2a94b, 0xe61fa29a), TOBN(0x4b2be13f, 0x06422233), + TOBN(0x36d6d062, 0x330d8d37), TOBN(0x5ef80e1e, 0xb28ca005), + TOBN(0x174d4699, 0x6d16768e), TOBN(0x9fc4ff6a, 0x628bf217), + TOBN(0x77705a94, 0x154e490d), TOBN(0x9d96dd28, 0x8d2d997a), + TOBN(0x77e2d9d8, 0xce5d72c4), TOBN(0x9d06c5a4, 0xc11c714f), + TOBN(0x02aa5136, 0x79e4a03e), TOBN(0x1386b3c2, 0x030ff28b), + TOBN(0xfe82e8a6, 0xfb283f61), TOBN(0x7df203e5, 0xf3abc3fb), + TOBN(0xeec7c351, 0x3a4d3622), TOBN(0xf7d17dbf, 0xdf762761), + TOBN(0xc3956e44, 0x522055f0), TOBN(0xde3012db, 0x8fa748db), + TOBN(0xca9fcb63, 0xbf1dcc14), TOBN(0xa56d9dcf, 0xbe4e2f3a), + TOBN(0xb86186b6, 0x8bcec9c2), TOBN(0x7cf24df9, 0x680b9f06), + TOBN(0xc46b45ea, 0xc0d29281), TOBN(0xfff42bc5, 0x07b10e12), + TOBN(0x12263c40, 0x4d289427), TOBN(0x3d5f1899, 0xb4848ec4), + TOBN(0x11f97010, 0xd040800c), TOBN(0xb4c5f529, 0x300feb20), + TOBN(0xcc543f8f, 0xde94fdcb), TOBN(0xe96af739, 0xc7c2f05e), + TOBN(0xaa5e0036, 0x882692e1), TOBN(0x09c75b68, 0x950d4ae9), + TOBN(0x62f63df2, 0xb5932a7a), TOBN(0x2658252e, 0xde0979ad), + TOBN(0x2a19343f, 0xb5e69631), TOBN(0x718c7501, 0x525b666b), + TOBN(0x26a42d69, 0xea40dc3a), TOBN(0xdc84ad22, 0xaecc018f), + TOBN(0x25c36c7b, 0x3270f04a), TOBN(0x46ba6d47, 0x50fa72ed), + TOBN(0x6c37d1c5, 0x93e58a8e), TOBN(0xa2394731, 0x120c088c), + TOBN(0xc3be4263, 0xcb6e86da), TOBN(0x2c417d36, 0x7126d038), + TOBN(0x5b70f9c5, 0x8b6f8efa), TOBN(0x671a2faa, 0x37718536), + TOBN(0xd3ced3c6, 0xb539c92b), TOBN(0xe56f1bd9, 0xa31203c2), + TOBN(0x8b096ec4, 0x9ff3c8eb), TOBN(0x2deae432, 0x43491cea), + TOBN(0x2465c6eb, 0x17943794), TOBN(0x5d267e66, 0x20586843), + TOBN(0x9d3d116d, 0xb07159d0), TOBN(0xae07a67f, 0xc1896210), + TOBN(0x8fc84d87, 0xbb961579), TOBN(0x30009e49, 0x1c1f8dd6), + TOBN(0x8a8caf22, 0xe3132819), TOBN(0xcffa197c, 0xf23ab4ff), + TOBN(0x58103a44, 0x205dd687), TOBN(0x57b796c3, 0x0ded67a2), + TOBN(0x0b9c3a6c, 0xa1779ad7), TOBN(0xa33cfe2e, 0x357c09c5), + TOBN(0x2ea29315, 0x3db4a57e), TOBN(0x91959695, 0x8ebeb52e), + TOBN(0x118db9a6, 0xe546c879), TOBN(0x8e996df4, 0x6295c8d6), + TOBN(0xdd990484, 0x55ec806b), TOBN(0x24f291ca, 0x165c1035), + TOBN(0xcca523bb, 0x440e2229), TOBN(0x324673a2, 0x73ef4d04), + TOBN(0xaf3adf34, 0x3e11ec39), TOBN(0x6136d7f1, 0xdc5968d3), + TOBN(0x7a7b2899, 0xb053a927), TOBN(0x3eaa2661, 0xae067ecd), + TOBN(0x8549b9c8, 0x02779cd9), TOBN(0x061d7940, 0xc53385ea), + TOBN(0x3e0ba883, 0xf06d18bd), TOBN(0x4ba6de53, 0xb2700843), + TOBN(0xb966b668, 0x591a9e4d), TOBN(0x93f67567, 0x7f4fa0ed), + TOBN(0x5a02711b, 0x4347237b), TOBN(0xbc041e2f, 0xe794608e), + TOBN(0x55af10f5, 0x70f73d8c), TOBN(0xd2d4d4f7, 0xbb7564f7), + TOBN(0xd7d27a89, 0xb3e93ce7), TOBN(0xf7b5a875, 0x5d3a2c1b), + TOBN(0xb29e68a0, 0x255b218a), TOBN(0xb533837e, 0x8af76754), + TOBN(0xd1b05a73, 0x579fab2e), TOBN(0xb41055a1, 0xecd74385), + TOBN(0xb2369274, 0x445e9115), TOBN(0x2972a7c4, 0xf520274e), + TOBN(0x6c08334e, 0xf678e68a), TOBN(0x4e4160f0, 0x99b057ed), + TOBN(0x3cfe11b8, 0x52ccb69a), TOBN(0x2fd1823a, 0x21c8f772), + TOBN(0xdf7f072f, 0x3298f055), TOBN(0x8c0566f9, 0xfec74a6e), + TOBN(0xe549e019, 0x5bb4d041), TOBN(0x7c3930ba, 0x9208d850), + TOBN(0xe07141fc, 0xaaa2902b), TOBN(0x539ad799, 0xe4f69ad3), + TOBN(0xa6453f94, 0x813f9ffd), TOBN(0xc58d3c48, 0x375bc2f7), + TOBN(0xb3326fad, 0x5dc64e96), TOBN(0x3aafcaa9, 0xb240e354), + TOBN(0x1d1b0903, 0xaca1e7a9), TOBN(0x4ceb9767, 0x1211b8a0), + TOBN(0xeca83e49, 0xe32a858e), TOBN(0x4c32892e, 0xae907bad), + TOBN(0xd5b42ab6, 0x2eb9b494), TOBN(0x7fde3ee2, 0x1eabae1b), + TOBN(0x13b5ab09, 0xcaf54957), TOBN(0xbfb028be, 0xe5f5d5d5), + TOBN(0x928a0650, 0x2003e2c0), TOBN(0x90793aac, 0x67476843), + TOBN(0x5e942e79, 0xc81710a0), TOBN(0x557e4a36, 0x27ccadd4), + TOBN(0x72a2bc56, 0x4bcf6d0c), TOBN(0x09ee5f43, 0x26d7b80c), + TOBN(0x6b70dbe9, 0xd4292f19), TOBN(0x56f74c26, 0x63f16b18), + TOBN(0xc23db0f7, 0x35fbb42a), TOBN(0xb606bdf6, 0x6ae10040), + TOBN(0x1eb15d4d, 0x044573ac), TOBN(0x7dc3cf86, 0x556b0ba4), + TOBN(0x97af9a33, 0xc60df6f7), TOBN(0x0b1ef85c, 0xa716ce8c), + TOBN(0x2922f884, 0xc96958be), TOBN(0x7c32fa94, 0x35690963), + TOBN(0x2d7f667c, 0xeaa00061), TOBN(0xeaaf7c17, 0x3547365c), + TOBN(0x1eb4de46, 0x87032d58), TOBN(0xc54f3d83, 0x5e2c79e0), + TOBN(0x07818df4, 0x5d04ef23), TOBN(0x55faa9c8, 0x673d41b4), + TOBN(0xced64f6f, 0x89b95355), TOBN(0x4860d2ea, 0xb7415c84), + TOBN(0x5fdb9bd2, 0x050ebad3), TOBN(0xdb53e0cc, 0x6685a5bf), + TOBN(0xb830c031, 0x9feb6593), TOBN(0xdd87f310, 0x6accff17), + TOBN(0x2303ebab, 0x9f555c10), TOBN(0x94603695, 0x287e7065), + TOBN(0xf88311c3, 0x2e83358c), TOBN(0x508dd9b4, 0xeefb0178), + TOBN(0x7ca23706, 0x2dba8652), TOBN(0x62aac5a3, 0x0047abe5), + TOBN(0x9a61d2a0, 0x8b1ea7b3), TOBN(0xd495ab63, 0xae8b1485), + TOBN(0x38740f84, 0x87052f99), TOBN(0x178ebe5b, 0xb2974eea), + TOBN(0x030bbcca, 0x5b36d17f), TOBN(0xb5e4cce3, 0xaaf86eea), + TOBN(0xb51a0220, 0x68f8e9e0), TOBN(0xa4348796, 0x09eb3e75), + TOBN(0xbe592309, 0xeef1a752), TOBN(0x5d7162d7, 0x6f2aa1ed), + TOBN(0xaebfb5ed, 0x0f007dd2), TOBN(0x255e14b2, 0xc89edd22), + TOBN(0xba85e072, 0x0303b697), TOBN(0xc5d17e25, 0xf05720ff), + TOBN(0x02b58d6e, 0x5128ebb6), TOBN(0x2c80242d, 0xd754e113), + TOBN(0x919fca5f, 0xabfae1ca), TOBN(0x937afaac, 0x1a21459b), + TOBN(0x9e0ca91c, 0x1f66a4d2), TOBN(0x194cc7f3, 0x23ec1331), + TOBN(0xad25143a, 0x8aa11690), TOBN(0xbe40ad8d, 0x09b59e08), + TOBN(0x37d60d9b, 0xe750860a), TOBN(0x6c53b008, 0xc6bf434c), + TOBN(0xb572415d, 0x1356eb80), TOBN(0xb8bf9da3, 0x9578ded8), + TOBN(0x22658e36, 0x5e8fb38b), TOBN(0x9b70ce22, 0x5af8cb22), + TOBN(0x7c00018a, 0x829a8180), TOBN(0x84329f93, 0xb81ed295), + TOBN(0x7c343ea2, 0x5f3cea83), TOBN(0x38f8655f, 0x67586536), + TOBN(0xa661a0d0, 0x1d3ec517), TOBN(0x98744652, 0x512321ae), + TOBN(0x084ca591, 0xeca92598), TOBN(0xa9bb9dc9, 0x1dcb3feb), + TOBN(0x14c54355, 0x78b4c240), TOBN(0x5ed62a3b, 0x610cafdc), + TOBN(0x07512f37, 0x1b38846b), TOBN(0x571bb70a, 0xb0e38161), + TOBN(0xb556b95b, 0x2da705d2), TOBN(0x3ef8ada6, 0xb1a08f98), + TOBN(0x85302ca7, 0xddecfbe5), TOBN(0x0e530573, 0x943105cd), + TOBN(0x60554d55, 0x21a9255d), TOBN(0x63a32fa1, 0xf2f3802a), + TOBN(0x35c8c5b0, 0xcd477875), TOBN(0x97f458ea, 0x6ad42da1), + TOBN(0x832d7080, 0xeb6b242d), TOBN(0xd30bd023, 0x3b71e246), + TOBN(0x7027991b, 0xbe31139d), TOBN(0x68797e91, 0x462e4e53), + TOBN(0x423fe20a, 0x6b4e185a), TOBN(0x82f2c67e, 0x42d9b707), + TOBN(0x25c81768, 0x4cf7811b), TOBN(0xbd53005e, 0x045bb95d)}, + {TOBN(0xe5f649be, 0x9d8e68fd), TOBN(0xdb0f0533, 0x1b044320), + TOBN(0xf6fde9b3, 0xe0c33398), TOBN(0x92f4209b, 0x66c8cfae), + TOBN(0xe9d1afcc, 0x1a739d4b), TOBN(0x09aea75f, 0xa28ab8de), + TOBN(0x14375fb5, 0xeac6f1d0), TOBN(0x6420b560, 0x708f7aa5), + TOBN(0x9eae499c, 0x6254dc41), TOBN(0x7e293924, 0x7a837e7e), + TOBN(0x74aec08c, 0x090524a7), TOBN(0xf82b9219, 0x8d6f55f2), + TOBN(0x493c962e, 0x1402cec5), TOBN(0x9f17ca17, 0xfa2f30e7), + TOBN(0xbcd783e8, 0xe9b879cb), TOBN(0xea3d8c14, 0x5a6f145f), + TOBN(0xdede15e7, 0x5e0dee6e), TOBN(0x74f24872, 0xdc628aa2), + TOBN(0xd3e9c4fe, 0x7861bb93), TOBN(0x56d4822a, 0x6187b2e0), + TOBN(0xb66417cf, 0xc59826f9), TOBN(0xca260969, 0x2408169e), + TOBN(0xedf69d06, 0xc79ef885), TOBN(0x00031f8a, 0xdc7d138f), + TOBN(0x103c46e6, 0x0ebcf726), TOBN(0x4482b831, 0x6231470e), + TOBN(0x6f6dfaca, 0x487c2109), TOBN(0x2e0ace97, 0x62e666ef), + TOBN(0x3246a9d3, 0x1f8d1f42), TOBN(0x1b1e83f1, 0x574944d2), + TOBN(0x13dfa63a, 0xa57f334b), TOBN(0x0cf8daed, 0x9f025d81), + TOBN(0x30d78ea8, 0x00ee11c1), TOBN(0xeb053cd4, 0xb5e3dd75), + TOBN(0x9b65b13e, 0xd58c43c5), TOBN(0xc3ad49bd, 0xbd151663), + TOBN(0x99fd8e41, 0xb6427990), TOBN(0x12cf15bd, 0x707eae1e), + TOBN(0x29ad4f1b, 0x1aabb71e), TOBN(0x5143e74d, 0x07545d0e), + TOBN(0x30266336, 0xc88bdee1), TOBN(0x25f29306, 0x5876767c), + TOBN(0x9c078571, 0xc6731996), TOBN(0xc88690b2, 0xed552951), + TOBN(0x274f2c2d, 0x852705b4), TOBN(0xb0bf8d44, 0x4e09552d), + TOBN(0x7628beeb, 0x986575d1), TOBN(0x407be238, 0x7f864651), + TOBN(0x0e5e3049, 0xa639fc6b), TOBN(0xe75c35d9, 0x86003625), + TOBN(0x0cf35bd8, 0x5dcc1646), TOBN(0x8bcaced2, 0x6c26273a), + TOBN(0xe22ecf1d, 0xb5536742), TOBN(0x013dd897, 0x1a9e068b), + TOBN(0x17f411cb, 0x8a7909c5), TOBN(0x5757ac98, 0x861dd506), + TOBN(0x85de1f0d, 0x1e935abb), TOBN(0xdefd10b4, 0x154de37a), + TOBN(0xb8d9e392, 0x369cebb5), TOBN(0x54d5ef9b, 0x761324be), + TOBN(0x4d6341ba, 0x74f17e26), TOBN(0xc0a0e3c8, 0x78c1dde4), + TOBN(0xa6d77581, 0x87d918fd), TOBN(0x66876015, 0x02ca3a13), + TOBN(0xc7313e9c, 0xf36658f0), TOBN(0xc433ef1c, 0x71f8057e), + TOBN(0x85326246, 0x1b6a835a), TOBN(0xc8f05398, 0x7c86394c), + TOBN(0xff398cdf, 0xe983c4a1), TOBN(0xbf5e8162, 0x03b7b931), + TOBN(0x93193c46, 0xb7b9045b), TOBN(0x1e4ebf5d, 0xa4a6e46b), + TOBN(0xf9942a60, 0x43a24fe7), TOBN(0x29c1191e, 0xffb3492b), + TOBN(0x9f662449, 0x902fde05), TOBN(0xc792a7ac, 0x6713c32d), + TOBN(0x2fd88ad8, 0xb737982c), TOBN(0x7e3a0319, 0xa21e60e3), + TOBN(0x09b0de44, 0x7383591a), TOBN(0x6df141ee, 0x8310a456), + TOBN(0xaec1a039, 0xe6d6f471), TOBN(0x14b2ba0f, 0x1198d12e), + TOBN(0xebc1a160, 0x3aeee5ac), TOBN(0x401f4836, 0xe0b964ce), + TOBN(0x2ee43796, 0x4fd03f66), TOBN(0x3fdb4e49, 0xdd8f3f12), + TOBN(0x6ef267f6, 0x29380f18), TOBN(0x3e8e9670, 0x8da64d16), + TOBN(0xbc19180c, 0x207674f1), TOBN(0x112e09a7, 0x33ae8fdb), + TOBN(0x99667554, 0x6aaeb71e), TOBN(0x79432af1, 0xe101b1c7), + TOBN(0xd5eb558f, 0xde2ddec6), TOBN(0x81392d1f, 0x5357753f), + TOBN(0xa7a76b97, 0x3ae1158a), TOBN(0x416fbbff, 0x4a899991), + TOBN(0x9e65fdfd, 0x0d4a9dcf), TOBN(0x7bc29e48, 0x944ddf12), + TOBN(0xbc1a92d9, 0x3c856866), TOBN(0x273c6905, 0x6e98dfe2), + TOBN(0x69fce418, 0xcdfaa6b8), TOBN(0x606bd823, 0x5061c69f), + TOBN(0x42d495a0, 0x6af75e27), TOBN(0x8ed3d505, 0x6d873a1f), + TOBN(0xaf552841, 0x6ab25b6a), TOBN(0xc6c0ffc7, 0x2b1a4523), + TOBN(0xab18827b, 0x21c99e03), TOBN(0x060e8648, 0x9034691b), + TOBN(0x5207f90f, 0x93c7f398), TOBN(0x9f4a96cb, 0x82f8d10b), + TOBN(0xdd71cd79, 0x3ad0f9e3), TOBN(0x84f435d2, 0xfc3a54f5), + TOBN(0x4b03c55b, 0x8e33787f), TOBN(0xef42f975, 0xa6384673), + TOBN(0xff7304f7, 0x5051b9f0), TOBN(0x18aca1dc, 0x741c87c2), + TOBN(0x56f120a7, 0x2d4bfe80), TOBN(0xfd823b3d, 0x053e732c), + TOBN(0x11bccfe4, 0x7537ca16), TOBN(0xdf6c9c74, 0x1b5a996b), + TOBN(0xee7332c7, 0x904fc3fa), TOBN(0x14a23f45, 0xc7e3636a), + TOBN(0xc38659c3, 0xf091d9aa), TOBN(0x4a995e5d, 0xb12d8540), + TOBN(0x20a53bec, 0xf3a5598a), TOBN(0x56534b17, 0xb1eaa995), + TOBN(0x9ed3dca4, 0xbf04e03c), TOBN(0x716c563a, 0xd8d56268), + TOBN(0x27ba77a4, 0x1d6178e7), TOBN(0xe4c80c40, 0x68a1ff8e), + TOBN(0x75011099, 0x0a13f63d), TOBN(0x7bf33521, 0xa61d46f3), + TOBN(0x0aff218e, 0x10b365bb), TOBN(0x81021804, 0x0fd7ea75), + TOBN(0x05a3fd8a, 0xa4b3a925), TOBN(0xb829e75f, 0x9b3db4e6), + TOBN(0x6bdc75a5, 0x4d53e5fb), TOBN(0x04a5dc02, 0xd52717e3), + TOBN(0x86af502f, 0xe9a42ec2), TOBN(0x8867e8fb, 0x2630e382), + TOBN(0xbf845c6e, 0xbec9889b), TOBN(0x54f491f2, 0xcb47c98d), + TOBN(0xa3091fba, 0x790c2a12), TOBN(0xd7f6fd78, 0xc20f708b), + TOBN(0xa569ac30, 0xacde5e17), TOBN(0xd0f996d0, 0x6852b4d7), + TOBN(0xe51d4bb5, 0x4609ae54), TOBN(0x3fa37d17, 0x0daed061), + TOBN(0x62a88684, 0x34b8fb41), TOBN(0x99a2acbd, 0x9efb64f1), + TOBN(0xb75c1a5e, 0x6448e1f2), TOBN(0xfa99951a, 0x42b5a069), + TOBN(0x6d956e89, 0x2f3b26e7), TOBN(0xf4709860, 0xda875247), + TOBN(0x3ad15179, 0x2482dda3), TOBN(0xd64110e3, 0x017d82f0), + TOBN(0x14928d2c, 0xfad414e4), TOBN(0x2b155f58, 0x2ed02b24), + TOBN(0x481a141b, 0xcb821bf1), TOBN(0x12e3c770, 0x4f81f5da), + TOBN(0xe49c5de5, 0x9fff8381), TOBN(0x11053232, 0x5bbec894), + TOBN(0xa0d051cc, 0x454d88c4), TOBN(0x4f6db89c, 0x1f8e531b), + TOBN(0x34fe3fd6, 0xca563a44), TOBN(0x7f5c2215, 0x58da8ab9), + TOBN(0x8445016d, 0x9474f0a1), TOBN(0x17d34d61, 0xcb7d8a0a), + TOBN(0x8e9d3910, 0x1c474019), TOBN(0xcaff2629, 0xd52ceefb), + TOBN(0xf9cf3e32, 0xc1622c2b), TOBN(0xd4b95e3c, 0xe9071a05), + TOBN(0xfbbca61f, 0x1594438c), TOBN(0x1eb6e6a6, 0x04aadedf), + TOBN(0x853027f4, 0x68e14940), TOBN(0x221d322a, 0xdfabda9c), + TOBN(0xed8ea9f6, 0xb7cb179a), TOBN(0xdc7b764d, 0xb7934dcc), + TOBN(0xfcb13940, 0x5e09180d), TOBN(0x6629a6bf, 0xb47dc2dd), + TOBN(0xbfc55e4e, 0x9f5a915e), TOBN(0xb1db9d37, 0x6204441e), + TOBN(0xf82d68cf, 0x930c5f53), TOBN(0x17d3a142, 0xcbb605b1), + TOBN(0xdd5944ea, 0x308780f2), TOBN(0xdc8de761, 0x3845f5e4), + TOBN(0x6beaba7d, 0x7624d7a3), TOBN(0x1e709afd, 0x304df11e), + TOBN(0x95364376, 0x02170456), TOBN(0xbf204b3a, 0xc8f94b64), + TOBN(0x4e53af7c, 0x5680ca68), TOBN(0x0526074a, 0xe0c67574), + TOBN(0x95d8cef8, 0xecd92af6), TOBN(0xe6b9fa7a, 0x6cd1745a), + TOBN(0x3d546d3d, 0xa325c3e4), TOBN(0x1f57691d, 0x9ae93aae), + TOBN(0xe891f3fe, 0x9d2e1a33), TOBN(0xd430093f, 0xac063d35), + TOBN(0xeda59b12, 0x5513a327), TOBN(0xdc2134f3, 0x5536f18f), + TOBN(0xaa51fe2c, 0x5c210286), TOBN(0x3f68aaee, 0x1cab658c), + TOBN(0x5a23a00b, 0xf9357292), TOBN(0x9a626f39, 0x7efdabed), + TOBN(0xfe2b3bf3, 0x199d78e3), TOBN(0xb7a2af77, 0x71bbc345), + TOBN(0x3d19827a, 0x1e59802c), TOBN(0x823bbc15, 0xb487a51c), + TOBN(0x856139f2, 0x99d0a422), TOBN(0x9ac3df65, 0xf456c6fb), + TOBN(0xaddf65c6, 0x701f8bd6), TOBN(0x149f321e, 0x3758df87), + TOBN(0xb1ecf714, 0x721b7eba), TOBN(0xe17df098, 0x31a3312a), + TOBN(0xdb2fd6ec, 0xd5c4d581), TOBN(0xfd02996f, 0x8fcea1b3), + TOBN(0xe29fa63e, 0x7882f14f), TOBN(0xc9f6dc35, 0x07c6cadc), + TOBN(0x46f22d6f, 0xb882bed0), TOBN(0x1a45755b, 0xd118e52c), + TOBN(0x9f2c7c27, 0x7c4608cf), TOBN(0x7ccbdf32, 0x568012c2), + TOBN(0xfcb0aedd, 0x61729b0e), TOBN(0x7ca2ca9e, 0xf7d75dbf), + TOBN(0xf58fecb1, 0x6f640f62), TOBN(0xe274b92b, 0x39f51946), + TOBN(0x7f4dfc04, 0x6288af44), TOBN(0x0a91f32a, 0xeac329e5), + TOBN(0x43ad274b, 0xd6aaba31), TOBN(0x719a1640, 0x0f6884f9), + TOBN(0x685d29f6, 0xdaf91e20), TOBN(0x5ec1cc33, 0x27e49d52), + TOBN(0x38f4de96, 0x3b54a059), TOBN(0x0e0015e5, 0xefbcfdb3), + TOBN(0x177d23d9, 0x4dbb8da6), TOBN(0x98724aa2, 0x97a617ad), + TOBN(0x30f0885b, 0xfdb6558e), TOBN(0xf9f7a28a, 0xc7899a96), + TOBN(0xd2ae8ac8, 0x872dc112), TOBN(0xfa0642ca, 0x73c3c459), + TOBN(0x15296981, 0xe7dfc8d6), TOBN(0x67cd4450, 0x1fb5b94a), + TOBN(0x0ec71cf1, 0x0eddfd37), TOBN(0xc7e5eeb3, 0x9a8eddc7), + TOBN(0x02ac8e3d, 0x81d95028), TOBN(0x0088f172, 0x70b0e35d), + TOBN(0xec041fab, 0xe1881fe3), TOBN(0x62cf71b8, 0xd99e7faa), + TOBN(0x5043dea7, 0xe0f222c2), TOBN(0x309d42ac, 0x72e65142), + TOBN(0x94fe9ddd, 0x9216cd30), TOBN(0xd6539c7d, 0x0f87feec), + TOBN(0x03c5a57c, 0x432ac7d7), TOBN(0x72692cf0, 0x327fda10), + TOBN(0xec28c85f, 0x280698de), TOBN(0x2331fb46, 0x7ec283b1), + TOBN(0xd34bfa32, 0x2867e633), TOBN(0x78709a82, 0x0a9cc815), + TOBN(0xb7fe6964, 0x875e2fa5), TOBN(0x25cc064f, 0x9e98bfb5), + TOBN(0x9eb0151c, 0x493a65c5), TOBN(0x5fb5d941, 0x53182464), + TOBN(0x69e6f130, 0xf04618e2), TOBN(0xa8ecec22, 0xf89c8ab6), + TOBN(0xcd6ac88b, 0xb96209bd), TOBN(0x65fa8cdb, 0xb3e1c9e0), + TOBN(0xa47d22f5, 0x4a8d8eac), TOBN(0x83895cdf, 0x8d33f963), + TOBN(0xa8adca59, 0xb56cd3d1), TOBN(0x10c8350b, 0xdaf38232), + TOBN(0x2b161fb3, 0xa5080a9f), TOBN(0xbe7f5c64, 0x3af65b3a), + TOBN(0x2c754039, 0x97403a11), TOBN(0x94626cf7, 0x121b96af), + TOBN(0x431de7c4, 0x6a983ec2), TOBN(0x3780dd3a, 0x52cc3df7), + TOBN(0xe28a0e46, 0x2baf8e3b), TOBN(0xabe68aad, 0x51d299ae), + TOBN(0x603eb8f9, 0x647a2408), TOBN(0x14c61ed6, 0x5c750981), + TOBN(0x88b34414, 0xc53352e7), TOBN(0x5a34889c, 0x1337d46e), + TOBN(0x612c1560, 0xf95f2bc8), TOBN(0x8a3f8441, 0xd4807a3a), + TOBN(0x680d9e97, 0x5224da68), TOBN(0x60cd6e88, 0xc3eb00e9), + TOBN(0x3875a98e, 0x9a6bc375), TOBN(0xdc80f924, 0x4fd554c2), + TOBN(0x6c4b3415, 0x6ac77407), TOBN(0xa1e5ea8f, 0x25420681), + TOBN(0x541bfa14, 0x4607a458), TOBN(0x5dbc7e7a, 0x96d7fbf9), + TOBN(0x646a851b, 0x31590a47), TOBN(0x039e85ba, 0x15ee6df8), + TOBN(0xd19fa231, 0xd7b43fc0), TOBN(0x84bc8be8, 0x299a0e04), + TOBN(0x2b9d2936, 0xf20df03a), TOBN(0x24054382, 0x8608d472), + TOBN(0x76b6ba04, 0x9149202a), TOBN(0xb21c3831, 0x3670e7b7), + TOBN(0xddd93059, 0xd6fdee10), TOBN(0x9da47ad3, 0x78488e71), + TOBN(0x99cc1dfd, 0xa0fcfb25), TOBN(0x42abde10, 0x64696954), + TOBN(0x14cc15fc, 0x17eab9fe), TOBN(0xd6e863e4, 0xd3e70972), + TOBN(0x29a7765c, 0x6432112c), TOBN(0x88660001, 0x5b0774d8), + TOBN(0x3729175a, 0x2c088eae), TOBN(0x13afbcae, 0x8230b8d4), + TOBN(0x44768151, 0x915f4379), TOBN(0xf086431a, 0xd8d22812), + TOBN(0x37461955, 0xc298b974), TOBN(0x905fb5f0, 0xf8711e04), + TOBN(0x787abf3a, 0xfe969d18), TOBN(0x392167c2, 0x6f6a494e), + TOBN(0xfc7a0d2d, 0x28c511da), TOBN(0xf127c7dc, 0xb66a262d), + TOBN(0xf9c4bb95, 0xfd63fdf0), TOBN(0x90016589, 0x3913ef46), + TOBN(0x74d2a73c, 0x11aa600d), TOBN(0x2f5379bd, 0x9fb5ab52), + TOBN(0xe49e53a4, 0x7fb70068), TOBN(0x68dd39e5, 0x404aa9a7), + TOBN(0xb9b0cf57, 0x2ecaa9c3), TOBN(0xba0e103b, 0xe824826b), + TOBN(0x60c2198b, 0x4631a3c4), TOBN(0xc5ff84ab, 0xfa8966a2), + TOBN(0x2d6ebe22, 0xac95aff8), TOBN(0x1c9bb6db, 0xb5a46d09), + TOBN(0x419062da, 0x53ee4f8d), TOBN(0x7b9042d0, 0xbb97efef), + TOBN(0x0f87f080, 0x830cf6bd), TOBN(0x4861d19a, 0x6ec8a6c6), + TOBN(0xd3a0daa1, 0x202f01aa), TOBN(0xb0111674, 0xf25afbd5), + TOBN(0x6d00d6cf, 0x1afb20d9), TOBN(0x13695000, 0x40671bc5), + TOBN(0x913ab0dc, 0x2485ea9b), TOBN(0x1f2bed06, 0x9eef61ac), + TOBN(0x850c8217, 0x6d799e20), TOBN(0x93415f37, 0x3271c2de), + TOBN(0x5afb06e9, 0x6c4f5910), TOBN(0x688a52df, 0xc4e9e421), + TOBN(0x30495ba3, 0xe2a9a6db), TOBN(0x4601303d, 0x58f9268b), + TOBN(0xbe3b0dad, 0x7eb0f04f), TOBN(0x4ea47250, 0x4456936d), + TOBN(0x8caf8798, 0xd33fd3e7), TOBN(0x1ccd8a89, 0xeb433708), + TOBN(0x9effe3e8, 0x87fd50ad), TOBN(0xbe240a56, 0x6b29c4df), + TOBN(0xec4ffd98, 0xca0e7ebd), TOBN(0xf586783a, 0xe748616e), + TOBN(0xa5b00d8f, 0xc77baa99), TOBN(0x0acada29, 0xb4f34c9c), + TOBN(0x36dad67d, 0x0fe723ac), TOBN(0x1d8e53a5, 0x39c36c1e), + TOBN(0xe4dd342d, 0x1f4bea41), TOBN(0x64fd5e35, 0xebc9e4e0), + TOBN(0x96f01f90, 0x57908805), TOBN(0xb5b9ea3d, 0x5ed480dd), + TOBN(0x366c5dc2, 0x3efd2dd0), TOBN(0xed2fe305, 0x6e9dfa27), + TOBN(0x4575e892, 0x6e9197e2), TOBN(0x11719c09, 0xab502a5d), + TOBN(0x264c7bec, 0xe81f213f), TOBN(0x741b9241, 0x55f5c457), + TOBN(0x78ac7b68, 0x49a5f4f4), TOBN(0xf91d70a2, 0x9fc45b7d), + TOBN(0x39b05544, 0xb0f5f355), TOBN(0x11f06bce, 0xeef930d9), + TOBN(0xdb84d25d, 0x038d05e1), TOBN(0x04838ee5, 0xbacc1d51), + TOBN(0x9da3ce86, 0x9e8ee00b), TOBN(0xc3412057, 0xc36eda1f), + TOBN(0xae80b913, 0x64d9c2f4), TOBN(0x7468bac3, 0xa010a8ff), + TOBN(0xdfd20037, 0x37359d41), TOBN(0x1a0f5ab8, 0x15efeacc), + TOBN(0x7c25ad2f, 0x659d0ce0), TOBN(0x4011bcbb, 0x6785cff1), + TOBN(0x128b9912, 0x7e2192c7), TOBN(0xa549d8e1, 0x13ccb0e8), + TOBN(0x805588d8, 0xc85438b1), TOBN(0x5680332d, 0xbc25cb27), + TOBN(0xdcd1bc96, 0x1a4bfdf4), TOBN(0x779ff428, 0x706f6566), + TOBN(0x8bbee998, 0xf059987a), TOBN(0xf6ce8cf2, 0xcc686de7), + TOBN(0xf8ad3c4a, 0x953cfdb2), TOBN(0xd1d426d9, 0x2205da36), + TOBN(0xb3c0f13f, 0xc781a241), TOBN(0x3e89360e, 0xd75362a8), + TOBN(0xccd05863, 0xc8a91184), TOBN(0x9bd0c9b7, 0xefa8a7f4), + TOBN(0x97ee4d53, 0x8a912a4b), TOBN(0xde5e15f8, 0xbcf518fd), + TOBN(0x6a055bf8, 0xc467e1e0), TOBN(0x10be4b4b, 0x1587e256), + TOBN(0xd90c14f2, 0x668621c9), TOBN(0xd5518f51, 0xab9c92c1), + TOBN(0x8e6a0100, 0xd6d47b3c), TOBN(0xcbe980dd, 0x66716175), + TOBN(0x500d3f10, 0xddd83683), TOBN(0x3b6cb35d, 0x99cac73c), + TOBN(0x53730c8b, 0x6083d550), TOBN(0xcf159767, 0xdf0a1987), + TOBN(0x84bfcf53, 0x43ad73b3), TOBN(0x1b528c20, 0x4f035a94), + TOBN(0x4294edf7, 0x33eeac69), TOBN(0xb6283e83, 0x817f3240), + TOBN(0xc3fdc959, 0x0a5f25b1), TOBN(0xefaf8aa5, 0x5844ee22), + TOBN(0xde269ba5, 0xdbdde4de), TOBN(0xe3347160, 0xc56133bf), + TOBN(0xc1184219, 0x8d9ea9f8), TOBN(0x090de5db, 0xf3fc1ab5), + TOBN(0x404c37b1, 0x0bf22cda), TOBN(0x7de20ec8, 0xf5618894), + TOBN(0x754c588e, 0xecdaecab), TOBN(0x6ca4b0ed, 0x88342743), + TOBN(0x76f08bdd, 0xf4a938ec), TOBN(0xd182de89, 0x91493ccb), + TOBN(0xd652c53e, 0xc8a4186a), TOBN(0xb3e878db, 0x946d8e33), + TOBN(0x088453c0, 0x5f37663c), TOBN(0x5cd9daaa, 0xb407748b), + TOBN(0xa1f5197f, 0x586d5e72), TOBN(0x47500be8, 0xc443ca59), + TOBN(0x78ef35b2, 0xe2652424), TOBN(0x09c5d26f, 0x6dd7767d), + TOBN(0x7175a79a, 0xa74d3f7b), TOBN(0x0428fd8d, 0xcf5ea459), + TOBN(0x511cb97c, 0xa5d1746d), TOBN(0x36363939, 0xe71d1278), + TOBN(0xcf2df955, 0x10350bf4), TOBN(0xb3817439, 0x60aae782), + TOBN(0xa748c0e4, 0x3e688809), TOBN(0x98021fbf, 0xd7a5a006), + TOBN(0x9076a70c, 0x0e367a98), TOBN(0xbea1bc15, 0x0f62b7c2), + TOBN(0x2645a68c, 0x30fe0343), TOBN(0xacaffa78, 0x699dc14f), + TOBN(0xf4469964, 0x457bf9c4), TOBN(0x0db6407b, 0x0d2ead83), + TOBN(0x68d56cad, 0xb2c6f3eb), TOBN(0x3b512e73, 0xf376356c), + TOBN(0xe43b0e1f, 0xfce10408), TOBN(0x89ddc003, 0x5a5e257d), + TOBN(0xb0ae0d12, 0x0362e5b3), TOBN(0x07f983c7, 0xb0519161), + TOBN(0xc2e94d15, 0x5d5231e7), TOBN(0xcff22aed, 0x0b4f9513), + TOBN(0xb02588dd, 0x6ad0b0b5), TOBN(0xb967d1ac, 0x11d0dcd5), + TOBN(0x8dac6bc6, 0xcf777b6c), TOBN(0x0062bdbd, 0x4c6d1959), + TOBN(0x53da71b5, 0x0ef5cc85), TOBN(0x07012c7d, 0x4006f14f), + TOBN(0x4617f962, 0xac47800d), TOBN(0x53365f2b, 0xc102ed75), + TOBN(0xb422efcb, 0x4ab8c9d3), TOBN(0x195cb26b, 0x34af31c9), + TOBN(0x3a926e29, 0x05f2c4ce), TOBN(0xbd2bdecb, 0x9856966c), + TOBN(0x5d16ab3a, 0x85527015), TOBN(0x9f81609e, 0x4486c231), + TOBN(0xd8b96b2c, 0xda350002), TOBN(0xbd054690, 0xfa1b7d36), + TOBN(0xdc90ebf5, 0xe71d79bc), TOBN(0xf241b6f9, 0x08964e4e), + TOBN(0x7c838643, 0x2fe3cd4c), TOBN(0xe0f33acb, 0xb4bc633c), + TOBN(0xb4a9ecec, 0x3d139f1f), TOBN(0x05ce69cd, 0xdc4a1f49), + TOBN(0xa19d1b16, 0xf5f98aaf), TOBN(0x45bb71d6, 0x6f23e0ef), + TOBN(0x33789fcd, 0x46cdfdd3), TOBN(0x9b8e2978, 0xcee040ca), + TOBN(0x9c69b246, 0xae0a6828), TOBN(0xba533d24, 0x7078d5aa), + TOBN(0x7a2e42c0, 0x7bb4fbdb), TOBN(0xcfb4879a, 0x7035385c), + TOBN(0x8c3dd30b, 0x3281705b), TOBN(0x7e361c6c, 0x404fe081), + TOBN(0x7b21649c, 0x3f604edf), TOBN(0x5dbf6a3f, 0xe52ffe47), + TOBN(0xc41b7c23, 0x4b54d9bf), TOBN(0x1374e681, 0x3511c3d9), + TOBN(0x1863bf16, 0xc1b2b758), TOBN(0x90e78507, 0x1e9e6a96), + TOBN(0xab4bf98d, 0x5d86f174), TOBN(0xd74e0bd3, 0x85e96fe4), + TOBN(0x8afde39f, 0xcac5d344), TOBN(0x90946dbc, 0xbd91b847), + TOBN(0xf5b42358, 0xfe1a838c), TOBN(0x05aae6c5, 0x620ac9d8), + TOBN(0x8e193bd8, 0xa1ce5a0b), TOBN(0x8f710571, 0x4dabfd72), + TOBN(0x8d8fdd48, 0x182caaac), TOBN(0x8c4aeefa, 0x040745cf), + TOBN(0x73c6c30a, 0xf3b93e6d), TOBN(0x991241f3, 0x16f42011), + TOBN(0xa0158eea, 0xe457a477), TOBN(0xd19857db, 0xee6ddc05), + TOBN(0xb3265224, 0x18c41671), TOBN(0x3ffdfc7e, 0x3c2c0d58), + TOBN(0x3a3a5254, 0x26ee7cda), TOBN(0x341b0869, 0xdf02c3a8), + TOBN(0xa023bf42, 0x723bbfc8), TOBN(0x3d15002a, 0x14452691)}, + {TOBN(0x5ef7324c, 0x85edfa30), TOBN(0x25976554, 0x87d4f3da), + TOBN(0x352f5bc0, 0xdcb50c86), TOBN(0x8f6927b0, 0x4832a96c), + TOBN(0xd08ee1ba, 0x55f2f94c), TOBN(0x6a996f99, 0x344b45fa), + TOBN(0xe133cb8d, 0xa8aa455d), TOBN(0x5d0721ec, 0x758dc1f7), + TOBN(0x6ba7a920, 0x79e5fb67), TOBN(0xe1331feb, 0x70aa725e), + TOBN(0x5080ccf5, 0x7df5d837), TOBN(0xe4cae01d, 0x7ff72e21), + TOBN(0xd9243ee6, 0x0412a77d), TOBN(0x06ff7cac, 0xdf449025), + TOBN(0xbe75f7cd, 0x23ef5a31), TOBN(0xbc957822, 0x0ddef7a8), + TOBN(0x8cf7230c, 0xb0ce1c55), TOBN(0x5b534d05, 0x0bbfb607), + TOBN(0xee1ef113, 0x0e16363b), TOBN(0x27e0aa7a, 0xb4999e82), + TOBN(0xce1dac2d, 0x79362c41), TOBN(0x67920c90, 0x91bb6cb0), + TOBN(0x1e648d63, 0x2223df24), TOBN(0x0f7d9eef, 0xe32e8f28), + TOBN(0x6943f39a, 0xfa833834), TOBN(0x22951722, 0xa6328562), + TOBN(0x81d63dd5, 0x4170fc10), TOBN(0x9f5fa58f, 0xaecc2e6d), + TOBN(0xb66c8725, 0xe77d9a3b), TOBN(0x11235cea, 0x6384ebe0), + TOBN(0x06a8c118, 0x5845e24a), TOBN(0x0137b286, 0xebd093b1), + TOBN(0xc589e1ce, 0x44ace150), TOBN(0xe0f8d3d9, 0x4381e97c), + TOBN(0x59e99b11, 0x62c5a4b8), TOBN(0x90d262f7, 0xfd0ec9f9), + TOBN(0xfbc854c9, 0x283e13c9), TOBN(0x2d04fde7, 0xaedc7085), + TOBN(0x057d7765, 0x47dcbecb), TOBN(0x8dbdf591, 0x9a76fa5f), + TOBN(0xd0150695, 0x0de1e578), TOBN(0x2e1463e7, 0xe9f72bc6), + TOBN(0xffa68441, 0x1b39eca5), TOBN(0x673c8530, 0x7c037f2f), + TOBN(0xd0d6a600, 0x747f91da), TOBN(0xb08d43e1, 0xc9cb78e9), + TOBN(0x0fc0c644, 0x27b5cef5), TOBN(0x5c1d160a, 0xa60a2fd6), + TOBN(0xf98cae53, 0x28c8e13b), TOBN(0x375f10c4, 0xb2eddcd1), + TOBN(0xd4eb8b7f, 0x5cce06ad), TOBN(0xb4669f45, 0x80a2e1ef), + TOBN(0xd593f9d0, 0x5bbd8699), TOBN(0x5528a4c9, 0xe7976d13), + TOBN(0x3923e095, 0x1c7e28d3), TOBN(0xb9293790, 0x3f6bb577), + TOBN(0xdb567d6a, 0xc42bd6d2), TOBN(0x6df86468, 0xbb1f96ae), + TOBN(0x0efe5b1a, 0x4843b28e), TOBN(0x961bbb05, 0x6379b240), + TOBN(0xb6caf5f0, 0x70a6a26b), TOBN(0x70686c0d, 0x328e6e39), + TOBN(0x80da06cf, 0x895fc8d3), TOBN(0x804d8810, 0xb363fdc9), + TOBN(0xbe22877b, 0x207f1670), TOBN(0x9b0dd188, 0x4e615291), + TOBN(0x625ae8dc, 0x97a3c2bf), TOBN(0x08584ef7, 0x439b86e8), + TOBN(0xde7190a5, 0xdcd898ff), TOBN(0x26286c40, 0x2058ee3d), + TOBN(0x3db0b217, 0x5f87b1c1), TOBN(0xcc334771, 0x102a6db5), + TOBN(0xd99de954, 0x2f770fb1), TOBN(0x97c1c620, 0x4cd7535e), + TOBN(0xd3b6c448, 0x3f09cefc), TOBN(0xd725af15, 0x5a63b4f8), + TOBN(0x0c95d24f, 0xc01e20ec), TOBN(0xdfd37494, 0x9ae7121f), + TOBN(0x7d6ddb72, 0xec77b7ec), TOBN(0xfe079d3b, 0x0353a4ae), + TOBN(0x3066e70a, 0x2e6ac8d2), TOBN(0x9c6b5a43, 0x106e5c05), + TOBN(0x52d3c6f5, 0xede59b8c), TOBN(0x30d6a5c3, 0xfccec9ae), + TOBN(0xedec7c22, 0x4fc0a9ef), TOBN(0x190ff083, 0x95c16ced), + TOBN(0xbe12ec8f, 0x94de0fde), TOBN(0x0d131ab8, 0x852d3433), + TOBN(0x42ace07e, 0x85701291), TOBN(0x94793ed9, 0x194061a8), + TOBN(0x30e83ed6, 0xd7f4a485), TOBN(0x9eec7269, 0xf9eeff4d), + TOBN(0x90acba59, 0x0c9d8005), TOBN(0x5feca458, 0x1e79b9d1), + TOBN(0x8fbe5427, 0x1d506a1e), TOBN(0xa32b2c8e, 0x2439cfa7), + TOBN(0x1671c173, 0x73dd0b4e), TOBN(0x37a28214, 0x44a054c6), + TOBN(0x81760a1b, 0x4e8b53f1), TOBN(0xa6c04224, 0xf9f93b9e), + TOBN(0x18784b34, 0xcf671e3c), TOBN(0x81bbecd2, 0xcda9b994), + TOBN(0x38831979, 0xb2ab3848), TOBN(0xef54feb7, 0xf2e03c2d), + TOBN(0xcf197ca7, 0xfb8088fa), TOBN(0x01427247, 0x4ddc96c5), + TOBN(0xa2d2550a, 0x30777176), TOBN(0x53469898, 0x4d0cf71d), + TOBN(0x6ce937b8, 0x3a2aaac6), TOBN(0xe9f91dc3, 0x5af38d9b), + TOBN(0x2598ad83, 0xc8bf2899), TOBN(0x8e706ac9, 0xb5536c16), + TOBN(0x40dc7495, 0xf688dc98), TOBN(0x26490cd7, 0x124c4afc), + TOBN(0xe651ec84, 0x1f18775c), TOBN(0x393ea6c3, 0xb4fdaf4a), + TOBN(0x1e1f3343, 0x7f338e0d), TOBN(0x39fb832b, 0x6053e7b5), + TOBN(0x46e702da, 0x619e14d5), TOBN(0x859cacd1, 0xcdeef6e0), + TOBN(0x63b99ce7, 0x4462007d), TOBN(0xb8ab48a5, 0x4cb5f5b7), + TOBN(0x9ec673d2, 0xf55edde7), TOBN(0xd1567f74, 0x8cfaefda), + TOBN(0x46381b6b, 0x0887bcec), TOBN(0x694497ce, 0xe178f3c2), + TOBN(0x5e6525e3, 0x1e6266cb), TOBN(0x5931de26, 0x697d6413), + TOBN(0x87f8df7c, 0x0e58d493), TOBN(0xb1ae5ed0, 0x58b73f12), + TOBN(0xc368f784, 0xdea0c34d), TOBN(0x9bd0a120, 0x859a91a0), + TOBN(0xb00d88b7, 0xcc863c68), TOBN(0x3a1cc11e, 0x3d1f4d65), + TOBN(0xea38e0e7, 0x0aa85593), TOBN(0x37f13e98, 0x7dc4aee8), + TOBN(0x10d38667, 0xbc947bad), TOBN(0x738e07ce, 0x2a36ee2e), + TOBN(0xc93470cd, 0xc577fcac), TOBN(0xdee1b616, 0x2782470d), + TOBN(0x36a25e67, 0x2e793d12), TOBN(0xd6aa6cae, 0xe0f186da), + TOBN(0x474d0fd9, 0x80e07af7), TOBN(0xf7cdc47d, 0xba8a5cd4), + TOBN(0x28af6d9d, 0xab15247f), TOBN(0x7c789c10, 0x493a537f), + TOBN(0x7ac9b110, 0x23a334e7), TOBN(0x0236ac09, 0x12c9c277), + TOBN(0xa7e5bd25, 0x1d7a5144), TOBN(0x098b9c2a, 0xf13ec4ec), + TOBN(0x3639daca, 0xd3f0abca), TOBN(0x642da81a, 0xa23960f9), + TOBN(0x7d2e5c05, 0x4f7269b1), TOBN(0xfcf30777, 0xe287c385), + TOBN(0x10edc84f, 0xf2a46f21), TOBN(0x35441757, 0x4f43fa36), + TOBN(0xf1327899, 0xfd703431), TOBN(0xa438d7a6, 0x16dd587a), + TOBN(0x65c34c57, 0xe9c8352d), TOBN(0xa728edab, 0x5cc5a24e), + TOBN(0xaed78abc, 0x42531689), TOBN(0x0a51a0e8, 0x010963ef), + TOBN(0x5776fa0a, 0xd717d9b3), TOBN(0xf356c239, 0x7dd3428b), + TOBN(0x29903fff, 0x8d3a3dac), TOBN(0x409597fa, 0x3d94491f), + TOBN(0x4cd7a5ff, 0xbf4a56a4), TOBN(0xe5096474, 0x8adab462), + TOBN(0xa97b5126, 0x5c3427b0), TOBN(0x6401405c, 0xd282c9bd), + TOBN(0x3629f8d7, 0x222c5c45), TOBN(0xb1c02c16, 0xe8d50aed), + TOBN(0xbea2ed75, 0xd9635bc9), TOBN(0x226790c7, 0x6e24552f), + TOBN(0x3c33f2a3, 0x65f1d066), TOBN(0x2a43463e, 0x6dfccc2e), + TOBN(0x8cc3453a, 0xdb483761), TOBN(0xe7cc6085, 0x65d5672b), + TOBN(0x277ed6cb, 0xde3efc87), TOBN(0x19f2f368, 0x69234eaf), + TOBN(0x9aaf4317, 0x5c0b800b), TOBN(0x1f1e7c89, 0x8b6da6e2), + TOBN(0x6cfb4715, 0xb94ec75e), TOBN(0xd590dd5f, 0x453118c2), + TOBN(0x14e49da1, 0x1f17a34c), TOBN(0x5420ab39, 0x235a1456), + TOBN(0xb7637241, 0x2f50363b), TOBN(0x7b15d623, 0xc3fabb6e), + TOBN(0xa0ef40b1, 0xe274e49c), TOBN(0x5cf50744, 0x96b1860a), + TOBN(0xd6583fbf, 0x66afe5a4), TOBN(0x44240510, 0xf47e3e9a), + TOBN(0x99254343, 0x11b2d595), TOBN(0xf1367499, 0xeec8df57), + TOBN(0x3cb12c61, 0x3e73dd05), TOBN(0xd248c033, 0x7dac102a), + TOBN(0xcf154f13, 0xa77739f5), TOBN(0xbf4288cb, 0x23d2af42), + TOBN(0xaa64c9b6, 0x32e4a1cf), TOBN(0xee8c07a8, 0xc8a208f3), + TOBN(0xe10d4999, 0x6fe8393f), TOBN(0x0f809a3f, 0xe91f3a32), + TOBN(0x61096d1c, 0x802f63c8), TOBN(0x289e1462, 0x57750d3d), + TOBN(0xed06167e, 0x9889feea), TOBN(0xd5c9c0e2, 0xe0993909), + TOBN(0x46fca0d8, 0x56508ac6), TOBN(0x91826047, 0x4f1b8e83), + TOBN(0x4f2c877a, 0x9a4a2751), TOBN(0x71bd0072, 0xcae6fead), + TOBN(0x38df8dcc, 0x06aa1941), TOBN(0x5a074b4c, 0x63beeaa8), + TOBN(0xd6d65934, 0xc1cec8ed), TOBN(0xa6ecb49e, 0xaabc03bd), + TOBN(0xaade91c2, 0xde8a8415), TOBN(0xcfb0efdf, 0x691136e0), + TOBN(0x11af45ee, 0x23ab3495), TOBN(0xa132df88, 0x0b77463d), + TOBN(0x8923c15c, 0x815d06f4), TOBN(0xc3ceb3f5, 0x0d61a436), + TOBN(0xaf52291d, 0xe88fb1da), TOBN(0xea057974, 0x1da12179), + TOBN(0xb0d7218c, 0xd2fef720), TOBN(0x6c0899c9, 0x8e1d8845), + TOBN(0x98157504, 0x752ddad7), TOBN(0xd60bd74f, 0xa1a68a97), + TOBN(0x7047a3a9, 0xf658fb99), TOBN(0x1f5d86d6, 0x5f8511e4), + TOBN(0xb8a4bc42, 0x4b5a6d88), TOBN(0x69eb2c33, 0x1abefa7d), + TOBN(0x95bf39e8, 0x13c9c510), TOBN(0xf571960a, 0xd48aab43), + TOBN(0x7e8cfbcf, 0x704e23c6), TOBN(0xc71b7d22, 0x28aaa65b), + TOBN(0xa041b2bd, 0x245e3c83), TOBN(0x69b98834, 0xd21854ff), + TOBN(0x89d227a3, 0x963bfeec), TOBN(0x99947aaa, 0xde7da7cb), + TOBN(0x1d9ee9db, 0xee68a9b1), TOBN(0x0a08f003, 0x698ec368), + TOBN(0xe9ea4094, 0x78ef2487), TOBN(0xc8d2d415, 0x02cfec26), + TOBN(0xc52f9a6e, 0xb7dcf328), TOBN(0x0ed489e3, 0x85b6a937), + TOBN(0x9b94986b, 0xbef3366e), TOBN(0x0de59c70, 0xedddddb8), + TOBN(0xffdb748c, 0xeadddbe2), TOBN(0x9b9784bb, 0x8266ea40), + TOBN(0x142b5502, 0x1a93507a), TOBN(0xb4cd1187, 0x8d3c06cf), + TOBN(0xdf70e76a, 0x91ec3f40), TOBN(0x484e81ad, 0x4e7553c2), + TOBN(0x830f87b5, 0x272e9d6e), TOBN(0xea1c93e5, 0xc6ff514a), + TOBN(0x67cc2adc, 0xc4192a8e), TOBN(0xc77e27e2, 0x42f4535a), + TOBN(0x9cdbab36, 0xd2b713c5), TOBN(0x86274ea0, 0xcf7b0cd3), + TOBN(0x784680f3, 0x09af826b), TOBN(0xbfcc837a, 0x0c72dea3), + TOBN(0xa8bdfe9d, 0xd6529b73), TOBN(0x708aa228, 0x63a88002), + TOBN(0x6c7a9a54, 0xc91d45b9), TOBN(0xdf1a38bb, 0xfd004f56), + TOBN(0x2e8c9a26, 0xb8bad853), TOBN(0x2d52cea3, 0x3723eae7), + TOBN(0x054d6d81, 0x56ca2830), TOBN(0xa3317d14, 0x9a8dc411), + TOBN(0xa08662fe, 0xfd4ddeda), TOBN(0xed2a153a, 0xb55d792b), + TOBN(0x7035c16a, 0xbfc6e944), TOBN(0xb6bc5834, 0x00171cf3), + TOBN(0xe27152b3, 0x83d102b6), TOBN(0xfe695a47, 0x0646b848), + TOBN(0xa5bb09d8, 0x916e6d37), TOBN(0xb4269d64, 0x0d17015e), + TOBN(0x8d8156a1, 0x0a1d2285), TOBN(0xfeef6c51, 0x46d26d72), + TOBN(0x9dac57c8, 0x4c5434a7), TOBN(0x0282e5be, 0x59d39e31), + TOBN(0xedfff181, 0x721c486d), TOBN(0x301baf10, 0xbc58824e), + TOBN(0x8136a6aa, 0x00570031), TOBN(0x55aaf78c, 0x1cddde68), + TOBN(0x26829371, 0x59c63952), TOBN(0x3a3bd274, 0x8bc25baf), + TOBN(0xecdf8657, 0xb7e52dc3), TOBN(0x2dd8c087, 0xfd78e6c8), + TOBN(0x20553274, 0xf5531461), TOBN(0x8b4a1281, 0x5d95499b), + TOBN(0xe2c8763a, 0x1a80f9d2), TOBN(0xd1dbe32b, 0x4ddec758), + TOBN(0xaf12210d, 0x30c34169), TOBN(0xba74a953, 0x78baa533), + TOBN(0x3d133c6e, 0xa438f254), TOBN(0xa431531a, 0x201bef5b), + TOBN(0x15295e22, 0xf669d7ec), TOBN(0xca374f64, 0x357fb515), + TOBN(0x8a8406ff, 0xeaa3fdb3), TOBN(0x106ae448, 0xdf3f2da8), + TOBN(0x8f9b0a90, 0x33c8e9a1), TOBN(0x234645e2, 0x71ad5885), + TOBN(0x3d083224, 0x1c0aed14), TOBN(0xf10a7d3e, 0x7a942d46), + TOBN(0x7c11deee, 0x40d5c9be), TOBN(0xb2bae7ff, 0xba84ed98), + TOBN(0x93e97139, 0xaad58ddd), TOBN(0x3d872796, 0x3f6d1fa3), + TOBN(0x483aca81, 0x8569ff13), TOBN(0x8b89a5fb, 0x9a600f72), + TOBN(0x4cbc27c3, 0xc06f2b86), TOBN(0x22130713, 0x63ad9c0b), + TOBN(0xb5358b1e, 0x48ac2840), TOBN(0x18311294, 0xecba9477), + TOBN(0xda58f990, 0xa6946b43), TOBN(0x3098baf9, 0x9ab41819), + TOBN(0x66c4c158, 0x4198da52), TOBN(0xab4fc17c, 0x146bfd1b), + TOBN(0x2f0a4c3c, 0xbf36a908), TOBN(0x2ae9e34b, 0x58cf7838), + TOBN(0xf411529e, 0x3fa11b1f), TOBN(0x21e43677, 0x974af2b4), + TOBN(0x7c20958e, 0xc230793b), TOBN(0x710ea885, 0x16e840f3), + TOBN(0xfc0b21fc, 0xc5dc67cf), TOBN(0x08d51647, 0x88405718), + TOBN(0xd955c21f, 0xcfe49eb7), TOBN(0x9722a5d5, 0x56dd4a1f), + TOBN(0xc9ef50e2, 0xc861baa5), TOBN(0xc0c21a5d, 0x9505ac3e), + TOBN(0xaf6b9a33, 0x8b7c063f), TOBN(0xc6370339, 0x2f4779c1), + TOBN(0x22df99c7, 0x638167c3), TOBN(0xfe6ffe76, 0x795db30c), + TOBN(0x2b822d33, 0xa4854989), TOBN(0xfef031dd, 0x30563aa5), + TOBN(0x16b09f82, 0xd57c667f), TOBN(0xc70312ce, 0xcc0b76f1), + TOBN(0xbf04a9e6, 0xc9118aec), TOBN(0x82fcb419, 0x3409d133), + TOBN(0x1a8ab385, 0xab45d44d), TOBN(0xfba07222, 0x617b83a3), + TOBN(0xb05f50dd, 0x58e81b52), TOBN(0x1d8db553, 0x21ce5aff), + TOBN(0x3097b8d4, 0xe344a873), TOBN(0x7d8d116d, 0xfe36d53e), + TOBN(0x6db22f58, 0x7875e750), TOBN(0x2dc5e373, 0x43e144ea), + TOBN(0xc05f32e6, 0xe799eb95), TOBN(0xe9e5f4df, 0x6899e6ec), + TOBN(0xbdc3bd68, 0x1fab23d5), TOBN(0xb72b8ab7, 0x73af60e6), + TOBN(0x8db27ae0, 0x2cecc84a), TOBN(0x600016d8, 0x7bdb871c), + TOBN(0x42a44b13, 0xd7c46f58), TOBN(0xb8919727, 0xc3a77d39), + TOBN(0xcfc6bbbd, 0xdafd6088), TOBN(0x1a740146, 0x6bd20d39), + TOBN(0x8c747abd, 0x98c41072), TOBN(0x4c91e765, 0xbdf68ea1), + TOBN(0x7c95e5ca, 0x08819a78), TOBN(0xcf48b729, 0xc9587921), + TOBN(0x091c7c5f, 0xdebbcc7d), TOBN(0x6f287404, 0xf0e05149), + TOBN(0xf83b5ac2, 0x26cd44ec), TOBN(0x88ae32a6, 0xcfea250e), + TOBN(0x6ac5047a, 0x1d06ebc5), TOBN(0xc7e550b4, 0xd434f781), + TOBN(0x61ab1cf2, 0x5c727bd2), TOBN(0x2e4badb1, 0x1cf915b0), + TOBN(0x1b4dadec, 0xf69d3920), TOBN(0xe61b1ca6, 0xf14c1dfe), + TOBN(0x90b479cc, 0xbd6bd51f), TOBN(0x8024e401, 0x8045ec30), + TOBN(0xcab29ca3, 0x25ef0e62), TOBN(0x4f2e9416, 0x49e4ebc0), + TOBN(0x45eb40ec, 0x0ccced58), TOBN(0x25cd4b9c, 0x0da44f98), + TOBN(0x43e06458, 0x871812c6), TOBN(0x99f80d55, 0x16cef651), + TOBN(0x571340c9, 0xce6dc153), TOBN(0x138d5117, 0xd8665521), + TOBN(0xacdb45bc, 0x4e07014d), TOBN(0x2f34bb38, 0x84b60b91), + TOBN(0xf44a4fd2, 0x2ae8921e), TOBN(0xb039288e, 0x892ba1e2), + TOBN(0x9da50174, 0xb1c180b2), TOBN(0x6b70ab66, 0x1693dc87), + TOBN(0x7e9babc9, 0xe7057481), TOBN(0x4581ddef, 0x9c80dc41), + TOBN(0x0c890da9, 0x51294682), TOBN(0x0b5629d3, 0x3f4736e5), + TOBN(0x2340c79e, 0xb06f5b41), TOBN(0xa42e84ce, 0x4e243469), + TOBN(0xf9a20135, 0x045a71a9), TOBN(0xefbfb415, 0xd27b6fb6), + TOBN(0x25ebea23, 0x9d33cd6f), TOBN(0x9caedb88, 0xaa6c0af8), + TOBN(0x53dc7e9a, 0xd9ce6f96), TOBN(0x3897f9fd, 0x51e0b15a), + TOBN(0xf51cb1f8, 0x8e5d788e), TOBN(0x1aec7ba8, 0xe1d490ee), + TOBN(0x265991e0, 0xcc58cb3c), TOBN(0x9f306e8c, 0x9fc3ad31), + TOBN(0x5fed006e, 0x5040a0ac), TOBN(0xca9d5043, 0xfb476f2e), + TOBN(0xa19c06e8, 0xbeea7a23), TOBN(0xd2865801, 0x0edabb63), + TOBN(0xdb92293f, 0x6967469a), TOBN(0x2894d839, 0x8d8a8ed8), + TOBN(0x87c9e406, 0xbbc77122), TOBN(0x8671c6f1, 0x2ea3a26a), + TOBN(0xe42df8d6, 0xd7de9853), TOBN(0x2e3ce346, 0xb1f2bcc7), + TOBN(0xda601dfc, 0x899d50cf), TOBN(0xbfc913de, 0xfb1b598f), + TOBN(0x81c4909f, 0xe61f7908), TOBN(0x192e304f, 0x9bbc7b29), + TOBN(0xc3ed8738, 0xc104b338), TOBN(0xedbe9e47, 0x783f5d61), + TOBN(0x0c06e9be, 0x2db30660), TOBN(0xda3e613f, 0xc0eb7d8e), + TOBN(0xd8fa3e97, 0x322e096e), TOBN(0xfebd91e8, 0xd336e247), + TOBN(0x8f13ccc4, 0xdf655a49), TOBN(0xa9e00dfc, 0x5eb20210), + TOBN(0x84631d0f, 0xc656b6ea), TOBN(0x93a058cd, 0xd8c0d947), + TOBN(0x6846904a, 0x67bd3448), TOBN(0x4a3d4e1a, 0xf394fd5c), + TOBN(0xc102c1a5, 0xdb225f52), TOBN(0xe3455bba, 0xfc4f5e9a), + TOBN(0x6b36985b, 0x4b9ad1ce), TOBN(0xa9818536, 0x5bb7f793), + TOBN(0x6c25e1d0, 0x48b1a416), TOBN(0x1381dd53, 0x3c81bee7), + TOBN(0xd2a30d61, 0x7a4a7620), TOBN(0xc8412926, 0x39b8944c), + TOBN(0x3c1c6fbe, 0x7a97c33a), TOBN(0x941e541d, 0x938664e7), + TOBN(0x417499e8, 0x4a34f239), TOBN(0x15fdb83c, 0xb90402d5), + TOBN(0xb75f46bf, 0x433aa832), TOBN(0xb61e15af, 0x63215db1), + TOBN(0xaabe59d4, 0xa127f89a), TOBN(0x5d541e0c, 0x07e816da), + TOBN(0xaaba0659, 0xa618b692), TOBN(0x55327733, 0x17266026), + TOBN(0xaf53a0fc, 0x95f57552), TOBN(0x32947650, 0x6cacb0c9), + TOBN(0x253ff58d, 0xc821be01), TOBN(0xb0309531, 0xa06f1146), + TOBN(0x59bbbdf5, 0x05c2e54d), TOBN(0x158f27ad, 0x26e8dd22), + TOBN(0xcc5b7ffb, 0x397e1e53), TOBN(0xae03f65b, 0x7fc1e50d), + TOBN(0xa9784ebd, 0x9c95f0f9), TOBN(0x5ed9deb2, 0x24640771), + TOBN(0x31244af7, 0x035561c4), TOBN(0x87332f3a, 0x7ee857de), + TOBN(0x09e16e9e, 0x2b9e0d88), TOBN(0x52d910f4, 0x56a06049), + TOBN(0x507ed477, 0xa9592f48), TOBN(0x85cb917b, 0x2365d678), + TOBN(0xf8511c93, 0x4c8998d1), TOBN(0x2186a3f1, 0x730ea58f), + TOBN(0x50189626, 0xb2029db0), TOBN(0x9137a6d9, 0x02ceb75a), + TOBN(0x2fe17f37, 0x748bc82c), TOBN(0x87c2e931, 0x80469f8c), + TOBN(0x850f71cd, 0xbf891aa2), TOBN(0x0ca1b89b, 0x75ec3d8d), + TOBN(0x516c43aa, 0x5e1cd3cd), TOBN(0x89397808, 0x9a887c28), + TOBN(0x0059c699, 0xddea1f9f), TOBN(0x7737d6fa, 0x8e6868f7), + TOBN(0x6d93746a, 0x60f1524b), TOBN(0x36985e55, 0xba052aa7), + TOBN(0x41b1d322, 0xed923ea5), TOBN(0x3429759f, 0x25852a11), + TOBN(0xbeca6ec3, 0x092e9f41), TOBN(0x3a238c66, 0x62256bbd), + TOBN(0xd82958ea, 0x70ad487d), TOBN(0x4ac8aaf9, 0x65610d93), + TOBN(0x3fa101b1, 0x5e4ccab0), TOBN(0x9bf430f2, 0x9de14bfb), + TOBN(0xa10f5cc6, 0x6531899d), TOBN(0x590005fb, 0xea8ce17d), + TOBN(0xc437912f, 0x24544cb6), TOBN(0x9987b71a, 0xd79ac2e3), + TOBN(0x13e3d9dd, 0xc058a212), TOBN(0x00075aac, 0xd2de9606), + TOBN(0x80ab508b, 0x6cac8369), TOBN(0x87842be7, 0xf54f6c89), + TOBN(0xa7ad663d, 0x6bc532a4), TOBN(0x67813de7, 0x78a91bc8), + TOBN(0x5dcb61ce, 0xc3427239), TOBN(0x5f3c7cf0, 0xc56934d9), + TOBN(0xc079e0fb, 0xe3191591), TOBN(0xe40896bd, 0xb01aada7), + TOBN(0x8d466791, 0x0492d25f), TOBN(0x8aeb30c9, 0xe7408276), + TOBN(0xe9437495, 0x9287aacc), TOBN(0x23d4708d, 0x79fe03d4), + TOBN(0x8cda9cf2, 0xd0c05199), TOBN(0x502fbc22, 0xfae78454), + TOBN(0xc0bda9df, 0xf572a182), TOBN(0x5f9b71b8, 0x6158b372), + TOBN(0xe0f33a59, 0x2b82dd07), TOBN(0x76302735, 0x9523032e), + TOBN(0x7fe1a721, 0xc4505a32), TOBN(0x7b6e3e82, 0xf796409f)}, + {TOBN(0xe3417bc0, 0x35d0b34a), TOBN(0x440b386b, 0x8327c0a7), + TOBN(0x8fb7262d, 0xac0362d1), TOBN(0x2c41114c, 0xe0cdf943), + TOBN(0x2ba5cef1, 0xad95a0b1), TOBN(0xc09b37a8, 0x67d54362), + TOBN(0x26d6cdd2, 0x01e486c9), TOBN(0x20477abf, 0x42ff9297), + TOBN(0xa004dcb3, 0x292a9287), TOBN(0xddc15cf6, 0x77b092c7), + TOBN(0x083a8464, 0x806c0605), TOBN(0x4a68df70, 0x3db997b0), + TOBN(0x9c134e45, 0x05bf7dd0), TOBN(0xa4e63d39, 0x8ccf7f8c), + TOBN(0xa6e6517f, 0x41b5f8af), TOBN(0xaa8b9342, 0xad7bc1cc), + TOBN(0x126f35b5, 0x1e706ad9), TOBN(0xb99cebb4, 0xc3a9ebdf), + TOBN(0xa75389af, 0xbf608d90), TOBN(0x76113c4f, 0xc6c89858), + TOBN(0x80de8eb0, 0x97e2b5aa), TOBN(0x7e1022cc, 0x63b91304), + TOBN(0x3bdab605, 0x6ccc066c), TOBN(0x33cbb144, 0xb2edf900), + TOBN(0xc4176471, 0x7af715d2), TOBN(0xe2f7f594, 0xd0134a96), + TOBN(0x2c1873ef, 0xa41ec956), TOBN(0xe4e7b4f6, 0x77821304), + TOBN(0xe5c8ff97, 0x88d5374a), TOBN(0x2b915e63, 0x80823d5b), + TOBN(0xea6bc755, 0xb2ee8fe2), TOBN(0x6657624c, 0xe7112651), + TOBN(0x157af101, 0xdace5aca), TOBN(0xc4fdbcf2, 0x11a6a267), + TOBN(0xdaddf340, 0xc49c8609), TOBN(0x97e49f52, 0xe9604a65), + TOBN(0x9be8e790, 0x937e2ad5), TOBN(0x846e2508, 0x326e17f1), + TOBN(0x3f38007a, 0x0bbbc0dc), TOBN(0xcf03603f, 0xb11e16d6), + TOBN(0xd6f800e0, 0x7442f1d5), TOBN(0x475607d1, 0x66e0e3ab), + TOBN(0x82807f16, 0xb7c64047), TOBN(0x8858e1e3, 0xa749883d), + TOBN(0x5859120b, 0x8231ee10), TOBN(0x1b80e7eb, 0x638a1ece), + TOBN(0xcb72525a, 0xc6aa73a4), TOBN(0xa7cdea3d, 0x844423ac), + TOBN(0x5ed0c007, 0xf8ae7c38), TOBN(0x6db07a5c, 0x3d740192), + TOBN(0xbe5e9c2a, 0x5fe36db3), TOBN(0xd5b9d57a, 0x76e95046), + TOBN(0x54ac32e7, 0x8eba20f2), TOBN(0xef11ca8f, 0x71b9a352), + TOBN(0x305e373e, 0xff98a658), TOBN(0xffe5a100, 0x823eb667), + TOBN(0x57477b11, 0xe51732d2), TOBN(0xdfd6eb28, 0x2538fc0e), + TOBN(0x5c43b0cc, 0x3b39eec5), TOBN(0x6af12778, 0xcb36cc57), + TOBN(0x70b0852d, 0x06c425ae), TOBN(0x6df92f8c, 0x5c221b9b), + TOBN(0x6c8d4f9e, 0xce826d9c), TOBN(0xf59aba7b, 0xb49359c3), + TOBN(0x5c8ed8d5, 0xda64309d), TOBN(0x61a6de56, 0x91b30704), + TOBN(0xd6b52f6a, 0x2f9b5808), TOBN(0x0eee4194, 0x98c958a7), + TOBN(0xcddd9aab, 0x771e4caa), TOBN(0x83965dfd, 0x78bc21be), + TOBN(0x02affce3, 0xb3b504f5), TOBN(0x30847a21, 0x561c8291), + TOBN(0xd2eb2cf1, 0x52bfda05), TOBN(0xe0e4c4e9, 0x6197b98c), + TOBN(0x1d35076c, 0xf8a1726f), TOBN(0x6c06085b, 0x2db11e3d), + TOBN(0x15c0c4d7, 0x4463ba14), TOBN(0x9d292f83, 0x0030238c), + TOBN(0x1311ee8b, 0x3727536d), TOBN(0xfeea86ef, 0xbeaedc1e), + TOBN(0xb9d18cd3, 0x66131e2e), TOBN(0xf31d974f, 0x80fe2682), + TOBN(0xb6e49e0f, 0xe4160289), TOBN(0x7c48ec0b, 0x08e92799), + TOBN(0x818111d8, 0xd1989aa7), TOBN(0xb34fa0aa, 0xebf926f9), + TOBN(0xdb5fe2f5, 0xa245474a), TOBN(0xf80a6ebb, 0x3c7ca756), + TOBN(0xa7f96054, 0xafa05dd8), TOBN(0x26dfcf21, 0xfcaf119e), + TOBN(0xe20ef2e3, 0x0564bb59), TOBN(0xef4dca50, 0x61cb02b8), + TOBN(0xcda7838a, 0x65d30672), TOBN(0x8b08d534, 0xfd657e86), + TOBN(0x4c5b4395, 0x46d595c8), TOBN(0x39b58725, 0x425cb836), + TOBN(0x8ea61059, 0x3de9abe3), TOBN(0x40434881, 0x9cdc03be), + TOBN(0x9b261245, 0xcfedce8c), TOBN(0x78c318b4, 0xcf5234a1), + TOBN(0x510bcf16, 0xfde24c99), TOBN(0x2a77cb75, 0xa2c2ff5d), + TOBN(0x9c895c2b, 0x27960fb4), TOBN(0xd30ce975, 0xb0eda42b), + TOBN(0xfda85393, 0x1a62cc26), TOBN(0x23c69b96, 0x50c0e052), + TOBN(0xa227df15, 0xbfc633f3), TOBN(0x2ac78848, 0x1bae7d48), + TOBN(0x487878f9, 0x187d073d), TOBN(0x6c2be919, 0x967f807d), + TOBN(0x765861d8, 0x336e6d8f), TOBN(0x88b8974c, 0xce528a43), + TOBN(0x09521177, 0xff57d051), TOBN(0x2ff38037, 0xfb6a1961), + TOBN(0xfc0aba74, 0xa3d76ad4), TOBN(0x7c764803, 0x25a7ec17), + TOBN(0x7532d75f, 0x48879bc8), TOBN(0xea7eacc0, 0x58ce6bc1), + TOBN(0xc82176b4, 0x8e896c16), TOBN(0x9a30e0b2, 0x2c750fed), + TOBN(0xc37e2c2e, 0x421d3aa4), TOBN(0xf926407c, 0xe84fa840), + TOBN(0x18abc03d, 0x1454e41c), TOBN(0x26605ecd, 0x3f7af644), + TOBN(0x242341a6, 0xd6a5eabf), TOBN(0x1edb84f4, 0x216b668e), + TOBN(0xd836edb8, 0x04010102), TOBN(0x5b337ce7, 0x945e1d8c), + TOBN(0xd2075c77, 0xc055dc14), TOBN(0x2a0ffa25, 0x81d89cdf), + TOBN(0x8ce815ea, 0x6ffdcbaf), TOBN(0xa3428878, 0xfb648867), + TOBN(0x277699cf, 0x884655fb), TOBN(0xfa5b5bd6, 0x364d3e41), + TOBN(0x01f680c6, 0x441e1cb7), TOBN(0x3fd61e66, 0xb70a7d67), + TOBN(0x666ba2dc, 0xcc78cf66), TOBN(0xb3018174, 0x6fdbff77), + TOBN(0x8d4dd0db, 0x168d4668), TOBN(0x259455d0, 0x1dab3a2a), + TOBN(0xf58564c5, 0xcde3acec), TOBN(0x77141925, 0x13adb276), + TOBN(0x527d725d, 0x8a303f65), TOBN(0x55deb6c9, 0xe6f38f7b), + TOBN(0xfd5bb657, 0xb1fa70fb), TOBN(0xfa07f50f, 0xd8073a00), + TOBN(0xf72e3aa7, 0xbca02500), TOBN(0xf68f895d, 0x9975740d), + TOBN(0x30112060, 0x5cae2a6a), TOBN(0x01bd7218, 0x02874842), + TOBN(0x3d423891, 0x7ce47bd3), TOBN(0xa66663c1, 0x789544f6), + TOBN(0x864d05d7, 0x3272d838), TOBN(0xe22924f9, 0xfa6295c5), + TOBN(0x8189593f, 0x6c2fda32), TOBN(0x330d7189, 0xb184b544), + TOBN(0x79efa62c, 0xbde1f714), TOBN(0x35771c94, 0xe5cb1a63), + TOBN(0x2f4826b8, 0x641c8332), TOBN(0x00a894fb, 0xc8cee854), + TOBN(0xb4b9a39b, 0x36194d40), TOBN(0xe857a7c5, 0x77612601), + TOBN(0xf4209dd2, 0x4ecf2f58), TOBN(0x82b9e66d, 0x5a033487), + TOBN(0xc1e36934, 0xe4e8b9dd), TOBN(0xd2372c9d, 0xa42377d7), + TOBN(0x51dc94c7, 0x0e3ae43b), TOBN(0x4c57761e, 0x04474f6f), + TOBN(0xdcdacd0a, 0x1058a318), TOBN(0x369cf3f5, 0x78053a9a), + TOBN(0xc6c3de50, 0x31c68de2), TOBN(0x4653a576, 0x3c4b6d9f), + TOBN(0x1688dd5a, 0xaa4e5c97), TOBN(0x5be80aa1, 0xb7ab3c74), + TOBN(0x70cefe7c, 0xbc65c283), TOBN(0x57f95f13, 0x06867091), + TOBN(0xa39114e2, 0x4415503b), TOBN(0xc08ff7c6, 0x4cbb17e9), + TOBN(0x1eff674d, 0xd7dec966), TOBN(0x6d4690af, 0x53376f63), + TOBN(0xff6fe32e, 0xea74237b), TOBN(0xc436d17e, 0xcd57508e), + TOBN(0x15aa28e1, 0xedcc40fe), TOBN(0x0d769c04, 0x581bbb44), + TOBN(0xc240b6de, 0x34eaacda), TOBN(0xd9e116e8, 0x2ba0f1de), + TOBN(0xcbe45ec7, 0x79438e55), TOBN(0x91787c9d, 0x96f752d7), + TOBN(0x897f532b, 0xf129ac2f), TOBN(0xd307b7c8, 0x5a36e22c), + TOBN(0x91940675, 0x749fb8f3), TOBN(0xd14f95d0, 0x157fdb28), + TOBN(0xfe51d029, 0x6ae55043), TOBN(0x8931e98f, 0x44a87de1), + TOBN(0xe57f1cc6, 0x09e4fee2), TOBN(0x0d063b67, 0x4e072d92), + TOBN(0x70a998b9, 0xed0e4316), TOBN(0xe74a736b, 0x306aca46), + TOBN(0xecf0fbf2, 0x4fda97c7), TOBN(0xa40f65cb, 0x3e178d93), + TOBN(0x16253604, 0x16df4285), TOBN(0xb0c9babb, 0xd0c56ae2), + TOBN(0x73032b19, 0xcfc5cfc3), TOBN(0xe497e5c3, 0x09752056), + TOBN(0x12096bb4, 0x164bda96), TOBN(0x1ee42419, 0xa0b74da1), + TOBN(0x8fc36243, 0x403826ba), TOBN(0x0c8f0069, 0xdc09e660), + TOBN(0x8667e981, 0xc27253c9), TOBN(0x05a6aefb, 0x92b36a45), + TOBN(0xa62c4b36, 0x9cb7bb46), TOBN(0x8394f375, 0x11f7027b), + TOBN(0x747bc79c, 0x5f109d0f), TOBN(0xcad88a76, 0x5b8cc60a), + TOBN(0x80c5a66b, 0x58f09e68), TOBN(0xe753d451, 0xf6127eac), + TOBN(0xc44b74a1, 0x5b0ec6f5), TOBN(0x47989fe4, 0x5289b2b8), + TOBN(0x745f8484, 0x58d6fc73), TOBN(0xec362a6f, 0xf61c70ab), + TOBN(0x070c98a7, 0xb3a8ad41), TOBN(0x73a20fc0, 0x7b63db51), + TOBN(0xed2c2173, 0xf44c35f4), TOBN(0x8a56149d, 0x9acc9dca), + TOBN(0x98f17881, 0x9ac6e0f4), TOBN(0x360fdeaf, 0xa413b5ed), + TOBN(0x0625b8f4, 0xa300b0fd), TOBN(0xf1f4d76a, 0x5b3222d3), + TOBN(0x9d6f5109, 0x587f76b8), TOBN(0x8b4ee08d, 0x2317fdb5), + TOBN(0x88089bb7, 0x8c68b095), TOBN(0x95570e9a, 0x5808d9b9), + TOBN(0xa395c36f, 0x35d33ae7), TOBN(0x200ea123, 0x50bb5a94), + TOBN(0x20c789bd, 0x0bafe84b), TOBN(0x243ef52d, 0x0919276a), + TOBN(0x3934c577, 0xe23ae233), TOBN(0xb93807af, 0xa460d1ec), + TOBN(0xb72a53b1, 0xf8fa76a4), TOBN(0xd8914cb0, 0xc3ca4491), + TOBN(0x2e128494, 0x3fb42622), TOBN(0x3b2700ac, 0x500907d5), + TOBN(0xf370fb09, 0x1a95ec63), TOBN(0xf8f30be2, 0x31b6dfbd), + TOBN(0xf2b2f8d2, 0x69e55f15), TOBN(0x1fead851, 0xcc1323e9), + TOBN(0xfa366010, 0xd9e5eef6), TOBN(0x64d487b0, 0xe316107e), + TOBN(0x4c076b86, 0xd23ddc82), TOBN(0x03fd344c, 0x7e0143f0), + TOBN(0xa95362ff, 0x317af2c5), TOBN(0x0add3db7, 0xe18b7a4f), + TOBN(0x9c673e3f, 0x8260e01b), TOBN(0xfbeb49e5, 0x54a1cc91), + TOBN(0x91351bf2, 0x92f2e433), TOBN(0xc755e7ec, 0x851141eb), + TOBN(0xc9a95139, 0x29607745), TOBN(0x0ca07420, 0xa26f2b28), + TOBN(0xcb2790e7, 0x4bc6f9dd), TOBN(0x345bbb58, 0xadcaffc0), + TOBN(0xc65ea38c, 0xbe0f27a2), TOBN(0x67c24d7c, 0x641fcb56), + TOBN(0x2c25f0a7, 0xa9e2c757), TOBN(0x93f5cdb0, 0x16f16c49), + TOBN(0x2ca5a9d7, 0xc5ee30a1), TOBN(0xd1593635, 0xb909b729), + TOBN(0x804ce9f3, 0xdadeff48), TOBN(0xec464751, 0xb07c30c3), + TOBN(0x89d65ff3, 0x9e49af6a), TOBN(0xf2d6238a, 0x6f3d01bc), + TOBN(0x1095561e, 0x0bced843), TOBN(0x51789e12, 0xc8a13fd8), + TOBN(0xd633f929, 0x763231df), TOBN(0x46df9f7d, 0xe7cbddef), + TOBN(0x01c889c0, 0xcb265da8), TOBN(0xfce1ad10, 0xaf4336d2), + TOBN(0x8d110df6, 0xfc6a0a7e), TOBN(0xdd431b98, 0x6da425dc), + TOBN(0xcdc4aeab, 0x1834aabe), TOBN(0x84deb124, 0x8439b7fc), + TOBN(0x8796f169, 0x3c2a5998), TOBN(0x9b9247b4, 0x7947190d), + TOBN(0x55b9d9a5, 0x11597014), TOBN(0x7e9dd70d, 0x7b1566ee), + TOBN(0x94ad78f7, 0xcbcd5e64), TOBN(0x0359ac17, 0x9bd4c032), + TOBN(0x3b11baaf, 0x7cc222ae), TOBN(0xa6a6e284, 0xba78e812), + TOBN(0x8392053f, 0x24cea1a0), TOBN(0xc97bce4a, 0x33621491), + TOBN(0x7eb1db34, 0x35399ee9), TOBN(0x473f78ef, 0xece81ad1), + TOBN(0x41d72fe0, 0xf63d3d0d), TOBN(0xe620b880, 0xafab62fc), + TOBN(0x92096bc9, 0x93158383), TOBN(0x41a21357, 0x8f896f6c), + TOBN(0x1b5ee2fa, 0xc7dcfcab), TOBN(0x650acfde, 0x9546e007), + TOBN(0xc081b749, 0xb1b02e07), TOBN(0xda9e41a0, 0xf9eca03d), + TOBN(0x013ba727, 0x175a54ab), TOBN(0xca0cd190, 0xea5d8d10), + TOBN(0x85ea52c0, 0x95fd96a9), TOBN(0x2c591b9f, 0xbc5c3940), + TOBN(0x6fb4d4e4, 0x2bad4d5f), TOBN(0xfa4c3590, 0xfef0059b), + TOBN(0x6a10218a, 0xf5122294), TOBN(0x9a78a81a, 0xa85751d1), + TOBN(0x04f20579, 0xa98e84e7), TOBN(0xfe1242c0, 0x4997e5b5), + TOBN(0xe77a273b, 0xca21e1e4), TOBN(0xfcc8b1ef, 0x9411939d), + TOBN(0xe20ea302, 0x92d0487a), TOBN(0x1442dbec, 0x294b91fe), + TOBN(0x1f7a4afe, 0xbb6b0e8f), TOBN(0x1700ef74, 0x6889c318), + TOBN(0xf5bbffc3, 0x70f1fc62), TOBN(0x3b31d4b6, 0x69c79cca), + TOBN(0xe8bc2aab, 0xa7f6340d), TOBN(0xb0b08ab4, 0xa725e10a), + TOBN(0x44f05701, 0xae340050), TOBN(0xba4b3016, 0x1cf0c569), + TOBN(0x5aa29f83, 0xfbe19a51), TOBN(0x1b9ed428, 0xb71d752e), + TOBN(0x1666e54e, 0xeb4819f5), TOBN(0x616cdfed, 0x9e18b75b), + TOBN(0x112ed5be, 0x3ee27b0b), TOBN(0xfbf28319, 0x44c7de4d), + TOBN(0xd685ec85, 0xe0e60d84), TOBN(0x68037e30, 0x1db7ee78), + TOBN(0x5b65bdcd, 0x003c4d6e), TOBN(0x33e7363a, 0x93e29a6a), + TOBN(0x995b3a61, 0x08d0756c), TOBN(0xd727f85c, 0x2faf134b), + TOBN(0xfac6edf7, 0x1d337823), TOBN(0x99b9aa50, 0x0439b8b4), + TOBN(0x722eb104, 0xe2b4e075), TOBN(0x49987295, 0x437c4926), + TOBN(0xb1e4c0e4, 0x46a9b82d), TOBN(0xd0cb3197, 0x57a006f5), + TOBN(0xf3de0f7d, 0xd7808c56), TOBN(0xb5c54d8f, 0x51f89772), + TOBN(0x500a114a, 0xadbd31aa), TOBN(0x9afaaaa6, 0x295f6cab), + TOBN(0x94705e21, 0x04cf667a), TOBN(0xfc2a811b, 0x9d3935d7), + TOBN(0x560b0280, 0x6d09267c), TOBN(0xf19ed119, 0xf780e53b), + TOBN(0xf0227c09, 0x067b6269), TOBN(0x967b8533, 0x5caef599), + TOBN(0x155b9243, 0x68efeebc), TOBN(0xcd6d34f5, 0xc497bae6), + TOBN(0x1dd8d5d3, 0x6cceb370), TOBN(0x2aeac579, 0xa78d7bf9), + TOBN(0x5d65017d, 0x70b67a62), TOBN(0x70c8e44f, 0x17c53f67), + TOBN(0xd1fc0950, 0x86a34d09), TOBN(0xe0fca256, 0xe7134907), + TOBN(0xe24fa29c, 0x80fdd315), TOBN(0x2c4acd03, 0xd87499ad), + TOBN(0xbaaf7517, 0x3b5a9ba6), TOBN(0xb9cbe1f6, 0x12e51a51), + TOBN(0xd88edae3, 0x5e154897), TOBN(0xe4309c3c, 0x77b66ca0), + TOBN(0xf5555805, 0xf67f3746), TOBN(0x85fc37ba, 0xa36401ff), + TOBN(0xdf86e2ca, 0xd9499a53), TOBN(0x6270b2a3, 0xecbc955b), + TOBN(0xafae64f5, 0x974ad33b), TOBN(0x04d85977, 0xfe7b2df1), + TOBN(0x2a3db3ff, 0x4ab03f73), TOBN(0x0b87878a, 0x8702740a), + TOBN(0x6d263f01, 0x5a061732), TOBN(0xc25430ce, 0xa32a1901), + TOBN(0xf7ebab3d, 0xdb155018), TOBN(0x3a86f693, 0x63a9b78e), + TOBN(0x349ae368, 0xda9f3804), TOBN(0x470f07fe, 0xa164349c), + TOBN(0xd52f4cc9, 0x8562baa5), TOBN(0xc74a9e86, 0x2b290df3), + TOBN(0xd3a1aa35, 0x43471a24), TOBN(0x239446be, 0xb8194511), + TOBN(0xbec2dd00, 0x81dcd44d), TOBN(0xca3d7f0f, 0xc42ac82d), + TOBN(0x1f3db085, 0xfdaf4520), TOBN(0xbb6d3e80, 0x4549daf2), + TOBN(0xf5969d8a, 0x19ad5c42), TOBN(0x7052b13d, 0xdbfd1511), + TOBN(0x11890d1b, 0x682b9060), TOBN(0xa71d3883, 0xac34452c), + TOBN(0xa438055b, 0x783805b4), TOBN(0x43241277, 0x4725b23e), + TOBN(0xf20cf96e, 0x4901bbed), TOBN(0x6419c710, 0xf432a2bb), + TOBN(0x57a0fbb9, 0xdfa9cd7d), TOBN(0x589111e4, 0x00daa249), + TOBN(0x19809a33, 0x7b60554e), TOBN(0xea5f8887, 0xede283a4), + TOBN(0x2d713802, 0x503bfd35), TOBN(0x151bb0af, 0x585d2a53), + TOBN(0x40b08f74, 0x43b30ca8), TOBN(0xe10b5bba, 0xd9934583), + TOBN(0xe8a546d6, 0xb51110ad), TOBN(0x1dd50e66, 0x28e0b6c5), + TOBN(0x292e9d54, 0xcff2b821), TOBN(0x3882555d, 0x47281760), + TOBN(0x134838f8, 0x3724d6e3), TOBN(0xf2c679e0, 0x22ddcda1), + TOBN(0x40ee8815, 0x6d2a5768), TOBN(0x7f227bd2, 0x1c1e7e2d), + TOBN(0x487ba134, 0xd04ff443), TOBN(0x76e2ff3d, 0xc614e54b), + TOBN(0x36b88d6f, 0xa3177ec7), TOBN(0xbf731d51, 0x2328fff5), + TOBN(0x758caea2, 0x49ba158e), TOBN(0x5ab8ff4c, 0x02938188), + TOBN(0x33e16056, 0x35edc56d), TOBN(0x5a69d349, 0x7e940d79), + TOBN(0x6c4fd001, 0x03866dcb), TOBN(0x20a38f57, 0x4893cdef), + TOBN(0xfbf3e790, 0xfac3a15b), TOBN(0x6ed7ea2e, 0x7a4f8e6b), + TOBN(0xa663eb4f, 0xbc3aca86), TOBN(0x22061ea5, 0x080d53f7), + TOBN(0x2480dfe6, 0xf546783f), TOBN(0xd38bc6da, 0x5a0a641e), + TOBN(0xfb093cd1, 0x2ede8965), TOBN(0x89654db4, 0xacb455cf), + TOBN(0x413cbf9a, 0x26e1adee), TOBN(0x291f3764, 0x373294d4), + TOBN(0x00797257, 0x648083fe), TOBN(0x25f504d3, 0x208cc341), + TOBN(0x635a8e5e, 0xc3a0ee43), TOBN(0x70aaebca, 0x679898ff), + TOBN(0x9ee9f547, 0x5dc63d56), TOBN(0xce987966, 0xffb34d00), + TOBN(0xf9f86b19, 0x5e26310a), TOBN(0x9e435484, 0x382a8ca8), + TOBN(0x253bcb81, 0xc2352fe4), TOBN(0xa4eac8b0, 0x4474b571), + TOBN(0xc1b97512, 0xc1ad8cf8), TOBN(0x193b4e9e, 0x99e0b697), + TOBN(0x939d2716, 0x01e85df0), TOBN(0x4fb265b3, 0xcd44eafd), + TOBN(0x321e7dcd, 0xe51e1ae2), TOBN(0x8e3a8ca6, 0xe3d8b096), + TOBN(0x8de46cb0, 0x52604998), TOBN(0x91099ad8, 0x39072aa7), + TOBN(0x2617f91c, 0x93aa96b8), TOBN(0x0fc8716b, 0x7fca2e13), + TOBN(0xa7106f5e, 0x95328723), TOBN(0xd1c9c40b, 0x262e6522), + TOBN(0xb9bafe86, 0x42b7c094), TOBN(0x1873439d, 0x1543c021), + TOBN(0xe1baa5de, 0x5cbefd5d), TOBN(0xa363fc5e, 0x521e8aff), + TOBN(0xefe6320d, 0xf862eaac), TOBN(0x14419c63, 0x22c647dc), + TOBN(0x0e06707c, 0x4e46d428), TOBN(0xcb6c834f, 0x4a178f8f), + TOBN(0x0f993a45, 0xd30f917c), TOBN(0xd4c4b049, 0x9879afee), + TOBN(0xb6142a1e, 0x70500063), TOBN(0x7c9b41c3, 0xa5d9d605), + TOBN(0xbc00fc2f, 0x2f8ba2c7), TOBN(0x0966eb2f, 0x7c67aa28), + TOBN(0x13f7b516, 0x5a786972), TOBN(0x3bfb7557, 0x8a2fbba0), + TOBN(0x131c4f23, 0x5a2b9620), TOBN(0xbff3ed27, 0x6faf46be), + TOBN(0x9b4473d1, 0x7e172323), TOBN(0x421e8878, 0x339f6246), + TOBN(0x0fa8587a, 0x25a41632), TOBN(0xc0814124, 0xa35b6c93), + TOBN(0x2b18a9f5, 0x59ebb8db), TOBN(0x264e3357, 0x76edb29c), + TOBN(0xaf245ccd, 0xc87c51e2), TOBN(0x16b3015b, 0x501e6214), + TOBN(0xbb31c560, 0x0a3882ce), TOBN(0x6961bb94, 0xfec11e04), + TOBN(0x3b825b8d, 0xeff7a3a0), TOBN(0xbec33738, 0xb1df7326), + TOBN(0x68ad747c, 0x99604a1f), TOBN(0xd154c934, 0x9a3bd499), + TOBN(0xac33506f, 0x1cc7a906), TOBN(0x73bb5392, 0x6c560e8f), + TOBN(0x6428fcbe, 0x263e3944), TOBN(0xc11828d5, 0x1c387434), + TOBN(0x3cd04be1, 0x3e4b12ff), TOBN(0xc3aad9f9, 0x2d88667c), + TOBN(0xc52ddcf8, 0x248120cf), TOBN(0x985a892e, 0x2a389532), + TOBN(0xfbb4b21b, 0x3bb85fa0), TOBN(0xf95375e0, 0x8dfc6269), + TOBN(0xfb4fb06c, 0x7ee2acea), TOBN(0x6785426e, 0x309c4d1f), + TOBN(0x659b17c8, 0xd8ceb147), TOBN(0x9b649eee, 0xb70a5554), + TOBN(0x6b7fa0b5, 0xac6bc634), TOBN(0xd99fe2c7, 0x1d6e732f), + TOBN(0x30e6e762, 0x8d3abba2), TOBN(0x18fee6e7, 0xa797b799), + TOBN(0x5c9d360d, 0xc696464d), TOBN(0xe3baeb48, 0x27bfde12), + TOBN(0x2bf5db47, 0xf23206d5), TOBN(0x2f6d3420, 0x1d260152), + TOBN(0x17b87653, 0x3f8ff89a), TOBN(0x5157c30c, 0x378fa458), + TOBN(0x7517c5c5, 0x2d4fb936), TOBN(0xef22f7ac, 0xe6518cdc), + TOBN(0xdeb483e6, 0xbf847a64), TOBN(0xf5084558, 0x92e0fa89)}, + {TOBN(0xab9659d8, 0xdf7304d4), TOBN(0xb71bcf1b, 0xff210e8e), + TOBN(0xa9a2438b, 0xd73fbd60), TOBN(0x4595cd1f, 0x5d11b4de), + TOBN(0x9c0d329a, 0x4835859d), TOBN(0x4a0f0d2d, 0x7dbb6e56), + TOBN(0xc6038e5e, 0xdf928a4e), TOBN(0xc9429621, 0x8f5ad154), + TOBN(0x91213462, 0xf23f2d92), TOBN(0x6cab71bd, 0x60b94078), + TOBN(0x6bdd0a63, 0x176cde20), TOBN(0x54c9b20c, 0xee4d54bc), + TOBN(0x3cd2d8aa, 0x9f2ac02f), TOBN(0x03f8e617, 0x206eedb0), + TOBN(0xc7f68e16, 0x93086434), TOBN(0x831469c5, 0x92dd3db9), + TOBN(0x8521df24, 0x8f981354), TOBN(0x587e23ec, 0x3588a259), + TOBN(0xcbedf281, 0xd7a0992c), TOBN(0x06930a55, 0x38961407), + TOBN(0x09320deb, 0xbe5bbe21), TOBN(0xa7ffa5b5, 0x2491817f), + TOBN(0xe6c8b4d9, 0x09065160), TOBN(0xac4f3992, 0xfff6d2a9), + TOBN(0x7aa7a158, 0x3ae9c1bd), TOBN(0xe0af6d98, 0xe37ce240), + TOBN(0xe54342d9, 0x28ab38b4), TOBN(0xe8b75007, 0x0a1c98ca), + TOBN(0xefce86af, 0xe02358f2), TOBN(0x31b8b856, 0xea921228), + TOBN(0x052a1912, 0x0a1c67fc), TOBN(0xb4069ea4, 0xe3aead59), + TOBN(0x3232d6e2, 0x7fa03cb3), TOBN(0xdb938e5b, 0x0fdd7d88), + TOBN(0x04c1d2cd, 0x2ccbfc5d), TOBN(0xd2f45c12, 0xaf3a580f), + TOBN(0x592620b5, 0x7883e614), TOBN(0x5fd27e68, 0xbe7c5f26), + TOBN(0x139e45a9, 0x1567e1e3), TOBN(0x2cc71d2d, 0x44d8aaaf), + TOBN(0x4a9090cd, 0xe36d0757), TOBN(0xf722d7b1, 0xd9a29382), + TOBN(0xfb7fb04c, 0x04b48ddf), TOBN(0x628ad2a7, 0xebe16f43), + TOBN(0xcd3fbfb5, 0x20226040), TOBN(0x6c34ecb1, 0x5104b6c4), + TOBN(0x30c0754e, 0xc903c188), TOBN(0xec336b08, 0x2d23cab0), + TOBN(0x473d62a2, 0x1e206ee5), TOBN(0xf1e27480, 0x8c49a633), + TOBN(0x87ab956c, 0xe9f6b2c3), TOBN(0x61830b48, 0x62b606ea), + TOBN(0x67cd6846, 0xe78e815f), TOBN(0xfe40139f, 0x4c02082a), + TOBN(0x52bbbfcb, 0x952ec365), TOBN(0x74c11642, 0x6b9836ab), + TOBN(0x9f51439e, 0x558df019), TOBN(0x230da4ba, 0xac712b27), + TOBN(0x518919e3, 0x55185a24), TOBN(0x4dcefcdd, 0x84b78f50), + TOBN(0xa7d90fb2, 0xa47d4c5a), TOBN(0x55ac9abf, 0xb30e009e), + TOBN(0xfd2fc359, 0x74eed273), TOBN(0xb72d824c, 0xdbea8faf), + TOBN(0xce721a74, 0x4513e2ca), TOBN(0x0b418612, 0x38240b2c), + TOBN(0x05199968, 0xd5baa450), TOBN(0xeb1757ed, 0x2b0e8c25), + TOBN(0x6ebc3e28, 0x3dfac6d5), TOBN(0xb2431e2e, 0x48a237f5), + TOBN(0x2acb5e23, 0x52f61499), TOBN(0x5558a2a7, 0xe06c936b), + TOBN(0xd213f923, 0xcbb13d1b), TOBN(0x98799f42, 0x5bfb9bfe), + TOBN(0x1ae8ddc9, 0x701144a9), TOBN(0x0b8b3bb6, 0x4c5595ee), + TOBN(0x0ea9ef2e, 0x3ecebb21), TOBN(0x17cb6c4b, 0x3671f9a7), + TOBN(0x47ef464f, 0x726f1d1f), TOBN(0x171b9484, 0x6943a276), + TOBN(0x51a4ae2d, 0x7ef0329c), TOBN(0x08509222, 0x91c4402a), + TOBN(0x64a61d35, 0xafd45bbc), TOBN(0x38f096fe, 0x3035a851), + TOBN(0xc7468b74, 0xa1dec027), TOBN(0xe8cf10e7, 0x4fc7dcba), + TOBN(0xea35ff40, 0xf4a06353), TOBN(0x0b4c0dfa, 0x8b77dd66), + TOBN(0x779b8552, 0xde7e5c19), TOBN(0xfab28609, 0xc1c0256c), + TOBN(0x64f58eee, 0xabd4743d), TOBN(0x4e8ef838, 0x7b6cc93b), + TOBN(0xee650d26, 0x4cb1bf3d), TOBN(0x4c1f9d09, 0x73dedf61), + TOBN(0xaef7c9d7, 0xbfb70ced), TOBN(0x1ec0507e, 0x1641de1e), + TOBN(0xcd7e5cc7, 0xcde45079), TOBN(0xde173c9a, 0x516ac9e4), + TOBN(0x517a8494, 0xc170315c), TOBN(0x438fd905, 0x91d8e8fb), + TOBN(0x5145c506, 0xc7d9630b), TOBN(0x6457a87b, 0xf47d4d75), + TOBN(0xd31646bf, 0x0d9a80e8), TOBN(0x453add2b, 0xcef3aabe), + TOBN(0xc9941109, 0xa607419d), TOBN(0xfaa71e62, 0xbb6bca80), + TOBN(0x34158c13, 0x07c431f3), TOBN(0x594abebc, 0x992bc47a), + TOBN(0x6dfea691, 0xeb78399f), TOBN(0x48aafb35, 0x3f42cba4), + TOBN(0xedcd65af, 0x077c04f0), TOBN(0x1a29a366, 0xe884491a), + TOBN(0x023a40e5, 0x1c21f2bf), TOBN(0xf99a513c, 0xa5057aee), + TOBN(0xa3fe7e25, 0xbcab072e), TOBN(0x8568d2e1, 0x40e32bcf), + TOBN(0x904594eb, 0xd3f69d9f), TOBN(0x181a9733, 0x07affab1), + TOBN(0xe4d68d76, 0xb6e330f4), TOBN(0x87a6dafb, 0xc75a7fc1), + TOBN(0x549db2b5, 0xef7d9289), TOBN(0x2480d4a8, 0x197f015a), + TOBN(0x61d5590b, 0xc40493b6), TOBN(0x3a55b52e, 0x6f780331), + TOBN(0x40eb8115, 0x309eadb0), TOBN(0xdea7de5a, 0x92e5c625), + TOBN(0x64d631f0, 0xcc6a3d5a), TOBN(0x9d5e9d7c, 0x93e8dd61), + TOBN(0xf297bef5, 0x206d3ffc), TOBN(0x23d5e033, 0x7d808bd4), + TOBN(0x4a4f6912, 0xd24cf5ba), TOBN(0xe4d8163b, 0x09cdaa8a), + TOBN(0x0e0de9ef, 0xd3082e8e), TOBN(0x4fe1246c, 0x0192f360), + TOBN(0x1f900150, 0x4b8eee0a), TOBN(0x5219da81, 0xf1da391b), + TOBN(0x7bf6a5c1, 0xf7ea25aa), TOBN(0xd165e6bf, 0xfbb07d5f), + TOBN(0xe3539361, 0x89e78671), TOBN(0xa3fcac89, 0x2bac4219), + TOBN(0xdfab6fd4, 0xf0baa8ab), TOBN(0x5a4adac1, 0xe2c1c2e5), + TOBN(0x6cd75e31, 0x40d85849), TOBN(0xce263fea, 0x19b39181), + TOBN(0xcb6803d3, 0x07032c72), TOBN(0x7f40d5ce, 0x790968c8), + TOBN(0xa6de86bd, 0xdce978f0), TOBN(0x25547c4f, 0x368f751c), + TOBN(0xb1e685fd, 0x65fb2a9e), TOBN(0xce69336f, 0x1eb9179c), + TOBN(0xb15d1c27, 0x12504442), TOBN(0xb7df465c, 0xb911a06b), + TOBN(0xb8d804a3, 0x315980cd), TOBN(0x693bc492, 0xfa3bebf7), + TOBN(0x3578aeee, 0x2253c504), TOBN(0x158de498, 0xcd2474a2), + TOBN(0x1331f5c7, 0xcfda8368), TOBN(0xd2d7bbb3, 0x78d7177e), + TOBN(0xdf61133a, 0xf3c1e46e), TOBN(0x5836ce7d, 0xd30e7be8), + TOBN(0x83084f19, 0x94f834cb), TOBN(0xd35653d4, 0x429ed782), + TOBN(0xa542f16f, 0x59e58243), TOBN(0xc2b52f65, 0x0470a22d), + TOBN(0xe3b6221b, 0x18f23d96), TOBN(0xcb05abac, 0x3f5252b4), + TOBN(0xca00938b, 0x87d61402), TOBN(0x2f186cdd, 0x411933e4), + TOBN(0xe042ece5, 0x9a29a5c5), TOBN(0xb19b3c07, 0x3b6c8402), + TOBN(0xc97667c7, 0x19d92684), TOBN(0xb5624622, 0xebc66372), + TOBN(0x0cb96e65, 0x3c04fa02), TOBN(0x83a7176c, 0x8eaa39aa), + TOBN(0x2033561d, 0xeaa1633f), TOBN(0x45a9d086, 0x4533df73), + TOBN(0xe0542c1d, 0x3dc090bc), TOBN(0x82c996ef, 0xaa59c167), + TOBN(0xe3f735e8, 0x0ee7fc4d), TOBN(0x7b179393, 0x7c35db79), + TOBN(0xb6419e25, 0xf8c5dbfd), TOBN(0x4d9d7a1e, 0x1f327b04), + TOBN(0x979f6f9b, 0x298dfca8), TOBN(0xc7c5dff1, 0x8de9366a), + TOBN(0x1b7a588d, 0x04c82bdd), TOBN(0x68005534, 0xf8319dfd), + TOBN(0xde8a55b5, 0xd8eb9580), TOBN(0x5ea886da, 0x8d5bca81), + TOBN(0xe8530a01, 0x252a0b4d), TOBN(0x1bffb4fe, 0x35eaa0a1), + TOBN(0x2ad828b1, 0xd8e99563), TOBN(0x7de96ef5, 0x95f9cd87), + TOBN(0x4abb2d0c, 0xd77d970c), TOBN(0x03cfb933, 0xd33ef9cb), + TOBN(0xb0547c01, 0x8b211fe9), TOBN(0x2fe64809, 0xa56ed1c6), + TOBN(0xcb7d5624, 0xc2ac98cc), TOBN(0x2a1372c0, 0x1a393e33), + TOBN(0xc8d1ec1c, 0x29660521), TOBN(0xf3d31b04, 0xb37ac3e9), + TOBN(0xa29ae9df, 0x5ece6e7c), TOBN(0x0603ac8f, 0x0facfb55), + TOBN(0xcfe85b7a, 0xdda233a5), TOBN(0xe618919f, 0xbd75f0b8), + TOBN(0xf555a3d2, 0x99bf1603), TOBN(0x1f43afc9, 0xf184255a), + TOBN(0xdcdaf341, 0x319a3e02), TOBN(0xd3b117ef, 0x03903a39), + TOBN(0xe095da13, 0x65d1d131), TOBN(0x86f16367, 0xc37ad03e), + TOBN(0x5f37389e, 0x462cd8dd), TOBN(0xc103fa04, 0xd67a60e6), + TOBN(0x57c34344, 0xf4b478f0), TOBN(0xce91edd8, 0xe117c98d), + TOBN(0x001777b0, 0x231fc12e), TOBN(0x11ae47f2, 0xb207bccb), + TOBN(0xd983cf8d, 0x20f8a242), TOBN(0x7aff5b1d, 0xf22e1ad8), + TOBN(0x68fd11d0, 0x7fc4feb3), TOBN(0x5d53ae90, 0xb0f1c3e1), + TOBN(0x50fb7905, 0xec041803), TOBN(0x85e3c977, 0x14404888), + TOBN(0x0e67faed, 0xac628d8f), TOBN(0x2e865150, 0x6668532c), + TOBN(0x15acaaa4, 0x6a67a6b0), TOBN(0xf4cdee25, 0xb25cec41), + TOBN(0x49ee565a, 0xe4c6701e), TOBN(0x2a04ca66, 0xfc7d63d8), + TOBN(0xeb105018, 0xef0543fb), TOBN(0xf709a4f5, 0xd1b0d81d), + TOBN(0x5b906ee6, 0x2915d333), TOBN(0xf4a87412, 0x96f1f0ab), + TOBN(0xb6b82fa7, 0x4d82f4c2), TOBN(0x90725a60, 0x6804efb3), + TOBN(0xbc82ec46, 0xadc3425e), TOBN(0xb7b80581, 0x2787843e), + TOBN(0xdf46d91c, 0xdd1fc74c), TOBN(0xdc1c62cb, 0xe783a6c4), + TOBN(0x59d1b9f3, 0x1a04cbba), TOBN(0xd87f6f72, 0x95e40764), + TOBN(0x02b4cfc1, 0x317f4a76), TOBN(0x8d2703eb, 0x91036bce), + TOBN(0x98206cc6, 0xa5e72a56), TOBN(0x57be9ed1, 0xcf53fb0f), + TOBN(0x09374571, 0xef0b17ac), TOBN(0x74b2655e, 0xd9181b38), + TOBN(0xc8f80ea8, 0x89935d0e), TOBN(0xc0d9e942, 0x91529936), + TOBN(0x19686041, 0x1e84e0e5), TOBN(0xa5db84d3, 0xaea34c93), + TOBN(0xf9d5bb19, 0x7073a732), TOBN(0xb8d2fe56, 0x6bcfd7c0), + TOBN(0x45775f36, 0xf3eb82fa), TOBN(0x8cb20ccc, 0xfdff8b58), + TOBN(0x1659b65f, 0x8374c110), TOBN(0xb8b4a422, 0x330c789a), + TOBN(0x75e3c3ea, 0x6fe8208b), TOBN(0xbd74b9e4, 0x286e78fe), + TOBN(0x0be2e81b, 0xd7d93a1a), TOBN(0x7ed06e27, 0xdd0a5aae), + TOBN(0x721f5a58, 0x6be8b800), TOBN(0x428299d1, 0xd846db28), + TOBN(0x95cb8e6b, 0x5be88ed3), TOBN(0xc3186b23, 0x1c034e11), + TOBN(0xa6312c9e, 0x8977d99b), TOBN(0xbe944331, 0x83f531e7), + TOBN(0x8232c0c2, 0x18d3b1d4), TOBN(0x617aae8b, 0xe1247b73), + TOBN(0x40153fc4, 0x282aec3b), TOBN(0xc6063d2f, 0xf7b8f823), + TOBN(0x68f10e58, 0x3304f94c), TOBN(0x31efae74, 0xee676346), + TOBN(0xbadb6c6d, 0x40a9b97c), TOBN(0x14702c63, 0x4f666256), + TOBN(0xdeb954f1, 0x5184b2e3), TOBN(0x5184a526, 0x94b6ca40), + TOBN(0xfff05337, 0x003c32ea), TOBN(0x5aa374dd, 0x205974c7), + TOBN(0x9a763854, 0x4b0dd71a), TOBN(0x459cd27f, 0xdeb947ec), + TOBN(0xa6e28161, 0x459c2b92), TOBN(0x2f020fa8, 0x75ee8ef5), + TOBN(0xb132ec2d, 0x30b06310), TOBN(0xc3e15899, 0xbc6a4530), + TOBN(0xdc5f53fe, 0xaa3f451a), TOBN(0x3a3c7f23, 0xc2d9acac), + TOBN(0x2ec2f892, 0x6b27e58b), TOBN(0x68466ee7, 0xd742799f), + TOBN(0x98324dd4, 0x1fa26613), TOBN(0xa2dc6dab, 0xbdc29d63), + TOBN(0xf9675faa, 0xd712d657), TOBN(0x813994be, 0x21fd8d15), + TOBN(0x5ccbb722, 0xfd4f7553), TOBN(0x5135ff8b, 0xf3a36b20), + TOBN(0x44be28af, 0x69559df5), TOBN(0x40b65bed, 0x9d41bf30), + TOBN(0xd98bf2a4, 0x3734e520), TOBN(0x5e3abbe3, 0x209bdcba), + TOBN(0x77c76553, 0xbc945b35), TOBN(0x5331c093, 0xc6ef14aa), + TOBN(0x518ffe29, 0x76b60c80), TOBN(0x2285593b, 0x7ace16f8), + TOBN(0xab1f64cc, 0xbe2b9784), TOBN(0xe8f2c0d9, 0xab2421b6), + TOBN(0x617d7174, 0xc1df065c), TOBN(0xafeeb5ab, 0x5f6578fa), + TOBN(0x16ff1329, 0x263b54a8), TOBN(0x45c55808, 0xc990dce3), + TOBN(0x42eab6c0, 0xecc8c177), TOBN(0x799ea9b5, 0x5982ecaa), + TOBN(0xf65da244, 0xb607ef8e), TOBN(0x8ab226ce, 0x32a3fc2c), + TOBN(0x745741e5, 0x7ea973dc), TOBN(0x5c00ca70, 0x20888f2e), + TOBN(0x7cdce3cf, 0x45fd9cf1), TOBN(0x8a741ef1, 0x5507f872), + TOBN(0x47c51c2f, 0x196b4cec), TOBN(0x70d08e43, 0xc97ea618), + TOBN(0x930da15c, 0x15b18a2b), TOBN(0x33b6c678, 0x2f610514), + TOBN(0xc662e4f8, 0x07ac9794), TOBN(0x1eccf050, 0xba06cb79), + TOBN(0x1ff08623, 0xe7d954e5), TOBN(0x6ef2c5fb, 0x24cf71c3), + TOBN(0xb2c063d2, 0x67978453), TOBN(0xa0cf3796, 0x1d654af8), + TOBN(0x7cb242ea, 0x7ebdaa37), TOBN(0x206e0b10, 0xb86747e0), + TOBN(0x481dae5f, 0xd5ecfefc), TOBN(0x07084fd8, 0xc2bff8fc), + TOBN(0x8040a01a, 0xea324596), TOBN(0x4c646980, 0xd4de4036), + TOBN(0x9eb8ab4e, 0xd65abfc3), TOBN(0xe01cb91f, 0x13541ec7), + TOBN(0x8f029adb, 0xfd695012), TOBN(0x9ae28483, 0x3c7569ec), + TOBN(0xa5614c9e, 0xa66d80a1), TOBN(0x680a3e44, 0x75f5f911), + TOBN(0x0c07b14d, 0xceba4fc1), TOBN(0x891c285b, 0xa13071c1), + TOBN(0xcac67ceb, 0x799ece3c), TOBN(0x29b910a9, 0x41e07e27), + TOBN(0x66bdb409, 0xf2e43123), TOBN(0x06f8b137, 0x7ac9ecbe), + TOBN(0x5981fafd, 0x38547090), TOBN(0x19ab8b9f, 0x85e3415d), + TOBN(0xfc28c194, 0xc7e31b27), TOBN(0x843be0aa, 0x6fbcbb42), + TOBN(0xf3b1ed43, 0xa6db836c), TOBN(0x2a1330e4, 0x01a45c05), + TOBN(0x4f19f3c5, 0x95c1a377), TOBN(0xa85f39d0, 0x44b5ee33), + TOBN(0x3da18e6d, 0x4ae52834), TOBN(0x5a403b39, 0x7423dcb0), + TOBN(0xbb555e0a, 0xf2374aef), TOBN(0x2ad599c4, 0x1e8ca111), + TOBN(0x1b3a2fb9, 0x014b3bf8), TOBN(0x73092684, 0xf66d5007), + TOBN(0x079f1426, 0xc4340102), TOBN(0x1827cf81, 0x8fddf4de), + TOBN(0xc83605f6, 0xf10ff927), TOBN(0xd3871451, 0x23739fc6), + TOBN(0x6d163450, 0xcac1c2cc), TOBN(0x6b521296, 0xa2ec1ac5), + TOBN(0x0606c4f9, 0x6e3cb4a5), TOBN(0xe47d3f41, 0x778abff7), + TOBN(0x425a8d5e, 0xbe8e3a45), TOBN(0x53ea9e97, 0xa6102160), + TOBN(0x477a106e, 0x39cbb688), TOBN(0x532401d2, 0xf3386d32), + TOBN(0x8e564f64, 0xb1b9b421), TOBN(0xca9b8388, 0x81dad33f), + TOBN(0xb1422b4e, 0x2093913e), TOBN(0x533d2f92, 0x69bc8112), + TOBN(0x3fa017be, 0xebe7b2c7), TOBN(0xb2767c4a, 0xcaf197c6), + TOBN(0xc925ff87, 0xaedbae9f), TOBN(0x7daf0eb9, 0x36880a54), + TOBN(0x9284ddf5, 0x9c4d0e71), TOBN(0x1581cf93, 0x316f8cf5), + TOBN(0x3eeca887, 0x3ac1f452), TOBN(0xb417fce9, 0xfb6aeffe), + TOBN(0xa5918046, 0xeefb8dc3), TOBN(0x73d318ac, 0x02209400), + TOBN(0xe800400f, 0x728693e5), TOBN(0xe87d814b, 0x339927ed), + TOBN(0x93e94d3b, 0x57ea9910), TOBN(0xff8a35b6, 0x2245fb69), + TOBN(0x043853d7, 0x7f200d34), TOBN(0x470f1e68, 0x0f653ce1), + TOBN(0x81ac05bd, 0x59a06379), TOBN(0xa14052c2, 0x03930c29), + TOBN(0x6b72fab5, 0x26bc2797), TOBN(0x13670d16, 0x99f16771), + TOBN(0x00170052, 0x1e3e48d1), TOBN(0x978fe401, 0xb7adf678), + TOBN(0x55ecfb92, 0xd41c5dd4), TOBN(0x5ff8e247, 0xc7b27da5), + TOBN(0xe7518272, 0x013fb606), TOBN(0x5768d7e5, 0x2f547a3c), + TOBN(0xbb24eaa3, 0x60017a5f), TOBN(0x6b18e6e4, 0x9c64ce9b), + TOBN(0xc225c655, 0x103dde07), TOBN(0xfc3672ae, 0x7592f7ea), + TOBN(0x9606ad77, 0xd06283a1), TOBN(0x542fc650, 0xe4d59d99), + TOBN(0xabb57c49, 0x2a40e7c2), TOBN(0xac948f13, 0xa8db9f55), + TOBN(0x6d4c9682, 0xb04465c3), TOBN(0xe3d062fa, 0x6468bd15), + TOBN(0xa51729ac, 0x5f318d7e), TOBN(0x1fc87df6, 0x9eb6fc95), + TOBN(0x63d146a8, 0x0591f652), TOBN(0xa861b8f7, 0x589621aa), + TOBN(0x59f5f15a, 0xce31348c), TOBN(0x8f663391, 0x440da6da), + TOBN(0xcfa778ac, 0xb591ffa3), TOBN(0x027ca9c5, 0x4cdfebce), + TOBN(0xbe8e05a5, 0x444ea6b3), TOBN(0x8aab4e69, 0xa78d8254), + TOBN(0x2437f04f, 0xb474d6b8), TOBN(0x6597ffd4, 0x045b3855), + TOBN(0xbb0aea4e, 0xca47ecaa), TOBN(0x568aae83, 0x85c7ebfc), + TOBN(0x0e966e64, 0xc73b2383), TOBN(0x49eb3447, 0xd17d8762), + TOBN(0xde107821, 0x8da05dab), TOBN(0x443d8baa, 0x016b7236), + TOBN(0x163b63a5, 0xea7610d6), TOBN(0xe47e4185, 0xce1ca979), + TOBN(0xae648b65, 0x80baa132), TOBN(0xebf53de2, 0x0e0d5b64), + TOBN(0x8d3bfcb4, 0xd3c8c1ca), TOBN(0x0d914ef3, 0x5d04b309), + TOBN(0x55ef6415, 0x3de7d395), TOBN(0xbde1666f, 0x26b850e8), + TOBN(0xdbe1ca6e, 0xd449ab19), TOBN(0x8902b322, 0xe89a2672), + TOBN(0xb1674b7e, 0xdacb7a53), TOBN(0x8e9faf6e, 0xf52523ff), + TOBN(0x6ba535da, 0x9a85788b), TOBN(0xd21f03ae, 0xbd0626d4), + TOBN(0x099f8c47, 0xe873dc64), TOBN(0xcda8564d, 0x018ec97e), + TOBN(0x3e8d7a5c, 0xde92c68c), TOBN(0x78e035a1, 0x73323cc4), + TOBN(0x3ef26275, 0xf880ff7c), TOBN(0xa4ee3dff, 0x273eedaa), + TOBN(0x58823507, 0xaf4e18f8), TOBN(0x967ec9b5, 0x0672f328), + TOBN(0x9ded19d9, 0x559d3186), TOBN(0x5e2ab3de, 0x6cdce39c), + TOBN(0xabad6e4d, 0x11c226df), TOBN(0xf9783f43, 0x87723014), + TOBN(0x9a49a0cf, 0x1a885719), TOBN(0xfc0c1a5a, 0x90da9dbf), + TOBN(0x8bbaec49, 0x571d92ac), TOBN(0x569e85fe, 0x4692517f), + TOBN(0x8333b014, 0xa14ea4af), TOBN(0x32f2a62f, 0x12e5c5ad), + TOBN(0x98c2ce3a, 0x06d89b85), TOBN(0xb90741aa, 0x2ff77a08), + TOBN(0x2530defc, 0x01f795a2), TOBN(0xd6e5ba0b, 0x84b3c199), + TOBN(0x7d8e8451, 0x12e4c936), TOBN(0xae419f7d, 0xbd0be17b), + TOBN(0xa583fc8c, 0x22262bc9), TOBN(0x6b842ac7, 0x91bfe2bd), + TOBN(0x33cef4e9, 0x440d6827), TOBN(0x5f69f4de, 0xef81fb14), + TOBN(0xf16cf6f6, 0x234fbb92), TOBN(0x76ae3fc3, 0xd9e7e158), + TOBN(0x4e89f6c2, 0xe9740b33), TOBN(0x677bc85d, 0x4962d6a1), + TOBN(0x6c6d8a7f, 0x68d10d15), TOBN(0x5f9a7224, 0x0257b1cd), + TOBN(0x7096b916, 0x4ad85961), TOBN(0x5f8c47f7, 0xe657ab4a), + TOBN(0xde57d7d0, 0xf7461d7e), TOBN(0x7eb6094d, 0x80ce5ee2), + TOBN(0x0b1e1dfd, 0x34190547), TOBN(0x8a394f43, 0xf05dd150), + TOBN(0x0a9eb24d, 0x97df44e6), TOBN(0x78ca06bf, 0x87675719), + TOBN(0x6f0b3462, 0x6ffeec22), TOBN(0x9d91bcea, 0x36cdd8fb), + TOBN(0xac83363c, 0xa105be47), TOBN(0x81ba76c1, 0x069710e3), + TOBN(0x3d1b24cb, 0x28c682c6), TOBN(0x27f25228, 0x8612575b), + TOBN(0xb587c779, 0xe8e66e98), TOBN(0x7b0c03e9, 0x405eb1fe), + TOBN(0xfdf0d030, 0x15b548e7), TOBN(0xa8be76e0, 0x38b36af7), + TOBN(0x4cdab04a, 0x4f310c40), TOBN(0x6287223e, 0xf47ecaec), + TOBN(0x678e6055, 0x8b399320), TOBN(0x61fe3fa6, 0xc01e4646), + TOBN(0xc482866b, 0x03261a5e), TOBN(0xdfcf45b8, 0x5c2f244a), + TOBN(0x8fab9a51, 0x2f684b43), TOBN(0xf796c654, 0xc7220a66), + TOBN(0x1d90707e, 0xf5afa58f), TOBN(0x2c421d97, 0x4fdbe0de), + TOBN(0xc4f4cda3, 0xaf2ebc2f), TOBN(0xa0af843d, 0xcb4efe24), + TOBN(0x53b857c1, 0x9ccd10b1), TOBN(0xddc9d1eb, 0x914d3e04), + TOBN(0x7bdec8bb, 0x62771deb), TOBN(0x829277aa, 0x91c5aa81), + TOBN(0x7af18dd6, 0x832391ae), TOBN(0x1740f316, 0xc71a84ca)}, + {TOBN(0x8928e99a, 0xeeaf8c49), TOBN(0xee7aa73d, 0x6e24d728), + TOBN(0x4c5007c2, 0xe72b156c), TOBN(0x5fcf57c5, 0xed408a1d), + TOBN(0x9f719e39, 0xb6057604), TOBN(0x7d343c01, 0xc2868bbf), + TOBN(0x2cca254b, 0x7e103e2d), TOBN(0xe6eb38a9, 0xf131bea2), + TOBN(0xb33e624f, 0x8be762b4), TOBN(0x2a9ee4d1, 0x058e3413), + TOBN(0x968e6369, 0x67d805fa), TOBN(0x9848949b, 0x7db8bfd7), + TOBN(0x5308d7e5, 0xd23a8417), TOBN(0x892f3b1d, 0xf3e29da5), + TOBN(0xc95c139e, 0x3dee471f), TOBN(0x8631594d, 0xd757e089), + TOBN(0xe0c82a3c, 0xde918dcc), TOBN(0x2e7b5994, 0x26fdcf4b), + TOBN(0x82c50249, 0x32cb1b2d), TOBN(0xea613a9d, 0x7657ae07), + TOBN(0xc2eb5f6c, 0xf1fdc9f7), TOBN(0xb6eae8b8, 0x879fe682), + TOBN(0x253dfee0, 0x591cbc7f), TOBN(0x000da713, 0x3e1290e6), + TOBN(0x1083e2ea, 0x1f095615), TOBN(0x0a28ad77, 0x14e68c33), + TOBN(0x6bfc0252, 0x3d8818be), TOBN(0xb585113a, 0xf35850cd), + TOBN(0x7d935f0b, 0x30df8aa1), TOBN(0xaddda07c, 0x4ab7e3ac), + TOBN(0x92c34299, 0x552f00cb), TOBN(0xc33ed1de, 0x2909df6c), + TOBN(0x22c2195d, 0x80e87766), TOBN(0x9e99e6d8, 0x9ddf4ac0), + TOBN(0x09642e4e, 0x65e74934), TOBN(0x2610ffa2, 0xff1ff241), + TOBN(0x4d1d47d4, 0x751c8159), TOBN(0x697b4985, 0xaf3a9363), + TOBN(0x0318ca46, 0x87477c33), TOBN(0xa90cb565, 0x9441eff3), + TOBN(0x58bb3848, 0x36f024cb), TOBN(0x85be1f77, 0x36016168), + TOBN(0x6c59587c, 0xdc7e07f1), TOBN(0x191be071, 0xaf1d8f02), + TOBN(0xbf169fa5, 0xcca5e55c), TOBN(0x3864ba3c, 0xf7d04eac), + TOBN(0x915e367f, 0x8d7d05db), TOBN(0xb48a876d, 0xa6549e5d), + TOBN(0xef89c656, 0x580e40a2), TOBN(0xf194ed8c, 0x728068bc), + TOBN(0x74528045, 0xa47990c9), TOBN(0xf53fc7d7, 0x5e1a4649), + TOBN(0xbec5ae9b, 0x78593e7d), TOBN(0x2cac4ee3, 0x41db65d7), + TOBN(0xa8c1eb24, 0x04a3d39b), TOBN(0x53b7d634, 0x03f8f3ef), + TOBN(0x2dc40d48, 0x3e07113c), TOBN(0x6e4a5d39, 0x7d8b63ae), + TOBN(0x5582a94b, 0x79684c2b), TOBN(0x932b33d4, 0x622da26c), + TOBN(0xf534f651, 0x0dbbf08d), TOBN(0x211d07c9, 0x64c23a52), + TOBN(0x0eeece0f, 0xee5bdc9b), TOBN(0xdf178168, 0xf7015558), + TOBN(0xd4294635, 0x0a712229), TOBN(0x93cbe448, 0x09273f8c), + TOBN(0x00b095ef, 0x8f13bc83), TOBN(0xbb741972, 0x8798978c), + TOBN(0x9d7309a2, 0x56dbe6e7), TOBN(0xe578ec56, 0x5a5d39ec), + TOBN(0x3961151b, 0x851f9a31), TOBN(0x2da7715d, 0xe5709eb4), + TOBN(0x867f3017, 0x53dfabf0), TOBN(0x728d2078, 0xb8e39259), + TOBN(0x5c75a0cd, 0x815d9958), TOBN(0xf84867a6, 0x16603be1), + TOBN(0xc865b13d, 0x70e35b1c), TOBN(0x02414468, 0x19b03e2c), + TOBN(0xe46041da, 0xac1f3121), TOBN(0x7c9017ad, 0x6f028a7c), + TOBN(0xabc96de9, 0x0a482873), TOBN(0x4265d6b1, 0xb77e54d4), + TOBN(0x68c38e79, 0xa57d88e7), TOBN(0xd461d766, 0x9ce82de3), + TOBN(0x817a9ec5, 0x64a7e489), TOBN(0xcc5675cd, 0xa0def5f2), + TOBN(0x9a00e785, 0x985d494e), TOBN(0xc626833f, 0x1b03514a), + TOBN(0xabe7905a, 0x83cdd60e), TOBN(0x50602fb5, 0xa1170184), + TOBN(0x689886cd, 0xb023642a), TOBN(0xd568d090, 0xa6e1fb00), + TOBN(0x5b1922c7, 0x0259217f), TOBN(0x93831cd9, 0xc43141e4), + TOBN(0xdfca3587, 0x0c95f86e), TOBN(0xdec2057a, 0x568ae828), + TOBN(0xc44ea599, 0xf98a759a), TOBN(0x55a0a7a2, 0xf7c23c1d), + TOBN(0xd5ffb6e6, 0x94c4f687), TOBN(0x3563cce2, 0x12848478), + TOBN(0x812b3517, 0xe7b1fbe1), TOBN(0x8a7dc979, 0x4f7338e0), + TOBN(0x211ecee9, 0x52d048db), TOBN(0x2eea4056, 0xc86ea3b8), + TOBN(0xd8cb68a7, 0xba772b34), TOBN(0xe16ed341, 0x5f4e2541), + TOBN(0x9b32f6a6, 0x0fec14db), TOBN(0xeee376f7, 0x391698be), + TOBN(0xe9a7aa17, 0x83674c02), TOBN(0x65832f97, 0x5843022a), + TOBN(0x29f3a8da, 0x5ba4990f), TOBN(0x79a59c3a, 0xfb8e3216), + TOBN(0x9cdc4d2e, 0xbd19bb16), TOBN(0xc6c7cfd0, 0xb3262d86), + TOBN(0xd4ce14d0, 0x969c0b47), TOBN(0x1fa352b7, 0x13e56128), + TOBN(0x383d55b8, 0x973db6d3), TOBN(0x71836850, 0xe8e5b7bf), + TOBN(0xc7714596, 0xe6bb571f), TOBN(0x259df31f, 0x2d5b2dd2), + TOBN(0x568f8925, 0x913cc16d), TOBN(0x18bc5b6d, 0xe1a26f5a), + TOBN(0xdfa413be, 0xf5f499ae), TOBN(0xf8835dec, 0xc3f0ae84), + TOBN(0xb6e60bd8, 0x65a40ab0), TOBN(0x65596439, 0x194b377e), + TOBN(0xbcd85625, 0x92084a69), TOBN(0x5ce433b9, 0x4f23ede0), + TOBN(0xe8e8f04f, 0x6ad65143), TOBN(0x11511827, 0xd6e14af6), + TOBN(0x3d390a10, 0x8295c0c7), TOBN(0x71e29ee4, 0x621eba16), + TOBN(0xa588fc09, 0x63717b46), TOBN(0x02be02fe, 0xe06ad4a2), + TOBN(0x931558c6, 0x04c22b22), TOBN(0xbb4d4bd6, 0x12f3c849), + TOBN(0x54a4f496, 0x20efd662), TOBN(0x92ba6d20, 0xc5952d14), + TOBN(0x2db8ea1e, 0xcc9784c2), TOBN(0x81cc10ca, 0x4b353644), + TOBN(0x40b570ad, 0x4b4d7f6c), TOBN(0x5c9f1d96, 0x84a1dcd2), + TOBN(0x01379f81, 0x3147e797), TOBN(0xe5c6097b, 0x2bd499f5), + TOBN(0x40dcafa6, 0x328e5e20), TOBN(0xf7b5244a, 0x54815550), + TOBN(0xb9a4f118, 0x47bfc978), TOBN(0x0ea0e79f, 0xd25825b1), + TOBN(0xa50f96eb, 0x646c7ecf), TOBN(0xeb811493, 0x446dea9d), + TOBN(0x2af04677, 0xdfabcf69), TOBN(0xbe3a068f, 0xc713f6e8), + TOBN(0x860d523d, 0x42e06189), TOBN(0xbf077941, 0x4e3aff13), + TOBN(0x0b616dca, 0xc1b20650), TOBN(0xe66dd6d1, 0x2131300d), + TOBN(0xd4a0fd67, 0xff99abde), TOBN(0xc9903550, 0xc7aac50d), + TOBN(0x022ecf8b, 0x7c46b2d7), TOBN(0x3333b1e8, 0x3abf92af), + TOBN(0x11cc113c, 0x6c491c14), TOBN(0x05976688, 0x80dd3f88), + TOBN(0xf5b4d9e7, 0x29d932ed), TOBN(0xe982aad8, 0xa2c38b6d), + TOBN(0x6f925347, 0x8be0dcf0), TOBN(0x700080ae, 0x65ca53f2), + TOBN(0xd8131156, 0x443ca77f), TOBN(0xe92d6942, 0xec51f984), + TOBN(0xd2a08af8, 0x85dfe9ae), TOBN(0xd825d9a5, 0x4d2a86ca), + TOBN(0x2c53988d, 0x39dff020), TOBN(0xf38b135a, 0x430cdc40), + TOBN(0x0c918ae0, 0x62a7150b), TOBN(0xf31fd8de, 0x0c340e9b), + TOBN(0xafa0e7ae, 0x4dbbf02e), TOBN(0x5847fb2a, 0x5eba6239), + TOBN(0x6b1647dc, 0xdccbac8b), TOBN(0xb642aa78, 0x06f485c8), + TOBN(0x873f3765, 0x7038ecdf), TOBN(0x2ce5e865, 0xfa49d3fe), + TOBN(0xea223788, 0xc98c4400), TOBN(0x8104a8cd, 0xf1fa5279), + TOBN(0xbcf7cc7a, 0x06becfd7), TOBN(0x49424316, 0xc8f974ae), + TOBN(0xc0da65e7, 0x84d6365d), TOBN(0xbcb7443f, 0x8f759fb8), + TOBN(0x35c712b1, 0x7ae81930), TOBN(0x80428dff, 0x4c6e08ab), + TOBN(0xf19dafef, 0xa4faf843), TOBN(0xced8538d, 0xffa9855f), + TOBN(0x20ac409c, 0xbe3ac7ce), TOBN(0x358c1fb6, 0x882da71e), + TOBN(0xafa9c0e5, 0xfd349961), TOBN(0x2b2cfa51, 0x8421c2fc), + TOBN(0x2a80db17, 0xf3a28d38), TOBN(0xa8aba539, 0x5d138e7e), + TOBN(0x52012d1d, 0x6e96eb8d), TOBN(0x65d8dea0, 0xcbaf9622), + TOBN(0x57735447, 0xb264f56c), TOBN(0xbeebef3f, 0x1b6c8da2), + TOBN(0xfc346d98, 0xce785254), TOBN(0xd50e8d72, 0xbb64a161), + TOBN(0xc03567c7, 0x49794add), TOBN(0x15a76065, 0x752c7ef6), + TOBN(0x59f3a222, 0x961f23d6), TOBN(0x378e4438, 0x73ecc0b0), + TOBN(0xc74be434, 0x5a82fde4), TOBN(0xae509af2, 0xd8b9cf34), + TOBN(0x4a61ee46, 0x577f44a1), TOBN(0xe09b748c, 0xb611deeb), + TOBN(0xc0481b2c, 0xf5f7b884), TOBN(0x35626678, 0x61acfa6b), + TOBN(0x37f4c518, 0xbf8d21e6), TOBN(0x22d96531, 0xb205a76d), + TOBN(0x37fb85e1, 0x954073c0), TOBN(0xbceafe4f, 0x65b3a567), + TOBN(0xefecdef7, 0xbe42a582), TOBN(0xd3fc6080, 0x65046be6), + TOBN(0xc9af13c8, 0x09e8dba9), TOBN(0x1e6c9847, 0x641491ff), + TOBN(0x3b574925, 0xd30c31f7), TOBN(0xb7eb72ba, 0xac2a2122), + TOBN(0x776a0dac, 0xef0859e7), TOBN(0x06fec314, 0x21900942), + TOBN(0x2464bc10, 0xf8c22049), TOBN(0x9bfbcce7, 0x875ebf69), + TOBN(0xd7a88e2a, 0x4336326b), TOBN(0xda05261c, 0x5bc2acfa), + TOBN(0xc29f5bdc, 0xeba7efc8), TOBN(0x471237ca, 0x25dbbf2e), + TOBN(0xa72773f2, 0x2975f127), TOBN(0xdc744e8e, 0x04d0b326), + TOBN(0x38a7ed16, 0xa56edb73), TOBN(0x64357e37, 0x2c007e70), + TOBN(0xa167d15b, 0x5080b400), TOBN(0x07b41164, 0x23de4be1), + TOBN(0xb2d91e32, 0x74c89883), TOBN(0x3c162821, 0x2882e7ed), + TOBN(0xad6b36ba, 0x7503e482), TOBN(0x48434e8e, 0x0ea34331), + TOBN(0x79f4f24f, 0x2c7ae0b9), TOBN(0xc46fbf81, 0x1939b44a), + TOBN(0x76fefae8, 0x56595eb1), TOBN(0x417b66ab, 0xcd5f29c7), + TOBN(0x5f2332b2, 0xc5ceec20), TOBN(0xd69661ff, 0xe1a1cae2), + TOBN(0x5ede7e52, 0x9b0286e6), TOBN(0x9d062529, 0xe276b993), + TOBN(0x324794b0, 0x7e50122b), TOBN(0xdd744f8b, 0x4af07ca5), + TOBN(0x30a12f08, 0xd63fc97b), TOBN(0x39650f1a, 0x76626d9d), + TOBN(0x101b47f7, 0x1fa38477), TOBN(0x3d815f19, 0xd4dc124f), + TOBN(0x1569ae95, 0xb26eb58a), TOBN(0xc3cde188, 0x95fb1887), + TOBN(0x54e9f37b, 0xf9539a48), TOBN(0xb0100e06, 0x7408c1a5), + TOBN(0x821d9811, 0xea580cbb), TOBN(0x8af52d35, 0x86e50c56), + TOBN(0xdfbd9d47, 0xdbbf698b), TOBN(0x2961a1ea, 0x03dc1c73), + TOBN(0x203d38f8, 0xe76a5df8), TOBN(0x08a53a68, 0x6def707a), + TOBN(0x26eefb48, 0x1bee45d4), TOBN(0xb3cee346, 0x3c688036), + TOBN(0x463c5315, 0xc42f2469), TOBN(0x19d84d2e, 0x81378162), + TOBN(0x22d7c3c5, 0x1c4d349f), TOBN(0x65965844, 0x163d59c5), + TOBN(0xcf198c56, 0xb8abceae), TOBN(0x6fb1fb1b, 0x628559d5), + TOBN(0x8bbffd06, 0x07bf8fe3), TOBN(0x46259c58, 0x3467734b), + TOBN(0xd8953cea, 0x35f7f0d3), TOBN(0x1f0bece2, 0xd65b0ff1), + TOBN(0xf7d5b4b3, 0xf3c72914), TOBN(0x29e8ea95, 0x3cb53389), + TOBN(0x4a365626, 0x836b6d46), TOBN(0xe849f910, 0xea174fde), + TOBN(0x7ec62fbb, 0xf4737f21), TOBN(0xd8dba5ab, 0x6209f5ac), + TOBN(0x24b5d7a9, 0xa5f9adbe), TOBN(0x707d28f7, 0xa61dc768), + TOBN(0x7711460b, 0xcaa999ea), TOBN(0xba7b174d, 0x1c92e4cc), + TOBN(0x3c4bab66, 0x18d4bf2d), TOBN(0xb8f0c980, 0xeb8bd279), + TOBN(0x024bea9a, 0x324b4737), TOBN(0xfba9e423, 0x32a83bca), + TOBN(0x6e635643, 0xa232dced), TOBN(0x99619367, 0x2571c8ba), + TOBN(0xe8c9f357, 0x54b7032b), TOBN(0xf936b3ba, 0x2442d54a), + TOBN(0x2263f0f0, 0x8290c65a), TOBN(0x48989780, 0xee2c7fdb), + TOBN(0xadc5d55a, 0x13d4f95e), TOBN(0x737cff85, 0xad9b8500), + TOBN(0x271c557b, 0x8a73f43d), TOBN(0xbed617a4, 0xe18bc476), + TOBN(0x66245401, 0x7dfd8ab2), TOBN(0xae7b89ae, 0x3a2870aa), + TOBN(0x1b555f53, 0x23a7e545), TOBN(0x6791e247, 0xbe057e4c), + TOBN(0x860136ad, 0x324fa34d), TOBN(0xea111447, 0x4cbeae28), + TOBN(0x023a4270, 0xbedd3299), TOBN(0x3d5c3a7f, 0xc1c35c34), + TOBN(0xb0f6db67, 0x8d0412d2), TOBN(0xd92625e2, 0xfcdc6b9a), + TOBN(0x92ae5ccc, 0x4e28a982), TOBN(0xea251c36, 0x47a3ce7e), + TOBN(0x9d658932, 0x790691bf), TOBN(0xed610589, 0x06b736ae), + TOBN(0x712c2f04, 0xc0d63b6e), TOBN(0x5cf06fd5, 0xc63d488f), + TOBN(0x97363fac, 0xd9588e41), TOBN(0x1f9bf762, 0x2b93257e), + TOBN(0xa9d1ffc4, 0x667acace), TOBN(0x1cf4a1aa, 0x0a061ecf), + TOBN(0x40e48a49, 0xdc1818d0), TOBN(0x0643ff39, 0xa3621ab0), + TOBN(0x5768640c, 0xe39ef639), TOBN(0x1fc099ea, 0x04d86854), + TOBN(0x9130b9c3, 0xeccd28fd), TOBN(0xd743cbd2, 0x7eec54ab), + TOBN(0x052b146f, 0xe5b475b6), TOBN(0x058d9a82, 0x900a7d1f), + TOBN(0x65e02292, 0x91262b72), TOBN(0x96f924f9, 0xbb0edf03), + TOBN(0x5cfa59c8, 0xfe206842), TOBN(0xf6037004, 0x5eafa720), + TOBN(0x5f30699e, 0x18d7dd96), TOBN(0x381e8782, 0xcbab2495), + TOBN(0x91669b46, 0xdd8be949), TOBN(0xb40606f5, 0x26aae8ef), + TOBN(0x2812b839, 0xfc6751a4), TOBN(0x16196214, 0xfba800ef), + TOBN(0x4398d5ca, 0x4c1a2875), TOBN(0x720c00ee, 0x653d8349), + TOBN(0xc2699eb0, 0xd820007c), TOBN(0x880ee660, 0xa39b5825), + TOBN(0x70694694, 0x471f6984), TOBN(0xf7d16ea8, 0xe3dda99a), + TOBN(0x28d675b2, 0xc0519a23), TOBN(0x9ebf94fe, 0x4f6952e3), + TOBN(0xf28bb767, 0xa2294a8a), TOBN(0x85512b4d, 0xfe0af3f5), + TOBN(0x18958ba8, 0x99b16a0d), TOBN(0x95c2430c, 0xba7548a7), + TOBN(0xb30d1b10, 0xa16be615), TOBN(0xe3ebbb97, 0x85bfb74c), + TOBN(0xa3273cfe, 0x18549fdb), TOBN(0xf6e200bf, 0x4fcdb792), + TOBN(0x54a76e18, 0x83aba56c), TOBN(0x73ec66f6, 0x89ef6aa2), + TOBN(0x8d17add7, 0xd1b9a305), TOBN(0xa959c5b9, 0xb7ae1b9d), + TOBN(0x88643522, 0x6bcc094a), TOBN(0xcc5616c4, 0xd7d429b9), + TOBN(0xa6dada01, 0xe6a33f7c), TOBN(0xc6217a07, 0x9d4e70ad), + TOBN(0xd619a818, 0x09c15b7c), TOBN(0xea06b329, 0x0e80c854), + TOBN(0x174811ce, 0xa5f5e7b9), TOBN(0x66dfc310, 0x787c65f4), + TOBN(0x4ea7bd69, 0x3316ab54), TOBN(0xc12c4acb, 0x1dcc0f70), + TOBN(0xe4308d1a, 0x1e407dd9), TOBN(0xe8a3587c, 0x91afa997), + TOBN(0xea296c12, 0xab77b7a5), TOBN(0xb5ad49e4, 0x673c0d52), + TOBN(0x40f9b2b2, 0x7006085a), TOBN(0xa88ff340, 0x87bf6ec2), + TOBN(0x978603b1, 0x4e3066a6), TOBN(0xb3f99fc2, 0xb5e486e2), + TOBN(0x07b53f5e, 0xb2e63645), TOBN(0xbe57e547, 0x84c84232), + TOBN(0xd779c216, 0x7214d5cf), TOBN(0x617969cd, 0x029a3aca), + TOBN(0xd17668cd, 0x8a7017a0), TOBN(0x77b4d19a, 0xbe9b7ee8), + TOBN(0x58fd0e93, 0x9c161776), TOBN(0xa8c4f4ef, 0xd5968a72), + TOBN(0x296071cc, 0x67b3de77), TOBN(0xae3c0b8e, 0x634f7905), + TOBN(0x67e440c2, 0x8a7100c9), TOBN(0xbb8c3c1b, 0xeb4b9b42), + TOBN(0x6d71e8ea, 0xc51b3583), TOBN(0x7591f5af, 0x9525e642), + TOBN(0xf73a2f7b, 0x13f509f3), TOBN(0x618487aa, 0x5619ac9b), + TOBN(0x3a72e5f7, 0x9d61718a), TOBN(0x00413bcc, 0x7592d28c), + TOBN(0x7d9b11d3, 0x963c35cf), TOBN(0x77623bcf, 0xb90a46ed), + TOBN(0xdeef273b, 0xdcdd2a50), TOBN(0x4a741f9b, 0x0601846e), + TOBN(0x33b89e51, 0x0ec6e929), TOBN(0xcb02319f, 0x8b7f22cd), + TOBN(0xbbe1500d, 0x084bae24), TOBN(0x2f0ae8d7, 0x343d2693), + TOBN(0xacffb5f2, 0x7cdef811), TOBN(0xaa0c030a, 0x263fb94f), + TOBN(0x6eef0d61, 0xa0f442de), TOBN(0xf92e1817, 0x27b139d3), + TOBN(0x1ae6deb7, 0x0ad8bc28), TOBN(0xa89e38dc, 0xc0514130), + TOBN(0x81eeb865, 0xd2fdca23), TOBN(0x5a15ee08, 0xcc8ef895), + TOBN(0x768fa10a, 0x01905614), TOBN(0xeff5b8ef, 0x880ee19b), + TOBN(0xf0c0cabb, 0xcb1c8a0e), TOBN(0x2e1ee9cd, 0xb8c838f9), + TOBN(0x0587d8b8, 0x8a4a14c0), TOBN(0xf6f27896, 0x2ff698e5), + TOBN(0xed38ef1c, 0x89ee6256), TOBN(0xf44ee1fe, 0x6b353b45), + TOBN(0x9115c0c7, 0x70e903b3), TOBN(0xc78ec0a1, 0x818f31df), + TOBN(0x6c003324, 0xb7dccbc6), TOBN(0xd96dd1f3, 0x163bbc25), + TOBN(0x33aa82dd, 0x5cedd805), TOBN(0x123aae4f, 0x7f7eb2f1), + TOBN(0x1723fcf5, 0xa26262cd), TOBN(0x1f7f4d5d, 0x0060ebd5), + TOBN(0xf19c5c01, 0xb2eaa3af), TOBN(0x2ccb9b14, 0x9790accf), + TOBN(0x1f9c1cad, 0x52324aa6), TOBN(0x63200526, 0x7247df54), + TOBN(0x5732fe42, 0xbac96f82), TOBN(0x52fe771f, 0x01a1c384), + TOBN(0x546ca13d, 0xb1001684), TOBN(0xb56b4eee, 0xa1709f75), + TOBN(0x266545a9, 0xd5db8672), TOBN(0xed971c90, 0x1e8f3cfb), + TOBN(0x4e7d8691, 0xe3a07b29), TOBN(0x7570d9ec, 0xe4b696b9), + TOBN(0xdc5fa067, 0x7bc7e9ae), TOBN(0x68b44caf, 0xc82c4844), + TOBN(0x519d34b3, 0xbf44da80), TOBN(0x283834f9, 0x5ab32e66), + TOBN(0x6e608797, 0x6278a000), TOBN(0x1e62960e, 0x627312f6), + TOBN(0x9b87b27b, 0xe6901c55), TOBN(0x80e78538, 0x24fdbc1f), + TOBN(0xbbbc0951, 0x2facc27d), TOBN(0x06394239, 0xac143b5a), + TOBN(0x35bb4a40, 0x376c1944), TOBN(0x7cb62694, 0x63da1511), + TOBN(0xafd29161, 0xb7148a3b), TOBN(0xa6f9d9ed, 0x4e2ea2ee), + TOBN(0x15dc2ca2, 0x880dd212), TOBN(0x903c3813, 0xa61139a9), + TOBN(0x2aa7b46d, 0x6c0f8785), TOBN(0x36ce2871, 0x901c60ff), + TOBN(0xc683b028, 0xe10d9c12), TOBN(0x7573baa2, 0x032f33d3), + TOBN(0x87a9b1f6, 0x67a31b58), TOBN(0xfd3ed11a, 0xf4ffae12), + TOBN(0x83dcaa9a, 0x0cb2748e), TOBN(0x8239f018, 0x5d6fdf16), + TOBN(0xba67b49c, 0x72753941), TOBN(0x2beec455, 0xc321cb36), + TOBN(0x88015606, 0x3f8b84ce), TOBN(0x76417083, 0x8d38c86f), + TOBN(0x054f1ca7, 0x598953dd), TOBN(0xc939e110, 0x4e8e7429), + TOBN(0x9b1ac2b3, 0x5a914f2f), TOBN(0x39e35ed3, 0xe74b8f9c), + TOBN(0xd0debdb2, 0x781b2fb0), TOBN(0x1585638f, 0x2d997ba2), + TOBN(0x9c4b646e, 0x9e2fce99), TOBN(0x68a21081, 0x1e80857f), + TOBN(0x06d54e44, 0x3643b52a), TOBN(0xde8d6d63, 0x0d8eb843), + TOBN(0x70321563, 0x42146a0a), TOBN(0x8ba826f2, 0x5eaa3622), + TOBN(0x227a58bd, 0x86138787), TOBN(0x43b6c03c, 0x10281d37), + TOBN(0x6326afbb, 0xb54dde39), TOBN(0x744e5e8a, 0xdb6f2d5f), + TOBN(0x48b2a99a, 0xcff158e1), TOBN(0xa93c8fa0, 0xef87918f), + TOBN(0x2182f956, 0xde058c5c), TOBN(0x216235d2, 0x936f9e7a), + TOBN(0xace0c0db, 0xd2e31e67), TOBN(0xc96449bf, 0xf23ac3e7), + TOBN(0x7e9a2874, 0x170693bd), TOBN(0xa28e14fd, 0xa45e6335), + TOBN(0x5757f6b3, 0x56427344), TOBN(0x822e4556, 0xacf8edf9), + TOBN(0x2b7a6ee2, 0xe6a285cd), TOBN(0x5866f211, 0xa9df3af0), + TOBN(0x40dde2dd, 0xf845b844), TOBN(0x986c3726, 0x110e5e49), + TOBN(0x73680c2a, 0xf7172277), TOBN(0x57b94f0f, 0x0cccb244), + TOBN(0xbdff7267, 0x2d438ca7), TOBN(0xbad1ce11, 0xcf4663fd), + TOBN(0x9813ed9d, 0xd8f71cae), TOBN(0xf43272a6, 0x961fdaa6), + TOBN(0xbeff0119, 0xbd6d1637), TOBN(0xfebc4f91, 0x30361978), + TOBN(0x02b37a95, 0x2f41deff), TOBN(0x0e44a59a, 0xe63b89b7), + TOBN(0x673257dc, 0x143ff951), TOBN(0x19c02205, 0xd752baf4), + TOBN(0x46c23069, 0xc4b7d692), TOBN(0x2e6392c3, 0xfd1502ac), + TOBN(0x6057b1a2, 0x1b220846), TOBN(0xe51ff946, 0x0c1b5b63)}, + {TOBN(0x6e85cb51, 0x566c5c43), TOBN(0xcff9c919, 0x3597f046), + TOBN(0x9354e90c, 0x4994d94a), TOBN(0xe0a39332, 0x2147927d), + TOBN(0x8427fac1, 0x0dc1eb2b), TOBN(0x88cfd8c2, 0x2ff319fa), + TOBN(0xe2d4e684, 0x01965274), TOBN(0xfa2e067d, 0x67aaa746), + TOBN(0xb6d92a7f, 0x3e5f9f11), TOBN(0x9afe153a, 0xd6cb3b8e), + TOBN(0x4d1a6dd7, 0xddf800bd), TOBN(0xf6c13cc0, 0xcaf17e19), + TOBN(0x15f6c58e, 0x325fc3ee), TOBN(0x71095400, 0xa31dc3b2), + TOBN(0x168e7c07, 0xafa3d3e7), TOBN(0x3f8417a1, 0x94c7ae2d), + TOBN(0xec234772, 0x813b230d), TOBN(0x634d0f5f, 0x17344427), + TOBN(0x11548ab1, 0xd77fc56a), TOBN(0x7fab1750, 0xce06af77), + TOBN(0xb62c10a7, 0x4f7c4f83), TOBN(0xa7d2edc4, 0x220a67d9), + TOBN(0x1c404170, 0x921209a0), TOBN(0x0b9815a0, 0xface59f0), + TOBN(0x2842589b, 0x319540c3), TOBN(0x18490f59, 0xa283d6f8), + TOBN(0xa2731f84, 0xdaae9fcb), TOBN(0x3db6d960, 0xc3683ba0), + TOBN(0xc85c63bb, 0x14611069), TOBN(0xb19436af, 0x0788bf05), + TOBN(0x905459df, 0x347460d2), TOBN(0x73f6e094, 0xe11a7db1), + TOBN(0xdc7f938e, 0xb6357f37), TOBN(0xc5d00f79, 0x2bd8aa62), + TOBN(0xc878dcb9, 0x2ca979fc), TOBN(0x37e83ed9, 0xeb023a99), + TOBN(0x6b23e273, 0x1560bf3d), TOBN(0x1086e459, 0x1d0fae61), + TOBN(0x78248316, 0x9a9414bd), TOBN(0x1b956bc0, 0xf0ea9ea1), + TOBN(0x7b85bb91, 0xc31b9c38), TOBN(0x0c5aa90b, 0x48ef57b5), + TOBN(0xdedeb169, 0xaf3bab6f), TOBN(0xe610ad73, 0x2d373685), + TOBN(0xf13870df, 0x02ba8e15), TOBN(0x0337edb6, 0x8ca7f771), + TOBN(0xe4acf747, 0xb62c036c), TOBN(0xd921d576, 0xb6b94e81), + TOBN(0xdbc86439, 0x2c422f7a), TOBN(0xfb635362, 0xed348898), + TOBN(0x83084668, 0xc45bfcd1), TOBN(0xc357c9e3, 0x2b315e11), + TOBN(0xb173b540, 0x5b2e5b8c), TOBN(0x7e946931, 0xe102b9a4), + TOBN(0x17c890eb, 0x7b0fb199), TOBN(0xec225a83, 0xd61b662b), + TOBN(0xf306a3c8, 0xee3c76cb), TOBN(0x3cf11623, 0xd32a1f6e), + TOBN(0xe6d5ab64, 0x6863e956), TOBN(0x3b8a4cbe, 0x5c005c26), + TOBN(0xdcd529a5, 0x9ce6bb27), TOBN(0xc4afaa52, 0x04d4b16f), + TOBN(0xb0624a26, 0x7923798d), TOBN(0x85e56df6, 0x6b307fab), + TOBN(0x0281893c, 0x2bf29698), TOBN(0x91fc19a4, 0xd7ce7603), + TOBN(0x75a5dca3, 0xad9a558f), TOBN(0x40ceb3fa, 0x4d50bf77), + TOBN(0x1baf6060, 0xbc9ba369), TOBN(0x927e1037, 0x597888c2), + TOBN(0xd936bf19, 0x86a34c07), TOBN(0xd4cf10c1, 0xc34ae980), + TOBN(0x3a3e5334, 0x859dd614), TOBN(0x9c475b5b, 0x18d0c8ee), + TOBN(0x63080d1f, 0x07cd51d5), TOBN(0xc9c0d0a6, 0xb88b4326), + TOBN(0x1ac98691, 0xc234296f), TOBN(0x2a0a83a4, 0x94887fb6), + TOBN(0x56511427, 0x0cea9cf2), TOBN(0x5230a6e8, 0xa24802f5), + TOBN(0xf7a2bf0f, 0x72e3d5c1), TOBN(0x37717446, 0x4f21439e), + TOBN(0xfedcbf25, 0x9ce30334), TOBN(0xe0030a78, 0x7ce202f9), + TOBN(0x6f2d9ebf, 0x1202e9ca), TOBN(0xe79dde6c, 0x75e6e591), + TOBN(0xf52072af, 0xf1dac4f8), TOBN(0x6c8d087e, 0xbb9b404d), + TOBN(0xad0fc73d, 0xbce913af), TOBN(0x909e587b, 0x458a07cb), + TOBN(0x1300da84, 0xd4f00c8a), TOBN(0x425cd048, 0xb54466ac), + TOBN(0xb59cb9be, 0x90e9d8bf), TOBN(0x991616db, 0x3e431b0e), + TOBN(0xd3aa117a, 0x531aecff), TOBN(0x91af92d3, 0x59f4dc3b), + TOBN(0x9b1ec292, 0xe93fda29), TOBN(0x76bb6c17, 0xe97d91bc), + TOBN(0x7509d95f, 0xaface1e6), TOBN(0x3653fe47, 0xbe855ae3), + TOBN(0x73180b28, 0x0f680e75), TOBN(0x75eefd1b, 0xeeb6c26c), + TOBN(0xa4cdf29f, 0xb66d4236), TOBN(0x2d70a997, 0x6b5821d8), + TOBN(0x7a3ee207, 0x20445c36), TOBN(0x71d1ac82, 0x59877174), + TOBN(0x0fc539f7, 0x949f73e9), TOBN(0xd05cf3d7, 0x982e3081), + TOBN(0x8758e20b, 0x7b1c7129), TOBN(0xffadcc20, 0x569e61f2), + TOBN(0xb05d3a2f, 0x59544c2d), TOBN(0xbe16f5c1, 0x9fff5e53), + TOBN(0x73cf65b8, 0xaad58135), TOBN(0x622c2119, 0x037aa5be), + TOBN(0x79373b3f, 0x646fd6a0), TOBN(0x0e029db5, 0x0d3978cf), + TOBN(0x8bdfc437, 0x94fba037), TOBN(0xaefbd687, 0x620797a6), + TOBN(0x3fa5382b, 0xbd30d38e), TOBN(0x7627cfbf, 0x585d7464), + TOBN(0xb2330fef, 0x4e4ca463), TOBN(0xbcef7287, 0x3566cc63), + TOBN(0xd161d2ca, 0xcf780900), TOBN(0x135dc539, 0x5b54827d), + TOBN(0x638f052e, 0x27bf1bc6), TOBN(0x10a224f0, 0x07dfa06c), + TOBN(0xe973586d, 0x6d3321da), TOBN(0x8b0c5738, 0x26152c8f), + TOBN(0x07ef4f2a, 0x34606074), TOBN(0x80fe7fe8, 0xa0f7047a), + TOBN(0x3d1a8152, 0xe1a0e306), TOBN(0x32cf43d8, 0x88da5222), + TOBN(0xbf89a95f, 0x5f02ffe6), TOBN(0x3d9eb9a4, 0x806ad3ea), + TOBN(0x012c17bb, 0x79c8e55e), TOBN(0xfdcd1a74, 0x99c81dac), + TOBN(0x7043178b, 0xb9556098), TOBN(0x4090a1df, 0x801c3886), + TOBN(0x759800ff, 0x9b67b912), TOBN(0x3e5c0304, 0x232620c8), + TOBN(0x4b9d3c4b, 0x70dceeca), TOBN(0xbb2d3c15, 0x181f648e), + TOBN(0xf981d837, 0x6e33345c), TOBN(0xb626289b, 0x0cf2297a), + TOBN(0x766ac659, 0x8baebdcf), TOBN(0x1a28ae09, 0x75df01e5), + TOBN(0xb71283da, 0x375876d8), TOBN(0x4865a96d, 0x607b9800), + TOBN(0x25dd1bcd, 0x237936b2), TOBN(0x332f4f4b, 0x60417494), + TOBN(0xd0923d68, 0x370a2147), TOBN(0x497f5dfb, 0xdc842203), + TOBN(0x9dc74cbd, 0x32be5e0f), TOBN(0x7475bcb7, 0x17a01375), + TOBN(0x438477c9, 0x50d872b1), TOBN(0xcec67879, 0xffe1d63d), + TOBN(0x9b006014, 0xd8578c70), TOBN(0xc9ad99a8, 0x78bb6b8b), + TOBN(0x6799008e, 0x11fb3806), TOBN(0xcfe81435, 0xcd44cab3), + TOBN(0xa2ee1582, 0x2f4fb344), TOBN(0xb8823450, 0x483fa6eb), + TOBN(0x622d323d, 0x652c7749), TOBN(0xd8474a98, 0xbeb0a15b), + TOBN(0xe43c154d, 0x5d1c00d0), TOBN(0x7fd581d9, 0x0e3e7aac), + TOBN(0x2b44c619, 0x2525ddf8), TOBN(0x67a033eb, 0xb8ae9739), + TOBN(0x113ffec1, 0x9ef2d2e4), TOBN(0x1bf6767e, 0xd5a0ea7f), + TOBN(0x57fff75e, 0x03714c0a), TOBN(0xa23c422e, 0x0a23e9ee), + TOBN(0xdd5f6b2d, 0x540f83af), TOBN(0xc2c2c27e, 0x55ea46a7), + TOBN(0xeb6b4246, 0x672a1208), TOBN(0xd13599f7, 0xae634f7a), + TOBN(0xcf914b5c, 0xd7b32c6e), TOBN(0x61a5a640, 0xeaf61814), + TOBN(0x8dc3df8b, 0x208a1bbb), TOBN(0xef627fd6, 0xb6d79aa5), + TOBN(0x44232ffc, 0xc4c86bc8), TOBN(0xe6f9231b, 0x061539fe), + TOBN(0x1d04f25a, 0x958b9533), TOBN(0x180cf934, 0x49e8c885), + TOBN(0x89689595, 0x9884aaf7), TOBN(0xb1959be3, 0x07b348a6), + TOBN(0x96250e57, 0x3c147c87), TOBN(0xae0efb3a, 0xdd0c61f8), + TOBN(0xed00745e, 0xca8c325e), TOBN(0x3c911696, 0xecff3f70), + TOBN(0x73acbc65, 0x319ad41d), TOBN(0x7b01a020, 0xf0b1c7ef), + TOBN(0xea32b293, 0x63a1483f), TOBN(0x89eabe71, 0x7a248f96), + TOBN(0x9c6231d3, 0x343157e5), TOBN(0x93a375e5, 0xdf3c546d), + TOBN(0xe76e9343, 0x6a2afe69), TOBN(0xc4f89100, 0xe166c88e), + TOBN(0x248efd0d, 0x4f872093), TOBN(0xae0eb3ea, 0x8fe0ea61), + TOBN(0xaf89790d, 0x9d79046e), TOBN(0x4d650f2d, 0x6cee0976), + TOBN(0xa3935d9a, 0x43071eca), TOBN(0x66fcd2c9, 0x283b0bfe), + TOBN(0x0e665eb5, 0x696605f1), TOBN(0xe77e5d07, 0xa54cd38d), + TOBN(0x90ee050a, 0x43d950cf), TOBN(0x86ddebda, 0xd32e69b5), + TOBN(0x6ad94a3d, 0xfddf7415), TOBN(0xf7fa1309, 0x3f6e8d5a), + TOBN(0xc4831d1d, 0xe9957f75), TOBN(0x7de28501, 0xd5817447), + TOBN(0x6f1d7078, 0x9e2aeb6b), TOBN(0xba2b9ff4, 0xf67a53c2), + TOBN(0x36963767, 0xdf9defc3), TOBN(0x479deed3, 0x0d38022c), + TOBN(0xd2edb89b, 0x3a8631e8), TOBN(0x8de855de, 0x7a213746), + TOBN(0xb2056cb7, 0xb00c5f11), TOBN(0xdeaefbd0, 0x2c9b85e4), + TOBN(0x03f39a8d, 0xd150892d), TOBN(0x37b84686, 0x218b7985), + TOBN(0x36296dd8, 0xb7375f1a), TOBN(0x472cd4b1, 0xb78e898e), + TOBN(0x15dff651, 0xe9f05de9), TOBN(0xd4045069, 0x2ce98ba9), + TOBN(0x8466a7ae, 0x9b38024c), TOBN(0xb910e700, 0xe5a6b5ef), + TOBN(0xae1c56ea, 0xb3aa8f0d), TOBN(0xbab2a507, 0x7eee74a6), + TOBN(0x0dca11e2, 0x4b4c4620), TOBN(0xfd896e2e, 0x4c47d1f4), + TOBN(0xeb45ae53, 0x308fbd93), TOBN(0x46cd5a2e, 0x02c36fda), + TOBN(0x6a3d4e90, 0xbaa48385), TOBN(0xdd55e62e, 0x9dbe9960), + TOBN(0xa1406aa0, 0x2a81ede7), TOBN(0x6860dd14, 0xf9274ea7), + TOBN(0xcfdcb0c2, 0x80414f86), TOBN(0xff410b10, 0x22f94327), + TOBN(0x5a33cc38, 0x49ad467b), TOBN(0xefb48b6c, 0x0a7335f1), + TOBN(0x14fb54a4, 0xb153a360), TOBN(0x604aa9d2, 0xb52469cc), + TOBN(0x5e9dc486, 0x754e48e9), TOBN(0x693cb455, 0x37471e8e), + TOBN(0xfb2fd7cd, 0x8d3b37b6), TOBN(0x63345e16, 0xcf09ff07), + TOBN(0x9910ba6b, 0x23a5d896), TOBN(0x1fe19e35, 0x7fe4364e), + TOBN(0x6e1da8c3, 0x9a33c677), TOBN(0x15b4488b, 0x29fd9fd0), + TOBN(0x1f439254, 0x1a1f22bf), TOBN(0x920a8a70, 0xab8163e8), + TOBN(0x3fd1b249, 0x07e5658e), TOBN(0xf2c4f79c, 0xb6ec839b), + TOBN(0x1abbc3d0, 0x4aa38d1b), TOBN(0x3b0db35c, 0xb5d9510e), + TOBN(0x1754ac78, 0x3e60dec0), TOBN(0x53272fd7, 0xea099b33), + TOBN(0x5fb0494f, 0x07a8e107), TOBN(0x4a89e137, 0x6a8191fa), + TOBN(0xa113b7f6, 0x3c4ad544), TOBN(0x88a2e909, 0x6cb9897b), + TOBN(0x17d55de3, 0xb44a3f84), TOBN(0xacb2f344, 0x17c6c690), + TOBN(0x32088168, 0x10232390), TOBN(0xf2e8a61f, 0x6c733bf7), + TOBN(0xa774aab6, 0x9c2d7652), TOBN(0xfb5307e3, 0xed95c5bc), + TOBN(0xa05c73c2, 0x4981f110), TOBN(0x1baae31c, 0xa39458c9), + TOBN(0x1def185b, 0xcbea62e7), TOBN(0xe8ac9eae, 0xeaf63059), + TOBN(0x098a8cfd, 0x9921851c), TOBN(0xd959c3f1, 0x3abe2f5b), + TOBN(0xa4f19525, 0x20e40ae5), TOBN(0x320789e3, 0x07a24aa1), + TOBN(0x259e6927, 0x7392b2bc), TOBN(0x58f6c667, 0x1918668b), + TOBN(0xce1db2bb, 0xc55d2d8b), TOBN(0x41d58bb7, 0xf4f6ca56), + TOBN(0x7650b680, 0x8f877614), TOBN(0x905e16ba, 0xf4c349ed), + TOBN(0xed415140, 0xf661acac), TOBN(0x3b8784f0, 0xcb2270af), + TOBN(0x3bc280ac, 0x8a402cba), TOBN(0xd53f7146, 0x0937921a), + TOBN(0xc03c8ee5, 0xe5681e83), TOBN(0x62126105, 0xf6ac9e4a), + TOBN(0x9503a53f, 0x936b1a38), TOBN(0x3d45e2d4, 0x782fecbd), + TOBN(0x69a5c439, 0x76e8ae98), TOBN(0xb53b2eeb, 0xbfb4b00e), + TOBN(0xf1674712, 0x72386c89), TOBN(0x30ca34a2, 0x4268bce4), + TOBN(0x7f1ed86c, 0x78341730), TOBN(0x8ef5beb8, 0xb525e248), + TOBN(0xbbc489fd, 0xb74fbf38), TOBN(0x38a92a0e, 0x91a0b382), + TOBN(0x7a77ba3f, 0x22433ccf), TOBN(0xde8362d6, 0xa29f05a9), + TOBN(0x7f6a30ea, 0x61189afc), TOBN(0x693b5505, 0x59ef114f), + TOBN(0x50266bc0, 0xcd1797a1), TOBN(0xea17b47e, 0xf4b7af2d), + TOBN(0xd6c4025c, 0x3df9483e), TOBN(0x8cbb9d9f, 0xa37b18c9), + TOBN(0x91cbfd9c, 0x4d8424cf), TOBN(0xdb7048f1, 0xab1c3506), + TOBN(0x9eaf641f, 0x028206a3), TOBN(0xf986f3f9, 0x25bdf6ce), + TOBN(0x262143b5, 0x224c08dc), TOBN(0x2bbb09b4, 0x81b50c91), + TOBN(0xc16ed709, 0xaca8c84f), TOBN(0xa6210d9d, 0xb2850ca8), + TOBN(0x6d8df67a, 0x09cb54d6), TOBN(0x91eef6e0, 0x500919a4), + TOBN(0x90f61381, 0x0f132857), TOBN(0x9acede47, 0xf8d5028b), + TOBN(0x844d1b71, 0x90b771c3), TOBN(0x563b71e4, 0xba6426be), + TOBN(0x2efa2e83, 0xbdb802ff), TOBN(0x3410cbab, 0xab5b4a41), + TOBN(0x555b2d26, 0x30da84dd), TOBN(0xd0711ae9, 0xee1cc29a), + TOBN(0xcf3e8c60, 0x2f547792), TOBN(0x03d7d5de, 0xdc678b35), + TOBN(0x071a2fa8, 0xced806b8), TOBN(0x222e6134, 0x697f1478), + TOBN(0xdc16fd5d, 0xabfcdbbf), TOBN(0x44912ebf, 0x121b53b8), + TOBN(0xac943674, 0x2496c27c), TOBN(0x8ea3176c, 0x1ffc26b0), + TOBN(0xb6e224ac, 0x13debf2c), TOBN(0x524cc235, 0xf372a832), + TOBN(0xd706e1d8, 0x9f6f1b18), TOBN(0x2552f005, 0x44cce35b), + TOBN(0x8c8326c2, 0xa88e31fc), TOBN(0xb5468b2c, 0xf9552047), + TOBN(0xce683e88, 0x3ff90f2b), TOBN(0x77947bdf, 0x2f0a5423), + TOBN(0xd0a1b28b, 0xed56e328), TOBN(0xaee35253, 0xc20134ac), + TOBN(0x7e98367d, 0x3567962f), TOBN(0x379ed61f, 0x8188bffb), + TOBN(0x73bba348, 0xfaf130a1), TOBN(0x6c1f75e1, 0x904ed734), + TOBN(0x18956642, 0x3b4a79fc), TOBN(0xf20bc83d, 0x54ef4493), + TOBN(0x836d425d, 0x9111eca1), TOBN(0xe5b5c318, 0x009a8dcf), + TOBN(0x3360b25d, 0x13221bc5), TOBN(0x707baad2, 0x6b3eeaf7), + TOBN(0xd7279ed8, 0x743a95a1), TOBN(0x7450a875, 0x969e809f), + TOBN(0x32b6bd53, 0xe5d0338f), TOBN(0x1e77f7af, 0x2b883bbc), + TOBN(0x90da12cc, 0x1063ecd0), TOBN(0xe2697b58, 0xc315be47), + TOBN(0x2771a5bd, 0xda85d534), TOBN(0x53e78c1f, 0xff980eea), + TOBN(0xadf1cf84, 0x900385e7), TOBN(0x7d3b14f6, 0xc9387b62), + TOBN(0x170e74b0, 0xcb8f2bd2), TOBN(0x2d50b486, 0x827fa993), + TOBN(0xcdbe8c9a, 0xf6f32bab), TOBN(0x55e906b0, 0xc3b93ab8), + TOBN(0x747f22fc, 0x8fe280d1), TOBN(0xcd8e0de5, 0xb2e114ab), + TOBN(0x5ab7dbeb, 0xe10b68b0), TOBN(0x9dc63a9c, 0xa480d4b2), + TOBN(0x78d4bc3b, 0x4be1495f), TOBN(0x25eb3db8, 0x9359122d), + TOBN(0x3f8ac05b, 0x0809cbdc), TOBN(0xbf4187bb, 0xd37c702f), + TOBN(0x84cea069, 0x1416a6a5), TOBN(0x8f860c79, 0x43ef881c), + TOBN(0x41311f8a, 0x38038a5d), TOBN(0xe78c2ec0, 0xfc612067), + TOBN(0x494d2e81, 0x5ad73581), TOBN(0xb4cc9e00, 0x59604097), + TOBN(0xff558aec, 0xf3612cba), TOBN(0x35beef7a, 0x9e36c39e), + TOBN(0x1845c7cf, 0xdbcf41b9), TOBN(0x5703662a, 0xaea997c0), + TOBN(0x8b925afe, 0xe402f6d8), TOBN(0xd0a1b1ae, 0x4dd72162), + TOBN(0x9f47b375, 0x03c41c4b), TOBN(0xa023829b, 0x0391d042), + TOBN(0x5f5045c3, 0x503b8b0a), TOBN(0x123c2688, 0x98c010e5), + TOBN(0x324ec0cc, 0x36ba06ee), TOBN(0xface3115, 0x3dd2cc0c), + TOBN(0xb364f3be, 0xf333e91f), TOBN(0xef8aff73, 0x28e832b0), + TOBN(0x1e9bad04, 0x2d05841b), TOBN(0x42f0e3df, 0x356a21e2), + TOBN(0xa3270bcb, 0x4add627e), TOBN(0xb09a8158, 0xd322e711), + TOBN(0x86e326a1, 0x0fee104a), TOBN(0xad7788f8, 0x3703f65d), + TOBN(0x7e765430, 0x47bc4833), TOBN(0x6cee582b, 0x2b9b893a), + TOBN(0x9cd2a167, 0xe8f55a7b), TOBN(0xefbee3c6, 0xd9e4190d), + TOBN(0x33ee7185, 0xd40c2e9d), TOBN(0x844cc9c5, 0xa380b548), + TOBN(0x323f8ecd, 0x66926e04), TOBN(0x0001e38f, 0x8110c1ba), + TOBN(0x8dbcac12, 0xfc6a7f07), TOBN(0xd65e1d58, 0x0cec0827), + TOBN(0xd2cd4141, 0xbe76ca2d), TOBN(0x7895cf5c, 0xe892f33a), + TOBN(0x956d230d, 0x367139d2), TOBN(0xa91abd3e, 0xd012c4c1), + TOBN(0x34fa4883, 0x87eb36bf), TOBN(0xc5f07102, 0x914b8fb4), + TOBN(0x90f0e579, 0xadb9c95f), TOBN(0xfe6ea8cb, 0x28888195), + TOBN(0x7b9b5065, 0xedfa9284), TOBN(0x6c510bd2, 0x2b8c8d65), + TOBN(0xd7b8ebef, 0xcbe8aafd), TOBN(0xedb3af98, 0x96b1da07), + TOBN(0x28ff779d, 0x6295d426), TOBN(0x0c4f6ac7, 0x3fa3ad7b), + TOBN(0xec44d054, 0x8b8e2604), TOBN(0x9b32a66d, 0x8b0050e1), + TOBN(0x1f943366, 0xf0476ce2), TOBN(0x7554d953, 0xa602c7b4), + TOBN(0xbe35aca6, 0x524f2809), TOBN(0xb6881229, 0xfd4edbea), + TOBN(0xe8cd0c8f, 0x508efb63), TOBN(0x9eb5b5c8, 0x6abcefc7), + TOBN(0xf5621f5f, 0xb441ab4f), TOBN(0x79e6c046, 0xb76a2b22), + TOBN(0x74a4792c, 0xe37a1f69), TOBN(0xcbd252cb, 0x03542b60), + TOBN(0x785f65d5, 0xb3c20bd3), TOBN(0x8dea6143, 0x4fabc60c), + TOBN(0x45e21446, 0xde673629), TOBN(0x57f7aa1e, 0x703c2d21), + TOBN(0xa0e99b7f, 0x98c868c7), TOBN(0x4e42f66d, 0x8b641676), + TOBN(0x602884dc, 0x91077896), TOBN(0xa0d690cf, 0xc2c9885b), + TOBN(0xfeb4da33, 0x3b9a5187), TOBN(0x5f789598, 0x153c87ee), + TOBN(0x2192dd47, 0x52b16dba), TOBN(0xdeefc0e6, 0x3524c1b1), + TOBN(0x465ea76e, 0xe4383693), TOBN(0x79401711, 0x361b8d98), + TOBN(0xa5f9ace9, 0xf21a15cb), TOBN(0x73d26163, 0xefee9aeb), + TOBN(0xcca844b3, 0xe677016c), TOBN(0x6c122b07, 0x57eaee06), + TOBN(0xb782dce7, 0x15f09690), TOBN(0x508b9b12, 0x2dfc0fc9), + TOBN(0x9015ab4b, 0x65d89fc6), TOBN(0x5e79dab7, 0xd6d5bb0f), + TOBN(0x64f021f0, 0x6c775aa2), TOBN(0xdf09d8cc, 0x37c7eca1), + TOBN(0x9a761367, 0xef2fa506), TOBN(0xed4ca476, 0x5b81eec6), + TOBN(0x262ede36, 0x10bbb8b5), TOBN(0x0737ce83, 0x0641ada3), + TOBN(0x4c94288a, 0xe9831ccc), TOBN(0x487fc1ce, 0x8065e635), + TOBN(0xb13d7ab3, 0xb8bb3659), TOBN(0xdea5df3e, 0x855e4120), + TOBN(0xb9a18573, 0x85eb0244), TOBN(0x1a1b8ea3, 0xa7cfe0a3), + TOBN(0x3b837119, 0x67b0867c), TOBN(0x8d5e0d08, 0x9d364520), + TOBN(0x52dccc1e, 0xd930f0e3), TOBN(0xefbbcec7, 0xbf20bbaf), + TOBN(0x99cffcab, 0x0263ad10), TOBN(0xd8199e6d, 0xfcd18f8a), + TOBN(0x64e2773f, 0xe9f10617), TOBN(0x0079e8e1, 0x08704848), + TOBN(0x1169989f, 0x8a342283), TOBN(0x8097799c, 0xa83012e6), + TOBN(0xece966cb, 0x8a6a9001), TOBN(0x93b3afef, 0x072ac7fc), + TOBN(0xe6893a2a, 0x2db3d5ba), TOBN(0x263dc462, 0x89bf4fdc), + TOBN(0x8852dfc9, 0xe0396673), TOBN(0x7ac70895, 0x3af362b6), + TOBN(0xbb9cce4d, 0x5c2f342b), TOBN(0xbf80907a, 0xb52d7aae), + TOBN(0x97f3d3cd, 0x2161bcd0), TOBN(0xb25b0834, 0x0962744d), + TOBN(0xc5b18ea5, 0x6c3a1dda), TOBN(0xfe4ec7eb, 0x06c92317), + TOBN(0xb787b890, 0xad1c4afe), TOBN(0xdccd9a92, 0x0ede801a), + TOBN(0x9ac6ddda, 0xdb58da1f), TOBN(0x22bbc12f, 0xb8cae6ee), + TOBN(0xc6f8bced, 0x815c4a43), TOBN(0x8105a92c, 0xf96480c7), + TOBN(0x0dc3dbf3, 0x7a859d51), TOBN(0xe3ec7ce6, 0x3041196b), + TOBN(0xd9f64b25, 0x0d1067c9), TOBN(0xf2321321, 0x3d1f8dd8), + TOBN(0x8b5c619c, 0x76497ee8), TOBN(0x5d2b0ac6, 0xc717370e), + TOBN(0x98204cb6, 0x4fcf68e1), TOBN(0x0bdec211, 0x62bc6792), + TOBN(0x6973ccef, 0xa63b1011), TOBN(0xf9e3fa97, 0xe0de1ac5), + TOBN(0x5efb693e, 0x3d0e0c8b), TOBN(0x037248e9, 0xd2d4fcb4)}, + {TOBN(0x80802dc9, 0x1ec34f9e), TOBN(0xd8772d35, 0x33810603), + TOBN(0x3f06d66c, 0x530cb4f3), TOBN(0x7be5ed0d, 0xc475c129), + TOBN(0xcb9e3c19, 0x31e82b10), TOBN(0xc63d2857, 0xc9ff6b4c), + TOBN(0xb92118c6, 0x92a1b45e), TOBN(0x0aec4414, 0x7285bbca), + TOBN(0xfc189ae7, 0x1e29a3ef), TOBN(0xcbe906f0, 0x4c93302e), + TOBN(0xd0107914, 0xceaae10e), TOBN(0xb7a23f34, 0xb68e19f8), + TOBN(0xe9d875c2, 0xefd2119d), TOBN(0x03198c6e, 0xfcadc9c8), + TOBN(0x65591bf6, 0x4da17113), TOBN(0x3cf0bbf8, 0x3d443038), + TOBN(0xae485bb7, 0x2b724759), TOBN(0x945353e1, 0xb2d4c63a), + TOBN(0x82159d07, 0xde7d6f2c), TOBN(0x389caef3, 0x4ec5b109), + TOBN(0x4a8ebb53, 0xdb65ef14), TOBN(0x2dc2cb7e, 0xdd99de43), + TOBN(0x816fa3ed, 0x83f2405f), TOBN(0x73429bb9, 0xc14208a3), + TOBN(0xb618d590, 0xb01e6e27), TOBN(0x047e2ccd, 0xe180b2dc), + TOBN(0xd1b299b5, 0x04aea4a9), TOBN(0x412c9e1e, 0x9fa403a4), + TOBN(0x88d28a36, 0x79407552), TOBN(0x49c50136, 0xf332b8e3), + TOBN(0x3a1b6fcc, 0xe668de19), TOBN(0x178851bc, 0x75122b97), + TOBN(0xb1e13752, 0xfb85fa4c), TOBN(0xd61257ce, 0x383c8ce9), + TOBN(0xd43da670, 0xd2f74dae), TOBN(0xa35aa23f, 0xbf846bbb), + TOBN(0x5e74235d, 0x4421fc83), TOBN(0xf6df8ee0, 0xc363473b), + TOBN(0x34d7f52a, 0x3c4aa158), TOBN(0x50d05aab, 0x9bc6d22e), + TOBN(0x8c56e735, 0xa64785f4), TOBN(0xbc56637b, 0x5f29cd07), + TOBN(0x53b2bb80, 0x3ee35067), TOBN(0x50235a0f, 0xdc919270), + TOBN(0x191ab6d8, 0xf2c4aa65), TOBN(0xc3475831, 0x8396023b), + TOBN(0x80400ba5, 0xf0f805ba), TOBN(0x8881065b, 0x5ec0f80f), + TOBN(0xc370e522, 0xcc1b5e83), TOBN(0xde2d4ad1, 0x860b8bfb), + TOBN(0xad364df0, 0x67b256df), TOBN(0x8f12502e, 0xe0138997), + TOBN(0x503fa0dc, 0x7783920a), TOBN(0xe80014ad, 0xc0bc866a), + TOBN(0x3f89b744, 0xd3064ba6), TOBN(0x03511dcd, 0xcba5dba5), + TOBN(0x197dd46d, 0x95a7b1a2), TOBN(0x9c4e7ad6, 0x3c6341fb), + TOBN(0x426eca29, 0x484c2ece), TOBN(0x9211e489, 0xde7f4f8a), + TOBN(0x14997f6e, 0xc78ef1f4), TOBN(0x2b2c0910, 0x06574586), + TOBN(0x17286a6e, 0x1c3eede8), TOBN(0x25f92e47, 0x0f60e018), + TOBN(0x805c5646, 0x31890a36), TOBN(0x703ef600, 0x57feea5b), + TOBN(0x389f747c, 0xaf3c3030), TOBN(0xe0e5daeb, 0x54dd3739), + TOBN(0xfe24a4c3, 0xc9c9f155), TOBN(0x7e4bf176, 0xb5393962), + TOBN(0x37183de2, 0xaf20bf29), TOBN(0x4a1bd7b5, 0xf95a8c3b), + TOBN(0xa83b9699, 0x46191d3d), TOBN(0x281fc8dd, 0x7b87f257), + TOBN(0xb18e2c13, 0x54107588), TOBN(0x6372def7, 0x9b2bafe8), + TOBN(0xdaf4bb48, 0x0d8972ca), TOBN(0x3f2dd4b7, 0x56167a3f), + TOBN(0x1eace32d, 0x84310cf4), TOBN(0xe3bcefaf, 0xe42700aa), + TOBN(0x5fe5691e, 0xd785e73d), TOBN(0xa5db5ab6, 0x2ea60467), + TOBN(0x02e23d41, 0xdfc6514a), TOBN(0x35e8048e, 0xe03c3665), + TOBN(0x3f8b118f, 0x1adaa0f8), TOBN(0x28ec3b45, 0x84ce1a5a), + TOBN(0xe8cacc6e, 0x2c6646b8), TOBN(0x1343d185, 0xdbd0e40f), + TOBN(0xe5d7f844, 0xcaaa358c), TOBN(0x1a1db7e4, 0x9924182a), + TOBN(0xd64cd42d, 0x9c875d9a), TOBN(0xb37b515f, 0x042eeec8), + TOBN(0x4d4dd409, 0x7b165fbe), TOBN(0xfc322ed9, 0xe206eff3), + TOBN(0x7dee4102, 0x59b7e17e), TOBN(0x55a481c0, 0x8236ca00), + TOBN(0x8c885312, 0xc23fc975), TOBN(0x15715806, 0x05d6297b), + TOBN(0xa078868e, 0xf78edd39), TOBN(0x956b31e0, 0x03c45e52), + TOBN(0x470275d5, 0xff7b33a6), TOBN(0xc8d5dc3a, 0x0c7e673f), + TOBN(0x419227b4, 0x7e2f2598), TOBN(0x8b37b634, 0x4c14a975), + TOBN(0xd0667ed6, 0x8b11888c), TOBN(0x5e0e8c3e, 0x803e25dc), + TOBN(0x34e5d0dc, 0xb987a24a), TOBN(0x9f40ac3b, 0xae920323), + TOBN(0x5463de95, 0x34e0f63a), TOBN(0xa128bf92, 0x6b6328f9), + TOBN(0x491ccd7c, 0xda64f1b7), TOBN(0x7ef1ec27, 0xc47bde35), + TOBN(0xa857240f, 0xa36a2737), TOBN(0x35dc1366, 0x63621bc1), + TOBN(0x7a3a6453, 0xd4fb6897), TOBN(0x80f1a439, 0xc929319d), + TOBN(0xfc18274b, 0xf8cb0ba0), TOBN(0xb0b53766, 0x8078c5eb), + TOBN(0xfb0d4924, 0x1e01d0ef), TOBN(0x50d7c67d, 0x372ab09c), + TOBN(0xb4e370af, 0x3aeac968), TOBN(0xe4f7fee9, 0xc4b63266), + TOBN(0xb4acd4c2, 0xe3ac5664), TOBN(0xf8910bd2, 0xceb38cbf), + TOBN(0x1c3ae50c, 0xc9c0726e), TOBN(0x15309569, 0xd97b40bf), + TOBN(0x70884b7f, 0xfd5a5a1b), TOBN(0x3890896a, 0xef8314cd), + TOBN(0x58e1515c, 0xa5618c93), TOBN(0xe665432b, 0x77d942d1), + TOBN(0xb32181bf, 0xb6f767a8), TOBN(0x753794e8, 0x3a604110), + TOBN(0x09afeb7c, 0xe8c0dbcc), TOBN(0x31e02613, 0x598673a3), + TOBN(0x5d98e557, 0x7d46db00), TOBN(0xfc21fb8c, 0x9d985b28), + TOBN(0xc9040116, 0xb0843e0b), TOBN(0x53b1b3a8, 0x69b04531), + TOBN(0xdd1649f0, 0x85d7d830), TOBN(0xbb3bcc87, 0xcb7427e8), + TOBN(0x77261100, 0xc93dce83), TOBN(0x7e79da61, 0xa1922a2a), + TOBN(0x587a2b02, 0xf3149ce8), TOBN(0x147e1384, 0xde92ec83), + TOBN(0x484c83d3, 0xaf077f30), TOBN(0xea78f844, 0x0658b53a), + TOBN(0x912076c2, 0x027aec53), TOBN(0xf34714e3, 0x93c8177d), + TOBN(0x37ef5d15, 0xc2376c84), TOBN(0x8315b659, 0x3d1aa783), + TOBN(0x3a75c484, 0xef852a90), TOBN(0x0ba0c58a, 0x16086bd4), + TOBN(0x29688d7a, 0x529a6d48), TOBN(0x9c7f250d, 0xc2f19203), + TOBN(0x123042fb, 0x682e2df9), TOBN(0x2b7587e7, 0xad8121bc), + TOBN(0x30fc0233, 0xe0182a65), TOBN(0xb82ecf87, 0xe3e1128a), + TOBN(0x71682861, 0x93fb098f), TOBN(0x043e21ae, 0x85e9e6a7), + TOBN(0xab5b49d6, 0x66c834ea), TOBN(0x3be43e18, 0x47414287), + TOBN(0xf40fb859, 0x219a2a47), TOBN(0x0e6559e9, 0xcc58df3c), + TOBN(0xfe1dfe8e, 0x0c6615b4), TOBN(0x14abc8fd, 0x56459d70), + TOBN(0x7be0fa8e, 0x05de0386), TOBN(0x8e63ef68, 0xe9035c7c), + TOBN(0x116401b4, 0x53b31e91), TOBN(0x0cba7ad4, 0x4436b4d8), + TOBN(0x9151f9a0, 0x107afd66), TOBN(0xafaca8d0, 0x1f0ee4c4), + TOBN(0x75fe5c1d, 0x9ee9761c), TOBN(0x3497a16b, 0xf0c0588f), + TOBN(0x3ee2bebd, 0x0304804c), TOBN(0xa8fb9a60, 0xc2c990b9), + TOBN(0xd14d32fe, 0x39251114), TOBN(0x36bf25bc, 0xcac73366), + TOBN(0xc9562c66, 0xdba7495c), TOBN(0x324d301b, 0x46ad348b), + TOBN(0x9f46620c, 0xd670407e), TOBN(0x0ea8d4f1, 0xe3733a01), + TOBN(0xd396d532, 0xb0c324e0), TOBN(0x5b211a0e, 0x03c317cd), + TOBN(0x090d7d20, 0x5ffe7b37), TOBN(0x3b7f3efb, 0x1747d2da), + TOBN(0xa2cb525f, 0xb54fc519), TOBN(0x6e220932, 0xf66a971e), + TOBN(0xddc160df, 0xb486d440), TOBN(0x7fcfec46, 0x3fe13465), + TOBN(0x83da7e4e, 0x76e4c151), TOBN(0xd6fa48a1, 0xd8d302b5), + TOBN(0xc6304f26, 0x5872cd88), TOBN(0x806c1d3c, 0x278b90a1), + TOBN(0x3553e725, 0xcaf0bc1c), TOBN(0xff59e603, 0xbb9d8d5c), + TOBN(0xa4550f32, 0x7a0b85dd), TOBN(0xdec5720a, 0x93ecc217), + TOBN(0x0b88b741, 0x69d62213), TOBN(0x7212f245, 0x5b365955), + TOBN(0x20764111, 0xb5cae787), TOBN(0x13cb7f58, 0x1dfd3124), + TOBN(0x2dca77da, 0x1175aefb), TOBN(0xeb75466b, 0xffaae775), + TOBN(0x74d76f3b, 0xdb6cff32), TOBN(0x7440f37a, 0x61fcda9a), + TOBN(0x1bb3ac92, 0xb525028b), TOBN(0x20fbf8f7, 0xa1975f29), + TOBN(0x982692e1, 0xdf83097f), TOBN(0x28738f6c, 0x554b0800), + TOBN(0xdc703717, 0xa2ce2f2f), TOBN(0x7913b93c, 0x40814194), + TOBN(0x04924593, 0x1fe89636), TOBN(0x7b98443f, 0xf78834a6), + TOBN(0x11c6ab01, 0x5114a5a1), TOBN(0x60deb383, 0xffba5f4c), + TOBN(0x4caa54c6, 0x01a982e6), TOBN(0x1dd35e11, 0x3491cd26), + TOBN(0x973c315f, 0x7cbd6b05), TOBN(0xcab00775, 0x52494724), + TOBN(0x04659b1f, 0x6565e15a), TOBN(0xbf30f529, 0x8c8fb026), + TOBN(0xfc21641b, 0xa8a0de37), TOBN(0xe9c7a366, 0xfa5e5114), + TOBN(0xdb849ca5, 0x52f03ad8), TOBN(0xc7e8dbe9, 0x024e35c0), + TOBN(0xa1a2bbac, 0xcfc3c789), TOBN(0xbf733e7d, 0x9c26f262), + TOBN(0x882ffbf5, 0xb8444823), TOBN(0xb7224e88, 0x6bf8483b), + TOBN(0x53023b8b, 0x65bef640), TOBN(0xaabfec91, 0xd4d5f8cd), + TOBN(0xa40e1510, 0x079ea1bd), TOBN(0x1ad9addc, 0xd05d5d26), + TOBN(0xdb3f2eab, 0x13e68d4f), TOBN(0x1cff1ae2, 0x640f803f), + TOBN(0xe0e7b749, 0xd4cee117), TOBN(0x8e9f275b, 0x4036d909), + TOBN(0xce34e31d, 0x8f4d4c38), TOBN(0x22b37f69, 0xd75130fc), + TOBN(0x83e0f1fd, 0xb4014604), TOBN(0xa8ce9919, 0x89415078), + TOBN(0x82375b75, 0x41792efe), TOBN(0x4f59bf5c, 0x97d4515b), + TOBN(0xac4f324f, 0x923a277d), TOBN(0xd9bc9b7d, 0x650f3406), + TOBN(0xc6fa87d1, 0x8a39bc51), TOBN(0x82588530, 0x5ccc108f), + TOBN(0x5ced3c9f, 0x82e4c634), TOBN(0x8efb8314, 0x3a4464f8), + TOBN(0xe706381b, 0x7a1dca25), TOBN(0x6cd15a3c, 0x5a2a412b), + TOBN(0x9347a8fd, 0xbfcd8fb5), TOBN(0x31db2eef, 0x6e54cd22), + TOBN(0xc4aeb11e, 0xf8d8932f), TOBN(0x11e7c1ed, 0x344411af), + TOBN(0x2653050c, 0xdc9a151e), TOBN(0x9edbfc08, 0x3bb0a859), + TOBN(0x926c81c7, 0xfd5691e7), TOBN(0x9c1b2342, 0x6f39019a), + TOBN(0x64a81c8b, 0x7f8474b9), TOBN(0x90657c07, 0x01761819), + TOBN(0x390b3331, 0x55e0375a), TOBN(0xc676c626, 0xb6ebc47d), + TOBN(0x51623247, 0xb7d6dee8), TOBN(0x0948d927, 0x79659313), + TOBN(0x99700161, 0xe9ab35ed), TOBN(0x06cc32b4, 0x8ddde408), + TOBN(0x6f2fd664, 0x061ef338), TOBN(0x1606fa02, 0xc202e9ed), + TOBN(0x55388bc1, 0x929ba99b), TOBN(0xc4428c5e, 0x1e81df69), + TOBN(0xce2028ae, 0xf91b0b2a), TOBN(0xce870a23, 0xf03dfd3f), + TOBN(0x66ec2c87, 0x0affe8ed), TOBN(0xb205fb46, 0x284d0c00), + TOBN(0xbf5dffe7, 0x44cefa48), TOBN(0xb6fc37a8, 0xa19876d7), + TOBN(0xbecfa84c, 0x08b72863), TOBN(0xd7205ff5, 0x2576374f), + TOBN(0x80330d32, 0x8887de41), TOBN(0x5de0df0c, 0x869ea534), + TOBN(0x13f42753, 0x3c56ea17), TOBN(0xeb1f6069, 0x452b1a78), + TOBN(0x50474396, 0xe30ea15c), TOBN(0x575816a1, 0xc1494125), + TOBN(0xbe1ce55b, 0xfe6bb38f), TOBN(0xb901a948, 0x96ae30f7), + TOBN(0xe5af0f08, 0xd8fc3548), TOBN(0x5010b5d0, 0xd73bfd08), + TOBN(0x993d2880, 0x53fe655a), TOBN(0x99f2630b, 0x1c1309fd), + TOBN(0xd8677baf, 0xb4e3b76f), TOBN(0x14e51ddc, 0xb840784b), + TOBN(0x326c750c, 0xbf0092ce), TOBN(0xc83d306b, 0xf528320f), + TOBN(0xc4456715, 0x77d4715c), TOBN(0xd30019f9, 0x6b703235), + TOBN(0x207ccb2e, 0xd669e986), TOBN(0x57c824af, 0xf6dbfc28), + TOBN(0xf0eb532f, 0xd8f92a23), TOBN(0x4a557fd4, 0x9bb98fd2), + TOBN(0xa57acea7, 0xc1e6199a), TOBN(0x0c663820, 0x8b94b1ed), + TOBN(0x9b42be8f, 0xf83a9266), TOBN(0xc7741c97, 0x0101bd45), + TOBN(0x95770c11, 0x07bd9ceb), TOBN(0x1f50250a, 0x8b2e0744), + TOBN(0xf762eec8, 0x1477b654), TOBN(0xc65b900e, 0x15efe59a), + TOBN(0x88c96148, 0x9546a897), TOBN(0x7e8025b3, 0xc30b4d7c), + TOBN(0xae4065ef, 0x12045cf9), TOBN(0x6fcb2caf, 0x9ccce8bd), + TOBN(0x1fa0ba4e, 0xf2cf6525), TOBN(0xf683125d, 0xcb72c312), + TOBN(0xa01da4ea, 0xe312410e), TOBN(0x67e28677, 0x6cd8e830), + TOBN(0xabd95752, 0x98fb3f07), TOBN(0x05f11e11, 0xeef649a5), + TOBN(0xba47faef, 0x9d3472c2), TOBN(0x3adff697, 0xc77d1345), + TOBN(0x4761fa04, 0xdd15afee), TOBN(0x64f1f61a, 0xb9e69462), + TOBN(0xfa691fab, 0x9bfb9093), TOBN(0x3df8ae8f, 0xa1133dfe), + TOBN(0xcd5f8967, 0x58cc710d), TOBN(0xfbb88d50, 0x16c7fe79), + TOBN(0x8e011b4c, 0xe88c50d1), TOBN(0x7532e807, 0xa8771c4f), + TOBN(0x64c78a48, 0xe2278ee4), TOBN(0x0b283e83, 0x3845072a), + TOBN(0x98a6f291, 0x49e69274), TOBN(0xb96e9668, 0x1868b21c), + TOBN(0x38f0adc2, 0xb1a8908e), TOBN(0x90afcff7, 0x1feb829d), + TOBN(0x9915a383, 0x210b0856), TOBN(0xa5a80602, 0xdef04889), + TOBN(0x800e9af9, 0x7c64d509), TOBN(0x81382d0b, 0xb8996f6f), + TOBN(0x490eba53, 0x81927e27), TOBN(0x46c63b32, 0x4af50182), + TOBN(0x784c5fd9, 0xd3ad62ce), TOBN(0xe4fa1870, 0xf8ae8736), + TOBN(0x4ec9d0bc, 0xd7466b25), TOBN(0x84ddbe1a, 0xdb235c65), + TOBN(0x5e2645ee, 0x163c1688), TOBN(0x570bd00e, 0x00eba747), + TOBN(0xfa51b629, 0x128bfa0f), TOBN(0x92fce1bd, 0x6c1d3b68), + TOBN(0x3e7361dc, 0xb66778b1), TOBN(0x9c7d249d, 0x5561d2bb), + TOBN(0xa40b28bf, 0x0bbc6229), TOBN(0x1c83c05e, 0xdfd91497), + TOBN(0x5f9f5154, 0xf083df05), TOBN(0xbac38b3c, 0xeee66c9d), + TOBN(0xf71db7e3, 0xec0dfcfd), TOBN(0xf2ecda8e, 0x8b0a8416), + TOBN(0x52fddd86, 0x7812aa66), TOBN(0x2896ef10, 0x4e6f4272), + TOBN(0xff27186a, 0x0fe9a745), TOBN(0x08249fcd, 0x49ca70db), + TOBN(0x7425a2e6, 0x441cac49), TOBN(0xf4a0885a, 0xece5ff57), + TOBN(0x6e2cb731, 0x7d7ead58), TOBN(0xf96cf7d6, 0x1898d104), + TOBN(0xafe67c9d, 0x4f2c9a89), TOBN(0x89895a50, 0x1c7bf5bc), + TOBN(0xdc7cb8e5, 0x573cecfa), TOBN(0x66497eae, 0xd15f03e6), + TOBN(0x6bc0de69, 0x3f084420), TOBN(0x323b9b36, 0xacd532b0), + TOBN(0xcfed390a, 0x0115a3c1), TOBN(0x9414c40b, 0x2d65ca0e), + TOBN(0x641406bd, 0x2f530c78), TOBN(0x29369a44, 0x833438f2), + TOBN(0x996884f5, 0x903fa271), TOBN(0xe6da0fd2, 0xb9da921e), + TOBN(0xa6f2f269, 0x5db01e54), TOBN(0x1ee3e9bd, 0x6876214e), + TOBN(0xa26e181c, 0xe27a9497), TOBN(0x36d254e4, 0x8e215e04), + TOBN(0x42f32a6c, 0x252cabca), TOBN(0x99481487, 0x80b57614), + TOBN(0x4c4dfe69, 0x40d9cae1), TOBN(0x05869580, 0x11a10f09), + TOBN(0xca287b57, 0x3491b64b), TOBN(0x77862d5d, 0x3fd4a53b), + TOBN(0xbf94856e, 0x50349126), TOBN(0x2be30bd1, 0x71c5268f), + TOBN(0x10393f19, 0xcbb650a6), TOBN(0x639531fe, 0x778cf9fd), + TOBN(0x02556a11, 0xb2935359), TOBN(0xda38aa96, 0xaf8c126e), + TOBN(0x47dbe6c2, 0x0960167f), TOBN(0x37bbabb6, 0x501901cd), + TOBN(0xb6e979e0, 0x2c947778), TOBN(0xd69a5175, 0x7a1a1dc6), + TOBN(0xc3ed5095, 0x9d9faf0c), TOBN(0x4dd9c096, 0x1d5fa5f0), + TOBN(0xa0c4304d, 0x64f16ea8), TOBN(0x8b1cac16, 0x7e718623), + TOBN(0x0b576546, 0x7c67f03e), TOBN(0x559cf5ad, 0xcbd88c01), + TOBN(0x074877bb, 0x0e2af19a), TOBN(0x1f717ec1, 0xa1228c92), + TOBN(0x70bcb800, 0x326e8920), TOBN(0xec6e2c5c, 0x4f312804), + TOBN(0x426aea7d, 0x3fca4752), TOBN(0xf12c0949, 0x2211f62a), + TOBN(0x24beecd8, 0x7be7b6b5), TOBN(0xb77eaf4c, 0x36d7a27d), + TOBN(0x154c2781, 0xfda78fd3), TOBN(0x848a83b0, 0x264eeabe), + TOBN(0x81287ef0, 0x4ffe2bc4), TOBN(0x7b6d88c6, 0xb6b6fc2a), + TOBN(0x805fb947, 0xce417d99), TOBN(0x4b93dcc3, 0x8b916cc4), + TOBN(0x72e65bb3, 0x21273323), TOBN(0xbcc1badd, 0x6ea9886e), + TOBN(0x0e223011, 0x4bc5ee85), TOBN(0xa561be74, 0xc18ee1e4), + TOBN(0x762fd2d4, 0xa6bcf1f1), TOBN(0x50e6a5a4, 0x95231489), + TOBN(0xca96001f, 0xa00b500b), TOBN(0x5c098cfc, 0x5d7dcdf5), + TOBN(0xa64e2d2e, 0x8c446a85), TOBN(0xbae9bcf1, 0x971f3c62), + TOBN(0x4ec22683, 0x8435a2c5), TOBN(0x8ceaed6c, 0x4bad4643), + TOBN(0xe9f8fb47, 0xccccf4e3), TOBN(0xbd4f3fa4, 0x1ce3b21e), + TOBN(0xd79fb110, 0xa3db3292), TOBN(0xe28a37da, 0xb536c66a), + TOBN(0x279ce87b, 0x8e49e6a9), TOBN(0x70ccfe8d, 0xfdcec8e3), + TOBN(0x2193e4e0, 0x3ba464b2), TOBN(0x0f39d60e, 0xaca9a398), + TOBN(0x7d7932af, 0xf82c12ab), TOBN(0xd8ff50ed, 0x91e7e0f7), + TOBN(0xea961058, 0xfa28a7e0), TOBN(0xc726cf25, 0x0bf5ec74), + TOBN(0xe74d55c8, 0xdb229666), TOBN(0x0bd9abbf, 0xa57f5799), + TOBN(0x7479ef07, 0x4dfc47b3), TOBN(0xd9c65fc3, 0x0c52f91d), + TOBN(0x8e0283fe, 0x36a8bde2), TOBN(0xa32a8b5e, 0x7d4b7280), + TOBN(0x6a677c61, 0x12e83233), TOBN(0x0fbb3512, 0xdcc9bf28), + TOBN(0x562e8ea5, 0x0d780f61), TOBN(0x0db8b22b, 0x1dc4e89c), + TOBN(0x0a6fd1fb, 0x89be0144), TOBN(0x8c77d246, 0xca57113b), + TOBN(0x4639075d, 0xff09c91c), TOBN(0x5b47b17f, 0x5060824c), + TOBN(0x58aea2b0, 0x16287b52), TOBN(0xa1343520, 0xd0cd8eb0), + TOBN(0x6148b4d0, 0xc5d58573), TOBN(0xdd2b6170, 0x291c68ae), + TOBN(0xa61b3929, 0x1da3b3b7), TOBN(0x5f946d79, 0x08c4ac10), + TOBN(0x4105d4a5, 0x7217d583), TOBN(0x5061da3d, 0x25e6de5e), + TOBN(0x3113940d, 0xec1b4991), TOBN(0xf12195e1, 0x36f485ae), + TOBN(0xa7507fb2, 0x731a2ee0), TOBN(0x95057a8e, 0x6e9e196e), + TOBN(0xa3c2c911, 0x2e130136), TOBN(0x97dfbb36, 0x33c60d15), + TOBN(0xcaf3c581, 0xb300ee2b), TOBN(0x77f25d90, 0xf4bac8b8), + TOBN(0xdb1c4f98, 0x6d840cd6), TOBN(0x471d62c0, 0xe634288c), + TOBN(0x8ec2f85e, 0xcec8a161), TOBN(0x41f37cbc, 0xfa6f4ae2), + TOBN(0x6793a20f, 0x4b709985), TOBN(0x7a7bd33b, 0xefa8985b), + TOBN(0x2c6a3fbd, 0x938e6446), TOBN(0x19042619, 0x2a8d47c1), + TOBN(0x16848667, 0xcc36975f), TOBN(0x02acf168, 0x9d5f1dfb), + TOBN(0x62d41ad4, 0x613baa94), TOBN(0xb56fbb92, 0x9f684670), + TOBN(0xce610d0d, 0xe9e40569), TOBN(0x7b99c65f, 0x35489fef), + TOBN(0x0c88ad1b, 0x3df18b97), TOBN(0x81b7d9be, 0x5d0e9edb), + TOBN(0xd85218c0, 0xc716cc0a), TOBN(0xf4b5ff90, 0x85691c49), + TOBN(0xa4fd666b, 0xce356ac6), TOBN(0x17c72895, 0x4b327a7a), + TOBN(0xf93d5085, 0xda6be7de), TOBN(0xff71530e, 0x3301d34e), + TOBN(0x4cd96442, 0xd8f448e8), TOBN(0x9283d331, 0x2ed18ffa), + TOBN(0x4d33dd99, 0x2a849870), TOBN(0xa716964b, 0x41576335), + TOBN(0xff5e3a9b, 0x179be0e5), TOBN(0x5b9d6b1b, 0x83b13632), + TOBN(0x3b8bd7d4, 0xa52f313b), TOBN(0xc9dd95a0, 0x637a4660), + TOBN(0x30035962, 0x0b3e218f), TOBN(0xce1481a3, 0xc7b28a3c), + TOBN(0xab41b43a, 0x43228d83), TOBN(0x24ae1c30, 0x4ad63f99), + TOBN(0x8e525f1a, 0x46a51229), TOBN(0x14af860f, 0xcd26d2b4), + TOBN(0xd6baef61, 0x3f714aa1), TOBN(0xf51865ad, 0xeb78795e), + TOBN(0xd3e21fce, 0xe6a9d694), TOBN(0x82ceb1dd, 0x8a37b527)}}; diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/ec/p256-x86_64.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/ec/p256-x86_64.c new file mode 100644 index 0000000..412843b --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/ec/p256-x86_64.c @@ -0,0 +1,447 @@ +/* + * Copyright 2014-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright (c) 2014, Intel Corporation. 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 + * + * Originally written by Shay Gueron (1, 2), and Vlad Krasnov (1) + * (1) Intel Corporation, Israel Development Center, Haifa, Israel + * (2) University of Haifa, Israel + * + * Reference: + * S.Gueron and V.Krasnov, "Fast Prime Field Elliptic Curve Cryptography with + * 256 Bit Primes" + */ + +#include + +#include +#include +#include + +#include +#include +#include + +#include "../bn/internal.h" +#include "../delocate.h" +#include "../../internal.h" +#include "internal.h" +#include "p256-x86_64.h" + + +#if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64) && \ + !defined(OPENSSL_SMALL) + +typedef P256_POINT_AFFINE PRECOMP256_ROW[64]; + +// One converted into the Montgomery domain +static const BN_ULONG ONE[P256_LIMBS] = { + TOBN(0x00000000, 0x00000001), TOBN(0xffffffff, 0x00000000), + TOBN(0xffffffff, 0xffffffff), TOBN(0x00000000, 0xfffffffe), +}; + +// Precomputed tables for the default generator +#include "p256-x86_64-table.h" + +// Recode window to a signed digit, see util-64.c for details +static unsigned booth_recode_w5(unsigned in) { + unsigned s, d; + + s = ~((in >> 5) - 1); + d = (1 << 6) - in - 1; + d = (d & s) | (in & ~s); + d = (d >> 1) + (d & 1); + + return (d << 1) + (s & 1); +} + +static unsigned booth_recode_w7(unsigned in) { + unsigned s, d; + + s = ~((in >> 7) - 1); + d = (1 << 8) - in - 1; + d = (d & s) | (in & ~s); + d = (d >> 1) + (d & 1); + + return (d << 1) + (s & 1); +} + +// copy_conditional copies |src| to |dst| if |move| is one and leaves it as-is +// if |move| is zero. +// +// WARNING: this breaks the usual convention of constant-time functions +// returning masks. +static void copy_conditional(BN_ULONG dst[P256_LIMBS], + const BN_ULONG src[P256_LIMBS], BN_ULONG move) { + BN_ULONG mask1 = ((BN_ULONG)0) - move; + BN_ULONG mask2 = ~mask1; + + dst[0] = (src[0] & mask1) ^ (dst[0] & mask2); + dst[1] = (src[1] & mask1) ^ (dst[1] & mask2); + dst[2] = (src[2] & mask1) ^ (dst[2] & mask2); + dst[3] = (src[3] & mask1) ^ (dst[3] & mask2); + if (P256_LIMBS == 8) { + dst[4] = (src[4] & mask1) ^ (dst[4] & mask2); + dst[5] = (src[5] & mask1) ^ (dst[5] & mask2); + dst[6] = (src[6] & mask1) ^ (dst[6] & mask2); + dst[7] = (src[7] & mask1) ^ (dst[7] & mask2); + } +} + +// is_not_zero returns one iff in != 0 and zero otherwise. +// +// WARNING: this breaks the usual convention of constant-time functions +// returning masks. +// +// (define-fun is_not_zero ((in (_ BitVec 64))) (_ BitVec 64) +// (bvlshr (bvor in (bvsub #x0000000000000000 in)) #x000000000000003f) +// ) +// +// (declare-fun x () (_ BitVec 64)) +// +// (assert (and (= x #x0000000000000000) (= (is_not_zero x) #x0000000000000001))) +// (check-sat) +// +// (assert (and (not (= x #x0000000000000000)) (= (is_not_zero x) #x0000000000000000))) +// (check-sat) +// +static BN_ULONG is_not_zero(BN_ULONG in) { + in |= (0 - in); + in >>= BN_BITS2 - 1; + return in; +} + +// ecp_nistz256_mod_inverse_mont sets |r| to (|in| * 2^-256)^-1 * 2^256 mod p. +// That is, |r| is the modular inverse of |in| for input and output in the +// Montgomery domain. +static void ecp_nistz256_mod_inverse_mont(BN_ULONG r[P256_LIMBS], + const BN_ULONG in[P256_LIMBS]) { + /* The poly is ffffffff 00000001 00000000 00000000 00000000 ffffffff ffffffff + ffffffff + We use FLT and used poly-2 as exponent */ + BN_ULONG p2[P256_LIMBS]; + BN_ULONG p4[P256_LIMBS]; + BN_ULONG p8[P256_LIMBS]; + BN_ULONG p16[P256_LIMBS]; + BN_ULONG p32[P256_LIMBS]; + BN_ULONG res[P256_LIMBS]; + int i; + + ecp_nistz256_sqr_mont(res, in); + ecp_nistz256_mul_mont(p2, res, in); // 3*p + + ecp_nistz256_sqr_mont(res, p2); + ecp_nistz256_sqr_mont(res, res); + ecp_nistz256_mul_mont(p4, res, p2); // f*p + + ecp_nistz256_sqr_mont(res, p4); + ecp_nistz256_sqr_mont(res, res); + ecp_nistz256_sqr_mont(res, res); + ecp_nistz256_sqr_mont(res, res); + ecp_nistz256_mul_mont(p8, res, p4); // ff*p + + ecp_nistz256_sqr_mont(res, p8); + for (i = 0; i < 7; i++) { + ecp_nistz256_sqr_mont(res, res); + } + ecp_nistz256_mul_mont(p16, res, p8); // ffff*p + + ecp_nistz256_sqr_mont(res, p16); + for (i = 0; i < 15; i++) { + ecp_nistz256_sqr_mont(res, res); + } + ecp_nistz256_mul_mont(p32, res, p16); // ffffffff*p + + ecp_nistz256_sqr_mont(res, p32); + for (i = 0; i < 31; i++) { + ecp_nistz256_sqr_mont(res, res); + } + ecp_nistz256_mul_mont(res, res, in); + + for (i = 0; i < 32 * 4; i++) { + ecp_nistz256_sqr_mont(res, res); + } + ecp_nistz256_mul_mont(res, res, p32); + + for (i = 0; i < 32; i++) { + ecp_nistz256_sqr_mont(res, res); + } + ecp_nistz256_mul_mont(res, res, p32); + + for (i = 0; i < 16; i++) { + ecp_nistz256_sqr_mont(res, res); + } + ecp_nistz256_mul_mont(res, res, p16); + + for (i = 0; i < 8; i++) { + ecp_nistz256_sqr_mont(res, res); + } + ecp_nistz256_mul_mont(res, res, p8); + + ecp_nistz256_sqr_mont(res, res); + ecp_nistz256_sqr_mont(res, res); + ecp_nistz256_sqr_mont(res, res); + ecp_nistz256_sqr_mont(res, res); + ecp_nistz256_mul_mont(res, res, p4); + + ecp_nistz256_sqr_mont(res, res); + ecp_nistz256_sqr_mont(res, res); + ecp_nistz256_mul_mont(res, res, p2); + + ecp_nistz256_sqr_mont(res, res); + ecp_nistz256_sqr_mont(res, res); + ecp_nistz256_mul_mont(r, res, in); +} + +// ecp_nistz256_bignum_to_field_elem copies the contents of |in| to |out| and +// returns one if it fits. Otherwise it returns zero. +static int ecp_nistz256_bignum_to_field_elem(BN_ULONG out[P256_LIMBS], + const BIGNUM *in) { + return bn_copy_words(out, P256_LIMBS, in); +} + +// r = p * p_scalar +static int ecp_nistz256_windowed_mul(const EC_GROUP *group, P256_POINT *r, + const EC_POINT *p, + const EC_SCALAR *p_scalar) { + assert(p != NULL); + assert(p_scalar != NULL); + + static const unsigned kWindowSize = 5; + static const unsigned kMask = (1 << (5 /* kWindowSize */ + 1)) - 1; + + // A |P256_POINT| is (3 * 32) = 96 bytes, and the 64-byte alignment should + // add no more than 63 bytes of overhead. Thus, |table| should require + // ~1599 ((96 * 16) + 63) bytes of stack space. + alignas(64) P256_POINT table[16]; + uint8_t p_str[33]; + OPENSSL_memcpy(p_str, p_scalar->bytes, 32); + p_str[32] = 0; + + // table[0] is implicitly (0,0,0) (the point at infinity), therefore it is + // not stored. All other values are actually stored with an offset of -1 in + // table. + P256_POINT *row = table; + + if (!ecp_nistz256_bignum_to_field_elem(row[1 - 1].X, &p->X) || + !ecp_nistz256_bignum_to_field_elem(row[1 - 1].Y, &p->Y) || + !ecp_nistz256_bignum_to_field_elem(row[1 - 1].Z, &p->Z)) { + OPENSSL_PUT_ERROR(EC, EC_R_COORDINATES_OUT_OF_RANGE); + return 0; + } + + ecp_nistz256_point_double(&row[2 - 1], &row[1 - 1]); + ecp_nistz256_point_add(&row[3 - 1], &row[2 - 1], &row[1 - 1]); + ecp_nistz256_point_double(&row[4 - 1], &row[2 - 1]); + ecp_nistz256_point_double(&row[6 - 1], &row[3 - 1]); + ecp_nistz256_point_double(&row[8 - 1], &row[4 - 1]); + ecp_nistz256_point_double(&row[12 - 1], &row[6 - 1]); + ecp_nistz256_point_add(&row[5 - 1], &row[4 - 1], &row[1 - 1]); + ecp_nistz256_point_add(&row[7 - 1], &row[6 - 1], &row[1 - 1]); + ecp_nistz256_point_add(&row[9 - 1], &row[8 - 1], &row[1 - 1]); + ecp_nistz256_point_add(&row[13 - 1], &row[12 - 1], &row[1 - 1]); + ecp_nistz256_point_double(&row[14 - 1], &row[7 - 1]); + ecp_nistz256_point_double(&row[10 - 1], &row[5 - 1]); + ecp_nistz256_point_add(&row[15 - 1], &row[14 - 1], &row[1 - 1]); + ecp_nistz256_point_add(&row[11 - 1], &row[10 - 1], &row[1 - 1]); + ecp_nistz256_point_double(&row[16 - 1], &row[8 - 1]); + + BN_ULONG tmp[P256_LIMBS]; + alignas(32) P256_POINT h; + unsigned index = 255; + unsigned wvalue = p_str[(index - 1) / 8]; + wvalue = (wvalue >> ((index - 1) % 8)) & kMask; + + ecp_nistz256_select_w5(r, table, booth_recode_w5(wvalue) >> 1); + + while (index >= 5) { + if (index != 255) { + unsigned off = (index - 1) / 8; + + wvalue = p_str[off] | p_str[off + 1] << 8; + wvalue = (wvalue >> ((index - 1) % 8)) & kMask; + + wvalue = booth_recode_w5(wvalue); + + ecp_nistz256_select_w5(&h, table, wvalue >> 1); + + ecp_nistz256_neg(tmp, h.Y); + copy_conditional(h.Y, tmp, (wvalue & 1)); + + ecp_nistz256_point_add(r, r, &h); + } + + index -= kWindowSize; + + ecp_nistz256_point_double(r, r); + ecp_nistz256_point_double(r, r); + ecp_nistz256_point_double(r, r); + ecp_nistz256_point_double(r, r); + ecp_nistz256_point_double(r, r); + } + + // Final window + wvalue = p_str[0]; + wvalue = (wvalue << 1) & kMask; + + wvalue = booth_recode_w5(wvalue); + + ecp_nistz256_select_w5(&h, table, wvalue >> 1); + + ecp_nistz256_neg(tmp, h.Y); + copy_conditional(h.Y, tmp, wvalue & 1); + + ecp_nistz256_point_add(r, r, &h); + + return 1; +} + +static int ecp_nistz256_points_mul(const EC_GROUP *group, EC_POINT *r, + const EC_SCALAR *g_scalar, + const EC_POINT *p_, + const EC_SCALAR *p_scalar, BN_CTX *ctx) { + assert((p_ != NULL) == (p_scalar != NULL)); + + static const unsigned kWindowSize = 7; + static const unsigned kMask = (1 << (7 /* kWindowSize */ + 1)) - 1; + + alignas(32) union { + P256_POINT p; + P256_POINT_AFFINE a; + } t, p; + + if (g_scalar != NULL) { + uint8_t p_str[33]; + OPENSSL_memcpy(p_str, g_scalar->bytes, 32); + p_str[32] = 0; + + // First window + unsigned wvalue = (p_str[0] << 1) & kMask; + unsigned index = kWindowSize; + + wvalue = booth_recode_w7(wvalue); + + const PRECOMP256_ROW *const precomputed_table = + (const PRECOMP256_ROW *)ecp_nistz256_precomputed; + ecp_nistz256_select_w7(&p.a, precomputed_table[0], wvalue >> 1); + + ecp_nistz256_neg(p.p.Z, p.p.Y); + copy_conditional(p.p.Y, p.p.Z, wvalue & 1); + + // Convert |p| from affine to Jacobian coordinates. We set Z to zero if |p| + // is infinity and |ONE| otherwise. |p| was computed from the table, so it + // is infinity iff |wvalue >> 1| is zero. + OPENSSL_memset(p.p.Z, 0, sizeof(p.p.Z)); + copy_conditional(p.p.Z, ONE, is_not_zero(wvalue >> 1)); + + for (int i = 1; i < 37; i++) { + unsigned off = (index - 1) / 8; + wvalue = p_str[off] | p_str[off + 1] << 8; + wvalue = (wvalue >> ((index - 1) % 8)) & kMask; + index += kWindowSize; + + wvalue = booth_recode_w7(wvalue); + + ecp_nistz256_select_w7(&t.a, precomputed_table[i], wvalue >> 1); + + ecp_nistz256_neg(t.p.Z, t.a.Y); + copy_conditional(t.a.Y, t.p.Z, wvalue & 1); + + ecp_nistz256_point_add_affine(&p.p, &p.p, &t.a); + } + } + + const int p_is_infinity = g_scalar == NULL; + if (p_scalar != NULL) { + P256_POINT *out = &t.p; + if (p_is_infinity) { + out = &p.p; + } + + if (!ecp_nistz256_windowed_mul(group, out, p_, p_scalar)) { + return 0; + } + + if (!p_is_infinity) { + ecp_nistz256_point_add(&p.p, &p.p, out); + } + } + + // Not constant-time, but we're only operating on the public output. + if (!bn_set_words(&r->X, p.p.X, P256_LIMBS) || + !bn_set_words(&r->Y, p.p.Y, P256_LIMBS) || + !bn_set_words(&r->Z, p.p.Z, P256_LIMBS)) { + return 0; + } + + return 1; +} + +static int ecp_nistz256_get_affine(const EC_GROUP *group, const EC_POINT *point, + BIGNUM *x, BIGNUM *y, BN_CTX *ctx) { + BN_ULONG z_inv2[P256_LIMBS]; + BN_ULONG z_inv3[P256_LIMBS]; + BN_ULONG point_x[P256_LIMBS], point_y[P256_LIMBS], point_z[P256_LIMBS]; + + if (EC_POINT_is_at_infinity(group, point)) { + OPENSSL_PUT_ERROR(EC, EC_R_POINT_AT_INFINITY); + return 0; + } + + if (!ecp_nistz256_bignum_to_field_elem(point_x, &point->X) || + !ecp_nistz256_bignum_to_field_elem(point_y, &point->Y) || + !ecp_nistz256_bignum_to_field_elem(point_z, &point->Z)) { + OPENSSL_PUT_ERROR(EC, EC_R_COORDINATES_OUT_OF_RANGE); + return 0; + } + + ecp_nistz256_mod_inverse_mont(z_inv3, point_z); + ecp_nistz256_sqr_mont(z_inv2, z_inv3); + + // Instead of using |ecp_nistz256_from_mont| to convert the |x| coordinate + // and then calling |ecp_nistz256_from_mont| again to convert the |y| + // coordinate below, convert the common factor |z_inv2| once now, saving one + // reduction. + ecp_nistz256_from_mont(z_inv2, z_inv2); + + if (x != NULL) { + BN_ULONG x_aff[P256_LIMBS]; + ecp_nistz256_mul_mont(x_aff, z_inv2, point_x); + if (!bn_set_words(x, x_aff, P256_LIMBS)) { + OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE); + return 0; + } + } + + if (y != NULL) { + BN_ULONG y_aff[P256_LIMBS]; + ecp_nistz256_mul_mont(z_inv3, z_inv3, z_inv2); + ecp_nistz256_mul_mont(y_aff, z_inv3, point_y); + if (!bn_set_words(y, y_aff, P256_LIMBS)) { + OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE); + return 0; + } + } + + return 1; +} + +DEFINE_METHOD_FUNCTION(EC_METHOD, EC_GFp_nistz256_method) { + out->group_init = ec_GFp_mont_group_init; + out->group_finish = ec_GFp_mont_group_finish; + out->group_set_curve = ec_GFp_mont_group_set_curve; + out->point_get_affine_coordinates = ecp_nistz256_get_affine; + out->mul = ecp_nistz256_points_mul; + out->mul_public = ecp_nistz256_points_mul; + out->field_mul = ec_GFp_mont_field_mul; + out->field_sqr = ec_GFp_mont_field_sqr; + out->field_encode = ec_GFp_mont_field_encode; + out->field_decode = ec_GFp_mont_field_decode; +}; + +#endif /* !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64) && \ + !defined(OPENSSL_SMALL) */ diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/ec/p256-x86_64.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/ec/p256-x86_64.c.grpc_back new file mode 100644 index 0000000..dbe99ed --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/ec/p256-x86_64.c.grpc_back @@ -0,0 +1,447 @@ +/* + * Copyright 2014-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright (c) 2014, Intel Corporation. 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 + * + * Originally written by Shay Gueron (1, 2), and Vlad Krasnov (1) + * (1) Intel Corporation, Israel Development Center, Haifa, Israel + * (2) University of Haifa, Israel + * + * Reference: + * S.Gueron and V.Krasnov, "Fast Prime Field Elliptic Curve Cryptography with + * 256 Bit Primes" + */ + +#include + +#include +#include +#include + +#include +#include +#include + +#include "../bn/internal.h" +#include "../delocate.h" +#include "../../internal.h" +#include "internal.h" +#include "p256-x86_64.h" + + +#if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64) && \ + !defined(OPENSSL_SMALL) + +typedef P256_POINT_AFFINE PRECOMP256_ROW[64]; + +// One converted into the Montgomery domain +static const BN_ULONG ONE[P256_LIMBS] = { + TOBN(0x00000000, 0x00000001), TOBN(0xffffffff, 0x00000000), + TOBN(0xffffffff, 0xffffffff), TOBN(0x00000000, 0xfffffffe), +}; + +// Precomputed tables for the default generator +#include "p256-x86_64-table.h" + +// Recode window to a signed digit, see util-64.c for details +static unsigned booth_recode_w5(unsigned in) { + unsigned s, d; + + s = ~((in >> 5) - 1); + d = (1 << 6) - in - 1; + d = (d & s) | (in & ~s); + d = (d >> 1) + (d & 1); + + return (d << 1) + (s & 1); +} + +static unsigned booth_recode_w7(unsigned in) { + unsigned s, d; + + s = ~((in >> 7) - 1); + d = (1 << 8) - in - 1; + d = (d & s) | (in & ~s); + d = (d >> 1) + (d & 1); + + return (d << 1) + (s & 1); +} + +// copy_conditional copies |src| to |dst| if |move| is one and leaves it as-is +// if |move| is zero. +// +// WARNING: this breaks the usual convention of constant-time functions +// returning masks. +static void copy_conditional(BN_ULONG dst[P256_LIMBS], + const BN_ULONG src[P256_LIMBS], BN_ULONG move) { + BN_ULONG mask1 = ((BN_ULONG)0) - move; + BN_ULONG mask2 = ~mask1; + + dst[0] = (src[0] & mask1) ^ (dst[0] & mask2); + dst[1] = (src[1] & mask1) ^ (dst[1] & mask2); + dst[2] = (src[2] & mask1) ^ (dst[2] & mask2); + dst[3] = (src[3] & mask1) ^ (dst[3] & mask2); + if (P256_LIMBS == 8) { + dst[4] = (src[4] & mask1) ^ (dst[4] & mask2); + dst[5] = (src[5] & mask1) ^ (dst[5] & mask2); + dst[6] = (src[6] & mask1) ^ (dst[6] & mask2); + dst[7] = (src[7] & mask1) ^ (dst[7] & mask2); + } +} + +// is_not_zero returns one iff in != 0 and zero otherwise. +// +// WARNING: this breaks the usual convention of constant-time functions +// returning masks. +// +// (define-fun is_not_zero ((in (_ BitVec 64))) (_ BitVec 64) +// (bvlshr (bvor in (bvsub #x0000000000000000 in)) #x000000000000003f) +// ) +// +// (declare-fun x () (_ BitVec 64)) +// +// (assert (and (= x #x0000000000000000) (= (is_not_zero x) #x0000000000000001))) +// (check-sat) +// +// (assert (and (not (= x #x0000000000000000)) (= (is_not_zero x) #x0000000000000000))) +// (check-sat) +// +static BN_ULONG is_not_zero(BN_ULONG in) { + in |= (0 - in); + in >>= BN_BITS2 - 1; + return in; +} + +// ecp_nistz256_mod_inverse_mont sets |r| to (|in| * 2^-256)^-1 * 2^256 mod p. +// That is, |r| is the modular inverse of |in| for input and output in the +// Montgomery domain. +static void ecp_nistz256_mod_inverse_mont(BN_ULONG r[P256_LIMBS], + const BN_ULONG in[P256_LIMBS]) { + /* The poly is ffffffff 00000001 00000000 00000000 00000000 ffffffff ffffffff + ffffffff + We use FLT and used poly-2 as exponent */ + BN_ULONG p2[P256_LIMBS]; + BN_ULONG p4[P256_LIMBS]; + BN_ULONG p8[P256_LIMBS]; + BN_ULONG p16[P256_LIMBS]; + BN_ULONG p32[P256_LIMBS]; + BN_ULONG res[P256_LIMBS]; + int i; + + ecp_nistz256_sqr_mont(res, in); + ecp_nistz256_mul_mont(p2, res, in); // 3*p + + ecp_nistz256_sqr_mont(res, p2); + ecp_nistz256_sqr_mont(res, res); + ecp_nistz256_mul_mont(p4, res, p2); // f*p + + ecp_nistz256_sqr_mont(res, p4); + ecp_nistz256_sqr_mont(res, res); + ecp_nistz256_sqr_mont(res, res); + ecp_nistz256_sqr_mont(res, res); + ecp_nistz256_mul_mont(p8, res, p4); // ff*p + + ecp_nistz256_sqr_mont(res, p8); + for (i = 0; i < 7; i++) { + ecp_nistz256_sqr_mont(res, res); + } + ecp_nistz256_mul_mont(p16, res, p8); // ffff*p + + ecp_nistz256_sqr_mont(res, p16); + for (i = 0; i < 15; i++) { + ecp_nistz256_sqr_mont(res, res); + } + ecp_nistz256_mul_mont(p32, res, p16); // ffffffff*p + + ecp_nistz256_sqr_mont(res, p32); + for (i = 0; i < 31; i++) { + ecp_nistz256_sqr_mont(res, res); + } + ecp_nistz256_mul_mont(res, res, in); + + for (i = 0; i < 32 * 4; i++) { + ecp_nistz256_sqr_mont(res, res); + } + ecp_nistz256_mul_mont(res, res, p32); + + for (i = 0; i < 32; i++) { + ecp_nistz256_sqr_mont(res, res); + } + ecp_nistz256_mul_mont(res, res, p32); + + for (i = 0; i < 16; i++) { + ecp_nistz256_sqr_mont(res, res); + } + ecp_nistz256_mul_mont(res, res, p16); + + for (i = 0; i < 8; i++) { + ecp_nistz256_sqr_mont(res, res); + } + ecp_nistz256_mul_mont(res, res, p8); + + ecp_nistz256_sqr_mont(res, res); + ecp_nistz256_sqr_mont(res, res); + ecp_nistz256_sqr_mont(res, res); + ecp_nistz256_sqr_mont(res, res); + ecp_nistz256_mul_mont(res, res, p4); + + ecp_nistz256_sqr_mont(res, res); + ecp_nistz256_sqr_mont(res, res); + ecp_nistz256_mul_mont(res, res, p2); + + ecp_nistz256_sqr_mont(res, res); + ecp_nistz256_sqr_mont(res, res); + ecp_nistz256_mul_mont(r, res, in); +} + +// ecp_nistz256_bignum_to_field_elem copies the contents of |in| to |out| and +// returns one if it fits. Otherwise it returns zero. +static int ecp_nistz256_bignum_to_field_elem(BN_ULONG out[P256_LIMBS], + const BIGNUM *in) { + return bn_copy_words(out, P256_LIMBS, in); +} + +// r = p * p_scalar +static int ecp_nistz256_windowed_mul(const EC_GROUP *group, P256_POINT *r, + const EC_POINT *p, + const EC_SCALAR *p_scalar) { + assert(p != NULL); + assert(p_scalar != NULL); + + static const unsigned kWindowSize = 5; + static const unsigned kMask = (1 << (5 /* kWindowSize */ + 1)) - 1; + + // A |P256_POINT| is (3 * 32) = 96 bytes, and the 64-byte alignment should + // add no more than 63 bytes of overhead. Thus, |table| should require + // ~1599 ((96 * 16) + 63) bytes of stack space. + alignas(64) P256_POINT table[16]; + uint8_t p_str[33]; + OPENSSL_memcpy(p_str, p_scalar->bytes, 32); + p_str[32] = 0; + + // table[0] is implicitly (0,0,0) (the point at infinity), therefore it is + // not stored. All other values are actually stored with an offset of -1 in + // table. + P256_POINT *row = table; + + if (!ecp_nistz256_bignum_to_field_elem(row[1 - 1].X, &p->X) || + !ecp_nistz256_bignum_to_field_elem(row[1 - 1].Y, &p->Y) || + !ecp_nistz256_bignum_to_field_elem(row[1 - 1].Z, &p->Z)) { + OPENSSL_PUT_ERROR(EC, EC_R_COORDINATES_OUT_OF_RANGE); + return 0; + } + + ecp_nistz256_point_double(&row[2 - 1], &row[1 - 1]); + ecp_nistz256_point_add(&row[3 - 1], &row[2 - 1], &row[1 - 1]); + ecp_nistz256_point_double(&row[4 - 1], &row[2 - 1]); + ecp_nistz256_point_double(&row[6 - 1], &row[3 - 1]); + ecp_nistz256_point_double(&row[8 - 1], &row[4 - 1]); + ecp_nistz256_point_double(&row[12 - 1], &row[6 - 1]); + ecp_nistz256_point_add(&row[5 - 1], &row[4 - 1], &row[1 - 1]); + ecp_nistz256_point_add(&row[7 - 1], &row[6 - 1], &row[1 - 1]); + ecp_nistz256_point_add(&row[9 - 1], &row[8 - 1], &row[1 - 1]); + ecp_nistz256_point_add(&row[13 - 1], &row[12 - 1], &row[1 - 1]); + ecp_nistz256_point_double(&row[14 - 1], &row[7 - 1]); + ecp_nistz256_point_double(&row[10 - 1], &row[5 - 1]); + ecp_nistz256_point_add(&row[15 - 1], &row[14 - 1], &row[1 - 1]); + ecp_nistz256_point_add(&row[11 - 1], &row[10 - 1], &row[1 - 1]); + ecp_nistz256_point_double(&row[16 - 1], &row[8 - 1]); + + BN_ULONG tmp[P256_LIMBS]; + alignas(32) P256_POINT h; + unsigned index = 255; + unsigned wvalue = p_str[(index - 1) / 8]; + wvalue = (wvalue >> ((index - 1) % 8)) & kMask; + + ecp_nistz256_select_w5(r, table, booth_recode_w5(wvalue) >> 1); + + while (index >= 5) { + if (index != 255) { + unsigned off = (index - 1) / 8; + + wvalue = p_str[off] | p_str[off + 1] << 8; + wvalue = (wvalue >> ((index - 1) % 8)) & kMask; + + wvalue = booth_recode_w5(wvalue); + + ecp_nistz256_select_w5(&h, table, wvalue >> 1); + + ecp_nistz256_neg(tmp, h.Y); + copy_conditional(h.Y, tmp, (wvalue & 1)); + + ecp_nistz256_point_add(r, r, &h); + } + + index -= kWindowSize; + + ecp_nistz256_point_double(r, r); + ecp_nistz256_point_double(r, r); + ecp_nistz256_point_double(r, r); + ecp_nistz256_point_double(r, r); + ecp_nistz256_point_double(r, r); + } + + // Final window + wvalue = p_str[0]; + wvalue = (wvalue << 1) & kMask; + + wvalue = booth_recode_w5(wvalue); + + ecp_nistz256_select_w5(&h, table, wvalue >> 1); + + ecp_nistz256_neg(tmp, h.Y); + copy_conditional(h.Y, tmp, wvalue & 1); + + ecp_nistz256_point_add(r, r, &h); + + return 1; +} + +static int ecp_nistz256_points_mul(const EC_GROUP *group, EC_POINT *r, + const EC_SCALAR *g_scalar, + const EC_POINT *p_, + const EC_SCALAR *p_scalar, BN_CTX *ctx) { + assert((p_ != NULL) == (p_scalar != NULL)); + + static const unsigned kWindowSize = 7; + static const unsigned kMask = (1 << (7 /* kWindowSize */ + 1)) - 1; + + alignas(32) union { + P256_POINT p; + P256_POINT_AFFINE a; + } t, p; + + if (g_scalar != NULL) { + uint8_t p_str[33]; + OPENSSL_memcpy(p_str, g_scalar->bytes, 32); + p_str[32] = 0; + + // First window + unsigned wvalue = (p_str[0] << 1) & kMask; + unsigned index = kWindowSize; + + wvalue = booth_recode_w7(wvalue); + + const PRECOMP256_ROW *const precomputed_table = + (const PRECOMP256_ROW *)ecp_nistz256_precomputed; + ecp_nistz256_select_w7(&p.a, precomputed_table[0], wvalue >> 1); + + ecp_nistz256_neg(p.p.Z, p.p.Y); + copy_conditional(p.p.Y, p.p.Z, wvalue & 1); + + // Convert |p| from affine to Jacobian coordinates. We set Z to zero if |p| + // is infinity and |ONE| otherwise. |p| was computed from the table, so it + // is infinity iff |wvalue >> 1| is zero. + OPENSSL_memset(p.p.Z, 0, sizeof(p.p.Z)); + copy_conditional(p.p.Z, ONE, is_not_zero(wvalue >> 1)); + + for (int i = 1; i < 37; i++) { + unsigned off = (index - 1) / 8; + wvalue = p_str[off] | p_str[off + 1] << 8; + wvalue = (wvalue >> ((index - 1) % 8)) & kMask; + index += kWindowSize; + + wvalue = booth_recode_w7(wvalue); + + ecp_nistz256_select_w7(&t.a, precomputed_table[i], wvalue >> 1); + + ecp_nistz256_neg(t.p.Z, t.a.Y); + copy_conditional(t.a.Y, t.p.Z, wvalue & 1); + + ecp_nistz256_point_add_affine(&p.p, &p.p, &t.a); + } + } + + const int p_is_infinity = g_scalar == NULL; + if (p_scalar != NULL) { + P256_POINT *out = &t.p; + if (p_is_infinity) { + out = &p.p; + } + + if (!ecp_nistz256_windowed_mul(group, out, p_, p_scalar)) { + return 0; + } + + if (!p_is_infinity) { + ecp_nistz256_point_add(&p.p, &p.p, out); + } + } + + // Not constant-time, but we're only operating on the public output. + if (!bn_set_words(&r->X, p.p.X, P256_LIMBS) || + !bn_set_words(&r->Y, p.p.Y, P256_LIMBS) || + !bn_set_words(&r->Z, p.p.Z, P256_LIMBS)) { + return 0; + } + + return 1; +} + +static int ecp_nistz256_get_affine(const EC_GROUP *group, const EC_POINT *point, + BIGNUM *x, BIGNUM *y, BN_CTX *ctx) { + BN_ULONG z_inv2[P256_LIMBS]; + BN_ULONG z_inv3[P256_LIMBS]; + BN_ULONG point_x[P256_LIMBS], point_y[P256_LIMBS], point_z[P256_LIMBS]; + + if (EC_POINT_is_at_infinity(group, point)) { + OPENSSL_PUT_ERROR(EC, EC_R_POINT_AT_INFINITY); + return 0; + } + + if (!ecp_nistz256_bignum_to_field_elem(point_x, &point->X) || + !ecp_nistz256_bignum_to_field_elem(point_y, &point->Y) || + !ecp_nistz256_bignum_to_field_elem(point_z, &point->Z)) { + OPENSSL_PUT_ERROR(EC, EC_R_COORDINATES_OUT_OF_RANGE); + return 0; + } + + ecp_nistz256_mod_inverse_mont(z_inv3, point_z); + ecp_nistz256_sqr_mont(z_inv2, z_inv3); + + // Instead of using |ecp_nistz256_from_mont| to convert the |x| coordinate + // and then calling |ecp_nistz256_from_mont| again to convert the |y| + // coordinate below, convert the common factor |z_inv2| once now, saving one + // reduction. + ecp_nistz256_from_mont(z_inv2, z_inv2); + + if (x != NULL) { + BN_ULONG x_aff[P256_LIMBS]; + ecp_nistz256_mul_mont(x_aff, z_inv2, point_x); + if (!bn_set_words(x, x_aff, P256_LIMBS)) { + OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE); + return 0; + } + } + + if (y != NULL) { + BN_ULONG y_aff[P256_LIMBS]; + ecp_nistz256_mul_mont(z_inv3, z_inv3, z_inv2); + ecp_nistz256_mul_mont(y_aff, z_inv3, point_y); + if (!bn_set_words(y, y_aff, P256_LIMBS)) { + OPENSSL_PUT_ERROR(EC, ERR_R_MALLOC_FAILURE); + return 0; + } + } + + return 1; +} + +DEFINE_METHOD_FUNCTION(EC_METHOD, EC_GFp_nistz256_method) { + out->group_init = ec_GFp_mont_group_init; + out->group_finish = ec_GFp_mont_group_finish; + out->group_set_curve = ec_GFp_mont_group_set_curve; + out->point_get_affine_coordinates = ecp_nistz256_get_affine; + out->mul = ecp_nistz256_points_mul; + out->mul_public = ecp_nistz256_points_mul; + out->field_mul = ec_GFp_mont_field_mul; + out->field_sqr = ec_GFp_mont_field_sqr; + out->field_encode = ec_GFp_mont_field_encode; + out->field_decode = ec_GFp_mont_field_decode; +}; + +#endif /* !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64) && \ + !defined(OPENSSL_SMALL) */ diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/ec/p256-x86_64.h b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/ec/p256-x86_64.h new file mode 100644 index 0000000..4d4526a --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/ec/p256-x86_64.h @@ -0,0 +1,117 @@ +/* + * Copyright 2014-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright (c) 2014, Intel Corporation. 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 + * + * Originally written by Shay Gueron (1, 2), and Vlad Krasnov (1) + * (1) Intel Corporation, Israel Development Center, Haifa, Israel + * (2) University of Haifa, Israel + * + * Reference: + * S.Gueron and V.Krasnov, "Fast Prime Field Elliptic Curve Cryptography with + * 256 Bit Primes" + */ + +#ifndef OPENSSL_HEADER_EC_P256_X86_64_H +#define OPENSSL_HEADER_EC_P256_X86_64_H + +#include + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +#if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64) && \ + !defined(OPENSSL_SMALL) + +// P-256 field operations. +// +// An element mod P in P-256 is represented as a little-endian array of +// |P256_LIMBS| |BN_ULONG|s, spanning the full range of values. +// +// The following functions take fully-reduced inputs mod P and give +// fully-reduced outputs. They may be used in-place. + +#define P256_LIMBS (256 / BN_BITS2) + +// ecp_nistz256_neg sets |res| to -|a| mod P. +void ecp_nistz256_neg(BN_ULONG res[P256_LIMBS], const BN_ULONG a[P256_LIMBS]); + +// ecp_nistz256_mul_mont sets |res| to |a| * |b| * 2^-256 mod P. +void ecp_nistz256_mul_mont(BN_ULONG res[P256_LIMBS], + const BN_ULONG a[P256_LIMBS], + const BN_ULONG b[P256_LIMBS]); + +// ecp_nistz256_sqr_mont sets |res| to |a| * |a| * 2^-256 mod P. +void ecp_nistz256_sqr_mont(BN_ULONG res[P256_LIMBS], + const BN_ULONG a[P256_LIMBS]); + +// ecp_nistz256_from_mont sets |res| to |in|, converted from Montgomery domain +// by multiplying with 1. +static inline void ecp_nistz256_from_mont(BN_ULONG res[P256_LIMBS], + const BN_ULONG in[P256_LIMBS]) { + static const BN_ULONG ONE[P256_LIMBS] = { 1 }; + ecp_nistz256_mul_mont(res, in, ONE); +} + + +// P-256 point operations. +// +// The following functions may be used in-place. All coordinates are in the +// Montgomery domain. + +// A P256_POINT represents a P-256 point in Jacobian coordinates. +typedef struct { + BN_ULONG X[P256_LIMBS]; + BN_ULONG Y[P256_LIMBS]; + BN_ULONG Z[P256_LIMBS]; +} P256_POINT; + +// A P256_POINT_AFFINE represents a P-256 point in affine coordinates. Infinity +// is encoded as (0, 0). +typedef struct { + BN_ULONG X[P256_LIMBS]; + BN_ULONG Y[P256_LIMBS]; +} P256_POINT_AFFINE; + +// ecp_nistz256_select_w5 sets |*val| to |in_t[index-1]| if 1 <= |index| <= 16 +// and all zeros (the point at infinity) if |index| is 0. This is done in +// constant time. +void ecp_nistz256_select_w5(P256_POINT *val, const P256_POINT in_t[16], + int index); + +// ecp_nistz256_select_w7 sets |*val| to |in_t[index-1]| if 1 <= |index| <= 64 +// and all zeros (the point at infinity) if |index| is 0. This is done in +// constant time. +void ecp_nistz256_select_w7(P256_POINT_AFFINE *val, + const P256_POINT_AFFINE in_t[64], int index); + +// ecp_nistz256_point_double sets |r| to |a| doubled. +void ecp_nistz256_point_double(P256_POINT *r, const P256_POINT *a); + +// ecp_nistz256_point_add adds |a| to |b| and places the result in |r|. +void ecp_nistz256_point_add(P256_POINT *r, const P256_POINT *a, + const P256_POINT *b); + +// ecp_nistz256_point_add_affine adds |a| to |b| and places the result in +// |r|. |a| and |b| must not represent the same point unless they are both +// infinity. +void ecp_nistz256_point_add_affine(P256_POINT *r, const P256_POINT *a, + const P256_POINT_AFFINE *b); + +#endif /* !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64) && \ + !defined(OPENSSL_SMALL) */ + + +#if defined(__cplusplus) +} // extern C++ +#endif + +#endif // OPENSSL_HEADER_EC_P256_X86_64_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/ec/p256-x86_64.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/ec/p256-x86_64.h.grpc_back new file mode 100644 index 0000000..9226124 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/ec/p256-x86_64.h.grpc_back @@ -0,0 +1,117 @@ +/* + * Copyright 2014-2016 The OpenSSL Project Authors. All Rights Reserved. + * Copyright (c) 2014, Intel Corporation. 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 + * + * Originally written by Shay Gueron (1, 2), and Vlad Krasnov (1) + * (1) Intel Corporation, Israel Development Center, Haifa, Israel + * (2) University of Haifa, Israel + * + * Reference: + * S.Gueron and V.Krasnov, "Fast Prime Field Elliptic Curve Cryptography with + * 256 Bit Primes" + */ + +#ifndef OPENSSL_HEADER_EC_P256_X86_64_H +#define OPENSSL_HEADER_EC_P256_X86_64_H + +#include + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +#if !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64) && \ + !defined(OPENSSL_SMALL) + +// P-256 field operations. +// +// An element mod P in P-256 is represented as a little-endian array of +// |P256_LIMBS| |BN_ULONG|s, spanning the full range of values. +// +// The following functions take fully-reduced inputs mod P and give +// fully-reduced outputs. They may be used in-place. + +#define P256_LIMBS (256 / BN_BITS2) + +// ecp_nistz256_neg sets |res| to -|a| mod P. +void ecp_nistz256_neg(BN_ULONG res[P256_LIMBS], const BN_ULONG a[P256_LIMBS]); + +// ecp_nistz256_mul_mont sets |res| to |a| * |b| * 2^-256 mod P. +void ecp_nistz256_mul_mont(BN_ULONG res[P256_LIMBS], + const BN_ULONG a[P256_LIMBS], + const BN_ULONG b[P256_LIMBS]); + +// ecp_nistz256_sqr_mont sets |res| to |a| * |a| * 2^-256 mod P. +void ecp_nistz256_sqr_mont(BN_ULONG res[P256_LIMBS], + const BN_ULONG a[P256_LIMBS]); + +// ecp_nistz256_from_mont sets |res| to |in|, converted from Montgomery domain +// by multiplying with 1. +static inline void ecp_nistz256_from_mont(BN_ULONG res[P256_LIMBS], + const BN_ULONG in[P256_LIMBS]) { + static const BN_ULONG ONE[P256_LIMBS] = { 1 }; + ecp_nistz256_mul_mont(res, in, ONE); +} + + +// P-256 point operations. +// +// The following functions may be used in-place. All coordinates are in the +// Montgomery domain. + +// A P256_POINT represents a P-256 point in Jacobian coordinates. +typedef struct { + BN_ULONG X[P256_LIMBS]; + BN_ULONG Y[P256_LIMBS]; + BN_ULONG Z[P256_LIMBS]; +} P256_POINT; + +// A P256_POINT_AFFINE represents a P-256 point in affine coordinates. Infinity +// is encoded as (0, 0). +typedef struct { + BN_ULONG X[P256_LIMBS]; + BN_ULONG Y[P256_LIMBS]; +} P256_POINT_AFFINE; + +// ecp_nistz256_select_w5 sets |*val| to |in_t[index-1]| if 1 <= |index| <= 16 +// and all zeros (the point at infinity) if |index| is 0. This is done in +// constant time. +void ecp_nistz256_select_w5(P256_POINT *val, const P256_POINT in_t[16], + int index); + +// ecp_nistz256_select_w7 sets |*val| to |in_t[index-1]| if 1 <= |index| <= 64 +// and all zeros (the point at infinity) if |index| is 0. This is done in +// constant time. +void ecp_nistz256_select_w7(P256_POINT_AFFINE *val, + const P256_POINT_AFFINE in_t[64], int index); + +// ecp_nistz256_point_double sets |r| to |a| doubled. +void ecp_nistz256_point_double(P256_POINT *r, const P256_POINT *a); + +// ecp_nistz256_point_add adds |a| to |b| and places the result in |r|. +void ecp_nistz256_point_add(P256_POINT *r, const P256_POINT *a, + const P256_POINT *b); + +// ecp_nistz256_point_add_affine adds |a| to |b| and places the result in +// |r|. |a| and |b| must not represent the same point unless they are both +// infinity. +void ecp_nistz256_point_add_affine(P256_POINT *r, const P256_POINT *a, + const P256_POINT_AFFINE *b); + +#endif /* !defined(OPENSSL_NO_ASM) && defined(OPENSSL_X86_64) && \ + !defined(OPENSSL_SMALL) */ + + +#if defined(__cplusplus) +} // extern C++ +#endif + +#endif // OPENSSL_HEADER_EC_P256_X86_64_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/ec/simple.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/ec/simple.c new file mode 100644 index 0000000..b00451f --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/ec/simple.c @@ -0,0 +1,1046 @@ +/* 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. */ + +#include + +#include + +#include +#include +#include + +#include "internal.h" +#include "../../internal.h" + + +// 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 here 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); + BN_init(&group->one); + 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); + BN_free(&group->one); +} + +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)) { + OPENSSL_PUT_ERROR(EC, 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); + // Store the field in minimal form, so it can be used with |BN_ULONG| arrays. + bn_set_minimal_width(&group->field); + + // group->a + if (!BN_nnmod(tmp_a, a, &group->field, 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, &group->field, ctx)) { + goto err; + } + if (group->meth->field_encode && + !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)); + + if (group->meth->field_encode != NULL) { + if (!group->meth->field_encode(group, &group->one, BN_value_one(), ctx)) { + goto err; + } + } else if (!BN_copy(&group->one, BN_value_one())) { + goto err; + } + + ret = 1; + +err: + BN_CTX_end(ctx); + 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 && !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 && !group->meth->field_decode(group, a, &group->a, ctx)) { + goto err; + } + if (b != NULL && !group->meth->field_decode(group, b, &group->b, ctx)) { + goto err; + } + } else { + if (a != NULL && !BN_copy(a, &group->a)) { + goto err; + } + if (b != NULL && !BN_copy(b, &group->b)) { + goto err; + } + } + } + + ret = 1; + +err: + BN_CTX_free(new_ctx); + return ret; +} + +unsigned ec_GFp_simple_group_get_degree(const EC_GROUP *group) { + return BN_num_bits(&group->field); +} + +int ec_GFp_simple_point_init(EC_POINT *point) { + BN_init(&point->X); + BN_init(&point->Y); + BN_init(&point->Z); + + return 1; +} + +void ec_GFp_simple_point_finish(EC_POINT *point) { + BN_free(&point->X); + BN_free(&point->Y); + BN_free(&point->Z); +} + +int ec_GFp_simple_point_copy(EC_POINT *dest, const EC_POINT *src) { + if (!BN_copy(&dest->X, &src->X) || + !BN_copy(&dest->Y, &src->Y) || + !BN_copy(&dest->Z, &src->Z)) { + return 0; + } + + return 1; +} + +int ec_GFp_simple_point_set_to_infinity(const EC_GROUP *group, + EC_POINT *point) { + BN_zero(&point->Z); + return 1; +} + +static int set_Jprojective_coordinate_GFp(const EC_GROUP *group, BIGNUM *out, + const BIGNUM *in, BN_CTX *ctx) { + if (in == NULL) { + return 1; + } + if (BN_is_negative(in) || + BN_cmp(in, &group->field) >= 0) { + OPENSSL_PUT_ERROR(EC, EC_R_COORDINATES_OUT_OF_RANGE); + return 0; + } + if (group->meth->field_encode) { + return group->meth->field_encode(group, out, in, ctx); + } + return BN_copy(out, in) != NULL; +} + +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) { + OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + BN_CTX *new_ctx = NULL; + int ret = 0; + + if (ctx == NULL) { + ctx = new_ctx = BN_CTX_new(); + if (ctx == NULL) { + return 0; + } + } + + if (!set_Jprojective_coordinate_GFp(group, &point->X, x, ctx) || + !set_Jprojective_coordinate_GFp(group, &point->Y, y, ctx) || + !BN_copy(&point->Z, &group->one)) { + goto err; + } + + ret = 1; + +err: + 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 + int b_Z_is_one = BN_cmp(&b->Z, &group->one) == 0; + + if (b_Z_is_one) { + if (!BN_copy(n1, &a->X) || !BN_copy(n2, &a->Y)) { + goto end; + } + // n1 = X_a + // n2 = Y_a + } else { + if (!field_sqr(group, n0, &b->Z, ctx) || + !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) || + !field_mul(group, n2, &a->Y, n0, ctx)) { + goto end; + } + // n2 = Y_a * Z_b^3 + } + + // n3, n4 + int a_Z_is_one = BN_cmp(&a->Z, &group->one) == 0; + if (a_Z_is_one) { + if (!BN_copy(n3, &b->X) || !BN_copy(n4, &b->Y)) { + goto end; + } + // n3 = X_b + // n4 = Y_b + } else { + if (!field_sqr(group, n0, &a->Z, ctx) || + !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) || + !field_mul(group, n4, &b->Y, n0, ctx)) { + goto end; + } + // n4 = Y_b * Z_a^3 + } + + // n5, n6 + if (!bn_mod_sub_consttime(n5, n1, n3, p, ctx) || + !bn_mod_sub_consttime(n6, n2, n4, p, ctx)) { + 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); + ret = 1; + goto end; + } + } + + // 'n7', 'n8' + if (!bn_mod_add_consttime(n1, n1, n3, p, ctx) || + !bn_mod_add_consttime(n2, n2, n4, p, ctx)) { + 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; + } + } + + // Z_r = Z_a * Z_b * n5 + + // X_r + if (!field_sqr(group, n0, n6, ctx) || + !field_sqr(group, n4, n5, ctx) || + !field_mul(group, n3, n1, n4, ctx) || + !bn_mod_sub_consttime(&r->X, n0, n3, p, ctx)) { + goto end; + } + // X_r = n6^2 - n5^2 * 'n7' + + // 'n9' + if (!bn_mod_lshift1_consttime(n0, &r->X, p, ctx) || + !bn_mod_sub_consttime(n0, n3, n0, p, ctx)) { + goto end; + } + // n9 = n5^2 * 'n7' - 2 * X_r + + // Y_r + if (!field_mul(group, n0, n0, n6, ctx) || + !field_mul(group, n5, n4, n5, ctx)) { + goto end; // now n5 is n5^3 + } + if (!field_mul(group, n1, n2, n5, ctx) || + !bn_mod_sub_consttime(n0, n0, n1, p, ctx)) { + goto end; + } + if (BN_is_odd(n0) && !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); + } + 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); + 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 (BN_cmp(&a->Z, &group->one) == 0) { + if (!field_sqr(group, n0, &a->X, ctx) || + !bn_mod_lshift1_consttime(n1, n0, p, ctx) || + !bn_mod_add_consttime(n0, n0, n1, p, ctx) || + !bn_mod_add_consttime(n1, n0, &group->a, p, ctx)) { + goto err; + } + // n1 = 3 * X_a^2 + a_curve + } else if (group->a_is_minus3) { + if (!field_sqr(group, n1, &a->Z, ctx) || + !bn_mod_add_consttime(n0, &a->X, n1, p, ctx) || + !bn_mod_sub_consttime(n2, &a->X, n1, p, ctx) || + !field_mul(group, n1, n0, n2, ctx) || + !bn_mod_lshift1_consttime(n0, n1, p, ctx) || + !bn_mod_add_consttime(n1, n0, n1, p, ctx)) { + 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) || + !bn_mod_lshift1_consttime(n1, n0, p, ctx) || + !bn_mod_add_consttime(n0, n0, n1, p, ctx) || + !field_sqr(group, n1, &a->Z, ctx) || + !field_sqr(group, n1, n1, ctx) || + !field_mul(group, n1, n1, &group->a, ctx) || + !bn_mod_add_consttime(n1, n1, n0, p, ctx)) { + goto err; + } + // n1 = 3 * X_a^2 + a_curve * Z_a^4 + } + + // Z_r + if (BN_cmp(&a->Z, &group->one) == 0) { + 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_consttime(&r->Z, n0, p, ctx)) { + goto err; + } + // Z_r = 2 * Y_a * Z_a + + // n2 + if (!field_sqr(group, n3, &a->Y, ctx) || + !field_mul(group, n2, &a->X, n3, ctx) || + !bn_mod_lshift_consttime(n2, n2, 2, p, ctx)) { + goto err; + } + // n2 = 4 * X_a * Y_a^2 + + // X_r + if (!bn_mod_lshift1_consttime(n0, n2, p, ctx) || + !field_sqr(group, &r->X, n1, ctx) || + !bn_mod_sub_consttime(&r->X, &r->X, n0, p, ctx)) { + goto err; + } + // X_r = n1^2 - 2 * n2 + + // n3 + if (!field_sqr(group, n0, n3, ctx) || + !bn_mod_lshift_consttime(n3, n0, 3, p, ctx)) { + goto err; + } + // n3 = 8 * Y_a^4 + + // Y_r + if (!bn_mod_sub_consttime(n0, n2, &r->X, p, ctx) || + !field_mul(group, n0, n1, n0, ctx) || + !bn_mod_sub_consttime(&r->Y, n0, n3, p, ctx)) { + goto err; + } + // Y_r = n1 * (n2 - X_r) - n3 + + ret = 1; + +err: + BN_CTX_end(ctx); + 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 = 0; + + 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 0; + } + } + + 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 (BN_cmp(&point->Z, &group->one) != 0) { + if (!field_sqr(group, tmp, &point->Z, ctx) || + !field_sqr(group, Z4, tmp, ctx) || + !field_mul(group, Z6, Z4, tmp, ctx)) { + goto err; + } + + // rh := (rh + a*Z^4)*X + if (group->a_is_minus3) { + if (!bn_mod_lshift1_consttime(tmp, Z4, p, ctx) || + !bn_mod_add_consttime(tmp, tmp, Z4, p, ctx) || + !bn_mod_sub_consttime(rh, rh, tmp, p, ctx) || + !field_mul(group, rh, rh, &point->X, ctx)) { + goto err; + } + } else { + if (!field_mul(group, tmp, Z4, &group->a, ctx) || + !bn_mod_add_consttime(rh, rh, tmp, p, ctx) || + !field_mul(group, rh, rh, &point->X, ctx)) { + goto err; + } + } + + // rh := rh + b*Z^6 + if (!field_mul(group, tmp, &group->b, Z6, ctx) || + !bn_mod_add_consttime(rh, rh, tmp, p, ctx)) { + goto err; + } + } else { + // rh := (rh + a)*X + if (!bn_mod_add_consttime(rh, rh, &group->a, p, ctx) || + !field_mul(group, rh, rh, &point->X, ctx)) { + goto err; + } + // rh := rh + b + if (!bn_mod_add_consttime(rh, rh, &group->b, p, ctx)) { + 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); + 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_GFp_simple_is_at_infinity(group, a)) { + return ec_GFp_simple_is_at_infinity(group, b) ? 0 : 1; + } + + if (ec_GFp_simple_is_at_infinity(group, b)) { + return 1; + } + + int a_Z_is_one = BN_cmp(&a->Z, &group->one) == 0; + int b_Z_is_one = BN_cmp(&b->Z, &group->one) == 0; + + 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) || + !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) || + !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) || + !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) || + !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); + 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 (BN_cmp(&point->Z, &group->one) == 0 || + 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) || + !EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx)) { + goto err; + } + if (BN_cmp(&point->Z, &group->one) != 0) { + OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR); + goto err; + } + + ret = 1; + +err: + BN_CTX_end(ctx); + 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; + 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; + } + OPENSSL_memset(prod_Z, 0, num * sizeof(prod_Z[0])); + for (size_t 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 (BN_copy(prod_Z[0], &group->one) == NULL) { + goto err; + } + } + + for (size_t 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. We use |BN_mod_inverse_odd| instead of doing a constant- + // time inversion using Fermat's Little Theorem because this function is + // usually only used for converting multiples of a public key point to + // affine, and a public key point isn't secret. If we were to use Fermat's + // Little Theorem then the cost of the inversion would usually be so high + // that converting the multiples to affine would be counterproductive. + int no_inverse; + if (!BN_mod_inverse_odd(tmp, &no_inverse, prod_Z[num - 1], &group->field, + ctx)) { + OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB); + goto err; + } + + if (group->meth->field_encode != NULL) { + // 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) || + !group->meth->field_encode(group, tmp, tmp, ctx)) { + goto err; + } + } + + for (size_t 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)) { + continue; + } + + // 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) || + // Update tmp to satisfy the loop invariant for i - 1. + !group->meth->field_mul(group, tmp, tmp, &points[i]->Z, ctx) || + // Replace points[i]->Z by its inverse. + !BN_copy(&points[i]->Z, tmp_Z)) { + goto err; + } + } + + // Replace points[0]->Z by its inverse. + if (!BN_is_zero(&points[0]->Z) && !BN_copy(&points[0]->Z, tmp)) { + goto err; + } + + // Finally, fix up the X and Y coordinates for all points. + for (size_t 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) || + !group->meth->field_mul(group, &p->X, &p->X, tmp, ctx) || + !group->meth->field_mul(group, tmp, tmp, &p->Z, ctx) || + !group->meth->field_mul(group, &p->Y, &p->Y, tmp, ctx)) { + goto err; + } + + if (BN_copy(&p->Z, &group->one) == NULL) { + goto err; + } + } + } + + ret = 1; + +err: + BN_CTX_end(ctx); + BN_CTX_free(new_ctx); + if (prod_Z != NULL) { + for (size_t 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/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/ec/simple.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/ec/simple.c.grpc_back new file mode 100644 index 0000000..90c61d5 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/ec/simple.c.grpc_back @@ -0,0 +1,1046 @@ +/* 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. */ + +#include + +#include + +#include +#include +#include + +#include "internal.h" +#include "../../internal.h" + + +// 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 here 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); + BN_init(&group->one); + 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); + BN_free(&group->one); +} + +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)) { + OPENSSL_PUT_ERROR(EC, 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); + // Store the field in minimal form, so it can be used with |BN_ULONG| arrays. + bn_set_minimal_width(&group->field); + + // group->a + if (!BN_nnmod(tmp_a, a, &group->field, 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, &group->field, ctx)) { + goto err; + } + if (group->meth->field_encode && + !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)); + + if (group->meth->field_encode != NULL) { + if (!group->meth->field_encode(group, &group->one, BN_value_one(), ctx)) { + goto err; + } + } else if (!BN_copy(&group->one, BN_value_one())) { + goto err; + } + + ret = 1; + +err: + BN_CTX_end(ctx); + 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 && !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 && !group->meth->field_decode(group, a, &group->a, ctx)) { + goto err; + } + if (b != NULL && !group->meth->field_decode(group, b, &group->b, ctx)) { + goto err; + } + } else { + if (a != NULL && !BN_copy(a, &group->a)) { + goto err; + } + if (b != NULL && !BN_copy(b, &group->b)) { + goto err; + } + } + } + + ret = 1; + +err: + BN_CTX_free(new_ctx); + return ret; +} + +unsigned ec_GFp_simple_group_get_degree(const EC_GROUP *group) { + return BN_num_bits(&group->field); +} + +int ec_GFp_simple_point_init(EC_POINT *point) { + BN_init(&point->X); + BN_init(&point->Y); + BN_init(&point->Z); + + return 1; +} + +void ec_GFp_simple_point_finish(EC_POINT *point) { + BN_free(&point->X); + BN_free(&point->Y); + BN_free(&point->Z); +} + +int ec_GFp_simple_point_copy(EC_POINT *dest, const EC_POINT *src) { + if (!BN_copy(&dest->X, &src->X) || + !BN_copy(&dest->Y, &src->Y) || + !BN_copy(&dest->Z, &src->Z)) { + return 0; + } + + return 1; +} + +int ec_GFp_simple_point_set_to_infinity(const EC_GROUP *group, + EC_POINT *point) { + BN_zero(&point->Z); + return 1; +} + +static int set_Jprojective_coordinate_GFp(const EC_GROUP *group, BIGNUM *out, + const BIGNUM *in, BN_CTX *ctx) { + if (in == NULL) { + return 1; + } + if (BN_is_negative(in) || + BN_cmp(in, &group->field) >= 0) { + OPENSSL_PUT_ERROR(EC, EC_R_COORDINATES_OUT_OF_RANGE); + return 0; + } + if (group->meth->field_encode) { + return group->meth->field_encode(group, out, in, ctx); + } + return BN_copy(out, in) != NULL; +} + +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) { + OPENSSL_PUT_ERROR(EC, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + BN_CTX *new_ctx = NULL; + int ret = 0; + + if (ctx == NULL) { + ctx = new_ctx = BN_CTX_new(); + if (ctx == NULL) { + return 0; + } + } + + if (!set_Jprojective_coordinate_GFp(group, &point->X, x, ctx) || + !set_Jprojective_coordinate_GFp(group, &point->Y, y, ctx) || + !BN_copy(&point->Z, &group->one)) { + goto err; + } + + ret = 1; + +err: + 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 + int b_Z_is_one = BN_cmp(&b->Z, &group->one) == 0; + + if (b_Z_is_one) { + if (!BN_copy(n1, &a->X) || !BN_copy(n2, &a->Y)) { + goto end; + } + // n1 = X_a + // n2 = Y_a + } else { + if (!field_sqr(group, n0, &b->Z, ctx) || + !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) || + !field_mul(group, n2, &a->Y, n0, ctx)) { + goto end; + } + // n2 = Y_a * Z_b^3 + } + + // n3, n4 + int a_Z_is_one = BN_cmp(&a->Z, &group->one) == 0; + if (a_Z_is_one) { + if (!BN_copy(n3, &b->X) || !BN_copy(n4, &b->Y)) { + goto end; + } + // n3 = X_b + // n4 = Y_b + } else { + if (!field_sqr(group, n0, &a->Z, ctx) || + !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) || + !field_mul(group, n4, &b->Y, n0, ctx)) { + goto end; + } + // n4 = Y_b * Z_a^3 + } + + // n5, n6 + if (!bn_mod_sub_consttime(n5, n1, n3, p, ctx) || + !bn_mod_sub_consttime(n6, n2, n4, p, ctx)) { + 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); + ret = 1; + goto end; + } + } + + // 'n7', 'n8' + if (!bn_mod_add_consttime(n1, n1, n3, p, ctx) || + !bn_mod_add_consttime(n2, n2, n4, p, ctx)) { + 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; + } + } + + // Z_r = Z_a * Z_b * n5 + + // X_r + if (!field_sqr(group, n0, n6, ctx) || + !field_sqr(group, n4, n5, ctx) || + !field_mul(group, n3, n1, n4, ctx) || + !bn_mod_sub_consttime(&r->X, n0, n3, p, ctx)) { + goto end; + } + // X_r = n6^2 - n5^2 * 'n7' + + // 'n9' + if (!bn_mod_lshift1_consttime(n0, &r->X, p, ctx) || + !bn_mod_sub_consttime(n0, n3, n0, p, ctx)) { + goto end; + } + // n9 = n5^2 * 'n7' - 2 * X_r + + // Y_r + if (!field_mul(group, n0, n0, n6, ctx) || + !field_mul(group, n5, n4, n5, ctx)) { + goto end; // now n5 is n5^3 + } + if (!field_mul(group, n1, n2, n5, ctx) || + !bn_mod_sub_consttime(n0, n0, n1, p, ctx)) { + goto end; + } + if (BN_is_odd(n0) && !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); + } + 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); + 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 (BN_cmp(&a->Z, &group->one) == 0) { + if (!field_sqr(group, n0, &a->X, ctx) || + !bn_mod_lshift1_consttime(n1, n0, p, ctx) || + !bn_mod_add_consttime(n0, n0, n1, p, ctx) || + !bn_mod_add_consttime(n1, n0, &group->a, p, ctx)) { + goto err; + } + // n1 = 3 * X_a^2 + a_curve + } else if (group->a_is_minus3) { + if (!field_sqr(group, n1, &a->Z, ctx) || + !bn_mod_add_consttime(n0, &a->X, n1, p, ctx) || + !bn_mod_sub_consttime(n2, &a->X, n1, p, ctx) || + !field_mul(group, n1, n0, n2, ctx) || + !bn_mod_lshift1_consttime(n0, n1, p, ctx) || + !bn_mod_add_consttime(n1, n0, n1, p, ctx)) { + 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) || + !bn_mod_lshift1_consttime(n1, n0, p, ctx) || + !bn_mod_add_consttime(n0, n0, n1, p, ctx) || + !field_sqr(group, n1, &a->Z, ctx) || + !field_sqr(group, n1, n1, ctx) || + !field_mul(group, n1, n1, &group->a, ctx) || + !bn_mod_add_consttime(n1, n1, n0, p, ctx)) { + goto err; + } + // n1 = 3 * X_a^2 + a_curve * Z_a^4 + } + + // Z_r + if (BN_cmp(&a->Z, &group->one) == 0) { + 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_consttime(&r->Z, n0, p, ctx)) { + goto err; + } + // Z_r = 2 * Y_a * Z_a + + // n2 + if (!field_sqr(group, n3, &a->Y, ctx) || + !field_mul(group, n2, &a->X, n3, ctx) || + !bn_mod_lshift_consttime(n2, n2, 2, p, ctx)) { + goto err; + } + // n2 = 4 * X_a * Y_a^2 + + // X_r + if (!bn_mod_lshift1_consttime(n0, n2, p, ctx) || + !field_sqr(group, &r->X, n1, ctx) || + !bn_mod_sub_consttime(&r->X, &r->X, n0, p, ctx)) { + goto err; + } + // X_r = n1^2 - 2 * n2 + + // n3 + if (!field_sqr(group, n0, n3, ctx) || + !bn_mod_lshift_consttime(n3, n0, 3, p, ctx)) { + goto err; + } + // n3 = 8 * Y_a^4 + + // Y_r + if (!bn_mod_sub_consttime(n0, n2, &r->X, p, ctx) || + !field_mul(group, n0, n1, n0, ctx) || + !bn_mod_sub_consttime(&r->Y, n0, n3, p, ctx)) { + goto err; + } + // Y_r = n1 * (n2 - X_r) - n3 + + ret = 1; + +err: + BN_CTX_end(ctx); + 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 = 0; + + 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 0; + } + } + + 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 (BN_cmp(&point->Z, &group->one) != 0) { + if (!field_sqr(group, tmp, &point->Z, ctx) || + !field_sqr(group, Z4, tmp, ctx) || + !field_mul(group, Z6, Z4, tmp, ctx)) { + goto err; + } + + // rh := (rh + a*Z^4)*X + if (group->a_is_minus3) { + if (!bn_mod_lshift1_consttime(tmp, Z4, p, ctx) || + !bn_mod_add_consttime(tmp, tmp, Z4, p, ctx) || + !bn_mod_sub_consttime(rh, rh, tmp, p, ctx) || + !field_mul(group, rh, rh, &point->X, ctx)) { + goto err; + } + } else { + if (!field_mul(group, tmp, Z4, &group->a, ctx) || + !bn_mod_add_consttime(rh, rh, tmp, p, ctx) || + !field_mul(group, rh, rh, &point->X, ctx)) { + goto err; + } + } + + // rh := rh + b*Z^6 + if (!field_mul(group, tmp, &group->b, Z6, ctx) || + !bn_mod_add_consttime(rh, rh, tmp, p, ctx)) { + goto err; + } + } else { + // rh := (rh + a)*X + if (!bn_mod_add_consttime(rh, rh, &group->a, p, ctx) || + !field_mul(group, rh, rh, &point->X, ctx)) { + goto err; + } + // rh := rh + b + if (!bn_mod_add_consttime(rh, rh, &group->b, p, ctx)) { + 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); + 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_GFp_simple_is_at_infinity(group, a)) { + return ec_GFp_simple_is_at_infinity(group, b) ? 0 : 1; + } + + if (ec_GFp_simple_is_at_infinity(group, b)) { + return 1; + } + + int a_Z_is_one = BN_cmp(&a->Z, &group->one) == 0; + int b_Z_is_one = BN_cmp(&b->Z, &group->one) == 0; + + 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) || + !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) || + !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) || + !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) || + !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); + 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 (BN_cmp(&point->Z, &group->one) == 0 || + 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) || + !EC_POINT_set_affine_coordinates_GFp(group, point, x, y, ctx)) { + goto err; + } + if (BN_cmp(&point->Z, &group->one) != 0) { + OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR); + goto err; + } + + ret = 1; + +err: + BN_CTX_end(ctx); + 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; + 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; + } + OPENSSL_memset(prod_Z, 0, num * sizeof(prod_Z[0])); + for (size_t 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 (BN_copy(prod_Z[0], &group->one) == NULL) { + goto err; + } + } + + for (size_t 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. We use |BN_mod_inverse_odd| instead of doing a constant- + // time inversion using Fermat's Little Theorem because this function is + // usually only used for converting multiples of a public key point to + // affine, and a public key point isn't secret. If we were to use Fermat's + // Little Theorem then the cost of the inversion would usually be so high + // that converting the multiples to affine would be counterproductive. + int no_inverse; + if (!BN_mod_inverse_odd(tmp, &no_inverse, prod_Z[num - 1], &group->field, + ctx)) { + OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB); + goto err; + } + + if (group->meth->field_encode != NULL) { + // 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) || + !group->meth->field_encode(group, tmp, tmp, ctx)) { + goto err; + } + } + + for (size_t 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)) { + continue; + } + + // 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) || + // Update tmp to satisfy the loop invariant for i - 1. + !group->meth->field_mul(group, tmp, tmp, &points[i]->Z, ctx) || + // Replace points[i]->Z by its inverse. + !BN_copy(&points[i]->Z, tmp_Z)) { + goto err; + } + } + + // Replace points[0]->Z by its inverse. + if (!BN_is_zero(&points[0]->Z) && !BN_copy(&points[0]->Z, tmp)) { + goto err; + } + + // Finally, fix up the X and Y coordinates for all points. + for (size_t 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) || + !group->meth->field_mul(group, &p->X, &p->X, tmp, ctx) || + !group->meth->field_mul(group, tmp, tmp, &p->Z, ctx) || + !group->meth->field_mul(group, &p->Y, &p->Y, tmp, ctx)) { + goto err; + } + + if (BN_copy(&p->Z, &group->one) == NULL) { + goto err; + } + } + } + + ret = 1; + +err: + BN_CTX_end(ctx); + BN_CTX_free(new_ctx); + if (prod_Z != NULL) { + for (size_t 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/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/ec/util.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/ec/util.c new file mode 100644 index 0000000..85d663f --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/ec/util.c @@ -0,0 +1,104 @@ +/* Copyright (c) 2015, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include + +#include "internal.h" + +// 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(uint8_t *sign, uint8_t *digit, + uint8_t in) { + uint8_t 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; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/ec/util.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/ec/util.c.grpc_back new file mode 100644 index 0000000..7303a15 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/ec/util.c.grpc_back @@ -0,0 +1,104 @@ +/* Copyright (c) 2015, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include + +#include "internal.h" + +// 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(uint8_t *sign, uint8_t *digit, + uint8_t in) { + uint8_t 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; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/ec/wnaf.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/ec/wnaf.c new file mode 100644 index 0000000..5e4202e --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/ec/wnaf.c @@ -0,0 +1,354 @@ +/* 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. */ + +#include + +#include + +#include +#include +#include +#include +#include + +#include "internal.h" +#include "../bn/internal.h" +#include "../../internal.h" + + +// This file implements the wNAF-based interleaving multi-exponentiation method +// at: +// http://link.springer.com/chapter/10.1007%2F3-540-45537-X_13 +// http://www.bmoeller.de/pdf/TI-01-08.multiexp.pdf + +int ec_compute_wNAF(const EC_GROUP *group, int8_t *out, const EC_SCALAR *scalar, + size_t bits, int w) { + // 'int8_t' can represent integers with absolute values less than 2^7. + if (w <= 0 || w > 7 || bits == 0) { + OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR); + return 0; + } + int bit = 1 << w; // at most 128 + int next_bit = bit << 1; // at most 256 + int mask = next_bit - 1; // at most 255 + + int window_val = scalar->words[0] & mask; + size_t j = 0; + // If j+w+1 >= bits, window_val will not increase. + while (window_val != 0 || j + w + 1 < bits) { + 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 >= bits) { + // 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)) { + OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR); + return 0; + } + + 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) { + OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR); + return 0; + } + } + + out[j++] = digit; + + window_val >>= 1; + window_val += + bit * bn_is_bit_set_words(scalar->words, group->order.width, j + w); + + if (window_val > next_bit) { + OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR); + return 0; + } + } + + // Fill the rest of the wNAF with zeros. + if (j > bits + 1) { + OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR); + return 0; + } + for (size_t i = j; i < bits + 1; i++) { + out[i] = 0; + } + + return 1; +} + +// TODO: table should be optimised for the wNAF-based implementation, +// sometimes smaller windows will give better performance +// (thus the boundaries should be increased) +static size_t window_bits_for_scalar_size(size_t b) { + if (b >= 300) { + return 4; + } + + if (b >= 70) { + return 3; + } + + if (b >= 20) { + return 2; + } + + return 1; +} + +// EC_WNAF_MAX_WINDOW_BITS is the largest value returned by +// |window_bits_for_scalar_size|. +#define EC_WNAF_MAX_WINDOW_BITS 4 + +// compute_precomp sets |out[i]| to a newly-allocated |EC_POINT| containing +// (2*i+1)*p, for i from 0 to |len|. It returns one on success and +// zero on error. +static int compute_precomp(const EC_GROUP *group, EC_POINT **out, + const EC_POINT *p, size_t len, BN_CTX *ctx) { + out[0] = EC_POINT_new(group); + if (out[0] == NULL || + !EC_POINT_copy(out[0], p)) { + return 0; + } + + int ret = 0; + EC_POINT *two_p = EC_POINT_new(group); + if (two_p == NULL || + !EC_POINT_dbl(group, two_p, p, ctx)) { + goto err; + } + + for (size_t i = 1; i < len; i++) { + out[i] = EC_POINT_new(group); + if (out[i] == NULL || + !EC_POINT_add(group, out[i], out[i - 1], two_p, ctx)) { + goto err; + } + } + + ret = 1; + +err: + EC_POINT_free(two_p); + return ret; +} + +static int lookup_precomp(const EC_GROUP *group, EC_POINT *out, + EC_POINT *const *precomp, int digit, BN_CTX *ctx) { + if (digit < 0) { + digit = -digit; + return EC_POINT_copy(out, precomp[digit >> 1]) && + EC_POINT_invert(group, out, ctx); + } + + return EC_POINT_copy(out, precomp[digit >> 1]); +} + +int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const EC_SCALAR *g_scalar, + const EC_POINT *p, const EC_SCALAR *p_scalar, BN_CTX *ctx) { + BN_CTX *new_ctx = NULL; + EC_POINT *precomp_storage[2 * (1 << (EC_WNAF_MAX_WINDOW_BITS - 1))] = {NULL}; + EC_POINT **g_precomp = NULL, **p_precomp = NULL; + int8_t g_wNAF[EC_MAX_SCALAR_BYTES * 8 + 1]; + int8_t p_wNAF[EC_MAX_SCALAR_BYTES * 8 + 1]; + EC_POINT *tmp = NULL; + int ret = 0; + + if (ctx == NULL) { + ctx = new_ctx = BN_CTX_new(); + if (ctx == NULL) { + goto err; + } + } + + size_t bits = BN_num_bits(&group->order); + size_t wsize = window_bits_for_scalar_size(bits); + size_t wNAF_len = bits + 1; + size_t precomp_len = (size_t)1 << (wsize - 1); + + OPENSSL_COMPILE_ASSERT( + OPENSSL_ARRAY_SIZE(g_wNAF) == OPENSSL_ARRAY_SIZE(p_wNAF), + g_wNAF_and_p_wNAF_are_different_sizes); + + if (wNAF_len > OPENSSL_ARRAY_SIZE(g_wNAF) || + 2 * precomp_len > OPENSSL_ARRAY_SIZE(precomp_storage)) { + OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR); + goto err; + } + + // TODO(davidben): |mul_public| is for ECDSA verification which can assume + // non-NULL inputs, but this code is also used for |mul| which cannot. It's + // not constant-time, so replace the generic |mul| and remove the NULL checks. + size_t total_precomp = 0; + if (g_scalar != NULL) { + const EC_POINT *g = EC_GROUP_get0_generator(group); + if (g == NULL) { + OPENSSL_PUT_ERROR(EC, EC_R_UNDEFINED_GENERATOR); + goto err; + } + g_precomp = precomp_storage + total_precomp; + total_precomp += precomp_len; + if (!ec_compute_wNAF(group, g_wNAF, g_scalar, bits, wsize) || + !compute_precomp(group, g_precomp, g, precomp_len, ctx)) { + goto err; + } + } + + if (p_scalar != NULL) { + p_precomp = precomp_storage + total_precomp; + total_precomp += precomp_len; + if (!ec_compute_wNAF(group, p_wNAF, p_scalar, bits, wsize) || + !compute_precomp(group, p_precomp, p, precomp_len, ctx)) { + goto err; + } + } + + tmp = EC_POINT_new(group); + if (tmp == NULL || + // |window_bits_for_scalar_size| assumes we do this step. + !EC_POINTs_make_affine(group, total_precomp, precomp_storage, ctx)) { + goto err; + } + + int r_is_at_infinity = 1; + for (size_t k = wNAF_len - 1; k < wNAF_len; k--) { + if (!r_is_at_infinity && !EC_POINT_dbl(group, r, r, ctx)) { + goto err; + } + + if (g_scalar != NULL) { + if (g_wNAF[k] != 0) { + if (!lookup_precomp(group, tmp, g_precomp, g_wNAF[k], ctx)) { + goto err; + } + if (r_is_at_infinity) { + if (!EC_POINT_copy(r, tmp)) { + goto err; + } + r_is_at_infinity = 0; + } else if (!EC_POINT_add(group, r, r, tmp, ctx)) { + goto err; + } + } + } + + if (p_scalar != NULL) { + if (p_wNAF[k] != 0) { + if (!lookup_precomp(group, tmp, p_precomp, p_wNAF[k], ctx)) { + goto err; + } + if (r_is_at_infinity) { + if (!EC_POINT_copy(r, tmp)) { + goto err; + } + r_is_at_infinity = 0; + } else if (!EC_POINT_add(group, r, r, tmp, ctx)) { + goto err; + } + } + } + } + + if (r_is_at_infinity && + !EC_POINT_set_to_infinity(group, r)) { + goto err; + } + + ret = 1; + +err: + BN_CTX_free(new_ctx); + EC_POINT_free(tmp); + OPENSSL_cleanse(&g_wNAF, sizeof(g_wNAF)); + OPENSSL_cleanse(&p_wNAF, sizeof(p_wNAF)); + for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(precomp_storage); i++) { + EC_POINT_free(precomp_storage[i]); + } + return ret; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/ec/wnaf.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/ec/wnaf.c.grpc_back new file mode 100644 index 0000000..7bc0bc7 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/ec/wnaf.c.grpc_back @@ -0,0 +1,354 @@ +/* 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. */ + +#include + +#include + +#include +#include +#include +#include +#include + +#include "internal.h" +#include "../bn/internal.h" +#include "../../internal.h" + + +// This file implements the wNAF-based interleaving multi-exponentiation method +// at: +// http://link.springer.com/chapter/10.1007%2F3-540-45537-X_13 +// http://www.bmoeller.de/pdf/TI-01-08.multiexp.pdf + +int ec_compute_wNAF(const EC_GROUP *group, int8_t *out, const EC_SCALAR *scalar, + size_t bits, int w) { + // 'int8_t' can represent integers with absolute values less than 2^7. + if (w <= 0 || w > 7 || bits == 0) { + OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR); + return 0; + } + int bit = 1 << w; // at most 128 + int next_bit = bit << 1; // at most 256 + int mask = next_bit - 1; // at most 255 + + int window_val = scalar->words[0] & mask; + size_t j = 0; + // If j+w+1 >= bits, window_val will not increase. + while (window_val != 0 || j + w + 1 < bits) { + 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 >= bits) { + // 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)) { + OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR); + return 0; + } + + 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) { + OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR); + return 0; + } + } + + out[j++] = digit; + + window_val >>= 1; + window_val += + bit * bn_is_bit_set_words(scalar->words, group->order.width, j + w); + + if (window_val > next_bit) { + OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR); + return 0; + } + } + + // Fill the rest of the wNAF with zeros. + if (j > bits + 1) { + OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR); + return 0; + } + for (size_t i = j; i < bits + 1; i++) { + out[i] = 0; + } + + return 1; +} + +// TODO: table should be optimised for the wNAF-based implementation, +// sometimes smaller windows will give better performance +// (thus the boundaries should be increased) +static size_t window_bits_for_scalar_size(size_t b) { + if (b >= 300) { + return 4; + } + + if (b >= 70) { + return 3; + } + + if (b >= 20) { + return 2; + } + + return 1; +} + +// EC_WNAF_MAX_WINDOW_BITS is the largest value returned by +// |window_bits_for_scalar_size|. +#define EC_WNAF_MAX_WINDOW_BITS 4 + +// compute_precomp sets |out[i]| to a newly-allocated |EC_POINT| containing +// (2*i+1)*p, for i from 0 to |len|. It returns one on success and +// zero on error. +static int compute_precomp(const EC_GROUP *group, EC_POINT **out, + const EC_POINT *p, size_t len, BN_CTX *ctx) { + out[0] = EC_POINT_new(group); + if (out[0] == NULL || + !EC_POINT_copy(out[0], p)) { + return 0; + } + + int ret = 0; + EC_POINT *two_p = EC_POINT_new(group); + if (two_p == NULL || + !EC_POINT_dbl(group, two_p, p, ctx)) { + goto err; + } + + for (size_t i = 1; i < len; i++) { + out[i] = EC_POINT_new(group); + if (out[i] == NULL || + !EC_POINT_add(group, out[i], out[i - 1], two_p, ctx)) { + goto err; + } + } + + ret = 1; + +err: + EC_POINT_free(two_p); + return ret; +} + +static int lookup_precomp(const EC_GROUP *group, EC_POINT *out, + EC_POINT *const *precomp, int digit, BN_CTX *ctx) { + if (digit < 0) { + digit = -digit; + return EC_POINT_copy(out, precomp[digit >> 1]) && + EC_POINT_invert(group, out, ctx); + } + + return EC_POINT_copy(out, precomp[digit >> 1]); +} + +int ec_wNAF_mul(const EC_GROUP *group, EC_POINT *r, const EC_SCALAR *g_scalar, + const EC_POINT *p, const EC_SCALAR *p_scalar, BN_CTX *ctx) { + BN_CTX *new_ctx = NULL; + EC_POINT *precomp_storage[2 * (1 << (EC_WNAF_MAX_WINDOW_BITS - 1))] = {NULL}; + EC_POINT **g_precomp = NULL, **p_precomp = NULL; + int8_t g_wNAF[EC_MAX_SCALAR_BYTES * 8 + 1]; + int8_t p_wNAF[EC_MAX_SCALAR_BYTES * 8 + 1]; + EC_POINT *tmp = NULL; + int ret = 0; + + if (ctx == NULL) { + ctx = new_ctx = BN_CTX_new(); + if (ctx == NULL) { + goto err; + } + } + + size_t bits = BN_num_bits(&group->order); + size_t wsize = window_bits_for_scalar_size(bits); + size_t wNAF_len = bits + 1; + size_t precomp_len = (size_t)1 << (wsize - 1); + + OPENSSL_COMPILE_ASSERT( + OPENSSL_ARRAY_SIZE(g_wNAF) == OPENSSL_ARRAY_SIZE(p_wNAF), + g_wNAF_and_p_wNAF_are_different_sizes); + + if (wNAF_len > OPENSSL_ARRAY_SIZE(g_wNAF) || + 2 * precomp_len > OPENSSL_ARRAY_SIZE(precomp_storage)) { + OPENSSL_PUT_ERROR(EC, ERR_R_INTERNAL_ERROR); + goto err; + } + + // TODO(davidben): |mul_public| is for ECDSA verification which can assume + // non-NULL inputs, but this code is also used for |mul| which cannot. It's + // not constant-time, so replace the generic |mul| and remove the NULL checks. + size_t total_precomp = 0; + if (g_scalar != NULL) { + const EC_POINT *g = EC_GROUP_get0_generator(group); + if (g == NULL) { + OPENSSL_PUT_ERROR(EC, EC_R_UNDEFINED_GENERATOR); + goto err; + } + g_precomp = precomp_storage + total_precomp; + total_precomp += precomp_len; + if (!ec_compute_wNAF(group, g_wNAF, g_scalar, bits, wsize) || + !compute_precomp(group, g_precomp, g, precomp_len, ctx)) { + goto err; + } + } + + if (p_scalar != NULL) { + p_precomp = precomp_storage + total_precomp; + total_precomp += precomp_len; + if (!ec_compute_wNAF(group, p_wNAF, p_scalar, bits, wsize) || + !compute_precomp(group, p_precomp, p, precomp_len, ctx)) { + goto err; + } + } + + tmp = EC_POINT_new(group); + if (tmp == NULL || + // |window_bits_for_scalar_size| assumes we do this step. + !EC_POINTs_make_affine(group, total_precomp, precomp_storage, ctx)) { + goto err; + } + + int r_is_at_infinity = 1; + for (size_t k = wNAF_len - 1; k < wNAF_len; k--) { + if (!r_is_at_infinity && !EC_POINT_dbl(group, r, r, ctx)) { + goto err; + } + + if (g_scalar != NULL) { + if (g_wNAF[k] != 0) { + if (!lookup_precomp(group, tmp, g_precomp, g_wNAF[k], ctx)) { + goto err; + } + if (r_is_at_infinity) { + if (!EC_POINT_copy(r, tmp)) { + goto err; + } + r_is_at_infinity = 0; + } else if (!EC_POINT_add(group, r, r, tmp, ctx)) { + goto err; + } + } + } + + if (p_scalar != NULL) { + if (p_wNAF[k] != 0) { + if (!lookup_precomp(group, tmp, p_precomp, p_wNAF[k], ctx)) { + goto err; + } + if (r_is_at_infinity) { + if (!EC_POINT_copy(r, tmp)) { + goto err; + } + r_is_at_infinity = 0; + } else if (!EC_POINT_add(group, r, r, tmp, ctx)) { + goto err; + } + } + } + } + + if (r_is_at_infinity && + !EC_POINT_set_to_infinity(group, r)) { + goto err; + } + + ret = 1; + +err: + BN_CTX_free(new_ctx); + EC_POINT_free(tmp); + OPENSSL_cleanse(&g_wNAF, sizeof(g_wNAF)); + OPENSSL_cleanse(&p_wNAF, sizeof(p_wNAF)); + for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(precomp_storage); i++) { + EC_POINT_free(precomp_storage[i]); + } + return ret; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/ecdsa/ecdsa.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/ecdsa/ecdsa.c new file mode 100644 index 0000000..eed1718 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/ecdsa/ecdsa.c @@ -0,0 +1,458 @@ +/* ==================================================================== + * 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 +#include + +#include +#include +#include +#include +#include + +#include "../bn/internal.h" +#include "../ec/internal.h" +#include "../../internal.h" + + +// EC_LOOSE_SCALAR is like |EC_SCALAR| but is bounded by 2^|BN_num_bits(order)| +// rather than |order|. +typedef union { + // bytes is the representation of the scalar in little-endian order. + uint8_t bytes[EC_MAX_SCALAR_BYTES]; + BN_ULONG words[EC_MAX_SCALAR_WORDS]; +} EC_LOOSE_SCALAR; + +static void scalar_add_loose(const EC_GROUP *group, EC_LOOSE_SCALAR *r, + const EC_LOOSE_SCALAR *a, const EC_SCALAR *b) { + // Add and subtract one copy of |order| if necessary. We have: + // |a| + |b| < 2^BN_num_bits(order) + order + // so this leaves |r| < 2^BN_num_bits(order). + const BIGNUM *order = &group->order; + BN_ULONG carry = bn_add_words(r->words, a->words, b->words, order->width); + EC_LOOSE_SCALAR tmp; + BN_ULONG v = + bn_sub_words(tmp.words, r->words, order->d, order->width) - carry; + bn_select_words(r->words, 0u - v, r->words /* tmp < 0 */, + tmp.words /* tmp >= 0 */, order->width); +} + +static int scalar_mod_mul_montgomery(const EC_GROUP *group, EC_SCALAR *r, + const EC_SCALAR *a, const EC_SCALAR *b) { + const BIGNUM *order = &group->order; + return bn_mod_mul_montgomery_small(r->words, order->width, a->words, + order->width, b->words, order->width, + group->order_mont); +} + +static int scalar_mod_mul_montgomery_loose(const EC_GROUP *group, EC_SCALAR *r, + const EC_LOOSE_SCALAR *a, + const EC_SCALAR *b) { + // Although |a| is loose, |bn_mod_mul_montgomery_small| only requires the + // product not exceed R * |order|. |b| is fully reduced and |a| < + // 2^BN_num_bits(order) <= R, so this holds. + const BIGNUM *order = &group->order; + return bn_mod_mul_montgomery_small(r->words, order->width, a->words, + order->width, b->words, order->width, + group->order_mont); +} + +// digest_to_scalar interprets |digest_len| bytes from |digest| as a scalar for +// ECDSA. Note this value is not fully reduced modulo the order, only the +// correct number of bits. +static void digest_to_scalar(const EC_GROUP *group, EC_LOOSE_SCALAR *out, + const uint8_t *digest, size_t digest_len) { + const BIGNUM *order = &group->order; + size_t num_bits = BN_num_bits(order); + // Need to truncate digest if it is too long: first truncate whole bytes. + if (8 * digest_len > num_bits) { + digest_len = (num_bits + 7) / 8; + } + OPENSSL_memset(out, 0, sizeof(EC_SCALAR)); + for (size_t i = 0; i < digest_len; i++) { + out->bytes[i] = digest[digest_len - 1 - i]; + } + + // If still too long truncate remaining bits with a shift + if (8 * digest_len > num_bits) { + size_t shift = 8 - (num_bits & 0x7); + for (int i = 0; i < order->width - 1; i++) { + out->words[i] = + (out->words[i] >> shift) | (out->words[i + 1] << (BN_BITS2 - shift)); + } + out->words[order->width - 1] >>= shift; + } +} + +// field_element_to_scalar reduces |r| modulo |group->order|. |r| must +// previously have been reduced modulo |group->field|. +static int field_element_to_scalar(const EC_GROUP *group, BIGNUM *r) { + // We must have p < 2×order, assuming p is not tiny (p >= 17). Thus rather we + // can reduce by performing at most one subtraction. + // + // Proof: We only work with prime order curves, so the number of points on + // the curve is the order. Thus Hasse's theorem gives: + // + // |order - (p + 1)| <= 2×sqrt(p) + // p + 1 - order <= 2×sqrt(p) + // p + 1 - 2×sqrt(p) <= order + // p + 1 - 2×(p/4) < order (p/4 > sqrt(p) for p >= 17) + // p/2 < p/2 + 1 < order + // p < 2×order + // + // Additionally, one can manually check this property for built-in curves. It + // is enforced for legacy custom curves in |EC_GROUP_set_generator|. + // + // TODO(davidben): Introduce |EC_FIELD_ELEMENT|, make this a function from + // |EC_FIELD_ELEMENT| to |EC_SCALAR|, and cut out the |BIGNUM|. Does this need + // to be constant-time for signing? |r| is the x-coordinate for kG, which is + // public unless k was rerolled because |s| was zero. + assert(!BN_is_negative(r)); + assert(BN_cmp(r, &group->field) < 0); + if (BN_cmp(r, &group->order) >= 0 && + !BN_sub(r, r, &group->order)) { + return 0; + } + assert(!BN_is_negative(r)); + assert(BN_cmp(r, &group->order) < 0); + return 1; +} + +ECDSA_SIG *ECDSA_SIG_new(void) { + ECDSA_SIG *sig = OPENSSL_malloc(sizeof(ECDSA_SIG)); + if (sig == NULL) { + return NULL; + } + sig->r = BN_new(); + sig->s = BN_new(); + if (sig->r == NULL || sig->s == NULL) { + ECDSA_SIG_free(sig); + return NULL; + } + return sig; +} + +void ECDSA_SIG_free(ECDSA_SIG *sig) { + if (sig == NULL) { + return; + } + + BN_free(sig->r); + BN_free(sig->s); + OPENSSL_free(sig); +} + +void ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **out_r, + const BIGNUM **out_s) { + if (out_r != NULL) { + *out_r = sig->r; + } + if (out_s != NULL) { + *out_s = sig->s; + } +} + +int ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s) { + if (r == NULL || s == NULL) { + return 0; + } + BN_free(sig->r); + BN_free(sig->s); + sig->r = r; + sig->s = s; + return 1; +} + +int ECDSA_do_verify(const uint8_t *digest, size_t digest_len, + const ECDSA_SIG *sig, const EC_KEY *eckey) { + const EC_GROUP *group = EC_KEY_get0_group(eckey); + const EC_POINT *pub_key = EC_KEY_get0_public_key(eckey); + if (group == NULL || pub_key == NULL || sig == NULL) { + OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_MISSING_PARAMETERS); + return 0; + } + + BN_CTX *ctx = BN_CTX_new(); + if (!ctx) { + OPENSSL_PUT_ERROR(ECDSA, ERR_R_MALLOC_FAILURE); + return 0; + } + int ret = 0; + EC_POINT *point = NULL; + BN_CTX_start(ctx); + BIGNUM *X = BN_CTX_get(ctx); + if (X == NULL) { + OPENSSL_PUT_ERROR(ECDSA, ERR_R_BN_LIB); + goto err; + } + + EC_SCALAR r, s, u1, u2, s_inv_mont; + EC_LOOSE_SCALAR m; + const BIGNUM *order = EC_GROUP_get0_order(group); + if (BN_is_zero(sig->r) || + !ec_bignum_to_scalar(group, &r, sig->r) || + BN_is_zero(sig->s) || + !ec_bignum_to_scalar(group, &s, sig->s)) { + OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_BAD_SIGNATURE); + goto err; + } + // s_inv_mont = s^-1 mod order. We convert the result to Montgomery form for + // the products below. + int no_inverse; + if (!BN_mod_inverse_odd(X, &no_inverse, sig->s, order, ctx) || + // TODO(davidben): Add a words version of |BN_mod_inverse_odd| and write + // into |s_inv_mont| directly. + !ec_bignum_to_scalar_unchecked(group, &s_inv_mont, X) || + !bn_to_montgomery_small(s_inv_mont.words, order->width, s_inv_mont.words, + order->width, group->order_mont)) { + goto err; + } + // u1 = m * s^-1 mod order + // u2 = r * s^-1 mod order + // + // |s_inv_mont| is in Montgomery form while |m| and |r| are not, so |u1| and + // |u2| will be taken out of Montgomery form, as desired. + digest_to_scalar(group, &m, digest, digest_len); + if (!scalar_mod_mul_montgomery_loose(group, &u1, &m, &s_inv_mont) || + !scalar_mod_mul_montgomery(group, &u2, &r, &s_inv_mont)) { + goto err; + } + + point = EC_POINT_new(group); + if (point == NULL) { + OPENSSL_PUT_ERROR(ECDSA, ERR_R_MALLOC_FAILURE); + goto err; + } + if (!ec_point_mul_scalar_public(group, point, &u1, pub_key, &u2, ctx)) { + OPENSSL_PUT_ERROR(ECDSA, ERR_R_EC_LIB); + goto err; + } + if (!EC_POINT_get_affine_coordinates_GFp(group, point, X, NULL, ctx)) { + OPENSSL_PUT_ERROR(ECDSA, ERR_R_EC_LIB); + goto err; + } + if (!field_element_to_scalar(group, X)) { + OPENSSL_PUT_ERROR(ECDSA, ERR_R_BN_LIB); + goto err; + } + // The signature is correct iff |X| is equal to |sig->r|. + if (BN_ucmp(X, sig->r) != 0) { + OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_BAD_SIGNATURE); + goto err; + } + + ret = 1; + +err: + BN_CTX_end(ctx); + BN_CTX_free(ctx); + EC_POINT_free(point); + return ret; +} + +static int ecdsa_sign_setup(const EC_KEY *eckey, BN_CTX *ctx, + EC_SCALAR *out_kinv_mont, BIGNUM **rp, + const uint8_t *digest, size_t digest_len, + const EC_SCALAR *priv_key) { + EC_POINT *tmp_point = NULL; + int ret = 0; + EC_SCALAR k; + BIGNUM *r = BN_new(); // this value is later returned in *rp + if (r == NULL) { + OPENSSL_PUT_ERROR(ECDSA, ERR_R_MALLOC_FAILURE); + goto err; + } + const EC_GROUP *group = EC_KEY_get0_group(eckey); + const BIGNUM *order = EC_GROUP_get0_order(group); + tmp_point = EC_POINT_new(group); + if (tmp_point == NULL) { + OPENSSL_PUT_ERROR(ECDSA, ERR_R_EC_LIB); + goto err; + } + + // Check that the size of the group order is FIPS compliant (FIPS 186-4 + // B.5.2). + if (BN_num_bits(order) < 160) { + OPENSSL_PUT_ERROR(ECDSA, EC_R_INVALID_GROUP_ORDER); + goto err; + } + + do { + // Include the private key and message digest in the k generation. + if (eckey->fixed_k != NULL) { + if (!ec_bignum_to_scalar(group, &k, eckey->fixed_k)) { + goto err; + } + } else { + // Pass a SHA512 hash of the private key and digest as additional data + // into the RBG. This is a hardening measure against entropy failure. + OPENSSL_COMPILE_ASSERT(SHA512_DIGEST_LENGTH >= 32, + additional_data_is_too_large_for_sha512); + SHA512_CTX sha; + uint8_t additional_data[SHA512_DIGEST_LENGTH]; + SHA512_Init(&sha); + SHA512_Update(&sha, priv_key->words, order->width * sizeof(BN_ULONG)); + SHA512_Update(&sha, digest, digest_len); + SHA512_Final(additional_data, &sha); + if (!ec_random_nonzero_scalar(group, &k, additional_data)) { + goto err; + } + } + + // Compute k^-1. We leave it in the Montgomery domain as an optimization for + // later operations. + if (!bn_to_montgomery_small(out_kinv_mont->words, order->width, k.words, + order->width, group->order_mont) || + !bn_mod_inverse_prime_mont_small(out_kinv_mont->words, order->width, + out_kinv_mont->words, order->width, + group->order_mont)) { + goto err; + } + + // Compute r, the x-coordinate of generator * k. + if (!ec_point_mul_scalar(group, tmp_point, &k, NULL, NULL, ctx) || + !EC_POINT_get_affine_coordinates_GFp(group, tmp_point, r, NULL, + ctx)) { + goto err; + } + + if (!field_element_to_scalar(group, r)) { + goto err; + } + } while (BN_is_zero(r)); + + BN_clear_free(*rp); + *rp = r; + r = NULL; + ret = 1; + +err: + OPENSSL_cleanse(&k, sizeof(k)); + BN_clear_free(r); + EC_POINT_free(tmp_point); + return ret; +} + +ECDSA_SIG *ECDSA_do_sign(const uint8_t *digest, size_t digest_len, + const EC_KEY *eckey) { + if (eckey->ecdsa_meth && eckey->ecdsa_meth->sign) { + OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_NOT_IMPLEMENTED); + return NULL; + } + + const EC_GROUP *group = EC_KEY_get0_group(eckey); + if (group == NULL || eckey->priv_key == NULL) { + OPENSSL_PUT_ERROR(ECDSA, ERR_R_PASSED_NULL_PARAMETER); + return NULL; + } + const BIGNUM *order = EC_GROUP_get0_order(group); + const EC_SCALAR *priv_key = &eckey->priv_key->scalar; + + int ok = 0; + ECDSA_SIG *ret = ECDSA_SIG_new(); + BN_CTX *ctx = BN_CTX_new(); + EC_SCALAR kinv_mont, r_mont, s; + EC_LOOSE_SCALAR m, tmp; + if (ret == NULL || ctx == NULL) { + OPENSSL_PUT_ERROR(ECDSA, ERR_R_MALLOC_FAILURE); + return NULL; + } + + digest_to_scalar(group, &m, digest, digest_len); + for (;;) { + if (!ecdsa_sign_setup(eckey, ctx, &kinv_mont, &ret->r, digest, digest_len, + priv_key)) { + goto err; + } + + // Compute priv_key * r (mod order). Note if only one parameter is in the + // Montgomery domain, |scalar_mod_mul_montgomery| will compute the answer in + // the normal domain. + if (!ec_bignum_to_scalar(group, &r_mont, ret->r) || + !bn_to_montgomery_small(r_mont.words, order->width, r_mont.words, + order->width, group->order_mont) || + !scalar_mod_mul_montgomery(group, &s, priv_key, &r_mont)) { + goto err; + } + + // Compute tmp = m + priv_key * r. + scalar_add_loose(group, &tmp, &m, &s); + + // Finally, multiply s by k^-1. That was retained in Montgomery form, so the + // same technique as the previous multiplication works. + if (!scalar_mod_mul_montgomery_loose(group, &s, &tmp, &kinv_mont) || + !bn_set_words(ret->s, s.words, order->width)) { + goto err; + } + if (!BN_is_zero(ret->s)) { + // s != 0 => we have a valid signature + break; + } + } + + ok = 1; + +err: + if (!ok) { + ECDSA_SIG_free(ret); + ret = NULL; + } + BN_CTX_free(ctx); + OPENSSL_cleanse(&kinv_mont, sizeof(kinv_mont)); + OPENSSL_cleanse(&r_mont, sizeof(r_mont)); + OPENSSL_cleanse(&s, sizeof(s)); + OPENSSL_cleanse(&tmp, sizeof(tmp)); + OPENSSL_cleanse(&m, sizeof(m)); + return ret; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/ecdsa/ecdsa.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/ecdsa/ecdsa.c.grpc_back new file mode 100644 index 0000000..1d08123 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/ecdsa/ecdsa.c.grpc_back @@ -0,0 +1,458 @@ +/* ==================================================================== + * 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 +#include + +#include +#include +#include +#include +#include + +#include "../bn/internal.h" +#include "../ec/internal.h" +#include "../../internal.h" + + +// EC_LOOSE_SCALAR is like |EC_SCALAR| but is bounded by 2^|BN_num_bits(order)| +// rather than |order|. +typedef union { + // bytes is the representation of the scalar in little-endian order. + uint8_t bytes[EC_MAX_SCALAR_BYTES]; + BN_ULONG words[EC_MAX_SCALAR_WORDS]; +} EC_LOOSE_SCALAR; + +static void scalar_add_loose(const EC_GROUP *group, EC_LOOSE_SCALAR *r, + const EC_LOOSE_SCALAR *a, const EC_SCALAR *b) { + // Add and subtract one copy of |order| if necessary. We have: + // |a| + |b| < 2^BN_num_bits(order) + order + // so this leaves |r| < 2^BN_num_bits(order). + const BIGNUM *order = &group->order; + BN_ULONG carry = bn_add_words(r->words, a->words, b->words, order->width); + EC_LOOSE_SCALAR tmp; + BN_ULONG v = + bn_sub_words(tmp.words, r->words, order->d, order->width) - carry; + bn_select_words(r->words, 0u - v, r->words /* tmp < 0 */, + tmp.words /* tmp >= 0 */, order->width); +} + +static int scalar_mod_mul_montgomery(const EC_GROUP *group, EC_SCALAR *r, + const EC_SCALAR *a, const EC_SCALAR *b) { + const BIGNUM *order = &group->order; + return bn_mod_mul_montgomery_small(r->words, order->width, a->words, + order->width, b->words, order->width, + group->order_mont); +} + +static int scalar_mod_mul_montgomery_loose(const EC_GROUP *group, EC_SCALAR *r, + const EC_LOOSE_SCALAR *a, + const EC_SCALAR *b) { + // Although |a| is loose, |bn_mod_mul_montgomery_small| only requires the + // product not exceed R * |order|. |b| is fully reduced and |a| < + // 2^BN_num_bits(order) <= R, so this holds. + const BIGNUM *order = &group->order; + return bn_mod_mul_montgomery_small(r->words, order->width, a->words, + order->width, b->words, order->width, + group->order_mont); +} + +// digest_to_scalar interprets |digest_len| bytes from |digest| as a scalar for +// ECDSA. Note this value is not fully reduced modulo the order, only the +// correct number of bits. +static void digest_to_scalar(const EC_GROUP *group, EC_LOOSE_SCALAR *out, + const uint8_t *digest, size_t digest_len) { + const BIGNUM *order = &group->order; + size_t num_bits = BN_num_bits(order); + // Need to truncate digest if it is too long: first truncate whole bytes. + if (8 * digest_len > num_bits) { + digest_len = (num_bits + 7) / 8; + } + OPENSSL_memset(out, 0, sizeof(EC_SCALAR)); + for (size_t i = 0; i < digest_len; i++) { + out->bytes[i] = digest[digest_len - 1 - i]; + } + + // If still too long truncate remaining bits with a shift + if (8 * digest_len > num_bits) { + size_t shift = 8 - (num_bits & 0x7); + for (int i = 0; i < order->width - 1; i++) { + out->words[i] = + (out->words[i] >> shift) | (out->words[i + 1] << (BN_BITS2 - shift)); + } + out->words[order->width - 1] >>= shift; + } +} + +// field_element_to_scalar reduces |r| modulo |group->order|. |r| must +// previously have been reduced modulo |group->field|. +static int field_element_to_scalar(const EC_GROUP *group, BIGNUM *r) { + // We must have p < 2×order, assuming p is not tiny (p >= 17). Thus rather we + // can reduce by performing at most one subtraction. + // + // Proof: We only work with prime order curves, so the number of points on + // the curve is the order. Thus Hasse's theorem gives: + // + // |order - (p + 1)| <= 2×sqrt(p) + // p + 1 - order <= 2×sqrt(p) + // p + 1 - 2×sqrt(p) <= order + // p + 1 - 2×(p/4) < order (p/4 > sqrt(p) for p >= 17) + // p/2 < p/2 + 1 < order + // p < 2×order + // + // Additionally, one can manually check this property for built-in curves. It + // is enforced for legacy custom curves in |EC_GROUP_set_generator|. + // + // TODO(davidben): Introduce |EC_FIELD_ELEMENT|, make this a function from + // |EC_FIELD_ELEMENT| to |EC_SCALAR|, and cut out the |BIGNUM|. Does this need + // to be constant-time for signing? |r| is the x-coordinate for kG, which is + // public unless k was rerolled because |s| was zero. + assert(!BN_is_negative(r)); + assert(BN_cmp(r, &group->field) < 0); + if (BN_cmp(r, &group->order) >= 0 && + !BN_sub(r, r, &group->order)) { + return 0; + } + assert(!BN_is_negative(r)); + assert(BN_cmp(r, &group->order) < 0); + return 1; +} + +ECDSA_SIG *ECDSA_SIG_new(void) { + ECDSA_SIG *sig = OPENSSL_malloc(sizeof(ECDSA_SIG)); + if (sig == NULL) { + return NULL; + } + sig->r = BN_new(); + sig->s = BN_new(); + if (sig->r == NULL || sig->s == NULL) { + ECDSA_SIG_free(sig); + return NULL; + } + return sig; +} + +void ECDSA_SIG_free(ECDSA_SIG *sig) { + if (sig == NULL) { + return; + } + + BN_free(sig->r); + BN_free(sig->s); + OPENSSL_free(sig); +} + +void ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **out_r, + const BIGNUM **out_s) { + if (out_r != NULL) { + *out_r = sig->r; + } + if (out_s != NULL) { + *out_s = sig->s; + } +} + +int ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s) { + if (r == NULL || s == NULL) { + return 0; + } + BN_free(sig->r); + BN_free(sig->s); + sig->r = r; + sig->s = s; + return 1; +} + +int ECDSA_do_verify(const uint8_t *digest, size_t digest_len, + const ECDSA_SIG *sig, const EC_KEY *eckey) { + const EC_GROUP *group = EC_KEY_get0_group(eckey); + const EC_POINT *pub_key = EC_KEY_get0_public_key(eckey); + if (group == NULL || pub_key == NULL || sig == NULL) { + OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_MISSING_PARAMETERS); + return 0; + } + + BN_CTX *ctx = BN_CTX_new(); + if (!ctx) { + OPENSSL_PUT_ERROR(ECDSA, ERR_R_MALLOC_FAILURE); + return 0; + } + int ret = 0; + EC_POINT *point = NULL; + BN_CTX_start(ctx); + BIGNUM *X = BN_CTX_get(ctx); + if (X == NULL) { + OPENSSL_PUT_ERROR(ECDSA, ERR_R_BN_LIB); + goto err; + } + + EC_SCALAR r, s, u1, u2, s_inv_mont; + EC_LOOSE_SCALAR m; + const BIGNUM *order = EC_GROUP_get0_order(group); + if (BN_is_zero(sig->r) || + !ec_bignum_to_scalar(group, &r, sig->r) || + BN_is_zero(sig->s) || + !ec_bignum_to_scalar(group, &s, sig->s)) { + OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_BAD_SIGNATURE); + goto err; + } + // s_inv_mont = s^-1 mod order. We convert the result to Montgomery form for + // the products below. + int no_inverse; + if (!BN_mod_inverse_odd(X, &no_inverse, sig->s, order, ctx) || + // TODO(davidben): Add a words version of |BN_mod_inverse_odd| and write + // into |s_inv_mont| directly. + !ec_bignum_to_scalar_unchecked(group, &s_inv_mont, X) || + !bn_to_montgomery_small(s_inv_mont.words, order->width, s_inv_mont.words, + order->width, group->order_mont)) { + goto err; + } + // u1 = m * s^-1 mod order + // u2 = r * s^-1 mod order + // + // |s_inv_mont| is in Montgomery form while |m| and |r| are not, so |u1| and + // |u2| will be taken out of Montgomery form, as desired. + digest_to_scalar(group, &m, digest, digest_len); + if (!scalar_mod_mul_montgomery_loose(group, &u1, &m, &s_inv_mont) || + !scalar_mod_mul_montgomery(group, &u2, &r, &s_inv_mont)) { + goto err; + } + + point = EC_POINT_new(group); + if (point == NULL) { + OPENSSL_PUT_ERROR(ECDSA, ERR_R_MALLOC_FAILURE); + goto err; + } + if (!ec_point_mul_scalar_public(group, point, &u1, pub_key, &u2, ctx)) { + OPENSSL_PUT_ERROR(ECDSA, ERR_R_EC_LIB); + goto err; + } + if (!EC_POINT_get_affine_coordinates_GFp(group, point, X, NULL, ctx)) { + OPENSSL_PUT_ERROR(ECDSA, ERR_R_EC_LIB); + goto err; + } + if (!field_element_to_scalar(group, X)) { + OPENSSL_PUT_ERROR(ECDSA, ERR_R_BN_LIB); + goto err; + } + // The signature is correct iff |X| is equal to |sig->r|. + if (BN_ucmp(X, sig->r) != 0) { + OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_BAD_SIGNATURE); + goto err; + } + + ret = 1; + +err: + BN_CTX_end(ctx); + BN_CTX_free(ctx); + EC_POINT_free(point); + return ret; +} + +static int ecdsa_sign_setup(const EC_KEY *eckey, BN_CTX *ctx, + EC_SCALAR *out_kinv_mont, BIGNUM **rp, + const uint8_t *digest, size_t digest_len, + const EC_SCALAR *priv_key) { + EC_POINT *tmp_point = NULL; + int ret = 0; + EC_SCALAR k; + BIGNUM *r = BN_new(); // this value is later returned in *rp + if (r == NULL) { + OPENSSL_PUT_ERROR(ECDSA, ERR_R_MALLOC_FAILURE); + goto err; + } + const EC_GROUP *group = EC_KEY_get0_group(eckey); + const BIGNUM *order = EC_GROUP_get0_order(group); + tmp_point = EC_POINT_new(group); + if (tmp_point == NULL) { + OPENSSL_PUT_ERROR(ECDSA, ERR_R_EC_LIB); + goto err; + } + + // Check that the size of the group order is FIPS compliant (FIPS 186-4 + // B.5.2). + if (BN_num_bits(order) < 160) { + OPENSSL_PUT_ERROR(ECDSA, EC_R_INVALID_GROUP_ORDER); + goto err; + } + + do { + // Include the private key and message digest in the k generation. + if (eckey->fixed_k != NULL) { + if (!ec_bignum_to_scalar(group, &k, eckey->fixed_k)) { + goto err; + } + } else { + // Pass a SHA512 hash of the private key and digest as additional data + // into the RBG. This is a hardening measure against entropy failure. + OPENSSL_COMPILE_ASSERT(SHA512_DIGEST_LENGTH >= 32, + additional_data_is_too_large_for_sha512); + SHA512_CTX sha; + uint8_t additional_data[SHA512_DIGEST_LENGTH]; + SHA512_Init(&sha); + SHA512_Update(&sha, priv_key->words, order->width * sizeof(BN_ULONG)); + SHA512_Update(&sha, digest, digest_len); + SHA512_Final(additional_data, &sha); + if (!ec_random_nonzero_scalar(group, &k, additional_data)) { + goto err; + } + } + + // Compute k^-1. We leave it in the Montgomery domain as an optimization for + // later operations. + if (!bn_to_montgomery_small(out_kinv_mont->words, order->width, k.words, + order->width, group->order_mont) || + !bn_mod_inverse_prime_mont_small(out_kinv_mont->words, order->width, + out_kinv_mont->words, order->width, + group->order_mont)) { + goto err; + } + + // Compute r, the x-coordinate of generator * k. + if (!ec_point_mul_scalar(group, tmp_point, &k, NULL, NULL, ctx) || + !EC_POINT_get_affine_coordinates_GFp(group, tmp_point, r, NULL, + ctx)) { + goto err; + } + + if (!field_element_to_scalar(group, r)) { + goto err; + } + } while (BN_is_zero(r)); + + BN_clear_free(*rp); + *rp = r; + r = NULL; + ret = 1; + +err: + OPENSSL_cleanse(&k, sizeof(k)); + BN_clear_free(r); + EC_POINT_free(tmp_point); + return ret; +} + +ECDSA_SIG *ECDSA_do_sign(const uint8_t *digest, size_t digest_len, + const EC_KEY *eckey) { + if (eckey->ecdsa_meth && eckey->ecdsa_meth->sign) { + OPENSSL_PUT_ERROR(ECDSA, ECDSA_R_NOT_IMPLEMENTED); + return NULL; + } + + const EC_GROUP *group = EC_KEY_get0_group(eckey); + if (group == NULL || eckey->priv_key == NULL) { + OPENSSL_PUT_ERROR(ECDSA, ERR_R_PASSED_NULL_PARAMETER); + return NULL; + } + const BIGNUM *order = EC_GROUP_get0_order(group); + const EC_SCALAR *priv_key = &eckey->priv_key->scalar; + + int ok = 0; + ECDSA_SIG *ret = ECDSA_SIG_new(); + BN_CTX *ctx = BN_CTX_new(); + EC_SCALAR kinv_mont, r_mont, s; + EC_LOOSE_SCALAR m, tmp; + if (ret == NULL || ctx == NULL) { + OPENSSL_PUT_ERROR(ECDSA, ERR_R_MALLOC_FAILURE); + return NULL; + } + + digest_to_scalar(group, &m, digest, digest_len); + for (;;) { + if (!ecdsa_sign_setup(eckey, ctx, &kinv_mont, &ret->r, digest, digest_len, + priv_key)) { + goto err; + } + + // Compute priv_key * r (mod order). Note if only one parameter is in the + // Montgomery domain, |scalar_mod_mul_montgomery| will compute the answer in + // the normal domain. + if (!ec_bignum_to_scalar(group, &r_mont, ret->r) || + !bn_to_montgomery_small(r_mont.words, order->width, r_mont.words, + order->width, group->order_mont) || + !scalar_mod_mul_montgomery(group, &s, priv_key, &r_mont)) { + goto err; + } + + // Compute tmp = m + priv_key * r. + scalar_add_loose(group, &tmp, &m, &s); + + // Finally, multiply s by k^-1. That was retained in Montgomery form, so the + // same technique as the previous multiplication works. + if (!scalar_mod_mul_montgomery_loose(group, &s, &tmp, &kinv_mont) || + !bn_set_words(ret->s, s.words, order->width)) { + goto err; + } + if (!BN_is_zero(ret->s)) { + // s != 0 => we have a valid signature + break; + } + } + + ok = 1; + +err: + if (!ok) { + ECDSA_SIG_free(ret); + ret = NULL; + } + BN_CTX_free(ctx); + OPENSSL_cleanse(&kinv_mont, sizeof(kinv_mont)); + OPENSSL_cleanse(&r_mont, sizeof(r_mont)); + OPENSSL_cleanse(&s, sizeof(s)); + OPENSSL_cleanse(&tmp, sizeof(tmp)); + OPENSSL_cleanse(&m, sizeof(m)); + return ret; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/hmac/hmac.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/hmac/hmac.c new file mode 100644 index 0000000..7466f94 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/hmac/hmac.c @@ -0,0 +1,228 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 + +#include "../../internal.h" + + +uint8_t *HMAC(const EVP_MD *evp_md, const void *key, size_t key_len, + const uint8_t *data, size_t data_len, uint8_t *out, + unsigned int *out_len) { + HMAC_CTX ctx; + HMAC_CTX_init(&ctx); + if (!HMAC_Init_ex(&ctx, key, key_len, evp_md, NULL) || + !HMAC_Update(&ctx, data, data_len) || + !HMAC_Final(&ctx, out, out_len)) { + out = NULL; + } + + HMAC_CTX_cleanup(&ctx); + return out; +} + +void HMAC_CTX_init(HMAC_CTX *ctx) { + ctx->md = NULL; + EVP_MD_CTX_init(&ctx->i_ctx); + EVP_MD_CTX_init(&ctx->o_ctx); + EVP_MD_CTX_init(&ctx->md_ctx); +} + +HMAC_CTX *HMAC_CTX_new(void) { + HMAC_CTX *ctx = OPENSSL_malloc(sizeof(HMAC_CTX)); + if (ctx != NULL) { + HMAC_CTX_init(ctx); + } + return ctx; +} + +void HMAC_CTX_cleanup(HMAC_CTX *ctx) { + 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(HMAC_CTX)); +} + +void HMAC_CTX_free(HMAC_CTX *ctx) { + if (ctx == NULL) { + return; + } + + HMAC_CTX_cleanup(ctx); + OPENSSL_free(ctx); +} + +int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, size_t key_len, + const EVP_MD *md, ENGINE *impl) { + if (md == NULL) { + md = ctx->md; + } + + // If either |key| is non-NULL or |md| has changed, initialize with a new key + // rather than rewinding the previous one. + // + // TODO(davidben,eroman): Passing the previous |md| with a NULL |key| is + // ambiguous between using the empty key and reusing the previous key. There + // exist callers which intend the latter, but the former is an awkward edge + // case. Fix to API to avoid this. + if (md != ctx->md || key != NULL) { + uint8_t pad[EVP_MAX_MD_BLOCK_SIZE]; + uint8_t key_block[EVP_MAX_MD_BLOCK_SIZE]; + unsigned key_block_len; + + size_t block_size = EVP_MD_block_size(md); + assert(block_size <= sizeof(key_block)); + if (block_size < key_len) { + // Long keys are hashed. + if (!EVP_DigestInit_ex(&ctx->md_ctx, md, impl) || + !EVP_DigestUpdate(&ctx->md_ctx, key, key_len) || + !EVP_DigestFinal_ex(&ctx->md_ctx, key_block, &key_block_len)) { + return 0; + } + } else { + assert(key_len <= sizeof(key_block)); + OPENSSL_memcpy(key_block, key, key_len); + key_block_len = (unsigned)key_len; + } + // Keys are then padded with zeros. + if (key_block_len != EVP_MAX_MD_BLOCK_SIZE) { + OPENSSL_memset(&key_block[key_block_len], 0, sizeof(key_block) - key_block_len); + } + + for (size_t i = 0; i < EVP_MAX_MD_BLOCK_SIZE; i++) { + pad[i] = 0x36 ^ key_block[i]; + } + if (!EVP_DigestInit_ex(&ctx->i_ctx, md, impl) || + !EVP_DigestUpdate(&ctx->i_ctx, pad, EVP_MD_block_size(md))) { + return 0; + } + + for (size_t i = 0; i < EVP_MAX_MD_BLOCK_SIZE; i++) { + pad[i] = 0x5c ^ key_block[i]; + } + if (!EVP_DigestInit_ex(&ctx->o_ctx, md, impl) || + !EVP_DigestUpdate(&ctx->o_ctx, pad, EVP_MD_block_size(md))) { + return 0; + } + + ctx->md = md; + } + + if (!EVP_MD_CTX_copy_ex(&ctx->md_ctx, &ctx->i_ctx)) { + return 0; + } + + return 1; +} + +int HMAC_Update(HMAC_CTX *ctx, const uint8_t *data, size_t data_len) { + return EVP_DigestUpdate(&ctx->md_ctx, data, data_len); +} + +int HMAC_Final(HMAC_CTX *ctx, uint8_t *out, unsigned int *out_len) { + unsigned int i; + uint8_t buf[EVP_MAX_MD_SIZE]; + + // TODO(davidben): The only thing that can officially fail here is + // |EVP_MD_CTX_copy_ex|, but even that should be impossible in this case. + if (!EVP_DigestFinal_ex(&ctx->md_ctx, buf, &i) || + !EVP_MD_CTX_copy_ex(&ctx->md_ctx, &ctx->o_ctx) || + !EVP_DigestUpdate(&ctx->md_ctx, buf, i) || + !EVP_DigestFinal_ex(&ctx->md_ctx, out, out_len)) { + *out_len = 0; + return 0; + } + + return 1; +} + +size_t HMAC_size(const HMAC_CTX *ctx) { + return EVP_MD_size(ctx->md); +} + +int HMAC_CTX_copy_ex(HMAC_CTX *dest, const HMAC_CTX *src) { + if (!EVP_MD_CTX_copy_ex(&dest->i_ctx, &src->i_ctx) || + !EVP_MD_CTX_copy_ex(&dest->o_ctx, &src->o_ctx) || + !EVP_MD_CTX_copy_ex(&dest->md_ctx, &src->md_ctx)) { + return 0; + } + + dest->md = src->md; + return 1; +} + +void HMAC_CTX_reset(HMAC_CTX *ctx) { + HMAC_CTX_cleanup(ctx); + HMAC_CTX_init(ctx); +} + +int HMAC_Init(HMAC_CTX *ctx, const void *key, int key_len, const EVP_MD *md) { + if (key && md) { + HMAC_CTX_init(ctx); + } + return HMAC_Init_ex(ctx, key, key_len, md, NULL); +} + +int HMAC_CTX_copy(HMAC_CTX *dest, const HMAC_CTX *src) { + HMAC_CTX_init(dest); + return HMAC_CTX_copy_ex(dest, src); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/hmac/hmac.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/hmac/hmac.c.grpc_back new file mode 100644 index 0000000..fb57bf2 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/hmac/hmac.c.grpc_back @@ -0,0 +1,228 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 + +#include "../../internal.h" + + +uint8_t *HMAC(const EVP_MD *evp_md, const void *key, size_t key_len, + const uint8_t *data, size_t data_len, uint8_t *out, + unsigned int *out_len) { + HMAC_CTX ctx; + HMAC_CTX_init(&ctx); + if (!HMAC_Init_ex(&ctx, key, key_len, evp_md, NULL) || + !HMAC_Update(&ctx, data, data_len) || + !HMAC_Final(&ctx, out, out_len)) { + out = NULL; + } + + HMAC_CTX_cleanup(&ctx); + return out; +} + +void HMAC_CTX_init(HMAC_CTX *ctx) { + ctx->md = NULL; + EVP_MD_CTX_init(&ctx->i_ctx); + EVP_MD_CTX_init(&ctx->o_ctx); + EVP_MD_CTX_init(&ctx->md_ctx); +} + +HMAC_CTX *HMAC_CTX_new(void) { + HMAC_CTX *ctx = OPENSSL_malloc(sizeof(HMAC_CTX)); + if (ctx != NULL) { + HMAC_CTX_init(ctx); + } + return ctx; +} + +void HMAC_CTX_cleanup(HMAC_CTX *ctx) { + 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(HMAC_CTX)); +} + +void HMAC_CTX_free(HMAC_CTX *ctx) { + if (ctx == NULL) { + return; + } + + HMAC_CTX_cleanup(ctx); + OPENSSL_free(ctx); +} + +int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, size_t key_len, + const EVP_MD *md, ENGINE *impl) { + if (md == NULL) { + md = ctx->md; + } + + // If either |key| is non-NULL or |md| has changed, initialize with a new key + // rather than rewinding the previous one. + // + // TODO(davidben,eroman): Passing the previous |md| with a NULL |key| is + // ambiguous between using the empty key and reusing the previous key. There + // exist callers which intend the latter, but the former is an awkward edge + // case. Fix to API to avoid this. + if (md != ctx->md || key != NULL) { + uint8_t pad[EVP_MAX_MD_BLOCK_SIZE]; + uint8_t key_block[EVP_MAX_MD_BLOCK_SIZE]; + unsigned key_block_len; + + size_t block_size = EVP_MD_block_size(md); + assert(block_size <= sizeof(key_block)); + if (block_size < key_len) { + // Long keys are hashed. + if (!EVP_DigestInit_ex(&ctx->md_ctx, md, impl) || + !EVP_DigestUpdate(&ctx->md_ctx, key, key_len) || + !EVP_DigestFinal_ex(&ctx->md_ctx, key_block, &key_block_len)) { + return 0; + } + } else { + assert(key_len <= sizeof(key_block)); + OPENSSL_memcpy(key_block, key, key_len); + key_block_len = (unsigned)key_len; + } + // Keys are then padded with zeros. + if (key_block_len != EVP_MAX_MD_BLOCK_SIZE) { + OPENSSL_memset(&key_block[key_block_len], 0, sizeof(key_block) - key_block_len); + } + + for (size_t i = 0; i < EVP_MAX_MD_BLOCK_SIZE; i++) { + pad[i] = 0x36 ^ key_block[i]; + } + if (!EVP_DigestInit_ex(&ctx->i_ctx, md, impl) || + !EVP_DigestUpdate(&ctx->i_ctx, pad, EVP_MD_block_size(md))) { + return 0; + } + + for (size_t i = 0; i < EVP_MAX_MD_BLOCK_SIZE; i++) { + pad[i] = 0x5c ^ key_block[i]; + } + if (!EVP_DigestInit_ex(&ctx->o_ctx, md, impl) || + !EVP_DigestUpdate(&ctx->o_ctx, pad, EVP_MD_block_size(md))) { + return 0; + } + + ctx->md = md; + } + + if (!EVP_MD_CTX_copy_ex(&ctx->md_ctx, &ctx->i_ctx)) { + return 0; + } + + return 1; +} + +int HMAC_Update(HMAC_CTX *ctx, const uint8_t *data, size_t data_len) { + return EVP_DigestUpdate(&ctx->md_ctx, data, data_len); +} + +int HMAC_Final(HMAC_CTX *ctx, uint8_t *out, unsigned int *out_len) { + unsigned int i; + uint8_t buf[EVP_MAX_MD_SIZE]; + + // TODO(davidben): The only thing that can officially fail here is + // |EVP_MD_CTX_copy_ex|, but even that should be impossible in this case. + if (!EVP_DigestFinal_ex(&ctx->md_ctx, buf, &i) || + !EVP_MD_CTX_copy_ex(&ctx->md_ctx, &ctx->o_ctx) || + !EVP_DigestUpdate(&ctx->md_ctx, buf, i) || + !EVP_DigestFinal_ex(&ctx->md_ctx, out, out_len)) { + *out_len = 0; + return 0; + } + + return 1; +} + +size_t HMAC_size(const HMAC_CTX *ctx) { + return EVP_MD_size(ctx->md); +} + +int HMAC_CTX_copy_ex(HMAC_CTX *dest, const HMAC_CTX *src) { + if (!EVP_MD_CTX_copy_ex(&dest->i_ctx, &src->i_ctx) || + !EVP_MD_CTX_copy_ex(&dest->o_ctx, &src->o_ctx) || + !EVP_MD_CTX_copy_ex(&dest->md_ctx, &src->md_ctx)) { + return 0; + } + + dest->md = src->md; + return 1; +} + +void HMAC_CTX_reset(HMAC_CTX *ctx) { + HMAC_CTX_cleanup(ctx); + HMAC_CTX_init(ctx); +} + +int HMAC_Init(HMAC_CTX *ctx, const void *key, int key_len, const EVP_MD *md) { + if (key && md) { + HMAC_CTX_init(ctx); + } + return HMAC_Init_ex(ctx, key, key_len, md, NULL); +} + +int HMAC_CTX_copy(HMAC_CTX *dest, const HMAC_CTX *src) { + HMAC_CTX_init(dest); + return HMAC_CTX_copy_ex(dest, src); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/is_fips.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/is_fips.c new file mode 100644 index 0000000..f8fd590 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/is_fips.c @@ -0,0 +1,27 @@ +/* Copyright (c) 2017, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + + +// This file exists in order to give the fipsmodule target, in non-FIPS mode, +// something to compile. + +int FIPS_mode(void) { +#if defined(BORINGSSL_FIPS) && !defined(OPENSSL_ASAN) + return 1; +#else + return 0; +#endif +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/is_fips.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/is_fips.c.grpc_back new file mode 100644 index 0000000..4182dfb --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/is_fips.c.grpc_back @@ -0,0 +1,27 @@ +/* Copyright (c) 2017, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + + +// This file exists in order to give the fipsmodule target, in non-FIPS mode, +// something to compile. + +int FIPS_mode(void) { +#if defined(BORINGSSL_FIPS) && !defined(OPENSSL_ASAN) + return 1; +#else + return 0; +#endif +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/md4/md4.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/md4/md4.c new file mode 100644 index 0000000..364029e --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/md4/md4.c @@ -0,0 +1,254 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 "../../internal.h" + + +uint8_t *MD4(const uint8_t *data, size_t len, uint8_t *out) { + MD4_CTX ctx; + MD4_Init(&ctx); + MD4_Update(&ctx, data, len); + MD4_Final(out, &ctx); + + return out; +} + +// Implemented from RFC1186 The MD4 Message-Digest Algorithm. + +int MD4_Init(MD4_CTX *md4) { + OPENSSL_memset(md4, 0, sizeof(MD4_CTX)); + md4->h[0] = 0x67452301UL; + md4->h[1] = 0xefcdab89UL; + md4->h[2] = 0x98badcfeUL; + md4->h[3] = 0x10325476UL; + return 1; +} + +void md4_block_data_order(uint32_t *state, const uint8_t *data, size_t num); + +#define DATA_ORDER_IS_LITTLE_ENDIAN + +#define HASH_CTX MD4_CTX +#define HASH_CBLOCK 64 +#define HASH_UPDATE MD4_Update +#define HASH_TRANSFORM MD4_Transform +#define HASH_FINAL MD4_Final +#define HASH_MAKE_STRING(c, s) \ + do { \ + uint32_t ll; \ + ll = (c)->h[0]; \ + HOST_l2c(ll, (s)); \ + ll = (c)->h[1]; \ + HOST_l2c(ll, (s)); \ + ll = (c)->h[2]; \ + HOST_l2c(ll, (s)); \ + ll = (c)->h[3]; \ + HOST_l2c(ll, (s)); \ + } while (0) +#define HASH_BLOCK_DATA_ORDER md4_block_data_order + +#include "../digest/md32_common.h" + +// 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 ROTATE(a, n) (((a) << (n)) | ((a) >> (32 - (n)))) + +#define R0(a, b, c, d, k, s, t) \ + do { \ + (a) += ((k) + (t) + F((b), (c), (d))); \ + (a) = ROTATE(a, s); \ + } while (0) + +#define R1(a, b, c, d, k, s, t) \ + do { \ + (a) += ((k) + (t) + G((b), (c), (d))); \ + (a) = ROTATE(a, s); \ + } while (0) + +#define R2(a, b, c, d, k, s, t) \ + do { \ + (a) += ((k) + (t) + H((b), (c), (d))); \ + (a) = ROTATE(a, s); \ + } while (0) + +void md4_block_data_order(uint32_t *state, const uint8_t *data, size_t num) { + uint32_t A, B, C, D, l; + uint32_t X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15; + + A = state[0]; + B = state[1]; + C = state[2]; + D = state[3]; + + for (; num--;) { + HOST_c2l(data, l); + X0 = l; + HOST_c2l(data, l); + X1 = l; + // Round 0 + R0(A, B, C, D, X0, 3, 0); + HOST_c2l(data, l); + X2 = l; + R0(D, A, B, C, X1, 7, 0); + HOST_c2l(data, l); + X3 = l; + R0(C, D, A, B, X2, 11, 0); + HOST_c2l(data, l); + X4 = l; + R0(B, C, D, A, X3, 19, 0); + HOST_c2l(data, l); + X5 = l; + R0(A, B, C, D, X4, 3, 0); + HOST_c2l(data, l); + X6 = l; + R0(D, A, B, C, X5, 7, 0); + HOST_c2l(data, l); + X7 = l; + R0(C, D, A, B, X6, 11, 0); + HOST_c2l(data, l); + X8 = l; + R0(B, C, D, A, X7, 19, 0); + HOST_c2l(data, l); + X9 = l; + R0(A, B, C, D, X8, 3, 0); + HOST_c2l(data, l); + X10 = l; + R0(D, A, B, C, X9, 7, 0); + HOST_c2l(data, l); + X11 = l; + R0(C, D, A, B, X10, 11, 0); + HOST_c2l(data, l); + X12 = l; + R0(B, C, D, A, X11, 19, 0); + HOST_c2l(data, l); + X13 = l; + R0(A, B, C, D, X12, 3, 0); + HOST_c2l(data, l); + X14 = l; + R0(D, A, B, C, X13, 7, 0); + HOST_c2l(data, l); + X15 = l; + R0(C, D, A, B, X14, 11, 0); + R0(B, C, D, A, X15, 19, 0); + // Round 1 + R1(A, B, C, D, X0, 3, 0x5A827999L); + R1(D, A, B, C, X4, 5, 0x5A827999L); + R1(C, D, A, B, X8, 9, 0x5A827999L); + R1(B, C, D, A, X12, 13, 0x5A827999L); + R1(A, B, C, D, X1, 3, 0x5A827999L); + R1(D, A, B, C, X5, 5, 0x5A827999L); + R1(C, D, A, B, X9, 9, 0x5A827999L); + R1(B, C, D, A, X13, 13, 0x5A827999L); + R1(A, B, C, D, X2, 3, 0x5A827999L); + R1(D, A, B, C, X6, 5, 0x5A827999L); + R1(C, D, A, B, X10, 9, 0x5A827999L); + R1(B, C, D, A, X14, 13, 0x5A827999L); + R1(A, B, C, D, X3, 3, 0x5A827999L); + R1(D, A, B, C, X7, 5, 0x5A827999L); + R1(C, D, A, B, X11, 9, 0x5A827999L); + R1(B, C, D, A, X15, 13, 0x5A827999L); + // Round 2 + R2(A, B, C, D, X0, 3, 0x6ED9EBA1L); + R2(D, A, B, C, X8, 9, 0x6ED9EBA1L); + R2(C, D, A, B, X4, 11, 0x6ED9EBA1L); + R2(B, C, D, A, X12, 15, 0x6ED9EBA1L); + R2(A, B, C, D, X2, 3, 0x6ED9EBA1L); + R2(D, A, B, C, X10, 9, 0x6ED9EBA1L); + R2(C, D, A, B, X6, 11, 0x6ED9EBA1L); + R2(B, C, D, A, X14, 15, 0x6ED9EBA1L); + R2(A, B, C, D, X1, 3, 0x6ED9EBA1L); + R2(D, A, B, C, X9, 9, 0x6ED9EBA1L); + R2(C, D, A, B, X5, 11, 0x6ED9EBA1L); + R2(B, C, D, A, X13, 15, 0x6ED9EBA1L); + R2(A, B, C, D, X3, 3, 0x6ED9EBA1L); + R2(D, A, B, C, X11, 9, 0x6ED9EBA1L); + R2(C, D, A, B, X7, 11, 0x6ED9EBA1L); + R2(B, C, D, A, X15, 15, 0x6ED9EBA1L); + + A = state[0] += A; + B = state[1] += B; + C = state[2] += C; + D = state[3] += D; + } +} + +#undef DATA_ORDER_IS_LITTLE_ENDIAN +#undef HASH_CTX +#undef HASH_CBLOCK +#undef HASH_UPDATE +#undef HASH_TRANSFORM +#undef HASH_FINAL +#undef HASH_MAKE_STRING +#undef HASH_BLOCK_DATA_ORDER +#undef F +#undef G +#undef H +#undef ROTATE +#undef R0 +#undef R1 +#undef R2 +#undef HOST_c2l +#undef HOST_l2c diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/md4/md4.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/md4/md4.c.grpc_back new file mode 100644 index 0000000..f0c1dcd --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/md4/md4.c.grpc_back @@ -0,0 +1,254 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 "../../internal.h" + + +uint8_t *MD4(const uint8_t *data, size_t len, uint8_t *out) { + MD4_CTX ctx; + MD4_Init(&ctx); + MD4_Update(&ctx, data, len); + MD4_Final(out, &ctx); + + return out; +} + +// Implemented from RFC1186 The MD4 Message-Digest Algorithm. + +int MD4_Init(MD4_CTX *md4) { + OPENSSL_memset(md4, 0, sizeof(MD4_CTX)); + md4->h[0] = 0x67452301UL; + md4->h[1] = 0xefcdab89UL; + md4->h[2] = 0x98badcfeUL; + md4->h[3] = 0x10325476UL; + return 1; +} + +void md4_block_data_order(uint32_t *state, const uint8_t *data, size_t num); + +#define DATA_ORDER_IS_LITTLE_ENDIAN + +#define HASH_CTX MD4_CTX +#define HASH_CBLOCK 64 +#define HASH_UPDATE MD4_Update +#define HASH_TRANSFORM MD4_Transform +#define HASH_FINAL MD4_Final +#define HASH_MAKE_STRING(c, s) \ + do { \ + uint32_t ll; \ + ll = (c)->h[0]; \ + HOST_l2c(ll, (s)); \ + ll = (c)->h[1]; \ + HOST_l2c(ll, (s)); \ + ll = (c)->h[2]; \ + HOST_l2c(ll, (s)); \ + ll = (c)->h[3]; \ + HOST_l2c(ll, (s)); \ + } while (0) +#define HASH_BLOCK_DATA_ORDER md4_block_data_order + +#include "../digest/md32_common.h" + +// 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 ROTATE(a, n) (((a) << (n)) | ((a) >> (32 - (n)))) + +#define R0(a, b, c, d, k, s, t) \ + do { \ + (a) += ((k) + (t) + F((b), (c), (d))); \ + (a) = ROTATE(a, s); \ + } while (0) + +#define R1(a, b, c, d, k, s, t) \ + do { \ + (a) += ((k) + (t) + G((b), (c), (d))); \ + (a) = ROTATE(a, s); \ + } while (0) + +#define R2(a, b, c, d, k, s, t) \ + do { \ + (a) += ((k) + (t) + H((b), (c), (d))); \ + (a) = ROTATE(a, s); \ + } while (0) + +void md4_block_data_order(uint32_t *state, const uint8_t *data, size_t num) { + uint32_t A, B, C, D, l; + uint32_t X0, X1, X2, X3, X4, X5, X6, X7, X8, X9, X10, X11, X12, X13, X14, X15; + + A = state[0]; + B = state[1]; + C = state[2]; + D = state[3]; + + for (; num--;) { + HOST_c2l(data, l); + X0 = l; + HOST_c2l(data, l); + X1 = l; + // Round 0 + R0(A, B, C, D, X0, 3, 0); + HOST_c2l(data, l); + X2 = l; + R0(D, A, B, C, X1, 7, 0); + HOST_c2l(data, l); + X3 = l; + R0(C, D, A, B, X2, 11, 0); + HOST_c2l(data, l); + X4 = l; + R0(B, C, D, A, X3, 19, 0); + HOST_c2l(data, l); + X5 = l; + R0(A, B, C, D, X4, 3, 0); + HOST_c2l(data, l); + X6 = l; + R0(D, A, B, C, X5, 7, 0); + HOST_c2l(data, l); + X7 = l; + R0(C, D, A, B, X6, 11, 0); + HOST_c2l(data, l); + X8 = l; + R0(B, C, D, A, X7, 19, 0); + HOST_c2l(data, l); + X9 = l; + R0(A, B, C, D, X8, 3, 0); + HOST_c2l(data, l); + X10 = l; + R0(D, A, B, C, X9, 7, 0); + HOST_c2l(data, l); + X11 = l; + R0(C, D, A, B, X10, 11, 0); + HOST_c2l(data, l); + X12 = l; + R0(B, C, D, A, X11, 19, 0); + HOST_c2l(data, l); + X13 = l; + R0(A, B, C, D, X12, 3, 0); + HOST_c2l(data, l); + X14 = l; + R0(D, A, B, C, X13, 7, 0); + HOST_c2l(data, l); + X15 = l; + R0(C, D, A, B, X14, 11, 0); + R0(B, C, D, A, X15, 19, 0); + // Round 1 + R1(A, B, C, D, X0, 3, 0x5A827999L); + R1(D, A, B, C, X4, 5, 0x5A827999L); + R1(C, D, A, B, X8, 9, 0x5A827999L); + R1(B, C, D, A, X12, 13, 0x5A827999L); + R1(A, B, C, D, X1, 3, 0x5A827999L); + R1(D, A, B, C, X5, 5, 0x5A827999L); + R1(C, D, A, B, X9, 9, 0x5A827999L); + R1(B, C, D, A, X13, 13, 0x5A827999L); + R1(A, B, C, D, X2, 3, 0x5A827999L); + R1(D, A, B, C, X6, 5, 0x5A827999L); + R1(C, D, A, B, X10, 9, 0x5A827999L); + R1(B, C, D, A, X14, 13, 0x5A827999L); + R1(A, B, C, D, X3, 3, 0x5A827999L); + R1(D, A, B, C, X7, 5, 0x5A827999L); + R1(C, D, A, B, X11, 9, 0x5A827999L); + R1(B, C, D, A, X15, 13, 0x5A827999L); + // Round 2 + R2(A, B, C, D, X0, 3, 0x6ED9EBA1L); + R2(D, A, B, C, X8, 9, 0x6ED9EBA1L); + R2(C, D, A, B, X4, 11, 0x6ED9EBA1L); + R2(B, C, D, A, X12, 15, 0x6ED9EBA1L); + R2(A, B, C, D, X2, 3, 0x6ED9EBA1L); + R2(D, A, B, C, X10, 9, 0x6ED9EBA1L); + R2(C, D, A, B, X6, 11, 0x6ED9EBA1L); + R2(B, C, D, A, X14, 15, 0x6ED9EBA1L); + R2(A, B, C, D, X1, 3, 0x6ED9EBA1L); + R2(D, A, B, C, X9, 9, 0x6ED9EBA1L); + R2(C, D, A, B, X5, 11, 0x6ED9EBA1L); + R2(B, C, D, A, X13, 15, 0x6ED9EBA1L); + R2(A, B, C, D, X3, 3, 0x6ED9EBA1L); + R2(D, A, B, C, X11, 9, 0x6ED9EBA1L); + R2(C, D, A, B, X7, 11, 0x6ED9EBA1L); + R2(B, C, D, A, X15, 15, 0x6ED9EBA1L); + + A = state[0] += A; + B = state[1] += B; + C = state[2] += C; + D = state[3] += D; + } +} + +#undef DATA_ORDER_IS_LITTLE_ENDIAN +#undef HASH_CTX +#undef HASH_CBLOCK +#undef HASH_UPDATE +#undef HASH_TRANSFORM +#undef HASH_FINAL +#undef HASH_MAKE_STRING +#undef HASH_BLOCK_DATA_ORDER +#undef F +#undef G +#undef H +#undef ROTATE +#undef R0 +#undef R1 +#undef R2 +#undef HOST_c2l +#undef HOST_l2c diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/md5/md5.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/md5/md5.c new file mode 100644 index 0000000..2f07d0b --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/md5/md5.c @@ -0,0 +1,298 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 "../../internal.h" + + +uint8_t *MD5(const uint8_t *data, size_t len, uint8_t *out) { + MD5_CTX ctx; + MD5_Init(&ctx); + MD5_Update(&ctx, data, len); + MD5_Final(out, &ctx); + + return out; +} + +int MD5_Init(MD5_CTX *md5) { + OPENSSL_memset(md5, 0, sizeof(MD5_CTX)); + md5->h[0] = 0x67452301UL; + md5->h[1] = 0xefcdab89UL; + md5->h[2] = 0x98badcfeUL; + md5->h[3] = 0x10325476UL; + return 1; +} + +#if !defined(OPENSSL_NO_ASM) && \ + (defined(OPENSSL_X86_64) || defined(OPENSSL_X86)) +#define MD5_ASM +#define md5_block_data_order md5_block_asm_data_order +#endif + + +void md5_block_data_order(uint32_t *state, const uint8_t *data, size_t num); + +#define DATA_ORDER_IS_LITTLE_ENDIAN + +#define HASH_CTX MD5_CTX +#define HASH_CBLOCK 64 +#define HASH_UPDATE MD5_Update +#define HASH_TRANSFORM MD5_Transform +#define HASH_FINAL MD5_Final +#define HASH_MAKE_STRING(c, s) \ + do { \ + uint32_t ll; \ + ll = (c)->h[0]; \ + HOST_l2c(ll, (s)); \ + ll = (c)->h[1]; \ + HOST_l2c(ll, (s)); \ + ll = (c)->h[2]; \ + HOST_l2c(ll, (s)); \ + ll = (c)->h[3]; \ + HOST_l2c(ll, (s)); \ + } while (0) +#define HASH_BLOCK_DATA_ORDER md5_block_data_order + +#include "../digest/md32_common.h" + +// 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 ROTATE(a, n) (((a) << (n)) | ((a) >> (32 - (n)))) + +#define R0(a, b, c, d, k, s, t) \ + do { \ + (a) += ((k) + (t) + F((b), (c), (d))); \ + (a) = ROTATE(a, s); \ + (a) += (b); \ + } while (0) + +#define R1(a, b, c, d, k, s, t) \ + do { \ + (a) += ((k) + (t) + G((b), (c), (d))); \ + (a) = ROTATE(a, s); \ + (a) += (b); \ + } while (0) + +#define R2(a, b, c, d, k, s, t) \ + do { \ + (a) += ((k) + (t) + H((b), (c), (d))); \ + (a) = ROTATE(a, s); \ + (a) += (b); \ + } while (0) + +#define R3(a, b, c, d, k, s, t) \ + do { \ + (a) += ((k) + (t) + I((b), (c), (d))); \ + (a) = ROTATE(a, s); \ + (a) += (b); \ + } while (0) + +#ifndef GRPC_SHADOW_md5_block_data_order +#ifdef X +#undef X +#endif +void md5_block_data_order(uint32_t *state, const uint8_t *data, size_t num) { + uint32_t A, B, C, D, l; + uint32_t XX0, XX1, XX2, XX3, XX4, XX5, XX6, XX7, XX8, XX9, XX10, XX11, XX12, + XX13, XX14, XX15; +#define X(i) XX##i + + A = state[0]; + B = state[1]; + C = state[2]; + D = state[3]; + + 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 = state[0] += A; + B = state[1] += B; + C = state[2] += C; + D = state[3] += D; + } +} +#undef X +#endif + +#undef DATA_ORDER_IS_LITTLE_ENDIAN +#undef HASH_CTX +#undef HASH_CBLOCK +#undef HASH_UPDATE +#undef HASH_TRANSFORM +#undef HASH_FINAL +#undef HASH_MAKE_STRING +#undef HASH_BLOCK_DATA_ORDER +#undef F +#undef G +#undef H +#undef I +#undef ROTATE +#undef R0 +#undef R1 +#undef R2 +#undef R3 +#undef HOST_c2l +#undef HOST_l2c diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/md5/md5.c.back b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/md5/md5.c.back new file mode 100644 index 0000000..32429da --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/md5/md5.c.back @@ -0,0 +1,298 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 "../../internal.h" + + +uint8_t *MD5(const uint8_t *data, size_t len, uint8_t *out) { + MD5_CTX ctx; + MD5_Init(&ctx); + MD5_Update(&ctx, data, len); + MD5_Final(out, &ctx); + + return out; +} + +int MD5_Init(MD5_CTX *md5) { + OPENSSL_memset(md5, 0, sizeof(MD5_CTX)); + md5->h[0] = 0x67452301UL; + md5->h[1] = 0xefcdab89UL; + md5->h[2] = 0x98badcfeUL; + md5->h[3] = 0x10325476UL; + return 1; +} + +#if !defined(OPENSSL_NO_ASM) && \ + (defined(OPENSSL_X86_64) || defined(OPENSSL_X86)) +#define MD5_ASM +#define md5_block_data_order md5_block_asm_data_order +#endif + + +void md5_block_data_order(uint32_t *state, const uint8_t *data, size_t num); + +#define DATA_ORDER_IS_LITTLE_ENDIAN + +#define HASH_CTX MD5_CTX +#define HASH_CBLOCK 64 +#define HASH_UPDATE MD5_Update +#define HASH_TRANSFORM MD5_Transform +#define HASH_FINAL MD5_Final +#define HASH_MAKE_STRING(c, s) \ + do { \ + uint32_t ll; \ + ll = (c)->h[0]; \ + HOST_l2c(ll, (s)); \ + ll = (c)->h[1]; \ + HOST_l2c(ll, (s)); \ + ll = (c)->h[2]; \ + HOST_l2c(ll, (s)); \ + ll = (c)->h[3]; \ + HOST_l2c(ll, (s)); \ + } while (0) +#define HASH_BLOCK_DATA_ORDER md5_block_data_order + +#include "../digest/md32_common.h" + +// 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 ROTATE(a, n) (((a) << (n)) | ((a) >> (32 - (n)))) + +#define R0(a, b, c, d, k, s, t) \ + do { \ + (a) += ((k) + (t) + F((b), (c), (d))); \ + (a) = ROTATE(a, s); \ + (a) += (b); \ + } while (0) + +#define R1(a, b, c, d, k, s, t) \ + do { \ + (a) += ((k) + (t) + G((b), (c), (d))); \ + (a) = ROTATE(a, s); \ + (a) += (b); \ + } while (0) + +#define R2(a, b, c, d, k, s, t) \ + do { \ + (a) += ((k) + (t) + H((b), (c), (d))); \ + (a) = ROTATE(a, s); \ + (a) += (b); \ + } while (0) + +#define R3(a, b, c, d, k, s, t) \ + do { \ + (a) += ((k) + (t) + I((b), (c), (d))); \ + (a) = ROTATE(a, s); \ + (a) += (b); \ + } while (0) + +#ifndef md5_block_data_order +#ifdef X +#undef X +#endif +void md5_block_data_order(uint32_t *state, const uint8_t *data, size_t num) { + uint32_t A, B, C, D, l; + uint32_t XX0, XX1, XX2, XX3, XX4, XX5, XX6, XX7, XX8, XX9, XX10, XX11, XX12, + XX13, XX14, XX15; +#define X(i) XX##i + + A = state[0]; + B = state[1]; + C = state[2]; + D = state[3]; + + 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 = state[0] += A; + B = state[1] += B; + C = state[2] += C; + D = state[3] += D; + } +} +#undef X +#endif + +#undef DATA_ORDER_IS_LITTLE_ENDIAN +#undef HASH_CTX +#undef HASH_CBLOCK +#undef HASH_UPDATE +#undef HASH_TRANSFORM +#undef HASH_FINAL +#undef HASH_MAKE_STRING +#undef HASH_BLOCK_DATA_ORDER +#undef F +#undef G +#undef H +#undef I +#undef ROTATE +#undef R0 +#undef R1 +#undef R2 +#undef R3 +#undef HOST_c2l +#undef HOST_l2c diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/md5/md5.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/md5/md5.c.grpc_back new file mode 100644 index 0000000..fd822b4 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/md5/md5.c.grpc_back @@ -0,0 +1,298 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 "../../internal.h" + + +uint8_t *MD5(const uint8_t *data, size_t len, uint8_t *out) { + MD5_CTX ctx; + MD5_Init(&ctx); + MD5_Update(&ctx, data, len); + MD5_Final(out, &ctx); + + return out; +} + +int MD5_Init(MD5_CTX *md5) { + OPENSSL_memset(md5, 0, sizeof(MD5_CTX)); + md5->h[0] = 0x67452301UL; + md5->h[1] = 0xefcdab89UL; + md5->h[2] = 0x98badcfeUL; + md5->h[3] = 0x10325476UL; + return 1; +} + +#if !defined(OPENSSL_NO_ASM) && \ + (defined(OPENSSL_X86_64) || defined(OPENSSL_X86)) +#define MD5_ASM +#define md5_block_data_order md5_block_asm_data_order +#endif + + +void md5_block_data_order(uint32_t *state, const uint8_t *data, size_t num); + +#define DATA_ORDER_IS_LITTLE_ENDIAN + +#define HASH_CTX MD5_CTX +#define HASH_CBLOCK 64 +#define HASH_UPDATE MD5_Update +#define HASH_TRANSFORM MD5_Transform +#define HASH_FINAL MD5_Final +#define HASH_MAKE_STRING(c, s) \ + do { \ + uint32_t ll; \ + ll = (c)->h[0]; \ + HOST_l2c(ll, (s)); \ + ll = (c)->h[1]; \ + HOST_l2c(ll, (s)); \ + ll = (c)->h[2]; \ + HOST_l2c(ll, (s)); \ + ll = (c)->h[3]; \ + HOST_l2c(ll, (s)); \ + } while (0) +#define HASH_BLOCK_DATA_ORDER md5_block_data_order + +#include "../digest/md32_common.h" + +// 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 ROTATE(a, n) (((a) << (n)) | ((a) >> (32 - (n)))) + +#define R0(a, b, c, d, k, s, t) \ + do { \ + (a) += ((k) + (t) + F((b), (c), (d))); \ + (a) = ROTATE(a, s); \ + (a) += (b); \ + } while (0) + +#define R1(a, b, c, d, k, s, t) \ + do { \ + (a) += ((k) + (t) + G((b), (c), (d))); \ + (a) = ROTATE(a, s); \ + (a) += (b); \ + } while (0) + +#define R2(a, b, c, d, k, s, t) \ + do { \ + (a) += ((k) + (t) + H((b), (c), (d))); \ + (a) = ROTATE(a, s); \ + (a) += (b); \ + } while (0) + +#define R3(a, b, c, d, k, s, t) \ + do { \ + (a) += ((k) + (t) + I((b), (c), (d))); \ + (a) = ROTATE(a, s); \ + (a) += (b); \ + } while (0) + +#ifndef GRPC_SHADOW_md5_block_data_order +#ifdef X +#undef X +#endif +void md5_block_data_order(uint32_t *state, const uint8_t *data, size_t num) { + uint32_t A, B, C, D, l; + uint32_t XX0, XX1, XX2, XX3, XX4, XX5, XX6, XX7, XX8, XX9, XX10, XX11, XX12, + XX13, XX14, XX15; +#define X(i) XX##i + + A = state[0]; + B = state[1]; + C = state[2]; + D = state[3]; + + 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 = state[0] += A; + B = state[1] += B; + C = state[2] += C; + D = state[3] += D; + } +} +#undef X +#endif + +#undef DATA_ORDER_IS_LITTLE_ENDIAN +#undef HASH_CTX +#undef HASH_CBLOCK +#undef HASH_UPDATE +#undef HASH_TRANSFORM +#undef HASH_FINAL +#undef HASH_MAKE_STRING +#undef HASH_BLOCK_DATA_ORDER +#undef F +#undef G +#undef H +#undef I +#undef ROTATE +#undef R0 +#undef R1 +#undef R2 +#undef R3 +#undef HOST_c2l +#undef HOST_l2c diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/modes/cbc.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/modes/cbc.c new file mode 100644 index 0000000..db9f024 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/modes/cbc.c @@ -0,0 +1,211 @@ +/* ==================================================================== + * 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 +#include + +#include "internal.h" + + +void CRYPTO_cbc128_encrypt(const uint8_t *in, uint8_t *out, size_t len, + const void *key, uint8_t ivec[16], + block128_f block) { + size_t n; + const uint8_t *iv = ivec; + + assert(key != NULL && ivec != NULL); + assert(len == 0 || (in != NULL && out != NULL)); + + if (STRICT_ALIGNMENT && + ((uintptr_t)in | (uintptr_t)out | (uintptr_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)) { + store_word_le(out + n, load_word_le(in + n) ^ load_word_le(iv + n)); + } + (*block)(out, out, key); + iv = out; + len -= 16; + in += 16; + out += 16; + } + } + + 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; + } + + OPENSSL_memcpy(ivec, iv, 16); +} + +void CRYPTO_cbc128_decrypt(const uint8_t *in, uint8_t *out, size_t len, + const void *key, uint8_t ivec[16], + block128_f block) { + size_t n; + union { + size_t t[16 / sizeof(size_t)]; + uint8_t c[16]; + } tmp; + + assert(key != NULL && ivec != NULL); + assert(len == 0 || (in != NULL && out != NULL)); + + const uintptr_t inptr = (uintptr_t) in; + const uintptr_t outptr = (uintptr_t) out; + // If |in| and |out| alias, |in| must be ahead. + assert(inptr >= outptr || inptr + len <= outptr); + + if ((inptr >= 32 && outptr <= inptr - 32) || inptr < outptr) { + // If |out| is at least two blocks behind |in| or completely disjoint, there + // is no need to decrypt to a temporary block. + const uint8_t *iv = ivec; + + if (STRICT_ALIGNMENT && + ((uintptr_t)in | (uintptr_t)out | (uintptr_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) { + (*block)(in, out, key); + for (n = 0; n < 16; n += sizeof(size_t)) { + store_word_le(out + n, load_word_le(out + n) ^ load_word_le(iv + n)); + } + iv = in; + len -= 16; + in += 16; + out += 16; + } + } + OPENSSL_memcpy(ivec, iv, 16); + } else { + // |out| is less than two blocks behind |in|. Decrypting an input block + // directly to |out| would overwrite a ciphertext block before it is used as + // the next block's IV. Decrypt to a temporary block instead. + if (STRICT_ALIGNMENT && + ((uintptr_t)in | (uintptr_t)out | (uintptr_t)ivec) % sizeof(size_t) != + 0) { + uint8_t 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) { + (*block)(in, tmp.c, key); + for (n = 0; n < 16; n += sizeof(size_t)) { + size_t c = load_word_le(in + n); + store_word_le(out + n, + tmp.t[n / sizeof(size_t)] ^ load_word_le(ivec + n)); + store_word_le(ivec + n, c); + } + len -= 16; + in += 16; + out += 16; + } + } + } + + while (len) { + uint8_t 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/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/modes/cbc.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/modes/cbc.c.grpc_back new file mode 100644 index 0000000..db9f024 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/modes/cbc.c.grpc_back @@ -0,0 +1,211 @@ +/* ==================================================================== + * 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 +#include + +#include "internal.h" + + +void CRYPTO_cbc128_encrypt(const uint8_t *in, uint8_t *out, size_t len, + const void *key, uint8_t ivec[16], + block128_f block) { + size_t n; + const uint8_t *iv = ivec; + + assert(key != NULL && ivec != NULL); + assert(len == 0 || (in != NULL && out != NULL)); + + if (STRICT_ALIGNMENT && + ((uintptr_t)in | (uintptr_t)out | (uintptr_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)) { + store_word_le(out + n, load_word_le(in + n) ^ load_word_le(iv + n)); + } + (*block)(out, out, key); + iv = out; + len -= 16; + in += 16; + out += 16; + } + } + + 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; + } + + OPENSSL_memcpy(ivec, iv, 16); +} + +void CRYPTO_cbc128_decrypt(const uint8_t *in, uint8_t *out, size_t len, + const void *key, uint8_t ivec[16], + block128_f block) { + size_t n; + union { + size_t t[16 / sizeof(size_t)]; + uint8_t c[16]; + } tmp; + + assert(key != NULL && ivec != NULL); + assert(len == 0 || (in != NULL && out != NULL)); + + const uintptr_t inptr = (uintptr_t) in; + const uintptr_t outptr = (uintptr_t) out; + // If |in| and |out| alias, |in| must be ahead. + assert(inptr >= outptr || inptr + len <= outptr); + + if ((inptr >= 32 && outptr <= inptr - 32) || inptr < outptr) { + // If |out| is at least two blocks behind |in| or completely disjoint, there + // is no need to decrypt to a temporary block. + const uint8_t *iv = ivec; + + if (STRICT_ALIGNMENT && + ((uintptr_t)in | (uintptr_t)out | (uintptr_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) { + (*block)(in, out, key); + for (n = 0; n < 16; n += sizeof(size_t)) { + store_word_le(out + n, load_word_le(out + n) ^ load_word_le(iv + n)); + } + iv = in; + len -= 16; + in += 16; + out += 16; + } + } + OPENSSL_memcpy(ivec, iv, 16); + } else { + // |out| is less than two blocks behind |in|. Decrypting an input block + // directly to |out| would overwrite a ciphertext block before it is used as + // the next block's IV. Decrypt to a temporary block instead. + if (STRICT_ALIGNMENT && + ((uintptr_t)in | (uintptr_t)out | (uintptr_t)ivec) % sizeof(size_t) != + 0) { + uint8_t 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) { + (*block)(in, tmp.c, key); + for (n = 0; n < 16; n += sizeof(size_t)) { + size_t c = load_word_le(in + n); + store_word_le(out + n, + tmp.t[n / sizeof(size_t)] ^ load_word_le(ivec + n)); + store_word_le(ivec + n, c); + } + len -= 16; + in += 16; + out += 16; + } + } + } + + while (len) { + uint8_t 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/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/modes/ccm.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/modes/ccm.c new file mode 100644 index 0000000..9c35d48 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/modes/ccm.c @@ -0,0 +1,256 @@ +/* ==================================================================== + * 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 +#include + +#include +#include + +#include "../../internal.h" +#include "internal.h" + + +struct ccm128_state { + union { + uint64_t u[2]; + uint8_t c[16]; + } nonce, cmac; +}; + +int CRYPTO_ccm128_init(CCM128_CONTEXT *ctx, const void *key, block128_f block, + ctr128_f ctr, unsigned M, unsigned L) { + if (M < 4 || M > 16 || (M & 1) != 0 || L < 2 || L > 8) { + return 0; + } + ctx->block = block; + ctx->ctr = ctr; + ctx->M = M; + ctx->L = L; + return 1; +} + +size_t CRYPTO_ccm128_max_input(const CCM128_CONTEXT *ctx) { + return ctx->L >= sizeof(size_t) ? (size_t)-1 + : (((size_t)1) << (ctx->L * 8)) - 1; +} + +static int ccm128_init_state(const CCM128_CONTEXT *ctx, + struct ccm128_state *state, const void *key, + const uint8_t *nonce, size_t nonce_len, + const uint8_t *aad, size_t aad_len, + size_t plaintext_len) { + const block128_f block = ctx->block; + const unsigned M = ctx->M; + const unsigned L = ctx->L; + + // |L| determines the expected |nonce_len| and the limit for |plaintext_len|. + if (plaintext_len > CRYPTO_ccm128_max_input(ctx) || + nonce_len != 15 - L) { + return 0; + } + + // Assemble the first block for computing the MAC. + OPENSSL_memset(state, 0, sizeof(*state)); + state->nonce.c[0] = (uint8_t)((L - 1) | ((M - 2) / 2) << 3); + if (aad_len != 0) { + state->nonce.c[0] |= 0x40; // Set AAD Flag + } + OPENSSL_memcpy(&state->nonce.c[1], nonce, nonce_len); + for (unsigned i = 0; i < L; i++) { + state->nonce.c[15 - i] = (uint8_t)(plaintext_len >> (8 * i)); + } + + (*block)(state->nonce.c, state->cmac.c, key); + size_t blocks = 1; + + if (aad_len != 0) { + unsigned i; + // Cast to u64 to avoid the compiler complaining about invalid shifts. + uint64_t aad_len_u64 = aad_len; + if (aad_len_u64 < 0x10000 - 0x100) { + state->cmac.c[0] ^= (uint8_t)(aad_len_u64 >> 8); + state->cmac.c[1] ^= (uint8_t)aad_len_u64; + i = 2; + } else if (aad_len_u64 <= 0xffffffff) { + state->cmac.c[0] ^= 0xff; + state->cmac.c[1] ^= 0xfe; + state->cmac.c[2] ^= (uint8_t)(aad_len_u64 >> 24); + state->cmac.c[3] ^= (uint8_t)(aad_len_u64 >> 16); + state->cmac.c[4] ^= (uint8_t)(aad_len_u64 >> 8); + state->cmac.c[5] ^= (uint8_t)aad_len_u64; + i = 6; + } else { + state->cmac.c[0] ^= 0xff; + state->cmac.c[1] ^= 0xff; + state->cmac.c[2] ^= (uint8_t)(aad_len_u64 >> 56); + state->cmac.c[3] ^= (uint8_t)(aad_len_u64 >> 48); + state->cmac.c[4] ^= (uint8_t)(aad_len_u64 >> 40); + state->cmac.c[5] ^= (uint8_t)(aad_len_u64 >> 32); + state->cmac.c[6] ^= (uint8_t)(aad_len_u64 >> 24); + state->cmac.c[7] ^= (uint8_t)(aad_len_u64 >> 16); + state->cmac.c[8] ^= (uint8_t)(aad_len_u64 >> 8); + state->cmac.c[9] ^= (uint8_t)aad_len_u64; + i = 10; + } + + do { + for (; i < 16 && aad_len != 0; i++) { + state->cmac.c[i] ^= *aad; + aad++; + aad_len--; + } + (*block)(state->cmac.c, state->cmac.c, key); + blocks++; + i = 0; + } while (aad_len != 0); + } + + // Per RFC 3610, section 2.6, the total number of block cipher operations done + // must not exceed 2^61. There are two block cipher operations remaining per + // message block, plus one block at the end to encrypt the MAC. + size_t remaining_blocks = 2 * ((plaintext_len + 15) / 16) + 1; + if (plaintext_len + 15 < plaintext_len || + remaining_blocks + blocks < blocks || + (uint64_t) remaining_blocks + blocks > UINT64_C(1) << 61) { + return 0; + } + + // Assemble the first block for encrypting and decrypting. The bottom |L| + // bytes are replaced with a counter and all bit the encoding of |L| is + // cleared in the first byte. + state->nonce.c[0] &= 7; + return 1; +} + +static int ccm128_encrypt(const CCM128_CONTEXT *ctx, struct ccm128_state *state, + const void *key, uint8_t *out, const uint8_t *in, + size_t len) { + // The counter for encryption begins at one. + for (unsigned i = 0; i < ctx->L; i++) { + state->nonce.c[15 - i] = 0; + } + state->nonce.c[15] = 1; + + uint8_t partial_buf[16]; + unsigned num = 0; + if (ctx->ctr != NULL) { + CRYPTO_ctr128_encrypt_ctr32(in, out, len, key, state->nonce.c, partial_buf, + &num, ctx->ctr); + } else { + CRYPTO_ctr128_encrypt(in, out, len, key, state->nonce.c, partial_buf, &num, + ctx->block); + } + return 1; +} + +static int ccm128_compute_mac(const CCM128_CONTEXT *ctx, + struct ccm128_state *state, const void *key, + uint8_t *out_tag, size_t tag_len, + const uint8_t *in, size_t len) { + block128_f block = ctx->block; + if (tag_len != ctx->M) { + return 0; + } + + // Incorporate |in| into the MAC. + union { + uint64_t u[2]; + uint8_t c[16]; + } tmp; + while (len >= 16) { + OPENSSL_memcpy(tmp.c, in, 16); + state->cmac.u[0] ^= tmp.u[0]; + state->cmac.u[1] ^= tmp.u[1]; + (*block)(state->cmac.c, state->cmac.c, key); + in += 16; + len -= 16; + } + if (len > 0) { + for (size_t i = 0; i < len; i++) { + state->cmac.c[i] ^= in[i]; + } + (*block)(state->cmac.c, state->cmac.c, key); + } + + // Encrypt the MAC with counter zero. + for (unsigned i = 0; i < ctx->L; i++) { + state->nonce.c[15 - i] = 0; + } + (*block)(state->nonce.c, tmp.c, key); + state->cmac.u[0] ^= tmp.u[0]; + state->cmac.u[1] ^= tmp.u[1]; + + OPENSSL_memcpy(out_tag, state->cmac.c, tag_len); + return 1; +} + +int CRYPTO_ccm128_encrypt(const CCM128_CONTEXT *ctx, const void *key, + uint8_t *out, uint8_t *out_tag, size_t tag_len, + const uint8_t *nonce, size_t nonce_len, + const uint8_t *in, size_t len, const uint8_t *aad, + size_t aad_len) { + struct ccm128_state state; + return ccm128_init_state(ctx, &state, key, nonce, nonce_len, aad, aad_len, + len) && + ccm128_compute_mac(ctx, &state, key, out_tag, tag_len, in, len) && + ccm128_encrypt(ctx, &state, key, out, in, len); +} + +int CRYPTO_ccm128_decrypt(const CCM128_CONTEXT *ctx, const void *key, + uint8_t *out, uint8_t *out_tag, size_t tag_len, + const uint8_t *nonce, size_t nonce_len, + const uint8_t *in, size_t len, const uint8_t *aad, + size_t aad_len) { + struct ccm128_state state; + return ccm128_init_state(ctx, &state, key, nonce, nonce_len, aad, aad_len, + len) && + ccm128_encrypt(ctx, &state, key, out, in, len) && + ccm128_compute_mac(ctx, &state, key, out_tag, tag_len, out, len); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/modes/ccm.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/modes/ccm.c.grpc_back new file mode 100644 index 0000000..784e4fa --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/modes/ccm.c.grpc_back @@ -0,0 +1,256 @@ +/* ==================================================================== + * 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 +#include + +#include +#include + +#include "../../internal.h" +#include "internal.h" + + +struct ccm128_state { + union { + uint64_t u[2]; + uint8_t c[16]; + } nonce, cmac; +}; + +int CRYPTO_ccm128_init(CCM128_CONTEXT *ctx, const void *key, block128_f block, + ctr128_f ctr, unsigned M, unsigned L) { + if (M < 4 || M > 16 || (M & 1) != 0 || L < 2 || L > 8) { + return 0; + } + ctx->block = block; + ctx->ctr = ctr; + ctx->M = M; + ctx->L = L; + return 1; +} + +size_t CRYPTO_ccm128_max_input(const CCM128_CONTEXT *ctx) { + return ctx->L >= sizeof(size_t) ? (size_t)-1 + : (((size_t)1) << (ctx->L * 8)) - 1; +} + +static int ccm128_init_state(const CCM128_CONTEXT *ctx, + struct ccm128_state *state, const void *key, + const uint8_t *nonce, size_t nonce_len, + const uint8_t *aad, size_t aad_len, + size_t plaintext_len) { + const block128_f block = ctx->block; + const unsigned M = ctx->M; + const unsigned L = ctx->L; + + // |L| determines the expected |nonce_len| and the limit for |plaintext_len|. + if (plaintext_len > CRYPTO_ccm128_max_input(ctx) || + nonce_len != 15 - L) { + return 0; + } + + // Assemble the first block for computing the MAC. + OPENSSL_memset(state, 0, sizeof(*state)); + state->nonce.c[0] = (uint8_t)((L - 1) | ((M - 2) / 2) << 3); + if (aad_len != 0) { + state->nonce.c[0] |= 0x40; // Set AAD Flag + } + OPENSSL_memcpy(&state->nonce.c[1], nonce, nonce_len); + for (unsigned i = 0; i < L; i++) { + state->nonce.c[15 - i] = (uint8_t)(plaintext_len >> (8 * i)); + } + + (*block)(state->nonce.c, state->cmac.c, key); + size_t blocks = 1; + + if (aad_len != 0) { + unsigned i; + // Cast to u64 to avoid the compiler complaining about invalid shifts. + uint64_t aad_len_u64 = aad_len; + if (aad_len_u64 < 0x10000 - 0x100) { + state->cmac.c[0] ^= (uint8_t)(aad_len_u64 >> 8); + state->cmac.c[1] ^= (uint8_t)aad_len_u64; + i = 2; + } else if (aad_len_u64 <= 0xffffffff) { + state->cmac.c[0] ^= 0xff; + state->cmac.c[1] ^= 0xfe; + state->cmac.c[2] ^= (uint8_t)(aad_len_u64 >> 24); + state->cmac.c[3] ^= (uint8_t)(aad_len_u64 >> 16); + state->cmac.c[4] ^= (uint8_t)(aad_len_u64 >> 8); + state->cmac.c[5] ^= (uint8_t)aad_len_u64; + i = 6; + } else { + state->cmac.c[0] ^= 0xff; + state->cmac.c[1] ^= 0xff; + state->cmac.c[2] ^= (uint8_t)(aad_len_u64 >> 56); + state->cmac.c[3] ^= (uint8_t)(aad_len_u64 >> 48); + state->cmac.c[4] ^= (uint8_t)(aad_len_u64 >> 40); + state->cmac.c[5] ^= (uint8_t)(aad_len_u64 >> 32); + state->cmac.c[6] ^= (uint8_t)(aad_len_u64 >> 24); + state->cmac.c[7] ^= (uint8_t)(aad_len_u64 >> 16); + state->cmac.c[8] ^= (uint8_t)(aad_len_u64 >> 8); + state->cmac.c[9] ^= (uint8_t)aad_len_u64; + i = 10; + } + + do { + for (; i < 16 && aad_len != 0; i++) { + state->cmac.c[i] ^= *aad; + aad++; + aad_len--; + } + (*block)(state->cmac.c, state->cmac.c, key); + blocks++; + i = 0; + } while (aad_len != 0); + } + + // Per RFC 3610, section 2.6, the total number of block cipher operations done + // must not exceed 2^61. There are two block cipher operations remaining per + // message block, plus one block at the end to encrypt the MAC. + size_t remaining_blocks = 2 * ((plaintext_len + 15) / 16) + 1; + if (plaintext_len + 15 < plaintext_len || + remaining_blocks + blocks < blocks || + (uint64_t) remaining_blocks + blocks > UINT64_C(1) << 61) { + return 0; + } + + // Assemble the first block for encrypting and decrypting. The bottom |L| + // bytes are replaced with a counter and all bit the encoding of |L| is + // cleared in the first byte. + state->nonce.c[0] &= 7; + return 1; +} + +static int ccm128_encrypt(const CCM128_CONTEXT *ctx, struct ccm128_state *state, + const void *key, uint8_t *out, const uint8_t *in, + size_t len) { + // The counter for encryption begins at one. + for (unsigned i = 0; i < ctx->L; i++) { + state->nonce.c[15 - i] = 0; + } + state->nonce.c[15] = 1; + + uint8_t partial_buf[16]; + unsigned num = 0; + if (ctx->ctr != NULL) { + CRYPTO_ctr128_encrypt_ctr32(in, out, len, key, state->nonce.c, partial_buf, + &num, ctx->ctr); + } else { + CRYPTO_ctr128_encrypt(in, out, len, key, state->nonce.c, partial_buf, &num, + ctx->block); + } + return 1; +} + +static int ccm128_compute_mac(const CCM128_CONTEXT *ctx, + struct ccm128_state *state, const void *key, + uint8_t *out_tag, size_t tag_len, + const uint8_t *in, size_t len) { + block128_f block = ctx->block; + if (tag_len != ctx->M) { + return 0; + } + + // Incorporate |in| into the MAC. + union { + uint64_t u[2]; + uint8_t c[16]; + } tmp; + while (len >= 16) { + OPENSSL_memcpy(tmp.c, in, 16); + state->cmac.u[0] ^= tmp.u[0]; + state->cmac.u[1] ^= tmp.u[1]; + (*block)(state->cmac.c, state->cmac.c, key); + in += 16; + len -= 16; + } + if (len > 0) { + for (size_t i = 0; i < len; i++) { + state->cmac.c[i] ^= in[i]; + } + (*block)(state->cmac.c, state->cmac.c, key); + } + + // Encrypt the MAC with counter zero. + for (unsigned i = 0; i < ctx->L; i++) { + state->nonce.c[15 - i] = 0; + } + (*block)(state->nonce.c, tmp.c, key); + state->cmac.u[0] ^= tmp.u[0]; + state->cmac.u[1] ^= tmp.u[1]; + + OPENSSL_memcpy(out_tag, state->cmac.c, tag_len); + return 1; +} + +int CRYPTO_ccm128_encrypt(const CCM128_CONTEXT *ctx, const void *key, + uint8_t *out, uint8_t *out_tag, size_t tag_len, + const uint8_t *nonce, size_t nonce_len, + const uint8_t *in, size_t len, const uint8_t *aad, + size_t aad_len) { + struct ccm128_state state; + return ccm128_init_state(ctx, &state, key, nonce, nonce_len, aad, aad_len, + len) && + ccm128_compute_mac(ctx, &state, key, out_tag, tag_len, in, len) && + ccm128_encrypt(ctx, &state, key, out, in, len); +} + +int CRYPTO_ccm128_decrypt(const CCM128_CONTEXT *ctx, const void *key, + uint8_t *out, uint8_t *out_tag, size_t tag_len, + const uint8_t *nonce, size_t nonce_len, + const uint8_t *in, size_t len, const uint8_t *aad, + size_t aad_len) { + struct ccm128_state state; + return ccm128_init_state(ctx, &state, key, nonce, nonce_len, aad, aad_len, + len) && + ccm128_encrypt(ctx, &state, key, out, in, len) && + ccm128_compute_mac(ctx, &state, key, out_tag, tag_len, out, len); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/modes/cfb.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/modes/cfb.c new file mode 100644 index 0000000..a32e315 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/modes/cfb.c @@ -0,0 +1,234 @@ +/* ==================================================================== + * 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 + +#include +#include + +#include "internal.h" + + +OPENSSL_COMPILE_ASSERT((16 % sizeof(size_t)) == 0, bad_size_t_size_cfb); + +void CRYPTO_cfb128_encrypt(const uint8_t *in, uint8_t *out, size_t len, + const void *key, uint8_t ivec[16], unsigned *num, + int enc, block128_f block) { + size_t l = 0; + + assert(in && out && key && ivec && num); + + unsigned n = *num; + + if (enc) { + while (n && len) { + *(out++) = ivec[n] ^= *(in++); + --len; + n = (n + 1) % 16; + } +#if STRICT_ALIGNMENT + if (((uintptr_t)in | (uintptr_t)out | (uintptr_t)ivec) % sizeof(size_t) != + 0) { + while (l < len) { + if (n == 0) { + (*block)(ivec, ivec, key); + } + out[l] = ivec[n] ^= in[l]; + ++l; + n = (n + 1) % 16; + } + *num = n; + return; + } +#endif + while (len >= 16) { + (*block)(ivec, ivec, key); + for (; n < 16; n += sizeof(size_t)) { + size_t tmp = load_word_le(ivec + n) ^ load_word_le(in + n); + store_word_le(ivec + n, tmp); + store_word_le(out + n, tmp); + } + 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; + } else { + while (n && len) { + uint8_t c; + *(out++) = ivec[n] ^ (c = *(in++)); + ivec[n] = c; + --len; + n = (n + 1) % 16; + } + if (STRICT_ALIGNMENT && + ((uintptr_t)in | (uintptr_t)out | (uintptr_t)ivec) % sizeof(size_t) != + 0) { + while (l < len) { + uint8_t 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; + return; + } + while (len >= 16) { + (*block)(ivec, ivec, key); + for (; n < 16; n += sizeof(size_t)) { + size_t t = load_word_le(in + n); + store_word_le(out + n, load_word_le(ivec + n) ^ t); + store_word_le(ivec + n, t); + } + len -= 16; + out += 16; + in += 16; + n = 0; + } + if (len) { + (*block)(ivec, ivec, key); + while (len--) { + uint8_t c; + out[n] = ivec[n] ^ (c = in[n]); + ivec[n] = c; + ++n; + } + } + *num = n; + return; + } +} + + +/* 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 uint8_t *in, uint8_t *out, unsigned nbits, + const void *key, uint8_t ivec[16], int enc, + block128_f block) { + int n, rem, num; + uint8_t 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 + OPENSSL_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) { + OPENSSL_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 uint8_t *in, uint8_t *out, size_t bits, + const void *key, uint8_t ivec[16], unsigned *num, + int enc, block128_f block) { + size_t n; + uint8_t 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], unsigned *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/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/modes/cfb.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/modes/cfb.c.grpc_back new file mode 100644 index 0000000..e1b0a80 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/modes/cfb.c.grpc_back @@ -0,0 +1,234 @@ +/* ==================================================================== + * 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 + +#include +#include + +#include "internal.h" + + +OPENSSL_COMPILE_ASSERT((16 % sizeof(size_t)) == 0, bad_size_t_size_cfb); + +void CRYPTO_cfb128_encrypt(const uint8_t *in, uint8_t *out, size_t len, + const void *key, uint8_t ivec[16], unsigned *num, + int enc, block128_f block) { + size_t l = 0; + + assert(in && out && key && ivec && num); + + unsigned n = *num; + + if (enc) { + while (n && len) { + *(out++) = ivec[n] ^= *(in++); + --len; + n = (n + 1) % 16; + } +#if STRICT_ALIGNMENT + if (((uintptr_t)in | (uintptr_t)out | (uintptr_t)ivec) % sizeof(size_t) != + 0) { + while (l < len) { + if (n == 0) { + (*block)(ivec, ivec, key); + } + out[l] = ivec[n] ^= in[l]; + ++l; + n = (n + 1) % 16; + } + *num = n; + return; + } +#endif + while (len >= 16) { + (*block)(ivec, ivec, key); + for (; n < 16; n += sizeof(size_t)) { + size_t tmp = load_word_le(ivec + n) ^ load_word_le(in + n); + store_word_le(ivec + n, tmp); + store_word_le(out + n, tmp); + } + 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; + } else { + while (n && len) { + uint8_t c; + *(out++) = ivec[n] ^ (c = *(in++)); + ivec[n] = c; + --len; + n = (n + 1) % 16; + } + if (STRICT_ALIGNMENT && + ((uintptr_t)in | (uintptr_t)out | (uintptr_t)ivec) % sizeof(size_t) != + 0) { + while (l < len) { + uint8_t 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; + return; + } + while (len >= 16) { + (*block)(ivec, ivec, key); + for (; n < 16; n += sizeof(size_t)) { + size_t t = load_word_le(in + n); + store_word_le(out + n, load_word_le(ivec + n) ^ t); + store_word_le(ivec + n, t); + } + len -= 16; + out += 16; + in += 16; + n = 0; + } + if (len) { + (*block)(ivec, ivec, key); + while (len--) { + uint8_t c; + out[n] = ivec[n] ^ (c = in[n]); + ivec[n] = c; + ++n; + } + } + *num = n; + return; + } +} + + +/* 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 uint8_t *in, uint8_t *out, unsigned nbits, + const void *key, uint8_t ivec[16], int enc, + block128_f block) { + int n, rem, num; + uint8_t 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 + OPENSSL_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) { + OPENSSL_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 uint8_t *in, uint8_t *out, size_t bits, + const void *key, uint8_t ivec[16], unsigned *num, + int enc, block128_f block) { + size_t n; + uint8_t 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], unsigned *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/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/modes/ctr.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/modes/ctr.c new file mode 100644 index 0000000..d996388 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/modes/ctr.c @@ -0,0 +1,220 @@ +/* ==================================================================== + * 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 + +#include +#include + +#include "internal.h" + + +// 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(uint8_t *counter) { + uint32_t n = 16, c = 1; + + do { + --n; + c += counter[n]; + counter[n] = (uint8_t) c; + c >>= 8; + } while (n); +} + +OPENSSL_COMPILE_ASSERT((16 % sizeof(size_t)) == 0, bad_size_t_size_ctr); + +// 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 responsibility for checking that +// the counter doesn't overflow into the rest of the IV when incremented. +void CRYPTO_ctr128_encrypt(const uint8_t *in, uint8_t *out, size_t len, + const void *key, uint8_t ivec[16], + uint8_t ecount_buf[16], unsigned int *num, + block128_f block) { + unsigned int n; + + assert(key && ecount_buf && num); + assert(len == 0 || (in && out)); + assert(*num < 16); + + n = *num; + + while (n && len) { + *(out++) = *(in++) ^ ecount_buf[n]; + --len; + n = (n + 1) % 16; + } + +#if STRICT_ALIGNMENT + if (((uintptr_t)in | (uintptr_t)out | + (uintptr_t)ecount_buf) % sizeof(size_t) != 0) { + size_t l = 0; + 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; + return; + } +#endif + + while (len >= 16) { + (*block)(ivec, ecount_buf, key); + ctr128_inc(ivec); + for (n = 0; n < 16; n += sizeof(size_t)) { + store_word_le(out + n, + load_word_le(in + n) ^ load_word_le(ecount_buf + n)); + } + len -= 16; + out += 16; + in += 16; + n = 0; + } + if (len) { + (*block)(ivec, ecount_buf, key); + ctr128_inc(ivec); + while (len--) { + out[n] = in[n] ^ ecount_buf[n]; + ++n; + } + } + *num = n; +} + +// increment upper 96 bits of 128-bit counter by 1 +static void ctr96_inc(uint8_t *counter) { + uint32_t n = 12, c = 1; + + do { + --n; + c += counter[n]; + counter[n] = (uint8_t) c; + c >>= 8; + } while (n); +} + +void CRYPTO_ctr128_encrypt_ctr32(const uint8_t *in, uint8_t *out, + size_t len, const void *key, + uint8_t ivec[16], + uint8_t ecount_buf[16], + unsigned int *num, ctr128_f func) { + unsigned int n, ctr32; + + assert(key && ecount_buf && num); + assert(len == 0 || (in && out)); + 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 += (uint32_t)blocks; + if (ctr32 < blocks) { + blocks -= ctr32; + ctr32 = 0; + } + (*func)(in, out, blocks, key, ivec); + // (*func) 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) { + OPENSSL_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/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/modes/ctr.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/modes/ctr.c.grpc_back new file mode 100644 index 0000000..63907b4 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/modes/ctr.c.grpc_back @@ -0,0 +1,220 @@ +/* ==================================================================== + * 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 + +#include +#include + +#include "internal.h" + + +// 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(uint8_t *counter) { + uint32_t n = 16, c = 1; + + do { + --n; + c += counter[n]; + counter[n] = (uint8_t) c; + c >>= 8; + } while (n); +} + +OPENSSL_COMPILE_ASSERT((16 % sizeof(size_t)) == 0, bad_size_t_size_ctr); + +// 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 responsibility for checking that +// the counter doesn't overflow into the rest of the IV when incremented. +void CRYPTO_ctr128_encrypt(const uint8_t *in, uint8_t *out, size_t len, + const void *key, uint8_t ivec[16], + uint8_t ecount_buf[16], unsigned int *num, + block128_f block) { + unsigned int n; + + assert(key && ecount_buf && num); + assert(len == 0 || (in && out)); + assert(*num < 16); + + n = *num; + + while (n && len) { + *(out++) = *(in++) ^ ecount_buf[n]; + --len; + n = (n + 1) % 16; + } + +#if STRICT_ALIGNMENT + if (((uintptr_t)in | (uintptr_t)out | + (uintptr_t)ecount_buf) % sizeof(size_t) != 0) { + size_t l = 0; + 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; + return; + } +#endif + + while (len >= 16) { + (*block)(ivec, ecount_buf, key); + ctr128_inc(ivec); + for (n = 0; n < 16; n += sizeof(size_t)) { + store_word_le(out + n, + load_word_le(in + n) ^ load_word_le(ecount_buf + n)); + } + len -= 16; + out += 16; + in += 16; + n = 0; + } + if (len) { + (*block)(ivec, ecount_buf, key); + ctr128_inc(ivec); + while (len--) { + out[n] = in[n] ^ ecount_buf[n]; + ++n; + } + } + *num = n; +} + +// increment upper 96 bits of 128-bit counter by 1 +static void ctr96_inc(uint8_t *counter) { + uint32_t n = 12, c = 1; + + do { + --n; + c += counter[n]; + counter[n] = (uint8_t) c; + c >>= 8; + } while (n); +} + +void CRYPTO_ctr128_encrypt_ctr32(const uint8_t *in, uint8_t *out, + size_t len, const void *key, + uint8_t ivec[16], + uint8_t ecount_buf[16], + unsigned int *num, ctr128_f func) { + unsigned int n, ctr32; + + assert(key && ecount_buf && num); + assert(len == 0 || (in && out)); + 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 += (uint32_t)blocks; + if (ctr32 < blocks) { + blocks -= ctr32; + ctr32 = 0; + } + (*func)(in, out, blocks, key, ivec); + // (*func) 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) { + OPENSSL_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/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/modes/gcm.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/modes/gcm.c new file mode 100644 index 0000000..50796e8 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/modes/gcm.c @@ -0,0 +1,1063 @@ +/* ==================================================================== + * 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 + +#include +#include + +#include +#include + +#include "internal.h" +#include "../../internal.h" + +#if !defined(OPENSSL_NO_ASM) && \ + (defined(OPENSSL_X86) || defined(OPENSSL_X86_64) || \ + defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64) || \ + defined(OPENSSL_PPC64LE)) +#define GHASH_ASM +#endif + +#define PACK(s) ((size_t)(s) << (sizeof(size_t) * 8 - 16)) +#define REDUCE1BIT(V) \ + do { \ + if (sizeof(size_t) == 8) { \ + uint64_t T = UINT64_C(0xe100000000000000) & (0 - ((V).lo & 1)); \ + (V).lo = ((V).hi << 63) | ((V).lo >> 1); \ + (V).hi = ((V).hi >> 1) ^ T; \ + } else { \ + uint32_t T = 0xe1000000U & (0 - (uint32_t)((V).lo & 1)); \ + (V).lo = ((V).hi << 63) | ((V).lo >> 1); \ + (V).hi = ((V).hi >> 1) ^ ((uint64_t)T << 32); \ + } \ + } while (0) + +// kSizeTWithoutLower4Bits is a mask that can be used to zero the lower four +// bits of a |size_t|. +static const size_t kSizeTWithoutLower4Bits = (size_t) -16; + +static void gcm_init_4bit(u128 Htable[16], uint64_t H[2]) { + u128 V; + + Htable[0].hi = 0; + Htable[0].lo = 0; + V.hi = H[0]; + V.lo = H[1]; + + 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; + +#if defined(GHASH_ASM) && defined(OPENSSL_ARM) + for (int j = 0; j < 16; ++j) { + V = Htable[j]; + Htable[j].hi = V.lo; + Htable[j].lo = V.hi; + } +#endif +} + +#if !defined(GHASH_ASM) || defined(OPENSSL_AARCH64) || defined(OPENSSL_PPC64LE) +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(uint64_t Xi[2], const u128 Htable[16]) { + u128 Z; + int cnt = 15; + size_t rem, nlo, nhi; + + nlo = ((const uint8_t *)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 ^= (uint64_t)rem_4bit[rem] << 32; + } + + Z.hi ^= Htable[nhi].hi; + Z.lo ^= Htable[nhi].lo; + + if (--cnt < 0) { + break; + } + + nlo = ((const uint8_t *)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 ^= (uint64_t)rem_4bit[rem] << 32; + } + + Z.hi ^= Htable[nlo].hi; + Z.lo ^= Htable[nlo].lo; + } + + Xi[0] = CRYPTO_bswap8(Z.hi); + Xi[1] = CRYPTO_bswap8(Z.lo); +} + +// 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(uint64_t Xi[2], const u128 Htable[16], + const uint8_t *inp, size_t len) { + u128 Z; + int cnt; + size_t rem, nlo, nhi; + + do { + cnt = 15; + nlo = ((const uint8_t *)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 ^= (uint64_t)rem_4bit[rem] << 32; + } + + Z.hi ^= Htable[nhi].hi; + Z.lo ^= Htable[nhi].lo; + + if (--cnt < 0) { + break; + } + + nlo = ((const uint8_t *)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 ^= (uint64_t)rem_4bit[rem] << 32; + } + + Z.hi ^= Htable[nlo].hi; + Z.lo ^= Htable[nlo].lo; + } + + Xi[0] = CRYPTO_bswap8(Z.hi); + Xi[1] = CRYPTO_bswap8(Z.lo); + } while (inp += 16, len -= 16); +} +#else // GHASH_ASM +void gcm_gmult_4bit(uint64_t Xi[2], const u128 Htable[16]); +void gcm_ghash_4bit(uint64_t Xi[2], const u128 Htable[16], const uint8_t *inp, + size_t len); +#endif + +#define GCM_MUL(ctx, Xi) gcm_gmult_4bit((ctx)->Xi.u, (ctx)->Htable) +#if defined(GHASH_ASM) +#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 + + +#if defined(GHASH_ASM) + +#if defined(OPENSSL_X86) || defined(OPENSSL_X86_64) +#define GCM_FUNCREF_4BIT +void gcm_init_clmul(u128 Htable[16], const uint64_t Xi[2]); +void gcm_gmult_clmul(uint64_t Xi[2], const u128 Htable[16]); +void gcm_ghash_clmul(uint64_t Xi[2], const u128 Htable[16], const uint8_t *inp, + size_t len); + +#if defined(OPENSSL_X86_64) +#define GHASH_ASM_X86_64 +void gcm_init_avx(u128 Htable[16], const uint64_t Xi[2]); +void gcm_gmult_avx(uint64_t Xi[2], const u128 Htable[16]); +void gcm_ghash_avx(uint64_t Xi[2], const u128 Htable[16], const uint8_t *in, + size_t len); +#define AESNI_GCM +size_t aesni_gcm_encrypt(const uint8_t *in, uint8_t *out, size_t len, + const void *key, uint8_t ivec[16], uint64_t *Xi); +size_t aesni_gcm_decrypt(const uint8_t *in, uint8_t *out, size_t len, + const void *key, uint8_t ivec[16], uint64_t *Xi); +#endif + +#if defined(OPENSSL_X86) +#define GHASH_ASM_X86 +void gcm_gmult_4bit_mmx(uint64_t Xi[2], const u128 Htable[16]); +void gcm_ghash_4bit_mmx(uint64_t Xi[2], const u128 Htable[16], const uint8_t *inp, + size_t len); +#endif + +#elif defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64) +#include +#if __ARM_ARCH__ >= 7 +#define GHASH_ASM_ARM +#define GCM_FUNCREF_4BIT + +static int pmull_capable(void) { + return CRYPTO_is_ARMv8_PMULL_capable(); +} + +void gcm_init_v8(u128 Htable[16], const uint64_t Xi[2]); +void gcm_gmult_v8(uint64_t Xi[2], const u128 Htable[16]); +void gcm_ghash_v8(uint64_t Xi[2], const u128 Htable[16], const uint8_t *inp, + size_t len); + +#if defined(OPENSSL_ARM) +// 32-bit ARM also has support for doing GCM with NEON instructions. +static int neon_capable(void) { + return CRYPTO_is_NEON_capable(); +} + +void gcm_init_neon(u128 Htable[16], const uint64_t Xi[2]); +void gcm_gmult_neon(uint64_t Xi[2], const u128 Htable[16]); +void gcm_ghash_neon(uint64_t Xi[2], const u128 Htable[16], const uint8_t *inp, + size_t len); +#else +// AArch64 only has the ARMv8 versions of functions. +static int neon_capable(void) { + return 0; +} +static void gcm_init_neon(u128 Htable[16], const uint64_t Xi[2]) { + abort(); +} +static void gcm_gmult_neon(uint64_t Xi[2], const u128 Htable[16]) { + abort(); +} +static void gcm_ghash_neon(uint64_t Xi[2], const u128 Htable[16], + const uint8_t *inp, size_t len) { + abort(); +} +#endif + +#endif +#elif defined(OPENSSL_PPC64LE) +#define GHASH_ASM_PPC64LE +#define GCM_FUNCREF_4BIT +void gcm_init_p8(u128 Htable[16], const uint64_t Xi[2]); +void gcm_gmult_p8(uint64_t Xi[2], const u128 Htable[16]); +void gcm_ghash_p8(uint64_t Xi[2], const u128 Htable[16], const uint8_t *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_ghash_init(gmult_func *out_mult, ghash_func *out_hash, + u128 *out_key, u128 out_table[16], + int *out_is_avx, + const uint8_t *gcm_key) { + *out_is_avx = 0; + + union { + uint64_t u[2]; + uint8_t c[16]; + } H; + + OPENSSL_memcpy(H.c, gcm_key, 16); + + // H is stored in host byte order + H.u[0] = CRYPTO_bswap8(H.u[0]); + H.u[1] = CRYPTO_bswap8(H.u[1]); + + OPENSSL_memcpy(out_key, H.c, 16); + +#if defined(GHASH_ASM_X86_64) + if (crypto_gcm_clmul_enabled()) { + if (((OPENSSL_ia32cap_get()[1] >> 22) & 0x41) == 0x41) { // AVX+MOVBE + gcm_init_avx(out_table, H.u); + *out_mult = gcm_gmult_avx; + *out_hash = gcm_ghash_avx; + *out_is_avx = 1; + return; + } + gcm_init_clmul(out_table, H.u); + *out_mult = gcm_gmult_clmul; + *out_hash = gcm_ghash_clmul; + return; + } +#elif defined(GHASH_ASM_X86) + if (crypto_gcm_clmul_enabled()) { + gcm_init_clmul(out_table, H.u); + *out_mult = gcm_gmult_clmul; + *out_hash = gcm_ghash_clmul; + return; + } +#elif defined(GHASH_ASM_ARM) + if (pmull_capable()) { + gcm_init_v8(out_table, H.u); + *out_mult = gcm_gmult_v8; + *out_hash = gcm_ghash_v8; + return; + } + + if (neon_capable()) { + gcm_init_neon(out_table, H.u); + *out_mult = gcm_gmult_neon; + *out_hash = gcm_ghash_neon; + return; + } +#elif defined(GHASH_ASM_PPC64LE) + if (CRYPTO_is_PPC64LE_vcrypto_capable()) { + gcm_init_p8(out_table, H.u); + *out_mult = gcm_gmult_p8; + *out_hash = gcm_ghash_p8; + return; + } +#endif + + gcm_init_4bit(out_table, H.u); +#if defined(GHASH_ASM_X86) + *out_mult = gcm_gmult_4bit_mmx; + *out_hash = gcm_ghash_4bit_mmx; +#else + *out_mult = gcm_gmult_4bit; + *out_hash = gcm_ghash_4bit; +#endif +} + +void CRYPTO_gcm128_init(GCM128_CONTEXT *ctx, const void *aes_key, + block128_f block, int is_aesni_encrypt) { + OPENSSL_memset(ctx, 0, sizeof(*ctx)); + ctx->block = block; + + uint8_t gcm_key[16]; + OPENSSL_memset(gcm_key, 0, sizeof(gcm_key)); + (*block)(gcm_key, gcm_key, aes_key); + + int is_avx; + CRYPTO_ghash_init(&ctx->gmult, &ctx->ghash, &ctx->H, ctx->Htable, &is_avx, + gcm_key); + + ctx->use_aesni_gcm_crypt = (is_avx && is_aesni_encrypt) ? 1 : 0; +} + +void CRYPTO_gcm128_setiv(GCM128_CONTEXT *ctx, const void *key, + const uint8_t *iv, size_t len) { + unsigned int ctr; +#ifdef GCM_FUNCREF_4BIT + void (*gcm_gmult_p)(uint64_t 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) { + OPENSSL_memcpy(ctx->Yi.c, iv, 12); + ctx->Yi.c[15] = 1; + ctr = 1; + } else { + uint64_t len0 = len; + + while (len >= 16) { + for (size_t i = 0; i < 16; ++i) { + ctx->Yi.c[i] ^= iv[i]; + } + GCM_MUL(ctx, Yi); + iv += 16; + len -= 16; + } + if (len) { + for (size_t i = 0; i < len; ++i) { + ctx->Yi.c[i] ^= iv[i]; + } + GCM_MUL(ctx, Yi); + } + len0 <<= 3; + ctx->Yi.u[1] ^= CRYPTO_bswap8(len0); + + GCM_MUL(ctx, Yi); + ctr = CRYPTO_bswap4(ctx->Yi.d[3]); + } + + (*ctx->block)(ctx->Yi.c, ctx->EK0.c, key); + ++ctr; + ctx->Yi.d[3] = CRYPTO_bswap4(ctr); +} + +int CRYPTO_gcm128_aad(GCM128_CONTEXT *ctx, const uint8_t *aad, size_t len) { + unsigned int n; + uint64_t alen = ctx->len.u[0]; +#ifdef GCM_FUNCREF_4BIT + void (*gcm_gmult_p)(uint64_t Xi[2], const u128 Htable[16]) = ctx->gmult; +#ifdef GHASH + void (*gcm_ghash_p)(uint64_t Xi[2], const u128 Htable[16], const uint8_t *inp, + size_t len) = ctx->ghash; +#endif +#endif + + if (ctx->len.u[1]) { + return 0; + } + + alen += len; + if (alen > (UINT64_C(1) << 61) || (sizeof(len) == 8 && alen < len)) { + return 0; + } + 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 1; + } + } + + // Process a whole number of blocks. +#ifdef GHASH + size_t len_blocks = len & kSizeTWithoutLower4Bits; + if (len_blocks != 0) { + GHASH(ctx, aad, len_blocks); + aad += len_blocks; + len -= len_blocks; + } +#else + while (len >= 16) { + for (size_t i = 0; i < 16; ++i) { + ctx->Xi.c[i] ^= aad[i]; + } + GCM_MUL(ctx, Xi); + aad += 16; + len -= 16; + } +#endif + + // Process the remainder. + if (len != 0) { + n = (unsigned int)len; + for (size_t i = 0; i < len; ++i) { + ctx->Xi.c[i] ^= aad[i]; + } + } + + ctx->ares = n; + return 1; +} + +int CRYPTO_gcm128_encrypt(GCM128_CONTEXT *ctx, const void *key, + const uint8_t *in, uint8_t *out, size_t len) { + unsigned int n, ctr; + uint64_t mlen = ctx->len.u[1]; + block128_f block = ctx->block; +#ifdef GCM_FUNCREF_4BIT + void (*gcm_gmult_p)(uint64_t Xi[2], const u128 Htable[16]) = ctx->gmult; +#ifdef GHASH + void (*gcm_ghash_p)(uint64_t Xi[2], const u128 Htable[16], const uint8_t *inp, + size_t len) = ctx->ghash; +#endif +#endif + + mlen += len; + if (mlen > ((UINT64_C(1) << 36) - 32) || + (sizeof(len) == 8 && mlen < len)) { + return 0; + } + ctx->len.u[1] = mlen; + + if (ctx->ares) { + // First call to encrypt finalizes GHASH(AAD) + GCM_MUL(ctx, Xi); + ctx->ares = 0; + } + + ctr = CRYPTO_bswap4(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 1; + } + } + if (STRICT_ALIGNMENT && + ((uintptr_t)in | (uintptr_t)out) % sizeof(size_t) != 0) { + for (size_t i = 0; i < len; ++i) { + if (n == 0) { + (*block)(ctx->Yi.c, ctx->EKi.c, key); + ++ctr; + ctx->Yi.d[3] = CRYPTO_bswap4(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 1; + } +#if defined(GHASH) && defined(GHASH_CHUNK) + while (len >= GHASH_CHUNK) { + size_t j = GHASH_CHUNK; + + while (j) { + (*block)(ctx->Yi.c, ctx->EKi.c, key); + ++ctr; + ctx->Yi.d[3] = CRYPTO_bswap4(ctr); + for (size_t i = 0; i < 16; i += sizeof(size_t)) { + store_word_le(out + i, + load_word_le(in + i) ^ ctx->EKi.t[i / sizeof(size_t)]); + } + out += 16; + in += 16; + j -= 16; + } + GHASH(ctx, out - GHASH_CHUNK, GHASH_CHUNK); + len -= GHASH_CHUNK; + } + size_t len_blocks = len & kSizeTWithoutLower4Bits; + if (len_blocks != 0) { + while (len >= 16) { + (*block)(ctx->Yi.c, ctx->EKi.c, key); + ++ctr; + ctx->Yi.d[3] = CRYPTO_bswap4(ctr); + for (size_t i = 0; i < 16; i += sizeof(size_t)) { + store_word_le(out + i, + load_word_le(in + i) ^ ctx->EKi.t[i / sizeof(size_t)]); + } + out += 16; + in += 16; + len -= 16; + } + GHASH(ctx, out - len_blocks, len_blocks); + } +#else + while (len >= 16) { + (*block)(ctx->Yi.c, ctx->EKi.c, key); + ++ctr; + ctx->Yi.d[3] = CRYPTO_bswap4(ctr); + for (size_t i = 0; i < 16; i += sizeof(size_t)) { + size_t tmp = load_word_le(in + i) ^ ctx->EKi.t[i / sizeof(size_t)]; + store_word_le(out + i, tmp); + ctx->Xi.t[i / sizeof(size_t)] ^= tmp; + } + GCM_MUL(ctx, Xi); + out += 16; + in += 16; + len -= 16; + } +#endif + if (len) { + (*block)(ctx->Yi.c, ctx->EKi.c, key); + ++ctr; + ctx->Yi.d[3] = CRYPTO_bswap4(ctr); + while (len--) { + ctx->Xi.c[n] ^= out[n] = in[n] ^ ctx->EKi.c[n]; + ++n; + } + } + + ctx->mres = n; + return 1; +} + +int CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx, const void *key, + const unsigned char *in, unsigned char *out, + size_t len) { + unsigned int n, ctr; + uint64_t mlen = ctx->len.u[1]; + block128_f block = ctx->block; +#ifdef GCM_FUNCREF_4BIT + void (*gcm_gmult_p)(uint64_t Xi[2], const u128 Htable[16]) = ctx->gmult; +#ifdef GHASH + void (*gcm_ghash_p)(uint64_t Xi[2], const u128 Htable[16], const uint8_t *inp, + size_t len) = ctx->ghash; +#endif +#endif + + mlen += len; + if (mlen > ((UINT64_C(1) << 36) - 32) || + (sizeof(len) == 8 && mlen < len)) { + return 0; + } + ctx->len.u[1] = mlen; + + if (ctx->ares) { + // First call to decrypt finalizes GHASH(AAD) + GCM_MUL(ctx, Xi); + ctx->ares = 0; + } + + ctr = CRYPTO_bswap4(ctx->Yi.d[3]); + + n = ctx->mres; + if (n) { + while (n && len) { + uint8_t 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 1; + } + } + if (STRICT_ALIGNMENT && + ((uintptr_t)in | (uintptr_t)out) % sizeof(size_t) != 0) { + for (size_t i = 0; i < len; ++i) { + uint8_t c; + if (n == 0) { + (*block)(ctx->Yi.c, ctx->EKi.c, key); + ++ctr; + ctx->Yi.d[3] = CRYPTO_bswap4(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 1; + } +#if defined(GHASH) && defined(GHASH_CHUNK) + while (len >= GHASH_CHUNK) { + size_t j = GHASH_CHUNK; + + GHASH(ctx, in, GHASH_CHUNK); + while (j) { + (*block)(ctx->Yi.c, ctx->EKi.c, key); + ++ctr; + ctx->Yi.d[3] = CRYPTO_bswap4(ctr); + for (size_t i = 0; i < 16; i += sizeof(size_t)) { + store_word_le(out + i, + load_word_le(in + i) ^ ctx->EKi.t[i / sizeof(size_t)]); + } + out += 16; + in += 16; + j -= 16; + } + len -= GHASH_CHUNK; + } + size_t len_blocks = len & kSizeTWithoutLower4Bits; + if (len_blocks != 0) { + GHASH(ctx, in, len_blocks); + while (len >= 16) { + (*block)(ctx->Yi.c, ctx->EKi.c, key); + ++ctr; + ctx->Yi.d[3] = CRYPTO_bswap4(ctr); + for (size_t i = 0; i < 16; i += sizeof(size_t)) { + store_word_le(out + i, + load_word_le(in + i) ^ ctx->EKi.t[i / sizeof(size_t)]); + } + out += 16; + in += 16; + len -= 16; + } + } +#else + while (len >= 16) { + (*block)(ctx->Yi.c, ctx->EKi.c, key); + ++ctr; + ctx->Yi.d[3] = CRYPTO_bswap4(ctr); + for (size_t i = 0; i < 16; i += sizeof(size_t)) { + size_t c = load_word_le(in + i); + store_word_le(out + i, c ^ ctx->EKi.t[i / sizeof(size_t)]); + ctx->Xi.t[i / sizeof(size_t)] ^= c; + } + GCM_MUL(ctx, Xi); + out += 16; + in += 16; + len -= 16; + } +#endif + if (len) { + (*block)(ctx->Yi.c, ctx->EKi.c, key); + ++ctr; + ctx->Yi.d[3] = CRYPTO_bswap4(ctr); + while (len--) { + uint8_t c = in[n]; + ctx->Xi.c[n] ^= c; + out[n] = c ^ ctx->EKi.c[n]; + ++n; + } + } + + ctx->mres = n; + return 1; +} + +int CRYPTO_gcm128_encrypt_ctr32(GCM128_CONTEXT *ctx, const void *key, + const uint8_t *in, uint8_t *out, size_t len, + ctr128_f stream) { + unsigned int n, ctr; + uint64_t mlen = ctx->len.u[1]; +#ifdef GCM_FUNCREF_4BIT + void (*gcm_gmult_p)(uint64_t Xi[2], const u128 Htable[16]) = ctx->gmult; +#ifdef GHASH + void (*gcm_ghash_p)(uint64_t Xi[2], const u128 Htable[16], const uint8_t *inp, + size_t len) = ctx->ghash; +#endif +#endif + + mlen += len; + if (mlen > ((UINT64_C(1) << 36) - 32) || + (sizeof(len) == 8 && mlen < len)) { + return 0; + } + ctx->len.u[1] = mlen; + + if (ctx->ares) { + // First call to encrypt finalizes GHASH(AAD) + GCM_MUL(ctx, Xi); + ctx->ares = 0; + } + + 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 1; + } + } + +#if defined(AESNI_GCM) + if (ctx->use_aesni_gcm_crypt) { + // |aesni_gcm_encrypt| may not process all the input given to it. It may + // not process *any* of its input if it is deemed too small. + size_t bulk = aesni_gcm_encrypt(in, out, len, key, ctx->Yi.c, ctx->Xi.u); + in += bulk; + out += bulk; + len -= bulk; + } +#endif + + ctr = CRYPTO_bswap4(ctx->Yi.d[3]); + +#if defined(GHASH) + while (len >= GHASH_CHUNK) { + (*stream)(in, out, GHASH_CHUNK / 16, key, ctx->Yi.c); + ctr += GHASH_CHUNK / 16; + ctx->Yi.d[3] = CRYPTO_bswap4(ctr); + GHASH(ctx, out, GHASH_CHUNK); + out += GHASH_CHUNK; + in += GHASH_CHUNK; + len -= GHASH_CHUNK; + } +#endif + size_t i = len & kSizeTWithoutLower4Bits; + if (i != 0) { + size_t j = i / 16; + + (*stream)(in, out, j, key, ctx->Yi.c); + ctr += (unsigned int)j; + ctx->Yi.d[3] = CRYPTO_bswap4(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; + ctx->Yi.d[3] = CRYPTO_bswap4(ctr); + while (len--) { + ctx->Xi.c[n] ^= out[n] = in[n] ^ ctx->EKi.c[n]; + ++n; + } + } + + ctx->mres = n; + return 1; +} + +int CRYPTO_gcm128_decrypt_ctr32(GCM128_CONTEXT *ctx, const void *key, + const uint8_t *in, uint8_t *out, size_t len, + ctr128_f stream) { + unsigned int n, ctr; + uint64_t mlen = ctx->len.u[1]; +#ifdef GCM_FUNCREF_4BIT + void (*gcm_gmult_p)(uint64_t Xi[2], const u128 Htable[16]) = ctx->gmult; +#ifdef GHASH + void (*gcm_ghash_p)(uint64_t Xi[2], const u128 Htable[16], const uint8_t *inp, + size_t len) = ctx->ghash; +#endif +#endif + + mlen += len; + if (mlen > ((UINT64_C(1) << 36) - 32) || + (sizeof(len) == 8 && mlen < len)) { + return 0; + } + ctx->len.u[1] = mlen; + + if (ctx->ares) { + // First call to decrypt finalizes GHASH(AAD) + GCM_MUL(ctx, Xi); + ctx->ares = 0; + } + + n = ctx->mres; + if (n) { + while (n && len) { + uint8_t 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 1; + } + } + +#if defined(AESNI_GCM) + if (ctx->use_aesni_gcm_crypt) { + // |aesni_gcm_decrypt| may not process all the input given to it. It may + // not process *any* of its input if it is deemed too small. + size_t bulk = aesni_gcm_decrypt(in, out, len, key, ctx->Yi.c, ctx->Xi.u); + in += bulk; + out += bulk; + len -= bulk; + } +#endif + + ctr = CRYPTO_bswap4(ctx->Yi.d[3]); + +#if defined(GHASH) + while (len >= GHASH_CHUNK) { + GHASH(ctx, in, GHASH_CHUNK); + (*stream)(in, out, GHASH_CHUNK / 16, key, ctx->Yi.c); + ctr += GHASH_CHUNK / 16; + ctx->Yi.d[3] = CRYPTO_bswap4(ctr); + out += GHASH_CHUNK; + in += GHASH_CHUNK; + len -= GHASH_CHUNK; + } +#endif + size_t i = len & kSizeTWithoutLower4Bits; + if (i != 0) { + 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; + ctx->Yi.d[3] = CRYPTO_bswap4(ctr); + out += i; + in += i; + len -= i; + } + if (len) { + (*ctx->block)(ctx->Yi.c, ctx->EKi.c, key); + ++ctr; + ctx->Yi.d[3] = CRYPTO_bswap4(ctr); + while (len--) { + uint8_t c = in[n]; + ctx->Xi.c[n] ^= c; + out[n] = c ^ ctx->EKi.c[n]; + ++n; + } + } + + ctx->mres = n; + return 1; +} + +int CRYPTO_gcm128_finish(GCM128_CONTEXT *ctx, const uint8_t *tag, size_t len) { + uint64_t alen = ctx->len.u[0] << 3; + uint64_t clen = ctx->len.u[1] << 3; +#ifdef GCM_FUNCREF_4BIT + void (*gcm_gmult_p)(uint64_t Xi[2], const u128 Htable[16]) = ctx->gmult; +#endif + + if (ctx->mres || ctx->ares) { + GCM_MUL(ctx, Xi); + } + + alen = CRYPTO_bswap8(alen); + clen = CRYPTO_bswap8(clen); + + 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) == 0; + } else { + return 0; + } +} + +void CRYPTO_gcm128_tag(GCM128_CONTEXT *ctx, unsigned char *tag, size_t len) { + CRYPTO_gcm128_finish(ctx, NULL, 0); + OPENSSL_memcpy(tag, ctx->Xi.c, + len <= sizeof(ctx->Xi.c) ? len : sizeof(ctx->Xi.c)); +} + +#if defined(OPENSSL_X86) || defined(OPENSSL_X86_64) +int crypto_gcm_clmul_enabled(void) { +#ifdef GHASH_ASM + const uint32_t *ia32cap = OPENSSL_ia32cap_get(); + return (ia32cap[0] & (1 << 24)) && // check FXSR bit + (ia32cap[1] & (1 << 1)); // check PCLMULQDQ bit +#else + return 0; +#endif +} +#endif diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/modes/gcm.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/modes/gcm.c.grpc_back new file mode 100644 index 0000000..05cd18d --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/modes/gcm.c.grpc_back @@ -0,0 +1,1063 @@ +/* ==================================================================== + * 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 + +#include +#include + +#include +#include + +#include "internal.h" +#include "../../internal.h" + +#if !defined(OPENSSL_NO_ASM) && \ + (defined(OPENSSL_X86) || defined(OPENSSL_X86_64) || \ + defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64) || \ + defined(OPENSSL_PPC64LE)) +#define GHASH_ASM +#endif + +#define PACK(s) ((size_t)(s) << (sizeof(size_t) * 8 - 16)) +#define REDUCE1BIT(V) \ + do { \ + if (sizeof(size_t) == 8) { \ + uint64_t T = UINT64_C(0xe100000000000000) & (0 - ((V).lo & 1)); \ + (V).lo = ((V).hi << 63) | ((V).lo >> 1); \ + (V).hi = ((V).hi >> 1) ^ T; \ + } else { \ + uint32_t T = 0xe1000000U & (0 - (uint32_t)((V).lo & 1)); \ + (V).lo = ((V).hi << 63) | ((V).lo >> 1); \ + (V).hi = ((V).hi >> 1) ^ ((uint64_t)T << 32); \ + } \ + } while (0) + +// kSizeTWithoutLower4Bits is a mask that can be used to zero the lower four +// bits of a |size_t|. +static const size_t kSizeTWithoutLower4Bits = (size_t) -16; + +static void gcm_init_4bit(u128 Htable[16], uint64_t H[2]) { + u128 V; + + Htable[0].hi = 0; + Htable[0].lo = 0; + V.hi = H[0]; + V.lo = H[1]; + + 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; + +#if defined(GHASH_ASM) && defined(OPENSSL_ARM) + for (int j = 0; j < 16; ++j) { + V = Htable[j]; + Htable[j].hi = V.lo; + Htable[j].lo = V.hi; + } +#endif +} + +#if !defined(GHASH_ASM) || defined(OPENSSL_AARCH64) || defined(OPENSSL_PPC64LE) +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(uint64_t Xi[2], const u128 Htable[16]) { + u128 Z; + int cnt = 15; + size_t rem, nlo, nhi; + + nlo = ((const uint8_t *)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 ^= (uint64_t)rem_4bit[rem] << 32; + } + + Z.hi ^= Htable[nhi].hi; + Z.lo ^= Htable[nhi].lo; + + if (--cnt < 0) { + break; + } + + nlo = ((const uint8_t *)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 ^= (uint64_t)rem_4bit[rem] << 32; + } + + Z.hi ^= Htable[nlo].hi; + Z.lo ^= Htable[nlo].lo; + } + + Xi[0] = CRYPTO_bswap8(Z.hi); + Xi[1] = CRYPTO_bswap8(Z.lo); +} + +// 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(uint64_t Xi[2], const u128 Htable[16], + const uint8_t *inp, size_t len) { + u128 Z; + int cnt; + size_t rem, nlo, nhi; + + do { + cnt = 15; + nlo = ((const uint8_t *)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 ^= (uint64_t)rem_4bit[rem] << 32; + } + + Z.hi ^= Htable[nhi].hi; + Z.lo ^= Htable[nhi].lo; + + if (--cnt < 0) { + break; + } + + nlo = ((const uint8_t *)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 ^= (uint64_t)rem_4bit[rem] << 32; + } + + Z.hi ^= Htable[nlo].hi; + Z.lo ^= Htable[nlo].lo; + } + + Xi[0] = CRYPTO_bswap8(Z.hi); + Xi[1] = CRYPTO_bswap8(Z.lo); + } while (inp += 16, len -= 16); +} +#else // GHASH_ASM +void gcm_gmult_4bit(uint64_t Xi[2], const u128 Htable[16]); +void gcm_ghash_4bit(uint64_t Xi[2], const u128 Htable[16], const uint8_t *inp, + size_t len); +#endif + +#define GCM_MUL(ctx, Xi) gcm_gmult_4bit((ctx)->Xi.u, (ctx)->Htable) +#if defined(GHASH_ASM) +#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 + + +#if defined(GHASH_ASM) + +#if defined(OPENSSL_X86) || defined(OPENSSL_X86_64) +#define GCM_FUNCREF_4BIT +void gcm_init_clmul(u128 Htable[16], const uint64_t Xi[2]); +void gcm_gmult_clmul(uint64_t Xi[2], const u128 Htable[16]); +void gcm_ghash_clmul(uint64_t Xi[2], const u128 Htable[16], const uint8_t *inp, + size_t len); + +#if defined(OPENSSL_X86_64) +#define GHASH_ASM_X86_64 +void gcm_init_avx(u128 Htable[16], const uint64_t Xi[2]); +void gcm_gmult_avx(uint64_t Xi[2], const u128 Htable[16]); +void gcm_ghash_avx(uint64_t Xi[2], const u128 Htable[16], const uint8_t *in, + size_t len); +#define AESNI_GCM +size_t aesni_gcm_encrypt(const uint8_t *in, uint8_t *out, size_t len, + const void *key, uint8_t ivec[16], uint64_t *Xi); +size_t aesni_gcm_decrypt(const uint8_t *in, uint8_t *out, size_t len, + const void *key, uint8_t ivec[16], uint64_t *Xi); +#endif + +#if defined(OPENSSL_X86) +#define GHASH_ASM_X86 +void gcm_gmult_4bit_mmx(uint64_t Xi[2], const u128 Htable[16]); +void gcm_ghash_4bit_mmx(uint64_t Xi[2], const u128 Htable[16], const uint8_t *inp, + size_t len); +#endif + +#elif defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64) +#include +#if __ARM_ARCH__ >= 7 +#define GHASH_ASM_ARM +#define GCM_FUNCREF_4BIT + +static int pmull_capable(void) { + return CRYPTO_is_ARMv8_PMULL_capable(); +} + +void gcm_init_v8(u128 Htable[16], const uint64_t Xi[2]); +void gcm_gmult_v8(uint64_t Xi[2], const u128 Htable[16]); +void gcm_ghash_v8(uint64_t Xi[2], const u128 Htable[16], const uint8_t *inp, + size_t len); + +#if defined(OPENSSL_ARM) +// 32-bit ARM also has support for doing GCM with NEON instructions. +static int neon_capable(void) { + return CRYPTO_is_NEON_capable(); +} + +void gcm_init_neon(u128 Htable[16], const uint64_t Xi[2]); +void gcm_gmult_neon(uint64_t Xi[2], const u128 Htable[16]); +void gcm_ghash_neon(uint64_t Xi[2], const u128 Htable[16], const uint8_t *inp, + size_t len); +#else +// AArch64 only has the ARMv8 versions of functions. +static int neon_capable(void) { + return 0; +} +static void gcm_init_neon(u128 Htable[16], const uint64_t Xi[2]) { + abort(); +} +static void gcm_gmult_neon(uint64_t Xi[2], const u128 Htable[16]) { + abort(); +} +static void gcm_ghash_neon(uint64_t Xi[2], const u128 Htable[16], + const uint8_t *inp, size_t len) { + abort(); +} +#endif + +#endif +#elif defined(OPENSSL_PPC64LE) +#define GHASH_ASM_PPC64LE +#define GCM_FUNCREF_4BIT +void gcm_init_p8(u128 Htable[16], const uint64_t Xi[2]); +void gcm_gmult_p8(uint64_t Xi[2], const u128 Htable[16]); +void gcm_ghash_p8(uint64_t Xi[2], const u128 Htable[16], const uint8_t *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_ghash_init(gmult_func *out_mult, ghash_func *out_hash, + u128 *out_key, u128 out_table[16], + int *out_is_avx, + const uint8_t *gcm_key) { + *out_is_avx = 0; + + union { + uint64_t u[2]; + uint8_t c[16]; + } H; + + OPENSSL_memcpy(H.c, gcm_key, 16); + + // H is stored in host byte order + H.u[0] = CRYPTO_bswap8(H.u[0]); + H.u[1] = CRYPTO_bswap8(H.u[1]); + + OPENSSL_memcpy(out_key, H.c, 16); + +#if defined(GHASH_ASM_X86_64) + if (crypto_gcm_clmul_enabled()) { + if (((OPENSSL_ia32cap_get()[1] >> 22) & 0x41) == 0x41) { // AVX+MOVBE + gcm_init_avx(out_table, H.u); + *out_mult = gcm_gmult_avx; + *out_hash = gcm_ghash_avx; + *out_is_avx = 1; + return; + } + gcm_init_clmul(out_table, H.u); + *out_mult = gcm_gmult_clmul; + *out_hash = gcm_ghash_clmul; + return; + } +#elif defined(GHASH_ASM_X86) + if (crypto_gcm_clmul_enabled()) { + gcm_init_clmul(out_table, H.u); + *out_mult = gcm_gmult_clmul; + *out_hash = gcm_ghash_clmul; + return; + } +#elif defined(GHASH_ASM_ARM) + if (pmull_capable()) { + gcm_init_v8(out_table, H.u); + *out_mult = gcm_gmult_v8; + *out_hash = gcm_ghash_v8; + return; + } + + if (neon_capable()) { + gcm_init_neon(out_table, H.u); + *out_mult = gcm_gmult_neon; + *out_hash = gcm_ghash_neon; + return; + } +#elif defined(GHASH_ASM_PPC64LE) + if (CRYPTO_is_PPC64LE_vcrypto_capable()) { + gcm_init_p8(out_table, H.u); + *out_mult = gcm_gmult_p8; + *out_hash = gcm_ghash_p8; + return; + } +#endif + + gcm_init_4bit(out_table, H.u); +#if defined(GHASH_ASM_X86) + *out_mult = gcm_gmult_4bit_mmx; + *out_hash = gcm_ghash_4bit_mmx; +#else + *out_mult = gcm_gmult_4bit; + *out_hash = gcm_ghash_4bit; +#endif +} + +void CRYPTO_gcm128_init(GCM128_CONTEXT *ctx, const void *aes_key, + block128_f block, int is_aesni_encrypt) { + OPENSSL_memset(ctx, 0, sizeof(*ctx)); + ctx->block = block; + + uint8_t gcm_key[16]; + OPENSSL_memset(gcm_key, 0, sizeof(gcm_key)); + (*block)(gcm_key, gcm_key, aes_key); + + int is_avx; + CRYPTO_ghash_init(&ctx->gmult, &ctx->ghash, &ctx->H, ctx->Htable, &is_avx, + gcm_key); + + ctx->use_aesni_gcm_crypt = (is_avx && is_aesni_encrypt) ? 1 : 0; +} + +void CRYPTO_gcm128_setiv(GCM128_CONTEXT *ctx, const void *key, + const uint8_t *iv, size_t len) { + unsigned int ctr; +#ifdef GCM_FUNCREF_4BIT + void (*gcm_gmult_p)(uint64_t 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) { + OPENSSL_memcpy(ctx->Yi.c, iv, 12); + ctx->Yi.c[15] = 1; + ctr = 1; + } else { + uint64_t len0 = len; + + while (len >= 16) { + for (size_t i = 0; i < 16; ++i) { + ctx->Yi.c[i] ^= iv[i]; + } + GCM_MUL(ctx, Yi); + iv += 16; + len -= 16; + } + if (len) { + for (size_t i = 0; i < len; ++i) { + ctx->Yi.c[i] ^= iv[i]; + } + GCM_MUL(ctx, Yi); + } + len0 <<= 3; + ctx->Yi.u[1] ^= CRYPTO_bswap8(len0); + + GCM_MUL(ctx, Yi); + ctr = CRYPTO_bswap4(ctx->Yi.d[3]); + } + + (*ctx->block)(ctx->Yi.c, ctx->EK0.c, key); + ++ctr; + ctx->Yi.d[3] = CRYPTO_bswap4(ctr); +} + +int CRYPTO_gcm128_aad(GCM128_CONTEXT *ctx, const uint8_t *aad, size_t len) { + unsigned int n; + uint64_t alen = ctx->len.u[0]; +#ifdef GCM_FUNCREF_4BIT + void (*gcm_gmult_p)(uint64_t Xi[2], const u128 Htable[16]) = ctx->gmult; +#ifdef GHASH + void (*gcm_ghash_p)(uint64_t Xi[2], const u128 Htable[16], const uint8_t *inp, + size_t len) = ctx->ghash; +#endif +#endif + + if (ctx->len.u[1]) { + return 0; + } + + alen += len; + if (alen > (UINT64_C(1) << 61) || (sizeof(len) == 8 && alen < len)) { + return 0; + } + 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 1; + } + } + + // Process a whole number of blocks. +#ifdef GHASH + size_t len_blocks = len & kSizeTWithoutLower4Bits; + if (len_blocks != 0) { + GHASH(ctx, aad, len_blocks); + aad += len_blocks; + len -= len_blocks; + } +#else + while (len >= 16) { + for (size_t i = 0; i < 16; ++i) { + ctx->Xi.c[i] ^= aad[i]; + } + GCM_MUL(ctx, Xi); + aad += 16; + len -= 16; + } +#endif + + // Process the remainder. + if (len != 0) { + n = (unsigned int)len; + for (size_t i = 0; i < len; ++i) { + ctx->Xi.c[i] ^= aad[i]; + } + } + + ctx->ares = n; + return 1; +} + +int CRYPTO_gcm128_encrypt(GCM128_CONTEXT *ctx, const void *key, + const uint8_t *in, uint8_t *out, size_t len) { + unsigned int n, ctr; + uint64_t mlen = ctx->len.u[1]; + block128_f block = ctx->block; +#ifdef GCM_FUNCREF_4BIT + void (*gcm_gmult_p)(uint64_t Xi[2], const u128 Htable[16]) = ctx->gmult; +#ifdef GHASH + void (*gcm_ghash_p)(uint64_t Xi[2], const u128 Htable[16], const uint8_t *inp, + size_t len) = ctx->ghash; +#endif +#endif + + mlen += len; + if (mlen > ((UINT64_C(1) << 36) - 32) || + (sizeof(len) == 8 && mlen < len)) { + return 0; + } + ctx->len.u[1] = mlen; + + if (ctx->ares) { + // First call to encrypt finalizes GHASH(AAD) + GCM_MUL(ctx, Xi); + ctx->ares = 0; + } + + ctr = CRYPTO_bswap4(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 1; + } + } + if (STRICT_ALIGNMENT && + ((uintptr_t)in | (uintptr_t)out) % sizeof(size_t) != 0) { + for (size_t i = 0; i < len; ++i) { + if (n == 0) { + (*block)(ctx->Yi.c, ctx->EKi.c, key); + ++ctr; + ctx->Yi.d[3] = CRYPTO_bswap4(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 1; + } +#if defined(GHASH) && defined(GHASH_CHUNK) + while (len >= GHASH_CHUNK) { + size_t j = GHASH_CHUNK; + + while (j) { + (*block)(ctx->Yi.c, ctx->EKi.c, key); + ++ctr; + ctx->Yi.d[3] = CRYPTO_bswap4(ctr); + for (size_t i = 0; i < 16; i += sizeof(size_t)) { + store_word_le(out + i, + load_word_le(in + i) ^ ctx->EKi.t[i / sizeof(size_t)]); + } + out += 16; + in += 16; + j -= 16; + } + GHASH(ctx, out - GHASH_CHUNK, GHASH_CHUNK); + len -= GHASH_CHUNK; + } + size_t len_blocks = len & kSizeTWithoutLower4Bits; + if (len_blocks != 0) { + while (len >= 16) { + (*block)(ctx->Yi.c, ctx->EKi.c, key); + ++ctr; + ctx->Yi.d[3] = CRYPTO_bswap4(ctr); + for (size_t i = 0; i < 16; i += sizeof(size_t)) { + store_word_le(out + i, + load_word_le(in + i) ^ ctx->EKi.t[i / sizeof(size_t)]); + } + out += 16; + in += 16; + len -= 16; + } + GHASH(ctx, out - len_blocks, len_blocks); + } +#else + while (len >= 16) { + (*block)(ctx->Yi.c, ctx->EKi.c, key); + ++ctr; + ctx->Yi.d[3] = CRYPTO_bswap4(ctr); + for (size_t i = 0; i < 16; i += sizeof(size_t)) { + size_t tmp = load_word_le(in + i) ^ ctx->EKi.t[i / sizeof(size_t)]; + store_word_le(out + i, tmp); + ctx->Xi.t[i / sizeof(size_t)] ^= tmp; + } + GCM_MUL(ctx, Xi); + out += 16; + in += 16; + len -= 16; + } +#endif + if (len) { + (*block)(ctx->Yi.c, ctx->EKi.c, key); + ++ctr; + ctx->Yi.d[3] = CRYPTO_bswap4(ctr); + while (len--) { + ctx->Xi.c[n] ^= out[n] = in[n] ^ ctx->EKi.c[n]; + ++n; + } + } + + ctx->mres = n; + return 1; +} + +int CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx, const void *key, + const unsigned char *in, unsigned char *out, + size_t len) { + unsigned int n, ctr; + uint64_t mlen = ctx->len.u[1]; + block128_f block = ctx->block; +#ifdef GCM_FUNCREF_4BIT + void (*gcm_gmult_p)(uint64_t Xi[2], const u128 Htable[16]) = ctx->gmult; +#ifdef GHASH + void (*gcm_ghash_p)(uint64_t Xi[2], const u128 Htable[16], const uint8_t *inp, + size_t len) = ctx->ghash; +#endif +#endif + + mlen += len; + if (mlen > ((UINT64_C(1) << 36) - 32) || + (sizeof(len) == 8 && mlen < len)) { + return 0; + } + ctx->len.u[1] = mlen; + + if (ctx->ares) { + // First call to decrypt finalizes GHASH(AAD) + GCM_MUL(ctx, Xi); + ctx->ares = 0; + } + + ctr = CRYPTO_bswap4(ctx->Yi.d[3]); + + n = ctx->mres; + if (n) { + while (n && len) { + uint8_t 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 1; + } + } + if (STRICT_ALIGNMENT && + ((uintptr_t)in | (uintptr_t)out) % sizeof(size_t) != 0) { + for (size_t i = 0; i < len; ++i) { + uint8_t c; + if (n == 0) { + (*block)(ctx->Yi.c, ctx->EKi.c, key); + ++ctr; + ctx->Yi.d[3] = CRYPTO_bswap4(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 1; + } +#if defined(GHASH) && defined(GHASH_CHUNK) + while (len >= GHASH_CHUNK) { + size_t j = GHASH_CHUNK; + + GHASH(ctx, in, GHASH_CHUNK); + while (j) { + (*block)(ctx->Yi.c, ctx->EKi.c, key); + ++ctr; + ctx->Yi.d[3] = CRYPTO_bswap4(ctr); + for (size_t i = 0; i < 16; i += sizeof(size_t)) { + store_word_le(out + i, + load_word_le(in + i) ^ ctx->EKi.t[i / sizeof(size_t)]); + } + out += 16; + in += 16; + j -= 16; + } + len -= GHASH_CHUNK; + } + size_t len_blocks = len & kSizeTWithoutLower4Bits; + if (len_blocks != 0) { + GHASH(ctx, in, len_blocks); + while (len >= 16) { + (*block)(ctx->Yi.c, ctx->EKi.c, key); + ++ctr; + ctx->Yi.d[3] = CRYPTO_bswap4(ctr); + for (size_t i = 0; i < 16; i += sizeof(size_t)) { + store_word_le(out + i, + load_word_le(in + i) ^ ctx->EKi.t[i / sizeof(size_t)]); + } + out += 16; + in += 16; + len -= 16; + } + } +#else + while (len >= 16) { + (*block)(ctx->Yi.c, ctx->EKi.c, key); + ++ctr; + ctx->Yi.d[3] = CRYPTO_bswap4(ctr); + for (size_t i = 0; i < 16; i += sizeof(size_t)) { + size_t c = load_word_le(in + i); + store_word_le(out + i, c ^ ctx->EKi.t[i / sizeof(size_t)]); + ctx->Xi.t[i / sizeof(size_t)] ^= c; + } + GCM_MUL(ctx, Xi); + out += 16; + in += 16; + len -= 16; + } +#endif + if (len) { + (*block)(ctx->Yi.c, ctx->EKi.c, key); + ++ctr; + ctx->Yi.d[3] = CRYPTO_bswap4(ctr); + while (len--) { + uint8_t c = in[n]; + ctx->Xi.c[n] ^= c; + out[n] = c ^ ctx->EKi.c[n]; + ++n; + } + } + + ctx->mres = n; + return 1; +} + +int CRYPTO_gcm128_encrypt_ctr32(GCM128_CONTEXT *ctx, const void *key, + const uint8_t *in, uint8_t *out, size_t len, + ctr128_f stream) { + unsigned int n, ctr; + uint64_t mlen = ctx->len.u[1]; +#ifdef GCM_FUNCREF_4BIT + void (*gcm_gmult_p)(uint64_t Xi[2], const u128 Htable[16]) = ctx->gmult; +#ifdef GHASH + void (*gcm_ghash_p)(uint64_t Xi[2], const u128 Htable[16], const uint8_t *inp, + size_t len) = ctx->ghash; +#endif +#endif + + mlen += len; + if (mlen > ((UINT64_C(1) << 36) - 32) || + (sizeof(len) == 8 && mlen < len)) { + return 0; + } + ctx->len.u[1] = mlen; + + if (ctx->ares) { + // First call to encrypt finalizes GHASH(AAD) + GCM_MUL(ctx, Xi); + ctx->ares = 0; + } + + 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 1; + } + } + +#if defined(AESNI_GCM) + if (ctx->use_aesni_gcm_crypt) { + // |aesni_gcm_encrypt| may not process all the input given to it. It may + // not process *any* of its input if it is deemed too small. + size_t bulk = aesni_gcm_encrypt(in, out, len, key, ctx->Yi.c, ctx->Xi.u); + in += bulk; + out += bulk; + len -= bulk; + } +#endif + + ctr = CRYPTO_bswap4(ctx->Yi.d[3]); + +#if defined(GHASH) + while (len >= GHASH_CHUNK) { + (*stream)(in, out, GHASH_CHUNK / 16, key, ctx->Yi.c); + ctr += GHASH_CHUNK / 16; + ctx->Yi.d[3] = CRYPTO_bswap4(ctr); + GHASH(ctx, out, GHASH_CHUNK); + out += GHASH_CHUNK; + in += GHASH_CHUNK; + len -= GHASH_CHUNK; + } +#endif + size_t i = len & kSizeTWithoutLower4Bits; + if (i != 0) { + size_t j = i / 16; + + (*stream)(in, out, j, key, ctx->Yi.c); + ctr += (unsigned int)j; + ctx->Yi.d[3] = CRYPTO_bswap4(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; + ctx->Yi.d[3] = CRYPTO_bswap4(ctr); + while (len--) { + ctx->Xi.c[n] ^= out[n] = in[n] ^ ctx->EKi.c[n]; + ++n; + } + } + + ctx->mres = n; + return 1; +} + +int CRYPTO_gcm128_decrypt_ctr32(GCM128_CONTEXT *ctx, const void *key, + const uint8_t *in, uint8_t *out, size_t len, + ctr128_f stream) { + unsigned int n, ctr; + uint64_t mlen = ctx->len.u[1]; +#ifdef GCM_FUNCREF_4BIT + void (*gcm_gmult_p)(uint64_t Xi[2], const u128 Htable[16]) = ctx->gmult; +#ifdef GHASH + void (*gcm_ghash_p)(uint64_t Xi[2], const u128 Htable[16], const uint8_t *inp, + size_t len) = ctx->ghash; +#endif +#endif + + mlen += len; + if (mlen > ((UINT64_C(1) << 36) - 32) || + (sizeof(len) == 8 && mlen < len)) { + return 0; + } + ctx->len.u[1] = mlen; + + if (ctx->ares) { + // First call to decrypt finalizes GHASH(AAD) + GCM_MUL(ctx, Xi); + ctx->ares = 0; + } + + n = ctx->mres; + if (n) { + while (n && len) { + uint8_t 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 1; + } + } + +#if defined(AESNI_GCM) + if (ctx->use_aesni_gcm_crypt) { + // |aesni_gcm_decrypt| may not process all the input given to it. It may + // not process *any* of its input if it is deemed too small. + size_t bulk = aesni_gcm_decrypt(in, out, len, key, ctx->Yi.c, ctx->Xi.u); + in += bulk; + out += bulk; + len -= bulk; + } +#endif + + ctr = CRYPTO_bswap4(ctx->Yi.d[3]); + +#if defined(GHASH) + while (len >= GHASH_CHUNK) { + GHASH(ctx, in, GHASH_CHUNK); + (*stream)(in, out, GHASH_CHUNK / 16, key, ctx->Yi.c); + ctr += GHASH_CHUNK / 16; + ctx->Yi.d[3] = CRYPTO_bswap4(ctr); + out += GHASH_CHUNK; + in += GHASH_CHUNK; + len -= GHASH_CHUNK; + } +#endif + size_t i = len & kSizeTWithoutLower4Bits; + if (i != 0) { + 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; + ctx->Yi.d[3] = CRYPTO_bswap4(ctr); + out += i; + in += i; + len -= i; + } + if (len) { + (*ctx->block)(ctx->Yi.c, ctx->EKi.c, key); + ++ctr; + ctx->Yi.d[3] = CRYPTO_bswap4(ctr); + while (len--) { + uint8_t c = in[n]; + ctx->Xi.c[n] ^= c; + out[n] = c ^ ctx->EKi.c[n]; + ++n; + } + } + + ctx->mres = n; + return 1; +} + +int CRYPTO_gcm128_finish(GCM128_CONTEXT *ctx, const uint8_t *tag, size_t len) { + uint64_t alen = ctx->len.u[0] << 3; + uint64_t clen = ctx->len.u[1] << 3; +#ifdef GCM_FUNCREF_4BIT + void (*gcm_gmult_p)(uint64_t Xi[2], const u128 Htable[16]) = ctx->gmult; +#endif + + if (ctx->mres || ctx->ares) { + GCM_MUL(ctx, Xi); + } + + alen = CRYPTO_bswap8(alen); + clen = CRYPTO_bswap8(clen); + + 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) == 0; + } else { + return 0; + } +} + +void CRYPTO_gcm128_tag(GCM128_CONTEXT *ctx, unsigned char *tag, size_t len) { + CRYPTO_gcm128_finish(ctx, NULL, 0); + OPENSSL_memcpy(tag, ctx->Xi.c, + len <= sizeof(ctx->Xi.c) ? len : sizeof(ctx->Xi.c)); +} + +#if defined(OPENSSL_X86) || defined(OPENSSL_X86_64) +int crypto_gcm_clmul_enabled(void) { +#ifdef GHASH_ASM + const uint32_t *ia32cap = OPENSSL_ia32cap_get(); + return (ia32cap[0] & (1 << 24)) && // check FXSR bit + (ia32cap[1] & (1 << 1)); // check PCLMULQDQ bit +#else + return 0; +#endif +} +#endif diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/modes/internal.h b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/modes/internal.h new file mode 100644 index 0000000..08d8d9c --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/modes/internal.h @@ -0,0 +1,388 @@ +/* ==================================================================== + * 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. + * ==================================================================== */ + +#ifndef OPENSSL_HEADER_MODES_INTERNAL_H +#define OPENSSL_HEADER_MODES_INTERNAL_H + +#include + +#include + +#include "../../internal.h" + +#if defined(__cplusplus) +extern "C" { +#endif + + +#define STRICT_ALIGNMENT 1 +#if defined(OPENSSL_X86_64) || defined(OPENSSL_X86) || defined(OPENSSL_AARCH64) +#undef STRICT_ALIGNMENT +#define STRICT_ALIGNMENT 0 +#endif + +static inline uint32_t GETU32(const void *in) { + uint32_t v; + OPENSSL_memcpy(&v, in, sizeof(v)); + return CRYPTO_bswap4(v); +} + +static inline void PUTU32(void *out, uint32_t v) { + v = CRYPTO_bswap4(v); + OPENSSL_memcpy(out, &v, sizeof(v)); +} + +static inline size_t load_word_le(const void *in) { + size_t v; + OPENSSL_memcpy(&v, in, sizeof(v)); + return v; +} + +static inline void store_word_le(void *out, size_t v) { + OPENSSL_memcpy(out, &v, sizeof(v)); +} + +// block128_f is the type of a 128-bit, block cipher. +typedef void (*block128_f)(const uint8_t in[16], uint8_t out[16], + const void *key); + +// GCM definitions +typedef struct { uint64_t hi,lo; } u128; + +// gmult_func multiplies |Xi| by the GCM key and writes the result back to +// |Xi|. +typedef void (*gmult_func)(uint64_t Xi[2], const u128 Htable[16]); + +// ghash_func repeatedly multiplies |Xi| by the GCM key and adds in blocks from +// |inp|. The result is written back to |Xi| and the |len| argument must be a +// multiple of 16. +typedef void (*ghash_func)(uint64_t Xi[2], const u128 Htable[16], + const uint8_t *inp, size_t len); + +// This differs from upstream's |gcm128_context| in that it does not have the +// |key| pointer, in order to make it |memcpy|-friendly. Rather the key is +// passed into each call that needs it. +struct gcm128_context { + // Following 6 names follow names in GCM specification + union { + uint64_t u[2]; + uint32_t d[4]; + uint8_t c[16]; + size_t t[16 / sizeof(size_t)]; + } Yi, EKi, EK0, len, Xi; + + // Note that the order of |Xi|, |H| and |Htable| is fixed by the MOVBE-based, + // x86-64, GHASH assembly. + u128 H; + u128 Htable[16]; + gmult_func gmult; + ghash_func ghash; + + unsigned int mres, ares; + block128_f block; + + // use_aesni_gcm_crypt is true if this context should use the assembly + // functions |aesni_gcm_encrypt| and |aesni_gcm_decrypt| to process data. + unsigned use_aesni_gcm_crypt:1; +}; + +#if defined(OPENSSL_X86) || defined(OPENSSL_X86_64) +// crypto_gcm_clmul_enabled returns one if the CLMUL implementation of GCM is +// used. +int crypto_gcm_clmul_enabled(void); +#endif + + +// CTR. + +// ctr128_f is the type of a function that performs CTR-mode encryption. +typedef void (*ctr128_f)(const uint8_t *in, uint8_t *out, size_t blocks, + const void *key, const uint8_t ivec[16]); + +// CRYPTO_ctr128_encrypt encrypts (or decrypts, it's the same in CTR mode) +// |len| bytes from |in| to |out| using |block| in counter mode. There's no +// requirement that |len| be a multiple of any value and any partial blocks are +// stored in |ecount_buf| and |*num|, which must be zeroed before the initial +// call. The counter is a 128-bit, big-endian value in |ivec| and is +// incremented by this function. +void CRYPTO_ctr128_encrypt(const uint8_t *in, uint8_t *out, size_t len, + const void *key, uint8_t ivec[16], + uint8_t ecount_buf[16], unsigned *num, + block128_f block); + +// CRYPTO_ctr128_encrypt_ctr32 acts like |CRYPTO_ctr128_encrypt| but takes +// |ctr|, a function that performs CTR mode but only deals with the lower 32 +// bits of the counter. This is useful when |ctr| can be an optimised +// function. +void CRYPTO_ctr128_encrypt_ctr32(const uint8_t *in, uint8_t *out, size_t len, + const void *key, uint8_t ivec[16], + uint8_t ecount_buf[16], unsigned *num, + ctr128_f ctr); + +#if !defined(OPENSSL_NO_ASM) && \ + (defined(OPENSSL_X86) || defined(OPENSSL_X86_64)) +void aesni_ctr32_encrypt_blocks(const uint8_t *in, uint8_t *out, size_t blocks, + const void *key, const uint8_t *ivec); +#endif + + +// GCM. +// +// This API differs from the upstream API slightly. The |GCM128_CONTEXT| does +// not have a |key| pointer that points to the key as upstream's version does. +// Instead, every function takes a |key| parameter. This way |GCM128_CONTEXT| +// can be safely copied. + +typedef struct gcm128_context GCM128_CONTEXT; + +// CRYPTO_ghash_init writes a precomputed table of powers of |gcm_key| to +// |out_table| and sets |*out_mult| and |*out_hash| to (potentially hardware +// accelerated) functions for performing operations in the GHASH field. If the +// AVX implementation was used |*out_is_avx| will be true. +void CRYPTO_ghash_init(gmult_func *out_mult, ghash_func *out_hash, + u128 *out_key, u128 out_table[16], int *out_is_avx, + const uint8_t *gcm_key); + +// CRYPTO_gcm128_init initialises |ctx| to use |block| (typically AES) with +// the given key. |is_aesni_encrypt| is one if |block| is |aesni_encrypt|. +OPENSSL_EXPORT void CRYPTO_gcm128_init(GCM128_CONTEXT *ctx, const void *key, + block128_f block, int is_aesni_encrypt); + +// CRYPTO_gcm128_setiv sets the IV (nonce) for |ctx|. The |key| must be the +// same key that was passed to |CRYPTO_gcm128_init|. +OPENSSL_EXPORT void CRYPTO_gcm128_setiv(GCM128_CONTEXT *ctx, const void *key, + const uint8_t *iv, size_t iv_len); + +// CRYPTO_gcm128_aad sets the authenticated data for an instance of GCM. +// This must be called before and data is encrypted. It returns one on success +// and zero otherwise. +OPENSSL_EXPORT int CRYPTO_gcm128_aad(GCM128_CONTEXT *ctx, const uint8_t *aad, + size_t len); + +// CRYPTO_gcm128_encrypt encrypts |len| bytes from |in| to |out|. The |key| +// must be the same key that was passed to |CRYPTO_gcm128_init|. It returns one +// on success and zero otherwise. +OPENSSL_EXPORT int CRYPTO_gcm128_encrypt(GCM128_CONTEXT *ctx, const void *key, + const uint8_t *in, uint8_t *out, + size_t len); + +// CRYPTO_gcm128_decrypt decrypts |len| bytes from |in| to |out|. The |key| +// must be the same key that was passed to |CRYPTO_gcm128_init|. It returns one +// on success and zero otherwise. +OPENSSL_EXPORT int CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx, const void *key, + const uint8_t *in, uint8_t *out, + size_t len); + +// CRYPTO_gcm128_encrypt_ctr32 encrypts |len| bytes from |in| to |out| using +// a CTR function that only handles the bottom 32 bits of the nonce, like +// |CRYPTO_ctr128_encrypt_ctr32|. The |key| must be the same key that was +// passed to |CRYPTO_gcm128_init|. It returns one on success and zero +// otherwise. +OPENSSL_EXPORT int CRYPTO_gcm128_encrypt_ctr32(GCM128_CONTEXT *ctx, + const void *key, + const uint8_t *in, uint8_t *out, + size_t len, ctr128_f stream); + +// CRYPTO_gcm128_decrypt_ctr32 decrypts |len| bytes from |in| to |out| using +// a CTR function that only handles the bottom 32 bits of the nonce, like +// |CRYPTO_ctr128_encrypt_ctr32|. The |key| must be the same key that was +// passed to |CRYPTO_gcm128_init|. It returns one on success and zero +// otherwise. +OPENSSL_EXPORT int CRYPTO_gcm128_decrypt_ctr32(GCM128_CONTEXT *ctx, + const void *key, + const uint8_t *in, uint8_t *out, + size_t len, ctr128_f stream); + +// CRYPTO_gcm128_finish calculates the authenticator and compares it against +// |len| bytes of |tag|. It returns one on success and zero otherwise. +OPENSSL_EXPORT int CRYPTO_gcm128_finish(GCM128_CONTEXT *ctx, const uint8_t *tag, + size_t len); + +// CRYPTO_gcm128_tag calculates the authenticator and copies it into |tag|. +// The minimum of |len| and 16 bytes are copied into |tag|. +OPENSSL_EXPORT void CRYPTO_gcm128_tag(GCM128_CONTEXT *ctx, uint8_t *tag, + size_t len); + + +// CCM. + +typedef struct ccm128_context { + block128_f block; + ctr128_f ctr; + unsigned M, L; +} CCM128_CONTEXT; + +// CRYPTO_ccm128_init initialises |ctx| to use |block| (typically AES) with the +// specified |M| and |L| parameters. It returns one on success and zero if |M| +// or |L| is invalid. +int CRYPTO_ccm128_init(CCM128_CONTEXT *ctx, const void *key, block128_f block, + ctr128_f ctr, unsigned M, unsigned L); + +// CRYPTO_ccm128_max_input returns the maximum input length accepted by |ctx|. +size_t CRYPTO_ccm128_max_input(const CCM128_CONTEXT *ctx); + +// CRYPTO_ccm128_encrypt encrypts |len| bytes from |in| to |out| writing the tag +// to |out_tag|. |key| must be the same key that was passed to +// |CRYPTO_ccm128_init|. It returns one on success and zero otherwise. +int CRYPTO_ccm128_encrypt(const CCM128_CONTEXT *ctx, const void *key, + uint8_t *out, uint8_t *out_tag, size_t tag_len, + const uint8_t *nonce, size_t nonce_len, + const uint8_t *in, size_t len, const uint8_t *aad, + size_t aad_len); + +// CRYPTO_ccm128_decrypt decrypts |len| bytes from |in| to |out|, writing the +// expected tag to |out_tag|. |key| must be the same key that was passed to +// |CRYPTO_ccm128_init|. It returns one on success and zero otherwise. +int CRYPTO_ccm128_decrypt(const CCM128_CONTEXT *ctx, const void *key, + uint8_t *out, uint8_t *out_tag, size_t tag_len, + const uint8_t *nonce, size_t nonce_len, + const uint8_t *in, size_t len, const uint8_t *aad, + size_t aad_len); + + +// CBC. + +// cbc128_f is the type of a function that performs CBC-mode encryption. +typedef void (*cbc128_f)(const uint8_t *in, uint8_t *out, size_t len, + const void *key, uint8_t ivec[16], int enc); + +// CRYPTO_cbc128_encrypt encrypts |len| bytes from |in| to |out| using the +// given IV and block cipher in CBC mode. The input need not be a multiple of +// 128 bits long, but the output will round up to the nearest 128 bit multiple, +// zero padding the input if needed. The IV will be updated on return. +void CRYPTO_cbc128_encrypt(const uint8_t *in, uint8_t *out, size_t len, + const void *key, uint8_t ivec[16], block128_f block); + +// CRYPTO_cbc128_decrypt decrypts |len| bytes from |in| to |out| using the +// given IV and block cipher in CBC mode. If |len| is not a multiple of 128 +// bits then only that many bytes will be written, but a multiple of 128 bits +// is always read from |in|. The IV will be updated on return. +void CRYPTO_cbc128_decrypt(const uint8_t *in, uint8_t *out, size_t len, + const void *key, uint8_t ivec[16], block128_f block); + + +// OFB. + +// CRYPTO_ofb128_encrypt encrypts (or decrypts, it's the same with OFB mode) +// |len| bytes from |in| to |out| using |block| in OFB mode. There's no +// requirement that |len| be a multiple of any value and any partial blocks are +// stored in |ivec| and |*num|, the latter must be zero before the initial +// call. +void CRYPTO_ofb128_encrypt(const uint8_t *in, uint8_t *out, + size_t len, const void *key, uint8_t ivec[16], + unsigned *num, block128_f block); + + +// CFB. + +// CRYPTO_cfb128_encrypt encrypts (or decrypts, if |enc| is zero) |len| bytes +// from |in| to |out| using |block| in CFB mode. There's no requirement that +// |len| be a multiple of any value and any partial blocks are stored in |ivec| +// and |*num|, the latter must be zero before the initial call. +void CRYPTO_cfb128_encrypt(const uint8_t *in, uint8_t *out, size_t len, + const void *key, uint8_t ivec[16], unsigned *num, + int enc, block128_f block); + +// CRYPTO_cfb128_8_encrypt encrypts (or decrypts, if |enc| is zero) |len| bytes +// from |in| to |out| using |block| in CFB-8 mode. Prior to the first call +// |num| should be set to zero. +void CRYPTO_cfb128_8_encrypt(const uint8_t *in, uint8_t *out, size_t len, + const void *key, uint8_t ivec[16], unsigned *num, + int enc, block128_f block); + +// CRYPTO_cfb128_1_encrypt encrypts (or decrypts, if |enc| is zero) |len| bytes +// from |in| to |out| using |block| in CFB-1 mode. Prior to the first call +// |num| should be set to zero. +void CRYPTO_cfb128_1_encrypt(const uint8_t *in, uint8_t *out, size_t bits, + const void *key, uint8_t ivec[16], unsigned *num, + int enc, block128_f block); + +size_t CRYPTO_cts128_encrypt_block(const uint8_t *in, uint8_t *out, size_t len, + const void *key, uint8_t ivec[16], + block128_f block); + + +// POLYVAL. +// +// POLYVAL is a polynomial authenticator that operates over a field very +// similar to the one that GHASH uses. See +// https://tools.ietf.org/html/draft-irtf-cfrg-gcmsiv-02#section-3. + +typedef union { + uint64_t u[2]; + uint8_t c[16]; +} polyval_block; + +struct polyval_ctx { + // Note that the order of |S|, |H| and |Htable| is fixed by the MOVBE-based, + // x86-64, GHASH assembly. + polyval_block S; + u128 H; + u128 Htable[16]; + gmult_func gmult; + ghash_func ghash; +}; + +// CRYPTO_POLYVAL_init initialises |ctx| using |key|. +void CRYPTO_POLYVAL_init(struct polyval_ctx *ctx, const uint8_t key[16]); + +// CRYPTO_POLYVAL_update_blocks updates the accumulator in |ctx| given the +// blocks from |in|. Only a whole number of blocks can be processed so |in_len| +// must be a multiple of 16. +void CRYPTO_POLYVAL_update_blocks(struct polyval_ctx *ctx, const uint8_t *in, + size_t in_len); + +// CRYPTO_POLYVAL_finish writes the accumulator from |ctx| to |out|. +void CRYPTO_POLYVAL_finish(const struct polyval_ctx *ctx, uint8_t out[16]); + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_MODES_INTERNAL_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/modes/internal.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/modes/internal.h.grpc_back new file mode 100644 index 0000000..de6c503 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/modes/internal.h.grpc_back @@ -0,0 +1,388 @@ +/* ==================================================================== + * 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. + * ==================================================================== */ + +#ifndef OPENSSL_HEADER_MODES_INTERNAL_H +#define OPENSSL_HEADER_MODES_INTERNAL_H + +#include + +#include + +#include "../../internal.h" + +#if defined(__cplusplus) +extern "C" { +#endif + + +#define STRICT_ALIGNMENT 1 +#if defined(OPENSSL_X86_64) || defined(OPENSSL_X86) || defined(OPENSSL_AARCH64) +#undef STRICT_ALIGNMENT +#define STRICT_ALIGNMENT 0 +#endif + +static inline uint32_t GETU32(const void *in) { + uint32_t v; + OPENSSL_memcpy(&v, in, sizeof(v)); + return CRYPTO_bswap4(v); +} + +static inline void PUTU32(void *out, uint32_t v) { + v = CRYPTO_bswap4(v); + OPENSSL_memcpy(out, &v, sizeof(v)); +} + +static inline size_t load_word_le(const void *in) { + size_t v; + OPENSSL_memcpy(&v, in, sizeof(v)); + return v; +} + +static inline void store_word_le(void *out, size_t v) { + OPENSSL_memcpy(out, &v, sizeof(v)); +} + +// block128_f is the type of a 128-bit, block cipher. +typedef void (*block128_f)(const uint8_t in[16], uint8_t out[16], + const void *key); + +// GCM definitions +typedef struct { uint64_t hi,lo; } u128; + +// gmult_func multiplies |Xi| by the GCM key and writes the result back to +// |Xi|. +typedef void (*gmult_func)(uint64_t Xi[2], const u128 Htable[16]); + +// ghash_func repeatedly multiplies |Xi| by the GCM key and adds in blocks from +// |inp|. The result is written back to |Xi| and the |len| argument must be a +// multiple of 16. +typedef void (*ghash_func)(uint64_t Xi[2], const u128 Htable[16], + const uint8_t *inp, size_t len); + +// This differs from upstream's |gcm128_context| in that it does not have the +// |key| pointer, in order to make it |memcpy|-friendly. Rather the key is +// passed into each call that needs it. +struct gcm128_context { + // Following 6 names follow names in GCM specification + union { + uint64_t u[2]; + uint32_t d[4]; + uint8_t c[16]; + size_t t[16 / sizeof(size_t)]; + } Yi, EKi, EK0, len, Xi; + + // Note that the order of |Xi|, |H| and |Htable| is fixed by the MOVBE-based, + // x86-64, GHASH assembly. + u128 H; + u128 Htable[16]; + gmult_func gmult; + ghash_func ghash; + + unsigned int mres, ares; + block128_f block; + + // use_aesni_gcm_crypt is true if this context should use the assembly + // functions |aesni_gcm_encrypt| and |aesni_gcm_decrypt| to process data. + unsigned use_aesni_gcm_crypt:1; +}; + +#if defined(OPENSSL_X86) || defined(OPENSSL_X86_64) +// crypto_gcm_clmul_enabled returns one if the CLMUL implementation of GCM is +// used. +int crypto_gcm_clmul_enabled(void); +#endif + + +// CTR. + +// ctr128_f is the type of a function that performs CTR-mode encryption. +typedef void (*ctr128_f)(const uint8_t *in, uint8_t *out, size_t blocks, + const void *key, const uint8_t ivec[16]); + +// CRYPTO_ctr128_encrypt encrypts (or decrypts, it's the same in CTR mode) +// |len| bytes from |in| to |out| using |block| in counter mode. There's no +// requirement that |len| be a multiple of any value and any partial blocks are +// stored in |ecount_buf| and |*num|, which must be zeroed before the initial +// call. The counter is a 128-bit, big-endian value in |ivec| and is +// incremented by this function. +void CRYPTO_ctr128_encrypt(const uint8_t *in, uint8_t *out, size_t len, + const void *key, uint8_t ivec[16], + uint8_t ecount_buf[16], unsigned *num, + block128_f block); + +// CRYPTO_ctr128_encrypt_ctr32 acts like |CRYPTO_ctr128_encrypt| but takes +// |ctr|, a function that performs CTR mode but only deals with the lower 32 +// bits of the counter. This is useful when |ctr| can be an optimised +// function. +void CRYPTO_ctr128_encrypt_ctr32(const uint8_t *in, uint8_t *out, size_t len, + const void *key, uint8_t ivec[16], + uint8_t ecount_buf[16], unsigned *num, + ctr128_f ctr); + +#if !defined(OPENSSL_NO_ASM) && \ + (defined(OPENSSL_X86) || defined(OPENSSL_X86_64)) +void aesni_ctr32_encrypt_blocks(const uint8_t *in, uint8_t *out, size_t blocks, + const void *key, const uint8_t *ivec); +#endif + + +// GCM. +// +// This API differs from the upstream API slightly. The |GCM128_CONTEXT| does +// not have a |key| pointer that points to the key as upstream's version does. +// Instead, every function takes a |key| parameter. This way |GCM128_CONTEXT| +// can be safely copied. + +typedef struct gcm128_context GCM128_CONTEXT; + +// CRYPTO_ghash_init writes a precomputed table of powers of |gcm_key| to +// |out_table| and sets |*out_mult| and |*out_hash| to (potentially hardware +// accelerated) functions for performing operations in the GHASH field. If the +// AVX implementation was used |*out_is_avx| will be true. +void CRYPTO_ghash_init(gmult_func *out_mult, ghash_func *out_hash, + u128 *out_key, u128 out_table[16], int *out_is_avx, + const uint8_t *gcm_key); + +// CRYPTO_gcm128_init initialises |ctx| to use |block| (typically AES) with +// the given key. |is_aesni_encrypt| is one if |block| is |aesni_encrypt|. +OPENSSL_EXPORT void CRYPTO_gcm128_init(GCM128_CONTEXT *ctx, const void *key, + block128_f block, int is_aesni_encrypt); + +// CRYPTO_gcm128_setiv sets the IV (nonce) for |ctx|. The |key| must be the +// same key that was passed to |CRYPTO_gcm128_init|. +OPENSSL_EXPORT void CRYPTO_gcm128_setiv(GCM128_CONTEXT *ctx, const void *key, + const uint8_t *iv, size_t iv_len); + +// CRYPTO_gcm128_aad sets the authenticated data for an instance of GCM. +// This must be called before and data is encrypted. It returns one on success +// and zero otherwise. +OPENSSL_EXPORT int CRYPTO_gcm128_aad(GCM128_CONTEXT *ctx, const uint8_t *aad, + size_t len); + +// CRYPTO_gcm128_encrypt encrypts |len| bytes from |in| to |out|. The |key| +// must be the same key that was passed to |CRYPTO_gcm128_init|. It returns one +// on success and zero otherwise. +OPENSSL_EXPORT int CRYPTO_gcm128_encrypt(GCM128_CONTEXT *ctx, const void *key, + const uint8_t *in, uint8_t *out, + size_t len); + +// CRYPTO_gcm128_decrypt decrypts |len| bytes from |in| to |out|. The |key| +// must be the same key that was passed to |CRYPTO_gcm128_init|. It returns one +// on success and zero otherwise. +OPENSSL_EXPORT int CRYPTO_gcm128_decrypt(GCM128_CONTEXT *ctx, const void *key, + const uint8_t *in, uint8_t *out, + size_t len); + +// CRYPTO_gcm128_encrypt_ctr32 encrypts |len| bytes from |in| to |out| using +// a CTR function that only handles the bottom 32 bits of the nonce, like +// |CRYPTO_ctr128_encrypt_ctr32|. The |key| must be the same key that was +// passed to |CRYPTO_gcm128_init|. It returns one on success and zero +// otherwise. +OPENSSL_EXPORT int CRYPTO_gcm128_encrypt_ctr32(GCM128_CONTEXT *ctx, + const void *key, + const uint8_t *in, uint8_t *out, + size_t len, ctr128_f stream); + +// CRYPTO_gcm128_decrypt_ctr32 decrypts |len| bytes from |in| to |out| using +// a CTR function that only handles the bottom 32 bits of the nonce, like +// |CRYPTO_ctr128_encrypt_ctr32|. The |key| must be the same key that was +// passed to |CRYPTO_gcm128_init|. It returns one on success and zero +// otherwise. +OPENSSL_EXPORT int CRYPTO_gcm128_decrypt_ctr32(GCM128_CONTEXT *ctx, + const void *key, + const uint8_t *in, uint8_t *out, + size_t len, ctr128_f stream); + +// CRYPTO_gcm128_finish calculates the authenticator and compares it against +// |len| bytes of |tag|. It returns one on success and zero otherwise. +OPENSSL_EXPORT int CRYPTO_gcm128_finish(GCM128_CONTEXT *ctx, const uint8_t *tag, + size_t len); + +// CRYPTO_gcm128_tag calculates the authenticator and copies it into |tag|. +// The minimum of |len| and 16 bytes are copied into |tag|. +OPENSSL_EXPORT void CRYPTO_gcm128_tag(GCM128_CONTEXT *ctx, uint8_t *tag, + size_t len); + + +// CCM. + +typedef struct ccm128_context { + block128_f block; + ctr128_f ctr; + unsigned M, L; +} CCM128_CONTEXT; + +// CRYPTO_ccm128_init initialises |ctx| to use |block| (typically AES) with the +// specified |M| and |L| parameters. It returns one on success and zero if |M| +// or |L| is invalid. +int CRYPTO_ccm128_init(CCM128_CONTEXT *ctx, const void *key, block128_f block, + ctr128_f ctr, unsigned M, unsigned L); + +// CRYPTO_ccm128_max_input returns the maximum input length accepted by |ctx|. +size_t CRYPTO_ccm128_max_input(const CCM128_CONTEXT *ctx); + +// CRYPTO_ccm128_encrypt encrypts |len| bytes from |in| to |out| writing the tag +// to |out_tag|. |key| must be the same key that was passed to +// |CRYPTO_ccm128_init|. It returns one on success and zero otherwise. +int CRYPTO_ccm128_encrypt(const CCM128_CONTEXT *ctx, const void *key, + uint8_t *out, uint8_t *out_tag, size_t tag_len, + const uint8_t *nonce, size_t nonce_len, + const uint8_t *in, size_t len, const uint8_t *aad, + size_t aad_len); + +// CRYPTO_ccm128_decrypt decrypts |len| bytes from |in| to |out|, writing the +// expected tag to |out_tag|. |key| must be the same key that was passed to +// |CRYPTO_ccm128_init|. It returns one on success and zero otherwise. +int CRYPTO_ccm128_decrypt(const CCM128_CONTEXT *ctx, const void *key, + uint8_t *out, uint8_t *out_tag, size_t tag_len, + const uint8_t *nonce, size_t nonce_len, + const uint8_t *in, size_t len, const uint8_t *aad, + size_t aad_len); + + +// CBC. + +// cbc128_f is the type of a function that performs CBC-mode encryption. +typedef void (*cbc128_f)(const uint8_t *in, uint8_t *out, size_t len, + const void *key, uint8_t ivec[16], int enc); + +// CRYPTO_cbc128_encrypt encrypts |len| bytes from |in| to |out| using the +// given IV and block cipher in CBC mode. The input need not be a multiple of +// 128 bits long, but the output will round up to the nearest 128 bit multiple, +// zero padding the input if needed. The IV will be updated on return. +void CRYPTO_cbc128_encrypt(const uint8_t *in, uint8_t *out, size_t len, + const void *key, uint8_t ivec[16], block128_f block); + +// CRYPTO_cbc128_decrypt decrypts |len| bytes from |in| to |out| using the +// given IV and block cipher in CBC mode. If |len| is not a multiple of 128 +// bits then only that many bytes will be written, but a multiple of 128 bits +// is always read from |in|. The IV will be updated on return. +void CRYPTO_cbc128_decrypt(const uint8_t *in, uint8_t *out, size_t len, + const void *key, uint8_t ivec[16], block128_f block); + + +// OFB. + +// CRYPTO_ofb128_encrypt encrypts (or decrypts, it's the same with OFB mode) +// |len| bytes from |in| to |out| using |block| in OFB mode. There's no +// requirement that |len| be a multiple of any value and any partial blocks are +// stored in |ivec| and |*num|, the latter must be zero before the initial +// call. +void CRYPTO_ofb128_encrypt(const uint8_t *in, uint8_t *out, + size_t len, const void *key, uint8_t ivec[16], + unsigned *num, block128_f block); + + +// CFB. + +// CRYPTO_cfb128_encrypt encrypts (or decrypts, if |enc| is zero) |len| bytes +// from |in| to |out| using |block| in CFB mode. There's no requirement that +// |len| be a multiple of any value and any partial blocks are stored in |ivec| +// and |*num|, the latter must be zero before the initial call. +void CRYPTO_cfb128_encrypt(const uint8_t *in, uint8_t *out, size_t len, + const void *key, uint8_t ivec[16], unsigned *num, + int enc, block128_f block); + +// CRYPTO_cfb128_8_encrypt encrypts (or decrypts, if |enc| is zero) |len| bytes +// from |in| to |out| using |block| in CFB-8 mode. Prior to the first call +// |num| should be set to zero. +void CRYPTO_cfb128_8_encrypt(const uint8_t *in, uint8_t *out, size_t len, + const void *key, uint8_t ivec[16], unsigned *num, + int enc, block128_f block); + +// CRYPTO_cfb128_1_encrypt encrypts (or decrypts, if |enc| is zero) |len| bytes +// from |in| to |out| using |block| in CFB-1 mode. Prior to the first call +// |num| should be set to zero. +void CRYPTO_cfb128_1_encrypt(const uint8_t *in, uint8_t *out, size_t bits, + const void *key, uint8_t ivec[16], unsigned *num, + int enc, block128_f block); + +size_t CRYPTO_cts128_encrypt_block(const uint8_t *in, uint8_t *out, size_t len, + const void *key, uint8_t ivec[16], + block128_f block); + + +// POLYVAL. +// +// POLYVAL is a polynomial authenticator that operates over a field very +// similar to the one that GHASH uses. See +// https://tools.ietf.org/html/draft-irtf-cfrg-gcmsiv-02#section-3. + +typedef union { + uint64_t u[2]; + uint8_t c[16]; +} polyval_block; + +struct polyval_ctx { + // Note that the order of |S|, |H| and |Htable| is fixed by the MOVBE-based, + // x86-64, GHASH assembly. + polyval_block S; + u128 H; + u128 Htable[16]; + gmult_func gmult; + ghash_func ghash; +}; + +// CRYPTO_POLYVAL_init initialises |ctx| using |key|. +void CRYPTO_POLYVAL_init(struct polyval_ctx *ctx, const uint8_t key[16]); + +// CRYPTO_POLYVAL_update_blocks updates the accumulator in |ctx| given the +// blocks from |in|. Only a whole number of blocks can be processed so |in_len| +// must be a multiple of 16. +void CRYPTO_POLYVAL_update_blocks(struct polyval_ctx *ctx, const uint8_t *in, + size_t in_len); + +// CRYPTO_POLYVAL_finish writes the accumulator from |ctx| to |out|. +void CRYPTO_POLYVAL_finish(const struct polyval_ctx *ctx, uint8_t out[16]); + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_MODES_INTERNAL_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/modes/ofb.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/modes/ofb.c new file mode 100644 index 0000000..203ca26 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/modes/ofb.c @@ -0,0 +1,95 @@ +/* ==================================================================== + * 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 + +#include +#include + +#include "internal.h" + + +OPENSSL_COMPILE_ASSERT((16 % sizeof(size_t)) == 0, bad_size_t_size_ofb); + +void CRYPTO_ofb128_encrypt(const uint8_t *in, uint8_t *out, size_t len, + const void *key, uint8_t ivec[16], unsigned *num, + block128_f block) { + assert(in && out && key && ivec && num); + + unsigned n = *num; + + while (n && len) { + *(out++) = *(in++) ^ ivec[n]; + --len; + n = (n + 1) % 16; + } + + while (len >= 16) { + (*block)(ivec, ivec, key); + for (; n < 16; n += sizeof(size_t)) { + size_t a, b; + OPENSSL_memcpy(&a, in + n, sizeof(size_t)); + OPENSSL_memcpy(&b, ivec + n, sizeof(size_t)); + + const size_t c = a ^ b; + OPENSSL_memcpy(out + n, &c, sizeof(size_t)); + } + 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; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/modes/ofb.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/modes/ofb.c.grpc_back new file mode 100644 index 0000000..63bba68 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/modes/ofb.c.grpc_back @@ -0,0 +1,95 @@ +/* ==================================================================== + * 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 + +#include +#include + +#include "internal.h" + + +OPENSSL_COMPILE_ASSERT((16 % sizeof(size_t)) == 0, bad_size_t_size_ofb); + +void CRYPTO_ofb128_encrypt(const uint8_t *in, uint8_t *out, size_t len, + const void *key, uint8_t ivec[16], unsigned *num, + block128_f block) { + assert(in && out && key && ivec && num); + + unsigned n = *num; + + while (n && len) { + *(out++) = *(in++) ^ ivec[n]; + --len; + n = (n + 1) % 16; + } + + while (len >= 16) { + (*block)(ivec, ivec, key); + for (; n < 16; n += sizeof(size_t)) { + size_t a, b; + OPENSSL_memcpy(&a, in + n, sizeof(size_t)); + OPENSSL_memcpy(&b, ivec + n, sizeof(size_t)); + + const size_t c = a ^ b; + OPENSSL_memcpy(out + n, &c, sizeof(size_t)); + } + 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; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/modes/polyval.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/modes/polyval.c new file mode 100644 index 0000000..7df1ce9 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/modes/polyval.c @@ -0,0 +1,91 @@ +/* Copyright (c) 2016, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include +#include + +#include "internal.h" +#include "../../internal.h" + + +// byte_reverse reverses the order of the bytes in |b->c|. +static void byte_reverse(polyval_block *b) { + const uint64_t t = CRYPTO_bswap8(b->u[0]); + b->u[0] = CRYPTO_bswap8(b->u[1]); + b->u[1] = t; +} + +// reverse_and_mulX_ghash interprets the bytes |b->c| as a reversed element of +// the GHASH field, multiplies that by 'x' and serialises the result back into +// |b|, but with GHASH's backwards bit ordering. +static void reverse_and_mulX_ghash(polyval_block *b) { + uint64_t hi = b->u[0]; + uint64_t lo = b->u[1]; + const crypto_word_t carry = constant_time_eq_w(hi & 1, 1); + hi >>= 1; + hi |= lo << 63; + lo >>= 1; + lo ^= ((uint64_t) constant_time_select_w(carry, 0xe1, 0)) << 56; + + b->u[0] = CRYPTO_bswap8(lo); + b->u[1] = CRYPTO_bswap8(hi); +} + +// POLYVAL(H, X_1, ..., X_n) = +// ByteReverse(GHASH(mulX_GHASH(ByteReverse(H)), ByteReverse(X_1), ..., +// ByteReverse(X_n))). +// +// See https://tools.ietf.org/html/draft-irtf-cfrg-gcmsiv-02#appendix-A. + +void CRYPTO_POLYVAL_init(struct polyval_ctx *ctx, const uint8_t key[16]) { + polyval_block H; + OPENSSL_memcpy(H.c, key, 16); + reverse_and_mulX_ghash(&H); + + int is_avx; + CRYPTO_ghash_init(&ctx->gmult, &ctx->ghash, &ctx->H, ctx->Htable, &is_avx, + H.c); + OPENSSL_memset(&ctx->S, 0, sizeof(ctx->S)); +} + +void CRYPTO_POLYVAL_update_blocks(struct polyval_ctx *ctx, const uint8_t *in, + size_t in_len) { + assert((in_len & 15) == 0); + polyval_block reversed[32]; + + while (in_len > 0) { + size_t todo = in_len; + if (todo > sizeof(reversed)) { + todo = sizeof(reversed); + } + OPENSSL_memcpy(reversed, in, todo); + in += todo; + in_len -= todo; + + size_t blocks = todo / sizeof(polyval_block); + for (size_t i = 0; i < blocks; i++) { + byte_reverse(&reversed[i]); + } + + ctx->ghash(ctx->S.u, ctx->Htable, (const uint8_t *) reversed, todo); + } +} + +void CRYPTO_POLYVAL_finish(const struct polyval_ctx *ctx, uint8_t out[16]) { + polyval_block S = ctx->S; + byte_reverse(&S); + OPENSSL_memcpy(out, &S.c, sizeof(polyval_block)); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/modes/polyval.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/modes/polyval.c.grpc_back new file mode 100644 index 0000000..857dc0e --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/modes/polyval.c.grpc_back @@ -0,0 +1,91 @@ +/* Copyright (c) 2016, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include +#include + +#include "internal.h" +#include "../../internal.h" + + +// byte_reverse reverses the order of the bytes in |b->c|. +static void byte_reverse(polyval_block *b) { + const uint64_t t = CRYPTO_bswap8(b->u[0]); + b->u[0] = CRYPTO_bswap8(b->u[1]); + b->u[1] = t; +} + +// reverse_and_mulX_ghash interprets the bytes |b->c| as a reversed element of +// the GHASH field, multiplies that by 'x' and serialises the result back into +// |b|, but with GHASH's backwards bit ordering. +static void reverse_and_mulX_ghash(polyval_block *b) { + uint64_t hi = b->u[0]; + uint64_t lo = b->u[1]; + const crypto_word_t carry = constant_time_eq_w(hi & 1, 1); + hi >>= 1; + hi |= lo << 63; + lo >>= 1; + lo ^= ((uint64_t) constant_time_select_w(carry, 0xe1, 0)) << 56; + + b->u[0] = CRYPTO_bswap8(lo); + b->u[1] = CRYPTO_bswap8(hi); +} + +// POLYVAL(H, X_1, ..., X_n) = +// ByteReverse(GHASH(mulX_GHASH(ByteReverse(H)), ByteReverse(X_1), ..., +// ByteReverse(X_n))). +// +// See https://tools.ietf.org/html/draft-irtf-cfrg-gcmsiv-02#appendix-A. + +void CRYPTO_POLYVAL_init(struct polyval_ctx *ctx, const uint8_t key[16]) { + polyval_block H; + OPENSSL_memcpy(H.c, key, 16); + reverse_and_mulX_ghash(&H); + + int is_avx; + CRYPTO_ghash_init(&ctx->gmult, &ctx->ghash, &ctx->H, ctx->Htable, &is_avx, + H.c); + OPENSSL_memset(&ctx->S, 0, sizeof(ctx->S)); +} + +void CRYPTO_POLYVAL_update_blocks(struct polyval_ctx *ctx, const uint8_t *in, + size_t in_len) { + assert((in_len & 15) == 0); + polyval_block reversed[32]; + + while (in_len > 0) { + size_t todo = in_len; + if (todo > sizeof(reversed)) { + todo = sizeof(reversed); + } + OPENSSL_memcpy(reversed, in, todo); + in += todo; + in_len -= todo; + + size_t blocks = todo / sizeof(polyval_block); + for (size_t i = 0; i < blocks; i++) { + byte_reverse(&reversed[i]); + } + + ctx->ghash(ctx->S.u, ctx->Htable, (const uint8_t *) reversed, todo); + } +} + +void CRYPTO_POLYVAL_finish(const struct polyval_ctx *ctx, uint8_t out[16]) { + polyval_block S = ctx->S; + byte_reverse(&S); + OPENSSL_memcpy(out, &S.c, sizeof(polyval_block)); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/rand/ctrdrbg.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/rand/ctrdrbg.c new file mode 100644 index 0000000..dcd27bd --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/rand/ctrdrbg.c @@ -0,0 +1,202 @@ +/* Copyright (c) 2017, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include +#include + +#include "internal.h" +#include "../cipher/internal.h" + + +// Section references in this file refer to SP 800-90Ar1: +// http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-90Ar1.pdf + +// See table 3. +static const uint64_t kMaxReseedCount = UINT64_C(1) << 48; + +int CTR_DRBG_init(CTR_DRBG_STATE *drbg, + const uint8_t entropy[CTR_DRBG_ENTROPY_LEN], + const uint8_t *personalization, size_t personalization_len) { + // Section 10.2.1.3.1 + if (personalization_len > CTR_DRBG_ENTROPY_LEN) { + return 0; + } + + uint8_t seed_material[CTR_DRBG_ENTROPY_LEN]; + OPENSSL_memcpy(seed_material, entropy, CTR_DRBG_ENTROPY_LEN); + + for (size_t i = 0; i < personalization_len; i++) { + seed_material[i] ^= personalization[i]; + } + + // Section 10.2.1.2 + + // kInitMask is the result of encrypting blocks with big-endian value 1, 2 + // and 3 with the all-zero AES-256 key. + static const uint8_t kInitMask[CTR_DRBG_ENTROPY_LEN] = { + 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9, 0xa9, 0x63, 0xb4, 0xf1, + 0xc4, 0xcb, 0x73, 0x8b, 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e, + 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18, 0x72, 0x60, 0x03, 0xca, + 0x37, 0xa6, 0x2a, 0x74, 0xd1, 0xa2, 0xf5, 0x8e, 0x75, 0x06, 0x35, 0x8e, + }; + + for (size_t i = 0; i < sizeof(kInitMask); i++) { + seed_material[i] ^= kInitMask[i]; + } + + drbg->ctr = aes_ctr_set_key(&drbg->ks, NULL, &drbg->block, seed_material, 32); + OPENSSL_memcpy(drbg->counter.bytes, seed_material + 32, 16); + drbg->reseed_counter = 1; + + return 1; +} + +OPENSSL_COMPILE_ASSERT(CTR_DRBG_ENTROPY_LEN % AES_BLOCK_SIZE == 0, + not_a_multiple_of_block_size); + +// ctr_inc adds |n| to the last four bytes of |drbg->counter|, treated as a +// big-endian number. +static void ctr32_add(CTR_DRBG_STATE *drbg, uint32_t n) { + drbg->counter.words[3] = + CRYPTO_bswap4(CRYPTO_bswap4(drbg->counter.words[3]) + n); +} + +static int ctr_drbg_update(CTR_DRBG_STATE *drbg, const uint8_t *data, + size_t data_len) { + // Per section 10.2.1.2, |data_len| must be |CTR_DRBG_ENTROPY_LEN|. Here, we + // allow shorter inputs and right-pad them with zeros. This is equivalent to + // the specified algorithm but saves a copy in |CTR_DRBG_generate|. + if (data_len > CTR_DRBG_ENTROPY_LEN) { + return 0; + } + + uint8_t temp[CTR_DRBG_ENTROPY_LEN]; + for (size_t i = 0; i < CTR_DRBG_ENTROPY_LEN; i += AES_BLOCK_SIZE) { + ctr32_add(drbg, 1); + drbg->block(drbg->counter.bytes, temp + i, &drbg->ks); + } + + for (size_t i = 0; i < data_len; i++) { + temp[i] ^= data[i]; + } + + drbg->ctr = aes_ctr_set_key(&drbg->ks, NULL, &drbg->block, temp, 32); + OPENSSL_memcpy(drbg->counter.bytes, temp + 32, 16); + + return 1; +} + +int CTR_DRBG_reseed(CTR_DRBG_STATE *drbg, + const uint8_t entropy[CTR_DRBG_ENTROPY_LEN], + const uint8_t *additional_data, + size_t additional_data_len) { + // Section 10.2.1.4 + uint8_t entropy_copy[CTR_DRBG_ENTROPY_LEN]; + + if (additional_data_len > 0) { + if (additional_data_len > CTR_DRBG_ENTROPY_LEN) { + return 0; + } + + OPENSSL_memcpy(entropy_copy, entropy, CTR_DRBG_ENTROPY_LEN); + for (size_t i = 0; i < additional_data_len; i++) { + entropy_copy[i] ^= additional_data[i]; + } + + entropy = entropy_copy; + } + + if (!ctr_drbg_update(drbg, entropy, CTR_DRBG_ENTROPY_LEN)) { + return 0; + } + + drbg->reseed_counter = 1; + + return 1; +} + +int CTR_DRBG_generate(CTR_DRBG_STATE *drbg, uint8_t *out, size_t out_len, + const uint8_t *additional_data, + size_t additional_data_len) { + // See 9.3.1 + if (out_len > CTR_DRBG_MAX_GENERATE_LENGTH) { + return 0; + } + + // See 10.2.1.5.1 + if (drbg->reseed_counter > kMaxReseedCount) { + return 0; + } + + if (additional_data_len != 0 && + !ctr_drbg_update(drbg, additional_data, additional_data_len)) { + return 0; + } + + // kChunkSize is used to interact better with the cache. Since the AES-CTR + // code assumes that it's encrypting rather than just writing keystream, the + // buffer has to be zeroed first. Without chunking, large reads would zero + // the whole buffer, flushing the L1 cache, and then do another pass (missing + // the cache every time) to “encrypt” it. The code can avoid this by + // chunking. + static const size_t kChunkSize = 8 * 1024; + + while (out_len >= AES_BLOCK_SIZE) { + size_t todo = kChunkSize; + if (todo > out_len) { + todo = out_len; + } + + todo &= ~(AES_BLOCK_SIZE-1); + const size_t num_blocks = todo / AES_BLOCK_SIZE; + + if (drbg->ctr) { + OPENSSL_memset(out, 0, todo); + ctr32_add(drbg, 1); + drbg->ctr(out, out, num_blocks, &drbg->ks, drbg->counter.bytes); + ctr32_add(drbg, num_blocks - 1); + } else { + for (size_t i = 0; i < todo; i += AES_BLOCK_SIZE) { + ctr32_add(drbg, 1); + drbg->block(drbg->counter.bytes, out + i, &drbg->ks); + } + } + + out += todo; + out_len -= todo; + } + + if (out_len > 0) { + uint8_t block[AES_BLOCK_SIZE]; + ctr32_add(drbg, 1); + drbg->block(drbg->counter.bytes, block, &drbg->ks); + + OPENSSL_memcpy(out, block, out_len); + } + + // Right-padding |additional_data| in step 2.2 is handled implicitly by + // |ctr_drbg_update|, to save a copy. + if (!ctr_drbg_update(drbg, additional_data, additional_data_len)) { + return 0; + } + + drbg->reseed_counter++; + return 1; +} + +void CTR_DRBG_clear(CTR_DRBG_STATE *drbg) { + OPENSSL_cleanse(drbg, sizeof(CTR_DRBG_STATE)); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/rand/ctrdrbg.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/rand/ctrdrbg.c.grpc_back new file mode 100644 index 0000000..f2fe8b3 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/rand/ctrdrbg.c.grpc_back @@ -0,0 +1,202 @@ +/* Copyright (c) 2017, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include +#include + +#include "internal.h" +#include "../cipher/internal.h" + + +// Section references in this file refer to SP 800-90Ar1: +// http://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-90Ar1.pdf + +// See table 3. +static const uint64_t kMaxReseedCount = UINT64_C(1) << 48; + +int CTR_DRBG_init(CTR_DRBG_STATE *drbg, + const uint8_t entropy[CTR_DRBG_ENTROPY_LEN], + const uint8_t *personalization, size_t personalization_len) { + // Section 10.2.1.3.1 + if (personalization_len > CTR_DRBG_ENTROPY_LEN) { + return 0; + } + + uint8_t seed_material[CTR_DRBG_ENTROPY_LEN]; + OPENSSL_memcpy(seed_material, entropy, CTR_DRBG_ENTROPY_LEN); + + for (size_t i = 0; i < personalization_len; i++) { + seed_material[i] ^= personalization[i]; + } + + // Section 10.2.1.2 + + // kInitMask is the result of encrypting blocks with big-endian value 1, 2 + // and 3 with the all-zero AES-256 key. + static const uint8_t kInitMask[CTR_DRBG_ENTROPY_LEN] = { + 0x53, 0x0f, 0x8a, 0xfb, 0xc7, 0x45, 0x36, 0xb9, 0xa9, 0x63, 0xb4, 0xf1, + 0xc4, 0xcb, 0x73, 0x8b, 0xce, 0xa7, 0x40, 0x3d, 0x4d, 0x60, 0x6b, 0x6e, + 0x07, 0x4e, 0xc5, 0xd3, 0xba, 0xf3, 0x9d, 0x18, 0x72, 0x60, 0x03, 0xca, + 0x37, 0xa6, 0x2a, 0x74, 0xd1, 0xa2, 0xf5, 0x8e, 0x75, 0x06, 0x35, 0x8e, + }; + + for (size_t i = 0; i < sizeof(kInitMask); i++) { + seed_material[i] ^= kInitMask[i]; + } + + drbg->ctr = aes_ctr_set_key(&drbg->ks, NULL, &drbg->block, seed_material, 32); + OPENSSL_memcpy(drbg->counter.bytes, seed_material + 32, 16); + drbg->reseed_counter = 1; + + return 1; +} + +OPENSSL_COMPILE_ASSERT(CTR_DRBG_ENTROPY_LEN % AES_BLOCK_SIZE == 0, + not_a_multiple_of_block_size); + +// ctr_inc adds |n| to the last four bytes of |drbg->counter|, treated as a +// big-endian number. +static void ctr32_add(CTR_DRBG_STATE *drbg, uint32_t n) { + drbg->counter.words[3] = + CRYPTO_bswap4(CRYPTO_bswap4(drbg->counter.words[3]) + n); +} + +static int ctr_drbg_update(CTR_DRBG_STATE *drbg, const uint8_t *data, + size_t data_len) { + // Per section 10.2.1.2, |data_len| must be |CTR_DRBG_ENTROPY_LEN|. Here, we + // allow shorter inputs and right-pad them with zeros. This is equivalent to + // the specified algorithm but saves a copy in |CTR_DRBG_generate|. + if (data_len > CTR_DRBG_ENTROPY_LEN) { + return 0; + } + + uint8_t temp[CTR_DRBG_ENTROPY_LEN]; + for (size_t i = 0; i < CTR_DRBG_ENTROPY_LEN; i += AES_BLOCK_SIZE) { + ctr32_add(drbg, 1); + drbg->block(drbg->counter.bytes, temp + i, &drbg->ks); + } + + for (size_t i = 0; i < data_len; i++) { + temp[i] ^= data[i]; + } + + drbg->ctr = aes_ctr_set_key(&drbg->ks, NULL, &drbg->block, temp, 32); + OPENSSL_memcpy(drbg->counter.bytes, temp + 32, 16); + + return 1; +} + +int CTR_DRBG_reseed(CTR_DRBG_STATE *drbg, + const uint8_t entropy[CTR_DRBG_ENTROPY_LEN], + const uint8_t *additional_data, + size_t additional_data_len) { + // Section 10.2.1.4 + uint8_t entropy_copy[CTR_DRBG_ENTROPY_LEN]; + + if (additional_data_len > 0) { + if (additional_data_len > CTR_DRBG_ENTROPY_LEN) { + return 0; + } + + OPENSSL_memcpy(entropy_copy, entropy, CTR_DRBG_ENTROPY_LEN); + for (size_t i = 0; i < additional_data_len; i++) { + entropy_copy[i] ^= additional_data[i]; + } + + entropy = entropy_copy; + } + + if (!ctr_drbg_update(drbg, entropy, CTR_DRBG_ENTROPY_LEN)) { + return 0; + } + + drbg->reseed_counter = 1; + + return 1; +} + +int CTR_DRBG_generate(CTR_DRBG_STATE *drbg, uint8_t *out, size_t out_len, + const uint8_t *additional_data, + size_t additional_data_len) { + // See 9.3.1 + if (out_len > CTR_DRBG_MAX_GENERATE_LENGTH) { + return 0; + } + + // See 10.2.1.5.1 + if (drbg->reseed_counter > kMaxReseedCount) { + return 0; + } + + if (additional_data_len != 0 && + !ctr_drbg_update(drbg, additional_data, additional_data_len)) { + return 0; + } + + // kChunkSize is used to interact better with the cache. Since the AES-CTR + // code assumes that it's encrypting rather than just writing keystream, the + // buffer has to be zeroed first. Without chunking, large reads would zero + // the whole buffer, flushing the L1 cache, and then do another pass (missing + // the cache every time) to “encrypt” it. The code can avoid this by + // chunking. + static const size_t kChunkSize = 8 * 1024; + + while (out_len >= AES_BLOCK_SIZE) { + size_t todo = kChunkSize; + if (todo > out_len) { + todo = out_len; + } + + todo &= ~(AES_BLOCK_SIZE-1); + const size_t num_blocks = todo / AES_BLOCK_SIZE; + + if (drbg->ctr) { + OPENSSL_memset(out, 0, todo); + ctr32_add(drbg, 1); + drbg->ctr(out, out, num_blocks, &drbg->ks, drbg->counter.bytes); + ctr32_add(drbg, num_blocks - 1); + } else { + for (size_t i = 0; i < todo; i += AES_BLOCK_SIZE) { + ctr32_add(drbg, 1); + drbg->block(drbg->counter.bytes, out + i, &drbg->ks); + } + } + + out += todo; + out_len -= todo; + } + + if (out_len > 0) { + uint8_t block[AES_BLOCK_SIZE]; + ctr32_add(drbg, 1); + drbg->block(drbg->counter.bytes, block, &drbg->ks); + + OPENSSL_memcpy(out, block, out_len); + } + + // Right-padding |additional_data| in step 2.2 is handled implicitly by + // |ctr_drbg_update|, to save a copy. + if (!ctr_drbg_update(drbg, additional_data, additional_data_len)) { + return 0; + } + + drbg->reseed_counter++; + return 1; +} + +void CTR_DRBG_clear(CTR_DRBG_STATE *drbg) { + OPENSSL_cleanse(drbg, sizeof(CTR_DRBG_STATE)); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/rand/internal.h b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/rand/internal.h new file mode 100644 index 0000000..482b844 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/rand/internal.h @@ -0,0 +1,92 @@ +/* Copyright (c) 2015, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_CRYPTO_RAND_INTERNAL_H +#define OPENSSL_HEADER_CRYPTO_RAND_INTERNAL_H + +#include + +#include "../../internal.h" +#include "../modes/internal.h" + +#if defined(__cplusplus) +extern "C" { +#endif + + +// RAND_bytes_with_additional_data samples from the RNG after mixing 32 bytes +// from |user_additional_data| in. +void RAND_bytes_with_additional_data(uint8_t *out, size_t out_len, + const uint8_t user_additional_data[32]); + +// CRYPTO_sysrand fills |len| bytes at |buf| with entropy from the operating +// system. +void CRYPTO_sysrand(uint8_t *buf, size_t len); + +// rand_fork_unsafe_buffering_enabled returns whether fork-unsafe buffering has +// been enabled via |RAND_enable_fork_unsafe_buffering|. +int rand_fork_unsafe_buffering_enabled(void); + +// CTR_DRBG_STATE contains the state of a CTR_DRBG based on AES-256. See SP +// 800-90Ar1. +typedef struct { + AES_KEY ks; + block128_f block; + ctr128_f ctr; + union { + uint8_t bytes[16]; + uint32_t words[4]; + } counter; + uint64_t reseed_counter; +} CTR_DRBG_STATE; + +// See SP 800-90Ar1, table 3. +#define CTR_DRBG_ENTROPY_LEN 48 +#define CTR_DRBG_MAX_GENERATE_LENGTH 65536 + +// CTR_DRBG_init initialises |*drbg| given |CTR_DRBG_ENTROPY_LEN| bytes of +// entropy in |entropy| and, optionally, a personalization string up to +// |CTR_DRBG_ENTROPY_LEN| bytes in length. It returns one on success and zero +// on error. +OPENSSL_EXPORT int CTR_DRBG_init(CTR_DRBG_STATE *drbg, + const uint8_t entropy[CTR_DRBG_ENTROPY_LEN], + const uint8_t *personalization, + size_t personalization_len); + +// CTR_DRBG_reseed reseeds |drbg| given |CTR_DRBG_ENTROPY_LEN| bytes of entropy +// in |entropy| and, optionally, up to |CTR_DRBG_ENTROPY_LEN| bytes of +// additional data. It returns one on success or zero on error. +OPENSSL_EXPORT int CTR_DRBG_reseed(CTR_DRBG_STATE *drbg, + const uint8_t entropy[CTR_DRBG_ENTROPY_LEN], + const uint8_t *additional_data, + size_t additional_data_len); + +// CTR_DRBG_generate processes to up |CTR_DRBG_ENTROPY_LEN| bytes of additional +// data (if any) and then writes |out_len| random bytes to |out|, where +// |out_len| <= |CTR_DRBG_MAX_GENERATE_LENGTH|. It returns one on success or +// zero on error. +OPENSSL_EXPORT int CTR_DRBG_generate(CTR_DRBG_STATE *drbg, uint8_t *out, + size_t out_len, + const uint8_t *additional_data, + size_t additional_data_len); + +// CTR_DRBG_clear zeroises the state of |drbg|. +OPENSSL_EXPORT void CTR_DRBG_clear(CTR_DRBG_STATE *drbg); + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_CRYPTO_RAND_INTERNAL_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/rand/internal.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/rand/internal.h.grpc_back new file mode 100644 index 0000000..f73f4a1 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/rand/internal.h.grpc_back @@ -0,0 +1,92 @@ +/* Copyright (c) 2015, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_CRYPTO_RAND_INTERNAL_H +#define OPENSSL_HEADER_CRYPTO_RAND_INTERNAL_H + +#include + +#include "../../internal.h" +#include "../modes/internal.h" + +#if defined(__cplusplus) +extern "C" { +#endif + + +// RAND_bytes_with_additional_data samples from the RNG after mixing 32 bytes +// from |user_additional_data| in. +void RAND_bytes_with_additional_data(uint8_t *out, size_t out_len, + const uint8_t user_additional_data[32]); + +// CRYPTO_sysrand fills |len| bytes at |buf| with entropy from the operating +// system. +void CRYPTO_sysrand(uint8_t *buf, size_t len); + +// rand_fork_unsafe_buffering_enabled returns whether fork-unsafe buffering has +// been enabled via |RAND_enable_fork_unsafe_buffering|. +int rand_fork_unsafe_buffering_enabled(void); + +// CTR_DRBG_STATE contains the state of a CTR_DRBG based on AES-256. See SP +// 800-90Ar1. +typedef struct { + AES_KEY ks; + block128_f block; + ctr128_f ctr; + union { + uint8_t bytes[16]; + uint32_t words[4]; + } counter; + uint64_t reseed_counter; +} CTR_DRBG_STATE; + +// See SP 800-90Ar1, table 3. +#define CTR_DRBG_ENTROPY_LEN 48 +#define CTR_DRBG_MAX_GENERATE_LENGTH 65536 + +// CTR_DRBG_init initialises |*drbg| given |CTR_DRBG_ENTROPY_LEN| bytes of +// entropy in |entropy| and, optionally, a personalization string up to +// |CTR_DRBG_ENTROPY_LEN| bytes in length. It returns one on success and zero +// on error. +OPENSSL_EXPORT int CTR_DRBG_init(CTR_DRBG_STATE *drbg, + const uint8_t entropy[CTR_DRBG_ENTROPY_LEN], + const uint8_t *personalization, + size_t personalization_len); + +// CTR_DRBG_reseed reseeds |drbg| given |CTR_DRBG_ENTROPY_LEN| bytes of entropy +// in |entropy| and, optionally, up to |CTR_DRBG_ENTROPY_LEN| bytes of +// additional data. It returns one on success or zero on error. +OPENSSL_EXPORT int CTR_DRBG_reseed(CTR_DRBG_STATE *drbg, + const uint8_t entropy[CTR_DRBG_ENTROPY_LEN], + const uint8_t *additional_data, + size_t additional_data_len); + +// CTR_DRBG_generate processes to up |CTR_DRBG_ENTROPY_LEN| bytes of additional +// data (if any) and then writes |out_len| random bytes to |out|, where +// |out_len| <= |CTR_DRBG_MAX_GENERATE_LENGTH|. It returns one on success or +// zero on error. +OPENSSL_EXPORT int CTR_DRBG_generate(CTR_DRBG_STATE *drbg, uint8_t *out, + size_t out_len, + const uint8_t *additional_data, + size_t additional_data_len); + +// CTR_DRBG_clear zeroises the state of |drbg|. +OPENSSL_EXPORT void CTR_DRBG_clear(CTR_DRBG_STATE *drbg); + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_CRYPTO_RAND_INTERNAL_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/rand/rand.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/rand/rand.c new file mode 100644 index 0000000..6b1f6d7 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/rand/rand.c @@ -0,0 +1,358 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include +#include +#include + +#if defined(BORINGSSL_FIPS) +#include +#endif + +#include +#include +#include + +#include "internal.h" +#include "../../internal.h" +#include "../delocate.h" + + +// It's assumed that the operating system always has an unfailing source of +// entropy which is accessed via |CRYPTO_sysrand|. (If the operating system +// entropy source fails, it's up to |CRYPTO_sysrand| to abort the process—we +// don't try to handle it.) +// +// In addition, the hardware may provide a low-latency RNG. Intel's rdrand +// instruction is the canonical example of this. When a hardware RNG is +// available we don't need to worry about an RNG failure arising from fork()ing +// the process or moving a VM, so we can keep thread-local RNG state and use it +// as an additional-data input to CTR-DRBG. +// +// (We assume that the OS entropy is safe from fork()ing and VM duplication. +// This might be a bit of a leap of faith, esp on Windows, but there's nothing +// that we can do about it.) + +// kReseedInterval is the number of generate calls made to CTR-DRBG before +// reseeding. +static const unsigned kReseedInterval = 4096; + +// CRNGT_BLOCK_SIZE is the number of bytes in a “block” for the purposes of the +// continuous random number generator test in FIPS 140-2, section 4.9.2. +#define CRNGT_BLOCK_SIZE 16 + +// rand_thread_state contains the per-thread state for the RNG. +struct rand_thread_state { + CTR_DRBG_STATE drbg; + // calls is the number of generate calls made on |drbg| since it was last + // (re)seeded. This is bound by |kReseedInterval|. + unsigned calls; + // last_block_valid is non-zero iff |last_block| contains data from + // |CRYPTO_sysrand|. + int last_block_valid; + +#if defined(BORINGSSL_FIPS) + // last_block contains the previous block from |CRYPTO_sysrand|. + uint8_t last_block[CRNGT_BLOCK_SIZE]; + // next and prev form a NULL-terminated, double-linked list of all states in + // a process. + struct rand_thread_state *next, *prev; +#endif +}; + +#if defined(BORINGSSL_FIPS) +// thread_states_list is the head of a linked-list of all |rand_thread_state| +// objects in the process, one per thread. This is needed because FIPS requires +// that they be zeroed on process exit, but thread-local destructors aren't +// called when the whole process is exiting. +DEFINE_BSS_GET(struct rand_thread_state *, thread_states_list); +DEFINE_STATIC_MUTEX(thread_states_list_lock); + +static void rand_thread_state_clear_all(void) __attribute__((destructor)); +static void rand_thread_state_clear_all(void) { + CRYPTO_STATIC_MUTEX_lock_write(thread_states_list_lock_bss_get()); + for (struct rand_thread_state *cur = *thread_states_list_bss_get(); + cur != NULL; cur = cur->next) { + CTR_DRBG_clear(&cur->drbg); + } + // |thread_states_list_lock is deliberately left locked so that any threads + // that are still running will hang if they try to call |RAND_bytes|. +} +#endif + +// rand_thread_state_free frees a |rand_thread_state|. This is called when a +// thread exits. +static void rand_thread_state_free(void *state_in) { + struct rand_thread_state *state = state_in; + + if (state_in == NULL) { + return; + } + +#if defined(BORINGSSL_FIPS) + CRYPTO_STATIC_MUTEX_lock_write(thread_states_list_lock_bss_get()); + + if (state->prev != NULL) { + state->prev->next = state->next; + } else { + *thread_states_list_bss_get() = state->next; + } + + if (state->next != NULL) { + state->next->prev = state->prev; + } + + CRYPTO_STATIC_MUTEX_unlock_write(thread_states_list_lock_bss_get()); + + CTR_DRBG_clear(&state->drbg); +#endif + + OPENSSL_free(state); +} + +#if defined(OPENSSL_X86_64) && !defined(OPENSSL_NO_ASM) && \ + !defined(BORINGSSL_UNSAFE_DETERMINISTIC_MODE) + +// These functions are defined in asm/rdrand-x86_64.pl +extern int CRYPTO_rdrand(uint8_t out[8]); +extern int CRYPTO_rdrand_multiple8_buf(uint8_t *buf, size_t len); + +static int have_rdrand(void) { + return (OPENSSL_ia32cap_get()[1] & (1u << 30)) != 0; +} + +static int hwrand(uint8_t *buf, const size_t len) { + if (!have_rdrand()) { + return 0; + } + + const size_t len_multiple8 = len & ~7; + if (!CRYPTO_rdrand_multiple8_buf(buf, len_multiple8)) { + return 0; + } + const size_t remainder = len - len_multiple8; + + if (remainder != 0) { + assert(remainder < 8); + + uint8_t rand_buf[8]; + if (!CRYPTO_rdrand(rand_buf)) { + return 0; + } + OPENSSL_memcpy(buf + len_multiple8, rand_buf, remainder); + } + +#if defined(BORINGSSL_FIPS_BREAK_CRNG) + // This breaks the "continuous random number generator test" defined in FIPS + // 140-2, section 4.9.2, and implemented in rand_get_seed(). + OPENSSL_memset(buf, 0, len); +#endif + + return 1; +} + +#else + +static int hwrand(uint8_t *buf, size_t len) { + return 0; +} + +#endif + +#if defined(BORINGSSL_FIPS) + +static void rand_get_seed(struct rand_thread_state *state, + uint8_t seed[CTR_DRBG_ENTROPY_LEN]) { + if (!state->last_block_valid) { + if (!hwrand(state->last_block, sizeof(state->last_block))) { + CRYPTO_sysrand(state->last_block, sizeof(state->last_block)); + } + state->last_block_valid = 1; + } + + // We overread from /dev/urandom or RDRAND by a factor of 10 and XOR to + // whiten. +#define FIPS_OVERREAD 10 + uint8_t entropy[CTR_DRBG_ENTROPY_LEN * FIPS_OVERREAD]; + + if (!hwrand(entropy, sizeof(entropy))) { + CRYPTO_sysrand(entropy, sizeof(entropy)); + } + + // See FIPS 140-2, section 4.9.2. This is the “continuous random number + // generator test” which causes the program to randomly abort. Hopefully the + // rate of failure is small enough not to be a problem in practice. + if (CRYPTO_memcmp(state->last_block, entropy, CRNGT_BLOCK_SIZE) == 0) { + printf("CRNGT failed.\n"); + BORINGSSL_FIPS_abort(); + } + + for (size_t i = CRNGT_BLOCK_SIZE; i < sizeof(entropy); + i += CRNGT_BLOCK_SIZE) { + if (CRYPTO_memcmp(entropy + i - CRNGT_BLOCK_SIZE, entropy + i, + CRNGT_BLOCK_SIZE) == 0) { + printf("CRNGT failed.\n"); + BORINGSSL_FIPS_abort(); + } + } + OPENSSL_memcpy(state->last_block, + entropy + sizeof(entropy) - CRNGT_BLOCK_SIZE, + CRNGT_BLOCK_SIZE); + + OPENSSL_memcpy(seed, entropy, CTR_DRBG_ENTROPY_LEN); + + for (size_t i = 1; i < FIPS_OVERREAD; i++) { + for (size_t j = 0; j < CTR_DRBG_ENTROPY_LEN; j++) { + seed[j] ^= entropy[CTR_DRBG_ENTROPY_LEN * i + j]; + } + } +} + +#else + +static void rand_get_seed(struct rand_thread_state *state, + uint8_t seed[CTR_DRBG_ENTROPY_LEN]) { + // If not in FIPS mode, we don't overread from the system entropy source and + // we don't depend only on the hardware RDRAND. + CRYPTO_sysrand(seed, CTR_DRBG_ENTROPY_LEN); +} + +#endif + +void RAND_bytes_with_additional_data(uint8_t *out, size_t out_len, + const uint8_t user_additional_data[32]) { + if (out_len == 0) { + return; + } + + // Additional data is mixed into every CTR-DRBG call to protect, as best we + // can, against forks & VM clones. We do not over-read this information and + // don't reseed with it so, from the point of view of FIPS, this doesn't + // provide “prediction resistance”. But, in practice, it does. + uint8_t additional_data[32]; + if (!hwrand(additional_data, sizeof(additional_data))) { + // Without a hardware RNG to save us from address-space duplication, the OS + // entropy is used. This can be expensive (one read per |RAND_bytes| call) + // and so can be disabled by applications that we have ensured don't fork + // and aren't at risk of VM cloning. + if (!rand_fork_unsafe_buffering_enabled()) { + CRYPTO_sysrand(additional_data, sizeof(additional_data)); + } else { + OPENSSL_memset(additional_data, 0, sizeof(additional_data)); + } + } + + for (size_t i = 0; i < sizeof(additional_data); i++) { + additional_data[i] ^= user_additional_data[i]; + } + + struct rand_thread_state stack_state; + struct rand_thread_state *state = + CRYPTO_get_thread_local(OPENSSL_THREAD_LOCAL_RAND); + + if (state == NULL) { + state = OPENSSL_malloc(sizeof(struct rand_thread_state)); + if (state == NULL || + !CRYPTO_set_thread_local(OPENSSL_THREAD_LOCAL_RAND, state, + rand_thread_state_free)) { + // If the system is out of memory, use an ephemeral state on the + // stack. + state = &stack_state; + } + + state->last_block_valid = 0; + uint8_t seed[CTR_DRBG_ENTROPY_LEN]; + rand_get_seed(state, seed); + if (!CTR_DRBG_init(&state->drbg, seed, NULL, 0)) { + abort(); + } + state->calls = 0; + +#if defined(BORINGSSL_FIPS) + if (state != &stack_state) { + CRYPTO_STATIC_MUTEX_lock_write(thread_states_list_lock_bss_get()); + struct rand_thread_state **states_list = thread_states_list_bss_get(); + state->next = *states_list; + if (state->next != NULL) { + state->next->prev = state; + } + state->prev = NULL; + *states_list = state; + CRYPTO_STATIC_MUTEX_unlock_write(thread_states_list_lock_bss_get()); + } +#endif + } + + if (state->calls >= kReseedInterval) { + uint8_t seed[CTR_DRBG_ENTROPY_LEN]; + rand_get_seed(state, seed); +#if defined(BORINGSSL_FIPS) + // Take a read lock around accesses to |state->drbg|. This is needed to + // avoid returning bad entropy if we race with + // |rand_thread_state_clear_all|. + // + // This lock must be taken after any calls to |CRYPTO_sysrand| to avoid a + // bug on ppc64le. glibc may implement pthread locks by wrapping user code + // in a hardware transaction, but, on some older versions of glibc and the + // kernel, syscalls made with |syscall| did not abort the transaction. + CRYPTO_STATIC_MUTEX_lock_read(thread_states_list_lock_bss_get()); +#endif + if (!CTR_DRBG_reseed(&state->drbg, seed, NULL, 0)) { + abort(); + } + state->calls = 0; + } else { +#if defined(BORINGSSL_FIPS) + CRYPTO_STATIC_MUTEX_lock_read(thread_states_list_lock_bss_get()); +#endif + } + + int first_call = 1; + while (out_len > 0) { + size_t todo = out_len; + if (todo > CTR_DRBG_MAX_GENERATE_LENGTH) { + todo = CTR_DRBG_MAX_GENERATE_LENGTH; + } + + if (!CTR_DRBG_generate(&state->drbg, out, todo, additional_data, + first_call ? sizeof(additional_data) : 0)) { + abort(); + } + + out += todo; + out_len -= todo; + state->calls++; + first_call = 0; + } + + if (state == &stack_state) { + CTR_DRBG_clear(&state->drbg); + } + +#if defined(BORINGSSL_FIPS) + CRYPTO_STATIC_MUTEX_unlock_read(thread_states_list_lock_bss_get()); +#endif +} + +int RAND_bytes(uint8_t *out, size_t out_len) { + static const uint8_t kZeroAdditionalData[32] = {0}; + RAND_bytes_with_additional_data(out, out_len, kZeroAdditionalData); + return 1; +} + +int RAND_pseudo_bytes(uint8_t *buf, size_t len) { + return RAND_bytes(buf, len); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/rand/rand.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/rand/rand.c.grpc_back new file mode 100644 index 0000000..dafc91f --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/rand/rand.c.grpc_back @@ -0,0 +1,358 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include +#include +#include + +#if defined(BORINGSSL_FIPS) +#include +#endif + +#include +#include +#include + +#include "internal.h" +#include "../../internal.h" +#include "../delocate.h" + + +// It's assumed that the operating system always has an unfailing source of +// entropy which is accessed via |CRYPTO_sysrand|. (If the operating system +// entropy source fails, it's up to |CRYPTO_sysrand| to abort the process—we +// don't try to handle it.) +// +// In addition, the hardware may provide a low-latency RNG. Intel's rdrand +// instruction is the canonical example of this. When a hardware RNG is +// available we don't need to worry about an RNG failure arising from fork()ing +// the process or moving a VM, so we can keep thread-local RNG state and use it +// as an additional-data input to CTR-DRBG. +// +// (We assume that the OS entropy is safe from fork()ing and VM duplication. +// This might be a bit of a leap of faith, esp on Windows, but there's nothing +// that we can do about it.) + +// kReseedInterval is the number of generate calls made to CTR-DRBG before +// reseeding. +static const unsigned kReseedInterval = 4096; + +// CRNGT_BLOCK_SIZE is the number of bytes in a “block” for the purposes of the +// continuous random number generator test in FIPS 140-2, section 4.9.2. +#define CRNGT_BLOCK_SIZE 16 + +// rand_thread_state contains the per-thread state for the RNG. +struct rand_thread_state { + CTR_DRBG_STATE drbg; + // calls is the number of generate calls made on |drbg| since it was last + // (re)seeded. This is bound by |kReseedInterval|. + unsigned calls; + // last_block_valid is non-zero iff |last_block| contains data from + // |CRYPTO_sysrand|. + int last_block_valid; + +#if defined(BORINGSSL_FIPS) + // last_block contains the previous block from |CRYPTO_sysrand|. + uint8_t last_block[CRNGT_BLOCK_SIZE]; + // next and prev form a NULL-terminated, double-linked list of all states in + // a process. + struct rand_thread_state *next, *prev; +#endif +}; + +#if defined(BORINGSSL_FIPS) +// thread_states_list is the head of a linked-list of all |rand_thread_state| +// objects in the process, one per thread. This is needed because FIPS requires +// that they be zeroed on process exit, but thread-local destructors aren't +// called when the whole process is exiting. +DEFINE_BSS_GET(struct rand_thread_state *, thread_states_list); +DEFINE_STATIC_MUTEX(thread_states_list_lock); + +static void rand_thread_state_clear_all(void) __attribute__((destructor)); +static void rand_thread_state_clear_all(void) { + CRYPTO_STATIC_MUTEX_lock_write(thread_states_list_lock_bss_get()); + for (struct rand_thread_state *cur = *thread_states_list_bss_get(); + cur != NULL; cur = cur->next) { + CTR_DRBG_clear(&cur->drbg); + } + // |thread_states_list_lock is deliberately left locked so that any threads + // that are still running will hang if they try to call |RAND_bytes|. +} +#endif + +// rand_thread_state_free frees a |rand_thread_state|. This is called when a +// thread exits. +static void rand_thread_state_free(void *state_in) { + struct rand_thread_state *state = state_in; + + if (state_in == NULL) { + return; + } + +#if defined(BORINGSSL_FIPS) + CRYPTO_STATIC_MUTEX_lock_write(thread_states_list_lock_bss_get()); + + if (state->prev != NULL) { + state->prev->next = state->next; + } else { + *thread_states_list_bss_get() = state->next; + } + + if (state->next != NULL) { + state->next->prev = state->prev; + } + + CRYPTO_STATIC_MUTEX_unlock_write(thread_states_list_lock_bss_get()); + + CTR_DRBG_clear(&state->drbg); +#endif + + OPENSSL_free(state); +} + +#if defined(OPENSSL_X86_64) && !defined(OPENSSL_NO_ASM) && \ + !defined(BORINGSSL_UNSAFE_DETERMINISTIC_MODE) + +// These functions are defined in asm/rdrand-x86_64.pl +extern int CRYPTO_rdrand(uint8_t out[8]); +extern int CRYPTO_rdrand_multiple8_buf(uint8_t *buf, size_t len); + +static int have_rdrand(void) { + return (OPENSSL_ia32cap_get()[1] & (1u << 30)) != 0; +} + +static int hwrand(uint8_t *buf, const size_t len) { + if (!have_rdrand()) { + return 0; + } + + const size_t len_multiple8 = len & ~7; + if (!CRYPTO_rdrand_multiple8_buf(buf, len_multiple8)) { + return 0; + } + const size_t remainder = len - len_multiple8; + + if (remainder != 0) { + assert(remainder < 8); + + uint8_t rand_buf[8]; + if (!CRYPTO_rdrand(rand_buf)) { + return 0; + } + OPENSSL_memcpy(buf + len_multiple8, rand_buf, remainder); + } + +#if defined(BORINGSSL_FIPS_BREAK_CRNG) + // This breaks the "continuous random number generator test" defined in FIPS + // 140-2, section 4.9.2, and implemented in rand_get_seed(). + OPENSSL_memset(buf, 0, len); +#endif + + return 1; +} + +#else + +static int hwrand(uint8_t *buf, size_t len) { + return 0; +} + +#endif + +#if defined(BORINGSSL_FIPS) + +static void rand_get_seed(struct rand_thread_state *state, + uint8_t seed[CTR_DRBG_ENTROPY_LEN]) { + if (!state->last_block_valid) { + if (!hwrand(state->last_block, sizeof(state->last_block))) { + CRYPTO_sysrand(state->last_block, sizeof(state->last_block)); + } + state->last_block_valid = 1; + } + + // We overread from /dev/urandom or RDRAND by a factor of 10 and XOR to + // whiten. +#define FIPS_OVERREAD 10 + uint8_t entropy[CTR_DRBG_ENTROPY_LEN * FIPS_OVERREAD]; + + if (!hwrand(entropy, sizeof(entropy))) { + CRYPTO_sysrand(entropy, sizeof(entropy)); + } + + // See FIPS 140-2, section 4.9.2. This is the “continuous random number + // generator test” which causes the program to randomly abort. Hopefully the + // rate of failure is small enough not to be a problem in practice. + if (CRYPTO_memcmp(state->last_block, entropy, CRNGT_BLOCK_SIZE) == 0) { + printf("CRNGT failed.\n"); + BORINGSSL_FIPS_abort(); + } + + for (size_t i = CRNGT_BLOCK_SIZE; i < sizeof(entropy); + i += CRNGT_BLOCK_SIZE) { + if (CRYPTO_memcmp(entropy + i - CRNGT_BLOCK_SIZE, entropy + i, + CRNGT_BLOCK_SIZE) == 0) { + printf("CRNGT failed.\n"); + BORINGSSL_FIPS_abort(); + } + } + OPENSSL_memcpy(state->last_block, + entropy + sizeof(entropy) - CRNGT_BLOCK_SIZE, + CRNGT_BLOCK_SIZE); + + OPENSSL_memcpy(seed, entropy, CTR_DRBG_ENTROPY_LEN); + + for (size_t i = 1; i < FIPS_OVERREAD; i++) { + for (size_t j = 0; j < CTR_DRBG_ENTROPY_LEN; j++) { + seed[j] ^= entropy[CTR_DRBG_ENTROPY_LEN * i + j]; + } + } +} + +#else + +static void rand_get_seed(struct rand_thread_state *state, + uint8_t seed[CTR_DRBG_ENTROPY_LEN]) { + // If not in FIPS mode, we don't overread from the system entropy source and + // we don't depend only on the hardware RDRAND. + CRYPTO_sysrand(seed, CTR_DRBG_ENTROPY_LEN); +} + +#endif + +void RAND_bytes_with_additional_data(uint8_t *out, size_t out_len, + const uint8_t user_additional_data[32]) { + if (out_len == 0) { + return; + } + + // Additional data is mixed into every CTR-DRBG call to protect, as best we + // can, against forks & VM clones. We do not over-read this information and + // don't reseed with it so, from the point of view of FIPS, this doesn't + // provide “prediction resistance”. But, in practice, it does. + uint8_t additional_data[32]; + if (!hwrand(additional_data, sizeof(additional_data))) { + // Without a hardware RNG to save us from address-space duplication, the OS + // entropy is used. This can be expensive (one read per |RAND_bytes| call) + // and so can be disabled by applications that we have ensured don't fork + // and aren't at risk of VM cloning. + if (!rand_fork_unsafe_buffering_enabled()) { + CRYPTO_sysrand(additional_data, sizeof(additional_data)); + } else { + OPENSSL_memset(additional_data, 0, sizeof(additional_data)); + } + } + + for (size_t i = 0; i < sizeof(additional_data); i++) { + additional_data[i] ^= user_additional_data[i]; + } + + struct rand_thread_state stack_state; + struct rand_thread_state *state = + CRYPTO_get_thread_local(OPENSSL_THREAD_LOCAL_RAND); + + if (state == NULL) { + state = OPENSSL_malloc(sizeof(struct rand_thread_state)); + if (state == NULL || + !CRYPTO_set_thread_local(OPENSSL_THREAD_LOCAL_RAND, state, + rand_thread_state_free)) { + // If the system is out of memory, use an ephemeral state on the + // stack. + state = &stack_state; + } + + state->last_block_valid = 0; + uint8_t seed[CTR_DRBG_ENTROPY_LEN]; + rand_get_seed(state, seed); + if (!CTR_DRBG_init(&state->drbg, seed, NULL, 0)) { + abort(); + } + state->calls = 0; + +#if defined(BORINGSSL_FIPS) + if (state != &stack_state) { + CRYPTO_STATIC_MUTEX_lock_write(thread_states_list_lock_bss_get()); + struct rand_thread_state **states_list = thread_states_list_bss_get(); + state->next = *states_list; + if (state->next != NULL) { + state->next->prev = state; + } + state->prev = NULL; + *states_list = state; + CRYPTO_STATIC_MUTEX_unlock_write(thread_states_list_lock_bss_get()); + } +#endif + } + + if (state->calls >= kReseedInterval) { + uint8_t seed[CTR_DRBG_ENTROPY_LEN]; + rand_get_seed(state, seed); +#if defined(BORINGSSL_FIPS) + // Take a read lock around accesses to |state->drbg|. This is needed to + // avoid returning bad entropy if we race with + // |rand_thread_state_clear_all|. + // + // This lock must be taken after any calls to |CRYPTO_sysrand| to avoid a + // bug on ppc64le. glibc may implement pthread locks by wrapping user code + // in a hardware transaction, but, on some older versions of glibc and the + // kernel, syscalls made with |syscall| did not abort the transaction. + CRYPTO_STATIC_MUTEX_lock_read(thread_states_list_lock_bss_get()); +#endif + if (!CTR_DRBG_reseed(&state->drbg, seed, NULL, 0)) { + abort(); + } + state->calls = 0; + } else { +#if defined(BORINGSSL_FIPS) + CRYPTO_STATIC_MUTEX_lock_read(thread_states_list_lock_bss_get()); +#endif + } + + int first_call = 1; + while (out_len > 0) { + size_t todo = out_len; + if (todo > CTR_DRBG_MAX_GENERATE_LENGTH) { + todo = CTR_DRBG_MAX_GENERATE_LENGTH; + } + + if (!CTR_DRBG_generate(&state->drbg, out, todo, additional_data, + first_call ? sizeof(additional_data) : 0)) { + abort(); + } + + out += todo; + out_len -= todo; + state->calls++; + first_call = 0; + } + + if (state == &stack_state) { + CTR_DRBG_clear(&state->drbg); + } + +#if defined(BORINGSSL_FIPS) + CRYPTO_STATIC_MUTEX_unlock_read(thread_states_list_lock_bss_get()); +#endif +} + +int RAND_bytes(uint8_t *out, size_t out_len) { + static const uint8_t kZeroAdditionalData[32] = {0}; + RAND_bytes_with_additional_data(out, out_len, kZeroAdditionalData); + return 1; +} + +int RAND_pseudo_bytes(uint8_t *buf, size_t len) { + return RAND_bytes(buf, len); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/rand/urandom.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/rand/urandom.c new file mode 100644 index 0000000..0255764 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/rand/urandom.c @@ -0,0 +1,302 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#if !defined(_GNU_SOURCE) +#define _GNU_SOURCE // needed for syscall() on Linux. +#endif + +#include + +#if !defined(OPENSSL_WINDOWS) && !defined(OPENSSL_FUCHSIA) && \ + !defined(BORINGSSL_UNSAFE_DETERMINISTIC_MODE) && !defined(OPENSSL_TRUSTY) + +#include +#include +#include +#include +#include +#include + +#if defined(OPENSSL_LINUX) +#if defined(BORINGSSL_FIPS) +#include +#include +#endif +#include +#endif + +#include +#include + +#include "internal.h" +#include "../delocate.h" +#include "../../internal.h" + + +#if defined(OPENSSL_LINUX) + +#if defined(OPENSSL_X86_64) +#define EXPECTED_NR_getrandom 318 +#elif defined(OPENSSL_X86) +#define EXPECTED_NR_getrandom 355 +#elif defined(OPENSSL_AARCH64) +#define EXPECTED_NR_getrandom 278 +#elif defined(OPENSSL_ARM) +#define EXPECTED_NR_getrandom 384 +#elif defined(OPENSSL_PPC64LE) +#define EXPECTED_NR_getrandom 359 +#endif + +#if defined(EXPECTED_NR_getrandom) +#define USE_NR_getrandom + +#if defined(__NR_getrandom) + +#if __NR_getrandom != EXPECTED_NR_getrandom +#error "system call number for getrandom is not the expected value" +#endif + +#else // __NR_getrandom + +#define __NR_getrandom EXPECTED_NR_getrandom + +#endif // __NR_getrandom + +#endif // EXPECTED_NR_getrandom + +#if !defined(GRND_NONBLOCK) +#define GRND_NONBLOCK 1 +#endif + +#endif // OPENSSL_LINUX + +// rand_lock is used to protect the |*_requested| variables. +DEFINE_STATIC_MUTEX(rand_lock); + +// The following constants are magic values of |urandom_fd|. +static const int kUnset = 0; +static const int kHaveGetrandom = -3; + +// urandom_fd_requested is set by |RAND_set_urandom_fd|. It's protected by +// |rand_lock|. +DEFINE_BSS_GET(int, urandom_fd_requested); + +// urandom_fd is a file descriptor to /dev/urandom. It's protected by |once|. +DEFINE_BSS_GET(int, urandom_fd); + +DEFINE_STATIC_ONCE(rand_once); + +#if defined(USE_NR_getrandom) || defined(BORINGSSL_FIPS) +// message writes |msg| to stderr. We use this because referencing |stderr| +// with |fprintf| generates relocations, which is a problem inside the FIPS +// module. +static void message(const char *msg) { + ssize_t r; + do { + r = write(2, msg, strlen(msg)); + } while (r == -1 && errno == EINTR); +} +#endif + +// init_once initializes the state of this module to values previously +// requested. This is the only function that modifies |urandom_fd| and +// |urandom_buffering|, whose values may be read safely after calling the +// once. +static void init_once(void) { + CRYPTO_STATIC_MUTEX_lock_read(rand_lock_bss_get()); + int fd = *urandom_fd_requested_bss_get(); + CRYPTO_STATIC_MUTEX_unlock_read(rand_lock_bss_get()); + +#if defined(USE_NR_getrandom) + uint8_t dummy; + long getrandom_ret = + syscall(__NR_getrandom, &dummy, sizeof(dummy), GRND_NONBLOCK); + + if (getrandom_ret == 1) { + *urandom_fd_bss_get() = kHaveGetrandom; + return; + } else if (getrandom_ret == -1 && errno == EAGAIN) { + message( + "getrandom indicates that the entropy pool has not been initialized. " + "Rather than continue with poor entropy, this process will block until " + "entropy is available.\n"); + + do { + getrandom_ret = + syscall(__NR_getrandom, &dummy, sizeof(dummy), 0 /* no flags */); + } while (getrandom_ret == -1 && errno == EINTR); + + if (getrandom_ret == 1) { + *urandom_fd_bss_get() = kHaveGetrandom; + return; + } + } +#endif // USE_NR_getrandom + + if (fd == kUnset) { + do { + fd = open("/dev/urandom", O_RDONLY); + } while (fd == -1 && errno == EINTR); + } + + if (fd < 0) { + abort(); + } + + assert(kUnset == 0); + if (fd == kUnset) { + // Because we want to keep |urandom_fd| in the BSS, we have to initialise + // it to zero. But zero is a valid file descriptor too. Thus if open + // returns zero for /dev/urandom, we dup it to get a non-zero number. + fd = dup(fd); + close(kUnset); + + if (fd <= 0) { + abort(); + } + } + +#if defined(BORINGSSL_FIPS) + // In FIPS mode we ensure that the kernel has sufficient entropy before + // continuing. This is automatically handled by getrandom, which requires + // that the entropy pool has been initialised, but for urandom we have to + // poll. + for (;;) { + int entropy_bits; + if (ioctl(fd, RNDGETENTCNT, &entropy_bits)) { + message( + "RNDGETENTCNT on /dev/urandom failed. We cannot continue in this " + "case when in FIPS mode.\n"); + abort(); + } + + static const int kBitsNeeded = 256; + if (entropy_bits >= kBitsNeeded) { + break; + } + + usleep(250000); + } +#endif + + int flags = fcntl(fd, F_GETFD); + if (flags == -1) { + // Native Client doesn't implement |fcntl|. + if (errno != ENOSYS) { + abort(); + } + } else { + flags |= FD_CLOEXEC; + if (fcntl(fd, F_SETFD, flags) == -1) { + abort(); + } + } + *urandom_fd_bss_get() = fd; +} + +void RAND_set_urandom_fd(int fd) { + fd = dup(fd); + if (fd < 0) { + abort(); + } + + assert(kUnset == 0); + if (fd == kUnset) { + // Because we want to keep |urandom_fd| in the BSS, we have to initialise + // it to zero. But zero is a valid file descriptor too. Thus if dup + // returned zero we dup it again to get a non-zero number. + fd = dup(fd); + close(kUnset); + + if (fd <= 0) { + abort(); + } + } + + CRYPTO_STATIC_MUTEX_lock_write(rand_lock_bss_get()); + *urandom_fd_requested_bss_get() = fd; + CRYPTO_STATIC_MUTEX_unlock_write(rand_lock_bss_get()); + + CRYPTO_once(rand_once_bss_get(), init_once); + if (*urandom_fd_bss_get() == kHaveGetrandom) { + close(fd); + } else if (*urandom_fd_bss_get() != fd) { + abort(); // Already initialized. + } +} + +#if defined(USE_NR_getrandom) && defined(OPENSSL_MSAN) +void __msan_unpoison(void *, size_t); +#endif + +// fill_with_entropy writes |len| bytes of entropy into |out|. It returns one +// on success and zero on error. +static char fill_with_entropy(uint8_t *out, size_t len) { + while (len > 0) { + ssize_t r; + + if (*urandom_fd_bss_get() == kHaveGetrandom) { +#if defined(USE_NR_getrandom) + do { + r = syscall(__NR_getrandom, out, len, 0 /* no flags */); + } while (r == -1 && errno == EINTR); + +#if defined(OPENSSL_MSAN) + if (r > 0) { + // MSAN doesn't recognise |syscall| and thus doesn't notice that we + // have initialised the output buffer. + __msan_unpoison(out, r); + } +#endif // OPENSSL_MSAN + +#else // USE_NR_getrandom + abort(); +#endif + } else { + do { + r = read(*urandom_fd_bss_get(), out, len); + } while (r == -1 && errno == EINTR); + } + + if (r <= 0) { + return 0; + } + out += r; + len -= r; + } + + return 1; +} + +// CRYPTO_sysrand puts |requested| random bytes into |out|. +void CRYPTO_sysrand(uint8_t *out, size_t requested) { + if (requested == 0) { + return; + } + + CRYPTO_once(rand_once_bss_get(), init_once); + + if (!fill_with_entropy(out, requested)) { + abort(); + } + +#if defined(BORINGSSL_FIPS_BREAK_CRNG) + // This breaks the "continuous random number generator test" defined in FIPS + // 140-2, section 4.9.2, and implemented in rand_get_seed(). + OPENSSL_memset(out, 0, requested); +#endif +} + +#endif /* !OPENSSL_WINDOWS && !defined(OPENSSL_FUCHSIA) && \ + !BORINGSSL_UNSAFE_DETERMINISTIC_MODE && !OPENSSL_TRUSTY */ diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/rand/urandom.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/rand/urandom.c.grpc_back new file mode 100644 index 0000000..d2be719 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/rand/urandom.c.grpc_back @@ -0,0 +1,302 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#if !defined(_GNU_SOURCE) +#define _GNU_SOURCE // needed for syscall() on Linux. +#endif + +#include + +#if !defined(OPENSSL_WINDOWS) && !defined(OPENSSL_FUCHSIA) && \ + !defined(BORINGSSL_UNSAFE_DETERMINISTIC_MODE) && !defined(OPENSSL_TRUSTY) + +#include +#include +#include +#include +#include +#include + +#if defined(OPENSSL_LINUX) +#if defined(BORINGSSL_FIPS) +#include +#include +#endif +#include +#endif + +#include +#include + +#include "internal.h" +#include "../delocate.h" +#include "../../internal.h" + + +#if defined(OPENSSL_LINUX) + +#if defined(OPENSSL_X86_64) +#define EXPECTED_NR_getrandom 318 +#elif defined(OPENSSL_X86) +#define EXPECTED_NR_getrandom 355 +#elif defined(OPENSSL_AARCH64) +#define EXPECTED_NR_getrandom 278 +#elif defined(OPENSSL_ARM) +#define EXPECTED_NR_getrandom 384 +#elif defined(OPENSSL_PPC64LE) +#define EXPECTED_NR_getrandom 359 +#endif + +#if defined(EXPECTED_NR_getrandom) +#define USE_NR_getrandom + +#if defined(__NR_getrandom) + +#if __NR_getrandom != EXPECTED_NR_getrandom +#error "system call number for getrandom is not the expected value" +#endif + +#else // __NR_getrandom + +#define __NR_getrandom EXPECTED_NR_getrandom + +#endif // __NR_getrandom + +#endif // EXPECTED_NR_getrandom + +#if !defined(GRND_NONBLOCK) +#define GRND_NONBLOCK 1 +#endif + +#endif // OPENSSL_LINUX + +// rand_lock is used to protect the |*_requested| variables. +DEFINE_STATIC_MUTEX(rand_lock); + +// The following constants are magic values of |urandom_fd|. +static const int kUnset = 0; +static const int kHaveGetrandom = -3; + +// urandom_fd_requested is set by |RAND_set_urandom_fd|. It's protected by +// |rand_lock|. +DEFINE_BSS_GET(int, urandom_fd_requested); + +// urandom_fd is a file descriptor to /dev/urandom. It's protected by |once|. +DEFINE_BSS_GET(int, urandom_fd); + +DEFINE_STATIC_ONCE(rand_once); + +#if defined(USE_NR_getrandom) || defined(BORINGSSL_FIPS) +// message writes |msg| to stderr. We use this because referencing |stderr| +// with |fprintf| generates relocations, which is a problem inside the FIPS +// module. +static void message(const char *msg) { + ssize_t r; + do { + r = write(2, msg, strlen(msg)); + } while (r == -1 && errno == EINTR); +} +#endif + +// init_once initializes the state of this module to values previously +// requested. This is the only function that modifies |urandom_fd| and +// |urandom_buffering|, whose values may be read safely after calling the +// once. +static void init_once(void) { + CRYPTO_STATIC_MUTEX_lock_read(rand_lock_bss_get()); + int fd = *urandom_fd_requested_bss_get(); + CRYPTO_STATIC_MUTEX_unlock_read(rand_lock_bss_get()); + +#if defined(USE_NR_getrandom) + uint8_t dummy; + long getrandom_ret = + syscall(__NR_getrandom, &dummy, sizeof(dummy), GRND_NONBLOCK); + + if (getrandom_ret == 1) { + *urandom_fd_bss_get() = kHaveGetrandom; + return; + } else if (getrandom_ret == -1 && errno == EAGAIN) { + message( + "getrandom indicates that the entropy pool has not been initialized. " + "Rather than continue with poor entropy, this process will block until " + "entropy is available.\n"); + + do { + getrandom_ret = + syscall(__NR_getrandom, &dummy, sizeof(dummy), 0 /* no flags */); + } while (getrandom_ret == -1 && errno == EINTR); + + if (getrandom_ret == 1) { + *urandom_fd_bss_get() = kHaveGetrandom; + return; + } + } +#endif // USE_NR_getrandom + + if (fd == kUnset) { + do { + fd = open("/dev/urandom", O_RDONLY); + } while (fd == -1 && errno == EINTR); + } + + if (fd < 0) { + abort(); + } + + assert(kUnset == 0); + if (fd == kUnset) { + // Because we want to keep |urandom_fd| in the BSS, we have to initialise + // it to zero. But zero is a valid file descriptor too. Thus if open + // returns zero for /dev/urandom, we dup it to get a non-zero number. + fd = dup(fd); + close(kUnset); + + if (fd <= 0) { + abort(); + } + } + +#if defined(BORINGSSL_FIPS) + // In FIPS mode we ensure that the kernel has sufficient entropy before + // continuing. This is automatically handled by getrandom, which requires + // that the entropy pool has been initialised, but for urandom we have to + // poll. + for (;;) { + int entropy_bits; + if (ioctl(fd, RNDGETENTCNT, &entropy_bits)) { + message( + "RNDGETENTCNT on /dev/urandom failed. We cannot continue in this " + "case when in FIPS mode.\n"); + abort(); + } + + static const int kBitsNeeded = 256; + if (entropy_bits >= kBitsNeeded) { + break; + } + + usleep(250000); + } +#endif + + int flags = fcntl(fd, F_GETFD); + if (flags == -1) { + // Native Client doesn't implement |fcntl|. + if (errno != ENOSYS) { + abort(); + } + } else { + flags |= FD_CLOEXEC; + if (fcntl(fd, F_SETFD, flags) == -1) { + abort(); + } + } + *urandom_fd_bss_get() = fd; +} + +void RAND_set_urandom_fd(int fd) { + fd = dup(fd); + if (fd < 0) { + abort(); + } + + assert(kUnset == 0); + if (fd == kUnset) { + // Because we want to keep |urandom_fd| in the BSS, we have to initialise + // it to zero. But zero is a valid file descriptor too. Thus if dup + // returned zero we dup it again to get a non-zero number. + fd = dup(fd); + close(kUnset); + + if (fd <= 0) { + abort(); + } + } + + CRYPTO_STATIC_MUTEX_lock_write(rand_lock_bss_get()); + *urandom_fd_requested_bss_get() = fd; + CRYPTO_STATIC_MUTEX_unlock_write(rand_lock_bss_get()); + + CRYPTO_once(rand_once_bss_get(), init_once); + if (*urandom_fd_bss_get() == kHaveGetrandom) { + close(fd); + } else if (*urandom_fd_bss_get() != fd) { + abort(); // Already initialized. + } +} + +#if defined(USE_NR_getrandom) && defined(OPENSSL_MSAN) +void __msan_unpoison(void *, size_t); +#endif + +// fill_with_entropy writes |len| bytes of entropy into |out|. It returns one +// on success and zero on error. +static char fill_with_entropy(uint8_t *out, size_t len) { + while (len > 0) { + ssize_t r; + + if (*urandom_fd_bss_get() == kHaveGetrandom) { +#if defined(USE_NR_getrandom) + do { + r = syscall(__NR_getrandom, out, len, 0 /* no flags */); + } while (r == -1 && errno == EINTR); + +#if defined(OPENSSL_MSAN) + if (r > 0) { + // MSAN doesn't recognise |syscall| and thus doesn't notice that we + // have initialised the output buffer. + __msan_unpoison(out, r); + } +#endif // OPENSSL_MSAN + +#else // USE_NR_getrandom + abort(); +#endif + } else { + do { + r = read(*urandom_fd_bss_get(), out, len); + } while (r == -1 && errno == EINTR); + } + + if (r <= 0) { + return 0; + } + out += r; + len -= r; + } + + return 1; +} + +// CRYPTO_sysrand puts |requested| random bytes into |out|. +void CRYPTO_sysrand(uint8_t *out, size_t requested) { + if (requested == 0) { + return; + } + + CRYPTO_once(rand_once_bss_get(), init_once); + + if (!fill_with_entropy(out, requested)) { + abort(); + } + +#if defined(BORINGSSL_FIPS_BREAK_CRNG) + // This breaks the "continuous random number generator test" defined in FIPS + // 140-2, section 4.9.2, and implemented in rand_get_seed(). + OPENSSL_memset(out, 0, requested); +#endif +} + +#endif /* !OPENSSL_WINDOWS && !defined(OPENSSL_FUCHSIA) && \ + !BORINGSSL_UNSAFE_DETERMINISTIC_MODE && !OPENSSL_TRUSTY */ diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/rsa/blinding.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/rsa/blinding.c new file mode 100644 index 0000000..652cae6 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/rsa/blinding.c @@ -0,0 +1,239 @@ +/* ==================================================================== + * 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.] */ + +#include + +#include + +#include +#include +#include + +#include "internal.h" +#include "../../internal.h" + + +#define BN_BLINDING_COUNTER 32 + +struct bn_blinding_st { + BIGNUM *A; // The base blinding factor, Montgomery-encoded. + BIGNUM *Ai; // The inverse of the blinding factor, Montgomery-encoded. + unsigned counter; +}; + +static int bn_blinding_create_param(BN_BLINDING *b, const BIGNUM *e, + const BN_MONT_CTX *mont, BN_CTX *ctx); + +BN_BLINDING *BN_BLINDING_new(void) { + BN_BLINDING *ret = OPENSSL_malloc(sizeof(BN_BLINDING)); + if (ret == NULL) { + OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); + return NULL; + } + OPENSSL_memset(ret, 0, sizeof(BN_BLINDING)); + + ret->A = BN_new(); + if (ret->A == NULL) { + goto err; + } + + ret->Ai = BN_new(); + if (ret->Ai == NULL) { + goto err; + } + + // The blinding values need to be created before this blinding can be used. + ret->counter = BN_BLINDING_COUNTER - 1; + + return ret; + +err: + BN_BLINDING_free(ret); + return NULL; +} + +void BN_BLINDING_free(BN_BLINDING *r) { + if (r == NULL) { + return; + } + + BN_free(r->A); + BN_free(r->Ai); + OPENSSL_free(r); +} + +static int bn_blinding_update(BN_BLINDING *b, const BIGNUM *e, + const BN_MONT_CTX *mont, BN_CTX *ctx) { + if (++b->counter == BN_BLINDING_COUNTER) { + // re-create blinding parameters + if (!bn_blinding_create_param(b, e, mont, ctx)) { + goto err; + } + b->counter = 0; + } else { + if (!BN_mod_mul_montgomery(b->A, b->A, b->A, mont, ctx) || + !BN_mod_mul_montgomery(b->Ai, b->Ai, b->Ai, mont, ctx)) { + goto err; + } + } + + return 1; + +err: + // |A| and |Ai| may be in an inconsistent state so they both need to be + // replaced the next time this blinding is used. Note that this is only + // sufficient because support for |BN_BLINDING_NO_UPDATE| and + // |BN_BLINDING_NO_RECREATE| was previously dropped. + b->counter = BN_BLINDING_COUNTER - 1; + + return 0; +} + +int BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *b, const BIGNUM *e, + const BN_MONT_CTX *mont, BN_CTX *ctx) { + // |n| is not Montgomery-encoded and |b->A| is. |BN_mod_mul_montgomery| + // cancels one Montgomery factor, so the resulting value of |n| is unencoded. + if (!bn_blinding_update(b, e, mont, ctx) || + !BN_mod_mul_montgomery(n, n, b->A, mont, ctx)) { + return 0; + } + + return 1; +} + +int BN_BLINDING_invert(BIGNUM *n, const BN_BLINDING *b, BN_MONT_CTX *mont, + BN_CTX *ctx) { + // |n| is not Montgomery-encoded and |b->A| is. |BN_mod_mul_montgomery| + // cancels one Montgomery factor, so the resulting value of |n| is unencoded. + return BN_mod_mul_montgomery(n, n, b->Ai, mont, ctx); +} + +static int bn_blinding_create_param(BN_BLINDING *b, const BIGNUM *e, + const BN_MONT_CTX *mont, BN_CTX *ctx) { + int no_inverse; + if (!BN_rand_range_ex(b->A, 1, &mont->N) || + // Compute |b->A|^-1 in Montgomery form. Note |BN_from_montgomery| + + // |BN_mod_inverse_blinded| is equivalent to, but more efficient than, + // |BN_mod_inverse_blinded| + |BN_to_montgomery|. + // + // We do not retry if |b->A| has no inverse. Finding a non-invertible + // value of |b->A| is equivalent to factoring |mont->N|. There is + // negligible probability of stumbling on one at random. + !BN_from_montgomery(b->Ai, b->A, mont, ctx) || + !BN_mod_inverse_blinded(b->Ai, &no_inverse, b->Ai, mont, ctx) || + // TODO(davidben): |BN_mod_exp_mont| internally computes the result in + // Montgomery form. Save a pair of Montgomery reductions and a + // multiplication by returning that value directly. + !BN_mod_exp_mont(b->A, b->A, e, &mont->N, ctx, mont) || + !BN_to_montgomery(b->A, b->A, mont, ctx)) { + OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR); + return 0; + } + + return 1; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/rsa/blinding.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/rsa/blinding.c.grpc_back new file mode 100644 index 0000000..b05f9c9 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/rsa/blinding.c.grpc_back @@ -0,0 +1,239 @@ +/* ==================================================================== + * 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.] */ + +#include + +#include + +#include +#include +#include + +#include "internal.h" +#include "../../internal.h" + + +#define BN_BLINDING_COUNTER 32 + +struct bn_blinding_st { + BIGNUM *A; // The base blinding factor, Montgomery-encoded. + BIGNUM *Ai; // The inverse of the blinding factor, Montgomery-encoded. + unsigned counter; +}; + +static int bn_blinding_create_param(BN_BLINDING *b, const BIGNUM *e, + const BN_MONT_CTX *mont, BN_CTX *ctx); + +BN_BLINDING *BN_BLINDING_new(void) { + BN_BLINDING *ret = OPENSSL_malloc(sizeof(BN_BLINDING)); + if (ret == NULL) { + OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); + return NULL; + } + OPENSSL_memset(ret, 0, sizeof(BN_BLINDING)); + + ret->A = BN_new(); + if (ret->A == NULL) { + goto err; + } + + ret->Ai = BN_new(); + if (ret->Ai == NULL) { + goto err; + } + + // The blinding values need to be created before this blinding can be used. + ret->counter = BN_BLINDING_COUNTER - 1; + + return ret; + +err: + BN_BLINDING_free(ret); + return NULL; +} + +void BN_BLINDING_free(BN_BLINDING *r) { + if (r == NULL) { + return; + } + + BN_free(r->A); + BN_free(r->Ai); + OPENSSL_free(r); +} + +static int bn_blinding_update(BN_BLINDING *b, const BIGNUM *e, + const BN_MONT_CTX *mont, BN_CTX *ctx) { + if (++b->counter == BN_BLINDING_COUNTER) { + // re-create blinding parameters + if (!bn_blinding_create_param(b, e, mont, ctx)) { + goto err; + } + b->counter = 0; + } else { + if (!BN_mod_mul_montgomery(b->A, b->A, b->A, mont, ctx) || + !BN_mod_mul_montgomery(b->Ai, b->Ai, b->Ai, mont, ctx)) { + goto err; + } + } + + return 1; + +err: + // |A| and |Ai| may be in an inconsistent state so they both need to be + // replaced the next time this blinding is used. Note that this is only + // sufficient because support for |BN_BLINDING_NO_UPDATE| and + // |BN_BLINDING_NO_RECREATE| was previously dropped. + b->counter = BN_BLINDING_COUNTER - 1; + + return 0; +} + +int BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *b, const BIGNUM *e, + const BN_MONT_CTX *mont, BN_CTX *ctx) { + // |n| is not Montgomery-encoded and |b->A| is. |BN_mod_mul_montgomery| + // cancels one Montgomery factor, so the resulting value of |n| is unencoded. + if (!bn_blinding_update(b, e, mont, ctx) || + !BN_mod_mul_montgomery(n, n, b->A, mont, ctx)) { + return 0; + } + + return 1; +} + +int BN_BLINDING_invert(BIGNUM *n, const BN_BLINDING *b, BN_MONT_CTX *mont, + BN_CTX *ctx) { + // |n| is not Montgomery-encoded and |b->A| is. |BN_mod_mul_montgomery| + // cancels one Montgomery factor, so the resulting value of |n| is unencoded. + return BN_mod_mul_montgomery(n, n, b->Ai, mont, ctx); +} + +static int bn_blinding_create_param(BN_BLINDING *b, const BIGNUM *e, + const BN_MONT_CTX *mont, BN_CTX *ctx) { + int no_inverse; + if (!BN_rand_range_ex(b->A, 1, &mont->N) || + // Compute |b->A|^-1 in Montgomery form. Note |BN_from_montgomery| + + // |BN_mod_inverse_blinded| is equivalent to, but more efficient than, + // |BN_mod_inverse_blinded| + |BN_to_montgomery|. + // + // We do not retry if |b->A| has no inverse. Finding a non-invertible + // value of |b->A| is equivalent to factoring |mont->N|. There is + // negligible probability of stumbling on one at random. + !BN_from_montgomery(b->Ai, b->A, mont, ctx) || + !BN_mod_inverse_blinded(b->Ai, &no_inverse, b->Ai, mont, ctx) || + // TODO(davidben): |BN_mod_exp_mont| internally computes the result in + // Montgomery form. Save a pair of Montgomery reductions and a + // multiplication by returning that value directly. + !BN_mod_exp_mont(b->A, b->A, e, &mont->N, ctx, mont) || + !BN_to_montgomery(b->A, b->A, mont, ctx)) { + OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR); + return 0; + } + + return 1; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/rsa/internal.h b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/rsa/internal.h new file mode 100644 index 0000000..91ab372 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/rsa/internal.h @@ -0,0 +1,126 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 OPENSSL_HEADER_RSA_INTERNAL_H +#define OPENSSL_HEADER_RSA_INTERNAL_H + +#include + +#include + + +#if defined(__cplusplus) +extern "C" { +#endif + + +// Default implementations of RSA operations. + +const RSA_METHOD *RSA_default_method(void); + +size_t rsa_default_size(const RSA *rsa); +int rsa_default_sign_raw(RSA *rsa, size_t *out_len, uint8_t *out, + size_t max_out, const uint8_t *in, size_t in_len, + int padding); +int rsa_default_decrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out, + const uint8_t *in, size_t in_len, int padding); +int rsa_default_private_transform(RSA *rsa, uint8_t *out, const uint8_t *in, + size_t len); + + +BN_BLINDING *BN_BLINDING_new(void); +void BN_BLINDING_free(BN_BLINDING *b); +int BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *b, const BIGNUM *e, + const BN_MONT_CTX *mont_ctx, BN_CTX *ctx); +int BN_BLINDING_invert(BIGNUM *n, const BN_BLINDING *b, BN_MONT_CTX *mont_ctx, + BN_CTX *ctx); + + +int RSA_padding_add_PKCS1_type_1(uint8_t *to, size_t to_len, + const uint8_t *from, size_t from_len); +int RSA_padding_check_PKCS1_type_1(uint8_t *out, size_t *out_len, + size_t max_out, const uint8_t *from, + size_t from_len); +int RSA_padding_add_PKCS1_type_2(uint8_t *to, size_t to_len, + const uint8_t *from, size_t from_len); +int RSA_padding_check_PKCS1_type_2(uint8_t *out, size_t *out_len, + size_t max_out, const uint8_t *from, + size_t from_len); +int RSA_padding_check_PKCS1_OAEP_mgf1(uint8_t *out, size_t *out_len, + size_t max_out, const uint8_t *from, + size_t from_len, const uint8_t *param, + size_t param_len, const EVP_MD *md, + const EVP_MD *mgf1md); +int RSA_padding_add_none(uint8_t *to, size_t to_len, const uint8_t *from, + size_t from_len); + +// RSA_private_transform calls either the method-specific |private_transform| +// function (if given) or the generic one. See the comment for +// |private_transform| in |rsa_meth_st|. +int RSA_private_transform(RSA *rsa, uint8_t *out, const uint8_t *in, + size_t len); + + +// This constant is exported for test purposes. +extern const BN_ULONG kBoringSSLRSASqrtTwo[]; +extern const size_t kBoringSSLRSASqrtTwoLen; + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_RSA_INTERNAL_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/rsa/internal.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/rsa/internal.h.grpc_back new file mode 100644 index 0000000..f913058 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/rsa/internal.h.grpc_back @@ -0,0 +1,126 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 OPENSSL_HEADER_RSA_INTERNAL_H +#define OPENSSL_HEADER_RSA_INTERNAL_H + +#include + +#include + + +#if defined(__cplusplus) +extern "C" { +#endif + + +// Default implementations of RSA operations. + +const RSA_METHOD *RSA_default_method(void); + +size_t rsa_default_size(const RSA *rsa); +int rsa_default_sign_raw(RSA *rsa, size_t *out_len, uint8_t *out, + size_t max_out, const uint8_t *in, size_t in_len, + int padding); +int rsa_default_decrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out, + const uint8_t *in, size_t in_len, int padding); +int rsa_default_private_transform(RSA *rsa, uint8_t *out, const uint8_t *in, + size_t len); + + +BN_BLINDING *BN_BLINDING_new(void); +void BN_BLINDING_free(BN_BLINDING *b); +int BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *b, const BIGNUM *e, + const BN_MONT_CTX *mont_ctx, BN_CTX *ctx); +int BN_BLINDING_invert(BIGNUM *n, const BN_BLINDING *b, BN_MONT_CTX *mont_ctx, + BN_CTX *ctx); + + +int RSA_padding_add_PKCS1_type_1(uint8_t *to, size_t to_len, + const uint8_t *from, size_t from_len); +int RSA_padding_check_PKCS1_type_1(uint8_t *out, size_t *out_len, + size_t max_out, const uint8_t *from, + size_t from_len); +int RSA_padding_add_PKCS1_type_2(uint8_t *to, size_t to_len, + const uint8_t *from, size_t from_len); +int RSA_padding_check_PKCS1_type_2(uint8_t *out, size_t *out_len, + size_t max_out, const uint8_t *from, + size_t from_len); +int RSA_padding_check_PKCS1_OAEP_mgf1(uint8_t *out, size_t *out_len, + size_t max_out, const uint8_t *from, + size_t from_len, const uint8_t *param, + size_t param_len, const EVP_MD *md, + const EVP_MD *mgf1md); +int RSA_padding_add_none(uint8_t *to, size_t to_len, const uint8_t *from, + size_t from_len); + +// RSA_private_transform calls either the method-specific |private_transform| +// function (if given) or the generic one. See the comment for +// |private_transform| in |rsa_meth_st|. +int RSA_private_transform(RSA *rsa, uint8_t *out, const uint8_t *in, + size_t len); + + +// This constant is exported for test purposes. +extern const BN_ULONG kBoringSSLRSASqrtTwo[]; +extern const size_t kBoringSSLRSASqrtTwoLen; + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_RSA_INTERNAL_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/rsa/padding.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/rsa/padding.c new file mode 100644 index 0000000..a8dd0e5 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/rsa/padding.c @@ -0,0 +1,692 @@ +/* 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 +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "internal.h" +#include "../../internal.h" + + +#define RSA_PKCS1_PADDING_SIZE 11 + +int RSA_padding_add_PKCS1_type_1(uint8_t *to, size_t to_len, + const uint8_t *from, size_t from_len) { + // See RFC 8017, section 9.2. + if (to_len < RSA_PKCS1_PADDING_SIZE) { + OPENSSL_PUT_ERROR(RSA, RSA_R_KEY_SIZE_TOO_SMALL); + return 0; + } + + if (from_len > to_len - RSA_PKCS1_PADDING_SIZE) { + OPENSSL_PUT_ERROR(RSA, RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY); + return 0; + } + + to[0] = 0; + to[1] = 1; + OPENSSL_memset(to + 2, 0xff, to_len - 3 - from_len); + to[to_len - from_len - 1] = 0; + OPENSSL_memcpy(to + to_len - from_len, from, from_len); + return 1; +} + +int RSA_padding_check_PKCS1_type_1(uint8_t *out, size_t *out_len, + size_t max_out, const uint8_t *from, + size_t from_len) { + // See RFC 8017, section 9.2. This is part of signature verification and thus + // does not need to run in constant-time. + if (from_len < 2) { + OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_SMALL); + return 0; + } + + // Check the header. + if (from[0] != 0 || from[1] != 1) { + OPENSSL_PUT_ERROR(RSA, RSA_R_BLOCK_TYPE_IS_NOT_01); + return 0; + } + + // Scan over padded data, looking for the 00. + size_t pad; + for (pad = 2 /* header */; pad < from_len; pad++) { + if (from[pad] == 0x00) { + break; + } + + if (from[pad] != 0xff) { + OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_FIXED_HEADER_DECRYPT); + return 0; + } + } + + if (pad == from_len) { + OPENSSL_PUT_ERROR(RSA, RSA_R_NULL_BEFORE_BLOCK_MISSING); + return 0; + } + + if (pad < 2 /* header */ + 8) { + OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_PAD_BYTE_COUNT); + return 0; + } + + // Skip over the 00. + pad++; + + if (from_len - pad > max_out) { + OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE); + return 0; + } + + OPENSSL_memcpy(out, from + pad, from_len - pad); + *out_len = from_len - pad; + return 1; +} + +static int rand_nonzero(uint8_t *out, size_t len) { + if (!RAND_bytes(out, len)) { + return 0; + } + + for (size_t i = 0; i < len; i++) { + while (out[i] == 0) { + if (!RAND_bytes(out + i, 1)) { + return 0; + } + } + } + + return 1; +} + +int RSA_padding_add_PKCS1_type_2(uint8_t *to, size_t to_len, + const uint8_t *from, size_t from_len) { + // See RFC 8017, section 7.2.1. + if (to_len < RSA_PKCS1_PADDING_SIZE) { + OPENSSL_PUT_ERROR(RSA, RSA_R_KEY_SIZE_TOO_SMALL); + return 0; + } + + if (from_len > to_len - RSA_PKCS1_PADDING_SIZE) { + OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE); + return 0; + } + + to[0] = 0; + to[1] = 2; + + size_t padding_len = to_len - 3 - from_len; + if (!rand_nonzero(to + 2, padding_len)) { + return 0; + } + + to[2 + padding_len] = 0; + OPENSSL_memcpy(to + to_len - from_len, from, from_len); + return 1; +} + +int RSA_padding_check_PKCS1_type_2(uint8_t *out, size_t *out_len, + size_t max_out, const uint8_t *from, + size_t from_len) { + if (from_len == 0) { + OPENSSL_PUT_ERROR(RSA, RSA_R_EMPTY_PUBLIC_KEY); + return 0; + } + + // PKCS#1 v1.5 decryption. See "PKCS #1 v2.2: RSA Cryptography + // Standard", section 7.2.2. + if (from_len < RSA_PKCS1_PADDING_SIZE) { + // |from| is zero-padded to the size of the RSA modulus, a public value, so + // this can be rejected in non-constant time. + OPENSSL_PUT_ERROR(RSA, RSA_R_KEY_SIZE_TOO_SMALL); + return 0; + } + + crypto_word_t first_byte_is_zero = constant_time_eq_w(from[0], 0); + crypto_word_t second_byte_is_two = constant_time_eq_w(from[1], 2); + + crypto_word_t zero_index = 0, looking_for_index = CONSTTIME_TRUE_W; + for (size_t i = 2; i < from_len; i++) { + crypto_word_t equals0 = constant_time_is_zero_w(from[i]); + zero_index = + constant_time_select_w(looking_for_index & equals0, i, zero_index); + looking_for_index = constant_time_select_w(equals0, 0, looking_for_index); + } + + // The input must begin with 00 02. + crypto_word_t valid_index = first_byte_is_zero; + valid_index &= second_byte_is_two; + + // We must have found the end of PS. + valid_index &= ~looking_for_index; + + // PS must be at least 8 bytes long, and it starts two bytes into |from|. + valid_index &= constant_time_ge_w(zero_index, 2 + 8); + + // Skip the zero byte. + zero_index++; + + // NOTE: Although this logic attempts to be constant time, the API contracts + // of this function and |RSA_decrypt| with |RSA_PKCS1_PADDING| make it + // impossible to completely avoid Bleichenbacher's attack. Consumers should + // use |RSA_PADDING_NONE| and perform the padding check in constant-time + // combined with a swap to a random session key or other mitigation. + if (!valid_index) { + OPENSSL_PUT_ERROR(RSA, RSA_R_PKCS_DECODING_ERROR); + return 0; + } + + const size_t msg_len = from_len - zero_index; + if (msg_len > max_out) { + // This shouldn't happen because this function is always called with + // |max_out| as the key size and |from_len| is bounded by the key size. + OPENSSL_PUT_ERROR(RSA, RSA_R_PKCS_DECODING_ERROR); + return 0; + } + + OPENSSL_memcpy(out, &from[zero_index], msg_len); + *out_len = msg_len; + return 1; +} + +int RSA_padding_add_none(uint8_t *to, size_t to_len, const uint8_t *from, + size_t from_len) { + if (from_len > to_len) { + OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE); + return 0; + } + + if (from_len < to_len) { + OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_SMALL); + return 0; + } + + OPENSSL_memcpy(to, from, from_len); + return 1; +} + +static int PKCS1_MGF1(uint8_t *out, size_t len, const uint8_t *seed, + size_t seed_len, const EVP_MD *md) { + int ret = 0; + EVP_MD_CTX ctx; + EVP_MD_CTX_init(&ctx); + + size_t md_len = EVP_MD_size(md); + + for (uint32_t i = 0; len > 0; i++) { + uint8_t counter[4]; + counter[0] = (uint8_t)(i >> 24); + counter[1] = (uint8_t)(i >> 16); + counter[2] = (uint8_t)(i >> 8); + counter[3] = (uint8_t)i; + if (!EVP_DigestInit_ex(&ctx, md, NULL) || + !EVP_DigestUpdate(&ctx, seed, seed_len) || + !EVP_DigestUpdate(&ctx, counter, sizeof(counter))) { + goto err; + } + + if (md_len <= len) { + if (!EVP_DigestFinal_ex(&ctx, out, NULL)) { + goto err; + } + out += md_len; + len -= md_len; + } else { + uint8_t digest[EVP_MAX_MD_SIZE]; + if (!EVP_DigestFinal_ex(&ctx, digest, NULL)) { + goto err; + } + OPENSSL_memcpy(out, digest, len); + len = 0; + } + } + + ret = 1; + +err: + EVP_MD_CTX_cleanup(&ctx); + return ret; +} + +int RSA_padding_add_PKCS1_OAEP_mgf1(uint8_t *to, size_t to_len, + const uint8_t *from, size_t from_len, + const uint8_t *param, size_t param_len, + const EVP_MD *md, const EVP_MD *mgf1md) { + if (md == NULL) { + md = EVP_sha1(); + } + if (mgf1md == NULL) { + mgf1md = md; + } + + size_t mdlen = EVP_MD_size(md); + + if (to_len < 2 * mdlen + 2) { + OPENSSL_PUT_ERROR(RSA, RSA_R_KEY_SIZE_TOO_SMALL); + return 0; + } + + size_t emlen = to_len - 1; + if (from_len > emlen - 2 * mdlen - 1) { + OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE); + return 0; + } + + if (emlen < 2 * mdlen + 1) { + OPENSSL_PUT_ERROR(RSA, RSA_R_KEY_SIZE_TOO_SMALL); + return 0; + } + + to[0] = 0; + uint8_t *seed = to + 1; + uint8_t *db = to + mdlen + 1; + + if (!EVP_Digest(param, param_len, db, NULL, md, NULL)) { + return 0; + } + OPENSSL_memset(db + mdlen, 0, emlen - from_len - 2 * mdlen - 1); + db[emlen - from_len - mdlen - 1] = 0x01; + OPENSSL_memcpy(db + emlen - from_len - mdlen, from, from_len); + if (!RAND_bytes(seed, mdlen)) { + return 0; + } + + uint8_t *dbmask = OPENSSL_malloc(emlen - mdlen); + if (dbmask == NULL) { + OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); + return 0; + } + + int ret = 0; + if (!PKCS1_MGF1(dbmask, emlen - mdlen, seed, mdlen, mgf1md)) { + goto out; + } + for (size_t i = 0; i < emlen - mdlen; i++) { + db[i] ^= dbmask[i]; + } + + uint8_t seedmask[EVP_MAX_MD_SIZE]; + if (!PKCS1_MGF1(seedmask, mdlen, db, emlen - mdlen, mgf1md)) { + goto out; + } + for (size_t i = 0; i < mdlen; i++) { + seed[i] ^= seedmask[i]; + } + ret = 1; + +out: + OPENSSL_free(dbmask); + return ret; +} + +int RSA_padding_check_PKCS1_OAEP_mgf1(uint8_t *out, size_t *out_len, + size_t max_out, const uint8_t *from, + size_t from_len, const uint8_t *param, + size_t param_len, const EVP_MD *md, + const EVP_MD *mgf1md) { + uint8_t *db = NULL; + + if (md == NULL) { + md = EVP_sha1(); + } + if (mgf1md == NULL) { + mgf1md = md; + } + + size_t mdlen = EVP_MD_size(md); + + // The encoded message is one byte smaller than the modulus to ensure that it + // doesn't end up greater than the modulus. Thus there's an extra "+1" here + // compared to https://tools.ietf.org/html/rfc2437#section-9.1.1.2. + if (from_len < 1 + 2*mdlen + 1) { + // 'from_len' is the length of the modulus, i.e. does not depend on the + // particular ciphertext. + goto decoding_err; + } + + size_t dblen = from_len - mdlen - 1; + db = OPENSSL_malloc(dblen); + if (db == NULL) { + OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); + goto err; + } + + const uint8_t *maskedseed = from + 1; + const uint8_t *maskeddb = from + 1 + mdlen; + + uint8_t seed[EVP_MAX_MD_SIZE]; + if (!PKCS1_MGF1(seed, mdlen, maskeddb, dblen, mgf1md)) { + goto err; + } + for (size_t i = 0; i < mdlen; i++) { + seed[i] ^= maskedseed[i]; + } + + if (!PKCS1_MGF1(db, dblen, seed, mdlen, mgf1md)) { + goto err; + } + for (size_t i = 0; i < dblen; i++) { + db[i] ^= maskeddb[i]; + } + + uint8_t phash[EVP_MAX_MD_SIZE]; + if (!EVP_Digest(param, param_len, phash, NULL, md, NULL)) { + goto err; + } + + crypto_word_t bad = ~constant_time_is_zero_w(CRYPTO_memcmp(db, phash, mdlen)); + bad |= ~constant_time_is_zero_w(from[0]); + + crypto_word_t looking_for_one_byte = CONSTTIME_TRUE_W; + size_t one_index = 0; + for (size_t i = mdlen; i < dblen; i++) { + crypto_word_t equals1 = constant_time_eq_w(db[i], 1); + crypto_word_t equals0 = constant_time_eq_w(db[i], 0); + one_index = + constant_time_select_w(looking_for_one_byte & equals1, i, one_index); + looking_for_one_byte = + constant_time_select_w(equals1, 0, looking_for_one_byte); + bad |= looking_for_one_byte & ~equals0; + } + + bad |= looking_for_one_byte; + + if (bad) { + goto decoding_err; + } + + one_index++; + size_t mlen = dblen - one_index; + if (max_out < mlen) { + OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE); + goto err; + } + + OPENSSL_memcpy(out, db + one_index, mlen); + *out_len = mlen; + OPENSSL_free(db); + return 1; + +decoding_err: + // to avoid chosen ciphertext attacks, the error message should not reveal + // which kind of decoding error happened + OPENSSL_PUT_ERROR(RSA, RSA_R_OAEP_DECODING_ERROR); + err: + OPENSSL_free(db); + return 0; +} + +static const uint8_t kPSSZeroes[] = {0, 0, 0, 0, 0, 0, 0, 0}; + +int RSA_verify_PKCS1_PSS_mgf1(RSA *rsa, const uint8_t *mHash, + const EVP_MD *Hash, const EVP_MD *mgf1Hash, + const uint8_t *EM, int sLen) { + int i; + int ret = 0; + int maskedDBLen, MSBits, emLen; + size_t hLen; + const uint8_t *H; + uint8_t *DB = NULL; + EVP_MD_CTX ctx; + uint8_t H_[EVP_MAX_MD_SIZE]; + EVP_MD_CTX_init(&ctx); + + if (mgf1Hash == NULL) { + mgf1Hash = Hash; + } + + hLen = EVP_MD_size(Hash); + + // 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) { + OPENSSL_PUT_ERROR(RSA, RSA_R_SLEN_CHECK_FAILED); + goto err; + } + + MSBits = (BN_num_bits(rsa->n) - 1) & 0x7; + emLen = RSA_size(rsa); + if (EM[0] & (0xFF << MSBits)) { + OPENSSL_PUT_ERROR(RSA, RSA_R_FIRST_OCTET_INVALID); + goto err; + } + if (MSBits == 0) { + EM++; + emLen--; + } + if (emLen < (int)hLen + 2 || emLen < ((int)hLen + sLen + 2)) { + // sLen can be small negative + OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE); + goto err; + } + if (EM[emLen - 1] != 0xbc) { + OPENSSL_PUT_ERROR(RSA, RSA_R_LAST_OCTET_INVALID); + goto err; + } + maskedDBLen = emLen - hLen - 1; + H = EM + maskedDBLen; + DB = OPENSSL_malloc(maskedDBLen); + if (!DB) { + OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); + goto err; + } + if (!PKCS1_MGF1(DB, maskedDBLen, H, hLen, mgf1Hash)) { + 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) { + OPENSSL_PUT_ERROR(RSA, RSA_R_SLEN_RECOVERY_FAILED); + goto err; + } + if (sLen >= 0 && (maskedDBLen - i) != sLen) { + OPENSSL_PUT_ERROR(RSA, RSA_R_SLEN_CHECK_FAILED); + goto err; + } + if (!EVP_DigestInit_ex(&ctx, Hash, NULL) || + !EVP_DigestUpdate(&ctx, kPSSZeroes, sizeof(kPSSZeroes)) || + !EVP_DigestUpdate(&ctx, mHash, hLen) || + !EVP_DigestUpdate(&ctx, DB + i, maskedDBLen - i) || + !EVP_DigestFinal_ex(&ctx, H_, NULL)) { + goto err; + } + if (OPENSSL_memcmp(H_, H, hLen)) { + OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_SIGNATURE); + ret = 0; + } else { + ret = 1; + } + +err: + OPENSSL_free(DB); + EVP_MD_CTX_cleanup(&ctx); + + return ret; +} + +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 sLenRequested) { + int ret = 0; + size_t maskedDBLen, MSBits, emLen; + size_t hLen; + unsigned char *H, *salt = NULL, *p; + + if (mgf1Hash == NULL) { + mgf1Hash = Hash; + } + + hLen = EVP_MD_size(Hash); + + if (BN_is_zero(rsa->n)) { + OPENSSL_PUT_ERROR(RSA, RSA_R_EMPTY_PUBLIC_KEY); + goto err; + } + + MSBits = (BN_num_bits(rsa->n) - 1) & 0x7; + emLen = RSA_size(rsa); + if (MSBits == 0) { + assert(emLen >= 1); + *EM++ = 0; + emLen--; + } + + if (emLen < hLen + 2) { + OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE); + goto err; + } + + // Negative sLenRequested has special meanings: + // -1 sLen == hLen + // -2 salt length is maximized + // -N reserved + size_t sLen; + if (sLenRequested == -1) { + sLen = hLen; + } else if (sLenRequested == -2) { + sLen = emLen - hLen - 2; + } else if (sLenRequested < 0) { + OPENSSL_PUT_ERROR(RSA, RSA_R_SLEN_CHECK_FAILED); + goto err; + } else { + sLen = (size_t)sLenRequested; + } + + if (emLen - hLen - 2 < sLen) { + OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE); + goto err; + } + + if (sLen > 0) { + salt = OPENSSL_malloc(sLen); + if (!salt) { + OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); + goto err; + } + if (!RAND_bytes(salt, sLen)) { + goto err; + } + } + maskedDBLen = emLen - hLen - 1; + H = EM + maskedDBLen; + + EVP_MD_CTX ctx; + EVP_MD_CTX_init(&ctx); + int digest_ok = EVP_DigestInit_ex(&ctx, Hash, NULL) && + EVP_DigestUpdate(&ctx, kPSSZeroes, sizeof(kPSSZeroes)) && + EVP_DigestUpdate(&ctx, mHash, hLen) && + EVP_DigestUpdate(&ctx, salt, sLen) && + EVP_DigestFinal_ex(&ctx, H, NULL); + EVP_MD_CTX_cleanup(&ctx); + if (!digest_ok) { + goto err; + } + + // 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 (size_t 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: + OPENSSL_free(salt); + + return ret; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/rsa/padding.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/rsa/padding.c.grpc_back new file mode 100644 index 0000000..9d88dba --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/rsa/padding.c.grpc_back @@ -0,0 +1,692 @@ +/* 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 +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "internal.h" +#include "../../internal.h" + + +#define RSA_PKCS1_PADDING_SIZE 11 + +int RSA_padding_add_PKCS1_type_1(uint8_t *to, size_t to_len, + const uint8_t *from, size_t from_len) { + // See RFC 8017, section 9.2. + if (to_len < RSA_PKCS1_PADDING_SIZE) { + OPENSSL_PUT_ERROR(RSA, RSA_R_KEY_SIZE_TOO_SMALL); + return 0; + } + + if (from_len > to_len - RSA_PKCS1_PADDING_SIZE) { + OPENSSL_PUT_ERROR(RSA, RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY); + return 0; + } + + to[0] = 0; + to[1] = 1; + OPENSSL_memset(to + 2, 0xff, to_len - 3 - from_len); + to[to_len - from_len - 1] = 0; + OPENSSL_memcpy(to + to_len - from_len, from, from_len); + return 1; +} + +int RSA_padding_check_PKCS1_type_1(uint8_t *out, size_t *out_len, + size_t max_out, const uint8_t *from, + size_t from_len) { + // See RFC 8017, section 9.2. This is part of signature verification and thus + // does not need to run in constant-time. + if (from_len < 2) { + OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_SMALL); + return 0; + } + + // Check the header. + if (from[0] != 0 || from[1] != 1) { + OPENSSL_PUT_ERROR(RSA, RSA_R_BLOCK_TYPE_IS_NOT_01); + return 0; + } + + // Scan over padded data, looking for the 00. + size_t pad; + for (pad = 2 /* header */; pad < from_len; pad++) { + if (from[pad] == 0x00) { + break; + } + + if (from[pad] != 0xff) { + OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_FIXED_HEADER_DECRYPT); + return 0; + } + } + + if (pad == from_len) { + OPENSSL_PUT_ERROR(RSA, RSA_R_NULL_BEFORE_BLOCK_MISSING); + return 0; + } + + if (pad < 2 /* header */ + 8) { + OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_PAD_BYTE_COUNT); + return 0; + } + + // Skip over the 00. + pad++; + + if (from_len - pad > max_out) { + OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE); + return 0; + } + + OPENSSL_memcpy(out, from + pad, from_len - pad); + *out_len = from_len - pad; + return 1; +} + +static int rand_nonzero(uint8_t *out, size_t len) { + if (!RAND_bytes(out, len)) { + return 0; + } + + for (size_t i = 0; i < len; i++) { + while (out[i] == 0) { + if (!RAND_bytes(out + i, 1)) { + return 0; + } + } + } + + return 1; +} + +int RSA_padding_add_PKCS1_type_2(uint8_t *to, size_t to_len, + const uint8_t *from, size_t from_len) { + // See RFC 8017, section 7.2.1. + if (to_len < RSA_PKCS1_PADDING_SIZE) { + OPENSSL_PUT_ERROR(RSA, RSA_R_KEY_SIZE_TOO_SMALL); + return 0; + } + + if (from_len > to_len - RSA_PKCS1_PADDING_SIZE) { + OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE); + return 0; + } + + to[0] = 0; + to[1] = 2; + + size_t padding_len = to_len - 3 - from_len; + if (!rand_nonzero(to + 2, padding_len)) { + return 0; + } + + to[2 + padding_len] = 0; + OPENSSL_memcpy(to + to_len - from_len, from, from_len); + return 1; +} + +int RSA_padding_check_PKCS1_type_2(uint8_t *out, size_t *out_len, + size_t max_out, const uint8_t *from, + size_t from_len) { + if (from_len == 0) { + OPENSSL_PUT_ERROR(RSA, RSA_R_EMPTY_PUBLIC_KEY); + return 0; + } + + // PKCS#1 v1.5 decryption. See "PKCS #1 v2.2: RSA Cryptography + // Standard", section 7.2.2. + if (from_len < RSA_PKCS1_PADDING_SIZE) { + // |from| is zero-padded to the size of the RSA modulus, a public value, so + // this can be rejected in non-constant time. + OPENSSL_PUT_ERROR(RSA, RSA_R_KEY_SIZE_TOO_SMALL); + return 0; + } + + crypto_word_t first_byte_is_zero = constant_time_eq_w(from[0], 0); + crypto_word_t second_byte_is_two = constant_time_eq_w(from[1], 2); + + crypto_word_t zero_index = 0, looking_for_index = CONSTTIME_TRUE_W; + for (size_t i = 2; i < from_len; i++) { + crypto_word_t equals0 = constant_time_is_zero_w(from[i]); + zero_index = + constant_time_select_w(looking_for_index & equals0, i, zero_index); + looking_for_index = constant_time_select_w(equals0, 0, looking_for_index); + } + + // The input must begin with 00 02. + crypto_word_t valid_index = first_byte_is_zero; + valid_index &= second_byte_is_two; + + // We must have found the end of PS. + valid_index &= ~looking_for_index; + + // PS must be at least 8 bytes long, and it starts two bytes into |from|. + valid_index &= constant_time_ge_w(zero_index, 2 + 8); + + // Skip the zero byte. + zero_index++; + + // NOTE: Although this logic attempts to be constant time, the API contracts + // of this function and |RSA_decrypt| with |RSA_PKCS1_PADDING| make it + // impossible to completely avoid Bleichenbacher's attack. Consumers should + // use |RSA_PADDING_NONE| and perform the padding check in constant-time + // combined with a swap to a random session key or other mitigation. + if (!valid_index) { + OPENSSL_PUT_ERROR(RSA, RSA_R_PKCS_DECODING_ERROR); + return 0; + } + + const size_t msg_len = from_len - zero_index; + if (msg_len > max_out) { + // This shouldn't happen because this function is always called with + // |max_out| as the key size and |from_len| is bounded by the key size. + OPENSSL_PUT_ERROR(RSA, RSA_R_PKCS_DECODING_ERROR); + return 0; + } + + OPENSSL_memcpy(out, &from[zero_index], msg_len); + *out_len = msg_len; + return 1; +} + +int RSA_padding_add_none(uint8_t *to, size_t to_len, const uint8_t *from, + size_t from_len) { + if (from_len > to_len) { + OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE); + return 0; + } + + if (from_len < to_len) { + OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_SMALL); + return 0; + } + + OPENSSL_memcpy(to, from, from_len); + return 1; +} + +static int PKCS1_MGF1(uint8_t *out, size_t len, const uint8_t *seed, + size_t seed_len, const EVP_MD *md) { + int ret = 0; + EVP_MD_CTX ctx; + EVP_MD_CTX_init(&ctx); + + size_t md_len = EVP_MD_size(md); + + for (uint32_t i = 0; len > 0; i++) { + uint8_t counter[4]; + counter[0] = (uint8_t)(i >> 24); + counter[1] = (uint8_t)(i >> 16); + counter[2] = (uint8_t)(i >> 8); + counter[3] = (uint8_t)i; + if (!EVP_DigestInit_ex(&ctx, md, NULL) || + !EVP_DigestUpdate(&ctx, seed, seed_len) || + !EVP_DigestUpdate(&ctx, counter, sizeof(counter))) { + goto err; + } + + if (md_len <= len) { + if (!EVP_DigestFinal_ex(&ctx, out, NULL)) { + goto err; + } + out += md_len; + len -= md_len; + } else { + uint8_t digest[EVP_MAX_MD_SIZE]; + if (!EVP_DigestFinal_ex(&ctx, digest, NULL)) { + goto err; + } + OPENSSL_memcpy(out, digest, len); + len = 0; + } + } + + ret = 1; + +err: + EVP_MD_CTX_cleanup(&ctx); + return ret; +} + +int RSA_padding_add_PKCS1_OAEP_mgf1(uint8_t *to, size_t to_len, + const uint8_t *from, size_t from_len, + const uint8_t *param, size_t param_len, + const EVP_MD *md, const EVP_MD *mgf1md) { + if (md == NULL) { + md = EVP_sha1(); + } + if (mgf1md == NULL) { + mgf1md = md; + } + + size_t mdlen = EVP_MD_size(md); + + if (to_len < 2 * mdlen + 2) { + OPENSSL_PUT_ERROR(RSA, RSA_R_KEY_SIZE_TOO_SMALL); + return 0; + } + + size_t emlen = to_len - 1; + if (from_len > emlen - 2 * mdlen - 1) { + OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE); + return 0; + } + + if (emlen < 2 * mdlen + 1) { + OPENSSL_PUT_ERROR(RSA, RSA_R_KEY_SIZE_TOO_SMALL); + return 0; + } + + to[0] = 0; + uint8_t *seed = to + 1; + uint8_t *db = to + mdlen + 1; + + if (!EVP_Digest(param, param_len, db, NULL, md, NULL)) { + return 0; + } + OPENSSL_memset(db + mdlen, 0, emlen - from_len - 2 * mdlen - 1); + db[emlen - from_len - mdlen - 1] = 0x01; + OPENSSL_memcpy(db + emlen - from_len - mdlen, from, from_len); + if (!RAND_bytes(seed, mdlen)) { + return 0; + } + + uint8_t *dbmask = OPENSSL_malloc(emlen - mdlen); + if (dbmask == NULL) { + OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); + return 0; + } + + int ret = 0; + if (!PKCS1_MGF1(dbmask, emlen - mdlen, seed, mdlen, mgf1md)) { + goto out; + } + for (size_t i = 0; i < emlen - mdlen; i++) { + db[i] ^= dbmask[i]; + } + + uint8_t seedmask[EVP_MAX_MD_SIZE]; + if (!PKCS1_MGF1(seedmask, mdlen, db, emlen - mdlen, mgf1md)) { + goto out; + } + for (size_t i = 0; i < mdlen; i++) { + seed[i] ^= seedmask[i]; + } + ret = 1; + +out: + OPENSSL_free(dbmask); + return ret; +} + +int RSA_padding_check_PKCS1_OAEP_mgf1(uint8_t *out, size_t *out_len, + size_t max_out, const uint8_t *from, + size_t from_len, const uint8_t *param, + size_t param_len, const EVP_MD *md, + const EVP_MD *mgf1md) { + uint8_t *db = NULL; + + if (md == NULL) { + md = EVP_sha1(); + } + if (mgf1md == NULL) { + mgf1md = md; + } + + size_t mdlen = EVP_MD_size(md); + + // The encoded message is one byte smaller than the modulus to ensure that it + // doesn't end up greater than the modulus. Thus there's an extra "+1" here + // compared to https://tools.ietf.org/html/rfc2437#section-9.1.1.2. + if (from_len < 1 + 2*mdlen + 1) { + // 'from_len' is the length of the modulus, i.e. does not depend on the + // particular ciphertext. + goto decoding_err; + } + + size_t dblen = from_len - mdlen - 1; + db = OPENSSL_malloc(dblen); + if (db == NULL) { + OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); + goto err; + } + + const uint8_t *maskedseed = from + 1; + const uint8_t *maskeddb = from + 1 + mdlen; + + uint8_t seed[EVP_MAX_MD_SIZE]; + if (!PKCS1_MGF1(seed, mdlen, maskeddb, dblen, mgf1md)) { + goto err; + } + for (size_t i = 0; i < mdlen; i++) { + seed[i] ^= maskedseed[i]; + } + + if (!PKCS1_MGF1(db, dblen, seed, mdlen, mgf1md)) { + goto err; + } + for (size_t i = 0; i < dblen; i++) { + db[i] ^= maskeddb[i]; + } + + uint8_t phash[EVP_MAX_MD_SIZE]; + if (!EVP_Digest(param, param_len, phash, NULL, md, NULL)) { + goto err; + } + + crypto_word_t bad = ~constant_time_is_zero_w(CRYPTO_memcmp(db, phash, mdlen)); + bad |= ~constant_time_is_zero_w(from[0]); + + crypto_word_t looking_for_one_byte = CONSTTIME_TRUE_W; + size_t one_index = 0; + for (size_t i = mdlen; i < dblen; i++) { + crypto_word_t equals1 = constant_time_eq_w(db[i], 1); + crypto_word_t equals0 = constant_time_eq_w(db[i], 0); + one_index = + constant_time_select_w(looking_for_one_byte & equals1, i, one_index); + looking_for_one_byte = + constant_time_select_w(equals1, 0, looking_for_one_byte); + bad |= looking_for_one_byte & ~equals0; + } + + bad |= looking_for_one_byte; + + if (bad) { + goto decoding_err; + } + + one_index++; + size_t mlen = dblen - one_index; + if (max_out < mlen) { + OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE); + goto err; + } + + OPENSSL_memcpy(out, db + one_index, mlen); + *out_len = mlen; + OPENSSL_free(db); + return 1; + +decoding_err: + // to avoid chosen ciphertext attacks, the error message should not reveal + // which kind of decoding error happened + OPENSSL_PUT_ERROR(RSA, RSA_R_OAEP_DECODING_ERROR); + err: + OPENSSL_free(db); + return 0; +} + +static const uint8_t kPSSZeroes[] = {0, 0, 0, 0, 0, 0, 0, 0}; + +int RSA_verify_PKCS1_PSS_mgf1(RSA *rsa, const uint8_t *mHash, + const EVP_MD *Hash, const EVP_MD *mgf1Hash, + const uint8_t *EM, int sLen) { + int i; + int ret = 0; + int maskedDBLen, MSBits, emLen; + size_t hLen; + const uint8_t *H; + uint8_t *DB = NULL; + EVP_MD_CTX ctx; + uint8_t H_[EVP_MAX_MD_SIZE]; + EVP_MD_CTX_init(&ctx); + + if (mgf1Hash == NULL) { + mgf1Hash = Hash; + } + + hLen = EVP_MD_size(Hash); + + // 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) { + OPENSSL_PUT_ERROR(RSA, RSA_R_SLEN_CHECK_FAILED); + goto err; + } + + MSBits = (BN_num_bits(rsa->n) - 1) & 0x7; + emLen = RSA_size(rsa); + if (EM[0] & (0xFF << MSBits)) { + OPENSSL_PUT_ERROR(RSA, RSA_R_FIRST_OCTET_INVALID); + goto err; + } + if (MSBits == 0) { + EM++; + emLen--; + } + if (emLen < (int)hLen + 2 || emLen < ((int)hLen + sLen + 2)) { + // sLen can be small negative + OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE); + goto err; + } + if (EM[emLen - 1] != 0xbc) { + OPENSSL_PUT_ERROR(RSA, RSA_R_LAST_OCTET_INVALID); + goto err; + } + maskedDBLen = emLen - hLen - 1; + H = EM + maskedDBLen; + DB = OPENSSL_malloc(maskedDBLen); + if (!DB) { + OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); + goto err; + } + if (!PKCS1_MGF1(DB, maskedDBLen, H, hLen, mgf1Hash)) { + 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) { + OPENSSL_PUT_ERROR(RSA, RSA_R_SLEN_RECOVERY_FAILED); + goto err; + } + if (sLen >= 0 && (maskedDBLen - i) != sLen) { + OPENSSL_PUT_ERROR(RSA, RSA_R_SLEN_CHECK_FAILED); + goto err; + } + if (!EVP_DigestInit_ex(&ctx, Hash, NULL) || + !EVP_DigestUpdate(&ctx, kPSSZeroes, sizeof(kPSSZeroes)) || + !EVP_DigestUpdate(&ctx, mHash, hLen) || + !EVP_DigestUpdate(&ctx, DB + i, maskedDBLen - i) || + !EVP_DigestFinal_ex(&ctx, H_, NULL)) { + goto err; + } + if (OPENSSL_memcmp(H_, H, hLen)) { + OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_SIGNATURE); + ret = 0; + } else { + ret = 1; + } + +err: + OPENSSL_free(DB); + EVP_MD_CTX_cleanup(&ctx); + + return ret; +} + +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 sLenRequested) { + int ret = 0; + size_t maskedDBLen, MSBits, emLen; + size_t hLen; + unsigned char *H, *salt = NULL, *p; + + if (mgf1Hash == NULL) { + mgf1Hash = Hash; + } + + hLen = EVP_MD_size(Hash); + + if (BN_is_zero(rsa->n)) { + OPENSSL_PUT_ERROR(RSA, RSA_R_EMPTY_PUBLIC_KEY); + goto err; + } + + MSBits = (BN_num_bits(rsa->n) - 1) & 0x7; + emLen = RSA_size(rsa); + if (MSBits == 0) { + assert(emLen >= 1); + *EM++ = 0; + emLen--; + } + + if (emLen < hLen + 2) { + OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE); + goto err; + } + + // Negative sLenRequested has special meanings: + // -1 sLen == hLen + // -2 salt length is maximized + // -N reserved + size_t sLen; + if (sLenRequested == -1) { + sLen = hLen; + } else if (sLenRequested == -2) { + sLen = emLen - hLen - 2; + } else if (sLenRequested < 0) { + OPENSSL_PUT_ERROR(RSA, RSA_R_SLEN_CHECK_FAILED); + goto err; + } else { + sLen = (size_t)sLenRequested; + } + + if (emLen - hLen - 2 < sLen) { + OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE); + goto err; + } + + if (sLen > 0) { + salt = OPENSSL_malloc(sLen); + if (!salt) { + OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); + goto err; + } + if (!RAND_bytes(salt, sLen)) { + goto err; + } + } + maskedDBLen = emLen - hLen - 1; + H = EM + maskedDBLen; + + EVP_MD_CTX ctx; + EVP_MD_CTX_init(&ctx); + int digest_ok = EVP_DigestInit_ex(&ctx, Hash, NULL) && + EVP_DigestUpdate(&ctx, kPSSZeroes, sizeof(kPSSZeroes)) && + EVP_DigestUpdate(&ctx, mHash, hLen) && + EVP_DigestUpdate(&ctx, salt, sLen) && + EVP_DigestFinal_ex(&ctx, H, NULL); + EVP_MD_CTX_cleanup(&ctx); + if (!digest_ok) { + goto err; + } + + // 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 (size_t 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: + OPENSSL_free(salt); + + return ret; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/rsa/rsa.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/rsa/rsa.c new file mode 100644 index 0000000..89eb908 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/rsa/rsa.c @@ -0,0 +1,875 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../bn/internal.h" +#include "../delocate.h" +#include "../../internal.h" +#include "internal.h" + + +DEFINE_STATIC_EX_DATA_CLASS(g_rsa_ex_data_class); + +RSA *RSA_new(void) { return RSA_new_method(NULL); } + +RSA *RSA_new_method(const ENGINE *engine) { + RSA *rsa = OPENSSL_malloc(sizeof(RSA)); + if (rsa == NULL) { + OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); + return NULL; + } + + OPENSSL_memset(rsa, 0, sizeof(RSA)); + + if (engine) { + rsa->meth = ENGINE_get_RSA_method(engine); + } + + if (rsa->meth == NULL) { + rsa->meth = (RSA_METHOD *) RSA_default_method(); + } + METHOD_ref(rsa->meth); + + rsa->references = 1; + rsa->flags = rsa->meth->flags; + CRYPTO_MUTEX_init(&rsa->lock); + CRYPTO_new_ex_data(&rsa->ex_data); + + if (rsa->meth->init && !rsa->meth->init(rsa)) { + CRYPTO_free_ex_data(g_rsa_ex_data_class_bss_get(), rsa, &rsa->ex_data); + CRYPTO_MUTEX_cleanup(&rsa->lock); + METHOD_unref(rsa->meth); + OPENSSL_free(rsa); + return NULL; + } + + return rsa; +} + +void RSA_free(RSA *rsa) { + unsigned u; + + if (rsa == NULL) { + return; + } + + if (!CRYPTO_refcount_dec_and_test_zero(&rsa->references)) { + return; + } + + if (rsa->meth->finish) { + rsa->meth->finish(rsa); + } + METHOD_unref(rsa->meth); + + CRYPTO_free_ex_data(g_rsa_ex_data_class_bss_get(), rsa, &rsa->ex_data); + + BN_free(rsa->n); + BN_free(rsa->e); + BN_free(rsa->d); + BN_free(rsa->p); + BN_free(rsa->q); + BN_free(rsa->dmp1); + BN_free(rsa->dmq1); + BN_free(rsa->iqmp); + BN_MONT_CTX_free(rsa->mont_n); + BN_MONT_CTX_free(rsa->mont_p); + BN_MONT_CTX_free(rsa->mont_q); + BN_free(rsa->d_fixed); + BN_free(rsa->dmp1_fixed); + BN_free(rsa->dmq1_fixed); + BN_free(rsa->inv_small_mod_large_mont); + for (u = 0; u < rsa->num_blindings; u++) { + BN_BLINDING_free(rsa->blindings[u]); + } + OPENSSL_free(rsa->blindings); + OPENSSL_free(rsa->blindings_inuse); + CRYPTO_MUTEX_cleanup(&rsa->lock); + OPENSSL_free(rsa); +} + +int RSA_up_ref(RSA *rsa) { + CRYPTO_refcount_inc(&rsa->references); + return 1; +} + +unsigned RSA_bits(const RSA *rsa) { return BN_num_bits(rsa->n); } + +void RSA_get0_key(const RSA *rsa, const BIGNUM **out_n, const BIGNUM **out_e, + const BIGNUM **out_d) { + if (out_n != NULL) { + *out_n = rsa->n; + } + if (out_e != NULL) { + *out_e = rsa->e; + } + if (out_d != NULL) { + *out_d = rsa->d; + } +} + +void RSA_get0_factors(const RSA *rsa, const BIGNUM **out_p, + const BIGNUM **out_q) { + if (out_p != NULL) { + *out_p = rsa->p; + } + if (out_q != NULL) { + *out_q = rsa->q; + } +} + +void RSA_get0_crt_params(const RSA *rsa, const BIGNUM **out_dmp1, + const BIGNUM **out_dmq1, const BIGNUM **out_iqmp) { + if (out_dmp1 != NULL) { + *out_dmp1 = rsa->dmp1; + } + if (out_dmq1 != NULL) { + *out_dmq1 = rsa->dmq1; + } + if (out_iqmp != NULL) { + *out_iqmp = rsa->iqmp; + } +} + +int RSA_set0_key(RSA *rsa, BIGNUM *n, BIGNUM *e, BIGNUM *d) { + if ((rsa->n == NULL && n == NULL) || + (rsa->e == NULL && e == NULL)) { + return 0; + } + + if (n != NULL) { + BN_free(rsa->n); + rsa->n = n; + } + if (e != NULL) { + BN_free(rsa->e); + rsa->e = e; + } + if (d != NULL) { + BN_free(rsa->d); + rsa->d = d; + } + + return 1; +} + +int RSA_set0_factors(RSA *rsa, BIGNUM *p, BIGNUM *q) { + if ((rsa->p == NULL && p == NULL) || + (rsa->q == NULL && q == NULL)) { + return 0; + } + + if (p != NULL) { + BN_free(rsa->p); + rsa->p = p; + } + if (q != NULL) { + BN_free(rsa->q); + rsa->q = q; + } + + return 1; +} + +int RSA_set0_crt_params(RSA *rsa, BIGNUM *dmp1, BIGNUM *dmq1, BIGNUM *iqmp) { + if ((rsa->dmp1 == NULL && dmp1 == NULL) || + (rsa->dmq1 == NULL && dmq1 == NULL) || + (rsa->iqmp == NULL && iqmp == NULL)) { + return 0; + } + + if (dmp1 != NULL) { + BN_free(rsa->dmp1); + rsa->dmp1 = dmp1; + } + if (dmq1 != NULL) { + BN_free(rsa->dmq1); + rsa->dmq1 = dmq1; + } + if (iqmp != NULL) { + BN_free(rsa->iqmp); + rsa->iqmp = iqmp; + } + + return 1; +} + +int RSA_public_encrypt(size_t flen, const uint8_t *from, uint8_t *to, RSA *rsa, + int padding) { + size_t out_len; + + if (!RSA_encrypt(rsa, &out_len, to, RSA_size(rsa), from, flen, padding)) { + return -1; + } + + if (out_len > INT_MAX) { + OPENSSL_PUT_ERROR(RSA, ERR_R_OVERFLOW); + return -1; + } + return out_len; +} + +int RSA_sign_raw(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out, + const uint8_t *in, size_t in_len, int padding) { + if (rsa->meth->sign_raw) { + return rsa->meth->sign_raw(rsa, out_len, out, max_out, in, in_len, padding); + } + + return rsa_default_sign_raw(rsa, out_len, out, max_out, in, in_len, padding); +} + +int RSA_private_encrypt(size_t flen, const uint8_t *from, uint8_t *to, RSA *rsa, + int padding) { + size_t out_len; + + if (!RSA_sign_raw(rsa, &out_len, to, RSA_size(rsa), from, flen, padding)) { + return -1; + } + + if (out_len > INT_MAX) { + OPENSSL_PUT_ERROR(RSA, ERR_R_OVERFLOW); + return -1; + } + return out_len; +} + +int RSA_decrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out, + const uint8_t *in, size_t in_len, int padding) { + if (rsa->meth->decrypt) { + return rsa->meth->decrypt(rsa, out_len, out, max_out, in, in_len, padding); + } + + return rsa_default_decrypt(rsa, out_len, out, max_out, in, in_len, padding); +} + +int RSA_private_decrypt(size_t flen, const uint8_t *from, uint8_t *to, RSA *rsa, + int padding) { + size_t out_len; + + if (!RSA_decrypt(rsa, &out_len, to, RSA_size(rsa), from, flen, padding)) { + return -1; + } + + if (out_len > INT_MAX) { + OPENSSL_PUT_ERROR(RSA, ERR_R_OVERFLOW); + return -1; + } + return out_len; +} + +int RSA_public_decrypt(size_t flen, const uint8_t *from, uint8_t *to, RSA *rsa, + int padding) { + size_t out_len; + + if (!RSA_verify_raw(rsa, &out_len, to, RSA_size(rsa), from, flen, padding)) { + return -1; + } + + if (out_len > INT_MAX) { + OPENSSL_PUT_ERROR(RSA, ERR_R_OVERFLOW); + return -1; + } + return out_len; +} + +unsigned RSA_size(const RSA *rsa) { + if (rsa->meth->size) { + return rsa->meth->size(rsa); + } + + return rsa_default_size(rsa); +} + +int RSA_is_opaque(const RSA *rsa) { + return rsa->meth && (rsa->meth->flags & RSA_FLAG_OPAQUE); +} + +int RSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused *unused, + CRYPTO_EX_dup *dup_unused, CRYPTO_EX_free *free_func) { + int index; + if (!CRYPTO_get_ex_new_index(g_rsa_ex_data_class_bss_get(), &index, argl, + argp, free_func)) { + return -1; + } + return index; +} + +int RSA_set_ex_data(RSA *rsa, int idx, void *arg) { + return CRYPTO_set_ex_data(&rsa->ex_data, idx, arg); +} + +void *RSA_get_ex_data(const RSA *rsa, int idx) { + return CRYPTO_get_ex_data(&rsa->ex_data, idx); +} + +// SSL_SIG_LENGTH is the size of an SSL/TLS (prior to TLS 1.2) signature: it's +// the length of an MD5 and SHA1 hash. +static const unsigned SSL_SIG_LENGTH = 36; + +// pkcs1_sig_prefix contains the ASN.1, DER encoded prefix for a hash that is +// to be signed with PKCS#1. +struct pkcs1_sig_prefix { + // nid identifies the hash function. + int nid; + // hash_len is the expected length of the hash function. + uint8_t hash_len; + // len is the number of bytes of |bytes| which are valid. + uint8_t len; + // bytes contains the DER bytes. + uint8_t bytes[19]; +}; + +// kPKCS1SigPrefixes contains the ASN.1 prefixes for PKCS#1 signatures with +// different hash functions. +static const struct pkcs1_sig_prefix kPKCS1SigPrefixes[] = { + { + NID_md5, + MD5_DIGEST_LENGTH, + 18, + {0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, + 0x02, 0x05, 0x05, 0x00, 0x04, 0x10}, + }, + { + NID_sha1, + SHA_DIGEST_LENGTH, + 15, + {0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, + 0x00, 0x04, 0x14}, + }, + { + NID_sha224, + SHA224_DIGEST_LENGTH, + 19, + {0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, + 0x04, 0x02, 0x04, 0x05, 0x00, 0x04, 0x1c}, + }, + { + NID_sha256, + SHA256_DIGEST_LENGTH, + 19, + {0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, + 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20}, + }, + { + NID_sha384, + SHA384_DIGEST_LENGTH, + 19, + {0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, + 0x04, 0x02, 0x02, 0x05, 0x00, 0x04, 0x30}, + }, + { + NID_sha512, + SHA512_DIGEST_LENGTH, + 19, + {0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, + 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40}, + }, + { + NID_undef, 0, 0, {0}, + }, +}; + +int RSA_add_pkcs1_prefix(uint8_t **out_msg, size_t *out_msg_len, + int *is_alloced, int hash_nid, const uint8_t *msg, + size_t msg_len) { + unsigned i; + + if (hash_nid == NID_md5_sha1) { + // Special case: SSL signature, just check the length. + if (msg_len != SSL_SIG_LENGTH) { + OPENSSL_PUT_ERROR(RSA, RSA_R_INVALID_MESSAGE_LENGTH); + return 0; + } + + *out_msg = (uint8_t*) msg; + *out_msg_len = SSL_SIG_LENGTH; + *is_alloced = 0; + return 1; + } + + for (i = 0; kPKCS1SigPrefixes[i].nid != NID_undef; i++) { + const struct pkcs1_sig_prefix *sig_prefix = &kPKCS1SigPrefixes[i]; + if (sig_prefix->nid != hash_nid) { + continue; + } + + if (msg_len != sig_prefix->hash_len) { + OPENSSL_PUT_ERROR(RSA, RSA_R_INVALID_MESSAGE_LENGTH); + return 0; + } + + const uint8_t* prefix = sig_prefix->bytes; + unsigned prefix_len = sig_prefix->len; + unsigned signed_msg_len; + uint8_t *signed_msg; + + signed_msg_len = prefix_len + msg_len; + if (signed_msg_len < prefix_len) { + OPENSSL_PUT_ERROR(RSA, RSA_R_TOO_LONG); + return 0; + } + + signed_msg = OPENSSL_malloc(signed_msg_len); + if (!signed_msg) { + OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); + return 0; + } + + OPENSSL_memcpy(signed_msg, prefix, prefix_len); + OPENSSL_memcpy(signed_msg + prefix_len, msg, msg_len); + + *out_msg = signed_msg; + *out_msg_len = signed_msg_len; + *is_alloced = 1; + + return 1; + } + + OPENSSL_PUT_ERROR(RSA, RSA_R_UNKNOWN_ALGORITHM_TYPE); + return 0; +} + +int RSA_sign(int hash_nid, const uint8_t *in, unsigned in_len, uint8_t *out, + unsigned *out_len, RSA *rsa) { + const unsigned rsa_size = RSA_size(rsa); + int ret = 0; + uint8_t *signed_msg = NULL; + size_t signed_msg_len = 0; + int signed_msg_is_alloced = 0; + size_t size_t_out_len; + + if (rsa->meth->sign) { + return rsa->meth->sign(hash_nid, in, in_len, out, out_len, rsa); + } + + if (!RSA_add_pkcs1_prefix(&signed_msg, &signed_msg_len, + &signed_msg_is_alloced, hash_nid, in, in_len) || + !RSA_sign_raw(rsa, &size_t_out_len, out, rsa_size, signed_msg, + signed_msg_len, RSA_PKCS1_PADDING)) { + goto err; + } + + *out_len = size_t_out_len; + ret = 1; + +err: + if (signed_msg_is_alloced) { + OPENSSL_free(signed_msg); + } + return ret; +} + +int RSA_sign_pss_mgf1(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out, + const uint8_t *in, size_t in_len, const EVP_MD *md, + const EVP_MD *mgf1_md, int salt_len) { + if (in_len != EVP_MD_size(md)) { + OPENSSL_PUT_ERROR(RSA, RSA_R_INVALID_MESSAGE_LENGTH); + return 0; + } + + size_t padded_len = RSA_size(rsa); + uint8_t *padded = OPENSSL_malloc(padded_len); + if (padded == NULL) { + OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); + return 0; + } + + int ret = + RSA_padding_add_PKCS1_PSS_mgf1(rsa, padded, in, md, mgf1_md, salt_len) && + RSA_sign_raw(rsa, out_len, out, max_out, padded, padded_len, + RSA_NO_PADDING); + OPENSSL_free(padded); + return ret; +} + +int RSA_verify(int hash_nid, const uint8_t *msg, size_t msg_len, + const uint8_t *sig, size_t sig_len, RSA *rsa) { + if (rsa->n == NULL || rsa->e == NULL) { + OPENSSL_PUT_ERROR(RSA, RSA_R_VALUE_MISSING); + return 0; + } + + const size_t rsa_size = RSA_size(rsa); + uint8_t *buf = NULL; + int ret = 0; + uint8_t *signed_msg = NULL; + size_t signed_msg_len = 0, len; + int signed_msg_is_alloced = 0; + + if (hash_nid == NID_md5_sha1 && msg_len != SSL_SIG_LENGTH) { + OPENSSL_PUT_ERROR(RSA, RSA_R_INVALID_MESSAGE_LENGTH); + return 0; + } + + buf = OPENSSL_malloc(rsa_size); + if (!buf) { + OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); + return 0; + } + + if (!RSA_verify_raw(rsa, &len, buf, rsa_size, sig, sig_len, + RSA_PKCS1_PADDING)) { + goto out; + } + + if (!RSA_add_pkcs1_prefix(&signed_msg, &signed_msg_len, + &signed_msg_is_alloced, hash_nid, msg, msg_len)) { + goto out; + } + + // Check that no other information follows the hash value (FIPS 186-4 Section + // 5.5) and it matches the expected hash. + if (len != signed_msg_len || OPENSSL_memcmp(buf, signed_msg, len) != 0) { + OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_SIGNATURE); + goto out; + } + + ret = 1; + +out: + OPENSSL_free(buf); + if (signed_msg_is_alloced) { + OPENSSL_free(signed_msg); + } + return ret; +} + +int RSA_verify_pss_mgf1(RSA *rsa, const uint8_t *msg, size_t msg_len, + const EVP_MD *md, const EVP_MD *mgf1_md, int salt_len, + const uint8_t *sig, size_t sig_len) { + if (msg_len != EVP_MD_size(md)) { + OPENSSL_PUT_ERROR(RSA, RSA_R_INVALID_MESSAGE_LENGTH); + return 0; + } + + size_t em_len = RSA_size(rsa); + uint8_t *em = OPENSSL_malloc(em_len); + if (em == NULL) { + OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); + return 0; + } + + int ret = 0; + if (!RSA_verify_raw(rsa, &em_len, em, em_len, sig, sig_len, RSA_NO_PADDING)) { + goto err; + } + + if (em_len != RSA_size(rsa)) { + OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR); + goto err; + } + + ret = RSA_verify_PKCS1_PSS_mgf1(rsa, msg, md, mgf1_md, em, salt_len); + +err: + OPENSSL_free(em); + return ret; +} + +static int check_mod_inverse(int *out_ok, const BIGNUM *a, const BIGNUM *ainv, + const BIGNUM *m, int check_reduced, BN_CTX *ctx) { + BN_CTX_start(ctx); + BIGNUM *tmp = BN_CTX_get(ctx); + int ret = tmp != NULL && + bn_mul_consttime(tmp, a, ainv, ctx) && + bn_div_consttime(NULL, tmp, tmp, m, ctx); + if (ret) { + *out_ok = BN_is_one(tmp); + if (check_reduced && (BN_is_negative(ainv) || BN_cmp(ainv, m) >= 0)) { + *out_ok = 0; + } + } + BN_CTX_end(ctx); + return ret; +} + +int RSA_check_key(const RSA *key) { + BIGNUM n, pm1, qm1, lcm, dmp1, dmq1, iqmp_times_q; + BN_CTX *ctx; + int ok = 0, has_crt_values; + + if (RSA_is_opaque(key)) { + // Opaque keys can't be checked. + return 1; + } + + if ((key->p != NULL) != (key->q != NULL)) { + OPENSSL_PUT_ERROR(RSA, RSA_R_ONLY_ONE_OF_P_Q_GIVEN); + return 0; + } + + if (!key->n || !key->e) { + OPENSSL_PUT_ERROR(RSA, RSA_R_VALUE_MISSING); + return 0; + } + + if (!key->d || !key->p) { + // For a public key, or without p and q, there's nothing that can be + // checked. + return 1; + } + + ctx = BN_CTX_new(); + if (ctx == NULL) { + OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); + return 0; + } + + BN_init(&n); + BN_init(&pm1); + BN_init(&qm1); + BN_init(&lcm); + BN_init(&dmp1); + BN_init(&dmq1); + BN_init(&iqmp_times_q); + + int d_ok; + if (!bn_mul_consttime(&n, key->p, key->q, ctx) || + // lcm = lcm(p, q) + !bn_usub_consttime(&pm1, key->p, BN_value_one()) || + !bn_usub_consttime(&qm1, key->q, BN_value_one()) || + !bn_lcm_consttime(&lcm, &pm1, &qm1, ctx) || + // Other implementations use the Euler totient rather than the Carmichael + // totient, so allow unreduced |key->d|. + !check_mod_inverse(&d_ok, key->e, key->d, &lcm, + 0 /* don't require reduced */, ctx)) { + OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN); + goto out; + } + + if (BN_cmp(&n, key->n) != 0) { + OPENSSL_PUT_ERROR(RSA, RSA_R_N_NOT_EQUAL_P_Q); + goto out; + } + + if (!d_ok) { + OPENSSL_PUT_ERROR(RSA, RSA_R_D_E_NOT_CONGRUENT_TO_1); + goto out; + } + + if (BN_is_negative(key->d) || BN_cmp(key->d, key->n) >= 0) { + OPENSSL_PUT_ERROR(RSA, RSA_R_D_OUT_OF_RANGE); + goto out; + } + + has_crt_values = key->dmp1 != NULL; + if (has_crt_values != (key->dmq1 != NULL) || + has_crt_values != (key->iqmp != NULL)) { + OPENSSL_PUT_ERROR(RSA, RSA_R_INCONSISTENT_SET_OF_CRT_VALUES); + goto out; + } + + if (has_crt_values) { + int dmp1_ok, dmq1_ok, iqmp_ok; + if (!check_mod_inverse(&dmp1_ok, key->e, key->dmp1, &pm1, + 1 /* check reduced */, ctx) || + !check_mod_inverse(&dmq1_ok, key->e, key->dmq1, &qm1, + 1 /* check reduced */, ctx) || + !check_mod_inverse(&iqmp_ok, key->q, key->iqmp, key->p, + 1 /* check reduced */, ctx)) { + OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN); + goto out; + } + + if (!dmp1_ok || !dmq1_ok || !iqmp_ok) { + OPENSSL_PUT_ERROR(RSA, RSA_R_CRT_VALUES_INCORRECT); + goto out; + } + } + + ok = 1; + +out: + BN_free(&n); + BN_free(&pm1); + BN_free(&qm1); + BN_free(&lcm); + BN_free(&dmp1); + BN_free(&dmq1); + BN_free(&iqmp_times_q); + BN_CTX_free(ctx); + + return ok; +} + + +// This is the product of the 132 smallest odd primes, from 3 to 751. +static const BN_ULONG kSmallFactorsLimbs[] = { + TOBN(0xc4309333, 0x3ef4e3e1), TOBN(0x71161eb6, 0xcd2d655f), + TOBN(0x95e2238c, 0x0bf94862), TOBN(0x3eb233d3, 0x24f7912b), + TOBN(0x6b55514b, 0xbf26c483), TOBN(0x0a84d817, 0x5a144871), + TOBN(0x77d12fee, 0x9b82210a), TOBN(0xdb5b93c2, 0x97f050b3), + TOBN(0x4acad6b9, 0x4d6c026b), TOBN(0xeb7751f3, 0x54aec893), + TOBN(0xdba53368, 0x36bc85c4), TOBN(0xd85a1b28, 0x7f5ec78e), + TOBN(0x2eb072d8, 0x6b322244), TOBN(0xbba51112, 0x5e2b3aea), + TOBN(0x36ed1a6c, 0x0e2486bf), TOBN(0x5f270460, 0xec0c5727), + 0x000017b1 +}; + +DEFINE_LOCAL_DATA(BIGNUM, g_small_factors) { + out->d = (BN_ULONG *) kSmallFactorsLimbs; + out->width = OPENSSL_ARRAY_SIZE(kSmallFactorsLimbs); + out->dmax = out->width; + out->neg = 0; + out->flags = BN_FLG_STATIC_DATA; +} + +int RSA_check_fips(RSA *key) { + if (RSA_is_opaque(key)) { + // Opaque keys can't be checked. + OPENSSL_PUT_ERROR(RSA, RSA_R_PUBLIC_KEY_VALIDATION_FAILED); + return 0; + } + + if (!RSA_check_key(key)) { + return 0; + } + + BN_CTX *ctx = BN_CTX_new(); + if (ctx == NULL) { + OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); + return 0; + } + + BIGNUM small_gcd; + BN_init(&small_gcd); + + int ret = 1; + + // Perform partial public key validation of RSA keys (SP 800-89 5.3.3). + enum bn_primality_result_t primality_result; + if (BN_num_bits(key->e) <= 16 || + BN_num_bits(key->e) > 256 || + !BN_is_odd(key->n) || + !BN_is_odd(key->e) || + !BN_gcd(&small_gcd, key->n, g_small_factors(), ctx) || + !BN_is_one(&small_gcd) || + !BN_enhanced_miller_rabin_primality_test(&primality_result, key->n, + BN_prime_checks, ctx, NULL) || + primality_result != bn_non_prime_power_composite) { + OPENSSL_PUT_ERROR(RSA, RSA_R_PUBLIC_KEY_VALIDATION_FAILED); + ret = 0; + } + + BN_free(&small_gcd); + BN_CTX_free(ctx); + + if (!ret || key->d == NULL || key->p == NULL) { + // On a failure or on only a public key, there's nothing else can be + // checked. + return ret; + } + + // FIPS pairwise consistency test (FIPS 140-2 4.9.2). Per FIPS 140-2 IG, + // section 9.9, it is not known whether |rsa| will be used for signing or + // encryption, so either pair-wise consistency self-test is acceptable. We + // perform a signing test. + uint8_t data[32] = {0}; + unsigned sig_len = RSA_size(key); + uint8_t *sig = OPENSSL_malloc(sig_len); + if (sig == NULL) { + OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); + return 0; + } + + if (!RSA_sign(NID_sha256, data, sizeof(data), sig, &sig_len, key)) { + OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR); + ret = 0; + goto cleanup; + } +#if defined(BORINGSSL_FIPS_BREAK_RSA_PWCT) + data[0] = ~data[0]; +#endif + if (!RSA_verify(NID_sha256, data, sizeof(data), sig, sig_len, key)) { + OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR); + ret = 0; + } + +cleanup: + OPENSSL_free(sig); + + return ret; +} + +int RSA_private_transform(RSA *rsa, uint8_t *out, const uint8_t *in, + size_t len) { + if (rsa->meth->private_transform) { + return rsa->meth->private_transform(rsa, out, in, len); + } + + return rsa_default_private_transform(rsa, out, in, len); +} + +int RSA_flags(const RSA *rsa) { return rsa->flags; } + +int RSA_blinding_on(RSA *rsa, BN_CTX *ctx) { + return 1; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/rsa/rsa.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/rsa/rsa.c.grpc_back new file mode 100644 index 0000000..aed87a6 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/rsa/rsa.c.grpc_back @@ -0,0 +1,875 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../bn/internal.h" +#include "../delocate.h" +#include "../../internal.h" +#include "internal.h" + + +DEFINE_STATIC_EX_DATA_CLASS(g_rsa_ex_data_class); + +RSA *RSA_new(void) { return RSA_new_method(NULL); } + +RSA *RSA_new_method(const ENGINE *engine) { + RSA *rsa = OPENSSL_malloc(sizeof(RSA)); + if (rsa == NULL) { + OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); + return NULL; + } + + OPENSSL_memset(rsa, 0, sizeof(RSA)); + + if (engine) { + rsa->meth = ENGINE_get_RSA_method(engine); + } + + if (rsa->meth == NULL) { + rsa->meth = (RSA_METHOD *) RSA_default_method(); + } + METHOD_ref(rsa->meth); + + rsa->references = 1; + rsa->flags = rsa->meth->flags; + CRYPTO_MUTEX_init(&rsa->lock); + CRYPTO_new_ex_data(&rsa->ex_data); + + if (rsa->meth->init && !rsa->meth->init(rsa)) { + CRYPTO_free_ex_data(g_rsa_ex_data_class_bss_get(), rsa, &rsa->ex_data); + CRYPTO_MUTEX_cleanup(&rsa->lock); + METHOD_unref(rsa->meth); + OPENSSL_free(rsa); + return NULL; + } + + return rsa; +} + +void RSA_free(RSA *rsa) { + unsigned u; + + if (rsa == NULL) { + return; + } + + if (!CRYPTO_refcount_dec_and_test_zero(&rsa->references)) { + return; + } + + if (rsa->meth->finish) { + rsa->meth->finish(rsa); + } + METHOD_unref(rsa->meth); + + CRYPTO_free_ex_data(g_rsa_ex_data_class_bss_get(), rsa, &rsa->ex_data); + + BN_free(rsa->n); + BN_free(rsa->e); + BN_free(rsa->d); + BN_free(rsa->p); + BN_free(rsa->q); + BN_free(rsa->dmp1); + BN_free(rsa->dmq1); + BN_free(rsa->iqmp); + BN_MONT_CTX_free(rsa->mont_n); + BN_MONT_CTX_free(rsa->mont_p); + BN_MONT_CTX_free(rsa->mont_q); + BN_free(rsa->d_fixed); + BN_free(rsa->dmp1_fixed); + BN_free(rsa->dmq1_fixed); + BN_free(rsa->inv_small_mod_large_mont); + for (u = 0; u < rsa->num_blindings; u++) { + BN_BLINDING_free(rsa->blindings[u]); + } + OPENSSL_free(rsa->blindings); + OPENSSL_free(rsa->blindings_inuse); + CRYPTO_MUTEX_cleanup(&rsa->lock); + OPENSSL_free(rsa); +} + +int RSA_up_ref(RSA *rsa) { + CRYPTO_refcount_inc(&rsa->references); + return 1; +} + +unsigned RSA_bits(const RSA *rsa) { return BN_num_bits(rsa->n); } + +void RSA_get0_key(const RSA *rsa, const BIGNUM **out_n, const BIGNUM **out_e, + const BIGNUM **out_d) { + if (out_n != NULL) { + *out_n = rsa->n; + } + if (out_e != NULL) { + *out_e = rsa->e; + } + if (out_d != NULL) { + *out_d = rsa->d; + } +} + +void RSA_get0_factors(const RSA *rsa, const BIGNUM **out_p, + const BIGNUM **out_q) { + if (out_p != NULL) { + *out_p = rsa->p; + } + if (out_q != NULL) { + *out_q = rsa->q; + } +} + +void RSA_get0_crt_params(const RSA *rsa, const BIGNUM **out_dmp1, + const BIGNUM **out_dmq1, const BIGNUM **out_iqmp) { + if (out_dmp1 != NULL) { + *out_dmp1 = rsa->dmp1; + } + if (out_dmq1 != NULL) { + *out_dmq1 = rsa->dmq1; + } + if (out_iqmp != NULL) { + *out_iqmp = rsa->iqmp; + } +} + +int RSA_set0_key(RSA *rsa, BIGNUM *n, BIGNUM *e, BIGNUM *d) { + if ((rsa->n == NULL && n == NULL) || + (rsa->e == NULL && e == NULL)) { + return 0; + } + + if (n != NULL) { + BN_free(rsa->n); + rsa->n = n; + } + if (e != NULL) { + BN_free(rsa->e); + rsa->e = e; + } + if (d != NULL) { + BN_free(rsa->d); + rsa->d = d; + } + + return 1; +} + +int RSA_set0_factors(RSA *rsa, BIGNUM *p, BIGNUM *q) { + if ((rsa->p == NULL && p == NULL) || + (rsa->q == NULL && q == NULL)) { + return 0; + } + + if (p != NULL) { + BN_free(rsa->p); + rsa->p = p; + } + if (q != NULL) { + BN_free(rsa->q); + rsa->q = q; + } + + return 1; +} + +int RSA_set0_crt_params(RSA *rsa, BIGNUM *dmp1, BIGNUM *dmq1, BIGNUM *iqmp) { + if ((rsa->dmp1 == NULL && dmp1 == NULL) || + (rsa->dmq1 == NULL && dmq1 == NULL) || + (rsa->iqmp == NULL && iqmp == NULL)) { + return 0; + } + + if (dmp1 != NULL) { + BN_free(rsa->dmp1); + rsa->dmp1 = dmp1; + } + if (dmq1 != NULL) { + BN_free(rsa->dmq1); + rsa->dmq1 = dmq1; + } + if (iqmp != NULL) { + BN_free(rsa->iqmp); + rsa->iqmp = iqmp; + } + + return 1; +} + +int RSA_public_encrypt(size_t flen, const uint8_t *from, uint8_t *to, RSA *rsa, + int padding) { + size_t out_len; + + if (!RSA_encrypt(rsa, &out_len, to, RSA_size(rsa), from, flen, padding)) { + return -1; + } + + if (out_len > INT_MAX) { + OPENSSL_PUT_ERROR(RSA, ERR_R_OVERFLOW); + return -1; + } + return out_len; +} + +int RSA_sign_raw(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out, + const uint8_t *in, size_t in_len, int padding) { + if (rsa->meth->sign_raw) { + return rsa->meth->sign_raw(rsa, out_len, out, max_out, in, in_len, padding); + } + + return rsa_default_sign_raw(rsa, out_len, out, max_out, in, in_len, padding); +} + +int RSA_private_encrypt(size_t flen, const uint8_t *from, uint8_t *to, RSA *rsa, + int padding) { + size_t out_len; + + if (!RSA_sign_raw(rsa, &out_len, to, RSA_size(rsa), from, flen, padding)) { + return -1; + } + + if (out_len > INT_MAX) { + OPENSSL_PUT_ERROR(RSA, ERR_R_OVERFLOW); + return -1; + } + return out_len; +} + +int RSA_decrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out, + const uint8_t *in, size_t in_len, int padding) { + if (rsa->meth->decrypt) { + return rsa->meth->decrypt(rsa, out_len, out, max_out, in, in_len, padding); + } + + return rsa_default_decrypt(rsa, out_len, out, max_out, in, in_len, padding); +} + +int RSA_private_decrypt(size_t flen, const uint8_t *from, uint8_t *to, RSA *rsa, + int padding) { + size_t out_len; + + if (!RSA_decrypt(rsa, &out_len, to, RSA_size(rsa), from, flen, padding)) { + return -1; + } + + if (out_len > INT_MAX) { + OPENSSL_PUT_ERROR(RSA, ERR_R_OVERFLOW); + return -1; + } + return out_len; +} + +int RSA_public_decrypt(size_t flen, const uint8_t *from, uint8_t *to, RSA *rsa, + int padding) { + size_t out_len; + + if (!RSA_verify_raw(rsa, &out_len, to, RSA_size(rsa), from, flen, padding)) { + return -1; + } + + if (out_len > INT_MAX) { + OPENSSL_PUT_ERROR(RSA, ERR_R_OVERFLOW); + return -1; + } + return out_len; +} + +unsigned RSA_size(const RSA *rsa) { + if (rsa->meth->size) { + return rsa->meth->size(rsa); + } + + return rsa_default_size(rsa); +} + +int RSA_is_opaque(const RSA *rsa) { + return rsa->meth && (rsa->meth->flags & RSA_FLAG_OPAQUE); +} + +int RSA_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused *unused, + CRYPTO_EX_dup *dup_unused, CRYPTO_EX_free *free_func) { + int index; + if (!CRYPTO_get_ex_new_index(g_rsa_ex_data_class_bss_get(), &index, argl, + argp, free_func)) { + return -1; + } + return index; +} + +int RSA_set_ex_data(RSA *rsa, int idx, void *arg) { + return CRYPTO_set_ex_data(&rsa->ex_data, idx, arg); +} + +void *RSA_get_ex_data(const RSA *rsa, int idx) { + return CRYPTO_get_ex_data(&rsa->ex_data, idx); +} + +// SSL_SIG_LENGTH is the size of an SSL/TLS (prior to TLS 1.2) signature: it's +// the length of an MD5 and SHA1 hash. +static const unsigned SSL_SIG_LENGTH = 36; + +// pkcs1_sig_prefix contains the ASN.1, DER encoded prefix for a hash that is +// to be signed with PKCS#1. +struct pkcs1_sig_prefix { + // nid identifies the hash function. + int nid; + // hash_len is the expected length of the hash function. + uint8_t hash_len; + // len is the number of bytes of |bytes| which are valid. + uint8_t len; + // bytes contains the DER bytes. + uint8_t bytes[19]; +}; + +// kPKCS1SigPrefixes contains the ASN.1 prefixes for PKCS#1 signatures with +// different hash functions. +static const struct pkcs1_sig_prefix kPKCS1SigPrefixes[] = { + { + NID_md5, + MD5_DIGEST_LENGTH, + 18, + {0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, + 0x02, 0x05, 0x05, 0x00, 0x04, 0x10}, + }, + { + NID_sha1, + SHA_DIGEST_LENGTH, + 15, + {0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, + 0x00, 0x04, 0x14}, + }, + { + NID_sha224, + SHA224_DIGEST_LENGTH, + 19, + {0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, + 0x04, 0x02, 0x04, 0x05, 0x00, 0x04, 0x1c}, + }, + { + NID_sha256, + SHA256_DIGEST_LENGTH, + 19, + {0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, + 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20}, + }, + { + NID_sha384, + SHA384_DIGEST_LENGTH, + 19, + {0x30, 0x41, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, + 0x04, 0x02, 0x02, 0x05, 0x00, 0x04, 0x30}, + }, + { + NID_sha512, + SHA512_DIGEST_LENGTH, + 19, + {0x30, 0x51, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, + 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40}, + }, + { + NID_undef, 0, 0, {0}, + }, +}; + +int RSA_add_pkcs1_prefix(uint8_t **out_msg, size_t *out_msg_len, + int *is_alloced, int hash_nid, const uint8_t *msg, + size_t msg_len) { + unsigned i; + + if (hash_nid == NID_md5_sha1) { + // Special case: SSL signature, just check the length. + if (msg_len != SSL_SIG_LENGTH) { + OPENSSL_PUT_ERROR(RSA, RSA_R_INVALID_MESSAGE_LENGTH); + return 0; + } + + *out_msg = (uint8_t*) msg; + *out_msg_len = SSL_SIG_LENGTH; + *is_alloced = 0; + return 1; + } + + for (i = 0; kPKCS1SigPrefixes[i].nid != NID_undef; i++) { + const struct pkcs1_sig_prefix *sig_prefix = &kPKCS1SigPrefixes[i]; + if (sig_prefix->nid != hash_nid) { + continue; + } + + if (msg_len != sig_prefix->hash_len) { + OPENSSL_PUT_ERROR(RSA, RSA_R_INVALID_MESSAGE_LENGTH); + return 0; + } + + const uint8_t* prefix = sig_prefix->bytes; + unsigned prefix_len = sig_prefix->len; + unsigned signed_msg_len; + uint8_t *signed_msg; + + signed_msg_len = prefix_len + msg_len; + if (signed_msg_len < prefix_len) { + OPENSSL_PUT_ERROR(RSA, RSA_R_TOO_LONG); + return 0; + } + + signed_msg = OPENSSL_malloc(signed_msg_len); + if (!signed_msg) { + OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); + return 0; + } + + OPENSSL_memcpy(signed_msg, prefix, prefix_len); + OPENSSL_memcpy(signed_msg + prefix_len, msg, msg_len); + + *out_msg = signed_msg; + *out_msg_len = signed_msg_len; + *is_alloced = 1; + + return 1; + } + + OPENSSL_PUT_ERROR(RSA, RSA_R_UNKNOWN_ALGORITHM_TYPE); + return 0; +} + +int RSA_sign(int hash_nid, const uint8_t *in, unsigned in_len, uint8_t *out, + unsigned *out_len, RSA *rsa) { + const unsigned rsa_size = RSA_size(rsa); + int ret = 0; + uint8_t *signed_msg = NULL; + size_t signed_msg_len = 0; + int signed_msg_is_alloced = 0; + size_t size_t_out_len; + + if (rsa->meth->sign) { + return rsa->meth->sign(hash_nid, in, in_len, out, out_len, rsa); + } + + if (!RSA_add_pkcs1_prefix(&signed_msg, &signed_msg_len, + &signed_msg_is_alloced, hash_nid, in, in_len) || + !RSA_sign_raw(rsa, &size_t_out_len, out, rsa_size, signed_msg, + signed_msg_len, RSA_PKCS1_PADDING)) { + goto err; + } + + *out_len = size_t_out_len; + ret = 1; + +err: + if (signed_msg_is_alloced) { + OPENSSL_free(signed_msg); + } + return ret; +} + +int RSA_sign_pss_mgf1(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out, + const uint8_t *in, size_t in_len, const EVP_MD *md, + const EVP_MD *mgf1_md, int salt_len) { + if (in_len != EVP_MD_size(md)) { + OPENSSL_PUT_ERROR(RSA, RSA_R_INVALID_MESSAGE_LENGTH); + return 0; + } + + size_t padded_len = RSA_size(rsa); + uint8_t *padded = OPENSSL_malloc(padded_len); + if (padded == NULL) { + OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); + return 0; + } + + int ret = + RSA_padding_add_PKCS1_PSS_mgf1(rsa, padded, in, md, mgf1_md, salt_len) && + RSA_sign_raw(rsa, out_len, out, max_out, padded, padded_len, + RSA_NO_PADDING); + OPENSSL_free(padded); + return ret; +} + +int RSA_verify(int hash_nid, const uint8_t *msg, size_t msg_len, + const uint8_t *sig, size_t sig_len, RSA *rsa) { + if (rsa->n == NULL || rsa->e == NULL) { + OPENSSL_PUT_ERROR(RSA, RSA_R_VALUE_MISSING); + return 0; + } + + const size_t rsa_size = RSA_size(rsa); + uint8_t *buf = NULL; + int ret = 0; + uint8_t *signed_msg = NULL; + size_t signed_msg_len = 0, len; + int signed_msg_is_alloced = 0; + + if (hash_nid == NID_md5_sha1 && msg_len != SSL_SIG_LENGTH) { + OPENSSL_PUT_ERROR(RSA, RSA_R_INVALID_MESSAGE_LENGTH); + return 0; + } + + buf = OPENSSL_malloc(rsa_size); + if (!buf) { + OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); + return 0; + } + + if (!RSA_verify_raw(rsa, &len, buf, rsa_size, sig, sig_len, + RSA_PKCS1_PADDING)) { + goto out; + } + + if (!RSA_add_pkcs1_prefix(&signed_msg, &signed_msg_len, + &signed_msg_is_alloced, hash_nid, msg, msg_len)) { + goto out; + } + + // Check that no other information follows the hash value (FIPS 186-4 Section + // 5.5) and it matches the expected hash. + if (len != signed_msg_len || OPENSSL_memcmp(buf, signed_msg, len) != 0) { + OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_SIGNATURE); + goto out; + } + + ret = 1; + +out: + OPENSSL_free(buf); + if (signed_msg_is_alloced) { + OPENSSL_free(signed_msg); + } + return ret; +} + +int RSA_verify_pss_mgf1(RSA *rsa, const uint8_t *msg, size_t msg_len, + const EVP_MD *md, const EVP_MD *mgf1_md, int salt_len, + const uint8_t *sig, size_t sig_len) { + if (msg_len != EVP_MD_size(md)) { + OPENSSL_PUT_ERROR(RSA, RSA_R_INVALID_MESSAGE_LENGTH); + return 0; + } + + size_t em_len = RSA_size(rsa); + uint8_t *em = OPENSSL_malloc(em_len); + if (em == NULL) { + OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); + return 0; + } + + int ret = 0; + if (!RSA_verify_raw(rsa, &em_len, em, em_len, sig, sig_len, RSA_NO_PADDING)) { + goto err; + } + + if (em_len != RSA_size(rsa)) { + OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR); + goto err; + } + + ret = RSA_verify_PKCS1_PSS_mgf1(rsa, msg, md, mgf1_md, em, salt_len); + +err: + OPENSSL_free(em); + return ret; +} + +static int check_mod_inverse(int *out_ok, const BIGNUM *a, const BIGNUM *ainv, + const BIGNUM *m, int check_reduced, BN_CTX *ctx) { + BN_CTX_start(ctx); + BIGNUM *tmp = BN_CTX_get(ctx); + int ret = tmp != NULL && + bn_mul_consttime(tmp, a, ainv, ctx) && + bn_div_consttime(NULL, tmp, tmp, m, ctx); + if (ret) { + *out_ok = BN_is_one(tmp); + if (check_reduced && (BN_is_negative(ainv) || BN_cmp(ainv, m) >= 0)) { + *out_ok = 0; + } + } + BN_CTX_end(ctx); + return ret; +} + +int RSA_check_key(const RSA *key) { + BIGNUM n, pm1, qm1, lcm, dmp1, dmq1, iqmp_times_q; + BN_CTX *ctx; + int ok = 0, has_crt_values; + + if (RSA_is_opaque(key)) { + // Opaque keys can't be checked. + return 1; + } + + if ((key->p != NULL) != (key->q != NULL)) { + OPENSSL_PUT_ERROR(RSA, RSA_R_ONLY_ONE_OF_P_Q_GIVEN); + return 0; + } + + if (!key->n || !key->e) { + OPENSSL_PUT_ERROR(RSA, RSA_R_VALUE_MISSING); + return 0; + } + + if (!key->d || !key->p) { + // For a public key, or without p and q, there's nothing that can be + // checked. + return 1; + } + + ctx = BN_CTX_new(); + if (ctx == NULL) { + OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); + return 0; + } + + BN_init(&n); + BN_init(&pm1); + BN_init(&qm1); + BN_init(&lcm); + BN_init(&dmp1); + BN_init(&dmq1); + BN_init(&iqmp_times_q); + + int d_ok; + if (!bn_mul_consttime(&n, key->p, key->q, ctx) || + // lcm = lcm(p, q) + !bn_usub_consttime(&pm1, key->p, BN_value_one()) || + !bn_usub_consttime(&qm1, key->q, BN_value_one()) || + !bn_lcm_consttime(&lcm, &pm1, &qm1, ctx) || + // Other implementations use the Euler totient rather than the Carmichael + // totient, so allow unreduced |key->d|. + !check_mod_inverse(&d_ok, key->e, key->d, &lcm, + 0 /* don't require reduced */, ctx)) { + OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN); + goto out; + } + + if (BN_cmp(&n, key->n) != 0) { + OPENSSL_PUT_ERROR(RSA, RSA_R_N_NOT_EQUAL_P_Q); + goto out; + } + + if (!d_ok) { + OPENSSL_PUT_ERROR(RSA, RSA_R_D_E_NOT_CONGRUENT_TO_1); + goto out; + } + + if (BN_is_negative(key->d) || BN_cmp(key->d, key->n) >= 0) { + OPENSSL_PUT_ERROR(RSA, RSA_R_D_OUT_OF_RANGE); + goto out; + } + + has_crt_values = key->dmp1 != NULL; + if (has_crt_values != (key->dmq1 != NULL) || + has_crt_values != (key->iqmp != NULL)) { + OPENSSL_PUT_ERROR(RSA, RSA_R_INCONSISTENT_SET_OF_CRT_VALUES); + goto out; + } + + if (has_crt_values) { + int dmp1_ok, dmq1_ok, iqmp_ok; + if (!check_mod_inverse(&dmp1_ok, key->e, key->dmp1, &pm1, + 1 /* check reduced */, ctx) || + !check_mod_inverse(&dmq1_ok, key->e, key->dmq1, &qm1, + 1 /* check reduced */, ctx) || + !check_mod_inverse(&iqmp_ok, key->q, key->iqmp, key->p, + 1 /* check reduced */, ctx)) { + OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN); + goto out; + } + + if (!dmp1_ok || !dmq1_ok || !iqmp_ok) { + OPENSSL_PUT_ERROR(RSA, RSA_R_CRT_VALUES_INCORRECT); + goto out; + } + } + + ok = 1; + +out: + BN_free(&n); + BN_free(&pm1); + BN_free(&qm1); + BN_free(&lcm); + BN_free(&dmp1); + BN_free(&dmq1); + BN_free(&iqmp_times_q); + BN_CTX_free(ctx); + + return ok; +} + + +// This is the product of the 132 smallest odd primes, from 3 to 751. +static const BN_ULONG kSmallFactorsLimbs[] = { + TOBN(0xc4309333, 0x3ef4e3e1), TOBN(0x71161eb6, 0xcd2d655f), + TOBN(0x95e2238c, 0x0bf94862), TOBN(0x3eb233d3, 0x24f7912b), + TOBN(0x6b55514b, 0xbf26c483), TOBN(0x0a84d817, 0x5a144871), + TOBN(0x77d12fee, 0x9b82210a), TOBN(0xdb5b93c2, 0x97f050b3), + TOBN(0x4acad6b9, 0x4d6c026b), TOBN(0xeb7751f3, 0x54aec893), + TOBN(0xdba53368, 0x36bc85c4), TOBN(0xd85a1b28, 0x7f5ec78e), + TOBN(0x2eb072d8, 0x6b322244), TOBN(0xbba51112, 0x5e2b3aea), + TOBN(0x36ed1a6c, 0x0e2486bf), TOBN(0x5f270460, 0xec0c5727), + 0x000017b1 +}; + +DEFINE_LOCAL_DATA(BIGNUM, g_small_factors) { + out->d = (BN_ULONG *) kSmallFactorsLimbs; + out->width = OPENSSL_ARRAY_SIZE(kSmallFactorsLimbs); + out->dmax = out->width; + out->neg = 0; + out->flags = BN_FLG_STATIC_DATA; +} + +int RSA_check_fips(RSA *key) { + if (RSA_is_opaque(key)) { + // Opaque keys can't be checked. + OPENSSL_PUT_ERROR(RSA, RSA_R_PUBLIC_KEY_VALIDATION_FAILED); + return 0; + } + + if (!RSA_check_key(key)) { + return 0; + } + + BN_CTX *ctx = BN_CTX_new(); + if (ctx == NULL) { + OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); + return 0; + } + + BIGNUM small_gcd; + BN_init(&small_gcd); + + int ret = 1; + + // Perform partial public key validation of RSA keys (SP 800-89 5.3.3). + enum bn_primality_result_t primality_result; + if (BN_num_bits(key->e) <= 16 || + BN_num_bits(key->e) > 256 || + !BN_is_odd(key->n) || + !BN_is_odd(key->e) || + !BN_gcd(&small_gcd, key->n, g_small_factors(), ctx) || + !BN_is_one(&small_gcd) || + !BN_enhanced_miller_rabin_primality_test(&primality_result, key->n, + BN_prime_checks, ctx, NULL) || + primality_result != bn_non_prime_power_composite) { + OPENSSL_PUT_ERROR(RSA, RSA_R_PUBLIC_KEY_VALIDATION_FAILED); + ret = 0; + } + + BN_free(&small_gcd); + BN_CTX_free(ctx); + + if (!ret || key->d == NULL || key->p == NULL) { + // On a failure or on only a public key, there's nothing else can be + // checked. + return ret; + } + + // FIPS pairwise consistency test (FIPS 140-2 4.9.2). Per FIPS 140-2 IG, + // section 9.9, it is not known whether |rsa| will be used for signing or + // encryption, so either pair-wise consistency self-test is acceptable. We + // perform a signing test. + uint8_t data[32] = {0}; + unsigned sig_len = RSA_size(key); + uint8_t *sig = OPENSSL_malloc(sig_len); + if (sig == NULL) { + OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); + return 0; + } + + if (!RSA_sign(NID_sha256, data, sizeof(data), sig, &sig_len, key)) { + OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR); + ret = 0; + goto cleanup; + } +#if defined(BORINGSSL_FIPS_BREAK_RSA_PWCT) + data[0] = ~data[0]; +#endif + if (!RSA_verify(NID_sha256, data, sizeof(data), sig, sig_len, key)) { + OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR); + ret = 0; + } + +cleanup: + OPENSSL_free(sig); + + return ret; +} + +int RSA_private_transform(RSA *rsa, uint8_t *out, const uint8_t *in, + size_t len) { + if (rsa->meth->private_transform) { + return rsa->meth->private_transform(rsa, out, in, len); + } + + return rsa_default_private_transform(rsa, out, in, len); +} + +int RSA_flags(const RSA *rsa) { return rsa->flags; } + +int RSA_blinding_on(RSA *rsa, BN_CTX *ctx) { + return 1; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/rsa/rsa_impl.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/rsa/rsa_impl.c new file mode 100644 index 0000000..94fcd3f --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/rsa/rsa_impl.c @@ -0,0 +1,1218 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 +#include +#include +#include +#include + +#include "internal.h" +#include "../bn/internal.h" +#include "../../internal.h" +#include "../delocate.h" + + +static int check_modulus_and_exponent_sizes(const RSA *rsa) { + unsigned rsa_bits = BN_num_bits(rsa->n); + + if (rsa_bits > 16 * 1024) { + OPENSSL_PUT_ERROR(RSA, RSA_R_MODULUS_TOO_LARGE); + return 0; + } + + // Mitigate DoS attacks by limiting the exponent size. 33 bits was chosen as + // the limit based on the recommendations in [1] and [2]. Windows CryptoAPI + // doesn't support values larger than 32 bits [3], so it is unlikely that + // exponents larger than 32 bits are being used for anything Windows commonly + // does. + // + // [1] https://www.imperialviolet.org/2012/03/16/rsae.html + // [2] https://www.imperialviolet.org/2012/03/17/rsados.html + // [3] https://msdn.microsoft.com/en-us/library/aa387685(VS.85).aspx + static const unsigned kMaxExponentBits = 33; + + if (BN_num_bits(rsa->e) > kMaxExponentBits) { + OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_E_VALUE); + return 0; + } + + // Verify |n > e|. Comparing |rsa_bits| to |kMaxExponentBits| is a small + // shortcut to comparing |n| and |e| directly. In reality, |kMaxExponentBits| + // is much smaller than the minimum RSA key size that any application should + // accept. + if (rsa_bits <= kMaxExponentBits) { + OPENSSL_PUT_ERROR(RSA, RSA_R_KEY_SIZE_TOO_SMALL); + return 0; + } + assert(BN_ucmp(rsa->n, rsa->e) > 0); + + return 1; +} + +static int ensure_fixed_copy(BIGNUM **out, const BIGNUM *in, int width) { + if (*out != NULL) { + return 1; + } + BIGNUM *copy = BN_dup(in); + if (copy == NULL || + !bn_resize_words(copy, width)) { + BN_free(copy); + return 0; + } + *out = copy; + return 1; +} + +// freeze_private_key finishes initializing |rsa|'s private key components. +// After this function has returned, |rsa| may not be changed. This is needed +// because |RSA| is a public struct and, additionally, OpenSSL 1.1.0 opaquified +// it wrong (see https://github.com/openssl/openssl/issues/5158). +static int freeze_private_key(RSA *rsa, BN_CTX *ctx) { + CRYPTO_MUTEX_lock_read(&rsa->lock); + int frozen = rsa->private_key_frozen; + CRYPTO_MUTEX_unlock_read(&rsa->lock); + if (frozen) { + return 1; + } + + int ret = 0; + CRYPTO_MUTEX_lock_write(&rsa->lock); + if (rsa->private_key_frozen) { + ret = 1; + goto err; + } + + // Pre-compute various intermediate values, as well as copies of private + // exponents with correct widths. Note that other threads may concurrently + // read from |rsa->n|, |rsa->e|, etc., so any fixes must be in separate + // copies. We use |mont_n->N|, |mont_p->N|, and |mont_q->N| as copies of |n|, + // |p|, and |q| with the correct minimal widths. + + if (rsa->mont_n == NULL) { + rsa->mont_n = BN_MONT_CTX_new_for_modulus(rsa->n, ctx); + if (rsa->mont_n == NULL) { + goto err; + } + } + const BIGNUM *n_fixed = &rsa->mont_n->N; + + // The only public upper-bound of |rsa->d| is the bit length of |rsa->n|. The + // ASN.1 serialization of RSA private keys unfortunately leaks the byte length + // of |rsa->d|, but normalize it so we only leak it once, rather than per + // operation. + if (rsa->d != NULL && + !ensure_fixed_copy(&rsa->d_fixed, rsa->d, n_fixed->width)) { + goto err; + } + + if (rsa->p != NULL && rsa->q != NULL) { + if (rsa->mont_p == NULL) { + rsa->mont_p = BN_MONT_CTX_new_for_modulus(rsa->p, ctx); + if (rsa->mont_p == NULL) { + goto err; + } + } + const BIGNUM *p_fixed = &rsa->mont_p->N; + + if (rsa->mont_q == NULL) { + rsa->mont_q = BN_MONT_CTX_new_for_modulus(rsa->q, ctx); + if (rsa->mont_q == NULL) { + goto err; + } + } + const BIGNUM *q_fixed = &rsa->mont_q->N; + + if (rsa->dmp1 != NULL && rsa->dmq1 != NULL) { + // Key generation relies on this function to compute |iqmp|. + if (rsa->iqmp == NULL) { + BIGNUM *iqmp = BN_new(); + if (iqmp == NULL || + !bn_mod_inverse_secret_prime(iqmp, rsa->q, rsa->p, ctx, + rsa->mont_p)) { + BN_free(iqmp); + goto err; + } + rsa->iqmp = iqmp; + } + + // CRT components are only publicly bounded by their corresponding + // moduli's bit lengths. |rsa->iqmp| is unused outside of this one-time + // setup, so we do not compute a fixed-width version of it. + if (!ensure_fixed_copy(&rsa->dmp1_fixed, rsa->dmp1, p_fixed->width) || + !ensure_fixed_copy(&rsa->dmq1_fixed, rsa->dmq1, q_fixed->width)) { + goto err; + } + + // Compute |inv_small_mod_large_mont|. Note that it is always modulo the + // larger prime, independent of what is stored in |rsa->iqmp|. + if (rsa->inv_small_mod_large_mont == NULL) { + BIGNUM *inv_small_mod_large_mont = BN_new(); + int ok; + if (BN_cmp(rsa->p, rsa->q) < 0) { + ok = inv_small_mod_large_mont != NULL && + bn_mod_inverse_secret_prime(inv_small_mod_large_mont, rsa->p, + rsa->q, ctx, rsa->mont_q) && + BN_to_montgomery(inv_small_mod_large_mont, + inv_small_mod_large_mont, rsa->mont_q, ctx); + } else { + ok = inv_small_mod_large_mont != NULL && + BN_to_montgomery(inv_small_mod_large_mont, rsa->iqmp, + rsa->mont_p, ctx); + } + if (!ok) { + BN_free(inv_small_mod_large_mont); + goto err; + } + rsa->inv_small_mod_large_mont = inv_small_mod_large_mont; + } + } + } + + rsa->private_key_frozen = 1; + ret = 1; + +err: + CRYPTO_MUTEX_unlock_write(&rsa->lock); + return ret; +} + +size_t rsa_default_size(const RSA *rsa) { + return BN_num_bytes(rsa->n); +} + +int RSA_encrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out, + const uint8_t *in, size_t in_len, int padding) { + if (rsa->n == NULL || rsa->e == NULL) { + OPENSSL_PUT_ERROR(RSA, RSA_R_VALUE_MISSING); + return 0; + } + + const unsigned rsa_size = RSA_size(rsa); + BIGNUM *f, *result; + uint8_t *buf = NULL; + BN_CTX *ctx = NULL; + int i, ret = 0; + + if (max_out < rsa_size) { + OPENSSL_PUT_ERROR(RSA, RSA_R_OUTPUT_BUFFER_TOO_SMALL); + return 0; + } + + if (!check_modulus_and_exponent_sizes(rsa)) { + return 0; + } + + ctx = BN_CTX_new(); + if (ctx == NULL) { + goto err; + } + + BN_CTX_start(ctx); + f = BN_CTX_get(ctx); + result = BN_CTX_get(ctx); + buf = OPENSSL_malloc(rsa_size); + if (!f || !result || !buf) { + OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); + goto err; + } + + switch (padding) { + case RSA_PKCS1_PADDING: + i = RSA_padding_add_PKCS1_type_2(buf, rsa_size, in, in_len); + break; + case RSA_PKCS1_OAEP_PADDING: + // Use the default parameters: SHA-1 for both hashes and no label. + i = RSA_padding_add_PKCS1_OAEP_mgf1(buf, rsa_size, in, in_len, + NULL, 0, NULL, NULL); + break; + case RSA_NO_PADDING: + i = RSA_padding_add_none(buf, rsa_size, in, in_len); + break; + default: + OPENSSL_PUT_ERROR(RSA, RSA_R_UNKNOWN_PADDING_TYPE); + goto err; + } + + if (i <= 0) { + goto err; + } + + if (BN_bin2bn(buf, rsa_size, f) == NULL) { + goto err; + } + + if (BN_ucmp(f, rsa->n) >= 0) { + // usually the padding functions would catch this + OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE); + goto err; + } + + if (!BN_MONT_CTX_set_locked(&rsa->mont_n, &rsa->lock, rsa->n, ctx) || + !BN_mod_exp_mont(result, f, rsa->e, &rsa->mont_n->N, ctx, rsa->mont_n)) { + goto err; + } + + // put in leading 0 bytes if the number is less than the length of the + // modulus + if (!BN_bn2bin_padded(out, rsa_size, result)) { + OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR); + goto err; + } + + *out_len = rsa_size; + ret = 1; + +err: + if (ctx != NULL) { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + OPENSSL_free(buf); + + return ret; +} + +// MAX_BLINDINGS_PER_RSA defines the maximum number of cached BN_BLINDINGs per +// RSA*. Then this limit is exceeded, BN_BLINDING objects will be created and +// destroyed as needed. +#define MAX_BLINDINGS_PER_RSA 1024 + +// rsa_blinding_get returns a BN_BLINDING to use with |rsa|. It does this by +// allocating one of the cached BN_BLINDING objects in |rsa->blindings|. If +// none are free, the cache will be extended by a extra element and the new +// BN_BLINDING is returned. +// +// On success, the index of the assigned BN_BLINDING is written to +// |*index_used| and must be passed to |rsa_blinding_release| when finished. +static BN_BLINDING *rsa_blinding_get(RSA *rsa, unsigned *index_used, + BN_CTX *ctx) { + assert(ctx != NULL); + assert(rsa->mont_n != NULL); + + BN_BLINDING *ret = NULL; + BN_BLINDING **new_blindings; + uint8_t *new_blindings_inuse; + char overflow = 0; + + CRYPTO_MUTEX_lock_write(&rsa->lock); + + unsigned i; + for (i = 0; i < rsa->num_blindings; i++) { + if (rsa->blindings_inuse[i] == 0) { + rsa->blindings_inuse[i] = 1; + ret = rsa->blindings[i]; + *index_used = i; + break; + } + } + + if (ret != NULL) { + CRYPTO_MUTEX_unlock_write(&rsa->lock); + return ret; + } + + overflow = rsa->num_blindings >= MAX_BLINDINGS_PER_RSA; + + // We didn't find a free BN_BLINDING to use so increase the length of + // the arrays by one and use the newly created element. + + CRYPTO_MUTEX_unlock_write(&rsa->lock); + ret = BN_BLINDING_new(); + if (ret == NULL) { + return NULL; + } + + if (overflow) { + // We cannot add any more cached BN_BLINDINGs so we use |ret| + // and mark it for destruction in |rsa_blinding_release|. + *index_used = MAX_BLINDINGS_PER_RSA; + return ret; + } + + CRYPTO_MUTEX_lock_write(&rsa->lock); + + new_blindings = + OPENSSL_malloc(sizeof(BN_BLINDING *) * (rsa->num_blindings + 1)); + if (new_blindings == NULL) { + goto err1; + } + OPENSSL_memcpy(new_blindings, rsa->blindings, + sizeof(BN_BLINDING *) * rsa->num_blindings); + new_blindings[rsa->num_blindings] = ret; + + new_blindings_inuse = OPENSSL_malloc(rsa->num_blindings + 1); + if (new_blindings_inuse == NULL) { + goto err2; + } + OPENSSL_memcpy(new_blindings_inuse, rsa->blindings_inuse, rsa->num_blindings); + new_blindings_inuse[rsa->num_blindings] = 1; + *index_used = rsa->num_blindings; + + OPENSSL_free(rsa->blindings); + rsa->blindings = new_blindings; + OPENSSL_free(rsa->blindings_inuse); + rsa->blindings_inuse = new_blindings_inuse; + rsa->num_blindings++; + + CRYPTO_MUTEX_unlock_write(&rsa->lock); + return ret; + +err2: + OPENSSL_free(new_blindings); + +err1: + CRYPTO_MUTEX_unlock_write(&rsa->lock); + BN_BLINDING_free(ret); + return NULL; +} + +// rsa_blinding_release marks the cached BN_BLINDING at the given index as free +// for other threads to use. +static void rsa_blinding_release(RSA *rsa, BN_BLINDING *blinding, + unsigned blinding_index) { + if (blinding_index == MAX_BLINDINGS_PER_RSA) { + // This blinding wasn't cached. + BN_BLINDING_free(blinding); + return; + } + + CRYPTO_MUTEX_lock_write(&rsa->lock); + rsa->blindings_inuse[blinding_index] = 0; + CRYPTO_MUTEX_unlock_write(&rsa->lock); +} + +// signing +int rsa_default_sign_raw(RSA *rsa, size_t *out_len, uint8_t *out, + size_t max_out, const uint8_t *in, size_t in_len, + int padding) { + const unsigned rsa_size = RSA_size(rsa); + uint8_t *buf = NULL; + int i, ret = 0; + + if (max_out < rsa_size) { + OPENSSL_PUT_ERROR(RSA, RSA_R_OUTPUT_BUFFER_TOO_SMALL); + return 0; + } + + buf = OPENSSL_malloc(rsa_size); + if (buf == NULL) { + OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); + goto err; + } + + switch (padding) { + case RSA_PKCS1_PADDING: + i = RSA_padding_add_PKCS1_type_1(buf, rsa_size, in, in_len); + break; + case RSA_NO_PADDING: + i = RSA_padding_add_none(buf, rsa_size, in, in_len); + break; + default: + OPENSSL_PUT_ERROR(RSA, RSA_R_UNKNOWN_PADDING_TYPE); + goto err; + } + + if (i <= 0) { + goto err; + } + + if (!RSA_private_transform(rsa, out, buf, rsa_size)) { + goto err; + } + + *out_len = rsa_size; + ret = 1; + +err: + OPENSSL_free(buf); + + return ret; +} + +int rsa_default_decrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out, + const uint8_t *in, size_t in_len, int padding) { + const unsigned rsa_size = RSA_size(rsa); + uint8_t *buf = NULL; + int ret = 0; + + if (max_out < rsa_size) { + OPENSSL_PUT_ERROR(RSA, RSA_R_OUTPUT_BUFFER_TOO_SMALL); + return 0; + } + + if (padding == RSA_NO_PADDING) { + buf = out; + } else { + // Allocate a temporary buffer to hold the padded plaintext. + buf = OPENSSL_malloc(rsa_size); + if (buf == NULL) { + OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); + goto err; + } + } + + if (in_len != rsa_size) { + OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_LEN_NOT_EQUAL_TO_MOD_LEN); + goto err; + } + + if (!RSA_private_transform(rsa, buf, in, rsa_size)) { + goto err; + } + + switch (padding) { + case RSA_PKCS1_PADDING: + ret = + RSA_padding_check_PKCS1_type_2(out, out_len, rsa_size, buf, rsa_size); + break; + case RSA_PKCS1_OAEP_PADDING: + // Use the default parameters: SHA-1 for both hashes and no label. + ret = RSA_padding_check_PKCS1_OAEP_mgf1(out, out_len, rsa_size, buf, + rsa_size, NULL, 0, NULL, NULL); + break; + case RSA_NO_PADDING: + *out_len = rsa_size; + ret = 1; + break; + default: + OPENSSL_PUT_ERROR(RSA, RSA_R_UNKNOWN_PADDING_TYPE); + goto err; + } + + if (!ret) { + OPENSSL_PUT_ERROR(RSA, RSA_R_PADDING_CHECK_FAILED); + } + +err: + if (padding != RSA_NO_PADDING) { + OPENSSL_free(buf); + } + + return ret; +} + +static int mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx); + +int RSA_verify_raw(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out, + const uint8_t *in, size_t in_len, int padding) { + if (rsa->n == NULL || rsa->e == NULL) { + OPENSSL_PUT_ERROR(RSA, RSA_R_VALUE_MISSING); + return 0; + } + + const unsigned rsa_size = RSA_size(rsa); + BIGNUM *f, *result; + + if (max_out < rsa_size) { + OPENSSL_PUT_ERROR(RSA, RSA_R_OUTPUT_BUFFER_TOO_SMALL); + return 0; + } + + if (in_len != rsa_size) { + OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_LEN_NOT_EQUAL_TO_MOD_LEN); + return 0; + } + + if (!check_modulus_and_exponent_sizes(rsa)) { + return 0; + } + + BN_CTX *ctx = BN_CTX_new(); + if (ctx == NULL) { + return 0; + } + + int ret = 0; + uint8_t *buf = NULL; + + BN_CTX_start(ctx); + f = BN_CTX_get(ctx); + result = BN_CTX_get(ctx); + if (f == NULL || result == NULL) { + OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (padding == RSA_NO_PADDING) { + buf = out; + } else { + // Allocate a temporary buffer to hold the padded plaintext. + buf = OPENSSL_malloc(rsa_size); + if (buf == NULL) { + OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); + goto err; + } + } + + if (BN_bin2bn(in, in_len, f) == NULL) { + goto err; + } + + if (BN_ucmp(f, rsa->n) >= 0) { + OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE); + goto err; + } + + if (!BN_MONT_CTX_set_locked(&rsa->mont_n, &rsa->lock, rsa->n, ctx) || + !BN_mod_exp_mont(result, f, rsa->e, &rsa->mont_n->N, ctx, rsa->mont_n)) { + goto err; + } + + if (!BN_bn2bin_padded(buf, rsa_size, result)) { + OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR); + goto err; + } + + switch (padding) { + case RSA_PKCS1_PADDING: + ret = + RSA_padding_check_PKCS1_type_1(out, out_len, rsa_size, buf, rsa_size); + break; + case RSA_NO_PADDING: + ret = 1; + *out_len = rsa_size; + break; + default: + OPENSSL_PUT_ERROR(RSA, RSA_R_UNKNOWN_PADDING_TYPE); + goto err; + } + + if (!ret) { + OPENSSL_PUT_ERROR(RSA, RSA_R_PADDING_CHECK_FAILED); + goto err; + } + +err: + BN_CTX_end(ctx); + BN_CTX_free(ctx); + if (buf != out) { + OPENSSL_free(buf); + } + return ret; +} + +int rsa_default_private_transform(RSA *rsa, uint8_t *out, const uint8_t *in, + size_t len) { + if (rsa->n == NULL || rsa->d == NULL) { + OPENSSL_PUT_ERROR(RSA, RSA_R_VALUE_MISSING); + return 0; + } + + BIGNUM *f, *result; + BN_CTX *ctx = NULL; + unsigned blinding_index = 0; + BN_BLINDING *blinding = NULL; + int ret = 0; + + ctx = BN_CTX_new(); + if (ctx == NULL) { + goto err; + } + BN_CTX_start(ctx); + f = BN_CTX_get(ctx); + result = BN_CTX_get(ctx); + + if (f == NULL || result == NULL) { + OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (BN_bin2bn(in, len, f) == NULL) { + goto err; + } + + if (BN_ucmp(f, rsa->n) >= 0) { + // Usually the padding functions would catch this. + OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE); + goto err; + } + + if (!freeze_private_key(rsa, ctx)) { + OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR); + goto err; + } + + const int do_blinding = (rsa->flags & RSA_FLAG_NO_BLINDING) == 0; + + if (rsa->e == NULL && do_blinding) { + // We cannot do blinding or verification without |e|, and continuing without + // those countermeasures is dangerous. However, the Java/Android RSA API + // requires support for keys where only |d| and |n| (and not |e|) are known. + // The callers that require that bad behavior set |RSA_FLAG_NO_BLINDING|. + OPENSSL_PUT_ERROR(RSA, RSA_R_NO_PUBLIC_EXPONENT); + goto err; + } + + if (do_blinding) { + blinding = rsa_blinding_get(rsa, &blinding_index, ctx); + if (blinding == NULL) { + OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR); + goto err; + } + if (!BN_BLINDING_convert(f, blinding, rsa->e, rsa->mont_n, ctx)) { + goto err; + } + } + + if (rsa->p != NULL && rsa->q != NULL && rsa->e != NULL && rsa->dmp1 != NULL && + rsa->dmq1 != NULL && rsa->iqmp != NULL) { + if (!mod_exp(result, f, rsa, ctx)) { + goto err; + } + } else if (!BN_mod_exp_mont_consttime(result, f, rsa->d_fixed, rsa->n, ctx, + rsa->mont_n)) { + goto err; + } + + // Verify the result to protect against fault attacks as described in the + // 1997 paper "On the Importance of Checking Cryptographic Protocols for + // Faults" by Dan Boneh, Richard A. DeMillo, and Richard J. Lipton. Some + // implementations do this only when the CRT is used, but we do it in all + // cases. Section 6 of the aforementioned paper describes an attack that + // works when the CRT isn't used. That attack is much less likely to succeed + // than the CRT attack, but there have likely been improvements since 1997. + // + // This check is cheap assuming |e| is small; it almost always is. + if (rsa->e != NULL) { + BIGNUM *vrfy = BN_CTX_get(ctx); + if (vrfy == NULL || + !BN_mod_exp_mont(vrfy, result, rsa->e, rsa->n, ctx, rsa->mont_n) || + !BN_equal_consttime(vrfy, f)) { + OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR); + goto err; + } + + } + + if (do_blinding && + !BN_BLINDING_invert(result, blinding, rsa->mont_n, ctx)) { + goto err; + } + + // The computation should have left |result| as a maximally-wide number, so + // that it and serializing does not leak information about the magnitude of + // the result. + // + // See Falko Stenzke, "Manger's Attack revisited", ICICS 2010. + assert(result->width == rsa->mont_n->N.width); + if (!BN_bn2bin_padded(out, len, result)) { + OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR); + goto err; + } + + ret = 1; + +err: + if (ctx != NULL) { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + if (blinding != NULL) { + rsa_blinding_release(rsa, blinding, blinding_index); + } + + return ret; +} + +// mod_montgomery sets |r| to |I| mod |p|. |I| must already be fully reduced +// modulo |p| times |q|. It returns one on success and zero on error. +static int mod_montgomery(BIGNUM *r, const BIGNUM *I, const BIGNUM *p, + const BN_MONT_CTX *mont_p, const BIGNUM *q, + BN_CTX *ctx) { + // Reducing in constant-time with Montgomery reduction requires I <= p * R. We + // have I < p * q, so this follows if q < R. In particular, this always holds + // if p and q are the same size, which is true for any RSA keys we or anyone + // sane generates. For other keys, we fall back to |BN_mod|. + if (!bn_less_than_montgomery_R(q, mont_p)) { + return BN_mod(r, I, p, ctx); + } + + if (// Reduce mod p with Montgomery reduction. This computes I * R^-1 mod p. + !BN_from_montgomery(r, I, mont_p, ctx) || + // Multiply by R^2 and do another Montgomery reduction to compute + // I * R^-1 * R^2 * R^-1 = I mod p. + !BN_to_montgomery(r, r, mont_p, ctx)) { + return 0; + } + + // By precomputing R^3 mod p (normally |BN_MONT_CTX| only uses R^2 mod p) and + // adjusting the API for |BN_mod_exp_mont_consttime|, we could instead compute + // I * R mod p here and save a reduction per prime. But this would require + // changing the RSAZ code and may not be worth it. Note that the RSAZ code + // uses a different radix, so it uses R' = 2^1044. There we'd actually want + // R^2 * R', and would futher benefit from a precomputed R'^2. It currently + // converts |mont_p->RR| to R'^2. + return 1; +} + +static int mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) { + assert(ctx != NULL); + + assert(rsa->n != NULL); + assert(rsa->e != NULL); + assert(rsa->d != NULL); + assert(rsa->p != NULL); + assert(rsa->q != NULL); + assert(rsa->dmp1 != NULL); + assert(rsa->dmq1 != NULL); + assert(rsa->iqmp != NULL); + + BIGNUM *r1, *m1; + int ret = 0; + + BN_CTX_start(ctx); + r1 = BN_CTX_get(ctx); + m1 = BN_CTX_get(ctx); + if (r1 == NULL || + m1 == NULL) { + goto err; + } + + if (!freeze_private_key(rsa, ctx)) { + goto err; + } + + // Implementing RSA with CRT in constant-time is sensitive to which prime is + // larger. Canonicalize fields so that |p| is the larger prime. + const BIGNUM *dmp1 = rsa->dmp1_fixed, *dmq1 = rsa->dmq1_fixed; + const BN_MONT_CTX *mont_p = rsa->mont_p, *mont_q = rsa->mont_q; + if (BN_cmp(rsa->p, rsa->q) < 0) { + mont_p = rsa->mont_q; + mont_q = rsa->mont_p; + dmp1 = rsa->dmq1_fixed; + dmq1 = rsa->dmp1_fixed; + } + + // Use the minimal-width versions of |n|, |p|, and |q|. Either works, but if + // someone gives us non-minimal values, these will be slightly more efficient + // on the non-Montgomery operations. + const BIGNUM *n = &rsa->mont_n->N; + const BIGNUM *p = &mont_p->N; + const BIGNUM *q = &mont_q->N; + + // This is a pre-condition for |mod_montgomery|. It was already checked by the + // caller. + assert(BN_ucmp(I, n) < 0); + + if (// |m1| is the result modulo |q|. + !mod_montgomery(r1, I, q, mont_q, p, ctx) || + !BN_mod_exp_mont_consttime(m1, r1, dmq1, q, ctx, mont_q) || + // |r0| is the result modulo |p|. + !mod_montgomery(r1, I, p, mont_p, q, ctx) || + !BN_mod_exp_mont_consttime(r0, r1, dmp1, p, ctx, mont_p) || + // Compute r0 = r0 - m1 mod p. |p| is the larger prime, so |m1| is already + // fully reduced mod |p|. + !bn_mod_sub_consttime(r0, r0, m1, p, ctx) || + // r0 = r0 * iqmp mod p. We use Montgomery multiplication to compute this + // in constant time. |inv_small_mod_large_mont| is in Montgomery form and + // r0 is not, so the result is taken out of Montgomery form. + !BN_mod_mul_montgomery(r0, r0, rsa->inv_small_mod_large_mont, mont_p, + ctx) || + // r0 = r0 * q + m1 gives the final result. Reducing modulo q gives m1, so + // it is correct mod p. Reducing modulo p gives (r0-m1)*iqmp*q + m1 = r0, + // so it is correct mod q. Finally, the result is bounded by [m1, n + m1), + // and the result is at least |m1|, so this must be the unique answer in + // [0, n). + !bn_mul_consttime(r0, r0, q, ctx) || + !bn_uadd_consttime(r0, r0, m1) || + // The result should be bounded by |n|, but fixed-width operations may + // bound the width slightly higher, so fix it. + !bn_resize_words(r0, n->width)) { + goto err; + } + + ret = 1; + +err: + BN_CTX_end(ctx); + return ret; +} + +static int ensure_bignum(BIGNUM **out) { + if (*out == NULL) { + *out = BN_new(); + } + return *out != NULL; +} + +// kBoringSSLRSASqrtTwo is the BIGNUM representation of ⌊2¹⁵³⁵×√2⌋. This is +// chosen to give enough precision for 3072-bit RSA, the largest key size FIPS +// specifies. Key sizes beyond this will round up. +// +// To verify this number, check that n² < 2³⁰⁷¹ < (n+1)², where n is value +// represented here. Note the components are listed in little-endian order. Here +// is some sample Python code to check: +// +// >>> TOBN = lambda a, b: a << 32 | b +// >>> l = [ ] +// >>> n = sum(a * 2**(64*i) for i, a in enumerate(l)) +// >>> n**2 < 2**3071 < (n+1)**2 +// True +const BN_ULONG kBoringSSLRSASqrtTwo[] = { + TOBN(0xdea06241, 0xf7aa81c2), TOBN(0xf6a1be3f, 0xca221307), + TOBN(0x332a5e9f, 0x7bda1ebf), TOBN(0x0104dc01, 0xfe32352f), + TOBN(0xb8cf341b, 0x6f8236c7), TOBN(0x4264dabc, 0xd528b651), + TOBN(0xf4d3a02c, 0xebc93e0c), TOBN(0x81394ab6, 0xd8fd0efd), + TOBN(0xeaa4a089, 0x9040ca4a), TOBN(0xf52f120f, 0x836e582e), + TOBN(0xcb2a6343, 0x31f3c84d), TOBN(0xc6d5a8a3, 0x8bb7e9dc), + TOBN(0x460abc72, 0x2f7c4e33), TOBN(0xcab1bc91, 0x1688458a), + TOBN(0x53059c60, 0x11bc337b), TOBN(0xd2202e87, 0x42af1f4e), + TOBN(0x78048736, 0x3dfa2768), TOBN(0x0f74a85e, 0x439c7b4a), + TOBN(0xa8b1fe6f, 0xdc83db39), TOBN(0x4afc8304, 0x3ab8a2c3), + TOBN(0xed17ac85, 0x83339915), TOBN(0x1d6f60ba, 0x893ba84c), + TOBN(0x597d89b3, 0x754abe9f), TOBN(0xb504f333, 0xf9de6484), +}; +const size_t kBoringSSLRSASqrtTwoLen = OPENSSL_ARRAY_SIZE(kBoringSSLRSASqrtTwo); + +// generate_prime sets |out| to a prime with length |bits| such that |out|-1 is +// relatively prime to |e|. If |p| is non-NULL, |out| will also not be close to +// |p|. |sqrt2| must be ⌊2^(bits-1)×√2⌋ (or a slightly overestimate for large +// sizes), and |pow2_bits_100| must be 2^(bits-100). +static int generate_prime(BIGNUM *out, int bits, const BIGNUM *e, + const BIGNUM *p, const BIGNUM *sqrt2, + const BIGNUM *pow2_bits_100, BN_CTX *ctx, + BN_GENCB *cb) { + if (bits < 128 || (bits % BN_BITS2) != 0) { + OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR); + return 0; + } + assert(BN_is_pow2(pow2_bits_100)); + assert(BN_is_bit_set(pow2_bits_100, bits - 100)); + + // See FIPS 186-4 appendix B.3.3, steps 4 and 5. Note |bits| here is nlen/2. + + // Use the limit from steps 4.7 and 5.8 for most values of |e|. When |e| is 3, + // the 186-4 limit is too low, so we use a higher one. Note this case is not + // reachable from |RSA_generate_key_fips|. + if (bits >= INT_MAX/32) { + OPENSSL_PUT_ERROR(RSA, RSA_R_MODULUS_TOO_LARGE); + return 0; + } + int limit = BN_is_word(e, 3) ? bits * 32 : bits * 5; + + int ret = 0, tries = 0, rand_tries = 0; + BN_CTX_start(ctx); + BIGNUM *tmp = BN_CTX_get(ctx); + if (tmp == NULL) { + goto err; + } + + for (;;) { + // Generate a random number of length |bits| where the bottom bit is set + // (steps 4.2, 4.3, 5.2 and 5.3) and the top bit is set (implied by the + // bound checked below in steps 4.4 and 5.5). + if (!BN_rand(out, bits, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ODD) || + !BN_GENCB_call(cb, BN_GENCB_GENERATED, rand_tries++)) { + goto err; + } + + if (p != NULL) { + // If |p| and |out| are too close, try again (step 5.4). + if (!bn_abs_sub_consttime(tmp, out, p, ctx)) { + goto err; + } + if (BN_cmp(tmp, pow2_bits_100) <= 0) { + continue; + } + } + + // If out < 2^(bits-1)×√2, try again (steps 4.4 and 5.5). This is equivalent + // to out <= ⌊2^(bits-1)×√2⌋, or out <= sqrt2 for FIPS key sizes. + // + // For larger keys, the comparison is approximate, leaning towards + // retrying. That is, we reject a negligible fraction of primes that are + // within the FIPS bound, but we will never accept a prime outside the + // bound, ensuring the resulting RSA key is the right size. + if (BN_cmp(out, sqrt2) <= 0) { + continue; + } + + // RSA key generation's bottleneck is discarding composites. If it fails + // trial division, do not bother computing a GCD or performing Rabin-Miller. + if (!bn_odd_number_is_obviously_composite(out)) { + // Check gcd(out-1, e) is one (steps 4.5 and 5.6). + int relatively_prime; + if (!BN_sub(tmp, out, BN_value_one()) || + !bn_is_relatively_prime(&relatively_prime, tmp, e, ctx)) { + goto err; + } + if (relatively_prime) { + // Test |out| for primality (steps 4.5.1 and 5.6.1). + int is_probable_prime; + if (!BN_primality_test(&is_probable_prime, out, BN_prime_checks, ctx, 0, + cb)) { + goto err; + } + if (is_probable_prime) { + ret = 1; + goto err; + } + } + } + + // If we've tried too many times to find a prime, abort (steps 4.7 and + // 5.8). + tries++; + if (tries >= limit) { + OPENSSL_PUT_ERROR(RSA, RSA_R_TOO_MANY_ITERATIONS); + goto err; + } + if (!BN_GENCB_call(cb, 2, tries)) { + goto err; + } + } + +err: + BN_CTX_end(ctx); + return ret; +} + +int RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb) { + // See FIPS 186-4 appendix B.3. This function implements a generalized version + // of the FIPS algorithm. |RSA_generate_key_fips| performs additional checks + // for FIPS-compliant key generation. + + // Always generate RSA keys which are a multiple of 128 bits. Round |bits| + // down as needed. + bits &= ~127; + + // Reject excessively small keys. + if (bits < 256) { + OPENSSL_PUT_ERROR(RSA, RSA_R_KEY_SIZE_TOO_SMALL); + return 0; + } + + // Reject excessively large public exponents. Windows CryptoAPI and Go don't + // support values larger than 32 bits, so match their limits for generating + // keys. (|check_modulus_and_exponent_sizes| uses a slightly more conservative + // value, but we don't need to support generating such keys.) + // https://github.com/golang/go/issues/3161 + // https://msdn.microsoft.com/en-us/library/aa387685(VS.85).aspx + if (BN_num_bits(e_value) > 32) { + OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_E_VALUE); + return 0; + } + + int ret = 0; + int prime_bits = bits / 2; + BN_CTX *ctx = BN_CTX_new(); + if (ctx == NULL) { + goto bn_err; + } + BN_CTX_start(ctx); + BIGNUM *totient = BN_CTX_get(ctx); + BIGNUM *pm1 = BN_CTX_get(ctx); + BIGNUM *qm1 = BN_CTX_get(ctx); + BIGNUM *sqrt2 = BN_CTX_get(ctx); + BIGNUM *pow2_prime_bits_100 = BN_CTX_get(ctx); + BIGNUM *pow2_prime_bits = BN_CTX_get(ctx); + if (totient == NULL || pm1 == NULL || qm1 == NULL || sqrt2 == NULL || + pow2_prime_bits_100 == NULL || pow2_prime_bits == NULL || + !BN_set_bit(pow2_prime_bits_100, prime_bits - 100) || + !BN_set_bit(pow2_prime_bits, prime_bits)) { + goto bn_err; + } + + // We need the RSA components non-NULL. + if (!ensure_bignum(&rsa->n) || + !ensure_bignum(&rsa->d) || + !ensure_bignum(&rsa->e) || + !ensure_bignum(&rsa->p) || + !ensure_bignum(&rsa->q) || + !ensure_bignum(&rsa->dmp1) || + !ensure_bignum(&rsa->dmq1)) { + goto bn_err; + } + + if (!BN_copy(rsa->e, e_value)) { + goto bn_err; + } + + // Compute sqrt2 >= ⌊2^(prime_bits-1)×√2⌋. + if (!bn_set_words(sqrt2, kBoringSSLRSASqrtTwo, kBoringSSLRSASqrtTwoLen)) { + goto bn_err; + } + int sqrt2_bits = kBoringSSLRSASqrtTwoLen * BN_BITS2; + assert(sqrt2_bits == (int)BN_num_bits(sqrt2)); + if (sqrt2_bits > prime_bits) { + // For key sizes up to 3072 (prime_bits = 1536), this is exactly + // ⌊2^(prime_bits-1)×√2⌋. + if (!BN_rshift(sqrt2, sqrt2, sqrt2_bits - prime_bits)) { + goto bn_err; + } + } else if (prime_bits > sqrt2_bits) { + // For key sizes beyond 3072, this is approximate. We err towards retrying + // to ensure our key is the right size and round up. + if (!BN_add_word(sqrt2, 1) || + !BN_lshift(sqrt2, sqrt2, prime_bits - sqrt2_bits)) { + goto bn_err; + } + } + assert(prime_bits == (int)BN_num_bits(sqrt2)); + + do { + // Generate p and q, each of size |prime_bits|, using the steps outlined in + // appendix FIPS 186-4 appendix B.3.3. + if (!generate_prime(rsa->p, prime_bits, rsa->e, NULL, sqrt2, + pow2_prime_bits_100, ctx, cb) || + !BN_GENCB_call(cb, 3, 0) || + !generate_prime(rsa->q, prime_bits, rsa->e, rsa->p, sqrt2, + pow2_prime_bits_100, ctx, cb) || + !BN_GENCB_call(cb, 3, 1)) { + goto bn_err; + } + + if (BN_cmp(rsa->p, rsa->q) < 0) { + BIGNUM *tmp = rsa->p; + rsa->p = rsa->q; + rsa->q = tmp; + } + + // Calculate d = e^(-1) (mod lcm(p-1, q-1)), per FIPS 186-4. This differs + // from typical RSA implementations which use (p-1)*(q-1). + // + // Note this means the size of d might reveal information about p-1 and + // q-1. However, we do operations with Chinese Remainder Theorem, so we only + // use d (mod p-1) and d (mod q-1) as exponents. Using a minimal totient + // does not affect those two values. + int no_inverse; + if (!bn_usub_consttime(pm1, rsa->p, BN_value_one()) || + !bn_usub_consttime(qm1, rsa->q, BN_value_one()) || + !bn_lcm_consttime(totient, pm1, qm1, ctx) || + !bn_mod_inverse_consttime(rsa->d, &no_inverse, rsa->e, totient, ctx)) { + goto bn_err; + } + + // Retry if |rsa->d| <= 2^|prime_bits|. See appendix B.3.1's guidance on + // values for d. + } while (BN_cmp(rsa->d, pow2_prime_bits) <= 0); + + if (// Calculate n. + !bn_mul_consttime(rsa->n, rsa->p, rsa->q, ctx) || + // Calculate d mod (p-1). + !bn_div_consttime(NULL, rsa->dmp1, rsa->d, pm1, ctx) || + // Calculate d mod (q-1) + !bn_div_consttime(NULL, rsa->dmq1, rsa->d, qm1, ctx)) { + goto bn_err; + } + bn_set_minimal_width(rsa->n); + + // Sanity-check that |rsa->n| has the specified size. This is implied by + // |generate_prime|'s bounds. + if (BN_num_bits(rsa->n) != (unsigned)bits) { + OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR); + goto err; + } + + // Call |freeze_private_key| to compute the inverse of q mod p, by way of + // |rsa->mont_p|. + if (!freeze_private_key(rsa, ctx)) { + goto bn_err; + } + + // The key generation process is complex and thus error-prone. It could be + // disastrous to generate and then use a bad key so double-check that the key + // makes sense. + if (!RSA_check_key(rsa)) { + OPENSSL_PUT_ERROR(RSA, RSA_R_INTERNAL_ERROR); + goto err; + } + + ret = 1; + +bn_err: + if (!ret) { + OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN); + } +err: + if (ctx != NULL) { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + return ret; +} + +int RSA_generate_key_fips(RSA *rsa, int bits, BN_GENCB *cb) { + // FIPS 186-4 allows 2048-bit and 3072-bit RSA keys (1024-bit and 1536-bit + // primes, respectively) with the prime generation method we use. + if (bits != 2048 && bits != 3072) { + OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_RSA_PARAMETERS); + return 0; + } + + BIGNUM *e = BN_new(); + int ret = e != NULL && + BN_set_word(e, RSA_F4) && + RSA_generate_key_ex(rsa, bits, e, cb) && + RSA_check_fips(rsa); + BN_free(e); + return ret; +} + +DEFINE_METHOD_FUNCTION(RSA_METHOD, RSA_default_method) { + // All of the methods are NULL to make it easier for the compiler/linker to + // drop unused functions. The wrapper functions will select the appropriate + // |rsa_default_*| implementation. + OPENSSL_memset(out, 0, sizeof(RSA_METHOD)); + out->common.is_static = 1; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/rsa/rsa_impl.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/rsa/rsa_impl.c.grpc_back new file mode 100644 index 0000000..49cbc15 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/rsa/rsa_impl.c.grpc_back @@ -0,0 +1,1218 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 +#include +#include +#include +#include + +#include "internal.h" +#include "../bn/internal.h" +#include "../../internal.h" +#include "../delocate.h" + + +static int check_modulus_and_exponent_sizes(const RSA *rsa) { + unsigned rsa_bits = BN_num_bits(rsa->n); + + if (rsa_bits > 16 * 1024) { + OPENSSL_PUT_ERROR(RSA, RSA_R_MODULUS_TOO_LARGE); + return 0; + } + + // Mitigate DoS attacks by limiting the exponent size. 33 bits was chosen as + // the limit based on the recommendations in [1] and [2]. Windows CryptoAPI + // doesn't support values larger than 32 bits [3], so it is unlikely that + // exponents larger than 32 bits are being used for anything Windows commonly + // does. + // + // [1] https://www.imperialviolet.org/2012/03/16/rsae.html + // [2] https://www.imperialviolet.org/2012/03/17/rsados.html + // [3] https://msdn.microsoft.com/en-us/library/aa387685(VS.85).aspx + static const unsigned kMaxExponentBits = 33; + + if (BN_num_bits(rsa->e) > kMaxExponentBits) { + OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_E_VALUE); + return 0; + } + + // Verify |n > e|. Comparing |rsa_bits| to |kMaxExponentBits| is a small + // shortcut to comparing |n| and |e| directly. In reality, |kMaxExponentBits| + // is much smaller than the minimum RSA key size that any application should + // accept. + if (rsa_bits <= kMaxExponentBits) { + OPENSSL_PUT_ERROR(RSA, RSA_R_KEY_SIZE_TOO_SMALL); + return 0; + } + assert(BN_ucmp(rsa->n, rsa->e) > 0); + + return 1; +} + +static int ensure_fixed_copy(BIGNUM **out, const BIGNUM *in, int width) { + if (*out != NULL) { + return 1; + } + BIGNUM *copy = BN_dup(in); + if (copy == NULL || + !bn_resize_words(copy, width)) { + BN_free(copy); + return 0; + } + *out = copy; + return 1; +} + +// freeze_private_key finishes initializing |rsa|'s private key components. +// After this function has returned, |rsa| may not be changed. This is needed +// because |RSA| is a public struct and, additionally, OpenSSL 1.1.0 opaquified +// it wrong (see https://github.com/openssl/openssl/issues/5158). +static int freeze_private_key(RSA *rsa, BN_CTX *ctx) { + CRYPTO_MUTEX_lock_read(&rsa->lock); + int frozen = rsa->private_key_frozen; + CRYPTO_MUTEX_unlock_read(&rsa->lock); + if (frozen) { + return 1; + } + + int ret = 0; + CRYPTO_MUTEX_lock_write(&rsa->lock); + if (rsa->private_key_frozen) { + ret = 1; + goto err; + } + + // Pre-compute various intermediate values, as well as copies of private + // exponents with correct widths. Note that other threads may concurrently + // read from |rsa->n|, |rsa->e|, etc., so any fixes must be in separate + // copies. We use |mont_n->N|, |mont_p->N|, and |mont_q->N| as copies of |n|, + // |p|, and |q| with the correct minimal widths. + + if (rsa->mont_n == NULL) { + rsa->mont_n = BN_MONT_CTX_new_for_modulus(rsa->n, ctx); + if (rsa->mont_n == NULL) { + goto err; + } + } + const BIGNUM *n_fixed = &rsa->mont_n->N; + + // The only public upper-bound of |rsa->d| is the bit length of |rsa->n|. The + // ASN.1 serialization of RSA private keys unfortunately leaks the byte length + // of |rsa->d|, but normalize it so we only leak it once, rather than per + // operation. + if (rsa->d != NULL && + !ensure_fixed_copy(&rsa->d_fixed, rsa->d, n_fixed->width)) { + goto err; + } + + if (rsa->p != NULL && rsa->q != NULL) { + if (rsa->mont_p == NULL) { + rsa->mont_p = BN_MONT_CTX_new_for_modulus(rsa->p, ctx); + if (rsa->mont_p == NULL) { + goto err; + } + } + const BIGNUM *p_fixed = &rsa->mont_p->N; + + if (rsa->mont_q == NULL) { + rsa->mont_q = BN_MONT_CTX_new_for_modulus(rsa->q, ctx); + if (rsa->mont_q == NULL) { + goto err; + } + } + const BIGNUM *q_fixed = &rsa->mont_q->N; + + if (rsa->dmp1 != NULL && rsa->dmq1 != NULL) { + // Key generation relies on this function to compute |iqmp|. + if (rsa->iqmp == NULL) { + BIGNUM *iqmp = BN_new(); + if (iqmp == NULL || + !bn_mod_inverse_secret_prime(iqmp, rsa->q, rsa->p, ctx, + rsa->mont_p)) { + BN_free(iqmp); + goto err; + } + rsa->iqmp = iqmp; + } + + // CRT components are only publicly bounded by their corresponding + // moduli's bit lengths. |rsa->iqmp| is unused outside of this one-time + // setup, so we do not compute a fixed-width version of it. + if (!ensure_fixed_copy(&rsa->dmp1_fixed, rsa->dmp1, p_fixed->width) || + !ensure_fixed_copy(&rsa->dmq1_fixed, rsa->dmq1, q_fixed->width)) { + goto err; + } + + // Compute |inv_small_mod_large_mont|. Note that it is always modulo the + // larger prime, independent of what is stored in |rsa->iqmp|. + if (rsa->inv_small_mod_large_mont == NULL) { + BIGNUM *inv_small_mod_large_mont = BN_new(); + int ok; + if (BN_cmp(rsa->p, rsa->q) < 0) { + ok = inv_small_mod_large_mont != NULL && + bn_mod_inverse_secret_prime(inv_small_mod_large_mont, rsa->p, + rsa->q, ctx, rsa->mont_q) && + BN_to_montgomery(inv_small_mod_large_mont, + inv_small_mod_large_mont, rsa->mont_q, ctx); + } else { + ok = inv_small_mod_large_mont != NULL && + BN_to_montgomery(inv_small_mod_large_mont, rsa->iqmp, + rsa->mont_p, ctx); + } + if (!ok) { + BN_free(inv_small_mod_large_mont); + goto err; + } + rsa->inv_small_mod_large_mont = inv_small_mod_large_mont; + } + } + } + + rsa->private_key_frozen = 1; + ret = 1; + +err: + CRYPTO_MUTEX_unlock_write(&rsa->lock); + return ret; +} + +size_t rsa_default_size(const RSA *rsa) { + return BN_num_bytes(rsa->n); +} + +int RSA_encrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out, + const uint8_t *in, size_t in_len, int padding) { + if (rsa->n == NULL || rsa->e == NULL) { + OPENSSL_PUT_ERROR(RSA, RSA_R_VALUE_MISSING); + return 0; + } + + const unsigned rsa_size = RSA_size(rsa); + BIGNUM *f, *result; + uint8_t *buf = NULL; + BN_CTX *ctx = NULL; + int i, ret = 0; + + if (max_out < rsa_size) { + OPENSSL_PUT_ERROR(RSA, RSA_R_OUTPUT_BUFFER_TOO_SMALL); + return 0; + } + + if (!check_modulus_and_exponent_sizes(rsa)) { + return 0; + } + + ctx = BN_CTX_new(); + if (ctx == NULL) { + goto err; + } + + BN_CTX_start(ctx); + f = BN_CTX_get(ctx); + result = BN_CTX_get(ctx); + buf = OPENSSL_malloc(rsa_size); + if (!f || !result || !buf) { + OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); + goto err; + } + + switch (padding) { + case RSA_PKCS1_PADDING: + i = RSA_padding_add_PKCS1_type_2(buf, rsa_size, in, in_len); + break; + case RSA_PKCS1_OAEP_PADDING: + // Use the default parameters: SHA-1 for both hashes and no label. + i = RSA_padding_add_PKCS1_OAEP_mgf1(buf, rsa_size, in, in_len, + NULL, 0, NULL, NULL); + break; + case RSA_NO_PADDING: + i = RSA_padding_add_none(buf, rsa_size, in, in_len); + break; + default: + OPENSSL_PUT_ERROR(RSA, RSA_R_UNKNOWN_PADDING_TYPE); + goto err; + } + + if (i <= 0) { + goto err; + } + + if (BN_bin2bn(buf, rsa_size, f) == NULL) { + goto err; + } + + if (BN_ucmp(f, rsa->n) >= 0) { + // usually the padding functions would catch this + OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE); + goto err; + } + + if (!BN_MONT_CTX_set_locked(&rsa->mont_n, &rsa->lock, rsa->n, ctx) || + !BN_mod_exp_mont(result, f, rsa->e, &rsa->mont_n->N, ctx, rsa->mont_n)) { + goto err; + } + + // put in leading 0 bytes if the number is less than the length of the + // modulus + if (!BN_bn2bin_padded(out, rsa_size, result)) { + OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR); + goto err; + } + + *out_len = rsa_size; + ret = 1; + +err: + if (ctx != NULL) { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + OPENSSL_free(buf); + + return ret; +} + +// MAX_BLINDINGS_PER_RSA defines the maximum number of cached BN_BLINDINGs per +// RSA*. Then this limit is exceeded, BN_BLINDING objects will be created and +// destroyed as needed. +#define MAX_BLINDINGS_PER_RSA 1024 + +// rsa_blinding_get returns a BN_BLINDING to use with |rsa|. It does this by +// allocating one of the cached BN_BLINDING objects in |rsa->blindings|. If +// none are free, the cache will be extended by a extra element and the new +// BN_BLINDING is returned. +// +// On success, the index of the assigned BN_BLINDING is written to +// |*index_used| and must be passed to |rsa_blinding_release| when finished. +static BN_BLINDING *rsa_blinding_get(RSA *rsa, unsigned *index_used, + BN_CTX *ctx) { + assert(ctx != NULL); + assert(rsa->mont_n != NULL); + + BN_BLINDING *ret = NULL; + BN_BLINDING **new_blindings; + uint8_t *new_blindings_inuse; + char overflow = 0; + + CRYPTO_MUTEX_lock_write(&rsa->lock); + + unsigned i; + for (i = 0; i < rsa->num_blindings; i++) { + if (rsa->blindings_inuse[i] == 0) { + rsa->blindings_inuse[i] = 1; + ret = rsa->blindings[i]; + *index_used = i; + break; + } + } + + if (ret != NULL) { + CRYPTO_MUTEX_unlock_write(&rsa->lock); + return ret; + } + + overflow = rsa->num_blindings >= MAX_BLINDINGS_PER_RSA; + + // We didn't find a free BN_BLINDING to use so increase the length of + // the arrays by one and use the newly created element. + + CRYPTO_MUTEX_unlock_write(&rsa->lock); + ret = BN_BLINDING_new(); + if (ret == NULL) { + return NULL; + } + + if (overflow) { + // We cannot add any more cached BN_BLINDINGs so we use |ret| + // and mark it for destruction in |rsa_blinding_release|. + *index_used = MAX_BLINDINGS_PER_RSA; + return ret; + } + + CRYPTO_MUTEX_lock_write(&rsa->lock); + + new_blindings = + OPENSSL_malloc(sizeof(BN_BLINDING *) * (rsa->num_blindings + 1)); + if (new_blindings == NULL) { + goto err1; + } + OPENSSL_memcpy(new_blindings, rsa->blindings, + sizeof(BN_BLINDING *) * rsa->num_blindings); + new_blindings[rsa->num_blindings] = ret; + + new_blindings_inuse = OPENSSL_malloc(rsa->num_blindings + 1); + if (new_blindings_inuse == NULL) { + goto err2; + } + OPENSSL_memcpy(new_blindings_inuse, rsa->blindings_inuse, rsa->num_blindings); + new_blindings_inuse[rsa->num_blindings] = 1; + *index_used = rsa->num_blindings; + + OPENSSL_free(rsa->blindings); + rsa->blindings = new_blindings; + OPENSSL_free(rsa->blindings_inuse); + rsa->blindings_inuse = new_blindings_inuse; + rsa->num_blindings++; + + CRYPTO_MUTEX_unlock_write(&rsa->lock); + return ret; + +err2: + OPENSSL_free(new_blindings); + +err1: + CRYPTO_MUTEX_unlock_write(&rsa->lock); + BN_BLINDING_free(ret); + return NULL; +} + +// rsa_blinding_release marks the cached BN_BLINDING at the given index as free +// for other threads to use. +static void rsa_blinding_release(RSA *rsa, BN_BLINDING *blinding, + unsigned blinding_index) { + if (blinding_index == MAX_BLINDINGS_PER_RSA) { + // This blinding wasn't cached. + BN_BLINDING_free(blinding); + return; + } + + CRYPTO_MUTEX_lock_write(&rsa->lock); + rsa->blindings_inuse[blinding_index] = 0; + CRYPTO_MUTEX_unlock_write(&rsa->lock); +} + +// signing +int rsa_default_sign_raw(RSA *rsa, size_t *out_len, uint8_t *out, + size_t max_out, const uint8_t *in, size_t in_len, + int padding) { + const unsigned rsa_size = RSA_size(rsa); + uint8_t *buf = NULL; + int i, ret = 0; + + if (max_out < rsa_size) { + OPENSSL_PUT_ERROR(RSA, RSA_R_OUTPUT_BUFFER_TOO_SMALL); + return 0; + } + + buf = OPENSSL_malloc(rsa_size); + if (buf == NULL) { + OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); + goto err; + } + + switch (padding) { + case RSA_PKCS1_PADDING: + i = RSA_padding_add_PKCS1_type_1(buf, rsa_size, in, in_len); + break; + case RSA_NO_PADDING: + i = RSA_padding_add_none(buf, rsa_size, in, in_len); + break; + default: + OPENSSL_PUT_ERROR(RSA, RSA_R_UNKNOWN_PADDING_TYPE); + goto err; + } + + if (i <= 0) { + goto err; + } + + if (!RSA_private_transform(rsa, out, buf, rsa_size)) { + goto err; + } + + *out_len = rsa_size; + ret = 1; + +err: + OPENSSL_free(buf); + + return ret; +} + +int rsa_default_decrypt(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out, + const uint8_t *in, size_t in_len, int padding) { + const unsigned rsa_size = RSA_size(rsa); + uint8_t *buf = NULL; + int ret = 0; + + if (max_out < rsa_size) { + OPENSSL_PUT_ERROR(RSA, RSA_R_OUTPUT_BUFFER_TOO_SMALL); + return 0; + } + + if (padding == RSA_NO_PADDING) { + buf = out; + } else { + // Allocate a temporary buffer to hold the padded plaintext. + buf = OPENSSL_malloc(rsa_size); + if (buf == NULL) { + OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); + goto err; + } + } + + if (in_len != rsa_size) { + OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_LEN_NOT_EQUAL_TO_MOD_LEN); + goto err; + } + + if (!RSA_private_transform(rsa, buf, in, rsa_size)) { + goto err; + } + + switch (padding) { + case RSA_PKCS1_PADDING: + ret = + RSA_padding_check_PKCS1_type_2(out, out_len, rsa_size, buf, rsa_size); + break; + case RSA_PKCS1_OAEP_PADDING: + // Use the default parameters: SHA-1 for both hashes and no label. + ret = RSA_padding_check_PKCS1_OAEP_mgf1(out, out_len, rsa_size, buf, + rsa_size, NULL, 0, NULL, NULL); + break; + case RSA_NO_PADDING: + *out_len = rsa_size; + ret = 1; + break; + default: + OPENSSL_PUT_ERROR(RSA, RSA_R_UNKNOWN_PADDING_TYPE); + goto err; + } + + if (!ret) { + OPENSSL_PUT_ERROR(RSA, RSA_R_PADDING_CHECK_FAILED); + } + +err: + if (padding != RSA_NO_PADDING) { + OPENSSL_free(buf); + } + + return ret; +} + +static int mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx); + +int RSA_verify_raw(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out, + const uint8_t *in, size_t in_len, int padding) { + if (rsa->n == NULL || rsa->e == NULL) { + OPENSSL_PUT_ERROR(RSA, RSA_R_VALUE_MISSING); + return 0; + } + + const unsigned rsa_size = RSA_size(rsa); + BIGNUM *f, *result; + + if (max_out < rsa_size) { + OPENSSL_PUT_ERROR(RSA, RSA_R_OUTPUT_BUFFER_TOO_SMALL); + return 0; + } + + if (in_len != rsa_size) { + OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_LEN_NOT_EQUAL_TO_MOD_LEN); + return 0; + } + + if (!check_modulus_and_exponent_sizes(rsa)) { + return 0; + } + + BN_CTX *ctx = BN_CTX_new(); + if (ctx == NULL) { + return 0; + } + + int ret = 0; + uint8_t *buf = NULL; + + BN_CTX_start(ctx); + f = BN_CTX_get(ctx); + result = BN_CTX_get(ctx); + if (f == NULL || result == NULL) { + OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (padding == RSA_NO_PADDING) { + buf = out; + } else { + // Allocate a temporary buffer to hold the padded plaintext. + buf = OPENSSL_malloc(rsa_size); + if (buf == NULL) { + OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); + goto err; + } + } + + if (BN_bin2bn(in, in_len, f) == NULL) { + goto err; + } + + if (BN_ucmp(f, rsa->n) >= 0) { + OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE); + goto err; + } + + if (!BN_MONT_CTX_set_locked(&rsa->mont_n, &rsa->lock, rsa->n, ctx) || + !BN_mod_exp_mont(result, f, rsa->e, &rsa->mont_n->N, ctx, rsa->mont_n)) { + goto err; + } + + if (!BN_bn2bin_padded(buf, rsa_size, result)) { + OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR); + goto err; + } + + switch (padding) { + case RSA_PKCS1_PADDING: + ret = + RSA_padding_check_PKCS1_type_1(out, out_len, rsa_size, buf, rsa_size); + break; + case RSA_NO_PADDING: + ret = 1; + *out_len = rsa_size; + break; + default: + OPENSSL_PUT_ERROR(RSA, RSA_R_UNKNOWN_PADDING_TYPE); + goto err; + } + + if (!ret) { + OPENSSL_PUT_ERROR(RSA, RSA_R_PADDING_CHECK_FAILED); + goto err; + } + +err: + BN_CTX_end(ctx); + BN_CTX_free(ctx); + if (buf != out) { + OPENSSL_free(buf); + } + return ret; +} + +int rsa_default_private_transform(RSA *rsa, uint8_t *out, const uint8_t *in, + size_t len) { + if (rsa->n == NULL || rsa->d == NULL) { + OPENSSL_PUT_ERROR(RSA, RSA_R_VALUE_MISSING); + return 0; + } + + BIGNUM *f, *result; + BN_CTX *ctx = NULL; + unsigned blinding_index = 0; + BN_BLINDING *blinding = NULL; + int ret = 0; + + ctx = BN_CTX_new(); + if (ctx == NULL) { + goto err; + } + BN_CTX_start(ctx); + f = BN_CTX_get(ctx); + result = BN_CTX_get(ctx); + + if (f == NULL || result == NULL) { + OPENSSL_PUT_ERROR(RSA, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (BN_bin2bn(in, len, f) == NULL) { + goto err; + } + + if (BN_ucmp(f, rsa->n) >= 0) { + // Usually the padding functions would catch this. + OPENSSL_PUT_ERROR(RSA, RSA_R_DATA_TOO_LARGE); + goto err; + } + + if (!freeze_private_key(rsa, ctx)) { + OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR); + goto err; + } + + const int do_blinding = (rsa->flags & RSA_FLAG_NO_BLINDING) == 0; + + if (rsa->e == NULL && do_blinding) { + // We cannot do blinding or verification without |e|, and continuing without + // those countermeasures is dangerous. However, the Java/Android RSA API + // requires support for keys where only |d| and |n| (and not |e|) are known. + // The callers that require that bad behavior set |RSA_FLAG_NO_BLINDING|. + OPENSSL_PUT_ERROR(RSA, RSA_R_NO_PUBLIC_EXPONENT); + goto err; + } + + if (do_blinding) { + blinding = rsa_blinding_get(rsa, &blinding_index, ctx); + if (blinding == NULL) { + OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR); + goto err; + } + if (!BN_BLINDING_convert(f, blinding, rsa->e, rsa->mont_n, ctx)) { + goto err; + } + } + + if (rsa->p != NULL && rsa->q != NULL && rsa->e != NULL && rsa->dmp1 != NULL && + rsa->dmq1 != NULL && rsa->iqmp != NULL) { + if (!mod_exp(result, f, rsa, ctx)) { + goto err; + } + } else if (!BN_mod_exp_mont_consttime(result, f, rsa->d_fixed, rsa->n, ctx, + rsa->mont_n)) { + goto err; + } + + // Verify the result to protect against fault attacks as described in the + // 1997 paper "On the Importance of Checking Cryptographic Protocols for + // Faults" by Dan Boneh, Richard A. DeMillo, and Richard J. Lipton. Some + // implementations do this only when the CRT is used, but we do it in all + // cases. Section 6 of the aforementioned paper describes an attack that + // works when the CRT isn't used. That attack is much less likely to succeed + // than the CRT attack, but there have likely been improvements since 1997. + // + // This check is cheap assuming |e| is small; it almost always is. + if (rsa->e != NULL) { + BIGNUM *vrfy = BN_CTX_get(ctx); + if (vrfy == NULL || + !BN_mod_exp_mont(vrfy, result, rsa->e, rsa->n, ctx, rsa->mont_n) || + !BN_equal_consttime(vrfy, f)) { + OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR); + goto err; + } + + } + + if (do_blinding && + !BN_BLINDING_invert(result, blinding, rsa->mont_n, ctx)) { + goto err; + } + + // The computation should have left |result| as a maximally-wide number, so + // that it and serializing does not leak information about the magnitude of + // the result. + // + // See Falko Stenzke, "Manger's Attack revisited", ICICS 2010. + assert(result->width == rsa->mont_n->N.width); + if (!BN_bn2bin_padded(out, len, result)) { + OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR); + goto err; + } + + ret = 1; + +err: + if (ctx != NULL) { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + if (blinding != NULL) { + rsa_blinding_release(rsa, blinding, blinding_index); + } + + return ret; +} + +// mod_montgomery sets |r| to |I| mod |p|. |I| must already be fully reduced +// modulo |p| times |q|. It returns one on success and zero on error. +static int mod_montgomery(BIGNUM *r, const BIGNUM *I, const BIGNUM *p, + const BN_MONT_CTX *mont_p, const BIGNUM *q, + BN_CTX *ctx) { + // Reducing in constant-time with Montgomery reduction requires I <= p * R. We + // have I < p * q, so this follows if q < R. In particular, this always holds + // if p and q are the same size, which is true for any RSA keys we or anyone + // sane generates. For other keys, we fall back to |BN_mod|. + if (!bn_less_than_montgomery_R(q, mont_p)) { + return BN_mod(r, I, p, ctx); + } + + if (// Reduce mod p with Montgomery reduction. This computes I * R^-1 mod p. + !BN_from_montgomery(r, I, mont_p, ctx) || + // Multiply by R^2 and do another Montgomery reduction to compute + // I * R^-1 * R^2 * R^-1 = I mod p. + !BN_to_montgomery(r, r, mont_p, ctx)) { + return 0; + } + + // By precomputing R^3 mod p (normally |BN_MONT_CTX| only uses R^2 mod p) and + // adjusting the API for |BN_mod_exp_mont_consttime|, we could instead compute + // I * R mod p here and save a reduction per prime. But this would require + // changing the RSAZ code and may not be worth it. Note that the RSAZ code + // uses a different radix, so it uses R' = 2^1044. There we'd actually want + // R^2 * R', and would futher benefit from a precomputed R'^2. It currently + // converts |mont_p->RR| to R'^2. + return 1; +} + +static int mod_exp(BIGNUM *r0, const BIGNUM *I, RSA *rsa, BN_CTX *ctx) { + assert(ctx != NULL); + + assert(rsa->n != NULL); + assert(rsa->e != NULL); + assert(rsa->d != NULL); + assert(rsa->p != NULL); + assert(rsa->q != NULL); + assert(rsa->dmp1 != NULL); + assert(rsa->dmq1 != NULL); + assert(rsa->iqmp != NULL); + + BIGNUM *r1, *m1; + int ret = 0; + + BN_CTX_start(ctx); + r1 = BN_CTX_get(ctx); + m1 = BN_CTX_get(ctx); + if (r1 == NULL || + m1 == NULL) { + goto err; + } + + if (!freeze_private_key(rsa, ctx)) { + goto err; + } + + // Implementing RSA with CRT in constant-time is sensitive to which prime is + // larger. Canonicalize fields so that |p| is the larger prime. + const BIGNUM *dmp1 = rsa->dmp1_fixed, *dmq1 = rsa->dmq1_fixed; + const BN_MONT_CTX *mont_p = rsa->mont_p, *mont_q = rsa->mont_q; + if (BN_cmp(rsa->p, rsa->q) < 0) { + mont_p = rsa->mont_q; + mont_q = rsa->mont_p; + dmp1 = rsa->dmq1_fixed; + dmq1 = rsa->dmp1_fixed; + } + + // Use the minimal-width versions of |n|, |p|, and |q|. Either works, but if + // someone gives us non-minimal values, these will be slightly more efficient + // on the non-Montgomery operations. + const BIGNUM *n = &rsa->mont_n->N; + const BIGNUM *p = &mont_p->N; + const BIGNUM *q = &mont_q->N; + + // This is a pre-condition for |mod_montgomery|. It was already checked by the + // caller. + assert(BN_ucmp(I, n) < 0); + + if (// |m1| is the result modulo |q|. + !mod_montgomery(r1, I, q, mont_q, p, ctx) || + !BN_mod_exp_mont_consttime(m1, r1, dmq1, q, ctx, mont_q) || + // |r0| is the result modulo |p|. + !mod_montgomery(r1, I, p, mont_p, q, ctx) || + !BN_mod_exp_mont_consttime(r0, r1, dmp1, p, ctx, mont_p) || + // Compute r0 = r0 - m1 mod p. |p| is the larger prime, so |m1| is already + // fully reduced mod |p|. + !bn_mod_sub_consttime(r0, r0, m1, p, ctx) || + // r0 = r0 * iqmp mod p. We use Montgomery multiplication to compute this + // in constant time. |inv_small_mod_large_mont| is in Montgomery form and + // r0 is not, so the result is taken out of Montgomery form. + !BN_mod_mul_montgomery(r0, r0, rsa->inv_small_mod_large_mont, mont_p, + ctx) || + // r0 = r0 * q + m1 gives the final result. Reducing modulo q gives m1, so + // it is correct mod p. Reducing modulo p gives (r0-m1)*iqmp*q + m1 = r0, + // so it is correct mod q. Finally, the result is bounded by [m1, n + m1), + // and the result is at least |m1|, so this must be the unique answer in + // [0, n). + !bn_mul_consttime(r0, r0, q, ctx) || + !bn_uadd_consttime(r0, r0, m1) || + // The result should be bounded by |n|, but fixed-width operations may + // bound the width slightly higher, so fix it. + !bn_resize_words(r0, n->width)) { + goto err; + } + + ret = 1; + +err: + BN_CTX_end(ctx); + return ret; +} + +static int ensure_bignum(BIGNUM **out) { + if (*out == NULL) { + *out = BN_new(); + } + return *out != NULL; +} + +// kBoringSSLRSASqrtTwo is the BIGNUM representation of ⌊2¹⁵³⁵×√2⌋. This is +// chosen to give enough precision for 3072-bit RSA, the largest key size FIPS +// specifies. Key sizes beyond this will round up. +// +// To verify this number, check that n² < 2³⁰⁷¹ < (n+1)², where n is value +// represented here. Note the components are listed in little-endian order. Here +// is some sample Python code to check: +// +// >>> TOBN = lambda a, b: a << 32 | b +// >>> l = [ ] +// >>> n = sum(a * 2**(64*i) for i, a in enumerate(l)) +// >>> n**2 < 2**3071 < (n+1)**2 +// True +const BN_ULONG kBoringSSLRSASqrtTwo[] = { + TOBN(0xdea06241, 0xf7aa81c2), TOBN(0xf6a1be3f, 0xca221307), + TOBN(0x332a5e9f, 0x7bda1ebf), TOBN(0x0104dc01, 0xfe32352f), + TOBN(0xb8cf341b, 0x6f8236c7), TOBN(0x4264dabc, 0xd528b651), + TOBN(0xf4d3a02c, 0xebc93e0c), TOBN(0x81394ab6, 0xd8fd0efd), + TOBN(0xeaa4a089, 0x9040ca4a), TOBN(0xf52f120f, 0x836e582e), + TOBN(0xcb2a6343, 0x31f3c84d), TOBN(0xc6d5a8a3, 0x8bb7e9dc), + TOBN(0x460abc72, 0x2f7c4e33), TOBN(0xcab1bc91, 0x1688458a), + TOBN(0x53059c60, 0x11bc337b), TOBN(0xd2202e87, 0x42af1f4e), + TOBN(0x78048736, 0x3dfa2768), TOBN(0x0f74a85e, 0x439c7b4a), + TOBN(0xa8b1fe6f, 0xdc83db39), TOBN(0x4afc8304, 0x3ab8a2c3), + TOBN(0xed17ac85, 0x83339915), TOBN(0x1d6f60ba, 0x893ba84c), + TOBN(0x597d89b3, 0x754abe9f), TOBN(0xb504f333, 0xf9de6484), +}; +const size_t kBoringSSLRSASqrtTwoLen = OPENSSL_ARRAY_SIZE(kBoringSSLRSASqrtTwo); + +// generate_prime sets |out| to a prime with length |bits| such that |out|-1 is +// relatively prime to |e|. If |p| is non-NULL, |out| will also not be close to +// |p|. |sqrt2| must be ⌊2^(bits-1)×√2⌋ (or a slightly overestimate for large +// sizes), and |pow2_bits_100| must be 2^(bits-100). +static int generate_prime(BIGNUM *out, int bits, const BIGNUM *e, + const BIGNUM *p, const BIGNUM *sqrt2, + const BIGNUM *pow2_bits_100, BN_CTX *ctx, + BN_GENCB *cb) { + if (bits < 128 || (bits % BN_BITS2) != 0) { + OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR); + return 0; + } + assert(BN_is_pow2(pow2_bits_100)); + assert(BN_is_bit_set(pow2_bits_100, bits - 100)); + + // See FIPS 186-4 appendix B.3.3, steps 4 and 5. Note |bits| here is nlen/2. + + // Use the limit from steps 4.7 and 5.8 for most values of |e|. When |e| is 3, + // the 186-4 limit is too low, so we use a higher one. Note this case is not + // reachable from |RSA_generate_key_fips|. + if (bits >= INT_MAX/32) { + OPENSSL_PUT_ERROR(RSA, RSA_R_MODULUS_TOO_LARGE); + return 0; + } + int limit = BN_is_word(e, 3) ? bits * 32 : bits * 5; + + int ret = 0, tries = 0, rand_tries = 0; + BN_CTX_start(ctx); + BIGNUM *tmp = BN_CTX_get(ctx); + if (tmp == NULL) { + goto err; + } + + for (;;) { + // Generate a random number of length |bits| where the bottom bit is set + // (steps 4.2, 4.3, 5.2 and 5.3) and the top bit is set (implied by the + // bound checked below in steps 4.4 and 5.5). + if (!BN_rand(out, bits, BN_RAND_TOP_ONE, BN_RAND_BOTTOM_ODD) || + !BN_GENCB_call(cb, BN_GENCB_GENERATED, rand_tries++)) { + goto err; + } + + if (p != NULL) { + // If |p| and |out| are too close, try again (step 5.4). + if (!bn_abs_sub_consttime(tmp, out, p, ctx)) { + goto err; + } + if (BN_cmp(tmp, pow2_bits_100) <= 0) { + continue; + } + } + + // If out < 2^(bits-1)×√2, try again (steps 4.4 and 5.5). This is equivalent + // to out <= ⌊2^(bits-1)×√2⌋, or out <= sqrt2 for FIPS key sizes. + // + // For larger keys, the comparison is approximate, leaning towards + // retrying. That is, we reject a negligible fraction of primes that are + // within the FIPS bound, but we will never accept a prime outside the + // bound, ensuring the resulting RSA key is the right size. + if (BN_cmp(out, sqrt2) <= 0) { + continue; + } + + // RSA key generation's bottleneck is discarding composites. If it fails + // trial division, do not bother computing a GCD or performing Rabin-Miller. + if (!bn_odd_number_is_obviously_composite(out)) { + // Check gcd(out-1, e) is one (steps 4.5 and 5.6). + int relatively_prime; + if (!BN_sub(tmp, out, BN_value_one()) || + !bn_is_relatively_prime(&relatively_prime, tmp, e, ctx)) { + goto err; + } + if (relatively_prime) { + // Test |out| for primality (steps 4.5.1 and 5.6.1). + int is_probable_prime; + if (!BN_primality_test(&is_probable_prime, out, BN_prime_checks, ctx, 0, + cb)) { + goto err; + } + if (is_probable_prime) { + ret = 1; + goto err; + } + } + } + + // If we've tried too many times to find a prime, abort (steps 4.7 and + // 5.8). + tries++; + if (tries >= limit) { + OPENSSL_PUT_ERROR(RSA, RSA_R_TOO_MANY_ITERATIONS); + goto err; + } + if (!BN_GENCB_call(cb, 2, tries)) { + goto err; + } + } + +err: + BN_CTX_end(ctx); + return ret; +} + +int RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e_value, BN_GENCB *cb) { + // See FIPS 186-4 appendix B.3. This function implements a generalized version + // of the FIPS algorithm. |RSA_generate_key_fips| performs additional checks + // for FIPS-compliant key generation. + + // Always generate RSA keys which are a multiple of 128 bits. Round |bits| + // down as needed. + bits &= ~127; + + // Reject excessively small keys. + if (bits < 256) { + OPENSSL_PUT_ERROR(RSA, RSA_R_KEY_SIZE_TOO_SMALL); + return 0; + } + + // Reject excessively large public exponents. Windows CryptoAPI and Go don't + // support values larger than 32 bits, so match their limits for generating + // keys. (|check_modulus_and_exponent_sizes| uses a slightly more conservative + // value, but we don't need to support generating such keys.) + // https://github.com/golang/go/issues/3161 + // https://msdn.microsoft.com/en-us/library/aa387685(VS.85).aspx + if (BN_num_bits(e_value) > 32) { + OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_E_VALUE); + return 0; + } + + int ret = 0; + int prime_bits = bits / 2; + BN_CTX *ctx = BN_CTX_new(); + if (ctx == NULL) { + goto bn_err; + } + BN_CTX_start(ctx); + BIGNUM *totient = BN_CTX_get(ctx); + BIGNUM *pm1 = BN_CTX_get(ctx); + BIGNUM *qm1 = BN_CTX_get(ctx); + BIGNUM *sqrt2 = BN_CTX_get(ctx); + BIGNUM *pow2_prime_bits_100 = BN_CTX_get(ctx); + BIGNUM *pow2_prime_bits = BN_CTX_get(ctx); + if (totient == NULL || pm1 == NULL || qm1 == NULL || sqrt2 == NULL || + pow2_prime_bits_100 == NULL || pow2_prime_bits == NULL || + !BN_set_bit(pow2_prime_bits_100, prime_bits - 100) || + !BN_set_bit(pow2_prime_bits, prime_bits)) { + goto bn_err; + } + + // We need the RSA components non-NULL. + if (!ensure_bignum(&rsa->n) || + !ensure_bignum(&rsa->d) || + !ensure_bignum(&rsa->e) || + !ensure_bignum(&rsa->p) || + !ensure_bignum(&rsa->q) || + !ensure_bignum(&rsa->dmp1) || + !ensure_bignum(&rsa->dmq1)) { + goto bn_err; + } + + if (!BN_copy(rsa->e, e_value)) { + goto bn_err; + } + + // Compute sqrt2 >= ⌊2^(prime_bits-1)×√2⌋. + if (!bn_set_words(sqrt2, kBoringSSLRSASqrtTwo, kBoringSSLRSASqrtTwoLen)) { + goto bn_err; + } + int sqrt2_bits = kBoringSSLRSASqrtTwoLen * BN_BITS2; + assert(sqrt2_bits == (int)BN_num_bits(sqrt2)); + if (sqrt2_bits > prime_bits) { + // For key sizes up to 3072 (prime_bits = 1536), this is exactly + // ⌊2^(prime_bits-1)×√2⌋. + if (!BN_rshift(sqrt2, sqrt2, sqrt2_bits - prime_bits)) { + goto bn_err; + } + } else if (prime_bits > sqrt2_bits) { + // For key sizes beyond 3072, this is approximate. We err towards retrying + // to ensure our key is the right size and round up. + if (!BN_add_word(sqrt2, 1) || + !BN_lshift(sqrt2, sqrt2, prime_bits - sqrt2_bits)) { + goto bn_err; + } + } + assert(prime_bits == (int)BN_num_bits(sqrt2)); + + do { + // Generate p and q, each of size |prime_bits|, using the steps outlined in + // appendix FIPS 186-4 appendix B.3.3. + if (!generate_prime(rsa->p, prime_bits, rsa->e, NULL, sqrt2, + pow2_prime_bits_100, ctx, cb) || + !BN_GENCB_call(cb, 3, 0) || + !generate_prime(rsa->q, prime_bits, rsa->e, rsa->p, sqrt2, + pow2_prime_bits_100, ctx, cb) || + !BN_GENCB_call(cb, 3, 1)) { + goto bn_err; + } + + if (BN_cmp(rsa->p, rsa->q) < 0) { + BIGNUM *tmp = rsa->p; + rsa->p = rsa->q; + rsa->q = tmp; + } + + // Calculate d = e^(-1) (mod lcm(p-1, q-1)), per FIPS 186-4. This differs + // from typical RSA implementations which use (p-1)*(q-1). + // + // Note this means the size of d might reveal information about p-1 and + // q-1. However, we do operations with Chinese Remainder Theorem, so we only + // use d (mod p-1) and d (mod q-1) as exponents. Using a minimal totient + // does not affect those two values. + int no_inverse; + if (!bn_usub_consttime(pm1, rsa->p, BN_value_one()) || + !bn_usub_consttime(qm1, rsa->q, BN_value_one()) || + !bn_lcm_consttime(totient, pm1, qm1, ctx) || + !bn_mod_inverse_consttime(rsa->d, &no_inverse, rsa->e, totient, ctx)) { + goto bn_err; + } + + // Retry if |rsa->d| <= 2^|prime_bits|. See appendix B.3.1's guidance on + // values for d. + } while (BN_cmp(rsa->d, pow2_prime_bits) <= 0); + + if (// Calculate n. + !bn_mul_consttime(rsa->n, rsa->p, rsa->q, ctx) || + // Calculate d mod (p-1). + !bn_div_consttime(NULL, rsa->dmp1, rsa->d, pm1, ctx) || + // Calculate d mod (q-1) + !bn_div_consttime(NULL, rsa->dmq1, rsa->d, qm1, ctx)) { + goto bn_err; + } + bn_set_minimal_width(rsa->n); + + // Sanity-check that |rsa->n| has the specified size. This is implied by + // |generate_prime|'s bounds. + if (BN_num_bits(rsa->n) != (unsigned)bits) { + OPENSSL_PUT_ERROR(RSA, ERR_R_INTERNAL_ERROR); + goto err; + } + + // Call |freeze_private_key| to compute the inverse of q mod p, by way of + // |rsa->mont_p|. + if (!freeze_private_key(rsa, ctx)) { + goto bn_err; + } + + // The key generation process is complex and thus error-prone. It could be + // disastrous to generate and then use a bad key so double-check that the key + // makes sense. + if (!RSA_check_key(rsa)) { + OPENSSL_PUT_ERROR(RSA, RSA_R_INTERNAL_ERROR); + goto err; + } + + ret = 1; + +bn_err: + if (!ret) { + OPENSSL_PUT_ERROR(RSA, ERR_LIB_BN); + } +err: + if (ctx != NULL) { + BN_CTX_end(ctx); + BN_CTX_free(ctx); + } + return ret; +} + +int RSA_generate_key_fips(RSA *rsa, int bits, BN_GENCB *cb) { + // FIPS 186-4 allows 2048-bit and 3072-bit RSA keys (1024-bit and 1536-bit + // primes, respectively) with the prime generation method we use. + if (bits != 2048 && bits != 3072) { + OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_RSA_PARAMETERS); + return 0; + } + + BIGNUM *e = BN_new(); + int ret = e != NULL && + BN_set_word(e, RSA_F4) && + RSA_generate_key_ex(rsa, bits, e, cb) && + RSA_check_fips(rsa); + BN_free(e); + return ret; +} + +DEFINE_METHOD_FUNCTION(RSA_METHOD, RSA_default_method) { + // All of the methods are NULL to make it easier for the compiler/linker to + // drop unused functions. The wrapper functions will select the appropriate + // |rsa_default_*| implementation. + OPENSSL_memset(out, 0, sizeof(RSA_METHOD)); + out->common.is_static = 1; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/self_check/self_check.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/self_check/self_check.c new file mode 100644 index 0000000..e21636a --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/self_check/self_check.c @@ -0,0 +1,581 @@ +/* Copyright (c) 2017, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../../internal.h" +#include "../ec/internal.h" +#include "../rand/internal.h" + + +// MSVC wants to put a NUL byte at the end of non-char arrays and so cannot +// compile this. +#if !defined(_MSC_VER) + +static void hexdump(const uint8_t *in, size_t len) { + for (size_t i = 0; i < len; i++) { + printf("%02x", in[i]); + } +} + +static int check_test(const void *expected, const void *actual, + size_t expected_len, const char *name) { + if (OPENSSL_memcmp(actual, expected, expected_len) != 0) { + printf("%s failed.\nExpected: ", name); + hexdump(expected, expected_len); + printf("\nCalculated: "); + hexdump(actual, expected_len); + printf("\n"); + return 0; + } + return 1; +} + +static int set_bignum(BIGNUM **out, const uint8_t *in, size_t len) { + *out = BN_bin2bn(in, len, NULL); + return *out != NULL; +} + +static RSA *self_test_rsa_key(void) { + static const uint8_t kN[] = { + 0xd3, 0x3a, 0x62, 0x9f, 0x07, 0x77, 0xb0, 0x18, 0xf3, 0xff, 0xfe, 0xcc, + 0xc9, 0xa2, 0xc2, 0x3a, 0xa6, 0x1d, 0xd8, 0xf0, 0x26, 0x5b, 0x38, 0x90, + 0x17, 0x48, 0x15, 0xce, 0x21, 0xcd, 0xd6, 0x62, 0x99, 0xe2, 0xd7, 0xda, + 0x40, 0x80, 0x3c, 0xad, 0x18, 0xb7, 0x26, 0xe9, 0x30, 0x8a, 0x23, 0x3f, + 0x68, 0x9a, 0x9c, 0x31, 0x34, 0x91, 0x99, 0x06, 0x11, 0x36, 0xb2, 0x9e, + 0x3a, 0xd0, 0xbc, 0xb9, 0x93, 0x4e, 0xb8, 0x72, 0xa1, 0x9f, 0xb6, 0x8c, + 0xd5, 0x17, 0x1f, 0x7e, 0xaa, 0x75, 0xbb, 0xdf, 0xa1, 0x70, 0x48, 0xc4, + 0xec, 0x9a, 0x51, 0xed, 0x41, 0xc9, 0x74, 0xc0, 0x3e, 0x1e, 0x85, 0x2f, + 0xbe, 0x34, 0xc7, 0x65, 0x34, 0x8b, 0x4d, 0x55, 0x4b, 0xe1, 0x45, 0x54, + 0x0d, 0x75, 0x7e, 0x89, 0x4d, 0x0c, 0xf6, 0x33, 0xe5, 0xfc, 0xfb, 0x56, + 0x1b, 0xf2, 0x39, 0x9d, 0xe0, 0xff, 0x55, 0xcf, 0x02, 0x05, 0xb9, 0x74, + 0xd2, 0x91, 0xfc, 0x87, 0xe1, 0xbb, 0x97, 0x2a, 0xe4, 0xdd, 0x20, 0xc0, + 0x38, 0x47, 0xc0, 0x76, 0x3f, 0xa1, 0x9b, 0x5c, 0x20, 0xff, 0xff, 0xc7, + 0x49, 0x3b, 0x4c, 0xaf, 0x99, 0xa6, 0x3e, 0x82, 0x5c, 0x58, 0x27, 0xce, + 0x01, 0x03, 0xc3, 0x16, 0x35, 0x20, 0xe9, 0xf0, 0x15, 0x7a, 0x41, 0xd5, + 0x1f, 0x52, 0xea, 0xdf, 0xad, 0x4c, 0xbb, 0x0d, 0xcb, 0x04, 0x91, 0xb0, + 0x95, 0xa8, 0xce, 0x25, 0xfd, 0xd2, 0x62, 0x47, 0x77, 0xee, 0x13, 0xf1, + 0x48, 0x72, 0x9e, 0xd9, 0x2d, 0xe6, 0x5f, 0xa4, 0xc6, 0x9e, 0x5a, 0xb2, + 0xc6, 0xa2, 0xf7, 0x0a, 0x16, 0x17, 0xae, 0x6b, 0x1c, 0x30, 0x7c, 0x63, + 0x08, 0x83, 0xe7, 0x43, 0xec, 0x54, 0x5e, 0x2c, 0x08, 0x0b, 0x5e, 0x46, + 0xa7, 0x10, 0x93, 0x43, 0x53, 0x4e, 0xe3, 0x16, 0x73, 0x55, 0xce, 0xf2, + 0x94, 0xc0, 0xbe, 0xb3, + }; + static const uint8_t kE[] = {0x01, 0x00, 0x01}; // 65537 + static const uint8_t kD[] = { + 0x2f, 0x2c, 0x1e, 0xd2, 0x3d, 0x2c, 0xb1, 0x9b, 0x21, 0x02, 0xce, 0xb8, + 0x95, 0x5f, 0x4f, 0xd9, 0x21, 0x38, 0x11, 0x36, 0xb0, 0x9a, 0x36, 0xab, + 0x97, 0x47, 0x75, 0xf7, 0x2e, 0xfd, 0x75, 0x1f, 0x58, 0x16, 0x9c, 0xf6, + 0x14, 0xe9, 0x8e, 0xa3, 0x69, 0x9d, 0x9d, 0x86, 0xfe, 0x5c, 0x1b, 0x3b, + 0x11, 0xf5, 0x55, 0x64, 0x77, 0xc4, 0xfc, 0x53, 0xaa, 0x8c, 0x78, 0x9f, + 0x75, 0xab, 0x20, 0x3a, 0xa1, 0x77, 0x37, 0x22, 0x02, 0x8e, 0x54, 0x8a, + 0x67, 0x1c, 0x5e, 0xe0, 0x3e, 0xd9, 0x44, 0x37, 0xd1, 0x29, 0xee, 0x56, + 0x6c, 0x30, 0x9a, 0x93, 0x4d, 0xd9, 0xdb, 0xc5, 0x03, 0x1a, 0x75, 0xcc, + 0x0f, 0xc2, 0x61, 0xb5, 0x6c, 0x62, 0x9f, 0xc6, 0xa8, 0xc7, 0x8a, 0x60, + 0x17, 0x11, 0x62, 0x4c, 0xef, 0x74, 0x31, 0x97, 0xad, 0x89, 0x2d, 0xe8, + 0x31, 0x1d, 0x8b, 0x58, 0x82, 0xe3, 0x03, 0x1a, 0x6b, 0xdf, 0x3f, 0x3e, + 0xa4, 0x27, 0x19, 0xef, 0x46, 0x7a, 0x90, 0xdf, 0xa7, 0xe7, 0xc9, 0x66, + 0xab, 0x41, 0x1d, 0x65, 0x78, 0x1c, 0x18, 0x40, 0x5c, 0xd6, 0x87, 0xb5, + 0xea, 0x29, 0x44, 0xb3, 0xf5, 0xb3, 0xd2, 0x4f, 0xce, 0x88, 0x78, 0x49, + 0x27, 0x4e, 0x0b, 0x30, 0x85, 0xfb, 0x73, 0xfd, 0x8b, 0x32, 0x15, 0xee, + 0x1f, 0xc9, 0x0e, 0x89, 0xb9, 0x43, 0x2f, 0xe9, 0x60, 0x8d, 0xda, 0xae, + 0x2b, 0x30, 0x99, 0xee, 0x88, 0x81, 0x20, 0x7b, 0x4a, 0xc3, 0x18, 0xf2, + 0x94, 0x02, 0x79, 0x94, 0xaa, 0x65, 0xd9, 0x1b, 0x45, 0x2a, 0xac, 0x6e, + 0x30, 0x48, 0x57, 0xea, 0xbe, 0x79, 0x7d, 0xfc, 0x67, 0xaa, 0x47, 0xc0, + 0xf7, 0x52, 0xfd, 0x0b, 0x63, 0x4e, 0x3d, 0x2e, 0xcc, 0x36, 0xa0, 0xdb, + 0x92, 0x0b, 0xa9, 0x1b, 0xeb, 0xc2, 0xd5, 0x08, 0xd3, 0x85, 0x87, 0xf8, + 0x5d, 0x1a, 0xf6, 0xc1, + }; + static const uint8_t kP[] = { + 0xf7, 0x06, 0xa3, 0x98, 0x8a, 0x52, 0xf8, 0x63, 0x68, 0x27, 0x4f, 0x68, + 0x7f, 0x34, 0xec, 0x8e, 0x5d, 0xf8, 0x30, 0x92, 0xb3, 0x62, 0x4c, 0xeb, + 0xdb, 0x19, 0x6b, 0x09, 0xc5, 0xa3, 0xf0, 0xbb, 0xff, 0x0f, 0xc2, 0xd4, + 0x9b, 0xc9, 0x54, 0x4f, 0xb9, 0xf9, 0xe1, 0x4c, 0xf0, 0xe3, 0x4c, 0x90, + 0xda, 0x7a, 0x01, 0xc2, 0x9f, 0xc4, 0xc8, 0x8e, 0xb1, 0x1e, 0x93, 0x75, + 0x75, 0xc6, 0x13, 0x25, 0xc3, 0xee, 0x3b, 0xcc, 0xb8, 0x72, 0x6c, 0x49, + 0xb0, 0x09, 0xfb, 0xab, 0x44, 0xeb, 0x4d, 0x40, 0xf0, 0x61, 0x6b, 0xe5, + 0xe6, 0xfe, 0x3e, 0x0a, 0x77, 0x26, 0x39, 0x76, 0x3d, 0x4c, 0x3e, 0x9b, + 0x5b, 0xc0, 0xaf, 0xa2, 0x58, 0x76, 0xb0, 0xe9, 0xda, 0x7f, 0x0e, 0x78, + 0xc9, 0x76, 0x49, 0x5c, 0xfa, 0xb3, 0xb0, 0x15, 0x4b, 0x41, 0xc7, 0x27, + 0xa4, 0x75, 0x28, 0x5c, 0x30, 0x69, 0x50, 0x29, + }; + static const uint8_t kQ[] = { + 0xda, 0xe6, 0xd2, 0xbb, 0x44, 0xff, 0x4f, 0xdf, 0x57, 0xc1, 0x11, 0xa3, + 0x51, 0xba, 0x17, 0x89, 0x4c, 0x01, 0xc0, 0x0c, 0x97, 0x34, 0x50, 0xcf, + 0x32, 0x1e, 0xc0, 0xbd, 0x7b, 0x35, 0xb5, 0x6a, 0x26, 0xcc, 0xea, 0x4c, + 0x8e, 0x87, 0x4a, 0x67, 0x8b, 0xd3, 0xe5, 0x4f, 0x3a, 0x60, 0x48, 0x59, + 0x04, 0x93, 0x39, 0xd7, 0x7c, 0xfb, 0x19, 0x1a, 0x34, 0xd5, 0xe8, 0xaf, + 0xe7, 0x22, 0x2c, 0x0d, 0xc2, 0x91, 0x69, 0xb6, 0xe9, 0x2a, 0xe9, 0x1c, + 0x4c, 0x6e, 0x8f, 0x40, 0xf5, 0xa8, 0x3e, 0x82, 0x69, 0x69, 0xbe, 0x9f, + 0x7d, 0x5c, 0x7f, 0x92, 0x78, 0x17, 0xa3, 0x6d, 0x41, 0x2d, 0x72, 0xed, + 0x3f, 0x71, 0xfa, 0x97, 0xb4, 0x63, 0xe4, 0x4f, 0xd9, 0x46, 0x03, 0xfb, + 0x00, 0xeb, 0x30, 0x70, 0xb9, 0x51, 0xd9, 0x0a, 0xd2, 0xf8, 0x50, 0xd4, + 0xfb, 0x43, 0x84, 0xf8, 0xac, 0x58, 0xc3, 0x7b, + }; + static const uint8_t kDModPMinusOne[] = { + 0xf5, 0x50, 0x8f, 0x88, 0x7d, 0xdd, 0xb5, 0xb4, 0x2a, 0x8b, 0xd7, 0x4d, + 0x23, 0xfe, 0xaf, 0xe9, 0x16, 0x22, 0xd2, 0x41, 0xed, 0x88, 0xf2, 0x70, + 0xcb, 0x4d, 0xeb, 0xc1, 0x71, 0x97, 0xc4, 0x0b, 0x3e, 0x5a, 0x2d, 0x96, + 0xab, 0xfa, 0xfd, 0x12, 0x8b, 0xd3, 0x3e, 0x4e, 0x05, 0x6f, 0x04, 0xeb, + 0x59, 0x3c, 0x0e, 0xa1, 0x73, 0xbe, 0x9d, 0x99, 0x2f, 0x05, 0xf9, 0x54, + 0x8d, 0x98, 0x1e, 0x0d, 0xc4, 0x0c, 0xc3, 0x30, 0x23, 0xff, 0xe5, 0xd0, + 0x2b, 0xd5, 0x4e, 0x2b, 0xa0, 0xae, 0xb8, 0x32, 0x84, 0x45, 0x8b, 0x3c, + 0x6d, 0xf0, 0x10, 0x36, 0x9e, 0x6a, 0xc4, 0x67, 0xca, 0xa9, 0xfc, 0x06, + 0x96, 0xd0, 0xbc, 0xda, 0xd1, 0x55, 0x55, 0x8d, 0x77, 0x21, 0xf4, 0x82, + 0x39, 0x37, 0x91, 0xd5, 0x97, 0x56, 0x78, 0xc8, 0x3c, 0xcb, 0x5e, 0xf6, + 0xdc, 0x58, 0x48, 0xb3, 0x7c, 0x94, 0x29, 0x39, + }; + static const uint8_t kDModQMinusOne[] = { + 0x64, 0x65, 0xbd, 0x7d, 0x1a, 0x96, 0x26, 0xa1, 0xfe, 0xf3, 0x94, 0x0d, + 0x5d, 0xec, 0x85, 0xe2, 0xf8, 0xb3, 0x4c, 0xcb, 0xf9, 0x85, 0x8b, 0x12, + 0x9c, 0xa0, 0x32, 0x32, 0x35, 0x92, 0x5a, 0x94, 0x47, 0x1b, 0x70, 0xd2, + 0x90, 0x04, 0x49, 0x01, 0xd8, 0xc5, 0xe4, 0xc4, 0x43, 0xb7, 0xe9, 0x36, + 0xba, 0xbc, 0x73, 0xa8, 0xfb, 0xaf, 0x86, 0xc1, 0xd8, 0x3d, 0xcb, 0xac, + 0xf1, 0xcb, 0x60, 0x7d, 0x27, 0x21, 0xde, 0x64, 0x7f, 0xe8, 0xa8, 0x65, + 0xcc, 0x40, 0x60, 0xff, 0xa0, 0x2b, 0xfc, 0x0f, 0x80, 0x1d, 0x79, 0xca, + 0x58, 0x8a, 0xd6, 0x0f, 0xed, 0x78, 0x9a, 0x02, 0x00, 0x04, 0xc2, 0x53, + 0x41, 0xe8, 0x1a, 0xd0, 0xfd, 0x71, 0x5b, 0x43, 0xac, 0x19, 0x4a, 0xb6, + 0x12, 0xa3, 0xcb, 0xe1, 0xc7, 0x7d, 0x5c, 0x98, 0x74, 0x4e, 0x63, 0x74, + 0x6b, 0x91, 0x7a, 0x29, 0x3b, 0x92, 0xb2, 0x85, + }; + static const uint8_t kQInverseModP[] = { + 0xd0, 0xde, 0x19, 0xda, 0x1e, 0xa2, 0xd8, 0x8f, 0x1c, 0x92, 0x73, 0xb0, + 0xc9, 0x90, 0xc7, 0xf5, 0xec, 0xc5, 0x89, 0x01, 0x05, 0x78, 0x11, 0x2d, + 0x74, 0x34, 0x44, 0xad, 0xd5, 0xf7, 0xa4, 0xfe, 0x9f, 0x25, 0x4d, 0x0b, + 0x92, 0xe3, 0xb8, 0x7d, 0xd3, 0xfd, 0xa5, 0xca, 0x95, 0x60, 0xa3, 0xf9, + 0x55, 0x42, 0x14, 0xb2, 0x45, 0x51, 0x9f, 0x73, 0x88, 0x43, 0x8a, 0xd1, + 0x65, 0x9e, 0xd1, 0xf7, 0x82, 0x2a, 0x2a, 0x8d, 0x70, 0x56, 0xe3, 0xef, + 0xc9, 0x0e, 0x2a, 0x2c, 0x15, 0xaf, 0x7f, 0x97, 0x81, 0x66, 0xf3, 0xb5, + 0x00, 0xa9, 0x26, 0xcc, 0x1e, 0xc2, 0x98, 0xdd, 0xd3, 0x37, 0x06, 0x79, + 0xb3, 0x60, 0x58, 0x79, 0x99, 0x3f, 0xa3, 0x15, 0x1f, 0x31, 0xe3, 0x11, + 0x88, 0x4c, 0x35, 0x57, 0xfa, 0x79, 0xd7, 0xd8, 0x72, 0xee, 0x73, 0x95, + 0x89, 0x29, 0xc7, 0x05, 0x27, 0x68, 0x90, 0x15, + }; + + RSA *rsa = RSA_new(); + if (rsa == NULL || + !set_bignum(&rsa->n, kN, sizeof(kN)) || + !set_bignum(&rsa->e, kE, sizeof(kE)) || + !set_bignum(&rsa->d, kD, sizeof(kD)) || + !set_bignum(&rsa->p, kP, sizeof(kP)) || + !set_bignum(&rsa->q, kQ, sizeof(kQ)) || + !set_bignum(&rsa->dmp1, kDModPMinusOne, sizeof(kDModPMinusOne)) || + !set_bignum(&rsa->dmq1, kDModQMinusOne, sizeof(kDModQMinusOne)) || + !set_bignum(&rsa->iqmp, kQInverseModP, sizeof(kQInverseModP))) { + RSA_free(rsa); + return NULL; + } + + return rsa; +} + +static EC_KEY *self_test_ecdsa_key(void) { + static const uint8_t kQx[] = { + 0xc8, 0x15, 0x61, 0xec, 0xf2, 0xe5, 0x4e, 0xde, 0xfe, 0x66, 0x17, + 0xdb, 0x1c, 0x7a, 0x34, 0xa7, 0x07, 0x44, 0xdd, 0xb2, 0x61, 0xf2, + 0x69, 0xb8, 0x3d, 0xac, 0xfc, 0xd2, 0xad, 0xe5, 0xa6, 0x81, + }; + static const uint8_t kQy[] = { + 0xe0, 0xe2, 0xaf, 0xa3, 0xf9, 0xb6, 0xab, 0xe4, 0xc6, 0x98, 0xef, + 0x64, 0x95, 0xf1, 0xbe, 0x49, 0xa3, 0x19, 0x6c, 0x50, 0x56, 0xac, + 0xb3, 0x76, 0x3f, 0xe4, 0x50, 0x7e, 0xec, 0x59, 0x6e, 0x88, + }; + static const uint8_t kD[] = { + 0xc6, 0xc1, 0xaa, 0xda, 0x15, 0xb0, 0x76, 0x61, 0xf8, 0x14, 0x2c, + 0x6c, 0xaf, 0x0f, 0xdb, 0x24, 0x1a, 0xff, 0x2e, 0xfe, 0x46, 0xc0, + 0x93, 0x8b, 0x74, 0xf2, 0xbc, 0xc5, 0x30, 0x52, 0xb0, 0x77, + }; + + EC_KEY *ec_key = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); + BIGNUM *qx = BN_bin2bn(kQx, sizeof(kQx), NULL); + BIGNUM *qy = BN_bin2bn(kQy, sizeof(kQy), NULL); + BIGNUM *d = BN_bin2bn(kD, sizeof(kD), NULL); + if (ec_key == NULL || qx == NULL || qy == NULL || d == NULL || + !EC_KEY_set_public_key_affine_coordinates(ec_key, qx, qy) || + !EC_KEY_set_private_key(ec_key, d)) { + EC_KEY_free(ec_key); + ec_key = NULL; + } + + BN_free(qx); + BN_free(qy); + BN_free(d); + return ec_key; +} + +int BORINGSSL_self_test(void) { + static const uint8_t kAESKey[16] = "BoringCrypto Key"; + static const uint8_t kAESIV[16] = {0}; + static const uint8_t kPlaintext[64] = + "BoringCryptoModule FIPS KAT Encryption and Decryption Plaintext!"; + static const uint8_t kAESCBCCiphertext[64] = { + 0x87, 0x2d, 0x98, 0xc2, 0xcc, 0x31, 0x5b, 0x41, 0xe0, 0xfa, 0x7b, + 0x0a, 0x71, 0xc0, 0x42, 0xbf, 0x4f, 0x61, 0xd0, 0x0d, 0x58, 0x8c, + 0xf7, 0x05, 0xfb, 0x94, 0x89, 0xd3, 0xbc, 0xaa, 0x1a, 0x50, 0x45, + 0x1f, 0xc3, 0x8c, 0xb8, 0x98, 0x86, 0xa3, 0xe3, 0x6c, 0xfc, 0xad, + 0x3a, 0xb5, 0x59, 0x27, 0x7d, 0x21, 0x07, 0xca, 0x4c, 0x1d, 0x55, + 0x34, 0xdd, 0x5a, 0x2d, 0xc4, 0xb4, 0xf5, 0xa8, +#if !defined(BORINGSSL_FIPS_BREAK_AES_CBC) + 0x35 +#else + 0x00 +#endif + }; + static const uint8_t kAESGCMCiphertext[80] = { + 0x4a, 0xd8, 0xe7, 0x7d, 0x78, 0xd7, 0x7d, 0x5e, 0xb2, 0x11, 0xb6, 0xc9, + 0xa4, 0xbc, 0xb2, 0xae, 0xbe, 0x93, 0xd1, 0xb7, 0xfe, 0x65, 0xc1, 0x82, + 0x2a, 0xb6, 0x71, 0x5f, 0x1a, 0x7c, 0xe0, 0x1b, 0x2b, 0xe2, 0x53, 0xfa, + 0xa0, 0x47, 0xfa, 0xd7, 0x8f, 0xb1, 0x4a, 0xc4, 0xdc, 0x89, 0xf9, 0xb4, + 0x14, 0x4d, 0xde, 0x95, 0xea, 0x29, 0x69, 0x76, 0x81, 0xa3, 0x5c, 0x33, + 0xd8, 0x37, 0xd8, 0xfa, 0x47, 0x19, 0x46, 0x2f, 0xf1, 0x90, 0xb7, 0x61, + 0x8f, 0x6f, 0xdd, 0x31, 0x3f, 0x6a, 0x64, +#if !defined(BORINGSSL_FIPS_BREAK_AES_GCM) + 0x0d +#else + 0x00 +#endif + }; + static const DES_cblock kDESKey1 = {"BCMDESK1"}; + static const DES_cblock kDESKey2 = {"BCMDESK2"}; + static const DES_cblock kDESKey3 = {"BCMDESK3"}; + static const DES_cblock kDESIV = {"BCMDESIV"}; + static const uint8_t kDESCiphertext[64] = { + 0xa4, 0x30, 0x7a, 0x4c, 0x1f, 0x60, 0x16, 0xd7, 0x4f, 0x41, 0xe1, + 0xbb, 0x27, 0xc4, 0x27, 0x37, 0xd4, 0x7f, 0xb9, 0x10, 0xf8, 0xbc, + 0xaf, 0x93, 0x91, 0xb8, 0x88, 0x24, 0xb1, 0xf6, 0xf8, 0xbd, 0x31, + 0x96, 0x06, 0x76, 0xde, 0x32, 0xcd, 0x29, 0x29, 0xba, 0x70, 0x5f, + 0xea, 0xc0, 0xcb, 0xde, 0xc7, 0x75, 0x90, 0xe0, 0x0f, 0x5e, 0x2c, + 0x0d, 0x49, 0x20, 0xd5, 0x30, 0x83, 0xf8, 0x08, +#if !defined(BORINGSSL_FIPS_BREAK_DES) + 0x5a +#else + 0x00 +#endif + }; + static const uint8_t kPlaintextSHA1[20] = { + 0xc6, 0xf8, 0xc9, 0x63, 0x1c, 0x14, 0x23, 0x62, 0x9b, 0xbd, + 0x55, 0x82, 0xf4, 0xd6, 0x1d, 0xf2, 0xab, 0x7d, 0xc8, +#if !defined(BORINGSSL_FIPS_BREAK_SHA_1) + 0x28 +#else + 0x00 +#endif + }; + static const uint8_t kPlaintextSHA256[32] = { + 0x37, 0xbd, 0x70, 0x53, 0x72, 0xfc, 0xd4, 0x03, 0x79, 0x70, 0xfb, + 0x06, 0x95, 0xb1, 0x2a, 0x82, 0x48, 0xe1, 0x3e, 0xf2, 0x33, 0xfb, + 0xef, 0x29, 0x81, 0x22, 0x45, 0x40, 0x43, 0x70, 0xce, +#if !defined(BORINGSSL_FIPS_BREAK_SHA_256) + 0x0f +#else + 0x00 +#endif + }; + static const uint8_t kPlaintextSHA512[64] = { + 0x08, 0x6a, 0x1c, 0x84, 0x61, 0x9d, 0x8e, 0xb3, 0xc0, 0x97, 0x4e, + 0xa1, 0x9f, 0x9c, 0xdc, 0xaf, 0x3b, 0x5c, 0x31, 0xf0, 0xf2, 0x74, + 0xc3, 0xbd, 0x6e, 0xd6, 0x1e, 0xb2, 0xbb, 0x34, 0x74, 0x72, 0x5c, + 0x51, 0x29, 0x8b, 0x87, 0x3a, 0xa3, 0xf2, 0x25, 0x23, 0xd4, 0x1c, + 0x82, 0x1b, 0xfe, 0xd3, 0xc6, 0xee, 0xb5, 0xd6, 0xaf, 0x07, 0x7b, + 0x98, 0xca, 0xa7, 0x01, 0xf3, 0x94, 0xf3, 0x68, +#if !defined(BORINGSSL_FIPS_BREAK_SHA_512) + 0x14 +#else + 0x00 +#endif + }; + static const uint8_t kRSASignature[256] = { + 0x62, 0x66, 0x4b, 0xe3, 0xb1, 0xd2, 0x83, 0xf1, 0xa8, 0x56, 0x2b, 0x33, + 0x60, 0x1e, 0xdb, 0x1e, 0x06, 0xf7, 0xa7, 0x1e, 0xa8, 0xef, 0x03, 0x4d, + 0x0c, 0xf6, 0x83, 0x75, 0x7a, 0xf0, 0x14, 0xc7, 0xe2, 0x94, 0x3a, 0xb5, + 0x67, 0x56, 0xa5, 0x48, 0x7f, 0x3a, 0xa5, 0xbf, 0xf7, 0x1d, 0x44, 0xa6, + 0x34, 0xed, 0x9b, 0xd6, 0x51, 0xaa, 0x2c, 0x4e, 0xce, 0x60, 0x5f, 0xe9, + 0x0e, 0xd5, 0xcd, 0xeb, 0x23, 0x27, 0xf8, 0xfb, 0x45, 0xe5, 0x34, 0x63, + 0x77, 0x7f, 0x2e, 0x80, 0xcf, 0x9d, 0x2e, 0xfc, 0xe2, 0x50, 0x75, 0x29, + 0x46, 0xf4, 0xaf, 0x91, 0xed, 0x36, 0xe1, 0x5e, 0xef, 0x66, 0xa1, 0xff, + 0x27, 0xfc, 0x87, 0x7e, 0x60, 0x84, 0x0f, 0x54, 0x51, 0x56, 0x0f, 0x68, + 0x99, 0xc0, 0x3f, 0xeb, 0xa5, 0xa0, 0x46, 0xb0, 0x86, 0x02, 0xb0, 0xc8, + 0xe8, 0x46, 0x13, 0x06, 0xcd, 0xb7, 0x8a, 0xd0, 0x3b, 0x46, 0xd0, 0x14, + 0x64, 0x53, 0x9b, 0x5b, 0x5e, 0x02, 0x45, 0xba, 0x6e, 0x7e, 0x0a, 0xb9, + 0x9e, 0x62, 0xb7, 0xd5, 0x7a, 0x87, 0xea, 0xd3, 0x24, 0xa5, 0xef, 0xb3, + 0xdc, 0x05, 0x9c, 0x04, 0x60, 0x4b, 0xde, 0xa8, 0x90, 0x08, 0x7b, 0x6a, + 0x5f, 0xb4, 0x3f, 0xda, 0xc5, 0x1f, 0x6e, 0xd6, 0x15, 0xde, 0x65, 0xa4, + 0x6e, 0x62, 0x9d, 0x8f, 0xa8, 0xbe, 0x86, 0xf6, 0x09, 0x90, 0x40, 0xa5, + 0xf4, 0x23, 0xc5, 0xf6, 0x38, 0x86, 0x0d, 0x1c, 0xed, 0x4a, 0x0a, 0xae, + 0xa4, 0x26, 0xc2, 0x2e, 0xd3, 0x13, 0x66, 0x61, 0xea, 0x35, 0x01, 0x0e, + 0x13, 0xda, 0x78, 0x20, 0xae, 0x59, 0x5f, 0x9b, 0xa9, 0x6c, 0xf9, 0x1b, + 0xdf, 0x76, 0x53, 0xc8, 0xa7, 0xf5, 0x63, 0x6d, 0xf3, 0xff, 0xfd, 0xaf, + 0x75, 0x4b, 0xac, 0x67, 0xb1, 0x3c, 0xbf, 0x5e, 0xde, 0x73, 0x02, 0x6d, + 0xd2, 0x0c, 0xb1, +#if !defined(BORINGSSL_FIPS_BREAK_RSA_SIG) + 0x64 +#else + 0x00 +#endif + }; + const uint8_t kDRBGEntropy[48] = + "BCM Known Answer Test DBRG Initial Entropy "; + const uint8_t kDRBGPersonalization[18] = "BCMPersonalization"; + const uint8_t kDRBGAD[16] = "BCM DRBG KAT AD "; + const uint8_t kDRBGOutput[64] = { + 0x1d, 0x63, 0xdf, 0x05, 0x51, 0x49, 0x22, 0x46, 0xcd, 0x9b, 0xc5, + 0xbb, 0xf1, 0x5d, 0x44, 0xae, 0x13, 0x78, 0xb1, 0xe4, 0x7c, 0xf1, + 0x96, 0x33, 0x3d, 0x60, 0xb6, 0x29, 0xd4, 0xbb, 0x6b, 0x44, 0xf9, + 0xef, 0xd9, 0xf4, 0xa2, 0xba, 0x48, 0xea, 0x39, 0x75, 0x59, 0x32, + 0xf7, 0x31, 0x2c, 0x98, 0x14, 0x2b, 0x49, 0xdf, 0x02, 0xb6, 0x5d, + 0x71, 0x09, 0x50, 0xdb, 0x23, 0xdb, 0xe5, 0x22, +#if !defined(BORINGSSL_FIPS_BREAK_DRBG) + 0x95 +#else + 0x00 +#endif + }; + const uint8_t kDRBGEntropy2[48] = + "BCM Known Answer Test DBRG Reseed Entropy "; + const uint8_t kDRBGReseedOutput[64] = { + 0xa4, 0x77, 0x05, 0xdb, 0x14, 0x11, 0x76, 0x71, 0x42, 0x5b, 0xd8, + 0xd7, 0xa5, 0x4f, 0x8b, 0x39, 0xf2, 0x10, 0x4a, 0x50, 0x5b, 0xa2, + 0xc8, 0xf0, 0xbb, 0x3e, 0xa1, 0xa5, 0x90, 0x7d, 0x54, 0xd9, 0xc6, + 0xb0, 0x96, 0xc0, 0x2b, 0x7e, 0x9b, 0xc9, 0xa1, 0xdd, 0x78, 0x2e, + 0xd5, 0xa8, 0x66, 0x16, 0xbd, 0x18, 0x3c, 0xf2, 0xaa, 0x7a, 0x2b, + 0x37, 0xf9, 0xab, 0x35, 0x64, 0x15, 0x01, 0x3f, 0xc4, + }; + const uint8_t kECDSASigR[32] = { + 0x67, 0x80, 0xc5, 0xfc, 0x70, 0x27, 0x5e, 0x2c, 0x70, 0x61, 0xa0, + 0xe7, 0x87, 0x7b, 0xb1, 0x74, 0xde, 0xad, 0xeb, 0x98, 0x87, 0x02, + 0x7f, 0x3f, 0xa8, 0x36, 0x54, 0x15, 0x8b, 0xa7, 0xf5, +#if !defined(BORINGSSL_FIPS_BREAK_ECDSA_SIG) + 0x0c, +#else + 0x00, +#endif + }; + const uint8_t kECDSASigS[32] = { + 0xa5, 0x93, 0xe0, 0x23, 0x91, 0xe7, 0x4b, 0x8d, 0x77, 0x25, 0xa6, + 0xba, 0x4d, 0xd9, 0x86, 0x77, 0xda, 0x7d, 0x8f, 0xef, 0xc4, 0x1a, + 0xf0, 0xcc, 0x81, 0xe5, 0xea, 0x3f, 0xc2, 0x41, 0x7f, 0xd8, + }; + + EVP_AEAD_CTX aead_ctx; + EVP_AEAD_CTX_zero(&aead_ctx); + RSA *rsa_key = NULL; + EC_KEY *ec_key = NULL; + ECDSA_SIG *sig = NULL; + int ret = 0; + + AES_KEY aes_key; + uint8_t aes_iv[16]; + uint8_t output[256]; + + // AES-CBC Encryption KAT + memcpy(aes_iv, kAESIV, sizeof(kAESIV)); + if (AES_set_encrypt_key(kAESKey, 8 * sizeof(kAESKey), &aes_key) != 0) { + goto err; + } + AES_cbc_encrypt(kPlaintext, output, sizeof(kPlaintext), &aes_key, aes_iv, + AES_ENCRYPT); + if (!check_test(kAESCBCCiphertext, output, sizeof(kAESCBCCiphertext), + "AES-CBC Encryption KAT")) { + goto err; + } + + // AES-CBC Decryption KAT + memcpy(aes_iv, kAESIV, sizeof(kAESIV)); + if (AES_set_decrypt_key(kAESKey, 8 * sizeof(kAESKey), &aes_key) != 0) { + goto err; + } + AES_cbc_encrypt(kAESCBCCiphertext, output, sizeof(kAESCBCCiphertext), + &aes_key, aes_iv, AES_DECRYPT); + if (!check_test(kPlaintext, output, sizeof(kPlaintext), + "AES-CBC Decryption KAT")) { + goto err; + } + + size_t out_len; + uint8_t nonce[EVP_AEAD_MAX_NONCE_LENGTH]; + OPENSSL_memset(nonce, 0, sizeof(nonce)); + if (!EVP_AEAD_CTX_init(&aead_ctx, EVP_aead_aes_128_gcm(), kAESKey, + sizeof(kAESKey), 0, NULL)) { + goto err; + } + + // AES-GCM Encryption KAT + if (!EVP_AEAD_CTX_seal(&aead_ctx, output, &out_len, sizeof(output), nonce, + EVP_AEAD_nonce_length(EVP_aead_aes_128_gcm()), + kPlaintext, sizeof(kPlaintext), NULL, 0) || + !check_test(kAESGCMCiphertext, output, sizeof(kAESGCMCiphertext), + "AES-GCM Encryption KAT")) { + goto err; + } + + // AES-GCM Decryption KAT + if (!EVP_AEAD_CTX_open(&aead_ctx, output, &out_len, sizeof(output), nonce, + EVP_AEAD_nonce_length(EVP_aead_aes_128_gcm()), + kAESGCMCiphertext, sizeof(kAESGCMCiphertext), NULL, + 0) || + !check_test(kPlaintext, output, sizeof(kPlaintext), + "AES-GCM Decryption KAT")) { + goto err; + } + + DES_key_schedule des1, des2, des3; + DES_cblock des_iv; + DES_set_key(&kDESKey1, &des1); + DES_set_key(&kDESKey2, &des2); + DES_set_key(&kDESKey3, &des3); + + // 3DES Encryption KAT + memcpy(&des_iv, &kDESIV, sizeof(des_iv)); + DES_ede3_cbc_encrypt(kPlaintext, output, sizeof(kPlaintext), &des1, &des2, + &des3, &des_iv, DES_ENCRYPT); + if (!check_test(kDESCiphertext, output, sizeof(kDESCiphertext), + "3DES Encryption KAT")) { + goto err; + } + + // 3DES Decryption KAT + memcpy(&des_iv, &kDESIV, sizeof(des_iv)); + DES_ede3_cbc_encrypt(kDESCiphertext, output, sizeof(kDESCiphertext), &des1, + &des2, &des3, &des_iv, DES_DECRYPT); + if (!check_test(kPlaintext, output, sizeof(kPlaintext), + "3DES Decryption KAT")) { + goto err; + } + + // SHA-1 KAT + SHA1(kPlaintext, sizeof(kPlaintext), output); + if (!check_test(kPlaintextSHA1, output, sizeof(kPlaintextSHA1), + "SHA-1 KAT")) { + goto err; + } + + // SHA-256 KAT + SHA256(kPlaintext, sizeof(kPlaintext), output); + if (!check_test(kPlaintextSHA256, output, sizeof(kPlaintextSHA256), + "SHA-256 KAT")) { + goto err; + } + + // SHA-512 KAT + SHA512(kPlaintext, sizeof(kPlaintext), output); + if (!check_test(kPlaintextSHA512, output, sizeof(kPlaintextSHA512), + "SHA-512 KAT")) { + goto err; + } + + rsa_key = self_test_rsa_key(); + if (rsa_key == NULL) { + printf("RSA KeyGen failed\n"); + goto err; + } + + // RSA Sign KAT + unsigned sig_len; + + // Disable blinding for the power-on tests because it's not needed and + // triggers an entropy draw. + rsa_key->flags |= RSA_FLAG_NO_BLINDING; + + if (!RSA_sign(NID_sha256, kPlaintextSHA256, sizeof(kPlaintextSHA256), output, + &sig_len, rsa_key) || + !check_test(kRSASignature, output, sizeof(kRSASignature), + "RSA Sign KAT")) { + goto err; + } + + // RSA Verify KAT + if (!RSA_verify(NID_sha256, kPlaintextSHA256, sizeof(kPlaintextSHA256), + kRSASignature, sizeof(kRSASignature), rsa_key)) { + printf("RSA Verify KAT failed.\n"); + goto err; + } + + ec_key = self_test_ecdsa_key(); + if (ec_key == NULL) { + printf("ECDSA KeyGen failed\n"); + goto err; + } + + // ECDSA Sign/Verify PWCT + + // The 'k' value for ECDSA is fixed to avoid an entropy draw. + ec_key->fixed_k = BN_new(); + if (ec_key->fixed_k == NULL || + !BN_set_word(ec_key->fixed_k, 42)) { + printf("Out of memory\n"); + goto err; + } + + sig = ECDSA_do_sign(kPlaintextSHA256, sizeof(kPlaintextSHA256), ec_key); + + uint8_t ecdsa_r_bytes[sizeof(kECDSASigR)]; + uint8_t ecdsa_s_bytes[sizeof(kECDSASigS)]; + if (sig == NULL || + BN_num_bytes(sig->r) != sizeof(ecdsa_r_bytes) || + !BN_bn2bin(sig->r, ecdsa_r_bytes) || + BN_num_bytes(sig->s) != sizeof(ecdsa_s_bytes) || + !BN_bn2bin(sig->s, ecdsa_s_bytes) || + !check_test(kECDSASigR, ecdsa_r_bytes, sizeof(kECDSASigR), "ECDSA R") || + !check_test(kECDSASigS, ecdsa_s_bytes, sizeof(kECDSASigS), "ECDSA S")) { + printf("ECDSA KAT failed.\n"); + goto err; + } + + // DBRG KAT + CTR_DRBG_STATE drbg; + if (!CTR_DRBG_init(&drbg, kDRBGEntropy, kDRBGPersonalization, + sizeof(kDRBGPersonalization)) || + !CTR_DRBG_generate(&drbg, output, sizeof(kDRBGOutput), kDRBGAD, + sizeof(kDRBGAD)) || + !check_test(kDRBGOutput, output, sizeof(kDRBGOutput), + "DBRG Generate KAT") || + !CTR_DRBG_reseed(&drbg, kDRBGEntropy2, kDRBGAD, sizeof(kDRBGAD)) || + !CTR_DRBG_generate(&drbg, output, sizeof(kDRBGReseedOutput), kDRBGAD, + sizeof(kDRBGAD)) || + !check_test(kDRBGReseedOutput, output, sizeof(kDRBGReseedOutput), + "DRBG Reseed KAT")) { + goto err; + } + CTR_DRBG_clear(&drbg); + + CTR_DRBG_STATE kZeroDRBG; + memset(&kZeroDRBG, 0, sizeof(kZeroDRBG)); + if (!check_test(&kZeroDRBG, &drbg, sizeof(drbg), "DRBG Clear KAT")) { + goto err; + } + + ret = 1; + +err: + EVP_AEAD_CTX_cleanup(&aead_ctx); + RSA_free(rsa_key); + EC_KEY_free(ec_key); + ECDSA_SIG_free(sig); + + return ret; +} + +#endif // !_MSC_VER diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/self_check/self_check.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/self_check/self_check.c.grpc_back new file mode 100644 index 0000000..468fd02 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/self_check/self_check.c.grpc_back @@ -0,0 +1,581 @@ +/* Copyright (c) 2017, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../../internal.h" +#include "../ec/internal.h" +#include "../rand/internal.h" + + +// MSVC wants to put a NUL byte at the end of non-char arrays and so cannot +// compile this. +#if !defined(_MSC_VER) + +static void hexdump(const uint8_t *in, size_t len) { + for (size_t i = 0; i < len; i++) { + printf("%02x", in[i]); + } +} + +static int check_test(const void *expected, const void *actual, + size_t expected_len, const char *name) { + if (OPENSSL_memcmp(actual, expected, expected_len) != 0) { + printf("%s failed.\nExpected: ", name); + hexdump(expected, expected_len); + printf("\nCalculated: "); + hexdump(actual, expected_len); + printf("\n"); + return 0; + } + return 1; +} + +static int set_bignum(BIGNUM **out, const uint8_t *in, size_t len) { + *out = BN_bin2bn(in, len, NULL); + return *out != NULL; +} + +static RSA *self_test_rsa_key(void) { + static const uint8_t kN[] = { + 0xd3, 0x3a, 0x62, 0x9f, 0x07, 0x77, 0xb0, 0x18, 0xf3, 0xff, 0xfe, 0xcc, + 0xc9, 0xa2, 0xc2, 0x3a, 0xa6, 0x1d, 0xd8, 0xf0, 0x26, 0x5b, 0x38, 0x90, + 0x17, 0x48, 0x15, 0xce, 0x21, 0xcd, 0xd6, 0x62, 0x99, 0xe2, 0xd7, 0xda, + 0x40, 0x80, 0x3c, 0xad, 0x18, 0xb7, 0x26, 0xe9, 0x30, 0x8a, 0x23, 0x3f, + 0x68, 0x9a, 0x9c, 0x31, 0x34, 0x91, 0x99, 0x06, 0x11, 0x36, 0xb2, 0x9e, + 0x3a, 0xd0, 0xbc, 0xb9, 0x93, 0x4e, 0xb8, 0x72, 0xa1, 0x9f, 0xb6, 0x8c, + 0xd5, 0x17, 0x1f, 0x7e, 0xaa, 0x75, 0xbb, 0xdf, 0xa1, 0x70, 0x48, 0xc4, + 0xec, 0x9a, 0x51, 0xed, 0x41, 0xc9, 0x74, 0xc0, 0x3e, 0x1e, 0x85, 0x2f, + 0xbe, 0x34, 0xc7, 0x65, 0x34, 0x8b, 0x4d, 0x55, 0x4b, 0xe1, 0x45, 0x54, + 0x0d, 0x75, 0x7e, 0x89, 0x4d, 0x0c, 0xf6, 0x33, 0xe5, 0xfc, 0xfb, 0x56, + 0x1b, 0xf2, 0x39, 0x9d, 0xe0, 0xff, 0x55, 0xcf, 0x02, 0x05, 0xb9, 0x74, + 0xd2, 0x91, 0xfc, 0x87, 0xe1, 0xbb, 0x97, 0x2a, 0xe4, 0xdd, 0x20, 0xc0, + 0x38, 0x47, 0xc0, 0x76, 0x3f, 0xa1, 0x9b, 0x5c, 0x20, 0xff, 0xff, 0xc7, + 0x49, 0x3b, 0x4c, 0xaf, 0x99, 0xa6, 0x3e, 0x82, 0x5c, 0x58, 0x27, 0xce, + 0x01, 0x03, 0xc3, 0x16, 0x35, 0x20, 0xe9, 0xf0, 0x15, 0x7a, 0x41, 0xd5, + 0x1f, 0x52, 0xea, 0xdf, 0xad, 0x4c, 0xbb, 0x0d, 0xcb, 0x04, 0x91, 0xb0, + 0x95, 0xa8, 0xce, 0x25, 0xfd, 0xd2, 0x62, 0x47, 0x77, 0xee, 0x13, 0xf1, + 0x48, 0x72, 0x9e, 0xd9, 0x2d, 0xe6, 0x5f, 0xa4, 0xc6, 0x9e, 0x5a, 0xb2, + 0xc6, 0xa2, 0xf7, 0x0a, 0x16, 0x17, 0xae, 0x6b, 0x1c, 0x30, 0x7c, 0x63, + 0x08, 0x83, 0xe7, 0x43, 0xec, 0x54, 0x5e, 0x2c, 0x08, 0x0b, 0x5e, 0x46, + 0xa7, 0x10, 0x93, 0x43, 0x53, 0x4e, 0xe3, 0x16, 0x73, 0x55, 0xce, 0xf2, + 0x94, 0xc0, 0xbe, 0xb3, + }; + static const uint8_t kE[] = {0x01, 0x00, 0x01}; // 65537 + static const uint8_t kD[] = { + 0x2f, 0x2c, 0x1e, 0xd2, 0x3d, 0x2c, 0xb1, 0x9b, 0x21, 0x02, 0xce, 0xb8, + 0x95, 0x5f, 0x4f, 0xd9, 0x21, 0x38, 0x11, 0x36, 0xb0, 0x9a, 0x36, 0xab, + 0x97, 0x47, 0x75, 0xf7, 0x2e, 0xfd, 0x75, 0x1f, 0x58, 0x16, 0x9c, 0xf6, + 0x14, 0xe9, 0x8e, 0xa3, 0x69, 0x9d, 0x9d, 0x86, 0xfe, 0x5c, 0x1b, 0x3b, + 0x11, 0xf5, 0x55, 0x64, 0x77, 0xc4, 0xfc, 0x53, 0xaa, 0x8c, 0x78, 0x9f, + 0x75, 0xab, 0x20, 0x3a, 0xa1, 0x77, 0x37, 0x22, 0x02, 0x8e, 0x54, 0x8a, + 0x67, 0x1c, 0x5e, 0xe0, 0x3e, 0xd9, 0x44, 0x37, 0xd1, 0x29, 0xee, 0x56, + 0x6c, 0x30, 0x9a, 0x93, 0x4d, 0xd9, 0xdb, 0xc5, 0x03, 0x1a, 0x75, 0xcc, + 0x0f, 0xc2, 0x61, 0xb5, 0x6c, 0x62, 0x9f, 0xc6, 0xa8, 0xc7, 0x8a, 0x60, + 0x17, 0x11, 0x62, 0x4c, 0xef, 0x74, 0x31, 0x97, 0xad, 0x89, 0x2d, 0xe8, + 0x31, 0x1d, 0x8b, 0x58, 0x82, 0xe3, 0x03, 0x1a, 0x6b, 0xdf, 0x3f, 0x3e, + 0xa4, 0x27, 0x19, 0xef, 0x46, 0x7a, 0x90, 0xdf, 0xa7, 0xe7, 0xc9, 0x66, + 0xab, 0x41, 0x1d, 0x65, 0x78, 0x1c, 0x18, 0x40, 0x5c, 0xd6, 0x87, 0xb5, + 0xea, 0x29, 0x44, 0xb3, 0xf5, 0xb3, 0xd2, 0x4f, 0xce, 0x88, 0x78, 0x49, + 0x27, 0x4e, 0x0b, 0x30, 0x85, 0xfb, 0x73, 0xfd, 0x8b, 0x32, 0x15, 0xee, + 0x1f, 0xc9, 0x0e, 0x89, 0xb9, 0x43, 0x2f, 0xe9, 0x60, 0x8d, 0xda, 0xae, + 0x2b, 0x30, 0x99, 0xee, 0x88, 0x81, 0x20, 0x7b, 0x4a, 0xc3, 0x18, 0xf2, + 0x94, 0x02, 0x79, 0x94, 0xaa, 0x65, 0xd9, 0x1b, 0x45, 0x2a, 0xac, 0x6e, + 0x30, 0x48, 0x57, 0xea, 0xbe, 0x79, 0x7d, 0xfc, 0x67, 0xaa, 0x47, 0xc0, + 0xf7, 0x52, 0xfd, 0x0b, 0x63, 0x4e, 0x3d, 0x2e, 0xcc, 0x36, 0xa0, 0xdb, + 0x92, 0x0b, 0xa9, 0x1b, 0xeb, 0xc2, 0xd5, 0x08, 0xd3, 0x85, 0x87, 0xf8, + 0x5d, 0x1a, 0xf6, 0xc1, + }; + static const uint8_t kP[] = { + 0xf7, 0x06, 0xa3, 0x98, 0x8a, 0x52, 0xf8, 0x63, 0x68, 0x27, 0x4f, 0x68, + 0x7f, 0x34, 0xec, 0x8e, 0x5d, 0xf8, 0x30, 0x92, 0xb3, 0x62, 0x4c, 0xeb, + 0xdb, 0x19, 0x6b, 0x09, 0xc5, 0xa3, 0xf0, 0xbb, 0xff, 0x0f, 0xc2, 0xd4, + 0x9b, 0xc9, 0x54, 0x4f, 0xb9, 0xf9, 0xe1, 0x4c, 0xf0, 0xe3, 0x4c, 0x90, + 0xda, 0x7a, 0x01, 0xc2, 0x9f, 0xc4, 0xc8, 0x8e, 0xb1, 0x1e, 0x93, 0x75, + 0x75, 0xc6, 0x13, 0x25, 0xc3, 0xee, 0x3b, 0xcc, 0xb8, 0x72, 0x6c, 0x49, + 0xb0, 0x09, 0xfb, 0xab, 0x44, 0xeb, 0x4d, 0x40, 0xf0, 0x61, 0x6b, 0xe5, + 0xe6, 0xfe, 0x3e, 0x0a, 0x77, 0x26, 0x39, 0x76, 0x3d, 0x4c, 0x3e, 0x9b, + 0x5b, 0xc0, 0xaf, 0xa2, 0x58, 0x76, 0xb0, 0xe9, 0xda, 0x7f, 0x0e, 0x78, + 0xc9, 0x76, 0x49, 0x5c, 0xfa, 0xb3, 0xb0, 0x15, 0x4b, 0x41, 0xc7, 0x27, + 0xa4, 0x75, 0x28, 0x5c, 0x30, 0x69, 0x50, 0x29, + }; + static const uint8_t kQ[] = { + 0xda, 0xe6, 0xd2, 0xbb, 0x44, 0xff, 0x4f, 0xdf, 0x57, 0xc1, 0x11, 0xa3, + 0x51, 0xba, 0x17, 0x89, 0x4c, 0x01, 0xc0, 0x0c, 0x97, 0x34, 0x50, 0xcf, + 0x32, 0x1e, 0xc0, 0xbd, 0x7b, 0x35, 0xb5, 0x6a, 0x26, 0xcc, 0xea, 0x4c, + 0x8e, 0x87, 0x4a, 0x67, 0x8b, 0xd3, 0xe5, 0x4f, 0x3a, 0x60, 0x48, 0x59, + 0x04, 0x93, 0x39, 0xd7, 0x7c, 0xfb, 0x19, 0x1a, 0x34, 0xd5, 0xe8, 0xaf, + 0xe7, 0x22, 0x2c, 0x0d, 0xc2, 0x91, 0x69, 0xb6, 0xe9, 0x2a, 0xe9, 0x1c, + 0x4c, 0x6e, 0x8f, 0x40, 0xf5, 0xa8, 0x3e, 0x82, 0x69, 0x69, 0xbe, 0x9f, + 0x7d, 0x5c, 0x7f, 0x92, 0x78, 0x17, 0xa3, 0x6d, 0x41, 0x2d, 0x72, 0xed, + 0x3f, 0x71, 0xfa, 0x97, 0xb4, 0x63, 0xe4, 0x4f, 0xd9, 0x46, 0x03, 0xfb, + 0x00, 0xeb, 0x30, 0x70, 0xb9, 0x51, 0xd9, 0x0a, 0xd2, 0xf8, 0x50, 0xd4, + 0xfb, 0x43, 0x84, 0xf8, 0xac, 0x58, 0xc3, 0x7b, + }; + static const uint8_t kDModPMinusOne[] = { + 0xf5, 0x50, 0x8f, 0x88, 0x7d, 0xdd, 0xb5, 0xb4, 0x2a, 0x8b, 0xd7, 0x4d, + 0x23, 0xfe, 0xaf, 0xe9, 0x16, 0x22, 0xd2, 0x41, 0xed, 0x88, 0xf2, 0x70, + 0xcb, 0x4d, 0xeb, 0xc1, 0x71, 0x97, 0xc4, 0x0b, 0x3e, 0x5a, 0x2d, 0x96, + 0xab, 0xfa, 0xfd, 0x12, 0x8b, 0xd3, 0x3e, 0x4e, 0x05, 0x6f, 0x04, 0xeb, + 0x59, 0x3c, 0x0e, 0xa1, 0x73, 0xbe, 0x9d, 0x99, 0x2f, 0x05, 0xf9, 0x54, + 0x8d, 0x98, 0x1e, 0x0d, 0xc4, 0x0c, 0xc3, 0x30, 0x23, 0xff, 0xe5, 0xd0, + 0x2b, 0xd5, 0x4e, 0x2b, 0xa0, 0xae, 0xb8, 0x32, 0x84, 0x45, 0x8b, 0x3c, + 0x6d, 0xf0, 0x10, 0x36, 0x9e, 0x6a, 0xc4, 0x67, 0xca, 0xa9, 0xfc, 0x06, + 0x96, 0xd0, 0xbc, 0xda, 0xd1, 0x55, 0x55, 0x8d, 0x77, 0x21, 0xf4, 0x82, + 0x39, 0x37, 0x91, 0xd5, 0x97, 0x56, 0x78, 0xc8, 0x3c, 0xcb, 0x5e, 0xf6, + 0xdc, 0x58, 0x48, 0xb3, 0x7c, 0x94, 0x29, 0x39, + }; + static const uint8_t kDModQMinusOne[] = { + 0x64, 0x65, 0xbd, 0x7d, 0x1a, 0x96, 0x26, 0xa1, 0xfe, 0xf3, 0x94, 0x0d, + 0x5d, 0xec, 0x85, 0xe2, 0xf8, 0xb3, 0x4c, 0xcb, 0xf9, 0x85, 0x8b, 0x12, + 0x9c, 0xa0, 0x32, 0x32, 0x35, 0x92, 0x5a, 0x94, 0x47, 0x1b, 0x70, 0xd2, + 0x90, 0x04, 0x49, 0x01, 0xd8, 0xc5, 0xe4, 0xc4, 0x43, 0xb7, 0xe9, 0x36, + 0xba, 0xbc, 0x73, 0xa8, 0xfb, 0xaf, 0x86, 0xc1, 0xd8, 0x3d, 0xcb, 0xac, + 0xf1, 0xcb, 0x60, 0x7d, 0x27, 0x21, 0xde, 0x64, 0x7f, 0xe8, 0xa8, 0x65, + 0xcc, 0x40, 0x60, 0xff, 0xa0, 0x2b, 0xfc, 0x0f, 0x80, 0x1d, 0x79, 0xca, + 0x58, 0x8a, 0xd6, 0x0f, 0xed, 0x78, 0x9a, 0x02, 0x00, 0x04, 0xc2, 0x53, + 0x41, 0xe8, 0x1a, 0xd0, 0xfd, 0x71, 0x5b, 0x43, 0xac, 0x19, 0x4a, 0xb6, + 0x12, 0xa3, 0xcb, 0xe1, 0xc7, 0x7d, 0x5c, 0x98, 0x74, 0x4e, 0x63, 0x74, + 0x6b, 0x91, 0x7a, 0x29, 0x3b, 0x92, 0xb2, 0x85, + }; + static const uint8_t kQInverseModP[] = { + 0xd0, 0xde, 0x19, 0xda, 0x1e, 0xa2, 0xd8, 0x8f, 0x1c, 0x92, 0x73, 0xb0, + 0xc9, 0x90, 0xc7, 0xf5, 0xec, 0xc5, 0x89, 0x01, 0x05, 0x78, 0x11, 0x2d, + 0x74, 0x34, 0x44, 0xad, 0xd5, 0xf7, 0xa4, 0xfe, 0x9f, 0x25, 0x4d, 0x0b, + 0x92, 0xe3, 0xb8, 0x7d, 0xd3, 0xfd, 0xa5, 0xca, 0x95, 0x60, 0xa3, 0xf9, + 0x55, 0x42, 0x14, 0xb2, 0x45, 0x51, 0x9f, 0x73, 0x88, 0x43, 0x8a, 0xd1, + 0x65, 0x9e, 0xd1, 0xf7, 0x82, 0x2a, 0x2a, 0x8d, 0x70, 0x56, 0xe3, 0xef, + 0xc9, 0x0e, 0x2a, 0x2c, 0x15, 0xaf, 0x7f, 0x97, 0x81, 0x66, 0xf3, 0xb5, + 0x00, 0xa9, 0x26, 0xcc, 0x1e, 0xc2, 0x98, 0xdd, 0xd3, 0x37, 0x06, 0x79, + 0xb3, 0x60, 0x58, 0x79, 0x99, 0x3f, 0xa3, 0x15, 0x1f, 0x31, 0xe3, 0x11, + 0x88, 0x4c, 0x35, 0x57, 0xfa, 0x79, 0xd7, 0xd8, 0x72, 0xee, 0x73, 0x95, + 0x89, 0x29, 0xc7, 0x05, 0x27, 0x68, 0x90, 0x15, + }; + + RSA *rsa = RSA_new(); + if (rsa == NULL || + !set_bignum(&rsa->n, kN, sizeof(kN)) || + !set_bignum(&rsa->e, kE, sizeof(kE)) || + !set_bignum(&rsa->d, kD, sizeof(kD)) || + !set_bignum(&rsa->p, kP, sizeof(kP)) || + !set_bignum(&rsa->q, kQ, sizeof(kQ)) || + !set_bignum(&rsa->dmp1, kDModPMinusOne, sizeof(kDModPMinusOne)) || + !set_bignum(&rsa->dmq1, kDModQMinusOne, sizeof(kDModQMinusOne)) || + !set_bignum(&rsa->iqmp, kQInverseModP, sizeof(kQInverseModP))) { + RSA_free(rsa); + return NULL; + } + + return rsa; +} + +static EC_KEY *self_test_ecdsa_key(void) { + static const uint8_t kQx[] = { + 0xc8, 0x15, 0x61, 0xec, 0xf2, 0xe5, 0x4e, 0xde, 0xfe, 0x66, 0x17, + 0xdb, 0x1c, 0x7a, 0x34, 0xa7, 0x07, 0x44, 0xdd, 0xb2, 0x61, 0xf2, + 0x69, 0xb8, 0x3d, 0xac, 0xfc, 0xd2, 0xad, 0xe5, 0xa6, 0x81, + }; + static const uint8_t kQy[] = { + 0xe0, 0xe2, 0xaf, 0xa3, 0xf9, 0xb6, 0xab, 0xe4, 0xc6, 0x98, 0xef, + 0x64, 0x95, 0xf1, 0xbe, 0x49, 0xa3, 0x19, 0x6c, 0x50, 0x56, 0xac, + 0xb3, 0x76, 0x3f, 0xe4, 0x50, 0x7e, 0xec, 0x59, 0x6e, 0x88, + }; + static const uint8_t kD[] = { + 0xc6, 0xc1, 0xaa, 0xda, 0x15, 0xb0, 0x76, 0x61, 0xf8, 0x14, 0x2c, + 0x6c, 0xaf, 0x0f, 0xdb, 0x24, 0x1a, 0xff, 0x2e, 0xfe, 0x46, 0xc0, + 0x93, 0x8b, 0x74, 0xf2, 0xbc, 0xc5, 0x30, 0x52, 0xb0, 0x77, + }; + + EC_KEY *ec_key = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); + BIGNUM *qx = BN_bin2bn(kQx, sizeof(kQx), NULL); + BIGNUM *qy = BN_bin2bn(kQy, sizeof(kQy), NULL); + BIGNUM *d = BN_bin2bn(kD, sizeof(kD), NULL); + if (ec_key == NULL || qx == NULL || qy == NULL || d == NULL || + !EC_KEY_set_public_key_affine_coordinates(ec_key, qx, qy) || + !EC_KEY_set_private_key(ec_key, d)) { + EC_KEY_free(ec_key); + ec_key = NULL; + } + + BN_free(qx); + BN_free(qy); + BN_free(d); + return ec_key; +} + +int BORINGSSL_self_test(void) { + static const uint8_t kAESKey[16] = "BoringCrypto Key"; + static const uint8_t kAESIV[16] = {0}; + static const uint8_t kPlaintext[64] = + "BoringCryptoModule FIPS KAT Encryption and Decryption Plaintext!"; + static const uint8_t kAESCBCCiphertext[64] = { + 0x87, 0x2d, 0x98, 0xc2, 0xcc, 0x31, 0x5b, 0x41, 0xe0, 0xfa, 0x7b, + 0x0a, 0x71, 0xc0, 0x42, 0xbf, 0x4f, 0x61, 0xd0, 0x0d, 0x58, 0x8c, + 0xf7, 0x05, 0xfb, 0x94, 0x89, 0xd3, 0xbc, 0xaa, 0x1a, 0x50, 0x45, + 0x1f, 0xc3, 0x8c, 0xb8, 0x98, 0x86, 0xa3, 0xe3, 0x6c, 0xfc, 0xad, + 0x3a, 0xb5, 0x59, 0x27, 0x7d, 0x21, 0x07, 0xca, 0x4c, 0x1d, 0x55, + 0x34, 0xdd, 0x5a, 0x2d, 0xc4, 0xb4, 0xf5, 0xa8, +#if !defined(BORINGSSL_FIPS_BREAK_AES_CBC) + 0x35 +#else + 0x00 +#endif + }; + static const uint8_t kAESGCMCiphertext[80] = { + 0x4a, 0xd8, 0xe7, 0x7d, 0x78, 0xd7, 0x7d, 0x5e, 0xb2, 0x11, 0xb6, 0xc9, + 0xa4, 0xbc, 0xb2, 0xae, 0xbe, 0x93, 0xd1, 0xb7, 0xfe, 0x65, 0xc1, 0x82, + 0x2a, 0xb6, 0x71, 0x5f, 0x1a, 0x7c, 0xe0, 0x1b, 0x2b, 0xe2, 0x53, 0xfa, + 0xa0, 0x47, 0xfa, 0xd7, 0x8f, 0xb1, 0x4a, 0xc4, 0xdc, 0x89, 0xf9, 0xb4, + 0x14, 0x4d, 0xde, 0x95, 0xea, 0x29, 0x69, 0x76, 0x81, 0xa3, 0x5c, 0x33, + 0xd8, 0x37, 0xd8, 0xfa, 0x47, 0x19, 0x46, 0x2f, 0xf1, 0x90, 0xb7, 0x61, + 0x8f, 0x6f, 0xdd, 0x31, 0x3f, 0x6a, 0x64, +#if !defined(BORINGSSL_FIPS_BREAK_AES_GCM) + 0x0d +#else + 0x00 +#endif + }; + static const DES_cblock kDESKey1 = {"BCMDESK1"}; + static const DES_cblock kDESKey2 = {"BCMDESK2"}; + static const DES_cblock kDESKey3 = {"BCMDESK3"}; + static const DES_cblock kDESIV = {"BCMDESIV"}; + static const uint8_t kDESCiphertext[64] = { + 0xa4, 0x30, 0x7a, 0x4c, 0x1f, 0x60, 0x16, 0xd7, 0x4f, 0x41, 0xe1, + 0xbb, 0x27, 0xc4, 0x27, 0x37, 0xd4, 0x7f, 0xb9, 0x10, 0xf8, 0xbc, + 0xaf, 0x93, 0x91, 0xb8, 0x88, 0x24, 0xb1, 0xf6, 0xf8, 0xbd, 0x31, + 0x96, 0x06, 0x76, 0xde, 0x32, 0xcd, 0x29, 0x29, 0xba, 0x70, 0x5f, + 0xea, 0xc0, 0xcb, 0xde, 0xc7, 0x75, 0x90, 0xe0, 0x0f, 0x5e, 0x2c, + 0x0d, 0x49, 0x20, 0xd5, 0x30, 0x83, 0xf8, 0x08, +#if !defined(BORINGSSL_FIPS_BREAK_DES) + 0x5a +#else + 0x00 +#endif + }; + static const uint8_t kPlaintextSHA1[20] = { + 0xc6, 0xf8, 0xc9, 0x63, 0x1c, 0x14, 0x23, 0x62, 0x9b, 0xbd, + 0x55, 0x82, 0xf4, 0xd6, 0x1d, 0xf2, 0xab, 0x7d, 0xc8, +#if !defined(BORINGSSL_FIPS_BREAK_SHA_1) + 0x28 +#else + 0x00 +#endif + }; + static const uint8_t kPlaintextSHA256[32] = { + 0x37, 0xbd, 0x70, 0x53, 0x72, 0xfc, 0xd4, 0x03, 0x79, 0x70, 0xfb, + 0x06, 0x95, 0xb1, 0x2a, 0x82, 0x48, 0xe1, 0x3e, 0xf2, 0x33, 0xfb, + 0xef, 0x29, 0x81, 0x22, 0x45, 0x40, 0x43, 0x70, 0xce, +#if !defined(BORINGSSL_FIPS_BREAK_SHA_256) + 0x0f +#else + 0x00 +#endif + }; + static const uint8_t kPlaintextSHA512[64] = { + 0x08, 0x6a, 0x1c, 0x84, 0x61, 0x9d, 0x8e, 0xb3, 0xc0, 0x97, 0x4e, + 0xa1, 0x9f, 0x9c, 0xdc, 0xaf, 0x3b, 0x5c, 0x31, 0xf0, 0xf2, 0x74, + 0xc3, 0xbd, 0x6e, 0xd6, 0x1e, 0xb2, 0xbb, 0x34, 0x74, 0x72, 0x5c, + 0x51, 0x29, 0x8b, 0x87, 0x3a, 0xa3, 0xf2, 0x25, 0x23, 0xd4, 0x1c, + 0x82, 0x1b, 0xfe, 0xd3, 0xc6, 0xee, 0xb5, 0xd6, 0xaf, 0x07, 0x7b, + 0x98, 0xca, 0xa7, 0x01, 0xf3, 0x94, 0xf3, 0x68, +#if !defined(BORINGSSL_FIPS_BREAK_SHA_512) + 0x14 +#else + 0x00 +#endif + }; + static const uint8_t kRSASignature[256] = { + 0x62, 0x66, 0x4b, 0xe3, 0xb1, 0xd2, 0x83, 0xf1, 0xa8, 0x56, 0x2b, 0x33, + 0x60, 0x1e, 0xdb, 0x1e, 0x06, 0xf7, 0xa7, 0x1e, 0xa8, 0xef, 0x03, 0x4d, + 0x0c, 0xf6, 0x83, 0x75, 0x7a, 0xf0, 0x14, 0xc7, 0xe2, 0x94, 0x3a, 0xb5, + 0x67, 0x56, 0xa5, 0x48, 0x7f, 0x3a, 0xa5, 0xbf, 0xf7, 0x1d, 0x44, 0xa6, + 0x34, 0xed, 0x9b, 0xd6, 0x51, 0xaa, 0x2c, 0x4e, 0xce, 0x60, 0x5f, 0xe9, + 0x0e, 0xd5, 0xcd, 0xeb, 0x23, 0x27, 0xf8, 0xfb, 0x45, 0xe5, 0x34, 0x63, + 0x77, 0x7f, 0x2e, 0x80, 0xcf, 0x9d, 0x2e, 0xfc, 0xe2, 0x50, 0x75, 0x29, + 0x46, 0xf4, 0xaf, 0x91, 0xed, 0x36, 0xe1, 0x5e, 0xef, 0x66, 0xa1, 0xff, + 0x27, 0xfc, 0x87, 0x7e, 0x60, 0x84, 0x0f, 0x54, 0x51, 0x56, 0x0f, 0x68, + 0x99, 0xc0, 0x3f, 0xeb, 0xa5, 0xa0, 0x46, 0xb0, 0x86, 0x02, 0xb0, 0xc8, + 0xe8, 0x46, 0x13, 0x06, 0xcd, 0xb7, 0x8a, 0xd0, 0x3b, 0x46, 0xd0, 0x14, + 0x64, 0x53, 0x9b, 0x5b, 0x5e, 0x02, 0x45, 0xba, 0x6e, 0x7e, 0x0a, 0xb9, + 0x9e, 0x62, 0xb7, 0xd5, 0x7a, 0x87, 0xea, 0xd3, 0x24, 0xa5, 0xef, 0xb3, + 0xdc, 0x05, 0x9c, 0x04, 0x60, 0x4b, 0xde, 0xa8, 0x90, 0x08, 0x7b, 0x6a, + 0x5f, 0xb4, 0x3f, 0xda, 0xc5, 0x1f, 0x6e, 0xd6, 0x15, 0xde, 0x65, 0xa4, + 0x6e, 0x62, 0x9d, 0x8f, 0xa8, 0xbe, 0x86, 0xf6, 0x09, 0x90, 0x40, 0xa5, + 0xf4, 0x23, 0xc5, 0xf6, 0x38, 0x86, 0x0d, 0x1c, 0xed, 0x4a, 0x0a, 0xae, + 0xa4, 0x26, 0xc2, 0x2e, 0xd3, 0x13, 0x66, 0x61, 0xea, 0x35, 0x01, 0x0e, + 0x13, 0xda, 0x78, 0x20, 0xae, 0x59, 0x5f, 0x9b, 0xa9, 0x6c, 0xf9, 0x1b, + 0xdf, 0x76, 0x53, 0xc8, 0xa7, 0xf5, 0x63, 0x6d, 0xf3, 0xff, 0xfd, 0xaf, + 0x75, 0x4b, 0xac, 0x67, 0xb1, 0x3c, 0xbf, 0x5e, 0xde, 0x73, 0x02, 0x6d, + 0xd2, 0x0c, 0xb1, +#if !defined(BORINGSSL_FIPS_BREAK_RSA_SIG) + 0x64 +#else + 0x00 +#endif + }; + const uint8_t kDRBGEntropy[48] = + "BCM Known Answer Test DBRG Initial Entropy "; + const uint8_t kDRBGPersonalization[18] = "BCMPersonalization"; + const uint8_t kDRBGAD[16] = "BCM DRBG KAT AD "; + const uint8_t kDRBGOutput[64] = { + 0x1d, 0x63, 0xdf, 0x05, 0x51, 0x49, 0x22, 0x46, 0xcd, 0x9b, 0xc5, + 0xbb, 0xf1, 0x5d, 0x44, 0xae, 0x13, 0x78, 0xb1, 0xe4, 0x7c, 0xf1, + 0x96, 0x33, 0x3d, 0x60, 0xb6, 0x29, 0xd4, 0xbb, 0x6b, 0x44, 0xf9, + 0xef, 0xd9, 0xf4, 0xa2, 0xba, 0x48, 0xea, 0x39, 0x75, 0x59, 0x32, + 0xf7, 0x31, 0x2c, 0x98, 0x14, 0x2b, 0x49, 0xdf, 0x02, 0xb6, 0x5d, + 0x71, 0x09, 0x50, 0xdb, 0x23, 0xdb, 0xe5, 0x22, +#if !defined(BORINGSSL_FIPS_BREAK_DRBG) + 0x95 +#else + 0x00 +#endif + }; + const uint8_t kDRBGEntropy2[48] = + "BCM Known Answer Test DBRG Reseed Entropy "; + const uint8_t kDRBGReseedOutput[64] = { + 0xa4, 0x77, 0x05, 0xdb, 0x14, 0x11, 0x76, 0x71, 0x42, 0x5b, 0xd8, + 0xd7, 0xa5, 0x4f, 0x8b, 0x39, 0xf2, 0x10, 0x4a, 0x50, 0x5b, 0xa2, + 0xc8, 0xf0, 0xbb, 0x3e, 0xa1, 0xa5, 0x90, 0x7d, 0x54, 0xd9, 0xc6, + 0xb0, 0x96, 0xc0, 0x2b, 0x7e, 0x9b, 0xc9, 0xa1, 0xdd, 0x78, 0x2e, + 0xd5, 0xa8, 0x66, 0x16, 0xbd, 0x18, 0x3c, 0xf2, 0xaa, 0x7a, 0x2b, + 0x37, 0xf9, 0xab, 0x35, 0x64, 0x15, 0x01, 0x3f, 0xc4, + }; + const uint8_t kECDSASigR[32] = { + 0x67, 0x80, 0xc5, 0xfc, 0x70, 0x27, 0x5e, 0x2c, 0x70, 0x61, 0xa0, + 0xe7, 0x87, 0x7b, 0xb1, 0x74, 0xde, 0xad, 0xeb, 0x98, 0x87, 0x02, + 0x7f, 0x3f, 0xa8, 0x36, 0x54, 0x15, 0x8b, 0xa7, 0xf5, +#if !defined(BORINGSSL_FIPS_BREAK_ECDSA_SIG) + 0x0c, +#else + 0x00, +#endif + }; + const uint8_t kECDSASigS[32] = { + 0xa5, 0x93, 0xe0, 0x23, 0x91, 0xe7, 0x4b, 0x8d, 0x77, 0x25, 0xa6, + 0xba, 0x4d, 0xd9, 0x86, 0x77, 0xda, 0x7d, 0x8f, 0xef, 0xc4, 0x1a, + 0xf0, 0xcc, 0x81, 0xe5, 0xea, 0x3f, 0xc2, 0x41, 0x7f, 0xd8, + }; + + EVP_AEAD_CTX aead_ctx; + EVP_AEAD_CTX_zero(&aead_ctx); + RSA *rsa_key = NULL; + EC_KEY *ec_key = NULL; + ECDSA_SIG *sig = NULL; + int ret = 0; + + AES_KEY aes_key; + uint8_t aes_iv[16]; + uint8_t output[256]; + + // AES-CBC Encryption KAT + memcpy(aes_iv, kAESIV, sizeof(kAESIV)); + if (AES_set_encrypt_key(kAESKey, 8 * sizeof(kAESKey), &aes_key) != 0) { + goto err; + } + AES_cbc_encrypt(kPlaintext, output, sizeof(kPlaintext), &aes_key, aes_iv, + AES_ENCRYPT); + if (!check_test(kAESCBCCiphertext, output, sizeof(kAESCBCCiphertext), + "AES-CBC Encryption KAT")) { + goto err; + } + + // AES-CBC Decryption KAT + memcpy(aes_iv, kAESIV, sizeof(kAESIV)); + if (AES_set_decrypt_key(kAESKey, 8 * sizeof(kAESKey), &aes_key) != 0) { + goto err; + } + AES_cbc_encrypt(kAESCBCCiphertext, output, sizeof(kAESCBCCiphertext), + &aes_key, aes_iv, AES_DECRYPT); + if (!check_test(kPlaintext, output, sizeof(kPlaintext), + "AES-CBC Decryption KAT")) { + goto err; + } + + size_t out_len; + uint8_t nonce[EVP_AEAD_MAX_NONCE_LENGTH]; + OPENSSL_memset(nonce, 0, sizeof(nonce)); + if (!EVP_AEAD_CTX_init(&aead_ctx, EVP_aead_aes_128_gcm(), kAESKey, + sizeof(kAESKey), 0, NULL)) { + goto err; + } + + // AES-GCM Encryption KAT + if (!EVP_AEAD_CTX_seal(&aead_ctx, output, &out_len, sizeof(output), nonce, + EVP_AEAD_nonce_length(EVP_aead_aes_128_gcm()), + kPlaintext, sizeof(kPlaintext), NULL, 0) || + !check_test(kAESGCMCiphertext, output, sizeof(kAESGCMCiphertext), + "AES-GCM Encryption KAT")) { + goto err; + } + + // AES-GCM Decryption KAT + if (!EVP_AEAD_CTX_open(&aead_ctx, output, &out_len, sizeof(output), nonce, + EVP_AEAD_nonce_length(EVP_aead_aes_128_gcm()), + kAESGCMCiphertext, sizeof(kAESGCMCiphertext), NULL, + 0) || + !check_test(kPlaintext, output, sizeof(kPlaintext), + "AES-GCM Decryption KAT")) { + goto err; + } + + DES_key_schedule des1, des2, des3; + DES_cblock des_iv; + DES_set_key(&kDESKey1, &des1); + DES_set_key(&kDESKey2, &des2); + DES_set_key(&kDESKey3, &des3); + + // 3DES Encryption KAT + memcpy(&des_iv, &kDESIV, sizeof(des_iv)); + DES_ede3_cbc_encrypt(kPlaintext, output, sizeof(kPlaintext), &des1, &des2, + &des3, &des_iv, DES_ENCRYPT); + if (!check_test(kDESCiphertext, output, sizeof(kDESCiphertext), + "3DES Encryption KAT")) { + goto err; + } + + // 3DES Decryption KAT + memcpy(&des_iv, &kDESIV, sizeof(des_iv)); + DES_ede3_cbc_encrypt(kDESCiphertext, output, sizeof(kDESCiphertext), &des1, + &des2, &des3, &des_iv, DES_DECRYPT); + if (!check_test(kPlaintext, output, sizeof(kPlaintext), + "3DES Decryption KAT")) { + goto err; + } + + // SHA-1 KAT + SHA1(kPlaintext, sizeof(kPlaintext), output); + if (!check_test(kPlaintextSHA1, output, sizeof(kPlaintextSHA1), + "SHA-1 KAT")) { + goto err; + } + + // SHA-256 KAT + SHA256(kPlaintext, sizeof(kPlaintext), output); + if (!check_test(kPlaintextSHA256, output, sizeof(kPlaintextSHA256), + "SHA-256 KAT")) { + goto err; + } + + // SHA-512 KAT + SHA512(kPlaintext, sizeof(kPlaintext), output); + if (!check_test(kPlaintextSHA512, output, sizeof(kPlaintextSHA512), + "SHA-512 KAT")) { + goto err; + } + + rsa_key = self_test_rsa_key(); + if (rsa_key == NULL) { + printf("RSA KeyGen failed\n"); + goto err; + } + + // RSA Sign KAT + unsigned sig_len; + + // Disable blinding for the power-on tests because it's not needed and + // triggers an entropy draw. + rsa_key->flags |= RSA_FLAG_NO_BLINDING; + + if (!RSA_sign(NID_sha256, kPlaintextSHA256, sizeof(kPlaintextSHA256), output, + &sig_len, rsa_key) || + !check_test(kRSASignature, output, sizeof(kRSASignature), + "RSA Sign KAT")) { + goto err; + } + + // RSA Verify KAT + if (!RSA_verify(NID_sha256, kPlaintextSHA256, sizeof(kPlaintextSHA256), + kRSASignature, sizeof(kRSASignature), rsa_key)) { + printf("RSA Verify KAT failed.\n"); + goto err; + } + + ec_key = self_test_ecdsa_key(); + if (ec_key == NULL) { + printf("ECDSA KeyGen failed\n"); + goto err; + } + + // ECDSA Sign/Verify PWCT + + // The 'k' value for ECDSA is fixed to avoid an entropy draw. + ec_key->fixed_k = BN_new(); + if (ec_key->fixed_k == NULL || + !BN_set_word(ec_key->fixed_k, 42)) { + printf("Out of memory\n"); + goto err; + } + + sig = ECDSA_do_sign(kPlaintextSHA256, sizeof(kPlaintextSHA256), ec_key); + + uint8_t ecdsa_r_bytes[sizeof(kECDSASigR)]; + uint8_t ecdsa_s_bytes[sizeof(kECDSASigS)]; + if (sig == NULL || + BN_num_bytes(sig->r) != sizeof(ecdsa_r_bytes) || + !BN_bn2bin(sig->r, ecdsa_r_bytes) || + BN_num_bytes(sig->s) != sizeof(ecdsa_s_bytes) || + !BN_bn2bin(sig->s, ecdsa_s_bytes) || + !check_test(kECDSASigR, ecdsa_r_bytes, sizeof(kECDSASigR), "ECDSA R") || + !check_test(kECDSASigS, ecdsa_s_bytes, sizeof(kECDSASigS), "ECDSA S")) { + printf("ECDSA KAT failed.\n"); + goto err; + } + + // DBRG KAT + CTR_DRBG_STATE drbg; + if (!CTR_DRBG_init(&drbg, kDRBGEntropy, kDRBGPersonalization, + sizeof(kDRBGPersonalization)) || + !CTR_DRBG_generate(&drbg, output, sizeof(kDRBGOutput), kDRBGAD, + sizeof(kDRBGAD)) || + !check_test(kDRBGOutput, output, sizeof(kDRBGOutput), + "DBRG Generate KAT") || + !CTR_DRBG_reseed(&drbg, kDRBGEntropy2, kDRBGAD, sizeof(kDRBGAD)) || + !CTR_DRBG_generate(&drbg, output, sizeof(kDRBGReseedOutput), kDRBGAD, + sizeof(kDRBGAD)) || + !check_test(kDRBGReseedOutput, output, sizeof(kDRBGReseedOutput), + "DRBG Reseed KAT")) { + goto err; + } + CTR_DRBG_clear(&drbg); + + CTR_DRBG_STATE kZeroDRBG; + memset(&kZeroDRBG, 0, sizeof(kZeroDRBG)); + if (!check_test(&kZeroDRBG, &drbg, sizeof(drbg), "DRBG Clear KAT")) { + goto err; + } + + ret = 1; + +err: + EVP_AEAD_CTX_cleanup(&aead_ctx); + RSA_free(rsa_key); + EC_KEY_free(ec_key); + ECDSA_SIG_free(sig); + + return ret; +} + +#endif // !_MSC_VER diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/sha/sha1-altivec.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/sha/sha1-altivec.c new file mode 100644 index 0000000..9a99775 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/sha/sha1-altivec.c @@ -0,0 +1,361 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +// Altivec-optimized SHA1 in C. This is tested on ppc64le only. +// +// References: +// https://software.intel.com/en-us/articles/improving-the-performance-of-the-secure-hash-algorithm-1 +// http://arctic.org/~dean/crypto/sha1.html +// +// This code used the generic SHA-1 from OpenSSL as a basis and AltiVec +// optimisations were added on top. + +#include + +#if defined(OPENSSL_PPC64LE) + +#include + +void sha1_block_data_order(uint32_t *state, const uint8_t *data, size_t num); + +static uint32_t rotate(uint32_t a, int n) { return (a << n) | (a >> (32 - n)); } + +typedef vector unsigned int vec_uint32_t; +typedef vector unsigned char vec_uint8_t; + +// Vector constants +static const vec_uint8_t k_swap_endianness = {3, 2, 1, 0, 7, 6, 5, 4, + 11, 10, 9, 8, 15, 14, 13, 12}; + +// Shift amounts for byte and bit shifts and rotations +static const vec_uint8_t k_4_bytes = {32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32}; +static const vec_uint8_t k_12_bytes = {96, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 96, 96, 96, 96, 96, 96}; + +#define K_00_19 0x5a827999UL +#define K_20_39 0x6ed9eba1UL +#define K_40_59 0x8f1bbcdcUL +#define K_60_79 0xca62c1d6UL + +// Vector versions of the above. +static const vec_uint32_t K_00_19_x_4 = {K_00_19, K_00_19, K_00_19, K_00_19}; +static const vec_uint32_t K_20_39_x_4 = {K_20_39, K_20_39, K_20_39, K_20_39}; +static const vec_uint32_t K_40_59_x_4 = {K_40_59, K_40_59, K_40_59, K_40_59}; +static const vec_uint32_t K_60_79_x_4 = {K_60_79, K_60_79, K_60_79, K_60_79}; + +// vector message scheduling: compute message schedule for round i..i+3 where i +// is divisible by 4. We return the schedule w[i..i+3] as a vector. In +// addition, we also precompute sum w[i..+3] and an additive constant K. This +// is done to offload some computation of f() in the integer execution units. +// +// Byte shifting code below may not be correct for big-endian systems. +static vec_uint32_t sched_00_15(vec_uint32_t *pre_added, const void *data, + vec_uint32_t k) { + const vector unsigned char unaligned_data = + vec_vsx_ld(0, (const unsigned char*) data); + const vec_uint32_t v = (vec_uint32_t) unaligned_data; + const vec_uint32_t w = vec_perm(v, v, k_swap_endianness); + vec_st(w + k, 0, pre_added); + return w; +} + +// Compute w[i..i+3] using these steps for i in [16, 20, 24, 28] +// +// w'[i ] = (w[i-3] ^ w[i-8] ^ w[i-14] ^ w[i-16]) <<< 1 +// w'[i+1] = (w[i-2] ^ w[i-7] ^ w[i-13] ^ w[i-15]) <<< 1 +// w'[i+2] = (w[i-1] ^ w[i-6] ^ w[i-12] ^ w[i-14]) <<< 1 +// w'[i+3] = ( 0 ^ w[i-5] ^ w[i-11] ^ w[i-13]) <<< 1 +// +// w[ i] = w'[ i] +// w[i+1] = w'[i+1] +// w[i+2] = w'[i+2] +// w[i+3] = w'[i+3] ^ (w'[i] <<< 1) +static vec_uint32_t sched_16_31(vec_uint32_t *pre_added, vec_uint32_t minus_4, + vec_uint32_t minus_8, vec_uint32_t minus_12, + vec_uint32_t minus_16, vec_uint32_t k) { + const vec_uint32_t minus_3 = vec_sro(minus_4, k_4_bytes); + const vec_uint32_t minus_14 = vec_sld((minus_12), (minus_16), 8); + const vec_uint32_t k_1_bit = vec_splat_u32(1); + const vec_uint32_t w_prime = + vec_rl(minus_3 ^ minus_8 ^ minus_14 ^ minus_16, k_1_bit); + const vec_uint32_t w = + w_prime ^ vec_rl(vec_slo(w_prime, k_12_bytes), k_1_bit); + vec_st(w + k, 0, pre_added); + return w; +} + +// Compute w[i..i+3] using this relation for i in [32, 36, 40 ... 76] +// w[i] = (w[i-6] ^ w[i-16] ^ w[i-28] ^ w[i-32]), 2) <<< 2 +static vec_uint32_t sched_32_79(vec_uint32_t *pre_added, vec_uint32_t minus_4, + vec_uint32_t minus_8, vec_uint32_t minus_16, + vec_uint32_t minus_28, vec_uint32_t minus_32, + vec_uint32_t k) { + const vec_uint32_t minus_6 = vec_sld(minus_4, minus_8, 8); + const vec_uint32_t k_2_bits = vec_splat_u32(2); + const vec_uint32_t w = + vec_rl(minus_6 ^ minus_16 ^ minus_28 ^ minus_32, k_2_bits); + vec_st(w + k, 0, pre_added); + return w; +} + +// 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) + +// We pre-added the K constants during message scheduling. +#define BODY_00_19(i, a, b, c, d, e, f) \ + do { \ + (f) = w[i] + (e) + rotate((a), 5) + F_00_19((b), (c), (d)); \ + (b) = rotate((b), 30); \ + } while (0) + +#define BODY_20_39(i, a, b, c, d, e, f) \ + do { \ + (f) = w[i] + (e) + rotate((a), 5) + F_20_39((b), (c), (d)); \ + (b) = rotate((b), 30); \ + } while (0) + +#define BODY_40_59(i, a, b, c, d, e, f) \ + do { \ + (f) = w[i] + (e) + rotate((a), 5) + F_40_59((b), (c), (d)); \ + (b) = rotate((b), 30); \ + } while (0) + +#define BODY_60_79(i, a, b, c, d, e, f) \ + do { \ + (f) = w[i] + (e) + rotate((a), 5) + F_60_79((b), (c), (d)); \ + (b) = rotate((b), 30); \ + } while (0) + +void sha1_block_data_order(uint32_t *state, const uint8_t *data, size_t num) { + uint32_t A, B, C, D, E, T; + + A = state[0]; + B = state[1]; + C = state[2]; + D = state[3]; + E = state[4]; + + for (;;) { + vec_uint32_t vw[20]; + const uint32_t *w = (const uint32_t *)&vw; + + vec_uint32_t k = K_00_19_x_4; + const vec_uint32_t w0 = sched_00_15(vw + 0, data + 0, k); + BODY_00_19(0, A, B, C, D, E, T); + BODY_00_19(1, T, A, B, C, D, E); + BODY_00_19(2, E, T, A, B, C, D); + BODY_00_19(3, D, E, T, A, B, C); + + const vec_uint32_t w4 = sched_00_15(vw + 1, data + 16, k); + BODY_00_19(4, C, D, E, T, A, B); + BODY_00_19(5, B, C, D, E, T, A); + BODY_00_19(6, A, B, C, D, E, T); + BODY_00_19(7, T, A, B, C, D, E); + + const vec_uint32_t w8 = sched_00_15(vw + 2, data + 32, k); + BODY_00_19(8, E, T, A, B, C, D); + BODY_00_19(9, D, E, T, A, B, C); + BODY_00_19(10, C, D, E, T, A, B); + BODY_00_19(11, B, C, D, E, T, A); + + const vec_uint32_t w12 = sched_00_15(vw + 3, data + 48, k); + BODY_00_19(12, A, B, C, D, E, T); + BODY_00_19(13, T, A, B, C, D, E); + BODY_00_19(14, E, T, A, B, C, D); + BODY_00_19(15, D, E, T, A, B, C); + + const vec_uint32_t w16 = sched_16_31(vw + 4, w12, w8, w4, w0, k); + BODY_00_19(16, C, D, E, T, A, B); + BODY_00_19(17, B, C, D, E, T, A); + BODY_00_19(18, A, B, C, D, E, T); + BODY_00_19(19, T, A, B, C, D, E); + + k = K_20_39_x_4; + const vec_uint32_t w20 = sched_16_31(vw + 5, w16, w12, w8, w4, k); + BODY_20_39(20, E, T, A, B, C, D); + BODY_20_39(21, D, E, T, A, B, C); + BODY_20_39(22, C, D, E, T, A, B); + BODY_20_39(23, B, C, D, E, T, A); + + const vec_uint32_t w24 = sched_16_31(vw + 6, w20, w16, w12, w8, k); + BODY_20_39(24, A, B, C, D, E, T); + BODY_20_39(25, T, A, B, C, D, E); + BODY_20_39(26, E, T, A, B, C, D); + BODY_20_39(27, D, E, T, A, B, C); + + const vec_uint32_t w28 = sched_16_31(vw + 7, w24, w20, w16, w12, k); + BODY_20_39(28, C, D, E, T, A, B); + BODY_20_39(29, B, C, D, E, T, A); + BODY_20_39(30, A, B, C, D, E, T); + BODY_20_39(31, T, A, B, C, D, E); + + const vec_uint32_t w32 = sched_32_79(vw + 8, w28, w24, w16, w4, w0, k); + BODY_20_39(32, E, T, A, B, C, D); + BODY_20_39(33, D, E, T, A, B, C); + BODY_20_39(34, C, D, E, T, A, B); + BODY_20_39(35, B, C, D, E, T, A); + + const vec_uint32_t w36 = sched_32_79(vw + 9, w32, w28, w20, w8, w4, k); + BODY_20_39(36, A, B, C, D, E, T); + BODY_20_39(37, T, A, B, C, D, E); + BODY_20_39(38, E, T, A, B, C, D); + BODY_20_39(39, D, E, T, A, B, C); + + k = K_40_59_x_4; + const vec_uint32_t w40 = sched_32_79(vw + 10, w36, w32, w24, w12, w8, k); + BODY_40_59(40, C, D, E, T, A, B); + BODY_40_59(41, B, C, D, E, T, A); + BODY_40_59(42, A, B, C, D, E, T); + BODY_40_59(43, T, A, B, C, D, E); + + const vec_uint32_t w44 = sched_32_79(vw + 11, w40, w36, w28, w16, w12, k); + BODY_40_59(44, E, T, A, B, C, D); + BODY_40_59(45, D, E, T, A, B, C); + BODY_40_59(46, C, D, E, T, A, B); + BODY_40_59(47, B, C, D, E, T, A); + + const vec_uint32_t w48 = sched_32_79(vw + 12, w44, w40, w32, w20, w16, k); + BODY_40_59(48, A, B, C, D, E, T); + BODY_40_59(49, T, A, B, C, D, E); + BODY_40_59(50, E, T, A, B, C, D); + BODY_40_59(51, D, E, T, A, B, C); + + const vec_uint32_t w52 = sched_32_79(vw + 13, w48, w44, w36, w24, w20, k); + BODY_40_59(52, C, D, E, T, A, B); + BODY_40_59(53, B, C, D, E, T, A); + BODY_40_59(54, A, B, C, D, E, T); + BODY_40_59(55, T, A, B, C, D, E); + + const vec_uint32_t w56 = sched_32_79(vw + 14, w52, w48, w40, w28, w24, k); + BODY_40_59(56, E, T, A, B, C, D); + BODY_40_59(57, D, E, T, A, B, C); + BODY_40_59(58, C, D, E, T, A, B); + BODY_40_59(59, B, C, D, E, T, A); + + k = K_60_79_x_4; + const vec_uint32_t w60 = sched_32_79(vw + 15, w56, w52, w44, w32, w28, k); + BODY_60_79(60, A, B, C, D, E, T); + BODY_60_79(61, T, A, B, C, D, E); + BODY_60_79(62, E, T, A, B, C, D); + BODY_60_79(63, D, E, T, A, B, C); + + const vec_uint32_t w64 = sched_32_79(vw + 16, w60, w56, w48, w36, w32, k); + BODY_60_79(64, C, D, E, T, A, B); + BODY_60_79(65, B, C, D, E, T, A); + BODY_60_79(66, A, B, C, D, E, T); + BODY_60_79(67, T, A, B, C, D, E); + + const vec_uint32_t w68 = sched_32_79(vw + 17, w64, w60, w52, w40, w36, k); + BODY_60_79(68, E, T, A, B, C, D); + BODY_60_79(69, D, E, T, A, B, C); + BODY_60_79(70, C, D, E, T, A, B); + BODY_60_79(71, B, C, D, E, T, A); + + const vec_uint32_t w72 = sched_32_79(vw + 18, w68, w64, w56, w44, w40, k); + BODY_60_79(72, A, B, C, D, E, T); + BODY_60_79(73, T, A, B, C, D, E); + BODY_60_79(74, E, T, A, B, C, D); + BODY_60_79(75, D, E, T, A, B, C); + + // We don't use the last value + (void)sched_32_79(vw + 19, w72, w68, w60, w48, w44, k); + BODY_60_79(76, C, D, E, T, A, B); + BODY_60_79(77, B, C, D, E, T, A); + BODY_60_79(78, A, B, C, D, E, T); + BODY_60_79(79, T, A, B, C, D, E); + + const uint32_t mask = 0xffffffffUL; + state[0] = (state[0] + E) & mask; + state[1] = (state[1] + T) & mask; + state[2] = (state[2] + A) & mask; + state[3] = (state[3] + B) & mask; + state[4] = (state[4] + C) & mask; + + data += 64; + if (--num == 0) { + break; + } + + A = state[0]; + B = state[1]; + C = state[2]; + D = state[3]; + E = state[4]; + } +} + +#endif // OPENSSL_PPC64LE + +#undef K_00_19 +#undef K_20_39 +#undef K_40_59 +#undef K_60_79 +#undef F_00_19 +#undef F_20_39 +#undef F_40_59 +#undef F_60_79 +#undef BODY_00_19 +#undef BODY_20_39 +#undef BODY_40_59 +#undef BODY_60_79 diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/sha/sha1-altivec.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/sha/sha1-altivec.c.grpc_back new file mode 100644 index 0000000..3152827 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/sha/sha1-altivec.c.grpc_back @@ -0,0 +1,361 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +// Altivec-optimized SHA1 in C. This is tested on ppc64le only. +// +// References: +// https://software.intel.com/en-us/articles/improving-the-performance-of-the-secure-hash-algorithm-1 +// http://arctic.org/~dean/crypto/sha1.html +// +// This code used the generic SHA-1 from OpenSSL as a basis and AltiVec +// optimisations were added on top. + +#include + +#if defined(OPENSSL_PPC64LE) + +#include + +void sha1_block_data_order(uint32_t *state, const uint8_t *data, size_t num); + +static uint32_t rotate(uint32_t a, int n) { return (a << n) | (a >> (32 - n)); } + +typedef vector unsigned int vec_uint32_t; +typedef vector unsigned char vec_uint8_t; + +// Vector constants +static const vec_uint8_t k_swap_endianness = {3, 2, 1, 0, 7, 6, 5, 4, + 11, 10, 9, 8, 15, 14, 13, 12}; + +// Shift amounts for byte and bit shifts and rotations +static const vec_uint8_t k_4_bytes = {32, 32, 32, 32, 32, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 32}; +static const vec_uint8_t k_12_bytes = {96, 96, 96, 96, 96, 96, 96, 96, + 96, 96, 96, 96, 96, 96, 96, 96}; + +#define K_00_19 0x5a827999UL +#define K_20_39 0x6ed9eba1UL +#define K_40_59 0x8f1bbcdcUL +#define K_60_79 0xca62c1d6UL + +// Vector versions of the above. +static const vec_uint32_t K_00_19_x_4 = {K_00_19, K_00_19, K_00_19, K_00_19}; +static const vec_uint32_t K_20_39_x_4 = {K_20_39, K_20_39, K_20_39, K_20_39}; +static const vec_uint32_t K_40_59_x_4 = {K_40_59, K_40_59, K_40_59, K_40_59}; +static const vec_uint32_t K_60_79_x_4 = {K_60_79, K_60_79, K_60_79, K_60_79}; + +// vector message scheduling: compute message schedule for round i..i+3 where i +// is divisible by 4. We return the schedule w[i..i+3] as a vector. In +// addition, we also precompute sum w[i..+3] and an additive constant K. This +// is done to offload some computation of f() in the integer execution units. +// +// Byte shifting code below may not be correct for big-endian systems. +static vec_uint32_t sched_00_15(vec_uint32_t *pre_added, const void *data, + vec_uint32_t k) { + const vector unsigned char unaligned_data = + vec_vsx_ld(0, (const unsigned char*) data); + const vec_uint32_t v = (vec_uint32_t) unaligned_data; + const vec_uint32_t w = vec_perm(v, v, k_swap_endianness); + vec_st(w + k, 0, pre_added); + return w; +} + +// Compute w[i..i+3] using these steps for i in [16, 20, 24, 28] +// +// w'[i ] = (w[i-3] ^ w[i-8] ^ w[i-14] ^ w[i-16]) <<< 1 +// w'[i+1] = (w[i-2] ^ w[i-7] ^ w[i-13] ^ w[i-15]) <<< 1 +// w'[i+2] = (w[i-1] ^ w[i-6] ^ w[i-12] ^ w[i-14]) <<< 1 +// w'[i+3] = ( 0 ^ w[i-5] ^ w[i-11] ^ w[i-13]) <<< 1 +// +// w[ i] = w'[ i] +// w[i+1] = w'[i+1] +// w[i+2] = w'[i+2] +// w[i+3] = w'[i+3] ^ (w'[i] <<< 1) +static vec_uint32_t sched_16_31(vec_uint32_t *pre_added, vec_uint32_t minus_4, + vec_uint32_t minus_8, vec_uint32_t minus_12, + vec_uint32_t minus_16, vec_uint32_t k) { + const vec_uint32_t minus_3 = vec_sro(minus_4, k_4_bytes); + const vec_uint32_t minus_14 = vec_sld((minus_12), (minus_16), 8); + const vec_uint32_t k_1_bit = vec_splat_u32(1); + const vec_uint32_t w_prime = + vec_rl(minus_3 ^ minus_8 ^ minus_14 ^ minus_16, k_1_bit); + const vec_uint32_t w = + w_prime ^ vec_rl(vec_slo(w_prime, k_12_bytes), k_1_bit); + vec_st(w + k, 0, pre_added); + return w; +} + +// Compute w[i..i+3] using this relation for i in [32, 36, 40 ... 76] +// w[i] = (w[i-6] ^ w[i-16] ^ w[i-28] ^ w[i-32]), 2) <<< 2 +static vec_uint32_t sched_32_79(vec_uint32_t *pre_added, vec_uint32_t minus_4, + vec_uint32_t minus_8, vec_uint32_t minus_16, + vec_uint32_t minus_28, vec_uint32_t minus_32, + vec_uint32_t k) { + const vec_uint32_t minus_6 = vec_sld(minus_4, minus_8, 8); + const vec_uint32_t k_2_bits = vec_splat_u32(2); + const vec_uint32_t w = + vec_rl(minus_6 ^ minus_16 ^ minus_28 ^ minus_32, k_2_bits); + vec_st(w + k, 0, pre_added); + return w; +} + +// 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) + +// We pre-added the K constants during message scheduling. +#define BODY_00_19(i, a, b, c, d, e, f) \ + do { \ + (f) = w[i] + (e) + rotate((a), 5) + F_00_19((b), (c), (d)); \ + (b) = rotate((b), 30); \ + } while (0) + +#define BODY_20_39(i, a, b, c, d, e, f) \ + do { \ + (f) = w[i] + (e) + rotate((a), 5) + F_20_39((b), (c), (d)); \ + (b) = rotate((b), 30); \ + } while (0) + +#define BODY_40_59(i, a, b, c, d, e, f) \ + do { \ + (f) = w[i] + (e) + rotate((a), 5) + F_40_59((b), (c), (d)); \ + (b) = rotate((b), 30); \ + } while (0) + +#define BODY_60_79(i, a, b, c, d, e, f) \ + do { \ + (f) = w[i] + (e) + rotate((a), 5) + F_60_79((b), (c), (d)); \ + (b) = rotate((b), 30); \ + } while (0) + +void sha1_block_data_order(uint32_t *state, const uint8_t *data, size_t num) { + uint32_t A, B, C, D, E, T; + + A = state[0]; + B = state[1]; + C = state[2]; + D = state[3]; + E = state[4]; + + for (;;) { + vec_uint32_t vw[20]; + const uint32_t *w = (const uint32_t *)&vw; + + vec_uint32_t k = K_00_19_x_4; + const vec_uint32_t w0 = sched_00_15(vw + 0, data + 0, k); + BODY_00_19(0, A, B, C, D, E, T); + BODY_00_19(1, T, A, B, C, D, E); + BODY_00_19(2, E, T, A, B, C, D); + BODY_00_19(3, D, E, T, A, B, C); + + const vec_uint32_t w4 = sched_00_15(vw + 1, data + 16, k); + BODY_00_19(4, C, D, E, T, A, B); + BODY_00_19(5, B, C, D, E, T, A); + BODY_00_19(6, A, B, C, D, E, T); + BODY_00_19(7, T, A, B, C, D, E); + + const vec_uint32_t w8 = sched_00_15(vw + 2, data + 32, k); + BODY_00_19(8, E, T, A, B, C, D); + BODY_00_19(9, D, E, T, A, B, C); + BODY_00_19(10, C, D, E, T, A, B); + BODY_00_19(11, B, C, D, E, T, A); + + const vec_uint32_t w12 = sched_00_15(vw + 3, data + 48, k); + BODY_00_19(12, A, B, C, D, E, T); + BODY_00_19(13, T, A, B, C, D, E); + BODY_00_19(14, E, T, A, B, C, D); + BODY_00_19(15, D, E, T, A, B, C); + + const vec_uint32_t w16 = sched_16_31(vw + 4, w12, w8, w4, w0, k); + BODY_00_19(16, C, D, E, T, A, B); + BODY_00_19(17, B, C, D, E, T, A); + BODY_00_19(18, A, B, C, D, E, T); + BODY_00_19(19, T, A, B, C, D, E); + + k = K_20_39_x_4; + const vec_uint32_t w20 = sched_16_31(vw + 5, w16, w12, w8, w4, k); + BODY_20_39(20, E, T, A, B, C, D); + BODY_20_39(21, D, E, T, A, B, C); + BODY_20_39(22, C, D, E, T, A, B); + BODY_20_39(23, B, C, D, E, T, A); + + const vec_uint32_t w24 = sched_16_31(vw + 6, w20, w16, w12, w8, k); + BODY_20_39(24, A, B, C, D, E, T); + BODY_20_39(25, T, A, B, C, D, E); + BODY_20_39(26, E, T, A, B, C, D); + BODY_20_39(27, D, E, T, A, B, C); + + const vec_uint32_t w28 = sched_16_31(vw + 7, w24, w20, w16, w12, k); + BODY_20_39(28, C, D, E, T, A, B); + BODY_20_39(29, B, C, D, E, T, A); + BODY_20_39(30, A, B, C, D, E, T); + BODY_20_39(31, T, A, B, C, D, E); + + const vec_uint32_t w32 = sched_32_79(vw + 8, w28, w24, w16, w4, w0, k); + BODY_20_39(32, E, T, A, B, C, D); + BODY_20_39(33, D, E, T, A, B, C); + BODY_20_39(34, C, D, E, T, A, B); + BODY_20_39(35, B, C, D, E, T, A); + + const vec_uint32_t w36 = sched_32_79(vw + 9, w32, w28, w20, w8, w4, k); + BODY_20_39(36, A, B, C, D, E, T); + BODY_20_39(37, T, A, B, C, D, E); + BODY_20_39(38, E, T, A, B, C, D); + BODY_20_39(39, D, E, T, A, B, C); + + k = K_40_59_x_4; + const vec_uint32_t w40 = sched_32_79(vw + 10, w36, w32, w24, w12, w8, k); + BODY_40_59(40, C, D, E, T, A, B); + BODY_40_59(41, B, C, D, E, T, A); + BODY_40_59(42, A, B, C, D, E, T); + BODY_40_59(43, T, A, B, C, D, E); + + const vec_uint32_t w44 = sched_32_79(vw + 11, w40, w36, w28, w16, w12, k); + BODY_40_59(44, E, T, A, B, C, D); + BODY_40_59(45, D, E, T, A, B, C); + BODY_40_59(46, C, D, E, T, A, B); + BODY_40_59(47, B, C, D, E, T, A); + + const vec_uint32_t w48 = sched_32_79(vw + 12, w44, w40, w32, w20, w16, k); + BODY_40_59(48, A, B, C, D, E, T); + BODY_40_59(49, T, A, B, C, D, E); + BODY_40_59(50, E, T, A, B, C, D); + BODY_40_59(51, D, E, T, A, B, C); + + const vec_uint32_t w52 = sched_32_79(vw + 13, w48, w44, w36, w24, w20, k); + BODY_40_59(52, C, D, E, T, A, B); + BODY_40_59(53, B, C, D, E, T, A); + BODY_40_59(54, A, B, C, D, E, T); + BODY_40_59(55, T, A, B, C, D, E); + + const vec_uint32_t w56 = sched_32_79(vw + 14, w52, w48, w40, w28, w24, k); + BODY_40_59(56, E, T, A, B, C, D); + BODY_40_59(57, D, E, T, A, B, C); + BODY_40_59(58, C, D, E, T, A, B); + BODY_40_59(59, B, C, D, E, T, A); + + k = K_60_79_x_4; + const vec_uint32_t w60 = sched_32_79(vw + 15, w56, w52, w44, w32, w28, k); + BODY_60_79(60, A, B, C, D, E, T); + BODY_60_79(61, T, A, B, C, D, E); + BODY_60_79(62, E, T, A, B, C, D); + BODY_60_79(63, D, E, T, A, B, C); + + const vec_uint32_t w64 = sched_32_79(vw + 16, w60, w56, w48, w36, w32, k); + BODY_60_79(64, C, D, E, T, A, B); + BODY_60_79(65, B, C, D, E, T, A); + BODY_60_79(66, A, B, C, D, E, T); + BODY_60_79(67, T, A, B, C, D, E); + + const vec_uint32_t w68 = sched_32_79(vw + 17, w64, w60, w52, w40, w36, k); + BODY_60_79(68, E, T, A, B, C, D); + BODY_60_79(69, D, E, T, A, B, C); + BODY_60_79(70, C, D, E, T, A, B); + BODY_60_79(71, B, C, D, E, T, A); + + const vec_uint32_t w72 = sched_32_79(vw + 18, w68, w64, w56, w44, w40, k); + BODY_60_79(72, A, B, C, D, E, T); + BODY_60_79(73, T, A, B, C, D, E); + BODY_60_79(74, E, T, A, B, C, D); + BODY_60_79(75, D, E, T, A, B, C); + + // We don't use the last value + (void)sched_32_79(vw + 19, w72, w68, w60, w48, w44, k); + BODY_60_79(76, C, D, E, T, A, B); + BODY_60_79(77, B, C, D, E, T, A); + BODY_60_79(78, A, B, C, D, E, T); + BODY_60_79(79, T, A, B, C, D, E); + + const uint32_t mask = 0xffffffffUL; + state[0] = (state[0] + E) & mask; + state[1] = (state[1] + T) & mask; + state[2] = (state[2] + A) & mask; + state[3] = (state[3] + B) & mask; + state[4] = (state[4] + C) & mask; + + data += 64; + if (--num == 0) { + break; + } + + A = state[0]; + B = state[1]; + C = state[2]; + D = state[3]; + E = state[4]; + } +} + +#endif // OPENSSL_PPC64LE + +#undef K_00_19 +#undef K_20_39 +#undef K_40_59 +#undef K_60_79 +#undef F_00_19 +#undef F_20_39 +#undef F_40_59 +#undef F_60_79 +#undef BODY_00_19 +#undef BODY_20_39 +#undef BODY_40_59 +#undef BODY_60_79 diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/sha/sha1.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/sha/sha1.c new file mode 100644 index 0000000..97a4856 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/sha/sha1.c @@ -0,0 +1,375 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 "../../internal.h" + + +#if (!defined(OPENSSL_NO_ASM) && \ + (defined(OPENSSL_X86) || defined(OPENSSL_X86_64) || \ + defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64))) || \ + defined(OPENSSL_PPC64LE) +#define SHA1_ASM +#endif + +int SHA1_Init(SHA_CTX *sha) { + OPENSSL_memset(sha, 0, sizeof(SHA_CTX)); + sha->h[0] = 0x67452301UL; + sha->h[1] = 0xefcdab89UL; + sha->h[2] = 0x98badcfeUL; + sha->h[3] = 0x10325476UL; + sha->h[4] = 0xc3d2e1f0UL; + return 1; +} + +uint8_t *SHA1(const uint8_t *data, size_t len, uint8_t *out) { + SHA_CTX ctx; + SHA1_Init(&ctx); + SHA1_Update(&ctx, data, len); + SHA1_Final(out, &ctx); + OPENSSL_cleanse(&ctx, sizeof(ctx)); + return out; +} + +#define DATA_ORDER_IS_BIG_ENDIAN + +#define HASH_CTX SHA_CTX +#define HASH_CBLOCK 64 +#define HASH_MAKE_STRING(c, s) \ + do { \ + uint32_t ll; \ + ll = (c)->h[0]; \ + HOST_l2c(ll, (s)); \ + ll = (c)->h[1]; \ + HOST_l2c(ll, (s)); \ + ll = (c)->h[2]; \ + HOST_l2c(ll, (s)); \ + ll = (c)->h[3]; \ + HOST_l2c(ll, (s)); \ + ll = (c)->h[4]; \ + HOST_l2c(ll, (s)); \ + } while (0) + +#define HASH_UPDATE SHA1_Update +#define HASH_TRANSFORM SHA1_Transform +#define HASH_FINAL SHA1_Final +#define HASH_BLOCK_DATA_ORDER sha1_block_data_order +#define ROTATE(a, n) (((a) << (n)) | ((a) >> (32 - (n)))) +#define Xupdate(a, ix, ia, ib, ic, id) \ + do { \ + (a) = ((ia) ^ (ib) ^ (ic) ^ (id)); \ + (ix) = (a) = ROTATE((a), 1); \ + } while (0) + +#ifndef SHA1_ASM +static +#endif +void sha1_block_data_order(uint32_t *state, const uint8_t *data, size_t num); + +#include "../digest/md32_common.h" + +#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) + +#define BODY_00_15(i, a, b, c, d, e, f, xi) \ + do { \ + (f) = (xi) + (e) + K_00_19 + ROTATE((a), 5) + F_00_19((b), (c), (d)); \ + (b) = ROTATE((b), 30); \ + } while (0) + +#define BODY_16_19(i, a, b, c, d, e, f, xi, xa, xb, xc, xd) \ + do { \ + 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); \ + } while (0) + +#define BODY_20_31(i, a, b, c, d, e, f, xi, xa, xb, xc, xd) \ + do { \ + 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); \ + } while (0) + +#define BODY_32_39(i, a, b, c, d, e, f, xa, xb, xc, xd) \ + do { \ + 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); \ + } while (0) + +#define BODY_40_59(i, a, b, c, d, e, f, xa, xb, xc, xd) \ + do { \ + 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); \ + } while (0) + +#define BODY_60_79(i, a, b, c, d, e, f, xa, xb, xc, xd) \ + do { \ + 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); \ + } while (0) + +#ifdef X +#undef X +#endif + +/* 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 + +#if !defined(SHA1_ASM) +static void sha1_block_data_order(uint32_t *state, const uint8_t *data, + size_t num) { + register uint32_t A, B, C, D, E, T, l; + uint32_t XX0, XX1, XX2, XX3, XX4, XX5, XX6, XX7, XX8, XX9, XX10, + XX11, XX12, XX13, XX14, XX15; + + A = state[0]; + B = state[1]; + C = state[2]; + D = state[3]; + E = state[4]; + + for (;;) { + HOST_c2l(data, l); + X(0) = l; + HOST_c2l(data, l); + X(1) = l; + BODY_00_15(0, A, B, C, D, E, T, X(0)); + HOST_c2l(data, l); + X(2) = l; + BODY_00_15(1, T, A, B, C, D, E, X(1)); + HOST_c2l(data, l); + X(3) = l; + BODY_00_15(2, E, T, A, B, C, D, X(2)); + HOST_c2l(data, l); + X(4) = l; + BODY_00_15(3, D, E, T, A, B, C, X(3)); + HOST_c2l(data, l); + X(5) = l; + BODY_00_15(4, C, D, E, T, A, B, X(4)); + HOST_c2l(data, l); + X(6) = l; + BODY_00_15(5, B, C, D, E, T, A, X(5)); + HOST_c2l(data, l); + X(7) = l; + BODY_00_15(6, A, B, C, D, E, T, X(6)); + HOST_c2l(data, l); + X(8) = l; + BODY_00_15(7, T, A, B, C, D, E, X(7)); + HOST_c2l(data, l); + X(9) = l; + BODY_00_15(8, E, T, A, B, C, D, X(8)); + HOST_c2l(data, l); + X(10) = l; + BODY_00_15(9, D, E, T, A, B, C, X(9)); + HOST_c2l(data, l); + X(11) = l; + BODY_00_15(10, C, D, E, T, A, B, X(10)); + HOST_c2l(data, l); + X(12) = l; + BODY_00_15(11, B, C, D, E, T, A, X(11)); + HOST_c2l(data, l); + X(13) = l; + BODY_00_15(12, A, B, C, D, E, T, X(12)); + HOST_c2l(data, l); + X(14) = l; + BODY_00_15(13, T, A, B, C, D, E, X(13)); + 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)); + + state[0] = (state[0] + E) & 0xffffffffL; + state[1] = (state[1] + T) & 0xffffffffL; + state[2] = (state[2] + A) & 0xffffffffL; + state[3] = (state[3] + B) & 0xffffffffL; + state[4] = (state[4] + C) & 0xffffffffL; + + if (--num == 0) { + break; + } + + A = state[0]; + B = state[1]; + C = state[2]; + D = state[3]; + E = state[4]; + } +} +#endif + +#undef DATA_ORDER_IS_BIG_ENDIAN +#undef HASH_CTX +#undef HASH_CBLOCK +#undef HASH_MAKE_STRING +#undef HASH_UPDATE +#undef HASH_TRANSFORM +#undef HASH_FINAL +#undef HASH_BLOCK_DATA_ORDER +#undef ROTATE +#undef Xupdate +#undef K_00_19 +#undef K_20_39 +#undef K_40_59 +#undef K_60_79 +#undef F_00_19 +#undef F_20_39 +#undef F_40_59 +#undef F_60_79 +#undef BODY_00_15 +#undef BODY_16_19 +#undef BODY_20_31 +#undef BODY_32_39 +#undef BODY_40_59 +#undef BODY_60_79 +#undef X +#undef HOST_c2l +#undef HOST_l2c diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/sha/sha1.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/sha/sha1.c.grpc_back new file mode 100644 index 0000000..e5b4ba6 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/sha/sha1.c.grpc_back @@ -0,0 +1,375 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 "../../internal.h" + + +#if (!defined(OPENSSL_NO_ASM) && \ + (defined(OPENSSL_X86) || defined(OPENSSL_X86_64) || \ + defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64))) || \ + defined(OPENSSL_PPC64LE) +#define SHA1_ASM +#endif + +int SHA1_Init(SHA_CTX *sha) { + OPENSSL_memset(sha, 0, sizeof(SHA_CTX)); + sha->h[0] = 0x67452301UL; + sha->h[1] = 0xefcdab89UL; + sha->h[2] = 0x98badcfeUL; + sha->h[3] = 0x10325476UL; + sha->h[4] = 0xc3d2e1f0UL; + return 1; +} + +uint8_t *SHA1(const uint8_t *data, size_t len, uint8_t *out) { + SHA_CTX ctx; + SHA1_Init(&ctx); + SHA1_Update(&ctx, data, len); + SHA1_Final(out, &ctx); + OPENSSL_cleanse(&ctx, sizeof(ctx)); + return out; +} + +#define DATA_ORDER_IS_BIG_ENDIAN + +#define HASH_CTX SHA_CTX +#define HASH_CBLOCK 64 +#define HASH_MAKE_STRING(c, s) \ + do { \ + uint32_t ll; \ + ll = (c)->h[0]; \ + HOST_l2c(ll, (s)); \ + ll = (c)->h[1]; \ + HOST_l2c(ll, (s)); \ + ll = (c)->h[2]; \ + HOST_l2c(ll, (s)); \ + ll = (c)->h[3]; \ + HOST_l2c(ll, (s)); \ + ll = (c)->h[4]; \ + HOST_l2c(ll, (s)); \ + } while (0) + +#define HASH_UPDATE SHA1_Update +#define HASH_TRANSFORM SHA1_Transform +#define HASH_FINAL SHA1_Final +#define HASH_BLOCK_DATA_ORDER sha1_block_data_order +#define ROTATE(a, n) (((a) << (n)) | ((a) >> (32 - (n)))) +#define Xupdate(a, ix, ia, ib, ic, id) \ + do { \ + (a) = ((ia) ^ (ib) ^ (ic) ^ (id)); \ + (ix) = (a) = ROTATE((a), 1); \ + } while (0) + +#ifndef SHA1_ASM +static +#endif +void sha1_block_data_order(uint32_t *state, const uint8_t *data, size_t num); + +#include "../digest/md32_common.h" + +#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) + +#define BODY_00_15(i, a, b, c, d, e, f, xi) \ + do { \ + (f) = (xi) + (e) + K_00_19 + ROTATE((a), 5) + F_00_19((b), (c), (d)); \ + (b) = ROTATE((b), 30); \ + } while (0) + +#define BODY_16_19(i, a, b, c, d, e, f, xi, xa, xb, xc, xd) \ + do { \ + 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); \ + } while (0) + +#define BODY_20_31(i, a, b, c, d, e, f, xi, xa, xb, xc, xd) \ + do { \ + 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); \ + } while (0) + +#define BODY_32_39(i, a, b, c, d, e, f, xa, xb, xc, xd) \ + do { \ + 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); \ + } while (0) + +#define BODY_40_59(i, a, b, c, d, e, f, xa, xb, xc, xd) \ + do { \ + 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); \ + } while (0) + +#define BODY_60_79(i, a, b, c, d, e, f, xa, xb, xc, xd) \ + do { \ + 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); \ + } while (0) + +#ifdef X +#undef X +#endif + +/* 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 + +#if !defined(SHA1_ASM) +static void sha1_block_data_order(uint32_t *state, const uint8_t *data, + size_t num) { + register uint32_t A, B, C, D, E, T, l; + uint32_t XX0, XX1, XX2, XX3, XX4, XX5, XX6, XX7, XX8, XX9, XX10, + XX11, XX12, XX13, XX14, XX15; + + A = state[0]; + B = state[1]; + C = state[2]; + D = state[3]; + E = state[4]; + + for (;;) { + HOST_c2l(data, l); + X(0) = l; + HOST_c2l(data, l); + X(1) = l; + BODY_00_15(0, A, B, C, D, E, T, X(0)); + HOST_c2l(data, l); + X(2) = l; + BODY_00_15(1, T, A, B, C, D, E, X(1)); + HOST_c2l(data, l); + X(3) = l; + BODY_00_15(2, E, T, A, B, C, D, X(2)); + HOST_c2l(data, l); + X(4) = l; + BODY_00_15(3, D, E, T, A, B, C, X(3)); + HOST_c2l(data, l); + X(5) = l; + BODY_00_15(4, C, D, E, T, A, B, X(4)); + HOST_c2l(data, l); + X(6) = l; + BODY_00_15(5, B, C, D, E, T, A, X(5)); + HOST_c2l(data, l); + X(7) = l; + BODY_00_15(6, A, B, C, D, E, T, X(6)); + HOST_c2l(data, l); + X(8) = l; + BODY_00_15(7, T, A, B, C, D, E, X(7)); + HOST_c2l(data, l); + X(9) = l; + BODY_00_15(8, E, T, A, B, C, D, X(8)); + HOST_c2l(data, l); + X(10) = l; + BODY_00_15(9, D, E, T, A, B, C, X(9)); + HOST_c2l(data, l); + X(11) = l; + BODY_00_15(10, C, D, E, T, A, B, X(10)); + HOST_c2l(data, l); + X(12) = l; + BODY_00_15(11, B, C, D, E, T, A, X(11)); + HOST_c2l(data, l); + X(13) = l; + BODY_00_15(12, A, B, C, D, E, T, X(12)); + HOST_c2l(data, l); + X(14) = l; + BODY_00_15(13, T, A, B, C, D, E, X(13)); + 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)); + + state[0] = (state[0] + E) & 0xffffffffL; + state[1] = (state[1] + T) & 0xffffffffL; + state[2] = (state[2] + A) & 0xffffffffL; + state[3] = (state[3] + B) & 0xffffffffL; + state[4] = (state[4] + C) & 0xffffffffL; + + if (--num == 0) { + break; + } + + A = state[0]; + B = state[1]; + C = state[2]; + D = state[3]; + E = state[4]; + } +} +#endif + +#undef DATA_ORDER_IS_BIG_ENDIAN +#undef HASH_CTX +#undef HASH_CBLOCK +#undef HASH_MAKE_STRING +#undef HASH_UPDATE +#undef HASH_TRANSFORM +#undef HASH_FINAL +#undef HASH_BLOCK_DATA_ORDER +#undef ROTATE +#undef Xupdate +#undef K_00_19 +#undef K_20_39 +#undef K_40_59 +#undef K_60_79 +#undef F_00_19 +#undef F_20_39 +#undef F_40_59 +#undef F_60_79 +#undef BODY_00_15 +#undef BODY_16_19 +#undef BODY_20_31 +#undef BODY_32_39 +#undef BODY_40_59 +#undef BODY_60_79 +#undef X +#undef HOST_c2l +#undef HOST_l2c diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/sha/sha256.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/sha/sha256.c new file mode 100644 index 0000000..9524d64 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/sha/sha256.c @@ -0,0 +1,337 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 "../../internal.h" + + +#if !defined(OPENSSL_NO_ASM) && \ + (defined(OPENSSL_X86) || defined(OPENSSL_X86_64) || \ + defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)) +#define SHA256_ASM +#endif + +int SHA224_Init(SHA256_CTX *sha) { + OPENSSL_memset(sha, 0, sizeof(SHA256_CTX)); + sha->h[0] = 0xc1059ed8UL; + sha->h[1] = 0x367cd507UL; + sha->h[2] = 0x3070dd17UL; + sha->h[3] = 0xf70e5939UL; + sha->h[4] = 0xffc00b31UL; + sha->h[5] = 0x68581511UL; + sha->h[6] = 0x64f98fa7UL; + sha->h[7] = 0xbefa4fa4UL; + sha->md_len = SHA224_DIGEST_LENGTH; + return 1; +} + +int SHA256_Init(SHA256_CTX *sha) { + OPENSSL_memset(sha, 0, sizeof(SHA256_CTX)); + sha->h[0] = 0x6a09e667UL; + sha->h[1] = 0xbb67ae85UL; + sha->h[2] = 0x3c6ef372UL; + sha->h[3] = 0xa54ff53aUL; + sha->h[4] = 0x510e527fUL; + sha->h[5] = 0x9b05688cUL; + sha->h[6] = 0x1f83d9abUL; + sha->h[7] = 0x5be0cd19UL; + sha->md_len = SHA256_DIGEST_LENGTH; + return 1; +} + +uint8_t *SHA224(const uint8_t *data, size_t len, uint8_t *out) { + SHA256_CTX ctx; + SHA224_Init(&ctx); + SHA224_Update(&ctx, data, len); + SHA224_Final(out, &ctx); + OPENSSL_cleanse(&ctx, sizeof(ctx)); + return out; +} + +uint8_t *SHA256(const uint8_t *data, size_t len, uint8_t *out) { + SHA256_CTX ctx; + SHA256_Init(&ctx); + SHA256_Update(&ctx, data, len); + SHA256_Final(out, &ctx); + OPENSSL_cleanse(&ctx, sizeof(ctx)); + return out; +} + +int SHA224_Update(SHA256_CTX *ctx, const void *data, size_t len) { + return SHA256_Update(ctx, data, len); +} + +int SHA224_Final(uint8_t *md, SHA256_CTX *ctx) { + return SHA256_Final(md, ctx); +} + +#define DATA_ORDER_IS_BIG_ENDIAN + +#define HASH_CTX SHA256_CTX +#define HASH_CBLOCK 64 + +// 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. +// +// TODO(davidben): The small |md_len| case is one of the few places a low-level +// hash 'final' function can fail. This should never happen. +#define HASH_MAKE_STRING(c, s) \ + do { \ + uint32_t ll; \ + unsigned int nn; \ + switch ((c)->md_len) { \ + case SHA224_DIGEST_LENGTH: \ + for (nn = 0; nn < SHA224_DIGEST_LENGTH / 4; nn++) { \ + ll = (c)->h[nn]; \ + HOST_l2c(ll, (s)); \ + } \ + break; \ + case SHA256_DIGEST_LENGTH: \ + for (nn = 0; nn < SHA256_DIGEST_LENGTH / 4; nn++) { \ + ll = (c)->h[nn]; \ + 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]; \ + 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(uint32_t *state, const uint8_t *in, size_t num); + +#include "../digest/md32_common.h" + +#ifndef SHA256_ASM +static const uint32_t 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}; + +#define ROTATE(a, n) (((a) << (n)) | ((a) >> (32 - (n)))) + +// 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))) + +#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(uint32_t *state, const uint8_t *data, + size_t num) { + uint32_t a, b, c, d, e, f, g, h, s0, s1, T1; + uint32_t X[16]; + int i; + + while (num--) { + a = state[0]; + b = state[1]; + c = state[2]; + d = state[3]; + e = state[4]; + f = state[5]; + g = state[6]; + h = state[7]; + + uint32_t 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); + } + + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + state[4] += e; + state[5] += f; + state[6] += g; + state[7] += h; + } +} + +#endif // !SHA256_ASM + +#undef DATA_ORDER_IS_BIG_ENDIAN +#undef HASH_CTX +#undef HASH_CBLOCK +#undef HASH_MAKE_STRING +#undef HASH_UPDATE +#undef HASH_TRANSFORM +#undef HASH_FINAL +#undef HASH_BLOCK_DATA_ORDER +#undef ROTATE +#undef Sigma0 +#undef Sigma1 +#undef sigma0 +#undef sigma1 +#undef Ch +#undef Maj +#undef ROUND_00_15 +#undef ROUND_16_63 +#undef HOST_c2l +#undef HOST_l2c diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/sha/sha256.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/sha/sha256.c.grpc_back new file mode 100644 index 0000000..6d709a6 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/sha/sha256.c.grpc_back @@ -0,0 +1,337 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 "../../internal.h" + + +#if !defined(OPENSSL_NO_ASM) && \ + (defined(OPENSSL_X86) || defined(OPENSSL_X86_64) || \ + defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)) +#define SHA256_ASM +#endif + +int SHA224_Init(SHA256_CTX *sha) { + OPENSSL_memset(sha, 0, sizeof(SHA256_CTX)); + sha->h[0] = 0xc1059ed8UL; + sha->h[1] = 0x367cd507UL; + sha->h[2] = 0x3070dd17UL; + sha->h[3] = 0xf70e5939UL; + sha->h[4] = 0xffc00b31UL; + sha->h[5] = 0x68581511UL; + sha->h[6] = 0x64f98fa7UL; + sha->h[7] = 0xbefa4fa4UL; + sha->md_len = SHA224_DIGEST_LENGTH; + return 1; +} + +int SHA256_Init(SHA256_CTX *sha) { + OPENSSL_memset(sha, 0, sizeof(SHA256_CTX)); + sha->h[0] = 0x6a09e667UL; + sha->h[1] = 0xbb67ae85UL; + sha->h[2] = 0x3c6ef372UL; + sha->h[3] = 0xa54ff53aUL; + sha->h[4] = 0x510e527fUL; + sha->h[5] = 0x9b05688cUL; + sha->h[6] = 0x1f83d9abUL; + sha->h[7] = 0x5be0cd19UL; + sha->md_len = SHA256_DIGEST_LENGTH; + return 1; +} + +uint8_t *SHA224(const uint8_t *data, size_t len, uint8_t *out) { + SHA256_CTX ctx; + SHA224_Init(&ctx); + SHA224_Update(&ctx, data, len); + SHA224_Final(out, &ctx); + OPENSSL_cleanse(&ctx, sizeof(ctx)); + return out; +} + +uint8_t *SHA256(const uint8_t *data, size_t len, uint8_t *out) { + SHA256_CTX ctx; + SHA256_Init(&ctx); + SHA256_Update(&ctx, data, len); + SHA256_Final(out, &ctx); + OPENSSL_cleanse(&ctx, sizeof(ctx)); + return out; +} + +int SHA224_Update(SHA256_CTX *ctx, const void *data, size_t len) { + return SHA256_Update(ctx, data, len); +} + +int SHA224_Final(uint8_t *md, SHA256_CTX *ctx) { + return SHA256_Final(md, ctx); +} + +#define DATA_ORDER_IS_BIG_ENDIAN + +#define HASH_CTX SHA256_CTX +#define HASH_CBLOCK 64 + +// 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. +// +// TODO(davidben): The small |md_len| case is one of the few places a low-level +// hash 'final' function can fail. This should never happen. +#define HASH_MAKE_STRING(c, s) \ + do { \ + uint32_t ll; \ + unsigned int nn; \ + switch ((c)->md_len) { \ + case SHA224_DIGEST_LENGTH: \ + for (nn = 0; nn < SHA224_DIGEST_LENGTH / 4; nn++) { \ + ll = (c)->h[nn]; \ + HOST_l2c(ll, (s)); \ + } \ + break; \ + case SHA256_DIGEST_LENGTH: \ + for (nn = 0; nn < SHA256_DIGEST_LENGTH / 4; nn++) { \ + ll = (c)->h[nn]; \ + 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]; \ + 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(uint32_t *state, const uint8_t *in, size_t num); + +#include "../digest/md32_common.h" + +#ifndef SHA256_ASM +static const uint32_t 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}; + +#define ROTATE(a, n) (((a) << (n)) | ((a) >> (32 - (n)))) + +// 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))) + +#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(uint32_t *state, const uint8_t *data, + size_t num) { + uint32_t a, b, c, d, e, f, g, h, s0, s1, T1; + uint32_t X[16]; + int i; + + while (num--) { + a = state[0]; + b = state[1]; + c = state[2]; + d = state[3]; + e = state[4]; + f = state[5]; + g = state[6]; + h = state[7]; + + uint32_t 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); + } + + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + state[4] += e; + state[5] += f; + state[6] += g; + state[7] += h; + } +} + +#endif // !SHA256_ASM + +#undef DATA_ORDER_IS_BIG_ENDIAN +#undef HASH_CTX +#undef HASH_CBLOCK +#undef HASH_MAKE_STRING +#undef HASH_UPDATE +#undef HASH_TRANSFORM +#undef HASH_FINAL +#undef HASH_BLOCK_DATA_ORDER +#undef ROTATE +#undef Sigma0 +#undef Sigma1 +#undef sigma0 +#undef sigma1 +#undef Ch +#undef Maj +#undef ROUND_00_15 +#undef ROUND_16_63 +#undef HOST_c2l +#undef HOST_l2c diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/sha/sha512.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/sha/sha512.c new file mode 100644 index 0000000..cc40821 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/sha/sha512.c @@ -0,0 +1,608 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 "../../internal.h" + + +// IMPLEMENTATION NOTES. +// +// The 32-bit hash algorithms share a common byte-order neutral collector and +// padding function implementations that operate on unaligned data, +// ../md32_common.h. This SHA-512 implementation does not. 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 a transform function that operates on *aligned* data +// the collector/padding function is simpler and easier to optimize. + +#if !defined(OPENSSL_NO_ASM) && \ + (defined(OPENSSL_X86) || defined(OPENSSL_X86_64) || \ + defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)) +#define SHA512_ASM +#endif + +#if defined(OPENSSL_X86) || defined(OPENSSL_X86_64) || \ + defined(__ARM_FEATURE_UNALIGNED) +#define SHA512_BLOCK_CAN_MANAGE_UNALIGNED_DATA +#endif + +int SHA384_Init(SHA512_CTX *sha) { + sha->h[0] = UINT64_C(0xcbbb9d5dc1059ed8); + sha->h[1] = UINT64_C(0x629a292a367cd507); + sha->h[2] = UINT64_C(0x9159015a3070dd17); + sha->h[3] = UINT64_C(0x152fecd8f70e5939); + sha->h[4] = UINT64_C(0x67332667ffc00b31); + sha->h[5] = UINT64_C(0x8eb44a8768581511); + sha->h[6] = UINT64_C(0xdb0c2e0d64f98fa7); + sha->h[7] = UINT64_C(0x47b5481dbefa4fa4); + + sha->Nl = 0; + sha->Nh = 0; + sha->num = 0; + sha->md_len = SHA384_DIGEST_LENGTH; + return 1; +} + + +int SHA512_Init(SHA512_CTX *sha) { + sha->h[0] = UINT64_C(0x6a09e667f3bcc908); + sha->h[1] = UINT64_C(0xbb67ae8584caa73b); + sha->h[2] = UINT64_C(0x3c6ef372fe94f82b); + sha->h[3] = UINT64_C(0xa54ff53a5f1d36f1); + sha->h[4] = UINT64_C(0x510e527fade682d1); + sha->h[5] = UINT64_C(0x9b05688c2b3e6c1f); + sha->h[6] = UINT64_C(0x1f83d9abfb41bd6b); + sha->h[7] = UINT64_C(0x5be0cd19137e2179); + + sha->Nl = 0; + sha->Nh = 0; + sha->num = 0; + sha->md_len = SHA512_DIGEST_LENGTH; + return 1; +} + +uint8_t *SHA384(const uint8_t *data, size_t len, uint8_t *out) { + SHA512_CTX ctx; + SHA384_Init(&ctx); + SHA384_Update(&ctx, data, len); + SHA384_Final(out, &ctx); + OPENSSL_cleanse(&ctx, sizeof(ctx)); + return out; +} + +uint8_t *SHA512(const uint8_t *data, size_t len, uint8_t *out) { + SHA512_CTX ctx; + SHA512_Init(&ctx); + SHA512_Update(&ctx, data, len); + SHA512_Final(out, &ctx); + OPENSSL_cleanse(&ctx, sizeof(ctx)); + return out; +} + +#if !defined(SHA512_ASM) +static +#endif +void sha512_block_data_order(uint64_t *state, const uint64_t *W, size_t num); + + +int SHA384_Final(uint8_t *md, SHA512_CTX *sha) { + return SHA512_Final(md, sha); +} + +int SHA384_Update(SHA512_CTX *sha, const void *data, size_t len) { + return SHA512_Update(sha, data, len); +} + +void SHA512_Transform(SHA512_CTX *c, const uint8_t *block) { +#ifndef SHA512_BLOCK_CAN_MANAGE_UNALIGNED_DATA + if ((size_t)block % sizeof(c->u.d[0]) != 0) { + OPENSSL_memcpy(c->u.p, block, sizeof(c->u.p)); + block = c->u.p; + } +#endif + sha512_block_data_order(c->h, (uint64_t *)block, 1); +} + +int SHA512_Update(SHA512_CTX *c, const void *in_data, size_t len) { + uint64_t l; + uint8_t *p = c->u.p; + const uint8_t *data = (const uint8_t *)in_data; + + if (len == 0) { + return 1; + } + + l = (c->Nl + (((uint64_t)len) << 3)) & UINT64_C(0xffffffffffffffff); + if (l < c->Nl) { + c->Nh++; + } + if (sizeof(len) >= 8) { + c->Nh += (((uint64_t)len) >> 61); + } + c->Nl = l; + + if (c->num != 0) { + size_t n = sizeof(c->u) - c->num; + + if (len < n) { + OPENSSL_memcpy(p + c->num, data, len); + c->num += (unsigned int)len; + return 1; + } else { + OPENSSL_memcpy(p + c->num, data, n), c->num = 0; + len -= n; + data += n; + sha512_block_data_order(c->h, (uint64_t *)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)) { + OPENSSL_memcpy(p, data, sizeof(c->u)); + sha512_block_data_order(c->h, (uint64_t *)p, 1); + len -= sizeof(c->u); + data += sizeof(c->u); + } + } else +#endif + { + sha512_block_data_order(c->h, (uint64_t *)data, len / sizeof(c->u)); + data += len; + len %= sizeof(c->u); + data -= len; + } + } + + if (len != 0) { + OPENSSL_memcpy(p, data, len); + c->num = (int)len; + } + + return 1; +} + +int SHA512_Final(uint8_t *md, SHA512_CTX *sha) { + uint8_t *p = (uint8_t *)sha->u.p; + size_t n = sha->num; + + p[n] = 0x80; // There always is a room for one + n++; + if (n > (sizeof(sha->u) - 16)) { + OPENSSL_memset(p + n, 0, sizeof(sha->u) - n); + n = 0; + sha512_block_data_order(sha->h, (uint64_t *)p, 1); + } + + OPENSSL_memset(p + n, 0, sizeof(sha->u) - 16 - n); + p[sizeof(sha->u) - 1] = (uint8_t)(sha->Nl); + p[sizeof(sha->u) - 2] = (uint8_t)(sha->Nl >> 8); + p[sizeof(sha->u) - 3] = (uint8_t)(sha->Nl >> 16); + p[sizeof(sha->u) - 4] = (uint8_t)(sha->Nl >> 24); + p[sizeof(sha->u) - 5] = (uint8_t)(sha->Nl >> 32); + p[sizeof(sha->u) - 6] = (uint8_t)(sha->Nl >> 40); + p[sizeof(sha->u) - 7] = (uint8_t)(sha->Nl >> 48); + p[sizeof(sha->u) - 8] = (uint8_t)(sha->Nl >> 56); + p[sizeof(sha->u) - 9] = (uint8_t)(sha->Nh); + p[sizeof(sha->u) - 10] = (uint8_t)(sha->Nh >> 8); + p[sizeof(sha->u) - 11] = (uint8_t)(sha->Nh >> 16); + p[sizeof(sha->u) - 12] = (uint8_t)(sha->Nh >> 24); + p[sizeof(sha->u) - 13] = (uint8_t)(sha->Nh >> 32); + p[sizeof(sha->u) - 14] = (uint8_t)(sha->Nh >> 40); + p[sizeof(sha->u) - 15] = (uint8_t)(sha->Nh >> 48); + p[sizeof(sha->u) - 16] = (uint8_t)(sha->Nh >> 56); + + sha512_block_data_order(sha->h, (uint64_t *)p, 1); + + if (md == NULL) { + // TODO(davidben): This NULL check is absent in other low-level hash 'final' + // functions and is one of the few places one can fail. + return 0; + } + + switch (sha->md_len) { + // Let compiler decide if it's appropriate to unroll... + case SHA384_DIGEST_LENGTH: + for (n = 0; n < SHA384_DIGEST_LENGTH / 8; n++) { + uint64_t t = sha->h[n]; + + *(md++) = (uint8_t)(t >> 56); + *(md++) = (uint8_t)(t >> 48); + *(md++) = (uint8_t)(t >> 40); + *(md++) = (uint8_t)(t >> 32); + *(md++) = (uint8_t)(t >> 24); + *(md++) = (uint8_t)(t >> 16); + *(md++) = (uint8_t)(t >> 8); + *(md++) = (uint8_t)(t); + } + break; + case SHA512_DIGEST_LENGTH: + for (n = 0; n < SHA512_DIGEST_LENGTH / 8; n++) { + uint64_t t = sha->h[n]; + + *(md++) = (uint8_t)(t >> 56); + *(md++) = (uint8_t)(t >> 48); + *(md++) = (uint8_t)(t >> 40); + *(md++) = (uint8_t)(t >> 32); + *(md++) = (uint8_t)(t >> 24); + *(md++) = (uint8_t)(t >> 16); + *(md++) = (uint8_t)(t >> 8); + *(md++) = (uint8_t)(t); + } + break; + // ... as well as make sure md_len is not abused. + default: + // TODO(davidben): This bad |md_len| case is one of the few places a + // low-level hash 'final' function can fail. This should never happen. + return 0; + } + + return 1; +} + +#ifndef SHA512_ASM +static const uint64_t K512[80] = { + UINT64_C(0x428a2f98d728ae22), UINT64_C(0x7137449123ef65cd), + UINT64_C(0xb5c0fbcfec4d3b2f), UINT64_C(0xe9b5dba58189dbbc), + UINT64_C(0x3956c25bf348b538), UINT64_C(0x59f111f1b605d019), + UINT64_C(0x923f82a4af194f9b), UINT64_C(0xab1c5ed5da6d8118), + UINT64_C(0xd807aa98a3030242), UINT64_C(0x12835b0145706fbe), + UINT64_C(0x243185be4ee4b28c), UINT64_C(0x550c7dc3d5ffb4e2), + UINT64_C(0x72be5d74f27b896f), UINT64_C(0x80deb1fe3b1696b1), + UINT64_C(0x9bdc06a725c71235), UINT64_C(0xc19bf174cf692694), + UINT64_C(0xe49b69c19ef14ad2), UINT64_C(0xefbe4786384f25e3), + UINT64_C(0x0fc19dc68b8cd5b5), UINT64_C(0x240ca1cc77ac9c65), + UINT64_C(0x2de92c6f592b0275), UINT64_C(0x4a7484aa6ea6e483), + UINT64_C(0x5cb0a9dcbd41fbd4), UINT64_C(0x76f988da831153b5), + UINT64_C(0x983e5152ee66dfab), UINT64_C(0xa831c66d2db43210), + UINT64_C(0xb00327c898fb213f), UINT64_C(0xbf597fc7beef0ee4), + UINT64_C(0xc6e00bf33da88fc2), UINT64_C(0xd5a79147930aa725), + UINT64_C(0x06ca6351e003826f), UINT64_C(0x142929670a0e6e70), + UINT64_C(0x27b70a8546d22ffc), UINT64_C(0x2e1b21385c26c926), + UINT64_C(0x4d2c6dfc5ac42aed), UINT64_C(0x53380d139d95b3df), + UINT64_C(0x650a73548baf63de), UINT64_C(0x766a0abb3c77b2a8), + UINT64_C(0x81c2c92e47edaee6), UINT64_C(0x92722c851482353b), + UINT64_C(0xa2bfe8a14cf10364), UINT64_C(0xa81a664bbc423001), + UINT64_C(0xc24b8b70d0f89791), UINT64_C(0xc76c51a30654be30), + UINT64_C(0xd192e819d6ef5218), UINT64_C(0xd69906245565a910), + UINT64_C(0xf40e35855771202a), UINT64_C(0x106aa07032bbd1b8), + UINT64_C(0x19a4c116b8d2d0c8), UINT64_C(0x1e376c085141ab53), + UINT64_C(0x2748774cdf8eeb99), UINT64_C(0x34b0bcb5e19b48a8), + UINT64_C(0x391c0cb3c5c95a63), UINT64_C(0x4ed8aa4ae3418acb), + UINT64_C(0x5b9cca4f7763e373), UINT64_C(0x682e6ff3d6b2b8a3), + UINT64_C(0x748f82ee5defb2fc), UINT64_C(0x78a5636f43172f60), + UINT64_C(0x84c87814a1f0ab72), UINT64_C(0x8cc702081a6439ec), + UINT64_C(0x90befffa23631e28), UINT64_C(0xa4506cebde82bde9), + UINT64_C(0xbef9a3f7b2c67915), UINT64_C(0xc67178f2e372532b), + UINT64_C(0xca273eceea26619c), UINT64_C(0xd186b8c721c0c207), + UINT64_C(0xeada7dd6cde0eb1e), UINT64_C(0xf57d4f7fee6ed178), + UINT64_C(0x06f067aa72176fba), UINT64_C(0x0a637dc5a2c898a6), + UINT64_C(0x113f9804bef90dae), UINT64_C(0x1b710b35131c471b), + UINT64_C(0x28db77f523047d84), UINT64_C(0x32caab7b40c72493), + UINT64_C(0x3c9ebe0a15c9bebc), UINT64_C(0x431d67c49c100d4c), + UINT64_C(0x4cc5d4becb3e42b6), UINT64_C(0x597f299cfc657e2a), + UINT64_C(0x5fcb6fab3ad6faec), UINT64_C(0x6c44198c4a475817), +}; + +#if defined(__GNUC__) && __GNUC__ >= 2 && !defined(OPENSSL_NO_ASM) +#if defined(__x86_64) || defined(__x86_64__) +#define ROTR(a, n) \ + ({ \ + uint64_t ret; \ + __asm__("rorq %1, %0" : "=r"(ret) : "J"(n), "0"(a) : "cc"); \ + ret; \ + }) +#define PULL64(x) \ + ({ \ + uint64_t ret = *((const uint64_t *)(&(x))); \ + __asm__("bswapq %0" : "=r"(ret) : "0"(ret)); \ + ret; \ + }) +#elif(defined(__i386) || defined(__i386__)) +#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)); \ + ((uint64_t)hi) << 32 | lo; \ + }) +#elif(defined(_ARCH_PPC) && defined(__64BIT__)) || defined(_ARCH_PPC64) +#define ROTR(a, n) \ + ({ \ + uint64_t ret; \ + __asm__("rotrdi %0, %1, %2" : "=r"(ret) : "r"(a), "K"(n)); \ + ret; \ + }) +#elif defined(__aarch64__) +#define ROTR(a, n) \ + ({ \ + uint64_t 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) \ + ({ \ + uint64_t ret; \ + __asm__("rev %0, %1" : "=r"(ret) : "r"(*((const uint64_t *)(&(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) +static uint64_t __fastcall __pull64be(const void *x) { + _asm mov edx, [ecx + 0] + _asm mov eax, [ecx + 4] + _asm bswap edx + _asm bswap eax +} +#define PULL64(x) __pull64be(&(x)) +#if _MSC_VER <= 1200 +#pragma inline_depth(0) +#endif +#endif +#endif + +#ifndef PULL64 +#define B(x, j) \ + (((uint64_t)(*(((const uint8_t *)(&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(uint64_t *state, const uint64_t *W, + size_t num) { + uint64_t A, E, T; + uint64_t X[9 + 80], *F; + int i; + + while (num--) { + F = X + 80; + A = state[0]; + F[1] = state[1]; + F[2] = state[2]; + F[3] = state[3]; + E = state[4]; + F[5] = state[5]; + F[6] = state[6]; + F[7] = state[7]; + + for (i = 0; i < 16; i++, F--) { + T = PULL64(W[i]); + 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]); + } + + state[0] += A; + state[1] += F[1]; + state[2] += F[2]; + state[3] += F[3]; + state[4] += E; + state[5] += F[5]; + state[6] += F[6]; + state[7] += F[7]; + + W += 16; + } +} + +#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(uint64_t *state, const uint64_t *W, + size_t num) { + uint64_t a, b, c, d, e, f, g, h, s0, s1, T1; + uint64_t X[16]; + int i; + + while (num--) { + + a = state[0]; + b = state[1]; + c = state[2]; + d = state[3]; + e = state[4]; + f = state[5]; + g = state[6]; + h = state[7]; + + 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); + + 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); + } + + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + state[4] += e; + state[5] += f; + state[6] += g; + state[7] += h; + + W += 16; + } +} + +#endif + +#endif // !SHA512_ASM + +#undef ROTR +#undef PULL64 +#undef B +#undef Sigma0 +#undef Sigma1 +#undef sigma0 +#undef sigma1 +#undef Ch +#undef Maj +#undef ROUND_00_15 +#undef ROUND_16_80 +#undef HOST_c2l +#undef HOST_l2c diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/sha/sha512.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/sha/sha512.c.grpc_back new file mode 100644 index 0000000..3902f50 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/sha/sha512.c.grpc_back @@ -0,0 +1,608 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 "../../internal.h" + + +// IMPLEMENTATION NOTES. +// +// The 32-bit hash algorithms share a common byte-order neutral collector and +// padding function implementations that operate on unaligned data, +// ../md32_common.h. This SHA-512 implementation does not. 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 a transform function that operates on *aligned* data +// the collector/padding function is simpler and easier to optimize. + +#if !defined(OPENSSL_NO_ASM) && \ + (defined(OPENSSL_X86) || defined(OPENSSL_X86_64) || \ + defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64)) +#define SHA512_ASM +#endif + +#if defined(OPENSSL_X86) || defined(OPENSSL_X86_64) || \ + defined(__ARM_FEATURE_UNALIGNED) +#define SHA512_BLOCK_CAN_MANAGE_UNALIGNED_DATA +#endif + +int SHA384_Init(SHA512_CTX *sha) { + sha->h[0] = UINT64_C(0xcbbb9d5dc1059ed8); + sha->h[1] = UINT64_C(0x629a292a367cd507); + sha->h[2] = UINT64_C(0x9159015a3070dd17); + sha->h[3] = UINT64_C(0x152fecd8f70e5939); + sha->h[4] = UINT64_C(0x67332667ffc00b31); + sha->h[5] = UINT64_C(0x8eb44a8768581511); + sha->h[6] = UINT64_C(0xdb0c2e0d64f98fa7); + sha->h[7] = UINT64_C(0x47b5481dbefa4fa4); + + sha->Nl = 0; + sha->Nh = 0; + sha->num = 0; + sha->md_len = SHA384_DIGEST_LENGTH; + return 1; +} + + +int SHA512_Init(SHA512_CTX *sha) { + sha->h[0] = UINT64_C(0x6a09e667f3bcc908); + sha->h[1] = UINT64_C(0xbb67ae8584caa73b); + sha->h[2] = UINT64_C(0x3c6ef372fe94f82b); + sha->h[3] = UINT64_C(0xa54ff53a5f1d36f1); + sha->h[4] = UINT64_C(0x510e527fade682d1); + sha->h[5] = UINT64_C(0x9b05688c2b3e6c1f); + sha->h[6] = UINT64_C(0x1f83d9abfb41bd6b); + sha->h[7] = UINT64_C(0x5be0cd19137e2179); + + sha->Nl = 0; + sha->Nh = 0; + sha->num = 0; + sha->md_len = SHA512_DIGEST_LENGTH; + return 1; +} + +uint8_t *SHA384(const uint8_t *data, size_t len, uint8_t *out) { + SHA512_CTX ctx; + SHA384_Init(&ctx); + SHA384_Update(&ctx, data, len); + SHA384_Final(out, &ctx); + OPENSSL_cleanse(&ctx, sizeof(ctx)); + return out; +} + +uint8_t *SHA512(const uint8_t *data, size_t len, uint8_t *out) { + SHA512_CTX ctx; + SHA512_Init(&ctx); + SHA512_Update(&ctx, data, len); + SHA512_Final(out, &ctx); + OPENSSL_cleanse(&ctx, sizeof(ctx)); + return out; +} + +#if !defined(SHA512_ASM) +static +#endif +void sha512_block_data_order(uint64_t *state, const uint64_t *W, size_t num); + + +int SHA384_Final(uint8_t *md, SHA512_CTX *sha) { + return SHA512_Final(md, sha); +} + +int SHA384_Update(SHA512_CTX *sha, const void *data, size_t len) { + return SHA512_Update(sha, data, len); +} + +void SHA512_Transform(SHA512_CTX *c, const uint8_t *block) { +#ifndef SHA512_BLOCK_CAN_MANAGE_UNALIGNED_DATA + if ((size_t)block % sizeof(c->u.d[0]) != 0) { + OPENSSL_memcpy(c->u.p, block, sizeof(c->u.p)); + block = c->u.p; + } +#endif + sha512_block_data_order(c->h, (uint64_t *)block, 1); +} + +int SHA512_Update(SHA512_CTX *c, const void *in_data, size_t len) { + uint64_t l; + uint8_t *p = c->u.p; + const uint8_t *data = (const uint8_t *)in_data; + + if (len == 0) { + return 1; + } + + l = (c->Nl + (((uint64_t)len) << 3)) & UINT64_C(0xffffffffffffffff); + if (l < c->Nl) { + c->Nh++; + } + if (sizeof(len) >= 8) { + c->Nh += (((uint64_t)len) >> 61); + } + c->Nl = l; + + if (c->num != 0) { + size_t n = sizeof(c->u) - c->num; + + if (len < n) { + OPENSSL_memcpy(p + c->num, data, len); + c->num += (unsigned int)len; + return 1; + } else { + OPENSSL_memcpy(p + c->num, data, n), c->num = 0; + len -= n; + data += n; + sha512_block_data_order(c->h, (uint64_t *)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)) { + OPENSSL_memcpy(p, data, sizeof(c->u)); + sha512_block_data_order(c->h, (uint64_t *)p, 1); + len -= sizeof(c->u); + data += sizeof(c->u); + } + } else +#endif + { + sha512_block_data_order(c->h, (uint64_t *)data, len / sizeof(c->u)); + data += len; + len %= sizeof(c->u); + data -= len; + } + } + + if (len != 0) { + OPENSSL_memcpy(p, data, len); + c->num = (int)len; + } + + return 1; +} + +int SHA512_Final(uint8_t *md, SHA512_CTX *sha) { + uint8_t *p = (uint8_t *)sha->u.p; + size_t n = sha->num; + + p[n] = 0x80; // There always is a room for one + n++; + if (n > (sizeof(sha->u) - 16)) { + OPENSSL_memset(p + n, 0, sizeof(sha->u) - n); + n = 0; + sha512_block_data_order(sha->h, (uint64_t *)p, 1); + } + + OPENSSL_memset(p + n, 0, sizeof(sha->u) - 16 - n); + p[sizeof(sha->u) - 1] = (uint8_t)(sha->Nl); + p[sizeof(sha->u) - 2] = (uint8_t)(sha->Nl >> 8); + p[sizeof(sha->u) - 3] = (uint8_t)(sha->Nl >> 16); + p[sizeof(sha->u) - 4] = (uint8_t)(sha->Nl >> 24); + p[sizeof(sha->u) - 5] = (uint8_t)(sha->Nl >> 32); + p[sizeof(sha->u) - 6] = (uint8_t)(sha->Nl >> 40); + p[sizeof(sha->u) - 7] = (uint8_t)(sha->Nl >> 48); + p[sizeof(sha->u) - 8] = (uint8_t)(sha->Nl >> 56); + p[sizeof(sha->u) - 9] = (uint8_t)(sha->Nh); + p[sizeof(sha->u) - 10] = (uint8_t)(sha->Nh >> 8); + p[sizeof(sha->u) - 11] = (uint8_t)(sha->Nh >> 16); + p[sizeof(sha->u) - 12] = (uint8_t)(sha->Nh >> 24); + p[sizeof(sha->u) - 13] = (uint8_t)(sha->Nh >> 32); + p[sizeof(sha->u) - 14] = (uint8_t)(sha->Nh >> 40); + p[sizeof(sha->u) - 15] = (uint8_t)(sha->Nh >> 48); + p[sizeof(sha->u) - 16] = (uint8_t)(sha->Nh >> 56); + + sha512_block_data_order(sha->h, (uint64_t *)p, 1); + + if (md == NULL) { + // TODO(davidben): This NULL check is absent in other low-level hash 'final' + // functions and is one of the few places one can fail. + return 0; + } + + switch (sha->md_len) { + // Let compiler decide if it's appropriate to unroll... + case SHA384_DIGEST_LENGTH: + for (n = 0; n < SHA384_DIGEST_LENGTH / 8; n++) { + uint64_t t = sha->h[n]; + + *(md++) = (uint8_t)(t >> 56); + *(md++) = (uint8_t)(t >> 48); + *(md++) = (uint8_t)(t >> 40); + *(md++) = (uint8_t)(t >> 32); + *(md++) = (uint8_t)(t >> 24); + *(md++) = (uint8_t)(t >> 16); + *(md++) = (uint8_t)(t >> 8); + *(md++) = (uint8_t)(t); + } + break; + case SHA512_DIGEST_LENGTH: + for (n = 0; n < SHA512_DIGEST_LENGTH / 8; n++) { + uint64_t t = sha->h[n]; + + *(md++) = (uint8_t)(t >> 56); + *(md++) = (uint8_t)(t >> 48); + *(md++) = (uint8_t)(t >> 40); + *(md++) = (uint8_t)(t >> 32); + *(md++) = (uint8_t)(t >> 24); + *(md++) = (uint8_t)(t >> 16); + *(md++) = (uint8_t)(t >> 8); + *(md++) = (uint8_t)(t); + } + break; + // ... as well as make sure md_len is not abused. + default: + // TODO(davidben): This bad |md_len| case is one of the few places a + // low-level hash 'final' function can fail. This should never happen. + return 0; + } + + return 1; +} + +#ifndef SHA512_ASM +static const uint64_t K512[80] = { + UINT64_C(0x428a2f98d728ae22), UINT64_C(0x7137449123ef65cd), + UINT64_C(0xb5c0fbcfec4d3b2f), UINT64_C(0xe9b5dba58189dbbc), + UINT64_C(0x3956c25bf348b538), UINT64_C(0x59f111f1b605d019), + UINT64_C(0x923f82a4af194f9b), UINT64_C(0xab1c5ed5da6d8118), + UINT64_C(0xd807aa98a3030242), UINT64_C(0x12835b0145706fbe), + UINT64_C(0x243185be4ee4b28c), UINT64_C(0x550c7dc3d5ffb4e2), + UINT64_C(0x72be5d74f27b896f), UINT64_C(0x80deb1fe3b1696b1), + UINT64_C(0x9bdc06a725c71235), UINT64_C(0xc19bf174cf692694), + UINT64_C(0xe49b69c19ef14ad2), UINT64_C(0xefbe4786384f25e3), + UINT64_C(0x0fc19dc68b8cd5b5), UINT64_C(0x240ca1cc77ac9c65), + UINT64_C(0x2de92c6f592b0275), UINT64_C(0x4a7484aa6ea6e483), + UINT64_C(0x5cb0a9dcbd41fbd4), UINT64_C(0x76f988da831153b5), + UINT64_C(0x983e5152ee66dfab), UINT64_C(0xa831c66d2db43210), + UINT64_C(0xb00327c898fb213f), UINT64_C(0xbf597fc7beef0ee4), + UINT64_C(0xc6e00bf33da88fc2), UINT64_C(0xd5a79147930aa725), + UINT64_C(0x06ca6351e003826f), UINT64_C(0x142929670a0e6e70), + UINT64_C(0x27b70a8546d22ffc), UINT64_C(0x2e1b21385c26c926), + UINT64_C(0x4d2c6dfc5ac42aed), UINT64_C(0x53380d139d95b3df), + UINT64_C(0x650a73548baf63de), UINT64_C(0x766a0abb3c77b2a8), + UINT64_C(0x81c2c92e47edaee6), UINT64_C(0x92722c851482353b), + UINT64_C(0xa2bfe8a14cf10364), UINT64_C(0xa81a664bbc423001), + UINT64_C(0xc24b8b70d0f89791), UINT64_C(0xc76c51a30654be30), + UINT64_C(0xd192e819d6ef5218), UINT64_C(0xd69906245565a910), + UINT64_C(0xf40e35855771202a), UINT64_C(0x106aa07032bbd1b8), + UINT64_C(0x19a4c116b8d2d0c8), UINT64_C(0x1e376c085141ab53), + UINT64_C(0x2748774cdf8eeb99), UINT64_C(0x34b0bcb5e19b48a8), + UINT64_C(0x391c0cb3c5c95a63), UINT64_C(0x4ed8aa4ae3418acb), + UINT64_C(0x5b9cca4f7763e373), UINT64_C(0x682e6ff3d6b2b8a3), + UINT64_C(0x748f82ee5defb2fc), UINT64_C(0x78a5636f43172f60), + UINT64_C(0x84c87814a1f0ab72), UINT64_C(0x8cc702081a6439ec), + UINT64_C(0x90befffa23631e28), UINT64_C(0xa4506cebde82bde9), + UINT64_C(0xbef9a3f7b2c67915), UINT64_C(0xc67178f2e372532b), + UINT64_C(0xca273eceea26619c), UINT64_C(0xd186b8c721c0c207), + UINT64_C(0xeada7dd6cde0eb1e), UINT64_C(0xf57d4f7fee6ed178), + UINT64_C(0x06f067aa72176fba), UINT64_C(0x0a637dc5a2c898a6), + UINT64_C(0x113f9804bef90dae), UINT64_C(0x1b710b35131c471b), + UINT64_C(0x28db77f523047d84), UINT64_C(0x32caab7b40c72493), + UINT64_C(0x3c9ebe0a15c9bebc), UINT64_C(0x431d67c49c100d4c), + UINT64_C(0x4cc5d4becb3e42b6), UINT64_C(0x597f299cfc657e2a), + UINT64_C(0x5fcb6fab3ad6faec), UINT64_C(0x6c44198c4a475817), +}; + +#if defined(__GNUC__) && __GNUC__ >= 2 && !defined(OPENSSL_NO_ASM) +#if defined(__x86_64) || defined(__x86_64__) +#define ROTR(a, n) \ + ({ \ + uint64_t ret; \ + __asm__("rorq %1, %0" : "=r"(ret) : "J"(n), "0"(a) : "cc"); \ + ret; \ + }) +#define PULL64(x) \ + ({ \ + uint64_t ret = *((const uint64_t *)(&(x))); \ + __asm__("bswapq %0" : "=r"(ret) : "0"(ret)); \ + ret; \ + }) +#elif(defined(__i386) || defined(__i386__)) +#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)); \ + ((uint64_t)hi) << 32 | lo; \ + }) +#elif(defined(_ARCH_PPC) && defined(__64BIT__)) || defined(_ARCH_PPC64) +#define ROTR(a, n) \ + ({ \ + uint64_t ret; \ + __asm__("rotrdi %0, %1, %2" : "=r"(ret) : "r"(a), "K"(n)); \ + ret; \ + }) +#elif defined(__aarch64__) +#define ROTR(a, n) \ + ({ \ + uint64_t 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) \ + ({ \ + uint64_t ret; \ + __asm__("rev %0, %1" : "=r"(ret) : "r"(*((const uint64_t *)(&(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) +static uint64_t __fastcall __pull64be(const void *x) { + _asm mov edx, [ecx + 0] + _asm mov eax, [ecx + 4] + _asm bswap edx + _asm bswap eax +} +#define PULL64(x) __pull64be(&(x)) +#if _MSC_VER <= 1200 +#pragma inline_depth(0) +#endif +#endif +#endif + +#ifndef PULL64 +#define B(x, j) \ + (((uint64_t)(*(((const uint8_t *)(&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(uint64_t *state, const uint64_t *W, + size_t num) { + uint64_t A, E, T; + uint64_t X[9 + 80], *F; + int i; + + while (num--) { + F = X + 80; + A = state[0]; + F[1] = state[1]; + F[2] = state[2]; + F[3] = state[3]; + E = state[4]; + F[5] = state[5]; + F[6] = state[6]; + F[7] = state[7]; + + for (i = 0; i < 16; i++, F--) { + T = PULL64(W[i]); + 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]); + } + + state[0] += A; + state[1] += F[1]; + state[2] += F[2]; + state[3] += F[3]; + state[4] += E; + state[5] += F[5]; + state[6] += F[6]; + state[7] += F[7]; + + W += 16; + } +} + +#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(uint64_t *state, const uint64_t *W, + size_t num) { + uint64_t a, b, c, d, e, f, g, h, s0, s1, T1; + uint64_t X[16]; + int i; + + while (num--) { + + a = state[0]; + b = state[1]; + c = state[2]; + d = state[3]; + e = state[4]; + f = state[5]; + g = state[6]; + h = state[7]; + + 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); + + 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); + } + + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + state[4] += e; + state[5] += f; + state[6] += g; + state[7] += h; + + W += 16; + } +} + +#endif + +#endif // !SHA512_ASM + +#undef ROTR +#undef PULL64 +#undef B +#undef Sigma0 +#undef Sigma1 +#undef sigma0 +#undef sigma1 +#undef Ch +#undef Maj +#undef ROUND_00_15 +#undef ROUND_16_80 +#undef HOST_c2l +#undef HOST_l2c diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/tls/internal.h b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/tls/internal.h new file mode 100644 index 0000000..ae3ab7f --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/tls/internal.h @@ -0,0 +1,39 @@ +/* Copyright (c) 2018, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_CRYPTO_FIPSMODULE_TLS_INTERNAL_H +#define OPENSSL_HEADER_CRYPTO_FIPSMODULE_TLS_INTERNAL_H + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// tls1_prf calculates |out_len| bytes of the TLS PDF, using |digest|, and +// writes them to |out|. It returns one on success and zero on error. +OPENSSL_EXPORT int CRYPTO_tls1_prf(const EVP_MD *digest, + uint8_t *out, size_t out_len, + const uint8_t *secret, size_t secret_len, + const char *label, size_t label_len, + const uint8_t *seed1, size_t seed1_len, + const uint8_t *seed2, size_t seed2_len); + + +#if defined(__cplusplus) +} +#endif + +#endif // OPENSSL_HEADER_CRYPTO_FIPSMODULE_TLS_INTERNAL_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/tls/internal.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/tls/internal.h.grpc_back new file mode 100644 index 0000000..ef642a6 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/tls/internal.h.grpc_back @@ -0,0 +1,39 @@ +/* Copyright (c) 2018, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_CRYPTO_FIPSMODULE_TLS_INTERNAL_H +#define OPENSSL_HEADER_CRYPTO_FIPSMODULE_TLS_INTERNAL_H + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// tls1_prf calculates |out_len| bytes of the TLS PDF, using |digest|, and +// writes them to |out|. It returns one on success and zero on error. +OPENSSL_EXPORT int CRYPTO_tls1_prf(const EVP_MD *digest, + uint8_t *out, size_t out_len, + const uint8_t *secret, size_t secret_len, + const char *label, size_t label_len, + const uint8_t *seed1, size_t seed1_len, + const uint8_t *seed2, size_t seed2_len); + + +#if defined(__cplusplus) +} +#endif + +#endif // OPENSSL_HEADER_CRYPTO_FIPSMODULE_TLS_INTERNAL_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/tls/kdf.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/tls/kdf.c new file mode 100644 index 0000000..07e2e4d --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/tls/kdf.c @@ -0,0 +1,165 @@ +/* ==================================================================== + * 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 + +#include +#include +#include + +#include "internal.h" +#include "../../internal.h" + + +// tls1_P_hash computes the TLS P_ function as described in RFC 5246, +// section 5. It XORs |out_len| bytes to |out|, using |md| as the hash and +// |secret| as the secret. |label|, |seed1|, and |seed2| are concatenated to +// form the seed parameter. It returns true on success and false on failure. +static int tls1_P_hash(uint8_t *out, size_t out_len, + const EVP_MD *md, + const uint8_t *secret, size_t secret_len, + const char *label, size_t label_len, + const uint8_t *seed1, size_t seed1_len, + const uint8_t *seed2, size_t seed2_len) { + HMAC_CTX ctx, ctx_tmp, ctx_init; + uint8_t A1[EVP_MAX_MD_SIZE]; + unsigned A1_len; + int ret = 0; + + const size_t chunk = EVP_MD_size(md); + HMAC_CTX_init(&ctx); + HMAC_CTX_init(&ctx_tmp); + HMAC_CTX_init(&ctx_init); + + if (!HMAC_Init_ex(&ctx_init, secret, secret_len, md, NULL) || + !HMAC_CTX_copy_ex(&ctx, &ctx_init) || + !HMAC_Update(&ctx, (const uint8_t *) label, label_len) || + !HMAC_Update(&ctx, seed1, seed1_len) || + !HMAC_Update(&ctx, seed2, seed2_len) || + !HMAC_Final(&ctx, A1, &A1_len)) { + goto err; + } + + for (;;) { + unsigned len; + uint8_t hmac[EVP_MAX_MD_SIZE]; + if (!HMAC_CTX_copy_ex(&ctx, &ctx_init) || + !HMAC_Update(&ctx, A1, A1_len) || + // Save a copy of |ctx| to compute the next A1 value below. + (out_len > chunk && !HMAC_CTX_copy_ex(&ctx_tmp, &ctx)) || + !HMAC_Update(&ctx, (const uint8_t *) label, label_len) || + !HMAC_Update(&ctx, seed1, seed1_len) || + !HMAC_Update(&ctx, seed2, seed2_len) || + !HMAC_Final(&ctx, hmac, &len)) { + goto err; + } + assert(len == chunk); + + // XOR the result into |out|. + if (len > out_len) { + len = out_len; + } + for (unsigned i = 0; i < len; i++) { + out[i] ^= hmac[i]; + } + out += len; + out_len -= len; + + if (out_len == 0) { + break; + } + + // Calculate the next A1 value. + if (!HMAC_Final(&ctx_tmp, A1, &A1_len)) { + goto err; + } + } + + ret = 1; + +err: + OPENSSL_cleanse(A1, sizeof(A1)); + HMAC_CTX_cleanup(&ctx); + HMAC_CTX_cleanup(&ctx_tmp); + HMAC_CTX_cleanup(&ctx_init); + return ret; +} + +int CRYPTO_tls1_prf(const EVP_MD *digest, + uint8_t *out, size_t out_len, + const uint8_t *secret, size_t secret_len, + const char *label, size_t label_len, + const uint8_t *seed1, size_t seed1_len, + const uint8_t *seed2, size_t seed2_len) { + if (out_len == 0) { + return 1; + } + + OPENSSL_memset(out, 0, out_len); + + if (digest == EVP_md5_sha1()) { + // If using the MD5/SHA1 PRF, |secret| is partitioned between MD5 and SHA-1. + size_t secret_half = secret_len - (secret_len / 2); + if (!tls1_P_hash(out, out_len, EVP_md5(), secret, secret_half, label, + label_len, seed1, seed1_len, seed2, seed2_len)) { + return 0; + } + + // Note that, if |secret_len| is odd, the two halves share a byte. + secret += secret_len - secret_half; + secret_len = secret_half; + digest = EVP_sha1(); + } + + return tls1_P_hash(out, out_len, digest, secret, secret_len, label, label_len, + seed1, seed1_len, seed2, seed2_len); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/tls/kdf.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/tls/kdf.c.grpc_back new file mode 100644 index 0000000..347e998 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/fipsmodule/tls/kdf.c.grpc_back @@ -0,0 +1,165 @@ +/* ==================================================================== + * 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 + +#include +#include +#include + +#include "internal.h" +#include "../../internal.h" + + +// tls1_P_hash computes the TLS P_ function as described in RFC 5246, +// section 5. It XORs |out_len| bytes to |out|, using |md| as the hash and +// |secret| as the secret. |label|, |seed1|, and |seed2| are concatenated to +// form the seed parameter. It returns true on success and false on failure. +static int tls1_P_hash(uint8_t *out, size_t out_len, + const EVP_MD *md, + const uint8_t *secret, size_t secret_len, + const char *label, size_t label_len, + const uint8_t *seed1, size_t seed1_len, + const uint8_t *seed2, size_t seed2_len) { + HMAC_CTX ctx, ctx_tmp, ctx_init; + uint8_t A1[EVP_MAX_MD_SIZE]; + unsigned A1_len; + int ret = 0; + + const size_t chunk = EVP_MD_size(md); + HMAC_CTX_init(&ctx); + HMAC_CTX_init(&ctx_tmp); + HMAC_CTX_init(&ctx_init); + + if (!HMAC_Init_ex(&ctx_init, secret, secret_len, md, NULL) || + !HMAC_CTX_copy_ex(&ctx, &ctx_init) || + !HMAC_Update(&ctx, (const uint8_t *) label, label_len) || + !HMAC_Update(&ctx, seed1, seed1_len) || + !HMAC_Update(&ctx, seed2, seed2_len) || + !HMAC_Final(&ctx, A1, &A1_len)) { + goto err; + } + + for (;;) { + unsigned len; + uint8_t hmac[EVP_MAX_MD_SIZE]; + if (!HMAC_CTX_copy_ex(&ctx, &ctx_init) || + !HMAC_Update(&ctx, A1, A1_len) || + // Save a copy of |ctx| to compute the next A1 value below. + (out_len > chunk && !HMAC_CTX_copy_ex(&ctx_tmp, &ctx)) || + !HMAC_Update(&ctx, (const uint8_t *) label, label_len) || + !HMAC_Update(&ctx, seed1, seed1_len) || + !HMAC_Update(&ctx, seed2, seed2_len) || + !HMAC_Final(&ctx, hmac, &len)) { + goto err; + } + assert(len == chunk); + + // XOR the result into |out|. + if (len > out_len) { + len = out_len; + } + for (unsigned i = 0; i < len; i++) { + out[i] ^= hmac[i]; + } + out += len; + out_len -= len; + + if (out_len == 0) { + break; + } + + // Calculate the next A1 value. + if (!HMAC_Final(&ctx_tmp, A1, &A1_len)) { + goto err; + } + } + + ret = 1; + +err: + OPENSSL_cleanse(A1, sizeof(A1)); + HMAC_CTX_cleanup(&ctx); + HMAC_CTX_cleanup(&ctx_tmp); + HMAC_CTX_cleanup(&ctx_init); + return ret; +} + +int CRYPTO_tls1_prf(const EVP_MD *digest, + uint8_t *out, size_t out_len, + const uint8_t *secret, size_t secret_len, + const char *label, size_t label_len, + const uint8_t *seed1, size_t seed1_len, + const uint8_t *seed2, size_t seed2_len) { + if (out_len == 0) { + return 1; + } + + OPENSSL_memset(out, 0, out_len); + + if (digest == EVP_md5_sha1()) { + // If using the MD5/SHA1 PRF, |secret| is partitioned between MD5 and SHA-1. + size_t secret_half = secret_len - (secret_len / 2); + if (!tls1_P_hash(out, out_len, EVP_md5(), secret, secret_half, label, + label_len, seed1, seed1_len, seed2, seed2_len)) { + return 0; + } + + // Note that, if |secret_len| is odd, the two halves share a byte. + secret += secret_len - secret_half; + secret_len = secret_half; + digest = EVP_sha1(); + } + + return tls1_P_hash(out, out_len, digest, secret, secret_len, label, label_len, + seed1, seed1_len, seed2, seed2_len); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/hkdf/hkdf.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/hkdf/hkdf.c new file mode 100644 index 0000000..7f4a28b --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/hkdf/hkdf.c @@ -0,0 +1,112 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include +#include + +#include +#include + +#include "../internal.h" + + +int HKDF(uint8_t *out_key, size_t out_len, const EVP_MD *digest, + const uint8_t *secret, size_t secret_len, const uint8_t *salt, + size_t salt_len, const uint8_t *info, size_t info_len) { + // https://tools.ietf.org/html/rfc5869#section-2 + uint8_t prk[EVP_MAX_MD_SIZE]; + size_t prk_len; + + if (!HKDF_extract(prk, &prk_len, digest, secret, secret_len, salt, + salt_len) || + !HKDF_expand(out_key, out_len, digest, prk, prk_len, info, info_len)) { + return 0; + } + + return 1; +} + +int HKDF_extract(uint8_t *out_key, size_t *out_len, const EVP_MD *digest, + const uint8_t *secret, size_t secret_len, const uint8_t *salt, + size_t salt_len) { + // https://tools.ietf.org/html/rfc5869#section-2.2 + + // If salt is not given, HashLength zeros are used. However, HMAC does that + // internally already so we can ignore it. + unsigned len; + if (HMAC(digest, salt, salt_len, secret, secret_len, out_key, &len) == NULL) { + OPENSSL_PUT_ERROR(HKDF, ERR_R_HMAC_LIB); + return 0; + } + *out_len = len; + assert(*out_len == EVP_MD_size(digest)); + return 1; +} + +int HKDF_expand(uint8_t *out_key, size_t out_len, const EVP_MD *digest, + const uint8_t *prk, size_t prk_len, const uint8_t *info, + size_t info_len) { + // https://tools.ietf.org/html/rfc5869#section-2.3 + const size_t digest_len = EVP_MD_size(digest); + uint8_t previous[EVP_MAX_MD_SIZE]; + size_t n, done = 0; + unsigned i; + int ret = 0; + HMAC_CTX hmac; + + // Expand key material to desired length. + n = (out_len + digest_len - 1) / digest_len; + if (out_len + digest_len < out_len || n > 255) { + OPENSSL_PUT_ERROR(HKDF, HKDF_R_OUTPUT_TOO_LARGE); + return 0; + } + + HMAC_CTX_init(&hmac); + if (!HMAC_Init_ex(&hmac, prk, prk_len, digest, NULL)) { + goto out; + } + + for (i = 0; i < n; i++) { + uint8_t ctr = i + 1; + size_t todo; + + if (i != 0 && (!HMAC_Init_ex(&hmac, NULL, 0, NULL, NULL) || + !HMAC_Update(&hmac, previous, digest_len))) { + goto out; + } + if (!HMAC_Update(&hmac, info, info_len) || + !HMAC_Update(&hmac, &ctr, 1) || + !HMAC_Final(&hmac, previous, NULL)) { + goto out; + } + + todo = digest_len; + if (done + todo > out_len) { + todo = out_len - done; + } + OPENSSL_memcpy(out_key + done, previous, todo); + done += todo; + } + + ret = 1; + +out: + HMAC_CTX_cleanup(&hmac); + if (ret != 1) { + OPENSSL_PUT_ERROR(HKDF, ERR_R_HMAC_LIB); + } + return ret; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/hkdf/hkdf.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/hkdf/hkdf.c.grpc_back new file mode 100644 index 0000000..23b60af --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/hkdf/hkdf.c.grpc_back @@ -0,0 +1,112 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include +#include + +#include +#include + +#include "../internal.h" + + +int HKDF(uint8_t *out_key, size_t out_len, const EVP_MD *digest, + const uint8_t *secret, size_t secret_len, const uint8_t *salt, + size_t salt_len, const uint8_t *info, size_t info_len) { + // https://tools.ietf.org/html/rfc5869#section-2 + uint8_t prk[EVP_MAX_MD_SIZE]; + size_t prk_len; + + if (!HKDF_extract(prk, &prk_len, digest, secret, secret_len, salt, + salt_len) || + !HKDF_expand(out_key, out_len, digest, prk, prk_len, info, info_len)) { + return 0; + } + + return 1; +} + +int HKDF_extract(uint8_t *out_key, size_t *out_len, const EVP_MD *digest, + const uint8_t *secret, size_t secret_len, const uint8_t *salt, + size_t salt_len) { + // https://tools.ietf.org/html/rfc5869#section-2.2 + + // If salt is not given, HashLength zeros are used. However, HMAC does that + // internally already so we can ignore it. + unsigned len; + if (HMAC(digest, salt, salt_len, secret, secret_len, out_key, &len) == NULL) { + OPENSSL_PUT_ERROR(HKDF, ERR_R_HMAC_LIB); + return 0; + } + *out_len = len; + assert(*out_len == EVP_MD_size(digest)); + return 1; +} + +int HKDF_expand(uint8_t *out_key, size_t out_len, const EVP_MD *digest, + const uint8_t *prk, size_t prk_len, const uint8_t *info, + size_t info_len) { + // https://tools.ietf.org/html/rfc5869#section-2.3 + const size_t digest_len = EVP_MD_size(digest); + uint8_t previous[EVP_MAX_MD_SIZE]; + size_t n, done = 0; + unsigned i; + int ret = 0; + HMAC_CTX hmac; + + // Expand key material to desired length. + n = (out_len + digest_len - 1) / digest_len; + if (out_len + digest_len < out_len || n > 255) { + OPENSSL_PUT_ERROR(HKDF, HKDF_R_OUTPUT_TOO_LARGE); + return 0; + } + + HMAC_CTX_init(&hmac); + if (!HMAC_Init_ex(&hmac, prk, prk_len, digest, NULL)) { + goto out; + } + + for (i = 0; i < n; i++) { + uint8_t ctr = i + 1; + size_t todo; + + if (i != 0 && (!HMAC_Init_ex(&hmac, NULL, 0, NULL, NULL) || + !HMAC_Update(&hmac, previous, digest_len))) { + goto out; + } + if (!HMAC_Update(&hmac, info, info_len) || + !HMAC_Update(&hmac, &ctr, 1) || + !HMAC_Final(&hmac, previous, NULL)) { + goto out; + } + + todo = digest_len; + if (done + todo > out_len) { + todo = out_len - done; + } + OPENSSL_memcpy(out_key + done, previous, todo); + done += todo; + } + + ret = 1; + +out: + HMAC_CTX_cleanup(&hmac); + if (ret != 1) { + OPENSSL_PUT_ERROR(HKDF, ERR_R_HMAC_LIB); + } + return ret; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/internal.h b/FoodApp/Pods/BoringSSL-GRPC/crypto/internal.h new file mode 100644 index 0000000..af06032 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/internal.h @@ -0,0 +1,739 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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). */ + +#ifndef OPENSSL_HEADER_CRYPTO_INTERNAL_H +#define OPENSSL_HEADER_CRYPTO_INTERNAL_H + +#include +#include +#include + +#include +#include + +#if defined(__GNUC__) && \ + (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40800 +// |alignas| and |alignof| were added in C11. GCC added support in version 4.8. +// Testing for __STDC_VERSION__/__cplusplus doesn't work because 4.7 already +// reports support for C11. +#define alignas(x) __attribute__ ((aligned (x))) +#define alignof(x) __alignof__ (x) +#elif !defined(__cplusplus) +#if defined(_MSC_VER) +#define alignas(x) __declspec(align(x)) +#define alignof __alignof +#else +#include +#endif +#endif + +#if !defined(OPENSSL_NO_THREADS) && \ + (!defined(OPENSSL_WINDOWS) || defined(__MINGW32__)) +#include +#define OPENSSL_PTHREADS +#endif + +#if !defined(OPENSSL_NO_THREADS) && !defined(OPENSSL_PTHREADS) && \ + defined(OPENSSL_WINDOWS) +#define OPENSSL_WINDOWS_THREADS +OPENSSL_MSVC_PRAGMA(warning(push, 3)) +#include +OPENSSL_MSVC_PRAGMA(warning(pop)) +#endif + +#if defined(__cplusplus) +extern "C" { +#endif + + +#if defined(OPENSSL_X86) || defined(OPENSSL_X86_64) || defined(OPENSSL_ARM) || \ + defined(OPENSSL_AARCH64) || defined(OPENSSL_PPC64LE) +// OPENSSL_cpuid_setup initializes the platform-specific feature cache. +void OPENSSL_cpuid_setup(void); +#endif + + +#if (!defined(_MSC_VER) || defined(__clang__)) && defined(OPENSSL_64_BIT) +#define BORINGSSL_HAS_UINT128 +typedef __int128_t int128_t; +typedef __uint128_t uint128_t; + +// clang-cl supports __uint128_t but modulus and division don't work. +// https://crbug.com/787617. +#if !defined(_MSC_VER) || !defined(__clang__) +#define BORINGSSL_CAN_DIVIDE_UINT128 +#endif +#endif + +#define OPENSSL_ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0])) + +// Have a generic fall-through for different versions of C/C++. +#if defined(__cplusplus) && __cplusplus >= 201703L +#define OPENSSL_FALLTHROUGH [[fallthrough]] +#elif defined(__cplusplus) && __cplusplus >= 201103L && defined(__clang__) +#define OPENSSL_FALLTHROUGH [[clang::fallthrough]] +#elif defined(__cplusplus) && __cplusplus >= 201103L && defined(__GNUC__) && \ + __GNUC__ >= 7 +#define OPENSSL_FALLTHROUGH [[gnu::fallthrough]] +#elif defined(__GNUC__) && __GNUC__ >= 7 // gcc 7 +#define OPENSSL_FALLTHROUGH __attribute__ ((fallthrough)) +#else // C++11 on gcc 6, and all other cases +#define OPENSSL_FALLTHROUGH +#endif + +// buffers_alias returns one if |a| and |b| alias and zero otherwise. +static inline int buffers_alias(const uint8_t *a, size_t a_len, + const uint8_t *b, size_t b_len) { + // Cast |a| and |b| to integers. In C, pointer comparisons between unrelated + // objects are undefined whereas pointer to integer conversions are merely + // implementation-defined. We assume the implementation defined it in a sane + // way. + uintptr_t a_u = (uintptr_t)a; + uintptr_t b_u = (uintptr_t)b; + return a_u + a_len > b_u && b_u + b_len > a_u; +} + + +// Constant-time utility functions. +// +// The following 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 +// +// crypto_word_t lt = constant_time_lt_w(a, b); +// c = constant_time_select_w(lt, a, b); + +// crypto_word_t is the type that most constant-time functions use. Ideally we +// would like it to be |size_t|, but NaCl builds in 64-bit mode with 32-bit +// pointers, which means that |size_t| can be 32 bits when |BN_ULONG| is 64 +// bits. Since we want to be able to do constant-time operations on a +// |BN_ULONG|, |crypto_word_t| is defined as an unsigned value with the native +// word length. +#if defined(OPENSSL_64_BIT) +typedef uint64_t crypto_word_t; +#elif defined(OPENSSL_32_BIT) +typedef uint32_t crypto_word_t; +#else +#error "Must define either OPENSSL_32_BIT or OPENSSL_64_BIT" +#endif + +#define CONSTTIME_TRUE_W ~((crypto_word_t)0) +#define CONSTTIME_FALSE_W ((crypto_word_t)0) +#define CONSTTIME_TRUE_8 ((uint8_t)0xff) + +#define CONSTTIME_TRUE_W ~((crypto_word_t)0) +#define CONSTTIME_FALSE_W ((crypto_word_t)0) +#define CONSTTIME_TRUE_8 ((uint8_t)0xff) +#define CONSTTIME_FALSE_8 ((uint8_t)0) + +// constant_time_msb_w returns the given value with the MSB copied to all the +// other bits. +static inline crypto_word_t constant_time_msb_w(crypto_word_t a) { + return 0u - (a >> (sizeof(a) * 8 - 1)); +} + +// constant_time_lt_w returns 0xff..f if a < b and 0 otherwise. +static inline crypto_word_t constant_time_lt_w(crypto_word_t a, + crypto_word_t b) { + // Consider the two cases of the problem: + // msb(a) == msb(b): a < b iff the MSB of a - b is set. + // msb(a) != msb(b): a < b iff the MSB of b is set. + // + // If msb(a) == msb(b) then the following evaluates as: + // msb(a^((a^b)|((a-b)^a))) == + // msb(a^((a-b) ^ a)) == (because msb(a^b) == 0) + // msb(a^a^(a-b)) == (rearranging) + // msb(a-b) (because ∀x. x^x == 0) + // + // Else, if msb(a) != msb(b) then the following evaluates as: + // msb(a^((a^b)|((a-b)^a))) == + // msb(a^(𝟙 | ((a-b)^a))) == (because msb(a^b) == 1 and 𝟙 + // represents a value s.t. msb(𝟙) = 1) + // msb(a^𝟙) == (because ORing with 1 results in 1) + // msb(b) + // + // + // Here is an SMT-LIB verification of this formula: + // + // (define-fun lt ((a (_ BitVec 32)) (b (_ BitVec 32))) (_ BitVec 32) + // (bvxor a (bvor (bvxor a b) (bvxor (bvsub a b) a))) + // ) + // + // (declare-fun a () (_ BitVec 32)) + // (declare-fun b () (_ BitVec 32)) + // + // (assert (not (= (= #x00000001 (bvlshr (lt a b) #x0000001f)) (bvult a b)))) + // (check-sat) + // (get-model) + return constant_time_msb_w(a^((a^b)|((a-b)^a))); +} + +// constant_time_lt_8 acts like |constant_time_lt_w| but returns an 8-bit +// mask. +static inline uint8_t constant_time_lt_8(crypto_word_t a, crypto_word_t b) { + return (uint8_t)(constant_time_lt_w(a, b)); +} + +// constant_time_ge_w returns 0xff..f if a >= b and 0 otherwise. +static inline crypto_word_t constant_time_ge_w(crypto_word_t a, + crypto_word_t b) { + return ~constant_time_lt_w(a, b); +} + +// constant_time_ge_8 acts like |constant_time_ge_w| but returns an 8-bit +// mask. +static inline uint8_t constant_time_ge_8(crypto_word_t a, crypto_word_t b) { + return (uint8_t)(constant_time_ge_w(a, b)); +} + +// constant_time_is_zero returns 0xff..f if a == 0 and 0 otherwise. +static inline crypto_word_t constant_time_is_zero_w(crypto_word_t a) { + // Here is an SMT-LIB verification of this formula: + // + // (define-fun is_zero ((a (_ BitVec 32))) (_ BitVec 32) + // (bvand (bvnot a) (bvsub a #x00000001)) + // ) + // + // (declare-fun a () (_ BitVec 32)) + // + // (assert (not (= (= #x00000001 (bvlshr (is_zero a) #x0000001f)) (= a #x00000000)))) + // (check-sat) + // (get-model) + return constant_time_msb_w(~a & (a - 1)); +} + +// constant_time_is_zero_8 acts like |constant_time_is_zero_w| but returns an +// 8-bit mask. +static inline uint8_t constant_time_is_zero_8(crypto_word_t a) { + return (uint8_t)(constant_time_is_zero_w(a)); +} + +// constant_time_eq_w returns 0xff..f if a == b and 0 otherwise. +static inline crypto_word_t constant_time_eq_w(crypto_word_t a, + crypto_word_t b) { + return constant_time_is_zero_w(a ^ b); +} + +// constant_time_eq_8 acts like |constant_time_eq_w| but returns an 8-bit +// mask. +static inline uint8_t constant_time_eq_8(crypto_word_t a, crypto_word_t b) { + return (uint8_t)(constant_time_eq_w(a, b)); +} + +// constant_time_eq_int acts like |constant_time_eq_w| but works on int +// values. +static inline crypto_word_t constant_time_eq_int(int a, int b) { + return constant_time_eq_w((crypto_word_t)(a), (crypto_word_t)(b)); +} + +// constant_time_eq_int_8 acts like |constant_time_eq_int| but returns an 8-bit +// mask. +static inline uint8_t constant_time_eq_int_8(int a, int b) { + return constant_time_eq_8((crypto_word_t)(a), (crypto_word_t)(b)); +} + +// constant_time_select_w 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 crypto_word_t constant_time_select_w(crypto_word_t mask, + crypto_word_t a, + crypto_word_t b) { + return (mask & a) | (~mask & b); +} + +// constant_time_select_8 acts like |constant_time_select| but operates on +// 8-bit values. +static inline uint8_t constant_time_select_8(uint8_t mask, uint8_t a, + uint8_t b) { + return (uint8_t)(constant_time_select_w(mask, a, b)); +} + +// constant_time_select_int acts like |constant_time_select| but operates on +// ints. +static inline int constant_time_select_int(crypto_word_t mask, int a, int b) { + return (int)(constant_time_select_w(mask, (crypto_word_t)(a), + (crypto_word_t)(b))); +} + + +// Thread-safe initialisation. + +#if defined(OPENSSL_NO_THREADS) +typedef uint32_t CRYPTO_once_t; +#define CRYPTO_ONCE_INIT 0 +#elif defined(OPENSSL_WINDOWS_THREADS) +typedef INIT_ONCE CRYPTO_once_t; +#define CRYPTO_ONCE_INIT INIT_ONCE_STATIC_INIT +#elif defined(OPENSSL_PTHREADS) +typedef pthread_once_t CRYPTO_once_t; +#define CRYPTO_ONCE_INIT PTHREAD_ONCE_INIT +#else +#error "Unknown threading library" +#endif + +// CRYPTO_once calls |init| exactly once per process. This is thread-safe: if +// concurrent threads call |CRYPTO_once| with the same |CRYPTO_once_t| argument +// then they will block until |init| completes, but |init| will have only been +// called once. +// +// The |once| argument must be a |CRYPTO_once_t| that has been initialised with +// the value |CRYPTO_ONCE_INIT|. +OPENSSL_EXPORT void CRYPTO_once(CRYPTO_once_t *once, void (*init)(void)); + + +// Reference counting. + +// CRYPTO_REFCOUNT_MAX is the value at which the reference count saturates. +#define CRYPTO_REFCOUNT_MAX 0xffffffff + +// CRYPTO_refcount_inc atomically increments the value at |*count| unless the +// value would overflow. It's safe for multiple threads to concurrently call +// this or |CRYPTO_refcount_dec_and_test_zero| on the same +// |CRYPTO_refcount_t|. +OPENSSL_EXPORT void CRYPTO_refcount_inc(CRYPTO_refcount_t *count); + +// CRYPTO_refcount_dec_and_test_zero tests the value at |*count|: +// if it's zero, it crashes the address space. +// if it's the maximum value, it returns zero. +// otherwise, it atomically decrements it and returns one iff the resulting +// value is zero. +// +// It's safe for multiple threads to concurrently call this or +// |CRYPTO_refcount_inc| on the same |CRYPTO_refcount_t|. +OPENSSL_EXPORT int CRYPTO_refcount_dec_and_test_zero(CRYPTO_refcount_t *count); + + +// Locks. +// +// Two types of locks are defined: |CRYPTO_MUTEX|, which can be used in +// structures as normal, and |struct CRYPTO_STATIC_MUTEX|, which can be used as +// a global lock. A global lock must be initialised to the value +// |CRYPTO_STATIC_MUTEX_INIT|. +// +// |CRYPTO_MUTEX| can appear in public structures and so is defined in +// thread.h as a structure large enough to fit the real type. The global lock is +// a different type so it may be initialized with platform initializer macros. + +#if defined(OPENSSL_NO_THREADS) +struct CRYPTO_STATIC_MUTEX { + char padding; // Empty structs have different sizes in C and C++. +}; +#define CRYPTO_STATIC_MUTEX_INIT { 0 } +#elif defined(OPENSSL_WINDOWS_THREADS) +struct CRYPTO_STATIC_MUTEX { + SRWLOCK lock; +}; +#define CRYPTO_STATIC_MUTEX_INIT { SRWLOCK_INIT } +#elif defined(OPENSSL_PTHREADS) +struct CRYPTO_STATIC_MUTEX { + pthread_rwlock_t lock; +}; +#define CRYPTO_STATIC_MUTEX_INIT { PTHREAD_RWLOCK_INITIALIZER } +#else +#error "Unknown threading library" +#endif + +// CRYPTO_MUTEX_init initialises |lock|. If |lock| is a static variable, use a +// |CRYPTO_STATIC_MUTEX|. +OPENSSL_EXPORT void CRYPTO_MUTEX_init(CRYPTO_MUTEX *lock); + +// CRYPTO_MUTEX_lock_read locks |lock| such that other threads may also have a +// read lock, but none may have a write lock. +OPENSSL_EXPORT void CRYPTO_MUTEX_lock_read(CRYPTO_MUTEX *lock); + +// CRYPTO_MUTEX_lock_write locks |lock| such that no other thread has any type +// of lock on it. +OPENSSL_EXPORT void CRYPTO_MUTEX_lock_write(CRYPTO_MUTEX *lock); + +// CRYPTO_MUTEX_unlock_read unlocks |lock| for reading. +OPENSSL_EXPORT void CRYPTO_MUTEX_unlock_read(CRYPTO_MUTEX *lock); + +// CRYPTO_MUTEX_unlock_write unlocks |lock| for writing. +OPENSSL_EXPORT void CRYPTO_MUTEX_unlock_write(CRYPTO_MUTEX *lock); + +// CRYPTO_MUTEX_cleanup releases all resources held by |lock|. +OPENSSL_EXPORT void CRYPTO_MUTEX_cleanup(CRYPTO_MUTEX *lock); + +// CRYPTO_STATIC_MUTEX_lock_read locks |lock| such that other threads may also +// have a read lock, but none may have a write lock. The |lock| variable does +// not need to be initialised by any function, but must have been statically +// initialised with |CRYPTO_STATIC_MUTEX_INIT|. +OPENSSL_EXPORT void CRYPTO_STATIC_MUTEX_lock_read( + struct CRYPTO_STATIC_MUTEX *lock); + +// CRYPTO_STATIC_MUTEX_lock_write locks |lock| such that no other thread has +// any type of lock on it. The |lock| variable does not need to be initialised +// by any function, but must have been statically initialised with +// |CRYPTO_STATIC_MUTEX_INIT|. +OPENSSL_EXPORT void CRYPTO_STATIC_MUTEX_lock_write( + struct CRYPTO_STATIC_MUTEX *lock); + +// CRYPTO_STATIC_MUTEX_unlock_read unlocks |lock| for reading. +OPENSSL_EXPORT void CRYPTO_STATIC_MUTEX_unlock_read( + struct CRYPTO_STATIC_MUTEX *lock); + +// CRYPTO_STATIC_MUTEX_unlock_write unlocks |lock| for writing. +OPENSSL_EXPORT void CRYPTO_STATIC_MUTEX_unlock_write( + struct CRYPTO_STATIC_MUTEX *lock); + +#if defined(__cplusplus) +extern "C++" { + +namespace bssl { + +namespace internal { + +// MutexLockBase is a RAII helper for CRYPTO_MUTEX locking. +template +class MutexLockBase { + public: + explicit MutexLockBase(CRYPTO_MUTEX *mu) : mu_(mu) { + assert(mu_ != nullptr); + LockFunc(mu_); + } + ~MutexLockBase() { ReleaseFunc(mu_); } + MutexLockBase(const MutexLockBase &) = delete; + MutexLockBase &operator=(const MutexLockBase &) = + delete; + + private: + CRYPTO_MUTEX *const mu_; +}; + +} // namespace internal + +using MutexWriteLock = + internal::MutexLockBase; +using MutexReadLock = + internal::MutexLockBase; + +} // namespace bssl + +} // extern "C++" +#endif // defined(__cplusplus) + + +// Thread local storage. + +// thread_local_data_t enumerates the types of thread-local data that can be +// stored. +typedef enum { + OPENSSL_THREAD_LOCAL_ERR = 0, + OPENSSL_THREAD_LOCAL_RAND, + OPENSSL_THREAD_LOCAL_TEST, + NUM_OPENSSL_THREAD_LOCALS, +} thread_local_data_t; + +// thread_local_destructor_t is the type of a destructor function that will be +// called when a thread exits and its thread-local storage needs to be freed. +typedef void (*thread_local_destructor_t)(void *); + +// CRYPTO_get_thread_local gets the pointer value that is stored for the +// current thread for the given index, or NULL if none has been set. +OPENSSL_EXPORT void *CRYPTO_get_thread_local(thread_local_data_t value); + +// CRYPTO_set_thread_local sets a pointer value for the current thread at the +// given index. This function should only be called once per thread for a given +// |index|: rather than update the pointer value itself, update the data that +// is pointed to. +// +// The destructor function will be called when a thread exits to free this +// thread-local data. All calls to |CRYPTO_set_thread_local| with the same +// |index| should have the same |destructor| argument. The destructor may be +// called with a NULL argument if a thread that never set a thread-local +// pointer for |index|, exits. The destructor may be called concurrently with +// different arguments. +// +// This function returns one on success or zero on error. If it returns zero +// then |destructor| has been called with |value| already. +OPENSSL_EXPORT int CRYPTO_set_thread_local( + thread_local_data_t index, void *value, + thread_local_destructor_t destructor); + + +// ex_data + +typedef struct crypto_ex_data_func_st CRYPTO_EX_DATA_FUNCS; + +DECLARE_STACK_OF(CRYPTO_EX_DATA_FUNCS) + +// CRYPTO_EX_DATA_CLASS tracks the ex_indices registered for a type which +// supports ex_data. It should defined as a static global within the module +// which defines that type. +typedef struct { + struct CRYPTO_STATIC_MUTEX lock; + STACK_OF(CRYPTO_EX_DATA_FUNCS) *meth; + // num_reserved is one if the ex_data index zero is reserved for legacy + // |TYPE_get_app_data| functions. + uint8_t num_reserved; +} CRYPTO_EX_DATA_CLASS; + +#define CRYPTO_EX_DATA_CLASS_INIT {CRYPTO_STATIC_MUTEX_INIT, NULL, 0} +#define CRYPTO_EX_DATA_CLASS_INIT_WITH_APP_DATA \ + {CRYPTO_STATIC_MUTEX_INIT, NULL, 1} + +// CRYPTO_get_ex_new_index allocates a new index for |ex_data_class| and writes +// it to |*out_index|. Each class of object should provide a wrapper function +// that uses the correct |CRYPTO_EX_DATA_CLASS|. It returns one on success and +// zero otherwise. +OPENSSL_EXPORT int CRYPTO_get_ex_new_index(CRYPTO_EX_DATA_CLASS *ex_data_class, + int *out_index, long argl, + void *argp, + CRYPTO_EX_free *free_func); + +// CRYPTO_set_ex_data sets an extra data pointer on a given object. Each class +// of object should provide a wrapper function. +OPENSSL_EXPORT int CRYPTO_set_ex_data(CRYPTO_EX_DATA *ad, int index, void *val); + +// CRYPTO_get_ex_data returns an extra data pointer for a given object, or NULL +// if no such index exists. Each class of object should provide a wrapper +// function. +OPENSSL_EXPORT void *CRYPTO_get_ex_data(const CRYPTO_EX_DATA *ad, int index); + +// CRYPTO_new_ex_data initialises a newly allocated |CRYPTO_EX_DATA|. +OPENSSL_EXPORT void CRYPTO_new_ex_data(CRYPTO_EX_DATA *ad); + +// CRYPTO_free_ex_data frees |ad|, which is embedded inside |obj|, which is an +// object of the given class. +OPENSSL_EXPORT void CRYPTO_free_ex_data(CRYPTO_EX_DATA_CLASS *ex_data_class, + void *obj, CRYPTO_EX_DATA *ad); + + +// Endianness conversions. + +#if defined(__GNUC__) && __GNUC__ >= 2 +static inline uint32_t CRYPTO_bswap4(uint32_t x) { + return __builtin_bswap32(x); +} + +static inline uint64_t CRYPTO_bswap8(uint64_t x) { + return __builtin_bswap64(x); +} +#elif defined(_MSC_VER) +OPENSSL_MSVC_PRAGMA(warning(push, 3)) +#include +OPENSSL_MSVC_PRAGMA(warning(pop)) +#pragma intrinsic(_byteswap_uint64, _byteswap_ulong) +static inline uint32_t CRYPTO_bswap4(uint32_t x) { + return _byteswap_ulong(x); +} + +static inline uint64_t CRYPTO_bswap8(uint64_t x) { + return _byteswap_uint64(x); +} +#else +static inline uint32_t CRYPTO_bswap4(uint32_t x) { + x = (x >> 16) | (x << 16); + x = ((x & 0xff00ff00) >> 8) | ((x & 0x00ff00ff) << 8); + return x; +} + +static inline uint64_t CRYPTO_bswap8(uint64_t x) { + return CRYPTO_bswap4(x >> 32) | (((uint64_t)CRYPTO_bswap4(x)) << 32); +} +#endif + + +// Language bug workarounds. +// +// Most C standard library functions are undefined if passed NULL, even when the +// corresponding length is zero. This gives them (and, in turn, all functions +// which call them) surprising behavior on empty arrays. Some compilers will +// miscompile code due to this rule. See also +// https://www.imperialviolet.org/2016/06/26/nonnull.html +// +// These wrapper functions behave the same as the corresponding C standard +// functions, but behave as expected when passed NULL if the length is zero. +// +// Note |OPENSSL_memcmp| is a different function from |CRYPTO_memcmp|. + +// C++ defines |memchr| as a const-correct overload. +#if defined(__cplusplus) +extern "C++" { + +static inline const void *OPENSSL_memchr(const void *s, int c, size_t n) { + if (n == 0) { + return NULL; + } + + return memchr(s, c, n); +} + +static inline void *OPENSSL_memchr(void *s, int c, size_t n) { + if (n == 0) { + return NULL; + } + + return memchr(s, c, n); +} + +} // extern "C++" +#else // __cplusplus + +static inline void *OPENSSL_memchr(const void *s, int c, size_t n) { + if (n == 0) { + return NULL; + } + + return memchr(s, c, n); +} + +#endif // __cplusplus + +static inline int OPENSSL_memcmp(const void *s1, const void *s2, size_t n) { + if (n == 0) { + return 0; + } + + return memcmp(s1, s2, n); +} + +static inline void *OPENSSL_memcpy(void *dst, const void *src, size_t n) { + if (n == 0) { + return dst; + } + + return memcpy(dst, src, n); +} + +static inline void *OPENSSL_memmove(void *dst, const void *src, size_t n) { + if (n == 0) { + return dst; + } + + return memmove(dst, src, n); +} + +static inline void *OPENSSL_memset(void *dst, int c, size_t n) { + if (n == 0) { + return dst; + } + + return memset(dst, c, n); +} + +#if defined(BORINGSSL_FIPS) +// BORINGSSL_FIPS_abort is called when a FIPS power-on or continuous test +// fails. It prevents any further cryptographic operations by the current +// process. +void BORINGSSL_FIPS_abort(void) __attribute__((noreturn)); +#endif + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_CRYPTO_INTERNAL_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/internal.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/internal.h.grpc_back new file mode 100644 index 0000000..067f3bb --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/internal.h.grpc_back @@ -0,0 +1,739 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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). */ + +#ifndef OPENSSL_HEADER_CRYPTO_INTERNAL_H +#define OPENSSL_HEADER_CRYPTO_INTERNAL_H + +#include +#include +#include + +#include +#include + +#if defined(__GNUC__) && \ + (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40800 +// |alignas| and |alignof| were added in C11. GCC added support in version 4.8. +// Testing for __STDC_VERSION__/__cplusplus doesn't work because 4.7 already +// reports support for C11. +#define alignas(x) __attribute__ ((aligned (x))) +#define alignof(x) __alignof__ (x) +#elif !defined(__cplusplus) +#if defined(_MSC_VER) +#define alignas(x) __declspec(align(x)) +#define alignof __alignof +#else +#include +#endif +#endif + +#if !defined(OPENSSL_NO_THREADS) && \ + (!defined(OPENSSL_WINDOWS) || defined(__MINGW32__)) +#include +#define OPENSSL_PTHREADS +#endif + +#if !defined(OPENSSL_NO_THREADS) && !defined(OPENSSL_PTHREADS) && \ + defined(OPENSSL_WINDOWS) +#define OPENSSL_WINDOWS_THREADS +OPENSSL_MSVC_PRAGMA(warning(push, 3)) +#include +OPENSSL_MSVC_PRAGMA(warning(pop)) +#endif + +#if defined(__cplusplus) +extern "C" { +#endif + + +#if defined(OPENSSL_X86) || defined(OPENSSL_X86_64) || defined(OPENSSL_ARM) || \ + defined(OPENSSL_AARCH64) || defined(OPENSSL_PPC64LE) +// OPENSSL_cpuid_setup initializes the platform-specific feature cache. +void OPENSSL_cpuid_setup(void); +#endif + + +#if (!defined(_MSC_VER) || defined(__clang__)) && defined(OPENSSL_64_BIT) +#define BORINGSSL_HAS_UINT128 +typedef __int128_t int128_t; +typedef __uint128_t uint128_t; + +// clang-cl supports __uint128_t but modulus and division don't work. +// https://crbug.com/787617. +#if !defined(_MSC_VER) || !defined(__clang__) +#define BORINGSSL_CAN_DIVIDE_UINT128 +#endif +#endif + +#define OPENSSL_ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0])) + +// Have a generic fall-through for different versions of C/C++. +#if defined(__cplusplus) && __cplusplus >= 201703L +#define OPENSSL_FALLTHROUGH [[fallthrough]] +#elif defined(__cplusplus) && __cplusplus >= 201103L && defined(__clang__) +#define OPENSSL_FALLTHROUGH [[clang::fallthrough]] +#elif defined(__cplusplus) && __cplusplus >= 201103L && defined(__GNUC__) && \ + __GNUC__ >= 7 +#define OPENSSL_FALLTHROUGH [[gnu::fallthrough]] +#elif defined(__GNUC__) && __GNUC__ >= 7 // gcc 7 +#define OPENSSL_FALLTHROUGH __attribute__ ((fallthrough)) +#else // C++11 on gcc 6, and all other cases +#define OPENSSL_FALLTHROUGH +#endif + +// buffers_alias returns one if |a| and |b| alias and zero otherwise. +static inline int buffers_alias(const uint8_t *a, size_t a_len, + const uint8_t *b, size_t b_len) { + // Cast |a| and |b| to integers. In C, pointer comparisons between unrelated + // objects are undefined whereas pointer to integer conversions are merely + // implementation-defined. We assume the implementation defined it in a sane + // way. + uintptr_t a_u = (uintptr_t)a; + uintptr_t b_u = (uintptr_t)b; + return a_u + a_len > b_u && b_u + b_len > a_u; +} + + +// Constant-time utility functions. +// +// The following 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 +// +// crypto_word_t lt = constant_time_lt_w(a, b); +// c = constant_time_select_w(lt, a, b); + +// crypto_word_t is the type that most constant-time functions use. Ideally we +// would like it to be |size_t|, but NaCl builds in 64-bit mode with 32-bit +// pointers, which means that |size_t| can be 32 bits when |BN_ULONG| is 64 +// bits. Since we want to be able to do constant-time operations on a +// |BN_ULONG|, |crypto_word_t| is defined as an unsigned value with the native +// word length. +#if defined(OPENSSL_64_BIT) +typedef uint64_t crypto_word_t; +#elif defined(OPENSSL_32_BIT) +typedef uint32_t crypto_word_t; +#else +#error "Must define either OPENSSL_32_BIT or OPENSSL_64_BIT" +#endif + +#define CONSTTIME_TRUE_W ~((crypto_word_t)0) +#define CONSTTIME_FALSE_W ((crypto_word_t)0) +#define CONSTTIME_TRUE_8 ((uint8_t)0xff) + +#define CONSTTIME_TRUE_W ~((crypto_word_t)0) +#define CONSTTIME_FALSE_W ((crypto_word_t)0) +#define CONSTTIME_TRUE_8 ((uint8_t)0xff) +#define CONSTTIME_FALSE_8 ((uint8_t)0) + +// constant_time_msb_w returns the given value with the MSB copied to all the +// other bits. +static inline crypto_word_t constant_time_msb_w(crypto_word_t a) { + return 0u - (a >> (sizeof(a) * 8 - 1)); +} + +// constant_time_lt_w returns 0xff..f if a < b and 0 otherwise. +static inline crypto_word_t constant_time_lt_w(crypto_word_t a, + crypto_word_t b) { + // Consider the two cases of the problem: + // msb(a) == msb(b): a < b iff the MSB of a - b is set. + // msb(a) != msb(b): a < b iff the MSB of b is set. + // + // If msb(a) == msb(b) then the following evaluates as: + // msb(a^((a^b)|((a-b)^a))) == + // msb(a^((a-b) ^ a)) == (because msb(a^b) == 0) + // msb(a^a^(a-b)) == (rearranging) + // msb(a-b) (because ∀x. x^x == 0) + // + // Else, if msb(a) != msb(b) then the following evaluates as: + // msb(a^((a^b)|((a-b)^a))) == + // msb(a^(𝟙 | ((a-b)^a))) == (because msb(a^b) == 1 and 𝟙 + // represents a value s.t. msb(𝟙) = 1) + // msb(a^𝟙) == (because ORing with 1 results in 1) + // msb(b) + // + // + // Here is an SMT-LIB verification of this formula: + // + // (define-fun lt ((a (_ BitVec 32)) (b (_ BitVec 32))) (_ BitVec 32) + // (bvxor a (bvor (bvxor a b) (bvxor (bvsub a b) a))) + // ) + // + // (declare-fun a () (_ BitVec 32)) + // (declare-fun b () (_ BitVec 32)) + // + // (assert (not (= (= #x00000001 (bvlshr (lt a b) #x0000001f)) (bvult a b)))) + // (check-sat) + // (get-model) + return constant_time_msb_w(a^((a^b)|((a-b)^a))); +} + +// constant_time_lt_8 acts like |constant_time_lt_w| but returns an 8-bit +// mask. +static inline uint8_t constant_time_lt_8(crypto_word_t a, crypto_word_t b) { + return (uint8_t)(constant_time_lt_w(a, b)); +} + +// constant_time_ge_w returns 0xff..f if a >= b and 0 otherwise. +static inline crypto_word_t constant_time_ge_w(crypto_word_t a, + crypto_word_t b) { + return ~constant_time_lt_w(a, b); +} + +// constant_time_ge_8 acts like |constant_time_ge_w| but returns an 8-bit +// mask. +static inline uint8_t constant_time_ge_8(crypto_word_t a, crypto_word_t b) { + return (uint8_t)(constant_time_ge_w(a, b)); +} + +// constant_time_is_zero returns 0xff..f if a == 0 and 0 otherwise. +static inline crypto_word_t constant_time_is_zero_w(crypto_word_t a) { + // Here is an SMT-LIB verification of this formula: + // + // (define-fun is_zero ((a (_ BitVec 32))) (_ BitVec 32) + // (bvand (bvnot a) (bvsub a #x00000001)) + // ) + // + // (declare-fun a () (_ BitVec 32)) + // + // (assert (not (= (= #x00000001 (bvlshr (is_zero a) #x0000001f)) (= a #x00000000)))) + // (check-sat) + // (get-model) + return constant_time_msb_w(~a & (a - 1)); +} + +// constant_time_is_zero_8 acts like |constant_time_is_zero_w| but returns an +// 8-bit mask. +static inline uint8_t constant_time_is_zero_8(crypto_word_t a) { + return (uint8_t)(constant_time_is_zero_w(a)); +} + +// constant_time_eq_w returns 0xff..f if a == b and 0 otherwise. +static inline crypto_word_t constant_time_eq_w(crypto_word_t a, + crypto_word_t b) { + return constant_time_is_zero_w(a ^ b); +} + +// constant_time_eq_8 acts like |constant_time_eq_w| but returns an 8-bit +// mask. +static inline uint8_t constant_time_eq_8(crypto_word_t a, crypto_word_t b) { + return (uint8_t)(constant_time_eq_w(a, b)); +} + +// constant_time_eq_int acts like |constant_time_eq_w| but works on int +// values. +static inline crypto_word_t constant_time_eq_int(int a, int b) { + return constant_time_eq_w((crypto_word_t)(a), (crypto_word_t)(b)); +} + +// constant_time_eq_int_8 acts like |constant_time_eq_int| but returns an 8-bit +// mask. +static inline uint8_t constant_time_eq_int_8(int a, int b) { + return constant_time_eq_8((crypto_word_t)(a), (crypto_word_t)(b)); +} + +// constant_time_select_w 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 crypto_word_t constant_time_select_w(crypto_word_t mask, + crypto_word_t a, + crypto_word_t b) { + return (mask & a) | (~mask & b); +} + +// constant_time_select_8 acts like |constant_time_select| but operates on +// 8-bit values. +static inline uint8_t constant_time_select_8(uint8_t mask, uint8_t a, + uint8_t b) { + return (uint8_t)(constant_time_select_w(mask, a, b)); +} + +// constant_time_select_int acts like |constant_time_select| but operates on +// ints. +static inline int constant_time_select_int(crypto_word_t mask, int a, int b) { + return (int)(constant_time_select_w(mask, (crypto_word_t)(a), + (crypto_word_t)(b))); +} + + +// Thread-safe initialisation. + +#if defined(OPENSSL_NO_THREADS) +typedef uint32_t CRYPTO_once_t; +#define CRYPTO_ONCE_INIT 0 +#elif defined(OPENSSL_WINDOWS_THREADS) +typedef INIT_ONCE CRYPTO_once_t; +#define CRYPTO_ONCE_INIT INIT_ONCE_STATIC_INIT +#elif defined(OPENSSL_PTHREADS) +typedef pthread_once_t CRYPTO_once_t; +#define CRYPTO_ONCE_INIT PTHREAD_ONCE_INIT +#else +#error "Unknown threading library" +#endif + +// CRYPTO_once calls |init| exactly once per process. This is thread-safe: if +// concurrent threads call |CRYPTO_once| with the same |CRYPTO_once_t| argument +// then they will block until |init| completes, but |init| will have only been +// called once. +// +// The |once| argument must be a |CRYPTO_once_t| that has been initialised with +// the value |CRYPTO_ONCE_INIT|. +OPENSSL_EXPORT void CRYPTO_once(CRYPTO_once_t *once, void (*init)(void)); + + +// Reference counting. + +// CRYPTO_REFCOUNT_MAX is the value at which the reference count saturates. +#define CRYPTO_REFCOUNT_MAX 0xffffffff + +// CRYPTO_refcount_inc atomically increments the value at |*count| unless the +// value would overflow. It's safe for multiple threads to concurrently call +// this or |CRYPTO_refcount_dec_and_test_zero| on the same +// |CRYPTO_refcount_t|. +OPENSSL_EXPORT void CRYPTO_refcount_inc(CRYPTO_refcount_t *count); + +// CRYPTO_refcount_dec_and_test_zero tests the value at |*count|: +// if it's zero, it crashes the address space. +// if it's the maximum value, it returns zero. +// otherwise, it atomically decrements it and returns one iff the resulting +// value is zero. +// +// It's safe for multiple threads to concurrently call this or +// |CRYPTO_refcount_inc| on the same |CRYPTO_refcount_t|. +OPENSSL_EXPORT int CRYPTO_refcount_dec_and_test_zero(CRYPTO_refcount_t *count); + + +// Locks. +// +// Two types of locks are defined: |CRYPTO_MUTEX|, which can be used in +// structures as normal, and |struct CRYPTO_STATIC_MUTEX|, which can be used as +// a global lock. A global lock must be initialised to the value +// |CRYPTO_STATIC_MUTEX_INIT|. +// +// |CRYPTO_MUTEX| can appear in public structures and so is defined in +// thread.h as a structure large enough to fit the real type. The global lock is +// a different type so it may be initialized with platform initializer macros. + +#if defined(OPENSSL_NO_THREADS) +struct CRYPTO_STATIC_MUTEX { + char padding; // Empty structs have different sizes in C and C++. +}; +#define CRYPTO_STATIC_MUTEX_INIT { 0 } +#elif defined(OPENSSL_WINDOWS_THREADS) +struct CRYPTO_STATIC_MUTEX { + SRWLOCK lock; +}; +#define CRYPTO_STATIC_MUTEX_INIT { SRWLOCK_INIT } +#elif defined(OPENSSL_PTHREADS) +struct CRYPTO_STATIC_MUTEX { + pthread_rwlock_t lock; +}; +#define CRYPTO_STATIC_MUTEX_INIT { PTHREAD_RWLOCK_INITIALIZER } +#else +#error "Unknown threading library" +#endif + +// CRYPTO_MUTEX_init initialises |lock|. If |lock| is a static variable, use a +// |CRYPTO_STATIC_MUTEX|. +OPENSSL_EXPORT void CRYPTO_MUTEX_init(CRYPTO_MUTEX *lock); + +// CRYPTO_MUTEX_lock_read locks |lock| such that other threads may also have a +// read lock, but none may have a write lock. +OPENSSL_EXPORT void CRYPTO_MUTEX_lock_read(CRYPTO_MUTEX *lock); + +// CRYPTO_MUTEX_lock_write locks |lock| such that no other thread has any type +// of lock on it. +OPENSSL_EXPORT void CRYPTO_MUTEX_lock_write(CRYPTO_MUTEX *lock); + +// CRYPTO_MUTEX_unlock_read unlocks |lock| for reading. +OPENSSL_EXPORT void CRYPTO_MUTEX_unlock_read(CRYPTO_MUTEX *lock); + +// CRYPTO_MUTEX_unlock_write unlocks |lock| for writing. +OPENSSL_EXPORT void CRYPTO_MUTEX_unlock_write(CRYPTO_MUTEX *lock); + +// CRYPTO_MUTEX_cleanup releases all resources held by |lock|. +OPENSSL_EXPORT void CRYPTO_MUTEX_cleanup(CRYPTO_MUTEX *lock); + +// CRYPTO_STATIC_MUTEX_lock_read locks |lock| such that other threads may also +// have a read lock, but none may have a write lock. The |lock| variable does +// not need to be initialised by any function, but must have been statically +// initialised with |CRYPTO_STATIC_MUTEX_INIT|. +OPENSSL_EXPORT void CRYPTO_STATIC_MUTEX_lock_read( + struct CRYPTO_STATIC_MUTEX *lock); + +// CRYPTO_STATIC_MUTEX_lock_write locks |lock| such that no other thread has +// any type of lock on it. The |lock| variable does not need to be initialised +// by any function, but must have been statically initialised with +// |CRYPTO_STATIC_MUTEX_INIT|. +OPENSSL_EXPORT void CRYPTO_STATIC_MUTEX_lock_write( + struct CRYPTO_STATIC_MUTEX *lock); + +// CRYPTO_STATIC_MUTEX_unlock_read unlocks |lock| for reading. +OPENSSL_EXPORT void CRYPTO_STATIC_MUTEX_unlock_read( + struct CRYPTO_STATIC_MUTEX *lock); + +// CRYPTO_STATIC_MUTEX_unlock_write unlocks |lock| for writing. +OPENSSL_EXPORT void CRYPTO_STATIC_MUTEX_unlock_write( + struct CRYPTO_STATIC_MUTEX *lock); + +#if defined(__cplusplus) +extern "C++" { + +namespace bssl { + +namespace internal { + +// MutexLockBase is a RAII helper for CRYPTO_MUTEX locking. +template +class MutexLockBase { + public: + explicit MutexLockBase(CRYPTO_MUTEX *mu) : mu_(mu) { + assert(mu_ != nullptr); + LockFunc(mu_); + } + ~MutexLockBase() { ReleaseFunc(mu_); } + MutexLockBase(const MutexLockBase &) = delete; + MutexLockBase &operator=(const MutexLockBase &) = + delete; + + private: + CRYPTO_MUTEX *const mu_; +}; + +} // namespace internal + +using MutexWriteLock = + internal::MutexLockBase; +using MutexReadLock = + internal::MutexLockBase; + +} // namespace bssl + +} // extern "C++" +#endif // defined(__cplusplus) + + +// Thread local storage. + +// thread_local_data_t enumerates the types of thread-local data that can be +// stored. +typedef enum { + OPENSSL_THREAD_LOCAL_ERR = 0, + OPENSSL_THREAD_LOCAL_RAND, + OPENSSL_THREAD_LOCAL_TEST, + NUM_OPENSSL_THREAD_LOCALS, +} thread_local_data_t; + +// thread_local_destructor_t is the type of a destructor function that will be +// called when a thread exits and its thread-local storage needs to be freed. +typedef void (*thread_local_destructor_t)(void *); + +// CRYPTO_get_thread_local gets the pointer value that is stored for the +// current thread for the given index, or NULL if none has been set. +OPENSSL_EXPORT void *CRYPTO_get_thread_local(thread_local_data_t value); + +// CRYPTO_set_thread_local sets a pointer value for the current thread at the +// given index. This function should only be called once per thread for a given +// |index|: rather than update the pointer value itself, update the data that +// is pointed to. +// +// The destructor function will be called when a thread exits to free this +// thread-local data. All calls to |CRYPTO_set_thread_local| with the same +// |index| should have the same |destructor| argument. The destructor may be +// called with a NULL argument if a thread that never set a thread-local +// pointer for |index|, exits. The destructor may be called concurrently with +// different arguments. +// +// This function returns one on success or zero on error. If it returns zero +// then |destructor| has been called with |value| already. +OPENSSL_EXPORT int CRYPTO_set_thread_local( + thread_local_data_t index, void *value, + thread_local_destructor_t destructor); + + +// ex_data + +typedef struct crypto_ex_data_func_st CRYPTO_EX_DATA_FUNCS; + +DECLARE_STACK_OF(CRYPTO_EX_DATA_FUNCS) + +// CRYPTO_EX_DATA_CLASS tracks the ex_indices registered for a type which +// supports ex_data. It should defined as a static global within the module +// which defines that type. +typedef struct { + struct CRYPTO_STATIC_MUTEX lock; + STACK_OF(CRYPTO_EX_DATA_FUNCS) *meth; + // num_reserved is one if the ex_data index zero is reserved for legacy + // |TYPE_get_app_data| functions. + uint8_t num_reserved; +} CRYPTO_EX_DATA_CLASS; + +#define CRYPTO_EX_DATA_CLASS_INIT {CRYPTO_STATIC_MUTEX_INIT, NULL, 0} +#define CRYPTO_EX_DATA_CLASS_INIT_WITH_APP_DATA \ + {CRYPTO_STATIC_MUTEX_INIT, NULL, 1} + +// CRYPTO_get_ex_new_index allocates a new index for |ex_data_class| and writes +// it to |*out_index|. Each class of object should provide a wrapper function +// that uses the correct |CRYPTO_EX_DATA_CLASS|. It returns one on success and +// zero otherwise. +OPENSSL_EXPORT int CRYPTO_get_ex_new_index(CRYPTO_EX_DATA_CLASS *ex_data_class, + int *out_index, long argl, + void *argp, + CRYPTO_EX_free *free_func); + +// CRYPTO_set_ex_data sets an extra data pointer on a given object. Each class +// of object should provide a wrapper function. +OPENSSL_EXPORT int CRYPTO_set_ex_data(CRYPTO_EX_DATA *ad, int index, void *val); + +// CRYPTO_get_ex_data returns an extra data pointer for a given object, or NULL +// if no such index exists. Each class of object should provide a wrapper +// function. +OPENSSL_EXPORT void *CRYPTO_get_ex_data(const CRYPTO_EX_DATA *ad, int index); + +// CRYPTO_new_ex_data initialises a newly allocated |CRYPTO_EX_DATA|. +OPENSSL_EXPORT void CRYPTO_new_ex_data(CRYPTO_EX_DATA *ad); + +// CRYPTO_free_ex_data frees |ad|, which is embedded inside |obj|, which is an +// object of the given class. +OPENSSL_EXPORT void CRYPTO_free_ex_data(CRYPTO_EX_DATA_CLASS *ex_data_class, + void *obj, CRYPTO_EX_DATA *ad); + + +// Endianness conversions. + +#if defined(__GNUC__) && __GNUC__ >= 2 +static inline uint32_t CRYPTO_bswap4(uint32_t x) { + return __builtin_bswap32(x); +} + +static inline uint64_t CRYPTO_bswap8(uint64_t x) { + return __builtin_bswap64(x); +} +#elif defined(_MSC_VER) +OPENSSL_MSVC_PRAGMA(warning(push, 3)) +#include +OPENSSL_MSVC_PRAGMA(warning(pop)) +#pragma intrinsic(_byteswap_uint64, _byteswap_ulong) +static inline uint32_t CRYPTO_bswap4(uint32_t x) { + return _byteswap_ulong(x); +} + +static inline uint64_t CRYPTO_bswap8(uint64_t x) { + return _byteswap_uint64(x); +} +#else +static inline uint32_t CRYPTO_bswap4(uint32_t x) { + x = (x >> 16) | (x << 16); + x = ((x & 0xff00ff00) >> 8) | ((x & 0x00ff00ff) << 8); + return x; +} + +static inline uint64_t CRYPTO_bswap8(uint64_t x) { + return CRYPTO_bswap4(x >> 32) | (((uint64_t)CRYPTO_bswap4(x)) << 32); +} +#endif + + +// Language bug workarounds. +// +// Most C standard library functions are undefined if passed NULL, even when the +// corresponding length is zero. This gives them (and, in turn, all functions +// which call them) surprising behavior on empty arrays. Some compilers will +// miscompile code due to this rule. See also +// https://www.imperialviolet.org/2016/06/26/nonnull.html +// +// These wrapper functions behave the same as the corresponding C standard +// functions, but behave as expected when passed NULL if the length is zero. +// +// Note |OPENSSL_memcmp| is a different function from |CRYPTO_memcmp|. + +// C++ defines |memchr| as a const-correct overload. +#if defined(__cplusplus) +extern "C++" { + +static inline const void *OPENSSL_memchr(const void *s, int c, size_t n) { + if (n == 0) { + return NULL; + } + + return memchr(s, c, n); +} + +static inline void *OPENSSL_memchr(void *s, int c, size_t n) { + if (n == 0) { + return NULL; + } + + return memchr(s, c, n); +} + +} // extern "C++" +#else // __cplusplus + +static inline void *OPENSSL_memchr(const void *s, int c, size_t n) { + if (n == 0) { + return NULL; + } + + return memchr(s, c, n); +} + +#endif // __cplusplus + +static inline int OPENSSL_memcmp(const void *s1, const void *s2, size_t n) { + if (n == 0) { + return 0; + } + + return memcmp(s1, s2, n); +} + +static inline void *OPENSSL_memcpy(void *dst, const void *src, size_t n) { + if (n == 0) { + return dst; + } + + return memcpy(dst, src, n); +} + +static inline void *OPENSSL_memmove(void *dst, const void *src, size_t n) { + if (n == 0) { + return dst; + } + + return memmove(dst, src, n); +} + +static inline void *OPENSSL_memset(void *dst, int c, size_t n) { + if (n == 0) { + return dst; + } + + return memset(dst, c, n); +} + +#if defined(BORINGSSL_FIPS) +// BORINGSSL_FIPS_abort is called when a FIPS power-on or continuous test +// fails. It prevents any further cryptographic operations by the current +// process. +void BORINGSSL_FIPS_abort(void) __attribute__((noreturn)); +#endif + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_CRYPTO_INTERNAL_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/lhash/lhash.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/lhash/lhash.c new file mode 100644 index 0000000..27e0481 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/lhash/lhash.c @@ -0,0 +1,336 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 + +#include "../internal.h" + + +// kMinNumBuckets is the minimum size of the buckets array in an |_LHASH|. +static const size_t kMinNumBuckets = 16; + +// kMaxAverageChainLength contains the maximum, average chain length. When the +// average chain length exceeds this value, the hash table will be resized. +static const size_t kMaxAverageChainLength = 2; +static const size_t kMinAverageChainLength = 1; + +struct lhash_st { + // num_items contains the total number of items in the hash table. + size_t num_items; + // buckets is an array of |num_buckets| pointers. Each points to the head of + // a chain of LHASH_ITEM objects that have the same hash value, mod + // |num_buckets|. + LHASH_ITEM **buckets; + // num_buckets contains the length of |buckets|. This value is always >= + // kMinNumBuckets. + size_t num_buckets; + // callback_depth contains the current depth of |lh_doall| or |lh_doall_arg| + // calls. If non-zero then this suppresses resizing of the |buckets| array, + // which would otherwise disrupt the iteration. + unsigned callback_depth; + + lhash_cmp_func comp; + lhash_hash_func hash; +}; + +_LHASH *lh_new(lhash_hash_func hash, lhash_cmp_func comp) { + _LHASH *ret = OPENSSL_malloc(sizeof(_LHASH)); + if (ret == NULL) { + return NULL; + } + OPENSSL_memset(ret, 0, sizeof(_LHASH)); + + ret->num_buckets = kMinNumBuckets; + ret->buckets = OPENSSL_malloc(sizeof(LHASH_ITEM *) * ret->num_buckets); + if (ret->buckets == NULL) { + OPENSSL_free(ret); + return NULL; + } + OPENSSL_memset(ret->buckets, 0, sizeof(LHASH_ITEM *) * ret->num_buckets); + + ret->comp = comp; + ret->hash = hash; + return ret; +} + +void lh_free(_LHASH *lh) { + if (lh == NULL) { + return; + } + + for (size_t i = 0; i < lh->num_buckets; i++) { + LHASH_ITEM *next; + for (LHASH_ITEM *n = lh->buckets[i]; n != NULL; n = next) { + next = n->next; + OPENSSL_free(n); + } + } + + OPENSSL_free(lh->buckets); + OPENSSL_free(lh); +} + +size_t lh_num_items(const _LHASH *lh) { return lh->num_items; } + +// get_next_ptr_and_hash returns a pointer to the pointer that points to the +// item equal to |data|. In other words, it searches for an item equal to |data| +// and, if it's at the start of a chain, then it returns a pointer to an +// element of |lh->buckets|, otherwise it returns a pointer to the |next| +// element of the previous item in the chain. If an element equal to |data| is +// not found, it returns a pointer that points to a NULL pointer. If |out_hash| +// is not NULL, then it also puts the hash value of |data| in |*out_hash|. +static LHASH_ITEM **get_next_ptr_and_hash(const _LHASH *lh, uint32_t *out_hash, + const void *data) { + const uint32_t hash = lh->hash(data); + LHASH_ITEM *cur, **ret; + + if (out_hash != NULL) { + *out_hash = hash; + } + + ret = &lh->buckets[hash % lh->num_buckets]; + for (cur = *ret; cur != NULL; cur = *ret) { + if (lh->comp(cur->data, data) == 0) { + break; + } + ret = &cur->next; + } + + return ret; +} + +void *lh_retrieve(const _LHASH *lh, const void *data) { + LHASH_ITEM **next_ptr; + + next_ptr = get_next_ptr_and_hash(lh, NULL, data); + + if (*next_ptr == NULL) { + return NULL; + } + + return (*next_ptr)->data; +} + +// lh_rebucket allocates a new array of |new_num_buckets| pointers and +// redistributes the existing items into it before making it |lh->buckets| and +// freeing the old array. +static void lh_rebucket(_LHASH *lh, const size_t new_num_buckets) { + LHASH_ITEM **new_buckets, *cur, *next; + size_t i, alloc_size; + + alloc_size = sizeof(LHASH_ITEM *) * new_num_buckets; + if (alloc_size / sizeof(LHASH_ITEM*) != new_num_buckets) { + return; + } + + new_buckets = OPENSSL_malloc(alloc_size); + if (new_buckets == NULL) { + return; + } + OPENSSL_memset(new_buckets, 0, alloc_size); + + for (i = 0; i < lh->num_buckets; i++) { + for (cur = lh->buckets[i]; cur != NULL; cur = next) { + const size_t new_bucket = cur->hash % new_num_buckets; + next = cur->next; + cur->next = new_buckets[new_bucket]; + new_buckets[new_bucket] = cur; + } + } + + OPENSSL_free(lh->buckets); + + lh->num_buckets = new_num_buckets; + lh->buckets = new_buckets; +} + +// lh_maybe_resize resizes the |buckets| array if needed. +static void lh_maybe_resize(_LHASH *lh) { + size_t avg_chain_length; + + if (lh->callback_depth > 0) { + // Don't resize the hash if we are currently iterating over it. + return; + } + + assert(lh->num_buckets >= kMinNumBuckets); + avg_chain_length = lh->num_items / lh->num_buckets; + + if (avg_chain_length > kMaxAverageChainLength) { + const size_t new_num_buckets = lh->num_buckets * 2; + + if (new_num_buckets > lh->num_buckets) { + lh_rebucket(lh, new_num_buckets); + } + } else if (avg_chain_length < kMinAverageChainLength && + lh->num_buckets > kMinNumBuckets) { + size_t new_num_buckets = lh->num_buckets / 2; + + if (new_num_buckets < kMinNumBuckets) { + new_num_buckets = kMinNumBuckets; + } + + lh_rebucket(lh, new_num_buckets); + } +} + +int lh_insert(_LHASH *lh, void **old_data, void *data) { + uint32_t hash; + LHASH_ITEM **next_ptr, *item; + + *old_data = NULL; + next_ptr = get_next_ptr_and_hash(lh, &hash, data); + + + if (*next_ptr != NULL) { + // An element equal to |data| already exists in the hash table. It will be + // replaced. + *old_data = (*next_ptr)->data; + (*next_ptr)->data = data; + return 1; + } + + // An element equal to |data| doesn't exist in the hash table yet. + item = OPENSSL_malloc(sizeof(LHASH_ITEM)); + if (item == NULL) { + return 0; + } + + item->data = data; + item->hash = hash; + item->next = NULL; + *next_ptr = item; + lh->num_items++; + lh_maybe_resize(lh); + + return 1; +} + +void *lh_delete(_LHASH *lh, const void *data) { + LHASH_ITEM **next_ptr, *item, *ret; + + next_ptr = get_next_ptr_and_hash(lh, NULL, data); + + if (*next_ptr == NULL) { + // No such element. + return NULL; + } + + item = *next_ptr; + *next_ptr = item->next; + ret = item->data; + OPENSSL_free(item); + + lh->num_items--; + lh_maybe_resize(lh); + + return ret; +} + +static void lh_doall_internal(_LHASH *lh, void (*no_arg_func)(void *), + void (*arg_func)(void *, void *), void *arg) { + if (lh == NULL) { + return; + } + + if (lh->callback_depth < UINT_MAX) { + // |callback_depth| is a saturating counter. + lh->callback_depth++; + } + + for (size_t i = 0; i < lh->num_buckets; i++) { + LHASH_ITEM *next; + for (LHASH_ITEM *cur = lh->buckets[i]; cur != NULL; cur = next) { + next = cur->next; + if (arg_func) { + arg_func(cur->data, arg); + } else { + no_arg_func(cur->data); + } + } + } + + if (lh->callback_depth < UINT_MAX) { + lh->callback_depth--; + } + + // The callback may have added or removed elements and the non-zero value of + // |callback_depth| will have suppressed any resizing. Thus any needed + // resizing is done here. + lh_maybe_resize(lh); +} + +void lh_doall(_LHASH *lh, void (*func)(void *)) { + lh_doall_internal(lh, func, NULL, NULL); +} + +void lh_doall_arg(_LHASH *lh, void (*func)(void *, void *), void *arg) { + lh_doall_internal(lh, NULL, func, arg); +} + +uint32_t lh_strhash(const char *c) { + if (c == NULL) { + return 0; + } + + return OPENSSL_hash32(c, strlen(c)); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/lhash/lhash.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/lhash/lhash.c.grpc_back new file mode 100644 index 0000000..7bfd289 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/lhash/lhash.c.grpc_back @@ -0,0 +1,336 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 + +#include "../internal.h" + + +// kMinNumBuckets is the minimum size of the buckets array in an |_LHASH|. +static const size_t kMinNumBuckets = 16; + +// kMaxAverageChainLength contains the maximum, average chain length. When the +// average chain length exceeds this value, the hash table will be resized. +static const size_t kMaxAverageChainLength = 2; +static const size_t kMinAverageChainLength = 1; + +struct lhash_st { + // num_items contains the total number of items in the hash table. + size_t num_items; + // buckets is an array of |num_buckets| pointers. Each points to the head of + // a chain of LHASH_ITEM objects that have the same hash value, mod + // |num_buckets|. + LHASH_ITEM **buckets; + // num_buckets contains the length of |buckets|. This value is always >= + // kMinNumBuckets. + size_t num_buckets; + // callback_depth contains the current depth of |lh_doall| or |lh_doall_arg| + // calls. If non-zero then this suppresses resizing of the |buckets| array, + // which would otherwise disrupt the iteration. + unsigned callback_depth; + + lhash_cmp_func comp; + lhash_hash_func hash; +}; + +_LHASH *lh_new(lhash_hash_func hash, lhash_cmp_func comp) { + _LHASH *ret = OPENSSL_malloc(sizeof(_LHASH)); + if (ret == NULL) { + return NULL; + } + OPENSSL_memset(ret, 0, sizeof(_LHASH)); + + ret->num_buckets = kMinNumBuckets; + ret->buckets = OPENSSL_malloc(sizeof(LHASH_ITEM *) * ret->num_buckets); + if (ret->buckets == NULL) { + OPENSSL_free(ret); + return NULL; + } + OPENSSL_memset(ret->buckets, 0, sizeof(LHASH_ITEM *) * ret->num_buckets); + + ret->comp = comp; + ret->hash = hash; + return ret; +} + +void lh_free(_LHASH *lh) { + if (lh == NULL) { + return; + } + + for (size_t i = 0; i < lh->num_buckets; i++) { + LHASH_ITEM *next; + for (LHASH_ITEM *n = lh->buckets[i]; n != NULL; n = next) { + next = n->next; + OPENSSL_free(n); + } + } + + OPENSSL_free(lh->buckets); + OPENSSL_free(lh); +} + +size_t lh_num_items(const _LHASH *lh) { return lh->num_items; } + +// get_next_ptr_and_hash returns a pointer to the pointer that points to the +// item equal to |data|. In other words, it searches for an item equal to |data| +// and, if it's at the start of a chain, then it returns a pointer to an +// element of |lh->buckets|, otherwise it returns a pointer to the |next| +// element of the previous item in the chain. If an element equal to |data| is +// not found, it returns a pointer that points to a NULL pointer. If |out_hash| +// is not NULL, then it also puts the hash value of |data| in |*out_hash|. +static LHASH_ITEM **get_next_ptr_and_hash(const _LHASH *lh, uint32_t *out_hash, + const void *data) { + const uint32_t hash = lh->hash(data); + LHASH_ITEM *cur, **ret; + + if (out_hash != NULL) { + *out_hash = hash; + } + + ret = &lh->buckets[hash % lh->num_buckets]; + for (cur = *ret; cur != NULL; cur = *ret) { + if (lh->comp(cur->data, data) == 0) { + break; + } + ret = &cur->next; + } + + return ret; +} + +void *lh_retrieve(const _LHASH *lh, const void *data) { + LHASH_ITEM **next_ptr; + + next_ptr = get_next_ptr_and_hash(lh, NULL, data); + + if (*next_ptr == NULL) { + return NULL; + } + + return (*next_ptr)->data; +} + +// lh_rebucket allocates a new array of |new_num_buckets| pointers and +// redistributes the existing items into it before making it |lh->buckets| and +// freeing the old array. +static void lh_rebucket(_LHASH *lh, const size_t new_num_buckets) { + LHASH_ITEM **new_buckets, *cur, *next; + size_t i, alloc_size; + + alloc_size = sizeof(LHASH_ITEM *) * new_num_buckets; + if (alloc_size / sizeof(LHASH_ITEM*) != new_num_buckets) { + return; + } + + new_buckets = OPENSSL_malloc(alloc_size); + if (new_buckets == NULL) { + return; + } + OPENSSL_memset(new_buckets, 0, alloc_size); + + for (i = 0; i < lh->num_buckets; i++) { + for (cur = lh->buckets[i]; cur != NULL; cur = next) { + const size_t new_bucket = cur->hash % new_num_buckets; + next = cur->next; + cur->next = new_buckets[new_bucket]; + new_buckets[new_bucket] = cur; + } + } + + OPENSSL_free(lh->buckets); + + lh->num_buckets = new_num_buckets; + lh->buckets = new_buckets; +} + +// lh_maybe_resize resizes the |buckets| array if needed. +static void lh_maybe_resize(_LHASH *lh) { + size_t avg_chain_length; + + if (lh->callback_depth > 0) { + // Don't resize the hash if we are currently iterating over it. + return; + } + + assert(lh->num_buckets >= kMinNumBuckets); + avg_chain_length = lh->num_items / lh->num_buckets; + + if (avg_chain_length > kMaxAverageChainLength) { + const size_t new_num_buckets = lh->num_buckets * 2; + + if (new_num_buckets > lh->num_buckets) { + lh_rebucket(lh, new_num_buckets); + } + } else if (avg_chain_length < kMinAverageChainLength && + lh->num_buckets > kMinNumBuckets) { + size_t new_num_buckets = lh->num_buckets / 2; + + if (new_num_buckets < kMinNumBuckets) { + new_num_buckets = kMinNumBuckets; + } + + lh_rebucket(lh, new_num_buckets); + } +} + +int lh_insert(_LHASH *lh, void **old_data, void *data) { + uint32_t hash; + LHASH_ITEM **next_ptr, *item; + + *old_data = NULL; + next_ptr = get_next_ptr_and_hash(lh, &hash, data); + + + if (*next_ptr != NULL) { + // An element equal to |data| already exists in the hash table. It will be + // replaced. + *old_data = (*next_ptr)->data; + (*next_ptr)->data = data; + return 1; + } + + // An element equal to |data| doesn't exist in the hash table yet. + item = OPENSSL_malloc(sizeof(LHASH_ITEM)); + if (item == NULL) { + return 0; + } + + item->data = data; + item->hash = hash; + item->next = NULL; + *next_ptr = item; + lh->num_items++; + lh_maybe_resize(lh); + + return 1; +} + +void *lh_delete(_LHASH *lh, const void *data) { + LHASH_ITEM **next_ptr, *item, *ret; + + next_ptr = get_next_ptr_and_hash(lh, NULL, data); + + if (*next_ptr == NULL) { + // No such element. + return NULL; + } + + item = *next_ptr; + *next_ptr = item->next; + ret = item->data; + OPENSSL_free(item); + + lh->num_items--; + lh_maybe_resize(lh); + + return ret; +} + +static void lh_doall_internal(_LHASH *lh, void (*no_arg_func)(void *), + void (*arg_func)(void *, void *), void *arg) { + if (lh == NULL) { + return; + } + + if (lh->callback_depth < UINT_MAX) { + // |callback_depth| is a saturating counter. + lh->callback_depth++; + } + + for (size_t i = 0; i < lh->num_buckets; i++) { + LHASH_ITEM *next; + for (LHASH_ITEM *cur = lh->buckets[i]; cur != NULL; cur = next) { + next = cur->next; + if (arg_func) { + arg_func(cur->data, arg); + } else { + no_arg_func(cur->data); + } + } + } + + if (lh->callback_depth < UINT_MAX) { + lh->callback_depth--; + } + + // The callback may have added or removed elements and the non-zero value of + // |callback_depth| will have suppressed any resizing. Thus any needed + // resizing is done here. + lh_maybe_resize(lh); +} + +void lh_doall(_LHASH *lh, void (*func)(void *)) { + lh_doall_internal(lh, func, NULL, NULL); +} + +void lh_doall_arg(_LHASH *lh, void (*func)(void *, void *), void *arg) { + lh_doall_internal(lh, NULL, func, arg); +} + +uint32_t lh_strhash(const char *c) { + if (c == NULL) { + return 0; + } + + return OPENSSL_hash32(c, strlen(c)); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/mem.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/mem.c new file mode 100644 index 0000000..82ddd0e --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/mem.c @@ -0,0 +1,235 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 + +#if defined(OPENSSL_WINDOWS) +OPENSSL_MSVC_PRAGMA(warning(push, 3)) +#include +OPENSSL_MSVC_PRAGMA(warning(pop)) +#endif + +#include "internal.h" + + +#define OPENSSL_MALLOC_PREFIX 8 + + +void *OPENSSL_malloc(size_t size) { + void *ptr = malloc(size + OPENSSL_MALLOC_PREFIX); + if (ptr == NULL) { + return NULL; + } + + *(size_t *)ptr = size; + + return ((uint8_t *)ptr) + OPENSSL_MALLOC_PREFIX; +} + +void OPENSSL_free(void *orig_ptr) { + if (orig_ptr == NULL) { + return; + } + + void *ptr = ((uint8_t *)orig_ptr) - OPENSSL_MALLOC_PREFIX; + + size_t size = *(size_t *)ptr; + OPENSSL_cleanse(ptr, size + OPENSSL_MALLOC_PREFIX); + free(ptr); +} + +void *OPENSSL_realloc(void *orig_ptr, size_t new_size) { + if (orig_ptr == NULL) { + return OPENSSL_malloc(new_size); + } + + void *ptr = ((uint8_t *)orig_ptr) - OPENSSL_MALLOC_PREFIX; + size_t old_size = *(size_t *)ptr; + + void *ret = OPENSSL_malloc(new_size); + if (ret == NULL) { + return NULL; + } + + size_t to_copy = new_size; + if (old_size < to_copy) { + to_copy = old_size; + } + + memcpy(ret, orig_ptr, to_copy); + OPENSSL_free(orig_ptr); + + return ret; +} + +void OPENSSL_cleanse(void *ptr, size_t len) { +#if defined(OPENSSL_WINDOWS) + SecureZeroMemory(ptr, len); +#else + OPENSSL_memset(ptr, 0, len); + +#if !defined(OPENSSL_NO_ASM) + /* As best as we can tell, this is sufficient to break any optimisations that + might try to eliminate "superfluous" memsets. If there's an easy way to + detect memset_s, it would be better to use that. */ + __asm__ __volatile__("" : : "r"(ptr) : "memory"); +#endif +#endif // !OPENSSL_NO_ASM +} + +int CRYPTO_memcmp(const void *in_a, const void *in_b, size_t len) { + const uint8_t *a = in_a; + const uint8_t *b = in_b; + uint8_t x = 0; + + for (size_t i = 0; i < len; i++) { + x |= a[i] ^ b[i]; + } + + return x; +} + +uint32_t OPENSSL_hash32(const void *ptr, size_t len) { + // These are the FNV-1a parameters for 32 bits. + static const uint32_t kPrime = 16777619u; + static const uint32_t kOffsetBasis = 2166136261u; + + const uint8_t *in = ptr; + uint32_t h = kOffsetBasis; + + for (size_t i = 0; i < len; i++) { + h ^= in[i]; + h *= kPrime; + } + + return h; +} + +size_t OPENSSL_strnlen(const char *s, size_t len) { + for (size_t i = 0; i < len; i++) { + if (s[i] == 0) { + return i; + } + } + + return len; +} + +char *OPENSSL_strdup(const char *s) { + const size_t len = strlen(s) + 1; + char *ret = OPENSSL_malloc(len); + if (ret == NULL) { + return NULL; + } + OPENSSL_memcpy(ret, s, len); + return ret; +} + +int OPENSSL_tolower(int c) { + if (c >= 'A' && c <= 'Z') { + return c + ('a' - 'A'); + } + return c; +} + +int OPENSSL_strcasecmp(const char *a, const char *b) { + for (size_t i = 0;; i++) { + const int aa = OPENSSL_tolower(a[i]); + const int bb = OPENSSL_tolower(b[i]); + + if (aa < bb) { + return -1; + } else if (aa > bb) { + return 1; + } else if (aa == 0) { + return 0; + } + } +} + +int OPENSSL_strncasecmp(const char *a, const char *b, size_t n) { + for (size_t i = 0; i < n; i++) { + const int aa = OPENSSL_tolower(a[i]); + const int bb = OPENSSL_tolower(b[i]); + + if (aa < bb) { + return -1; + } else if (aa > bb) { + return 1; + } else if (aa == 0) { + return 0; + } + } + + return 0; +} + +int BIO_snprintf(char *buf, size_t n, const char *format, ...) { + va_list args; + va_start(args, format); + int 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) { + return vsnprintf(buf, n, format, args); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/mem.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/mem.c.grpc_back new file mode 100644 index 0000000..50c6fe6 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/mem.c.grpc_back @@ -0,0 +1,235 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 + +#if defined(OPENSSL_WINDOWS) +OPENSSL_MSVC_PRAGMA(warning(push, 3)) +#include +OPENSSL_MSVC_PRAGMA(warning(pop)) +#endif + +#include "internal.h" + + +#define OPENSSL_MALLOC_PREFIX 8 + + +void *OPENSSL_malloc(size_t size) { + void *ptr = malloc(size + OPENSSL_MALLOC_PREFIX); + if (ptr == NULL) { + return NULL; + } + + *(size_t *)ptr = size; + + return ((uint8_t *)ptr) + OPENSSL_MALLOC_PREFIX; +} + +void OPENSSL_free(void *orig_ptr) { + if (orig_ptr == NULL) { + return; + } + + void *ptr = ((uint8_t *)orig_ptr) - OPENSSL_MALLOC_PREFIX; + + size_t size = *(size_t *)ptr; + OPENSSL_cleanse(ptr, size + OPENSSL_MALLOC_PREFIX); + free(ptr); +} + +void *OPENSSL_realloc(void *orig_ptr, size_t new_size) { + if (orig_ptr == NULL) { + return OPENSSL_malloc(new_size); + } + + void *ptr = ((uint8_t *)orig_ptr) - OPENSSL_MALLOC_PREFIX; + size_t old_size = *(size_t *)ptr; + + void *ret = OPENSSL_malloc(new_size); + if (ret == NULL) { + return NULL; + } + + size_t to_copy = new_size; + if (old_size < to_copy) { + to_copy = old_size; + } + + memcpy(ret, orig_ptr, to_copy); + OPENSSL_free(orig_ptr); + + return ret; +} + +void OPENSSL_cleanse(void *ptr, size_t len) { +#if defined(OPENSSL_WINDOWS) + SecureZeroMemory(ptr, len); +#else + OPENSSL_memset(ptr, 0, len); + +#if !defined(OPENSSL_NO_ASM) + /* As best as we can tell, this is sufficient to break any optimisations that + might try to eliminate "superfluous" memsets. If there's an easy way to + detect memset_s, it would be better to use that. */ + __asm__ __volatile__("" : : "r"(ptr) : "memory"); +#endif +#endif // !OPENSSL_NO_ASM +} + +int CRYPTO_memcmp(const void *in_a, const void *in_b, size_t len) { + const uint8_t *a = in_a; + const uint8_t *b = in_b; + uint8_t x = 0; + + for (size_t i = 0; i < len; i++) { + x |= a[i] ^ b[i]; + } + + return x; +} + +uint32_t OPENSSL_hash32(const void *ptr, size_t len) { + // These are the FNV-1a parameters for 32 bits. + static const uint32_t kPrime = 16777619u; + static const uint32_t kOffsetBasis = 2166136261u; + + const uint8_t *in = ptr; + uint32_t h = kOffsetBasis; + + for (size_t i = 0; i < len; i++) { + h ^= in[i]; + h *= kPrime; + } + + return h; +} + +size_t OPENSSL_strnlen(const char *s, size_t len) { + for (size_t i = 0; i < len; i++) { + if (s[i] == 0) { + return i; + } + } + + return len; +} + +char *OPENSSL_strdup(const char *s) { + const size_t len = strlen(s) + 1; + char *ret = OPENSSL_malloc(len); + if (ret == NULL) { + return NULL; + } + OPENSSL_memcpy(ret, s, len); + return ret; +} + +int OPENSSL_tolower(int c) { + if (c >= 'A' && c <= 'Z') { + return c + ('a' - 'A'); + } + return c; +} + +int OPENSSL_strcasecmp(const char *a, const char *b) { + for (size_t i = 0;; i++) { + const int aa = OPENSSL_tolower(a[i]); + const int bb = OPENSSL_tolower(b[i]); + + if (aa < bb) { + return -1; + } else if (aa > bb) { + return 1; + } else if (aa == 0) { + return 0; + } + } +} + +int OPENSSL_strncasecmp(const char *a, const char *b, size_t n) { + for (size_t i = 0; i < n; i++) { + const int aa = OPENSSL_tolower(a[i]); + const int bb = OPENSSL_tolower(b[i]); + + if (aa < bb) { + return -1; + } else if (aa > bb) { + return 1; + } else if (aa == 0) { + return 0; + } + } + + return 0; +} + +int BIO_snprintf(char *buf, size_t n, const char *format, ...) { + va_list args; + va_start(args, format); + int 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) { + return vsnprintf(buf, n, format, args); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/obj/obj.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/obj/obj.c new file mode 100644 index 0000000..b19d586 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/obj/obj.c @@ -0,0 +1,554 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#if !defined(__STDC_FORMAT_MACROS) +#define __STDC_FORMAT_MACROS +#endif + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "obj_dat.h" +#include "../internal.h" + + +static struct CRYPTO_STATIC_MUTEX global_added_lock = CRYPTO_STATIC_MUTEX_INIT; +// These globals are protected by |global_added_lock|. +static LHASH_OF(ASN1_OBJECT) *global_added_by_data = NULL; +static LHASH_OF(ASN1_OBJECT) *global_added_by_nid = NULL; +static LHASH_OF(ASN1_OBJECT) *global_added_by_short_name = NULL; +static LHASH_OF(ASN1_OBJECT) *global_added_by_long_name = NULL; + +static struct CRYPTO_STATIC_MUTEX global_next_nid_lock = + CRYPTO_STATIC_MUTEX_INIT; +static unsigned global_next_nid = NUM_NID; + +static int obj_next_nid(void) { + int ret; + + CRYPTO_STATIC_MUTEX_lock_write(&global_next_nid_lock); + ret = global_next_nid++; + CRYPTO_STATIC_MUTEX_unlock_write(&global_next_nid_lock); + + return ret; +} + +ASN1_OBJECT *OBJ_dup(const ASN1_OBJECT *o) { + ASN1_OBJECT *r; + unsigned char *data = NULL; + char *sn = NULL, *ln = NULL; + + if (o == NULL) { + return NULL; + } + + if (!(o->flags & ASN1_OBJECT_FLAG_DYNAMIC)) { + // TODO(fork): this is a little dangerous. + return (ASN1_OBJECT *)o; + } + + r = ASN1_OBJECT_new(); + if (r == NULL) { + OPENSSL_PUT_ERROR(OBJ, ERR_R_ASN1_LIB); + return NULL; + } + r->ln = r->sn = NULL; + + data = OPENSSL_malloc(o->length); + if (data == NULL) { + goto err; + } + if (o->data != NULL) { + OPENSSL_memcpy(data, o->data, o->length); + } + + // once data is attached to an object, it remains const + r->data = data; + r->length = o->length; + r->nid = o->nid; + + if (o->ln != NULL) { + ln = OPENSSL_strdup(o->ln); + if (ln == NULL) { + goto err; + } + } + + if (o->sn != NULL) { + sn = OPENSSL_strdup(o->sn); + if (sn == NULL) { + goto err; + } + } + + r->sn = sn; + r->ln = ln; + + r->flags = + o->flags | (ASN1_OBJECT_FLAG_DYNAMIC | ASN1_OBJECT_FLAG_DYNAMIC_STRINGS | + ASN1_OBJECT_FLAG_DYNAMIC_DATA); + return r; + +err: + OPENSSL_PUT_ERROR(OBJ, ERR_R_MALLOC_FAILURE); + OPENSSL_free(ln); + OPENSSL_free(sn); + OPENSSL_free(data); + 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 OPENSSL_memcmp(a->data, b->data, a->length); +} + +const uint8_t *OBJ_get0_data(const ASN1_OBJECT *obj) { + if (obj == NULL) { + return NULL; + } + + return obj->data; +} + +size_t OBJ_length(const ASN1_OBJECT *obj) { + if (obj == NULL || obj->length < 0) { + return 0; + } + + return (size_t)obj->length; +} + +// obj_cmp is called to search the kNIDsInOIDOrder array. The |key| argument is +// an |ASN1_OBJECT|* that we're looking for and |element| is a pointer to an +// unsigned int in the array. +static int obj_cmp(const void *key, const void *element) { + unsigned nid = *((const unsigned*) element); + const ASN1_OBJECT *a = key; + const ASN1_OBJECT *b = &kObjects[nid]; + + if (a->length < b->length) { + return -1; + } else if (a->length > b->length) { + return 1; + } + return OPENSSL_memcmp(a->data, b->data, a->length); +} + +int OBJ_obj2nid(const ASN1_OBJECT *obj) { + const unsigned int *nid_ptr; + + if (obj == NULL) { + return NID_undef; + } + + if (obj->nid != 0) { + return obj->nid; + } + + CRYPTO_STATIC_MUTEX_lock_read(&global_added_lock); + if (global_added_by_data != NULL) { + ASN1_OBJECT *match; + + match = lh_ASN1_OBJECT_retrieve(global_added_by_data, obj); + if (match != NULL) { + CRYPTO_STATIC_MUTEX_unlock_read(&global_added_lock); + return match->nid; + } + } + CRYPTO_STATIC_MUTEX_unlock_read(&global_added_lock); + + nid_ptr = bsearch(obj, kNIDsInOIDOrder, OPENSSL_ARRAY_SIZE(kNIDsInOIDOrder), + sizeof(kNIDsInOIDOrder[0]), obj_cmp); + if (nid_ptr == NULL) { + return NID_undef; + } + + return kObjects[*nid_ptr].nid; +} + +int OBJ_cbs2nid(const CBS *cbs) { + if (CBS_len(cbs) > INT_MAX) { + return NID_undef; + } + + ASN1_OBJECT obj; + OPENSSL_memset(&obj, 0, sizeof(obj)); + obj.data = CBS_data(cbs); + obj.length = (int)CBS_len(cbs); + + return OBJ_obj2nid(&obj); +} + +// short_name_cmp is called to search the kNIDsInShortNameOrder array. The +// |key| argument is name that we're looking for and |element| is a pointer to +// an unsigned int in the array. +static int short_name_cmp(const void *key, const void *element) { + const char *name = (const char *) key; + unsigned nid = *((unsigned*) element); + + return strcmp(name, kObjects[nid].sn); +} + +int OBJ_sn2nid(const char *short_name) { + const unsigned int *nid_ptr; + + CRYPTO_STATIC_MUTEX_lock_read(&global_added_lock); + if (global_added_by_short_name != NULL) { + ASN1_OBJECT *match, template; + + template.sn = short_name; + match = lh_ASN1_OBJECT_retrieve(global_added_by_short_name, &template); + if (match != NULL) { + CRYPTO_STATIC_MUTEX_unlock_read(&global_added_lock); + return match->nid; + } + } + CRYPTO_STATIC_MUTEX_unlock_read(&global_added_lock); + + nid_ptr = bsearch(short_name, kNIDsInShortNameOrder, + OPENSSL_ARRAY_SIZE(kNIDsInShortNameOrder), + sizeof(kNIDsInShortNameOrder[0]), short_name_cmp); + if (nid_ptr == NULL) { + return NID_undef; + } + + return kObjects[*nid_ptr].nid; +} + +// long_name_cmp is called to search the kNIDsInLongNameOrder array. The +// |key| argument is name that we're looking for and |element| is a pointer to +// an unsigned int in the array. +static int long_name_cmp(const void *key, const void *element) { + const char *name = (const char *) key; + unsigned nid = *((unsigned*) element); + + return strcmp(name, kObjects[nid].ln); +} + +int OBJ_ln2nid(const char *long_name) { + const unsigned int *nid_ptr; + + CRYPTO_STATIC_MUTEX_lock_read(&global_added_lock); + if (global_added_by_long_name != NULL) { + ASN1_OBJECT *match, template; + + template.ln = long_name; + match = lh_ASN1_OBJECT_retrieve(global_added_by_long_name, &template); + if (match != NULL) { + CRYPTO_STATIC_MUTEX_unlock_read(&global_added_lock); + return match->nid; + } + } + CRYPTO_STATIC_MUTEX_unlock_read(&global_added_lock); + + nid_ptr = bsearch(long_name, kNIDsInLongNameOrder, + OPENSSL_ARRAY_SIZE(kNIDsInLongNameOrder), + sizeof(kNIDsInLongNameOrder[0]), long_name_cmp); + if (nid_ptr == NULL) { + return NID_undef; + } + + return kObjects[*nid_ptr].nid; +} + +int OBJ_txt2nid(const char *s) { + ASN1_OBJECT *obj; + int nid; + + obj = OBJ_txt2obj(s, 0 /* search names */); + nid = OBJ_obj2nid(obj); + ASN1_OBJECT_free(obj); + return nid; +} + +OPENSSL_EXPORT int OBJ_nid2cbb(CBB *out, int nid) { + const ASN1_OBJECT *obj = OBJ_nid2obj(nid); + CBB oid; + + if (obj == NULL || + !CBB_add_asn1(out, &oid, CBS_ASN1_OBJECT) || + !CBB_add_bytes(&oid, obj->data, obj->length) || + !CBB_flush(out)) { + return 0; + } + + return 1; +} + +const ASN1_OBJECT *OBJ_nid2obj(int nid) { + if (nid >= 0 && nid < NUM_NID) { + if (nid != NID_undef && kObjects[nid].nid == NID_undef) { + goto err; + } + return &kObjects[nid]; + } + + CRYPTO_STATIC_MUTEX_lock_read(&global_added_lock); + if (global_added_by_nid != NULL) { + ASN1_OBJECT *match, template; + + template.nid = nid; + match = lh_ASN1_OBJECT_retrieve(global_added_by_nid, &template); + if (match != NULL) { + CRYPTO_STATIC_MUTEX_unlock_read(&global_added_lock); + return match; + } + } + CRYPTO_STATIC_MUTEX_unlock_read(&global_added_lock); + +err: + OPENSSL_PUT_ERROR(OBJ, OBJ_R_UNKNOWN_NID); + return NULL; +} + +const char *OBJ_nid2sn(int nid) { + const ASN1_OBJECT *obj = OBJ_nid2obj(nid); + if (obj == NULL) { + return NULL; + } + + return obj->sn; +} + +const char *OBJ_nid2ln(int nid) { + const ASN1_OBJECT *obj = OBJ_nid2obj(nid); + if (obj == NULL) { + return NULL; + } + + return obj->ln; +} + +static ASN1_OBJECT *create_object_with_text_oid(int (*get_nid)(void), + const char *oid, + const char *short_name, + const char *long_name) { + uint8_t *buf; + size_t len; + CBB cbb; + if (!CBB_init(&cbb, 32) || + !CBB_add_asn1_oid_from_text(&cbb, oid, strlen(oid)) || + !CBB_finish(&cbb, &buf, &len)) { + OPENSSL_PUT_ERROR(OBJ, OBJ_R_INVALID_OID_STRING); + CBB_cleanup(&cbb); + return NULL; + } + + ASN1_OBJECT *ret = ASN1_OBJECT_create(get_nid ? get_nid() : NID_undef, buf, + len, short_name, long_name); + OPENSSL_free(buf); + return ret; +} + +ASN1_OBJECT *OBJ_txt2obj(const char *s, int dont_search_names) { + if (!dont_search_names) { + int nid = OBJ_sn2nid(s); + if (nid == NID_undef) { + nid = OBJ_ln2nid(s); + } + + if (nid != NID_undef) { + return (ASN1_OBJECT*) OBJ_nid2obj(nid); + } + } + + return create_object_with_text_oid(NULL, s, NULL, NULL); +} + +static int strlcpy_int(char *dst, const char *src, int dst_size) { + size_t ret = BUF_strlcpy(dst, src, dst_size < 0 ? 0 : (size_t)dst_size); + if (ret > INT_MAX) { + OPENSSL_PUT_ERROR(OBJ, ERR_R_OVERFLOW); + return -1; + } + return (int)ret; +} + +int OBJ_obj2txt(char *out, int out_len, const ASN1_OBJECT *obj, + int always_return_oid) { + // Python depends on the empty OID successfully encoding as the empty + // string. + if (obj == NULL || obj->length == 0) { + return strlcpy_int(out, "", out_len); + } + + if (!always_return_oid) { + int nid = OBJ_obj2nid(obj); + if (nid != NID_undef) { + const char *name = OBJ_nid2ln(nid); + if (name == NULL) { + name = OBJ_nid2sn(nid); + } + if (name != NULL) { + return strlcpy_int(out, name, out_len); + } + } + } + + CBS cbs; + CBS_init(&cbs, obj->data, obj->length); + char *txt = CBS_asn1_oid_to_text(&cbs); + if (txt == NULL) { + if (out_len > 0) { + out[0] = '\0'; + } + return -1; + } + + int ret = strlcpy_int(out, txt, out_len); + OPENSSL_free(txt); + return ret; +} + +static uint32_t hash_nid(const ASN1_OBJECT *obj) { + return obj->nid; +} + +static int cmp_nid(const ASN1_OBJECT *a, const ASN1_OBJECT *b) { + return a->nid - b->nid; +} + +static uint32_t hash_data(const ASN1_OBJECT *obj) { + return OPENSSL_hash32(obj->data, obj->length); +} + +static int cmp_data(const ASN1_OBJECT *a, const ASN1_OBJECT *b) { + int i = a->length - b->length; + if (i) { + return i; + } + return OPENSSL_memcmp(a->data, b->data, a->length); +} + +static uint32_t hash_short_name(const ASN1_OBJECT *obj) { + return lh_strhash(obj->sn); +} + +static int cmp_short_name(const ASN1_OBJECT *a, const ASN1_OBJECT *b) { + return strcmp(a->sn, b->sn); +} + +static uint32_t hash_long_name(const ASN1_OBJECT *obj) { + return lh_strhash(obj->ln); +} + +static int cmp_long_name(const ASN1_OBJECT *a, const ASN1_OBJECT *b) { + return strcmp(a->ln, b->ln); +} + +// obj_add_object inserts |obj| into the various global hashes for run-time +// added objects. It returns one on success or zero otherwise. +static int obj_add_object(ASN1_OBJECT *obj) { + int ok; + ASN1_OBJECT *old_object; + + obj->flags &= ~(ASN1_OBJECT_FLAG_DYNAMIC | ASN1_OBJECT_FLAG_DYNAMIC_STRINGS | + ASN1_OBJECT_FLAG_DYNAMIC_DATA); + + CRYPTO_STATIC_MUTEX_lock_write(&global_added_lock); + if (global_added_by_nid == NULL) { + global_added_by_nid = lh_ASN1_OBJECT_new(hash_nid, cmp_nid); + global_added_by_data = lh_ASN1_OBJECT_new(hash_data, cmp_data); + global_added_by_short_name = lh_ASN1_OBJECT_new(hash_short_name, cmp_short_name); + global_added_by_long_name = lh_ASN1_OBJECT_new(hash_long_name, cmp_long_name); + } + + // We don't pay attention to |old_object| (which contains any previous object + // that was evicted from the hashes) because we don't have a reference count + // on ASN1_OBJECT values. Also, we should never have duplicates nids and so + // should always have objects in |global_added_by_nid|. + + ok = lh_ASN1_OBJECT_insert(global_added_by_nid, &old_object, obj); + if (obj->length != 0 && obj->data != NULL) { + ok &= lh_ASN1_OBJECT_insert(global_added_by_data, &old_object, obj); + } + if (obj->sn != NULL) { + ok &= lh_ASN1_OBJECT_insert(global_added_by_short_name, &old_object, obj); + } + if (obj->ln != NULL) { + ok &= lh_ASN1_OBJECT_insert(global_added_by_long_name, &old_object, obj); + } + CRYPTO_STATIC_MUTEX_unlock_write(&global_added_lock); + + return ok; +} + +int OBJ_create(const char *oid, const char *short_name, const char *long_name) { + ASN1_OBJECT *op = + create_object_with_text_oid(obj_next_nid, oid, short_name, long_name); + if (op == NULL || + !obj_add_object(op)) { + return NID_undef; + } + return op->nid; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/obj/obj.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/obj/obj.c.grpc_back new file mode 100644 index 0000000..a34d6dc --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/obj/obj.c.grpc_back @@ -0,0 +1,554 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#if !defined(__STDC_FORMAT_MACROS) +#define __STDC_FORMAT_MACROS +#endif + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "obj_dat.h" +#include "../internal.h" + + +static struct CRYPTO_STATIC_MUTEX global_added_lock = CRYPTO_STATIC_MUTEX_INIT; +// These globals are protected by |global_added_lock|. +static LHASH_OF(ASN1_OBJECT) *global_added_by_data = NULL; +static LHASH_OF(ASN1_OBJECT) *global_added_by_nid = NULL; +static LHASH_OF(ASN1_OBJECT) *global_added_by_short_name = NULL; +static LHASH_OF(ASN1_OBJECT) *global_added_by_long_name = NULL; + +static struct CRYPTO_STATIC_MUTEX global_next_nid_lock = + CRYPTO_STATIC_MUTEX_INIT; +static unsigned global_next_nid = NUM_NID; + +static int obj_next_nid(void) { + int ret; + + CRYPTO_STATIC_MUTEX_lock_write(&global_next_nid_lock); + ret = global_next_nid++; + CRYPTO_STATIC_MUTEX_unlock_write(&global_next_nid_lock); + + return ret; +} + +ASN1_OBJECT *OBJ_dup(const ASN1_OBJECT *o) { + ASN1_OBJECT *r; + unsigned char *data = NULL; + char *sn = NULL, *ln = NULL; + + if (o == NULL) { + return NULL; + } + + if (!(o->flags & ASN1_OBJECT_FLAG_DYNAMIC)) { + // TODO(fork): this is a little dangerous. + return (ASN1_OBJECT *)o; + } + + r = ASN1_OBJECT_new(); + if (r == NULL) { + OPENSSL_PUT_ERROR(OBJ, ERR_R_ASN1_LIB); + return NULL; + } + r->ln = r->sn = NULL; + + data = OPENSSL_malloc(o->length); + if (data == NULL) { + goto err; + } + if (o->data != NULL) { + OPENSSL_memcpy(data, o->data, o->length); + } + + // once data is attached to an object, it remains const + r->data = data; + r->length = o->length; + r->nid = o->nid; + + if (o->ln != NULL) { + ln = OPENSSL_strdup(o->ln); + if (ln == NULL) { + goto err; + } + } + + if (o->sn != NULL) { + sn = OPENSSL_strdup(o->sn); + if (sn == NULL) { + goto err; + } + } + + r->sn = sn; + r->ln = ln; + + r->flags = + o->flags | (ASN1_OBJECT_FLAG_DYNAMIC | ASN1_OBJECT_FLAG_DYNAMIC_STRINGS | + ASN1_OBJECT_FLAG_DYNAMIC_DATA); + return r; + +err: + OPENSSL_PUT_ERROR(OBJ, ERR_R_MALLOC_FAILURE); + OPENSSL_free(ln); + OPENSSL_free(sn); + OPENSSL_free(data); + 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 OPENSSL_memcmp(a->data, b->data, a->length); +} + +const uint8_t *OBJ_get0_data(const ASN1_OBJECT *obj) { + if (obj == NULL) { + return NULL; + } + + return obj->data; +} + +size_t OBJ_length(const ASN1_OBJECT *obj) { + if (obj == NULL || obj->length < 0) { + return 0; + } + + return (size_t)obj->length; +} + +// obj_cmp is called to search the kNIDsInOIDOrder array. The |key| argument is +// an |ASN1_OBJECT|* that we're looking for and |element| is a pointer to an +// unsigned int in the array. +static int obj_cmp(const void *key, const void *element) { + unsigned nid = *((const unsigned*) element); + const ASN1_OBJECT *a = key; + const ASN1_OBJECT *b = &kObjects[nid]; + + if (a->length < b->length) { + return -1; + } else if (a->length > b->length) { + return 1; + } + return OPENSSL_memcmp(a->data, b->data, a->length); +} + +int OBJ_obj2nid(const ASN1_OBJECT *obj) { + const unsigned int *nid_ptr; + + if (obj == NULL) { + return NID_undef; + } + + if (obj->nid != 0) { + return obj->nid; + } + + CRYPTO_STATIC_MUTEX_lock_read(&global_added_lock); + if (global_added_by_data != NULL) { + ASN1_OBJECT *match; + + match = lh_ASN1_OBJECT_retrieve(global_added_by_data, obj); + if (match != NULL) { + CRYPTO_STATIC_MUTEX_unlock_read(&global_added_lock); + return match->nid; + } + } + CRYPTO_STATIC_MUTEX_unlock_read(&global_added_lock); + + nid_ptr = bsearch(obj, kNIDsInOIDOrder, OPENSSL_ARRAY_SIZE(kNIDsInOIDOrder), + sizeof(kNIDsInOIDOrder[0]), obj_cmp); + if (nid_ptr == NULL) { + return NID_undef; + } + + return kObjects[*nid_ptr].nid; +} + +int OBJ_cbs2nid(const CBS *cbs) { + if (CBS_len(cbs) > INT_MAX) { + return NID_undef; + } + + ASN1_OBJECT obj; + OPENSSL_memset(&obj, 0, sizeof(obj)); + obj.data = CBS_data(cbs); + obj.length = (int)CBS_len(cbs); + + return OBJ_obj2nid(&obj); +} + +// short_name_cmp is called to search the kNIDsInShortNameOrder array. The +// |key| argument is name that we're looking for and |element| is a pointer to +// an unsigned int in the array. +static int short_name_cmp(const void *key, const void *element) { + const char *name = (const char *) key; + unsigned nid = *((unsigned*) element); + + return strcmp(name, kObjects[nid].sn); +} + +int OBJ_sn2nid(const char *short_name) { + const unsigned int *nid_ptr; + + CRYPTO_STATIC_MUTEX_lock_read(&global_added_lock); + if (global_added_by_short_name != NULL) { + ASN1_OBJECT *match, template; + + template.sn = short_name; + match = lh_ASN1_OBJECT_retrieve(global_added_by_short_name, &template); + if (match != NULL) { + CRYPTO_STATIC_MUTEX_unlock_read(&global_added_lock); + return match->nid; + } + } + CRYPTO_STATIC_MUTEX_unlock_read(&global_added_lock); + + nid_ptr = bsearch(short_name, kNIDsInShortNameOrder, + OPENSSL_ARRAY_SIZE(kNIDsInShortNameOrder), + sizeof(kNIDsInShortNameOrder[0]), short_name_cmp); + if (nid_ptr == NULL) { + return NID_undef; + } + + return kObjects[*nid_ptr].nid; +} + +// long_name_cmp is called to search the kNIDsInLongNameOrder array. The +// |key| argument is name that we're looking for and |element| is a pointer to +// an unsigned int in the array. +static int long_name_cmp(const void *key, const void *element) { + const char *name = (const char *) key; + unsigned nid = *((unsigned*) element); + + return strcmp(name, kObjects[nid].ln); +} + +int OBJ_ln2nid(const char *long_name) { + const unsigned int *nid_ptr; + + CRYPTO_STATIC_MUTEX_lock_read(&global_added_lock); + if (global_added_by_long_name != NULL) { + ASN1_OBJECT *match, template; + + template.ln = long_name; + match = lh_ASN1_OBJECT_retrieve(global_added_by_long_name, &template); + if (match != NULL) { + CRYPTO_STATIC_MUTEX_unlock_read(&global_added_lock); + return match->nid; + } + } + CRYPTO_STATIC_MUTEX_unlock_read(&global_added_lock); + + nid_ptr = bsearch(long_name, kNIDsInLongNameOrder, + OPENSSL_ARRAY_SIZE(kNIDsInLongNameOrder), + sizeof(kNIDsInLongNameOrder[0]), long_name_cmp); + if (nid_ptr == NULL) { + return NID_undef; + } + + return kObjects[*nid_ptr].nid; +} + +int OBJ_txt2nid(const char *s) { + ASN1_OBJECT *obj; + int nid; + + obj = OBJ_txt2obj(s, 0 /* search names */); + nid = OBJ_obj2nid(obj); + ASN1_OBJECT_free(obj); + return nid; +} + +OPENSSL_EXPORT int OBJ_nid2cbb(CBB *out, int nid) { + const ASN1_OBJECT *obj = OBJ_nid2obj(nid); + CBB oid; + + if (obj == NULL || + !CBB_add_asn1(out, &oid, CBS_ASN1_OBJECT) || + !CBB_add_bytes(&oid, obj->data, obj->length) || + !CBB_flush(out)) { + return 0; + } + + return 1; +} + +const ASN1_OBJECT *OBJ_nid2obj(int nid) { + if (nid >= 0 && nid < NUM_NID) { + if (nid != NID_undef && kObjects[nid].nid == NID_undef) { + goto err; + } + return &kObjects[nid]; + } + + CRYPTO_STATIC_MUTEX_lock_read(&global_added_lock); + if (global_added_by_nid != NULL) { + ASN1_OBJECT *match, template; + + template.nid = nid; + match = lh_ASN1_OBJECT_retrieve(global_added_by_nid, &template); + if (match != NULL) { + CRYPTO_STATIC_MUTEX_unlock_read(&global_added_lock); + return match; + } + } + CRYPTO_STATIC_MUTEX_unlock_read(&global_added_lock); + +err: + OPENSSL_PUT_ERROR(OBJ, OBJ_R_UNKNOWN_NID); + return NULL; +} + +const char *OBJ_nid2sn(int nid) { + const ASN1_OBJECT *obj = OBJ_nid2obj(nid); + if (obj == NULL) { + return NULL; + } + + return obj->sn; +} + +const char *OBJ_nid2ln(int nid) { + const ASN1_OBJECT *obj = OBJ_nid2obj(nid); + if (obj == NULL) { + return NULL; + } + + return obj->ln; +} + +static ASN1_OBJECT *create_object_with_text_oid(int (*get_nid)(void), + const char *oid, + const char *short_name, + const char *long_name) { + uint8_t *buf; + size_t len; + CBB cbb; + if (!CBB_init(&cbb, 32) || + !CBB_add_asn1_oid_from_text(&cbb, oid, strlen(oid)) || + !CBB_finish(&cbb, &buf, &len)) { + OPENSSL_PUT_ERROR(OBJ, OBJ_R_INVALID_OID_STRING); + CBB_cleanup(&cbb); + return NULL; + } + + ASN1_OBJECT *ret = ASN1_OBJECT_create(get_nid ? get_nid() : NID_undef, buf, + len, short_name, long_name); + OPENSSL_free(buf); + return ret; +} + +ASN1_OBJECT *OBJ_txt2obj(const char *s, int dont_search_names) { + if (!dont_search_names) { + int nid = OBJ_sn2nid(s); + if (nid == NID_undef) { + nid = OBJ_ln2nid(s); + } + + if (nid != NID_undef) { + return (ASN1_OBJECT*) OBJ_nid2obj(nid); + } + } + + return create_object_with_text_oid(NULL, s, NULL, NULL); +} + +static int strlcpy_int(char *dst, const char *src, int dst_size) { + size_t ret = BUF_strlcpy(dst, src, dst_size < 0 ? 0 : (size_t)dst_size); + if (ret > INT_MAX) { + OPENSSL_PUT_ERROR(OBJ, ERR_R_OVERFLOW); + return -1; + } + return (int)ret; +} + +int OBJ_obj2txt(char *out, int out_len, const ASN1_OBJECT *obj, + int always_return_oid) { + // Python depends on the empty OID successfully encoding as the empty + // string. + if (obj == NULL || obj->length == 0) { + return strlcpy_int(out, "", out_len); + } + + if (!always_return_oid) { + int nid = OBJ_obj2nid(obj); + if (nid != NID_undef) { + const char *name = OBJ_nid2ln(nid); + if (name == NULL) { + name = OBJ_nid2sn(nid); + } + if (name != NULL) { + return strlcpy_int(out, name, out_len); + } + } + } + + CBS cbs; + CBS_init(&cbs, obj->data, obj->length); + char *txt = CBS_asn1_oid_to_text(&cbs); + if (txt == NULL) { + if (out_len > 0) { + out[0] = '\0'; + } + return -1; + } + + int ret = strlcpy_int(out, txt, out_len); + OPENSSL_free(txt); + return ret; +} + +static uint32_t hash_nid(const ASN1_OBJECT *obj) { + return obj->nid; +} + +static int cmp_nid(const ASN1_OBJECT *a, const ASN1_OBJECT *b) { + return a->nid - b->nid; +} + +static uint32_t hash_data(const ASN1_OBJECT *obj) { + return OPENSSL_hash32(obj->data, obj->length); +} + +static int cmp_data(const ASN1_OBJECT *a, const ASN1_OBJECT *b) { + int i = a->length - b->length; + if (i) { + return i; + } + return OPENSSL_memcmp(a->data, b->data, a->length); +} + +static uint32_t hash_short_name(const ASN1_OBJECT *obj) { + return lh_strhash(obj->sn); +} + +static int cmp_short_name(const ASN1_OBJECT *a, const ASN1_OBJECT *b) { + return strcmp(a->sn, b->sn); +} + +static uint32_t hash_long_name(const ASN1_OBJECT *obj) { + return lh_strhash(obj->ln); +} + +static int cmp_long_name(const ASN1_OBJECT *a, const ASN1_OBJECT *b) { + return strcmp(a->ln, b->ln); +} + +// obj_add_object inserts |obj| into the various global hashes for run-time +// added objects. It returns one on success or zero otherwise. +static int obj_add_object(ASN1_OBJECT *obj) { + int ok; + ASN1_OBJECT *old_object; + + obj->flags &= ~(ASN1_OBJECT_FLAG_DYNAMIC | ASN1_OBJECT_FLAG_DYNAMIC_STRINGS | + ASN1_OBJECT_FLAG_DYNAMIC_DATA); + + CRYPTO_STATIC_MUTEX_lock_write(&global_added_lock); + if (global_added_by_nid == NULL) { + global_added_by_nid = lh_ASN1_OBJECT_new(hash_nid, cmp_nid); + global_added_by_data = lh_ASN1_OBJECT_new(hash_data, cmp_data); + global_added_by_short_name = lh_ASN1_OBJECT_new(hash_short_name, cmp_short_name); + global_added_by_long_name = lh_ASN1_OBJECT_new(hash_long_name, cmp_long_name); + } + + // We don't pay attention to |old_object| (which contains any previous object + // that was evicted from the hashes) because we don't have a reference count + // on ASN1_OBJECT values. Also, we should never have duplicates nids and so + // should always have objects in |global_added_by_nid|. + + ok = lh_ASN1_OBJECT_insert(global_added_by_nid, &old_object, obj); + if (obj->length != 0 && obj->data != NULL) { + ok &= lh_ASN1_OBJECT_insert(global_added_by_data, &old_object, obj); + } + if (obj->sn != NULL) { + ok &= lh_ASN1_OBJECT_insert(global_added_by_short_name, &old_object, obj); + } + if (obj->ln != NULL) { + ok &= lh_ASN1_OBJECT_insert(global_added_by_long_name, &old_object, obj); + } + CRYPTO_STATIC_MUTEX_unlock_write(&global_added_lock); + + return ok; +} + +int OBJ_create(const char *oid, const char *short_name, const char *long_name) { + ASN1_OBJECT *op = + create_object_with_text_oid(obj_next_nid, oid, short_name, long_name); + if (op == NULL || + !obj_add_object(op)) { + return NID_undef; + } + return op->nid; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/obj/obj_dat.h b/FoodApp/Pods/BoringSSL-GRPC/crypto/obj/obj_dat.h new file mode 100644 index 0000000..dceaf03 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/obj/obj_dat.h @@ -0,0 +1,6244 @@ +/* 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.] */ + +/* This file is generated by crypto/obj/objects.go. */ + + +#define NUM_NID 959 + +static const uint8_t kObjectData[] = { + /* NID_rsadsi */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, + /* NID_pkcs */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, + /* NID_md2 */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x02, + /* NID_md5 */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05, + /* NID_rc4 */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x03, 0x04, + /* NID_rsaEncryption */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, + /* NID_md2WithRSAEncryption */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x02, + /* NID_md5WithRSAEncryption */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x04, + /* NID_pbeWithMD2AndDES_CBC */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x05, 0x01, + /* NID_pbeWithMD5AndDES_CBC */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x05, 0x03, + /* NID_X500 */ + 0x55, + /* NID_X509 */ + 0x55, 0x04, + /* NID_commonName */ + 0x55, 0x04, 0x03, + /* NID_countryName */ + 0x55, 0x04, 0x06, + /* NID_localityName */ + 0x55, 0x04, 0x07, + /* NID_stateOrProvinceName */ + 0x55, 0x04, 0x08, + /* NID_organizationName */ + 0x55, 0x04, 0x0a, + /* NID_organizationalUnitName */ + 0x55, 0x04, 0x0b, + /* NID_rsa */ + 0x55, 0x08, 0x01, 0x01, + /* NID_pkcs7 */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, + /* NID_pkcs7_data */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, + /* NID_pkcs7_signed */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, + /* NID_pkcs7_enveloped */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x03, + /* NID_pkcs7_signedAndEnveloped */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x04, + /* NID_pkcs7_digest */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x05, + /* NID_pkcs7_encrypted */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x06, + /* NID_pkcs3 */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x03, + /* NID_dhKeyAgreement */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x03, 0x01, + /* NID_des_ecb */ + 0x2b, 0x0e, 0x03, 0x02, 0x06, + /* NID_des_cfb64 */ + 0x2b, 0x0e, 0x03, 0x02, 0x09, + /* NID_des_cbc */ + 0x2b, 0x0e, 0x03, 0x02, 0x07, + /* NID_des_ede_ecb */ + 0x2b, 0x0e, 0x03, 0x02, 0x11, + /* NID_idea_cbc */ + 0x2b, 0x06, 0x01, 0x04, 0x01, 0x81, 0x3c, 0x07, 0x01, 0x01, 0x02, + /* NID_rc2_cbc */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x03, 0x02, + /* NID_sha */ + 0x2b, 0x0e, 0x03, 0x02, 0x12, + /* NID_shaWithRSAEncryption */ + 0x2b, 0x0e, 0x03, 0x02, 0x0f, + /* NID_des_ede3_cbc */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x03, 0x07, + /* NID_des_ofb64 */ + 0x2b, 0x0e, 0x03, 0x02, 0x08, + /* NID_pkcs9 */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, + /* NID_pkcs9_emailAddress */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, + /* NID_pkcs9_unstructuredName */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x02, + /* NID_pkcs9_contentType */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x03, + /* NID_pkcs9_messageDigest */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x04, + /* NID_pkcs9_signingTime */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x05, + /* NID_pkcs9_countersignature */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x06, + /* NID_pkcs9_challengePassword */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x07, + /* NID_pkcs9_unstructuredAddress */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x08, + /* NID_pkcs9_extCertAttributes */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x09, + /* NID_netscape */ + 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, + /* NID_netscape_cert_extension */ + 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, + /* NID_netscape_data_type */ + 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x02, + /* NID_sha1 */ + 0x2b, 0x0e, 0x03, 0x02, 0x1a, + /* NID_sha1WithRSAEncryption */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, + /* NID_dsaWithSHA */ + 0x2b, 0x0e, 0x03, 0x02, 0x0d, + /* NID_dsa_2 */ + 0x2b, 0x0e, 0x03, 0x02, 0x0c, + /* NID_pbeWithSHA1AndRC2_CBC */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x05, 0x0b, + /* NID_id_pbkdf2 */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x05, 0x0c, + /* NID_dsaWithSHA1_2 */ + 0x2b, 0x0e, 0x03, 0x02, 0x1b, + /* NID_netscape_cert_type */ + 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, 0x01, + /* NID_netscape_base_url */ + 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, 0x02, + /* NID_netscape_revocation_url */ + 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, 0x03, + /* NID_netscape_ca_revocation_url */ + 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, 0x04, + /* NID_netscape_renewal_url */ + 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, 0x07, + /* NID_netscape_ca_policy_url */ + 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, 0x08, + /* NID_netscape_ssl_server_name */ + 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, 0x0c, + /* NID_netscape_comment */ + 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, 0x0d, + /* NID_netscape_cert_sequence */ + 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x02, 0x05, + /* NID_id_ce */ + 0x55, 0x1d, + /* NID_subject_key_identifier */ + 0x55, 0x1d, 0x0e, + /* NID_key_usage */ + 0x55, 0x1d, 0x0f, + /* NID_private_key_usage_period */ + 0x55, 0x1d, 0x10, + /* NID_subject_alt_name */ + 0x55, 0x1d, 0x11, + /* NID_issuer_alt_name */ + 0x55, 0x1d, 0x12, + /* NID_basic_constraints */ + 0x55, 0x1d, 0x13, + /* NID_crl_number */ + 0x55, 0x1d, 0x14, + /* NID_certificate_policies */ + 0x55, 0x1d, 0x20, + /* NID_authority_key_identifier */ + 0x55, 0x1d, 0x23, + /* NID_bf_cbc */ + 0x2b, 0x06, 0x01, 0x04, 0x01, 0x97, 0x55, 0x01, 0x02, + /* NID_mdc2 */ + 0x55, 0x08, 0x03, 0x65, + /* NID_mdc2WithRSA */ + 0x55, 0x08, 0x03, 0x64, + /* NID_givenName */ + 0x55, 0x04, 0x2a, + /* NID_surname */ + 0x55, 0x04, 0x04, + /* NID_initials */ + 0x55, 0x04, 0x2b, + /* NID_crl_distribution_points */ + 0x55, 0x1d, 0x1f, + /* NID_md5WithRSA */ + 0x2b, 0x0e, 0x03, 0x02, 0x03, + /* NID_serialNumber */ + 0x55, 0x04, 0x05, + /* NID_title */ + 0x55, 0x04, 0x0c, + /* NID_description */ + 0x55, 0x04, 0x0d, + /* NID_cast5_cbc */ + 0x2a, 0x86, 0x48, 0x86, 0xf6, 0x7d, 0x07, 0x42, 0x0a, + /* NID_pbeWithMD5AndCast5_CBC */ + 0x2a, 0x86, 0x48, 0x86, 0xf6, 0x7d, 0x07, 0x42, 0x0c, + /* NID_dsaWithSHA1 */ + 0x2a, 0x86, 0x48, 0xce, 0x38, 0x04, 0x03, + /* NID_sha1WithRSA */ + 0x2b, 0x0e, 0x03, 0x02, 0x1d, + /* NID_dsa */ + 0x2a, 0x86, 0x48, 0xce, 0x38, 0x04, 0x01, + /* NID_ripemd160 */ + 0x2b, 0x24, 0x03, 0x02, 0x01, + /* NID_ripemd160WithRSA */ + 0x2b, 0x24, 0x03, 0x03, 0x01, 0x02, + /* NID_rc5_cbc */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x03, 0x08, + /* NID_zlib_compression */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x03, 0x08, + /* NID_ext_key_usage */ + 0x55, 0x1d, 0x25, + /* NID_id_pkix */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, + /* NID_id_kp */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, + /* NID_server_auth */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01, + /* NID_client_auth */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, + /* NID_code_sign */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x03, + /* NID_email_protect */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x04, + /* NID_time_stamp */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x08, + /* NID_ms_code_ind */ + 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x02, 0x01, 0x15, + /* NID_ms_code_com */ + 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x02, 0x01, 0x16, + /* NID_ms_ctl_sign */ + 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x0a, 0x03, 0x01, + /* NID_ms_sgc */ + 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x0a, 0x03, 0x03, + /* NID_ms_efs */ + 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x0a, 0x03, 0x04, + /* NID_ns_sgc */ + 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x04, 0x01, + /* NID_delta_crl */ + 0x55, 0x1d, 0x1b, + /* NID_crl_reason */ + 0x55, 0x1d, 0x15, + /* NID_invalidity_date */ + 0x55, 0x1d, 0x18, + /* NID_sxnet */ + 0x2b, 0x65, 0x01, 0x04, 0x01, + /* NID_pbe_WithSHA1And128BitRC4 */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x01, 0x01, + /* NID_pbe_WithSHA1And40BitRC4 */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x01, 0x02, + /* NID_pbe_WithSHA1And3_Key_TripleDES_CBC */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x01, 0x03, + /* NID_pbe_WithSHA1And2_Key_TripleDES_CBC */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x01, 0x04, + /* NID_pbe_WithSHA1And128BitRC2_CBC */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x01, 0x05, + /* NID_pbe_WithSHA1And40BitRC2_CBC */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x01, 0x06, + /* NID_keyBag */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x0a, 0x01, 0x01, + /* NID_pkcs8ShroudedKeyBag */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x0a, 0x01, 0x02, + /* NID_certBag */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x0a, 0x01, 0x03, + /* NID_crlBag */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x0a, 0x01, 0x04, + /* NID_secretBag */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x0a, 0x01, 0x05, + /* NID_safeContentsBag */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x0a, 0x01, 0x06, + /* NID_friendlyName */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x14, + /* NID_localKeyID */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x15, + /* NID_x509Certificate */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x16, 0x01, + /* NID_sdsiCertificate */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x16, 0x02, + /* NID_x509Crl */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x17, 0x01, + /* NID_pbes2 */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x05, 0x0d, + /* NID_pbmac1 */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x05, 0x0e, + /* NID_hmacWithSHA1 */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x07, + /* NID_id_qt_cps */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, + /* NID_id_qt_unotice */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x02, + /* NID_SMIMECapabilities */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x0f, + /* NID_pbeWithMD2AndRC2_CBC */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x05, 0x04, + /* NID_pbeWithMD5AndRC2_CBC */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x05, 0x06, + /* NID_pbeWithSHA1AndDES_CBC */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x05, 0x0a, + /* NID_ms_ext_req */ + 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x02, 0x01, 0x0e, + /* NID_ext_req */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x0e, + /* NID_name */ + 0x55, 0x04, 0x29, + /* NID_dnQualifier */ + 0x55, 0x04, 0x2e, + /* NID_id_pe */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, + /* NID_id_ad */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, + /* NID_info_access */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, + /* NID_ad_OCSP */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, + /* NID_ad_ca_issuers */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, + /* NID_OCSP_sign */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x09, + /* NID_member_body */ + 0x2a, + /* NID_ISO_US */ + 0x2a, 0x86, 0x48, + /* NID_X9_57 */ + 0x2a, 0x86, 0x48, 0xce, 0x38, + /* NID_X9cm */ + 0x2a, 0x86, 0x48, 0xce, 0x38, 0x04, + /* NID_pkcs1 */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, + /* NID_pkcs5 */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x05, + /* NID_SMIME */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, + /* NID_id_smime_mod */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x00, + /* NID_id_smime_ct */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x01, + /* NID_id_smime_aa */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x02, + /* NID_id_smime_alg */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x03, + /* NID_id_smime_cd */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x04, + /* NID_id_smime_spq */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x05, + /* NID_id_smime_cti */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x06, + /* NID_id_smime_mod_cms */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x00, 0x01, + /* NID_id_smime_mod_ess */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x00, 0x02, + /* NID_id_smime_mod_oid */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x00, 0x03, + /* NID_id_smime_mod_msg_v3 */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x00, 0x04, + /* NID_id_smime_mod_ets_eSignature_88 */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x00, 0x05, + /* NID_id_smime_mod_ets_eSignature_97 */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x00, 0x06, + /* NID_id_smime_mod_ets_eSigPolicy_88 */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x00, 0x07, + /* NID_id_smime_mod_ets_eSigPolicy_97 */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x00, 0x08, + /* NID_id_smime_ct_receipt */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x01, 0x01, + /* NID_id_smime_ct_authData */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x01, 0x02, + /* NID_id_smime_ct_publishCert */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x01, 0x03, + /* NID_id_smime_ct_TSTInfo */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x01, 0x04, + /* NID_id_smime_ct_TDTInfo */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x01, 0x05, + /* NID_id_smime_ct_contentInfo */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x01, 0x06, + /* NID_id_smime_ct_DVCSRequestData */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x01, 0x07, + /* NID_id_smime_ct_DVCSResponseData */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x01, 0x08, + /* NID_id_smime_aa_receiptRequest */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x02, 0x01, + /* NID_id_smime_aa_securityLabel */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x02, 0x02, + /* NID_id_smime_aa_mlExpandHistory */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x02, 0x03, + /* NID_id_smime_aa_contentHint */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x02, 0x04, + /* NID_id_smime_aa_msgSigDigest */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x02, 0x05, + /* NID_id_smime_aa_encapContentType */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x02, 0x06, + /* NID_id_smime_aa_contentIdentifier */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x02, 0x07, + /* NID_id_smime_aa_macValue */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x02, 0x08, + /* NID_id_smime_aa_equivalentLabels */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x02, 0x09, + /* NID_id_smime_aa_contentReference */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x02, 0x0a, + /* NID_id_smime_aa_encrypKeyPref */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x02, 0x0b, + /* NID_id_smime_aa_signingCertificate */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x02, 0x0c, + /* NID_id_smime_aa_smimeEncryptCerts */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x02, 0x0d, + /* NID_id_smime_aa_timeStampToken */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x02, 0x0e, + /* NID_id_smime_aa_ets_sigPolicyId */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x02, 0x0f, + /* NID_id_smime_aa_ets_commitmentType */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x02, 0x10, + /* NID_id_smime_aa_ets_signerLocation */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x02, 0x11, + /* NID_id_smime_aa_ets_signerAttr */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x02, 0x12, + /* NID_id_smime_aa_ets_otherSigCert */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x02, 0x13, + /* NID_id_smime_aa_ets_contentTimestamp */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x02, 0x14, + /* NID_id_smime_aa_ets_CertificateRefs */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x02, 0x15, + /* NID_id_smime_aa_ets_RevocationRefs */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x02, 0x16, + /* NID_id_smime_aa_ets_certValues */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x02, 0x17, + /* NID_id_smime_aa_ets_revocationValues */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x02, 0x18, + /* NID_id_smime_aa_ets_escTimeStamp */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x02, 0x19, + /* NID_id_smime_aa_ets_certCRLTimestamp */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x02, 0x1a, + /* NID_id_smime_aa_ets_archiveTimeStamp */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x02, 0x1b, + /* NID_id_smime_aa_signatureType */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x02, 0x1c, + /* NID_id_smime_aa_dvcs_dvc */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x02, 0x1d, + /* NID_id_smime_alg_ESDHwith3DES */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x03, 0x01, + /* NID_id_smime_alg_ESDHwithRC2 */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x03, 0x02, + /* NID_id_smime_alg_3DESwrap */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x03, 0x03, + /* NID_id_smime_alg_RC2wrap */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x03, 0x04, + /* NID_id_smime_alg_ESDH */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x03, 0x05, + /* NID_id_smime_alg_CMS3DESwrap */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x03, 0x06, + /* NID_id_smime_alg_CMSRC2wrap */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x03, 0x07, + /* NID_id_smime_cd_ldap */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x04, 0x01, + /* NID_id_smime_spq_ets_sqt_uri */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x05, 0x01, + /* NID_id_smime_spq_ets_sqt_unotice */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x05, 0x02, + /* NID_id_smime_cti_ets_proofOfOrigin */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x06, 0x01, + /* NID_id_smime_cti_ets_proofOfReceipt */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x06, 0x02, + /* NID_id_smime_cti_ets_proofOfDelivery */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x06, 0x03, + /* NID_id_smime_cti_ets_proofOfSender */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x06, 0x04, + /* NID_id_smime_cti_ets_proofOfApproval */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x06, 0x05, + /* NID_id_smime_cti_ets_proofOfCreation */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x06, 0x06, + /* NID_md4 */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x04, + /* NID_id_pkix_mod */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x00, + /* NID_id_qt */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, + /* NID_id_it */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x04, + /* NID_id_pkip */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x05, + /* NID_id_alg */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x06, + /* NID_id_cmc */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x07, + /* NID_id_on */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x08, + /* NID_id_pda */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x09, + /* NID_id_aca */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x0a, + /* NID_id_qcs */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x0b, + /* NID_id_cct */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x0c, + /* NID_id_pkix1_explicit_88 */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x00, 0x01, + /* NID_id_pkix1_implicit_88 */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x00, 0x02, + /* NID_id_pkix1_explicit_93 */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x00, 0x03, + /* NID_id_pkix1_implicit_93 */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x00, 0x04, + /* NID_id_mod_crmf */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x00, 0x05, + /* NID_id_mod_cmc */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x00, 0x06, + /* NID_id_mod_kea_profile_88 */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x00, 0x07, + /* NID_id_mod_kea_profile_93 */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x00, 0x08, + /* NID_id_mod_cmp */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x00, 0x09, + /* NID_id_mod_qualified_cert_88 */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x00, 0x0a, + /* NID_id_mod_qualified_cert_93 */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x00, 0x0b, + /* NID_id_mod_attribute_cert */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x00, 0x0c, + /* NID_id_mod_timestamp_protocol */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x00, 0x0d, + /* NID_id_mod_ocsp */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x00, 0x0e, + /* NID_id_mod_dvcs */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x00, 0x0f, + /* NID_id_mod_cmp2000 */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x00, 0x10, + /* NID_biometricInfo */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x02, + /* NID_qcStatements */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x03, + /* NID_ac_auditEntity */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x04, + /* NID_ac_targeting */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x05, + /* NID_aaControls */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x06, + /* NID_sbgp_ipAddrBlock */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x07, + /* NID_sbgp_autonomousSysNum */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x08, + /* NID_sbgp_routerIdentifier */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x09, + /* NID_textNotice */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x03, + /* NID_ipsecEndSystem */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x05, + /* NID_ipsecTunnel */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x06, + /* NID_ipsecUser */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x07, + /* NID_dvcs */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x0a, + /* NID_id_it_caProtEncCert */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x04, 0x01, + /* NID_id_it_signKeyPairTypes */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x04, 0x02, + /* NID_id_it_encKeyPairTypes */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x04, 0x03, + /* NID_id_it_preferredSymmAlg */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x04, 0x04, + /* NID_id_it_caKeyUpdateInfo */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x04, 0x05, + /* NID_id_it_currentCRL */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x04, 0x06, + /* NID_id_it_unsupportedOIDs */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x04, 0x07, + /* NID_id_it_subscriptionRequest */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x04, 0x08, + /* NID_id_it_subscriptionResponse */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x04, 0x09, + /* NID_id_it_keyPairParamReq */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x04, 0x0a, + /* NID_id_it_keyPairParamRep */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x04, 0x0b, + /* NID_id_it_revPassphrase */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x04, 0x0c, + /* NID_id_it_implicitConfirm */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x04, 0x0d, + /* NID_id_it_confirmWaitTime */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x04, 0x0e, + /* NID_id_it_origPKIMessage */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x04, 0x0f, + /* NID_id_regCtrl */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x05, 0x01, + /* NID_id_regInfo */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x05, 0x02, + /* NID_id_regCtrl_regToken */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x05, 0x01, 0x01, + /* NID_id_regCtrl_authenticator */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x05, 0x01, 0x02, + /* NID_id_regCtrl_pkiPublicationInfo */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x05, 0x01, 0x03, + /* NID_id_regCtrl_pkiArchiveOptions */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x05, 0x01, 0x04, + /* NID_id_regCtrl_oldCertID */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x05, 0x01, 0x05, + /* NID_id_regCtrl_protocolEncrKey */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x05, 0x01, 0x06, + /* NID_id_regInfo_utf8Pairs */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x05, 0x02, 0x01, + /* NID_id_regInfo_certReq */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x05, 0x02, 0x02, + /* NID_id_alg_des40 */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x06, 0x01, + /* NID_id_alg_noSignature */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x06, 0x02, + /* NID_id_alg_dh_sig_hmac_sha1 */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x06, 0x03, + /* NID_id_alg_dh_pop */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x06, 0x04, + /* NID_id_cmc_statusInfo */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x07, 0x01, + /* NID_id_cmc_identification */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x07, 0x02, + /* NID_id_cmc_identityProof */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x07, 0x03, + /* NID_id_cmc_dataReturn */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x07, 0x04, + /* NID_id_cmc_transactionId */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x07, 0x05, + /* NID_id_cmc_senderNonce */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x07, 0x06, + /* NID_id_cmc_recipientNonce */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x07, 0x07, + /* NID_id_cmc_addExtensions */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x07, 0x08, + /* NID_id_cmc_encryptedPOP */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x07, 0x09, + /* NID_id_cmc_decryptedPOP */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x07, 0x0a, + /* NID_id_cmc_lraPOPWitness */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x07, 0x0b, + /* NID_id_cmc_getCert */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x07, 0x0f, + /* NID_id_cmc_getCRL */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x07, 0x10, + /* NID_id_cmc_revokeRequest */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x07, 0x11, + /* NID_id_cmc_regInfo */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x07, 0x12, + /* NID_id_cmc_responseInfo */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x07, 0x13, + /* NID_id_cmc_queryPending */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x07, 0x15, + /* NID_id_cmc_popLinkRandom */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x07, 0x16, + /* NID_id_cmc_popLinkWitness */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x07, 0x17, + /* NID_id_cmc_confirmCertAcceptance */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x07, 0x18, + /* NID_id_on_personalData */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x08, 0x01, + /* NID_id_pda_dateOfBirth */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x09, 0x01, + /* NID_id_pda_placeOfBirth */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x09, 0x02, + /* NID_id_pda_gender */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x09, 0x03, + /* NID_id_pda_countryOfCitizenship */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x09, 0x04, + /* NID_id_pda_countryOfResidence */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x09, 0x05, + /* NID_id_aca_authenticationInfo */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x0a, 0x01, + /* NID_id_aca_accessIdentity */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x0a, 0x02, + /* NID_id_aca_chargingIdentity */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x0a, 0x03, + /* NID_id_aca_group */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x0a, 0x04, + /* NID_id_aca_role */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x0a, 0x05, + /* NID_id_qcs_pkixQCSyntax_v1 */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x0b, 0x01, + /* NID_id_cct_crs */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x0c, 0x01, + /* NID_id_cct_PKIData */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x0c, 0x02, + /* NID_id_cct_PKIResponse */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x0c, 0x03, + /* NID_ad_timeStamping */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x03, + /* NID_ad_dvcs */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x04, + /* NID_id_pkix_OCSP_basic */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x01, + /* NID_id_pkix_OCSP_Nonce */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x02, + /* NID_id_pkix_OCSP_CrlID */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x03, + /* NID_id_pkix_OCSP_acceptableResponses */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x04, + /* NID_id_pkix_OCSP_noCheck */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x05, + /* NID_id_pkix_OCSP_archiveCutoff */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x06, + /* NID_id_pkix_OCSP_serviceLocator */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x07, + /* NID_id_pkix_OCSP_extendedStatus */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x08, + /* NID_id_pkix_OCSP_valid */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x09, + /* NID_id_pkix_OCSP_path */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x0a, + /* NID_id_pkix_OCSP_trustRoot */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x0b, + /* NID_algorithm */ + 0x2b, 0x0e, 0x03, 0x02, + /* NID_rsaSignature */ + 0x2b, 0x0e, 0x03, 0x02, 0x0b, + /* NID_X500algorithms */ + 0x55, 0x08, + /* NID_org */ + 0x2b, + /* NID_dod */ + 0x2b, 0x06, + /* NID_iana */ + 0x2b, 0x06, 0x01, + /* NID_Directory */ + 0x2b, 0x06, 0x01, 0x01, + /* NID_Management */ + 0x2b, 0x06, 0x01, 0x02, + /* NID_Experimental */ + 0x2b, 0x06, 0x01, 0x03, + /* NID_Private */ + 0x2b, 0x06, 0x01, 0x04, + /* NID_Security */ + 0x2b, 0x06, 0x01, 0x05, + /* NID_SNMPv2 */ + 0x2b, 0x06, 0x01, 0x06, + /* NID_Mail */ + 0x2b, 0x06, 0x01, 0x07, + /* NID_Enterprises */ + 0x2b, 0x06, 0x01, 0x04, 0x01, + /* NID_dcObject */ + 0x2b, 0x06, 0x01, 0x04, 0x01, 0x8b, 0x3a, 0x82, 0x58, + /* NID_domainComponent */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, + /* NID_Domain */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x04, 0x0d, + /* NID_selected_attribute_types */ + 0x55, 0x01, 0x05, + /* NID_clearance */ + 0x55, 0x01, 0x05, 0x37, + /* NID_md4WithRSAEncryption */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x03, + /* NID_ac_proxying */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x0a, + /* NID_sinfo_access */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x0b, + /* NID_id_aca_encAttrs */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x0a, 0x06, + /* NID_role */ + 0x55, 0x04, 0x48, + /* NID_policy_constraints */ + 0x55, 0x1d, 0x24, + /* NID_target_information */ + 0x55, 0x1d, 0x37, + /* NID_no_rev_avail */ + 0x55, 0x1d, 0x38, + /* NID_ansi_X9_62 */ + 0x2a, 0x86, 0x48, 0xce, 0x3d, + /* NID_X9_62_prime_field */ + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x01, 0x01, + /* NID_X9_62_characteristic_two_field */ + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x01, 0x02, + /* NID_X9_62_id_ecPublicKey */ + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, + /* NID_X9_62_prime192v1 */ + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x01, + /* NID_X9_62_prime192v2 */ + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x02, + /* NID_X9_62_prime192v3 */ + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x03, + /* NID_X9_62_prime239v1 */ + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x04, + /* NID_X9_62_prime239v2 */ + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x05, + /* NID_X9_62_prime239v3 */ + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x06, + /* NID_X9_62_prime256v1 */ + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, + /* NID_ecdsa_with_SHA1 */ + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x01, + /* NID_ms_csp_name */ + 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x11, 0x01, + /* NID_aes_128_ecb */ + 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x01, + /* NID_aes_128_cbc */ + 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x02, + /* NID_aes_128_ofb128 */ + 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x03, + /* NID_aes_128_cfb128 */ + 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x04, + /* NID_aes_192_ecb */ + 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x15, + /* NID_aes_192_cbc */ + 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x16, + /* NID_aes_192_ofb128 */ + 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x17, + /* NID_aes_192_cfb128 */ + 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x18, + /* NID_aes_256_ecb */ + 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x29, + /* NID_aes_256_cbc */ + 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x2a, + /* NID_aes_256_ofb128 */ + 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x2b, + /* NID_aes_256_cfb128 */ + 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x2c, + /* NID_hold_instruction_code */ + 0x55, 0x1d, 0x17, + /* NID_hold_instruction_none */ + 0x2a, 0x86, 0x48, 0xce, 0x38, 0x02, 0x01, + /* NID_hold_instruction_call_issuer */ + 0x2a, 0x86, 0x48, 0xce, 0x38, 0x02, 0x02, + /* NID_hold_instruction_reject */ + 0x2a, 0x86, 0x48, 0xce, 0x38, 0x02, 0x03, + /* NID_data */ + 0x09, + /* NID_pss */ + 0x09, 0x92, 0x26, + /* NID_ucl */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, + /* NID_pilot */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, + /* NID_pilotAttributeType */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, + /* NID_pilotAttributeSyntax */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x03, + /* NID_pilotObjectClass */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x04, + /* NID_pilotGroups */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x0a, + /* NID_iA5StringSyntax */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x03, 0x04, + /* NID_caseIgnoreIA5StringSyntax */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x03, 0x05, + /* NID_pilotObject */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x04, 0x03, + /* NID_pilotPerson */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x04, 0x04, + /* NID_account */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x04, 0x05, + /* NID_document */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x04, 0x06, + /* NID_room */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x04, 0x07, + /* NID_documentSeries */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x04, 0x09, + /* NID_rFC822localPart */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x04, 0x0e, + /* NID_dNSDomain */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x04, 0x0f, + /* NID_domainRelatedObject */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x04, 0x11, + /* NID_friendlyCountry */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x04, 0x12, + /* NID_simpleSecurityObject */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x04, 0x13, + /* NID_pilotOrganization */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x04, 0x14, + /* NID_pilotDSA */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x04, 0x15, + /* NID_qualityLabelledData */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x04, 0x16, + /* NID_userId */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x01, + /* NID_textEncodedORAddress */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x02, + /* NID_rfc822Mailbox */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x03, + /* NID_info */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x04, + /* NID_favouriteDrink */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x05, + /* NID_roomNumber */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x06, + /* NID_photo */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x07, + /* NID_userClass */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x08, + /* NID_host */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x09, + /* NID_manager */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x0a, + /* NID_documentIdentifier */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x0b, + /* NID_documentTitle */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x0c, + /* NID_documentVersion */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x0d, + /* NID_documentAuthor */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x0e, + /* NID_documentLocation */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x0f, + /* NID_homeTelephoneNumber */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x14, + /* NID_secretary */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x15, + /* NID_otherMailbox */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x16, + /* NID_lastModifiedTime */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x17, + /* NID_lastModifiedBy */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x18, + /* NID_aRecord */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x1a, + /* NID_pilotAttributeType27 */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x1b, + /* NID_mXRecord */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x1c, + /* NID_nSRecord */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x1d, + /* NID_sOARecord */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x1e, + /* NID_cNAMERecord */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x1f, + /* NID_associatedDomain */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x25, + /* NID_associatedName */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x26, + /* NID_homePostalAddress */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x27, + /* NID_personalTitle */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x28, + /* NID_mobileTelephoneNumber */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x29, + /* NID_pagerTelephoneNumber */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x2a, + /* NID_friendlyCountryName */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x2b, + /* NID_organizationalStatus */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x2d, + /* NID_janetMailbox */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x2e, + /* NID_mailPreferenceOption */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x2f, + /* NID_buildingName */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x30, + /* NID_dSAQuality */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x31, + /* NID_singleLevelQuality */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x32, + /* NID_subtreeMinimumQuality */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x33, + /* NID_subtreeMaximumQuality */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x34, + /* NID_personalSignature */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x35, + /* NID_dITRedirect */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x36, + /* NID_audio */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x37, + /* NID_documentPublisher */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x38, + /* NID_x500UniqueIdentifier */ + 0x55, 0x04, 0x2d, + /* NID_mime_mhs */ + 0x2b, 0x06, 0x01, 0x07, 0x01, + /* NID_mime_mhs_headings */ + 0x2b, 0x06, 0x01, 0x07, 0x01, 0x01, + /* NID_mime_mhs_bodies */ + 0x2b, 0x06, 0x01, 0x07, 0x01, 0x02, + /* NID_id_hex_partial_message */ + 0x2b, 0x06, 0x01, 0x07, 0x01, 0x01, 0x01, + /* NID_id_hex_multipart_message */ + 0x2b, 0x06, 0x01, 0x07, 0x01, 0x01, 0x02, + /* NID_generationQualifier */ + 0x55, 0x04, 0x2c, + /* NID_pseudonym */ + 0x55, 0x04, 0x41, + /* NID_id_set */ + 0x67, 0x2a, + /* NID_set_ctype */ + 0x67, 0x2a, 0x00, + /* NID_set_msgExt */ + 0x67, 0x2a, 0x01, + /* NID_set_attr */ + 0x67, 0x2a, 0x03, + /* NID_set_policy */ + 0x67, 0x2a, 0x05, + /* NID_set_certExt */ + 0x67, 0x2a, 0x07, + /* NID_set_brand */ + 0x67, 0x2a, 0x08, + /* NID_setct_PANData */ + 0x67, 0x2a, 0x00, 0x00, + /* NID_setct_PANToken */ + 0x67, 0x2a, 0x00, 0x01, + /* NID_setct_PANOnly */ + 0x67, 0x2a, 0x00, 0x02, + /* NID_setct_OIData */ + 0x67, 0x2a, 0x00, 0x03, + /* NID_setct_PI */ + 0x67, 0x2a, 0x00, 0x04, + /* NID_setct_PIData */ + 0x67, 0x2a, 0x00, 0x05, + /* NID_setct_PIDataUnsigned */ + 0x67, 0x2a, 0x00, 0x06, + /* NID_setct_HODInput */ + 0x67, 0x2a, 0x00, 0x07, + /* NID_setct_AuthResBaggage */ + 0x67, 0x2a, 0x00, 0x08, + /* NID_setct_AuthRevReqBaggage */ + 0x67, 0x2a, 0x00, 0x09, + /* NID_setct_AuthRevResBaggage */ + 0x67, 0x2a, 0x00, 0x0a, + /* NID_setct_CapTokenSeq */ + 0x67, 0x2a, 0x00, 0x0b, + /* NID_setct_PInitResData */ + 0x67, 0x2a, 0x00, 0x0c, + /* NID_setct_PI_TBS */ + 0x67, 0x2a, 0x00, 0x0d, + /* NID_setct_PResData */ + 0x67, 0x2a, 0x00, 0x0e, + /* NID_setct_AuthReqTBS */ + 0x67, 0x2a, 0x00, 0x10, + /* NID_setct_AuthResTBS */ + 0x67, 0x2a, 0x00, 0x11, + /* NID_setct_AuthResTBSX */ + 0x67, 0x2a, 0x00, 0x12, + /* NID_setct_AuthTokenTBS */ + 0x67, 0x2a, 0x00, 0x13, + /* NID_setct_CapTokenData */ + 0x67, 0x2a, 0x00, 0x14, + /* NID_setct_CapTokenTBS */ + 0x67, 0x2a, 0x00, 0x15, + /* NID_setct_AcqCardCodeMsg */ + 0x67, 0x2a, 0x00, 0x16, + /* NID_setct_AuthRevReqTBS */ + 0x67, 0x2a, 0x00, 0x17, + /* NID_setct_AuthRevResData */ + 0x67, 0x2a, 0x00, 0x18, + /* NID_setct_AuthRevResTBS */ + 0x67, 0x2a, 0x00, 0x19, + /* NID_setct_CapReqTBS */ + 0x67, 0x2a, 0x00, 0x1a, + /* NID_setct_CapReqTBSX */ + 0x67, 0x2a, 0x00, 0x1b, + /* NID_setct_CapResData */ + 0x67, 0x2a, 0x00, 0x1c, + /* NID_setct_CapRevReqTBS */ + 0x67, 0x2a, 0x00, 0x1d, + /* NID_setct_CapRevReqTBSX */ + 0x67, 0x2a, 0x00, 0x1e, + /* NID_setct_CapRevResData */ + 0x67, 0x2a, 0x00, 0x1f, + /* NID_setct_CredReqTBS */ + 0x67, 0x2a, 0x00, 0x20, + /* NID_setct_CredReqTBSX */ + 0x67, 0x2a, 0x00, 0x21, + /* NID_setct_CredResData */ + 0x67, 0x2a, 0x00, 0x22, + /* NID_setct_CredRevReqTBS */ + 0x67, 0x2a, 0x00, 0x23, + /* NID_setct_CredRevReqTBSX */ + 0x67, 0x2a, 0x00, 0x24, + /* NID_setct_CredRevResData */ + 0x67, 0x2a, 0x00, 0x25, + /* NID_setct_PCertReqData */ + 0x67, 0x2a, 0x00, 0x26, + /* NID_setct_PCertResTBS */ + 0x67, 0x2a, 0x00, 0x27, + /* NID_setct_BatchAdminReqData */ + 0x67, 0x2a, 0x00, 0x28, + /* NID_setct_BatchAdminResData */ + 0x67, 0x2a, 0x00, 0x29, + /* NID_setct_CardCInitResTBS */ + 0x67, 0x2a, 0x00, 0x2a, + /* NID_setct_MeAqCInitResTBS */ + 0x67, 0x2a, 0x00, 0x2b, + /* NID_setct_RegFormResTBS */ + 0x67, 0x2a, 0x00, 0x2c, + /* NID_setct_CertReqData */ + 0x67, 0x2a, 0x00, 0x2d, + /* NID_setct_CertReqTBS */ + 0x67, 0x2a, 0x00, 0x2e, + /* NID_setct_CertResData */ + 0x67, 0x2a, 0x00, 0x2f, + /* NID_setct_CertInqReqTBS */ + 0x67, 0x2a, 0x00, 0x30, + /* NID_setct_ErrorTBS */ + 0x67, 0x2a, 0x00, 0x31, + /* NID_setct_PIDualSignedTBE */ + 0x67, 0x2a, 0x00, 0x32, + /* NID_setct_PIUnsignedTBE */ + 0x67, 0x2a, 0x00, 0x33, + /* NID_setct_AuthReqTBE */ + 0x67, 0x2a, 0x00, 0x34, + /* NID_setct_AuthResTBE */ + 0x67, 0x2a, 0x00, 0x35, + /* NID_setct_AuthResTBEX */ + 0x67, 0x2a, 0x00, 0x36, + /* NID_setct_AuthTokenTBE */ + 0x67, 0x2a, 0x00, 0x37, + /* NID_setct_CapTokenTBE */ + 0x67, 0x2a, 0x00, 0x38, + /* NID_setct_CapTokenTBEX */ + 0x67, 0x2a, 0x00, 0x39, + /* NID_setct_AcqCardCodeMsgTBE */ + 0x67, 0x2a, 0x00, 0x3a, + /* NID_setct_AuthRevReqTBE */ + 0x67, 0x2a, 0x00, 0x3b, + /* NID_setct_AuthRevResTBE */ + 0x67, 0x2a, 0x00, 0x3c, + /* NID_setct_AuthRevResTBEB */ + 0x67, 0x2a, 0x00, 0x3d, + /* NID_setct_CapReqTBE */ + 0x67, 0x2a, 0x00, 0x3e, + /* NID_setct_CapReqTBEX */ + 0x67, 0x2a, 0x00, 0x3f, + /* NID_setct_CapResTBE */ + 0x67, 0x2a, 0x00, 0x40, + /* NID_setct_CapRevReqTBE */ + 0x67, 0x2a, 0x00, 0x41, + /* NID_setct_CapRevReqTBEX */ + 0x67, 0x2a, 0x00, 0x42, + /* NID_setct_CapRevResTBE */ + 0x67, 0x2a, 0x00, 0x43, + /* NID_setct_CredReqTBE */ + 0x67, 0x2a, 0x00, 0x44, + /* NID_setct_CredReqTBEX */ + 0x67, 0x2a, 0x00, 0x45, + /* NID_setct_CredResTBE */ + 0x67, 0x2a, 0x00, 0x46, + /* NID_setct_CredRevReqTBE */ + 0x67, 0x2a, 0x00, 0x47, + /* NID_setct_CredRevReqTBEX */ + 0x67, 0x2a, 0x00, 0x48, + /* NID_setct_CredRevResTBE */ + 0x67, 0x2a, 0x00, 0x49, + /* NID_setct_BatchAdminReqTBE */ + 0x67, 0x2a, 0x00, 0x4a, + /* NID_setct_BatchAdminResTBE */ + 0x67, 0x2a, 0x00, 0x4b, + /* NID_setct_RegFormReqTBE */ + 0x67, 0x2a, 0x00, 0x4c, + /* NID_setct_CertReqTBE */ + 0x67, 0x2a, 0x00, 0x4d, + /* NID_setct_CertReqTBEX */ + 0x67, 0x2a, 0x00, 0x4e, + /* NID_setct_CertResTBE */ + 0x67, 0x2a, 0x00, 0x4f, + /* NID_setct_CRLNotificationTBS */ + 0x67, 0x2a, 0x00, 0x50, + /* NID_setct_CRLNotificationResTBS */ + 0x67, 0x2a, 0x00, 0x51, + /* NID_setct_BCIDistributionTBS */ + 0x67, 0x2a, 0x00, 0x52, + /* NID_setext_genCrypt */ + 0x67, 0x2a, 0x01, 0x01, + /* NID_setext_miAuth */ + 0x67, 0x2a, 0x01, 0x03, + /* NID_setext_pinSecure */ + 0x67, 0x2a, 0x01, 0x04, + /* NID_setext_pinAny */ + 0x67, 0x2a, 0x01, 0x05, + /* NID_setext_track2 */ + 0x67, 0x2a, 0x01, 0x07, + /* NID_setext_cv */ + 0x67, 0x2a, 0x01, 0x08, + /* NID_set_policy_root */ + 0x67, 0x2a, 0x05, 0x00, + /* NID_setCext_hashedRoot */ + 0x67, 0x2a, 0x07, 0x00, + /* NID_setCext_certType */ + 0x67, 0x2a, 0x07, 0x01, + /* NID_setCext_merchData */ + 0x67, 0x2a, 0x07, 0x02, + /* NID_setCext_cCertRequired */ + 0x67, 0x2a, 0x07, 0x03, + /* NID_setCext_tunneling */ + 0x67, 0x2a, 0x07, 0x04, + /* NID_setCext_setExt */ + 0x67, 0x2a, 0x07, 0x05, + /* NID_setCext_setQualf */ + 0x67, 0x2a, 0x07, 0x06, + /* NID_setCext_PGWYcapabilities */ + 0x67, 0x2a, 0x07, 0x07, + /* NID_setCext_TokenIdentifier */ + 0x67, 0x2a, 0x07, 0x08, + /* NID_setCext_Track2Data */ + 0x67, 0x2a, 0x07, 0x09, + /* NID_setCext_TokenType */ + 0x67, 0x2a, 0x07, 0x0a, + /* NID_setCext_IssuerCapabilities */ + 0x67, 0x2a, 0x07, 0x0b, + /* NID_setAttr_Cert */ + 0x67, 0x2a, 0x03, 0x00, + /* NID_setAttr_PGWYcap */ + 0x67, 0x2a, 0x03, 0x01, + /* NID_setAttr_TokenType */ + 0x67, 0x2a, 0x03, 0x02, + /* NID_setAttr_IssCap */ + 0x67, 0x2a, 0x03, 0x03, + /* NID_set_rootKeyThumb */ + 0x67, 0x2a, 0x03, 0x00, 0x00, + /* NID_set_addPolicy */ + 0x67, 0x2a, 0x03, 0x00, 0x01, + /* NID_setAttr_Token_EMV */ + 0x67, 0x2a, 0x03, 0x02, 0x01, + /* NID_setAttr_Token_B0Prime */ + 0x67, 0x2a, 0x03, 0x02, 0x02, + /* NID_setAttr_IssCap_CVM */ + 0x67, 0x2a, 0x03, 0x03, 0x03, + /* NID_setAttr_IssCap_T2 */ + 0x67, 0x2a, 0x03, 0x03, 0x04, + /* NID_setAttr_IssCap_Sig */ + 0x67, 0x2a, 0x03, 0x03, 0x05, + /* NID_setAttr_GenCryptgrm */ + 0x67, 0x2a, 0x03, 0x03, 0x03, 0x01, + /* NID_setAttr_T2Enc */ + 0x67, 0x2a, 0x03, 0x03, 0x04, 0x01, + /* NID_setAttr_T2cleartxt */ + 0x67, 0x2a, 0x03, 0x03, 0x04, 0x02, + /* NID_setAttr_TokICCsig */ + 0x67, 0x2a, 0x03, 0x03, 0x05, 0x01, + /* NID_setAttr_SecDevSig */ + 0x67, 0x2a, 0x03, 0x03, 0x05, 0x02, + /* NID_set_brand_IATA_ATA */ + 0x67, 0x2a, 0x08, 0x01, + /* NID_set_brand_Diners */ + 0x67, 0x2a, 0x08, 0x1e, + /* NID_set_brand_AmericanExpress */ + 0x67, 0x2a, 0x08, 0x22, + /* NID_set_brand_JCB */ + 0x67, 0x2a, 0x08, 0x23, + /* NID_set_brand_Visa */ + 0x67, 0x2a, 0x08, 0x04, + /* NID_set_brand_MasterCard */ + 0x67, 0x2a, 0x08, 0x05, + /* NID_set_brand_Novus */ + 0x67, 0x2a, 0x08, 0xae, 0x7b, + /* NID_des_cdmf */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x03, 0x0a, + /* NID_rsaOAEPEncryptionSET */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x06, + /* NID_international_organizations */ + 0x67, + /* NID_ms_smartcard_login */ + 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x14, 0x02, 0x02, + /* NID_ms_upn */ + 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x14, 0x02, 0x03, + /* NID_streetAddress */ + 0x55, 0x04, 0x09, + /* NID_postalCode */ + 0x55, 0x04, 0x11, + /* NID_id_ppl */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x15, + /* NID_proxyCertInfo */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x0e, + /* NID_id_ppl_anyLanguage */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x15, 0x00, + /* NID_id_ppl_inheritAll */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x15, 0x01, + /* NID_name_constraints */ + 0x55, 0x1d, 0x1e, + /* NID_Independent */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x15, 0x02, + /* NID_sha256WithRSAEncryption */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, + /* NID_sha384WithRSAEncryption */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0c, + /* NID_sha512WithRSAEncryption */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0d, + /* NID_sha224WithRSAEncryption */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0e, + /* NID_sha256 */ + 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, + /* NID_sha384 */ + 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, + /* NID_sha512 */ + 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, + /* NID_sha224 */ + 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04, + /* NID_identified_organization */ + 0x2b, + /* NID_certicom_arc */ + 0x2b, 0x81, 0x04, + /* NID_wap */ + 0x67, 0x2b, + /* NID_wap_wsg */ + 0x67, 0x2b, 0x01, + /* NID_X9_62_id_characteristic_two_basis */ + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x01, 0x02, 0x03, + /* NID_X9_62_onBasis */ + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x01, 0x02, 0x03, 0x01, + /* NID_X9_62_tpBasis */ + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x01, 0x02, 0x03, 0x02, + /* NID_X9_62_ppBasis */ + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x01, 0x02, 0x03, 0x03, + /* NID_X9_62_c2pnb163v1 */ + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x00, 0x01, + /* NID_X9_62_c2pnb163v2 */ + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x00, 0x02, + /* NID_X9_62_c2pnb163v3 */ + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x00, 0x03, + /* NID_X9_62_c2pnb176v1 */ + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x00, 0x04, + /* NID_X9_62_c2tnb191v1 */ + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x00, 0x05, + /* NID_X9_62_c2tnb191v2 */ + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x00, 0x06, + /* NID_X9_62_c2tnb191v3 */ + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x00, 0x07, + /* NID_X9_62_c2onb191v4 */ + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x00, 0x08, + /* NID_X9_62_c2onb191v5 */ + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x00, 0x09, + /* NID_X9_62_c2pnb208w1 */ + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x00, 0x0a, + /* NID_X9_62_c2tnb239v1 */ + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x00, 0x0b, + /* NID_X9_62_c2tnb239v2 */ + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x00, 0x0c, + /* NID_X9_62_c2tnb239v3 */ + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x00, 0x0d, + /* NID_X9_62_c2onb239v4 */ + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x00, 0x0e, + /* NID_X9_62_c2onb239v5 */ + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x00, 0x0f, + /* NID_X9_62_c2pnb272w1 */ + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x00, 0x10, + /* NID_X9_62_c2pnb304w1 */ + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x00, 0x11, + /* NID_X9_62_c2tnb359v1 */ + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x00, 0x12, + /* NID_X9_62_c2pnb368w1 */ + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x00, 0x13, + /* NID_X9_62_c2tnb431r1 */ + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x00, 0x14, + /* NID_secp112r1 */ + 0x2b, 0x81, 0x04, 0x00, 0x06, + /* NID_secp112r2 */ + 0x2b, 0x81, 0x04, 0x00, 0x07, + /* NID_secp128r1 */ + 0x2b, 0x81, 0x04, 0x00, 0x1c, + /* NID_secp128r2 */ + 0x2b, 0x81, 0x04, 0x00, 0x1d, + /* NID_secp160k1 */ + 0x2b, 0x81, 0x04, 0x00, 0x09, + /* NID_secp160r1 */ + 0x2b, 0x81, 0x04, 0x00, 0x08, + /* NID_secp160r2 */ + 0x2b, 0x81, 0x04, 0x00, 0x1e, + /* NID_secp192k1 */ + 0x2b, 0x81, 0x04, 0x00, 0x1f, + /* NID_secp224k1 */ + 0x2b, 0x81, 0x04, 0x00, 0x20, + /* NID_secp224r1 */ + 0x2b, 0x81, 0x04, 0x00, 0x21, + /* NID_secp256k1 */ + 0x2b, 0x81, 0x04, 0x00, 0x0a, + /* NID_secp384r1 */ + 0x2b, 0x81, 0x04, 0x00, 0x22, + /* NID_secp521r1 */ + 0x2b, 0x81, 0x04, 0x00, 0x23, + /* NID_sect113r1 */ + 0x2b, 0x81, 0x04, 0x00, 0x04, + /* NID_sect113r2 */ + 0x2b, 0x81, 0x04, 0x00, 0x05, + /* NID_sect131r1 */ + 0x2b, 0x81, 0x04, 0x00, 0x16, + /* NID_sect131r2 */ + 0x2b, 0x81, 0x04, 0x00, 0x17, + /* NID_sect163k1 */ + 0x2b, 0x81, 0x04, 0x00, 0x01, + /* NID_sect163r1 */ + 0x2b, 0x81, 0x04, 0x00, 0x02, + /* NID_sect163r2 */ + 0x2b, 0x81, 0x04, 0x00, 0x0f, + /* NID_sect193r1 */ + 0x2b, 0x81, 0x04, 0x00, 0x18, + /* NID_sect193r2 */ + 0x2b, 0x81, 0x04, 0x00, 0x19, + /* NID_sect233k1 */ + 0x2b, 0x81, 0x04, 0x00, 0x1a, + /* NID_sect233r1 */ + 0x2b, 0x81, 0x04, 0x00, 0x1b, + /* NID_sect239k1 */ + 0x2b, 0x81, 0x04, 0x00, 0x03, + /* NID_sect283k1 */ + 0x2b, 0x81, 0x04, 0x00, 0x10, + /* NID_sect283r1 */ + 0x2b, 0x81, 0x04, 0x00, 0x11, + /* NID_sect409k1 */ + 0x2b, 0x81, 0x04, 0x00, 0x24, + /* NID_sect409r1 */ + 0x2b, 0x81, 0x04, 0x00, 0x25, + /* NID_sect571k1 */ + 0x2b, 0x81, 0x04, 0x00, 0x26, + /* NID_sect571r1 */ + 0x2b, 0x81, 0x04, 0x00, 0x27, + /* NID_wap_wsg_idm_ecid_wtls1 */ + 0x67, 0x2b, 0x01, 0x04, 0x01, + /* NID_wap_wsg_idm_ecid_wtls3 */ + 0x67, 0x2b, 0x01, 0x04, 0x03, + /* NID_wap_wsg_idm_ecid_wtls4 */ + 0x67, 0x2b, 0x01, 0x04, 0x04, + /* NID_wap_wsg_idm_ecid_wtls5 */ + 0x67, 0x2b, 0x01, 0x04, 0x05, + /* NID_wap_wsg_idm_ecid_wtls6 */ + 0x67, 0x2b, 0x01, 0x04, 0x06, + /* NID_wap_wsg_idm_ecid_wtls7 */ + 0x67, 0x2b, 0x01, 0x04, 0x07, + /* NID_wap_wsg_idm_ecid_wtls8 */ + 0x67, 0x2b, 0x01, 0x04, 0x08, + /* NID_wap_wsg_idm_ecid_wtls9 */ + 0x67, 0x2b, 0x01, 0x04, 0x09, + /* NID_wap_wsg_idm_ecid_wtls10 */ + 0x67, 0x2b, 0x01, 0x04, 0x0a, + /* NID_wap_wsg_idm_ecid_wtls11 */ + 0x67, 0x2b, 0x01, 0x04, 0x0b, + /* NID_wap_wsg_idm_ecid_wtls12 */ + 0x67, 0x2b, 0x01, 0x04, 0x0c, + /* NID_any_policy */ + 0x55, 0x1d, 0x20, 0x00, + /* NID_policy_mappings */ + 0x55, 0x1d, 0x21, + /* NID_inhibit_any_policy */ + 0x55, 0x1d, 0x36, + /* NID_camellia_128_cbc */ + 0x2a, 0x83, 0x08, 0x8c, 0x9a, 0x4b, 0x3d, 0x01, 0x01, 0x01, 0x02, + /* NID_camellia_192_cbc */ + 0x2a, 0x83, 0x08, 0x8c, 0x9a, 0x4b, 0x3d, 0x01, 0x01, 0x01, 0x03, + /* NID_camellia_256_cbc */ + 0x2a, 0x83, 0x08, 0x8c, 0x9a, 0x4b, 0x3d, 0x01, 0x01, 0x01, 0x04, + /* NID_camellia_128_ecb */ + 0x03, 0xa2, 0x31, 0x05, 0x03, 0x01, 0x09, 0x01, + /* NID_camellia_192_ecb */ + 0x03, 0xa2, 0x31, 0x05, 0x03, 0x01, 0x09, 0x15, + /* NID_camellia_256_ecb */ + 0x03, 0xa2, 0x31, 0x05, 0x03, 0x01, 0x09, 0x29, + /* NID_camellia_128_cfb128 */ + 0x03, 0xa2, 0x31, 0x05, 0x03, 0x01, 0x09, 0x04, + /* NID_camellia_192_cfb128 */ + 0x03, 0xa2, 0x31, 0x05, 0x03, 0x01, 0x09, 0x18, + /* NID_camellia_256_cfb128 */ + 0x03, 0xa2, 0x31, 0x05, 0x03, 0x01, 0x09, 0x2c, + /* NID_camellia_128_ofb128 */ + 0x03, 0xa2, 0x31, 0x05, 0x03, 0x01, 0x09, 0x03, + /* NID_camellia_192_ofb128 */ + 0x03, 0xa2, 0x31, 0x05, 0x03, 0x01, 0x09, 0x17, + /* NID_camellia_256_ofb128 */ + 0x03, 0xa2, 0x31, 0x05, 0x03, 0x01, 0x09, 0x2b, + /* NID_subject_directory_attributes */ + 0x55, 0x1d, 0x09, + /* NID_issuing_distribution_point */ + 0x55, 0x1d, 0x1c, + /* NID_certificate_issuer */ + 0x55, 0x1d, 0x1d, + /* NID_kisa */ + 0x2a, 0x83, 0x1a, 0x8c, 0x9a, 0x44, + /* NID_seed_ecb */ + 0x2a, 0x83, 0x1a, 0x8c, 0x9a, 0x44, 0x01, 0x03, + /* NID_seed_cbc */ + 0x2a, 0x83, 0x1a, 0x8c, 0x9a, 0x44, 0x01, 0x04, + /* NID_seed_ofb128 */ + 0x2a, 0x83, 0x1a, 0x8c, 0x9a, 0x44, 0x01, 0x06, + /* NID_seed_cfb128 */ + 0x2a, 0x83, 0x1a, 0x8c, 0x9a, 0x44, 0x01, 0x05, + /* NID_hmac_md5 */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x08, 0x01, 0x01, + /* NID_hmac_sha1 */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x08, 0x01, 0x02, + /* NID_id_PasswordBasedMAC */ + 0x2a, 0x86, 0x48, 0x86, 0xf6, 0x7d, 0x07, 0x42, 0x0d, + /* NID_id_DHBasedMac */ + 0x2a, 0x86, 0x48, 0x86, 0xf6, 0x7d, 0x07, 0x42, 0x1e, + /* NID_id_it_suppLangTags */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x04, 0x10, + /* NID_caRepository */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x05, + /* NID_id_smime_ct_compressedData */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x01, 0x09, + /* NID_id_ct_asciiTextWithCRLF */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x01, 0x1b, + /* NID_id_aes128_wrap */ + 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x05, + /* NID_id_aes192_wrap */ + 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x19, + /* NID_id_aes256_wrap */ + 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x2d, + /* NID_ecdsa_with_Recommended */ + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x02, + /* NID_ecdsa_with_Specified */ + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, + /* NID_ecdsa_with_SHA224 */ + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x01, + /* NID_ecdsa_with_SHA256 */ + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, + /* NID_ecdsa_with_SHA384 */ + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x03, + /* NID_ecdsa_with_SHA512 */ + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x04, + /* NID_hmacWithMD5 */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x06, + /* NID_hmacWithSHA224 */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x08, + /* NID_hmacWithSHA256 */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x09, + /* NID_hmacWithSHA384 */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x0a, + /* NID_hmacWithSHA512 */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x0b, + /* NID_dsa_with_SHA224 */ + 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x03, 0x01, + /* NID_dsa_with_SHA256 */ + 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x03, 0x02, + /* NID_whirlpool */ + 0x28, 0xcf, 0x06, 0x03, 0x00, 0x37, + /* NID_cryptopro */ + 0x2a, 0x85, 0x03, 0x02, 0x02, + /* NID_cryptocom */ + 0x2a, 0x85, 0x03, 0x02, 0x09, + /* NID_id_GostR3411_94_with_GostR3410_2001 */ + 0x2a, 0x85, 0x03, 0x02, 0x02, 0x03, + /* NID_id_GostR3411_94_with_GostR3410_94 */ + 0x2a, 0x85, 0x03, 0x02, 0x02, 0x04, + /* NID_id_GostR3411_94 */ + 0x2a, 0x85, 0x03, 0x02, 0x02, 0x09, + /* NID_id_HMACGostR3411_94 */ + 0x2a, 0x85, 0x03, 0x02, 0x02, 0x0a, + /* NID_id_GostR3410_2001 */ + 0x2a, 0x85, 0x03, 0x02, 0x02, 0x13, + /* NID_id_GostR3410_94 */ + 0x2a, 0x85, 0x03, 0x02, 0x02, 0x14, + /* NID_id_Gost28147_89 */ + 0x2a, 0x85, 0x03, 0x02, 0x02, 0x15, + /* NID_id_Gost28147_89_MAC */ + 0x2a, 0x85, 0x03, 0x02, 0x02, 0x16, + /* NID_id_GostR3411_94_prf */ + 0x2a, 0x85, 0x03, 0x02, 0x02, 0x17, + /* NID_id_GostR3410_2001DH */ + 0x2a, 0x85, 0x03, 0x02, 0x02, 0x62, + /* NID_id_GostR3410_94DH */ + 0x2a, 0x85, 0x03, 0x02, 0x02, 0x63, + /* NID_id_Gost28147_89_CryptoPro_KeyMeshing */ + 0x2a, 0x85, 0x03, 0x02, 0x02, 0x0e, 0x01, + /* NID_id_Gost28147_89_None_KeyMeshing */ + 0x2a, 0x85, 0x03, 0x02, 0x02, 0x0e, 0x00, + /* NID_id_GostR3411_94_TestParamSet */ + 0x2a, 0x85, 0x03, 0x02, 0x02, 0x1e, 0x00, + /* NID_id_GostR3411_94_CryptoProParamSet */ + 0x2a, 0x85, 0x03, 0x02, 0x02, 0x1e, 0x01, + /* NID_id_Gost28147_89_TestParamSet */ + 0x2a, 0x85, 0x03, 0x02, 0x02, 0x1f, 0x00, + /* NID_id_Gost28147_89_CryptoPro_A_ParamSet */ + 0x2a, 0x85, 0x03, 0x02, 0x02, 0x1f, 0x01, + /* NID_id_Gost28147_89_CryptoPro_B_ParamSet */ + 0x2a, 0x85, 0x03, 0x02, 0x02, 0x1f, 0x02, + /* NID_id_Gost28147_89_CryptoPro_C_ParamSet */ + 0x2a, 0x85, 0x03, 0x02, 0x02, 0x1f, 0x03, + /* NID_id_Gost28147_89_CryptoPro_D_ParamSet */ + 0x2a, 0x85, 0x03, 0x02, 0x02, 0x1f, 0x04, + /* NID_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet */ + 0x2a, 0x85, 0x03, 0x02, 0x02, 0x1f, 0x05, + /* NID_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet */ + 0x2a, 0x85, 0x03, 0x02, 0x02, 0x1f, 0x06, + /* NID_id_Gost28147_89_CryptoPro_RIC_1_ParamSet */ + 0x2a, 0x85, 0x03, 0x02, 0x02, 0x1f, 0x07, + /* NID_id_GostR3410_94_TestParamSet */ + 0x2a, 0x85, 0x03, 0x02, 0x02, 0x20, 0x00, + /* NID_id_GostR3410_94_CryptoPro_A_ParamSet */ + 0x2a, 0x85, 0x03, 0x02, 0x02, 0x20, 0x02, + /* NID_id_GostR3410_94_CryptoPro_B_ParamSet */ + 0x2a, 0x85, 0x03, 0x02, 0x02, 0x20, 0x03, + /* NID_id_GostR3410_94_CryptoPro_C_ParamSet */ + 0x2a, 0x85, 0x03, 0x02, 0x02, 0x20, 0x04, + /* NID_id_GostR3410_94_CryptoPro_D_ParamSet */ + 0x2a, 0x85, 0x03, 0x02, 0x02, 0x20, 0x05, + /* NID_id_GostR3410_94_CryptoPro_XchA_ParamSet */ + 0x2a, 0x85, 0x03, 0x02, 0x02, 0x21, 0x01, + /* NID_id_GostR3410_94_CryptoPro_XchB_ParamSet */ + 0x2a, 0x85, 0x03, 0x02, 0x02, 0x21, 0x02, + /* NID_id_GostR3410_94_CryptoPro_XchC_ParamSet */ + 0x2a, 0x85, 0x03, 0x02, 0x02, 0x21, 0x03, + /* NID_id_GostR3410_2001_TestParamSet */ + 0x2a, 0x85, 0x03, 0x02, 0x02, 0x23, 0x00, + /* NID_id_GostR3410_2001_CryptoPro_A_ParamSet */ + 0x2a, 0x85, 0x03, 0x02, 0x02, 0x23, 0x01, + /* NID_id_GostR3410_2001_CryptoPro_B_ParamSet */ + 0x2a, 0x85, 0x03, 0x02, 0x02, 0x23, 0x02, + /* NID_id_GostR3410_2001_CryptoPro_C_ParamSet */ + 0x2a, 0x85, 0x03, 0x02, 0x02, 0x23, 0x03, + /* NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet */ + 0x2a, 0x85, 0x03, 0x02, 0x02, 0x24, 0x00, + /* NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet */ + 0x2a, 0x85, 0x03, 0x02, 0x02, 0x24, 0x01, + /* NID_id_GostR3410_94_a */ + 0x2a, 0x85, 0x03, 0x02, 0x02, 0x14, 0x01, + /* NID_id_GostR3410_94_aBis */ + 0x2a, 0x85, 0x03, 0x02, 0x02, 0x14, 0x02, + /* NID_id_GostR3410_94_b */ + 0x2a, 0x85, 0x03, 0x02, 0x02, 0x14, 0x03, + /* NID_id_GostR3410_94_bBis */ + 0x2a, 0x85, 0x03, 0x02, 0x02, 0x14, 0x04, + /* NID_id_Gost28147_89_cc */ + 0x2a, 0x85, 0x03, 0x02, 0x09, 0x01, 0x06, 0x01, + /* NID_id_GostR3410_94_cc */ + 0x2a, 0x85, 0x03, 0x02, 0x09, 0x01, 0x05, 0x03, + /* NID_id_GostR3410_2001_cc */ + 0x2a, 0x85, 0x03, 0x02, 0x09, 0x01, 0x05, 0x04, + /* NID_id_GostR3411_94_with_GostR3410_94_cc */ + 0x2a, 0x85, 0x03, 0x02, 0x09, 0x01, 0x03, 0x03, + /* NID_id_GostR3411_94_with_GostR3410_2001_cc */ + 0x2a, 0x85, 0x03, 0x02, 0x09, 0x01, 0x03, 0x04, + /* NID_id_GostR3410_2001_ParamSet_cc */ + 0x2a, 0x85, 0x03, 0x02, 0x09, 0x01, 0x08, 0x01, + /* NID_LocalKeySet */ + 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x11, 0x02, + /* NID_freshest_crl */ + 0x55, 0x1d, 0x2e, + /* NID_id_on_permanentIdentifier */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x08, 0x03, + /* NID_searchGuide */ + 0x55, 0x04, 0x0e, + /* NID_businessCategory */ + 0x55, 0x04, 0x0f, + /* NID_postalAddress */ + 0x55, 0x04, 0x10, + /* NID_postOfficeBox */ + 0x55, 0x04, 0x12, + /* NID_physicalDeliveryOfficeName */ + 0x55, 0x04, 0x13, + /* NID_telephoneNumber */ + 0x55, 0x04, 0x14, + /* NID_telexNumber */ + 0x55, 0x04, 0x15, + /* NID_teletexTerminalIdentifier */ + 0x55, 0x04, 0x16, + /* NID_facsimileTelephoneNumber */ + 0x55, 0x04, 0x17, + /* NID_x121Address */ + 0x55, 0x04, 0x18, + /* NID_internationaliSDNNumber */ + 0x55, 0x04, 0x19, + /* NID_registeredAddress */ + 0x55, 0x04, 0x1a, + /* NID_destinationIndicator */ + 0x55, 0x04, 0x1b, + /* NID_preferredDeliveryMethod */ + 0x55, 0x04, 0x1c, + /* NID_presentationAddress */ + 0x55, 0x04, 0x1d, + /* NID_supportedApplicationContext */ + 0x55, 0x04, 0x1e, + /* NID_member */ + 0x55, 0x04, 0x1f, + /* NID_owner */ + 0x55, 0x04, 0x20, + /* NID_roleOccupant */ + 0x55, 0x04, 0x21, + /* NID_seeAlso */ + 0x55, 0x04, 0x22, + /* NID_userPassword */ + 0x55, 0x04, 0x23, + /* NID_userCertificate */ + 0x55, 0x04, 0x24, + /* NID_cACertificate */ + 0x55, 0x04, 0x25, + /* NID_authorityRevocationList */ + 0x55, 0x04, 0x26, + /* NID_certificateRevocationList */ + 0x55, 0x04, 0x27, + /* NID_crossCertificatePair */ + 0x55, 0x04, 0x28, + /* NID_enhancedSearchGuide */ + 0x55, 0x04, 0x2f, + /* NID_protocolInformation */ + 0x55, 0x04, 0x30, + /* NID_distinguishedName */ + 0x55, 0x04, 0x31, + /* NID_uniqueMember */ + 0x55, 0x04, 0x32, + /* NID_houseIdentifier */ + 0x55, 0x04, 0x33, + /* NID_supportedAlgorithms */ + 0x55, 0x04, 0x34, + /* NID_deltaRevocationList */ + 0x55, 0x04, 0x35, + /* NID_dmdName */ + 0x55, 0x04, 0x36, + /* NID_id_alg_PWRI_KEK */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x03, 0x09, + /* NID_aes_128_gcm */ + 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x06, + /* NID_aes_128_ccm */ + 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x07, + /* NID_id_aes128_wrap_pad */ + 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x08, + /* NID_aes_192_gcm */ + 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x1a, + /* NID_aes_192_ccm */ + 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x1b, + /* NID_id_aes192_wrap_pad */ + 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x1c, + /* NID_aes_256_gcm */ + 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x2e, + /* NID_aes_256_ccm */ + 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x2f, + /* NID_id_aes256_wrap_pad */ + 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x30, + /* NID_id_camellia128_wrap */ + 0x2a, 0x83, 0x08, 0x8c, 0x9a, 0x4b, 0x3d, 0x01, 0x01, 0x03, 0x02, + /* NID_id_camellia192_wrap */ + 0x2a, 0x83, 0x08, 0x8c, 0x9a, 0x4b, 0x3d, 0x01, 0x01, 0x03, 0x03, + /* NID_id_camellia256_wrap */ + 0x2a, 0x83, 0x08, 0x8c, 0x9a, 0x4b, 0x3d, 0x01, 0x01, 0x03, 0x04, + /* NID_anyExtendedKeyUsage */ + 0x55, 0x1d, 0x25, 0x00, + /* NID_mgf1 */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x08, + /* NID_rsassaPss */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0a, + /* NID_rsaesOaep */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x07, + /* NID_dhpublicnumber */ + 0x2a, 0x86, 0x48, 0xce, 0x3e, 0x02, 0x01, + /* NID_brainpoolP160r1 */ + 0x2b, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x01, + /* NID_brainpoolP160t1 */ + 0x2b, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x02, + /* NID_brainpoolP192r1 */ + 0x2b, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x03, + /* NID_brainpoolP192t1 */ + 0x2b, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x04, + /* NID_brainpoolP224r1 */ + 0x2b, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x05, + /* NID_brainpoolP224t1 */ + 0x2b, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x06, + /* NID_brainpoolP256r1 */ + 0x2b, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x07, + /* NID_brainpoolP256t1 */ + 0x2b, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x08, + /* NID_brainpoolP320r1 */ + 0x2b, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x09, + /* NID_brainpoolP320t1 */ + 0x2b, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x0a, + /* NID_brainpoolP384r1 */ + 0x2b, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x0b, + /* NID_brainpoolP384t1 */ + 0x2b, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x0c, + /* NID_brainpoolP512r1 */ + 0x2b, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x0d, + /* NID_brainpoolP512t1 */ + 0x2b, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x0e, + /* NID_pSpecified */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x09, + /* NID_dhSinglePass_stdDH_sha1kdf_scheme */ + 0x2b, 0x81, 0x05, 0x10, 0x86, 0x48, 0x3f, 0x00, 0x02, + /* NID_dhSinglePass_stdDH_sha224kdf_scheme */ + 0x2b, 0x81, 0x04, 0x01, 0x0b, 0x00, + /* NID_dhSinglePass_stdDH_sha256kdf_scheme */ + 0x2b, 0x81, 0x04, 0x01, 0x0b, 0x01, + /* NID_dhSinglePass_stdDH_sha384kdf_scheme */ + 0x2b, 0x81, 0x04, 0x01, 0x0b, 0x02, + /* NID_dhSinglePass_stdDH_sha512kdf_scheme */ + 0x2b, 0x81, 0x04, 0x01, 0x0b, 0x03, + /* NID_dhSinglePass_cofactorDH_sha1kdf_scheme */ + 0x2b, 0x81, 0x05, 0x10, 0x86, 0x48, 0x3f, 0x00, 0x03, + /* NID_dhSinglePass_cofactorDH_sha224kdf_scheme */ + 0x2b, 0x81, 0x04, 0x01, 0x0e, 0x00, + /* NID_dhSinglePass_cofactorDH_sha256kdf_scheme */ + 0x2b, 0x81, 0x04, 0x01, 0x0e, 0x01, + /* NID_dhSinglePass_cofactorDH_sha384kdf_scheme */ + 0x2b, 0x81, 0x04, 0x01, 0x0e, 0x02, + /* NID_dhSinglePass_cofactorDH_sha512kdf_scheme */ + 0x2b, 0x81, 0x04, 0x01, 0x0e, 0x03, + /* NID_ED25519 */ + 0x2b, 0x65, 0x70, +}; + +static const ASN1_OBJECT kObjects[NUM_NID] = { + {"UNDEF", "undefined", NID_undef, 0, NULL, 0}, + {"rsadsi", "RSA Data Security, Inc.", NID_rsadsi, 6, &kObjectData[0], 0}, + {"pkcs", "RSA Data Security, Inc. PKCS", NID_pkcs, 7, &kObjectData[6], 0}, + {"MD2", "md2", NID_md2, 8, &kObjectData[13], 0}, + {"MD5", "md5", NID_md5, 8, &kObjectData[21], 0}, + {"RC4", "rc4", NID_rc4, 8, &kObjectData[29], 0}, + {"rsaEncryption", "rsaEncryption", NID_rsaEncryption, 9, &kObjectData[37], + 0}, + {"RSA-MD2", "md2WithRSAEncryption", NID_md2WithRSAEncryption, 9, + &kObjectData[46], 0}, + {"RSA-MD5", "md5WithRSAEncryption", NID_md5WithRSAEncryption, 9, + &kObjectData[55], 0}, + {"PBE-MD2-DES", "pbeWithMD2AndDES-CBC", NID_pbeWithMD2AndDES_CBC, 9, + &kObjectData[64], 0}, + {"PBE-MD5-DES", "pbeWithMD5AndDES-CBC", NID_pbeWithMD5AndDES_CBC, 9, + &kObjectData[73], 0}, + {"X500", "directory services (X.500)", NID_X500, 1, &kObjectData[82], 0}, + {"X509", "X509", NID_X509, 2, &kObjectData[83], 0}, + {"CN", "commonName", NID_commonName, 3, &kObjectData[85], 0}, + {"C", "countryName", NID_countryName, 3, &kObjectData[88], 0}, + {"L", "localityName", NID_localityName, 3, &kObjectData[91], 0}, + {"ST", "stateOrProvinceName", NID_stateOrProvinceName, 3, &kObjectData[94], + 0}, + {"O", "organizationName", NID_organizationName, 3, &kObjectData[97], 0}, + {"OU", "organizationalUnitName", NID_organizationalUnitName, 3, + &kObjectData[100], 0}, + {"RSA", "rsa", NID_rsa, 4, &kObjectData[103], 0}, + {"pkcs7", "pkcs7", NID_pkcs7, 8, &kObjectData[107], 0}, + {"pkcs7-data", "pkcs7-data", NID_pkcs7_data, 9, &kObjectData[115], 0}, + {"pkcs7-signedData", "pkcs7-signedData", NID_pkcs7_signed, 9, + &kObjectData[124], 0}, + {"pkcs7-envelopedData", "pkcs7-envelopedData", NID_pkcs7_enveloped, 9, + &kObjectData[133], 0}, + {"pkcs7-signedAndEnvelopedData", "pkcs7-signedAndEnvelopedData", + NID_pkcs7_signedAndEnveloped, 9, &kObjectData[142], 0}, + {"pkcs7-digestData", "pkcs7-digestData", NID_pkcs7_digest, 9, + &kObjectData[151], 0}, + {"pkcs7-encryptedData", "pkcs7-encryptedData", NID_pkcs7_encrypted, 9, + &kObjectData[160], 0}, + {"pkcs3", "pkcs3", NID_pkcs3, 8, &kObjectData[169], 0}, + {"dhKeyAgreement", "dhKeyAgreement", NID_dhKeyAgreement, 9, + &kObjectData[177], 0}, + {"DES-ECB", "des-ecb", NID_des_ecb, 5, &kObjectData[186], 0}, + {"DES-CFB", "des-cfb", NID_des_cfb64, 5, &kObjectData[191], 0}, + {"DES-CBC", "des-cbc", NID_des_cbc, 5, &kObjectData[196], 0}, + {"DES-EDE", "des-ede", NID_des_ede_ecb, 5, &kObjectData[201], 0}, + {"DES-EDE3", "des-ede3", NID_des_ede3_ecb, 0, NULL, 0}, + {"IDEA-CBC", "idea-cbc", NID_idea_cbc, 11, &kObjectData[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, &kObjectData[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, &kObjectData[225], 0}, + {"RSA-SHA", "shaWithRSAEncryption", NID_shaWithRSAEncryption, 5, + &kObjectData[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, &kObjectData[235], 0}, + {"DES-OFB", "des-ofb", NID_des_ofb64, 5, &kObjectData[243], 0}, + {"IDEA-OFB", "idea-ofb", NID_idea_ofb64, 0, NULL, 0}, + {"pkcs9", "pkcs9", NID_pkcs9, 8, &kObjectData[248], 0}, + {"emailAddress", "emailAddress", NID_pkcs9_emailAddress, 9, + &kObjectData[256], 0}, + {"unstructuredName", "unstructuredName", NID_pkcs9_unstructuredName, 9, + &kObjectData[265], 0}, + {"contentType", "contentType", NID_pkcs9_contentType, 9, &kObjectData[274], + 0}, + {"messageDigest", "messageDigest", NID_pkcs9_messageDigest, 9, + &kObjectData[283], 0}, + {"signingTime", "signingTime", NID_pkcs9_signingTime, 9, &kObjectData[292], + 0}, + {"countersignature", "countersignature", NID_pkcs9_countersignature, 9, + &kObjectData[301], 0}, + {"challengePassword", "challengePassword", NID_pkcs9_challengePassword, 9, + &kObjectData[310], 0}, + {"unstructuredAddress", "unstructuredAddress", + NID_pkcs9_unstructuredAddress, 9, &kObjectData[319], 0}, + {"extendedCertificateAttributes", "extendedCertificateAttributes", + NID_pkcs9_extCertAttributes, 9, &kObjectData[328], 0}, + {"Netscape", "Netscape Communications Corp.", NID_netscape, 7, + &kObjectData[337], 0}, + {"nsCertExt", "Netscape Certificate Extension", NID_netscape_cert_extension, + 8, &kObjectData[344], 0}, + {"nsDataType", "Netscape Data Type", NID_netscape_data_type, 8, + &kObjectData[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, &kObjectData[360], 0}, + {"RSA-SHA1", "sha1WithRSAEncryption", NID_sha1WithRSAEncryption, 9, + &kObjectData[365], 0}, + {"DSA-SHA", "dsaWithSHA", NID_dsaWithSHA, 5, &kObjectData[374], 0}, + {"DSA-old", "dsaEncryption-old", NID_dsa_2, 5, &kObjectData[379], 0}, + {"PBE-SHA1-RC2-64", "pbeWithSHA1AndRC2-CBC", NID_pbeWithSHA1AndRC2_CBC, 9, + &kObjectData[384], 0}, + {"PBKDF2", "PBKDF2", NID_id_pbkdf2, 9, &kObjectData[393], 0}, + {"DSA-SHA1-old", "dsaWithSHA1-old", NID_dsaWithSHA1_2, 5, &kObjectData[402], + 0}, + {"nsCertType", "Netscape Cert Type", NID_netscape_cert_type, 9, + &kObjectData[407], 0}, + {"nsBaseUrl", "Netscape Base Url", NID_netscape_base_url, 9, + &kObjectData[416], 0}, + {"nsRevocationUrl", "Netscape Revocation Url", NID_netscape_revocation_url, + 9, &kObjectData[425], 0}, + {"nsCaRevocationUrl", "Netscape CA Revocation Url", + NID_netscape_ca_revocation_url, 9, &kObjectData[434], 0}, + {"nsRenewalUrl", "Netscape Renewal Url", NID_netscape_renewal_url, 9, + &kObjectData[443], 0}, + {"nsCaPolicyUrl", "Netscape CA Policy Url", NID_netscape_ca_policy_url, 9, + &kObjectData[452], 0}, + {"nsSslServerName", "Netscape SSL Server Name", + NID_netscape_ssl_server_name, 9, &kObjectData[461], 0}, + {"nsComment", "Netscape Comment", NID_netscape_comment, 9, + &kObjectData[470], 0}, + {"nsCertSequence", "Netscape Certificate Sequence", + NID_netscape_cert_sequence, 9, &kObjectData[479], 0}, + {"DESX-CBC", "desx-cbc", NID_desx_cbc, 0, NULL, 0}, + {"id-ce", "id-ce", NID_id_ce, 2, &kObjectData[488], 0}, + {"subjectKeyIdentifier", "X509v3 Subject Key Identifier", + NID_subject_key_identifier, 3, &kObjectData[490], 0}, + {"keyUsage", "X509v3 Key Usage", NID_key_usage, 3, &kObjectData[493], 0}, + {"privateKeyUsagePeriod", "X509v3 Private Key Usage Period", + NID_private_key_usage_period, 3, &kObjectData[496], 0}, + {"subjectAltName", "X509v3 Subject Alternative Name", NID_subject_alt_name, + 3, &kObjectData[499], 0}, + {"issuerAltName", "X509v3 Issuer Alternative Name", NID_issuer_alt_name, 3, + &kObjectData[502], 0}, + {"basicConstraints", "X509v3 Basic Constraints", NID_basic_constraints, 3, + &kObjectData[505], 0}, + {"crlNumber", "X509v3 CRL Number", NID_crl_number, 3, &kObjectData[508], 0}, + {"certificatePolicies", "X509v3 Certificate Policies", + NID_certificate_policies, 3, &kObjectData[511], 0}, + {"authorityKeyIdentifier", "X509v3 Authority Key Identifier", + NID_authority_key_identifier, 3, &kObjectData[514], 0}, + {"BF-CBC", "bf-cbc", NID_bf_cbc, 9, &kObjectData[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, &kObjectData[526], 0}, + {"RSA-MDC2", "mdc2WithRSA", NID_mdc2WithRSA, 4, &kObjectData[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, &kObjectData[534], 0}, + {"SN", "surname", NID_surname, 3, &kObjectData[537], 0}, + {"initials", "initials", NID_initials, 3, &kObjectData[540], 0}, + {NULL, NULL, NID_undef, 0, NULL, 0}, + {"crlDistributionPoints", "X509v3 CRL Distribution Points", + NID_crl_distribution_points, 3, &kObjectData[543], 0}, + {"RSA-NP-MD5", "md5WithRSA", NID_md5WithRSA, 5, &kObjectData[546], 0}, + {"serialNumber", "serialNumber", NID_serialNumber, 3, &kObjectData[551], 0}, + {"title", "title", NID_title, 3, &kObjectData[554], 0}, + {"description", "description", NID_description, 3, &kObjectData[557], 0}, + {"CAST5-CBC", "cast5-cbc", NID_cast5_cbc, 9, &kObjectData[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, &kObjectData[569], 0}, + {"DSA-SHA1", "dsaWithSHA1", NID_dsaWithSHA1, 7, &kObjectData[578], 0}, + {"MD5-SHA1", "md5-sha1", NID_md5_sha1, 0, NULL, 0}, + {"RSA-SHA1-2", "sha1WithRSA", NID_sha1WithRSA, 5, &kObjectData[585], 0}, + {"DSA", "dsaEncryption", NID_dsa, 7, &kObjectData[590], 0}, + {"RIPEMD160", "ripemd160", NID_ripemd160, 5, &kObjectData[597], 0}, + {NULL, NULL, NID_undef, 0, NULL, 0}, + {"RSA-RIPEMD160", "ripemd160WithRSA", NID_ripemd160WithRSA, 6, + &kObjectData[602], 0}, + {"RC5-CBC", "rc5-cbc", NID_rc5_cbc, 8, &kObjectData[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}, + {NULL, NULL, NID_undef, 0, NULL, 0}, + {"ZLIB", "zlib compression", NID_zlib_compression, 11, &kObjectData[616], + 0}, + {"extendedKeyUsage", "X509v3 Extended Key Usage", NID_ext_key_usage, 3, + &kObjectData[627], 0}, + {"PKIX", "PKIX", NID_id_pkix, 6, &kObjectData[630], 0}, + {"id-kp", "id-kp", NID_id_kp, 7, &kObjectData[636], 0}, + {"serverAuth", "TLS Web Server Authentication", NID_server_auth, 8, + &kObjectData[643], 0}, + {"clientAuth", "TLS Web Client Authentication", NID_client_auth, 8, + &kObjectData[651], 0}, + {"codeSigning", "Code Signing", NID_code_sign, 8, &kObjectData[659], 0}, + {"emailProtection", "E-mail Protection", NID_email_protect, 8, + &kObjectData[667], 0}, + {"timeStamping", "Time Stamping", NID_time_stamp, 8, &kObjectData[675], 0}, + {"msCodeInd", "Microsoft Individual Code Signing", NID_ms_code_ind, 10, + &kObjectData[683], 0}, + {"msCodeCom", "Microsoft Commercial Code Signing", NID_ms_code_com, 10, + &kObjectData[693], 0}, + {"msCTLSign", "Microsoft Trust List Signing", NID_ms_ctl_sign, 10, + &kObjectData[703], 0}, + {"msSGC", "Microsoft Server Gated Crypto", NID_ms_sgc, 10, + &kObjectData[713], 0}, + {"msEFS", "Microsoft Encrypted File System", NID_ms_efs, 10, + &kObjectData[723], 0}, + {"nsSGC", "Netscape Server Gated Crypto", NID_ns_sgc, 9, &kObjectData[733], + 0}, + {"deltaCRL", "X509v3 Delta CRL Indicator", NID_delta_crl, 3, + &kObjectData[742], 0}, + {"CRLReason", "X509v3 CRL Reason Code", NID_crl_reason, 3, + &kObjectData[745], 0}, + {"invalidityDate", "Invalidity Date", NID_invalidity_date, 3, + &kObjectData[748], 0}, + {"SXNetID", "Strong Extranet ID", NID_sxnet, 5, &kObjectData[751], 0}, + {"PBE-SHA1-RC4-128", "pbeWithSHA1And128BitRC4", + NID_pbe_WithSHA1And128BitRC4, 10, &kObjectData[756], 0}, + {"PBE-SHA1-RC4-40", "pbeWithSHA1And40BitRC4", NID_pbe_WithSHA1And40BitRC4, + 10, &kObjectData[766], 0}, + {"PBE-SHA1-3DES", "pbeWithSHA1And3-KeyTripleDES-CBC", + NID_pbe_WithSHA1And3_Key_TripleDES_CBC, 10, &kObjectData[776], 0}, + {"PBE-SHA1-2DES", "pbeWithSHA1And2-KeyTripleDES-CBC", + NID_pbe_WithSHA1And2_Key_TripleDES_CBC, 10, &kObjectData[786], 0}, + {"PBE-SHA1-RC2-128", "pbeWithSHA1And128BitRC2-CBC", + NID_pbe_WithSHA1And128BitRC2_CBC, 10, &kObjectData[796], 0}, + {"PBE-SHA1-RC2-40", "pbeWithSHA1And40BitRC2-CBC", + NID_pbe_WithSHA1And40BitRC2_CBC, 10, &kObjectData[806], 0}, + {"keyBag", "keyBag", NID_keyBag, 11, &kObjectData[816], 0}, + {"pkcs8ShroudedKeyBag", "pkcs8ShroudedKeyBag", NID_pkcs8ShroudedKeyBag, 11, + &kObjectData[827], 0}, + {"certBag", "certBag", NID_certBag, 11, &kObjectData[838], 0}, + {"crlBag", "crlBag", NID_crlBag, 11, &kObjectData[849], 0}, + {"secretBag", "secretBag", NID_secretBag, 11, &kObjectData[860], 0}, + {"safeContentsBag", "safeContentsBag", NID_safeContentsBag, 11, + &kObjectData[871], 0}, + {"friendlyName", "friendlyName", NID_friendlyName, 9, &kObjectData[882], 0}, + {"localKeyID", "localKeyID", NID_localKeyID, 9, &kObjectData[891], 0}, + {"x509Certificate", "x509Certificate", NID_x509Certificate, 10, + &kObjectData[900], 0}, + {"sdsiCertificate", "sdsiCertificate", NID_sdsiCertificate, 10, + &kObjectData[910], 0}, + {"x509Crl", "x509Crl", NID_x509Crl, 10, &kObjectData[920], 0}, + {"PBES2", "PBES2", NID_pbes2, 9, &kObjectData[930], 0}, + {"PBMAC1", "PBMAC1", NID_pbmac1, 9, &kObjectData[939], 0}, + {"hmacWithSHA1", "hmacWithSHA1", NID_hmacWithSHA1, 8, &kObjectData[948], 0}, + {"id-qt-cps", "Policy Qualifier CPS", NID_id_qt_cps, 8, &kObjectData[956], + 0}, + {"id-qt-unotice", "Policy Qualifier User Notice", NID_id_qt_unotice, 8, + &kObjectData[964], 0}, + {"RC2-64-CBC", "rc2-64-cbc", NID_rc2_64_cbc, 0, NULL, 0}, + {"SMIME-CAPS", "S/MIME Capabilities", NID_SMIMECapabilities, 9, + &kObjectData[972], 0}, + {"PBE-MD2-RC2-64", "pbeWithMD2AndRC2-CBC", NID_pbeWithMD2AndRC2_CBC, 9, + &kObjectData[981], 0}, + {"PBE-MD5-RC2-64", "pbeWithMD5AndRC2-CBC", NID_pbeWithMD5AndRC2_CBC, 9, + &kObjectData[990], 0}, + {"PBE-SHA1-DES", "pbeWithSHA1AndDES-CBC", NID_pbeWithSHA1AndDES_CBC, 9, + &kObjectData[999], 0}, + {"msExtReq", "Microsoft Extension Request", NID_ms_ext_req, 10, + &kObjectData[1008], 0}, + {"extReq", "Extension Request", NID_ext_req, 9, &kObjectData[1018], 0}, + {"name", "name", NID_name, 3, &kObjectData[1027], 0}, + {"dnQualifier", "dnQualifier", NID_dnQualifier, 3, &kObjectData[1030], 0}, + {"id-pe", "id-pe", NID_id_pe, 7, &kObjectData[1033], 0}, + {"id-ad", "id-ad", NID_id_ad, 7, &kObjectData[1040], 0}, + {"authorityInfoAccess", "Authority Information Access", NID_info_access, 8, + &kObjectData[1047], 0}, + {"OCSP", "OCSP", NID_ad_OCSP, 8, &kObjectData[1055], 0}, + {"caIssuers", "CA Issuers", NID_ad_ca_issuers, 8, &kObjectData[1063], 0}, + {"OCSPSigning", "OCSP Signing", NID_OCSP_sign, 8, &kObjectData[1071], 0}, + {"ISO", "iso", NID_iso, 0, NULL, 0}, + {"member-body", "ISO Member Body", NID_member_body, 1, &kObjectData[1079], + 0}, + {"ISO-US", "ISO US Member Body", NID_ISO_US, 3, &kObjectData[1080], 0}, + {"X9-57", "X9.57", NID_X9_57, 5, &kObjectData[1083], 0}, + {"X9cm", "X9.57 CM ?", NID_X9cm, 6, &kObjectData[1088], 0}, + {"pkcs1", "pkcs1", NID_pkcs1, 8, &kObjectData[1094], 0}, + {"pkcs5", "pkcs5", NID_pkcs5, 8, &kObjectData[1102], 0}, + {"SMIME", "S/MIME", NID_SMIME, 9, &kObjectData[1110], 0}, + {"id-smime-mod", "id-smime-mod", NID_id_smime_mod, 10, &kObjectData[1119], + 0}, + {"id-smime-ct", "id-smime-ct", NID_id_smime_ct, 10, &kObjectData[1129], 0}, + {"id-smime-aa", "id-smime-aa", NID_id_smime_aa, 10, &kObjectData[1139], 0}, + {"id-smime-alg", "id-smime-alg", NID_id_smime_alg, 10, &kObjectData[1149], + 0}, + {"id-smime-cd", "id-smime-cd", NID_id_smime_cd, 10, &kObjectData[1159], 0}, + {"id-smime-spq", "id-smime-spq", NID_id_smime_spq, 10, &kObjectData[1169], + 0}, + {"id-smime-cti", "id-smime-cti", NID_id_smime_cti, 10, &kObjectData[1179], + 0}, + {"id-smime-mod-cms", "id-smime-mod-cms", NID_id_smime_mod_cms, 11, + &kObjectData[1189], 0}, + {"id-smime-mod-ess", "id-smime-mod-ess", NID_id_smime_mod_ess, 11, + &kObjectData[1200], 0}, + {"id-smime-mod-oid", "id-smime-mod-oid", NID_id_smime_mod_oid, 11, + &kObjectData[1211], 0}, + {"id-smime-mod-msg-v3", "id-smime-mod-msg-v3", NID_id_smime_mod_msg_v3, 11, + &kObjectData[1222], 0}, + {"id-smime-mod-ets-eSignature-88", "id-smime-mod-ets-eSignature-88", + NID_id_smime_mod_ets_eSignature_88, 11, &kObjectData[1233], 0}, + {"id-smime-mod-ets-eSignature-97", "id-smime-mod-ets-eSignature-97", + NID_id_smime_mod_ets_eSignature_97, 11, &kObjectData[1244], 0}, + {"id-smime-mod-ets-eSigPolicy-88", "id-smime-mod-ets-eSigPolicy-88", + NID_id_smime_mod_ets_eSigPolicy_88, 11, &kObjectData[1255], 0}, + {"id-smime-mod-ets-eSigPolicy-97", "id-smime-mod-ets-eSigPolicy-97", + NID_id_smime_mod_ets_eSigPolicy_97, 11, &kObjectData[1266], 0}, + {"id-smime-ct-receipt", "id-smime-ct-receipt", NID_id_smime_ct_receipt, 11, + &kObjectData[1277], 0}, + {"id-smime-ct-authData", "id-smime-ct-authData", NID_id_smime_ct_authData, + 11, &kObjectData[1288], 0}, + {"id-smime-ct-publishCert", "id-smime-ct-publishCert", + NID_id_smime_ct_publishCert, 11, &kObjectData[1299], 0}, + {"id-smime-ct-TSTInfo", "id-smime-ct-TSTInfo", NID_id_smime_ct_TSTInfo, 11, + &kObjectData[1310], 0}, + {"id-smime-ct-TDTInfo", "id-smime-ct-TDTInfo", NID_id_smime_ct_TDTInfo, 11, + &kObjectData[1321], 0}, + {"id-smime-ct-contentInfo", "id-smime-ct-contentInfo", + NID_id_smime_ct_contentInfo, 11, &kObjectData[1332], 0}, + {"id-smime-ct-DVCSRequestData", "id-smime-ct-DVCSRequestData", + NID_id_smime_ct_DVCSRequestData, 11, &kObjectData[1343], 0}, + {"id-smime-ct-DVCSResponseData", "id-smime-ct-DVCSResponseData", + NID_id_smime_ct_DVCSResponseData, 11, &kObjectData[1354], 0}, + {"id-smime-aa-receiptRequest", "id-smime-aa-receiptRequest", + NID_id_smime_aa_receiptRequest, 11, &kObjectData[1365], 0}, + {"id-smime-aa-securityLabel", "id-smime-aa-securityLabel", + NID_id_smime_aa_securityLabel, 11, &kObjectData[1376], 0}, + {"id-smime-aa-mlExpandHistory", "id-smime-aa-mlExpandHistory", + NID_id_smime_aa_mlExpandHistory, 11, &kObjectData[1387], 0}, + {"id-smime-aa-contentHint", "id-smime-aa-contentHint", + NID_id_smime_aa_contentHint, 11, &kObjectData[1398], 0}, + {"id-smime-aa-msgSigDigest", "id-smime-aa-msgSigDigest", + NID_id_smime_aa_msgSigDigest, 11, &kObjectData[1409], 0}, + {"id-smime-aa-encapContentType", "id-smime-aa-encapContentType", + NID_id_smime_aa_encapContentType, 11, &kObjectData[1420], 0}, + {"id-smime-aa-contentIdentifier", "id-smime-aa-contentIdentifier", + NID_id_smime_aa_contentIdentifier, 11, &kObjectData[1431], 0}, + {"id-smime-aa-macValue", "id-smime-aa-macValue", NID_id_smime_aa_macValue, + 11, &kObjectData[1442], 0}, + {"id-smime-aa-equivalentLabels", "id-smime-aa-equivalentLabels", + NID_id_smime_aa_equivalentLabels, 11, &kObjectData[1453], 0}, + {"id-smime-aa-contentReference", "id-smime-aa-contentReference", + NID_id_smime_aa_contentReference, 11, &kObjectData[1464], 0}, + {"id-smime-aa-encrypKeyPref", "id-smime-aa-encrypKeyPref", + NID_id_smime_aa_encrypKeyPref, 11, &kObjectData[1475], 0}, + {"id-smime-aa-signingCertificate", "id-smime-aa-signingCertificate", + NID_id_smime_aa_signingCertificate, 11, &kObjectData[1486], 0}, + {"id-smime-aa-smimeEncryptCerts", "id-smime-aa-smimeEncryptCerts", + NID_id_smime_aa_smimeEncryptCerts, 11, &kObjectData[1497], 0}, + {"id-smime-aa-timeStampToken", "id-smime-aa-timeStampToken", + NID_id_smime_aa_timeStampToken, 11, &kObjectData[1508], 0}, + {"id-smime-aa-ets-sigPolicyId", "id-smime-aa-ets-sigPolicyId", + NID_id_smime_aa_ets_sigPolicyId, 11, &kObjectData[1519], 0}, + {"id-smime-aa-ets-commitmentType", "id-smime-aa-ets-commitmentType", + NID_id_smime_aa_ets_commitmentType, 11, &kObjectData[1530], 0}, + {"id-smime-aa-ets-signerLocation", "id-smime-aa-ets-signerLocation", + NID_id_smime_aa_ets_signerLocation, 11, &kObjectData[1541], 0}, + {"id-smime-aa-ets-signerAttr", "id-smime-aa-ets-signerAttr", + NID_id_smime_aa_ets_signerAttr, 11, &kObjectData[1552], 0}, + {"id-smime-aa-ets-otherSigCert", "id-smime-aa-ets-otherSigCert", + NID_id_smime_aa_ets_otherSigCert, 11, &kObjectData[1563], 0}, + {"id-smime-aa-ets-contentTimestamp", "id-smime-aa-ets-contentTimestamp", + NID_id_smime_aa_ets_contentTimestamp, 11, &kObjectData[1574], 0}, + {"id-smime-aa-ets-CertificateRefs", "id-smime-aa-ets-CertificateRefs", + NID_id_smime_aa_ets_CertificateRefs, 11, &kObjectData[1585], 0}, + {"id-smime-aa-ets-RevocationRefs", "id-smime-aa-ets-RevocationRefs", + NID_id_smime_aa_ets_RevocationRefs, 11, &kObjectData[1596], 0}, + {"id-smime-aa-ets-certValues", "id-smime-aa-ets-certValues", + NID_id_smime_aa_ets_certValues, 11, &kObjectData[1607], 0}, + {"id-smime-aa-ets-revocationValues", "id-smime-aa-ets-revocationValues", + NID_id_smime_aa_ets_revocationValues, 11, &kObjectData[1618], 0}, + {"id-smime-aa-ets-escTimeStamp", "id-smime-aa-ets-escTimeStamp", + NID_id_smime_aa_ets_escTimeStamp, 11, &kObjectData[1629], 0}, + {"id-smime-aa-ets-certCRLTimestamp", "id-smime-aa-ets-certCRLTimestamp", + NID_id_smime_aa_ets_certCRLTimestamp, 11, &kObjectData[1640], 0}, + {"id-smime-aa-ets-archiveTimeStamp", "id-smime-aa-ets-archiveTimeStamp", + NID_id_smime_aa_ets_archiveTimeStamp, 11, &kObjectData[1651], 0}, + {"id-smime-aa-signatureType", "id-smime-aa-signatureType", + NID_id_smime_aa_signatureType, 11, &kObjectData[1662], 0}, + {"id-smime-aa-dvcs-dvc", "id-smime-aa-dvcs-dvc", NID_id_smime_aa_dvcs_dvc, + 11, &kObjectData[1673], 0}, + {"id-smime-alg-ESDHwith3DES", "id-smime-alg-ESDHwith3DES", + NID_id_smime_alg_ESDHwith3DES, 11, &kObjectData[1684], 0}, + {"id-smime-alg-ESDHwithRC2", "id-smime-alg-ESDHwithRC2", + NID_id_smime_alg_ESDHwithRC2, 11, &kObjectData[1695], 0}, + {"id-smime-alg-3DESwrap", "id-smime-alg-3DESwrap", + NID_id_smime_alg_3DESwrap, 11, &kObjectData[1706], 0}, + {"id-smime-alg-RC2wrap", "id-smime-alg-RC2wrap", NID_id_smime_alg_RC2wrap, + 11, &kObjectData[1717], 0}, + {"id-smime-alg-ESDH", "id-smime-alg-ESDH", NID_id_smime_alg_ESDH, 11, + &kObjectData[1728], 0}, + {"id-smime-alg-CMS3DESwrap", "id-smime-alg-CMS3DESwrap", + NID_id_smime_alg_CMS3DESwrap, 11, &kObjectData[1739], 0}, + {"id-smime-alg-CMSRC2wrap", "id-smime-alg-CMSRC2wrap", + NID_id_smime_alg_CMSRC2wrap, 11, &kObjectData[1750], 0}, + {"id-smime-cd-ldap", "id-smime-cd-ldap", NID_id_smime_cd_ldap, 11, + &kObjectData[1761], 0}, + {"id-smime-spq-ets-sqt-uri", "id-smime-spq-ets-sqt-uri", + NID_id_smime_spq_ets_sqt_uri, 11, &kObjectData[1772], 0}, + {"id-smime-spq-ets-sqt-unotice", "id-smime-spq-ets-sqt-unotice", + NID_id_smime_spq_ets_sqt_unotice, 11, &kObjectData[1783], 0}, + {"id-smime-cti-ets-proofOfOrigin", "id-smime-cti-ets-proofOfOrigin", + NID_id_smime_cti_ets_proofOfOrigin, 11, &kObjectData[1794], 0}, + {"id-smime-cti-ets-proofOfReceipt", "id-smime-cti-ets-proofOfReceipt", + NID_id_smime_cti_ets_proofOfReceipt, 11, &kObjectData[1805], 0}, + {"id-smime-cti-ets-proofOfDelivery", "id-smime-cti-ets-proofOfDelivery", + NID_id_smime_cti_ets_proofOfDelivery, 11, &kObjectData[1816], 0}, + {"id-smime-cti-ets-proofOfSender", "id-smime-cti-ets-proofOfSender", + NID_id_smime_cti_ets_proofOfSender, 11, &kObjectData[1827], 0}, + {"id-smime-cti-ets-proofOfApproval", "id-smime-cti-ets-proofOfApproval", + NID_id_smime_cti_ets_proofOfApproval, 11, &kObjectData[1838], 0}, + {"id-smime-cti-ets-proofOfCreation", "id-smime-cti-ets-proofOfCreation", + NID_id_smime_cti_ets_proofOfCreation, 11, &kObjectData[1849], 0}, + {"MD4", "md4", NID_md4, 8, &kObjectData[1860], 0}, + {"id-pkix-mod", "id-pkix-mod", NID_id_pkix_mod, 7, &kObjectData[1868], 0}, + {"id-qt", "id-qt", NID_id_qt, 7, &kObjectData[1875], 0}, + {"id-it", "id-it", NID_id_it, 7, &kObjectData[1882], 0}, + {"id-pkip", "id-pkip", NID_id_pkip, 7, &kObjectData[1889], 0}, + {"id-alg", "id-alg", NID_id_alg, 7, &kObjectData[1896], 0}, + {"id-cmc", "id-cmc", NID_id_cmc, 7, &kObjectData[1903], 0}, + {"id-on", "id-on", NID_id_on, 7, &kObjectData[1910], 0}, + {"id-pda", "id-pda", NID_id_pda, 7, &kObjectData[1917], 0}, + {"id-aca", "id-aca", NID_id_aca, 7, &kObjectData[1924], 0}, + {"id-qcs", "id-qcs", NID_id_qcs, 7, &kObjectData[1931], 0}, + {"id-cct", "id-cct", NID_id_cct, 7, &kObjectData[1938], 0}, + {"id-pkix1-explicit-88", "id-pkix1-explicit-88", NID_id_pkix1_explicit_88, + 8, &kObjectData[1945], 0}, + {"id-pkix1-implicit-88", "id-pkix1-implicit-88", NID_id_pkix1_implicit_88, + 8, &kObjectData[1953], 0}, + {"id-pkix1-explicit-93", "id-pkix1-explicit-93", NID_id_pkix1_explicit_93, + 8, &kObjectData[1961], 0}, + {"id-pkix1-implicit-93", "id-pkix1-implicit-93", NID_id_pkix1_implicit_93, + 8, &kObjectData[1969], 0}, + {"id-mod-crmf", "id-mod-crmf", NID_id_mod_crmf, 8, &kObjectData[1977], 0}, + {"id-mod-cmc", "id-mod-cmc", NID_id_mod_cmc, 8, &kObjectData[1985], 0}, + {"id-mod-kea-profile-88", "id-mod-kea-profile-88", + NID_id_mod_kea_profile_88, 8, &kObjectData[1993], 0}, + {"id-mod-kea-profile-93", "id-mod-kea-profile-93", + NID_id_mod_kea_profile_93, 8, &kObjectData[2001], 0}, + {"id-mod-cmp", "id-mod-cmp", NID_id_mod_cmp, 8, &kObjectData[2009], 0}, + {"id-mod-qualified-cert-88", "id-mod-qualified-cert-88", + NID_id_mod_qualified_cert_88, 8, &kObjectData[2017], 0}, + {"id-mod-qualified-cert-93", "id-mod-qualified-cert-93", + NID_id_mod_qualified_cert_93, 8, &kObjectData[2025], 0}, + {"id-mod-attribute-cert", "id-mod-attribute-cert", + NID_id_mod_attribute_cert, 8, &kObjectData[2033], 0}, + {"id-mod-timestamp-protocol", "id-mod-timestamp-protocol", + NID_id_mod_timestamp_protocol, 8, &kObjectData[2041], 0}, + {"id-mod-ocsp", "id-mod-ocsp", NID_id_mod_ocsp, 8, &kObjectData[2049], 0}, + {"id-mod-dvcs", "id-mod-dvcs", NID_id_mod_dvcs, 8, &kObjectData[2057], 0}, + {"id-mod-cmp2000", "id-mod-cmp2000", NID_id_mod_cmp2000, 8, + &kObjectData[2065], 0}, + {"biometricInfo", "Biometric Info", NID_biometricInfo, 8, + &kObjectData[2073], 0}, + {"qcStatements", "qcStatements", NID_qcStatements, 8, &kObjectData[2081], + 0}, + {"ac-auditEntity", "ac-auditEntity", NID_ac_auditEntity, 8, + &kObjectData[2089], 0}, + {"ac-targeting", "ac-targeting", NID_ac_targeting, 8, &kObjectData[2097], + 0}, + {"aaControls", "aaControls", NID_aaControls, 8, &kObjectData[2105], 0}, + {"sbgp-ipAddrBlock", "sbgp-ipAddrBlock", NID_sbgp_ipAddrBlock, 8, + &kObjectData[2113], 0}, + {"sbgp-autonomousSysNum", "sbgp-autonomousSysNum", + NID_sbgp_autonomousSysNum, 8, &kObjectData[2121], 0}, + {"sbgp-routerIdentifier", "sbgp-routerIdentifier", + NID_sbgp_routerIdentifier, 8, &kObjectData[2129], 0}, + {"textNotice", "textNotice", NID_textNotice, 8, &kObjectData[2137], 0}, + {"ipsecEndSystem", "IPSec End System", NID_ipsecEndSystem, 8, + &kObjectData[2145], 0}, + {"ipsecTunnel", "IPSec Tunnel", NID_ipsecTunnel, 8, &kObjectData[2153], 0}, + {"ipsecUser", "IPSec User", NID_ipsecUser, 8, &kObjectData[2161], 0}, + {"DVCS", "dvcs", NID_dvcs, 8, &kObjectData[2169], 0}, + {"id-it-caProtEncCert", "id-it-caProtEncCert", NID_id_it_caProtEncCert, 8, + &kObjectData[2177], 0}, + {"id-it-signKeyPairTypes", "id-it-signKeyPairTypes", + NID_id_it_signKeyPairTypes, 8, &kObjectData[2185], 0}, + {"id-it-encKeyPairTypes", "id-it-encKeyPairTypes", + NID_id_it_encKeyPairTypes, 8, &kObjectData[2193], 0}, + {"id-it-preferredSymmAlg", "id-it-preferredSymmAlg", + NID_id_it_preferredSymmAlg, 8, &kObjectData[2201], 0}, + {"id-it-caKeyUpdateInfo", "id-it-caKeyUpdateInfo", + NID_id_it_caKeyUpdateInfo, 8, &kObjectData[2209], 0}, + {"id-it-currentCRL", "id-it-currentCRL", NID_id_it_currentCRL, 8, + &kObjectData[2217], 0}, + {"id-it-unsupportedOIDs", "id-it-unsupportedOIDs", + NID_id_it_unsupportedOIDs, 8, &kObjectData[2225], 0}, + {"id-it-subscriptionRequest", "id-it-subscriptionRequest", + NID_id_it_subscriptionRequest, 8, &kObjectData[2233], 0}, + {"id-it-subscriptionResponse", "id-it-subscriptionResponse", + NID_id_it_subscriptionResponse, 8, &kObjectData[2241], 0}, + {"id-it-keyPairParamReq", "id-it-keyPairParamReq", + NID_id_it_keyPairParamReq, 8, &kObjectData[2249], 0}, + {"id-it-keyPairParamRep", "id-it-keyPairParamRep", + NID_id_it_keyPairParamRep, 8, &kObjectData[2257], 0}, + {"id-it-revPassphrase", "id-it-revPassphrase", NID_id_it_revPassphrase, 8, + &kObjectData[2265], 0}, + {"id-it-implicitConfirm", "id-it-implicitConfirm", + NID_id_it_implicitConfirm, 8, &kObjectData[2273], 0}, + {"id-it-confirmWaitTime", "id-it-confirmWaitTime", + NID_id_it_confirmWaitTime, 8, &kObjectData[2281], 0}, + {"id-it-origPKIMessage", "id-it-origPKIMessage", NID_id_it_origPKIMessage, + 8, &kObjectData[2289], 0}, + {"id-regCtrl", "id-regCtrl", NID_id_regCtrl, 8, &kObjectData[2297], 0}, + {"id-regInfo", "id-regInfo", NID_id_regInfo, 8, &kObjectData[2305], 0}, + {"id-regCtrl-regToken", "id-regCtrl-regToken", NID_id_regCtrl_regToken, 9, + &kObjectData[2313], 0}, + {"id-regCtrl-authenticator", "id-regCtrl-authenticator", + NID_id_regCtrl_authenticator, 9, &kObjectData[2322], 0}, + {"id-regCtrl-pkiPublicationInfo", "id-regCtrl-pkiPublicationInfo", + NID_id_regCtrl_pkiPublicationInfo, 9, &kObjectData[2331], 0}, + {"id-regCtrl-pkiArchiveOptions", "id-regCtrl-pkiArchiveOptions", + NID_id_regCtrl_pkiArchiveOptions, 9, &kObjectData[2340], 0}, + {"id-regCtrl-oldCertID", "id-regCtrl-oldCertID", NID_id_regCtrl_oldCertID, + 9, &kObjectData[2349], 0}, + {"id-regCtrl-protocolEncrKey", "id-regCtrl-protocolEncrKey", + NID_id_regCtrl_protocolEncrKey, 9, &kObjectData[2358], 0}, + {"id-regInfo-utf8Pairs", "id-regInfo-utf8Pairs", NID_id_regInfo_utf8Pairs, + 9, &kObjectData[2367], 0}, + {"id-regInfo-certReq", "id-regInfo-certReq", NID_id_regInfo_certReq, 9, + &kObjectData[2376], 0}, + {"id-alg-des40", "id-alg-des40", NID_id_alg_des40, 8, &kObjectData[2385], + 0}, + {"id-alg-noSignature", "id-alg-noSignature", NID_id_alg_noSignature, 8, + &kObjectData[2393], 0}, + {"id-alg-dh-sig-hmac-sha1", "id-alg-dh-sig-hmac-sha1", + NID_id_alg_dh_sig_hmac_sha1, 8, &kObjectData[2401], 0}, + {"id-alg-dh-pop", "id-alg-dh-pop", NID_id_alg_dh_pop, 8, &kObjectData[2409], + 0}, + {"id-cmc-statusInfo", "id-cmc-statusInfo", NID_id_cmc_statusInfo, 8, + &kObjectData[2417], 0}, + {"id-cmc-identification", "id-cmc-identification", + NID_id_cmc_identification, 8, &kObjectData[2425], 0}, + {"id-cmc-identityProof", "id-cmc-identityProof", NID_id_cmc_identityProof, + 8, &kObjectData[2433], 0}, + {"id-cmc-dataReturn", "id-cmc-dataReturn", NID_id_cmc_dataReturn, 8, + &kObjectData[2441], 0}, + {"id-cmc-transactionId", "id-cmc-transactionId", NID_id_cmc_transactionId, + 8, &kObjectData[2449], 0}, + {"id-cmc-senderNonce", "id-cmc-senderNonce", NID_id_cmc_senderNonce, 8, + &kObjectData[2457], 0}, + {"id-cmc-recipientNonce", "id-cmc-recipientNonce", + NID_id_cmc_recipientNonce, 8, &kObjectData[2465], 0}, + {"id-cmc-addExtensions", "id-cmc-addExtensions", NID_id_cmc_addExtensions, + 8, &kObjectData[2473], 0}, + {"id-cmc-encryptedPOP", "id-cmc-encryptedPOP", NID_id_cmc_encryptedPOP, 8, + &kObjectData[2481], 0}, + {"id-cmc-decryptedPOP", "id-cmc-decryptedPOP", NID_id_cmc_decryptedPOP, 8, + &kObjectData[2489], 0}, + {"id-cmc-lraPOPWitness", "id-cmc-lraPOPWitness", NID_id_cmc_lraPOPWitness, + 8, &kObjectData[2497], 0}, + {"id-cmc-getCert", "id-cmc-getCert", NID_id_cmc_getCert, 8, + &kObjectData[2505], 0}, + {"id-cmc-getCRL", "id-cmc-getCRL", NID_id_cmc_getCRL, 8, &kObjectData[2513], + 0}, + {"id-cmc-revokeRequest", "id-cmc-revokeRequest", NID_id_cmc_revokeRequest, + 8, &kObjectData[2521], 0}, + {"id-cmc-regInfo", "id-cmc-regInfo", NID_id_cmc_regInfo, 8, + &kObjectData[2529], 0}, + {"id-cmc-responseInfo", "id-cmc-responseInfo", NID_id_cmc_responseInfo, 8, + &kObjectData[2537], 0}, + {"id-cmc-queryPending", "id-cmc-queryPending", NID_id_cmc_queryPending, 8, + &kObjectData[2545], 0}, + {"id-cmc-popLinkRandom", "id-cmc-popLinkRandom", NID_id_cmc_popLinkRandom, + 8, &kObjectData[2553], 0}, + {"id-cmc-popLinkWitness", "id-cmc-popLinkWitness", + NID_id_cmc_popLinkWitness, 8, &kObjectData[2561], 0}, + {"id-cmc-confirmCertAcceptance", "id-cmc-confirmCertAcceptance", + NID_id_cmc_confirmCertAcceptance, 8, &kObjectData[2569], 0}, + {"id-on-personalData", "id-on-personalData", NID_id_on_personalData, 8, + &kObjectData[2577], 0}, + {"id-pda-dateOfBirth", "id-pda-dateOfBirth", NID_id_pda_dateOfBirth, 8, + &kObjectData[2585], 0}, + {"id-pda-placeOfBirth", "id-pda-placeOfBirth", NID_id_pda_placeOfBirth, 8, + &kObjectData[2593], 0}, + {NULL, NULL, NID_undef, 0, NULL, 0}, + {"id-pda-gender", "id-pda-gender", NID_id_pda_gender, 8, &kObjectData[2601], + 0}, + {"id-pda-countryOfCitizenship", "id-pda-countryOfCitizenship", + NID_id_pda_countryOfCitizenship, 8, &kObjectData[2609], 0}, + {"id-pda-countryOfResidence", "id-pda-countryOfResidence", + NID_id_pda_countryOfResidence, 8, &kObjectData[2617], 0}, + {"id-aca-authenticationInfo", "id-aca-authenticationInfo", + NID_id_aca_authenticationInfo, 8, &kObjectData[2625], 0}, + {"id-aca-accessIdentity", "id-aca-accessIdentity", + NID_id_aca_accessIdentity, 8, &kObjectData[2633], 0}, + {"id-aca-chargingIdentity", "id-aca-chargingIdentity", + NID_id_aca_chargingIdentity, 8, &kObjectData[2641], 0}, + {"id-aca-group", "id-aca-group", NID_id_aca_group, 8, &kObjectData[2649], + 0}, + {"id-aca-role", "id-aca-role", NID_id_aca_role, 8, &kObjectData[2657], 0}, + {"id-qcs-pkixQCSyntax-v1", "id-qcs-pkixQCSyntax-v1", + NID_id_qcs_pkixQCSyntax_v1, 8, &kObjectData[2665], 0}, + {"id-cct-crs", "id-cct-crs", NID_id_cct_crs, 8, &kObjectData[2673], 0}, + {"id-cct-PKIData", "id-cct-PKIData", NID_id_cct_PKIData, 8, + &kObjectData[2681], 0}, + {"id-cct-PKIResponse", "id-cct-PKIResponse", NID_id_cct_PKIResponse, 8, + &kObjectData[2689], 0}, + {"ad_timestamping", "AD Time Stamping", NID_ad_timeStamping, 8, + &kObjectData[2697], 0}, + {"AD_DVCS", "ad dvcs", NID_ad_dvcs, 8, &kObjectData[2705], 0}, + {"basicOCSPResponse", "Basic OCSP Response", NID_id_pkix_OCSP_basic, 9, + &kObjectData[2713], 0}, + {"Nonce", "OCSP Nonce", NID_id_pkix_OCSP_Nonce, 9, &kObjectData[2722], 0}, + {"CrlID", "OCSP CRL ID", NID_id_pkix_OCSP_CrlID, 9, &kObjectData[2731], 0}, + {"acceptableResponses", "Acceptable OCSP Responses", + NID_id_pkix_OCSP_acceptableResponses, 9, &kObjectData[2740], 0}, + {"noCheck", "OCSP No Check", NID_id_pkix_OCSP_noCheck, 9, + &kObjectData[2749], 0}, + {"archiveCutoff", "OCSP Archive Cutoff", NID_id_pkix_OCSP_archiveCutoff, 9, + &kObjectData[2758], 0}, + {"serviceLocator", "OCSP Service Locator", NID_id_pkix_OCSP_serviceLocator, + 9, &kObjectData[2767], 0}, + {"extendedStatus", "Extended OCSP Status", NID_id_pkix_OCSP_extendedStatus, + 9, &kObjectData[2776], 0}, + {"valid", "valid", NID_id_pkix_OCSP_valid, 9, &kObjectData[2785], 0}, + {"path", "path", NID_id_pkix_OCSP_path, 9, &kObjectData[2794], 0}, + {"trustRoot", "Trust Root", NID_id_pkix_OCSP_trustRoot, 9, + &kObjectData[2803], 0}, + {"algorithm", "algorithm", NID_algorithm, 4, &kObjectData[2812], 0}, + {"rsaSignature", "rsaSignature", NID_rsaSignature, 5, &kObjectData[2816], + 0}, + {"X500algorithms", "directory services - algorithms", NID_X500algorithms, 2, + &kObjectData[2821], 0}, + {"ORG", "org", NID_org, 1, &kObjectData[2823], 0}, + {"DOD", "dod", NID_dod, 2, &kObjectData[2824], 0}, + {"IANA", "iana", NID_iana, 3, &kObjectData[2826], 0}, + {"directory", "Directory", NID_Directory, 4, &kObjectData[2829], 0}, + {"mgmt", "Management", NID_Management, 4, &kObjectData[2833], 0}, + {"experimental", "Experimental", NID_Experimental, 4, &kObjectData[2837], + 0}, + {"private", "Private", NID_Private, 4, &kObjectData[2841], 0}, + {"security", "Security", NID_Security, 4, &kObjectData[2845], 0}, + {"snmpv2", "SNMPv2", NID_SNMPv2, 4, &kObjectData[2849], 0}, + {"Mail", "Mail", NID_Mail, 4, &kObjectData[2853], 0}, + {"enterprises", "Enterprises", NID_Enterprises, 5, &kObjectData[2857], 0}, + {"dcobject", "dcObject", NID_dcObject, 9, &kObjectData[2862], 0}, + {"DC", "domainComponent", NID_domainComponent, 10, &kObjectData[2871], 0}, + {"domain", "Domain", NID_Domain, 10, &kObjectData[2881], 0}, + {NULL, NULL, NID_undef, 0, NULL, 0}, + {"selected-attribute-types", "Selected Attribute Types", + NID_selected_attribute_types, 3, &kObjectData[2891], 0}, + {"clearance", "clearance", NID_clearance, 4, &kObjectData[2894], 0}, + {"RSA-MD4", "md4WithRSAEncryption", NID_md4WithRSAEncryption, 9, + &kObjectData[2898], 0}, + {"ac-proxying", "ac-proxying", NID_ac_proxying, 8, &kObjectData[2907], 0}, + {"subjectInfoAccess", "Subject Information Access", NID_sinfo_access, 8, + &kObjectData[2915], 0}, + {"id-aca-encAttrs", "id-aca-encAttrs", NID_id_aca_encAttrs, 8, + &kObjectData[2923], 0}, + {"role", "role", NID_role, 3, &kObjectData[2931], 0}, + {"policyConstraints", "X509v3 Policy Constraints", NID_policy_constraints, + 3, &kObjectData[2934], 0}, + {"targetInformation", "X509v3 AC Targeting", NID_target_information, 3, + &kObjectData[2937], 0}, + {"noRevAvail", "X509v3 No Revocation Available", NID_no_rev_avail, 3, + &kObjectData[2940], 0}, + {NULL, NULL, NID_undef, 0, NULL, 0}, + {"ansi-X9-62", "ANSI X9.62", NID_ansi_X9_62, 5, &kObjectData[2943], 0}, + {"prime-field", "prime-field", NID_X9_62_prime_field, 7, &kObjectData[2948], + 0}, + {"characteristic-two-field", "characteristic-two-field", + NID_X9_62_characteristic_two_field, 7, &kObjectData[2955], 0}, + {"id-ecPublicKey", "id-ecPublicKey", NID_X9_62_id_ecPublicKey, 7, + &kObjectData[2962], 0}, + {"prime192v1", "prime192v1", NID_X9_62_prime192v1, 8, &kObjectData[2969], + 0}, + {"prime192v2", "prime192v2", NID_X9_62_prime192v2, 8, &kObjectData[2977], + 0}, + {"prime192v3", "prime192v3", NID_X9_62_prime192v3, 8, &kObjectData[2985], + 0}, + {"prime239v1", "prime239v1", NID_X9_62_prime239v1, 8, &kObjectData[2993], + 0}, + {"prime239v2", "prime239v2", NID_X9_62_prime239v2, 8, &kObjectData[3001], + 0}, + {"prime239v3", "prime239v3", NID_X9_62_prime239v3, 8, &kObjectData[3009], + 0}, + {"prime256v1", "prime256v1", NID_X9_62_prime256v1, 8, &kObjectData[3017], + 0}, + {"ecdsa-with-SHA1", "ecdsa-with-SHA1", NID_ecdsa_with_SHA1, 7, + &kObjectData[3025], 0}, + {"CSPName", "Microsoft CSP Name", NID_ms_csp_name, 9, &kObjectData[3032], + 0}, + {"AES-128-ECB", "aes-128-ecb", NID_aes_128_ecb, 9, &kObjectData[3041], 0}, + {"AES-128-CBC", "aes-128-cbc", NID_aes_128_cbc, 9, &kObjectData[3050], 0}, + {"AES-128-OFB", "aes-128-ofb", NID_aes_128_ofb128, 9, &kObjectData[3059], + 0}, + {"AES-128-CFB", "aes-128-cfb", NID_aes_128_cfb128, 9, &kObjectData[3068], + 0}, + {"AES-192-ECB", "aes-192-ecb", NID_aes_192_ecb, 9, &kObjectData[3077], 0}, + {"AES-192-CBC", "aes-192-cbc", NID_aes_192_cbc, 9, &kObjectData[3086], 0}, + {"AES-192-OFB", "aes-192-ofb", NID_aes_192_ofb128, 9, &kObjectData[3095], + 0}, + {"AES-192-CFB", "aes-192-cfb", NID_aes_192_cfb128, 9, &kObjectData[3104], + 0}, + {"AES-256-ECB", "aes-256-ecb", NID_aes_256_ecb, 9, &kObjectData[3113], 0}, + {"AES-256-CBC", "aes-256-cbc", NID_aes_256_cbc, 9, &kObjectData[3122], 0}, + {"AES-256-OFB", "aes-256-ofb", NID_aes_256_ofb128, 9, &kObjectData[3131], + 0}, + {"AES-256-CFB", "aes-256-cfb", NID_aes_256_cfb128, 9, &kObjectData[3140], + 0}, + {"holdInstructionCode", "Hold Instruction Code", NID_hold_instruction_code, + 3, &kObjectData[3149], 0}, + {"holdInstructionNone", "Hold Instruction None", NID_hold_instruction_none, + 7, &kObjectData[3152], 0}, + {"holdInstructionCallIssuer", "Hold Instruction Call Issuer", + NID_hold_instruction_call_issuer, 7, &kObjectData[3159], 0}, + {"holdInstructionReject", "Hold Instruction Reject", + NID_hold_instruction_reject, 7, &kObjectData[3166], 0}, + {"data", "data", NID_data, 1, &kObjectData[3173], 0}, + {"pss", "pss", NID_pss, 3, &kObjectData[3174], 0}, + {"ucl", "ucl", NID_ucl, 7, &kObjectData[3177], 0}, + {"pilot", "pilot", NID_pilot, 8, &kObjectData[3184], 0}, + {"pilotAttributeType", "pilotAttributeType", NID_pilotAttributeType, 9, + &kObjectData[3192], 0}, + {"pilotAttributeSyntax", "pilotAttributeSyntax", NID_pilotAttributeSyntax, + 9, &kObjectData[3201], 0}, + {"pilotObjectClass", "pilotObjectClass", NID_pilotObjectClass, 9, + &kObjectData[3210], 0}, + {"pilotGroups", "pilotGroups", NID_pilotGroups, 9, &kObjectData[3219], 0}, + {"iA5StringSyntax", "iA5StringSyntax", NID_iA5StringSyntax, 10, + &kObjectData[3228], 0}, + {"caseIgnoreIA5StringSyntax", "caseIgnoreIA5StringSyntax", + NID_caseIgnoreIA5StringSyntax, 10, &kObjectData[3238], 0}, + {"pilotObject", "pilotObject", NID_pilotObject, 10, &kObjectData[3248], 0}, + {"pilotPerson", "pilotPerson", NID_pilotPerson, 10, &kObjectData[3258], 0}, + {"account", "account", NID_account, 10, &kObjectData[3268], 0}, + {"document", "document", NID_document, 10, &kObjectData[3278], 0}, + {"room", "room", NID_room, 10, &kObjectData[3288], 0}, + {"documentSeries", "documentSeries", NID_documentSeries, 10, + &kObjectData[3298], 0}, + {"rFC822localPart", "rFC822localPart", NID_rFC822localPart, 10, + &kObjectData[3308], 0}, + {"dNSDomain", "dNSDomain", NID_dNSDomain, 10, &kObjectData[3318], 0}, + {"domainRelatedObject", "domainRelatedObject", NID_domainRelatedObject, 10, + &kObjectData[3328], 0}, + {"friendlyCountry", "friendlyCountry", NID_friendlyCountry, 10, + &kObjectData[3338], 0}, + {"simpleSecurityObject", "simpleSecurityObject", NID_simpleSecurityObject, + 10, &kObjectData[3348], 0}, + {"pilotOrganization", "pilotOrganization", NID_pilotOrganization, 10, + &kObjectData[3358], 0}, + {"pilotDSA", "pilotDSA", NID_pilotDSA, 10, &kObjectData[3368], 0}, + {"qualityLabelledData", "qualityLabelledData", NID_qualityLabelledData, 10, + &kObjectData[3378], 0}, + {"UID", "userId", NID_userId, 10, &kObjectData[3388], 0}, + {"textEncodedORAddress", "textEncodedORAddress", NID_textEncodedORAddress, + 10, &kObjectData[3398], 0}, + {"mail", "rfc822Mailbox", NID_rfc822Mailbox, 10, &kObjectData[3408], 0}, + {"info", "info", NID_info, 10, &kObjectData[3418], 0}, + {"favouriteDrink", "favouriteDrink", NID_favouriteDrink, 10, + &kObjectData[3428], 0}, + {"roomNumber", "roomNumber", NID_roomNumber, 10, &kObjectData[3438], 0}, + {"photo", "photo", NID_photo, 10, &kObjectData[3448], 0}, + {"userClass", "userClass", NID_userClass, 10, &kObjectData[3458], 0}, + {"host", "host", NID_host, 10, &kObjectData[3468], 0}, + {"manager", "manager", NID_manager, 10, &kObjectData[3478], 0}, + {"documentIdentifier", "documentIdentifier", NID_documentIdentifier, 10, + &kObjectData[3488], 0}, + {"documentTitle", "documentTitle", NID_documentTitle, 10, + &kObjectData[3498], 0}, + {"documentVersion", "documentVersion", NID_documentVersion, 10, + &kObjectData[3508], 0}, + {"documentAuthor", "documentAuthor", NID_documentAuthor, 10, + &kObjectData[3518], 0}, + {"documentLocation", "documentLocation", NID_documentLocation, 10, + &kObjectData[3528], 0}, + {"homeTelephoneNumber", "homeTelephoneNumber", NID_homeTelephoneNumber, 10, + &kObjectData[3538], 0}, + {"secretary", "secretary", NID_secretary, 10, &kObjectData[3548], 0}, + {"otherMailbox", "otherMailbox", NID_otherMailbox, 10, &kObjectData[3558], + 0}, + {"lastModifiedTime", "lastModifiedTime", NID_lastModifiedTime, 10, + &kObjectData[3568], 0}, + {"lastModifiedBy", "lastModifiedBy", NID_lastModifiedBy, 10, + &kObjectData[3578], 0}, + {"aRecord", "aRecord", NID_aRecord, 10, &kObjectData[3588], 0}, + {"pilotAttributeType27", "pilotAttributeType27", NID_pilotAttributeType27, + 10, &kObjectData[3598], 0}, + {"mXRecord", "mXRecord", NID_mXRecord, 10, &kObjectData[3608], 0}, + {"nSRecord", "nSRecord", NID_nSRecord, 10, &kObjectData[3618], 0}, + {"sOARecord", "sOARecord", NID_sOARecord, 10, &kObjectData[3628], 0}, + {"cNAMERecord", "cNAMERecord", NID_cNAMERecord, 10, &kObjectData[3638], 0}, + {"associatedDomain", "associatedDomain", NID_associatedDomain, 10, + &kObjectData[3648], 0}, + {"associatedName", "associatedName", NID_associatedName, 10, + &kObjectData[3658], 0}, + {"homePostalAddress", "homePostalAddress", NID_homePostalAddress, 10, + &kObjectData[3668], 0}, + {"personalTitle", "personalTitle", NID_personalTitle, 10, + &kObjectData[3678], 0}, + {"mobileTelephoneNumber", "mobileTelephoneNumber", + NID_mobileTelephoneNumber, 10, &kObjectData[3688], 0}, + {"pagerTelephoneNumber", "pagerTelephoneNumber", NID_pagerTelephoneNumber, + 10, &kObjectData[3698], 0}, + {"friendlyCountryName", "friendlyCountryName", NID_friendlyCountryName, 10, + &kObjectData[3708], 0}, + {"organizationalStatus", "organizationalStatus", NID_organizationalStatus, + 10, &kObjectData[3718], 0}, + {"janetMailbox", "janetMailbox", NID_janetMailbox, 10, &kObjectData[3728], + 0}, + {"mailPreferenceOption", "mailPreferenceOption", NID_mailPreferenceOption, + 10, &kObjectData[3738], 0}, + {"buildingName", "buildingName", NID_buildingName, 10, &kObjectData[3748], + 0}, + {"dSAQuality", "dSAQuality", NID_dSAQuality, 10, &kObjectData[3758], 0}, + {"singleLevelQuality", "singleLevelQuality", NID_singleLevelQuality, 10, + &kObjectData[3768], 0}, + {"subtreeMinimumQuality", "subtreeMinimumQuality", + NID_subtreeMinimumQuality, 10, &kObjectData[3778], 0}, + {"subtreeMaximumQuality", "subtreeMaximumQuality", + NID_subtreeMaximumQuality, 10, &kObjectData[3788], 0}, + {"personalSignature", "personalSignature", NID_personalSignature, 10, + &kObjectData[3798], 0}, + {"dITRedirect", "dITRedirect", NID_dITRedirect, 10, &kObjectData[3808], 0}, + {"audio", "audio", NID_audio, 10, &kObjectData[3818], 0}, + {"documentPublisher", "documentPublisher", NID_documentPublisher, 10, + &kObjectData[3828], 0}, + {"x500UniqueIdentifier", "x500UniqueIdentifier", NID_x500UniqueIdentifier, + 3, &kObjectData[3838], 0}, + {"mime-mhs", "MIME MHS", NID_mime_mhs, 5, &kObjectData[3841], 0}, + {"mime-mhs-headings", "mime-mhs-headings", NID_mime_mhs_headings, 6, + &kObjectData[3846], 0}, + {"mime-mhs-bodies", "mime-mhs-bodies", NID_mime_mhs_bodies, 6, + &kObjectData[3852], 0}, + {"id-hex-partial-message", "id-hex-partial-message", + NID_id_hex_partial_message, 7, &kObjectData[3858], 0}, + {"id-hex-multipart-message", "id-hex-multipart-message", + NID_id_hex_multipart_message, 7, &kObjectData[3865], 0}, + {"generationQualifier", "generationQualifier", NID_generationQualifier, 3, + &kObjectData[3872], 0}, + {"pseudonym", "pseudonym", NID_pseudonym, 3, &kObjectData[3875], 0}, + {NULL, NULL, NID_undef, 0, NULL, 0}, + {"id-set", "Secure Electronic Transactions", NID_id_set, 2, + &kObjectData[3878], 0}, + {"set-ctype", "content types", NID_set_ctype, 3, &kObjectData[3880], 0}, + {"set-msgExt", "message extensions", NID_set_msgExt, 3, &kObjectData[3883], + 0}, + {"set-attr", "set-attr", NID_set_attr, 3, &kObjectData[3886], 0}, + {"set-policy", "set-policy", NID_set_policy, 3, &kObjectData[3889], 0}, + {"set-certExt", "certificate extensions", NID_set_certExt, 3, + &kObjectData[3892], 0}, + {"set-brand", "set-brand", NID_set_brand, 3, &kObjectData[3895], 0}, + {"setct-PANData", "setct-PANData", NID_setct_PANData, 4, &kObjectData[3898], + 0}, + {"setct-PANToken", "setct-PANToken", NID_setct_PANToken, 4, + &kObjectData[3902], 0}, + {"setct-PANOnly", "setct-PANOnly", NID_setct_PANOnly, 4, &kObjectData[3906], + 0}, + {"setct-OIData", "setct-OIData", NID_setct_OIData, 4, &kObjectData[3910], + 0}, + {"setct-PI", "setct-PI", NID_setct_PI, 4, &kObjectData[3914], 0}, + {"setct-PIData", "setct-PIData", NID_setct_PIData, 4, &kObjectData[3918], + 0}, + {"setct-PIDataUnsigned", "setct-PIDataUnsigned", NID_setct_PIDataUnsigned, + 4, &kObjectData[3922], 0}, + {"setct-HODInput", "setct-HODInput", NID_setct_HODInput, 4, + &kObjectData[3926], 0}, + {"setct-AuthResBaggage", "setct-AuthResBaggage", NID_setct_AuthResBaggage, + 4, &kObjectData[3930], 0}, + {"setct-AuthRevReqBaggage", "setct-AuthRevReqBaggage", + NID_setct_AuthRevReqBaggage, 4, &kObjectData[3934], 0}, + {"setct-AuthRevResBaggage", "setct-AuthRevResBaggage", + NID_setct_AuthRevResBaggage, 4, &kObjectData[3938], 0}, + {"setct-CapTokenSeq", "setct-CapTokenSeq", NID_setct_CapTokenSeq, 4, + &kObjectData[3942], 0}, + {"setct-PInitResData", "setct-PInitResData", NID_setct_PInitResData, 4, + &kObjectData[3946], 0}, + {"setct-PI-TBS", "setct-PI-TBS", NID_setct_PI_TBS, 4, &kObjectData[3950], + 0}, + {"setct-PResData", "setct-PResData", NID_setct_PResData, 4, + &kObjectData[3954], 0}, + {"setct-AuthReqTBS", "setct-AuthReqTBS", NID_setct_AuthReqTBS, 4, + &kObjectData[3958], 0}, + {"setct-AuthResTBS", "setct-AuthResTBS", NID_setct_AuthResTBS, 4, + &kObjectData[3962], 0}, + {"setct-AuthResTBSX", "setct-AuthResTBSX", NID_setct_AuthResTBSX, 4, + &kObjectData[3966], 0}, + {"setct-AuthTokenTBS", "setct-AuthTokenTBS", NID_setct_AuthTokenTBS, 4, + &kObjectData[3970], 0}, + {"setct-CapTokenData", "setct-CapTokenData", NID_setct_CapTokenData, 4, + &kObjectData[3974], 0}, + {"setct-CapTokenTBS", "setct-CapTokenTBS", NID_setct_CapTokenTBS, 4, + &kObjectData[3978], 0}, + {"setct-AcqCardCodeMsg", "setct-AcqCardCodeMsg", NID_setct_AcqCardCodeMsg, + 4, &kObjectData[3982], 0}, + {"setct-AuthRevReqTBS", "setct-AuthRevReqTBS", NID_setct_AuthRevReqTBS, 4, + &kObjectData[3986], 0}, + {"setct-AuthRevResData", "setct-AuthRevResData", NID_setct_AuthRevResData, + 4, &kObjectData[3990], 0}, + {"setct-AuthRevResTBS", "setct-AuthRevResTBS", NID_setct_AuthRevResTBS, 4, + &kObjectData[3994], 0}, + {"setct-CapReqTBS", "setct-CapReqTBS", NID_setct_CapReqTBS, 4, + &kObjectData[3998], 0}, + {"setct-CapReqTBSX", "setct-CapReqTBSX", NID_setct_CapReqTBSX, 4, + &kObjectData[4002], 0}, + {"setct-CapResData", "setct-CapResData", NID_setct_CapResData, 4, + &kObjectData[4006], 0}, + {"setct-CapRevReqTBS", "setct-CapRevReqTBS", NID_setct_CapRevReqTBS, 4, + &kObjectData[4010], 0}, + {"setct-CapRevReqTBSX", "setct-CapRevReqTBSX", NID_setct_CapRevReqTBSX, 4, + &kObjectData[4014], 0}, + {"setct-CapRevResData", "setct-CapRevResData", NID_setct_CapRevResData, 4, + &kObjectData[4018], 0}, + {"setct-CredReqTBS", "setct-CredReqTBS", NID_setct_CredReqTBS, 4, + &kObjectData[4022], 0}, + {"setct-CredReqTBSX", "setct-CredReqTBSX", NID_setct_CredReqTBSX, 4, + &kObjectData[4026], 0}, + {"setct-CredResData", "setct-CredResData", NID_setct_CredResData, 4, + &kObjectData[4030], 0}, + {"setct-CredRevReqTBS", "setct-CredRevReqTBS", NID_setct_CredRevReqTBS, 4, + &kObjectData[4034], 0}, + {"setct-CredRevReqTBSX", "setct-CredRevReqTBSX", NID_setct_CredRevReqTBSX, + 4, &kObjectData[4038], 0}, + {"setct-CredRevResData", "setct-CredRevResData", NID_setct_CredRevResData, + 4, &kObjectData[4042], 0}, + {"setct-PCertReqData", "setct-PCertReqData", NID_setct_PCertReqData, 4, + &kObjectData[4046], 0}, + {"setct-PCertResTBS", "setct-PCertResTBS", NID_setct_PCertResTBS, 4, + &kObjectData[4050], 0}, + {"setct-BatchAdminReqData", "setct-BatchAdminReqData", + NID_setct_BatchAdminReqData, 4, &kObjectData[4054], 0}, + {"setct-BatchAdminResData", "setct-BatchAdminResData", + NID_setct_BatchAdminResData, 4, &kObjectData[4058], 0}, + {"setct-CardCInitResTBS", "setct-CardCInitResTBS", + NID_setct_CardCInitResTBS, 4, &kObjectData[4062], 0}, + {"setct-MeAqCInitResTBS", "setct-MeAqCInitResTBS", + NID_setct_MeAqCInitResTBS, 4, &kObjectData[4066], 0}, + {"setct-RegFormResTBS", "setct-RegFormResTBS", NID_setct_RegFormResTBS, 4, + &kObjectData[4070], 0}, + {"setct-CertReqData", "setct-CertReqData", NID_setct_CertReqData, 4, + &kObjectData[4074], 0}, + {"setct-CertReqTBS", "setct-CertReqTBS", NID_setct_CertReqTBS, 4, + &kObjectData[4078], 0}, + {"setct-CertResData", "setct-CertResData", NID_setct_CertResData, 4, + &kObjectData[4082], 0}, + {"setct-CertInqReqTBS", "setct-CertInqReqTBS", NID_setct_CertInqReqTBS, 4, + &kObjectData[4086], 0}, + {"setct-ErrorTBS", "setct-ErrorTBS", NID_setct_ErrorTBS, 4, + &kObjectData[4090], 0}, + {"setct-PIDualSignedTBE", "setct-PIDualSignedTBE", + NID_setct_PIDualSignedTBE, 4, &kObjectData[4094], 0}, + {"setct-PIUnsignedTBE", "setct-PIUnsignedTBE", NID_setct_PIUnsignedTBE, 4, + &kObjectData[4098], 0}, + {"setct-AuthReqTBE", "setct-AuthReqTBE", NID_setct_AuthReqTBE, 4, + &kObjectData[4102], 0}, + {"setct-AuthResTBE", "setct-AuthResTBE", NID_setct_AuthResTBE, 4, + &kObjectData[4106], 0}, + {"setct-AuthResTBEX", "setct-AuthResTBEX", NID_setct_AuthResTBEX, 4, + &kObjectData[4110], 0}, + {"setct-AuthTokenTBE", "setct-AuthTokenTBE", NID_setct_AuthTokenTBE, 4, + &kObjectData[4114], 0}, + {"setct-CapTokenTBE", "setct-CapTokenTBE", NID_setct_CapTokenTBE, 4, + &kObjectData[4118], 0}, + {"setct-CapTokenTBEX", "setct-CapTokenTBEX", NID_setct_CapTokenTBEX, 4, + &kObjectData[4122], 0}, + {"setct-AcqCardCodeMsgTBE", "setct-AcqCardCodeMsgTBE", + NID_setct_AcqCardCodeMsgTBE, 4, &kObjectData[4126], 0}, + {"setct-AuthRevReqTBE", "setct-AuthRevReqTBE", NID_setct_AuthRevReqTBE, 4, + &kObjectData[4130], 0}, + {"setct-AuthRevResTBE", "setct-AuthRevResTBE", NID_setct_AuthRevResTBE, 4, + &kObjectData[4134], 0}, + {"setct-AuthRevResTBEB", "setct-AuthRevResTBEB", NID_setct_AuthRevResTBEB, + 4, &kObjectData[4138], 0}, + {"setct-CapReqTBE", "setct-CapReqTBE", NID_setct_CapReqTBE, 4, + &kObjectData[4142], 0}, + {"setct-CapReqTBEX", "setct-CapReqTBEX", NID_setct_CapReqTBEX, 4, + &kObjectData[4146], 0}, + {"setct-CapResTBE", "setct-CapResTBE", NID_setct_CapResTBE, 4, + &kObjectData[4150], 0}, + {"setct-CapRevReqTBE", "setct-CapRevReqTBE", NID_setct_CapRevReqTBE, 4, + &kObjectData[4154], 0}, + {"setct-CapRevReqTBEX", "setct-CapRevReqTBEX", NID_setct_CapRevReqTBEX, 4, + &kObjectData[4158], 0}, + {"setct-CapRevResTBE", "setct-CapRevResTBE", NID_setct_CapRevResTBE, 4, + &kObjectData[4162], 0}, + {"setct-CredReqTBE", "setct-CredReqTBE", NID_setct_CredReqTBE, 4, + &kObjectData[4166], 0}, + {"setct-CredReqTBEX", "setct-CredReqTBEX", NID_setct_CredReqTBEX, 4, + &kObjectData[4170], 0}, + {"setct-CredResTBE", "setct-CredResTBE", NID_setct_CredResTBE, 4, + &kObjectData[4174], 0}, + {"setct-CredRevReqTBE", "setct-CredRevReqTBE", NID_setct_CredRevReqTBE, 4, + &kObjectData[4178], 0}, + {"setct-CredRevReqTBEX", "setct-CredRevReqTBEX", NID_setct_CredRevReqTBEX, + 4, &kObjectData[4182], 0}, + {"setct-CredRevResTBE", "setct-CredRevResTBE", NID_setct_CredRevResTBE, 4, + &kObjectData[4186], 0}, + {"setct-BatchAdminReqTBE", "setct-BatchAdminReqTBE", + NID_setct_BatchAdminReqTBE, 4, &kObjectData[4190], 0}, + {"setct-BatchAdminResTBE", "setct-BatchAdminResTBE", + NID_setct_BatchAdminResTBE, 4, &kObjectData[4194], 0}, + {"setct-RegFormReqTBE", "setct-RegFormReqTBE", NID_setct_RegFormReqTBE, 4, + &kObjectData[4198], 0}, + {"setct-CertReqTBE", "setct-CertReqTBE", NID_setct_CertReqTBE, 4, + &kObjectData[4202], 0}, + {"setct-CertReqTBEX", "setct-CertReqTBEX", NID_setct_CertReqTBEX, 4, + &kObjectData[4206], 0}, + {"setct-CertResTBE", "setct-CertResTBE", NID_setct_CertResTBE, 4, + &kObjectData[4210], 0}, + {"setct-CRLNotificationTBS", "setct-CRLNotificationTBS", + NID_setct_CRLNotificationTBS, 4, &kObjectData[4214], 0}, + {"setct-CRLNotificationResTBS", "setct-CRLNotificationResTBS", + NID_setct_CRLNotificationResTBS, 4, &kObjectData[4218], 0}, + {"setct-BCIDistributionTBS", "setct-BCIDistributionTBS", + NID_setct_BCIDistributionTBS, 4, &kObjectData[4222], 0}, + {"setext-genCrypt", "generic cryptogram", NID_setext_genCrypt, 4, + &kObjectData[4226], 0}, + {"setext-miAuth", "merchant initiated auth", NID_setext_miAuth, 4, + &kObjectData[4230], 0}, + {"setext-pinSecure", "setext-pinSecure", NID_setext_pinSecure, 4, + &kObjectData[4234], 0}, + {"setext-pinAny", "setext-pinAny", NID_setext_pinAny, 4, &kObjectData[4238], + 0}, + {"setext-track2", "setext-track2", NID_setext_track2, 4, &kObjectData[4242], + 0}, + {"setext-cv", "additional verification", NID_setext_cv, 4, + &kObjectData[4246], 0}, + {"set-policy-root", "set-policy-root", NID_set_policy_root, 4, + &kObjectData[4250], 0}, + {"setCext-hashedRoot", "setCext-hashedRoot", NID_setCext_hashedRoot, 4, + &kObjectData[4254], 0}, + {"setCext-certType", "setCext-certType", NID_setCext_certType, 4, + &kObjectData[4258], 0}, + {"setCext-merchData", "setCext-merchData", NID_setCext_merchData, 4, + &kObjectData[4262], 0}, + {"setCext-cCertRequired", "setCext-cCertRequired", + NID_setCext_cCertRequired, 4, &kObjectData[4266], 0}, + {"setCext-tunneling", "setCext-tunneling", NID_setCext_tunneling, 4, + &kObjectData[4270], 0}, + {"setCext-setExt", "setCext-setExt", NID_setCext_setExt, 4, + &kObjectData[4274], 0}, + {"setCext-setQualf", "setCext-setQualf", NID_setCext_setQualf, 4, + &kObjectData[4278], 0}, + {"setCext-PGWYcapabilities", "setCext-PGWYcapabilities", + NID_setCext_PGWYcapabilities, 4, &kObjectData[4282], 0}, + {"setCext-TokenIdentifier", "setCext-TokenIdentifier", + NID_setCext_TokenIdentifier, 4, &kObjectData[4286], 0}, + {"setCext-Track2Data", "setCext-Track2Data", NID_setCext_Track2Data, 4, + &kObjectData[4290], 0}, + {"setCext-TokenType", "setCext-TokenType", NID_setCext_TokenType, 4, + &kObjectData[4294], 0}, + {"setCext-IssuerCapabilities", "setCext-IssuerCapabilities", + NID_setCext_IssuerCapabilities, 4, &kObjectData[4298], 0}, + {"setAttr-Cert", "setAttr-Cert", NID_setAttr_Cert, 4, &kObjectData[4302], + 0}, + {"setAttr-PGWYcap", "payment gateway capabilities", NID_setAttr_PGWYcap, 4, + &kObjectData[4306], 0}, + {"setAttr-TokenType", "setAttr-TokenType", NID_setAttr_TokenType, 4, + &kObjectData[4310], 0}, + {"setAttr-IssCap", "issuer capabilities", NID_setAttr_IssCap, 4, + &kObjectData[4314], 0}, + {"set-rootKeyThumb", "set-rootKeyThumb", NID_set_rootKeyThumb, 5, + &kObjectData[4318], 0}, + {"set-addPolicy", "set-addPolicy", NID_set_addPolicy, 5, &kObjectData[4323], + 0}, + {"setAttr-Token-EMV", "setAttr-Token-EMV", NID_setAttr_Token_EMV, 5, + &kObjectData[4328], 0}, + {"setAttr-Token-B0Prime", "setAttr-Token-B0Prime", + NID_setAttr_Token_B0Prime, 5, &kObjectData[4333], 0}, + {"setAttr-IssCap-CVM", "setAttr-IssCap-CVM", NID_setAttr_IssCap_CVM, 5, + &kObjectData[4338], 0}, + {"setAttr-IssCap-T2", "setAttr-IssCap-T2", NID_setAttr_IssCap_T2, 5, + &kObjectData[4343], 0}, + {"setAttr-IssCap-Sig", "setAttr-IssCap-Sig", NID_setAttr_IssCap_Sig, 5, + &kObjectData[4348], 0}, + {"setAttr-GenCryptgrm", "generate cryptogram", NID_setAttr_GenCryptgrm, 6, + &kObjectData[4353], 0}, + {"setAttr-T2Enc", "encrypted track 2", NID_setAttr_T2Enc, 6, + &kObjectData[4359], 0}, + {"setAttr-T2cleartxt", "cleartext track 2", NID_setAttr_T2cleartxt, 6, + &kObjectData[4365], 0}, + {"setAttr-TokICCsig", "ICC or token signature", NID_setAttr_TokICCsig, 6, + &kObjectData[4371], 0}, + {"setAttr-SecDevSig", "secure device signature", NID_setAttr_SecDevSig, 6, + &kObjectData[4377], 0}, + {"set-brand-IATA-ATA", "set-brand-IATA-ATA", NID_set_brand_IATA_ATA, 4, + &kObjectData[4383], 0}, + {"set-brand-Diners", "set-brand-Diners", NID_set_brand_Diners, 4, + &kObjectData[4387], 0}, + {"set-brand-AmericanExpress", "set-brand-AmericanExpress", + NID_set_brand_AmericanExpress, 4, &kObjectData[4391], 0}, + {"set-brand-JCB", "set-brand-JCB", NID_set_brand_JCB, 4, &kObjectData[4395], + 0}, + {"set-brand-Visa", "set-brand-Visa", NID_set_brand_Visa, 4, + &kObjectData[4399], 0}, + {"set-brand-MasterCard", "set-brand-MasterCard", NID_set_brand_MasterCard, + 4, &kObjectData[4403], 0}, + {"set-brand-Novus", "set-brand-Novus", NID_set_brand_Novus, 5, + &kObjectData[4407], 0}, + {"DES-CDMF", "des-cdmf", NID_des_cdmf, 8, &kObjectData[4412], 0}, + {"rsaOAEPEncryptionSET", "rsaOAEPEncryptionSET", NID_rsaOAEPEncryptionSET, + 9, &kObjectData[4420], 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, &kObjectData[4429], 0}, + {"msSmartcardLogin", "Microsoft Smartcardlogin", NID_ms_smartcard_login, 10, + &kObjectData[4430], 0}, + {"msUPN", "Microsoft Universal Principal Name", NID_ms_upn, 10, + &kObjectData[4440], 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, &kObjectData[4450], 0}, + {"postalCode", "postalCode", NID_postalCode, 3, &kObjectData[4453], 0}, + {"id-ppl", "id-ppl", NID_id_ppl, 7, &kObjectData[4456], 0}, + {"proxyCertInfo", "Proxy Certificate Information", NID_proxyCertInfo, 8, + &kObjectData[4463], 0}, + {"id-ppl-anyLanguage", "Any language", NID_id_ppl_anyLanguage, 8, + &kObjectData[4471], 0}, + {"id-ppl-inheritAll", "Inherit all", NID_id_ppl_inheritAll, 8, + &kObjectData[4479], 0}, + {"nameConstraints", "X509v3 Name Constraints", NID_name_constraints, 3, + &kObjectData[4487], 0}, + {"id-ppl-independent", "Independent", NID_Independent, 8, + &kObjectData[4490], 0}, + {"RSA-SHA256", "sha256WithRSAEncryption", NID_sha256WithRSAEncryption, 9, + &kObjectData[4498], 0}, + {"RSA-SHA384", "sha384WithRSAEncryption", NID_sha384WithRSAEncryption, 9, + &kObjectData[4507], 0}, + {"RSA-SHA512", "sha512WithRSAEncryption", NID_sha512WithRSAEncryption, 9, + &kObjectData[4516], 0}, + {"RSA-SHA224", "sha224WithRSAEncryption", NID_sha224WithRSAEncryption, 9, + &kObjectData[4525], 0}, + {"SHA256", "sha256", NID_sha256, 9, &kObjectData[4534], 0}, + {"SHA384", "sha384", NID_sha384, 9, &kObjectData[4543], 0}, + {"SHA512", "sha512", NID_sha512, 9, &kObjectData[4552], 0}, + {"SHA224", "sha224", NID_sha224, 9, &kObjectData[4561], 0}, + {"identified-organization", "identified-organization", + NID_identified_organization, 1, &kObjectData[4570], 0}, + {"certicom-arc", "certicom-arc", NID_certicom_arc, 3, &kObjectData[4571], + 0}, + {"wap", "wap", NID_wap, 2, &kObjectData[4574], 0}, + {"wap-wsg", "wap-wsg", NID_wap_wsg, 3, &kObjectData[4576], 0}, + {"id-characteristic-two-basis", "id-characteristic-two-basis", + NID_X9_62_id_characteristic_two_basis, 8, &kObjectData[4579], 0}, + {"onBasis", "onBasis", NID_X9_62_onBasis, 9, &kObjectData[4587], 0}, + {"tpBasis", "tpBasis", NID_X9_62_tpBasis, 9, &kObjectData[4596], 0}, + {"ppBasis", "ppBasis", NID_X9_62_ppBasis, 9, &kObjectData[4605], 0}, + {"c2pnb163v1", "c2pnb163v1", NID_X9_62_c2pnb163v1, 8, &kObjectData[4614], + 0}, + {"c2pnb163v2", "c2pnb163v2", NID_X9_62_c2pnb163v2, 8, &kObjectData[4622], + 0}, + {"c2pnb163v3", "c2pnb163v3", NID_X9_62_c2pnb163v3, 8, &kObjectData[4630], + 0}, + {"c2pnb176v1", "c2pnb176v1", NID_X9_62_c2pnb176v1, 8, &kObjectData[4638], + 0}, + {"c2tnb191v1", "c2tnb191v1", NID_X9_62_c2tnb191v1, 8, &kObjectData[4646], + 0}, + {"c2tnb191v2", "c2tnb191v2", NID_X9_62_c2tnb191v2, 8, &kObjectData[4654], + 0}, + {"c2tnb191v3", "c2tnb191v3", NID_X9_62_c2tnb191v3, 8, &kObjectData[4662], + 0}, + {"c2onb191v4", "c2onb191v4", NID_X9_62_c2onb191v4, 8, &kObjectData[4670], + 0}, + {"c2onb191v5", "c2onb191v5", NID_X9_62_c2onb191v5, 8, &kObjectData[4678], + 0}, + {"c2pnb208w1", "c2pnb208w1", NID_X9_62_c2pnb208w1, 8, &kObjectData[4686], + 0}, + {"c2tnb239v1", "c2tnb239v1", NID_X9_62_c2tnb239v1, 8, &kObjectData[4694], + 0}, + {"c2tnb239v2", "c2tnb239v2", NID_X9_62_c2tnb239v2, 8, &kObjectData[4702], + 0}, + {"c2tnb239v3", "c2tnb239v3", NID_X9_62_c2tnb239v3, 8, &kObjectData[4710], + 0}, + {"c2onb239v4", "c2onb239v4", NID_X9_62_c2onb239v4, 8, &kObjectData[4718], + 0}, + {"c2onb239v5", "c2onb239v5", NID_X9_62_c2onb239v5, 8, &kObjectData[4726], + 0}, + {"c2pnb272w1", "c2pnb272w1", NID_X9_62_c2pnb272w1, 8, &kObjectData[4734], + 0}, + {"c2pnb304w1", "c2pnb304w1", NID_X9_62_c2pnb304w1, 8, &kObjectData[4742], + 0}, + {"c2tnb359v1", "c2tnb359v1", NID_X9_62_c2tnb359v1, 8, &kObjectData[4750], + 0}, + {"c2pnb368w1", "c2pnb368w1", NID_X9_62_c2pnb368w1, 8, &kObjectData[4758], + 0}, + {"c2tnb431r1", "c2tnb431r1", NID_X9_62_c2tnb431r1, 8, &kObjectData[4766], + 0}, + {"secp112r1", "secp112r1", NID_secp112r1, 5, &kObjectData[4774], 0}, + {"secp112r2", "secp112r2", NID_secp112r2, 5, &kObjectData[4779], 0}, + {"secp128r1", "secp128r1", NID_secp128r1, 5, &kObjectData[4784], 0}, + {"secp128r2", "secp128r2", NID_secp128r2, 5, &kObjectData[4789], 0}, + {"secp160k1", "secp160k1", NID_secp160k1, 5, &kObjectData[4794], 0}, + {"secp160r1", "secp160r1", NID_secp160r1, 5, &kObjectData[4799], 0}, + {"secp160r2", "secp160r2", NID_secp160r2, 5, &kObjectData[4804], 0}, + {"secp192k1", "secp192k1", NID_secp192k1, 5, &kObjectData[4809], 0}, + {"secp224k1", "secp224k1", NID_secp224k1, 5, &kObjectData[4814], 0}, + {"secp224r1", "secp224r1", NID_secp224r1, 5, &kObjectData[4819], 0}, + {"secp256k1", "secp256k1", NID_secp256k1, 5, &kObjectData[4824], 0}, + {"secp384r1", "secp384r1", NID_secp384r1, 5, &kObjectData[4829], 0}, + {"secp521r1", "secp521r1", NID_secp521r1, 5, &kObjectData[4834], 0}, + {"sect113r1", "sect113r1", NID_sect113r1, 5, &kObjectData[4839], 0}, + {"sect113r2", "sect113r2", NID_sect113r2, 5, &kObjectData[4844], 0}, + {"sect131r1", "sect131r1", NID_sect131r1, 5, &kObjectData[4849], 0}, + {"sect131r2", "sect131r2", NID_sect131r2, 5, &kObjectData[4854], 0}, + {"sect163k1", "sect163k1", NID_sect163k1, 5, &kObjectData[4859], 0}, + {"sect163r1", "sect163r1", NID_sect163r1, 5, &kObjectData[4864], 0}, + {"sect163r2", "sect163r2", NID_sect163r2, 5, &kObjectData[4869], 0}, + {"sect193r1", "sect193r1", NID_sect193r1, 5, &kObjectData[4874], 0}, + {"sect193r2", "sect193r2", NID_sect193r2, 5, &kObjectData[4879], 0}, + {"sect233k1", "sect233k1", NID_sect233k1, 5, &kObjectData[4884], 0}, + {"sect233r1", "sect233r1", NID_sect233r1, 5, &kObjectData[4889], 0}, + {"sect239k1", "sect239k1", NID_sect239k1, 5, &kObjectData[4894], 0}, + {"sect283k1", "sect283k1", NID_sect283k1, 5, &kObjectData[4899], 0}, + {"sect283r1", "sect283r1", NID_sect283r1, 5, &kObjectData[4904], 0}, + {"sect409k1", "sect409k1", NID_sect409k1, 5, &kObjectData[4909], 0}, + {"sect409r1", "sect409r1", NID_sect409r1, 5, &kObjectData[4914], 0}, + {"sect571k1", "sect571k1", NID_sect571k1, 5, &kObjectData[4919], 0}, + {"sect571r1", "sect571r1", NID_sect571r1, 5, &kObjectData[4924], 0}, + {"wap-wsg-idm-ecid-wtls1", "wap-wsg-idm-ecid-wtls1", + NID_wap_wsg_idm_ecid_wtls1, 5, &kObjectData[4929], 0}, + {"wap-wsg-idm-ecid-wtls3", "wap-wsg-idm-ecid-wtls3", + NID_wap_wsg_idm_ecid_wtls3, 5, &kObjectData[4934], 0}, + {"wap-wsg-idm-ecid-wtls4", "wap-wsg-idm-ecid-wtls4", + NID_wap_wsg_idm_ecid_wtls4, 5, &kObjectData[4939], 0}, + {"wap-wsg-idm-ecid-wtls5", "wap-wsg-idm-ecid-wtls5", + NID_wap_wsg_idm_ecid_wtls5, 5, &kObjectData[4944], 0}, + {"wap-wsg-idm-ecid-wtls6", "wap-wsg-idm-ecid-wtls6", + NID_wap_wsg_idm_ecid_wtls6, 5, &kObjectData[4949], 0}, + {"wap-wsg-idm-ecid-wtls7", "wap-wsg-idm-ecid-wtls7", + NID_wap_wsg_idm_ecid_wtls7, 5, &kObjectData[4954], 0}, + {"wap-wsg-idm-ecid-wtls8", "wap-wsg-idm-ecid-wtls8", + NID_wap_wsg_idm_ecid_wtls8, 5, &kObjectData[4959], 0}, + {"wap-wsg-idm-ecid-wtls9", "wap-wsg-idm-ecid-wtls9", + NID_wap_wsg_idm_ecid_wtls9, 5, &kObjectData[4964], 0}, + {"wap-wsg-idm-ecid-wtls10", "wap-wsg-idm-ecid-wtls10", + NID_wap_wsg_idm_ecid_wtls10, 5, &kObjectData[4969], 0}, + {"wap-wsg-idm-ecid-wtls11", "wap-wsg-idm-ecid-wtls11", + NID_wap_wsg_idm_ecid_wtls11, 5, &kObjectData[4974], 0}, + {"wap-wsg-idm-ecid-wtls12", "wap-wsg-idm-ecid-wtls12", + NID_wap_wsg_idm_ecid_wtls12, 5, &kObjectData[4979], 0}, + {"anyPolicy", "X509v3 Any Policy", NID_any_policy, 4, &kObjectData[4984], + 0}, + {"policyMappings", "X509v3 Policy Mappings", NID_policy_mappings, 3, + &kObjectData[4988], 0}, + {"inhibitAnyPolicy", "X509v3 Inhibit Any Policy", NID_inhibit_any_policy, 3, + &kObjectData[4991], 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, + &kObjectData[4994], 0}, + {"CAMELLIA-192-CBC", "camellia-192-cbc", NID_camellia_192_cbc, 11, + &kObjectData[5005], 0}, + {"CAMELLIA-256-CBC", "camellia-256-cbc", NID_camellia_256_cbc, 11, + &kObjectData[5016], 0}, + {"CAMELLIA-128-ECB", "camellia-128-ecb", NID_camellia_128_ecb, 8, + &kObjectData[5027], 0}, + {"CAMELLIA-192-ECB", "camellia-192-ecb", NID_camellia_192_ecb, 8, + &kObjectData[5035], 0}, + {"CAMELLIA-256-ECB", "camellia-256-ecb", NID_camellia_256_ecb, 8, + &kObjectData[5043], 0}, + {"CAMELLIA-128-CFB", "camellia-128-cfb", NID_camellia_128_cfb128, 8, + &kObjectData[5051], 0}, + {"CAMELLIA-192-CFB", "camellia-192-cfb", NID_camellia_192_cfb128, 8, + &kObjectData[5059], 0}, + {"CAMELLIA-256-CFB", "camellia-256-cfb", NID_camellia_256_cfb128, 8, + &kObjectData[5067], 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, + &kObjectData[5075], 0}, + {"CAMELLIA-192-OFB", "camellia-192-ofb", NID_camellia_192_ofb128, 8, + &kObjectData[5083], 0}, + {"CAMELLIA-256-OFB", "camellia-256-ofb", NID_camellia_256_ofb128, 8, + &kObjectData[5091], 0}, + {"subjectDirectoryAttributes", "X509v3 Subject Directory Attributes", + NID_subject_directory_attributes, 3, &kObjectData[5099], 0}, + {"issuingDistributionPoint", "X509v3 Issuing Distribution Point", + NID_issuing_distribution_point, 3, &kObjectData[5102], 0}, + {"certificateIssuer", "X509v3 Certificate Issuer", NID_certificate_issuer, + 3, &kObjectData[5105], 0}, + {NULL, NULL, NID_undef, 0, NULL, 0}, + {"KISA", "kisa", NID_kisa, 6, &kObjectData[5108], 0}, + {NULL, NULL, NID_undef, 0, NULL, 0}, + {NULL, NULL, NID_undef, 0, NULL, 0}, + {"SEED-ECB", "seed-ecb", NID_seed_ecb, 8, &kObjectData[5114], 0}, + {"SEED-CBC", "seed-cbc", NID_seed_cbc, 8, &kObjectData[5122], 0}, + {"SEED-OFB", "seed-ofb", NID_seed_ofb128, 8, &kObjectData[5130], 0}, + {"SEED-CFB", "seed-cfb", NID_seed_cfb128, 8, &kObjectData[5138], 0}, + {"HMAC-MD5", "hmac-md5", NID_hmac_md5, 8, &kObjectData[5146], 0}, + {"HMAC-SHA1", "hmac-sha1", NID_hmac_sha1, 8, &kObjectData[5154], 0}, + {"id-PasswordBasedMAC", "password based MAC", NID_id_PasswordBasedMAC, 9, + &kObjectData[5162], 0}, + {"id-DHBasedMac", "Diffie-Hellman based MAC", NID_id_DHBasedMac, 9, + &kObjectData[5171], 0}, + {"id-it-suppLangTags", "id-it-suppLangTags", NID_id_it_suppLangTags, 8, + &kObjectData[5180], 0}, + {"caRepository", "CA Repository", NID_caRepository, 8, &kObjectData[5188], + 0}, + {"id-smime-ct-compressedData", "id-smime-ct-compressedData", + NID_id_smime_ct_compressedData, 11, &kObjectData[5196], 0}, + {"id-ct-asciiTextWithCRLF", "id-ct-asciiTextWithCRLF", + NID_id_ct_asciiTextWithCRLF, 11, &kObjectData[5207], 0}, + {"id-aes128-wrap", "id-aes128-wrap", NID_id_aes128_wrap, 9, + &kObjectData[5218], 0}, + {"id-aes192-wrap", "id-aes192-wrap", NID_id_aes192_wrap, 9, + &kObjectData[5227], 0}, + {"id-aes256-wrap", "id-aes256-wrap", NID_id_aes256_wrap, 9, + &kObjectData[5236], 0}, + {"ecdsa-with-Recommended", "ecdsa-with-Recommended", + NID_ecdsa_with_Recommended, 7, &kObjectData[5245], 0}, + {"ecdsa-with-Specified", "ecdsa-with-Specified", NID_ecdsa_with_Specified, + 7, &kObjectData[5252], 0}, + {"ecdsa-with-SHA224", "ecdsa-with-SHA224", NID_ecdsa_with_SHA224, 8, + &kObjectData[5259], 0}, + {"ecdsa-with-SHA256", "ecdsa-with-SHA256", NID_ecdsa_with_SHA256, 8, + &kObjectData[5267], 0}, + {"ecdsa-with-SHA384", "ecdsa-with-SHA384", NID_ecdsa_with_SHA384, 8, + &kObjectData[5275], 0}, + {"ecdsa-with-SHA512", "ecdsa-with-SHA512", NID_ecdsa_with_SHA512, 8, + &kObjectData[5283], 0}, + {"hmacWithMD5", "hmacWithMD5", NID_hmacWithMD5, 8, &kObjectData[5291], 0}, + {"hmacWithSHA224", "hmacWithSHA224", NID_hmacWithSHA224, 8, + &kObjectData[5299], 0}, + {"hmacWithSHA256", "hmacWithSHA256", NID_hmacWithSHA256, 8, + &kObjectData[5307], 0}, + {"hmacWithSHA384", "hmacWithSHA384", NID_hmacWithSHA384, 8, + &kObjectData[5315], 0}, + {"hmacWithSHA512", "hmacWithSHA512", NID_hmacWithSHA512, 8, + &kObjectData[5323], 0}, + {"dsa_with_SHA224", "dsa_with_SHA224", NID_dsa_with_SHA224, 9, + &kObjectData[5331], 0}, + {"dsa_with_SHA256", "dsa_with_SHA256", NID_dsa_with_SHA256, 9, + &kObjectData[5340], 0}, + {"whirlpool", "whirlpool", NID_whirlpool, 6, &kObjectData[5349], 0}, + {"cryptopro", "cryptopro", NID_cryptopro, 5, &kObjectData[5355], 0}, + {"cryptocom", "cryptocom", NID_cryptocom, 5, &kObjectData[5360], 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, &kObjectData[5365], 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, &kObjectData[5371], 0}, + {"md_gost94", "GOST R 34.11-94", NID_id_GostR3411_94, 6, &kObjectData[5377], + 0}, + {"id-HMACGostR3411-94", "HMAC GOST 34.11-94", NID_id_HMACGostR3411_94, 6, + &kObjectData[5383], 0}, + {"gost2001", "GOST R 34.10-2001", NID_id_GostR3410_2001, 6, + &kObjectData[5389], 0}, + {"gost94", "GOST R 34.10-94", NID_id_GostR3410_94, 6, &kObjectData[5395], + 0}, + {"gost89", "GOST 28147-89", NID_id_Gost28147_89, 6, &kObjectData[5401], 0}, + {"gost89-cnt", "gost89-cnt", NID_gost89_cnt, 0, NULL, 0}, + {"gost-mac", "GOST 28147-89 MAC", NID_id_Gost28147_89_MAC, 6, + &kObjectData[5407], 0}, + {"prf-gostr3411-94", "GOST R 34.11-94 PRF", NID_id_GostR3411_94_prf, 6, + &kObjectData[5413], 0}, + {"id-GostR3410-2001DH", "GOST R 34.10-2001 DH", NID_id_GostR3410_2001DH, 6, + &kObjectData[5419], 0}, + {"id-GostR3410-94DH", "GOST R 34.10-94 DH", NID_id_GostR3410_94DH, 6, + &kObjectData[5425], 0}, + {"id-Gost28147-89-CryptoPro-KeyMeshing", + "id-Gost28147-89-CryptoPro-KeyMeshing", + NID_id_Gost28147_89_CryptoPro_KeyMeshing, 7, &kObjectData[5431], 0}, + {"id-Gost28147-89-None-KeyMeshing", "id-Gost28147-89-None-KeyMeshing", + NID_id_Gost28147_89_None_KeyMeshing, 7, &kObjectData[5438], 0}, + {"id-GostR3411-94-TestParamSet", "id-GostR3411-94-TestParamSet", + NID_id_GostR3411_94_TestParamSet, 7, &kObjectData[5445], 0}, + {"id-GostR3411-94-CryptoProParamSet", "id-GostR3411-94-CryptoProParamSet", + NID_id_GostR3411_94_CryptoProParamSet, 7, &kObjectData[5452], 0}, + {"id-Gost28147-89-TestParamSet", "id-Gost28147-89-TestParamSet", + NID_id_Gost28147_89_TestParamSet, 7, &kObjectData[5459], 0}, + {"id-Gost28147-89-CryptoPro-A-ParamSet", + "id-Gost28147-89-CryptoPro-A-ParamSet", + NID_id_Gost28147_89_CryptoPro_A_ParamSet, 7, &kObjectData[5466], 0}, + {"id-Gost28147-89-CryptoPro-B-ParamSet", + "id-Gost28147-89-CryptoPro-B-ParamSet", + NID_id_Gost28147_89_CryptoPro_B_ParamSet, 7, &kObjectData[5473], 0}, + {"id-Gost28147-89-CryptoPro-C-ParamSet", + "id-Gost28147-89-CryptoPro-C-ParamSet", + NID_id_Gost28147_89_CryptoPro_C_ParamSet, 7, &kObjectData[5480], 0}, + {"id-Gost28147-89-CryptoPro-D-ParamSet", + "id-Gost28147-89-CryptoPro-D-ParamSet", + NID_id_Gost28147_89_CryptoPro_D_ParamSet, 7, &kObjectData[5487], 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, &kObjectData[5494], + 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, &kObjectData[5501], + 0}, + {"id-Gost28147-89-CryptoPro-RIC-1-ParamSet", + "id-Gost28147-89-CryptoPro-RIC-1-ParamSet", + NID_id_Gost28147_89_CryptoPro_RIC_1_ParamSet, 7, &kObjectData[5508], 0}, + {"id-GostR3410-94-TestParamSet", "id-GostR3410-94-TestParamSet", + NID_id_GostR3410_94_TestParamSet, 7, &kObjectData[5515], 0}, + {"id-GostR3410-94-CryptoPro-A-ParamSet", + "id-GostR3410-94-CryptoPro-A-ParamSet", + NID_id_GostR3410_94_CryptoPro_A_ParamSet, 7, &kObjectData[5522], 0}, + {"id-GostR3410-94-CryptoPro-B-ParamSet", + "id-GostR3410-94-CryptoPro-B-ParamSet", + NID_id_GostR3410_94_CryptoPro_B_ParamSet, 7, &kObjectData[5529], 0}, + {"id-GostR3410-94-CryptoPro-C-ParamSet", + "id-GostR3410-94-CryptoPro-C-ParamSet", + NID_id_GostR3410_94_CryptoPro_C_ParamSet, 7, &kObjectData[5536], 0}, + {"id-GostR3410-94-CryptoPro-D-ParamSet", + "id-GostR3410-94-CryptoPro-D-ParamSet", + NID_id_GostR3410_94_CryptoPro_D_ParamSet, 7, &kObjectData[5543], 0}, + {"id-GostR3410-94-CryptoPro-XchA-ParamSet", + "id-GostR3410-94-CryptoPro-XchA-ParamSet", + NID_id_GostR3410_94_CryptoPro_XchA_ParamSet, 7, &kObjectData[5550], 0}, + {"id-GostR3410-94-CryptoPro-XchB-ParamSet", + "id-GostR3410-94-CryptoPro-XchB-ParamSet", + NID_id_GostR3410_94_CryptoPro_XchB_ParamSet, 7, &kObjectData[5557], 0}, + {"id-GostR3410-94-CryptoPro-XchC-ParamSet", + "id-GostR3410-94-CryptoPro-XchC-ParamSet", + NID_id_GostR3410_94_CryptoPro_XchC_ParamSet, 7, &kObjectData[5564], 0}, + {"id-GostR3410-2001-TestParamSet", "id-GostR3410-2001-TestParamSet", + NID_id_GostR3410_2001_TestParamSet, 7, &kObjectData[5571], 0}, + {"id-GostR3410-2001-CryptoPro-A-ParamSet", + "id-GostR3410-2001-CryptoPro-A-ParamSet", + NID_id_GostR3410_2001_CryptoPro_A_ParamSet, 7, &kObjectData[5578], 0}, + {"id-GostR3410-2001-CryptoPro-B-ParamSet", + "id-GostR3410-2001-CryptoPro-B-ParamSet", + NID_id_GostR3410_2001_CryptoPro_B_ParamSet, 7, &kObjectData[5585], 0}, + {"id-GostR3410-2001-CryptoPro-C-ParamSet", + "id-GostR3410-2001-CryptoPro-C-ParamSet", + NID_id_GostR3410_2001_CryptoPro_C_ParamSet, 7, &kObjectData[5592], 0}, + {"id-GostR3410-2001-CryptoPro-XchA-ParamSet", + "id-GostR3410-2001-CryptoPro-XchA-ParamSet", + NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet, 7, &kObjectData[5599], 0}, + {"id-GostR3410-2001-CryptoPro-XchB-ParamSet", + "id-GostR3410-2001-CryptoPro-XchB-ParamSet", + NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet, 7, &kObjectData[5606], 0}, + {"id-GostR3410-94-a", "id-GostR3410-94-a", NID_id_GostR3410_94_a, 7, + &kObjectData[5613], 0}, + {"id-GostR3410-94-aBis", "id-GostR3410-94-aBis", NID_id_GostR3410_94_aBis, + 7, &kObjectData[5620], 0}, + {"id-GostR3410-94-b", "id-GostR3410-94-b", NID_id_GostR3410_94_b, 7, + &kObjectData[5627], 0}, + {"id-GostR3410-94-bBis", "id-GostR3410-94-bBis", NID_id_GostR3410_94_bBis, + 7, &kObjectData[5634], 0}, + {"id-Gost28147-89-cc", "GOST 28147-89 Cryptocom ParamSet", + NID_id_Gost28147_89_cc, 8, &kObjectData[5641], 0}, + {"gost94cc", "GOST 34.10-94 Cryptocom", NID_id_GostR3410_94_cc, 8, + &kObjectData[5649], 0}, + {"gost2001cc", "GOST 34.10-2001 Cryptocom", NID_id_GostR3410_2001_cc, 8, + &kObjectData[5657], 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, &kObjectData[5665], 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, &kObjectData[5673], 0}, + {"id-GostR3410-2001-ParamSet-cc", + "GOST R 3410-2001 Parameter Set Cryptocom", + NID_id_GostR3410_2001_ParamSet_cc, 8, &kObjectData[5681], 0}, + {"HMAC", "hmac", NID_hmac, 0, NULL, 0}, + {"LocalKeySet", "Microsoft Local Key set", NID_LocalKeySet, 9, + &kObjectData[5689], 0}, + {"freshestCRL", "X509v3 Freshest CRL", NID_freshest_crl, 3, + &kObjectData[5698], 0}, + {"id-on-permanentIdentifier", "Permanent Identifier", + NID_id_on_permanentIdentifier, 8, &kObjectData[5701], 0}, + {"searchGuide", "searchGuide", NID_searchGuide, 3, &kObjectData[5709], 0}, + {"businessCategory", "businessCategory", NID_businessCategory, 3, + &kObjectData[5712], 0}, + {"postalAddress", "postalAddress", NID_postalAddress, 3, &kObjectData[5715], + 0}, + {"postOfficeBox", "postOfficeBox", NID_postOfficeBox, 3, &kObjectData[5718], + 0}, + {"physicalDeliveryOfficeName", "physicalDeliveryOfficeName", + NID_physicalDeliveryOfficeName, 3, &kObjectData[5721], 0}, + {"telephoneNumber", "telephoneNumber", NID_telephoneNumber, 3, + &kObjectData[5724], 0}, + {"telexNumber", "telexNumber", NID_telexNumber, 3, &kObjectData[5727], 0}, + {"teletexTerminalIdentifier", "teletexTerminalIdentifier", + NID_teletexTerminalIdentifier, 3, &kObjectData[5730], 0}, + {"facsimileTelephoneNumber", "facsimileTelephoneNumber", + NID_facsimileTelephoneNumber, 3, &kObjectData[5733], 0}, + {"x121Address", "x121Address", NID_x121Address, 3, &kObjectData[5736], 0}, + {"internationaliSDNNumber", "internationaliSDNNumber", + NID_internationaliSDNNumber, 3, &kObjectData[5739], 0}, + {"registeredAddress", "registeredAddress", NID_registeredAddress, 3, + &kObjectData[5742], 0}, + {"destinationIndicator", "destinationIndicator", NID_destinationIndicator, + 3, &kObjectData[5745], 0}, + {"preferredDeliveryMethod", "preferredDeliveryMethod", + NID_preferredDeliveryMethod, 3, &kObjectData[5748], 0}, + {"presentationAddress", "presentationAddress", NID_presentationAddress, 3, + &kObjectData[5751], 0}, + {"supportedApplicationContext", "supportedApplicationContext", + NID_supportedApplicationContext, 3, &kObjectData[5754], 0}, + {"member", "member", NID_member, 3, &kObjectData[5757], 0}, + {"owner", "owner", NID_owner, 3, &kObjectData[5760], 0}, + {"roleOccupant", "roleOccupant", NID_roleOccupant, 3, &kObjectData[5763], + 0}, + {"seeAlso", "seeAlso", NID_seeAlso, 3, &kObjectData[5766], 0}, + {"userPassword", "userPassword", NID_userPassword, 3, &kObjectData[5769], + 0}, + {"userCertificate", "userCertificate", NID_userCertificate, 3, + &kObjectData[5772], 0}, + {"cACertificate", "cACertificate", NID_cACertificate, 3, &kObjectData[5775], + 0}, + {"authorityRevocationList", "authorityRevocationList", + NID_authorityRevocationList, 3, &kObjectData[5778], 0}, + {"certificateRevocationList", "certificateRevocationList", + NID_certificateRevocationList, 3, &kObjectData[5781], 0}, + {"crossCertificatePair", "crossCertificatePair", NID_crossCertificatePair, + 3, &kObjectData[5784], 0}, + {"enhancedSearchGuide", "enhancedSearchGuide", NID_enhancedSearchGuide, 3, + &kObjectData[5787], 0}, + {"protocolInformation", "protocolInformation", NID_protocolInformation, 3, + &kObjectData[5790], 0}, + {"distinguishedName", "distinguishedName", NID_distinguishedName, 3, + &kObjectData[5793], 0}, + {"uniqueMember", "uniqueMember", NID_uniqueMember, 3, &kObjectData[5796], + 0}, + {"houseIdentifier", "houseIdentifier", NID_houseIdentifier, 3, + &kObjectData[5799], 0}, + {"supportedAlgorithms", "supportedAlgorithms", NID_supportedAlgorithms, 3, + &kObjectData[5802], 0}, + {"deltaRevocationList", "deltaRevocationList", NID_deltaRevocationList, 3, + &kObjectData[5805], 0}, + {"dmdName", "dmdName", NID_dmdName, 3, &kObjectData[5808], 0}, + {"id-alg-PWRI-KEK", "id-alg-PWRI-KEK", NID_id_alg_PWRI_KEK, 11, + &kObjectData[5811], 0}, + {"CMAC", "cmac", NID_cmac, 0, NULL, 0}, + {"id-aes128-GCM", "aes-128-gcm", NID_aes_128_gcm, 9, &kObjectData[5822], 0}, + {"id-aes128-CCM", "aes-128-ccm", NID_aes_128_ccm, 9, &kObjectData[5831], 0}, + {"id-aes128-wrap-pad", "id-aes128-wrap-pad", NID_id_aes128_wrap_pad, 9, + &kObjectData[5840], 0}, + {"id-aes192-GCM", "aes-192-gcm", NID_aes_192_gcm, 9, &kObjectData[5849], 0}, + {"id-aes192-CCM", "aes-192-ccm", NID_aes_192_ccm, 9, &kObjectData[5858], 0}, + {"id-aes192-wrap-pad", "id-aes192-wrap-pad", NID_id_aes192_wrap_pad, 9, + &kObjectData[5867], 0}, + {"id-aes256-GCM", "aes-256-gcm", NID_aes_256_gcm, 9, &kObjectData[5876], 0}, + {"id-aes256-CCM", "aes-256-ccm", NID_aes_256_ccm, 9, &kObjectData[5885], 0}, + {"id-aes256-wrap-pad", "id-aes256-wrap-pad", NID_id_aes256_wrap_pad, 9, + &kObjectData[5894], 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, + &kObjectData[5903], 0}, + {"id-camellia192-wrap", "id-camellia192-wrap", NID_id_camellia192_wrap, 11, + &kObjectData[5914], 0}, + {"id-camellia256-wrap", "id-camellia256-wrap", NID_id_camellia256_wrap, 11, + &kObjectData[5925], 0}, + {"anyExtendedKeyUsage", "Any Extended Key Usage", NID_anyExtendedKeyUsage, + 4, &kObjectData[5936], 0}, + {"MGF1", "mgf1", NID_mgf1, 9, &kObjectData[5940], 0}, + {"RSASSA-PSS", "rsassaPss", NID_rsassaPss, 9, &kObjectData[5949], 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, &kObjectData[5958], 0}, + {"dhpublicnumber", "X9.42 DH", NID_dhpublicnumber, 7, &kObjectData[5967], + 0}, + {"brainpoolP160r1", "brainpoolP160r1", NID_brainpoolP160r1, 9, + &kObjectData[5974], 0}, + {"brainpoolP160t1", "brainpoolP160t1", NID_brainpoolP160t1, 9, + &kObjectData[5983], 0}, + {"brainpoolP192r1", "brainpoolP192r1", NID_brainpoolP192r1, 9, + &kObjectData[5992], 0}, + {"brainpoolP192t1", "brainpoolP192t1", NID_brainpoolP192t1, 9, + &kObjectData[6001], 0}, + {"brainpoolP224r1", "brainpoolP224r1", NID_brainpoolP224r1, 9, + &kObjectData[6010], 0}, + {"brainpoolP224t1", "brainpoolP224t1", NID_brainpoolP224t1, 9, + &kObjectData[6019], 0}, + {"brainpoolP256r1", "brainpoolP256r1", NID_brainpoolP256r1, 9, + &kObjectData[6028], 0}, + {"brainpoolP256t1", "brainpoolP256t1", NID_brainpoolP256t1, 9, + &kObjectData[6037], 0}, + {"brainpoolP320r1", "brainpoolP320r1", NID_brainpoolP320r1, 9, + &kObjectData[6046], 0}, + {"brainpoolP320t1", "brainpoolP320t1", NID_brainpoolP320t1, 9, + &kObjectData[6055], 0}, + {"brainpoolP384r1", "brainpoolP384r1", NID_brainpoolP384r1, 9, + &kObjectData[6064], 0}, + {"brainpoolP384t1", "brainpoolP384t1", NID_brainpoolP384t1, 9, + &kObjectData[6073], 0}, + {"brainpoolP512r1", "brainpoolP512r1", NID_brainpoolP512r1, 9, + &kObjectData[6082], 0}, + {"brainpoolP512t1", "brainpoolP512t1", NID_brainpoolP512t1, 9, + &kObjectData[6091], 0}, + {"PSPECIFIED", "pSpecified", NID_pSpecified, 9, &kObjectData[6100], 0}, + {"dhSinglePass-stdDH-sha1kdf-scheme", "dhSinglePass-stdDH-sha1kdf-scheme", + NID_dhSinglePass_stdDH_sha1kdf_scheme, 9, &kObjectData[6109], 0}, + {"dhSinglePass-stdDH-sha224kdf-scheme", + "dhSinglePass-stdDH-sha224kdf-scheme", + NID_dhSinglePass_stdDH_sha224kdf_scheme, 6, &kObjectData[6118], 0}, + {"dhSinglePass-stdDH-sha256kdf-scheme", + "dhSinglePass-stdDH-sha256kdf-scheme", + NID_dhSinglePass_stdDH_sha256kdf_scheme, 6, &kObjectData[6124], 0}, + {"dhSinglePass-stdDH-sha384kdf-scheme", + "dhSinglePass-stdDH-sha384kdf-scheme", + NID_dhSinglePass_stdDH_sha384kdf_scheme, 6, &kObjectData[6130], 0}, + {"dhSinglePass-stdDH-sha512kdf-scheme", + "dhSinglePass-stdDH-sha512kdf-scheme", + NID_dhSinglePass_stdDH_sha512kdf_scheme, 6, &kObjectData[6136], 0}, + {"dhSinglePass-cofactorDH-sha1kdf-scheme", + "dhSinglePass-cofactorDH-sha1kdf-scheme", + NID_dhSinglePass_cofactorDH_sha1kdf_scheme, 9, &kObjectData[6142], 0}, + {"dhSinglePass-cofactorDH-sha224kdf-scheme", + "dhSinglePass-cofactorDH-sha224kdf-scheme", + NID_dhSinglePass_cofactorDH_sha224kdf_scheme, 6, &kObjectData[6151], 0}, + {"dhSinglePass-cofactorDH-sha256kdf-scheme", + "dhSinglePass-cofactorDH-sha256kdf-scheme", + NID_dhSinglePass_cofactorDH_sha256kdf_scheme, 6, &kObjectData[6157], 0}, + {"dhSinglePass-cofactorDH-sha384kdf-scheme", + "dhSinglePass-cofactorDH-sha384kdf-scheme", + NID_dhSinglePass_cofactorDH_sha384kdf_scheme, 6, &kObjectData[6163], 0}, + {"dhSinglePass-cofactorDH-sha512kdf-scheme", + "dhSinglePass-cofactorDH-sha512kdf-scheme", + NID_dhSinglePass_cofactorDH_sha512kdf_scheme, 6, &kObjectData[6169], 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}, + {"X25519", "X25519", NID_X25519, 0, NULL, 0}, + {"ED25519", "ED25519", NID_ED25519, 3, &kObjectData[6175], 0}, + {"ChaCha20-Poly1305", "chacha20-poly1305", NID_chacha20_poly1305, 0, NULL, + 0}, + {"KxRSA", "kx-rsa", NID_kx_rsa, 0, NULL, 0}, + {"KxECDHE", "kx-ecdhe", NID_kx_ecdhe, 0, NULL, 0}, + {"KxPSK", "kx-psk", NID_kx_psk, 0, NULL, 0}, + {"AuthRSA", "auth-rsa", NID_auth_rsa, 0, NULL, 0}, + {"AuthECDSA", "auth-ecdsa", NID_auth_ecdsa, 0, NULL, 0}, + {"AuthPSK", "auth-psk", NID_auth_psk, 0, NULL, 0}, + {"KxANY", "kx-any", NID_kx_any, 0, NULL, 0}, + {"AuthANY", "auth-any", NID_auth_any, 0, NULL, 0}, +}; + +static const unsigned kNIDsInShortNameOrder[] = { + 364 /* AD_DVCS */, + 419 /* AES-128-CBC */, + 916 /* AES-128-CBC-HMAC-SHA1 */, + 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 */, + 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 */, + 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 */, + 958 /* AuthANY */, + 955 /* AuthECDSA */, + 956 /* AuthPSK */, + 954 /* AuthRSA */, + 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 */, + 950 /* ChaCha20-Poly1305 */, + 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 */, + 949 /* ED25519 */, + 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 */, + 957 /* KxANY */, + 952 /* KxECDHE */, + 953 /* KxPSK */, + 951 /* KxRSA */, + 15 /* L */, + 856 /* LocalKeySet */, + 3 /* MD2 */, + 257 /* MD4 */, + 4 /* MD5 */, + 114 /* MD5-SHA1 */, + 95 /* MDC2 */, + 911 /* MGF1 */, + 388 /* Mail */, + 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 */, + 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 */, + 948 /* X25519 */, + 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 */, + 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 */, + 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 kNIDsInLongNameOrder[] = { + 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 */, + 131 /* Code Signing */, + 783 /* Diffie-Hellman based MAC */, + 382 /* Directory */, + 392 /* Domain */, + 132 /* E-mail Protection */, + 949 /* ED25519 */, + 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 */, + 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 */, + 948 /* X25519 */, + 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 Distribution 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 */, + 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 */, + 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 */, + 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 */, + 958 /* auth-any */, + 955 /* auth-ecdsa */, + 956 /* auth-psk */, + 954 /* auth-rsa */, + 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 */, + 950 /* chacha20-poly1305 */, + 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 */, + 150 /* keyBag */, + 773 /* kisa */, + 957 /* kx-any */, + 952 /* kx-ecdhe */, + 953 /* kx-psk */, + 951 /* kx-rsa */, + 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 */, + 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 kNIDsInOIDOrder[] = { + 434 /* 0.9 (OBJ_data) */, + 182 /* 1.2 (OBJ_member_body) */, + 379 /* 1.3 (OBJ_org) */, + 676 /* 1.3 (OBJ_identified_organization) */, + 11 /* 2.5 (OBJ_X500) */, + 647 /* 2.23 (OBJ_international_organizations) */, + 380 /* 1.3.6 (OBJ_dod) */, + 12 /* 2.5.4 (OBJ_X509) */, + 378 /* 2.5.8 (OBJ_X500algorithms) */, + 81 /* 2.5.29 (OBJ_id_ce) */, + 512 /* 2.23.42 (OBJ_id_set) */, + 678 /* 2.23.43 (OBJ_wap) */, + 435 /* 0.9.2342 (OBJ_pss) */, + 183 /* 1.2.840 (OBJ_ISO_US) */, + 381 /* 1.3.6.1 (OBJ_iana) */, + 949 /* 1.3.101.112 (OBJ_ED25519) */, + 677 /* 1.3.132 (OBJ_certicom_arc) */, + 394 /* 2.5.1.5 (OBJ_selected_attribute_types) */, + 13 /* 2.5.4.3 (OBJ_commonName) */, + 100 /* 2.5.4.4 (OBJ_surname) */, + 105 /* 2.5.4.5 (OBJ_serialNumber) */, + 14 /* 2.5.4.6 (OBJ_countryName) */, + 15 /* 2.5.4.7 (OBJ_localityName) */, + 16 /* 2.5.4.8 (OBJ_stateOrProvinceName) */, + 660 /* 2.5.4.9 (OBJ_streetAddress) */, + 17 /* 2.5.4.10 (OBJ_organizationName) */, + 18 /* 2.5.4.11 (OBJ_organizationalUnitName) */, + 106 /* 2.5.4.12 (OBJ_title) */, + 107 /* 2.5.4.13 (OBJ_description) */, + 859 /* 2.5.4.14 (OBJ_searchGuide) */, + 860 /* 2.5.4.15 (OBJ_businessCategory) */, + 861 /* 2.5.4.16 (OBJ_postalAddress) */, + 661 /* 2.5.4.17 (OBJ_postalCode) */, + 862 /* 2.5.4.18 (OBJ_postOfficeBox) */, + 863 /* 2.5.4.19 (OBJ_physicalDeliveryOfficeName) */, + 864 /* 2.5.4.20 (OBJ_telephoneNumber) */, + 865 /* 2.5.4.21 (OBJ_telexNumber) */, + 866 /* 2.5.4.22 (OBJ_teletexTerminalIdentifier) */, + 867 /* 2.5.4.23 (OBJ_facsimileTelephoneNumber) */, + 868 /* 2.5.4.24 (OBJ_x121Address) */, + 869 /* 2.5.4.25 (OBJ_internationaliSDNNumber) */, + 870 /* 2.5.4.26 (OBJ_registeredAddress) */, + 871 /* 2.5.4.27 (OBJ_destinationIndicator) */, + 872 /* 2.5.4.28 (OBJ_preferredDeliveryMethod) */, + 873 /* 2.5.4.29 (OBJ_presentationAddress) */, + 874 /* 2.5.4.30 (OBJ_supportedApplicationContext) */, + 875 /* 2.5.4.31 (OBJ_member) */, + 876 /* 2.5.4.32 (OBJ_owner) */, + 877 /* 2.5.4.33 (OBJ_roleOccupant) */, + 878 /* 2.5.4.34 (OBJ_seeAlso) */, + 879 /* 2.5.4.35 (OBJ_userPassword) */, + 880 /* 2.5.4.36 (OBJ_userCertificate) */, + 881 /* 2.5.4.37 (OBJ_cACertificate) */, + 882 /* 2.5.4.38 (OBJ_authorityRevocationList) */, + 883 /* 2.5.4.39 (OBJ_certificateRevocationList) */, + 884 /* 2.5.4.40 (OBJ_crossCertificatePair) */, + 173 /* 2.5.4.41 (OBJ_name) */, + 99 /* 2.5.4.42 (OBJ_givenName) */, + 101 /* 2.5.4.43 (OBJ_initials) */, + 509 /* 2.5.4.44 (OBJ_generationQualifier) */, + 503 /* 2.5.4.45 (OBJ_x500UniqueIdentifier) */, + 174 /* 2.5.4.46 (OBJ_dnQualifier) */, + 885 /* 2.5.4.47 (OBJ_enhancedSearchGuide) */, + 886 /* 2.5.4.48 (OBJ_protocolInformation) */, + 887 /* 2.5.4.49 (OBJ_distinguishedName) */, + 888 /* 2.5.4.50 (OBJ_uniqueMember) */, + 889 /* 2.5.4.51 (OBJ_houseIdentifier) */, + 890 /* 2.5.4.52 (OBJ_supportedAlgorithms) */, + 891 /* 2.5.4.53 (OBJ_deltaRevocationList) */, + 892 /* 2.5.4.54 (OBJ_dmdName) */, + 510 /* 2.5.4.65 (OBJ_pseudonym) */, + 400 /* 2.5.4.72 (OBJ_role) */, + 769 /* 2.5.29.9 (OBJ_subject_directory_attributes) */, + 82 /* 2.5.29.14 (OBJ_subject_key_identifier) */, + 83 /* 2.5.29.15 (OBJ_key_usage) */, + 84 /* 2.5.29.16 (OBJ_private_key_usage_period) */, + 85 /* 2.5.29.17 (OBJ_subject_alt_name) */, + 86 /* 2.5.29.18 (OBJ_issuer_alt_name) */, + 87 /* 2.5.29.19 (OBJ_basic_constraints) */, + 88 /* 2.5.29.20 (OBJ_crl_number) */, + 141 /* 2.5.29.21 (OBJ_crl_reason) */, + 430 /* 2.5.29.23 (OBJ_hold_instruction_code) */, + 142 /* 2.5.29.24 (OBJ_invalidity_date) */, + 140 /* 2.5.29.27 (OBJ_delta_crl) */, + 770 /* 2.5.29.28 (OBJ_issuing_distribution_point) */, + 771 /* 2.5.29.29 (OBJ_certificate_issuer) */, + 666 /* 2.5.29.30 (OBJ_name_constraints) */, + 103 /* 2.5.29.31 (OBJ_crl_distribution_points) */, + 89 /* 2.5.29.32 (OBJ_certificate_policies) */, + 747 /* 2.5.29.33 (OBJ_policy_mappings) */, + 90 /* 2.5.29.35 (OBJ_authority_key_identifier) */, + 401 /* 2.5.29.36 (OBJ_policy_constraints) */, + 126 /* 2.5.29.37 (OBJ_ext_key_usage) */, + 857 /* 2.5.29.46 (OBJ_freshest_crl) */, + 748 /* 2.5.29.54 (OBJ_inhibit_any_policy) */, + 402 /* 2.5.29.55 (OBJ_target_information) */, + 403 /* 2.5.29.56 (OBJ_no_rev_avail) */, + 513 /* 2.23.42.0 (OBJ_set_ctype) */, + 514 /* 2.23.42.1 (OBJ_set_msgExt) */, + 515 /* 2.23.42.3 (OBJ_set_attr) */, + 516 /* 2.23.42.5 (OBJ_set_policy) */, + 517 /* 2.23.42.7 (OBJ_set_certExt) */, + 518 /* 2.23.42.8 (OBJ_set_brand) */, + 679 /* 2.23.43.1 (OBJ_wap_wsg) */, + 382 /* 1.3.6.1.1 (OBJ_Directory) */, + 383 /* 1.3.6.1.2 (OBJ_Management) */, + 384 /* 1.3.6.1.3 (OBJ_Experimental) */, + 385 /* 1.3.6.1.4 (OBJ_Private) */, + 386 /* 1.3.6.1.5 (OBJ_Security) */, + 387 /* 1.3.6.1.6 (OBJ_SNMPv2) */, + 388 /* 1.3.6.1.7 (OBJ_Mail) */, + 376 /* 1.3.14.3.2 (OBJ_algorithm) */, + 395 /* 2.5.1.5.55 (OBJ_clearance) */, + 19 /* 2.5.8.1.1 (OBJ_rsa) */, + 96 /* 2.5.8.3.100 (OBJ_mdc2WithRSA) */, + 95 /* 2.5.8.3.101 (OBJ_mdc2) */, + 746 /* 2.5.29.32.0 (OBJ_any_policy) */, + 910 /* 2.5.29.37.0 (OBJ_anyExtendedKeyUsage) */, + 519 /* 2.23.42.0.0 (OBJ_setct_PANData) */, + 520 /* 2.23.42.0.1 (OBJ_setct_PANToken) */, + 521 /* 2.23.42.0.2 (OBJ_setct_PANOnly) */, + 522 /* 2.23.42.0.3 (OBJ_setct_OIData) */, + 523 /* 2.23.42.0.4 (OBJ_setct_PI) */, + 524 /* 2.23.42.0.5 (OBJ_setct_PIData) */, + 525 /* 2.23.42.0.6 (OBJ_setct_PIDataUnsigned) */, + 526 /* 2.23.42.0.7 (OBJ_setct_HODInput) */, + 527 /* 2.23.42.0.8 (OBJ_setct_AuthResBaggage) */, + 528 /* 2.23.42.0.9 (OBJ_setct_AuthRevReqBaggage) */, + 529 /* 2.23.42.0.10 (OBJ_setct_AuthRevResBaggage) */, + 530 /* 2.23.42.0.11 (OBJ_setct_CapTokenSeq) */, + 531 /* 2.23.42.0.12 (OBJ_setct_PInitResData) */, + 532 /* 2.23.42.0.13 (OBJ_setct_PI_TBS) */, + 533 /* 2.23.42.0.14 (OBJ_setct_PResData) */, + 534 /* 2.23.42.0.16 (OBJ_setct_AuthReqTBS) */, + 535 /* 2.23.42.0.17 (OBJ_setct_AuthResTBS) */, + 536 /* 2.23.42.0.18 (OBJ_setct_AuthResTBSX) */, + 537 /* 2.23.42.0.19 (OBJ_setct_AuthTokenTBS) */, + 538 /* 2.23.42.0.20 (OBJ_setct_CapTokenData) */, + 539 /* 2.23.42.0.21 (OBJ_setct_CapTokenTBS) */, + 540 /* 2.23.42.0.22 (OBJ_setct_AcqCardCodeMsg) */, + 541 /* 2.23.42.0.23 (OBJ_setct_AuthRevReqTBS) */, + 542 /* 2.23.42.0.24 (OBJ_setct_AuthRevResData) */, + 543 /* 2.23.42.0.25 (OBJ_setct_AuthRevResTBS) */, + 544 /* 2.23.42.0.26 (OBJ_setct_CapReqTBS) */, + 545 /* 2.23.42.0.27 (OBJ_setct_CapReqTBSX) */, + 546 /* 2.23.42.0.28 (OBJ_setct_CapResData) */, + 547 /* 2.23.42.0.29 (OBJ_setct_CapRevReqTBS) */, + 548 /* 2.23.42.0.30 (OBJ_setct_CapRevReqTBSX) */, + 549 /* 2.23.42.0.31 (OBJ_setct_CapRevResData) */, + 550 /* 2.23.42.0.32 (OBJ_setct_CredReqTBS) */, + 551 /* 2.23.42.0.33 (OBJ_setct_CredReqTBSX) */, + 552 /* 2.23.42.0.34 (OBJ_setct_CredResData) */, + 553 /* 2.23.42.0.35 (OBJ_setct_CredRevReqTBS) */, + 554 /* 2.23.42.0.36 (OBJ_setct_CredRevReqTBSX) */, + 555 /* 2.23.42.0.37 (OBJ_setct_CredRevResData) */, + 556 /* 2.23.42.0.38 (OBJ_setct_PCertReqData) */, + 557 /* 2.23.42.0.39 (OBJ_setct_PCertResTBS) */, + 558 /* 2.23.42.0.40 (OBJ_setct_BatchAdminReqData) */, + 559 /* 2.23.42.0.41 (OBJ_setct_BatchAdminResData) */, + 560 /* 2.23.42.0.42 (OBJ_setct_CardCInitResTBS) */, + 561 /* 2.23.42.0.43 (OBJ_setct_MeAqCInitResTBS) */, + 562 /* 2.23.42.0.44 (OBJ_setct_RegFormResTBS) */, + 563 /* 2.23.42.0.45 (OBJ_setct_CertReqData) */, + 564 /* 2.23.42.0.46 (OBJ_setct_CertReqTBS) */, + 565 /* 2.23.42.0.47 (OBJ_setct_CertResData) */, + 566 /* 2.23.42.0.48 (OBJ_setct_CertInqReqTBS) */, + 567 /* 2.23.42.0.49 (OBJ_setct_ErrorTBS) */, + 568 /* 2.23.42.0.50 (OBJ_setct_PIDualSignedTBE) */, + 569 /* 2.23.42.0.51 (OBJ_setct_PIUnsignedTBE) */, + 570 /* 2.23.42.0.52 (OBJ_setct_AuthReqTBE) */, + 571 /* 2.23.42.0.53 (OBJ_setct_AuthResTBE) */, + 572 /* 2.23.42.0.54 (OBJ_setct_AuthResTBEX) */, + 573 /* 2.23.42.0.55 (OBJ_setct_AuthTokenTBE) */, + 574 /* 2.23.42.0.56 (OBJ_setct_CapTokenTBE) */, + 575 /* 2.23.42.0.57 (OBJ_setct_CapTokenTBEX) */, + 576 /* 2.23.42.0.58 (OBJ_setct_AcqCardCodeMsgTBE) */, + 577 /* 2.23.42.0.59 (OBJ_setct_AuthRevReqTBE) */, + 578 /* 2.23.42.0.60 (OBJ_setct_AuthRevResTBE) */, + 579 /* 2.23.42.0.61 (OBJ_setct_AuthRevResTBEB) */, + 580 /* 2.23.42.0.62 (OBJ_setct_CapReqTBE) */, + 581 /* 2.23.42.0.63 (OBJ_setct_CapReqTBEX) */, + 582 /* 2.23.42.0.64 (OBJ_setct_CapResTBE) */, + 583 /* 2.23.42.0.65 (OBJ_setct_CapRevReqTBE) */, + 584 /* 2.23.42.0.66 (OBJ_setct_CapRevReqTBEX) */, + 585 /* 2.23.42.0.67 (OBJ_setct_CapRevResTBE) */, + 586 /* 2.23.42.0.68 (OBJ_setct_CredReqTBE) */, + 587 /* 2.23.42.0.69 (OBJ_setct_CredReqTBEX) */, + 588 /* 2.23.42.0.70 (OBJ_setct_CredResTBE) */, + 589 /* 2.23.42.0.71 (OBJ_setct_CredRevReqTBE) */, + 590 /* 2.23.42.0.72 (OBJ_setct_CredRevReqTBEX) */, + 591 /* 2.23.42.0.73 (OBJ_setct_CredRevResTBE) */, + 592 /* 2.23.42.0.74 (OBJ_setct_BatchAdminReqTBE) */, + 593 /* 2.23.42.0.75 (OBJ_setct_BatchAdminResTBE) */, + 594 /* 2.23.42.0.76 (OBJ_setct_RegFormReqTBE) */, + 595 /* 2.23.42.0.77 (OBJ_setct_CertReqTBE) */, + 596 /* 2.23.42.0.78 (OBJ_setct_CertReqTBEX) */, + 597 /* 2.23.42.0.79 (OBJ_setct_CertResTBE) */, + 598 /* 2.23.42.0.80 (OBJ_setct_CRLNotificationTBS) */, + 599 /* 2.23.42.0.81 (OBJ_setct_CRLNotificationResTBS) */, + 600 /* 2.23.42.0.82 (OBJ_setct_BCIDistributionTBS) */, + 601 /* 2.23.42.1.1 (OBJ_setext_genCrypt) */, + 602 /* 2.23.42.1.3 (OBJ_setext_miAuth) */, + 603 /* 2.23.42.1.4 (OBJ_setext_pinSecure) */, + 604 /* 2.23.42.1.5 (OBJ_setext_pinAny) */, + 605 /* 2.23.42.1.7 (OBJ_setext_track2) */, + 606 /* 2.23.42.1.8 (OBJ_setext_cv) */, + 620 /* 2.23.42.3.0 (OBJ_setAttr_Cert) */, + 621 /* 2.23.42.3.1 (OBJ_setAttr_PGWYcap) */, + 622 /* 2.23.42.3.2 (OBJ_setAttr_TokenType) */, + 623 /* 2.23.42.3.3 (OBJ_setAttr_IssCap) */, + 607 /* 2.23.42.5.0 (OBJ_set_policy_root) */, + 608 /* 2.23.42.7.0 (OBJ_setCext_hashedRoot) */, + 609 /* 2.23.42.7.1 (OBJ_setCext_certType) */, + 610 /* 2.23.42.7.2 (OBJ_setCext_merchData) */, + 611 /* 2.23.42.7.3 (OBJ_setCext_cCertRequired) */, + 612 /* 2.23.42.7.4 (OBJ_setCext_tunneling) */, + 613 /* 2.23.42.7.5 (OBJ_setCext_setExt) */, + 614 /* 2.23.42.7.6 (OBJ_setCext_setQualf) */, + 615 /* 2.23.42.7.7 (OBJ_setCext_PGWYcapabilities) */, + 616 /* 2.23.42.7.8 (OBJ_setCext_TokenIdentifier) */, + 617 /* 2.23.42.7.9 (OBJ_setCext_Track2Data) */, + 618 /* 2.23.42.7.10 (OBJ_setCext_TokenType) */, + 619 /* 2.23.42.7.11 (OBJ_setCext_IssuerCapabilities) */, + 636 /* 2.23.42.8.1 (OBJ_set_brand_IATA_ATA) */, + 640 /* 2.23.42.8.4 (OBJ_set_brand_Visa) */, + 641 /* 2.23.42.8.5 (OBJ_set_brand_MasterCard) */, + 637 /* 2.23.42.8.30 (OBJ_set_brand_Diners) */, + 638 /* 2.23.42.8.34 (OBJ_set_brand_AmericanExpress) */, + 639 /* 2.23.42.8.35 (OBJ_set_brand_JCB) */, + 805 /* 1.2.643.2.2 (OBJ_cryptopro) */, + 806 /* 1.2.643.2.9 (OBJ_cryptocom) */, + 184 /* 1.2.840.10040 (OBJ_X9_57) */, + 405 /* 1.2.840.10045 (OBJ_ansi_X9_62) */, + 389 /* 1.3.6.1.4.1 (OBJ_Enterprises) */, + 504 /* 1.3.6.1.7.1 (OBJ_mime_mhs) */, + 104 /* 1.3.14.3.2.3 (OBJ_md5WithRSA) */, + 29 /* 1.3.14.3.2.6 (OBJ_des_ecb) */, + 31 /* 1.3.14.3.2.7 (OBJ_des_cbc) */, + 45 /* 1.3.14.3.2.8 (OBJ_des_ofb64) */, + 30 /* 1.3.14.3.2.9 (OBJ_des_cfb64) */, + 377 /* 1.3.14.3.2.11 (OBJ_rsaSignature) */, + 67 /* 1.3.14.3.2.12 (OBJ_dsa_2) */, + 66 /* 1.3.14.3.2.13 (OBJ_dsaWithSHA) */, + 42 /* 1.3.14.3.2.15 (OBJ_shaWithRSAEncryption) */, + 32 /* 1.3.14.3.2.17 (OBJ_des_ede_ecb) */, + 41 /* 1.3.14.3.2.18 (OBJ_sha) */, + 64 /* 1.3.14.3.2.26 (OBJ_sha1) */, + 70 /* 1.3.14.3.2.27 (OBJ_dsaWithSHA1_2) */, + 115 /* 1.3.14.3.2.29 (OBJ_sha1WithRSA) */, + 117 /* 1.3.36.3.2.1 (OBJ_ripemd160) */, + 143 /* 1.3.101.1.4.1 (OBJ_sxnet) */, + 721 /* 1.3.132.0.1 (OBJ_sect163k1) */, + 722 /* 1.3.132.0.2 (OBJ_sect163r1) */, + 728 /* 1.3.132.0.3 (OBJ_sect239k1) */, + 717 /* 1.3.132.0.4 (OBJ_sect113r1) */, + 718 /* 1.3.132.0.5 (OBJ_sect113r2) */, + 704 /* 1.3.132.0.6 (OBJ_secp112r1) */, + 705 /* 1.3.132.0.7 (OBJ_secp112r2) */, + 709 /* 1.3.132.0.8 (OBJ_secp160r1) */, + 708 /* 1.3.132.0.9 (OBJ_secp160k1) */, + 714 /* 1.3.132.0.10 (OBJ_secp256k1) */, + 723 /* 1.3.132.0.15 (OBJ_sect163r2) */, + 729 /* 1.3.132.0.16 (OBJ_sect283k1) */, + 730 /* 1.3.132.0.17 (OBJ_sect283r1) */, + 719 /* 1.3.132.0.22 (OBJ_sect131r1) */, + 720 /* 1.3.132.0.23 (OBJ_sect131r2) */, + 724 /* 1.3.132.0.24 (OBJ_sect193r1) */, + 725 /* 1.3.132.0.25 (OBJ_sect193r2) */, + 726 /* 1.3.132.0.26 (OBJ_sect233k1) */, + 727 /* 1.3.132.0.27 (OBJ_sect233r1) */, + 706 /* 1.3.132.0.28 (OBJ_secp128r1) */, + 707 /* 1.3.132.0.29 (OBJ_secp128r2) */, + 710 /* 1.3.132.0.30 (OBJ_secp160r2) */, + 711 /* 1.3.132.0.31 (OBJ_secp192k1) */, + 712 /* 1.3.132.0.32 (OBJ_secp224k1) */, + 713 /* 1.3.132.0.33 (OBJ_secp224r1) */, + 715 /* 1.3.132.0.34 (OBJ_secp384r1) */, + 716 /* 1.3.132.0.35 (OBJ_secp521r1) */, + 731 /* 1.3.132.0.36 (OBJ_sect409k1) */, + 732 /* 1.3.132.0.37 (OBJ_sect409r1) */, + 733 /* 1.3.132.0.38 (OBJ_sect571k1) */, + 734 /* 1.3.132.0.39 (OBJ_sect571r1) */, + 624 /* 2.23.42.3.0.0 (OBJ_set_rootKeyThumb) */, + 625 /* 2.23.42.3.0.1 (OBJ_set_addPolicy) */, + 626 /* 2.23.42.3.2.1 (OBJ_setAttr_Token_EMV) */, + 627 /* 2.23.42.3.2.2 (OBJ_setAttr_Token_B0Prime) */, + 628 /* 2.23.42.3.3.3 (OBJ_setAttr_IssCap_CVM) */, + 629 /* 2.23.42.3.3.4 (OBJ_setAttr_IssCap_T2) */, + 630 /* 2.23.42.3.3.5 (OBJ_setAttr_IssCap_Sig) */, + 642 /* 2.23.42.8.6011 (OBJ_set_brand_Novus) */, + 735 /* 2.23.43.1.4.1 (OBJ_wap_wsg_idm_ecid_wtls1) */, + 736 /* 2.23.43.1.4.3 (OBJ_wap_wsg_idm_ecid_wtls3) */, + 737 /* 2.23.43.1.4.4 (OBJ_wap_wsg_idm_ecid_wtls4) */, + 738 /* 2.23.43.1.4.5 (OBJ_wap_wsg_idm_ecid_wtls5) */, + 739 /* 2.23.43.1.4.6 (OBJ_wap_wsg_idm_ecid_wtls6) */, + 740 /* 2.23.43.1.4.7 (OBJ_wap_wsg_idm_ecid_wtls7) */, + 741 /* 2.23.43.1.4.8 (OBJ_wap_wsg_idm_ecid_wtls8) */, + 742 /* 2.23.43.1.4.9 (OBJ_wap_wsg_idm_ecid_wtls9) */, + 743 /* 2.23.43.1.4.10 (OBJ_wap_wsg_idm_ecid_wtls10) */, + 744 /* 2.23.43.1.4.11 (OBJ_wap_wsg_idm_ecid_wtls11) */, + 745 /* 2.23.43.1.4.12 (OBJ_wap_wsg_idm_ecid_wtls12) */, + 804 /* 1.0.10118.3.0.55 (OBJ_whirlpool) */, + 773 /* 1.2.410.200004 (OBJ_kisa) */, + 807 /* 1.2.643.2.2.3 (OBJ_id_GostR3411_94_with_GostR3410_2001) */, + 808 /* 1.2.643.2.2.4 (OBJ_id_GostR3411_94_with_GostR3410_94) */, + 809 /* 1.2.643.2.2.9 (OBJ_id_GostR3411_94) */, + 810 /* 1.2.643.2.2.10 (OBJ_id_HMACGostR3411_94) */, + 811 /* 1.2.643.2.2.19 (OBJ_id_GostR3410_2001) */, + 812 /* 1.2.643.2.2.20 (OBJ_id_GostR3410_94) */, + 813 /* 1.2.643.2.2.21 (OBJ_id_Gost28147_89) */, + 815 /* 1.2.643.2.2.22 (OBJ_id_Gost28147_89_MAC) */, + 816 /* 1.2.643.2.2.23 (OBJ_id_GostR3411_94_prf) */, + 817 /* 1.2.643.2.2.98 (OBJ_id_GostR3410_2001DH) */, + 818 /* 1.2.643.2.2.99 (OBJ_id_GostR3410_94DH) */, + 1 /* 1.2.840.113549 (OBJ_rsadsi) */, + 185 /* 1.2.840.10040.4 (OBJ_X9cm) */, + 127 /* 1.3.6.1.5.5.7 (OBJ_id_pkix) */, + 505 /* 1.3.6.1.7.1.1 (OBJ_mime_mhs_headings) */, + 506 /* 1.3.6.1.7.1.2 (OBJ_mime_mhs_bodies) */, + 119 /* 1.3.36.3.3.1.2 (OBJ_ripemd160WithRSA) */, + 937 /* 1.3.132.1.11.0 (OBJ_dhSinglePass_stdDH_sha224kdf_scheme) */, + 938 /* 1.3.132.1.11.1 (OBJ_dhSinglePass_stdDH_sha256kdf_scheme) */, + 939 /* 1.3.132.1.11.2 (OBJ_dhSinglePass_stdDH_sha384kdf_scheme) */, + 940 /* 1.3.132.1.11.3 (OBJ_dhSinglePass_stdDH_sha512kdf_scheme) */, + 942 /* 1.3.132.1.14.0 (OBJ_dhSinglePass_cofactorDH_sha224kdf_scheme) */, + 943 /* 1.3.132.1.14.1 (OBJ_dhSinglePass_cofactorDH_sha256kdf_scheme) */, + 944 /* 1.3.132.1.14.2 (OBJ_dhSinglePass_cofactorDH_sha384kdf_scheme) */, + 945 /* 1.3.132.1.14.3 (OBJ_dhSinglePass_cofactorDH_sha512kdf_scheme) */, + 631 /* 2.23.42.3.3.3.1 (OBJ_setAttr_GenCryptgrm) */, + 632 /* 2.23.42.3.3.4.1 (OBJ_setAttr_T2Enc) */, + 633 /* 2.23.42.3.3.4.2 (OBJ_setAttr_T2cleartxt) */, + 634 /* 2.23.42.3.3.5.1 (OBJ_setAttr_TokICCsig) */, + 635 /* 2.23.42.3.3.5.2 (OBJ_setAttr_SecDevSig) */, + 436 /* 0.9.2342.19200300 (OBJ_ucl) */, + 820 /* 1.2.643.2.2.14.0 (OBJ_id_Gost28147_89_None_KeyMeshing) */, + 819 /* 1.2.643.2.2.14.1 (OBJ_id_Gost28147_89_CryptoPro_KeyMeshing) */, + 845 /* 1.2.643.2.2.20.1 (OBJ_id_GostR3410_94_a) */, + 846 /* 1.2.643.2.2.20.2 (OBJ_id_GostR3410_94_aBis) */, + 847 /* 1.2.643.2.2.20.3 (OBJ_id_GostR3410_94_b) */, + 848 /* 1.2.643.2.2.20.4 (OBJ_id_GostR3410_94_bBis) */, + 821 /* 1.2.643.2.2.30.0 (OBJ_id_GostR3411_94_TestParamSet) */, + 822 /* 1.2.643.2.2.30.1 (OBJ_id_GostR3411_94_CryptoProParamSet) */, + 823 /* 1.2.643.2.2.31.0 (OBJ_id_Gost28147_89_TestParamSet) */, + 824 /* 1.2.643.2.2.31.1 (OBJ_id_Gost28147_89_CryptoPro_A_ParamSet) */, + 825 /* 1.2.643.2.2.31.2 (OBJ_id_Gost28147_89_CryptoPro_B_ParamSet) */, + 826 /* 1.2.643.2.2.31.3 (OBJ_id_Gost28147_89_CryptoPro_C_ParamSet) */, + 827 /* 1.2.643.2.2.31.4 (OBJ_id_Gost28147_89_CryptoPro_D_ParamSet) */, + 828 /* 1.2.643.2.2.31.5 (OBJ_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet) */ + , + 829 /* 1.2.643.2.2.31.6 (OBJ_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet) */ + , + 830 /* 1.2.643.2.2.31.7 (OBJ_id_Gost28147_89_CryptoPro_RIC_1_ParamSet) */, + 831 /* 1.2.643.2.2.32.0 (OBJ_id_GostR3410_94_TestParamSet) */, + 832 /* 1.2.643.2.2.32.2 (OBJ_id_GostR3410_94_CryptoPro_A_ParamSet) */, + 833 /* 1.2.643.2.2.32.3 (OBJ_id_GostR3410_94_CryptoPro_B_ParamSet) */, + 834 /* 1.2.643.2.2.32.4 (OBJ_id_GostR3410_94_CryptoPro_C_ParamSet) */, + 835 /* 1.2.643.2.2.32.5 (OBJ_id_GostR3410_94_CryptoPro_D_ParamSet) */, + 836 /* 1.2.643.2.2.33.1 (OBJ_id_GostR3410_94_CryptoPro_XchA_ParamSet) */, + 837 /* 1.2.643.2.2.33.2 (OBJ_id_GostR3410_94_CryptoPro_XchB_ParamSet) */, + 838 /* 1.2.643.2.2.33.3 (OBJ_id_GostR3410_94_CryptoPro_XchC_ParamSet) */, + 839 /* 1.2.643.2.2.35.0 (OBJ_id_GostR3410_2001_TestParamSet) */, + 840 /* 1.2.643.2.2.35.1 (OBJ_id_GostR3410_2001_CryptoPro_A_ParamSet) */, + 841 /* 1.2.643.2.2.35.2 (OBJ_id_GostR3410_2001_CryptoPro_B_ParamSet) */, + 842 /* 1.2.643.2.2.35.3 (OBJ_id_GostR3410_2001_CryptoPro_C_ParamSet) */, + 843 /* 1.2.643.2.2.36.0 (OBJ_id_GostR3410_2001_CryptoPro_XchA_ParamSet) */, + 844 /* 1.2.643.2.2.36.1 (OBJ_id_GostR3410_2001_CryptoPro_XchB_ParamSet) */, + 2 /* 1.2.840.113549.1 (OBJ_pkcs) */, + 431 /* 1.2.840.10040.2.1 (OBJ_hold_instruction_none) */, + 432 /* 1.2.840.10040.2.2 (OBJ_hold_instruction_call_issuer) */, + 433 /* 1.2.840.10040.2.3 (OBJ_hold_instruction_reject) */, + 116 /* 1.2.840.10040.4.1 (OBJ_dsa) */, + 113 /* 1.2.840.10040.4.3 (OBJ_dsaWithSHA1) */, + 406 /* 1.2.840.10045.1.1 (OBJ_X9_62_prime_field) */, + 407 /* 1.2.840.10045.1.2 (OBJ_X9_62_characteristic_two_field) */, + 408 /* 1.2.840.10045.2.1 (OBJ_X9_62_id_ecPublicKey) */, + 416 /* 1.2.840.10045.4.1 (OBJ_ecdsa_with_SHA1) */, + 791 /* 1.2.840.10045.4.2 (OBJ_ecdsa_with_Recommended) */, + 792 /* 1.2.840.10045.4.3 (OBJ_ecdsa_with_Specified) */, + 920 /* 1.2.840.10046.2.1 (OBJ_dhpublicnumber) */, + 258 /* 1.3.6.1.5.5.7.0 (OBJ_id_pkix_mod) */, + 175 /* 1.3.6.1.5.5.7.1 (OBJ_id_pe) */, + 259 /* 1.3.6.1.5.5.7.2 (OBJ_id_qt) */, + 128 /* 1.3.6.1.5.5.7.3 (OBJ_id_kp) */, + 260 /* 1.3.6.1.5.5.7.4 (OBJ_id_it) */, + 261 /* 1.3.6.1.5.5.7.5 (OBJ_id_pkip) */, + 262 /* 1.3.6.1.5.5.7.6 (OBJ_id_alg) */, + 263 /* 1.3.6.1.5.5.7.7 (OBJ_id_cmc) */, + 264 /* 1.3.6.1.5.5.7.8 (OBJ_id_on) */, + 265 /* 1.3.6.1.5.5.7.9 (OBJ_id_pda) */, + 266 /* 1.3.6.1.5.5.7.10 (OBJ_id_aca) */, + 267 /* 1.3.6.1.5.5.7.11 (OBJ_id_qcs) */, + 268 /* 1.3.6.1.5.5.7.12 (OBJ_id_cct) */, + 662 /* 1.3.6.1.5.5.7.21 (OBJ_id_ppl) */, + 176 /* 1.3.6.1.5.5.7.48 (OBJ_id_ad) */, + 507 /* 1.3.6.1.7.1.1.1 (OBJ_id_hex_partial_message) */, + 508 /* 1.3.6.1.7.1.1.2 (OBJ_id_hex_multipart_message) */, + 57 /* 2.16.840.1.113730 (OBJ_netscape) */, + 754 /* 0.3.4401.5.3.1.9.1 (OBJ_camellia_128_ecb) */, + 766 /* 0.3.4401.5.3.1.9.3 (OBJ_camellia_128_ofb128) */, + 757 /* 0.3.4401.5.3.1.9.4 (OBJ_camellia_128_cfb128) */, + 755 /* 0.3.4401.5.3.1.9.21 (OBJ_camellia_192_ecb) */, + 767 /* 0.3.4401.5.3.1.9.23 (OBJ_camellia_192_ofb128) */, + 758 /* 0.3.4401.5.3.1.9.24 (OBJ_camellia_192_cfb128) */, + 756 /* 0.3.4401.5.3.1.9.41 (OBJ_camellia_256_ecb) */, + 768 /* 0.3.4401.5.3.1.9.43 (OBJ_camellia_256_ofb128) */, + 759 /* 0.3.4401.5.3.1.9.44 (OBJ_camellia_256_cfb128) */, + 437 /* 0.9.2342.19200300.100 (OBJ_pilot) */, + 776 /* 1.2.410.200004.1.3 (OBJ_seed_ecb) */, + 777 /* 1.2.410.200004.1.4 (OBJ_seed_cbc) */, + 779 /* 1.2.410.200004.1.5 (OBJ_seed_cfb128) */, + 778 /* 1.2.410.200004.1.6 (OBJ_seed_ofb128) */, + 852 /* 1.2.643.2.9.1.3.3 (OBJ_id_GostR3411_94_with_GostR3410_94_cc) */, + 853 /* 1.2.643.2.9.1.3.4 (OBJ_id_GostR3411_94_with_GostR3410_2001_cc) */, + 850 /* 1.2.643.2.9.1.5.3 (OBJ_id_GostR3410_94_cc) */, + 851 /* 1.2.643.2.9.1.5.4 (OBJ_id_GostR3410_2001_cc) */, + 849 /* 1.2.643.2.9.1.6.1 (OBJ_id_Gost28147_89_cc) */, + 854 /* 1.2.643.2.9.1.8.1 (OBJ_id_GostR3410_2001_ParamSet_cc) */, + 186 /* 1.2.840.113549.1.1 (OBJ_pkcs1) */, + 27 /* 1.2.840.113549.1.3 (OBJ_pkcs3) */, + 187 /* 1.2.840.113549.1.5 (OBJ_pkcs5) */, + 20 /* 1.2.840.113549.1.7 (OBJ_pkcs7) */, + 47 /* 1.2.840.113549.1.9 (OBJ_pkcs9) */, + 3 /* 1.2.840.113549.2.2 (OBJ_md2) */, + 257 /* 1.2.840.113549.2.4 (OBJ_md4) */, + 4 /* 1.2.840.113549.2.5 (OBJ_md5) */, + 797 /* 1.2.840.113549.2.6 (OBJ_hmacWithMD5) */, + 163 /* 1.2.840.113549.2.7 (OBJ_hmacWithSHA1) */, + 798 /* 1.2.840.113549.2.8 (OBJ_hmacWithSHA224) */, + 799 /* 1.2.840.113549.2.9 (OBJ_hmacWithSHA256) */, + 800 /* 1.2.840.113549.2.10 (OBJ_hmacWithSHA384) */, + 801 /* 1.2.840.113549.2.11 (OBJ_hmacWithSHA512) */, + 37 /* 1.2.840.113549.3.2 (OBJ_rc2_cbc) */, + 5 /* 1.2.840.113549.3.4 (OBJ_rc4) */, + 44 /* 1.2.840.113549.3.7 (OBJ_des_ede3_cbc) */, + 120 /* 1.2.840.113549.3.8 (OBJ_rc5_cbc) */, + 643 /* 1.2.840.113549.3.10 (OBJ_des_cdmf) */, + 680 /* 1.2.840.10045.1.2.3 (OBJ_X9_62_id_characteristic_two_basis) */, + 684 /* 1.2.840.10045.3.0.1 (OBJ_X9_62_c2pnb163v1) */, + 685 /* 1.2.840.10045.3.0.2 (OBJ_X9_62_c2pnb163v2) */, + 686 /* 1.2.840.10045.3.0.3 (OBJ_X9_62_c2pnb163v3) */, + 687 /* 1.2.840.10045.3.0.4 (OBJ_X9_62_c2pnb176v1) */, + 688 /* 1.2.840.10045.3.0.5 (OBJ_X9_62_c2tnb191v1) */, + 689 /* 1.2.840.10045.3.0.6 (OBJ_X9_62_c2tnb191v2) */, + 690 /* 1.2.840.10045.3.0.7 (OBJ_X9_62_c2tnb191v3) */, + 691 /* 1.2.840.10045.3.0.8 (OBJ_X9_62_c2onb191v4) */, + 692 /* 1.2.840.10045.3.0.9 (OBJ_X9_62_c2onb191v5) */, + 693 /* 1.2.840.10045.3.0.10 (OBJ_X9_62_c2pnb208w1) */, + 694 /* 1.2.840.10045.3.0.11 (OBJ_X9_62_c2tnb239v1) */, + 695 /* 1.2.840.10045.3.0.12 (OBJ_X9_62_c2tnb239v2) */, + 696 /* 1.2.840.10045.3.0.13 (OBJ_X9_62_c2tnb239v3) */, + 697 /* 1.2.840.10045.3.0.14 (OBJ_X9_62_c2onb239v4) */, + 698 /* 1.2.840.10045.3.0.15 (OBJ_X9_62_c2onb239v5) */, + 699 /* 1.2.840.10045.3.0.16 (OBJ_X9_62_c2pnb272w1) */, + 700 /* 1.2.840.10045.3.0.17 (OBJ_X9_62_c2pnb304w1) */, + 701 /* 1.2.840.10045.3.0.18 (OBJ_X9_62_c2tnb359v1) */, + 702 /* 1.2.840.10045.3.0.19 (OBJ_X9_62_c2pnb368w1) */, + 703 /* 1.2.840.10045.3.0.20 (OBJ_X9_62_c2tnb431r1) */, + 409 /* 1.2.840.10045.3.1.1 (OBJ_X9_62_prime192v1) */, + 410 /* 1.2.840.10045.3.1.2 (OBJ_X9_62_prime192v2) */, + 411 /* 1.2.840.10045.3.1.3 (OBJ_X9_62_prime192v3) */, + 412 /* 1.2.840.10045.3.1.4 (OBJ_X9_62_prime239v1) */, + 413 /* 1.2.840.10045.3.1.5 (OBJ_X9_62_prime239v2) */, + 414 /* 1.2.840.10045.3.1.6 (OBJ_X9_62_prime239v3) */, + 415 /* 1.2.840.10045.3.1.7 (OBJ_X9_62_prime256v1) */, + 793 /* 1.2.840.10045.4.3.1 (OBJ_ecdsa_with_SHA224) */, + 794 /* 1.2.840.10045.4.3.2 (OBJ_ecdsa_with_SHA256) */, + 795 /* 1.2.840.10045.4.3.3 (OBJ_ecdsa_with_SHA384) */, + 796 /* 1.2.840.10045.4.3.4 (OBJ_ecdsa_with_SHA512) */, + 269 /* 1.3.6.1.5.5.7.0.1 (OBJ_id_pkix1_explicit_88) */, + 270 /* 1.3.6.1.5.5.7.0.2 (OBJ_id_pkix1_implicit_88) */, + 271 /* 1.3.6.1.5.5.7.0.3 (OBJ_id_pkix1_explicit_93) */, + 272 /* 1.3.6.1.5.5.7.0.4 (OBJ_id_pkix1_implicit_93) */, + 273 /* 1.3.6.1.5.5.7.0.5 (OBJ_id_mod_crmf) */, + 274 /* 1.3.6.1.5.5.7.0.6 (OBJ_id_mod_cmc) */, + 275 /* 1.3.6.1.5.5.7.0.7 (OBJ_id_mod_kea_profile_88) */, + 276 /* 1.3.6.1.5.5.7.0.8 (OBJ_id_mod_kea_profile_93) */, + 277 /* 1.3.6.1.5.5.7.0.9 (OBJ_id_mod_cmp) */, + 278 /* 1.3.6.1.5.5.7.0.10 (OBJ_id_mod_qualified_cert_88) */, + 279 /* 1.3.6.1.5.5.7.0.11 (OBJ_id_mod_qualified_cert_93) */, + 280 /* 1.3.6.1.5.5.7.0.12 (OBJ_id_mod_attribute_cert) */, + 281 /* 1.3.6.1.5.5.7.0.13 (OBJ_id_mod_timestamp_protocol) */, + 282 /* 1.3.6.1.5.5.7.0.14 (OBJ_id_mod_ocsp) */, + 283 /* 1.3.6.1.5.5.7.0.15 (OBJ_id_mod_dvcs) */, + 284 /* 1.3.6.1.5.5.7.0.16 (OBJ_id_mod_cmp2000) */, + 177 /* 1.3.6.1.5.5.7.1.1 (OBJ_info_access) */, + 285 /* 1.3.6.1.5.5.7.1.2 (OBJ_biometricInfo) */, + 286 /* 1.3.6.1.5.5.7.1.3 (OBJ_qcStatements) */, + 287 /* 1.3.6.1.5.5.7.1.4 (OBJ_ac_auditEntity) */, + 288 /* 1.3.6.1.5.5.7.1.5 (OBJ_ac_targeting) */, + 289 /* 1.3.6.1.5.5.7.1.6 (OBJ_aaControls) */, + 290 /* 1.3.6.1.5.5.7.1.7 (OBJ_sbgp_ipAddrBlock) */, + 291 /* 1.3.6.1.5.5.7.1.8 (OBJ_sbgp_autonomousSysNum) */, + 292 /* 1.3.6.1.5.5.7.1.9 (OBJ_sbgp_routerIdentifier) */, + 397 /* 1.3.6.1.5.5.7.1.10 (OBJ_ac_proxying) */, + 398 /* 1.3.6.1.5.5.7.1.11 (OBJ_sinfo_access) */, + 663 /* 1.3.6.1.5.5.7.1.14 (OBJ_proxyCertInfo) */, + 164 /* 1.3.6.1.5.5.7.2.1 (OBJ_id_qt_cps) */, + 165 /* 1.3.6.1.5.5.7.2.2 (OBJ_id_qt_unotice) */, + 293 /* 1.3.6.1.5.5.7.2.3 (OBJ_textNotice) */, + 129 /* 1.3.6.1.5.5.7.3.1 (OBJ_server_auth) */, + 130 /* 1.3.6.1.5.5.7.3.2 (OBJ_client_auth) */, + 131 /* 1.3.6.1.5.5.7.3.3 (OBJ_code_sign) */, + 132 /* 1.3.6.1.5.5.7.3.4 (OBJ_email_protect) */, + 294 /* 1.3.6.1.5.5.7.3.5 (OBJ_ipsecEndSystem) */, + 295 /* 1.3.6.1.5.5.7.3.6 (OBJ_ipsecTunnel) */, + 296 /* 1.3.6.1.5.5.7.3.7 (OBJ_ipsecUser) */, + 133 /* 1.3.6.1.5.5.7.3.8 (OBJ_time_stamp) */, + 180 /* 1.3.6.1.5.5.7.3.9 (OBJ_OCSP_sign) */, + 297 /* 1.3.6.1.5.5.7.3.10 (OBJ_dvcs) */, + 298 /* 1.3.6.1.5.5.7.4.1 (OBJ_id_it_caProtEncCert) */, + 299 /* 1.3.6.1.5.5.7.4.2 (OBJ_id_it_signKeyPairTypes) */, + 300 /* 1.3.6.1.5.5.7.4.3 (OBJ_id_it_encKeyPairTypes) */, + 301 /* 1.3.6.1.5.5.7.4.4 (OBJ_id_it_preferredSymmAlg) */, + 302 /* 1.3.6.1.5.5.7.4.5 (OBJ_id_it_caKeyUpdateInfo) */, + 303 /* 1.3.6.1.5.5.7.4.6 (OBJ_id_it_currentCRL) */, + 304 /* 1.3.6.1.5.5.7.4.7 (OBJ_id_it_unsupportedOIDs) */, + 305 /* 1.3.6.1.5.5.7.4.8 (OBJ_id_it_subscriptionRequest) */, + 306 /* 1.3.6.1.5.5.7.4.9 (OBJ_id_it_subscriptionResponse) */, + 307 /* 1.3.6.1.5.5.7.4.10 (OBJ_id_it_keyPairParamReq) */, + 308 /* 1.3.6.1.5.5.7.4.11 (OBJ_id_it_keyPairParamRep) */, + 309 /* 1.3.6.1.5.5.7.4.12 (OBJ_id_it_revPassphrase) */, + 310 /* 1.3.6.1.5.5.7.4.13 (OBJ_id_it_implicitConfirm) */, + 311 /* 1.3.6.1.5.5.7.4.14 (OBJ_id_it_confirmWaitTime) */, + 312 /* 1.3.6.1.5.5.7.4.15 (OBJ_id_it_origPKIMessage) */, + 784 /* 1.3.6.1.5.5.7.4.16 (OBJ_id_it_suppLangTags) */, + 313 /* 1.3.6.1.5.5.7.5.1 (OBJ_id_regCtrl) */, + 314 /* 1.3.6.1.5.5.7.5.2 (OBJ_id_regInfo) */, + 323 /* 1.3.6.1.5.5.7.6.1 (OBJ_id_alg_des40) */, + 324 /* 1.3.6.1.5.5.7.6.2 (OBJ_id_alg_noSignature) */, + 325 /* 1.3.6.1.5.5.7.6.3 (OBJ_id_alg_dh_sig_hmac_sha1) */, + 326 /* 1.3.6.1.5.5.7.6.4 (OBJ_id_alg_dh_pop) */, + 327 /* 1.3.6.1.5.5.7.7.1 (OBJ_id_cmc_statusInfo) */, + 328 /* 1.3.6.1.5.5.7.7.2 (OBJ_id_cmc_identification) */, + 329 /* 1.3.6.1.5.5.7.7.3 (OBJ_id_cmc_identityProof) */, + 330 /* 1.3.6.1.5.5.7.7.4 (OBJ_id_cmc_dataReturn) */, + 331 /* 1.3.6.1.5.5.7.7.5 (OBJ_id_cmc_transactionId) */, + 332 /* 1.3.6.1.5.5.7.7.6 (OBJ_id_cmc_senderNonce) */, + 333 /* 1.3.6.1.5.5.7.7.7 (OBJ_id_cmc_recipientNonce) */, + 334 /* 1.3.6.1.5.5.7.7.8 (OBJ_id_cmc_addExtensions) */, + 335 /* 1.3.6.1.5.5.7.7.9 (OBJ_id_cmc_encryptedPOP) */, + 336 /* 1.3.6.1.5.5.7.7.10 (OBJ_id_cmc_decryptedPOP) */, + 337 /* 1.3.6.1.5.5.7.7.11 (OBJ_id_cmc_lraPOPWitness) */, + 338 /* 1.3.6.1.5.5.7.7.15 (OBJ_id_cmc_getCert) */, + 339 /* 1.3.6.1.5.5.7.7.16 (OBJ_id_cmc_getCRL) */, + 340 /* 1.3.6.1.5.5.7.7.17 (OBJ_id_cmc_revokeRequest) */, + 341 /* 1.3.6.1.5.5.7.7.18 (OBJ_id_cmc_regInfo) */, + 342 /* 1.3.6.1.5.5.7.7.19 (OBJ_id_cmc_responseInfo) */, + 343 /* 1.3.6.1.5.5.7.7.21 (OBJ_id_cmc_queryPending) */, + 344 /* 1.3.6.1.5.5.7.7.22 (OBJ_id_cmc_popLinkRandom) */, + 345 /* 1.3.6.1.5.5.7.7.23 (OBJ_id_cmc_popLinkWitness) */, + 346 /* 1.3.6.1.5.5.7.7.24 (OBJ_id_cmc_confirmCertAcceptance) */, + 347 /* 1.3.6.1.5.5.7.8.1 (OBJ_id_on_personalData) */, + 858 /* 1.3.6.1.5.5.7.8.3 (OBJ_id_on_permanentIdentifier) */, + 348 /* 1.3.6.1.5.5.7.9.1 (OBJ_id_pda_dateOfBirth) */, + 349 /* 1.3.6.1.5.5.7.9.2 (OBJ_id_pda_placeOfBirth) */, + 351 /* 1.3.6.1.5.5.7.9.3 (OBJ_id_pda_gender) */, + 352 /* 1.3.6.1.5.5.7.9.4 (OBJ_id_pda_countryOfCitizenship) */, + 353 /* 1.3.6.1.5.5.7.9.5 (OBJ_id_pda_countryOfResidence) */, + 354 /* 1.3.6.1.5.5.7.10.1 (OBJ_id_aca_authenticationInfo) */, + 355 /* 1.3.6.1.5.5.7.10.2 (OBJ_id_aca_accessIdentity) */, + 356 /* 1.3.6.1.5.5.7.10.3 (OBJ_id_aca_chargingIdentity) */, + 357 /* 1.3.6.1.5.5.7.10.4 (OBJ_id_aca_group) */, + 358 /* 1.3.6.1.5.5.7.10.5 (OBJ_id_aca_role) */, + 399 /* 1.3.6.1.5.5.7.10.6 (OBJ_id_aca_encAttrs) */, + 359 /* 1.3.6.1.5.5.7.11.1 (OBJ_id_qcs_pkixQCSyntax_v1) */, + 360 /* 1.3.6.1.5.5.7.12.1 (OBJ_id_cct_crs) */, + 361 /* 1.3.6.1.5.5.7.12.2 (OBJ_id_cct_PKIData) */, + 362 /* 1.3.6.1.5.5.7.12.3 (OBJ_id_cct_PKIResponse) */, + 664 /* 1.3.6.1.5.5.7.21.0 (OBJ_id_ppl_anyLanguage) */, + 665 /* 1.3.6.1.5.5.7.21.1 (OBJ_id_ppl_inheritAll) */, + 667 /* 1.3.6.1.5.5.7.21.2 (OBJ_Independent) */, + 178 /* 1.3.6.1.5.5.7.48.1 (OBJ_ad_OCSP) */, + 179 /* 1.3.6.1.5.5.7.48.2 (OBJ_ad_ca_issuers) */, + 363 /* 1.3.6.1.5.5.7.48.3 (OBJ_ad_timeStamping) */, + 364 /* 1.3.6.1.5.5.7.48.4 (OBJ_ad_dvcs) */, + 785 /* 1.3.6.1.5.5.7.48.5 (OBJ_caRepository) */, + 780 /* 1.3.6.1.5.5.8.1.1 (OBJ_hmac_md5) */, + 781 /* 1.3.6.1.5.5.8.1.2 (OBJ_hmac_sha1) */, + 58 /* 2.16.840.1.113730.1 (OBJ_netscape_cert_extension) */, + 59 /* 2.16.840.1.113730.2 (OBJ_netscape_data_type) */, + 438 /* 0.9.2342.19200300.100.1 (OBJ_pilotAttributeType) */, + 439 /* 0.9.2342.19200300.100.3 (OBJ_pilotAttributeSyntax) */, + 440 /* 0.9.2342.19200300.100.4 (OBJ_pilotObjectClass) */, + 441 /* 0.9.2342.19200300.100.10 (OBJ_pilotGroups) */, + 108 /* 1.2.840.113533.7.66.10 (OBJ_cast5_cbc) */, + 112 /* 1.2.840.113533.7.66.12 (OBJ_pbeWithMD5AndCast5_CBC) */, + 782 /* 1.2.840.113533.7.66.13 (OBJ_id_PasswordBasedMAC) */, + 783 /* 1.2.840.113533.7.66.30 (OBJ_id_DHBasedMac) */, + 6 /* 1.2.840.113549.1.1.1 (OBJ_rsaEncryption) */, + 7 /* 1.2.840.113549.1.1.2 (OBJ_md2WithRSAEncryption) */, + 396 /* 1.2.840.113549.1.1.3 (OBJ_md4WithRSAEncryption) */, + 8 /* 1.2.840.113549.1.1.4 (OBJ_md5WithRSAEncryption) */, + 65 /* 1.2.840.113549.1.1.5 (OBJ_sha1WithRSAEncryption) */, + 644 /* 1.2.840.113549.1.1.6 (OBJ_rsaOAEPEncryptionSET) */, + 919 /* 1.2.840.113549.1.1.7 (OBJ_rsaesOaep) */, + 911 /* 1.2.840.113549.1.1.8 (OBJ_mgf1) */, + 935 /* 1.2.840.113549.1.1.9 (OBJ_pSpecified) */, + 912 /* 1.2.840.113549.1.1.10 (OBJ_rsassaPss) */, + 668 /* 1.2.840.113549.1.1.11 (OBJ_sha256WithRSAEncryption) */, + 669 /* 1.2.840.113549.1.1.12 (OBJ_sha384WithRSAEncryption) */, + 670 /* 1.2.840.113549.1.1.13 (OBJ_sha512WithRSAEncryption) */, + 671 /* 1.2.840.113549.1.1.14 (OBJ_sha224WithRSAEncryption) */, + 28 /* 1.2.840.113549.1.3.1 (OBJ_dhKeyAgreement) */, + 9 /* 1.2.840.113549.1.5.1 (OBJ_pbeWithMD2AndDES_CBC) */, + 10 /* 1.2.840.113549.1.5.3 (OBJ_pbeWithMD5AndDES_CBC) */, + 168 /* 1.2.840.113549.1.5.4 (OBJ_pbeWithMD2AndRC2_CBC) */, + 169 /* 1.2.840.113549.1.5.6 (OBJ_pbeWithMD5AndRC2_CBC) */, + 170 /* 1.2.840.113549.1.5.10 (OBJ_pbeWithSHA1AndDES_CBC) */, + 68 /* 1.2.840.113549.1.5.11 (OBJ_pbeWithSHA1AndRC2_CBC) */, + 69 /* 1.2.840.113549.1.5.12 (OBJ_id_pbkdf2) */, + 161 /* 1.2.840.113549.1.5.13 (OBJ_pbes2) */, + 162 /* 1.2.840.113549.1.5.14 (OBJ_pbmac1) */, + 21 /* 1.2.840.113549.1.7.1 (OBJ_pkcs7_data) */, + 22 /* 1.2.840.113549.1.7.2 (OBJ_pkcs7_signed) */, + 23 /* 1.2.840.113549.1.7.3 (OBJ_pkcs7_enveloped) */, + 24 /* 1.2.840.113549.1.7.4 (OBJ_pkcs7_signedAndEnveloped) */, + 25 /* 1.2.840.113549.1.7.5 (OBJ_pkcs7_digest) */, + 26 /* 1.2.840.113549.1.7.6 (OBJ_pkcs7_encrypted) */, + 48 /* 1.2.840.113549.1.9.1 (OBJ_pkcs9_emailAddress) */, + 49 /* 1.2.840.113549.1.9.2 (OBJ_pkcs9_unstructuredName) */, + 50 /* 1.2.840.113549.1.9.3 (OBJ_pkcs9_contentType) */, + 51 /* 1.2.840.113549.1.9.4 (OBJ_pkcs9_messageDigest) */, + 52 /* 1.2.840.113549.1.9.5 (OBJ_pkcs9_signingTime) */, + 53 /* 1.2.840.113549.1.9.6 (OBJ_pkcs9_countersignature) */, + 54 /* 1.2.840.113549.1.9.7 (OBJ_pkcs9_challengePassword) */, + 55 /* 1.2.840.113549.1.9.8 (OBJ_pkcs9_unstructuredAddress) */, + 56 /* 1.2.840.113549.1.9.9 (OBJ_pkcs9_extCertAttributes) */, + 172 /* 1.2.840.113549.1.9.14 (OBJ_ext_req) */, + 167 /* 1.2.840.113549.1.9.15 (OBJ_SMIMECapabilities) */, + 188 /* 1.2.840.113549.1.9.16 (OBJ_SMIME) */, + 156 /* 1.2.840.113549.1.9.20 (OBJ_friendlyName) */, + 157 /* 1.2.840.113549.1.9.21 (OBJ_localKeyID) */, + 681 /* 1.2.840.10045.1.2.3.1 (OBJ_X9_62_onBasis) */, + 682 /* 1.2.840.10045.1.2.3.2 (OBJ_X9_62_tpBasis) */, + 683 /* 1.2.840.10045.1.2.3.3 (OBJ_X9_62_ppBasis) */, + 417 /* 1.3.6.1.4.1.311.17.1 (OBJ_ms_csp_name) */, + 856 /* 1.3.6.1.4.1.311.17.2 (OBJ_LocalKeySet) */, + 390 /* 1.3.6.1.4.1.1466.344 (OBJ_dcObject) */, + 91 /* 1.3.6.1.4.1.3029.1.2 (OBJ_bf_cbc) */, + 315 /* 1.3.6.1.5.5.7.5.1.1 (OBJ_id_regCtrl_regToken) */, + 316 /* 1.3.6.1.5.5.7.5.1.2 (OBJ_id_regCtrl_authenticator) */, + 317 /* 1.3.6.1.5.5.7.5.1.3 (OBJ_id_regCtrl_pkiPublicationInfo) */, + 318 /* 1.3.6.1.5.5.7.5.1.4 (OBJ_id_regCtrl_pkiArchiveOptions) */, + 319 /* 1.3.6.1.5.5.7.5.1.5 (OBJ_id_regCtrl_oldCertID) */, + 320 /* 1.3.6.1.5.5.7.5.1.6 (OBJ_id_regCtrl_protocolEncrKey) */, + 321 /* 1.3.6.1.5.5.7.5.2.1 (OBJ_id_regInfo_utf8Pairs) */, + 322 /* 1.3.6.1.5.5.7.5.2.2 (OBJ_id_regInfo_certReq) */, + 365 /* 1.3.6.1.5.5.7.48.1.1 (OBJ_id_pkix_OCSP_basic) */, + 366 /* 1.3.6.1.5.5.7.48.1.2 (OBJ_id_pkix_OCSP_Nonce) */, + 367 /* 1.3.6.1.5.5.7.48.1.3 (OBJ_id_pkix_OCSP_CrlID) */, + 368 /* 1.3.6.1.5.5.7.48.1.4 (OBJ_id_pkix_OCSP_acceptableResponses) */, + 369 /* 1.3.6.1.5.5.7.48.1.5 (OBJ_id_pkix_OCSP_noCheck) */, + 370 /* 1.3.6.1.5.5.7.48.1.6 (OBJ_id_pkix_OCSP_archiveCutoff) */, + 371 /* 1.3.6.1.5.5.7.48.1.7 (OBJ_id_pkix_OCSP_serviceLocator) */, + 372 /* 1.3.6.1.5.5.7.48.1.8 (OBJ_id_pkix_OCSP_extendedStatus) */, + 373 /* 1.3.6.1.5.5.7.48.1.9 (OBJ_id_pkix_OCSP_valid) */, + 374 /* 1.3.6.1.5.5.7.48.1.10 (OBJ_id_pkix_OCSP_path) */, + 375 /* 1.3.6.1.5.5.7.48.1.11 (OBJ_id_pkix_OCSP_trustRoot) */, + 921 /* 1.3.36.3.3.2.8.1.1.1 (OBJ_brainpoolP160r1) */, + 922 /* 1.3.36.3.3.2.8.1.1.2 (OBJ_brainpoolP160t1) */, + 923 /* 1.3.36.3.3.2.8.1.1.3 (OBJ_brainpoolP192r1) */, + 924 /* 1.3.36.3.3.2.8.1.1.4 (OBJ_brainpoolP192t1) */, + 925 /* 1.3.36.3.3.2.8.1.1.5 (OBJ_brainpoolP224r1) */, + 926 /* 1.3.36.3.3.2.8.1.1.6 (OBJ_brainpoolP224t1) */, + 927 /* 1.3.36.3.3.2.8.1.1.7 (OBJ_brainpoolP256r1) */, + 928 /* 1.3.36.3.3.2.8.1.1.8 (OBJ_brainpoolP256t1) */, + 929 /* 1.3.36.3.3.2.8.1.1.9 (OBJ_brainpoolP320r1) */, + 930 /* 1.3.36.3.3.2.8.1.1.10 (OBJ_brainpoolP320t1) */, + 931 /* 1.3.36.3.3.2.8.1.1.11 (OBJ_brainpoolP384r1) */, + 932 /* 1.3.36.3.3.2.8.1.1.12 (OBJ_brainpoolP384t1) */, + 933 /* 1.3.36.3.3.2.8.1.1.13 (OBJ_brainpoolP512r1) */, + 934 /* 1.3.36.3.3.2.8.1.1.14 (OBJ_brainpoolP512t1) */, + 936 /* 1.3.133.16.840.63.0.2 (OBJ_dhSinglePass_stdDH_sha1kdf_scheme) */, + 941 /* 1.3.133.16.840.63.0.3 (OBJ_dhSinglePass_cofactorDH_sha1kdf_scheme) */ + , + 418 /* 2.16.840.1.101.3.4.1.1 (OBJ_aes_128_ecb) */, + 419 /* 2.16.840.1.101.3.4.1.2 (OBJ_aes_128_cbc) */, + 420 /* 2.16.840.1.101.3.4.1.3 (OBJ_aes_128_ofb128) */, + 421 /* 2.16.840.1.101.3.4.1.4 (OBJ_aes_128_cfb128) */, + 788 /* 2.16.840.1.101.3.4.1.5 (OBJ_id_aes128_wrap) */, + 895 /* 2.16.840.1.101.3.4.1.6 (OBJ_aes_128_gcm) */, + 896 /* 2.16.840.1.101.3.4.1.7 (OBJ_aes_128_ccm) */, + 897 /* 2.16.840.1.101.3.4.1.8 (OBJ_id_aes128_wrap_pad) */, + 422 /* 2.16.840.1.101.3.4.1.21 (OBJ_aes_192_ecb) */, + 423 /* 2.16.840.1.101.3.4.1.22 (OBJ_aes_192_cbc) */, + 424 /* 2.16.840.1.101.3.4.1.23 (OBJ_aes_192_ofb128) */, + 425 /* 2.16.840.1.101.3.4.1.24 (OBJ_aes_192_cfb128) */, + 789 /* 2.16.840.1.101.3.4.1.25 (OBJ_id_aes192_wrap) */, + 898 /* 2.16.840.1.101.3.4.1.26 (OBJ_aes_192_gcm) */, + 899 /* 2.16.840.1.101.3.4.1.27 (OBJ_aes_192_ccm) */, + 900 /* 2.16.840.1.101.3.4.1.28 (OBJ_id_aes192_wrap_pad) */, + 426 /* 2.16.840.1.101.3.4.1.41 (OBJ_aes_256_ecb) */, + 427 /* 2.16.840.1.101.3.4.1.42 (OBJ_aes_256_cbc) */, + 428 /* 2.16.840.1.101.3.4.1.43 (OBJ_aes_256_ofb128) */, + 429 /* 2.16.840.1.101.3.4.1.44 (OBJ_aes_256_cfb128) */, + 790 /* 2.16.840.1.101.3.4.1.45 (OBJ_id_aes256_wrap) */, + 901 /* 2.16.840.1.101.3.4.1.46 (OBJ_aes_256_gcm) */, + 902 /* 2.16.840.1.101.3.4.1.47 (OBJ_aes_256_ccm) */, + 903 /* 2.16.840.1.101.3.4.1.48 (OBJ_id_aes256_wrap_pad) */, + 672 /* 2.16.840.1.101.3.4.2.1 (OBJ_sha256) */, + 673 /* 2.16.840.1.101.3.4.2.2 (OBJ_sha384) */, + 674 /* 2.16.840.1.101.3.4.2.3 (OBJ_sha512) */, + 675 /* 2.16.840.1.101.3.4.2.4 (OBJ_sha224) */, + 802 /* 2.16.840.1.101.3.4.3.1 (OBJ_dsa_with_SHA224) */, + 803 /* 2.16.840.1.101.3.4.3.2 (OBJ_dsa_with_SHA256) */, + 71 /* 2.16.840.1.113730.1.1 (OBJ_netscape_cert_type) */, + 72 /* 2.16.840.1.113730.1.2 (OBJ_netscape_base_url) */, + 73 /* 2.16.840.1.113730.1.3 (OBJ_netscape_revocation_url) */, + 74 /* 2.16.840.1.113730.1.4 (OBJ_netscape_ca_revocation_url) */, + 75 /* 2.16.840.1.113730.1.7 (OBJ_netscape_renewal_url) */, + 76 /* 2.16.840.1.113730.1.8 (OBJ_netscape_ca_policy_url) */, + 77 /* 2.16.840.1.113730.1.12 (OBJ_netscape_ssl_server_name) */, + 78 /* 2.16.840.1.113730.1.13 (OBJ_netscape_comment) */, + 79 /* 2.16.840.1.113730.2.5 (OBJ_netscape_cert_sequence) */, + 139 /* 2.16.840.1.113730.4.1 (OBJ_ns_sgc) */, + 458 /* 0.9.2342.19200300.100.1.1 (OBJ_userId) */, + 459 /* 0.9.2342.19200300.100.1.2 (OBJ_textEncodedORAddress) */, + 460 /* 0.9.2342.19200300.100.1.3 (OBJ_rfc822Mailbox) */, + 461 /* 0.9.2342.19200300.100.1.4 (OBJ_info) */, + 462 /* 0.9.2342.19200300.100.1.5 (OBJ_favouriteDrink) */, + 463 /* 0.9.2342.19200300.100.1.6 (OBJ_roomNumber) */, + 464 /* 0.9.2342.19200300.100.1.7 (OBJ_photo) */, + 465 /* 0.9.2342.19200300.100.1.8 (OBJ_userClass) */, + 466 /* 0.9.2342.19200300.100.1.9 (OBJ_host) */, + 467 /* 0.9.2342.19200300.100.1.10 (OBJ_manager) */, + 468 /* 0.9.2342.19200300.100.1.11 (OBJ_documentIdentifier) */, + 469 /* 0.9.2342.19200300.100.1.12 (OBJ_documentTitle) */, + 470 /* 0.9.2342.19200300.100.1.13 (OBJ_documentVersion) */, + 471 /* 0.9.2342.19200300.100.1.14 (OBJ_documentAuthor) */, + 472 /* 0.9.2342.19200300.100.1.15 (OBJ_documentLocation) */, + 473 /* 0.9.2342.19200300.100.1.20 (OBJ_homeTelephoneNumber) */, + 474 /* 0.9.2342.19200300.100.1.21 (OBJ_secretary) */, + 475 /* 0.9.2342.19200300.100.1.22 (OBJ_otherMailbox) */, + 476 /* 0.9.2342.19200300.100.1.23 (OBJ_lastModifiedTime) */, + 477 /* 0.9.2342.19200300.100.1.24 (OBJ_lastModifiedBy) */, + 391 /* 0.9.2342.19200300.100.1.25 (OBJ_domainComponent) */, + 478 /* 0.9.2342.19200300.100.1.26 (OBJ_aRecord) */, + 479 /* 0.9.2342.19200300.100.1.27 (OBJ_pilotAttributeType27) */, + 480 /* 0.9.2342.19200300.100.1.28 (OBJ_mXRecord) */, + 481 /* 0.9.2342.19200300.100.1.29 (OBJ_nSRecord) */, + 482 /* 0.9.2342.19200300.100.1.30 (OBJ_sOARecord) */, + 483 /* 0.9.2342.19200300.100.1.31 (OBJ_cNAMERecord) */, + 484 /* 0.9.2342.19200300.100.1.37 (OBJ_associatedDomain) */, + 485 /* 0.9.2342.19200300.100.1.38 (OBJ_associatedName) */, + 486 /* 0.9.2342.19200300.100.1.39 (OBJ_homePostalAddress) */, + 487 /* 0.9.2342.19200300.100.1.40 (OBJ_personalTitle) */, + 488 /* 0.9.2342.19200300.100.1.41 (OBJ_mobileTelephoneNumber) */, + 489 /* 0.9.2342.19200300.100.1.42 (OBJ_pagerTelephoneNumber) */, + 490 /* 0.9.2342.19200300.100.1.43 (OBJ_friendlyCountryName) */, + 491 /* 0.9.2342.19200300.100.1.45 (OBJ_organizationalStatus) */, + 492 /* 0.9.2342.19200300.100.1.46 (OBJ_janetMailbox) */, + 493 /* 0.9.2342.19200300.100.1.47 (OBJ_mailPreferenceOption) */, + 494 /* 0.9.2342.19200300.100.1.48 (OBJ_buildingName) */, + 495 /* 0.9.2342.19200300.100.1.49 (OBJ_dSAQuality) */, + 496 /* 0.9.2342.19200300.100.1.50 (OBJ_singleLevelQuality) */, + 497 /* 0.9.2342.19200300.100.1.51 (OBJ_subtreeMinimumQuality) */, + 498 /* 0.9.2342.19200300.100.1.52 (OBJ_subtreeMaximumQuality) */, + 499 /* 0.9.2342.19200300.100.1.53 (OBJ_personalSignature) */, + 500 /* 0.9.2342.19200300.100.1.54 (OBJ_dITRedirect) */, + 501 /* 0.9.2342.19200300.100.1.55 (OBJ_audio) */, + 502 /* 0.9.2342.19200300.100.1.56 (OBJ_documentPublisher) */, + 442 /* 0.9.2342.19200300.100.3.4 (OBJ_iA5StringSyntax) */, + 443 /* 0.9.2342.19200300.100.3.5 (OBJ_caseIgnoreIA5StringSyntax) */, + 444 /* 0.9.2342.19200300.100.4.3 (OBJ_pilotObject) */, + 445 /* 0.9.2342.19200300.100.4.4 (OBJ_pilotPerson) */, + 446 /* 0.9.2342.19200300.100.4.5 (OBJ_account) */, + 447 /* 0.9.2342.19200300.100.4.6 (OBJ_document) */, + 448 /* 0.9.2342.19200300.100.4.7 (OBJ_room) */, + 449 /* 0.9.2342.19200300.100.4.9 (OBJ_documentSeries) */, + 392 /* 0.9.2342.19200300.100.4.13 (OBJ_Domain) */, + 450 /* 0.9.2342.19200300.100.4.14 (OBJ_rFC822localPart) */, + 451 /* 0.9.2342.19200300.100.4.15 (OBJ_dNSDomain) */, + 452 /* 0.9.2342.19200300.100.4.17 (OBJ_domainRelatedObject) */, + 453 /* 0.9.2342.19200300.100.4.18 (OBJ_friendlyCountry) */, + 454 /* 0.9.2342.19200300.100.4.19 (OBJ_simpleSecurityObject) */, + 455 /* 0.9.2342.19200300.100.4.20 (OBJ_pilotOrganization) */, + 456 /* 0.9.2342.19200300.100.4.21 (OBJ_pilotDSA) */, + 457 /* 0.9.2342.19200300.100.4.22 (OBJ_qualityLabelledData) */, + 189 /* 1.2.840.113549.1.9.16.0 (OBJ_id_smime_mod) */, + 190 /* 1.2.840.113549.1.9.16.1 (OBJ_id_smime_ct) */, + 191 /* 1.2.840.113549.1.9.16.2 (OBJ_id_smime_aa) */, + 192 /* 1.2.840.113549.1.9.16.3 (OBJ_id_smime_alg) */, + 193 /* 1.2.840.113549.1.9.16.4 (OBJ_id_smime_cd) */, + 194 /* 1.2.840.113549.1.9.16.5 (OBJ_id_smime_spq) */, + 195 /* 1.2.840.113549.1.9.16.6 (OBJ_id_smime_cti) */, + 158 /* 1.2.840.113549.1.9.22.1 (OBJ_x509Certificate) */, + 159 /* 1.2.840.113549.1.9.22.2 (OBJ_sdsiCertificate) */, + 160 /* 1.2.840.113549.1.9.23.1 (OBJ_x509Crl) */, + 144 /* 1.2.840.113549.1.12.1.1 (OBJ_pbe_WithSHA1And128BitRC4) */, + 145 /* 1.2.840.113549.1.12.1.2 (OBJ_pbe_WithSHA1And40BitRC4) */, + 146 /* 1.2.840.113549.1.12.1.3 (OBJ_pbe_WithSHA1And3_Key_TripleDES_CBC) */, + 147 /* 1.2.840.113549.1.12.1.4 (OBJ_pbe_WithSHA1And2_Key_TripleDES_CBC) */, + 148 /* 1.2.840.113549.1.12.1.5 (OBJ_pbe_WithSHA1And128BitRC2_CBC) */, + 149 /* 1.2.840.113549.1.12.1.6 (OBJ_pbe_WithSHA1And40BitRC2_CBC) */, + 171 /* 1.3.6.1.4.1.311.2.1.14 (OBJ_ms_ext_req) */, + 134 /* 1.3.6.1.4.1.311.2.1.21 (OBJ_ms_code_ind) */, + 135 /* 1.3.6.1.4.1.311.2.1.22 (OBJ_ms_code_com) */, + 136 /* 1.3.6.1.4.1.311.10.3.1 (OBJ_ms_ctl_sign) */, + 137 /* 1.3.6.1.4.1.311.10.3.3 (OBJ_ms_sgc) */, + 138 /* 1.3.6.1.4.1.311.10.3.4 (OBJ_ms_efs) */, + 648 /* 1.3.6.1.4.1.311.20.2.2 (OBJ_ms_smartcard_login) */, + 649 /* 1.3.6.1.4.1.311.20.2.3 (OBJ_ms_upn) */, + 751 /* 1.2.392.200011.61.1.1.1.2 (OBJ_camellia_128_cbc) */, + 752 /* 1.2.392.200011.61.1.1.1.3 (OBJ_camellia_192_cbc) */, + 753 /* 1.2.392.200011.61.1.1.1.4 (OBJ_camellia_256_cbc) */, + 907 /* 1.2.392.200011.61.1.1.3.2 (OBJ_id_camellia128_wrap) */, + 908 /* 1.2.392.200011.61.1.1.3.3 (OBJ_id_camellia192_wrap) */, + 909 /* 1.2.392.200011.61.1.1.3.4 (OBJ_id_camellia256_wrap) */, + 196 /* 1.2.840.113549.1.9.16.0.1 (OBJ_id_smime_mod_cms) */, + 197 /* 1.2.840.113549.1.9.16.0.2 (OBJ_id_smime_mod_ess) */, + 198 /* 1.2.840.113549.1.9.16.0.3 (OBJ_id_smime_mod_oid) */, + 199 /* 1.2.840.113549.1.9.16.0.4 (OBJ_id_smime_mod_msg_v3) */, + 200 /* 1.2.840.113549.1.9.16.0.5 (OBJ_id_smime_mod_ets_eSignature_88) */, + 201 /* 1.2.840.113549.1.9.16.0.6 (OBJ_id_smime_mod_ets_eSignature_97) */, + 202 /* 1.2.840.113549.1.9.16.0.7 (OBJ_id_smime_mod_ets_eSigPolicy_88) */, + 203 /* 1.2.840.113549.1.9.16.0.8 (OBJ_id_smime_mod_ets_eSigPolicy_97) */, + 204 /* 1.2.840.113549.1.9.16.1.1 (OBJ_id_smime_ct_receipt) */, + 205 /* 1.2.840.113549.1.9.16.1.2 (OBJ_id_smime_ct_authData) */, + 206 /* 1.2.840.113549.1.9.16.1.3 (OBJ_id_smime_ct_publishCert) */, + 207 /* 1.2.840.113549.1.9.16.1.4 (OBJ_id_smime_ct_TSTInfo) */, + 208 /* 1.2.840.113549.1.9.16.1.5 (OBJ_id_smime_ct_TDTInfo) */, + 209 /* 1.2.840.113549.1.9.16.1.6 (OBJ_id_smime_ct_contentInfo) */, + 210 /* 1.2.840.113549.1.9.16.1.7 (OBJ_id_smime_ct_DVCSRequestData) */, + 211 /* 1.2.840.113549.1.9.16.1.8 (OBJ_id_smime_ct_DVCSResponseData) */, + 786 /* 1.2.840.113549.1.9.16.1.9 (OBJ_id_smime_ct_compressedData) */, + 787 /* 1.2.840.113549.1.9.16.1.27 (OBJ_id_ct_asciiTextWithCRLF) */, + 212 /* 1.2.840.113549.1.9.16.2.1 (OBJ_id_smime_aa_receiptRequest) */, + 213 /* 1.2.840.113549.1.9.16.2.2 (OBJ_id_smime_aa_securityLabel) */, + 214 /* 1.2.840.113549.1.9.16.2.3 (OBJ_id_smime_aa_mlExpandHistory) */, + 215 /* 1.2.840.113549.1.9.16.2.4 (OBJ_id_smime_aa_contentHint) */, + 216 /* 1.2.840.113549.1.9.16.2.5 (OBJ_id_smime_aa_msgSigDigest) */, + 217 /* 1.2.840.113549.1.9.16.2.6 (OBJ_id_smime_aa_encapContentType) */, + 218 /* 1.2.840.113549.1.9.16.2.7 (OBJ_id_smime_aa_contentIdentifier) */, + 219 /* 1.2.840.113549.1.9.16.2.8 (OBJ_id_smime_aa_macValue) */, + 220 /* 1.2.840.113549.1.9.16.2.9 (OBJ_id_smime_aa_equivalentLabels) */, + 221 /* 1.2.840.113549.1.9.16.2.10 (OBJ_id_smime_aa_contentReference) */, + 222 /* 1.2.840.113549.1.9.16.2.11 (OBJ_id_smime_aa_encrypKeyPref) */, + 223 /* 1.2.840.113549.1.9.16.2.12 (OBJ_id_smime_aa_signingCertificate) */, + 224 /* 1.2.840.113549.1.9.16.2.13 (OBJ_id_smime_aa_smimeEncryptCerts) */, + 225 /* 1.2.840.113549.1.9.16.2.14 (OBJ_id_smime_aa_timeStampToken) */, + 226 /* 1.2.840.113549.1.9.16.2.15 (OBJ_id_smime_aa_ets_sigPolicyId) */, + 227 /* 1.2.840.113549.1.9.16.2.16 (OBJ_id_smime_aa_ets_commitmentType) */, + 228 /* 1.2.840.113549.1.9.16.2.17 (OBJ_id_smime_aa_ets_signerLocation) */, + 229 /* 1.2.840.113549.1.9.16.2.18 (OBJ_id_smime_aa_ets_signerAttr) */, + 230 /* 1.2.840.113549.1.9.16.2.19 (OBJ_id_smime_aa_ets_otherSigCert) */, + 231 /* 1.2.840.113549.1.9.16.2.20 (OBJ_id_smime_aa_ets_contentTimestamp) */, + 232 /* 1.2.840.113549.1.9.16.2.21 (OBJ_id_smime_aa_ets_CertificateRefs) */, + 233 /* 1.2.840.113549.1.9.16.2.22 (OBJ_id_smime_aa_ets_RevocationRefs) */, + 234 /* 1.2.840.113549.1.9.16.2.23 (OBJ_id_smime_aa_ets_certValues) */, + 235 /* 1.2.840.113549.1.9.16.2.24 (OBJ_id_smime_aa_ets_revocationValues) */, + 236 /* 1.2.840.113549.1.9.16.2.25 (OBJ_id_smime_aa_ets_escTimeStamp) */, + 237 /* 1.2.840.113549.1.9.16.2.26 (OBJ_id_smime_aa_ets_certCRLTimestamp) */, + 238 /* 1.2.840.113549.1.9.16.2.27 (OBJ_id_smime_aa_ets_archiveTimeStamp) */, + 239 /* 1.2.840.113549.1.9.16.2.28 (OBJ_id_smime_aa_signatureType) */, + 240 /* 1.2.840.113549.1.9.16.2.29 (OBJ_id_smime_aa_dvcs_dvc) */, + 241 /* 1.2.840.113549.1.9.16.3.1 (OBJ_id_smime_alg_ESDHwith3DES) */, + 242 /* 1.2.840.113549.1.9.16.3.2 (OBJ_id_smime_alg_ESDHwithRC2) */, + 243 /* 1.2.840.113549.1.9.16.3.3 (OBJ_id_smime_alg_3DESwrap) */, + 244 /* 1.2.840.113549.1.9.16.3.4 (OBJ_id_smime_alg_RC2wrap) */, + 245 /* 1.2.840.113549.1.9.16.3.5 (OBJ_id_smime_alg_ESDH) */, + 246 /* 1.2.840.113549.1.9.16.3.6 (OBJ_id_smime_alg_CMS3DESwrap) */, + 247 /* 1.2.840.113549.1.9.16.3.7 (OBJ_id_smime_alg_CMSRC2wrap) */, + 125 /* 1.2.840.113549.1.9.16.3.8 (OBJ_zlib_compression) */, + 893 /* 1.2.840.113549.1.9.16.3.9 (OBJ_id_alg_PWRI_KEK) */, + 248 /* 1.2.840.113549.1.9.16.4.1 (OBJ_id_smime_cd_ldap) */, + 249 /* 1.2.840.113549.1.9.16.5.1 (OBJ_id_smime_spq_ets_sqt_uri) */, + 250 /* 1.2.840.113549.1.9.16.5.2 (OBJ_id_smime_spq_ets_sqt_unotice) */, + 251 /* 1.2.840.113549.1.9.16.6.1 (OBJ_id_smime_cti_ets_proofOfOrigin) */, + 252 /* 1.2.840.113549.1.9.16.6.2 (OBJ_id_smime_cti_ets_proofOfReceipt) */, + 253 /* 1.2.840.113549.1.9.16.6.3 (OBJ_id_smime_cti_ets_proofOfDelivery) */, + 254 /* 1.2.840.113549.1.9.16.6.4 (OBJ_id_smime_cti_ets_proofOfSender) */, + 255 /* 1.2.840.113549.1.9.16.6.5 (OBJ_id_smime_cti_ets_proofOfApproval) */, + 256 /* 1.2.840.113549.1.9.16.6.6 (OBJ_id_smime_cti_ets_proofOfCreation) */, + 150 /* 1.2.840.113549.1.12.10.1.1 (OBJ_keyBag) */, + 151 /* 1.2.840.113549.1.12.10.1.2 (OBJ_pkcs8ShroudedKeyBag) */, + 152 /* 1.2.840.113549.1.12.10.1.3 (OBJ_certBag) */, + 153 /* 1.2.840.113549.1.12.10.1.4 (OBJ_crlBag) */, + 154 /* 1.2.840.113549.1.12.10.1.5 (OBJ_secretBag) */, + 155 /* 1.2.840.113549.1.12.10.1.6 (OBJ_safeContentsBag) */, + 34 /* 1.3.6.1.4.1.188.7.1.1.2 (OBJ_idea_cbc) */, +}; diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/obj/obj_dat.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/obj/obj_dat.h.grpc_back new file mode 100644 index 0000000..dceaf03 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/obj/obj_dat.h.grpc_back @@ -0,0 +1,6244 @@ +/* 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.] */ + +/* This file is generated by crypto/obj/objects.go. */ + + +#define NUM_NID 959 + +static const uint8_t kObjectData[] = { + /* NID_rsadsi */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, + /* NID_pkcs */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, + /* NID_md2 */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x02, + /* NID_md5 */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x05, + /* NID_rc4 */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x03, 0x04, + /* NID_rsaEncryption */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, + /* NID_md2WithRSAEncryption */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x02, + /* NID_md5WithRSAEncryption */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x04, + /* NID_pbeWithMD2AndDES_CBC */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x05, 0x01, + /* NID_pbeWithMD5AndDES_CBC */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x05, 0x03, + /* NID_X500 */ + 0x55, + /* NID_X509 */ + 0x55, 0x04, + /* NID_commonName */ + 0x55, 0x04, 0x03, + /* NID_countryName */ + 0x55, 0x04, 0x06, + /* NID_localityName */ + 0x55, 0x04, 0x07, + /* NID_stateOrProvinceName */ + 0x55, 0x04, 0x08, + /* NID_organizationName */ + 0x55, 0x04, 0x0a, + /* NID_organizationalUnitName */ + 0x55, 0x04, 0x0b, + /* NID_rsa */ + 0x55, 0x08, 0x01, 0x01, + /* NID_pkcs7 */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, + /* NID_pkcs7_data */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, + /* NID_pkcs7_signed */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, + /* NID_pkcs7_enveloped */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x03, + /* NID_pkcs7_signedAndEnveloped */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x04, + /* NID_pkcs7_digest */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x05, + /* NID_pkcs7_encrypted */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x06, + /* NID_pkcs3 */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x03, + /* NID_dhKeyAgreement */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x03, 0x01, + /* NID_des_ecb */ + 0x2b, 0x0e, 0x03, 0x02, 0x06, + /* NID_des_cfb64 */ + 0x2b, 0x0e, 0x03, 0x02, 0x09, + /* NID_des_cbc */ + 0x2b, 0x0e, 0x03, 0x02, 0x07, + /* NID_des_ede_ecb */ + 0x2b, 0x0e, 0x03, 0x02, 0x11, + /* NID_idea_cbc */ + 0x2b, 0x06, 0x01, 0x04, 0x01, 0x81, 0x3c, 0x07, 0x01, 0x01, 0x02, + /* NID_rc2_cbc */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x03, 0x02, + /* NID_sha */ + 0x2b, 0x0e, 0x03, 0x02, 0x12, + /* NID_shaWithRSAEncryption */ + 0x2b, 0x0e, 0x03, 0x02, 0x0f, + /* NID_des_ede3_cbc */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x03, 0x07, + /* NID_des_ofb64 */ + 0x2b, 0x0e, 0x03, 0x02, 0x08, + /* NID_pkcs9 */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, + /* NID_pkcs9_emailAddress */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x01, + /* NID_pkcs9_unstructuredName */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x02, + /* NID_pkcs9_contentType */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x03, + /* NID_pkcs9_messageDigest */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x04, + /* NID_pkcs9_signingTime */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x05, + /* NID_pkcs9_countersignature */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x06, + /* NID_pkcs9_challengePassword */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x07, + /* NID_pkcs9_unstructuredAddress */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x08, + /* NID_pkcs9_extCertAttributes */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x09, + /* NID_netscape */ + 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, + /* NID_netscape_cert_extension */ + 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, + /* NID_netscape_data_type */ + 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x02, + /* NID_sha1 */ + 0x2b, 0x0e, 0x03, 0x02, 0x1a, + /* NID_sha1WithRSAEncryption */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, + /* NID_dsaWithSHA */ + 0x2b, 0x0e, 0x03, 0x02, 0x0d, + /* NID_dsa_2 */ + 0x2b, 0x0e, 0x03, 0x02, 0x0c, + /* NID_pbeWithSHA1AndRC2_CBC */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x05, 0x0b, + /* NID_id_pbkdf2 */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x05, 0x0c, + /* NID_dsaWithSHA1_2 */ + 0x2b, 0x0e, 0x03, 0x02, 0x1b, + /* NID_netscape_cert_type */ + 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, 0x01, + /* NID_netscape_base_url */ + 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, 0x02, + /* NID_netscape_revocation_url */ + 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, 0x03, + /* NID_netscape_ca_revocation_url */ + 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, 0x04, + /* NID_netscape_renewal_url */ + 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, 0x07, + /* NID_netscape_ca_policy_url */ + 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, 0x08, + /* NID_netscape_ssl_server_name */ + 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, 0x0c, + /* NID_netscape_comment */ + 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, 0x0d, + /* NID_netscape_cert_sequence */ + 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x02, 0x05, + /* NID_id_ce */ + 0x55, 0x1d, + /* NID_subject_key_identifier */ + 0x55, 0x1d, 0x0e, + /* NID_key_usage */ + 0x55, 0x1d, 0x0f, + /* NID_private_key_usage_period */ + 0x55, 0x1d, 0x10, + /* NID_subject_alt_name */ + 0x55, 0x1d, 0x11, + /* NID_issuer_alt_name */ + 0x55, 0x1d, 0x12, + /* NID_basic_constraints */ + 0x55, 0x1d, 0x13, + /* NID_crl_number */ + 0x55, 0x1d, 0x14, + /* NID_certificate_policies */ + 0x55, 0x1d, 0x20, + /* NID_authority_key_identifier */ + 0x55, 0x1d, 0x23, + /* NID_bf_cbc */ + 0x2b, 0x06, 0x01, 0x04, 0x01, 0x97, 0x55, 0x01, 0x02, + /* NID_mdc2 */ + 0x55, 0x08, 0x03, 0x65, + /* NID_mdc2WithRSA */ + 0x55, 0x08, 0x03, 0x64, + /* NID_givenName */ + 0x55, 0x04, 0x2a, + /* NID_surname */ + 0x55, 0x04, 0x04, + /* NID_initials */ + 0x55, 0x04, 0x2b, + /* NID_crl_distribution_points */ + 0x55, 0x1d, 0x1f, + /* NID_md5WithRSA */ + 0x2b, 0x0e, 0x03, 0x02, 0x03, + /* NID_serialNumber */ + 0x55, 0x04, 0x05, + /* NID_title */ + 0x55, 0x04, 0x0c, + /* NID_description */ + 0x55, 0x04, 0x0d, + /* NID_cast5_cbc */ + 0x2a, 0x86, 0x48, 0x86, 0xf6, 0x7d, 0x07, 0x42, 0x0a, + /* NID_pbeWithMD5AndCast5_CBC */ + 0x2a, 0x86, 0x48, 0x86, 0xf6, 0x7d, 0x07, 0x42, 0x0c, + /* NID_dsaWithSHA1 */ + 0x2a, 0x86, 0x48, 0xce, 0x38, 0x04, 0x03, + /* NID_sha1WithRSA */ + 0x2b, 0x0e, 0x03, 0x02, 0x1d, + /* NID_dsa */ + 0x2a, 0x86, 0x48, 0xce, 0x38, 0x04, 0x01, + /* NID_ripemd160 */ + 0x2b, 0x24, 0x03, 0x02, 0x01, + /* NID_ripemd160WithRSA */ + 0x2b, 0x24, 0x03, 0x03, 0x01, 0x02, + /* NID_rc5_cbc */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x03, 0x08, + /* NID_zlib_compression */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x03, 0x08, + /* NID_ext_key_usage */ + 0x55, 0x1d, 0x25, + /* NID_id_pkix */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, + /* NID_id_kp */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, + /* NID_server_auth */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01, + /* NID_client_auth */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x02, + /* NID_code_sign */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x03, + /* NID_email_protect */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x04, + /* NID_time_stamp */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x08, + /* NID_ms_code_ind */ + 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x02, 0x01, 0x15, + /* NID_ms_code_com */ + 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x02, 0x01, 0x16, + /* NID_ms_ctl_sign */ + 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x0a, 0x03, 0x01, + /* NID_ms_sgc */ + 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x0a, 0x03, 0x03, + /* NID_ms_efs */ + 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x0a, 0x03, 0x04, + /* NID_ns_sgc */ + 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x04, 0x01, + /* NID_delta_crl */ + 0x55, 0x1d, 0x1b, + /* NID_crl_reason */ + 0x55, 0x1d, 0x15, + /* NID_invalidity_date */ + 0x55, 0x1d, 0x18, + /* NID_sxnet */ + 0x2b, 0x65, 0x01, 0x04, 0x01, + /* NID_pbe_WithSHA1And128BitRC4 */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x01, 0x01, + /* NID_pbe_WithSHA1And40BitRC4 */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x01, 0x02, + /* NID_pbe_WithSHA1And3_Key_TripleDES_CBC */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x01, 0x03, + /* NID_pbe_WithSHA1And2_Key_TripleDES_CBC */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x01, 0x04, + /* NID_pbe_WithSHA1And128BitRC2_CBC */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x01, 0x05, + /* NID_pbe_WithSHA1And40BitRC2_CBC */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x01, 0x06, + /* NID_keyBag */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x0a, 0x01, 0x01, + /* NID_pkcs8ShroudedKeyBag */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x0a, 0x01, 0x02, + /* NID_certBag */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x0a, 0x01, 0x03, + /* NID_crlBag */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x0a, 0x01, 0x04, + /* NID_secretBag */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x0a, 0x01, 0x05, + /* NID_safeContentsBag */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x0a, 0x01, 0x06, + /* NID_friendlyName */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x14, + /* NID_localKeyID */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x15, + /* NID_x509Certificate */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x16, 0x01, + /* NID_sdsiCertificate */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x16, 0x02, + /* NID_x509Crl */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x17, 0x01, + /* NID_pbes2 */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x05, 0x0d, + /* NID_pbmac1 */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x05, 0x0e, + /* NID_hmacWithSHA1 */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x07, + /* NID_id_qt_cps */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x01, + /* NID_id_qt_unotice */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x02, + /* NID_SMIMECapabilities */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x0f, + /* NID_pbeWithMD2AndRC2_CBC */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x05, 0x04, + /* NID_pbeWithMD5AndRC2_CBC */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x05, 0x06, + /* NID_pbeWithSHA1AndDES_CBC */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x05, 0x0a, + /* NID_ms_ext_req */ + 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x02, 0x01, 0x0e, + /* NID_ext_req */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x0e, + /* NID_name */ + 0x55, 0x04, 0x29, + /* NID_dnQualifier */ + 0x55, 0x04, 0x2e, + /* NID_id_pe */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, + /* NID_id_ad */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, + /* NID_info_access */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, + /* NID_ad_OCSP */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, + /* NID_ad_ca_issuers */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x02, + /* NID_OCSP_sign */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x09, + /* NID_member_body */ + 0x2a, + /* NID_ISO_US */ + 0x2a, 0x86, 0x48, + /* NID_X9_57 */ + 0x2a, 0x86, 0x48, 0xce, 0x38, + /* NID_X9cm */ + 0x2a, 0x86, 0x48, 0xce, 0x38, 0x04, + /* NID_pkcs1 */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, + /* NID_pkcs5 */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x05, + /* NID_SMIME */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, + /* NID_id_smime_mod */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x00, + /* NID_id_smime_ct */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x01, + /* NID_id_smime_aa */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x02, + /* NID_id_smime_alg */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x03, + /* NID_id_smime_cd */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x04, + /* NID_id_smime_spq */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x05, + /* NID_id_smime_cti */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x06, + /* NID_id_smime_mod_cms */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x00, 0x01, + /* NID_id_smime_mod_ess */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x00, 0x02, + /* NID_id_smime_mod_oid */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x00, 0x03, + /* NID_id_smime_mod_msg_v3 */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x00, 0x04, + /* NID_id_smime_mod_ets_eSignature_88 */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x00, 0x05, + /* NID_id_smime_mod_ets_eSignature_97 */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x00, 0x06, + /* NID_id_smime_mod_ets_eSigPolicy_88 */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x00, 0x07, + /* NID_id_smime_mod_ets_eSigPolicy_97 */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x00, 0x08, + /* NID_id_smime_ct_receipt */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x01, 0x01, + /* NID_id_smime_ct_authData */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x01, 0x02, + /* NID_id_smime_ct_publishCert */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x01, 0x03, + /* NID_id_smime_ct_TSTInfo */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x01, 0x04, + /* NID_id_smime_ct_TDTInfo */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x01, 0x05, + /* NID_id_smime_ct_contentInfo */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x01, 0x06, + /* NID_id_smime_ct_DVCSRequestData */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x01, 0x07, + /* NID_id_smime_ct_DVCSResponseData */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x01, 0x08, + /* NID_id_smime_aa_receiptRequest */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x02, 0x01, + /* NID_id_smime_aa_securityLabel */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x02, 0x02, + /* NID_id_smime_aa_mlExpandHistory */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x02, 0x03, + /* NID_id_smime_aa_contentHint */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x02, 0x04, + /* NID_id_smime_aa_msgSigDigest */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x02, 0x05, + /* NID_id_smime_aa_encapContentType */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x02, 0x06, + /* NID_id_smime_aa_contentIdentifier */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x02, 0x07, + /* NID_id_smime_aa_macValue */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x02, 0x08, + /* NID_id_smime_aa_equivalentLabels */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x02, 0x09, + /* NID_id_smime_aa_contentReference */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x02, 0x0a, + /* NID_id_smime_aa_encrypKeyPref */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x02, 0x0b, + /* NID_id_smime_aa_signingCertificate */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x02, 0x0c, + /* NID_id_smime_aa_smimeEncryptCerts */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x02, 0x0d, + /* NID_id_smime_aa_timeStampToken */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x02, 0x0e, + /* NID_id_smime_aa_ets_sigPolicyId */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x02, 0x0f, + /* NID_id_smime_aa_ets_commitmentType */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x02, 0x10, + /* NID_id_smime_aa_ets_signerLocation */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x02, 0x11, + /* NID_id_smime_aa_ets_signerAttr */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x02, 0x12, + /* NID_id_smime_aa_ets_otherSigCert */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x02, 0x13, + /* NID_id_smime_aa_ets_contentTimestamp */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x02, 0x14, + /* NID_id_smime_aa_ets_CertificateRefs */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x02, 0x15, + /* NID_id_smime_aa_ets_RevocationRefs */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x02, 0x16, + /* NID_id_smime_aa_ets_certValues */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x02, 0x17, + /* NID_id_smime_aa_ets_revocationValues */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x02, 0x18, + /* NID_id_smime_aa_ets_escTimeStamp */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x02, 0x19, + /* NID_id_smime_aa_ets_certCRLTimestamp */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x02, 0x1a, + /* NID_id_smime_aa_ets_archiveTimeStamp */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x02, 0x1b, + /* NID_id_smime_aa_signatureType */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x02, 0x1c, + /* NID_id_smime_aa_dvcs_dvc */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x02, 0x1d, + /* NID_id_smime_alg_ESDHwith3DES */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x03, 0x01, + /* NID_id_smime_alg_ESDHwithRC2 */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x03, 0x02, + /* NID_id_smime_alg_3DESwrap */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x03, 0x03, + /* NID_id_smime_alg_RC2wrap */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x03, 0x04, + /* NID_id_smime_alg_ESDH */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x03, 0x05, + /* NID_id_smime_alg_CMS3DESwrap */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x03, 0x06, + /* NID_id_smime_alg_CMSRC2wrap */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x03, 0x07, + /* NID_id_smime_cd_ldap */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x04, 0x01, + /* NID_id_smime_spq_ets_sqt_uri */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x05, 0x01, + /* NID_id_smime_spq_ets_sqt_unotice */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x05, 0x02, + /* NID_id_smime_cti_ets_proofOfOrigin */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x06, 0x01, + /* NID_id_smime_cti_ets_proofOfReceipt */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x06, 0x02, + /* NID_id_smime_cti_ets_proofOfDelivery */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x06, 0x03, + /* NID_id_smime_cti_ets_proofOfSender */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x06, 0x04, + /* NID_id_smime_cti_ets_proofOfApproval */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x06, 0x05, + /* NID_id_smime_cti_ets_proofOfCreation */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x06, 0x06, + /* NID_md4 */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x04, + /* NID_id_pkix_mod */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x00, + /* NID_id_qt */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, + /* NID_id_it */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x04, + /* NID_id_pkip */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x05, + /* NID_id_alg */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x06, + /* NID_id_cmc */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x07, + /* NID_id_on */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x08, + /* NID_id_pda */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x09, + /* NID_id_aca */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x0a, + /* NID_id_qcs */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x0b, + /* NID_id_cct */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x0c, + /* NID_id_pkix1_explicit_88 */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x00, 0x01, + /* NID_id_pkix1_implicit_88 */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x00, 0x02, + /* NID_id_pkix1_explicit_93 */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x00, 0x03, + /* NID_id_pkix1_implicit_93 */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x00, 0x04, + /* NID_id_mod_crmf */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x00, 0x05, + /* NID_id_mod_cmc */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x00, 0x06, + /* NID_id_mod_kea_profile_88 */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x00, 0x07, + /* NID_id_mod_kea_profile_93 */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x00, 0x08, + /* NID_id_mod_cmp */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x00, 0x09, + /* NID_id_mod_qualified_cert_88 */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x00, 0x0a, + /* NID_id_mod_qualified_cert_93 */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x00, 0x0b, + /* NID_id_mod_attribute_cert */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x00, 0x0c, + /* NID_id_mod_timestamp_protocol */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x00, 0x0d, + /* NID_id_mod_ocsp */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x00, 0x0e, + /* NID_id_mod_dvcs */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x00, 0x0f, + /* NID_id_mod_cmp2000 */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x00, 0x10, + /* NID_biometricInfo */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x02, + /* NID_qcStatements */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x03, + /* NID_ac_auditEntity */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x04, + /* NID_ac_targeting */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x05, + /* NID_aaControls */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x06, + /* NID_sbgp_ipAddrBlock */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x07, + /* NID_sbgp_autonomousSysNum */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x08, + /* NID_sbgp_routerIdentifier */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x09, + /* NID_textNotice */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x02, 0x03, + /* NID_ipsecEndSystem */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x05, + /* NID_ipsecTunnel */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x06, + /* NID_ipsecUser */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x07, + /* NID_dvcs */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x0a, + /* NID_id_it_caProtEncCert */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x04, 0x01, + /* NID_id_it_signKeyPairTypes */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x04, 0x02, + /* NID_id_it_encKeyPairTypes */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x04, 0x03, + /* NID_id_it_preferredSymmAlg */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x04, 0x04, + /* NID_id_it_caKeyUpdateInfo */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x04, 0x05, + /* NID_id_it_currentCRL */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x04, 0x06, + /* NID_id_it_unsupportedOIDs */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x04, 0x07, + /* NID_id_it_subscriptionRequest */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x04, 0x08, + /* NID_id_it_subscriptionResponse */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x04, 0x09, + /* NID_id_it_keyPairParamReq */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x04, 0x0a, + /* NID_id_it_keyPairParamRep */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x04, 0x0b, + /* NID_id_it_revPassphrase */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x04, 0x0c, + /* NID_id_it_implicitConfirm */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x04, 0x0d, + /* NID_id_it_confirmWaitTime */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x04, 0x0e, + /* NID_id_it_origPKIMessage */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x04, 0x0f, + /* NID_id_regCtrl */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x05, 0x01, + /* NID_id_regInfo */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x05, 0x02, + /* NID_id_regCtrl_regToken */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x05, 0x01, 0x01, + /* NID_id_regCtrl_authenticator */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x05, 0x01, 0x02, + /* NID_id_regCtrl_pkiPublicationInfo */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x05, 0x01, 0x03, + /* NID_id_regCtrl_pkiArchiveOptions */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x05, 0x01, 0x04, + /* NID_id_regCtrl_oldCertID */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x05, 0x01, 0x05, + /* NID_id_regCtrl_protocolEncrKey */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x05, 0x01, 0x06, + /* NID_id_regInfo_utf8Pairs */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x05, 0x02, 0x01, + /* NID_id_regInfo_certReq */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x05, 0x02, 0x02, + /* NID_id_alg_des40 */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x06, 0x01, + /* NID_id_alg_noSignature */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x06, 0x02, + /* NID_id_alg_dh_sig_hmac_sha1 */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x06, 0x03, + /* NID_id_alg_dh_pop */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x06, 0x04, + /* NID_id_cmc_statusInfo */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x07, 0x01, + /* NID_id_cmc_identification */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x07, 0x02, + /* NID_id_cmc_identityProof */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x07, 0x03, + /* NID_id_cmc_dataReturn */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x07, 0x04, + /* NID_id_cmc_transactionId */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x07, 0x05, + /* NID_id_cmc_senderNonce */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x07, 0x06, + /* NID_id_cmc_recipientNonce */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x07, 0x07, + /* NID_id_cmc_addExtensions */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x07, 0x08, + /* NID_id_cmc_encryptedPOP */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x07, 0x09, + /* NID_id_cmc_decryptedPOP */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x07, 0x0a, + /* NID_id_cmc_lraPOPWitness */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x07, 0x0b, + /* NID_id_cmc_getCert */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x07, 0x0f, + /* NID_id_cmc_getCRL */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x07, 0x10, + /* NID_id_cmc_revokeRequest */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x07, 0x11, + /* NID_id_cmc_regInfo */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x07, 0x12, + /* NID_id_cmc_responseInfo */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x07, 0x13, + /* NID_id_cmc_queryPending */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x07, 0x15, + /* NID_id_cmc_popLinkRandom */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x07, 0x16, + /* NID_id_cmc_popLinkWitness */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x07, 0x17, + /* NID_id_cmc_confirmCertAcceptance */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x07, 0x18, + /* NID_id_on_personalData */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x08, 0x01, + /* NID_id_pda_dateOfBirth */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x09, 0x01, + /* NID_id_pda_placeOfBirth */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x09, 0x02, + /* NID_id_pda_gender */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x09, 0x03, + /* NID_id_pda_countryOfCitizenship */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x09, 0x04, + /* NID_id_pda_countryOfResidence */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x09, 0x05, + /* NID_id_aca_authenticationInfo */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x0a, 0x01, + /* NID_id_aca_accessIdentity */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x0a, 0x02, + /* NID_id_aca_chargingIdentity */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x0a, 0x03, + /* NID_id_aca_group */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x0a, 0x04, + /* NID_id_aca_role */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x0a, 0x05, + /* NID_id_qcs_pkixQCSyntax_v1 */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x0b, 0x01, + /* NID_id_cct_crs */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x0c, 0x01, + /* NID_id_cct_PKIData */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x0c, 0x02, + /* NID_id_cct_PKIResponse */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x0c, 0x03, + /* NID_ad_timeStamping */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x03, + /* NID_ad_dvcs */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x04, + /* NID_id_pkix_OCSP_basic */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x01, + /* NID_id_pkix_OCSP_Nonce */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x02, + /* NID_id_pkix_OCSP_CrlID */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x03, + /* NID_id_pkix_OCSP_acceptableResponses */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x04, + /* NID_id_pkix_OCSP_noCheck */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x05, + /* NID_id_pkix_OCSP_archiveCutoff */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x06, + /* NID_id_pkix_OCSP_serviceLocator */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x07, + /* NID_id_pkix_OCSP_extendedStatus */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x08, + /* NID_id_pkix_OCSP_valid */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x09, + /* NID_id_pkix_OCSP_path */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x0a, + /* NID_id_pkix_OCSP_trustRoot */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x01, 0x0b, + /* NID_algorithm */ + 0x2b, 0x0e, 0x03, 0x02, + /* NID_rsaSignature */ + 0x2b, 0x0e, 0x03, 0x02, 0x0b, + /* NID_X500algorithms */ + 0x55, 0x08, + /* NID_org */ + 0x2b, + /* NID_dod */ + 0x2b, 0x06, + /* NID_iana */ + 0x2b, 0x06, 0x01, + /* NID_Directory */ + 0x2b, 0x06, 0x01, 0x01, + /* NID_Management */ + 0x2b, 0x06, 0x01, 0x02, + /* NID_Experimental */ + 0x2b, 0x06, 0x01, 0x03, + /* NID_Private */ + 0x2b, 0x06, 0x01, 0x04, + /* NID_Security */ + 0x2b, 0x06, 0x01, 0x05, + /* NID_SNMPv2 */ + 0x2b, 0x06, 0x01, 0x06, + /* NID_Mail */ + 0x2b, 0x06, 0x01, 0x07, + /* NID_Enterprises */ + 0x2b, 0x06, 0x01, 0x04, 0x01, + /* NID_dcObject */ + 0x2b, 0x06, 0x01, 0x04, 0x01, 0x8b, 0x3a, 0x82, 0x58, + /* NID_domainComponent */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x19, + /* NID_Domain */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x04, 0x0d, + /* NID_selected_attribute_types */ + 0x55, 0x01, 0x05, + /* NID_clearance */ + 0x55, 0x01, 0x05, 0x37, + /* NID_md4WithRSAEncryption */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x03, + /* NID_ac_proxying */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x0a, + /* NID_sinfo_access */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x0b, + /* NID_id_aca_encAttrs */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x0a, 0x06, + /* NID_role */ + 0x55, 0x04, 0x48, + /* NID_policy_constraints */ + 0x55, 0x1d, 0x24, + /* NID_target_information */ + 0x55, 0x1d, 0x37, + /* NID_no_rev_avail */ + 0x55, 0x1d, 0x38, + /* NID_ansi_X9_62 */ + 0x2a, 0x86, 0x48, 0xce, 0x3d, + /* NID_X9_62_prime_field */ + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x01, 0x01, + /* NID_X9_62_characteristic_two_field */ + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x01, 0x02, + /* NID_X9_62_id_ecPublicKey */ + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, + /* NID_X9_62_prime192v1 */ + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x01, + /* NID_X9_62_prime192v2 */ + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x02, + /* NID_X9_62_prime192v3 */ + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x03, + /* NID_X9_62_prime239v1 */ + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x04, + /* NID_X9_62_prime239v2 */ + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x05, + /* NID_X9_62_prime239v3 */ + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x06, + /* NID_X9_62_prime256v1 */ + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, + /* NID_ecdsa_with_SHA1 */ + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x01, + /* NID_ms_csp_name */ + 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x11, 0x01, + /* NID_aes_128_ecb */ + 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x01, + /* NID_aes_128_cbc */ + 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x02, + /* NID_aes_128_ofb128 */ + 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x03, + /* NID_aes_128_cfb128 */ + 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x04, + /* NID_aes_192_ecb */ + 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x15, + /* NID_aes_192_cbc */ + 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x16, + /* NID_aes_192_ofb128 */ + 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x17, + /* NID_aes_192_cfb128 */ + 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x18, + /* NID_aes_256_ecb */ + 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x29, + /* NID_aes_256_cbc */ + 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x2a, + /* NID_aes_256_ofb128 */ + 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x2b, + /* NID_aes_256_cfb128 */ + 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x2c, + /* NID_hold_instruction_code */ + 0x55, 0x1d, 0x17, + /* NID_hold_instruction_none */ + 0x2a, 0x86, 0x48, 0xce, 0x38, 0x02, 0x01, + /* NID_hold_instruction_call_issuer */ + 0x2a, 0x86, 0x48, 0xce, 0x38, 0x02, 0x02, + /* NID_hold_instruction_reject */ + 0x2a, 0x86, 0x48, 0xce, 0x38, 0x02, 0x03, + /* NID_data */ + 0x09, + /* NID_pss */ + 0x09, 0x92, 0x26, + /* NID_ucl */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, + /* NID_pilot */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, + /* NID_pilotAttributeType */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, + /* NID_pilotAttributeSyntax */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x03, + /* NID_pilotObjectClass */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x04, + /* NID_pilotGroups */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x0a, + /* NID_iA5StringSyntax */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x03, 0x04, + /* NID_caseIgnoreIA5StringSyntax */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x03, 0x05, + /* NID_pilotObject */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x04, 0x03, + /* NID_pilotPerson */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x04, 0x04, + /* NID_account */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x04, 0x05, + /* NID_document */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x04, 0x06, + /* NID_room */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x04, 0x07, + /* NID_documentSeries */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x04, 0x09, + /* NID_rFC822localPart */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x04, 0x0e, + /* NID_dNSDomain */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x04, 0x0f, + /* NID_domainRelatedObject */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x04, 0x11, + /* NID_friendlyCountry */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x04, 0x12, + /* NID_simpleSecurityObject */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x04, 0x13, + /* NID_pilotOrganization */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x04, 0x14, + /* NID_pilotDSA */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x04, 0x15, + /* NID_qualityLabelledData */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x04, 0x16, + /* NID_userId */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x01, + /* NID_textEncodedORAddress */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x02, + /* NID_rfc822Mailbox */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x03, + /* NID_info */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x04, + /* NID_favouriteDrink */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x05, + /* NID_roomNumber */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x06, + /* NID_photo */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x07, + /* NID_userClass */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x08, + /* NID_host */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x09, + /* NID_manager */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x0a, + /* NID_documentIdentifier */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x0b, + /* NID_documentTitle */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x0c, + /* NID_documentVersion */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x0d, + /* NID_documentAuthor */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x0e, + /* NID_documentLocation */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x0f, + /* NID_homeTelephoneNumber */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x14, + /* NID_secretary */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x15, + /* NID_otherMailbox */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x16, + /* NID_lastModifiedTime */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x17, + /* NID_lastModifiedBy */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x18, + /* NID_aRecord */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x1a, + /* NID_pilotAttributeType27 */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x1b, + /* NID_mXRecord */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x1c, + /* NID_nSRecord */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x1d, + /* NID_sOARecord */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x1e, + /* NID_cNAMERecord */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x1f, + /* NID_associatedDomain */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x25, + /* NID_associatedName */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x26, + /* NID_homePostalAddress */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x27, + /* NID_personalTitle */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x28, + /* NID_mobileTelephoneNumber */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x29, + /* NID_pagerTelephoneNumber */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x2a, + /* NID_friendlyCountryName */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x2b, + /* NID_organizationalStatus */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x2d, + /* NID_janetMailbox */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x2e, + /* NID_mailPreferenceOption */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x2f, + /* NID_buildingName */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x30, + /* NID_dSAQuality */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x31, + /* NID_singleLevelQuality */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x32, + /* NID_subtreeMinimumQuality */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x33, + /* NID_subtreeMaximumQuality */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x34, + /* NID_personalSignature */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x35, + /* NID_dITRedirect */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x36, + /* NID_audio */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x37, + /* NID_documentPublisher */ + 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x01, 0x38, + /* NID_x500UniqueIdentifier */ + 0x55, 0x04, 0x2d, + /* NID_mime_mhs */ + 0x2b, 0x06, 0x01, 0x07, 0x01, + /* NID_mime_mhs_headings */ + 0x2b, 0x06, 0x01, 0x07, 0x01, 0x01, + /* NID_mime_mhs_bodies */ + 0x2b, 0x06, 0x01, 0x07, 0x01, 0x02, + /* NID_id_hex_partial_message */ + 0x2b, 0x06, 0x01, 0x07, 0x01, 0x01, 0x01, + /* NID_id_hex_multipart_message */ + 0x2b, 0x06, 0x01, 0x07, 0x01, 0x01, 0x02, + /* NID_generationQualifier */ + 0x55, 0x04, 0x2c, + /* NID_pseudonym */ + 0x55, 0x04, 0x41, + /* NID_id_set */ + 0x67, 0x2a, + /* NID_set_ctype */ + 0x67, 0x2a, 0x00, + /* NID_set_msgExt */ + 0x67, 0x2a, 0x01, + /* NID_set_attr */ + 0x67, 0x2a, 0x03, + /* NID_set_policy */ + 0x67, 0x2a, 0x05, + /* NID_set_certExt */ + 0x67, 0x2a, 0x07, + /* NID_set_brand */ + 0x67, 0x2a, 0x08, + /* NID_setct_PANData */ + 0x67, 0x2a, 0x00, 0x00, + /* NID_setct_PANToken */ + 0x67, 0x2a, 0x00, 0x01, + /* NID_setct_PANOnly */ + 0x67, 0x2a, 0x00, 0x02, + /* NID_setct_OIData */ + 0x67, 0x2a, 0x00, 0x03, + /* NID_setct_PI */ + 0x67, 0x2a, 0x00, 0x04, + /* NID_setct_PIData */ + 0x67, 0x2a, 0x00, 0x05, + /* NID_setct_PIDataUnsigned */ + 0x67, 0x2a, 0x00, 0x06, + /* NID_setct_HODInput */ + 0x67, 0x2a, 0x00, 0x07, + /* NID_setct_AuthResBaggage */ + 0x67, 0x2a, 0x00, 0x08, + /* NID_setct_AuthRevReqBaggage */ + 0x67, 0x2a, 0x00, 0x09, + /* NID_setct_AuthRevResBaggage */ + 0x67, 0x2a, 0x00, 0x0a, + /* NID_setct_CapTokenSeq */ + 0x67, 0x2a, 0x00, 0x0b, + /* NID_setct_PInitResData */ + 0x67, 0x2a, 0x00, 0x0c, + /* NID_setct_PI_TBS */ + 0x67, 0x2a, 0x00, 0x0d, + /* NID_setct_PResData */ + 0x67, 0x2a, 0x00, 0x0e, + /* NID_setct_AuthReqTBS */ + 0x67, 0x2a, 0x00, 0x10, + /* NID_setct_AuthResTBS */ + 0x67, 0x2a, 0x00, 0x11, + /* NID_setct_AuthResTBSX */ + 0x67, 0x2a, 0x00, 0x12, + /* NID_setct_AuthTokenTBS */ + 0x67, 0x2a, 0x00, 0x13, + /* NID_setct_CapTokenData */ + 0x67, 0x2a, 0x00, 0x14, + /* NID_setct_CapTokenTBS */ + 0x67, 0x2a, 0x00, 0x15, + /* NID_setct_AcqCardCodeMsg */ + 0x67, 0x2a, 0x00, 0x16, + /* NID_setct_AuthRevReqTBS */ + 0x67, 0x2a, 0x00, 0x17, + /* NID_setct_AuthRevResData */ + 0x67, 0x2a, 0x00, 0x18, + /* NID_setct_AuthRevResTBS */ + 0x67, 0x2a, 0x00, 0x19, + /* NID_setct_CapReqTBS */ + 0x67, 0x2a, 0x00, 0x1a, + /* NID_setct_CapReqTBSX */ + 0x67, 0x2a, 0x00, 0x1b, + /* NID_setct_CapResData */ + 0x67, 0x2a, 0x00, 0x1c, + /* NID_setct_CapRevReqTBS */ + 0x67, 0x2a, 0x00, 0x1d, + /* NID_setct_CapRevReqTBSX */ + 0x67, 0x2a, 0x00, 0x1e, + /* NID_setct_CapRevResData */ + 0x67, 0x2a, 0x00, 0x1f, + /* NID_setct_CredReqTBS */ + 0x67, 0x2a, 0x00, 0x20, + /* NID_setct_CredReqTBSX */ + 0x67, 0x2a, 0x00, 0x21, + /* NID_setct_CredResData */ + 0x67, 0x2a, 0x00, 0x22, + /* NID_setct_CredRevReqTBS */ + 0x67, 0x2a, 0x00, 0x23, + /* NID_setct_CredRevReqTBSX */ + 0x67, 0x2a, 0x00, 0x24, + /* NID_setct_CredRevResData */ + 0x67, 0x2a, 0x00, 0x25, + /* NID_setct_PCertReqData */ + 0x67, 0x2a, 0x00, 0x26, + /* NID_setct_PCertResTBS */ + 0x67, 0x2a, 0x00, 0x27, + /* NID_setct_BatchAdminReqData */ + 0x67, 0x2a, 0x00, 0x28, + /* NID_setct_BatchAdminResData */ + 0x67, 0x2a, 0x00, 0x29, + /* NID_setct_CardCInitResTBS */ + 0x67, 0x2a, 0x00, 0x2a, + /* NID_setct_MeAqCInitResTBS */ + 0x67, 0x2a, 0x00, 0x2b, + /* NID_setct_RegFormResTBS */ + 0x67, 0x2a, 0x00, 0x2c, + /* NID_setct_CertReqData */ + 0x67, 0x2a, 0x00, 0x2d, + /* NID_setct_CertReqTBS */ + 0x67, 0x2a, 0x00, 0x2e, + /* NID_setct_CertResData */ + 0x67, 0x2a, 0x00, 0x2f, + /* NID_setct_CertInqReqTBS */ + 0x67, 0x2a, 0x00, 0x30, + /* NID_setct_ErrorTBS */ + 0x67, 0x2a, 0x00, 0x31, + /* NID_setct_PIDualSignedTBE */ + 0x67, 0x2a, 0x00, 0x32, + /* NID_setct_PIUnsignedTBE */ + 0x67, 0x2a, 0x00, 0x33, + /* NID_setct_AuthReqTBE */ + 0x67, 0x2a, 0x00, 0x34, + /* NID_setct_AuthResTBE */ + 0x67, 0x2a, 0x00, 0x35, + /* NID_setct_AuthResTBEX */ + 0x67, 0x2a, 0x00, 0x36, + /* NID_setct_AuthTokenTBE */ + 0x67, 0x2a, 0x00, 0x37, + /* NID_setct_CapTokenTBE */ + 0x67, 0x2a, 0x00, 0x38, + /* NID_setct_CapTokenTBEX */ + 0x67, 0x2a, 0x00, 0x39, + /* NID_setct_AcqCardCodeMsgTBE */ + 0x67, 0x2a, 0x00, 0x3a, + /* NID_setct_AuthRevReqTBE */ + 0x67, 0x2a, 0x00, 0x3b, + /* NID_setct_AuthRevResTBE */ + 0x67, 0x2a, 0x00, 0x3c, + /* NID_setct_AuthRevResTBEB */ + 0x67, 0x2a, 0x00, 0x3d, + /* NID_setct_CapReqTBE */ + 0x67, 0x2a, 0x00, 0x3e, + /* NID_setct_CapReqTBEX */ + 0x67, 0x2a, 0x00, 0x3f, + /* NID_setct_CapResTBE */ + 0x67, 0x2a, 0x00, 0x40, + /* NID_setct_CapRevReqTBE */ + 0x67, 0x2a, 0x00, 0x41, + /* NID_setct_CapRevReqTBEX */ + 0x67, 0x2a, 0x00, 0x42, + /* NID_setct_CapRevResTBE */ + 0x67, 0x2a, 0x00, 0x43, + /* NID_setct_CredReqTBE */ + 0x67, 0x2a, 0x00, 0x44, + /* NID_setct_CredReqTBEX */ + 0x67, 0x2a, 0x00, 0x45, + /* NID_setct_CredResTBE */ + 0x67, 0x2a, 0x00, 0x46, + /* NID_setct_CredRevReqTBE */ + 0x67, 0x2a, 0x00, 0x47, + /* NID_setct_CredRevReqTBEX */ + 0x67, 0x2a, 0x00, 0x48, + /* NID_setct_CredRevResTBE */ + 0x67, 0x2a, 0x00, 0x49, + /* NID_setct_BatchAdminReqTBE */ + 0x67, 0x2a, 0x00, 0x4a, + /* NID_setct_BatchAdminResTBE */ + 0x67, 0x2a, 0x00, 0x4b, + /* NID_setct_RegFormReqTBE */ + 0x67, 0x2a, 0x00, 0x4c, + /* NID_setct_CertReqTBE */ + 0x67, 0x2a, 0x00, 0x4d, + /* NID_setct_CertReqTBEX */ + 0x67, 0x2a, 0x00, 0x4e, + /* NID_setct_CertResTBE */ + 0x67, 0x2a, 0x00, 0x4f, + /* NID_setct_CRLNotificationTBS */ + 0x67, 0x2a, 0x00, 0x50, + /* NID_setct_CRLNotificationResTBS */ + 0x67, 0x2a, 0x00, 0x51, + /* NID_setct_BCIDistributionTBS */ + 0x67, 0x2a, 0x00, 0x52, + /* NID_setext_genCrypt */ + 0x67, 0x2a, 0x01, 0x01, + /* NID_setext_miAuth */ + 0x67, 0x2a, 0x01, 0x03, + /* NID_setext_pinSecure */ + 0x67, 0x2a, 0x01, 0x04, + /* NID_setext_pinAny */ + 0x67, 0x2a, 0x01, 0x05, + /* NID_setext_track2 */ + 0x67, 0x2a, 0x01, 0x07, + /* NID_setext_cv */ + 0x67, 0x2a, 0x01, 0x08, + /* NID_set_policy_root */ + 0x67, 0x2a, 0x05, 0x00, + /* NID_setCext_hashedRoot */ + 0x67, 0x2a, 0x07, 0x00, + /* NID_setCext_certType */ + 0x67, 0x2a, 0x07, 0x01, + /* NID_setCext_merchData */ + 0x67, 0x2a, 0x07, 0x02, + /* NID_setCext_cCertRequired */ + 0x67, 0x2a, 0x07, 0x03, + /* NID_setCext_tunneling */ + 0x67, 0x2a, 0x07, 0x04, + /* NID_setCext_setExt */ + 0x67, 0x2a, 0x07, 0x05, + /* NID_setCext_setQualf */ + 0x67, 0x2a, 0x07, 0x06, + /* NID_setCext_PGWYcapabilities */ + 0x67, 0x2a, 0x07, 0x07, + /* NID_setCext_TokenIdentifier */ + 0x67, 0x2a, 0x07, 0x08, + /* NID_setCext_Track2Data */ + 0x67, 0x2a, 0x07, 0x09, + /* NID_setCext_TokenType */ + 0x67, 0x2a, 0x07, 0x0a, + /* NID_setCext_IssuerCapabilities */ + 0x67, 0x2a, 0x07, 0x0b, + /* NID_setAttr_Cert */ + 0x67, 0x2a, 0x03, 0x00, + /* NID_setAttr_PGWYcap */ + 0x67, 0x2a, 0x03, 0x01, + /* NID_setAttr_TokenType */ + 0x67, 0x2a, 0x03, 0x02, + /* NID_setAttr_IssCap */ + 0x67, 0x2a, 0x03, 0x03, + /* NID_set_rootKeyThumb */ + 0x67, 0x2a, 0x03, 0x00, 0x00, + /* NID_set_addPolicy */ + 0x67, 0x2a, 0x03, 0x00, 0x01, + /* NID_setAttr_Token_EMV */ + 0x67, 0x2a, 0x03, 0x02, 0x01, + /* NID_setAttr_Token_B0Prime */ + 0x67, 0x2a, 0x03, 0x02, 0x02, + /* NID_setAttr_IssCap_CVM */ + 0x67, 0x2a, 0x03, 0x03, 0x03, + /* NID_setAttr_IssCap_T2 */ + 0x67, 0x2a, 0x03, 0x03, 0x04, + /* NID_setAttr_IssCap_Sig */ + 0x67, 0x2a, 0x03, 0x03, 0x05, + /* NID_setAttr_GenCryptgrm */ + 0x67, 0x2a, 0x03, 0x03, 0x03, 0x01, + /* NID_setAttr_T2Enc */ + 0x67, 0x2a, 0x03, 0x03, 0x04, 0x01, + /* NID_setAttr_T2cleartxt */ + 0x67, 0x2a, 0x03, 0x03, 0x04, 0x02, + /* NID_setAttr_TokICCsig */ + 0x67, 0x2a, 0x03, 0x03, 0x05, 0x01, + /* NID_setAttr_SecDevSig */ + 0x67, 0x2a, 0x03, 0x03, 0x05, 0x02, + /* NID_set_brand_IATA_ATA */ + 0x67, 0x2a, 0x08, 0x01, + /* NID_set_brand_Diners */ + 0x67, 0x2a, 0x08, 0x1e, + /* NID_set_brand_AmericanExpress */ + 0x67, 0x2a, 0x08, 0x22, + /* NID_set_brand_JCB */ + 0x67, 0x2a, 0x08, 0x23, + /* NID_set_brand_Visa */ + 0x67, 0x2a, 0x08, 0x04, + /* NID_set_brand_MasterCard */ + 0x67, 0x2a, 0x08, 0x05, + /* NID_set_brand_Novus */ + 0x67, 0x2a, 0x08, 0xae, 0x7b, + /* NID_des_cdmf */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x03, 0x0a, + /* NID_rsaOAEPEncryptionSET */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x06, + /* NID_international_organizations */ + 0x67, + /* NID_ms_smartcard_login */ + 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x14, 0x02, 0x02, + /* NID_ms_upn */ + 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x14, 0x02, 0x03, + /* NID_streetAddress */ + 0x55, 0x04, 0x09, + /* NID_postalCode */ + 0x55, 0x04, 0x11, + /* NID_id_ppl */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x15, + /* NID_proxyCertInfo */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x0e, + /* NID_id_ppl_anyLanguage */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x15, 0x00, + /* NID_id_ppl_inheritAll */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x15, 0x01, + /* NID_name_constraints */ + 0x55, 0x1d, 0x1e, + /* NID_Independent */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x15, 0x02, + /* NID_sha256WithRSAEncryption */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, + /* NID_sha384WithRSAEncryption */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0c, + /* NID_sha512WithRSAEncryption */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0d, + /* NID_sha224WithRSAEncryption */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0e, + /* NID_sha256 */ + 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, + /* NID_sha384 */ + 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02, + /* NID_sha512 */ + 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03, + /* NID_sha224 */ + 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04, + /* NID_identified_organization */ + 0x2b, + /* NID_certicom_arc */ + 0x2b, 0x81, 0x04, + /* NID_wap */ + 0x67, 0x2b, + /* NID_wap_wsg */ + 0x67, 0x2b, 0x01, + /* NID_X9_62_id_characteristic_two_basis */ + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x01, 0x02, 0x03, + /* NID_X9_62_onBasis */ + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x01, 0x02, 0x03, 0x01, + /* NID_X9_62_tpBasis */ + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x01, 0x02, 0x03, 0x02, + /* NID_X9_62_ppBasis */ + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x01, 0x02, 0x03, 0x03, + /* NID_X9_62_c2pnb163v1 */ + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x00, 0x01, + /* NID_X9_62_c2pnb163v2 */ + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x00, 0x02, + /* NID_X9_62_c2pnb163v3 */ + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x00, 0x03, + /* NID_X9_62_c2pnb176v1 */ + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x00, 0x04, + /* NID_X9_62_c2tnb191v1 */ + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x00, 0x05, + /* NID_X9_62_c2tnb191v2 */ + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x00, 0x06, + /* NID_X9_62_c2tnb191v3 */ + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x00, 0x07, + /* NID_X9_62_c2onb191v4 */ + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x00, 0x08, + /* NID_X9_62_c2onb191v5 */ + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x00, 0x09, + /* NID_X9_62_c2pnb208w1 */ + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x00, 0x0a, + /* NID_X9_62_c2tnb239v1 */ + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x00, 0x0b, + /* NID_X9_62_c2tnb239v2 */ + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x00, 0x0c, + /* NID_X9_62_c2tnb239v3 */ + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x00, 0x0d, + /* NID_X9_62_c2onb239v4 */ + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x00, 0x0e, + /* NID_X9_62_c2onb239v5 */ + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x00, 0x0f, + /* NID_X9_62_c2pnb272w1 */ + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x00, 0x10, + /* NID_X9_62_c2pnb304w1 */ + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x00, 0x11, + /* NID_X9_62_c2tnb359v1 */ + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x00, 0x12, + /* NID_X9_62_c2pnb368w1 */ + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x00, 0x13, + /* NID_X9_62_c2tnb431r1 */ + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x00, 0x14, + /* NID_secp112r1 */ + 0x2b, 0x81, 0x04, 0x00, 0x06, + /* NID_secp112r2 */ + 0x2b, 0x81, 0x04, 0x00, 0x07, + /* NID_secp128r1 */ + 0x2b, 0x81, 0x04, 0x00, 0x1c, + /* NID_secp128r2 */ + 0x2b, 0x81, 0x04, 0x00, 0x1d, + /* NID_secp160k1 */ + 0x2b, 0x81, 0x04, 0x00, 0x09, + /* NID_secp160r1 */ + 0x2b, 0x81, 0x04, 0x00, 0x08, + /* NID_secp160r2 */ + 0x2b, 0x81, 0x04, 0x00, 0x1e, + /* NID_secp192k1 */ + 0x2b, 0x81, 0x04, 0x00, 0x1f, + /* NID_secp224k1 */ + 0x2b, 0x81, 0x04, 0x00, 0x20, + /* NID_secp224r1 */ + 0x2b, 0x81, 0x04, 0x00, 0x21, + /* NID_secp256k1 */ + 0x2b, 0x81, 0x04, 0x00, 0x0a, + /* NID_secp384r1 */ + 0x2b, 0x81, 0x04, 0x00, 0x22, + /* NID_secp521r1 */ + 0x2b, 0x81, 0x04, 0x00, 0x23, + /* NID_sect113r1 */ + 0x2b, 0x81, 0x04, 0x00, 0x04, + /* NID_sect113r2 */ + 0x2b, 0x81, 0x04, 0x00, 0x05, + /* NID_sect131r1 */ + 0x2b, 0x81, 0x04, 0x00, 0x16, + /* NID_sect131r2 */ + 0x2b, 0x81, 0x04, 0x00, 0x17, + /* NID_sect163k1 */ + 0x2b, 0x81, 0x04, 0x00, 0x01, + /* NID_sect163r1 */ + 0x2b, 0x81, 0x04, 0x00, 0x02, + /* NID_sect163r2 */ + 0x2b, 0x81, 0x04, 0x00, 0x0f, + /* NID_sect193r1 */ + 0x2b, 0x81, 0x04, 0x00, 0x18, + /* NID_sect193r2 */ + 0x2b, 0x81, 0x04, 0x00, 0x19, + /* NID_sect233k1 */ + 0x2b, 0x81, 0x04, 0x00, 0x1a, + /* NID_sect233r1 */ + 0x2b, 0x81, 0x04, 0x00, 0x1b, + /* NID_sect239k1 */ + 0x2b, 0x81, 0x04, 0x00, 0x03, + /* NID_sect283k1 */ + 0x2b, 0x81, 0x04, 0x00, 0x10, + /* NID_sect283r1 */ + 0x2b, 0x81, 0x04, 0x00, 0x11, + /* NID_sect409k1 */ + 0x2b, 0x81, 0x04, 0x00, 0x24, + /* NID_sect409r1 */ + 0x2b, 0x81, 0x04, 0x00, 0x25, + /* NID_sect571k1 */ + 0x2b, 0x81, 0x04, 0x00, 0x26, + /* NID_sect571r1 */ + 0x2b, 0x81, 0x04, 0x00, 0x27, + /* NID_wap_wsg_idm_ecid_wtls1 */ + 0x67, 0x2b, 0x01, 0x04, 0x01, + /* NID_wap_wsg_idm_ecid_wtls3 */ + 0x67, 0x2b, 0x01, 0x04, 0x03, + /* NID_wap_wsg_idm_ecid_wtls4 */ + 0x67, 0x2b, 0x01, 0x04, 0x04, + /* NID_wap_wsg_idm_ecid_wtls5 */ + 0x67, 0x2b, 0x01, 0x04, 0x05, + /* NID_wap_wsg_idm_ecid_wtls6 */ + 0x67, 0x2b, 0x01, 0x04, 0x06, + /* NID_wap_wsg_idm_ecid_wtls7 */ + 0x67, 0x2b, 0x01, 0x04, 0x07, + /* NID_wap_wsg_idm_ecid_wtls8 */ + 0x67, 0x2b, 0x01, 0x04, 0x08, + /* NID_wap_wsg_idm_ecid_wtls9 */ + 0x67, 0x2b, 0x01, 0x04, 0x09, + /* NID_wap_wsg_idm_ecid_wtls10 */ + 0x67, 0x2b, 0x01, 0x04, 0x0a, + /* NID_wap_wsg_idm_ecid_wtls11 */ + 0x67, 0x2b, 0x01, 0x04, 0x0b, + /* NID_wap_wsg_idm_ecid_wtls12 */ + 0x67, 0x2b, 0x01, 0x04, 0x0c, + /* NID_any_policy */ + 0x55, 0x1d, 0x20, 0x00, + /* NID_policy_mappings */ + 0x55, 0x1d, 0x21, + /* NID_inhibit_any_policy */ + 0x55, 0x1d, 0x36, + /* NID_camellia_128_cbc */ + 0x2a, 0x83, 0x08, 0x8c, 0x9a, 0x4b, 0x3d, 0x01, 0x01, 0x01, 0x02, + /* NID_camellia_192_cbc */ + 0x2a, 0x83, 0x08, 0x8c, 0x9a, 0x4b, 0x3d, 0x01, 0x01, 0x01, 0x03, + /* NID_camellia_256_cbc */ + 0x2a, 0x83, 0x08, 0x8c, 0x9a, 0x4b, 0x3d, 0x01, 0x01, 0x01, 0x04, + /* NID_camellia_128_ecb */ + 0x03, 0xa2, 0x31, 0x05, 0x03, 0x01, 0x09, 0x01, + /* NID_camellia_192_ecb */ + 0x03, 0xa2, 0x31, 0x05, 0x03, 0x01, 0x09, 0x15, + /* NID_camellia_256_ecb */ + 0x03, 0xa2, 0x31, 0x05, 0x03, 0x01, 0x09, 0x29, + /* NID_camellia_128_cfb128 */ + 0x03, 0xa2, 0x31, 0x05, 0x03, 0x01, 0x09, 0x04, + /* NID_camellia_192_cfb128 */ + 0x03, 0xa2, 0x31, 0x05, 0x03, 0x01, 0x09, 0x18, + /* NID_camellia_256_cfb128 */ + 0x03, 0xa2, 0x31, 0x05, 0x03, 0x01, 0x09, 0x2c, + /* NID_camellia_128_ofb128 */ + 0x03, 0xa2, 0x31, 0x05, 0x03, 0x01, 0x09, 0x03, + /* NID_camellia_192_ofb128 */ + 0x03, 0xa2, 0x31, 0x05, 0x03, 0x01, 0x09, 0x17, + /* NID_camellia_256_ofb128 */ + 0x03, 0xa2, 0x31, 0x05, 0x03, 0x01, 0x09, 0x2b, + /* NID_subject_directory_attributes */ + 0x55, 0x1d, 0x09, + /* NID_issuing_distribution_point */ + 0x55, 0x1d, 0x1c, + /* NID_certificate_issuer */ + 0x55, 0x1d, 0x1d, + /* NID_kisa */ + 0x2a, 0x83, 0x1a, 0x8c, 0x9a, 0x44, + /* NID_seed_ecb */ + 0x2a, 0x83, 0x1a, 0x8c, 0x9a, 0x44, 0x01, 0x03, + /* NID_seed_cbc */ + 0x2a, 0x83, 0x1a, 0x8c, 0x9a, 0x44, 0x01, 0x04, + /* NID_seed_ofb128 */ + 0x2a, 0x83, 0x1a, 0x8c, 0x9a, 0x44, 0x01, 0x06, + /* NID_seed_cfb128 */ + 0x2a, 0x83, 0x1a, 0x8c, 0x9a, 0x44, 0x01, 0x05, + /* NID_hmac_md5 */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x08, 0x01, 0x01, + /* NID_hmac_sha1 */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x08, 0x01, 0x02, + /* NID_id_PasswordBasedMAC */ + 0x2a, 0x86, 0x48, 0x86, 0xf6, 0x7d, 0x07, 0x42, 0x0d, + /* NID_id_DHBasedMac */ + 0x2a, 0x86, 0x48, 0x86, 0xf6, 0x7d, 0x07, 0x42, 0x1e, + /* NID_id_it_suppLangTags */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x04, 0x10, + /* NID_caRepository */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x30, 0x05, + /* NID_id_smime_ct_compressedData */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x01, 0x09, + /* NID_id_ct_asciiTextWithCRLF */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x01, 0x1b, + /* NID_id_aes128_wrap */ + 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x05, + /* NID_id_aes192_wrap */ + 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x19, + /* NID_id_aes256_wrap */ + 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x2d, + /* NID_ecdsa_with_Recommended */ + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x02, + /* NID_ecdsa_with_Specified */ + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, + /* NID_ecdsa_with_SHA224 */ + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x01, + /* NID_ecdsa_with_SHA256 */ + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, + /* NID_ecdsa_with_SHA384 */ + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x03, + /* NID_ecdsa_with_SHA512 */ + 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x04, + /* NID_hmacWithMD5 */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x06, + /* NID_hmacWithSHA224 */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x08, + /* NID_hmacWithSHA256 */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x09, + /* NID_hmacWithSHA384 */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x0a, + /* NID_hmacWithSHA512 */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x02, 0x0b, + /* NID_dsa_with_SHA224 */ + 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x03, 0x01, + /* NID_dsa_with_SHA256 */ + 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x03, 0x02, + /* NID_whirlpool */ + 0x28, 0xcf, 0x06, 0x03, 0x00, 0x37, + /* NID_cryptopro */ + 0x2a, 0x85, 0x03, 0x02, 0x02, + /* NID_cryptocom */ + 0x2a, 0x85, 0x03, 0x02, 0x09, + /* NID_id_GostR3411_94_with_GostR3410_2001 */ + 0x2a, 0x85, 0x03, 0x02, 0x02, 0x03, + /* NID_id_GostR3411_94_with_GostR3410_94 */ + 0x2a, 0x85, 0x03, 0x02, 0x02, 0x04, + /* NID_id_GostR3411_94 */ + 0x2a, 0x85, 0x03, 0x02, 0x02, 0x09, + /* NID_id_HMACGostR3411_94 */ + 0x2a, 0x85, 0x03, 0x02, 0x02, 0x0a, + /* NID_id_GostR3410_2001 */ + 0x2a, 0x85, 0x03, 0x02, 0x02, 0x13, + /* NID_id_GostR3410_94 */ + 0x2a, 0x85, 0x03, 0x02, 0x02, 0x14, + /* NID_id_Gost28147_89 */ + 0x2a, 0x85, 0x03, 0x02, 0x02, 0x15, + /* NID_id_Gost28147_89_MAC */ + 0x2a, 0x85, 0x03, 0x02, 0x02, 0x16, + /* NID_id_GostR3411_94_prf */ + 0x2a, 0x85, 0x03, 0x02, 0x02, 0x17, + /* NID_id_GostR3410_2001DH */ + 0x2a, 0x85, 0x03, 0x02, 0x02, 0x62, + /* NID_id_GostR3410_94DH */ + 0x2a, 0x85, 0x03, 0x02, 0x02, 0x63, + /* NID_id_Gost28147_89_CryptoPro_KeyMeshing */ + 0x2a, 0x85, 0x03, 0x02, 0x02, 0x0e, 0x01, + /* NID_id_Gost28147_89_None_KeyMeshing */ + 0x2a, 0x85, 0x03, 0x02, 0x02, 0x0e, 0x00, + /* NID_id_GostR3411_94_TestParamSet */ + 0x2a, 0x85, 0x03, 0x02, 0x02, 0x1e, 0x00, + /* NID_id_GostR3411_94_CryptoProParamSet */ + 0x2a, 0x85, 0x03, 0x02, 0x02, 0x1e, 0x01, + /* NID_id_Gost28147_89_TestParamSet */ + 0x2a, 0x85, 0x03, 0x02, 0x02, 0x1f, 0x00, + /* NID_id_Gost28147_89_CryptoPro_A_ParamSet */ + 0x2a, 0x85, 0x03, 0x02, 0x02, 0x1f, 0x01, + /* NID_id_Gost28147_89_CryptoPro_B_ParamSet */ + 0x2a, 0x85, 0x03, 0x02, 0x02, 0x1f, 0x02, + /* NID_id_Gost28147_89_CryptoPro_C_ParamSet */ + 0x2a, 0x85, 0x03, 0x02, 0x02, 0x1f, 0x03, + /* NID_id_Gost28147_89_CryptoPro_D_ParamSet */ + 0x2a, 0x85, 0x03, 0x02, 0x02, 0x1f, 0x04, + /* NID_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet */ + 0x2a, 0x85, 0x03, 0x02, 0x02, 0x1f, 0x05, + /* NID_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet */ + 0x2a, 0x85, 0x03, 0x02, 0x02, 0x1f, 0x06, + /* NID_id_Gost28147_89_CryptoPro_RIC_1_ParamSet */ + 0x2a, 0x85, 0x03, 0x02, 0x02, 0x1f, 0x07, + /* NID_id_GostR3410_94_TestParamSet */ + 0x2a, 0x85, 0x03, 0x02, 0x02, 0x20, 0x00, + /* NID_id_GostR3410_94_CryptoPro_A_ParamSet */ + 0x2a, 0x85, 0x03, 0x02, 0x02, 0x20, 0x02, + /* NID_id_GostR3410_94_CryptoPro_B_ParamSet */ + 0x2a, 0x85, 0x03, 0x02, 0x02, 0x20, 0x03, + /* NID_id_GostR3410_94_CryptoPro_C_ParamSet */ + 0x2a, 0x85, 0x03, 0x02, 0x02, 0x20, 0x04, + /* NID_id_GostR3410_94_CryptoPro_D_ParamSet */ + 0x2a, 0x85, 0x03, 0x02, 0x02, 0x20, 0x05, + /* NID_id_GostR3410_94_CryptoPro_XchA_ParamSet */ + 0x2a, 0x85, 0x03, 0x02, 0x02, 0x21, 0x01, + /* NID_id_GostR3410_94_CryptoPro_XchB_ParamSet */ + 0x2a, 0x85, 0x03, 0x02, 0x02, 0x21, 0x02, + /* NID_id_GostR3410_94_CryptoPro_XchC_ParamSet */ + 0x2a, 0x85, 0x03, 0x02, 0x02, 0x21, 0x03, + /* NID_id_GostR3410_2001_TestParamSet */ + 0x2a, 0x85, 0x03, 0x02, 0x02, 0x23, 0x00, + /* NID_id_GostR3410_2001_CryptoPro_A_ParamSet */ + 0x2a, 0x85, 0x03, 0x02, 0x02, 0x23, 0x01, + /* NID_id_GostR3410_2001_CryptoPro_B_ParamSet */ + 0x2a, 0x85, 0x03, 0x02, 0x02, 0x23, 0x02, + /* NID_id_GostR3410_2001_CryptoPro_C_ParamSet */ + 0x2a, 0x85, 0x03, 0x02, 0x02, 0x23, 0x03, + /* NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet */ + 0x2a, 0x85, 0x03, 0x02, 0x02, 0x24, 0x00, + /* NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet */ + 0x2a, 0x85, 0x03, 0x02, 0x02, 0x24, 0x01, + /* NID_id_GostR3410_94_a */ + 0x2a, 0x85, 0x03, 0x02, 0x02, 0x14, 0x01, + /* NID_id_GostR3410_94_aBis */ + 0x2a, 0x85, 0x03, 0x02, 0x02, 0x14, 0x02, + /* NID_id_GostR3410_94_b */ + 0x2a, 0x85, 0x03, 0x02, 0x02, 0x14, 0x03, + /* NID_id_GostR3410_94_bBis */ + 0x2a, 0x85, 0x03, 0x02, 0x02, 0x14, 0x04, + /* NID_id_Gost28147_89_cc */ + 0x2a, 0x85, 0x03, 0x02, 0x09, 0x01, 0x06, 0x01, + /* NID_id_GostR3410_94_cc */ + 0x2a, 0x85, 0x03, 0x02, 0x09, 0x01, 0x05, 0x03, + /* NID_id_GostR3410_2001_cc */ + 0x2a, 0x85, 0x03, 0x02, 0x09, 0x01, 0x05, 0x04, + /* NID_id_GostR3411_94_with_GostR3410_94_cc */ + 0x2a, 0x85, 0x03, 0x02, 0x09, 0x01, 0x03, 0x03, + /* NID_id_GostR3411_94_with_GostR3410_2001_cc */ + 0x2a, 0x85, 0x03, 0x02, 0x09, 0x01, 0x03, 0x04, + /* NID_id_GostR3410_2001_ParamSet_cc */ + 0x2a, 0x85, 0x03, 0x02, 0x09, 0x01, 0x08, 0x01, + /* NID_LocalKeySet */ + 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0x37, 0x11, 0x02, + /* NID_freshest_crl */ + 0x55, 0x1d, 0x2e, + /* NID_id_on_permanentIdentifier */ + 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x08, 0x03, + /* NID_searchGuide */ + 0x55, 0x04, 0x0e, + /* NID_businessCategory */ + 0x55, 0x04, 0x0f, + /* NID_postalAddress */ + 0x55, 0x04, 0x10, + /* NID_postOfficeBox */ + 0x55, 0x04, 0x12, + /* NID_physicalDeliveryOfficeName */ + 0x55, 0x04, 0x13, + /* NID_telephoneNumber */ + 0x55, 0x04, 0x14, + /* NID_telexNumber */ + 0x55, 0x04, 0x15, + /* NID_teletexTerminalIdentifier */ + 0x55, 0x04, 0x16, + /* NID_facsimileTelephoneNumber */ + 0x55, 0x04, 0x17, + /* NID_x121Address */ + 0x55, 0x04, 0x18, + /* NID_internationaliSDNNumber */ + 0x55, 0x04, 0x19, + /* NID_registeredAddress */ + 0x55, 0x04, 0x1a, + /* NID_destinationIndicator */ + 0x55, 0x04, 0x1b, + /* NID_preferredDeliveryMethod */ + 0x55, 0x04, 0x1c, + /* NID_presentationAddress */ + 0x55, 0x04, 0x1d, + /* NID_supportedApplicationContext */ + 0x55, 0x04, 0x1e, + /* NID_member */ + 0x55, 0x04, 0x1f, + /* NID_owner */ + 0x55, 0x04, 0x20, + /* NID_roleOccupant */ + 0x55, 0x04, 0x21, + /* NID_seeAlso */ + 0x55, 0x04, 0x22, + /* NID_userPassword */ + 0x55, 0x04, 0x23, + /* NID_userCertificate */ + 0x55, 0x04, 0x24, + /* NID_cACertificate */ + 0x55, 0x04, 0x25, + /* NID_authorityRevocationList */ + 0x55, 0x04, 0x26, + /* NID_certificateRevocationList */ + 0x55, 0x04, 0x27, + /* NID_crossCertificatePair */ + 0x55, 0x04, 0x28, + /* NID_enhancedSearchGuide */ + 0x55, 0x04, 0x2f, + /* NID_protocolInformation */ + 0x55, 0x04, 0x30, + /* NID_distinguishedName */ + 0x55, 0x04, 0x31, + /* NID_uniqueMember */ + 0x55, 0x04, 0x32, + /* NID_houseIdentifier */ + 0x55, 0x04, 0x33, + /* NID_supportedAlgorithms */ + 0x55, 0x04, 0x34, + /* NID_deltaRevocationList */ + 0x55, 0x04, 0x35, + /* NID_dmdName */ + 0x55, 0x04, 0x36, + /* NID_id_alg_PWRI_KEK */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 0x10, 0x03, 0x09, + /* NID_aes_128_gcm */ + 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x06, + /* NID_aes_128_ccm */ + 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x07, + /* NID_id_aes128_wrap_pad */ + 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x08, + /* NID_aes_192_gcm */ + 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x1a, + /* NID_aes_192_ccm */ + 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x1b, + /* NID_id_aes192_wrap_pad */ + 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x1c, + /* NID_aes_256_gcm */ + 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x2e, + /* NID_aes_256_ccm */ + 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x2f, + /* NID_id_aes256_wrap_pad */ + 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x30, + /* NID_id_camellia128_wrap */ + 0x2a, 0x83, 0x08, 0x8c, 0x9a, 0x4b, 0x3d, 0x01, 0x01, 0x03, 0x02, + /* NID_id_camellia192_wrap */ + 0x2a, 0x83, 0x08, 0x8c, 0x9a, 0x4b, 0x3d, 0x01, 0x01, 0x03, 0x03, + /* NID_id_camellia256_wrap */ + 0x2a, 0x83, 0x08, 0x8c, 0x9a, 0x4b, 0x3d, 0x01, 0x01, 0x03, 0x04, + /* NID_anyExtendedKeyUsage */ + 0x55, 0x1d, 0x25, 0x00, + /* NID_mgf1 */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x08, + /* NID_rsassaPss */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0a, + /* NID_rsaesOaep */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x07, + /* NID_dhpublicnumber */ + 0x2a, 0x86, 0x48, 0xce, 0x3e, 0x02, 0x01, + /* NID_brainpoolP160r1 */ + 0x2b, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x01, + /* NID_brainpoolP160t1 */ + 0x2b, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x02, + /* NID_brainpoolP192r1 */ + 0x2b, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x03, + /* NID_brainpoolP192t1 */ + 0x2b, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x04, + /* NID_brainpoolP224r1 */ + 0x2b, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x05, + /* NID_brainpoolP224t1 */ + 0x2b, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x06, + /* NID_brainpoolP256r1 */ + 0x2b, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x07, + /* NID_brainpoolP256t1 */ + 0x2b, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x08, + /* NID_brainpoolP320r1 */ + 0x2b, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x09, + /* NID_brainpoolP320t1 */ + 0x2b, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x0a, + /* NID_brainpoolP384r1 */ + 0x2b, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x0b, + /* NID_brainpoolP384t1 */ + 0x2b, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x0c, + /* NID_brainpoolP512r1 */ + 0x2b, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x0d, + /* NID_brainpoolP512t1 */ + 0x2b, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x0e, + /* NID_pSpecified */ + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x09, + /* NID_dhSinglePass_stdDH_sha1kdf_scheme */ + 0x2b, 0x81, 0x05, 0x10, 0x86, 0x48, 0x3f, 0x00, 0x02, + /* NID_dhSinglePass_stdDH_sha224kdf_scheme */ + 0x2b, 0x81, 0x04, 0x01, 0x0b, 0x00, + /* NID_dhSinglePass_stdDH_sha256kdf_scheme */ + 0x2b, 0x81, 0x04, 0x01, 0x0b, 0x01, + /* NID_dhSinglePass_stdDH_sha384kdf_scheme */ + 0x2b, 0x81, 0x04, 0x01, 0x0b, 0x02, + /* NID_dhSinglePass_stdDH_sha512kdf_scheme */ + 0x2b, 0x81, 0x04, 0x01, 0x0b, 0x03, + /* NID_dhSinglePass_cofactorDH_sha1kdf_scheme */ + 0x2b, 0x81, 0x05, 0x10, 0x86, 0x48, 0x3f, 0x00, 0x03, + /* NID_dhSinglePass_cofactorDH_sha224kdf_scheme */ + 0x2b, 0x81, 0x04, 0x01, 0x0e, 0x00, + /* NID_dhSinglePass_cofactorDH_sha256kdf_scheme */ + 0x2b, 0x81, 0x04, 0x01, 0x0e, 0x01, + /* NID_dhSinglePass_cofactorDH_sha384kdf_scheme */ + 0x2b, 0x81, 0x04, 0x01, 0x0e, 0x02, + /* NID_dhSinglePass_cofactorDH_sha512kdf_scheme */ + 0x2b, 0x81, 0x04, 0x01, 0x0e, 0x03, + /* NID_ED25519 */ + 0x2b, 0x65, 0x70, +}; + +static const ASN1_OBJECT kObjects[NUM_NID] = { + {"UNDEF", "undefined", NID_undef, 0, NULL, 0}, + {"rsadsi", "RSA Data Security, Inc.", NID_rsadsi, 6, &kObjectData[0], 0}, + {"pkcs", "RSA Data Security, Inc. PKCS", NID_pkcs, 7, &kObjectData[6], 0}, + {"MD2", "md2", NID_md2, 8, &kObjectData[13], 0}, + {"MD5", "md5", NID_md5, 8, &kObjectData[21], 0}, + {"RC4", "rc4", NID_rc4, 8, &kObjectData[29], 0}, + {"rsaEncryption", "rsaEncryption", NID_rsaEncryption, 9, &kObjectData[37], + 0}, + {"RSA-MD2", "md2WithRSAEncryption", NID_md2WithRSAEncryption, 9, + &kObjectData[46], 0}, + {"RSA-MD5", "md5WithRSAEncryption", NID_md5WithRSAEncryption, 9, + &kObjectData[55], 0}, + {"PBE-MD2-DES", "pbeWithMD2AndDES-CBC", NID_pbeWithMD2AndDES_CBC, 9, + &kObjectData[64], 0}, + {"PBE-MD5-DES", "pbeWithMD5AndDES-CBC", NID_pbeWithMD5AndDES_CBC, 9, + &kObjectData[73], 0}, + {"X500", "directory services (X.500)", NID_X500, 1, &kObjectData[82], 0}, + {"X509", "X509", NID_X509, 2, &kObjectData[83], 0}, + {"CN", "commonName", NID_commonName, 3, &kObjectData[85], 0}, + {"C", "countryName", NID_countryName, 3, &kObjectData[88], 0}, + {"L", "localityName", NID_localityName, 3, &kObjectData[91], 0}, + {"ST", "stateOrProvinceName", NID_stateOrProvinceName, 3, &kObjectData[94], + 0}, + {"O", "organizationName", NID_organizationName, 3, &kObjectData[97], 0}, + {"OU", "organizationalUnitName", NID_organizationalUnitName, 3, + &kObjectData[100], 0}, + {"RSA", "rsa", NID_rsa, 4, &kObjectData[103], 0}, + {"pkcs7", "pkcs7", NID_pkcs7, 8, &kObjectData[107], 0}, + {"pkcs7-data", "pkcs7-data", NID_pkcs7_data, 9, &kObjectData[115], 0}, + {"pkcs7-signedData", "pkcs7-signedData", NID_pkcs7_signed, 9, + &kObjectData[124], 0}, + {"pkcs7-envelopedData", "pkcs7-envelopedData", NID_pkcs7_enveloped, 9, + &kObjectData[133], 0}, + {"pkcs7-signedAndEnvelopedData", "pkcs7-signedAndEnvelopedData", + NID_pkcs7_signedAndEnveloped, 9, &kObjectData[142], 0}, + {"pkcs7-digestData", "pkcs7-digestData", NID_pkcs7_digest, 9, + &kObjectData[151], 0}, + {"pkcs7-encryptedData", "pkcs7-encryptedData", NID_pkcs7_encrypted, 9, + &kObjectData[160], 0}, + {"pkcs3", "pkcs3", NID_pkcs3, 8, &kObjectData[169], 0}, + {"dhKeyAgreement", "dhKeyAgreement", NID_dhKeyAgreement, 9, + &kObjectData[177], 0}, + {"DES-ECB", "des-ecb", NID_des_ecb, 5, &kObjectData[186], 0}, + {"DES-CFB", "des-cfb", NID_des_cfb64, 5, &kObjectData[191], 0}, + {"DES-CBC", "des-cbc", NID_des_cbc, 5, &kObjectData[196], 0}, + {"DES-EDE", "des-ede", NID_des_ede_ecb, 5, &kObjectData[201], 0}, + {"DES-EDE3", "des-ede3", NID_des_ede3_ecb, 0, NULL, 0}, + {"IDEA-CBC", "idea-cbc", NID_idea_cbc, 11, &kObjectData[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, &kObjectData[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, &kObjectData[225], 0}, + {"RSA-SHA", "shaWithRSAEncryption", NID_shaWithRSAEncryption, 5, + &kObjectData[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, &kObjectData[235], 0}, + {"DES-OFB", "des-ofb", NID_des_ofb64, 5, &kObjectData[243], 0}, + {"IDEA-OFB", "idea-ofb", NID_idea_ofb64, 0, NULL, 0}, + {"pkcs9", "pkcs9", NID_pkcs9, 8, &kObjectData[248], 0}, + {"emailAddress", "emailAddress", NID_pkcs9_emailAddress, 9, + &kObjectData[256], 0}, + {"unstructuredName", "unstructuredName", NID_pkcs9_unstructuredName, 9, + &kObjectData[265], 0}, + {"contentType", "contentType", NID_pkcs9_contentType, 9, &kObjectData[274], + 0}, + {"messageDigest", "messageDigest", NID_pkcs9_messageDigest, 9, + &kObjectData[283], 0}, + {"signingTime", "signingTime", NID_pkcs9_signingTime, 9, &kObjectData[292], + 0}, + {"countersignature", "countersignature", NID_pkcs9_countersignature, 9, + &kObjectData[301], 0}, + {"challengePassword", "challengePassword", NID_pkcs9_challengePassword, 9, + &kObjectData[310], 0}, + {"unstructuredAddress", "unstructuredAddress", + NID_pkcs9_unstructuredAddress, 9, &kObjectData[319], 0}, + {"extendedCertificateAttributes", "extendedCertificateAttributes", + NID_pkcs9_extCertAttributes, 9, &kObjectData[328], 0}, + {"Netscape", "Netscape Communications Corp.", NID_netscape, 7, + &kObjectData[337], 0}, + {"nsCertExt", "Netscape Certificate Extension", NID_netscape_cert_extension, + 8, &kObjectData[344], 0}, + {"nsDataType", "Netscape Data Type", NID_netscape_data_type, 8, + &kObjectData[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, &kObjectData[360], 0}, + {"RSA-SHA1", "sha1WithRSAEncryption", NID_sha1WithRSAEncryption, 9, + &kObjectData[365], 0}, + {"DSA-SHA", "dsaWithSHA", NID_dsaWithSHA, 5, &kObjectData[374], 0}, + {"DSA-old", "dsaEncryption-old", NID_dsa_2, 5, &kObjectData[379], 0}, + {"PBE-SHA1-RC2-64", "pbeWithSHA1AndRC2-CBC", NID_pbeWithSHA1AndRC2_CBC, 9, + &kObjectData[384], 0}, + {"PBKDF2", "PBKDF2", NID_id_pbkdf2, 9, &kObjectData[393], 0}, + {"DSA-SHA1-old", "dsaWithSHA1-old", NID_dsaWithSHA1_2, 5, &kObjectData[402], + 0}, + {"nsCertType", "Netscape Cert Type", NID_netscape_cert_type, 9, + &kObjectData[407], 0}, + {"nsBaseUrl", "Netscape Base Url", NID_netscape_base_url, 9, + &kObjectData[416], 0}, + {"nsRevocationUrl", "Netscape Revocation Url", NID_netscape_revocation_url, + 9, &kObjectData[425], 0}, + {"nsCaRevocationUrl", "Netscape CA Revocation Url", + NID_netscape_ca_revocation_url, 9, &kObjectData[434], 0}, + {"nsRenewalUrl", "Netscape Renewal Url", NID_netscape_renewal_url, 9, + &kObjectData[443], 0}, + {"nsCaPolicyUrl", "Netscape CA Policy Url", NID_netscape_ca_policy_url, 9, + &kObjectData[452], 0}, + {"nsSslServerName", "Netscape SSL Server Name", + NID_netscape_ssl_server_name, 9, &kObjectData[461], 0}, + {"nsComment", "Netscape Comment", NID_netscape_comment, 9, + &kObjectData[470], 0}, + {"nsCertSequence", "Netscape Certificate Sequence", + NID_netscape_cert_sequence, 9, &kObjectData[479], 0}, + {"DESX-CBC", "desx-cbc", NID_desx_cbc, 0, NULL, 0}, + {"id-ce", "id-ce", NID_id_ce, 2, &kObjectData[488], 0}, + {"subjectKeyIdentifier", "X509v3 Subject Key Identifier", + NID_subject_key_identifier, 3, &kObjectData[490], 0}, + {"keyUsage", "X509v3 Key Usage", NID_key_usage, 3, &kObjectData[493], 0}, + {"privateKeyUsagePeriod", "X509v3 Private Key Usage Period", + NID_private_key_usage_period, 3, &kObjectData[496], 0}, + {"subjectAltName", "X509v3 Subject Alternative Name", NID_subject_alt_name, + 3, &kObjectData[499], 0}, + {"issuerAltName", "X509v3 Issuer Alternative Name", NID_issuer_alt_name, 3, + &kObjectData[502], 0}, + {"basicConstraints", "X509v3 Basic Constraints", NID_basic_constraints, 3, + &kObjectData[505], 0}, + {"crlNumber", "X509v3 CRL Number", NID_crl_number, 3, &kObjectData[508], 0}, + {"certificatePolicies", "X509v3 Certificate Policies", + NID_certificate_policies, 3, &kObjectData[511], 0}, + {"authorityKeyIdentifier", "X509v3 Authority Key Identifier", + NID_authority_key_identifier, 3, &kObjectData[514], 0}, + {"BF-CBC", "bf-cbc", NID_bf_cbc, 9, &kObjectData[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, &kObjectData[526], 0}, + {"RSA-MDC2", "mdc2WithRSA", NID_mdc2WithRSA, 4, &kObjectData[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, &kObjectData[534], 0}, + {"SN", "surname", NID_surname, 3, &kObjectData[537], 0}, + {"initials", "initials", NID_initials, 3, &kObjectData[540], 0}, + {NULL, NULL, NID_undef, 0, NULL, 0}, + {"crlDistributionPoints", "X509v3 CRL Distribution Points", + NID_crl_distribution_points, 3, &kObjectData[543], 0}, + {"RSA-NP-MD5", "md5WithRSA", NID_md5WithRSA, 5, &kObjectData[546], 0}, + {"serialNumber", "serialNumber", NID_serialNumber, 3, &kObjectData[551], 0}, + {"title", "title", NID_title, 3, &kObjectData[554], 0}, + {"description", "description", NID_description, 3, &kObjectData[557], 0}, + {"CAST5-CBC", "cast5-cbc", NID_cast5_cbc, 9, &kObjectData[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, &kObjectData[569], 0}, + {"DSA-SHA1", "dsaWithSHA1", NID_dsaWithSHA1, 7, &kObjectData[578], 0}, + {"MD5-SHA1", "md5-sha1", NID_md5_sha1, 0, NULL, 0}, + {"RSA-SHA1-2", "sha1WithRSA", NID_sha1WithRSA, 5, &kObjectData[585], 0}, + {"DSA", "dsaEncryption", NID_dsa, 7, &kObjectData[590], 0}, + {"RIPEMD160", "ripemd160", NID_ripemd160, 5, &kObjectData[597], 0}, + {NULL, NULL, NID_undef, 0, NULL, 0}, + {"RSA-RIPEMD160", "ripemd160WithRSA", NID_ripemd160WithRSA, 6, + &kObjectData[602], 0}, + {"RC5-CBC", "rc5-cbc", NID_rc5_cbc, 8, &kObjectData[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}, + {NULL, NULL, NID_undef, 0, NULL, 0}, + {"ZLIB", "zlib compression", NID_zlib_compression, 11, &kObjectData[616], + 0}, + {"extendedKeyUsage", "X509v3 Extended Key Usage", NID_ext_key_usage, 3, + &kObjectData[627], 0}, + {"PKIX", "PKIX", NID_id_pkix, 6, &kObjectData[630], 0}, + {"id-kp", "id-kp", NID_id_kp, 7, &kObjectData[636], 0}, + {"serverAuth", "TLS Web Server Authentication", NID_server_auth, 8, + &kObjectData[643], 0}, + {"clientAuth", "TLS Web Client Authentication", NID_client_auth, 8, + &kObjectData[651], 0}, + {"codeSigning", "Code Signing", NID_code_sign, 8, &kObjectData[659], 0}, + {"emailProtection", "E-mail Protection", NID_email_protect, 8, + &kObjectData[667], 0}, + {"timeStamping", "Time Stamping", NID_time_stamp, 8, &kObjectData[675], 0}, + {"msCodeInd", "Microsoft Individual Code Signing", NID_ms_code_ind, 10, + &kObjectData[683], 0}, + {"msCodeCom", "Microsoft Commercial Code Signing", NID_ms_code_com, 10, + &kObjectData[693], 0}, + {"msCTLSign", "Microsoft Trust List Signing", NID_ms_ctl_sign, 10, + &kObjectData[703], 0}, + {"msSGC", "Microsoft Server Gated Crypto", NID_ms_sgc, 10, + &kObjectData[713], 0}, + {"msEFS", "Microsoft Encrypted File System", NID_ms_efs, 10, + &kObjectData[723], 0}, + {"nsSGC", "Netscape Server Gated Crypto", NID_ns_sgc, 9, &kObjectData[733], + 0}, + {"deltaCRL", "X509v3 Delta CRL Indicator", NID_delta_crl, 3, + &kObjectData[742], 0}, + {"CRLReason", "X509v3 CRL Reason Code", NID_crl_reason, 3, + &kObjectData[745], 0}, + {"invalidityDate", "Invalidity Date", NID_invalidity_date, 3, + &kObjectData[748], 0}, + {"SXNetID", "Strong Extranet ID", NID_sxnet, 5, &kObjectData[751], 0}, + {"PBE-SHA1-RC4-128", "pbeWithSHA1And128BitRC4", + NID_pbe_WithSHA1And128BitRC4, 10, &kObjectData[756], 0}, + {"PBE-SHA1-RC4-40", "pbeWithSHA1And40BitRC4", NID_pbe_WithSHA1And40BitRC4, + 10, &kObjectData[766], 0}, + {"PBE-SHA1-3DES", "pbeWithSHA1And3-KeyTripleDES-CBC", + NID_pbe_WithSHA1And3_Key_TripleDES_CBC, 10, &kObjectData[776], 0}, + {"PBE-SHA1-2DES", "pbeWithSHA1And2-KeyTripleDES-CBC", + NID_pbe_WithSHA1And2_Key_TripleDES_CBC, 10, &kObjectData[786], 0}, + {"PBE-SHA1-RC2-128", "pbeWithSHA1And128BitRC2-CBC", + NID_pbe_WithSHA1And128BitRC2_CBC, 10, &kObjectData[796], 0}, + {"PBE-SHA1-RC2-40", "pbeWithSHA1And40BitRC2-CBC", + NID_pbe_WithSHA1And40BitRC2_CBC, 10, &kObjectData[806], 0}, + {"keyBag", "keyBag", NID_keyBag, 11, &kObjectData[816], 0}, + {"pkcs8ShroudedKeyBag", "pkcs8ShroudedKeyBag", NID_pkcs8ShroudedKeyBag, 11, + &kObjectData[827], 0}, + {"certBag", "certBag", NID_certBag, 11, &kObjectData[838], 0}, + {"crlBag", "crlBag", NID_crlBag, 11, &kObjectData[849], 0}, + {"secretBag", "secretBag", NID_secretBag, 11, &kObjectData[860], 0}, + {"safeContentsBag", "safeContentsBag", NID_safeContentsBag, 11, + &kObjectData[871], 0}, + {"friendlyName", "friendlyName", NID_friendlyName, 9, &kObjectData[882], 0}, + {"localKeyID", "localKeyID", NID_localKeyID, 9, &kObjectData[891], 0}, + {"x509Certificate", "x509Certificate", NID_x509Certificate, 10, + &kObjectData[900], 0}, + {"sdsiCertificate", "sdsiCertificate", NID_sdsiCertificate, 10, + &kObjectData[910], 0}, + {"x509Crl", "x509Crl", NID_x509Crl, 10, &kObjectData[920], 0}, + {"PBES2", "PBES2", NID_pbes2, 9, &kObjectData[930], 0}, + {"PBMAC1", "PBMAC1", NID_pbmac1, 9, &kObjectData[939], 0}, + {"hmacWithSHA1", "hmacWithSHA1", NID_hmacWithSHA1, 8, &kObjectData[948], 0}, + {"id-qt-cps", "Policy Qualifier CPS", NID_id_qt_cps, 8, &kObjectData[956], + 0}, + {"id-qt-unotice", "Policy Qualifier User Notice", NID_id_qt_unotice, 8, + &kObjectData[964], 0}, + {"RC2-64-CBC", "rc2-64-cbc", NID_rc2_64_cbc, 0, NULL, 0}, + {"SMIME-CAPS", "S/MIME Capabilities", NID_SMIMECapabilities, 9, + &kObjectData[972], 0}, + {"PBE-MD2-RC2-64", "pbeWithMD2AndRC2-CBC", NID_pbeWithMD2AndRC2_CBC, 9, + &kObjectData[981], 0}, + {"PBE-MD5-RC2-64", "pbeWithMD5AndRC2-CBC", NID_pbeWithMD5AndRC2_CBC, 9, + &kObjectData[990], 0}, + {"PBE-SHA1-DES", "pbeWithSHA1AndDES-CBC", NID_pbeWithSHA1AndDES_CBC, 9, + &kObjectData[999], 0}, + {"msExtReq", "Microsoft Extension Request", NID_ms_ext_req, 10, + &kObjectData[1008], 0}, + {"extReq", "Extension Request", NID_ext_req, 9, &kObjectData[1018], 0}, + {"name", "name", NID_name, 3, &kObjectData[1027], 0}, + {"dnQualifier", "dnQualifier", NID_dnQualifier, 3, &kObjectData[1030], 0}, + {"id-pe", "id-pe", NID_id_pe, 7, &kObjectData[1033], 0}, + {"id-ad", "id-ad", NID_id_ad, 7, &kObjectData[1040], 0}, + {"authorityInfoAccess", "Authority Information Access", NID_info_access, 8, + &kObjectData[1047], 0}, + {"OCSP", "OCSP", NID_ad_OCSP, 8, &kObjectData[1055], 0}, + {"caIssuers", "CA Issuers", NID_ad_ca_issuers, 8, &kObjectData[1063], 0}, + {"OCSPSigning", "OCSP Signing", NID_OCSP_sign, 8, &kObjectData[1071], 0}, + {"ISO", "iso", NID_iso, 0, NULL, 0}, + {"member-body", "ISO Member Body", NID_member_body, 1, &kObjectData[1079], + 0}, + {"ISO-US", "ISO US Member Body", NID_ISO_US, 3, &kObjectData[1080], 0}, + {"X9-57", "X9.57", NID_X9_57, 5, &kObjectData[1083], 0}, + {"X9cm", "X9.57 CM ?", NID_X9cm, 6, &kObjectData[1088], 0}, + {"pkcs1", "pkcs1", NID_pkcs1, 8, &kObjectData[1094], 0}, + {"pkcs5", "pkcs5", NID_pkcs5, 8, &kObjectData[1102], 0}, + {"SMIME", "S/MIME", NID_SMIME, 9, &kObjectData[1110], 0}, + {"id-smime-mod", "id-smime-mod", NID_id_smime_mod, 10, &kObjectData[1119], + 0}, + {"id-smime-ct", "id-smime-ct", NID_id_smime_ct, 10, &kObjectData[1129], 0}, + {"id-smime-aa", "id-smime-aa", NID_id_smime_aa, 10, &kObjectData[1139], 0}, + {"id-smime-alg", "id-smime-alg", NID_id_smime_alg, 10, &kObjectData[1149], + 0}, + {"id-smime-cd", "id-smime-cd", NID_id_smime_cd, 10, &kObjectData[1159], 0}, + {"id-smime-spq", "id-smime-spq", NID_id_smime_spq, 10, &kObjectData[1169], + 0}, + {"id-smime-cti", "id-smime-cti", NID_id_smime_cti, 10, &kObjectData[1179], + 0}, + {"id-smime-mod-cms", "id-smime-mod-cms", NID_id_smime_mod_cms, 11, + &kObjectData[1189], 0}, + {"id-smime-mod-ess", "id-smime-mod-ess", NID_id_smime_mod_ess, 11, + &kObjectData[1200], 0}, + {"id-smime-mod-oid", "id-smime-mod-oid", NID_id_smime_mod_oid, 11, + &kObjectData[1211], 0}, + {"id-smime-mod-msg-v3", "id-smime-mod-msg-v3", NID_id_smime_mod_msg_v3, 11, + &kObjectData[1222], 0}, + {"id-smime-mod-ets-eSignature-88", "id-smime-mod-ets-eSignature-88", + NID_id_smime_mod_ets_eSignature_88, 11, &kObjectData[1233], 0}, + {"id-smime-mod-ets-eSignature-97", "id-smime-mod-ets-eSignature-97", + NID_id_smime_mod_ets_eSignature_97, 11, &kObjectData[1244], 0}, + {"id-smime-mod-ets-eSigPolicy-88", "id-smime-mod-ets-eSigPolicy-88", + NID_id_smime_mod_ets_eSigPolicy_88, 11, &kObjectData[1255], 0}, + {"id-smime-mod-ets-eSigPolicy-97", "id-smime-mod-ets-eSigPolicy-97", + NID_id_smime_mod_ets_eSigPolicy_97, 11, &kObjectData[1266], 0}, + {"id-smime-ct-receipt", "id-smime-ct-receipt", NID_id_smime_ct_receipt, 11, + &kObjectData[1277], 0}, + {"id-smime-ct-authData", "id-smime-ct-authData", NID_id_smime_ct_authData, + 11, &kObjectData[1288], 0}, + {"id-smime-ct-publishCert", "id-smime-ct-publishCert", + NID_id_smime_ct_publishCert, 11, &kObjectData[1299], 0}, + {"id-smime-ct-TSTInfo", "id-smime-ct-TSTInfo", NID_id_smime_ct_TSTInfo, 11, + &kObjectData[1310], 0}, + {"id-smime-ct-TDTInfo", "id-smime-ct-TDTInfo", NID_id_smime_ct_TDTInfo, 11, + &kObjectData[1321], 0}, + {"id-smime-ct-contentInfo", "id-smime-ct-contentInfo", + NID_id_smime_ct_contentInfo, 11, &kObjectData[1332], 0}, + {"id-smime-ct-DVCSRequestData", "id-smime-ct-DVCSRequestData", + NID_id_smime_ct_DVCSRequestData, 11, &kObjectData[1343], 0}, + {"id-smime-ct-DVCSResponseData", "id-smime-ct-DVCSResponseData", + NID_id_smime_ct_DVCSResponseData, 11, &kObjectData[1354], 0}, + {"id-smime-aa-receiptRequest", "id-smime-aa-receiptRequest", + NID_id_smime_aa_receiptRequest, 11, &kObjectData[1365], 0}, + {"id-smime-aa-securityLabel", "id-smime-aa-securityLabel", + NID_id_smime_aa_securityLabel, 11, &kObjectData[1376], 0}, + {"id-smime-aa-mlExpandHistory", "id-smime-aa-mlExpandHistory", + NID_id_smime_aa_mlExpandHistory, 11, &kObjectData[1387], 0}, + {"id-smime-aa-contentHint", "id-smime-aa-contentHint", + NID_id_smime_aa_contentHint, 11, &kObjectData[1398], 0}, + {"id-smime-aa-msgSigDigest", "id-smime-aa-msgSigDigest", + NID_id_smime_aa_msgSigDigest, 11, &kObjectData[1409], 0}, + {"id-smime-aa-encapContentType", "id-smime-aa-encapContentType", + NID_id_smime_aa_encapContentType, 11, &kObjectData[1420], 0}, + {"id-smime-aa-contentIdentifier", "id-smime-aa-contentIdentifier", + NID_id_smime_aa_contentIdentifier, 11, &kObjectData[1431], 0}, + {"id-smime-aa-macValue", "id-smime-aa-macValue", NID_id_smime_aa_macValue, + 11, &kObjectData[1442], 0}, + {"id-smime-aa-equivalentLabels", "id-smime-aa-equivalentLabels", + NID_id_smime_aa_equivalentLabels, 11, &kObjectData[1453], 0}, + {"id-smime-aa-contentReference", "id-smime-aa-contentReference", + NID_id_smime_aa_contentReference, 11, &kObjectData[1464], 0}, + {"id-smime-aa-encrypKeyPref", "id-smime-aa-encrypKeyPref", + NID_id_smime_aa_encrypKeyPref, 11, &kObjectData[1475], 0}, + {"id-smime-aa-signingCertificate", "id-smime-aa-signingCertificate", + NID_id_smime_aa_signingCertificate, 11, &kObjectData[1486], 0}, + {"id-smime-aa-smimeEncryptCerts", "id-smime-aa-smimeEncryptCerts", + NID_id_smime_aa_smimeEncryptCerts, 11, &kObjectData[1497], 0}, + {"id-smime-aa-timeStampToken", "id-smime-aa-timeStampToken", + NID_id_smime_aa_timeStampToken, 11, &kObjectData[1508], 0}, + {"id-smime-aa-ets-sigPolicyId", "id-smime-aa-ets-sigPolicyId", + NID_id_smime_aa_ets_sigPolicyId, 11, &kObjectData[1519], 0}, + {"id-smime-aa-ets-commitmentType", "id-smime-aa-ets-commitmentType", + NID_id_smime_aa_ets_commitmentType, 11, &kObjectData[1530], 0}, + {"id-smime-aa-ets-signerLocation", "id-smime-aa-ets-signerLocation", + NID_id_smime_aa_ets_signerLocation, 11, &kObjectData[1541], 0}, + {"id-smime-aa-ets-signerAttr", "id-smime-aa-ets-signerAttr", + NID_id_smime_aa_ets_signerAttr, 11, &kObjectData[1552], 0}, + {"id-smime-aa-ets-otherSigCert", "id-smime-aa-ets-otherSigCert", + NID_id_smime_aa_ets_otherSigCert, 11, &kObjectData[1563], 0}, + {"id-smime-aa-ets-contentTimestamp", "id-smime-aa-ets-contentTimestamp", + NID_id_smime_aa_ets_contentTimestamp, 11, &kObjectData[1574], 0}, + {"id-smime-aa-ets-CertificateRefs", "id-smime-aa-ets-CertificateRefs", + NID_id_smime_aa_ets_CertificateRefs, 11, &kObjectData[1585], 0}, + {"id-smime-aa-ets-RevocationRefs", "id-smime-aa-ets-RevocationRefs", + NID_id_smime_aa_ets_RevocationRefs, 11, &kObjectData[1596], 0}, + {"id-smime-aa-ets-certValues", "id-smime-aa-ets-certValues", + NID_id_smime_aa_ets_certValues, 11, &kObjectData[1607], 0}, + {"id-smime-aa-ets-revocationValues", "id-smime-aa-ets-revocationValues", + NID_id_smime_aa_ets_revocationValues, 11, &kObjectData[1618], 0}, + {"id-smime-aa-ets-escTimeStamp", "id-smime-aa-ets-escTimeStamp", + NID_id_smime_aa_ets_escTimeStamp, 11, &kObjectData[1629], 0}, + {"id-smime-aa-ets-certCRLTimestamp", "id-smime-aa-ets-certCRLTimestamp", + NID_id_smime_aa_ets_certCRLTimestamp, 11, &kObjectData[1640], 0}, + {"id-smime-aa-ets-archiveTimeStamp", "id-smime-aa-ets-archiveTimeStamp", + NID_id_smime_aa_ets_archiveTimeStamp, 11, &kObjectData[1651], 0}, + {"id-smime-aa-signatureType", "id-smime-aa-signatureType", + NID_id_smime_aa_signatureType, 11, &kObjectData[1662], 0}, + {"id-smime-aa-dvcs-dvc", "id-smime-aa-dvcs-dvc", NID_id_smime_aa_dvcs_dvc, + 11, &kObjectData[1673], 0}, + {"id-smime-alg-ESDHwith3DES", "id-smime-alg-ESDHwith3DES", + NID_id_smime_alg_ESDHwith3DES, 11, &kObjectData[1684], 0}, + {"id-smime-alg-ESDHwithRC2", "id-smime-alg-ESDHwithRC2", + NID_id_smime_alg_ESDHwithRC2, 11, &kObjectData[1695], 0}, + {"id-smime-alg-3DESwrap", "id-smime-alg-3DESwrap", + NID_id_smime_alg_3DESwrap, 11, &kObjectData[1706], 0}, + {"id-smime-alg-RC2wrap", "id-smime-alg-RC2wrap", NID_id_smime_alg_RC2wrap, + 11, &kObjectData[1717], 0}, + {"id-smime-alg-ESDH", "id-smime-alg-ESDH", NID_id_smime_alg_ESDH, 11, + &kObjectData[1728], 0}, + {"id-smime-alg-CMS3DESwrap", "id-smime-alg-CMS3DESwrap", + NID_id_smime_alg_CMS3DESwrap, 11, &kObjectData[1739], 0}, + {"id-smime-alg-CMSRC2wrap", "id-smime-alg-CMSRC2wrap", + NID_id_smime_alg_CMSRC2wrap, 11, &kObjectData[1750], 0}, + {"id-smime-cd-ldap", "id-smime-cd-ldap", NID_id_smime_cd_ldap, 11, + &kObjectData[1761], 0}, + {"id-smime-spq-ets-sqt-uri", "id-smime-spq-ets-sqt-uri", + NID_id_smime_spq_ets_sqt_uri, 11, &kObjectData[1772], 0}, + {"id-smime-spq-ets-sqt-unotice", "id-smime-spq-ets-sqt-unotice", + NID_id_smime_spq_ets_sqt_unotice, 11, &kObjectData[1783], 0}, + {"id-smime-cti-ets-proofOfOrigin", "id-smime-cti-ets-proofOfOrigin", + NID_id_smime_cti_ets_proofOfOrigin, 11, &kObjectData[1794], 0}, + {"id-smime-cti-ets-proofOfReceipt", "id-smime-cti-ets-proofOfReceipt", + NID_id_smime_cti_ets_proofOfReceipt, 11, &kObjectData[1805], 0}, + {"id-smime-cti-ets-proofOfDelivery", "id-smime-cti-ets-proofOfDelivery", + NID_id_smime_cti_ets_proofOfDelivery, 11, &kObjectData[1816], 0}, + {"id-smime-cti-ets-proofOfSender", "id-smime-cti-ets-proofOfSender", + NID_id_smime_cti_ets_proofOfSender, 11, &kObjectData[1827], 0}, + {"id-smime-cti-ets-proofOfApproval", "id-smime-cti-ets-proofOfApproval", + NID_id_smime_cti_ets_proofOfApproval, 11, &kObjectData[1838], 0}, + {"id-smime-cti-ets-proofOfCreation", "id-smime-cti-ets-proofOfCreation", + NID_id_smime_cti_ets_proofOfCreation, 11, &kObjectData[1849], 0}, + {"MD4", "md4", NID_md4, 8, &kObjectData[1860], 0}, + {"id-pkix-mod", "id-pkix-mod", NID_id_pkix_mod, 7, &kObjectData[1868], 0}, + {"id-qt", "id-qt", NID_id_qt, 7, &kObjectData[1875], 0}, + {"id-it", "id-it", NID_id_it, 7, &kObjectData[1882], 0}, + {"id-pkip", "id-pkip", NID_id_pkip, 7, &kObjectData[1889], 0}, + {"id-alg", "id-alg", NID_id_alg, 7, &kObjectData[1896], 0}, + {"id-cmc", "id-cmc", NID_id_cmc, 7, &kObjectData[1903], 0}, + {"id-on", "id-on", NID_id_on, 7, &kObjectData[1910], 0}, + {"id-pda", "id-pda", NID_id_pda, 7, &kObjectData[1917], 0}, + {"id-aca", "id-aca", NID_id_aca, 7, &kObjectData[1924], 0}, + {"id-qcs", "id-qcs", NID_id_qcs, 7, &kObjectData[1931], 0}, + {"id-cct", "id-cct", NID_id_cct, 7, &kObjectData[1938], 0}, + {"id-pkix1-explicit-88", "id-pkix1-explicit-88", NID_id_pkix1_explicit_88, + 8, &kObjectData[1945], 0}, + {"id-pkix1-implicit-88", "id-pkix1-implicit-88", NID_id_pkix1_implicit_88, + 8, &kObjectData[1953], 0}, + {"id-pkix1-explicit-93", "id-pkix1-explicit-93", NID_id_pkix1_explicit_93, + 8, &kObjectData[1961], 0}, + {"id-pkix1-implicit-93", "id-pkix1-implicit-93", NID_id_pkix1_implicit_93, + 8, &kObjectData[1969], 0}, + {"id-mod-crmf", "id-mod-crmf", NID_id_mod_crmf, 8, &kObjectData[1977], 0}, + {"id-mod-cmc", "id-mod-cmc", NID_id_mod_cmc, 8, &kObjectData[1985], 0}, + {"id-mod-kea-profile-88", "id-mod-kea-profile-88", + NID_id_mod_kea_profile_88, 8, &kObjectData[1993], 0}, + {"id-mod-kea-profile-93", "id-mod-kea-profile-93", + NID_id_mod_kea_profile_93, 8, &kObjectData[2001], 0}, + {"id-mod-cmp", "id-mod-cmp", NID_id_mod_cmp, 8, &kObjectData[2009], 0}, + {"id-mod-qualified-cert-88", "id-mod-qualified-cert-88", + NID_id_mod_qualified_cert_88, 8, &kObjectData[2017], 0}, + {"id-mod-qualified-cert-93", "id-mod-qualified-cert-93", + NID_id_mod_qualified_cert_93, 8, &kObjectData[2025], 0}, + {"id-mod-attribute-cert", "id-mod-attribute-cert", + NID_id_mod_attribute_cert, 8, &kObjectData[2033], 0}, + {"id-mod-timestamp-protocol", "id-mod-timestamp-protocol", + NID_id_mod_timestamp_protocol, 8, &kObjectData[2041], 0}, + {"id-mod-ocsp", "id-mod-ocsp", NID_id_mod_ocsp, 8, &kObjectData[2049], 0}, + {"id-mod-dvcs", "id-mod-dvcs", NID_id_mod_dvcs, 8, &kObjectData[2057], 0}, + {"id-mod-cmp2000", "id-mod-cmp2000", NID_id_mod_cmp2000, 8, + &kObjectData[2065], 0}, + {"biometricInfo", "Biometric Info", NID_biometricInfo, 8, + &kObjectData[2073], 0}, + {"qcStatements", "qcStatements", NID_qcStatements, 8, &kObjectData[2081], + 0}, + {"ac-auditEntity", "ac-auditEntity", NID_ac_auditEntity, 8, + &kObjectData[2089], 0}, + {"ac-targeting", "ac-targeting", NID_ac_targeting, 8, &kObjectData[2097], + 0}, + {"aaControls", "aaControls", NID_aaControls, 8, &kObjectData[2105], 0}, + {"sbgp-ipAddrBlock", "sbgp-ipAddrBlock", NID_sbgp_ipAddrBlock, 8, + &kObjectData[2113], 0}, + {"sbgp-autonomousSysNum", "sbgp-autonomousSysNum", + NID_sbgp_autonomousSysNum, 8, &kObjectData[2121], 0}, + {"sbgp-routerIdentifier", "sbgp-routerIdentifier", + NID_sbgp_routerIdentifier, 8, &kObjectData[2129], 0}, + {"textNotice", "textNotice", NID_textNotice, 8, &kObjectData[2137], 0}, + {"ipsecEndSystem", "IPSec End System", NID_ipsecEndSystem, 8, + &kObjectData[2145], 0}, + {"ipsecTunnel", "IPSec Tunnel", NID_ipsecTunnel, 8, &kObjectData[2153], 0}, + {"ipsecUser", "IPSec User", NID_ipsecUser, 8, &kObjectData[2161], 0}, + {"DVCS", "dvcs", NID_dvcs, 8, &kObjectData[2169], 0}, + {"id-it-caProtEncCert", "id-it-caProtEncCert", NID_id_it_caProtEncCert, 8, + &kObjectData[2177], 0}, + {"id-it-signKeyPairTypes", "id-it-signKeyPairTypes", + NID_id_it_signKeyPairTypes, 8, &kObjectData[2185], 0}, + {"id-it-encKeyPairTypes", "id-it-encKeyPairTypes", + NID_id_it_encKeyPairTypes, 8, &kObjectData[2193], 0}, + {"id-it-preferredSymmAlg", "id-it-preferredSymmAlg", + NID_id_it_preferredSymmAlg, 8, &kObjectData[2201], 0}, + {"id-it-caKeyUpdateInfo", "id-it-caKeyUpdateInfo", + NID_id_it_caKeyUpdateInfo, 8, &kObjectData[2209], 0}, + {"id-it-currentCRL", "id-it-currentCRL", NID_id_it_currentCRL, 8, + &kObjectData[2217], 0}, + {"id-it-unsupportedOIDs", "id-it-unsupportedOIDs", + NID_id_it_unsupportedOIDs, 8, &kObjectData[2225], 0}, + {"id-it-subscriptionRequest", "id-it-subscriptionRequest", + NID_id_it_subscriptionRequest, 8, &kObjectData[2233], 0}, + {"id-it-subscriptionResponse", "id-it-subscriptionResponse", + NID_id_it_subscriptionResponse, 8, &kObjectData[2241], 0}, + {"id-it-keyPairParamReq", "id-it-keyPairParamReq", + NID_id_it_keyPairParamReq, 8, &kObjectData[2249], 0}, + {"id-it-keyPairParamRep", "id-it-keyPairParamRep", + NID_id_it_keyPairParamRep, 8, &kObjectData[2257], 0}, + {"id-it-revPassphrase", "id-it-revPassphrase", NID_id_it_revPassphrase, 8, + &kObjectData[2265], 0}, + {"id-it-implicitConfirm", "id-it-implicitConfirm", + NID_id_it_implicitConfirm, 8, &kObjectData[2273], 0}, + {"id-it-confirmWaitTime", "id-it-confirmWaitTime", + NID_id_it_confirmWaitTime, 8, &kObjectData[2281], 0}, + {"id-it-origPKIMessage", "id-it-origPKIMessage", NID_id_it_origPKIMessage, + 8, &kObjectData[2289], 0}, + {"id-regCtrl", "id-regCtrl", NID_id_regCtrl, 8, &kObjectData[2297], 0}, + {"id-regInfo", "id-regInfo", NID_id_regInfo, 8, &kObjectData[2305], 0}, + {"id-regCtrl-regToken", "id-regCtrl-regToken", NID_id_regCtrl_regToken, 9, + &kObjectData[2313], 0}, + {"id-regCtrl-authenticator", "id-regCtrl-authenticator", + NID_id_regCtrl_authenticator, 9, &kObjectData[2322], 0}, + {"id-regCtrl-pkiPublicationInfo", "id-regCtrl-pkiPublicationInfo", + NID_id_regCtrl_pkiPublicationInfo, 9, &kObjectData[2331], 0}, + {"id-regCtrl-pkiArchiveOptions", "id-regCtrl-pkiArchiveOptions", + NID_id_regCtrl_pkiArchiveOptions, 9, &kObjectData[2340], 0}, + {"id-regCtrl-oldCertID", "id-regCtrl-oldCertID", NID_id_regCtrl_oldCertID, + 9, &kObjectData[2349], 0}, + {"id-regCtrl-protocolEncrKey", "id-regCtrl-protocolEncrKey", + NID_id_regCtrl_protocolEncrKey, 9, &kObjectData[2358], 0}, + {"id-regInfo-utf8Pairs", "id-regInfo-utf8Pairs", NID_id_regInfo_utf8Pairs, + 9, &kObjectData[2367], 0}, + {"id-regInfo-certReq", "id-regInfo-certReq", NID_id_regInfo_certReq, 9, + &kObjectData[2376], 0}, + {"id-alg-des40", "id-alg-des40", NID_id_alg_des40, 8, &kObjectData[2385], + 0}, + {"id-alg-noSignature", "id-alg-noSignature", NID_id_alg_noSignature, 8, + &kObjectData[2393], 0}, + {"id-alg-dh-sig-hmac-sha1", "id-alg-dh-sig-hmac-sha1", + NID_id_alg_dh_sig_hmac_sha1, 8, &kObjectData[2401], 0}, + {"id-alg-dh-pop", "id-alg-dh-pop", NID_id_alg_dh_pop, 8, &kObjectData[2409], + 0}, + {"id-cmc-statusInfo", "id-cmc-statusInfo", NID_id_cmc_statusInfo, 8, + &kObjectData[2417], 0}, + {"id-cmc-identification", "id-cmc-identification", + NID_id_cmc_identification, 8, &kObjectData[2425], 0}, + {"id-cmc-identityProof", "id-cmc-identityProof", NID_id_cmc_identityProof, + 8, &kObjectData[2433], 0}, + {"id-cmc-dataReturn", "id-cmc-dataReturn", NID_id_cmc_dataReturn, 8, + &kObjectData[2441], 0}, + {"id-cmc-transactionId", "id-cmc-transactionId", NID_id_cmc_transactionId, + 8, &kObjectData[2449], 0}, + {"id-cmc-senderNonce", "id-cmc-senderNonce", NID_id_cmc_senderNonce, 8, + &kObjectData[2457], 0}, + {"id-cmc-recipientNonce", "id-cmc-recipientNonce", + NID_id_cmc_recipientNonce, 8, &kObjectData[2465], 0}, + {"id-cmc-addExtensions", "id-cmc-addExtensions", NID_id_cmc_addExtensions, + 8, &kObjectData[2473], 0}, + {"id-cmc-encryptedPOP", "id-cmc-encryptedPOP", NID_id_cmc_encryptedPOP, 8, + &kObjectData[2481], 0}, + {"id-cmc-decryptedPOP", "id-cmc-decryptedPOP", NID_id_cmc_decryptedPOP, 8, + &kObjectData[2489], 0}, + {"id-cmc-lraPOPWitness", "id-cmc-lraPOPWitness", NID_id_cmc_lraPOPWitness, + 8, &kObjectData[2497], 0}, + {"id-cmc-getCert", "id-cmc-getCert", NID_id_cmc_getCert, 8, + &kObjectData[2505], 0}, + {"id-cmc-getCRL", "id-cmc-getCRL", NID_id_cmc_getCRL, 8, &kObjectData[2513], + 0}, + {"id-cmc-revokeRequest", "id-cmc-revokeRequest", NID_id_cmc_revokeRequest, + 8, &kObjectData[2521], 0}, + {"id-cmc-regInfo", "id-cmc-regInfo", NID_id_cmc_regInfo, 8, + &kObjectData[2529], 0}, + {"id-cmc-responseInfo", "id-cmc-responseInfo", NID_id_cmc_responseInfo, 8, + &kObjectData[2537], 0}, + {"id-cmc-queryPending", "id-cmc-queryPending", NID_id_cmc_queryPending, 8, + &kObjectData[2545], 0}, + {"id-cmc-popLinkRandom", "id-cmc-popLinkRandom", NID_id_cmc_popLinkRandom, + 8, &kObjectData[2553], 0}, + {"id-cmc-popLinkWitness", "id-cmc-popLinkWitness", + NID_id_cmc_popLinkWitness, 8, &kObjectData[2561], 0}, + {"id-cmc-confirmCertAcceptance", "id-cmc-confirmCertAcceptance", + NID_id_cmc_confirmCertAcceptance, 8, &kObjectData[2569], 0}, + {"id-on-personalData", "id-on-personalData", NID_id_on_personalData, 8, + &kObjectData[2577], 0}, + {"id-pda-dateOfBirth", "id-pda-dateOfBirth", NID_id_pda_dateOfBirth, 8, + &kObjectData[2585], 0}, + {"id-pda-placeOfBirth", "id-pda-placeOfBirth", NID_id_pda_placeOfBirth, 8, + &kObjectData[2593], 0}, + {NULL, NULL, NID_undef, 0, NULL, 0}, + {"id-pda-gender", "id-pda-gender", NID_id_pda_gender, 8, &kObjectData[2601], + 0}, + {"id-pda-countryOfCitizenship", "id-pda-countryOfCitizenship", + NID_id_pda_countryOfCitizenship, 8, &kObjectData[2609], 0}, + {"id-pda-countryOfResidence", "id-pda-countryOfResidence", + NID_id_pda_countryOfResidence, 8, &kObjectData[2617], 0}, + {"id-aca-authenticationInfo", "id-aca-authenticationInfo", + NID_id_aca_authenticationInfo, 8, &kObjectData[2625], 0}, + {"id-aca-accessIdentity", "id-aca-accessIdentity", + NID_id_aca_accessIdentity, 8, &kObjectData[2633], 0}, + {"id-aca-chargingIdentity", "id-aca-chargingIdentity", + NID_id_aca_chargingIdentity, 8, &kObjectData[2641], 0}, + {"id-aca-group", "id-aca-group", NID_id_aca_group, 8, &kObjectData[2649], + 0}, + {"id-aca-role", "id-aca-role", NID_id_aca_role, 8, &kObjectData[2657], 0}, + {"id-qcs-pkixQCSyntax-v1", "id-qcs-pkixQCSyntax-v1", + NID_id_qcs_pkixQCSyntax_v1, 8, &kObjectData[2665], 0}, + {"id-cct-crs", "id-cct-crs", NID_id_cct_crs, 8, &kObjectData[2673], 0}, + {"id-cct-PKIData", "id-cct-PKIData", NID_id_cct_PKIData, 8, + &kObjectData[2681], 0}, + {"id-cct-PKIResponse", "id-cct-PKIResponse", NID_id_cct_PKIResponse, 8, + &kObjectData[2689], 0}, + {"ad_timestamping", "AD Time Stamping", NID_ad_timeStamping, 8, + &kObjectData[2697], 0}, + {"AD_DVCS", "ad dvcs", NID_ad_dvcs, 8, &kObjectData[2705], 0}, + {"basicOCSPResponse", "Basic OCSP Response", NID_id_pkix_OCSP_basic, 9, + &kObjectData[2713], 0}, + {"Nonce", "OCSP Nonce", NID_id_pkix_OCSP_Nonce, 9, &kObjectData[2722], 0}, + {"CrlID", "OCSP CRL ID", NID_id_pkix_OCSP_CrlID, 9, &kObjectData[2731], 0}, + {"acceptableResponses", "Acceptable OCSP Responses", + NID_id_pkix_OCSP_acceptableResponses, 9, &kObjectData[2740], 0}, + {"noCheck", "OCSP No Check", NID_id_pkix_OCSP_noCheck, 9, + &kObjectData[2749], 0}, + {"archiveCutoff", "OCSP Archive Cutoff", NID_id_pkix_OCSP_archiveCutoff, 9, + &kObjectData[2758], 0}, + {"serviceLocator", "OCSP Service Locator", NID_id_pkix_OCSP_serviceLocator, + 9, &kObjectData[2767], 0}, + {"extendedStatus", "Extended OCSP Status", NID_id_pkix_OCSP_extendedStatus, + 9, &kObjectData[2776], 0}, + {"valid", "valid", NID_id_pkix_OCSP_valid, 9, &kObjectData[2785], 0}, + {"path", "path", NID_id_pkix_OCSP_path, 9, &kObjectData[2794], 0}, + {"trustRoot", "Trust Root", NID_id_pkix_OCSP_trustRoot, 9, + &kObjectData[2803], 0}, + {"algorithm", "algorithm", NID_algorithm, 4, &kObjectData[2812], 0}, + {"rsaSignature", "rsaSignature", NID_rsaSignature, 5, &kObjectData[2816], + 0}, + {"X500algorithms", "directory services - algorithms", NID_X500algorithms, 2, + &kObjectData[2821], 0}, + {"ORG", "org", NID_org, 1, &kObjectData[2823], 0}, + {"DOD", "dod", NID_dod, 2, &kObjectData[2824], 0}, + {"IANA", "iana", NID_iana, 3, &kObjectData[2826], 0}, + {"directory", "Directory", NID_Directory, 4, &kObjectData[2829], 0}, + {"mgmt", "Management", NID_Management, 4, &kObjectData[2833], 0}, + {"experimental", "Experimental", NID_Experimental, 4, &kObjectData[2837], + 0}, + {"private", "Private", NID_Private, 4, &kObjectData[2841], 0}, + {"security", "Security", NID_Security, 4, &kObjectData[2845], 0}, + {"snmpv2", "SNMPv2", NID_SNMPv2, 4, &kObjectData[2849], 0}, + {"Mail", "Mail", NID_Mail, 4, &kObjectData[2853], 0}, + {"enterprises", "Enterprises", NID_Enterprises, 5, &kObjectData[2857], 0}, + {"dcobject", "dcObject", NID_dcObject, 9, &kObjectData[2862], 0}, + {"DC", "domainComponent", NID_domainComponent, 10, &kObjectData[2871], 0}, + {"domain", "Domain", NID_Domain, 10, &kObjectData[2881], 0}, + {NULL, NULL, NID_undef, 0, NULL, 0}, + {"selected-attribute-types", "Selected Attribute Types", + NID_selected_attribute_types, 3, &kObjectData[2891], 0}, + {"clearance", "clearance", NID_clearance, 4, &kObjectData[2894], 0}, + {"RSA-MD4", "md4WithRSAEncryption", NID_md4WithRSAEncryption, 9, + &kObjectData[2898], 0}, + {"ac-proxying", "ac-proxying", NID_ac_proxying, 8, &kObjectData[2907], 0}, + {"subjectInfoAccess", "Subject Information Access", NID_sinfo_access, 8, + &kObjectData[2915], 0}, + {"id-aca-encAttrs", "id-aca-encAttrs", NID_id_aca_encAttrs, 8, + &kObjectData[2923], 0}, + {"role", "role", NID_role, 3, &kObjectData[2931], 0}, + {"policyConstraints", "X509v3 Policy Constraints", NID_policy_constraints, + 3, &kObjectData[2934], 0}, + {"targetInformation", "X509v3 AC Targeting", NID_target_information, 3, + &kObjectData[2937], 0}, + {"noRevAvail", "X509v3 No Revocation Available", NID_no_rev_avail, 3, + &kObjectData[2940], 0}, + {NULL, NULL, NID_undef, 0, NULL, 0}, + {"ansi-X9-62", "ANSI X9.62", NID_ansi_X9_62, 5, &kObjectData[2943], 0}, + {"prime-field", "prime-field", NID_X9_62_prime_field, 7, &kObjectData[2948], + 0}, + {"characteristic-two-field", "characteristic-two-field", + NID_X9_62_characteristic_two_field, 7, &kObjectData[2955], 0}, + {"id-ecPublicKey", "id-ecPublicKey", NID_X9_62_id_ecPublicKey, 7, + &kObjectData[2962], 0}, + {"prime192v1", "prime192v1", NID_X9_62_prime192v1, 8, &kObjectData[2969], + 0}, + {"prime192v2", "prime192v2", NID_X9_62_prime192v2, 8, &kObjectData[2977], + 0}, + {"prime192v3", "prime192v3", NID_X9_62_prime192v3, 8, &kObjectData[2985], + 0}, + {"prime239v1", "prime239v1", NID_X9_62_prime239v1, 8, &kObjectData[2993], + 0}, + {"prime239v2", "prime239v2", NID_X9_62_prime239v2, 8, &kObjectData[3001], + 0}, + {"prime239v3", "prime239v3", NID_X9_62_prime239v3, 8, &kObjectData[3009], + 0}, + {"prime256v1", "prime256v1", NID_X9_62_prime256v1, 8, &kObjectData[3017], + 0}, + {"ecdsa-with-SHA1", "ecdsa-with-SHA1", NID_ecdsa_with_SHA1, 7, + &kObjectData[3025], 0}, + {"CSPName", "Microsoft CSP Name", NID_ms_csp_name, 9, &kObjectData[3032], + 0}, + {"AES-128-ECB", "aes-128-ecb", NID_aes_128_ecb, 9, &kObjectData[3041], 0}, + {"AES-128-CBC", "aes-128-cbc", NID_aes_128_cbc, 9, &kObjectData[3050], 0}, + {"AES-128-OFB", "aes-128-ofb", NID_aes_128_ofb128, 9, &kObjectData[3059], + 0}, + {"AES-128-CFB", "aes-128-cfb", NID_aes_128_cfb128, 9, &kObjectData[3068], + 0}, + {"AES-192-ECB", "aes-192-ecb", NID_aes_192_ecb, 9, &kObjectData[3077], 0}, + {"AES-192-CBC", "aes-192-cbc", NID_aes_192_cbc, 9, &kObjectData[3086], 0}, + {"AES-192-OFB", "aes-192-ofb", NID_aes_192_ofb128, 9, &kObjectData[3095], + 0}, + {"AES-192-CFB", "aes-192-cfb", NID_aes_192_cfb128, 9, &kObjectData[3104], + 0}, + {"AES-256-ECB", "aes-256-ecb", NID_aes_256_ecb, 9, &kObjectData[3113], 0}, + {"AES-256-CBC", "aes-256-cbc", NID_aes_256_cbc, 9, &kObjectData[3122], 0}, + {"AES-256-OFB", "aes-256-ofb", NID_aes_256_ofb128, 9, &kObjectData[3131], + 0}, + {"AES-256-CFB", "aes-256-cfb", NID_aes_256_cfb128, 9, &kObjectData[3140], + 0}, + {"holdInstructionCode", "Hold Instruction Code", NID_hold_instruction_code, + 3, &kObjectData[3149], 0}, + {"holdInstructionNone", "Hold Instruction None", NID_hold_instruction_none, + 7, &kObjectData[3152], 0}, + {"holdInstructionCallIssuer", "Hold Instruction Call Issuer", + NID_hold_instruction_call_issuer, 7, &kObjectData[3159], 0}, + {"holdInstructionReject", "Hold Instruction Reject", + NID_hold_instruction_reject, 7, &kObjectData[3166], 0}, + {"data", "data", NID_data, 1, &kObjectData[3173], 0}, + {"pss", "pss", NID_pss, 3, &kObjectData[3174], 0}, + {"ucl", "ucl", NID_ucl, 7, &kObjectData[3177], 0}, + {"pilot", "pilot", NID_pilot, 8, &kObjectData[3184], 0}, + {"pilotAttributeType", "pilotAttributeType", NID_pilotAttributeType, 9, + &kObjectData[3192], 0}, + {"pilotAttributeSyntax", "pilotAttributeSyntax", NID_pilotAttributeSyntax, + 9, &kObjectData[3201], 0}, + {"pilotObjectClass", "pilotObjectClass", NID_pilotObjectClass, 9, + &kObjectData[3210], 0}, + {"pilotGroups", "pilotGroups", NID_pilotGroups, 9, &kObjectData[3219], 0}, + {"iA5StringSyntax", "iA5StringSyntax", NID_iA5StringSyntax, 10, + &kObjectData[3228], 0}, + {"caseIgnoreIA5StringSyntax", "caseIgnoreIA5StringSyntax", + NID_caseIgnoreIA5StringSyntax, 10, &kObjectData[3238], 0}, + {"pilotObject", "pilotObject", NID_pilotObject, 10, &kObjectData[3248], 0}, + {"pilotPerson", "pilotPerson", NID_pilotPerson, 10, &kObjectData[3258], 0}, + {"account", "account", NID_account, 10, &kObjectData[3268], 0}, + {"document", "document", NID_document, 10, &kObjectData[3278], 0}, + {"room", "room", NID_room, 10, &kObjectData[3288], 0}, + {"documentSeries", "documentSeries", NID_documentSeries, 10, + &kObjectData[3298], 0}, + {"rFC822localPart", "rFC822localPart", NID_rFC822localPart, 10, + &kObjectData[3308], 0}, + {"dNSDomain", "dNSDomain", NID_dNSDomain, 10, &kObjectData[3318], 0}, + {"domainRelatedObject", "domainRelatedObject", NID_domainRelatedObject, 10, + &kObjectData[3328], 0}, + {"friendlyCountry", "friendlyCountry", NID_friendlyCountry, 10, + &kObjectData[3338], 0}, + {"simpleSecurityObject", "simpleSecurityObject", NID_simpleSecurityObject, + 10, &kObjectData[3348], 0}, + {"pilotOrganization", "pilotOrganization", NID_pilotOrganization, 10, + &kObjectData[3358], 0}, + {"pilotDSA", "pilotDSA", NID_pilotDSA, 10, &kObjectData[3368], 0}, + {"qualityLabelledData", "qualityLabelledData", NID_qualityLabelledData, 10, + &kObjectData[3378], 0}, + {"UID", "userId", NID_userId, 10, &kObjectData[3388], 0}, + {"textEncodedORAddress", "textEncodedORAddress", NID_textEncodedORAddress, + 10, &kObjectData[3398], 0}, + {"mail", "rfc822Mailbox", NID_rfc822Mailbox, 10, &kObjectData[3408], 0}, + {"info", "info", NID_info, 10, &kObjectData[3418], 0}, + {"favouriteDrink", "favouriteDrink", NID_favouriteDrink, 10, + &kObjectData[3428], 0}, + {"roomNumber", "roomNumber", NID_roomNumber, 10, &kObjectData[3438], 0}, + {"photo", "photo", NID_photo, 10, &kObjectData[3448], 0}, + {"userClass", "userClass", NID_userClass, 10, &kObjectData[3458], 0}, + {"host", "host", NID_host, 10, &kObjectData[3468], 0}, + {"manager", "manager", NID_manager, 10, &kObjectData[3478], 0}, + {"documentIdentifier", "documentIdentifier", NID_documentIdentifier, 10, + &kObjectData[3488], 0}, + {"documentTitle", "documentTitle", NID_documentTitle, 10, + &kObjectData[3498], 0}, + {"documentVersion", "documentVersion", NID_documentVersion, 10, + &kObjectData[3508], 0}, + {"documentAuthor", "documentAuthor", NID_documentAuthor, 10, + &kObjectData[3518], 0}, + {"documentLocation", "documentLocation", NID_documentLocation, 10, + &kObjectData[3528], 0}, + {"homeTelephoneNumber", "homeTelephoneNumber", NID_homeTelephoneNumber, 10, + &kObjectData[3538], 0}, + {"secretary", "secretary", NID_secretary, 10, &kObjectData[3548], 0}, + {"otherMailbox", "otherMailbox", NID_otherMailbox, 10, &kObjectData[3558], + 0}, + {"lastModifiedTime", "lastModifiedTime", NID_lastModifiedTime, 10, + &kObjectData[3568], 0}, + {"lastModifiedBy", "lastModifiedBy", NID_lastModifiedBy, 10, + &kObjectData[3578], 0}, + {"aRecord", "aRecord", NID_aRecord, 10, &kObjectData[3588], 0}, + {"pilotAttributeType27", "pilotAttributeType27", NID_pilotAttributeType27, + 10, &kObjectData[3598], 0}, + {"mXRecord", "mXRecord", NID_mXRecord, 10, &kObjectData[3608], 0}, + {"nSRecord", "nSRecord", NID_nSRecord, 10, &kObjectData[3618], 0}, + {"sOARecord", "sOARecord", NID_sOARecord, 10, &kObjectData[3628], 0}, + {"cNAMERecord", "cNAMERecord", NID_cNAMERecord, 10, &kObjectData[3638], 0}, + {"associatedDomain", "associatedDomain", NID_associatedDomain, 10, + &kObjectData[3648], 0}, + {"associatedName", "associatedName", NID_associatedName, 10, + &kObjectData[3658], 0}, + {"homePostalAddress", "homePostalAddress", NID_homePostalAddress, 10, + &kObjectData[3668], 0}, + {"personalTitle", "personalTitle", NID_personalTitle, 10, + &kObjectData[3678], 0}, + {"mobileTelephoneNumber", "mobileTelephoneNumber", + NID_mobileTelephoneNumber, 10, &kObjectData[3688], 0}, + {"pagerTelephoneNumber", "pagerTelephoneNumber", NID_pagerTelephoneNumber, + 10, &kObjectData[3698], 0}, + {"friendlyCountryName", "friendlyCountryName", NID_friendlyCountryName, 10, + &kObjectData[3708], 0}, + {"organizationalStatus", "organizationalStatus", NID_organizationalStatus, + 10, &kObjectData[3718], 0}, + {"janetMailbox", "janetMailbox", NID_janetMailbox, 10, &kObjectData[3728], + 0}, + {"mailPreferenceOption", "mailPreferenceOption", NID_mailPreferenceOption, + 10, &kObjectData[3738], 0}, + {"buildingName", "buildingName", NID_buildingName, 10, &kObjectData[3748], + 0}, + {"dSAQuality", "dSAQuality", NID_dSAQuality, 10, &kObjectData[3758], 0}, + {"singleLevelQuality", "singleLevelQuality", NID_singleLevelQuality, 10, + &kObjectData[3768], 0}, + {"subtreeMinimumQuality", "subtreeMinimumQuality", + NID_subtreeMinimumQuality, 10, &kObjectData[3778], 0}, + {"subtreeMaximumQuality", "subtreeMaximumQuality", + NID_subtreeMaximumQuality, 10, &kObjectData[3788], 0}, + {"personalSignature", "personalSignature", NID_personalSignature, 10, + &kObjectData[3798], 0}, + {"dITRedirect", "dITRedirect", NID_dITRedirect, 10, &kObjectData[3808], 0}, + {"audio", "audio", NID_audio, 10, &kObjectData[3818], 0}, + {"documentPublisher", "documentPublisher", NID_documentPublisher, 10, + &kObjectData[3828], 0}, + {"x500UniqueIdentifier", "x500UniqueIdentifier", NID_x500UniqueIdentifier, + 3, &kObjectData[3838], 0}, + {"mime-mhs", "MIME MHS", NID_mime_mhs, 5, &kObjectData[3841], 0}, + {"mime-mhs-headings", "mime-mhs-headings", NID_mime_mhs_headings, 6, + &kObjectData[3846], 0}, + {"mime-mhs-bodies", "mime-mhs-bodies", NID_mime_mhs_bodies, 6, + &kObjectData[3852], 0}, + {"id-hex-partial-message", "id-hex-partial-message", + NID_id_hex_partial_message, 7, &kObjectData[3858], 0}, + {"id-hex-multipart-message", "id-hex-multipart-message", + NID_id_hex_multipart_message, 7, &kObjectData[3865], 0}, + {"generationQualifier", "generationQualifier", NID_generationQualifier, 3, + &kObjectData[3872], 0}, + {"pseudonym", "pseudonym", NID_pseudonym, 3, &kObjectData[3875], 0}, + {NULL, NULL, NID_undef, 0, NULL, 0}, + {"id-set", "Secure Electronic Transactions", NID_id_set, 2, + &kObjectData[3878], 0}, + {"set-ctype", "content types", NID_set_ctype, 3, &kObjectData[3880], 0}, + {"set-msgExt", "message extensions", NID_set_msgExt, 3, &kObjectData[3883], + 0}, + {"set-attr", "set-attr", NID_set_attr, 3, &kObjectData[3886], 0}, + {"set-policy", "set-policy", NID_set_policy, 3, &kObjectData[3889], 0}, + {"set-certExt", "certificate extensions", NID_set_certExt, 3, + &kObjectData[3892], 0}, + {"set-brand", "set-brand", NID_set_brand, 3, &kObjectData[3895], 0}, + {"setct-PANData", "setct-PANData", NID_setct_PANData, 4, &kObjectData[3898], + 0}, + {"setct-PANToken", "setct-PANToken", NID_setct_PANToken, 4, + &kObjectData[3902], 0}, + {"setct-PANOnly", "setct-PANOnly", NID_setct_PANOnly, 4, &kObjectData[3906], + 0}, + {"setct-OIData", "setct-OIData", NID_setct_OIData, 4, &kObjectData[3910], + 0}, + {"setct-PI", "setct-PI", NID_setct_PI, 4, &kObjectData[3914], 0}, + {"setct-PIData", "setct-PIData", NID_setct_PIData, 4, &kObjectData[3918], + 0}, + {"setct-PIDataUnsigned", "setct-PIDataUnsigned", NID_setct_PIDataUnsigned, + 4, &kObjectData[3922], 0}, + {"setct-HODInput", "setct-HODInput", NID_setct_HODInput, 4, + &kObjectData[3926], 0}, + {"setct-AuthResBaggage", "setct-AuthResBaggage", NID_setct_AuthResBaggage, + 4, &kObjectData[3930], 0}, + {"setct-AuthRevReqBaggage", "setct-AuthRevReqBaggage", + NID_setct_AuthRevReqBaggage, 4, &kObjectData[3934], 0}, + {"setct-AuthRevResBaggage", "setct-AuthRevResBaggage", + NID_setct_AuthRevResBaggage, 4, &kObjectData[3938], 0}, + {"setct-CapTokenSeq", "setct-CapTokenSeq", NID_setct_CapTokenSeq, 4, + &kObjectData[3942], 0}, + {"setct-PInitResData", "setct-PInitResData", NID_setct_PInitResData, 4, + &kObjectData[3946], 0}, + {"setct-PI-TBS", "setct-PI-TBS", NID_setct_PI_TBS, 4, &kObjectData[3950], + 0}, + {"setct-PResData", "setct-PResData", NID_setct_PResData, 4, + &kObjectData[3954], 0}, + {"setct-AuthReqTBS", "setct-AuthReqTBS", NID_setct_AuthReqTBS, 4, + &kObjectData[3958], 0}, + {"setct-AuthResTBS", "setct-AuthResTBS", NID_setct_AuthResTBS, 4, + &kObjectData[3962], 0}, + {"setct-AuthResTBSX", "setct-AuthResTBSX", NID_setct_AuthResTBSX, 4, + &kObjectData[3966], 0}, + {"setct-AuthTokenTBS", "setct-AuthTokenTBS", NID_setct_AuthTokenTBS, 4, + &kObjectData[3970], 0}, + {"setct-CapTokenData", "setct-CapTokenData", NID_setct_CapTokenData, 4, + &kObjectData[3974], 0}, + {"setct-CapTokenTBS", "setct-CapTokenTBS", NID_setct_CapTokenTBS, 4, + &kObjectData[3978], 0}, + {"setct-AcqCardCodeMsg", "setct-AcqCardCodeMsg", NID_setct_AcqCardCodeMsg, + 4, &kObjectData[3982], 0}, + {"setct-AuthRevReqTBS", "setct-AuthRevReqTBS", NID_setct_AuthRevReqTBS, 4, + &kObjectData[3986], 0}, + {"setct-AuthRevResData", "setct-AuthRevResData", NID_setct_AuthRevResData, + 4, &kObjectData[3990], 0}, + {"setct-AuthRevResTBS", "setct-AuthRevResTBS", NID_setct_AuthRevResTBS, 4, + &kObjectData[3994], 0}, + {"setct-CapReqTBS", "setct-CapReqTBS", NID_setct_CapReqTBS, 4, + &kObjectData[3998], 0}, + {"setct-CapReqTBSX", "setct-CapReqTBSX", NID_setct_CapReqTBSX, 4, + &kObjectData[4002], 0}, + {"setct-CapResData", "setct-CapResData", NID_setct_CapResData, 4, + &kObjectData[4006], 0}, + {"setct-CapRevReqTBS", "setct-CapRevReqTBS", NID_setct_CapRevReqTBS, 4, + &kObjectData[4010], 0}, + {"setct-CapRevReqTBSX", "setct-CapRevReqTBSX", NID_setct_CapRevReqTBSX, 4, + &kObjectData[4014], 0}, + {"setct-CapRevResData", "setct-CapRevResData", NID_setct_CapRevResData, 4, + &kObjectData[4018], 0}, + {"setct-CredReqTBS", "setct-CredReqTBS", NID_setct_CredReqTBS, 4, + &kObjectData[4022], 0}, + {"setct-CredReqTBSX", "setct-CredReqTBSX", NID_setct_CredReqTBSX, 4, + &kObjectData[4026], 0}, + {"setct-CredResData", "setct-CredResData", NID_setct_CredResData, 4, + &kObjectData[4030], 0}, + {"setct-CredRevReqTBS", "setct-CredRevReqTBS", NID_setct_CredRevReqTBS, 4, + &kObjectData[4034], 0}, + {"setct-CredRevReqTBSX", "setct-CredRevReqTBSX", NID_setct_CredRevReqTBSX, + 4, &kObjectData[4038], 0}, + {"setct-CredRevResData", "setct-CredRevResData", NID_setct_CredRevResData, + 4, &kObjectData[4042], 0}, + {"setct-PCertReqData", "setct-PCertReqData", NID_setct_PCertReqData, 4, + &kObjectData[4046], 0}, + {"setct-PCertResTBS", "setct-PCertResTBS", NID_setct_PCertResTBS, 4, + &kObjectData[4050], 0}, + {"setct-BatchAdminReqData", "setct-BatchAdminReqData", + NID_setct_BatchAdminReqData, 4, &kObjectData[4054], 0}, + {"setct-BatchAdminResData", "setct-BatchAdminResData", + NID_setct_BatchAdminResData, 4, &kObjectData[4058], 0}, + {"setct-CardCInitResTBS", "setct-CardCInitResTBS", + NID_setct_CardCInitResTBS, 4, &kObjectData[4062], 0}, + {"setct-MeAqCInitResTBS", "setct-MeAqCInitResTBS", + NID_setct_MeAqCInitResTBS, 4, &kObjectData[4066], 0}, + {"setct-RegFormResTBS", "setct-RegFormResTBS", NID_setct_RegFormResTBS, 4, + &kObjectData[4070], 0}, + {"setct-CertReqData", "setct-CertReqData", NID_setct_CertReqData, 4, + &kObjectData[4074], 0}, + {"setct-CertReqTBS", "setct-CertReqTBS", NID_setct_CertReqTBS, 4, + &kObjectData[4078], 0}, + {"setct-CertResData", "setct-CertResData", NID_setct_CertResData, 4, + &kObjectData[4082], 0}, + {"setct-CertInqReqTBS", "setct-CertInqReqTBS", NID_setct_CertInqReqTBS, 4, + &kObjectData[4086], 0}, + {"setct-ErrorTBS", "setct-ErrorTBS", NID_setct_ErrorTBS, 4, + &kObjectData[4090], 0}, + {"setct-PIDualSignedTBE", "setct-PIDualSignedTBE", + NID_setct_PIDualSignedTBE, 4, &kObjectData[4094], 0}, + {"setct-PIUnsignedTBE", "setct-PIUnsignedTBE", NID_setct_PIUnsignedTBE, 4, + &kObjectData[4098], 0}, + {"setct-AuthReqTBE", "setct-AuthReqTBE", NID_setct_AuthReqTBE, 4, + &kObjectData[4102], 0}, + {"setct-AuthResTBE", "setct-AuthResTBE", NID_setct_AuthResTBE, 4, + &kObjectData[4106], 0}, + {"setct-AuthResTBEX", "setct-AuthResTBEX", NID_setct_AuthResTBEX, 4, + &kObjectData[4110], 0}, + {"setct-AuthTokenTBE", "setct-AuthTokenTBE", NID_setct_AuthTokenTBE, 4, + &kObjectData[4114], 0}, + {"setct-CapTokenTBE", "setct-CapTokenTBE", NID_setct_CapTokenTBE, 4, + &kObjectData[4118], 0}, + {"setct-CapTokenTBEX", "setct-CapTokenTBEX", NID_setct_CapTokenTBEX, 4, + &kObjectData[4122], 0}, + {"setct-AcqCardCodeMsgTBE", "setct-AcqCardCodeMsgTBE", + NID_setct_AcqCardCodeMsgTBE, 4, &kObjectData[4126], 0}, + {"setct-AuthRevReqTBE", "setct-AuthRevReqTBE", NID_setct_AuthRevReqTBE, 4, + &kObjectData[4130], 0}, + {"setct-AuthRevResTBE", "setct-AuthRevResTBE", NID_setct_AuthRevResTBE, 4, + &kObjectData[4134], 0}, + {"setct-AuthRevResTBEB", "setct-AuthRevResTBEB", NID_setct_AuthRevResTBEB, + 4, &kObjectData[4138], 0}, + {"setct-CapReqTBE", "setct-CapReqTBE", NID_setct_CapReqTBE, 4, + &kObjectData[4142], 0}, + {"setct-CapReqTBEX", "setct-CapReqTBEX", NID_setct_CapReqTBEX, 4, + &kObjectData[4146], 0}, + {"setct-CapResTBE", "setct-CapResTBE", NID_setct_CapResTBE, 4, + &kObjectData[4150], 0}, + {"setct-CapRevReqTBE", "setct-CapRevReqTBE", NID_setct_CapRevReqTBE, 4, + &kObjectData[4154], 0}, + {"setct-CapRevReqTBEX", "setct-CapRevReqTBEX", NID_setct_CapRevReqTBEX, 4, + &kObjectData[4158], 0}, + {"setct-CapRevResTBE", "setct-CapRevResTBE", NID_setct_CapRevResTBE, 4, + &kObjectData[4162], 0}, + {"setct-CredReqTBE", "setct-CredReqTBE", NID_setct_CredReqTBE, 4, + &kObjectData[4166], 0}, + {"setct-CredReqTBEX", "setct-CredReqTBEX", NID_setct_CredReqTBEX, 4, + &kObjectData[4170], 0}, + {"setct-CredResTBE", "setct-CredResTBE", NID_setct_CredResTBE, 4, + &kObjectData[4174], 0}, + {"setct-CredRevReqTBE", "setct-CredRevReqTBE", NID_setct_CredRevReqTBE, 4, + &kObjectData[4178], 0}, + {"setct-CredRevReqTBEX", "setct-CredRevReqTBEX", NID_setct_CredRevReqTBEX, + 4, &kObjectData[4182], 0}, + {"setct-CredRevResTBE", "setct-CredRevResTBE", NID_setct_CredRevResTBE, 4, + &kObjectData[4186], 0}, + {"setct-BatchAdminReqTBE", "setct-BatchAdminReqTBE", + NID_setct_BatchAdminReqTBE, 4, &kObjectData[4190], 0}, + {"setct-BatchAdminResTBE", "setct-BatchAdminResTBE", + NID_setct_BatchAdminResTBE, 4, &kObjectData[4194], 0}, + {"setct-RegFormReqTBE", "setct-RegFormReqTBE", NID_setct_RegFormReqTBE, 4, + &kObjectData[4198], 0}, + {"setct-CertReqTBE", "setct-CertReqTBE", NID_setct_CertReqTBE, 4, + &kObjectData[4202], 0}, + {"setct-CertReqTBEX", "setct-CertReqTBEX", NID_setct_CertReqTBEX, 4, + &kObjectData[4206], 0}, + {"setct-CertResTBE", "setct-CertResTBE", NID_setct_CertResTBE, 4, + &kObjectData[4210], 0}, + {"setct-CRLNotificationTBS", "setct-CRLNotificationTBS", + NID_setct_CRLNotificationTBS, 4, &kObjectData[4214], 0}, + {"setct-CRLNotificationResTBS", "setct-CRLNotificationResTBS", + NID_setct_CRLNotificationResTBS, 4, &kObjectData[4218], 0}, + {"setct-BCIDistributionTBS", "setct-BCIDistributionTBS", + NID_setct_BCIDistributionTBS, 4, &kObjectData[4222], 0}, + {"setext-genCrypt", "generic cryptogram", NID_setext_genCrypt, 4, + &kObjectData[4226], 0}, + {"setext-miAuth", "merchant initiated auth", NID_setext_miAuth, 4, + &kObjectData[4230], 0}, + {"setext-pinSecure", "setext-pinSecure", NID_setext_pinSecure, 4, + &kObjectData[4234], 0}, + {"setext-pinAny", "setext-pinAny", NID_setext_pinAny, 4, &kObjectData[4238], + 0}, + {"setext-track2", "setext-track2", NID_setext_track2, 4, &kObjectData[4242], + 0}, + {"setext-cv", "additional verification", NID_setext_cv, 4, + &kObjectData[4246], 0}, + {"set-policy-root", "set-policy-root", NID_set_policy_root, 4, + &kObjectData[4250], 0}, + {"setCext-hashedRoot", "setCext-hashedRoot", NID_setCext_hashedRoot, 4, + &kObjectData[4254], 0}, + {"setCext-certType", "setCext-certType", NID_setCext_certType, 4, + &kObjectData[4258], 0}, + {"setCext-merchData", "setCext-merchData", NID_setCext_merchData, 4, + &kObjectData[4262], 0}, + {"setCext-cCertRequired", "setCext-cCertRequired", + NID_setCext_cCertRequired, 4, &kObjectData[4266], 0}, + {"setCext-tunneling", "setCext-tunneling", NID_setCext_tunneling, 4, + &kObjectData[4270], 0}, + {"setCext-setExt", "setCext-setExt", NID_setCext_setExt, 4, + &kObjectData[4274], 0}, + {"setCext-setQualf", "setCext-setQualf", NID_setCext_setQualf, 4, + &kObjectData[4278], 0}, + {"setCext-PGWYcapabilities", "setCext-PGWYcapabilities", + NID_setCext_PGWYcapabilities, 4, &kObjectData[4282], 0}, + {"setCext-TokenIdentifier", "setCext-TokenIdentifier", + NID_setCext_TokenIdentifier, 4, &kObjectData[4286], 0}, + {"setCext-Track2Data", "setCext-Track2Data", NID_setCext_Track2Data, 4, + &kObjectData[4290], 0}, + {"setCext-TokenType", "setCext-TokenType", NID_setCext_TokenType, 4, + &kObjectData[4294], 0}, + {"setCext-IssuerCapabilities", "setCext-IssuerCapabilities", + NID_setCext_IssuerCapabilities, 4, &kObjectData[4298], 0}, + {"setAttr-Cert", "setAttr-Cert", NID_setAttr_Cert, 4, &kObjectData[4302], + 0}, + {"setAttr-PGWYcap", "payment gateway capabilities", NID_setAttr_PGWYcap, 4, + &kObjectData[4306], 0}, + {"setAttr-TokenType", "setAttr-TokenType", NID_setAttr_TokenType, 4, + &kObjectData[4310], 0}, + {"setAttr-IssCap", "issuer capabilities", NID_setAttr_IssCap, 4, + &kObjectData[4314], 0}, + {"set-rootKeyThumb", "set-rootKeyThumb", NID_set_rootKeyThumb, 5, + &kObjectData[4318], 0}, + {"set-addPolicy", "set-addPolicy", NID_set_addPolicy, 5, &kObjectData[4323], + 0}, + {"setAttr-Token-EMV", "setAttr-Token-EMV", NID_setAttr_Token_EMV, 5, + &kObjectData[4328], 0}, + {"setAttr-Token-B0Prime", "setAttr-Token-B0Prime", + NID_setAttr_Token_B0Prime, 5, &kObjectData[4333], 0}, + {"setAttr-IssCap-CVM", "setAttr-IssCap-CVM", NID_setAttr_IssCap_CVM, 5, + &kObjectData[4338], 0}, + {"setAttr-IssCap-T2", "setAttr-IssCap-T2", NID_setAttr_IssCap_T2, 5, + &kObjectData[4343], 0}, + {"setAttr-IssCap-Sig", "setAttr-IssCap-Sig", NID_setAttr_IssCap_Sig, 5, + &kObjectData[4348], 0}, + {"setAttr-GenCryptgrm", "generate cryptogram", NID_setAttr_GenCryptgrm, 6, + &kObjectData[4353], 0}, + {"setAttr-T2Enc", "encrypted track 2", NID_setAttr_T2Enc, 6, + &kObjectData[4359], 0}, + {"setAttr-T2cleartxt", "cleartext track 2", NID_setAttr_T2cleartxt, 6, + &kObjectData[4365], 0}, + {"setAttr-TokICCsig", "ICC or token signature", NID_setAttr_TokICCsig, 6, + &kObjectData[4371], 0}, + {"setAttr-SecDevSig", "secure device signature", NID_setAttr_SecDevSig, 6, + &kObjectData[4377], 0}, + {"set-brand-IATA-ATA", "set-brand-IATA-ATA", NID_set_brand_IATA_ATA, 4, + &kObjectData[4383], 0}, + {"set-brand-Diners", "set-brand-Diners", NID_set_brand_Diners, 4, + &kObjectData[4387], 0}, + {"set-brand-AmericanExpress", "set-brand-AmericanExpress", + NID_set_brand_AmericanExpress, 4, &kObjectData[4391], 0}, + {"set-brand-JCB", "set-brand-JCB", NID_set_brand_JCB, 4, &kObjectData[4395], + 0}, + {"set-brand-Visa", "set-brand-Visa", NID_set_brand_Visa, 4, + &kObjectData[4399], 0}, + {"set-brand-MasterCard", "set-brand-MasterCard", NID_set_brand_MasterCard, + 4, &kObjectData[4403], 0}, + {"set-brand-Novus", "set-brand-Novus", NID_set_brand_Novus, 5, + &kObjectData[4407], 0}, + {"DES-CDMF", "des-cdmf", NID_des_cdmf, 8, &kObjectData[4412], 0}, + {"rsaOAEPEncryptionSET", "rsaOAEPEncryptionSET", NID_rsaOAEPEncryptionSET, + 9, &kObjectData[4420], 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, &kObjectData[4429], 0}, + {"msSmartcardLogin", "Microsoft Smartcardlogin", NID_ms_smartcard_login, 10, + &kObjectData[4430], 0}, + {"msUPN", "Microsoft Universal Principal Name", NID_ms_upn, 10, + &kObjectData[4440], 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, &kObjectData[4450], 0}, + {"postalCode", "postalCode", NID_postalCode, 3, &kObjectData[4453], 0}, + {"id-ppl", "id-ppl", NID_id_ppl, 7, &kObjectData[4456], 0}, + {"proxyCertInfo", "Proxy Certificate Information", NID_proxyCertInfo, 8, + &kObjectData[4463], 0}, + {"id-ppl-anyLanguage", "Any language", NID_id_ppl_anyLanguage, 8, + &kObjectData[4471], 0}, + {"id-ppl-inheritAll", "Inherit all", NID_id_ppl_inheritAll, 8, + &kObjectData[4479], 0}, + {"nameConstraints", "X509v3 Name Constraints", NID_name_constraints, 3, + &kObjectData[4487], 0}, + {"id-ppl-independent", "Independent", NID_Independent, 8, + &kObjectData[4490], 0}, + {"RSA-SHA256", "sha256WithRSAEncryption", NID_sha256WithRSAEncryption, 9, + &kObjectData[4498], 0}, + {"RSA-SHA384", "sha384WithRSAEncryption", NID_sha384WithRSAEncryption, 9, + &kObjectData[4507], 0}, + {"RSA-SHA512", "sha512WithRSAEncryption", NID_sha512WithRSAEncryption, 9, + &kObjectData[4516], 0}, + {"RSA-SHA224", "sha224WithRSAEncryption", NID_sha224WithRSAEncryption, 9, + &kObjectData[4525], 0}, + {"SHA256", "sha256", NID_sha256, 9, &kObjectData[4534], 0}, + {"SHA384", "sha384", NID_sha384, 9, &kObjectData[4543], 0}, + {"SHA512", "sha512", NID_sha512, 9, &kObjectData[4552], 0}, + {"SHA224", "sha224", NID_sha224, 9, &kObjectData[4561], 0}, + {"identified-organization", "identified-organization", + NID_identified_organization, 1, &kObjectData[4570], 0}, + {"certicom-arc", "certicom-arc", NID_certicom_arc, 3, &kObjectData[4571], + 0}, + {"wap", "wap", NID_wap, 2, &kObjectData[4574], 0}, + {"wap-wsg", "wap-wsg", NID_wap_wsg, 3, &kObjectData[4576], 0}, + {"id-characteristic-two-basis", "id-characteristic-two-basis", + NID_X9_62_id_characteristic_two_basis, 8, &kObjectData[4579], 0}, + {"onBasis", "onBasis", NID_X9_62_onBasis, 9, &kObjectData[4587], 0}, + {"tpBasis", "tpBasis", NID_X9_62_tpBasis, 9, &kObjectData[4596], 0}, + {"ppBasis", "ppBasis", NID_X9_62_ppBasis, 9, &kObjectData[4605], 0}, + {"c2pnb163v1", "c2pnb163v1", NID_X9_62_c2pnb163v1, 8, &kObjectData[4614], + 0}, + {"c2pnb163v2", "c2pnb163v2", NID_X9_62_c2pnb163v2, 8, &kObjectData[4622], + 0}, + {"c2pnb163v3", "c2pnb163v3", NID_X9_62_c2pnb163v3, 8, &kObjectData[4630], + 0}, + {"c2pnb176v1", "c2pnb176v1", NID_X9_62_c2pnb176v1, 8, &kObjectData[4638], + 0}, + {"c2tnb191v1", "c2tnb191v1", NID_X9_62_c2tnb191v1, 8, &kObjectData[4646], + 0}, + {"c2tnb191v2", "c2tnb191v2", NID_X9_62_c2tnb191v2, 8, &kObjectData[4654], + 0}, + {"c2tnb191v3", "c2tnb191v3", NID_X9_62_c2tnb191v3, 8, &kObjectData[4662], + 0}, + {"c2onb191v4", "c2onb191v4", NID_X9_62_c2onb191v4, 8, &kObjectData[4670], + 0}, + {"c2onb191v5", "c2onb191v5", NID_X9_62_c2onb191v5, 8, &kObjectData[4678], + 0}, + {"c2pnb208w1", "c2pnb208w1", NID_X9_62_c2pnb208w1, 8, &kObjectData[4686], + 0}, + {"c2tnb239v1", "c2tnb239v1", NID_X9_62_c2tnb239v1, 8, &kObjectData[4694], + 0}, + {"c2tnb239v2", "c2tnb239v2", NID_X9_62_c2tnb239v2, 8, &kObjectData[4702], + 0}, + {"c2tnb239v3", "c2tnb239v3", NID_X9_62_c2tnb239v3, 8, &kObjectData[4710], + 0}, + {"c2onb239v4", "c2onb239v4", NID_X9_62_c2onb239v4, 8, &kObjectData[4718], + 0}, + {"c2onb239v5", "c2onb239v5", NID_X9_62_c2onb239v5, 8, &kObjectData[4726], + 0}, + {"c2pnb272w1", "c2pnb272w1", NID_X9_62_c2pnb272w1, 8, &kObjectData[4734], + 0}, + {"c2pnb304w1", "c2pnb304w1", NID_X9_62_c2pnb304w1, 8, &kObjectData[4742], + 0}, + {"c2tnb359v1", "c2tnb359v1", NID_X9_62_c2tnb359v1, 8, &kObjectData[4750], + 0}, + {"c2pnb368w1", "c2pnb368w1", NID_X9_62_c2pnb368w1, 8, &kObjectData[4758], + 0}, + {"c2tnb431r1", "c2tnb431r1", NID_X9_62_c2tnb431r1, 8, &kObjectData[4766], + 0}, + {"secp112r1", "secp112r1", NID_secp112r1, 5, &kObjectData[4774], 0}, + {"secp112r2", "secp112r2", NID_secp112r2, 5, &kObjectData[4779], 0}, + {"secp128r1", "secp128r1", NID_secp128r1, 5, &kObjectData[4784], 0}, + {"secp128r2", "secp128r2", NID_secp128r2, 5, &kObjectData[4789], 0}, + {"secp160k1", "secp160k1", NID_secp160k1, 5, &kObjectData[4794], 0}, + {"secp160r1", "secp160r1", NID_secp160r1, 5, &kObjectData[4799], 0}, + {"secp160r2", "secp160r2", NID_secp160r2, 5, &kObjectData[4804], 0}, + {"secp192k1", "secp192k1", NID_secp192k1, 5, &kObjectData[4809], 0}, + {"secp224k1", "secp224k1", NID_secp224k1, 5, &kObjectData[4814], 0}, + {"secp224r1", "secp224r1", NID_secp224r1, 5, &kObjectData[4819], 0}, + {"secp256k1", "secp256k1", NID_secp256k1, 5, &kObjectData[4824], 0}, + {"secp384r1", "secp384r1", NID_secp384r1, 5, &kObjectData[4829], 0}, + {"secp521r1", "secp521r1", NID_secp521r1, 5, &kObjectData[4834], 0}, + {"sect113r1", "sect113r1", NID_sect113r1, 5, &kObjectData[4839], 0}, + {"sect113r2", "sect113r2", NID_sect113r2, 5, &kObjectData[4844], 0}, + {"sect131r1", "sect131r1", NID_sect131r1, 5, &kObjectData[4849], 0}, + {"sect131r2", "sect131r2", NID_sect131r2, 5, &kObjectData[4854], 0}, + {"sect163k1", "sect163k1", NID_sect163k1, 5, &kObjectData[4859], 0}, + {"sect163r1", "sect163r1", NID_sect163r1, 5, &kObjectData[4864], 0}, + {"sect163r2", "sect163r2", NID_sect163r2, 5, &kObjectData[4869], 0}, + {"sect193r1", "sect193r1", NID_sect193r1, 5, &kObjectData[4874], 0}, + {"sect193r2", "sect193r2", NID_sect193r2, 5, &kObjectData[4879], 0}, + {"sect233k1", "sect233k1", NID_sect233k1, 5, &kObjectData[4884], 0}, + {"sect233r1", "sect233r1", NID_sect233r1, 5, &kObjectData[4889], 0}, + {"sect239k1", "sect239k1", NID_sect239k1, 5, &kObjectData[4894], 0}, + {"sect283k1", "sect283k1", NID_sect283k1, 5, &kObjectData[4899], 0}, + {"sect283r1", "sect283r1", NID_sect283r1, 5, &kObjectData[4904], 0}, + {"sect409k1", "sect409k1", NID_sect409k1, 5, &kObjectData[4909], 0}, + {"sect409r1", "sect409r1", NID_sect409r1, 5, &kObjectData[4914], 0}, + {"sect571k1", "sect571k1", NID_sect571k1, 5, &kObjectData[4919], 0}, + {"sect571r1", "sect571r1", NID_sect571r1, 5, &kObjectData[4924], 0}, + {"wap-wsg-idm-ecid-wtls1", "wap-wsg-idm-ecid-wtls1", + NID_wap_wsg_idm_ecid_wtls1, 5, &kObjectData[4929], 0}, + {"wap-wsg-idm-ecid-wtls3", "wap-wsg-idm-ecid-wtls3", + NID_wap_wsg_idm_ecid_wtls3, 5, &kObjectData[4934], 0}, + {"wap-wsg-idm-ecid-wtls4", "wap-wsg-idm-ecid-wtls4", + NID_wap_wsg_idm_ecid_wtls4, 5, &kObjectData[4939], 0}, + {"wap-wsg-idm-ecid-wtls5", "wap-wsg-idm-ecid-wtls5", + NID_wap_wsg_idm_ecid_wtls5, 5, &kObjectData[4944], 0}, + {"wap-wsg-idm-ecid-wtls6", "wap-wsg-idm-ecid-wtls6", + NID_wap_wsg_idm_ecid_wtls6, 5, &kObjectData[4949], 0}, + {"wap-wsg-idm-ecid-wtls7", "wap-wsg-idm-ecid-wtls7", + NID_wap_wsg_idm_ecid_wtls7, 5, &kObjectData[4954], 0}, + {"wap-wsg-idm-ecid-wtls8", "wap-wsg-idm-ecid-wtls8", + NID_wap_wsg_idm_ecid_wtls8, 5, &kObjectData[4959], 0}, + {"wap-wsg-idm-ecid-wtls9", "wap-wsg-idm-ecid-wtls9", + NID_wap_wsg_idm_ecid_wtls9, 5, &kObjectData[4964], 0}, + {"wap-wsg-idm-ecid-wtls10", "wap-wsg-idm-ecid-wtls10", + NID_wap_wsg_idm_ecid_wtls10, 5, &kObjectData[4969], 0}, + {"wap-wsg-idm-ecid-wtls11", "wap-wsg-idm-ecid-wtls11", + NID_wap_wsg_idm_ecid_wtls11, 5, &kObjectData[4974], 0}, + {"wap-wsg-idm-ecid-wtls12", "wap-wsg-idm-ecid-wtls12", + NID_wap_wsg_idm_ecid_wtls12, 5, &kObjectData[4979], 0}, + {"anyPolicy", "X509v3 Any Policy", NID_any_policy, 4, &kObjectData[4984], + 0}, + {"policyMappings", "X509v3 Policy Mappings", NID_policy_mappings, 3, + &kObjectData[4988], 0}, + {"inhibitAnyPolicy", "X509v3 Inhibit Any Policy", NID_inhibit_any_policy, 3, + &kObjectData[4991], 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, + &kObjectData[4994], 0}, + {"CAMELLIA-192-CBC", "camellia-192-cbc", NID_camellia_192_cbc, 11, + &kObjectData[5005], 0}, + {"CAMELLIA-256-CBC", "camellia-256-cbc", NID_camellia_256_cbc, 11, + &kObjectData[5016], 0}, + {"CAMELLIA-128-ECB", "camellia-128-ecb", NID_camellia_128_ecb, 8, + &kObjectData[5027], 0}, + {"CAMELLIA-192-ECB", "camellia-192-ecb", NID_camellia_192_ecb, 8, + &kObjectData[5035], 0}, + {"CAMELLIA-256-ECB", "camellia-256-ecb", NID_camellia_256_ecb, 8, + &kObjectData[5043], 0}, + {"CAMELLIA-128-CFB", "camellia-128-cfb", NID_camellia_128_cfb128, 8, + &kObjectData[5051], 0}, + {"CAMELLIA-192-CFB", "camellia-192-cfb", NID_camellia_192_cfb128, 8, + &kObjectData[5059], 0}, + {"CAMELLIA-256-CFB", "camellia-256-cfb", NID_camellia_256_cfb128, 8, + &kObjectData[5067], 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, + &kObjectData[5075], 0}, + {"CAMELLIA-192-OFB", "camellia-192-ofb", NID_camellia_192_ofb128, 8, + &kObjectData[5083], 0}, + {"CAMELLIA-256-OFB", "camellia-256-ofb", NID_camellia_256_ofb128, 8, + &kObjectData[5091], 0}, + {"subjectDirectoryAttributes", "X509v3 Subject Directory Attributes", + NID_subject_directory_attributes, 3, &kObjectData[5099], 0}, + {"issuingDistributionPoint", "X509v3 Issuing Distribution Point", + NID_issuing_distribution_point, 3, &kObjectData[5102], 0}, + {"certificateIssuer", "X509v3 Certificate Issuer", NID_certificate_issuer, + 3, &kObjectData[5105], 0}, + {NULL, NULL, NID_undef, 0, NULL, 0}, + {"KISA", "kisa", NID_kisa, 6, &kObjectData[5108], 0}, + {NULL, NULL, NID_undef, 0, NULL, 0}, + {NULL, NULL, NID_undef, 0, NULL, 0}, + {"SEED-ECB", "seed-ecb", NID_seed_ecb, 8, &kObjectData[5114], 0}, + {"SEED-CBC", "seed-cbc", NID_seed_cbc, 8, &kObjectData[5122], 0}, + {"SEED-OFB", "seed-ofb", NID_seed_ofb128, 8, &kObjectData[5130], 0}, + {"SEED-CFB", "seed-cfb", NID_seed_cfb128, 8, &kObjectData[5138], 0}, + {"HMAC-MD5", "hmac-md5", NID_hmac_md5, 8, &kObjectData[5146], 0}, + {"HMAC-SHA1", "hmac-sha1", NID_hmac_sha1, 8, &kObjectData[5154], 0}, + {"id-PasswordBasedMAC", "password based MAC", NID_id_PasswordBasedMAC, 9, + &kObjectData[5162], 0}, + {"id-DHBasedMac", "Diffie-Hellman based MAC", NID_id_DHBasedMac, 9, + &kObjectData[5171], 0}, + {"id-it-suppLangTags", "id-it-suppLangTags", NID_id_it_suppLangTags, 8, + &kObjectData[5180], 0}, + {"caRepository", "CA Repository", NID_caRepository, 8, &kObjectData[5188], + 0}, + {"id-smime-ct-compressedData", "id-smime-ct-compressedData", + NID_id_smime_ct_compressedData, 11, &kObjectData[5196], 0}, + {"id-ct-asciiTextWithCRLF", "id-ct-asciiTextWithCRLF", + NID_id_ct_asciiTextWithCRLF, 11, &kObjectData[5207], 0}, + {"id-aes128-wrap", "id-aes128-wrap", NID_id_aes128_wrap, 9, + &kObjectData[5218], 0}, + {"id-aes192-wrap", "id-aes192-wrap", NID_id_aes192_wrap, 9, + &kObjectData[5227], 0}, + {"id-aes256-wrap", "id-aes256-wrap", NID_id_aes256_wrap, 9, + &kObjectData[5236], 0}, + {"ecdsa-with-Recommended", "ecdsa-with-Recommended", + NID_ecdsa_with_Recommended, 7, &kObjectData[5245], 0}, + {"ecdsa-with-Specified", "ecdsa-with-Specified", NID_ecdsa_with_Specified, + 7, &kObjectData[5252], 0}, + {"ecdsa-with-SHA224", "ecdsa-with-SHA224", NID_ecdsa_with_SHA224, 8, + &kObjectData[5259], 0}, + {"ecdsa-with-SHA256", "ecdsa-with-SHA256", NID_ecdsa_with_SHA256, 8, + &kObjectData[5267], 0}, + {"ecdsa-with-SHA384", "ecdsa-with-SHA384", NID_ecdsa_with_SHA384, 8, + &kObjectData[5275], 0}, + {"ecdsa-with-SHA512", "ecdsa-with-SHA512", NID_ecdsa_with_SHA512, 8, + &kObjectData[5283], 0}, + {"hmacWithMD5", "hmacWithMD5", NID_hmacWithMD5, 8, &kObjectData[5291], 0}, + {"hmacWithSHA224", "hmacWithSHA224", NID_hmacWithSHA224, 8, + &kObjectData[5299], 0}, + {"hmacWithSHA256", "hmacWithSHA256", NID_hmacWithSHA256, 8, + &kObjectData[5307], 0}, + {"hmacWithSHA384", "hmacWithSHA384", NID_hmacWithSHA384, 8, + &kObjectData[5315], 0}, + {"hmacWithSHA512", "hmacWithSHA512", NID_hmacWithSHA512, 8, + &kObjectData[5323], 0}, + {"dsa_with_SHA224", "dsa_with_SHA224", NID_dsa_with_SHA224, 9, + &kObjectData[5331], 0}, + {"dsa_with_SHA256", "dsa_with_SHA256", NID_dsa_with_SHA256, 9, + &kObjectData[5340], 0}, + {"whirlpool", "whirlpool", NID_whirlpool, 6, &kObjectData[5349], 0}, + {"cryptopro", "cryptopro", NID_cryptopro, 5, &kObjectData[5355], 0}, + {"cryptocom", "cryptocom", NID_cryptocom, 5, &kObjectData[5360], 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, &kObjectData[5365], 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, &kObjectData[5371], 0}, + {"md_gost94", "GOST R 34.11-94", NID_id_GostR3411_94, 6, &kObjectData[5377], + 0}, + {"id-HMACGostR3411-94", "HMAC GOST 34.11-94", NID_id_HMACGostR3411_94, 6, + &kObjectData[5383], 0}, + {"gost2001", "GOST R 34.10-2001", NID_id_GostR3410_2001, 6, + &kObjectData[5389], 0}, + {"gost94", "GOST R 34.10-94", NID_id_GostR3410_94, 6, &kObjectData[5395], + 0}, + {"gost89", "GOST 28147-89", NID_id_Gost28147_89, 6, &kObjectData[5401], 0}, + {"gost89-cnt", "gost89-cnt", NID_gost89_cnt, 0, NULL, 0}, + {"gost-mac", "GOST 28147-89 MAC", NID_id_Gost28147_89_MAC, 6, + &kObjectData[5407], 0}, + {"prf-gostr3411-94", "GOST R 34.11-94 PRF", NID_id_GostR3411_94_prf, 6, + &kObjectData[5413], 0}, + {"id-GostR3410-2001DH", "GOST R 34.10-2001 DH", NID_id_GostR3410_2001DH, 6, + &kObjectData[5419], 0}, + {"id-GostR3410-94DH", "GOST R 34.10-94 DH", NID_id_GostR3410_94DH, 6, + &kObjectData[5425], 0}, + {"id-Gost28147-89-CryptoPro-KeyMeshing", + "id-Gost28147-89-CryptoPro-KeyMeshing", + NID_id_Gost28147_89_CryptoPro_KeyMeshing, 7, &kObjectData[5431], 0}, + {"id-Gost28147-89-None-KeyMeshing", "id-Gost28147-89-None-KeyMeshing", + NID_id_Gost28147_89_None_KeyMeshing, 7, &kObjectData[5438], 0}, + {"id-GostR3411-94-TestParamSet", "id-GostR3411-94-TestParamSet", + NID_id_GostR3411_94_TestParamSet, 7, &kObjectData[5445], 0}, + {"id-GostR3411-94-CryptoProParamSet", "id-GostR3411-94-CryptoProParamSet", + NID_id_GostR3411_94_CryptoProParamSet, 7, &kObjectData[5452], 0}, + {"id-Gost28147-89-TestParamSet", "id-Gost28147-89-TestParamSet", + NID_id_Gost28147_89_TestParamSet, 7, &kObjectData[5459], 0}, + {"id-Gost28147-89-CryptoPro-A-ParamSet", + "id-Gost28147-89-CryptoPro-A-ParamSet", + NID_id_Gost28147_89_CryptoPro_A_ParamSet, 7, &kObjectData[5466], 0}, + {"id-Gost28147-89-CryptoPro-B-ParamSet", + "id-Gost28147-89-CryptoPro-B-ParamSet", + NID_id_Gost28147_89_CryptoPro_B_ParamSet, 7, &kObjectData[5473], 0}, + {"id-Gost28147-89-CryptoPro-C-ParamSet", + "id-Gost28147-89-CryptoPro-C-ParamSet", + NID_id_Gost28147_89_CryptoPro_C_ParamSet, 7, &kObjectData[5480], 0}, + {"id-Gost28147-89-CryptoPro-D-ParamSet", + "id-Gost28147-89-CryptoPro-D-ParamSet", + NID_id_Gost28147_89_CryptoPro_D_ParamSet, 7, &kObjectData[5487], 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, &kObjectData[5494], + 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, &kObjectData[5501], + 0}, + {"id-Gost28147-89-CryptoPro-RIC-1-ParamSet", + "id-Gost28147-89-CryptoPro-RIC-1-ParamSet", + NID_id_Gost28147_89_CryptoPro_RIC_1_ParamSet, 7, &kObjectData[5508], 0}, + {"id-GostR3410-94-TestParamSet", "id-GostR3410-94-TestParamSet", + NID_id_GostR3410_94_TestParamSet, 7, &kObjectData[5515], 0}, + {"id-GostR3410-94-CryptoPro-A-ParamSet", + "id-GostR3410-94-CryptoPro-A-ParamSet", + NID_id_GostR3410_94_CryptoPro_A_ParamSet, 7, &kObjectData[5522], 0}, + {"id-GostR3410-94-CryptoPro-B-ParamSet", + "id-GostR3410-94-CryptoPro-B-ParamSet", + NID_id_GostR3410_94_CryptoPro_B_ParamSet, 7, &kObjectData[5529], 0}, + {"id-GostR3410-94-CryptoPro-C-ParamSet", + "id-GostR3410-94-CryptoPro-C-ParamSet", + NID_id_GostR3410_94_CryptoPro_C_ParamSet, 7, &kObjectData[5536], 0}, + {"id-GostR3410-94-CryptoPro-D-ParamSet", + "id-GostR3410-94-CryptoPro-D-ParamSet", + NID_id_GostR3410_94_CryptoPro_D_ParamSet, 7, &kObjectData[5543], 0}, + {"id-GostR3410-94-CryptoPro-XchA-ParamSet", + "id-GostR3410-94-CryptoPro-XchA-ParamSet", + NID_id_GostR3410_94_CryptoPro_XchA_ParamSet, 7, &kObjectData[5550], 0}, + {"id-GostR3410-94-CryptoPro-XchB-ParamSet", + "id-GostR3410-94-CryptoPro-XchB-ParamSet", + NID_id_GostR3410_94_CryptoPro_XchB_ParamSet, 7, &kObjectData[5557], 0}, + {"id-GostR3410-94-CryptoPro-XchC-ParamSet", + "id-GostR3410-94-CryptoPro-XchC-ParamSet", + NID_id_GostR3410_94_CryptoPro_XchC_ParamSet, 7, &kObjectData[5564], 0}, + {"id-GostR3410-2001-TestParamSet", "id-GostR3410-2001-TestParamSet", + NID_id_GostR3410_2001_TestParamSet, 7, &kObjectData[5571], 0}, + {"id-GostR3410-2001-CryptoPro-A-ParamSet", + "id-GostR3410-2001-CryptoPro-A-ParamSet", + NID_id_GostR3410_2001_CryptoPro_A_ParamSet, 7, &kObjectData[5578], 0}, + {"id-GostR3410-2001-CryptoPro-B-ParamSet", + "id-GostR3410-2001-CryptoPro-B-ParamSet", + NID_id_GostR3410_2001_CryptoPro_B_ParamSet, 7, &kObjectData[5585], 0}, + {"id-GostR3410-2001-CryptoPro-C-ParamSet", + "id-GostR3410-2001-CryptoPro-C-ParamSet", + NID_id_GostR3410_2001_CryptoPro_C_ParamSet, 7, &kObjectData[5592], 0}, + {"id-GostR3410-2001-CryptoPro-XchA-ParamSet", + "id-GostR3410-2001-CryptoPro-XchA-ParamSet", + NID_id_GostR3410_2001_CryptoPro_XchA_ParamSet, 7, &kObjectData[5599], 0}, + {"id-GostR3410-2001-CryptoPro-XchB-ParamSet", + "id-GostR3410-2001-CryptoPro-XchB-ParamSet", + NID_id_GostR3410_2001_CryptoPro_XchB_ParamSet, 7, &kObjectData[5606], 0}, + {"id-GostR3410-94-a", "id-GostR3410-94-a", NID_id_GostR3410_94_a, 7, + &kObjectData[5613], 0}, + {"id-GostR3410-94-aBis", "id-GostR3410-94-aBis", NID_id_GostR3410_94_aBis, + 7, &kObjectData[5620], 0}, + {"id-GostR3410-94-b", "id-GostR3410-94-b", NID_id_GostR3410_94_b, 7, + &kObjectData[5627], 0}, + {"id-GostR3410-94-bBis", "id-GostR3410-94-bBis", NID_id_GostR3410_94_bBis, + 7, &kObjectData[5634], 0}, + {"id-Gost28147-89-cc", "GOST 28147-89 Cryptocom ParamSet", + NID_id_Gost28147_89_cc, 8, &kObjectData[5641], 0}, + {"gost94cc", "GOST 34.10-94 Cryptocom", NID_id_GostR3410_94_cc, 8, + &kObjectData[5649], 0}, + {"gost2001cc", "GOST 34.10-2001 Cryptocom", NID_id_GostR3410_2001_cc, 8, + &kObjectData[5657], 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, &kObjectData[5665], 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, &kObjectData[5673], 0}, + {"id-GostR3410-2001-ParamSet-cc", + "GOST R 3410-2001 Parameter Set Cryptocom", + NID_id_GostR3410_2001_ParamSet_cc, 8, &kObjectData[5681], 0}, + {"HMAC", "hmac", NID_hmac, 0, NULL, 0}, + {"LocalKeySet", "Microsoft Local Key set", NID_LocalKeySet, 9, + &kObjectData[5689], 0}, + {"freshestCRL", "X509v3 Freshest CRL", NID_freshest_crl, 3, + &kObjectData[5698], 0}, + {"id-on-permanentIdentifier", "Permanent Identifier", + NID_id_on_permanentIdentifier, 8, &kObjectData[5701], 0}, + {"searchGuide", "searchGuide", NID_searchGuide, 3, &kObjectData[5709], 0}, + {"businessCategory", "businessCategory", NID_businessCategory, 3, + &kObjectData[5712], 0}, + {"postalAddress", "postalAddress", NID_postalAddress, 3, &kObjectData[5715], + 0}, + {"postOfficeBox", "postOfficeBox", NID_postOfficeBox, 3, &kObjectData[5718], + 0}, + {"physicalDeliveryOfficeName", "physicalDeliveryOfficeName", + NID_physicalDeliveryOfficeName, 3, &kObjectData[5721], 0}, + {"telephoneNumber", "telephoneNumber", NID_telephoneNumber, 3, + &kObjectData[5724], 0}, + {"telexNumber", "telexNumber", NID_telexNumber, 3, &kObjectData[5727], 0}, + {"teletexTerminalIdentifier", "teletexTerminalIdentifier", + NID_teletexTerminalIdentifier, 3, &kObjectData[5730], 0}, + {"facsimileTelephoneNumber", "facsimileTelephoneNumber", + NID_facsimileTelephoneNumber, 3, &kObjectData[5733], 0}, + {"x121Address", "x121Address", NID_x121Address, 3, &kObjectData[5736], 0}, + {"internationaliSDNNumber", "internationaliSDNNumber", + NID_internationaliSDNNumber, 3, &kObjectData[5739], 0}, + {"registeredAddress", "registeredAddress", NID_registeredAddress, 3, + &kObjectData[5742], 0}, + {"destinationIndicator", "destinationIndicator", NID_destinationIndicator, + 3, &kObjectData[5745], 0}, + {"preferredDeliveryMethod", "preferredDeliveryMethod", + NID_preferredDeliveryMethod, 3, &kObjectData[5748], 0}, + {"presentationAddress", "presentationAddress", NID_presentationAddress, 3, + &kObjectData[5751], 0}, + {"supportedApplicationContext", "supportedApplicationContext", + NID_supportedApplicationContext, 3, &kObjectData[5754], 0}, + {"member", "member", NID_member, 3, &kObjectData[5757], 0}, + {"owner", "owner", NID_owner, 3, &kObjectData[5760], 0}, + {"roleOccupant", "roleOccupant", NID_roleOccupant, 3, &kObjectData[5763], + 0}, + {"seeAlso", "seeAlso", NID_seeAlso, 3, &kObjectData[5766], 0}, + {"userPassword", "userPassword", NID_userPassword, 3, &kObjectData[5769], + 0}, + {"userCertificate", "userCertificate", NID_userCertificate, 3, + &kObjectData[5772], 0}, + {"cACertificate", "cACertificate", NID_cACertificate, 3, &kObjectData[5775], + 0}, + {"authorityRevocationList", "authorityRevocationList", + NID_authorityRevocationList, 3, &kObjectData[5778], 0}, + {"certificateRevocationList", "certificateRevocationList", + NID_certificateRevocationList, 3, &kObjectData[5781], 0}, + {"crossCertificatePair", "crossCertificatePair", NID_crossCertificatePair, + 3, &kObjectData[5784], 0}, + {"enhancedSearchGuide", "enhancedSearchGuide", NID_enhancedSearchGuide, 3, + &kObjectData[5787], 0}, + {"protocolInformation", "protocolInformation", NID_protocolInformation, 3, + &kObjectData[5790], 0}, + {"distinguishedName", "distinguishedName", NID_distinguishedName, 3, + &kObjectData[5793], 0}, + {"uniqueMember", "uniqueMember", NID_uniqueMember, 3, &kObjectData[5796], + 0}, + {"houseIdentifier", "houseIdentifier", NID_houseIdentifier, 3, + &kObjectData[5799], 0}, + {"supportedAlgorithms", "supportedAlgorithms", NID_supportedAlgorithms, 3, + &kObjectData[5802], 0}, + {"deltaRevocationList", "deltaRevocationList", NID_deltaRevocationList, 3, + &kObjectData[5805], 0}, + {"dmdName", "dmdName", NID_dmdName, 3, &kObjectData[5808], 0}, + {"id-alg-PWRI-KEK", "id-alg-PWRI-KEK", NID_id_alg_PWRI_KEK, 11, + &kObjectData[5811], 0}, + {"CMAC", "cmac", NID_cmac, 0, NULL, 0}, + {"id-aes128-GCM", "aes-128-gcm", NID_aes_128_gcm, 9, &kObjectData[5822], 0}, + {"id-aes128-CCM", "aes-128-ccm", NID_aes_128_ccm, 9, &kObjectData[5831], 0}, + {"id-aes128-wrap-pad", "id-aes128-wrap-pad", NID_id_aes128_wrap_pad, 9, + &kObjectData[5840], 0}, + {"id-aes192-GCM", "aes-192-gcm", NID_aes_192_gcm, 9, &kObjectData[5849], 0}, + {"id-aes192-CCM", "aes-192-ccm", NID_aes_192_ccm, 9, &kObjectData[5858], 0}, + {"id-aes192-wrap-pad", "id-aes192-wrap-pad", NID_id_aes192_wrap_pad, 9, + &kObjectData[5867], 0}, + {"id-aes256-GCM", "aes-256-gcm", NID_aes_256_gcm, 9, &kObjectData[5876], 0}, + {"id-aes256-CCM", "aes-256-ccm", NID_aes_256_ccm, 9, &kObjectData[5885], 0}, + {"id-aes256-wrap-pad", "id-aes256-wrap-pad", NID_id_aes256_wrap_pad, 9, + &kObjectData[5894], 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, + &kObjectData[5903], 0}, + {"id-camellia192-wrap", "id-camellia192-wrap", NID_id_camellia192_wrap, 11, + &kObjectData[5914], 0}, + {"id-camellia256-wrap", "id-camellia256-wrap", NID_id_camellia256_wrap, 11, + &kObjectData[5925], 0}, + {"anyExtendedKeyUsage", "Any Extended Key Usage", NID_anyExtendedKeyUsage, + 4, &kObjectData[5936], 0}, + {"MGF1", "mgf1", NID_mgf1, 9, &kObjectData[5940], 0}, + {"RSASSA-PSS", "rsassaPss", NID_rsassaPss, 9, &kObjectData[5949], 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, &kObjectData[5958], 0}, + {"dhpublicnumber", "X9.42 DH", NID_dhpublicnumber, 7, &kObjectData[5967], + 0}, + {"brainpoolP160r1", "brainpoolP160r1", NID_brainpoolP160r1, 9, + &kObjectData[5974], 0}, + {"brainpoolP160t1", "brainpoolP160t1", NID_brainpoolP160t1, 9, + &kObjectData[5983], 0}, + {"brainpoolP192r1", "brainpoolP192r1", NID_brainpoolP192r1, 9, + &kObjectData[5992], 0}, + {"brainpoolP192t1", "brainpoolP192t1", NID_brainpoolP192t1, 9, + &kObjectData[6001], 0}, + {"brainpoolP224r1", "brainpoolP224r1", NID_brainpoolP224r1, 9, + &kObjectData[6010], 0}, + {"brainpoolP224t1", "brainpoolP224t1", NID_brainpoolP224t1, 9, + &kObjectData[6019], 0}, + {"brainpoolP256r1", "brainpoolP256r1", NID_brainpoolP256r1, 9, + &kObjectData[6028], 0}, + {"brainpoolP256t1", "brainpoolP256t1", NID_brainpoolP256t1, 9, + &kObjectData[6037], 0}, + {"brainpoolP320r1", "brainpoolP320r1", NID_brainpoolP320r1, 9, + &kObjectData[6046], 0}, + {"brainpoolP320t1", "brainpoolP320t1", NID_brainpoolP320t1, 9, + &kObjectData[6055], 0}, + {"brainpoolP384r1", "brainpoolP384r1", NID_brainpoolP384r1, 9, + &kObjectData[6064], 0}, + {"brainpoolP384t1", "brainpoolP384t1", NID_brainpoolP384t1, 9, + &kObjectData[6073], 0}, + {"brainpoolP512r1", "brainpoolP512r1", NID_brainpoolP512r1, 9, + &kObjectData[6082], 0}, + {"brainpoolP512t1", "brainpoolP512t1", NID_brainpoolP512t1, 9, + &kObjectData[6091], 0}, + {"PSPECIFIED", "pSpecified", NID_pSpecified, 9, &kObjectData[6100], 0}, + {"dhSinglePass-stdDH-sha1kdf-scheme", "dhSinglePass-stdDH-sha1kdf-scheme", + NID_dhSinglePass_stdDH_sha1kdf_scheme, 9, &kObjectData[6109], 0}, + {"dhSinglePass-stdDH-sha224kdf-scheme", + "dhSinglePass-stdDH-sha224kdf-scheme", + NID_dhSinglePass_stdDH_sha224kdf_scheme, 6, &kObjectData[6118], 0}, + {"dhSinglePass-stdDH-sha256kdf-scheme", + "dhSinglePass-stdDH-sha256kdf-scheme", + NID_dhSinglePass_stdDH_sha256kdf_scheme, 6, &kObjectData[6124], 0}, + {"dhSinglePass-stdDH-sha384kdf-scheme", + "dhSinglePass-stdDH-sha384kdf-scheme", + NID_dhSinglePass_stdDH_sha384kdf_scheme, 6, &kObjectData[6130], 0}, + {"dhSinglePass-stdDH-sha512kdf-scheme", + "dhSinglePass-stdDH-sha512kdf-scheme", + NID_dhSinglePass_stdDH_sha512kdf_scheme, 6, &kObjectData[6136], 0}, + {"dhSinglePass-cofactorDH-sha1kdf-scheme", + "dhSinglePass-cofactorDH-sha1kdf-scheme", + NID_dhSinglePass_cofactorDH_sha1kdf_scheme, 9, &kObjectData[6142], 0}, + {"dhSinglePass-cofactorDH-sha224kdf-scheme", + "dhSinglePass-cofactorDH-sha224kdf-scheme", + NID_dhSinglePass_cofactorDH_sha224kdf_scheme, 6, &kObjectData[6151], 0}, + {"dhSinglePass-cofactorDH-sha256kdf-scheme", + "dhSinglePass-cofactorDH-sha256kdf-scheme", + NID_dhSinglePass_cofactorDH_sha256kdf_scheme, 6, &kObjectData[6157], 0}, + {"dhSinglePass-cofactorDH-sha384kdf-scheme", + "dhSinglePass-cofactorDH-sha384kdf-scheme", + NID_dhSinglePass_cofactorDH_sha384kdf_scheme, 6, &kObjectData[6163], 0}, + {"dhSinglePass-cofactorDH-sha512kdf-scheme", + "dhSinglePass-cofactorDH-sha512kdf-scheme", + NID_dhSinglePass_cofactorDH_sha512kdf_scheme, 6, &kObjectData[6169], 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}, + {"X25519", "X25519", NID_X25519, 0, NULL, 0}, + {"ED25519", "ED25519", NID_ED25519, 3, &kObjectData[6175], 0}, + {"ChaCha20-Poly1305", "chacha20-poly1305", NID_chacha20_poly1305, 0, NULL, + 0}, + {"KxRSA", "kx-rsa", NID_kx_rsa, 0, NULL, 0}, + {"KxECDHE", "kx-ecdhe", NID_kx_ecdhe, 0, NULL, 0}, + {"KxPSK", "kx-psk", NID_kx_psk, 0, NULL, 0}, + {"AuthRSA", "auth-rsa", NID_auth_rsa, 0, NULL, 0}, + {"AuthECDSA", "auth-ecdsa", NID_auth_ecdsa, 0, NULL, 0}, + {"AuthPSK", "auth-psk", NID_auth_psk, 0, NULL, 0}, + {"KxANY", "kx-any", NID_kx_any, 0, NULL, 0}, + {"AuthANY", "auth-any", NID_auth_any, 0, NULL, 0}, +}; + +static const unsigned kNIDsInShortNameOrder[] = { + 364 /* AD_DVCS */, + 419 /* AES-128-CBC */, + 916 /* AES-128-CBC-HMAC-SHA1 */, + 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 */, + 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 */, + 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 */, + 958 /* AuthANY */, + 955 /* AuthECDSA */, + 956 /* AuthPSK */, + 954 /* AuthRSA */, + 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 */, + 950 /* ChaCha20-Poly1305 */, + 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 */, + 949 /* ED25519 */, + 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 */, + 957 /* KxANY */, + 952 /* KxECDHE */, + 953 /* KxPSK */, + 951 /* KxRSA */, + 15 /* L */, + 856 /* LocalKeySet */, + 3 /* MD2 */, + 257 /* MD4 */, + 4 /* MD5 */, + 114 /* MD5-SHA1 */, + 95 /* MDC2 */, + 911 /* MGF1 */, + 388 /* Mail */, + 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 */, + 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 */, + 948 /* X25519 */, + 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 */, + 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 */, + 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 kNIDsInLongNameOrder[] = { + 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 */, + 131 /* Code Signing */, + 783 /* Diffie-Hellman based MAC */, + 382 /* Directory */, + 392 /* Domain */, + 132 /* E-mail Protection */, + 949 /* ED25519 */, + 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 */, + 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 */, + 948 /* X25519 */, + 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 Distribution 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 */, + 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 */, + 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 */, + 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 */, + 958 /* auth-any */, + 955 /* auth-ecdsa */, + 956 /* auth-psk */, + 954 /* auth-rsa */, + 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 */, + 950 /* chacha20-poly1305 */, + 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 */, + 150 /* keyBag */, + 773 /* kisa */, + 957 /* kx-any */, + 952 /* kx-ecdhe */, + 953 /* kx-psk */, + 951 /* kx-rsa */, + 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 */, + 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 kNIDsInOIDOrder[] = { + 434 /* 0.9 (OBJ_data) */, + 182 /* 1.2 (OBJ_member_body) */, + 379 /* 1.3 (OBJ_org) */, + 676 /* 1.3 (OBJ_identified_organization) */, + 11 /* 2.5 (OBJ_X500) */, + 647 /* 2.23 (OBJ_international_organizations) */, + 380 /* 1.3.6 (OBJ_dod) */, + 12 /* 2.5.4 (OBJ_X509) */, + 378 /* 2.5.8 (OBJ_X500algorithms) */, + 81 /* 2.5.29 (OBJ_id_ce) */, + 512 /* 2.23.42 (OBJ_id_set) */, + 678 /* 2.23.43 (OBJ_wap) */, + 435 /* 0.9.2342 (OBJ_pss) */, + 183 /* 1.2.840 (OBJ_ISO_US) */, + 381 /* 1.3.6.1 (OBJ_iana) */, + 949 /* 1.3.101.112 (OBJ_ED25519) */, + 677 /* 1.3.132 (OBJ_certicom_arc) */, + 394 /* 2.5.1.5 (OBJ_selected_attribute_types) */, + 13 /* 2.5.4.3 (OBJ_commonName) */, + 100 /* 2.5.4.4 (OBJ_surname) */, + 105 /* 2.5.4.5 (OBJ_serialNumber) */, + 14 /* 2.5.4.6 (OBJ_countryName) */, + 15 /* 2.5.4.7 (OBJ_localityName) */, + 16 /* 2.5.4.8 (OBJ_stateOrProvinceName) */, + 660 /* 2.5.4.9 (OBJ_streetAddress) */, + 17 /* 2.5.4.10 (OBJ_organizationName) */, + 18 /* 2.5.4.11 (OBJ_organizationalUnitName) */, + 106 /* 2.5.4.12 (OBJ_title) */, + 107 /* 2.5.4.13 (OBJ_description) */, + 859 /* 2.5.4.14 (OBJ_searchGuide) */, + 860 /* 2.5.4.15 (OBJ_businessCategory) */, + 861 /* 2.5.4.16 (OBJ_postalAddress) */, + 661 /* 2.5.4.17 (OBJ_postalCode) */, + 862 /* 2.5.4.18 (OBJ_postOfficeBox) */, + 863 /* 2.5.4.19 (OBJ_physicalDeliveryOfficeName) */, + 864 /* 2.5.4.20 (OBJ_telephoneNumber) */, + 865 /* 2.5.4.21 (OBJ_telexNumber) */, + 866 /* 2.5.4.22 (OBJ_teletexTerminalIdentifier) */, + 867 /* 2.5.4.23 (OBJ_facsimileTelephoneNumber) */, + 868 /* 2.5.4.24 (OBJ_x121Address) */, + 869 /* 2.5.4.25 (OBJ_internationaliSDNNumber) */, + 870 /* 2.5.4.26 (OBJ_registeredAddress) */, + 871 /* 2.5.4.27 (OBJ_destinationIndicator) */, + 872 /* 2.5.4.28 (OBJ_preferredDeliveryMethod) */, + 873 /* 2.5.4.29 (OBJ_presentationAddress) */, + 874 /* 2.5.4.30 (OBJ_supportedApplicationContext) */, + 875 /* 2.5.4.31 (OBJ_member) */, + 876 /* 2.5.4.32 (OBJ_owner) */, + 877 /* 2.5.4.33 (OBJ_roleOccupant) */, + 878 /* 2.5.4.34 (OBJ_seeAlso) */, + 879 /* 2.5.4.35 (OBJ_userPassword) */, + 880 /* 2.5.4.36 (OBJ_userCertificate) */, + 881 /* 2.5.4.37 (OBJ_cACertificate) */, + 882 /* 2.5.4.38 (OBJ_authorityRevocationList) */, + 883 /* 2.5.4.39 (OBJ_certificateRevocationList) */, + 884 /* 2.5.4.40 (OBJ_crossCertificatePair) */, + 173 /* 2.5.4.41 (OBJ_name) */, + 99 /* 2.5.4.42 (OBJ_givenName) */, + 101 /* 2.5.4.43 (OBJ_initials) */, + 509 /* 2.5.4.44 (OBJ_generationQualifier) */, + 503 /* 2.5.4.45 (OBJ_x500UniqueIdentifier) */, + 174 /* 2.5.4.46 (OBJ_dnQualifier) */, + 885 /* 2.5.4.47 (OBJ_enhancedSearchGuide) */, + 886 /* 2.5.4.48 (OBJ_protocolInformation) */, + 887 /* 2.5.4.49 (OBJ_distinguishedName) */, + 888 /* 2.5.4.50 (OBJ_uniqueMember) */, + 889 /* 2.5.4.51 (OBJ_houseIdentifier) */, + 890 /* 2.5.4.52 (OBJ_supportedAlgorithms) */, + 891 /* 2.5.4.53 (OBJ_deltaRevocationList) */, + 892 /* 2.5.4.54 (OBJ_dmdName) */, + 510 /* 2.5.4.65 (OBJ_pseudonym) */, + 400 /* 2.5.4.72 (OBJ_role) */, + 769 /* 2.5.29.9 (OBJ_subject_directory_attributes) */, + 82 /* 2.5.29.14 (OBJ_subject_key_identifier) */, + 83 /* 2.5.29.15 (OBJ_key_usage) */, + 84 /* 2.5.29.16 (OBJ_private_key_usage_period) */, + 85 /* 2.5.29.17 (OBJ_subject_alt_name) */, + 86 /* 2.5.29.18 (OBJ_issuer_alt_name) */, + 87 /* 2.5.29.19 (OBJ_basic_constraints) */, + 88 /* 2.5.29.20 (OBJ_crl_number) */, + 141 /* 2.5.29.21 (OBJ_crl_reason) */, + 430 /* 2.5.29.23 (OBJ_hold_instruction_code) */, + 142 /* 2.5.29.24 (OBJ_invalidity_date) */, + 140 /* 2.5.29.27 (OBJ_delta_crl) */, + 770 /* 2.5.29.28 (OBJ_issuing_distribution_point) */, + 771 /* 2.5.29.29 (OBJ_certificate_issuer) */, + 666 /* 2.5.29.30 (OBJ_name_constraints) */, + 103 /* 2.5.29.31 (OBJ_crl_distribution_points) */, + 89 /* 2.5.29.32 (OBJ_certificate_policies) */, + 747 /* 2.5.29.33 (OBJ_policy_mappings) */, + 90 /* 2.5.29.35 (OBJ_authority_key_identifier) */, + 401 /* 2.5.29.36 (OBJ_policy_constraints) */, + 126 /* 2.5.29.37 (OBJ_ext_key_usage) */, + 857 /* 2.5.29.46 (OBJ_freshest_crl) */, + 748 /* 2.5.29.54 (OBJ_inhibit_any_policy) */, + 402 /* 2.5.29.55 (OBJ_target_information) */, + 403 /* 2.5.29.56 (OBJ_no_rev_avail) */, + 513 /* 2.23.42.0 (OBJ_set_ctype) */, + 514 /* 2.23.42.1 (OBJ_set_msgExt) */, + 515 /* 2.23.42.3 (OBJ_set_attr) */, + 516 /* 2.23.42.5 (OBJ_set_policy) */, + 517 /* 2.23.42.7 (OBJ_set_certExt) */, + 518 /* 2.23.42.8 (OBJ_set_brand) */, + 679 /* 2.23.43.1 (OBJ_wap_wsg) */, + 382 /* 1.3.6.1.1 (OBJ_Directory) */, + 383 /* 1.3.6.1.2 (OBJ_Management) */, + 384 /* 1.3.6.1.3 (OBJ_Experimental) */, + 385 /* 1.3.6.1.4 (OBJ_Private) */, + 386 /* 1.3.6.1.5 (OBJ_Security) */, + 387 /* 1.3.6.1.6 (OBJ_SNMPv2) */, + 388 /* 1.3.6.1.7 (OBJ_Mail) */, + 376 /* 1.3.14.3.2 (OBJ_algorithm) */, + 395 /* 2.5.1.5.55 (OBJ_clearance) */, + 19 /* 2.5.8.1.1 (OBJ_rsa) */, + 96 /* 2.5.8.3.100 (OBJ_mdc2WithRSA) */, + 95 /* 2.5.8.3.101 (OBJ_mdc2) */, + 746 /* 2.5.29.32.0 (OBJ_any_policy) */, + 910 /* 2.5.29.37.0 (OBJ_anyExtendedKeyUsage) */, + 519 /* 2.23.42.0.0 (OBJ_setct_PANData) */, + 520 /* 2.23.42.0.1 (OBJ_setct_PANToken) */, + 521 /* 2.23.42.0.2 (OBJ_setct_PANOnly) */, + 522 /* 2.23.42.0.3 (OBJ_setct_OIData) */, + 523 /* 2.23.42.0.4 (OBJ_setct_PI) */, + 524 /* 2.23.42.0.5 (OBJ_setct_PIData) */, + 525 /* 2.23.42.0.6 (OBJ_setct_PIDataUnsigned) */, + 526 /* 2.23.42.0.7 (OBJ_setct_HODInput) */, + 527 /* 2.23.42.0.8 (OBJ_setct_AuthResBaggage) */, + 528 /* 2.23.42.0.9 (OBJ_setct_AuthRevReqBaggage) */, + 529 /* 2.23.42.0.10 (OBJ_setct_AuthRevResBaggage) */, + 530 /* 2.23.42.0.11 (OBJ_setct_CapTokenSeq) */, + 531 /* 2.23.42.0.12 (OBJ_setct_PInitResData) */, + 532 /* 2.23.42.0.13 (OBJ_setct_PI_TBS) */, + 533 /* 2.23.42.0.14 (OBJ_setct_PResData) */, + 534 /* 2.23.42.0.16 (OBJ_setct_AuthReqTBS) */, + 535 /* 2.23.42.0.17 (OBJ_setct_AuthResTBS) */, + 536 /* 2.23.42.0.18 (OBJ_setct_AuthResTBSX) */, + 537 /* 2.23.42.0.19 (OBJ_setct_AuthTokenTBS) */, + 538 /* 2.23.42.0.20 (OBJ_setct_CapTokenData) */, + 539 /* 2.23.42.0.21 (OBJ_setct_CapTokenTBS) */, + 540 /* 2.23.42.0.22 (OBJ_setct_AcqCardCodeMsg) */, + 541 /* 2.23.42.0.23 (OBJ_setct_AuthRevReqTBS) */, + 542 /* 2.23.42.0.24 (OBJ_setct_AuthRevResData) */, + 543 /* 2.23.42.0.25 (OBJ_setct_AuthRevResTBS) */, + 544 /* 2.23.42.0.26 (OBJ_setct_CapReqTBS) */, + 545 /* 2.23.42.0.27 (OBJ_setct_CapReqTBSX) */, + 546 /* 2.23.42.0.28 (OBJ_setct_CapResData) */, + 547 /* 2.23.42.0.29 (OBJ_setct_CapRevReqTBS) */, + 548 /* 2.23.42.0.30 (OBJ_setct_CapRevReqTBSX) */, + 549 /* 2.23.42.0.31 (OBJ_setct_CapRevResData) */, + 550 /* 2.23.42.0.32 (OBJ_setct_CredReqTBS) */, + 551 /* 2.23.42.0.33 (OBJ_setct_CredReqTBSX) */, + 552 /* 2.23.42.0.34 (OBJ_setct_CredResData) */, + 553 /* 2.23.42.0.35 (OBJ_setct_CredRevReqTBS) */, + 554 /* 2.23.42.0.36 (OBJ_setct_CredRevReqTBSX) */, + 555 /* 2.23.42.0.37 (OBJ_setct_CredRevResData) */, + 556 /* 2.23.42.0.38 (OBJ_setct_PCertReqData) */, + 557 /* 2.23.42.0.39 (OBJ_setct_PCertResTBS) */, + 558 /* 2.23.42.0.40 (OBJ_setct_BatchAdminReqData) */, + 559 /* 2.23.42.0.41 (OBJ_setct_BatchAdminResData) */, + 560 /* 2.23.42.0.42 (OBJ_setct_CardCInitResTBS) */, + 561 /* 2.23.42.0.43 (OBJ_setct_MeAqCInitResTBS) */, + 562 /* 2.23.42.0.44 (OBJ_setct_RegFormResTBS) */, + 563 /* 2.23.42.0.45 (OBJ_setct_CertReqData) */, + 564 /* 2.23.42.0.46 (OBJ_setct_CertReqTBS) */, + 565 /* 2.23.42.0.47 (OBJ_setct_CertResData) */, + 566 /* 2.23.42.0.48 (OBJ_setct_CertInqReqTBS) */, + 567 /* 2.23.42.0.49 (OBJ_setct_ErrorTBS) */, + 568 /* 2.23.42.0.50 (OBJ_setct_PIDualSignedTBE) */, + 569 /* 2.23.42.0.51 (OBJ_setct_PIUnsignedTBE) */, + 570 /* 2.23.42.0.52 (OBJ_setct_AuthReqTBE) */, + 571 /* 2.23.42.0.53 (OBJ_setct_AuthResTBE) */, + 572 /* 2.23.42.0.54 (OBJ_setct_AuthResTBEX) */, + 573 /* 2.23.42.0.55 (OBJ_setct_AuthTokenTBE) */, + 574 /* 2.23.42.0.56 (OBJ_setct_CapTokenTBE) */, + 575 /* 2.23.42.0.57 (OBJ_setct_CapTokenTBEX) */, + 576 /* 2.23.42.0.58 (OBJ_setct_AcqCardCodeMsgTBE) */, + 577 /* 2.23.42.0.59 (OBJ_setct_AuthRevReqTBE) */, + 578 /* 2.23.42.0.60 (OBJ_setct_AuthRevResTBE) */, + 579 /* 2.23.42.0.61 (OBJ_setct_AuthRevResTBEB) */, + 580 /* 2.23.42.0.62 (OBJ_setct_CapReqTBE) */, + 581 /* 2.23.42.0.63 (OBJ_setct_CapReqTBEX) */, + 582 /* 2.23.42.0.64 (OBJ_setct_CapResTBE) */, + 583 /* 2.23.42.0.65 (OBJ_setct_CapRevReqTBE) */, + 584 /* 2.23.42.0.66 (OBJ_setct_CapRevReqTBEX) */, + 585 /* 2.23.42.0.67 (OBJ_setct_CapRevResTBE) */, + 586 /* 2.23.42.0.68 (OBJ_setct_CredReqTBE) */, + 587 /* 2.23.42.0.69 (OBJ_setct_CredReqTBEX) */, + 588 /* 2.23.42.0.70 (OBJ_setct_CredResTBE) */, + 589 /* 2.23.42.0.71 (OBJ_setct_CredRevReqTBE) */, + 590 /* 2.23.42.0.72 (OBJ_setct_CredRevReqTBEX) */, + 591 /* 2.23.42.0.73 (OBJ_setct_CredRevResTBE) */, + 592 /* 2.23.42.0.74 (OBJ_setct_BatchAdminReqTBE) */, + 593 /* 2.23.42.0.75 (OBJ_setct_BatchAdminResTBE) */, + 594 /* 2.23.42.0.76 (OBJ_setct_RegFormReqTBE) */, + 595 /* 2.23.42.0.77 (OBJ_setct_CertReqTBE) */, + 596 /* 2.23.42.0.78 (OBJ_setct_CertReqTBEX) */, + 597 /* 2.23.42.0.79 (OBJ_setct_CertResTBE) */, + 598 /* 2.23.42.0.80 (OBJ_setct_CRLNotificationTBS) */, + 599 /* 2.23.42.0.81 (OBJ_setct_CRLNotificationResTBS) */, + 600 /* 2.23.42.0.82 (OBJ_setct_BCIDistributionTBS) */, + 601 /* 2.23.42.1.1 (OBJ_setext_genCrypt) */, + 602 /* 2.23.42.1.3 (OBJ_setext_miAuth) */, + 603 /* 2.23.42.1.4 (OBJ_setext_pinSecure) */, + 604 /* 2.23.42.1.5 (OBJ_setext_pinAny) */, + 605 /* 2.23.42.1.7 (OBJ_setext_track2) */, + 606 /* 2.23.42.1.8 (OBJ_setext_cv) */, + 620 /* 2.23.42.3.0 (OBJ_setAttr_Cert) */, + 621 /* 2.23.42.3.1 (OBJ_setAttr_PGWYcap) */, + 622 /* 2.23.42.3.2 (OBJ_setAttr_TokenType) */, + 623 /* 2.23.42.3.3 (OBJ_setAttr_IssCap) */, + 607 /* 2.23.42.5.0 (OBJ_set_policy_root) */, + 608 /* 2.23.42.7.0 (OBJ_setCext_hashedRoot) */, + 609 /* 2.23.42.7.1 (OBJ_setCext_certType) */, + 610 /* 2.23.42.7.2 (OBJ_setCext_merchData) */, + 611 /* 2.23.42.7.3 (OBJ_setCext_cCertRequired) */, + 612 /* 2.23.42.7.4 (OBJ_setCext_tunneling) */, + 613 /* 2.23.42.7.5 (OBJ_setCext_setExt) */, + 614 /* 2.23.42.7.6 (OBJ_setCext_setQualf) */, + 615 /* 2.23.42.7.7 (OBJ_setCext_PGWYcapabilities) */, + 616 /* 2.23.42.7.8 (OBJ_setCext_TokenIdentifier) */, + 617 /* 2.23.42.7.9 (OBJ_setCext_Track2Data) */, + 618 /* 2.23.42.7.10 (OBJ_setCext_TokenType) */, + 619 /* 2.23.42.7.11 (OBJ_setCext_IssuerCapabilities) */, + 636 /* 2.23.42.8.1 (OBJ_set_brand_IATA_ATA) */, + 640 /* 2.23.42.8.4 (OBJ_set_brand_Visa) */, + 641 /* 2.23.42.8.5 (OBJ_set_brand_MasterCard) */, + 637 /* 2.23.42.8.30 (OBJ_set_brand_Diners) */, + 638 /* 2.23.42.8.34 (OBJ_set_brand_AmericanExpress) */, + 639 /* 2.23.42.8.35 (OBJ_set_brand_JCB) */, + 805 /* 1.2.643.2.2 (OBJ_cryptopro) */, + 806 /* 1.2.643.2.9 (OBJ_cryptocom) */, + 184 /* 1.2.840.10040 (OBJ_X9_57) */, + 405 /* 1.2.840.10045 (OBJ_ansi_X9_62) */, + 389 /* 1.3.6.1.4.1 (OBJ_Enterprises) */, + 504 /* 1.3.6.1.7.1 (OBJ_mime_mhs) */, + 104 /* 1.3.14.3.2.3 (OBJ_md5WithRSA) */, + 29 /* 1.3.14.3.2.6 (OBJ_des_ecb) */, + 31 /* 1.3.14.3.2.7 (OBJ_des_cbc) */, + 45 /* 1.3.14.3.2.8 (OBJ_des_ofb64) */, + 30 /* 1.3.14.3.2.9 (OBJ_des_cfb64) */, + 377 /* 1.3.14.3.2.11 (OBJ_rsaSignature) */, + 67 /* 1.3.14.3.2.12 (OBJ_dsa_2) */, + 66 /* 1.3.14.3.2.13 (OBJ_dsaWithSHA) */, + 42 /* 1.3.14.3.2.15 (OBJ_shaWithRSAEncryption) */, + 32 /* 1.3.14.3.2.17 (OBJ_des_ede_ecb) */, + 41 /* 1.3.14.3.2.18 (OBJ_sha) */, + 64 /* 1.3.14.3.2.26 (OBJ_sha1) */, + 70 /* 1.3.14.3.2.27 (OBJ_dsaWithSHA1_2) */, + 115 /* 1.3.14.3.2.29 (OBJ_sha1WithRSA) */, + 117 /* 1.3.36.3.2.1 (OBJ_ripemd160) */, + 143 /* 1.3.101.1.4.1 (OBJ_sxnet) */, + 721 /* 1.3.132.0.1 (OBJ_sect163k1) */, + 722 /* 1.3.132.0.2 (OBJ_sect163r1) */, + 728 /* 1.3.132.0.3 (OBJ_sect239k1) */, + 717 /* 1.3.132.0.4 (OBJ_sect113r1) */, + 718 /* 1.3.132.0.5 (OBJ_sect113r2) */, + 704 /* 1.3.132.0.6 (OBJ_secp112r1) */, + 705 /* 1.3.132.0.7 (OBJ_secp112r2) */, + 709 /* 1.3.132.0.8 (OBJ_secp160r1) */, + 708 /* 1.3.132.0.9 (OBJ_secp160k1) */, + 714 /* 1.3.132.0.10 (OBJ_secp256k1) */, + 723 /* 1.3.132.0.15 (OBJ_sect163r2) */, + 729 /* 1.3.132.0.16 (OBJ_sect283k1) */, + 730 /* 1.3.132.0.17 (OBJ_sect283r1) */, + 719 /* 1.3.132.0.22 (OBJ_sect131r1) */, + 720 /* 1.3.132.0.23 (OBJ_sect131r2) */, + 724 /* 1.3.132.0.24 (OBJ_sect193r1) */, + 725 /* 1.3.132.0.25 (OBJ_sect193r2) */, + 726 /* 1.3.132.0.26 (OBJ_sect233k1) */, + 727 /* 1.3.132.0.27 (OBJ_sect233r1) */, + 706 /* 1.3.132.0.28 (OBJ_secp128r1) */, + 707 /* 1.3.132.0.29 (OBJ_secp128r2) */, + 710 /* 1.3.132.0.30 (OBJ_secp160r2) */, + 711 /* 1.3.132.0.31 (OBJ_secp192k1) */, + 712 /* 1.3.132.0.32 (OBJ_secp224k1) */, + 713 /* 1.3.132.0.33 (OBJ_secp224r1) */, + 715 /* 1.3.132.0.34 (OBJ_secp384r1) */, + 716 /* 1.3.132.0.35 (OBJ_secp521r1) */, + 731 /* 1.3.132.0.36 (OBJ_sect409k1) */, + 732 /* 1.3.132.0.37 (OBJ_sect409r1) */, + 733 /* 1.3.132.0.38 (OBJ_sect571k1) */, + 734 /* 1.3.132.0.39 (OBJ_sect571r1) */, + 624 /* 2.23.42.3.0.0 (OBJ_set_rootKeyThumb) */, + 625 /* 2.23.42.3.0.1 (OBJ_set_addPolicy) */, + 626 /* 2.23.42.3.2.1 (OBJ_setAttr_Token_EMV) */, + 627 /* 2.23.42.3.2.2 (OBJ_setAttr_Token_B0Prime) */, + 628 /* 2.23.42.3.3.3 (OBJ_setAttr_IssCap_CVM) */, + 629 /* 2.23.42.3.3.4 (OBJ_setAttr_IssCap_T2) */, + 630 /* 2.23.42.3.3.5 (OBJ_setAttr_IssCap_Sig) */, + 642 /* 2.23.42.8.6011 (OBJ_set_brand_Novus) */, + 735 /* 2.23.43.1.4.1 (OBJ_wap_wsg_idm_ecid_wtls1) */, + 736 /* 2.23.43.1.4.3 (OBJ_wap_wsg_idm_ecid_wtls3) */, + 737 /* 2.23.43.1.4.4 (OBJ_wap_wsg_idm_ecid_wtls4) */, + 738 /* 2.23.43.1.4.5 (OBJ_wap_wsg_idm_ecid_wtls5) */, + 739 /* 2.23.43.1.4.6 (OBJ_wap_wsg_idm_ecid_wtls6) */, + 740 /* 2.23.43.1.4.7 (OBJ_wap_wsg_idm_ecid_wtls7) */, + 741 /* 2.23.43.1.4.8 (OBJ_wap_wsg_idm_ecid_wtls8) */, + 742 /* 2.23.43.1.4.9 (OBJ_wap_wsg_idm_ecid_wtls9) */, + 743 /* 2.23.43.1.4.10 (OBJ_wap_wsg_idm_ecid_wtls10) */, + 744 /* 2.23.43.1.4.11 (OBJ_wap_wsg_idm_ecid_wtls11) */, + 745 /* 2.23.43.1.4.12 (OBJ_wap_wsg_idm_ecid_wtls12) */, + 804 /* 1.0.10118.3.0.55 (OBJ_whirlpool) */, + 773 /* 1.2.410.200004 (OBJ_kisa) */, + 807 /* 1.2.643.2.2.3 (OBJ_id_GostR3411_94_with_GostR3410_2001) */, + 808 /* 1.2.643.2.2.4 (OBJ_id_GostR3411_94_with_GostR3410_94) */, + 809 /* 1.2.643.2.2.9 (OBJ_id_GostR3411_94) */, + 810 /* 1.2.643.2.2.10 (OBJ_id_HMACGostR3411_94) */, + 811 /* 1.2.643.2.2.19 (OBJ_id_GostR3410_2001) */, + 812 /* 1.2.643.2.2.20 (OBJ_id_GostR3410_94) */, + 813 /* 1.2.643.2.2.21 (OBJ_id_Gost28147_89) */, + 815 /* 1.2.643.2.2.22 (OBJ_id_Gost28147_89_MAC) */, + 816 /* 1.2.643.2.2.23 (OBJ_id_GostR3411_94_prf) */, + 817 /* 1.2.643.2.2.98 (OBJ_id_GostR3410_2001DH) */, + 818 /* 1.2.643.2.2.99 (OBJ_id_GostR3410_94DH) */, + 1 /* 1.2.840.113549 (OBJ_rsadsi) */, + 185 /* 1.2.840.10040.4 (OBJ_X9cm) */, + 127 /* 1.3.6.1.5.5.7 (OBJ_id_pkix) */, + 505 /* 1.3.6.1.7.1.1 (OBJ_mime_mhs_headings) */, + 506 /* 1.3.6.1.7.1.2 (OBJ_mime_mhs_bodies) */, + 119 /* 1.3.36.3.3.1.2 (OBJ_ripemd160WithRSA) */, + 937 /* 1.3.132.1.11.0 (OBJ_dhSinglePass_stdDH_sha224kdf_scheme) */, + 938 /* 1.3.132.1.11.1 (OBJ_dhSinglePass_stdDH_sha256kdf_scheme) */, + 939 /* 1.3.132.1.11.2 (OBJ_dhSinglePass_stdDH_sha384kdf_scheme) */, + 940 /* 1.3.132.1.11.3 (OBJ_dhSinglePass_stdDH_sha512kdf_scheme) */, + 942 /* 1.3.132.1.14.0 (OBJ_dhSinglePass_cofactorDH_sha224kdf_scheme) */, + 943 /* 1.3.132.1.14.1 (OBJ_dhSinglePass_cofactorDH_sha256kdf_scheme) */, + 944 /* 1.3.132.1.14.2 (OBJ_dhSinglePass_cofactorDH_sha384kdf_scheme) */, + 945 /* 1.3.132.1.14.3 (OBJ_dhSinglePass_cofactorDH_sha512kdf_scheme) */, + 631 /* 2.23.42.3.3.3.1 (OBJ_setAttr_GenCryptgrm) */, + 632 /* 2.23.42.3.3.4.1 (OBJ_setAttr_T2Enc) */, + 633 /* 2.23.42.3.3.4.2 (OBJ_setAttr_T2cleartxt) */, + 634 /* 2.23.42.3.3.5.1 (OBJ_setAttr_TokICCsig) */, + 635 /* 2.23.42.3.3.5.2 (OBJ_setAttr_SecDevSig) */, + 436 /* 0.9.2342.19200300 (OBJ_ucl) */, + 820 /* 1.2.643.2.2.14.0 (OBJ_id_Gost28147_89_None_KeyMeshing) */, + 819 /* 1.2.643.2.2.14.1 (OBJ_id_Gost28147_89_CryptoPro_KeyMeshing) */, + 845 /* 1.2.643.2.2.20.1 (OBJ_id_GostR3410_94_a) */, + 846 /* 1.2.643.2.2.20.2 (OBJ_id_GostR3410_94_aBis) */, + 847 /* 1.2.643.2.2.20.3 (OBJ_id_GostR3410_94_b) */, + 848 /* 1.2.643.2.2.20.4 (OBJ_id_GostR3410_94_bBis) */, + 821 /* 1.2.643.2.2.30.0 (OBJ_id_GostR3411_94_TestParamSet) */, + 822 /* 1.2.643.2.2.30.1 (OBJ_id_GostR3411_94_CryptoProParamSet) */, + 823 /* 1.2.643.2.2.31.0 (OBJ_id_Gost28147_89_TestParamSet) */, + 824 /* 1.2.643.2.2.31.1 (OBJ_id_Gost28147_89_CryptoPro_A_ParamSet) */, + 825 /* 1.2.643.2.2.31.2 (OBJ_id_Gost28147_89_CryptoPro_B_ParamSet) */, + 826 /* 1.2.643.2.2.31.3 (OBJ_id_Gost28147_89_CryptoPro_C_ParamSet) */, + 827 /* 1.2.643.2.2.31.4 (OBJ_id_Gost28147_89_CryptoPro_D_ParamSet) */, + 828 /* 1.2.643.2.2.31.5 (OBJ_id_Gost28147_89_CryptoPro_Oscar_1_1_ParamSet) */ + , + 829 /* 1.2.643.2.2.31.6 (OBJ_id_Gost28147_89_CryptoPro_Oscar_1_0_ParamSet) */ + , + 830 /* 1.2.643.2.2.31.7 (OBJ_id_Gost28147_89_CryptoPro_RIC_1_ParamSet) */, + 831 /* 1.2.643.2.2.32.0 (OBJ_id_GostR3410_94_TestParamSet) */, + 832 /* 1.2.643.2.2.32.2 (OBJ_id_GostR3410_94_CryptoPro_A_ParamSet) */, + 833 /* 1.2.643.2.2.32.3 (OBJ_id_GostR3410_94_CryptoPro_B_ParamSet) */, + 834 /* 1.2.643.2.2.32.4 (OBJ_id_GostR3410_94_CryptoPro_C_ParamSet) */, + 835 /* 1.2.643.2.2.32.5 (OBJ_id_GostR3410_94_CryptoPro_D_ParamSet) */, + 836 /* 1.2.643.2.2.33.1 (OBJ_id_GostR3410_94_CryptoPro_XchA_ParamSet) */, + 837 /* 1.2.643.2.2.33.2 (OBJ_id_GostR3410_94_CryptoPro_XchB_ParamSet) */, + 838 /* 1.2.643.2.2.33.3 (OBJ_id_GostR3410_94_CryptoPro_XchC_ParamSet) */, + 839 /* 1.2.643.2.2.35.0 (OBJ_id_GostR3410_2001_TestParamSet) */, + 840 /* 1.2.643.2.2.35.1 (OBJ_id_GostR3410_2001_CryptoPro_A_ParamSet) */, + 841 /* 1.2.643.2.2.35.2 (OBJ_id_GostR3410_2001_CryptoPro_B_ParamSet) */, + 842 /* 1.2.643.2.2.35.3 (OBJ_id_GostR3410_2001_CryptoPro_C_ParamSet) */, + 843 /* 1.2.643.2.2.36.0 (OBJ_id_GostR3410_2001_CryptoPro_XchA_ParamSet) */, + 844 /* 1.2.643.2.2.36.1 (OBJ_id_GostR3410_2001_CryptoPro_XchB_ParamSet) */, + 2 /* 1.2.840.113549.1 (OBJ_pkcs) */, + 431 /* 1.2.840.10040.2.1 (OBJ_hold_instruction_none) */, + 432 /* 1.2.840.10040.2.2 (OBJ_hold_instruction_call_issuer) */, + 433 /* 1.2.840.10040.2.3 (OBJ_hold_instruction_reject) */, + 116 /* 1.2.840.10040.4.1 (OBJ_dsa) */, + 113 /* 1.2.840.10040.4.3 (OBJ_dsaWithSHA1) */, + 406 /* 1.2.840.10045.1.1 (OBJ_X9_62_prime_field) */, + 407 /* 1.2.840.10045.1.2 (OBJ_X9_62_characteristic_two_field) */, + 408 /* 1.2.840.10045.2.1 (OBJ_X9_62_id_ecPublicKey) */, + 416 /* 1.2.840.10045.4.1 (OBJ_ecdsa_with_SHA1) */, + 791 /* 1.2.840.10045.4.2 (OBJ_ecdsa_with_Recommended) */, + 792 /* 1.2.840.10045.4.3 (OBJ_ecdsa_with_Specified) */, + 920 /* 1.2.840.10046.2.1 (OBJ_dhpublicnumber) */, + 258 /* 1.3.6.1.5.5.7.0 (OBJ_id_pkix_mod) */, + 175 /* 1.3.6.1.5.5.7.1 (OBJ_id_pe) */, + 259 /* 1.3.6.1.5.5.7.2 (OBJ_id_qt) */, + 128 /* 1.3.6.1.5.5.7.3 (OBJ_id_kp) */, + 260 /* 1.3.6.1.5.5.7.4 (OBJ_id_it) */, + 261 /* 1.3.6.1.5.5.7.5 (OBJ_id_pkip) */, + 262 /* 1.3.6.1.5.5.7.6 (OBJ_id_alg) */, + 263 /* 1.3.6.1.5.5.7.7 (OBJ_id_cmc) */, + 264 /* 1.3.6.1.5.5.7.8 (OBJ_id_on) */, + 265 /* 1.3.6.1.5.5.7.9 (OBJ_id_pda) */, + 266 /* 1.3.6.1.5.5.7.10 (OBJ_id_aca) */, + 267 /* 1.3.6.1.5.5.7.11 (OBJ_id_qcs) */, + 268 /* 1.3.6.1.5.5.7.12 (OBJ_id_cct) */, + 662 /* 1.3.6.1.5.5.7.21 (OBJ_id_ppl) */, + 176 /* 1.3.6.1.5.5.7.48 (OBJ_id_ad) */, + 507 /* 1.3.6.1.7.1.1.1 (OBJ_id_hex_partial_message) */, + 508 /* 1.3.6.1.7.1.1.2 (OBJ_id_hex_multipart_message) */, + 57 /* 2.16.840.1.113730 (OBJ_netscape) */, + 754 /* 0.3.4401.5.3.1.9.1 (OBJ_camellia_128_ecb) */, + 766 /* 0.3.4401.5.3.1.9.3 (OBJ_camellia_128_ofb128) */, + 757 /* 0.3.4401.5.3.1.9.4 (OBJ_camellia_128_cfb128) */, + 755 /* 0.3.4401.5.3.1.9.21 (OBJ_camellia_192_ecb) */, + 767 /* 0.3.4401.5.3.1.9.23 (OBJ_camellia_192_ofb128) */, + 758 /* 0.3.4401.5.3.1.9.24 (OBJ_camellia_192_cfb128) */, + 756 /* 0.3.4401.5.3.1.9.41 (OBJ_camellia_256_ecb) */, + 768 /* 0.3.4401.5.3.1.9.43 (OBJ_camellia_256_ofb128) */, + 759 /* 0.3.4401.5.3.1.9.44 (OBJ_camellia_256_cfb128) */, + 437 /* 0.9.2342.19200300.100 (OBJ_pilot) */, + 776 /* 1.2.410.200004.1.3 (OBJ_seed_ecb) */, + 777 /* 1.2.410.200004.1.4 (OBJ_seed_cbc) */, + 779 /* 1.2.410.200004.1.5 (OBJ_seed_cfb128) */, + 778 /* 1.2.410.200004.1.6 (OBJ_seed_ofb128) */, + 852 /* 1.2.643.2.9.1.3.3 (OBJ_id_GostR3411_94_with_GostR3410_94_cc) */, + 853 /* 1.2.643.2.9.1.3.4 (OBJ_id_GostR3411_94_with_GostR3410_2001_cc) */, + 850 /* 1.2.643.2.9.1.5.3 (OBJ_id_GostR3410_94_cc) */, + 851 /* 1.2.643.2.9.1.5.4 (OBJ_id_GostR3410_2001_cc) */, + 849 /* 1.2.643.2.9.1.6.1 (OBJ_id_Gost28147_89_cc) */, + 854 /* 1.2.643.2.9.1.8.1 (OBJ_id_GostR3410_2001_ParamSet_cc) */, + 186 /* 1.2.840.113549.1.1 (OBJ_pkcs1) */, + 27 /* 1.2.840.113549.1.3 (OBJ_pkcs3) */, + 187 /* 1.2.840.113549.1.5 (OBJ_pkcs5) */, + 20 /* 1.2.840.113549.1.7 (OBJ_pkcs7) */, + 47 /* 1.2.840.113549.1.9 (OBJ_pkcs9) */, + 3 /* 1.2.840.113549.2.2 (OBJ_md2) */, + 257 /* 1.2.840.113549.2.4 (OBJ_md4) */, + 4 /* 1.2.840.113549.2.5 (OBJ_md5) */, + 797 /* 1.2.840.113549.2.6 (OBJ_hmacWithMD5) */, + 163 /* 1.2.840.113549.2.7 (OBJ_hmacWithSHA1) */, + 798 /* 1.2.840.113549.2.8 (OBJ_hmacWithSHA224) */, + 799 /* 1.2.840.113549.2.9 (OBJ_hmacWithSHA256) */, + 800 /* 1.2.840.113549.2.10 (OBJ_hmacWithSHA384) */, + 801 /* 1.2.840.113549.2.11 (OBJ_hmacWithSHA512) */, + 37 /* 1.2.840.113549.3.2 (OBJ_rc2_cbc) */, + 5 /* 1.2.840.113549.3.4 (OBJ_rc4) */, + 44 /* 1.2.840.113549.3.7 (OBJ_des_ede3_cbc) */, + 120 /* 1.2.840.113549.3.8 (OBJ_rc5_cbc) */, + 643 /* 1.2.840.113549.3.10 (OBJ_des_cdmf) */, + 680 /* 1.2.840.10045.1.2.3 (OBJ_X9_62_id_characteristic_two_basis) */, + 684 /* 1.2.840.10045.3.0.1 (OBJ_X9_62_c2pnb163v1) */, + 685 /* 1.2.840.10045.3.0.2 (OBJ_X9_62_c2pnb163v2) */, + 686 /* 1.2.840.10045.3.0.3 (OBJ_X9_62_c2pnb163v3) */, + 687 /* 1.2.840.10045.3.0.4 (OBJ_X9_62_c2pnb176v1) */, + 688 /* 1.2.840.10045.3.0.5 (OBJ_X9_62_c2tnb191v1) */, + 689 /* 1.2.840.10045.3.0.6 (OBJ_X9_62_c2tnb191v2) */, + 690 /* 1.2.840.10045.3.0.7 (OBJ_X9_62_c2tnb191v3) */, + 691 /* 1.2.840.10045.3.0.8 (OBJ_X9_62_c2onb191v4) */, + 692 /* 1.2.840.10045.3.0.9 (OBJ_X9_62_c2onb191v5) */, + 693 /* 1.2.840.10045.3.0.10 (OBJ_X9_62_c2pnb208w1) */, + 694 /* 1.2.840.10045.3.0.11 (OBJ_X9_62_c2tnb239v1) */, + 695 /* 1.2.840.10045.3.0.12 (OBJ_X9_62_c2tnb239v2) */, + 696 /* 1.2.840.10045.3.0.13 (OBJ_X9_62_c2tnb239v3) */, + 697 /* 1.2.840.10045.3.0.14 (OBJ_X9_62_c2onb239v4) */, + 698 /* 1.2.840.10045.3.0.15 (OBJ_X9_62_c2onb239v5) */, + 699 /* 1.2.840.10045.3.0.16 (OBJ_X9_62_c2pnb272w1) */, + 700 /* 1.2.840.10045.3.0.17 (OBJ_X9_62_c2pnb304w1) */, + 701 /* 1.2.840.10045.3.0.18 (OBJ_X9_62_c2tnb359v1) */, + 702 /* 1.2.840.10045.3.0.19 (OBJ_X9_62_c2pnb368w1) */, + 703 /* 1.2.840.10045.3.0.20 (OBJ_X9_62_c2tnb431r1) */, + 409 /* 1.2.840.10045.3.1.1 (OBJ_X9_62_prime192v1) */, + 410 /* 1.2.840.10045.3.1.2 (OBJ_X9_62_prime192v2) */, + 411 /* 1.2.840.10045.3.1.3 (OBJ_X9_62_prime192v3) */, + 412 /* 1.2.840.10045.3.1.4 (OBJ_X9_62_prime239v1) */, + 413 /* 1.2.840.10045.3.1.5 (OBJ_X9_62_prime239v2) */, + 414 /* 1.2.840.10045.3.1.6 (OBJ_X9_62_prime239v3) */, + 415 /* 1.2.840.10045.3.1.7 (OBJ_X9_62_prime256v1) */, + 793 /* 1.2.840.10045.4.3.1 (OBJ_ecdsa_with_SHA224) */, + 794 /* 1.2.840.10045.4.3.2 (OBJ_ecdsa_with_SHA256) */, + 795 /* 1.2.840.10045.4.3.3 (OBJ_ecdsa_with_SHA384) */, + 796 /* 1.2.840.10045.4.3.4 (OBJ_ecdsa_with_SHA512) */, + 269 /* 1.3.6.1.5.5.7.0.1 (OBJ_id_pkix1_explicit_88) */, + 270 /* 1.3.6.1.5.5.7.0.2 (OBJ_id_pkix1_implicit_88) */, + 271 /* 1.3.6.1.5.5.7.0.3 (OBJ_id_pkix1_explicit_93) */, + 272 /* 1.3.6.1.5.5.7.0.4 (OBJ_id_pkix1_implicit_93) */, + 273 /* 1.3.6.1.5.5.7.0.5 (OBJ_id_mod_crmf) */, + 274 /* 1.3.6.1.5.5.7.0.6 (OBJ_id_mod_cmc) */, + 275 /* 1.3.6.1.5.5.7.0.7 (OBJ_id_mod_kea_profile_88) */, + 276 /* 1.3.6.1.5.5.7.0.8 (OBJ_id_mod_kea_profile_93) */, + 277 /* 1.3.6.1.5.5.7.0.9 (OBJ_id_mod_cmp) */, + 278 /* 1.3.6.1.5.5.7.0.10 (OBJ_id_mod_qualified_cert_88) */, + 279 /* 1.3.6.1.5.5.7.0.11 (OBJ_id_mod_qualified_cert_93) */, + 280 /* 1.3.6.1.5.5.7.0.12 (OBJ_id_mod_attribute_cert) */, + 281 /* 1.3.6.1.5.5.7.0.13 (OBJ_id_mod_timestamp_protocol) */, + 282 /* 1.3.6.1.5.5.7.0.14 (OBJ_id_mod_ocsp) */, + 283 /* 1.3.6.1.5.5.7.0.15 (OBJ_id_mod_dvcs) */, + 284 /* 1.3.6.1.5.5.7.0.16 (OBJ_id_mod_cmp2000) */, + 177 /* 1.3.6.1.5.5.7.1.1 (OBJ_info_access) */, + 285 /* 1.3.6.1.5.5.7.1.2 (OBJ_biometricInfo) */, + 286 /* 1.3.6.1.5.5.7.1.3 (OBJ_qcStatements) */, + 287 /* 1.3.6.1.5.5.7.1.4 (OBJ_ac_auditEntity) */, + 288 /* 1.3.6.1.5.5.7.1.5 (OBJ_ac_targeting) */, + 289 /* 1.3.6.1.5.5.7.1.6 (OBJ_aaControls) */, + 290 /* 1.3.6.1.5.5.7.1.7 (OBJ_sbgp_ipAddrBlock) */, + 291 /* 1.3.6.1.5.5.7.1.8 (OBJ_sbgp_autonomousSysNum) */, + 292 /* 1.3.6.1.5.5.7.1.9 (OBJ_sbgp_routerIdentifier) */, + 397 /* 1.3.6.1.5.5.7.1.10 (OBJ_ac_proxying) */, + 398 /* 1.3.6.1.5.5.7.1.11 (OBJ_sinfo_access) */, + 663 /* 1.3.6.1.5.5.7.1.14 (OBJ_proxyCertInfo) */, + 164 /* 1.3.6.1.5.5.7.2.1 (OBJ_id_qt_cps) */, + 165 /* 1.3.6.1.5.5.7.2.2 (OBJ_id_qt_unotice) */, + 293 /* 1.3.6.1.5.5.7.2.3 (OBJ_textNotice) */, + 129 /* 1.3.6.1.5.5.7.3.1 (OBJ_server_auth) */, + 130 /* 1.3.6.1.5.5.7.3.2 (OBJ_client_auth) */, + 131 /* 1.3.6.1.5.5.7.3.3 (OBJ_code_sign) */, + 132 /* 1.3.6.1.5.5.7.3.4 (OBJ_email_protect) */, + 294 /* 1.3.6.1.5.5.7.3.5 (OBJ_ipsecEndSystem) */, + 295 /* 1.3.6.1.5.5.7.3.6 (OBJ_ipsecTunnel) */, + 296 /* 1.3.6.1.5.5.7.3.7 (OBJ_ipsecUser) */, + 133 /* 1.3.6.1.5.5.7.3.8 (OBJ_time_stamp) */, + 180 /* 1.3.6.1.5.5.7.3.9 (OBJ_OCSP_sign) */, + 297 /* 1.3.6.1.5.5.7.3.10 (OBJ_dvcs) */, + 298 /* 1.3.6.1.5.5.7.4.1 (OBJ_id_it_caProtEncCert) */, + 299 /* 1.3.6.1.5.5.7.4.2 (OBJ_id_it_signKeyPairTypes) */, + 300 /* 1.3.6.1.5.5.7.4.3 (OBJ_id_it_encKeyPairTypes) */, + 301 /* 1.3.6.1.5.5.7.4.4 (OBJ_id_it_preferredSymmAlg) */, + 302 /* 1.3.6.1.5.5.7.4.5 (OBJ_id_it_caKeyUpdateInfo) */, + 303 /* 1.3.6.1.5.5.7.4.6 (OBJ_id_it_currentCRL) */, + 304 /* 1.3.6.1.5.5.7.4.7 (OBJ_id_it_unsupportedOIDs) */, + 305 /* 1.3.6.1.5.5.7.4.8 (OBJ_id_it_subscriptionRequest) */, + 306 /* 1.3.6.1.5.5.7.4.9 (OBJ_id_it_subscriptionResponse) */, + 307 /* 1.3.6.1.5.5.7.4.10 (OBJ_id_it_keyPairParamReq) */, + 308 /* 1.3.6.1.5.5.7.4.11 (OBJ_id_it_keyPairParamRep) */, + 309 /* 1.3.6.1.5.5.7.4.12 (OBJ_id_it_revPassphrase) */, + 310 /* 1.3.6.1.5.5.7.4.13 (OBJ_id_it_implicitConfirm) */, + 311 /* 1.3.6.1.5.5.7.4.14 (OBJ_id_it_confirmWaitTime) */, + 312 /* 1.3.6.1.5.5.7.4.15 (OBJ_id_it_origPKIMessage) */, + 784 /* 1.3.6.1.5.5.7.4.16 (OBJ_id_it_suppLangTags) */, + 313 /* 1.3.6.1.5.5.7.5.1 (OBJ_id_regCtrl) */, + 314 /* 1.3.6.1.5.5.7.5.2 (OBJ_id_regInfo) */, + 323 /* 1.3.6.1.5.5.7.6.1 (OBJ_id_alg_des40) */, + 324 /* 1.3.6.1.5.5.7.6.2 (OBJ_id_alg_noSignature) */, + 325 /* 1.3.6.1.5.5.7.6.3 (OBJ_id_alg_dh_sig_hmac_sha1) */, + 326 /* 1.3.6.1.5.5.7.6.4 (OBJ_id_alg_dh_pop) */, + 327 /* 1.3.6.1.5.5.7.7.1 (OBJ_id_cmc_statusInfo) */, + 328 /* 1.3.6.1.5.5.7.7.2 (OBJ_id_cmc_identification) */, + 329 /* 1.3.6.1.5.5.7.7.3 (OBJ_id_cmc_identityProof) */, + 330 /* 1.3.6.1.5.5.7.7.4 (OBJ_id_cmc_dataReturn) */, + 331 /* 1.3.6.1.5.5.7.7.5 (OBJ_id_cmc_transactionId) */, + 332 /* 1.3.6.1.5.5.7.7.6 (OBJ_id_cmc_senderNonce) */, + 333 /* 1.3.6.1.5.5.7.7.7 (OBJ_id_cmc_recipientNonce) */, + 334 /* 1.3.6.1.5.5.7.7.8 (OBJ_id_cmc_addExtensions) */, + 335 /* 1.3.6.1.5.5.7.7.9 (OBJ_id_cmc_encryptedPOP) */, + 336 /* 1.3.6.1.5.5.7.7.10 (OBJ_id_cmc_decryptedPOP) */, + 337 /* 1.3.6.1.5.5.7.7.11 (OBJ_id_cmc_lraPOPWitness) */, + 338 /* 1.3.6.1.5.5.7.7.15 (OBJ_id_cmc_getCert) */, + 339 /* 1.3.6.1.5.5.7.7.16 (OBJ_id_cmc_getCRL) */, + 340 /* 1.3.6.1.5.5.7.7.17 (OBJ_id_cmc_revokeRequest) */, + 341 /* 1.3.6.1.5.5.7.7.18 (OBJ_id_cmc_regInfo) */, + 342 /* 1.3.6.1.5.5.7.7.19 (OBJ_id_cmc_responseInfo) */, + 343 /* 1.3.6.1.5.5.7.7.21 (OBJ_id_cmc_queryPending) */, + 344 /* 1.3.6.1.5.5.7.7.22 (OBJ_id_cmc_popLinkRandom) */, + 345 /* 1.3.6.1.5.5.7.7.23 (OBJ_id_cmc_popLinkWitness) */, + 346 /* 1.3.6.1.5.5.7.7.24 (OBJ_id_cmc_confirmCertAcceptance) */, + 347 /* 1.3.6.1.5.5.7.8.1 (OBJ_id_on_personalData) */, + 858 /* 1.3.6.1.5.5.7.8.3 (OBJ_id_on_permanentIdentifier) */, + 348 /* 1.3.6.1.5.5.7.9.1 (OBJ_id_pda_dateOfBirth) */, + 349 /* 1.3.6.1.5.5.7.9.2 (OBJ_id_pda_placeOfBirth) */, + 351 /* 1.3.6.1.5.5.7.9.3 (OBJ_id_pda_gender) */, + 352 /* 1.3.6.1.5.5.7.9.4 (OBJ_id_pda_countryOfCitizenship) */, + 353 /* 1.3.6.1.5.5.7.9.5 (OBJ_id_pda_countryOfResidence) */, + 354 /* 1.3.6.1.5.5.7.10.1 (OBJ_id_aca_authenticationInfo) */, + 355 /* 1.3.6.1.5.5.7.10.2 (OBJ_id_aca_accessIdentity) */, + 356 /* 1.3.6.1.5.5.7.10.3 (OBJ_id_aca_chargingIdentity) */, + 357 /* 1.3.6.1.5.5.7.10.4 (OBJ_id_aca_group) */, + 358 /* 1.3.6.1.5.5.7.10.5 (OBJ_id_aca_role) */, + 399 /* 1.3.6.1.5.5.7.10.6 (OBJ_id_aca_encAttrs) */, + 359 /* 1.3.6.1.5.5.7.11.1 (OBJ_id_qcs_pkixQCSyntax_v1) */, + 360 /* 1.3.6.1.5.5.7.12.1 (OBJ_id_cct_crs) */, + 361 /* 1.3.6.1.5.5.7.12.2 (OBJ_id_cct_PKIData) */, + 362 /* 1.3.6.1.5.5.7.12.3 (OBJ_id_cct_PKIResponse) */, + 664 /* 1.3.6.1.5.5.7.21.0 (OBJ_id_ppl_anyLanguage) */, + 665 /* 1.3.6.1.5.5.7.21.1 (OBJ_id_ppl_inheritAll) */, + 667 /* 1.3.6.1.5.5.7.21.2 (OBJ_Independent) */, + 178 /* 1.3.6.1.5.5.7.48.1 (OBJ_ad_OCSP) */, + 179 /* 1.3.6.1.5.5.7.48.2 (OBJ_ad_ca_issuers) */, + 363 /* 1.3.6.1.5.5.7.48.3 (OBJ_ad_timeStamping) */, + 364 /* 1.3.6.1.5.5.7.48.4 (OBJ_ad_dvcs) */, + 785 /* 1.3.6.1.5.5.7.48.5 (OBJ_caRepository) */, + 780 /* 1.3.6.1.5.5.8.1.1 (OBJ_hmac_md5) */, + 781 /* 1.3.6.1.5.5.8.1.2 (OBJ_hmac_sha1) */, + 58 /* 2.16.840.1.113730.1 (OBJ_netscape_cert_extension) */, + 59 /* 2.16.840.1.113730.2 (OBJ_netscape_data_type) */, + 438 /* 0.9.2342.19200300.100.1 (OBJ_pilotAttributeType) */, + 439 /* 0.9.2342.19200300.100.3 (OBJ_pilotAttributeSyntax) */, + 440 /* 0.9.2342.19200300.100.4 (OBJ_pilotObjectClass) */, + 441 /* 0.9.2342.19200300.100.10 (OBJ_pilotGroups) */, + 108 /* 1.2.840.113533.7.66.10 (OBJ_cast5_cbc) */, + 112 /* 1.2.840.113533.7.66.12 (OBJ_pbeWithMD5AndCast5_CBC) */, + 782 /* 1.2.840.113533.7.66.13 (OBJ_id_PasswordBasedMAC) */, + 783 /* 1.2.840.113533.7.66.30 (OBJ_id_DHBasedMac) */, + 6 /* 1.2.840.113549.1.1.1 (OBJ_rsaEncryption) */, + 7 /* 1.2.840.113549.1.1.2 (OBJ_md2WithRSAEncryption) */, + 396 /* 1.2.840.113549.1.1.3 (OBJ_md4WithRSAEncryption) */, + 8 /* 1.2.840.113549.1.1.4 (OBJ_md5WithRSAEncryption) */, + 65 /* 1.2.840.113549.1.1.5 (OBJ_sha1WithRSAEncryption) */, + 644 /* 1.2.840.113549.1.1.6 (OBJ_rsaOAEPEncryptionSET) */, + 919 /* 1.2.840.113549.1.1.7 (OBJ_rsaesOaep) */, + 911 /* 1.2.840.113549.1.1.8 (OBJ_mgf1) */, + 935 /* 1.2.840.113549.1.1.9 (OBJ_pSpecified) */, + 912 /* 1.2.840.113549.1.1.10 (OBJ_rsassaPss) */, + 668 /* 1.2.840.113549.1.1.11 (OBJ_sha256WithRSAEncryption) */, + 669 /* 1.2.840.113549.1.1.12 (OBJ_sha384WithRSAEncryption) */, + 670 /* 1.2.840.113549.1.1.13 (OBJ_sha512WithRSAEncryption) */, + 671 /* 1.2.840.113549.1.1.14 (OBJ_sha224WithRSAEncryption) */, + 28 /* 1.2.840.113549.1.3.1 (OBJ_dhKeyAgreement) */, + 9 /* 1.2.840.113549.1.5.1 (OBJ_pbeWithMD2AndDES_CBC) */, + 10 /* 1.2.840.113549.1.5.3 (OBJ_pbeWithMD5AndDES_CBC) */, + 168 /* 1.2.840.113549.1.5.4 (OBJ_pbeWithMD2AndRC2_CBC) */, + 169 /* 1.2.840.113549.1.5.6 (OBJ_pbeWithMD5AndRC2_CBC) */, + 170 /* 1.2.840.113549.1.5.10 (OBJ_pbeWithSHA1AndDES_CBC) */, + 68 /* 1.2.840.113549.1.5.11 (OBJ_pbeWithSHA1AndRC2_CBC) */, + 69 /* 1.2.840.113549.1.5.12 (OBJ_id_pbkdf2) */, + 161 /* 1.2.840.113549.1.5.13 (OBJ_pbes2) */, + 162 /* 1.2.840.113549.1.5.14 (OBJ_pbmac1) */, + 21 /* 1.2.840.113549.1.7.1 (OBJ_pkcs7_data) */, + 22 /* 1.2.840.113549.1.7.2 (OBJ_pkcs7_signed) */, + 23 /* 1.2.840.113549.1.7.3 (OBJ_pkcs7_enveloped) */, + 24 /* 1.2.840.113549.1.7.4 (OBJ_pkcs7_signedAndEnveloped) */, + 25 /* 1.2.840.113549.1.7.5 (OBJ_pkcs7_digest) */, + 26 /* 1.2.840.113549.1.7.6 (OBJ_pkcs7_encrypted) */, + 48 /* 1.2.840.113549.1.9.1 (OBJ_pkcs9_emailAddress) */, + 49 /* 1.2.840.113549.1.9.2 (OBJ_pkcs9_unstructuredName) */, + 50 /* 1.2.840.113549.1.9.3 (OBJ_pkcs9_contentType) */, + 51 /* 1.2.840.113549.1.9.4 (OBJ_pkcs9_messageDigest) */, + 52 /* 1.2.840.113549.1.9.5 (OBJ_pkcs9_signingTime) */, + 53 /* 1.2.840.113549.1.9.6 (OBJ_pkcs9_countersignature) */, + 54 /* 1.2.840.113549.1.9.7 (OBJ_pkcs9_challengePassword) */, + 55 /* 1.2.840.113549.1.9.8 (OBJ_pkcs9_unstructuredAddress) */, + 56 /* 1.2.840.113549.1.9.9 (OBJ_pkcs9_extCertAttributes) */, + 172 /* 1.2.840.113549.1.9.14 (OBJ_ext_req) */, + 167 /* 1.2.840.113549.1.9.15 (OBJ_SMIMECapabilities) */, + 188 /* 1.2.840.113549.1.9.16 (OBJ_SMIME) */, + 156 /* 1.2.840.113549.1.9.20 (OBJ_friendlyName) */, + 157 /* 1.2.840.113549.1.9.21 (OBJ_localKeyID) */, + 681 /* 1.2.840.10045.1.2.3.1 (OBJ_X9_62_onBasis) */, + 682 /* 1.2.840.10045.1.2.3.2 (OBJ_X9_62_tpBasis) */, + 683 /* 1.2.840.10045.1.2.3.3 (OBJ_X9_62_ppBasis) */, + 417 /* 1.3.6.1.4.1.311.17.1 (OBJ_ms_csp_name) */, + 856 /* 1.3.6.1.4.1.311.17.2 (OBJ_LocalKeySet) */, + 390 /* 1.3.6.1.4.1.1466.344 (OBJ_dcObject) */, + 91 /* 1.3.6.1.4.1.3029.1.2 (OBJ_bf_cbc) */, + 315 /* 1.3.6.1.5.5.7.5.1.1 (OBJ_id_regCtrl_regToken) */, + 316 /* 1.3.6.1.5.5.7.5.1.2 (OBJ_id_regCtrl_authenticator) */, + 317 /* 1.3.6.1.5.5.7.5.1.3 (OBJ_id_regCtrl_pkiPublicationInfo) */, + 318 /* 1.3.6.1.5.5.7.5.1.4 (OBJ_id_regCtrl_pkiArchiveOptions) */, + 319 /* 1.3.6.1.5.5.7.5.1.5 (OBJ_id_regCtrl_oldCertID) */, + 320 /* 1.3.6.1.5.5.7.5.1.6 (OBJ_id_regCtrl_protocolEncrKey) */, + 321 /* 1.3.6.1.5.5.7.5.2.1 (OBJ_id_regInfo_utf8Pairs) */, + 322 /* 1.3.6.1.5.5.7.5.2.2 (OBJ_id_regInfo_certReq) */, + 365 /* 1.3.6.1.5.5.7.48.1.1 (OBJ_id_pkix_OCSP_basic) */, + 366 /* 1.3.6.1.5.5.7.48.1.2 (OBJ_id_pkix_OCSP_Nonce) */, + 367 /* 1.3.6.1.5.5.7.48.1.3 (OBJ_id_pkix_OCSP_CrlID) */, + 368 /* 1.3.6.1.5.5.7.48.1.4 (OBJ_id_pkix_OCSP_acceptableResponses) */, + 369 /* 1.3.6.1.5.5.7.48.1.5 (OBJ_id_pkix_OCSP_noCheck) */, + 370 /* 1.3.6.1.5.5.7.48.1.6 (OBJ_id_pkix_OCSP_archiveCutoff) */, + 371 /* 1.3.6.1.5.5.7.48.1.7 (OBJ_id_pkix_OCSP_serviceLocator) */, + 372 /* 1.3.6.1.5.5.7.48.1.8 (OBJ_id_pkix_OCSP_extendedStatus) */, + 373 /* 1.3.6.1.5.5.7.48.1.9 (OBJ_id_pkix_OCSP_valid) */, + 374 /* 1.3.6.1.5.5.7.48.1.10 (OBJ_id_pkix_OCSP_path) */, + 375 /* 1.3.6.1.5.5.7.48.1.11 (OBJ_id_pkix_OCSP_trustRoot) */, + 921 /* 1.3.36.3.3.2.8.1.1.1 (OBJ_brainpoolP160r1) */, + 922 /* 1.3.36.3.3.2.8.1.1.2 (OBJ_brainpoolP160t1) */, + 923 /* 1.3.36.3.3.2.8.1.1.3 (OBJ_brainpoolP192r1) */, + 924 /* 1.3.36.3.3.2.8.1.1.4 (OBJ_brainpoolP192t1) */, + 925 /* 1.3.36.3.3.2.8.1.1.5 (OBJ_brainpoolP224r1) */, + 926 /* 1.3.36.3.3.2.8.1.1.6 (OBJ_brainpoolP224t1) */, + 927 /* 1.3.36.3.3.2.8.1.1.7 (OBJ_brainpoolP256r1) */, + 928 /* 1.3.36.3.3.2.8.1.1.8 (OBJ_brainpoolP256t1) */, + 929 /* 1.3.36.3.3.2.8.1.1.9 (OBJ_brainpoolP320r1) */, + 930 /* 1.3.36.3.3.2.8.1.1.10 (OBJ_brainpoolP320t1) */, + 931 /* 1.3.36.3.3.2.8.1.1.11 (OBJ_brainpoolP384r1) */, + 932 /* 1.3.36.3.3.2.8.1.1.12 (OBJ_brainpoolP384t1) */, + 933 /* 1.3.36.3.3.2.8.1.1.13 (OBJ_brainpoolP512r1) */, + 934 /* 1.3.36.3.3.2.8.1.1.14 (OBJ_brainpoolP512t1) */, + 936 /* 1.3.133.16.840.63.0.2 (OBJ_dhSinglePass_stdDH_sha1kdf_scheme) */, + 941 /* 1.3.133.16.840.63.0.3 (OBJ_dhSinglePass_cofactorDH_sha1kdf_scheme) */ + , + 418 /* 2.16.840.1.101.3.4.1.1 (OBJ_aes_128_ecb) */, + 419 /* 2.16.840.1.101.3.4.1.2 (OBJ_aes_128_cbc) */, + 420 /* 2.16.840.1.101.3.4.1.3 (OBJ_aes_128_ofb128) */, + 421 /* 2.16.840.1.101.3.4.1.4 (OBJ_aes_128_cfb128) */, + 788 /* 2.16.840.1.101.3.4.1.5 (OBJ_id_aes128_wrap) */, + 895 /* 2.16.840.1.101.3.4.1.6 (OBJ_aes_128_gcm) */, + 896 /* 2.16.840.1.101.3.4.1.7 (OBJ_aes_128_ccm) */, + 897 /* 2.16.840.1.101.3.4.1.8 (OBJ_id_aes128_wrap_pad) */, + 422 /* 2.16.840.1.101.3.4.1.21 (OBJ_aes_192_ecb) */, + 423 /* 2.16.840.1.101.3.4.1.22 (OBJ_aes_192_cbc) */, + 424 /* 2.16.840.1.101.3.4.1.23 (OBJ_aes_192_ofb128) */, + 425 /* 2.16.840.1.101.3.4.1.24 (OBJ_aes_192_cfb128) */, + 789 /* 2.16.840.1.101.3.4.1.25 (OBJ_id_aes192_wrap) */, + 898 /* 2.16.840.1.101.3.4.1.26 (OBJ_aes_192_gcm) */, + 899 /* 2.16.840.1.101.3.4.1.27 (OBJ_aes_192_ccm) */, + 900 /* 2.16.840.1.101.3.4.1.28 (OBJ_id_aes192_wrap_pad) */, + 426 /* 2.16.840.1.101.3.4.1.41 (OBJ_aes_256_ecb) */, + 427 /* 2.16.840.1.101.3.4.1.42 (OBJ_aes_256_cbc) */, + 428 /* 2.16.840.1.101.3.4.1.43 (OBJ_aes_256_ofb128) */, + 429 /* 2.16.840.1.101.3.4.1.44 (OBJ_aes_256_cfb128) */, + 790 /* 2.16.840.1.101.3.4.1.45 (OBJ_id_aes256_wrap) */, + 901 /* 2.16.840.1.101.3.4.1.46 (OBJ_aes_256_gcm) */, + 902 /* 2.16.840.1.101.3.4.1.47 (OBJ_aes_256_ccm) */, + 903 /* 2.16.840.1.101.3.4.1.48 (OBJ_id_aes256_wrap_pad) */, + 672 /* 2.16.840.1.101.3.4.2.1 (OBJ_sha256) */, + 673 /* 2.16.840.1.101.3.4.2.2 (OBJ_sha384) */, + 674 /* 2.16.840.1.101.3.4.2.3 (OBJ_sha512) */, + 675 /* 2.16.840.1.101.3.4.2.4 (OBJ_sha224) */, + 802 /* 2.16.840.1.101.3.4.3.1 (OBJ_dsa_with_SHA224) */, + 803 /* 2.16.840.1.101.3.4.3.2 (OBJ_dsa_with_SHA256) */, + 71 /* 2.16.840.1.113730.1.1 (OBJ_netscape_cert_type) */, + 72 /* 2.16.840.1.113730.1.2 (OBJ_netscape_base_url) */, + 73 /* 2.16.840.1.113730.1.3 (OBJ_netscape_revocation_url) */, + 74 /* 2.16.840.1.113730.1.4 (OBJ_netscape_ca_revocation_url) */, + 75 /* 2.16.840.1.113730.1.7 (OBJ_netscape_renewal_url) */, + 76 /* 2.16.840.1.113730.1.8 (OBJ_netscape_ca_policy_url) */, + 77 /* 2.16.840.1.113730.1.12 (OBJ_netscape_ssl_server_name) */, + 78 /* 2.16.840.1.113730.1.13 (OBJ_netscape_comment) */, + 79 /* 2.16.840.1.113730.2.5 (OBJ_netscape_cert_sequence) */, + 139 /* 2.16.840.1.113730.4.1 (OBJ_ns_sgc) */, + 458 /* 0.9.2342.19200300.100.1.1 (OBJ_userId) */, + 459 /* 0.9.2342.19200300.100.1.2 (OBJ_textEncodedORAddress) */, + 460 /* 0.9.2342.19200300.100.1.3 (OBJ_rfc822Mailbox) */, + 461 /* 0.9.2342.19200300.100.1.4 (OBJ_info) */, + 462 /* 0.9.2342.19200300.100.1.5 (OBJ_favouriteDrink) */, + 463 /* 0.9.2342.19200300.100.1.6 (OBJ_roomNumber) */, + 464 /* 0.9.2342.19200300.100.1.7 (OBJ_photo) */, + 465 /* 0.9.2342.19200300.100.1.8 (OBJ_userClass) */, + 466 /* 0.9.2342.19200300.100.1.9 (OBJ_host) */, + 467 /* 0.9.2342.19200300.100.1.10 (OBJ_manager) */, + 468 /* 0.9.2342.19200300.100.1.11 (OBJ_documentIdentifier) */, + 469 /* 0.9.2342.19200300.100.1.12 (OBJ_documentTitle) */, + 470 /* 0.9.2342.19200300.100.1.13 (OBJ_documentVersion) */, + 471 /* 0.9.2342.19200300.100.1.14 (OBJ_documentAuthor) */, + 472 /* 0.9.2342.19200300.100.1.15 (OBJ_documentLocation) */, + 473 /* 0.9.2342.19200300.100.1.20 (OBJ_homeTelephoneNumber) */, + 474 /* 0.9.2342.19200300.100.1.21 (OBJ_secretary) */, + 475 /* 0.9.2342.19200300.100.1.22 (OBJ_otherMailbox) */, + 476 /* 0.9.2342.19200300.100.1.23 (OBJ_lastModifiedTime) */, + 477 /* 0.9.2342.19200300.100.1.24 (OBJ_lastModifiedBy) */, + 391 /* 0.9.2342.19200300.100.1.25 (OBJ_domainComponent) */, + 478 /* 0.9.2342.19200300.100.1.26 (OBJ_aRecord) */, + 479 /* 0.9.2342.19200300.100.1.27 (OBJ_pilotAttributeType27) */, + 480 /* 0.9.2342.19200300.100.1.28 (OBJ_mXRecord) */, + 481 /* 0.9.2342.19200300.100.1.29 (OBJ_nSRecord) */, + 482 /* 0.9.2342.19200300.100.1.30 (OBJ_sOARecord) */, + 483 /* 0.9.2342.19200300.100.1.31 (OBJ_cNAMERecord) */, + 484 /* 0.9.2342.19200300.100.1.37 (OBJ_associatedDomain) */, + 485 /* 0.9.2342.19200300.100.1.38 (OBJ_associatedName) */, + 486 /* 0.9.2342.19200300.100.1.39 (OBJ_homePostalAddress) */, + 487 /* 0.9.2342.19200300.100.1.40 (OBJ_personalTitle) */, + 488 /* 0.9.2342.19200300.100.1.41 (OBJ_mobileTelephoneNumber) */, + 489 /* 0.9.2342.19200300.100.1.42 (OBJ_pagerTelephoneNumber) */, + 490 /* 0.9.2342.19200300.100.1.43 (OBJ_friendlyCountryName) */, + 491 /* 0.9.2342.19200300.100.1.45 (OBJ_organizationalStatus) */, + 492 /* 0.9.2342.19200300.100.1.46 (OBJ_janetMailbox) */, + 493 /* 0.9.2342.19200300.100.1.47 (OBJ_mailPreferenceOption) */, + 494 /* 0.9.2342.19200300.100.1.48 (OBJ_buildingName) */, + 495 /* 0.9.2342.19200300.100.1.49 (OBJ_dSAQuality) */, + 496 /* 0.9.2342.19200300.100.1.50 (OBJ_singleLevelQuality) */, + 497 /* 0.9.2342.19200300.100.1.51 (OBJ_subtreeMinimumQuality) */, + 498 /* 0.9.2342.19200300.100.1.52 (OBJ_subtreeMaximumQuality) */, + 499 /* 0.9.2342.19200300.100.1.53 (OBJ_personalSignature) */, + 500 /* 0.9.2342.19200300.100.1.54 (OBJ_dITRedirect) */, + 501 /* 0.9.2342.19200300.100.1.55 (OBJ_audio) */, + 502 /* 0.9.2342.19200300.100.1.56 (OBJ_documentPublisher) */, + 442 /* 0.9.2342.19200300.100.3.4 (OBJ_iA5StringSyntax) */, + 443 /* 0.9.2342.19200300.100.3.5 (OBJ_caseIgnoreIA5StringSyntax) */, + 444 /* 0.9.2342.19200300.100.4.3 (OBJ_pilotObject) */, + 445 /* 0.9.2342.19200300.100.4.4 (OBJ_pilotPerson) */, + 446 /* 0.9.2342.19200300.100.4.5 (OBJ_account) */, + 447 /* 0.9.2342.19200300.100.4.6 (OBJ_document) */, + 448 /* 0.9.2342.19200300.100.4.7 (OBJ_room) */, + 449 /* 0.9.2342.19200300.100.4.9 (OBJ_documentSeries) */, + 392 /* 0.9.2342.19200300.100.4.13 (OBJ_Domain) */, + 450 /* 0.9.2342.19200300.100.4.14 (OBJ_rFC822localPart) */, + 451 /* 0.9.2342.19200300.100.4.15 (OBJ_dNSDomain) */, + 452 /* 0.9.2342.19200300.100.4.17 (OBJ_domainRelatedObject) */, + 453 /* 0.9.2342.19200300.100.4.18 (OBJ_friendlyCountry) */, + 454 /* 0.9.2342.19200300.100.4.19 (OBJ_simpleSecurityObject) */, + 455 /* 0.9.2342.19200300.100.4.20 (OBJ_pilotOrganization) */, + 456 /* 0.9.2342.19200300.100.4.21 (OBJ_pilotDSA) */, + 457 /* 0.9.2342.19200300.100.4.22 (OBJ_qualityLabelledData) */, + 189 /* 1.2.840.113549.1.9.16.0 (OBJ_id_smime_mod) */, + 190 /* 1.2.840.113549.1.9.16.1 (OBJ_id_smime_ct) */, + 191 /* 1.2.840.113549.1.9.16.2 (OBJ_id_smime_aa) */, + 192 /* 1.2.840.113549.1.9.16.3 (OBJ_id_smime_alg) */, + 193 /* 1.2.840.113549.1.9.16.4 (OBJ_id_smime_cd) */, + 194 /* 1.2.840.113549.1.9.16.5 (OBJ_id_smime_spq) */, + 195 /* 1.2.840.113549.1.9.16.6 (OBJ_id_smime_cti) */, + 158 /* 1.2.840.113549.1.9.22.1 (OBJ_x509Certificate) */, + 159 /* 1.2.840.113549.1.9.22.2 (OBJ_sdsiCertificate) */, + 160 /* 1.2.840.113549.1.9.23.1 (OBJ_x509Crl) */, + 144 /* 1.2.840.113549.1.12.1.1 (OBJ_pbe_WithSHA1And128BitRC4) */, + 145 /* 1.2.840.113549.1.12.1.2 (OBJ_pbe_WithSHA1And40BitRC4) */, + 146 /* 1.2.840.113549.1.12.1.3 (OBJ_pbe_WithSHA1And3_Key_TripleDES_CBC) */, + 147 /* 1.2.840.113549.1.12.1.4 (OBJ_pbe_WithSHA1And2_Key_TripleDES_CBC) */, + 148 /* 1.2.840.113549.1.12.1.5 (OBJ_pbe_WithSHA1And128BitRC2_CBC) */, + 149 /* 1.2.840.113549.1.12.1.6 (OBJ_pbe_WithSHA1And40BitRC2_CBC) */, + 171 /* 1.3.6.1.4.1.311.2.1.14 (OBJ_ms_ext_req) */, + 134 /* 1.3.6.1.4.1.311.2.1.21 (OBJ_ms_code_ind) */, + 135 /* 1.3.6.1.4.1.311.2.1.22 (OBJ_ms_code_com) */, + 136 /* 1.3.6.1.4.1.311.10.3.1 (OBJ_ms_ctl_sign) */, + 137 /* 1.3.6.1.4.1.311.10.3.3 (OBJ_ms_sgc) */, + 138 /* 1.3.6.1.4.1.311.10.3.4 (OBJ_ms_efs) */, + 648 /* 1.3.6.1.4.1.311.20.2.2 (OBJ_ms_smartcard_login) */, + 649 /* 1.3.6.1.4.1.311.20.2.3 (OBJ_ms_upn) */, + 751 /* 1.2.392.200011.61.1.1.1.2 (OBJ_camellia_128_cbc) */, + 752 /* 1.2.392.200011.61.1.1.1.3 (OBJ_camellia_192_cbc) */, + 753 /* 1.2.392.200011.61.1.1.1.4 (OBJ_camellia_256_cbc) */, + 907 /* 1.2.392.200011.61.1.1.3.2 (OBJ_id_camellia128_wrap) */, + 908 /* 1.2.392.200011.61.1.1.3.3 (OBJ_id_camellia192_wrap) */, + 909 /* 1.2.392.200011.61.1.1.3.4 (OBJ_id_camellia256_wrap) */, + 196 /* 1.2.840.113549.1.9.16.0.1 (OBJ_id_smime_mod_cms) */, + 197 /* 1.2.840.113549.1.9.16.0.2 (OBJ_id_smime_mod_ess) */, + 198 /* 1.2.840.113549.1.9.16.0.3 (OBJ_id_smime_mod_oid) */, + 199 /* 1.2.840.113549.1.9.16.0.4 (OBJ_id_smime_mod_msg_v3) */, + 200 /* 1.2.840.113549.1.9.16.0.5 (OBJ_id_smime_mod_ets_eSignature_88) */, + 201 /* 1.2.840.113549.1.9.16.0.6 (OBJ_id_smime_mod_ets_eSignature_97) */, + 202 /* 1.2.840.113549.1.9.16.0.7 (OBJ_id_smime_mod_ets_eSigPolicy_88) */, + 203 /* 1.2.840.113549.1.9.16.0.8 (OBJ_id_smime_mod_ets_eSigPolicy_97) */, + 204 /* 1.2.840.113549.1.9.16.1.1 (OBJ_id_smime_ct_receipt) */, + 205 /* 1.2.840.113549.1.9.16.1.2 (OBJ_id_smime_ct_authData) */, + 206 /* 1.2.840.113549.1.9.16.1.3 (OBJ_id_smime_ct_publishCert) */, + 207 /* 1.2.840.113549.1.9.16.1.4 (OBJ_id_smime_ct_TSTInfo) */, + 208 /* 1.2.840.113549.1.9.16.1.5 (OBJ_id_smime_ct_TDTInfo) */, + 209 /* 1.2.840.113549.1.9.16.1.6 (OBJ_id_smime_ct_contentInfo) */, + 210 /* 1.2.840.113549.1.9.16.1.7 (OBJ_id_smime_ct_DVCSRequestData) */, + 211 /* 1.2.840.113549.1.9.16.1.8 (OBJ_id_smime_ct_DVCSResponseData) */, + 786 /* 1.2.840.113549.1.9.16.1.9 (OBJ_id_smime_ct_compressedData) */, + 787 /* 1.2.840.113549.1.9.16.1.27 (OBJ_id_ct_asciiTextWithCRLF) */, + 212 /* 1.2.840.113549.1.9.16.2.1 (OBJ_id_smime_aa_receiptRequest) */, + 213 /* 1.2.840.113549.1.9.16.2.2 (OBJ_id_smime_aa_securityLabel) */, + 214 /* 1.2.840.113549.1.9.16.2.3 (OBJ_id_smime_aa_mlExpandHistory) */, + 215 /* 1.2.840.113549.1.9.16.2.4 (OBJ_id_smime_aa_contentHint) */, + 216 /* 1.2.840.113549.1.9.16.2.5 (OBJ_id_smime_aa_msgSigDigest) */, + 217 /* 1.2.840.113549.1.9.16.2.6 (OBJ_id_smime_aa_encapContentType) */, + 218 /* 1.2.840.113549.1.9.16.2.7 (OBJ_id_smime_aa_contentIdentifier) */, + 219 /* 1.2.840.113549.1.9.16.2.8 (OBJ_id_smime_aa_macValue) */, + 220 /* 1.2.840.113549.1.9.16.2.9 (OBJ_id_smime_aa_equivalentLabels) */, + 221 /* 1.2.840.113549.1.9.16.2.10 (OBJ_id_smime_aa_contentReference) */, + 222 /* 1.2.840.113549.1.9.16.2.11 (OBJ_id_smime_aa_encrypKeyPref) */, + 223 /* 1.2.840.113549.1.9.16.2.12 (OBJ_id_smime_aa_signingCertificate) */, + 224 /* 1.2.840.113549.1.9.16.2.13 (OBJ_id_smime_aa_smimeEncryptCerts) */, + 225 /* 1.2.840.113549.1.9.16.2.14 (OBJ_id_smime_aa_timeStampToken) */, + 226 /* 1.2.840.113549.1.9.16.2.15 (OBJ_id_smime_aa_ets_sigPolicyId) */, + 227 /* 1.2.840.113549.1.9.16.2.16 (OBJ_id_smime_aa_ets_commitmentType) */, + 228 /* 1.2.840.113549.1.9.16.2.17 (OBJ_id_smime_aa_ets_signerLocation) */, + 229 /* 1.2.840.113549.1.9.16.2.18 (OBJ_id_smime_aa_ets_signerAttr) */, + 230 /* 1.2.840.113549.1.9.16.2.19 (OBJ_id_smime_aa_ets_otherSigCert) */, + 231 /* 1.2.840.113549.1.9.16.2.20 (OBJ_id_smime_aa_ets_contentTimestamp) */, + 232 /* 1.2.840.113549.1.9.16.2.21 (OBJ_id_smime_aa_ets_CertificateRefs) */, + 233 /* 1.2.840.113549.1.9.16.2.22 (OBJ_id_smime_aa_ets_RevocationRefs) */, + 234 /* 1.2.840.113549.1.9.16.2.23 (OBJ_id_smime_aa_ets_certValues) */, + 235 /* 1.2.840.113549.1.9.16.2.24 (OBJ_id_smime_aa_ets_revocationValues) */, + 236 /* 1.2.840.113549.1.9.16.2.25 (OBJ_id_smime_aa_ets_escTimeStamp) */, + 237 /* 1.2.840.113549.1.9.16.2.26 (OBJ_id_smime_aa_ets_certCRLTimestamp) */, + 238 /* 1.2.840.113549.1.9.16.2.27 (OBJ_id_smime_aa_ets_archiveTimeStamp) */, + 239 /* 1.2.840.113549.1.9.16.2.28 (OBJ_id_smime_aa_signatureType) */, + 240 /* 1.2.840.113549.1.9.16.2.29 (OBJ_id_smime_aa_dvcs_dvc) */, + 241 /* 1.2.840.113549.1.9.16.3.1 (OBJ_id_smime_alg_ESDHwith3DES) */, + 242 /* 1.2.840.113549.1.9.16.3.2 (OBJ_id_smime_alg_ESDHwithRC2) */, + 243 /* 1.2.840.113549.1.9.16.3.3 (OBJ_id_smime_alg_3DESwrap) */, + 244 /* 1.2.840.113549.1.9.16.3.4 (OBJ_id_smime_alg_RC2wrap) */, + 245 /* 1.2.840.113549.1.9.16.3.5 (OBJ_id_smime_alg_ESDH) */, + 246 /* 1.2.840.113549.1.9.16.3.6 (OBJ_id_smime_alg_CMS3DESwrap) */, + 247 /* 1.2.840.113549.1.9.16.3.7 (OBJ_id_smime_alg_CMSRC2wrap) */, + 125 /* 1.2.840.113549.1.9.16.3.8 (OBJ_zlib_compression) */, + 893 /* 1.2.840.113549.1.9.16.3.9 (OBJ_id_alg_PWRI_KEK) */, + 248 /* 1.2.840.113549.1.9.16.4.1 (OBJ_id_smime_cd_ldap) */, + 249 /* 1.2.840.113549.1.9.16.5.1 (OBJ_id_smime_spq_ets_sqt_uri) */, + 250 /* 1.2.840.113549.1.9.16.5.2 (OBJ_id_smime_spq_ets_sqt_unotice) */, + 251 /* 1.2.840.113549.1.9.16.6.1 (OBJ_id_smime_cti_ets_proofOfOrigin) */, + 252 /* 1.2.840.113549.1.9.16.6.2 (OBJ_id_smime_cti_ets_proofOfReceipt) */, + 253 /* 1.2.840.113549.1.9.16.6.3 (OBJ_id_smime_cti_ets_proofOfDelivery) */, + 254 /* 1.2.840.113549.1.9.16.6.4 (OBJ_id_smime_cti_ets_proofOfSender) */, + 255 /* 1.2.840.113549.1.9.16.6.5 (OBJ_id_smime_cti_ets_proofOfApproval) */, + 256 /* 1.2.840.113549.1.9.16.6.6 (OBJ_id_smime_cti_ets_proofOfCreation) */, + 150 /* 1.2.840.113549.1.12.10.1.1 (OBJ_keyBag) */, + 151 /* 1.2.840.113549.1.12.10.1.2 (OBJ_pkcs8ShroudedKeyBag) */, + 152 /* 1.2.840.113549.1.12.10.1.3 (OBJ_certBag) */, + 153 /* 1.2.840.113549.1.12.10.1.4 (OBJ_crlBag) */, + 154 /* 1.2.840.113549.1.12.10.1.5 (OBJ_secretBag) */, + 155 /* 1.2.840.113549.1.12.10.1.6 (OBJ_safeContentsBag) */, + 34 /* 1.3.6.1.4.1.188.7.1.1.2 (OBJ_idea_cbc) */, +}; diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/obj/obj_xref.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/obj/obj_xref.c new file mode 100644 index 0000000..303a8d9 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/obj/obj_xref.c @@ -0,0 +1,122 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include "../internal.h" + + +typedef struct { + int sign_nid; + int digest_nid; + int pkey_nid; +} nid_triple; + +static const nid_triple kTriples[] = { + // RSA PKCS#1. + {NID_md4WithRSAEncryption, NID_md4, NID_rsaEncryption}, + {NID_md5WithRSAEncryption, NID_md5, NID_rsaEncryption}, + {NID_sha1WithRSAEncryption, NID_sha1, NID_rsaEncryption}, + {NID_sha224WithRSAEncryption, NID_sha224, NID_rsaEncryption}, + {NID_sha256WithRSAEncryption, NID_sha256, NID_rsaEncryption}, + {NID_sha384WithRSAEncryption, NID_sha384, NID_rsaEncryption}, + {NID_sha512WithRSAEncryption, NID_sha512, NID_rsaEncryption}, + // DSA. + {NID_dsaWithSHA1, NID_sha1, NID_dsa}, + {NID_dsaWithSHA1_2, NID_sha1, NID_dsa_2}, + {NID_dsa_with_SHA224, NID_sha224, NID_dsa}, + {NID_dsa_with_SHA256, NID_sha256, NID_dsa}, + // ECDSA. + {NID_ecdsa_with_SHA1, NID_sha1, 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}, + // The following algorithms use more complex (or simpler) parameters. The + // digest "undef" indicates the caller should handle this explicitly. + {NID_rsassaPss, NID_undef, NID_rsaEncryption}, + {NID_ED25519, NID_undef, NID_ED25519}, +}; + +int OBJ_find_sigid_algs(int sign_nid, int *out_digest_nid, int *out_pkey_nid) { + for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kTriples); i++) { + if (kTriples[i].sign_nid == sign_nid) { + if (out_digest_nid != NULL) { + *out_digest_nid = kTriples[i].digest_nid; + } + if (out_pkey_nid != NULL) { + *out_pkey_nid = kTriples[i].pkey_nid; + } + return 1; + } + } + + return 0; +} + +int OBJ_find_sigid_by_algs(int *out_sign_nid, int digest_nid, int pkey_nid) { + for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kTriples); i++) { + if (kTriples[i].digest_nid == digest_nid && + kTriples[i].pkey_nid == pkey_nid) { + if (out_sign_nid != NULL) { + *out_sign_nid = kTriples[i].sign_nid; + } + return 1; + } + } + + return 0; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/obj/obj_xref.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/obj/obj_xref.c.grpc_back new file mode 100644 index 0000000..21bde27 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/obj/obj_xref.c.grpc_back @@ -0,0 +1,122 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + +#include "../internal.h" + + +typedef struct { + int sign_nid; + int digest_nid; + int pkey_nid; +} nid_triple; + +static const nid_triple kTriples[] = { + // RSA PKCS#1. + {NID_md4WithRSAEncryption, NID_md4, NID_rsaEncryption}, + {NID_md5WithRSAEncryption, NID_md5, NID_rsaEncryption}, + {NID_sha1WithRSAEncryption, NID_sha1, NID_rsaEncryption}, + {NID_sha224WithRSAEncryption, NID_sha224, NID_rsaEncryption}, + {NID_sha256WithRSAEncryption, NID_sha256, NID_rsaEncryption}, + {NID_sha384WithRSAEncryption, NID_sha384, NID_rsaEncryption}, + {NID_sha512WithRSAEncryption, NID_sha512, NID_rsaEncryption}, + // DSA. + {NID_dsaWithSHA1, NID_sha1, NID_dsa}, + {NID_dsaWithSHA1_2, NID_sha1, NID_dsa_2}, + {NID_dsa_with_SHA224, NID_sha224, NID_dsa}, + {NID_dsa_with_SHA256, NID_sha256, NID_dsa}, + // ECDSA. + {NID_ecdsa_with_SHA1, NID_sha1, 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}, + // The following algorithms use more complex (or simpler) parameters. The + // digest "undef" indicates the caller should handle this explicitly. + {NID_rsassaPss, NID_undef, NID_rsaEncryption}, + {NID_ED25519, NID_undef, NID_ED25519}, +}; + +int OBJ_find_sigid_algs(int sign_nid, int *out_digest_nid, int *out_pkey_nid) { + for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kTriples); i++) { + if (kTriples[i].sign_nid == sign_nid) { + if (out_digest_nid != NULL) { + *out_digest_nid = kTriples[i].digest_nid; + } + if (out_pkey_nid != NULL) { + *out_pkey_nid = kTriples[i].pkey_nid; + } + return 1; + } + } + + return 0; +} + +int OBJ_find_sigid_by_algs(int *out_sign_nid, int digest_nid, int pkey_nid) { + for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kTriples); i++) { + if (kTriples[i].digest_nid == digest_nid && + kTriples[i].pkey_nid == pkey_nid) { + if (out_sign_nid != NULL) { + *out_sign_nid = kTriples[i].sign_nid; + } + return 1; + } + } + + return 0; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/pem/pem_all.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/pem/pem_all.c new file mode 100644 index 0000000..bf79a3f --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/pem/pem_all.c @@ -0,0 +1,262 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 +#include +#include +#include +#include +/* + * #include + */ +#include +#include + +static RSA *pkey_get_rsa(EVP_PKEY *key, RSA **rsa); +static DSA *pkey_get_dsa(EVP_PKEY *key, DSA **dsa); +static EC_KEY *pkey_get_eckey(EVP_PKEY *key, EC_KEY **eckey); + +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) + +/* + * 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 + +IMPLEMENT_PEM_write_cb_const(RSAPrivateKey, RSA, PEM_STRING_RSA, + RSAPrivateKey) + + +IMPLEMENT_PEM_rw_const(RSAPublicKey, RSA, PEM_STRING_RSA_PUBLIC, + RSAPublicKey) IMPLEMENT_PEM_rw(RSA_PUBKEY, RSA, + PEM_STRING_PUBLIC, + RSA_PUBKEY) +#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 */ +} + +IMPLEMENT_PEM_write_cb_const(DSAPrivateKey, DSA, PEM_STRING_DSA, + DSAPrivateKey) + + 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 +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_write_cb(ECPrivateKey, EC_KEY, PEM_STRING_ECPRIVATEKEY, + ECPrivateKey) + + 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 + +IMPLEMENT_PEM_write_const(DHparams, DH, PEM_STRING_DHPARAMS, DHparams) + + IMPLEMENT_PEM_rw(PUBKEY, EVP_PKEY, PEM_STRING_PUBLIC, PUBKEY) diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/pem/pem_all.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/pem/pem_all.c.grpc_back new file mode 100644 index 0000000..e94ff26 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/pem/pem_all.c.grpc_back @@ -0,0 +1,262 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 +#include +#include +#include +#include +/* + * #include + */ +#include +#include + +static RSA *pkey_get_rsa(EVP_PKEY *key, RSA **rsa); +static DSA *pkey_get_dsa(EVP_PKEY *key, DSA **dsa); +static EC_KEY *pkey_get_eckey(EVP_PKEY *key, EC_KEY **eckey); + +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) + +/* + * 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 + +IMPLEMENT_PEM_write_cb_const(RSAPrivateKey, RSA, PEM_STRING_RSA, + RSAPrivateKey) + + +IMPLEMENT_PEM_rw_const(RSAPublicKey, RSA, PEM_STRING_RSA_PUBLIC, + RSAPublicKey) IMPLEMENT_PEM_rw(RSA_PUBKEY, RSA, + PEM_STRING_PUBLIC, + RSA_PUBKEY) +#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 */ +} + +IMPLEMENT_PEM_write_cb_const(DSAPrivateKey, DSA, PEM_STRING_DSA, + DSAPrivateKey) + + 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 +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_write_cb(ECPrivateKey, EC_KEY, PEM_STRING_ECPRIVATEKEY, + ECPrivateKey) + + 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 + +IMPLEMENT_PEM_write_const(DHparams, DH, PEM_STRING_DHPARAMS, DHparams) + + IMPLEMENT_PEM_rw(PUBKEY, EVP_PKEY, PEM_STRING_PUBLIC, PUBKEY) diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/pem/pem_info.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/pem/pem_info.c new file mode 100644 index 0000000..1a306a8 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/pem/pem_info.c @@ -0,0 +1,379 @@ +/* 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 +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#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) { + OPENSSL_PUT_ERROR(PEM, 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) { + OPENSSL_PUT_ERROR(PEM, 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 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(); + ptype = EVP_PKEY_RSA; + pp = &xi->x_pkey->dec_pkey; + if ((int)strlen(header) > 10) /* assume encrypted */ + raw = 1; + } else +#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(); + ptype = EVP_PKEY_DSA; + pp = &xi->x_pkey->dec_pkey; + if ((int)strlen(header) > 10) /* assume encrypted */ + raw = 1; + } else +#endif + 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(); + ptype = EVP_PKEY_EC; + pp = &xi->x_pkey->dec_pkey; + if ((int)strlen(header) > 10) /* assume encrypted */ + raw = 1; + } else { + 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)) { + OPENSSL_PUT_ERROR(PEM, ERR_R_ASN1_LIB); + goto err; + } + } else if (d2i(pp, &p, len) == NULL) { + OPENSSL_PUT_ERROR(PEM, 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; 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) +{ + int i, ret = 0; + unsigned char *data = NULL; + const char *objstr = NULL; + char buf[PEM_BUFSIZE]; + unsigned char *iv = NULL; + unsigned iv_len = 0; + + if (enc != NULL) { + iv_len = EVP_CIPHER_iv_length(enc); + objstr = OBJ_nid2sn(EVP_CIPHER_nid(enc)); + if (objstr == NULL) { + OPENSSL_PUT_ERROR(PEM, 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) { + OPENSSL_PUT_ERROR(PEM, 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) { + OPENSSL_PUT_ERROR(PEM, PEM_R_UNSUPPORTED_CIPHER); + goto err; + } + + /* create the right magic header stuff */ + assert(strlen(objstr) + 23 + 2 * iv_len + 13 <= sizeof buf); + buf[0] = '\0'; + PEM_proc_type(buf, PEM_TYPE_ENCRYPTED); + PEM_dek_info(buf, objstr, 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 */ + /* 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; + } + } + + /* 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(buf, PEM_BUFSIZE); + return ret; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/pem/pem_info.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/pem/pem_info.c.grpc_back new file mode 100644 index 0000000..d707e42 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/pem/pem_info.c.grpc_back @@ -0,0 +1,379 @@ +/* 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 +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#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) { + OPENSSL_PUT_ERROR(PEM, 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) { + OPENSSL_PUT_ERROR(PEM, 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 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(); + ptype = EVP_PKEY_RSA; + pp = &xi->x_pkey->dec_pkey; + if ((int)strlen(header) > 10) /* assume encrypted */ + raw = 1; + } else +#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(); + ptype = EVP_PKEY_DSA; + pp = &xi->x_pkey->dec_pkey; + if ((int)strlen(header) > 10) /* assume encrypted */ + raw = 1; + } else +#endif + 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(); + ptype = EVP_PKEY_EC; + pp = &xi->x_pkey->dec_pkey; + if ((int)strlen(header) > 10) /* assume encrypted */ + raw = 1; + } else { + 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)) { + OPENSSL_PUT_ERROR(PEM, ERR_R_ASN1_LIB); + goto err; + } + } else if (d2i(pp, &p, len) == NULL) { + OPENSSL_PUT_ERROR(PEM, 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; 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) +{ + int i, ret = 0; + unsigned char *data = NULL; + const char *objstr = NULL; + char buf[PEM_BUFSIZE]; + unsigned char *iv = NULL; + unsigned iv_len = 0; + + if (enc != NULL) { + iv_len = EVP_CIPHER_iv_length(enc); + objstr = OBJ_nid2sn(EVP_CIPHER_nid(enc)); + if (objstr == NULL) { + OPENSSL_PUT_ERROR(PEM, 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) { + OPENSSL_PUT_ERROR(PEM, 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) { + OPENSSL_PUT_ERROR(PEM, PEM_R_UNSUPPORTED_CIPHER); + goto err; + } + + /* create the right magic header stuff */ + assert(strlen(objstr) + 23 + 2 * iv_len + 13 <= sizeof buf); + buf[0] = '\0'; + PEM_proc_type(buf, PEM_TYPE_ENCRYPTED); + PEM_dek_info(buf, objstr, 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 */ + /* 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; + } + } + + /* 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(buf, PEM_BUFSIZE); + return ret; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/pem/pem_lib.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/pem/pem_lib.c new file mode 100644 index 0000000..c21676a --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/pem/pem_lib.c @@ -0,0 +1,776 @@ +/* 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 +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../internal.h" + + +#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); + +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) { + OPENSSL_PUT_ERROR(PEM, 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)) { + return !strcmp(nm, PEM_STRING_PKCS8) || + !strcmp(nm, PEM_STRING_PKCS8INF) || + !strcmp(nm, PEM_STRING_RSA) || + !strcmp(nm, PEM_STRING_EC) || + !strcmp(nm, PEM_STRING_DSA); + } + + /* 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) { + OPENSSL_PUT_ERROR(PEM, 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) { + OPENSSL_PUT_ERROR(PEM, PEM_R_UNSUPPORTED_CIPHER); + goto err; + } + } + + if ((dsize = i2d(x, NULL)) < 0) { + OPENSSL_PUT_ERROR(PEM, 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) { + OPENSSL_PUT_ERROR(PEM, ERR_R_MALLOC_FAILURE); + goto err; + } + p = data; + i = i2d(x, &p); + + if (enc != NULL) { + const unsigned iv_len = EVP_CIPHER_iv_length(enc); + + if (kstr == NULL) { + klen = 0; + if (!callback) + callback = PEM_def_callback; + klen = (*callback) (buf, PEM_BUFSIZE, 1, u); + if (klen <= 0) { + OPENSSL_PUT_ERROR(PEM, PEM_R_READ_KEY); + goto err; + } + kstr = (unsigned char *)buf; + } + assert(iv_len <= (int)sizeof(iv)); + if (!RAND_bytes(iv, iv_len)) /* 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); + + assert(strlen(objstr) + 23 + 2 * iv_len + 13 <= sizeof buf); + + buf[0] = '\0'; + PEM_proc_type(buf, PEM_TYPE_ENCRYPTED); + PEM_dek_info(buf, objstr, 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; + else + i += j; + EVP_CIPHER_CTX_cleanup(&ctx); + if (ret == 0) + goto err; + } 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); + 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); + + klen = 0; + if (!callback) + callback = PEM_def_callback; + klen = callback(buf, PEM_BUFSIZE, 0, u); + if (klen <= 0) { + OPENSSL_PUT_ERROR(PEM, PEM_R_BAD_PASSWORD_READ); + return (0); + } + + 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) { + OPENSSL_PUT_ERROR(PEM, PEM_R_BAD_DECRYPT); + return (0); + } + j += i; + *plen = j; + return (1); +} + +static const EVP_CIPHER *cipher_by_name(const char *name) +{ + /* This is similar to the (deprecated) function |EVP_get_cipherbyname|. */ + if (0 == strcmp(name, SN_rc4)) { + return EVP_rc4(); + } else if (0 == strcmp(name, SN_des_cbc)) { + return EVP_des_cbc(); + } else if (0 == strcmp(name, SN_des_ede3_cbc)) { + return EVP_des_ede3_cbc(); + } else if (0 == strcmp(name, SN_aes_128_cbc)) { + return EVP_aes_128_cbc(); + } else if (0 == strcmp(name, SN_aes_192_cbc)) { + return EVP_aes_192_cbc(); + } else if (0 == strcmp(name, SN_aes_256_cbc)) { + return EVP_aes_256_cbc(); + } else { + return NULL; + } +} + +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; + if ((header == NULL) || (*header == '\0') || (*header == '\n')) + return (1); + if (strncmp(header, "Proc-Type: ", 11) != 0) { + OPENSSL_PUT_ERROR(PEM, 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) { + OPENSSL_PUT_ERROR(PEM, PEM_R_NOT_ENCRYPTED); + return (0); + } + for (; (*header != '\n') && (*header != '\0'); header++) ; + if (*header == '\0') { + OPENSSL_PUT_ERROR(PEM, PEM_R_SHORT_HEADER); + return (0); + } + header++; + if (strncmp(header, "DEK-Info: ", 10) != 0) { + OPENSSL_PUT_ERROR(PEM, PEM_R_NOT_DEK_INFO); + return (0); + } + header += 10; + + p = header; + for (;;) { + c = *header; + if (!(((c >= 'A') && (c <= 'Z')) || (c == '-') || + ((c >= '0') && (c <= '9')))) + break; + header++; + } + *header = '\0'; + cipher->cipher = enc = cipher_by_name(p); + *header = c; + header++; + + if (enc == NULL) { + OPENSSL_PUT_ERROR(PEM, PEM_R_UNSUPPORTED_ENCRYPTION); + return (0); + } + if (!load_iv(header_pp, &(cipher->iv[0]), EVP_CIPHER_iv_length(enc))) + 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 { + OPENSSL_PUT_ERROR(PEM, 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) { + OPENSSL_PUT_ERROR(PEM, 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_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_free(buf); + } + OPENSSL_PUT_ERROR(PEM, 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) { + OPENSSL_PUT_ERROR(PEM, 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); + OPENSSL_PUT_ERROR(PEM, ERR_R_MALLOC_FAILURE); + return (0); + } + + buf[254] = '\0'; + for (;;) { + i = BIO_gets(bp, buf, 254); + + if (i <= 0) { + OPENSSL_PUT_ERROR(PEM, 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)) { + OPENSSL_PUT_ERROR(PEM, ERR_R_MALLOC_FAILURE); + goto err; + } + OPENSSL_memcpy(nameB->data, &(buf[11]), i - 6); + nameB->data[i - 6] = '\0'; + break; + } + } + hl = 0; + if (!BUF_MEM_grow(headerB, 256)) { + OPENSSL_PUT_ERROR(PEM, 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)) { + OPENSSL_PUT_ERROR(PEM, ERR_R_MALLOC_FAILURE); + goto err; + } + if (strncmp(buf, "-----END ", 9) == 0) { + nohead = 1; + break; + } + OPENSSL_memcpy(&(headerB->data[hl]), buf, i); + headerB->data[hl + i] = '\0'; + hl += i; + } + + bl = 0; + if (!BUF_MEM_grow(dataB, 1024)) { + OPENSSL_PUT_ERROR(PEM, 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)) { + OPENSSL_PUT_ERROR(PEM, ERR_R_MALLOC_FAILURE); + goto err; + } + OPENSSL_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)) { + OPENSSL_PUT_ERROR(PEM, 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) { + OPENSSL_PUT_ERROR(PEM, PEM_R_BAD_BASE64_DECODE); + goto err; + } + i = EVP_DecodeFinal(&ctx, (unsigned char *)&(dataB->data[bl]), &k); + if (i < 0) { + OPENSSL_PUT_ERROR(PEM, 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); +} + +int PEM_def_callback(char *buf, int size, int rwflag, void *userdata) +{ + if (!buf || !userdata || size < 0) { + return 0; + } + size_t len = strlen((char *)userdata); + if (len >= (size_t)size) { + return 0; + } + BUF_strlcpy(buf, userdata, (size_t)size); + return len; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/pem/pem_lib.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/pem/pem_lib.c.grpc_back new file mode 100644 index 0000000..8f89096 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/pem/pem_lib.c.grpc_back @@ -0,0 +1,776 @@ +/* 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 +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../internal.h" + + +#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); + +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) { + OPENSSL_PUT_ERROR(PEM, 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)) { + return !strcmp(nm, PEM_STRING_PKCS8) || + !strcmp(nm, PEM_STRING_PKCS8INF) || + !strcmp(nm, PEM_STRING_RSA) || + !strcmp(nm, PEM_STRING_EC) || + !strcmp(nm, PEM_STRING_DSA); + } + + /* 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) { + OPENSSL_PUT_ERROR(PEM, 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) { + OPENSSL_PUT_ERROR(PEM, PEM_R_UNSUPPORTED_CIPHER); + goto err; + } + } + + if ((dsize = i2d(x, NULL)) < 0) { + OPENSSL_PUT_ERROR(PEM, 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) { + OPENSSL_PUT_ERROR(PEM, ERR_R_MALLOC_FAILURE); + goto err; + } + p = data; + i = i2d(x, &p); + + if (enc != NULL) { + const unsigned iv_len = EVP_CIPHER_iv_length(enc); + + if (kstr == NULL) { + klen = 0; + if (!callback) + callback = PEM_def_callback; + klen = (*callback) (buf, PEM_BUFSIZE, 1, u); + if (klen <= 0) { + OPENSSL_PUT_ERROR(PEM, PEM_R_READ_KEY); + goto err; + } + kstr = (unsigned char *)buf; + } + assert(iv_len <= (int)sizeof(iv)); + if (!RAND_bytes(iv, iv_len)) /* 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); + + assert(strlen(objstr) + 23 + 2 * iv_len + 13 <= sizeof buf); + + buf[0] = '\0'; + PEM_proc_type(buf, PEM_TYPE_ENCRYPTED); + PEM_dek_info(buf, objstr, 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; + else + i += j; + EVP_CIPHER_CTX_cleanup(&ctx); + if (ret == 0) + goto err; + } 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); + 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); + + klen = 0; + if (!callback) + callback = PEM_def_callback; + klen = callback(buf, PEM_BUFSIZE, 0, u); + if (klen <= 0) { + OPENSSL_PUT_ERROR(PEM, PEM_R_BAD_PASSWORD_READ); + return (0); + } + + 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) { + OPENSSL_PUT_ERROR(PEM, PEM_R_BAD_DECRYPT); + return (0); + } + j += i; + *plen = j; + return (1); +} + +static const EVP_CIPHER *cipher_by_name(const char *name) +{ + /* This is similar to the (deprecated) function |EVP_get_cipherbyname|. */ + if (0 == strcmp(name, SN_rc4)) { + return EVP_rc4(); + } else if (0 == strcmp(name, SN_des_cbc)) { + return EVP_des_cbc(); + } else if (0 == strcmp(name, SN_des_ede3_cbc)) { + return EVP_des_ede3_cbc(); + } else if (0 == strcmp(name, SN_aes_128_cbc)) { + return EVP_aes_128_cbc(); + } else if (0 == strcmp(name, SN_aes_192_cbc)) { + return EVP_aes_192_cbc(); + } else if (0 == strcmp(name, SN_aes_256_cbc)) { + return EVP_aes_256_cbc(); + } else { + return NULL; + } +} + +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; + if ((header == NULL) || (*header == '\0') || (*header == '\n')) + return (1); + if (strncmp(header, "Proc-Type: ", 11) != 0) { + OPENSSL_PUT_ERROR(PEM, 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) { + OPENSSL_PUT_ERROR(PEM, PEM_R_NOT_ENCRYPTED); + return (0); + } + for (; (*header != '\n') && (*header != '\0'); header++) ; + if (*header == '\0') { + OPENSSL_PUT_ERROR(PEM, PEM_R_SHORT_HEADER); + return (0); + } + header++; + if (strncmp(header, "DEK-Info: ", 10) != 0) { + OPENSSL_PUT_ERROR(PEM, PEM_R_NOT_DEK_INFO); + return (0); + } + header += 10; + + p = header; + for (;;) { + c = *header; + if (!(((c >= 'A') && (c <= 'Z')) || (c == '-') || + ((c >= '0') && (c <= '9')))) + break; + header++; + } + *header = '\0'; + cipher->cipher = enc = cipher_by_name(p); + *header = c; + header++; + + if (enc == NULL) { + OPENSSL_PUT_ERROR(PEM, PEM_R_UNSUPPORTED_ENCRYPTION); + return (0); + } + if (!load_iv(header_pp, &(cipher->iv[0]), EVP_CIPHER_iv_length(enc))) + 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 { + OPENSSL_PUT_ERROR(PEM, 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) { + OPENSSL_PUT_ERROR(PEM, 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_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_free(buf); + } + OPENSSL_PUT_ERROR(PEM, 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) { + OPENSSL_PUT_ERROR(PEM, 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); + OPENSSL_PUT_ERROR(PEM, ERR_R_MALLOC_FAILURE); + return (0); + } + + buf[254] = '\0'; + for (;;) { + i = BIO_gets(bp, buf, 254); + + if (i <= 0) { + OPENSSL_PUT_ERROR(PEM, 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)) { + OPENSSL_PUT_ERROR(PEM, ERR_R_MALLOC_FAILURE); + goto err; + } + OPENSSL_memcpy(nameB->data, &(buf[11]), i - 6); + nameB->data[i - 6] = '\0'; + break; + } + } + hl = 0; + if (!BUF_MEM_grow(headerB, 256)) { + OPENSSL_PUT_ERROR(PEM, 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)) { + OPENSSL_PUT_ERROR(PEM, ERR_R_MALLOC_FAILURE); + goto err; + } + if (strncmp(buf, "-----END ", 9) == 0) { + nohead = 1; + break; + } + OPENSSL_memcpy(&(headerB->data[hl]), buf, i); + headerB->data[hl + i] = '\0'; + hl += i; + } + + bl = 0; + if (!BUF_MEM_grow(dataB, 1024)) { + OPENSSL_PUT_ERROR(PEM, 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)) { + OPENSSL_PUT_ERROR(PEM, ERR_R_MALLOC_FAILURE); + goto err; + } + OPENSSL_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)) { + OPENSSL_PUT_ERROR(PEM, 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) { + OPENSSL_PUT_ERROR(PEM, PEM_R_BAD_BASE64_DECODE); + goto err; + } + i = EVP_DecodeFinal(&ctx, (unsigned char *)&(dataB->data[bl]), &k); + if (i < 0) { + OPENSSL_PUT_ERROR(PEM, 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); +} + +int PEM_def_callback(char *buf, int size, int rwflag, void *userdata) +{ + if (!buf || !userdata || size < 0) { + return 0; + } + size_t len = strlen((char *)userdata); + if (len >= (size_t)size) { + return 0; + } + BUF_strlcpy(buf, userdata, (size_t)size); + return len; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/pem/pem_oth.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/pem/pem_oth.c new file mode 100644 index 0000000..ad79855 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/pem/pem_oth.c @@ -0,0 +1,88 @@ +/* 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 + +#include +#include +#include +#include +#include +#include +#include + +/* 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) + OPENSSL_PUT_ERROR(PEM, ERR_R_ASN1_LIB); + OPENSSL_free(data); + return ret; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/pem/pem_oth.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/pem/pem_oth.c.grpc_back new file mode 100644 index 0000000..8530c56 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/pem/pem_oth.c.grpc_back @@ -0,0 +1,88 @@ +/* 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 + +#include +#include +#include +#include +#include +#include +#include + +/* 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) + OPENSSL_PUT_ERROR(PEM, ERR_R_ASN1_LIB); + OPENSSL_free(data); + return ret; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/pem/pem_pk8.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/pem/pem_pk8.c new file mode 100644 index 0000000..533edba --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/pem/pem_pk8.c @@ -0,0 +1,258 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 +#include +#include +#include +#include + +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))) { + OPENSSL_PUT_ERROR(PEM, PEM_R_ERROR_CONVERTING_PRIVATE_KEY); + return 0; + } + if (enc || (nid != -1)) { + if (!kstr) { + klen = 0; + if (!cb) + cb = PEM_def_callback; + klen = cb(buf, PEM_BUFSIZE, 1, u); + if (klen <= 0) { + OPENSSL_PUT_ERROR(PEM, 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 (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; + + klen = 0; + if (!cb) + cb = PEM_def_callback; + klen = cb(psbuf, PEM_BUFSIZE, 0, u); + if (klen <= 0) { + OPENSSL_PUT_ERROR(PEM, 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))) { + OPENSSL_PUT_ERROR(PEM, 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))) { + OPENSSL_PUT_ERROR(PEM, 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) diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/pem/pem_pk8.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/pem/pem_pk8.c.grpc_back new file mode 100644 index 0000000..15385ec --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/pem/pem_pk8.c.grpc_back @@ -0,0 +1,258 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 +#include +#include +#include +#include + +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))) { + OPENSSL_PUT_ERROR(PEM, PEM_R_ERROR_CONVERTING_PRIVATE_KEY); + return 0; + } + if (enc || (nid != -1)) { + if (!kstr) { + klen = 0; + if (!cb) + cb = PEM_def_callback; + klen = cb(buf, PEM_BUFSIZE, 1, u); + if (klen <= 0) { + OPENSSL_PUT_ERROR(PEM, 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 (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; + + klen = 0; + if (!cb) + cb = PEM_def_callback; + klen = cb(psbuf, PEM_BUFSIZE, 0, u); + if (klen <= 0) { + OPENSSL_PUT_ERROR(PEM, 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))) { + OPENSSL_PUT_ERROR(PEM, 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))) { + OPENSSL_PUT_ERROR(PEM, 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) diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/pem/pem_pkey.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/pem/pem_pkey.c new file mode 100644 index 0000000..a6d1815 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/pem/pem_pkey.c @@ -0,0 +1,227 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 +#include +#include +#include +#include +#include +#include +#include + +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; + 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; + + klen = 0; + if (!cb) + cb = PEM_def_callback; + klen = cb(psbuf, PEM_BUFSIZE, 0, u); + if (klen <= 0) { + OPENSSL_PUT_ERROR(PEM, 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 (strcmp(nm, PEM_STRING_RSA) == 0) { + /* TODO(davidben): d2i_PrivateKey parses PKCS#8 along with the + * standalone format. This and the cases below probably should not + * accept PKCS#8. */ + ret = d2i_PrivateKey(EVP_PKEY_RSA, x, &p, len); + } else if (strcmp(nm, PEM_STRING_EC) == 0) { + ret = d2i_PrivateKey(EVP_PKEY_EC, x, &p, len); + } else if (strcmp(nm, PEM_STRING_DSA) == 0) { + ret = d2i_PrivateKey(EVP_PKEY_DSA, x, &p, len); + } + p8err: + if (ret == NULL) + OPENSSL_PUT_ERROR(PEM, ERR_R_ASN1_LIB); + + err: + OPENSSL_free(nm); + 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) +{ + return PEM_write_bio_PKCS8PrivateKey(bp, x, enc, (char *)kstr, klen, cb, u); +} + +#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) { + OPENSSL_PUT_ERROR(PEM, 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) { + OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB); + return 0; + } + ret = PEM_write_bio_PrivateKey(b, x, enc, kstr, klen, cb, u); + BIO_free(b); + return ret; +} + +#endif + +/* 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; + + ret = d2i_DHparams(x, &p, len); + + if (ret == NULL) + OPENSSL_PUT_ERROR(PEM, 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) { + OPENSSL_PUT_ERROR(PEM, 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 diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/pem/pem_pkey.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/pem/pem_pkey.c.grpc_back new file mode 100644 index 0000000..9fbaeef --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/pem/pem_pkey.c.grpc_back @@ -0,0 +1,227 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 +#include +#include +#include +#include +#include +#include +#include + +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; + 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; + + klen = 0; + if (!cb) + cb = PEM_def_callback; + klen = cb(psbuf, PEM_BUFSIZE, 0, u); + if (klen <= 0) { + OPENSSL_PUT_ERROR(PEM, 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 (strcmp(nm, PEM_STRING_RSA) == 0) { + /* TODO(davidben): d2i_PrivateKey parses PKCS#8 along with the + * standalone format. This and the cases below probably should not + * accept PKCS#8. */ + ret = d2i_PrivateKey(EVP_PKEY_RSA, x, &p, len); + } else if (strcmp(nm, PEM_STRING_EC) == 0) { + ret = d2i_PrivateKey(EVP_PKEY_EC, x, &p, len); + } else if (strcmp(nm, PEM_STRING_DSA) == 0) { + ret = d2i_PrivateKey(EVP_PKEY_DSA, x, &p, len); + } + p8err: + if (ret == NULL) + OPENSSL_PUT_ERROR(PEM, ERR_R_ASN1_LIB); + + err: + OPENSSL_free(nm); + 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) +{ + return PEM_write_bio_PKCS8PrivateKey(bp, x, enc, (char *)kstr, klen, cb, u); +} + +#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) { + OPENSSL_PUT_ERROR(PEM, 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) { + OPENSSL_PUT_ERROR(PEM, ERR_R_BUF_LIB); + return 0; + } + ret = PEM_write_bio_PrivateKey(b, x, enc, kstr, klen, cb, u); + BIO_free(b); + return ret; +} + +#endif + +/* 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; + + ret = d2i_DHparams(x, &p, len); + + if (ret == NULL) + OPENSSL_PUT_ERROR(PEM, 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) { + OPENSSL_PUT_ERROR(PEM, 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 diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/pem/pem_x509.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/pem/pem_x509.c new file mode 100644 index 0000000..0d9b3be --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/pem/pem_x509.c @@ -0,0 +1,65 @@ +/* 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 +#include +#include +#include + +IMPLEMENT_PEM_rw(X509, X509, PEM_STRING_X509, X509) diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/pem/pem_x509.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/pem/pem_x509.c.grpc_back new file mode 100644 index 0000000..97f814d --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/pem/pem_x509.c.grpc_back @@ -0,0 +1,65 @@ +/* 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 +#include +#include +#include + +IMPLEMENT_PEM_rw(X509, X509, PEM_STRING_X509, X509) diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/pem/pem_xaux.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/pem/pem_xaux.c new file mode 100644 index 0000000..86dbe0c --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/pem/pem_xaux.c @@ -0,0 +1,65 @@ +/* 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 +#include +#include +#include + +IMPLEMENT_PEM_rw(X509_AUX, X509, PEM_STRING_X509_TRUSTED, X509_AUX) diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/pem/pem_xaux.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/pem/pem_xaux.c.grpc_back new file mode 100644 index 0000000..b0cceca --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/pem/pem_xaux.c.grpc_back @@ -0,0 +1,65 @@ +/* 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 +#include +#include +#include + +IMPLEMENT_PEM_rw(X509_AUX, X509, PEM_STRING_X509_TRUSTED, X509_AUX) diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/pkcs7/internal.h b/FoodApp/Pods/BoringSSL-GRPC/crypto/pkcs7/internal.h new file mode 100644 index 0000000..538d249 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/pkcs7/internal.h @@ -0,0 +1,49 @@ +/* Copyright (c) 2017, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_PKCS7_INTERNAL_H +#define OPENSSL_HEADER_PKCS7_INTERNAL_H + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// pkcs7_parse_header reads the non-certificate/non-CRL prefix of a PKCS#7 +// SignedData blob from |cbs| and sets |*out| to point to the rest of the +// input. If the input is in BER format, then |*der_bytes| will be set to a +// pointer that needs to be freed by the caller once they have finished +// processing |*out| (which will be pointing into |*der_bytes|). +// +// It returns one on success or zero on error. On error, |*der_bytes| is +// NULL. +int pkcs7_parse_header(uint8_t **der_bytes, CBS *out, CBS *cbs); + +// pkcs7_bundle writes a PKCS#7, SignedData structure to |out| and then calls +// |cb| with a CBB to which certificate or CRL data can be written, and the +// opaque context pointer, |arg|. The callback can return zero to indicate an +// error. +// +// pkcs7_bundle returns one on success or zero on error. +int pkcs7_bundle(CBB *out, int (*cb)(CBB *out, const void *arg), + const void *arg); + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_PKCS7_INTERNAL_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/pkcs7/internal.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/pkcs7/internal.h.grpc_back new file mode 100644 index 0000000..9541bea --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/pkcs7/internal.h.grpc_back @@ -0,0 +1,49 @@ +/* Copyright (c) 2017, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_PKCS7_INTERNAL_H +#define OPENSSL_HEADER_PKCS7_INTERNAL_H + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// pkcs7_parse_header reads the non-certificate/non-CRL prefix of a PKCS#7 +// SignedData blob from |cbs| and sets |*out| to point to the rest of the +// input. If the input is in BER format, then |*der_bytes| will be set to a +// pointer that needs to be freed by the caller once they have finished +// processing |*out| (which will be pointing into |*der_bytes|). +// +// It returns one on success or zero on error. On error, |*der_bytes| is +// NULL. +int pkcs7_parse_header(uint8_t **der_bytes, CBS *out, CBS *cbs); + +// pkcs7_bundle writes a PKCS#7, SignedData structure to |out| and then calls +// |cb| with a CBB to which certificate or CRL data can be written, and the +// opaque context pointer, |arg|. The callback can return zero to indicate an +// error. +// +// pkcs7_bundle returns one on success or zero on error. +int pkcs7_bundle(CBB *out, int (*cb)(CBB *out, const void *arg), + const void *arg); + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_PKCS7_INTERNAL_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/pkcs7/pkcs7.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/pkcs7/pkcs7.c new file mode 100644 index 0000000..f9714bd --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/pkcs7/pkcs7.c @@ -0,0 +1,166 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include +#include +#include +#include +#include + +#include "internal.h" +#include "../bytestring/internal.h" + + +// 1.2.840.113549.1.7.1 +static const uint8_t kPKCS7Data[] = {0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x07, 0x01}; + +// 1.2.840.113549.1.7.2 +static const uint8_t kPKCS7SignedData[] = {0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x07, 0x02}; + +// pkcs7_parse_header reads the non-certificate/non-CRL prefix of a PKCS#7 +// SignedData blob from |cbs| and sets |*out| to point to the rest of the +// input. If the input is in BER format, then |*der_bytes| will be set to a +// pointer that needs to be freed by the caller once they have finished +// processing |*out| (which will be pointing into |*der_bytes|). +// +// It returns one on success or zero on error. On error, |*der_bytes| is +// NULL. +int pkcs7_parse_header(uint8_t **der_bytes, CBS *out, CBS *cbs) { + size_t der_len; + CBS in, content_info, content_type, wrapped_signed_data, signed_data; + uint64_t version; + + // The input may be in BER format. + *der_bytes = NULL; + if (!CBS_asn1_ber_to_der(cbs, der_bytes, &der_len)) { + return 0; + } + if (*der_bytes != NULL) { + CBS_init(&in, *der_bytes, der_len); + } else { + CBS_init(&in, CBS_data(cbs), CBS_len(cbs)); + } + + // See https://tools.ietf.org/html/rfc2315#section-7 + if (!CBS_get_asn1(&in, &content_info, CBS_ASN1_SEQUENCE) || + !CBS_get_asn1(&content_info, &content_type, CBS_ASN1_OBJECT)) { + goto err; + } + + if (!CBS_mem_equal(&content_type, kPKCS7SignedData, + sizeof(kPKCS7SignedData))) { + OPENSSL_PUT_ERROR(PKCS7, PKCS7_R_NOT_PKCS7_SIGNED_DATA); + goto err; + } + + // See https://tools.ietf.org/html/rfc2315#section-9.1 + if (!CBS_get_asn1(&content_info, &wrapped_signed_data, + CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0) || + !CBS_get_asn1(&wrapped_signed_data, &signed_data, CBS_ASN1_SEQUENCE) || + !CBS_get_asn1_uint64(&signed_data, &version) || + !CBS_get_asn1(&signed_data, NULL /* digests */, CBS_ASN1_SET) || + !CBS_get_asn1(&signed_data, NULL /* content */, CBS_ASN1_SEQUENCE)) { + goto err; + } + + if (version < 1) { + OPENSSL_PUT_ERROR(PKCS7, PKCS7_R_BAD_PKCS7_VERSION); + goto err; + } + + CBS_init(out, CBS_data(&signed_data), CBS_len(&signed_data)); + return 1; + +err: + OPENSSL_free(*der_bytes); + *der_bytes = NULL; + return 0; +} + +int PKCS7_get_raw_certificates(STACK_OF(CRYPTO_BUFFER) *out_certs, CBS *cbs, + CRYPTO_BUFFER_POOL *pool) { + CBS signed_data, certificates; + uint8_t *der_bytes = NULL; + int ret = 0; + const size_t initial_certs_len = sk_CRYPTO_BUFFER_num(out_certs); + + if (!pkcs7_parse_header(&der_bytes, &signed_data, cbs)) { + return 0; + } + + // See https://tools.ietf.org/html/rfc2315#section-9.1 + if (!CBS_get_asn1(&signed_data, &certificates, + CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0)) { + OPENSSL_PUT_ERROR(PKCS7, PKCS7_R_NO_CERTIFICATES_INCLUDED); + goto err; + } + + while (CBS_len(&certificates) > 0) { + CBS cert; + if (!CBS_get_asn1_element(&certificates, &cert, CBS_ASN1_SEQUENCE)) { + goto err; + } + + CRYPTO_BUFFER *buf = CRYPTO_BUFFER_new_from_CBS(&cert, pool); + if (buf == NULL || + !sk_CRYPTO_BUFFER_push(out_certs, buf)) { + CRYPTO_BUFFER_free(buf); + goto err; + } + } + + ret = 1; + +err: + OPENSSL_free(der_bytes); + + if (!ret) { + while (sk_CRYPTO_BUFFER_num(out_certs) != initial_certs_len) { + CRYPTO_BUFFER *buf = sk_CRYPTO_BUFFER_pop(out_certs); + CRYPTO_BUFFER_free(buf); + } + } + + return ret; +} + +int pkcs7_bundle(CBB *out, int (*cb)(CBB *out, const void *arg), + const void *arg) { + CBB outer_seq, oid, wrapped_seq, seq, version_bytes, digest_algos_set, + content_info; + + // See https://tools.ietf.org/html/rfc2315#section-7 + if (!CBB_add_asn1(out, &outer_seq, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1(&outer_seq, &oid, CBS_ASN1_OBJECT) || + !CBB_add_bytes(&oid, kPKCS7SignedData, sizeof(kPKCS7SignedData)) || + !CBB_add_asn1(&outer_seq, &wrapped_seq, + CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0) || + // See https://tools.ietf.org/html/rfc2315#section-9.1 + !CBB_add_asn1(&wrapped_seq, &seq, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1(&seq, &version_bytes, CBS_ASN1_INTEGER) || + !CBB_add_u8(&version_bytes, 1) || + !CBB_add_asn1(&seq, &digest_algos_set, CBS_ASN1_SET) || + !CBB_add_asn1(&seq, &content_info, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1(&content_info, &oid, CBS_ASN1_OBJECT) || + !CBB_add_bytes(&oid, kPKCS7Data, sizeof(kPKCS7Data)) || + !cb(&seq, arg)) { + return 0; + } + + return CBB_flush(out); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/pkcs7/pkcs7.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/pkcs7/pkcs7.c.grpc_back new file mode 100644 index 0000000..fc175a9 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/pkcs7/pkcs7.c.grpc_back @@ -0,0 +1,166 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include +#include +#include +#include +#include + +#include "internal.h" +#include "../bytestring/internal.h" + + +// 1.2.840.113549.1.7.1 +static const uint8_t kPKCS7Data[] = {0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x07, 0x01}; + +// 1.2.840.113549.1.7.2 +static const uint8_t kPKCS7SignedData[] = {0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x07, 0x02}; + +// pkcs7_parse_header reads the non-certificate/non-CRL prefix of a PKCS#7 +// SignedData blob from |cbs| and sets |*out| to point to the rest of the +// input. If the input is in BER format, then |*der_bytes| will be set to a +// pointer that needs to be freed by the caller once they have finished +// processing |*out| (which will be pointing into |*der_bytes|). +// +// It returns one on success or zero on error. On error, |*der_bytes| is +// NULL. +int pkcs7_parse_header(uint8_t **der_bytes, CBS *out, CBS *cbs) { + size_t der_len; + CBS in, content_info, content_type, wrapped_signed_data, signed_data; + uint64_t version; + + // The input may be in BER format. + *der_bytes = NULL; + if (!CBS_asn1_ber_to_der(cbs, der_bytes, &der_len)) { + return 0; + } + if (*der_bytes != NULL) { + CBS_init(&in, *der_bytes, der_len); + } else { + CBS_init(&in, CBS_data(cbs), CBS_len(cbs)); + } + + // See https://tools.ietf.org/html/rfc2315#section-7 + if (!CBS_get_asn1(&in, &content_info, CBS_ASN1_SEQUENCE) || + !CBS_get_asn1(&content_info, &content_type, CBS_ASN1_OBJECT)) { + goto err; + } + + if (!CBS_mem_equal(&content_type, kPKCS7SignedData, + sizeof(kPKCS7SignedData))) { + OPENSSL_PUT_ERROR(PKCS7, PKCS7_R_NOT_PKCS7_SIGNED_DATA); + goto err; + } + + // See https://tools.ietf.org/html/rfc2315#section-9.1 + if (!CBS_get_asn1(&content_info, &wrapped_signed_data, + CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0) || + !CBS_get_asn1(&wrapped_signed_data, &signed_data, CBS_ASN1_SEQUENCE) || + !CBS_get_asn1_uint64(&signed_data, &version) || + !CBS_get_asn1(&signed_data, NULL /* digests */, CBS_ASN1_SET) || + !CBS_get_asn1(&signed_data, NULL /* content */, CBS_ASN1_SEQUENCE)) { + goto err; + } + + if (version < 1) { + OPENSSL_PUT_ERROR(PKCS7, PKCS7_R_BAD_PKCS7_VERSION); + goto err; + } + + CBS_init(out, CBS_data(&signed_data), CBS_len(&signed_data)); + return 1; + +err: + OPENSSL_free(*der_bytes); + *der_bytes = NULL; + return 0; +} + +int PKCS7_get_raw_certificates(STACK_OF(CRYPTO_BUFFER) *out_certs, CBS *cbs, + CRYPTO_BUFFER_POOL *pool) { + CBS signed_data, certificates; + uint8_t *der_bytes = NULL; + int ret = 0; + const size_t initial_certs_len = sk_CRYPTO_BUFFER_num(out_certs); + + if (!pkcs7_parse_header(&der_bytes, &signed_data, cbs)) { + return 0; + } + + // See https://tools.ietf.org/html/rfc2315#section-9.1 + if (!CBS_get_asn1(&signed_data, &certificates, + CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0)) { + OPENSSL_PUT_ERROR(PKCS7, PKCS7_R_NO_CERTIFICATES_INCLUDED); + goto err; + } + + while (CBS_len(&certificates) > 0) { + CBS cert; + if (!CBS_get_asn1_element(&certificates, &cert, CBS_ASN1_SEQUENCE)) { + goto err; + } + + CRYPTO_BUFFER *buf = CRYPTO_BUFFER_new_from_CBS(&cert, pool); + if (buf == NULL || + !sk_CRYPTO_BUFFER_push(out_certs, buf)) { + CRYPTO_BUFFER_free(buf); + goto err; + } + } + + ret = 1; + +err: + OPENSSL_free(der_bytes); + + if (!ret) { + while (sk_CRYPTO_BUFFER_num(out_certs) != initial_certs_len) { + CRYPTO_BUFFER *buf = sk_CRYPTO_BUFFER_pop(out_certs); + CRYPTO_BUFFER_free(buf); + } + } + + return ret; +} + +int pkcs7_bundle(CBB *out, int (*cb)(CBB *out, const void *arg), + const void *arg) { + CBB outer_seq, oid, wrapped_seq, seq, version_bytes, digest_algos_set, + content_info; + + // See https://tools.ietf.org/html/rfc2315#section-7 + if (!CBB_add_asn1(out, &outer_seq, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1(&outer_seq, &oid, CBS_ASN1_OBJECT) || + !CBB_add_bytes(&oid, kPKCS7SignedData, sizeof(kPKCS7SignedData)) || + !CBB_add_asn1(&outer_seq, &wrapped_seq, + CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0) || + // See https://tools.ietf.org/html/rfc2315#section-9.1 + !CBB_add_asn1(&wrapped_seq, &seq, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1(&seq, &version_bytes, CBS_ASN1_INTEGER) || + !CBB_add_u8(&version_bytes, 1) || + !CBB_add_asn1(&seq, &digest_algos_set, CBS_ASN1_SET) || + !CBB_add_asn1(&seq, &content_info, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1(&content_info, &oid, CBS_ASN1_OBJECT) || + !CBB_add_bytes(&oid, kPKCS7Data, sizeof(kPKCS7Data)) || + !cb(&seq, arg)) { + return 0; + } + + return CBB_flush(out); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/pkcs7/pkcs7_x509.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/pkcs7/pkcs7_x509.c new file mode 100644 index 0000000..bcc8da2 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/pkcs7/pkcs7_x509.c @@ -0,0 +1,233 @@ +/* Copyright (c) 2017, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "internal.h" + + +int PKCS7_get_certificates(STACK_OF(X509) *out_certs, CBS *cbs) { + int ret = 0; + const size_t initial_certs_len = sk_X509_num(out_certs); + STACK_OF(CRYPTO_BUFFER) *raw = sk_CRYPTO_BUFFER_new_null(); + if (raw == NULL || + !PKCS7_get_raw_certificates(raw, cbs, NULL)) { + goto err; + } + + for (size_t i = 0; i < sk_CRYPTO_BUFFER_num(raw); i++) { + CRYPTO_BUFFER *buf = sk_CRYPTO_BUFFER_value(raw, i); + X509 *x509 = X509_parse_from_buffer(buf); + if (x509 == NULL || + !sk_X509_push(out_certs, x509)) { + X509_free(x509); + goto err; + } + } + + ret = 1; + +err: + sk_CRYPTO_BUFFER_pop_free(raw, CRYPTO_BUFFER_free); + if (!ret) { + while (sk_X509_num(out_certs) != initial_certs_len) { + X509 *x509 = sk_X509_pop(out_certs); + X509_free(x509); + } + } + + return ret; +} + +int PKCS7_get_CRLs(STACK_OF(X509_CRL) *out_crls, CBS *cbs) { + CBS signed_data, crls; + uint8_t *der_bytes = NULL; + int ret = 0; + const size_t initial_crls_len = sk_X509_CRL_num(out_crls); + + if (!pkcs7_parse_header(&der_bytes, &signed_data, cbs)) { + return 0; + } + + // See https://tools.ietf.org/html/rfc2315#section-9.1 + + // Even if only CRLs are included, there may be an empty certificates block. + // OpenSSL does this, for example. + if (CBS_peek_asn1_tag(&signed_data, + CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0) && + !CBS_get_asn1(&signed_data, NULL /* certificates */, + CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0)) { + goto err; + } + + if (!CBS_get_asn1(&signed_data, &crls, + CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 1)) { + OPENSSL_PUT_ERROR(PKCS7, PKCS7_R_NO_CRLS_INCLUDED); + goto err; + } + + while (CBS_len(&crls) > 0) { + CBS crl_data; + X509_CRL *crl; + const uint8_t *inp; + + if (!CBS_get_asn1_element(&crls, &crl_data, CBS_ASN1_SEQUENCE)) { + goto err; + } + + if (CBS_len(&crl_data) > LONG_MAX) { + goto err; + } + inp = CBS_data(&crl_data); + crl = d2i_X509_CRL(NULL, &inp, (long)CBS_len(&crl_data)); + if (!crl) { + goto err; + } + + assert(inp == CBS_data(&crl_data) + CBS_len(&crl_data)); + + if (sk_X509_CRL_push(out_crls, crl) == 0) { + X509_CRL_free(crl); + goto err; + } + } + + ret = 1; + +err: + OPENSSL_free(der_bytes); + + if (!ret) { + while (sk_X509_CRL_num(out_crls) != initial_crls_len) { + X509_CRL_free(sk_X509_CRL_pop(out_crls)); + } + } + + return ret; +} + +int PKCS7_get_PEM_certificates(STACK_OF(X509) *out_certs, BIO *pem_bio) { + uint8_t *data; + long len; + int ret; + + // Even though we pass PEM_STRING_PKCS7 as the expected PEM type here, PEM + // internally will actually allow several other values too, including + // "CERTIFICATE". + if (!PEM_bytes_read_bio(&data, &len, NULL /* PEM type output */, + PEM_STRING_PKCS7, pem_bio, + NULL /* password callback */, + NULL /* password callback argument */)) { + return 0; + } + + CBS cbs; + CBS_init(&cbs, data, len); + ret = PKCS7_get_certificates(out_certs, &cbs); + OPENSSL_free(data); + return ret; +} + +int PKCS7_get_PEM_CRLs(STACK_OF(X509_CRL) *out_crls, BIO *pem_bio) { + uint8_t *data; + long len; + int ret; + + // Even though we pass PEM_STRING_PKCS7 as the expected PEM type here, PEM + // internally will actually allow several other values too, including + // "CERTIFICATE". + if (!PEM_bytes_read_bio(&data, &len, NULL /* PEM type output */, + PEM_STRING_PKCS7, pem_bio, + NULL /* password callback */, + NULL /* password callback argument */)) { + return 0; + } + + CBS cbs; + CBS_init(&cbs, data, len); + ret = PKCS7_get_CRLs(out_crls, &cbs); + OPENSSL_free(data); + return ret; +} + +static int pkcs7_bundle_certificates_cb(CBB *out, const void *arg) { + const STACK_OF(X509) *certs = arg; + size_t i; + CBB certificates; + + // See https://tools.ietf.org/html/rfc2315#section-9.1 + if (!CBB_add_asn1(out, &certificates, + CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0)) { + return 0; + } + + for (i = 0; i < sk_X509_num(certs); i++) { + X509 *x509 = sk_X509_value(certs, i); + uint8_t *buf; + int len = i2d_X509(x509, NULL); + + if (len < 0 || + !CBB_add_space(&certificates, &buf, len) || + i2d_X509(x509, &buf) < 0) { + return 0; + } + } + + return CBB_flush(out); +} + +int PKCS7_bundle_certificates(CBB *out, const STACK_OF(X509) *certs) { + return pkcs7_bundle(out, pkcs7_bundle_certificates_cb, certs); +} + +static int pkcs7_bundle_crls_cb(CBB *out, const void *arg) { + const STACK_OF(X509_CRL) *crls = arg; + size_t i; + CBB crl_data; + + // See https://tools.ietf.org/html/rfc2315#section-9.1 + if (!CBB_add_asn1(out, &crl_data, + CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 1)) { + return 0; + } + + for (i = 0; i < sk_X509_CRL_num(crls); i++) { + X509_CRL *crl = sk_X509_CRL_value(crls, i); + uint8_t *buf; + int len = i2d_X509_CRL(crl, NULL); + + if (len < 0 || + !CBB_add_space(&crl_data, &buf, len) || + i2d_X509_CRL(crl, &buf) < 0) { + return 0; + } + } + + return CBB_flush(out); +} + +int PKCS7_bundle_CRLs(CBB *out, const STACK_OF(X509_CRL) *crls) { + return pkcs7_bundle(out, pkcs7_bundle_crls_cb, crls); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/pkcs7/pkcs7_x509.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/pkcs7/pkcs7_x509.c.grpc_back new file mode 100644 index 0000000..7bc39d2 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/pkcs7/pkcs7_x509.c.grpc_back @@ -0,0 +1,233 @@ +/* Copyright (c) 2017, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "internal.h" + + +int PKCS7_get_certificates(STACK_OF(X509) *out_certs, CBS *cbs) { + int ret = 0; + const size_t initial_certs_len = sk_X509_num(out_certs); + STACK_OF(CRYPTO_BUFFER) *raw = sk_CRYPTO_BUFFER_new_null(); + if (raw == NULL || + !PKCS7_get_raw_certificates(raw, cbs, NULL)) { + goto err; + } + + for (size_t i = 0; i < sk_CRYPTO_BUFFER_num(raw); i++) { + CRYPTO_BUFFER *buf = sk_CRYPTO_BUFFER_value(raw, i); + X509 *x509 = X509_parse_from_buffer(buf); + if (x509 == NULL || + !sk_X509_push(out_certs, x509)) { + X509_free(x509); + goto err; + } + } + + ret = 1; + +err: + sk_CRYPTO_BUFFER_pop_free(raw, CRYPTO_BUFFER_free); + if (!ret) { + while (sk_X509_num(out_certs) != initial_certs_len) { + X509 *x509 = sk_X509_pop(out_certs); + X509_free(x509); + } + } + + return ret; +} + +int PKCS7_get_CRLs(STACK_OF(X509_CRL) *out_crls, CBS *cbs) { + CBS signed_data, crls; + uint8_t *der_bytes = NULL; + int ret = 0; + const size_t initial_crls_len = sk_X509_CRL_num(out_crls); + + if (!pkcs7_parse_header(&der_bytes, &signed_data, cbs)) { + return 0; + } + + // See https://tools.ietf.org/html/rfc2315#section-9.1 + + // Even if only CRLs are included, there may be an empty certificates block. + // OpenSSL does this, for example. + if (CBS_peek_asn1_tag(&signed_data, + CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0) && + !CBS_get_asn1(&signed_data, NULL /* certificates */, + CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0)) { + goto err; + } + + if (!CBS_get_asn1(&signed_data, &crls, + CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 1)) { + OPENSSL_PUT_ERROR(PKCS7, PKCS7_R_NO_CRLS_INCLUDED); + goto err; + } + + while (CBS_len(&crls) > 0) { + CBS crl_data; + X509_CRL *crl; + const uint8_t *inp; + + if (!CBS_get_asn1_element(&crls, &crl_data, CBS_ASN1_SEQUENCE)) { + goto err; + } + + if (CBS_len(&crl_data) > LONG_MAX) { + goto err; + } + inp = CBS_data(&crl_data); + crl = d2i_X509_CRL(NULL, &inp, (long)CBS_len(&crl_data)); + if (!crl) { + goto err; + } + + assert(inp == CBS_data(&crl_data) + CBS_len(&crl_data)); + + if (sk_X509_CRL_push(out_crls, crl) == 0) { + X509_CRL_free(crl); + goto err; + } + } + + ret = 1; + +err: + OPENSSL_free(der_bytes); + + if (!ret) { + while (sk_X509_CRL_num(out_crls) != initial_crls_len) { + X509_CRL_free(sk_X509_CRL_pop(out_crls)); + } + } + + return ret; +} + +int PKCS7_get_PEM_certificates(STACK_OF(X509) *out_certs, BIO *pem_bio) { + uint8_t *data; + long len; + int ret; + + // Even though we pass PEM_STRING_PKCS7 as the expected PEM type here, PEM + // internally will actually allow several other values too, including + // "CERTIFICATE". + if (!PEM_bytes_read_bio(&data, &len, NULL /* PEM type output */, + PEM_STRING_PKCS7, pem_bio, + NULL /* password callback */, + NULL /* password callback argument */)) { + return 0; + } + + CBS cbs; + CBS_init(&cbs, data, len); + ret = PKCS7_get_certificates(out_certs, &cbs); + OPENSSL_free(data); + return ret; +} + +int PKCS7_get_PEM_CRLs(STACK_OF(X509_CRL) *out_crls, BIO *pem_bio) { + uint8_t *data; + long len; + int ret; + + // Even though we pass PEM_STRING_PKCS7 as the expected PEM type here, PEM + // internally will actually allow several other values too, including + // "CERTIFICATE". + if (!PEM_bytes_read_bio(&data, &len, NULL /* PEM type output */, + PEM_STRING_PKCS7, pem_bio, + NULL /* password callback */, + NULL /* password callback argument */)) { + return 0; + } + + CBS cbs; + CBS_init(&cbs, data, len); + ret = PKCS7_get_CRLs(out_crls, &cbs); + OPENSSL_free(data); + return ret; +} + +static int pkcs7_bundle_certificates_cb(CBB *out, const void *arg) { + const STACK_OF(X509) *certs = arg; + size_t i; + CBB certificates; + + // See https://tools.ietf.org/html/rfc2315#section-9.1 + if (!CBB_add_asn1(out, &certificates, + CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0)) { + return 0; + } + + for (i = 0; i < sk_X509_num(certs); i++) { + X509 *x509 = sk_X509_value(certs, i); + uint8_t *buf; + int len = i2d_X509(x509, NULL); + + if (len < 0 || + !CBB_add_space(&certificates, &buf, len) || + i2d_X509(x509, &buf) < 0) { + return 0; + } + } + + return CBB_flush(out); +} + +int PKCS7_bundle_certificates(CBB *out, const STACK_OF(X509) *certs) { + return pkcs7_bundle(out, pkcs7_bundle_certificates_cb, certs); +} + +static int pkcs7_bundle_crls_cb(CBB *out, const void *arg) { + const STACK_OF(X509_CRL) *crls = arg; + size_t i; + CBB crl_data; + + // See https://tools.ietf.org/html/rfc2315#section-9.1 + if (!CBB_add_asn1(out, &crl_data, + CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 1)) { + return 0; + } + + for (i = 0; i < sk_X509_CRL_num(crls); i++) { + X509_CRL *crl = sk_X509_CRL_value(crls, i); + uint8_t *buf; + int len = i2d_X509_CRL(crl, NULL); + + if (len < 0 || + !CBB_add_space(&crl_data, &buf, len) || + i2d_X509_CRL(crl, &buf) < 0) { + return 0; + } + } + + return CBB_flush(out); +} + +int PKCS7_bundle_CRLs(CBB *out, const STACK_OF(X509_CRL) *crls) { + return pkcs7_bundle(out, pkcs7_bundle_crls_cb, crls); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/pkcs8/internal.h b/FoodApp/Pods/BoringSSL-GRPC/crypto/pkcs8/internal.h new file mode 100644 index 0000000..7ac57f7 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/pkcs8/internal.h @@ -0,0 +1,120 @@ +/* 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_HEADER_PKCS8_INTERNAL_H +#define OPENSSL_HEADER_PKCS8_INTERNAL_H + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// pkcs8_pbe_decrypt decrypts |in| using the PBE scheme described by +// |algorithm|, which should be a serialized AlgorithmIdentifier structure. On +// success, it sets |*out| to a newly-allocated buffer containing the decrypted +// result and returns one. Otherwise, it returns zero. +int pkcs8_pbe_decrypt(uint8_t **out, size_t *out_len, CBS *algorithm, + const char *pass, size_t pass_len, const uint8_t *in, + size_t in_len); + +#define PKCS12_KEY_ID 1 +#define PKCS12_IV_ID 2 +#define PKCS12_MAC_ID 3 + +// pkcs12_key_gen runs the PKCS#12 key derivation function as specified in +// RFC 7292, appendix B. On success, it writes the resulting |out_len| bytes of +// key material to |out| and returns one. Otherwise, it returns zero. |id| +// should be one of the |PKCS12_*_ID| values. +int pkcs12_key_gen(const char *pass, size_t pass_len, const uint8_t *salt, + size_t salt_len, uint8_t id, unsigned iterations, + size_t out_len, uint8_t *out, const EVP_MD *md); + +struct pbe_suite { + int pbe_nid; + uint8_t oid[10]; + uint8_t oid_len; + const EVP_CIPHER *(*cipher_func)(void); + const EVP_MD *(*md_func)(void); + // decrypt_init initialize |ctx| for decrypting. The password is specified by + // |pass| and |pass_len|. |param| contains the serialized parameters field of + // the AlgorithmIdentifier. + // + // It returns one on success and zero on error. + int (*decrypt_init)(const struct pbe_suite *suite, EVP_CIPHER_CTX *ctx, + const char *pass, size_t pass_len, CBS *param); +}; + +#define PKCS5_DEFAULT_ITERATIONS 2048 +#define PKCS5_SALT_LEN 8 + +int PKCS5_pbe2_decrypt_init(const struct pbe_suite *suite, EVP_CIPHER_CTX *ctx, + const char *pass, size_t pass_len, CBS *param); + +// PKCS5_pbe2_encrypt_init configures |ctx| for encrypting with PKCS #5 PBES2, +// as defined in RFC 2998, with the specified parameters. It writes the +// corresponding AlgorithmIdentifier to |out|. +int PKCS5_pbe2_encrypt_init(CBB *out, EVP_CIPHER_CTX *ctx, + const EVP_CIPHER *cipher, unsigned iterations, + const char *pass, size_t pass_len, + const uint8_t *salt, size_t salt_len); + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_PKCS8_INTERNAL_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/pkcs8/internal.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/pkcs8/internal.h.grpc_back new file mode 100644 index 0000000..9399489 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/pkcs8/internal.h.grpc_back @@ -0,0 +1,120 @@ +/* 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_HEADER_PKCS8_INTERNAL_H +#define OPENSSL_HEADER_PKCS8_INTERNAL_H + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// pkcs8_pbe_decrypt decrypts |in| using the PBE scheme described by +// |algorithm|, which should be a serialized AlgorithmIdentifier structure. On +// success, it sets |*out| to a newly-allocated buffer containing the decrypted +// result and returns one. Otherwise, it returns zero. +int pkcs8_pbe_decrypt(uint8_t **out, size_t *out_len, CBS *algorithm, + const char *pass, size_t pass_len, const uint8_t *in, + size_t in_len); + +#define PKCS12_KEY_ID 1 +#define PKCS12_IV_ID 2 +#define PKCS12_MAC_ID 3 + +// pkcs12_key_gen runs the PKCS#12 key derivation function as specified in +// RFC 7292, appendix B. On success, it writes the resulting |out_len| bytes of +// key material to |out| and returns one. Otherwise, it returns zero. |id| +// should be one of the |PKCS12_*_ID| values. +int pkcs12_key_gen(const char *pass, size_t pass_len, const uint8_t *salt, + size_t salt_len, uint8_t id, unsigned iterations, + size_t out_len, uint8_t *out, const EVP_MD *md); + +struct pbe_suite { + int pbe_nid; + uint8_t oid[10]; + uint8_t oid_len; + const EVP_CIPHER *(*cipher_func)(void); + const EVP_MD *(*md_func)(void); + // decrypt_init initialize |ctx| for decrypting. The password is specified by + // |pass| and |pass_len|. |param| contains the serialized parameters field of + // the AlgorithmIdentifier. + // + // It returns one on success and zero on error. + int (*decrypt_init)(const struct pbe_suite *suite, EVP_CIPHER_CTX *ctx, + const char *pass, size_t pass_len, CBS *param); +}; + +#define PKCS5_DEFAULT_ITERATIONS 2048 +#define PKCS5_SALT_LEN 8 + +int PKCS5_pbe2_decrypt_init(const struct pbe_suite *suite, EVP_CIPHER_CTX *ctx, + const char *pass, size_t pass_len, CBS *param); + +// PKCS5_pbe2_encrypt_init configures |ctx| for encrypting with PKCS #5 PBES2, +// as defined in RFC 2998, with the specified parameters. It writes the +// corresponding AlgorithmIdentifier to |out|. +int PKCS5_pbe2_encrypt_init(CBB *out, EVP_CIPHER_CTX *ctx, + const EVP_CIPHER *cipher, unsigned iterations, + const char *pass, size_t pass_len, + const uint8_t *salt, size_t salt_len); + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_PKCS8_INTERNAL_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/pkcs8/p5_pbev2.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/pkcs8/p5_pbev2.c new file mode 100644 index 0000000..9f59abb --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/pkcs8/p5_pbev2.c @@ -0,0 +1,307 @@ +/* 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 +#include + +#include +#include +#include +#include +#include +#include + +#include "internal.h" +#include "../internal.h" + + +// 1.2.840.113549.1.5.12 +static const uint8_t kPBKDF2[] = {0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x05, 0x0c}; + +// 1.2.840.113549.1.5.13 +static const uint8_t kPBES2[] = {0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x05, 0x0d}; + +// 1.2.840.113549.2.7 +static const uint8_t kHMACWithSHA1[] = {0x2a, 0x86, 0x48, 0x86, + 0xf7, 0x0d, 0x02, 0x07}; + +static const struct { + uint8_t oid[9]; + uint8_t oid_len; + int nid; + const EVP_CIPHER *(*cipher_func)(void); +} kCipherOIDs[] = { + // 1.2.840.113549.3.2 + {{0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x03, 0x02}, + 8, + NID_rc2_cbc, + &EVP_rc2_cbc}, + // 1.2.840.113549.3.7 + {{0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x03, 0x07}, + 8, + NID_des_ede3_cbc, + &EVP_des_ede3_cbc}, + // 2.16.840.1.101.3.4.1.2 + {{0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x02}, + 9, + NID_aes_128_cbc, + &EVP_aes_128_cbc}, + // 2.16.840.1.101.3.4.1.22 + {{0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x16}, + 9, + NID_aes_192_cbc, + &EVP_aes_192_cbc}, + // 2.16.840.1.101.3.4.1.42 + {{0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x2a}, + 9, + NID_aes_256_cbc, + &EVP_aes_256_cbc}, +}; + +static const EVP_CIPHER *cbs_to_cipher(const CBS *cbs) { + for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kCipherOIDs); i++) { + if (CBS_mem_equal(cbs, kCipherOIDs[i].oid, kCipherOIDs[i].oid_len)) { + return kCipherOIDs[i].cipher_func(); + } + } + + return NULL; +} + +static int add_cipher_oid(CBB *out, int nid) { + for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kCipherOIDs); i++) { + if (kCipherOIDs[i].nid == nid) { + CBB child; + return CBB_add_asn1(out, &child, CBS_ASN1_OBJECT) && + CBB_add_bytes(&child, kCipherOIDs[i].oid, + kCipherOIDs[i].oid_len) && + CBB_flush(out); + } + } + + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_UNSUPPORTED_CIPHER); + return 0; +} + +static int pkcs5_pbe2_cipher_init(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + unsigned iterations, const char *pass, + size_t pass_len, const uint8_t *salt, + size_t salt_len, const uint8_t *iv, + size_t iv_len, int enc) { + if (iv_len != EVP_CIPHER_iv_length(cipher)) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_ERROR_SETTING_CIPHER_PARAMS); + return 0; + } + + uint8_t key[EVP_MAX_KEY_LENGTH]; + int ret = PKCS5_PBKDF2_HMAC_SHA1(pass, pass_len, salt, salt_len, iterations, + EVP_CIPHER_key_length(cipher), key) && + EVP_CipherInit_ex(ctx, cipher, NULL /* engine */, key, iv, enc); + OPENSSL_cleanse(key, EVP_MAX_KEY_LENGTH); + return ret; +} + +int PKCS5_pbe2_encrypt_init(CBB *out, EVP_CIPHER_CTX *ctx, + const EVP_CIPHER *cipher, unsigned iterations, + const char *pass, size_t pass_len, + const uint8_t *salt, size_t salt_len) { + int cipher_nid = EVP_CIPHER_nid(cipher); + if (cipher_nid == NID_undef) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER); + return 0; + } + + // Generate a random IV. + uint8_t iv[EVP_MAX_IV_LENGTH]; + if (!RAND_bytes(iv, EVP_CIPHER_iv_length(cipher))) { + return 0; + } + + // See RFC 2898, appendix A. + CBB algorithm, oid, param, kdf, kdf_oid, kdf_param, salt_cbb, cipher_cbb, + iv_cbb; + if (!CBB_add_asn1(out, &algorithm, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) || + !CBB_add_bytes(&oid, kPBES2, sizeof(kPBES2)) || + !CBB_add_asn1(&algorithm, ¶m, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1(¶m, &kdf, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1(&kdf, &kdf_oid, CBS_ASN1_OBJECT) || + !CBB_add_bytes(&kdf_oid, kPBKDF2, sizeof(kPBKDF2)) || + !CBB_add_asn1(&kdf, &kdf_param, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1(&kdf_param, &salt_cbb, CBS_ASN1_OCTETSTRING) || + !CBB_add_bytes(&salt_cbb, salt, salt_len) || + !CBB_add_asn1_uint64(&kdf_param, iterations) || + // Specify a key length for RC2. + (cipher_nid == NID_rc2_cbc && + !CBB_add_asn1_uint64(&kdf_param, EVP_CIPHER_key_length(cipher))) || + // Omit the PRF. We use the default hmacWithSHA1. + !CBB_add_asn1(¶m, &cipher_cbb, CBS_ASN1_SEQUENCE) || + !add_cipher_oid(&cipher_cbb, cipher_nid) || + // RFC 2898 says RC2-CBC and RC5-CBC-Pad use a SEQUENCE with version and + // IV, but OpenSSL always uses an OCTET STRING IV, so we do the same. + !CBB_add_asn1(&cipher_cbb, &iv_cbb, CBS_ASN1_OCTETSTRING) || + !CBB_add_bytes(&iv_cbb, iv, EVP_CIPHER_iv_length(cipher)) || + !CBB_flush(out)) { + return 0; + } + + return pkcs5_pbe2_cipher_init(ctx, cipher, iterations, pass, pass_len, salt, + salt_len, iv, EVP_CIPHER_iv_length(cipher), + 1 /* encrypt */); +} + +int PKCS5_pbe2_decrypt_init(const struct pbe_suite *suite, EVP_CIPHER_CTX *ctx, + const char *pass, size_t pass_len, CBS *param) { + CBS pbe_param, kdf, kdf_obj, enc_scheme, enc_obj; + if (!CBS_get_asn1(param, &pbe_param, CBS_ASN1_SEQUENCE) || + CBS_len(param) != 0 || + !CBS_get_asn1(&pbe_param, &kdf, CBS_ASN1_SEQUENCE) || + !CBS_get_asn1(&pbe_param, &enc_scheme, CBS_ASN1_SEQUENCE) || + CBS_len(&pbe_param) != 0 || + !CBS_get_asn1(&kdf, &kdf_obj, CBS_ASN1_OBJECT) || + !CBS_get_asn1(&enc_scheme, &enc_obj, CBS_ASN1_OBJECT)) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_DECODE_ERROR); + return 0; + } + + // Only PBKDF2 is supported. + if (!CBS_mem_equal(&kdf_obj, kPBKDF2, sizeof(kPBKDF2))) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION); + return 0; + } + + // See if we recognise the encryption algorithm. + const EVP_CIPHER *cipher = cbs_to_cipher(&enc_obj); + if (cipher == NULL) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_UNSUPPORTED_CIPHER); + return 0; + } + + // Parse the KDF parameters. See RFC 8018, appendix A.2. + CBS pbkdf2_params, salt; + uint64_t iterations; + if (!CBS_get_asn1(&kdf, &pbkdf2_params, CBS_ASN1_SEQUENCE) || + CBS_len(&kdf) != 0 || + !CBS_get_asn1(&pbkdf2_params, &salt, CBS_ASN1_OCTETSTRING) || + !CBS_get_asn1_uint64(&pbkdf2_params, &iterations)) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_DECODE_ERROR); + return 0; + } + + if (iterations == 0 || iterations > UINT_MAX) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_ITERATION_COUNT); + return 0; + } + + // The optional keyLength parameter, if present, must match the key length of + // the cipher. + if (CBS_peek_asn1_tag(&pbkdf2_params, CBS_ASN1_INTEGER)) { + uint64_t key_len; + if (!CBS_get_asn1_uint64(&pbkdf2_params, &key_len)) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_DECODE_ERROR); + return 0; + } + + if (key_len != EVP_CIPHER_key_length(cipher)) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_UNSUPPORTED_KEYLENGTH); + return 0; + } + } + + if (CBS_len(&pbkdf2_params) != 0) { + CBS alg_id, prf; + if (!CBS_get_asn1(&pbkdf2_params, &alg_id, CBS_ASN1_SEQUENCE) || + !CBS_get_asn1(&alg_id, &prf, CBS_ASN1_OBJECT) || + CBS_len(&pbkdf2_params) != 0) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_DECODE_ERROR); + return 0; + } + + // We only support hmacWithSHA1. It is the DEFAULT, so DER requires it be + // omitted, but we match OpenSSL in tolerating it being present. + if (!CBS_mem_equal(&prf, kHMACWithSHA1, sizeof(kHMACWithSHA1))) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_UNSUPPORTED_PRF); + return 0; + } + + // hmacWithSHA1 has a NULL parameter. + CBS null; + if (!CBS_get_asn1(&alg_id, &null, CBS_ASN1_NULL) || + CBS_len(&null) != 0 || + CBS_len(&alg_id) != 0) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_DECODE_ERROR); + return 0; + } + } + + // Parse the encryption scheme parameters. Note OpenSSL does not match the + // specification. Per RFC 2898, this should depend on the encryption scheme. + // In particular, RC2-CBC uses a SEQUENCE with version and IV. We align with + // OpenSSL. + CBS iv; + if (!CBS_get_asn1(&enc_scheme, &iv, CBS_ASN1_OCTETSTRING) || + CBS_len(&enc_scheme) != 0) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_UNSUPPORTED_PRF); + return 0; + } + + return pkcs5_pbe2_cipher_init(ctx, cipher, (unsigned)iterations, pass, + pass_len, CBS_data(&salt), CBS_len(&salt), + CBS_data(&iv), CBS_len(&iv), 0 /* decrypt */); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/pkcs8/p5_pbev2.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/pkcs8/p5_pbev2.c.grpc_back new file mode 100644 index 0000000..6686cf3 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/pkcs8/p5_pbev2.c.grpc_back @@ -0,0 +1,307 @@ +/* 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 +#include + +#include +#include +#include +#include +#include +#include + +#include "internal.h" +#include "../internal.h" + + +// 1.2.840.113549.1.5.12 +static const uint8_t kPBKDF2[] = {0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x05, 0x0c}; + +// 1.2.840.113549.1.5.13 +static const uint8_t kPBES2[] = {0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x05, 0x0d}; + +// 1.2.840.113549.2.7 +static const uint8_t kHMACWithSHA1[] = {0x2a, 0x86, 0x48, 0x86, + 0xf7, 0x0d, 0x02, 0x07}; + +static const struct { + uint8_t oid[9]; + uint8_t oid_len; + int nid; + const EVP_CIPHER *(*cipher_func)(void); +} kCipherOIDs[] = { + // 1.2.840.113549.3.2 + {{0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x03, 0x02}, + 8, + NID_rc2_cbc, + &EVP_rc2_cbc}, + // 1.2.840.113549.3.7 + {{0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x03, 0x07}, + 8, + NID_des_ede3_cbc, + &EVP_des_ede3_cbc}, + // 2.16.840.1.101.3.4.1.2 + {{0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x02}, + 9, + NID_aes_128_cbc, + &EVP_aes_128_cbc}, + // 2.16.840.1.101.3.4.1.22 + {{0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x16}, + 9, + NID_aes_192_cbc, + &EVP_aes_192_cbc}, + // 2.16.840.1.101.3.4.1.42 + {{0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x01, 0x2a}, + 9, + NID_aes_256_cbc, + &EVP_aes_256_cbc}, +}; + +static const EVP_CIPHER *cbs_to_cipher(const CBS *cbs) { + for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kCipherOIDs); i++) { + if (CBS_mem_equal(cbs, kCipherOIDs[i].oid, kCipherOIDs[i].oid_len)) { + return kCipherOIDs[i].cipher_func(); + } + } + + return NULL; +} + +static int add_cipher_oid(CBB *out, int nid) { + for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kCipherOIDs); i++) { + if (kCipherOIDs[i].nid == nid) { + CBB child; + return CBB_add_asn1(out, &child, CBS_ASN1_OBJECT) && + CBB_add_bytes(&child, kCipherOIDs[i].oid, + kCipherOIDs[i].oid_len) && + CBB_flush(out); + } + } + + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_UNSUPPORTED_CIPHER); + return 0; +} + +static int pkcs5_pbe2_cipher_init(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + unsigned iterations, const char *pass, + size_t pass_len, const uint8_t *salt, + size_t salt_len, const uint8_t *iv, + size_t iv_len, int enc) { + if (iv_len != EVP_CIPHER_iv_length(cipher)) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_ERROR_SETTING_CIPHER_PARAMS); + return 0; + } + + uint8_t key[EVP_MAX_KEY_LENGTH]; + int ret = PKCS5_PBKDF2_HMAC_SHA1(pass, pass_len, salt, salt_len, iterations, + EVP_CIPHER_key_length(cipher), key) && + EVP_CipherInit_ex(ctx, cipher, NULL /* engine */, key, iv, enc); + OPENSSL_cleanse(key, EVP_MAX_KEY_LENGTH); + return ret; +} + +int PKCS5_pbe2_encrypt_init(CBB *out, EVP_CIPHER_CTX *ctx, + const EVP_CIPHER *cipher, unsigned iterations, + const char *pass, size_t pass_len, + const uint8_t *salt, size_t salt_len) { + int cipher_nid = EVP_CIPHER_nid(cipher); + if (cipher_nid == NID_undef) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER); + return 0; + } + + // Generate a random IV. + uint8_t iv[EVP_MAX_IV_LENGTH]; + if (!RAND_bytes(iv, EVP_CIPHER_iv_length(cipher))) { + return 0; + } + + // See RFC 2898, appendix A. + CBB algorithm, oid, param, kdf, kdf_oid, kdf_param, salt_cbb, cipher_cbb, + iv_cbb; + if (!CBB_add_asn1(out, &algorithm, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) || + !CBB_add_bytes(&oid, kPBES2, sizeof(kPBES2)) || + !CBB_add_asn1(&algorithm, ¶m, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1(¶m, &kdf, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1(&kdf, &kdf_oid, CBS_ASN1_OBJECT) || + !CBB_add_bytes(&kdf_oid, kPBKDF2, sizeof(kPBKDF2)) || + !CBB_add_asn1(&kdf, &kdf_param, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1(&kdf_param, &salt_cbb, CBS_ASN1_OCTETSTRING) || + !CBB_add_bytes(&salt_cbb, salt, salt_len) || + !CBB_add_asn1_uint64(&kdf_param, iterations) || + // Specify a key length for RC2. + (cipher_nid == NID_rc2_cbc && + !CBB_add_asn1_uint64(&kdf_param, EVP_CIPHER_key_length(cipher))) || + // Omit the PRF. We use the default hmacWithSHA1. + !CBB_add_asn1(¶m, &cipher_cbb, CBS_ASN1_SEQUENCE) || + !add_cipher_oid(&cipher_cbb, cipher_nid) || + // RFC 2898 says RC2-CBC and RC5-CBC-Pad use a SEQUENCE with version and + // IV, but OpenSSL always uses an OCTET STRING IV, so we do the same. + !CBB_add_asn1(&cipher_cbb, &iv_cbb, CBS_ASN1_OCTETSTRING) || + !CBB_add_bytes(&iv_cbb, iv, EVP_CIPHER_iv_length(cipher)) || + !CBB_flush(out)) { + return 0; + } + + return pkcs5_pbe2_cipher_init(ctx, cipher, iterations, pass, pass_len, salt, + salt_len, iv, EVP_CIPHER_iv_length(cipher), + 1 /* encrypt */); +} + +int PKCS5_pbe2_decrypt_init(const struct pbe_suite *suite, EVP_CIPHER_CTX *ctx, + const char *pass, size_t pass_len, CBS *param) { + CBS pbe_param, kdf, kdf_obj, enc_scheme, enc_obj; + if (!CBS_get_asn1(param, &pbe_param, CBS_ASN1_SEQUENCE) || + CBS_len(param) != 0 || + !CBS_get_asn1(&pbe_param, &kdf, CBS_ASN1_SEQUENCE) || + !CBS_get_asn1(&pbe_param, &enc_scheme, CBS_ASN1_SEQUENCE) || + CBS_len(&pbe_param) != 0 || + !CBS_get_asn1(&kdf, &kdf_obj, CBS_ASN1_OBJECT) || + !CBS_get_asn1(&enc_scheme, &enc_obj, CBS_ASN1_OBJECT)) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_DECODE_ERROR); + return 0; + } + + // Only PBKDF2 is supported. + if (!CBS_mem_equal(&kdf_obj, kPBKDF2, sizeof(kPBKDF2))) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION); + return 0; + } + + // See if we recognise the encryption algorithm. + const EVP_CIPHER *cipher = cbs_to_cipher(&enc_obj); + if (cipher == NULL) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_UNSUPPORTED_CIPHER); + return 0; + } + + // Parse the KDF parameters. See RFC 8018, appendix A.2. + CBS pbkdf2_params, salt; + uint64_t iterations; + if (!CBS_get_asn1(&kdf, &pbkdf2_params, CBS_ASN1_SEQUENCE) || + CBS_len(&kdf) != 0 || + !CBS_get_asn1(&pbkdf2_params, &salt, CBS_ASN1_OCTETSTRING) || + !CBS_get_asn1_uint64(&pbkdf2_params, &iterations)) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_DECODE_ERROR); + return 0; + } + + if (iterations == 0 || iterations > UINT_MAX) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_ITERATION_COUNT); + return 0; + } + + // The optional keyLength parameter, if present, must match the key length of + // the cipher. + if (CBS_peek_asn1_tag(&pbkdf2_params, CBS_ASN1_INTEGER)) { + uint64_t key_len; + if (!CBS_get_asn1_uint64(&pbkdf2_params, &key_len)) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_DECODE_ERROR); + return 0; + } + + if (key_len != EVP_CIPHER_key_length(cipher)) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_UNSUPPORTED_KEYLENGTH); + return 0; + } + } + + if (CBS_len(&pbkdf2_params) != 0) { + CBS alg_id, prf; + if (!CBS_get_asn1(&pbkdf2_params, &alg_id, CBS_ASN1_SEQUENCE) || + !CBS_get_asn1(&alg_id, &prf, CBS_ASN1_OBJECT) || + CBS_len(&pbkdf2_params) != 0) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_DECODE_ERROR); + return 0; + } + + // We only support hmacWithSHA1. It is the DEFAULT, so DER requires it be + // omitted, but we match OpenSSL in tolerating it being present. + if (!CBS_mem_equal(&prf, kHMACWithSHA1, sizeof(kHMACWithSHA1))) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_UNSUPPORTED_PRF); + return 0; + } + + // hmacWithSHA1 has a NULL parameter. + CBS null; + if (!CBS_get_asn1(&alg_id, &null, CBS_ASN1_NULL) || + CBS_len(&null) != 0 || + CBS_len(&alg_id) != 0) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_DECODE_ERROR); + return 0; + } + } + + // Parse the encryption scheme parameters. Note OpenSSL does not match the + // specification. Per RFC 2898, this should depend on the encryption scheme. + // In particular, RC2-CBC uses a SEQUENCE with version and IV. We align with + // OpenSSL. + CBS iv; + if (!CBS_get_asn1(&enc_scheme, &iv, CBS_ASN1_OCTETSTRING) || + CBS_len(&enc_scheme) != 0) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_UNSUPPORTED_PRF); + return 0; + } + + return pkcs5_pbe2_cipher_init(ctx, cipher, (unsigned)iterations, pass, + pass_len, CBS_data(&salt), CBS_len(&salt), + CBS_data(&iv), CBS_len(&iv), 0 /* decrypt */); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/pkcs8/pkcs8.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/pkcs8/pkcs8.c new file mode 100644 index 0000000..7fd175d --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/pkcs8/pkcs8.c @@ -0,0 +1,513 @@ +/* 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 + +#include +#include +#include +#include +#include +#include +#include + +#include "internal.h" +#include "../internal.h" + + +static int ascii_to_ucs2(const char *ascii, size_t ascii_len, + uint8_t **out, size_t *out_len) { + size_t ulen = ascii_len * 2 + 2; + if (ascii_len * 2 < ascii_len || ulen < ascii_len * 2) { + return 0; + } + + uint8_t *unitmp = OPENSSL_malloc(ulen); + if (unitmp == NULL) { + OPENSSL_PUT_ERROR(PKCS8, ERR_R_MALLOC_FAILURE); + return 0; + } + for (size_t i = 0; i < ulen - 2; i += 2) { + unitmp[i] = 0; + unitmp[i + 1] = ascii[i >> 1]; + } + + // Terminate the result with a UCS-2 NUL. + unitmp[ulen - 2] = 0; + unitmp[ulen - 1] = 0; + *out_len = ulen; + *out = unitmp; + return 1; +} + +int pkcs12_key_gen(const char *pass, size_t pass_len, const uint8_t *salt, + size_t salt_len, uint8_t id, unsigned iterations, + size_t out_len, uint8_t *out, const EVP_MD *md) { + // See https://tools.ietf.org/html/rfc7292#appendix-B. Quoted parts of the + // specification have errata applied and other typos fixed. + + if (iterations < 1) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_ITERATION_COUNT); + return 0; + } + + int ret = 0; + EVP_MD_CTX ctx; + EVP_MD_CTX_init(&ctx); + uint8_t *pass_raw = NULL, *I = NULL; + size_t pass_raw_len = 0, I_len = 0; + // If |pass| is NULL, we use the empty string rather than {0, 0} as the raw + // password. + if (pass != NULL && + !ascii_to_ucs2(pass, pass_len, &pass_raw, &pass_raw_len)) { + goto err; + } + + // In the spec, |block_size| is called "v", but measured in bits. + size_t block_size = EVP_MD_block_size(md); + + // 1. Construct a string, D (the "diversifier"), by concatenating v/8 copies + // of ID. + uint8_t D[EVP_MAX_MD_BLOCK_SIZE]; + OPENSSL_memset(D, id, block_size); + + // 2. Concatenate copies of the salt together to create a string S of length + // v(ceiling(s/v)) bits (the final copy of the salt may be truncated to + // create S). Note that if the salt is the empty string, then so is S. + // + // 3. Concatenate copies of the password together to create a string P of + // length v(ceiling(p/v)) bits (the final copy of the password may be + // truncated to create P). Note that if the password is the empty string, + // then so is P. + // + // 4. Set I=S||P to be the concatenation of S and P. + if (salt_len + block_size - 1 < salt_len || + pass_raw_len + block_size - 1 < pass_raw_len) { + OPENSSL_PUT_ERROR(PKCS8, ERR_R_OVERFLOW); + goto err; + } + size_t S_len = block_size * ((salt_len + block_size - 1) / block_size); + size_t P_len = block_size * ((pass_raw_len + block_size - 1) / block_size); + I_len = S_len + P_len; + if (I_len < S_len) { + OPENSSL_PUT_ERROR(PKCS8, ERR_R_OVERFLOW); + goto err; + } + + I = OPENSSL_malloc(I_len); + if (I_len != 0 && I == NULL) { + OPENSSL_PUT_ERROR(PKCS8, ERR_R_MALLOC_FAILURE); + goto err; + } + + for (size_t i = 0; i < S_len; i++) { + I[i] = salt[i % salt_len]; + } + for (size_t i = 0; i < P_len; i++) { + I[i + S_len] = pass_raw[i % pass_raw_len]; + } + + while (out_len != 0) { + // A. Set A_i=H^r(D||I). (i.e., the r-th hash of D||I, + // H(H(H(... H(D||I)))) + uint8_t A[EVP_MAX_MD_SIZE]; + unsigned A_len; + if (!EVP_DigestInit_ex(&ctx, md, NULL) || + !EVP_DigestUpdate(&ctx, D, block_size) || + !EVP_DigestUpdate(&ctx, I, I_len) || + !EVP_DigestFinal_ex(&ctx, A, &A_len)) { + goto err; + } + for (unsigned iter = 1; iter < iterations; iter++) { + if (!EVP_DigestInit_ex(&ctx, md, NULL) || + !EVP_DigestUpdate(&ctx, A, A_len) || + !EVP_DigestFinal_ex(&ctx, A, &A_len)) { + goto err; + } + } + + size_t todo = out_len < A_len ? out_len : A_len; + OPENSSL_memcpy(out, A, todo); + out += todo; + out_len -= todo; + if (out_len == 0) { + break; + } + + // B. Concatenate copies of A_i to create a string B of length v bits (the + // final copy of A_i may be truncated to create B). + uint8_t B[EVP_MAX_MD_BLOCK_SIZE]; + for (size_t i = 0; i < block_size; i++) { + B[i] = A[i % A_len]; + } + + // C. Treating I as a concatenation I_0, I_1, ..., I_(k-1) of v-bit blocks, + // where k=ceiling(s/v)+ceiling(p/v), modify I by setting I_j=(I_j+B+1) mod + // 2^v for each j. + assert(I_len % block_size == 0); + for (size_t i = 0; i < I_len; i += block_size) { + unsigned carry = 1; + for (size_t j = block_size - 1; j < block_size; j--) { + carry += I[i + j] + B[j]; + I[i + j] = (uint8_t)carry; + carry >>= 8; + } + } + } + + ret = 1; + +err: + OPENSSL_free(I); + OPENSSL_free(pass_raw); + EVP_MD_CTX_cleanup(&ctx); + return ret; +} + +static int pkcs12_pbe_cipher_init(const struct pbe_suite *suite, + EVP_CIPHER_CTX *ctx, unsigned iterations, + const char *pass, size_t pass_len, + const uint8_t *salt, size_t salt_len, + int is_encrypt) { + const EVP_CIPHER *cipher = suite->cipher_func(); + const EVP_MD *md = suite->md_func(); + + uint8_t key[EVP_MAX_KEY_LENGTH]; + uint8_t iv[EVP_MAX_IV_LENGTH]; + if (!pkcs12_key_gen(pass, pass_len, salt, salt_len, PKCS12_KEY_ID, iterations, + EVP_CIPHER_key_length(cipher), key, md) || + !pkcs12_key_gen(pass, pass_len, salt, salt_len, PKCS12_IV_ID, iterations, + EVP_CIPHER_iv_length(cipher), iv, md)) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_KEY_GEN_ERROR); + return 0; + } + + int ret = EVP_CipherInit_ex(ctx, cipher, NULL, key, iv, is_encrypt); + OPENSSL_cleanse(key, EVP_MAX_KEY_LENGTH); + OPENSSL_cleanse(iv, EVP_MAX_IV_LENGTH); + return ret; +} + +static int pkcs12_pbe_decrypt_init(const struct pbe_suite *suite, + EVP_CIPHER_CTX *ctx, const char *pass, + size_t pass_len, CBS *param) { + CBS pbe_param, salt; + uint64_t iterations; + if (!CBS_get_asn1(param, &pbe_param, CBS_ASN1_SEQUENCE) || + !CBS_get_asn1(&pbe_param, &salt, CBS_ASN1_OCTETSTRING) || + !CBS_get_asn1_uint64(&pbe_param, &iterations) || + CBS_len(&pbe_param) != 0 || + CBS_len(param) != 0) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_DECODE_ERROR); + return 0; + } + + if (iterations == 0 || iterations > UINT_MAX) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_ITERATION_COUNT); + return 0; + } + + return pkcs12_pbe_cipher_init(suite, ctx, (unsigned)iterations, pass, + pass_len, CBS_data(&salt), CBS_len(&salt), + 0 /* decrypt */); +} + +static const struct pbe_suite kBuiltinPBE[] = { + { + NID_pbe_WithSHA1And40BitRC2_CBC, + // 1.2.840.113549.1.12.1.6 + {0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x01, 0x06}, + 10, + EVP_rc2_40_cbc, + EVP_sha1, + pkcs12_pbe_decrypt_init, + }, + { + NID_pbe_WithSHA1And128BitRC4, + // 1.2.840.113549.1.12.1.1 + {0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x01, 0x01}, + 10, + EVP_rc4, + EVP_sha1, + pkcs12_pbe_decrypt_init, + }, + { + NID_pbe_WithSHA1And3_Key_TripleDES_CBC, + // 1.2.840.113549.1.12.1.3 + {0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x01, 0x03}, + 10, + EVP_des_ede3_cbc, + EVP_sha1, + pkcs12_pbe_decrypt_init, + }, + { + NID_pbes2, + // 1.2.840.113549.1.5.13 + {0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x05, 0x0d}, + 9, + NULL, + NULL, + PKCS5_pbe2_decrypt_init, + }, +}; + +static const struct pbe_suite *get_pbe_suite(int pbe_nid) { + for (unsigned i = 0; i < OPENSSL_ARRAY_SIZE(kBuiltinPBE); i++) { + if (kBuiltinPBE[i].pbe_nid == pbe_nid) { + return &kBuiltinPBE[i]; + } + } + + return NULL; +} + +static int pkcs12_pbe_encrypt_init(CBB *out, EVP_CIPHER_CTX *ctx, int alg, + unsigned iterations, const char *pass, + size_t pass_len, const uint8_t *salt, + size_t salt_len) { + const struct pbe_suite *suite = get_pbe_suite(alg); + if (suite == NULL) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_UNKNOWN_ALGORITHM); + return 0; + } + + // See RFC 2898, appendix A.3. + CBB algorithm, oid, param, salt_cbb; + if (!CBB_add_asn1(out, &algorithm, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) || + !CBB_add_bytes(&oid, suite->oid, suite->oid_len) || + !CBB_add_asn1(&algorithm, ¶m, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1(¶m, &salt_cbb, CBS_ASN1_OCTETSTRING) || + !CBB_add_bytes(&salt_cbb, salt, salt_len) || + !CBB_add_asn1_uint64(¶m, iterations) || + !CBB_flush(out)) { + return 0; + } + + return pkcs12_pbe_cipher_init(suite, ctx, iterations, pass, pass_len, salt, + salt_len, 1 /* encrypt */); +} + +int pkcs8_pbe_decrypt(uint8_t **out, size_t *out_len, CBS *algorithm, + const char *pass, size_t pass_len, const uint8_t *in, + size_t in_len) { + int ret = 0; + uint8_t *buf = NULL;; + EVP_CIPHER_CTX ctx; + EVP_CIPHER_CTX_init(&ctx); + + CBS obj; + if (!CBS_get_asn1(algorithm, &obj, CBS_ASN1_OBJECT)) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_DECODE_ERROR); + goto err; + } + + const struct pbe_suite *suite = NULL; + for (unsigned i = 0; i < OPENSSL_ARRAY_SIZE(kBuiltinPBE); i++) { + if (CBS_mem_equal(&obj, kBuiltinPBE[i].oid, kBuiltinPBE[i].oid_len)) { + suite = &kBuiltinPBE[i]; + break; + } + } + if (suite == NULL) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_UNKNOWN_ALGORITHM); + goto err; + } + + if (!suite->decrypt_init(suite, &ctx, pass, pass_len, algorithm)) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_KEYGEN_FAILURE); + goto err; + } + + buf = OPENSSL_malloc(in_len); + if (buf == NULL) { + OPENSSL_PUT_ERROR(PKCS8, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (in_len > INT_MAX) { + OPENSSL_PUT_ERROR(PKCS8, ERR_R_OVERFLOW); + goto err; + } + + int n1, n2; + if (!EVP_DecryptUpdate(&ctx, buf, &n1, in, (int)in_len) || + !EVP_DecryptFinal_ex(&ctx, buf + n1, &n2)) { + goto err; + } + + *out = buf; + *out_len = n1 + n2; + ret = 1; + buf = NULL; + +err: + OPENSSL_free(buf); + EVP_CIPHER_CTX_cleanup(&ctx); + return ret; +} + +EVP_PKEY *PKCS8_parse_encrypted_private_key(CBS *cbs, const char *pass, + size_t pass_len) { + // See RFC 5208, section 6. + CBS epki, algorithm, ciphertext; + if (!CBS_get_asn1(cbs, &epki, CBS_ASN1_SEQUENCE) || + !CBS_get_asn1(&epki, &algorithm, CBS_ASN1_SEQUENCE) || + !CBS_get_asn1(&epki, &ciphertext, CBS_ASN1_OCTETSTRING) || + CBS_len(&epki) != 0) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_DECODE_ERROR); + return 0; + } + + uint8_t *out; + size_t out_len; + if (!pkcs8_pbe_decrypt(&out, &out_len, &algorithm, pass, pass_len, + CBS_data(&ciphertext), CBS_len(&ciphertext))) { + return 0; + } + + CBS pki; + CBS_init(&pki, out, out_len); + EVP_PKEY *ret = EVP_parse_private_key(&pki); + OPENSSL_free(out); + return ret; +} + +int PKCS8_marshal_encrypted_private_key(CBB *out, int pbe_nid, + const EVP_CIPHER *cipher, + const char *pass, size_t pass_len, + const uint8_t *salt, size_t salt_len, + int iterations, const EVP_PKEY *pkey) { + int ret = 0; + uint8_t *plaintext = NULL, *salt_buf = NULL; + size_t plaintext_len = 0; + EVP_CIPHER_CTX ctx; + EVP_CIPHER_CTX_init(&ctx); + + // Generate a random salt if necessary. + if (salt == NULL) { + if (salt_len == 0) { + salt_len = PKCS5_SALT_LEN; + } + + salt_buf = OPENSSL_malloc(salt_len); + if (salt_buf == NULL || + !RAND_bytes(salt_buf, salt_len)) { + goto err; + } + + salt = salt_buf; + } + + if (iterations <= 0) { + iterations = PKCS5_DEFAULT_ITERATIONS; + } + + // Serialize the input key. + CBB plaintext_cbb; + if (!CBB_init(&plaintext_cbb, 128) || + !EVP_marshal_private_key(&plaintext_cbb, pkey) || + !CBB_finish(&plaintext_cbb, &plaintext, &plaintext_len)) { + CBB_cleanup(&plaintext_cbb); + goto err; + } + + CBB epki; + if (!CBB_add_asn1(out, &epki, CBS_ASN1_SEQUENCE)) { + goto err; + } + + int alg_ok; + if (pbe_nid == -1) { + alg_ok = PKCS5_pbe2_encrypt_init(&epki, &ctx, cipher, (unsigned)iterations, + pass, pass_len, salt, salt_len); + } else { + alg_ok = pkcs12_pbe_encrypt_init(&epki, &ctx, pbe_nid, (unsigned)iterations, + pass, pass_len, salt, salt_len); + } + if (!alg_ok) { + goto err; + } + + size_t max_out = plaintext_len + EVP_CIPHER_CTX_block_size(&ctx); + if (max_out < plaintext_len) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_TOO_LONG); + goto err; + } + + CBB ciphertext; + uint8_t *ptr; + int n1, n2; + if (!CBB_add_asn1(&epki, &ciphertext, CBS_ASN1_OCTETSTRING) || + !CBB_reserve(&ciphertext, &ptr, max_out) || + !EVP_CipherUpdate(&ctx, ptr, &n1, plaintext, plaintext_len) || + !EVP_CipherFinal_ex(&ctx, ptr + n1, &n2) || + !CBB_did_write(&ciphertext, n1 + n2) || + !CBB_flush(out)) { + goto err; + } + + ret = 1; + +err: + OPENSSL_free(plaintext); + OPENSSL_free(salt_buf); + EVP_CIPHER_CTX_cleanup(&ctx); + return ret; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/pkcs8/pkcs8.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/pkcs8/pkcs8.c.grpc_back new file mode 100644 index 0000000..94205e6 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/pkcs8/pkcs8.c.grpc_back @@ -0,0 +1,513 @@ +/* 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 + +#include +#include +#include +#include +#include +#include +#include + +#include "internal.h" +#include "../internal.h" + + +static int ascii_to_ucs2(const char *ascii, size_t ascii_len, + uint8_t **out, size_t *out_len) { + size_t ulen = ascii_len * 2 + 2; + if (ascii_len * 2 < ascii_len || ulen < ascii_len * 2) { + return 0; + } + + uint8_t *unitmp = OPENSSL_malloc(ulen); + if (unitmp == NULL) { + OPENSSL_PUT_ERROR(PKCS8, ERR_R_MALLOC_FAILURE); + return 0; + } + for (size_t i = 0; i < ulen - 2; i += 2) { + unitmp[i] = 0; + unitmp[i + 1] = ascii[i >> 1]; + } + + // Terminate the result with a UCS-2 NUL. + unitmp[ulen - 2] = 0; + unitmp[ulen - 1] = 0; + *out_len = ulen; + *out = unitmp; + return 1; +} + +int pkcs12_key_gen(const char *pass, size_t pass_len, const uint8_t *salt, + size_t salt_len, uint8_t id, unsigned iterations, + size_t out_len, uint8_t *out, const EVP_MD *md) { + // See https://tools.ietf.org/html/rfc7292#appendix-B. Quoted parts of the + // specification have errata applied and other typos fixed. + + if (iterations < 1) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_ITERATION_COUNT); + return 0; + } + + int ret = 0; + EVP_MD_CTX ctx; + EVP_MD_CTX_init(&ctx); + uint8_t *pass_raw = NULL, *I = NULL; + size_t pass_raw_len = 0, I_len = 0; + // If |pass| is NULL, we use the empty string rather than {0, 0} as the raw + // password. + if (pass != NULL && + !ascii_to_ucs2(pass, pass_len, &pass_raw, &pass_raw_len)) { + goto err; + } + + // In the spec, |block_size| is called "v", but measured in bits. + size_t block_size = EVP_MD_block_size(md); + + // 1. Construct a string, D (the "diversifier"), by concatenating v/8 copies + // of ID. + uint8_t D[EVP_MAX_MD_BLOCK_SIZE]; + OPENSSL_memset(D, id, block_size); + + // 2. Concatenate copies of the salt together to create a string S of length + // v(ceiling(s/v)) bits (the final copy of the salt may be truncated to + // create S). Note that if the salt is the empty string, then so is S. + // + // 3. Concatenate copies of the password together to create a string P of + // length v(ceiling(p/v)) bits (the final copy of the password may be + // truncated to create P). Note that if the password is the empty string, + // then so is P. + // + // 4. Set I=S||P to be the concatenation of S and P. + if (salt_len + block_size - 1 < salt_len || + pass_raw_len + block_size - 1 < pass_raw_len) { + OPENSSL_PUT_ERROR(PKCS8, ERR_R_OVERFLOW); + goto err; + } + size_t S_len = block_size * ((salt_len + block_size - 1) / block_size); + size_t P_len = block_size * ((pass_raw_len + block_size - 1) / block_size); + I_len = S_len + P_len; + if (I_len < S_len) { + OPENSSL_PUT_ERROR(PKCS8, ERR_R_OVERFLOW); + goto err; + } + + I = OPENSSL_malloc(I_len); + if (I_len != 0 && I == NULL) { + OPENSSL_PUT_ERROR(PKCS8, ERR_R_MALLOC_FAILURE); + goto err; + } + + for (size_t i = 0; i < S_len; i++) { + I[i] = salt[i % salt_len]; + } + for (size_t i = 0; i < P_len; i++) { + I[i + S_len] = pass_raw[i % pass_raw_len]; + } + + while (out_len != 0) { + // A. Set A_i=H^r(D||I). (i.e., the r-th hash of D||I, + // H(H(H(... H(D||I)))) + uint8_t A[EVP_MAX_MD_SIZE]; + unsigned A_len; + if (!EVP_DigestInit_ex(&ctx, md, NULL) || + !EVP_DigestUpdate(&ctx, D, block_size) || + !EVP_DigestUpdate(&ctx, I, I_len) || + !EVP_DigestFinal_ex(&ctx, A, &A_len)) { + goto err; + } + for (unsigned iter = 1; iter < iterations; iter++) { + if (!EVP_DigestInit_ex(&ctx, md, NULL) || + !EVP_DigestUpdate(&ctx, A, A_len) || + !EVP_DigestFinal_ex(&ctx, A, &A_len)) { + goto err; + } + } + + size_t todo = out_len < A_len ? out_len : A_len; + OPENSSL_memcpy(out, A, todo); + out += todo; + out_len -= todo; + if (out_len == 0) { + break; + } + + // B. Concatenate copies of A_i to create a string B of length v bits (the + // final copy of A_i may be truncated to create B). + uint8_t B[EVP_MAX_MD_BLOCK_SIZE]; + for (size_t i = 0; i < block_size; i++) { + B[i] = A[i % A_len]; + } + + // C. Treating I as a concatenation I_0, I_1, ..., I_(k-1) of v-bit blocks, + // where k=ceiling(s/v)+ceiling(p/v), modify I by setting I_j=(I_j+B+1) mod + // 2^v for each j. + assert(I_len % block_size == 0); + for (size_t i = 0; i < I_len; i += block_size) { + unsigned carry = 1; + for (size_t j = block_size - 1; j < block_size; j--) { + carry += I[i + j] + B[j]; + I[i + j] = (uint8_t)carry; + carry >>= 8; + } + } + } + + ret = 1; + +err: + OPENSSL_free(I); + OPENSSL_free(pass_raw); + EVP_MD_CTX_cleanup(&ctx); + return ret; +} + +static int pkcs12_pbe_cipher_init(const struct pbe_suite *suite, + EVP_CIPHER_CTX *ctx, unsigned iterations, + const char *pass, size_t pass_len, + const uint8_t *salt, size_t salt_len, + int is_encrypt) { + const EVP_CIPHER *cipher = suite->cipher_func(); + const EVP_MD *md = suite->md_func(); + + uint8_t key[EVP_MAX_KEY_LENGTH]; + uint8_t iv[EVP_MAX_IV_LENGTH]; + if (!pkcs12_key_gen(pass, pass_len, salt, salt_len, PKCS12_KEY_ID, iterations, + EVP_CIPHER_key_length(cipher), key, md) || + !pkcs12_key_gen(pass, pass_len, salt, salt_len, PKCS12_IV_ID, iterations, + EVP_CIPHER_iv_length(cipher), iv, md)) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_KEY_GEN_ERROR); + return 0; + } + + int ret = EVP_CipherInit_ex(ctx, cipher, NULL, key, iv, is_encrypt); + OPENSSL_cleanse(key, EVP_MAX_KEY_LENGTH); + OPENSSL_cleanse(iv, EVP_MAX_IV_LENGTH); + return ret; +} + +static int pkcs12_pbe_decrypt_init(const struct pbe_suite *suite, + EVP_CIPHER_CTX *ctx, const char *pass, + size_t pass_len, CBS *param) { + CBS pbe_param, salt; + uint64_t iterations; + if (!CBS_get_asn1(param, &pbe_param, CBS_ASN1_SEQUENCE) || + !CBS_get_asn1(&pbe_param, &salt, CBS_ASN1_OCTETSTRING) || + !CBS_get_asn1_uint64(&pbe_param, &iterations) || + CBS_len(&pbe_param) != 0 || + CBS_len(param) != 0) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_DECODE_ERROR); + return 0; + } + + if (iterations == 0 || iterations > UINT_MAX) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_ITERATION_COUNT); + return 0; + } + + return pkcs12_pbe_cipher_init(suite, ctx, (unsigned)iterations, pass, + pass_len, CBS_data(&salt), CBS_len(&salt), + 0 /* decrypt */); +} + +static const struct pbe_suite kBuiltinPBE[] = { + { + NID_pbe_WithSHA1And40BitRC2_CBC, + // 1.2.840.113549.1.12.1.6 + {0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x01, 0x06}, + 10, + EVP_rc2_40_cbc, + EVP_sha1, + pkcs12_pbe_decrypt_init, + }, + { + NID_pbe_WithSHA1And128BitRC4, + // 1.2.840.113549.1.12.1.1 + {0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x01, 0x01}, + 10, + EVP_rc4, + EVP_sha1, + pkcs12_pbe_decrypt_init, + }, + { + NID_pbe_WithSHA1And3_Key_TripleDES_CBC, + // 1.2.840.113549.1.12.1.3 + {0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x01, 0x03}, + 10, + EVP_des_ede3_cbc, + EVP_sha1, + pkcs12_pbe_decrypt_init, + }, + { + NID_pbes2, + // 1.2.840.113549.1.5.13 + {0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x05, 0x0d}, + 9, + NULL, + NULL, + PKCS5_pbe2_decrypt_init, + }, +}; + +static const struct pbe_suite *get_pbe_suite(int pbe_nid) { + for (unsigned i = 0; i < OPENSSL_ARRAY_SIZE(kBuiltinPBE); i++) { + if (kBuiltinPBE[i].pbe_nid == pbe_nid) { + return &kBuiltinPBE[i]; + } + } + + return NULL; +} + +static int pkcs12_pbe_encrypt_init(CBB *out, EVP_CIPHER_CTX *ctx, int alg, + unsigned iterations, const char *pass, + size_t pass_len, const uint8_t *salt, + size_t salt_len) { + const struct pbe_suite *suite = get_pbe_suite(alg); + if (suite == NULL) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_UNKNOWN_ALGORITHM); + return 0; + } + + // See RFC 2898, appendix A.3. + CBB algorithm, oid, param, salt_cbb; + if (!CBB_add_asn1(out, &algorithm, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1(&algorithm, &oid, CBS_ASN1_OBJECT) || + !CBB_add_bytes(&oid, suite->oid, suite->oid_len) || + !CBB_add_asn1(&algorithm, ¶m, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1(¶m, &salt_cbb, CBS_ASN1_OCTETSTRING) || + !CBB_add_bytes(&salt_cbb, salt, salt_len) || + !CBB_add_asn1_uint64(¶m, iterations) || + !CBB_flush(out)) { + return 0; + } + + return pkcs12_pbe_cipher_init(suite, ctx, iterations, pass, pass_len, salt, + salt_len, 1 /* encrypt */); +} + +int pkcs8_pbe_decrypt(uint8_t **out, size_t *out_len, CBS *algorithm, + const char *pass, size_t pass_len, const uint8_t *in, + size_t in_len) { + int ret = 0; + uint8_t *buf = NULL;; + EVP_CIPHER_CTX ctx; + EVP_CIPHER_CTX_init(&ctx); + + CBS obj; + if (!CBS_get_asn1(algorithm, &obj, CBS_ASN1_OBJECT)) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_DECODE_ERROR); + goto err; + } + + const struct pbe_suite *suite = NULL; + for (unsigned i = 0; i < OPENSSL_ARRAY_SIZE(kBuiltinPBE); i++) { + if (CBS_mem_equal(&obj, kBuiltinPBE[i].oid, kBuiltinPBE[i].oid_len)) { + suite = &kBuiltinPBE[i]; + break; + } + } + if (suite == NULL) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_UNKNOWN_ALGORITHM); + goto err; + } + + if (!suite->decrypt_init(suite, &ctx, pass, pass_len, algorithm)) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_KEYGEN_FAILURE); + goto err; + } + + buf = OPENSSL_malloc(in_len); + if (buf == NULL) { + OPENSSL_PUT_ERROR(PKCS8, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (in_len > INT_MAX) { + OPENSSL_PUT_ERROR(PKCS8, ERR_R_OVERFLOW); + goto err; + } + + int n1, n2; + if (!EVP_DecryptUpdate(&ctx, buf, &n1, in, (int)in_len) || + !EVP_DecryptFinal_ex(&ctx, buf + n1, &n2)) { + goto err; + } + + *out = buf; + *out_len = n1 + n2; + ret = 1; + buf = NULL; + +err: + OPENSSL_free(buf); + EVP_CIPHER_CTX_cleanup(&ctx); + return ret; +} + +EVP_PKEY *PKCS8_parse_encrypted_private_key(CBS *cbs, const char *pass, + size_t pass_len) { + // See RFC 5208, section 6. + CBS epki, algorithm, ciphertext; + if (!CBS_get_asn1(cbs, &epki, CBS_ASN1_SEQUENCE) || + !CBS_get_asn1(&epki, &algorithm, CBS_ASN1_SEQUENCE) || + !CBS_get_asn1(&epki, &ciphertext, CBS_ASN1_OCTETSTRING) || + CBS_len(&epki) != 0) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_DECODE_ERROR); + return 0; + } + + uint8_t *out; + size_t out_len; + if (!pkcs8_pbe_decrypt(&out, &out_len, &algorithm, pass, pass_len, + CBS_data(&ciphertext), CBS_len(&ciphertext))) { + return 0; + } + + CBS pki; + CBS_init(&pki, out, out_len); + EVP_PKEY *ret = EVP_parse_private_key(&pki); + OPENSSL_free(out); + return ret; +} + +int PKCS8_marshal_encrypted_private_key(CBB *out, int pbe_nid, + const EVP_CIPHER *cipher, + const char *pass, size_t pass_len, + const uint8_t *salt, size_t salt_len, + int iterations, const EVP_PKEY *pkey) { + int ret = 0; + uint8_t *plaintext = NULL, *salt_buf = NULL; + size_t plaintext_len = 0; + EVP_CIPHER_CTX ctx; + EVP_CIPHER_CTX_init(&ctx); + + // Generate a random salt if necessary. + if (salt == NULL) { + if (salt_len == 0) { + salt_len = PKCS5_SALT_LEN; + } + + salt_buf = OPENSSL_malloc(salt_len); + if (salt_buf == NULL || + !RAND_bytes(salt_buf, salt_len)) { + goto err; + } + + salt = salt_buf; + } + + if (iterations <= 0) { + iterations = PKCS5_DEFAULT_ITERATIONS; + } + + // Serialize the input key. + CBB plaintext_cbb; + if (!CBB_init(&plaintext_cbb, 128) || + !EVP_marshal_private_key(&plaintext_cbb, pkey) || + !CBB_finish(&plaintext_cbb, &plaintext, &plaintext_len)) { + CBB_cleanup(&plaintext_cbb); + goto err; + } + + CBB epki; + if (!CBB_add_asn1(out, &epki, CBS_ASN1_SEQUENCE)) { + goto err; + } + + int alg_ok; + if (pbe_nid == -1) { + alg_ok = PKCS5_pbe2_encrypt_init(&epki, &ctx, cipher, (unsigned)iterations, + pass, pass_len, salt, salt_len); + } else { + alg_ok = pkcs12_pbe_encrypt_init(&epki, &ctx, pbe_nid, (unsigned)iterations, + pass, pass_len, salt, salt_len); + } + if (!alg_ok) { + goto err; + } + + size_t max_out = plaintext_len + EVP_CIPHER_CTX_block_size(&ctx); + if (max_out < plaintext_len) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_TOO_LONG); + goto err; + } + + CBB ciphertext; + uint8_t *ptr; + int n1, n2; + if (!CBB_add_asn1(&epki, &ciphertext, CBS_ASN1_OCTETSTRING) || + !CBB_reserve(&ciphertext, &ptr, max_out) || + !EVP_CipherUpdate(&ctx, ptr, &n1, plaintext, plaintext_len) || + !EVP_CipherFinal_ex(&ctx, ptr + n1, &n2) || + !CBB_did_write(&ciphertext, n1 + n2) || + !CBB_flush(out)) { + goto err; + } + + ret = 1; + +err: + OPENSSL_free(plaintext); + OPENSSL_free(salt_buf); + EVP_CIPHER_CTX_cleanup(&ctx); + return ret; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/pkcs8/pkcs8_x509.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/pkcs8/pkcs8_x509.c new file mode 100644 index 0000000..ffcd914 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/pkcs8/pkcs8_x509.c @@ -0,0 +1,789 @@ +/* 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "internal.h" +#include "../bytestring/internal.h" +#include "../internal.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) { + 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) + +EVP_PKEY *EVP_PKCS82PKEY(PKCS8_PRIV_KEY_INFO *p8) { + uint8_t *der = NULL; + int der_len = i2d_PKCS8_PRIV_KEY_INFO(p8, &der); + if (der_len < 0) { + return NULL; + } + + CBS cbs; + CBS_init(&cbs, der, (size_t)der_len); + EVP_PKEY *ret = EVP_parse_private_key(&cbs); + if (ret == NULL || CBS_len(&cbs) != 0) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_DECODE_ERROR); + EVP_PKEY_free(ret); + OPENSSL_free(der); + return NULL; + } + + OPENSSL_free(der); + return ret; +} + +PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(EVP_PKEY *pkey) { + CBB cbb; + uint8_t *der = NULL; + size_t der_len; + if (!CBB_init(&cbb, 0) || + !EVP_marshal_private_key(&cbb, pkey) || + !CBB_finish(&cbb, &der, &der_len) || + der_len > LONG_MAX) { + CBB_cleanup(&cbb); + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_ENCODE_ERROR); + goto err; + } + + const uint8_t *p = der; + PKCS8_PRIV_KEY_INFO *p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, (long)der_len); + if (p8 == NULL || p != der + der_len) { + PKCS8_PRIV_KEY_INFO_free(p8); + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_DECODE_ERROR); + goto err; + } + + OPENSSL_free(der); + return p8; + +err: + OPENSSL_free(der); + return NULL; +} + +PKCS8_PRIV_KEY_INFO *PKCS8_decrypt(X509_SIG *pkcs8, const char *pass, + int pass_len_in) { + size_t pass_len; + if (pass_len_in == -1 && pass != NULL) { + pass_len = strlen(pass); + } else { + pass_len = (size_t)pass_len_in; + } + + PKCS8_PRIV_KEY_INFO *ret = NULL; + EVP_PKEY *pkey = NULL; + uint8_t *in = NULL; + + // Convert the legacy ASN.1 object to a byte string. + int in_len = i2d_X509_SIG(pkcs8, &in); + if (in_len < 0) { + goto err; + } + + CBS cbs; + CBS_init(&cbs, in, in_len); + pkey = PKCS8_parse_encrypted_private_key(&cbs, pass, pass_len); + if (pkey == NULL || CBS_len(&cbs) != 0) { + goto err; + } + + ret = EVP_PKEY2PKCS8(pkey); + +err: + OPENSSL_free(in); + EVP_PKEY_free(pkey); + return ret; +} + +X509_SIG *PKCS8_encrypt(int pbe_nid, const EVP_CIPHER *cipher, const char *pass, + int pass_len_in, const uint8_t *salt, size_t salt_len, + int iterations, PKCS8_PRIV_KEY_INFO *p8inf) { + size_t pass_len; + if (pass_len_in == -1 && pass != NULL) { + pass_len = strlen(pass); + } else { + pass_len = (size_t)pass_len_in; + } + + // Parse out the private key. + EVP_PKEY *pkey = EVP_PKCS82PKEY(p8inf); + if (pkey == NULL) { + return NULL; + } + + X509_SIG *ret = NULL; + uint8_t *der = NULL; + size_t der_len; + CBB cbb; + if (!CBB_init(&cbb, 128) || + !PKCS8_marshal_encrypted_private_key(&cbb, pbe_nid, cipher, pass, + pass_len, salt, salt_len, iterations, + pkey) || + !CBB_finish(&cbb, &der, &der_len)) { + CBB_cleanup(&cbb); + goto err; + } + + // Convert back to legacy ASN.1 objects. + const uint8_t *ptr = der; + ret = d2i_X509_SIG(NULL, &ptr, der_len); + if (ret == NULL || ptr != der + der_len) { + OPENSSL_PUT_ERROR(PKCS8, ERR_R_INTERNAL_ERROR); + X509_SIG_free(ret); + ret = NULL; + } + +err: + OPENSSL_free(der); + EVP_PKEY_free(pkey); + return ret; +} + +struct pkcs12_context { + EVP_PKEY **out_key; + STACK_OF(X509) *out_certs; + const char *password; + size_t password_len; +}; + +// PKCS12_handle_sequence parses a BER-encoded SEQUENCE of elements in a PKCS#12 +// structure. +static int PKCS12_handle_sequence( + CBS *sequence, struct pkcs12_context *ctx, + int (*handle_element)(CBS *cbs, struct pkcs12_context *ctx)) { + uint8_t *der_bytes = NULL; + size_t der_len; + CBS in; + int ret = 0; + + // Although a BER->DER conversion is done at the beginning of |PKCS12_parse|, + // the ASN.1 data gets wrapped in OCTETSTRINGs and/or encrypted and the + // conversion cannot see through those wrappings. So each time we step + // through one we need to convert to DER again. + if (!CBS_asn1_ber_to_der(sequence, &der_bytes, &der_len)) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); + return 0; + } + + if (der_bytes != NULL) { + CBS_init(&in, der_bytes, der_len); + } else { + CBS_init(&in, CBS_data(sequence), CBS_len(sequence)); + } + + CBS child; + if (!CBS_get_asn1(&in, &child, CBS_ASN1_SEQUENCE) || + CBS_len(&in) != 0) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); + goto err; + } + + while (CBS_len(&child) > 0) { + CBS element; + if (!CBS_get_asn1(&child, &element, CBS_ASN1_SEQUENCE)) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); + goto err; + } + + if (!handle_element(&element, ctx)) { + goto err; + } + } + + ret = 1; + +err: + OPENSSL_free(der_bytes); + return ret; +} + +// 1.2.840.113549.1.12.10.1.2 +static const uint8_t kPKCS8ShroudedKeyBag[] = { + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x0a, 0x01, 0x02}; + +// 1.2.840.113549.1.12.10.1.3 +static const uint8_t kCertBag[] = {0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, + 0x01, 0x0c, 0x0a, 0x01, 0x03}; + +// 1.2.840.113549.1.9.22.1 +static const uint8_t kX509Certificate[] = {0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x09, 0x16, 0x01}; + +// PKCS12_handle_safe_bag parses a single SafeBag element in a PKCS#12 +// structure. +static int PKCS12_handle_safe_bag(CBS *safe_bag, struct pkcs12_context *ctx) { + CBS bag_id, wrapped_value; + if (!CBS_get_asn1(safe_bag, &bag_id, CBS_ASN1_OBJECT) || + !CBS_get_asn1(safe_bag, &wrapped_value, + CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0) + /* Ignore the bagAttributes field. */) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); + return 0; + } + + if (CBS_mem_equal(&bag_id, kPKCS8ShroudedKeyBag, + sizeof(kPKCS8ShroudedKeyBag))) { + // See RFC 7292, section 4.2.2. + if (*ctx->out_key) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_MULTIPLE_PRIVATE_KEYS_IN_PKCS12); + return 0; + } + + EVP_PKEY *pkey = PKCS8_parse_encrypted_private_key( + &wrapped_value, ctx->password, ctx->password_len); + if (pkey == NULL) { + return 0; + } + + if (CBS_len(&wrapped_value) != 0) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); + EVP_PKEY_free(pkey); + return 0; + } + + *ctx->out_key = pkey; + return 1; + } + + if (CBS_mem_equal(&bag_id, kCertBag, sizeof(kCertBag))) { + // See RFC 7292, section 4.2.3. + CBS cert_bag, cert_type, wrapped_cert, cert; + if (!CBS_get_asn1(&wrapped_value, &cert_bag, CBS_ASN1_SEQUENCE) || + !CBS_get_asn1(&cert_bag, &cert_type, CBS_ASN1_OBJECT) || + !CBS_get_asn1(&cert_bag, &wrapped_cert, + CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0) || + !CBS_get_asn1(&wrapped_cert, &cert, CBS_ASN1_OCTETSTRING)) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); + return 0; + } + + // Skip unknown certificate types. + if (!CBS_mem_equal(&cert_type, kX509Certificate, + sizeof(kX509Certificate))) { + return 1; + } + + if (CBS_len(&cert) > LONG_MAX) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); + return 0; + } + + const uint8_t *inp = CBS_data(&cert); + X509 *x509 = d2i_X509(NULL, &inp, (long)CBS_len(&cert)); + if (!x509) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); + return 0; + } + + if (inp != CBS_data(&cert) + CBS_len(&cert)) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); + X509_free(x509); + return 0; + } + + if (0 == sk_X509_push(ctx->out_certs, x509)) { + X509_free(x509); + return 0; + } + + return 1; + } + + // Unknown element type - ignore it. + return 1; +} + +// 1.2.840.113549.1.7.1 +static const uint8_t kPKCS7Data[] = {0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x07, 0x01}; + +// 1.2.840.113549.1.7.6 +static const uint8_t kPKCS7EncryptedData[] = {0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x07, 0x06}; + +// PKCS12_handle_content_info parses a single PKCS#7 ContentInfo element in a +// PKCS#12 structure. +static int PKCS12_handle_content_info(CBS *content_info, + struct pkcs12_context *ctx) { + CBS content_type, wrapped_contents, contents; + int ret = 0; + uint8_t *storage = NULL; + + if (!CBS_get_asn1(content_info, &content_type, CBS_ASN1_OBJECT) || + !CBS_get_asn1(content_info, &wrapped_contents, + CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0) || + CBS_len(content_info) != 0) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); + goto err; + } + + if (CBS_mem_equal(&content_type, kPKCS7EncryptedData, + sizeof(kPKCS7EncryptedData))) { + // See https://tools.ietf.org/html/rfc2315#section-13. + // + // PKCS#7 encrypted data inside a PKCS#12 structure is generally an + // encrypted certificate bag and it's generally encrypted with 40-bit + // RC2-CBC. + CBS version_bytes, eci, contents_type, ai, encrypted_contents; + uint8_t *out; + size_t out_len; + + if (!CBS_get_asn1(&wrapped_contents, &contents, CBS_ASN1_SEQUENCE) || + !CBS_get_asn1(&contents, &version_bytes, CBS_ASN1_INTEGER) || + // EncryptedContentInfo, see + // https://tools.ietf.org/html/rfc2315#section-10.1 + !CBS_get_asn1(&contents, &eci, CBS_ASN1_SEQUENCE) || + !CBS_get_asn1(&eci, &contents_type, CBS_ASN1_OBJECT) || + // AlgorithmIdentifier, see + // https://tools.ietf.org/html/rfc5280#section-4.1.1.2 + !CBS_get_asn1(&eci, &ai, CBS_ASN1_SEQUENCE) || + !CBS_get_asn1_implicit_string( + &eci, &encrypted_contents, &storage, + CBS_ASN1_CONTEXT_SPECIFIC | 0, CBS_ASN1_OCTETSTRING)) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); + goto err; + } + + if (!CBS_mem_equal(&contents_type, kPKCS7Data, sizeof(kPKCS7Data))) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); + goto err; + } + + if (!pkcs8_pbe_decrypt(&out, &out_len, &ai, ctx->password, + ctx->password_len, CBS_data(&encrypted_contents), + CBS_len(&encrypted_contents))) { + goto err; + } + + CBS safe_contents; + CBS_init(&safe_contents, out, out_len); + ret = PKCS12_handle_sequence(&safe_contents, ctx, PKCS12_handle_safe_bag); + OPENSSL_free(out); + } else if (CBS_mem_equal(&content_type, kPKCS7Data, sizeof(kPKCS7Data))) { + CBS octet_string_contents; + + if (!CBS_get_asn1(&wrapped_contents, &octet_string_contents, + CBS_ASN1_OCTETSTRING)) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); + goto err; + } + + ret = PKCS12_handle_sequence(&octet_string_contents, ctx, + PKCS12_handle_safe_bag); + } else { + // Unknown element type - ignore it. + ret = 1; + } + +err: + OPENSSL_free(storage); + return ret; +} + +int PKCS12_get_key_and_certs(EVP_PKEY **out_key, STACK_OF(X509) *out_certs, + CBS *ber_in, const char *password) { + uint8_t *der_bytes = NULL; + size_t der_len; + CBS in, pfx, mac_data, authsafe, content_type, wrapped_authsafes, authsafes; + uint64_t version; + int ret = 0; + struct pkcs12_context ctx; + const size_t original_out_certs_len = sk_X509_num(out_certs); + + // The input may be in BER format. + if (!CBS_asn1_ber_to_der(ber_in, &der_bytes, &der_len)) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); + return 0; + } + if (der_bytes != NULL) { + CBS_init(&in, der_bytes, der_len); + } else { + CBS_init(&in, CBS_data(ber_in), CBS_len(ber_in)); + } + + *out_key = NULL; + OPENSSL_memset(&ctx, 0, sizeof(ctx)); + + // See ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-12/pkcs-12v1.pdf, section + // four. + if (!CBS_get_asn1(&in, &pfx, CBS_ASN1_SEQUENCE) || + CBS_len(&in) != 0 || + !CBS_get_asn1_uint64(&pfx, &version)) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); + goto err; + } + + if (version < 3) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_VERSION); + goto err; + } + + if (!CBS_get_asn1(&pfx, &authsafe, CBS_ASN1_SEQUENCE)) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); + goto err; + } + + if (CBS_len(&pfx) == 0) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_MISSING_MAC); + goto err; + } + + if (!CBS_get_asn1(&pfx, &mac_data, CBS_ASN1_SEQUENCE)) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); + goto err; + } + + // authsafe is a PKCS#7 ContentInfo. See + // https://tools.ietf.org/html/rfc2315#section-7. + if (!CBS_get_asn1(&authsafe, &content_type, CBS_ASN1_OBJECT) || + !CBS_get_asn1(&authsafe, &wrapped_authsafes, + CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0)) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); + goto err; + } + + // The content type can either be data or signedData. The latter indicates + // that it's signed by a public key, which isn't supported. + if (!CBS_mem_equal(&content_type, kPKCS7Data, sizeof(kPKCS7Data))) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_PKCS12_PUBLIC_KEY_INTEGRITY_NOT_SUPPORTED); + goto err; + } + + if (!CBS_get_asn1(&wrapped_authsafes, &authsafes, CBS_ASN1_OCTETSTRING)) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); + goto err; + } + + ctx.out_key = out_key; + ctx.out_certs = out_certs; + ctx.password = password; + ctx.password_len = password != NULL ? strlen(password) : 0; + + // Verify the MAC. + { + CBS mac, salt, expected_mac; + if (!CBS_get_asn1(&mac_data, &mac, CBS_ASN1_SEQUENCE)) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); + goto err; + } + + const EVP_MD *md = EVP_parse_digest_algorithm(&mac); + if (md == NULL) { + goto err; + } + + if (!CBS_get_asn1(&mac, &expected_mac, CBS_ASN1_OCTETSTRING) || + !CBS_get_asn1(&mac_data, &salt, CBS_ASN1_OCTETSTRING)) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); + goto err; + } + + // The iteration count is optional and the default is one. + uint64_t iterations = 1; + if (CBS_len(&mac_data) > 0) { + if (!CBS_get_asn1_uint64(&mac_data, &iterations) || + iterations > UINT_MAX) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); + goto err; + } + } + + uint8_t hmac_key[EVP_MAX_MD_SIZE]; + if (!pkcs12_key_gen(ctx.password, ctx.password_len, CBS_data(&salt), + CBS_len(&salt), PKCS12_MAC_ID, iterations, + EVP_MD_size(md), hmac_key, md)) { + goto err; + } + + uint8_t hmac[EVP_MAX_MD_SIZE]; + unsigned hmac_len; + if (NULL == HMAC(md, hmac_key, EVP_MD_size(md), CBS_data(&authsafes), + CBS_len(&authsafes), hmac, &hmac_len)) { + goto err; + } + + if (!CBS_mem_equal(&expected_mac, hmac, hmac_len)) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_INCORRECT_PASSWORD); + goto err; + } + } + + // authsafes contains a series of PKCS#7 ContentInfos. + if (!PKCS12_handle_sequence(&authsafes, &ctx, PKCS12_handle_content_info)) { + goto err; + } + + ret = 1; + +err: + OPENSSL_free(der_bytes); + if (!ret) { + EVP_PKEY_free(*out_key); + *out_key = NULL; + while (sk_X509_num(out_certs) > original_out_certs_len) { + X509 *x509 = sk_X509_pop(out_certs); + X509_free(x509); + } + } + + return ret; +} + +void PKCS12_PBE_add(void) {} + +struct pkcs12_st { + uint8_t *ber_bytes; + size_t ber_len; +}; + +PKCS12 *d2i_PKCS12(PKCS12 **out_p12, const uint8_t **ber_bytes, + size_t ber_len) { + PKCS12 *p12; + + p12 = OPENSSL_malloc(sizeof(PKCS12)); + if (!p12) { + return NULL; + } + + p12->ber_bytes = OPENSSL_malloc(ber_len); + if (!p12->ber_bytes) { + OPENSSL_free(p12); + return NULL; + } + + OPENSSL_memcpy(p12->ber_bytes, *ber_bytes, ber_len); + p12->ber_len = ber_len; + *ber_bytes += ber_len; + + if (out_p12) { + PKCS12_free(*out_p12); + + *out_p12 = p12; + } + + return p12; +} + +PKCS12* d2i_PKCS12_bio(BIO *bio, PKCS12 **out_p12) { + size_t used = 0; + BUF_MEM *buf; + const uint8_t *dummy; + static const size_t kMaxSize = 256 * 1024; + PKCS12 *ret = NULL; + + buf = BUF_MEM_new(); + if (buf == NULL) { + return NULL; + } + if (BUF_MEM_grow(buf, 8192) == 0) { + goto out; + } + + for (;;) { + int n = BIO_read(bio, &buf->data[used], buf->length - used); + if (n < 0) { + if (used == 0) { + goto out; + } + // Workaround a bug in node.js. It uses a memory BIO for this in the wrong + // mode. + n = 0; + } + + if (n == 0) { + break; + } + used += n; + + if (used < buf->length) { + continue; + } + + if (buf->length > kMaxSize || + BUF_MEM_grow(buf, buf->length * 2) == 0) { + goto out; + } + } + + dummy = (uint8_t*) buf->data; + ret = d2i_PKCS12(out_p12, &dummy, used); + +out: + BUF_MEM_free(buf); + return ret; +} + +PKCS12* d2i_PKCS12_fp(FILE *fp, PKCS12 **out_p12) { + BIO *bio; + PKCS12 *ret; + + bio = BIO_new_fp(fp, 0 /* don't take ownership */); + if (!bio) { + return NULL; + } + + ret = d2i_PKCS12_bio(bio, out_p12); + BIO_free(bio); + return ret; +} + +int PKCS12_parse(const PKCS12 *p12, const char *password, EVP_PKEY **out_pkey, + X509 **out_cert, STACK_OF(X509) **out_ca_certs) { + CBS ber_bytes; + STACK_OF(X509) *ca_certs = NULL; + char ca_certs_alloced = 0; + + if (out_ca_certs != NULL && *out_ca_certs != NULL) { + ca_certs = *out_ca_certs; + } + + if (!ca_certs) { + ca_certs = sk_X509_new_null(); + if (ca_certs == NULL) { + OPENSSL_PUT_ERROR(PKCS8, ERR_R_MALLOC_FAILURE); + return 0; + } + ca_certs_alloced = 1; + } + + CBS_init(&ber_bytes, p12->ber_bytes, p12->ber_len); + if (!PKCS12_get_key_and_certs(out_pkey, ca_certs, &ber_bytes, password)) { + if (ca_certs_alloced) { + sk_X509_free(ca_certs); + } + return 0; + } + + *out_cert = NULL; + if (sk_X509_num(ca_certs) > 0) { + *out_cert = sk_X509_shift(ca_certs); + } + + if (out_ca_certs) { + *out_ca_certs = ca_certs; + } else { + sk_X509_pop_free(ca_certs, X509_free); + } + + return 1; +} + +int PKCS12_verify_mac(const PKCS12 *p12, const char *password, + int password_len) { + if (password == NULL) { + if (password_len != 0) { + return 0; + } + } else if (password_len != -1 && + (password[password_len] != 0 || + OPENSSL_memchr(password, 0, password_len) != NULL)) { + return 0; + } + + EVP_PKEY *pkey = NULL; + X509 *cert = NULL; + if (!PKCS12_parse(p12, password, &pkey, &cert, NULL)) { + ERR_clear_error(); + return 0; + } + + EVP_PKEY_free(pkey); + X509_free(cert); + + return 1; +} + +void PKCS12_free(PKCS12 *p12) { + if (p12 == NULL) { + return; + } + OPENSSL_free(p12->ber_bytes); + OPENSSL_free(p12); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/pkcs8/pkcs8_x509.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/pkcs8/pkcs8_x509.c.grpc_back new file mode 100644 index 0000000..b3e2d93 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/pkcs8/pkcs8_x509.c.grpc_back @@ -0,0 +1,789 @@ +/* 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "internal.h" +#include "../bytestring/internal.h" +#include "../internal.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) { + 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) + +EVP_PKEY *EVP_PKCS82PKEY(PKCS8_PRIV_KEY_INFO *p8) { + uint8_t *der = NULL; + int der_len = i2d_PKCS8_PRIV_KEY_INFO(p8, &der); + if (der_len < 0) { + return NULL; + } + + CBS cbs; + CBS_init(&cbs, der, (size_t)der_len); + EVP_PKEY *ret = EVP_parse_private_key(&cbs); + if (ret == NULL || CBS_len(&cbs) != 0) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_DECODE_ERROR); + EVP_PKEY_free(ret); + OPENSSL_free(der); + return NULL; + } + + OPENSSL_free(der); + return ret; +} + +PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(EVP_PKEY *pkey) { + CBB cbb; + uint8_t *der = NULL; + size_t der_len; + if (!CBB_init(&cbb, 0) || + !EVP_marshal_private_key(&cbb, pkey) || + !CBB_finish(&cbb, &der, &der_len) || + der_len > LONG_MAX) { + CBB_cleanup(&cbb); + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_ENCODE_ERROR); + goto err; + } + + const uint8_t *p = der; + PKCS8_PRIV_KEY_INFO *p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, (long)der_len); + if (p8 == NULL || p != der + der_len) { + PKCS8_PRIV_KEY_INFO_free(p8); + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_DECODE_ERROR); + goto err; + } + + OPENSSL_free(der); + return p8; + +err: + OPENSSL_free(der); + return NULL; +} + +PKCS8_PRIV_KEY_INFO *PKCS8_decrypt(X509_SIG *pkcs8, const char *pass, + int pass_len_in) { + size_t pass_len; + if (pass_len_in == -1 && pass != NULL) { + pass_len = strlen(pass); + } else { + pass_len = (size_t)pass_len_in; + } + + PKCS8_PRIV_KEY_INFO *ret = NULL; + EVP_PKEY *pkey = NULL; + uint8_t *in = NULL; + + // Convert the legacy ASN.1 object to a byte string. + int in_len = i2d_X509_SIG(pkcs8, &in); + if (in_len < 0) { + goto err; + } + + CBS cbs; + CBS_init(&cbs, in, in_len); + pkey = PKCS8_parse_encrypted_private_key(&cbs, pass, pass_len); + if (pkey == NULL || CBS_len(&cbs) != 0) { + goto err; + } + + ret = EVP_PKEY2PKCS8(pkey); + +err: + OPENSSL_free(in); + EVP_PKEY_free(pkey); + return ret; +} + +X509_SIG *PKCS8_encrypt(int pbe_nid, const EVP_CIPHER *cipher, const char *pass, + int pass_len_in, const uint8_t *salt, size_t salt_len, + int iterations, PKCS8_PRIV_KEY_INFO *p8inf) { + size_t pass_len; + if (pass_len_in == -1 && pass != NULL) { + pass_len = strlen(pass); + } else { + pass_len = (size_t)pass_len_in; + } + + // Parse out the private key. + EVP_PKEY *pkey = EVP_PKCS82PKEY(p8inf); + if (pkey == NULL) { + return NULL; + } + + X509_SIG *ret = NULL; + uint8_t *der = NULL; + size_t der_len; + CBB cbb; + if (!CBB_init(&cbb, 128) || + !PKCS8_marshal_encrypted_private_key(&cbb, pbe_nid, cipher, pass, + pass_len, salt, salt_len, iterations, + pkey) || + !CBB_finish(&cbb, &der, &der_len)) { + CBB_cleanup(&cbb); + goto err; + } + + // Convert back to legacy ASN.1 objects. + const uint8_t *ptr = der; + ret = d2i_X509_SIG(NULL, &ptr, der_len); + if (ret == NULL || ptr != der + der_len) { + OPENSSL_PUT_ERROR(PKCS8, ERR_R_INTERNAL_ERROR); + X509_SIG_free(ret); + ret = NULL; + } + +err: + OPENSSL_free(der); + EVP_PKEY_free(pkey); + return ret; +} + +struct pkcs12_context { + EVP_PKEY **out_key; + STACK_OF(X509) *out_certs; + const char *password; + size_t password_len; +}; + +// PKCS12_handle_sequence parses a BER-encoded SEQUENCE of elements in a PKCS#12 +// structure. +static int PKCS12_handle_sequence( + CBS *sequence, struct pkcs12_context *ctx, + int (*handle_element)(CBS *cbs, struct pkcs12_context *ctx)) { + uint8_t *der_bytes = NULL; + size_t der_len; + CBS in; + int ret = 0; + + // Although a BER->DER conversion is done at the beginning of |PKCS12_parse|, + // the ASN.1 data gets wrapped in OCTETSTRINGs and/or encrypted and the + // conversion cannot see through those wrappings. So each time we step + // through one we need to convert to DER again. + if (!CBS_asn1_ber_to_der(sequence, &der_bytes, &der_len)) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); + return 0; + } + + if (der_bytes != NULL) { + CBS_init(&in, der_bytes, der_len); + } else { + CBS_init(&in, CBS_data(sequence), CBS_len(sequence)); + } + + CBS child; + if (!CBS_get_asn1(&in, &child, CBS_ASN1_SEQUENCE) || + CBS_len(&in) != 0) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); + goto err; + } + + while (CBS_len(&child) > 0) { + CBS element; + if (!CBS_get_asn1(&child, &element, CBS_ASN1_SEQUENCE)) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); + goto err; + } + + if (!handle_element(&element, ctx)) { + goto err; + } + } + + ret = 1; + +err: + OPENSSL_free(der_bytes); + return ret; +} + +// 1.2.840.113549.1.12.10.1.2 +static const uint8_t kPKCS8ShroudedKeyBag[] = { + 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x0c, 0x0a, 0x01, 0x02}; + +// 1.2.840.113549.1.12.10.1.3 +static const uint8_t kCertBag[] = {0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, + 0x01, 0x0c, 0x0a, 0x01, 0x03}; + +// 1.2.840.113549.1.9.22.1 +static const uint8_t kX509Certificate[] = {0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x09, 0x16, 0x01}; + +// PKCS12_handle_safe_bag parses a single SafeBag element in a PKCS#12 +// structure. +static int PKCS12_handle_safe_bag(CBS *safe_bag, struct pkcs12_context *ctx) { + CBS bag_id, wrapped_value; + if (!CBS_get_asn1(safe_bag, &bag_id, CBS_ASN1_OBJECT) || + !CBS_get_asn1(safe_bag, &wrapped_value, + CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0) + /* Ignore the bagAttributes field. */) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); + return 0; + } + + if (CBS_mem_equal(&bag_id, kPKCS8ShroudedKeyBag, + sizeof(kPKCS8ShroudedKeyBag))) { + // See RFC 7292, section 4.2.2. + if (*ctx->out_key) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_MULTIPLE_PRIVATE_KEYS_IN_PKCS12); + return 0; + } + + EVP_PKEY *pkey = PKCS8_parse_encrypted_private_key( + &wrapped_value, ctx->password, ctx->password_len); + if (pkey == NULL) { + return 0; + } + + if (CBS_len(&wrapped_value) != 0) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); + EVP_PKEY_free(pkey); + return 0; + } + + *ctx->out_key = pkey; + return 1; + } + + if (CBS_mem_equal(&bag_id, kCertBag, sizeof(kCertBag))) { + // See RFC 7292, section 4.2.3. + CBS cert_bag, cert_type, wrapped_cert, cert; + if (!CBS_get_asn1(&wrapped_value, &cert_bag, CBS_ASN1_SEQUENCE) || + !CBS_get_asn1(&cert_bag, &cert_type, CBS_ASN1_OBJECT) || + !CBS_get_asn1(&cert_bag, &wrapped_cert, + CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0) || + !CBS_get_asn1(&wrapped_cert, &cert, CBS_ASN1_OCTETSTRING)) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); + return 0; + } + + // Skip unknown certificate types. + if (!CBS_mem_equal(&cert_type, kX509Certificate, + sizeof(kX509Certificate))) { + return 1; + } + + if (CBS_len(&cert) > LONG_MAX) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); + return 0; + } + + const uint8_t *inp = CBS_data(&cert); + X509 *x509 = d2i_X509(NULL, &inp, (long)CBS_len(&cert)); + if (!x509) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); + return 0; + } + + if (inp != CBS_data(&cert) + CBS_len(&cert)) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); + X509_free(x509); + return 0; + } + + if (0 == sk_X509_push(ctx->out_certs, x509)) { + X509_free(x509); + return 0; + } + + return 1; + } + + // Unknown element type - ignore it. + return 1; +} + +// 1.2.840.113549.1.7.1 +static const uint8_t kPKCS7Data[] = {0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x07, 0x01}; + +// 1.2.840.113549.1.7.6 +static const uint8_t kPKCS7EncryptedData[] = {0x2a, 0x86, 0x48, 0x86, 0xf7, + 0x0d, 0x01, 0x07, 0x06}; + +// PKCS12_handle_content_info parses a single PKCS#7 ContentInfo element in a +// PKCS#12 structure. +static int PKCS12_handle_content_info(CBS *content_info, + struct pkcs12_context *ctx) { + CBS content_type, wrapped_contents, contents; + int ret = 0; + uint8_t *storage = NULL; + + if (!CBS_get_asn1(content_info, &content_type, CBS_ASN1_OBJECT) || + !CBS_get_asn1(content_info, &wrapped_contents, + CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0) || + CBS_len(content_info) != 0) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); + goto err; + } + + if (CBS_mem_equal(&content_type, kPKCS7EncryptedData, + sizeof(kPKCS7EncryptedData))) { + // See https://tools.ietf.org/html/rfc2315#section-13. + // + // PKCS#7 encrypted data inside a PKCS#12 structure is generally an + // encrypted certificate bag and it's generally encrypted with 40-bit + // RC2-CBC. + CBS version_bytes, eci, contents_type, ai, encrypted_contents; + uint8_t *out; + size_t out_len; + + if (!CBS_get_asn1(&wrapped_contents, &contents, CBS_ASN1_SEQUENCE) || + !CBS_get_asn1(&contents, &version_bytes, CBS_ASN1_INTEGER) || + // EncryptedContentInfo, see + // https://tools.ietf.org/html/rfc2315#section-10.1 + !CBS_get_asn1(&contents, &eci, CBS_ASN1_SEQUENCE) || + !CBS_get_asn1(&eci, &contents_type, CBS_ASN1_OBJECT) || + // AlgorithmIdentifier, see + // https://tools.ietf.org/html/rfc5280#section-4.1.1.2 + !CBS_get_asn1(&eci, &ai, CBS_ASN1_SEQUENCE) || + !CBS_get_asn1_implicit_string( + &eci, &encrypted_contents, &storage, + CBS_ASN1_CONTEXT_SPECIFIC | 0, CBS_ASN1_OCTETSTRING)) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); + goto err; + } + + if (!CBS_mem_equal(&contents_type, kPKCS7Data, sizeof(kPKCS7Data))) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); + goto err; + } + + if (!pkcs8_pbe_decrypt(&out, &out_len, &ai, ctx->password, + ctx->password_len, CBS_data(&encrypted_contents), + CBS_len(&encrypted_contents))) { + goto err; + } + + CBS safe_contents; + CBS_init(&safe_contents, out, out_len); + ret = PKCS12_handle_sequence(&safe_contents, ctx, PKCS12_handle_safe_bag); + OPENSSL_free(out); + } else if (CBS_mem_equal(&content_type, kPKCS7Data, sizeof(kPKCS7Data))) { + CBS octet_string_contents; + + if (!CBS_get_asn1(&wrapped_contents, &octet_string_contents, + CBS_ASN1_OCTETSTRING)) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); + goto err; + } + + ret = PKCS12_handle_sequence(&octet_string_contents, ctx, + PKCS12_handle_safe_bag); + } else { + // Unknown element type - ignore it. + ret = 1; + } + +err: + OPENSSL_free(storage); + return ret; +} + +int PKCS12_get_key_and_certs(EVP_PKEY **out_key, STACK_OF(X509) *out_certs, + CBS *ber_in, const char *password) { + uint8_t *der_bytes = NULL; + size_t der_len; + CBS in, pfx, mac_data, authsafe, content_type, wrapped_authsafes, authsafes; + uint64_t version; + int ret = 0; + struct pkcs12_context ctx; + const size_t original_out_certs_len = sk_X509_num(out_certs); + + // The input may be in BER format. + if (!CBS_asn1_ber_to_der(ber_in, &der_bytes, &der_len)) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); + return 0; + } + if (der_bytes != NULL) { + CBS_init(&in, der_bytes, der_len); + } else { + CBS_init(&in, CBS_data(ber_in), CBS_len(ber_in)); + } + + *out_key = NULL; + OPENSSL_memset(&ctx, 0, sizeof(ctx)); + + // See ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-12/pkcs-12v1.pdf, section + // four. + if (!CBS_get_asn1(&in, &pfx, CBS_ASN1_SEQUENCE) || + CBS_len(&in) != 0 || + !CBS_get_asn1_uint64(&pfx, &version)) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); + goto err; + } + + if (version < 3) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_VERSION); + goto err; + } + + if (!CBS_get_asn1(&pfx, &authsafe, CBS_ASN1_SEQUENCE)) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); + goto err; + } + + if (CBS_len(&pfx) == 0) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_MISSING_MAC); + goto err; + } + + if (!CBS_get_asn1(&pfx, &mac_data, CBS_ASN1_SEQUENCE)) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); + goto err; + } + + // authsafe is a PKCS#7 ContentInfo. See + // https://tools.ietf.org/html/rfc2315#section-7. + if (!CBS_get_asn1(&authsafe, &content_type, CBS_ASN1_OBJECT) || + !CBS_get_asn1(&authsafe, &wrapped_authsafes, + CBS_ASN1_CONTEXT_SPECIFIC | CBS_ASN1_CONSTRUCTED | 0)) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); + goto err; + } + + // The content type can either be data or signedData. The latter indicates + // that it's signed by a public key, which isn't supported. + if (!CBS_mem_equal(&content_type, kPKCS7Data, sizeof(kPKCS7Data))) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_PKCS12_PUBLIC_KEY_INTEGRITY_NOT_SUPPORTED); + goto err; + } + + if (!CBS_get_asn1(&wrapped_authsafes, &authsafes, CBS_ASN1_OCTETSTRING)) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); + goto err; + } + + ctx.out_key = out_key; + ctx.out_certs = out_certs; + ctx.password = password; + ctx.password_len = password != NULL ? strlen(password) : 0; + + // Verify the MAC. + { + CBS mac, salt, expected_mac; + if (!CBS_get_asn1(&mac_data, &mac, CBS_ASN1_SEQUENCE)) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); + goto err; + } + + const EVP_MD *md = EVP_parse_digest_algorithm(&mac); + if (md == NULL) { + goto err; + } + + if (!CBS_get_asn1(&mac, &expected_mac, CBS_ASN1_OCTETSTRING) || + !CBS_get_asn1(&mac_data, &salt, CBS_ASN1_OCTETSTRING)) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); + goto err; + } + + // The iteration count is optional and the default is one. + uint64_t iterations = 1; + if (CBS_len(&mac_data) > 0) { + if (!CBS_get_asn1_uint64(&mac_data, &iterations) || + iterations > UINT_MAX) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_BAD_PKCS12_DATA); + goto err; + } + } + + uint8_t hmac_key[EVP_MAX_MD_SIZE]; + if (!pkcs12_key_gen(ctx.password, ctx.password_len, CBS_data(&salt), + CBS_len(&salt), PKCS12_MAC_ID, iterations, + EVP_MD_size(md), hmac_key, md)) { + goto err; + } + + uint8_t hmac[EVP_MAX_MD_SIZE]; + unsigned hmac_len; + if (NULL == HMAC(md, hmac_key, EVP_MD_size(md), CBS_data(&authsafes), + CBS_len(&authsafes), hmac, &hmac_len)) { + goto err; + } + + if (!CBS_mem_equal(&expected_mac, hmac, hmac_len)) { + OPENSSL_PUT_ERROR(PKCS8, PKCS8_R_INCORRECT_PASSWORD); + goto err; + } + } + + // authsafes contains a series of PKCS#7 ContentInfos. + if (!PKCS12_handle_sequence(&authsafes, &ctx, PKCS12_handle_content_info)) { + goto err; + } + + ret = 1; + +err: + OPENSSL_free(der_bytes); + if (!ret) { + EVP_PKEY_free(*out_key); + *out_key = NULL; + while (sk_X509_num(out_certs) > original_out_certs_len) { + X509 *x509 = sk_X509_pop(out_certs); + X509_free(x509); + } + } + + return ret; +} + +void PKCS12_PBE_add(void) {} + +struct pkcs12_st { + uint8_t *ber_bytes; + size_t ber_len; +}; + +PKCS12 *d2i_PKCS12(PKCS12 **out_p12, const uint8_t **ber_bytes, + size_t ber_len) { + PKCS12 *p12; + + p12 = OPENSSL_malloc(sizeof(PKCS12)); + if (!p12) { + return NULL; + } + + p12->ber_bytes = OPENSSL_malloc(ber_len); + if (!p12->ber_bytes) { + OPENSSL_free(p12); + return NULL; + } + + OPENSSL_memcpy(p12->ber_bytes, *ber_bytes, ber_len); + p12->ber_len = ber_len; + *ber_bytes += ber_len; + + if (out_p12) { + PKCS12_free(*out_p12); + + *out_p12 = p12; + } + + return p12; +} + +PKCS12* d2i_PKCS12_bio(BIO *bio, PKCS12 **out_p12) { + size_t used = 0; + BUF_MEM *buf; + const uint8_t *dummy; + static const size_t kMaxSize = 256 * 1024; + PKCS12 *ret = NULL; + + buf = BUF_MEM_new(); + if (buf == NULL) { + return NULL; + } + if (BUF_MEM_grow(buf, 8192) == 0) { + goto out; + } + + for (;;) { + int n = BIO_read(bio, &buf->data[used], buf->length - used); + if (n < 0) { + if (used == 0) { + goto out; + } + // Workaround a bug in node.js. It uses a memory BIO for this in the wrong + // mode. + n = 0; + } + + if (n == 0) { + break; + } + used += n; + + if (used < buf->length) { + continue; + } + + if (buf->length > kMaxSize || + BUF_MEM_grow(buf, buf->length * 2) == 0) { + goto out; + } + } + + dummy = (uint8_t*) buf->data; + ret = d2i_PKCS12(out_p12, &dummy, used); + +out: + BUF_MEM_free(buf); + return ret; +} + +PKCS12* d2i_PKCS12_fp(FILE *fp, PKCS12 **out_p12) { + BIO *bio; + PKCS12 *ret; + + bio = BIO_new_fp(fp, 0 /* don't take ownership */); + if (!bio) { + return NULL; + } + + ret = d2i_PKCS12_bio(bio, out_p12); + BIO_free(bio); + return ret; +} + +int PKCS12_parse(const PKCS12 *p12, const char *password, EVP_PKEY **out_pkey, + X509 **out_cert, STACK_OF(X509) **out_ca_certs) { + CBS ber_bytes; + STACK_OF(X509) *ca_certs = NULL; + char ca_certs_alloced = 0; + + if (out_ca_certs != NULL && *out_ca_certs != NULL) { + ca_certs = *out_ca_certs; + } + + if (!ca_certs) { + ca_certs = sk_X509_new_null(); + if (ca_certs == NULL) { + OPENSSL_PUT_ERROR(PKCS8, ERR_R_MALLOC_FAILURE); + return 0; + } + ca_certs_alloced = 1; + } + + CBS_init(&ber_bytes, p12->ber_bytes, p12->ber_len); + if (!PKCS12_get_key_and_certs(out_pkey, ca_certs, &ber_bytes, password)) { + if (ca_certs_alloced) { + sk_X509_free(ca_certs); + } + return 0; + } + + *out_cert = NULL; + if (sk_X509_num(ca_certs) > 0) { + *out_cert = sk_X509_shift(ca_certs); + } + + if (out_ca_certs) { + *out_ca_certs = ca_certs; + } else { + sk_X509_pop_free(ca_certs, X509_free); + } + + return 1; +} + +int PKCS12_verify_mac(const PKCS12 *p12, const char *password, + int password_len) { + if (password == NULL) { + if (password_len != 0) { + return 0; + } + } else if (password_len != -1 && + (password[password_len] != 0 || + OPENSSL_memchr(password, 0, password_len) != NULL)) { + return 0; + } + + EVP_PKEY *pkey = NULL; + X509 *cert = NULL; + if (!PKCS12_parse(p12, password, &pkey, &cert, NULL)) { + ERR_clear_error(); + return 0; + } + + EVP_PKEY_free(pkey); + X509_free(cert); + + return 1; +} + +void PKCS12_free(PKCS12 *p12) { + if (p12 == NULL) { + return; + } + OPENSSL_free(p12->ber_bytes); + OPENSSL_free(p12); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/poly1305/internal.h b/FoodApp/Pods/BoringSSL-GRPC/crypto/poly1305/internal.h new file mode 100644 index 0000000..fe4708c --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/poly1305/internal.h @@ -0,0 +1,41 @@ +/* Copyright (c) 2016, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_POLY1305_INTERNAL_H +#define OPENSSL_HEADER_POLY1305_INTERNAL_H + +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +#if defined(OPENSSL_ARM) && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_APPLE) +#define OPENSSL_POLY1305_NEON + +void CRYPTO_poly1305_init_neon(poly1305_state *state, const uint8_t key[32]); + +void CRYPTO_poly1305_update_neon(poly1305_state *state, const uint8_t *in, + size_t in_len); + +void CRYPTO_poly1305_finish_neon(poly1305_state *state, uint8_t mac[16]); +#endif + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_POLY1305_INTERNAL_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/poly1305/internal.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/poly1305/internal.h.grpc_back new file mode 100644 index 0000000..251b1f4 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/poly1305/internal.h.grpc_back @@ -0,0 +1,41 @@ +/* Copyright (c) 2016, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_POLY1305_INTERNAL_H +#define OPENSSL_HEADER_POLY1305_INTERNAL_H + +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +#if defined(OPENSSL_ARM) && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_APPLE) +#define OPENSSL_POLY1305_NEON + +void CRYPTO_poly1305_init_neon(poly1305_state *state, const uint8_t key[32]); + +void CRYPTO_poly1305_update_neon(poly1305_state *state, const uint8_t *in, + size_t in_len); + +void CRYPTO_poly1305_finish_neon(poly1305_state *state, uint8_t mac[16]); +#endif + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_POLY1305_INTERNAL_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/poly1305/poly1305.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/poly1305/poly1305.c new file mode 100644 index 0000000..08e3a98 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/poly1305/poly1305.c @@ -0,0 +1,318 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +// This implementation of poly1305 is by Andrew Moon +// (https://github.com/floodyberry/poly1305-donna) and released as public +// domain. + +#include + +#include + +#include + +#include "internal.h" +#include "../internal.h" + + +#if defined(OPENSSL_WINDOWS) || !defined(OPENSSL_X86_64) + +// We can assume little-endian. +static uint32_t U8TO32_LE(const uint8_t *m) { + uint32_t r; + OPENSSL_memcpy(&r, m, sizeof(r)); + return r; +} + +static void U32TO8_LE(uint8_t *m, uint32_t v) { + OPENSSL_memcpy(m, &v, sizeof(v)); +} + +static uint64_t mul32x32_64(uint32_t a, uint32_t b) { return (uint64_t)a * b; } + +struct poly1305_state_st { + uint32_t r0, r1, r2, r3, r4; + uint32_t s1, s2, s3, s4; + uint32_t h0, h1, h2, h3, h4; + uint8_t buf[16]; + unsigned int buf_used; + uint8_t key[16]; +}; + +static inline struct poly1305_state_st *poly1305_aligned_state( + poly1305_state *state) { + return (struct poly1305_state_st *)(((uintptr_t)state + 63) & ~63); +} + +// poly1305_blocks updates |state| given some amount of input data. This +// function may only be called with a |len| that is not a multiple of 16 at the +// end of the data. Otherwise the input must be buffered into 16 byte blocks. +static void poly1305_update(struct poly1305_state_st *state, const uint8_t *in, + size_t len) { + uint32_t t0, t1, t2, t3; + uint64_t t[5]; + uint32_t b; + uint64_t c; + size_t j; + uint8_t mp[16]; + + if (len < 16) { + goto poly1305_donna_atmost15bytes; + } + +poly1305_donna_16bytes: + t0 = U8TO32_LE(in); + t1 = U8TO32_LE(in + 4); + t2 = U8TO32_LE(in + 8); + t3 = U8TO32_LE(in + 12); + + in += 16; + len -= 16; + + state->h0 += t0 & 0x3ffffff; + state->h1 += ((((uint64_t)t1 << 32) | t0) >> 26) & 0x3ffffff; + state->h2 += ((((uint64_t)t2 << 32) | t1) >> 20) & 0x3ffffff; + state->h3 += ((((uint64_t)t3 << 32) | t2) >> 14) & 0x3ffffff; + state->h4 += (t3 >> 8) | (1 << 24); + +poly1305_donna_mul: + t[0] = mul32x32_64(state->h0, state->r0) + mul32x32_64(state->h1, state->s4) + + mul32x32_64(state->h2, state->s3) + mul32x32_64(state->h3, state->s2) + + mul32x32_64(state->h4, state->s1); + t[1] = mul32x32_64(state->h0, state->r1) + mul32x32_64(state->h1, state->r0) + + mul32x32_64(state->h2, state->s4) + mul32x32_64(state->h3, state->s3) + + mul32x32_64(state->h4, state->s2); + t[2] = mul32x32_64(state->h0, state->r2) + mul32x32_64(state->h1, state->r1) + + mul32x32_64(state->h2, state->r0) + mul32x32_64(state->h3, state->s4) + + mul32x32_64(state->h4, state->s3); + t[3] = mul32x32_64(state->h0, state->r3) + mul32x32_64(state->h1, state->r2) + + mul32x32_64(state->h2, state->r1) + mul32x32_64(state->h3, state->r0) + + mul32x32_64(state->h4, state->s4); + t[4] = mul32x32_64(state->h0, state->r4) + mul32x32_64(state->h1, state->r3) + + mul32x32_64(state->h2, state->r2) + mul32x32_64(state->h3, state->r1) + + mul32x32_64(state->h4, state->r0); + + state->h0 = (uint32_t)t[0] & 0x3ffffff; + c = (t[0] >> 26); + t[1] += c; + state->h1 = (uint32_t)t[1] & 0x3ffffff; + b = (uint32_t)(t[1] >> 26); + t[2] += b; + state->h2 = (uint32_t)t[2] & 0x3ffffff; + b = (uint32_t)(t[2] >> 26); + t[3] += b; + state->h3 = (uint32_t)t[3] & 0x3ffffff; + b = (uint32_t)(t[3] >> 26); + t[4] += b; + state->h4 = (uint32_t)t[4] & 0x3ffffff; + b = (uint32_t)(t[4] >> 26); + state->h0 += b * 5; + + if (len >= 16) { + goto poly1305_donna_16bytes; + } + +// final bytes +poly1305_donna_atmost15bytes: + if (!len) { + return; + } + + for (j = 0; j < len; j++) { + mp[j] = in[j]; + } + mp[j++] = 1; + for (; j < 16; j++) { + mp[j] = 0; + } + len = 0; + + t0 = U8TO32_LE(mp + 0); + t1 = U8TO32_LE(mp + 4); + t2 = U8TO32_LE(mp + 8); + t3 = U8TO32_LE(mp + 12); + + state->h0 += t0 & 0x3ffffff; + state->h1 += ((((uint64_t)t1 << 32) | t0) >> 26) & 0x3ffffff; + state->h2 += ((((uint64_t)t2 << 32) | t1) >> 20) & 0x3ffffff; + state->h3 += ((((uint64_t)t3 << 32) | t2) >> 14) & 0x3ffffff; + state->h4 += (t3 >> 8); + + goto poly1305_donna_mul; +} + +void CRYPTO_poly1305_init(poly1305_state *statep, const uint8_t key[32]) { + struct poly1305_state_st *state = poly1305_aligned_state(statep); + uint32_t t0, t1, t2, t3; + +#if defined(OPENSSL_POLY1305_NEON) + if (CRYPTO_is_NEON_capable()) { + CRYPTO_poly1305_init_neon(statep, key); + return; + } +#endif + + t0 = U8TO32_LE(key + 0); + t1 = U8TO32_LE(key + 4); + t2 = U8TO32_LE(key + 8); + t3 = U8TO32_LE(key + 12); + + // precompute multipliers + state->r0 = t0 & 0x3ffffff; + t0 >>= 26; + t0 |= t1 << 6; + state->r1 = t0 & 0x3ffff03; + t1 >>= 20; + t1 |= t2 << 12; + state->r2 = t1 & 0x3ffc0ff; + t2 >>= 14; + t2 |= t3 << 18; + state->r3 = t2 & 0x3f03fff; + t3 >>= 8; + state->r4 = t3 & 0x00fffff; + + state->s1 = state->r1 * 5; + state->s2 = state->r2 * 5; + state->s3 = state->r3 * 5; + state->s4 = state->r4 * 5; + + // init state + state->h0 = 0; + state->h1 = 0; + state->h2 = 0; + state->h3 = 0; + state->h4 = 0; + + state->buf_used = 0; + OPENSSL_memcpy(state->key, key + 16, sizeof(state->key)); +} + +void CRYPTO_poly1305_update(poly1305_state *statep, const uint8_t *in, + size_t in_len) { + unsigned int i; + struct poly1305_state_st *state = poly1305_aligned_state(statep); + +#if defined(OPENSSL_POLY1305_NEON) + if (CRYPTO_is_NEON_capable()) { + CRYPTO_poly1305_update_neon(statep, in, in_len); + return; + } +#endif + + if (state->buf_used) { + unsigned todo = 16 - state->buf_used; + if (todo > in_len) { + todo = (unsigned)in_len; + } + for (i = 0; i < todo; i++) { + state->buf[state->buf_used + i] = in[i]; + } + state->buf_used += todo; + in_len -= todo; + in += todo; + + if (state->buf_used == 16) { + poly1305_update(state, state->buf, 16); + state->buf_used = 0; + } + } + + if (in_len >= 16) { + size_t todo = in_len & ~0xf; + poly1305_update(state, in, todo); + in += todo; + in_len &= 0xf; + } + + if (in_len) { + for (i = 0; i < in_len; i++) { + state->buf[i] = in[i]; + } + state->buf_used = (unsigned)in_len; + } +} + +void CRYPTO_poly1305_finish(poly1305_state *statep, uint8_t mac[16]) { + struct poly1305_state_st *state = poly1305_aligned_state(statep); + uint64_t f0, f1, f2, f3; + uint32_t g0, g1, g2, g3, g4; + uint32_t b, nb; + +#if defined(OPENSSL_POLY1305_NEON) + if (CRYPTO_is_NEON_capable()) { + CRYPTO_poly1305_finish_neon(statep, mac); + return; + } +#endif + + if (state->buf_used) { + poly1305_update(state, state->buf, state->buf_used); + } + + b = state->h0 >> 26; + state->h0 = state->h0 & 0x3ffffff; + state->h1 += b; + b = state->h1 >> 26; + state->h1 = state->h1 & 0x3ffffff; + state->h2 += b; + b = state->h2 >> 26; + state->h2 = state->h2 & 0x3ffffff; + state->h3 += b; + b = state->h3 >> 26; + state->h3 = state->h3 & 0x3ffffff; + state->h4 += b; + b = state->h4 >> 26; + state->h4 = state->h4 & 0x3ffffff; + state->h0 += b * 5; + + g0 = state->h0 + 5; + b = g0 >> 26; + g0 &= 0x3ffffff; + g1 = state->h1 + b; + b = g1 >> 26; + g1 &= 0x3ffffff; + g2 = state->h2 + b; + b = g2 >> 26; + g2 &= 0x3ffffff; + g3 = state->h3 + b; + b = g3 >> 26; + g3 &= 0x3ffffff; + g4 = state->h4 + b - (1 << 26); + + b = (g4 >> 31) - 1; + nb = ~b; + state->h0 = (state->h0 & nb) | (g0 & b); + state->h1 = (state->h1 & nb) | (g1 & b); + state->h2 = (state->h2 & nb) | (g2 & b); + state->h3 = (state->h3 & nb) | (g3 & b); + state->h4 = (state->h4 & nb) | (g4 & b); + + f0 = ((state->h0) | (state->h1 << 26)) + (uint64_t)U8TO32_LE(&state->key[0]); + f1 = ((state->h1 >> 6) | (state->h2 << 20)) + + (uint64_t)U8TO32_LE(&state->key[4]); + f2 = ((state->h2 >> 12) | (state->h3 << 14)) + + (uint64_t)U8TO32_LE(&state->key[8]); + f3 = ((state->h3 >> 18) | (state->h4 << 8)) + + (uint64_t)U8TO32_LE(&state->key[12]); + + U32TO8_LE(&mac[0], f0); + f1 += (f0 >> 32); + U32TO8_LE(&mac[4], f1); + f2 += (f1 >> 32); + U32TO8_LE(&mac[8], f2); + f3 += (f2 >> 32); + U32TO8_LE(&mac[12], f3); +} + +#endif // OPENSSL_WINDOWS || !OPENSSL_X86_64 diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/poly1305/poly1305.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/poly1305/poly1305.c.grpc_back new file mode 100644 index 0000000..c3e9272 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/poly1305/poly1305.c.grpc_back @@ -0,0 +1,318 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +// This implementation of poly1305 is by Andrew Moon +// (https://github.com/floodyberry/poly1305-donna) and released as public +// domain. + +#include + +#include + +#include + +#include "internal.h" +#include "../internal.h" + + +#if defined(OPENSSL_WINDOWS) || !defined(OPENSSL_X86_64) + +// We can assume little-endian. +static uint32_t U8TO32_LE(const uint8_t *m) { + uint32_t r; + OPENSSL_memcpy(&r, m, sizeof(r)); + return r; +} + +static void U32TO8_LE(uint8_t *m, uint32_t v) { + OPENSSL_memcpy(m, &v, sizeof(v)); +} + +static uint64_t mul32x32_64(uint32_t a, uint32_t b) { return (uint64_t)a * b; } + +struct poly1305_state_st { + uint32_t r0, r1, r2, r3, r4; + uint32_t s1, s2, s3, s4; + uint32_t h0, h1, h2, h3, h4; + uint8_t buf[16]; + unsigned int buf_used; + uint8_t key[16]; +}; + +static inline struct poly1305_state_st *poly1305_aligned_state( + poly1305_state *state) { + return (struct poly1305_state_st *)(((uintptr_t)state + 63) & ~63); +} + +// poly1305_blocks updates |state| given some amount of input data. This +// function may only be called with a |len| that is not a multiple of 16 at the +// end of the data. Otherwise the input must be buffered into 16 byte blocks. +static void poly1305_update(struct poly1305_state_st *state, const uint8_t *in, + size_t len) { + uint32_t t0, t1, t2, t3; + uint64_t t[5]; + uint32_t b; + uint64_t c; + size_t j; + uint8_t mp[16]; + + if (len < 16) { + goto poly1305_donna_atmost15bytes; + } + +poly1305_donna_16bytes: + t0 = U8TO32_LE(in); + t1 = U8TO32_LE(in + 4); + t2 = U8TO32_LE(in + 8); + t3 = U8TO32_LE(in + 12); + + in += 16; + len -= 16; + + state->h0 += t0 & 0x3ffffff; + state->h1 += ((((uint64_t)t1 << 32) | t0) >> 26) & 0x3ffffff; + state->h2 += ((((uint64_t)t2 << 32) | t1) >> 20) & 0x3ffffff; + state->h3 += ((((uint64_t)t3 << 32) | t2) >> 14) & 0x3ffffff; + state->h4 += (t3 >> 8) | (1 << 24); + +poly1305_donna_mul: + t[0] = mul32x32_64(state->h0, state->r0) + mul32x32_64(state->h1, state->s4) + + mul32x32_64(state->h2, state->s3) + mul32x32_64(state->h3, state->s2) + + mul32x32_64(state->h4, state->s1); + t[1] = mul32x32_64(state->h0, state->r1) + mul32x32_64(state->h1, state->r0) + + mul32x32_64(state->h2, state->s4) + mul32x32_64(state->h3, state->s3) + + mul32x32_64(state->h4, state->s2); + t[2] = mul32x32_64(state->h0, state->r2) + mul32x32_64(state->h1, state->r1) + + mul32x32_64(state->h2, state->r0) + mul32x32_64(state->h3, state->s4) + + mul32x32_64(state->h4, state->s3); + t[3] = mul32x32_64(state->h0, state->r3) + mul32x32_64(state->h1, state->r2) + + mul32x32_64(state->h2, state->r1) + mul32x32_64(state->h3, state->r0) + + mul32x32_64(state->h4, state->s4); + t[4] = mul32x32_64(state->h0, state->r4) + mul32x32_64(state->h1, state->r3) + + mul32x32_64(state->h2, state->r2) + mul32x32_64(state->h3, state->r1) + + mul32x32_64(state->h4, state->r0); + + state->h0 = (uint32_t)t[0] & 0x3ffffff; + c = (t[0] >> 26); + t[1] += c; + state->h1 = (uint32_t)t[1] & 0x3ffffff; + b = (uint32_t)(t[1] >> 26); + t[2] += b; + state->h2 = (uint32_t)t[2] & 0x3ffffff; + b = (uint32_t)(t[2] >> 26); + t[3] += b; + state->h3 = (uint32_t)t[3] & 0x3ffffff; + b = (uint32_t)(t[3] >> 26); + t[4] += b; + state->h4 = (uint32_t)t[4] & 0x3ffffff; + b = (uint32_t)(t[4] >> 26); + state->h0 += b * 5; + + if (len >= 16) { + goto poly1305_donna_16bytes; + } + +// final bytes +poly1305_donna_atmost15bytes: + if (!len) { + return; + } + + for (j = 0; j < len; j++) { + mp[j] = in[j]; + } + mp[j++] = 1; + for (; j < 16; j++) { + mp[j] = 0; + } + len = 0; + + t0 = U8TO32_LE(mp + 0); + t1 = U8TO32_LE(mp + 4); + t2 = U8TO32_LE(mp + 8); + t3 = U8TO32_LE(mp + 12); + + state->h0 += t0 & 0x3ffffff; + state->h1 += ((((uint64_t)t1 << 32) | t0) >> 26) & 0x3ffffff; + state->h2 += ((((uint64_t)t2 << 32) | t1) >> 20) & 0x3ffffff; + state->h3 += ((((uint64_t)t3 << 32) | t2) >> 14) & 0x3ffffff; + state->h4 += (t3 >> 8); + + goto poly1305_donna_mul; +} + +void CRYPTO_poly1305_init(poly1305_state *statep, const uint8_t key[32]) { + struct poly1305_state_st *state = poly1305_aligned_state(statep); + uint32_t t0, t1, t2, t3; + +#if defined(OPENSSL_POLY1305_NEON) + if (CRYPTO_is_NEON_capable()) { + CRYPTO_poly1305_init_neon(statep, key); + return; + } +#endif + + t0 = U8TO32_LE(key + 0); + t1 = U8TO32_LE(key + 4); + t2 = U8TO32_LE(key + 8); + t3 = U8TO32_LE(key + 12); + + // precompute multipliers + state->r0 = t0 & 0x3ffffff; + t0 >>= 26; + t0 |= t1 << 6; + state->r1 = t0 & 0x3ffff03; + t1 >>= 20; + t1 |= t2 << 12; + state->r2 = t1 & 0x3ffc0ff; + t2 >>= 14; + t2 |= t3 << 18; + state->r3 = t2 & 0x3f03fff; + t3 >>= 8; + state->r4 = t3 & 0x00fffff; + + state->s1 = state->r1 * 5; + state->s2 = state->r2 * 5; + state->s3 = state->r3 * 5; + state->s4 = state->r4 * 5; + + // init state + state->h0 = 0; + state->h1 = 0; + state->h2 = 0; + state->h3 = 0; + state->h4 = 0; + + state->buf_used = 0; + OPENSSL_memcpy(state->key, key + 16, sizeof(state->key)); +} + +void CRYPTO_poly1305_update(poly1305_state *statep, const uint8_t *in, + size_t in_len) { + unsigned int i; + struct poly1305_state_st *state = poly1305_aligned_state(statep); + +#if defined(OPENSSL_POLY1305_NEON) + if (CRYPTO_is_NEON_capable()) { + CRYPTO_poly1305_update_neon(statep, in, in_len); + return; + } +#endif + + if (state->buf_used) { + unsigned todo = 16 - state->buf_used; + if (todo > in_len) { + todo = (unsigned)in_len; + } + for (i = 0; i < todo; i++) { + state->buf[state->buf_used + i] = in[i]; + } + state->buf_used += todo; + in_len -= todo; + in += todo; + + if (state->buf_used == 16) { + poly1305_update(state, state->buf, 16); + state->buf_used = 0; + } + } + + if (in_len >= 16) { + size_t todo = in_len & ~0xf; + poly1305_update(state, in, todo); + in += todo; + in_len &= 0xf; + } + + if (in_len) { + for (i = 0; i < in_len; i++) { + state->buf[i] = in[i]; + } + state->buf_used = (unsigned)in_len; + } +} + +void CRYPTO_poly1305_finish(poly1305_state *statep, uint8_t mac[16]) { + struct poly1305_state_st *state = poly1305_aligned_state(statep); + uint64_t f0, f1, f2, f3; + uint32_t g0, g1, g2, g3, g4; + uint32_t b, nb; + +#if defined(OPENSSL_POLY1305_NEON) + if (CRYPTO_is_NEON_capable()) { + CRYPTO_poly1305_finish_neon(statep, mac); + return; + } +#endif + + if (state->buf_used) { + poly1305_update(state, state->buf, state->buf_used); + } + + b = state->h0 >> 26; + state->h0 = state->h0 & 0x3ffffff; + state->h1 += b; + b = state->h1 >> 26; + state->h1 = state->h1 & 0x3ffffff; + state->h2 += b; + b = state->h2 >> 26; + state->h2 = state->h2 & 0x3ffffff; + state->h3 += b; + b = state->h3 >> 26; + state->h3 = state->h3 & 0x3ffffff; + state->h4 += b; + b = state->h4 >> 26; + state->h4 = state->h4 & 0x3ffffff; + state->h0 += b * 5; + + g0 = state->h0 + 5; + b = g0 >> 26; + g0 &= 0x3ffffff; + g1 = state->h1 + b; + b = g1 >> 26; + g1 &= 0x3ffffff; + g2 = state->h2 + b; + b = g2 >> 26; + g2 &= 0x3ffffff; + g3 = state->h3 + b; + b = g3 >> 26; + g3 &= 0x3ffffff; + g4 = state->h4 + b - (1 << 26); + + b = (g4 >> 31) - 1; + nb = ~b; + state->h0 = (state->h0 & nb) | (g0 & b); + state->h1 = (state->h1 & nb) | (g1 & b); + state->h2 = (state->h2 & nb) | (g2 & b); + state->h3 = (state->h3 & nb) | (g3 & b); + state->h4 = (state->h4 & nb) | (g4 & b); + + f0 = ((state->h0) | (state->h1 << 26)) + (uint64_t)U8TO32_LE(&state->key[0]); + f1 = ((state->h1 >> 6) | (state->h2 << 20)) + + (uint64_t)U8TO32_LE(&state->key[4]); + f2 = ((state->h2 >> 12) | (state->h3 << 14)) + + (uint64_t)U8TO32_LE(&state->key[8]); + f3 = ((state->h3 >> 18) | (state->h4 << 8)) + + (uint64_t)U8TO32_LE(&state->key[12]); + + U32TO8_LE(&mac[0], f0); + f1 += (f0 >> 32); + U32TO8_LE(&mac[4], f1); + f2 += (f1 >> 32); + U32TO8_LE(&mac[8], f2); + f3 += (f2 >> 32); + U32TO8_LE(&mac[12], f3); +} + +#endif // OPENSSL_WINDOWS || !OPENSSL_X86_64 diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/poly1305/poly1305_arm.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/poly1305/poly1305_arm.c new file mode 100644 index 0000000..8ce679f --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/poly1305/poly1305_arm.c @@ -0,0 +1,304 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +// This implementation was taken from the public domain, neon2 version in +// SUPERCOP by D. J. Bernstein and Peter Schwabe. + +#include + +#include + +#include "../internal.h" +#include "internal.h" + + +#if defined(OPENSSL_POLY1305_NEON) + +typedef struct { + uint32_t v[12]; // for alignment; only using 10 +} fe1305x2; + +#define addmulmod openssl_poly1305_neon2_addmulmod +#define blocks openssl_poly1305_neon2_blocks + +extern void addmulmod(fe1305x2 *r, const fe1305x2 *x, const fe1305x2 *y, + const fe1305x2 *c); + +extern int blocks(fe1305x2 *h, const fe1305x2 *precomp, const uint8_t *in, + unsigned int inlen); + +static void freeze(fe1305x2 *r) { + int i; + + uint32_t x0 = r->v[0]; + uint32_t x1 = r->v[2]; + uint32_t x2 = r->v[4]; + uint32_t x3 = r->v[6]; + uint32_t x4 = r->v[8]; + uint32_t y0; + uint32_t y1; + uint32_t y2; + uint32_t y3; + uint32_t y4; + uint32_t swap; + + for (i = 0; i < 3; ++i) { + x1 += x0 >> 26; + x0 &= 0x3ffffff; + x2 += x1 >> 26; + x1 &= 0x3ffffff; + x3 += x2 >> 26; + x2 &= 0x3ffffff; + x4 += x3 >> 26; + x3 &= 0x3ffffff; + x0 += 5 * (x4 >> 26); + x4 &= 0x3ffffff; + } + + y0 = x0 + 5; + y1 = x1 + (y0 >> 26); + y0 &= 0x3ffffff; + y2 = x2 + (y1 >> 26); + y1 &= 0x3ffffff; + y3 = x3 + (y2 >> 26); + y2 &= 0x3ffffff; + y4 = x4 + (y3 >> 26); + y3 &= 0x3ffffff; + swap = -(y4 >> 26); + y4 &= 0x3ffffff; + + y0 ^= x0; + y1 ^= x1; + y2 ^= x2; + y3 ^= x3; + y4 ^= x4; + + y0 &= swap; + y1 &= swap; + y2 &= swap; + y3 &= swap; + y4 &= swap; + + y0 ^= x0; + y1 ^= x1; + y2 ^= x2; + y3 ^= x3; + y4 ^= x4; + + r->v[0] = y0; + r->v[2] = y1; + r->v[4] = y2; + r->v[6] = y3; + r->v[8] = y4; +} + +static void fe1305x2_tobytearray(uint8_t *r, fe1305x2 *x) { + uint32_t x0 = x->v[0]; + uint32_t x1 = x->v[2]; + uint32_t x2 = x->v[4]; + uint32_t x3 = x->v[6]; + uint32_t x4 = x->v[8]; + + x1 += x0 >> 26; + x0 &= 0x3ffffff; + x2 += x1 >> 26; + x1 &= 0x3ffffff; + x3 += x2 >> 26; + x2 &= 0x3ffffff; + x4 += x3 >> 26; + x3 &= 0x3ffffff; + + *(uint32_t *)r = x0 + (x1 << 26); + *(uint32_t *)(r + 4) = (x1 >> 6) + (x2 << 20); + *(uint32_t *)(r + 8) = (x2 >> 12) + (x3 << 14); + *(uint32_t *)(r + 12) = (x3 >> 18) + (x4 << 8); +} + +// load32 exists to avoid breaking strict aliasing rules in +// fe1305x2_frombytearray. +static uint32_t load32(uint8_t *t) { + uint32_t tmp; + OPENSSL_memcpy(&tmp, t, sizeof(tmp)); + return tmp; +} + +static void fe1305x2_frombytearray(fe1305x2 *r, const uint8_t *x, + unsigned long long xlen) { + unsigned i; + uint8_t t[17]; + + for (i = 0; (i < 16) && (i < xlen); i++) { + t[i] = x[i]; + } + xlen -= i; + x += i; + t[i++] = 1; + for (; i < 17; i++) { + t[i] = 0; + } + + r->v[0] = 0x3ffffff & load32(t); + r->v[2] = 0x3ffffff & (load32(t + 3) >> 2); + r->v[4] = 0x3ffffff & (load32(t + 6) >> 4); + r->v[6] = 0x3ffffff & (load32(t + 9) >> 6); + r->v[8] = load32(t + 13); + + if (xlen) { + for (i = 0; (i < 16) && (i < xlen); i++) { + t[i] = x[i]; + } + t[i++] = 1; + for (; i < 17; i++) { + t[i] = 0; + } + + r->v[1] = 0x3ffffff & load32(t); + r->v[3] = 0x3ffffff & (load32(t + 3) >> 2); + r->v[5] = 0x3ffffff & (load32(t + 6) >> 4); + r->v[7] = 0x3ffffff & (load32(t + 9) >> 6); + r->v[9] = load32(t + 13); + } else { + r->v[1] = r->v[3] = r->v[5] = r->v[7] = r->v[9] = 0; + } +} + +static const alignas(16) fe1305x2 zero; + +struct poly1305_state_st { + uint8_t data[sizeof(fe1305x2[5]) + 128]; + uint8_t buf[32]; + unsigned int buf_used; + uint8_t key[16]; +}; + +void CRYPTO_poly1305_init_neon(poly1305_state *state, const uint8_t key[32]) { + struct poly1305_state_st *st = (struct poly1305_state_st *)(state); + fe1305x2 *const r = (fe1305x2 *)(st->data + (15 & (-(int)st->data))); + fe1305x2 *const h = r + 1; + fe1305x2 *const c = h + 1; + fe1305x2 *const precomp = c + 1; + unsigned int j; + + r->v[1] = r->v[0] = 0x3ffffff & *(uint32_t *)key; + r->v[3] = r->v[2] = 0x3ffff03 & ((*(uint32_t *)(key + 3)) >> 2); + r->v[5] = r->v[4] = 0x3ffc0ff & ((*(uint32_t *)(key + 6)) >> 4); + r->v[7] = r->v[6] = 0x3f03fff & ((*(uint32_t *)(key + 9)) >> 6); + r->v[9] = r->v[8] = 0x00fffff & ((*(uint32_t *)(key + 12)) >> 8); + + for (j = 0; j < 10; j++) { + h->v[j] = 0; // XXX: should fast-forward a bit + } + + addmulmod(precomp, r, r, &zero); // precompute r^2 + addmulmod(precomp + 1, precomp, precomp, &zero); // precompute r^4 + + OPENSSL_memcpy(st->key, key + 16, 16); + st->buf_used = 0; +} + +void CRYPTO_poly1305_update_neon(poly1305_state *state, const uint8_t *in, + size_t in_len) { + struct poly1305_state_st *st = (struct poly1305_state_st *)(state); + fe1305x2 *const r = (fe1305x2 *)(st->data + (15 & (-(int)st->data))); + fe1305x2 *const h = r + 1; + fe1305x2 *const c = h + 1; + fe1305x2 *const precomp = c + 1; + unsigned int i; + + if (st->buf_used) { + unsigned int todo = 32 - st->buf_used; + if (todo > in_len) { + todo = in_len; + } + for (i = 0; i < todo; i++) { + st->buf[st->buf_used + i] = in[i]; + } + st->buf_used += todo; + in_len -= todo; + in += todo; + + if (st->buf_used == sizeof(st->buf) && in_len) { + addmulmod(h, h, precomp, &zero); + fe1305x2_frombytearray(c, st->buf, sizeof(st->buf)); + for (i = 0; i < 10; i++) { + h->v[i] += c->v[i]; + } + st->buf_used = 0; + } + } + + while (in_len > 32) { + unsigned int tlen = 1048576; + if (in_len < tlen) { + tlen = in_len; + } + tlen -= blocks(h, precomp, in, tlen); + in_len -= tlen; + in += tlen; + } + + if (in_len) { + for (i = 0; i < in_len; i++) { + st->buf[i] = in[i]; + } + st->buf_used = in_len; + } +} + +void CRYPTO_poly1305_finish_neon(poly1305_state *state, uint8_t mac[16]) { + struct poly1305_state_st *st = (struct poly1305_state_st *)(state); + fe1305x2 *const r = (fe1305x2 *)(st->data + (15 & (-(int)st->data))); + fe1305x2 *const h = r + 1; + fe1305x2 *const c = h + 1; + fe1305x2 *const precomp = c + 1; + + addmulmod(h, h, precomp, &zero); + + if (st->buf_used > 16) { + fe1305x2_frombytearray(c, st->buf, st->buf_used); + precomp->v[1] = r->v[1]; + precomp->v[3] = r->v[3]; + precomp->v[5] = r->v[5]; + precomp->v[7] = r->v[7]; + precomp->v[9] = r->v[9]; + addmulmod(h, h, precomp, c); + } else if (st->buf_used > 0) { + fe1305x2_frombytearray(c, st->buf, st->buf_used); + r->v[1] = 1; + r->v[3] = 0; + r->v[5] = 0; + r->v[7] = 0; + r->v[9] = 0; + addmulmod(h, h, r, c); + } + + h->v[0] += h->v[1]; + h->v[2] += h->v[3]; + h->v[4] += h->v[5]; + h->v[6] += h->v[7]; + h->v[8] += h->v[9]; + freeze(h); + + fe1305x2_frombytearray(c, st->key, 16); + c->v[8] ^= (1 << 24); + + h->v[0] += c->v[0]; + h->v[2] += c->v[2]; + h->v[4] += c->v[4]; + h->v[6] += c->v[6]; + h->v[8] += c->v[8]; + fe1305x2_tobytearray(mac, h); +} + +#endif // OPENSSL_POLY1305_NEON diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/poly1305/poly1305_arm.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/poly1305/poly1305_arm.c.grpc_back new file mode 100644 index 0000000..4aff713 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/poly1305/poly1305_arm.c.grpc_back @@ -0,0 +1,304 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +// This implementation was taken from the public domain, neon2 version in +// SUPERCOP by D. J. Bernstein and Peter Schwabe. + +#include + +#include + +#include "../internal.h" +#include "internal.h" + + +#if defined(OPENSSL_POLY1305_NEON) + +typedef struct { + uint32_t v[12]; // for alignment; only using 10 +} fe1305x2; + +#define addmulmod openssl_poly1305_neon2_addmulmod +#define blocks openssl_poly1305_neon2_blocks + +extern void addmulmod(fe1305x2 *r, const fe1305x2 *x, const fe1305x2 *y, + const fe1305x2 *c); + +extern int blocks(fe1305x2 *h, const fe1305x2 *precomp, const uint8_t *in, + unsigned int inlen); + +static void freeze(fe1305x2 *r) { + int i; + + uint32_t x0 = r->v[0]; + uint32_t x1 = r->v[2]; + uint32_t x2 = r->v[4]; + uint32_t x3 = r->v[6]; + uint32_t x4 = r->v[8]; + uint32_t y0; + uint32_t y1; + uint32_t y2; + uint32_t y3; + uint32_t y4; + uint32_t swap; + + for (i = 0; i < 3; ++i) { + x1 += x0 >> 26; + x0 &= 0x3ffffff; + x2 += x1 >> 26; + x1 &= 0x3ffffff; + x3 += x2 >> 26; + x2 &= 0x3ffffff; + x4 += x3 >> 26; + x3 &= 0x3ffffff; + x0 += 5 * (x4 >> 26); + x4 &= 0x3ffffff; + } + + y0 = x0 + 5; + y1 = x1 + (y0 >> 26); + y0 &= 0x3ffffff; + y2 = x2 + (y1 >> 26); + y1 &= 0x3ffffff; + y3 = x3 + (y2 >> 26); + y2 &= 0x3ffffff; + y4 = x4 + (y3 >> 26); + y3 &= 0x3ffffff; + swap = -(y4 >> 26); + y4 &= 0x3ffffff; + + y0 ^= x0; + y1 ^= x1; + y2 ^= x2; + y3 ^= x3; + y4 ^= x4; + + y0 &= swap; + y1 &= swap; + y2 &= swap; + y3 &= swap; + y4 &= swap; + + y0 ^= x0; + y1 ^= x1; + y2 ^= x2; + y3 ^= x3; + y4 ^= x4; + + r->v[0] = y0; + r->v[2] = y1; + r->v[4] = y2; + r->v[6] = y3; + r->v[8] = y4; +} + +static void fe1305x2_tobytearray(uint8_t *r, fe1305x2 *x) { + uint32_t x0 = x->v[0]; + uint32_t x1 = x->v[2]; + uint32_t x2 = x->v[4]; + uint32_t x3 = x->v[6]; + uint32_t x4 = x->v[8]; + + x1 += x0 >> 26; + x0 &= 0x3ffffff; + x2 += x1 >> 26; + x1 &= 0x3ffffff; + x3 += x2 >> 26; + x2 &= 0x3ffffff; + x4 += x3 >> 26; + x3 &= 0x3ffffff; + + *(uint32_t *)r = x0 + (x1 << 26); + *(uint32_t *)(r + 4) = (x1 >> 6) + (x2 << 20); + *(uint32_t *)(r + 8) = (x2 >> 12) + (x3 << 14); + *(uint32_t *)(r + 12) = (x3 >> 18) + (x4 << 8); +} + +// load32 exists to avoid breaking strict aliasing rules in +// fe1305x2_frombytearray. +static uint32_t load32(uint8_t *t) { + uint32_t tmp; + OPENSSL_memcpy(&tmp, t, sizeof(tmp)); + return tmp; +} + +static void fe1305x2_frombytearray(fe1305x2 *r, const uint8_t *x, + unsigned long long xlen) { + unsigned i; + uint8_t t[17]; + + for (i = 0; (i < 16) && (i < xlen); i++) { + t[i] = x[i]; + } + xlen -= i; + x += i; + t[i++] = 1; + for (; i < 17; i++) { + t[i] = 0; + } + + r->v[0] = 0x3ffffff & load32(t); + r->v[2] = 0x3ffffff & (load32(t + 3) >> 2); + r->v[4] = 0x3ffffff & (load32(t + 6) >> 4); + r->v[6] = 0x3ffffff & (load32(t + 9) >> 6); + r->v[8] = load32(t + 13); + + if (xlen) { + for (i = 0; (i < 16) && (i < xlen); i++) { + t[i] = x[i]; + } + t[i++] = 1; + for (; i < 17; i++) { + t[i] = 0; + } + + r->v[1] = 0x3ffffff & load32(t); + r->v[3] = 0x3ffffff & (load32(t + 3) >> 2); + r->v[5] = 0x3ffffff & (load32(t + 6) >> 4); + r->v[7] = 0x3ffffff & (load32(t + 9) >> 6); + r->v[9] = load32(t + 13); + } else { + r->v[1] = r->v[3] = r->v[5] = r->v[7] = r->v[9] = 0; + } +} + +static const alignas(16) fe1305x2 zero; + +struct poly1305_state_st { + uint8_t data[sizeof(fe1305x2[5]) + 128]; + uint8_t buf[32]; + unsigned int buf_used; + uint8_t key[16]; +}; + +void CRYPTO_poly1305_init_neon(poly1305_state *state, const uint8_t key[32]) { + struct poly1305_state_st *st = (struct poly1305_state_st *)(state); + fe1305x2 *const r = (fe1305x2 *)(st->data + (15 & (-(int)st->data))); + fe1305x2 *const h = r + 1; + fe1305x2 *const c = h + 1; + fe1305x2 *const precomp = c + 1; + unsigned int j; + + r->v[1] = r->v[0] = 0x3ffffff & *(uint32_t *)key; + r->v[3] = r->v[2] = 0x3ffff03 & ((*(uint32_t *)(key + 3)) >> 2); + r->v[5] = r->v[4] = 0x3ffc0ff & ((*(uint32_t *)(key + 6)) >> 4); + r->v[7] = r->v[6] = 0x3f03fff & ((*(uint32_t *)(key + 9)) >> 6); + r->v[9] = r->v[8] = 0x00fffff & ((*(uint32_t *)(key + 12)) >> 8); + + for (j = 0; j < 10; j++) { + h->v[j] = 0; // XXX: should fast-forward a bit + } + + addmulmod(precomp, r, r, &zero); // precompute r^2 + addmulmod(precomp + 1, precomp, precomp, &zero); // precompute r^4 + + OPENSSL_memcpy(st->key, key + 16, 16); + st->buf_used = 0; +} + +void CRYPTO_poly1305_update_neon(poly1305_state *state, const uint8_t *in, + size_t in_len) { + struct poly1305_state_st *st = (struct poly1305_state_st *)(state); + fe1305x2 *const r = (fe1305x2 *)(st->data + (15 & (-(int)st->data))); + fe1305x2 *const h = r + 1; + fe1305x2 *const c = h + 1; + fe1305x2 *const precomp = c + 1; + unsigned int i; + + if (st->buf_used) { + unsigned int todo = 32 - st->buf_used; + if (todo > in_len) { + todo = in_len; + } + for (i = 0; i < todo; i++) { + st->buf[st->buf_used + i] = in[i]; + } + st->buf_used += todo; + in_len -= todo; + in += todo; + + if (st->buf_used == sizeof(st->buf) && in_len) { + addmulmod(h, h, precomp, &zero); + fe1305x2_frombytearray(c, st->buf, sizeof(st->buf)); + for (i = 0; i < 10; i++) { + h->v[i] += c->v[i]; + } + st->buf_used = 0; + } + } + + while (in_len > 32) { + unsigned int tlen = 1048576; + if (in_len < tlen) { + tlen = in_len; + } + tlen -= blocks(h, precomp, in, tlen); + in_len -= tlen; + in += tlen; + } + + if (in_len) { + for (i = 0; i < in_len; i++) { + st->buf[i] = in[i]; + } + st->buf_used = in_len; + } +} + +void CRYPTO_poly1305_finish_neon(poly1305_state *state, uint8_t mac[16]) { + struct poly1305_state_st *st = (struct poly1305_state_st *)(state); + fe1305x2 *const r = (fe1305x2 *)(st->data + (15 & (-(int)st->data))); + fe1305x2 *const h = r + 1; + fe1305x2 *const c = h + 1; + fe1305x2 *const precomp = c + 1; + + addmulmod(h, h, precomp, &zero); + + if (st->buf_used > 16) { + fe1305x2_frombytearray(c, st->buf, st->buf_used); + precomp->v[1] = r->v[1]; + precomp->v[3] = r->v[3]; + precomp->v[5] = r->v[5]; + precomp->v[7] = r->v[7]; + precomp->v[9] = r->v[9]; + addmulmod(h, h, precomp, c); + } else if (st->buf_used > 0) { + fe1305x2_frombytearray(c, st->buf, st->buf_used); + r->v[1] = 1; + r->v[3] = 0; + r->v[5] = 0; + r->v[7] = 0; + r->v[9] = 0; + addmulmod(h, h, r, c); + } + + h->v[0] += h->v[1]; + h->v[2] += h->v[3]; + h->v[4] += h->v[5]; + h->v[6] += h->v[7]; + h->v[8] += h->v[9]; + freeze(h); + + fe1305x2_frombytearray(c, st->key, 16); + c->v[8] ^= (1 << 24); + + h->v[0] += c->v[0]; + h->v[2] += c->v[2]; + h->v[4] += c->v[4]; + h->v[6] += c->v[6]; + h->v[8] += c->v[8]; + fe1305x2_tobytearray(mac, h); +} + +#endif // OPENSSL_POLY1305_NEON diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/poly1305/poly1305_vec.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/poly1305/poly1305_vec.c new file mode 100644 index 0000000..44dbe7a --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/poly1305/poly1305_vec.c @@ -0,0 +1,839 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +// This implementation of poly1305 is by Andrew Moon +// (https://github.com/floodyberry/poly1305-donna) and released as public +// domain. It implements SIMD vectorization based on the algorithm described in +// http://cr.yp.to/papers.html#neoncrypto. Unrolled to 2 powers, i.e. 64 byte +// block size + +#include + +#include "../internal.h" + + +#if !defined(OPENSSL_WINDOWS) && defined(OPENSSL_X86_64) + +#include + +#define U8TO64_LE(m) (*(const uint64_t *)(m)) +#define U8TO32_LE(m) (*(const uint32_t *)(m)) +#define U64TO8_LE(m, v) (*(uint64_t *)(m)) = v + +typedef __m128i xmmi; + +static const alignas(16) uint32_t poly1305_x64_sse2_message_mask[4] = { + (1 << 26) - 1, 0, (1 << 26) - 1, 0}; +static const alignas(16) uint32_t poly1305_x64_sse2_5[4] = {5, 0, 5, 0}; +static const alignas(16) uint32_t poly1305_x64_sse2_1shl128[4] = { + (1 << 24), 0, (1 << 24), 0}; + +static inline uint128_t add128(uint128_t a, uint128_t b) { return a + b; } + +static inline uint128_t add128_64(uint128_t a, uint64_t b) { return a + b; } + +static inline uint128_t mul64x64_128(uint64_t a, uint64_t b) { + return (uint128_t)a * b; +} + +static inline uint64_t lo128(uint128_t a) { return (uint64_t)a; } + +static inline uint64_t shr128(uint128_t v, const int shift) { + return (uint64_t)(v >> shift); +} + +static inline uint64_t shr128_pair(uint64_t hi, uint64_t lo, const int shift) { + return (uint64_t)((((uint128_t)hi << 64) | lo) >> shift); +} + +typedef struct poly1305_power_t { + union { + xmmi v; + uint64_t u[2]; + uint32_t d[4]; + } R20, R21, R22, R23, R24, S21, S22, S23, S24; +} poly1305_power; + +typedef struct poly1305_state_internal_t { + poly1305_power P[2]; /* 288 bytes, top 32 bit halves unused = 144 + bytes of free storage */ + union { + xmmi H[5]; // 80 bytes + uint64_t HH[10]; + }; + // uint64_t r0,r1,r2; [24 bytes] + // uint64_t pad0,pad1; [16 bytes] + uint64_t started; // 8 bytes + uint64_t leftover; // 8 bytes + uint8_t buffer[64]; // 64 bytes +} poly1305_state_internal; /* 448 bytes total + 63 bytes for + alignment = 511 bytes raw */ + +static inline poly1305_state_internal *poly1305_aligned_state( + poly1305_state *state) { + return (poly1305_state_internal *)(((uint64_t)state + 63) & ~63); +} + +static inline size_t poly1305_min(size_t a, size_t b) { + return (a < b) ? a : b; +} + +void CRYPTO_poly1305_init(poly1305_state *state, const uint8_t key[32]) { + poly1305_state_internal *st = poly1305_aligned_state(state); + poly1305_power *p; + uint64_t r0, r1, r2; + uint64_t t0, t1; + + // clamp key + t0 = U8TO64_LE(key + 0); + t1 = U8TO64_LE(key + 8); + r0 = t0 & 0xffc0fffffff; + t0 >>= 44; + t0 |= t1 << 20; + r1 = t0 & 0xfffffc0ffff; + t1 >>= 24; + r2 = t1 & 0x00ffffffc0f; + + // store r in un-used space of st->P[1] + p = &st->P[1]; + p->R20.d[1] = (uint32_t)(r0); + p->R20.d[3] = (uint32_t)(r0 >> 32); + p->R21.d[1] = (uint32_t)(r1); + p->R21.d[3] = (uint32_t)(r1 >> 32); + p->R22.d[1] = (uint32_t)(r2); + p->R22.d[3] = (uint32_t)(r2 >> 32); + + // store pad + p->R23.d[1] = U8TO32_LE(key + 16); + p->R23.d[3] = U8TO32_LE(key + 20); + p->R24.d[1] = U8TO32_LE(key + 24); + p->R24.d[3] = U8TO32_LE(key + 28); + + // H = 0 + st->H[0] = _mm_setzero_si128(); + st->H[1] = _mm_setzero_si128(); + st->H[2] = _mm_setzero_si128(); + st->H[3] = _mm_setzero_si128(); + st->H[4] = _mm_setzero_si128(); + + st->started = 0; + st->leftover = 0; +} + +static void poly1305_first_block(poly1305_state_internal *st, + const uint8_t *m) { + const xmmi MMASK = _mm_load_si128((const xmmi *)poly1305_x64_sse2_message_mask); + const xmmi FIVE = _mm_load_si128((const xmmi *)poly1305_x64_sse2_5); + const xmmi HIBIT = _mm_load_si128((const xmmi *)poly1305_x64_sse2_1shl128); + xmmi T5, T6; + poly1305_power *p; + uint128_t d[3]; + uint64_t r0, r1, r2; + uint64_t r20, r21, r22, s22; + uint64_t pad0, pad1; + uint64_t c; + uint64_t i; + + // pull out stored info + p = &st->P[1]; + + r0 = ((uint64_t)p->R20.d[3] << 32) | (uint64_t)p->R20.d[1]; + r1 = ((uint64_t)p->R21.d[3] << 32) | (uint64_t)p->R21.d[1]; + r2 = ((uint64_t)p->R22.d[3] << 32) | (uint64_t)p->R22.d[1]; + pad0 = ((uint64_t)p->R23.d[3] << 32) | (uint64_t)p->R23.d[1]; + pad1 = ((uint64_t)p->R24.d[3] << 32) | (uint64_t)p->R24.d[1]; + + // compute powers r^2,r^4 + r20 = r0; + r21 = r1; + r22 = r2; + for (i = 0; i < 2; i++) { + s22 = r22 * (5 << 2); + + d[0] = add128(mul64x64_128(r20, r20), mul64x64_128(r21 * 2, s22)); + d[1] = add128(mul64x64_128(r22, s22), mul64x64_128(r20 * 2, r21)); + d[2] = add128(mul64x64_128(r21, r21), mul64x64_128(r22 * 2, r20)); + + r20 = lo128(d[0]) & 0xfffffffffff; + c = shr128(d[0], 44); + d[1] = add128_64(d[1], c); + r21 = lo128(d[1]) & 0xfffffffffff; + c = shr128(d[1], 44); + d[2] = add128_64(d[2], c); + r22 = lo128(d[2]) & 0x3ffffffffff; + c = shr128(d[2], 42); + r20 += c * 5; + c = (r20 >> 44); + r20 = r20 & 0xfffffffffff; + r21 += c; + + p->R20.v = _mm_shuffle_epi32(_mm_cvtsi32_si128((uint32_t)(r20)&0x3ffffff), + _MM_SHUFFLE(1, 0, 1, 0)); + p->R21.v = _mm_shuffle_epi32( + _mm_cvtsi32_si128((uint32_t)((r20 >> 26) | (r21 << 18)) & 0x3ffffff), + _MM_SHUFFLE(1, 0, 1, 0)); + p->R22.v = + _mm_shuffle_epi32(_mm_cvtsi32_si128((uint32_t)((r21 >> 8)) & 0x3ffffff), + _MM_SHUFFLE(1, 0, 1, 0)); + p->R23.v = _mm_shuffle_epi32( + _mm_cvtsi32_si128((uint32_t)((r21 >> 34) | (r22 << 10)) & 0x3ffffff), + _MM_SHUFFLE(1, 0, 1, 0)); + p->R24.v = _mm_shuffle_epi32(_mm_cvtsi32_si128((uint32_t)((r22 >> 16))), + _MM_SHUFFLE(1, 0, 1, 0)); + p->S21.v = _mm_mul_epu32(p->R21.v, FIVE); + p->S22.v = _mm_mul_epu32(p->R22.v, FIVE); + p->S23.v = _mm_mul_epu32(p->R23.v, FIVE); + p->S24.v = _mm_mul_epu32(p->R24.v, FIVE); + p--; + } + + // put saved info back + p = &st->P[1]; + p->R20.d[1] = (uint32_t)(r0); + p->R20.d[3] = (uint32_t)(r0 >> 32); + p->R21.d[1] = (uint32_t)(r1); + p->R21.d[3] = (uint32_t)(r1 >> 32); + p->R22.d[1] = (uint32_t)(r2); + p->R22.d[3] = (uint32_t)(r2 >> 32); + p->R23.d[1] = (uint32_t)(pad0); + p->R23.d[3] = (uint32_t)(pad0 >> 32); + p->R24.d[1] = (uint32_t)(pad1); + p->R24.d[3] = (uint32_t)(pad1 >> 32); + + // H = [Mx,My] + T5 = _mm_unpacklo_epi64(_mm_loadl_epi64((const xmmi *)(m + 0)), + _mm_loadl_epi64((const xmmi *)(m + 16))); + T6 = _mm_unpacklo_epi64(_mm_loadl_epi64((const xmmi *)(m + 8)), + _mm_loadl_epi64((const xmmi *)(m + 24))); + st->H[0] = _mm_and_si128(MMASK, T5); + st->H[1] = _mm_and_si128(MMASK, _mm_srli_epi64(T5, 26)); + T5 = _mm_or_si128(_mm_srli_epi64(T5, 52), _mm_slli_epi64(T6, 12)); + st->H[2] = _mm_and_si128(MMASK, T5); + st->H[3] = _mm_and_si128(MMASK, _mm_srli_epi64(T5, 26)); + st->H[4] = _mm_or_si128(_mm_srli_epi64(T6, 40), HIBIT); +} + +static void poly1305_blocks(poly1305_state_internal *st, const uint8_t *m, + size_t bytes) { + const xmmi MMASK = _mm_load_si128((const xmmi *)poly1305_x64_sse2_message_mask); + const xmmi FIVE = _mm_load_si128((const xmmi *)poly1305_x64_sse2_5); + const xmmi HIBIT = _mm_load_si128((const xmmi *)poly1305_x64_sse2_1shl128); + + poly1305_power *p; + xmmi H0, H1, H2, H3, H4; + xmmi T0, T1, T2, T3, T4, T5, T6; + xmmi M0, M1, M2, M3, M4; + xmmi C1, C2; + + H0 = st->H[0]; + H1 = st->H[1]; + H2 = st->H[2]; + H3 = st->H[3]; + H4 = st->H[4]; + + while (bytes >= 64) { + // H *= [r^4,r^4] + p = &st->P[0]; + T0 = _mm_mul_epu32(H0, p->R20.v); + T1 = _mm_mul_epu32(H0, p->R21.v); + T2 = _mm_mul_epu32(H0, p->R22.v); + T3 = _mm_mul_epu32(H0, p->R23.v); + T4 = _mm_mul_epu32(H0, p->R24.v); + T5 = _mm_mul_epu32(H1, p->S24.v); + T6 = _mm_mul_epu32(H1, p->R20.v); + T0 = _mm_add_epi64(T0, T5); + T1 = _mm_add_epi64(T1, T6); + T5 = _mm_mul_epu32(H2, p->S23.v); + T6 = _mm_mul_epu32(H2, p->S24.v); + T0 = _mm_add_epi64(T0, T5); + T1 = _mm_add_epi64(T1, T6); + T5 = _mm_mul_epu32(H3, p->S22.v); + T6 = _mm_mul_epu32(H3, p->S23.v); + T0 = _mm_add_epi64(T0, T5); + T1 = _mm_add_epi64(T1, T6); + T5 = _mm_mul_epu32(H4, p->S21.v); + T6 = _mm_mul_epu32(H4, p->S22.v); + T0 = _mm_add_epi64(T0, T5); + T1 = _mm_add_epi64(T1, T6); + T5 = _mm_mul_epu32(H1, p->R21.v); + T6 = _mm_mul_epu32(H1, p->R22.v); + T2 = _mm_add_epi64(T2, T5); + T3 = _mm_add_epi64(T3, T6); + T5 = _mm_mul_epu32(H2, p->R20.v); + T6 = _mm_mul_epu32(H2, p->R21.v); + T2 = _mm_add_epi64(T2, T5); + T3 = _mm_add_epi64(T3, T6); + T5 = _mm_mul_epu32(H3, p->S24.v); + T6 = _mm_mul_epu32(H3, p->R20.v); + T2 = _mm_add_epi64(T2, T5); + T3 = _mm_add_epi64(T3, T6); + T5 = _mm_mul_epu32(H4, p->S23.v); + T6 = _mm_mul_epu32(H4, p->S24.v); + T2 = _mm_add_epi64(T2, T5); + T3 = _mm_add_epi64(T3, T6); + T5 = _mm_mul_epu32(H1, p->R23.v); + T4 = _mm_add_epi64(T4, T5); + T5 = _mm_mul_epu32(H2, p->R22.v); + T4 = _mm_add_epi64(T4, T5); + T5 = _mm_mul_epu32(H3, p->R21.v); + T4 = _mm_add_epi64(T4, T5); + T5 = _mm_mul_epu32(H4, p->R20.v); + T4 = _mm_add_epi64(T4, T5); + + // H += [Mx,My]*[r^2,r^2] + T5 = _mm_unpacklo_epi64(_mm_loadl_epi64((const xmmi *)(m + 0)), + _mm_loadl_epi64((const xmmi *)(m + 16))); + T6 = _mm_unpacklo_epi64(_mm_loadl_epi64((const xmmi *)(m + 8)), + _mm_loadl_epi64((const xmmi *)(m + 24))); + M0 = _mm_and_si128(MMASK, T5); + M1 = _mm_and_si128(MMASK, _mm_srli_epi64(T5, 26)); + T5 = _mm_or_si128(_mm_srli_epi64(T5, 52), _mm_slli_epi64(T6, 12)); + M2 = _mm_and_si128(MMASK, T5); + M3 = _mm_and_si128(MMASK, _mm_srli_epi64(T5, 26)); + M4 = _mm_or_si128(_mm_srli_epi64(T6, 40), HIBIT); + + p = &st->P[1]; + T5 = _mm_mul_epu32(M0, p->R20.v); + T6 = _mm_mul_epu32(M0, p->R21.v); + T0 = _mm_add_epi64(T0, T5); + T1 = _mm_add_epi64(T1, T6); + T5 = _mm_mul_epu32(M1, p->S24.v); + T6 = _mm_mul_epu32(M1, p->R20.v); + T0 = _mm_add_epi64(T0, T5); + T1 = _mm_add_epi64(T1, T6); + T5 = _mm_mul_epu32(M2, p->S23.v); + T6 = _mm_mul_epu32(M2, p->S24.v); + T0 = _mm_add_epi64(T0, T5); + T1 = _mm_add_epi64(T1, T6); + T5 = _mm_mul_epu32(M3, p->S22.v); + T6 = _mm_mul_epu32(M3, p->S23.v); + T0 = _mm_add_epi64(T0, T5); + T1 = _mm_add_epi64(T1, T6); + T5 = _mm_mul_epu32(M4, p->S21.v); + T6 = _mm_mul_epu32(M4, p->S22.v); + T0 = _mm_add_epi64(T0, T5); + T1 = _mm_add_epi64(T1, T6); + T5 = _mm_mul_epu32(M0, p->R22.v); + T6 = _mm_mul_epu32(M0, p->R23.v); + T2 = _mm_add_epi64(T2, T5); + T3 = _mm_add_epi64(T3, T6); + T5 = _mm_mul_epu32(M1, p->R21.v); + T6 = _mm_mul_epu32(M1, p->R22.v); + T2 = _mm_add_epi64(T2, T5); + T3 = _mm_add_epi64(T3, T6); + T5 = _mm_mul_epu32(M2, p->R20.v); + T6 = _mm_mul_epu32(M2, p->R21.v); + T2 = _mm_add_epi64(T2, T5); + T3 = _mm_add_epi64(T3, T6); + T5 = _mm_mul_epu32(M3, p->S24.v); + T6 = _mm_mul_epu32(M3, p->R20.v); + T2 = _mm_add_epi64(T2, T5); + T3 = _mm_add_epi64(T3, T6); + T5 = _mm_mul_epu32(M4, p->S23.v); + T6 = _mm_mul_epu32(M4, p->S24.v); + T2 = _mm_add_epi64(T2, T5); + T3 = _mm_add_epi64(T3, T6); + T5 = _mm_mul_epu32(M0, p->R24.v); + T4 = _mm_add_epi64(T4, T5); + T5 = _mm_mul_epu32(M1, p->R23.v); + T4 = _mm_add_epi64(T4, T5); + T5 = _mm_mul_epu32(M2, p->R22.v); + T4 = _mm_add_epi64(T4, T5); + T5 = _mm_mul_epu32(M3, p->R21.v); + T4 = _mm_add_epi64(T4, T5); + T5 = _mm_mul_epu32(M4, p->R20.v); + T4 = _mm_add_epi64(T4, T5); + + // H += [Mx,My] + T5 = _mm_unpacklo_epi64(_mm_loadl_epi64((const xmmi *)(m + 32)), + _mm_loadl_epi64((const xmmi *)(m + 48))); + T6 = _mm_unpacklo_epi64(_mm_loadl_epi64((const xmmi *)(m + 40)), + _mm_loadl_epi64((const xmmi *)(m + 56))); + M0 = _mm_and_si128(MMASK, T5); + M1 = _mm_and_si128(MMASK, _mm_srli_epi64(T5, 26)); + T5 = _mm_or_si128(_mm_srli_epi64(T5, 52), _mm_slli_epi64(T6, 12)); + M2 = _mm_and_si128(MMASK, T5); + M3 = _mm_and_si128(MMASK, _mm_srli_epi64(T5, 26)); + M4 = _mm_or_si128(_mm_srli_epi64(T6, 40), HIBIT); + + T0 = _mm_add_epi64(T0, M0); + T1 = _mm_add_epi64(T1, M1); + T2 = _mm_add_epi64(T2, M2); + T3 = _mm_add_epi64(T3, M3); + T4 = _mm_add_epi64(T4, M4); + + // reduce + C1 = _mm_srli_epi64(T0, 26); + C2 = _mm_srli_epi64(T3, 26); + T0 = _mm_and_si128(T0, MMASK); + T3 = _mm_and_si128(T3, MMASK); + T1 = _mm_add_epi64(T1, C1); + T4 = _mm_add_epi64(T4, C2); + C1 = _mm_srli_epi64(T1, 26); + C2 = _mm_srli_epi64(T4, 26); + T1 = _mm_and_si128(T1, MMASK); + T4 = _mm_and_si128(T4, MMASK); + T2 = _mm_add_epi64(T2, C1); + T0 = _mm_add_epi64(T0, _mm_mul_epu32(C2, FIVE)); + C1 = _mm_srli_epi64(T2, 26); + C2 = _mm_srli_epi64(T0, 26); + T2 = _mm_and_si128(T2, MMASK); + T0 = _mm_and_si128(T0, MMASK); + T3 = _mm_add_epi64(T3, C1); + T1 = _mm_add_epi64(T1, C2); + C1 = _mm_srli_epi64(T3, 26); + T3 = _mm_and_si128(T3, MMASK); + T4 = _mm_add_epi64(T4, C1); + + // H = (H*[r^4,r^4] + [Mx,My]*[r^2,r^2] + [Mx,My]) + H0 = T0; + H1 = T1; + H2 = T2; + H3 = T3; + H4 = T4; + + m += 64; + bytes -= 64; + } + + st->H[0] = H0; + st->H[1] = H1; + st->H[2] = H2; + st->H[3] = H3; + st->H[4] = H4; +} + +static size_t poly1305_combine(poly1305_state_internal *st, const uint8_t *m, + size_t bytes) { + const xmmi MMASK = _mm_load_si128((const xmmi *)poly1305_x64_sse2_message_mask); + const xmmi HIBIT = _mm_load_si128((const xmmi *)poly1305_x64_sse2_1shl128); + const xmmi FIVE = _mm_load_si128((const xmmi *)poly1305_x64_sse2_5); + + poly1305_power *p; + xmmi H0, H1, H2, H3, H4; + xmmi M0, M1, M2, M3, M4; + xmmi T0, T1, T2, T3, T4, T5, T6; + xmmi C1, C2; + + uint64_t r0, r1, r2; + uint64_t t0, t1, t2, t3, t4; + uint64_t c; + size_t consumed = 0; + + H0 = st->H[0]; + H1 = st->H[1]; + H2 = st->H[2]; + H3 = st->H[3]; + H4 = st->H[4]; + + // p = [r^2,r^2] + p = &st->P[1]; + + if (bytes >= 32) { + // H *= [r^2,r^2] + T0 = _mm_mul_epu32(H0, p->R20.v); + T1 = _mm_mul_epu32(H0, p->R21.v); + T2 = _mm_mul_epu32(H0, p->R22.v); + T3 = _mm_mul_epu32(H0, p->R23.v); + T4 = _mm_mul_epu32(H0, p->R24.v); + T5 = _mm_mul_epu32(H1, p->S24.v); + T6 = _mm_mul_epu32(H1, p->R20.v); + T0 = _mm_add_epi64(T0, T5); + T1 = _mm_add_epi64(T1, T6); + T5 = _mm_mul_epu32(H2, p->S23.v); + T6 = _mm_mul_epu32(H2, p->S24.v); + T0 = _mm_add_epi64(T0, T5); + T1 = _mm_add_epi64(T1, T6); + T5 = _mm_mul_epu32(H3, p->S22.v); + T6 = _mm_mul_epu32(H3, p->S23.v); + T0 = _mm_add_epi64(T0, T5); + T1 = _mm_add_epi64(T1, T6); + T5 = _mm_mul_epu32(H4, p->S21.v); + T6 = _mm_mul_epu32(H4, p->S22.v); + T0 = _mm_add_epi64(T0, T5); + T1 = _mm_add_epi64(T1, T6); + T5 = _mm_mul_epu32(H1, p->R21.v); + T6 = _mm_mul_epu32(H1, p->R22.v); + T2 = _mm_add_epi64(T2, T5); + T3 = _mm_add_epi64(T3, T6); + T5 = _mm_mul_epu32(H2, p->R20.v); + T6 = _mm_mul_epu32(H2, p->R21.v); + T2 = _mm_add_epi64(T2, T5); + T3 = _mm_add_epi64(T3, T6); + T5 = _mm_mul_epu32(H3, p->S24.v); + T6 = _mm_mul_epu32(H3, p->R20.v); + T2 = _mm_add_epi64(T2, T5); + T3 = _mm_add_epi64(T3, T6); + T5 = _mm_mul_epu32(H4, p->S23.v); + T6 = _mm_mul_epu32(H4, p->S24.v); + T2 = _mm_add_epi64(T2, T5); + T3 = _mm_add_epi64(T3, T6); + T5 = _mm_mul_epu32(H1, p->R23.v); + T4 = _mm_add_epi64(T4, T5); + T5 = _mm_mul_epu32(H2, p->R22.v); + T4 = _mm_add_epi64(T4, T5); + T5 = _mm_mul_epu32(H3, p->R21.v); + T4 = _mm_add_epi64(T4, T5); + T5 = _mm_mul_epu32(H4, p->R20.v); + T4 = _mm_add_epi64(T4, T5); + + // H += [Mx,My] + T5 = _mm_unpacklo_epi64(_mm_loadl_epi64((const xmmi *)(m + 0)), + _mm_loadl_epi64((const xmmi *)(m + 16))); + T6 = _mm_unpacklo_epi64(_mm_loadl_epi64((const xmmi *)(m + 8)), + _mm_loadl_epi64((const xmmi *)(m + 24))); + M0 = _mm_and_si128(MMASK, T5); + M1 = _mm_and_si128(MMASK, _mm_srli_epi64(T5, 26)); + T5 = _mm_or_si128(_mm_srli_epi64(T5, 52), _mm_slli_epi64(T6, 12)); + M2 = _mm_and_si128(MMASK, T5); + M3 = _mm_and_si128(MMASK, _mm_srli_epi64(T5, 26)); + M4 = _mm_or_si128(_mm_srli_epi64(T6, 40), HIBIT); + + T0 = _mm_add_epi64(T0, M0); + T1 = _mm_add_epi64(T1, M1); + T2 = _mm_add_epi64(T2, M2); + T3 = _mm_add_epi64(T3, M3); + T4 = _mm_add_epi64(T4, M4); + + // reduce + C1 = _mm_srli_epi64(T0, 26); + C2 = _mm_srli_epi64(T3, 26); + T0 = _mm_and_si128(T0, MMASK); + T3 = _mm_and_si128(T3, MMASK); + T1 = _mm_add_epi64(T1, C1); + T4 = _mm_add_epi64(T4, C2); + C1 = _mm_srli_epi64(T1, 26); + C2 = _mm_srli_epi64(T4, 26); + T1 = _mm_and_si128(T1, MMASK); + T4 = _mm_and_si128(T4, MMASK); + T2 = _mm_add_epi64(T2, C1); + T0 = _mm_add_epi64(T0, _mm_mul_epu32(C2, FIVE)); + C1 = _mm_srli_epi64(T2, 26); + C2 = _mm_srli_epi64(T0, 26); + T2 = _mm_and_si128(T2, MMASK); + T0 = _mm_and_si128(T0, MMASK); + T3 = _mm_add_epi64(T3, C1); + T1 = _mm_add_epi64(T1, C2); + C1 = _mm_srli_epi64(T3, 26); + T3 = _mm_and_si128(T3, MMASK); + T4 = _mm_add_epi64(T4, C1); + + // H = (H*[r^2,r^2] + [Mx,My]) + H0 = T0; + H1 = T1; + H2 = T2; + H3 = T3; + H4 = T4; + + consumed = 32; + } + + // finalize, H *= [r^2,r] + r0 = ((uint64_t)p->R20.d[3] << 32) | (uint64_t)p->R20.d[1]; + r1 = ((uint64_t)p->R21.d[3] << 32) | (uint64_t)p->R21.d[1]; + r2 = ((uint64_t)p->R22.d[3] << 32) | (uint64_t)p->R22.d[1]; + + p->R20.d[2] = (uint32_t)(r0)&0x3ffffff; + p->R21.d[2] = (uint32_t)((r0 >> 26) | (r1 << 18)) & 0x3ffffff; + p->R22.d[2] = (uint32_t)((r1 >> 8)) & 0x3ffffff; + p->R23.d[2] = (uint32_t)((r1 >> 34) | (r2 << 10)) & 0x3ffffff; + p->R24.d[2] = (uint32_t)((r2 >> 16)); + p->S21.d[2] = p->R21.d[2] * 5; + p->S22.d[2] = p->R22.d[2] * 5; + p->S23.d[2] = p->R23.d[2] * 5; + p->S24.d[2] = p->R24.d[2] * 5; + + // H *= [r^2,r] + T0 = _mm_mul_epu32(H0, p->R20.v); + T1 = _mm_mul_epu32(H0, p->R21.v); + T2 = _mm_mul_epu32(H0, p->R22.v); + T3 = _mm_mul_epu32(H0, p->R23.v); + T4 = _mm_mul_epu32(H0, p->R24.v); + T5 = _mm_mul_epu32(H1, p->S24.v); + T6 = _mm_mul_epu32(H1, p->R20.v); + T0 = _mm_add_epi64(T0, T5); + T1 = _mm_add_epi64(T1, T6); + T5 = _mm_mul_epu32(H2, p->S23.v); + T6 = _mm_mul_epu32(H2, p->S24.v); + T0 = _mm_add_epi64(T0, T5); + T1 = _mm_add_epi64(T1, T6); + T5 = _mm_mul_epu32(H3, p->S22.v); + T6 = _mm_mul_epu32(H3, p->S23.v); + T0 = _mm_add_epi64(T0, T5); + T1 = _mm_add_epi64(T1, T6); + T5 = _mm_mul_epu32(H4, p->S21.v); + T6 = _mm_mul_epu32(H4, p->S22.v); + T0 = _mm_add_epi64(T0, T5); + T1 = _mm_add_epi64(T1, T6); + T5 = _mm_mul_epu32(H1, p->R21.v); + T6 = _mm_mul_epu32(H1, p->R22.v); + T2 = _mm_add_epi64(T2, T5); + T3 = _mm_add_epi64(T3, T6); + T5 = _mm_mul_epu32(H2, p->R20.v); + T6 = _mm_mul_epu32(H2, p->R21.v); + T2 = _mm_add_epi64(T2, T5); + T3 = _mm_add_epi64(T3, T6); + T5 = _mm_mul_epu32(H3, p->S24.v); + T6 = _mm_mul_epu32(H3, p->R20.v); + T2 = _mm_add_epi64(T2, T5); + T3 = _mm_add_epi64(T3, T6); + T5 = _mm_mul_epu32(H4, p->S23.v); + T6 = _mm_mul_epu32(H4, p->S24.v); + T2 = _mm_add_epi64(T2, T5); + T3 = _mm_add_epi64(T3, T6); + T5 = _mm_mul_epu32(H1, p->R23.v); + T4 = _mm_add_epi64(T4, T5); + T5 = _mm_mul_epu32(H2, p->R22.v); + T4 = _mm_add_epi64(T4, T5); + T5 = _mm_mul_epu32(H3, p->R21.v); + T4 = _mm_add_epi64(T4, T5); + T5 = _mm_mul_epu32(H4, p->R20.v); + T4 = _mm_add_epi64(T4, T5); + + C1 = _mm_srli_epi64(T0, 26); + C2 = _mm_srli_epi64(T3, 26); + T0 = _mm_and_si128(T0, MMASK); + T3 = _mm_and_si128(T3, MMASK); + T1 = _mm_add_epi64(T1, C1); + T4 = _mm_add_epi64(T4, C2); + C1 = _mm_srli_epi64(T1, 26); + C2 = _mm_srli_epi64(T4, 26); + T1 = _mm_and_si128(T1, MMASK); + T4 = _mm_and_si128(T4, MMASK); + T2 = _mm_add_epi64(T2, C1); + T0 = _mm_add_epi64(T0, _mm_mul_epu32(C2, FIVE)); + C1 = _mm_srli_epi64(T2, 26); + C2 = _mm_srli_epi64(T0, 26); + T2 = _mm_and_si128(T2, MMASK); + T0 = _mm_and_si128(T0, MMASK); + T3 = _mm_add_epi64(T3, C1); + T1 = _mm_add_epi64(T1, C2); + C1 = _mm_srli_epi64(T3, 26); + T3 = _mm_and_si128(T3, MMASK); + T4 = _mm_add_epi64(T4, C1); + + // H = H[0]+H[1] + H0 = _mm_add_epi64(T0, _mm_srli_si128(T0, 8)); + H1 = _mm_add_epi64(T1, _mm_srli_si128(T1, 8)); + H2 = _mm_add_epi64(T2, _mm_srli_si128(T2, 8)); + H3 = _mm_add_epi64(T3, _mm_srli_si128(T3, 8)); + H4 = _mm_add_epi64(T4, _mm_srli_si128(T4, 8)); + + t0 = _mm_cvtsi128_si32(H0); + c = (t0 >> 26); + t0 &= 0x3ffffff; + t1 = _mm_cvtsi128_si32(H1) + c; + c = (t1 >> 26); + t1 &= 0x3ffffff; + t2 = _mm_cvtsi128_si32(H2) + c; + c = (t2 >> 26); + t2 &= 0x3ffffff; + t3 = _mm_cvtsi128_si32(H3) + c; + c = (t3 >> 26); + t3 &= 0x3ffffff; + t4 = _mm_cvtsi128_si32(H4) + c; + c = (t4 >> 26); + t4 &= 0x3ffffff; + t0 = t0 + (c * 5); + c = (t0 >> 26); + t0 &= 0x3ffffff; + t1 = t1 + c; + + st->HH[0] = ((t0) | (t1 << 26)) & UINT64_C(0xfffffffffff); + st->HH[1] = ((t1 >> 18) | (t2 << 8) | (t3 << 34)) & UINT64_C(0xfffffffffff); + st->HH[2] = ((t3 >> 10) | (t4 << 16)) & UINT64_C(0x3ffffffffff); + + return consumed; +} + +void CRYPTO_poly1305_update(poly1305_state *state, const uint8_t *m, + size_t bytes) { + poly1305_state_internal *st = poly1305_aligned_state(state); + size_t want; + + // need at least 32 initial bytes to start the accelerated branch + if (!st->started) { + if ((st->leftover == 0) && (bytes > 32)) { + poly1305_first_block(st, m); + m += 32; + bytes -= 32; + } else { + want = poly1305_min(32 - st->leftover, bytes); + OPENSSL_memcpy(st->buffer + st->leftover, m, want); + bytes -= want; + m += want; + st->leftover += want; + if ((st->leftover < 32) || (bytes == 0)) { + return; + } + poly1305_first_block(st, st->buffer); + st->leftover = 0; + } + st->started = 1; + } + + // handle leftover + if (st->leftover) { + want = poly1305_min(64 - st->leftover, bytes); + OPENSSL_memcpy(st->buffer + st->leftover, m, want); + bytes -= want; + m += want; + st->leftover += want; + if (st->leftover < 64) { + return; + } + poly1305_blocks(st, st->buffer, 64); + st->leftover = 0; + } + + // process 64 byte blocks + if (bytes >= 64) { + want = (bytes & ~63); + poly1305_blocks(st, m, want); + m += want; + bytes -= want; + } + + if (bytes) { + OPENSSL_memcpy(st->buffer + st->leftover, m, bytes); + st->leftover += bytes; + } +} + +void CRYPTO_poly1305_finish(poly1305_state *state, uint8_t mac[16]) { + poly1305_state_internal *st = poly1305_aligned_state(state); + size_t leftover = st->leftover; + uint8_t *m = st->buffer; + uint128_t d[3]; + uint64_t h0, h1, h2; + uint64_t t0, t1; + uint64_t g0, g1, g2, c, nc; + uint64_t r0, r1, r2, s1, s2; + poly1305_power *p; + + if (st->started) { + size_t consumed = poly1305_combine(st, m, leftover); + leftover -= consumed; + m += consumed; + } + + // st->HH will either be 0 or have the combined result + h0 = st->HH[0]; + h1 = st->HH[1]; + h2 = st->HH[2]; + + p = &st->P[1]; + r0 = ((uint64_t)p->R20.d[3] << 32) | (uint64_t)p->R20.d[1]; + r1 = ((uint64_t)p->R21.d[3] << 32) | (uint64_t)p->R21.d[1]; + r2 = ((uint64_t)p->R22.d[3] << 32) | (uint64_t)p->R22.d[1]; + s1 = r1 * (5 << 2); + s2 = r2 * (5 << 2); + + if (leftover < 16) { + goto poly1305_donna_atmost15bytes; + } + +poly1305_donna_atleast16bytes: + t0 = U8TO64_LE(m + 0); + t1 = U8TO64_LE(m + 8); + h0 += t0 & 0xfffffffffff; + t0 = shr128_pair(t1, t0, 44); + h1 += t0 & 0xfffffffffff; + h2 += (t1 >> 24) | ((uint64_t)1 << 40); + +poly1305_donna_mul: + d[0] = add128(add128(mul64x64_128(h0, r0), mul64x64_128(h1, s2)), + mul64x64_128(h2, s1)); + d[1] = add128(add128(mul64x64_128(h0, r1), mul64x64_128(h1, r0)), + mul64x64_128(h2, s2)); + d[2] = add128(add128(mul64x64_128(h0, r2), mul64x64_128(h1, r1)), + mul64x64_128(h2, r0)); + h0 = lo128(d[0]) & 0xfffffffffff; + c = shr128(d[0], 44); + d[1] = add128_64(d[1], c); + h1 = lo128(d[1]) & 0xfffffffffff; + c = shr128(d[1], 44); + d[2] = add128_64(d[2], c); + h2 = lo128(d[2]) & 0x3ffffffffff; + c = shr128(d[2], 42); + h0 += c * 5; + + m += 16; + leftover -= 16; + if (leftover >= 16) { + goto poly1305_donna_atleast16bytes; + } + +// final bytes +poly1305_donna_atmost15bytes: + if (!leftover) { + goto poly1305_donna_finish; + } + + m[leftover++] = 1; + OPENSSL_memset(m + leftover, 0, 16 - leftover); + leftover = 16; + + t0 = U8TO64_LE(m + 0); + t1 = U8TO64_LE(m + 8); + h0 += t0 & 0xfffffffffff; + t0 = shr128_pair(t1, t0, 44); + h1 += t0 & 0xfffffffffff; + h2 += (t1 >> 24); + + goto poly1305_donna_mul; + +poly1305_donna_finish: + c = (h0 >> 44); + h0 &= 0xfffffffffff; + h1 += c; + c = (h1 >> 44); + h1 &= 0xfffffffffff; + h2 += c; + c = (h2 >> 42); + h2 &= 0x3ffffffffff; + h0 += c * 5; + + g0 = h0 + 5; + c = (g0 >> 44); + g0 &= 0xfffffffffff; + g1 = h1 + c; + c = (g1 >> 44); + g1 &= 0xfffffffffff; + g2 = h2 + c - ((uint64_t)1 << 42); + + c = (g2 >> 63) - 1; + nc = ~c; + h0 = (h0 & nc) | (g0 & c); + h1 = (h1 & nc) | (g1 & c); + h2 = (h2 & nc) | (g2 & c); + + // pad + t0 = ((uint64_t)p->R23.d[3] << 32) | (uint64_t)p->R23.d[1]; + t1 = ((uint64_t)p->R24.d[3] << 32) | (uint64_t)p->R24.d[1]; + h0 += (t0 & 0xfffffffffff); + c = (h0 >> 44); + h0 &= 0xfffffffffff; + t0 = shr128_pair(t1, t0, 44); + h1 += (t0 & 0xfffffffffff) + c; + c = (h1 >> 44); + h1 &= 0xfffffffffff; + t1 = (t1 >> 24); + h2 += (t1)+c; + + U64TO8_LE(mac + 0, ((h0) | (h1 << 44))); + U64TO8_LE(mac + 8, ((h1 >> 20) | (h2 << 24))); +} + +#endif // !OPENSSL_WINDOWS && OPENSSL_X86_64 diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/poly1305/poly1305_vec.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/poly1305/poly1305_vec.c.grpc_back new file mode 100644 index 0000000..480d9e5 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/poly1305/poly1305_vec.c.grpc_back @@ -0,0 +1,839 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +// This implementation of poly1305 is by Andrew Moon +// (https://github.com/floodyberry/poly1305-donna) and released as public +// domain. It implements SIMD vectorization based on the algorithm described in +// http://cr.yp.to/papers.html#neoncrypto. Unrolled to 2 powers, i.e. 64 byte +// block size + +#include + +#include "../internal.h" + + +#if !defined(OPENSSL_WINDOWS) && defined(OPENSSL_X86_64) + +#include + +#define U8TO64_LE(m) (*(const uint64_t *)(m)) +#define U8TO32_LE(m) (*(const uint32_t *)(m)) +#define U64TO8_LE(m, v) (*(uint64_t *)(m)) = v + +typedef __m128i xmmi; + +static const alignas(16) uint32_t poly1305_x64_sse2_message_mask[4] = { + (1 << 26) - 1, 0, (1 << 26) - 1, 0}; +static const alignas(16) uint32_t poly1305_x64_sse2_5[4] = {5, 0, 5, 0}; +static const alignas(16) uint32_t poly1305_x64_sse2_1shl128[4] = { + (1 << 24), 0, (1 << 24), 0}; + +static inline uint128_t add128(uint128_t a, uint128_t b) { return a + b; } + +static inline uint128_t add128_64(uint128_t a, uint64_t b) { return a + b; } + +static inline uint128_t mul64x64_128(uint64_t a, uint64_t b) { + return (uint128_t)a * b; +} + +static inline uint64_t lo128(uint128_t a) { return (uint64_t)a; } + +static inline uint64_t shr128(uint128_t v, const int shift) { + return (uint64_t)(v >> shift); +} + +static inline uint64_t shr128_pair(uint64_t hi, uint64_t lo, const int shift) { + return (uint64_t)((((uint128_t)hi << 64) | lo) >> shift); +} + +typedef struct poly1305_power_t { + union { + xmmi v; + uint64_t u[2]; + uint32_t d[4]; + } R20, R21, R22, R23, R24, S21, S22, S23, S24; +} poly1305_power; + +typedef struct poly1305_state_internal_t { + poly1305_power P[2]; /* 288 bytes, top 32 bit halves unused = 144 + bytes of free storage */ + union { + xmmi H[5]; // 80 bytes + uint64_t HH[10]; + }; + // uint64_t r0,r1,r2; [24 bytes] + // uint64_t pad0,pad1; [16 bytes] + uint64_t started; // 8 bytes + uint64_t leftover; // 8 bytes + uint8_t buffer[64]; // 64 bytes +} poly1305_state_internal; /* 448 bytes total + 63 bytes for + alignment = 511 bytes raw */ + +static inline poly1305_state_internal *poly1305_aligned_state( + poly1305_state *state) { + return (poly1305_state_internal *)(((uint64_t)state + 63) & ~63); +} + +static inline size_t poly1305_min(size_t a, size_t b) { + return (a < b) ? a : b; +} + +void CRYPTO_poly1305_init(poly1305_state *state, const uint8_t key[32]) { + poly1305_state_internal *st = poly1305_aligned_state(state); + poly1305_power *p; + uint64_t r0, r1, r2; + uint64_t t0, t1; + + // clamp key + t0 = U8TO64_LE(key + 0); + t1 = U8TO64_LE(key + 8); + r0 = t0 & 0xffc0fffffff; + t0 >>= 44; + t0 |= t1 << 20; + r1 = t0 & 0xfffffc0ffff; + t1 >>= 24; + r2 = t1 & 0x00ffffffc0f; + + // store r in un-used space of st->P[1] + p = &st->P[1]; + p->R20.d[1] = (uint32_t)(r0); + p->R20.d[3] = (uint32_t)(r0 >> 32); + p->R21.d[1] = (uint32_t)(r1); + p->R21.d[3] = (uint32_t)(r1 >> 32); + p->R22.d[1] = (uint32_t)(r2); + p->R22.d[3] = (uint32_t)(r2 >> 32); + + // store pad + p->R23.d[1] = U8TO32_LE(key + 16); + p->R23.d[3] = U8TO32_LE(key + 20); + p->R24.d[1] = U8TO32_LE(key + 24); + p->R24.d[3] = U8TO32_LE(key + 28); + + // H = 0 + st->H[0] = _mm_setzero_si128(); + st->H[1] = _mm_setzero_si128(); + st->H[2] = _mm_setzero_si128(); + st->H[3] = _mm_setzero_si128(); + st->H[4] = _mm_setzero_si128(); + + st->started = 0; + st->leftover = 0; +} + +static void poly1305_first_block(poly1305_state_internal *st, + const uint8_t *m) { + const xmmi MMASK = _mm_load_si128((const xmmi *)poly1305_x64_sse2_message_mask); + const xmmi FIVE = _mm_load_si128((const xmmi *)poly1305_x64_sse2_5); + const xmmi HIBIT = _mm_load_si128((const xmmi *)poly1305_x64_sse2_1shl128); + xmmi T5, T6; + poly1305_power *p; + uint128_t d[3]; + uint64_t r0, r1, r2; + uint64_t r20, r21, r22, s22; + uint64_t pad0, pad1; + uint64_t c; + uint64_t i; + + // pull out stored info + p = &st->P[1]; + + r0 = ((uint64_t)p->R20.d[3] << 32) | (uint64_t)p->R20.d[1]; + r1 = ((uint64_t)p->R21.d[3] << 32) | (uint64_t)p->R21.d[1]; + r2 = ((uint64_t)p->R22.d[3] << 32) | (uint64_t)p->R22.d[1]; + pad0 = ((uint64_t)p->R23.d[3] << 32) | (uint64_t)p->R23.d[1]; + pad1 = ((uint64_t)p->R24.d[3] << 32) | (uint64_t)p->R24.d[1]; + + // compute powers r^2,r^4 + r20 = r0; + r21 = r1; + r22 = r2; + for (i = 0; i < 2; i++) { + s22 = r22 * (5 << 2); + + d[0] = add128(mul64x64_128(r20, r20), mul64x64_128(r21 * 2, s22)); + d[1] = add128(mul64x64_128(r22, s22), mul64x64_128(r20 * 2, r21)); + d[2] = add128(mul64x64_128(r21, r21), mul64x64_128(r22 * 2, r20)); + + r20 = lo128(d[0]) & 0xfffffffffff; + c = shr128(d[0], 44); + d[1] = add128_64(d[1], c); + r21 = lo128(d[1]) & 0xfffffffffff; + c = shr128(d[1], 44); + d[2] = add128_64(d[2], c); + r22 = lo128(d[2]) & 0x3ffffffffff; + c = shr128(d[2], 42); + r20 += c * 5; + c = (r20 >> 44); + r20 = r20 & 0xfffffffffff; + r21 += c; + + p->R20.v = _mm_shuffle_epi32(_mm_cvtsi32_si128((uint32_t)(r20)&0x3ffffff), + _MM_SHUFFLE(1, 0, 1, 0)); + p->R21.v = _mm_shuffle_epi32( + _mm_cvtsi32_si128((uint32_t)((r20 >> 26) | (r21 << 18)) & 0x3ffffff), + _MM_SHUFFLE(1, 0, 1, 0)); + p->R22.v = + _mm_shuffle_epi32(_mm_cvtsi32_si128((uint32_t)((r21 >> 8)) & 0x3ffffff), + _MM_SHUFFLE(1, 0, 1, 0)); + p->R23.v = _mm_shuffle_epi32( + _mm_cvtsi32_si128((uint32_t)((r21 >> 34) | (r22 << 10)) & 0x3ffffff), + _MM_SHUFFLE(1, 0, 1, 0)); + p->R24.v = _mm_shuffle_epi32(_mm_cvtsi32_si128((uint32_t)((r22 >> 16))), + _MM_SHUFFLE(1, 0, 1, 0)); + p->S21.v = _mm_mul_epu32(p->R21.v, FIVE); + p->S22.v = _mm_mul_epu32(p->R22.v, FIVE); + p->S23.v = _mm_mul_epu32(p->R23.v, FIVE); + p->S24.v = _mm_mul_epu32(p->R24.v, FIVE); + p--; + } + + // put saved info back + p = &st->P[1]; + p->R20.d[1] = (uint32_t)(r0); + p->R20.d[3] = (uint32_t)(r0 >> 32); + p->R21.d[1] = (uint32_t)(r1); + p->R21.d[3] = (uint32_t)(r1 >> 32); + p->R22.d[1] = (uint32_t)(r2); + p->R22.d[3] = (uint32_t)(r2 >> 32); + p->R23.d[1] = (uint32_t)(pad0); + p->R23.d[3] = (uint32_t)(pad0 >> 32); + p->R24.d[1] = (uint32_t)(pad1); + p->R24.d[3] = (uint32_t)(pad1 >> 32); + + // H = [Mx,My] + T5 = _mm_unpacklo_epi64(_mm_loadl_epi64((const xmmi *)(m + 0)), + _mm_loadl_epi64((const xmmi *)(m + 16))); + T6 = _mm_unpacklo_epi64(_mm_loadl_epi64((const xmmi *)(m + 8)), + _mm_loadl_epi64((const xmmi *)(m + 24))); + st->H[0] = _mm_and_si128(MMASK, T5); + st->H[1] = _mm_and_si128(MMASK, _mm_srli_epi64(T5, 26)); + T5 = _mm_or_si128(_mm_srli_epi64(T5, 52), _mm_slli_epi64(T6, 12)); + st->H[2] = _mm_and_si128(MMASK, T5); + st->H[3] = _mm_and_si128(MMASK, _mm_srli_epi64(T5, 26)); + st->H[4] = _mm_or_si128(_mm_srli_epi64(T6, 40), HIBIT); +} + +static void poly1305_blocks(poly1305_state_internal *st, const uint8_t *m, + size_t bytes) { + const xmmi MMASK = _mm_load_si128((const xmmi *)poly1305_x64_sse2_message_mask); + const xmmi FIVE = _mm_load_si128((const xmmi *)poly1305_x64_sse2_5); + const xmmi HIBIT = _mm_load_si128((const xmmi *)poly1305_x64_sse2_1shl128); + + poly1305_power *p; + xmmi H0, H1, H2, H3, H4; + xmmi T0, T1, T2, T3, T4, T5, T6; + xmmi M0, M1, M2, M3, M4; + xmmi C1, C2; + + H0 = st->H[0]; + H1 = st->H[1]; + H2 = st->H[2]; + H3 = st->H[3]; + H4 = st->H[4]; + + while (bytes >= 64) { + // H *= [r^4,r^4] + p = &st->P[0]; + T0 = _mm_mul_epu32(H0, p->R20.v); + T1 = _mm_mul_epu32(H0, p->R21.v); + T2 = _mm_mul_epu32(H0, p->R22.v); + T3 = _mm_mul_epu32(H0, p->R23.v); + T4 = _mm_mul_epu32(H0, p->R24.v); + T5 = _mm_mul_epu32(H1, p->S24.v); + T6 = _mm_mul_epu32(H1, p->R20.v); + T0 = _mm_add_epi64(T0, T5); + T1 = _mm_add_epi64(T1, T6); + T5 = _mm_mul_epu32(H2, p->S23.v); + T6 = _mm_mul_epu32(H2, p->S24.v); + T0 = _mm_add_epi64(T0, T5); + T1 = _mm_add_epi64(T1, T6); + T5 = _mm_mul_epu32(H3, p->S22.v); + T6 = _mm_mul_epu32(H3, p->S23.v); + T0 = _mm_add_epi64(T0, T5); + T1 = _mm_add_epi64(T1, T6); + T5 = _mm_mul_epu32(H4, p->S21.v); + T6 = _mm_mul_epu32(H4, p->S22.v); + T0 = _mm_add_epi64(T0, T5); + T1 = _mm_add_epi64(T1, T6); + T5 = _mm_mul_epu32(H1, p->R21.v); + T6 = _mm_mul_epu32(H1, p->R22.v); + T2 = _mm_add_epi64(T2, T5); + T3 = _mm_add_epi64(T3, T6); + T5 = _mm_mul_epu32(H2, p->R20.v); + T6 = _mm_mul_epu32(H2, p->R21.v); + T2 = _mm_add_epi64(T2, T5); + T3 = _mm_add_epi64(T3, T6); + T5 = _mm_mul_epu32(H3, p->S24.v); + T6 = _mm_mul_epu32(H3, p->R20.v); + T2 = _mm_add_epi64(T2, T5); + T3 = _mm_add_epi64(T3, T6); + T5 = _mm_mul_epu32(H4, p->S23.v); + T6 = _mm_mul_epu32(H4, p->S24.v); + T2 = _mm_add_epi64(T2, T5); + T3 = _mm_add_epi64(T3, T6); + T5 = _mm_mul_epu32(H1, p->R23.v); + T4 = _mm_add_epi64(T4, T5); + T5 = _mm_mul_epu32(H2, p->R22.v); + T4 = _mm_add_epi64(T4, T5); + T5 = _mm_mul_epu32(H3, p->R21.v); + T4 = _mm_add_epi64(T4, T5); + T5 = _mm_mul_epu32(H4, p->R20.v); + T4 = _mm_add_epi64(T4, T5); + + // H += [Mx,My]*[r^2,r^2] + T5 = _mm_unpacklo_epi64(_mm_loadl_epi64((const xmmi *)(m + 0)), + _mm_loadl_epi64((const xmmi *)(m + 16))); + T6 = _mm_unpacklo_epi64(_mm_loadl_epi64((const xmmi *)(m + 8)), + _mm_loadl_epi64((const xmmi *)(m + 24))); + M0 = _mm_and_si128(MMASK, T5); + M1 = _mm_and_si128(MMASK, _mm_srli_epi64(T5, 26)); + T5 = _mm_or_si128(_mm_srli_epi64(T5, 52), _mm_slli_epi64(T6, 12)); + M2 = _mm_and_si128(MMASK, T5); + M3 = _mm_and_si128(MMASK, _mm_srli_epi64(T5, 26)); + M4 = _mm_or_si128(_mm_srli_epi64(T6, 40), HIBIT); + + p = &st->P[1]; + T5 = _mm_mul_epu32(M0, p->R20.v); + T6 = _mm_mul_epu32(M0, p->R21.v); + T0 = _mm_add_epi64(T0, T5); + T1 = _mm_add_epi64(T1, T6); + T5 = _mm_mul_epu32(M1, p->S24.v); + T6 = _mm_mul_epu32(M1, p->R20.v); + T0 = _mm_add_epi64(T0, T5); + T1 = _mm_add_epi64(T1, T6); + T5 = _mm_mul_epu32(M2, p->S23.v); + T6 = _mm_mul_epu32(M2, p->S24.v); + T0 = _mm_add_epi64(T0, T5); + T1 = _mm_add_epi64(T1, T6); + T5 = _mm_mul_epu32(M3, p->S22.v); + T6 = _mm_mul_epu32(M3, p->S23.v); + T0 = _mm_add_epi64(T0, T5); + T1 = _mm_add_epi64(T1, T6); + T5 = _mm_mul_epu32(M4, p->S21.v); + T6 = _mm_mul_epu32(M4, p->S22.v); + T0 = _mm_add_epi64(T0, T5); + T1 = _mm_add_epi64(T1, T6); + T5 = _mm_mul_epu32(M0, p->R22.v); + T6 = _mm_mul_epu32(M0, p->R23.v); + T2 = _mm_add_epi64(T2, T5); + T3 = _mm_add_epi64(T3, T6); + T5 = _mm_mul_epu32(M1, p->R21.v); + T6 = _mm_mul_epu32(M1, p->R22.v); + T2 = _mm_add_epi64(T2, T5); + T3 = _mm_add_epi64(T3, T6); + T5 = _mm_mul_epu32(M2, p->R20.v); + T6 = _mm_mul_epu32(M2, p->R21.v); + T2 = _mm_add_epi64(T2, T5); + T3 = _mm_add_epi64(T3, T6); + T5 = _mm_mul_epu32(M3, p->S24.v); + T6 = _mm_mul_epu32(M3, p->R20.v); + T2 = _mm_add_epi64(T2, T5); + T3 = _mm_add_epi64(T3, T6); + T5 = _mm_mul_epu32(M4, p->S23.v); + T6 = _mm_mul_epu32(M4, p->S24.v); + T2 = _mm_add_epi64(T2, T5); + T3 = _mm_add_epi64(T3, T6); + T5 = _mm_mul_epu32(M0, p->R24.v); + T4 = _mm_add_epi64(T4, T5); + T5 = _mm_mul_epu32(M1, p->R23.v); + T4 = _mm_add_epi64(T4, T5); + T5 = _mm_mul_epu32(M2, p->R22.v); + T4 = _mm_add_epi64(T4, T5); + T5 = _mm_mul_epu32(M3, p->R21.v); + T4 = _mm_add_epi64(T4, T5); + T5 = _mm_mul_epu32(M4, p->R20.v); + T4 = _mm_add_epi64(T4, T5); + + // H += [Mx,My] + T5 = _mm_unpacklo_epi64(_mm_loadl_epi64((const xmmi *)(m + 32)), + _mm_loadl_epi64((const xmmi *)(m + 48))); + T6 = _mm_unpacklo_epi64(_mm_loadl_epi64((const xmmi *)(m + 40)), + _mm_loadl_epi64((const xmmi *)(m + 56))); + M0 = _mm_and_si128(MMASK, T5); + M1 = _mm_and_si128(MMASK, _mm_srli_epi64(T5, 26)); + T5 = _mm_or_si128(_mm_srli_epi64(T5, 52), _mm_slli_epi64(T6, 12)); + M2 = _mm_and_si128(MMASK, T5); + M3 = _mm_and_si128(MMASK, _mm_srli_epi64(T5, 26)); + M4 = _mm_or_si128(_mm_srli_epi64(T6, 40), HIBIT); + + T0 = _mm_add_epi64(T0, M0); + T1 = _mm_add_epi64(T1, M1); + T2 = _mm_add_epi64(T2, M2); + T3 = _mm_add_epi64(T3, M3); + T4 = _mm_add_epi64(T4, M4); + + // reduce + C1 = _mm_srli_epi64(T0, 26); + C2 = _mm_srli_epi64(T3, 26); + T0 = _mm_and_si128(T0, MMASK); + T3 = _mm_and_si128(T3, MMASK); + T1 = _mm_add_epi64(T1, C1); + T4 = _mm_add_epi64(T4, C2); + C1 = _mm_srli_epi64(T1, 26); + C2 = _mm_srli_epi64(T4, 26); + T1 = _mm_and_si128(T1, MMASK); + T4 = _mm_and_si128(T4, MMASK); + T2 = _mm_add_epi64(T2, C1); + T0 = _mm_add_epi64(T0, _mm_mul_epu32(C2, FIVE)); + C1 = _mm_srli_epi64(T2, 26); + C2 = _mm_srli_epi64(T0, 26); + T2 = _mm_and_si128(T2, MMASK); + T0 = _mm_and_si128(T0, MMASK); + T3 = _mm_add_epi64(T3, C1); + T1 = _mm_add_epi64(T1, C2); + C1 = _mm_srli_epi64(T3, 26); + T3 = _mm_and_si128(T3, MMASK); + T4 = _mm_add_epi64(T4, C1); + + // H = (H*[r^4,r^4] + [Mx,My]*[r^2,r^2] + [Mx,My]) + H0 = T0; + H1 = T1; + H2 = T2; + H3 = T3; + H4 = T4; + + m += 64; + bytes -= 64; + } + + st->H[0] = H0; + st->H[1] = H1; + st->H[2] = H2; + st->H[3] = H3; + st->H[4] = H4; +} + +static size_t poly1305_combine(poly1305_state_internal *st, const uint8_t *m, + size_t bytes) { + const xmmi MMASK = _mm_load_si128((const xmmi *)poly1305_x64_sse2_message_mask); + const xmmi HIBIT = _mm_load_si128((const xmmi *)poly1305_x64_sse2_1shl128); + const xmmi FIVE = _mm_load_si128((const xmmi *)poly1305_x64_sse2_5); + + poly1305_power *p; + xmmi H0, H1, H2, H3, H4; + xmmi M0, M1, M2, M3, M4; + xmmi T0, T1, T2, T3, T4, T5, T6; + xmmi C1, C2; + + uint64_t r0, r1, r2; + uint64_t t0, t1, t2, t3, t4; + uint64_t c; + size_t consumed = 0; + + H0 = st->H[0]; + H1 = st->H[1]; + H2 = st->H[2]; + H3 = st->H[3]; + H4 = st->H[4]; + + // p = [r^2,r^2] + p = &st->P[1]; + + if (bytes >= 32) { + // H *= [r^2,r^2] + T0 = _mm_mul_epu32(H0, p->R20.v); + T1 = _mm_mul_epu32(H0, p->R21.v); + T2 = _mm_mul_epu32(H0, p->R22.v); + T3 = _mm_mul_epu32(H0, p->R23.v); + T4 = _mm_mul_epu32(H0, p->R24.v); + T5 = _mm_mul_epu32(H1, p->S24.v); + T6 = _mm_mul_epu32(H1, p->R20.v); + T0 = _mm_add_epi64(T0, T5); + T1 = _mm_add_epi64(T1, T6); + T5 = _mm_mul_epu32(H2, p->S23.v); + T6 = _mm_mul_epu32(H2, p->S24.v); + T0 = _mm_add_epi64(T0, T5); + T1 = _mm_add_epi64(T1, T6); + T5 = _mm_mul_epu32(H3, p->S22.v); + T6 = _mm_mul_epu32(H3, p->S23.v); + T0 = _mm_add_epi64(T0, T5); + T1 = _mm_add_epi64(T1, T6); + T5 = _mm_mul_epu32(H4, p->S21.v); + T6 = _mm_mul_epu32(H4, p->S22.v); + T0 = _mm_add_epi64(T0, T5); + T1 = _mm_add_epi64(T1, T6); + T5 = _mm_mul_epu32(H1, p->R21.v); + T6 = _mm_mul_epu32(H1, p->R22.v); + T2 = _mm_add_epi64(T2, T5); + T3 = _mm_add_epi64(T3, T6); + T5 = _mm_mul_epu32(H2, p->R20.v); + T6 = _mm_mul_epu32(H2, p->R21.v); + T2 = _mm_add_epi64(T2, T5); + T3 = _mm_add_epi64(T3, T6); + T5 = _mm_mul_epu32(H3, p->S24.v); + T6 = _mm_mul_epu32(H3, p->R20.v); + T2 = _mm_add_epi64(T2, T5); + T3 = _mm_add_epi64(T3, T6); + T5 = _mm_mul_epu32(H4, p->S23.v); + T6 = _mm_mul_epu32(H4, p->S24.v); + T2 = _mm_add_epi64(T2, T5); + T3 = _mm_add_epi64(T3, T6); + T5 = _mm_mul_epu32(H1, p->R23.v); + T4 = _mm_add_epi64(T4, T5); + T5 = _mm_mul_epu32(H2, p->R22.v); + T4 = _mm_add_epi64(T4, T5); + T5 = _mm_mul_epu32(H3, p->R21.v); + T4 = _mm_add_epi64(T4, T5); + T5 = _mm_mul_epu32(H4, p->R20.v); + T4 = _mm_add_epi64(T4, T5); + + // H += [Mx,My] + T5 = _mm_unpacklo_epi64(_mm_loadl_epi64((const xmmi *)(m + 0)), + _mm_loadl_epi64((const xmmi *)(m + 16))); + T6 = _mm_unpacklo_epi64(_mm_loadl_epi64((const xmmi *)(m + 8)), + _mm_loadl_epi64((const xmmi *)(m + 24))); + M0 = _mm_and_si128(MMASK, T5); + M1 = _mm_and_si128(MMASK, _mm_srli_epi64(T5, 26)); + T5 = _mm_or_si128(_mm_srli_epi64(T5, 52), _mm_slli_epi64(T6, 12)); + M2 = _mm_and_si128(MMASK, T5); + M3 = _mm_and_si128(MMASK, _mm_srli_epi64(T5, 26)); + M4 = _mm_or_si128(_mm_srli_epi64(T6, 40), HIBIT); + + T0 = _mm_add_epi64(T0, M0); + T1 = _mm_add_epi64(T1, M1); + T2 = _mm_add_epi64(T2, M2); + T3 = _mm_add_epi64(T3, M3); + T4 = _mm_add_epi64(T4, M4); + + // reduce + C1 = _mm_srli_epi64(T0, 26); + C2 = _mm_srli_epi64(T3, 26); + T0 = _mm_and_si128(T0, MMASK); + T3 = _mm_and_si128(T3, MMASK); + T1 = _mm_add_epi64(T1, C1); + T4 = _mm_add_epi64(T4, C2); + C1 = _mm_srli_epi64(T1, 26); + C2 = _mm_srli_epi64(T4, 26); + T1 = _mm_and_si128(T1, MMASK); + T4 = _mm_and_si128(T4, MMASK); + T2 = _mm_add_epi64(T2, C1); + T0 = _mm_add_epi64(T0, _mm_mul_epu32(C2, FIVE)); + C1 = _mm_srli_epi64(T2, 26); + C2 = _mm_srli_epi64(T0, 26); + T2 = _mm_and_si128(T2, MMASK); + T0 = _mm_and_si128(T0, MMASK); + T3 = _mm_add_epi64(T3, C1); + T1 = _mm_add_epi64(T1, C2); + C1 = _mm_srli_epi64(T3, 26); + T3 = _mm_and_si128(T3, MMASK); + T4 = _mm_add_epi64(T4, C1); + + // H = (H*[r^2,r^2] + [Mx,My]) + H0 = T0; + H1 = T1; + H2 = T2; + H3 = T3; + H4 = T4; + + consumed = 32; + } + + // finalize, H *= [r^2,r] + r0 = ((uint64_t)p->R20.d[3] << 32) | (uint64_t)p->R20.d[1]; + r1 = ((uint64_t)p->R21.d[3] << 32) | (uint64_t)p->R21.d[1]; + r2 = ((uint64_t)p->R22.d[3] << 32) | (uint64_t)p->R22.d[1]; + + p->R20.d[2] = (uint32_t)(r0)&0x3ffffff; + p->R21.d[2] = (uint32_t)((r0 >> 26) | (r1 << 18)) & 0x3ffffff; + p->R22.d[2] = (uint32_t)((r1 >> 8)) & 0x3ffffff; + p->R23.d[2] = (uint32_t)((r1 >> 34) | (r2 << 10)) & 0x3ffffff; + p->R24.d[2] = (uint32_t)((r2 >> 16)); + p->S21.d[2] = p->R21.d[2] * 5; + p->S22.d[2] = p->R22.d[2] * 5; + p->S23.d[2] = p->R23.d[2] * 5; + p->S24.d[2] = p->R24.d[2] * 5; + + // H *= [r^2,r] + T0 = _mm_mul_epu32(H0, p->R20.v); + T1 = _mm_mul_epu32(H0, p->R21.v); + T2 = _mm_mul_epu32(H0, p->R22.v); + T3 = _mm_mul_epu32(H0, p->R23.v); + T4 = _mm_mul_epu32(H0, p->R24.v); + T5 = _mm_mul_epu32(H1, p->S24.v); + T6 = _mm_mul_epu32(H1, p->R20.v); + T0 = _mm_add_epi64(T0, T5); + T1 = _mm_add_epi64(T1, T6); + T5 = _mm_mul_epu32(H2, p->S23.v); + T6 = _mm_mul_epu32(H2, p->S24.v); + T0 = _mm_add_epi64(T0, T5); + T1 = _mm_add_epi64(T1, T6); + T5 = _mm_mul_epu32(H3, p->S22.v); + T6 = _mm_mul_epu32(H3, p->S23.v); + T0 = _mm_add_epi64(T0, T5); + T1 = _mm_add_epi64(T1, T6); + T5 = _mm_mul_epu32(H4, p->S21.v); + T6 = _mm_mul_epu32(H4, p->S22.v); + T0 = _mm_add_epi64(T0, T5); + T1 = _mm_add_epi64(T1, T6); + T5 = _mm_mul_epu32(H1, p->R21.v); + T6 = _mm_mul_epu32(H1, p->R22.v); + T2 = _mm_add_epi64(T2, T5); + T3 = _mm_add_epi64(T3, T6); + T5 = _mm_mul_epu32(H2, p->R20.v); + T6 = _mm_mul_epu32(H2, p->R21.v); + T2 = _mm_add_epi64(T2, T5); + T3 = _mm_add_epi64(T3, T6); + T5 = _mm_mul_epu32(H3, p->S24.v); + T6 = _mm_mul_epu32(H3, p->R20.v); + T2 = _mm_add_epi64(T2, T5); + T3 = _mm_add_epi64(T3, T6); + T5 = _mm_mul_epu32(H4, p->S23.v); + T6 = _mm_mul_epu32(H4, p->S24.v); + T2 = _mm_add_epi64(T2, T5); + T3 = _mm_add_epi64(T3, T6); + T5 = _mm_mul_epu32(H1, p->R23.v); + T4 = _mm_add_epi64(T4, T5); + T5 = _mm_mul_epu32(H2, p->R22.v); + T4 = _mm_add_epi64(T4, T5); + T5 = _mm_mul_epu32(H3, p->R21.v); + T4 = _mm_add_epi64(T4, T5); + T5 = _mm_mul_epu32(H4, p->R20.v); + T4 = _mm_add_epi64(T4, T5); + + C1 = _mm_srli_epi64(T0, 26); + C2 = _mm_srli_epi64(T3, 26); + T0 = _mm_and_si128(T0, MMASK); + T3 = _mm_and_si128(T3, MMASK); + T1 = _mm_add_epi64(T1, C1); + T4 = _mm_add_epi64(T4, C2); + C1 = _mm_srli_epi64(T1, 26); + C2 = _mm_srli_epi64(T4, 26); + T1 = _mm_and_si128(T1, MMASK); + T4 = _mm_and_si128(T4, MMASK); + T2 = _mm_add_epi64(T2, C1); + T0 = _mm_add_epi64(T0, _mm_mul_epu32(C2, FIVE)); + C1 = _mm_srli_epi64(T2, 26); + C2 = _mm_srli_epi64(T0, 26); + T2 = _mm_and_si128(T2, MMASK); + T0 = _mm_and_si128(T0, MMASK); + T3 = _mm_add_epi64(T3, C1); + T1 = _mm_add_epi64(T1, C2); + C1 = _mm_srli_epi64(T3, 26); + T3 = _mm_and_si128(T3, MMASK); + T4 = _mm_add_epi64(T4, C1); + + // H = H[0]+H[1] + H0 = _mm_add_epi64(T0, _mm_srli_si128(T0, 8)); + H1 = _mm_add_epi64(T1, _mm_srli_si128(T1, 8)); + H2 = _mm_add_epi64(T2, _mm_srli_si128(T2, 8)); + H3 = _mm_add_epi64(T3, _mm_srli_si128(T3, 8)); + H4 = _mm_add_epi64(T4, _mm_srli_si128(T4, 8)); + + t0 = _mm_cvtsi128_si32(H0); + c = (t0 >> 26); + t0 &= 0x3ffffff; + t1 = _mm_cvtsi128_si32(H1) + c; + c = (t1 >> 26); + t1 &= 0x3ffffff; + t2 = _mm_cvtsi128_si32(H2) + c; + c = (t2 >> 26); + t2 &= 0x3ffffff; + t3 = _mm_cvtsi128_si32(H3) + c; + c = (t3 >> 26); + t3 &= 0x3ffffff; + t4 = _mm_cvtsi128_si32(H4) + c; + c = (t4 >> 26); + t4 &= 0x3ffffff; + t0 = t0 + (c * 5); + c = (t0 >> 26); + t0 &= 0x3ffffff; + t1 = t1 + c; + + st->HH[0] = ((t0) | (t1 << 26)) & UINT64_C(0xfffffffffff); + st->HH[1] = ((t1 >> 18) | (t2 << 8) | (t3 << 34)) & UINT64_C(0xfffffffffff); + st->HH[2] = ((t3 >> 10) | (t4 << 16)) & UINT64_C(0x3ffffffffff); + + return consumed; +} + +void CRYPTO_poly1305_update(poly1305_state *state, const uint8_t *m, + size_t bytes) { + poly1305_state_internal *st = poly1305_aligned_state(state); + size_t want; + + // need at least 32 initial bytes to start the accelerated branch + if (!st->started) { + if ((st->leftover == 0) && (bytes > 32)) { + poly1305_first_block(st, m); + m += 32; + bytes -= 32; + } else { + want = poly1305_min(32 - st->leftover, bytes); + OPENSSL_memcpy(st->buffer + st->leftover, m, want); + bytes -= want; + m += want; + st->leftover += want; + if ((st->leftover < 32) || (bytes == 0)) { + return; + } + poly1305_first_block(st, st->buffer); + st->leftover = 0; + } + st->started = 1; + } + + // handle leftover + if (st->leftover) { + want = poly1305_min(64 - st->leftover, bytes); + OPENSSL_memcpy(st->buffer + st->leftover, m, want); + bytes -= want; + m += want; + st->leftover += want; + if (st->leftover < 64) { + return; + } + poly1305_blocks(st, st->buffer, 64); + st->leftover = 0; + } + + // process 64 byte blocks + if (bytes >= 64) { + want = (bytes & ~63); + poly1305_blocks(st, m, want); + m += want; + bytes -= want; + } + + if (bytes) { + OPENSSL_memcpy(st->buffer + st->leftover, m, bytes); + st->leftover += bytes; + } +} + +void CRYPTO_poly1305_finish(poly1305_state *state, uint8_t mac[16]) { + poly1305_state_internal *st = poly1305_aligned_state(state); + size_t leftover = st->leftover; + uint8_t *m = st->buffer; + uint128_t d[3]; + uint64_t h0, h1, h2; + uint64_t t0, t1; + uint64_t g0, g1, g2, c, nc; + uint64_t r0, r1, r2, s1, s2; + poly1305_power *p; + + if (st->started) { + size_t consumed = poly1305_combine(st, m, leftover); + leftover -= consumed; + m += consumed; + } + + // st->HH will either be 0 or have the combined result + h0 = st->HH[0]; + h1 = st->HH[1]; + h2 = st->HH[2]; + + p = &st->P[1]; + r0 = ((uint64_t)p->R20.d[3] << 32) | (uint64_t)p->R20.d[1]; + r1 = ((uint64_t)p->R21.d[3] << 32) | (uint64_t)p->R21.d[1]; + r2 = ((uint64_t)p->R22.d[3] << 32) | (uint64_t)p->R22.d[1]; + s1 = r1 * (5 << 2); + s2 = r2 * (5 << 2); + + if (leftover < 16) { + goto poly1305_donna_atmost15bytes; + } + +poly1305_donna_atleast16bytes: + t0 = U8TO64_LE(m + 0); + t1 = U8TO64_LE(m + 8); + h0 += t0 & 0xfffffffffff; + t0 = shr128_pair(t1, t0, 44); + h1 += t0 & 0xfffffffffff; + h2 += (t1 >> 24) | ((uint64_t)1 << 40); + +poly1305_donna_mul: + d[0] = add128(add128(mul64x64_128(h0, r0), mul64x64_128(h1, s2)), + mul64x64_128(h2, s1)); + d[1] = add128(add128(mul64x64_128(h0, r1), mul64x64_128(h1, r0)), + mul64x64_128(h2, s2)); + d[2] = add128(add128(mul64x64_128(h0, r2), mul64x64_128(h1, r1)), + mul64x64_128(h2, r0)); + h0 = lo128(d[0]) & 0xfffffffffff; + c = shr128(d[0], 44); + d[1] = add128_64(d[1], c); + h1 = lo128(d[1]) & 0xfffffffffff; + c = shr128(d[1], 44); + d[2] = add128_64(d[2], c); + h2 = lo128(d[2]) & 0x3ffffffffff; + c = shr128(d[2], 42); + h0 += c * 5; + + m += 16; + leftover -= 16; + if (leftover >= 16) { + goto poly1305_donna_atleast16bytes; + } + +// final bytes +poly1305_donna_atmost15bytes: + if (!leftover) { + goto poly1305_donna_finish; + } + + m[leftover++] = 1; + OPENSSL_memset(m + leftover, 0, 16 - leftover); + leftover = 16; + + t0 = U8TO64_LE(m + 0); + t1 = U8TO64_LE(m + 8); + h0 += t0 & 0xfffffffffff; + t0 = shr128_pair(t1, t0, 44); + h1 += t0 & 0xfffffffffff; + h2 += (t1 >> 24); + + goto poly1305_donna_mul; + +poly1305_donna_finish: + c = (h0 >> 44); + h0 &= 0xfffffffffff; + h1 += c; + c = (h1 >> 44); + h1 &= 0xfffffffffff; + h2 += c; + c = (h2 >> 42); + h2 &= 0x3ffffffffff; + h0 += c * 5; + + g0 = h0 + 5; + c = (g0 >> 44); + g0 &= 0xfffffffffff; + g1 = h1 + c; + c = (g1 >> 44); + g1 &= 0xfffffffffff; + g2 = h2 + c - ((uint64_t)1 << 42); + + c = (g2 >> 63) - 1; + nc = ~c; + h0 = (h0 & nc) | (g0 & c); + h1 = (h1 & nc) | (g1 & c); + h2 = (h2 & nc) | (g2 & c); + + // pad + t0 = ((uint64_t)p->R23.d[3] << 32) | (uint64_t)p->R23.d[1]; + t1 = ((uint64_t)p->R24.d[3] << 32) | (uint64_t)p->R24.d[1]; + h0 += (t0 & 0xfffffffffff); + c = (h0 >> 44); + h0 &= 0xfffffffffff; + t0 = shr128_pair(t1, t0, 44); + h1 += (t0 & 0xfffffffffff) + c; + c = (h1 >> 44); + h1 &= 0xfffffffffff; + t1 = (t1 >> 24); + h2 += (t1)+c; + + U64TO8_LE(mac + 0, ((h0) | (h1 << 44))); + U64TO8_LE(mac + 8, ((h1 >> 20) | (h2 << 24))); +} + +#endif // !OPENSSL_WINDOWS && OPENSSL_X86_64 diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/pool/internal.h b/FoodApp/Pods/BoringSSL-GRPC/crypto/pool/internal.h new file mode 100644 index 0000000..6dad521 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/pool/internal.h @@ -0,0 +1,45 @@ +/* Copyright (c) 2016, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_POOL_INTERNAL_H +#define OPENSSL_HEADER_POOL_INTERNAL_H + +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +DECLARE_LHASH_OF(CRYPTO_BUFFER); + +struct crypto_buffer_st { + CRYPTO_BUFFER_POOL *pool; + uint8_t *data; + size_t len; + CRYPTO_refcount_t references; +}; + +struct crypto_buffer_pool_st { + LHASH_OF(CRYPTO_BUFFER) *bufs; + CRYPTO_MUTEX lock; +}; + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_POOL_INTERNAL_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/pool/internal.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/pool/internal.h.grpc_back new file mode 100644 index 0000000..5b288eb --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/pool/internal.h.grpc_back @@ -0,0 +1,45 @@ +/* Copyright (c) 2016, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_POOL_INTERNAL_H +#define OPENSSL_HEADER_POOL_INTERNAL_H + +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +DECLARE_LHASH_OF(CRYPTO_BUFFER); + +struct crypto_buffer_st { + CRYPTO_BUFFER_POOL *pool; + uint8_t *data; + size_t len; + CRYPTO_refcount_t references; +}; + +struct crypto_buffer_pool_st { + LHASH_OF(CRYPTO_BUFFER) *bufs; + CRYPTO_MUTEX lock; +}; + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_POOL_INTERNAL_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/pool/pool.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/pool/pool.c new file mode 100644 index 0000000..af57f2a --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/pool/pool.c @@ -0,0 +1,200 @@ +/* Copyright (c) 2016, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include +#include + +#include +#include +#include +#include + +#include "../internal.h" +#include "internal.h" + + +static uint32_t CRYPTO_BUFFER_hash(const CRYPTO_BUFFER *buf) { + return OPENSSL_hash32(buf->data, buf->len); +} + +static int CRYPTO_BUFFER_cmp(const CRYPTO_BUFFER *a, const CRYPTO_BUFFER *b) { + if (a->len != b->len) { + return 1; + } + return OPENSSL_memcmp(a->data, b->data, a->len); +} + +CRYPTO_BUFFER_POOL* CRYPTO_BUFFER_POOL_new(void) { + CRYPTO_BUFFER_POOL *pool = OPENSSL_malloc(sizeof(CRYPTO_BUFFER_POOL)); + if (pool == NULL) { + return NULL; + } + + OPENSSL_memset(pool, 0, sizeof(CRYPTO_BUFFER_POOL)); + pool->bufs = lh_CRYPTO_BUFFER_new(CRYPTO_BUFFER_hash, CRYPTO_BUFFER_cmp); + if (pool->bufs == NULL) { + OPENSSL_free(pool); + return NULL; + } + + CRYPTO_MUTEX_init(&pool->lock); + + return pool; +} + +void CRYPTO_BUFFER_POOL_free(CRYPTO_BUFFER_POOL *pool) { + if (pool == NULL) { + return; + } + +#if !defined(NDEBUG) + CRYPTO_MUTEX_lock_write(&pool->lock); + assert(lh_CRYPTO_BUFFER_num_items(pool->bufs) == 0); + CRYPTO_MUTEX_unlock_write(&pool->lock); +#endif + + lh_CRYPTO_BUFFER_free(pool->bufs); + CRYPTO_MUTEX_cleanup(&pool->lock); + OPENSSL_free(pool); +} + +CRYPTO_BUFFER *CRYPTO_BUFFER_new(const uint8_t *data, size_t len, + CRYPTO_BUFFER_POOL *pool) { + if (pool != NULL) { + CRYPTO_BUFFER tmp; + tmp.data = (uint8_t *) data; + tmp.len = len; + + CRYPTO_MUTEX_lock_read(&pool->lock); + CRYPTO_BUFFER *const duplicate = + lh_CRYPTO_BUFFER_retrieve(pool->bufs, &tmp); + if (duplicate != NULL) { + CRYPTO_refcount_inc(&duplicate->references); + } + CRYPTO_MUTEX_unlock_read(&pool->lock); + + if (duplicate != NULL) { + return duplicate; + } + } + + CRYPTO_BUFFER *const buf = OPENSSL_malloc(sizeof(CRYPTO_BUFFER)); + if (buf == NULL) { + return NULL; + } + OPENSSL_memset(buf, 0, sizeof(CRYPTO_BUFFER)); + + buf->data = BUF_memdup(data, len); + if (len != 0 && buf->data == NULL) { + OPENSSL_free(buf); + return NULL; + } + + buf->len = len; + buf->references = 1; + + if (pool == NULL) { + return buf; + } + + buf->pool = pool; + + CRYPTO_MUTEX_lock_write(&pool->lock); + CRYPTO_BUFFER *duplicate = lh_CRYPTO_BUFFER_retrieve(pool->bufs, buf); + int inserted = 0; + if (duplicate == NULL) { + CRYPTO_BUFFER *old = NULL; + inserted = lh_CRYPTO_BUFFER_insert(pool->bufs, &old, buf); + assert(old == NULL); + } else { + CRYPTO_refcount_inc(&duplicate->references); + } + CRYPTO_MUTEX_unlock_write(&pool->lock); + + if (!inserted) { + // We raced to insert |buf| into the pool and lost, or else there was an + // error inserting. + OPENSSL_free(buf->data); + OPENSSL_free(buf); + return duplicate; + } + + return buf; +} + +CRYPTO_BUFFER* CRYPTO_BUFFER_new_from_CBS(CBS *cbs, CRYPTO_BUFFER_POOL *pool) { + return CRYPTO_BUFFER_new(CBS_data(cbs), CBS_len(cbs), pool); +} + +void CRYPTO_BUFFER_free(CRYPTO_BUFFER *buf) { + if (buf == NULL) { + return; + } + + CRYPTO_BUFFER_POOL *const pool = buf->pool; + if (pool == NULL) { + if (CRYPTO_refcount_dec_and_test_zero(&buf->references)) { + // If a reference count of zero is observed, there cannot be a reference + // from any pool to this buffer and thus we are able to free this + // buffer. + OPENSSL_free(buf->data); + OPENSSL_free(buf); + } + + return; + } + + CRYPTO_MUTEX_lock_write(&pool->lock); + if (!CRYPTO_refcount_dec_and_test_zero(&buf->references)) { + CRYPTO_MUTEX_unlock_write(&buf->pool->lock); + return; + } + + // We have an exclusive lock on the pool, therefore no concurrent lookups can + // find this buffer and increment the reference count. Thus, if the count is + // zero there are and can never be any more references and thus we can free + // this buffer. + void *found = lh_CRYPTO_BUFFER_delete(pool->bufs, buf); + assert(found != NULL); + assert(found == buf); + (void)found; + CRYPTO_MUTEX_unlock_write(&buf->pool->lock); + OPENSSL_free(buf->data); + OPENSSL_free(buf); +} + +int CRYPTO_BUFFER_up_ref(CRYPTO_BUFFER *buf) { + // This is safe in the case that |buf->pool| is NULL because it's just + // standard reference counting in that case. + // + // This is also safe if |buf->pool| is non-NULL because, if it were racing + // with |CRYPTO_BUFFER_free| then the two callers must have independent + // references already and so the reference count will never hit zero. + CRYPTO_refcount_inc(&buf->references); + return 1; +} + +const uint8_t *CRYPTO_BUFFER_data(const CRYPTO_BUFFER *buf) { + return buf->data; +} + +size_t CRYPTO_BUFFER_len(const CRYPTO_BUFFER *buf) { + return buf->len; +} + +void CRYPTO_BUFFER_init_CBS(const CRYPTO_BUFFER *buf, CBS *out) { + CBS_init(out, buf->data, buf->len); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/pool/pool.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/pool/pool.c.grpc_back new file mode 100644 index 0000000..9cfbf1e --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/pool/pool.c.grpc_back @@ -0,0 +1,200 @@ +/* Copyright (c) 2016, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include +#include + +#include +#include +#include +#include + +#include "../internal.h" +#include "internal.h" + + +static uint32_t CRYPTO_BUFFER_hash(const CRYPTO_BUFFER *buf) { + return OPENSSL_hash32(buf->data, buf->len); +} + +static int CRYPTO_BUFFER_cmp(const CRYPTO_BUFFER *a, const CRYPTO_BUFFER *b) { + if (a->len != b->len) { + return 1; + } + return OPENSSL_memcmp(a->data, b->data, a->len); +} + +CRYPTO_BUFFER_POOL* CRYPTO_BUFFER_POOL_new(void) { + CRYPTO_BUFFER_POOL *pool = OPENSSL_malloc(sizeof(CRYPTO_BUFFER_POOL)); + if (pool == NULL) { + return NULL; + } + + OPENSSL_memset(pool, 0, sizeof(CRYPTO_BUFFER_POOL)); + pool->bufs = lh_CRYPTO_BUFFER_new(CRYPTO_BUFFER_hash, CRYPTO_BUFFER_cmp); + if (pool->bufs == NULL) { + OPENSSL_free(pool); + return NULL; + } + + CRYPTO_MUTEX_init(&pool->lock); + + return pool; +} + +void CRYPTO_BUFFER_POOL_free(CRYPTO_BUFFER_POOL *pool) { + if (pool == NULL) { + return; + } + +#if !defined(NDEBUG) + CRYPTO_MUTEX_lock_write(&pool->lock); + assert(lh_CRYPTO_BUFFER_num_items(pool->bufs) == 0); + CRYPTO_MUTEX_unlock_write(&pool->lock); +#endif + + lh_CRYPTO_BUFFER_free(pool->bufs); + CRYPTO_MUTEX_cleanup(&pool->lock); + OPENSSL_free(pool); +} + +CRYPTO_BUFFER *CRYPTO_BUFFER_new(const uint8_t *data, size_t len, + CRYPTO_BUFFER_POOL *pool) { + if (pool != NULL) { + CRYPTO_BUFFER tmp; + tmp.data = (uint8_t *) data; + tmp.len = len; + + CRYPTO_MUTEX_lock_read(&pool->lock); + CRYPTO_BUFFER *const duplicate = + lh_CRYPTO_BUFFER_retrieve(pool->bufs, &tmp); + if (duplicate != NULL) { + CRYPTO_refcount_inc(&duplicate->references); + } + CRYPTO_MUTEX_unlock_read(&pool->lock); + + if (duplicate != NULL) { + return duplicate; + } + } + + CRYPTO_BUFFER *const buf = OPENSSL_malloc(sizeof(CRYPTO_BUFFER)); + if (buf == NULL) { + return NULL; + } + OPENSSL_memset(buf, 0, sizeof(CRYPTO_BUFFER)); + + buf->data = BUF_memdup(data, len); + if (len != 0 && buf->data == NULL) { + OPENSSL_free(buf); + return NULL; + } + + buf->len = len; + buf->references = 1; + + if (pool == NULL) { + return buf; + } + + buf->pool = pool; + + CRYPTO_MUTEX_lock_write(&pool->lock); + CRYPTO_BUFFER *duplicate = lh_CRYPTO_BUFFER_retrieve(pool->bufs, buf); + int inserted = 0; + if (duplicate == NULL) { + CRYPTO_BUFFER *old = NULL; + inserted = lh_CRYPTO_BUFFER_insert(pool->bufs, &old, buf); + assert(old == NULL); + } else { + CRYPTO_refcount_inc(&duplicate->references); + } + CRYPTO_MUTEX_unlock_write(&pool->lock); + + if (!inserted) { + // We raced to insert |buf| into the pool and lost, or else there was an + // error inserting. + OPENSSL_free(buf->data); + OPENSSL_free(buf); + return duplicate; + } + + return buf; +} + +CRYPTO_BUFFER* CRYPTO_BUFFER_new_from_CBS(CBS *cbs, CRYPTO_BUFFER_POOL *pool) { + return CRYPTO_BUFFER_new(CBS_data(cbs), CBS_len(cbs), pool); +} + +void CRYPTO_BUFFER_free(CRYPTO_BUFFER *buf) { + if (buf == NULL) { + return; + } + + CRYPTO_BUFFER_POOL *const pool = buf->pool; + if (pool == NULL) { + if (CRYPTO_refcount_dec_and_test_zero(&buf->references)) { + // If a reference count of zero is observed, there cannot be a reference + // from any pool to this buffer and thus we are able to free this + // buffer. + OPENSSL_free(buf->data); + OPENSSL_free(buf); + } + + return; + } + + CRYPTO_MUTEX_lock_write(&pool->lock); + if (!CRYPTO_refcount_dec_and_test_zero(&buf->references)) { + CRYPTO_MUTEX_unlock_write(&buf->pool->lock); + return; + } + + // We have an exclusive lock on the pool, therefore no concurrent lookups can + // find this buffer and increment the reference count. Thus, if the count is + // zero there are and can never be any more references and thus we can free + // this buffer. + void *found = lh_CRYPTO_BUFFER_delete(pool->bufs, buf); + assert(found != NULL); + assert(found == buf); + (void)found; + CRYPTO_MUTEX_unlock_write(&buf->pool->lock); + OPENSSL_free(buf->data); + OPENSSL_free(buf); +} + +int CRYPTO_BUFFER_up_ref(CRYPTO_BUFFER *buf) { + // This is safe in the case that |buf->pool| is NULL because it's just + // standard reference counting in that case. + // + // This is also safe if |buf->pool| is non-NULL because, if it were racing + // with |CRYPTO_BUFFER_free| then the two callers must have independent + // references already and so the reference count will never hit zero. + CRYPTO_refcount_inc(&buf->references); + return 1; +} + +const uint8_t *CRYPTO_BUFFER_data(const CRYPTO_BUFFER *buf) { + return buf->data; +} + +size_t CRYPTO_BUFFER_len(const CRYPTO_BUFFER *buf) { + return buf->len; +} + +void CRYPTO_BUFFER_init_CBS(const CRYPTO_BUFFER *buf, CBS *out) { + CBS_init(out, buf->data, buf->len); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/rand_extra/deterministic.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/rand_extra/deterministic.c new file mode 100644 index 0000000..7950da8 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/rand_extra/deterministic.c @@ -0,0 +1,48 @@ +/* Copyright (c) 2016, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#if defined(BORINGSSL_UNSAFE_DETERMINISTIC_MODE) + +#include + +#include + +#include "../internal.h" +#include "../fipsmodule/rand/internal.h" + + +// g_num_calls is the number of calls to |CRYPTO_sysrand| that have occurred. +// +// This is intentionally not thread-safe. If the fuzzer mode is ever used in a +// multi-threaded program, replace this with a thread-local. (A mutex would not +// be deterministic.) +static uint64_t g_num_calls = 0; + +void RAND_reset_for_fuzzing(void) { g_num_calls = 0; } + +void CRYPTO_sysrand(uint8_t *out, size_t requested) { + static const uint8_t kZeroKey[32]; + + uint8_t nonce[12]; + OPENSSL_memset(nonce, 0, sizeof(nonce)); + OPENSSL_memcpy(nonce, &g_num_calls, sizeof(g_num_calls)); + + OPENSSL_memset(out, 0, requested); + CRYPTO_chacha_20(out, out, requested, kZeroKey, nonce, 0); + g_num_calls++; +} + +#endif // BORINGSSL_UNSAFE_DETERMINISTIC_MODE diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/rand_extra/deterministic.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/rand_extra/deterministic.c.grpc_back new file mode 100644 index 0000000..17fa71e --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/rand_extra/deterministic.c.grpc_back @@ -0,0 +1,48 @@ +/* Copyright (c) 2016, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#if defined(BORINGSSL_UNSAFE_DETERMINISTIC_MODE) + +#include + +#include + +#include "../internal.h" +#include "../fipsmodule/rand/internal.h" + + +// g_num_calls is the number of calls to |CRYPTO_sysrand| that have occurred. +// +// This is intentionally not thread-safe. If the fuzzer mode is ever used in a +// multi-threaded program, replace this with a thread-local. (A mutex would not +// be deterministic.) +static uint64_t g_num_calls = 0; + +void RAND_reset_for_fuzzing(void) { g_num_calls = 0; } + +void CRYPTO_sysrand(uint8_t *out, size_t requested) { + static const uint8_t kZeroKey[32]; + + uint8_t nonce[12]; + OPENSSL_memset(nonce, 0, sizeof(nonce)); + OPENSSL_memcpy(nonce, &g_num_calls, sizeof(g_num_calls)); + + OPENSSL_memset(out, 0, requested); + CRYPTO_chacha_20(out, out, requested, kZeroKey, nonce, 0); + g_num_calls++; +} + +#endif // BORINGSSL_UNSAFE_DETERMINISTIC_MODE diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/rand_extra/forkunsafe.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/rand_extra/forkunsafe.c new file mode 100644 index 0000000..bd90472 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/rand_extra/forkunsafe.c @@ -0,0 +1,46 @@ +/* Copyright (c) 2017, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include + +#include "../fipsmodule/rand/internal.h" + + +// g_buffering_enabled is true if fork-unsafe buffering has been enabled. +static int g_buffering_enabled = 0; + +// g_lock protects |g_buffering_enabled|. +static struct CRYPTO_STATIC_MUTEX g_lock = CRYPTO_STATIC_MUTEX_INIT; + +#if !defined(OPENSSL_WINDOWS) +void RAND_enable_fork_unsafe_buffering(int fd) { + // We no longer support setting the file-descriptor with this function. + if (fd != -1) { + abort(); + } + + CRYPTO_STATIC_MUTEX_lock_write(&g_lock); + g_buffering_enabled = 1; + CRYPTO_STATIC_MUTEX_unlock_write(&g_lock); +} +#endif + +int rand_fork_unsafe_buffering_enabled(void) { + CRYPTO_STATIC_MUTEX_lock_read(&g_lock); + const int ret = g_buffering_enabled; + CRYPTO_STATIC_MUTEX_unlock_read(&g_lock); + return ret; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/rand_extra/forkunsafe.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/rand_extra/forkunsafe.c.grpc_back new file mode 100644 index 0000000..0f1ecec --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/rand_extra/forkunsafe.c.grpc_back @@ -0,0 +1,46 @@ +/* Copyright (c) 2017, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include + +#include "../fipsmodule/rand/internal.h" + + +// g_buffering_enabled is true if fork-unsafe buffering has been enabled. +static int g_buffering_enabled = 0; + +// g_lock protects |g_buffering_enabled|. +static struct CRYPTO_STATIC_MUTEX g_lock = CRYPTO_STATIC_MUTEX_INIT; + +#if !defined(OPENSSL_WINDOWS) +void RAND_enable_fork_unsafe_buffering(int fd) { + // We no longer support setting the file-descriptor with this function. + if (fd != -1) { + abort(); + } + + CRYPTO_STATIC_MUTEX_lock_write(&g_lock); + g_buffering_enabled = 1; + CRYPTO_STATIC_MUTEX_unlock_write(&g_lock); +} +#endif + +int rand_fork_unsafe_buffering_enabled(void) { + CRYPTO_STATIC_MUTEX_lock_read(&g_lock); + const int ret = g_buffering_enabled; + CRYPTO_STATIC_MUTEX_unlock_read(&g_lock); + return ret; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/rand_extra/fuchsia.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/rand_extra/fuchsia.c new file mode 100644 index 0000000..5507d71 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/rand_extra/fuchsia.c @@ -0,0 +1,43 @@ +/* Copyright (c) 2017, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#if defined(OPENSSL_FUCHSIA) && !defined(BORINGSSL_UNSAFE_DETERMINISTIC_MODE) + +#include +#include + +#include + +#include "../fipsmodule/rand/internal.h" + +void CRYPTO_sysrand(uint8_t *out, size_t requested) { + while (requested > 0) { + size_t output_bytes_this_pass = ZX_CPRNG_DRAW_MAX_LEN; + if (requested < output_bytes_this_pass) { + output_bytes_this_pass = requested; + } + size_t bytes_drawn; + zx_status_t status = + zx_cprng_draw(out, output_bytes_this_pass, &bytes_drawn); + if (status != ZX_OK) { + abort(); + } + requested -= bytes_drawn; + out += bytes_drawn; + } +} + +#endif // OPENSSL_FUCHSIA && !BORINGSSL_UNSAFE_DETERMINISTIC_MODE diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/rand_extra/fuchsia.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/rand_extra/fuchsia.c.grpc_back new file mode 100644 index 0000000..ce8356c --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/rand_extra/fuchsia.c.grpc_back @@ -0,0 +1,43 @@ +/* Copyright (c) 2017, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#if defined(OPENSSL_FUCHSIA) && !defined(BORINGSSL_UNSAFE_DETERMINISTIC_MODE) + +#include +#include + +#include + +#include "../fipsmodule/rand/internal.h" + +void CRYPTO_sysrand(uint8_t *out, size_t requested) { + while (requested > 0) { + size_t output_bytes_this_pass = ZX_CPRNG_DRAW_MAX_LEN; + if (requested < output_bytes_this_pass) { + output_bytes_this_pass = requested; + } + size_t bytes_drawn; + zx_status_t status = + zx_cprng_draw(out, output_bytes_this_pass, &bytes_drawn); + if (status != ZX_OK) { + abort(); + } + requested -= bytes_drawn; + out += bytes_drawn; + } +} + +#endif // OPENSSL_FUCHSIA && !BORINGSSL_UNSAFE_DETERMINISTIC_MODE diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/rand_extra/rand_extra.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/rand_extra/rand_extra.c new file mode 100644 index 0000000..7c3c66f --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/rand_extra/rand_extra.c @@ -0,0 +1,70 @@ +/* Copyright (c) 2017, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include + + +void RAND_seed(const void *buf, int num) { + // OpenSSH calls |RAND_seed| before jailing on the assumption that any needed + // file descriptors etc will be opened. + uint8_t unused; + RAND_bytes(&unused, sizeof(unused)); +} + +int RAND_load_file(const char *path, long num) { + if (num < 0) { // read the "whole file" + return 1; + } else if (num <= INT_MAX) { + return (int) num; + } else { + return INT_MAX; + } +} + +const char *RAND_file_name(char *buf, size_t num) { return NULL; } + +void RAND_add(const void *buf, int num, double entropy) {} + +int RAND_egd(const char *path) { + return 255; +} + +int RAND_poll(void) { + return 1; +} + +int RAND_status(void) { + return 1; +} + +static const struct rand_meth_st kSSLeayMethod = { + RAND_seed, + RAND_bytes, + RAND_cleanup, + RAND_add, + RAND_pseudo_bytes, + RAND_status, +}; + +RAND_METHOD *RAND_SSLeay(void) { + return (RAND_METHOD*) &kSSLeayMethod; +} + +const RAND_METHOD *RAND_get_rand_method(void) { return RAND_SSLeay(); } + +void RAND_set_rand_method(const RAND_METHOD *method) {} + +void RAND_cleanup(void) {} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/rand_extra/rand_extra.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/rand_extra/rand_extra.c.grpc_back new file mode 100644 index 0000000..bed9e1e --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/rand_extra/rand_extra.c.grpc_back @@ -0,0 +1,70 @@ +/* Copyright (c) 2017, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include + + +void RAND_seed(const void *buf, int num) { + // OpenSSH calls |RAND_seed| before jailing on the assumption that any needed + // file descriptors etc will be opened. + uint8_t unused; + RAND_bytes(&unused, sizeof(unused)); +} + +int RAND_load_file(const char *path, long num) { + if (num < 0) { // read the "whole file" + return 1; + } else if (num <= INT_MAX) { + return (int) num; + } else { + return INT_MAX; + } +} + +const char *RAND_file_name(char *buf, size_t num) { return NULL; } + +void RAND_add(const void *buf, int num, double entropy) {} + +int RAND_egd(const char *path) { + return 255; +} + +int RAND_poll(void) { + return 1; +} + +int RAND_status(void) { + return 1; +} + +static const struct rand_meth_st kSSLeayMethod = { + RAND_seed, + RAND_bytes, + RAND_cleanup, + RAND_add, + RAND_pseudo_bytes, + RAND_status, +}; + +RAND_METHOD *RAND_SSLeay(void) { + return (RAND_METHOD*) &kSSLeayMethod; +} + +const RAND_METHOD *RAND_get_rand_method(void) { return RAND_SSLeay(); } + +void RAND_set_rand_method(const RAND_METHOD *method) {} + +void RAND_cleanup(void) {} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/rand_extra/windows.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/rand_extra/windows.c new file mode 100644 index 0000000..c524633 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/rand_extra/windows.c @@ -0,0 +1,53 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#if defined(OPENSSL_WINDOWS) && !defined(BORINGSSL_UNSAFE_DETERMINISTIC_MODE) + +#include +#include + +OPENSSL_MSVC_PRAGMA(warning(push, 3)) + +#include + +// #define needed to link in RtlGenRandom(), a.k.a. SystemFunction036. See the +// "Community Additions" comment on MSDN here: +// http://msdn.microsoft.com/en-us/library/windows/desktop/aa387694.aspx +#define SystemFunction036 NTAPI SystemFunction036 +#include +#undef SystemFunction036 + +OPENSSL_MSVC_PRAGMA(warning(pop)) + +#include "../fipsmodule/rand/internal.h" + + +void CRYPTO_sysrand(uint8_t *out, size_t requested) { + while (requested > 0) { + ULONG output_bytes_this_pass = ULONG_MAX; + if (requested < output_bytes_this_pass) { + output_bytes_this_pass = (ULONG)requested; + } + if (RtlGenRandom(out, output_bytes_this_pass) == FALSE) { + abort(); + } + requested -= output_bytes_this_pass; + out += output_bytes_this_pass; + } + return; +} + +#endif // OPENSSL_WINDOWS && !BORINGSSL_UNSAFE_DETERMINISTIC_MODE diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/rand_extra/windows.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/rand_extra/windows.c.grpc_back new file mode 100644 index 0000000..c955587 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/rand_extra/windows.c.grpc_back @@ -0,0 +1,53 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#if defined(OPENSSL_WINDOWS) && !defined(BORINGSSL_UNSAFE_DETERMINISTIC_MODE) + +#include +#include + +OPENSSL_MSVC_PRAGMA(warning(push, 3)) + +#include + +// #define needed to link in RtlGenRandom(), a.k.a. SystemFunction036. See the +// "Community Additions" comment on MSDN here: +// http://msdn.microsoft.com/en-us/library/windows/desktop/aa387694.aspx +#define SystemFunction036 NTAPI SystemFunction036 +#include +#undef SystemFunction036 + +OPENSSL_MSVC_PRAGMA(warning(pop)) + +#include "../fipsmodule/rand/internal.h" + + +void CRYPTO_sysrand(uint8_t *out, size_t requested) { + while (requested > 0) { + ULONG output_bytes_this_pass = ULONG_MAX; + if (requested < output_bytes_this_pass) { + output_bytes_this_pass = (ULONG)requested; + } + if (RtlGenRandom(out, output_bytes_this_pass) == FALSE) { + abort(); + } + requested -= output_bytes_this_pass; + out += output_bytes_this_pass; + } + return; +} + +#endif // OPENSSL_WINDOWS && !BORINGSSL_UNSAFE_DETERMINISTIC_MODE diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/rc4/rc4.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/rc4/rc4.c new file mode 100644 index 0000000..0fb6339 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/rc4/rc4.c @@ -0,0 +1,98 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + + +void RC4(RC4_KEY *key, size_t len, const uint8_t *in, uint8_t *out) { + uint32_t x = key->x; + uint32_t y = key->y; + uint32_t *d = key->data; + + for (size_t i = 0; i < len; i++) { + x = (x + 1) & 0xff; + uint32_t tx = d[x]; + y = (tx + y) & 0xff; + uint32_t ty = d[y]; + d[x] = ty; + d[y] = tx; + out[i] = d[(tx + ty) & 0xff] ^ in[i]; + } + + key->x = x; + key->y = y; +} + +void RC4_set_key(RC4_KEY *rc4key, unsigned len, const uint8_t *key) { + uint32_t *d = &rc4key->data[0]; + rc4key->x = 0; + rc4key->y = 0; + + for (unsigned i = 0; i < 256; i++) { + d[i] = i; + } + + unsigned id1 = 0, id2 = 0; + for (unsigned i = 0; i < 256; i++) { + uint32_t tmp = d[i]; + id2 = (key[id1] + tmp + id2) & 0xff; + if (++id1 == len) { + id1 = 0; + } + d[i] = d[id2]; + d[id2] = tmp; + } +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/rc4/rc4.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/rc4/rc4.c.grpc_back new file mode 100644 index 0000000..a27a657 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/rc4/rc4.c.grpc_back @@ -0,0 +1,98 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + + +void RC4(RC4_KEY *key, size_t len, const uint8_t *in, uint8_t *out) { + uint32_t x = key->x; + uint32_t y = key->y; + uint32_t *d = key->data; + + for (size_t i = 0; i < len; i++) { + x = (x + 1) & 0xff; + uint32_t tx = d[x]; + y = (tx + y) & 0xff; + uint32_t ty = d[y]; + d[x] = ty; + d[y] = tx; + out[i] = d[(tx + ty) & 0xff] ^ in[i]; + } + + key->x = x; + key->y = y; +} + +void RC4_set_key(RC4_KEY *rc4key, unsigned len, const uint8_t *key) { + uint32_t *d = &rc4key->data[0]; + rc4key->x = 0; + rc4key->y = 0; + + for (unsigned i = 0; i < 256; i++) { + d[i] = i; + } + + unsigned id1 = 0, id2 = 0; + for (unsigned i = 0; i < 256; i++) { + uint32_t tmp = d[i]; + id2 = (key[id1] + tmp + id2) & 0xff; + if (++id1 == len) { + id1 = 0; + } + d[i] = d[id2]; + d[id2] = tmp; + } +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/refcount_c11.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/refcount_c11.c new file mode 100644 index 0000000..ffb1a7e --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/refcount_c11.c @@ -0,0 +1,67 @@ +/* Copyright (c) 2015, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include "internal.h" + + +#if defined(OPENSSL_C11_ATOMIC) + +#include +#include +#include +#include + +#include + + +// See comment above the typedef of CRYPTO_refcount_t about these tests. +static_assert(alignof(CRYPTO_refcount_t) == alignof(_Atomic CRYPTO_refcount_t), + "_Atomic alters the needed alignment of a reference count"); +static_assert(sizeof(CRYPTO_refcount_t) == sizeof(_Atomic CRYPTO_refcount_t), + "_Atomic alters the size of a reference count"); + +static_assert((CRYPTO_refcount_t)-1 == CRYPTO_REFCOUNT_MAX, + "CRYPTO_REFCOUNT_MAX is incorrect"); + +void CRYPTO_refcount_inc(CRYPTO_refcount_t *in_count) { + _Atomic CRYPTO_refcount_t *count = (_Atomic CRYPTO_refcount_t *) in_count; + uint32_t expected = atomic_load(count); + + while (expected != CRYPTO_REFCOUNT_MAX) { + uint32_t new_value = expected + 1; + if (atomic_compare_exchange_weak(count, &expected, new_value)) { + break; + } + } +} + +int CRYPTO_refcount_dec_and_test_zero(CRYPTO_refcount_t *in_count) { + _Atomic CRYPTO_refcount_t *count = (_Atomic CRYPTO_refcount_t *)in_count; + uint32_t expected = atomic_load(count); + + for (;;) { + if (expected == 0) { + abort(); + } else if (expected == CRYPTO_REFCOUNT_MAX) { + return 0; + } else { + const uint32_t new_value = expected - 1; + if (atomic_compare_exchange_weak(count, &expected, new_value)) { + return new_value == 0; + } + } + } +} + +#endif // OPENSSL_C11_ATOMIC diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/refcount_c11.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/refcount_c11.c.grpc_back new file mode 100644 index 0000000..0a331a4 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/refcount_c11.c.grpc_back @@ -0,0 +1,67 @@ +/* Copyright (c) 2015, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include "internal.h" + + +#if defined(OPENSSL_C11_ATOMIC) + +#include +#include +#include +#include + +#include + + +// See comment above the typedef of CRYPTO_refcount_t about these tests. +static_assert(alignof(CRYPTO_refcount_t) == alignof(_Atomic CRYPTO_refcount_t), + "_Atomic alters the needed alignment of a reference count"); +static_assert(sizeof(CRYPTO_refcount_t) == sizeof(_Atomic CRYPTO_refcount_t), + "_Atomic alters the size of a reference count"); + +static_assert((CRYPTO_refcount_t)-1 == CRYPTO_REFCOUNT_MAX, + "CRYPTO_REFCOUNT_MAX is incorrect"); + +void CRYPTO_refcount_inc(CRYPTO_refcount_t *in_count) { + _Atomic CRYPTO_refcount_t *count = (_Atomic CRYPTO_refcount_t *) in_count; + uint32_t expected = atomic_load(count); + + while (expected != CRYPTO_REFCOUNT_MAX) { + uint32_t new_value = expected + 1; + if (atomic_compare_exchange_weak(count, &expected, new_value)) { + break; + } + } +} + +int CRYPTO_refcount_dec_and_test_zero(CRYPTO_refcount_t *in_count) { + _Atomic CRYPTO_refcount_t *count = (_Atomic CRYPTO_refcount_t *)in_count; + uint32_t expected = atomic_load(count); + + for (;;) { + if (expected == 0) { + abort(); + } else if (expected == CRYPTO_REFCOUNT_MAX) { + return 0; + } else { + const uint32_t new_value = expected - 1; + if (atomic_compare_exchange_weak(count, &expected, new_value)) { + return new_value == 0; + } + } + } +} + +#endif // OPENSSL_C11_ATOMIC diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/refcount_lock.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/refcount_lock.c new file mode 100644 index 0000000..b5de7be --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/refcount_lock.c @@ -0,0 +1,53 @@ +/* Copyright (c) 2015, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include "internal.h" + +#include + +#include + + +#if !defined(OPENSSL_C11_ATOMIC) + +OPENSSL_COMPILE_ASSERT((CRYPTO_refcount_t)-1 == CRYPTO_REFCOUNT_MAX, + CRYPTO_REFCOUNT_MAX_is_incorrect); + +static struct CRYPTO_STATIC_MUTEX g_refcount_lock = CRYPTO_STATIC_MUTEX_INIT; + +void CRYPTO_refcount_inc(CRYPTO_refcount_t *count) { + CRYPTO_STATIC_MUTEX_lock_write(&g_refcount_lock); + if (*count < CRYPTO_REFCOUNT_MAX) { + (*count)++; + } + CRYPTO_STATIC_MUTEX_unlock_write(&g_refcount_lock); +} + +int CRYPTO_refcount_dec_and_test_zero(CRYPTO_refcount_t *count) { + int ret; + + CRYPTO_STATIC_MUTEX_lock_write(&g_refcount_lock); + if (*count == 0) { + abort(); + } + if (*count < CRYPTO_REFCOUNT_MAX) { + (*count)--; + } + ret = (*count == 0); + CRYPTO_STATIC_MUTEX_unlock_write(&g_refcount_lock); + + return ret; +} + +#endif // OPENSSL_C11_ATOMIC diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/refcount_lock.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/refcount_lock.c.grpc_back new file mode 100644 index 0000000..8b855d6 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/refcount_lock.c.grpc_back @@ -0,0 +1,53 @@ +/* Copyright (c) 2015, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include "internal.h" + +#include + +#include + + +#if !defined(OPENSSL_C11_ATOMIC) + +OPENSSL_COMPILE_ASSERT((CRYPTO_refcount_t)-1 == CRYPTO_REFCOUNT_MAX, + CRYPTO_REFCOUNT_MAX_is_incorrect); + +static struct CRYPTO_STATIC_MUTEX g_refcount_lock = CRYPTO_STATIC_MUTEX_INIT; + +void CRYPTO_refcount_inc(CRYPTO_refcount_t *count) { + CRYPTO_STATIC_MUTEX_lock_write(&g_refcount_lock); + if (*count < CRYPTO_REFCOUNT_MAX) { + (*count)++; + } + CRYPTO_STATIC_MUTEX_unlock_write(&g_refcount_lock); +} + +int CRYPTO_refcount_dec_and_test_zero(CRYPTO_refcount_t *count) { + int ret; + + CRYPTO_STATIC_MUTEX_lock_write(&g_refcount_lock); + if (*count == 0) { + abort(); + } + if (*count < CRYPTO_REFCOUNT_MAX) { + (*count)--; + } + ret = (*count == 0); + CRYPTO_STATIC_MUTEX_unlock_write(&g_refcount_lock); + + return ret; +} + +#endif // OPENSSL_C11_ATOMIC diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/rsa_extra/rsa_asn1.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/rsa_extra/rsa_asn1.c new file mode 100644 index 0000000..6d4f9b8 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/rsa_extra/rsa_asn1.c @@ -0,0 +1,325 @@ +/* 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 +#include +#include + +#include +#include +#include +#include + +#include "../fipsmodule/rsa/internal.h" +#include "../bytestring/internal.h" +#include "../internal.h" + + +static int parse_integer(CBS *cbs, BIGNUM **out) { + assert(*out == NULL); + *out = BN_new(); + if (*out == NULL) { + return 0; + } + return BN_parse_asn1_unsigned(cbs, *out); +} + +static int marshal_integer(CBB *cbb, BIGNUM *bn) { + if (bn == NULL) { + // An RSA object may be missing some components. + OPENSSL_PUT_ERROR(RSA, RSA_R_VALUE_MISSING); + return 0; + } + return BN_marshal_asn1(cbb, bn); +} + +RSA *RSA_parse_public_key(CBS *cbs) { + RSA *ret = RSA_new(); + if (ret == NULL) { + return NULL; + } + CBS child; + if (!CBS_get_asn1(cbs, &child, CBS_ASN1_SEQUENCE) || + !parse_integer(&child, &ret->n) || + !parse_integer(&child, &ret->e) || + CBS_len(&child) != 0) { + OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_ENCODING); + RSA_free(ret); + return NULL; + } + + if (!BN_is_odd(ret->e) || + BN_num_bits(ret->e) < 2) { + OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_RSA_PARAMETERS); + RSA_free(ret); + return NULL; + } + + return ret; +} + +RSA *RSA_public_key_from_bytes(const uint8_t *in, size_t in_len) { + CBS cbs; + CBS_init(&cbs, in, in_len); + RSA *ret = RSA_parse_public_key(&cbs); + if (ret == NULL || CBS_len(&cbs) != 0) { + OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_ENCODING); + RSA_free(ret); + return NULL; + } + return ret; +} + +int RSA_marshal_public_key(CBB *cbb, const RSA *rsa) { + CBB child; + if (!CBB_add_asn1(cbb, &child, CBS_ASN1_SEQUENCE) || + !marshal_integer(&child, rsa->n) || + !marshal_integer(&child, rsa->e) || + !CBB_flush(cbb)) { + OPENSSL_PUT_ERROR(RSA, RSA_R_ENCODE_ERROR); + return 0; + } + return 1; +} + +int RSA_public_key_to_bytes(uint8_t **out_bytes, size_t *out_len, + const RSA *rsa) { + CBB cbb; + CBB_zero(&cbb); + if (!CBB_init(&cbb, 0) || + !RSA_marshal_public_key(&cbb, rsa) || + !CBB_finish(&cbb, out_bytes, out_len)) { + OPENSSL_PUT_ERROR(RSA, RSA_R_ENCODE_ERROR); + CBB_cleanup(&cbb); + return 0; + } + return 1; +} + +// kVersionTwoPrime is the value of the version field for a two-prime +// RSAPrivateKey structure (RFC 3447). +static const uint64_t kVersionTwoPrime = 0; + +RSA *RSA_parse_private_key(CBS *cbs) { + RSA *ret = RSA_new(); + if (ret == NULL) { + return NULL; + } + + CBS child; + uint64_t version; + if (!CBS_get_asn1(cbs, &child, CBS_ASN1_SEQUENCE) || + !CBS_get_asn1_uint64(&child, &version)) { + OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_ENCODING); + goto err; + } + + if (version != kVersionTwoPrime) { + OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_VERSION); + goto err; + } + + if (!parse_integer(&child, &ret->n) || + !parse_integer(&child, &ret->e) || + !parse_integer(&child, &ret->d) || + !parse_integer(&child, &ret->p) || + !parse_integer(&child, &ret->q) || + !parse_integer(&child, &ret->dmp1) || + !parse_integer(&child, &ret->dmq1) || + !parse_integer(&child, &ret->iqmp)) { + goto err; + } + + if (CBS_len(&child) != 0) { + OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_ENCODING); + goto err; + } + + if (!RSA_check_key(ret)) { + OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_RSA_PARAMETERS); + goto err; + } + + return ret; + +err: + RSA_free(ret); + return NULL; +} + +RSA *RSA_private_key_from_bytes(const uint8_t *in, size_t in_len) { + CBS cbs; + CBS_init(&cbs, in, in_len); + RSA *ret = RSA_parse_private_key(&cbs); + if (ret == NULL || CBS_len(&cbs) != 0) { + OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_ENCODING); + RSA_free(ret); + return NULL; + } + return ret; +} + +int RSA_marshal_private_key(CBB *cbb, const RSA *rsa) { + CBB child; + if (!CBB_add_asn1(cbb, &child, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1_uint64(&child, kVersionTwoPrime) || + !marshal_integer(&child, rsa->n) || + !marshal_integer(&child, rsa->e) || + !marshal_integer(&child, rsa->d) || + !marshal_integer(&child, rsa->p) || + !marshal_integer(&child, rsa->q) || + !marshal_integer(&child, rsa->dmp1) || + !marshal_integer(&child, rsa->dmq1) || + !marshal_integer(&child, rsa->iqmp) || + !CBB_flush(cbb)) { + OPENSSL_PUT_ERROR(RSA, RSA_R_ENCODE_ERROR); + return 0; + } + return 1; +} + +int RSA_private_key_to_bytes(uint8_t **out_bytes, size_t *out_len, + const RSA *rsa) { + CBB cbb; + CBB_zero(&cbb); + if (!CBB_init(&cbb, 0) || + !RSA_marshal_private_key(&cbb, rsa) || + !CBB_finish(&cbb, out_bytes, out_len)) { + OPENSSL_PUT_ERROR(RSA, RSA_R_ENCODE_ERROR); + CBB_cleanup(&cbb); + return 0; + } + return 1; +} + +RSA *d2i_RSAPublicKey(RSA **out, const uint8_t **inp, long len) { + if (len < 0) { + return NULL; + } + CBS cbs; + CBS_init(&cbs, *inp, (size_t)len); + RSA *ret = RSA_parse_public_key(&cbs); + if (ret == NULL) { + return NULL; + } + if (out != NULL) { + RSA_free(*out); + *out = ret; + } + *inp = CBS_data(&cbs); + return ret; +} + +int i2d_RSAPublicKey(const RSA *in, uint8_t **outp) { + CBB cbb; + if (!CBB_init(&cbb, 0) || + !RSA_marshal_public_key(&cbb, in)) { + CBB_cleanup(&cbb); + return -1; + } + return CBB_finish_i2d(&cbb, outp); +} + +RSA *d2i_RSAPrivateKey(RSA **out, const uint8_t **inp, long len) { + if (len < 0) { + return NULL; + } + CBS cbs; + CBS_init(&cbs, *inp, (size_t)len); + RSA *ret = RSA_parse_private_key(&cbs); + if (ret == NULL) { + return NULL; + } + if (out != NULL) { + RSA_free(*out); + *out = ret; + } + *inp = CBS_data(&cbs); + return ret; +} + +int i2d_RSAPrivateKey(const RSA *in, uint8_t **outp) { + CBB cbb; + if (!CBB_init(&cbb, 0) || + !RSA_marshal_private_key(&cbb, in)) { + CBB_cleanup(&cbb); + return -1; + } + return CBB_finish_i2d(&cbb, outp); +} + +RSA *RSAPublicKey_dup(const RSA *rsa) { + uint8_t *der; + size_t der_len; + if (!RSA_public_key_to_bytes(&der, &der_len, rsa)) { + return NULL; + } + RSA *ret = RSA_public_key_from_bytes(der, der_len); + OPENSSL_free(der); + return ret; +} + +RSA *RSAPrivateKey_dup(const RSA *rsa) { + uint8_t *der; + size_t der_len; + if (!RSA_private_key_to_bytes(&der, &der_len, rsa)) { + return NULL; + } + RSA *ret = RSA_private_key_from_bytes(der, der_len); + OPENSSL_free(der); + return ret; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/rsa_extra/rsa_asn1.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/rsa_extra/rsa_asn1.c.grpc_back new file mode 100644 index 0000000..3cc6a9c --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/rsa_extra/rsa_asn1.c.grpc_back @@ -0,0 +1,325 @@ +/* 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 +#include +#include + +#include +#include +#include +#include + +#include "../fipsmodule/rsa/internal.h" +#include "../bytestring/internal.h" +#include "../internal.h" + + +static int parse_integer(CBS *cbs, BIGNUM **out) { + assert(*out == NULL); + *out = BN_new(); + if (*out == NULL) { + return 0; + } + return BN_parse_asn1_unsigned(cbs, *out); +} + +static int marshal_integer(CBB *cbb, BIGNUM *bn) { + if (bn == NULL) { + // An RSA object may be missing some components. + OPENSSL_PUT_ERROR(RSA, RSA_R_VALUE_MISSING); + return 0; + } + return BN_marshal_asn1(cbb, bn); +} + +RSA *RSA_parse_public_key(CBS *cbs) { + RSA *ret = RSA_new(); + if (ret == NULL) { + return NULL; + } + CBS child; + if (!CBS_get_asn1(cbs, &child, CBS_ASN1_SEQUENCE) || + !parse_integer(&child, &ret->n) || + !parse_integer(&child, &ret->e) || + CBS_len(&child) != 0) { + OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_ENCODING); + RSA_free(ret); + return NULL; + } + + if (!BN_is_odd(ret->e) || + BN_num_bits(ret->e) < 2) { + OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_RSA_PARAMETERS); + RSA_free(ret); + return NULL; + } + + return ret; +} + +RSA *RSA_public_key_from_bytes(const uint8_t *in, size_t in_len) { + CBS cbs; + CBS_init(&cbs, in, in_len); + RSA *ret = RSA_parse_public_key(&cbs); + if (ret == NULL || CBS_len(&cbs) != 0) { + OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_ENCODING); + RSA_free(ret); + return NULL; + } + return ret; +} + +int RSA_marshal_public_key(CBB *cbb, const RSA *rsa) { + CBB child; + if (!CBB_add_asn1(cbb, &child, CBS_ASN1_SEQUENCE) || + !marshal_integer(&child, rsa->n) || + !marshal_integer(&child, rsa->e) || + !CBB_flush(cbb)) { + OPENSSL_PUT_ERROR(RSA, RSA_R_ENCODE_ERROR); + return 0; + } + return 1; +} + +int RSA_public_key_to_bytes(uint8_t **out_bytes, size_t *out_len, + const RSA *rsa) { + CBB cbb; + CBB_zero(&cbb); + if (!CBB_init(&cbb, 0) || + !RSA_marshal_public_key(&cbb, rsa) || + !CBB_finish(&cbb, out_bytes, out_len)) { + OPENSSL_PUT_ERROR(RSA, RSA_R_ENCODE_ERROR); + CBB_cleanup(&cbb); + return 0; + } + return 1; +} + +// kVersionTwoPrime is the value of the version field for a two-prime +// RSAPrivateKey structure (RFC 3447). +static const uint64_t kVersionTwoPrime = 0; + +RSA *RSA_parse_private_key(CBS *cbs) { + RSA *ret = RSA_new(); + if (ret == NULL) { + return NULL; + } + + CBS child; + uint64_t version; + if (!CBS_get_asn1(cbs, &child, CBS_ASN1_SEQUENCE) || + !CBS_get_asn1_uint64(&child, &version)) { + OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_ENCODING); + goto err; + } + + if (version != kVersionTwoPrime) { + OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_VERSION); + goto err; + } + + if (!parse_integer(&child, &ret->n) || + !parse_integer(&child, &ret->e) || + !parse_integer(&child, &ret->d) || + !parse_integer(&child, &ret->p) || + !parse_integer(&child, &ret->q) || + !parse_integer(&child, &ret->dmp1) || + !parse_integer(&child, &ret->dmq1) || + !parse_integer(&child, &ret->iqmp)) { + goto err; + } + + if (CBS_len(&child) != 0) { + OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_ENCODING); + goto err; + } + + if (!RSA_check_key(ret)) { + OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_RSA_PARAMETERS); + goto err; + } + + return ret; + +err: + RSA_free(ret); + return NULL; +} + +RSA *RSA_private_key_from_bytes(const uint8_t *in, size_t in_len) { + CBS cbs; + CBS_init(&cbs, in, in_len); + RSA *ret = RSA_parse_private_key(&cbs); + if (ret == NULL || CBS_len(&cbs) != 0) { + OPENSSL_PUT_ERROR(RSA, RSA_R_BAD_ENCODING); + RSA_free(ret); + return NULL; + } + return ret; +} + +int RSA_marshal_private_key(CBB *cbb, const RSA *rsa) { + CBB child; + if (!CBB_add_asn1(cbb, &child, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1_uint64(&child, kVersionTwoPrime) || + !marshal_integer(&child, rsa->n) || + !marshal_integer(&child, rsa->e) || + !marshal_integer(&child, rsa->d) || + !marshal_integer(&child, rsa->p) || + !marshal_integer(&child, rsa->q) || + !marshal_integer(&child, rsa->dmp1) || + !marshal_integer(&child, rsa->dmq1) || + !marshal_integer(&child, rsa->iqmp) || + !CBB_flush(cbb)) { + OPENSSL_PUT_ERROR(RSA, RSA_R_ENCODE_ERROR); + return 0; + } + return 1; +} + +int RSA_private_key_to_bytes(uint8_t **out_bytes, size_t *out_len, + const RSA *rsa) { + CBB cbb; + CBB_zero(&cbb); + if (!CBB_init(&cbb, 0) || + !RSA_marshal_private_key(&cbb, rsa) || + !CBB_finish(&cbb, out_bytes, out_len)) { + OPENSSL_PUT_ERROR(RSA, RSA_R_ENCODE_ERROR); + CBB_cleanup(&cbb); + return 0; + } + return 1; +} + +RSA *d2i_RSAPublicKey(RSA **out, const uint8_t **inp, long len) { + if (len < 0) { + return NULL; + } + CBS cbs; + CBS_init(&cbs, *inp, (size_t)len); + RSA *ret = RSA_parse_public_key(&cbs); + if (ret == NULL) { + return NULL; + } + if (out != NULL) { + RSA_free(*out); + *out = ret; + } + *inp = CBS_data(&cbs); + return ret; +} + +int i2d_RSAPublicKey(const RSA *in, uint8_t **outp) { + CBB cbb; + if (!CBB_init(&cbb, 0) || + !RSA_marshal_public_key(&cbb, in)) { + CBB_cleanup(&cbb); + return -1; + } + return CBB_finish_i2d(&cbb, outp); +} + +RSA *d2i_RSAPrivateKey(RSA **out, const uint8_t **inp, long len) { + if (len < 0) { + return NULL; + } + CBS cbs; + CBS_init(&cbs, *inp, (size_t)len); + RSA *ret = RSA_parse_private_key(&cbs); + if (ret == NULL) { + return NULL; + } + if (out != NULL) { + RSA_free(*out); + *out = ret; + } + *inp = CBS_data(&cbs); + return ret; +} + +int i2d_RSAPrivateKey(const RSA *in, uint8_t **outp) { + CBB cbb; + if (!CBB_init(&cbb, 0) || + !RSA_marshal_private_key(&cbb, in)) { + CBB_cleanup(&cbb); + return -1; + } + return CBB_finish_i2d(&cbb, outp); +} + +RSA *RSAPublicKey_dup(const RSA *rsa) { + uint8_t *der; + size_t der_len; + if (!RSA_public_key_to_bytes(&der, &der_len, rsa)) { + return NULL; + } + RSA *ret = RSA_public_key_from_bytes(der, der_len); + OPENSSL_free(der); + return ret; +} + +RSA *RSAPrivateKey_dup(const RSA *rsa) { + uint8_t *der; + size_t der_len; + if (!RSA_private_key_to_bytes(&der, &der_len, rsa)) { + return NULL; + } + RSA *ret = RSA_private_key_from_bytes(der, der_len); + OPENSSL_free(der); + return ret; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/stack/stack.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/stack/stack.c new file mode 100644 index 0000000..659b4e1 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/stack/stack.c @@ -0,0 +1,380 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 "../internal.h" + + +// kMinSize is the number of pointers that will be initially allocated in a new +// stack. +static const size_t kMinSize = 4; + +_STACK *sk_new(stack_cmp_func comp) { + _STACK *ret; + + ret = OPENSSL_malloc(sizeof(_STACK)); + if (ret == NULL) { + goto err; + } + OPENSSL_memset(ret, 0, sizeof(_STACK)); + + ret->data = OPENSSL_malloc(sizeof(void *) * kMinSize); + if (ret->data == NULL) { + goto err; + } + + OPENSSL_memset(ret->data, 0, sizeof(void *) * kMinSize); + + ret->comp = comp; + ret->num_alloc = kMinSize; + + return ret; + +err: + OPENSSL_free(ret); + return NULL; +} + +_STACK *sk_new_null(void) { return sk_new(NULL); } + +size_t sk_num(const _STACK *sk) { + if (sk == NULL) { + return 0; + } + return sk->num; +} + +void sk_zero(_STACK *sk) { + if (sk == NULL || sk->num == 0) { + return; + } + OPENSSL_memset(sk->data, 0, sizeof(void*) * sk->num); + sk->num = 0; + sk->sorted = 0; +} + +void *sk_value(const _STACK *sk, size_t i) { + if (!sk || i >= sk->num) { + return NULL; + } + return sk->data[i]; +} + +void *sk_set(_STACK *sk, size_t i, void *value) { + if (!sk || i >= sk->num) { + return NULL; + } + return sk->data[i] = value; +} + +void sk_free(_STACK *sk) { + if (sk == NULL) { + return; + } + OPENSSL_free(sk->data); + OPENSSL_free(sk); +} + +void sk_pop_free(_STACK *sk, void (*func)(void *)) { + if (sk == NULL) { + return; + } + + for (size_t i = 0; i < sk->num; i++) { + if (sk->data[i] != NULL) { + func(sk->data[i]); + } + } + sk_free(sk); +} + +size_t sk_insert(_STACK *sk, void *p, size_t where) { + if (sk == NULL) { + return 0; + } + + if (sk->num_alloc <= sk->num + 1) { + // Attempt to double the size of the array. + size_t new_alloc = sk->num_alloc << 1; + size_t alloc_size = new_alloc * sizeof(void *); + void **data; + + // If the doubling overflowed, try to increment. + if (new_alloc < sk->num_alloc || alloc_size / sizeof(void *) != new_alloc) { + new_alloc = sk->num_alloc + 1; + alloc_size = new_alloc * sizeof(void *); + } + + // If the increment also overflowed, fail. + if (new_alloc < sk->num_alloc || alloc_size / sizeof(void *) != new_alloc) { + return 0; + } + + data = OPENSSL_realloc(sk->data, alloc_size); + if (data == NULL) { + return 0; + } + + sk->data = data; + sk->num_alloc = new_alloc; + } + + if (where >= sk->num) { + sk->data[sk->num] = p; + } else { + OPENSSL_memmove(&sk->data[where + 1], &sk->data[where], + sizeof(void *) * (sk->num - where)); + sk->data[where] = p; + } + + sk->num++; + sk->sorted = 0; + + return sk->num; +} + +void *sk_delete(_STACK *sk, size_t where) { + void *ret; + + if (!sk || where >= sk->num) { + return NULL; + } + + ret = sk->data[where]; + + if (where != sk->num - 1) { + OPENSSL_memmove(&sk->data[where], &sk->data[where + 1], + sizeof(void *) * (sk->num - where - 1)); + } + + sk->num--; + return ret; +} + +void *sk_delete_ptr(_STACK *sk, void *p) { + if (sk == NULL) { + return NULL; + } + + for (size_t i = 0; i < sk->num; i++) { + if (sk->data[i] == p) { + return sk_delete(sk, i); + } + } + + return NULL; +} + +int sk_find(_STACK *sk, size_t *out_index, void *p) { + if (sk == NULL) { + return 0; + } + + if (sk->comp == NULL) { + // Use pointer equality when no comparison function has been set. + for (size_t i = 0; i < sk->num; i++) { + if (sk->data[i] == p) { + if (out_index) { + *out_index = i; + } + return 1; + } + } + return 0; + } + + if (p == NULL) { + return 0; + } + + sk_sort(sk); + + // sk->comp is a function that takes pointers to pointers to elements, but + // qsort and bsearch take a comparison function that just takes pointers to + // elements. However, since we're passing an array of pointers to + // qsort/bsearch, we can just cast the comparison function and everything + // works. + const void *const *r = bsearch(&p, sk->data, sk->num, sizeof(void *), + (int (*)(const void *, const void *))sk->comp); + if (r == NULL) { + return 0; + } + size_t idx = ((void **)r) - sk->data; + // This function always returns the first result. + while (idx > 0 && + sk->comp((const void **)&p, (const void **)&sk->data[idx - 1]) == 0) { + idx--; + } + if (out_index) { + *out_index = idx; + } + return 1; +} + +void *sk_shift(_STACK *sk) { + if (sk == NULL) { + return NULL; + } + if (sk->num == 0) { + return NULL; + } + return sk_delete(sk, 0); +} + +size_t sk_push(_STACK *sk, void *p) { return (sk_insert(sk, p, sk->num)); } + +void *sk_pop(_STACK *sk) { + if (sk == NULL) { + return NULL; + } + if (sk->num == 0) { + return NULL; + } + return sk_delete(sk, sk->num - 1); +} + +_STACK *sk_dup(const _STACK *sk) { + _STACK *ret; + void **s; + + if (sk == NULL) { + return NULL; + } + + ret = sk_new(sk->comp); + if (ret == NULL) { + goto err; + } + + s = (void **)OPENSSL_realloc(ret->data, sizeof(void *) * sk->num_alloc); + if (s == NULL) { + goto err; + } + ret->data = s; + + ret->num = sk->num; + OPENSSL_memcpy(ret->data, sk->data, sizeof(void *) * sk->num); + ret->sorted = sk->sorted; + ret->num_alloc = sk->num_alloc; + ret->comp = sk->comp; + return ret; + +err: + sk_free(ret); + return NULL; +} + +void sk_sort(_STACK *sk) { + int (*comp_func)(const void *,const void *); + + if (sk == NULL || sk->comp == NULL || sk->sorted) { + return; + } + + // See the comment in sk_find about this cast. + comp_func = (int (*)(const void *, const void *))(sk->comp); + qsort(sk->data, sk->num, sizeof(void *), comp_func); + sk->sorted = 1; +} + +int sk_is_sorted(const _STACK *sk) { + if (!sk) { + return 1; + } + return sk->sorted; +} + +stack_cmp_func sk_set_cmp_func(_STACK *sk, stack_cmp_func comp) { + stack_cmp_func old = sk->comp; + + if (sk->comp != comp) { + sk->sorted = 0; + } + sk->comp = comp; + + return old; +} + +_STACK *sk_deep_copy(const _STACK *sk, void *(*copy_func)(void *), + void (*free_func)(void *)) { + _STACK *ret = sk_dup(sk); + if (ret == NULL) { + return NULL; + } + + for (size_t i = 0; i < ret->num; i++) { + if (ret->data[i] == NULL) { + continue; + } + ret->data[i] = copy_func(ret->data[i]); + if (ret->data[i] == NULL) { + for (size_t j = 0; j < i; j++) { + if (ret->data[j] != NULL) { + free_func(ret->data[j]); + } + } + sk_free(ret); + return NULL; + } + } + + return ret; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/stack/stack.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/stack/stack.c.grpc_back new file mode 100644 index 0000000..f6b4412 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/stack/stack.c.grpc_back @@ -0,0 +1,380 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 "../internal.h" + + +// kMinSize is the number of pointers that will be initially allocated in a new +// stack. +static const size_t kMinSize = 4; + +_STACK *sk_new(stack_cmp_func comp) { + _STACK *ret; + + ret = OPENSSL_malloc(sizeof(_STACK)); + if (ret == NULL) { + goto err; + } + OPENSSL_memset(ret, 0, sizeof(_STACK)); + + ret->data = OPENSSL_malloc(sizeof(void *) * kMinSize); + if (ret->data == NULL) { + goto err; + } + + OPENSSL_memset(ret->data, 0, sizeof(void *) * kMinSize); + + ret->comp = comp; + ret->num_alloc = kMinSize; + + return ret; + +err: + OPENSSL_free(ret); + return NULL; +} + +_STACK *sk_new_null(void) { return sk_new(NULL); } + +size_t sk_num(const _STACK *sk) { + if (sk == NULL) { + return 0; + } + return sk->num; +} + +void sk_zero(_STACK *sk) { + if (sk == NULL || sk->num == 0) { + return; + } + OPENSSL_memset(sk->data, 0, sizeof(void*) * sk->num); + sk->num = 0; + sk->sorted = 0; +} + +void *sk_value(const _STACK *sk, size_t i) { + if (!sk || i >= sk->num) { + return NULL; + } + return sk->data[i]; +} + +void *sk_set(_STACK *sk, size_t i, void *value) { + if (!sk || i >= sk->num) { + return NULL; + } + return sk->data[i] = value; +} + +void sk_free(_STACK *sk) { + if (sk == NULL) { + return; + } + OPENSSL_free(sk->data); + OPENSSL_free(sk); +} + +void sk_pop_free(_STACK *sk, void (*func)(void *)) { + if (sk == NULL) { + return; + } + + for (size_t i = 0; i < sk->num; i++) { + if (sk->data[i] != NULL) { + func(sk->data[i]); + } + } + sk_free(sk); +} + +size_t sk_insert(_STACK *sk, void *p, size_t where) { + if (sk == NULL) { + return 0; + } + + if (sk->num_alloc <= sk->num + 1) { + // Attempt to double the size of the array. + size_t new_alloc = sk->num_alloc << 1; + size_t alloc_size = new_alloc * sizeof(void *); + void **data; + + // If the doubling overflowed, try to increment. + if (new_alloc < sk->num_alloc || alloc_size / sizeof(void *) != new_alloc) { + new_alloc = sk->num_alloc + 1; + alloc_size = new_alloc * sizeof(void *); + } + + // If the increment also overflowed, fail. + if (new_alloc < sk->num_alloc || alloc_size / sizeof(void *) != new_alloc) { + return 0; + } + + data = OPENSSL_realloc(sk->data, alloc_size); + if (data == NULL) { + return 0; + } + + sk->data = data; + sk->num_alloc = new_alloc; + } + + if (where >= sk->num) { + sk->data[sk->num] = p; + } else { + OPENSSL_memmove(&sk->data[where + 1], &sk->data[where], + sizeof(void *) * (sk->num - where)); + sk->data[where] = p; + } + + sk->num++; + sk->sorted = 0; + + return sk->num; +} + +void *sk_delete(_STACK *sk, size_t where) { + void *ret; + + if (!sk || where >= sk->num) { + return NULL; + } + + ret = sk->data[where]; + + if (where != sk->num - 1) { + OPENSSL_memmove(&sk->data[where], &sk->data[where + 1], + sizeof(void *) * (sk->num - where - 1)); + } + + sk->num--; + return ret; +} + +void *sk_delete_ptr(_STACK *sk, void *p) { + if (sk == NULL) { + return NULL; + } + + for (size_t i = 0; i < sk->num; i++) { + if (sk->data[i] == p) { + return sk_delete(sk, i); + } + } + + return NULL; +} + +int sk_find(_STACK *sk, size_t *out_index, void *p) { + if (sk == NULL) { + return 0; + } + + if (sk->comp == NULL) { + // Use pointer equality when no comparison function has been set. + for (size_t i = 0; i < sk->num; i++) { + if (sk->data[i] == p) { + if (out_index) { + *out_index = i; + } + return 1; + } + } + return 0; + } + + if (p == NULL) { + return 0; + } + + sk_sort(sk); + + // sk->comp is a function that takes pointers to pointers to elements, but + // qsort and bsearch take a comparison function that just takes pointers to + // elements. However, since we're passing an array of pointers to + // qsort/bsearch, we can just cast the comparison function and everything + // works. + const void *const *r = bsearch(&p, sk->data, sk->num, sizeof(void *), + (int (*)(const void *, const void *))sk->comp); + if (r == NULL) { + return 0; + } + size_t idx = ((void **)r) - sk->data; + // This function always returns the first result. + while (idx > 0 && + sk->comp((const void **)&p, (const void **)&sk->data[idx - 1]) == 0) { + idx--; + } + if (out_index) { + *out_index = idx; + } + return 1; +} + +void *sk_shift(_STACK *sk) { + if (sk == NULL) { + return NULL; + } + if (sk->num == 0) { + return NULL; + } + return sk_delete(sk, 0); +} + +size_t sk_push(_STACK *sk, void *p) { return (sk_insert(sk, p, sk->num)); } + +void *sk_pop(_STACK *sk) { + if (sk == NULL) { + return NULL; + } + if (sk->num == 0) { + return NULL; + } + return sk_delete(sk, sk->num - 1); +} + +_STACK *sk_dup(const _STACK *sk) { + _STACK *ret; + void **s; + + if (sk == NULL) { + return NULL; + } + + ret = sk_new(sk->comp); + if (ret == NULL) { + goto err; + } + + s = (void **)OPENSSL_realloc(ret->data, sizeof(void *) * sk->num_alloc); + if (s == NULL) { + goto err; + } + ret->data = s; + + ret->num = sk->num; + OPENSSL_memcpy(ret->data, sk->data, sizeof(void *) * sk->num); + ret->sorted = sk->sorted; + ret->num_alloc = sk->num_alloc; + ret->comp = sk->comp; + return ret; + +err: + sk_free(ret); + return NULL; +} + +void sk_sort(_STACK *sk) { + int (*comp_func)(const void *,const void *); + + if (sk == NULL || sk->comp == NULL || sk->sorted) { + return; + } + + // See the comment in sk_find about this cast. + comp_func = (int (*)(const void *, const void *))(sk->comp); + qsort(sk->data, sk->num, sizeof(void *), comp_func); + sk->sorted = 1; +} + +int sk_is_sorted(const _STACK *sk) { + if (!sk) { + return 1; + } + return sk->sorted; +} + +stack_cmp_func sk_set_cmp_func(_STACK *sk, stack_cmp_func comp) { + stack_cmp_func old = sk->comp; + + if (sk->comp != comp) { + sk->sorted = 0; + } + sk->comp = comp; + + return old; +} + +_STACK *sk_deep_copy(const _STACK *sk, void *(*copy_func)(void *), + void (*free_func)(void *)) { + _STACK *ret = sk_dup(sk); + if (ret == NULL) { + return NULL; + } + + for (size_t i = 0; i < ret->num; i++) { + if (ret->data[i] == NULL) { + continue; + } + ret->data[i] = copy_func(ret->data[i]); + if (ret->data[i] == NULL) { + for (size_t j = 0; j < i; j++) { + if (ret->data[j] != NULL) { + free_func(ret->data[j]); + } + } + sk_free(ret); + return NULL; + } + } + + return ret; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/thread.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/thread.c new file mode 100644 index 0000000..dc8e248 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/thread.c @@ -0,0 +1,110 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + + +int CRYPTO_num_locks(void) { return 1; } + +void CRYPTO_set_locking_callback(void (*func)(int mode, int lock_num, + const char *file, int line)) {} + +void (*CRYPTO_get_locking_callback(void))(int mode, int lock_num, + const char *file, int line) { + return NULL; +} + +void CRYPTO_set_add_lock_callback(int (*func)(int *num, int mount, int lock_num, + const char *file, int line)) {} + +const char *CRYPTO_get_lock_name(int lock_num) { + return "No old-style OpenSSL locks anymore"; +} + +int CRYPTO_THREADID_set_callback(void (*func)(CRYPTO_THREADID *)) { return 1; } + +void CRYPTO_THREADID_set_numeric(CRYPTO_THREADID *id, unsigned long val) {} + +void CRYPTO_THREADID_set_pointer(CRYPTO_THREADID *id, void *ptr) {} + +void CRYPTO_THREADID_current(CRYPTO_THREADID *id) {} + +void CRYPTO_set_id_callback(unsigned long (*func)(void)) {} + +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) { + return NULL; +} + +void (*CRYPTO_get_dynlock_lock_callback(void))(int mode, + struct CRYPTO_dynlock_value *l, + const char *file, int line) { + return NULL; +} + +void (*CRYPTO_get_dynlock_destroy_callback(void))( + struct CRYPTO_dynlock_value *l, const char *file, int line) { + return NULL; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/thread.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/thread.c.grpc_back new file mode 100644 index 0000000..25acce1 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/thread.c.grpc_back @@ -0,0 +1,110 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include + + +int CRYPTO_num_locks(void) { return 1; } + +void CRYPTO_set_locking_callback(void (*func)(int mode, int lock_num, + const char *file, int line)) {} + +void (*CRYPTO_get_locking_callback(void))(int mode, int lock_num, + const char *file, int line) { + return NULL; +} + +void CRYPTO_set_add_lock_callback(int (*func)(int *num, int mount, int lock_num, + const char *file, int line)) {} + +const char *CRYPTO_get_lock_name(int lock_num) { + return "No old-style OpenSSL locks anymore"; +} + +int CRYPTO_THREADID_set_callback(void (*func)(CRYPTO_THREADID *)) { return 1; } + +void CRYPTO_THREADID_set_numeric(CRYPTO_THREADID *id, unsigned long val) {} + +void CRYPTO_THREADID_set_pointer(CRYPTO_THREADID *id, void *ptr) {} + +void CRYPTO_THREADID_current(CRYPTO_THREADID *id) {} + +void CRYPTO_set_id_callback(unsigned long (*func)(void)) {} + +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) { + return NULL; +} + +void (*CRYPTO_get_dynlock_lock_callback(void))(int mode, + struct CRYPTO_dynlock_value *l, + const char *file, int line) { + return NULL; +} + +void (*CRYPTO_get_dynlock_destroy_callback(void))( + struct CRYPTO_dynlock_value *l, const char *file, int line) { + return NULL; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/thread_none.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/thread_none.c new file mode 100644 index 0000000..718d960 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/thread_none.c @@ -0,0 +1,59 @@ +/* Copyright (c) 2015, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include "internal.h" + +#if defined(OPENSSL_NO_THREADS) + +void CRYPTO_MUTEX_init(CRYPTO_MUTEX *lock) {} + +void CRYPTO_MUTEX_lock_read(CRYPTO_MUTEX *lock) {} + +void CRYPTO_MUTEX_lock_write(CRYPTO_MUTEX *lock) {} + +void CRYPTO_MUTEX_unlock_read(CRYPTO_MUTEX *lock) {} + +void CRYPTO_MUTEX_unlock_write(CRYPTO_MUTEX *lock) {} + +void CRYPTO_MUTEX_cleanup(CRYPTO_MUTEX *lock) {} + +void CRYPTO_STATIC_MUTEX_lock_read(struct CRYPTO_STATIC_MUTEX *lock) {} + +void CRYPTO_STATIC_MUTEX_lock_write(struct CRYPTO_STATIC_MUTEX *lock) {} + +void CRYPTO_STATIC_MUTEX_unlock_read(struct CRYPTO_STATIC_MUTEX *lock) {} + +void CRYPTO_STATIC_MUTEX_unlock_write(struct CRYPTO_STATIC_MUTEX *lock) {} + +void CRYPTO_once(CRYPTO_once_t *once, void (*init)(void)) { + if (*once) { + return; + } + *once = 1; + init(); +} + +static void *g_thread_locals[NUM_OPENSSL_THREAD_LOCALS]; + +void *CRYPTO_get_thread_local(thread_local_data_t index) { + return g_thread_locals[index]; +} + +int CRYPTO_set_thread_local(thread_local_data_t index, void *value, + thread_local_destructor_t destructor) { + g_thread_locals[index] = value; + return 1; +} + +#endif // OPENSSL_NO_THREADS diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/thread_none.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/thread_none.c.grpc_back new file mode 100644 index 0000000..718d960 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/thread_none.c.grpc_back @@ -0,0 +1,59 @@ +/* Copyright (c) 2015, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include "internal.h" + +#if defined(OPENSSL_NO_THREADS) + +void CRYPTO_MUTEX_init(CRYPTO_MUTEX *lock) {} + +void CRYPTO_MUTEX_lock_read(CRYPTO_MUTEX *lock) {} + +void CRYPTO_MUTEX_lock_write(CRYPTO_MUTEX *lock) {} + +void CRYPTO_MUTEX_unlock_read(CRYPTO_MUTEX *lock) {} + +void CRYPTO_MUTEX_unlock_write(CRYPTO_MUTEX *lock) {} + +void CRYPTO_MUTEX_cleanup(CRYPTO_MUTEX *lock) {} + +void CRYPTO_STATIC_MUTEX_lock_read(struct CRYPTO_STATIC_MUTEX *lock) {} + +void CRYPTO_STATIC_MUTEX_lock_write(struct CRYPTO_STATIC_MUTEX *lock) {} + +void CRYPTO_STATIC_MUTEX_unlock_read(struct CRYPTO_STATIC_MUTEX *lock) {} + +void CRYPTO_STATIC_MUTEX_unlock_write(struct CRYPTO_STATIC_MUTEX *lock) {} + +void CRYPTO_once(CRYPTO_once_t *once, void (*init)(void)) { + if (*once) { + return; + } + *once = 1; + init(); +} + +static void *g_thread_locals[NUM_OPENSSL_THREAD_LOCALS]; + +void *CRYPTO_get_thread_local(thread_local_data_t index) { + return g_thread_locals[index]; +} + +int CRYPTO_set_thread_local(thread_local_data_t index, void *value, + thread_local_destructor_t destructor) { + g_thread_locals[index] = value; + return 1; +} + +#endif // OPENSSL_NO_THREADS diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/thread_pthread.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/thread_pthread.c new file mode 100644 index 0000000..1e0c35d --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/thread_pthread.c @@ -0,0 +1,206 @@ +/* Copyright (c) 2015, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include "internal.h" + +#if defined(OPENSSL_PTHREADS) + +#include +#include +#include + +#include +#include + + +OPENSSL_COMPILE_ASSERT(sizeof(CRYPTO_MUTEX) >= sizeof(pthread_rwlock_t), + CRYPTO_MUTEX_too_small); + +void CRYPTO_MUTEX_init(CRYPTO_MUTEX *lock) { + if (pthread_rwlock_init((pthread_rwlock_t *) lock, NULL) != 0) { + abort(); + } +} + +void CRYPTO_MUTEX_lock_read(CRYPTO_MUTEX *lock) { + if (pthread_rwlock_rdlock((pthread_rwlock_t *) lock) != 0) { + abort(); + } +} + +void CRYPTO_MUTEX_lock_write(CRYPTO_MUTEX *lock) { + if (pthread_rwlock_wrlock((pthread_rwlock_t *) lock) != 0) { + abort(); + } +} + +void CRYPTO_MUTEX_unlock_read(CRYPTO_MUTEX *lock) { + if (pthread_rwlock_unlock((pthread_rwlock_t *) lock) != 0) { + abort(); + } +} + +void CRYPTO_MUTEX_unlock_write(CRYPTO_MUTEX *lock) { + if (pthread_rwlock_unlock((pthread_rwlock_t *) lock) != 0) { + abort(); + } +} + +void CRYPTO_MUTEX_cleanup(CRYPTO_MUTEX *lock) { + pthread_rwlock_destroy((pthread_rwlock_t *) lock); +} + +void CRYPTO_STATIC_MUTEX_lock_read(struct CRYPTO_STATIC_MUTEX *lock) { + if (pthread_rwlock_rdlock(&lock->lock) != 0) { + abort(); + } +} + +void CRYPTO_STATIC_MUTEX_lock_write(struct CRYPTO_STATIC_MUTEX *lock) { + if (pthread_rwlock_wrlock(&lock->lock) != 0) { + abort(); + } +} + +void CRYPTO_STATIC_MUTEX_unlock_read(struct CRYPTO_STATIC_MUTEX *lock) { + if (pthread_rwlock_unlock(&lock->lock) != 0) { + abort(); + } +} + +void CRYPTO_STATIC_MUTEX_unlock_write(struct CRYPTO_STATIC_MUTEX *lock) { + if (pthread_rwlock_unlock(&lock->lock) != 0) { + abort(); + } +} + +void CRYPTO_once(CRYPTO_once_t *once, void (*init)(void)) { + if (pthread_once(once, init) != 0) { + abort(); + } +} + +static pthread_mutex_t g_destructors_lock = PTHREAD_MUTEX_INITIALIZER; +static thread_local_destructor_t g_destructors[NUM_OPENSSL_THREAD_LOCALS]; + +// thread_local_destructor is called when a thread exits. It releases thread +// local data for that thread only. +static void thread_local_destructor(void *arg) { + if (arg == NULL) { + return; + } + + thread_local_destructor_t destructors[NUM_OPENSSL_THREAD_LOCALS]; + if (pthread_mutex_lock(&g_destructors_lock) != 0) { + return; + } + OPENSSL_memcpy(destructors, g_destructors, sizeof(destructors)); + pthread_mutex_unlock(&g_destructors_lock); + + unsigned i; + void **pointers = arg; + for (i = 0; i < NUM_OPENSSL_THREAD_LOCALS; i++) { + if (destructors[i] != NULL) { + destructors[i](pointers[i]); + } + } + + OPENSSL_free(pointers); +} + +static pthread_once_t g_thread_local_init_once = PTHREAD_ONCE_INIT; +static pthread_key_t g_thread_local_key; +static int g_thread_local_key_created = 0; + +// OPENSSL_DANGEROUS_RELEASE_PTHREAD_KEY can be defined to cause +// |pthread_key_delete| to be called in a destructor function. This can be +// useful for programs that dlclose BoringSSL. +// +// Note that dlclose()ing BoringSSL is not supported and will leak memory: +// thread-local values will be leaked as well as anything initialised via a +// once. The |pthread_key_t| is destroyed because they run out very quickly, +// while the other leaks are slow, and this allows code that happens to use +// dlclose() despite all the problems to continue functioning. +// +// This is marked "dangerous" because it can cause multi-threaded processes to +// crash (even if they don't use dlclose): if the destructor runs while other +// threads are still executing then they may end up using an invalid key to +// access thread-local variables. +// +// This may be removed after February 2020. +#if defined(OPENSSL_DANGEROUS_RELEASE_PTHREAD_KEY) && \ + (defined(__GNUC__) || defined(__clang__)) +// thread_key_destructor is called when the library is unloaded with dlclose. +static void thread_key_destructor(void) __attribute__((destructor, unused)); +static void thread_key_destructor(void) { + if (g_thread_local_key_created) { + g_thread_local_key_created = 0; + pthread_key_delete(g_thread_local_key); + } +} +#endif + +static void thread_local_init(void) { + g_thread_local_key_created = + pthread_key_create(&g_thread_local_key, thread_local_destructor) == 0; +} + +void *CRYPTO_get_thread_local(thread_local_data_t index) { + CRYPTO_once(&g_thread_local_init_once, thread_local_init); + if (!g_thread_local_key_created) { + return NULL; + } + + void **pointers = pthread_getspecific(g_thread_local_key); + if (pointers == NULL) { + return NULL; + } + return pointers[index]; +} + +int CRYPTO_set_thread_local(thread_local_data_t index, void *value, + thread_local_destructor_t destructor) { + CRYPTO_once(&g_thread_local_init_once, thread_local_init); + if (!g_thread_local_key_created) { + destructor(value); + return 0; + } + + void **pointers = pthread_getspecific(g_thread_local_key); + if (pointers == NULL) { + pointers = OPENSSL_malloc(sizeof(void *) * NUM_OPENSSL_THREAD_LOCALS); + if (pointers == NULL) { + destructor(value); + return 0; + } + OPENSSL_memset(pointers, 0, sizeof(void *) * NUM_OPENSSL_THREAD_LOCALS); + if (pthread_setspecific(g_thread_local_key, pointers) != 0) { + OPENSSL_free(pointers); + destructor(value); + return 0; + } + } + + if (pthread_mutex_lock(&g_destructors_lock) != 0) { + destructor(value); + return 0; + } + g_destructors[index] = destructor; + pthread_mutex_unlock(&g_destructors_lock); + + pointers[index] = value; + return 1; +} + +#endif // OPENSSL_PTHREADS diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/thread_pthread.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/thread_pthread.c.grpc_back new file mode 100644 index 0000000..f8bf595 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/thread_pthread.c.grpc_back @@ -0,0 +1,206 @@ +/* Copyright (c) 2015, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include "internal.h" + +#if defined(OPENSSL_PTHREADS) + +#include +#include +#include + +#include +#include + + +OPENSSL_COMPILE_ASSERT(sizeof(CRYPTO_MUTEX) >= sizeof(pthread_rwlock_t), + CRYPTO_MUTEX_too_small); + +void CRYPTO_MUTEX_init(CRYPTO_MUTEX *lock) { + if (pthread_rwlock_init((pthread_rwlock_t *) lock, NULL) != 0) { + abort(); + } +} + +void CRYPTO_MUTEX_lock_read(CRYPTO_MUTEX *lock) { + if (pthread_rwlock_rdlock((pthread_rwlock_t *) lock) != 0) { + abort(); + } +} + +void CRYPTO_MUTEX_lock_write(CRYPTO_MUTEX *lock) { + if (pthread_rwlock_wrlock((pthread_rwlock_t *) lock) != 0) { + abort(); + } +} + +void CRYPTO_MUTEX_unlock_read(CRYPTO_MUTEX *lock) { + if (pthread_rwlock_unlock((pthread_rwlock_t *) lock) != 0) { + abort(); + } +} + +void CRYPTO_MUTEX_unlock_write(CRYPTO_MUTEX *lock) { + if (pthread_rwlock_unlock((pthread_rwlock_t *) lock) != 0) { + abort(); + } +} + +void CRYPTO_MUTEX_cleanup(CRYPTO_MUTEX *lock) { + pthread_rwlock_destroy((pthread_rwlock_t *) lock); +} + +void CRYPTO_STATIC_MUTEX_lock_read(struct CRYPTO_STATIC_MUTEX *lock) { + if (pthread_rwlock_rdlock(&lock->lock) != 0) { + abort(); + } +} + +void CRYPTO_STATIC_MUTEX_lock_write(struct CRYPTO_STATIC_MUTEX *lock) { + if (pthread_rwlock_wrlock(&lock->lock) != 0) { + abort(); + } +} + +void CRYPTO_STATIC_MUTEX_unlock_read(struct CRYPTO_STATIC_MUTEX *lock) { + if (pthread_rwlock_unlock(&lock->lock) != 0) { + abort(); + } +} + +void CRYPTO_STATIC_MUTEX_unlock_write(struct CRYPTO_STATIC_MUTEX *lock) { + if (pthread_rwlock_unlock(&lock->lock) != 0) { + abort(); + } +} + +void CRYPTO_once(CRYPTO_once_t *once, void (*init)(void)) { + if (pthread_once(once, init) != 0) { + abort(); + } +} + +static pthread_mutex_t g_destructors_lock = PTHREAD_MUTEX_INITIALIZER; +static thread_local_destructor_t g_destructors[NUM_OPENSSL_THREAD_LOCALS]; + +// thread_local_destructor is called when a thread exits. It releases thread +// local data for that thread only. +static void thread_local_destructor(void *arg) { + if (arg == NULL) { + return; + } + + thread_local_destructor_t destructors[NUM_OPENSSL_THREAD_LOCALS]; + if (pthread_mutex_lock(&g_destructors_lock) != 0) { + return; + } + OPENSSL_memcpy(destructors, g_destructors, sizeof(destructors)); + pthread_mutex_unlock(&g_destructors_lock); + + unsigned i; + void **pointers = arg; + for (i = 0; i < NUM_OPENSSL_THREAD_LOCALS; i++) { + if (destructors[i] != NULL) { + destructors[i](pointers[i]); + } + } + + OPENSSL_free(pointers); +} + +static pthread_once_t g_thread_local_init_once = PTHREAD_ONCE_INIT; +static pthread_key_t g_thread_local_key; +static int g_thread_local_key_created = 0; + +// OPENSSL_DANGEROUS_RELEASE_PTHREAD_KEY can be defined to cause +// |pthread_key_delete| to be called in a destructor function. This can be +// useful for programs that dlclose BoringSSL. +// +// Note that dlclose()ing BoringSSL is not supported and will leak memory: +// thread-local values will be leaked as well as anything initialised via a +// once. The |pthread_key_t| is destroyed because they run out very quickly, +// while the other leaks are slow, and this allows code that happens to use +// dlclose() despite all the problems to continue functioning. +// +// This is marked "dangerous" because it can cause multi-threaded processes to +// crash (even if they don't use dlclose): if the destructor runs while other +// threads are still executing then they may end up using an invalid key to +// access thread-local variables. +// +// This may be removed after February 2020. +#if defined(OPENSSL_DANGEROUS_RELEASE_PTHREAD_KEY) && \ + (defined(__GNUC__) || defined(__clang__)) +// thread_key_destructor is called when the library is unloaded with dlclose. +static void thread_key_destructor(void) __attribute__((destructor, unused)); +static void thread_key_destructor(void) { + if (g_thread_local_key_created) { + g_thread_local_key_created = 0; + pthread_key_delete(g_thread_local_key); + } +} +#endif + +static void thread_local_init(void) { + g_thread_local_key_created = + pthread_key_create(&g_thread_local_key, thread_local_destructor) == 0; +} + +void *CRYPTO_get_thread_local(thread_local_data_t index) { + CRYPTO_once(&g_thread_local_init_once, thread_local_init); + if (!g_thread_local_key_created) { + return NULL; + } + + void **pointers = pthread_getspecific(g_thread_local_key); + if (pointers == NULL) { + return NULL; + } + return pointers[index]; +} + +int CRYPTO_set_thread_local(thread_local_data_t index, void *value, + thread_local_destructor_t destructor) { + CRYPTO_once(&g_thread_local_init_once, thread_local_init); + if (!g_thread_local_key_created) { + destructor(value); + return 0; + } + + void **pointers = pthread_getspecific(g_thread_local_key); + if (pointers == NULL) { + pointers = OPENSSL_malloc(sizeof(void *) * NUM_OPENSSL_THREAD_LOCALS); + if (pointers == NULL) { + destructor(value); + return 0; + } + OPENSSL_memset(pointers, 0, sizeof(void *) * NUM_OPENSSL_THREAD_LOCALS); + if (pthread_setspecific(g_thread_local_key, pointers) != 0) { + OPENSSL_free(pointers); + destructor(value); + return 0; + } + } + + if (pthread_mutex_lock(&g_destructors_lock) != 0) { + destructor(value); + return 0; + } + g_destructors[index] = destructor; + pthread_mutex_unlock(&g_destructors_lock); + + pointers[index] = value; + return 1; +} + +#endif // OPENSSL_PTHREADS diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/thread_win.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/thread_win.c new file mode 100644 index 0000000..66183ee --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/thread_win.c @@ -0,0 +1,237 @@ +/* Copyright (c) 2015, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include "internal.h" + +#if defined(OPENSSL_WINDOWS_THREADS) + +OPENSSL_MSVC_PRAGMA(warning(push, 3)) +#include +OPENSSL_MSVC_PRAGMA(warning(pop)) + +#include +#include + +#include +#include + + +OPENSSL_COMPILE_ASSERT(sizeof(CRYPTO_MUTEX) >= sizeof(SRWLOCK), + CRYPTO_MUTEX_too_small); + +static BOOL CALLBACK call_once_init(INIT_ONCE *once, void *arg, void **out) { + void (**init)(void) = (void (**)(void))arg; + (**init)(); + return TRUE; +} + +void CRYPTO_once(CRYPTO_once_t *once, void (*init)(void)) { + if (!InitOnceExecuteOnce(once, call_once_init, &init, NULL)) { + abort(); + } +} + +void CRYPTO_MUTEX_init(CRYPTO_MUTEX *lock) { + InitializeSRWLock((SRWLOCK *) lock); +} + +void CRYPTO_MUTEX_lock_read(CRYPTO_MUTEX *lock) { + AcquireSRWLockShared((SRWLOCK *) lock); +} + +void CRYPTO_MUTEX_lock_write(CRYPTO_MUTEX *lock) { + AcquireSRWLockExclusive((SRWLOCK *) lock); +} + +void CRYPTO_MUTEX_unlock_read(CRYPTO_MUTEX *lock) { + ReleaseSRWLockShared((SRWLOCK *) lock); +} + +void CRYPTO_MUTEX_unlock_write(CRYPTO_MUTEX *lock) { + ReleaseSRWLockExclusive((SRWLOCK *) lock); +} + +void CRYPTO_MUTEX_cleanup(CRYPTO_MUTEX *lock) { + // SRWLOCKs require no cleanup. +} + +void CRYPTO_STATIC_MUTEX_lock_read(struct CRYPTO_STATIC_MUTEX *lock) { + AcquireSRWLockShared(&lock->lock); +} + +void CRYPTO_STATIC_MUTEX_lock_write(struct CRYPTO_STATIC_MUTEX *lock) { + AcquireSRWLockExclusive(&lock->lock); +} + +void CRYPTO_STATIC_MUTEX_unlock_read(struct CRYPTO_STATIC_MUTEX *lock) { + ReleaseSRWLockShared(&lock->lock); +} + +void CRYPTO_STATIC_MUTEX_unlock_write(struct CRYPTO_STATIC_MUTEX *lock) { + ReleaseSRWLockExclusive(&lock->lock); +} + +static CRITICAL_SECTION g_destructors_lock; +static thread_local_destructor_t g_destructors[NUM_OPENSSL_THREAD_LOCALS]; + +static CRYPTO_once_t g_thread_local_init_once = CRYPTO_ONCE_INIT; +static DWORD g_thread_local_key; +static int g_thread_local_failed; + +static void thread_local_init(void) { + if (!InitializeCriticalSectionAndSpinCount(&g_destructors_lock, 0x400)) { + g_thread_local_failed = 1; + return; + } + g_thread_local_key = TlsAlloc(); + g_thread_local_failed = (g_thread_local_key == TLS_OUT_OF_INDEXES); +} + +static void NTAPI thread_local_destructor(PVOID module, DWORD reason, + PVOID reserved) { + // Only free memory on |DLL_THREAD_DETACH|, not |DLL_PROCESS_DETACH|. In + // VS2015's debug runtime, the C runtime has been unloaded by the time + // |DLL_PROCESS_DETACH| runs. See https://crbug.com/575795. This is consistent + // with |pthread_key_create| which does not call destructors on process exit, + // only thread exit. + if (reason != DLL_THREAD_DETACH) { + return; + } + + CRYPTO_once(&g_thread_local_init_once, thread_local_init); + if (g_thread_local_failed) { + return; + } + + void **pointers = (void**) TlsGetValue(g_thread_local_key); + if (pointers == NULL) { + return; + } + + thread_local_destructor_t destructors[NUM_OPENSSL_THREAD_LOCALS]; + + EnterCriticalSection(&g_destructors_lock); + OPENSSL_memcpy(destructors, g_destructors, sizeof(destructors)); + LeaveCriticalSection(&g_destructors_lock); + + unsigned i; + for (i = 0; i < NUM_OPENSSL_THREAD_LOCALS; i++) { + if (destructors[i] != NULL) { + destructors[i](pointers[i]); + } + } + + OPENSSL_free(pointers); +} + +// Thread Termination Callbacks. +// +// Windows doesn't support a per-thread destructor with its TLS primitives. +// So, we build it manually by inserting a function to be called on each +// thread's exit. This magic is from http://www.codeproject.com/threads/tls.asp +// and it works for VC++ 7.0 and later. +// +// Force a reference to _tls_used to make the linker create the TLS directory +// if it's not already there. (E.g. if __declspec(thread) is not used). Force +// a reference to p_thread_callback_boringssl to prevent whole program +// optimization from discarding the variable. +#ifdef _WIN64 +#pragma comment(linker, "/INCLUDE:_tls_used") +#pragma comment(linker, "/INCLUDE:p_thread_callback_boringssl") +#else +#pragma comment(linker, "/INCLUDE:__tls_used") +#pragma comment(linker, "/INCLUDE:_p_thread_callback_boringssl") +#endif + +// .CRT$XLA to .CRT$XLZ is an array of PIMAGE_TLS_CALLBACK pointers that are +// called automatically by the OS loader code (not the CRT) when the module is +// loaded and on thread creation. They are NOT called if the module has been +// loaded by a LoadLibrary() call. It must have implicitly been loaded at +// process startup. +// +// By implicitly loaded, I mean that it is directly referenced by the main EXE +// or by one of its dependent DLLs. Delay-loaded DLL doesn't count as being +// implicitly loaded. +// +// See VC\crt\src\tlssup.c for reference. + +// The linker must not discard p_thread_callback_boringssl. (We force a +// reference to this variable with a linker /INCLUDE:symbol pragma to ensure +// that.) If this variable is discarded, the OnThreadExit function will never +// be called. +#ifdef _WIN64 + +// .CRT section is merged with .rdata on x64 so it must be constant data. +#pragma const_seg(".CRT$XLC") +// When defining a const variable, it must have external linkage to be sure the +// linker doesn't discard it. +extern const PIMAGE_TLS_CALLBACK p_thread_callback_boringssl; +const PIMAGE_TLS_CALLBACK p_thread_callback_boringssl = thread_local_destructor; +// Reset the default section. +#pragma const_seg() + +#else + +#pragma data_seg(".CRT$XLC") +PIMAGE_TLS_CALLBACK p_thread_callback_boringssl = thread_local_destructor; +// Reset the default section. +#pragma data_seg() + +#endif // _WIN64 + +void *CRYPTO_get_thread_local(thread_local_data_t index) { + CRYPTO_once(&g_thread_local_init_once, thread_local_init); + if (g_thread_local_failed) { + return NULL; + } + + void **pointers = TlsGetValue(g_thread_local_key); + if (pointers == NULL) { + return NULL; + } + return pointers[index]; +} + +int CRYPTO_set_thread_local(thread_local_data_t index, void *value, + thread_local_destructor_t destructor) { + CRYPTO_once(&g_thread_local_init_once, thread_local_init); + if (g_thread_local_failed) { + destructor(value); + return 0; + } + + void **pointers = TlsGetValue(g_thread_local_key); + if (pointers == NULL) { + pointers = OPENSSL_malloc(sizeof(void *) * NUM_OPENSSL_THREAD_LOCALS); + if (pointers == NULL) { + destructor(value); + return 0; + } + OPENSSL_memset(pointers, 0, sizeof(void *) * NUM_OPENSSL_THREAD_LOCALS); + if (TlsSetValue(g_thread_local_key, pointers) == 0) { + OPENSSL_free(pointers); + destructor(value); + return 0; + } + } + + EnterCriticalSection(&g_destructors_lock); + g_destructors[index] = destructor; + LeaveCriticalSection(&g_destructors_lock); + + pointers[index] = value; + return 1; +} + +#endif // OPENSSL_WINDOWS_THREADS diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/thread_win.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/thread_win.c.grpc_back new file mode 100644 index 0000000..d6fa548 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/thread_win.c.grpc_back @@ -0,0 +1,237 @@ +/* Copyright (c) 2015, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include "internal.h" + +#if defined(OPENSSL_WINDOWS_THREADS) + +OPENSSL_MSVC_PRAGMA(warning(push, 3)) +#include +OPENSSL_MSVC_PRAGMA(warning(pop)) + +#include +#include + +#include +#include + + +OPENSSL_COMPILE_ASSERT(sizeof(CRYPTO_MUTEX) >= sizeof(SRWLOCK), + CRYPTO_MUTEX_too_small); + +static BOOL CALLBACK call_once_init(INIT_ONCE *once, void *arg, void **out) { + void (**init)(void) = (void (**)(void))arg; + (**init)(); + return TRUE; +} + +void CRYPTO_once(CRYPTO_once_t *once, void (*init)(void)) { + if (!InitOnceExecuteOnce(once, call_once_init, &init, NULL)) { + abort(); + } +} + +void CRYPTO_MUTEX_init(CRYPTO_MUTEX *lock) { + InitializeSRWLock((SRWLOCK *) lock); +} + +void CRYPTO_MUTEX_lock_read(CRYPTO_MUTEX *lock) { + AcquireSRWLockShared((SRWLOCK *) lock); +} + +void CRYPTO_MUTEX_lock_write(CRYPTO_MUTEX *lock) { + AcquireSRWLockExclusive((SRWLOCK *) lock); +} + +void CRYPTO_MUTEX_unlock_read(CRYPTO_MUTEX *lock) { + ReleaseSRWLockShared((SRWLOCK *) lock); +} + +void CRYPTO_MUTEX_unlock_write(CRYPTO_MUTEX *lock) { + ReleaseSRWLockExclusive((SRWLOCK *) lock); +} + +void CRYPTO_MUTEX_cleanup(CRYPTO_MUTEX *lock) { + // SRWLOCKs require no cleanup. +} + +void CRYPTO_STATIC_MUTEX_lock_read(struct CRYPTO_STATIC_MUTEX *lock) { + AcquireSRWLockShared(&lock->lock); +} + +void CRYPTO_STATIC_MUTEX_lock_write(struct CRYPTO_STATIC_MUTEX *lock) { + AcquireSRWLockExclusive(&lock->lock); +} + +void CRYPTO_STATIC_MUTEX_unlock_read(struct CRYPTO_STATIC_MUTEX *lock) { + ReleaseSRWLockShared(&lock->lock); +} + +void CRYPTO_STATIC_MUTEX_unlock_write(struct CRYPTO_STATIC_MUTEX *lock) { + ReleaseSRWLockExclusive(&lock->lock); +} + +static CRITICAL_SECTION g_destructors_lock; +static thread_local_destructor_t g_destructors[NUM_OPENSSL_THREAD_LOCALS]; + +static CRYPTO_once_t g_thread_local_init_once = CRYPTO_ONCE_INIT; +static DWORD g_thread_local_key; +static int g_thread_local_failed; + +static void thread_local_init(void) { + if (!InitializeCriticalSectionAndSpinCount(&g_destructors_lock, 0x400)) { + g_thread_local_failed = 1; + return; + } + g_thread_local_key = TlsAlloc(); + g_thread_local_failed = (g_thread_local_key == TLS_OUT_OF_INDEXES); +} + +static void NTAPI thread_local_destructor(PVOID module, DWORD reason, + PVOID reserved) { + // Only free memory on |DLL_THREAD_DETACH|, not |DLL_PROCESS_DETACH|. In + // VS2015's debug runtime, the C runtime has been unloaded by the time + // |DLL_PROCESS_DETACH| runs. See https://crbug.com/575795. This is consistent + // with |pthread_key_create| which does not call destructors on process exit, + // only thread exit. + if (reason != DLL_THREAD_DETACH) { + return; + } + + CRYPTO_once(&g_thread_local_init_once, thread_local_init); + if (g_thread_local_failed) { + return; + } + + void **pointers = (void**) TlsGetValue(g_thread_local_key); + if (pointers == NULL) { + return; + } + + thread_local_destructor_t destructors[NUM_OPENSSL_THREAD_LOCALS]; + + EnterCriticalSection(&g_destructors_lock); + OPENSSL_memcpy(destructors, g_destructors, sizeof(destructors)); + LeaveCriticalSection(&g_destructors_lock); + + unsigned i; + for (i = 0; i < NUM_OPENSSL_THREAD_LOCALS; i++) { + if (destructors[i] != NULL) { + destructors[i](pointers[i]); + } + } + + OPENSSL_free(pointers); +} + +// Thread Termination Callbacks. +// +// Windows doesn't support a per-thread destructor with its TLS primitives. +// So, we build it manually by inserting a function to be called on each +// thread's exit. This magic is from http://www.codeproject.com/threads/tls.asp +// and it works for VC++ 7.0 and later. +// +// Force a reference to _tls_used to make the linker create the TLS directory +// if it's not already there. (E.g. if __declspec(thread) is not used). Force +// a reference to p_thread_callback_boringssl to prevent whole program +// optimization from discarding the variable. +#ifdef _WIN64 +#pragma comment(linker, "/INCLUDE:_tls_used") +#pragma comment(linker, "/INCLUDE:p_thread_callback_boringssl") +#else +#pragma comment(linker, "/INCLUDE:__tls_used") +#pragma comment(linker, "/INCLUDE:_p_thread_callback_boringssl") +#endif + +// .CRT$XLA to .CRT$XLZ is an array of PIMAGE_TLS_CALLBACK pointers that are +// called automatically by the OS loader code (not the CRT) when the module is +// loaded and on thread creation. They are NOT called if the module has been +// loaded by a LoadLibrary() call. It must have implicitly been loaded at +// process startup. +// +// By implicitly loaded, I mean that it is directly referenced by the main EXE +// or by one of its dependent DLLs. Delay-loaded DLL doesn't count as being +// implicitly loaded. +// +// See VC\crt\src\tlssup.c for reference. + +// The linker must not discard p_thread_callback_boringssl. (We force a +// reference to this variable with a linker /INCLUDE:symbol pragma to ensure +// that.) If this variable is discarded, the OnThreadExit function will never +// be called. +#ifdef _WIN64 + +// .CRT section is merged with .rdata on x64 so it must be constant data. +#pragma const_seg(".CRT$XLC") +// When defining a const variable, it must have external linkage to be sure the +// linker doesn't discard it. +extern const PIMAGE_TLS_CALLBACK p_thread_callback_boringssl; +const PIMAGE_TLS_CALLBACK p_thread_callback_boringssl = thread_local_destructor; +// Reset the default section. +#pragma const_seg() + +#else + +#pragma data_seg(".CRT$XLC") +PIMAGE_TLS_CALLBACK p_thread_callback_boringssl = thread_local_destructor; +// Reset the default section. +#pragma data_seg() + +#endif // _WIN64 + +void *CRYPTO_get_thread_local(thread_local_data_t index) { + CRYPTO_once(&g_thread_local_init_once, thread_local_init); + if (g_thread_local_failed) { + return NULL; + } + + void **pointers = TlsGetValue(g_thread_local_key); + if (pointers == NULL) { + return NULL; + } + return pointers[index]; +} + +int CRYPTO_set_thread_local(thread_local_data_t index, void *value, + thread_local_destructor_t destructor) { + CRYPTO_once(&g_thread_local_init_once, thread_local_init); + if (g_thread_local_failed) { + destructor(value); + return 0; + } + + void **pointers = TlsGetValue(g_thread_local_key); + if (pointers == NULL) { + pointers = OPENSSL_malloc(sizeof(void *) * NUM_OPENSSL_THREAD_LOCALS); + if (pointers == NULL) { + destructor(value); + return 0; + } + OPENSSL_memset(pointers, 0, sizeof(void *) * NUM_OPENSSL_THREAD_LOCALS); + if (TlsSetValue(g_thread_local_key, pointers) == 0) { + OPENSSL_free(pointers); + destructor(value); + return 0; + } + } + + EnterCriticalSection(&g_destructors_lock); + g_destructors[index] = destructor; + LeaveCriticalSection(&g_destructors_lock); + + pointers[index] = value; + return 1; +} + +#endif // OPENSSL_WINDOWS_THREADS diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/a_digest.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/a_digest.c new file mode 100644 index 0000000..7186690 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/a_digest.c @@ -0,0 +1,96 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 + +int ASN1_digest(i2d_of_void *i2d, const EVP_MD *type, char *data, + unsigned char *md, unsigned int *len) +{ + int i, ret; + unsigned char *str, *p; + + i = i2d(data, NULL); + if ((str = (unsigned char *)OPENSSL_malloc(i)) == NULL) { + OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); + return (0); + } + p = str; + i2d(data, &p); + + ret = EVP_Digest(str, i, md, len, type, NULL); + OPENSSL_free(str); + return ret; +} + +int ASN1_item_digest(const ASN1_ITEM *it, const EVP_MD *type, void *asn, + unsigned char *md, unsigned int *len) +{ + int i, ret; + unsigned char *str = NULL; + + i = ASN1_item_i2d(asn, &str, it); + if (!str) + return (0); + + ret = EVP_Digest(str, i, md, len, type, NULL); + OPENSSL_free(str); + return ret; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/a_digest.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/a_digest.c.grpc_back new file mode 100644 index 0000000..b88d6ac --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/a_digest.c.grpc_back @@ -0,0 +1,96 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 + +int ASN1_digest(i2d_of_void *i2d, const EVP_MD *type, char *data, + unsigned char *md, unsigned int *len) +{ + int i, ret; + unsigned char *str, *p; + + i = i2d(data, NULL); + if ((str = (unsigned char *)OPENSSL_malloc(i)) == NULL) { + OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); + return (0); + } + p = str; + i2d(data, &p); + + ret = EVP_Digest(str, i, md, len, type, NULL); + OPENSSL_free(str); + return ret; +} + +int ASN1_item_digest(const ASN1_ITEM *it, const EVP_MD *type, void *asn, + unsigned char *md, unsigned int *len) +{ + int i, ret; + unsigned char *str = NULL; + + i = ASN1_item_i2d(asn, &str, it); + if (!str) + return (0); + + ret = EVP_Digest(str, i, md, len, type, NULL); + OPENSSL_free(str); + return ret; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/a_sign.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/a_sign.c new file mode 100644 index 0000000..c3d5cb8 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/a_sign.c @@ -0,0 +1,128 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 +#include +#include + +#include "internal.h" + +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) +{ + EVP_PKEY *pkey; + unsigned char *buf_in = NULL, *buf_out = NULL; + size_t inl = 0, outl = 0; + + pkey = EVP_PKEY_CTX_get0_pkey(ctx->pctx); + + /* Write out the requested copies of the AlgorithmIdentifier. */ + if (algor1 && !x509_digest_sign_algorithm(ctx, algor1)) { + goto err; + } + if (algor2 && !x509_digest_sign_algorithm(ctx, algor2)) { + goto err; + } + + inl = ASN1_item_i2d(asn, &buf_in, it); + outl = EVP_PKEY_size(pkey); + buf_out = OPENSSL_malloc((unsigned int)outl); + if ((buf_in == NULL) || (buf_out == NULL)) { + outl = 0; + OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (!EVP_DigestSign(ctx, buf_out, &outl, buf_in, inl)) { + outl = 0; + OPENSSL_PUT_ERROR(X509, 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); + OPENSSL_free(buf_in); + OPENSSL_free(buf_out); + return (outl); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/a_sign.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/a_sign.c.grpc_back new file mode 100644 index 0000000..6c7f713 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/a_sign.c.grpc_back @@ -0,0 +1,128 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 +#include +#include + +#include "internal.h" + +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) +{ + EVP_PKEY *pkey; + unsigned char *buf_in = NULL, *buf_out = NULL; + size_t inl = 0, outl = 0; + + pkey = EVP_PKEY_CTX_get0_pkey(ctx->pctx); + + /* Write out the requested copies of the AlgorithmIdentifier. */ + if (algor1 && !x509_digest_sign_algorithm(ctx, algor1)) { + goto err; + } + if (algor2 && !x509_digest_sign_algorithm(ctx, algor2)) { + goto err; + } + + inl = ASN1_item_i2d(asn, &buf_in, it); + outl = EVP_PKEY_size(pkey); + buf_out = OPENSSL_malloc((unsigned int)outl); + if ((buf_in == NULL) || (buf_out == NULL)) { + outl = 0; + OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (!EVP_DigestSign(ctx, buf_out, &outl, buf_in, inl)) { + outl = 0; + OPENSSL_PUT_ERROR(X509, 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); + OPENSSL_free(buf_in); + OPENSSL_free(buf_out); + return (outl); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/a_strex.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/a_strex.c new file mode 100644 index 0000000..79c2fe9 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/a_strex.c @@ -0,0 +1,633 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 +#include + +#include "charmap.h" +#include "../asn1/asn1_locl.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) + +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. + */ + +#define HEX_SIZE(type) (sizeof(type)*2) + +static int do_esc_char(uint32_t c, unsigned char flags, char *do_quotes, + char_io *io_ch, void *arg) +{ + unsigned char chflgs, chtmp; + char tmphex[HEX_SIZE(uint32_t) + 3]; + + if (c > 0xffff) { + BIO_snprintf(tmphex, sizeof tmphex, "\\W%08" PRIX32, c); + if (!io_ch(arg, tmphex, 10)) + return -1; + return 10; + } + if (c > 0xff) { + BIO_snprintf(tmphex, sizeof tmphex, "\\U%04" PRIX32, 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; + unsigned char orflags, *p, *q; + uint32_t c; + p = buf; + q = buf + buflen; + outlen = 0; + while (p != q) { + if (p == buf && flags & ASN1_STRFLGS_ESC_2253) + orflags = CHARTYPE_FIRST_ESC_2253; + else + orflags = 0; + switch (type & BUF_TYPE_WIDTH_MASK) { + case 4: + c = ((uint32_t)*p++) << 24; + c |= ((uint32_t)*p++) << 16; + c |= ((uint32_t)*p++) << 8; + c |= *p++; + break; + + case 2: + c = ((uint32_t)*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 */ + 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; + const 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; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/a_strex.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/a_strex.c.grpc_back new file mode 100644 index 0000000..465ad08 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/a_strex.c.grpc_back @@ -0,0 +1,633 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 +#include + +#include "charmap.h" +#include "../asn1/asn1_locl.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) + +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. + */ + +#define HEX_SIZE(type) (sizeof(type)*2) + +static int do_esc_char(uint32_t c, unsigned char flags, char *do_quotes, + char_io *io_ch, void *arg) +{ + unsigned char chflgs, chtmp; + char tmphex[HEX_SIZE(uint32_t) + 3]; + + if (c > 0xffff) { + BIO_snprintf(tmphex, sizeof tmphex, "\\W%08" PRIX32, c); + if (!io_ch(arg, tmphex, 10)) + return -1; + return 10; + } + if (c > 0xff) { + BIO_snprintf(tmphex, sizeof tmphex, "\\U%04" PRIX32, 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; + unsigned char orflags, *p, *q; + uint32_t c; + p = buf; + q = buf + buflen; + outlen = 0; + while (p != q) { + if (p == buf && flags & ASN1_STRFLGS_ESC_2253) + orflags = CHARTYPE_FIRST_ESC_2253; + else + orflags = 0; + switch (type & BUF_TYPE_WIDTH_MASK) { + case 4: + c = ((uint32_t)*p++) << 24; + c |= ((uint32_t)*p++) << 16; + c |= ((uint32_t)*p++) << 8; + c |= *p++; + break; + + case 2: + c = ((uint32_t)*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 */ + 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; + const 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; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/a_verify.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/a_verify.c new file mode 100644 index 0000000..96a275a --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/a_verify.c @@ -0,0 +1,115 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 +#include +#include +#include +#include +#include +#include + +#include "internal.h" + +int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a, + ASN1_BIT_STRING *signature, void *asn, EVP_PKEY *pkey) +{ + EVP_MD_CTX ctx; + uint8_t *buf_in = NULL; + int ret = 0, inl = 0; + + if (!pkey) { + OPENSSL_PUT_ERROR(X509, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + if (signature->type == V_ASN1_BIT_STRING && signature->flags & 0x7) { + OPENSSL_PUT_ERROR(X509, X509_R_INVALID_BIT_STRING_BITS_LEFT); + return 0; + } + + EVP_MD_CTX_init(&ctx); + + if (!x509_digest_verify_init(&ctx, a, pkey)) { + goto err; + } + + inl = ASN1_item_i2d(asn, &buf_in, it); + + if (buf_in == NULL) { + OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (!EVP_DigestVerify(&ctx, signature->data, (size_t)signature->length, + buf_in, inl)) { + OPENSSL_PUT_ERROR(X509, ERR_R_EVP_LIB); + goto err; + } + + ret = 1; + +err: + OPENSSL_free(buf_in); + EVP_MD_CTX_cleanup(&ctx); + return ret; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/a_verify.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/a_verify.c.grpc_back new file mode 100644 index 0000000..5b75167 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/a_verify.c.grpc_back @@ -0,0 +1,115 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 +#include +#include +#include +#include +#include +#include + +#include "internal.h" + +int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a, + ASN1_BIT_STRING *signature, void *asn, EVP_PKEY *pkey) +{ + EVP_MD_CTX ctx; + uint8_t *buf_in = NULL; + int ret = 0, inl = 0; + + if (!pkey) { + OPENSSL_PUT_ERROR(X509, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + if (signature->type == V_ASN1_BIT_STRING && signature->flags & 0x7) { + OPENSSL_PUT_ERROR(X509, X509_R_INVALID_BIT_STRING_BITS_LEFT); + return 0; + } + + EVP_MD_CTX_init(&ctx); + + if (!x509_digest_verify_init(&ctx, a, pkey)) { + goto err; + } + + inl = ASN1_item_i2d(asn, &buf_in, it); + + if (buf_in == NULL) { + OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); + goto err; + } + + if (!EVP_DigestVerify(&ctx, signature->data, (size_t)signature->length, + buf_in, inl)) { + OPENSSL_PUT_ERROR(X509, ERR_R_EVP_LIB); + goto err; + } + + ret = 1; + +err: + OPENSSL_free(buf_in); + EVP_MD_CTX_cleanup(&ctx); + return ret; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/algorithm.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/algorithm.c new file mode 100644 index 0000000..aadcafb --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/algorithm.c @@ -0,0 +1,153 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 +#include + +#include "internal.h" + + +int x509_digest_sign_algorithm(EVP_MD_CTX *ctx, X509_ALGOR *algor) { + EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx->pctx); + if (pkey == NULL) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_CONTEXT_NOT_INITIALISED); + return 0; + } + + if (EVP_PKEY_id(pkey) == EVP_PKEY_RSA) { + int pad_mode; + if (!EVP_PKEY_CTX_get_rsa_padding(ctx->pctx, &pad_mode)) { + return 0; + } + /* RSA-PSS has special signature algorithm logic. */ + if (pad_mode == RSA_PKCS1_PSS_PADDING) { + return x509_rsa_ctx_to_pss(ctx, algor); + } + } + + if (EVP_PKEY_id(pkey) == EVP_PKEY_ED25519) { + return X509_ALGOR_set0(algor, OBJ_nid2obj(NID_ED25519), V_ASN1_UNDEF, NULL); + } + + /* Default behavior: look up the OID for the algorithm/hash pair and encode + * that. */ + const EVP_MD *digest = EVP_MD_CTX_md(ctx); + if (digest == NULL) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_CONTEXT_NOT_INITIALISED); + return 0; + } + + int sign_nid; + if (!OBJ_find_sigid_by_algs(&sign_nid, EVP_MD_type(digest), + EVP_PKEY_id(pkey))) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED); + return 0; + } + + /* RSA signature algorithms include an explicit NULL parameter. Others omit + * it. */ + int paramtype = + (EVP_PKEY_id(pkey) == EVP_PKEY_RSA) ? V_ASN1_NULL : V_ASN1_UNDEF; + X509_ALGOR_set0(algor, OBJ_nid2obj(sign_nid), paramtype, NULL); + return 1; +} + +int x509_digest_verify_init(EVP_MD_CTX *ctx, X509_ALGOR *sigalg, + EVP_PKEY *pkey) { + /* Convert the signature OID into digest and public key OIDs. */ + int sigalg_nid = OBJ_obj2nid(sigalg->algorithm); + int digest_nid, pkey_nid; + if (!OBJ_find_sigid_algs(sigalg_nid, &digest_nid, &pkey_nid)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM); + return 0; + } + + /* Check the public key OID matches the public key type. */ + if (pkey_nid != EVP_PKEY_id(pkey)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_WRONG_PUBLIC_KEY_TYPE); + return 0; + } + + /* NID_undef signals that there are custom parameters to set. */ + if (digest_nid == NID_undef) { + if (sigalg_nid == NID_rsassaPss) { + return x509_rsa_pss_to_ctx(ctx, sigalg, pkey); + } + if (sigalg_nid == NID_ED25519) { + if (sigalg->parameter != NULL) { + OPENSSL_PUT_ERROR(X509, X509_R_INVALID_PARAMETER); + return 0; + } + return EVP_DigestVerifyInit(ctx, NULL, NULL, NULL, pkey); + } + OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM); + return 0; + } + + /* Otherwise, initialize with the digest from the OID. */ + const EVP_MD *digest = EVP_get_digestbynid(digest_nid); + if (digest == NULL) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM); + return 0; + } + + return EVP_DigestVerifyInit(ctx, NULL, digest, NULL, pkey); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/algorithm.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/algorithm.c.grpc_back new file mode 100644 index 0000000..8f53fff --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/algorithm.c.grpc_back @@ -0,0 +1,153 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 +#include + +#include "internal.h" + + +int x509_digest_sign_algorithm(EVP_MD_CTX *ctx, X509_ALGOR *algor) { + EVP_PKEY *pkey = EVP_PKEY_CTX_get0_pkey(ctx->pctx); + if (pkey == NULL) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_CONTEXT_NOT_INITIALISED); + return 0; + } + + if (EVP_PKEY_id(pkey) == EVP_PKEY_RSA) { + int pad_mode; + if (!EVP_PKEY_CTX_get_rsa_padding(ctx->pctx, &pad_mode)) { + return 0; + } + /* RSA-PSS has special signature algorithm logic. */ + if (pad_mode == RSA_PKCS1_PSS_PADDING) { + return x509_rsa_ctx_to_pss(ctx, algor); + } + } + + if (EVP_PKEY_id(pkey) == EVP_PKEY_ED25519) { + return X509_ALGOR_set0(algor, OBJ_nid2obj(NID_ED25519), V_ASN1_UNDEF, NULL); + } + + /* Default behavior: look up the OID for the algorithm/hash pair and encode + * that. */ + const EVP_MD *digest = EVP_MD_CTX_md(ctx); + if (digest == NULL) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_CONTEXT_NOT_INITIALISED); + return 0; + } + + int sign_nid; + if (!OBJ_find_sigid_by_algs(&sign_nid, EVP_MD_type(digest), + EVP_PKEY_id(pkey))) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED); + return 0; + } + + /* RSA signature algorithms include an explicit NULL parameter. Others omit + * it. */ + int paramtype = + (EVP_PKEY_id(pkey) == EVP_PKEY_RSA) ? V_ASN1_NULL : V_ASN1_UNDEF; + X509_ALGOR_set0(algor, OBJ_nid2obj(sign_nid), paramtype, NULL); + return 1; +} + +int x509_digest_verify_init(EVP_MD_CTX *ctx, X509_ALGOR *sigalg, + EVP_PKEY *pkey) { + /* Convert the signature OID into digest and public key OIDs. */ + int sigalg_nid = OBJ_obj2nid(sigalg->algorithm); + int digest_nid, pkey_nid; + if (!OBJ_find_sigid_algs(sigalg_nid, &digest_nid, &pkey_nid)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM); + return 0; + } + + /* Check the public key OID matches the public key type. */ + if (pkey_nid != EVP_PKEY_id(pkey)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_WRONG_PUBLIC_KEY_TYPE); + return 0; + } + + /* NID_undef signals that there are custom parameters to set. */ + if (digest_nid == NID_undef) { + if (sigalg_nid == NID_rsassaPss) { + return x509_rsa_pss_to_ctx(ctx, sigalg, pkey); + } + if (sigalg_nid == NID_ED25519) { + if (sigalg->parameter != NULL) { + OPENSSL_PUT_ERROR(X509, X509_R_INVALID_PARAMETER); + return 0; + } + return EVP_DigestVerifyInit(ctx, NULL, NULL, NULL, pkey); + } + OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM); + return 0; + } + + /* Otherwise, initialize with the digest from the OID. */ + const EVP_MD *digest = EVP_get_digestbynid(digest_nid); + if (digest == NULL) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM); + return 0; + } + + return EVP_DigestVerifyInit(ctx, NULL, digest, NULL, pkey); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/asn1_gen.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/asn1_gen.c new file mode 100644 index 0000000..e0d9f53 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/asn1_gen.c @@ -0,0 +1,841 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 +#include +#include + +#include "../internal.h" + +/* + * Although this file is in crypto/x509 for layering purposes, it emits + * errors from the ASN.1 module for OpenSSL compatibility. + */ + +#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) + OPENSSL_PUT_ERROR(ASN1, 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 = 0; + 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 */ + OPENSSL_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) { + OPENSSL_PUT_ERROR(ASN1, 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]) { + OPENSSL_PUT_ERROR(ASN1, 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) { + OPENSSL_PUT_ERROR(ASN1, 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) { + OPENSSL_PUT_ERROR(ASN1, 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 { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNKNOWN_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) { + OPENSSL_PUT_ERROR(ASN1, 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; + OPENSSL_PUT_ERROR(ASN1, 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; + size_t 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) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_IMPLICIT_TAG); + return 0; + } + + if (arg->exp_count == ASN1_FLAG_EXP_MAX) { + OPENSSL_PUT_ERROR(ASN1, 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())) { + OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); + return NULL; + } + + if (!str) + str = ""; + + switch (utype) { + + case V_ASN1_NULL: + if (str && *str) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_NULL_VALUE); + goto bad_form; + } + break; + + case V_ASN1_BOOLEAN: + if (format != ASN1_GEN_FORMAT_ASCII) { + OPENSSL_PUT_ERROR(ASN1, 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)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_BOOLEAN); + goto bad_str; + } + break; + + case V_ASN1_INTEGER: + case V_ASN1_ENUMERATED: + if (format != ASN1_GEN_FORMAT_ASCII) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_INTEGER_NOT_ASCII_FORMAT); + goto bad_form; + } + if (!(atmp->value.integer = s2i_ASN1_INTEGER(NULL, (char *)str))) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_INTEGER); + goto bad_str; + } + break; + + case V_ASN1_OBJECT: + if (format != ASN1_GEN_FORMAT_ASCII) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_OBJECT_NOT_ASCII_FORMAT); + goto bad_form; + } + if (!(atmp->value.object = OBJ_txt2obj(str, 0))) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_OBJECT); + goto bad_str; + } + break; + + case V_ASN1_UTCTIME: + case V_ASN1_GENERALIZEDTIME: + if (format != ASN1_GEN_FORMAT_ASCII) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_TIME_NOT_ASCII_FORMAT); + goto bad_form; + } + if (!(atmp->value.asn1_string = ASN1_STRING_new())) { + OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); + goto bad_str; + } + if (!ASN1_STRING_set(atmp->value.asn1_string, str, -1)) { + OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); + goto bad_str; + } + atmp->value.asn1_string->type = utype; + if (!ASN1_TIME_check(atmp->value.asn1_string)) { + OPENSSL_PUT_ERROR(ASN1, 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 { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_FORMAT); + goto bad_form; + } + + if (ASN1_mbstring_copy(&atmp->value.asn1_string, (unsigned char *)str, + -1, format, ASN1_tag2bit(utype)) <= 0) { + OPENSSL_PUT_ERROR(ASN1, 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())) { + OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); + goto bad_form; + } + + if (format == ASN1_GEN_FORMAT_HEX) { + + if (!(rdata = string_to_hex((char *)str, &rdlen))) { + OPENSSL_PUT_ERROR(ASN1, 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)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_LIST_ERROR); + goto bad_str; + } + no_unused = 0; + + } else { + OPENSSL_PUT_ERROR(ASN1, 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: + OPENSSL_PUT_ERROR(ASN1, 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) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_NUMBER); + return 0; + } + if (!ASN1_BIT_STRING_set_bit(bitstr, bitnum, 1)) { + OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); + return 0; + } + return 1; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/asn1_gen.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/asn1_gen.c.grpc_back new file mode 100644 index 0000000..5b74cd1 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/asn1_gen.c.grpc_back @@ -0,0 +1,841 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 +#include +#include + +#include "../internal.h" + +/* + * Although this file is in crypto/x509 for layering purposes, it emits + * errors from the ASN.1 module for OpenSSL compatibility. + */ + +#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) + OPENSSL_PUT_ERROR(ASN1, 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 = 0; + 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 */ + OPENSSL_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) { + OPENSSL_PUT_ERROR(ASN1, 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]) { + OPENSSL_PUT_ERROR(ASN1, 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) { + OPENSSL_PUT_ERROR(ASN1, 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) { + OPENSSL_PUT_ERROR(ASN1, 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 { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNKNOWN_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) { + OPENSSL_PUT_ERROR(ASN1, 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; + OPENSSL_PUT_ERROR(ASN1, 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; + size_t 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) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_IMPLICIT_TAG); + return 0; + } + + if (arg->exp_count == ASN1_FLAG_EXP_MAX) { + OPENSSL_PUT_ERROR(ASN1, 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())) { + OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); + return NULL; + } + + if (!str) + str = ""; + + switch (utype) { + + case V_ASN1_NULL: + if (str && *str) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_NULL_VALUE); + goto bad_form; + } + break; + + case V_ASN1_BOOLEAN: + if (format != ASN1_GEN_FORMAT_ASCII) { + OPENSSL_PUT_ERROR(ASN1, 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)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_BOOLEAN); + goto bad_str; + } + break; + + case V_ASN1_INTEGER: + case V_ASN1_ENUMERATED: + if (format != ASN1_GEN_FORMAT_ASCII) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_INTEGER_NOT_ASCII_FORMAT); + goto bad_form; + } + if (!(atmp->value.integer = s2i_ASN1_INTEGER(NULL, (char *)str))) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_INTEGER); + goto bad_str; + } + break; + + case V_ASN1_OBJECT: + if (format != ASN1_GEN_FORMAT_ASCII) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_OBJECT_NOT_ASCII_FORMAT); + goto bad_form; + } + if (!(atmp->value.object = OBJ_txt2obj(str, 0))) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_OBJECT); + goto bad_str; + } + break; + + case V_ASN1_UTCTIME: + case V_ASN1_GENERALIZEDTIME: + if (format != ASN1_GEN_FORMAT_ASCII) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_TIME_NOT_ASCII_FORMAT); + goto bad_form; + } + if (!(atmp->value.asn1_string = ASN1_STRING_new())) { + OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); + goto bad_str; + } + if (!ASN1_STRING_set(atmp->value.asn1_string, str, -1)) { + OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); + goto bad_str; + } + atmp->value.asn1_string->type = utype; + if (!ASN1_TIME_check(atmp->value.asn1_string)) { + OPENSSL_PUT_ERROR(ASN1, 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 { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_ILLEGAL_FORMAT); + goto bad_form; + } + + if (ASN1_mbstring_copy(&atmp->value.asn1_string, (unsigned char *)str, + -1, format, ASN1_tag2bit(utype)) <= 0) { + OPENSSL_PUT_ERROR(ASN1, 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())) { + OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); + goto bad_form; + } + + if (format == ASN1_GEN_FORMAT_HEX) { + + if (!(rdata = string_to_hex((char *)str, &rdlen))) { + OPENSSL_PUT_ERROR(ASN1, 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)) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_LIST_ERROR); + goto bad_str; + } + no_unused = 0; + + } else { + OPENSSL_PUT_ERROR(ASN1, 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: + OPENSSL_PUT_ERROR(ASN1, 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) { + OPENSSL_PUT_ERROR(ASN1, ASN1_R_INVALID_NUMBER); + return 0; + } + if (!ASN1_BIT_STRING_set_bit(bitstr, bitnum, 1)) { + OPENSSL_PUT_ERROR(ASN1, ERR_R_MALLOC_FAILURE); + return 0; + } + return 1; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/by_dir.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/by_dir.c new file mode 100644 index 0000000..42aac8d --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/by_dir.c @@ -0,0 +1,451 @@ +/* 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 +#include +#include +#include +#include + +#include "../internal.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; + +DEFINE_STACK_OF(BY_DIR_HASH) +DEFINE_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); +static 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 *)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) { + OPENSSL_PUT_ERROR(X509, 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 **a, const BY_DIR_HASH **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) +{ + size_t j, len; + const char *s, *ss, *p; + + if (dir == NULL || !*dir) { + OPENSSL_PUT_ERROR(X509, X509_R_INVALID_DIRECTORY); + return 0; + } + + s = dir; + p = s; + do { + if ((*p == ':') || (*p == '\0')) { + BY_DIR_ENTRY *ent; + ss = s; + s = p + 1; + len = 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) == len && + strncmp(ent->dir, ss, 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) { + OPENSSL_PUT_ERROR(X509, 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(len + 1); + if (!ent->dir || !ent->hashes) { + by_dir_entry_free(ent); + return 0; + } + BUF_strlcpy(ent->dir, ss, len + 1); + if (!sk_BY_DIR_ENTRY_push(ctx->dirs, ent)) { + by_dir_entry_free(ent); + return 0; + } + } + } while (*p++ != '\0'); + return 1; +} + +/* + * g_ent_hashes_lock protects the |hashes| member of all |BY_DIR_ENTRY| + * objects. + */ +static struct CRYPTO_STATIC_MUTEX g_ent_hashes_lock = + CRYPTO_STATIC_MUTEX_INIT; + +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; + size_t i; + int j, k; + unsigned long h; + unsigned long hash_array[2]; + int hash_index; + 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 { + OPENSSL_PUT_ERROR(X509, X509_R_WRONG_LOOKUP_TYPE); + goto finish; + } + + if ((b = BUF_MEM_new()) == NULL) { + OPENSSL_PUT_ERROR(X509, ERR_R_BUF_LIB); + goto finish; + } + + ctx = (BY_DIR *)xl->method_data; + + hash_array[0] = X509_NAME_hash(name); + hash_array[1] = X509_NAME_hash_old(name); + for (hash_index = 0; hash_index < 2; ++hash_index) { + h = hash_array[hash_index]; + for (i = 0; i < sk_BY_DIR_ENTRY_num(ctx->dirs); i++) { + BY_DIR_ENTRY *ent; + size_t 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)) { + OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); + goto finish; + } + if (type == X509_LU_CRL && ent->hashes) { + htmp.hash = h; + CRYPTO_STATIC_MUTEX_lock_read(&g_ent_hashes_lock); + if (sk_BY_DIR_HASH_find(ent->hashes, &idx, &htmp)) { + hent = sk_BY_DIR_HASH_value(ent->hashes, idx); + k = hent->suffix; + } else { + hent = NULL; + k = 0; + } + CRYPTO_STATIC_MUTEX_unlock_read(&g_ent_hashes_lock); + } 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 +# if defined(_WIN32) && !defined(stat) +# 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_MUTEX_lock_write(&xl->store_ctx->objs_lock); + tmp = NULL; + if (sk_X509_OBJECT_find(xl->store_ctx->objs, &idx, &stmp)) { + tmp = sk_X509_OBJECT_value(xl->store_ctx->objs, idx); + } + CRYPTO_MUTEX_unlock_write(&xl->store_ctx->objs_lock); + + /* + * If a CRL, update the last file suffix added for this + */ + + if (type == X509_LU_CRL) { + CRYPTO_STATIC_MUTEX_lock_write(&g_ent_hashes_lock); + /* + * Look for entry again in case another thread added an entry + * first. + */ + if (!hent) { + htmp.hash = h; + if (sk_BY_DIR_HASH_find(ent->hashes, &idx, &htmp)) + hent = sk_BY_DIR_HASH_value(ent->hashes, idx); + } + if (!hent) { + hent = OPENSSL_malloc(sizeof(BY_DIR_HASH)); + if (hent == NULL) { + CRYPTO_STATIC_MUTEX_unlock_write(&g_ent_hashes_lock); + ok = 0; + goto finish; + } + hent->hash = h; + hent->suffix = k; + if (!sk_BY_DIR_HASH_push(ent->hashes, hent)) { + CRYPTO_STATIC_MUTEX_unlock_write(&g_ent_hashes_lock); + OPENSSL_free(hent); + ok = 0; + goto finish; + } + } else if (hent->suffix < k) + hent->suffix = k; + + CRYPTO_STATIC_MUTEX_unlock_write(&g_ent_hashes_lock); + } + + if (tmp != NULL) { + ok = 1; + ret->type = tmp->type; + OPENSSL_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); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/by_dir.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/by_dir.c.grpc_back new file mode 100644 index 0000000..635b851 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/by_dir.c.grpc_back @@ -0,0 +1,451 @@ +/* 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 +#include +#include +#include +#include + +#include "../internal.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; + +DEFINE_STACK_OF(BY_DIR_HASH) +DEFINE_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); +static 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 *)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) { + OPENSSL_PUT_ERROR(X509, 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 **a, const BY_DIR_HASH **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) +{ + size_t j, len; + const char *s, *ss, *p; + + if (dir == NULL || !*dir) { + OPENSSL_PUT_ERROR(X509, X509_R_INVALID_DIRECTORY); + return 0; + } + + s = dir; + p = s; + do { + if ((*p == ':') || (*p == '\0')) { + BY_DIR_ENTRY *ent; + ss = s; + s = p + 1; + len = 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) == len && + strncmp(ent->dir, ss, 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) { + OPENSSL_PUT_ERROR(X509, 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(len + 1); + if (!ent->dir || !ent->hashes) { + by_dir_entry_free(ent); + return 0; + } + BUF_strlcpy(ent->dir, ss, len + 1); + if (!sk_BY_DIR_ENTRY_push(ctx->dirs, ent)) { + by_dir_entry_free(ent); + return 0; + } + } + } while (*p++ != '\0'); + return 1; +} + +/* + * g_ent_hashes_lock protects the |hashes| member of all |BY_DIR_ENTRY| + * objects. + */ +static struct CRYPTO_STATIC_MUTEX g_ent_hashes_lock = + CRYPTO_STATIC_MUTEX_INIT; + +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; + size_t i; + int j, k; + unsigned long h; + unsigned long hash_array[2]; + int hash_index; + 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 { + OPENSSL_PUT_ERROR(X509, X509_R_WRONG_LOOKUP_TYPE); + goto finish; + } + + if ((b = BUF_MEM_new()) == NULL) { + OPENSSL_PUT_ERROR(X509, ERR_R_BUF_LIB); + goto finish; + } + + ctx = (BY_DIR *)xl->method_data; + + hash_array[0] = X509_NAME_hash(name); + hash_array[1] = X509_NAME_hash_old(name); + for (hash_index = 0; hash_index < 2; ++hash_index) { + h = hash_array[hash_index]; + for (i = 0; i < sk_BY_DIR_ENTRY_num(ctx->dirs); i++) { + BY_DIR_ENTRY *ent; + size_t 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)) { + OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); + goto finish; + } + if (type == X509_LU_CRL && ent->hashes) { + htmp.hash = h; + CRYPTO_STATIC_MUTEX_lock_read(&g_ent_hashes_lock); + if (sk_BY_DIR_HASH_find(ent->hashes, &idx, &htmp)) { + hent = sk_BY_DIR_HASH_value(ent->hashes, idx); + k = hent->suffix; + } else { + hent = NULL; + k = 0; + } + CRYPTO_STATIC_MUTEX_unlock_read(&g_ent_hashes_lock); + } 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 +# if defined(_WIN32) && !defined(stat) +# 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_MUTEX_lock_write(&xl->store_ctx->objs_lock); + tmp = NULL; + if (sk_X509_OBJECT_find(xl->store_ctx->objs, &idx, &stmp)) { + tmp = sk_X509_OBJECT_value(xl->store_ctx->objs, idx); + } + CRYPTO_MUTEX_unlock_write(&xl->store_ctx->objs_lock); + + /* + * If a CRL, update the last file suffix added for this + */ + + if (type == X509_LU_CRL) { + CRYPTO_STATIC_MUTEX_lock_write(&g_ent_hashes_lock); + /* + * Look for entry again in case another thread added an entry + * first. + */ + if (!hent) { + htmp.hash = h; + if (sk_BY_DIR_HASH_find(ent->hashes, &idx, &htmp)) + hent = sk_BY_DIR_HASH_value(ent->hashes, idx); + } + if (!hent) { + hent = OPENSSL_malloc(sizeof(BY_DIR_HASH)); + if (hent == NULL) { + CRYPTO_STATIC_MUTEX_unlock_write(&g_ent_hashes_lock); + ok = 0; + goto finish; + } + hent->hash = h; + hent->suffix = k; + if (!sk_BY_DIR_HASH_push(ent->hashes, hent)) { + CRYPTO_STATIC_MUTEX_unlock_write(&g_ent_hashes_lock); + OPENSSL_free(hent); + ok = 0; + goto finish; + } + } else if (hent->suffix < k) + hent->suffix = k; + + CRYPTO_STATIC_MUTEX_unlock_write(&g_ent_hashes_lock); + } + + if (tmp != NULL) { + ok = 1; + ret->type = tmp->type; + OPENSSL_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); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/by_file.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/by_file.c new file mode 100644 index 0000000..a83f159 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/by_file.c @@ -0,0 +1,274 @@ +/* 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 +#include + +#ifndef OPENSSL_NO_STDIO + +static int by_file_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, + long argl, char **ret); +static 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 = 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) { + OPENSSL_PUT_ERROR(X509, 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()); + + if ((in == NULL) || (BIO_read_filename(in, file) <= 0)) { + OPENSSL_PUT_ERROR(X509, ERR_R_SYS_LIB); + goto err; + } + + if (type == X509_FILETYPE_PEM) { + for (;;) { + x = PEM_read_bio_X509_AUX(in, NULL, 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 { + OPENSSL_PUT_ERROR(X509, 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) { + OPENSSL_PUT_ERROR(X509, ERR_R_ASN1_LIB); + goto err; + } + i = X509_STORE_add_cert(ctx->store_ctx, x); + if (!i) + goto err; + ret = i; + } else { + OPENSSL_PUT_ERROR(X509, 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()); + + if ((in == NULL) || (BIO_read_filename(in, file) <= 0)) { + OPENSSL_PUT_ERROR(X509, ERR_R_SYS_LIB); + goto err; + } + + if (type == X509_FILETYPE_PEM) { + for (;;) { + x = PEM_read_bio_X509_CRL(in, NULL, 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 { + OPENSSL_PUT_ERROR(X509, 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) { + OPENSSL_PUT_ERROR(X509, ERR_R_ASN1_LIB); + goto err; + } + i = X509_STORE_add_crl(ctx->store_ctx, x); + if (!i) + goto err; + ret = i; + } else { + OPENSSL_PUT_ERROR(X509, 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; + size_t i; + int count = 0; + if (type != X509_FILETYPE_PEM) + return X509_load_cert_file(ctx, file, type); + in = BIO_new_file(file, "r"); + if (!in) { + OPENSSL_PUT_ERROR(X509, ERR_R_SYS_LIB); + return 0; + } + inf = PEM_X509_INFO_read_bio(in, NULL, NULL, NULL); + BIO_free(in); + if (!inf) { + OPENSSL_PUT_ERROR(X509, 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/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/by_file.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/by_file.c.grpc_back new file mode 100644 index 0000000..555cb85 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/by_file.c.grpc_back @@ -0,0 +1,274 @@ +/* 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 +#include + +#ifndef OPENSSL_NO_STDIO + +static int by_file_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, + long argl, char **ret); +static 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 = 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) { + OPENSSL_PUT_ERROR(X509, 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()); + + if ((in == NULL) || (BIO_read_filename(in, file) <= 0)) { + OPENSSL_PUT_ERROR(X509, ERR_R_SYS_LIB); + goto err; + } + + if (type == X509_FILETYPE_PEM) { + for (;;) { + x = PEM_read_bio_X509_AUX(in, NULL, 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 { + OPENSSL_PUT_ERROR(X509, 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) { + OPENSSL_PUT_ERROR(X509, ERR_R_ASN1_LIB); + goto err; + } + i = X509_STORE_add_cert(ctx->store_ctx, x); + if (!i) + goto err; + ret = i; + } else { + OPENSSL_PUT_ERROR(X509, 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()); + + if ((in == NULL) || (BIO_read_filename(in, file) <= 0)) { + OPENSSL_PUT_ERROR(X509, ERR_R_SYS_LIB); + goto err; + } + + if (type == X509_FILETYPE_PEM) { + for (;;) { + x = PEM_read_bio_X509_CRL(in, NULL, 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 { + OPENSSL_PUT_ERROR(X509, 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) { + OPENSSL_PUT_ERROR(X509, ERR_R_ASN1_LIB); + goto err; + } + i = X509_STORE_add_crl(ctx->store_ctx, x); + if (!i) + goto err; + ret = i; + } else { + OPENSSL_PUT_ERROR(X509, 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; + size_t i; + int count = 0; + if (type != X509_FILETYPE_PEM) + return X509_load_cert_file(ctx, file, type); + in = BIO_new_file(file, "r"); + if (!in) { + OPENSSL_PUT_ERROR(X509, ERR_R_SYS_LIB); + return 0; + } + inf = PEM_X509_INFO_read_bio(in, NULL, NULL, NULL); + BIO_free(in); + if (!inf) { + OPENSSL_PUT_ERROR(X509, 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/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/charmap.h b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/charmap.h new file mode 100644 index 0000000..3305ad1 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/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/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/charmap.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/charmap.h.grpc_back new file mode 100644 index 0000000..3305ad1 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/charmap.h.grpc_back @@ -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/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/i2d_pr.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/i2d_pr.c new file mode 100644 index 0000000..df75012 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/i2d_pr.c @@ -0,0 +1,83 @@ +/* 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 +#include +#include +#include +#include + + +int i2d_PrivateKey(const EVP_PKEY *a, uint8_t **pp) +{ + switch (EVP_PKEY_id(a)) { + case EVP_PKEY_RSA: + return i2d_RSAPrivateKey(a->pkey.rsa, pp); + case EVP_PKEY_EC: + return i2d_ECPrivateKey(a->pkey.ec, pp); + case EVP_PKEY_DSA: + return i2d_DSAPrivateKey(a->pkey.dsa, pp); + default: + /* + * Although this file is in crypto/x509 for layering reasons, it emits + * an error code from ASN1 for OpenSSL compatibility. + */ + OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE); + return -1; + } +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/i2d_pr.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/i2d_pr.c.grpc_back new file mode 100644 index 0000000..c3fb8a8 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/i2d_pr.c.grpc_back @@ -0,0 +1,83 @@ +/* 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 +#include +#include +#include +#include + + +int i2d_PrivateKey(const EVP_PKEY *a, uint8_t **pp) +{ + switch (EVP_PKEY_id(a)) { + case EVP_PKEY_RSA: + return i2d_RSAPrivateKey(a->pkey.rsa, pp); + case EVP_PKEY_EC: + return i2d_ECPrivateKey(a->pkey.ec, pp); + case EVP_PKEY_DSA: + return i2d_DSAPrivateKey(a->pkey.dsa, pp); + default: + /* + * Although this file is in crypto/x509 for layering reasons, it emits + * an error code from ASN1 for OpenSSL compatibility. + */ + OPENSSL_PUT_ERROR(ASN1, ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE); + return -1; + } +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/internal.h b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/internal.h new file mode 100644 index 0000000..435f90c --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/internal.h @@ -0,0 +1,66 @@ +/* Copyright (c) 2016, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_X509_INTERNAL_H +#define OPENSSL_HEADER_X509_INTERNAL_H + +#include +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +/* RSA-PSS functions. */ + +/* x509_rsa_pss_to_ctx configures |ctx| for an RSA-PSS operation based on + * signature algorithm parameters in |sigalg| (which must have type + * |NID_rsassaPss|) and key |pkey|. It returns one on success and zero on + * error. */ +int x509_rsa_pss_to_ctx(EVP_MD_CTX *ctx, X509_ALGOR *sigalg, EVP_PKEY *pkey); + +/* x509_rsa_pss_to_ctx sets |algor| to the signature algorithm parameters for + * |ctx|, which must have been configured for an RSA-PSS signing operation. It + * returns one on success and zero on error. */ +int x509_rsa_ctx_to_pss(EVP_MD_CTX *ctx, X509_ALGOR *algor); + +/* x509_print_rsa_pss_params prints a human-readable representation of RSA-PSS + * parameters in |sigalg| to |bp|. It returns one on success and zero on + * error. */ +int x509_print_rsa_pss_params(BIO *bp, const X509_ALGOR *sigalg, int indent, + ASN1_PCTX *pctx); + + +/* Signature algorithm functions. */ + +/* x509_digest_sign_algorithm encodes the signing parameters of |ctx| as an + * AlgorithmIdentifer and saves the result in |algor|. It returns one on + * success, or zero on error. */ +int x509_digest_sign_algorithm(EVP_MD_CTX *ctx, X509_ALGOR *algor); + +/* x509_digest_verify_init sets up |ctx| for a signature verification operation + * with public key |pkey| and parameters from |algor|. The |ctx| argument must + * have been initialised with |EVP_MD_CTX_init|. It returns one on success, or + * zero on error. */ +int x509_digest_verify_init(EVP_MD_CTX *ctx, X509_ALGOR *sigalg, + EVP_PKEY *pkey); + + +#if defined(__cplusplus) +} /* extern C */ +#endif + +#endif /* OPENSSL_HEADER_X509_INTERNAL_H */ diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/internal.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/internal.h.grpc_back new file mode 100644 index 0000000..4957c1e --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/internal.h.grpc_back @@ -0,0 +1,66 @@ +/* Copyright (c) 2016, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_X509_INTERNAL_H +#define OPENSSL_HEADER_X509_INTERNAL_H + +#include +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +/* RSA-PSS functions. */ + +/* x509_rsa_pss_to_ctx configures |ctx| for an RSA-PSS operation based on + * signature algorithm parameters in |sigalg| (which must have type + * |NID_rsassaPss|) and key |pkey|. It returns one on success and zero on + * error. */ +int x509_rsa_pss_to_ctx(EVP_MD_CTX *ctx, X509_ALGOR *sigalg, EVP_PKEY *pkey); + +/* x509_rsa_pss_to_ctx sets |algor| to the signature algorithm parameters for + * |ctx|, which must have been configured for an RSA-PSS signing operation. It + * returns one on success and zero on error. */ +int x509_rsa_ctx_to_pss(EVP_MD_CTX *ctx, X509_ALGOR *algor); + +/* x509_print_rsa_pss_params prints a human-readable representation of RSA-PSS + * parameters in |sigalg| to |bp|. It returns one on success and zero on + * error. */ +int x509_print_rsa_pss_params(BIO *bp, const X509_ALGOR *sigalg, int indent, + ASN1_PCTX *pctx); + + +/* Signature algorithm functions. */ + +/* x509_digest_sign_algorithm encodes the signing parameters of |ctx| as an + * AlgorithmIdentifer and saves the result in |algor|. It returns one on + * success, or zero on error. */ +int x509_digest_sign_algorithm(EVP_MD_CTX *ctx, X509_ALGOR *algor); + +/* x509_digest_verify_init sets up |ctx| for a signature verification operation + * with public key |pkey| and parameters from |algor|. The |ctx| argument must + * have been initialised with |EVP_MD_CTX_init|. It returns one on success, or + * zero on error. */ +int x509_digest_verify_init(EVP_MD_CTX *ctx, X509_ALGOR *sigalg, + EVP_PKEY *pkey); + + +#if defined(__cplusplus) +} /* extern C */ +#endif + +#endif /* OPENSSL_HEADER_X509_INTERNAL_H */ diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/rsa_pss.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/rsa_pss.c new file mode 100644 index 0000000..30ee781 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/rsa_pss.c @@ -0,0 +1,385 @@ +/* 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 +#include +#include +#include + +#include "internal.h" + + +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) + + +/* Given an MGF1 Algorithm ID decode to an Algorithm Identifier */ +static X509_ALGOR *rsa_mgf1_decode(X509_ALGOR *alg) { + if (alg == NULL || alg->parameter == NULL || + OBJ_obj2nid(alg->algorithm) != NID_mgf1 || + alg->parameter->type != V_ASN1_SEQUENCE) { + return NULL; + } + + const uint8_t *p = alg->parameter->value.sequence->data; + int 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) { + *pmaskHash = NULL; + + if (alg->parameter == NULL || alg->parameter->type != V_ASN1_SEQUENCE) { + return NULL; + } + + const uint8_t *p = alg->parameter->value.sequence->data; + int plen = alg->parameter->value.sequence->length; + RSA_PSS_PARAMS *pss = d2i_RSA_PSS_PARAMS(NULL, &p, plen); + if (pss == NULL) { + return NULL; + } + + *pmaskHash = rsa_mgf1_decode(pss->maskGenAlgorithm); + return pss; +} + +/* 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 == NULL) { + 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) || + !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: + ASN1_STRING_free(stmp); + 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) { + OPENSSL_PUT_ERROR(X509, X509_R_INVALID_PSS_PARAMETERS); + } + 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 || + maskHash == NULL) { + OPENSSL_PUT_ERROR(X509, X509_R_INVALID_PSS_PARAMETERS); + return NULL; + } + md = EVP_get_digestbyobj(maskHash->algorithm); + if (md == NULL) { + OPENSSL_PUT_ERROR(X509, X509_R_INVALID_PSS_PARAMETERS); + return NULL; + } + return md; +} + +int x509_rsa_ctx_to_pss(EVP_MD_CTX *ctx, X509_ALGOR *algor) { + const EVP_MD *sigmd, *mgf1md; + int saltlen; + if (!EVP_PKEY_CTX_get_signature_md(ctx->pctx, &sigmd) || + !EVP_PKEY_CTX_get_rsa_mgf1_md(ctx->pctx, &mgf1md) || + !EVP_PKEY_CTX_get_rsa_pss_saltlen(ctx->pctx, &saltlen)) { + return 0; + } + + EVP_PKEY *pk = EVP_PKEY_CTX_get0_pkey(ctx->pctx); + 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--; + } + } else { + return 0; + } + + int ret = 0; + ASN1_STRING *os = NULL; + RSA_PSS_PARAMS *pss = RSA_PSS_PARAMS_new(); + if (!pss) { + goto err; + } + + if (saltlen != 20) { + pss->saltLength = ASN1_INTEGER_new(); + if (!pss->saltLength || + !ASN1_INTEGER_set(pss->saltLength, saltlen)) { + goto err; + } + } + + if (!rsa_md_to_algor(&pss->hashAlgorithm, sigmd) || + !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; + } + + X509_ALGOR_set0(algor, OBJ_nid2obj(NID_rsassaPss), V_ASN1_SEQUENCE, os); + os = NULL; + ret = 1; + +err: + RSA_PSS_PARAMS_free(pss); + ASN1_STRING_free(os); + return ret; +} + +int x509_rsa_pss_to_ctx(EVP_MD_CTX *ctx, X509_ALGOR *sigalg, EVP_PKEY *pkey) { + assert(OBJ_obj2nid(sigalg->algorithm) == NID_rsassaPss); + + /* Decode PSS parameters */ + int ret = 0; + X509_ALGOR *maskHash; + RSA_PSS_PARAMS *pss = rsa_pss_decode(sigalg, &maskHash); + if (pss == NULL) { + OPENSSL_PUT_ERROR(X509, X509_R_INVALID_PSS_PARAMETERS); + goto err; + } + + const EVP_MD *mgf1md = rsa_mgf1_to_md(pss->maskGenAlgorithm, maskHash); + const EVP_MD *md = rsa_algor_to_md(pss->hashAlgorithm); + if (mgf1md == NULL || md == NULL) { + goto err; + } + + int saltlen = 20; + if (pss->saltLength != NULL) { + 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) { + OPENSSL_PUT_ERROR(X509, X509_R_INVALID_PSS_PARAMETERS); + goto err; + } + } + + /* low-level routines support only trailer field 0xbc (value 1) + * and PKCS#1 says we should reject any other value anyway. */ + if (pss->trailerField != NULL && ASN1_INTEGER_get(pss->trailerField) != 1) { + OPENSSL_PUT_ERROR(X509, X509_R_INVALID_PSS_PARAMETERS); + goto err; + } + + EVP_PKEY_CTX *pctx; + if (!EVP_DigestVerifyInit(ctx, &pctx, md, NULL, pkey) || + !EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PSS_PADDING) || + !EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, saltlen) || + !EVP_PKEY_CTX_set_rsa_mgf1_md(pctx, mgf1md)) { + goto err; + } + + ret = 1; + +err: + RSA_PSS_PARAMS_free(pss); + X509_ALGOR_free(maskHash); + return ret; +} + +int x509_print_rsa_pss_params(BIO *bp, const X509_ALGOR *sigalg, int indent, + ASN1_PCTX *pctx) { + assert(OBJ_obj2nid(sigalg->algorithm) == NID_rsassaPss); + + int rv = 0; + X509_ALGOR *maskHash; + RSA_PSS_PARAMS *pss = rsa_pss_decode(sigalg, &maskHash); + if (!pss) { + if (BIO_puts(bp, " (INVALID PSS PARAMETERS)\n") <= 0) { + goto err; + } + rv = 1; + goto err; + } + + if (BIO_puts(bp, "\n") <= 0 || + !BIO_indent(bp, indent, 128) || + 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 || + !BIO_indent(bp, indent, 128) || + BIO_puts(bp, "Mask Algorithm: ") <= 0) { + goto err; + } + + if (pss->maskGenAlgorithm) { + if (i2a_ASN1_OBJECT(bp, pss->maskGenAlgorithm->algorithm) <= 0 || + 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) || + 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) || + 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: + RSA_PSS_PARAMS_free(pss); + X509_ALGOR_free(maskHash); + return rv; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/rsa_pss.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/rsa_pss.c.grpc_back new file mode 100644 index 0000000..9230934 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/rsa_pss.c.grpc_back @@ -0,0 +1,385 @@ +/* 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 +#include +#include +#include + +#include "internal.h" + + +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) + + +/* Given an MGF1 Algorithm ID decode to an Algorithm Identifier */ +static X509_ALGOR *rsa_mgf1_decode(X509_ALGOR *alg) { + if (alg == NULL || alg->parameter == NULL || + OBJ_obj2nid(alg->algorithm) != NID_mgf1 || + alg->parameter->type != V_ASN1_SEQUENCE) { + return NULL; + } + + const uint8_t *p = alg->parameter->value.sequence->data; + int 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) { + *pmaskHash = NULL; + + if (alg->parameter == NULL || alg->parameter->type != V_ASN1_SEQUENCE) { + return NULL; + } + + const uint8_t *p = alg->parameter->value.sequence->data; + int plen = alg->parameter->value.sequence->length; + RSA_PSS_PARAMS *pss = d2i_RSA_PSS_PARAMS(NULL, &p, plen); + if (pss == NULL) { + return NULL; + } + + *pmaskHash = rsa_mgf1_decode(pss->maskGenAlgorithm); + return pss; +} + +/* 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 == NULL) { + 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) || + !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: + ASN1_STRING_free(stmp); + 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) { + OPENSSL_PUT_ERROR(X509, X509_R_INVALID_PSS_PARAMETERS); + } + 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 || + maskHash == NULL) { + OPENSSL_PUT_ERROR(X509, X509_R_INVALID_PSS_PARAMETERS); + return NULL; + } + md = EVP_get_digestbyobj(maskHash->algorithm); + if (md == NULL) { + OPENSSL_PUT_ERROR(X509, X509_R_INVALID_PSS_PARAMETERS); + return NULL; + } + return md; +} + +int x509_rsa_ctx_to_pss(EVP_MD_CTX *ctx, X509_ALGOR *algor) { + const EVP_MD *sigmd, *mgf1md; + int saltlen; + if (!EVP_PKEY_CTX_get_signature_md(ctx->pctx, &sigmd) || + !EVP_PKEY_CTX_get_rsa_mgf1_md(ctx->pctx, &mgf1md) || + !EVP_PKEY_CTX_get_rsa_pss_saltlen(ctx->pctx, &saltlen)) { + return 0; + } + + EVP_PKEY *pk = EVP_PKEY_CTX_get0_pkey(ctx->pctx); + 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--; + } + } else { + return 0; + } + + int ret = 0; + ASN1_STRING *os = NULL; + RSA_PSS_PARAMS *pss = RSA_PSS_PARAMS_new(); + if (!pss) { + goto err; + } + + if (saltlen != 20) { + pss->saltLength = ASN1_INTEGER_new(); + if (!pss->saltLength || + !ASN1_INTEGER_set(pss->saltLength, saltlen)) { + goto err; + } + } + + if (!rsa_md_to_algor(&pss->hashAlgorithm, sigmd) || + !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; + } + + X509_ALGOR_set0(algor, OBJ_nid2obj(NID_rsassaPss), V_ASN1_SEQUENCE, os); + os = NULL; + ret = 1; + +err: + RSA_PSS_PARAMS_free(pss); + ASN1_STRING_free(os); + return ret; +} + +int x509_rsa_pss_to_ctx(EVP_MD_CTX *ctx, X509_ALGOR *sigalg, EVP_PKEY *pkey) { + assert(OBJ_obj2nid(sigalg->algorithm) == NID_rsassaPss); + + /* Decode PSS parameters */ + int ret = 0; + X509_ALGOR *maskHash; + RSA_PSS_PARAMS *pss = rsa_pss_decode(sigalg, &maskHash); + if (pss == NULL) { + OPENSSL_PUT_ERROR(X509, X509_R_INVALID_PSS_PARAMETERS); + goto err; + } + + const EVP_MD *mgf1md = rsa_mgf1_to_md(pss->maskGenAlgorithm, maskHash); + const EVP_MD *md = rsa_algor_to_md(pss->hashAlgorithm); + if (mgf1md == NULL || md == NULL) { + goto err; + } + + int saltlen = 20; + if (pss->saltLength != NULL) { + 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) { + OPENSSL_PUT_ERROR(X509, X509_R_INVALID_PSS_PARAMETERS); + goto err; + } + } + + /* low-level routines support only trailer field 0xbc (value 1) + * and PKCS#1 says we should reject any other value anyway. */ + if (pss->trailerField != NULL && ASN1_INTEGER_get(pss->trailerField) != 1) { + OPENSSL_PUT_ERROR(X509, X509_R_INVALID_PSS_PARAMETERS); + goto err; + } + + EVP_PKEY_CTX *pctx; + if (!EVP_DigestVerifyInit(ctx, &pctx, md, NULL, pkey) || + !EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PSS_PADDING) || + !EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, saltlen) || + !EVP_PKEY_CTX_set_rsa_mgf1_md(pctx, mgf1md)) { + goto err; + } + + ret = 1; + +err: + RSA_PSS_PARAMS_free(pss); + X509_ALGOR_free(maskHash); + return ret; +} + +int x509_print_rsa_pss_params(BIO *bp, const X509_ALGOR *sigalg, int indent, + ASN1_PCTX *pctx) { + assert(OBJ_obj2nid(sigalg->algorithm) == NID_rsassaPss); + + int rv = 0; + X509_ALGOR *maskHash; + RSA_PSS_PARAMS *pss = rsa_pss_decode(sigalg, &maskHash); + if (!pss) { + if (BIO_puts(bp, " (INVALID PSS PARAMETERS)\n") <= 0) { + goto err; + } + rv = 1; + goto err; + } + + if (BIO_puts(bp, "\n") <= 0 || + !BIO_indent(bp, indent, 128) || + 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 || + !BIO_indent(bp, indent, 128) || + BIO_puts(bp, "Mask Algorithm: ") <= 0) { + goto err; + } + + if (pss->maskGenAlgorithm) { + if (i2a_ASN1_OBJECT(bp, pss->maskGenAlgorithm->algorithm) <= 0 || + 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) || + 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) || + 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: + RSA_PSS_PARAMS_free(pss); + X509_ALGOR_free(maskHash); + return rv; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/t_crl.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/t_crl.c new file mode 100644 index 0000000..305ef40 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/t_crl.c @@ -0,0 +1,128 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 +#include + +#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) { + OPENSSL_PUT_ERROR(X509, 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; + size_t 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); + 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; + +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/t_crl.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/t_crl.c.grpc_back new file mode 100644 index 0000000..6c347cb --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/t_crl.c.grpc_back @@ -0,0 +1,128 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 +#include + +#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) { + OPENSSL_PUT_ERROR(X509, 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; + size_t 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); + 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; + +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/t_req.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/t_req.c new file mode 100644 index 0000000..e17fca5 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/t_req.c @@ -0,0 +1,246 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 +#include +#include + + +int X509_REQ_print_fp(FILE *fp, X509_REQ *x) { + BIO *bio = BIO_new(BIO_s_file()); + if (bio == NULL) { + OPENSSL_PUT_ERROR(X509, ERR_R_BUF_LIB); + return 0; + } + + BIO_set_fp(bio, fp, BIO_NOCLOSE); + int ret = X509_REQ_print(bio, x); + BIO_free(bio); + return ret; +} + +int X509_REQ_print_ex(BIO *bio, X509_REQ *x, unsigned long nmflags, + unsigned long cflag) { + long l; + EVP_PKEY *pkey; + STACK_OF(X509_ATTRIBUTE) * sk; + 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; + } + + X509_REQ_INFO *ri = x->req_info; + if (!(cflag & X509_FLAG_NO_HEADER)) { + if (BIO_write(bio, "Certificate Request:\n", 21) <= 0 || + BIO_write(bio, " Data:\n", 10) <= 0) { + goto err; + } + } + if (!(cflag & X509_FLAG_NO_VERSION)) { + l = X509_REQ_get_version(x); + if (BIO_printf(bio, "%8sVersion: %ld (0x%lx)\n", "", l + 1, l) <= 0) { + goto err; + } + } + if (!(cflag & X509_FLAG_NO_SUBJECT)) { + if (BIO_printf(bio, " Subject:%c", mlch) <= 0 || + X509_NAME_print_ex(bio, ri->subject, nmindent, nmflags) < 0 || + BIO_write(bio, "\n", 1) <= 0) { + goto err; + } + } + if (!(cflag & X509_FLAG_NO_PUBKEY)) { + if (BIO_write(bio, " Subject Public Key Info:\n", 33) <= 0 || + BIO_printf(bio, "%12sPublic Key Algorithm: ", "") <= 0 || + i2a_ASN1_OBJECT(bio, ri->pubkey->algor->algorithm) <= 0 || + BIO_puts(bio, "\n") <= 0) { + goto err; + } + + pkey = X509_REQ_get_pubkey(x); + if (pkey == NULL) { + BIO_printf(bio, "%12sUnable to load Public Key\n", ""); + ERR_print_errors(bio); + } else { + EVP_PKEY_print_public(bio, pkey, 16, NULL); + EVP_PKEY_free(pkey); + } + } + + if (!(cflag & X509_FLAG_NO_ATTRIBUTES)) { + if (BIO_printf(bio, "%8sAttributes:\n", "") <= 0) { + goto err; + } + + sk = x->req_info->attributes; + if (sk_X509_ATTRIBUTE_num(sk) == 0) { + if (BIO_printf(bio, "%12sa0:00\n", "") <= 0) { + goto err; + } + } else { + size_t i; + for (i = 0; i < sk_X509_ATTRIBUTE_num(sk); i++) { + X509_ATTRIBUTE *a = sk_X509_ATTRIBUTE_value(sk, i); + ASN1_OBJECT *aobj = X509_ATTRIBUTE_get0_object(a); + + if (X509_REQ_extension_nid(OBJ_obj2nid(aobj))) { + continue; + } + + if (BIO_printf(bio, "%12s", "") <= 0) { + goto err; + } + + const int num_attrs = X509_ATTRIBUTE_count(a); + const int obj_str_len = i2a_ASN1_OBJECT(bio, aobj); + if (obj_str_len <= 0) { + if (BIO_puts(bio, "(Unable to print attribute ID.)\n") < 0) { + goto err; + } else { + continue; + } + } + + int j; + for (j = 0; j < num_attrs; j++) { + const ASN1_TYPE *at = X509_ATTRIBUTE_get0_type(a, j); + const int type = at->type; + ASN1_BIT_STRING *bs = at->value.asn1_string; + + int k; + for (k = 25 - obj_str_len; k > 0; k--) { + if (BIO_write(bio, " ", 1) != 1) { + goto err; + } + } + + if (BIO_puts(bio, ":") <= 0) { + goto err; + } + + if (type == V_ASN1_PRINTABLESTRING || + type == V_ASN1_UTF8STRING || + type == V_ASN1_IA5STRING || + type == V_ASN1_T61STRING) { + if (BIO_write(bio, (char *)bs->data, bs->length) != bs->length) { + goto err; + } + BIO_puts(bio, "\n"); + } else { + BIO_puts(bio, "unable to print attribute\n"); + } + } + } + } + } + + if (!(cflag & X509_FLAG_NO_EXTENSIONS)) { + STACK_OF(X509_EXTENSION) *exts = X509_REQ_get_extensions(x); + if (exts) { + BIO_printf(bio, "%8sRequested Extensions:\n", ""); + + size_t i; + for (i = 0; i < sk_X509_EXTENSION_num(exts); i++) { + X509_EXTENSION *ex = sk_X509_EXTENSION_value(exts, i); + if (BIO_printf(bio, "%12s", "") <= 0) { + goto err; + } + ASN1_OBJECT *obj = X509_EXTENSION_get_object(ex); + i2a_ASN1_OBJECT(bio, obj); + const int is_critical = X509_EXTENSION_get_critical(ex); + if (BIO_printf(bio, ": %s\n", is_critical ? "critical" : "") <= 0) { + goto err; + } + if (!X509V3_EXT_print(bio, ex, cflag, 16)) { + BIO_printf(bio, "%16s", ""); + ASN1_STRING_print(bio, X509_EXTENSION_get_data(ex)); + } + if (BIO_write(bio, "\n", 1) <= 0) { + goto err; + } + } + sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free); + } + } + + if (!(cflag & X509_FLAG_NO_SIGDUMP) && + !X509_signature_print(bio, x->sig_alg, x->signature)) { + goto err; + } + + return 1; + +err: + OPENSSL_PUT_ERROR(X509, ERR_R_BUF_LIB); + return 0; +} + +int X509_REQ_print(BIO *bio, X509_REQ *req) { + return X509_REQ_print_ex(bio, req, XN_FLAG_COMPAT, X509_FLAG_COMPAT); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/t_req.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/t_req.c.grpc_back new file mode 100644 index 0000000..39c836c --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/t_req.c.grpc_back @@ -0,0 +1,246 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 +#include +#include + + +int X509_REQ_print_fp(FILE *fp, X509_REQ *x) { + BIO *bio = BIO_new(BIO_s_file()); + if (bio == NULL) { + OPENSSL_PUT_ERROR(X509, ERR_R_BUF_LIB); + return 0; + } + + BIO_set_fp(bio, fp, BIO_NOCLOSE); + int ret = X509_REQ_print(bio, x); + BIO_free(bio); + return ret; +} + +int X509_REQ_print_ex(BIO *bio, X509_REQ *x, unsigned long nmflags, + unsigned long cflag) { + long l; + EVP_PKEY *pkey; + STACK_OF(X509_ATTRIBUTE) * sk; + 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; + } + + X509_REQ_INFO *ri = x->req_info; + if (!(cflag & X509_FLAG_NO_HEADER)) { + if (BIO_write(bio, "Certificate Request:\n", 21) <= 0 || + BIO_write(bio, " Data:\n", 10) <= 0) { + goto err; + } + } + if (!(cflag & X509_FLAG_NO_VERSION)) { + l = X509_REQ_get_version(x); + if (BIO_printf(bio, "%8sVersion: %ld (0x%lx)\n", "", l + 1, l) <= 0) { + goto err; + } + } + if (!(cflag & X509_FLAG_NO_SUBJECT)) { + if (BIO_printf(bio, " Subject:%c", mlch) <= 0 || + X509_NAME_print_ex(bio, ri->subject, nmindent, nmflags) < 0 || + BIO_write(bio, "\n", 1) <= 0) { + goto err; + } + } + if (!(cflag & X509_FLAG_NO_PUBKEY)) { + if (BIO_write(bio, " Subject Public Key Info:\n", 33) <= 0 || + BIO_printf(bio, "%12sPublic Key Algorithm: ", "") <= 0 || + i2a_ASN1_OBJECT(bio, ri->pubkey->algor->algorithm) <= 0 || + BIO_puts(bio, "\n") <= 0) { + goto err; + } + + pkey = X509_REQ_get_pubkey(x); + if (pkey == NULL) { + BIO_printf(bio, "%12sUnable to load Public Key\n", ""); + ERR_print_errors(bio); + } else { + EVP_PKEY_print_public(bio, pkey, 16, NULL); + EVP_PKEY_free(pkey); + } + } + + if (!(cflag & X509_FLAG_NO_ATTRIBUTES)) { + if (BIO_printf(bio, "%8sAttributes:\n", "") <= 0) { + goto err; + } + + sk = x->req_info->attributes; + if (sk_X509_ATTRIBUTE_num(sk) == 0) { + if (BIO_printf(bio, "%12sa0:00\n", "") <= 0) { + goto err; + } + } else { + size_t i; + for (i = 0; i < sk_X509_ATTRIBUTE_num(sk); i++) { + X509_ATTRIBUTE *a = sk_X509_ATTRIBUTE_value(sk, i); + ASN1_OBJECT *aobj = X509_ATTRIBUTE_get0_object(a); + + if (X509_REQ_extension_nid(OBJ_obj2nid(aobj))) { + continue; + } + + if (BIO_printf(bio, "%12s", "") <= 0) { + goto err; + } + + const int num_attrs = X509_ATTRIBUTE_count(a); + const int obj_str_len = i2a_ASN1_OBJECT(bio, aobj); + if (obj_str_len <= 0) { + if (BIO_puts(bio, "(Unable to print attribute ID.)\n") < 0) { + goto err; + } else { + continue; + } + } + + int j; + for (j = 0; j < num_attrs; j++) { + const ASN1_TYPE *at = X509_ATTRIBUTE_get0_type(a, j); + const int type = at->type; + ASN1_BIT_STRING *bs = at->value.asn1_string; + + int k; + for (k = 25 - obj_str_len; k > 0; k--) { + if (BIO_write(bio, " ", 1) != 1) { + goto err; + } + } + + if (BIO_puts(bio, ":") <= 0) { + goto err; + } + + if (type == V_ASN1_PRINTABLESTRING || + type == V_ASN1_UTF8STRING || + type == V_ASN1_IA5STRING || + type == V_ASN1_T61STRING) { + if (BIO_write(bio, (char *)bs->data, bs->length) != bs->length) { + goto err; + } + BIO_puts(bio, "\n"); + } else { + BIO_puts(bio, "unable to print attribute\n"); + } + } + } + } + } + + if (!(cflag & X509_FLAG_NO_EXTENSIONS)) { + STACK_OF(X509_EXTENSION) *exts = X509_REQ_get_extensions(x); + if (exts) { + BIO_printf(bio, "%8sRequested Extensions:\n", ""); + + size_t i; + for (i = 0; i < sk_X509_EXTENSION_num(exts); i++) { + X509_EXTENSION *ex = sk_X509_EXTENSION_value(exts, i); + if (BIO_printf(bio, "%12s", "") <= 0) { + goto err; + } + ASN1_OBJECT *obj = X509_EXTENSION_get_object(ex); + i2a_ASN1_OBJECT(bio, obj); + const int is_critical = X509_EXTENSION_get_critical(ex); + if (BIO_printf(bio, ": %s\n", is_critical ? "critical" : "") <= 0) { + goto err; + } + if (!X509V3_EXT_print(bio, ex, cflag, 16)) { + BIO_printf(bio, "%16s", ""); + ASN1_STRING_print(bio, X509_EXTENSION_get_data(ex)); + } + if (BIO_write(bio, "\n", 1) <= 0) { + goto err; + } + } + sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free); + } + } + + if (!(cflag & X509_FLAG_NO_SIGDUMP) && + !X509_signature_print(bio, x->sig_alg, x->signature)) { + goto err; + } + + return 1; + +err: + OPENSSL_PUT_ERROR(X509, ERR_R_BUF_LIB); + return 0; +} + +int X509_REQ_print(BIO *bio, X509_REQ *req) { + return X509_REQ_print_ex(bio, req, XN_FLAG_COMPAT, X509_FLAG_COMPAT); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/t_x509.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/t_x509.c new file mode 100644 index 0000000..cc99971 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/t_x509.c @@ -0,0 +1,547 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 +#include +#include +#include +#include +#include + +#include "internal.h" + + +#ifndef OPENSSL_NO_FP_API +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) { + OPENSSL_PUT_ERROR(X509, 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); +} + +int X509_print_fp(FILE *fp, X509 *x) +{ + return X509_print_ex_fp(fp, x, XN_FLAG_COMPAT, X509_FLAG_COMPAT); +} +#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 (!(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_print(BIO *bp, const X509_ALGOR *sigalg, + const ASN1_STRING *sig) +{ + if (BIO_puts(bp, " Signature Algorithm: ") <= 0) + return 0; + if (i2a_ASN1_OBJECT(bp, sigalg->algorithm) <= 0) + return 0; + + /* RSA-PSS signatures have parameters to print. */ + int sig_nid = OBJ_obj2nid(sigalg->algorithm); + if (sig_nid == NID_rsassaPss && + !x509_print_rsa_pss_params(bp, sigalg, 9, 0)) { + return 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 *const 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); +} + +// consume_two_digits is a helper function for ASN1_UTCTIME_print. If |*v|, +// assumed to be |*len| bytes long, has two leading digits, updates |*out| with +// their value, updates |v| and |len|, and returns one. Otherwise, returns +// zero. +static int consume_two_digits(int* out, const char **v, int *len) { + if (*len < 2|| !isdigit((*v)[0]) || !isdigit((*v)[1])) { + return 0; + } + *out = ((*v)[0] - '0') * 10 + ((*v)[1] - '0'); + *len -= 2; + *v += 2; + return 1; +} + +// consume_zulu_timezone is a helper function for ASN1_UTCTIME_print. If |*v|, +// assumed to be |*len| bytes long, starts with "Z" then it updates |*v| and +// |*len| and returns one. Otherwise returns zero. +static int consume_zulu_timezone(const char **v, int *len) { + if (*len == 0 || (*v)[0] != 'Z') { + return 0; + } + + *len -= 1; + *v += 1; + return 1; +} + +int ASN1_UTCTIME_print(BIO *bp, const ASN1_UTCTIME *tm) { + const char *v = (const char *)tm->data; + int len = tm->length; + int Y = 0, M = 0, D = 0, h = 0, m = 0, s = 0; + + // YYMMDDhhmm are required to be present. + if (!consume_two_digits(&Y, &v, &len) || + !consume_two_digits(&M, &v, &len) || + !consume_two_digits(&D, &v, &len) || + !consume_two_digits(&h, &v, &len) || + !consume_two_digits(&m, &v, &len)) { + goto err; + } + // https://tools.ietf.org/html/rfc5280, section 4.1.2.5.1, requires seconds + // to be present, but historically this code has forgiven its absence. + consume_two_digits(&s, &v, &len); + + // https://tools.ietf.org/html/rfc5280, section 4.1.2.5.1, specifies this + // interpretation of the year. + if (Y < 50) { + Y += 2000; + } else { + Y += 1900; + } + if (M > 12 || M == 0) { + goto err; + } + if (D > 31 || D == 0) { + goto err; + } + if (h > 23 || m > 59 || s > 60) { + goto err; + } + + // https://tools.ietf.org/html/rfc5280, section 4.1.2.5.1, requires the "Z" + // to be present, but historically this code has forgiven its absence. + const int is_gmt = consume_zulu_timezone(&v, &len); + + // https://tools.ietf.org/html/rfc5280, section 4.1.2.5.1, does not permit + // the specification of timezones using the +hhmm / -hhmm syntax, which is + // the only other thing that might legitimately be found at the end. + if (len) { + goto err; + } + + return BIO_printf(bp, "%s %2d %02d:%02d:%02d %d%s", mon[M - 1], D, h, m, s, Y, + is_gmt ? " GMT" : "") > 0; + +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 (;;) { + if (((*s == '/') && + ((s[1] >= 'A') && (s[1] <= 'Z') && ((s[2] == '=') || + ((s[2] >= 'A') + && (s[2] <= 'Z') + && (s[3] == '=')) + ))) || (*s == '\0')) { + 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: + OPENSSL_PUT_ERROR(X509, ERR_R_BUF_LIB); + } + OPENSSL_free(b); + return (ret); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/t_x509.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/t_x509.c.grpc_back new file mode 100644 index 0000000..3339523 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/t_x509.c.grpc_back @@ -0,0 +1,547 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 +#include +#include +#include +#include +#include + +#include "internal.h" + + +#ifndef OPENSSL_NO_FP_API +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) { + OPENSSL_PUT_ERROR(X509, 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); +} + +int X509_print_fp(FILE *fp, X509 *x) +{ + return X509_print_ex_fp(fp, x, XN_FLAG_COMPAT, X509_FLAG_COMPAT); +} +#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 (!(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_print(BIO *bp, const X509_ALGOR *sigalg, + const ASN1_STRING *sig) +{ + if (BIO_puts(bp, " Signature Algorithm: ") <= 0) + return 0; + if (i2a_ASN1_OBJECT(bp, sigalg->algorithm) <= 0) + return 0; + + /* RSA-PSS signatures have parameters to print. */ + int sig_nid = OBJ_obj2nid(sigalg->algorithm); + if (sig_nid == NID_rsassaPss && + !x509_print_rsa_pss_params(bp, sigalg, 9, 0)) { + return 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 *const 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); +} + +// consume_two_digits is a helper function for ASN1_UTCTIME_print. If |*v|, +// assumed to be |*len| bytes long, has two leading digits, updates |*out| with +// their value, updates |v| and |len|, and returns one. Otherwise, returns +// zero. +static int consume_two_digits(int* out, const char **v, int *len) { + if (*len < 2|| !isdigit((*v)[0]) || !isdigit((*v)[1])) { + return 0; + } + *out = ((*v)[0] - '0') * 10 + ((*v)[1] - '0'); + *len -= 2; + *v += 2; + return 1; +} + +// consume_zulu_timezone is a helper function for ASN1_UTCTIME_print. If |*v|, +// assumed to be |*len| bytes long, starts with "Z" then it updates |*v| and +// |*len| and returns one. Otherwise returns zero. +static int consume_zulu_timezone(const char **v, int *len) { + if (*len == 0 || (*v)[0] != 'Z') { + return 0; + } + + *len -= 1; + *v += 1; + return 1; +} + +int ASN1_UTCTIME_print(BIO *bp, const ASN1_UTCTIME *tm) { + const char *v = (const char *)tm->data; + int len = tm->length; + int Y = 0, M = 0, D = 0, h = 0, m = 0, s = 0; + + // YYMMDDhhmm are required to be present. + if (!consume_two_digits(&Y, &v, &len) || + !consume_two_digits(&M, &v, &len) || + !consume_two_digits(&D, &v, &len) || + !consume_two_digits(&h, &v, &len) || + !consume_two_digits(&m, &v, &len)) { + goto err; + } + // https://tools.ietf.org/html/rfc5280, section 4.1.2.5.1, requires seconds + // to be present, but historically this code has forgiven its absence. + consume_two_digits(&s, &v, &len); + + // https://tools.ietf.org/html/rfc5280, section 4.1.2.5.1, specifies this + // interpretation of the year. + if (Y < 50) { + Y += 2000; + } else { + Y += 1900; + } + if (M > 12 || M == 0) { + goto err; + } + if (D > 31 || D == 0) { + goto err; + } + if (h > 23 || m > 59 || s > 60) { + goto err; + } + + // https://tools.ietf.org/html/rfc5280, section 4.1.2.5.1, requires the "Z" + // to be present, but historically this code has forgiven its absence. + const int is_gmt = consume_zulu_timezone(&v, &len); + + // https://tools.ietf.org/html/rfc5280, section 4.1.2.5.1, does not permit + // the specification of timezones using the +hhmm / -hhmm syntax, which is + // the only other thing that might legitimately be found at the end. + if (len) { + goto err; + } + + return BIO_printf(bp, "%s %2d %02d:%02d:%02d %d%s", mon[M - 1], D, h, m, s, Y, + is_gmt ? " GMT" : "") > 0; + +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 (;;) { + if (((*s == '/') && + ((s[1] >= 'A') && (s[1] <= 'Z') && ((s[2] == '=') || + ((s[2] >= 'A') + && (s[2] <= 'Z') + && (s[3] == '=')) + ))) || (*s == '\0')) { + 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: + OPENSSL_PUT_ERROR(X509, ERR_R_BUF_LIB); + } + OPENSSL_free(b); + return (ret); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/t_x509a.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/t_x509a.c new file mode 100644 index 0000000..89d7fce --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/t_x509a.c @@ -0,0 +1,111 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 + +/* X509_CERT_AUX and string set routines */ + +int X509_CERT_AUX_print(BIO *out, X509_CERT_AUX *aux, int indent) +{ + char oidstr[80], first; + size_t i; + int j; + 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 (j = 0; j < aux->keyid->length; j++) + BIO_printf(out, "%s%02X", j ? ":" : "", aux->keyid->data[j]); + BIO_write(out, "\n", 1); + } + return 1; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/t_x509a.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/t_x509a.c.grpc_back new file mode 100644 index 0000000..5436828 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/t_x509a.c.grpc_back @@ -0,0 +1,111 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 + +/* X509_CERT_AUX and string set routines */ + +int X509_CERT_AUX_print(BIO *out, X509_CERT_AUX *aux, int indent) +{ + char oidstr[80], first; + size_t i; + int j; + 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 (j = 0; j < aux->keyid->length; j++) + BIO_printf(out, "%s%02X", j ? ":" : "", aux->keyid->data[j]); + BIO_write(out, "\n", 1); + } + return 1; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/vpm_int.h b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/vpm_int.h new file mode 100644 index 0000000..53b4a0d --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/vpm_int.h @@ -0,0 +1,71 @@ +/* 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 */ + unsigned char poison; /* Fail all verifications */ +}; diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/vpm_int.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/vpm_int.h.grpc_back new file mode 100644 index 0000000..53b4a0d --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/vpm_int.h.grpc_back @@ -0,0 +1,71 @@ +/* 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 */ + unsigned char poison; /* Fail all verifications */ +}; diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509.c new file mode 100644 index 0000000..fd217c9 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509.c @@ -0,0 +1,157 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 + + +/* |X509_R_UNSUPPORTED_ALGORITHM| is no longer emitted, but continue to define + * it to avoid downstream churn. */ +OPENSSL_DECLARE_ERROR_REASON(X509, UNSUPPORTED_ALGORITHM) + +int PKCS8_pkey_set0(PKCS8_PRIV_KEY_INFO *priv, ASN1_OBJECT *aobj, int version, + int ptype, void *pval, uint8_t *penc, int penclen) { + uint8_t **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 uint8_t **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; +} + +int X509_signature_dump(BIO *bp, const ASN1_STRING *sig, int indent) { + const uint8_t *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 || + 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; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509.c.grpc_back new file mode 100644 index 0000000..188fd49 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509.c.grpc_back @@ -0,0 +1,157 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 + + +/* |X509_R_UNSUPPORTED_ALGORITHM| is no longer emitted, but continue to define + * it to avoid downstream churn. */ +OPENSSL_DECLARE_ERROR_REASON(X509, UNSUPPORTED_ALGORITHM) + +int PKCS8_pkey_set0(PKCS8_PRIV_KEY_INFO *priv, ASN1_OBJECT *aobj, int version, + int ptype, void *pval, uint8_t *penc, int penclen) { + uint8_t **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 uint8_t **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; +} + +int X509_signature_dump(BIO *bp, const ASN1_STRING *sig, int indent) { + const uint8_t *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 || + 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; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509_att.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509_att.c new file mode 100644 index 0000000..9b5ee59 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509_att.c @@ -0,0 +1,381 @@ +/* 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 +#include +#include +#include +#include + +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) +{ + const 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, + const 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 || loc < 0 || sk_X509_ATTRIBUTE_num(x) <= (size_t)loc) + 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 || loc < 0 || sk_X509_ATTRIBUTE_num(x) <= (size_t)loc) + 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) { + OPENSSL_PUT_ERROR(X509, 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: + OPENSSL_PUT_ERROR(X509, 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) +{ + const ASN1_OBJECT *obj; + + obj = OBJ_nid2obj(nid); + if (obj == NULL) { + OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_NID); + return (NULL); + } + return X509_ATTRIBUTE_create_by_OBJ(attr, obj, atrtype, data, len); +} + +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) { + OPENSSL_PUT_ERROR(X509, 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) { + OPENSSL_PUT_ERROR(X509, 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 attr->object != NULL; +} + +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) { + OPENSSL_PUT_ERROR(X509, 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: + OPENSSL_PUT_ERROR(X509, 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)) { + OPENSSL_PUT_ERROR(X509, 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; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509_att.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509_att.c.grpc_back new file mode 100644 index 0000000..85d65e7 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509_att.c.grpc_back @@ -0,0 +1,381 @@ +/* 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 +#include +#include +#include +#include + +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) +{ + const 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, + const 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 || loc < 0 || sk_X509_ATTRIBUTE_num(x) <= (size_t)loc) + 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 || loc < 0 || sk_X509_ATTRIBUTE_num(x) <= (size_t)loc) + 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) { + OPENSSL_PUT_ERROR(X509, 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: + OPENSSL_PUT_ERROR(X509, 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) +{ + const ASN1_OBJECT *obj; + + obj = OBJ_nid2obj(nid); + if (obj == NULL) { + OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_NID); + return (NULL); + } + return X509_ATTRIBUTE_create_by_OBJ(attr, obj, atrtype, data, len); +} + +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) { + OPENSSL_PUT_ERROR(X509, 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) { + OPENSSL_PUT_ERROR(X509, 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 attr->object != NULL; +} + +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) { + OPENSSL_PUT_ERROR(X509, 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: + OPENSSL_PUT_ERROR(X509, 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)) { + OPENSSL_PUT_ERROR(X509, 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; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509_cmp.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509_cmp.c new file mode 100644 index 0000000..81fb6fd --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509_cmp.c @@ -0,0 +1,477 @@ +/* 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 +#include +#include +#include +#include +#include +#include +#include + +#include "../internal.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)); +} + +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); +} + +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)); +} + +int X509_CRL_match(const X509_CRL *a, const X509_CRL *b) +{ + return OPENSSL_memcmp(a->sha1_hash, b->sha1_hash, 20); +} + +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)); +} + +unsigned long X509_issuer_name_hash_old(X509 *x) +{ + return (X509_NAME_hash_old(x->cert_info->issuer)); +} + +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)); +} + +unsigned long X509_subject_name_hash_old(X509 *x) +{ + return (X509_NAME_hash_old(x->cert_info->subject)); +} + +/* + * 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 = OPENSSL_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 OPENSSL_memcmp(a->cert_info->enc.enc, b->cert_info->enc.enc, + a->cert_info->enc.len); + } + return rv; +} + +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) + return ret; + + return OPENSSL_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); +} + +/* + * 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); +} + +/* 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) +{ + size_t 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; + size_t 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: + OPENSSL_PUT_ERROR(X509, X509_R_KEY_VALUES_MISMATCH); + break; + case -1: + OPENSSL_PUT_ERROR(X509, X509_R_KEY_TYPE_MISMATCH); + break; + case -2: + OPENSSL_PUT_ERROR(X509, 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. + */ + +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, sign_nid; + size_t i; + 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); +} + +/* + * 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; + size_t i; + ret = sk_X509_dup(chain); + for (i = 0; i < sk_X509_num(ret); i++) { + X509_up_ref(sk_X509_value(ret, i)); + } + return ret; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509_cmp.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509_cmp.c.grpc_back new file mode 100644 index 0000000..98236d9 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509_cmp.c.grpc_back @@ -0,0 +1,477 @@ +/* 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 +#include +#include +#include +#include +#include +#include +#include + +#include "../internal.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)); +} + +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); +} + +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)); +} + +int X509_CRL_match(const X509_CRL *a, const X509_CRL *b) +{ + return OPENSSL_memcmp(a->sha1_hash, b->sha1_hash, 20); +} + +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)); +} + +unsigned long X509_issuer_name_hash_old(X509 *x) +{ + return (X509_NAME_hash_old(x->cert_info->issuer)); +} + +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)); +} + +unsigned long X509_subject_name_hash_old(X509 *x) +{ + return (X509_NAME_hash_old(x->cert_info->subject)); +} + +/* + * 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 = OPENSSL_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 OPENSSL_memcmp(a->cert_info->enc.enc, b->cert_info->enc.enc, + a->cert_info->enc.len); + } + return rv; +} + +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) + return ret; + + return OPENSSL_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); +} + +/* + * 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); +} + +/* 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) +{ + size_t 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; + size_t 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: + OPENSSL_PUT_ERROR(X509, X509_R_KEY_VALUES_MISMATCH); + break; + case -1: + OPENSSL_PUT_ERROR(X509, X509_R_KEY_TYPE_MISMATCH); + break; + case -2: + OPENSSL_PUT_ERROR(X509, 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. + */ + +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, sign_nid; + size_t i; + 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); +} + +/* + * 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; + size_t i; + ret = sk_X509_dup(chain); + for (i = 0; i < sk_X509_num(ret); i++) { + X509_up_ref(sk_X509_value(ret, i)); + } + return ret; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509_d2.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509_d2.c new file mode 100644 index 0000000..a407c1e --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509_d2.c @@ -0,0 +1,106 @@ +/* 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 + +#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 diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509_d2.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509_d2.c.grpc_back new file mode 100644 index 0000000..69ae54e --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509_d2.c.grpc_back @@ -0,0 +1,106 @@ +/* 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 + +#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 diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509_def.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509_def.c new file mode 100644 index 0000000..2737915 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509_def.c @@ -0,0 +1,103 @@ +/* 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 + +/* TODO(fork): cleanup */ + +#if defined(OPENSSL_FUCHSIA) +#define OPENSSLDIR "/system/data/boringssl" +#else +#define OPENSSLDIR "/etc/ssl" +#endif + +#define X509_CERT_AREA OPENSSLDIR +#define X509_CERT_DIR OPENSSLDIR "/certs" +#define X509_CERT_FILE OPENSSLDIR "/cert.pem" +#define X509_PRIVATE_DIR OPENSSLDIR "/private" +#define X509_CERT_DIR_EVP "SSL_CERT_DIR" +#define X509_CERT_FILE_EVP "SSL_CERT_FILE" + +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); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509_def.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509_def.c.grpc_back new file mode 100644 index 0000000..cb34ea4 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509_def.c.grpc_back @@ -0,0 +1,103 @@ +/* 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 + +/* TODO(fork): cleanup */ + +#if defined(OPENSSL_FUCHSIA) +#define OPENSSLDIR "/system/data/boringssl" +#else +#define OPENSSLDIR "/etc/ssl" +#endif + +#define X509_CERT_AREA OPENSSLDIR +#define X509_CERT_DIR OPENSSLDIR "/certs" +#define X509_CERT_FILE OPENSSLDIR "/cert.pem" +#define X509_PRIVATE_DIR OPENSSLDIR "/private" +#define X509_CERT_DIR_EVP "SSL_CERT_DIR" +#define X509_CERT_FILE_EVP "SSL_CERT_FILE" + +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); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509_ext.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509_ext.c new file mode 100644 index 0000000..69aaafb --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509_ext.c @@ -0,0 +1,206 @@ +/* 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 +#include +#include +#include +#include + +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_ASN1_SET_OF(X509_EXTENSION) diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509_ext.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509_ext.c.grpc_back new file mode 100644 index 0000000..a329f6f --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509_ext.c.grpc_back @@ -0,0 +1,206 @@ +/* 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 +#include +#include +#include +#include + +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_ASN1_SET_OF(X509_EXTENSION) diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509_lu.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509_lu.c new file mode 100644 index 0000000..285f8e3 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509_lu.c @@ -0,0 +1,725 @@ +/* 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 +#include +#include +#include +#include + +#include "../internal.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 0; + if (ctx->skip) + return 0; + return ctx->method->get_by_subject(ctx, type, name, ret) > 0; +} + +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 0; + return ctx->method->get_by_issuer_serial(ctx, type, name, serial, ret) > 0; +} + +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 0; + return ctx->method->get_by_fingerprint(ctx, type, bytes, len, ret) > 0; +} + +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 0; + return ctx->method->get_by_alias(ctx, type, str, len, ret) > 0; +} + +static int x509_object_cmp(const X509_OBJECT **a, const X509_OBJECT **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; + OPENSSL_memset(ret, 0, sizeof(*ret)); + CRYPTO_MUTEX_init(&ret->objs_lock); + ret->objs = sk_X509_OBJECT_new(x509_object_cmp); + if (ret->objs == NULL) + goto err; + ret->cache = 1; + ret->get_cert_methods = sk_X509_LOOKUP_new_null(); + if (ret->get_cert_methods == NULL) + goto err; + ret->param = X509_VERIFY_PARAM_new(); + if (ret->param == NULL) + goto err; + + ret->references = 1; + return ret; + err: + if (ret) { + CRYPTO_MUTEX_cleanup(&ret->objs_lock); + if (ret->param) + X509_VERIFY_PARAM_free(ret->param); + if (ret->get_cert_methods) + sk_X509_LOOKUP_free(ret->get_cert_methods); + if (ret->objs) + sk_X509_OBJECT_free(ret->objs); + OPENSSL_free(ret); + } + return NULL; +} + +int X509_STORE_up_ref(X509_STORE *store) +{ + CRYPTO_refcount_inc(&store->references); + return 1; +} + +static void cleanup(X509_OBJECT *a) +{ + if (a == NULL) { + 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) +{ + size_t j; + STACK_OF(X509_LOOKUP) *sk; + X509_LOOKUP *lu; + + if (vfy == NULL) + return; + + if (!CRYPTO_refcount_dec_and_test_zero(&vfy->references)) { + return; + } + + CRYPTO_MUTEX_cleanup(&vfy->objs_lock); + + sk = vfy->get_cert_methods; + for (j = 0; j < sk_X509_LOOKUP_num(sk); j++) { + lu = sk_X509_LOOKUP_value(sk, j); + X509_LOOKUP_shutdown(lu); + X509_LOOKUP_free(lu); + } + sk_X509_LOOKUP_free(sk); + sk_X509_OBJECT_pop_free(vfy->objs, cleanup); + + 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) +{ + size_t 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; + + CRYPTO_MUTEX_lock_write(&ctx->objs_lock); + tmp = X509_OBJECT_retrieve_by_subject(ctx->objs, type, name); + CRYPTO_MUTEX_unlock_write(&ctx->objs_lock); + + if (tmp == NULL || type == X509_LU_CRL) { + for (i = 0; i < (int)sk_X509_LOOKUP_num(ctx->get_cert_methods); i++) { + lu = sk_X509_LOOKUP_value(ctx->get_cert_methods, i); + if (X509_LOOKUP_by_subject(lu, type, name, &stmp)) { + tmp = &stmp; + break; + } + } + 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) { + OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); + return 0; + } + obj->type = X509_LU_X509; + obj->data.x509 = x; + + CRYPTO_MUTEX_lock_write(&ctx->objs_lock); + + X509_OBJECT_up_ref_count(obj); + + if (X509_OBJECT_retrieve_match(ctx->objs, obj)) { + X509_OBJECT_free_contents(obj); + OPENSSL_free(obj); + OPENSSL_PUT_ERROR(X509, 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); + OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); + ret = 0; + } + + CRYPTO_MUTEX_unlock_write(&ctx->objs_lock); + + 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) { + OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); + return 0; + } + obj->type = X509_LU_CRL; + obj->data.crl = x; + + CRYPTO_MUTEX_lock_write(&ctx->objs_lock); + + X509_OBJECT_up_ref_count(obj); + + if (X509_OBJECT_retrieve_match(ctx->objs, obj)) { + X509_OBJECT_free_contents(obj); + OPENSSL_free(obj); + OPENSSL_PUT_ERROR(X509, 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); + OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); + ret = 0; + } + + CRYPTO_MUTEX_unlock_write(&ctx->objs_lock); + + return ret; +} + +void X509_STORE_set0_additional_untrusted(X509_STORE *ctx, + STACK_OF(X509) *untrusted) { + ctx->additional_untrusted = untrusted; +} + +int X509_OBJECT_up_ref_count(X509_OBJECT *a) +{ + switch (a->type) { + case X509_LU_X509: + X509_up_ref(a->data.x509); + break; + case X509_LU_CRL: + X509_CRL_up_ref(a->data.crl); + break; + } + return 1; +} + +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; + } +} + +int X509_OBJECT_get_type(const X509_OBJECT *a) +{ + return a->type; +} + +X509 *X509_OBJECT_get0_X509(const X509_OBJECT *a) +{ + if (a == NULL || a->type != X509_LU_X509) { + return NULL; + } + return a->data.x509; +} + +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; + + 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; + } + + size_t idx; + if (!sk_X509_OBJECT_find(h, &idx, &stmp)) + return -1; + + if (pnmatch != NULL) { + int tidx; + const X509_OBJECT *tobj, *pstmp; + *pnmatch = 1; + pstmp = &stmp; + for (tidx = idx + 1; tidx < (int)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_OBJECT) *X509_STORE_get0_objects(X509_STORE *st) +{ + return st->objs; +} + +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; + sk = sk_X509_new_null(); + if (sk == NULL) + return NULL; + CRYPTO_MUTEX_lock_write(&ctx->ctx->objs_lock); + 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_MUTEX_unlock_write(&ctx->ctx->objs_lock); + if (!X509_STORE_get_by_subject(ctx, X509_LU_X509, nm, &xobj)) { + sk_X509_free(sk); + return NULL; + } + X509_OBJECT_free_contents(&xobj); + CRYPTO_MUTEX_lock_write(&ctx->ctx->objs_lock); + idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_X509, nm, &cnt); + if (idx < 0) { + CRYPTO_MUTEX_unlock_write(&ctx->ctx->objs_lock); + 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; + if (!sk_X509_push(sk, x)) { + CRYPTO_MUTEX_unlock_write(&ctx->ctx->objs_lock); + sk_X509_pop_free(sk, X509_free); + return NULL; + } + X509_up_ref(x); + } + CRYPTO_MUTEX_unlock_write(&ctx->ctx->objs_lock); + 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; + sk = sk_X509_CRL_new_null(); + if (sk == NULL) + return NULL; + + /* Always do lookup to possibly add new CRLs to cache. */ + 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_MUTEX_lock_write(&ctx->ctx->objs_lock); + idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_CRL, nm, &cnt); + if (idx < 0) { + CRYPTO_MUTEX_unlock_write(&ctx->ctx->objs_lock); + 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; + X509_CRL_up_ref(x); + if (!sk_X509_CRL_push(sk, x)) { + CRYPTO_MUTEX_unlock_write(&ctx->ctx->objs_lock); + X509_CRL_free(x); + sk_X509_CRL_pop_free(sk, X509_CRL_free); + return NULL; + } + } + CRYPTO_MUTEX_unlock_write(&ctx->ctx->objs_lock); + return sk; +} + +X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h, + X509_OBJECT *x) +{ + size_t idx, i; + X509_OBJECT *obj; + + if (!sk_X509_OBJECT_find(h, &idx, x)) { + 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 idx, ret; + size_t i; + xn = X509_get_issuer_name(x); + if (!X509_STORE_get_by_subject(ctx, X509_LU_X509, xn, &obj)) + 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); + + /* Else find index of first cert accepted by 'check_issued' */ + ret = 0; + CRYPTO_MUTEX_lock_write(&ctx->ctx->objs_lock); + 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_MUTEX_unlock_write(&ctx->ctx->objs_lock); + 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); +} + +X509_VERIFY_PARAM *X509_STORE_get0_param(X509_STORE *ctx) +{ + return ctx->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; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509_lu.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509_lu.c.grpc_back new file mode 100644 index 0000000..1a841db --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509_lu.c.grpc_back @@ -0,0 +1,725 @@ +/* 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 +#include +#include +#include +#include + +#include "../internal.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 0; + if (ctx->skip) + return 0; + return ctx->method->get_by_subject(ctx, type, name, ret) > 0; +} + +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 0; + return ctx->method->get_by_issuer_serial(ctx, type, name, serial, ret) > 0; +} + +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 0; + return ctx->method->get_by_fingerprint(ctx, type, bytes, len, ret) > 0; +} + +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 0; + return ctx->method->get_by_alias(ctx, type, str, len, ret) > 0; +} + +static int x509_object_cmp(const X509_OBJECT **a, const X509_OBJECT **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; + OPENSSL_memset(ret, 0, sizeof(*ret)); + CRYPTO_MUTEX_init(&ret->objs_lock); + ret->objs = sk_X509_OBJECT_new(x509_object_cmp); + if (ret->objs == NULL) + goto err; + ret->cache = 1; + ret->get_cert_methods = sk_X509_LOOKUP_new_null(); + if (ret->get_cert_methods == NULL) + goto err; + ret->param = X509_VERIFY_PARAM_new(); + if (ret->param == NULL) + goto err; + + ret->references = 1; + return ret; + err: + if (ret) { + CRYPTO_MUTEX_cleanup(&ret->objs_lock); + if (ret->param) + X509_VERIFY_PARAM_free(ret->param); + if (ret->get_cert_methods) + sk_X509_LOOKUP_free(ret->get_cert_methods); + if (ret->objs) + sk_X509_OBJECT_free(ret->objs); + OPENSSL_free(ret); + } + return NULL; +} + +int X509_STORE_up_ref(X509_STORE *store) +{ + CRYPTO_refcount_inc(&store->references); + return 1; +} + +static void cleanup(X509_OBJECT *a) +{ + if (a == NULL) { + 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) +{ + size_t j; + STACK_OF(X509_LOOKUP) *sk; + X509_LOOKUP *lu; + + if (vfy == NULL) + return; + + if (!CRYPTO_refcount_dec_and_test_zero(&vfy->references)) { + return; + } + + CRYPTO_MUTEX_cleanup(&vfy->objs_lock); + + sk = vfy->get_cert_methods; + for (j = 0; j < sk_X509_LOOKUP_num(sk); j++) { + lu = sk_X509_LOOKUP_value(sk, j); + X509_LOOKUP_shutdown(lu); + X509_LOOKUP_free(lu); + } + sk_X509_LOOKUP_free(sk); + sk_X509_OBJECT_pop_free(vfy->objs, cleanup); + + 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) +{ + size_t 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; + + CRYPTO_MUTEX_lock_write(&ctx->objs_lock); + tmp = X509_OBJECT_retrieve_by_subject(ctx->objs, type, name); + CRYPTO_MUTEX_unlock_write(&ctx->objs_lock); + + if (tmp == NULL || type == X509_LU_CRL) { + for (i = 0; i < (int)sk_X509_LOOKUP_num(ctx->get_cert_methods); i++) { + lu = sk_X509_LOOKUP_value(ctx->get_cert_methods, i); + if (X509_LOOKUP_by_subject(lu, type, name, &stmp)) { + tmp = &stmp; + break; + } + } + 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) { + OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); + return 0; + } + obj->type = X509_LU_X509; + obj->data.x509 = x; + + CRYPTO_MUTEX_lock_write(&ctx->objs_lock); + + X509_OBJECT_up_ref_count(obj); + + if (X509_OBJECT_retrieve_match(ctx->objs, obj)) { + X509_OBJECT_free_contents(obj); + OPENSSL_free(obj); + OPENSSL_PUT_ERROR(X509, 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); + OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); + ret = 0; + } + + CRYPTO_MUTEX_unlock_write(&ctx->objs_lock); + + 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) { + OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); + return 0; + } + obj->type = X509_LU_CRL; + obj->data.crl = x; + + CRYPTO_MUTEX_lock_write(&ctx->objs_lock); + + X509_OBJECT_up_ref_count(obj); + + if (X509_OBJECT_retrieve_match(ctx->objs, obj)) { + X509_OBJECT_free_contents(obj); + OPENSSL_free(obj); + OPENSSL_PUT_ERROR(X509, 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); + OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); + ret = 0; + } + + CRYPTO_MUTEX_unlock_write(&ctx->objs_lock); + + return ret; +} + +void X509_STORE_set0_additional_untrusted(X509_STORE *ctx, + STACK_OF(X509) *untrusted) { + ctx->additional_untrusted = untrusted; +} + +int X509_OBJECT_up_ref_count(X509_OBJECT *a) +{ + switch (a->type) { + case X509_LU_X509: + X509_up_ref(a->data.x509); + break; + case X509_LU_CRL: + X509_CRL_up_ref(a->data.crl); + break; + } + return 1; +} + +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; + } +} + +int X509_OBJECT_get_type(const X509_OBJECT *a) +{ + return a->type; +} + +X509 *X509_OBJECT_get0_X509(const X509_OBJECT *a) +{ + if (a == NULL || a->type != X509_LU_X509) { + return NULL; + } + return a->data.x509; +} + +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; + + 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; + } + + size_t idx; + if (!sk_X509_OBJECT_find(h, &idx, &stmp)) + return -1; + + if (pnmatch != NULL) { + int tidx; + const X509_OBJECT *tobj, *pstmp; + *pnmatch = 1; + pstmp = &stmp; + for (tidx = idx + 1; tidx < (int)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_OBJECT) *X509_STORE_get0_objects(X509_STORE *st) +{ + return st->objs; +} + +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; + sk = sk_X509_new_null(); + if (sk == NULL) + return NULL; + CRYPTO_MUTEX_lock_write(&ctx->ctx->objs_lock); + 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_MUTEX_unlock_write(&ctx->ctx->objs_lock); + if (!X509_STORE_get_by_subject(ctx, X509_LU_X509, nm, &xobj)) { + sk_X509_free(sk); + return NULL; + } + X509_OBJECT_free_contents(&xobj); + CRYPTO_MUTEX_lock_write(&ctx->ctx->objs_lock); + idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_X509, nm, &cnt); + if (idx < 0) { + CRYPTO_MUTEX_unlock_write(&ctx->ctx->objs_lock); + 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; + if (!sk_X509_push(sk, x)) { + CRYPTO_MUTEX_unlock_write(&ctx->ctx->objs_lock); + sk_X509_pop_free(sk, X509_free); + return NULL; + } + X509_up_ref(x); + } + CRYPTO_MUTEX_unlock_write(&ctx->ctx->objs_lock); + 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; + sk = sk_X509_CRL_new_null(); + if (sk == NULL) + return NULL; + + /* Always do lookup to possibly add new CRLs to cache. */ + 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_MUTEX_lock_write(&ctx->ctx->objs_lock); + idx = x509_object_idx_cnt(ctx->ctx->objs, X509_LU_CRL, nm, &cnt); + if (idx < 0) { + CRYPTO_MUTEX_unlock_write(&ctx->ctx->objs_lock); + 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; + X509_CRL_up_ref(x); + if (!sk_X509_CRL_push(sk, x)) { + CRYPTO_MUTEX_unlock_write(&ctx->ctx->objs_lock); + X509_CRL_free(x); + sk_X509_CRL_pop_free(sk, X509_CRL_free); + return NULL; + } + } + CRYPTO_MUTEX_unlock_write(&ctx->ctx->objs_lock); + return sk; +} + +X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h, + X509_OBJECT *x) +{ + size_t idx, i; + X509_OBJECT *obj; + + if (!sk_X509_OBJECT_find(h, &idx, x)) { + 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 idx, ret; + size_t i; + xn = X509_get_issuer_name(x); + if (!X509_STORE_get_by_subject(ctx, X509_LU_X509, xn, &obj)) + 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); + + /* Else find index of first cert accepted by 'check_issued' */ + ret = 0; + CRYPTO_MUTEX_lock_write(&ctx->ctx->objs_lock); + 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_MUTEX_unlock_write(&ctx->ctx->objs_lock); + 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); +} + +X509_VERIFY_PARAM *X509_STORE_get0_param(X509_STORE *ctx) +{ + return ctx->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; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509_obj.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509_obj.c new file mode 100644 index 0000000..8184ce4 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509_obj.c @@ -0,0 +1,198 @@ +/* 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 +#include +#include +#include +#include + +#include "../internal.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; + size_t 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]; + + 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); + } + BUF_strlcpy(buf, "NO X509_NAME", len); + 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) { + OPENSSL_PUT_ERROR(X509, X509_R_NAME_TOO_LONG); + goto end; + } + q = ne->value->data; + + 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++; + if ((q[j] < ' ') || (q[j] > '~')) + l2 += 3; + } + + lold = l; + l += 1 + l1 + 1 + l2; + if (l > NAME_ONELINE_MAX) { + OPENSSL_PUT_ERROR(X509, 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++) = '/'; + OPENSSL_memcpy(p, s, (unsigned int)l1); + p += l1; + *(p++) = '='; + + q = ne->value->data; + + for (j = 0; j < num; j++) { + if (!gs_doit[j & 3]) + continue; + n = q[j]; + if ((n < ' ') || (n > '~')) { + *(p++) = '\\'; + *(p++) = 'x'; + *(p++) = hex[(n >> 4) & 0x0f]; + *(p++) = hex[n & 0x0f]; + } else + *(p++) = n; + } + *p = '\0'; + } + if (b != NULL) { + p = b->data; + OPENSSL_free(b); + } else + p = buf; + if (i == 0) + *p = '\0'; + return (p); + err: + OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); + end: + BUF_MEM_free(b); + return (NULL); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509_obj.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509_obj.c.grpc_back new file mode 100644 index 0000000..65b1bfb --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509_obj.c.grpc_back @@ -0,0 +1,198 @@ +/* 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 +#include +#include +#include +#include + +#include "../internal.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; + size_t 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]; + + 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); + } + BUF_strlcpy(buf, "NO X509_NAME", len); + 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) { + OPENSSL_PUT_ERROR(X509, X509_R_NAME_TOO_LONG); + goto end; + } + q = ne->value->data; + + 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++; + if ((q[j] < ' ') || (q[j] > '~')) + l2 += 3; + } + + lold = l; + l += 1 + l1 + 1 + l2; + if (l > NAME_ONELINE_MAX) { + OPENSSL_PUT_ERROR(X509, 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++) = '/'; + OPENSSL_memcpy(p, s, (unsigned int)l1); + p += l1; + *(p++) = '='; + + q = ne->value->data; + + for (j = 0; j < num; j++) { + if (!gs_doit[j & 3]) + continue; + n = q[j]; + if ((n < ' ') || (n > '~')) { + *(p++) = '\\'; + *(p++) = 'x'; + *(p++) = hex[(n >> 4) & 0x0f]; + *(p++) = hex[n & 0x0f]; + } else + *(p++) = n; + } + *p = '\0'; + } + if (b != NULL) { + p = b->data; + OPENSSL_free(b); + } else + p = buf; + if (i == 0) + *p = '\0'; + return (p); + err: + OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); + end: + BUF_MEM_free(b); + return (NULL); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509_r2x.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509_r2x.c new file mode 100644 index 0000000..a1d1d79 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509_r2x.c @@ -0,0 +1,117 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 +#include +#include +#include + +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) { + OPENSSL_PUT_ERROR(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); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509_r2x.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509_r2x.c.grpc_back new file mode 100644 index 0000000..9bdf441 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509_r2x.c.grpc_back @@ -0,0 +1,117 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 +#include +#include +#include + +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) { + OPENSSL_PUT_ERROR(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); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509_req.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509_req.c new file mode 100644 index 0000000..6752b7f --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509_req.c @@ -0,0 +1,322 @@ +/* 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 +#include +#include +#include +#include +#include +#include +#include +#include + +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) { + OPENSSL_PUT_ERROR(X509, 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: + OPENSSL_PUT_ERROR(X509, X509_R_KEY_VALUES_MISMATCH); + break; + case -1: + OPENSSL_PUT_ERROR(X509, X509_R_KEY_TYPE_MISMATCH); + break; + case -2: + if (k->type == EVP_PKEY_EC) { + OPENSSL_PUT_ERROR(X509, ERR_R_EC_LIB); + break; + } + if (k->type == EVP_PKEY_DH) { + /* No idea */ + OPENSSL_PUT_ERROR(X509, X509_R_CANT_CHECK_DH_KEY); + break; + } + OPENSSL_PUT_ERROR(X509, 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 const int ext_nid_list[] = { NID_ext_req, NID_ms_ext_req, NID_undef }; + +static const 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; + } +} + +const int *X509_REQ_get_extension_nids(void) +{ + return ext_nids; +} + +void X509_REQ_set_extension_nids(const 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; + const int *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 = (ASN1_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; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509_req.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509_req.c.grpc_back new file mode 100644 index 0000000..69bc6f1 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509_req.c.grpc_back @@ -0,0 +1,322 @@ +/* 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 +#include +#include +#include +#include +#include +#include +#include +#include + +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) { + OPENSSL_PUT_ERROR(X509, 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: + OPENSSL_PUT_ERROR(X509, X509_R_KEY_VALUES_MISMATCH); + break; + case -1: + OPENSSL_PUT_ERROR(X509, X509_R_KEY_TYPE_MISMATCH); + break; + case -2: + if (k->type == EVP_PKEY_EC) { + OPENSSL_PUT_ERROR(X509, ERR_R_EC_LIB); + break; + } + if (k->type == EVP_PKEY_DH) { + /* No idea */ + OPENSSL_PUT_ERROR(X509, X509_R_CANT_CHECK_DH_KEY); + break; + } + OPENSSL_PUT_ERROR(X509, 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 const int ext_nid_list[] = { NID_ext_req, NID_ms_ext_req, NID_undef }; + +static const 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; + } +} + +const int *X509_REQ_get_extension_nids(void) +{ + return ext_nids; +} + +void X509_REQ_set_extension_nids(const 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; + const int *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 = (ASN1_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; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509_set.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509_set.c new file mode 100644 index 0000000..7200e5e --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509_set.c @@ -0,0 +1,164 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 + +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); +} + +const ASN1_TIME *X509_get0_notBefore(const X509 *x) +{ + return x->cert_info->validity->notBefore; +} + +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); +} + +const ASN1_TIME *X509_get0_notAfter(const X509 *x) +{ + return x->cert_info->validity->notAfter; +} + +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)); +} + +STACK_OF(X509_EXTENSION) *X509_get0_extensions(const X509 *x) +{ + return x->cert_info->extensions; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509_set.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509_set.c.grpc_back new file mode 100644 index 0000000..413a20d --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509_set.c.grpc_back @@ -0,0 +1,164 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 + +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); +} + +const ASN1_TIME *X509_get0_notBefore(const X509 *x) +{ + return x->cert_info->validity->notBefore; +} + +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); +} + +const ASN1_TIME *X509_get0_notAfter(const X509 *x) +{ + return x->cert_info->validity->notAfter; +} + +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)); +} + +STACK_OF(X509_EXTENSION) *X509_get0_extensions(const X509 *x) +{ + return x->cert_info->extensions; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509_trs.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509_trs.c new file mode 100644 index 0000000..4530d09 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509_trs.c @@ -0,0 +1,326 @@ +/* + * 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 +#include + +static int tr_cmp(const X509_TRUST **a, const X509_TRUST **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, (char *)"compatible", 0, NULL}, + {X509_TRUST_SSL_CLIENT, 0, trust_1oidany, (char *)"SSL Client", + NID_client_auth, NULL}, + {X509_TRUST_SSL_SERVER, 0, trust_1oidany, (char *)"SSL Server", + NID_server_auth, NULL}, + {X509_TRUST_EMAIL, 0, trust_1oidany, (char *)"S/MIME email", + NID_email_protect, NULL}, + {X509_TRUST_OBJECT_SIGN, 0, trust_1oidany, (char *)"Object Signer", + NID_code_sign, NULL}, + {X509_TRUST_OCSP_SIGN, 0, trust_1oid, (char *)"OCSP responder", + NID_OCSP_sign, NULL}, + {X509_TRUST_OCSP_REQUEST, 0, trust_1oid, (char *)"OCSP request", + NID_ad_OCSP, NULL}, + {X509_TRUST_TSA, 0, trust_1oidany, (char *)"TSA server", NID_time_stamp, + NULL} +}; + +#define X509_TRUST_COUNT (sizeof(trstandard)/sizeof(X509_TRUST)) + +static STACK_OF(X509_TRUST) *trtable = NULL; + +static int tr_cmp(const X509_TRUST **a, const X509_TRUST **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; + size_t idx; + + if ((id >= X509_TRUST_MIN) && (id <= X509_TRUST_MAX)) + return id - X509_TRUST_MIN; + tmp.trust = id; + if (!trtable) + return -1; + if (!sk_X509_TRUST_find(trtable, &idx, &tmp)) { + return -1; + } + return idx + X509_TRUST_COUNT; +} + +int X509_TRUST_set(int *t, int trust) +{ + if (X509_TRUST_get_by_id(trust) == -1) { + OPENSSL_PUT_ERROR(X509, 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; + char *name_dup; + + /* + * 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)))) { + OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); + return 0; + } + trtmp->flags = X509_TRUST_DYNAMIC; + } else + trtmp = X509_TRUST_get0(idx); + + /* Duplicate the supplied name. */ + name_dup = BUF_strdup(name); + if (name_dup == NULL) { + OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); + if (idx == -1) + OPENSSL_free(trtmp); + return 0; + } + + /* OPENSSL_free existing name if dynamic */ + if (trtmp->flags & X509_TRUST_DYNAMIC_NAME) + OPENSSL_free(trtmp->name); + trtmp->name = name_dup; + /* 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))) { + OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); + trtable_free(trtmp); + return 0; + } + if (!sk_X509_TRUST_push(trtable, trtmp)) { + OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); + trtable_free(trtmp); + 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; + size_t 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; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509_trs.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509_trs.c.grpc_back new file mode 100644 index 0000000..c7dfcad --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509_trs.c.grpc_back @@ -0,0 +1,326 @@ +/* + * 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 +#include + +static int tr_cmp(const X509_TRUST **a, const X509_TRUST **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, (char *)"compatible", 0, NULL}, + {X509_TRUST_SSL_CLIENT, 0, trust_1oidany, (char *)"SSL Client", + NID_client_auth, NULL}, + {X509_TRUST_SSL_SERVER, 0, trust_1oidany, (char *)"SSL Server", + NID_server_auth, NULL}, + {X509_TRUST_EMAIL, 0, trust_1oidany, (char *)"S/MIME email", + NID_email_protect, NULL}, + {X509_TRUST_OBJECT_SIGN, 0, trust_1oidany, (char *)"Object Signer", + NID_code_sign, NULL}, + {X509_TRUST_OCSP_SIGN, 0, trust_1oid, (char *)"OCSP responder", + NID_OCSP_sign, NULL}, + {X509_TRUST_OCSP_REQUEST, 0, trust_1oid, (char *)"OCSP request", + NID_ad_OCSP, NULL}, + {X509_TRUST_TSA, 0, trust_1oidany, (char *)"TSA server", NID_time_stamp, + NULL} +}; + +#define X509_TRUST_COUNT (sizeof(trstandard)/sizeof(X509_TRUST)) + +static STACK_OF(X509_TRUST) *trtable = NULL; + +static int tr_cmp(const X509_TRUST **a, const X509_TRUST **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; + size_t idx; + + if ((id >= X509_TRUST_MIN) && (id <= X509_TRUST_MAX)) + return id - X509_TRUST_MIN; + tmp.trust = id; + if (!trtable) + return -1; + if (!sk_X509_TRUST_find(trtable, &idx, &tmp)) { + return -1; + } + return idx + X509_TRUST_COUNT; +} + +int X509_TRUST_set(int *t, int trust) +{ + if (X509_TRUST_get_by_id(trust) == -1) { + OPENSSL_PUT_ERROR(X509, 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; + char *name_dup; + + /* + * 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)))) { + OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); + return 0; + } + trtmp->flags = X509_TRUST_DYNAMIC; + } else + trtmp = X509_TRUST_get0(idx); + + /* Duplicate the supplied name. */ + name_dup = BUF_strdup(name); + if (name_dup == NULL) { + OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); + if (idx == -1) + OPENSSL_free(trtmp); + return 0; + } + + /* OPENSSL_free existing name if dynamic */ + if (trtmp->flags & X509_TRUST_DYNAMIC_NAME) + OPENSSL_free(trtmp->name); + trtmp->name = name_dup; + /* 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))) { + OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); + trtable_free(trtmp); + return 0; + } + if (!sk_X509_TRUST_push(trtable, trtmp)) { + OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); + trtable_free(trtmp); + 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; + size_t 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; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509_txt.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509_txt.c new file mode 100644 index 0000000..87dc346 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509_txt.c @@ -0,0 +1,205 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include +#include + +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"); + + default: + BIO_snprintf(buf, sizeof buf, "error number %ld", n); + return (buf); + } +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509_txt.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509_txt.c.grpc_back new file mode 100644 index 0000000..753e720 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509_txt.c.grpc_back @@ -0,0 +1,205 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code cannot be changed. i.e. this code cannot simply be + * copied and put under another distribution licence + * [including the GNU Public Licence.] */ + +#include +#include + +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"); + + default: + BIO_snprintf(buf, sizeof buf, "error number %ld", n); + return (buf); + } +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509_v3.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509_v3.c new file mode 100644 index 0000000..0cb893f --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509_v3.c @@ -0,0 +1,278 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 +#include +#include + +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) +{ + const 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, + const 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 || loc < 0 || sk_X509_EXTENSION_num(x) <= (size_t)loc) + 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 || loc < 0 || sk_X509_EXTENSION_num(x) <= (size_t)loc) + 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) { + OPENSSL_PUT_ERROR(X509, 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: + OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); + err2: + if (new_ex != NULL) + X509_EXTENSION_free(new_ex); + if (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) +{ + const ASN1_OBJECT *obj; + X509_EXTENSION *ret; + + obj = OBJ_nid2obj(nid); + if (obj == NULL) { + OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_NID); + return (NULL); + } + ret = X509_EXTENSION_create_by_OBJ(ex, obj, crit, data); + return (ret); +} + +X509_EXTENSION *X509_EXTENSION_create_by_OBJ(X509_EXTENSION **ex, + const ASN1_OBJECT *obj, int crit, + ASN1_OCTET_STRING *data) +{ + X509_EXTENSION *ret; + + if ((ex == NULL) || (*ex == NULL)) { + if ((ret = X509_EXTENSION_new()) == NULL) { + OPENSSL_PUT_ERROR(X509, 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, const ASN1_OBJECT *obj) +{ + if ((ex == NULL) || (obj == NULL)) + return (0); + ASN1_OBJECT_free(ex->object); + ex->object = OBJ_dup(obj); + return ex->object != NULL; +} + +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; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509_v3.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509_v3.c.grpc_back new file mode 100644 index 0000000..ecbc0dd --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509_v3.c.grpc_back @@ -0,0 +1,278 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 +#include +#include + +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) +{ + const 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, + const 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 || loc < 0 || sk_X509_EXTENSION_num(x) <= (size_t)loc) + 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 || loc < 0 || sk_X509_EXTENSION_num(x) <= (size_t)loc) + 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) { + OPENSSL_PUT_ERROR(X509, 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: + OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); + err2: + if (new_ex != NULL) + X509_EXTENSION_free(new_ex); + if (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) +{ + const ASN1_OBJECT *obj; + X509_EXTENSION *ret; + + obj = OBJ_nid2obj(nid); + if (obj == NULL) { + OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_NID); + return (NULL); + } + ret = X509_EXTENSION_create_by_OBJ(ex, obj, crit, data); + return (ret); +} + +X509_EXTENSION *X509_EXTENSION_create_by_OBJ(X509_EXTENSION **ex, + const ASN1_OBJECT *obj, int crit, + ASN1_OCTET_STRING *data) +{ + X509_EXTENSION *ret; + + if ((ex == NULL) || (*ex == NULL)) { + if ((ret = X509_EXTENSION_new()) == NULL) { + OPENSSL_PUT_ERROR(X509, 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, const ASN1_OBJECT *obj) +{ + if ((ex == NULL) || (obj == NULL)) + return (0); + ASN1_OBJECT_free(ex->object); + ex->object = OBJ_dup(obj); + return ex->object != NULL; +} + +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; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509_vfy.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509_vfy.c new file mode 100644 index 0000000..41fb6c8 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509_vfy.c @@ -0,0 +1,2476 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 +#include +#include +#include +#include +#include +#include + +#include "vpm_int.h" +#include "../internal.h" + +static CRYPTO_EX_DATA_CLASS g_ex_data_class = + CRYPTO_EX_DATA_CLASS_INIT_WITH_APP_DATA; + +/* 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); + +static int null_callback(int ok, X509_STORE_CTX *e) +{ + return ok; +} + +/* 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; + size_t 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)) + X509_up_ref(xtmp); + 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, trust; + int (*cb) (int xok, X509_STORE_CTX *xctx); + STACK_OF(X509) *sktmp = NULL; + if (ctx->cert == NULL) { + OPENSSL_PUT_ERROR(X509, 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. + */ + OPENSSL_PUT_ERROR(X509, 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 + */ + ctx->chain = sk_X509_new_null(); + if (ctx->chain == NULL || !sk_X509_push(ctx->chain, ctx->cert)) { + OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); + ctx->error = X509_V_ERR_OUT_OF_MEM; + goto end; + } + X509_up_ref(ctx->cert); + ctx->last_untrusted = 1; + + /* We use a temporary STACK so we can chop and hack at it. + * sktmp = ctx->untrusted ++ ctx->ctx->additional_untrusted */ + if (ctx->untrusted != NULL + && (sktmp = sk_X509_dup(ctx->untrusted)) == NULL) { + OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); + ctx->error = X509_V_ERR_OUT_OF_MEM; + goto end; + } + + if (ctx->ctx->additional_untrusted != NULL) { + if (sktmp == NULL) { + sktmp = sk_X509_new_null(); + if (sktmp == NULL) { + OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); + ctx->error = X509_V_ERR_OUT_OF_MEM; + goto end; + } + } + + for (size_t k = 0; k < sk_X509_num(ctx->ctx->additional_untrusted); + k++) { + if (!sk_X509_push(sktmp, + sk_X509_value(ctx->ctx->additional_untrusted, + k))) { + OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); + ctx->error = X509_V_ERR_OUT_OF_MEM; + goto end; + } + } + } + + 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 end; + } + /* + * 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 (sktmp != NULL) { + xtmp = find_issuer(ctx, sktmp, x); + if (xtmp != NULL) { + if (!sk_X509_push(ctx->chain, xtmp)) { + OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); + ctx->error = X509_V_ERR_OUT_OF_MEM; + ok = 0; + goto end; + } + X509_up_ref(xtmp); + (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 end; + } 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 end; + } + if (ok == 0) + break; + x = xtmp; + if (!sk_X509_push(ctx->chain, x)) { + X509_free(xtmp); + OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); + ctx->error = X509_V_ERR_OUT_OF_MEM; + ok = 0; + goto end; + } + num++; + } + + /* we now have our chain, lets check it... */ + trust = check_trust(ctx); + + /* If explicitly rejected error */ + if (trust == X509_TRUST_REJECTED) { + ok = 0; + goto end; + } + /* + * 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) + goto end; + /* 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 end; + } + + /* We have the chain complete: now we need to check its purpose */ + ok = check_chain_extensions(ctx); + + if (!ok) + goto end; + + ok = check_id(ctx); + + if (!ok) + goto end; + + /* + * 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 end; + + int 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 end; + } + + /* 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 end; + + /* Check name constraints */ + + ok = check_name_constraints(ctx); + if (!ok) + goto end; + + /* If we get this far evaluate policies */ + if (!bad_chain && (ctx->param->flags & X509_V_FLAG_POLICY_CHECK)) + ok = ctx->check_policy(ctx); + + end: + 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) +{ + size_t 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) { + X509_up_ref(*issuer); + 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) +{ + 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); + 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 not self issued */ + if ((i > 1) && !(x->ex_flags & EXFLAG_SI) + && (x->ex_pathlen != -1) + && (plen > (x->ex_pathlen + proxy_path_length + 1))) { + 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 self issued */ + if (!(x->ex_flags & EXFLAG_SI)) + 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) { + if (x->ex_pcpathlen != -1 && i > 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++; + must_be_ca = 0; + } else + must_be_ca = 1; + } + ok = 1; + end: + return ok; +} + +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; + /* + * 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) +{ + size_t i; + size_t 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, strlen(name), 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->poison) { + if (!check_id_error(ctx, X509_V_ERR_INVALID_CALL)) + return 0; + } + 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) +{ + size_t i; + int 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 < (int)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 = 0, 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; + 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 crl_score, best_score = *pscore; + size_t i; + 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; + X509_CRL_up_ref(best_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; + size_t 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; + X509_CRL_up_ref(delta); + *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; + size_t i; + + if ((size_t)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 < (int)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; + } + } + + for (i = 0; i < sk_X509_num(ctx->ctx->additional_untrusted); i++) { + crl_issuer = sk_X509_value(ctx->ctx->additional_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; + size_t 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) +{ + size_t 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) +{ + size_t 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) { + OPENSSL_PUT_ERROR(X509, 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; + size_t 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 != 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; + } + + 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) +{ + char *str; + ASN1_TIME atm; + long offset; + char buff1[24], buff2[24], *p; + int i, j, remaining; + + p = buff1; + remaining = ctm->length; + str = (char *)ctm->data; + /* + * Note that the following (historical) code allows much more slack in + * the time format than RFC5280. In RFC5280, the representation is fixed: + * UTCTime: YYMMDDHHMMSSZ GeneralizedTime: YYYYMMDDHHMMSSZ + */ + if (ctm->type == V_ASN1_UTCTIME) { + /* YYMMDDHHMM[SS]Z or YYMMDDHHMM[SS](+-)hhmm */ + int min_length = sizeof("YYMMDDHHMMZ") - 1; + int max_length = sizeof("YYMMDDHHMMSS+hhmm") - 1; + if (remaining < min_length || remaining > max_length) + return 0; + OPENSSL_memcpy(p, str, 10); + p += 10; + str += 10; + remaining -= 10; + } else { + /* + * YYYYMMDDHHMM[SS[.fff]]Z or YYYYMMDDHHMM[SS[.f[f[f]]]](+-)hhmm + */ + int min_length = sizeof("YYYYMMDDHHMMZ") - 1; + int max_length = sizeof("YYYYMMDDHHMMSS.fff+hhmm") - 1; + if (remaining < min_length || remaining > max_length) + return 0; + OPENSSL_memcpy(p, str, 12); + p += 12; + str += 12; + remaining -= 12; + } + + if ((*str == 'Z') || (*str == '-') || (*str == '+')) { + *(p++) = '0'; + *(p++) = '0'; + } else { + /* SS (seconds) */ + if (remaining < 2) + return 0; + *(p++) = *(str++); + *(p++) = *(str++); + remaining -= 2; + /* + * Skip any (up to three) fractional seconds... TODO(emilia): in + * RFC5280, fractional seconds are forbidden. Can we just kill them + * altogether? + */ + if (remaining && *str == '.') { + str++; + remaining--; + for (i = 0; i < 3 && remaining; i++, str++, remaining--) { + if (*str < '0' || *str > '9') + break; + } + } + + } + *(p++) = 'Z'; + *(p++) = '\0'; + + /* We now need either a terminating 'Z' or an offset. */ + if (!remaining) + return 0; + if (*str == 'Z') { + if (remaining != 1) + return 0; + offset = 0; + } else { + /* (+-)HHMM */ + if ((*str != '+') && (*str != '-')) + return 0; + /* + * Historical behaviour: the (+-)hhmm offset is forbidden in RFC5280. + */ + if (remaining != 5) + return 0; + if (str[1] < '0' || str[1] > '9' || str[2] < '0' || str[2] > '9' || + str[3] < '0' || str[3] > '9' || str[4] < '0' || str[4] > '9') + return 0; + offset = ((str[1] - '0') * 10 + (str[2] - '0')) * 60; + offset += (str[3] - '0') * 10 + (str[4] - '0'); + if (*str == '-') + offset = -offset; + } + atm.type = ctm->type; + atm.flags = 0; + atm.length = sizeof(buff2); + atm.data = (unsigned char *)buff2; + + if (X509_time_adj(&atm, offset * 60, cmp_time) == NULL) + return 0; + + if (ctm->type == V_ASN1_UTCTIME) { + i = (buff1[0] - '0') * 10 + (buff1[1] - '0'); + if (i < 50) + i += 100; /* cf. RFC 2459 */ + j = (buff2[0] - '0') * 10 + (buff2[1] - '0'); + if (j < 50) + j += 100; + + if (i < j) + return -1; + if (i > j) + return 1; + } + i = strcmp(buff1, buff2); + if (i == 0) /* wait a second then return younger :-) */ + return -1; + else + return i; +} + +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 = 0; + + 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); +} + +/* 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; + size_t j; + STACK_OF(X509_REVOKED) *revs = NULL; + /* CRLs can't be delta already */ + if (base->base_crl_number || newer->base_crl_number) { + OPENSSL_PUT_ERROR(X509, X509_R_CRL_ALREADY_DELTA); + return NULL; + } + /* Base and new CRL must have a CRL number */ + if (!base->crl_number || !newer->crl_number) { + OPENSSL_PUT_ERROR(X509, 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))) { + OPENSSL_PUT_ERROR(X509, X509_R_ISSUER_MISMATCH); + return NULL; + } + /* AKID and IDP must match */ + if (!crl_extension_match(base, newer, NID_authority_key_identifier)) { + OPENSSL_PUT_ERROR(X509, X509_R_AKID_MISMATCH); + return NULL; + } + if (!crl_extension_match(base, newer, NID_issuing_distribution_point)) { + OPENSSL_PUT_ERROR(X509, 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) { + OPENSSL_PUT_ERROR(X509, 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)) { + OPENSSL_PUT_ERROR(X509, 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 (j = 0; j < sk_X509_REVOKED_num(revs); j++) { + X509_REVOKED *rvn, *rvtmp; + rvn = sk_X509_REVOKED_value(revs, j); + /* + * 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: + OPENSSL_PUT_ERROR(X509, 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_unused * unused, + CRYPTO_EX_dup *dup_unused, + 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). + */ + int index; + if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp, + free_func)) { + return -1; + } + return index; +} + +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; +} + +STACK_OF(X509) *X509_STORE_CTX_get0_untrusted(X509_STORE_CTX *ctx) +{ + return ctx->untrusted; +} + +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) { + OPENSSL_PUT_ERROR(X509, 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) { + OPENSSL_PUT_ERROR(X509, 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) { + OPENSSL_PUT_ERROR(X509, 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) { + OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); + return NULL; + } + X509_STORE_CTX_zero(ctx); + return ctx; +} + +void X509_STORE_CTX_zero(X509_STORE_CTX *ctx) +{ + OPENSSL_memset(ctx, 0, sizeof(X509_STORE_CTX)); +} + +void X509_STORE_CTX_free(X509_STORE_CTX *ctx) +{ + if (ctx == NULL) { + 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; + + X509_STORE_CTX_zero(ctx); + ctx->ctx = store; + ctx->cert = x509; + ctx->untrusted = chain; + + CRYPTO_new_ex_data(&ctx->ex_data); + + ctx->param = X509_VERIFY_PARAM_new(); + if (!ctx->param) + goto err; + + /* + * 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; + 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) + 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; + + return 1; + + err: + CRYPTO_free_ex_data(&g_ex_data_class, ctx, &ctx->ex_data); + if (ctx->param != NULL) { + X509_VERIFY_PARAM_free(ctx->param); + } + + OPENSSL_memset(ctx, 0, sizeof(X509_STORE_CTX)); + OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); + 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, |X509_STORE_CTX_free| + * also calls this function. */ + 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(&g_ex_data_class, ctx, &(ctx->ex_data)); + OPENSSL_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_ASN1_SET_OF(X509) + +IMPLEMENT_ASN1_SET_OF(X509_ATTRIBUTE) diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509_vfy.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509_vfy.c.grpc_back new file mode 100644 index 0000000..2b754f0 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509_vfy.c.grpc_back @@ -0,0 +1,2476 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 +#include +#include +#include +#include +#include +#include + +#include "vpm_int.h" +#include "../internal.h" + +static CRYPTO_EX_DATA_CLASS g_ex_data_class = + CRYPTO_EX_DATA_CLASS_INIT_WITH_APP_DATA; + +/* 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); + +static int null_callback(int ok, X509_STORE_CTX *e) +{ + return ok; +} + +/* 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; + size_t 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)) + X509_up_ref(xtmp); + 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, trust; + int (*cb) (int xok, X509_STORE_CTX *xctx); + STACK_OF(X509) *sktmp = NULL; + if (ctx->cert == NULL) { + OPENSSL_PUT_ERROR(X509, 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. + */ + OPENSSL_PUT_ERROR(X509, 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 + */ + ctx->chain = sk_X509_new_null(); + if (ctx->chain == NULL || !sk_X509_push(ctx->chain, ctx->cert)) { + OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); + ctx->error = X509_V_ERR_OUT_OF_MEM; + goto end; + } + X509_up_ref(ctx->cert); + ctx->last_untrusted = 1; + + /* We use a temporary STACK so we can chop and hack at it. + * sktmp = ctx->untrusted ++ ctx->ctx->additional_untrusted */ + if (ctx->untrusted != NULL + && (sktmp = sk_X509_dup(ctx->untrusted)) == NULL) { + OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); + ctx->error = X509_V_ERR_OUT_OF_MEM; + goto end; + } + + if (ctx->ctx->additional_untrusted != NULL) { + if (sktmp == NULL) { + sktmp = sk_X509_new_null(); + if (sktmp == NULL) { + OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); + ctx->error = X509_V_ERR_OUT_OF_MEM; + goto end; + } + } + + for (size_t k = 0; k < sk_X509_num(ctx->ctx->additional_untrusted); + k++) { + if (!sk_X509_push(sktmp, + sk_X509_value(ctx->ctx->additional_untrusted, + k))) { + OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); + ctx->error = X509_V_ERR_OUT_OF_MEM; + goto end; + } + } + } + + 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 end; + } + /* + * 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 (sktmp != NULL) { + xtmp = find_issuer(ctx, sktmp, x); + if (xtmp != NULL) { + if (!sk_X509_push(ctx->chain, xtmp)) { + OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); + ctx->error = X509_V_ERR_OUT_OF_MEM; + ok = 0; + goto end; + } + X509_up_ref(xtmp); + (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 end; + } 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 end; + } + if (ok == 0) + break; + x = xtmp; + if (!sk_X509_push(ctx->chain, x)) { + X509_free(xtmp); + OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); + ctx->error = X509_V_ERR_OUT_OF_MEM; + ok = 0; + goto end; + } + num++; + } + + /* we now have our chain, lets check it... */ + trust = check_trust(ctx); + + /* If explicitly rejected error */ + if (trust == X509_TRUST_REJECTED) { + ok = 0; + goto end; + } + /* + * 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) + goto end; + /* 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 end; + } + + /* We have the chain complete: now we need to check its purpose */ + ok = check_chain_extensions(ctx); + + if (!ok) + goto end; + + ok = check_id(ctx); + + if (!ok) + goto end; + + /* + * 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 end; + + int 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 end; + } + + /* 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 end; + + /* Check name constraints */ + + ok = check_name_constraints(ctx); + if (!ok) + goto end; + + /* If we get this far evaluate policies */ + if (!bad_chain && (ctx->param->flags & X509_V_FLAG_POLICY_CHECK)) + ok = ctx->check_policy(ctx); + + end: + 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) +{ + size_t 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) { + X509_up_ref(*issuer); + 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) +{ + 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); + 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 not self issued */ + if ((i > 1) && !(x->ex_flags & EXFLAG_SI) + && (x->ex_pathlen != -1) + && (plen > (x->ex_pathlen + proxy_path_length + 1))) { + 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 self issued */ + if (!(x->ex_flags & EXFLAG_SI)) + 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) { + if (x->ex_pcpathlen != -1 && i > 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++; + must_be_ca = 0; + } else + must_be_ca = 1; + } + ok = 1; + end: + return ok; +} + +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; + /* + * 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) +{ + size_t i; + size_t 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, strlen(name), 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->poison) { + if (!check_id_error(ctx, X509_V_ERR_INVALID_CALL)) + return 0; + } + 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) +{ + size_t i; + int 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 < (int)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 = 0, 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; + 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 crl_score, best_score = *pscore; + size_t i; + 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; + X509_CRL_up_ref(best_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; + size_t 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; + X509_CRL_up_ref(delta); + *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; + size_t i; + + if ((size_t)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 < (int)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; + } + } + + for (i = 0; i < sk_X509_num(ctx->ctx->additional_untrusted); i++) { + crl_issuer = sk_X509_value(ctx->ctx->additional_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; + size_t 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) +{ + size_t 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) +{ + size_t 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) { + OPENSSL_PUT_ERROR(X509, 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; + size_t 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 != 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; + } + + 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) +{ + char *str; + ASN1_TIME atm; + long offset; + char buff1[24], buff2[24], *p; + int i, j, remaining; + + p = buff1; + remaining = ctm->length; + str = (char *)ctm->data; + /* + * Note that the following (historical) code allows much more slack in + * the time format than RFC5280. In RFC5280, the representation is fixed: + * UTCTime: YYMMDDHHMMSSZ GeneralizedTime: YYYYMMDDHHMMSSZ + */ + if (ctm->type == V_ASN1_UTCTIME) { + /* YYMMDDHHMM[SS]Z or YYMMDDHHMM[SS](+-)hhmm */ + int min_length = sizeof("YYMMDDHHMMZ") - 1; + int max_length = sizeof("YYMMDDHHMMSS+hhmm") - 1; + if (remaining < min_length || remaining > max_length) + return 0; + OPENSSL_memcpy(p, str, 10); + p += 10; + str += 10; + remaining -= 10; + } else { + /* + * YYYYMMDDHHMM[SS[.fff]]Z or YYYYMMDDHHMM[SS[.f[f[f]]]](+-)hhmm + */ + int min_length = sizeof("YYYYMMDDHHMMZ") - 1; + int max_length = sizeof("YYYYMMDDHHMMSS.fff+hhmm") - 1; + if (remaining < min_length || remaining > max_length) + return 0; + OPENSSL_memcpy(p, str, 12); + p += 12; + str += 12; + remaining -= 12; + } + + if ((*str == 'Z') || (*str == '-') || (*str == '+')) { + *(p++) = '0'; + *(p++) = '0'; + } else { + /* SS (seconds) */ + if (remaining < 2) + return 0; + *(p++) = *(str++); + *(p++) = *(str++); + remaining -= 2; + /* + * Skip any (up to three) fractional seconds... TODO(emilia): in + * RFC5280, fractional seconds are forbidden. Can we just kill them + * altogether? + */ + if (remaining && *str == '.') { + str++; + remaining--; + for (i = 0; i < 3 && remaining; i++, str++, remaining--) { + if (*str < '0' || *str > '9') + break; + } + } + + } + *(p++) = 'Z'; + *(p++) = '\0'; + + /* We now need either a terminating 'Z' or an offset. */ + if (!remaining) + return 0; + if (*str == 'Z') { + if (remaining != 1) + return 0; + offset = 0; + } else { + /* (+-)HHMM */ + if ((*str != '+') && (*str != '-')) + return 0; + /* + * Historical behaviour: the (+-)hhmm offset is forbidden in RFC5280. + */ + if (remaining != 5) + return 0; + if (str[1] < '0' || str[1] > '9' || str[2] < '0' || str[2] > '9' || + str[3] < '0' || str[3] > '9' || str[4] < '0' || str[4] > '9') + return 0; + offset = ((str[1] - '0') * 10 + (str[2] - '0')) * 60; + offset += (str[3] - '0') * 10 + (str[4] - '0'); + if (*str == '-') + offset = -offset; + } + atm.type = ctm->type; + atm.flags = 0; + atm.length = sizeof(buff2); + atm.data = (unsigned char *)buff2; + + if (X509_time_adj(&atm, offset * 60, cmp_time) == NULL) + return 0; + + if (ctm->type == V_ASN1_UTCTIME) { + i = (buff1[0] - '0') * 10 + (buff1[1] - '0'); + if (i < 50) + i += 100; /* cf. RFC 2459 */ + j = (buff2[0] - '0') * 10 + (buff2[1] - '0'); + if (j < 50) + j += 100; + + if (i < j) + return -1; + if (i > j) + return 1; + } + i = strcmp(buff1, buff2); + if (i == 0) /* wait a second then return younger :-) */ + return -1; + else + return i; +} + +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 = 0; + + 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); +} + +/* 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; + size_t j; + STACK_OF(X509_REVOKED) *revs = NULL; + /* CRLs can't be delta already */ + if (base->base_crl_number || newer->base_crl_number) { + OPENSSL_PUT_ERROR(X509, X509_R_CRL_ALREADY_DELTA); + return NULL; + } + /* Base and new CRL must have a CRL number */ + if (!base->crl_number || !newer->crl_number) { + OPENSSL_PUT_ERROR(X509, 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))) { + OPENSSL_PUT_ERROR(X509, X509_R_ISSUER_MISMATCH); + return NULL; + } + /* AKID and IDP must match */ + if (!crl_extension_match(base, newer, NID_authority_key_identifier)) { + OPENSSL_PUT_ERROR(X509, X509_R_AKID_MISMATCH); + return NULL; + } + if (!crl_extension_match(base, newer, NID_issuing_distribution_point)) { + OPENSSL_PUT_ERROR(X509, 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) { + OPENSSL_PUT_ERROR(X509, 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)) { + OPENSSL_PUT_ERROR(X509, 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 (j = 0; j < sk_X509_REVOKED_num(revs); j++) { + X509_REVOKED *rvn, *rvtmp; + rvn = sk_X509_REVOKED_value(revs, j); + /* + * 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: + OPENSSL_PUT_ERROR(X509, 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_unused * unused, + CRYPTO_EX_dup *dup_unused, + 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). + */ + int index; + if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp, + free_func)) { + return -1; + } + return index; +} + +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; +} + +STACK_OF(X509) *X509_STORE_CTX_get0_untrusted(X509_STORE_CTX *ctx) +{ + return ctx->untrusted; +} + +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) { + OPENSSL_PUT_ERROR(X509, 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) { + OPENSSL_PUT_ERROR(X509, 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) { + OPENSSL_PUT_ERROR(X509, 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) { + OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); + return NULL; + } + X509_STORE_CTX_zero(ctx); + return ctx; +} + +void X509_STORE_CTX_zero(X509_STORE_CTX *ctx) +{ + OPENSSL_memset(ctx, 0, sizeof(X509_STORE_CTX)); +} + +void X509_STORE_CTX_free(X509_STORE_CTX *ctx) +{ + if (ctx == NULL) { + 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; + + X509_STORE_CTX_zero(ctx); + ctx->ctx = store; + ctx->cert = x509; + ctx->untrusted = chain; + + CRYPTO_new_ex_data(&ctx->ex_data); + + ctx->param = X509_VERIFY_PARAM_new(); + if (!ctx->param) + goto err; + + /* + * 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; + 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) + 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; + + return 1; + + err: + CRYPTO_free_ex_data(&g_ex_data_class, ctx, &ctx->ex_data); + if (ctx->param != NULL) { + X509_VERIFY_PARAM_free(ctx->param); + } + + OPENSSL_memset(ctx, 0, sizeof(X509_STORE_CTX)); + OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); + 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, |X509_STORE_CTX_free| + * also calls this function. */ + 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(&g_ex_data_class, ctx, &(ctx->ex_data)); + OPENSSL_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_ASN1_SET_OF(X509) + +IMPLEMENT_ASN1_SET_OF(X509_ATTRIBUTE) diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509_vpm.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509_vpm.c new file mode 100644 index 0000000..f4b3a7c --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509_vpm.c @@ -0,0 +1,670 @@ +/* + * 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 +#include +#include +#include +#include +#include + +#include "vpm_int.h" +#include "../internal.h" + + +/* X509_VERIFY_PARAM functions */ + +#define SET_HOST 0 +#define ADD_HOST 1 + +static char *str_copy(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; + + if (name == NULL || namelen == 0) { + // Unlike OpenSSL, we reject trying to set or add an empty name. + return 0; + } + + /* + * Refuse names with embedded NUL bytes. + * XXX: Do we need to push an error onto the error stack? + */ + if (name && OPENSSL_memchr(name, '\0', namelen)) + return 0; + + if (mode == SET_HOST && id->hosts) { + string_stack_free(id->hosts); + id->hosts = NULL; + } + + 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; + } + paramid->poison = 0; +} + +X509_VERIFY_PARAM *X509_VERIFY_PARAM_new(void) +{ + X509_VERIFY_PARAM *param; + X509_VERIFY_PARAM_ID *paramid; + param = OPENSSL_malloc(sizeof(X509_VERIFY_PARAM)); + if (!param) + return NULL; + paramid = OPENSSL_malloc(sizeof(X509_VERIFY_PARAM_ID)); + if (!paramid) { + OPENSSL_free(param); + return NULL; + } + OPENSSL_memset(param, 0, sizeof(X509_VERIFY_PARAM)); + OPENSSL_memset(paramid, 0, sizeof(X509_VERIFY_PARAM_ID)); + 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; + } + + dest->id->poison = src->id->poison; + + 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 == NULL || srclen == 0) { + // Unlike OpenSSL, we do not allow an empty string to disable previously + // configured checks. + return 0; + } + + tmp = BUF_memdup(src, srclen); + if (!tmp) { + return 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) +{ + size_t 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) +{ + if (!int_x509_param_set_hosts(param->id, SET_HOST, name, namelen)) { + param->id->poison = 1; + return 0; + } + return 1; +} + +int X509_VERIFY_PARAM_add1_host(X509_VERIFY_PARAM *param, + const char *name, size_t namelen) +{ + if (!int_x509_param_set_hosts(param->id, ADD_HOST, name, namelen)) { + param->id->poison = 1; + return 0; + } + return 1; +} + +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) +{ + if (OPENSSL_memchr(email, '\0', emaillen) != NULL || + !int_x509_param_set1(¶m->id->email, ¶m->id->emaillen, + email, emaillen)) { + param->id->poison = 1; + return 0; + } + + return 1; +} + +int X509_VERIFY_PARAM_set1_ip(X509_VERIFY_PARAM *param, + const unsigned char *ip, size_t iplen) +{ + if ((iplen != 4 && iplen != 16) || + !int_x509_param_set1((char **)¶m->id->ip, ¶m->id->iplen, + (char *)ip, iplen)) { + param->id->poison = 1; + return 0; + } + + return 1; +} + +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 const X509_VERIFY_PARAM_ID _empty_id = + { NULL, 0U, NULL, NULL, 0, NULL, 0, 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[] = { + { + (char *)"default", /* X509 default parameters */ + 0, /* Check time */ + 0, /* internal flags */ + 0, /* flags */ + 0, /* purpose */ + 0, /* trust */ + 100, /* depth */ + NULL, /* policies */ + vpm_empty_id}, + { + (char *)"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}, + { + (char *)"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}, + { + (char *)"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}, + { + (char *)"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 param_cmp(const X509_VERIFY_PARAM **a, const X509_VERIFY_PARAM **b) +{ + return strcmp((*a)->name, (*b)->name); +} + +int X509_VERIFY_PARAM_add0_table(X509_VERIFY_PARAM *param) +{ + X509_VERIFY_PARAM *ptmp; + if (!param_table) { + param_table = sk_X509_VERIFY_PARAM_new(param_cmp); + if (!param_table) + return 0; + } else { + size_t idx; + + if (sk_X509_VERIFY_PARAM_find(param_table, &idx, param)) { + 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) +{ + X509_VERIFY_PARAM pm; + unsigned i, limit; + + pm.name = (char *)name; + if (param_table) { + size_t idx; + if (sk_X509_VERIFY_PARAM_find(param_table, &idx, &pm)) + return sk_X509_VERIFY_PARAM_value(param_table, idx); + } + + limit = sizeof(default_table) / sizeof(X509_VERIFY_PARAM); + for (i = 0; i < limit; i++) { + if (strcmp(default_table[i].name, name) == 0) { + return &default_table[i]; + } + } + return NULL; +} + +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/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509_vpm.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509_vpm.c.grpc_back new file mode 100644 index 0000000..43353c6 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509_vpm.c.grpc_back @@ -0,0 +1,670 @@ +/* + * 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 +#include +#include +#include +#include +#include + +#include "vpm_int.h" +#include "../internal.h" + + +/* X509_VERIFY_PARAM functions */ + +#define SET_HOST 0 +#define ADD_HOST 1 + +static char *str_copy(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; + + if (name == NULL || namelen == 0) { + // Unlike OpenSSL, we reject trying to set or add an empty name. + return 0; + } + + /* + * Refuse names with embedded NUL bytes. + * XXX: Do we need to push an error onto the error stack? + */ + if (name && OPENSSL_memchr(name, '\0', namelen)) + return 0; + + if (mode == SET_HOST && id->hosts) { + string_stack_free(id->hosts); + id->hosts = NULL; + } + + 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; + } + paramid->poison = 0; +} + +X509_VERIFY_PARAM *X509_VERIFY_PARAM_new(void) +{ + X509_VERIFY_PARAM *param; + X509_VERIFY_PARAM_ID *paramid; + param = OPENSSL_malloc(sizeof(X509_VERIFY_PARAM)); + if (!param) + return NULL; + paramid = OPENSSL_malloc(sizeof(X509_VERIFY_PARAM_ID)); + if (!paramid) { + OPENSSL_free(param); + return NULL; + } + OPENSSL_memset(param, 0, sizeof(X509_VERIFY_PARAM)); + OPENSSL_memset(paramid, 0, sizeof(X509_VERIFY_PARAM_ID)); + 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; + } + + dest->id->poison = src->id->poison; + + 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 == NULL || srclen == 0) { + // Unlike OpenSSL, we do not allow an empty string to disable previously + // configured checks. + return 0; + } + + tmp = BUF_memdup(src, srclen); + if (!tmp) { + return 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) +{ + size_t 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) +{ + if (!int_x509_param_set_hosts(param->id, SET_HOST, name, namelen)) { + param->id->poison = 1; + return 0; + } + return 1; +} + +int X509_VERIFY_PARAM_add1_host(X509_VERIFY_PARAM *param, + const char *name, size_t namelen) +{ + if (!int_x509_param_set_hosts(param->id, ADD_HOST, name, namelen)) { + param->id->poison = 1; + return 0; + } + return 1; +} + +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) +{ + if (OPENSSL_memchr(email, '\0', emaillen) != NULL || + !int_x509_param_set1(¶m->id->email, ¶m->id->emaillen, + email, emaillen)) { + param->id->poison = 1; + return 0; + } + + return 1; +} + +int X509_VERIFY_PARAM_set1_ip(X509_VERIFY_PARAM *param, + const unsigned char *ip, size_t iplen) +{ + if ((iplen != 4 && iplen != 16) || + !int_x509_param_set1((char **)¶m->id->ip, ¶m->id->iplen, + (char *)ip, iplen)) { + param->id->poison = 1; + return 0; + } + + return 1; +} + +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 const X509_VERIFY_PARAM_ID _empty_id = + { NULL, 0U, NULL, NULL, 0, NULL, 0, 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[] = { + { + (char *)"default", /* X509 default parameters */ + 0, /* Check time */ + 0, /* internal flags */ + 0, /* flags */ + 0, /* purpose */ + 0, /* trust */ + 100, /* depth */ + NULL, /* policies */ + vpm_empty_id}, + { + (char *)"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}, + { + (char *)"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}, + { + (char *)"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}, + { + (char *)"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 param_cmp(const X509_VERIFY_PARAM **a, const X509_VERIFY_PARAM **b) +{ + return strcmp((*a)->name, (*b)->name); +} + +int X509_VERIFY_PARAM_add0_table(X509_VERIFY_PARAM *param) +{ + X509_VERIFY_PARAM *ptmp; + if (!param_table) { + param_table = sk_X509_VERIFY_PARAM_new(param_cmp); + if (!param_table) + return 0; + } else { + size_t idx; + + if (sk_X509_VERIFY_PARAM_find(param_table, &idx, param)) { + 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) +{ + X509_VERIFY_PARAM pm; + unsigned i, limit; + + pm.name = (char *)name; + if (param_table) { + size_t idx; + if (sk_X509_VERIFY_PARAM_find(param_table, &idx, &pm)) + return sk_X509_VERIFY_PARAM_value(param_table, idx); + } + + limit = sizeof(default_table) / sizeof(X509_VERIFY_PARAM); + for (i = 0; i < limit; i++) { + if (strcmp(default_table[i].name, name) == 0) { + return &default_table[i]; + } + } + return NULL; +} + +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/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509cset.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509cset.c new file mode 100644 index 0000000..2fd3f12 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509cset.c @@ -0,0 +1,170 @@ +/* + * 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 +#include +#include + +#include "../internal.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) +{ + size_t 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_CRL_up_ref(X509_CRL *crl) +{ + CRYPTO_refcount_inc(&crl->references); + 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/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509cset.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509cset.c.grpc_back new file mode 100644 index 0000000..2fd48a9 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509cset.c.grpc_back @@ -0,0 +1,170 @@ +/* + * 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 +#include +#include + +#include "../internal.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) +{ + size_t 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_CRL_up_ref(X509_CRL *crl) +{ + CRYPTO_refcount_inc(&crl->references); + 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/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509name.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509name.c new file mode 100644 index 0000000..eca5138 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509name.c @@ -0,0 +1,389 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 +#include +#include + +#include "../internal.h" + + +int X509_NAME_get_text_by_NID(X509_NAME *name, int nid, char *buf, int len) +{ + const 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, const 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); + OPENSSL_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) +{ + const 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, const 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 || loc < 0 + || sk_X509_NAME_ENTRY_num(name->entries) <= (size_t)loc) + 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 || loc < 0 + || sk_X509_NAME_ENTRY_num(name->entries) <= (size_t)loc) + 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)) { + OPENSSL_PUT_ERROR(X509, 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) { + OPENSSL_PUT_ERROR(X509, 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) +{ + const ASN1_OBJECT *obj = OBJ_nid2obj(nid); + if (obj == NULL) { + OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_NID); + return NULL; + } + return X509_NAME_ENTRY_create_by_OBJ(ne, obj, type, bytes, len); +} + +X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_OBJ(X509_NAME_ENTRY **ne, + const 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, const ASN1_OBJECT *obj) +{ + if ((ne == NULL) || (obj == NULL)) { + OPENSSL_PUT_ERROR(X509, 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/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509name.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509name.c.grpc_back new file mode 100644 index 0000000..610de5f --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509name.c.grpc_back @@ -0,0 +1,389 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 +#include +#include + +#include "../internal.h" + + +int X509_NAME_get_text_by_NID(X509_NAME *name, int nid, char *buf, int len) +{ + const 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, const 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); + OPENSSL_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) +{ + const 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, const 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 || loc < 0 + || sk_X509_NAME_ENTRY_num(name->entries) <= (size_t)loc) + 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 || loc < 0 + || sk_X509_NAME_ENTRY_num(name->entries) <= (size_t)loc) + 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)) { + OPENSSL_PUT_ERROR(X509, 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) { + OPENSSL_PUT_ERROR(X509, 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) +{ + const ASN1_OBJECT *obj = OBJ_nid2obj(nid); + if (obj == NULL) { + OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_NID); + return NULL; + } + return X509_NAME_ENTRY_create_by_OBJ(ne, obj, type, bytes, len); +} + +X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_OBJ(X509_NAME_ENTRY **ne, + const 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, const ASN1_OBJECT *obj) +{ + if ((ne == NULL) || (obj == NULL)) { + OPENSSL_PUT_ERROR(X509, 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/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509rset.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509rset.c new file mode 100644 index 0000000..d364ede --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509rset.c @@ -0,0 +1,81 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 + +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/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509rset.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509rset.c.grpc_back new file mode 100644 index 0000000..c4e6683 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509rset.c.grpc_back @@ -0,0 +1,81 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 + +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/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509spki.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509spki.c new file mode 100644 index 0000000..2df5ef6 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509spki.c @@ -0,0 +1,137 @@ +/* + * 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 +#include + +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; + size_t spki_len; + NETSCAPE_SPKI *spki; + if (len <= 0) + len = strlen(str); + if (!EVP_DecodedLength(&spki_len, len)) { + OPENSSL_PUT_ERROR(X509, X509_R_BASE64_DECODE_ERROR); + return NULL; + } + if (!(spki_der = OPENSSL_malloc(spki_len))) { + OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); + return NULL; + } + if (!EVP_DecodeBase64 + (spki_der, &spki_len, spki_len, (const uint8_t *)str, len)) { + OPENSSL_PUT_ERROR(X509, 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; + size_t b64_len; + int der_len; + der_len = i2d_NETSCAPE_SPKI(spki, NULL); + if (!EVP_EncodedLength(&b64_len, der_len)) { + OPENSSL_PUT_ERROR(X509, ERR_R_OVERFLOW); + return NULL; + } + der_spki = OPENSSL_malloc(der_len); + if (der_spki == NULL) { + OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); + return NULL; + } + b64_str = OPENSSL_malloc(b64_len); + if (b64_str == NULL) { + OPENSSL_free(der_spki); + OPENSSL_PUT_ERROR(X509, 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/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509spki.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509spki.c.grpc_back new file mode 100644 index 0000000..4a9b95e --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x509spki.c.grpc_back @@ -0,0 +1,137 @@ +/* + * 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 +#include + +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; + size_t spki_len; + NETSCAPE_SPKI *spki; + if (len <= 0) + len = strlen(str); + if (!EVP_DecodedLength(&spki_len, len)) { + OPENSSL_PUT_ERROR(X509, X509_R_BASE64_DECODE_ERROR); + return NULL; + } + if (!(spki_der = OPENSSL_malloc(spki_len))) { + OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); + return NULL; + } + if (!EVP_DecodeBase64 + (spki_der, &spki_len, spki_len, (const uint8_t *)str, len)) { + OPENSSL_PUT_ERROR(X509, 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; + size_t b64_len; + int der_len; + der_len = i2d_NETSCAPE_SPKI(spki, NULL); + if (!EVP_EncodedLength(&b64_len, der_len)) { + OPENSSL_PUT_ERROR(X509, ERR_R_OVERFLOW); + return NULL; + } + der_spki = OPENSSL_malloc(der_len); + if (der_spki == NULL) { + OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); + return NULL; + } + b64_str = OPENSSL_malloc(b64_len); + if (b64_str == NULL) { + OPENSSL_free(der_spki); + OPENSSL_PUT_ERROR(X509, 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/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x_algor.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x_algor.c new file mode 100644 index 0000000..8863b78 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x_algor.c @@ -0,0 +1,151 @@ +/* + * 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 +#include +#include +#include + + +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_ASN1_SET_OF(X509_ALGOR) + +int X509_ALGOR_set0(X509_ALGOR *alg, const 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 = (ASN1_OBJECT *)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(const ASN1_OBJECT **paobj, int *pptype, const void **ppval, + const 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 (EVP_MD_flags(md) & 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); + +} + +/* + * X509_ALGOR_cmp returns 0 if |a| and |b| are equal and non-zero otherwise. + */ +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); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x_algor.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x_algor.c.grpc_back new file mode 100644 index 0000000..13c9a8c --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x_algor.c.grpc_back @@ -0,0 +1,151 @@ +/* + * 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 +#include +#include +#include + + +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_ASN1_SET_OF(X509_ALGOR) + +int X509_ALGOR_set0(X509_ALGOR *alg, const 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 = (ASN1_OBJECT *)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(const ASN1_OBJECT **paobj, int *pptype, const void **ppval, + const 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 (EVP_MD_flags(md) & 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); + +} + +/* + * X509_ALGOR_cmp returns 0 if |a| and |b| are equal and non-zero otherwise. + */ +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); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x_all.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x_all.c new file mode 100644 index 0000000..8ea59dd --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x_all.c @@ -0,0 +1,501 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 +#include +#include +#include + +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 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_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 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)); +} + +int NETSCAPE_SPKI_verify(NETSCAPE_SPKI *x, EVP_PKEY *pkey) +{ + return (ASN1_item_verify(ASN1_ITEM_rptr(NETSCAPE_SPKAC), x->sig_algor, + x->signature, x->spkac, pkey)); +} + +#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 +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_FP_API +RSA *d2i_RSAPrivateKey_fp(FILE *fp, RSA **rsa) +{ + return ASN1_d2i_fp_of(RSA, RSA_new, d2i_RSAPrivateKey, fp, rsa); +} + +int i2d_RSAPrivateKey_fp(FILE *fp, RSA *rsa) +{ + return ASN1_i2d_fp_of_const(RSA, i2d_RSAPrivateKey, fp, rsa); +} + +RSA *d2i_RSAPublicKey_fp(FILE *fp, RSA **rsa) +{ + return ASN1_d2i_fp_of(RSA, RSA_new, d2i_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_i2d_fp_of_const(RSA, i2d_RSAPublicKey, fp, rsa); +} + +int i2d_RSA_PUBKEY_fp(FILE *fp, RSA *rsa) +{ + return ASN1_i2d_fp((I2D_OF_const(void))i2d_RSA_PUBKEY, fp, rsa); +} +#endif + +RSA *d2i_RSAPrivateKey_bio(BIO *bp, RSA **rsa) +{ + return ASN1_d2i_bio_of(RSA, RSA_new, d2i_RSAPrivateKey, bp, rsa); +} + +int i2d_RSAPrivateKey_bio(BIO *bp, RSA *rsa) +{ + return ASN1_i2d_bio_of_const(RSA, i2d_RSAPrivateKey, bp, rsa); +} + +RSA *d2i_RSAPublicKey_bio(BIO *bp, RSA **rsa) +{ + return ASN1_d2i_bio_of(RSA, RSA_new, d2i_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_i2d_bio_of_const(RSA, i2d_RSAPublicKey, bp, rsa); +} + +int i2d_RSA_PUBKEY_bio(BIO *bp, RSA *rsa) +{ + return ASN1_i2d_bio_of_const(RSA, i2d_RSA_PUBKEY, bp, rsa); +} + +#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_const(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_const(DSA, i2d_DSA_PUBKEY, bp, dsa); +} + +#endif + +#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_const(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_const(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_const(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_const(EC_KEY, i2d_ECPrivateKey, bp, eckey); +} + +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)); +} + +#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_const(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_const(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); +} + +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; +} +#endif + +int i2d_PrivateKey_bio(BIO *bp, EVP_PKEY *pkey) +{ + return ASN1_i2d_bio_of_const(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_const(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); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x_all.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x_all.c.grpc_back new file mode 100644 index 0000000..c430a7d --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x_all.c.grpc_back @@ -0,0 +1,501 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 +#include +#include +#include + +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 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_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 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)); +} + +int NETSCAPE_SPKI_verify(NETSCAPE_SPKI *x, EVP_PKEY *pkey) +{ + return (ASN1_item_verify(ASN1_ITEM_rptr(NETSCAPE_SPKAC), x->sig_algor, + x->signature, x->spkac, pkey)); +} + +#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 +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_FP_API +RSA *d2i_RSAPrivateKey_fp(FILE *fp, RSA **rsa) +{ + return ASN1_d2i_fp_of(RSA, RSA_new, d2i_RSAPrivateKey, fp, rsa); +} + +int i2d_RSAPrivateKey_fp(FILE *fp, RSA *rsa) +{ + return ASN1_i2d_fp_of_const(RSA, i2d_RSAPrivateKey, fp, rsa); +} + +RSA *d2i_RSAPublicKey_fp(FILE *fp, RSA **rsa) +{ + return ASN1_d2i_fp_of(RSA, RSA_new, d2i_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_i2d_fp_of_const(RSA, i2d_RSAPublicKey, fp, rsa); +} + +int i2d_RSA_PUBKEY_fp(FILE *fp, RSA *rsa) +{ + return ASN1_i2d_fp((I2D_OF_const(void))i2d_RSA_PUBKEY, fp, rsa); +} +#endif + +RSA *d2i_RSAPrivateKey_bio(BIO *bp, RSA **rsa) +{ + return ASN1_d2i_bio_of(RSA, RSA_new, d2i_RSAPrivateKey, bp, rsa); +} + +int i2d_RSAPrivateKey_bio(BIO *bp, RSA *rsa) +{ + return ASN1_i2d_bio_of_const(RSA, i2d_RSAPrivateKey, bp, rsa); +} + +RSA *d2i_RSAPublicKey_bio(BIO *bp, RSA **rsa) +{ + return ASN1_d2i_bio_of(RSA, RSA_new, d2i_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_i2d_bio_of_const(RSA, i2d_RSAPublicKey, bp, rsa); +} + +int i2d_RSA_PUBKEY_bio(BIO *bp, RSA *rsa) +{ + return ASN1_i2d_bio_of_const(RSA, i2d_RSA_PUBKEY, bp, rsa); +} + +#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_const(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_const(DSA, i2d_DSA_PUBKEY, bp, dsa); +} + +#endif + +#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_const(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_const(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_const(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_const(EC_KEY, i2d_ECPrivateKey, bp, eckey); +} + +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)); +} + +#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_const(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_const(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); +} + +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; +} +#endif + +int i2d_PrivateKey_bio(BIO *bp, EVP_PKEY *pkey) +{ + return ASN1_i2d_bio_of_const(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_const(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); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x_attrib.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x_attrib.c new file mode 100644 index 0000000..1e7f845 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x_attrib.c @@ -0,0 +1,111 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 + +/* + * 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); + /* TODO(fork): const correctness. */ + ret->object = (ASN1_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); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x_attrib.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x_attrib.c.grpc_back new file mode 100644 index 0000000..de8c95c --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x_attrib.c.grpc_back @@ -0,0 +1,111 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 + +/* + * 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); + /* TODO(fork): const correctness. */ + ret->object = (ASN1_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); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x_crl.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x_crl.c new file mode 100644 index 0000000..b1ba6fb --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x_crl.c @@ -0,0 +1,541 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 +#include +#include +#include +#include +#include + +#include "../internal.h" + +/* + * 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); +}; + +static int X509_REVOKED_cmp(const X509_REVOKED **a, const X509_REVOKED **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 const 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) +{ + + size_t i, k; + int 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 (k = 0; k < sk_X509_EXTENSION_num(exts); k++) { + ext = sk_X509_EXTENSION_value(exts, k); + 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; + size_t 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: + X509_CRL_digest(crl, EVP_sha1(), crl->sha1_hash, NULL); + 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: + /* |crl->meth| may be NULL if constructing the object failed before + * |ASN1_OP_NEW_POST| was run. */ + if (crl->meth && 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) = { + 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 **a, const X509_REVOKED **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)) { + OPENSSL_PUT_ERROR(X509, 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) +{ + size_t 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 struct CRYPTO_STATIC_MUTEX g_crl_sort_lock = CRYPTO_STATIC_MUTEX_INIT; + +static int def_crl_lookup(X509_CRL *crl, + X509_REVOKED **ret, ASN1_INTEGER *serial, + X509_NAME *issuer) +{ + X509_REVOKED rtmp, *rev; + size_t idx; + rtmp.serialNumber = serial; + /* + * Sort revoked into serial number order if not already sorted. Do this + * under a lock to avoid race condition. + */ + + CRYPTO_STATIC_MUTEX_lock_read(&g_crl_sort_lock); + const int is_sorted = sk_X509_REVOKED_is_sorted(crl->crl->revoked); + CRYPTO_STATIC_MUTEX_unlock_read(&g_crl_sort_lock); + + if (!is_sorted) { + CRYPTO_STATIC_MUTEX_lock_write(&g_crl_sort_lock); + if (!sk_X509_REVOKED_is_sorted(crl->crl->revoked)) { + sk_X509_REVOKED_sort(crl->crl->revoked); + } + CRYPTO_STATIC_MUTEX_unlock_write(&g_crl_sort_lock); + } + + if (!sk_X509_REVOKED_find(crl->crl->revoked, &idx, &rtmp)) + 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_ASN1_SET_OF(X509_REVOKED) + +IMPLEMENT_ASN1_SET_OF(X509_CRL) diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x_crl.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x_crl.c.grpc_back new file mode 100644 index 0000000..6450e84 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x_crl.c.grpc_back @@ -0,0 +1,541 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 +#include +#include +#include +#include +#include + +#include "../internal.h" + +/* + * 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); +}; + +static int X509_REVOKED_cmp(const X509_REVOKED **a, const X509_REVOKED **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 const 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) +{ + + size_t i, k; + int 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 (k = 0; k < sk_X509_EXTENSION_num(exts); k++) { + ext = sk_X509_EXTENSION_value(exts, k); + 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; + size_t 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: + X509_CRL_digest(crl, EVP_sha1(), crl->sha1_hash, NULL); + 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: + /* |crl->meth| may be NULL if constructing the object failed before + * |ASN1_OP_NEW_POST| was run. */ + if (crl->meth && 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) = { + 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 **a, const X509_REVOKED **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)) { + OPENSSL_PUT_ERROR(X509, 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) +{ + size_t 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 struct CRYPTO_STATIC_MUTEX g_crl_sort_lock = CRYPTO_STATIC_MUTEX_INIT; + +static int def_crl_lookup(X509_CRL *crl, + X509_REVOKED **ret, ASN1_INTEGER *serial, + X509_NAME *issuer) +{ + X509_REVOKED rtmp, *rev; + size_t idx; + rtmp.serialNumber = serial; + /* + * Sort revoked into serial number order if not already sorted. Do this + * under a lock to avoid race condition. + */ + + CRYPTO_STATIC_MUTEX_lock_read(&g_crl_sort_lock); + const int is_sorted = sk_X509_REVOKED_is_sorted(crl->crl->revoked); + CRYPTO_STATIC_MUTEX_unlock_read(&g_crl_sort_lock); + + if (!is_sorted) { + CRYPTO_STATIC_MUTEX_lock_write(&g_crl_sort_lock); + if (!sk_X509_REVOKED_is_sorted(crl->crl->revoked)) { + sk_X509_REVOKED_sort(crl->crl->revoked); + } + CRYPTO_STATIC_MUTEX_unlock_write(&g_crl_sort_lock); + } + + if (!sk_X509_REVOKED_find(crl->crl->revoked, &idx, &rtmp)) + 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_ASN1_SET_OF(X509_REVOKED) + +IMPLEMENT_ASN1_SET_OF(X509_CRL) diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x_exten.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x_exten.c new file mode 100644 index 0000000..ca653e8 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x_exten.c @@ -0,0 +1,75 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 + + +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) diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x_exten.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x_exten.c.grpc_back new file mode 100644 index 0000000..36403e4 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x_exten.c.grpc_back @@ -0,0 +1,75 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 + + +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) diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x_info.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x_info.c new file mode 100644 index 0000000..4217eb1 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x_info.c @@ -0,0 +1,98 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 + +X509_INFO *X509_INFO_new(void) +{ + X509_INFO *ret = NULL; + + ret = (X509_INFO *)OPENSSL_malloc(sizeof(X509_INFO)); + if (ret == NULL) { + OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); + return (NULL); + } + + ret->enc_cipher.cipher = NULL; + ret->enc_len = 0; + ret->enc_data = NULL; + + ret->x509 = NULL; + ret->crl = NULL; + ret->x_pkey = NULL; + return (ret); +} + +void X509_INFO_free(X509_INFO *x) +{ + if (x == NULL) + return; + + 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); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x_info.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x_info.c.grpc_back new file mode 100644 index 0000000..177cd0e --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x_info.c.grpc_back @@ -0,0 +1,98 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 + +X509_INFO *X509_INFO_new(void) +{ + X509_INFO *ret = NULL; + + ret = (X509_INFO *)OPENSSL_malloc(sizeof(X509_INFO)); + if (ret == NULL) { + OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); + return (NULL); + } + + ret->enc_cipher.cipher = NULL; + ret->enc_len = 0; + ret->enc_data = NULL; + + ret->x509 = NULL; + ret->crl = NULL; + ret->x_pkey = NULL; + return (ret); +} + +void X509_INFO_free(X509_INFO *x) +{ + if (x == NULL) + return; + + 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); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x_name.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x_name.c new file mode 100644 index 0000000..5775c56 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x_name.c @@ -0,0 +1,554 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 +#include +#include +#include +#include +#include + +#include "../asn1/asn1_locl.h" +#include "../internal.h" + + +typedef STACK_OF(X509_NAME_ENTRY) STACK_OF_X509_NAME_ENTRY; +DEFINE_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); + +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. + */ + +static 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, + NULL, +}; + +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: + OPENSSL_PUT_ERROR(X509, 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 + }; + size_t i, j; + int ret; + STACK_OF(X509_NAME_ENTRY) *entries; + X509_NAME_ENTRY *entry; + /* Bound the size of an X509_NAME we are willing to parse. */ + 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; + OPENSSL_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; + (void)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); + OPENSSL_PUT_ERROR(X509, ERR_R_ASN1_LIB); + 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) { + OPENSSL_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 set = -1; + size_t i; + 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); + OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); + return -1; +} + +/* + * 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 + * OPENSSL_memcmp() of the canonical encoding. By omitting the leading SEQUENCE name + * constraints of type dirName can also be checked with a simple OPENSSL_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 set = -1, ret = 0, len; + size_t i; + + 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 == NULL) + 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 */ + + len = i2d_name_canon(intname, NULL); + if (len < 0) { + goto err; + } + a->canon_enclen = len; + + 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; + + /* Ignore trailing spaces */ + while ((len > 0) && !(to[-1] & 0x80) && isspace(to[-1])) { + 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++ = OPENSSL_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 len, ltmp; + size_t i; + 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_ASN1_SET_OF(X509_NAME_ENTRY) + +int X509_NAME_ENTRY_set(const X509_NAME_ENTRY *ne) +{ + return ne->set; +} + +int X509_NAME_get0_der(X509_NAME *nm, const unsigned char **pder, + size_t *pderlen) +{ + /* Make sure encoding is valid */ + if (i2d_X509_NAME(nm, NULL) <= 0) + return 0; + if (pder != NULL) + *pder = (unsigned char *)nm->bytes->data; + if (pderlen != NULL) + *pderlen = nm->bytes->length; + return 1; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x_name.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x_name.c.grpc_back new file mode 100644 index 0000000..7824100 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x_name.c.grpc_back @@ -0,0 +1,554 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 +#include +#include +#include +#include +#include + +#include "../asn1/asn1_locl.h" +#include "../internal.h" + + +typedef STACK_OF(X509_NAME_ENTRY) STACK_OF_X509_NAME_ENTRY; +DEFINE_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); + +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. + */ + +static 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, + NULL, +}; + +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: + OPENSSL_PUT_ERROR(X509, 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 + }; + size_t i, j; + int ret; + STACK_OF(X509_NAME_ENTRY) *entries; + X509_NAME_ENTRY *entry; + /* Bound the size of an X509_NAME we are willing to parse. */ + 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; + OPENSSL_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; + (void)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); + OPENSSL_PUT_ERROR(X509, ERR_R_ASN1_LIB); + 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) { + OPENSSL_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 set = -1; + size_t i; + 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); + OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); + return -1; +} + +/* + * 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 + * OPENSSL_memcmp() of the canonical encoding. By omitting the leading SEQUENCE name + * constraints of type dirName can also be checked with a simple OPENSSL_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 set = -1, ret = 0, len; + size_t i; + + 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 == NULL) + 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 */ + + len = i2d_name_canon(intname, NULL); + if (len < 0) { + goto err; + } + a->canon_enclen = len; + + 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; + + /* Ignore trailing spaces */ + while ((len > 0) && !(to[-1] & 0x80) && isspace(to[-1])) { + 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++ = OPENSSL_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 len, ltmp; + size_t i; + 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_ASN1_SET_OF(X509_NAME_ENTRY) + +int X509_NAME_ENTRY_set(const X509_NAME_ENTRY *ne) +{ + return ne->set; +} + +int X509_NAME_get0_der(X509_NAME *nm, const unsigned char **pder, + size_t *pderlen) +{ + /* Make sure encoding is valid */ + if (i2d_X509_NAME(nm, NULL) <= 0) + return 0; + if (pder != NULL) + *pder = (unsigned char *)nm->bytes->data; + if (pderlen != NULL) + *pderlen = nm->bytes->length; + return 1; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x_pkey.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x_pkey.c new file mode 100644 index 0000000..126560d --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x_pkey.c @@ -0,0 +1,106 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 +#include + +#include "../internal.h" + + +X509_PKEY *X509_PKEY_new(void) +{ + X509_PKEY *ret = OPENSSL_malloc(sizeof(X509_PKEY)); + if (ret == NULL) { + OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); + goto err; + } + OPENSSL_memset(ret, 0, sizeof(X509_PKEY)); + + ret->enc_algor = X509_ALGOR_new(); + if (ret->enc_algor == NULL) + goto err; + ret->enc_pkey = M_ASN1_OCTET_STRING_new(); + if (ret->enc_pkey == NULL) + goto err; + return ret; + + err: + if (ret != NULL) + X509_PKEY_free(ret); + return NULL; +} + +void X509_PKEY_free(X509_PKEY *x) +{ + if (x == NULL) + return; + + 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); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x_pkey.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x_pkey.c.grpc_back new file mode 100644 index 0000000..8231a24 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x_pkey.c.grpc_back @@ -0,0 +1,106 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 +#include + +#include "../internal.h" + + +X509_PKEY *X509_PKEY_new(void) +{ + X509_PKEY *ret = OPENSSL_malloc(sizeof(X509_PKEY)); + if (ret == NULL) { + OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); + goto err; + } + OPENSSL_memset(ret, 0, sizeof(X509_PKEY)); + + ret->enc_algor = X509_ALGOR_new(); + if (ret->enc_algor == NULL) + goto err; + ret->enc_pkey = M_ASN1_OCTET_STRING_new(); + if (ret->enc_pkey == NULL) + goto err; + return ret; + + err: + if (ret != NULL) + X509_PKEY_free(ret); + return NULL; +} + +void X509_PKEY_free(X509_PKEY *x) +{ + if (x == NULL) + return; + + 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); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x_pubkey.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x_pubkey.c new file mode 100644 index 0000000..a948854 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x_pubkey.c @@ -0,0 +1,368 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 +#include +#include +#include +#include +#include + +#include "../internal.h" + +/* 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; + uint8_t *spki = NULL; + size_t spki_len; + + if (x == NULL) + return (0); + + CBB cbb; + if (!CBB_init(&cbb, 0) || + !EVP_marshal_public_key(&cbb, pkey) || + !CBB_finish(&cbb, &spki, &spki_len) || + spki_len > LONG_MAX) { + CBB_cleanup(&cbb); + OPENSSL_PUT_ERROR(X509, X509_R_PUBLIC_KEY_ENCODE_ERROR); + goto error; + } + + const uint8_t *p = spki; + pk = d2i_X509_PUBKEY(NULL, &p, (long)spki_len); + if (pk == NULL || p != spki + spki_len) { + OPENSSL_PUT_ERROR(X509, X509_R_PUBLIC_KEY_DECODE_ERROR); + goto error; + } + + OPENSSL_free(spki); + X509_PUBKEY_free(*x); + *x = pk; + + return 1; + error: + X509_PUBKEY_free(pk); + OPENSSL_free(spki); + return 0; +} + +/* g_pubkey_lock is used to protect the initialisation of the |pkey| member of + * |X509_PUBKEY| objects. Really |X509_PUBKEY| should have a |CRYPTO_once_t| + * inside it for this, but |CRYPTO_once_t| is private and |X509_PUBKEY| is + * not. */ +static struct CRYPTO_STATIC_MUTEX g_pubkey_lock = CRYPTO_STATIC_MUTEX_INIT; + +EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key) +{ + EVP_PKEY *ret = NULL; + uint8_t *spki = NULL; + + if (key == NULL) + goto error; + + CRYPTO_STATIC_MUTEX_lock_read(&g_pubkey_lock); + if (key->pkey != NULL) { + CRYPTO_STATIC_MUTEX_unlock_read(&g_pubkey_lock); + EVP_PKEY_up_ref(key->pkey); + return key->pkey; + } + CRYPTO_STATIC_MUTEX_unlock_read(&g_pubkey_lock); + + /* Re-encode the |X509_PUBKEY| to DER and parse it. */ + int spki_len = i2d_X509_PUBKEY(key, &spki); + if (spki_len < 0) { + goto error; + } + CBS cbs; + CBS_init(&cbs, spki, (size_t)spki_len); + ret = EVP_parse_public_key(&cbs); + if (ret == NULL || CBS_len(&cbs) != 0) { + OPENSSL_PUT_ERROR(X509, X509_R_PUBLIC_KEY_DECODE_ERROR); + goto error; + } + + /* Check to see if another thread set key->pkey first */ + CRYPTO_STATIC_MUTEX_lock_write(&g_pubkey_lock); + if (key->pkey) { + CRYPTO_STATIC_MUTEX_unlock_write(&g_pubkey_lock); + EVP_PKEY_free(ret); + ret = key->pkey; + } else { + key->pkey = ret; + CRYPTO_STATIC_MUTEX_unlock_write(&g_pubkey_lock); + } + + OPENSSL_free(spki); + EVP_PKEY_up_ref(ret); + return ret; + + error: + OPENSSL_free(spki); + 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; + xpk = d2i_X509_PUBKEY(NULL, pp, length); + if (!xpk) + return NULL; + pktmp = X509_PUBKEY_get(xpk); + X509_PUBKEY_free(xpk); + if (!pktmp) + return NULL; + if (a) { + EVP_PKEY_free(*a); + *a = pktmp; + } + return pktmp; +} + +int i2d_PUBKEY(const EVP_PKEY *a, unsigned char **pp) +{ + X509_PUBKEY *xpk = NULL; + int ret; + if (!a) + return 0; + if (!X509_PUBKEY_set(&xpk, (EVP_PKEY *)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 + */ +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(const RSA *a, unsigned char **pp) +{ + EVP_PKEY *pktmp; + int ret; + if (!a) + return 0; + pktmp = EVP_PKEY_new(); + if (!pktmp) { + OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); + return 0; + } + EVP_PKEY_set1_RSA(pktmp, (RSA *)a); + ret = i2d_PUBKEY(pktmp, pp); + EVP_PKEY_free(pktmp); + return ret; +} + +#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(const DSA *a, unsigned char **pp) +{ + EVP_PKEY *pktmp; + int ret; + if (!a) + return 0; + pktmp = EVP_PKEY_new(); + if (!pktmp) { + OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); + return 0; + } + EVP_PKEY_set1_DSA(pktmp, (DSA *)a); + ret = i2d_PUBKEY(pktmp, pp); + EVP_PKEY_free(pktmp); + return ret; +} +#endif + +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(const EC_KEY *a, unsigned char **pp) +{ + EVP_PKEY *pktmp; + int ret; + if (!a) + return (0); + if ((pktmp = EVP_PKEY_new()) == NULL) { + OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); + return (0); + } + EVP_PKEY_set1_EC_KEY(pktmp, (EC_KEY *)a); + ret = i2d_PUBKEY(pktmp, pp); + EVP_PKEY_free(pktmp); + return (ret); +} + +int X509_PUBKEY_set0_param(X509_PUBKEY *pub, const 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; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x_pubkey.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x_pubkey.c.grpc_back new file mode 100644 index 0000000..3d07d66 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x_pubkey.c.grpc_back @@ -0,0 +1,368 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 +#include +#include +#include +#include +#include + +#include "../internal.h" + +/* 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; + uint8_t *spki = NULL; + size_t spki_len; + + if (x == NULL) + return (0); + + CBB cbb; + if (!CBB_init(&cbb, 0) || + !EVP_marshal_public_key(&cbb, pkey) || + !CBB_finish(&cbb, &spki, &spki_len) || + spki_len > LONG_MAX) { + CBB_cleanup(&cbb); + OPENSSL_PUT_ERROR(X509, X509_R_PUBLIC_KEY_ENCODE_ERROR); + goto error; + } + + const uint8_t *p = spki; + pk = d2i_X509_PUBKEY(NULL, &p, (long)spki_len); + if (pk == NULL || p != spki + spki_len) { + OPENSSL_PUT_ERROR(X509, X509_R_PUBLIC_KEY_DECODE_ERROR); + goto error; + } + + OPENSSL_free(spki); + X509_PUBKEY_free(*x); + *x = pk; + + return 1; + error: + X509_PUBKEY_free(pk); + OPENSSL_free(spki); + return 0; +} + +/* g_pubkey_lock is used to protect the initialisation of the |pkey| member of + * |X509_PUBKEY| objects. Really |X509_PUBKEY| should have a |CRYPTO_once_t| + * inside it for this, but |CRYPTO_once_t| is private and |X509_PUBKEY| is + * not. */ +static struct CRYPTO_STATIC_MUTEX g_pubkey_lock = CRYPTO_STATIC_MUTEX_INIT; + +EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key) +{ + EVP_PKEY *ret = NULL; + uint8_t *spki = NULL; + + if (key == NULL) + goto error; + + CRYPTO_STATIC_MUTEX_lock_read(&g_pubkey_lock); + if (key->pkey != NULL) { + CRYPTO_STATIC_MUTEX_unlock_read(&g_pubkey_lock); + EVP_PKEY_up_ref(key->pkey); + return key->pkey; + } + CRYPTO_STATIC_MUTEX_unlock_read(&g_pubkey_lock); + + /* Re-encode the |X509_PUBKEY| to DER and parse it. */ + int spki_len = i2d_X509_PUBKEY(key, &spki); + if (spki_len < 0) { + goto error; + } + CBS cbs; + CBS_init(&cbs, spki, (size_t)spki_len); + ret = EVP_parse_public_key(&cbs); + if (ret == NULL || CBS_len(&cbs) != 0) { + OPENSSL_PUT_ERROR(X509, X509_R_PUBLIC_KEY_DECODE_ERROR); + goto error; + } + + /* Check to see if another thread set key->pkey first */ + CRYPTO_STATIC_MUTEX_lock_write(&g_pubkey_lock); + if (key->pkey) { + CRYPTO_STATIC_MUTEX_unlock_write(&g_pubkey_lock); + EVP_PKEY_free(ret); + ret = key->pkey; + } else { + key->pkey = ret; + CRYPTO_STATIC_MUTEX_unlock_write(&g_pubkey_lock); + } + + OPENSSL_free(spki); + EVP_PKEY_up_ref(ret); + return ret; + + error: + OPENSSL_free(spki); + 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; + xpk = d2i_X509_PUBKEY(NULL, pp, length); + if (!xpk) + return NULL; + pktmp = X509_PUBKEY_get(xpk); + X509_PUBKEY_free(xpk); + if (!pktmp) + return NULL; + if (a) { + EVP_PKEY_free(*a); + *a = pktmp; + } + return pktmp; +} + +int i2d_PUBKEY(const EVP_PKEY *a, unsigned char **pp) +{ + X509_PUBKEY *xpk = NULL; + int ret; + if (!a) + return 0; + if (!X509_PUBKEY_set(&xpk, (EVP_PKEY *)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 + */ +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(const RSA *a, unsigned char **pp) +{ + EVP_PKEY *pktmp; + int ret; + if (!a) + return 0; + pktmp = EVP_PKEY_new(); + if (!pktmp) { + OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); + return 0; + } + EVP_PKEY_set1_RSA(pktmp, (RSA *)a); + ret = i2d_PUBKEY(pktmp, pp); + EVP_PKEY_free(pktmp); + return ret; +} + +#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(const DSA *a, unsigned char **pp) +{ + EVP_PKEY *pktmp; + int ret; + if (!a) + return 0; + pktmp = EVP_PKEY_new(); + if (!pktmp) { + OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); + return 0; + } + EVP_PKEY_set1_DSA(pktmp, (DSA *)a); + ret = i2d_PUBKEY(pktmp, pp); + EVP_PKEY_free(pktmp); + return ret; +} +#endif + +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(const EC_KEY *a, unsigned char **pp) +{ + EVP_PKEY *pktmp; + int ret; + if (!a) + return (0); + if ((pktmp = EVP_PKEY_new()) == NULL) { + OPENSSL_PUT_ERROR(X509, ERR_R_MALLOC_FAILURE); + return (0); + } + EVP_PKEY_set1_EC_KEY(pktmp, (EC_KEY *)a); + ret = i2d_PUBKEY(pktmp, pp); + EVP_PKEY_free(pktmp); + return (ret); +} + +int X509_PUBKEY_set0_param(X509_PUBKEY *pub, const 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; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x_req.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x_req.c new file mode 100644 index 0000000..a19775a --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x_req.c @@ -0,0 +1,109 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 + +/* + * 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) = { + 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) diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x_req.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x_req.c.grpc_back new file mode 100644 index 0000000..5dfe19e --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x_req.c.grpc_back @@ -0,0 +1,109 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 + +/* + * 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) = { + 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) diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x_sig.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x_sig.c new file mode 100644 index 0000000..b3c5ea5 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x_sig.c @@ -0,0 +1,69 @@ +/* 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 +#include + + +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) diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x_sig.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x_sig.c.grpc_back new file mode 100644 index 0000000..e18024a --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x_sig.c.grpc_back @@ -0,0 +1,69 @@ +/* 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 +#include + + +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) diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x_spki.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x_spki.c new file mode 100644 index 0000000..2b05a41 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x_spki.c @@ -0,0 +1,80 @@ +/* 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 + + +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) diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x_spki.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x_spki.c.grpc_back new file mode 100644 index 0000000..86da6dd --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x_spki.c.grpc_back @@ -0,0 +1,80 @@ +/* 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 + + +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) diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x_val.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x_val.c new file mode 100644 index 0000000..797f71d --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x_val.c @@ -0,0 +1,69 @@ +/* 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 +#include + + +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) diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x_val.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x_val.c.grpc_back new file mode 100644 index 0000000..ad4f7e1 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x_val.c.grpc_back @@ -0,0 +1,69 @@ +/* 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 +#include + + +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) diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x_x509.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x_x509.c new file mode 100644 index 0000000..f774b7a --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x_x509.c @@ -0,0 +1,328 @@ +/* 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 +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../internal.h" + +static CRYPTO_EX_DATA_CLASS g_ex_data_class = CRYPTO_EX_DATA_CLASS_INIT; + +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->name = NULL; + ret->ex_flags = 0; + ret->ex_pathlen = -1; + ret->skid = NULL; + ret->akid = NULL; + ret->aux = NULL; + ret->crldp = NULL; + ret->buf = NULL; + CRYPTO_new_ex_data(&ret->ex_data); + CRYPTO_MUTEX_init(&ret->lock); + break; + + case ASN1_OP_D2I_PRE: + CRYPTO_BUFFER_free(ret->buf); + ret->buf = NULL; + 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_MUTEX_cleanup(&ret->lock); + CRYPTO_free_ex_data(&g_ex_data_class, 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); + CRYPTO_BUFFER_free(ret->buf); + OPENSSL_free(ret->name); + break; + + } + + return 1; + +} + +ASN1_SEQUENCE_ref(X509, x509_cb) = { + 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) + +X509 *X509_parse_from_buffer(CRYPTO_BUFFER *buf) { + if (CRYPTO_BUFFER_len(buf) > LONG_MAX) { + OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW); + return 0; + } + + X509 *x509 = X509_new(); + if (x509 == NULL) { + return NULL; + } + + x509->cert_info->enc.alias_only_on_next_parse = 1; + + const uint8_t *inp = CRYPTO_BUFFER_data(buf); + X509 *x509p = x509; + X509 *ret = d2i_X509(&x509p, &inp, CRYPTO_BUFFER_len(buf)); + if (ret == NULL || + inp - CRYPTO_BUFFER_data(buf) != (ptrdiff_t)CRYPTO_BUFFER_len(buf)) { + X509_free(x509p); + return NULL; + } + assert(x509p == x509); + assert(ret == x509); + + CRYPTO_BUFFER_up_ref(buf); + ret->buf = buf; + + return ret; +} + +int X509_up_ref(X509 *x) +{ + CRYPTO_refcount_inc(&x->references); + return 1; +} + +int X509_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused * unused, + CRYPTO_EX_dup *dup_unused, CRYPTO_EX_free *free_func) +{ + int index; + if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp, + free_func)) { + return -1; + } + return index; +} + +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 = *pp; + X509 *ret; + int freeret = 0; + + 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; + /* Parse auxiliary information if there is any. */ + 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; + + 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; +} + +void X509_get0_signature(const ASN1_BIT_STRING **psig, const 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); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x_x509.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x_x509.c.grpc_back new file mode 100644 index 0000000..01464a1 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x_x509.c.grpc_back @@ -0,0 +1,328 @@ +/* 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 +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../internal.h" + +static CRYPTO_EX_DATA_CLASS g_ex_data_class = CRYPTO_EX_DATA_CLASS_INIT; + +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->name = NULL; + ret->ex_flags = 0; + ret->ex_pathlen = -1; + ret->skid = NULL; + ret->akid = NULL; + ret->aux = NULL; + ret->crldp = NULL; + ret->buf = NULL; + CRYPTO_new_ex_data(&ret->ex_data); + CRYPTO_MUTEX_init(&ret->lock); + break; + + case ASN1_OP_D2I_PRE: + CRYPTO_BUFFER_free(ret->buf); + ret->buf = NULL; + 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_MUTEX_cleanup(&ret->lock); + CRYPTO_free_ex_data(&g_ex_data_class, 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); + CRYPTO_BUFFER_free(ret->buf); + OPENSSL_free(ret->name); + break; + + } + + return 1; + +} + +ASN1_SEQUENCE_ref(X509, x509_cb) = { + 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) + +X509 *X509_parse_from_buffer(CRYPTO_BUFFER *buf) { + if (CRYPTO_BUFFER_len(buf) > LONG_MAX) { + OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW); + return 0; + } + + X509 *x509 = X509_new(); + if (x509 == NULL) { + return NULL; + } + + x509->cert_info->enc.alias_only_on_next_parse = 1; + + const uint8_t *inp = CRYPTO_BUFFER_data(buf); + X509 *x509p = x509; + X509 *ret = d2i_X509(&x509p, &inp, CRYPTO_BUFFER_len(buf)); + if (ret == NULL || + inp - CRYPTO_BUFFER_data(buf) != (ptrdiff_t)CRYPTO_BUFFER_len(buf)) { + X509_free(x509p); + return NULL; + } + assert(x509p == x509); + assert(ret == x509); + + CRYPTO_BUFFER_up_ref(buf); + ret->buf = buf; + + return ret; +} + +int X509_up_ref(X509 *x) +{ + CRYPTO_refcount_inc(&x->references); + return 1; +} + +int X509_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused * unused, + CRYPTO_EX_dup *dup_unused, CRYPTO_EX_free *free_func) +{ + int index; + if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp, + free_func)) { + return -1; + } + return index; +} + +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 = *pp; + X509 *ret; + int freeret = 0; + + 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; + /* Parse auxiliary information if there is any. */ + 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; + + 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; +} + +void X509_get0_signature(const ASN1_BIT_STRING **psig, const 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); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x_x509a.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x_x509a.c new file mode 100644 index 0000000..e2ed356 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x_x509a.c @@ -0,0 +1,198 @@ +/* + * 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 +#include + +/* + * 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) +{ + ASN1_OBJECT *objtmp = OBJ_dup(obj); + if (objtmp == NULL) + goto err; + X509_CERT_AUX *aux = aux_get(x); + if (aux->trust == NULL) { + aux->trust = sk_ASN1_OBJECT_new_null(); + if (aux->trust == NULL) + goto err; + } + if (!sk_ASN1_OBJECT_push(aux->trust, objtmp)) + goto err; + return 1; + + err: + ASN1_OBJECT_free(objtmp); + return 0; +} + +int X509_add1_reject_object(X509 *x, ASN1_OBJECT *obj) +{ + ASN1_OBJECT *objtmp = OBJ_dup(obj); + if (objtmp == NULL) + goto err; + X509_CERT_AUX *aux = aux_get(x); + if (aux->reject == NULL) { + aux->reject = sk_ASN1_OBJECT_new_null(); + if (aux->reject == NULL) + goto err; + } + if (!sk_ASN1_OBJECT_push(aux->reject, objtmp)) + goto err; + return 1; + + 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; + } +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x_x509a.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x_x509a.c.grpc_back new file mode 100644 index 0000000..dccc46a --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509/x_x509a.c.grpc_back @@ -0,0 +1,198 @@ +/* + * 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 +#include + +/* + * 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) +{ + ASN1_OBJECT *objtmp = OBJ_dup(obj); + if (objtmp == NULL) + goto err; + X509_CERT_AUX *aux = aux_get(x); + if (aux->trust == NULL) { + aux->trust = sk_ASN1_OBJECT_new_null(); + if (aux->trust == NULL) + goto err; + } + if (!sk_ASN1_OBJECT_push(aux->trust, objtmp)) + goto err; + return 1; + + err: + ASN1_OBJECT_free(objtmp); + return 0; +} + +int X509_add1_reject_object(X509 *x, ASN1_OBJECT *obj) +{ + ASN1_OBJECT *objtmp = OBJ_dup(obj); + if (objtmp == NULL) + goto err; + X509_CERT_AUX *aux = aux_get(x); + if (aux->reject == NULL) { + aux->reject = sk_ASN1_OBJECT_new_null(); + if (aux->reject == NULL) + goto err; + } + if (!sk_ASN1_OBJECT_push(aux->reject, objtmp)) + goto err; + return 1; + + 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; + } +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/ext_dat.h b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/ext_dat.h new file mode 100644 index 0000000..78fa793 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/ext_dat.h @@ -0,0 +1,143 @@ +/* + * 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 */ + +#if defined(__cplusplus) +extern "C" { +#endif + +extern const X509V3_EXT_METHOD v3_bcons, v3_nscert, v3_key_usage, v3_ext_ku; +extern const X509V3_EXT_METHOD v3_pkey_usage_period, v3_sxnet, v3_info, + v3_sinfo; +extern const X509V3_EXT_METHOD v3_ns_ia5_list[], v3_alt[], v3_skey_id, + v3_akey_id; +extern const X509V3_EXT_METHOD v3_crl_num, v3_crl_reason, v3_crl_invdate; +extern const X509V3_EXT_METHOD v3_delta_crl, v3_cpols, v3_crld, + v3_freshest_crl; +extern const X509V3_EXT_METHOD v3_ocsp_nonce, v3_ocsp_accresp, + v3_ocsp_acutoff; +extern const X509V3_EXT_METHOD v3_ocsp_crlid, v3_ocsp_nocheck, + v3_ocsp_serviceloc; +extern const X509V3_EXT_METHOD v3_crl_hold, v3_pci; +extern const X509V3_EXT_METHOD v3_policy_mappings, v3_policy_constraints; +extern const X509V3_EXT_METHOD v3_name_constraints, v3_inhibit_anyp, v3_idp; +extern const X509V3_EXT_METHOD v3_addr, v3_asid; + +/* + * This table will be searched using OBJ_bsearch so it *must* kept in order + * of the ext_nid values. + */ + +/* TODO(fork): OCSP support */ +#define OPENSSL_NO_OCSP + +static const X509V3_EXT_METHOD *const 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_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, +}; + +/* Number of standard extensions */ + +#define STANDARD_EXTENSION_COUNT (sizeof(standard_exts)/sizeof(X509V3_EXT_METHOD *)) + +#if defined(__cplusplus) +} /* extern C */ +#endif diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/ext_dat.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/ext_dat.h.grpc_back new file mode 100644 index 0000000..78fa793 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/ext_dat.h.grpc_back @@ -0,0 +1,143 @@ +/* + * 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 */ + +#if defined(__cplusplus) +extern "C" { +#endif + +extern const X509V3_EXT_METHOD v3_bcons, v3_nscert, v3_key_usage, v3_ext_ku; +extern const X509V3_EXT_METHOD v3_pkey_usage_period, v3_sxnet, v3_info, + v3_sinfo; +extern const X509V3_EXT_METHOD v3_ns_ia5_list[], v3_alt[], v3_skey_id, + v3_akey_id; +extern const X509V3_EXT_METHOD v3_crl_num, v3_crl_reason, v3_crl_invdate; +extern const X509V3_EXT_METHOD v3_delta_crl, v3_cpols, v3_crld, + v3_freshest_crl; +extern const X509V3_EXT_METHOD v3_ocsp_nonce, v3_ocsp_accresp, + v3_ocsp_acutoff; +extern const X509V3_EXT_METHOD v3_ocsp_crlid, v3_ocsp_nocheck, + v3_ocsp_serviceloc; +extern const X509V3_EXT_METHOD v3_crl_hold, v3_pci; +extern const X509V3_EXT_METHOD v3_policy_mappings, v3_policy_constraints; +extern const X509V3_EXT_METHOD v3_name_constraints, v3_inhibit_anyp, v3_idp; +extern const X509V3_EXT_METHOD v3_addr, v3_asid; + +/* + * This table will be searched using OBJ_bsearch so it *must* kept in order + * of the ext_nid values. + */ + +/* TODO(fork): OCSP support */ +#define OPENSSL_NO_OCSP + +static const X509V3_EXT_METHOD *const 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_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, +}; + +/* Number of standard extensions */ + +#define STANDARD_EXTENSION_COUNT (sizeof(standard_exts)/sizeof(X509V3_EXT_METHOD *)) + +#if defined(__cplusplus) +} /* extern C */ +#endif diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/pcy_cache.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/pcy_cache.c new file mode 100644 index 0000000..c1159f3 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/pcy_cache.c @@ -0,0 +1,284 @@ +/* + * 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 +#include +#include +#include + +#include "pcy_int.h" +#include "../internal.h" + +static int policy_data_cmp(const X509_POLICY_DATA **a, + const X509_POLICY_DATA **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) +{ + size_t 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, NULL, data)) { + 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); +} + +/* + * g_x509_policy_cache_lock is used to protect against concurrent calls to + * |policy_cache_new|. Ideally this would be done with a |CRYPTO_once_t| in + * the |X509| structure, but |CRYPTO_once_t| isn't public. + */ +static struct CRYPTO_STATIC_MUTEX g_x509_policy_cache_lock = + CRYPTO_STATIC_MUTEX_INIT; + +const X509_POLICY_CACHE *policy_cache_set(X509 *x) +{ + X509_POLICY_CACHE *cache; + + CRYPTO_STATIC_MUTEX_lock_read(&g_x509_policy_cache_lock); + cache = x->policy_cache; + CRYPTO_STATIC_MUTEX_unlock_read(&g_x509_policy_cache_lock); + + if (cache != NULL) + return cache; + + CRYPTO_STATIC_MUTEX_lock_write(&g_x509_policy_cache_lock); + if (x->policy_cache == NULL) + policy_cache_new(x); + cache = x->policy_cache; + CRYPTO_STATIC_MUTEX_unlock_write(&g_x509_policy_cache_lock); + + return cache; +} + +X509_POLICY_DATA *policy_cache_find_data(const X509_POLICY_CACHE *cache, + const ASN1_OBJECT *id) +{ + size_t idx; + X509_POLICY_DATA tmp; + + tmp.valid_policy = (ASN1_OBJECT *)id; + if (!sk_X509_POLICY_DATA_find(cache->data, &idx, &tmp)) + return NULL; + return sk_X509_POLICY_DATA_value(cache->data, idx); +} + +static int policy_data_cmp(const X509_POLICY_DATA **a, + const X509_POLICY_DATA **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; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/pcy_cache.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/pcy_cache.c.grpc_back new file mode 100644 index 0000000..b8a4be2 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/pcy_cache.c.grpc_back @@ -0,0 +1,284 @@ +/* + * 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 +#include +#include +#include + +#include "pcy_int.h" +#include "../internal.h" + +static int policy_data_cmp(const X509_POLICY_DATA **a, + const X509_POLICY_DATA **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) +{ + size_t 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, NULL, data)) { + 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); +} + +/* + * g_x509_policy_cache_lock is used to protect against concurrent calls to + * |policy_cache_new|. Ideally this would be done with a |CRYPTO_once_t| in + * the |X509| structure, but |CRYPTO_once_t| isn't public. + */ +static struct CRYPTO_STATIC_MUTEX g_x509_policy_cache_lock = + CRYPTO_STATIC_MUTEX_INIT; + +const X509_POLICY_CACHE *policy_cache_set(X509 *x) +{ + X509_POLICY_CACHE *cache; + + CRYPTO_STATIC_MUTEX_lock_read(&g_x509_policy_cache_lock); + cache = x->policy_cache; + CRYPTO_STATIC_MUTEX_unlock_read(&g_x509_policy_cache_lock); + + if (cache != NULL) + return cache; + + CRYPTO_STATIC_MUTEX_lock_write(&g_x509_policy_cache_lock); + if (x->policy_cache == NULL) + policy_cache_new(x); + cache = x->policy_cache; + CRYPTO_STATIC_MUTEX_unlock_write(&g_x509_policy_cache_lock); + + return cache; +} + +X509_POLICY_DATA *policy_cache_find_data(const X509_POLICY_CACHE *cache, + const ASN1_OBJECT *id) +{ + size_t idx; + X509_POLICY_DATA tmp; + + tmp.valid_policy = (ASN1_OBJECT *)id; + if (!sk_X509_POLICY_DATA_find(cache->data, &idx, &tmp)) + return NULL; + return sk_X509_POLICY_DATA_value(cache->data, idx); +} + +static int policy_data_cmp(const X509_POLICY_DATA **a, + const X509_POLICY_DATA **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; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/pcy_data.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/pcy_data.c new file mode 100644 index 0000000..e8ab073 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/pcy_data.c @@ -0,0 +1,130 @@ +/* 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 +#include +#include +#include + +#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; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/pcy_data.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/pcy_data.c.grpc_back new file mode 100644 index 0000000..498de4d --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/pcy_data.c.grpc_back @@ -0,0 +1,130 @@ +/* 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 +#include +#include +#include + +#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; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/pcy_int.h b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/pcy_int.h new file mode 100644 index 0000000..fc6e20a --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/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; + +DEFINE_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, + 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/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/pcy_int.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/pcy_int.h.grpc_back new file mode 100644 index 0000000..fc6e20a --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/pcy_int.h.grpc_back @@ -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; + +DEFINE_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, + 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/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/pcy_lib.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/pcy_lib.c new file mode 100644 index 0000000..f7283a6 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/pcy_lib.c @@ -0,0 +1,155 @@ +/* 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 +#include + +#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; +} + +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; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/pcy_lib.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/pcy_lib.c.grpc_back new file mode 100644 index 0000000..7d5f067 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/pcy_lib.c.grpc_back @@ -0,0 +1,155 @@ +/* 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 +#include + +#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; +} + +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; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/pcy_map.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/pcy_map.c new file mode 100644 index 0000000..e0a1520 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/pcy_map.c @@ -0,0 +1,130 @@ +/* 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 +#include +#include + +#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; + size_t 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; + +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/pcy_map.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/pcy_map.c.grpc_back new file mode 100644 index 0000000..7263c69 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/pcy_map.c.grpc_back @@ -0,0 +1,130 @@ +/* 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 +#include +#include + +#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; + size_t 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; + +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/pcy_node.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/pcy_node.c new file mode 100644 index 0000000..f4233c5 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/pcy_node.c @@ -0,0 +1,188 @@ +/* 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 +#include +#include +#include +#include + +#include "pcy_int.h" + +static int node_cmp(const X509_POLICY_NODE **a, const X509_POLICY_NODE **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; + size_t idx; + + n.valid_policy = (ASN1_OBJECT *)id; + l.data = &n; + + if (!sk_X509_POLICY_NODE_find(nodes, &idx, &l)) + 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; + size_t 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, + 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) +{ + size_t 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; + +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/pcy_node.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/pcy_node.c.grpc_back new file mode 100644 index 0000000..b3edfe4 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/pcy_node.c.grpc_back @@ -0,0 +1,188 @@ +/* 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 +#include +#include +#include +#include + +#include "pcy_int.h" + +static int node_cmp(const X509_POLICY_NODE **a, const X509_POLICY_NODE **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; + size_t idx; + + n.valid_policy = (ASN1_OBJECT *)id; + l.data = &n; + + if (!sk_X509_POLICY_NODE_find(nodes, &idx, &l)) + 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; + size_t 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, + 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) +{ + size_t 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; + +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/pcy_tree.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/pcy_tree.c new file mode 100644 index 0000000..3ba5ed9 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/pcy_tree.c @@ -0,0 +1,840 @@ +/* + * 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 +#include +#include +#include +#include +#include + +#include "pcy_int.h" +#include "../internal.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; + } + + OPENSSL_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); + X509_up_ref(x); + 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, + X509_POLICY_DATA *data) +{ + X509_POLICY_LEVEL *last = curr - 1; + X509_POLICY_NODE *node; + int matched = 0; + size_t i; + /* 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) +{ + size_t 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; + size_t 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 ((size_t)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) +{ + size_t 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; + } + } + +} + +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, NULL, pcy)) + 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; + size_t 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) +{ + size_t 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/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/pcy_tree.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/pcy_tree.c.grpc_back new file mode 100644 index 0000000..256fe88 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/pcy_tree.c.grpc_back @@ -0,0 +1,840 @@ +/* + * 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 +#include +#include +#include +#include +#include + +#include "pcy_int.h" +#include "../internal.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; + } + + OPENSSL_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); + X509_up_ref(x); + 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, + X509_POLICY_DATA *data) +{ + X509_POLICY_LEVEL *last = curr - 1; + X509_POLICY_NODE *node; + int matched = 0; + size_t i; + /* 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) +{ + size_t 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; + size_t 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 ((size_t)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) +{ + size_t 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; + } + } + +} + +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, NULL, pcy)) + 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; + size_t 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) +{ + size_t 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/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_akey.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_akey.c new file mode 100644 index 0000000..b31e031 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_akey.c @@ -0,0 +1,204 @@ +/* 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 + +#include +#include +#include +#include +#include +#include +#include + +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; + size_t i; + int j; + 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 { + OPENSSL_PUT_ERROR(X509V3, 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(); + OPENSSL_PUT_ERROR(X509V3, X509V3_R_NO_ISSUER_CERTIFICATE); + return NULL; + } + + cert = ctx->issuer_cert; + + if (keyid) { + j = X509_get_ext_by_NID(cert, NID_subject_key_identifier, -1); + if ((j >= 0) && (ext = X509_get_ext(cert, j))) + ikeyid = X509V3_EXT_d2i(ext); + if (keyid == 2 && !ikeyid) { + OPENSSL_PUT_ERROR(X509V3, 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) { + OPENSSL_PUT_ERROR(X509V3, 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)) { + OPENSSL_PUT_ERROR(X509V3, 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; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_akey.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_akey.c.grpc_back new file mode 100644 index 0000000..4503e61 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_akey.c.grpc_back @@ -0,0 +1,204 @@ +/* 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 + +#include +#include +#include +#include +#include +#include +#include + +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; + size_t i; + int j; + 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 { + OPENSSL_PUT_ERROR(X509V3, 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(); + OPENSSL_PUT_ERROR(X509V3, X509V3_R_NO_ISSUER_CERTIFICATE); + return NULL; + } + + cert = ctx->issuer_cert; + + if (keyid) { + j = X509_get_ext_by_NID(cert, NID_subject_key_identifier, -1); + if ((j >= 0) && (ext = X509_get_ext(cert, j))) + ikeyid = X509V3_EXT_d2i(ext); + if (keyid == 2 && !ikeyid) { + OPENSSL_PUT_ERROR(X509V3, 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) { + OPENSSL_PUT_ERROR(X509V3, 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)) { + OPENSSL_PUT_ERROR(X509V3, 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; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_akeya.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_akeya.c new file mode 100644 index 0000000..950cae9 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_akeya.c @@ -0,0 +1,72 @@ +/* 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 +#include +#include +#include + + +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) diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_akeya.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_akeya.c.grpc_back new file mode 100644 index 0000000..844dee5 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_akeya.c.grpc_back @@ -0,0 +1,72 @@ +/* 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 +#include +#include +#include + + +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) diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_alt.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_alt.c new file mode 100644 index 0000000..bfd7a82 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_alt.c @@ -0,0 +1,623 @@ +/* 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 + +#include +#include +#include +#include +#include + +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) +{ + size_t 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; + BUF_strlcat(oline, htmp, sizeof(oline)); + if (i != 7) + BUF_strlcat(oline, ":", sizeof(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; + size_t i; + if (!(gens = sk_GENERAL_NAME_new_null())) { + OPENSSL_PUT_ERROR(X509V3, 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; + size_t j; + if (ctx && (ctx->flags == CTX_TEST)) + return 1; + if (!ctx || !ctx->issuer_cert) { + OPENSSL_PUT_ERROR(X509V3, 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))) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_ISSUER_DECODE_ERROR); + goto err; + } + + for (j = 0; j < sk_GENERAL_NAME_num(ialt); j++) { + gen = sk_GENERAL_NAME_value(ialt, j); + if (!sk_GENERAL_NAME_push(gens, gen)) { + OPENSSL_PUT_ERROR(X509V3, 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; + size_t i; + if (!(gens = sk_GENERAL_NAME_new_null())) { + OPENSSL_PUT_ERROR(X509V3, 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)) { + OPENSSL_PUT_ERROR(X509V3, 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())) { + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + goto err; + } + gen->d.ia5 = email; + email = NULL; + gen->type = GEN_EMAIL; + if (!sk_GENERAL_NAME_push(gens, gen)) { + OPENSSL_PUT_ERROR(X509V3, 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; + size_t i; + if (!(gens = sk_GENERAL_NAME_new_null())) { + OPENSSL_PUT_ERROR(X509V3, 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) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_MISSING_VALUE); + return NULL; + } + + if (out) + gen = out; + else { + gen = GENERAL_NAME_new(); + if (gen == NULL) { + OPENSSL_PUT_ERROR(X509V3, 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))) { + OPENSSL_PUT_ERROR(X509V3, 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) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_BAD_IP_ADDRESS); + ERR_add_error_data(2, "value=", value); + goto err; + } + break; + + case GEN_DIRNAME: + if (!do_dirname(gen, value, ctx)) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_DIRNAME_ERROR); + goto err; + } + break; + + case GEN_OTHERNAME: + if (!do_othername(gen, value, ctx)) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_OTHERNAME_ERROR); + goto err; + } + break; + default: + OPENSSL_PUT_ERROR(X509V3, 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))) { + OPENSSL_PUT_ERROR(X509V3, 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) { + OPENSSL_PUT_ERROR(X509V3, 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 { + OPENSSL_PUT_ERROR(X509V3, 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; + BUF_strlcpy(objtmp, value, objlen + 1); + 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 = X509_NAME_new(); + if (nm == NULL) + goto err; + sk = X509V3_get_section(ctx, value); + if (sk == NULL) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_SECTION_NOT_FOUND); + ERR_add_error_data(2, "section=", value); + goto err; + } + /* FIXME: should allow other character types... */ + if (!X509V3_NAME_from_section(nm, sk, MBSTRING_ASC)) + goto err; + gen->d.dirn = nm; + ret = 1; + + err: + if (!ret) + X509_NAME_free(nm); + X509V3_section_free(ctx, sk); + return ret; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_alt.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_alt.c.grpc_back new file mode 100644 index 0000000..b78a410 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_alt.c.grpc_back @@ -0,0 +1,623 @@ +/* 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 + +#include +#include +#include +#include +#include + +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) +{ + size_t 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; + BUF_strlcat(oline, htmp, sizeof(oline)); + if (i != 7) + BUF_strlcat(oline, ":", sizeof(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; + size_t i; + if (!(gens = sk_GENERAL_NAME_new_null())) { + OPENSSL_PUT_ERROR(X509V3, 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; + size_t j; + if (ctx && (ctx->flags == CTX_TEST)) + return 1; + if (!ctx || !ctx->issuer_cert) { + OPENSSL_PUT_ERROR(X509V3, 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))) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_ISSUER_DECODE_ERROR); + goto err; + } + + for (j = 0; j < sk_GENERAL_NAME_num(ialt); j++) { + gen = sk_GENERAL_NAME_value(ialt, j); + if (!sk_GENERAL_NAME_push(gens, gen)) { + OPENSSL_PUT_ERROR(X509V3, 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; + size_t i; + if (!(gens = sk_GENERAL_NAME_new_null())) { + OPENSSL_PUT_ERROR(X509V3, 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)) { + OPENSSL_PUT_ERROR(X509V3, 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())) { + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + goto err; + } + gen->d.ia5 = email; + email = NULL; + gen->type = GEN_EMAIL; + if (!sk_GENERAL_NAME_push(gens, gen)) { + OPENSSL_PUT_ERROR(X509V3, 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; + size_t i; + if (!(gens = sk_GENERAL_NAME_new_null())) { + OPENSSL_PUT_ERROR(X509V3, 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) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_MISSING_VALUE); + return NULL; + } + + if (out) + gen = out; + else { + gen = GENERAL_NAME_new(); + if (gen == NULL) { + OPENSSL_PUT_ERROR(X509V3, 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))) { + OPENSSL_PUT_ERROR(X509V3, 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) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_BAD_IP_ADDRESS); + ERR_add_error_data(2, "value=", value); + goto err; + } + break; + + case GEN_DIRNAME: + if (!do_dirname(gen, value, ctx)) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_DIRNAME_ERROR); + goto err; + } + break; + + case GEN_OTHERNAME: + if (!do_othername(gen, value, ctx)) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_OTHERNAME_ERROR); + goto err; + } + break; + default: + OPENSSL_PUT_ERROR(X509V3, 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))) { + OPENSSL_PUT_ERROR(X509V3, 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) { + OPENSSL_PUT_ERROR(X509V3, 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 { + OPENSSL_PUT_ERROR(X509V3, 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; + BUF_strlcpy(objtmp, value, objlen + 1); + 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 = X509_NAME_new(); + if (nm == NULL) + goto err; + sk = X509V3_get_section(ctx, value); + if (sk == NULL) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_SECTION_NOT_FOUND); + ERR_add_error_data(2, "section=", value); + goto err; + } + /* FIXME: should allow other character types... */ + if (!X509V3_NAME_from_section(nm, sk, MBSTRING_ASC)) + goto err; + gen->d.dirn = nm; + ret = 1; + + err: + if (!ret) + X509_NAME_free(nm); + X509V3_section_free(ctx, sk); + return ret; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_bcons.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_bcons.c new file mode 100644 index 0000000..ee52e14 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_bcons.c @@ -0,0 +1,133 @@ +/* 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 + +#include +#include +#include +#include +#include +#include + +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; + size_t i; + if (!(bcons = BASIC_CONSTRAINTS_new())) { + OPENSSL_PUT_ERROR(X509V3, 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 { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NAME); + X509V3_conf_err(val); + goto err; + } + } + return bcons; + err: + BASIC_CONSTRAINTS_free(bcons); + return NULL; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_bcons.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_bcons.c.grpc_back new file mode 100644 index 0000000..aefefdf --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_bcons.c.grpc_back @@ -0,0 +1,133 @@ +/* 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 + +#include +#include +#include +#include +#include +#include + +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; + size_t i; + if (!(bcons = BASIC_CONSTRAINTS_new())) { + OPENSSL_PUT_ERROR(X509V3, 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 { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NAME); + X509V3_conf_err(val); + goto err; + } + } + return bcons; + err: + BASIC_CONSTRAINTS_free(bcons); + return NULL; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_bitst.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_bitst.c new file mode 100644 index 0000000..0e8d074 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_bitst.c @@ -0,0 +1,141 @@ +/* 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 + +#include +#include +#include +#include + +static const 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 const 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) +{ + const 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; + size_t i; + const BIT_STRING_BITNAME *bnam; + if (!(bs = M_ASN1_BIT_STRING_new())) { + OPENSSL_PUT_ERROR(X509V3, 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)) { + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + M_ASN1_BIT_STRING_free(bs); + return NULL; + } + break; + } + } + if (!bnam->lname) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT); + X509V3_conf_err(val); + M_ASN1_BIT_STRING_free(bs); + return NULL; + } + } + return bs; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_bitst.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_bitst.c.grpc_back new file mode 100644 index 0000000..86a8c36 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_bitst.c.grpc_back @@ -0,0 +1,141 @@ +/* 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 + +#include +#include +#include +#include + +static const 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 const 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) +{ + const 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; + size_t i; + const BIT_STRING_BITNAME *bnam; + if (!(bs = M_ASN1_BIT_STRING_new())) { + OPENSSL_PUT_ERROR(X509V3, 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)) { + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + M_ASN1_BIT_STRING_free(bs); + return NULL; + } + break; + } + } + if (!bnam->lname) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT); + X509V3_conf_err(val); + M_ASN1_BIT_STRING_free(bs); + return NULL; + } + } + return bs; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_conf.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_conf.c new file mode 100644 index 0000000..e6a4332 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_conf.c @@ -0,0 +1,462 @@ +/* v3_conf.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * 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). */ + +/* extension creation utilities */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "../internal.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 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) { + OPENSSL_PUT_ERROR(X509V3, 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) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNKNOWN_EXTENSION_NAME); + return NULL; + } + if (!(method = X509V3_EXT_get_nid(ext_nid))) { + OPENSSL_PUT_ERROR(X509V3, 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) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_EXTENSION_STRING); + ERR_add_error_data(4, "name=", OBJ_nid2sn(ext_nid), ",section=", + value); + if (*value != '@') + sk_CONF_VALUE_pop_free(nval, X509V3_conf_free); + 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) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_NO_CONFIG_DATABASE); + return NULL; + } + if (!(ext_struc = method->r2i(method, ctx, value))) + return NULL; + } else { + OPENSSL_PUT_ERROR(X509V3, 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: + OPENSSL_PUT_ERROR(X509V3, 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))) { + OPENSSL_PUT_ERROR(X509V3, 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 = 0; + ASN1_OBJECT *obj = NULL; + ASN1_OCTET_STRING *oct = NULL; + X509_EXTENSION *extension = NULL; + if (!(obj = OBJ_txt2obj(ext, 0))) { + OPENSSL_PUT_ERROR(X509V3, 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) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_EXTENSION_VALUE_ERROR); + ERR_add_error_data(2, "value=", value); + goto err; + } + + if (!(oct = M_ASN1_OCTET_STRING_new())) { + OPENSSL_PUT_ERROR(X509V3, 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; + size_t 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) + X509v3_add_ext(sk, ext, -1); + 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) { + OPENSSL_PUT_ERROR(X509V3, 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) { + OPENSSL_PUT_ERROR(X509V3, 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) +{ + /* TODO(fork): this should return a const value. */ + return (char *)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 const 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; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_conf.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_conf.c.grpc_back new file mode 100644 index 0000000..ff2eae1 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_conf.c.grpc_back @@ -0,0 +1,462 @@ +/* v3_conf.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 1999. + */ +/* ==================================================================== + * 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). */ + +/* extension creation utilities */ + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "../internal.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 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) { + OPENSSL_PUT_ERROR(X509V3, 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) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_UNKNOWN_EXTENSION_NAME); + return NULL; + } + if (!(method = X509V3_EXT_get_nid(ext_nid))) { + OPENSSL_PUT_ERROR(X509V3, 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) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_EXTENSION_STRING); + ERR_add_error_data(4, "name=", OBJ_nid2sn(ext_nid), ",section=", + value); + if (*value != '@') + sk_CONF_VALUE_pop_free(nval, X509V3_conf_free); + 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) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_NO_CONFIG_DATABASE); + return NULL; + } + if (!(ext_struc = method->r2i(method, ctx, value))) + return NULL; + } else { + OPENSSL_PUT_ERROR(X509V3, 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: + OPENSSL_PUT_ERROR(X509V3, 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))) { + OPENSSL_PUT_ERROR(X509V3, 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 = 0; + ASN1_OBJECT *obj = NULL; + ASN1_OCTET_STRING *oct = NULL; + X509_EXTENSION *extension = NULL; + if (!(obj = OBJ_txt2obj(ext, 0))) { + OPENSSL_PUT_ERROR(X509V3, 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) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_EXTENSION_VALUE_ERROR); + ERR_add_error_data(2, "value=", value); + goto err; + } + + if (!(oct = M_ASN1_OCTET_STRING_new())) { + OPENSSL_PUT_ERROR(X509V3, 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; + size_t 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) + X509v3_add_ext(sk, ext, -1); + 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) { + OPENSSL_PUT_ERROR(X509V3, 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) { + OPENSSL_PUT_ERROR(X509V3, 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) +{ + /* TODO(fork): this should return a const value. */ + return (char *)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 const 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; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_cpols.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_cpols.c new file mode 100644 index 0000000..d6aa391 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_cpols.c @@ -0,0 +1,502 @@ +/* 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 + +#include +#include +#include +#include +#include +#include +#include +#include + +#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; + size_t i; + int ia5org; + pols = sk_POLICYINFO_new_null(); + if (pols == NULL) { + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + return NULL; + } + vals = X509V3_parse_list(value); + if (vals == NULL) { + OPENSSL_PUT_ERROR(X509V3, 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) { + OPENSSL_PUT_ERROR(X509V3, 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) { + OPENSSL_PUT_ERROR(X509V3, 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))) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_OBJECT_IDENTIFIER); + X509V3_conf_err(cnf); + goto err; + } + pol = POLICYINFO_new(); + if (pol == NULL) { + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + ASN1_OBJECT_free(pobj); + goto err; + } + pol->policyid = pobj; + } + if (!sk_POLICYINFO_push(pols, pol)) { + POLICYINFO_free(pol); + OPENSSL_PUT_ERROR(X509V3, 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) +{ + size_t 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))) { + OPENSSL_PUT_ERROR(X509V3, 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; + /* TODO(fork): const correctness */ + qual->pqualid = (ASN1_OBJECT *)OBJ_nid2obj(NID_id_qt_cps); + if (qual->pqualid == NULL) { + OPENSSL_PUT_ERROR(X509V3, ERR_R_INTERNAL_ERROR); + goto err; + } + qual->d.cpsuri = M_ASN1_IA5STRING_new(); + if (qual->d.cpsuri == NULL) { + goto err; + } + 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 != '@') { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_EXPECTED_A_SECTION_NAME); + X509V3_conf_err(cnf); + goto err; + } + unot = X509V3_get_section(ctx, cnf->value + 1); + if (!unot) { + OPENSSL_PUT_ERROR(X509V3, 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 { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_OPTION); + + X509V3_conf_err(cnf); + goto err; + } + } + if (!pol->policyid) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_NO_POLICY_IDENTIFIER); + goto err; + } + + return pol; + + merr: + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + + err: + POLICYINFO_free(pol); + return NULL; + +} + +static POLICYQUALINFO *notice_section(X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *unot, int ia5org) +{ + size_t i; + int ret; + CONF_VALUE *cnf; + USERNOTICE *not; + POLICYQUALINFO *qual; + if (!(qual = POLICYQUALINFO_new())) + goto merr; + /* TODO(fork): const correctness */ + qual->pqualid = (ASN1_OBJECT *)OBJ_nid2obj(NID_id_qt_unotice); + if (qual->pqualid == NULL) { + OPENSSL_PUT_ERROR(X509V3, 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")) { + not->exptext = M_ASN1_VISIBLESTRING_new(); + if (not->exptext == NULL) + 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)) { + OPENSSL_PUT_ERROR(X509V3, 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 { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_OPTION); + X509V3_conf_err(cnf); + goto err; + } + } + + if (not->noticeref && + (!not->noticeref->noticenos || !not->noticeref->organization)) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_NEED_ORGANIZATION_AND_NUMBERS); + goto err; + } + + return qual; + + merr: + OPENSSL_PUT_ERROR(X509V3, 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; + + size_t 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))) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NUMBER); + goto err; + } + if (!sk_ASN1_INTEGER_push(nnums, aint)) + goto merr; + } + return 1; + + merr: + ASN1_INTEGER_free(aint); + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + + err: + return 0; +} + +static int i2r_certpol(X509V3_EXT_METHOD *method, STACK_OF(POLICYINFO) *pol, + BIO *out, int indent) +{ + size_t 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; + size_t 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) +{ + size_t 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, ""); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_cpols.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_cpols.c.grpc_back new file mode 100644 index 0000000..4def530 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_cpols.c.grpc_back @@ -0,0 +1,502 @@ +/* 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 + +#include +#include +#include +#include +#include +#include +#include +#include + +#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; + size_t i; + int ia5org; + pols = sk_POLICYINFO_new_null(); + if (pols == NULL) { + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + return NULL; + } + vals = X509V3_parse_list(value); + if (vals == NULL) { + OPENSSL_PUT_ERROR(X509V3, 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) { + OPENSSL_PUT_ERROR(X509V3, 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) { + OPENSSL_PUT_ERROR(X509V3, 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))) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_OBJECT_IDENTIFIER); + X509V3_conf_err(cnf); + goto err; + } + pol = POLICYINFO_new(); + if (pol == NULL) { + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + ASN1_OBJECT_free(pobj); + goto err; + } + pol->policyid = pobj; + } + if (!sk_POLICYINFO_push(pols, pol)) { + POLICYINFO_free(pol); + OPENSSL_PUT_ERROR(X509V3, 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) +{ + size_t 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))) { + OPENSSL_PUT_ERROR(X509V3, 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; + /* TODO(fork): const correctness */ + qual->pqualid = (ASN1_OBJECT *)OBJ_nid2obj(NID_id_qt_cps); + if (qual->pqualid == NULL) { + OPENSSL_PUT_ERROR(X509V3, ERR_R_INTERNAL_ERROR); + goto err; + } + qual->d.cpsuri = M_ASN1_IA5STRING_new(); + if (qual->d.cpsuri == NULL) { + goto err; + } + 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 != '@') { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_EXPECTED_A_SECTION_NAME); + X509V3_conf_err(cnf); + goto err; + } + unot = X509V3_get_section(ctx, cnf->value + 1); + if (!unot) { + OPENSSL_PUT_ERROR(X509V3, 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 { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_OPTION); + + X509V3_conf_err(cnf); + goto err; + } + } + if (!pol->policyid) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_NO_POLICY_IDENTIFIER); + goto err; + } + + return pol; + + merr: + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + + err: + POLICYINFO_free(pol); + return NULL; + +} + +static POLICYQUALINFO *notice_section(X509V3_CTX *ctx, + STACK_OF(CONF_VALUE) *unot, int ia5org) +{ + size_t i; + int ret; + CONF_VALUE *cnf; + USERNOTICE *not; + POLICYQUALINFO *qual; + if (!(qual = POLICYQUALINFO_new())) + goto merr; + /* TODO(fork): const correctness */ + qual->pqualid = (ASN1_OBJECT *)OBJ_nid2obj(NID_id_qt_unotice); + if (qual->pqualid == NULL) { + OPENSSL_PUT_ERROR(X509V3, 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")) { + not->exptext = M_ASN1_VISIBLESTRING_new(); + if (not->exptext == NULL) + 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)) { + OPENSSL_PUT_ERROR(X509V3, 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 { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_OPTION); + X509V3_conf_err(cnf); + goto err; + } + } + + if (not->noticeref && + (!not->noticeref->noticenos || !not->noticeref->organization)) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_NEED_ORGANIZATION_AND_NUMBERS); + goto err; + } + + return qual; + + merr: + OPENSSL_PUT_ERROR(X509V3, 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; + + size_t 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))) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NUMBER); + goto err; + } + if (!sk_ASN1_INTEGER_push(nnums, aint)) + goto merr; + } + return 1; + + merr: + ASN1_INTEGER_free(aint); + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + + err: + return 0; +} + +static int i2r_certpol(X509V3_EXT_METHOD *method, STACK_OF(POLICYINFO) *pol, + BIO *out, int indent) +{ + size_t 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; + size_t 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) +{ + size_t 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, ""); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_crld.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_crld.c new file mode 100644 index 0000000..d0c64cf --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_crld.c @@ -0,0 +1,561 @@ +/* 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 + +#include +#include +#include +#include +#include +#include +#include + +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) { + OPENSSL_PUT_ERROR(X509V3, 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) { + OPENSSL_PUT_ERROR(X509V3, 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) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_MULTIPLE_RDNS); + goto err; + } + } else + return 0; + + if (*pdp) { + OPENSSL_PUT_ERROR(X509V3, 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; + size_t i; + int 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) +{ + size_t 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; + size_t 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: + OPENSSL_PUT_ERROR(X509V3, 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_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; + size_t i; + int 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 { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NAME); + X509V3_conf_err(cnf); + goto err; + } + } + return idp; + + merr: + OPENSSL_PUT_ERROR(X509V3, 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) +{ + size_t 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; + size_t 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) +{ + size_t 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; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_crld.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_crld.c.grpc_back new file mode 100644 index 0000000..c93c449 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_crld.c.grpc_back @@ -0,0 +1,561 @@ +/* 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 + +#include +#include +#include +#include +#include +#include +#include + +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) { + OPENSSL_PUT_ERROR(X509V3, 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) { + OPENSSL_PUT_ERROR(X509V3, 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) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_MULTIPLE_RDNS); + goto err; + } + } else + return 0; + + if (*pdp) { + OPENSSL_PUT_ERROR(X509V3, 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; + size_t i; + int 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) +{ + size_t 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; + size_t 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: + OPENSSL_PUT_ERROR(X509V3, 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_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; + size_t i; + int 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 { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NAME); + X509V3_conf_err(cnf); + goto err; + } + } + return idp; + + merr: + OPENSSL_PUT_ERROR(X509V3, 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) +{ + size_t 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; + size_t 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) +{ + size_t 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; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_enum.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_enum.c new file mode 100644 index 0000000..8595eb3 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_enum.c @@ -0,0 +1,100 @@ +/* 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 +#include +#include + +static const 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, + (void *)crl_reasons +}; + +char *i2s_ASN1_ENUMERATED_TABLE(X509V3_EXT_METHOD *method, ASN1_ENUMERATED *e) +{ + const 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); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_enum.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_enum.c.grpc_back new file mode 100644 index 0000000..6bfb232 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_enum.c.grpc_back @@ -0,0 +1,100 @@ +/* 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 +#include +#include + +static const 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, + (void *)crl_reasons +}; + +char *i2s_ASN1_ENUMERATED_TABLE(X509V3_EXT_METHOD *method, ASN1_ENUMERATED *e) +{ + const 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); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_extku.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_extku.c new file mode 100644 index 0000000..199576d --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_extku.c @@ -0,0 +1,148 @@ +/* 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 +#include +#include +#include +#include + +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; + size_t 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; + size_t i; + + if (!(extku = sk_ASN1_OBJECT_new_null())) { + OPENSSL_PUT_ERROR(X509V3, 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); + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_OBJECT_IDENTIFIER); + X509V3_conf_err(val); + return NULL; + } + sk_ASN1_OBJECT_push(extku, objtmp); + } + return extku; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_extku.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_extku.c.grpc_back new file mode 100644 index 0000000..952e032 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_extku.c.grpc_back @@ -0,0 +1,148 @@ +/* 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 +#include +#include +#include +#include + +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; + size_t 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; + size_t i; + + if (!(extku = sk_ASN1_OBJECT_new_null())) { + OPENSSL_PUT_ERROR(X509V3, 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); + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_OBJECT_IDENTIFIER); + X509V3_conf_err(val); + return NULL; + } + sk_ASN1_OBJECT_push(extku, objtmp); + } + return extku; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_genn.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_genn.c new file mode 100644 index 0000000..8a85cb8 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_genn.c @@ -0,0 +1,251 @@ +/* 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 +#include +#include +#include + + +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; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_genn.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_genn.c.grpc_back new file mode 100644 index 0000000..8c92687 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_genn.c.grpc_back @@ -0,0 +1,251 @@ +/* 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 +#include +#include +#include + + +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; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_ia5.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_ia5.c new file mode 100644 index 0000000..b88c8b9 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_ia5.c @@ -0,0 +1,122 @@ +/* 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 + +#include +#include +#include +#include +#include +#include + +#include "../internal.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))) { + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + return NULL; + } + OPENSSL_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) { + OPENSSL_PUT_ERROR(X509V3, 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; + } + return ia5; + err: + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + return NULL; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_ia5.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_ia5.c.grpc_back new file mode 100644 index 0000000..6b2056d --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_ia5.c.grpc_back @@ -0,0 +1,122 @@ +/* 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 + +#include +#include +#include +#include +#include +#include + +#include "../internal.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))) { + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + return NULL; + } + OPENSSL_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) { + OPENSSL_PUT_ERROR(X509V3, 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; + } + return ia5; + err: + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + return NULL; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_info.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_info.c new file mode 100644 index 0000000..7e9a28a --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_info.c @@ -0,0 +1,219 @@ +/* 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 + +#include +#include +#include +#include +#include +#include +#include +#include + +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; + size_t i; + int 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: + OPENSSL_PUT_ERROR(X509V3, 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; + size_t i; + int objlen; + char *objtmp, *ptmp; + if (!(ainfo = sk_ACCESS_DESCRIPTION_new_null())) { + OPENSSL_PUT_ERROR(X509V3, 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)) { + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + goto err; + } + ptmp = strchr(cnf->name, ';'); + if (!ptmp) { + OPENSSL_PUT_ERROR(X509V3, 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))) { + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + goto err; + } + BUF_strlcpy(objtmp, cnf->name, objlen + 1); + acc->method = OBJ_txt2obj(objtmp, 0); + if (!acc->method) { + OPENSSL_PUT_ERROR(X509V3, 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; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_info.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_info.c.grpc_back new file mode 100644 index 0000000..ff96489 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_info.c.grpc_back @@ -0,0 +1,219 @@ +/* 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 + +#include +#include +#include +#include +#include +#include +#include +#include + +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; + size_t i; + int 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: + OPENSSL_PUT_ERROR(X509V3, 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; + size_t i; + int objlen; + char *objtmp, *ptmp; + if (!(ainfo = sk_ACCESS_DESCRIPTION_new_null())) { + OPENSSL_PUT_ERROR(X509V3, 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)) { + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + goto err; + } + ptmp = strchr(cnf->name, ';'); + if (!ptmp) { + OPENSSL_PUT_ERROR(X509V3, 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))) { + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + goto err; + } + BUF_strlcpy(objtmp, cnf->name, objlen + 1); + acc->method = OBJ_txt2obj(objtmp, 0); + if (!acc->method) { + OPENSSL_PUT_ERROR(X509V3, 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; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_int.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_int.c new file mode 100644 index 0000000..3cf01ca --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_int.c @@ -0,0 +1,91 @@ +/* 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 +#include + +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 +}; diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_int.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_int.c.grpc_back new file mode 100644 index 0000000..7bde446 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_int.c.grpc_back @@ -0,0 +1,91 @@ +/* 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 +#include + +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 +}; diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_lib.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_lib.c new file mode 100644 index 0000000..24dfc3f --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_lib.c @@ -0,0 +1,370 @@ +/* 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 +#include +#include +#include +#include + +#include "ext_dat.h" +static STACK_OF(X509V3_EXT_METHOD) *ext_list = NULL; + +static void ext_list_free(X509V3_EXT_METHOD *ext); + +static int ext_stack_cmp(const X509V3_EXT_METHOD **a, + const X509V3_EXT_METHOD **b) +{ + return ((*a)->ext_nid - (*b)->ext_nid); +} + +int X509V3_EXT_add(X509V3_EXT_METHOD *ext) +{ + if (!ext_list && !(ext_list = sk_X509V3_EXT_METHOD_new(ext_stack_cmp))) { + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + ext_list_free(ext); + return 0; + } + if (!sk_X509V3_EXT_METHOD_push(ext_list, ext)) { + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + ext_list_free(ext); + return 0; + } + return 1; +} + +static int ext_cmp(const void *void_a, const void *void_b) +{ + const X509V3_EXT_METHOD **a = (const X509V3_EXT_METHOD **)void_a; + const X509V3_EXT_METHOD **b = (const X509V3_EXT_METHOD **)void_b; + return ext_stack_cmp(a, b); +} + +const X509V3_EXT_METHOD *X509V3_EXT_get_nid(int nid) +{ + X509V3_EXT_METHOD tmp; + const X509V3_EXT_METHOD *t = &tmp, *const *ret; + size_t idx; + + if (nid < 0) + return NULL; + tmp.ext_nid = nid; + ret = + bsearch(&t, standard_exts, STANDARD_EXTENSION_COUNT, + sizeof(X509V3_EXT_METHOD *), ext_cmp); + if (ret) + return *ret; + if (!ext_list) + return NULL; + + if (!sk_X509V3_EXT_METHOD_find(ext_list, &idx, &tmp)) + 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) { + OPENSSL_PUT_ERROR(X509V3, 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 { + OPENSSL_PUT_ERROR(X509V3, 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))) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_EXTENSION_NOT_FOUND); + return 0; + } + if (! + (tmpext = + (X509V3_EXT_METHOD *)OPENSSL_malloc(sizeof(X509V3_EXT_METHOD)))) { + OPENSSL_PUT_ERROR(X509V3, 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; + size_t 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) { + OPENSSL_PUT_ERROR(X509V3, 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)) + OPENSSL_PUT_ERROR(X509V3, errcode); + return 0; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_lib.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_lib.c.grpc_back new file mode 100644 index 0000000..8f5435d --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_lib.c.grpc_back @@ -0,0 +1,370 @@ +/* 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 +#include +#include +#include +#include + +#include "ext_dat.h" +static STACK_OF(X509V3_EXT_METHOD) *ext_list = NULL; + +static void ext_list_free(X509V3_EXT_METHOD *ext); + +static int ext_stack_cmp(const X509V3_EXT_METHOD **a, + const X509V3_EXT_METHOD **b) +{ + return ((*a)->ext_nid - (*b)->ext_nid); +} + +int X509V3_EXT_add(X509V3_EXT_METHOD *ext) +{ + if (!ext_list && !(ext_list = sk_X509V3_EXT_METHOD_new(ext_stack_cmp))) { + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + ext_list_free(ext); + return 0; + } + if (!sk_X509V3_EXT_METHOD_push(ext_list, ext)) { + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + ext_list_free(ext); + return 0; + } + return 1; +} + +static int ext_cmp(const void *void_a, const void *void_b) +{ + const X509V3_EXT_METHOD **a = (const X509V3_EXT_METHOD **)void_a; + const X509V3_EXT_METHOD **b = (const X509V3_EXT_METHOD **)void_b; + return ext_stack_cmp(a, b); +} + +const X509V3_EXT_METHOD *X509V3_EXT_get_nid(int nid) +{ + X509V3_EXT_METHOD tmp; + const X509V3_EXT_METHOD *t = &tmp, *const *ret; + size_t idx; + + if (nid < 0) + return NULL; + tmp.ext_nid = nid; + ret = + bsearch(&t, standard_exts, STANDARD_EXTENSION_COUNT, + sizeof(X509V3_EXT_METHOD *), ext_cmp); + if (ret) + return *ret; + if (!ext_list) + return NULL; + + if (!sk_X509V3_EXT_METHOD_find(ext_list, &idx, &tmp)) + 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) { + OPENSSL_PUT_ERROR(X509V3, 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 { + OPENSSL_PUT_ERROR(X509V3, 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))) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_EXTENSION_NOT_FOUND); + return 0; + } + if (! + (tmpext = + (X509V3_EXT_METHOD *)OPENSSL_malloc(sizeof(X509V3_EXT_METHOD)))) { + OPENSSL_PUT_ERROR(X509V3, 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; + size_t 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) { + OPENSSL_PUT_ERROR(X509V3, 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)) + OPENSSL_PUT_ERROR(X509V3, errcode); + return 0; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_ncons.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_ncons.c new file mode 100644 index 0000000..fb3a818 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_ncons.c @@ -0,0 +1,501 @@ +/* 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 + +#include +#include +#include +#include +#include +#include + +#include "../internal.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, const 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) + +static void *v2i_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval) +{ + size_t 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 { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_SYNTAX); + goto err; + } + tval.value = val->value; + sub = GENERAL_SUBTREE_new(); + 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: + OPENSSL_PUT_ERROR(X509V3, 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, const char *name) +{ + GENERAL_SUBTREE *tree; + size_t 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_UNSPECIFIED: Unspecified error. + * X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE: Unsupported constraint type. + * X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX: Bad or 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; + size_t j; + X509_NAME *nm; + + nm = X509_get_subject_name(x); + + /* Guard against certificates with an excessive number of names or + * constraints causing a computationally expensive name constraints + * check. */ + size_t name_count = + X509_NAME_entry_count(nm) + sk_GENERAL_NAME_num(x->altname); + size_t constraint_count = sk_GENERAL_SUBTREE_num(nc->permittedSubtrees) + + sk_GENERAL_SUBTREE_num(nc->excludedSubtrees); + size_t check_count = constraint_count * name_count; + if (name_count < (size_t)X509_NAME_entry_count(nm) || + constraint_count < sk_GENERAL_SUBTREE_num(nc->permittedSubtrees) || + (constraint_count && check_count / constraint_count != name_count) || + check_count > 1 << 20) { + return X509_V_ERR_UNSPECIFIED; + } + + 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 (j = 0; j < sk_GENERAL_NAME_num(x->altname); j++) { + GENERAL_NAME *gen = sk_GENERAL_NAME_value(x->altname, j); + 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 r, match = 0; + size_t i; + + /* + * 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 (OPENSSL_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 (OPENSSL_strcasecmp(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 (!OPENSSL_strcasecmp(baseptr, emlptr)) + 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 (OPENSSL_strcasecmp(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 (!OPENSSL_strncasecmp(p, baseptr, base->length)) + return X509_V_OK; + } + return X509_V_ERR_PERMITTED_VIOLATION; + } + + if ((base->length != (int)hostlen) + || OPENSSL_strncasecmp(hostptr, baseptr, hostlen)) + return X509_V_ERR_PERMITTED_VIOLATION; + + return X509_V_OK; + +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_ncons.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_ncons.c.grpc_back new file mode 100644 index 0000000..593a520 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_ncons.c.grpc_back @@ -0,0 +1,501 @@ +/* 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 + +#include +#include +#include +#include +#include +#include + +#include "../internal.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, const 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) + +static void *v2i_NAME_CONSTRAINTS(const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval) +{ + size_t 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 { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_SYNTAX); + goto err; + } + tval.value = val->value; + sub = GENERAL_SUBTREE_new(); + 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: + OPENSSL_PUT_ERROR(X509V3, 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, const char *name) +{ + GENERAL_SUBTREE *tree; + size_t 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_UNSPECIFIED: Unspecified error. + * X509_V_ERR_UNSUPPORTED_CONSTRAINT_TYPE: Unsupported constraint type. + * X509_V_ERR_UNSUPPORTED_CONSTRAINT_SYNTAX: Bad or 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; + size_t j; + X509_NAME *nm; + + nm = X509_get_subject_name(x); + + /* Guard against certificates with an excessive number of names or + * constraints causing a computationally expensive name constraints + * check. */ + size_t name_count = + X509_NAME_entry_count(nm) + sk_GENERAL_NAME_num(x->altname); + size_t constraint_count = sk_GENERAL_SUBTREE_num(nc->permittedSubtrees) + + sk_GENERAL_SUBTREE_num(nc->excludedSubtrees); + size_t check_count = constraint_count * name_count; + if (name_count < (size_t)X509_NAME_entry_count(nm) || + constraint_count < sk_GENERAL_SUBTREE_num(nc->permittedSubtrees) || + (constraint_count && check_count / constraint_count != name_count) || + check_count > 1 << 20) { + return X509_V_ERR_UNSPECIFIED; + } + + 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 (j = 0; j < sk_GENERAL_NAME_num(x->altname); j++) { + GENERAL_NAME *gen = sk_GENERAL_NAME_value(x->altname, j); + 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 r, match = 0; + size_t i; + + /* + * 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 (OPENSSL_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 (OPENSSL_strcasecmp(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 (!OPENSSL_strcasecmp(baseptr, emlptr)) + 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 (OPENSSL_strcasecmp(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 (!OPENSSL_strncasecmp(p, baseptr, base->length)) + return X509_V_OK; + } + return X509_V_ERR_PERMITTED_VIOLATION; + } + + if ((base->length != (int)hostlen) + || OPENSSL_strncasecmp(hostptr, baseptr, hostlen)) + return X509_V_ERR_PERMITTED_VIOLATION; + + return X509_V_OK; + +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_pci.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_pci.c new file mode 100644 index 0000000..8bef402 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_pci.c @@ -0,0 +1,287 @@ +/* v3_pci.c -*- mode:C; c-file-style: "eay" -*- */ +/* + * 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 +#include +#include +#include +#include + +#include "../internal.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) { + OPENSSL_PUT_ERROR(X509V3, + X509V3_R_POLICY_LANGUAGE_ALREADY_DEFINED); + X509V3_conf_err(val); + return 0; + } + if (!(*language = OBJ_txt2obj(val->value, 0))) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_OBJECT_IDENTIFIER); + X509V3_conf_err(val); + return 0; + } + } else if (strcmp(val->name, "pathlen") == 0) { + if (*pathlen) { + OPENSSL_PUT_ERROR(X509V3, + X509V3_R_POLICY_PATH_LENGTH_ALREADY_DEFINED); + X509V3_conf_err(val); + return 0; + } + if (!X509V3_get_value_int(val, pathlen)) { + OPENSSL_PUT_ERROR(X509V3, 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) { + OPENSSL_PUT_ERROR(X509V3, 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) { + OPENSSL_PUT_ERROR(X509V3, 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; + OPENSSL_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; + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + X509V3_conf_err(val); + goto err; + } + OPENSSL_free(tmp_data2); + } 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; + OPENSSL_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; + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + X509V3_conf_err(val); + goto err; + } + } else { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INCORRECT_POLICY_SYNTAX_TAG); + X509V3_conf_err(val); + goto err; + } + if (!tmp_data) { + OPENSSL_PUT_ERROR(X509V3, 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; + size_t i, j; + int nid; + + 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)) { + OPENSSL_PUT_ERROR(X509V3, 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) { + OPENSSL_PUT_ERROR(X509V3, 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) { + OPENSSL_PUT_ERROR(X509V3, + X509V3_R_NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED); + goto err; + } + nid = OBJ_obj2nid(language); + if ((nid == NID_Independent || nid == NID_id_ppl_inheritAll) && policy) { + OPENSSL_PUT_ERROR(X509V3, + X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY); + goto err; + } + + pci = PROXY_CERT_INFO_EXTENSION_new(); + if (!pci) { + OPENSSL_PUT_ERROR(X509V3, 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; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_pci.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_pci.c.grpc_back new file mode 100644 index 0000000..4352abe --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_pci.c.grpc_back @@ -0,0 +1,287 @@ +/* v3_pci.c -*- mode:C; c-file-style: "eay" -*- */ +/* + * 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 +#include +#include +#include +#include + +#include "../internal.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) { + OPENSSL_PUT_ERROR(X509V3, + X509V3_R_POLICY_LANGUAGE_ALREADY_DEFINED); + X509V3_conf_err(val); + return 0; + } + if (!(*language = OBJ_txt2obj(val->value, 0))) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_OBJECT_IDENTIFIER); + X509V3_conf_err(val); + return 0; + } + } else if (strcmp(val->name, "pathlen") == 0) { + if (*pathlen) { + OPENSSL_PUT_ERROR(X509V3, + X509V3_R_POLICY_PATH_LENGTH_ALREADY_DEFINED); + X509V3_conf_err(val); + return 0; + } + if (!X509V3_get_value_int(val, pathlen)) { + OPENSSL_PUT_ERROR(X509V3, 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) { + OPENSSL_PUT_ERROR(X509V3, 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) { + OPENSSL_PUT_ERROR(X509V3, 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; + OPENSSL_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; + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + X509V3_conf_err(val); + goto err; + } + OPENSSL_free(tmp_data2); + } 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; + OPENSSL_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; + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + X509V3_conf_err(val); + goto err; + } + } else { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INCORRECT_POLICY_SYNTAX_TAG); + X509V3_conf_err(val); + goto err; + } + if (!tmp_data) { + OPENSSL_PUT_ERROR(X509V3, 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; + size_t i, j; + int nid; + + 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)) { + OPENSSL_PUT_ERROR(X509V3, 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) { + OPENSSL_PUT_ERROR(X509V3, 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) { + OPENSSL_PUT_ERROR(X509V3, + X509V3_R_NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED); + goto err; + } + nid = OBJ_obj2nid(language); + if ((nid == NID_Independent || nid == NID_id_ppl_inheritAll) && policy) { + OPENSSL_PUT_ERROR(X509V3, + X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY); + goto err; + } + + pci = PROXY_CERT_INFO_EXTENSION_new(); + if (!pci) { + OPENSSL_PUT_ERROR(X509V3, 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; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_pcia.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_pcia.c new file mode 100644 index 0000000..f803cc8 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_pcia.c @@ -0,0 +1,57 @@ +/* v3_pcia.c -*- mode:C; c-file-style: "eay" -*- */ +/* + * 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 +#include + + +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) diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_pcia.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_pcia.c.grpc_back new file mode 100644 index 0000000..3f285f3 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_pcia.c.grpc_back @@ -0,0 +1,57 @@ +/* v3_pcia.c -*- mode:C; c-file-style: "eay" -*- */ +/* + * 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 +#include + + +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) diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_pcons.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_pcons.c new file mode 100644 index 0000000..5558ca3 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_pcons.c @@ -0,0 +1,139 @@ +/* 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 + +#include +#include +#include +#include +#include +#include + +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; + size_t i; + if (!(pcons = POLICY_CONSTRAINTS_new())) { + OPENSSL_PUT_ERROR(X509V3, 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 { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NAME); + X509V3_conf_err(val); + goto err; + } + } + if (!pcons->inhibitPolicyMapping && !pcons->requireExplicitPolicy) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_ILLEGAL_EMPTY_EXTENSION); + goto err; + } + + return pcons; + err: + POLICY_CONSTRAINTS_free(pcons); + return NULL; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_pcons.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_pcons.c.grpc_back new file mode 100644 index 0000000..1a46314 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_pcons.c.grpc_back @@ -0,0 +1,139 @@ +/* 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 + +#include +#include +#include +#include +#include +#include + +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; + size_t i; + if (!(pcons = POLICY_CONSTRAINTS_new())) { + OPENSSL_PUT_ERROR(X509V3, 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 { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NAME); + X509V3_conf_err(val); + goto err; + } + } + if (!pcons->inhibitPolicyMapping && !pcons->requireExplicitPolicy) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_ILLEGAL_EMPTY_EXTENSION); + goto err; + } + + return pcons; + err: + POLICY_CONSTRAINTS_free(pcons); + return NULL; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_pku.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_pku.c new file mode 100644 index 0000000..d448741 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_pku.c @@ -0,0 +1,110 @@ +/* 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 +#include +#include +#include +#include + +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; } + */ diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_pku.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_pku.c.grpc_back new file mode 100644 index 0000000..e4868b4 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_pku.c.grpc_back @@ -0,0 +1,110 @@ +/* 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 +#include +#include +#include +#include + +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; } + */ diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_pmaps.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_pmaps.c new file mode 100644 index 0000000..8c43dca --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_pmaps.c @@ -0,0 +1,154 @@ +/* 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 +#include +#include +#include +#include + +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; + size_t 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; + size_t i; + + if (!(pmaps = sk_POLICY_MAPPING_new_null())) { + OPENSSL_PUT_ERROR(X509V3, 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); + OPENSSL_PUT_ERROR(X509V3, 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); + OPENSSL_PUT_ERROR(X509V3, 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); + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + return NULL; + } + pmap->issuerDomainPolicy = obj1; + pmap->subjectDomainPolicy = obj2; + sk_POLICY_MAPPING_push(pmaps, pmap); + } + return pmaps; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_pmaps.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_pmaps.c.grpc_back new file mode 100644 index 0000000..caacdb2 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_pmaps.c.grpc_back @@ -0,0 +1,154 @@ +/* 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 +#include +#include +#include +#include + +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; + size_t 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; + size_t i; + + if (!(pmaps = sk_POLICY_MAPPING_new_null())) { + OPENSSL_PUT_ERROR(X509V3, 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); + OPENSSL_PUT_ERROR(X509V3, 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); + OPENSSL_PUT_ERROR(X509V3, 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); + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + return NULL; + } + pmap->issuerDomainPolicy = obj1; + pmap->subjectDomainPolicy = obj2; + sk_POLICY_MAPPING_push(pmaps, pmap); + } + return pmaps; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_prn.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_prn.c new file mode 100644 index 0000000..dbe3adc --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_prn.c @@ -0,0 +1,229 @@ +/* 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 +#include +#include +#include + +/* 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) +{ + size_t 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); + else + BIO_printf(out, "%s:%s", nval->name, nval->value); + 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; + } + BIO_printf(out, "%*s%s", indent, "", value); + } 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, const char *title, + STACK_OF(X509_EXTENSION) *exts, + unsigned long flag, int indent) +{ + size_t i; + int 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: + case X509V3_EXT_DUMP_UNKNOWN: + return BIO_hexdump(out, 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 diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_prn.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_prn.c.grpc_back new file mode 100644 index 0000000..2f5efcf --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_prn.c.grpc_back @@ -0,0 +1,229 @@ +/* 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 +#include +#include +#include + +/* 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) +{ + size_t 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); + else + BIO_printf(out, "%s:%s", nval->name, nval->value); + 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; + } + BIO_printf(out, "%*s%s", indent, "", value); + } 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, const char *title, + STACK_OF(X509_EXTENSION) *exts, + unsigned long flag, int indent) +{ + size_t i; + int 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: + case X509V3_EXT_DUMP_UNKNOWN: + return BIO_hexdump(out, 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 diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_purp.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_purp.c new file mode 100644 index 0000000..aae566a --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_purp.c @@ -0,0 +1,866 @@ +/* v3_purp.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2001. + */ +/* ==================================================================== + * 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 + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../internal.h" + +#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); + +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 **a, const X509_PURPOSE **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, (char *)"SSL client", (char *)"sslclient", + NULL}, + {X509_PURPOSE_SSL_SERVER, X509_TRUST_SSL_SERVER, 0, + check_purpose_ssl_server, (char *)"SSL server", (char *)"sslserver", + NULL}, + {X509_PURPOSE_NS_SSL_SERVER, X509_TRUST_SSL_SERVER, 0, + check_purpose_ns_ssl_server, (char *)"Netscape SSL server", + (char *)"nssslserver", NULL}, + {X509_PURPOSE_SMIME_SIGN, X509_TRUST_EMAIL, 0, check_purpose_smime_sign, + (char *)"S/MIME signing", (char *)"smimesign", NULL}, + {X509_PURPOSE_SMIME_ENCRYPT, X509_TRUST_EMAIL, 0, + check_purpose_smime_encrypt, (char *)"S/MIME encryption", + (char *)"smimeencrypt", NULL}, + {X509_PURPOSE_CRL_SIGN, X509_TRUST_COMPAT, 0, check_purpose_crl_sign, + (char *)"CRL signing", (char *)"crlsign", NULL}, + {X509_PURPOSE_ANY, X509_TRUST_DEFAULT, 0, no_check, (char *)"Any Purpose", + (char *)"any", NULL}, + {X509_PURPOSE_OCSP_HELPER, X509_TRUST_COMPAT, 0, ocsp_helper, + (char *)"OCSP helper", (char *)"ocsphelper", NULL}, + {X509_PURPOSE_TIMESTAMP_SIGN, X509_TRUST_TSA, 0, + check_purpose_timestamp_sign, (char *)"Time Stamp signing", + (char *)"timestampsign", NULL}, +}; + +#define X509_PURPOSE_COUNT (sizeof(xstandard)/sizeof(X509_PURPOSE)) + +static STACK_OF(X509_PURPOSE) *xptable = NULL; + +static int xp_cmp(const X509_PURPOSE **a, const X509_PURPOSE **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); + 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) { + OPENSSL_PUT_ERROR(X509V3, 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; + size_t idx; + + if ((purpose >= X509_PURPOSE_MIN) && (purpose <= X509_PURPOSE_MAX)) + return purpose - X509_PURPOSE_MIN; + tmp.purpose = purpose; + if (!xptable) + return -1; + + if (!sk_X509_PURPOSE_find(xptable, &idx, &tmp)) + 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; + char *name_dup, *sname_dup; + + /* + * 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)))) { + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + return 0; + } + ptmp->flags = X509_PURPOSE_DYNAMIC; + } else + ptmp = X509_PURPOSE_get0(idx); + + /* Duplicate the supplied names. */ + name_dup = BUF_strdup(name); + sname_dup = BUF_strdup(sname); + if (name_dup == NULL || sname_dup == NULL) { + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + if (name_dup != NULL) + OPENSSL_free(name_dup); + if (sname_dup != NULL) + OPENSSL_free(sname_dup); + if (idx == -1) + OPENSSL_free(ptmp); + return 0; + } + + /* 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 = name_dup; + ptmp->sname = sname_dup; + /* 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))) { + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + xptable_free(ptmp); + return 0; + } + if (!sk_X509_PURPOSE_push(xptable, ptmp)) { + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + xptable_free(ptmp); + 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 void *void_a, const void *void_b) +{ + const int *a = void_a, *b = void_b; + + return *a - *b; +} + +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_ext_key_usage, /* 126 */ + 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 (bsearch + (&ex_nid, supported_nids, sizeof(supported_nids) / sizeof(int), + sizeof(int), nid_cmp) != NULL) + return 1; + return 0; +} + +static void setup_dp(X509 *x, DIST_POINT *dp) +{ + X509_NAME *iname = NULL; + size_t 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) +{ + size_t 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)); +} + +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; + size_t i; + int j; + + CRYPTO_MUTEX_lock_read(&x->lock); + const int is_set = x->ex_flags & EXFLAG_SET; + CRYPTO_MUTEX_unlock_read(&x->lock); + + if (is_set) { + return; + } + + CRYPTO_MUTEX_lock_write(&x->lock); + if (x->ex_flags & EXFLAG_SET) { + CRYPTO_MUTEX_unlock_write(&x->lock); + return; + } + + X509_digest(x, EVP_sha1(), x->sha1_hash, NULL); + /* 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, &j, NULL); + if (!x->nc && (j != -1)) + x->ex_flags |= EXFLAG_INVALID; + setup_crldp(x); + + for (j = 0; j < X509_get_ext_count(x); j++) { + ex = X509_get_ext(x, j); + 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_MUTEX_unlock_write(&x->lock); +} + +/* + * 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; + size_t 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; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_purp.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_purp.c.grpc_back new file mode 100644 index 0000000..324de85 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_purp.c.grpc_back @@ -0,0 +1,866 @@ +/* v3_purp.c */ +/* + * Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project + * 2001. + */ +/* ==================================================================== + * 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 + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../internal.h" + +#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); + +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 **a, const X509_PURPOSE **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, (char *)"SSL client", (char *)"sslclient", + NULL}, + {X509_PURPOSE_SSL_SERVER, X509_TRUST_SSL_SERVER, 0, + check_purpose_ssl_server, (char *)"SSL server", (char *)"sslserver", + NULL}, + {X509_PURPOSE_NS_SSL_SERVER, X509_TRUST_SSL_SERVER, 0, + check_purpose_ns_ssl_server, (char *)"Netscape SSL server", + (char *)"nssslserver", NULL}, + {X509_PURPOSE_SMIME_SIGN, X509_TRUST_EMAIL, 0, check_purpose_smime_sign, + (char *)"S/MIME signing", (char *)"smimesign", NULL}, + {X509_PURPOSE_SMIME_ENCRYPT, X509_TRUST_EMAIL, 0, + check_purpose_smime_encrypt, (char *)"S/MIME encryption", + (char *)"smimeencrypt", NULL}, + {X509_PURPOSE_CRL_SIGN, X509_TRUST_COMPAT, 0, check_purpose_crl_sign, + (char *)"CRL signing", (char *)"crlsign", NULL}, + {X509_PURPOSE_ANY, X509_TRUST_DEFAULT, 0, no_check, (char *)"Any Purpose", + (char *)"any", NULL}, + {X509_PURPOSE_OCSP_HELPER, X509_TRUST_COMPAT, 0, ocsp_helper, + (char *)"OCSP helper", (char *)"ocsphelper", NULL}, + {X509_PURPOSE_TIMESTAMP_SIGN, X509_TRUST_TSA, 0, + check_purpose_timestamp_sign, (char *)"Time Stamp signing", + (char *)"timestampsign", NULL}, +}; + +#define X509_PURPOSE_COUNT (sizeof(xstandard)/sizeof(X509_PURPOSE)) + +static STACK_OF(X509_PURPOSE) *xptable = NULL; + +static int xp_cmp(const X509_PURPOSE **a, const X509_PURPOSE **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); + 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) { + OPENSSL_PUT_ERROR(X509V3, 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; + size_t idx; + + if ((purpose >= X509_PURPOSE_MIN) && (purpose <= X509_PURPOSE_MAX)) + return purpose - X509_PURPOSE_MIN; + tmp.purpose = purpose; + if (!xptable) + return -1; + + if (!sk_X509_PURPOSE_find(xptable, &idx, &tmp)) + 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; + char *name_dup, *sname_dup; + + /* + * 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)))) { + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + return 0; + } + ptmp->flags = X509_PURPOSE_DYNAMIC; + } else + ptmp = X509_PURPOSE_get0(idx); + + /* Duplicate the supplied names. */ + name_dup = BUF_strdup(name); + sname_dup = BUF_strdup(sname); + if (name_dup == NULL || sname_dup == NULL) { + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + if (name_dup != NULL) + OPENSSL_free(name_dup); + if (sname_dup != NULL) + OPENSSL_free(sname_dup); + if (idx == -1) + OPENSSL_free(ptmp); + return 0; + } + + /* 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 = name_dup; + ptmp->sname = sname_dup; + /* 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))) { + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + xptable_free(ptmp); + return 0; + } + if (!sk_X509_PURPOSE_push(xptable, ptmp)) { + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + xptable_free(ptmp); + 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 void *void_a, const void *void_b) +{ + const int *a = void_a, *b = void_b; + + return *a - *b; +} + +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_ext_key_usage, /* 126 */ + 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 (bsearch + (&ex_nid, supported_nids, sizeof(supported_nids) / sizeof(int), + sizeof(int), nid_cmp) != NULL) + return 1; + return 0; +} + +static void setup_dp(X509 *x, DIST_POINT *dp) +{ + X509_NAME *iname = NULL; + size_t 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) +{ + size_t 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)); +} + +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; + size_t i; + int j; + + CRYPTO_MUTEX_lock_read(&x->lock); + const int is_set = x->ex_flags & EXFLAG_SET; + CRYPTO_MUTEX_unlock_read(&x->lock); + + if (is_set) { + return; + } + + CRYPTO_MUTEX_lock_write(&x->lock); + if (x->ex_flags & EXFLAG_SET) { + CRYPTO_MUTEX_unlock_write(&x->lock); + return; + } + + X509_digest(x, EVP_sha1(), x->sha1_hash, NULL); + /* 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, &j, NULL); + if (!x->nc && (j != -1)) + x->ex_flags |= EXFLAG_INVALID; + setup_crldp(x); + + for (j = 0; j < X509_get_ext_count(x); j++) { + ex = X509_get_ext(x, j); + 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_MUTEX_unlock_write(&x->lock); +} + +/* + * 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; + size_t 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; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_skey.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_skey.c new file mode 100644 index 0000000..a8830b5 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_skey.c @@ -0,0 +1,152 @@ +/* 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 + +#include +#include +#include +#include + +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())) { + OPENSSL_PUT_ERROR(X509V3, 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())) { + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + return NULL; + } + + if (ctx && (ctx->flags == CTX_TEST)) + return oct; + + if (!ctx || (!ctx->subject_req && !ctx->subject_cert)) { + OPENSSL_PUT_ERROR(X509V3, 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) { + OPENSSL_PUT_ERROR(X509V3, 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)) { + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + goto err; + } + + return oct; + + err: + M_ASN1_OCTET_STRING_free(oct); + return NULL; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_skey.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_skey.c.grpc_back new file mode 100644 index 0000000..65f8287 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_skey.c.grpc_back @@ -0,0 +1,152 @@ +/* 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 + +#include +#include +#include +#include + +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())) { + OPENSSL_PUT_ERROR(X509V3, 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())) { + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + return NULL; + } + + if (ctx && (ctx->flags == CTX_TEST)) + return oct; + + if (!ctx || (!ctx->subject_req && !ctx->subject_cert)) { + OPENSSL_PUT_ERROR(X509V3, 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) { + OPENSSL_PUT_ERROR(X509V3, 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)) { + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + goto err; + } + + return oct; + + err: + M_ASN1_OCTET_STRING_free(oct); + return NULL; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_sxnet.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_sxnet.c new file mode 100644 index 0000000..75ff4bc --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_sxnet.c @@ -0,0 +1,274 @@ +/* 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 + +#include +#include +#include +#include +#include +#include +#include + +/* 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; + size_t 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; + size_t 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))) { + OPENSSL_PUT_ERROR(X509V3, 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)) { + OPENSSL_PUT_ERROR(X509V3, 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) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NULL_ARGUMENT); + return 0; + } + if (userlen == -1) + userlen = strlen(user); + if (userlen > 64) { + OPENSSL_PUT_ERROR(X509V3, 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)) { + OPENSSL_PUT_ERROR(X509V3, 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: + OPENSSL_PUT_ERROR(X509V3, 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))) { + OPENSSL_PUT_ERROR(X509V3, 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)) { + OPENSSL_PUT_ERROR(X509V3, 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; + size_t 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_ASN1_SET_OF(SXNETID) diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_sxnet.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_sxnet.c.grpc_back new file mode 100644 index 0000000..51c5a67 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_sxnet.c.grpc_back @@ -0,0 +1,274 @@ +/* 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 + +#include +#include +#include +#include +#include +#include +#include + +/* 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; + size_t 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; + size_t 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))) { + OPENSSL_PUT_ERROR(X509V3, 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)) { + OPENSSL_PUT_ERROR(X509V3, 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) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_INVALID_NULL_ARGUMENT); + return 0; + } + if (userlen == -1) + userlen = strlen(user); + if (userlen > 64) { + OPENSSL_PUT_ERROR(X509V3, 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)) { + OPENSSL_PUT_ERROR(X509V3, 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: + OPENSSL_PUT_ERROR(X509V3, 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))) { + OPENSSL_PUT_ERROR(X509V3, 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)) { + OPENSSL_PUT_ERROR(X509V3, 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; + size_t 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_ASN1_SET_OF(SXNETID) diff --git a/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_utl.c b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_utl.c new file mode 100644 index 0000000..55d97bf --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_utl.c @@ -0,0 +1,1352 @@ +/* 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 + +#include +#include +#include +#include +#include +#include +#include + +#include "../conf/internal.h" +#include "../internal.h" + + +static char *strip_spaces(char *name); +static int sk_strcmp(const OPENSSL_STRING *a, const OPENSSL_STRING *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_new())) + 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: + OPENSSL_PUT_ERROR(X509V3, 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; +} + +static char *bignum_to_string(const BIGNUM *bn) +{ + char *tmp, *ret; + size_t len; + + /* + * Display large numbers in hex and small numbers in decimal. Converting to + * decimal takes quadratic time and is no more useful than hex for large + * numbers. + */ + if (BN_num_bits(bn) < 32) { + return BN_bn2dec(bn); + } + + tmp = BN_bn2hex(bn); + if (tmp == NULL) { + return NULL; + } + + len = strlen(tmp) + 3; + ret = OPENSSL_malloc(len); + if (ret == NULL) { + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + OPENSSL_free(tmp); + return NULL; + } + + /* Prepend "0x", but place it after the "-" if negative. */ + if (tmp[0] == '-') { + BUF_strlcpy(ret, "-0x", len); + BUF_strlcat(ret, tmp + 1, len); + } else { + BUF_strlcpy(ret, "0x", len); + BUF_strlcat(ret, tmp, len); + } + OPENSSL_free(tmp); + return ret; +} + +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 = bignum_to_string(bntmp))) + OPENSSL_PUT_ERROR(X509V3, 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 = bignum_to_string(bntmp))) + OPENSSL_PUT_ERROR(X509V3, 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) { + OPENSSL_PUT_ERROR(X509V3, 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); + OPENSSL_PUT_ERROR(X509V3, 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) { + OPENSSL_PUT_ERROR(X509V3, 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: + OPENSSL_PUT_ERROR(X509V3, 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) { + OPENSSL_PUT_ERROR(X509V3, 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) { + OPENSSL_PUT_ERROR(X509V3, 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) { + OPENSSL_PUT_ERROR(X509V3, 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) { + OPENSSL_PUT_ERROR(X509V3, 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) { + OPENSSL_PUT_ERROR(X509V3, 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) { + OPENSSL_PUT_ERROR(X509V3, 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; + static const char hexdig[] = "0123456789ABCDEF"; + if (!buffer || !len) + return NULL; + if (!(tmp = OPENSSL_malloc(len * 3 + 1))) { + OPENSSL_PUT_ERROR(X509V3, 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; + + 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) { + OPENSSL_PUT_ERROR(X509V3, 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++; + if (ch == ':') + continue; + cl = *p++; + if (!cl) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_ODD_NUMBER_OF_DIGITS); + OPENSSL_free(hexbuf); + return NULL; + } + + if ((ch >= '0') && (ch <= '9')) + ch -= '0'; + else if ((ch >= 'a') && (ch <= 'f')) + ch -= 'a' - 10; + 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 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); + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + return NULL; + + badhex: + OPENSSL_free(hexbuf); + OPENSSL_PUT_ERROR(X509V3, 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 OPENSSL_STRING *a, const OPENSSL_STRING *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; + size_t 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; + size_t j; + /* 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 (j = 0; j < sk_GENERAL_NAME_num(gens); j++) { + gen = sk_GENERAL_NAME_value(gens, j); + 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, NULL, (char *)email->data)) + 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 OPENSSL_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 !OPENSSL_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 + && OPENSSL_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 + && OPENSSL_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 && !OPENSSL_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) + 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; + size_t i; + int j; + 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; + } + + 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; + + j = -1; + name = X509_get_subject_name(x); + while ((j = X509_NAME_get_index_by_NID(name, cnid, j)) >= 0) { + X509_NAME_ENTRY *ne; + ASN1_STRING *str; + ne = X509_NAME_get_entry(name, j); + 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; + if (OPENSSL_memchr(chk, '\0', chklen)) + return -2; + 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; + if (OPENSSL_memchr(chk, '\0', chklen)) + return -2; + 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 */ + OPENSSL_memcpy(v6, v6stat.tmp, v6stat.zero_pos); + /* Zero middle */ + OPENSSL_memset(v6 + v6stat.zero_pos, 0, 16 - v6stat.total); + /* Copy final part */ + if (v6stat.total != v6stat.zero_pos) + OPENSSL_memcpy(v6 + v6stat.zero_pos + 16 - v6stat.total, + v6stat.tmp + v6stat.zero_pos, + v6stat.total - v6stat.zero_pos); + } else + OPENSSL_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 mval; + size_t i; + 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++) + if ((*p == ':') || (*p == ',') || (*p == '.')) { + p++; + if (*p) + type = p; + break; + } + if (*type == '+') { + 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/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_utl.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_utl.c.grpc_back new file mode 100644 index 0000000..7d109ee --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/crypto/x509v3/v3_utl.c.grpc_back @@ -0,0 +1,1352 @@ +/* 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 + +#include +#include +#include +#include +#include +#include +#include + +#include "../conf/internal.h" +#include "../internal.h" + + +static char *strip_spaces(char *name); +static int sk_strcmp(const OPENSSL_STRING *a, const OPENSSL_STRING *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_new())) + 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: + OPENSSL_PUT_ERROR(X509V3, 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; +} + +static char *bignum_to_string(const BIGNUM *bn) +{ + char *tmp, *ret; + size_t len; + + /* + * Display large numbers in hex and small numbers in decimal. Converting to + * decimal takes quadratic time and is no more useful than hex for large + * numbers. + */ + if (BN_num_bits(bn) < 32) { + return BN_bn2dec(bn); + } + + tmp = BN_bn2hex(bn); + if (tmp == NULL) { + return NULL; + } + + len = strlen(tmp) + 3; + ret = OPENSSL_malloc(len); + if (ret == NULL) { + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + OPENSSL_free(tmp); + return NULL; + } + + /* Prepend "0x", but place it after the "-" if negative. */ + if (tmp[0] == '-') { + BUF_strlcpy(ret, "-0x", len); + BUF_strlcat(ret, tmp + 1, len); + } else { + BUF_strlcpy(ret, "0x", len); + BUF_strlcat(ret, tmp, len); + } + OPENSSL_free(tmp); + return ret; +} + +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 = bignum_to_string(bntmp))) + OPENSSL_PUT_ERROR(X509V3, 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 = bignum_to_string(bntmp))) + OPENSSL_PUT_ERROR(X509V3, 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) { + OPENSSL_PUT_ERROR(X509V3, 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); + OPENSSL_PUT_ERROR(X509V3, 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) { + OPENSSL_PUT_ERROR(X509V3, 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: + OPENSSL_PUT_ERROR(X509V3, 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) { + OPENSSL_PUT_ERROR(X509V3, 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) { + OPENSSL_PUT_ERROR(X509V3, 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) { + OPENSSL_PUT_ERROR(X509V3, 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) { + OPENSSL_PUT_ERROR(X509V3, 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) { + OPENSSL_PUT_ERROR(X509V3, 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) { + OPENSSL_PUT_ERROR(X509V3, 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; + static const char hexdig[] = "0123456789ABCDEF"; + if (!buffer || !len) + return NULL; + if (!(tmp = OPENSSL_malloc(len * 3 + 1))) { + OPENSSL_PUT_ERROR(X509V3, 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; + + 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) { + OPENSSL_PUT_ERROR(X509V3, 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++; + if (ch == ':') + continue; + cl = *p++; + if (!cl) { + OPENSSL_PUT_ERROR(X509V3, X509V3_R_ODD_NUMBER_OF_DIGITS); + OPENSSL_free(hexbuf); + return NULL; + } + + if ((ch >= '0') && (ch <= '9')) + ch -= '0'; + else if ((ch >= 'a') && (ch <= 'f')) + ch -= 'a' - 10; + 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 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); + OPENSSL_PUT_ERROR(X509V3, ERR_R_MALLOC_FAILURE); + return NULL; + + badhex: + OPENSSL_free(hexbuf); + OPENSSL_PUT_ERROR(X509V3, 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 OPENSSL_STRING *a, const OPENSSL_STRING *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; + size_t 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; + size_t j; + /* 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 (j = 0; j < sk_GENERAL_NAME_num(gens); j++) { + gen = sk_GENERAL_NAME_value(gens, j); + 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, NULL, (char *)email->data)) + 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 OPENSSL_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 !OPENSSL_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 + && OPENSSL_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 + && OPENSSL_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 && !OPENSSL_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) + 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; + size_t i; + int j; + 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; + } + + 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; + + j = -1; + name = X509_get_subject_name(x); + while ((j = X509_NAME_get_index_by_NID(name, cnid, j)) >= 0) { + X509_NAME_ENTRY *ne; + ASN1_STRING *str; + ne = X509_NAME_get_entry(name, j); + 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; + if (OPENSSL_memchr(chk, '\0', chklen)) + return -2; + 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; + if (OPENSSL_memchr(chk, '\0', chklen)) + return -2; + 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 */ + OPENSSL_memcpy(v6, v6stat.tmp, v6stat.zero_pos); + /* Zero middle */ + OPENSSL_memset(v6 + v6stat.zero_pos, 0, 16 - v6stat.total); + /* Copy final part */ + if (v6stat.total != v6stat.zero_pos) + OPENSSL_memcpy(v6 + v6stat.zero_pos + 16 - v6stat.total, + v6stat.tmp + v6stat.zero_pos, + v6stat.total - v6stat.zero_pos); + } else + OPENSSL_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 mval; + size_t i; + 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++) + if ((*p == ':') || (*p == ',') || (*p == '.')) { + p++; + if (*p) + type = p; + break; + } + if (*type == '+') { + 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/FoodApp/Pods/BoringSSL-GRPC/err_data.c b/FoodApp/Pods/BoringSSL-GRPC/err_data.c new file mode 100644 index 0000000..54e7086 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/err_data.c @@ -0,0 +1,1341 @@ + /* Copyright (c) 2015, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + + /* This file was generated by err_data_generate.go. */ + + #include + #include + #include + + + OPENSSL_COMPILE_ASSERT(ERR_LIB_NONE == 1, library_values_changed_1); + OPENSSL_COMPILE_ASSERT(ERR_LIB_SYS == 2, library_values_changed_2); + OPENSSL_COMPILE_ASSERT(ERR_LIB_BN == 3, library_values_changed_3); + OPENSSL_COMPILE_ASSERT(ERR_LIB_RSA == 4, library_values_changed_4); + OPENSSL_COMPILE_ASSERT(ERR_LIB_DH == 5, library_values_changed_5); + OPENSSL_COMPILE_ASSERT(ERR_LIB_EVP == 6, library_values_changed_6); + OPENSSL_COMPILE_ASSERT(ERR_LIB_BUF == 7, library_values_changed_7); + OPENSSL_COMPILE_ASSERT(ERR_LIB_OBJ == 8, library_values_changed_8); + OPENSSL_COMPILE_ASSERT(ERR_LIB_PEM == 9, library_values_changed_9); + OPENSSL_COMPILE_ASSERT(ERR_LIB_DSA == 10, library_values_changed_10); + OPENSSL_COMPILE_ASSERT(ERR_LIB_X509 == 11, library_values_changed_11); + OPENSSL_COMPILE_ASSERT(ERR_LIB_ASN1 == 12, library_values_changed_12); + OPENSSL_COMPILE_ASSERT(ERR_LIB_CONF == 13, library_values_changed_13); + OPENSSL_COMPILE_ASSERT(ERR_LIB_CRYPTO == 14, library_values_changed_14); + OPENSSL_COMPILE_ASSERT(ERR_LIB_EC == 15, library_values_changed_15); + OPENSSL_COMPILE_ASSERT(ERR_LIB_SSL == 16, library_values_changed_16); + OPENSSL_COMPILE_ASSERT(ERR_LIB_BIO == 17, library_values_changed_17); + OPENSSL_COMPILE_ASSERT(ERR_LIB_PKCS7 == 18, library_values_changed_18); + OPENSSL_COMPILE_ASSERT(ERR_LIB_PKCS8 == 19, library_values_changed_19); + OPENSSL_COMPILE_ASSERT(ERR_LIB_X509V3 == 20, library_values_changed_20); + OPENSSL_COMPILE_ASSERT(ERR_LIB_RAND == 21, library_values_changed_21); + OPENSSL_COMPILE_ASSERT(ERR_LIB_ENGINE == 22, library_values_changed_22); + OPENSSL_COMPILE_ASSERT(ERR_LIB_OCSP == 23, library_values_changed_23); + OPENSSL_COMPILE_ASSERT(ERR_LIB_UI == 24, library_values_changed_24); + OPENSSL_COMPILE_ASSERT(ERR_LIB_COMP == 25, library_values_changed_25); + OPENSSL_COMPILE_ASSERT(ERR_LIB_ECDSA == 26, library_values_changed_26); + OPENSSL_COMPILE_ASSERT(ERR_LIB_ECDH == 27, library_values_changed_27); + OPENSSL_COMPILE_ASSERT(ERR_LIB_HMAC == 28, library_values_changed_28); + OPENSSL_COMPILE_ASSERT(ERR_LIB_DIGEST == 29, library_values_changed_29); + OPENSSL_COMPILE_ASSERT(ERR_LIB_CIPHER == 30, library_values_changed_30); + OPENSSL_COMPILE_ASSERT(ERR_LIB_HKDF == 31, library_values_changed_31); + OPENSSL_COMPILE_ASSERT(ERR_LIB_USER == 32, library_values_changed_32); + OPENSSL_COMPILE_ASSERT(ERR_NUM_LIBS == 33, library_values_changed_num); + + const uint32_t kOpenSSLReasonValues[] = { + 0xc320838, + 0xc328852, + 0xc330861, + 0xc338871, + 0xc340880, + 0xc348899, + 0xc3508a5, + 0xc3588c2, + 0xc3608e2, + 0xc3688f0, + 0xc370900, + 0xc37890d, + 0xc38091d, + 0xc388928, + 0xc39093e, + 0xc39894d, + 0xc3a0961, + 0xc3a8845, + 0xc3b00ea, + 0xc3b88d4, + 0x10320845, + 0x10329513, + 0x1033151f, + 0x10339538, + 0x1034154b, + 0x10348eed, + 0x10350c5e, + 0x1035955e, + 0x10361573, + 0x10369586, + 0x103715a5, + 0x103795be, + 0x103815d3, + 0x103895f1, + 0x10391600, + 0x1039961c, + 0x103a1637, + 0x103a9646, + 0x103b1662, + 0x103b967d, + 0x103c1694, + 0x103c80ea, + 0x103d16a5, + 0x103d96b9, + 0x103e16d8, + 0x103e96e7, + 0x103f16fe, + 0x103f9711, + 0x10400c22, + 0x10409724, + 0x10411742, + 0x10419755, + 0x1042176f, + 0x1042977f, + 0x10431793, + 0x104397a9, + 0x104417c1, + 0x104497d6, + 0x104517ea, + 0x104597fc, + 0x104605fb, + 0x1046894d, + 0x10471811, + 0x10479828, + 0x1048183d, + 0x1048984b, + 0x10490e4f, + 0x14320c05, + 0x14328c13, + 0x14330c22, + 0x14338c34, + 0x143400ac, + 0x143480ea, + 0x18320083, + 0x18328f43, + 0x183300ac, + 0x18338f59, + 0x18340f6d, + 0x183480ea, + 0x18350f82, + 0x18358f9a, + 0x18360faf, + 0x18368fc3, + 0x18370fe7, + 0x18378ffd, + 0x18381011, + 0x18389021, + 0x18390a73, + 0x18399031, + 0x183a1059, + 0x183a907f, + 0x183b0c6a, + 0x183b90b4, + 0x183c10c6, + 0x183c90d1, + 0x183d10e1, + 0x183d90f2, + 0x183e1103, + 0x183e9115, + 0x183f113e, + 0x183f9157, + 0x1840116f, + 0x184086d3, + 0x184110a2, + 0x1841906d, + 0x1842108c, + 0x18429046, + 0x20321196, + 0x243211a2, + 0x24328993, + 0x243311b4, + 0x243391c1, + 0x243411ce, + 0x243491e0, + 0x243511ef, + 0x2435920c, + 0x24361219, + 0x24369227, + 0x24371235, + 0x24379243, + 0x2438124c, + 0x24389259, + 0x2439126c, + 0x28320c52, + 0x28328c6a, + 0x28330c22, + 0x28338c7d, + 0x28340c5e, + 0x283480ac, + 0x283500ea, + 0x2c322c30, + 0x2c329283, + 0x2c332c3e, + 0x2c33ac50, + 0x2c342c64, + 0x2c34ac76, + 0x2c352c91, + 0x2c35aca3, + 0x2c362cb6, + 0x2c36832d, + 0x2c372cc3, + 0x2c37acd5, + 0x2c382cfa, + 0x2c38ad11, + 0x2c392d1f, + 0x2c39ad2f, + 0x2c3a2d41, + 0x2c3aad55, + 0x2c3b2d66, + 0x2c3bad85, + 0x2c3c1295, + 0x2c3c92ab, + 0x2c3d2d99, + 0x2c3d92c4, + 0x2c3e2db6, + 0x2c3eadc4, + 0x2c3f2ddc, + 0x2c3fadf4, + 0x2c402e01, + 0x2c409196, + 0x2c412e12, + 0x2c41ae25, + 0x2c42116f, + 0x2c42ae36, + 0x2c430720, + 0x2c43ad77, + 0x2c442ce8, + 0x30320000, + 0x30328015, + 0x3033001f, + 0x30338038, + 0x3034004a, + 0x30348064, + 0x3035006b, + 0x30358083, + 0x30360094, + 0x303680ac, + 0x303700b9, + 0x303780c8, + 0x303800ea, + 0x303880f7, + 0x3039010a, + 0x30398125, + 0x303a013a, + 0x303a814e, + 0x303b0162, + 0x303b8173, + 0x303c018c, + 0x303c81a9, + 0x303d01b7, + 0x303d81cb, + 0x303e01db, + 0x303e81f4, + 0x303f0204, + 0x303f8217, + 0x30400226, + 0x30408232, + 0x30410247, + 0x30418257, + 0x3042026e, + 0x3042827b, + 0x3043028e, + 0x3043829d, + 0x304402b2, + 0x304482d3, + 0x304502e6, + 0x304582f9, + 0x30460312, + 0x3046832d, + 0x3047034a, + 0x30478363, + 0x30480371, + 0x30488382, + 0x30490391, + 0x304983a9, + 0x304a03bb, + 0x304a83cf, + 0x304b03ee, + 0x304b8401, + 0x304c040c, + 0x304c841d, + 0x304d0429, + 0x304d843f, + 0x304e044d, + 0x304e8463, + 0x304f0475, + 0x304f8487, + 0x3050049a, + 0x305084ad, + 0x305104be, + 0x305184ce, + 0x305204e6, + 0x305284fb, + 0x30530513, + 0x30538527, + 0x3054053f, + 0x30548558, + 0x30550571, + 0x3055858e, + 0x30560599, + 0x305685b1, + 0x305705c1, + 0x305785d2, + 0x305805e5, + 0x305885fb, + 0x30590604, + 0x30598619, + 0x305a062c, + 0x305a863b, + 0x305b065b, + 0x305b866a, + 0x305c068b, + 0x305c86a7, + 0x305d06b3, + 0x305d86d3, + 0x305e06ef, + 0x305e8700, + 0x305f0716, + 0x305f8720, + 0x34320b63, + 0x34328b77, + 0x34330b94, + 0x34338ba7, + 0x34340bb6, + 0x34348bef, + 0x34350bd3, + 0x3c320083, + 0x3c328ca7, + 0x3c330cc0, + 0x3c338cdb, + 0x3c340cf8, + 0x3c348d22, + 0x3c350d3d, + 0x3c358d63, + 0x3c360d7c, + 0x3c368d94, + 0x3c370da5, + 0x3c378db3, + 0x3c380dc0, + 0x3c388dd4, + 0x3c390c6a, + 0x3c398de8, + 0x3c3a0dfc, + 0x3c3a890d, + 0x3c3b0e0c, + 0x3c3b8e27, + 0x3c3c0e39, + 0x3c3c8e6c, + 0x3c3d0e76, + 0x3c3d8e8a, + 0x3c3e0e98, + 0x3c3e8ebd, + 0x3c3f0c93, + 0x3c3f8ea6, + 0x3c4000ac, + 0x3c4080ea, + 0x3c410d13, + 0x3c418d52, + 0x3c420e4f, + 0x403218a4, + 0x403298ba, + 0x403318e8, + 0x403398f2, + 0x40341909, + 0x40349927, + 0x40351937, + 0x40359949, + 0x40361956, + 0x40369962, + 0x40371977, + 0x40379989, + 0x40381994, + 0x403899a6, + 0x40390eed, + 0x403999b6, + 0x403a19c9, + 0x403a99ea, + 0x403b19fb, + 0x403b9a0b, + 0x403c0064, + 0x403c8083, + 0x403d1a8f, + 0x403d9aa5, + 0x403e1ab4, + 0x403e9aec, + 0x403f1b06, + 0x403f9b14, + 0x40401b29, + 0x40409b3d, + 0x40411b5a, + 0x40419b75, + 0x40421b8e, + 0x40429ba1, + 0x40431bb5, + 0x40439bcd, + 0x40441be4, + 0x404480ac, + 0x40451bf9, + 0x40459c0b, + 0x40461c2f, + 0x40469c4f, + 0x40471c5d, + 0x40479c84, + 0x40481cc1, + 0x40489cda, + 0x40491cf1, + 0x40499d0b, + 0x404a1d22, + 0x404a9d40, + 0x404b1d58, + 0x404b9d6f, + 0x404c1d85, + 0x404c9d97, + 0x404d1db8, + 0x404d9dda, + 0x404e1dee, + 0x404e9dfb, + 0x404f1e28, + 0x404f9e51, + 0x40501e8c, + 0x40509ea0, + 0x40511ebb, + 0x40521ecb, + 0x40529eef, + 0x40531f07, + 0x40539f1a, + 0x40541f2f, + 0x40549f52, + 0x40551f60, + 0x40559f7d, + 0x40561f8a, + 0x40569fa3, + 0x40571fbb, + 0x40579fce, + 0x40581fe3, + 0x4058a00a, + 0x40592039, + 0x4059a066, + 0x405a207a, + 0x405aa08a, + 0x405b20a2, + 0x405ba0b3, + 0x405c20c6, + 0x405ca105, + 0x405d2112, + 0x405da129, + 0x405e2167, + 0x405e8ab1, + 0x405f2188, + 0x405fa195, + 0x406021a3, + 0x4060a1c5, + 0x40612209, + 0x4061a241, + 0x40622258, + 0x4062a269, + 0x4063227a, + 0x4063a28f, + 0x406422a6, + 0x4064a2d2, + 0x406522ed, + 0x4065a304, + 0x4066231c, + 0x4066a346, + 0x40672371, + 0x4067a392, + 0x406823b9, + 0x4068a3da, + 0x4069240c, + 0x4069a43a, + 0x406a245b, + 0x406aa47b, + 0x406b2603, + 0x406ba626, + 0x406c263c, + 0x406ca8b7, + 0x406d28e6, + 0x406da90e, + 0x406e293c, + 0x406ea989, + 0x406f29a8, + 0x406fa9e0, + 0x407029f3, + 0x4070aa10, + 0x40710800, + 0x4071aa22, + 0x40722a35, + 0x4072aa4e, + 0x40732a66, + 0x40739482, + 0x40742a7a, + 0x4074aa94, + 0x40752aa5, + 0x4075aab9, + 0x40762ac7, + 0x40769259, + 0x40772aec, + 0x4077ab0e, + 0x40782b29, + 0x4078ab62, + 0x40792b79, + 0x4079ab8f, + 0x407a2b9b, + 0x407aabae, + 0x407b2bc3, + 0x407babd5, + 0x407c2c06, + 0x407cac0f, + 0x407d23f5, + 0x407d9e61, + 0x407e2b3e, + 0x407ea01a, + 0x407f1c71, + 0x407f9a31, + 0x40801e38, + 0x40809c99, + 0x40811edd, + 0x40819e12, + 0x40822927, + 0x40829a17, + 0x40831ff5, + 0x4083a2b7, + 0x40841cad, + 0x4084a052, + 0x408520d7, + 0x4085a1ed, + 0x40862149, + 0x40869e7b, + 0x4087296d, + 0x4087a21e, + 0x40881a78, + 0x4088a3a5, + 0x40891ac7, + 0x40899a54, + 0x408a265c, + 0x408a9862, + 0x408b2bea, + 0x408ba9bd, + 0x408c20e7, + 0x408c987e, + 0x41f4252e, + 0x41f925c0, + 0x41fe24b3, + 0x41fea6a8, + 0x41ff2799, + 0x42032547, + 0x42082569, + 0x4208a5a5, + 0x42092497, + 0x4209a5df, + 0x420a24ee, + 0x420aa4ce, + 0x420b250e, + 0x420ba587, + 0x420c27b5, + 0x420ca675, + 0x420d268f, + 0x420da6c6, + 0x421226e0, + 0x4217277c, + 0x4217a722, + 0x421c2744, + 0x421f26ff, + 0x422127cc, + 0x4226275f, + 0x422b289b, + 0x422ba849, + 0x422c2883, + 0x422ca808, + 0x422d27e7, + 0x422da868, + 0x422e282e, + 0x422ea954, + 0x4432072b, + 0x4432873a, + 0x44330746, + 0x44338754, + 0x44340767, + 0x44348778, + 0x4435077f, + 0x44358789, + 0x4436079c, + 0x443687b2, + 0x443707c4, + 0x443787d1, + 0x443807e0, + 0x443887e8, + 0x44390800, + 0x4439880e, + 0x443a0821, + 0x48321283, + 0x48329295, + 0x483312ab, + 0x483392c4, + 0x4c3212e9, + 0x4c3292f9, + 0x4c33130c, + 0x4c33932c, + 0x4c3400ac, + 0x4c3480ea, + 0x4c351338, + 0x4c359346, + 0x4c361362, + 0x4c369375, + 0x4c371384, + 0x4c379392, + 0x4c3813a7, + 0x4c3893b3, + 0x4c3913d3, + 0x4c3993fd, + 0x4c3a1416, + 0x4c3a942f, + 0x4c3b05fb, + 0x4c3b9448, + 0x4c3c145a, + 0x4c3c9469, + 0x4c3d1482, + 0x4c3d8c45, + 0x4c3e14db, + 0x4c3e9491, + 0x4c3f14fd, + 0x4c3f9259, + 0x4c4014a7, + 0x4c4092d5, + 0x4c4114cb, + 0x50322e48, + 0x5032ae57, + 0x50332e62, + 0x5033ae72, + 0x50342e8b, + 0x5034aea5, + 0x50352eb3, + 0x5035aec9, + 0x50362edb, + 0x5036aef1, + 0x50372f0a, + 0x5037af1d, + 0x50382f35, + 0x5038af46, + 0x50392f5b, + 0x5039af6f, + 0x503a2f8f, + 0x503aafa5, + 0x503b2fbd, + 0x503bafcf, + 0x503c2feb, + 0x503cb002, + 0x503d301b, + 0x503db031, + 0x503e303e, + 0x503eb054, + 0x503f3066, + 0x503f8382, + 0x50403079, + 0x5040b089, + 0x504130a3, + 0x5041b0b2, + 0x504230cc, + 0x5042b0e9, + 0x504330f9, + 0x5043b109, + 0x50443118, + 0x5044843f, + 0x5045312c, + 0x5045b14a, + 0x5046315d, + 0x5046b173, + 0x50473185, + 0x5047b19a, + 0x504831c0, + 0x5048b1ce, + 0x504931e1, + 0x5049b1f6, + 0x504a320c, + 0x504ab21c, + 0x504b323c, + 0x504bb24f, + 0x504c3272, + 0x504cb2a0, + 0x504d32b2, + 0x504db2cf, + 0x504e32ea, + 0x504eb306, + 0x504f3318, + 0x504fb32f, + 0x5050333e, + 0x505086ef, + 0x50513351, + 0x58320f2b, + 0x68320eed, + 0x68328c6a, + 0x68330c7d, + 0x68338efb, + 0x68340f0b, + 0x683480ea, + 0x6c320ec9, + 0x6c328c34, + 0x6c330ed4, + 0x74320a19, + 0x743280ac, + 0x74330c45, + 0x7832097e, + 0x78328993, + 0x7833099f, + 0x78338083, + 0x783409ae, + 0x783489c3, + 0x783509e2, + 0x78358a04, + 0x78360a19, + 0x78368a2f, + 0x78370a3f, + 0x78378a60, + 0x78380a73, + 0x78388a85, + 0x78390a92, + 0x78398ab1, + 0x783a0ac6, + 0x783a8ad4, + 0x783b0ade, + 0x783b8af2, + 0x783c0b09, + 0x783c8b1e, + 0x783d0b35, + 0x783d8b4a, + 0x783e0aa0, + 0x783e8a52, + 0x7c321185, + }; + + const size_t kOpenSSLReasonValuesLen = sizeof(kOpenSSLReasonValues) / sizeof(kOpenSSLReasonValues[0]); + + const char kOpenSSLReasonStringData[] = + "ASN1_LENGTH_MISMATCH\0" + "AUX_ERROR\0" + "BAD_GET_ASN1_OBJECT_CALL\0" + "BAD_OBJECT_HEADER\0" + "BMPSTRING_IS_WRONG_LENGTH\0" + "BN_LIB\0" + "BOOLEAN_IS_WRONG_LENGTH\0" + "BUFFER_TOO_SMALL\0" + "CONTEXT_NOT_INITIALISED\0" + "DECODE_ERROR\0" + "DEPTH_EXCEEDED\0" + "DIGEST_AND_KEY_TYPE_NOT_SUPPORTED\0" + "ENCODE_ERROR\0" + "ERROR_GETTING_TIME\0" + "EXPECTING_AN_ASN1_SEQUENCE\0" + "EXPECTING_AN_INTEGER\0" + "EXPECTING_AN_OBJECT\0" + "EXPECTING_A_BOOLEAN\0" + "EXPECTING_A_TIME\0" + "EXPLICIT_LENGTH_MISMATCH\0" + "EXPLICIT_TAG_NOT_CONSTRUCTED\0" + "FIELD_MISSING\0" + "FIRST_NUM_TOO_LARGE\0" + "HEADER_TOO_LONG\0" + "ILLEGAL_BITSTRING_FORMAT\0" + "ILLEGAL_BOOLEAN\0" + "ILLEGAL_CHARACTERS\0" + "ILLEGAL_FORMAT\0" + "ILLEGAL_HEX\0" + "ILLEGAL_IMPLICIT_TAG\0" + "ILLEGAL_INTEGER\0" + "ILLEGAL_NESTED_TAGGING\0" + "ILLEGAL_NULL\0" + "ILLEGAL_NULL_VALUE\0" + "ILLEGAL_OBJECT\0" + "ILLEGAL_OPTIONAL_ANY\0" + "ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE\0" + "ILLEGAL_TAGGED_ANY\0" + "ILLEGAL_TIME_VALUE\0" + "INTEGER_NOT_ASCII_FORMAT\0" + "INTEGER_TOO_LARGE_FOR_LONG\0" + "INVALID_BIT_STRING_BITS_LEFT\0" + "INVALID_BMPSTRING_LENGTH\0" + "INVALID_DIGIT\0" + "INVALID_MODIFIER\0" + "INVALID_NUMBER\0" + "INVALID_OBJECT_ENCODING\0" + "INVALID_SEPARATOR\0" + "INVALID_TIME_FORMAT\0" + "INVALID_UNIVERSALSTRING_LENGTH\0" + "INVALID_UTF8STRING\0" + "LIST_ERROR\0" + "MISSING_ASN1_EOS\0" + "MISSING_EOC\0" + "MISSING_SECOND_NUMBER\0" + "MISSING_VALUE\0" + "MSTRING_NOT_UNIVERSAL\0" + "MSTRING_WRONG_TAG\0" + "NESTED_ASN1_ERROR\0" + "NESTED_ASN1_STRING\0" + "NON_HEX_CHARACTERS\0" + "NOT_ASCII_FORMAT\0" + "NOT_ENOUGH_DATA\0" + "NO_MATCHING_CHOICE_TYPE\0" + "NULL_IS_WRONG_LENGTH\0" + "OBJECT_NOT_ASCII_FORMAT\0" + "ODD_NUMBER_OF_CHARS\0" + "SECOND_NUMBER_TOO_LARGE\0" + "SEQUENCE_LENGTH_MISMATCH\0" + "SEQUENCE_NOT_CONSTRUCTED\0" + "SEQUENCE_OR_SET_NEEDS_CONFIG\0" + "SHORT_LINE\0" + "STREAMING_NOT_SUPPORTED\0" + "STRING_TOO_LONG\0" + "STRING_TOO_SHORT\0" + "TAG_VALUE_TOO_HIGH\0" + "TIME_NOT_ASCII_FORMAT\0" + "TOO_LONG\0" + "TYPE_NOT_CONSTRUCTED\0" + "TYPE_NOT_PRIMITIVE\0" + "UNEXPECTED_EOC\0" + "UNIVERSALSTRING_IS_WRONG_LENGTH\0" + "UNKNOWN_FORMAT\0" + "UNKNOWN_MESSAGE_DIGEST_ALGORITHM\0" + "UNKNOWN_SIGNATURE_ALGORITHM\0" + "UNKNOWN_TAG\0" + "UNSUPPORTED_ANY_DEFINED_BY_TYPE\0" + "UNSUPPORTED_PUBLIC_KEY_TYPE\0" + "UNSUPPORTED_TYPE\0" + "WRONG_PUBLIC_KEY_TYPE\0" + "WRONG_TAG\0" + "WRONG_TYPE\0" + "BAD_FOPEN_MODE\0" + "BROKEN_PIPE\0" + "CONNECT_ERROR\0" + "ERROR_SETTING_NBIO\0" + "INVALID_ARGUMENT\0" + "IN_USE\0" + "KEEPALIVE\0" + "NBIO_CONNECT_ERROR\0" + "NO_HOSTNAME_SPECIFIED\0" + "NO_PORT_SPECIFIED\0" + "NO_SUCH_FILE\0" + "NULL_PARAMETER\0" + "SYS_LIB\0" + "UNABLE_TO_CREATE_SOCKET\0" + "UNINITIALIZED\0" + "UNSUPPORTED_METHOD\0" + "WRITE_TO_READ_ONLY_BIO\0" + "ARG2_LT_ARG3\0" + "BAD_ENCODING\0" + "BAD_RECIPROCAL\0" + "BIGNUM_TOO_LONG\0" + "BITS_TOO_SMALL\0" + "CALLED_WITH_EVEN_MODULUS\0" + "DIV_BY_ZERO\0" + "EXPAND_ON_STATIC_BIGNUM_DATA\0" + "INPUT_NOT_REDUCED\0" + "INVALID_INPUT\0" + "INVALID_RANGE\0" + "NEGATIVE_NUMBER\0" + "NOT_A_SQUARE\0" + "NOT_INITIALIZED\0" + "NO_INVERSE\0" + "PRIVATE_KEY_TOO_LARGE\0" + "P_IS_NOT_PRIME\0" + "TOO_MANY_ITERATIONS\0" + "TOO_MANY_TEMPORARY_VARIABLES\0" + "AES_KEY_SETUP_FAILED\0" + "BAD_DECRYPT\0" + "BAD_KEY_LENGTH\0" + "CTRL_NOT_IMPLEMENTED\0" + "CTRL_OPERATION_NOT_IMPLEMENTED\0" + "DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH\0" + "INITIALIZATION_ERROR\0" + "INPUT_NOT_INITIALIZED\0" + "INVALID_AD_SIZE\0" + "INVALID_KEY_LENGTH\0" + "INVALID_NONCE\0" + "INVALID_NONCE_SIZE\0" + "INVALID_OPERATION\0" + "IV_TOO_LARGE\0" + "NO_CIPHER_SET\0" + "NO_DIRECTION_SET\0" + "OUTPUT_ALIASES_INPUT\0" + "TAG_TOO_LARGE\0" + "TOO_LARGE\0" + "UNSUPPORTED_AD_SIZE\0" + "UNSUPPORTED_INPUT_SIZE\0" + "UNSUPPORTED_KEY_SIZE\0" + "UNSUPPORTED_NONCE_SIZE\0" + "UNSUPPORTED_TAG_SIZE\0" + "WRONG_FINAL_BLOCK_LENGTH\0" + "LIST_CANNOT_BE_NULL\0" + "MISSING_CLOSE_SQUARE_BRACKET\0" + "MISSING_EQUAL_SIGN\0" + "NO_CLOSE_BRACE\0" + "UNABLE_TO_CREATE_NEW_SECTION\0" + "VARIABLE_EXPANSION_TOO_LONG\0" + "VARIABLE_HAS_NO_VALUE\0" + "BAD_GENERATOR\0" + "INVALID_PUBKEY\0" + "MODULUS_TOO_LARGE\0" + "NO_PRIVATE_VALUE\0" + "UNKNOWN_HASH\0" + "BAD_Q_VALUE\0" + "BAD_VERSION\0" + "MISSING_PARAMETERS\0" + "NEED_NEW_SETUP_VALUES\0" + "BIGNUM_OUT_OF_RANGE\0" + "COORDINATES_OUT_OF_RANGE\0" + "D2I_ECPKPARAMETERS_FAILURE\0" + "EC_GROUP_NEW_BY_NAME_FAILURE\0" + "GROUP2PKPARAMETERS_FAILURE\0" + "GROUP_MISMATCH\0" + "I2D_ECPKPARAMETERS_FAILURE\0" + "INCOMPATIBLE_OBJECTS\0" + "INVALID_COFACTOR\0" + "INVALID_COMPRESSED_POINT\0" + "INVALID_COMPRESSION_BIT\0" + "INVALID_ENCODING\0" + "INVALID_FIELD\0" + "INVALID_FORM\0" + "INVALID_GROUP_ORDER\0" + "INVALID_PRIVATE_KEY\0" + "MISSING_PRIVATE_KEY\0" + "NON_NAMED_CURVE\0" + "PKPARAMETERS2GROUP_FAILURE\0" + "POINT_AT_INFINITY\0" + "POINT_IS_NOT_ON_CURVE\0" + "PUBLIC_KEY_VALIDATION_FAILED\0" + "SLOT_FULL\0" + "UNDEFINED_GENERATOR\0" + "UNKNOWN_GROUP\0" + "UNKNOWN_ORDER\0" + "WRONG_CURVE_PARAMETERS\0" + "WRONG_ORDER\0" + "KDF_FAILED\0" + "POINT_ARITHMETIC_FAILURE\0" + "BAD_SIGNATURE\0" + "NOT_IMPLEMENTED\0" + "RANDOM_NUMBER_GENERATION_FAILED\0" + "OPERATION_NOT_SUPPORTED\0" + "COMMAND_NOT_SUPPORTED\0" + "DIFFERENT_KEY_TYPES\0" + "DIFFERENT_PARAMETERS\0" + "EXPECTING_AN_EC_KEY_KEY\0" + "EXPECTING_AN_RSA_KEY\0" + "EXPECTING_A_DSA_KEY\0" + "ILLEGAL_OR_UNSUPPORTED_PADDING_MODE\0" + "INVALID_DIGEST_LENGTH\0" + "INVALID_DIGEST_TYPE\0" + "INVALID_KEYBITS\0" + "INVALID_MGF1_MD\0" + "INVALID_PADDING_MODE\0" + "INVALID_PARAMETERS\0" + "INVALID_PSS_SALTLEN\0" + "INVALID_SIGNATURE\0" + "KEYS_NOT_SET\0" + "MEMORY_LIMIT_EXCEEDED\0" + "NOT_A_PRIVATE_KEY\0" + "NO_DEFAULT_DIGEST\0" + "NO_KEY_SET\0" + "NO_MDC2_SUPPORT\0" + "NO_NID_FOR_CURVE\0" + "NO_OPERATION_SET\0" + "NO_PARAMETERS_SET\0" + "OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE\0" + "OPERATON_NOT_INITIALIZED\0" + "UNKNOWN_PUBLIC_KEY_TYPE\0" + "UNSUPPORTED_ALGORITHM\0" + "OUTPUT_TOO_LARGE\0" + "UNKNOWN_NID\0" + "BAD_BASE64_DECODE\0" + "BAD_END_LINE\0" + "BAD_IV_CHARS\0" + "BAD_PASSWORD_READ\0" + "CIPHER_IS_NULL\0" + "ERROR_CONVERTING_PRIVATE_KEY\0" + "NOT_DEK_INFO\0" + "NOT_ENCRYPTED\0" + "NOT_PROC_TYPE\0" + "NO_START_LINE\0" + "READ_KEY\0" + "SHORT_HEADER\0" + "UNSUPPORTED_CIPHER\0" + "UNSUPPORTED_ENCRYPTION\0" + "BAD_PKCS7_VERSION\0" + "NOT_PKCS7_SIGNED_DATA\0" + "NO_CERTIFICATES_INCLUDED\0" + "NO_CRLS_INCLUDED\0" + "BAD_ITERATION_COUNT\0" + "BAD_PKCS12_DATA\0" + "BAD_PKCS12_VERSION\0" + "CIPHER_HAS_NO_OBJECT_IDENTIFIER\0" + "CRYPT_ERROR\0" + "ENCRYPT_ERROR\0" + "ERROR_SETTING_CIPHER_PARAMS\0" + "INCORRECT_PASSWORD\0" + "KEYGEN_FAILURE\0" + "KEY_GEN_ERROR\0" + "METHOD_NOT_SUPPORTED\0" + "MISSING_MAC\0" + "MULTIPLE_PRIVATE_KEYS_IN_PKCS12\0" + "PKCS12_PUBLIC_KEY_INTEGRITY_NOT_SUPPORTED\0" + "PKCS12_TOO_DEEPLY_NESTED\0" + "PRIVATE_KEY_DECODE_ERROR\0" + "PRIVATE_KEY_ENCODE_ERROR\0" + "UNKNOWN_ALGORITHM\0" + "UNKNOWN_CIPHER\0" + "UNKNOWN_CIPHER_ALGORITHM\0" + "UNKNOWN_DIGEST\0" + "UNSUPPORTED_KEYLENGTH\0" + "UNSUPPORTED_KEY_DERIVATION_FUNCTION\0" + "UNSUPPORTED_PRF\0" + "UNSUPPORTED_PRIVATE_KEY_ALGORITHM\0" + "UNSUPPORTED_SALT_TYPE\0" + "BAD_E_VALUE\0" + "BAD_FIXED_HEADER_DECRYPT\0" + "BAD_PAD_BYTE_COUNT\0" + "BAD_RSA_PARAMETERS\0" + "BLOCK_TYPE_IS_NOT_01\0" + "BN_NOT_INITIALIZED\0" + "CANNOT_RECOVER_MULTI_PRIME_KEY\0" + "CRT_PARAMS_ALREADY_GIVEN\0" + "CRT_VALUES_INCORRECT\0" + "DATA_LEN_NOT_EQUAL_TO_MOD_LEN\0" + "DATA_TOO_LARGE\0" + "DATA_TOO_LARGE_FOR_KEY_SIZE\0" + "DATA_TOO_LARGE_FOR_MODULUS\0" + "DATA_TOO_SMALL\0" + "DATA_TOO_SMALL_FOR_KEY_SIZE\0" + "DIGEST_TOO_BIG_FOR_RSA_KEY\0" + "D_E_NOT_CONGRUENT_TO_1\0" + "EMPTY_PUBLIC_KEY\0" + "FIRST_OCTET_INVALID\0" + "INCONSISTENT_SET_OF_CRT_VALUES\0" + "INTERNAL_ERROR\0" + "INVALID_MESSAGE_LENGTH\0" + "KEY_SIZE_TOO_SMALL\0" + "LAST_OCTET_INVALID\0" + "MUST_HAVE_AT_LEAST_TWO_PRIMES\0" + "NO_PUBLIC_EXPONENT\0" + "NULL_BEFORE_BLOCK_MISSING\0" + "N_NOT_EQUAL_P_Q\0" + "OAEP_DECODING_ERROR\0" + "ONLY_ONE_OF_P_Q_GIVEN\0" + "OUTPUT_BUFFER_TOO_SMALL\0" + "PADDING_CHECK_FAILED\0" + "PKCS_DECODING_ERROR\0" + "SLEN_CHECK_FAILED\0" + "SLEN_RECOVERY_FAILED\0" + "UNKNOWN_ALGORITHM_TYPE\0" + "UNKNOWN_PADDING_TYPE\0" + "VALUE_MISSING\0" + "WRONG_SIGNATURE_LENGTH\0" + "ALPN_MISMATCH_ON_EARLY_DATA\0" + "APPLICATION_DATA_INSTEAD_OF_HANDSHAKE\0" + "APP_DATA_IN_HANDSHAKE\0" + "ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT\0" + "BAD_ALERT\0" + "BAD_CHANGE_CIPHER_SPEC\0" + "BAD_DATA_RETURNED_BY_CALLBACK\0" + "BAD_DH_P_LENGTH\0" + "BAD_DIGEST_LENGTH\0" + "BAD_ECC_CERT\0" + "BAD_ECPOINT\0" + "BAD_HANDSHAKE_RECORD\0" + "BAD_HELLO_REQUEST\0" + "BAD_LENGTH\0" + "BAD_PACKET_LENGTH\0" + "BAD_RSA_ENCRYPT\0" + "BAD_SRTP_MKI_VALUE\0" + "BAD_SRTP_PROTECTION_PROFILE_LIST\0" + "BAD_SSL_FILETYPE\0" + "BAD_WRITE_RETRY\0" + "BIO_NOT_SET\0" + "BLOCK_CIPHER_PAD_IS_WRONG\0" + "BUFFERED_MESSAGES_ON_CIPHER_CHANGE\0" + "CANNOT_HAVE_BOTH_PRIVKEY_AND_METHOD\0" + "CANNOT_PARSE_LEAF_CERT\0" + "CA_DN_LENGTH_MISMATCH\0" + "CA_DN_TOO_LONG\0" + "CCS_RECEIVED_EARLY\0" + "CERTIFICATE_AND_PRIVATE_KEY_MISMATCH\0" + "CERTIFICATE_VERIFY_FAILED\0" + "CERT_CB_ERROR\0" + "CERT_LENGTH_MISMATCH\0" + "CHANNEL_ID_NOT_P256\0" + "CHANNEL_ID_SIGNATURE_INVALID\0" + "CIPHER_OR_HASH_UNAVAILABLE\0" + "CLIENTHELLO_PARSE_FAILED\0" + "CLIENTHELLO_TLSEXT\0" + "CONNECTION_REJECTED\0" + "CONNECTION_TYPE_NOT_SET\0" + "CUSTOM_EXTENSION_ERROR\0" + "DATA_LENGTH_TOO_LONG\0" + "DECRYPTION_FAILED\0" + "DECRYPTION_FAILED_OR_BAD_RECORD_MAC\0" + "DH_PUBLIC_VALUE_LENGTH_IS_WRONG\0" + "DH_P_TOO_LONG\0" + "DIGEST_CHECK_FAILED\0" + "DOWNGRADE_DETECTED\0" + "DTLS_MESSAGE_TOO_BIG\0" + "DUPLICATE_EXTENSION\0" + "DUPLICATE_KEY_SHARE\0" + "ECC_CERT_NOT_FOR_SIGNING\0" + "EMS_STATE_INCONSISTENT\0" + "ENCRYPTED_LENGTH_TOO_LONG\0" + "ERROR_ADDING_EXTENSION\0" + "ERROR_IN_RECEIVED_CIPHER_LIST\0" + "ERROR_PARSING_EXTENSION\0" + "EXCESSIVE_MESSAGE_SIZE\0" + "EXTRA_DATA_IN_MESSAGE\0" + "FRAGMENT_MISMATCH\0" + "GOT_NEXT_PROTO_WITHOUT_EXTENSION\0" + "HANDSHAKE_FAILURE_ON_CLIENT_HELLO\0" + "HTTPS_PROXY_REQUEST\0" + "HTTP_REQUEST\0" + "INAPPROPRIATE_FALLBACK\0" + "INVALID_ALPN_PROTOCOL\0" + "INVALID_COMMAND\0" + "INVALID_COMPRESSION_LIST\0" + "INVALID_MESSAGE\0" + "INVALID_OUTER_RECORD_TYPE\0" + "INVALID_SCT_LIST\0" + "INVALID_SSL_SESSION\0" + "INVALID_TICKET_KEYS_LENGTH\0" + "LENGTH_MISMATCH\0" + "MISSING_EXTENSION\0" + "MISSING_KEY_SHARE\0" + "MISSING_RSA_CERTIFICATE\0" + "MISSING_TMP_DH_KEY\0" + "MISSING_TMP_ECDH_KEY\0" + "MIXED_SPECIAL_OPERATOR_WITH_GROUPS\0" + "MTU_TOO_SMALL\0" + "NEGOTIATED_BOTH_NPN_AND_ALPN\0" + "NESTED_GROUP\0" + "NO_CERTIFICATES_RETURNED\0" + "NO_CERTIFICATE_ASSIGNED\0" + "NO_CERTIFICATE_SET\0" + "NO_CIPHERS_AVAILABLE\0" + "NO_CIPHERS_PASSED\0" + "NO_CIPHERS_SPECIFIED\0" + "NO_CIPHER_MATCH\0" + "NO_COMMON_SIGNATURE_ALGORITHMS\0" + "NO_COMPRESSION_SPECIFIED\0" + "NO_GROUPS_SPECIFIED\0" + "NO_METHOD_SPECIFIED\0" + "NO_P256_SUPPORT\0" + "NO_PRIVATE_KEY_ASSIGNED\0" + "NO_RENEGOTIATION\0" + "NO_REQUIRED_DIGEST\0" + "NO_SHARED_CIPHER\0" + "NO_SHARED_GROUP\0" + "NO_SUPPORTED_VERSIONS_ENABLED\0" + "NULL_SSL_CTX\0" + "NULL_SSL_METHOD_PASSED\0" + "OLD_SESSION_CIPHER_NOT_RETURNED\0" + "OLD_SESSION_PRF_HASH_MISMATCH\0" + "OLD_SESSION_VERSION_NOT_RETURNED\0" + "PARSE_TLSEXT\0" + "PATH_TOO_LONG\0" + "PEER_DID_NOT_RETURN_A_CERTIFICATE\0" + "PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE\0" + "PRE_SHARED_KEY_MUST_BE_LAST\0" + "PROTOCOL_IS_SHUTDOWN\0" + "PSK_IDENTITY_BINDER_COUNT_MISMATCH\0" + "PSK_IDENTITY_NOT_FOUND\0" + "PSK_NO_CLIENT_CB\0" + "PSK_NO_SERVER_CB\0" + "READ_TIMEOUT_EXPIRED\0" + "RECORD_LENGTH_MISMATCH\0" + "RECORD_TOO_LARGE\0" + "RENEGOTIATION_EMS_MISMATCH\0" + "RENEGOTIATION_ENCODING_ERR\0" + "RENEGOTIATION_MISMATCH\0" + "REQUIRED_CIPHER_MISSING\0" + "RESUMED_EMS_SESSION_WITHOUT_EMS_EXTENSION\0" + "RESUMED_NON_EMS_SESSION_WITH_EMS_EXTENSION\0" + "SCSV_RECEIVED_WHEN_RENEGOTIATING\0" + "SERVERHELLO_TLSEXT\0" + "SERVER_CERT_CHANGED\0" + "SESSION_ID_CONTEXT_UNINITIALIZED\0" + "SESSION_MAY_NOT_BE_CREATED\0" + "SHUTDOWN_WHILE_IN_INIT\0" + "SIGNATURE_ALGORITHMS_EXTENSION_SENT_BY_SERVER\0" + "SRTP_COULD_NOT_ALLOCATE_PROFILES\0" + "SRTP_UNKNOWN_PROTECTION_PROFILE\0" + "SSL3_EXT_INVALID_SERVERNAME\0" + "SSLV3_ALERT_BAD_CERTIFICATE\0" + "SSLV3_ALERT_BAD_RECORD_MAC\0" + "SSLV3_ALERT_CERTIFICATE_EXPIRED\0" + "SSLV3_ALERT_CERTIFICATE_REVOKED\0" + "SSLV3_ALERT_CERTIFICATE_UNKNOWN\0" + "SSLV3_ALERT_CLOSE_NOTIFY\0" + "SSLV3_ALERT_DECOMPRESSION_FAILURE\0" + "SSLV3_ALERT_HANDSHAKE_FAILURE\0" + "SSLV3_ALERT_ILLEGAL_PARAMETER\0" + "SSLV3_ALERT_NO_CERTIFICATE\0" + "SSLV3_ALERT_UNEXPECTED_MESSAGE\0" + "SSLV3_ALERT_UNSUPPORTED_CERTIFICATE\0" + "SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION\0" + "SSL_HANDSHAKE_FAILURE\0" + "SSL_SESSION_ID_CONTEXT_TOO_LONG\0" + "TICKET_ENCRYPTION_FAILED\0" + "TLSV1_ALERT_ACCESS_DENIED\0" + "TLSV1_ALERT_DECODE_ERROR\0" + "TLSV1_ALERT_DECRYPTION_FAILED\0" + "TLSV1_ALERT_DECRYPT_ERROR\0" + "TLSV1_ALERT_EXPORT_RESTRICTION\0" + "TLSV1_ALERT_INAPPROPRIATE_FALLBACK\0" + "TLSV1_ALERT_INSUFFICIENT_SECURITY\0" + "TLSV1_ALERT_INTERNAL_ERROR\0" + "TLSV1_ALERT_NO_RENEGOTIATION\0" + "TLSV1_ALERT_PROTOCOL_VERSION\0" + "TLSV1_ALERT_RECORD_OVERFLOW\0" + "TLSV1_ALERT_UNKNOWN_CA\0" + "TLSV1_ALERT_USER_CANCELLED\0" + "TLSV1_BAD_CERTIFICATE_HASH_VALUE\0" + "TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE\0" + "TLSV1_CERTIFICATE_REQUIRED\0" + "TLSV1_CERTIFICATE_UNOBTAINABLE\0" + "TLSV1_UNKNOWN_PSK_IDENTITY\0" + "TLSV1_UNRECOGNIZED_NAME\0" + "TLSV1_UNSUPPORTED_EXTENSION\0" + "TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST\0" + "TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG\0" + "TOO_MANY_EMPTY_FRAGMENTS\0" + "TOO_MANY_KEY_UPDATES\0" + "TOO_MANY_WARNING_ALERTS\0" + "TOO_MUCH_READ_EARLY_DATA\0" + "TOO_MUCH_SKIPPED_EARLY_DATA\0" + "UNABLE_TO_FIND_ECDH_PARAMETERS\0" + "UNEXPECTED_EXTENSION\0" + "UNEXPECTED_EXTENSION_ON_EARLY_DATA\0" + "UNEXPECTED_MESSAGE\0" + "UNEXPECTED_OPERATOR_IN_GROUP\0" + "UNEXPECTED_RECORD\0" + "UNKNOWN_ALERT_TYPE\0" + "UNKNOWN_CERTIFICATE_TYPE\0" + "UNKNOWN_CIPHER_RETURNED\0" + "UNKNOWN_CIPHER_TYPE\0" + "UNKNOWN_KEY_EXCHANGE_TYPE\0" + "UNKNOWN_PROTOCOL\0" + "UNKNOWN_SSL_VERSION\0" + "UNKNOWN_STATE\0" + "UNSAFE_LEGACY_RENEGOTIATION_DISABLED\0" + "UNSUPPORTED_COMPRESSION_ALGORITHM\0" + "UNSUPPORTED_ELLIPTIC_CURVE\0" + "UNSUPPORTED_PROTOCOL\0" + "UNSUPPORTED_PROTOCOL_FOR_CUSTOM_KEY\0" + "WRONG_CERTIFICATE_TYPE\0" + "WRONG_CIPHER_RETURNED\0" + "WRONG_CURVE\0" + "WRONG_MESSAGE_TYPE\0" + "WRONG_SIGNATURE_TYPE\0" + "WRONG_SSL_VERSION\0" + "WRONG_VERSION_NUMBER\0" + "WRONG_VERSION_ON_EARLY_DATA\0" + "X509_LIB\0" + "X509_VERIFICATION_SETUP_PROBLEMS\0" + "AKID_MISMATCH\0" + "BAD_X509_FILETYPE\0" + "BASE64_DECODE_ERROR\0" + "CANT_CHECK_DH_KEY\0" + "CERT_ALREADY_IN_HASH_TABLE\0" + "CRL_ALREADY_DELTA\0" + "CRL_VERIFY_FAILURE\0" + "IDP_MISMATCH\0" + "INVALID_DIRECTORY\0" + "INVALID_FIELD_NAME\0" + "INVALID_PARAMETER\0" + "INVALID_PSS_PARAMETERS\0" + "INVALID_TRUST\0" + "ISSUER_MISMATCH\0" + "KEY_TYPE_MISMATCH\0" + "KEY_VALUES_MISMATCH\0" + "LOADING_CERT_DIR\0" + "LOADING_DEFAULTS\0" + "NAME_TOO_LONG\0" + "NEWER_CRL_NOT_NEWER\0" + "NO_CERT_SET_FOR_US_TO_VERIFY\0" + "NO_CRL_NUMBER\0" + "PUBLIC_KEY_DECODE_ERROR\0" + "PUBLIC_KEY_ENCODE_ERROR\0" + "SHOULD_RETRY\0" + "UNKNOWN_KEY_TYPE\0" + "UNKNOWN_PURPOSE_ID\0" + "UNKNOWN_TRUST_ID\0" + "WRONG_LOOKUP_TYPE\0" + "BAD_IP_ADDRESS\0" + "BAD_OBJECT\0" + "BN_DEC2BN_ERROR\0" + "BN_TO_ASN1_INTEGER_ERROR\0" + "CANNOT_FIND_FREE_FUNCTION\0" + "DIRNAME_ERROR\0" + "DISTPOINT_ALREADY_SET\0" + "DUPLICATE_ZONE_ID\0" + "ERROR_CONVERTING_ZONE\0" + "ERROR_CREATING_EXTENSION\0" + "ERROR_IN_EXTENSION\0" + "EXPECTED_A_SECTION_NAME\0" + "EXTENSION_EXISTS\0" + "EXTENSION_NAME_ERROR\0" + "EXTENSION_NOT_FOUND\0" + "EXTENSION_SETTING_NOT_SUPPORTED\0" + "EXTENSION_VALUE_ERROR\0" + "ILLEGAL_EMPTY_EXTENSION\0" + "ILLEGAL_HEX_DIGIT\0" + "INCORRECT_POLICY_SYNTAX_TAG\0" + "INVALID_BOOLEAN_STRING\0" + "INVALID_EXTENSION_STRING\0" + "INVALID_MULTIPLE_RDNS\0" + "INVALID_NAME\0" + "INVALID_NULL_ARGUMENT\0" + "INVALID_NULL_NAME\0" + "INVALID_NULL_VALUE\0" + "INVALID_NUMBERS\0" + "INVALID_OBJECT_IDENTIFIER\0" + "INVALID_OPTION\0" + "INVALID_POLICY_IDENTIFIER\0" + "INVALID_PROXY_POLICY_SETTING\0" + "INVALID_PURPOSE\0" + "INVALID_SECTION\0" + "INVALID_SYNTAX\0" + "ISSUER_DECODE_ERROR\0" + "NEED_ORGANIZATION_AND_NUMBERS\0" + "NO_CONFIG_DATABASE\0" + "NO_ISSUER_CERTIFICATE\0" + "NO_ISSUER_DETAILS\0" + "NO_POLICY_IDENTIFIER\0" + "NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED\0" + "NO_PUBLIC_KEY\0" + "NO_SUBJECT_DETAILS\0" + "ODD_NUMBER_OF_DIGITS\0" + "OPERATION_NOT_DEFINED\0" + "OTHERNAME_ERROR\0" + "POLICY_LANGUAGE_ALREADY_DEFINED\0" + "POLICY_PATH_LENGTH\0" + "POLICY_PATH_LENGTH_ALREADY_DEFINED\0" + "POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY\0" + "SECTION_NOT_FOUND\0" + "UNABLE_TO_GET_ISSUER_DETAILS\0" + "UNABLE_TO_GET_ISSUER_KEYID\0" + "UNKNOWN_BIT_STRING_ARGUMENT\0" + "UNKNOWN_EXTENSION\0" + "UNKNOWN_EXTENSION_NAME\0" + "UNKNOWN_OPTION\0" + "UNSUPPORTED_OPTION\0" + "USER_TOO_LONG\0" + ""; diff --git a/FoodApp/Pods/BoringSSL-GRPC/err_data.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/err_data.c.grpc_back new file mode 100644 index 0000000..e6c3f90 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/err_data.c.grpc_back @@ -0,0 +1,1341 @@ + /* Copyright (c) 2015, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + + /* This file was generated by err_data_generate.go. */ + + #include + #include + #include + + + OPENSSL_COMPILE_ASSERT(ERR_LIB_NONE == 1, library_values_changed_1); + OPENSSL_COMPILE_ASSERT(ERR_LIB_SYS == 2, library_values_changed_2); + OPENSSL_COMPILE_ASSERT(ERR_LIB_BN == 3, library_values_changed_3); + OPENSSL_COMPILE_ASSERT(ERR_LIB_RSA == 4, library_values_changed_4); + OPENSSL_COMPILE_ASSERT(ERR_LIB_DH == 5, library_values_changed_5); + OPENSSL_COMPILE_ASSERT(ERR_LIB_EVP == 6, library_values_changed_6); + OPENSSL_COMPILE_ASSERT(ERR_LIB_BUF == 7, library_values_changed_7); + OPENSSL_COMPILE_ASSERT(ERR_LIB_OBJ == 8, library_values_changed_8); + OPENSSL_COMPILE_ASSERT(ERR_LIB_PEM == 9, library_values_changed_9); + OPENSSL_COMPILE_ASSERT(ERR_LIB_DSA == 10, library_values_changed_10); + OPENSSL_COMPILE_ASSERT(ERR_LIB_X509 == 11, library_values_changed_11); + OPENSSL_COMPILE_ASSERT(ERR_LIB_ASN1 == 12, library_values_changed_12); + OPENSSL_COMPILE_ASSERT(ERR_LIB_CONF == 13, library_values_changed_13); + OPENSSL_COMPILE_ASSERT(ERR_LIB_CRYPTO == 14, library_values_changed_14); + OPENSSL_COMPILE_ASSERT(ERR_LIB_EC == 15, library_values_changed_15); + OPENSSL_COMPILE_ASSERT(ERR_LIB_SSL == 16, library_values_changed_16); + OPENSSL_COMPILE_ASSERT(ERR_LIB_BIO == 17, library_values_changed_17); + OPENSSL_COMPILE_ASSERT(ERR_LIB_PKCS7 == 18, library_values_changed_18); + OPENSSL_COMPILE_ASSERT(ERR_LIB_PKCS8 == 19, library_values_changed_19); + OPENSSL_COMPILE_ASSERT(ERR_LIB_X509V3 == 20, library_values_changed_20); + OPENSSL_COMPILE_ASSERT(ERR_LIB_RAND == 21, library_values_changed_21); + OPENSSL_COMPILE_ASSERT(ERR_LIB_ENGINE == 22, library_values_changed_22); + OPENSSL_COMPILE_ASSERT(ERR_LIB_OCSP == 23, library_values_changed_23); + OPENSSL_COMPILE_ASSERT(ERR_LIB_UI == 24, library_values_changed_24); + OPENSSL_COMPILE_ASSERT(ERR_LIB_COMP == 25, library_values_changed_25); + OPENSSL_COMPILE_ASSERT(ERR_LIB_ECDSA == 26, library_values_changed_26); + OPENSSL_COMPILE_ASSERT(ERR_LIB_ECDH == 27, library_values_changed_27); + OPENSSL_COMPILE_ASSERT(ERR_LIB_HMAC == 28, library_values_changed_28); + OPENSSL_COMPILE_ASSERT(ERR_LIB_DIGEST == 29, library_values_changed_29); + OPENSSL_COMPILE_ASSERT(ERR_LIB_CIPHER == 30, library_values_changed_30); + OPENSSL_COMPILE_ASSERT(ERR_LIB_HKDF == 31, library_values_changed_31); + OPENSSL_COMPILE_ASSERT(ERR_LIB_USER == 32, library_values_changed_32); + OPENSSL_COMPILE_ASSERT(ERR_NUM_LIBS == 33, library_values_changed_num); + + const uint32_t kOpenSSLReasonValues[] = { + 0xc320838, + 0xc328852, + 0xc330861, + 0xc338871, + 0xc340880, + 0xc348899, + 0xc3508a5, + 0xc3588c2, + 0xc3608e2, + 0xc3688f0, + 0xc370900, + 0xc37890d, + 0xc38091d, + 0xc388928, + 0xc39093e, + 0xc39894d, + 0xc3a0961, + 0xc3a8845, + 0xc3b00ea, + 0xc3b88d4, + 0x10320845, + 0x10329513, + 0x1033151f, + 0x10339538, + 0x1034154b, + 0x10348eed, + 0x10350c5e, + 0x1035955e, + 0x10361573, + 0x10369586, + 0x103715a5, + 0x103795be, + 0x103815d3, + 0x103895f1, + 0x10391600, + 0x1039961c, + 0x103a1637, + 0x103a9646, + 0x103b1662, + 0x103b967d, + 0x103c1694, + 0x103c80ea, + 0x103d16a5, + 0x103d96b9, + 0x103e16d8, + 0x103e96e7, + 0x103f16fe, + 0x103f9711, + 0x10400c22, + 0x10409724, + 0x10411742, + 0x10419755, + 0x1042176f, + 0x1042977f, + 0x10431793, + 0x104397a9, + 0x104417c1, + 0x104497d6, + 0x104517ea, + 0x104597fc, + 0x104605fb, + 0x1046894d, + 0x10471811, + 0x10479828, + 0x1048183d, + 0x1048984b, + 0x10490e4f, + 0x14320c05, + 0x14328c13, + 0x14330c22, + 0x14338c34, + 0x143400ac, + 0x143480ea, + 0x18320083, + 0x18328f43, + 0x183300ac, + 0x18338f59, + 0x18340f6d, + 0x183480ea, + 0x18350f82, + 0x18358f9a, + 0x18360faf, + 0x18368fc3, + 0x18370fe7, + 0x18378ffd, + 0x18381011, + 0x18389021, + 0x18390a73, + 0x18399031, + 0x183a1059, + 0x183a907f, + 0x183b0c6a, + 0x183b90b4, + 0x183c10c6, + 0x183c90d1, + 0x183d10e1, + 0x183d90f2, + 0x183e1103, + 0x183e9115, + 0x183f113e, + 0x183f9157, + 0x1840116f, + 0x184086d3, + 0x184110a2, + 0x1841906d, + 0x1842108c, + 0x18429046, + 0x20321196, + 0x243211a2, + 0x24328993, + 0x243311b4, + 0x243391c1, + 0x243411ce, + 0x243491e0, + 0x243511ef, + 0x2435920c, + 0x24361219, + 0x24369227, + 0x24371235, + 0x24379243, + 0x2438124c, + 0x24389259, + 0x2439126c, + 0x28320c52, + 0x28328c6a, + 0x28330c22, + 0x28338c7d, + 0x28340c5e, + 0x283480ac, + 0x283500ea, + 0x2c322c30, + 0x2c329283, + 0x2c332c3e, + 0x2c33ac50, + 0x2c342c64, + 0x2c34ac76, + 0x2c352c91, + 0x2c35aca3, + 0x2c362cb6, + 0x2c36832d, + 0x2c372cc3, + 0x2c37acd5, + 0x2c382cfa, + 0x2c38ad11, + 0x2c392d1f, + 0x2c39ad2f, + 0x2c3a2d41, + 0x2c3aad55, + 0x2c3b2d66, + 0x2c3bad85, + 0x2c3c1295, + 0x2c3c92ab, + 0x2c3d2d99, + 0x2c3d92c4, + 0x2c3e2db6, + 0x2c3eadc4, + 0x2c3f2ddc, + 0x2c3fadf4, + 0x2c402e01, + 0x2c409196, + 0x2c412e12, + 0x2c41ae25, + 0x2c42116f, + 0x2c42ae36, + 0x2c430720, + 0x2c43ad77, + 0x2c442ce8, + 0x30320000, + 0x30328015, + 0x3033001f, + 0x30338038, + 0x3034004a, + 0x30348064, + 0x3035006b, + 0x30358083, + 0x30360094, + 0x303680ac, + 0x303700b9, + 0x303780c8, + 0x303800ea, + 0x303880f7, + 0x3039010a, + 0x30398125, + 0x303a013a, + 0x303a814e, + 0x303b0162, + 0x303b8173, + 0x303c018c, + 0x303c81a9, + 0x303d01b7, + 0x303d81cb, + 0x303e01db, + 0x303e81f4, + 0x303f0204, + 0x303f8217, + 0x30400226, + 0x30408232, + 0x30410247, + 0x30418257, + 0x3042026e, + 0x3042827b, + 0x3043028e, + 0x3043829d, + 0x304402b2, + 0x304482d3, + 0x304502e6, + 0x304582f9, + 0x30460312, + 0x3046832d, + 0x3047034a, + 0x30478363, + 0x30480371, + 0x30488382, + 0x30490391, + 0x304983a9, + 0x304a03bb, + 0x304a83cf, + 0x304b03ee, + 0x304b8401, + 0x304c040c, + 0x304c841d, + 0x304d0429, + 0x304d843f, + 0x304e044d, + 0x304e8463, + 0x304f0475, + 0x304f8487, + 0x3050049a, + 0x305084ad, + 0x305104be, + 0x305184ce, + 0x305204e6, + 0x305284fb, + 0x30530513, + 0x30538527, + 0x3054053f, + 0x30548558, + 0x30550571, + 0x3055858e, + 0x30560599, + 0x305685b1, + 0x305705c1, + 0x305785d2, + 0x305805e5, + 0x305885fb, + 0x30590604, + 0x30598619, + 0x305a062c, + 0x305a863b, + 0x305b065b, + 0x305b866a, + 0x305c068b, + 0x305c86a7, + 0x305d06b3, + 0x305d86d3, + 0x305e06ef, + 0x305e8700, + 0x305f0716, + 0x305f8720, + 0x34320b63, + 0x34328b77, + 0x34330b94, + 0x34338ba7, + 0x34340bb6, + 0x34348bef, + 0x34350bd3, + 0x3c320083, + 0x3c328ca7, + 0x3c330cc0, + 0x3c338cdb, + 0x3c340cf8, + 0x3c348d22, + 0x3c350d3d, + 0x3c358d63, + 0x3c360d7c, + 0x3c368d94, + 0x3c370da5, + 0x3c378db3, + 0x3c380dc0, + 0x3c388dd4, + 0x3c390c6a, + 0x3c398de8, + 0x3c3a0dfc, + 0x3c3a890d, + 0x3c3b0e0c, + 0x3c3b8e27, + 0x3c3c0e39, + 0x3c3c8e6c, + 0x3c3d0e76, + 0x3c3d8e8a, + 0x3c3e0e98, + 0x3c3e8ebd, + 0x3c3f0c93, + 0x3c3f8ea6, + 0x3c4000ac, + 0x3c4080ea, + 0x3c410d13, + 0x3c418d52, + 0x3c420e4f, + 0x403218a4, + 0x403298ba, + 0x403318e8, + 0x403398f2, + 0x40341909, + 0x40349927, + 0x40351937, + 0x40359949, + 0x40361956, + 0x40369962, + 0x40371977, + 0x40379989, + 0x40381994, + 0x403899a6, + 0x40390eed, + 0x403999b6, + 0x403a19c9, + 0x403a99ea, + 0x403b19fb, + 0x403b9a0b, + 0x403c0064, + 0x403c8083, + 0x403d1a8f, + 0x403d9aa5, + 0x403e1ab4, + 0x403e9aec, + 0x403f1b06, + 0x403f9b14, + 0x40401b29, + 0x40409b3d, + 0x40411b5a, + 0x40419b75, + 0x40421b8e, + 0x40429ba1, + 0x40431bb5, + 0x40439bcd, + 0x40441be4, + 0x404480ac, + 0x40451bf9, + 0x40459c0b, + 0x40461c2f, + 0x40469c4f, + 0x40471c5d, + 0x40479c84, + 0x40481cc1, + 0x40489cda, + 0x40491cf1, + 0x40499d0b, + 0x404a1d22, + 0x404a9d40, + 0x404b1d58, + 0x404b9d6f, + 0x404c1d85, + 0x404c9d97, + 0x404d1db8, + 0x404d9dda, + 0x404e1dee, + 0x404e9dfb, + 0x404f1e28, + 0x404f9e51, + 0x40501e8c, + 0x40509ea0, + 0x40511ebb, + 0x40521ecb, + 0x40529eef, + 0x40531f07, + 0x40539f1a, + 0x40541f2f, + 0x40549f52, + 0x40551f60, + 0x40559f7d, + 0x40561f8a, + 0x40569fa3, + 0x40571fbb, + 0x40579fce, + 0x40581fe3, + 0x4058a00a, + 0x40592039, + 0x4059a066, + 0x405a207a, + 0x405aa08a, + 0x405b20a2, + 0x405ba0b3, + 0x405c20c6, + 0x405ca105, + 0x405d2112, + 0x405da129, + 0x405e2167, + 0x405e8ab1, + 0x405f2188, + 0x405fa195, + 0x406021a3, + 0x4060a1c5, + 0x40612209, + 0x4061a241, + 0x40622258, + 0x4062a269, + 0x4063227a, + 0x4063a28f, + 0x406422a6, + 0x4064a2d2, + 0x406522ed, + 0x4065a304, + 0x4066231c, + 0x4066a346, + 0x40672371, + 0x4067a392, + 0x406823b9, + 0x4068a3da, + 0x4069240c, + 0x4069a43a, + 0x406a245b, + 0x406aa47b, + 0x406b2603, + 0x406ba626, + 0x406c263c, + 0x406ca8b7, + 0x406d28e6, + 0x406da90e, + 0x406e293c, + 0x406ea989, + 0x406f29a8, + 0x406fa9e0, + 0x407029f3, + 0x4070aa10, + 0x40710800, + 0x4071aa22, + 0x40722a35, + 0x4072aa4e, + 0x40732a66, + 0x40739482, + 0x40742a7a, + 0x4074aa94, + 0x40752aa5, + 0x4075aab9, + 0x40762ac7, + 0x40769259, + 0x40772aec, + 0x4077ab0e, + 0x40782b29, + 0x4078ab62, + 0x40792b79, + 0x4079ab8f, + 0x407a2b9b, + 0x407aabae, + 0x407b2bc3, + 0x407babd5, + 0x407c2c06, + 0x407cac0f, + 0x407d23f5, + 0x407d9e61, + 0x407e2b3e, + 0x407ea01a, + 0x407f1c71, + 0x407f9a31, + 0x40801e38, + 0x40809c99, + 0x40811edd, + 0x40819e12, + 0x40822927, + 0x40829a17, + 0x40831ff5, + 0x4083a2b7, + 0x40841cad, + 0x4084a052, + 0x408520d7, + 0x4085a1ed, + 0x40862149, + 0x40869e7b, + 0x4087296d, + 0x4087a21e, + 0x40881a78, + 0x4088a3a5, + 0x40891ac7, + 0x40899a54, + 0x408a265c, + 0x408a9862, + 0x408b2bea, + 0x408ba9bd, + 0x408c20e7, + 0x408c987e, + 0x41f4252e, + 0x41f925c0, + 0x41fe24b3, + 0x41fea6a8, + 0x41ff2799, + 0x42032547, + 0x42082569, + 0x4208a5a5, + 0x42092497, + 0x4209a5df, + 0x420a24ee, + 0x420aa4ce, + 0x420b250e, + 0x420ba587, + 0x420c27b5, + 0x420ca675, + 0x420d268f, + 0x420da6c6, + 0x421226e0, + 0x4217277c, + 0x4217a722, + 0x421c2744, + 0x421f26ff, + 0x422127cc, + 0x4226275f, + 0x422b289b, + 0x422ba849, + 0x422c2883, + 0x422ca808, + 0x422d27e7, + 0x422da868, + 0x422e282e, + 0x422ea954, + 0x4432072b, + 0x4432873a, + 0x44330746, + 0x44338754, + 0x44340767, + 0x44348778, + 0x4435077f, + 0x44358789, + 0x4436079c, + 0x443687b2, + 0x443707c4, + 0x443787d1, + 0x443807e0, + 0x443887e8, + 0x44390800, + 0x4439880e, + 0x443a0821, + 0x48321283, + 0x48329295, + 0x483312ab, + 0x483392c4, + 0x4c3212e9, + 0x4c3292f9, + 0x4c33130c, + 0x4c33932c, + 0x4c3400ac, + 0x4c3480ea, + 0x4c351338, + 0x4c359346, + 0x4c361362, + 0x4c369375, + 0x4c371384, + 0x4c379392, + 0x4c3813a7, + 0x4c3893b3, + 0x4c3913d3, + 0x4c3993fd, + 0x4c3a1416, + 0x4c3a942f, + 0x4c3b05fb, + 0x4c3b9448, + 0x4c3c145a, + 0x4c3c9469, + 0x4c3d1482, + 0x4c3d8c45, + 0x4c3e14db, + 0x4c3e9491, + 0x4c3f14fd, + 0x4c3f9259, + 0x4c4014a7, + 0x4c4092d5, + 0x4c4114cb, + 0x50322e48, + 0x5032ae57, + 0x50332e62, + 0x5033ae72, + 0x50342e8b, + 0x5034aea5, + 0x50352eb3, + 0x5035aec9, + 0x50362edb, + 0x5036aef1, + 0x50372f0a, + 0x5037af1d, + 0x50382f35, + 0x5038af46, + 0x50392f5b, + 0x5039af6f, + 0x503a2f8f, + 0x503aafa5, + 0x503b2fbd, + 0x503bafcf, + 0x503c2feb, + 0x503cb002, + 0x503d301b, + 0x503db031, + 0x503e303e, + 0x503eb054, + 0x503f3066, + 0x503f8382, + 0x50403079, + 0x5040b089, + 0x504130a3, + 0x5041b0b2, + 0x504230cc, + 0x5042b0e9, + 0x504330f9, + 0x5043b109, + 0x50443118, + 0x5044843f, + 0x5045312c, + 0x5045b14a, + 0x5046315d, + 0x5046b173, + 0x50473185, + 0x5047b19a, + 0x504831c0, + 0x5048b1ce, + 0x504931e1, + 0x5049b1f6, + 0x504a320c, + 0x504ab21c, + 0x504b323c, + 0x504bb24f, + 0x504c3272, + 0x504cb2a0, + 0x504d32b2, + 0x504db2cf, + 0x504e32ea, + 0x504eb306, + 0x504f3318, + 0x504fb32f, + 0x5050333e, + 0x505086ef, + 0x50513351, + 0x58320f2b, + 0x68320eed, + 0x68328c6a, + 0x68330c7d, + 0x68338efb, + 0x68340f0b, + 0x683480ea, + 0x6c320ec9, + 0x6c328c34, + 0x6c330ed4, + 0x74320a19, + 0x743280ac, + 0x74330c45, + 0x7832097e, + 0x78328993, + 0x7833099f, + 0x78338083, + 0x783409ae, + 0x783489c3, + 0x783509e2, + 0x78358a04, + 0x78360a19, + 0x78368a2f, + 0x78370a3f, + 0x78378a60, + 0x78380a73, + 0x78388a85, + 0x78390a92, + 0x78398ab1, + 0x783a0ac6, + 0x783a8ad4, + 0x783b0ade, + 0x783b8af2, + 0x783c0b09, + 0x783c8b1e, + 0x783d0b35, + 0x783d8b4a, + 0x783e0aa0, + 0x783e8a52, + 0x7c321185, + }; + + const size_t kOpenSSLReasonValuesLen = sizeof(kOpenSSLReasonValues) / sizeof(kOpenSSLReasonValues[0]); + + const char kOpenSSLReasonStringData[] = + "ASN1_LENGTH_MISMATCH\0" + "AUX_ERROR\0" + "BAD_GET_ASN1_OBJECT_CALL\0" + "BAD_OBJECT_HEADER\0" + "BMPSTRING_IS_WRONG_LENGTH\0" + "BN_LIB\0" + "BOOLEAN_IS_WRONG_LENGTH\0" + "BUFFER_TOO_SMALL\0" + "CONTEXT_NOT_INITIALISED\0" + "DECODE_ERROR\0" + "DEPTH_EXCEEDED\0" + "DIGEST_AND_KEY_TYPE_NOT_SUPPORTED\0" + "ENCODE_ERROR\0" + "ERROR_GETTING_TIME\0" + "EXPECTING_AN_ASN1_SEQUENCE\0" + "EXPECTING_AN_INTEGER\0" + "EXPECTING_AN_OBJECT\0" + "EXPECTING_A_BOOLEAN\0" + "EXPECTING_A_TIME\0" + "EXPLICIT_LENGTH_MISMATCH\0" + "EXPLICIT_TAG_NOT_CONSTRUCTED\0" + "FIELD_MISSING\0" + "FIRST_NUM_TOO_LARGE\0" + "HEADER_TOO_LONG\0" + "ILLEGAL_BITSTRING_FORMAT\0" + "ILLEGAL_BOOLEAN\0" + "ILLEGAL_CHARACTERS\0" + "ILLEGAL_FORMAT\0" + "ILLEGAL_HEX\0" + "ILLEGAL_IMPLICIT_TAG\0" + "ILLEGAL_INTEGER\0" + "ILLEGAL_NESTED_TAGGING\0" + "ILLEGAL_NULL\0" + "ILLEGAL_NULL_VALUE\0" + "ILLEGAL_OBJECT\0" + "ILLEGAL_OPTIONAL_ANY\0" + "ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE\0" + "ILLEGAL_TAGGED_ANY\0" + "ILLEGAL_TIME_VALUE\0" + "INTEGER_NOT_ASCII_FORMAT\0" + "INTEGER_TOO_LARGE_FOR_LONG\0" + "INVALID_BIT_STRING_BITS_LEFT\0" + "INVALID_BMPSTRING_LENGTH\0" + "INVALID_DIGIT\0" + "INVALID_MODIFIER\0" + "INVALID_NUMBER\0" + "INVALID_OBJECT_ENCODING\0" + "INVALID_SEPARATOR\0" + "INVALID_TIME_FORMAT\0" + "INVALID_UNIVERSALSTRING_LENGTH\0" + "INVALID_UTF8STRING\0" + "LIST_ERROR\0" + "MISSING_ASN1_EOS\0" + "MISSING_EOC\0" + "MISSING_SECOND_NUMBER\0" + "MISSING_VALUE\0" + "MSTRING_NOT_UNIVERSAL\0" + "MSTRING_WRONG_TAG\0" + "NESTED_ASN1_ERROR\0" + "NESTED_ASN1_STRING\0" + "NON_HEX_CHARACTERS\0" + "NOT_ASCII_FORMAT\0" + "NOT_ENOUGH_DATA\0" + "NO_MATCHING_CHOICE_TYPE\0" + "NULL_IS_WRONG_LENGTH\0" + "OBJECT_NOT_ASCII_FORMAT\0" + "ODD_NUMBER_OF_CHARS\0" + "SECOND_NUMBER_TOO_LARGE\0" + "SEQUENCE_LENGTH_MISMATCH\0" + "SEQUENCE_NOT_CONSTRUCTED\0" + "SEQUENCE_OR_SET_NEEDS_CONFIG\0" + "SHORT_LINE\0" + "STREAMING_NOT_SUPPORTED\0" + "STRING_TOO_LONG\0" + "STRING_TOO_SHORT\0" + "TAG_VALUE_TOO_HIGH\0" + "TIME_NOT_ASCII_FORMAT\0" + "TOO_LONG\0" + "TYPE_NOT_CONSTRUCTED\0" + "TYPE_NOT_PRIMITIVE\0" + "UNEXPECTED_EOC\0" + "UNIVERSALSTRING_IS_WRONG_LENGTH\0" + "UNKNOWN_FORMAT\0" + "UNKNOWN_MESSAGE_DIGEST_ALGORITHM\0" + "UNKNOWN_SIGNATURE_ALGORITHM\0" + "UNKNOWN_TAG\0" + "UNSUPPORTED_ANY_DEFINED_BY_TYPE\0" + "UNSUPPORTED_PUBLIC_KEY_TYPE\0" + "UNSUPPORTED_TYPE\0" + "WRONG_PUBLIC_KEY_TYPE\0" + "WRONG_TAG\0" + "WRONG_TYPE\0" + "BAD_FOPEN_MODE\0" + "BROKEN_PIPE\0" + "CONNECT_ERROR\0" + "ERROR_SETTING_NBIO\0" + "INVALID_ARGUMENT\0" + "IN_USE\0" + "KEEPALIVE\0" + "NBIO_CONNECT_ERROR\0" + "NO_HOSTNAME_SPECIFIED\0" + "NO_PORT_SPECIFIED\0" + "NO_SUCH_FILE\0" + "NULL_PARAMETER\0" + "SYS_LIB\0" + "UNABLE_TO_CREATE_SOCKET\0" + "UNINITIALIZED\0" + "UNSUPPORTED_METHOD\0" + "WRITE_TO_READ_ONLY_BIO\0" + "ARG2_LT_ARG3\0" + "BAD_ENCODING\0" + "BAD_RECIPROCAL\0" + "BIGNUM_TOO_LONG\0" + "BITS_TOO_SMALL\0" + "CALLED_WITH_EVEN_MODULUS\0" + "DIV_BY_ZERO\0" + "EXPAND_ON_STATIC_BIGNUM_DATA\0" + "INPUT_NOT_REDUCED\0" + "INVALID_INPUT\0" + "INVALID_RANGE\0" + "NEGATIVE_NUMBER\0" + "NOT_A_SQUARE\0" + "NOT_INITIALIZED\0" + "NO_INVERSE\0" + "PRIVATE_KEY_TOO_LARGE\0" + "P_IS_NOT_PRIME\0" + "TOO_MANY_ITERATIONS\0" + "TOO_MANY_TEMPORARY_VARIABLES\0" + "AES_KEY_SETUP_FAILED\0" + "BAD_DECRYPT\0" + "BAD_KEY_LENGTH\0" + "CTRL_NOT_IMPLEMENTED\0" + "CTRL_OPERATION_NOT_IMPLEMENTED\0" + "DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH\0" + "INITIALIZATION_ERROR\0" + "INPUT_NOT_INITIALIZED\0" + "INVALID_AD_SIZE\0" + "INVALID_KEY_LENGTH\0" + "INVALID_NONCE\0" + "INVALID_NONCE_SIZE\0" + "INVALID_OPERATION\0" + "IV_TOO_LARGE\0" + "NO_CIPHER_SET\0" + "NO_DIRECTION_SET\0" + "OUTPUT_ALIASES_INPUT\0" + "TAG_TOO_LARGE\0" + "TOO_LARGE\0" + "UNSUPPORTED_AD_SIZE\0" + "UNSUPPORTED_INPUT_SIZE\0" + "UNSUPPORTED_KEY_SIZE\0" + "UNSUPPORTED_NONCE_SIZE\0" + "UNSUPPORTED_TAG_SIZE\0" + "WRONG_FINAL_BLOCK_LENGTH\0" + "LIST_CANNOT_BE_NULL\0" + "MISSING_CLOSE_SQUARE_BRACKET\0" + "MISSING_EQUAL_SIGN\0" + "NO_CLOSE_BRACE\0" + "UNABLE_TO_CREATE_NEW_SECTION\0" + "VARIABLE_EXPANSION_TOO_LONG\0" + "VARIABLE_HAS_NO_VALUE\0" + "BAD_GENERATOR\0" + "INVALID_PUBKEY\0" + "MODULUS_TOO_LARGE\0" + "NO_PRIVATE_VALUE\0" + "UNKNOWN_HASH\0" + "BAD_Q_VALUE\0" + "BAD_VERSION\0" + "MISSING_PARAMETERS\0" + "NEED_NEW_SETUP_VALUES\0" + "BIGNUM_OUT_OF_RANGE\0" + "COORDINATES_OUT_OF_RANGE\0" + "D2I_ECPKPARAMETERS_FAILURE\0" + "EC_GROUP_NEW_BY_NAME_FAILURE\0" + "GROUP2PKPARAMETERS_FAILURE\0" + "GROUP_MISMATCH\0" + "I2D_ECPKPARAMETERS_FAILURE\0" + "INCOMPATIBLE_OBJECTS\0" + "INVALID_COFACTOR\0" + "INVALID_COMPRESSED_POINT\0" + "INVALID_COMPRESSION_BIT\0" + "INVALID_ENCODING\0" + "INVALID_FIELD\0" + "INVALID_FORM\0" + "INVALID_GROUP_ORDER\0" + "INVALID_PRIVATE_KEY\0" + "MISSING_PRIVATE_KEY\0" + "NON_NAMED_CURVE\0" + "PKPARAMETERS2GROUP_FAILURE\0" + "POINT_AT_INFINITY\0" + "POINT_IS_NOT_ON_CURVE\0" + "PUBLIC_KEY_VALIDATION_FAILED\0" + "SLOT_FULL\0" + "UNDEFINED_GENERATOR\0" + "UNKNOWN_GROUP\0" + "UNKNOWN_ORDER\0" + "WRONG_CURVE_PARAMETERS\0" + "WRONG_ORDER\0" + "KDF_FAILED\0" + "POINT_ARITHMETIC_FAILURE\0" + "BAD_SIGNATURE\0" + "NOT_IMPLEMENTED\0" + "RANDOM_NUMBER_GENERATION_FAILED\0" + "OPERATION_NOT_SUPPORTED\0" + "COMMAND_NOT_SUPPORTED\0" + "DIFFERENT_KEY_TYPES\0" + "DIFFERENT_PARAMETERS\0" + "EXPECTING_AN_EC_KEY_KEY\0" + "EXPECTING_AN_RSA_KEY\0" + "EXPECTING_A_DSA_KEY\0" + "ILLEGAL_OR_UNSUPPORTED_PADDING_MODE\0" + "INVALID_DIGEST_LENGTH\0" + "INVALID_DIGEST_TYPE\0" + "INVALID_KEYBITS\0" + "INVALID_MGF1_MD\0" + "INVALID_PADDING_MODE\0" + "INVALID_PARAMETERS\0" + "INVALID_PSS_SALTLEN\0" + "INVALID_SIGNATURE\0" + "KEYS_NOT_SET\0" + "MEMORY_LIMIT_EXCEEDED\0" + "NOT_A_PRIVATE_KEY\0" + "NO_DEFAULT_DIGEST\0" + "NO_KEY_SET\0" + "NO_MDC2_SUPPORT\0" + "NO_NID_FOR_CURVE\0" + "NO_OPERATION_SET\0" + "NO_PARAMETERS_SET\0" + "OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE\0" + "OPERATON_NOT_INITIALIZED\0" + "UNKNOWN_PUBLIC_KEY_TYPE\0" + "UNSUPPORTED_ALGORITHM\0" + "OUTPUT_TOO_LARGE\0" + "UNKNOWN_NID\0" + "BAD_BASE64_DECODE\0" + "BAD_END_LINE\0" + "BAD_IV_CHARS\0" + "BAD_PASSWORD_READ\0" + "CIPHER_IS_NULL\0" + "ERROR_CONVERTING_PRIVATE_KEY\0" + "NOT_DEK_INFO\0" + "NOT_ENCRYPTED\0" + "NOT_PROC_TYPE\0" + "NO_START_LINE\0" + "READ_KEY\0" + "SHORT_HEADER\0" + "UNSUPPORTED_CIPHER\0" + "UNSUPPORTED_ENCRYPTION\0" + "BAD_PKCS7_VERSION\0" + "NOT_PKCS7_SIGNED_DATA\0" + "NO_CERTIFICATES_INCLUDED\0" + "NO_CRLS_INCLUDED\0" + "BAD_ITERATION_COUNT\0" + "BAD_PKCS12_DATA\0" + "BAD_PKCS12_VERSION\0" + "CIPHER_HAS_NO_OBJECT_IDENTIFIER\0" + "CRYPT_ERROR\0" + "ENCRYPT_ERROR\0" + "ERROR_SETTING_CIPHER_PARAMS\0" + "INCORRECT_PASSWORD\0" + "KEYGEN_FAILURE\0" + "KEY_GEN_ERROR\0" + "METHOD_NOT_SUPPORTED\0" + "MISSING_MAC\0" + "MULTIPLE_PRIVATE_KEYS_IN_PKCS12\0" + "PKCS12_PUBLIC_KEY_INTEGRITY_NOT_SUPPORTED\0" + "PKCS12_TOO_DEEPLY_NESTED\0" + "PRIVATE_KEY_DECODE_ERROR\0" + "PRIVATE_KEY_ENCODE_ERROR\0" + "UNKNOWN_ALGORITHM\0" + "UNKNOWN_CIPHER\0" + "UNKNOWN_CIPHER_ALGORITHM\0" + "UNKNOWN_DIGEST\0" + "UNSUPPORTED_KEYLENGTH\0" + "UNSUPPORTED_KEY_DERIVATION_FUNCTION\0" + "UNSUPPORTED_PRF\0" + "UNSUPPORTED_PRIVATE_KEY_ALGORITHM\0" + "UNSUPPORTED_SALT_TYPE\0" + "BAD_E_VALUE\0" + "BAD_FIXED_HEADER_DECRYPT\0" + "BAD_PAD_BYTE_COUNT\0" + "BAD_RSA_PARAMETERS\0" + "BLOCK_TYPE_IS_NOT_01\0" + "BN_NOT_INITIALIZED\0" + "CANNOT_RECOVER_MULTI_PRIME_KEY\0" + "CRT_PARAMS_ALREADY_GIVEN\0" + "CRT_VALUES_INCORRECT\0" + "DATA_LEN_NOT_EQUAL_TO_MOD_LEN\0" + "DATA_TOO_LARGE\0" + "DATA_TOO_LARGE_FOR_KEY_SIZE\0" + "DATA_TOO_LARGE_FOR_MODULUS\0" + "DATA_TOO_SMALL\0" + "DATA_TOO_SMALL_FOR_KEY_SIZE\0" + "DIGEST_TOO_BIG_FOR_RSA_KEY\0" + "D_E_NOT_CONGRUENT_TO_1\0" + "EMPTY_PUBLIC_KEY\0" + "FIRST_OCTET_INVALID\0" + "INCONSISTENT_SET_OF_CRT_VALUES\0" + "INTERNAL_ERROR\0" + "INVALID_MESSAGE_LENGTH\0" + "KEY_SIZE_TOO_SMALL\0" + "LAST_OCTET_INVALID\0" + "MUST_HAVE_AT_LEAST_TWO_PRIMES\0" + "NO_PUBLIC_EXPONENT\0" + "NULL_BEFORE_BLOCK_MISSING\0" + "N_NOT_EQUAL_P_Q\0" + "OAEP_DECODING_ERROR\0" + "ONLY_ONE_OF_P_Q_GIVEN\0" + "OUTPUT_BUFFER_TOO_SMALL\0" + "PADDING_CHECK_FAILED\0" + "PKCS_DECODING_ERROR\0" + "SLEN_CHECK_FAILED\0" + "SLEN_RECOVERY_FAILED\0" + "UNKNOWN_ALGORITHM_TYPE\0" + "UNKNOWN_PADDING_TYPE\0" + "VALUE_MISSING\0" + "WRONG_SIGNATURE_LENGTH\0" + "ALPN_MISMATCH_ON_EARLY_DATA\0" + "APPLICATION_DATA_INSTEAD_OF_HANDSHAKE\0" + "APP_DATA_IN_HANDSHAKE\0" + "ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT\0" + "BAD_ALERT\0" + "BAD_CHANGE_CIPHER_SPEC\0" + "BAD_DATA_RETURNED_BY_CALLBACK\0" + "BAD_DH_P_LENGTH\0" + "BAD_DIGEST_LENGTH\0" + "BAD_ECC_CERT\0" + "BAD_ECPOINT\0" + "BAD_HANDSHAKE_RECORD\0" + "BAD_HELLO_REQUEST\0" + "BAD_LENGTH\0" + "BAD_PACKET_LENGTH\0" + "BAD_RSA_ENCRYPT\0" + "BAD_SRTP_MKI_VALUE\0" + "BAD_SRTP_PROTECTION_PROFILE_LIST\0" + "BAD_SSL_FILETYPE\0" + "BAD_WRITE_RETRY\0" + "BIO_NOT_SET\0" + "BLOCK_CIPHER_PAD_IS_WRONG\0" + "BUFFERED_MESSAGES_ON_CIPHER_CHANGE\0" + "CANNOT_HAVE_BOTH_PRIVKEY_AND_METHOD\0" + "CANNOT_PARSE_LEAF_CERT\0" + "CA_DN_LENGTH_MISMATCH\0" + "CA_DN_TOO_LONG\0" + "CCS_RECEIVED_EARLY\0" + "CERTIFICATE_AND_PRIVATE_KEY_MISMATCH\0" + "CERTIFICATE_VERIFY_FAILED\0" + "CERT_CB_ERROR\0" + "CERT_LENGTH_MISMATCH\0" + "CHANNEL_ID_NOT_P256\0" + "CHANNEL_ID_SIGNATURE_INVALID\0" + "CIPHER_OR_HASH_UNAVAILABLE\0" + "CLIENTHELLO_PARSE_FAILED\0" + "CLIENTHELLO_TLSEXT\0" + "CONNECTION_REJECTED\0" + "CONNECTION_TYPE_NOT_SET\0" + "CUSTOM_EXTENSION_ERROR\0" + "DATA_LENGTH_TOO_LONG\0" + "DECRYPTION_FAILED\0" + "DECRYPTION_FAILED_OR_BAD_RECORD_MAC\0" + "DH_PUBLIC_VALUE_LENGTH_IS_WRONG\0" + "DH_P_TOO_LONG\0" + "DIGEST_CHECK_FAILED\0" + "DOWNGRADE_DETECTED\0" + "DTLS_MESSAGE_TOO_BIG\0" + "DUPLICATE_EXTENSION\0" + "DUPLICATE_KEY_SHARE\0" + "ECC_CERT_NOT_FOR_SIGNING\0" + "EMS_STATE_INCONSISTENT\0" + "ENCRYPTED_LENGTH_TOO_LONG\0" + "ERROR_ADDING_EXTENSION\0" + "ERROR_IN_RECEIVED_CIPHER_LIST\0" + "ERROR_PARSING_EXTENSION\0" + "EXCESSIVE_MESSAGE_SIZE\0" + "EXTRA_DATA_IN_MESSAGE\0" + "FRAGMENT_MISMATCH\0" + "GOT_NEXT_PROTO_WITHOUT_EXTENSION\0" + "HANDSHAKE_FAILURE_ON_CLIENT_HELLO\0" + "HTTPS_PROXY_REQUEST\0" + "HTTP_REQUEST\0" + "INAPPROPRIATE_FALLBACK\0" + "INVALID_ALPN_PROTOCOL\0" + "INVALID_COMMAND\0" + "INVALID_COMPRESSION_LIST\0" + "INVALID_MESSAGE\0" + "INVALID_OUTER_RECORD_TYPE\0" + "INVALID_SCT_LIST\0" + "INVALID_SSL_SESSION\0" + "INVALID_TICKET_KEYS_LENGTH\0" + "LENGTH_MISMATCH\0" + "MISSING_EXTENSION\0" + "MISSING_KEY_SHARE\0" + "MISSING_RSA_CERTIFICATE\0" + "MISSING_TMP_DH_KEY\0" + "MISSING_TMP_ECDH_KEY\0" + "MIXED_SPECIAL_OPERATOR_WITH_GROUPS\0" + "MTU_TOO_SMALL\0" + "NEGOTIATED_BOTH_NPN_AND_ALPN\0" + "NESTED_GROUP\0" + "NO_CERTIFICATES_RETURNED\0" + "NO_CERTIFICATE_ASSIGNED\0" + "NO_CERTIFICATE_SET\0" + "NO_CIPHERS_AVAILABLE\0" + "NO_CIPHERS_PASSED\0" + "NO_CIPHERS_SPECIFIED\0" + "NO_CIPHER_MATCH\0" + "NO_COMMON_SIGNATURE_ALGORITHMS\0" + "NO_COMPRESSION_SPECIFIED\0" + "NO_GROUPS_SPECIFIED\0" + "NO_METHOD_SPECIFIED\0" + "NO_P256_SUPPORT\0" + "NO_PRIVATE_KEY_ASSIGNED\0" + "NO_RENEGOTIATION\0" + "NO_REQUIRED_DIGEST\0" + "NO_SHARED_CIPHER\0" + "NO_SHARED_GROUP\0" + "NO_SUPPORTED_VERSIONS_ENABLED\0" + "NULL_SSL_CTX\0" + "NULL_SSL_METHOD_PASSED\0" + "OLD_SESSION_CIPHER_NOT_RETURNED\0" + "OLD_SESSION_PRF_HASH_MISMATCH\0" + "OLD_SESSION_VERSION_NOT_RETURNED\0" + "PARSE_TLSEXT\0" + "PATH_TOO_LONG\0" + "PEER_DID_NOT_RETURN_A_CERTIFICATE\0" + "PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE\0" + "PRE_SHARED_KEY_MUST_BE_LAST\0" + "PROTOCOL_IS_SHUTDOWN\0" + "PSK_IDENTITY_BINDER_COUNT_MISMATCH\0" + "PSK_IDENTITY_NOT_FOUND\0" + "PSK_NO_CLIENT_CB\0" + "PSK_NO_SERVER_CB\0" + "READ_TIMEOUT_EXPIRED\0" + "RECORD_LENGTH_MISMATCH\0" + "RECORD_TOO_LARGE\0" + "RENEGOTIATION_EMS_MISMATCH\0" + "RENEGOTIATION_ENCODING_ERR\0" + "RENEGOTIATION_MISMATCH\0" + "REQUIRED_CIPHER_MISSING\0" + "RESUMED_EMS_SESSION_WITHOUT_EMS_EXTENSION\0" + "RESUMED_NON_EMS_SESSION_WITH_EMS_EXTENSION\0" + "SCSV_RECEIVED_WHEN_RENEGOTIATING\0" + "SERVERHELLO_TLSEXT\0" + "SERVER_CERT_CHANGED\0" + "SESSION_ID_CONTEXT_UNINITIALIZED\0" + "SESSION_MAY_NOT_BE_CREATED\0" + "SHUTDOWN_WHILE_IN_INIT\0" + "SIGNATURE_ALGORITHMS_EXTENSION_SENT_BY_SERVER\0" + "SRTP_COULD_NOT_ALLOCATE_PROFILES\0" + "SRTP_UNKNOWN_PROTECTION_PROFILE\0" + "SSL3_EXT_INVALID_SERVERNAME\0" + "SSLV3_ALERT_BAD_CERTIFICATE\0" + "SSLV3_ALERT_BAD_RECORD_MAC\0" + "SSLV3_ALERT_CERTIFICATE_EXPIRED\0" + "SSLV3_ALERT_CERTIFICATE_REVOKED\0" + "SSLV3_ALERT_CERTIFICATE_UNKNOWN\0" + "SSLV3_ALERT_CLOSE_NOTIFY\0" + "SSLV3_ALERT_DECOMPRESSION_FAILURE\0" + "SSLV3_ALERT_HANDSHAKE_FAILURE\0" + "SSLV3_ALERT_ILLEGAL_PARAMETER\0" + "SSLV3_ALERT_NO_CERTIFICATE\0" + "SSLV3_ALERT_UNEXPECTED_MESSAGE\0" + "SSLV3_ALERT_UNSUPPORTED_CERTIFICATE\0" + "SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION\0" + "SSL_HANDSHAKE_FAILURE\0" + "SSL_SESSION_ID_CONTEXT_TOO_LONG\0" + "TICKET_ENCRYPTION_FAILED\0" + "TLSV1_ALERT_ACCESS_DENIED\0" + "TLSV1_ALERT_DECODE_ERROR\0" + "TLSV1_ALERT_DECRYPTION_FAILED\0" + "TLSV1_ALERT_DECRYPT_ERROR\0" + "TLSV1_ALERT_EXPORT_RESTRICTION\0" + "TLSV1_ALERT_INAPPROPRIATE_FALLBACK\0" + "TLSV1_ALERT_INSUFFICIENT_SECURITY\0" + "TLSV1_ALERT_INTERNAL_ERROR\0" + "TLSV1_ALERT_NO_RENEGOTIATION\0" + "TLSV1_ALERT_PROTOCOL_VERSION\0" + "TLSV1_ALERT_RECORD_OVERFLOW\0" + "TLSV1_ALERT_UNKNOWN_CA\0" + "TLSV1_ALERT_USER_CANCELLED\0" + "TLSV1_BAD_CERTIFICATE_HASH_VALUE\0" + "TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE\0" + "TLSV1_CERTIFICATE_REQUIRED\0" + "TLSV1_CERTIFICATE_UNOBTAINABLE\0" + "TLSV1_UNKNOWN_PSK_IDENTITY\0" + "TLSV1_UNRECOGNIZED_NAME\0" + "TLSV1_UNSUPPORTED_EXTENSION\0" + "TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST\0" + "TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG\0" + "TOO_MANY_EMPTY_FRAGMENTS\0" + "TOO_MANY_KEY_UPDATES\0" + "TOO_MANY_WARNING_ALERTS\0" + "TOO_MUCH_READ_EARLY_DATA\0" + "TOO_MUCH_SKIPPED_EARLY_DATA\0" + "UNABLE_TO_FIND_ECDH_PARAMETERS\0" + "UNEXPECTED_EXTENSION\0" + "UNEXPECTED_EXTENSION_ON_EARLY_DATA\0" + "UNEXPECTED_MESSAGE\0" + "UNEXPECTED_OPERATOR_IN_GROUP\0" + "UNEXPECTED_RECORD\0" + "UNKNOWN_ALERT_TYPE\0" + "UNKNOWN_CERTIFICATE_TYPE\0" + "UNKNOWN_CIPHER_RETURNED\0" + "UNKNOWN_CIPHER_TYPE\0" + "UNKNOWN_KEY_EXCHANGE_TYPE\0" + "UNKNOWN_PROTOCOL\0" + "UNKNOWN_SSL_VERSION\0" + "UNKNOWN_STATE\0" + "UNSAFE_LEGACY_RENEGOTIATION_DISABLED\0" + "UNSUPPORTED_COMPRESSION_ALGORITHM\0" + "UNSUPPORTED_ELLIPTIC_CURVE\0" + "UNSUPPORTED_PROTOCOL\0" + "UNSUPPORTED_PROTOCOL_FOR_CUSTOM_KEY\0" + "WRONG_CERTIFICATE_TYPE\0" + "WRONG_CIPHER_RETURNED\0" + "WRONG_CURVE\0" + "WRONG_MESSAGE_TYPE\0" + "WRONG_SIGNATURE_TYPE\0" + "WRONG_SSL_VERSION\0" + "WRONG_VERSION_NUMBER\0" + "WRONG_VERSION_ON_EARLY_DATA\0" + "X509_LIB\0" + "X509_VERIFICATION_SETUP_PROBLEMS\0" + "AKID_MISMATCH\0" + "BAD_X509_FILETYPE\0" + "BASE64_DECODE_ERROR\0" + "CANT_CHECK_DH_KEY\0" + "CERT_ALREADY_IN_HASH_TABLE\0" + "CRL_ALREADY_DELTA\0" + "CRL_VERIFY_FAILURE\0" + "IDP_MISMATCH\0" + "INVALID_DIRECTORY\0" + "INVALID_FIELD_NAME\0" + "INVALID_PARAMETER\0" + "INVALID_PSS_PARAMETERS\0" + "INVALID_TRUST\0" + "ISSUER_MISMATCH\0" + "KEY_TYPE_MISMATCH\0" + "KEY_VALUES_MISMATCH\0" + "LOADING_CERT_DIR\0" + "LOADING_DEFAULTS\0" + "NAME_TOO_LONG\0" + "NEWER_CRL_NOT_NEWER\0" + "NO_CERT_SET_FOR_US_TO_VERIFY\0" + "NO_CRL_NUMBER\0" + "PUBLIC_KEY_DECODE_ERROR\0" + "PUBLIC_KEY_ENCODE_ERROR\0" + "SHOULD_RETRY\0" + "UNKNOWN_KEY_TYPE\0" + "UNKNOWN_PURPOSE_ID\0" + "UNKNOWN_TRUST_ID\0" + "WRONG_LOOKUP_TYPE\0" + "BAD_IP_ADDRESS\0" + "BAD_OBJECT\0" + "BN_DEC2BN_ERROR\0" + "BN_TO_ASN1_INTEGER_ERROR\0" + "CANNOT_FIND_FREE_FUNCTION\0" + "DIRNAME_ERROR\0" + "DISTPOINT_ALREADY_SET\0" + "DUPLICATE_ZONE_ID\0" + "ERROR_CONVERTING_ZONE\0" + "ERROR_CREATING_EXTENSION\0" + "ERROR_IN_EXTENSION\0" + "EXPECTED_A_SECTION_NAME\0" + "EXTENSION_EXISTS\0" + "EXTENSION_NAME_ERROR\0" + "EXTENSION_NOT_FOUND\0" + "EXTENSION_SETTING_NOT_SUPPORTED\0" + "EXTENSION_VALUE_ERROR\0" + "ILLEGAL_EMPTY_EXTENSION\0" + "ILLEGAL_HEX_DIGIT\0" + "INCORRECT_POLICY_SYNTAX_TAG\0" + "INVALID_BOOLEAN_STRING\0" + "INVALID_EXTENSION_STRING\0" + "INVALID_MULTIPLE_RDNS\0" + "INVALID_NAME\0" + "INVALID_NULL_ARGUMENT\0" + "INVALID_NULL_NAME\0" + "INVALID_NULL_VALUE\0" + "INVALID_NUMBERS\0" + "INVALID_OBJECT_IDENTIFIER\0" + "INVALID_OPTION\0" + "INVALID_POLICY_IDENTIFIER\0" + "INVALID_PROXY_POLICY_SETTING\0" + "INVALID_PURPOSE\0" + "INVALID_SECTION\0" + "INVALID_SYNTAX\0" + "ISSUER_DECODE_ERROR\0" + "NEED_ORGANIZATION_AND_NUMBERS\0" + "NO_CONFIG_DATABASE\0" + "NO_ISSUER_CERTIFICATE\0" + "NO_ISSUER_DETAILS\0" + "NO_POLICY_IDENTIFIER\0" + "NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED\0" + "NO_PUBLIC_KEY\0" + "NO_SUBJECT_DETAILS\0" + "ODD_NUMBER_OF_DIGITS\0" + "OPERATION_NOT_DEFINED\0" + "OTHERNAME_ERROR\0" + "POLICY_LANGUAGE_ALREADY_DEFINED\0" + "POLICY_PATH_LENGTH\0" + "POLICY_PATH_LENGTH_ALREADY_DEFINED\0" + "POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY\0" + "SECTION_NOT_FOUND\0" + "UNABLE_TO_GET_ISSUER_DETAILS\0" + "UNABLE_TO_GET_ISSUER_KEYID\0" + "UNKNOWN_BIT_STRING_ARGUMENT\0" + "UNKNOWN_EXTENSION\0" + "UNKNOWN_EXTENSION_NAME\0" + "UNKNOWN_OPTION\0" + "UNSUPPORTED_OPTION\0" + "USER_TOO_LONG\0" + ""; diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/BoringSSL.modulemap b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/BoringSSL.modulemap new file mode 100644 index 0000000..283008b --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/BoringSSL.modulemap @@ -0,0 +1,6 @@ + framework module openssl { + umbrella header "umbrella.h" + textual header "arm_arch.h" + export * + module * { export * } + } diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/aead.h b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/aead.h new file mode 100644 index 0000000..92427aa --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/aead.h @@ -0,0 +1,433 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_AEAD_H +#define OPENSSL_HEADER_AEAD_H + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// Authenticated Encryption with Additional Data. +// +// AEAD couples confidentiality and integrity in a single primitive. AEAD +// algorithms take a key and then can seal and open individual messages. Each +// message has a unique, per-message nonce and, optionally, additional data +// which is authenticated but not included in the ciphertext. +// +// The |EVP_AEAD_CTX_init| function initialises an |EVP_AEAD_CTX| structure and +// performs any precomputation needed to use |aead| with |key|. The length of +// the key, |key_len|, is given in bytes. +// +// The |tag_len| argument contains the length of the tags, in bytes, and allows +// for the processing of truncated authenticators. A zero value indicates that +// the default tag length should be used and this is defined as +// |EVP_AEAD_DEFAULT_TAG_LENGTH| in order to make the code clear. Using +// truncated tags increases an attacker's chance of creating a valid forgery. +// Be aware that the attacker's chance may increase more than exponentially as +// would naively be expected. +// +// When no longer needed, the initialised |EVP_AEAD_CTX| structure must be +// passed to |EVP_AEAD_CTX_cleanup|, which will deallocate any memory used. +// +// With an |EVP_AEAD_CTX| in hand, one can seal and open messages. These +// operations are intended to meet the standard notions of privacy and +// authenticity for authenticated encryption. For formal definitions see +// Bellare and Namprempre, "Authenticated encryption: relations among notions +// and analysis of the generic composition paradigm," Lecture Notes in Computer +// Science B<1976> (2000), 531–545, +// http://www-cse.ucsd.edu/~mihir/papers/oem.html. +// +// When sealing messages, a nonce must be given. The length of the nonce is +// fixed by the AEAD in use and is returned by |EVP_AEAD_nonce_length|. *The +// nonce must be unique for all messages with the same key*. This is critically +// important - nonce reuse may completely undermine the security of the AEAD. +// Nonces may be predictable and public, so long as they are unique. Uniqueness +// may be achieved with a simple counter or, if large enough, may be generated +// randomly. The nonce must be passed into the "open" operation by the receiver +// so must either be implicit (e.g. a counter), or must be transmitted along +// with the sealed message. +// +// The "seal" and "open" operations are atomic - an entire message must be +// encrypted or decrypted in a single call. Large messages may have to be split +// up in order to accommodate this. When doing so, be mindful of the need not to +// repeat nonces and the possibility that an attacker could duplicate, reorder +// or drop message chunks. For example, using a single key for a given (large) +// message and sealing chunks with nonces counting from zero would be secure as +// long as the number of chunks was securely transmitted. (Otherwise an +// attacker could truncate the message by dropping chunks from the end.) +// +// The number of chunks could be transmitted by prefixing it to the plaintext, +// for example. This also assumes that no other message would ever use the same +// key otherwise the rule that nonces must be unique for a given key would be +// violated. +// +// The "seal" and "open" operations also permit additional data to be +// authenticated via the |ad| parameter. This data is not included in the +// ciphertext and must be identical for both the "seal" and "open" call. This +// permits implicit context to be authenticated but may be empty if not needed. +// +// The "seal" and "open" operations may work in-place if the |out| and |in| +// arguments are equal. Otherwise, if |out| and |in| alias, input data may be +// overwritten before it is read. This situation will cause an error. +// +// The "seal" and "open" operations return one on success and zero on error. + + +// AEAD algorithms. + +// EVP_aead_aes_128_gcm is AES-128 in Galois Counter Mode. +OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_128_gcm(void); + +// EVP_aead_aes_256_gcm is AES-256 in Galois Counter Mode. +OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_256_gcm(void); + +// EVP_aead_chacha20_poly1305 is the AEAD built from ChaCha20 and +// Poly1305 as described in RFC 7539. +OPENSSL_EXPORT const EVP_AEAD *EVP_aead_chacha20_poly1305(void); + +// EVP_aead_aes_128_ctr_hmac_sha256 is AES-128 in CTR mode with HMAC-SHA256 for +// authentication. The nonce is 12 bytes; the bottom 32-bits are used as the +// block counter, thus the maximum plaintext size is 64GB. +OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_128_ctr_hmac_sha256(void); + +// EVP_aead_aes_256_ctr_hmac_sha256 is AES-256 in CTR mode with HMAC-SHA256 for +// authentication. See |EVP_aead_aes_128_ctr_hmac_sha256| for details. +OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_256_ctr_hmac_sha256(void); + +// EVP_aead_aes_128_gcm_siv is AES-128 in GCM-SIV mode. See +// https://tools.ietf.org/html/draft-irtf-cfrg-gcmsiv-02 +OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_128_gcm_siv(void); + +// EVP_aead_aes_256_gcm_siv is AES-256 in GCM-SIV mode. See +// https://tools.ietf.org/html/draft-irtf-cfrg-gcmsiv-02 +OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_256_gcm_siv(void); + +// EVP_aead_aes_128_ccm_bluetooth is AES-128-CCM with M=4 and L=2 (4-byte tags +// and 13-byte nonces), as decribed in the Bluetooth Core Specification v5.0, +// Volume 6, Part E, Section 1. +OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_128_ccm_bluetooth(void); + +// EVP_aead_aes_128_ccm_bluetooth_8 is AES-128-CCM with M=8 and L=2 (8-byte tags +// and 13-byte nonces), as used in the Bluetooth Mesh Networking Specification +// v1.0. +OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_128_ccm_bluetooth_8(void); + +// EVP_has_aes_hardware returns one if we enable hardware support for fast and +// constant-time AES-GCM. +OPENSSL_EXPORT int EVP_has_aes_hardware(void); + + +// Utility functions. + +// EVP_AEAD_key_length returns the length, in bytes, of the keys used by +// |aead|. +OPENSSL_EXPORT size_t EVP_AEAD_key_length(const EVP_AEAD *aead); + +// EVP_AEAD_nonce_length returns the length, in bytes, of the per-message nonce +// for |aead|. +OPENSSL_EXPORT size_t EVP_AEAD_nonce_length(const EVP_AEAD *aead); + +// EVP_AEAD_max_overhead returns the maximum number of additional bytes added +// by the act of sealing data with |aead|. +OPENSSL_EXPORT size_t EVP_AEAD_max_overhead(const EVP_AEAD *aead); + +// EVP_AEAD_max_tag_len returns the maximum tag length when using |aead|. This +// is the largest value that can be passed as |tag_len| to +// |EVP_AEAD_CTX_init|. +OPENSSL_EXPORT size_t EVP_AEAD_max_tag_len(const EVP_AEAD *aead); + + +// AEAD operations. + +// An EVP_AEAD_CTX represents an AEAD algorithm configured with a specific key +// and message-independent IV. +typedef struct evp_aead_ctx_st { + const EVP_AEAD *aead; + // aead_state is an opaque pointer to whatever state the AEAD needs to + // maintain. + void *aead_state; + // tag_len may contain the actual length of the authentication tag if it is + // known at initialization time. + uint8_t tag_len; +} EVP_AEAD_CTX; + +// EVP_AEAD_MAX_KEY_LENGTH contains the maximum key length used by +// any AEAD defined in this header. +#define EVP_AEAD_MAX_KEY_LENGTH 80 + +// EVP_AEAD_MAX_NONCE_LENGTH contains the maximum nonce length used by +// any AEAD defined in this header. +#define EVP_AEAD_MAX_NONCE_LENGTH 16 + +// EVP_AEAD_MAX_OVERHEAD contains the maximum overhead used by any AEAD +// defined in this header. +#define EVP_AEAD_MAX_OVERHEAD 64 + +// EVP_AEAD_DEFAULT_TAG_LENGTH is a magic value that can be passed to +// EVP_AEAD_CTX_init to indicate that the default tag length for an AEAD should +// be used. +#define EVP_AEAD_DEFAULT_TAG_LENGTH 0 + +// EVP_AEAD_CTX_zero sets an uninitialized |ctx| to the zero state. It must be +// initialized with |EVP_AEAD_CTX_init| before use. It is safe, but not +// necessary, to call |EVP_AEAD_CTX_cleanup| in this state. This may be used for +// more uniform cleanup of |EVP_AEAD_CTX|. +OPENSSL_EXPORT void EVP_AEAD_CTX_zero(EVP_AEAD_CTX *ctx); + +// EVP_AEAD_CTX_new allocates an |EVP_AEAD_CTX|, calls |EVP_AEAD_CTX_init| and +// returns the |EVP_AEAD_CTX|, or NULL on error. +OPENSSL_EXPORT EVP_AEAD_CTX *EVP_AEAD_CTX_new(const EVP_AEAD *aead, + const uint8_t *key, + size_t key_len, size_t tag_len); + +// EVP_AEAD_CTX_free calls |EVP_AEAD_CTX_cleanup| and |OPENSSL_free| on +// |ctx|. +OPENSSL_EXPORT void EVP_AEAD_CTX_free(EVP_AEAD_CTX *ctx); + +// EVP_AEAD_CTX_init initializes |ctx| for the given AEAD algorithm. The |impl| +// argument is ignored and should be NULL. Authentication tags may be truncated +// by passing a size as |tag_len|. A |tag_len| of zero indicates the default +// tag length and this is defined as EVP_AEAD_DEFAULT_TAG_LENGTH for +// readability. +// +// Returns 1 on success. Otherwise returns 0 and pushes to the error stack. In +// the error case, you do not need to call |EVP_AEAD_CTX_cleanup|, but it's +// harmless to do so. +OPENSSL_EXPORT int EVP_AEAD_CTX_init(EVP_AEAD_CTX *ctx, const EVP_AEAD *aead, + const uint8_t *key, size_t key_len, + size_t tag_len, ENGINE *impl); + +// EVP_AEAD_CTX_cleanup frees any data allocated by |ctx|. It is a no-op to +// call |EVP_AEAD_CTX_cleanup| on a |EVP_AEAD_CTX| that has been |memset| to +// all zeros. +OPENSSL_EXPORT void EVP_AEAD_CTX_cleanup(EVP_AEAD_CTX *ctx); + +// EVP_AEAD_CTX_seal encrypts and authenticates |in_len| bytes from |in| and +// authenticates |ad_len| bytes from |ad| and writes the result to |out|. It +// returns one on success and zero otherwise. +// +// This function may be called concurrently with itself or any other seal/open +// function on the same |EVP_AEAD_CTX|. +// +// At most |max_out_len| bytes are written to |out| and, in order to ensure +// success, |max_out_len| should be |in_len| plus the result of +// |EVP_AEAD_max_overhead|. On successful return, |*out_len| is set to the +// actual number of bytes written. +// +// The length of |nonce|, |nonce_len|, must be equal to the result of +// |EVP_AEAD_nonce_length| for this AEAD. +// +// |EVP_AEAD_CTX_seal| never results in a partial output. If |max_out_len| is +// insufficient, zero will be returned. If any error occurs, |out| will be +// filled with zero bytes and |*out_len| set to zero. +// +// If |in| and |out| alias then |out| must be == |in|. +OPENSSL_EXPORT int EVP_AEAD_CTX_seal(const EVP_AEAD_CTX *ctx, uint8_t *out, + size_t *out_len, size_t max_out_len, + const uint8_t *nonce, size_t nonce_len, + const uint8_t *in, size_t in_len, + const uint8_t *ad, size_t ad_len); + +// EVP_AEAD_CTX_open authenticates |in_len| bytes from |in| and |ad_len| bytes +// from |ad| and decrypts at most |in_len| bytes into |out|. It returns one on +// success and zero otherwise. +// +// This function may be called concurrently with itself or any other seal/open +// function on the same |EVP_AEAD_CTX|. +// +// At most |in_len| bytes are written to |out|. In order to ensure success, +// |max_out_len| should be at least |in_len|. On successful return, |*out_len| +// is set to the the actual number of bytes written. +// +// The length of |nonce|, |nonce_len|, must be equal to the result of +// |EVP_AEAD_nonce_length| for this AEAD. +// +// |EVP_AEAD_CTX_open| never results in a partial output. If |max_out_len| is +// insufficient, zero will be returned. If any error occurs, |out| will be +// filled with zero bytes and |*out_len| set to zero. +// +// If |in| and |out| alias then |out| must be == |in|. +OPENSSL_EXPORT int EVP_AEAD_CTX_open(const EVP_AEAD_CTX *ctx, uint8_t *out, + size_t *out_len, size_t max_out_len, + const uint8_t *nonce, size_t nonce_len, + const uint8_t *in, size_t in_len, + const uint8_t *ad, size_t ad_len); + +// EVP_AEAD_CTX_seal_scatter encrypts and authenticates |in_len| bytes from |in| +// and authenticates |ad_len| bytes from |ad|. It writes |in_len| bytes of +// ciphertext to |out| and the authentication tag to |out_tag|. It returns one +// on success and zero otherwise. +// +// This function may be called concurrently with itself or any other seal/open +// function on the same |EVP_AEAD_CTX|. +// +// Exactly |in_len| bytes are written to |out|, and up to +// |EVP_AEAD_max_overhead+extra_in_len| bytes to |out_tag|. On successful +// return, |*out_tag_len| is set to the actual number of bytes written to +// |out_tag|. +// +// |extra_in| may point to an additional plaintext input buffer if the cipher +// supports it. If present, |extra_in_len| additional bytes of plaintext are +// encrypted and authenticated, and the ciphertext is written (before the tag) +// to |out_tag|. |max_out_tag_len| must be sized to allow for the additional +// |extra_in_len| bytes. +// +// The length of |nonce|, |nonce_len|, must be equal to the result of +// |EVP_AEAD_nonce_length| for this AEAD. +// +// |EVP_AEAD_CTX_seal_scatter| never results in a partial output. If +// |max_out_tag_len| is insufficient, zero will be returned. If any error +// occurs, |out| and |out_tag| will be filled with zero bytes and |*out_tag_len| +// set to zero. +// +// If |in| and |out| alias then |out| must be == |in|. |out_tag| may not alias +// any other argument. +OPENSSL_EXPORT int EVP_AEAD_CTX_seal_scatter( + const EVP_AEAD_CTX *ctx, uint8_t *out, + uint8_t *out_tag, size_t *out_tag_len, size_t max_out_tag_len, + const uint8_t *nonce, size_t nonce_len, + const uint8_t *in, size_t in_len, + const uint8_t *extra_in, size_t extra_in_len, + const uint8_t *ad, size_t ad_len); + +// EVP_AEAD_CTX_open_gather decrypts and authenticates |in_len| bytes from |in| +// and authenticates |ad_len| bytes from |ad| using |in_tag_len| bytes of +// authentication tag from |in_tag|. If successful, it writes |in_len| bytes of +// plaintext to |out|. It returns one on success and zero otherwise. +// +// This function may be called concurrently with itself or any other seal/open +// function on the same |EVP_AEAD_CTX|. +// +// The length of |nonce|, |nonce_len|, must be equal to the result of +// |EVP_AEAD_nonce_length| for this AEAD. +// +// |EVP_AEAD_CTX_open_gather| never results in a partial output. If any error +// occurs, |out| will be filled with zero bytes. +// +// If |in| and |out| alias then |out| must be == |in|. +OPENSSL_EXPORT int EVP_AEAD_CTX_open_gather( + const EVP_AEAD_CTX *ctx, uint8_t *out, const uint8_t *nonce, + size_t nonce_len, const uint8_t *in, size_t in_len, const uint8_t *in_tag, + size_t in_tag_len, const uint8_t *ad, size_t ad_len); + +// EVP_AEAD_CTX_aead returns the underlying AEAD for |ctx|, or NULL if one has +// not been set. +OPENSSL_EXPORT const EVP_AEAD *EVP_AEAD_CTX_aead(const EVP_AEAD_CTX *ctx); + + +// TLS-specific AEAD algorithms. +// +// These AEAD primitives do not meet the definition of generic AEADs. They are +// all specific to TLS and should not be used outside of that context. They must +// be initialized with |EVP_AEAD_CTX_init_with_direction|, are stateful, and may +// not be used concurrently. Any nonces are used as IVs, so they must be +// unpredictable. They only accept an |ad| parameter of length 11 (the standard +// TLS one with length omitted). + +OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_128_cbc_sha1_tls(void); +OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_128_cbc_sha1_tls_implicit_iv(void); +OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_128_cbc_sha256_tls(void); + +OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_256_cbc_sha1_tls(void); +OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_256_cbc_sha1_tls_implicit_iv(void); +OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_256_cbc_sha256_tls(void); +OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_256_cbc_sha384_tls(void); + +OPENSSL_EXPORT const EVP_AEAD *EVP_aead_des_ede3_cbc_sha1_tls(void); +OPENSSL_EXPORT const EVP_AEAD *EVP_aead_des_ede3_cbc_sha1_tls_implicit_iv(void); + +OPENSSL_EXPORT const EVP_AEAD *EVP_aead_null_sha1_tls(void); + +// EVP_aead_aes_128_gcm_tls12 is AES-128 in Galois Counter Mode using the TLS +// 1.2 nonce construction. +OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_128_gcm_tls12(void); + +// EVP_aead_aes_256_gcm_tls12 is AES-256 in Galois Counter Mode using the TLS +// 1.2 nonce construction. +OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_256_gcm_tls12(void); + + +// SSLv3-specific AEAD algorithms. +// +// These AEAD primitives do not meet the definition of generic AEADs. They are +// all specific to SSLv3 and should not be used outside of that context. They +// must be initialized with |EVP_AEAD_CTX_init_with_direction|, are stateful, +// and may not be used concurrently. They only accept an |ad| parameter of +// length 9 (the standard TLS one with length and version omitted). + +OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_128_cbc_sha1_ssl3(void); +OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_256_cbc_sha1_ssl3(void); +OPENSSL_EXPORT const EVP_AEAD *EVP_aead_des_ede3_cbc_sha1_ssl3(void); +OPENSSL_EXPORT const EVP_AEAD *EVP_aead_null_sha1_ssl3(void); + + +// Obscure functions. + +// evp_aead_direction_t denotes the direction of an AEAD operation. +enum evp_aead_direction_t { + evp_aead_open, + evp_aead_seal, +}; + +// EVP_AEAD_CTX_init_with_direction calls |EVP_AEAD_CTX_init| for normal +// AEADs. For TLS-specific and SSL3-specific AEADs, it initializes |ctx| for a +// given direction. +OPENSSL_EXPORT int EVP_AEAD_CTX_init_with_direction( + EVP_AEAD_CTX *ctx, const EVP_AEAD *aead, const uint8_t *key, size_t key_len, + size_t tag_len, enum evp_aead_direction_t dir); + +// EVP_AEAD_CTX_get_iv sets |*out_len| to the length of the IV for |ctx| and +// sets |*out_iv| to point to that many bytes of the current IV. This is only +// meaningful for AEADs with implicit IVs (i.e. CBC mode in SSLv3 and TLS 1.0). +// +// It returns one on success or zero on error. +OPENSSL_EXPORT int EVP_AEAD_CTX_get_iv(const EVP_AEAD_CTX *ctx, + const uint8_t **out_iv, size_t *out_len); + +// EVP_AEAD_CTX_tag_len computes the exact byte length of the tag written by +// |EVP_AEAD_CTX_seal_scatter| and writes it to |*out_tag_len|. It returns one +// on success or zero on error. |in_len| and |extra_in_len| must equal the +// arguments of the same names passed to |EVP_AEAD_CTX_seal_scatter|. +OPENSSL_EXPORT int EVP_AEAD_CTX_tag_len(const EVP_AEAD_CTX *ctx, + size_t *out_tag_len, + const size_t in_len, + const size_t extra_in_len); + + +#if defined(__cplusplus) +} // extern C + +#if !defined(BORINGSSL_NO_CXX) +extern "C++" { + +namespace bssl { + +using ScopedEVP_AEAD_CTX = + internal::StackAllocated; + +BORINGSSL_MAKE_DELETER(EVP_AEAD_CTX, EVP_AEAD_CTX_free) + +} // namespace bssl + +} // extern C++ +#endif + +#endif + +#endif // OPENSSL_HEADER_AEAD_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/aead.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/aead.h.grpc_back new file mode 100644 index 0000000..1d50197 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/aead.h.grpc_back @@ -0,0 +1,433 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_AEAD_H +#define OPENSSL_HEADER_AEAD_H + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// Authenticated Encryption with Additional Data. +// +// AEAD couples confidentiality and integrity in a single primitive. AEAD +// algorithms take a key and then can seal and open individual messages. Each +// message has a unique, per-message nonce and, optionally, additional data +// which is authenticated but not included in the ciphertext. +// +// The |EVP_AEAD_CTX_init| function initialises an |EVP_AEAD_CTX| structure and +// performs any precomputation needed to use |aead| with |key|. The length of +// the key, |key_len|, is given in bytes. +// +// The |tag_len| argument contains the length of the tags, in bytes, and allows +// for the processing of truncated authenticators. A zero value indicates that +// the default tag length should be used and this is defined as +// |EVP_AEAD_DEFAULT_TAG_LENGTH| in order to make the code clear. Using +// truncated tags increases an attacker's chance of creating a valid forgery. +// Be aware that the attacker's chance may increase more than exponentially as +// would naively be expected. +// +// When no longer needed, the initialised |EVP_AEAD_CTX| structure must be +// passed to |EVP_AEAD_CTX_cleanup|, which will deallocate any memory used. +// +// With an |EVP_AEAD_CTX| in hand, one can seal and open messages. These +// operations are intended to meet the standard notions of privacy and +// authenticity for authenticated encryption. For formal definitions see +// Bellare and Namprempre, "Authenticated encryption: relations among notions +// and analysis of the generic composition paradigm," Lecture Notes in Computer +// Science B<1976> (2000), 531–545, +// http://www-cse.ucsd.edu/~mihir/papers/oem.html. +// +// When sealing messages, a nonce must be given. The length of the nonce is +// fixed by the AEAD in use and is returned by |EVP_AEAD_nonce_length|. *The +// nonce must be unique for all messages with the same key*. This is critically +// important - nonce reuse may completely undermine the security of the AEAD. +// Nonces may be predictable and public, so long as they are unique. Uniqueness +// may be achieved with a simple counter or, if large enough, may be generated +// randomly. The nonce must be passed into the "open" operation by the receiver +// so must either be implicit (e.g. a counter), or must be transmitted along +// with the sealed message. +// +// The "seal" and "open" operations are atomic - an entire message must be +// encrypted or decrypted in a single call. Large messages may have to be split +// up in order to accommodate this. When doing so, be mindful of the need not to +// repeat nonces and the possibility that an attacker could duplicate, reorder +// or drop message chunks. For example, using a single key for a given (large) +// message and sealing chunks with nonces counting from zero would be secure as +// long as the number of chunks was securely transmitted. (Otherwise an +// attacker could truncate the message by dropping chunks from the end.) +// +// The number of chunks could be transmitted by prefixing it to the plaintext, +// for example. This also assumes that no other message would ever use the same +// key otherwise the rule that nonces must be unique for a given key would be +// violated. +// +// The "seal" and "open" operations also permit additional data to be +// authenticated via the |ad| parameter. This data is not included in the +// ciphertext and must be identical for both the "seal" and "open" call. This +// permits implicit context to be authenticated but may be empty if not needed. +// +// The "seal" and "open" operations may work in-place if the |out| and |in| +// arguments are equal. Otherwise, if |out| and |in| alias, input data may be +// overwritten before it is read. This situation will cause an error. +// +// The "seal" and "open" operations return one on success and zero on error. + + +// AEAD algorithms. + +// EVP_aead_aes_128_gcm is AES-128 in Galois Counter Mode. +OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_128_gcm(void); + +// EVP_aead_aes_256_gcm is AES-256 in Galois Counter Mode. +OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_256_gcm(void); + +// EVP_aead_chacha20_poly1305 is the AEAD built from ChaCha20 and +// Poly1305 as described in RFC 7539. +OPENSSL_EXPORT const EVP_AEAD *EVP_aead_chacha20_poly1305(void); + +// EVP_aead_aes_128_ctr_hmac_sha256 is AES-128 in CTR mode with HMAC-SHA256 for +// authentication. The nonce is 12 bytes; the bottom 32-bits are used as the +// block counter, thus the maximum plaintext size is 64GB. +OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_128_ctr_hmac_sha256(void); + +// EVP_aead_aes_256_ctr_hmac_sha256 is AES-256 in CTR mode with HMAC-SHA256 for +// authentication. See |EVP_aead_aes_128_ctr_hmac_sha256| for details. +OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_256_ctr_hmac_sha256(void); + +// EVP_aead_aes_128_gcm_siv is AES-128 in GCM-SIV mode. See +// https://tools.ietf.org/html/draft-irtf-cfrg-gcmsiv-02 +OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_128_gcm_siv(void); + +// EVP_aead_aes_256_gcm_siv is AES-256 in GCM-SIV mode. See +// https://tools.ietf.org/html/draft-irtf-cfrg-gcmsiv-02 +OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_256_gcm_siv(void); + +// EVP_aead_aes_128_ccm_bluetooth is AES-128-CCM with M=4 and L=2 (4-byte tags +// and 13-byte nonces), as decribed in the Bluetooth Core Specification v5.0, +// Volume 6, Part E, Section 1. +OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_128_ccm_bluetooth(void); + +// EVP_aead_aes_128_ccm_bluetooth_8 is AES-128-CCM with M=8 and L=2 (8-byte tags +// and 13-byte nonces), as used in the Bluetooth Mesh Networking Specification +// v1.0. +OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_128_ccm_bluetooth_8(void); + +// EVP_has_aes_hardware returns one if we enable hardware support for fast and +// constant-time AES-GCM. +OPENSSL_EXPORT int EVP_has_aes_hardware(void); + + +// Utility functions. + +// EVP_AEAD_key_length returns the length, in bytes, of the keys used by +// |aead|. +OPENSSL_EXPORT size_t EVP_AEAD_key_length(const EVP_AEAD *aead); + +// EVP_AEAD_nonce_length returns the length, in bytes, of the per-message nonce +// for |aead|. +OPENSSL_EXPORT size_t EVP_AEAD_nonce_length(const EVP_AEAD *aead); + +// EVP_AEAD_max_overhead returns the maximum number of additional bytes added +// by the act of sealing data with |aead|. +OPENSSL_EXPORT size_t EVP_AEAD_max_overhead(const EVP_AEAD *aead); + +// EVP_AEAD_max_tag_len returns the maximum tag length when using |aead|. This +// is the largest value that can be passed as |tag_len| to +// |EVP_AEAD_CTX_init|. +OPENSSL_EXPORT size_t EVP_AEAD_max_tag_len(const EVP_AEAD *aead); + + +// AEAD operations. + +// An EVP_AEAD_CTX represents an AEAD algorithm configured with a specific key +// and message-independent IV. +typedef struct evp_aead_ctx_st { + const EVP_AEAD *aead; + // aead_state is an opaque pointer to whatever state the AEAD needs to + // maintain. + void *aead_state; + // tag_len may contain the actual length of the authentication tag if it is + // known at initialization time. + uint8_t tag_len; +} EVP_AEAD_CTX; + +// EVP_AEAD_MAX_KEY_LENGTH contains the maximum key length used by +// any AEAD defined in this header. +#define EVP_AEAD_MAX_KEY_LENGTH 80 + +// EVP_AEAD_MAX_NONCE_LENGTH contains the maximum nonce length used by +// any AEAD defined in this header. +#define EVP_AEAD_MAX_NONCE_LENGTH 16 + +// EVP_AEAD_MAX_OVERHEAD contains the maximum overhead used by any AEAD +// defined in this header. +#define EVP_AEAD_MAX_OVERHEAD 64 + +// EVP_AEAD_DEFAULT_TAG_LENGTH is a magic value that can be passed to +// EVP_AEAD_CTX_init to indicate that the default tag length for an AEAD should +// be used. +#define EVP_AEAD_DEFAULT_TAG_LENGTH 0 + +// EVP_AEAD_CTX_zero sets an uninitialized |ctx| to the zero state. It must be +// initialized with |EVP_AEAD_CTX_init| before use. It is safe, but not +// necessary, to call |EVP_AEAD_CTX_cleanup| in this state. This may be used for +// more uniform cleanup of |EVP_AEAD_CTX|. +OPENSSL_EXPORT void EVP_AEAD_CTX_zero(EVP_AEAD_CTX *ctx); + +// EVP_AEAD_CTX_new allocates an |EVP_AEAD_CTX|, calls |EVP_AEAD_CTX_init| and +// returns the |EVP_AEAD_CTX|, or NULL on error. +OPENSSL_EXPORT EVP_AEAD_CTX *EVP_AEAD_CTX_new(const EVP_AEAD *aead, + const uint8_t *key, + size_t key_len, size_t tag_len); + +// EVP_AEAD_CTX_free calls |EVP_AEAD_CTX_cleanup| and |OPENSSL_free| on +// |ctx|. +OPENSSL_EXPORT void EVP_AEAD_CTX_free(EVP_AEAD_CTX *ctx); + +// EVP_AEAD_CTX_init initializes |ctx| for the given AEAD algorithm. The |impl| +// argument is ignored and should be NULL. Authentication tags may be truncated +// by passing a size as |tag_len|. A |tag_len| of zero indicates the default +// tag length and this is defined as EVP_AEAD_DEFAULT_TAG_LENGTH for +// readability. +// +// Returns 1 on success. Otherwise returns 0 and pushes to the error stack. In +// the error case, you do not need to call |EVP_AEAD_CTX_cleanup|, but it's +// harmless to do so. +OPENSSL_EXPORT int EVP_AEAD_CTX_init(EVP_AEAD_CTX *ctx, const EVP_AEAD *aead, + const uint8_t *key, size_t key_len, + size_t tag_len, ENGINE *impl); + +// EVP_AEAD_CTX_cleanup frees any data allocated by |ctx|. It is a no-op to +// call |EVP_AEAD_CTX_cleanup| on a |EVP_AEAD_CTX| that has been |memset| to +// all zeros. +OPENSSL_EXPORT void EVP_AEAD_CTX_cleanup(EVP_AEAD_CTX *ctx); + +// EVP_AEAD_CTX_seal encrypts and authenticates |in_len| bytes from |in| and +// authenticates |ad_len| bytes from |ad| and writes the result to |out|. It +// returns one on success and zero otherwise. +// +// This function may be called concurrently with itself or any other seal/open +// function on the same |EVP_AEAD_CTX|. +// +// At most |max_out_len| bytes are written to |out| and, in order to ensure +// success, |max_out_len| should be |in_len| plus the result of +// |EVP_AEAD_max_overhead|. On successful return, |*out_len| is set to the +// actual number of bytes written. +// +// The length of |nonce|, |nonce_len|, must be equal to the result of +// |EVP_AEAD_nonce_length| for this AEAD. +// +// |EVP_AEAD_CTX_seal| never results in a partial output. If |max_out_len| is +// insufficient, zero will be returned. If any error occurs, |out| will be +// filled with zero bytes and |*out_len| set to zero. +// +// If |in| and |out| alias then |out| must be == |in|. +OPENSSL_EXPORT int EVP_AEAD_CTX_seal(const EVP_AEAD_CTX *ctx, uint8_t *out, + size_t *out_len, size_t max_out_len, + const uint8_t *nonce, size_t nonce_len, + const uint8_t *in, size_t in_len, + const uint8_t *ad, size_t ad_len); + +// EVP_AEAD_CTX_open authenticates |in_len| bytes from |in| and |ad_len| bytes +// from |ad| and decrypts at most |in_len| bytes into |out|. It returns one on +// success and zero otherwise. +// +// This function may be called concurrently with itself or any other seal/open +// function on the same |EVP_AEAD_CTX|. +// +// At most |in_len| bytes are written to |out|. In order to ensure success, +// |max_out_len| should be at least |in_len|. On successful return, |*out_len| +// is set to the the actual number of bytes written. +// +// The length of |nonce|, |nonce_len|, must be equal to the result of +// |EVP_AEAD_nonce_length| for this AEAD. +// +// |EVP_AEAD_CTX_open| never results in a partial output. If |max_out_len| is +// insufficient, zero will be returned. If any error occurs, |out| will be +// filled with zero bytes and |*out_len| set to zero. +// +// If |in| and |out| alias then |out| must be == |in|. +OPENSSL_EXPORT int EVP_AEAD_CTX_open(const EVP_AEAD_CTX *ctx, uint8_t *out, + size_t *out_len, size_t max_out_len, + const uint8_t *nonce, size_t nonce_len, + const uint8_t *in, size_t in_len, + const uint8_t *ad, size_t ad_len); + +// EVP_AEAD_CTX_seal_scatter encrypts and authenticates |in_len| bytes from |in| +// and authenticates |ad_len| bytes from |ad|. It writes |in_len| bytes of +// ciphertext to |out| and the authentication tag to |out_tag|. It returns one +// on success and zero otherwise. +// +// This function may be called concurrently with itself or any other seal/open +// function on the same |EVP_AEAD_CTX|. +// +// Exactly |in_len| bytes are written to |out|, and up to +// |EVP_AEAD_max_overhead+extra_in_len| bytes to |out_tag|. On successful +// return, |*out_tag_len| is set to the actual number of bytes written to +// |out_tag|. +// +// |extra_in| may point to an additional plaintext input buffer if the cipher +// supports it. If present, |extra_in_len| additional bytes of plaintext are +// encrypted and authenticated, and the ciphertext is written (before the tag) +// to |out_tag|. |max_out_tag_len| must be sized to allow for the additional +// |extra_in_len| bytes. +// +// The length of |nonce|, |nonce_len|, must be equal to the result of +// |EVP_AEAD_nonce_length| for this AEAD. +// +// |EVP_AEAD_CTX_seal_scatter| never results in a partial output. If +// |max_out_tag_len| is insufficient, zero will be returned. If any error +// occurs, |out| and |out_tag| will be filled with zero bytes and |*out_tag_len| +// set to zero. +// +// If |in| and |out| alias then |out| must be == |in|. |out_tag| may not alias +// any other argument. +OPENSSL_EXPORT int EVP_AEAD_CTX_seal_scatter( + const EVP_AEAD_CTX *ctx, uint8_t *out, + uint8_t *out_tag, size_t *out_tag_len, size_t max_out_tag_len, + const uint8_t *nonce, size_t nonce_len, + const uint8_t *in, size_t in_len, + const uint8_t *extra_in, size_t extra_in_len, + const uint8_t *ad, size_t ad_len); + +// EVP_AEAD_CTX_open_gather decrypts and authenticates |in_len| bytes from |in| +// and authenticates |ad_len| bytes from |ad| using |in_tag_len| bytes of +// authentication tag from |in_tag|. If successful, it writes |in_len| bytes of +// plaintext to |out|. It returns one on success and zero otherwise. +// +// This function may be called concurrently with itself or any other seal/open +// function on the same |EVP_AEAD_CTX|. +// +// The length of |nonce|, |nonce_len|, must be equal to the result of +// |EVP_AEAD_nonce_length| for this AEAD. +// +// |EVP_AEAD_CTX_open_gather| never results in a partial output. If any error +// occurs, |out| will be filled with zero bytes. +// +// If |in| and |out| alias then |out| must be == |in|. +OPENSSL_EXPORT int EVP_AEAD_CTX_open_gather( + const EVP_AEAD_CTX *ctx, uint8_t *out, const uint8_t *nonce, + size_t nonce_len, const uint8_t *in, size_t in_len, const uint8_t *in_tag, + size_t in_tag_len, const uint8_t *ad, size_t ad_len); + +// EVP_AEAD_CTX_aead returns the underlying AEAD for |ctx|, or NULL if one has +// not been set. +OPENSSL_EXPORT const EVP_AEAD *EVP_AEAD_CTX_aead(const EVP_AEAD_CTX *ctx); + + +// TLS-specific AEAD algorithms. +// +// These AEAD primitives do not meet the definition of generic AEADs. They are +// all specific to TLS and should not be used outside of that context. They must +// be initialized with |EVP_AEAD_CTX_init_with_direction|, are stateful, and may +// not be used concurrently. Any nonces are used as IVs, so they must be +// unpredictable. They only accept an |ad| parameter of length 11 (the standard +// TLS one with length omitted). + +OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_128_cbc_sha1_tls(void); +OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_128_cbc_sha1_tls_implicit_iv(void); +OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_128_cbc_sha256_tls(void); + +OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_256_cbc_sha1_tls(void); +OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_256_cbc_sha1_tls_implicit_iv(void); +OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_256_cbc_sha256_tls(void); +OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_256_cbc_sha384_tls(void); + +OPENSSL_EXPORT const EVP_AEAD *EVP_aead_des_ede3_cbc_sha1_tls(void); +OPENSSL_EXPORT const EVP_AEAD *EVP_aead_des_ede3_cbc_sha1_tls_implicit_iv(void); + +OPENSSL_EXPORT const EVP_AEAD *EVP_aead_null_sha1_tls(void); + +// EVP_aead_aes_128_gcm_tls12 is AES-128 in Galois Counter Mode using the TLS +// 1.2 nonce construction. +OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_128_gcm_tls12(void); + +// EVP_aead_aes_256_gcm_tls12 is AES-256 in Galois Counter Mode using the TLS +// 1.2 nonce construction. +OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_256_gcm_tls12(void); + + +// SSLv3-specific AEAD algorithms. +// +// These AEAD primitives do not meet the definition of generic AEADs. They are +// all specific to SSLv3 and should not be used outside of that context. They +// must be initialized with |EVP_AEAD_CTX_init_with_direction|, are stateful, +// and may not be used concurrently. They only accept an |ad| parameter of +// length 9 (the standard TLS one with length and version omitted). + +OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_128_cbc_sha1_ssl3(void); +OPENSSL_EXPORT const EVP_AEAD *EVP_aead_aes_256_cbc_sha1_ssl3(void); +OPENSSL_EXPORT const EVP_AEAD *EVP_aead_des_ede3_cbc_sha1_ssl3(void); +OPENSSL_EXPORT const EVP_AEAD *EVP_aead_null_sha1_ssl3(void); + + +// Obscure functions. + +// evp_aead_direction_t denotes the direction of an AEAD operation. +enum evp_aead_direction_t { + evp_aead_open, + evp_aead_seal, +}; + +// EVP_AEAD_CTX_init_with_direction calls |EVP_AEAD_CTX_init| for normal +// AEADs. For TLS-specific and SSL3-specific AEADs, it initializes |ctx| for a +// given direction. +OPENSSL_EXPORT int EVP_AEAD_CTX_init_with_direction( + EVP_AEAD_CTX *ctx, const EVP_AEAD *aead, const uint8_t *key, size_t key_len, + size_t tag_len, enum evp_aead_direction_t dir); + +// EVP_AEAD_CTX_get_iv sets |*out_len| to the length of the IV for |ctx| and +// sets |*out_iv| to point to that many bytes of the current IV. This is only +// meaningful for AEADs with implicit IVs (i.e. CBC mode in SSLv3 and TLS 1.0). +// +// It returns one on success or zero on error. +OPENSSL_EXPORT int EVP_AEAD_CTX_get_iv(const EVP_AEAD_CTX *ctx, + const uint8_t **out_iv, size_t *out_len); + +// EVP_AEAD_CTX_tag_len computes the exact byte length of the tag written by +// |EVP_AEAD_CTX_seal_scatter| and writes it to |*out_tag_len|. It returns one +// on success or zero on error. |in_len| and |extra_in_len| must equal the +// arguments of the same names passed to |EVP_AEAD_CTX_seal_scatter|. +OPENSSL_EXPORT int EVP_AEAD_CTX_tag_len(const EVP_AEAD_CTX *ctx, + size_t *out_tag_len, + const size_t in_len, + const size_t extra_in_len); + + +#if defined(__cplusplus) +} // extern C + +#if !defined(BORINGSSL_NO_CXX) +extern "C++" { + +namespace bssl { + +using ScopedEVP_AEAD_CTX = + internal::StackAllocated; + +BORINGSSL_MAKE_DELETER(EVP_AEAD_CTX, EVP_AEAD_CTX_free) + +} // namespace bssl + +} // extern C++ +#endif + +#endif + +#endif // OPENSSL_HEADER_AEAD_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/aes.h b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/aes.h new file mode 100644 index 0000000..a8aafeb --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/aes.h @@ -0,0 +1,170 @@ +/* ==================================================================== + * 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. + * ==================================================================== */ + +#ifndef OPENSSL_HEADER_AES_H +#define OPENSSL_HEADER_AES_H + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// Raw AES functions. + + +#define AES_ENCRYPT 1 +#define AES_DECRYPT 0 + +// AES_MAXNR is the maximum number of AES rounds. +#define AES_MAXNR 14 + +#define AES_BLOCK_SIZE 16 + +// aes_key_st should be an opaque type, but EVP requires that the size be +// known. +struct aes_key_st { + uint32_t rd_key[4 * (AES_MAXNR + 1)]; + unsigned rounds; +}; +typedef struct aes_key_st AES_KEY; + +// AES_set_encrypt_key configures |aeskey| to encrypt with the |bits|-bit key, +// |key|. +// +// WARNING: unlike other OpenSSL functions, this returns zero on success and a +// negative number on error. +OPENSSL_EXPORT int AES_set_encrypt_key(const uint8_t *key, unsigned bits, + AES_KEY *aeskey); + +// AES_set_decrypt_key configures |aeskey| to decrypt with the |bits|-bit key, +// |key|. +// +// WARNING: unlike other OpenSSL functions, this returns zero on success and a +// negative number on error. +OPENSSL_EXPORT int AES_set_decrypt_key(const uint8_t *key, unsigned bits, + AES_KEY *aeskey); + +// AES_encrypt encrypts a single block from |in| to |out| with |key|. The |in| +// and |out| pointers may overlap. +OPENSSL_EXPORT void AES_encrypt(const uint8_t *in, uint8_t *out, + const AES_KEY *key); + +// AES_decrypt decrypts a single block from |in| to |out| with |key|. The |in| +// and |out| pointers may overlap. +OPENSSL_EXPORT void AES_decrypt(const uint8_t *in, uint8_t *out, + const AES_KEY *key); + + +// Block cipher modes. + +// AES_ctr128_encrypt encrypts (or decrypts, it's the same in CTR mode) |len| +// bytes from |in| to |out|. The |num| parameter must be set to zero on the +// first call and |ivec| will be incremented. +OPENSSL_EXPORT void AES_ctr128_encrypt(const uint8_t *in, uint8_t *out, + size_t len, const AES_KEY *key, + uint8_t ivec[AES_BLOCK_SIZE], + uint8_t ecount_buf[AES_BLOCK_SIZE], + unsigned int *num); + +// AES_ecb_encrypt encrypts (or decrypts, if |enc| == |AES_DECRYPT|) a single, +// 16 byte block from |in| to |out|. +OPENSSL_EXPORT void AES_ecb_encrypt(const uint8_t *in, uint8_t *out, + const AES_KEY *key, const int enc); + +// AES_cbc_encrypt encrypts (or decrypts, if |enc| == |AES_DECRYPT|) |len| +// bytes from |in| to |out|. The length must be a multiple of the block size. +OPENSSL_EXPORT void AES_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t len, + const AES_KEY *key, uint8_t *ivec, + const int enc); + +// AES_ofb128_encrypt encrypts (or decrypts, it's the same in OFB mode) |len| +// bytes from |in| to |out|. The |num| parameter must be set to zero on the +// first call. +OPENSSL_EXPORT void AES_ofb128_encrypt(const uint8_t *in, uint8_t *out, + size_t len, const AES_KEY *key, + uint8_t *ivec, int *num); + +// AES_cfb128_encrypt encrypts (or decrypts, if |enc| == |AES_DECRYPT|) |len| +// bytes from |in| to |out|. The |num| parameter must be set to zero on the +// first call. +OPENSSL_EXPORT void AES_cfb128_encrypt(const uint8_t *in, uint8_t *out, + size_t len, const AES_KEY *key, + uint8_t *ivec, int *num, int enc); + + +// AES key wrap. +// +// These functions implement AES Key Wrap mode, as defined in RFC 3394. They +// should never be used except to interoperate with existing systems that use +// this mode. + +// AES_wrap_key performs AES key wrap on |in| which must be a multiple of 8 +// bytes. |iv| must point to an 8 byte value or be NULL to use the default IV. +// |key| must have been configured for encryption. On success, it writes +// |in_len| + 8 bytes to |out| and returns |in_len| + 8. Otherwise, it returns +// -1. +OPENSSL_EXPORT int AES_wrap_key(const AES_KEY *key, const uint8_t *iv, + uint8_t *out, const uint8_t *in, size_t in_len); + +// AES_unwrap_key performs AES key unwrap on |in| which must be a multiple of 8 +// bytes. |iv| must point to an 8 byte value or be NULL to use the default IV. +// |key| must have been configured for decryption. On success, it writes +// |in_len| - 8 bytes to |out| and returns |in_len| - 8. Otherwise, it returns +// -1. +OPENSSL_EXPORT int AES_unwrap_key(const AES_KEY *key, const uint8_t *iv, + uint8_t *out, const uint8_t *in, + size_t in_len); + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_AES_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/aes.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/aes.h.grpc_back new file mode 100644 index 0000000..1156585 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/aes.h.grpc_back @@ -0,0 +1,170 @@ +/* ==================================================================== + * 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. + * ==================================================================== */ + +#ifndef OPENSSL_HEADER_AES_H +#define OPENSSL_HEADER_AES_H + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// Raw AES functions. + + +#define AES_ENCRYPT 1 +#define AES_DECRYPT 0 + +// AES_MAXNR is the maximum number of AES rounds. +#define AES_MAXNR 14 + +#define AES_BLOCK_SIZE 16 + +// aes_key_st should be an opaque type, but EVP requires that the size be +// known. +struct aes_key_st { + uint32_t rd_key[4 * (AES_MAXNR + 1)]; + unsigned rounds; +}; +typedef struct aes_key_st AES_KEY; + +// AES_set_encrypt_key configures |aeskey| to encrypt with the |bits|-bit key, +// |key|. +// +// WARNING: unlike other OpenSSL functions, this returns zero on success and a +// negative number on error. +OPENSSL_EXPORT int AES_set_encrypt_key(const uint8_t *key, unsigned bits, + AES_KEY *aeskey); + +// AES_set_decrypt_key configures |aeskey| to decrypt with the |bits|-bit key, +// |key|. +// +// WARNING: unlike other OpenSSL functions, this returns zero on success and a +// negative number on error. +OPENSSL_EXPORT int AES_set_decrypt_key(const uint8_t *key, unsigned bits, + AES_KEY *aeskey); + +// AES_encrypt encrypts a single block from |in| to |out| with |key|. The |in| +// and |out| pointers may overlap. +OPENSSL_EXPORT void AES_encrypt(const uint8_t *in, uint8_t *out, + const AES_KEY *key); + +// AES_decrypt decrypts a single block from |in| to |out| with |key|. The |in| +// and |out| pointers may overlap. +OPENSSL_EXPORT void AES_decrypt(const uint8_t *in, uint8_t *out, + const AES_KEY *key); + + +// Block cipher modes. + +// AES_ctr128_encrypt encrypts (or decrypts, it's the same in CTR mode) |len| +// bytes from |in| to |out|. The |num| parameter must be set to zero on the +// first call and |ivec| will be incremented. +OPENSSL_EXPORT void AES_ctr128_encrypt(const uint8_t *in, uint8_t *out, + size_t len, const AES_KEY *key, + uint8_t ivec[AES_BLOCK_SIZE], + uint8_t ecount_buf[AES_BLOCK_SIZE], + unsigned int *num); + +// AES_ecb_encrypt encrypts (or decrypts, if |enc| == |AES_DECRYPT|) a single, +// 16 byte block from |in| to |out|. +OPENSSL_EXPORT void AES_ecb_encrypt(const uint8_t *in, uint8_t *out, + const AES_KEY *key, const int enc); + +// AES_cbc_encrypt encrypts (or decrypts, if |enc| == |AES_DECRYPT|) |len| +// bytes from |in| to |out|. The length must be a multiple of the block size. +OPENSSL_EXPORT void AES_cbc_encrypt(const uint8_t *in, uint8_t *out, size_t len, + const AES_KEY *key, uint8_t *ivec, + const int enc); + +// AES_ofb128_encrypt encrypts (or decrypts, it's the same in OFB mode) |len| +// bytes from |in| to |out|. The |num| parameter must be set to zero on the +// first call. +OPENSSL_EXPORT void AES_ofb128_encrypt(const uint8_t *in, uint8_t *out, + size_t len, const AES_KEY *key, + uint8_t *ivec, int *num); + +// AES_cfb128_encrypt encrypts (or decrypts, if |enc| == |AES_DECRYPT|) |len| +// bytes from |in| to |out|. The |num| parameter must be set to zero on the +// first call. +OPENSSL_EXPORT void AES_cfb128_encrypt(const uint8_t *in, uint8_t *out, + size_t len, const AES_KEY *key, + uint8_t *ivec, int *num, int enc); + + +// AES key wrap. +// +// These functions implement AES Key Wrap mode, as defined in RFC 3394. They +// should never be used except to interoperate with existing systems that use +// this mode. + +// AES_wrap_key performs AES key wrap on |in| which must be a multiple of 8 +// bytes. |iv| must point to an 8 byte value or be NULL to use the default IV. +// |key| must have been configured for encryption. On success, it writes +// |in_len| + 8 bytes to |out| and returns |in_len| + 8. Otherwise, it returns +// -1. +OPENSSL_EXPORT int AES_wrap_key(const AES_KEY *key, const uint8_t *iv, + uint8_t *out, const uint8_t *in, size_t in_len); + +// AES_unwrap_key performs AES key unwrap on |in| which must be a multiple of 8 +// bytes. |iv| must point to an 8 byte value or be NULL to use the default IV. +// |key| must have been configured for decryption. On success, it writes +// |in_len| - 8 bytes to |out| and returns |in_len| - 8. Otherwise, it returns +// -1. +OPENSSL_EXPORT int AES_unwrap_key(const AES_KEY *key, const uint8_t *iv, + uint8_t *out, const uint8_t *in, + size_t in_len); + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_AES_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/arm_arch.h b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/arm_arch.h new file mode 100644 index 0000000..faa2655 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/arm_arch.h @@ -0,0 +1,121 @@ +/* ==================================================================== + * Copyright (c) 1998-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). */ + +#ifndef OPENSSL_HEADER_ARM_ARCH_H +#define OPENSSL_HEADER_ARM_ARCH_H + +#if !defined(__ARM_ARCH__) +# if defined(__CC_ARM) +# define __ARM_ARCH__ __TARGET_ARCH_ARM +# if defined(__BIG_ENDIAN) +# define __ARMEB__ +# else +# define __ARMEL__ +# endif +# elif defined(__GNUC__) +# if defined(__aarch64__) +# define __ARM_ARCH__ 8 +# if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ +# define __ARMEB__ +# else +# define __ARMEL__ +# endif + // Why doesn't gcc define __ARM_ARCH__? Instead it defines + // bunch of below macros. See all_architectires[] table in + // gcc/config/arm/arm.c. On a side note it defines + // __ARMEL__/__ARMEB__ for little-/big-endian. +# elif defined(__ARM_ARCH) +# define __ARM_ARCH__ __ARM_ARCH +# elif defined(__ARM_ARCH_8A__) +# define __ARM_ARCH__ 8 +# elif defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || \ + defined(__ARM_ARCH_7R__)|| defined(__ARM_ARCH_7M__) || \ + defined(__ARM_ARCH_7EM__) +# define __ARM_ARCH__ 7 +# elif defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || \ + defined(__ARM_ARCH_6K__)|| defined(__ARM_ARCH_6M__) || \ + defined(__ARM_ARCH_6Z__)|| defined(__ARM_ARCH_6ZK__) || \ + defined(__ARM_ARCH_6T2__) +# define __ARM_ARCH__ 6 +# elif defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5T__) || \ + defined(__ARM_ARCH_5E__)|| defined(__ARM_ARCH_5TE__) || \ + defined(__ARM_ARCH_5TEJ__) +# define __ARM_ARCH__ 5 +# elif defined(__ARM_ARCH_4__) || defined(__ARM_ARCH_4T__) +# define __ARM_ARCH__ 4 +# else +# error "unsupported ARM architecture" +# endif +# endif +#endif + +// Even when building for 32-bit ARM, support for aarch64 crypto instructions +// will be included. +#define __ARM_MAX_ARCH__ 8 + +// ARMV7_NEON is true when a NEON unit is present in the current CPU. +#define ARMV7_NEON (1 << 0) + +// ARMV8_AES indicates support for hardware AES instructions. +#define ARMV8_AES (1 << 2) + +// ARMV8_SHA1 indicates support for hardware SHA-1 instructions. +#define ARMV8_SHA1 (1 << 3) + +// ARMV8_SHA256 indicates support for hardware SHA-256 instructions. +#define ARMV8_SHA256 (1 << 4) + +// ARMV8_PMULL indicates support for carryless multiplication. +#define ARMV8_PMULL (1 << 5) + + +#endif // OPENSSL_HEADER_ARM_ARCH_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/arm_arch.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/arm_arch.h.grpc_back new file mode 100644 index 0000000..faa2655 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/arm_arch.h.grpc_back @@ -0,0 +1,121 @@ +/* ==================================================================== + * Copyright (c) 1998-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). */ + +#ifndef OPENSSL_HEADER_ARM_ARCH_H +#define OPENSSL_HEADER_ARM_ARCH_H + +#if !defined(__ARM_ARCH__) +# if defined(__CC_ARM) +# define __ARM_ARCH__ __TARGET_ARCH_ARM +# if defined(__BIG_ENDIAN) +# define __ARMEB__ +# else +# define __ARMEL__ +# endif +# elif defined(__GNUC__) +# if defined(__aarch64__) +# define __ARM_ARCH__ 8 +# if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ +# define __ARMEB__ +# else +# define __ARMEL__ +# endif + // Why doesn't gcc define __ARM_ARCH__? Instead it defines + // bunch of below macros. See all_architectires[] table in + // gcc/config/arm/arm.c. On a side note it defines + // __ARMEL__/__ARMEB__ for little-/big-endian. +# elif defined(__ARM_ARCH) +# define __ARM_ARCH__ __ARM_ARCH +# elif defined(__ARM_ARCH_8A__) +# define __ARM_ARCH__ 8 +# elif defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || \ + defined(__ARM_ARCH_7R__)|| defined(__ARM_ARCH_7M__) || \ + defined(__ARM_ARCH_7EM__) +# define __ARM_ARCH__ 7 +# elif defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || \ + defined(__ARM_ARCH_6K__)|| defined(__ARM_ARCH_6M__) || \ + defined(__ARM_ARCH_6Z__)|| defined(__ARM_ARCH_6ZK__) || \ + defined(__ARM_ARCH_6T2__) +# define __ARM_ARCH__ 6 +# elif defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5T__) || \ + defined(__ARM_ARCH_5E__)|| defined(__ARM_ARCH_5TE__) || \ + defined(__ARM_ARCH_5TEJ__) +# define __ARM_ARCH__ 5 +# elif defined(__ARM_ARCH_4__) || defined(__ARM_ARCH_4T__) +# define __ARM_ARCH__ 4 +# else +# error "unsupported ARM architecture" +# endif +# endif +#endif + +// Even when building for 32-bit ARM, support for aarch64 crypto instructions +// will be included. +#define __ARM_MAX_ARCH__ 8 + +// ARMV7_NEON is true when a NEON unit is present in the current CPU. +#define ARMV7_NEON (1 << 0) + +// ARMV8_AES indicates support for hardware AES instructions. +#define ARMV8_AES (1 << 2) + +// ARMV8_SHA1 indicates support for hardware SHA-1 instructions. +#define ARMV8_SHA1 (1 << 3) + +// ARMV8_SHA256 indicates support for hardware SHA-256 instructions. +#define ARMV8_SHA256 (1 << 4) + +// ARMV8_PMULL indicates support for carryless multiplication. +#define ARMV8_PMULL (1 << 5) + + +#endif // OPENSSL_HEADER_ARM_ARCH_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/asn1.h b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/asn1.h new file mode 100644 index 0000000..e41d414 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/asn1.h @@ -0,0 +1,981 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 + +#include +#include + +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Legacy ASN.1 library. + * + * This header is part of OpenSSL's ASN.1 implementation. It is retained for + * compatibility but otherwise underdocumented and not actively maintained. Use + * the new |CBS| and |CBB| library in instead. */ + + +#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_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 */ +/* No supported universal tags may exceed this value, to avoid ambiguity with + * V_ASN1_NEG. */ +#define V_ASN1_MAX_UNIVERSAL 0xff + +#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 DECLARE_ASN1_SET_OF(type) /* filled in by mkstack.pl */ +#define IMPLEMENT_ASN1_SET_OF(type) /* nothing, no longer needed */ + +/* 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_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_STACK_OF(ASN1_OBJECT) + +#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 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 */ + /* alias_only is zero if |enc| owns the buffer that it points to + * (although |enc| may still be NULL). If one, |enc| points into a + * buffer that is owned elsewhere. */ + unsigned alias_only:1; + /* alias_only_on_next_parse is one iff the next parsing operation + * should avoid taking a copy of the input and rather set + * |alias_only|. */ + unsigned alias_only_on_next_parse:1; + } ASN1_ENCODING; + +#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; + +/* 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) \ + OPENSSL_EXPORT type *d2i_##name(type **a, const unsigned char **in, long len); \ + OPENSSL_EXPORT int i2d_##name(type *a, unsigned char **out); \ + DECLARE_ASN1_ITEM(itname) + +#define DECLARE_ASN1_ENCODE_FUNCTIONS_const(type, name) \ + OPENSSL_EXPORT type *d2i_##name(type **a, const unsigned char **in, long len); \ + OPENSSL_EXPORT int i2d_##name(const type *a, unsigned char **out); \ + DECLARE_ASN1_ITEM(name) + +#define DECLARE_ASN1_NDEF_FUNCTION(name) \ + OPENSSL_EXPORT 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) \ + OPENSSL_EXPORT type *name##_new(void); \ + OPENSSL_EXPORT 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) \ + OPENSSL_EXPORT 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_PPTR_OF(type, p) \ + ((void**) (1 ? p : (type**)0)) + +typedef void *d2i_of_void(void **, const unsigned char **, long); +typedef int i2d_of_void(const void *, unsigned char **); + +/* 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. + * + */ + +/* 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) \ + extern OPENSSL_EXPORT const ASN1_ITEM name##_it; + +/* 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) + +DEFINE_STACK_OF(ASN1_INTEGER) +DECLARE_ASN1_SET_OF(ASN1_INTEGER) + +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; + }; + +DEFINE_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) + +struct X509_algor_st + { + ASN1_OBJECT *algorithm; + ASN1_TYPE *parameter; + } /* X509_ALGOR */; + +DECLARE_ASN1_FUNCTIONS(X509_ALGOR) + +/* 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 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_DIRECTORYSTRING_new() ASN1_STRING_type_new(V_ASN1_PRINTABLESTRING) +#define M_DIRECTORYSTRING_free(a) ASN1_STRING_free((ASN1_STRING *)a) + +#define M_DISPLAYTEXT_new() ASN1_STRING_type_new(V_ASN1_VISIBLESTRING) +#define M_DISPLAYTEXT_free(a) ASN1_STRING_free((ASN1_STRING *)a) + +#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_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_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_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_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_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_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_ASN1_UTF8STRING_new() (ASN1_UTF8STRING *)\ + ASN1_STRING_type_new(V_ASN1_UTF8STRING) +#define M_ASN1_UTF8STRING_free(a) ASN1_STRING_free((ASN1_STRING *)a) + +DECLARE_ASN1_FUNCTIONS_fname(ASN1_TYPE, ASN1_ANY, ASN1_TYPE) + +OPENSSL_EXPORT int ASN1_TYPE_get(ASN1_TYPE *a); +OPENSSL_EXPORT void ASN1_TYPE_set(ASN1_TYPE *a, int type, void *value); +OPENSSL_EXPORT int ASN1_TYPE_set1(ASN1_TYPE *a, int type, const void *value); +OPENSSL_EXPORT int ASN1_TYPE_cmp(const ASN1_TYPE *a, const ASN1_TYPE *b); + +OPENSSL_EXPORT ASN1_OBJECT * ASN1_OBJECT_new(void ); +OPENSSL_EXPORT void ASN1_OBJECT_free(ASN1_OBJECT *a); +OPENSSL_EXPORT int i2d_ASN1_OBJECT(ASN1_OBJECT *a,unsigned char **pp); +OPENSSL_EXPORT ASN1_OBJECT * c2i_ASN1_OBJECT(ASN1_OBJECT **a,const unsigned char **pp, + long length); +OPENSSL_EXPORT ASN1_OBJECT * d2i_ASN1_OBJECT(ASN1_OBJECT **a,const unsigned char **pp, + long length); + +DECLARE_ASN1_ITEM(ASN1_OBJECT) + +DECLARE_ASN1_SET_OF(ASN1_OBJECT) + +OPENSSL_EXPORT ASN1_STRING * ASN1_STRING_new(void); +OPENSSL_EXPORT void ASN1_STRING_free(ASN1_STRING *a); +OPENSSL_EXPORT int ASN1_STRING_copy(ASN1_STRING *dst, const ASN1_STRING *str); +OPENSSL_EXPORT ASN1_STRING * ASN1_STRING_dup(const ASN1_STRING *a); +OPENSSL_EXPORT ASN1_STRING * ASN1_STRING_type_new(int type ); +OPENSSL_EXPORT 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 * */ +OPENSSL_EXPORT int ASN1_STRING_set(ASN1_STRING *str, const void *data, int len); +OPENSSL_EXPORT void ASN1_STRING_set0(ASN1_STRING *str, void *data, int len); +OPENSSL_EXPORT int ASN1_STRING_length(const ASN1_STRING *x); +OPENSSL_EXPORT void ASN1_STRING_length_set(ASN1_STRING *x, int n); +OPENSSL_EXPORT int ASN1_STRING_type(ASN1_STRING *x); +OPENSSL_EXPORT unsigned char * ASN1_STRING_data(ASN1_STRING *x); +OPENSSL_EXPORT const unsigned char *ASN1_STRING_get0_data(const ASN1_STRING *x); + +DECLARE_ASN1_FUNCTIONS(ASN1_BIT_STRING) +OPENSSL_EXPORT int i2c_ASN1_BIT_STRING(ASN1_BIT_STRING *a,unsigned char **pp); +OPENSSL_EXPORT ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a,const unsigned char **pp, long length); +OPENSSL_EXPORT int ASN1_BIT_STRING_set(ASN1_BIT_STRING *a, unsigned char *d, int length ); +OPENSSL_EXPORT int ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value); +OPENSSL_EXPORT int ASN1_BIT_STRING_get_bit(ASN1_BIT_STRING *a, int n); +OPENSSL_EXPORT int ASN1_BIT_STRING_check(ASN1_BIT_STRING *a, unsigned char *flags, int flags_len); + +OPENSSL_EXPORT int i2d_ASN1_BOOLEAN(int a,unsigned char **pp); +OPENSSL_EXPORT int d2i_ASN1_BOOLEAN(int *a,const unsigned char **pp,long length); + +DECLARE_ASN1_FUNCTIONS(ASN1_INTEGER) +OPENSSL_EXPORT int i2c_ASN1_INTEGER(ASN1_INTEGER *a,unsigned char **pp); +OPENSSL_EXPORT ASN1_INTEGER *c2i_ASN1_INTEGER(ASN1_INTEGER **a,const unsigned char **pp, long length); +OPENSSL_EXPORT ASN1_INTEGER *d2i_ASN1_UINTEGER(ASN1_INTEGER **a,const unsigned char **pp, long length); +OPENSSL_EXPORT ASN1_INTEGER * ASN1_INTEGER_dup(const ASN1_INTEGER *x); +OPENSSL_EXPORT int ASN1_INTEGER_cmp(const ASN1_INTEGER *x, const ASN1_INTEGER *y); + +DECLARE_ASN1_FUNCTIONS(ASN1_ENUMERATED) + +OPENSSL_EXPORT int ASN1_UTCTIME_check(const ASN1_UTCTIME *a); +OPENSSL_EXPORT ASN1_UTCTIME *ASN1_UTCTIME_set(ASN1_UTCTIME *s,time_t t); +OPENSSL_EXPORT ASN1_UTCTIME *ASN1_UTCTIME_adj(ASN1_UTCTIME *s, time_t t, int offset_day, long offset_sec); +OPENSSL_EXPORT int ASN1_UTCTIME_set_string(ASN1_UTCTIME *s, const char *str); +OPENSSL_EXPORT 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 + +OPENSSL_EXPORT int ASN1_GENERALIZEDTIME_check(const ASN1_GENERALIZEDTIME *a); +OPENSSL_EXPORT ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_set(ASN1_GENERALIZEDTIME *s,time_t t); +OPENSSL_EXPORT ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_adj(ASN1_GENERALIZEDTIME *s, time_t t, int offset_day, long offset_sec); +OPENSSL_EXPORT int ASN1_GENERALIZEDTIME_set_string(ASN1_GENERALIZEDTIME *s, const char *str); +OPENSSL_EXPORT int ASN1_TIME_diff(int *pday, int *psec, const ASN1_TIME *from, const ASN1_TIME *to); + +DECLARE_ASN1_FUNCTIONS(ASN1_OCTET_STRING) +OPENSSL_EXPORT ASN1_OCTET_STRING * ASN1_OCTET_STRING_dup(const ASN1_OCTET_STRING *a); +OPENSSL_EXPORT int ASN1_OCTET_STRING_cmp(const ASN1_OCTET_STRING *a, const ASN1_OCTET_STRING *b); +OPENSSL_EXPORT 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) + +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) + +OPENSSL_EXPORT ASN1_TIME *ASN1_TIME_set(ASN1_TIME *s,time_t t); +OPENSSL_EXPORT ASN1_TIME *ASN1_TIME_adj(ASN1_TIME *s,time_t t, int offset_day, long offset_sec); +OPENSSL_EXPORT int ASN1_TIME_check(ASN1_TIME *t); +OPENSSL_EXPORT ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(ASN1_TIME *t, ASN1_GENERALIZEDTIME **out); +OPENSSL_EXPORT int ASN1_TIME_set_string(ASN1_TIME *s, const char *str); + +OPENSSL_EXPORT int i2a_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *a); +OPENSSL_EXPORT int i2a_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *a); +OPENSSL_EXPORT int i2a_ASN1_OBJECT(BIO *bp,ASN1_OBJECT *a); +OPENSSL_EXPORT int i2a_ASN1_STRING(BIO *bp, ASN1_STRING *a, int type); +OPENSSL_EXPORT int i2t_ASN1_OBJECT(char *buf,int buf_len,ASN1_OBJECT *a); + +OPENSSL_EXPORT ASN1_OBJECT *ASN1_OBJECT_create(int nid, unsigned char *data,int len, const char *sn, const char *ln); + +OPENSSL_EXPORT int ASN1_INTEGER_set(ASN1_INTEGER *a, long v); +OPENSSL_EXPORT int ASN1_INTEGER_set_uint64(ASN1_INTEGER *out, uint64_t v); +OPENSSL_EXPORT long ASN1_INTEGER_get(const ASN1_INTEGER *a); +OPENSSL_EXPORT ASN1_INTEGER *BN_to_ASN1_INTEGER(const BIGNUM *bn, ASN1_INTEGER *ai); +OPENSSL_EXPORT BIGNUM *ASN1_INTEGER_to_BN(const ASN1_INTEGER *ai,BIGNUM *bn); + +OPENSSL_EXPORT int ASN1_ENUMERATED_set(ASN1_ENUMERATED *a, long v); +OPENSSL_EXPORT long ASN1_ENUMERATED_get(ASN1_ENUMERATED *a); +OPENSSL_EXPORT ASN1_ENUMERATED *BN_to_ASN1_ENUMERATED(BIGNUM *bn, ASN1_ENUMERATED *ai); +OPENSSL_EXPORT BIGNUM *ASN1_ENUMERATED_to_BN(ASN1_ENUMERATED *ai,BIGNUM *bn); + +/* General */ +/* given a string, return the correct type, max is the maximum length */ +OPENSSL_EXPORT int ASN1_PRINTABLE_type(const unsigned char *s, int max); + +OPENSSL_EXPORT unsigned long ASN1_tag2bit(int tag); + +/* SPECIALS */ +OPENSSL_EXPORT int ASN1_get_object(const unsigned char **pp, long *plength, int *ptag, int *pclass, long omax); +OPENSSL_EXPORT void ASN1_put_object(unsigned char **pp, int constructed, int length, int tag, int xclass); +OPENSSL_EXPORT int ASN1_put_eoc(unsigned char **pp); +OPENSSL_EXPORT int ASN1_object_size(int constructed, int length, int tag); + +/* Used to implement other functions */ +OPENSSL_EXPORT 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))) + +OPENSSL_EXPORT 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 +OPENSSL_EXPORT 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))) + +OPENSSL_EXPORT void *ASN1_item_d2i_fp(const ASN1_ITEM *it, FILE *in, void *x); +OPENSSL_EXPORT 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))) + +OPENSSL_EXPORT int ASN1_item_i2d_fp(const ASN1_ITEM *it, FILE *out, void *x); +OPENSSL_EXPORT int ASN1_STRING_print_ex_fp(FILE *fp, ASN1_STRING *str, unsigned long flags); +#endif + +OPENSSL_EXPORT int ASN1_STRING_to_UTF8(unsigned char **out, ASN1_STRING *in); + +OPENSSL_EXPORT 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))) + +OPENSSL_EXPORT void *ASN1_item_d2i_bio(const ASN1_ITEM *it, BIO *in, void *x); +OPENSSL_EXPORT int ASN1_i2d_bio(i2d_of_void *i2d,BIO *out, void *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))) + +OPENSSL_EXPORT int ASN1_item_i2d_bio(const ASN1_ITEM *it, BIO *out, void *x); +OPENSSL_EXPORT int ASN1_UTCTIME_print(BIO *fp, const ASN1_UTCTIME *a); +OPENSSL_EXPORT int ASN1_GENERALIZEDTIME_print(BIO *fp, const ASN1_GENERALIZEDTIME *a); +OPENSSL_EXPORT int ASN1_TIME_print(BIO *fp, const ASN1_TIME *a); +OPENSSL_EXPORT int ASN1_STRING_print(BIO *bp, const ASN1_STRING *v); +OPENSSL_EXPORT int ASN1_STRING_print_ex(BIO *out, ASN1_STRING *str, unsigned long flags); +OPENSSL_EXPORT const char *ASN1_tag2str(int tag); + +/* Used to load and write netscape format cert */ + +OPENSSL_EXPORT void *ASN1_item_unpack(ASN1_STRING *oct, const ASN1_ITEM *it); + +OPENSSL_EXPORT ASN1_STRING *ASN1_item_pack(void *obj, const ASN1_ITEM *it, ASN1_OCTET_STRING **oct); + +OPENSSL_EXPORT void ASN1_STRING_set_default_mask(unsigned long mask); +OPENSSL_EXPORT int ASN1_STRING_set_default_mask_asc(const char *p); +OPENSSL_EXPORT unsigned long ASN1_STRING_get_default_mask(void); +OPENSSL_EXPORT int ASN1_mbstring_copy(ASN1_STRING **out, const unsigned char *in, int len, int inform, unsigned long mask); +OPENSSL_EXPORT int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len, int inform, unsigned long mask, long minsize, long maxsize); + +OPENSSL_EXPORT ASN1_STRING *ASN1_STRING_set_by_NID(ASN1_STRING **out, const unsigned char *in, int inlen, int inform, int nid); +OPENSSL_EXPORT ASN1_STRING_TABLE *ASN1_STRING_TABLE_get(int nid); +OPENSSL_EXPORT int ASN1_STRING_TABLE_add(int, long, long, unsigned long, unsigned long); +OPENSSL_EXPORT void ASN1_STRING_TABLE_cleanup(void); + +/* ASN1 template functions */ + +/* Old API compatible functions */ +OPENSSL_EXPORT ASN1_VALUE *ASN1_item_new(const ASN1_ITEM *it); +OPENSSL_EXPORT void ASN1_item_free(ASN1_VALUE *val, const ASN1_ITEM *it); +OPENSSL_EXPORT ASN1_VALUE * ASN1_item_d2i(ASN1_VALUE **val, const unsigned char **in, long len, const ASN1_ITEM *it); +OPENSSL_EXPORT int ASN1_item_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it); +OPENSSL_EXPORT int ASN1_item_ndef_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it); + +OPENSSL_EXPORT ASN1_TYPE *ASN1_generate_nconf(char *str, CONF *nconf); +OPENSSL_EXPORT ASN1_TYPE *ASN1_generate_v3(char *str, X509V3_CTX *cnf); + + +#ifdef __cplusplus +} + +extern "C++" { + +namespace bssl { + +BORINGSSL_MAKE_DELETER(ASN1_OBJECT, ASN1_OBJECT_free) +BORINGSSL_MAKE_DELETER(ASN1_STRING, ASN1_STRING_free) +BORINGSSL_MAKE_DELETER(ASN1_TYPE, ASN1_TYPE_free) + +} // namespace bssl + +} /* extern C++ */ + +#endif + +#define ASN1_R_ASN1_LENGTH_MISMATCH 100 +#define ASN1_R_AUX_ERROR 101 +#define ASN1_R_BAD_GET_ASN1_OBJECT_CALL 102 +#define ASN1_R_BAD_OBJECT_HEADER 103 +#define ASN1_R_BMPSTRING_IS_WRONG_LENGTH 104 +#define ASN1_R_BN_LIB 105 +#define ASN1_R_BOOLEAN_IS_WRONG_LENGTH 106 +#define ASN1_R_BUFFER_TOO_SMALL 107 +#define ASN1_R_CONTEXT_NOT_INITIALISED 108 +#define ASN1_R_DECODE_ERROR 109 +#define ASN1_R_DEPTH_EXCEEDED 110 +#define ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED 111 +#define ASN1_R_ENCODE_ERROR 112 +#define ASN1_R_ERROR_GETTING_TIME 113 +#define ASN1_R_EXPECTING_AN_ASN1_SEQUENCE 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 124 +#define ASN1_R_ILLEGAL_BOOLEAN 125 +#define ASN1_R_ILLEGAL_CHARACTERS 126 +#define ASN1_R_ILLEGAL_FORMAT 127 +#define ASN1_R_ILLEGAL_HEX 128 +#define ASN1_R_ILLEGAL_IMPLICIT_TAG 129 +#define ASN1_R_ILLEGAL_INTEGER 130 +#define ASN1_R_ILLEGAL_NESTED_TAGGING 131 +#define ASN1_R_ILLEGAL_NULL 132 +#define ASN1_R_ILLEGAL_NULL_VALUE 133 +#define ASN1_R_ILLEGAL_OBJECT 134 +#define ASN1_R_ILLEGAL_OPTIONAL_ANY 135 +#define ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE 136 +#define ASN1_R_ILLEGAL_TAGGED_ANY 137 +#define ASN1_R_ILLEGAL_TIME_VALUE 138 +#define ASN1_R_INTEGER_NOT_ASCII_FORMAT 139 +#define ASN1_R_INTEGER_TOO_LARGE_FOR_LONG 140 +#define ASN1_R_INVALID_BIT_STRING_BITS_LEFT 141 +#define ASN1_R_INVALID_BMPSTRING_LENGTH 142 +#define ASN1_R_INVALID_DIGIT 143 +#define ASN1_R_INVALID_MODIFIER 144 +#define ASN1_R_INVALID_NUMBER 145 +#define ASN1_R_INVALID_OBJECT_ENCODING 146 +#define ASN1_R_INVALID_SEPARATOR 147 +#define ASN1_R_INVALID_TIME_FORMAT 148 +#define ASN1_R_INVALID_UNIVERSALSTRING_LENGTH 149 +#define ASN1_R_INVALID_UTF8STRING 150 +#define ASN1_R_LIST_ERROR 151 +#define ASN1_R_MISSING_ASN1_EOS 152 +#define ASN1_R_MISSING_EOC 153 +#define ASN1_R_MISSING_SECOND_NUMBER 154 +#define ASN1_R_MISSING_VALUE 155 +#define ASN1_R_MSTRING_NOT_UNIVERSAL 156 +#define ASN1_R_MSTRING_WRONG_TAG 157 +#define ASN1_R_NESTED_ASN1_ERROR 158 +#define ASN1_R_NESTED_ASN1_STRING 159 +#define ASN1_R_NON_HEX_CHARACTERS 160 +#define ASN1_R_NOT_ASCII_FORMAT 161 +#define ASN1_R_NOT_ENOUGH_DATA 162 +#define ASN1_R_NO_MATCHING_CHOICE_TYPE 163 +#define ASN1_R_NULL_IS_WRONG_LENGTH 164 +#define ASN1_R_OBJECT_NOT_ASCII_FORMAT 165 +#define ASN1_R_ODD_NUMBER_OF_CHARS 166 +#define ASN1_R_SECOND_NUMBER_TOO_LARGE 167 +#define ASN1_R_SEQUENCE_LENGTH_MISMATCH 168 +#define ASN1_R_SEQUENCE_NOT_CONSTRUCTED 169 +#define ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG 170 +#define ASN1_R_SHORT_LINE 171 +#define ASN1_R_STREAMING_NOT_SUPPORTED 172 +#define ASN1_R_STRING_TOO_LONG 173 +#define ASN1_R_STRING_TOO_SHORT 174 +#define ASN1_R_TAG_VALUE_TOO_HIGH 175 +#define ASN1_R_TIME_NOT_ASCII_FORMAT 176 +#define ASN1_R_TOO_LONG 177 +#define ASN1_R_TYPE_NOT_CONSTRUCTED 178 +#define ASN1_R_TYPE_NOT_PRIMITIVE 179 +#define ASN1_R_UNEXPECTED_EOC 180 +#define ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH 181 +#define ASN1_R_UNKNOWN_FORMAT 182 +#define ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM 183 +#define ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM 184 +#define ASN1_R_UNKNOWN_TAG 185 +#define ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE 186 +#define ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE 187 +#define ASN1_R_UNSUPPORTED_TYPE 188 +#define ASN1_R_WRONG_PUBLIC_KEY_TYPE 189 +#define ASN1_R_WRONG_TAG 190 +#define ASN1_R_WRONG_TYPE 191 +#define ASN1_R_NESTED_TOO_DEEP 192 + +#endif diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/asn1.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/asn1.h.grpc_back new file mode 100644 index 0000000..f2e92a7 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/asn1.h.grpc_back @@ -0,0 +1,981 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 + +#include +#include + +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Legacy ASN.1 library. + * + * This header is part of OpenSSL's ASN.1 implementation. It is retained for + * compatibility but otherwise underdocumented and not actively maintained. Use + * the new |CBS| and |CBB| library in instead. */ + + +#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_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 */ +/* No supported universal tags may exceed this value, to avoid ambiguity with + * V_ASN1_NEG. */ +#define V_ASN1_MAX_UNIVERSAL 0xff + +#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 DECLARE_ASN1_SET_OF(type) /* filled in by mkstack.pl */ +#define IMPLEMENT_ASN1_SET_OF(type) /* nothing, no longer needed */ + +/* 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_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_STACK_OF(ASN1_OBJECT) + +#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 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 */ + /* alias_only is zero if |enc| owns the buffer that it points to + * (although |enc| may still be NULL). If one, |enc| points into a + * buffer that is owned elsewhere. */ + unsigned alias_only:1; + /* alias_only_on_next_parse is one iff the next parsing operation + * should avoid taking a copy of the input and rather set + * |alias_only|. */ + unsigned alias_only_on_next_parse:1; + } ASN1_ENCODING; + +#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; + +/* 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) \ + OPENSSL_EXPORT type *d2i_##name(type **a, const unsigned char **in, long len); \ + OPENSSL_EXPORT int i2d_##name(type *a, unsigned char **out); \ + DECLARE_ASN1_ITEM(itname) + +#define DECLARE_ASN1_ENCODE_FUNCTIONS_const(type, name) \ + OPENSSL_EXPORT type *d2i_##name(type **a, const unsigned char **in, long len); \ + OPENSSL_EXPORT int i2d_##name(const type *a, unsigned char **out); \ + DECLARE_ASN1_ITEM(name) + +#define DECLARE_ASN1_NDEF_FUNCTION(name) \ + OPENSSL_EXPORT 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) \ + OPENSSL_EXPORT type *name##_new(void); \ + OPENSSL_EXPORT 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) \ + OPENSSL_EXPORT 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_PPTR_OF(type, p) \ + ((void**) (1 ? p : (type**)0)) + +typedef void *d2i_of_void(void **, const unsigned char **, long); +typedef int i2d_of_void(const void *, unsigned char **); + +/* 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. + * + */ + +/* 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) \ + extern OPENSSL_EXPORT const ASN1_ITEM name##_it; + +/* 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) + +DEFINE_STACK_OF(ASN1_INTEGER) +DECLARE_ASN1_SET_OF(ASN1_INTEGER) + +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; + }; + +DEFINE_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) + +struct X509_algor_st + { + ASN1_OBJECT *algorithm; + ASN1_TYPE *parameter; + } /* X509_ALGOR */; + +DECLARE_ASN1_FUNCTIONS(X509_ALGOR) + +/* 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 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_DIRECTORYSTRING_new() ASN1_STRING_type_new(V_ASN1_PRINTABLESTRING) +#define M_DIRECTORYSTRING_free(a) ASN1_STRING_free((ASN1_STRING *)a) + +#define M_DISPLAYTEXT_new() ASN1_STRING_type_new(V_ASN1_VISIBLESTRING) +#define M_DISPLAYTEXT_free(a) ASN1_STRING_free((ASN1_STRING *)a) + +#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_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_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_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_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_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_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_ASN1_UTF8STRING_new() (ASN1_UTF8STRING *)\ + ASN1_STRING_type_new(V_ASN1_UTF8STRING) +#define M_ASN1_UTF8STRING_free(a) ASN1_STRING_free((ASN1_STRING *)a) + +DECLARE_ASN1_FUNCTIONS_fname(ASN1_TYPE, ASN1_ANY, ASN1_TYPE) + +OPENSSL_EXPORT int ASN1_TYPE_get(ASN1_TYPE *a); +OPENSSL_EXPORT void ASN1_TYPE_set(ASN1_TYPE *a, int type, void *value); +OPENSSL_EXPORT int ASN1_TYPE_set1(ASN1_TYPE *a, int type, const void *value); +OPENSSL_EXPORT int ASN1_TYPE_cmp(const ASN1_TYPE *a, const ASN1_TYPE *b); + +OPENSSL_EXPORT ASN1_OBJECT * ASN1_OBJECT_new(void ); +OPENSSL_EXPORT void ASN1_OBJECT_free(ASN1_OBJECT *a); +OPENSSL_EXPORT int i2d_ASN1_OBJECT(ASN1_OBJECT *a,unsigned char **pp); +OPENSSL_EXPORT ASN1_OBJECT * c2i_ASN1_OBJECT(ASN1_OBJECT **a,const unsigned char **pp, + long length); +OPENSSL_EXPORT ASN1_OBJECT * d2i_ASN1_OBJECT(ASN1_OBJECT **a,const unsigned char **pp, + long length); + +DECLARE_ASN1_ITEM(ASN1_OBJECT) + +DECLARE_ASN1_SET_OF(ASN1_OBJECT) + +OPENSSL_EXPORT ASN1_STRING * ASN1_STRING_new(void); +OPENSSL_EXPORT void ASN1_STRING_free(ASN1_STRING *a); +OPENSSL_EXPORT int ASN1_STRING_copy(ASN1_STRING *dst, const ASN1_STRING *str); +OPENSSL_EXPORT ASN1_STRING * ASN1_STRING_dup(const ASN1_STRING *a); +OPENSSL_EXPORT ASN1_STRING * ASN1_STRING_type_new(int type ); +OPENSSL_EXPORT 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 * */ +OPENSSL_EXPORT int ASN1_STRING_set(ASN1_STRING *str, const void *data, int len); +OPENSSL_EXPORT void ASN1_STRING_set0(ASN1_STRING *str, void *data, int len); +OPENSSL_EXPORT int ASN1_STRING_length(const ASN1_STRING *x); +OPENSSL_EXPORT void ASN1_STRING_length_set(ASN1_STRING *x, int n); +OPENSSL_EXPORT int ASN1_STRING_type(ASN1_STRING *x); +OPENSSL_EXPORT unsigned char * ASN1_STRING_data(ASN1_STRING *x); +OPENSSL_EXPORT const unsigned char *ASN1_STRING_get0_data(const ASN1_STRING *x); + +DECLARE_ASN1_FUNCTIONS(ASN1_BIT_STRING) +OPENSSL_EXPORT int i2c_ASN1_BIT_STRING(ASN1_BIT_STRING *a,unsigned char **pp); +OPENSSL_EXPORT ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a,const unsigned char **pp, long length); +OPENSSL_EXPORT int ASN1_BIT_STRING_set(ASN1_BIT_STRING *a, unsigned char *d, int length ); +OPENSSL_EXPORT int ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value); +OPENSSL_EXPORT int ASN1_BIT_STRING_get_bit(ASN1_BIT_STRING *a, int n); +OPENSSL_EXPORT int ASN1_BIT_STRING_check(ASN1_BIT_STRING *a, unsigned char *flags, int flags_len); + +OPENSSL_EXPORT int i2d_ASN1_BOOLEAN(int a,unsigned char **pp); +OPENSSL_EXPORT int d2i_ASN1_BOOLEAN(int *a,const unsigned char **pp,long length); + +DECLARE_ASN1_FUNCTIONS(ASN1_INTEGER) +OPENSSL_EXPORT int i2c_ASN1_INTEGER(ASN1_INTEGER *a,unsigned char **pp); +OPENSSL_EXPORT ASN1_INTEGER *c2i_ASN1_INTEGER(ASN1_INTEGER **a,const unsigned char **pp, long length); +OPENSSL_EXPORT ASN1_INTEGER *d2i_ASN1_UINTEGER(ASN1_INTEGER **a,const unsigned char **pp, long length); +OPENSSL_EXPORT ASN1_INTEGER * ASN1_INTEGER_dup(const ASN1_INTEGER *x); +OPENSSL_EXPORT int ASN1_INTEGER_cmp(const ASN1_INTEGER *x, const ASN1_INTEGER *y); + +DECLARE_ASN1_FUNCTIONS(ASN1_ENUMERATED) + +OPENSSL_EXPORT int ASN1_UTCTIME_check(const ASN1_UTCTIME *a); +OPENSSL_EXPORT ASN1_UTCTIME *ASN1_UTCTIME_set(ASN1_UTCTIME *s,time_t t); +OPENSSL_EXPORT ASN1_UTCTIME *ASN1_UTCTIME_adj(ASN1_UTCTIME *s, time_t t, int offset_day, long offset_sec); +OPENSSL_EXPORT int ASN1_UTCTIME_set_string(ASN1_UTCTIME *s, const char *str); +OPENSSL_EXPORT 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 + +OPENSSL_EXPORT int ASN1_GENERALIZEDTIME_check(const ASN1_GENERALIZEDTIME *a); +OPENSSL_EXPORT ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_set(ASN1_GENERALIZEDTIME *s,time_t t); +OPENSSL_EXPORT ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_adj(ASN1_GENERALIZEDTIME *s, time_t t, int offset_day, long offset_sec); +OPENSSL_EXPORT int ASN1_GENERALIZEDTIME_set_string(ASN1_GENERALIZEDTIME *s, const char *str); +OPENSSL_EXPORT int ASN1_TIME_diff(int *pday, int *psec, const ASN1_TIME *from, const ASN1_TIME *to); + +DECLARE_ASN1_FUNCTIONS(ASN1_OCTET_STRING) +OPENSSL_EXPORT ASN1_OCTET_STRING * ASN1_OCTET_STRING_dup(const ASN1_OCTET_STRING *a); +OPENSSL_EXPORT int ASN1_OCTET_STRING_cmp(const ASN1_OCTET_STRING *a, const ASN1_OCTET_STRING *b); +OPENSSL_EXPORT 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) + +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) + +OPENSSL_EXPORT ASN1_TIME *ASN1_TIME_set(ASN1_TIME *s,time_t t); +OPENSSL_EXPORT ASN1_TIME *ASN1_TIME_adj(ASN1_TIME *s,time_t t, int offset_day, long offset_sec); +OPENSSL_EXPORT int ASN1_TIME_check(ASN1_TIME *t); +OPENSSL_EXPORT ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(ASN1_TIME *t, ASN1_GENERALIZEDTIME **out); +OPENSSL_EXPORT int ASN1_TIME_set_string(ASN1_TIME *s, const char *str); + +OPENSSL_EXPORT int i2a_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *a); +OPENSSL_EXPORT int i2a_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *a); +OPENSSL_EXPORT int i2a_ASN1_OBJECT(BIO *bp,ASN1_OBJECT *a); +OPENSSL_EXPORT int i2a_ASN1_STRING(BIO *bp, ASN1_STRING *a, int type); +OPENSSL_EXPORT int i2t_ASN1_OBJECT(char *buf,int buf_len,ASN1_OBJECT *a); + +OPENSSL_EXPORT ASN1_OBJECT *ASN1_OBJECT_create(int nid, unsigned char *data,int len, const char *sn, const char *ln); + +OPENSSL_EXPORT int ASN1_INTEGER_set(ASN1_INTEGER *a, long v); +OPENSSL_EXPORT int ASN1_INTEGER_set_uint64(ASN1_INTEGER *out, uint64_t v); +OPENSSL_EXPORT long ASN1_INTEGER_get(const ASN1_INTEGER *a); +OPENSSL_EXPORT ASN1_INTEGER *BN_to_ASN1_INTEGER(const BIGNUM *bn, ASN1_INTEGER *ai); +OPENSSL_EXPORT BIGNUM *ASN1_INTEGER_to_BN(const ASN1_INTEGER *ai,BIGNUM *bn); + +OPENSSL_EXPORT int ASN1_ENUMERATED_set(ASN1_ENUMERATED *a, long v); +OPENSSL_EXPORT long ASN1_ENUMERATED_get(ASN1_ENUMERATED *a); +OPENSSL_EXPORT ASN1_ENUMERATED *BN_to_ASN1_ENUMERATED(BIGNUM *bn, ASN1_ENUMERATED *ai); +OPENSSL_EXPORT BIGNUM *ASN1_ENUMERATED_to_BN(ASN1_ENUMERATED *ai,BIGNUM *bn); + +/* General */ +/* given a string, return the correct type, max is the maximum length */ +OPENSSL_EXPORT int ASN1_PRINTABLE_type(const unsigned char *s, int max); + +OPENSSL_EXPORT unsigned long ASN1_tag2bit(int tag); + +/* SPECIALS */ +OPENSSL_EXPORT int ASN1_get_object(const unsigned char **pp, long *plength, int *ptag, int *pclass, long omax); +OPENSSL_EXPORT void ASN1_put_object(unsigned char **pp, int constructed, int length, int tag, int xclass); +OPENSSL_EXPORT int ASN1_put_eoc(unsigned char **pp); +OPENSSL_EXPORT int ASN1_object_size(int constructed, int length, int tag); + +/* Used to implement other functions */ +OPENSSL_EXPORT 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))) + +OPENSSL_EXPORT 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 +OPENSSL_EXPORT 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))) + +OPENSSL_EXPORT void *ASN1_item_d2i_fp(const ASN1_ITEM *it, FILE *in, void *x); +OPENSSL_EXPORT 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))) + +OPENSSL_EXPORT int ASN1_item_i2d_fp(const ASN1_ITEM *it, FILE *out, void *x); +OPENSSL_EXPORT int ASN1_STRING_print_ex_fp(FILE *fp, ASN1_STRING *str, unsigned long flags); +#endif + +OPENSSL_EXPORT int ASN1_STRING_to_UTF8(unsigned char **out, ASN1_STRING *in); + +OPENSSL_EXPORT 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))) + +OPENSSL_EXPORT void *ASN1_item_d2i_bio(const ASN1_ITEM *it, BIO *in, void *x); +OPENSSL_EXPORT int ASN1_i2d_bio(i2d_of_void *i2d,BIO *out, void *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))) + +OPENSSL_EXPORT int ASN1_item_i2d_bio(const ASN1_ITEM *it, BIO *out, void *x); +OPENSSL_EXPORT int ASN1_UTCTIME_print(BIO *fp, const ASN1_UTCTIME *a); +OPENSSL_EXPORT int ASN1_GENERALIZEDTIME_print(BIO *fp, const ASN1_GENERALIZEDTIME *a); +OPENSSL_EXPORT int ASN1_TIME_print(BIO *fp, const ASN1_TIME *a); +OPENSSL_EXPORT int ASN1_STRING_print(BIO *bp, const ASN1_STRING *v); +OPENSSL_EXPORT int ASN1_STRING_print_ex(BIO *out, ASN1_STRING *str, unsigned long flags); +OPENSSL_EXPORT const char *ASN1_tag2str(int tag); + +/* Used to load and write netscape format cert */ + +OPENSSL_EXPORT void *ASN1_item_unpack(ASN1_STRING *oct, const ASN1_ITEM *it); + +OPENSSL_EXPORT ASN1_STRING *ASN1_item_pack(void *obj, const ASN1_ITEM *it, ASN1_OCTET_STRING **oct); + +OPENSSL_EXPORT void ASN1_STRING_set_default_mask(unsigned long mask); +OPENSSL_EXPORT int ASN1_STRING_set_default_mask_asc(const char *p); +OPENSSL_EXPORT unsigned long ASN1_STRING_get_default_mask(void); +OPENSSL_EXPORT int ASN1_mbstring_copy(ASN1_STRING **out, const unsigned char *in, int len, int inform, unsigned long mask); +OPENSSL_EXPORT int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len, int inform, unsigned long mask, long minsize, long maxsize); + +OPENSSL_EXPORT ASN1_STRING *ASN1_STRING_set_by_NID(ASN1_STRING **out, const unsigned char *in, int inlen, int inform, int nid); +OPENSSL_EXPORT ASN1_STRING_TABLE *ASN1_STRING_TABLE_get(int nid); +OPENSSL_EXPORT int ASN1_STRING_TABLE_add(int, long, long, unsigned long, unsigned long); +OPENSSL_EXPORT void ASN1_STRING_TABLE_cleanup(void); + +/* ASN1 template functions */ + +/* Old API compatible functions */ +OPENSSL_EXPORT ASN1_VALUE *ASN1_item_new(const ASN1_ITEM *it); +OPENSSL_EXPORT void ASN1_item_free(ASN1_VALUE *val, const ASN1_ITEM *it); +OPENSSL_EXPORT ASN1_VALUE * ASN1_item_d2i(ASN1_VALUE **val, const unsigned char **in, long len, const ASN1_ITEM *it); +OPENSSL_EXPORT int ASN1_item_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it); +OPENSSL_EXPORT int ASN1_item_ndef_i2d(ASN1_VALUE *val, unsigned char **out, const ASN1_ITEM *it); + +OPENSSL_EXPORT ASN1_TYPE *ASN1_generate_nconf(char *str, CONF *nconf); +OPENSSL_EXPORT ASN1_TYPE *ASN1_generate_v3(char *str, X509V3_CTX *cnf); + + +#ifdef __cplusplus +} + +extern "C++" { + +namespace bssl { + +BORINGSSL_MAKE_DELETER(ASN1_OBJECT, ASN1_OBJECT_free) +BORINGSSL_MAKE_DELETER(ASN1_STRING, ASN1_STRING_free) +BORINGSSL_MAKE_DELETER(ASN1_TYPE, ASN1_TYPE_free) + +} // namespace bssl + +} /* extern C++ */ + +#endif + +#define ASN1_R_ASN1_LENGTH_MISMATCH 100 +#define ASN1_R_AUX_ERROR 101 +#define ASN1_R_BAD_GET_ASN1_OBJECT_CALL 102 +#define ASN1_R_BAD_OBJECT_HEADER 103 +#define ASN1_R_BMPSTRING_IS_WRONG_LENGTH 104 +#define ASN1_R_BN_LIB 105 +#define ASN1_R_BOOLEAN_IS_WRONG_LENGTH 106 +#define ASN1_R_BUFFER_TOO_SMALL 107 +#define ASN1_R_CONTEXT_NOT_INITIALISED 108 +#define ASN1_R_DECODE_ERROR 109 +#define ASN1_R_DEPTH_EXCEEDED 110 +#define ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED 111 +#define ASN1_R_ENCODE_ERROR 112 +#define ASN1_R_ERROR_GETTING_TIME 113 +#define ASN1_R_EXPECTING_AN_ASN1_SEQUENCE 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 124 +#define ASN1_R_ILLEGAL_BOOLEAN 125 +#define ASN1_R_ILLEGAL_CHARACTERS 126 +#define ASN1_R_ILLEGAL_FORMAT 127 +#define ASN1_R_ILLEGAL_HEX 128 +#define ASN1_R_ILLEGAL_IMPLICIT_TAG 129 +#define ASN1_R_ILLEGAL_INTEGER 130 +#define ASN1_R_ILLEGAL_NESTED_TAGGING 131 +#define ASN1_R_ILLEGAL_NULL 132 +#define ASN1_R_ILLEGAL_NULL_VALUE 133 +#define ASN1_R_ILLEGAL_OBJECT 134 +#define ASN1_R_ILLEGAL_OPTIONAL_ANY 135 +#define ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE 136 +#define ASN1_R_ILLEGAL_TAGGED_ANY 137 +#define ASN1_R_ILLEGAL_TIME_VALUE 138 +#define ASN1_R_INTEGER_NOT_ASCII_FORMAT 139 +#define ASN1_R_INTEGER_TOO_LARGE_FOR_LONG 140 +#define ASN1_R_INVALID_BIT_STRING_BITS_LEFT 141 +#define ASN1_R_INVALID_BMPSTRING_LENGTH 142 +#define ASN1_R_INVALID_DIGIT 143 +#define ASN1_R_INVALID_MODIFIER 144 +#define ASN1_R_INVALID_NUMBER 145 +#define ASN1_R_INVALID_OBJECT_ENCODING 146 +#define ASN1_R_INVALID_SEPARATOR 147 +#define ASN1_R_INVALID_TIME_FORMAT 148 +#define ASN1_R_INVALID_UNIVERSALSTRING_LENGTH 149 +#define ASN1_R_INVALID_UTF8STRING 150 +#define ASN1_R_LIST_ERROR 151 +#define ASN1_R_MISSING_ASN1_EOS 152 +#define ASN1_R_MISSING_EOC 153 +#define ASN1_R_MISSING_SECOND_NUMBER 154 +#define ASN1_R_MISSING_VALUE 155 +#define ASN1_R_MSTRING_NOT_UNIVERSAL 156 +#define ASN1_R_MSTRING_WRONG_TAG 157 +#define ASN1_R_NESTED_ASN1_ERROR 158 +#define ASN1_R_NESTED_ASN1_STRING 159 +#define ASN1_R_NON_HEX_CHARACTERS 160 +#define ASN1_R_NOT_ASCII_FORMAT 161 +#define ASN1_R_NOT_ENOUGH_DATA 162 +#define ASN1_R_NO_MATCHING_CHOICE_TYPE 163 +#define ASN1_R_NULL_IS_WRONG_LENGTH 164 +#define ASN1_R_OBJECT_NOT_ASCII_FORMAT 165 +#define ASN1_R_ODD_NUMBER_OF_CHARS 166 +#define ASN1_R_SECOND_NUMBER_TOO_LARGE 167 +#define ASN1_R_SEQUENCE_LENGTH_MISMATCH 168 +#define ASN1_R_SEQUENCE_NOT_CONSTRUCTED 169 +#define ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG 170 +#define ASN1_R_SHORT_LINE 171 +#define ASN1_R_STREAMING_NOT_SUPPORTED 172 +#define ASN1_R_STRING_TOO_LONG 173 +#define ASN1_R_STRING_TOO_SHORT 174 +#define ASN1_R_TAG_VALUE_TOO_HIGH 175 +#define ASN1_R_TIME_NOT_ASCII_FORMAT 176 +#define ASN1_R_TOO_LONG 177 +#define ASN1_R_TYPE_NOT_CONSTRUCTED 178 +#define ASN1_R_TYPE_NOT_PRIMITIVE 179 +#define ASN1_R_UNEXPECTED_EOC 180 +#define ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH 181 +#define ASN1_R_UNKNOWN_FORMAT 182 +#define ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM 183 +#define ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM 184 +#define ASN1_R_UNKNOWN_TAG 185 +#define ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE 186 +#define ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE 187 +#define ASN1_R_UNSUPPORTED_TYPE 188 +#define ASN1_R_WRONG_PUBLIC_KEY_TYPE 189 +#define ASN1_R_WRONG_TAG 190 +#define ASN1_R_WRONG_TYPE 191 +#define ASN1_R_NESTED_TOO_DEEP 192 + +#endif diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/asn1_mac.h b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/asn1_mac.h new file mode 100644 index 0000000..666e569 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/asn1_mac.h @@ -0,0 +1,18 @@ +/* Copyright (c) 2016, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +/* This header is provided in order to make compiling against code that expects + OpenSSL easier. */ + +#include "asn1.h" diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/asn1_mac.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/asn1_mac.h.grpc_back new file mode 100644 index 0000000..666e569 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/asn1_mac.h.grpc_back @@ -0,0 +1,18 @@ +/* Copyright (c) 2016, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +/* This header is provided in order to make compiling against code that expects + OpenSSL easier. */ + +#include "asn1.h" diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/asn1t.h b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/asn1t.h new file mode 100644 index 0000000..44995df --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/asn1t.h @@ -0,0 +1,892 @@ +/* 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 + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Legacy ASN.1 library template definitions. + * + * This header is used to define new types in OpenSSL's ASN.1 implementation. It + * is deprecated and will be unexported from the library. Use the new |CBS| and + * |CBB| library in instead. */ + + +/* 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 = { + +#define ASN1_ITEM_end(itname) \ + }; + +/* 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, cb, 0}; \ + ASN1_SEQUENCE(tname) + +#define ASN1_BROKEN_SEQUENCE(tname) \ + static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_BROKEN, 0, 0, 0}; \ + ASN1_SEQUENCE(tname) + +#define ASN1_SEQUENCE_ref(tname, cb) \ + static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_REFCOUNT, offsetof(tname, references), cb, 0}; \ + ASN1_SEQUENCE(tname) + +#define ASN1_SEQUENCE_enc(tname, enc, cb) \ + static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_ENCODING, 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, 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 */ + +#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) } +/* 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[] + +#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\ + } + +#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; + +typedef struct asn1_must_be_null_st ASN1_MUST_BE_NULL; + +struct ASN1_ADB_st { + unsigned long flags; /* Various flags */ + unsigned long offset; /* Offset of selector field */ + ASN1_MUST_BE_NULL *unused; + 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 is unused. */ + 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 */ + 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_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) + +DEFINE_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_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); +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); + +void asn1_refcount_set_one(ASN1_VALUE **pval, const ASN1_ITEM *it); +int asn1_refcount_dec_and_test_zero(ASN1_VALUE **pval, 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/FoodApp/Pods/BoringSSL-GRPC/include/openssl/asn1t.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/asn1t.h.grpc_back new file mode 100644 index 0000000..7bd7701 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/asn1t.h.grpc_back @@ -0,0 +1,892 @@ +/* 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 + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Legacy ASN.1 library template definitions. + * + * This header is used to define new types in OpenSSL's ASN.1 implementation. It + * is deprecated and will be unexported from the library. Use the new |CBS| and + * |CBB| library in instead. */ + + +/* 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 = { + +#define ASN1_ITEM_end(itname) \ + }; + +/* 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, cb, 0}; \ + ASN1_SEQUENCE(tname) + +#define ASN1_BROKEN_SEQUENCE(tname) \ + static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_BROKEN, 0, 0, 0}; \ + ASN1_SEQUENCE(tname) + +#define ASN1_SEQUENCE_ref(tname, cb) \ + static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_REFCOUNT, offsetof(tname, references), cb, 0}; \ + ASN1_SEQUENCE(tname) + +#define ASN1_SEQUENCE_enc(tname, enc, cb) \ + static const ASN1_AUX tname##_aux = {NULL, ASN1_AFLG_ENCODING, 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, 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 */ + +#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) } +/* 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[] + +#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\ + } + +#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; + +typedef struct asn1_must_be_null_st ASN1_MUST_BE_NULL; + +struct ASN1_ADB_st { + unsigned long flags; /* Various flags */ + unsigned long offset; /* Offset of selector field */ + ASN1_MUST_BE_NULL *unused; + 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 is unused. */ + 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 */ + 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_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) + +DEFINE_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_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); +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); + +void asn1_refcount_set_one(ASN1_VALUE **pval, const ASN1_ITEM *it); +int asn1_refcount_dec_and_test_zero(ASN1_VALUE **pval, 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/FoodApp/Pods/BoringSSL-GRPC/include/openssl/base.h b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/base.h new file mode 100644 index 0000000..832b441 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/base.h @@ -0,0 +1,457 @@ +/* ==================================================================== + * 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 OPENSSL_HEADER_BASE_H +#define OPENSSL_HEADER_BASE_H + + +// This file should be the first included by all BoringSSL headers. + +#include +#include +#include + +#if defined(__MINGW32__) +// stdio.h is needed on MinGW for __MINGW_PRINTF_FORMAT. +#include +#endif + +// Include a BoringSSL-only header so consumers including this header without +// setting up include paths do not accidentally pick up the system +// opensslconf.h. +#include +#include + +#if defined(BORINGSSL_PREFIX) +#include +#endif + +#if defined(__cplusplus) +extern "C" { +#endif + + +#if defined(__x86_64) || defined(_M_AMD64) || defined(_M_X64) +#define OPENSSL_64_BIT +#define OPENSSL_X86_64 +#elif defined(__x86) || defined(__i386) || defined(__i386__) || defined(_M_IX86) +#define OPENSSL_32_BIT +#define OPENSSL_X86 +#elif defined(__aarch64__) +#define OPENSSL_64_BIT +#define OPENSSL_AARCH64 +#elif defined(__arm) || defined(__arm__) || defined(_M_ARM) +#define OPENSSL_32_BIT +#define OPENSSL_ARM +#elif (defined(__PPC64__) || defined(__powerpc64__)) && defined(_LITTLE_ENDIAN) +#define OPENSSL_64_BIT +#define OPENSSL_PPC64LE +#elif defined(__mips__) && !defined(__LP64__) +#define OPENSSL_32_BIT +#define OPENSSL_MIPS +#elif defined(__mips__) && defined(__LP64__) +#define OPENSSL_64_BIT +#define OPENSSL_MIPS64 +#elif defined(__pnacl__) +#define OPENSSL_32_BIT +#define OPENSSL_PNACL +#elif defined(__wasm__) +#define OPENSSL_32_BIT +#elif defined(__asmjs__) +#define OPENSSL_32_BIT +#elif defined(__myriad2__) +#define OPENSSL_32_BIT +#else +// Note BoringSSL only supports standard 32-bit and 64-bit two's-complement, +// little-endian architectures. Functions will not produce the correct answer +// on other systems. Run the crypto_test binary, notably +// crypto/compiler_test.cc, before adding a new architecture. +#error "Unknown target CPU" +#endif + +#if defined(__APPLE__) +#define OPENSSL_APPLE +#endif + +#if defined(_WIN32) +#define OPENSSL_WINDOWS +#endif + +#if defined(__linux__) +#define OPENSSL_LINUX +#endif + +#if defined(__Fuchsia__) +#define OPENSSL_FUCHSIA +#endif + +#if defined(TRUSTY) +#define OPENSSL_TRUSTY +#define OPENSSL_NO_THREADS +#endif + +#if !defined(OPENSSL_NO_THREADS) +#define OPENSSL_THREADS +#endif + +#define OPENSSL_IS_BORINGSSL +#define OPENSSL_VERSION_NUMBER 0x1010007f +#define SSLEAY_VERSION_NUMBER OPENSSL_VERSION_NUMBER + +// BORINGSSL_API_VERSION is a positive integer that increments as BoringSSL +// changes over time. The value itself is not meaningful. It will be incremented +// whenever is convenient to coordinate an API change with consumers. This will +// not denote any special point in development. +// +// A consumer may use this symbol in the preprocessor to temporarily build +// against multiple revisions of BoringSSL at the same time. It is not +// recommended to do so for longer than is necessary. +#define BORINGSSL_API_VERSION 7 + +#if defined(BORINGSSL_SHARED_LIBRARY) + +#if defined(OPENSSL_WINDOWS) + +#if defined(BORINGSSL_IMPLEMENTATION) +#define OPENSSL_EXPORT __declspec(dllexport) +#else +#define OPENSSL_EXPORT __declspec(dllimport) +#endif + +#else // defined(OPENSSL_WINDOWS) + +#if defined(BORINGSSL_IMPLEMENTATION) +#define OPENSSL_EXPORT __attribute__((visibility("default"))) +#else +#define OPENSSL_EXPORT +#endif + +#endif // defined(OPENSSL_WINDOWS) + +#else // defined(BORINGSSL_SHARED_LIBRARY) + +#define OPENSSL_EXPORT + +#endif // defined(BORINGSSL_SHARED_LIBRARY) + + +#if defined(__GNUC__) || defined(__clang__) +// MinGW has two different printf implementations. Ensure the format macro +// matches the selected implementation. See +// https://sourceforge.net/p/mingw-w64/wiki2/gnu%20printf/. +#if defined(__MINGW_PRINTF_FORMAT) +#define OPENSSL_PRINTF_FORMAT_FUNC(string_index, first_to_check) \ + __attribute__( \ + (__format__(__MINGW_PRINTF_FORMAT, string_index, first_to_check))) +#else +#define OPENSSL_PRINTF_FORMAT_FUNC(string_index, first_to_check) \ + __attribute__((__format__(__printf__, string_index, first_to_check))) +#endif +#else +#define OPENSSL_PRINTF_FORMAT_FUNC(string_index, first_to_check) +#endif + +// OPENSSL_MSVC_PRAGMA emits a pragma on MSVC and nothing on other compilers. +#if defined(_MSC_VER) +#define OPENSSL_MSVC_PRAGMA(arg) __pragma(arg) +#else +#define OPENSSL_MSVC_PRAGMA(arg) +#endif + +#if defined(__GNUC__) || defined(__clang__) +#define OPENSSL_UNUSED __attribute__((unused)) +#else +#define OPENSSL_UNUSED +#endif + +#if defined(BORINGSSL_UNSAFE_FUZZER_MODE) && \ + !defined(BORINGSSL_UNSAFE_DETERMINISTIC_MODE) +#define BORINGSSL_UNSAFE_DETERMINISTIC_MODE +#endif + +#if defined(__has_feature) +#if __has_feature(address_sanitizer) +#define OPENSSL_ASAN +#endif +#if __has_feature(memory_sanitizer) +#define OPENSSL_MSAN +#endif +#endif + +// CRYPTO_THREADID is a dummy value. +typedef int CRYPTO_THREADID; + +typedef int ASN1_BOOLEAN; +typedef int ASN1_NULL; +typedef struct ASN1_ITEM_st ASN1_ITEM; +typedef struct asn1_object_st ASN1_OBJECT; +typedef struct asn1_pctx_st ASN1_PCTX; +typedef struct asn1_string_st ASN1_BIT_STRING; +typedef struct asn1_string_st ASN1_BMPSTRING; +typedef struct asn1_string_st ASN1_ENUMERATED; +typedef struct asn1_string_st ASN1_GENERALIZEDTIME; +typedef struct asn1_string_st ASN1_GENERALSTRING; +typedef struct asn1_string_st ASN1_IA5STRING; +typedef struct asn1_string_st ASN1_INTEGER; +typedef struct asn1_string_st ASN1_OCTET_STRING; +typedef struct asn1_string_st ASN1_PRINTABLESTRING; +typedef struct asn1_string_st ASN1_STRING; +typedef struct asn1_string_st ASN1_T61STRING; +typedef struct asn1_string_st ASN1_TIME; +typedef struct asn1_string_st ASN1_UNIVERSALSTRING; +typedef struct asn1_string_st ASN1_UTCTIME; +typedef struct asn1_string_st ASN1_UTF8STRING; +typedef struct asn1_string_st ASN1_VISIBLESTRING; +typedef struct asn1_type_st ASN1_TYPE; +typedef struct AUTHORITY_KEYID_st AUTHORITY_KEYID; +typedef struct BASIC_CONSTRAINTS_st BASIC_CONSTRAINTS; +typedef struct DIST_POINT_st DIST_POINT; +typedef struct DSA_SIG_st DSA_SIG; +typedef struct ISSUING_DIST_POINT_st ISSUING_DIST_POINT; +typedef struct NAME_CONSTRAINTS_st NAME_CONSTRAINTS; +typedef struct Netscape_spkac_st NETSCAPE_SPKAC; +typedef struct Netscape_spki_st NETSCAPE_SPKI; +typedef struct RIPEMD160state_st RIPEMD160_CTX; +typedef struct X509_POLICY_CACHE_st X509_POLICY_CACHE; +typedef struct X509_POLICY_LEVEL_st X509_POLICY_LEVEL; +typedef struct X509_POLICY_NODE_st X509_POLICY_NODE; +typedef struct X509_POLICY_TREE_st X509_POLICY_TREE; +typedef struct X509_VERIFY_PARAM_st X509_VERIFY_PARAM; +typedef struct X509_algor_st X509_ALGOR; +typedef struct X509_crl_info_st X509_CRL_INFO; +typedef struct X509_crl_st X509_CRL; +typedef struct X509_extension_st X509_EXTENSION; +typedef struct X509_info_st X509_INFO; +typedef struct X509_name_entry_st X509_NAME_ENTRY; +typedef struct X509_name_st X509_NAME; +typedef struct X509_pubkey_st X509_PUBKEY; +typedef struct X509_req_info_st X509_REQ_INFO; +typedef struct X509_req_st X509_REQ; +typedef struct X509_sig_st X509_SIG; +typedef struct X509_val_st X509_VAL; +typedef struct bignum_ctx BN_CTX; +typedef struct bignum_st BIGNUM; +typedef struct bio_method_st BIO_METHOD; +typedef struct bio_st BIO; +typedef struct bn_gencb_st BN_GENCB; +typedef struct bn_mont_ctx_st BN_MONT_CTX; +typedef struct buf_mem_st BUF_MEM; +typedef struct cbb_st CBB; +typedef struct cbs_st CBS; +typedef struct cmac_ctx_st CMAC_CTX; +typedef struct conf_st CONF; +typedef struct conf_value_st CONF_VALUE; +typedef struct crypto_buffer_pool_st CRYPTO_BUFFER_POOL; +typedef struct crypto_buffer_st CRYPTO_BUFFER; +typedef struct dh_st DH; +typedef struct dsa_st DSA; +typedef struct ec_group_st EC_GROUP; +typedef struct ec_key_st EC_KEY; +typedef struct ec_point_st EC_POINT; +typedef struct ecdsa_method_st ECDSA_METHOD; +typedef struct ecdsa_sig_st ECDSA_SIG; +typedef struct engine_st ENGINE; +typedef struct env_md_ctx_st EVP_MD_CTX; +typedef struct env_md_st EVP_MD; +typedef struct evp_aead_st EVP_AEAD; +typedef struct evp_cipher_ctx_st EVP_CIPHER_CTX; +typedef struct evp_cipher_st EVP_CIPHER; +typedef struct evp_encode_ctx_st EVP_ENCODE_CTX; +typedef struct evp_pkey_asn1_method_st EVP_PKEY_ASN1_METHOD; +typedef struct evp_pkey_ctx_st EVP_PKEY_CTX; +typedef struct evp_pkey_method_st EVP_PKEY_METHOD; +typedef struct evp_pkey_st EVP_PKEY; +typedef struct hmac_ctx_st HMAC_CTX; +typedef struct md4_state_st MD4_CTX; +typedef struct md5_state_st MD5_CTX; +typedef struct ossl_init_settings_st OPENSSL_INIT_SETTINGS; +typedef struct pkcs12_st PKCS12; +typedef struct pkcs8_priv_key_info_st PKCS8_PRIV_KEY_INFO; +typedef struct private_key_st X509_PKEY; +typedef struct rand_meth_st RAND_METHOD; +typedef struct rc4_key_st RC4_KEY; +typedef struct rsa_meth_st RSA_METHOD; +typedef struct rsa_st RSA; +typedef struct sha256_state_st SHA256_CTX; +typedef struct sha512_state_st SHA512_CTX; +typedef struct sha_state_st SHA_CTX; +typedef struct spake2_ctx_st SPAKE2_CTX; +typedef struct srtp_protection_profile_st SRTP_PROTECTION_PROFILE; +typedef struct ssl_cipher_st SSL_CIPHER; +typedef struct ssl_ctx_st SSL_CTX; +typedef struct ssl_method_st SSL_METHOD; +typedef struct ssl_private_key_method_st SSL_PRIVATE_KEY_METHOD; +typedef struct ssl_session_st SSL_SESSION; +typedef struct ssl_st SSL; +typedef struct ssl_ticket_aead_method_st SSL_TICKET_AEAD_METHOD; +typedef struct st_ERR_FNS ERR_FNS; +typedef struct v3_ext_ctx X509V3_CTX; +typedef struct x509_attributes_st X509_ATTRIBUTE; +typedef struct x509_cert_aux_st X509_CERT_AUX; +typedef struct x509_cinf_st X509_CINF; +typedef struct x509_crl_method_st X509_CRL_METHOD; +typedef struct x509_lookup_st X509_LOOKUP; +typedef struct x509_revoked_st X509_REVOKED; +typedef struct x509_st X509; +typedef struct x509_store_ctx_st X509_STORE_CTX; +typedef struct x509_store_st X509_STORE; +typedef struct x509_trust_st X509_TRUST; + +typedef void *OPENSSL_BLOCK; + + +#if defined(__cplusplus) +} // extern C +#elif !defined(BORINGSSL_NO_CXX) +#define BORINGSSL_NO_CXX +#endif + +// MSVC doesn't set __cplusplus to 201103 to indicate C++11 support (see +// https://connect.microsoft.com/VisualStudio/feedback/details/763051/a-value-of-predefined-macro-cplusplus-is-still-199711l) +// so MSVC is just assumed to support C++11. +#if !defined(BORINGSSL_NO_CXX) && __cplusplus < 201103L && !defined(_MSC_VER) +#define BORINGSSL_NO_CXX +#endif + +#if !defined(BORINGSSL_NO_CXX) +extern "C++" { + +#include + +// STLPort, used by some Android consumers, not have std::unique_ptr. +#if defined(_STLPORT_VERSION) +#define BORINGSSL_NO_CXX +#endif + +} // extern C++ +#endif // !BORINGSSL_NO_CXX + +#if defined(BORINGSSL_NO_CXX) + +#define BORINGSSL_MAKE_DELETER(type, deleter) + +#else + +extern "C++" { + +namespace bssl { + +namespace internal { + +// The Enable parameter is ignored and only exists so specializations can use +// SFINAE. +template +struct DeleterImpl {}; + +template +struct Deleter { + void operator()(T *ptr) { + // Rather than specialize Deleter for each type, we specialize + // DeleterImpl. This allows bssl::UniquePtr to be used while only + // including base.h as long as the destructor is not emitted. This matches + // std::unique_ptr's behavior on forward-declared types. + // + // DeleterImpl itself is specialized in the corresponding module's header + // and must be included to release an object. If not included, the compiler + // will error that DeleterImpl does not have a method Free. + DeleterImpl::Free(ptr); + } +}; + +template +class StackAllocated { + public: + StackAllocated() { init(&ctx_); } + ~StackAllocated() { cleanup(&ctx_); } + + StackAllocated(const StackAllocated &) = delete; + T& operator=(const StackAllocated &) = delete; + + T *get() { return &ctx_; } + const T *get() const { return &ctx_; } + + T *operator->() { return &ctx_; } + const T *operator->() const { return &ctx_; } + + void Reset() { + cleanup(&ctx_); + init(&ctx_); + } + + private: + T ctx_; +}; + +} // namespace internal + +#define BORINGSSL_MAKE_DELETER(type, deleter) \ + namespace internal { \ + template <> \ + struct DeleterImpl { \ + static void Free(type *ptr) { deleter(ptr); } \ + }; \ + } + +// Holds ownership of heap-allocated BoringSSL structures. Sample usage: +// bssl::UniquePtr rsa(RSA_new()); +// bssl::UniquePtr bio(BIO_new(BIO_s_mem())); +template +using UniquePtr = std::unique_ptr>; + +} // namespace bssl + +} // extern C++ + +#endif // !BORINGSSL_NO_CXX + +#endif // OPENSSL_HEADER_BASE_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/base.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/base.h.grpc_back new file mode 100644 index 0000000..bd41d11 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/base.h.grpc_back @@ -0,0 +1,457 @@ +/* ==================================================================== + * 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 OPENSSL_HEADER_BASE_H +#define OPENSSL_HEADER_BASE_H + + +// This file should be the first included by all BoringSSL headers. + +#include +#include +#include + +#if defined(__MINGW32__) +// stdio.h is needed on MinGW for __MINGW_PRINTF_FORMAT. +#include +#endif + +// Include a BoringSSL-only header so consumers including this header without +// setting up include paths do not accidentally pick up the system +// opensslconf.h. +#include +#include + +#if defined(BORINGSSL_PREFIX) +#include +#endif + +#if defined(__cplusplus) +extern "C" { +#endif + + +#if defined(__x86_64) || defined(_M_AMD64) || defined(_M_X64) +#define OPENSSL_64_BIT +#define OPENSSL_X86_64 +#elif defined(__x86) || defined(__i386) || defined(__i386__) || defined(_M_IX86) +#define OPENSSL_32_BIT +#define OPENSSL_X86 +#elif defined(__aarch64__) +#define OPENSSL_64_BIT +#define OPENSSL_AARCH64 +#elif defined(__arm) || defined(__arm__) || defined(_M_ARM) +#define OPENSSL_32_BIT +#define OPENSSL_ARM +#elif (defined(__PPC64__) || defined(__powerpc64__)) && defined(_LITTLE_ENDIAN) +#define OPENSSL_64_BIT +#define OPENSSL_PPC64LE +#elif defined(__mips__) && !defined(__LP64__) +#define OPENSSL_32_BIT +#define OPENSSL_MIPS +#elif defined(__mips__) && defined(__LP64__) +#define OPENSSL_64_BIT +#define OPENSSL_MIPS64 +#elif defined(__pnacl__) +#define OPENSSL_32_BIT +#define OPENSSL_PNACL +#elif defined(__wasm__) +#define OPENSSL_32_BIT +#elif defined(__asmjs__) +#define OPENSSL_32_BIT +#elif defined(__myriad2__) +#define OPENSSL_32_BIT +#else +// Note BoringSSL only supports standard 32-bit and 64-bit two's-complement, +// little-endian architectures. Functions will not produce the correct answer +// on other systems. Run the crypto_test binary, notably +// crypto/compiler_test.cc, before adding a new architecture. +#error "Unknown target CPU" +#endif + +#if defined(__APPLE__) +#define OPENSSL_APPLE +#endif + +#if defined(_WIN32) +#define OPENSSL_WINDOWS +#endif + +#if defined(__linux__) +#define OPENSSL_LINUX +#endif + +#if defined(__Fuchsia__) +#define OPENSSL_FUCHSIA +#endif + +#if defined(TRUSTY) +#define OPENSSL_TRUSTY +#define OPENSSL_NO_THREADS +#endif + +#if !defined(OPENSSL_NO_THREADS) +#define OPENSSL_THREADS +#endif + +#define OPENSSL_IS_BORINGSSL +#define OPENSSL_VERSION_NUMBER 0x1010007f +#define SSLEAY_VERSION_NUMBER OPENSSL_VERSION_NUMBER + +// BORINGSSL_API_VERSION is a positive integer that increments as BoringSSL +// changes over time. The value itself is not meaningful. It will be incremented +// whenever is convenient to coordinate an API change with consumers. This will +// not denote any special point in development. +// +// A consumer may use this symbol in the preprocessor to temporarily build +// against multiple revisions of BoringSSL at the same time. It is not +// recommended to do so for longer than is necessary. +#define BORINGSSL_API_VERSION 7 + +#if defined(BORINGSSL_SHARED_LIBRARY) + +#if defined(OPENSSL_WINDOWS) + +#if defined(BORINGSSL_IMPLEMENTATION) +#define OPENSSL_EXPORT __declspec(dllexport) +#else +#define OPENSSL_EXPORT __declspec(dllimport) +#endif + +#else // defined(OPENSSL_WINDOWS) + +#if defined(BORINGSSL_IMPLEMENTATION) +#define OPENSSL_EXPORT __attribute__((visibility("default"))) +#else +#define OPENSSL_EXPORT +#endif + +#endif // defined(OPENSSL_WINDOWS) + +#else // defined(BORINGSSL_SHARED_LIBRARY) + +#define OPENSSL_EXPORT + +#endif // defined(BORINGSSL_SHARED_LIBRARY) + + +#if defined(__GNUC__) || defined(__clang__) +// MinGW has two different printf implementations. Ensure the format macro +// matches the selected implementation. See +// https://sourceforge.net/p/mingw-w64/wiki2/gnu%20printf/. +#if defined(__MINGW_PRINTF_FORMAT) +#define OPENSSL_PRINTF_FORMAT_FUNC(string_index, first_to_check) \ + __attribute__( \ + (__format__(__MINGW_PRINTF_FORMAT, string_index, first_to_check))) +#else +#define OPENSSL_PRINTF_FORMAT_FUNC(string_index, first_to_check) \ + __attribute__((__format__(__printf__, string_index, first_to_check))) +#endif +#else +#define OPENSSL_PRINTF_FORMAT_FUNC(string_index, first_to_check) +#endif + +// OPENSSL_MSVC_PRAGMA emits a pragma on MSVC and nothing on other compilers. +#if defined(_MSC_VER) +#define OPENSSL_MSVC_PRAGMA(arg) __pragma(arg) +#else +#define OPENSSL_MSVC_PRAGMA(arg) +#endif + +#if defined(__GNUC__) || defined(__clang__) +#define OPENSSL_UNUSED __attribute__((unused)) +#else +#define OPENSSL_UNUSED +#endif + +#if defined(BORINGSSL_UNSAFE_FUZZER_MODE) && \ + !defined(BORINGSSL_UNSAFE_DETERMINISTIC_MODE) +#define BORINGSSL_UNSAFE_DETERMINISTIC_MODE +#endif + +#if defined(__has_feature) +#if __has_feature(address_sanitizer) +#define OPENSSL_ASAN +#endif +#if __has_feature(memory_sanitizer) +#define OPENSSL_MSAN +#endif +#endif + +// CRYPTO_THREADID is a dummy value. +typedef int CRYPTO_THREADID; + +typedef int ASN1_BOOLEAN; +typedef int ASN1_NULL; +typedef struct ASN1_ITEM_st ASN1_ITEM; +typedef struct asn1_object_st ASN1_OBJECT; +typedef struct asn1_pctx_st ASN1_PCTX; +typedef struct asn1_string_st ASN1_BIT_STRING; +typedef struct asn1_string_st ASN1_BMPSTRING; +typedef struct asn1_string_st ASN1_ENUMERATED; +typedef struct asn1_string_st ASN1_GENERALIZEDTIME; +typedef struct asn1_string_st ASN1_GENERALSTRING; +typedef struct asn1_string_st ASN1_IA5STRING; +typedef struct asn1_string_st ASN1_INTEGER; +typedef struct asn1_string_st ASN1_OCTET_STRING; +typedef struct asn1_string_st ASN1_PRINTABLESTRING; +typedef struct asn1_string_st ASN1_STRING; +typedef struct asn1_string_st ASN1_T61STRING; +typedef struct asn1_string_st ASN1_TIME; +typedef struct asn1_string_st ASN1_UNIVERSALSTRING; +typedef struct asn1_string_st ASN1_UTCTIME; +typedef struct asn1_string_st ASN1_UTF8STRING; +typedef struct asn1_string_st ASN1_VISIBLESTRING; +typedef struct asn1_type_st ASN1_TYPE; +typedef struct AUTHORITY_KEYID_st AUTHORITY_KEYID; +typedef struct BASIC_CONSTRAINTS_st BASIC_CONSTRAINTS; +typedef struct DIST_POINT_st DIST_POINT; +typedef struct DSA_SIG_st DSA_SIG; +typedef struct ISSUING_DIST_POINT_st ISSUING_DIST_POINT; +typedef struct NAME_CONSTRAINTS_st NAME_CONSTRAINTS; +typedef struct Netscape_spkac_st NETSCAPE_SPKAC; +typedef struct Netscape_spki_st NETSCAPE_SPKI; +typedef struct RIPEMD160state_st RIPEMD160_CTX; +typedef struct X509_POLICY_CACHE_st X509_POLICY_CACHE; +typedef struct X509_POLICY_LEVEL_st X509_POLICY_LEVEL; +typedef struct X509_POLICY_NODE_st X509_POLICY_NODE; +typedef struct X509_POLICY_TREE_st X509_POLICY_TREE; +typedef struct X509_VERIFY_PARAM_st X509_VERIFY_PARAM; +typedef struct X509_algor_st X509_ALGOR; +typedef struct X509_crl_info_st X509_CRL_INFO; +typedef struct X509_crl_st X509_CRL; +typedef struct X509_extension_st X509_EXTENSION; +typedef struct X509_info_st X509_INFO; +typedef struct X509_name_entry_st X509_NAME_ENTRY; +typedef struct X509_name_st X509_NAME; +typedef struct X509_pubkey_st X509_PUBKEY; +typedef struct X509_req_info_st X509_REQ_INFO; +typedef struct X509_req_st X509_REQ; +typedef struct X509_sig_st X509_SIG; +typedef struct X509_val_st X509_VAL; +typedef struct bignum_ctx BN_CTX; +typedef struct bignum_st BIGNUM; +typedef struct bio_method_st BIO_METHOD; +typedef struct bio_st BIO; +typedef struct bn_gencb_st BN_GENCB; +typedef struct bn_mont_ctx_st BN_MONT_CTX; +typedef struct buf_mem_st BUF_MEM; +typedef struct cbb_st CBB; +typedef struct cbs_st CBS; +typedef struct cmac_ctx_st CMAC_CTX; +typedef struct conf_st CONF; +typedef struct conf_value_st CONF_VALUE; +typedef struct crypto_buffer_pool_st CRYPTO_BUFFER_POOL; +typedef struct crypto_buffer_st CRYPTO_BUFFER; +typedef struct dh_st DH; +typedef struct dsa_st DSA; +typedef struct ec_group_st EC_GROUP; +typedef struct ec_key_st EC_KEY; +typedef struct ec_point_st EC_POINT; +typedef struct ecdsa_method_st ECDSA_METHOD; +typedef struct ecdsa_sig_st ECDSA_SIG; +typedef struct engine_st ENGINE; +typedef struct env_md_ctx_st EVP_MD_CTX; +typedef struct env_md_st EVP_MD; +typedef struct evp_aead_st EVP_AEAD; +typedef struct evp_cipher_ctx_st EVP_CIPHER_CTX; +typedef struct evp_cipher_st EVP_CIPHER; +typedef struct evp_encode_ctx_st EVP_ENCODE_CTX; +typedef struct evp_pkey_asn1_method_st EVP_PKEY_ASN1_METHOD; +typedef struct evp_pkey_ctx_st EVP_PKEY_CTX; +typedef struct evp_pkey_method_st EVP_PKEY_METHOD; +typedef struct evp_pkey_st EVP_PKEY; +typedef struct hmac_ctx_st HMAC_CTX; +typedef struct md4_state_st MD4_CTX; +typedef struct md5_state_st MD5_CTX; +typedef struct ossl_init_settings_st OPENSSL_INIT_SETTINGS; +typedef struct pkcs12_st PKCS12; +typedef struct pkcs8_priv_key_info_st PKCS8_PRIV_KEY_INFO; +typedef struct private_key_st X509_PKEY; +typedef struct rand_meth_st RAND_METHOD; +typedef struct rc4_key_st RC4_KEY; +typedef struct rsa_meth_st RSA_METHOD; +typedef struct rsa_st RSA; +typedef struct sha256_state_st SHA256_CTX; +typedef struct sha512_state_st SHA512_CTX; +typedef struct sha_state_st SHA_CTX; +typedef struct spake2_ctx_st SPAKE2_CTX; +typedef struct srtp_protection_profile_st SRTP_PROTECTION_PROFILE; +typedef struct ssl_cipher_st SSL_CIPHER; +typedef struct ssl_ctx_st SSL_CTX; +typedef struct ssl_method_st SSL_METHOD; +typedef struct ssl_private_key_method_st SSL_PRIVATE_KEY_METHOD; +typedef struct ssl_session_st SSL_SESSION; +typedef struct ssl_st SSL; +typedef struct ssl_ticket_aead_method_st SSL_TICKET_AEAD_METHOD; +typedef struct st_ERR_FNS ERR_FNS; +typedef struct v3_ext_ctx X509V3_CTX; +typedef struct x509_attributes_st X509_ATTRIBUTE; +typedef struct x509_cert_aux_st X509_CERT_AUX; +typedef struct x509_cinf_st X509_CINF; +typedef struct x509_crl_method_st X509_CRL_METHOD; +typedef struct x509_lookup_st X509_LOOKUP; +typedef struct x509_revoked_st X509_REVOKED; +typedef struct x509_st X509; +typedef struct x509_store_ctx_st X509_STORE_CTX; +typedef struct x509_store_st X509_STORE; +typedef struct x509_trust_st X509_TRUST; + +typedef void *OPENSSL_BLOCK; + + +#if defined(__cplusplus) +} // extern C +#elif !defined(BORINGSSL_NO_CXX) +#define BORINGSSL_NO_CXX +#endif + +// MSVC doesn't set __cplusplus to 201103 to indicate C++11 support (see +// https://connect.microsoft.com/VisualStudio/feedback/details/763051/a-value-of-predefined-macro-cplusplus-is-still-199711l) +// so MSVC is just assumed to support C++11. +#if !defined(BORINGSSL_NO_CXX) && __cplusplus < 201103L && !defined(_MSC_VER) +#define BORINGSSL_NO_CXX +#endif + +#if !defined(BORINGSSL_NO_CXX) +extern "C++" { + +#include + +// STLPort, used by some Android consumers, not have std::unique_ptr. +#if defined(_STLPORT_VERSION) +#define BORINGSSL_NO_CXX +#endif + +} // extern C++ +#endif // !BORINGSSL_NO_CXX + +#if defined(BORINGSSL_NO_CXX) + +#define BORINGSSL_MAKE_DELETER(type, deleter) + +#else + +extern "C++" { + +namespace bssl { + +namespace internal { + +// The Enable parameter is ignored and only exists so specializations can use +// SFINAE. +template +struct DeleterImpl {}; + +template +struct Deleter { + void operator()(T *ptr) { + // Rather than specialize Deleter for each type, we specialize + // DeleterImpl. This allows bssl::UniquePtr to be used while only + // including base.h as long as the destructor is not emitted. This matches + // std::unique_ptr's behavior on forward-declared types. + // + // DeleterImpl itself is specialized in the corresponding module's header + // and must be included to release an object. If not included, the compiler + // will error that DeleterImpl does not have a method Free. + DeleterImpl::Free(ptr); + } +}; + +template +class StackAllocated { + public: + StackAllocated() { init(&ctx_); } + ~StackAllocated() { cleanup(&ctx_); } + + StackAllocated(const StackAllocated &) = delete; + T& operator=(const StackAllocated &) = delete; + + T *get() { return &ctx_; } + const T *get() const { return &ctx_; } + + T *operator->() { return &ctx_; } + const T *operator->() const { return &ctx_; } + + void Reset() { + cleanup(&ctx_); + init(&ctx_); + } + + private: + T ctx_; +}; + +} // namespace internal + +#define BORINGSSL_MAKE_DELETER(type, deleter) \ + namespace internal { \ + template <> \ + struct DeleterImpl { \ + static void Free(type *ptr) { deleter(ptr); } \ + }; \ + } + +// Holds ownership of heap-allocated BoringSSL structures. Sample usage: +// bssl::UniquePtr rsa(RSA_new()); +// bssl::UniquePtr bio(BIO_new(BIO_s_mem())); +template +using UniquePtr = std::unique_ptr>; + +} // namespace bssl + +} // extern C++ + +#endif // !BORINGSSL_NO_CXX + +#endif // OPENSSL_HEADER_BASE_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/base64.h b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/base64.h new file mode 100644 index 0000000..415c6eb --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/base64.h @@ -0,0 +1,187 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 OPENSSL_HEADER_BASE64_H +#define OPENSSL_HEADER_BASE64_H + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// base64 functions. +// +// For historical reasons, these functions have the EVP_ prefix but just do +// base64 encoding and decoding. + + +// Encoding + +// EVP_EncodeBlock encodes |src_len| bytes from |src| and writes the +// result to |dst| with a trailing NUL. It returns the number of bytes +// written, not including this trailing NUL. +OPENSSL_EXPORT size_t EVP_EncodeBlock(uint8_t *dst, const uint8_t *src, + size_t src_len); + +// EVP_EncodedLength sets |*out_len| to the number of bytes that will be needed +// to call |EVP_EncodeBlock| on an input of length |len|. This includes the +// final NUL that |EVP_EncodeBlock| writes. It returns one on success or zero +// on error. +OPENSSL_EXPORT int EVP_EncodedLength(size_t *out_len, size_t len); + + +// Decoding + +// EVP_DecodedLength sets |*out_len| to the maximum number of bytes that will +// be needed to call |EVP_DecodeBase64| on an input of length |len|. It returns +// one on success or zero if |len| is not a valid length for a base64-encoded +// string. +OPENSSL_EXPORT int EVP_DecodedLength(size_t *out_len, size_t len); + +// EVP_DecodeBase64 decodes |in_len| bytes from base64 and writes +// |*out_len| bytes to |out|. |max_out| is the size of the output +// buffer. If it is not enough for the maximum output size, the +// operation fails. It returns one on success or zero on error. +OPENSSL_EXPORT int EVP_DecodeBase64(uint8_t *out, size_t *out_len, + size_t max_out, const uint8_t *in, + size_t in_len); + + +// Deprecated functions. +// +// OpenSSL provides a streaming base64 implementation, however its behavior is +// very specific to PEM. It is also very lenient of invalid input. Use of any of +// these functions is thus deprecated. + +// EVP_EncodeInit initialises |*ctx|, which is typically stack +// allocated, for an encoding operation. +// +// NOTE: The encoding operation breaks its output with newlines every +// 64 characters of output (48 characters of input). Use +// EVP_EncodeBlock to encode raw base64. +OPENSSL_EXPORT void EVP_EncodeInit(EVP_ENCODE_CTX *ctx); + +// EVP_EncodeUpdate encodes |in_len| bytes from |in| and writes an encoded +// version of them to |out| and sets |*out_len| to the number of bytes written. +// Some state may be contained in |ctx| so |EVP_EncodeFinal| must be used to +// flush it before using the encoded data. +OPENSSL_EXPORT void EVP_EncodeUpdate(EVP_ENCODE_CTX *ctx, uint8_t *out, + int *out_len, const uint8_t *in, + size_t in_len); + +// EVP_EncodeFinal flushes any remaining output bytes from |ctx| to |out| and +// sets |*out_len| to the number of bytes written. +OPENSSL_EXPORT void EVP_EncodeFinal(EVP_ENCODE_CTX *ctx, uint8_t *out, + int *out_len); + +// EVP_DecodeInit initialises |*ctx|, which is typically stack allocated, for +// a decoding operation. +// +// TODO(davidben): This isn't a straight-up base64 decode either. Document +// and/or fix exactly what's going on here; maximum line length and such. +OPENSSL_EXPORT void EVP_DecodeInit(EVP_ENCODE_CTX *ctx); + +// EVP_DecodeUpdate decodes |in_len| bytes from |in| and writes the decoded +// data to |out| and sets |*out_len| to the number of bytes written. Some state +// may be contained in |ctx| so |EVP_DecodeFinal| must be used to flush it +// before using the encoded data. +// +// It returns -1 on error, one if a full line of input was processed and zero +// if the line was short (i.e. it was the last line). +OPENSSL_EXPORT int EVP_DecodeUpdate(EVP_ENCODE_CTX *ctx, uint8_t *out, + int *out_len, const uint8_t *in, + size_t in_len); + +// EVP_DecodeFinal flushes any remaining output bytes from |ctx| to |out| and +// sets |*out_len| to the number of bytes written. It returns one on success +// and minus one on error. +OPENSSL_EXPORT int EVP_DecodeFinal(EVP_ENCODE_CTX *ctx, uint8_t *out, + int *out_len); + +// EVP_DecodeBlock encodes |src_len| bytes from |src| and writes the result to +// |dst|. It returns the number of bytes written or -1 on error. +// +// WARNING: EVP_DecodeBlock's return value does not take padding into +// account. It also strips leading whitespace and trailing +// whitespace and minuses. +OPENSSL_EXPORT int EVP_DecodeBlock(uint8_t *dst, const uint8_t *src, + size_t src_len); + + +struct evp_encode_ctx_st { + // data_used indicates the number of bytes of |data| that are valid. When + // encoding, |data| will be filled and encoded as a lump. When decoding, only + // the first four bytes of |data| will be used. + unsigned data_used; + uint8_t data[48]; + + // eof_seen indicates that the end of the base64 data has been seen when + // decoding. Only whitespace can follow. + char eof_seen; + + // error_encountered indicates that invalid base64 data was found. This will + // cause all future calls to fail. + char error_encountered; +}; + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_BASE64_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/base64.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/base64.h.grpc_back new file mode 100644 index 0000000..ef76088 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/base64.h.grpc_back @@ -0,0 +1,187 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 OPENSSL_HEADER_BASE64_H +#define OPENSSL_HEADER_BASE64_H + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// base64 functions. +// +// For historical reasons, these functions have the EVP_ prefix but just do +// base64 encoding and decoding. + + +// Encoding + +// EVP_EncodeBlock encodes |src_len| bytes from |src| and writes the +// result to |dst| with a trailing NUL. It returns the number of bytes +// written, not including this trailing NUL. +OPENSSL_EXPORT size_t EVP_EncodeBlock(uint8_t *dst, const uint8_t *src, + size_t src_len); + +// EVP_EncodedLength sets |*out_len| to the number of bytes that will be needed +// to call |EVP_EncodeBlock| on an input of length |len|. This includes the +// final NUL that |EVP_EncodeBlock| writes. It returns one on success or zero +// on error. +OPENSSL_EXPORT int EVP_EncodedLength(size_t *out_len, size_t len); + + +// Decoding + +// EVP_DecodedLength sets |*out_len| to the maximum number of bytes that will +// be needed to call |EVP_DecodeBase64| on an input of length |len|. It returns +// one on success or zero if |len| is not a valid length for a base64-encoded +// string. +OPENSSL_EXPORT int EVP_DecodedLength(size_t *out_len, size_t len); + +// EVP_DecodeBase64 decodes |in_len| bytes from base64 and writes +// |*out_len| bytes to |out|. |max_out| is the size of the output +// buffer. If it is not enough for the maximum output size, the +// operation fails. It returns one on success or zero on error. +OPENSSL_EXPORT int EVP_DecodeBase64(uint8_t *out, size_t *out_len, + size_t max_out, const uint8_t *in, + size_t in_len); + + +// Deprecated functions. +// +// OpenSSL provides a streaming base64 implementation, however its behavior is +// very specific to PEM. It is also very lenient of invalid input. Use of any of +// these functions is thus deprecated. + +// EVP_EncodeInit initialises |*ctx|, which is typically stack +// allocated, for an encoding operation. +// +// NOTE: The encoding operation breaks its output with newlines every +// 64 characters of output (48 characters of input). Use +// EVP_EncodeBlock to encode raw base64. +OPENSSL_EXPORT void EVP_EncodeInit(EVP_ENCODE_CTX *ctx); + +// EVP_EncodeUpdate encodes |in_len| bytes from |in| and writes an encoded +// version of them to |out| and sets |*out_len| to the number of bytes written. +// Some state may be contained in |ctx| so |EVP_EncodeFinal| must be used to +// flush it before using the encoded data. +OPENSSL_EXPORT void EVP_EncodeUpdate(EVP_ENCODE_CTX *ctx, uint8_t *out, + int *out_len, const uint8_t *in, + size_t in_len); + +// EVP_EncodeFinal flushes any remaining output bytes from |ctx| to |out| and +// sets |*out_len| to the number of bytes written. +OPENSSL_EXPORT void EVP_EncodeFinal(EVP_ENCODE_CTX *ctx, uint8_t *out, + int *out_len); + +// EVP_DecodeInit initialises |*ctx|, which is typically stack allocated, for +// a decoding operation. +// +// TODO(davidben): This isn't a straight-up base64 decode either. Document +// and/or fix exactly what's going on here; maximum line length and such. +OPENSSL_EXPORT void EVP_DecodeInit(EVP_ENCODE_CTX *ctx); + +// EVP_DecodeUpdate decodes |in_len| bytes from |in| and writes the decoded +// data to |out| and sets |*out_len| to the number of bytes written. Some state +// may be contained in |ctx| so |EVP_DecodeFinal| must be used to flush it +// before using the encoded data. +// +// It returns -1 on error, one if a full line of input was processed and zero +// if the line was short (i.e. it was the last line). +OPENSSL_EXPORT int EVP_DecodeUpdate(EVP_ENCODE_CTX *ctx, uint8_t *out, + int *out_len, const uint8_t *in, + size_t in_len); + +// EVP_DecodeFinal flushes any remaining output bytes from |ctx| to |out| and +// sets |*out_len| to the number of bytes written. It returns one on success +// and minus one on error. +OPENSSL_EXPORT int EVP_DecodeFinal(EVP_ENCODE_CTX *ctx, uint8_t *out, + int *out_len); + +// EVP_DecodeBlock encodes |src_len| bytes from |src| and writes the result to +// |dst|. It returns the number of bytes written or -1 on error. +// +// WARNING: EVP_DecodeBlock's return value does not take padding into +// account. It also strips leading whitespace and trailing +// whitespace and minuses. +OPENSSL_EXPORT int EVP_DecodeBlock(uint8_t *dst, const uint8_t *src, + size_t src_len); + + +struct evp_encode_ctx_st { + // data_used indicates the number of bytes of |data| that are valid. When + // encoding, |data| will be filled and encoded as a lump. When decoding, only + // the first four bytes of |data| will be used. + unsigned data_used; + uint8_t data[48]; + + // eof_seen indicates that the end of the base64 data has been seen when + // decoding. Only whitespace can follow. + char eof_seen; + + // error_encountered indicates that invalid base64 data was found. This will + // cause all future calls to fail. + char error_encountered; +}; + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_BASE64_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/bio.h b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/bio.h new file mode 100644 index 0000000..db7f02d --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/bio.h @@ -0,0 +1,902 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 OPENSSL_HEADER_BIO_H +#define OPENSSL_HEADER_BIO_H + +#include + +#include // For FILE + +#include +#include // for ERR_print_errors_fp +#include +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// BIO abstracts over a file-descriptor like interface. + + +// Allocation and freeing. + +DEFINE_STACK_OF(BIO) + +// BIO_new creates a new BIO with the given method and a reference count of one. +// It returns the fresh |BIO|, or NULL on error. +OPENSSL_EXPORT BIO *BIO_new(const BIO_METHOD *method); + +// BIO_free decrements the reference count of |bio|. If the reference count +// drops to zero, it calls the destroy callback, if present, on the method and +// frees |bio| itself. It then repeats that for the next BIO in the chain, if +// any. +// +// It returns one on success or zero otherwise. +OPENSSL_EXPORT int BIO_free(BIO *bio); + +// BIO_vfree performs the same actions as |BIO_free|, but has a void return +// value. This is provided for API-compat. +// +// TODO(fork): remove. +OPENSSL_EXPORT void BIO_vfree(BIO *bio); + +// BIO_up_ref increments the reference count of |bio| and returns one. +OPENSSL_EXPORT int BIO_up_ref(BIO *bio); + + +// Basic I/O. + +// BIO_read attempts to read |len| bytes into |data|. It returns the number of +// bytes read, zero on EOF, or a negative number on error. +OPENSSL_EXPORT int BIO_read(BIO *bio, void *data, int len); + +// BIO_gets "reads a line" from |bio| and puts at most |size| bytes into |buf|. +// It returns the number of bytes read or a negative number on error. The +// phrase "reads a line" is in quotes in the previous sentence because the +// exact operation depends on the BIO's method. For example, a digest BIO will +// return the digest in response to a |BIO_gets| call. +// +// TODO(fork): audit the set of BIOs that we end up needing. If all actually +// return a line for this call, remove the warning above. +OPENSSL_EXPORT int BIO_gets(BIO *bio, char *buf, int size); + +// BIO_write writes |len| bytes from |data| to BIO. It returns the number of +// bytes written or a negative number on error. +OPENSSL_EXPORT int BIO_write(BIO *bio, const void *data, int len); + +// BIO_puts writes a NUL terminated string from |buf| to |bio|. It returns the +// number of bytes written or a negative number on error. +OPENSSL_EXPORT int BIO_puts(BIO *bio, const char *buf); + +// BIO_flush flushes any buffered output. It returns one on success and zero +// otherwise. +OPENSSL_EXPORT int BIO_flush(BIO *bio); + + +// Low-level control functions. +// +// These are generic functions for sending control requests to a BIO. In +// general one should use the wrapper functions like |BIO_get_close|. + +// BIO_ctrl sends the control request |cmd| to |bio|. The |cmd| argument should +// be one of the |BIO_C_*| values. +OPENSSL_EXPORT long BIO_ctrl(BIO *bio, int cmd, long larg, void *parg); + +// BIO_ptr_ctrl acts like |BIO_ctrl| but passes the address of a |void*| +// pointer as |parg| and returns the value that is written to it, or NULL if +// the control request returns <= 0. +OPENSSL_EXPORT char *BIO_ptr_ctrl(BIO *bp, int cmd, long larg); + +// BIO_int_ctrl acts like |BIO_ctrl| but passes the address of a copy of |iarg| +// as |parg|. +OPENSSL_EXPORT long BIO_int_ctrl(BIO *bp, int cmd, long larg, int iarg); + +// BIO_reset resets |bio| to its initial state, the precise meaning of which +// depends on the concrete type of |bio|. It returns one on success and zero +// otherwise. +OPENSSL_EXPORT int BIO_reset(BIO *bio); + +// BIO_eof returns non-zero when |bio| has reached end-of-file. The precise +// meaning of which depends on the concrete type of |bio|. Note that in the +// case of BIO_pair this always returns non-zero. +OPENSSL_EXPORT int BIO_eof(BIO *bio); + +// BIO_set_flags ORs |flags| with |bio->flags|. +OPENSSL_EXPORT void BIO_set_flags(BIO *bio, int flags); + +// BIO_test_flags returns |bio->flags| AND |flags|. +OPENSSL_EXPORT int BIO_test_flags(const BIO *bio, int flags); + +// BIO_should_read returns non-zero if |bio| encountered a temporary error +// while reading (i.e. EAGAIN), indicating that the caller should retry the +// read. +OPENSSL_EXPORT int BIO_should_read(const BIO *bio); + +// BIO_should_write returns non-zero if |bio| encountered a temporary error +// while writing (i.e. EAGAIN), indicating that the caller should retry the +// write. +OPENSSL_EXPORT int BIO_should_write(const BIO *bio); + +// BIO_should_retry returns non-zero if the reason that caused a failed I/O +// operation is temporary and thus the operation should be retried. Otherwise, +// it was a permanent error and it returns zero. +OPENSSL_EXPORT int BIO_should_retry(const BIO *bio); + +// BIO_should_io_special returns non-zero if |bio| encountered a temporary +// error while performing a special I/O operation, indicating that the caller +// should retry. The operation that caused the error is returned by +// |BIO_get_retry_reason|. +OPENSSL_EXPORT int BIO_should_io_special(const BIO *bio); + +// BIO_RR_CONNECT indicates that a connect would have blocked +#define BIO_RR_CONNECT 0x02 + +// BIO_RR_ACCEPT indicates that an accept would have blocked +#define BIO_RR_ACCEPT 0x03 + +// BIO_get_retry_reason returns the special I/O operation that needs to be +// retried. The return value is one of the |BIO_RR_*| values. +OPENSSL_EXPORT int BIO_get_retry_reason(const BIO *bio); + +// BIO_clear_flags ANDs |bio->flags| with the bitwise-complement of |flags|. +OPENSSL_EXPORT void BIO_clear_flags(BIO *bio, int flags); + +// BIO_set_retry_read sets the |BIO_FLAGS_READ| and |BIO_FLAGS_SHOULD_RETRY| +// flags on |bio|. +OPENSSL_EXPORT void BIO_set_retry_read(BIO *bio); + +// BIO_set_retry_write sets the |BIO_FLAGS_WRITE| and |BIO_FLAGS_SHOULD_RETRY| +// flags on |bio|. +OPENSSL_EXPORT void BIO_set_retry_write(BIO *bio); + +// BIO_get_retry_flags gets the |BIO_FLAGS_READ|, |BIO_FLAGS_WRITE|, +// |BIO_FLAGS_IO_SPECIAL| and |BIO_FLAGS_SHOULD_RETRY| flags from |bio|. +OPENSSL_EXPORT int BIO_get_retry_flags(BIO *bio); + +// BIO_clear_retry_flags clears the |BIO_FLAGS_READ|, |BIO_FLAGS_WRITE|, +// |BIO_FLAGS_IO_SPECIAL| and |BIO_FLAGS_SHOULD_RETRY| flags from |bio|. +OPENSSL_EXPORT void BIO_clear_retry_flags(BIO *bio); + +// BIO_method_type returns the type of |bio|, which is one of the |BIO_TYPE_*| +// values. +OPENSSL_EXPORT int BIO_method_type(const BIO *bio); + +// These are passed to 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 + +// bio_info_cb is the type of a callback function that can be called for most +// BIO operations. The |event| argument is one of |BIO_CB_*| and can be ORed +// with |BIO_CB_RETURN| if the callback is being made after the operation in +// question. In that case, |return_value| will contain the return value from +// the operation. +typedef long (*bio_info_cb)(BIO *bio, int event, const char *parg, int cmd, + long larg, long return_value); + +// BIO_callback_ctrl allows the callback function to be manipulated. The |cmd| +// arg will generally be |BIO_CTRL_SET_CALLBACK| but arbitrary command values +// can be interpreted by the |BIO|. +OPENSSL_EXPORT long BIO_callback_ctrl(BIO *bio, int cmd, bio_info_cb fp); + +// BIO_pending returns the number of bytes pending to be read. +OPENSSL_EXPORT size_t BIO_pending(const BIO *bio); + +// BIO_ctrl_pending calls |BIO_pending| and exists only for compatibility with +// OpenSSL. +OPENSSL_EXPORT size_t BIO_ctrl_pending(const BIO *bio); + +// BIO_wpending returns the number of bytes pending to be written. +OPENSSL_EXPORT size_t BIO_wpending(const BIO *bio); + +// BIO_set_close sets the close flag for |bio|. The meaning of which depends on +// the type of |bio| but, for example, a memory BIO interprets the close flag +// as meaning that it owns its buffer. It returns one on success and zero +// otherwise. +OPENSSL_EXPORT int BIO_set_close(BIO *bio, int close_flag); + +// BIO_number_read returns the number of bytes that have been read from +// |bio|. +OPENSSL_EXPORT size_t BIO_number_read(const BIO *bio); + +// BIO_number_written returns the number of bytes that have been written to +// |bio|. +OPENSSL_EXPORT size_t BIO_number_written(const BIO *bio); + + +// Managing chains of BIOs. +// +// BIOs can be put into chains where the output of one is used as the input of +// the next etc. The most common case is a buffering BIO, which accepts and +// buffers writes until flushed into the next BIO in the chain. + +// BIO_push adds |appended_bio| to the end of the chain with |bio| at the head. +// It returns |bio|. Note that |appended_bio| may be the head of a chain itself +// and thus this function can be used to join two chains. +// +// BIO_push takes ownership of the caller's reference to |appended_bio|. +OPENSSL_EXPORT BIO *BIO_push(BIO *bio, BIO *appended_bio); + +// BIO_pop removes |bio| from the head of a chain and returns the next BIO in +// the chain, or NULL if there is no next BIO. +// +// The caller takes ownership of the chain's reference to |bio|. +OPENSSL_EXPORT BIO *BIO_pop(BIO *bio); + +// BIO_next returns the next BIO in the chain after |bio|, or NULL if there is +// no such BIO. +OPENSSL_EXPORT BIO *BIO_next(BIO *bio); + +// BIO_free_all calls |BIO_free|. +// +// TODO(fork): update callers and remove. +OPENSSL_EXPORT void BIO_free_all(BIO *bio); + +// BIO_find_type walks a chain of BIOs and returns the first that matches +// |type|, which is one of the |BIO_TYPE_*| values. +OPENSSL_EXPORT BIO *BIO_find_type(BIO *bio, int type); + +// BIO_copy_next_retry sets the retry flags and |retry_reason| of |bio| from +// the next BIO in the chain. +OPENSSL_EXPORT void BIO_copy_next_retry(BIO *bio); + + +// Printf functions. + +// BIO_printf behaves like |printf| but outputs to |bio| rather than a |FILE|. +// It returns the number of bytes written or a negative number on error. +OPENSSL_EXPORT int BIO_printf(BIO *bio, const char *format, ...) + OPENSSL_PRINTF_FORMAT_FUNC(2, 3); + + +// Utility functions. + +// BIO_indent prints min(|indent|, |max_indent|) spaces. It returns one on +// success and zero otherwise. +OPENSSL_EXPORT int BIO_indent(BIO *bio, unsigned indent, unsigned max_indent); + +// BIO_hexdump writes a hex dump of |data| to |bio|. Each line will be indented +// by |indent| spaces. +OPENSSL_EXPORT int BIO_hexdump(BIO *bio, const uint8_t *data, size_t len, + unsigned indent); + +// ERR_print_errors prints the current contents of the error stack to |bio| +// using human readable strings where possible. +OPENSSL_EXPORT void ERR_print_errors(BIO *bio); + +// BIO_read_asn1 reads a single ASN.1 object from |bio|. If successful it sets +// |*out| to be an allocated buffer (that should be freed with |OPENSSL_free|), +// |*out_size| to the length, in bytes, of that buffer and returns one. +// Otherwise it returns zero. +// +// If the length of the object is greater than |max_len| or 2^32 then the +// function will fail. Long-form tags are not supported. If the length of the +// object is indefinite the full contents of |bio| are read, unless it would be +// greater than |max_len|, in which case the function fails. +// +// If the function fails then some unknown amount of data may have been read +// from |bio|. +OPENSSL_EXPORT int BIO_read_asn1(BIO *bio, uint8_t **out, size_t *out_len, + size_t max_len); + + +// Memory BIOs. +// +// Memory BIOs can be used as a read-only source (with |BIO_new_mem_buf|) or a +// writable sink (with |BIO_new|, |BIO_s_mem| and |BIO_mem_contents|). Data +// written to a writable, memory BIO can be recalled by reading from it. +// +// Calling |BIO_reset| on a read-only BIO resets it to the original contents. +// On a writable BIO, it clears any data. +// +// If the close flag is set to |BIO_NOCLOSE| (not the default) then the +// underlying |BUF_MEM| will not be freed when the |BIO| is freed. +// +// Memory BIOs support |BIO_gets| and |BIO_puts|. +// +// |BIO_ctrl_pending| returns the number of bytes currently stored. + +// BIO_NOCLOSE and |BIO_CLOSE| can be used as symbolic arguments when a "close +// flag" is passed to a BIO function. +#define BIO_NOCLOSE 0 +#define BIO_CLOSE 1 + +// BIO_s_mem returns a |BIO_METHOD| that uses a in-memory buffer. +OPENSSL_EXPORT const BIO_METHOD *BIO_s_mem(void); + +// BIO_new_mem_buf creates read-only BIO that reads from |len| bytes at |buf|. +// It does not take ownership of |buf|. It returns the BIO or NULL on error. +// +// If |len| is negative, then |buf| is treated as a NUL-terminated string, but +// don't depend on this in new code. +OPENSSL_EXPORT BIO *BIO_new_mem_buf(const void *buf, int len); + +// BIO_mem_contents sets |*out_contents| to point to the current contents of +// |bio| and |*out_len| to contain the length of that data. It returns one on +// success and zero otherwise. +OPENSSL_EXPORT int BIO_mem_contents(const BIO *bio, + const uint8_t **out_contents, + size_t *out_len); + +// BIO_get_mem_data sets |*contents| to point to the current contents of |bio| +// and returns the length of the data. +// +// WARNING: don't use this, use |BIO_mem_contents|. A return value of zero from +// this function can mean either that it failed or that the memory buffer is +// empty. +OPENSSL_EXPORT long BIO_get_mem_data(BIO *bio, char **contents); + +// BIO_get_mem_ptr sets |*out| to a BUF_MEM containing the current contents of +// |bio|. It returns one on success or zero on error. +OPENSSL_EXPORT int BIO_get_mem_ptr(BIO *bio, BUF_MEM **out); + +// BIO_set_mem_buf sets |b| as the contents of |bio|. If |take_ownership| is +// non-zero, then |b| will be freed when |bio| is closed. Returns one on +// success or zero otherwise. +OPENSSL_EXPORT int BIO_set_mem_buf(BIO *bio, BUF_MEM *b, int take_ownership); + +// BIO_set_mem_eof_return sets the value that will be returned from reading +// |bio| when empty. If |eof_value| is zero then an empty memory BIO will +// return EOF (that is it will return zero and |BIO_should_retry| will be +// false). If |eof_value| is non zero then it will return |eof_value| when it +// is empty and it will set the read retry flag (that is |BIO_read_retry| is +// true). To avoid ambiguity with a normal positive return value, |eof_value| +// should be set to a negative value, typically -1. +// +// For a read-only BIO, the default is zero (EOF). For a writable BIO, the +// default is -1 so that additional data can be written once exhausted. +OPENSSL_EXPORT int BIO_set_mem_eof_return(BIO *bio, int eof_value); + + +// File descriptor BIOs. +// +// File descriptor BIOs are wrappers around the system's |read| and |write| +// functions. If the close flag is set then then |close| is called on the +// underlying file descriptor when the BIO is freed. +// +// |BIO_reset| attempts to seek the file pointer to the start of file using +// |lseek|. + +// BIO_s_fd returns a |BIO_METHOD| for file descriptor fds. +OPENSSL_EXPORT const BIO_METHOD *BIO_s_fd(void); + +// BIO_new_fd creates a new file descriptor BIO wrapping |fd|. If |close_flag| +// is non-zero, then |fd| will be closed when the BIO is. +OPENSSL_EXPORT BIO *BIO_new_fd(int fd, int close_flag); + +// BIO_set_fd sets the file descriptor of |bio| to |fd|. If |close_flag| is +// non-zero then |fd| will be closed when |bio| is. It returns one on success +// or zero on error. +// +// This function may also be used with socket BIOs (see |BIO_s_socket| and +// |BIO_new_socket|). +OPENSSL_EXPORT int BIO_set_fd(BIO *bio, int fd, int close_flag); + +// BIO_get_fd returns the file descriptor currently in use by |bio| or -1 if +// |bio| does not wrap a file descriptor. If there is a file descriptor and +// |out_fd| is not NULL, it also sets |*out_fd| to the file descriptor. +// +// This function may also be used with socket BIOs (see |BIO_s_socket| and +// |BIO_new_socket|). +OPENSSL_EXPORT int BIO_get_fd(BIO *bio, int *out_fd); + + +// File BIOs. +// +// File BIOs are wrappers around a C |FILE| object. +// +// |BIO_flush| on a file BIO calls |fflush| on the wrapped stream. +// +// |BIO_reset| attempts to seek the file pointer to the start of file using +// |fseek|. +// +// Setting the close flag causes |fclose| to be called on the stream when the +// BIO is freed. + +// BIO_s_file returns a BIO_METHOD that wraps a |FILE|. +OPENSSL_EXPORT const BIO_METHOD *BIO_s_file(void); + +// BIO_new_file creates a file BIO by opening |filename| with the given mode. +// See the |fopen| manual page for details of the mode argument. +OPENSSL_EXPORT BIO *BIO_new_file(const char *filename, const char *mode); + +// BIO_new_fp creates a new file BIO that wraps the given |FILE|. If +// |close_flag| is |BIO_CLOSE|, then |fclose| will be called on |stream| when +// the BIO is closed. +OPENSSL_EXPORT BIO *BIO_new_fp(FILE *stream, int close_flag); + +// BIO_get_fp sets |*out_file| to the current |FILE| for |bio|. It returns one +// on success and zero otherwise. +OPENSSL_EXPORT int BIO_get_fp(BIO *bio, FILE **out_file); + +// BIO_set_fp sets the |FILE| for |bio|. If |close_flag| is |BIO_CLOSE| then +// |fclose| will be called on |file| when |bio| is closed. It returns one on +// success and zero otherwise. +OPENSSL_EXPORT int BIO_set_fp(BIO *bio, FILE *file, int close_flag); + +// BIO_read_filename opens |filename| for reading and sets the result as the +// |FILE| for |bio|. It returns one on success and zero otherwise. The |FILE| +// will be closed when |bio| is freed. +OPENSSL_EXPORT int BIO_read_filename(BIO *bio, const char *filename); + +// BIO_write_filename opens |filename| for writing and sets the result as the +// |FILE| for |bio|. It returns one on success and zero otherwise. The |FILE| +// will be closed when |bio| is freed. +OPENSSL_EXPORT int BIO_write_filename(BIO *bio, const char *filename); + +// BIO_append_filename opens |filename| for appending and sets the result as +// the |FILE| for |bio|. It returns one on success and zero otherwise. The +// |FILE| will be closed when |bio| is freed. +OPENSSL_EXPORT int BIO_append_filename(BIO *bio, const char *filename); + +// BIO_rw_filename opens |filename| for reading and writing and sets the result +// as the |FILE| for |bio|. It returns one on success and zero otherwise. The +// |FILE| will be closed when |bio| is freed. +OPENSSL_EXPORT int BIO_rw_filename(BIO *bio, const char *filename); + + +// Socket BIOs. +// +// Socket BIOs behave like file descriptor BIOs but, on Windows systems, wrap +// the system's |recv| and |send| functions instead of |read| and |write|. On +// Windows, file descriptors are provided by C runtime and are not +// interchangeable with sockets. +// +// Socket BIOs may be used with |BIO_set_fd| and |BIO_get_fd|. +// +// TODO(davidben): Add separate APIs and fix the internals to use |SOCKET|s +// around rather than rely on int casts. + +OPENSSL_EXPORT const BIO_METHOD *BIO_s_socket(void); + +// BIO_new_socket allocates and initialises a fresh BIO which will read and +// write to the socket |fd|. If |close_flag| is |BIO_CLOSE| then closing the +// BIO will close |fd|. It returns the fresh |BIO| or NULL on error. +OPENSSL_EXPORT BIO *BIO_new_socket(int fd, int close_flag); + + +// Connect BIOs. +// +// A connection BIO creates a network connection and transfers data over the +// resulting socket. + +OPENSSL_EXPORT const BIO_METHOD *BIO_s_connect(void); + +// BIO_new_connect returns a BIO that connects to the given hostname and port. +// The |host_and_optional_port| argument should be of the form +// "www.example.com" or "www.example.com:443". If the port is omitted, it must +// be provided with |BIO_set_conn_port|. +// +// It returns the new BIO on success, or NULL on error. +OPENSSL_EXPORT BIO *BIO_new_connect(const char *host_and_optional_port); + +// BIO_set_conn_hostname sets |host_and_optional_port| as the hostname and +// optional port that |bio| will connect to. If the port is omitted, it must be +// provided with |BIO_set_conn_port|. +// +// It returns one on success and zero otherwise. +OPENSSL_EXPORT int BIO_set_conn_hostname(BIO *bio, + const char *host_and_optional_port); + +// BIO_set_conn_port sets |port_str| as the port or service name that |bio| +// will connect to. It returns one on success and zero otherwise. +OPENSSL_EXPORT int BIO_set_conn_port(BIO *bio, const char *port_str); + +// BIO_set_conn_int_port sets |*port| as the port that |bio| will connect to. +// It returns one on success and zero otherwise. +OPENSSL_EXPORT int BIO_set_conn_int_port(BIO *bio, const int *port); + +// BIO_set_nbio sets whether |bio| will use non-blocking I/O operations. It +// returns one on success and zero otherwise. +OPENSSL_EXPORT int BIO_set_nbio(BIO *bio, int on); + +// BIO_do_connect connects |bio| if it has not been connected yet. It returns +// one on success and <= 0 otherwise. +OPENSSL_EXPORT int BIO_do_connect(BIO *bio); + + +// Datagram BIOs. +// +// TODO(fork): not implemented. + +#define BIO_CTRL_DGRAM_QUERY_MTU 40 // as kernel for current 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. */ + +// BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT is unsupported as it is unused by consumers +// and depends on |timeval|, which is not 2038-clean on all platforms. + +#define BIO_CTRL_DGRAM_GET_PEER 46 + +#define BIO_CTRL_DGRAM_GET_FALLBACK_MTU 47 + + +// BIO Pairs. +// +// BIO pairs provide a "loopback" like system: a pair of BIOs where data +// written to one can be read from the other and vice versa. + +// BIO_new_bio_pair sets |*out1| and |*out2| to two freshly created BIOs where +// data written to one can be read from the other and vice versa. The +// |writebuf1| argument gives the size of the buffer used in |*out1| and +// |writebuf2| for |*out2|. It returns one on success and zero on error. +OPENSSL_EXPORT int BIO_new_bio_pair(BIO **out1, size_t writebuf1, BIO **out2, + size_t writebuf2); + +// BIO_ctrl_get_read_request returns the number of bytes that the other side of +// |bio| tried (unsuccessfully) to read. +OPENSSL_EXPORT size_t BIO_ctrl_get_read_request(BIO *bio); + +// BIO_ctrl_get_write_guarantee returns the number of bytes that |bio| (which +// must have been returned by |BIO_new_bio_pair|) will accept on the next +// |BIO_write| call. +OPENSSL_EXPORT size_t BIO_ctrl_get_write_guarantee(BIO *bio); + +// BIO_shutdown_wr marks |bio| as closed, from the point of view of the other +// side of the pair. Future |BIO_write| calls on |bio| will fail. It returns +// one on success and zero otherwise. +OPENSSL_EXPORT int BIO_shutdown_wr(BIO *bio); + + +// Custom BIOs. +// +// Consumers can create custom |BIO|s by filling in a |BIO_METHOD| and using +// low-level control functions to set state. + +// BIO_get_new_index returns a new "type" value for a custom |BIO|. +OPENSSL_EXPORT int BIO_get_new_index(void); + +// BIO_meth_new returns a newly-allocated |BIO_METHOD| or NULL on allocation +// error. The |type| specifies the type that will be returned by +// |BIO_method_type|. If this is unnecessary, this value may be zero. The |name| +// parameter is vestigial and may be NULL. +// +// Use the |BIO_meth_set_*| functions below to initialize the |BIO_METHOD|. The +// function implementations may use |BIO_set_data| and |BIO_get_data| to add +// method-specific state to associated |BIO|s. Additionally, |BIO_set_init| must +// be called after an associated |BIO| is fully initialized. State set via +// |BIO_set_data| may be released by configuring a destructor with +// |BIO_meth_set_destroy|. +OPENSSL_EXPORT BIO_METHOD *BIO_meth_new(int type, const char *name); + +// BIO_meth_free releases memory associated with |method|. +OPENSSL_EXPORT void BIO_meth_free(BIO_METHOD *method); + +// BIO_meth_set_create sets a function to be called on |BIO_new| for |method| +// and returns one. The function should return one on success and zero on +// error. +OPENSSL_EXPORT int BIO_meth_set_create(BIO_METHOD *method, + int (*create)(BIO *)); + +// BIO_meth_set_destroy sets a function to release data associated with a |BIO| +// and returns one. The function's return value is ignored. +OPENSSL_EXPORT int BIO_meth_set_destroy(BIO_METHOD *method, + int (*destroy)(BIO *)); + +// BIO_meth_set_write sets the implementation of |BIO_write| for |method| and +// returns one. |BIO_METHOD|s which implement |BIO_write| should also implement +// |BIO_CTRL_FLUSH|. (See |BIO_meth_set_ctrl|.) +OPENSSL_EXPORT int BIO_meth_set_write(BIO_METHOD *method, + int (*write)(BIO *, const char *, int)); + +// BIO_meth_set_read sets the implementation of |BIO_read| for |method| and +// returns one. +OPENSSL_EXPORT int BIO_meth_set_read(BIO_METHOD *method, + int (*read)(BIO *, char *, int)); + +// BIO_meth_set_gets sets the implementation of |BIO_gets| for |method| and +// returns one. +OPENSSL_EXPORT int BIO_meth_set_gets(BIO_METHOD *method, + int (*gets)(BIO *, char *, int)); + +// BIO_meth_set_ctrl sets the implementation of |BIO_ctrl| for |method| and +// returns one. +OPENSSL_EXPORT int BIO_meth_set_ctrl(BIO_METHOD *method, + long (*ctrl)(BIO *, int, long, void *)); + +// BIO_set_data sets custom data on |bio|. It may be retried with +// |BIO_get_data|. +OPENSSL_EXPORT void BIO_set_data(BIO *bio, void *ptr); + +// BIO_get_data returns custom data on |bio| set by |BIO_get_data|. +OPENSSL_EXPORT void *BIO_get_data(BIO *bio); + +// BIO_set_init sets whether |bio| has been fully initialized. Until fully +// initialized, |BIO_read| and |BIO_write| will fail. +OPENSSL_EXPORT void BIO_set_init(BIO *bio, int init); + +// BIO_get_init returns whether |bio| has been fully initialized. +OPENSSL_EXPORT int BIO_get_init(BIO *bio); + +// These are values of the |cmd| argument 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 +#define BIO_CTRL_POP 7 +#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_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 + +// BIO_CTRL_DUP is never used, but exists to allow code to compile more +// easily. +#define BIO_CTRL_DUP 12 + + +// Deprecated functions. + +// BIO_f_base64 returns a filter |BIO| that base64-encodes data written into +// it, and decodes data read from it. |BIO_gets| is not supported. Call +// |BIO_flush| when done writing, to signal that no more data are to be +// encoded. The flag |BIO_FLAGS_BASE64_NO_NL| may be set to encode all the data +// on one line. +OPENSSL_EXPORT const BIO_METHOD *BIO_f_base64(void); + +OPENSSL_EXPORT void BIO_set_retry_special(BIO *bio); + +// BIO_set_write_buffer_size returns zero. +OPENSSL_EXPORT int BIO_set_write_buffer_size(BIO *bio, int buffer_size); + +// BIO_set_shutdown sets a method-specific "shutdown" bit on |bio|. +OPENSSL_EXPORT void BIO_set_shutdown(BIO *bio, int shutdown); + +// BIO_get_shutdown returns the method-specific "shutdown" bit. +OPENSSL_EXPORT int BIO_get_shutdown(BIO *bio); + +// BIO_meth_set_puts returns one. |BIO_puts| is implemented with |BIO_write| in +// BoringSSL. +OPENSSL_EXPORT int BIO_meth_set_puts(BIO_METHOD *method, + int (*puts)(BIO *, const char *)); + + +// Private functions + +#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 +#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 + +// 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) +#define BIO_TYPE_ASN1 (22 | 0x0200) // filter +#define BIO_TYPE_COMP (23 | 0x0200) // filter + +// |BIO_TYPE_DESCRIPTOR| denotes that the |BIO| responds to the |BIO_C_SET_FD| +// (|BIO_set_fd|) and |BIO_C_GET_FD| (|BIO_get_fd|) control hooks. +#define BIO_TYPE_DESCRIPTOR 0x0100 // socket, fd, connect or accept +#define BIO_TYPE_FILTER 0x0200 +#define BIO_TYPE_SOURCE_SINK 0x0400 + +// BIO_TYPE_START is the first user-allocated |BIO| type. No pre-defined type, +// flag bits aside, may exceed this value. +#define BIO_TYPE_START 128 + +struct bio_method_st { + int type; + const char *name; + int (*bwrite)(BIO *, const char *, int); + int (*bread)(BIO *, char *, int); + // TODO(fork): remove bputs. + 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); +}; + +struct bio_st { + const BIO_METHOD *method; + + // init is non-zero if this |BIO| has been initialised. + int init; + // shutdown is often used by specific |BIO_METHOD|s to determine whether + // they own some underlying resource. This flag can often by controlled by + // |BIO_set_close|. For example, whether an fd BIO closes the underlying fd + // when it, itself, is closed. + int shutdown; + int flags; + int retry_reason; + // num is a BIO-specific value. For example, in fd BIOs it's used to store a + // file descriptor. + int num; + CRYPTO_refcount_t references; + void *ptr; + // next_bio points to the next |BIO| in a chain. This |BIO| owns a reference + // to |next_bio|. + BIO *next_bio; // used by filter BIOs + size_t num_read, num_write; +}; + +#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_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_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 + + +#if defined(__cplusplus) +} // extern C + +extern "C++" { + +namespace bssl { + +BORINGSSL_MAKE_DELETER(BIO, BIO_free) + +} // namespace bssl + +} // extern C++ + +#endif + +#define BIO_R_BAD_FOPEN_MODE 100 +#define BIO_R_BROKEN_PIPE 101 +#define BIO_R_CONNECT_ERROR 102 +#define BIO_R_ERROR_SETTING_NBIO 103 +#define BIO_R_INVALID_ARGUMENT 104 +#define BIO_R_IN_USE 105 +#define BIO_R_KEEPALIVE 106 +#define BIO_R_NBIO_CONNECT_ERROR 107 +#define BIO_R_NO_HOSTNAME_SPECIFIED 108 +#define BIO_R_NO_PORT_SPECIFIED 109 +#define BIO_R_NO_SUCH_FILE 110 +#define BIO_R_NULL_PARAMETER 111 +#define BIO_R_SYS_LIB 112 +#define BIO_R_UNABLE_TO_CREATE_SOCKET 113 +#define BIO_R_UNINITIALIZED 114 +#define BIO_R_UNSUPPORTED_METHOD 115 +#define BIO_R_WRITE_TO_READ_ONLY_BIO 116 + +#endif // OPENSSL_HEADER_BIO_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/bio.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/bio.h.grpc_back new file mode 100644 index 0000000..5e3e2ef --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/bio.h.grpc_back @@ -0,0 +1,902 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 OPENSSL_HEADER_BIO_H +#define OPENSSL_HEADER_BIO_H + +#include + +#include // For FILE + +#include +#include // for ERR_print_errors_fp +#include +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// BIO abstracts over a file-descriptor like interface. + + +// Allocation and freeing. + +DEFINE_STACK_OF(BIO) + +// BIO_new creates a new BIO with the given method and a reference count of one. +// It returns the fresh |BIO|, or NULL on error. +OPENSSL_EXPORT BIO *BIO_new(const BIO_METHOD *method); + +// BIO_free decrements the reference count of |bio|. If the reference count +// drops to zero, it calls the destroy callback, if present, on the method and +// frees |bio| itself. It then repeats that for the next BIO in the chain, if +// any. +// +// It returns one on success or zero otherwise. +OPENSSL_EXPORT int BIO_free(BIO *bio); + +// BIO_vfree performs the same actions as |BIO_free|, but has a void return +// value. This is provided for API-compat. +// +// TODO(fork): remove. +OPENSSL_EXPORT void BIO_vfree(BIO *bio); + +// BIO_up_ref increments the reference count of |bio| and returns one. +OPENSSL_EXPORT int BIO_up_ref(BIO *bio); + + +// Basic I/O. + +// BIO_read attempts to read |len| bytes into |data|. It returns the number of +// bytes read, zero on EOF, or a negative number on error. +OPENSSL_EXPORT int BIO_read(BIO *bio, void *data, int len); + +// BIO_gets "reads a line" from |bio| and puts at most |size| bytes into |buf|. +// It returns the number of bytes read or a negative number on error. The +// phrase "reads a line" is in quotes in the previous sentence because the +// exact operation depends on the BIO's method. For example, a digest BIO will +// return the digest in response to a |BIO_gets| call. +// +// TODO(fork): audit the set of BIOs that we end up needing. If all actually +// return a line for this call, remove the warning above. +OPENSSL_EXPORT int BIO_gets(BIO *bio, char *buf, int size); + +// BIO_write writes |len| bytes from |data| to BIO. It returns the number of +// bytes written or a negative number on error. +OPENSSL_EXPORT int BIO_write(BIO *bio, const void *data, int len); + +// BIO_puts writes a NUL terminated string from |buf| to |bio|. It returns the +// number of bytes written or a negative number on error. +OPENSSL_EXPORT int BIO_puts(BIO *bio, const char *buf); + +// BIO_flush flushes any buffered output. It returns one on success and zero +// otherwise. +OPENSSL_EXPORT int BIO_flush(BIO *bio); + + +// Low-level control functions. +// +// These are generic functions for sending control requests to a BIO. In +// general one should use the wrapper functions like |BIO_get_close|. + +// BIO_ctrl sends the control request |cmd| to |bio|. The |cmd| argument should +// be one of the |BIO_C_*| values. +OPENSSL_EXPORT long BIO_ctrl(BIO *bio, int cmd, long larg, void *parg); + +// BIO_ptr_ctrl acts like |BIO_ctrl| but passes the address of a |void*| +// pointer as |parg| and returns the value that is written to it, or NULL if +// the control request returns <= 0. +OPENSSL_EXPORT char *BIO_ptr_ctrl(BIO *bp, int cmd, long larg); + +// BIO_int_ctrl acts like |BIO_ctrl| but passes the address of a copy of |iarg| +// as |parg|. +OPENSSL_EXPORT long BIO_int_ctrl(BIO *bp, int cmd, long larg, int iarg); + +// BIO_reset resets |bio| to its initial state, the precise meaning of which +// depends on the concrete type of |bio|. It returns one on success and zero +// otherwise. +OPENSSL_EXPORT int BIO_reset(BIO *bio); + +// BIO_eof returns non-zero when |bio| has reached end-of-file. The precise +// meaning of which depends on the concrete type of |bio|. Note that in the +// case of BIO_pair this always returns non-zero. +OPENSSL_EXPORT int BIO_eof(BIO *bio); + +// BIO_set_flags ORs |flags| with |bio->flags|. +OPENSSL_EXPORT void BIO_set_flags(BIO *bio, int flags); + +// BIO_test_flags returns |bio->flags| AND |flags|. +OPENSSL_EXPORT int BIO_test_flags(const BIO *bio, int flags); + +// BIO_should_read returns non-zero if |bio| encountered a temporary error +// while reading (i.e. EAGAIN), indicating that the caller should retry the +// read. +OPENSSL_EXPORT int BIO_should_read(const BIO *bio); + +// BIO_should_write returns non-zero if |bio| encountered a temporary error +// while writing (i.e. EAGAIN), indicating that the caller should retry the +// write. +OPENSSL_EXPORT int BIO_should_write(const BIO *bio); + +// BIO_should_retry returns non-zero if the reason that caused a failed I/O +// operation is temporary and thus the operation should be retried. Otherwise, +// it was a permanent error and it returns zero. +OPENSSL_EXPORT int BIO_should_retry(const BIO *bio); + +// BIO_should_io_special returns non-zero if |bio| encountered a temporary +// error while performing a special I/O operation, indicating that the caller +// should retry. The operation that caused the error is returned by +// |BIO_get_retry_reason|. +OPENSSL_EXPORT int BIO_should_io_special(const BIO *bio); + +// BIO_RR_CONNECT indicates that a connect would have blocked +#define BIO_RR_CONNECT 0x02 + +// BIO_RR_ACCEPT indicates that an accept would have blocked +#define BIO_RR_ACCEPT 0x03 + +// BIO_get_retry_reason returns the special I/O operation that needs to be +// retried. The return value is one of the |BIO_RR_*| values. +OPENSSL_EXPORT int BIO_get_retry_reason(const BIO *bio); + +// BIO_clear_flags ANDs |bio->flags| with the bitwise-complement of |flags|. +OPENSSL_EXPORT void BIO_clear_flags(BIO *bio, int flags); + +// BIO_set_retry_read sets the |BIO_FLAGS_READ| and |BIO_FLAGS_SHOULD_RETRY| +// flags on |bio|. +OPENSSL_EXPORT void BIO_set_retry_read(BIO *bio); + +// BIO_set_retry_write sets the |BIO_FLAGS_WRITE| and |BIO_FLAGS_SHOULD_RETRY| +// flags on |bio|. +OPENSSL_EXPORT void BIO_set_retry_write(BIO *bio); + +// BIO_get_retry_flags gets the |BIO_FLAGS_READ|, |BIO_FLAGS_WRITE|, +// |BIO_FLAGS_IO_SPECIAL| and |BIO_FLAGS_SHOULD_RETRY| flags from |bio|. +OPENSSL_EXPORT int BIO_get_retry_flags(BIO *bio); + +// BIO_clear_retry_flags clears the |BIO_FLAGS_READ|, |BIO_FLAGS_WRITE|, +// |BIO_FLAGS_IO_SPECIAL| and |BIO_FLAGS_SHOULD_RETRY| flags from |bio|. +OPENSSL_EXPORT void BIO_clear_retry_flags(BIO *bio); + +// BIO_method_type returns the type of |bio|, which is one of the |BIO_TYPE_*| +// values. +OPENSSL_EXPORT int BIO_method_type(const BIO *bio); + +// These are passed to 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 + +// bio_info_cb is the type of a callback function that can be called for most +// BIO operations. The |event| argument is one of |BIO_CB_*| and can be ORed +// with |BIO_CB_RETURN| if the callback is being made after the operation in +// question. In that case, |return_value| will contain the return value from +// the operation. +typedef long (*bio_info_cb)(BIO *bio, int event, const char *parg, int cmd, + long larg, long return_value); + +// BIO_callback_ctrl allows the callback function to be manipulated. The |cmd| +// arg will generally be |BIO_CTRL_SET_CALLBACK| but arbitrary command values +// can be interpreted by the |BIO|. +OPENSSL_EXPORT long BIO_callback_ctrl(BIO *bio, int cmd, bio_info_cb fp); + +// BIO_pending returns the number of bytes pending to be read. +OPENSSL_EXPORT size_t BIO_pending(const BIO *bio); + +// BIO_ctrl_pending calls |BIO_pending| and exists only for compatibility with +// OpenSSL. +OPENSSL_EXPORT size_t BIO_ctrl_pending(const BIO *bio); + +// BIO_wpending returns the number of bytes pending to be written. +OPENSSL_EXPORT size_t BIO_wpending(const BIO *bio); + +// BIO_set_close sets the close flag for |bio|. The meaning of which depends on +// the type of |bio| but, for example, a memory BIO interprets the close flag +// as meaning that it owns its buffer. It returns one on success and zero +// otherwise. +OPENSSL_EXPORT int BIO_set_close(BIO *bio, int close_flag); + +// BIO_number_read returns the number of bytes that have been read from +// |bio|. +OPENSSL_EXPORT size_t BIO_number_read(const BIO *bio); + +// BIO_number_written returns the number of bytes that have been written to +// |bio|. +OPENSSL_EXPORT size_t BIO_number_written(const BIO *bio); + + +// Managing chains of BIOs. +// +// BIOs can be put into chains where the output of one is used as the input of +// the next etc. The most common case is a buffering BIO, which accepts and +// buffers writes until flushed into the next BIO in the chain. + +// BIO_push adds |appended_bio| to the end of the chain with |bio| at the head. +// It returns |bio|. Note that |appended_bio| may be the head of a chain itself +// and thus this function can be used to join two chains. +// +// BIO_push takes ownership of the caller's reference to |appended_bio|. +OPENSSL_EXPORT BIO *BIO_push(BIO *bio, BIO *appended_bio); + +// BIO_pop removes |bio| from the head of a chain and returns the next BIO in +// the chain, or NULL if there is no next BIO. +// +// The caller takes ownership of the chain's reference to |bio|. +OPENSSL_EXPORT BIO *BIO_pop(BIO *bio); + +// BIO_next returns the next BIO in the chain after |bio|, or NULL if there is +// no such BIO. +OPENSSL_EXPORT BIO *BIO_next(BIO *bio); + +// BIO_free_all calls |BIO_free|. +// +// TODO(fork): update callers and remove. +OPENSSL_EXPORT void BIO_free_all(BIO *bio); + +// BIO_find_type walks a chain of BIOs and returns the first that matches +// |type|, which is one of the |BIO_TYPE_*| values. +OPENSSL_EXPORT BIO *BIO_find_type(BIO *bio, int type); + +// BIO_copy_next_retry sets the retry flags and |retry_reason| of |bio| from +// the next BIO in the chain. +OPENSSL_EXPORT void BIO_copy_next_retry(BIO *bio); + + +// Printf functions. + +// BIO_printf behaves like |printf| but outputs to |bio| rather than a |FILE|. +// It returns the number of bytes written or a negative number on error. +OPENSSL_EXPORT int BIO_printf(BIO *bio, const char *format, ...) + OPENSSL_PRINTF_FORMAT_FUNC(2, 3); + + +// Utility functions. + +// BIO_indent prints min(|indent|, |max_indent|) spaces. It returns one on +// success and zero otherwise. +OPENSSL_EXPORT int BIO_indent(BIO *bio, unsigned indent, unsigned max_indent); + +// BIO_hexdump writes a hex dump of |data| to |bio|. Each line will be indented +// by |indent| spaces. +OPENSSL_EXPORT int BIO_hexdump(BIO *bio, const uint8_t *data, size_t len, + unsigned indent); + +// ERR_print_errors prints the current contents of the error stack to |bio| +// using human readable strings where possible. +OPENSSL_EXPORT void ERR_print_errors(BIO *bio); + +// BIO_read_asn1 reads a single ASN.1 object from |bio|. If successful it sets +// |*out| to be an allocated buffer (that should be freed with |OPENSSL_free|), +// |*out_size| to the length, in bytes, of that buffer and returns one. +// Otherwise it returns zero. +// +// If the length of the object is greater than |max_len| or 2^32 then the +// function will fail. Long-form tags are not supported. If the length of the +// object is indefinite the full contents of |bio| are read, unless it would be +// greater than |max_len|, in which case the function fails. +// +// If the function fails then some unknown amount of data may have been read +// from |bio|. +OPENSSL_EXPORT int BIO_read_asn1(BIO *bio, uint8_t **out, size_t *out_len, + size_t max_len); + + +// Memory BIOs. +// +// Memory BIOs can be used as a read-only source (with |BIO_new_mem_buf|) or a +// writable sink (with |BIO_new|, |BIO_s_mem| and |BIO_mem_contents|). Data +// written to a writable, memory BIO can be recalled by reading from it. +// +// Calling |BIO_reset| on a read-only BIO resets it to the original contents. +// On a writable BIO, it clears any data. +// +// If the close flag is set to |BIO_NOCLOSE| (not the default) then the +// underlying |BUF_MEM| will not be freed when the |BIO| is freed. +// +// Memory BIOs support |BIO_gets| and |BIO_puts|. +// +// |BIO_ctrl_pending| returns the number of bytes currently stored. + +// BIO_NOCLOSE and |BIO_CLOSE| can be used as symbolic arguments when a "close +// flag" is passed to a BIO function. +#define BIO_NOCLOSE 0 +#define BIO_CLOSE 1 + +// BIO_s_mem returns a |BIO_METHOD| that uses a in-memory buffer. +OPENSSL_EXPORT const BIO_METHOD *BIO_s_mem(void); + +// BIO_new_mem_buf creates read-only BIO that reads from |len| bytes at |buf|. +// It does not take ownership of |buf|. It returns the BIO or NULL on error. +// +// If |len| is negative, then |buf| is treated as a NUL-terminated string, but +// don't depend on this in new code. +OPENSSL_EXPORT BIO *BIO_new_mem_buf(const void *buf, int len); + +// BIO_mem_contents sets |*out_contents| to point to the current contents of +// |bio| and |*out_len| to contain the length of that data. It returns one on +// success and zero otherwise. +OPENSSL_EXPORT int BIO_mem_contents(const BIO *bio, + const uint8_t **out_contents, + size_t *out_len); + +// BIO_get_mem_data sets |*contents| to point to the current contents of |bio| +// and returns the length of the data. +// +// WARNING: don't use this, use |BIO_mem_contents|. A return value of zero from +// this function can mean either that it failed or that the memory buffer is +// empty. +OPENSSL_EXPORT long BIO_get_mem_data(BIO *bio, char **contents); + +// BIO_get_mem_ptr sets |*out| to a BUF_MEM containing the current contents of +// |bio|. It returns one on success or zero on error. +OPENSSL_EXPORT int BIO_get_mem_ptr(BIO *bio, BUF_MEM **out); + +// BIO_set_mem_buf sets |b| as the contents of |bio|. If |take_ownership| is +// non-zero, then |b| will be freed when |bio| is closed. Returns one on +// success or zero otherwise. +OPENSSL_EXPORT int BIO_set_mem_buf(BIO *bio, BUF_MEM *b, int take_ownership); + +// BIO_set_mem_eof_return sets the value that will be returned from reading +// |bio| when empty. If |eof_value| is zero then an empty memory BIO will +// return EOF (that is it will return zero and |BIO_should_retry| will be +// false). If |eof_value| is non zero then it will return |eof_value| when it +// is empty and it will set the read retry flag (that is |BIO_read_retry| is +// true). To avoid ambiguity with a normal positive return value, |eof_value| +// should be set to a negative value, typically -1. +// +// For a read-only BIO, the default is zero (EOF). For a writable BIO, the +// default is -1 so that additional data can be written once exhausted. +OPENSSL_EXPORT int BIO_set_mem_eof_return(BIO *bio, int eof_value); + + +// File descriptor BIOs. +// +// File descriptor BIOs are wrappers around the system's |read| and |write| +// functions. If the close flag is set then then |close| is called on the +// underlying file descriptor when the BIO is freed. +// +// |BIO_reset| attempts to seek the file pointer to the start of file using +// |lseek|. + +// BIO_s_fd returns a |BIO_METHOD| for file descriptor fds. +OPENSSL_EXPORT const BIO_METHOD *BIO_s_fd(void); + +// BIO_new_fd creates a new file descriptor BIO wrapping |fd|. If |close_flag| +// is non-zero, then |fd| will be closed when the BIO is. +OPENSSL_EXPORT BIO *BIO_new_fd(int fd, int close_flag); + +// BIO_set_fd sets the file descriptor of |bio| to |fd|. If |close_flag| is +// non-zero then |fd| will be closed when |bio| is. It returns one on success +// or zero on error. +// +// This function may also be used with socket BIOs (see |BIO_s_socket| and +// |BIO_new_socket|). +OPENSSL_EXPORT int BIO_set_fd(BIO *bio, int fd, int close_flag); + +// BIO_get_fd returns the file descriptor currently in use by |bio| or -1 if +// |bio| does not wrap a file descriptor. If there is a file descriptor and +// |out_fd| is not NULL, it also sets |*out_fd| to the file descriptor. +// +// This function may also be used with socket BIOs (see |BIO_s_socket| and +// |BIO_new_socket|). +OPENSSL_EXPORT int BIO_get_fd(BIO *bio, int *out_fd); + + +// File BIOs. +// +// File BIOs are wrappers around a C |FILE| object. +// +// |BIO_flush| on a file BIO calls |fflush| on the wrapped stream. +// +// |BIO_reset| attempts to seek the file pointer to the start of file using +// |fseek|. +// +// Setting the close flag causes |fclose| to be called on the stream when the +// BIO is freed. + +// BIO_s_file returns a BIO_METHOD that wraps a |FILE|. +OPENSSL_EXPORT const BIO_METHOD *BIO_s_file(void); + +// BIO_new_file creates a file BIO by opening |filename| with the given mode. +// See the |fopen| manual page for details of the mode argument. +OPENSSL_EXPORT BIO *BIO_new_file(const char *filename, const char *mode); + +// BIO_new_fp creates a new file BIO that wraps the given |FILE|. If +// |close_flag| is |BIO_CLOSE|, then |fclose| will be called on |stream| when +// the BIO is closed. +OPENSSL_EXPORT BIO *BIO_new_fp(FILE *stream, int close_flag); + +// BIO_get_fp sets |*out_file| to the current |FILE| for |bio|. It returns one +// on success and zero otherwise. +OPENSSL_EXPORT int BIO_get_fp(BIO *bio, FILE **out_file); + +// BIO_set_fp sets the |FILE| for |bio|. If |close_flag| is |BIO_CLOSE| then +// |fclose| will be called on |file| when |bio| is closed. It returns one on +// success and zero otherwise. +OPENSSL_EXPORT int BIO_set_fp(BIO *bio, FILE *file, int close_flag); + +// BIO_read_filename opens |filename| for reading and sets the result as the +// |FILE| for |bio|. It returns one on success and zero otherwise. The |FILE| +// will be closed when |bio| is freed. +OPENSSL_EXPORT int BIO_read_filename(BIO *bio, const char *filename); + +// BIO_write_filename opens |filename| for writing and sets the result as the +// |FILE| for |bio|. It returns one on success and zero otherwise. The |FILE| +// will be closed when |bio| is freed. +OPENSSL_EXPORT int BIO_write_filename(BIO *bio, const char *filename); + +// BIO_append_filename opens |filename| for appending and sets the result as +// the |FILE| for |bio|. It returns one on success and zero otherwise. The +// |FILE| will be closed when |bio| is freed. +OPENSSL_EXPORT int BIO_append_filename(BIO *bio, const char *filename); + +// BIO_rw_filename opens |filename| for reading and writing and sets the result +// as the |FILE| for |bio|. It returns one on success and zero otherwise. The +// |FILE| will be closed when |bio| is freed. +OPENSSL_EXPORT int BIO_rw_filename(BIO *bio, const char *filename); + + +// Socket BIOs. +// +// Socket BIOs behave like file descriptor BIOs but, on Windows systems, wrap +// the system's |recv| and |send| functions instead of |read| and |write|. On +// Windows, file descriptors are provided by C runtime and are not +// interchangeable with sockets. +// +// Socket BIOs may be used with |BIO_set_fd| and |BIO_get_fd|. +// +// TODO(davidben): Add separate APIs and fix the internals to use |SOCKET|s +// around rather than rely on int casts. + +OPENSSL_EXPORT const BIO_METHOD *BIO_s_socket(void); + +// BIO_new_socket allocates and initialises a fresh BIO which will read and +// write to the socket |fd|. If |close_flag| is |BIO_CLOSE| then closing the +// BIO will close |fd|. It returns the fresh |BIO| or NULL on error. +OPENSSL_EXPORT BIO *BIO_new_socket(int fd, int close_flag); + + +// Connect BIOs. +// +// A connection BIO creates a network connection and transfers data over the +// resulting socket. + +OPENSSL_EXPORT const BIO_METHOD *BIO_s_connect(void); + +// BIO_new_connect returns a BIO that connects to the given hostname and port. +// The |host_and_optional_port| argument should be of the form +// "www.example.com" or "www.example.com:443". If the port is omitted, it must +// be provided with |BIO_set_conn_port|. +// +// It returns the new BIO on success, or NULL on error. +OPENSSL_EXPORT BIO *BIO_new_connect(const char *host_and_optional_port); + +// BIO_set_conn_hostname sets |host_and_optional_port| as the hostname and +// optional port that |bio| will connect to. If the port is omitted, it must be +// provided with |BIO_set_conn_port|. +// +// It returns one on success and zero otherwise. +OPENSSL_EXPORT int BIO_set_conn_hostname(BIO *bio, + const char *host_and_optional_port); + +// BIO_set_conn_port sets |port_str| as the port or service name that |bio| +// will connect to. It returns one on success and zero otherwise. +OPENSSL_EXPORT int BIO_set_conn_port(BIO *bio, const char *port_str); + +// BIO_set_conn_int_port sets |*port| as the port that |bio| will connect to. +// It returns one on success and zero otherwise. +OPENSSL_EXPORT int BIO_set_conn_int_port(BIO *bio, const int *port); + +// BIO_set_nbio sets whether |bio| will use non-blocking I/O operations. It +// returns one on success and zero otherwise. +OPENSSL_EXPORT int BIO_set_nbio(BIO *bio, int on); + +// BIO_do_connect connects |bio| if it has not been connected yet. It returns +// one on success and <= 0 otherwise. +OPENSSL_EXPORT int BIO_do_connect(BIO *bio); + + +// Datagram BIOs. +// +// TODO(fork): not implemented. + +#define BIO_CTRL_DGRAM_QUERY_MTU 40 // as kernel for current 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. */ + +// BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT is unsupported as it is unused by consumers +// and depends on |timeval|, which is not 2038-clean on all platforms. + +#define BIO_CTRL_DGRAM_GET_PEER 46 + +#define BIO_CTRL_DGRAM_GET_FALLBACK_MTU 47 + + +// BIO Pairs. +// +// BIO pairs provide a "loopback" like system: a pair of BIOs where data +// written to one can be read from the other and vice versa. + +// BIO_new_bio_pair sets |*out1| and |*out2| to two freshly created BIOs where +// data written to one can be read from the other and vice versa. The +// |writebuf1| argument gives the size of the buffer used in |*out1| and +// |writebuf2| for |*out2|. It returns one on success and zero on error. +OPENSSL_EXPORT int BIO_new_bio_pair(BIO **out1, size_t writebuf1, BIO **out2, + size_t writebuf2); + +// BIO_ctrl_get_read_request returns the number of bytes that the other side of +// |bio| tried (unsuccessfully) to read. +OPENSSL_EXPORT size_t BIO_ctrl_get_read_request(BIO *bio); + +// BIO_ctrl_get_write_guarantee returns the number of bytes that |bio| (which +// must have been returned by |BIO_new_bio_pair|) will accept on the next +// |BIO_write| call. +OPENSSL_EXPORT size_t BIO_ctrl_get_write_guarantee(BIO *bio); + +// BIO_shutdown_wr marks |bio| as closed, from the point of view of the other +// side of the pair. Future |BIO_write| calls on |bio| will fail. It returns +// one on success and zero otherwise. +OPENSSL_EXPORT int BIO_shutdown_wr(BIO *bio); + + +// Custom BIOs. +// +// Consumers can create custom |BIO|s by filling in a |BIO_METHOD| and using +// low-level control functions to set state. + +// BIO_get_new_index returns a new "type" value for a custom |BIO|. +OPENSSL_EXPORT int BIO_get_new_index(void); + +// BIO_meth_new returns a newly-allocated |BIO_METHOD| or NULL on allocation +// error. The |type| specifies the type that will be returned by +// |BIO_method_type|. If this is unnecessary, this value may be zero. The |name| +// parameter is vestigial and may be NULL. +// +// Use the |BIO_meth_set_*| functions below to initialize the |BIO_METHOD|. The +// function implementations may use |BIO_set_data| and |BIO_get_data| to add +// method-specific state to associated |BIO|s. Additionally, |BIO_set_init| must +// be called after an associated |BIO| is fully initialized. State set via +// |BIO_set_data| may be released by configuring a destructor with +// |BIO_meth_set_destroy|. +OPENSSL_EXPORT BIO_METHOD *BIO_meth_new(int type, const char *name); + +// BIO_meth_free releases memory associated with |method|. +OPENSSL_EXPORT void BIO_meth_free(BIO_METHOD *method); + +// BIO_meth_set_create sets a function to be called on |BIO_new| for |method| +// and returns one. The function should return one on success and zero on +// error. +OPENSSL_EXPORT int BIO_meth_set_create(BIO_METHOD *method, + int (*create)(BIO *)); + +// BIO_meth_set_destroy sets a function to release data associated with a |BIO| +// and returns one. The function's return value is ignored. +OPENSSL_EXPORT int BIO_meth_set_destroy(BIO_METHOD *method, + int (*destroy)(BIO *)); + +// BIO_meth_set_write sets the implementation of |BIO_write| for |method| and +// returns one. |BIO_METHOD|s which implement |BIO_write| should also implement +// |BIO_CTRL_FLUSH|. (See |BIO_meth_set_ctrl|.) +OPENSSL_EXPORT int BIO_meth_set_write(BIO_METHOD *method, + int (*write)(BIO *, const char *, int)); + +// BIO_meth_set_read sets the implementation of |BIO_read| for |method| and +// returns one. +OPENSSL_EXPORT int BIO_meth_set_read(BIO_METHOD *method, + int (*read)(BIO *, char *, int)); + +// BIO_meth_set_gets sets the implementation of |BIO_gets| for |method| and +// returns one. +OPENSSL_EXPORT int BIO_meth_set_gets(BIO_METHOD *method, + int (*gets)(BIO *, char *, int)); + +// BIO_meth_set_ctrl sets the implementation of |BIO_ctrl| for |method| and +// returns one. +OPENSSL_EXPORT int BIO_meth_set_ctrl(BIO_METHOD *method, + long (*ctrl)(BIO *, int, long, void *)); + +// BIO_set_data sets custom data on |bio|. It may be retried with +// |BIO_get_data|. +OPENSSL_EXPORT void BIO_set_data(BIO *bio, void *ptr); + +// BIO_get_data returns custom data on |bio| set by |BIO_get_data|. +OPENSSL_EXPORT void *BIO_get_data(BIO *bio); + +// BIO_set_init sets whether |bio| has been fully initialized. Until fully +// initialized, |BIO_read| and |BIO_write| will fail. +OPENSSL_EXPORT void BIO_set_init(BIO *bio, int init); + +// BIO_get_init returns whether |bio| has been fully initialized. +OPENSSL_EXPORT int BIO_get_init(BIO *bio); + +// These are values of the |cmd| argument 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 +#define BIO_CTRL_POP 7 +#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_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 + +// BIO_CTRL_DUP is never used, but exists to allow code to compile more +// easily. +#define BIO_CTRL_DUP 12 + + +// Deprecated functions. + +// BIO_f_base64 returns a filter |BIO| that base64-encodes data written into +// it, and decodes data read from it. |BIO_gets| is not supported. Call +// |BIO_flush| when done writing, to signal that no more data are to be +// encoded. The flag |BIO_FLAGS_BASE64_NO_NL| may be set to encode all the data +// on one line. +OPENSSL_EXPORT const BIO_METHOD *BIO_f_base64(void); + +OPENSSL_EXPORT void BIO_set_retry_special(BIO *bio); + +// BIO_set_write_buffer_size returns zero. +OPENSSL_EXPORT int BIO_set_write_buffer_size(BIO *bio, int buffer_size); + +// BIO_set_shutdown sets a method-specific "shutdown" bit on |bio|. +OPENSSL_EXPORT void BIO_set_shutdown(BIO *bio, int shutdown); + +// BIO_get_shutdown returns the method-specific "shutdown" bit. +OPENSSL_EXPORT int BIO_get_shutdown(BIO *bio); + +// BIO_meth_set_puts returns one. |BIO_puts| is implemented with |BIO_write| in +// BoringSSL. +OPENSSL_EXPORT int BIO_meth_set_puts(BIO_METHOD *method, + int (*puts)(BIO *, const char *)); + + +// Private functions + +#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 +#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 + +// 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) +#define BIO_TYPE_ASN1 (22 | 0x0200) // filter +#define BIO_TYPE_COMP (23 | 0x0200) // filter + +// |BIO_TYPE_DESCRIPTOR| denotes that the |BIO| responds to the |BIO_C_SET_FD| +// (|BIO_set_fd|) and |BIO_C_GET_FD| (|BIO_get_fd|) control hooks. +#define BIO_TYPE_DESCRIPTOR 0x0100 // socket, fd, connect or accept +#define BIO_TYPE_FILTER 0x0200 +#define BIO_TYPE_SOURCE_SINK 0x0400 + +// BIO_TYPE_START is the first user-allocated |BIO| type. No pre-defined type, +// flag bits aside, may exceed this value. +#define BIO_TYPE_START 128 + +struct bio_method_st { + int type; + const char *name; + int (*bwrite)(BIO *, const char *, int); + int (*bread)(BIO *, char *, int); + // TODO(fork): remove bputs. + 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); +}; + +struct bio_st { + const BIO_METHOD *method; + + // init is non-zero if this |BIO| has been initialised. + int init; + // shutdown is often used by specific |BIO_METHOD|s to determine whether + // they own some underlying resource. This flag can often by controlled by + // |BIO_set_close|. For example, whether an fd BIO closes the underlying fd + // when it, itself, is closed. + int shutdown; + int flags; + int retry_reason; + // num is a BIO-specific value. For example, in fd BIOs it's used to store a + // file descriptor. + int num; + CRYPTO_refcount_t references; + void *ptr; + // next_bio points to the next |BIO| in a chain. This |BIO| owns a reference + // to |next_bio|. + BIO *next_bio; // used by filter BIOs + size_t num_read, num_write; +}; + +#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_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_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 + + +#if defined(__cplusplus) +} // extern C + +extern "C++" { + +namespace bssl { + +BORINGSSL_MAKE_DELETER(BIO, BIO_free) + +} // namespace bssl + +} // extern C++ + +#endif + +#define BIO_R_BAD_FOPEN_MODE 100 +#define BIO_R_BROKEN_PIPE 101 +#define BIO_R_CONNECT_ERROR 102 +#define BIO_R_ERROR_SETTING_NBIO 103 +#define BIO_R_INVALID_ARGUMENT 104 +#define BIO_R_IN_USE 105 +#define BIO_R_KEEPALIVE 106 +#define BIO_R_NBIO_CONNECT_ERROR 107 +#define BIO_R_NO_HOSTNAME_SPECIFIED 108 +#define BIO_R_NO_PORT_SPECIFIED 109 +#define BIO_R_NO_SUCH_FILE 110 +#define BIO_R_NULL_PARAMETER 111 +#define BIO_R_SYS_LIB 112 +#define BIO_R_UNABLE_TO_CREATE_SOCKET 113 +#define BIO_R_UNINITIALIZED 114 +#define BIO_R_UNSUPPORTED_METHOD 115 +#define BIO_R_WRITE_TO_READ_ONLY_BIO 116 + +#endif // OPENSSL_HEADER_BIO_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/blowfish.h b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/blowfish.h new file mode 100644 index 0000000..7345600 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/blowfish.h @@ -0,0 +1,93 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 OPENSSL_HEADER_BLOWFISH_H +#define OPENSSL_HEADER_BLOWFISH_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +#define BF_ENCRYPT 1 +#define BF_DECRYPT 0 + +#define BF_ROUNDS 16 +#define BF_BLOCK 8 + +typedef struct bf_key_st { + uint32_t P[BF_ROUNDS + 2]; + uint32_t S[4 * 256]; +} BF_KEY; + +OPENSSL_EXPORT void BF_set_key(BF_KEY *key, size_t len, const uint8_t *data); +OPENSSL_EXPORT void BF_encrypt(uint32_t *data, const BF_KEY *key); +OPENSSL_EXPORT void BF_decrypt(uint32_t *data, const BF_KEY *key); + +OPENSSL_EXPORT void BF_ecb_encrypt(const uint8_t *in, uint8_t *out, + const BF_KEY *key, int enc); +OPENSSL_EXPORT void BF_cbc_encrypt(const uint8_t *in, uint8_t *out, long length, + const BF_KEY *schedule, uint8_t *ivec, + int enc); + + +#ifdef __cplusplus +} +#endif + +#endif // OPENSSL_HEADER_BLOWFISH_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/blowfish.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/blowfish.h.grpc_back new file mode 100644 index 0000000..ecf9d45 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/blowfish.h.grpc_back @@ -0,0 +1,93 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 OPENSSL_HEADER_BLOWFISH_H +#define OPENSSL_HEADER_BLOWFISH_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +#define BF_ENCRYPT 1 +#define BF_DECRYPT 0 + +#define BF_ROUNDS 16 +#define BF_BLOCK 8 + +typedef struct bf_key_st { + uint32_t P[BF_ROUNDS + 2]; + uint32_t S[4 * 256]; +} BF_KEY; + +OPENSSL_EXPORT void BF_set_key(BF_KEY *key, size_t len, const uint8_t *data); +OPENSSL_EXPORT void BF_encrypt(uint32_t *data, const BF_KEY *key); +OPENSSL_EXPORT void BF_decrypt(uint32_t *data, const BF_KEY *key); + +OPENSSL_EXPORT void BF_ecb_encrypt(const uint8_t *in, uint8_t *out, + const BF_KEY *key, int enc); +OPENSSL_EXPORT void BF_cbc_encrypt(const uint8_t *in, uint8_t *out, long length, + const BF_KEY *schedule, uint8_t *ivec, + int enc); + + +#ifdef __cplusplus +} +#endif + +#endif // OPENSSL_HEADER_BLOWFISH_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/bn.h b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/bn.h new file mode 100644 index 0000000..7c0b5b5 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/bn.h @@ -0,0 +1,1019 @@ +/* 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-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 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 OPENSSL_HEADER_BN_H +#define OPENSSL_HEADER_BN_H + +#include +#include + +#include // for PRIu64 and friends +#include // for FILE* + +#if defined(__cplusplus) +extern "C" { +#endif + + +// BN provides support for working with arbitrary sized integers. For example, +// although the largest integer supported by the compiler might be 64 bits, BN +// will allow you to work with numbers until you run out of memory. + + +// BN_ULONG is the native word size when working with big integers. +// +// Note: on some platforms, inttypes.h does not define print format macros in +// C++ unless |__STDC_FORMAT_MACROS| defined. As this is a public header, bn.h +// does not define |__STDC_FORMAT_MACROS| itself. C++ source files which use the +// FMT macros must define it externally. +#if defined(OPENSSL_64_BIT) +#define BN_ULONG uint64_t +#define BN_BITS2 64 +#define BN_DEC_FMT1 "%" PRIu64 +#define BN_DEC_FMT2 "%019" PRIu64 +#define BN_HEX_FMT1 "%" PRIx64 +#define BN_HEX_FMT2 "%016" PRIx64 +#elif defined(OPENSSL_32_BIT) +#define BN_ULONG uint32_t +#define BN_BITS2 32 +#define BN_DEC_FMT1 "%" PRIu32 +#define BN_DEC_FMT2 "%09" PRIu32 +#define BN_HEX_FMT1 "%" PRIx32 +#define BN_HEX_FMT2 "%08" PRIx64 +#else +#error "Must define either OPENSSL_32_BIT or OPENSSL_64_BIT" +#endif + + +// Allocation and freeing. + +// BN_new creates a new, allocated BIGNUM and initialises it. +OPENSSL_EXPORT BIGNUM *BN_new(void); + +// BN_init initialises a stack allocated |BIGNUM|. +OPENSSL_EXPORT void BN_init(BIGNUM *bn); + +// BN_free frees the data referenced by |bn| and, if |bn| was originally +// allocated on the heap, frees |bn| also. +OPENSSL_EXPORT void BN_free(BIGNUM *bn); + +// BN_clear_free erases and frees the data referenced by |bn| and, if |bn| was +// originally allocated on the heap, frees |bn| also. +OPENSSL_EXPORT void BN_clear_free(BIGNUM *bn); + +// BN_dup allocates a new BIGNUM and sets it equal to |src|. It returns the +// allocated BIGNUM on success or NULL otherwise. +OPENSSL_EXPORT BIGNUM *BN_dup(const BIGNUM *src); + +// BN_copy sets |dest| equal to |src| and returns |dest| or NULL on allocation +// failure. +OPENSSL_EXPORT BIGNUM *BN_copy(BIGNUM *dest, const BIGNUM *src); + +// BN_clear sets |bn| to zero and erases the old data. +OPENSSL_EXPORT void BN_clear(BIGNUM *bn); + +// BN_value_one returns a static BIGNUM with value 1. +OPENSSL_EXPORT const BIGNUM *BN_value_one(void); + + +// Basic functions. + +// BN_num_bits returns the minimum number of bits needed to represent the +// absolute value of |bn|. +OPENSSL_EXPORT unsigned BN_num_bits(const BIGNUM *bn); + +// BN_num_bytes returns the minimum number of bytes needed to represent the +// absolute value of |bn|. +OPENSSL_EXPORT unsigned BN_num_bytes(const BIGNUM *bn); + +// BN_zero sets |bn| to zero. +OPENSSL_EXPORT void BN_zero(BIGNUM *bn); + +// BN_one sets |bn| to one. It returns one on success or zero on allocation +// failure. +OPENSSL_EXPORT int BN_one(BIGNUM *bn); + +// BN_set_word sets |bn| to |value|. It returns one on success or zero on +// allocation failure. +OPENSSL_EXPORT int BN_set_word(BIGNUM *bn, BN_ULONG value); + +// BN_set_u64 sets |bn| to |value|. It returns one on success or zero on +// allocation failure. +OPENSSL_EXPORT int BN_set_u64(BIGNUM *bn, uint64_t value); + +// BN_set_negative sets the sign of |bn|. +OPENSSL_EXPORT void BN_set_negative(BIGNUM *bn, int sign); + +// BN_is_negative returns one if |bn| is negative and zero otherwise. +OPENSSL_EXPORT int BN_is_negative(const BIGNUM *bn); + + +// Conversion functions. + +// BN_bin2bn sets |*ret| to the value of |len| bytes from |in|, interpreted as +// a big-endian number, and returns |ret|. If |ret| is NULL then a fresh +// |BIGNUM| is allocated and returned. It returns NULL on allocation +// failure. +OPENSSL_EXPORT BIGNUM *BN_bin2bn(const uint8_t *in, size_t len, BIGNUM *ret); + +// BN_bn2bin serialises the absolute value of |in| to |out| as a big-endian +// integer, which must have |BN_num_bytes| of space available. It returns the +// number of bytes written. Note this function leaks the magnitude of |in|. If +// |in| is secret, use |BN_bn2bin_padded| instead. +OPENSSL_EXPORT size_t BN_bn2bin(const BIGNUM *in, uint8_t *out); + +// BN_le2bn sets |*ret| to the value of |len| bytes from |in|, interpreted as +// a little-endian number, and returns |ret|. If |ret| is NULL then a fresh +// |BIGNUM| is allocated and returned. It returns NULL on allocation +// failure. +OPENSSL_EXPORT BIGNUM *BN_le2bn(const uint8_t *in, size_t len, BIGNUM *ret); + +// BN_bn2le_padded serialises the absolute value of |in| to |out| as a +// little-endian integer, which must have |len| of space available, padding +// out the remainder of out with zeros. If |len| is smaller than |BN_num_bytes|, +// the function fails and returns 0. Otherwise, it returns 1. +OPENSSL_EXPORT int BN_bn2le_padded(uint8_t *out, size_t len, const BIGNUM *in); + +// BN_bn2bin_padded serialises the absolute value of |in| to |out| as a +// big-endian integer. The integer is padded with leading zeros up to size +// |len|. If |len| is smaller than |BN_num_bytes|, the function fails and +// returns 0. Otherwise, it returns 1. +OPENSSL_EXPORT int BN_bn2bin_padded(uint8_t *out, size_t len, const BIGNUM *in); + +// BN_bn2cbb_padded behaves like |BN_bn2bin_padded| but writes to a |CBB|. +OPENSSL_EXPORT int BN_bn2cbb_padded(CBB *out, size_t len, const BIGNUM *in); + +// BN_bn2hex returns an allocated string that contains a NUL-terminated, hex +// representation of |bn|. If |bn| is negative, the first char in the resulting +// string will be '-'. Returns NULL on allocation failure. +OPENSSL_EXPORT char *BN_bn2hex(const BIGNUM *bn); + +// BN_hex2bn parses the leading hex number from |in|, which may be proceeded by +// a '-' to indicate a negative number and may contain trailing, non-hex data. +// If |outp| is not NULL, it constructs a BIGNUM equal to the hex number and +// stores it in |*outp|. If |*outp| is NULL then it allocates a new BIGNUM and +// updates |*outp|. It returns the number of bytes of |in| processed or zero on +// error. +OPENSSL_EXPORT int BN_hex2bn(BIGNUM **outp, const char *in); + +// BN_bn2dec returns an allocated string that contains a NUL-terminated, +// decimal representation of |bn|. If |bn| is negative, the first char in the +// resulting string will be '-'. Returns NULL on allocation failure. +OPENSSL_EXPORT char *BN_bn2dec(const BIGNUM *a); + +// BN_dec2bn parses the leading decimal number from |in|, which may be +// proceeded by a '-' to indicate a negative number and may contain trailing, +// non-decimal data. If |outp| is not NULL, it constructs a BIGNUM equal to the +// decimal number and stores it in |*outp|. If |*outp| is NULL then it +// allocates a new BIGNUM and updates |*outp|. It returns the number of bytes +// of |in| processed or zero on error. +OPENSSL_EXPORT int BN_dec2bn(BIGNUM **outp, const char *in); + +// BN_asc2bn acts like |BN_dec2bn| or |BN_hex2bn| depending on whether |in| +// begins with "0X" or "0x" (indicating hex) or not (indicating decimal). A +// leading '-' is still permitted and comes before the optional 0X/0x. It +// returns one on success or zero on error. +OPENSSL_EXPORT int BN_asc2bn(BIGNUM **outp, const char *in); + +// BN_print writes a hex encoding of |a| to |bio|. It returns one on success +// and zero on error. +OPENSSL_EXPORT int BN_print(BIO *bio, const BIGNUM *a); + +// BN_print_fp acts like |BIO_print|, but wraps |fp| in a |BIO| first. +OPENSSL_EXPORT int BN_print_fp(FILE *fp, const BIGNUM *a); + +// BN_get_word returns the absolute value of |bn| as a single word. If |bn| is +// too large to be represented as a single word, the maximum possible value +// will be returned. +OPENSSL_EXPORT BN_ULONG BN_get_word(const BIGNUM *bn); + +// BN_get_u64 sets |*out| to the absolute value of |bn| as a |uint64_t| and +// returns one. If |bn| is too large to be represented as a |uint64_t|, it +// returns zero. +OPENSSL_EXPORT int BN_get_u64(const BIGNUM *bn, uint64_t *out); + + +// ASN.1 functions. + +// BN_parse_asn1_unsigned parses a non-negative DER INTEGER from |cbs| writes +// the result to |ret|. It returns one on success and zero on failure. +OPENSSL_EXPORT int BN_parse_asn1_unsigned(CBS *cbs, BIGNUM *ret); + +// BN_marshal_asn1 marshals |bn| as a non-negative DER INTEGER and appends the +// result to |cbb|. It returns one on success and zero on failure. +OPENSSL_EXPORT int BN_marshal_asn1(CBB *cbb, const BIGNUM *bn); + + +// BIGNUM pools. +// +// Certain BIGNUM operations need to use many temporary variables and +// allocating and freeing them can be quite slow. Thus such operations typically +// take a |BN_CTX| parameter, which contains a pool of |BIGNUMs|. The |ctx| +// argument to a public function may be NULL, in which case a local |BN_CTX| +// will be created just for the lifetime of that call. +// +// A function must call |BN_CTX_start| first. Then, |BN_CTX_get| may be called +// repeatedly to obtain temporary |BIGNUM|s. All |BN_CTX_get| calls must be made +// before calling any other functions that use the |ctx| as an argument. +// +// Finally, |BN_CTX_end| must be called before returning from the function. +// When |BN_CTX_end| is called, the |BIGNUM| pointers obtained from +// |BN_CTX_get| become invalid. + +// BN_CTX_new returns a new, empty BN_CTX or NULL on allocation failure. +OPENSSL_EXPORT BN_CTX *BN_CTX_new(void); + +// BN_CTX_free frees all BIGNUMs contained in |ctx| and then frees |ctx| +// itself. +OPENSSL_EXPORT void BN_CTX_free(BN_CTX *ctx); + +// BN_CTX_start "pushes" a new entry onto the |ctx| stack and allows future +// calls to |BN_CTX_get|. +OPENSSL_EXPORT void BN_CTX_start(BN_CTX *ctx); + +// BN_CTX_get returns a new |BIGNUM|, or NULL on allocation failure. Once +// |BN_CTX_get| has returned NULL, all future calls will also return NULL until +// |BN_CTX_end| is called. +OPENSSL_EXPORT BIGNUM *BN_CTX_get(BN_CTX *ctx); + +// BN_CTX_end invalidates all |BIGNUM|s returned from |BN_CTX_get| since the +// matching |BN_CTX_start| call. +OPENSSL_EXPORT void BN_CTX_end(BN_CTX *ctx); + + +// Simple arithmetic + +// BN_add sets |r| = |a| + |b|, where |r| may be the same pointer as either |a| +// or |b|. It returns one on success and zero on allocation failure. +OPENSSL_EXPORT int BN_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); + +// BN_uadd sets |r| = |a| + |b|, where |a| and |b| are non-negative and |r| may +// be the same pointer as either |a| or |b|. It returns one on success and zero +// on allocation failure. +OPENSSL_EXPORT int BN_uadd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); + +// BN_add_word adds |w| to |a|. It returns one on success and zero otherwise. +OPENSSL_EXPORT int BN_add_word(BIGNUM *a, BN_ULONG w); + +// BN_sub sets |r| = |a| - |b|, where |r| may be the same pointer as either |a| +// or |b|. It returns one on success and zero on allocation failure. +OPENSSL_EXPORT int BN_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); + +// BN_usub sets |r| = |a| - |b|, where |a| and |b| are non-negative integers, +// |b| < |a| and |r| may be the same pointer as either |a| or |b|. It returns +// one on success and zero on allocation failure. +OPENSSL_EXPORT int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); + +// BN_sub_word subtracts |w| from |a|. It returns one on success and zero on +// allocation failure. +OPENSSL_EXPORT int BN_sub_word(BIGNUM *a, BN_ULONG w); + +// BN_mul sets |r| = |a| * |b|, where |r| may be the same pointer as |a| or +// |b|. Returns one on success and zero otherwise. +OPENSSL_EXPORT int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + BN_CTX *ctx); + +// BN_mul_word sets |bn| = |bn| * |w|. It returns one on success or zero on +// allocation failure. +OPENSSL_EXPORT int BN_mul_word(BIGNUM *bn, BN_ULONG w); + +// BN_sqr sets |r| = |a|^2 (i.e. squares), where |r| may be the same pointer as +// |a|. Returns one on success and zero otherwise. This is more efficient than +// BN_mul(r, a, a, ctx). +OPENSSL_EXPORT int BN_sqr(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx); + +// BN_div divides |numerator| by |divisor| and places the result in |quotient| +// and the remainder in |rem|. Either of |quotient| or |rem| may be NULL, in +// which case the respective value is not returned. The result is rounded +// towards zero; thus if |numerator| is negative, the remainder will be zero or +// negative. It returns one on success or zero on error. +OPENSSL_EXPORT int BN_div(BIGNUM *quotient, BIGNUM *rem, + const BIGNUM *numerator, const BIGNUM *divisor, + BN_CTX *ctx); + +// BN_div_word sets |numerator| = |numerator|/|divisor| and returns the +// remainder or (BN_ULONG)-1 on error. +OPENSSL_EXPORT BN_ULONG BN_div_word(BIGNUM *numerator, BN_ULONG divisor); + +// BN_sqrt sets |*out_sqrt| (which may be the same |BIGNUM| as |in|) to the +// square root of |in|, using |ctx|. It returns one on success or zero on +// error. Negative numbers and non-square numbers will result in an error with +// appropriate errors on the error queue. +OPENSSL_EXPORT int BN_sqrt(BIGNUM *out_sqrt, const BIGNUM *in, BN_CTX *ctx); + + +// Comparison functions + +// BN_cmp returns a value less than, equal to or greater than zero if |a| is +// less than, equal to or greater than |b|, respectively. +OPENSSL_EXPORT int BN_cmp(const BIGNUM *a, const BIGNUM *b); + +// BN_cmp_word is like |BN_cmp| except it takes its second argument as a +// |BN_ULONG| instead of a |BIGNUM|. +OPENSSL_EXPORT int BN_cmp_word(const BIGNUM *a, BN_ULONG b); + +// BN_ucmp returns a value less than, equal to or greater than zero if the +// absolute value of |a| is less than, equal to or greater than the absolute +// value of |b|, respectively. +OPENSSL_EXPORT int BN_ucmp(const BIGNUM *a, const BIGNUM *b); + +// BN_equal_consttime returns one if |a| is equal to |b|, and zero otherwise. +// It takes an amount of time dependent on the sizes of |a| and |b|, but +// independent of the contents (including the signs) of |a| and |b|. +OPENSSL_EXPORT int BN_equal_consttime(const BIGNUM *a, const BIGNUM *b); + +// BN_abs_is_word returns one if the absolute value of |bn| equals |w| and zero +// otherwise. +OPENSSL_EXPORT int BN_abs_is_word(const BIGNUM *bn, BN_ULONG w); + +// BN_is_zero returns one if |bn| is zero and zero otherwise. +OPENSSL_EXPORT int BN_is_zero(const BIGNUM *bn); + +// BN_is_one returns one if |bn| equals one and zero otherwise. +OPENSSL_EXPORT int BN_is_one(const BIGNUM *bn); + +// BN_is_word returns one if |bn| is exactly |w| and zero otherwise. +OPENSSL_EXPORT int BN_is_word(const BIGNUM *bn, BN_ULONG w); + +// BN_is_odd returns one if |bn| is odd and zero otherwise. +OPENSSL_EXPORT int BN_is_odd(const BIGNUM *bn); + +// BN_is_pow2 returns 1 if |a| is a power of two, and 0 otherwise. +OPENSSL_EXPORT int BN_is_pow2(const BIGNUM *a); + + +// Bitwise operations. + +// BN_lshift sets |r| equal to |a| << n. The |a| and |r| arguments may be the +// same |BIGNUM|. It returns one on success and zero on allocation failure. +OPENSSL_EXPORT int BN_lshift(BIGNUM *r, const BIGNUM *a, int n); + +// BN_lshift1 sets |r| equal to |a| << 1, where |r| and |a| may be the same +// pointer. It returns one on success and zero on allocation failure. +OPENSSL_EXPORT int BN_lshift1(BIGNUM *r, const BIGNUM *a); + +// BN_rshift sets |r| equal to |a| >> n, where |r| and |a| may be the same +// pointer. It returns one on success and zero on allocation failure. +OPENSSL_EXPORT int BN_rshift(BIGNUM *r, const BIGNUM *a, int n); + +// BN_rshift1 sets |r| equal to |a| >> 1, where |r| and |a| may be the same +// pointer. It returns one on success and zero on allocation failure. +OPENSSL_EXPORT int BN_rshift1(BIGNUM *r, const BIGNUM *a); + +// BN_set_bit sets the |n|th, least-significant bit in |a|. For example, if |a| +// is 2 then setting bit zero will make it 3. It returns one on success or zero +// on allocation failure. +OPENSSL_EXPORT int BN_set_bit(BIGNUM *a, int n); + +// BN_clear_bit clears the |n|th, least-significant bit in |a|. For example, if +// |a| is 3, clearing bit zero will make it two. It returns one on success or +// zero on allocation failure. +OPENSSL_EXPORT int BN_clear_bit(BIGNUM *a, int n); + +// BN_is_bit_set returns one if the |n|th least-significant bit in |a| exists +// and is set. Otherwise, it returns zero. +OPENSSL_EXPORT int BN_is_bit_set(const BIGNUM *a, int n); + +// BN_mask_bits truncates |a| so that it is only |n| bits long. It returns one +// on success or zero if |n| is negative. +// +// This differs from OpenSSL which additionally returns zero if |a|'s word +// length is less than or equal to |n|, rounded down to a number of words. Note +// word size is platform-dependent, so this behavior is also difficult to rely +// on in OpenSSL and not very useful. +OPENSSL_EXPORT int BN_mask_bits(BIGNUM *a, int n); + +// BN_count_low_zero_bits returns the number of low-order zero bits in |bn|, or +// the number of factors of two which divide it. It returns zero if |bn| is +// zero. +OPENSSL_EXPORT int BN_count_low_zero_bits(const BIGNUM *bn); + + +// Modulo arithmetic. + +// BN_mod_word returns |a| mod |w| or (BN_ULONG)-1 on error. +OPENSSL_EXPORT BN_ULONG BN_mod_word(const BIGNUM *a, BN_ULONG w); + +// BN_mod_pow2 sets |r| = |a| mod 2^|e|. It returns 1 on success and +// 0 on error. +OPENSSL_EXPORT int BN_mod_pow2(BIGNUM *r, const BIGNUM *a, size_t e); + +// BN_nnmod_pow2 sets |r| = |a| mod 2^|e| where |r| is always positive. +// It returns 1 on success and 0 on error. +OPENSSL_EXPORT int BN_nnmod_pow2(BIGNUM *r, const BIGNUM *a, size_t e); + +// BN_mod is a helper macro that calls |BN_div| and discards the quotient. +#define BN_mod(rem, numerator, divisor, ctx) \ + BN_div(NULL, (rem), (numerator), (divisor), (ctx)) + +// BN_nnmod is a non-negative modulo function. It acts like |BN_mod|, but 0 <= +// |rem| < |divisor| is always true. It returns one on success and zero on +// error. +OPENSSL_EXPORT int BN_nnmod(BIGNUM *rem, const BIGNUM *numerator, + const BIGNUM *divisor, BN_CTX *ctx); + +// BN_mod_add sets |r| = |a| + |b| mod |m|. It returns one on success and zero +// on error. +OPENSSL_EXPORT int BN_mod_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const BIGNUM *m, BN_CTX *ctx); + +// BN_mod_add_quick acts like |BN_mod_add| but requires that |a| and |b| be +// non-negative and less than |m|. +OPENSSL_EXPORT int BN_mod_add_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const BIGNUM *m); + +// BN_mod_sub sets |r| = |a| - |b| mod |m|. It returns one on success and zero +// on error. +OPENSSL_EXPORT int BN_mod_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const BIGNUM *m, BN_CTX *ctx); + +// BN_mod_sub_quick acts like |BN_mod_sub| but requires that |a| and |b| be +// non-negative and less than |m|. +OPENSSL_EXPORT int BN_mod_sub_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const BIGNUM *m); + +// BN_mod_mul sets |r| = |a|*|b| mod |m|. It returns one on success and zero +// on error. +OPENSSL_EXPORT int BN_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const BIGNUM *m, BN_CTX *ctx); + +// BN_mod_sqr sets |r| = |a|^2 mod |m|. It returns one on success and zero +// on error. +OPENSSL_EXPORT int BN_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, + BN_CTX *ctx); + +// BN_mod_lshift sets |r| = (|a| << n) mod |m|, where |r| and |a| may be the +// same pointer. It returns one on success and zero on error. +OPENSSL_EXPORT int BN_mod_lshift(BIGNUM *r, const BIGNUM *a, int n, + const BIGNUM *m, BN_CTX *ctx); + +// BN_mod_lshift_quick acts like |BN_mod_lshift| but requires that |a| be +// non-negative and less than |m|. +OPENSSL_EXPORT int BN_mod_lshift_quick(BIGNUM *r, const BIGNUM *a, int n, + const BIGNUM *m); + +// BN_mod_lshift1 sets |r| = (|a| << 1) mod |m|, where |r| and |a| may be the +// same pointer. It returns one on success and zero on error. +OPENSSL_EXPORT int BN_mod_lshift1(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, + BN_CTX *ctx); + +// BN_mod_lshift1_quick acts like |BN_mod_lshift1| but requires that |a| be +// non-negative and less than |m|. +OPENSSL_EXPORT int BN_mod_lshift1_quick(BIGNUM *r, const BIGNUM *a, + const BIGNUM *m); + +// BN_mod_sqrt returns a newly-allocated |BIGNUM|, r, such that +// r^2 == a (mod p). |p| must be a prime. It returns NULL on error or if |a| is +// not a square mod |p|. In the latter case, it will add |BN_R_NOT_A_SQUARE| to +// the error queue. +OPENSSL_EXPORT BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, + BN_CTX *ctx); + + +// Random and prime number generation. + +// The following are values for the |top| parameter of |BN_rand|. +#define BN_RAND_TOP_ANY (-1) +#define BN_RAND_TOP_ONE 0 +#define BN_RAND_TOP_TWO 1 + +// The following are values for the |bottom| parameter of |BN_rand|. +#define BN_RAND_BOTTOM_ANY 0 +#define BN_RAND_BOTTOM_ODD 1 + +// BN_rand sets |rnd| to a random number of length |bits|. It returns one on +// success and zero otherwise. +// +// |top| must be one of the |BN_RAND_TOP_*| values. If |BN_RAND_TOP_ONE|, the +// most-significant bit, if any, will be set. If |BN_RAND_TOP_TWO|, the two +// most significant bits, if any, will be set. If |BN_RAND_TOP_ANY|, no extra +// action will be taken and |BN_num_bits(rnd)| may not equal |bits| if the most +// significant bits randomly ended up as zeros. +// +// |bottom| must be one of the |BN_RAND_BOTTOM_*| values. If +// |BN_RAND_BOTTOM_ODD|, the least-significant bit, if any, will be set. If +// |BN_RAND_BOTTOM_ANY|, no extra action will be taken. +OPENSSL_EXPORT int BN_rand(BIGNUM *rnd, int bits, int top, int bottom); + +// BN_pseudo_rand is an alias for |BN_rand|. +OPENSSL_EXPORT int BN_pseudo_rand(BIGNUM *rnd, int bits, int top, int bottom); + +// BN_rand_range is equivalent to |BN_rand_range_ex| with |min_inclusive| set +// to zero and |max_exclusive| set to |range|. +OPENSSL_EXPORT int BN_rand_range(BIGNUM *rnd, const BIGNUM *range); + +// BN_rand_range_ex sets |rnd| to a random value in +// [min_inclusive..max_exclusive). It returns one on success and zero +// otherwise. +OPENSSL_EXPORT int BN_rand_range_ex(BIGNUM *r, BN_ULONG min_inclusive, + const BIGNUM *max_exclusive); + +// BN_pseudo_rand_range is an alias for BN_rand_range. +OPENSSL_EXPORT int BN_pseudo_rand_range(BIGNUM *rnd, const BIGNUM *range); + +// BN_GENCB holds a callback function that is used by generation functions that +// can take a very long time to complete. Use |BN_GENCB_set| to initialise a +// |BN_GENCB| structure. +// +// The callback receives the address of that |BN_GENCB| structure as its last +// argument and the user is free to put an arbitrary pointer in |arg|. The other +// arguments are set as follows: +// event=BN_GENCB_GENERATED, n=i: after generating the i'th possible prime +// number. +// event=BN_GENCB_PRIME_TEST, n=-1: when finished trial division primality +// checks. +// event=BN_GENCB_PRIME_TEST, n=i: when the i'th primality test has finished. +// +// The callback can return zero to abort the generation progress or one to +// allow it to continue. +// +// When other code needs to call a BN generation function it will often take a +// BN_GENCB argument and may call the function with other argument values. +#define BN_GENCB_GENERATED 0 +#define BN_GENCB_PRIME_TEST 1 + +struct bn_gencb_st { + void *arg; // callback-specific data + int (*callback)(int event, int n, struct bn_gencb_st *); +}; + +// BN_GENCB_set configures |callback| to call |f| and sets |callout->arg| to +// |arg|. +OPENSSL_EXPORT void BN_GENCB_set(BN_GENCB *callback, + int (*f)(int event, int n, + struct bn_gencb_st *), + void *arg); + +// BN_GENCB_call calls |callback|, if not NULL, and returns the return value of +// the callback, or 1 if |callback| is NULL. +OPENSSL_EXPORT int BN_GENCB_call(BN_GENCB *callback, int event, int n); + +// BN_generate_prime_ex sets |ret| to a prime number of |bits| length. If safe +// is non-zero then the prime will be such that (ret-1)/2 is also a prime. +// (This is needed for Diffie-Hellman groups to ensure that the only subgroups +// are of size 2 and (p-1)/2.). +// +// If |add| is not NULL, the prime will fulfill the condition |ret| % |add| == +// |rem| in order to suit a given generator. (If |rem| is NULL then |ret| % +// |add| == 1.) +// +// If |cb| is not NULL, it will be called during processing to give an +// indication of progress. See the comments for |BN_GENCB|. It returns one on +// success and zero otherwise. +OPENSSL_EXPORT int BN_generate_prime_ex(BIGNUM *ret, int bits, int safe, + const BIGNUM *add, const BIGNUM *rem, + BN_GENCB *cb); + +// BN_prime_checks is magic value that can be used as the |checks| argument to +// the primality testing functions in order to automatically select a number of +// Miller-Rabin checks that gives a false positive rate of ~2^{-80}. +#define BN_prime_checks 0 + +// bn_primality_result_t enumerates the outcomes of primality-testing. +enum bn_primality_result_t { + bn_probably_prime, + bn_composite, + bn_non_prime_power_composite, +}; + +// BN_enhanced_miller_rabin_primality_test tests whether |w| is probably a prime +// number using the Enhanced Miller-Rabin Test (FIPS 186-4 C.3.2) with +// |iterations| iterations and returns the result in |out_result|. Enhanced +// Miller-Rabin tests primality for odd integers greater than 3, returning +// |bn_probably_prime| if the number is probably prime, +// |bn_non_prime_power_composite| if the number is a composite that is not the +// power of a single prime, and |bn_composite| otherwise. If |iterations| is +// |BN_prime_checks|, then a value that results in a false positive rate lower +// than the number-field sieve security level of |w| is used. It returns one on +// success and zero on failure. If |cb| is not NULL, then it is called during +// each iteration of the primality test. +OPENSSL_EXPORT int BN_enhanced_miller_rabin_primality_test( + enum bn_primality_result_t *out_result, const BIGNUM *w, int iterations, + BN_CTX *ctx, BN_GENCB *cb); + +// BN_primality_test sets |*is_probably_prime| to one if |candidate| is +// probably a prime number by the Miller-Rabin test or zero if it's certainly +// not. +// +// If |do_trial_division| is non-zero then |candidate| will be tested against a +// list of small primes before Miller-Rabin tests. The probability of this +// function returning a false positive is 2^{2*checks}. If |checks| is +// |BN_prime_checks| then a value that results in a false positive rate lower +// than the number-field sieve security level of |candidate| is used. If |cb| is +// not NULL then it is called during the checking process. See the comment above +// |BN_GENCB|. +// +// The function returns one on success and zero on error. +// +// (If you are unsure whether you want |do_trial_division|, don't set it.) +OPENSSL_EXPORT int BN_primality_test(int *is_probably_prime, + const BIGNUM *candidate, int checks, + BN_CTX *ctx, int do_trial_division, + BN_GENCB *cb); + +// BN_is_prime_fasttest_ex returns one if |candidate| is probably a prime +// number by the Miller-Rabin test, zero if it's certainly not and -1 on error. +// +// If |do_trial_division| is non-zero then |candidate| will be tested against a +// list of small primes before Miller-Rabin tests. The probability of this +// function returning one when |candidate| is composite is 2^{2*checks}. If +// |checks| is |BN_prime_checks| then a value that results in a false positive +// rate lower than the number-field sieve security level of |candidate| is used. +// If |cb| is not NULL then it is called during the checking process. See the +// comment above |BN_GENCB|. +// +// WARNING: deprecated. Use |BN_primality_test|. +OPENSSL_EXPORT int BN_is_prime_fasttest_ex(const BIGNUM *candidate, int checks, + BN_CTX *ctx, int do_trial_division, + BN_GENCB *cb); + +// BN_is_prime_ex acts the same as |BN_is_prime_fasttest_ex| with +// |do_trial_division| set to zero. +// +// WARNING: deprecated: Use |BN_primality_test|. +OPENSSL_EXPORT int BN_is_prime_ex(const BIGNUM *candidate, int checks, + BN_CTX *ctx, BN_GENCB *cb); + + +// Number theory functions + +// BN_gcd sets |r| = gcd(|a|, |b|). It returns one on success and zero +// otherwise. +OPENSSL_EXPORT int BN_gcd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + BN_CTX *ctx); + +// BN_mod_inverse sets |out| equal to |a|^-1, mod |n|. If |out| is NULL, a +// fresh BIGNUM is allocated. It returns the result or NULL on error. +// +// If |n| is even then the operation is performed using an algorithm that avoids +// some branches but which isn't constant-time. This function shouldn't be used +// for secret values; use |BN_mod_inverse_blinded| instead. Or, if |n| is +// guaranteed to be prime, use +// |BN_mod_exp_mont_consttime(out, a, m_minus_2, m, ctx, m_mont)|, taking +// advantage of Fermat's Little Theorem. +OPENSSL_EXPORT BIGNUM *BN_mod_inverse(BIGNUM *out, const BIGNUM *a, + const BIGNUM *n, BN_CTX *ctx); + +// BN_mod_inverse_blinded sets |out| equal to |a|^-1, mod |n|, where |n| is the +// Montgomery modulus for |mont|. |a| must be non-negative and must be less +// than |n|. |n| must be greater than 1. |a| is blinded (masked by a random +// value) to protect it against side-channel attacks. On failure, if the failure +// was caused by |a| having no inverse mod |n| then |*out_no_inverse| will be +// set to one; otherwise it will be set to zero. +// +// Note this function may incorrectly report |a| has no inverse if the random +// blinding value has no inverse. It should only be used when |n| has few +// non-invertible elements, such as an RSA modulus. +int BN_mod_inverse_blinded(BIGNUM *out, int *out_no_inverse, const BIGNUM *a, + const BN_MONT_CTX *mont, BN_CTX *ctx); + +// BN_mod_inverse_odd sets |out| equal to |a|^-1, mod |n|. |a| must be +// non-negative and must be less than |n|. |n| must be odd. This function +// shouldn't be used for secret values; use |BN_mod_inverse_blinded| instead. +// Or, if |n| is guaranteed to be prime, use +// |BN_mod_exp_mont_consttime(out, a, m_minus_2, m, ctx, m_mont)|, taking +// advantage of Fermat's Little Theorem. It returns one on success or zero on +// failure. On failure, if the failure was caused by |a| having no inverse mod +// |n| then |*out_no_inverse| will be set to one; otherwise it will be set to +// zero. +int BN_mod_inverse_odd(BIGNUM *out, int *out_no_inverse, const BIGNUM *a, + const BIGNUM *n, BN_CTX *ctx); + + +// Montgomery arithmetic. + +// BN_MONT_CTX contains the precomputed values needed to work in a specific +// Montgomery domain. + +// BN_MONT_CTX_new_for_modulus returns a fresh |BN_MONT_CTX| given the modulus, +// |mod| or NULL on error. +OPENSSL_EXPORT BN_MONT_CTX *BN_MONT_CTX_new_for_modulus(const BIGNUM *mod, + BN_CTX *ctx); + +// BN_MONT_CTX_free frees memory associated with |mont|. +OPENSSL_EXPORT void BN_MONT_CTX_free(BN_MONT_CTX *mont); + +// BN_MONT_CTX_copy sets |to| equal to |from|. It returns |to| on success or +// NULL on error. +OPENSSL_EXPORT BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to, + const BN_MONT_CTX *from); + +// BN_MONT_CTX_set_locked takes |lock| and checks whether |*pmont| is NULL. If +// so, it creates a new |BN_MONT_CTX| and sets the modulus for it to |mod|. It +// then stores it as |*pmont|. It returns one on success and zero on error. +// +// If |*pmont| is already non-NULL then it does nothing and returns one. +int BN_MONT_CTX_set_locked(BN_MONT_CTX **pmont, CRYPTO_MUTEX *lock, + const BIGNUM *mod, BN_CTX *bn_ctx); + +// BN_to_montgomery sets |ret| equal to |a| in the Montgomery domain. |a| is +// assumed to be in the range [0, n), where |n| is the Montgomery modulus. It +// returns one on success or zero on error. +OPENSSL_EXPORT int BN_to_montgomery(BIGNUM *ret, const BIGNUM *a, + const BN_MONT_CTX *mont, BN_CTX *ctx); + +// BN_from_montgomery sets |ret| equal to |a| * R^-1, i.e. translates values out +// of the Montgomery domain. |a| is assumed to be in the range [0, n), where |n| +// is the Montgomery modulus. It returns one on success or zero on error. +OPENSSL_EXPORT int BN_from_montgomery(BIGNUM *ret, const BIGNUM *a, + const BN_MONT_CTX *mont, BN_CTX *ctx); + +// BN_mod_mul_montgomery set |r| equal to |a| * |b|, in the Montgomery domain. +// Both |a| and |b| must already be in the Montgomery domain (by +// |BN_to_montgomery|). In particular, |a| and |b| are assumed to be in the +// range [0, n), where |n| is the Montgomery modulus. It returns one on success +// or zero on error. +OPENSSL_EXPORT int BN_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, + const BIGNUM *b, + const BN_MONT_CTX *mont, BN_CTX *ctx); + + +// Exponentiation. + +// BN_exp sets |r| equal to |a|^{|p|}. It does so with a square-and-multiply +// algorithm that leaks side-channel information. It returns one on success or +// zero otherwise. +OPENSSL_EXPORT int BN_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + BN_CTX *ctx); + +// BN_mod_exp sets |r| equal to |a|^{|p|} mod |m|. It does so with the best +// algorithm for the values provided. It returns one on success or zero +// otherwise. The |BN_mod_exp_mont_consttime| variant must be used if the +// exponent is secret. +OPENSSL_EXPORT int BN_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx); + +OPENSSL_EXPORT int BN_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, + const BN_MONT_CTX *mont); + +OPENSSL_EXPORT int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, + const BIGNUM *p, const BIGNUM *m, + BN_CTX *ctx, + const BN_MONT_CTX *mont); + + +// Deprecated functions + +// BN_bn2mpi serialises the value of |in| to |out|, using a format that consists +// of the number's length in bytes represented as a 4-byte big-endian number, +// and the number itself in big-endian format, where the most significant bit +// signals a negative number. (The representation of numbers with the MSB set is +// prefixed with null byte). |out| must have sufficient space available; to +// find the needed amount of space, call the function with |out| set to NULL. +OPENSSL_EXPORT size_t BN_bn2mpi(const BIGNUM *in, uint8_t *out); + +// BN_mpi2bn parses |len| bytes from |in| and returns the resulting value. The +// bytes at |in| are expected to be in the format emitted by |BN_bn2mpi|. +// +// If |out| is NULL then a fresh |BIGNUM| is allocated and returned, otherwise +// |out| is reused and returned. On error, NULL is returned and the error queue +// is updated. +OPENSSL_EXPORT BIGNUM *BN_mpi2bn(const uint8_t *in, size_t len, BIGNUM *out); + +// BN_mod_exp_mont_word is like |BN_mod_exp_mont| except that the base |a| is +// given as a |BN_ULONG| instead of a |BIGNUM *|. It returns one on success +// or zero otherwise. +OPENSSL_EXPORT int BN_mod_exp_mont_word(BIGNUM *r, BN_ULONG a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, + const BN_MONT_CTX *mont); + +// BN_mod_exp2_mont calculates (a1^p1) * (a2^p2) mod m. It returns 1 on success +// or zero otherwise. +OPENSSL_EXPORT 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, const BN_MONT_CTX *mont); + +// BN_MONT_CTX_new returns a fresh |BN_MONT_CTX| or NULL on allocation failure. +// Use |BN_MONT_CTX_new_for_modulus| instead. +OPENSSL_EXPORT BN_MONT_CTX *BN_MONT_CTX_new(void); + +// BN_MONT_CTX_set sets up a Montgomery context given the modulus, |mod|. It +// returns one on success and zero on error. Use |BN_MONT_CTX_new_for_modulus| +// instead. +OPENSSL_EXPORT int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, + BN_CTX *ctx); + + +// Private functions + +struct bignum_st { + // d is a pointer to an array of |width| |BN_BITS2|-bit chunks in + // little-endian order. This stores the absolute value of the number. + BN_ULONG *d; + // width is the number of elements of |d| which are valid. This value is not + // necessarily minimal; the most-significant words of |d| may be zero. + // |width| determines a potentially loose upper-bound on the absolute value + // of the |BIGNUM|. + // + // Functions taking |BIGNUM| inputs must compute the same answer for all + // possible widths. |bn_minimal_width|, |bn_set_minimal_width|, and other + // helpers may be used to recover the minimal width, provided it is not + // secret. If it is secret, use a different algorithm. Functions may output + // minimal or non-minimal |BIGNUM|s depending on secrecy requirements, but + // those which cause widths to unboundedly grow beyond the minimal value + // should be documented such. + // + // Note this is different from historical |BIGNUM| semantics. + int width; + // dmax is number of elements of |d| which are allocated. + int dmax; + // neg is one if the number if negative and zero otherwise. + int neg; + // flags is a bitmask of |BN_FLG_*| values + int flags; +}; + +struct bn_mont_ctx_st { + // RR is R^2, reduced modulo |N|. It is used to convert to Montgomery form. + BIGNUM RR; + // N is the modulus. It is always stored in minimal form, so |N.top| + // determines R. + BIGNUM N; + BN_ULONG n0[2]; // least significant words of (R*Ri-1)/N +}; + +OPENSSL_EXPORT unsigned BN_num_bits_word(BN_ULONG l); + +#define BN_FLG_MALLOCED 0x01 +#define BN_FLG_STATIC_DATA 0x02 +// |BN_FLG_CONSTTIME| has been removed and intentionally omitted so code relying +// on it will not compile. Consumers outside BoringSSL should use the +// higher-level cryptographic algorithms exposed by other modules. Consumers +// within the library should call the appropriate timing-sensitive algorithm +// directly. + + +#if defined(__cplusplus) +} // extern C + +#if !defined(BORINGSSL_NO_CXX) +extern "C++" { + +namespace bssl { + +BORINGSSL_MAKE_DELETER(BIGNUM, BN_free) +BORINGSSL_MAKE_DELETER(BN_CTX, BN_CTX_free) +BORINGSSL_MAKE_DELETER(BN_MONT_CTX, BN_MONT_CTX_free) + +class BN_CTXScope { + public: + BN_CTXScope(BN_CTX *ctx) : ctx_(ctx) { BN_CTX_start(ctx_); } + ~BN_CTXScope() { BN_CTX_end(ctx_); } + + private: + BN_CTX *ctx_; + + BN_CTXScope(BN_CTXScope &) = delete; + BN_CTXScope &operator=(BN_CTXScope &) = delete; +}; + +} // namespace bssl + +} // extern C++ +#endif + +#endif + +#define BN_R_ARG2_LT_ARG3 100 +#define BN_R_BAD_RECIPROCAL 101 +#define BN_R_BIGNUM_TOO_LONG 102 +#define BN_R_BITS_TOO_SMALL 103 +#define BN_R_CALLED_WITH_EVEN_MODULUS 104 +#define BN_R_DIV_BY_ZERO 105 +#define BN_R_EXPAND_ON_STATIC_BIGNUM_DATA 106 +#define BN_R_INPUT_NOT_REDUCED 107 +#define BN_R_INVALID_RANGE 108 +#define BN_R_NEGATIVE_NUMBER 109 +#define BN_R_NOT_A_SQUARE 110 +#define BN_R_NOT_INITIALIZED 111 +#define BN_R_NO_INVERSE 112 +#define BN_R_PRIVATE_KEY_TOO_LARGE 113 +#define BN_R_P_IS_NOT_PRIME 114 +#define BN_R_TOO_MANY_ITERATIONS 115 +#define BN_R_TOO_MANY_TEMPORARY_VARIABLES 116 +#define BN_R_BAD_ENCODING 117 +#define BN_R_ENCODE_ERROR 118 +#define BN_R_INVALID_INPUT 119 + +#endif // OPENSSL_HEADER_BN_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/bn.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/bn.h.grpc_back new file mode 100644 index 0000000..eeb25a3 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/bn.h.grpc_back @@ -0,0 +1,1019 @@ +/* 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-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 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 OPENSSL_HEADER_BN_H +#define OPENSSL_HEADER_BN_H + +#include +#include + +#include // for PRIu64 and friends +#include // for FILE* + +#if defined(__cplusplus) +extern "C" { +#endif + + +// BN provides support for working with arbitrary sized integers. For example, +// although the largest integer supported by the compiler might be 64 bits, BN +// will allow you to work with numbers until you run out of memory. + + +// BN_ULONG is the native word size when working with big integers. +// +// Note: on some platforms, inttypes.h does not define print format macros in +// C++ unless |__STDC_FORMAT_MACROS| defined. As this is a public header, bn.h +// does not define |__STDC_FORMAT_MACROS| itself. C++ source files which use the +// FMT macros must define it externally. +#if defined(OPENSSL_64_BIT) +#define BN_ULONG uint64_t +#define BN_BITS2 64 +#define BN_DEC_FMT1 "%" PRIu64 +#define BN_DEC_FMT2 "%019" PRIu64 +#define BN_HEX_FMT1 "%" PRIx64 +#define BN_HEX_FMT2 "%016" PRIx64 +#elif defined(OPENSSL_32_BIT) +#define BN_ULONG uint32_t +#define BN_BITS2 32 +#define BN_DEC_FMT1 "%" PRIu32 +#define BN_DEC_FMT2 "%09" PRIu32 +#define BN_HEX_FMT1 "%" PRIx32 +#define BN_HEX_FMT2 "%08" PRIx64 +#else +#error "Must define either OPENSSL_32_BIT or OPENSSL_64_BIT" +#endif + + +// Allocation and freeing. + +// BN_new creates a new, allocated BIGNUM and initialises it. +OPENSSL_EXPORT BIGNUM *BN_new(void); + +// BN_init initialises a stack allocated |BIGNUM|. +OPENSSL_EXPORT void BN_init(BIGNUM *bn); + +// BN_free frees the data referenced by |bn| and, if |bn| was originally +// allocated on the heap, frees |bn| also. +OPENSSL_EXPORT void BN_free(BIGNUM *bn); + +// BN_clear_free erases and frees the data referenced by |bn| and, if |bn| was +// originally allocated on the heap, frees |bn| also. +OPENSSL_EXPORT void BN_clear_free(BIGNUM *bn); + +// BN_dup allocates a new BIGNUM and sets it equal to |src|. It returns the +// allocated BIGNUM on success or NULL otherwise. +OPENSSL_EXPORT BIGNUM *BN_dup(const BIGNUM *src); + +// BN_copy sets |dest| equal to |src| and returns |dest| or NULL on allocation +// failure. +OPENSSL_EXPORT BIGNUM *BN_copy(BIGNUM *dest, const BIGNUM *src); + +// BN_clear sets |bn| to zero and erases the old data. +OPENSSL_EXPORT void BN_clear(BIGNUM *bn); + +// BN_value_one returns a static BIGNUM with value 1. +OPENSSL_EXPORT const BIGNUM *BN_value_one(void); + + +// Basic functions. + +// BN_num_bits returns the minimum number of bits needed to represent the +// absolute value of |bn|. +OPENSSL_EXPORT unsigned BN_num_bits(const BIGNUM *bn); + +// BN_num_bytes returns the minimum number of bytes needed to represent the +// absolute value of |bn|. +OPENSSL_EXPORT unsigned BN_num_bytes(const BIGNUM *bn); + +// BN_zero sets |bn| to zero. +OPENSSL_EXPORT void BN_zero(BIGNUM *bn); + +// BN_one sets |bn| to one. It returns one on success or zero on allocation +// failure. +OPENSSL_EXPORT int BN_one(BIGNUM *bn); + +// BN_set_word sets |bn| to |value|. It returns one on success or zero on +// allocation failure. +OPENSSL_EXPORT int BN_set_word(BIGNUM *bn, BN_ULONG value); + +// BN_set_u64 sets |bn| to |value|. It returns one on success or zero on +// allocation failure. +OPENSSL_EXPORT int BN_set_u64(BIGNUM *bn, uint64_t value); + +// BN_set_negative sets the sign of |bn|. +OPENSSL_EXPORT void BN_set_negative(BIGNUM *bn, int sign); + +// BN_is_negative returns one if |bn| is negative and zero otherwise. +OPENSSL_EXPORT int BN_is_negative(const BIGNUM *bn); + + +// Conversion functions. + +// BN_bin2bn sets |*ret| to the value of |len| bytes from |in|, interpreted as +// a big-endian number, and returns |ret|. If |ret| is NULL then a fresh +// |BIGNUM| is allocated and returned. It returns NULL on allocation +// failure. +OPENSSL_EXPORT BIGNUM *BN_bin2bn(const uint8_t *in, size_t len, BIGNUM *ret); + +// BN_bn2bin serialises the absolute value of |in| to |out| as a big-endian +// integer, which must have |BN_num_bytes| of space available. It returns the +// number of bytes written. Note this function leaks the magnitude of |in|. If +// |in| is secret, use |BN_bn2bin_padded| instead. +OPENSSL_EXPORT size_t BN_bn2bin(const BIGNUM *in, uint8_t *out); + +// BN_le2bn sets |*ret| to the value of |len| bytes from |in|, interpreted as +// a little-endian number, and returns |ret|. If |ret| is NULL then a fresh +// |BIGNUM| is allocated and returned. It returns NULL on allocation +// failure. +OPENSSL_EXPORT BIGNUM *BN_le2bn(const uint8_t *in, size_t len, BIGNUM *ret); + +// BN_bn2le_padded serialises the absolute value of |in| to |out| as a +// little-endian integer, which must have |len| of space available, padding +// out the remainder of out with zeros. If |len| is smaller than |BN_num_bytes|, +// the function fails and returns 0. Otherwise, it returns 1. +OPENSSL_EXPORT int BN_bn2le_padded(uint8_t *out, size_t len, const BIGNUM *in); + +// BN_bn2bin_padded serialises the absolute value of |in| to |out| as a +// big-endian integer. The integer is padded with leading zeros up to size +// |len|. If |len| is smaller than |BN_num_bytes|, the function fails and +// returns 0. Otherwise, it returns 1. +OPENSSL_EXPORT int BN_bn2bin_padded(uint8_t *out, size_t len, const BIGNUM *in); + +// BN_bn2cbb_padded behaves like |BN_bn2bin_padded| but writes to a |CBB|. +OPENSSL_EXPORT int BN_bn2cbb_padded(CBB *out, size_t len, const BIGNUM *in); + +// BN_bn2hex returns an allocated string that contains a NUL-terminated, hex +// representation of |bn|. If |bn| is negative, the first char in the resulting +// string will be '-'. Returns NULL on allocation failure. +OPENSSL_EXPORT char *BN_bn2hex(const BIGNUM *bn); + +// BN_hex2bn parses the leading hex number from |in|, which may be proceeded by +// a '-' to indicate a negative number and may contain trailing, non-hex data. +// If |outp| is not NULL, it constructs a BIGNUM equal to the hex number and +// stores it in |*outp|. If |*outp| is NULL then it allocates a new BIGNUM and +// updates |*outp|. It returns the number of bytes of |in| processed or zero on +// error. +OPENSSL_EXPORT int BN_hex2bn(BIGNUM **outp, const char *in); + +// BN_bn2dec returns an allocated string that contains a NUL-terminated, +// decimal representation of |bn|. If |bn| is negative, the first char in the +// resulting string will be '-'. Returns NULL on allocation failure. +OPENSSL_EXPORT char *BN_bn2dec(const BIGNUM *a); + +// BN_dec2bn parses the leading decimal number from |in|, which may be +// proceeded by a '-' to indicate a negative number and may contain trailing, +// non-decimal data. If |outp| is not NULL, it constructs a BIGNUM equal to the +// decimal number and stores it in |*outp|. If |*outp| is NULL then it +// allocates a new BIGNUM and updates |*outp|. It returns the number of bytes +// of |in| processed or zero on error. +OPENSSL_EXPORT int BN_dec2bn(BIGNUM **outp, const char *in); + +// BN_asc2bn acts like |BN_dec2bn| or |BN_hex2bn| depending on whether |in| +// begins with "0X" or "0x" (indicating hex) or not (indicating decimal). A +// leading '-' is still permitted and comes before the optional 0X/0x. It +// returns one on success or zero on error. +OPENSSL_EXPORT int BN_asc2bn(BIGNUM **outp, const char *in); + +// BN_print writes a hex encoding of |a| to |bio|. It returns one on success +// and zero on error. +OPENSSL_EXPORT int BN_print(BIO *bio, const BIGNUM *a); + +// BN_print_fp acts like |BIO_print|, but wraps |fp| in a |BIO| first. +OPENSSL_EXPORT int BN_print_fp(FILE *fp, const BIGNUM *a); + +// BN_get_word returns the absolute value of |bn| as a single word. If |bn| is +// too large to be represented as a single word, the maximum possible value +// will be returned. +OPENSSL_EXPORT BN_ULONG BN_get_word(const BIGNUM *bn); + +// BN_get_u64 sets |*out| to the absolute value of |bn| as a |uint64_t| and +// returns one. If |bn| is too large to be represented as a |uint64_t|, it +// returns zero. +OPENSSL_EXPORT int BN_get_u64(const BIGNUM *bn, uint64_t *out); + + +// ASN.1 functions. + +// BN_parse_asn1_unsigned parses a non-negative DER INTEGER from |cbs| writes +// the result to |ret|. It returns one on success and zero on failure. +OPENSSL_EXPORT int BN_parse_asn1_unsigned(CBS *cbs, BIGNUM *ret); + +// BN_marshal_asn1 marshals |bn| as a non-negative DER INTEGER and appends the +// result to |cbb|. It returns one on success and zero on failure. +OPENSSL_EXPORT int BN_marshal_asn1(CBB *cbb, const BIGNUM *bn); + + +// BIGNUM pools. +// +// Certain BIGNUM operations need to use many temporary variables and +// allocating and freeing them can be quite slow. Thus such operations typically +// take a |BN_CTX| parameter, which contains a pool of |BIGNUMs|. The |ctx| +// argument to a public function may be NULL, in which case a local |BN_CTX| +// will be created just for the lifetime of that call. +// +// A function must call |BN_CTX_start| first. Then, |BN_CTX_get| may be called +// repeatedly to obtain temporary |BIGNUM|s. All |BN_CTX_get| calls must be made +// before calling any other functions that use the |ctx| as an argument. +// +// Finally, |BN_CTX_end| must be called before returning from the function. +// When |BN_CTX_end| is called, the |BIGNUM| pointers obtained from +// |BN_CTX_get| become invalid. + +// BN_CTX_new returns a new, empty BN_CTX or NULL on allocation failure. +OPENSSL_EXPORT BN_CTX *BN_CTX_new(void); + +// BN_CTX_free frees all BIGNUMs contained in |ctx| and then frees |ctx| +// itself. +OPENSSL_EXPORT void BN_CTX_free(BN_CTX *ctx); + +// BN_CTX_start "pushes" a new entry onto the |ctx| stack and allows future +// calls to |BN_CTX_get|. +OPENSSL_EXPORT void BN_CTX_start(BN_CTX *ctx); + +// BN_CTX_get returns a new |BIGNUM|, or NULL on allocation failure. Once +// |BN_CTX_get| has returned NULL, all future calls will also return NULL until +// |BN_CTX_end| is called. +OPENSSL_EXPORT BIGNUM *BN_CTX_get(BN_CTX *ctx); + +// BN_CTX_end invalidates all |BIGNUM|s returned from |BN_CTX_get| since the +// matching |BN_CTX_start| call. +OPENSSL_EXPORT void BN_CTX_end(BN_CTX *ctx); + + +// Simple arithmetic + +// BN_add sets |r| = |a| + |b|, where |r| may be the same pointer as either |a| +// or |b|. It returns one on success and zero on allocation failure. +OPENSSL_EXPORT int BN_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); + +// BN_uadd sets |r| = |a| + |b|, where |a| and |b| are non-negative and |r| may +// be the same pointer as either |a| or |b|. It returns one on success and zero +// on allocation failure. +OPENSSL_EXPORT int BN_uadd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); + +// BN_add_word adds |w| to |a|. It returns one on success and zero otherwise. +OPENSSL_EXPORT int BN_add_word(BIGNUM *a, BN_ULONG w); + +// BN_sub sets |r| = |a| - |b|, where |r| may be the same pointer as either |a| +// or |b|. It returns one on success and zero on allocation failure. +OPENSSL_EXPORT int BN_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); + +// BN_usub sets |r| = |a| - |b|, where |a| and |b| are non-negative integers, +// |b| < |a| and |r| may be the same pointer as either |a| or |b|. It returns +// one on success and zero on allocation failure. +OPENSSL_EXPORT int BN_usub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b); + +// BN_sub_word subtracts |w| from |a|. It returns one on success and zero on +// allocation failure. +OPENSSL_EXPORT int BN_sub_word(BIGNUM *a, BN_ULONG w); + +// BN_mul sets |r| = |a| * |b|, where |r| may be the same pointer as |a| or +// |b|. Returns one on success and zero otherwise. +OPENSSL_EXPORT int BN_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + BN_CTX *ctx); + +// BN_mul_word sets |bn| = |bn| * |w|. It returns one on success or zero on +// allocation failure. +OPENSSL_EXPORT int BN_mul_word(BIGNUM *bn, BN_ULONG w); + +// BN_sqr sets |r| = |a|^2 (i.e. squares), where |r| may be the same pointer as +// |a|. Returns one on success and zero otherwise. This is more efficient than +// BN_mul(r, a, a, ctx). +OPENSSL_EXPORT int BN_sqr(BIGNUM *r, const BIGNUM *a, BN_CTX *ctx); + +// BN_div divides |numerator| by |divisor| and places the result in |quotient| +// and the remainder in |rem|. Either of |quotient| or |rem| may be NULL, in +// which case the respective value is not returned. The result is rounded +// towards zero; thus if |numerator| is negative, the remainder will be zero or +// negative. It returns one on success or zero on error. +OPENSSL_EXPORT int BN_div(BIGNUM *quotient, BIGNUM *rem, + const BIGNUM *numerator, const BIGNUM *divisor, + BN_CTX *ctx); + +// BN_div_word sets |numerator| = |numerator|/|divisor| and returns the +// remainder or (BN_ULONG)-1 on error. +OPENSSL_EXPORT BN_ULONG BN_div_word(BIGNUM *numerator, BN_ULONG divisor); + +// BN_sqrt sets |*out_sqrt| (which may be the same |BIGNUM| as |in|) to the +// square root of |in|, using |ctx|. It returns one on success or zero on +// error. Negative numbers and non-square numbers will result in an error with +// appropriate errors on the error queue. +OPENSSL_EXPORT int BN_sqrt(BIGNUM *out_sqrt, const BIGNUM *in, BN_CTX *ctx); + + +// Comparison functions + +// BN_cmp returns a value less than, equal to or greater than zero if |a| is +// less than, equal to or greater than |b|, respectively. +OPENSSL_EXPORT int BN_cmp(const BIGNUM *a, const BIGNUM *b); + +// BN_cmp_word is like |BN_cmp| except it takes its second argument as a +// |BN_ULONG| instead of a |BIGNUM|. +OPENSSL_EXPORT int BN_cmp_word(const BIGNUM *a, BN_ULONG b); + +// BN_ucmp returns a value less than, equal to or greater than zero if the +// absolute value of |a| is less than, equal to or greater than the absolute +// value of |b|, respectively. +OPENSSL_EXPORT int BN_ucmp(const BIGNUM *a, const BIGNUM *b); + +// BN_equal_consttime returns one if |a| is equal to |b|, and zero otherwise. +// It takes an amount of time dependent on the sizes of |a| and |b|, but +// independent of the contents (including the signs) of |a| and |b|. +OPENSSL_EXPORT int BN_equal_consttime(const BIGNUM *a, const BIGNUM *b); + +// BN_abs_is_word returns one if the absolute value of |bn| equals |w| and zero +// otherwise. +OPENSSL_EXPORT int BN_abs_is_word(const BIGNUM *bn, BN_ULONG w); + +// BN_is_zero returns one if |bn| is zero and zero otherwise. +OPENSSL_EXPORT int BN_is_zero(const BIGNUM *bn); + +// BN_is_one returns one if |bn| equals one and zero otherwise. +OPENSSL_EXPORT int BN_is_one(const BIGNUM *bn); + +// BN_is_word returns one if |bn| is exactly |w| and zero otherwise. +OPENSSL_EXPORT int BN_is_word(const BIGNUM *bn, BN_ULONG w); + +// BN_is_odd returns one if |bn| is odd and zero otherwise. +OPENSSL_EXPORT int BN_is_odd(const BIGNUM *bn); + +// BN_is_pow2 returns 1 if |a| is a power of two, and 0 otherwise. +OPENSSL_EXPORT int BN_is_pow2(const BIGNUM *a); + + +// Bitwise operations. + +// BN_lshift sets |r| equal to |a| << n. The |a| and |r| arguments may be the +// same |BIGNUM|. It returns one on success and zero on allocation failure. +OPENSSL_EXPORT int BN_lshift(BIGNUM *r, const BIGNUM *a, int n); + +// BN_lshift1 sets |r| equal to |a| << 1, where |r| and |a| may be the same +// pointer. It returns one on success and zero on allocation failure. +OPENSSL_EXPORT int BN_lshift1(BIGNUM *r, const BIGNUM *a); + +// BN_rshift sets |r| equal to |a| >> n, where |r| and |a| may be the same +// pointer. It returns one on success and zero on allocation failure. +OPENSSL_EXPORT int BN_rshift(BIGNUM *r, const BIGNUM *a, int n); + +// BN_rshift1 sets |r| equal to |a| >> 1, where |r| and |a| may be the same +// pointer. It returns one on success and zero on allocation failure. +OPENSSL_EXPORT int BN_rshift1(BIGNUM *r, const BIGNUM *a); + +// BN_set_bit sets the |n|th, least-significant bit in |a|. For example, if |a| +// is 2 then setting bit zero will make it 3. It returns one on success or zero +// on allocation failure. +OPENSSL_EXPORT int BN_set_bit(BIGNUM *a, int n); + +// BN_clear_bit clears the |n|th, least-significant bit in |a|. For example, if +// |a| is 3, clearing bit zero will make it two. It returns one on success or +// zero on allocation failure. +OPENSSL_EXPORT int BN_clear_bit(BIGNUM *a, int n); + +// BN_is_bit_set returns one if the |n|th least-significant bit in |a| exists +// and is set. Otherwise, it returns zero. +OPENSSL_EXPORT int BN_is_bit_set(const BIGNUM *a, int n); + +// BN_mask_bits truncates |a| so that it is only |n| bits long. It returns one +// on success or zero if |n| is negative. +// +// This differs from OpenSSL which additionally returns zero if |a|'s word +// length is less than or equal to |n|, rounded down to a number of words. Note +// word size is platform-dependent, so this behavior is also difficult to rely +// on in OpenSSL and not very useful. +OPENSSL_EXPORT int BN_mask_bits(BIGNUM *a, int n); + +// BN_count_low_zero_bits returns the number of low-order zero bits in |bn|, or +// the number of factors of two which divide it. It returns zero if |bn| is +// zero. +OPENSSL_EXPORT int BN_count_low_zero_bits(const BIGNUM *bn); + + +// Modulo arithmetic. + +// BN_mod_word returns |a| mod |w| or (BN_ULONG)-1 on error. +OPENSSL_EXPORT BN_ULONG BN_mod_word(const BIGNUM *a, BN_ULONG w); + +// BN_mod_pow2 sets |r| = |a| mod 2^|e|. It returns 1 on success and +// 0 on error. +OPENSSL_EXPORT int BN_mod_pow2(BIGNUM *r, const BIGNUM *a, size_t e); + +// BN_nnmod_pow2 sets |r| = |a| mod 2^|e| where |r| is always positive. +// It returns 1 on success and 0 on error. +OPENSSL_EXPORT int BN_nnmod_pow2(BIGNUM *r, const BIGNUM *a, size_t e); + +// BN_mod is a helper macro that calls |BN_div| and discards the quotient. +#define BN_mod(rem, numerator, divisor, ctx) \ + BN_div(NULL, (rem), (numerator), (divisor), (ctx)) + +// BN_nnmod is a non-negative modulo function. It acts like |BN_mod|, but 0 <= +// |rem| < |divisor| is always true. It returns one on success and zero on +// error. +OPENSSL_EXPORT int BN_nnmod(BIGNUM *rem, const BIGNUM *numerator, + const BIGNUM *divisor, BN_CTX *ctx); + +// BN_mod_add sets |r| = |a| + |b| mod |m|. It returns one on success and zero +// on error. +OPENSSL_EXPORT int BN_mod_add(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const BIGNUM *m, BN_CTX *ctx); + +// BN_mod_add_quick acts like |BN_mod_add| but requires that |a| and |b| be +// non-negative and less than |m|. +OPENSSL_EXPORT int BN_mod_add_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const BIGNUM *m); + +// BN_mod_sub sets |r| = |a| - |b| mod |m|. It returns one on success and zero +// on error. +OPENSSL_EXPORT int BN_mod_sub(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const BIGNUM *m, BN_CTX *ctx); + +// BN_mod_sub_quick acts like |BN_mod_sub| but requires that |a| and |b| be +// non-negative and less than |m|. +OPENSSL_EXPORT int BN_mod_sub_quick(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const BIGNUM *m); + +// BN_mod_mul sets |r| = |a|*|b| mod |m|. It returns one on success and zero +// on error. +OPENSSL_EXPORT int BN_mod_mul(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + const BIGNUM *m, BN_CTX *ctx); + +// BN_mod_sqr sets |r| = |a|^2 mod |m|. It returns one on success and zero +// on error. +OPENSSL_EXPORT int BN_mod_sqr(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, + BN_CTX *ctx); + +// BN_mod_lshift sets |r| = (|a| << n) mod |m|, where |r| and |a| may be the +// same pointer. It returns one on success and zero on error. +OPENSSL_EXPORT int BN_mod_lshift(BIGNUM *r, const BIGNUM *a, int n, + const BIGNUM *m, BN_CTX *ctx); + +// BN_mod_lshift_quick acts like |BN_mod_lshift| but requires that |a| be +// non-negative and less than |m|. +OPENSSL_EXPORT int BN_mod_lshift_quick(BIGNUM *r, const BIGNUM *a, int n, + const BIGNUM *m); + +// BN_mod_lshift1 sets |r| = (|a| << 1) mod |m|, where |r| and |a| may be the +// same pointer. It returns one on success and zero on error. +OPENSSL_EXPORT int BN_mod_lshift1(BIGNUM *r, const BIGNUM *a, const BIGNUM *m, + BN_CTX *ctx); + +// BN_mod_lshift1_quick acts like |BN_mod_lshift1| but requires that |a| be +// non-negative and less than |m|. +OPENSSL_EXPORT int BN_mod_lshift1_quick(BIGNUM *r, const BIGNUM *a, + const BIGNUM *m); + +// BN_mod_sqrt returns a newly-allocated |BIGNUM|, r, such that +// r^2 == a (mod p). |p| must be a prime. It returns NULL on error or if |a| is +// not a square mod |p|. In the latter case, it will add |BN_R_NOT_A_SQUARE| to +// the error queue. +OPENSSL_EXPORT BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, + BN_CTX *ctx); + + +// Random and prime number generation. + +// The following are values for the |top| parameter of |BN_rand|. +#define BN_RAND_TOP_ANY (-1) +#define BN_RAND_TOP_ONE 0 +#define BN_RAND_TOP_TWO 1 + +// The following are values for the |bottom| parameter of |BN_rand|. +#define BN_RAND_BOTTOM_ANY 0 +#define BN_RAND_BOTTOM_ODD 1 + +// BN_rand sets |rnd| to a random number of length |bits|. It returns one on +// success and zero otherwise. +// +// |top| must be one of the |BN_RAND_TOP_*| values. If |BN_RAND_TOP_ONE|, the +// most-significant bit, if any, will be set. If |BN_RAND_TOP_TWO|, the two +// most significant bits, if any, will be set. If |BN_RAND_TOP_ANY|, no extra +// action will be taken and |BN_num_bits(rnd)| may not equal |bits| if the most +// significant bits randomly ended up as zeros. +// +// |bottom| must be one of the |BN_RAND_BOTTOM_*| values. If +// |BN_RAND_BOTTOM_ODD|, the least-significant bit, if any, will be set. If +// |BN_RAND_BOTTOM_ANY|, no extra action will be taken. +OPENSSL_EXPORT int BN_rand(BIGNUM *rnd, int bits, int top, int bottom); + +// BN_pseudo_rand is an alias for |BN_rand|. +OPENSSL_EXPORT int BN_pseudo_rand(BIGNUM *rnd, int bits, int top, int bottom); + +// BN_rand_range is equivalent to |BN_rand_range_ex| with |min_inclusive| set +// to zero and |max_exclusive| set to |range|. +OPENSSL_EXPORT int BN_rand_range(BIGNUM *rnd, const BIGNUM *range); + +// BN_rand_range_ex sets |rnd| to a random value in +// [min_inclusive..max_exclusive). It returns one on success and zero +// otherwise. +OPENSSL_EXPORT int BN_rand_range_ex(BIGNUM *r, BN_ULONG min_inclusive, + const BIGNUM *max_exclusive); + +// BN_pseudo_rand_range is an alias for BN_rand_range. +OPENSSL_EXPORT int BN_pseudo_rand_range(BIGNUM *rnd, const BIGNUM *range); + +// BN_GENCB holds a callback function that is used by generation functions that +// can take a very long time to complete. Use |BN_GENCB_set| to initialise a +// |BN_GENCB| structure. +// +// The callback receives the address of that |BN_GENCB| structure as its last +// argument and the user is free to put an arbitrary pointer in |arg|. The other +// arguments are set as follows: +// event=BN_GENCB_GENERATED, n=i: after generating the i'th possible prime +// number. +// event=BN_GENCB_PRIME_TEST, n=-1: when finished trial division primality +// checks. +// event=BN_GENCB_PRIME_TEST, n=i: when the i'th primality test has finished. +// +// The callback can return zero to abort the generation progress or one to +// allow it to continue. +// +// When other code needs to call a BN generation function it will often take a +// BN_GENCB argument and may call the function with other argument values. +#define BN_GENCB_GENERATED 0 +#define BN_GENCB_PRIME_TEST 1 + +struct bn_gencb_st { + void *arg; // callback-specific data + int (*callback)(int event, int n, struct bn_gencb_st *); +}; + +// BN_GENCB_set configures |callback| to call |f| and sets |callout->arg| to +// |arg|. +OPENSSL_EXPORT void BN_GENCB_set(BN_GENCB *callback, + int (*f)(int event, int n, + struct bn_gencb_st *), + void *arg); + +// BN_GENCB_call calls |callback|, if not NULL, and returns the return value of +// the callback, or 1 if |callback| is NULL. +OPENSSL_EXPORT int BN_GENCB_call(BN_GENCB *callback, int event, int n); + +// BN_generate_prime_ex sets |ret| to a prime number of |bits| length. If safe +// is non-zero then the prime will be such that (ret-1)/2 is also a prime. +// (This is needed for Diffie-Hellman groups to ensure that the only subgroups +// are of size 2 and (p-1)/2.). +// +// If |add| is not NULL, the prime will fulfill the condition |ret| % |add| == +// |rem| in order to suit a given generator. (If |rem| is NULL then |ret| % +// |add| == 1.) +// +// If |cb| is not NULL, it will be called during processing to give an +// indication of progress. See the comments for |BN_GENCB|. It returns one on +// success and zero otherwise. +OPENSSL_EXPORT int BN_generate_prime_ex(BIGNUM *ret, int bits, int safe, + const BIGNUM *add, const BIGNUM *rem, + BN_GENCB *cb); + +// BN_prime_checks is magic value that can be used as the |checks| argument to +// the primality testing functions in order to automatically select a number of +// Miller-Rabin checks that gives a false positive rate of ~2^{-80}. +#define BN_prime_checks 0 + +// bn_primality_result_t enumerates the outcomes of primality-testing. +enum bn_primality_result_t { + bn_probably_prime, + bn_composite, + bn_non_prime_power_composite, +}; + +// BN_enhanced_miller_rabin_primality_test tests whether |w| is probably a prime +// number using the Enhanced Miller-Rabin Test (FIPS 186-4 C.3.2) with +// |iterations| iterations and returns the result in |out_result|. Enhanced +// Miller-Rabin tests primality for odd integers greater than 3, returning +// |bn_probably_prime| if the number is probably prime, +// |bn_non_prime_power_composite| if the number is a composite that is not the +// power of a single prime, and |bn_composite| otherwise. If |iterations| is +// |BN_prime_checks|, then a value that results in a false positive rate lower +// than the number-field sieve security level of |w| is used. It returns one on +// success and zero on failure. If |cb| is not NULL, then it is called during +// each iteration of the primality test. +OPENSSL_EXPORT int BN_enhanced_miller_rabin_primality_test( + enum bn_primality_result_t *out_result, const BIGNUM *w, int iterations, + BN_CTX *ctx, BN_GENCB *cb); + +// BN_primality_test sets |*is_probably_prime| to one if |candidate| is +// probably a prime number by the Miller-Rabin test or zero if it's certainly +// not. +// +// If |do_trial_division| is non-zero then |candidate| will be tested against a +// list of small primes before Miller-Rabin tests. The probability of this +// function returning a false positive is 2^{2*checks}. If |checks| is +// |BN_prime_checks| then a value that results in a false positive rate lower +// than the number-field sieve security level of |candidate| is used. If |cb| is +// not NULL then it is called during the checking process. See the comment above +// |BN_GENCB|. +// +// The function returns one on success and zero on error. +// +// (If you are unsure whether you want |do_trial_division|, don't set it.) +OPENSSL_EXPORT int BN_primality_test(int *is_probably_prime, + const BIGNUM *candidate, int checks, + BN_CTX *ctx, int do_trial_division, + BN_GENCB *cb); + +// BN_is_prime_fasttest_ex returns one if |candidate| is probably a prime +// number by the Miller-Rabin test, zero if it's certainly not and -1 on error. +// +// If |do_trial_division| is non-zero then |candidate| will be tested against a +// list of small primes before Miller-Rabin tests. The probability of this +// function returning one when |candidate| is composite is 2^{2*checks}. If +// |checks| is |BN_prime_checks| then a value that results in a false positive +// rate lower than the number-field sieve security level of |candidate| is used. +// If |cb| is not NULL then it is called during the checking process. See the +// comment above |BN_GENCB|. +// +// WARNING: deprecated. Use |BN_primality_test|. +OPENSSL_EXPORT int BN_is_prime_fasttest_ex(const BIGNUM *candidate, int checks, + BN_CTX *ctx, int do_trial_division, + BN_GENCB *cb); + +// BN_is_prime_ex acts the same as |BN_is_prime_fasttest_ex| with +// |do_trial_division| set to zero. +// +// WARNING: deprecated: Use |BN_primality_test|. +OPENSSL_EXPORT int BN_is_prime_ex(const BIGNUM *candidate, int checks, + BN_CTX *ctx, BN_GENCB *cb); + + +// Number theory functions + +// BN_gcd sets |r| = gcd(|a|, |b|). It returns one on success and zero +// otherwise. +OPENSSL_EXPORT int BN_gcd(BIGNUM *r, const BIGNUM *a, const BIGNUM *b, + BN_CTX *ctx); + +// BN_mod_inverse sets |out| equal to |a|^-1, mod |n|. If |out| is NULL, a +// fresh BIGNUM is allocated. It returns the result or NULL on error. +// +// If |n| is even then the operation is performed using an algorithm that avoids +// some branches but which isn't constant-time. This function shouldn't be used +// for secret values; use |BN_mod_inverse_blinded| instead. Or, if |n| is +// guaranteed to be prime, use +// |BN_mod_exp_mont_consttime(out, a, m_minus_2, m, ctx, m_mont)|, taking +// advantage of Fermat's Little Theorem. +OPENSSL_EXPORT BIGNUM *BN_mod_inverse(BIGNUM *out, const BIGNUM *a, + const BIGNUM *n, BN_CTX *ctx); + +// BN_mod_inverse_blinded sets |out| equal to |a|^-1, mod |n|, where |n| is the +// Montgomery modulus for |mont|. |a| must be non-negative and must be less +// than |n|. |n| must be greater than 1. |a| is blinded (masked by a random +// value) to protect it against side-channel attacks. On failure, if the failure +// was caused by |a| having no inverse mod |n| then |*out_no_inverse| will be +// set to one; otherwise it will be set to zero. +// +// Note this function may incorrectly report |a| has no inverse if the random +// blinding value has no inverse. It should only be used when |n| has few +// non-invertible elements, such as an RSA modulus. +int BN_mod_inverse_blinded(BIGNUM *out, int *out_no_inverse, const BIGNUM *a, + const BN_MONT_CTX *mont, BN_CTX *ctx); + +// BN_mod_inverse_odd sets |out| equal to |a|^-1, mod |n|. |a| must be +// non-negative and must be less than |n|. |n| must be odd. This function +// shouldn't be used for secret values; use |BN_mod_inverse_blinded| instead. +// Or, if |n| is guaranteed to be prime, use +// |BN_mod_exp_mont_consttime(out, a, m_minus_2, m, ctx, m_mont)|, taking +// advantage of Fermat's Little Theorem. It returns one on success or zero on +// failure. On failure, if the failure was caused by |a| having no inverse mod +// |n| then |*out_no_inverse| will be set to one; otherwise it will be set to +// zero. +int BN_mod_inverse_odd(BIGNUM *out, int *out_no_inverse, const BIGNUM *a, + const BIGNUM *n, BN_CTX *ctx); + + +// Montgomery arithmetic. + +// BN_MONT_CTX contains the precomputed values needed to work in a specific +// Montgomery domain. + +// BN_MONT_CTX_new_for_modulus returns a fresh |BN_MONT_CTX| given the modulus, +// |mod| or NULL on error. +OPENSSL_EXPORT BN_MONT_CTX *BN_MONT_CTX_new_for_modulus(const BIGNUM *mod, + BN_CTX *ctx); + +// BN_MONT_CTX_free frees memory associated with |mont|. +OPENSSL_EXPORT void BN_MONT_CTX_free(BN_MONT_CTX *mont); + +// BN_MONT_CTX_copy sets |to| equal to |from|. It returns |to| on success or +// NULL on error. +OPENSSL_EXPORT BN_MONT_CTX *BN_MONT_CTX_copy(BN_MONT_CTX *to, + const BN_MONT_CTX *from); + +// BN_MONT_CTX_set_locked takes |lock| and checks whether |*pmont| is NULL. If +// so, it creates a new |BN_MONT_CTX| and sets the modulus for it to |mod|. It +// then stores it as |*pmont|. It returns one on success and zero on error. +// +// If |*pmont| is already non-NULL then it does nothing and returns one. +int BN_MONT_CTX_set_locked(BN_MONT_CTX **pmont, CRYPTO_MUTEX *lock, + const BIGNUM *mod, BN_CTX *bn_ctx); + +// BN_to_montgomery sets |ret| equal to |a| in the Montgomery domain. |a| is +// assumed to be in the range [0, n), where |n| is the Montgomery modulus. It +// returns one on success or zero on error. +OPENSSL_EXPORT int BN_to_montgomery(BIGNUM *ret, const BIGNUM *a, + const BN_MONT_CTX *mont, BN_CTX *ctx); + +// BN_from_montgomery sets |ret| equal to |a| * R^-1, i.e. translates values out +// of the Montgomery domain. |a| is assumed to be in the range [0, n), where |n| +// is the Montgomery modulus. It returns one on success or zero on error. +OPENSSL_EXPORT int BN_from_montgomery(BIGNUM *ret, const BIGNUM *a, + const BN_MONT_CTX *mont, BN_CTX *ctx); + +// BN_mod_mul_montgomery set |r| equal to |a| * |b|, in the Montgomery domain. +// Both |a| and |b| must already be in the Montgomery domain (by +// |BN_to_montgomery|). In particular, |a| and |b| are assumed to be in the +// range [0, n), where |n| is the Montgomery modulus. It returns one on success +// or zero on error. +OPENSSL_EXPORT int BN_mod_mul_montgomery(BIGNUM *r, const BIGNUM *a, + const BIGNUM *b, + const BN_MONT_CTX *mont, BN_CTX *ctx); + + +// Exponentiation. + +// BN_exp sets |r| equal to |a|^{|p|}. It does so with a square-and-multiply +// algorithm that leaks side-channel information. It returns one on success or +// zero otherwise. +OPENSSL_EXPORT int BN_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + BN_CTX *ctx); + +// BN_mod_exp sets |r| equal to |a|^{|p|} mod |m|. It does so with the best +// algorithm for the values provided. It returns one on success or zero +// otherwise. The |BN_mod_exp_mont_consttime| variant must be used if the +// exponent is secret. +OPENSSL_EXPORT int BN_mod_exp(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx); + +OPENSSL_EXPORT int BN_mod_exp_mont(BIGNUM *r, const BIGNUM *a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, + const BN_MONT_CTX *mont); + +OPENSSL_EXPORT int BN_mod_exp_mont_consttime(BIGNUM *rr, const BIGNUM *a, + const BIGNUM *p, const BIGNUM *m, + BN_CTX *ctx, + const BN_MONT_CTX *mont); + + +// Deprecated functions + +// BN_bn2mpi serialises the value of |in| to |out|, using a format that consists +// of the number's length in bytes represented as a 4-byte big-endian number, +// and the number itself in big-endian format, where the most significant bit +// signals a negative number. (The representation of numbers with the MSB set is +// prefixed with null byte). |out| must have sufficient space available; to +// find the needed amount of space, call the function with |out| set to NULL. +OPENSSL_EXPORT size_t BN_bn2mpi(const BIGNUM *in, uint8_t *out); + +// BN_mpi2bn parses |len| bytes from |in| and returns the resulting value. The +// bytes at |in| are expected to be in the format emitted by |BN_bn2mpi|. +// +// If |out| is NULL then a fresh |BIGNUM| is allocated and returned, otherwise +// |out| is reused and returned. On error, NULL is returned and the error queue +// is updated. +OPENSSL_EXPORT BIGNUM *BN_mpi2bn(const uint8_t *in, size_t len, BIGNUM *out); + +// BN_mod_exp_mont_word is like |BN_mod_exp_mont| except that the base |a| is +// given as a |BN_ULONG| instead of a |BIGNUM *|. It returns one on success +// or zero otherwise. +OPENSSL_EXPORT int BN_mod_exp_mont_word(BIGNUM *r, BN_ULONG a, const BIGNUM *p, + const BIGNUM *m, BN_CTX *ctx, + const BN_MONT_CTX *mont); + +// BN_mod_exp2_mont calculates (a1^p1) * (a2^p2) mod m. It returns 1 on success +// or zero otherwise. +OPENSSL_EXPORT 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, const BN_MONT_CTX *mont); + +// BN_MONT_CTX_new returns a fresh |BN_MONT_CTX| or NULL on allocation failure. +// Use |BN_MONT_CTX_new_for_modulus| instead. +OPENSSL_EXPORT BN_MONT_CTX *BN_MONT_CTX_new(void); + +// BN_MONT_CTX_set sets up a Montgomery context given the modulus, |mod|. It +// returns one on success and zero on error. Use |BN_MONT_CTX_new_for_modulus| +// instead. +OPENSSL_EXPORT int BN_MONT_CTX_set(BN_MONT_CTX *mont, const BIGNUM *mod, + BN_CTX *ctx); + + +// Private functions + +struct bignum_st { + // d is a pointer to an array of |width| |BN_BITS2|-bit chunks in + // little-endian order. This stores the absolute value of the number. + BN_ULONG *d; + // width is the number of elements of |d| which are valid. This value is not + // necessarily minimal; the most-significant words of |d| may be zero. + // |width| determines a potentially loose upper-bound on the absolute value + // of the |BIGNUM|. + // + // Functions taking |BIGNUM| inputs must compute the same answer for all + // possible widths. |bn_minimal_width|, |bn_set_minimal_width|, and other + // helpers may be used to recover the minimal width, provided it is not + // secret. If it is secret, use a different algorithm. Functions may output + // minimal or non-minimal |BIGNUM|s depending on secrecy requirements, but + // those which cause widths to unboundedly grow beyond the minimal value + // should be documented such. + // + // Note this is different from historical |BIGNUM| semantics. + int width; + // dmax is number of elements of |d| which are allocated. + int dmax; + // neg is one if the number if negative and zero otherwise. + int neg; + // flags is a bitmask of |BN_FLG_*| values + int flags; +}; + +struct bn_mont_ctx_st { + // RR is R^2, reduced modulo |N|. It is used to convert to Montgomery form. + BIGNUM RR; + // N is the modulus. It is always stored in minimal form, so |N.top| + // determines R. + BIGNUM N; + BN_ULONG n0[2]; // least significant words of (R*Ri-1)/N +}; + +OPENSSL_EXPORT unsigned BN_num_bits_word(BN_ULONG l); + +#define BN_FLG_MALLOCED 0x01 +#define BN_FLG_STATIC_DATA 0x02 +// |BN_FLG_CONSTTIME| has been removed and intentionally omitted so code relying +// on it will not compile. Consumers outside BoringSSL should use the +// higher-level cryptographic algorithms exposed by other modules. Consumers +// within the library should call the appropriate timing-sensitive algorithm +// directly. + + +#if defined(__cplusplus) +} // extern C + +#if !defined(BORINGSSL_NO_CXX) +extern "C++" { + +namespace bssl { + +BORINGSSL_MAKE_DELETER(BIGNUM, BN_free) +BORINGSSL_MAKE_DELETER(BN_CTX, BN_CTX_free) +BORINGSSL_MAKE_DELETER(BN_MONT_CTX, BN_MONT_CTX_free) + +class BN_CTXScope { + public: + BN_CTXScope(BN_CTX *ctx) : ctx_(ctx) { BN_CTX_start(ctx_); } + ~BN_CTXScope() { BN_CTX_end(ctx_); } + + private: + BN_CTX *ctx_; + + BN_CTXScope(BN_CTXScope &) = delete; + BN_CTXScope &operator=(BN_CTXScope &) = delete; +}; + +} // namespace bssl + +} // extern C++ +#endif + +#endif + +#define BN_R_ARG2_LT_ARG3 100 +#define BN_R_BAD_RECIPROCAL 101 +#define BN_R_BIGNUM_TOO_LONG 102 +#define BN_R_BITS_TOO_SMALL 103 +#define BN_R_CALLED_WITH_EVEN_MODULUS 104 +#define BN_R_DIV_BY_ZERO 105 +#define BN_R_EXPAND_ON_STATIC_BIGNUM_DATA 106 +#define BN_R_INPUT_NOT_REDUCED 107 +#define BN_R_INVALID_RANGE 108 +#define BN_R_NEGATIVE_NUMBER 109 +#define BN_R_NOT_A_SQUARE 110 +#define BN_R_NOT_INITIALIZED 111 +#define BN_R_NO_INVERSE 112 +#define BN_R_PRIVATE_KEY_TOO_LARGE 113 +#define BN_R_P_IS_NOT_PRIME 114 +#define BN_R_TOO_MANY_ITERATIONS 115 +#define BN_R_TOO_MANY_TEMPORARY_VARIABLES 116 +#define BN_R_BAD_ENCODING 117 +#define BN_R_ENCODE_ERROR 118 +#define BN_R_INVALID_INPUT 119 + +#endif // OPENSSL_HEADER_BN_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/buf.h b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/buf.h new file mode 100644 index 0000000..b4a8bd5 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/buf.h @@ -0,0 +1,137 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 OPENSSL_HEADER_BUFFER_H +#define OPENSSL_HEADER_BUFFER_H + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// Memory and string functions, see also mem.h. + + +// buf_mem_st (aka |BUF_MEM|) is a generic buffer object used by OpenSSL. +struct buf_mem_st { + size_t length; // current number of bytes + char *data; + size_t max; // size of buffer +}; + +// BUF_MEM_new creates a new BUF_MEM which has no allocated data buffer. +OPENSSL_EXPORT BUF_MEM *BUF_MEM_new(void); + +// BUF_MEM_free frees |buf->data| if needed and then frees |buf| itself. +OPENSSL_EXPORT void BUF_MEM_free(BUF_MEM *buf); + +// BUF_MEM_reserve ensures |buf| has capacity |cap| and allocates memory if +// needed. It returns one on success and zero on error. +OPENSSL_EXPORT int BUF_MEM_reserve(BUF_MEM *buf, size_t cap); + +// BUF_MEM_grow ensures that |buf| has length |len| and allocates memory if +// needed. If the length of |buf| increased, the new bytes are filled with +// zeros. It returns the length of |buf|, or zero if there's an error. +OPENSSL_EXPORT size_t BUF_MEM_grow(BUF_MEM *buf, size_t len); + +// BUF_MEM_grow_clean calls |BUF_MEM_grow|. BoringSSL always zeros memory +// allocated memory on free. +OPENSSL_EXPORT size_t BUF_MEM_grow_clean(BUF_MEM *buf, size_t len); + +// BUF_MEM_append appends |in| to |buf|. It returns one on success and zero on +// error. +OPENSSL_EXPORT int BUF_MEM_append(BUF_MEM *buf, const void *in, size_t len); + +// BUF_strdup returns an allocated, duplicate of |str|. +OPENSSL_EXPORT char *BUF_strdup(const char *str); + +// BUF_strnlen returns the number of characters in |str|, excluding the NUL +// byte, but at most |max_len|. This function never reads more than |max_len| +// bytes from |str|. +OPENSSL_EXPORT size_t BUF_strnlen(const char *str, size_t max_len); + +// BUF_strndup returns an allocated, duplicate of |str|, which is, at most, +// |size| bytes. The result is always NUL terminated. +OPENSSL_EXPORT char *BUF_strndup(const char *str, size_t size); + +// BUF_memdup returns an allocated, duplicate of |size| bytes from |data|. +OPENSSL_EXPORT void *BUF_memdup(const void *data, size_t size); + +// BUF_strlcpy acts like strlcpy(3). +OPENSSL_EXPORT size_t BUF_strlcpy(char *dst, const char *src, size_t dst_size); + +// BUF_strlcat acts like strlcat(3). +OPENSSL_EXPORT size_t BUF_strlcat(char *dst, const char *src, size_t dst_size); + + +#if defined(__cplusplus) +} // extern C + +extern "C++" { + +namespace bssl { + +BORINGSSL_MAKE_DELETER(BUF_MEM, BUF_MEM_free) + +} // namespace bssl + +} // extern C++ + +#endif + +#endif // OPENSSL_HEADER_BUFFER_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/buf.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/buf.h.grpc_back new file mode 100644 index 0000000..3f961b8 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/buf.h.grpc_back @@ -0,0 +1,137 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 OPENSSL_HEADER_BUFFER_H +#define OPENSSL_HEADER_BUFFER_H + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// Memory and string functions, see also mem.h. + + +// buf_mem_st (aka |BUF_MEM|) is a generic buffer object used by OpenSSL. +struct buf_mem_st { + size_t length; // current number of bytes + char *data; + size_t max; // size of buffer +}; + +// BUF_MEM_new creates a new BUF_MEM which has no allocated data buffer. +OPENSSL_EXPORT BUF_MEM *BUF_MEM_new(void); + +// BUF_MEM_free frees |buf->data| if needed and then frees |buf| itself. +OPENSSL_EXPORT void BUF_MEM_free(BUF_MEM *buf); + +// BUF_MEM_reserve ensures |buf| has capacity |cap| and allocates memory if +// needed. It returns one on success and zero on error. +OPENSSL_EXPORT int BUF_MEM_reserve(BUF_MEM *buf, size_t cap); + +// BUF_MEM_grow ensures that |buf| has length |len| and allocates memory if +// needed. If the length of |buf| increased, the new bytes are filled with +// zeros. It returns the length of |buf|, or zero if there's an error. +OPENSSL_EXPORT size_t BUF_MEM_grow(BUF_MEM *buf, size_t len); + +// BUF_MEM_grow_clean calls |BUF_MEM_grow|. BoringSSL always zeros memory +// allocated memory on free. +OPENSSL_EXPORT size_t BUF_MEM_grow_clean(BUF_MEM *buf, size_t len); + +// BUF_MEM_append appends |in| to |buf|. It returns one on success and zero on +// error. +OPENSSL_EXPORT int BUF_MEM_append(BUF_MEM *buf, const void *in, size_t len); + +// BUF_strdup returns an allocated, duplicate of |str|. +OPENSSL_EXPORT char *BUF_strdup(const char *str); + +// BUF_strnlen returns the number of characters in |str|, excluding the NUL +// byte, but at most |max_len|. This function never reads more than |max_len| +// bytes from |str|. +OPENSSL_EXPORT size_t BUF_strnlen(const char *str, size_t max_len); + +// BUF_strndup returns an allocated, duplicate of |str|, which is, at most, +// |size| bytes. The result is always NUL terminated. +OPENSSL_EXPORT char *BUF_strndup(const char *str, size_t size); + +// BUF_memdup returns an allocated, duplicate of |size| bytes from |data|. +OPENSSL_EXPORT void *BUF_memdup(const void *data, size_t size); + +// BUF_strlcpy acts like strlcpy(3). +OPENSSL_EXPORT size_t BUF_strlcpy(char *dst, const char *src, size_t dst_size); + +// BUF_strlcat acts like strlcat(3). +OPENSSL_EXPORT size_t BUF_strlcat(char *dst, const char *src, size_t dst_size); + + +#if defined(__cplusplus) +} // extern C + +extern "C++" { + +namespace bssl { + +BORINGSSL_MAKE_DELETER(BUF_MEM, BUF_MEM_free) + +} // namespace bssl + +} // extern C++ + +#endif + +#endif // OPENSSL_HEADER_BUFFER_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/buffer.h b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/buffer.h new file mode 100644 index 0000000..c6b721c --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/buffer.h @@ -0,0 +1,18 @@ +/* Copyright (c) 2015, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +/* This header is provided in order to make compiling against code that expects + OpenSSL easier. */ + +#include "buf.h" diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/buffer.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/buffer.h.grpc_back new file mode 100644 index 0000000..c6b721c --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/buffer.h.grpc_back @@ -0,0 +1,18 @@ +/* Copyright (c) 2015, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +/* This header is provided in order to make compiling against code that expects + OpenSSL easier. */ + +#include "buf.h" diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/bytestring.h b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/bytestring.h new file mode 100644 index 0000000..1e616b3 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/bytestring.h @@ -0,0 +1,505 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_BYTESTRING_H +#define OPENSSL_HEADER_BYTESTRING_H + +#include + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// Bytestrings are used for parsing and building TLS and ASN.1 messages. +// +// A "CBS" (CRYPTO ByteString) represents a string of bytes in memory and +// provides utility functions for safely parsing length-prefixed structures +// like TLS and ASN.1 from it. +// +// A "CBB" (CRYPTO ByteBuilder) is a memory buffer that grows as needed and +// provides utility functions for building length-prefixed messages. + + +// CRYPTO ByteString + +struct cbs_st { + const uint8_t *data; + size_t len; + +#if !defined(BORINGSSL_NO_CXX) + // Allow implicit conversions to and from bssl::Span. + cbs_st(bssl::Span span) + : data(span.data()), len(span.size()) {} + operator bssl::Span() const { + return bssl::MakeConstSpan(data, len); + } + + // Defining any constructors requires we explicitly default the others. + cbs_st() = default; + cbs_st(const cbs_st &) = default; +#endif +}; + +// CBS_init sets |cbs| to point to |data|. It does not take ownership of +// |data|. +OPENSSL_EXPORT void CBS_init(CBS *cbs, const uint8_t *data, size_t len); + +// CBS_skip advances |cbs| by |len| bytes. It returns one on success and zero +// otherwise. +OPENSSL_EXPORT int CBS_skip(CBS *cbs, size_t len); + +// CBS_data returns a pointer to the contents of |cbs|. +OPENSSL_EXPORT const uint8_t *CBS_data(const CBS *cbs); + +// CBS_len returns the number of bytes remaining in |cbs|. +OPENSSL_EXPORT size_t CBS_len(const CBS *cbs); + +// CBS_stow copies the current contents of |cbs| into |*out_ptr| and +// |*out_len|. If |*out_ptr| is not NULL, the contents are freed with +// OPENSSL_free. It returns one on success and zero on allocation failure. On +// success, |*out_ptr| should be freed with OPENSSL_free. If |cbs| is empty, +// |*out_ptr| will be NULL. +OPENSSL_EXPORT int CBS_stow(const CBS *cbs, uint8_t **out_ptr, size_t *out_len); + +// CBS_strdup copies the current contents of |cbs| into |*out_ptr| as a +// NUL-terminated C string. If |*out_ptr| is not NULL, the contents are freed +// with OPENSSL_free. It returns one on success and zero on allocation +// failure. On success, |*out_ptr| should be freed with OPENSSL_free. +// +// NOTE: If |cbs| contains NUL bytes, the string will be truncated. Call +// |CBS_contains_zero_byte(cbs)| to check for NUL bytes. +OPENSSL_EXPORT int CBS_strdup(const CBS *cbs, char **out_ptr); + +// CBS_contains_zero_byte returns one if the current contents of |cbs| contains +// a NUL byte and zero otherwise. +OPENSSL_EXPORT int CBS_contains_zero_byte(const CBS *cbs); + +// CBS_mem_equal compares the current contents of |cbs| with the |len| bytes +// starting at |data|. If they're equal, it returns one, otherwise zero. If the +// lengths match, it uses a constant-time comparison. +OPENSSL_EXPORT int CBS_mem_equal(const CBS *cbs, const uint8_t *data, + size_t len); + +// CBS_get_u8 sets |*out| to the next uint8_t from |cbs| and advances |cbs|. It +// returns one on success and zero on error. +OPENSSL_EXPORT int CBS_get_u8(CBS *cbs, uint8_t *out); + +// CBS_get_u16 sets |*out| to the next, big-endian uint16_t from |cbs| and +// advances |cbs|. It returns one on success and zero on error. +OPENSSL_EXPORT int CBS_get_u16(CBS *cbs, uint16_t *out); + +// CBS_get_u24 sets |*out| to the next, big-endian 24-bit value from |cbs| and +// advances |cbs|. It returns one on success and zero on error. +OPENSSL_EXPORT int CBS_get_u24(CBS *cbs, uint32_t *out); + +// CBS_get_u32 sets |*out| to the next, big-endian uint32_t value from |cbs| +// and advances |cbs|. It returns one on success and zero on error. +OPENSSL_EXPORT int CBS_get_u32(CBS *cbs, uint32_t *out); + +// CBS_get_last_u8 sets |*out| to the last uint8_t from |cbs| and shortens +// |cbs|. It returns one on success and zero on error. +OPENSSL_EXPORT int CBS_get_last_u8(CBS *cbs, uint8_t *out); + +// CBS_get_bytes sets |*out| to the next |len| bytes from |cbs| and advances +// |cbs|. It returns one on success and zero on error. +OPENSSL_EXPORT int CBS_get_bytes(CBS *cbs, CBS *out, size_t len); + +// CBS_copy_bytes copies the next |len| bytes from |cbs| to |out| and advances +// |cbs|. It returns one on success and zero on error. +OPENSSL_EXPORT int CBS_copy_bytes(CBS *cbs, uint8_t *out, size_t len); + +// CBS_get_u8_length_prefixed sets |*out| to the contents of an 8-bit, +// length-prefixed value from |cbs| and advances |cbs| over it. It returns one +// on success and zero on error. +OPENSSL_EXPORT int CBS_get_u8_length_prefixed(CBS *cbs, CBS *out); + +// CBS_get_u16_length_prefixed sets |*out| to the contents of a 16-bit, +// big-endian, length-prefixed value from |cbs| and advances |cbs| over it. It +// returns one on success and zero on error. +OPENSSL_EXPORT int CBS_get_u16_length_prefixed(CBS *cbs, CBS *out); + +// CBS_get_u24_length_prefixed sets |*out| to the contents of a 24-bit, +// big-endian, length-prefixed value from |cbs| and advances |cbs| over it. It +// returns one on success and zero on error. +OPENSSL_EXPORT int CBS_get_u24_length_prefixed(CBS *cbs, CBS *out); + + +// Parsing ASN.1 + +// The following values are tag numbers for UNIVERSAL elements. +#define CBS_ASN1_BOOLEAN 0x1u +#define CBS_ASN1_INTEGER 0x2u +#define CBS_ASN1_BITSTRING 0x3u +#define CBS_ASN1_OCTETSTRING 0x4u +#define CBS_ASN1_NULL 0x5u +#define CBS_ASN1_OBJECT 0x6u +#define CBS_ASN1_ENUMERATED 0xau +#define CBS_ASN1_UTF8STRING 0xcu +#define CBS_ASN1_SEQUENCE (0x10u | CBS_ASN1_CONSTRUCTED) +#define CBS_ASN1_SET (0x11u | CBS_ASN1_CONSTRUCTED) +#define CBS_ASN1_NUMERICSTRING 0x12u +#define CBS_ASN1_PRINTABLESTRING 0x13u +#define CBS_ASN1_T61STRING 0x14u +#define CBS_ASN1_VIDEOTEXSTRING 0x15u +#define CBS_ASN1_IA5STRING 0x16u +#define CBS_ASN1_UTCTIME 0x17u +#define CBS_ASN1_GENERALIZEDTIME 0x18u +#define CBS_ASN1_GRAPHICSTRING 0x19u +#define CBS_ASN1_VISIBLESTRING 0x1au +#define CBS_ASN1_GENERALSTRING 0x1bu +#define CBS_ASN1_UNIVERSALSTRING 0x1cu +#define CBS_ASN1_BMPSTRING 0x1eu + +// CBS_ASN1_TAG_SHIFT is how much the in-memory representation shifts the class +// and constructed bits from the DER serialization. This allows representing tag +// numbers beyond 31. +// +// Consumers must use the following constants to decompose or assemble tags. +#define CBS_ASN1_TAG_SHIFT 24 + +// CBS_ASN1_CONSTRUCTED may be ORed into a tag to toggle the constructed +// bit. |CBS| and |CBB| APIs consider the constructed bit to be part of the +// tag. +#define CBS_ASN1_CONSTRUCTED (0x20u << CBS_ASN1_TAG_SHIFT) + +// The following values specify the tag class and may be ORed into a tag number +// to produce the final tag. If none is used, the tag will be UNIVERSAL. +#define CBS_ASN1_UNIVERSAL (0u << CBS_ASN1_TAG_SHIFT) +#define CBS_ASN1_APPLICATION (0x40u << CBS_ASN1_TAG_SHIFT) +#define CBS_ASN1_CONTEXT_SPECIFIC (0x80u << CBS_ASN1_TAG_SHIFT) +#define CBS_ASN1_PRIVATE (0xc0u << CBS_ASN1_TAG_SHIFT) + +// CBS_ASN1_CLASS_MASK may be ANDed with a tag to query its class. This will +// give one of the four values above. +#define CBS_ASN1_CLASS_MASK (0xc0u << CBS_ASN1_TAG_SHIFT) + +// CBS_ASN1_TAG_NUMBER_MASK may be ANDed with a tag to query its number. +#define CBS_ASN1_TAG_NUMBER_MASK ((1u << (5 + CBS_ASN1_TAG_SHIFT)) - 1) + +// CBS_get_asn1 sets |*out| to the contents of DER-encoded, ASN.1 element (not +// including tag and length bytes) and advances |cbs| over it. The ASN.1 +// element must match |tag_value|. It returns one on success and zero +// on error. +OPENSSL_EXPORT int CBS_get_asn1(CBS *cbs, CBS *out, unsigned tag_value); + +// CBS_get_asn1_element acts like |CBS_get_asn1| but |out| will include the +// ASN.1 header bytes too. +OPENSSL_EXPORT int CBS_get_asn1_element(CBS *cbs, CBS *out, unsigned tag_value); + +// CBS_peek_asn1_tag looks ahead at the next ASN.1 tag and returns one +// if the next ASN.1 element on |cbs| would have tag |tag_value|. If +// |cbs| is empty or the tag does not match, it returns zero. Note: if +// it returns one, CBS_get_asn1 may still fail if the rest of the +// element is malformed. +OPENSSL_EXPORT int CBS_peek_asn1_tag(const CBS *cbs, unsigned tag_value); + +// CBS_get_any_asn1 sets |*out| to contain the next ASN.1 element from |*cbs| +// (not including tag and length bytes), sets |*out_tag| to the tag number, and +// advances |*cbs|. It returns one on success and zero on error. Either of |out| +// and |out_tag| may be NULL to ignore the value. +OPENSSL_EXPORT int CBS_get_any_asn1(CBS *cbs, CBS *out, unsigned *out_tag); + +// CBS_get_any_asn1_element sets |*out| to contain the next ASN.1 element from +// |*cbs| (including header bytes) and advances |*cbs|. It sets |*out_tag| to +// the tag number and |*out_header_len| to the length of the ASN.1 header. Each +// of |out|, |out_tag|, and |out_header_len| may be NULL to ignore the value. +OPENSSL_EXPORT int CBS_get_any_asn1_element(CBS *cbs, CBS *out, + unsigned *out_tag, + size_t *out_header_len); + +// CBS_get_any_ber_asn1_element acts the same as |CBS_get_any_asn1_element| but +// also allows indefinite-length elements to be returned. In that case, +// |*out_header_len| and |CBS_len(out)| will both be two as only the header is +// returned, otherwise it behaves the same as the previous function. +OPENSSL_EXPORT int CBS_get_any_ber_asn1_element(CBS *cbs, CBS *out, + unsigned *out_tag, + size_t *out_header_len); + +// CBS_get_asn1_uint64 gets an ASN.1 INTEGER from |cbs| using |CBS_get_asn1| +// and sets |*out| to its value. It returns one on success and zero on error, +// where error includes the integer being negative, or too large to represent +// in 64 bits. +OPENSSL_EXPORT int CBS_get_asn1_uint64(CBS *cbs, uint64_t *out); + +// CBS_get_asn1_bool gets an ASN.1 BOOLEAN from |cbs| and sets |*out| to zero +// or one based on its value. It returns one on success or zero on error. +OPENSSL_EXPORT int CBS_get_asn1_bool(CBS *cbs, int *out); + +// CBS_get_optional_asn1 gets an optional explicitly-tagged element from |cbs| +// tagged with |tag| and sets |*out| to its contents, or ignores it if |out| is +// NULL. If present and if |out_present| is not NULL, it sets |*out_present| to +// one, otherwise zero. It returns one on success, whether or not the element +// was present, and zero on decode failure. +OPENSSL_EXPORT int CBS_get_optional_asn1(CBS *cbs, CBS *out, int *out_present, + unsigned tag); + +// CBS_get_optional_asn1_octet_string gets an optional +// explicitly-tagged OCTET STRING from |cbs|. If present, it sets +// |*out| to the string and |*out_present| to one. Otherwise, it sets +// |*out| to empty and |*out_present| to zero. |out_present| may be +// NULL. It returns one on success, whether or not the element was +// present, and zero on decode failure. +OPENSSL_EXPORT int CBS_get_optional_asn1_octet_string(CBS *cbs, CBS *out, + int *out_present, + unsigned tag); + +// CBS_get_optional_asn1_uint64 gets an optional explicitly-tagged +// INTEGER from |cbs|. If present, it sets |*out| to the +// value. Otherwise, it sets |*out| to |default_value|. It returns one +// on success, whether or not the element was present, and zero on +// decode failure. +OPENSSL_EXPORT int CBS_get_optional_asn1_uint64(CBS *cbs, uint64_t *out, + unsigned tag, + uint64_t default_value); + +// CBS_get_optional_asn1_bool gets an optional, explicitly-tagged BOOLEAN from +// |cbs|. If present, it sets |*out| to either zero or one, based on the +// boolean. Otherwise, it sets |*out| to |default_value|. It returns one on +// success, whether or not the element was present, and zero on decode +// failure. +OPENSSL_EXPORT int CBS_get_optional_asn1_bool(CBS *cbs, int *out, unsigned tag, + int default_value); + +// CBS_is_valid_asn1_bitstring returns one if |cbs| is a valid ASN.1 BIT STRING +// and zero otherwise. +OPENSSL_EXPORT int CBS_is_valid_asn1_bitstring(const CBS *cbs); + +// CBS_asn1_bitstring_has_bit returns one if |cbs| is a valid ASN.1 BIT STRING +// and the specified bit is present and set. Otherwise, it returns zero. |bit| +// is indexed starting from zero. +OPENSSL_EXPORT int CBS_asn1_bitstring_has_bit(const CBS *cbs, unsigned bit); + +// CBS_asn1_oid_to_text interprets |cbs| as DER-encoded ASN.1 OBJECT IDENTIFIER +// contents (not including the element framing) and returns the ASCII +// representation (e.g., "1.2.840.113554.4.1.72585") in a newly-allocated +// string, or NULL on failure. The caller must release the result with +// |OPENSSL_free|. +OPENSSL_EXPORT char *CBS_asn1_oid_to_text(const CBS *cbs); + + +// CRYPTO ByteBuilder. +// +// |CBB| objects allow one to build length-prefixed serialisations. A |CBB| +// object is associated with a buffer and new buffers are created with +// |CBB_init|. Several |CBB| objects can point at the same buffer when a +// length-prefix is pending, however only a single |CBB| can be 'current' at +// any one time. For example, if one calls |CBB_add_u8_length_prefixed| then +// the new |CBB| points at the same buffer as the original. But if the original +// |CBB| is used then the length prefix is written out and the new |CBB| must +// not be used again. +// +// If one needs to force a length prefix to be written out because a |CBB| is +// going out of scope, use |CBB_flush|. If an operation on a |CBB| fails, it is +// in an undefined state and must not be used except to call |CBB_cleanup|. + +struct cbb_buffer_st { + uint8_t *buf; + size_t len; // The number of valid bytes. + size_t cap; // The size of buf. + char can_resize; /* One iff |buf| is owned by this object. If not then |buf| + cannot be resized. */ + char error; /* One iff there was an error writing to this CBB. All future + operations will fail. */ +}; + +struct cbb_st { + struct cbb_buffer_st *base; + // child points to a child CBB if a length-prefix is pending. + CBB *child; + // offset is the number of bytes from the start of |base->buf| to this |CBB|'s + // pending length prefix. + size_t offset; + // pending_len_len contains the number of bytes in this |CBB|'s pending + // length-prefix, or zero if no length-prefix is pending. + uint8_t pending_len_len; + char pending_is_asn1; + // is_top_level is true iff this is a top-level |CBB| (as opposed to a child + // |CBB|). Top-level objects are valid arguments for |CBB_finish|. + char is_top_level; +}; + +// CBB_zero sets an uninitialised |cbb| to the zero state. It must be +// initialised with |CBB_init| or |CBB_init_fixed| before use, but it is safe to +// call |CBB_cleanup| without a successful |CBB_init|. This may be used for more +// uniform cleanup of a |CBB|. +OPENSSL_EXPORT void CBB_zero(CBB *cbb); + +// CBB_init initialises |cbb| with |initial_capacity|. Since a |CBB| grows as +// needed, the |initial_capacity| is just a hint. It returns one on success or +// zero on error. +OPENSSL_EXPORT int CBB_init(CBB *cbb, size_t initial_capacity); + +// CBB_init_fixed initialises |cbb| to write to |len| bytes at |buf|. Since +// |buf| cannot grow, trying to write more than |len| bytes will cause CBB +// functions to fail. It returns one on success or zero on error. +OPENSSL_EXPORT int CBB_init_fixed(CBB *cbb, uint8_t *buf, size_t len); + +// CBB_cleanup frees all resources owned by |cbb| and other |CBB| objects +// writing to the same buffer. This should be used in an error case where a +// serialisation is abandoned. +// +// This function can only be called on a "top level" |CBB|, i.e. one initialised +// with |CBB_init| or |CBB_init_fixed|, or a |CBB| set to the zero state with +// |CBB_zero|. +OPENSSL_EXPORT void CBB_cleanup(CBB *cbb); + +// CBB_finish completes any pending length prefix and sets |*out_data| to a +// malloced buffer and |*out_len| to the length of that buffer. The caller +// takes ownership of the buffer and, unless the buffer was fixed with +// |CBB_init_fixed|, must call |OPENSSL_free| when done. +// +// It can only be called on a "top level" |CBB|, i.e. one initialised with +// |CBB_init| or |CBB_init_fixed|. It returns one on success and zero on +// error. +OPENSSL_EXPORT int CBB_finish(CBB *cbb, uint8_t **out_data, size_t *out_len); + +// CBB_flush causes any pending length prefixes to be written out and any child +// |CBB| objects of |cbb| to be invalidated. This allows |cbb| to continue to be +// used after the children go out of scope, e.g. when local |CBB| objects are +// added as children to a |CBB| that persists after a function returns. This +// function returns one on success or zero on error. +OPENSSL_EXPORT int CBB_flush(CBB *cbb); + +// CBB_data returns a pointer to the bytes written to |cbb|. It does not flush +// |cbb|. The pointer is valid until the next operation to |cbb|. +// +// To avoid unfinalized length prefixes, it is a fatal error to call this on a +// CBB with any active children. +OPENSSL_EXPORT const uint8_t *CBB_data(const CBB *cbb); + +// CBB_len returns the number of bytes written to |cbb|. It does not flush +// |cbb|. +// +// To avoid unfinalized length prefixes, it is a fatal error to call this on a +// CBB with any active children. +OPENSSL_EXPORT size_t CBB_len(const CBB *cbb); + +// CBB_add_u8_length_prefixed sets |*out_contents| to a new child of |cbb|. The +// data written to |*out_contents| will be prefixed in |cbb| with an 8-bit +// length. It returns one on success or zero on error. +OPENSSL_EXPORT int CBB_add_u8_length_prefixed(CBB *cbb, CBB *out_contents); + +// CBB_add_u16_length_prefixed sets |*out_contents| to a new child of |cbb|. +// The data written to |*out_contents| will be prefixed in |cbb| with a 16-bit, +// big-endian length. It returns one on success or zero on error. +OPENSSL_EXPORT int CBB_add_u16_length_prefixed(CBB *cbb, CBB *out_contents); + +// CBB_add_u24_length_prefixed sets |*out_contents| to a new child of |cbb|. +// The data written to |*out_contents| will be prefixed in |cbb| with a 24-bit, +// big-endian length. It returns one on success or zero on error. +OPENSSL_EXPORT int CBB_add_u24_length_prefixed(CBB *cbb, CBB *out_contents); + +// CBB_add_asn1 sets |*out_contents| to a |CBB| into which the contents of an +// ASN.1 object can be written. The |tag| argument will be used as the tag for +// the object. It returns one on success or zero on error. +OPENSSL_EXPORT int CBB_add_asn1(CBB *cbb, CBB *out_contents, unsigned tag); + +// CBB_add_bytes appends |len| bytes from |data| to |cbb|. It returns one on +// success and zero otherwise. +OPENSSL_EXPORT int CBB_add_bytes(CBB *cbb, const uint8_t *data, size_t len); + +// CBB_add_space appends |len| bytes to |cbb| and sets |*out_data| to point to +// the beginning of that space. The caller must then write |len| bytes of +// actual contents to |*out_data|. It returns one on success and zero +// otherwise. +OPENSSL_EXPORT int CBB_add_space(CBB *cbb, uint8_t **out_data, size_t len); + +// CBB_reserve ensures |cbb| has room for |len| additional bytes and sets +// |*out_data| to point to the beginning of that space. It returns one on +// success and zero otherwise. The caller may write up to |len| bytes to +// |*out_data| and call |CBB_did_write| to complete the write. |*out_data| is +// valid until the next operation on |cbb| or an ancestor |CBB|. +OPENSSL_EXPORT int CBB_reserve(CBB *cbb, uint8_t **out_data, size_t len); + +// CBB_did_write advances |cbb| by |len| bytes, assuming the space has been +// written to by the caller. It returns one on success and zero on error. +OPENSSL_EXPORT int CBB_did_write(CBB *cbb, size_t len); + +// CBB_add_u8 appends an 8-bit number from |value| to |cbb|. It returns one on +// success and zero otherwise. +OPENSSL_EXPORT int CBB_add_u8(CBB *cbb, uint8_t value); + +// CBB_add_u16 appends a 16-bit, big-endian number from |value| to |cbb|. It +// returns one on success and zero otherwise. +OPENSSL_EXPORT int CBB_add_u16(CBB *cbb, uint16_t value); + +// CBB_add_u24 appends a 24-bit, big-endian number from |value| to |cbb|. It +// returns one on success and zero otherwise. +OPENSSL_EXPORT int CBB_add_u24(CBB *cbb, uint32_t value); + +// CBB_add_u32 appends a 32-bit, big-endian number from |value| to |cbb|. It +// returns one on success and zero otherwise. +OPENSSL_EXPORT int CBB_add_u32(CBB *cbb, uint32_t value); + +// CBB_discard_child discards the current unflushed child of |cbb|. Neither the +// child's contents nor the length prefix will be included in the output. +OPENSSL_EXPORT void CBB_discard_child(CBB *cbb); + +// CBB_add_asn1_uint64 writes an ASN.1 INTEGER into |cbb| using |CBB_add_asn1| +// and writes |value| in its contents. It returns one on success and zero on +// error. +OPENSSL_EXPORT int CBB_add_asn1_uint64(CBB *cbb, uint64_t value); + +// CBB_add_asn1_octet_string writes an ASN.1 OCTET STRING into |cbb| with the +// given contents. It returns one on success and zero on error. +OPENSSL_EXPORT int CBB_add_asn1_octet_string(CBB *cbb, const uint8_t *data, + size_t data_len); + +// CBB_add_asn1_bool writes an ASN.1 BOOLEAN into |cbb| which is true iff +// |value| is non-zero. It returns one on success and zero on error. +OPENSSL_EXPORT int CBB_add_asn1_bool(CBB *cbb, int value); + +// CBB_add_asn1_oid_from_text decodes |len| bytes from |text| as an ASCII OID +// representation, e.g. "1.2.840.113554.4.1.72585", and writes the DER-encoded +// contents to |cbb|. It returns one on success and zero on malloc failure or if +// |text| was invalid. It does not include the OBJECT IDENTIFER framing, only +// the element's contents. +// +// This function considers OID strings with components which do not fit in a +// |uint64_t| to be invalid. +OPENSSL_EXPORT int CBB_add_asn1_oid_from_text(CBB *cbb, const char *text, + size_t len); + +// CBB_flush_asn1_set_of calls |CBB_flush| on |cbb| and then reorders the +// contents for a DER-encoded ASN.1 SET OF type. It returns one on success and +// zero on failure. DER canonicalizes SET OF contents by sorting +// lexicographically by encoding. Call this function when encoding a SET OF +// type in an order that is not already known to be canonical. +// +// Note a SET type has a slightly different ordering than a SET OF. +OPENSSL_EXPORT int CBB_flush_asn1_set_of(CBB *cbb); + + +#if defined(__cplusplus) +} // extern C + + +#if !defined(BORINGSSL_NO_CXX) +extern "C++" { + +namespace bssl { + +using ScopedCBB = internal::StackAllocated; + +} // namespace bssl + +} // extern C++ +#endif + +#endif + +#endif // OPENSSL_HEADER_BYTESTRING_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/bytestring.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/bytestring.h.grpc_back new file mode 100644 index 0000000..6ed1644 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/bytestring.h.grpc_back @@ -0,0 +1,505 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_BYTESTRING_H +#define OPENSSL_HEADER_BYTESTRING_H + +#include + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// Bytestrings are used for parsing and building TLS and ASN.1 messages. +// +// A "CBS" (CRYPTO ByteString) represents a string of bytes in memory and +// provides utility functions for safely parsing length-prefixed structures +// like TLS and ASN.1 from it. +// +// A "CBB" (CRYPTO ByteBuilder) is a memory buffer that grows as needed and +// provides utility functions for building length-prefixed messages. + + +// CRYPTO ByteString + +struct cbs_st { + const uint8_t *data; + size_t len; + +#if !defined(BORINGSSL_NO_CXX) + // Allow implicit conversions to and from bssl::Span. + cbs_st(bssl::Span span) + : data(span.data()), len(span.size()) {} + operator bssl::Span() const { + return bssl::MakeConstSpan(data, len); + } + + // Defining any constructors requires we explicitly default the others. + cbs_st() = default; + cbs_st(const cbs_st &) = default; +#endif +}; + +// CBS_init sets |cbs| to point to |data|. It does not take ownership of +// |data|. +OPENSSL_EXPORT void CBS_init(CBS *cbs, const uint8_t *data, size_t len); + +// CBS_skip advances |cbs| by |len| bytes. It returns one on success and zero +// otherwise. +OPENSSL_EXPORT int CBS_skip(CBS *cbs, size_t len); + +// CBS_data returns a pointer to the contents of |cbs|. +OPENSSL_EXPORT const uint8_t *CBS_data(const CBS *cbs); + +// CBS_len returns the number of bytes remaining in |cbs|. +OPENSSL_EXPORT size_t CBS_len(const CBS *cbs); + +// CBS_stow copies the current contents of |cbs| into |*out_ptr| and +// |*out_len|. If |*out_ptr| is not NULL, the contents are freed with +// OPENSSL_free. It returns one on success and zero on allocation failure. On +// success, |*out_ptr| should be freed with OPENSSL_free. If |cbs| is empty, +// |*out_ptr| will be NULL. +OPENSSL_EXPORT int CBS_stow(const CBS *cbs, uint8_t **out_ptr, size_t *out_len); + +// CBS_strdup copies the current contents of |cbs| into |*out_ptr| as a +// NUL-terminated C string. If |*out_ptr| is not NULL, the contents are freed +// with OPENSSL_free. It returns one on success and zero on allocation +// failure. On success, |*out_ptr| should be freed with OPENSSL_free. +// +// NOTE: If |cbs| contains NUL bytes, the string will be truncated. Call +// |CBS_contains_zero_byte(cbs)| to check for NUL bytes. +OPENSSL_EXPORT int CBS_strdup(const CBS *cbs, char **out_ptr); + +// CBS_contains_zero_byte returns one if the current contents of |cbs| contains +// a NUL byte and zero otherwise. +OPENSSL_EXPORT int CBS_contains_zero_byte(const CBS *cbs); + +// CBS_mem_equal compares the current contents of |cbs| with the |len| bytes +// starting at |data|. If they're equal, it returns one, otherwise zero. If the +// lengths match, it uses a constant-time comparison. +OPENSSL_EXPORT int CBS_mem_equal(const CBS *cbs, const uint8_t *data, + size_t len); + +// CBS_get_u8 sets |*out| to the next uint8_t from |cbs| and advances |cbs|. It +// returns one on success and zero on error. +OPENSSL_EXPORT int CBS_get_u8(CBS *cbs, uint8_t *out); + +// CBS_get_u16 sets |*out| to the next, big-endian uint16_t from |cbs| and +// advances |cbs|. It returns one on success and zero on error. +OPENSSL_EXPORT int CBS_get_u16(CBS *cbs, uint16_t *out); + +// CBS_get_u24 sets |*out| to the next, big-endian 24-bit value from |cbs| and +// advances |cbs|. It returns one on success and zero on error. +OPENSSL_EXPORT int CBS_get_u24(CBS *cbs, uint32_t *out); + +// CBS_get_u32 sets |*out| to the next, big-endian uint32_t value from |cbs| +// and advances |cbs|. It returns one on success and zero on error. +OPENSSL_EXPORT int CBS_get_u32(CBS *cbs, uint32_t *out); + +// CBS_get_last_u8 sets |*out| to the last uint8_t from |cbs| and shortens +// |cbs|. It returns one on success and zero on error. +OPENSSL_EXPORT int CBS_get_last_u8(CBS *cbs, uint8_t *out); + +// CBS_get_bytes sets |*out| to the next |len| bytes from |cbs| and advances +// |cbs|. It returns one on success and zero on error. +OPENSSL_EXPORT int CBS_get_bytes(CBS *cbs, CBS *out, size_t len); + +// CBS_copy_bytes copies the next |len| bytes from |cbs| to |out| and advances +// |cbs|. It returns one on success and zero on error. +OPENSSL_EXPORT int CBS_copy_bytes(CBS *cbs, uint8_t *out, size_t len); + +// CBS_get_u8_length_prefixed sets |*out| to the contents of an 8-bit, +// length-prefixed value from |cbs| and advances |cbs| over it. It returns one +// on success and zero on error. +OPENSSL_EXPORT int CBS_get_u8_length_prefixed(CBS *cbs, CBS *out); + +// CBS_get_u16_length_prefixed sets |*out| to the contents of a 16-bit, +// big-endian, length-prefixed value from |cbs| and advances |cbs| over it. It +// returns one on success and zero on error. +OPENSSL_EXPORT int CBS_get_u16_length_prefixed(CBS *cbs, CBS *out); + +// CBS_get_u24_length_prefixed sets |*out| to the contents of a 24-bit, +// big-endian, length-prefixed value from |cbs| and advances |cbs| over it. It +// returns one on success and zero on error. +OPENSSL_EXPORT int CBS_get_u24_length_prefixed(CBS *cbs, CBS *out); + + +// Parsing ASN.1 + +// The following values are tag numbers for UNIVERSAL elements. +#define CBS_ASN1_BOOLEAN 0x1u +#define CBS_ASN1_INTEGER 0x2u +#define CBS_ASN1_BITSTRING 0x3u +#define CBS_ASN1_OCTETSTRING 0x4u +#define CBS_ASN1_NULL 0x5u +#define CBS_ASN1_OBJECT 0x6u +#define CBS_ASN1_ENUMERATED 0xau +#define CBS_ASN1_UTF8STRING 0xcu +#define CBS_ASN1_SEQUENCE (0x10u | CBS_ASN1_CONSTRUCTED) +#define CBS_ASN1_SET (0x11u | CBS_ASN1_CONSTRUCTED) +#define CBS_ASN1_NUMERICSTRING 0x12u +#define CBS_ASN1_PRINTABLESTRING 0x13u +#define CBS_ASN1_T61STRING 0x14u +#define CBS_ASN1_VIDEOTEXSTRING 0x15u +#define CBS_ASN1_IA5STRING 0x16u +#define CBS_ASN1_UTCTIME 0x17u +#define CBS_ASN1_GENERALIZEDTIME 0x18u +#define CBS_ASN1_GRAPHICSTRING 0x19u +#define CBS_ASN1_VISIBLESTRING 0x1au +#define CBS_ASN1_GENERALSTRING 0x1bu +#define CBS_ASN1_UNIVERSALSTRING 0x1cu +#define CBS_ASN1_BMPSTRING 0x1eu + +// CBS_ASN1_TAG_SHIFT is how much the in-memory representation shifts the class +// and constructed bits from the DER serialization. This allows representing tag +// numbers beyond 31. +// +// Consumers must use the following constants to decompose or assemble tags. +#define CBS_ASN1_TAG_SHIFT 24 + +// CBS_ASN1_CONSTRUCTED may be ORed into a tag to toggle the constructed +// bit. |CBS| and |CBB| APIs consider the constructed bit to be part of the +// tag. +#define CBS_ASN1_CONSTRUCTED (0x20u << CBS_ASN1_TAG_SHIFT) + +// The following values specify the tag class and may be ORed into a tag number +// to produce the final tag. If none is used, the tag will be UNIVERSAL. +#define CBS_ASN1_UNIVERSAL (0u << CBS_ASN1_TAG_SHIFT) +#define CBS_ASN1_APPLICATION (0x40u << CBS_ASN1_TAG_SHIFT) +#define CBS_ASN1_CONTEXT_SPECIFIC (0x80u << CBS_ASN1_TAG_SHIFT) +#define CBS_ASN1_PRIVATE (0xc0u << CBS_ASN1_TAG_SHIFT) + +// CBS_ASN1_CLASS_MASK may be ANDed with a tag to query its class. This will +// give one of the four values above. +#define CBS_ASN1_CLASS_MASK (0xc0u << CBS_ASN1_TAG_SHIFT) + +// CBS_ASN1_TAG_NUMBER_MASK may be ANDed with a tag to query its number. +#define CBS_ASN1_TAG_NUMBER_MASK ((1u << (5 + CBS_ASN1_TAG_SHIFT)) - 1) + +// CBS_get_asn1 sets |*out| to the contents of DER-encoded, ASN.1 element (not +// including tag and length bytes) and advances |cbs| over it. The ASN.1 +// element must match |tag_value|. It returns one on success and zero +// on error. +OPENSSL_EXPORT int CBS_get_asn1(CBS *cbs, CBS *out, unsigned tag_value); + +// CBS_get_asn1_element acts like |CBS_get_asn1| but |out| will include the +// ASN.1 header bytes too. +OPENSSL_EXPORT int CBS_get_asn1_element(CBS *cbs, CBS *out, unsigned tag_value); + +// CBS_peek_asn1_tag looks ahead at the next ASN.1 tag and returns one +// if the next ASN.1 element on |cbs| would have tag |tag_value|. If +// |cbs| is empty or the tag does not match, it returns zero. Note: if +// it returns one, CBS_get_asn1 may still fail if the rest of the +// element is malformed. +OPENSSL_EXPORT int CBS_peek_asn1_tag(const CBS *cbs, unsigned tag_value); + +// CBS_get_any_asn1 sets |*out| to contain the next ASN.1 element from |*cbs| +// (not including tag and length bytes), sets |*out_tag| to the tag number, and +// advances |*cbs|. It returns one on success and zero on error. Either of |out| +// and |out_tag| may be NULL to ignore the value. +OPENSSL_EXPORT int CBS_get_any_asn1(CBS *cbs, CBS *out, unsigned *out_tag); + +// CBS_get_any_asn1_element sets |*out| to contain the next ASN.1 element from +// |*cbs| (including header bytes) and advances |*cbs|. It sets |*out_tag| to +// the tag number and |*out_header_len| to the length of the ASN.1 header. Each +// of |out|, |out_tag|, and |out_header_len| may be NULL to ignore the value. +OPENSSL_EXPORT int CBS_get_any_asn1_element(CBS *cbs, CBS *out, + unsigned *out_tag, + size_t *out_header_len); + +// CBS_get_any_ber_asn1_element acts the same as |CBS_get_any_asn1_element| but +// also allows indefinite-length elements to be returned. In that case, +// |*out_header_len| and |CBS_len(out)| will both be two as only the header is +// returned, otherwise it behaves the same as the previous function. +OPENSSL_EXPORT int CBS_get_any_ber_asn1_element(CBS *cbs, CBS *out, + unsigned *out_tag, + size_t *out_header_len); + +// CBS_get_asn1_uint64 gets an ASN.1 INTEGER from |cbs| using |CBS_get_asn1| +// and sets |*out| to its value. It returns one on success and zero on error, +// where error includes the integer being negative, or too large to represent +// in 64 bits. +OPENSSL_EXPORT int CBS_get_asn1_uint64(CBS *cbs, uint64_t *out); + +// CBS_get_asn1_bool gets an ASN.1 BOOLEAN from |cbs| and sets |*out| to zero +// or one based on its value. It returns one on success or zero on error. +OPENSSL_EXPORT int CBS_get_asn1_bool(CBS *cbs, int *out); + +// CBS_get_optional_asn1 gets an optional explicitly-tagged element from |cbs| +// tagged with |tag| and sets |*out| to its contents, or ignores it if |out| is +// NULL. If present and if |out_present| is not NULL, it sets |*out_present| to +// one, otherwise zero. It returns one on success, whether or not the element +// was present, and zero on decode failure. +OPENSSL_EXPORT int CBS_get_optional_asn1(CBS *cbs, CBS *out, int *out_present, + unsigned tag); + +// CBS_get_optional_asn1_octet_string gets an optional +// explicitly-tagged OCTET STRING from |cbs|. If present, it sets +// |*out| to the string and |*out_present| to one. Otherwise, it sets +// |*out| to empty and |*out_present| to zero. |out_present| may be +// NULL. It returns one on success, whether or not the element was +// present, and zero on decode failure. +OPENSSL_EXPORT int CBS_get_optional_asn1_octet_string(CBS *cbs, CBS *out, + int *out_present, + unsigned tag); + +// CBS_get_optional_asn1_uint64 gets an optional explicitly-tagged +// INTEGER from |cbs|. If present, it sets |*out| to the +// value. Otherwise, it sets |*out| to |default_value|. It returns one +// on success, whether or not the element was present, and zero on +// decode failure. +OPENSSL_EXPORT int CBS_get_optional_asn1_uint64(CBS *cbs, uint64_t *out, + unsigned tag, + uint64_t default_value); + +// CBS_get_optional_asn1_bool gets an optional, explicitly-tagged BOOLEAN from +// |cbs|. If present, it sets |*out| to either zero or one, based on the +// boolean. Otherwise, it sets |*out| to |default_value|. It returns one on +// success, whether or not the element was present, and zero on decode +// failure. +OPENSSL_EXPORT int CBS_get_optional_asn1_bool(CBS *cbs, int *out, unsigned tag, + int default_value); + +// CBS_is_valid_asn1_bitstring returns one if |cbs| is a valid ASN.1 BIT STRING +// and zero otherwise. +OPENSSL_EXPORT int CBS_is_valid_asn1_bitstring(const CBS *cbs); + +// CBS_asn1_bitstring_has_bit returns one if |cbs| is a valid ASN.1 BIT STRING +// and the specified bit is present and set. Otherwise, it returns zero. |bit| +// is indexed starting from zero. +OPENSSL_EXPORT int CBS_asn1_bitstring_has_bit(const CBS *cbs, unsigned bit); + +// CBS_asn1_oid_to_text interprets |cbs| as DER-encoded ASN.1 OBJECT IDENTIFIER +// contents (not including the element framing) and returns the ASCII +// representation (e.g., "1.2.840.113554.4.1.72585") in a newly-allocated +// string, or NULL on failure. The caller must release the result with +// |OPENSSL_free|. +OPENSSL_EXPORT char *CBS_asn1_oid_to_text(const CBS *cbs); + + +// CRYPTO ByteBuilder. +// +// |CBB| objects allow one to build length-prefixed serialisations. A |CBB| +// object is associated with a buffer and new buffers are created with +// |CBB_init|. Several |CBB| objects can point at the same buffer when a +// length-prefix is pending, however only a single |CBB| can be 'current' at +// any one time. For example, if one calls |CBB_add_u8_length_prefixed| then +// the new |CBB| points at the same buffer as the original. But if the original +// |CBB| is used then the length prefix is written out and the new |CBB| must +// not be used again. +// +// If one needs to force a length prefix to be written out because a |CBB| is +// going out of scope, use |CBB_flush|. If an operation on a |CBB| fails, it is +// in an undefined state and must not be used except to call |CBB_cleanup|. + +struct cbb_buffer_st { + uint8_t *buf; + size_t len; // The number of valid bytes. + size_t cap; // The size of buf. + char can_resize; /* One iff |buf| is owned by this object. If not then |buf| + cannot be resized. */ + char error; /* One iff there was an error writing to this CBB. All future + operations will fail. */ +}; + +struct cbb_st { + struct cbb_buffer_st *base; + // child points to a child CBB if a length-prefix is pending. + CBB *child; + // offset is the number of bytes from the start of |base->buf| to this |CBB|'s + // pending length prefix. + size_t offset; + // pending_len_len contains the number of bytes in this |CBB|'s pending + // length-prefix, or zero if no length-prefix is pending. + uint8_t pending_len_len; + char pending_is_asn1; + // is_top_level is true iff this is a top-level |CBB| (as opposed to a child + // |CBB|). Top-level objects are valid arguments for |CBB_finish|. + char is_top_level; +}; + +// CBB_zero sets an uninitialised |cbb| to the zero state. It must be +// initialised with |CBB_init| or |CBB_init_fixed| before use, but it is safe to +// call |CBB_cleanup| without a successful |CBB_init|. This may be used for more +// uniform cleanup of a |CBB|. +OPENSSL_EXPORT void CBB_zero(CBB *cbb); + +// CBB_init initialises |cbb| with |initial_capacity|. Since a |CBB| grows as +// needed, the |initial_capacity| is just a hint. It returns one on success or +// zero on error. +OPENSSL_EXPORT int CBB_init(CBB *cbb, size_t initial_capacity); + +// CBB_init_fixed initialises |cbb| to write to |len| bytes at |buf|. Since +// |buf| cannot grow, trying to write more than |len| bytes will cause CBB +// functions to fail. It returns one on success or zero on error. +OPENSSL_EXPORT int CBB_init_fixed(CBB *cbb, uint8_t *buf, size_t len); + +// CBB_cleanup frees all resources owned by |cbb| and other |CBB| objects +// writing to the same buffer. This should be used in an error case where a +// serialisation is abandoned. +// +// This function can only be called on a "top level" |CBB|, i.e. one initialised +// with |CBB_init| or |CBB_init_fixed|, or a |CBB| set to the zero state with +// |CBB_zero|. +OPENSSL_EXPORT void CBB_cleanup(CBB *cbb); + +// CBB_finish completes any pending length prefix and sets |*out_data| to a +// malloced buffer and |*out_len| to the length of that buffer. The caller +// takes ownership of the buffer and, unless the buffer was fixed with +// |CBB_init_fixed|, must call |OPENSSL_free| when done. +// +// It can only be called on a "top level" |CBB|, i.e. one initialised with +// |CBB_init| or |CBB_init_fixed|. It returns one on success and zero on +// error. +OPENSSL_EXPORT int CBB_finish(CBB *cbb, uint8_t **out_data, size_t *out_len); + +// CBB_flush causes any pending length prefixes to be written out and any child +// |CBB| objects of |cbb| to be invalidated. This allows |cbb| to continue to be +// used after the children go out of scope, e.g. when local |CBB| objects are +// added as children to a |CBB| that persists after a function returns. This +// function returns one on success or zero on error. +OPENSSL_EXPORT int CBB_flush(CBB *cbb); + +// CBB_data returns a pointer to the bytes written to |cbb|. It does not flush +// |cbb|. The pointer is valid until the next operation to |cbb|. +// +// To avoid unfinalized length prefixes, it is a fatal error to call this on a +// CBB with any active children. +OPENSSL_EXPORT const uint8_t *CBB_data(const CBB *cbb); + +// CBB_len returns the number of bytes written to |cbb|. It does not flush +// |cbb|. +// +// To avoid unfinalized length prefixes, it is a fatal error to call this on a +// CBB with any active children. +OPENSSL_EXPORT size_t CBB_len(const CBB *cbb); + +// CBB_add_u8_length_prefixed sets |*out_contents| to a new child of |cbb|. The +// data written to |*out_contents| will be prefixed in |cbb| with an 8-bit +// length. It returns one on success or zero on error. +OPENSSL_EXPORT int CBB_add_u8_length_prefixed(CBB *cbb, CBB *out_contents); + +// CBB_add_u16_length_prefixed sets |*out_contents| to a new child of |cbb|. +// The data written to |*out_contents| will be prefixed in |cbb| with a 16-bit, +// big-endian length. It returns one on success or zero on error. +OPENSSL_EXPORT int CBB_add_u16_length_prefixed(CBB *cbb, CBB *out_contents); + +// CBB_add_u24_length_prefixed sets |*out_contents| to a new child of |cbb|. +// The data written to |*out_contents| will be prefixed in |cbb| with a 24-bit, +// big-endian length. It returns one on success or zero on error. +OPENSSL_EXPORT int CBB_add_u24_length_prefixed(CBB *cbb, CBB *out_contents); + +// CBB_add_asn1 sets |*out_contents| to a |CBB| into which the contents of an +// ASN.1 object can be written. The |tag| argument will be used as the tag for +// the object. It returns one on success or zero on error. +OPENSSL_EXPORT int CBB_add_asn1(CBB *cbb, CBB *out_contents, unsigned tag); + +// CBB_add_bytes appends |len| bytes from |data| to |cbb|. It returns one on +// success and zero otherwise. +OPENSSL_EXPORT int CBB_add_bytes(CBB *cbb, const uint8_t *data, size_t len); + +// CBB_add_space appends |len| bytes to |cbb| and sets |*out_data| to point to +// the beginning of that space. The caller must then write |len| bytes of +// actual contents to |*out_data|. It returns one on success and zero +// otherwise. +OPENSSL_EXPORT int CBB_add_space(CBB *cbb, uint8_t **out_data, size_t len); + +// CBB_reserve ensures |cbb| has room for |len| additional bytes and sets +// |*out_data| to point to the beginning of that space. It returns one on +// success and zero otherwise. The caller may write up to |len| bytes to +// |*out_data| and call |CBB_did_write| to complete the write. |*out_data| is +// valid until the next operation on |cbb| or an ancestor |CBB|. +OPENSSL_EXPORT int CBB_reserve(CBB *cbb, uint8_t **out_data, size_t len); + +// CBB_did_write advances |cbb| by |len| bytes, assuming the space has been +// written to by the caller. It returns one on success and zero on error. +OPENSSL_EXPORT int CBB_did_write(CBB *cbb, size_t len); + +// CBB_add_u8 appends an 8-bit number from |value| to |cbb|. It returns one on +// success and zero otherwise. +OPENSSL_EXPORT int CBB_add_u8(CBB *cbb, uint8_t value); + +// CBB_add_u16 appends a 16-bit, big-endian number from |value| to |cbb|. It +// returns one on success and zero otherwise. +OPENSSL_EXPORT int CBB_add_u16(CBB *cbb, uint16_t value); + +// CBB_add_u24 appends a 24-bit, big-endian number from |value| to |cbb|. It +// returns one on success and zero otherwise. +OPENSSL_EXPORT int CBB_add_u24(CBB *cbb, uint32_t value); + +// CBB_add_u32 appends a 32-bit, big-endian number from |value| to |cbb|. It +// returns one on success and zero otherwise. +OPENSSL_EXPORT int CBB_add_u32(CBB *cbb, uint32_t value); + +// CBB_discard_child discards the current unflushed child of |cbb|. Neither the +// child's contents nor the length prefix will be included in the output. +OPENSSL_EXPORT void CBB_discard_child(CBB *cbb); + +// CBB_add_asn1_uint64 writes an ASN.1 INTEGER into |cbb| using |CBB_add_asn1| +// and writes |value| in its contents. It returns one on success and zero on +// error. +OPENSSL_EXPORT int CBB_add_asn1_uint64(CBB *cbb, uint64_t value); + +// CBB_add_asn1_octet_string writes an ASN.1 OCTET STRING into |cbb| with the +// given contents. It returns one on success and zero on error. +OPENSSL_EXPORT int CBB_add_asn1_octet_string(CBB *cbb, const uint8_t *data, + size_t data_len); + +// CBB_add_asn1_bool writes an ASN.1 BOOLEAN into |cbb| which is true iff +// |value| is non-zero. It returns one on success and zero on error. +OPENSSL_EXPORT int CBB_add_asn1_bool(CBB *cbb, int value); + +// CBB_add_asn1_oid_from_text decodes |len| bytes from |text| as an ASCII OID +// representation, e.g. "1.2.840.113554.4.1.72585", and writes the DER-encoded +// contents to |cbb|. It returns one on success and zero on malloc failure or if +// |text| was invalid. It does not include the OBJECT IDENTIFER framing, only +// the element's contents. +// +// This function considers OID strings with components which do not fit in a +// |uint64_t| to be invalid. +OPENSSL_EXPORT int CBB_add_asn1_oid_from_text(CBB *cbb, const char *text, + size_t len); + +// CBB_flush_asn1_set_of calls |CBB_flush| on |cbb| and then reorders the +// contents for a DER-encoded ASN.1 SET OF type. It returns one on success and +// zero on failure. DER canonicalizes SET OF contents by sorting +// lexicographically by encoding. Call this function when encoding a SET OF +// type in an order that is not already known to be canonical. +// +// Note a SET type has a slightly different ordering than a SET OF. +OPENSSL_EXPORT int CBB_flush_asn1_set_of(CBB *cbb); + + +#if defined(__cplusplus) +} // extern C + + +#if !defined(BORINGSSL_NO_CXX) +extern "C++" { + +namespace bssl { + +using ScopedCBB = internal::StackAllocated; + +} // namespace bssl + +} // extern C++ +#endif + +#endif + +#endif // OPENSSL_HEADER_BYTESTRING_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/cast.h b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/cast.h new file mode 100644 index 0000000..3165f0d --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/cast.h @@ -0,0 +1,96 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 OPENSSL_HEADER_CAST_H +#define OPENSSL_HEADER_CAST_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +#define CAST_ENCRYPT 1 +#define CAST_DECRYPT 0 + +#define CAST_BLOCK 8 +#define CAST_KEY_LENGTH 16 + +typedef struct cast_key_st { + uint32_t data[32]; + int short_key; // Use reduced rounds for short key +} CAST_KEY; + +OPENSSL_EXPORT void CAST_set_key(CAST_KEY *key, size_t len, + const uint8_t *data); +OPENSSL_EXPORT void CAST_ecb_encrypt(const uint8_t *in, uint8_t *out, + const CAST_KEY *key, int enc); +OPENSSL_EXPORT void CAST_encrypt(uint32_t *data, const CAST_KEY *key); +OPENSSL_EXPORT void CAST_decrypt(uint32_t *data, const CAST_KEY *key); +OPENSSL_EXPORT void CAST_cbc_encrypt(const uint8_t *in, uint8_t *out, + long length, const CAST_KEY *ks, + uint8_t *iv, int enc); + +OPENSSL_EXPORT void CAST_cfb64_encrypt(const uint8_t *in, uint8_t *out, + long length, const CAST_KEY *schedule, + uint8_t *ivec, int *num, int enc); + +#ifdef __cplusplus +} +#endif + +#endif // OPENSSL_HEADER_CAST_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/cast.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/cast.h.grpc_back new file mode 100644 index 0000000..2978a67 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/cast.h.grpc_back @@ -0,0 +1,96 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 OPENSSL_HEADER_CAST_H +#define OPENSSL_HEADER_CAST_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +#define CAST_ENCRYPT 1 +#define CAST_DECRYPT 0 + +#define CAST_BLOCK 8 +#define CAST_KEY_LENGTH 16 + +typedef struct cast_key_st { + uint32_t data[32]; + int short_key; // Use reduced rounds for short key +} CAST_KEY; + +OPENSSL_EXPORT void CAST_set_key(CAST_KEY *key, size_t len, + const uint8_t *data); +OPENSSL_EXPORT void CAST_ecb_encrypt(const uint8_t *in, uint8_t *out, + const CAST_KEY *key, int enc); +OPENSSL_EXPORT void CAST_encrypt(uint32_t *data, const CAST_KEY *key); +OPENSSL_EXPORT void CAST_decrypt(uint32_t *data, const CAST_KEY *key); +OPENSSL_EXPORT void CAST_cbc_encrypt(const uint8_t *in, uint8_t *out, + long length, const CAST_KEY *ks, + uint8_t *iv, int enc); + +OPENSSL_EXPORT void CAST_cfb64_encrypt(const uint8_t *in, uint8_t *out, + long length, const CAST_KEY *schedule, + uint8_t *ivec, int *num, int enc); + +#ifdef __cplusplus +} +#endif + +#endif // OPENSSL_HEADER_CAST_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/chacha.h b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/chacha.h new file mode 100644 index 0000000..18a97c3 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/chacha.h @@ -0,0 +1,41 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_CHACHA_H +#define OPENSSL_HEADER_CHACHA_H + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +// ChaCha20. +// +// ChaCha20 is a stream cipher. See https://tools.ietf.org/html/rfc7539. + + +// CRYPTO_chacha_20 encrypts |in_len| bytes from |in| with the given key and +// nonce and writes the result to |out|. If |in| and |out| alias, they must be +// equal. The initial block counter is specified by |counter|. +OPENSSL_EXPORT void CRYPTO_chacha_20(uint8_t *out, const uint8_t *in, + size_t in_len, const uint8_t key[32], + const uint8_t nonce[12], uint32_t counter); + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_CHACHA_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/chacha.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/chacha.h.grpc_back new file mode 100644 index 0000000..684fc5b --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/chacha.h.grpc_back @@ -0,0 +1,41 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_CHACHA_H +#define OPENSSL_HEADER_CHACHA_H + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + +// ChaCha20. +// +// ChaCha20 is a stream cipher. See https://tools.ietf.org/html/rfc7539. + + +// CRYPTO_chacha_20 encrypts |in_len| bytes from |in| with the given key and +// nonce and writes the result to |out|. If |in| and |out| alias, they must be +// equal. The initial block counter is specified by |counter|. +OPENSSL_EXPORT void CRYPTO_chacha_20(uint8_t *out, const uint8_t *in, + size_t in_len, const uint8_t key[32], + const uint8_t nonce[12], uint32_t counter); + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_CHACHA_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/cipher.h b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/cipher.h new file mode 100644 index 0000000..87ed7c0 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/cipher.h @@ -0,0 +1,608 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 OPENSSL_HEADER_CIPHER_H +#define OPENSSL_HEADER_CIPHER_H + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// Ciphers. + + +// Cipher primitives. +// +// The following functions return |EVP_CIPHER| objects that implement the named +// cipher algorithm. + +OPENSSL_EXPORT const EVP_CIPHER *EVP_rc4(void); + +OPENSSL_EXPORT const EVP_CIPHER *EVP_des_cbc(void); +OPENSSL_EXPORT const EVP_CIPHER *EVP_des_ecb(void); +OPENSSL_EXPORT const EVP_CIPHER *EVP_des_ede(void); +OPENSSL_EXPORT const EVP_CIPHER *EVP_des_ede3(void); +OPENSSL_EXPORT const EVP_CIPHER *EVP_des_ede_cbc(void); +OPENSSL_EXPORT const EVP_CIPHER *EVP_des_ede3_cbc(void); + +OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_128_ecb(void); +OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_128_cbc(void); +OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_128_ctr(void); +OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_128_ofb(void); + +OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_256_ecb(void); +OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_256_cbc(void); +OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_256_ctr(void); +OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_256_ofb(void); +OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_256_xts(void); + +// EVP_enc_null returns a 'cipher' that passes plaintext through as +// ciphertext. +OPENSSL_EXPORT const EVP_CIPHER *EVP_enc_null(void); + +// EVP_rc2_cbc returns a cipher that implements 128-bit RC2 in CBC mode. +OPENSSL_EXPORT const EVP_CIPHER *EVP_rc2_cbc(void); + +// EVP_rc2_40_cbc returns a cipher that implements 40-bit RC2 in CBC mode. This +// is obviously very, very weak and is included only in order to read PKCS#12 +// files, which often encrypt the certificate chain using this cipher. It is +// deliberately not exported. +const EVP_CIPHER *EVP_rc2_40_cbc(void); + +// EVP_get_cipherbynid returns the cipher corresponding to the given NID, or +// NULL if no such cipher is known. +OPENSSL_EXPORT const EVP_CIPHER *EVP_get_cipherbynid(int nid); + + +// Cipher context allocation. +// +// An |EVP_CIPHER_CTX| represents the state of an encryption or decryption in +// progress. + +// EVP_CIPHER_CTX_init initialises an, already allocated, |EVP_CIPHER_CTX|. +OPENSSL_EXPORT void EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *ctx); + +// EVP_CIPHER_CTX_new allocates a fresh |EVP_CIPHER_CTX|, calls +// |EVP_CIPHER_CTX_init| and returns it, or NULL on allocation failure. +OPENSSL_EXPORT EVP_CIPHER_CTX *EVP_CIPHER_CTX_new(void); + +// EVP_CIPHER_CTX_cleanup frees any memory referenced by |ctx|. It returns +// one. +OPENSSL_EXPORT int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *ctx); + +// EVP_CIPHER_CTX_free calls |EVP_CIPHER_CTX_cleanup| on |ctx| and then frees +// |ctx| itself. +OPENSSL_EXPORT void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx); + +// EVP_CIPHER_CTX_copy sets |out| to be a duplicate of the current state of +// |in|. The |out| argument must have been previously initialised. +OPENSSL_EXPORT int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, + const EVP_CIPHER_CTX *in); + +// EVP_CIPHER_CTX_reset calls |EVP_CIPHER_CTX_cleanup| followed by +// |EVP_CIPHER_CTX_init|. +OPENSSL_EXPORT void EVP_CIPHER_CTX_reset(EVP_CIPHER_CTX *ctx); + + +// Cipher context configuration. + +// EVP_CipherInit_ex configures |ctx| for a fresh encryption (or decryption, if +// |enc| is zero) operation using |cipher|. If |ctx| has been previously +// configured with a cipher then |cipher|, |key| and |iv| may be |NULL| and +// |enc| may be -1 to reuse the previous values. The operation will use |key| +// as the key and |iv| as the IV (if any). These should have the correct +// lengths given by |EVP_CIPHER_key_length| and |EVP_CIPHER_iv_length|. It +// returns one on success and zero on error. +OPENSSL_EXPORT int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, + const EVP_CIPHER *cipher, ENGINE *engine, + const uint8_t *key, const uint8_t *iv, + int enc); + +// EVP_EncryptInit_ex calls |EVP_CipherInit_ex| with |enc| equal to one. +OPENSSL_EXPORT int EVP_EncryptInit_ex(EVP_CIPHER_CTX *ctx, + const EVP_CIPHER *cipher, ENGINE *impl, + const uint8_t *key, const uint8_t *iv); + +// EVP_DecryptInit_ex calls |EVP_CipherInit_ex| with |enc| equal to zero. +OPENSSL_EXPORT int EVP_DecryptInit_ex(EVP_CIPHER_CTX *ctx, + const EVP_CIPHER *cipher, ENGINE *impl, + const uint8_t *key, const uint8_t *iv); + + +// Cipher operations. + +// EVP_EncryptUpdate encrypts |in_len| bytes from |in| to |out|. The number +// of output bytes may be up to |in_len| plus the block length minus one and +// |out| must have sufficient space. The number of bytes actually output is +// written to |*out_len|. It returns one on success and zero otherwise. +OPENSSL_EXPORT int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, uint8_t *out, + int *out_len, const uint8_t *in, + int in_len); + +// EVP_EncryptFinal_ex writes at most a block of ciphertext to |out| and sets +// |*out_len| to the number of bytes written. If padding is enabled (the +// default) then standard padding is applied to create the final block. If +// padding is disabled (with |EVP_CIPHER_CTX_set_padding|) then any partial +// block remaining will cause an error. The function returns one on success and +// zero otherwise. +OPENSSL_EXPORT int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, uint8_t *out, + int *out_len); + +// EVP_DecryptUpdate decrypts |in_len| bytes from |in| to |out|. The number of +// output bytes may be up to |in_len| plus the block length minus one and |out| +// must have sufficient space. The number of bytes actually output is written +// to |*out_len|. It returns one on success and zero otherwise. +OPENSSL_EXPORT int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, uint8_t *out, + int *out_len, const uint8_t *in, + int in_len); + +// EVP_DecryptFinal_ex writes at most a block of ciphertext to |out| and sets +// |*out_len| to the number of bytes written. If padding is enabled (the +// default) then padding is removed from the final block. +// +// WARNING: it is unsafe to call this function with unauthenticated +// ciphertext if padding is enabled. +OPENSSL_EXPORT int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, + int *out_len); + +// EVP_Cipher performs a one-shot encryption/decryption operation. No partial +// blocks are maintained between calls. However, any internal cipher state is +// still updated. For CBC-mode ciphers, the IV is updated to the final +// ciphertext block. For stream ciphers, the stream is advanced past the bytes +// used. It returns one on success and zero otherwise, unless |EVP_CIPHER_flags| +// has |EVP_CIPH_FLAG_CUSTOM_CIPHER| set. Then it returns the number of bytes +// written or -1 on error. +// +// WARNING: this differs from the usual return value convention when using +// |EVP_CIPH_FLAG_CUSTOM_CIPHER|. +// +// TODO(davidben): The normal ciphers currently never fail, even if, e.g., +// |in_len| is not a multiple of the block size for CBC-mode decryption. The +// input just gets rounded up while the output gets truncated. This should +// either be officially documented or fail. +OPENSSL_EXPORT int EVP_Cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, + const uint8_t *in, size_t in_len); + +// EVP_CipherUpdate calls either |EVP_EncryptUpdate| or |EVP_DecryptUpdate| +// depending on how |ctx| has been setup. +OPENSSL_EXPORT int EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, uint8_t *out, + int *out_len, const uint8_t *in, + int in_len); + +// EVP_CipherFinal_ex calls either |EVP_EncryptFinal_ex| or +// |EVP_DecryptFinal_ex| depending on how |ctx| has been setup. +OPENSSL_EXPORT int EVP_CipherFinal_ex(EVP_CIPHER_CTX *ctx, uint8_t *out, + int *out_len); + + +// Cipher context accessors. + +// EVP_CIPHER_CTX_cipher returns the |EVP_CIPHER| underlying |ctx|, or NULL if +// none has been set. +OPENSSL_EXPORT const EVP_CIPHER *EVP_CIPHER_CTX_cipher( + const EVP_CIPHER_CTX *ctx); + +// EVP_CIPHER_CTX_nid returns a NID identifying the |EVP_CIPHER| underlying +// |ctx| (e.g. |NID_aes_128_gcm|). It will crash if no cipher has been +// configured. +OPENSSL_EXPORT int EVP_CIPHER_CTX_nid(const EVP_CIPHER_CTX *ctx); + +// EVP_CIPHER_CTX_block_size returns the block size, in bytes, of the cipher +// underlying |ctx|, or one if the cipher is a stream cipher. It will crash if +// no cipher has been configured. +OPENSSL_EXPORT unsigned EVP_CIPHER_CTX_block_size(const EVP_CIPHER_CTX *ctx); + +// EVP_CIPHER_CTX_key_length returns the key size, in bytes, of the cipher +// underlying |ctx| or zero if no cipher has been configured. +OPENSSL_EXPORT unsigned EVP_CIPHER_CTX_key_length(const EVP_CIPHER_CTX *ctx); + +// EVP_CIPHER_CTX_iv_length returns the IV size, in bytes, of the cipher +// underlying |ctx|. It will crash if no cipher has been configured. +OPENSSL_EXPORT unsigned EVP_CIPHER_CTX_iv_length(const EVP_CIPHER_CTX *ctx); + +// EVP_CIPHER_CTX_get_app_data returns the opaque, application data pointer for +// |ctx|, or NULL if none has been set. +OPENSSL_EXPORT void *EVP_CIPHER_CTX_get_app_data(const EVP_CIPHER_CTX *ctx); + +// EVP_CIPHER_CTX_set_app_data sets the opaque, application data pointer for +// |ctx| to |data|. +OPENSSL_EXPORT void EVP_CIPHER_CTX_set_app_data(EVP_CIPHER_CTX *ctx, + void *data); + +// EVP_CIPHER_CTX_flags returns a value which is the OR of zero or more +// |EVP_CIPH_*| flags. It will crash if no cipher has been configured. +OPENSSL_EXPORT uint32_t EVP_CIPHER_CTX_flags(const EVP_CIPHER_CTX *ctx); + +// EVP_CIPHER_CTX_mode returns one of the |EVP_CIPH_*| cipher mode values +// enumerated below. It will crash if no cipher has been configured. +OPENSSL_EXPORT uint32_t EVP_CIPHER_CTX_mode(const EVP_CIPHER_CTX *ctx); + +// EVP_CIPHER_CTX_ctrl is an |ioctl| like function. The |command| argument +// should be one of the |EVP_CTRL_*| values. The |arg| and |ptr| arguments are +// specific to the command in question. +OPENSSL_EXPORT int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int command, + int arg, void *ptr); + +// EVP_CIPHER_CTX_set_padding sets whether padding is enabled for |ctx| and +// returns one. Pass a non-zero |pad| to enable padding (the default) or zero +// to disable. +OPENSSL_EXPORT int EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *ctx, int pad); + +// EVP_CIPHER_CTX_set_key_length sets the key length for |ctx|. This is only +// valid for ciphers that can take a variable length key. It returns one on +// success and zero on error. +OPENSSL_EXPORT int EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *ctx, + unsigned key_len); + + +// Cipher accessors. + +// EVP_CIPHER_nid returns a NID identifying |cipher|. (For example, +// |NID_aes_128_gcm|.) +OPENSSL_EXPORT int EVP_CIPHER_nid(const EVP_CIPHER *cipher); + +// EVP_CIPHER_block_size returns the block size, in bytes, for |cipher|, or one +// if |cipher| is a stream cipher. +OPENSSL_EXPORT unsigned EVP_CIPHER_block_size(const EVP_CIPHER *cipher); + +// EVP_CIPHER_key_length returns the key size, in bytes, for |cipher|. If +// |cipher| can take a variable key length then this function returns the +// default key length and |EVP_CIPHER_flags| will return a value with +// |EVP_CIPH_VARIABLE_LENGTH| set. +OPENSSL_EXPORT unsigned EVP_CIPHER_key_length(const EVP_CIPHER *cipher); + +// EVP_CIPHER_iv_length returns the IV size, in bytes, of |cipher|, or zero if +// |cipher| doesn't take an IV. +OPENSSL_EXPORT unsigned EVP_CIPHER_iv_length(const EVP_CIPHER *cipher); + +// EVP_CIPHER_flags returns a value which is the OR of zero or more +// |EVP_CIPH_*| flags. +OPENSSL_EXPORT uint32_t EVP_CIPHER_flags(const EVP_CIPHER *cipher); + +// EVP_CIPHER_mode returns one of the cipher mode values enumerated below. +OPENSSL_EXPORT uint32_t EVP_CIPHER_mode(const EVP_CIPHER *cipher); + + +// Key derivation. + +// EVP_BytesToKey generates a key and IV for the cipher |type| by iterating +// |md| |count| times using |data| and |salt|. On entry, the |key| and |iv| +// buffers must have enough space to hold a key and IV for |type|. It returns +// the length of the key on success or zero on error. +OPENSSL_EXPORT int EVP_BytesToKey(const EVP_CIPHER *type, const EVP_MD *md, + const uint8_t *salt, const uint8_t *data, + size_t data_len, unsigned count, uint8_t *key, + uint8_t *iv); + + +// Cipher modes (for |EVP_CIPHER_mode|). + +#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_XTS_MODE 0x7 + + +// Cipher flags (for |EVP_CIPHER_flags|). + +// EVP_CIPH_VARIABLE_LENGTH indicates that the cipher takes a variable length +// key. +#define EVP_CIPH_VARIABLE_LENGTH 0x40 + +// EVP_CIPH_ALWAYS_CALL_INIT indicates that the |init| function for the cipher +// should always be called when initialising a new operation, even if the key +// is NULL to indicate that the same key is being used. +#define EVP_CIPH_ALWAYS_CALL_INIT 0x80 + +// EVP_CIPH_CUSTOM_IV indicates that the cipher manages the IV itself rather +// than keeping it in the |iv| member of |EVP_CIPHER_CTX|. +#define EVP_CIPH_CUSTOM_IV 0x100 + +// EVP_CIPH_CTRL_INIT indicates that EVP_CTRL_INIT should be used when +// initialising an |EVP_CIPHER_CTX|. +#define EVP_CIPH_CTRL_INIT 0x200 + +// EVP_CIPH_FLAG_CUSTOM_CIPHER indicates that the cipher manages blocking +// itself. This causes EVP_(En|De)crypt_ex to be simple wrapper functions. +#define EVP_CIPH_FLAG_CUSTOM_CIPHER 0x400 + +// EVP_CIPH_FLAG_AEAD_CIPHER specifies that the cipher is an AEAD. This is an +// older version of the proper AEAD interface. See aead.h for the current +// one. +#define EVP_CIPH_FLAG_AEAD_CIPHER 0x800 + +// EVP_CIPH_CUSTOM_COPY indicates that the |ctrl| callback should be called +// with |EVP_CTRL_COPY| at the end of normal |EVP_CIPHER_CTX_copy| +// processing. +#define EVP_CIPH_CUSTOM_COPY 0x1000 + + +// Deprecated functions + +// EVP_CipherInit acts like EVP_CipherInit_ex except that |EVP_CIPHER_CTX_init| +// is called on |cipher| first, if |cipher| is not NULL. +OPENSSL_EXPORT int EVP_CipherInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + const uint8_t *key, const uint8_t *iv, + int enc); + +// EVP_EncryptInit calls |EVP_CipherInit| with |enc| equal to one. +OPENSSL_EXPORT int EVP_EncryptInit(EVP_CIPHER_CTX *ctx, + const EVP_CIPHER *cipher, const uint8_t *key, + const uint8_t *iv); + +// EVP_DecryptInit calls |EVP_CipherInit| with |enc| equal to zero. +OPENSSL_EXPORT int EVP_DecryptInit(EVP_CIPHER_CTX *ctx, + const EVP_CIPHER *cipher, const uint8_t *key, + const uint8_t *iv); + +// EVP_add_cipher_alias does nothing and returns one. +OPENSSL_EXPORT int EVP_add_cipher_alias(const char *a, const char *b); + +// EVP_get_cipherbyname returns an |EVP_CIPHER| given a human readable name in +// |name|, or NULL if the name is unknown. +OPENSSL_EXPORT const EVP_CIPHER *EVP_get_cipherbyname(const char *name); + +// These AEADs are deprecated AES-GCM implementations that set +// |EVP_CIPH_FLAG_CUSTOM_CIPHER|. Use |EVP_aead_aes_128_gcm| and +// |EVP_aead_aes_256_gcm| instead. +OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_128_gcm(void); +OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_256_gcm(void); + +// These are deprecated, 192-bit version of AES. +OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_192_ecb(void); +OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_192_cbc(void); +OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_192_ctr(void); +OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_192_gcm(void); + +// EVP_aes_128_cfb128 is only available in decrepit. +OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_128_cfb128(void); + +// The following flags do nothing and are included only to make it easier to +// compile code with BoringSSL. +#define EVP_CIPH_CCM_MODE 0 +#define EVP_CIPH_WRAP_MODE 0 +#define EVP_CIPHER_CTX_FLAG_WRAP_ALLOW 0 + +// EVP_CIPHER_CTX_set_flags does nothing. +OPENSSL_EXPORT void EVP_CIPHER_CTX_set_flags(const EVP_CIPHER_CTX *ctx, + uint32_t flags); + + +// Private functions. + +// EVP_CIPH_NO_PADDING disables padding in block ciphers. +#define EVP_CIPH_NO_PADDING 0x800 + +// EVP_CIPHER_CTX_ctrl commands. +#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_AEAD_SET_MAC_KEY 0x17 +// Set the GCM invocation field, decrypt only +#define EVP_CTRL_GCM_SET_IV_INV 0x18 + +// 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 + +#define EVP_MAX_KEY_LENGTH 64 +#define EVP_MAX_IV_LENGTH 16 +#define EVP_MAX_BLOCK_LENGTH 32 + +struct evp_cipher_ctx_st { + // cipher contains the underlying cipher for this context. + const EVP_CIPHER *cipher; + + // app_data is a pointer to opaque, user data. + void *app_data; // application stuff + + // cipher_data points to the |cipher| specific state. + void *cipher_data; + + // key_len contains the length of the key, which may differ from + // |cipher->key_len| if the cipher can take a variable key length. + unsigned key_len; + + // encrypt is one if encrypting and zero if decrypting. + int encrypt; + + // flags contains the OR of zero or more |EVP_CIPH_*| flags, above. + uint32_t flags; + + // oiv contains the original IV value. + uint8_t oiv[EVP_MAX_IV_LENGTH]; + + // iv contains the current IV value, which may have been updated. + uint8_t iv[EVP_MAX_IV_LENGTH]; + + // buf contains a partial block which is used by, for example, CTR mode to + // store unused keystream bytes. + uint8_t buf[EVP_MAX_BLOCK_LENGTH]; + + // buf_len contains the number of bytes of a partial block contained in + // |buf|. + int buf_len; + + // num contains the number of bytes of |iv| which are valid for modes that + // manage partial blocks themselves. + unsigned num; + + // final_used is non-zero if the |final| buffer contains plaintext. + int final_used; + + // block_mask contains |cipher->block_size| minus one. (The block size + // assumed to be a power of two.) + int block_mask; + + uint8_t final[EVP_MAX_BLOCK_LENGTH]; // possible final block +} /* EVP_CIPHER_CTX */; + +typedef struct evp_cipher_info_st { + const EVP_CIPHER *cipher; + unsigned char iv[EVP_MAX_IV_LENGTH]; +} EVP_CIPHER_INFO; + +struct evp_cipher_st { + // type contains a NID identifing the cipher. (e.g. NID_aes_128_gcm.) + int nid; + + // block_size contains the block size, in bytes, of the cipher, or 1 for a + // stream cipher. + unsigned block_size; + + // key_len contains the key size, in bytes, for the cipher. If the cipher + // takes a variable key size then this contains the default size. + unsigned key_len; + + // iv_len contains the IV size, in bytes, or zero if inapplicable. + unsigned iv_len; + + // ctx_size contains the size, in bytes, of the per-key context for this + // cipher. + unsigned ctx_size; + + // flags contains the OR of a number of flags. See |EVP_CIPH_*|. + uint32_t flags; + + // app_data is a pointer to opaque, user data. + void *app_data; + + int (*init)(EVP_CIPHER_CTX *ctx, const uint8_t *key, const uint8_t *iv, + int enc); + + int (*cipher)(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in, + size_t inl); + + // cleanup, if non-NULL, releases memory associated with the context. It is + // called if |EVP_CTRL_INIT| succeeds. Note that |init| may not have been + // called at this point. + void (*cleanup)(EVP_CIPHER_CTX *); + + int (*ctrl)(EVP_CIPHER_CTX *, int type, int arg, void *ptr); +}; + + +#if defined(__cplusplus) +} // extern C + +#if !defined(BORINGSSL_NO_CXX) +extern "C++" { + +namespace bssl { + +BORINGSSL_MAKE_DELETER(EVP_CIPHER_CTX, EVP_CIPHER_CTX_free) + +using ScopedEVP_CIPHER_CTX = + internal::StackAllocated; + +} // namespace bssl + +} // extern C++ +#endif + +#endif + +#define CIPHER_R_AES_KEY_SETUP_FAILED 100 +#define CIPHER_R_BAD_DECRYPT 101 +#define CIPHER_R_BAD_KEY_LENGTH 102 +#define CIPHER_R_BUFFER_TOO_SMALL 103 +#define CIPHER_R_CTRL_NOT_IMPLEMENTED 104 +#define CIPHER_R_CTRL_OPERATION_NOT_IMPLEMENTED 105 +#define CIPHER_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH 106 +#define CIPHER_R_INITIALIZATION_ERROR 107 +#define CIPHER_R_INPUT_NOT_INITIALIZED 108 +#define CIPHER_R_INVALID_AD_SIZE 109 +#define CIPHER_R_INVALID_KEY_LENGTH 110 +#define CIPHER_R_INVALID_NONCE_SIZE 111 +#define CIPHER_R_INVALID_OPERATION 112 +#define CIPHER_R_IV_TOO_LARGE 113 +#define CIPHER_R_NO_CIPHER_SET 114 +#define CIPHER_R_OUTPUT_ALIASES_INPUT 115 +#define CIPHER_R_TAG_TOO_LARGE 116 +#define CIPHER_R_TOO_LARGE 117 +#define CIPHER_R_UNSUPPORTED_AD_SIZE 118 +#define CIPHER_R_UNSUPPORTED_INPUT_SIZE 119 +#define CIPHER_R_UNSUPPORTED_KEY_SIZE 120 +#define CIPHER_R_UNSUPPORTED_NONCE_SIZE 121 +#define CIPHER_R_UNSUPPORTED_TAG_SIZE 122 +#define CIPHER_R_WRONG_FINAL_BLOCK_LENGTH 123 +#define CIPHER_R_NO_DIRECTION_SET 124 +#define CIPHER_R_INVALID_NONCE 125 + +#endif // OPENSSL_HEADER_CIPHER_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/cipher.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/cipher.h.grpc_back new file mode 100644 index 0000000..643bf04 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/cipher.h.grpc_back @@ -0,0 +1,608 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 OPENSSL_HEADER_CIPHER_H +#define OPENSSL_HEADER_CIPHER_H + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// Ciphers. + + +// Cipher primitives. +// +// The following functions return |EVP_CIPHER| objects that implement the named +// cipher algorithm. + +OPENSSL_EXPORT const EVP_CIPHER *EVP_rc4(void); + +OPENSSL_EXPORT const EVP_CIPHER *EVP_des_cbc(void); +OPENSSL_EXPORT const EVP_CIPHER *EVP_des_ecb(void); +OPENSSL_EXPORT const EVP_CIPHER *EVP_des_ede(void); +OPENSSL_EXPORT const EVP_CIPHER *EVP_des_ede3(void); +OPENSSL_EXPORT const EVP_CIPHER *EVP_des_ede_cbc(void); +OPENSSL_EXPORT const EVP_CIPHER *EVP_des_ede3_cbc(void); + +OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_128_ecb(void); +OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_128_cbc(void); +OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_128_ctr(void); +OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_128_ofb(void); + +OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_256_ecb(void); +OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_256_cbc(void); +OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_256_ctr(void); +OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_256_ofb(void); +OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_256_xts(void); + +// EVP_enc_null returns a 'cipher' that passes plaintext through as +// ciphertext. +OPENSSL_EXPORT const EVP_CIPHER *EVP_enc_null(void); + +// EVP_rc2_cbc returns a cipher that implements 128-bit RC2 in CBC mode. +OPENSSL_EXPORT const EVP_CIPHER *EVP_rc2_cbc(void); + +// EVP_rc2_40_cbc returns a cipher that implements 40-bit RC2 in CBC mode. This +// is obviously very, very weak and is included only in order to read PKCS#12 +// files, which often encrypt the certificate chain using this cipher. It is +// deliberately not exported. +const EVP_CIPHER *EVP_rc2_40_cbc(void); + +// EVP_get_cipherbynid returns the cipher corresponding to the given NID, or +// NULL if no such cipher is known. +OPENSSL_EXPORT const EVP_CIPHER *EVP_get_cipherbynid(int nid); + + +// Cipher context allocation. +// +// An |EVP_CIPHER_CTX| represents the state of an encryption or decryption in +// progress. + +// EVP_CIPHER_CTX_init initialises an, already allocated, |EVP_CIPHER_CTX|. +OPENSSL_EXPORT void EVP_CIPHER_CTX_init(EVP_CIPHER_CTX *ctx); + +// EVP_CIPHER_CTX_new allocates a fresh |EVP_CIPHER_CTX|, calls +// |EVP_CIPHER_CTX_init| and returns it, or NULL on allocation failure. +OPENSSL_EXPORT EVP_CIPHER_CTX *EVP_CIPHER_CTX_new(void); + +// EVP_CIPHER_CTX_cleanup frees any memory referenced by |ctx|. It returns +// one. +OPENSSL_EXPORT int EVP_CIPHER_CTX_cleanup(EVP_CIPHER_CTX *ctx); + +// EVP_CIPHER_CTX_free calls |EVP_CIPHER_CTX_cleanup| on |ctx| and then frees +// |ctx| itself. +OPENSSL_EXPORT void EVP_CIPHER_CTX_free(EVP_CIPHER_CTX *ctx); + +// EVP_CIPHER_CTX_copy sets |out| to be a duplicate of the current state of +// |in|. The |out| argument must have been previously initialised. +OPENSSL_EXPORT int EVP_CIPHER_CTX_copy(EVP_CIPHER_CTX *out, + const EVP_CIPHER_CTX *in); + +// EVP_CIPHER_CTX_reset calls |EVP_CIPHER_CTX_cleanup| followed by +// |EVP_CIPHER_CTX_init|. +OPENSSL_EXPORT void EVP_CIPHER_CTX_reset(EVP_CIPHER_CTX *ctx); + + +// Cipher context configuration. + +// EVP_CipherInit_ex configures |ctx| for a fresh encryption (or decryption, if +// |enc| is zero) operation using |cipher|. If |ctx| has been previously +// configured with a cipher then |cipher|, |key| and |iv| may be |NULL| and +// |enc| may be -1 to reuse the previous values. The operation will use |key| +// as the key and |iv| as the IV (if any). These should have the correct +// lengths given by |EVP_CIPHER_key_length| and |EVP_CIPHER_iv_length|. It +// returns one on success and zero on error. +OPENSSL_EXPORT int EVP_CipherInit_ex(EVP_CIPHER_CTX *ctx, + const EVP_CIPHER *cipher, ENGINE *engine, + const uint8_t *key, const uint8_t *iv, + int enc); + +// EVP_EncryptInit_ex calls |EVP_CipherInit_ex| with |enc| equal to one. +OPENSSL_EXPORT int EVP_EncryptInit_ex(EVP_CIPHER_CTX *ctx, + const EVP_CIPHER *cipher, ENGINE *impl, + const uint8_t *key, const uint8_t *iv); + +// EVP_DecryptInit_ex calls |EVP_CipherInit_ex| with |enc| equal to zero. +OPENSSL_EXPORT int EVP_DecryptInit_ex(EVP_CIPHER_CTX *ctx, + const EVP_CIPHER *cipher, ENGINE *impl, + const uint8_t *key, const uint8_t *iv); + + +// Cipher operations. + +// EVP_EncryptUpdate encrypts |in_len| bytes from |in| to |out|. The number +// of output bytes may be up to |in_len| plus the block length minus one and +// |out| must have sufficient space. The number of bytes actually output is +// written to |*out_len|. It returns one on success and zero otherwise. +OPENSSL_EXPORT int EVP_EncryptUpdate(EVP_CIPHER_CTX *ctx, uint8_t *out, + int *out_len, const uint8_t *in, + int in_len); + +// EVP_EncryptFinal_ex writes at most a block of ciphertext to |out| and sets +// |*out_len| to the number of bytes written. If padding is enabled (the +// default) then standard padding is applied to create the final block. If +// padding is disabled (with |EVP_CIPHER_CTX_set_padding|) then any partial +// block remaining will cause an error. The function returns one on success and +// zero otherwise. +OPENSSL_EXPORT int EVP_EncryptFinal_ex(EVP_CIPHER_CTX *ctx, uint8_t *out, + int *out_len); + +// EVP_DecryptUpdate decrypts |in_len| bytes from |in| to |out|. The number of +// output bytes may be up to |in_len| plus the block length minus one and |out| +// must have sufficient space. The number of bytes actually output is written +// to |*out_len|. It returns one on success and zero otherwise. +OPENSSL_EXPORT int EVP_DecryptUpdate(EVP_CIPHER_CTX *ctx, uint8_t *out, + int *out_len, const uint8_t *in, + int in_len); + +// EVP_DecryptFinal_ex writes at most a block of ciphertext to |out| and sets +// |*out_len| to the number of bytes written. If padding is enabled (the +// default) then padding is removed from the final block. +// +// WARNING: it is unsafe to call this function with unauthenticated +// ciphertext if padding is enabled. +OPENSSL_EXPORT int EVP_DecryptFinal_ex(EVP_CIPHER_CTX *ctx, unsigned char *out, + int *out_len); + +// EVP_Cipher performs a one-shot encryption/decryption operation. No partial +// blocks are maintained between calls. However, any internal cipher state is +// still updated. For CBC-mode ciphers, the IV is updated to the final +// ciphertext block. For stream ciphers, the stream is advanced past the bytes +// used. It returns one on success and zero otherwise, unless |EVP_CIPHER_flags| +// has |EVP_CIPH_FLAG_CUSTOM_CIPHER| set. Then it returns the number of bytes +// written or -1 on error. +// +// WARNING: this differs from the usual return value convention when using +// |EVP_CIPH_FLAG_CUSTOM_CIPHER|. +// +// TODO(davidben): The normal ciphers currently never fail, even if, e.g., +// |in_len| is not a multiple of the block size for CBC-mode decryption. The +// input just gets rounded up while the output gets truncated. This should +// either be officially documented or fail. +OPENSSL_EXPORT int EVP_Cipher(EVP_CIPHER_CTX *ctx, uint8_t *out, + const uint8_t *in, size_t in_len); + +// EVP_CipherUpdate calls either |EVP_EncryptUpdate| or |EVP_DecryptUpdate| +// depending on how |ctx| has been setup. +OPENSSL_EXPORT int EVP_CipherUpdate(EVP_CIPHER_CTX *ctx, uint8_t *out, + int *out_len, const uint8_t *in, + int in_len); + +// EVP_CipherFinal_ex calls either |EVP_EncryptFinal_ex| or +// |EVP_DecryptFinal_ex| depending on how |ctx| has been setup. +OPENSSL_EXPORT int EVP_CipherFinal_ex(EVP_CIPHER_CTX *ctx, uint8_t *out, + int *out_len); + + +// Cipher context accessors. + +// EVP_CIPHER_CTX_cipher returns the |EVP_CIPHER| underlying |ctx|, or NULL if +// none has been set. +OPENSSL_EXPORT const EVP_CIPHER *EVP_CIPHER_CTX_cipher( + const EVP_CIPHER_CTX *ctx); + +// EVP_CIPHER_CTX_nid returns a NID identifying the |EVP_CIPHER| underlying +// |ctx| (e.g. |NID_aes_128_gcm|). It will crash if no cipher has been +// configured. +OPENSSL_EXPORT int EVP_CIPHER_CTX_nid(const EVP_CIPHER_CTX *ctx); + +// EVP_CIPHER_CTX_block_size returns the block size, in bytes, of the cipher +// underlying |ctx|, or one if the cipher is a stream cipher. It will crash if +// no cipher has been configured. +OPENSSL_EXPORT unsigned EVP_CIPHER_CTX_block_size(const EVP_CIPHER_CTX *ctx); + +// EVP_CIPHER_CTX_key_length returns the key size, in bytes, of the cipher +// underlying |ctx| or zero if no cipher has been configured. +OPENSSL_EXPORT unsigned EVP_CIPHER_CTX_key_length(const EVP_CIPHER_CTX *ctx); + +// EVP_CIPHER_CTX_iv_length returns the IV size, in bytes, of the cipher +// underlying |ctx|. It will crash if no cipher has been configured. +OPENSSL_EXPORT unsigned EVP_CIPHER_CTX_iv_length(const EVP_CIPHER_CTX *ctx); + +// EVP_CIPHER_CTX_get_app_data returns the opaque, application data pointer for +// |ctx|, or NULL if none has been set. +OPENSSL_EXPORT void *EVP_CIPHER_CTX_get_app_data(const EVP_CIPHER_CTX *ctx); + +// EVP_CIPHER_CTX_set_app_data sets the opaque, application data pointer for +// |ctx| to |data|. +OPENSSL_EXPORT void EVP_CIPHER_CTX_set_app_data(EVP_CIPHER_CTX *ctx, + void *data); + +// EVP_CIPHER_CTX_flags returns a value which is the OR of zero or more +// |EVP_CIPH_*| flags. It will crash if no cipher has been configured. +OPENSSL_EXPORT uint32_t EVP_CIPHER_CTX_flags(const EVP_CIPHER_CTX *ctx); + +// EVP_CIPHER_CTX_mode returns one of the |EVP_CIPH_*| cipher mode values +// enumerated below. It will crash if no cipher has been configured. +OPENSSL_EXPORT uint32_t EVP_CIPHER_CTX_mode(const EVP_CIPHER_CTX *ctx); + +// EVP_CIPHER_CTX_ctrl is an |ioctl| like function. The |command| argument +// should be one of the |EVP_CTRL_*| values. The |arg| and |ptr| arguments are +// specific to the command in question. +OPENSSL_EXPORT int EVP_CIPHER_CTX_ctrl(EVP_CIPHER_CTX *ctx, int command, + int arg, void *ptr); + +// EVP_CIPHER_CTX_set_padding sets whether padding is enabled for |ctx| and +// returns one. Pass a non-zero |pad| to enable padding (the default) or zero +// to disable. +OPENSSL_EXPORT int EVP_CIPHER_CTX_set_padding(EVP_CIPHER_CTX *ctx, int pad); + +// EVP_CIPHER_CTX_set_key_length sets the key length for |ctx|. This is only +// valid for ciphers that can take a variable length key. It returns one on +// success and zero on error. +OPENSSL_EXPORT int EVP_CIPHER_CTX_set_key_length(EVP_CIPHER_CTX *ctx, + unsigned key_len); + + +// Cipher accessors. + +// EVP_CIPHER_nid returns a NID identifying |cipher|. (For example, +// |NID_aes_128_gcm|.) +OPENSSL_EXPORT int EVP_CIPHER_nid(const EVP_CIPHER *cipher); + +// EVP_CIPHER_block_size returns the block size, in bytes, for |cipher|, or one +// if |cipher| is a stream cipher. +OPENSSL_EXPORT unsigned EVP_CIPHER_block_size(const EVP_CIPHER *cipher); + +// EVP_CIPHER_key_length returns the key size, in bytes, for |cipher|. If +// |cipher| can take a variable key length then this function returns the +// default key length and |EVP_CIPHER_flags| will return a value with +// |EVP_CIPH_VARIABLE_LENGTH| set. +OPENSSL_EXPORT unsigned EVP_CIPHER_key_length(const EVP_CIPHER *cipher); + +// EVP_CIPHER_iv_length returns the IV size, in bytes, of |cipher|, or zero if +// |cipher| doesn't take an IV. +OPENSSL_EXPORT unsigned EVP_CIPHER_iv_length(const EVP_CIPHER *cipher); + +// EVP_CIPHER_flags returns a value which is the OR of zero or more +// |EVP_CIPH_*| flags. +OPENSSL_EXPORT uint32_t EVP_CIPHER_flags(const EVP_CIPHER *cipher); + +// EVP_CIPHER_mode returns one of the cipher mode values enumerated below. +OPENSSL_EXPORT uint32_t EVP_CIPHER_mode(const EVP_CIPHER *cipher); + + +// Key derivation. + +// EVP_BytesToKey generates a key and IV for the cipher |type| by iterating +// |md| |count| times using |data| and |salt|. On entry, the |key| and |iv| +// buffers must have enough space to hold a key and IV for |type|. It returns +// the length of the key on success or zero on error. +OPENSSL_EXPORT int EVP_BytesToKey(const EVP_CIPHER *type, const EVP_MD *md, + const uint8_t *salt, const uint8_t *data, + size_t data_len, unsigned count, uint8_t *key, + uint8_t *iv); + + +// Cipher modes (for |EVP_CIPHER_mode|). + +#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_XTS_MODE 0x7 + + +// Cipher flags (for |EVP_CIPHER_flags|). + +// EVP_CIPH_VARIABLE_LENGTH indicates that the cipher takes a variable length +// key. +#define EVP_CIPH_VARIABLE_LENGTH 0x40 + +// EVP_CIPH_ALWAYS_CALL_INIT indicates that the |init| function for the cipher +// should always be called when initialising a new operation, even if the key +// is NULL to indicate that the same key is being used. +#define EVP_CIPH_ALWAYS_CALL_INIT 0x80 + +// EVP_CIPH_CUSTOM_IV indicates that the cipher manages the IV itself rather +// than keeping it in the |iv| member of |EVP_CIPHER_CTX|. +#define EVP_CIPH_CUSTOM_IV 0x100 + +// EVP_CIPH_CTRL_INIT indicates that EVP_CTRL_INIT should be used when +// initialising an |EVP_CIPHER_CTX|. +#define EVP_CIPH_CTRL_INIT 0x200 + +// EVP_CIPH_FLAG_CUSTOM_CIPHER indicates that the cipher manages blocking +// itself. This causes EVP_(En|De)crypt_ex to be simple wrapper functions. +#define EVP_CIPH_FLAG_CUSTOM_CIPHER 0x400 + +// EVP_CIPH_FLAG_AEAD_CIPHER specifies that the cipher is an AEAD. This is an +// older version of the proper AEAD interface. See aead.h for the current +// one. +#define EVP_CIPH_FLAG_AEAD_CIPHER 0x800 + +// EVP_CIPH_CUSTOM_COPY indicates that the |ctrl| callback should be called +// with |EVP_CTRL_COPY| at the end of normal |EVP_CIPHER_CTX_copy| +// processing. +#define EVP_CIPH_CUSTOM_COPY 0x1000 + + +// Deprecated functions + +// EVP_CipherInit acts like EVP_CipherInit_ex except that |EVP_CIPHER_CTX_init| +// is called on |cipher| first, if |cipher| is not NULL. +OPENSSL_EXPORT int EVP_CipherInit(EVP_CIPHER_CTX *ctx, const EVP_CIPHER *cipher, + const uint8_t *key, const uint8_t *iv, + int enc); + +// EVP_EncryptInit calls |EVP_CipherInit| with |enc| equal to one. +OPENSSL_EXPORT int EVP_EncryptInit(EVP_CIPHER_CTX *ctx, + const EVP_CIPHER *cipher, const uint8_t *key, + const uint8_t *iv); + +// EVP_DecryptInit calls |EVP_CipherInit| with |enc| equal to zero. +OPENSSL_EXPORT int EVP_DecryptInit(EVP_CIPHER_CTX *ctx, + const EVP_CIPHER *cipher, const uint8_t *key, + const uint8_t *iv); + +// EVP_add_cipher_alias does nothing and returns one. +OPENSSL_EXPORT int EVP_add_cipher_alias(const char *a, const char *b); + +// EVP_get_cipherbyname returns an |EVP_CIPHER| given a human readable name in +// |name|, or NULL if the name is unknown. +OPENSSL_EXPORT const EVP_CIPHER *EVP_get_cipherbyname(const char *name); + +// These AEADs are deprecated AES-GCM implementations that set +// |EVP_CIPH_FLAG_CUSTOM_CIPHER|. Use |EVP_aead_aes_128_gcm| and +// |EVP_aead_aes_256_gcm| instead. +OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_128_gcm(void); +OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_256_gcm(void); + +// These are deprecated, 192-bit version of AES. +OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_192_ecb(void); +OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_192_cbc(void); +OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_192_ctr(void); +OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_192_gcm(void); + +// EVP_aes_128_cfb128 is only available in decrepit. +OPENSSL_EXPORT const EVP_CIPHER *EVP_aes_128_cfb128(void); + +// The following flags do nothing and are included only to make it easier to +// compile code with BoringSSL. +#define EVP_CIPH_CCM_MODE 0 +#define EVP_CIPH_WRAP_MODE 0 +#define EVP_CIPHER_CTX_FLAG_WRAP_ALLOW 0 + +// EVP_CIPHER_CTX_set_flags does nothing. +OPENSSL_EXPORT void EVP_CIPHER_CTX_set_flags(const EVP_CIPHER_CTX *ctx, + uint32_t flags); + + +// Private functions. + +// EVP_CIPH_NO_PADDING disables padding in block ciphers. +#define EVP_CIPH_NO_PADDING 0x800 + +// EVP_CIPHER_CTX_ctrl commands. +#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_AEAD_SET_MAC_KEY 0x17 +// Set the GCM invocation field, decrypt only +#define EVP_CTRL_GCM_SET_IV_INV 0x18 + +// 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 + +#define EVP_MAX_KEY_LENGTH 64 +#define EVP_MAX_IV_LENGTH 16 +#define EVP_MAX_BLOCK_LENGTH 32 + +struct evp_cipher_ctx_st { + // cipher contains the underlying cipher for this context. + const EVP_CIPHER *cipher; + + // app_data is a pointer to opaque, user data. + void *app_data; // application stuff + + // cipher_data points to the |cipher| specific state. + void *cipher_data; + + // key_len contains the length of the key, which may differ from + // |cipher->key_len| if the cipher can take a variable key length. + unsigned key_len; + + // encrypt is one if encrypting and zero if decrypting. + int encrypt; + + // flags contains the OR of zero or more |EVP_CIPH_*| flags, above. + uint32_t flags; + + // oiv contains the original IV value. + uint8_t oiv[EVP_MAX_IV_LENGTH]; + + // iv contains the current IV value, which may have been updated. + uint8_t iv[EVP_MAX_IV_LENGTH]; + + // buf contains a partial block which is used by, for example, CTR mode to + // store unused keystream bytes. + uint8_t buf[EVP_MAX_BLOCK_LENGTH]; + + // buf_len contains the number of bytes of a partial block contained in + // |buf|. + int buf_len; + + // num contains the number of bytes of |iv| which are valid for modes that + // manage partial blocks themselves. + unsigned num; + + // final_used is non-zero if the |final| buffer contains plaintext. + int final_used; + + // block_mask contains |cipher->block_size| minus one. (The block size + // assumed to be a power of two.) + int block_mask; + + uint8_t final[EVP_MAX_BLOCK_LENGTH]; // possible final block +} /* EVP_CIPHER_CTX */; + +typedef struct evp_cipher_info_st { + const EVP_CIPHER *cipher; + unsigned char iv[EVP_MAX_IV_LENGTH]; +} EVP_CIPHER_INFO; + +struct evp_cipher_st { + // type contains a NID identifing the cipher. (e.g. NID_aes_128_gcm.) + int nid; + + // block_size contains the block size, in bytes, of the cipher, or 1 for a + // stream cipher. + unsigned block_size; + + // key_len contains the key size, in bytes, for the cipher. If the cipher + // takes a variable key size then this contains the default size. + unsigned key_len; + + // iv_len contains the IV size, in bytes, or zero if inapplicable. + unsigned iv_len; + + // ctx_size contains the size, in bytes, of the per-key context for this + // cipher. + unsigned ctx_size; + + // flags contains the OR of a number of flags. See |EVP_CIPH_*|. + uint32_t flags; + + // app_data is a pointer to opaque, user data. + void *app_data; + + int (*init)(EVP_CIPHER_CTX *ctx, const uint8_t *key, const uint8_t *iv, + int enc); + + int (*cipher)(EVP_CIPHER_CTX *ctx, uint8_t *out, const uint8_t *in, + size_t inl); + + // cleanup, if non-NULL, releases memory associated with the context. It is + // called if |EVP_CTRL_INIT| succeeds. Note that |init| may not have been + // called at this point. + void (*cleanup)(EVP_CIPHER_CTX *); + + int (*ctrl)(EVP_CIPHER_CTX *, int type, int arg, void *ptr); +}; + + +#if defined(__cplusplus) +} // extern C + +#if !defined(BORINGSSL_NO_CXX) +extern "C++" { + +namespace bssl { + +BORINGSSL_MAKE_DELETER(EVP_CIPHER_CTX, EVP_CIPHER_CTX_free) + +using ScopedEVP_CIPHER_CTX = + internal::StackAllocated; + +} // namespace bssl + +} // extern C++ +#endif + +#endif + +#define CIPHER_R_AES_KEY_SETUP_FAILED 100 +#define CIPHER_R_BAD_DECRYPT 101 +#define CIPHER_R_BAD_KEY_LENGTH 102 +#define CIPHER_R_BUFFER_TOO_SMALL 103 +#define CIPHER_R_CTRL_NOT_IMPLEMENTED 104 +#define CIPHER_R_CTRL_OPERATION_NOT_IMPLEMENTED 105 +#define CIPHER_R_DATA_NOT_MULTIPLE_OF_BLOCK_LENGTH 106 +#define CIPHER_R_INITIALIZATION_ERROR 107 +#define CIPHER_R_INPUT_NOT_INITIALIZED 108 +#define CIPHER_R_INVALID_AD_SIZE 109 +#define CIPHER_R_INVALID_KEY_LENGTH 110 +#define CIPHER_R_INVALID_NONCE_SIZE 111 +#define CIPHER_R_INVALID_OPERATION 112 +#define CIPHER_R_IV_TOO_LARGE 113 +#define CIPHER_R_NO_CIPHER_SET 114 +#define CIPHER_R_OUTPUT_ALIASES_INPUT 115 +#define CIPHER_R_TAG_TOO_LARGE 116 +#define CIPHER_R_TOO_LARGE 117 +#define CIPHER_R_UNSUPPORTED_AD_SIZE 118 +#define CIPHER_R_UNSUPPORTED_INPUT_SIZE 119 +#define CIPHER_R_UNSUPPORTED_KEY_SIZE 120 +#define CIPHER_R_UNSUPPORTED_NONCE_SIZE 121 +#define CIPHER_R_UNSUPPORTED_TAG_SIZE 122 +#define CIPHER_R_WRONG_FINAL_BLOCK_LENGTH 123 +#define CIPHER_R_NO_DIRECTION_SET 124 +#define CIPHER_R_INVALID_NONCE 125 + +#endif // OPENSSL_HEADER_CIPHER_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/cmac.h b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/cmac.h new file mode 100644 index 0000000..48e73f5 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/cmac.h @@ -0,0 +1,87 @@ +/* Copyright (c) 2015, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_CMAC_H +#define OPENSSL_HEADER_CMAC_H + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// CMAC. +// +// CMAC is a MAC based on AES-CBC and defined in +// https://tools.ietf.org/html/rfc4493#section-2.3. + + +// One-shot functions. + +// AES_CMAC calculates the 16-byte, CMAC authenticator of |in_len| bytes of +// |in| and writes it to |out|. The |key_len| may be 16 or 32 bytes to select +// between AES-128 and AES-256. It returns one on success or zero on error. +OPENSSL_EXPORT int AES_CMAC(uint8_t out[16], const uint8_t *key, size_t key_len, + const uint8_t *in, size_t in_len); + + +// Incremental interface. + +// CMAC_CTX_new allocates a fresh |CMAC_CTX| and returns it, or NULL on +// error. +OPENSSL_EXPORT CMAC_CTX *CMAC_CTX_new(void); + +// CMAC_CTX_free frees a |CMAC_CTX|. +OPENSSL_EXPORT void CMAC_CTX_free(CMAC_CTX *ctx); + +// CMAC_Init configures |ctx| to use the given |key| and |cipher|. The CMAC RFC +// only specifies the use of AES-128 thus |key_len| should be 16 and |cipher| +// should be |EVP_aes_128_cbc()|. However, this implementation also supports +// AES-256 by setting |key_len| to 32 and |cipher| to |EVP_aes_256_cbc()|. The +// |engine| argument is ignored. +// +// It returns one on success or zero on error. +OPENSSL_EXPORT int CMAC_Init(CMAC_CTX *ctx, const void *key, size_t key_len, + const EVP_CIPHER *cipher, ENGINE *engine); + + +// CMAC_Reset resets |ctx| so that a fresh message can be authenticated. +OPENSSL_EXPORT int CMAC_Reset(CMAC_CTX *ctx); + +// CMAC_Update processes |in_len| bytes of message from |in|. It returns one on +// success or zero on error. +OPENSSL_EXPORT int CMAC_Update(CMAC_CTX *ctx, const uint8_t *in, size_t in_len); + +// CMAC_Final sets |*out_len| to 16 and, if |out| is not NULL, writes 16 bytes +// of authenticator to it. It returns one on success or zero on error. +OPENSSL_EXPORT int CMAC_Final(CMAC_CTX *ctx, uint8_t *out, size_t *out_len); + + +#if defined(__cplusplus) +} // extern C + +extern "C++" { + +namespace bssl { + +BORINGSSL_MAKE_DELETER(CMAC_CTX, CMAC_CTX_free) + +} // namespace bssl + +} // extern C++ + +#endif + +#endif // OPENSSL_HEADER_CMAC_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/cmac.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/cmac.h.grpc_back new file mode 100644 index 0000000..dfcd37b --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/cmac.h.grpc_back @@ -0,0 +1,87 @@ +/* Copyright (c) 2015, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_CMAC_H +#define OPENSSL_HEADER_CMAC_H + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// CMAC. +// +// CMAC is a MAC based on AES-CBC and defined in +// https://tools.ietf.org/html/rfc4493#section-2.3. + + +// One-shot functions. + +// AES_CMAC calculates the 16-byte, CMAC authenticator of |in_len| bytes of +// |in| and writes it to |out|. The |key_len| may be 16 or 32 bytes to select +// between AES-128 and AES-256. It returns one on success or zero on error. +OPENSSL_EXPORT int AES_CMAC(uint8_t out[16], const uint8_t *key, size_t key_len, + const uint8_t *in, size_t in_len); + + +// Incremental interface. + +// CMAC_CTX_new allocates a fresh |CMAC_CTX| and returns it, or NULL on +// error. +OPENSSL_EXPORT CMAC_CTX *CMAC_CTX_new(void); + +// CMAC_CTX_free frees a |CMAC_CTX|. +OPENSSL_EXPORT void CMAC_CTX_free(CMAC_CTX *ctx); + +// CMAC_Init configures |ctx| to use the given |key| and |cipher|. The CMAC RFC +// only specifies the use of AES-128 thus |key_len| should be 16 and |cipher| +// should be |EVP_aes_128_cbc()|. However, this implementation also supports +// AES-256 by setting |key_len| to 32 and |cipher| to |EVP_aes_256_cbc()|. The +// |engine| argument is ignored. +// +// It returns one on success or zero on error. +OPENSSL_EXPORT int CMAC_Init(CMAC_CTX *ctx, const void *key, size_t key_len, + const EVP_CIPHER *cipher, ENGINE *engine); + + +// CMAC_Reset resets |ctx| so that a fresh message can be authenticated. +OPENSSL_EXPORT int CMAC_Reset(CMAC_CTX *ctx); + +// CMAC_Update processes |in_len| bytes of message from |in|. It returns one on +// success or zero on error. +OPENSSL_EXPORT int CMAC_Update(CMAC_CTX *ctx, const uint8_t *in, size_t in_len); + +// CMAC_Final sets |*out_len| to 16 and, if |out| is not NULL, writes 16 bytes +// of authenticator to it. It returns one on success or zero on error. +OPENSSL_EXPORT int CMAC_Final(CMAC_CTX *ctx, uint8_t *out, size_t *out_len); + + +#if defined(__cplusplus) +} // extern C + +extern "C++" { + +namespace bssl { + +BORINGSSL_MAKE_DELETER(CMAC_CTX, CMAC_CTX_free) + +} // namespace bssl + +} // extern C++ + +#endif + +#endif // OPENSSL_HEADER_CMAC_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/conf.h b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/conf.h new file mode 100644 index 0000000..922fb96 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/conf.h @@ -0,0 +1,183 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 OPENSSL_HEADER_CONF_H +#define OPENSSL_HEADER_CONF_H + +#include + +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// Config files look like: +// +// # Comment +// +// # This key is in the default section. +// key=value +// +// [section_name] +// key2=value2 +// +// Config files are represented by a |CONF|. + +struct conf_value_st { + char *section; + char *name; + char *value; +}; + +struct conf_st { + LHASH_OF(CONF_VALUE) *data; +}; + +DEFINE_STACK_OF(CONF_VALUE) + + +// NCONF_new returns a fresh, empty |CONF|, or NULL on error. The |method| +// argument must be NULL. +OPENSSL_EXPORT CONF *NCONF_new(void *method); + +// NCONF_free frees all the data owned by |conf| and then |conf| itself. +OPENSSL_EXPORT void NCONF_free(CONF *conf); + +// NCONF_load parses the file named |filename| and adds the values found to +// |conf|. It returns one on success and zero on error. In the event of an +// error, if |out_error_line| is not NULL, |*out_error_line| is set to the +// number of the line that contained the error. +int NCONF_load(CONF *conf, const char *filename, long *out_error_line); + +// NCONF_load_bio acts like |NCONF_load| but reads from |bio| rather than from +// a named file. +int NCONF_load_bio(CONF *conf, BIO *bio, long *out_error_line); + +// NCONF_get_section returns a stack of values for a given section in |conf|. +// If |section| is NULL, the default section is returned. It returns NULL on +// error. +STACK_OF(CONF_VALUE) *NCONF_get_section(const CONF *conf, const char *section); + +// NCONF_get_string returns the value of the key |name|, in section |section|. +// The |section| argument may be NULL to indicate the default section. It +// returns the value or NULL on error. +const char *NCONF_get_string(const CONF *conf, const char *section, + const char *name); + + +// Utility functions + +// CONF_parse_list takes a list separated by 'sep' and calls |list_cb| 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. If |list_cb| returns <= 0, then the iteration is halted and that +// value is returned immediately. Otherwise it returns one. Note that |list_cb| +// may be called on an empty member. +int CONF_parse_list(const char *list, char sep, int remove_whitespace, + int (*list_cb)(const char *elem, int len, void *usr), + void *arg); + + +// Deprecated functions + +// These defines do nothing but are provided to make old code easier to +// compile. +#define CONF_MFLAGS_DEFAULT_SECTION 0 +#define CONF_MFLAGS_IGNORE_MISSING_FILE 0 + +// CONF_modules_load_file returns one. BoringSSL is defined to have no config +// file options, thus loading from |filename| always succeeds by doing nothing. +OPENSSL_EXPORT int CONF_modules_load_file(const char *filename, + const char *appname, + unsigned long flags); + +// CONF_modules_free does nothing. +OPENSSL_EXPORT void CONF_modules_free(void); + +// OPENSSL_config does nothing. +OPENSSL_EXPORT void OPENSSL_config(const char *config_name); + +// OPENSSL_no_config does nothing. +OPENSSL_EXPORT void OPENSSL_no_config(void); + + +#if defined(__cplusplus) +} // extern C + +extern "C++" { + +namespace bssl { + +BORINGSSL_MAKE_DELETER(CONF, NCONF_free) + +} // namespace bssl + +} // extern C++ + +#endif + +#define CONF_R_LIST_CANNOT_BE_NULL 100 +#define CONF_R_MISSING_CLOSE_SQUARE_BRACKET 101 +#define CONF_R_MISSING_EQUAL_SIGN 102 +#define CONF_R_NO_CLOSE_BRACE 103 +#define CONF_R_UNABLE_TO_CREATE_NEW_SECTION 104 +#define CONF_R_VARIABLE_HAS_NO_VALUE 105 +#define CONF_R_VARIABLE_EXPANSION_TOO_LONG 106 + +#endif // OPENSSL_HEADER_THREAD_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/conf.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/conf.h.grpc_back new file mode 100644 index 0000000..4ffce37 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/conf.h.grpc_back @@ -0,0 +1,183 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 OPENSSL_HEADER_CONF_H +#define OPENSSL_HEADER_CONF_H + +#include + +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// Config files look like: +// +// # Comment +// +// # This key is in the default section. +// key=value +// +// [section_name] +// key2=value2 +// +// Config files are represented by a |CONF|. + +struct conf_value_st { + char *section; + char *name; + char *value; +}; + +struct conf_st { + LHASH_OF(CONF_VALUE) *data; +}; + +DEFINE_STACK_OF(CONF_VALUE) + + +// NCONF_new returns a fresh, empty |CONF|, or NULL on error. The |method| +// argument must be NULL. +OPENSSL_EXPORT CONF *NCONF_new(void *method); + +// NCONF_free frees all the data owned by |conf| and then |conf| itself. +OPENSSL_EXPORT void NCONF_free(CONF *conf); + +// NCONF_load parses the file named |filename| and adds the values found to +// |conf|. It returns one on success and zero on error. In the event of an +// error, if |out_error_line| is not NULL, |*out_error_line| is set to the +// number of the line that contained the error. +int NCONF_load(CONF *conf, const char *filename, long *out_error_line); + +// NCONF_load_bio acts like |NCONF_load| but reads from |bio| rather than from +// a named file. +int NCONF_load_bio(CONF *conf, BIO *bio, long *out_error_line); + +// NCONF_get_section returns a stack of values for a given section in |conf|. +// If |section| is NULL, the default section is returned. It returns NULL on +// error. +STACK_OF(CONF_VALUE) *NCONF_get_section(const CONF *conf, const char *section); + +// NCONF_get_string returns the value of the key |name|, in section |section|. +// The |section| argument may be NULL to indicate the default section. It +// returns the value or NULL on error. +const char *NCONF_get_string(const CONF *conf, const char *section, + const char *name); + + +// Utility functions + +// CONF_parse_list takes a list separated by 'sep' and calls |list_cb| 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. If |list_cb| returns <= 0, then the iteration is halted and that +// value is returned immediately. Otherwise it returns one. Note that |list_cb| +// may be called on an empty member. +int CONF_parse_list(const char *list, char sep, int remove_whitespace, + int (*list_cb)(const char *elem, int len, void *usr), + void *arg); + + +// Deprecated functions + +// These defines do nothing but are provided to make old code easier to +// compile. +#define CONF_MFLAGS_DEFAULT_SECTION 0 +#define CONF_MFLAGS_IGNORE_MISSING_FILE 0 + +// CONF_modules_load_file returns one. BoringSSL is defined to have no config +// file options, thus loading from |filename| always succeeds by doing nothing. +OPENSSL_EXPORT int CONF_modules_load_file(const char *filename, + const char *appname, + unsigned long flags); + +// CONF_modules_free does nothing. +OPENSSL_EXPORT void CONF_modules_free(void); + +// OPENSSL_config does nothing. +OPENSSL_EXPORT void OPENSSL_config(const char *config_name); + +// OPENSSL_no_config does nothing. +OPENSSL_EXPORT void OPENSSL_no_config(void); + + +#if defined(__cplusplus) +} // extern C + +extern "C++" { + +namespace bssl { + +BORINGSSL_MAKE_DELETER(CONF, NCONF_free) + +} // namespace bssl + +} // extern C++ + +#endif + +#define CONF_R_LIST_CANNOT_BE_NULL 100 +#define CONF_R_MISSING_CLOSE_SQUARE_BRACKET 101 +#define CONF_R_MISSING_EQUAL_SIGN 102 +#define CONF_R_NO_CLOSE_BRACE 103 +#define CONF_R_UNABLE_TO_CREATE_NEW_SECTION 104 +#define CONF_R_VARIABLE_HAS_NO_VALUE 105 +#define CONF_R_VARIABLE_EXPANSION_TOO_LONG 106 + +#endif // OPENSSL_HEADER_THREAD_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/cpu.h b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/cpu.h new file mode 100644 index 0000000..3e92bf2 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/cpu.h @@ -0,0 +1,196 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). */ + +#ifndef OPENSSL_HEADER_CPU_H +#define OPENSSL_HEADER_CPU_H + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// Runtime CPU feature support + + +#if defined(OPENSSL_X86) || defined(OPENSSL_X86_64) +// OPENSSL_ia32cap_P contains the Intel CPUID bits when running on an x86 or +// x86-64 system. +// +// Index 0: +// EDX for CPUID where EAX = 1 +// Bit 20 is always zero +// Bit 28 is adjusted to reflect whether the data cache is shared between +// multiple logical cores +// Bit 30 is used to indicate an Intel CPU +// Index 1: +// ECX for CPUID where EAX = 1 +// Bit 11 is used to indicate AMD XOP support, not SDBG +// Index 2: +// EBX for CPUID where EAX = 7 +// Index 3 is set to zero. +// +// Note: the CPUID bits are pre-adjusted for the OSXSAVE bit and the YMM and XMM +// bits in XCR0, so it is not necessary to check those. +extern uint32_t OPENSSL_ia32cap_P[4]; + +#if defined(BORINGSSL_FIPS) +const uint32_t *OPENSSL_ia32cap_get(void); +#else +static inline const uint32_t *OPENSSL_ia32cap_get(void) { + return OPENSSL_ia32cap_P; +} +#endif + +#endif + +#if defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64) + +#if defined(OPENSSL_APPLE) +// iOS builds use the static ARM configuration. +#define OPENSSL_STATIC_ARMCAP +#endif + +#if !defined(OPENSSL_STATIC_ARMCAP) + +// CRYPTO_is_NEON_capable_at_runtime returns true if the current CPU has a NEON +// unit. Note that |OPENSSL_armcap_P| also exists and contains the same +// information in a form that's easier for assembly to use. +OPENSSL_EXPORT char CRYPTO_is_NEON_capable_at_runtime(void); + +// CRYPTO_is_NEON_capable returns true if the current CPU has a NEON unit. If +// this is known statically then it returns one immediately. +static inline int CRYPTO_is_NEON_capable(void) { + // Only statically skip the runtime lookup on aarch64. On arm, one CPU is + // known to have a broken NEON unit which is known to fail with on some + // hand-written NEON assembly. For now, continue to apply the workaround even + // when the compiler is instructed to freely emit NEON code. See + // https://crbug.com/341598 and https://crbug.com/606629. +#if defined(__ARM_NEON__) && !defined(OPENSSL_ARM) + return 1; +#else + return CRYPTO_is_NEON_capable_at_runtime(); +#endif +} + +#if defined(OPENSSL_ARM) +// CRYPTO_has_broken_NEON returns one if the current CPU is known to have a +// broken NEON unit. See https://crbug.com/341598. +OPENSSL_EXPORT int CRYPTO_has_broken_NEON(void); + +// CRYPTO_needs_hwcap2_workaround returns one if the ARMv8 AArch32 AT_HWCAP2 +// workaround was needed. See https://crbug.com/boringssl/46. +OPENSSL_EXPORT int CRYPTO_needs_hwcap2_workaround(void); +#endif + +// CRYPTO_is_ARMv8_AES_capable returns true if the current CPU supports the +// ARMv8 AES instruction. +int CRYPTO_is_ARMv8_AES_capable(void); + +// CRYPTO_is_ARMv8_PMULL_capable returns true if the current CPU supports the +// ARMv8 PMULL instruction. +int CRYPTO_is_ARMv8_PMULL_capable(void); + +#else + +static inline int CRYPTO_is_NEON_capable(void) { +#if defined(OPENSSL_STATIC_ARMCAP_NEON) || defined(__ARM_NEON__) + return 1; +#else + return 0; +#endif +} + +static inline int CRYPTO_is_ARMv8_AES_capable(void) { +#if defined(OPENSSL_STATIC_ARMCAP_AES) || defined(__ARM_FEATURE_CRYPTO) + return 1; +#else + return 0; +#endif +} + +static inline int CRYPTO_is_ARMv8_PMULL_capable(void) { +#if defined(OPENSSL_STATIC_ARMCAP_PMULL) || defined(__ARM_FEATURE_CRYPTO) + return 1; +#else + return 0; +#endif +} + +#endif // OPENSSL_STATIC_ARMCAP +#endif // OPENSSL_ARM || OPENSSL_AARCH64 + +#if defined(OPENSSL_PPC64LE) + +// CRYPTO_is_PPC64LE_vcrypto_capable returns true iff the current CPU supports +// the Vector.AES category of instructions. +int CRYPTO_is_PPC64LE_vcrypto_capable(void); + +extern unsigned long OPENSSL_ppc64le_hwcap2; + +#endif // OPENSSL_PPC64LE + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_CPU_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/cpu.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/cpu.h.grpc_back new file mode 100644 index 0000000..dd95ddc --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/cpu.h.grpc_back @@ -0,0 +1,196 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). */ + +#ifndef OPENSSL_HEADER_CPU_H +#define OPENSSL_HEADER_CPU_H + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// Runtime CPU feature support + + +#if defined(OPENSSL_X86) || defined(OPENSSL_X86_64) +// OPENSSL_ia32cap_P contains the Intel CPUID bits when running on an x86 or +// x86-64 system. +// +// Index 0: +// EDX for CPUID where EAX = 1 +// Bit 20 is always zero +// Bit 28 is adjusted to reflect whether the data cache is shared between +// multiple logical cores +// Bit 30 is used to indicate an Intel CPU +// Index 1: +// ECX for CPUID where EAX = 1 +// Bit 11 is used to indicate AMD XOP support, not SDBG +// Index 2: +// EBX for CPUID where EAX = 7 +// Index 3 is set to zero. +// +// Note: the CPUID bits are pre-adjusted for the OSXSAVE bit and the YMM and XMM +// bits in XCR0, so it is not necessary to check those. +extern uint32_t OPENSSL_ia32cap_P[4]; + +#if defined(BORINGSSL_FIPS) +const uint32_t *OPENSSL_ia32cap_get(void); +#else +static inline const uint32_t *OPENSSL_ia32cap_get(void) { + return OPENSSL_ia32cap_P; +} +#endif + +#endif + +#if defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64) + +#if defined(OPENSSL_APPLE) +// iOS builds use the static ARM configuration. +#define OPENSSL_STATIC_ARMCAP +#endif + +#if !defined(OPENSSL_STATIC_ARMCAP) + +// CRYPTO_is_NEON_capable_at_runtime returns true if the current CPU has a NEON +// unit. Note that |OPENSSL_armcap_P| also exists and contains the same +// information in a form that's easier for assembly to use. +OPENSSL_EXPORT char CRYPTO_is_NEON_capable_at_runtime(void); + +// CRYPTO_is_NEON_capable returns true if the current CPU has a NEON unit. If +// this is known statically then it returns one immediately. +static inline int CRYPTO_is_NEON_capable(void) { + // Only statically skip the runtime lookup on aarch64. On arm, one CPU is + // known to have a broken NEON unit which is known to fail with on some + // hand-written NEON assembly. For now, continue to apply the workaround even + // when the compiler is instructed to freely emit NEON code. See + // https://crbug.com/341598 and https://crbug.com/606629. +#if defined(__ARM_NEON__) && !defined(OPENSSL_ARM) + return 1; +#else + return CRYPTO_is_NEON_capable_at_runtime(); +#endif +} + +#if defined(OPENSSL_ARM) +// CRYPTO_has_broken_NEON returns one if the current CPU is known to have a +// broken NEON unit. See https://crbug.com/341598. +OPENSSL_EXPORT int CRYPTO_has_broken_NEON(void); + +// CRYPTO_needs_hwcap2_workaround returns one if the ARMv8 AArch32 AT_HWCAP2 +// workaround was needed. See https://crbug.com/boringssl/46. +OPENSSL_EXPORT int CRYPTO_needs_hwcap2_workaround(void); +#endif + +// CRYPTO_is_ARMv8_AES_capable returns true if the current CPU supports the +// ARMv8 AES instruction. +int CRYPTO_is_ARMv8_AES_capable(void); + +// CRYPTO_is_ARMv8_PMULL_capable returns true if the current CPU supports the +// ARMv8 PMULL instruction. +int CRYPTO_is_ARMv8_PMULL_capable(void); + +#else + +static inline int CRYPTO_is_NEON_capable(void) { +#if defined(OPENSSL_STATIC_ARMCAP_NEON) || defined(__ARM_NEON__) + return 1; +#else + return 0; +#endif +} + +static inline int CRYPTO_is_ARMv8_AES_capable(void) { +#if defined(OPENSSL_STATIC_ARMCAP_AES) || defined(__ARM_FEATURE_CRYPTO) + return 1; +#else + return 0; +#endif +} + +static inline int CRYPTO_is_ARMv8_PMULL_capable(void) { +#if defined(OPENSSL_STATIC_ARMCAP_PMULL) || defined(__ARM_FEATURE_CRYPTO) + return 1; +#else + return 0; +#endif +} + +#endif // OPENSSL_STATIC_ARMCAP +#endif // OPENSSL_ARM || OPENSSL_AARCH64 + +#if defined(OPENSSL_PPC64LE) + +// CRYPTO_is_PPC64LE_vcrypto_capable returns true iff the current CPU supports +// the Vector.AES category of instructions. +int CRYPTO_is_PPC64LE_vcrypto_capable(void); + +extern unsigned long OPENSSL_ppc64le_hwcap2; + +#endif // OPENSSL_PPC64LE + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_CPU_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/crypto.h b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/crypto.h new file mode 100644 index 0000000..3c2b35b --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/crypto.h @@ -0,0 +1,122 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_CRYPTO_H +#define OPENSSL_HEADER_CRYPTO_H + +#include + +// Upstream OpenSSL defines |OPENSSL_malloc|, etc., in crypto.h rather than +// mem.h. +#include + +// Upstream OpenSSL defines |CRYPTO_LOCK|, etc., in crypto.h rather than +// thread.h. +#include + + +#if defined(__cplusplus) +extern "C" { +#endif + + +// crypto.h contains functions for initializing the crypto library. + + +// CRYPTO_library_init initializes the crypto library. It must be called if the +// library is built with BORINGSSL_NO_STATIC_INITIALIZER. Otherwise, it does +// nothing and a static initializer is used instead. It is safe to call this +// function multiple times and concurrently from multiple threads. +// +// On some ARM configurations, this function may require filesystem access and +// should be called before entering a sandbox. +OPENSSL_EXPORT void CRYPTO_library_init(void); + +// CRYPTO_is_confidential_build returns one if the linked version of BoringSSL +// has been built with the BORINGSSL_CONFIDENTIAL define and zero otherwise. +// +// This is used by some consumers to identify whether they are using an +// internal version of BoringSSL. +OPENSSL_EXPORT int CRYPTO_is_confidential_build(void); + +// CRYPTO_has_asm returns one unless BoringSSL was built with OPENSSL_NO_ASM, +// in which case it returns zero. +OPENSSL_EXPORT int CRYPTO_has_asm(void); + +// FIPS_mode returns zero unless BoringSSL is built with BORINGSSL_FIPS, in +// which case it returns one. +OPENSSL_EXPORT int FIPS_mode(void); + +// BORINGSSL_self_test triggers the FIPS KAT-based self tests. It returns one +// on success and zero on error. +OPENSSL_EXPORT int BORINGSSL_self_test(void); + + +// Deprecated functions. + +// OPENSSL_VERSION_TEXT contains a string the identifies the version of +// “OpenSSL”. node.js requires a version number in this text. +#define OPENSSL_VERSION_TEXT "OpenSSL 1.1.0 (compatible; BoringSSL)" + +#define SSLEAY_VERSION 0 + +// SSLeay_version is a compatibility function that returns the string +// "BoringSSL". +OPENSSL_EXPORT const char *SSLeay_version(int unused); + +#define OPENSSL_VERSION 0 + +// OpenSSL_version is a compatibility function that returns the string +// "BoringSSL". +OPENSSL_EXPORT const char *OpenSSL_version(int unused); + +// SSLeay is a compatibility function that returns OPENSSL_VERSION_NUMBER from +// base.h. +OPENSSL_EXPORT unsigned long SSLeay(void); + +// OpenSSL_version_num is a compatibility function that returns +// OPENSSL_VERSION_NUMBER from base.h. +OPENSSL_EXPORT unsigned long OpenSSL_version_num(void); + +// CRYPTO_malloc_init returns one. +OPENSSL_EXPORT int CRYPTO_malloc_init(void); + +// ENGINE_load_builtin_engines does nothing. +OPENSSL_EXPORT void ENGINE_load_builtin_engines(void); + +// ENGINE_register_all_complete returns one. +OPENSSL_EXPORT int ENGINE_register_all_complete(void); + +// OPENSSL_load_builtin_modules does nothing. +OPENSSL_EXPORT void OPENSSL_load_builtin_modules(void); + +#define OPENSSL_INIT_NO_LOAD_CRYPTO_STRINGS 0 +#define OPENSSL_INIT_LOAD_CRYPTO_STRINGS 0 +#define OPENSSL_INIT_ADD_ALL_CIPHERS 0 +#define OPENSSL_INIT_ADD_ALL_DIGESTS 0 +#define OPENSSL_INIT_NO_ADD_ALL_CIPHERS 0 +#define OPENSSL_INIT_NO_ADD_ALL_DIGESTS 0 +#define OPENSSL_INIT_LOAD_CONFIG 0 +#define OPENSSL_INIT_NO_LOAD_CONFIG 0 + +// OPENSSL_init_crypto calls |CRYPTO_library_init| and returns one. +OPENSSL_EXPORT int OPENSSL_init_crypto(uint64_t opts, + const OPENSSL_INIT_SETTINGS *settings); + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_CRYPTO_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/crypto.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/crypto.h.grpc_back new file mode 100644 index 0000000..ccf5012 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/crypto.h.grpc_back @@ -0,0 +1,122 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_CRYPTO_H +#define OPENSSL_HEADER_CRYPTO_H + +#include + +// Upstream OpenSSL defines |OPENSSL_malloc|, etc., in crypto.h rather than +// mem.h. +#include + +// Upstream OpenSSL defines |CRYPTO_LOCK|, etc., in crypto.h rather than +// thread.h. +#include + + +#if defined(__cplusplus) +extern "C" { +#endif + + +// crypto.h contains functions for initializing the crypto library. + + +// CRYPTO_library_init initializes the crypto library. It must be called if the +// library is built with BORINGSSL_NO_STATIC_INITIALIZER. Otherwise, it does +// nothing and a static initializer is used instead. It is safe to call this +// function multiple times and concurrently from multiple threads. +// +// On some ARM configurations, this function may require filesystem access and +// should be called before entering a sandbox. +OPENSSL_EXPORT void CRYPTO_library_init(void); + +// CRYPTO_is_confidential_build returns one if the linked version of BoringSSL +// has been built with the BORINGSSL_CONFIDENTIAL define and zero otherwise. +// +// This is used by some consumers to identify whether they are using an +// internal version of BoringSSL. +OPENSSL_EXPORT int CRYPTO_is_confidential_build(void); + +// CRYPTO_has_asm returns one unless BoringSSL was built with OPENSSL_NO_ASM, +// in which case it returns zero. +OPENSSL_EXPORT int CRYPTO_has_asm(void); + +// FIPS_mode returns zero unless BoringSSL is built with BORINGSSL_FIPS, in +// which case it returns one. +OPENSSL_EXPORT int FIPS_mode(void); + +// BORINGSSL_self_test triggers the FIPS KAT-based self tests. It returns one +// on success and zero on error. +OPENSSL_EXPORT int BORINGSSL_self_test(void); + + +// Deprecated functions. + +// OPENSSL_VERSION_TEXT contains a string the identifies the version of +// “OpenSSL”. node.js requires a version number in this text. +#define OPENSSL_VERSION_TEXT "OpenSSL 1.1.0 (compatible; BoringSSL)" + +#define SSLEAY_VERSION 0 + +// SSLeay_version is a compatibility function that returns the string +// "BoringSSL". +OPENSSL_EXPORT const char *SSLeay_version(int unused); + +#define OPENSSL_VERSION 0 + +// OpenSSL_version is a compatibility function that returns the string +// "BoringSSL". +OPENSSL_EXPORT const char *OpenSSL_version(int unused); + +// SSLeay is a compatibility function that returns OPENSSL_VERSION_NUMBER from +// base.h. +OPENSSL_EXPORT unsigned long SSLeay(void); + +// OpenSSL_version_num is a compatibility function that returns +// OPENSSL_VERSION_NUMBER from base.h. +OPENSSL_EXPORT unsigned long OpenSSL_version_num(void); + +// CRYPTO_malloc_init returns one. +OPENSSL_EXPORT int CRYPTO_malloc_init(void); + +// ENGINE_load_builtin_engines does nothing. +OPENSSL_EXPORT void ENGINE_load_builtin_engines(void); + +// ENGINE_register_all_complete returns one. +OPENSSL_EXPORT int ENGINE_register_all_complete(void); + +// OPENSSL_load_builtin_modules does nothing. +OPENSSL_EXPORT void OPENSSL_load_builtin_modules(void); + +#define OPENSSL_INIT_NO_LOAD_CRYPTO_STRINGS 0 +#define OPENSSL_INIT_LOAD_CRYPTO_STRINGS 0 +#define OPENSSL_INIT_ADD_ALL_CIPHERS 0 +#define OPENSSL_INIT_ADD_ALL_DIGESTS 0 +#define OPENSSL_INIT_NO_ADD_ALL_CIPHERS 0 +#define OPENSSL_INIT_NO_ADD_ALL_DIGESTS 0 +#define OPENSSL_INIT_LOAD_CONFIG 0 +#define OPENSSL_INIT_NO_LOAD_CONFIG 0 + +// OPENSSL_init_crypto calls |CRYPTO_library_init| and returns one. +OPENSSL_EXPORT int OPENSSL_init_crypto(uint64_t opts, + const OPENSSL_INIT_SETTINGS *settings); + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_CRYPTO_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/curve25519.h b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/curve25519.h new file mode 100644 index 0000000..75c88cc --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/curve25519.h @@ -0,0 +1,201 @@ +/* Copyright (c) 2015, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_CURVE25519_H +#define OPENSSL_HEADER_CURVE25519_H + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// Curve25519. +// +// Curve25519 is an elliptic curve. See https://tools.ietf.org/html/rfc7748. + + +// X25519. +// +// X25519 is the Diffie-Hellman primitive built from curve25519. It is +// sometimes referred to as “curve25519”, but “X25519” is a more precise name. +// See http://cr.yp.to/ecdh.html and https://tools.ietf.org/html/rfc7748. + +#define X25519_PRIVATE_KEY_LEN 32 +#define X25519_PUBLIC_VALUE_LEN 32 +#define X25519_SHARED_KEY_LEN 32 + +// X25519_keypair sets |out_public_value| and |out_private_key| to a freshly +// generated, public–private key pair. +OPENSSL_EXPORT void X25519_keypair(uint8_t out_public_value[32], + uint8_t out_private_key[32]); + +// X25519 writes a shared key to |out_shared_key| that is calculated from the +// given private key and the peer's public value. It returns one on success and +// zero on error. +// +// Don't use the shared key directly, rather use a KDF and also include the two +// public values as inputs. +OPENSSL_EXPORT int X25519(uint8_t out_shared_key[32], + const uint8_t private_key[32], + const uint8_t peer_public_value[32]); + +// X25519_public_from_private calculates a Diffie-Hellman public value from the +// given private key and writes it to |out_public_value|. +OPENSSL_EXPORT void X25519_public_from_private(uint8_t out_public_value[32], + const uint8_t private_key[32]); + + +// Ed25519. +// +// Ed25519 is a signature scheme using a twisted-Edwards curve that is +// birationally equivalent to curve25519. +// +// Note that, unlike RFC 8032's formulation, our private key representation +// includes a public key suffix to make multiple key signing operations with the +// same key more efficient. The RFC 8032 key private key is referred to in this +// implementation as the "seed" and is the first 32 bytes of our private key. + +#define ED25519_PRIVATE_KEY_LEN 64 +#define ED25519_PUBLIC_KEY_LEN 32 +#define ED25519_SIGNATURE_LEN 64 + +// ED25519_keypair sets |out_public_key| and |out_private_key| to a freshly +// generated, public–private key pair. +OPENSSL_EXPORT void ED25519_keypair(uint8_t out_public_key[32], + uint8_t out_private_key[64]); + +// ED25519_sign sets |out_sig| to be a signature of |message_len| bytes from +// |message| using |private_key|. It returns one on success or zero on +// error. +OPENSSL_EXPORT int ED25519_sign(uint8_t out_sig[64], const uint8_t *message, + size_t message_len, + const uint8_t private_key[64]); + +// ED25519_verify returns one iff |signature| is a valid signature, by +// |public_key| of |message_len| bytes from |message|. It returns zero +// otherwise. +OPENSSL_EXPORT int ED25519_verify(const uint8_t *message, size_t message_len, + const uint8_t signature[64], + const uint8_t public_key[32]); + +// ED25519_keypair_from_seed calculates a public and private key from an +// Ed25519 “seed”. Seed values are not exposed by this API (although they +// happen to be the first 32 bytes of a private key) so this function is for +// interoperating with systems that may store just a seed instead of a full +// private key. +OPENSSL_EXPORT void ED25519_keypair_from_seed(uint8_t out_public_key[32], + uint8_t out_private_key[64], + const uint8_t seed[32]); + + +// SPAKE2. +// +// SPAKE2 is a password-authenticated key-exchange. It allows two parties, +// who share a low-entropy secret (i.e. password), to agree on a shared key. +// An attacker can only make one guess of the password per execution of the +// protocol. +// +// See https://tools.ietf.org/html/draft-irtf-cfrg-spake2-02. + +// spake2_role_t enumerates the different “roles” in SPAKE2. The protocol +// requires that the symmetry of the two parties be broken so one participant +// must be “Alice” and the other be “Bob”. +enum spake2_role_t { + spake2_role_alice, + spake2_role_bob, +}; + +// SPAKE2_CTX_new creates a new |SPAKE2_CTX| (which can only be used for a +// single execution of the protocol). SPAKE2 requires the symmetry of the two +// parties to be broken which is indicated via |my_role| – each party must pass +// a different value for this argument. +// +// The |my_name| and |their_name| arguments allow optional, opaque names to be +// bound into the protocol. For example MAC addresses, hostnames, usernames +// etc. These values are not exposed and can avoid context-confusion attacks +// when a password is shared between several devices. +OPENSSL_EXPORT SPAKE2_CTX *SPAKE2_CTX_new( + enum spake2_role_t my_role, + const uint8_t *my_name, size_t my_name_len, + const uint8_t *their_name, size_t their_name_len); + +// SPAKE2_CTX_free frees |ctx| and all the resources that it has allocated. +OPENSSL_EXPORT void SPAKE2_CTX_free(SPAKE2_CTX *ctx); + +// SPAKE2_MAX_MSG_SIZE is the maximum size of a SPAKE2 message. +#define SPAKE2_MAX_MSG_SIZE 32 + +// SPAKE2_generate_msg generates a SPAKE2 message given |password|, writes +// it to |out| and sets |*out_len| to the number of bytes written. +// +// At most |max_out_len| bytes are written to |out| and, in order to ensure +// success, |max_out_len| should be at least |SPAKE2_MAX_MSG_SIZE| bytes. +// +// This function can only be called once for a given |SPAKE2_CTX|. +// +// It returns one on success and zero on error. +OPENSSL_EXPORT int SPAKE2_generate_msg(SPAKE2_CTX *ctx, uint8_t *out, + size_t *out_len, size_t max_out_len, + const uint8_t *password, + size_t password_len); + +// SPAKE2_MAX_KEY_SIZE is the maximum amount of key material that SPAKE2 will +// produce. +#define SPAKE2_MAX_KEY_SIZE 64 + +// SPAKE2_process_msg completes the SPAKE2 exchange given the peer's message in +// |their_msg|, writes at most |max_out_key_len| bytes to |out_key| and sets +// |*out_key_len| to the number of bytes written. +// +// The resulting keying material is suitable for: +// a) Using directly in a key-confirmation step: i.e. each side could +// transmit a hash of their role, a channel-binding value and the key +// material to prove to the other side that they know the shared key. +// b) Using as input keying material to HKDF to generate a variety of subkeys +// for encryption etc. +// +// If |max_out_key_key| is smaller than the amount of key material generated +// then the key is silently truncated. If you want to ensure that no truncation +// occurs then |max_out_key| should be at least |SPAKE2_MAX_KEY_SIZE|. +// +// You must call |SPAKE2_generate_msg| on a given |SPAKE2_CTX| before calling +// this function. On successful return, |ctx| is complete and calling +// |SPAKE2_CTX_free| is the only acceptable operation on it. +// +// Returns one on success or zero on error. +OPENSSL_EXPORT int SPAKE2_process_msg(SPAKE2_CTX *ctx, uint8_t *out_key, + size_t *out_key_len, + size_t max_out_key_len, + const uint8_t *their_msg, + size_t their_msg_len); + + +#if defined(__cplusplus) +} // extern C + +extern "C++" { + +namespace bssl { + +BORINGSSL_MAKE_DELETER(SPAKE2_CTX, SPAKE2_CTX_free) + +} // namespace bssl + +} // extern C++ + +#endif + +#endif // OPENSSL_HEADER_CURVE25519_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/curve25519.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/curve25519.h.grpc_back new file mode 100644 index 0000000..58a181f --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/curve25519.h.grpc_back @@ -0,0 +1,201 @@ +/* Copyright (c) 2015, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_CURVE25519_H +#define OPENSSL_HEADER_CURVE25519_H + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// Curve25519. +// +// Curve25519 is an elliptic curve. See https://tools.ietf.org/html/rfc7748. + + +// X25519. +// +// X25519 is the Diffie-Hellman primitive built from curve25519. It is +// sometimes referred to as “curve25519”, but “X25519” is a more precise name. +// See http://cr.yp.to/ecdh.html and https://tools.ietf.org/html/rfc7748. + +#define X25519_PRIVATE_KEY_LEN 32 +#define X25519_PUBLIC_VALUE_LEN 32 +#define X25519_SHARED_KEY_LEN 32 + +// X25519_keypair sets |out_public_value| and |out_private_key| to a freshly +// generated, public–private key pair. +OPENSSL_EXPORT void X25519_keypair(uint8_t out_public_value[32], + uint8_t out_private_key[32]); + +// X25519 writes a shared key to |out_shared_key| that is calculated from the +// given private key and the peer's public value. It returns one on success and +// zero on error. +// +// Don't use the shared key directly, rather use a KDF and also include the two +// public values as inputs. +OPENSSL_EXPORT int X25519(uint8_t out_shared_key[32], + const uint8_t private_key[32], + const uint8_t peer_public_value[32]); + +// X25519_public_from_private calculates a Diffie-Hellman public value from the +// given private key and writes it to |out_public_value|. +OPENSSL_EXPORT void X25519_public_from_private(uint8_t out_public_value[32], + const uint8_t private_key[32]); + + +// Ed25519. +// +// Ed25519 is a signature scheme using a twisted-Edwards curve that is +// birationally equivalent to curve25519. +// +// Note that, unlike RFC 8032's formulation, our private key representation +// includes a public key suffix to make multiple key signing operations with the +// same key more efficient. The RFC 8032 key private key is referred to in this +// implementation as the "seed" and is the first 32 bytes of our private key. + +#define ED25519_PRIVATE_KEY_LEN 64 +#define ED25519_PUBLIC_KEY_LEN 32 +#define ED25519_SIGNATURE_LEN 64 + +// ED25519_keypair sets |out_public_key| and |out_private_key| to a freshly +// generated, public–private key pair. +OPENSSL_EXPORT void ED25519_keypair(uint8_t out_public_key[32], + uint8_t out_private_key[64]); + +// ED25519_sign sets |out_sig| to be a signature of |message_len| bytes from +// |message| using |private_key|. It returns one on success or zero on +// error. +OPENSSL_EXPORT int ED25519_sign(uint8_t out_sig[64], const uint8_t *message, + size_t message_len, + const uint8_t private_key[64]); + +// ED25519_verify returns one iff |signature| is a valid signature, by +// |public_key| of |message_len| bytes from |message|. It returns zero +// otherwise. +OPENSSL_EXPORT int ED25519_verify(const uint8_t *message, size_t message_len, + const uint8_t signature[64], + const uint8_t public_key[32]); + +// ED25519_keypair_from_seed calculates a public and private key from an +// Ed25519 “seed”. Seed values are not exposed by this API (although they +// happen to be the first 32 bytes of a private key) so this function is for +// interoperating with systems that may store just a seed instead of a full +// private key. +OPENSSL_EXPORT void ED25519_keypair_from_seed(uint8_t out_public_key[32], + uint8_t out_private_key[64], + const uint8_t seed[32]); + + +// SPAKE2. +// +// SPAKE2 is a password-authenticated key-exchange. It allows two parties, +// who share a low-entropy secret (i.e. password), to agree on a shared key. +// An attacker can only make one guess of the password per execution of the +// protocol. +// +// See https://tools.ietf.org/html/draft-irtf-cfrg-spake2-02. + +// spake2_role_t enumerates the different “roles” in SPAKE2. The protocol +// requires that the symmetry of the two parties be broken so one participant +// must be “Alice” and the other be “Bob”. +enum spake2_role_t { + spake2_role_alice, + spake2_role_bob, +}; + +// SPAKE2_CTX_new creates a new |SPAKE2_CTX| (which can only be used for a +// single execution of the protocol). SPAKE2 requires the symmetry of the two +// parties to be broken which is indicated via |my_role| – each party must pass +// a different value for this argument. +// +// The |my_name| and |their_name| arguments allow optional, opaque names to be +// bound into the protocol. For example MAC addresses, hostnames, usernames +// etc. These values are not exposed and can avoid context-confusion attacks +// when a password is shared between several devices. +OPENSSL_EXPORT SPAKE2_CTX *SPAKE2_CTX_new( + enum spake2_role_t my_role, + const uint8_t *my_name, size_t my_name_len, + const uint8_t *their_name, size_t their_name_len); + +// SPAKE2_CTX_free frees |ctx| and all the resources that it has allocated. +OPENSSL_EXPORT void SPAKE2_CTX_free(SPAKE2_CTX *ctx); + +// SPAKE2_MAX_MSG_SIZE is the maximum size of a SPAKE2 message. +#define SPAKE2_MAX_MSG_SIZE 32 + +// SPAKE2_generate_msg generates a SPAKE2 message given |password|, writes +// it to |out| and sets |*out_len| to the number of bytes written. +// +// At most |max_out_len| bytes are written to |out| and, in order to ensure +// success, |max_out_len| should be at least |SPAKE2_MAX_MSG_SIZE| bytes. +// +// This function can only be called once for a given |SPAKE2_CTX|. +// +// It returns one on success and zero on error. +OPENSSL_EXPORT int SPAKE2_generate_msg(SPAKE2_CTX *ctx, uint8_t *out, + size_t *out_len, size_t max_out_len, + const uint8_t *password, + size_t password_len); + +// SPAKE2_MAX_KEY_SIZE is the maximum amount of key material that SPAKE2 will +// produce. +#define SPAKE2_MAX_KEY_SIZE 64 + +// SPAKE2_process_msg completes the SPAKE2 exchange given the peer's message in +// |their_msg|, writes at most |max_out_key_len| bytes to |out_key| and sets +// |*out_key_len| to the number of bytes written. +// +// The resulting keying material is suitable for: +// a) Using directly in a key-confirmation step: i.e. each side could +// transmit a hash of their role, a channel-binding value and the key +// material to prove to the other side that they know the shared key. +// b) Using as input keying material to HKDF to generate a variety of subkeys +// for encryption etc. +// +// If |max_out_key_key| is smaller than the amount of key material generated +// then the key is silently truncated. If you want to ensure that no truncation +// occurs then |max_out_key| should be at least |SPAKE2_MAX_KEY_SIZE|. +// +// You must call |SPAKE2_generate_msg| on a given |SPAKE2_CTX| before calling +// this function. On successful return, |ctx| is complete and calling +// |SPAKE2_CTX_free| is the only acceptable operation on it. +// +// Returns one on success or zero on error. +OPENSSL_EXPORT int SPAKE2_process_msg(SPAKE2_CTX *ctx, uint8_t *out_key, + size_t *out_key_len, + size_t max_out_key_len, + const uint8_t *their_msg, + size_t their_msg_len); + + +#if defined(__cplusplus) +} // extern C + +extern "C++" { + +namespace bssl { + +BORINGSSL_MAKE_DELETER(SPAKE2_CTX, SPAKE2_CTX_free) + +} // namespace bssl + +} // extern C++ + +#endif + +#endif // OPENSSL_HEADER_CURVE25519_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/des.h b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/des.h new file mode 100644 index 0000000..a817755 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/des.h @@ -0,0 +1,177 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 OPENSSL_HEADER_DES_H +#define OPENSSL_HEADER_DES_H + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// DES. + + +typedef struct DES_cblock_st { + uint8_t bytes[8]; +} DES_cblock; + +typedef struct DES_ks { + uint32_t subkeys[16][2]; +} DES_key_schedule; + + +#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 + +// DES_set_key performs a key schedule and initialises |schedule| with |key|. +OPENSSL_EXPORT void DES_set_key(const DES_cblock *key, + DES_key_schedule *schedule); + +// DES_set_odd_parity sets the parity bits (the least-significant bits in each +// byte) of |key| given the other bits in each byte. +OPENSSL_EXPORT void DES_set_odd_parity(DES_cblock *key); + +// DES_ecb_encrypt encrypts (or decrypts, if |is_encrypt| is |DES_DECRYPT|) a +// single DES block (8 bytes) from in to out, using the key configured in +// |schedule|. +OPENSSL_EXPORT void DES_ecb_encrypt(const DES_cblock *in, DES_cblock *out, + const DES_key_schedule *schedule, + int is_encrypt); + +// DES_ncbc_encrypt encrypts (or decrypts, if |enc| is |DES_DECRYPT|) |len| +// bytes from |in| to |out| with DES in CBC mode. +OPENSSL_EXPORT void DES_ncbc_encrypt(const uint8_t *in, uint8_t *out, + size_t len, + const DES_key_schedule *schedule, + DES_cblock *ivec, int enc); + +// DES_ecb3_encrypt encrypts (or decrypts, if |enc| is |DES_DECRYPT|) a single +// block (8 bytes) of data from |input| to |output| using 3DES. +OPENSSL_EXPORT void DES_ecb3_encrypt(const DES_cblock *input, + DES_cblock *output, + const DES_key_schedule *ks1, + const DES_key_schedule *ks2, + const DES_key_schedule *ks3, + int enc); + +// DES_ede3_cbc_encrypt encrypts (or decrypts, if |enc| is |DES_DECRYPT|) |len| +// bytes from |in| to |out| with 3DES in CBC mode. 3DES uses three keys, thus +// the function takes three different |DES_key_schedule|s. +OPENSSL_EXPORT void DES_ede3_cbc_encrypt(const uint8_t *in, uint8_t *out, + size_t len, + const DES_key_schedule *ks1, + const DES_key_schedule *ks2, + const DES_key_schedule *ks3, + DES_cblock *ivec, int enc); + +// DES_ede2_cbc_encrypt encrypts (or decrypts, if |enc| is |DES_DECRYPT|) |len| +// bytes from |in| to |out| with 3DES in CBC mode. With this keying option, the +// first and third 3DES keys are identical. Thus, this function takes only two +// different |DES_key_schedule|s. +OPENSSL_EXPORT void DES_ede2_cbc_encrypt(const uint8_t *in, uint8_t *out, + size_t len, + const DES_key_schedule *ks1, + const DES_key_schedule *ks2, + DES_cblock *ivec, int enc); + + +// Deprecated functions. + +// DES_set_key_unchecked calls |DES_set_key|. +OPENSSL_EXPORT void DES_set_key_unchecked(const DES_cblock *key, + DES_key_schedule *schedule); + +OPENSSL_EXPORT void DES_ede3_cfb64_encrypt(const uint8_t *in, uint8_t *out, + long length, DES_key_schedule *ks1, + DES_key_schedule *ks2, + DES_key_schedule *ks3, + DES_cblock *ivec, int *num, int enc); + +OPENSSL_EXPORT void DES_ede3_cfb_encrypt(const uint8_t *in, uint8_t *out, + int numbits, long length, + DES_key_schedule *ks1, + DES_key_schedule *ks2, + DES_key_schedule *ks3, + DES_cblock *ivec, int enc); + + +// Private functions. +// +// These functions are only exported for use in |decrepit|. + +OPENSSL_EXPORT void DES_decrypt3(uint32_t *data, const DES_key_schedule *ks1, + const DES_key_schedule *ks2, + const DES_key_schedule *ks3); + +OPENSSL_EXPORT void DES_encrypt3(uint32_t *data, const DES_key_schedule *ks1, + const DES_key_schedule *ks2, + const DES_key_schedule *ks3); + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_DES_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/des.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/des.h.grpc_back new file mode 100644 index 0000000..af1c822 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/des.h.grpc_back @@ -0,0 +1,177 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 OPENSSL_HEADER_DES_H +#define OPENSSL_HEADER_DES_H + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// DES. + + +typedef struct DES_cblock_st { + uint8_t bytes[8]; +} DES_cblock; + +typedef struct DES_ks { + uint32_t subkeys[16][2]; +} DES_key_schedule; + + +#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 + +// DES_set_key performs a key schedule and initialises |schedule| with |key|. +OPENSSL_EXPORT void DES_set_key(const DES_cblock *key, + DES_key_schedule *schedule); + +// DES_set_odd_parity sets the parity bits (the least-significant bits in each +// byte) of |key| given the other bits in each byte. +OPENSSL_EXPORT void DES_set_odd_parity(DES_cblock *key); + +// DES_ecb_encrypt encrypts (or decrypts, if |is_encrypt| is |DES_DECRYPT|) a +// single DES block (8 bytes) from in to out, using the key configured in +// |schedule|. +OPENSSL_EXPORT void DES_ecb_encrypt(const DES_cblock *in, DES_cblock *out, + const DES_key_schedule *schedule, + int is_encrypt); + +// DES_ncbc_encrypt encrypts (or decrypts, if |enc| is |DES_DECRYPT|) |len| +// bytes from |in| to |out| with DES in CBC mode. +OPENSSL_EXPORT void DES_ncbc_encrypt(const uint8_t *in, uint8_t *out, + size_t len, + const DES_key_schedule *schedule, + DES_cblock *ivec, int enc); + +// DES_ecb3_encrypt encrypts (or decrypts, if |enc| is |DES_DECRYPT|) a single +// block (8 bytes) of data from |input| to |output| using 3DES. +OPENSSL_EXPORT void DES_ecb3_encrypt(const DES_cblock *input, + DES_cblock *output, + const DES_key_schedule *ks1, + const DES_key_schedule *ks2, + const DES_key_schedule *ks3, + int enc); + +// DES_ede3_cbc_encrypt encrypts (or decrypts, if |enc| is |DES_DECRYPT|) |len| +// bytes from |in| to |out| with 3DES in CBC mode. 3DES uses three keys, thus +// the function takes three different |DES_key_schedule|s. +OPENSSL_EXPORT void DES_ede3_cbc_encrypt(const uint8_t *in, uint8_t *out, + size_t len, + const DES_key_schedule *ks1, + const DES_key_schedule *ks2, + const DES_key_schedule *ks3, + DES_cblock *ivec, int enc); + +// DES_ede2_cbc_encrypt encrypts (or decrypts, if |enc| is |DES_DECRYPT|) |len| +// bytes from |in| to |out| with 3DES in CBC mode. With this keying option, the +// first and third 3DES keys are identical. Thus, this function takes only two +// different |DES_key_schedule|s. +OPENSSL_EXPORT void DES_ede2_cbc_encrypt(const uint8_t *in, uint8_t *out, + size_t len, + const DES_key_schedule *ks1, + const DES_key_schedule *ks2, + DES_cblock *ivec, int enc); + + +// Deprecated functions. + +// DES_set_key_unchecked calls |DES_set_key|. +OPENSSL_EXPORT void DES_set_key_unchecked(const DES_cblock *key, + DES_key_schedule *schedule); + +OPENSSL_EXPORT void DES_ede3_cfb64_encrypt(const uint8_t *in, uint8_t *out, + long length, DES_key_schedule *ks1, + DES_key_schedule *ks2, + DES_key_schedule *ks3, + DES_cblock *ivec, int *num, int enc); + +OPENSSL_EXPORT void DES_ede3_cfb_encrypt(const uint8_t *in, uint8_t *out, + int numbits, long length, + DES_key_schedule *ks1, + DES_key_schedule *ks2, + DES_key_schedule *ks3, + DES_cblock *ivec, int enc); + + +// Private functions. +// +// These functions are only exported for use in |decrepit|. + +OPENSSL_EXPORT void DES_decrypt3(uint32_t *data, const DES_key_schedule *ks1, + const DES_key_schedule *ks2, + const DES_key_schedule *ks3); + +OPENSSL_EXPORT void DES_encrypt3(uint32_t *data, const DES_key_schedule *ks1, + const DES_key_schedule *ks2, + const DES_key_schedule *ks3); + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_DES_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/dh.h b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/dh.h new file mode 100644 index 0000000..dd9f6ea --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/dh.h @@ -0,0 +1,298 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 OPENSSL_HEADER_DH_H +#define OPENSSL_HEADER_DH_H + +#include + +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// DH contains functions for performing Diffie-Hellman key agreement in +// multiplicative groups. + + +// Allocation and destruction. + +// DH_new returns a new, empty DH object or NULL on error. +OPENSSL_EXPORT DH *DH_new(void); + +// DH_free decrements the reference count of |dh| and frees it if the reference +// count drops to zero. +OPENSSL_EXPORT void DH_free(DH *dh); + +// DH_up_ref increments the reference count of |dh| and returns one. +OPENSSL_EXPORT int DH_up_ref(DH *dh); + + +// Properties. + +// DH_get0_key sets |*out_pub_key| and |*out_priv_key|, if non-NULL, to |dh|'s +// public and private key, respectively. If |dh| is a public key, the private +// key will be set to NULL. +OPENSSL_EXPORT void DH_get0_key(const DH *dh, const BIGNUM **out_pub_key, + const BIGNUM **out_priv_key); + +// DH_set0_key sets |dh|'s public and private key to the specified values. If +// NULL, the field is left unchanged. On success, it takes ownership of each +// argument and returns one. Otherwise, it returns zero. +OPENSSL_EXPORT int DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key); + +// DH_get0_pqg sets |*out_p|, |*out_q|, and |*out_g|, if non-NULL, to |dh|'s p, +// q, and g parameters, respectively. +OPENSSL_EXPORT void DH_get0_pqg(const DH *dh, const BIGNUM **out_p, + const BIGNUM **out_q, const BIGNUM **out_g); + +// DH_set0_pqg sets |dh|'s p, q, and g parameters to the specified values. If +// NULL, the field is left unchanged. On success, it takes ownership of each +// argument and returns one. Otherwise, it returns zero. |q| may be NULL, but +// |p| and |g| must either be specified or already configured on |dh|. +OPENSSL_EXPORT int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g); + + +// Standard parameters. + +// BN_get_rfc3526_prime_1536 sets |*ret| to the 1536-bit MODP group from RFC +// 3526 and returns |ret|. If |ret| is NULL then a fresh |BIGNUM| is allocated +// and returned. It returns NULL on allocation failure. +OPENSSL_EXPORT BIGNUM *BN_get_rfc3526_prime_1536(BIGNUM *ret); + + +// Parameter generation. + +#define DH_GENERATOR_2 2 +#define DH_GENERATOR_5 5 + +// DH_generate_parameters_ex generates a suitable Diffie-Hellman group with a +// prime that is |prime_bits| long and stores it in |dh|. The generator of the +// group will be |generator|, which should be |DH_GENERATOR_2| unless there's a +// good reason to use a different value. The |cb| argument contains a callback +// function that will be called during the generation. See the documentation in +// |bn.h| about this. In addition to the callback invocations from |BN|, |cb| +// will also be called with |event| equal to three when the generation is +// complete. +OPENSSL_EXPORT int DH_generate_parameters_ex(DH *dh, int prime_bits, + int generator, BN_GENCB *cb); + + +// Diffie-Hellman operations. + +// DH_generate_key generates a new, random, private key and stores it in +// |dh|. It returns one on success and zero on error. +OPENSSL_EXPORT int DH_generate_key(DH *dh); + +// DH_compute_key calculates the shared key between |dh| and |peers_key| and +// writes it as a big-endian integer into |out|, which must have |DH_size| +// bytes of space. It returns the number of bytes written, or a negative number +// on error. +OPENSSL_EXPORT int DH_compute_key(uint8_t *out, const BIGNUM *peers_key, + DH *dh); + + +// Utility functions. + +// DH_size returns the number of bytes in the DH group's prime. +OPENSSL_EXPORT int DH_size(const DH *dh); + +// DH_num_bits returns the minimum number of bits needed to represent the +// absolute value of the DH group's prime. +OPENSSL_EXPORT unsigned DH_num_bits(const DH *dh); + +#define DH_CHECK_P_NOT_PRIME 0x01 +#define DH_CHECK_P_NOT_SAFE_PRIME 0x02 +#define DH_CHECK_UNABLE_TO_CHECK_GENERATOR 0x04 +#define DH_CHECK_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 + +// These are compatibility defines. +#define DH_NOT_SUITABLE_GENERATOR DH_CHECK_NOT_SUITABLE_GENERATOR +#define DH_UNABLE_TO_CHECK_GENERATOR DH_CHECK_UNABLE_TO_CHECK_GENERATOR + +// DH_check checks the suitability of |dh| as a Diffie-Hellman group. and sets +// |DH_CHECK_*| flags in |*out_flags| if it finds any errors. It returns one if +// |*out_flags| was successfully set and zero on error. +// +// Note: these checks may be quite computationally expensive. +OPENSSL_EXPORT int DH_check(const DH *dh, int *out_flags); + +#define DH_CHECK_PUBKEY_TOO_SMALL 0x1 +#define DH_CHECK_PUBKEY_TOO_LARGE 0x2 +#define DH_CHECK_PUBKEY_INVALID 0x4 + +// DH_check_pub_key checks the suitability of |pub_key| as a public key for the +// DH group in |dh| and sets |DH_CHECK_PUBKEY_*| flags in |*out_flags| if it +// finds any errors. It returns one if |*out_flags| was successfully set and +// zero on error. +OPENSSL_EXPORT int DH_check_pub_key(const DH *dh, const BIGNUM *pub_key, + int *out_flags); + +// DHparams_dup allocates a fresh |DH| and copies the parameters from |dh| into +// it. It returns the new |DH| or NULL on error. +OPENSSL_EXPORT DH *DHparams_dup(const DH *dh); + + +// ASN.1 functions. + +// DH_parse_parameters decodes a DER-encoded DHParameter structure (PKCS #3) +// from |cbs| and advances |cbs|. It returns a newly-allocated |DH| or NULL on +// error. +OPENSSL_EXPORT DH *DH_parse_parameters(CBS *cbs); + +// DH_marshal_parameters marshals |dh| as a DER-encoded DHParameter structure +// (PKCS #3) and appends the result to |cbb|. It returns one on success and zero +// on error. +OPENSSL_EXPORT int DH_marshal_parameters(CBB *cbb, const DH *dh); + + +// ex_data functions. +// +// See |ex_data.h| for details. + +OPENSSL_EXPORT int DH_get_ex_new_index(long argl, void *argp, + CRYPTO_EX_unused *unused, + CRYPTO_EX_dup *dup_unused, + CRYPTO_EX_free *free_func); +OPENSSL_EXPORT int DH_set_ex_data(DH *d, int idx, void *arg); +OPENSSL_EXPORT void *DH_get_ex_data(DH *d, int idx); + + +// Deprecated functions. + +// DH_generate_parameters behaves like |DH_generate_parameters_ex|, which is +// what you should use instead. It returns NULL on error, or a newly-allocated +// |DH| on success. This function is provided for compatibility only. +OPENSSL_EXPORT DH *DH_generate_parameters(int prime_len, int generator, + void (*callback)(int, int, void *), + void *cb_arg); + +// d2i_DHparams parses an ASN.1, DER encoded Diffie-Hellman parameters structure +// from |len| bytes at |*inp|. If |ret| is not NULL then, on exit, a pointer to +// the result is in |*ret|. Note that, even if |*ret| is already non-NULL on +// entry, it will not be written to. Rather, a fresh |DH| is allocated and the +// previous one is freed. +// +// On successful exit, |*inp| is advanced past the DER structure. It +// returns the result or NULL on error. +// +// Use |DH_parse_parameters| instead. +OPENSSL_EXPORT DH *d2i_DHparams(DH **ret, const unsigned char **inp, long len); + +// i2d_DHparams marshals |in| to an ASN.1, DER structure. If |outp| is not NULL +// then the result is written to |*outp| and |*outp| is advanced just past the +// output. It returns the number of bytes in the result, whether written or +// not, or a negative value on error. +// +// Use |DH_marshal_parameters| instead. +OPENSSL_EXPORT int i2d_DHparams(const DH *in, unsigned char **outp); + + +struct dh_st { + BIGNUM *p; + BIGNUM *g; + BIGNUM *pub_key; // g^x mod p + BIGNUM *priv_key; // x + + // priv_length contains the length, in bits, of the private value. If zero, + // the private value will be the same length as |p|. + unsigned priv_length; + + CRYPTO_MUTEX method_mont_p_lock; + 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 flags; + CRYPTO_refcount_t references; + CRYPTO_EX_DATA ex_data; +}; + + +#if defined(__cplusplus) +} // extern C + +extern "C++" { + +namespace bssl { + +BORINGSSL_MAKE_DELETER(DH, DH_free) + +} // namespace bssl + +} // extern C++ + +#endif + +#define DH_R_BAD_GENERATOR 100 +#define DH_R_INVALID_PUBKEY 101 +#define DH_R_MODULUS_TOO_LARGE 102 +#define DH_R_NO_PRIVATE_VALUE 103 +#define DH_R_DECODE_ERROR 104 +#define DH_R_ENCODE_ERROR 105 + +#endif // OPENSSL_HEADER_DH_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/dh.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/dh.h.grpc_back new file mode 100644 index 0000000..ae24c25 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/dh.h.grpc_back @@ -0,0 +1,298 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 OPENSSL_HEADER_DH_H +#define OPENSSL_HEADER_DH_H + +#include + +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// DH contains functions for performing Diffie-Hellman key agreement in +// multiplicative groups. + + +// Allocation and destruction. + +// DH_new returns a new, empty DH object or NULL on error. +OPENSSL_EXPORT DH *DH_new(void); + +// DH_free decrements the reference count of |dh| and frees it if the reference +// count drops to zero. +OPENSSL_EXPORT void DH_free(DH *dh); + +// DH_up_ref increments the reference count of |dh| and returns one. +OPENSSL_EXPORT int DH_up_ref(DH *dh); + + +// Properties. + +// DH_get0_key sets |*out_pub_key| and |*out_priv_key|, if non-NULL, to |dh|'s +// public and private key, respectively. If |dh| is a public key, the private +// key will be set to NULL. +OPENSSL_EXPORT void DH_get0_key(const DH *dh, const BIGNUM **out_pub_key, + const BIGNUM **out_priv_key); + +// DH_set0_key sets |dh|'s public and private key to the specified values. If +// NULL, the field is left unchanged. On success, it takes ownership of each +// argument and returns one. Otherwise, it returns zero. +OPENSSL_EXPORT int DH_set0_key(DH *dh, BIGNUM *pub_key, BIGNUM *priv_key); + +// DH_get0_pqg sets |*out_p|, |*out_q|, and |*out_g|, if non-NULL, to |dh|'s p, +// q, and g parameters, respectively. +OPENSSL_EXPORT void DH_get0_pqg(const DH *dh, const BIGNUM **out_p, + const BIGNUM **out_q, const BIGNUM **out_g); + +// DH_set0_pqg sets |dh|'s p, q, and g parameters to the specified values. If +// NULL, the field is left unchanged. On success, it takes ownership of each +// argument and returns one. Otherwise, it returns zero. |q| may be NULL, but +// |p| and |g| must either be specified or already configured on |dh|. +OPENSSL_EXPORT int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g); + + +// Standard parameters. + +// BN_get_rfc3526_prime_1536 sets |*ret| to the 1536-bit MODP group from RFC +// 3526 and returns |ret|. If |ret| is NULL then a fresh |BIGNUM| is allocated +// and returned. It returns NULL on allocation failure. +OPENSSL_EXPORT BIGNUM *BN_get_rfc3526_prime_1536(BIGNUM *ret); + + +// Parameter generation. + +#define DH_GENERATOR_2 2 +#define DH_GENERATOR_5 5 + +// DH_generate_parameters_ex generates a suitable Diffie-Hellman group with a +// prime that is |prime_bits| long and stores it in |dh|. The generator of the +// group will be |generator|, which should be |DH_GENERATOR_2| unless there's a +// good reason to use a different value. The |cb| argument contains a callback +// function that will be called during the generation. See the documentation in +// |bn.h| about this. In addition to the callback invocations from |BN|, |cb| +// will also be called with |event| equal to three when the generation is +// complete. +OPENSSL_EXPORT int DH_generate_parameters_ex(DH *dh, int prime_bits, + int generator, BN_GENCB *cb); + + +// Diffie-Hellman operations. + +// DH_generate_key generates a new, random, private key and stores it in +// |dh|. It returns one on success and zero on error. +OPENSSL_EXPORT int DH_generate_key(DH *dh); + +// DH_compute_key calculates the shared key between |dh| and |peers_key| and +// writes it as a big-endian integer into |out|, which must have |DH_size| +// bytes of space. It returns the number of bytes written, or a negative number +// on error. +OPENSSL_EXPORT int DH_compute_key(uint8_t *out, const BIGNUM *peers_key, + DH *dh); + + +// Utility functions. + +// DH_size returns the number of bytes in the DH group's prime. +OPENSSL_EXPORT int DH_size(const DH *dh); + +// DH_num_bits returns the minimum number of bits needed to represent the +// absolute value of the DH group's prime. +OPENSSL_EXPORT unsigned DH_num_bits(const DH *dh); + +#define DH_CHECK_P_NOT_PRIME 0x01 +#define DH_CHECK_P_NOT_SAFE_PRIME 0x02 +#define DH_CHECK_UNABLE_TO_CHECK_GENERATOR 0x04 +#define DH_CHECK_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 + +// These are compatibility defines. +#define DH_NOT_SUITABLE_GENERATOR DH_CHECK_NOT_SUITABLE_GENERATOR +#define DH_UNABLE_TO_CHECK_GENERATOR DH_CHECK_UNABLE_TO_CHECK_GENERATOR + +// DH_check checks the suitability of |dh| as a Diffie-Hellman group. and sets +// |DH_CHECK_*| flags in |*out_flags| if it finds any errors. It returns one if +// |*out_flags| was successfully set and zero on error. +// +// Note: these checks may be quite computationally expensive. +OPENSSL_EXPORT int DH_check(const DH *dh, int *out_flags); + +#define DH_CHECK_PUBKEY_TOO_SMALL 0x1 +#define DH_CHECK_PUBKEY_TOO_LARGE 0x2 +#define DH_CHECK_PUBKEY_INVALID 0x4 + +// DH_check_pub_key checks the suitability of |pub_key| as a public key for the +// DH group in |dh| and sets |DH_CHECK_PUBKEY_*| flags in |*out_flags| if it +// finds any errors. It returns one if |*out_flags| was successfully set and +// zero on error. +OPENSSL_EXPORT int DH_check_pub_key(const DH *dh, const BIGNUM *pub_key, + int *out_flags); + +// DHparams_dup allocates a fresh |DH| and copies the parameters from |dh| into +// it. It returns the new |DH| or NULL on error. +OPENSSL_EXPORT DH *DHparams_dup(const DH *dh); + + +// ASN.1 functions. + +// DH_parse_parameters decodes a DER-encoded DHParameter structure (PKCS #3) +// from |cbs| and advances |cbs|. It returns a newly-allocated |DH| or NULL on +// error. +OPENSSL_EXPORT DH *DH_parse_parameters(CBS *cbs); + +// DH_marshal_parameters marshals |dh| as a DER-encoded DHParameter structure +// (PKCS #3) and appends the result to |cbb|. It returns one on success and zero +// on error. +OPENSSL_EXPORT int DH_marshal_parameters(CBB *cbb, const DH *dh); + + +// ex_data functions. +// +// See |ex_data.h| for details. + +OPENSSL_EXPORT int DH_get_ex_new_index(long argl, void *argp, + CRYPTO_EX_unused *unused, + CRYPTO_EX_dup *dup_unused, + CRYPTO_EX_free *free_func); +OPENSSL_EXPORT int DH_set_ex_data(DH *d, int idx, void *arg); +OPENSSL_EXPORT void *DH_get_ex_data(DH *d, int idx); + + +// Deprecated functions. + +// DH_generate_parameters behaves like |DH_generate_parameters_ex|, which is +// what you should use instead. It returns NULL on error, or a newly-allocated +// |DH| on success. This function is provided for compatibility only. +OPENSSL_EXPORT DH *DH_generate_parameters(int prime_len, int generator, + void (*callback)(int, int, void *), + void *cb_arg); + +// d2i_DHparams parses an ASN.1, DER encoded Diffie-Hellman parameters structure +// from |len| bytes at |*inp|. If |ret| is not NULL then, on exit, a pointer to +// the result is in |*ret|. Note that, even if |*ret| is already non-NULL on +// entry, it will not be written to. Rather, a fresh |DH| is allocated and the +// previous one is freed. +// +// On successful exit, |*inp| is advanced past the DER structure. It +// returns the result or NULL on error. +// +// Use |DH_parse_parameters| instead. +OPENSSL_EXPORT DH *d2i_DHparams(DH **ret, const unsigned char **inp, long len); + +// i2d_DHparams marshals |in| to an ASN.1, DER structure. If |outp| is not NULL +// then the result is written to |*outp| and |*outp| is advanced just past the +// output. It returns the number of bytes in the result, whether written or +// not, or a negative value on error. +// +// Use |DH_marshal_parameters| instead. +OPENSSL_EXPORT int i2d_DHparams(const DH *in, unsigned char **outp); + + +struct dh_st { + BIGNUM *p; + BIGNUM *g; + BIGNUM *pub_key; // g^x mod p + BIGNUM *priv_key; // x + + // priv_length contains the length, in bits, of the private value. If zero, + // the private value will be the same length as |p|. + unsigned priv_length; + + CRYPTO_MUTEX method_mont_p_lock; + 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 flags; + CRYPTO_refcount_t references; + CRYPTO_EX_DATA ex_data; +}; + + +#if defined(__cplusplus) +} // extern C + +extern "C++" { + +namespace bssl { + +BORINGSSL_MAKE_DELETER(DH, DH_free) + +} // namespace bssl + +} // extern C++ + +#endif + +#define DH_R_BAD_GENERATOR 100 +#define DH_R_INVALID_PUBKEY 101 +#define DH_R_MODULUS_TOO_LARGE 102 +#define DH_R_NO_PRIVATE_VALUE 103 +#define DH_R_DECODE_ERROR 104 +#define DH_R_ENCODE_ERROR 105 + +#endif // OPENSSL_HEADER_DH_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/digest.h b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/digest.h new file mode 100644 index 0000000..f451b00 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/digest.h @@ -0,0 +1,316 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 OPENSSL_HEADER_DIGEST_H +#define OPENSSL_HEADER_DIGEST_H + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// Digest functions. +// +// An EVP_MD abstracts the details of a specific hash function allowing code to +// deal with the concept of a "hash function" without needing to know exactly +// which hash function it is. + + +// Hash algorithms. +// +// The following functions return |EVP_MD| objects that implement the named hash +// function. + +OPENSSL_EXPORT const EVP_MD *EVP_md4(void); +OPENSSL_EXPORT const EVP_MD *EVP_md5(void); +OPENSSL_EXPORT const EVP_MD *EVP_sha1(void); +OPENSSL_EXPORT const EVP_MD *EVP_sha224(void); +OPENSSL_EXPORT const EVP_MD *EVP_sha256(void); +OPENSSL_EXPORT const EVP_MD *EVP_sha384(void); +OPENSSL_EXPORT const EVP_MD *EVP_sha512(void); + +// EVP_md5_sha1 is a TLS-specific |EVP_MD| which computes the concatenation of +// MD5 and SHA-1, as used in TLS 1.1 and below. +OPENSSL_EXPORT const EVP_MD *EVP_md5_sha1(void); + +// EVP_get_digestbynid returns an |EVP_MD| for the given NID, or NULL if no +// such digest is known. +OPENSSL_EXPORT const EVP_MD *EVP_get_digestbynid(int nid); + +// EVP_get_digestbyobj returns an |EVP_MD| for the given |ASN1_OBJECT|, or NULL +// if no such digest is known. +OPENSSL_EXPORT const EVP_MD *EVP_get_digestbyobj(const ASN1_OBJECT *obj); + + +// Digest contexts. +// +// An EVP_MD_CTX represents the state of a specific digest operation in +// progress. + +// EVP_MD_CTX_init initialises an, already allocated, |EVP_MD_CTX|. This is the +// same as setting the structure to zero. +OPENSSL_EXPORT void EVP_MD_CTX_init(EVP_MD_CTX *ctx); + +// EVP_MD_CTX_new allocates and initialises a fresh |EVP_MD_CTX| and returns +// it, or NULL on allocation failure. The caller must use |EVP_MD_CTX_free| to +// release the resulting object. +OPENSSL_EXPORT EVP_MD_CTX *EVP_MD_CTX_new(void); + +// EVP_MD_CTX_cleanup frees any resources owned by |ctx| and resets it to a +// freshly initialised state. It does not free |ctx| itself. It returns one. +OPENSSL_EXPORT int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx); + +// EVP_MD_CTX_free calls |EVP_MD_CTX_cleanup| and then frees |ctx| itself. +OPENSSL_EXPORT void EVP_MD_CTX_free(EVP_MD_CTX *ctx); + +// EVP_MD_CTX_copy_ex sets |out|, which must already be initialised, to be a +// copy of |in|. It returns one on success and zero on error. +OPENSSL_EXPORT int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in); + +// EVP_MD_CTX_reset calls |EVP_MD_CTX_cleanup| followed by |EVP_MD_CTX_init|. +OPENSSL_EXPORT void EVP_MD_CTX_reset(EVP_MD_CTX *ctx); + + +// Digest operations. + +// EVP_DigestInit_ex configures |ctx|, which must already have been +// initialised, for a fresh hashing operation using |type|. It returns one on +// success and zero otherwise. +OPENSSL_EXPORT int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, + ENGINE *engine); + +// EVP_DigestInit acts like |EVP_DigestInit_ex| except that |ctx| is +// initialised before use. +OPENSSL_EXPORT int EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type); + +// EVP_DigestUpdate hashes |len| bytes from |data| into the hashing operation +// in |ctx|. It returns one. +OPENSSL_EXPORT int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *data, + size_t len); + +// EVP_MAX_MD_SIZE is the largest digest size supported, in bytes. +// Functions that output a digest generally require the buffer have +// at least this much space. +#define EVP_MAX_MD_SIZE 64 // SHA-512 is the longest so far. + +// EVP_MAX_MD_BLOCK_SIZE is the largest digest block size supported, in +// bytes. +#define EVP_MAX_MD_BLOCK_SIZE 128 // SHA-512 is the longest so far. + +// EVP_DigestFinal_ex finishes the digest in |ctx| and writes the output to +// |md_out|. |EVP_MD_CTX_size| bytes are written, which is at most +// |EVP_MAX_MD_SIZE|. If |out_size| is not NULL then |*out_size| is set to the +// number of bytes written. It returns one. After this call, the hash cannot be +// updated or finished again until |EVP_DigestInit_ex| is called to start +// another hashing operation. +OPENSSL_EXPORT int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, uint8_t *md_out, + unsigned int *out_size); + +// EVP_DigestFinal acts like |EVP_DigestFinal_ex| except that +// |EVP_MD_CTX_cleanup| is called on |ctx| before returning. +OPENSSL_EXPORT int EVP_DigestFinal(EVP_MD_CTX *ctx, uint8_t *md_out, + unsigned int *out_size); + +// EVP_Digest performs a complete hashing operation in one call. It hashes |len| +// bytes from |data| and writes the digest to |md_out|. |EVP_MD_CTX_size| bytes +// are written, which is at most |EVP_MAX_MD_SIZE|. If |out_size| is not NULL +// then |*out_size| is set to the number of bytes written. It returns one on +// success and zero otherwise. +OPENSSL_EXPORT int EVP_Digest(const void *data, size_t len, uint8_t *md_out, + unsigned int *md_out_size, const EVP_MD *type, + ENGINE *impl); + + +// Digest function accessors. +// +// These functions allow code to learn details about an abstract hash +// function. + +// EVP_MD_type returns a NID identifying |md|. (For example, |NID_sha256|.) +OPENSSL_EXPORT int EVP_MD_type(const EVP_MD *md); + +// EVP_MD_flags returns the flags for |md|, which is a set of |EVP_MD_FLAG_*| +// values, ORed together. +OPENSSL_EXPORT uint32_t EVP_MD_flags(const EVP_MD *md); + +// EVP_MD_size returns the digest size of |md|, in bytes. +OPENSSL_EXPORT size_t EVP_MD_size(const EVP_MD *md); + +// EVP_MD_block_size returns the native block-size of |md|, in bytes. +OPENSSL_EXPORT size_t EVP_MD_block_size(const EVP_MD *md); + +// EVP_MD_FLAG_PKEY_DIGEST indicates the the digest function is used with a +// specific public key in order to verify signatures. (For example, +// EVP_dss1.) +#define EVP_MD_FLAG_PKEY_DIGEST 1 + +// EVP_MD_FLAG_DIGALGID_ABSENT indicates that the parameter type in an X.509 +// DigestAlgorithmIdentifier representing this digest function should be +// undefined rather than NULL. +#define EVP_MD_FLAG_DIGALGID_ABSENT 2 + + +// Digest operation accessors. + +// EVP_MD_CTX_md returns the underlying digest function, or NULL if one has not +// been set. +OPENSSL_EXPORT const EVP_MD *EVP_MD_CTX_md(const EVP_MD_CTX *ctx); + +// EVP_MD_CTX_size returns the digest size of |ctx|, in bytes. It +// will crash if a digest hasn't been set on |ctx|. +OPENSSL_EXPORT size_t EVP_MD_CTX_size(const EVP_MD_CTX *ctx); + +// EVP_MD_CTX_block_size returns the block size of the digest function used by +// |ctx|, in bytes. It will crash if a digest hasn't been set on |ctx|. +OPENSSL_EXPORT size_t EVP_MD_CTX_block_size(const EVP_MD_CTX *ctx); + +// EVP_MD_CTX_type returns a NID describing the digest function used by |ctx|. +// (For example, |NID_sha256|.) It will crash if a digest hasn't been set on +// |ctx|. +OPENSSL_EXPORT int EVP_MD_CTX_type(const EVP_MD_CTX *ctx); + + +// ASN.1 functions. +// +// These functions allow code to parse and serialize AlgorithmIdentifiers for +// hash functions. + +// EVP_parse_digest_algorithm parses an AlgorithmIdentifier structure containing +// a hash function OID (for example, 2.16.840.1.101.3.4.2.1 is SHA-256) and +// advances |cbs|. The parameters field may either be omitted or a NULL. It +// returns the digest function or NULL on error. +OPENSSL_EXPORT const EVP_MD *EVP_parse_digest_algorithm(CBS *cbs); + +// EVP_marshal_digest_algorithm marshals |md| as an AlgorithmIdentifier +// structure and appends the result to |cbb|. It returns one on success and zero +// on error. +OPENSSL_EXPORT int EVP_marshal_digest_algorithm(CBB *cbb, const EVP_MD *md); + + +// Deprecated functions. + +// EVP_MD_CTX_copy sets |out|, which must /not/ be initialised, to be a copy of +// |in|. It returns one on success and zero on error. +OPENSSL_EXPORT int EVP_MD_CTX_copy(EVP_MD_CTX *out, const EVP_MD_CTX *in); + +// EVP_add_digest does nothing and returns one. It exists only for +// compatibility with OpenSSL. +OPENSSL_EXPORT int EVP_add_digest(const EVP_MD *digest); + +// EVP_get_digestbyname returns an |EVP_MD| given a human readable name in +// |name|, or NULL if the name is unknown. +OPENSSL_EXPORT const EVP_MD *EVP_get_digestbyname(const char *); + +// EVP_dss1 returns the value of EVP_sha1(). This was provided by OpenSSL to +// specifiy the original DSA signatures, which were fixed to use SHA-1. Note, +// however, that attempting to sign or verify DSA signatures with the EVP +// interface will always fail. +OPENSSL_EXPORT const EVP_MD *EVP_dss1(void); + +// EVP_MD_CTX_create calls |EVP_MD_CTX_new|. +OPENSSL_EXPORT EVP_MD_CTX *EVP_MD_CTX_create(void); + +// EVP_MD_CTX_destroy calls |EVP_MD_CTX_free|. +OPENSSL_EXPORT void EVP_MD_CTX_destroy(EVP_MD_CTX *ctx); + + +struct evp_md_pctx_ops; + +struct env_md_ctx_st { + // digest is the underlying digest function, or NULL if not set. + const EVP_MD *digest; + // md_data points to a block of memory that contains the hash-specific + // context. + void *md_data; + + // pctx is an opaque (at this layer) pointer to additional context that + // EVP_PKEY functions may store in this object. + EVP_PKEY_CTX *pctx; + + // pctx_ops, if not NULL, points to a vtable that contains functions to + // manipulate |pctx|. + const struct evp_md_pctx_ops *pctx_ops; +} /* EVP_MD_CTX */; + + +#if defined(__cplusplus) +} // extern C + +#if !defined(BORINGSSL_NO_CXX) +extern "C++" { + +namespace bssl { + +BORINGSSL_MAKE_DELETER(EVP_MD_CTX, EVP_MD_CTX_free) + +using ScopedEVP_MD_CTX = + internal::StackAllocated; + +} // namespace bssl + +} // extern C++ +#endif + +#endif + +#define DIGEST_R_INPUT_NOT_INITIALIZED 100 +#define DIGEST_R_DECODE_ERROR 101 +#define DIGEST_R_UNKNOWN_HASH 102 + +#endif // OPENSSL_HEADER_DIGEST_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/digest.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/digest.h.grpc_back new file mode 100644 index 0000000..81f5892 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/digest.h.grpc_back @@ -0,0 +1,316 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 OPENSSL_HEADER_DIGEST_H +#define OPENSSL_HEADER_DIGEST_H + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// Digest functions. +// +// An EVP_MD abstracts the details of a specific hash function allowing code to +// deal with the concept of a "hash function" without needing to know exactly +// which hash function it is. + + +// Hash algorithms. +// +// The following functions return |EVP_MD| objects that implement the named hash +// function. + +OPENSSL_EXPORT const EVP_MD *EVP_md4(void); +OPENSSL_EXPORT const EVP_MD *EVP_md5(void); +OPENSSL_EXPORT const EVP_MD *EVP_sha1(void); +OPENSSL_EXPORT const EVP_MD *EVP_sha224(void); +OPENSSL_EXPORT const EVP_MD *EVP_sha256(void); +OPENSSL_EXPORT const EVP_MD *EVP_sha384(void); +OPENSSL_EXPORT const EVP_MD *EVP_sha512(void); + +// EVP_md5_sha1 is a TLS-specific |EVP_MD| which computes the concatenation of +// MD5 and SHA-1, as used in TLS 1.1 and below. +OPENSSL_EXPORT const EVP_MD *EVP_md5_sha1(void); + +// EVP_get_digestbynid returns an |EVP_MD| for the given NID, or NULL if no +// such digest is known. +OPENSSL_EXPORT const EVP_MD *EVP_get_digestbynid(int nid); + +// EVP_get_digestbyobj returns an |EVP_MD| for the given |ASN1_OBJECT|, or NULL +// if no such digest is known. +OPENSSL_EXPORT const EVP_MD *EVP_get_digestbyobj(const ASN1_OBJECT *obj); + + +// Digest contexts. +// +// An EVP_MD_CTX represents the state of a specific digest operation in +// progress. + +// EVP_MD_CTX_init initialises an, already allocated, |EVP_MD_CTX|. This is the +// same as setting the structure to zero. +OPENSSL_EXPORT void EVP_MD_CTX_init(EVP_MD_CTX *ctx); + +// EVP_MD_CTX_new allocates and initialises a fresh |EVP_MD_CTX| and returns +// it, or NULL on allocation failure. The caller must use |EVP_MD_CTX_free| to +// release the resulting object. +OPENSSL_EXPORT EVP_MD_CTX *EVP_MD_CTX_new(void); + +// EVP_MD_CTX_cleanup frees any resources owned by |ctx| and resets it to a +// freshly initialised state. It does not free |ctx| itself. It returns one. +OPENSSL_EXPORT int EVP_MD_CTX_cleanup(EVP_MD_CTX *ctx); + +// EVP_MD_CTX_free calls |EVP_MD_CTX_cleanup| and then frees |ctx| itself. +OPENSSL_EXPORT void EVP_MD_CTX_free(EVP_MD_CTX *ctx); + +// EVP_MD_CTX_copy_ex sets |out|, which must already be initialised, to be a +// copy of |in|. It returns one on success and zero on error. +OPENSSL_EXPORT int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in); + +// EVP_MD_CTX_reset calls |EVP_MD_CTX_cleanup| followed by |EVP_MD_CTX_init|. +OPENSSL_EXPORT void EVP_MD_CTX_reset(EVP_MD_CTX *ctx); + + +// Digest operations. + +// EVP_DigestInit_ex configures |ctx|, which must already have been +// initialised, for a fresh hashing operation using |type|. It returns one on +// success and zero otherwise. +OPENSSL_EXPORT int EVP_DigestInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, + ENGINE *engine); + +// EVP_DigestInit acts like |EVP_DigestInit_ex| except that |ctx| is +// initialised before use. +OPENSSL_EXPORT int EVP_DigestInit(EVP_MD_CTX *ctx, const EVP_MD *type); + +// EVP_DigestUpdate hashes |len| bytes from |data| into the hashing operation +// in |ctx|. It returns one. +OPENSSL_EXPORT int EVP_DigestUpdate(EVP_MD_CTX *ctx, const void *data, + size_t len); + +// EVP_MAX_MD_SIZE is the largest digest size supported, in bytes. +// Functions that output a digest generally require the buffer have +// at least this much space. +#define EVP_MAX_MD_SIZE 64 // SHA-512 is the longest so far. + +// EVP_MAX_MD_BLOCK_SIZE is the largest digest block size supported, in +// bytes. +#define EVP_MAX_MD_BLOCK_SIZE 128 // SHA-512 is the longest so far. + +// EVP_DigestFinal_ex finishes the digest in |ctx| and writes the output to +// |md_out|. |EVP_MD_CTX_size| bytes are written, which is at most +// |EVP_MAX_MD_SIZE|. If |out_size| is not NULL then |*out_size| is set to the +// number of bytes written. It returns one. After this call, the hash cannot be +// updated or finished again until |EVP_DigestInit_ex| is called to start +// another hashing operation. +OPENSSL_EXPORT int EVP_DigestFinal_ex(EVP_MD_CTX *ctx, uint8_t *md_out, + unsigned int *out_size); + +// EVP_DigestFinal acts like |EVP_DigestFinal_ex| except that +// |EVP_MD_CTX_cleanup| is called on |ctx| before returning. +OPENSSL_EXPORT int EVP_DigestFinal(EVP_MD_CTX *ctx, uint8_t *md_out, + unsigned int *out_size); + +// EVP_Digest performs a complete hashing operation in one call. It hashes |len| +// bytes from |data| and writes the digest to |md_out|. |EVP_MD_CTX_size| bytes +// are written, which is at most |EVP_MAX_MD_SIZE|. If |out_size| is not NULL +// then |*out_size| is set to the number of bytes written. It returns one on +// success and zero otherwise. +OPENSSL_EXPORT int EVP_Digest(const void *data, size_t len, uint8_t *md_out, + unsigned int *md_out_size, const EVP_MD *type, + ENGINE *impl); + + +// Digest function accessors. +// +// These functions allow code to learn details about an abstract hash +// function. + +// EVP_MD_type returns a NID identifying |md|. (For example, |NID_sha256|.) +OPENSSL_EXPORT int EVP_MD_type(const EVP_MD *md); + +// EVP_MD_flags returns the flags for |md|, which is a set of |EVP_MD_FLAG_*| +// values, ORed together. +OPENSSL_EXPORT uint32_t EVP_MD_flags(const EVP_MD *md); + +// EVP_MD_size returns the digest size of |md|, in bytes. +OPENSSL_EXPORT size_t EVP_MD_size(const EVP_MD *md); + +// EVP_MD_block_size returns the native block-size of |md|, in bytes. +OPENSSL_EXPORT size_t EVP_MD_block_size(const EVP_MD *md); + +// EVP_MD_FLAG_PKEY_DIGEST indicates the the digest function is used with a +// specific public key in order to verify signatures. (For example, +// EVP_dss1.) +#define EVP_MD_FLAG_PKEY_DIGEST 1 + +// EVP_MD_FLAG_DIGALGID_ABSENT indicates that the parameter type in an X.509 +// DigestAlgorithmIdentifier representing this digest function should be +// undefined rather than NULL. +#define EVP_MD_FLAG_DIGALGID_ABSENT 2 + + +// Digest operation accessors. + +// EVP_MD_CTX_md returns the underlying digest function, or NULL if one has not +// been set. +OPENSSL_EXPORT const EVP_MD *EVP_MD_CTX_md(const EVP_MD_CTX *ctx); + +// EVP_MD_CTX_size returns the digest size of |ctx|, in bytes. It +// will crash if a digest hasn't been set on |ctx|. +OPENSSL_EXPORT size_t EVP_MD_CTX_size(const EVP_MD_CTX *ctx); + +// EVP_MD_CTX_block_size returns the block size of the digest function used by +// |ctx|, in bytes. It will crash if a digest hasn't been set on |ctx|. +OPENSSL_EXPORT size_t EVP_MD_CTX_block_size(const EVP_MD_CTX *ctx); + +// EVP_MD_CTX_type returns a NID describing the digest function used by |ctx|. +// (For example, |NID_sha256|.) It will crash if a digest hasn't been set on +// |ctx|. +OPENSSL_EXPORT int EVP_MD_CTX_type(const EVP_MD_CTX *ctx); + + +// ASN.1 functions. +// +// These functions allow code to parse and serialize AlgorithmIdentifiers for +// hash functions. + +// EVP_parse_digest_algorithm parses an AlgorithmIdentifier structure containing +// a hash function OID (for example, 2.16.840.1.101.3.4.2.1 is SHA-256) and +// advances |cbs|. The parameters field may either be omitted or a NULL. It +// returns the digest function or NULL on error. +OPENSSL_EXPORT const EVP_MD *EVP_parse_digest_algorithm(CBS *cbs); + +// EVP_marshal_digest_algorithm marshals |md| as an AlgorithmIdentifier +// structure and appends the result to |cbb|. It returns one on success and zero +// on error. +OPENSSL_EXPORT int EVP_marshal_digest_algorithm(CBB *cbb, const EVP_MD *md); + + +// Deprecated functions. + +// EVP_MD_CTX_copy sets |out|, which must /not/ be initialised, to be a copy of +// |in|. It returns one on success and zero on error. +OPENSSL_EXPORT int EVP_MD_CTX_copy(EVP_MD_CTX *out, const EVP_MD_CTX *in); + +// EVP_add_digest does nothing and returns one. It exists only for +// compatibility with OpenSSL. +OPENSSL_EXPORT int EVP_add_digest(const EVP_MD *digest); + +// EVP_get_digestbyname returns an |EVP_MD| given a human readable name in +// |name|, or NULL if the name is unknown. +OPENSSL_EXPORT const EVP_MD *EVP_get_digestbyname(const char *); + +// EVP_dss1 returns the value of EVP_sha1(). This was provided by OpenSSL to +// specifiy the original DSA signatures, which were fixed to use SHA-1. Note, +// however, that attempting to sign or verify DSA signatures with the EVP +// interface will always fail. +OPENSSL_EXPORT const EVP_MD *EVP_dss1(void); + +// EVP_MD_CTX_create calls |EVP_MD_CTX_new|. +OPENSSL_EXPORT EVP_MD_CTX *EVP_MD_CTX_create(void); + +// EVP_MD_CTX_destroy calls |EVP_MD_CTX_free|. +OPENSSL_EXPORT void EVP_MD_CTX_destroy(EVP_MD_CTX *ctx); + + +struct evp_md_pctx_ops; + +struct env_md_ctx_st { + // digest is the underlying digest function, or NULL if not set. + const EVP_MD *digest; + // md_data points to a block of memory that contains the hash-specific + // context. + void *md_data; + + // pctx is an opaque (at this layer) pointer to additional context that + // EVP_PKEY functions may store in this object. + EVP_PKEY_CTX *pctx; + + // pctx_ops, if not NULL, points to a vtable that contains functions to + // manipulate |pctx|. + const struct evp_md_pctx_ops *pctx_ops; +} /* EVP_MD_CTX */; + + +#if defined(__cplusplus) +} // extern C + +#if !defined(BORINGSSL_NO_CXX) +extern "C++" { + +namespace bssl { + +BORINGSSL_MAKE_DELETER(EVP_MD_CTX, EVP_MD_CTX_free) + +using ScopedEVP_MD_CTX = + internal::StackAllocated; + +} // namespace bssl + +} // extern C++ +#endif + +#endif + +#define DIGEST_R_INPUT_NOT_INITIALIZED 100 +#define DIGEST_R_DECODE_ERROR 101 +#define DIGEST_R_UNKNOWN_HASH 102 + +#endif // OPENSSL_HEADER_DIGEST_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/dsa.h b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/dsa.h new file mode 100644 index 0000000..2eaf7da --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/dsa.h @@ -0,0 +1,435 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 . */ + +#ifndef OPENSSL_HEADER_DSA_H +#define OPENSSL_HEADER_DSA_H + +#include + +#include +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// DSA contains functions for signing and verifying with the Digital Signature +// Algorithm. + + +// Allocation and destruction. + +// DSA_new returns a new, empty DSA object or NULL on error. +OPENSSL_EXPORT DSA *DSA_new(void); + +// DSA_free decrements the reference count of |dsa| and frees it if the +// reference count drops to zero. +OPENSSL_EXPORT void DSA_free(DSA *dsa); + +// DSA_up_ref increments the reference count of |dsa| and returns one. +OPENSSL_EXPORT int DSA_up_ref(DSA *dsa); + + +// Properties. + +// DSA_get0_key sets |*out_pub_key| and |*out_priv_key|, if non-NULL, to |dsa|'s +// public and private key, respectively. If |dsa| is a public key, the private +// key will be set to NULL. +OPENSSL_EXPORT void DSA_get0_key(const DSA *dsa, const BIGNUM **out_pub_key, + const BIGNUM **out_priv_key); + +// DSA_get0_pqg sets |*out_p|, |*out_q|, and |*out_g|, if non-NULL, to |dsa|'s +// p, q, and g parameters, respectively. +OPENSSL_EXPORT void DSA_get0_pqg(const DSA *dsa, const BIGNUM **out_p, + const BIGNUM **out_q, const BIGNUM **out_g); + +// DSA_set0_key sets |dsa|'s public and private key to |pub_key| and |priv_key|, +// respectively, if non-NULL. On success, it takes ownership of each argument +// and returns one. Otherwise, it returns zero. +// +// |priv_key| may be NULL, but |pub_key| must either be non-NULL or already +// configured on |dsa|. +OPENSSL_EXPORT int DSA_set0_key(DSA *dsa, BIGNUM *pub_key, BIGNUM *priv_key); + +// DSA_set0_pqg sets |dsa|'s parameters to |p|, |q|, and |g|, if non-NULL, and +// takes ownership of them. On success, it takes ownership of each argument and +// returns one. Otherwise, it returns zero. +// +// Each argument must either be non-NULL or already configured on |dsa|. +OPENSSL_EXPORT int DSA_set0_pqg(DSA *dsa, BIGNUM *p, BIGNUM *q, BIGNUM *g); + + +// Parameter generation. + +// DSA_generate_parameters_ex generates a set of DSA parameters by following +// the procedure given in FIPS 186-4, appendix A. +// (http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf) +// +// The larger prime will have a length of |bits| (e.g. 2048). The |seed| value +// allows others to generate and verify the same parameters and should be +// random input which is kept for reference. If |out_counter| or |out_h| are +// not NULL then the counter and h value used in the generation are written to +// them. +// +// The |cb| argument is passed to |BN_generate_prime_ex| and is thus called +// during the generation process in order to indicate progress. See the +// comments for that function for details. In addition to the calls made by +// |BN_generate_prime_ex|, |DSA_generate_parameters_ex| will call it with +// |event| equal to 2 and 3 at different stages of the process. +// +// It returns one on success and zero otherwise. +OPENSSL_EXPORT int DSA_generate_parameters_ex(DSA *dsa, unsigned bits, + const uint8_t *seed, + size_t seed_len, int *out_counter, + unsigned long *out_h, + BN_GENCB *cb); + +// DSAparams_dup returns a freshly allocated |DSA| that contains a copy of the +// parameters from |dsa|. It returns NULL on error. +OPENSSL_EXPORT DSA *DSAparams_dup(const DSA *dsa); + + +// Key generation. + +// DSA_generate_key generates a public/private key pair in |dsa|, which must +// already have parameters setup. It returns one on success and zero on +// error. +OPENSSL_EXPORT int DSA_generate_key(DSA *dsa); + + +// Signatures. + +// DSA_SIG_st (aka |DSA_SIG|) contains a DSA signature as a pair of integers. +struct DSA_SIG_st { + BIGNUM *r, *s; +}; + +// DSA_SIG_new returns a freshly allocated, DIG_SIG structure or NULL on error. +// Both |r| and |s| in the signature will be NULL. +OPENSSL_EXPORT DSA_SIG *DSA_SIG_new(void); + +// DSA_SIG_free frees the contents of |sig| and then frees |sig| itself. +OPENSSL_EXPORT void DSA_SIG_free(DSA_SIG *sig); + +// DSA_do_sign returns a signature of the hash in |digest| by the key in |dsa| +// and returns an allocated, DSA_SIG structure, or NULL on error. +OPENSSL_EXPORT DSA_SIG *DSA_do_sign(const uint8_t *digest, size_t digest_len, + const DSA *dsa); + +// DSA_do_verify verifies that |sig| is a valid signature, by the public key in +// |dsa|, of the hash in |digest|. It returns one if so, zero if invalid and -1 +// on error. +// +// WARNING: do not use. This function returns -1 for error, 0 for invalid and 1 +// for valid. However, this is dangerously different to the usual OpenSSL +// convention and could be a disaster if a user did |if (DSA_do_verify(...))|. +// Because of this, |DSA_check_signature| is a safer version of this. +// +// TODO(fork): deprecate. +OPENSSL_EXPORT int DSA_do_verify(const uint8_t *digest, size_t digest_len, + DSA_SIG *sig, const DSA *dsa); + +// DSA_do_check_signature sets |*out_valid| to zero. Then it verifies that |sig| +// is a valid signature, by the public key in |dsa| of the hash in |digest| +// and, if so, it sets |*out_valid| to one. +// +// It returns one if it was able to verify the signature as valid or invalid, +// and zero on error. +OPENSSL_EXPORT int DSA_do_check_signature(int *out_valid, const uint8_t *digest, + size_t digest_len, DSA_SIG *sig, + const DSA *dsa); + + +// ASN.1 signatures. +// +// These functions also perform DSA signature operations, but deal with ASN.1 +// encoded signatures as opposed to raw |BIGNUM|s. If you don't know what +// encoding a DSA signature is in, it's probably ASN.1. + +// DSA_sign signs |digest| with the key in |dsa| and writes the resulting +// signature, in ASN.1 form, to |out_sig| and the length of the signature to +// |*out_siglen|. There must be, at least, |DSA_size(dsa)| bytes of space in +// |out_sig|. It returns one on success and zero otherwise. +// +// (The |type| argument is ignored.) +OPENSSL_EXPORT int DSA_sign(int type, const uint8_t *digest, size_t digest_len, + uint8_t *out_sig, unsigned int *out_siglen, + const DSA *dsa); + +// DSA_verify verifies that |sig| is a valid, ASN.1 signature, by the public +// key in |dsa|, of the hash in |digest|. It returns one if so, zero if invalid +// and -1 on error. +// +// (The |type| argument is ignored.) +// +// WARNING: do not use. This function returns -1 for error, 0 for invalid and 1 +// for valid. However, this is dangerously different to the usual OpenSSL +// convention and could be a disaster if a user did |if (DSA_do_verify(...))|. +// Because of this, |DSA_check_signature| is a safer version of this. +// +// TODO(fork): deprecate. +OPENSSL_EXPORT int DSA_verify(int type, const uint8_t *digest, + size_t digest_len, const uint8_t *sig, + size_t sig_len, const DSA *dsa); + +// DSA_check_signature sets |*out_valid| to zero. Then it verifies that |sig| +// is a valid, ASN.1 signature, by the public key in |dsa|, of the hash in +// |digest|. If so, it sets |*out_valid| to one. +// +// It returns one if it was able to verify the signature as valid or invalid, +// and zero on error. +OPENSSL_EXPORT int DSA_check_signature(int *out_valid, const uint8_t *digest, + size_t digest_len, const uint8_t *sig, + size_t sig_len, const DSA *dsa); + +// DSA_size returns the size, in bytes, of an ASN.1 encoded, DSA signature +// generated by |dsa|. Parameters must already have been setup in |dsa|. +OPENSSL_EXPORT int DSA_size(const DSA *dsa); + + +// ASN.1 encoding. + +// DSA_SIG_parse parses a DER-encoded DSA-Sig-Value structure from |cbs| and +// advances |cbs|. It returns a newly-allocated |DSA_SIG| or NULL on error. +OPENSSL_EXPORT DSA_SIG *DSA_SIG_parse(CBS *cbs); + +// DSA_SIG_marshal marshals |sig| as a DER-encoded DSA-Sig-Value and appends the +// result to |cbb|. It returns one on success and zero on error. +OPENSSL_EXPORT int DSA_SIG_marshal(CBB *cbb, const DSA_SIG *sig); + +// DSA_parse_public_key parses a DER-encoded DSA public key from |cbs| and +// advances |cbs|. It returns a newly-allocated |DSA| or NULL on error. +OPENSSL_EXPORT DSA *DSA_parse_public_key(CBS *cbs); + +// DSA_marshal_public_key marshals |dsa| as a DER-encoded DSA public key and +// appends the result to |cbb|. It returns one on success and zero on +// failure. +OPENSSL_EXPORT int DSA_marshal_public_key(CBB *cbb, const DSA *dsa); + +// DSA_parse_private_key parses a DER-encoded DSA private key from |cbs| and +// advances |cbs|. It returns a newly-allocated |DSA| or NULL on error. +OPENSSL_EXPORT DSA *DSA_parse_private_key(CBS *cbs); + +// DSA_marshal_private_key marshals |dsa| as a DER-encoded DSA private key and +// appends the result to |cbb|. It returns one on success and zero on +// failure. +OPENSSL_EXPORT int DSA_marshal_private_key(CBB *cbb, const DSA *dsa); + +// DSA_parse_parameters parses a DER-encoded Dss-Parms structure (RFC 3279) +// from |cbs| and advances |cbs|. It returns a newly-allocated |DSA| or NULL on +// error. +OPENSSL_EXPORT DSA *DSA_parse_parameters(CBS *cbs); + +// DSA_marshal_parameters marshals |dsa| as a DER-encoded Dss-Parms structure +// (RFC 3447) and appends the result to |cbb|. It returns one on success and +// zero on failure. +OPENSSL_EXPORT int DSA_marshal_parameters(CBB *cbb, const DSA *dsa); + + +// Conversion. + +// DSA_dup_DH returns a |DH| constructed from the parameters of |dsa|. This is +// sometimes needed when Diffie-Hellman parameters are stored in the form of +// DSA parameters. It returns an allocated |DH| on success or NULL on error. +OPENSSL_EXPORT DH *DSA_dup_DH(const DSA *dsa); + + +// ex_data functions. +// +// See |ex_data.h| for details. + +OPENSSL_EXPORT int DSA_get_ex_new_index(long argl, void *argp, + CRYPTO_EX_unused *unused, + CRYPTO_EX_dup *dup_unused, + CRYPTO_EX_free *free_func); +OPENSSL_EXPORT int DSA_set_ex_data(DSA *dsa, int idx, void *arg); +OPENSSL_EXPORT void *DSA_get_ex_data(const DSA *dsa, int idx); + + +// Deprecated functions. + +// d2i_DSA_SIG parses an ASN.1, DER-encoded, DSA signature from |len| bytes at +// |*inp|. If |out_sig| is not NULL then, on exit, a pointer to the result is +// in |*out_sig|. Note that, even if |*out_sig| is already non-NULL on entry, it +// will not be written to. Rather, a fresh |DSA_SIG| is allocated and the +// previous one is freed. On successful exit, |*inp| is advanced past the DER +// structure. It returns the result or NULL on error. +// +// Use |DSA_SIG_parse| instead. +OPENSSL_EXPORT DSA_SIG *d2i_DSA_SIG(DSA_SIG **out_sig, const uint8_t **inp, + long len); + +// i2d_DSA_SIG marshals |in| to an ASN.1, DER structure. If |outp| is not NULL +// then the result is written to |*outp| and |*outp| is advanced just past the +// output. It returns the number of bytes in the result, whether written or not, +// or a negative value on error. +// +// Use |DSA_SIG_marshal| instead. +OPENSSL_EXPORT int i2d_DSA_SIG(const DSA_SIG *in, uint8_t **outp); + +// d2i_DSAPublicKey parses an ASN.1, DER-encoded, DSA public key from |len| +// bytes at |*inp|. If |out| is not NULL then, on exit, a pointer to the result +// is in |*out|. Note that, even if |*ou| is already non-NULL on entry, it will +// not be written to. Rather, a fresh |DSA| is allocated and the previous one is +// freed. On successful exit, |*inp| is advanced past the DER structure. It +// returns the result or NULL on error. +// +// Use |DSA_parse_public_key| instead. +OPENSSL_EXPORT DSA *d2i_DSAPublicKey(DSA **out, const uint8_t **inp, long len); + +// i2d_DSAPublicKey marshals a public key from |in| to an ASN.1, DER structure. +// If |outp| is not NULL then the result is written to |*outp| and |*outp| is +// advanced just past the output. It returns the number of bytes in the result, +// whether written or not, or a negative value on error. +// +// Use |DSA_marshal_public_key| instead. +OPENSSL_EXPORT int i2d_DSAPublicKey(const DSA *in, uint8_t **outp); + +// d2i_DSAPrivateKey parses an ASN.1, DER-encoded, DSA private key from |len| +// bytes at |*inp|. If |out| is not NULL then, on exit, a pointer to the result +// is in |*out|. Note that, even if |*out| is already non-NULL on entry, it will +// not be written to. Rather, a fresh |DSA| is allocated and the previous one is +// freed. On successful exit, |*inp| is advanced past the DER structure. It +// returns the result or NULL on error. +// +// Use |DSA_parse_private_key| instead. +OPENSSL_EXPORT DSA *d2i_DSAPrivateKey(DSA **out, const uint8_t **inp, long len); + +// i2d_DSAPrivateKey marshals a private key from |in| to an ASN.1, DER +// structure. If |outp| is not NULL then the result is written to |*outp| and +// |*outp| is advanced just past the output. It returns the number of bytes in +// the result, whether written or not, or a negative value on error. +// +// Use |DSA_marshal_private_key| instead. +OPENSSL_EXPORT int i2d_DSAPrivateKey(const DSA *in, uint8_t **outp); + +// d2i_DSAparams parses ASN.1, DER-encoded, DSA parameters from |len| bytes at +// |*inp|. If |out| is not NULL then, on exit, a pointer to the result is in +// |*out|. Note that, even if |*out| is already non-NULL on entry, it will not +// be written to. Rather, a fresh |DSA| is allocated and the previous one is +// freed. On successful exit, |*inp| is advanced past the DER structure. It +// returns the result or NULL on error. +// +// Use |DSA_parse_parameters| instead. +OPENSSL_EXPORT DSA *d2i_DSAparams(DSA **out, const uint8_t **inp, long len); + +// i2d_DSAparams marshals DSA parameters from |in| to an ASN.1, DER structure. +// If |outp| is not NULL then the result is written to |*outp| and |*outp| is +// advanced just past the output. It returns the number of bytes in the result, +// whether written or not, or a negative value on error. +// +// Use |DSA_marshal_parameters| instead. +OPENSSL_EXPORT int i2d_DSAparams(const DSA *in, uint8_t **outp); + +// DSA_generate_parameters is a deprecated version of +// |DSA_generate_parameters_ex| that creates and returns a |DSA*|. Don't use +// it. +OPENSSL_EXPORT 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); + + +struct dsa_st { + long version; + BIGNUM *p; + BIGNUM *q; // == 20 + BIGNUM *g; + + BIGNUM *pub_key; // y public key + BIGNUM *priv_key; // x private key + + int flags; + // Normally used to cache montgomery values + CRYPTO_MUTEX method_mont_lock; + BN_MONT_CTX *method_mont_p; + BN_MONT_CTX *method_mont_q; + CRYPTO_refcount_t references; + CRYPTO_EX_DATA ex_data; +}; + + +#if defined(__cplusplus) +} // extern C + +extern "C++" { + +namespace bssl { + +BORINGSSL_MAKE_DELETER(DSA, DSA_free) +BORINGSSL_MAKE_DELETER(DSA_SIG, DSA_SIG_free) + +} // namespace bssl + +} // extern C++ + +#endif + +#define DSA_R_BAD_Q_VALUE 100 +#define DSA_R_MISSING_PARAMETERS 101 +#define DSA_R_MODULUS_TOO_LARGE 102 +#define DSA_R_NEED_NEW_SETUP_VALUES 103 +#define DSA_R_BAD_VERSION 104 +#define DSA_R_DECODE_ERROR 105 +#define DSA_R_ENCODE_ERROR 106 + +#endif // OPENSSL_HEADER_DSA_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/dsa.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/dsa.h.grpc_back new file mode 100644 index 0000000..2966f9d --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/dsa.h.grpc_back @@ -0,0 +1,435 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 . */ + +#ifndef OPENSSL_HEADER_DSA_H +#define OPENSSL_HEADER_DSA_H + +#include + +#include +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// DSA contains functions for signing and verifying with the Digital Signature +// Algorithm. + + +// Allocation and destruction. + +// DSA_new returns a new, empty DSA object or NULL on error. +OPENSSL_EXPORT DSA *DSA_new(void); + +// DSA_free decrements the reference count of |dsa| and frees it if the +// reference count drops to zero. +OPENSSL_EXPORT void DSA_free(DSA *dsa); + +// DSA_up_ref increments the reference count of |dsa| and returns one. +OPENSSL_EXPORT int DSA_up_ref(DSA *dsa); + + +// Properties. + +// DSA_get0_key sets |*out_pub_key| and |*out_priv_key|, if non-NULL, to |dsa|'s +// public and private key, respectively. If |dsa| is a public key, the private +// key will be set to NULL. +OPENSSL_EXPORT void DSA_get0_key(const DSA *dsa, const BIGNUM **out_pub_key, + const BIGNUM **out_priv_key); + +// DSA_get0_pqg sets |*out_p|, |*out_q|, and |*out_g|, if non-NULL, to |dsa|'s +// p, q, and g parameters, respectively. +OPENSSL_EXPORT void DSA_get0_pqg(const DSA *dsa, const BIGNUM **out_p, + const BIGNUM **out_q, const BIGNUM **out_g); + +// DSA_set0_key sets |dsa|'s public and private key to |pub_key| and |priv_key|, +// respectively, if non-NULL. On success, it takes ownership of each argument +// and returns one. Otherwise, it returns zero. +// +// |priv_key| may be NULL, but |pub_key| must either be non-NULL or already +// configured on |dsa|. +OPENSSL_EXPORT int DSA_set0_key(DSA *dsa, BIGNUM *pub_key, BIGNUM *priv_key); + +// DSA_set0_pqg sets |dsa|'s parameters to |p|, |q|, and |g|, if non-NULL, and +// takes ownership of them. On success, it takes ownership of each argument and +// returns one. Otherwise, it returns zero. +// +// Each argument must either be non-NULL or already configured on |dsa|. +OPENSSL_EXPORT int DSA_set0_pqg(DSA *dsa, BIGNUM *p, BIGNUM *q, BIGNUM *g); + + +// Parameter generation. + +// DSA_generate_parameters_ex generates a set of DSA parameters by following +// the procedure given in FIPS 186-4, appendix A. +// (http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf) +// +// The larger prime will have a length of |bits| (e.g. 2048). The |seed| value +// allows others to generate and verify the same parameters and should be +// random input which is kept for reference. If |out_counter| or |out_h| are +// not NULL then the counter and h value used in the generation are written to +// them. +// +// The |cb| argument is passed to |BN_generate_prime_ex| and is thus called +// during the generation process in order to indicate progress. See the +// comments for that function for details. In addition to the calls made by +// |BN_generate_prime_ex|, |DSA_generate_parameters_ex| will call it with +// |event| equal to 2 and 3 at different stages of the process. +// +// It returns one on success and zero otherwise. +OPENSSL_EXPORT int DSA_generate_parameters_ex(DSA *dsa, unsigned bits, + const uint8_t *seed, + size_t seed_len, int *out_counter, + unsigned long *out_h, + BN_GENCB *cb); + +// DSAparams_dup returns a freshly allocated |DSA| that contains a copy of the +// parameters from |dsa|. It returns NULL on error. +OPENSSL_EXPORT DSA *DSAparams_dup(const DSA *dsa); + + +// Key generation. + +// DSA_generate_key generates a public/private key pair in |dsa|, which must +// already have parameters setup. It returns one on success and zero on +// error. +OPENSSL_EXPORT int DSA_generate_key(DSA *dsa); + + +// Signatures. + +// DSA_SIG_st (aka |DSA_SIG|) contains a DSA signature as a pair of integers. +struct DSA_SIG_st { + BIGNUM *r, *s; +}; + +// DSA_SIG_new returns a freshly allocated, DIG_SIG structure or NULL on error. +// Both |r| and |s| in the signature will be NULL. +OPENSSL_EXPORT DSA_SIG *DSA_SIG_new(void); + +// DSA_SIG_free frees the contents of |sig| and then frees |sig| itself. +OPENSSL_EXPORT void DSA_SIG_free(DSA_SIG *sig); + +// DSA_do_sign returns a signature of the hash in |digest| by the key in |dsa| +// and returns an allocated, DSA_SIG structure, or NULL on error. +OPENSSL_EXPORT DSA_SIG *DSA_do_sign(const uint8_t *digest, size_t digest_len, + const DSA *dsa); + +// DSA_do_verify verifies that |sig| is a valid signature, by the public key in +// |dsa|, of the hash in |digest|. It returns one if so, zero if invalid and -1 +// on error. +// +// WARNING: do not use. This function returns -1 for error, 0 for invalid and 1 +// for valid. However, this is dangerously different to the usual OpenSSL +// convention and could be a disaster if a user did |if (DSA_do_verify(...))|. +// Because of this, |DSA_check_signature| is a safer version of this. +// +// TODO(fork): deprecate. +OPENSSL_EXPORT int DSA_do_verify(const uint8_t *digest, size_t digest_len, + DSA_SIG *sig, const DSA *dsa); + +// DSA_do_check_signature sets |*out_valid| to zero. Then it verifies that |sig| +// is a valid signature, by the public key in |dsa| of the hash in |digest| +// and, if so, it sets |*out_valid| to one. +// +// It returns one if it was able to verify the signature as valid or invalid, +// and zero on error. +OPENSSL_EXPORT int DSA_do_check_signature(int *out_valid, const uint8_t *digest, + size_t digest_len, DSA_SIG *sig, + const DSA *dsa); + + +// ASN.1 signatures. +// +// These functions also perform DSA signature operations, but deal with ASN.1 +// encoded signatures as opposed to raw |BIGNUM|s. If you don't know what +// encoding a DSA signature is in, it's probably ASN.1. + +// DSA_sign signs |digest| with the key in |dsa| and writes the resulting +// signature, in ASN.1 form, to |out_sig| and the length of the signature to +// |*out_siglen|. There must be, at least, |DSA_size(dsa)| bytes of space in +// |out_sig|. It returns one on success and zero otherwise. +// +// (The |type| argument is ignored.) +OPENSSL_EXPORT int DSA_sign(int type, const uint8_t *digest, size_t digest_len, + uint8_t *out_sig, unsigned int *out_siglen, + const DSA *dsa); + +// DSA_verify verifies that |sig| is a valid, ASN.1 signature, by the public +// key in |dsa|, of the hash in |digest|. It returns one if so, zero if invalid +// and -1 on error. +// +// (The |type| argument is ignored.) +// +// WARNING: do not use. This function returns -1 for error, 0 for invalid and 1 +// for valid. However, this is dangerously different to the usual OpenSSL +// convention and could be a disaster if a user did |if (DSA_do_verify(...))|. +// Because of this, |DSA_check_signature| is a safer version of this. +// +// TODO(fork): deprecate. +OPENSSL_EXPORT int DSA_verify(int type, const uint8_t *digest, + size_t digest_len, const uint8_t *sig, + size_t sig_len, const DSA *dsa); + +// DSA_check_signature sets |*out_valid| to zero. Then it verifies that |sig| +// is a valid, ASN.1 signature, by the public key in |dsa|, of the hash in +// |digest|. If so, it sets |*out_valid| to one. +// +// It returns one if it was able to verify the signature as valid or invalid, +// and zero on error. +OPENSSL_EXPORT int DSA_check_signature(int *out_valid, const uint8_t *digest, + size_t digest_len, const uint8_t *sig, + size_t sig_len, const DSA *dsa); + +// DSA_size returns the size, in bytes, of an ASN.1 encoded, DSA signature +// generated by |dsa|. Parameters must already have been setup in |dsa|. +OPENSSL_EXPORT int DSA_size(const DSA *dsa); + + +// ASN.1 encoding. + +// DSA_SIG_parse parses a DER-encoded DSA-Sig-Value structure from |cbs| and +// advances |cbs|. It returns a newly-allocated |DSA_SIG| or NULL on error. +OPENSSL_EXPORT DSA_SIG *DSA_SIG_parse(CBS *cbs); + +// DSA_SIG_marshal marshals |sig| as a DER-encoded DSA-Sig-Value and appends the +// result to |cbb|. It returns one on success and zero on error. +OPENSSL_EXPORT int DSA_SIG_marshal(CBB *cbb, const DSA_SIG *sig); + +// DSA_parse_public_key parses a DER-encoded DSA public key from |cbs| and +// advances |cbs|. It returns a newly-allocated |DSA| or NULL on error. +OPENSSL_EXPORT DSA *DSA_parse_public_key(CBS *cbs); + +// DSA_marshal_public_key marshals |dsa| as a DER-encoded DSA public key and +// appends the result to |cbb|. It returns one on success and zero on +// failure. +OPENSSL_EXPORT int DSA_marshal_public_key(CBB *cbb, const DSA *dsa); + +// DSA_parse_private_key parses a DER-encoded DSA private key from |cbs| and +// advances |cbs|. It returns a newly-allocated |DSA| or NULL on error. +OPENSSL_EXPORT DSA *DSA_parse_private_key(CBS *cbs); + +// DSA_marshal_private_key marshals |dsa| as a DER-encoded DSA private key and +// appends the result to |cbb|. It returns one on success and zero on +// failure. +OPENSSL_EXPORT int DSA_marshal_private_key(CBB *cbb, const DSA *dsa); + +// DSA_parse_parameters parses a DER-encoded Dss-Parms structure (RFC 3279) +// from |cbs| and advances |cbs|. It returns a newly-allocated |DSA| or NULL on +// error. +OPENSSL_EXPORT DSA *DSA_parse_parameters(CBS *cbs); + +// DSA_marshal_parameters marshals |dsa| as a DER-encoded Dss-Parms structure +// (RFC 3447) and appends the result to |cbb|. It returns one on success and +// zero on failure. +OPENSSL_EXPORT int DSA_marshal_parameters(CBB *cbb, const DSA *dsa); + + +// Conversion. + +// DSA_dup_DH returns a |DH| constructed from the parameters of |dsa|. This is +// sometimes needed when Diffie-Hellman parameters are stored in the form of +// DSA parameters. It returns an allocated |DH| on success or NULL on error. +OPENSSL_EXPORT DH *DSA_dup_DH(const DSA *dsa); + + +// ex_data functions. +// +// See |ex_data.h| for details. + +OPENSSL_EXPORT int DSA_get_ex_new_index(long argl, void *argp, + CRYPTO_EX_unused *unused, + CRYPTO_EX_dup *dup_unused, + CRYPTO_EX_free *free_func); +OPENSSL_EXPORT int DSA_set_ex_data(DSA *dsa, int idx, void *arg); +OPENSSL_EXPORT void *DSA_get_ex_data(const DSA *dsa, int idx); + + +// Deprecated functions. + +// d2i_DSA_SIG parses an ASN.1, DER-encoded, DSA signature from |len| bytes at +// |*inp|. If |out_sig| is not NULL then, on exit, a pointer to the result is +// in |*out_sig|. Note that, even if |*out_sig| is already non-NULL on entry, it +// will not be written to. Rather, a fresh |DSA_SIG| is allocated and the +// previous one is freed. On successful exit, |*inp| is advanced past the DER +// structure. It returns the result or NULL on error. +// +// Use |DSA_SIG_parse| instead. +OPENSSL_EXPORT DSA_SIG *d2i_DSA_SIG(DSA_SIG **out_sig, const uint8_t **inp, + long len); + +// i2d_DSA_SIG marshals |in| to an ASN.1, DER structure. If |outp| is not NULL +// then the result is written to |*outp| and |*outp| is advanced just past the +// output. It returns the number of bytes in the result, whether written or not, +// or a negative value on error. +// +// Use |DSA_SIG_marshal| instead. +OPENSSL_EXPORT int i2d_DSA_SIG(const DSA_SIG *in, uint8_t **outp); + +// d2i_DSAPublicKey parses an ASN.1, DER-encoded, DSA public key from |len| +// bytes at |*inp|. If |out| is not NULL then, on exit, a pointer to the result +// is in |*out|. Note that, even if |*ou| is already non-NULL on entry, it will +// not be written to. Rather, a fresh |DSA| is allocated and the previous one is +// freed. On successful exit, |*inp| is advanced past the DER structure. It +// returns the result or NULL on error. +// +// Use |DSA_parse_public_key| instead. +OPENSSL_EXPORT DSA *d2i_DSAPublicKey(DSA **out, const uint8_t **inp, long len); + +// i2d_DSAPublicKey marshals a public key from |in| to an ASN.1, DER structure. +// If |outp| is not NULL then the result is written to |*outp| and |*outp| is +// advanced just past the output. It returns the number of bytes in the result, +// whether written or not, or a negative value on error. +// +// Use |DSA_marshal_public_key| instead. +OPENSSL_EXPORT int i2d_DSAPublicKey(const DSA *in, uint8_t **outp); + +// d2i_DSAPrivateKey parses an ASN.1, DER-encoded, DSA private key from |len| +// bytes at |*inp|. If |out| is not NULL then, on exit, a pointer to the result +// is in |*out|. Note that, even if |*out| is already non-NULL on entry, it will +// not be written to. Rather, a fresh |DSA| is allocated and the previous one is +// freed. On successful exit, |*inp| is advanced past the DER structure. It +// returns the result or NULL on error. +// +// Use |DSA_parse_private_key| instead. +OPENSSL_EXPORT DSA *d2i_DSAPrivateKey(DSA **out, const uint8_t **inp, long len); + +// i2d_DSAPrivateKey marshals a private key from |in| to an ASN.1, DER +// structure. If |outp| is not NULL then the result is written to |*outp| and +// |*outp| is advanced just past the output. It returns the number of bytes in +// the result, whether written or not, or a negative value on error. +// +// Use |DSA_marshal_private_key| instead. +OPENSSL_EXPORT int i2d_DSAPrivateKey(const DSA *in, uint8_t **outp); + +// d2i_DSAparams parses ASN.1, DER-encoded, DSA parameters from |len| bytes at +// |*inp|. If |out| is not NULL then, on exit, a pointer to the result is in +// |*out|. Note that, even if |*out| is already non-NULL on entry, it will not +// be written to. Rather, a fresh |DSA| is allocated and the previous one is +// freed. On successful exit, |*inp| is advanced past the DER structure. It +// returns the result or NULL on error. +// +// Use |DSA_parse_parameters| instead. +OPENSSL_EXPORT DSA *d2i_DSAparams(DSA **out, const uint8_t **inp, long len); + +// i2d_DSAparams marshals DSA parameters from |in| to an ASN.1, DER structure. +// If |outp| is not NULL then the result is written to |*outp| and |*outp| is +// advanced just past the output. It returns the number of bytes in the result, +// whether written or not, or a negative value on error. +// +// Use |DSA_marshal_parameters| instead. +OPENSSL_EXPORT int i2d_DSAparams(const DSA *in, uint8_t **outp); + +// DSA_generate_parameters is a deprecated version of +// |DSA_generate_parameters_ex| that creates and returns a |DSA*|. Don't use +// it. +OPENSSL_EXPORT 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); + + +struct dsa_st { + long version; + BIGNUM *p; + BIGNUM *q; // == 20 + BIGNUM *g; + + BIGNUM *pub_key; // y public key + BIGNUM *priv_key; // x private key + + int flags; + // Normally used to cache montgomery values + CRYPTO_MUTEX method_mont_lock; + BN_MONT_CTX *method_mont_p; + BN_MONT_CTX *method_mont_q; + CRYPTO_refcount_t references; + CRYPTO_EX_DATA ex_data; +}; + + +#if defined(__cplusplus) +} // extern C + +extern "C++" { + +namespace bssl { + +BORINGSSL_MAKE_DELETER(DSA, DSA_free) +BORINGSSL_MAKE_DELETER(DSA_SIG, DSA_SIG_free) + +} // namespace bssl + +} // extern C++ + +#endif + +#define DSA_R_BAD_Q_VALUE 100 +#define DSA_R_MISSING_PARAMETERS 101 +#define DSA_R_MODULUS_TOO_LARGE 102 +#define DSA_R_NEED_NEW_SETUP_VALUES 103 +#define DSA_R_BAD_VERSION 104 +#define DSA_R_DECODE_ERROR 105 +#define DSA_R_ENCODE_ERROR 106 + +#endif // OPENSSL_HEADER_DSA_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/dtls1.h b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/dtls1.h new file mode 100644 index 0000000..38ca801 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/dtls1.h @@ -0,0 +1,16 @@ +/* Copyright (c) 2015, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +/* This header is provided in order to make compiling against code that expects + OpenSSL easier. */ diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/dtls1.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/dtls1.h.grpc_back new file mode 100644 index 0000000..38ca801 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/dtls1.h.grpc_back @@ -0,0 +1,16 @@ +/* Copyright (c) 2015, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +/* This header is provided in order to make compiling against code that expects + OpenSSL easier. */ diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/ec.h b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/ec.h new file mode 100644 index 0000000..94772b0 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/ec.h @@ -0,0 +1,413 @@ +/* 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 OPENSSL_HEADER_EC_H +#define OPENSSL_HEADER_EC_H + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// Low-level operations on elliptic curves. + + +// point_conversion_form_t enumerates forms, as defined in X9.62 (ECDSA), for +// the encoding of a elliptic curve point (x,y) +typedef enum { + // POINT_CONVERSION_COMPRESSED indicates that the point is encoded as z||x, + // where the octet z specifies which solution of the quadratic equation y + // is. + POINT_CONVERSION_COMPRESSED = 2, + + // POINT_CONVERSION_UNCOMPRESSED indicates that the point is encoded as + // z||x||y, where z is the octet 0x04. + POINT_CONVERSION_UNCOMPRESSED = 4, + + // POINT_CONVERSION_HYBRID indicates that the point is encoded as z||x||y, + // where z specifies which solution of the quadratic equation y is. This is + // not supported by the code and has never been observed in use. + // + // TODO(agl): remove once node.js no longer references this. + POINT_CONVERSION_HYBRID = 6, +} point_conversion_form_t; + + +// Elliptic curve groups. + +// EC_GROUP_new_by_curve_name returns a fresh EC_GROUP object for the elliptic +// curve specified by |nid|, or NULL on error. +// +// The supported NIDs are: +// NID_secp224r1 (P-224), +// NID_X9_62_prime256v1 (P-256), +// NID_secp384r1 (P-384), +// NID_secp521r1 (P-521) +// +// If in doubt, use |NID_X9_62_prime256v1|, or see the curve25519.h header for +// more modern primitives. +OPENSSL_EXPORT EC_GROUP *EC_GROUP_new_by_curve_name(int nid); + +// EC_GROUP_free frees |group| and the data that it points to. +OPENSSL_EXPORT void EC_GROUP_free(EC_GROUP *group); + +// EC_GROUP_dup returns a fresh |EC_GROUP| which is equal to |a| or NULL on +// error. +OPENSSL_EXPORT EC_GROUP *EC_GROUP_dup(const EC_GROUP *a); + +// EC_GROUP_cmp returns zero if |a| and |b| are the same group and non-zero +// otherwise. +OPENSSL_EXPORT int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, + BN_CTX *ignored); + +// EC_GROUP_get0_generator returns a pointer to the internal |EC_POINT| object +// in |group| that specifies the generator for the group. +OPENSSL_EXPORT const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group); + +// EC_GROUP_get0_order returns a pointer to the internal |BIGNUM| object in +// |group| that specifies the order of the group. +OPENSSL_EXPORT const BIGNUM *EC_GROUP_get0_order(const EC_GROUP *group); + +// EC_GROUP_get_cofactor sets |*cofactor| to the cofactor of |group| using +// |ctx|, if it's not NULL. It returns one on success and zero otherwise. +OPENSSL_EXPORT int EC_GROUP_get_cofactor(const EC_GROUP *group, + BIGNUM *cofactor, BN_CTX *ctx); + +// EC_GROUP_get_curve_GFp gets various parameters about a group. It sets +// |*out_p| to the order of the coordinate field and |*out_a| and |*out_b| to +// the parameters of the curve when expressed as y² = x³ + ax + b. Any of the +// output parameters can be NULL. It returns one on success and zero on +// error. +OPENSSL_EXPORT int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *out_p, + BIGNUM *out_a, BIGNUM *out_b, + BN_CTX *ctx); + +// EC_GROUP_get_curve_name returns a NID that identifies |group|. +OPENSSL_EXPORT int EC_GROUP_get_curve_name(const EC_GROUP *group); + +// EC_GROUP_get_degree returns the number of bits needed to represent an +// element of the field underlying |group|. +OPENSSL_EXPORT unsigned EC_GROUP_get_degree(const EC_GROUP *group); + + +// Points on elliptic curves. + +// EC_POINT_new returns a fresh |EC_POINT| object in the given group, or NULL +// on error. +OPENSSL_EXPORT EC_POINT *EC_POINT_new(const EC_GROUP *group); + +// EC_POINT_free frees |point| and the data that it points to. +OPENSSL_EXPORT void EC_POINT_free(EC_POINT *point); + +// EC_POINT_copy sets |*dest| equal to |*src|. It returns one on success and +// zero otherwise. +OPENSSL_EXPORT int EC_POINT_copy(EC_POINT *dest, const EC_POINT *src); + +// EC_POINT_dup returns a fresh |EC_POINT| that contains the same values as +// |src|, or NULL on error. +OPENSSL_EXPORT EC_POINT *EC_POINT_dup(const EC_POINT *src, + const EC_GROUP *group); + +// EC_POINT_set_to_infinity sets |point| to be the "point at infinity" for the +// given group. +OPENSSL_EXPORT int EC_POINT_set_to_infinity(const EC_GROUP *group, + EC_POINT *point); + +// EC_POINT_is_at_infinity returns one iff |point| is the point at infinity and +// zero otherwise. +OPENSSL_EXPORT int EC_POINT_is_at_infinity(const EC_GROUP *group, + const EC_POINT *point); + +// EC_POINT_is_on_curve returns one if |point| is an element of |group| and +// and zero otherwise or when an error occurs. This is different from OpenSSL, +// which returns -1 on error. If |ctx| is non-NULL, it may be used. +OPENSSL_EXPORT int EC_POINT_is_on_curve(const EC_GROUP *group, + const EC_POINT *point, BN_CTX *ctx); + +// EC_POINT_cmp returns zero if |a| is equal to |b|, greater than zero if +// not equal and -1 on error. If |ctx| is not NULL, it may be used. +OPENSSL_EXPORT int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, + const EC_POINT *b, BN_CTX *ctx); + +// EC_POINT_make_affine converts |point| to affine form, internally. It returns +// one on success and zero otherwise. If |ctx| is not NULL, it may be used. +OPENSSL_EXPORT int EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, + BN_CTX *ctx); + +// EC_POINTs_make_affine converts |num| points from |points| to affine form, +// internally. It returns one on success and zero otherwise. If |ctx| is not +// NULL, it may be used. +OPENSSL_EXPORT int EC_POINTs_make_affine(const EC_GROUP *group, size_t num, + EC_POINT *points[], BN_CTX *ctx); + + +// Point conversion. + +// EC_POINT_get_affine_coordinates_GFp sets |x| and |y| to the affine value of +// |point| using |ctx|, if it's not NULL. It returns one on success and zero +// otherwise. +// +// Either |x| or |y| may be NULL to skip computing that coordinate. This is +// slightly faster in the common case where only the x-coordinate is needed. +OPENSSL_EXPORT int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group, + const EC_POINT *point, + BIGNUM *x, BIGNUM *y, + BN_CTX *ctx); + +// EC_POINT_set_affine_coordinates_GFp sets the value of |point| to be +// (|x|, |y|). The |ctx| argument may be used if not NULL. It returns one +// on success or zero on error. Note that, unlike with OpenSSL, it's +// considered an error if the point is not on the curve. +OPENSSL_EXPORT int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, + EC_POINT *point, + const BIGNUM *x, + const BIGNUM *y, + BN_CTX *ctx); + +// EC_POINT_point2oct serialises |point| into the X9.62 form given by |form| +// into, at most, |len| bytes at |buf|. It returns the number of bytes written +// or zero on error if |buf| is non-NULL, else the number of bytes needed. The +// |ctx| argument may be used if not NULL. +OPENSSL_EXPORT size_t EC_POINT_point2oct(const EC_GROUP *group, + const EC_POINT *point, + point_conversion_form_t form, + uint8_t *buf, size_t len, BN_CTX *ctx); + +// EC_POINT_point2cbb behaves like |EC_POINT_point2oct| but appends the +// serialised point to |cbb|. It returns one on success and zero on error. +OPENSSL_EXPORT int EC_POINT_point2cbb(CBB *out, const EC_GROUP *group, + const EC_POINT *point, + point_conversion_form_t form, + BN_CTX *ctx); + +// EC_POINT_oct2point sets |point| from |len| bytes of X9.62 format +// serialisation in |buf|. It returns one on success and zero otherwise. The +// |ctx| argument may be used if not NULL. +OPENSSL_EXPORT int EC_POINT_oct2point(const EC_GROUP *group, EC_POINT *point, + const uint8_t *buf, size_t len, + BN_CTX *ctx); + +// EC_POINT_set_compressed_coordinates_GFp sets |point| to equal the point with +// the given |x| coordinate and the y coordinate specified by |y_bit| (see +// X9.62). It returns one on success and zero otherwise. +OPENSSL_EXPORT int EC_POINT_set_compressed_coordinates_GFp( + const EC_GROUP *group, EC_POINT *point, const BIGNUM *x, int y_bit, + BN_CTX *ctx); + + +// Group operations. + +// EC_POINT_add sets |r| equal to |a| plus |b|. It returns one on success and +// zero otherwise. If |ctx| is not NULL, it may be used. +OPENSSL_EXPORT int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, + const EC_POINT *a, const EC_POINT *b, + BN_CTX *ctx); + +// EC_POINT_dbl sets |r| equal to |a| plus |a|. It returns one on success and +// zero otherwise. If |ctx| is not NULL, it may be used. +OPENSSL_EXPORT int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, + const EC_POINT *a, BN_CTX *ctx); + +// EC_POINT_invert sets |a| equal to minus |a|. It returns one on success and +// zero otherwise. If |ctx| is not NULL, it may be used. +OPENSSL_EXPORT int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, + BN_CTX *ctx); + +// EC_POINT_mul sets r = generator*n + q*m. It returns one on success and zero +// otherwise. If |ctx| is not NULL, it may be used. +OPENSSL_EXPORT int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, + const BIGNUM *n, const EC_POINT *q, + const BIGNUM *m, BN_CTX *ctx); + + +// Deprecated functions. + +// EC_GROUP_new_curve_GFp creates a new, arbitrary elliptic curve group based +// on the equation y² = x³ + a·x + b. It returns the new group or NULL on +// error. +// +// This new group has no generator. It is an error to use a generator-less group +// with any functions except for |EC_GROUP_free|, |EC_POINT_new|, +// |EC_POINT_set_affine_coordinates_GFp|, and |EC_GROUP_set_generator|. +// +// |EC_GROUP|s returned by this function will always compare as unequal via +// |EC_GROUP_cmp| (even to themselves). |EC_GROUP_get_curve_name| will always +// return |NID_undef|. +// +// Avoid using arbitrary curves and use |EC_GROUP_new_by_curve_name| instead. +OPENSSL_EXPORT EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, + const BIGNUM *a, + const BIGNUM *b, BN_CTX *ctx); + +// EC_GROUP_set_generator sets the generator for |group| to |generator|, which +// must have the given order and cofactor. It may only be used with |EC_GROUP| +// objects returned by |EC_GROUP_new_curve_GFp| and may only be used once on +// each group. |generator| must have been created using |group|. +OPENSSL_EXPORT int EC_GROUP_set_generator(EC_GROUP *group, + const EC_POINT *generator, + const BIGNUM *order, + const BIGNUM *cofactor); + +// EC_GROUP_get_order sets |*order| to the order of |group|, if it's not +// NULL. It returns one on success and zero otherwise. |ctx| is ignored. Use +// |EC_GROUP_get0_order| instead. +OPENSSL_EXPORT int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, + BN_CTX *ctx); + +// EC_GROUP_set_asn1_flag does nothing. +OPENSSL_EXPORT void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag); + +#define OPENSSL_EC_NAMED_CURVE 0 + +typedef struct ec_method_st EC_METHOD; + +// EC_GROUP_method_of returns NULL. +OPENSSL_EXPORT const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *group); + +// EC_METHOD_get_field_type returns NID_X9_62_prime_field. +OPENSSL_EXPORT int EC_METHOD_get_field_type(const EC_METHOD *meth); + +// EC_GROUP_set_point_conversion_form aborts the process if |form| is not +// |POINT_CONVERSION_UNCOMPRESSED| and otherwise does nothing. +OPENSSL_EXPORT void EC_GROUP_set_point_conversion_form( + EC_GROUP *group, point_conversion_form_t form); + +// EC_builtin_curve describes a supported elliptic curve. +typedef struct { + int nid; + const char *comment; +} EC_builtin_curve; + +// EC_get_builtin_curves writes at most |max_num_curves| elements to +// |out_curves| and returns the total number that it would have written, had +// |max_num_curves| been large enough. +// +// The |EC_builtin_curve| items describe the supported elliptic curves. +OPENSSL_EXPORT size_t EC_get_builtin_curves(EC_builtin_curve *out_curves, + size_t max_num_curves); + +// EC_POINT_clear_free calls |EC_POINT_free|. +OPENSSL_EXPORT void EC_POINT_clear_free(EC_POINT *point); + +// Old code expects to get EC_KEY from ec.h. +#include + + +#if defined(__cplusplus) +} // extern C + +extern "C++" { + +namespace bssl { + +BORINGSSL_MAKE_DELETER(EC_POINT, EC_POINT_free) +BORINGSSL_MAKE_DELETER(EC_GROUP, EC_GROUP_free) + +} // namespace bssl + +} // extern C++ + +#endif + +#define EC_R_BUFFER_TOO_SMALL 100 +#define EC_R_COORDINATES_OUT_OF_RANGE 101 +#define EC_R_D2I_ECPKPARAMETERS_FAILURE 102 +#define EC_R_EC_GROUP_NEW_BY_NAME_FAILURE 103 +#define EC_R_GROUP2PKPARAMETERS_FAILURE 104 +#define EC_R_I2D_ECPKPARAMETERS_FAILURE 105 +#define EC_R_INCOMPATIBLE_OBJECTS 106 +#define EC_R_INVALID_COMPRESSED_POINT 107 +#define EC_R_INVALID_COMPRESSION_BIT 108 +#define EC_R_INVALID_ENCODING 109 +#define EC_R_INVALID_FIELD 110 +#define EC_R_INVALID_FORM 111 +#define EC_R_INVALID_GROUP_ORDER 112 +#define EC_R_INVALID_PRIVATE_KEY 113 +#define EC_R_MISSING_PARAMETERS 114 +#define EC_R_MISSING_PRIVATE_KEY 115 +#define EC_R_NON_NAMED_CURVE 116 +#define EC_R_NOT_INITIALIZED 117 +#define EC_R_PKPARAMETERS2GROUP_FAILURE 118 +#define EC_R_POINT_AT_INFINITY 119 +#define EC_R_POINT_IS_NOT_ON_CURVE 120 +#define EC_R_SLOT_FULL 121 +#define EC_R_UNDEFINED_GENERATOR 122 +#define EC_R_UNKNOWN_GROUP 123 +#define EC_R_UNKNOWN_ORDER 124 +#define EC_R_WRONG_ORDER 125 +#define EC_R_BIGNUM_OUT_OF_RANGE 126 +#define EC_R_WRONG_CURVE_PARAMETERS 127 +#define EC_R_DECODE_ERROR 128 +#define EC_R_ENCODE_ERROR 129 +#define EC_R_GROUP_MISMATCH 130 +#define EC_R_INVALID_COFACTOR 131 +#define EC_R_PUBLIC_KEY_VALIDATION_FAILED 132 +#define EC_R_INVALID_SCALAR 133 + +#endif // OPENSSL_HEADER_EC_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/ec.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/ec.h.grpc_back new file mode 100644 index 0000000..5eee366 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/ec.h.grpc_back @@ -0,0 +1,413 @@ +/* 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 OPENSSL_HEADER_EC_H +#define OPENSSL_HEADER_EC_H + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// Low-level operations on elliptic curves. + + +// point_conversion_form_t enumerates forms, as defined in X9.62 (ECDSA), for +// the encoding of a elliptic curve point (x,y) +typedef enum { + // POINT_CONVERSION_COMPRESSED indicates that the point is encoded as z||x, + // where the octet z specifies which solution of the quadratic equation y + // is. + POINT_CONVERSION_COMPRESSED = 2, + + // POINT_CONVERSION_UNCOMPRESSED indicates that the point is encoded as + // z||x||y, where z is the octet 0x04. + POINT_CONVERSION_UNCOMPRESSED = 4, + + // POINT_CONVERSION_HYBRID indicates that the point is encoded as z||x||y, + // where z specifies which solution of the quadratic equation y is. This is + // not supported by the code and has never been observed in use. + // + // TODO(agl): remove once node.js no longer references this. + POINT_CONVERSION_HYBRID = 6, +} point_conversion_form_t; + + +// Elliptic curve groups. + +// EC_GROUP_new_by_curve_name returns a fresh EC_GROUP object for the elliptic +// curve specified by |nid|, or NULL on error. +// +// The supported NIDs are: +// NID_secp224r1 (P-224), +// NID_X9_62_prime256v1 (P-256), +// NID_secp384r1 (P-384), +// NID_secp521r1 (P-521) +// +// If in doubt, use |NID_X9_62_prime256v1|, or see the curve25519.h header for +// more modern primitives. +OPENSSL_EXPORT EC_GROUP *EC_GROUP_new_by_curve_name(int nid); + +// EC_GROUP_free frees |group| and the data that it points to. +OPENSSL_EXPORT void EC_GROUP_free(EC_GROUP *group); + +// EC_GROUP_dup returns a fresh |EC_GROUP| which is equal to |a| or NULL on +// error. +OPENSSL_EXPORT EC_GROUP *EC_GROUP_dup(const EC_GROUP *a); + +// EC_GROUP_cmp returns zero if |a| and |b| are the same group and non-zero +// otherwise. +OPENSSL_EXPORT int EC_GROUP_cmp(const EC_GROUP *a, const EC_GROUP *b, + BN_CTX *ignored); + +// EC_GROUP_get0_generator returns a pointer to the internal |EC_POINT| object +// in |group| that specifies the generator for the group. +OPENSSL_EXPORT const EC_POINT *EC_GROUP_get0_generator(const EC_GROUP *group); + +// EC_GROUP_get0_order returns a pointer to the internal |BIGNUM| object in +// |group| that specifies the order of the group. +OPENSSL_EXPORT const BIGNUM *EC_GROUP_get0_order(const EC_GROUP *group); + +// EC_GROUP_get_cofactor sets |*cofactor| to the cofactor of |group| using +// |ctx|, if it's not NULL. It returns one on success and zero otherwise. +OPENSSL_EXPORT int EC_GROUP_get_cofactor(const EC_GROUP *group, + BIGNUM *cofactor, BN_CTX *ctx); + +// EC_GROUP_get_curve_GFp gets various parameters about a group. It sets +// |*out_p| to the order of the coordinate field and |*out_a| and |*out_b| to +// the parameters of the curve when expressed as y² = x³ + ax + b. Any of the +// output parameters can be NULL. It returns one on success and zero on +// error. +OPENSSL_EXPORT int EC_GROUP_get_curve_GFp(const EC_GROUP *group, BIGNUM *out_p, + BIGNUM *out_a, BIGNUM *out_b, + BN_CTX *ctx); + +// EC_GROUP_get_curve_name returns a NID that identifies |group|. +OPENSSL_EXPORT int EC_GROUP_get_curve_name(const EC_GROUP *group); + +// EC_GROUP_get_degree returns the number of bits needed to represent an +// element of the field underlying |group|. +OPENSSL_EXPORT unsigned EC_GROUP_get_degree(const EC_GROUP *group); + + +// Points on elliptic curves. + +// EC_POINT_new returns a fresh |EC_POINT| object in the given group, or NULL +// on error. +OPENSSL_EXPORT EC_POINT *EC_POINT_new(const EC_GROUP *group); + +// EC_POINT_free frees |point| and the data that it points to. +OPENSSL_EXPORT void EC_POINT_free(EC_POINT *point); + +// EC_POINT_copy sets |*dest| equal to |*src|. It returns one on success and +// zero otherwise. +OPENSSL_EXPORT int EC_POINT_copy(EC_POINT *dest, const EC_POINT *src); + +// EC_POINT_dup returns a fresh |EC_POINT| that contains the same values as +// |src|, or NULL on error. +OPENSSL_EXPORT EC_POINT *EC_POINT_dup(const EC_POINT *src, + const EC_GROUP *group); + +// EC_POINT_set_to_infinity sets |point| to be the "point at infinity" for the +// given group. +OPENSSL_EXPORT int EC_POINT_set_to_infinity(const EC_GROUP *group, + EC_POINT *point); + +// EC_POINT_is_at_infinity returns one iff |point| is the point at infinity and +// zero otherwise. +OPENSSL_EXPORT int EC_POINT_is_at_infinity(const EC_GROUP *group, + const EC_POINT *point); + +// EC_POINT_is_on_curve returns one if |point| is an element of |group| and +// and zero otherwise or when an error occurs. This is different from OpenSSL, +// which returns -1 on error. If |ctx| is non-NULL, it may be used. +OPENSSL_EXPORT int EC_POINT_is_on_curve(const EC_GROUP *group, + const EC_POINT *point, BN_CTX *ctx); + +// EC_POINT_cmp returns zero if |a| is equal to |b|, greater than zero if +// not equal and -1 on error. If |ctx| is not NULL, it may be used. +OPENSSL_EXPORT int EC_POINT_cmp(const EC_GROUP *group, const EC_POINT *a, + const EC_POINT *b, BN_CTX *ctx); + +// EC_POINT_make_affine converts |point| to affine form, internally. It returns +// one on success and zero otherwise. If |ctx| is not NULL, it may be used. +OPENSSL_EXPORT int EC_POINT_make_affine(const EC_GROUP *group, EC_POINT *point, + BN_CTX *ctx); + +// EC_POINTs_make_affine converts |num| points from |points| to affine form, +// internally. It returns one on success and zero otherwise. If |ctx| is not +// NULL, it may be used. +OPENSSL_EXPORT int EC_POINTs_make_affine(const EC_GROUP *group, size_t num, + EC_POINT *points[], BN_CTX *ctx); + + +// Point conversion. + +// EC_POINT_get_affine_coordinates_GFp sets |x| and |y| to the affine value of +// |point| using |ctx|, if it's not NULL. It returns one on success and zero +// otherwise. +// +// Either |x| or |y| may be NULL to skip computing that coordinate. This is +// slightly faster in the common case where only the x-coordinate is needed. +OPENSSL_EXPORT int EC_POINT_get_affine_coordinates_GFp(const EC_GROUP *group, + const EC_POINT *point, + BIGNUM *x, BIGNUM *y, + BN_CTX *ctx); + +// EC_POINT_set_affine_coordinates_GFp sets the value of |point| to be +// (|x|, |y|). The |ctx| argument may be used if not NULL. It returns one +// on success or zero on error. Note that, unlike with OpenSSL, it's +// considered an error if the point is not on the curve. +OPENSSL_EXPORT int EC_POINT_set_affine_coordinates_GFp(const EC_GROUP *group, + EC_POINT *point, + const BIGNUM *x, + const BIGNUM *y, + BN_CTX *ctx); + +// EC_POINT_point2oct serialises |point| into the X9.62 form given by |form| +// into, at most, |len| bytes at |buf|. It returns the number of bytes written +// or zero on error if |buf| is non-NULL, else the number of bytes needed. The +// |ctx| argument may be used if not NULL. +OPENSSL_EXPORT size_t EC_POINT_point2oct(const EC_GROUP *group, + const EC_POINT *point, + point_conversion_form_t form, + uint8_t *buf, size_t len, BN_CTX *ctx); + +// EC_POINT_point2cbb behaves like |EC_POINT_point2oct| but appends the +// serialised point to |cbb|. It returns one on success and zero on error. +OPENSSL_EXPORT int EC_POINT_point2cbb(CBB *out, const EC_GROUP *group, + const EC_POINT *point, + point_conversion_form_t form, + BN_CTX *ctx); + +// EC_POINT_oct2point sets |point| from |len| bytes of X9.62 format +// serialisation in |buf|. It returns one on success and zero otherwise. The +// |ctx| argument may be used if not NULL. +OPENSSL_EXPORT int EC_POINT_oct2point(const EC_GROUP *group, EC_POINT *point, + const uint8_t *buf, size_t len, + BN_CTX *ctx); + +// EC_POINT_set_compressed_coordinates_GFp sets |point| to equal the point with +// the given |x| coordinate and the y coordinate specified by |y_bit| (see +// X9.62). It returns one on success and zero otherwise. +OPENSSL_EXPORT int EC_POINT_set_compressed_coordinates_GFp( + const EC_GROUP *group, EC_POINT *point, const BIGNUM *x, int y_bit, + BN_CTX *ctx); + + +// Group operations. + +// EC_POINT_add sets |r| equal to |a| plus |b|. It returns one on success and +// zero otherwise. If |ctx| is not NULL, it may be used. +OPENSSL_EXPORT int EC_POINT_add(const EC_GROUP *group, EC_POINT *r, + const EC_POINT *a, const EC_POINT *b, + BN_CTX *ctx); + +// EC_POINT_dbl sets |r| equal to |a| plus |a|. It returns one on success and +// zero otherwise. If |ctx| is not NULL, it may be used. +OPENSSL_EXPORT int EC_POINT_dbl(const EC_GROUP *group, EC_POINT *r, + const EC_POINT *a, BN_CTX *ctx); + +// EC_POINT_invert sets |a| equal to minus |a|. It returns one on success and +// zero otherwise. If |ctx| is not NULL, it may be used. +OPENSSL_EXPORT int EC_POINT_invert(const EC_GROUP *group, EC_POINT *a, + BN_CTX *ctx); + +// EC_POINT_mul sets r = generator*n + q*m. It returns one on success and zero +// otherwise. If |ctx| is not NULL, it may be used. +OPENSSL_EXPORT int EC_POINT_mul(const EC_GROUP *group, EC_POINT *r, + const BIGNUM *n, const EC_POINT *q, + const BIGNUM *m, BN_CTX *ctx); + + +// Deprecated functions. + +// EC_GROUP_new_curve_GFp creates a new, arbitrary elliptic curve group based +// on the equation y² = x³ + a·x + b. It returns the new group or NULL on +// error. +// +// This new group has no generator. It is an error to use a generator-less group +// with any functions except for |EC_GROUP_free|, |EC_POINT_new|, +// |EC_POINT_set_affine_coordinates_GFp|, and |EC_GROUP_set_generator|. +// +// |EC_GROUP|s returned by this function will always compare as unequal via +// |EC_GROUP_cmp| (even to themselves). |EC_GROUP_get_curve_name| will always +// return |NID_undef|. +// +// Avoid using arbitrary curves and use |EC_GROUP_new_by_curve_name| instead. +OPENSSL_EXPORT EC_GROUP *EC_GROUP_new_curve_GFp(const BIGNUM *p, + const BIGNUM *a, + const BIGNUM *b, BN_CTX *ctx); + +// EC_GROUP_set_generator sets the generator for |group| to |generator|, which +// must have the given order and cofactor. It may only be used with |EC_GROUP| +// objects returned by |EC_GROUP_new_curve_GFp| and may only be used once on +// each group. |generator| must have been created using |group|. +OPENSSL_EXPORT int EC_GROUP_set_generator(EC_GROUP *group, + const EC_POINT *generator, + const BIGNUM *order, + const BIGNUM *cofactor); + +// EC_GROUP_get_order sets |*order| to the order of |group|, if it's not +// NULL. It returns one on success and zero otherwise. |ctx| is ignored. Use +// |EC_GROUP_get0_order| instead. +OPENSSL_EXPORT int EC_GROUP_get_order(const EC_GROUP *group, BIGNUM *order, + BN_CTX *ctx); + +// EC_GROUP_set_asn1_flag does nothing. +OPENSSL_EXPORT void EC_GROUP_set_asn1_flag(EC_GROUP *group, int flag); + +#define OPENSSL_EC_NAMED_CURVE 0 + +typedef struct ec_method_st EC_METHOD; + +// EC_GROUP_method_of returns NULL. +OPENSSL_EXPORT const EC_METHOD *EC_GROUP_method_of(const EC_GROUP *group); + +// EC_METHOD_get_field_type returns NID_X9_62_prime_field. +OPENSSL_EXPORT int EC_METHOD_get_field_type(const EC_METHOD *meth); + +// EC_GROUP_set_point_conversion_form aborts the process if |form| is not +// |POINT_CONVERSION_UNCOMPRESSED| and otherwise does nothing. +OPENSSL_EXPORT void EC_GROUP_set_point_conversion_form( + EC_GROUP *group, point_conversion_form_t form); + +// EC_builtin_curve describes a supported elliptic curve. +typedef struct { + int nid; + const char *comment; +} EC_builtin_curve; + +// EC_get_builtin_curves writes at most |max_num_curves| elements to +// |out_curves| and returns the total number that it would have written, had +// |max_num_curves| been large enough. +// +// The |EC_builtin_curve| items describe the supported elliptic curves. +OPENSSL_EXPORT size_t EC_get_builtin_curves(EC_builtin_curve *out_curves, + size_t max_num_curves); + +// EC_POINT_clear_free calls |EC_POINT_free|. +OPENSSL_EXPORT void EC_POINT_clear_free(EC_POINT *point); + +// Old code expects to get EC_KEY from ec.h. +#include + + +#if defined(__cplusplus) +} // extern C + +extern "C++" { + +namespace bssl { + +BORINGSSL_MAKE_DELETER(EC_POINT, EC_POINT_free) +BORINGSSL_MAKE_DELETER(EC_GROUP, EC_GROUP_free) + +} // namespace bssl + +} // extern C++ + +#endif + +#define EC_R_BUFFER_TOO_SMALL 100 +#define EC_R_COORDINATES_OUT_OF_RANGE 101 +#define EC_R_D2I_ECPKPARAMETERS_FAILURE 102 +#define EC_R_EC_GROUP_NEW_BY_NAME_FAILURE 103 +#define EC_R_GROUP2PKPARAMETERS_FAILURE 104 +#define EC_R_I2D_ECPKPARAMETERS_FAILURE 105 +#define EC_R_INCOMPATIBLE_OBJECTS 106 +#define EC_R_INVALID_COMPRESSED_POINT 107 +#define EC_R_INVALID_COMPRESSION_BIT 108 +#define EC_R_INVALID_ENCODING 109 +#define EC_R_INVALID_FIELD 110 +#define EC_R_INVALID_FORM 111 +#define EC_R_INVALID_GROUP_ORDER 112 +#define EC_R_INVALID_PRIVATE_KEY 113 +#define EC_R_MISSING_PARAMETERS 114 +#define EC_R_MISSING_PRIVATE_KEY 115 +#define EC_R_NON_NAMED_CURVE 116 +#define EC_R_NOT_INITIALIZED 117 +#define EC_R_PKPARAMETERS2GROUP_FAILURE 118 +#define EC_R_POINT_AT_INFINITY 119 +#define EC_R_POINT_IS_NOT_ON_CURVE 120 +#define EC_R_SLOT_FULL 121 +#define EC_R_UNDEFINED_GENERATOR 122 +#define EC_R_UNKNOWN_GROUP 123 +#define EC_R_UNKNOWN_ORDER 124 +#define EC_R_WRONG_ORDER 125 +#define EC_R_BIGNUM_OUT_OF_RANGE 126 +#define EC_R_WRONG_CURVE_PARAMETERS 127 +#define EC_R_DECODE_ERROR 128 +#define EC_R_ENCODE_ERROR 129 +#define EC_R_GROUP_MISMATCH 130 +#define EC_R_INVALID_COFACTOR 131 +#define EC_R_PUBLIC_KEY_VALIDATION_FAILED 132 +#define EC_R_INVALID_SCALAR 133 + +#endif // OPENSSL_HEADER_EC_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/ec_key.h b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/ec_key.h new file mode 100644 index 0000000..b3e9042 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/ec_key.h @@ -0,0 +1,342 @@ +/* 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 OPENSSL_HEADER_EC_KEY_H +#define OPENSSL_HEADER_EC_KEY_H + +#include + +#include +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// ec_key.h contains functions that handle elliptic-curve points that are +// public/private keys. + + +// EC key objects. + +// EC_KEY_new returns a fresh |EC_KEY| object or NULL on error. +OPENSSL_EXPORT EC_KEY *EC_KEY_new(void); + +// EC_KEY_new_method acts the same as |EC_KEY_new|, but takes an explicit +// |ENGINE|. +OPENSSL_EXPORT EC_KEY *EC_KEY_new_method(const ENGINE *engine); + +// EC_KEY_new_by_curve_name returns a fresh EC_KEY for group specified by |nid| +// or NULL on error. +OPENSSL_EXPORT EC_KEY *EC_KEY_new_by_curve_name(int nid); + +// EC_KEY_free frees all the data owned by |key| and |key| itself. +OPENSSL_EXPORT void EC_KEY_free(EC_KEY *key); + +// EC_KEY_dup returns a fresh copy of |src| or NULL on error. +OPENSSL_EXPORT EC_KEY *EC_KEY_dup(const EC_KEY *src); + +// EC_KEY_up_ref increases the reference count of |key| and returns one. +OPENSSL_EXPORT int EC_KEY_up_ref(EC_KEY *key); + +// EC_KEY_is_opaque returns one if |key| is opaque and doesn't expose its key +// material. Otherwise it return zero. +OPENSSL_EXPORT int EC_KEY_is_opaque(const EC_KEY *key); + +// EC_KEY_get0_group returns a pointer to the |EC_GROUP| object inside |key|. +OPENSSL_EXPORT const EC_GROUP *EC_KEY_get0_group(const EC_KEY *key); + +// EC_KEY_set_group sets the |EC_GROUP| object that |key| will use to |group|. +// It returns one on success and zero otherwise. If |key| already has a group, +// it is an error to change to a different one. +OPENSSL_EXPORT int EC_KEY_set_group(EC_KEY *key, const EC_GROUP *group); + +// EC_KEY_get0_private_key returns a pointer to the private key inside |key|. +OPENSSL_EXPORT const BIGNUM *EC_KEY_get0_private_key(const EC_KEY *key); + +// EC_KEY_set_private_key sets the private key of |key| to |priv|. It returns +// one on success and zero otherwise. |key| must already have had a group +// configured (see |EC_KEY_set_group| and |EC_KEY_new_by_curve_name|). +OPENSSL_EXPORT int EC_KEY_set_private_key(EC_KEY *key, const BIGNUM *prv); + +// EC_KEY_get0_public_key returns a pointer to the public key point inside +// |key|. +OPENSSL_EXPORT const EC_POINT *EC_KEY_get0_public_key(const EC_KEY *key); + +// EC_KEY_set_public_key sets the public key of |key| to |pub|, by copying it. +// It returns one on success and zero otherwise. |key| must already have had a +// group configured (see |EC_KEY_set_group| and |EC_KEY_new_by_curve_name|), and +// |pub| must also belong to that group. +OPENSSL_EXPORT int EC_KEY_set_public_key(EC_KEY *key, const EC_POINT *pub); + +#define EC_PKEY_NO_PARAMETERS 0x001 +#define EC_PKEY_NO_PUBKEY 0x002 + +// EC_KEY_get_enc_flags returns the encoding flags for |key|, which is a +// bitwise-OR of |EC_PKEY_*| values. +OPENSSL_EXPORT unsigned EC_KEY_get_enc_flags(const EC_KEY *key); + +// EC_KEY_set_enc_flags sets the encoding flags for |key|, which is a +// bitwise-OR of |EC_PKEY_*| values. +OPENSSL_EXPORT void EC_KEY_set_enc_flags(EC_KEY *key, unsigned flags); + +// EC_KEY_get_conv_form returns the conversation form that will be used by +// |key|. +OPENSSL_EXPORT point_conversion_form_t EC_KEY_get_conv_form(const EC_KEY *key); + +// EC_KEY_set_conv_form sets the conversion form to be used by |key|. +OPENSSL_EXPORT void EC_KEY_set_conv_form(EC_KEY *key, + point_conversion_form_t cform); + +// EC_KEY_check_key performs several checks on |key| (possibly including an +// expensive check that the public key is in the primary subgroup). It returns +// one if all checks pass and zero otherwise. If it returns zero then detail +// about the problem can be found on the error stack. +OPENSSL_EXPORT int EC_KEY_check_key(const EC_KEY *key); + +// EC_KEY_check_fips performs a signing pairwise consistency test (FIPS 140-2 +// 4.9.2). It returns one if it passes and zero otherwise. +OPENSSL_EXPORT int EC_KEY_check_fips(const EC_KEY *key); + +// EC_KEY_set_public_key_affine_coordinates sets the public key in |key| to +// (|x|, |y|). It returns one on success and zero otherwise. +OPENSSL_EXPORT int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, + BIGNUM *x, + BIGNUM *y); + + +// Key generation. + +// EC_KEY_generate_key generates a random, private key, calculates the +// corresponding public key and stores both in |key|. It returns one on success +// or zero otherwise. +OPENSSL_EXPORT int EC_KEY_generate_key(EC_KEY *key); + +// EC_KEY_generate_key_fips behaves like |EC_KEY_generate_key| but performs +// additional checks for FIPS compliance. +OPENSSL_EXPORT int EC_KEY_generate_key_fips(EC_KEY *key); + + +// Serialisation. + +// EC_KEY_parse_private_key parses a DER-encoded ECPrivateKey structure (RFC +// 5915) from |cbs| and advances |cbs|. It returns a newly-allocated |EC_KEY| or +// NULL on error. If |group| is non-null, the parameters field of the +// ECPrivateKey may be omitted (but must match |group| if present). Otherwise, +// the parameters field is required. +OPENSSL_EXPORT EC_KEY *EC_KEY_parse_private_key(CBS *cbs, + const EC_GROUP *group); + +// EC_KEY_marshal_private_key marshals |key| as a DER-encoded ECPrivateKey +// structure (RFC 5915) and appends the result to |cbb|. It returns one on +// success and zero on failure. |enc_flags| is a combination of |EC_PKEY_*| +// values and controls whether corresponding fields are omitted. +OPENSSL_EXPORT int EC_KEY_marshal_private_key(CBB *cbb, const EC_KEY *key, + unsigned enc_flags); + +// EC_KEY_parse_curve_name parses a DER-encoded OBJECT IDENTIFIER as a curve +// name from |cbs| and advances |cbs|. It returns a newly-allocated |EC_GROUP| +// or NULL on error. +OPENSSL_EXPORT EC_GROUP *EC_KEY_parse_curve_name(CBS *cbs); + +// EC_KEY_marshal_curve_name marshals |group| as a DER-encoded OBJECT IDENTIFIER +// and appends the result to |cbb|. It returns one on success and zero on +// failure. +OPENSSL_EXPORT int EC_KEY_marshal_curve_name(CBB *cbb, const EC_GROUP *group); + +// EC_KEY_parse_parameters parses a DER-encoded ECParameters structure (RFC +// 5480) from |cbs| and advances |cbs|. It returns a newly-allocated |EC_GROUP| +// or NULL on error. It supports the namedCurve and specifiedCurve options, but +// use of specifiedCurve is deprecated. Use |EC_KEY_parse_curve_name| +// instead. +OPENSSL_EXPORT EC_GROUP *EC_KEY_parse_parameters(CBS *cbs); + + +// ex_data functions. +// +// These functions are wrappers. See |ex_data.h| for details. + +OPENSSL_EXPORT int EC_KEY_get_ex_new_index(long argl, void *argp, + CRYPTO_EX_unused *unused, + CRYPTO_EX_dup *dup_unused, + CRYPTO_EX_free *free_func); +OPENSSL_EXPORT int EC_KEY_set_ex_data(EC_KEY *r, int idx, void *arg); +OPENSSL_EXPORT void *EC_KEY_get_ex_data(const EC_KEY *r, int idx); + + +// ECDSA method. + +// ECDSA_FLAG_OPAQUE specifies that this ECDSA_METHOD does not expose its key +// material. This may be set if, for instance, it is wrapping some other crypto +// API, like a platform key store. +#define ECDSA_FLAG_OPAQUE 1 + +// ecdsa_method_st is a structure of function pointers for implementing ECDSA. +// See engine.h. +struct ecdsa_method_st { + struct openssl_method_common_st common; + + void *app_data; + + int (*init)(EC_KEY *key); + int (*finish)(EC_KEY *key); + + // group_order_size returns the number of bytes needed to represent the order + // of the group. This is used to calculate the maximum size of an ECDSA + // signature in |ECDSA_size|. + size_t (*group_order_size)(const EC_KEY *key); + + // sign matches the arguments and behaviour of |ECDSA_sign|. + int (*sign)(const uint8_t *digest, size_t digest_len, uint8_t *sig, + unsigned int *sig_len, EC_KEY *eckey); + + int flags; +}; + + +// Deprecated functions. + +// EC_KEY_set_asn1_flag does nothing. +OPENSSL_EXPORT void EC_KEY_set_asn1_flag(EC_KEY *key, int flag); + +// d2i_ECPrivateKey parses an ASN.1, DER-encoded, private key from |len| bytes +// at |*inp|. If |out_key| is not NULL then, on exit, a pointer to the result +// is in |*out_key|. Note that, even if |*out_key| is already non-NULL on entry, +// it * will not be written to. Rather, a fresh |EC_KEY| is allocated and the +// previous * one is freed. On successful exit, |*inp| is advanced past the DER +// structure. It returns the result or NULL on error. +// +// On input, if |*out_key| is non-NULL and has a group configured, the +// parameters field may be omitted but must match that group if present. +// +// Use |EC_KEY_parse_private_key| instead. +OPENSSL_EXPORT EC_KEY *d2i_ECPrivateKey(EC_KEY **out_key, const uint8_t **inp, + long len); + +// i2d_ECPrivateKey marshals an EC private key from |key| to an ASN.1, DER +// structure. If |outp| is not NULL then the result is written to |*outp| and +// |*outp| is advanced just past the output. It returns the number of bytes in +// the result, whether written or not, or a negative value on error. +// +// Use |EC_KEY_marshal_private_key| instead. +OPENSSL_EXPORT int i2d_ECPrivateKey(const EC_KEY *key, uint8_t **outp); + +// d2i_ECParameters parses an ASN.1, DER-encoded, set of EC parameters from +// |len| bytes at |*inp|. If |out_key| is not NULL then, on exit, a pointer to +// the result is in |*out_key|. Note that, even if |*out_key| is already +// non-NULL on entry, it will not be written to. Rather, a fresh |EC_KEY| is +// allocated and the previous one is freed. On successful exit, |*inp| is +// advanced past the DER structure. It returns the result or NULL on error. +// +// Use |EC_KEY_parse_parameters| or |EC_KEY_parse_curve_name| instead. +OPENSSL_EXPORT EC_KEY *d2i_ECParameters(EC_KEY **out_key, const uint8_t **inp, + long len); + +// i2d_ECParameters marshals EC parameters from |key| to an ASN.1, DER +// structure. If |outp| is not NULL then the result is written to |*outp| and +// |*outp| is advanced just past the output. It returns the number of bytes in +// the result, whether written or not, or a negative value on error. +// +// Use |EC_KEY_marshal_curve_name| instead. +OPENSSL_EXPORT int i2d_ECParameters(const EC_KEY *key, uint8_t **outp); + +// o2i_ECPublicKey parses an EC point from |len| bytes at |*inp| into +// |*out_key|. Note that this differs from the d2i format in that |*out_key| +// must be non-NULL with a group set. On successful exit, |*inp| is advanced by +// |len| bytes. It returns |*out_key| or NULL on error. +// +// Use |EC_POINT_oct2point| instead. +OPENSSL_EXPORT EC_KEY *o2i_ECPublicKey(EC_KEY **out_key, const uint8_t **inp, + long len); + +// i2o_ECPublicKey marshals an EC point from |key|. If |outp| is not NULL then +// the result is written to |*outp| and |*outp| is advanced just past the +// output. It returns the number of bytes in the result, whether written or +// not, or a negative value on error. +// +// Use |EC_POINT_point2cbb| instead. +OPENSSL_EXPORT int i2o_ECPublicKey(const EC_KEY *key, unsigned char **outp); + + +#if defined(__cplusplus) +} // extern C + +extern "C++" { + +namespace bssl { + +BORINGSSL_MAKE_DELETER(EC_KEY, EC_KEY_free) + +} // namespace bssl + +} // extern C++ + +#endif + +#endif // OPENSSL_HEADER_EC_KEY_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/ec_key.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/ec_key.h.grpc_back new file mode 100644 index 0000000..cc075e5 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/ec_key.h.grpc_back @@ -0,0 +1,342 @@ +/* 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 OPENSSL_HEADER_EC_KEY_H +#define OPENSSL_HEADER_EC_KEY_H + +#include + +#include +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// ec_key.h contains functions that handle elliptic-curve points that are +// public/private keys. + + +// EC key objects. + +// EC_KEY_new returns a fresh |EC_KEY| object or NULL on error. +OPENSSL_EXPORT EC_KEY *EC_KEY_new(void); + +// EC_KEY_new_method acts the same as |EC_KEY_new|, but takes an explicit +// |ENGINE|. +OPENSSL_EXPORT EC_KEY *EC_KEY_new_method(const ENGINE *engine); + +// EC_KEY_new_by_curve_name returns a fresh EC_KEY for group specified by |nid| +// or NULL on error. +OPENSSL_EXPORT EC_KEY *EC_KEY_new_by_curve_name(int nid); + +// EC_KEY_free frees all the data owned by |key| and |key| itself. +OPENSSL_EXPORT void EC_KEY_free(EC_KEY *key); + +// EC_KEY_dup returns a fresh copy of |src| or NULL on error. +OPENSSL_EXPORT EC_KEY *EC_KEY_dup(const EC_KEY *src); + +// EC_KEY_up_ref increases the reference count of |key| and returns one. +OPENSSL_EXPORT int EC_KEY_up_ref(EC_KEY *key); + +// EC_KEY_is_opaque returns one if |key| is opaque and doesn't expose its key +// material. Otherwise it return zero. +OPENSSL_EXPORT int EC_KEY_is_opaque(const EC_KEY *key); + +// EC_KEY_get0_group returns a pointer to the |EC_GROUP| object inside |key|. +OPENSSL_EXPORT const EC_GROUP *EC_KEY_get0_group(const EC_KEY *key); + +// EC_KEY_set_group sets the |EC_GROUP| object that |key| will use to |group|. +// It returns one on success and zero otherwise. If |key| already has a group, +// it is an error to change to a different one. +OPENSSL_EXPORT int EC_KEY_set_group(EC_KEY *key, const EC_GROUP *group); + +// EC_KEY_get0_private_key returns a pointer to the private key inside |key|. +OPENSSL_EXPORT const BIGNUM *EC_KEY_get0_private_key(const EC_KEY *key); + +// EC_KEY_set_private_key sets the private key of |key| to |priv|. It returns +// one on success and zero otherwise. |key| must already have had a group +// configured (see |EC_KEY_set_group| and |EC_KEY_new_by_curve_name|). +OPENSSL_EXPORT int EC_KEY_set_private_key(EC_KEY *key, const BIGNUM *prv); + +// EC_KEY_get0_public_key returns a pointer to the public key point inside +// |key|. +OPENSSL_EXPORT const EC_POINT *EC_KEY_get0_public_key(const EC_KEY *key); + +// EC_KEY_set_public_key sets the public key of |key| to |pub|, by copying it. +// It returns one on success and zero otherwise. |key| must already have had a +// group configured (see |EC_KEY_set_group| and |EC_KEY_new_by_curve_name|), and +// |pub| must also belong to that group. +OPENSSL_EXPORT int EC_KEY_set_public_key(EC_KEY *key, const EC_POINT *pub); + +#define EC_PKEY_NO_PARAMETERS 0x001 +#define EC_PKEY_NO_PUBKEY 0x002 + +// EC_KEY_get_enc_flags returns the encoding flags for |key|, which is a +// bitwise-OR of |EC_PKEY_*| values. +OPENSSL_EXPORT unsigned EC_KEY_get_enc_flags(const EC_KEY *key); + +// EC_KEY_set_enc_flags sets the encoding flags for |key|, which is a +// bitwise-OR of |EC_PKEY_*| values. +OPENSSL_EXPORT void EC_KEY_set_enc_flags(EC_KEY *key, unsigned flags); + +// EC_KEY_get_conv_form returns the conversation form that will be used by +// |key|. +OPENSSL_EXPORT point_conversion_form_t EC_KEY_get_conv_form(const EC_KEY *key); + +// EC_KEY_set_conv_form sets the conversion form to be used by |key|. +OPENSSL_EXPORT void EC_KEY_set_conv_form(EC_KEY *key, + point_conversion_form_t cform); + +// EC_KEY_check_key performs several checks on |key| (possibly including an +// expensive check that the public key is in the primary subgroup). It returns +// one if all checks pass and zero otherwise. If it returns zero then detail +// about the problem can be found on the error stack. +OPENSSL_EXPORT int EC_KEY_check_key(const EC_KEY *key); + +// EC_KEY_check_fips performs a signing pairwise consistency test (FIPS 140-2 +// 4.9.2). It returns one if it passes and zero otherwise. +OPENSSL_EXPORT int EC_KEY_check_fips(const EC_KEY *key); + +// EC_KEY_set_public_key_affine_coordinates sets the public key in |key| to +// (|x|, |y|). It returns one on success and zero otherwise. +OPENSSL_EXPORT int EC_KEY_set_public_key_affine_coordinates(EC_KEY *key, + BIGNUM *x, + BIGNUM *y); + + +// Key generation. + +// EC_KEY_generate_key generates a random, private key, calculates the +// corresponding public key and stores both in |key|. It returns one on success +// or zero otherwise. +OPENSSL_EXPORT int EC_KEY_generate_key(EC_KEY *key); + +// EC_KEY_generate_key_fips behaves like |EC_KEY_generate_key| but performs +// additional checks for FIPS compliance. +OPENSSL_EXPORT int EC_KEY_generate_key_fips(EC_KEY *key); + + +// Serialisation. + +// EC_KEY_parse_private_key parses a DER-encoded ECPrivateKey structure (RFC +// 5915) from |cbs| and advances |cbs|. It returns a newly-allocated |EC_KEY| or +// NULL on error. If |group| is non-null, the parameters field of the +// ECPrivateKey may be omitted (but must match |group| if present). Otherwise, +// the parameters field is required. +OPENSSL_EXPORT EC_KEY *EC_KEY_parse_private_key(CBS *cbs, + const EC_GROUP *group); + +// EC_KEY_marshal_private_key marshals |key| as a DER-encoded ECPrivateKey +// structure (RFC 5915) and appends the result to |cbb|. It returns one on +// success and zero on failure. |enc_flags| is a combination of |EC_PKEY_*| +// values and controls whether corresponding fields are omitted. +OPENSSL_EXPORT int EC_KEY_marshal_private_key(CBB *cbb, const EC_KEY *key, + unsigned enc_flags); + +// EC_KEY_parse_curve_name parses a DER-encoded OBJECT IDENTIFIER as a curve +// name from |cbs| and advances |cbs|. It returns a newly-allocated |EC_GROUP| +// or NULL on error. +OPENSSL_EXPORT EC_GROUP *EC_KEY_parse_curve_name(CBS *cbs); + +// EC_KEY_marshal_curve_name marshals |group| as a DER-encoded OBJECT IDENTIFIER +// and appends the result to |cbb|. It returns one on success and zero on +// failure. +OPENSSL_EXPORT int EC_KEY_marshal_curve_name(CBB *cbb, const EC_GROUP *group); + +// EC_KEY_parse_parameters parses a DER-encoded ECParameters structure (RFC +// 5480) from |cbs| and advances |cbs|. It returns a newly-allocated |EC_GROUP| +// or NULL on error. It supports the namedCurve and specifiedCurve options, but +// use of specifiedCurve is deprecated. Use |EC_KEY_parse_curve_name| +// instead. +OPENSSL_EXPORT EC_GROUP *EC_KEY_parse_parameters(CBS *cbs); + + +// ex_data functions. +// +// These functions are wrappers. See |ex_data.h| for details. + +OPENSSL_EXPORT int EC_KEY_get_ex_new_index(long argl, void *argp, + CRYPTO_EX_unused *unused, + CRYPTO_EX_dup *dup_unused, + CRYPTO_EX_free *free_func); +OPENSSL_EXPORT int EC_KEY_set_ex_data(EC_KEY *r, int idx, void *arg); +OPENSSL_EXPORT void *EC_KEY_get_ex_data(const EC_KEY *r, int idx); + + +// ECDSA method. + +// ECDSA_FLAG_OPAQUE specifies that this ECDSA_METHOD does not expose its key +// material. This may be set if, for instance, it is wrapping some other crypto +// API, like a platform key store. +#define ECDSA_FLAG_OPAQUE 1 + +// ecdsa_method_st is a structure of function pointers for implementing ECDSA. +// See engine.h. +struct ecdsa_method_st { + struct openssl_method_common_st common; + + void *app_data; + + int (*init)(EC_KEY *key); + int (*finish)(EC_KEY *key); + + // group_order_size returns the number of bytes needed to represent the order + // of the group. This is used to calculate the maximum size of an ECDSA + // signature in |ECDSA_size|. + size_t (*group_order_size)(const EC_KEY *key); + + // sign matches the arguments and behaviour of |ECDSA_sign|. + int (*sign)(const uint8_t *digest, size_t digest_len, uint8_t *sig, + unsigned int *sig_len, EC_KEY *eckey); + + int flags; +}; + + +// Deprecated functions. + +// EC_KEY_set_asn1_flag does nothing. +OPENSSL_EXPORT void EC_KEY_set_asn1_flag(EC_KEY *key, int flag); + +// d2i_ECPrivateKey parses an ASN.1, DER-encoded, private key from |len| bytes +// at |*inp|. If |out_key| is not NULL then, on exit, a pointer to the result +// is in |*out_key|. Note that, even if |*out_key| is already non-NULL on entry, +// it * will not be written to. Rather, a fresh |EC_KEY| is allocated and the +// previous * one is freed. On successful exit, |*inp| is advanced past the DER +// structure. It returns the result or NULL on error. +// +// On input, if |*out_key| is non-NULL and has a group configured, the +// parameters field may be omitted but must match that group if present. +// +// Use |EC_KEY_parse_private_key| instead. +OPENSSL_EXPORT EC_KEY *d2i_ECPrivateKey(EC_KEY **out_key, const uint8_t **inp, + long len); + +// i2d_ECPrivateKey marshals an EC private key from |key| to an ASN.1, DER +// structure. If |outp| is not NULL then the result is written to |*outp| and +// |*outp| is advanced just past the output. It returns the number of bytes in +// the result, whether written or not, or a negative value on error. +// +// Use |EC_KEY_marshal_private_key| instead. +OPENSSL_EXPORT int i2d_ECPrivateKey(const EC_KEY *key, uint8_t **outp); + +// d2i_ECParameters parses an ASN.1, DER-encoded, set of EC parameters from +// |len| bytes at |*inp|. If |out_key| is not NULL then, on exit, a pointer to +// the result is in |*out_key|. Note that, even if |*out_key| is already +// non-NULL on entry, it will not be written to. Rather, a fresh |EC_KEY| is +// allocated and the previous one is freed. On successful exit, |*inp| is +// advanced past the DER structure. It returns the result or NULL on error. +// +// Use |EC_KEY_parse_parameters| or |EC_KEY_parse_curve_name| instead. +OPENSSL_EXPORT EC_KEY *d2i_ECParameters(EC_KEY **out_key, const uint8_t **inp, + long len); + +// i2d_ECParameters marshals EC parameters from |key| to an ASN.1, DER +// structure. If |outp| is not NULL then the result is written to |*outp| and +// |*outp| is advanced just past the output. It returns the number of bytes in +// the result, whether written or not, or a negative value on error. +// +// Use |EC_KEY_marshal_curve_name| instead. +OPENSSL_EXPORT int i2d_ECParameters(const EC_KEY *key, uint8_t **outp); + +// o2i_ECPublicKey parses an EC point from |len| bytes at |*inp| into +// |*out_key|. Note that this differs from the d2i format in that |*out_key| +// must be non-NULL with a group set. On successful exit, |*inp| is advanced by +// |len| bytes. It returns |*out_key| or NULL on error. +// +// Use |EC_POINT_oct2point| instead. +OPENSSL_EXPORT EC_KEY *o2i_ECPublicKey(EC_KEY **out_key, const uint8_t **inp, + long len); + +// i2o_ECPublicKey marshals an EC point from |key|. If |outp| is not NULL then +// the result is written to |*outp| and |*outp| is advanced just past the +// output. It returns the number of bytes in the result, whether written or +// not, or a negative value on error. +// +// Use |EC_POINT_point2cbb| instead. +OPENSSL_EXPORT int i2o_ECPublicKey(const EC_KEY *key, unsigned char **outp); + + +#if defined(__cplusplus) +} // extern C + +extern "C++" { + +namespace bssl { + +BORINGSSL_MAKE_DELETER(EC_KEY, EC_KEY_free) + +} // namespace bssl + +} // extern C++ + +#endif + +#endif // OPENSSL_HEADER_EC_KEY_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/ecdh.h b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/ecdh.h new file mode 100644 index 0000000..037296e --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/ecdh.h @@ -0,0 +1,101 @@ +/* ==================================================================== + * 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 OPENSSL_HEADER_ECDH_H +#define OPENSSL_HEADER_ECDH_H + +#include + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// Elliptic curve Diffie-Hellman. + + +// ECDH_compute_key calculates the shared key between |pub_key| and |priv_key|. +// If |kdf| is not NULL, then it is called with the bytes of the shared key and +// the parameter |out|. When |kdf| returns, the value of |*outlen| becomes the +// return value. Otherwise, as many bytes of the shared key as will fit are +// copied directly to, at most, |outlen| bytes at |out|. It returns the number +// of bytes written to |out|, or -1 on error. +OPENSSL_EXPORT int ECDH_compute_key( + void *out, size_t outlen, const EC_POINT *pub_key, const EC_KEY *priv_key, + void *(*kdf)(const void *in, size_t inlen, void *out, size_t *outlen)); + + +#if defined(__cplusplus) +} // extern C +#endif + +#define ECDH_R_KDF_FAILED 100 +#define ECDH_R_NO_PRIVATE_VALUE 101 +#define ECDH_R_POINT_ARITHMETIC_FAILURE 102 + +#endif // OPENSSL_HEADER_ECDH_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/ecdh.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/ecdh.h.grpc_back new file mode 100644 index 0000000..73e2140 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/ecdh.h.grpc_back @@ -0,0 +1,101 @@ +/* ==================================================================== + * 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 OPENSSL_HEADER_ECDH_H +#define OPENSSL_HEADER_ECDH_H + +#include + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// Elliptic curve Diffie-Hellman. + + +// ECDH_compute_key calculates the shared key between |pub_key| and |priv_key|. +// If |kdf| is not NULL, then it is called with the bytes of the shared key and +// the parameter |out|. When |kdf| returns, the value of |*outlen| becomes the +// return value. Otherwise, as many bytes of the shared key as will fit are +// copied directly to, at most, |outlen| bytes at |out|. It returns the number +// of bytes written to |out|, or -1 on error. +OPENSSL_EXPORT int ECDH_compute_key( + void *out, size_t outlen, const EC_POINT *pub_key, const EC_KEY *priv_key, + void *(*kdf)(const void *in, size_t inlen, void *out, size_t *outlen)); + + +#if defined(__cplusplus) +} // extern C +#endif + +#define ECDH_R_KDF_FAILED 100 +#define ECDH_R_NO_PRIVATE_VALUE 101 +#define ECDH_R_POINT_ARITHMETIC_FAILURE 102 + +#endif // OPENSSL_HEADER_ECDH_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/ecdsa.h b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/ecdsa.h new file mode 100644 index 0000000..eb5e6a6 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/ecdsa.h @@ -0,0 +1,199 @@ +/* ==================================================================== + * 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). */ + +#ifndef OPENSSL_HEADER_ECDSA_H +#define OPENSSL_HEADER_ECDSA_H + +#include + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// ECDSA contains functions for signing and verifying with the Digital Signature +// Algorithm over elliptic curves. + + +// Signing and verifying. + +// ECDSA_sign signs |digest_len| bytes from |digest| with |key| and writes the +// resulting signature to |sig|, which must have |ECDSA_size(key)| bytes of +// space. On successful exit, |*sig_len| is set to the actual number of bytes +// written. The |type| argument should be zero. It returns one on success and +// zero otherwise. +OPENSSL_EXPORT int ECDSA_sign(int type, const uint8_t *digest, + size_t digest_len, uint8_t *sig, + unsigned int *sig_len, const EC_KEY *key); + +// ECDSA_verify verifies that |sig_len| bytes from |sig| constitute a valid +// signature by |key| of |digest|. (The |type| argument should be zero.) It +// returns one on success or zero if the signature is invalid or an error +// occurred. +OPENSSL_EXPORT int ECDSA_verify(int type, const uint8_t *digest, + size_t digest_len, const uint8_t *sig, + size_t sig_len, const EC_KEY *key); + +// ECDSA_size returns the maximum size of an ECDSA signature using |key|. It +// returns zero on error. +OPENSSL_EXPORT size_t ECDSA_size(const EC_KEY *key); + + +// Low-level signing and verification. +// +// Low-level functions handle signatures as |ECDSA_SIG| structures which allow +// the two values in an ECDSA signature to be handled separately. + +struct ecdsa_sig_st { + BIGNUM *r; + BIGNUM *s; +}; + +// ECDSA_SIG_new returns a fresh |ECDSA_SIG| structure or NULL on error. +OPENSSL_EXPORT ECDSA_SIG *ECDSA_SIG_new(void); + +// ECDSA_SIG_free frees |sig| its member |BIGNUM|s. +OPENSSL_EXPORT void ECDSA_SIG_free(ECDSA_SIG *sig); + +// ECDSA_SIG_get0 sets |*out_r| and |*out_s|, if non-NULL, to the two +// components of |sig|. +OPENSSL_EXPORT void ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **out_r, + const BIGNUM **out_s); + +// ECDSA_SIG_set0 sets |sig|'s components to |r| and |s|, neither of which may +// be NULL. On success, it takes ownership of each argument and returns one. +// Otherwise, it returns zero. +OPENSSL_EXPORT int ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s); + +// ECDSA_do_sign signs |digest_len| bytes from |digest| with |key| and returns +// the resulting signature structure, or NULL on error. +OPENSSL_EXPORT ECDSA_SIG *ECDSA_do_sign(const uint8_t *digest, + size_t digest_len, const EC_KEY *key); + +// ECDSA_do_verify verifies that |sig| constitutes a valid signature by |key| +// of |digest|. It returns one on success or zero if the signature is invalid +// or on error. +OPENSSL_EXPORT int ECDSA_do_verify(const uint8_t *digest, size_t digest_len, + const ECDSA_SIG *sig, const EC_KEY *key); + + +// ASN.1 functions. + +// ECDSA_SIG_parse parses a DER-encoded ECDSA-Sig-Value structure from |cbs| and +// advances |cbs|. It returns a newly-allocated |ECDSA_SIG| or NULL on error. +OPENSSL_EXPORT ECDSA_SIG *ECDSA_SIG_parse(CBS *cbs); + +// ECDSA_SIG_from_bytes parses |in| as a DER-encoded ECDSA-Sig-Value structure. +// It returns a newly-allocated |ECDSA_SIG| structure or NULL on error. +OPENSSL_EXPORT ECDSA_SIG *ECDSA_SIG_from_bytes(const uint8_t *in, + size_t in_len); + +// ECDSA_SIG_marshal marshals |sig| as a DER-encoded ECDSA-Sig-Value and appends +// the result to |cbb|. It returns one on success and zero on error. +OPENSSL_EXPORT int ECDSA_SIG_marshal(CBB *cbb, const ECDSA_SIG *sig); + +// ECDSA_SIG_to_bytes marshals |sig| as a DER-encoded ECDSA-Sig-Value and, on +// success, sets |*out_bytes| to a newly allocated buffer containing the result +// and returns one. Otherwise, it returns zero. The result should be freed with +// |OPENSSL_free|. +OPENSSL_EXPORT int ECDSA_SIG_to_bytes(uint8_t **out_bytes, size_t *out_len, + const ECDSA_SIG *sig); + +// ECDSA_SIG_max_len returns the maximum length of a DER-encoded ECDSA-Sig-Value +// structure for a group whose order is represented in |order_len| bytes, or +// zero on overflow. +OPENSSL_EXPORT size_t ECDSA_SIG_max_len(size_t order_len); + + +// Deprecated functions. + +// d2i_ECDSA_SIG parses an ASN.1, DER-encoded, signature from |len| bytes at +// |*inp|. If |out| is not NULL then, on exit, a pointer to the result is in +// |*out|. Note that, even if |*out| is already non-NULL on entry, it will not +// be written to. Rather, a fresh |ECDSA_SIG| is allocated and the previous one +// is freed. On successful exit, |*inp| is advanced past the DER structure. It +// returns the result or NULL on error. +OPENSSL_EXPORT ECDSA_SIG *d2i_ECDSA_SIG(ECDSA_SIG **out, const uint8_t **inp, + long len); + +// i2d_ECDSA_SIG marshals a signature from |sig| to an ASN.1, DER +// structure. If |outp| is not NULL then the result is written to |*outp| and +// |*outp| is advanced just past the output. It returns the number of bytes in +// the result, whether written or not, or a negative value on error. +OPENSSL_EXPORT int i2d_ECDSA_SIG(const ECDSA_SIG *sig, uint8_t **outp); + + +#if defined(__cplusplus) +} // extern C + +extern "C++" { + +namespace bssl { + +BORINGSSL_MAKE_DELETER(ECDSA_SIG, ECDSA_SIG_free) + +} // namespace bssl + +} // extern C++ + +#endif + +#define ECDSA_R_BAD_SIGNATURE 100 +#define ECDSA_R_MISSING_PARAMETERS 101 +#define ECDSA_R_NEED_NEW_SETUP_VALUES 102 +#define ECDSA_R_NOT_IMPLEMENTED 103 +#define ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED 104 +#define ECDSA_R_ENCODE_ERROR 105 + +#endif // OPENSSL_HEADER_ECDSA_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/ecdsa.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/ecdsa.h.grpc_back new file mode 100644 index 0000000..42da1c6 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/ecdsa.h.grpc_back @@ -0,0 +1,199 @@ +/* ==================================================================== + * 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). */ + +#ifndef OPENSSL_HEADER_ECDSA_H +#define OPENSSL_HEADER_ECDSA_H + +#include + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// ECDSA contains functions for signing and verifying with the Digital Signature +// Algorithm over elliptic curves. + + +// Signing and verifying. + +// ECDSA_sign signs |digest_len| bytes from |digest| with |key| and writes the +// resulting signature to |sig|, which must have |ECDSA_size(key)| bytes of +// space. On successful exit, |*sig_len| is set to the actual number of bytes +// written. The |type| argument should be zero. It returns one on success and +// zero otherwise. +OPENSSL_EXPORT int ECDSA_sign(int type, const uint8_t *digest, + size_t digest_len, uint8_t *sig, + unsigned int *sig_len, const EC_KEY *key); + +// ECDSA_verify verifies that |sig_len| bytes from |sig| constitute a valid +// signature by |key| of |digest|. (The |type| argument should be zero.) It +// returns one on success or zero if the signature is invalid or an error +// occurred. +OPENSSL_EXPORT int ECDSA_verify(int type, const uint8_t *digest, + size_t digest_len, const uint8_t *sig, + size_t sig_len, const EC_KEY *key); + +// ECDSA_size returns the maximum size of an ECDSA signature using |key|. It +// returns zero on error. +OPENSSL_EXPORT size_t ECDSA_size(const EC_KEY *key); + + +// Low-level signing and verification. +// +// Low-level functions handle signatures as |ECDSA_SIG| structures which allow +// the two values in an ECDSA signature to be handled separately. + +struct ecdsa_sig_st { + BIGNUM *r; + BIGNUM *s; +}; + +// ECDSA_SIG_new returns a fresh |ECDSA_SIG| structure or NULL on error. +OPENSSL_EXPORT ECDSA_SIG *ECDSA_SIG_new(void); + +// ECDSA_SIG_free frees |sig| its member |BIGNUM|s. +OPENSSL_EXPORT void ECDSA_SIG_free(ECDSA_SIG *sig); + +// ECDSA_SIG_get0 sets |*out_r| and |*out_s|, if non-NULL, to the two +// components of |sig|. +OPENSSL_EXPORT void ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **out_r, + const BIGNUM **out_s); + +// ECDSA_SIG_set0 sets |sig|'s components to |r| and |s|, neither of which may +// be NULL. On success, it takes ownership of each argument and returns one. +// Otherwise, it returns zero. +OPENSSL_EXPORT int ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s); + +// ECDSA_do_sign signs |digest_len| bytes from |digest| with |key| and returns +// the resulting signature structure, or NULL on error. +OPENSSL_EXPORT ECDSA_SIG *ECDSA_do_sign(const uint8_t *digest, + size_t digest_len, const EC_KEY *key); + +// ECDSA_do_verify verifies that |sig| constitutes a valid signature by |key| +// of |digest|. It returns one on success or zero if the signature is invalid +// or on error. +OPENSSL_EXPORT int ECDSA_do_verify(const uint8_t *digest, size_t digest_len, + const ECDSA_SIG *sig, const EC_KEY *key); + + +// ASN.1 functions. + +// ECDSA_SIG_parse parses a DER-encoded ECDSA-Sig-Value structure from |cbs| and +// advances |cbs|. It returns a newly-allocated |ECDSA_SIG| or NULL on error. +OPENSSL_EXPORT ECDSA_SIG *ECDSA_SIG_parse(CBS *cbs); + +// ECDSA_SIG_from_bytes parses |in| as a DER-encoded ECDSA-Sig-Value structure. +// It returns a newly-allocated |ECDSA_SIG| structure or NULL on error. +OPENSSL_EXPORT ECDSA_SIG *ECDSA_SIG_from_bytes(const uint8_t *in, + size_t in_len); + +// ECDSA_SIG_marshal marshals |sig| as a DER-encoded ECDSA-Sig-Value and appends +// the result to |cbb|. It returns one on success and zero on error. +OPENSSL_EXPORT int ECDSA_SIG_marshal(CBB *cbb, const ECDSA_SIG *sig); + +// ECDSA_SIG_to_bytes marshals |sig| as a DER-encoded ECDSA-Sig-Value and, on +// success, sets |*out_bytes| to a newly allocated buffer containing the result +// and returns one. Otherwise, it returns zero. The result should be freed with +// |OPENSSL_free|. +OPENSSL_EXPORT int ECDSA_SIG_to_bytes(uint8_t **out_bytes, size_t *out_len, + const ECDSA_SIG *sig); + +// ECDSA_SIG_max_len returns the maximum length of a DER-encoded ECDSA-Sig-Value +// structure for a group whose order is represented in |order_len| bytes, or +// zero on overflow. +OPENSSL_EXPORT size_t ECDSA_SIG_max_len(size_t order_len); + + +// Deprecated functions. + +// d2i_ECDSA_SIG parses an ASN.1, DER-encoded, signature from |len| bytes at +// |*inp|. If |out| is not NULL then, on exit, a pointer to the result is in +// |*out|. Note that, even if |*out| is already non-NULL on entry, it will not +// be written to. Rather, a fresh |ECDSA_SIG| is allocated and the previous one +// is freed. On successful exit, |*inp| is advanced past the DER structure. It +// returns the result or NULL on error. +OPENSSL_EXPORT ECDSA_SIG *d2i_ECDSA_SIG(ECDSA_SIG **out, const uint8_t **inp, + long len); + +// i2d_ECDSA_SIG marshals a signature from |sig| to an ASN.1, DER +// structure. If |outp| is not NULL then the result is written to |*outp| and +// |*outp| is advanced just past the output. It returns the number of bytes in +// the result, whether written or not, or a negative value on error. +OPENSSL_EXPORT int i2d_ECDSA_SIG(const ECDSA_SIG *sig, uint8_t **outp); + + +#if defined(__cplusplus) +} // extern C + +extern "C++" { + +namespace bssl { + +BORINGSSL_MAKE_DELETER(ECDSA_SIG, ECDSA_SIG_free) + +} // namespace bssl + +} // extern C++ + +#endif + +#define ECDSA_R_BAD_SIGNATURE 100 +#define ECDSA_R_MISSING_PARAMETERS 101 +#define ECDSA_R_NEED_NEW_SETUP_VALUES 102 +#define ECDSA_R_NOT_IMPLEMENTED 103 +#define ECDSA_R_RANDOM_NUMBER_GENERATION_FAILED 104 +#define ECDSA_R_ENCODE_ERROR 105 + +#endif // OPENSSL_HEADER_ECDSA_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/engine.h b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/engine.h new file mode 100644 index 0000000..1db19a1 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/engine.h @@ -0,0 +1,109 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_ENGINE_H +#define OPENSSL_HEADER_ENGINE_H + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// Engines are collections of methods. Methods are tables of function pointers, +// defined for certain algorithms, that allow operations on those algorithms to +// be overridden via a callback. This can be used, for example, to implement an +// RSA* that forwards operations to a hardware module. +// +// Methods are reference counted but |ENGINE|s are not. When creating a method, +// you should zero the whole structure and fill in the function pointers that +// you wish before setting it on an |ENGINE|. Any functions pointers that +// are NULL indicate that the default behaviour should be used. + + +// Allocation and destruction. + +// ENGINE_new returns an empty ENGINE that uses the default method for all +// algorithms. +OPENSSL_EXPORT ENGINE *ENGINE_new(void); + +// ENGINE_free decrements the reference counts for all methods linked from +// |engine| and frees |engine| itself. +OPENSSL_EXPORT void ENGINE_free(ENGINE *engine); + + +// Method accessors. +// +// Method accessors take a method pointer and the size of the structure. The +// size allows for ABI compatibility in the case that the method structure is +// extended with extra elements at the end. Methods are always copied by the +// set functions. +// +// Set functions return one on success and zero on allocation failure. + +OPENSSL_EXPORT int ENGINE_set_RSA_method(ENGINE *engine, + const RSA_METHOD *method, + size_t method_size); +OPENSSL_EXPORT RSA_METHOD *ENGINE_get_RSA_method(const ENGINE *engine); + +OPENSSL_EXPORT int ENGINE_set_ECDSA_method(ENGINE *engine, + const ECDSA_METHOD *method, + size_t method_size); +OPENSSL_EXPORT ECDSA_METHOD *ENGINE_get_ECDSA_method(const ENGINE *engine); + + +// Generic method functions. +// +// These functions take a void* type but actually operate on all method +// structures. + +// METHOD_ref increments the reference count of |method|. This is a no-op for +// now because all methods are currently static. +void METHOD_ref(void *method); + +// METHOD_unref decrements the reference count of |method| and frees it if the +// reference count drops to zero. This is a no-op for now because all methods +// are currently static. +void METHOD_unref(void *method); + + +// Private functions. + +// openssl_method_common_st contains the common part of all method structures. +// This must be the first member of all method structures. +struct openssl_method_common_st { + int references; // dummy – not used. + char is_static; +}; + + +#if defined(__cplusplus) +} // extern C + +extern "C++" { + +namespace bssl { + +BORINGSSL_MAKE_DELETER(ENGINE, ENGINE_free) + +} // namespace bssl + +} // extern C++ + +#endif + +#define ENGINE_R_OPERATION_NOT_SUPPORTED 100 + +#endif // OPENSSL_HEADER_ENGINE_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/engine.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/engine.h.grpc_back new file mode 100644 index 0000000..595e53c --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/engine.h.grpc_back @@ -0,0 +1,109 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_ENGINE_H +#define OPENSSL_HEADER_ENGINE_H + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// Engines are collections of methods. Methods are tables of function pointers, +// defined for certain algorithms, that allow operations on those algorithms to +// be overridden via a callback. This can be used, for example, to implement an +// RSA* that forwards operations to a hardware module. +// +// Methods are reference counted but |ENGINE|s are not. When creating a method, +// you should zero the whole structure and fill in the function pointers that +// you wish before setting it on an |ENGINE|. Any functions pointers that +// are NULL indicate that the default behaviour should be used. + + +// Allocation and destruction. + +// ENGINE_new returns an empty ENGINE that uses the default method for all +// algorithms. +OPENSSL_EXPORT ENGINE *ENGINE_new(void); + +// ENGINE_free decrements the reference counts for all methods linked from +// |engine| and frees |engine| itself. +OPENSSL_EXPORT void ENGINE_free(ENGINE *engine); + + +// Method accessors. +// +// Method accessors take a method pointer and the size of the structure. The +// size allows for ABI compatibility in the case that the method structure is +// extended with extra elements at the end. Methods are always copied by the +// set functions. +// +// Set functions return one on success and zero on allocation failure. + +OPENSSL_EXPORT int ENGINE_set_RSA_method(ENGINE *engine, + const RSA_METHOD *method, + size_t method_size); +OPENSSL_EXPORT RSA_METHOD *ENGINE_get_RSA_method(const ENGINE *engine); + +OPENSSL_EXPORT int ENGINE_set_ECDSA_method(ENGINE *engine, + const ECDSA_METHOD *method, + size_t method_size); +OPENSSL_EXPORT ECDSA_METHOD *ENGINE_get_ECDSA_method(const ENGINE *engine); + + +// Generic method functions. +// +// These functions take a void* type but actually operate on all method +// structures. + +// METHOD_ref increments the reference count of |method|. This is a no-op for +// now because all methods are currently static. +void METHOD_ref(void *method); + +// METHOD_unref decrements the reference count of |method| and frees it if the +// reference count drops to zero. This is a no-op for now because all methods +// are currently static. +void METHOD_unref(void *method); + + +// Private functions. + +// openssl_method_common_st contains the common part of all method structures. +// This must be the first member of all method structures. +struct openssl_method_common_st { + int references; // dummy – not used. + char is_static; +}; + + +#if defined(__cplusplus) +} // extern C + +extern "C++" { + +namespace bssl { + +BORINGSSL_MAKE_DELETER(ENGINE, ENGINE_free) + +} // namespace bssl + +} // extern C++ + +#endif + +#define ENGINE_R_OPERATION_NOT_SUPPORTED 100 + +#endif // OPENSSL_HEADER_ENGINE_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/err.h b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/err.h new file mode 100644 index 0000000..2af5d0c --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/err.h @@ -0,0 +1,458 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 OPENSSL_HEADER_ERR_H +#define OPENSSL_HEADER_ERR_H + +#include + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// Error queue handling functions. +// +// Errors in OpenSSL are generally signaled by the return value of a function. +// When a function fails it may add an entry to a per-thread error queue, +// which is managed by the functions in this header. +// +// Each error contains: +// 1) The library (i.e. ec, pem, rsa) which created it. +// 2) The file and line number of the call that added the error. +// 3) A pointer to some error specific data, which may be NULL. +// +// The library identifier and reason code are packed in a uint32_t and there +// exist various functions for unpacking it. +// +// The typical behaviour is that an error will occur deep in a call queue and +// that code will push an error onto the error queue. As the error queue +// unwinds, other functions will push their own errors. Thus, the "least +// recent" error is the most specific and the other errors will provide a +// backtrace of sorts. + + +// Startup and shutdown. + +// ERR_load_BIO_strings does nothing. +// +// TODO(fork): remove. libjingle calls this. +OPENSSL_EXPORT void ERR_load_BIO_strings(void); + +// ERR_load_ERR_strings does nothing. +OPENSSL_EXPORT void ERR_load_ERR_strings(void); + +// ERR_load_crypto_strings does nothing. +OPENSSL_EXPORT void ERR_load_crypto_strings(void); + +// ERR_free_strings does nothing. +OPENSSL_EXPORT void ERR_free_strings(void); + + +// Reading and formatting errors. + +// ERR_GET_LIB returns the library code for the error. This is one of +// the |ERR_LIB_*| values. +#define ERR_GET_LIB(packed_error) ((int)(((packed_error) >> 24) & 0xff)) + +// ERR_GET_REASON returns the reason code for the error. This is one of +// library-specific |LIB_R_*| values where |LIB| is the library (see +// |ERR_GET_LIB|). Note that reason codes are specific to the library. +#define ERR_GET_REASON(packed_error) ((int)((packed_error) & 0xfff)) + +// ERR_get_error gets the packed error code for the least recent error and +// removes that error from the queue. If there are no errors in the queue then +// it returns zero. +OPENSSL_EXPORT uint32_t ERR_get_error(void); + +// ERR_get_error_line acts like |ERR_get_error|, except that the file and line +// number of the call that added the error are also returned. +OPENSSL_EXPORT uint32_t ERR_get_error_line(const char **file, int *line); + +// ERR_FLAG_STRING means that the |data| member is a NUL-terminated string that +// can be printed. This is always set if |data| is non-NULL. +#define ERR_FLAG_STRING 1 + +// ERR_get_error_line_data acts like |ERR_get_error_line|, but also returns the +// error-specific data pointer and flags. The flags are a bitwise-OR of +// |ERR_FLAG_*| values. The error-specific data is owned by the error queue +// and the pointer becomes invalid after the next call that affects the same +// thread's error queue. If |*flags| contains |ERR_FLAG_STRING| then |*data| is +// human-readable. +OPENSSL_EXPORT uint32_t ERR_get_error_line_data(const char **file, int *line, + const char **data, int *flags); + +// The "peek" functions act like the |ERR_get_error| functions, above, but they +// do not remove the error from the queue. +OPENSSL_EXPORT uint32_t ERR_peek_error(void); +OPENSSL_EXPORT uint32_t ERR_peek_error_line(const char **file, int *line); +OPENSSL_EXPORT uint32_t ERR_peek_error_line_data(const char **file, int *line, + const char **data, int *flags); + +// The "peek last" functions act like the "peek" functions, above, except that +// they return the most recent error. +OPENSSL_EXPORT uint32_t ERR_peek_last_error(void); +OPENSSL_EXPORT uint32_t ERR_peek_last_error_line(const char **file, int *line); +OPENSSL_EXPORT uint32_t ERR_peek_last_error_line_data(const char **file, + int *line, + const char **data, + int *flags); + +// ERR_error_string_n generates a human-readable string representing +// |packed_error| and places it at |buf|. It writes at most |len| bytes +// (including the terminating NUL) and truncates the string if necessary. If +// |len| is greater than zero then |buf| is always NUL terminated. +// +// The string will have the following format: +// +// error:[error code]:[library name]:OPENSSL_internal:[reason string] +// +// error code is an 8 digit hexadecimal number; library name and reason string +// are ASCII text. +OPENSSL_EXPORT void ERR_error_string_n(uint32_t packed_error, char *buf, + size_t len); + +// ERR_lib_error_string returns a string representation of the library that +// generated |packed_error|. +OPENSSL_EXPORT const char *ERR_lib_error_string(uint32_t packed_error); + +// ERR_reason_error_string returns a string representation of the reason for +// |packed_error|. +OPENSSL_EXPORT const char *ERR_reason_error_string(uint32_t packed_error); + +// ERR_print_errors_callback_t is the type of a function used by +// |ERR_print_errors_cb|. It takes a pointer to a human readable string (and +// its length) that describes an entry in the error queue. The |ctx| argument +// is an opaque pointer given to |ERR_print_errors_cb|. +// +// It should return one on success or zero on error, which will stop the +// iteration over the error queue. +typedef int (*ERR_print_errors_callback_t)(const char *str, size_t len, + void *ctx); + +// ERR_print_errors_cb clears the current thread's error queue, calling +// |callback| with a string representation of each error, from the least recent +// to the most recent error. +// +// The string will have the following format (which differs from +// |ERR_error_string|): +// +// [thread id]:error:[error code]:[library name]:OPENSSL_internal:[reason string]:[file]:[line number]:[optional string data] +// +// The callback can return one to continue the iteration or zero to stop it. +// The |ctx| argument is an opaque value that is passed through to the +// callback. +OPENSSL_EXPORT void ERR_print_errors_cb(ERR_print_errors_callback_t callback, + void *ctx); + +// ERR_print_errors_fp clears the current thread's error queue, printing each +// error to |file|. See |ERR_print_errors_cb| for the format. +OPENSSL_EXPORT void ERR_print_errors_fp(FILE *file); + + +// Clearing errors. + +// ERR_clear_error clears the error queue for the current thread. +OPENSSL_EXPORT void ERR_clear_error(void); + +// ERR_set_mark "marks" the most recent error for use with |ERR_pop_to_mark|. +// It returns one if an error was marked and zero if there are no errors. +OPENSSL_EXPORT int ERR_set_mark(void); + +// ERR_pop_to_mark removes errors from the most recent to the least recent +// until (and not including) a "marked" error. It returns zero if no marked +// error was found (and thus all errors were removed) and one otherwise. Errors +// are marked using |ERR_set_mark|. +OPENSSL_EXPORT int ERR_pop_to_mark(void); + + +// Custom errors. + +// ERR_get_next_error_library returns a value suitable for passing as the +// |library| argument to |ERR_put_error|. This is intended for code that wishes +// to push its own, non-standard errors to the error queue. +OPENSSL_EXPORT int ERR_get_next_error_library(void); + + +// Built-in library and reason codes. + +// The following values are built-in library codes. +enum { + ERR_LIB_NONE = 1, + ERR_LIB_SYS, + ERR_LIB_BN, + ERR_LIB_RSA, + ERR_LIB_DH, + ERR_LIB_EVP, + ERR_LIB_BUF, + ERR_LIB_OBJ, + ERR_LIB_PEM, + ERR_LIB_DSA, + ERR_LIB_X509, + ERR_LIB_ASN1, + ERR_LIB_CONF, + ERR_LIB_CRYPTO, + ERR_LIB_EC, + ERR_LIB_SSL, + ERR_LIB_BIO, + ERR_LIB_PKCS7, + ERR_LIB_PKCS8, + ERR_LIB_X509V3, + ERR_LIB_RAND, + ERR_LIB_ENGINE, + ERR_LIB_OCSP, + ERR_LIB_UI, + ERR_LIB_COMP, + ERR_LIB_ECDSA, + ERR_LIB_ECDH, + ERR_LIB_HMAC, + ERR_LIB_DIGEST, + ERR_LIB_CIPHER, + ERR_LIB_HKDF, + ERR_LIB_USER, + ERR_NUM_LIBS +}; + +// The following reason codes used to denote an error occuring in another +// library. They are sometimes used for a stack trace. +#define ERR_R_SYS_LIB ERR_LIB_SYS +#define ERR_R_BN_LIB ERR_LIB_BN +#define ERR_R_RSA_LIB ERR_LIB_RSA +#define ERR_R_DH_LIB ERR_LIB_DH +#define ERR_R_EVP_LIB ERR_LIB_EVP +#define ERR_R_BUF_LIB ERR_LIB_BUF +#define ERR_R_OBJ_LIB ERR_LIB_OBJ +#define ERR_R_PEM_LIB ERR_LIB_PEM +#define ERR_R_DSA_LIB ERR_LIB_DSA +#define ERR_R_X509_LIB ERR_LIB_X509 +#define ERR_R_ASN1_LIB ERR_LIB_ASN1 +#define ERR_R_CONF_LIB ERR_LIB_CONF +#define ERR_R_CRYPTO_LIB ERR_LIB_CRYPTO +#define ERR_R_EC_LIB ERR_LIB_EC +#define ERR_R_SSL_LIB ERR_LIB_SSL +#define ERR_R_BIO_LIB ERR_LIB_BIO +#define ERR_R_PKCS7_LIB ERR_LIB_PKCS7 +#define ERR_R_PKCS8_LIB ERR_LIB_PKCS8 +#define ERR_R_X509V3_LIB ERR_LIB_X509V3 +#define ERR_R_RAND_LIB ERR_LIB_RAND +#define ERR_R_DSO_LIB ERR_LIB_DSO +#define ERR_R_ENGINE_LIB ERR_LIB_ENGINE +#define ERR_R_OCSP_LIB ERR_LIB_OCSP +#define ERR_R_UI_LIB ERR_LIB_UI +#define ERR_R_COMP_LIB ERR_LIB_COMP +#define ERR_R_ECDSA_LIB ERR_LIB_ECDSA +#define ERR_R_ECDH_LIB ERR_LIB_ECDH +#define ERR_R_STORE_LIB ERR_LIB_STORE +#define ERR_R_FIPS_LIB ERR_LIB_FIPS +#define ERR_R_CMS_LIB ERR_LIB_CMS +#define ERR_R_TS_LIB ERR_LIB_TS +#define ERR_R_HMAC_LIB ERR_LIB_HMAC +#define ERR_R_JPAKE_LIB ERR_LIB_JPAKE +#define ERR_R_USER_LIB ERR_LIB_USER +#define ERR_R_DIGEST_LIB ERR_LIB_DIGEST +#define ERR_R_CIPHER_LIB ERR_LIB_CIPHER +#define ERR_R_HKDF_LIB ERR_LIB_HKDF + +// The following values are global reason codes. They may occur in any library. +#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_OVERFLOW (5 | ERR_R_FATAL) + + +// Deprecated functions. + +// ERR_remove_state calls |ERR_clear_error|. +OPENSSL_EXPORT void ERR_remove_state(unsigned long pid); + +// ERR_remove_thread_state clears the error queue for the current thread if +// |tid| is NULL. Otherwise it calls |assert(0)|, because it's no longer +// possible to delete the error queue for other threads. +// +// Use |ERR_clear_error| instead. Note error queues are deleted automatically on +// thread exit. You do not need to call this function to release memory. +OPENSSL_EXPORT void ERR_remove_thread_state(const CRYPTO_THREADID *tid); + +// ERR_func_error_string returns the string "OPENSSL_internal". +OPENSSL_EXPORT const char *ERR_func_error_string(uint32_t packed_error); + +// ERR_error_string behaves like |ERR_error_string_n| but |len| is implicitly +// |ERR_ERROR_STRING_BUF_LEN| and it returns |buf|. If |buf| is NULL, the error +// string is placed in a static buffer which is returned. (The static buffer may +// be overridden by concurrent calls in other threads so this form should not be +// used.) +// +// Use |ERR_error_string_n| instead. +// +// TODO(fork): remove this function. +OPENSSL_EXPORT char *ERR_error_string(uint32_t packed_error, char *buf); +#define ERR_ERROR_STRING_BUF_LEN 120 + +// ERR_GET_FUNC returns zero. BoringSSL errors do not report a function code. +#define ERR_GET_FUNC(packed_error) 0 + +// ERR_TXT_STRING is provided for compatibility with code that assumes that +// it's using OpenSSL. +#define ERR_TXT_STRING ERR_FLAG_STRING + + +// Private functions. + +// ERR_clear_system_error clears the system's error value (i.e. errno). +OPENSSL_EXPORT void ERR_clear_system_error(void); + +// OPENSSL_PUT_ERROR is used by OpenSSL code to add an error to the error +// queue. +#define OPENSSL_PUT_ERROR(library, reason) \ + ERR_put_error(ERR_LIB_##library, 0, reason, __FILE__, __LINE__) + +// OPENSSL_PUT_SYSTEM_ERROR is used by OpenSSL code to add an error from the +// operating system to the error queue. +// TODO(fork): include errno. +#define OPENSSL_PUT_SYSTEM_ERROR() \ + ERR_put_error(ERR_LIB_SYS, 0, 0, __FILE__, __LINE__); + +// ERR_put_error adds an error to the error queue, dropping the least recent +// error if necessary for space reasons. +OPENSSL_EXPORT void ERR_put_error(int library, int unused, int reason, + const char *file, unsigned line); + +// ERR_add_error_data takes a variable number (|count|) of const char* +// pointers, concatenates them and sets the result as the data on the most +// recent error. +OPENSSL_EXPORT void ERR_add_error_data(unsigned count, ...); + +// ERR_add_error_dataf takes a printf-style format and arguments, and sets the +// result as the data on the most recent error. +OPENSSL_EXPORT void ERR_add_error_dataf(const char *format, ...) + OPENSSL_PRINTF_FORMAT_FUNC(1, 2); + +// ERR_NUM_ERRORS is one more than the limit of the number of errors in the +// queue. +#define ERR_NUM_ERRORS 16 + +#define ERR_PACK(lib, reason) \ + (((((uint32_t)(lib)) & 0xff) << 24) | ((((uint32_t)(reason)) & 0xfff))) + +// OPENSSL_DECLARE_ERROR_REASON is used by util/make_errors.h (which generates +// the error defines) to recognise that an additional reason value is needed. +// This is needed when the reason value is used outside of an +// |OPENSSL_PUT_ERROR| macro. The resulting define will be +// ${lib}_R_${reason}. +#define OPENSSL_DECLARE_ERROR_REASON(lib, reason) + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_ERR_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/err.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/err.h.grpc_back new file mode 100644 index 0000000..a39c090 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/err.h.grpc_back @@ -0,0 +1,458 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 OPENSSL_HEADER_ERR_H +#define OPENSSL_HEADER_ERR_H + +#include + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// Error queue handling functions. +// +// Errors in OpenSSL are generally signaled by the return value of a function. +// When a function fails it may add an entry to a per-thread error queue, +// which is managed by the functions in this header. +// +// Each error contains: +// 1) The library (i.e. ec, pem, rsa) which created it. +// 2) The file and line number of the call that added the error. +// 3) A pointer to some error specific data, which may be NULL. +// +// The library identifier and reason code are packed in a uint32_t and there +// exist various functions for unpacking it. +// +// The typical behaviour is that an error will occur deep in a call queue and +// that code will push an error onto the error queue. As the error queue +// unwinds, other functions will push their own errors. Thus, the "least +// recent" error is the most specific and the other errors will provide a +// backtrace of sorts. + + +// Startup and shutdown. + +// ERR_load_BIO_strings does nothing. +// +// TODO(fork): remove. libjingle calls this. +OPENSSL_EXPORT void ERR_load_BIO_strings(void); + +// ERR_load_ERR_strings does nothing. +OPENSSL_EXPORT void ERR_load_ERR_strings(void); + +// ERR_load_crypto_strings does nothing. +OPENSSL_EXPORT void ERR_load_crypto_strings(void); + +// ERR_free_strings does nothing. +OPENSSL_EXPORT void ERR_free_strings(void); + + +// Reading and formatting errors. + +// ERR_GET_LIB returns the library code for the error. This is one of +// the |ERR_LIB_*| values. +#define ERR_GET_LIB(packed_error) ((int)(((packed_error) >> 24) & 0xff)) + +// ERR_GET_REASON returns the reason code for the error. This is one of +// library-specific |LIB_R_*| values where |LIB| is the library (see +// |ERR_GET_LIB|). Note that reason codes are specific to the library. +#define ERR_GET_REASON(packed_error) ((int)((packed_error) & 0xfff)) + +// ERR_get_error gets the packed error code for the least recent error and +// removes that error from the queue. If there are no errors in the queue then +// it returns zero. +OPENSSL_EXPORT uint32_t ERR_get_error(void); + +// ERR_get_error_line acts like |ERR_get_error|, except that the file and line +// number of the call that added the error are also returned. +OPENSSL_EXPORT uint32_t ERR_get_error_line(const char **file, int *line); + +// ERR_FLAG_STRING means that the |data| member is a NUL-terminated string that +// can be printed. This is always set if |data| is non-NULL. +#define ERR_FLAG_STRING 1 + +// ERR_get_error_line_data acts like |ERR_get_error_line|, but also returns the +// error-specific data pointer and flags. The flags are a bitwise-OR of +// |ERR_FLAG_*| values. The error-specific data is owned by the error queue +// and the pointer becomes invalid after the next call that affects the same +// thread's error queue. If |*flags| contains |ERR_FLAG_STRING| then |*data| is +// human-readable. +OPENSSL_EXPORT uint32_t ERR_get_error_line_data(const char **file, int *line, + const char **data, int *flags); + +// The "peek" functions act like the |ERR_get_error| functions, above, but they +// do not remove the error from the queue. +OPENSSL_EXPORT uint32_t ERR_peek_error(void); +OPENSSL_EXPORT uint32_t ERR_peek_error_line(const char **file, int *line); +OPENSSL_EXPORT uint32_t ERR_peek_error_line_data(const char **file, int *line, + const char **data, int *flags); + +// The "peek last" functions act like the "peek" functions, above, except that +// they return the most recent error. +OPENSSL_EXPORT uint32_t ERR_peek_last_error(void); +OPENSSL_EXPORT uint32_t ERR_peek_last_error_line(const char **file, int *line); +OPENSSL_EXPORT uint32_t ERR_peek_last_error_line_data(const char **file, + int *line, + const char **data, + int *flags); + +// ERR_error_string_n generates a human-readable string representing +// |packed_error| and places it at |buf|. It writes at most |len| bytes +// (including the terminating NUL) and truncates the string if necessary. If +// |len| is greater than zero then |buf| is always NUL terminated. +// +// The string will have the following format: +// +// error:[error code]:[library name]:OPENSSL_internal:[reason string] +// +// error code is an 8 digit hexadecimal number; library name and reason string +// are ASCII text. +OPENSSL_EXPORT void ERR_error_string_n(uint32_t packed_error, char *buf, + size_t len); + +// ERR_lib_error_string returns a string representation of the library that +// generated |packed_error|. +OPENSSL_EXPORT const char *ERR_lib_error_string(uint32_t packed_error); + +// ERR_reason_error_string returns a string representation of the reason for +// |packed_error|. +OPENSSL_EXPORT const char *ERR_reason_error_string(uint32_t packed_error); + +// ERR_print_errors_callback_t is the type of a function used by +// |ERR_print_errors_cb|. It takes a pointer to a human readable string (and +// its length) that describes an entry in the error queue. The |ctx| argument +// is an opaque pointer given to |ERR_print_errors_cb|. +// +// It should return one on success or zero on error, which will stop the +// iteration over the error queue. +typedef int (*ERR_print_errors_callback_t)(const char *str, size_t len, + void *ctx); + +// ERR_print_errors_cb clears the current thread's error queue, calling +// |callback| with a string representation of each error, from the least recent +// to the most recent error. +// +// The string will have the following format (which differs from +// |ERR_error_string|): +// +// [thread id]:error:[error code]:[library name]:OPENSSL_internal:[reason string]:[file]:[line number]:[optional string data] +// +// The callback can return one to continue the iteration or zero to stop it. +// The |ctx| argument is an opaque value that is passed through to the +// callback. +OPENSSL_EXPORT void ERR_print_errors_cb(ERR_print_errors_callback_t callback, + void *ctx); + +// ERR_print_errors_fp clears the current thread's error queue, printing each +// error to |file|. See |ERR_print_errors_cb| for the format. +OPENSSL_EXPORT void ERR_print_errors_fp(FILE *file); + + +// Clearing errors. + +// ERR_clear_error clears the error queue for the current thread. +OPENSSL_EXPORT void ERR_clear_error(void); + +// ERR_set_mark "marks" the most recent error for use with |ERR_pop_to_mark|. +// It returns one if an error was marked and zero if there are no errors. +OPENSSL_EXPORT int ERR_set_mark(void); + +// ERR_pop_to_mark removes errors from the most recent to the least recent +// until (and not including) a "marked" error. It returns zero if no marked +// error was found (and thus all errors were removed) and one otherwise. Errors +// are marked using |ERR_set_mark|. +OPENSSL_EXPORT int ERR_pop_to_mark(void); + + +// Custom errors. + +// ERR_get_next_error_library returns a value suitable for passing as the +// |library| argument to |ERR_put_error|. This is intended for code that wishes +// to push its own, non-standard errors to the error queue. +OPENSSL_EXPORT int ERR_get_next_error_library(void); + + +// Built-in library and reason codes. + +// The following values are built-in library codes. +enum { + ERR_LIB_NONE = 1, + ERR_LIB_SYS, + ERR_LIB_BN, + ERR_LIB_RSA, + ERR_LIB_DH, + ERR_LIB_EVP, + ERR_LIB_BUF, + ERR_LIB_OBJ, + ERR_LIB_PEM, + ERR_LIB_DSA, + ERR_LIB_X509, + ERR_LIB_ASN1, + ERR_LIB_CONF, + ERR_LIB_CRYPTO, + ERR_LIB_EC, + ERR_LIB_SSL, + ERR_LIB_BIO, + ERR_LIB_PKCS7, + ERR_LIB_PKCS8, + ERR_LIB_X509V3, + ERR_LIB_RAND, + ERR_LIB_ENGINE, + ERR_LIB_OCSP, + ERR_LIB_UI, + ERR_LIB_COMP, + ERR_LIB_ECDSA, + ERR_LIB_ECDH, + ERR_LIB_HMAC, + ERR_LIB_DIGEST, + ERR_LIB_CIPHER, + ERR_LIB_HKDF, + ERR_LIB_USER, + ERR_NUM_LIBS +}; + +// The following reason codes used to denote an error occuring in another +// library. They are sometimes used for a stack trace. +#define ERR_R_SYS_LIB ERR_LIB_SYS +#define ERR_R_BN_LIB ERR_LIB_BN +#define ERR_R_RSA_LIB ERR_LIB_RSA +#define ERR_R_DH_LIB ERR_LIB_DH +#define ERR_R_EVP_LIB ERR_LIB_EVP +#define ERR_R_BUF_LIB ERR_LIB_BUF +#define ERR_R_OBJ_LIB ERR_LIB_OBJ +#define ERR_R_PEM_LIB ERR_LIB_PEM +#define ERR_R_DSA_LIB ERR_LIB_DSA +#define ERR_R_X509_LIB ERR_LIB_X509 +#define ERR_R_ASN1_LIB ERR_LIB_ASN1 +#define ERR_R_CONF_LIB ERR_LIB_CONF +#define ERR_R_CRYPTO_LIB ERR_LIB_CRYPTO +#define ERR_R_EC_LIB ERR_LIB_EC +#define ERR_R_SSL_LIB ERR_LIB_SSL +#define ERR_R_BIO_LIB ERR_LIB_BIO +#define ERR_R_PKCS7_LIB ERR_LIB_PKCS7 +#define ERR_R_PKCS8_LIB ERR_LIB_PKCS8 +#define ERR_R_X509V3_LIB ERR_LIB_X509V3 +#define ERR_R_RAND_LIB ERR_LIB_RAND +#define ERR_R_DSO_LIB ERR_LIB_DSO +#define ERR_R_ENGINE_LIB ERR_LIB_ENGINE +#define ERR_R_OCSP_LIB ERR_LIB_OCSP +#define ERR_R_UI_LIB ERR_LIB_UI +#define ERR_R_COMP_LIB ERR_LIB_COMP +#define ERR_R_ECDSA_LIB ERR_LIB_ECDSA +#define ERR_R_ECDH_LIB ERR_LIB_ECDH +#define ERR_R_STORE_LIB ERR_LIB_STORE +#define ERR_R_FIPS_LIB ERR_LIB_FIPS +#define ERR_R_CMS_LIB ERR_LIB_CMS +#define ERR_R_TS_LIB ERR_LIB_TS +#define ERR_R_HMAC_LIB ERR_LIB_HMAC +#define ERR_R_JPAKE_LIB ERR_LIB_JPAKE +#define ERR_R_USER_LIB ERR_LIB_USER +#define ERR_R_DIGEST_LIB ERR_LIB_DIGEST +#define ERR_R_CIPHER_LIB ERR_LIB_CIPHER +#define ERR_R_HKDF_LIB ERR_LIB_HKDF + +// The following values are global reason codes. They may occur in any library. +#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_OVERFLOW (5 | ERR_R_FATAL) + + +// Deprecated functions. + +// ERR_remove_state calls |ERR_clear_error|. +OPENSSL_EXPORT void ERR_remove_state(unsigned long pid); + +// ERR_remove_thread_state clears the error queue for the current thread if +// |tid| is NULL. Otherwise it calls |assert(0)|, because it's no longer +// possible to delete the error queue for other threads. +// +// Use |ERR_clear_error| instead. Note error queues are deleted automatically on +// thread exit. You do not need to call this function to release memory. +OPENSSL_EXPORT void ERR_remove_thread_state(const CRYPTO_THREADID *tid); + +// ERR_func_error_string returns the string "OPENSSL_internal". +OPENSSL_EXPORT const char *ERR_func_error_string(uint32_t packed_error); + +// ERR_error_string behaves like |ERR_error_string_n| but |len| is implicitly +// |ERR_ERROR_STRING_BUF_LEN| and it returns |buf|. If |buf| is NULL, the error +// string is placed in a static buffer which is returned. (The static buffer may +// be overridden by concurrent calls in other threads so this form should not be +// used.) +// +// Use |ERR_error_string_n| instead. +// +// TODO(fork): remove this function. +OPENSSL_EXPORT char *ERR_error_string(uint32_t packed_error, char *buf); +#define ERR_ERROR_STRING_BUF_LEN 120 + +// ERR_GET_FUNC returns zero. BoringSSL errors do not report a function code. +#define ERR_GET_FUNC(packed_error) 0 + +// ERR_TXT_STRING is provided for compatibility with code that assumes that +// it's using OpenSSL. +#define ERR_TXT_STRING ERR_FLAG_STRING + + +// Private functions. + +// ERR_clear_system_error clears the system's error value (i.e. errno). +OPENSSL_EXPORT void ERR_clear_system_error(void); + +// OPENSSL_PUT_ERROR is used by OpenSSL code to add an error to the error +// queue. +#define OPENSSL_PUT_ERROR(library, reason) \ + ERR_put_error(ERR_LIB_##library, 0, reason, __FILE__, __LINE__) + +// OPENSSL_PUT_SYSTEM_ERROR is used by OpenSSL code to add an error from the +// operating system to the error queue. +// TODO(fork): include errno. +#define OPENSSL_PUT_SYSTEM_ERROR() \ + ERR_put_error(ERR_LIB_SYS, 0, 0, __FILE__, __LINE__); + +// ERR_put_error adds an error to the error queue, dropping the least recent +// error if necessary for space reasons. +OPENSSL_EXPORT void ERR_put_error(int library, int unused, int reason, + const char *file, unsigned line); + +// ERR_add_error_data takes a variable number (|count|) of const char* +// pointers, concatenates them and sets the result as the data on the most +// recent error. +OPENSSL_EXPORT void ERR_add_error_data(unsigned count, ...); + +// ERR_add_error_dataf takes a printf-style format and arguments, and sets the +// result as the data on the most recent error. +OPENSSL_EXPORT void ERR_add_error_dataf(const char *format, ...) + OPENSSL_PRINTF_FORMAT_FUNC(1, 2); + +// ERR_NUM_ERRORS is one more than the limit of the number of errors in the +// queue. +#define ERR_NUM_ERRORS 16 + +#define ERR_PACK(lib, reason) \ + (((((uint32_t)(lib)) & 0xff) << 24) | ((((uint32_t)(reason)) & 0xfff))) + +// OPENSSL_DECLARE_ERROR_REASON is used by util/make_errors.h (which generates +// the error defines) to recognise that an additional reason value is needed. +// This is needed when the reason value is used outside of an +// |OPENSSL_PUT_ERROR| macro. The resulting define will be +// ${lib}_R_${reason}. +#define OPENSSL_DECLARE_ERROR_REASON(lib, reason) + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_ERR_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/evp.h b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/evp.h new file mode 100644 index 0000000..7d0dcae --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/evp.h @@ -0,0 +1,873 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 OPENSSL_HEADER_EVP_H +#define OPENSSL_HEADER_EVP_H + +#include + +#include + +// OpenSSL included digest and cipher functions in this header so we include +// them for users that still expect that. +// +// TODO(fork): clean up callers so that they include what they use. +#include +#include +#include +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// EVP abstracts over public/private key algorithms. + + +// Public key objects. + +// EVP_PKEY_new creates a new, empty public-key object and returns it or NULL +// on allocation failure. +OPENSSL_EXPORT EVP_PKEY *EVP_PKEY_new(void); + +// EVP_PKEY_free frees all data referenced by |pkey| and then frees |pkey| +// itself. +OPENSSL_EXPORT void EVP_PKEY_free(EVP_PKEY *pkey); + +// EVP_PKEY_up_ref increments the reference count of |pkey| and returns one. +OPENSSL_EXPORT int EVP_PKEY_up_ref(EVP_PKEY *pkey); + +// EVP_PKEY_is_opaque returns one if |pkey| is opaque. Opaque keys are backed by +// custom implementations which do not expose key material and parameters. It is +// an error to attempt to duplicate, export, or compare an opaque key. +OPENSSL_EXPORT int EVP_PKEY_is_opaque(const EVP_PKEY *pkey); + +// EVP_PKEY_cmp compares |a| and |b| and returns one if they are equal, zero if +// not and a negative number on error. +// +// WARNING: this differs from the traditional return value of a "cmp" +// function. +OPENSSL_EXPORT int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b); + +// EVP_PKEY_copy_parameters sets the parameters of |to| to equal the parameters +// of |from|. It returns one on success and zero on error. +OPENSSL_EXPORT int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from); + +// EVP_PKEY_missing_parameters returns one if |pkey| is missing needed +// parameters or zero if not, or if the algorithm doesn't take parameters. +OPENSSL_EXPORT int EVP_PKEY_missing_parameters(const EVP_PKEY *pkey); + +// EVP_PKEY_size returns the maximum size, in bytes, of a signature signed by +// |pkey|. For an RSA key, this returns the number of bytes needed to represent +// the modulus. For an EC key, this returns the maximum size of a DER-encoded +// ECDSA signature. +OPENSSL_EXPORT int EVP_PKEY_size(const EVP_PKEY *pkey); + +// EVP_PKEY_bits returns the "size", in bits, of |pkey|. For an RSA key, this +// returns the bit length of the modulus. For an EC key, this returns the bit +// length of the group order. +OPENSSL_EXPORT int EVP_PKEY_bits(EVP_PKEY *pkey); + +// EVP_PKEY_id returns the type of |pkey|, which is one of the |EVP_PKEY_*| +// values. +OPENSSL_EXPORT int EVP_PKEY_id(const EVP_PKEY *pkey); + +// EVP_PKEY_type returns |nid| if |nid| is a known key type and |NID_undef| +// otherwise. +OPENSSL_EXPORT int EVP_PKEY_type(int nid); + + +// Getting and setting concrete public key types. +// +// The following functions get and set the underlying public key in an +// |EVP_PKEY| object. The |set1| functions take an additional reference to the +// underlying key and return one on success or zero on error. The |assign| +// functions adopt the caller's reference. The |get1| functions return a fresh +// reference to the underlying object or NULL if |pkey| is not of the correct +// type. The |get0| functions behave the same but return a non-owning +// pointer. + +OPENSSL_EXPORT int EVP_PKEY_set1_RSA(EVP_PKEY *pkey, RSA *key); +OPENSSL_EXPORT int EVP_PKEY_assign_RSA(EVP_PKEY *pkey, RSA *key); +OPENSSL_EXPORT RSA *EVP_PKEY_get0_RSA(EVP_PKEY *pkey); +OPENSSL_EXPORT RSA *EVP_PKEY_get1_RSA(EVP_PKEY *pkey); + +OPENSSL_EXPORT int EVP_PKEY_set1_DSA(EVP_PKEY *pkey, DSA *key); +OPENSSL_EXPORT int EVP_PKEY_assign_DSA(EVP_PKEY *pkey, DSA *key); +OPENSSL_EXPORT DSA *EVP_PKEY_get0_DSA(EVP_PKEY *pkey); +OPENSSL_EXPORT DSA *EVP_PKEY_get1_DSA(EVP_PKEY *pkey); + +OPENSSL_EXPORT int EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey, EC_KEY *key); +OPENSSL_EXPORT int EVP_PKEY_assign_EC_KEY(EVP_PKEY *pkey, EC_KEY *key); +OPENSSL_EXPORT EC_KEY *EVP_PKEY_get0_EC_KEY(EVP_PKEY *pkey); +OPENSSL_EXPORT EC_KEY *EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey); + +// EVP_PKEY_new_ed25519_public returns a newly allocated |EVP_PKEY| wrapping an +// Ed25519 public key, or NULL on allocation error. +OPENSSL_EXPORT EVP_PKEY *EVP_PKEY_new_ed25519_public( + const uint8_t public_key[32]); + +// EVP_PKEY_new_ed25519_private returns a newly allocated |EVP_PKEY| wrapping an +// Ed25519 private key, or NULL on allocation error. +OPENSSL_EXPORT EVP_PKEY *EVP_PKEY_new_ed25519_private( + const uint8_t private_key[64]); + +#define EVP_PKEY_NONE NID_undef +#define EVP_PKEY_RSA NID_rsaEncryption +#define EVP_PKEY_DSA NID_dsa +#define EVP_PKEY_EC NID_X9_62_id_ecPublicKey +#define EVP_PKEY_ED25519 NID_ED25519 + +// EVP_PKEY_assign sets the underlying key of |pkey| to |key|, which must be of +// the given type. The |type| argument should be one of the |EVP_PKEY_*| +// values. +OPENSSL_EXPORT int EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key); + +// EVP_PKEY_set_type sets the type of |pkey| to |type|, which should be one of +// the |EVP_PKEY_*| values. It returns one if successful or zero otherwise. If +// |pkey| is NULL, it simply reports whether the type is known. +OPENSSL_EXPORT int EVP_PKEY_set_type(EVP_PKEY *pkey, int type); + +// EVP_PKEY_cmp_parameters compares the parameters of |a| and |b|. It returns +// one if they match, zero if not, or a negative number of on error. +// +// WARNING: the return value differs from the usual return value convention. +OPENSSL_EXPORT int EVP_PKEY_cmp_parameters(const EVP_PKEY *a, + const EVP_PKEY *b); + + +// ASN.1 functions + +// EVP_parse_public_key decodes a DER-encoded SubjectPublicKeyInfo structure +// (RFC 5280) from |cbs| and advances |cbs|. It returns a newly-allocated +// |EVP_PKEY| or NULL on error. +// +// The caller must check the type of the parsed public key to ensure it is +// suitable and validate other desired key properties such as RSA modulus size +// or EC curve. +OPENSSL_EXPORT EVP_PKEY *EVP_parse_public_key(CBS *cbs); + +// EVP_marshal_public_key marshals |key| as a DER-encoded SubjectPublicKeyInfo +// structure (RFC 5280) and appends the result to |cbb|. It returns one on +// success and zero on error. +OPENSSL_EXPORT int EVP_marshal_public_key(CBB *cbb, const EVP_PKEY *key); + +// EVP_parse_private_key decodes a DER-encoded PrivateKeyInfo structure (RFC +// 5208) from |cbs| and advances |cbs|. It returns a newly-allocated |EVP_PKEY| +// or NULL on error. +// +// The caller must check the type of the parsed private key to ensure it is +// suitable and validate other desired key properties such as RSA modulus size +// or EC curve. +// +// A PrivateKeyInfo ends with an optional set of attributes. These are not +// processed and so this function will silently ignore any trailing data in the +// structure. +OPENSSL_EXPORT EVP_PKEY *EVP_parse_private_key(CBS *cbs); + +// EVP_marshal_private_key marshals |key| as a DER-encoded PrivateKeyInfo +// structure (RFC 5208) and appends the result to |cbb|. It returns one on +// success and zero on error. +OPENSSL_EXPORT int EVP_marshal_private_key(CBB *cbb, const EVP_PKEY *key); + + +// Signing + +// EVP_DigestSignInit sets up |ctx| for a signing operation with |type| and +// |pkey|. The |ctx| argument must have been initialised with +// |EVP_MD_CTX_init|. If |pctx| is not NULL, the |EVP_PKEY_CTX| of the signing +// operation will be written to |*pctx|; this can be used to set alternative +// signing options. +// +// For single-shot signing algorithms which do not use a pre-hash, such as +// Ed25519, |type| should be NULL. The |EVP_MD_CTX| itself is unused but is +// present so the API is uniform. See |EVP_DigestSign|. +// +// It returns one on success, or zero on error. +OPENSSL_EXPORT int EVP_DigestSignInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, + const EVP_MD *type, ENGINE *e, + EVP_PKEY *pkey); + +// EVP_DigestSignUpdate appends |len| bytes from |data| to the data which will +// be signed in |EVP_DigestSignFinal|. It returns one. +// +// This function performs a streaming signing operation and will fail for +// signature algorithms which do not support this. Use |EVP_DigestSign| for a +// single-shot operation. +OPENSSL_EXPORT int EVP_DigestSignUpdate(EVP_MD_CTX *ctx, const void *data, + size_t len); + +// EVP_DigestSignFinal signs the data that has been included by one or more +// calls to |EVP_DigestSignUpdate|. If |out_sig| is NULL then |*out_sig_len| is +// set to the maximum number of output bytes. Otherwise, on entry, +// |*out_sig_len| must contain the length of the |out_sig| buffer. If the call +// is successful, the signature is written to |out_sig| and |*out_sig_len| is +// set to its length. +// +// This function performs a streaming signing operation and will fail for +// signature algorithms which do not support this. Use |EVP_DigestSign| for a +// single-shot operation. +// +// It returns one on success, or zero on error. +OPENSSL_EXPORT int EVP_DigestSignFinal(EVP_MD_CTX *ctx, uint8_t *out_sig, + size_t *out_sig_len); + +// EVP_DigestSign signs |data_len| bytes from |data| using |ctx|. If |out_sig| +// is NULL then |*out_sig_len| is set to the maximum number of output +// bytes. Otherwise, on entry, |*out_sig_len| must contain the length of the +// |out_sig| buffer. If the call is successful, the signature is written to +// |out_sig| and |*out_sig_len| is set to its length. +// +// It returns one on success and zero on error. +OPENSSL_EXPORT int EVP_DigestSign(EVP_MD_CTX *ctx, uint8_t *out_sig, + size_t *out_sig_len, const uint8_t *data, + size_t data_len); + + +// Verifying + +// EVP_DigestVerifyInit sets up |ctx| for a signature verification operation +// with |type| and |pkey|. The |ctx| argument must have been initialised with +// |EVP_MD_CTX_init|. If |pctx| is not NULL, the |EVP_PKEY_CTX| of the signing +// operation will be written to |*pctx|; this can be used to set alternative +// signing options. +// +// For single-shot signing algorithms which do not use a pre-hash, such as +// Ed25519, |type| should be NULL. The |EVP_MD_CTX| itself is unused but is +// present so the API is uniform. See |EVP_DigestVerify|. +// +// It returns one on success, or zero on error. +OPENSSL_EXPORT int EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, + const EVP_MD *type, ENGINE *e, + EVP_PKEY *pkey); + +// EVP_DigestVerifyUpdate appends |len| bytes from |data| to the data which +// will be verified by |EVP_DigestVerifyFinal|. It returns one. +// +// This function performs streaming signature verification and will fail for +// signature algorithms which do not support this. Use |EVP_PKEY_verify_message| +// for a single-shot verification. +OPENSSL_EXPORT int EVP_DigestVerifyUpdate(EVP_MD_CTX *ctx, const void *data, + size_t len); + +// EVP_DigestVerifyFinal verifies that |sig_len| bytes of |sig| are a valid +// signature for the data that has been included by one or more calls to +// |EVP_DigestVerifyUpdate|. It returns one on success and zero otherwise. +// +// This function performs streaming signature verification and will fail for +// signature algorithms which do not support this. Use |EVP_PKEY_verify_message| +// for a single-shot verification. +OPENSSL_EXPORT int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const uint8_t *sig, + size_t sig_len); + +// EVP_DigestVerify verifies that |sig_len| bytes from |sig| are a valid +// signature for |data|. It returns one on success or zero on error. +OPENSSL_EXPORT int EVP_DigestVerify(EVP_MD_CTX *ctx, const uint8_t *sig, + size_t sig_len, const uint8_t *data, + size_t len); + + +// Signing (old functions) + +// EVP_SignInit_ex configures |ctx|, which must already have been initialised, +// for a fresh signing operation using the hash function |type|. It returns one +// on success and zero otherwise. +// +// (In order to initialise |ctx|, either obtain it initialised with +// |EVP_MD_CTX_create|, or use |EVP_MD_CTX_init|.) +OPENSSL_EXPORT int EVP_SignInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, + ENGINE *impl); + +// EVP_SignInit is a deprecated version of |EVP_SignInit_ex|. +// +// TODO(fork): remove. +OPENSSL_EXPORT int EVP_SignInit(EVP_MD_CTX *ctx, const EVP_MD *type); + +// EVP_SignUpdate appends |len| bytes from |data| to the data which will be +// signed in |EVP_SignFinal|. +OPENSSL_EXPORT int EVP_SignUpdate(EVP_MD_CTX *ctx, const void *data, + size_t len); + +// EVP_SignFinal signs the data that has been included by one or more calls to +// |EVP_SignUpdate|, using the key |pkey|, and writes it to |sig|. On entry, +// |sig| must point to at least |EVP_PKEY_size(pkey)| bytes of space. The +// actual size of the signature is written to |*out_sig_len|. +// +// It returns one on success and zero otherwise. +// +// It does not modify |ctx|, thus it's possible to continue to use |ctx| in +// order to sign a longer message. +OPENSSL_EXPORT int EVP_SignFinal(const EVP_MD_CTX *ctx, uint8_t *sig, + unsigned int *out_sig_len, EVP_PKEY *pkey); + + +// Verifying (old functions) + +// EVP_VerifyInit_ex configures |ctx|, which must already have been +// initialised, for a fresh signature verification operation using the hash +// function |type|. It returns one on success and zero otherwise. +// +// (In order to initialise |ctx|, either obtain it initialised with +// |EVP_MD_CTX_create|, or use |EVP_MD_CTX_init|.) +OPENSSL_EXPORT int EVP_VerifyInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, + ENGINE *impl); + +// EVP_VerifyInit is a deprecated version of |EVP_VerifyInit_ex|. +// +// TODO(fork): remove. +OPENSSL_EXPORT int EVP_VerifyInit(EVP_MD_CTX *ctx, const EVP_MD *type); + +// EVP_VerifyUpdate appends |len| bytes from |data| to the data which will be +// signed in |EVP_VerifyFinal|. +OPENSSL_EXPORT int EVP_VerifyUpdate(EVP_MD_CTX *ctx, const void *data, + size_t len); + +// EVP_VerifyFinal verifies that |sig_len| bytes of |sig| are a valid +// signature, by |pkey|, for the data that has been included by one or more +// calls to |EVP_VerifyUpdate|. +// +// It returns one on success and zero otherwise. +// +// It does not modify |ctx|, thus it's possible to continue to use |ctx| in +// order to sign a longer message. +OPENSSL_EXPORT int EVP_VerifyFinal(EVP_MD_CTX *ctx, const uint8_t *sig, + size_t sig_len, EVP_PKEY *pkey); + + +// Printing + +// EVP_PKEY_print_public prints a textual representation of the public key in +// |pkey| to |out|. Returns one on success or zero otherwise. +OPENSSL_EXPORT int EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey, + int indent, ASN1_PCTX *pctx); + +// EVP_PKEY_print_private prints a textual representation of the private key in +// |pkey| to |out|. Returns one on success or zero otherwise. +OPENSSL_EXPORT int EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey, + int indent, ASN1_PCTX *pctx); + +// EVP_PKEY_print_params prints a textual representation of the parameters in +// |pkey| to |out|. Returns one on success or zero otherwise. +OPENSSL_EXPORT int EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey, + int indent, ASN1_PCTX *pctx); + + +// Password stretching. +// +// Password stretching functions take a low-entropy password and apply a slow +// function that results in a key suitable for use in symmetric +// cryptography. + +// PKCS5_PBKDF2_HMAC computes |iterations| iterations of PBKDF2 of |password| +// and |salt|, using |digest|, and outputs |key_len| bytes to |out_key|. It +// returns one on success and zero on error. +OPENSSL_EXPORT int PKCS5_PBKDF2_HMAC(const char *password, size_t password_len, + const uint8_t *salt, size_t salt_len, + unsigned iterations, const EVP_MD *digest, + size_t key_len, uint8_t *out_key); + +// PKCS5_PBKDF2_HMAC_SHA1 is the same as PKCS5_PBKDF2_HMAC, but with |digest| +// fixed to |EVP_sha1|. +OPENSSL_EXPORT int PKCS5_PBKDF2_HMAC_SHA1(const char *password, + size_t password_len, + const uint8_t *salt, size_t salt_len, + unsigned iterations, size_t key_len, + uint8_t *out_key); + +// EVP_PBE_scrypt expands |password| into a secret key of length |key_len| using +// scrypt, as described in RFC 7914, and writes the result to |out_key|. It +// returns one on success and zero on error. +// +// |N|, |r|, and |p| are as described in RFC 7914 section 6. They determine the +// cost of the operation. If the memory required exceeds |max_mem|, the +// operation will fail instead. If |max_mem| is zero, a defult limit of 32MiB +// will be used. +OPENSSL_EXPORT int EVP_PBE_scrypt(const char *password, size_t password_len, + const uint8_t *salt, size_t salt_len, + uint64_t N, uint64_t r, uint64_t p, + size_t max_mem, uint8_t *out_key, + size_t key_len); + + +// Public key contexts. +// +// |EVP_PKEY_CTX| objects hold the context of an operation (e.g. signing or +// encrypting) that uses a public key. + +// EVP_PKEY_CTX_new allocates a fresh |EVP_PKEY_CTX| for use with |pkey|. It +// returns the context or NULL on error. +OPENSSL_EXPORT EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e); + +// EVP_PKEY_CTX_new_id allocates a fresh |EVP_PKEY_CTX| for a key of type |id| +// (e.g. |EVP_PKEY_HMAC|). This can be used for key generation where +// |EVP_PKEY_CTX_new| can't be used because there isn't an |EVP_PKEY| to pass +// it. It returns the context or NULL on error. +OPENSSL_EXPORT EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int id, ENGINE *e); + +// EVP_PKEY_CTX_free frees |ctx| and the data it owns. +OPENSSL_EXPORT void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx); + +// EVP_PKEY_CTX_dup allocates a fresh |EVP_PKEY_CTX| and sets it equal to the +// state of |ctx|. It returns the fresh |EVP_PKEY_CTX| or NULL on error. +OPENSSL_EXPORT EVP_PKEY_CTX *EVP_PKEY_CTX_dup(EVP_PKEY_CTX *ctx); + +// EVP_PKEY_CTX_get0_pkey returns the |EVP_PKEY| associated with |ctx|. +OPENSSL_EXPORT EVP_PKEY *EVP_PKEY_CTX_get0_pkey(EVP_PKEY_CTX *ctx); + +// EVP_PKEY_sign_init initialises an |EVP_PKEY_CTX| for a signing operation. It +// should be called before |EVP_PKEY_sign|. +// +// It returns one on success or zero on error. +OPENSSL_EXPORT int EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx); + +// EVP_PKEY_sign signs |digest_len| bytes from |digest| using |ctx|. If |sig| is +// NULL, the maximum size of the signature is written to +// |out_sig_len|. Otherwise, |*sig_len| must contain the number of bytes of +// space available at |sig|. If sufficient, the signature will be written to +// |sig| and |*sig_len| updated with the true length. +// +// This function expects a pre-hashed input and will fail for signature +// algorithms which do not support this. Use |EVP_DigestSignInit| to sign an +// unhashed input. +// +// WARNING: Setting |sig| to NULL only gives the maximum size of the +// signature. The actual signature may be smaller. +// +// It returns one on success or zero on error. (Note: this differs from +// OpenSSL, which can also return negative values to indicate an error. ) +OPENSSL_EXPORT int EVP_PKEY_sign(EVP_PKEY_CTX *ctx, uint8_t *sig, + size_t *sig_len, const uint8_t *digest, + size_t digest_len); + +// EVP_PKEY_verify_init initialises an |EVP_PKEY_CTX| for a signature +// verification operation. It should be called before |EVP_PKEY_verify|. +// +// It returns one on success or zero on error. +OPENSSL_EXPORT int EVP_PKEY_verify_init(EVP_PKEY_CTX *ctx); + +// EVP_PKEY_verify verifies that |sig_len| bytes from |sig| are a valid +// signature for |digest|. +// +// This function expects a pre-hashed input and will fail for signature +// algorithms which do not support this. Use |EVP_DigestVerifyInit| to verify a +// signature given the unhashed input. +// +// It returns one on success or zero on error. +OPENSSL_EXPORT int EVP_PKEY_verify(EVP_PKEY_CTX *ctx, const uint8_t *sig, + size_t sig_len, const uint8_t *digest, + size_t digest_len); + +// EVP_PKEY_encrypt_init initialises an |EVP_PKEY_CTX| for an encryption +// operation. It should be called before |EVP_PKEY_encrypt|. +// +// It returns one on success or zero on error. +OPENSSL_EXPORT int EVP_PKEY_encrypt_init(EVP_PKEY_CTX *ctx); + +// EVP_PKEY_encrypt encrypts |in_len| bytes from |in|. If |out| is NULL, the +// maximum size of the ciphertext is written to |out_len|. Otherwise, |*out_len| +// must contain the number of bytes of space available at |out|. If sufficient, +// the ciphertext will be written to |out| and |*out_len| updated with the true +// length. +// +// WARNING: Setting |out| to NULL only gives the maximum size of the +// ciphertext. The actual ciphertext may be smaller. +// +// It returns one on success or zero on error. +OPENSSL_EXPORT int EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx, uint8_t *out, + size_t *out_len, const uint8_t *in, + size_t in_len); + +// EVP_PKEY_decrypt_init initialises an |EVP_PKEY_CTX| for a decryption +// operation. It should be called before |EVP_PKEY_decrypt|. +// +// It returns one on success or zero on error. +OPENSSL_EXPORT int EVP_PKEY_decrypt_init(EVP_PKEY_CTX *ctx); + +// EVP_PKEY_decrypt decrypts |in_len| bytes from |in|. If |out| is NULL, the +// maximum size of the plaintext is written to |out_len|. Otherwise, |*out_len| +// must contain the number of bytes of space available at |out|. If sufficient, +// the ciphertext will be written to |out| and |*out_len| updated with the true +// length. +// +// WARNING: Setting |out| to NULL only gives the maximum size of the +// plaintext. The actual plaintext may be smaller. +// +// It returns one on success or zero on error. +OPENSSL_EXPORT int EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx, uint8_t *out, + size_t *out_len, const uint8_t *in, + size_t in_len); + +// EVP_PKEY_verify_recover_init initialises an |EVP_PKEY_CTX| for a public-key +// decryption operation. It should be called before |EVP_PKEY_verify_recover|. +// +// Public-key decryption is a very obscure operation that is only implemented +// by RSA keys. It is effectively a signature verification operation that +// returns the signed message directly. It is almost certainly not what you +// want. +// +// It returns one on success or zero on error. +OPENSSL_EXPORT int EVP_PKEY_verify_recover_init(EVP_PKEY_CTX *ctx); + +// EVP_PKEY_verify_recover decrypts |sig_len| bytes from |sig|. If |out| is +// NULL, the maximum size of the plaintext is written to |out_len|. Otherwise, +// |*out_len| must contain the number of bytes of space available at |out|. If +// sufficient, the ciphertext will be written to |out| and |*out_len| updated +// with the true length. +// +// WARNING: Setting |out| to NULL only gives the maximum size of the +// plaintext. The actual plaintext may be smaller. +// +// See the warning about this operation in |EVP_PKEY_verify_recover_init|. It +// is probably not what you want. +// +// It returns one on success or zero on error. +OPENSSL_EXPORT int EVP_PKEY_verify_recover(EVP_PKEY_CTX *ctx, uint8_t *out, + size_t *out_len, const uint8_t *sig, + size_t siglen); + +// EVP_PKEY_derive_init initialises an |EVP_PKEY_CTX| for a key derivation +// operation. It should be called before |EVP_PKEY_derive_set_peer| and +// |EVP_PKEY_derive|. +// +// It returns one on success or zero on error. +OPENSSL_EXPORT int EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx); + +// EVP_PKEY_derive_set_peer sets the peer's key to be used for key derivation +// by |ctx| to |peer|. It should be called after |EVP_PKEY_derive_init|. (For +// example, this is used to set the peer's key in (EC)DH.) It returns one on +// success and zero on error. +OPENSSL_EXPORT int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer); + +// EVP_PKEY_derive derives a shared key between the two keys configured in +// |ctx|. If |key| is non-NULL then, on entry, |out_key_len| must contain the +// amount of space at |key|. If sufficient then the shared key will be written +// to |key| and |*out_key_len| will be set to the length. If |key| is NULL then +// |out_key_len| will be set to the maximum length. +// +// WARNING: Setting |out| to NULL only gives the maximum size of the key. The +// actual key may be smaller. +// +// It returns one on success and zero on error. +OPENSSL_EXPORT int EVP_PKEY_derive(EVP_PKEY_CTX *ctx, uint8_t *key, + size_t *out_key_len); + +// EVP_PKEY_keygen_init initialises an |EVP_PKEY_CTX| for a key generation +// operation. It should be called before |EVP_PKEY_keygen|. +// +// It returns one on success or zero on error. +OPENSSL_EXPORT int EVP_PKEY_keygen_init(EVP_PKEY_CTX *ctx); + +// EVP_PKEY_keygen performs a key generation operation using the values from +// |ctx| and sets |*ppkey| to a fresh |EVP_PKEY| containing the resulting key. +// It returns one on success or zero on error. +OPENSSL_EXPORT int EVP_PKEY_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey); + + +// Generic control functions. + +// EVP_PKEY_CTX_set_signature_md sets |md| as the digest to be used in a +// signature operation. It returns one on success or zero on error. +OPENSSL_EXPORT int EVP_PKEY_CTX_set_signature_md(EVP_PKEY_CTX *ctx, + const EVP_MD *md); + +// EVP_PKEY_CTX_get_signature_md sets |*out_md| to the digest to be used in a +// signature operation. It returns one on success or zero on error. +OPENSSL_EXPORT int EVP_PKEY_CTX_get_signature_md(EVP_PKEY_CTX *ctx, + const EVP_MD **out_md); + + +// RSA specific control functions. + +// EVP_PKEY_CTX_set_rsa_padding sets the padding type to use. It should be one +// of the |RSA_*_PADDING| values. Returns one on success or zero on error. +OPENSSL_EXPORT int EVP_PKEY_CTX_set_rsa_padding(EVP_PKEY_CTX *ctx, int padding); + +// EVP_PKEY_CTX_get_rsa_padding sets |*out_padding| to the current padding +// value, which is one of the |RSA_*_PADDING| values. Returns one on success or +// zero on error. +OPENSSL_EXPORT int EVP_PKEY_CTX_get_rsa_padding(EVP_PKEY_CTX *ctx, + int *out_padding); + +// EVP_PKEY_CTX_set_rsa_pss_saltlen sets the length of the salt in a PSS-padded +// signature. A value of -1 cause the salt to be the same length as the digest +// in the signature. A value of -2 causes the salt to be the maximum length +// that will fit when signing and recovered from the signature when verifying. +// Otherwise the value gives the size of the salt in bytes. +// +// If unsure, use -1. +// +// Returns one on success or zero on error. +OPENSSL_EXPORT int EVP_PKEY_CTX_set_rsa_pss_saltlen(EVP_PKEY_CTX *ctx, + int salt_len); + +// EVP_PKEY_CTX_get_rsa_pss_saltlen sets |*out_salt_len| to the salt length of +// a PSS-padded signature. See the documentation for +// |EVP_PKEY_CTX_set_rsa_pss_saltlen| for details of the special values that it +// can take. +// +// Returns one on success or zero on error. +OPENSSL_EXPORT int EVP_PKEY_CTX_get_rsa_pss_saltlen(EVP_PKEY_CTX *ctx, + int *out_salt_len); + +// EVP_PKEY_CTX_set_rsa_keygen_bits sets the size of the desired RSA modulus, +// in bits, for key generation. Returns one on success or zero on +// error. +OPENSSL_EXPORT int EVP_PKEY_CTX_set_rsa_keygen_bits(EVP_PKEY_CTX *ctx, + int bits); + +// EVP_PKEY_CTX_set_rsa_keygen_pubexp sets |e| as the public exponent for key +// generation. Returns one on success or zero on error. +OPENSSL_EXPORT int EVP_PKEY_CTX_set_rsa_keygen_pubexp(EVP_PKEY_CTX *ctx, + BIGNUM *e); + +// EVP_PKEY_CTX_set_rsa_oaep_md sets |md| as the digest used in OAEP padding. +// Returns one on success or zero on error. +OPENSSL_EXPORT int EVP_PKEY_CTX_set_rsa_oaep_md(EVP_PKEY_CTX *ctx, + const EVP_MD *md); + +// EVP_PKEY_CTX_get_rsa_oaep_md sets |*out_md| to the digest function used in +// OAEP padding. Returns one on success or zero on error. +OPENSSL_EXPORT int EVP_PKEY_CTX_get_rsa_oaep_md(EVP_PKEY_CTX *ctx, + const EVP_MD **out_md); + +// EVP_PKEY_CTX_set_rsa_mgf1_md sets |md| as the digest used in MGF1. Returns +// one on success or zero on error. +OPENSSL_EXPORT int EVP_PKEY_CTX_set_rsa_mgf1_md(EVP_PKEY_CTX *ctx, + const EVP_MD *md); + +// EVP_PKEY_CTX_get_rsa_mgf1_md sets |*out_md| to the digest function used in +// MGF1. Returns one on success or zero on error. +OPENSSL_EXPORT int EVP_PKEY_CTX_get_rsa_mgf1_md(EVP_PKEY_CTX *ctx, + const EVP_MD **out_md); + +// EVP_PKEY_CTX_set0_rsa_oaep_label sets |label_len| bytes from |label| as the +// label used in OAEP. DANGER: On success, this call takes ownership of |label| +// and will call |OPENSSL_free| on it when |ctx| is destroyed. +// +// Returns one on success or zero on error. +OPENSSL_EXPORT int EVP_PKEY_CTX_set0_rsa_oaep_label(EVP_PKEY_CTX *ctx, + uint8_t *label, + size_t label_len); + +// EVP_PKEY_CTX_get0_rsa_oaep_label sets |*out_label| to point to the internal +// buffer containing the OAEP label (which may be NULL) and returns the length +// of the label or a negative value on error. +// +// WARNING: the return value differs from the usual return value convention. +OPENSSL_EXPORT int EVP_PKEY_CTX_get0_rsa_oaep_label(EVP_PKEY_CTX *ctx, + const uint8_t **out_label); + + +// Deprecated functions. + +// EVP_PKEY_DH is defined for compatibility, but it is impossible to create an +// |EVP_PKEY| of that type. +#define EVP_PKEY_DH NID_dhKeyAgreement + +// EVP_PKEY_RSA2 was historically an alternate form for RSA public keys (OID +// 2.5.8.1.1), but is no longer accepted. +#define EVP_PKEY_RSA2 NID_rsa + +// OpenSSL_add_all_algorithms does nothing. +OPENSSL_EXPORT void OpenSSL_add_all_algorithms(void); + +// OPENSSL_add_all_algorithms_conf does nothing. +OPENSSL_EXPORT void OPENSSL_add_all_algorithms_conf(void); + +// OpenSSL_add_all_ciphers does nothing. +OPENSSL_EXPORT void OpenSSL_add_all_ciphers(void); + +// OpenSSL_add_all_digests does nothing. +OPENSSL_EXPORT void OpenSSL_add_all_digests(void); + +// EVP_cleanup does nothing. +OPENSSL_EXPORT void EVP_cleanup(void); + +OPENSSL_EXPORT void EVP_CIPHER_do_all_sorted( + void (*callback)(const EVP_CIPHER *cipher, const char *name, + const char *unused, void *arg), + void *arg); + +OPENSSL_EXPORT void EVP_MD_do_all_sorted(void (*callback)(const EVP_MD *cipher, + const char *name, + const char *unused, + void *arg), + void *arg); + +// i2d_PrivateKey marshals a private key from |key| to an ASN.1, DER +// structure. If |outp| is not NULL then the result is written to |*outp| and +// |*outp| is advanced just past the output. It returns the number of bytes in +// the result, whether written or not, or a negative value on error. +// +// RSA keys are serialized as a DER-encoded RSAPublicKey (RFC 3447) structure. +// EC keys are serialized as a DER-encoded ECPrivateKey (RFC 5915) structure. +// +// Use |RSA_marshal_private_key| or |EC_KEY_marshal_private_key| instead. +OPENSSL_EXPORT int i2d_PrivateKey(const EVP_PKEY *key, uint8_t **outp); + +// i2d_PublicKey marshals a public key from |key| to a type-specific format. +// If |outp| is not NULL then the result is written to |*outp| and +// |*outp| is advanced just past the output. It returns the number of bytes in +// the result, whether written or not, or a negative value on error. +// +// RSA keys are serialized as a DER-encoded RSAPublicKey (RFC 3447) structure. +// EC keys are serialized as an EC point per SEC 1. +// +// Use |RSA_marshal_public_key| or |EC_POINT_point2cbb| instead. +OPENSSL_EXPORT int i2d_PublicKey(EVP_PKEY *key, uint8_t **outp); + +// d2i_PrivateKey parses an ASN.1, DER-encoded, private key from |len| bytes at +// |*inp|. If |out| is not NULL then, on exit, a pointer to the result is in +// |*out|. Note that, even if |*out| is already non-NULL on entry, it will not +// be written to. Rather, a fresh |EVP_PKEY| is allocated and the previous one +// is freed. On successful exit, |*inp| is advanced past the DER structure. It +// returns the result or NULL on error. +// +// This function tries to detect one of several formats. Instead, use +// |EVP_parse_private_key| for a PrivateKeyInfo, |RSA_parse_private_key| for an +// RSAPrivateKey, and |EC_parse_private_key| for an ECPrivateKey. +OPENSSL_EXPORT EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **out, + const uint8_t **inp, long len); + +// d2i_AutoPrivateKey acts the same as |d2i_PrivateKey|, but detects the type +// of the private key. +// +// This function tries to detect one of several formats. Instead, use +// |EVP_parse_private_key| for a PrivateKeyInfo, |RSA_parse_private_key| for an +// RSAPrivateKey, and |EC_parse_private_key| for an ECPrivateKey. +OPENSSL_EXPORT EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **out, const uint8_t **inp, + long len); + +// EVP_PKEY_get0_DH returns NULL. +OPENSSL_EXPORT DH *EVP_PKEY_get0_DH(EVP_PKEY *pkey); + + +// Private structures. + +struct evp_pkey_st { + CRYPTO_refcount_t references; + + // type contains one of the EVP_PKEY_* values or NID_undef and determines + // which element (if any) of the |pkey| union is valid. + int type; + + union { + void *ptr; + RSA *rsa; + DSA *dsa; + DH *dh; + EC_KEY *ec; + } pkey; + + // ameth contains a pointer to a method table that contains many ASN.1 + // methods for the key type. + const EVP_PKEY_ASN1_METHOD *ameth; +} /* EVP_PKEY */; + + +#if defined(__cplusplus) +} // extern C + +extern "C++" { +namespace bssl { + +BORINGSSL_MAKE_DELETER(EVP_PKEY, EVP_PKEY_free) +BORINGSSL_MAKE_DELETER(EVP_PKEY_CTX, EVP_PKEY_CTX_free) + +} // namespace bssl + +} // extern C++ + +#endif + +#define EVP_R_BUFFER_TOO_SMALL 100 +#define EVP_R_COMMAND_NOT_SUPPORTED 101 +#define EVP_R_DECODE_ERROR 102 +#define EVP_R_DIFFERENT_KEY_TYPES 103 +#define EVP_R_DIFFERENT_PARAMETERS 104 +#define EVP_R_ENCODE_ERROR 105 +#define EVP_R_EXPECTING_AN_EC_KEY_KEY 106 +#define EVP_R_EXPECTING_AN_RSA_KEY 107 +#define EVP_R_EXPECTING_A_DSA_KEY 108 +#define EVP_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE 109 +#define EVP_R_INVALID_DIGEST_LENGTH 110 +#define EVP_R_INVALID_DIGEST_TYPE 111 +#define EVP_R_INVALID_KEYBITS 112 +#define EVP_R_INVALID_MGF1_MD 113 +#define EVP_R_INVALID_OPERATION 114 +#define EVP_R_INVALID_PADDING_MODE 115 +#define EVP_R_INVALID_PSS_SALTLEN 116 +#define EVP_R_KEYS_NOT_SET 117 +#define EVP_R_MISSING_PARAMETERS 118 +#define EVP_R_NO_DEFAULT_DIGEST 119 +#define EVP_R_NO_KEY_SET 120 +#define EVP_R_NO_MDC2_SUPPORT 121 +#define EVP_R_NO_NID_FOR_CURVE 122 +#define EVP_R_NO_OPERATION_SET 123 +#define EVP_R_NO_PARAMETERS_SET 124 +#define EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE 125 +#define EVP_R_OPERATON_NOT_INITIALIZED 126 +#define EVP_R_UNKNOWN_PUBLIC_KEY_TYPE 127 +#define EVP_R_UNSUPPORTED_ALGORITHM 128 +#define EVP_R_UNSUPPORTED_PUBLIC_KEY_TYPE 129 +#define EVP_R_NOT_A_PRIVATE_KEY 130 +#define EVP_R_INVALID_SIGNATURE 131 +#define EVP_R_MEMORY_LIMIT_EXCEEDED 132 +#define EVP_R_INVALID_PARAMETERS 133 + +#endif // OPENSSL_HEADER_EVP_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/evp.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/evp.h.grpc_back new file mode 100644 index 0000000..7816b59 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/evp.h.grpc_back @@ -0,0 +1,873 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 OPENSSL_HEADER_EVP_H +#define OPENSSL_HEADER_EVP_H + +#include + +#include + +// OpenSSL included digest and cipher functions in this header so we include +// them for users that still expect that. +// +// TODO(fork): clean up callers so that they include what they use. +#include +#include +#include +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// EVP abstracts over public/private key algorithms. + + +// Public key objects. + +// EVP_PKEY_new creates a new, empty public-key object and returns it or NULL +// on allocation failure. +OPENSSL_EXPORT EVP_PKEY *EVP_PKEY_new(void); + +// EVP_PKEY_free frees all data referenced by |pkey| and then frees |pkey| +// itself. +OPENSSL_EXPORT void EVP_PKEY_free(EVP_PKEY *pkey); + +// EVP_PKEY_up_ref increments the reference count of |pkey| and returns one. +OPENSSL_EXPORT int EVP_PKEY_up_ref(EVP_PKEY *pkey); + +// EVP_PKEY_is_opaque returns one if |pkey| is opaque. Opaque keys are backed by +// custom implementations which do not expose key material and parameters. It is +// an error to attempt to duplicate, export, or compare an opaque key. +OPENSSL_EXPORT int EVP_PKEY_is_opaque(const EVP_PKEY *pkey); + +// EVP_PKEY_cmp compares |a| and |b| and returns one if they are equal, zero if +// not and a negative number on error. +// +// WARNING: this differs from the traditional return value of a "cmp" +// function. +OPENSSL_EXPORT int EVP_PKEY_cmp(const EVP_PKEY *a, const EVP_PKEY *b); + +// EVP_PKEY_copy_parameters sets the parameters of |to| to equal the parameters +// of |from|. It returns one on success and zero on error. +OPENSSL_EXPORT int EVP_PKEY_copy_parameters(EVP_PKEY *to, const EVP_PKEY *from); + +// EVP_PKEY_missing_parameters returns one if |pkey| is missing needed +// parameters or zero if not, or if the algorithm doesn't take parameters. +OPENSSL_EXPORT int EVP_PKEY_missing_parameters(const EVP_PKEY *pkey); + +// EVP_PKEY_size returns the maximum size, in bytes, of a signature signed by +// |pkey|. For an RSA key, this returns the number of bytes needed to represent +// the modulus. For an EC key, this returns the maximum size of a DER-encoded +// ECDSA signature. +OPENSSL_EXPORT int EVP_PKEY_size(const EVP_PKEY *pkey); + +// EVP_PKEY_bits returns the "size", in bits, of |pkey|. For an RSA key, this +// returns the bit length of the modulus. For an EC key, this returns the bit +// length of the group order. +OPENSSL_EXPORT int EVP_PKEY_bits(EVP_PKEY *pkey); + +// EVP_PKEY_id returns the type of |pkey|, which is one of the |EVP_PKEY_*| +// values. +OPENSSL_EXPORT int EVP_PKEY_id(const EVP_PKEY *pkey); + +// EVP_PKEY_type returns |nid| if |nid| is a known key type and |NID_undef| +// otherwise. +OPENSSL_EXPORT int EVP_PKEY_type(int nid); + + +// Getting and setting concrete public key types. +// +// The following functions get and set the underlying public key in an +// |EVP_PKEY| object. The |set1| functions take an additional reference to the +// underlying key and return one on success or zero on error. The |assign| +// functions adopt the caller's reference. The |get1| functions return a fresh +// reference to the underlying object or NULL if |pkey| is not of the correct +// type. The |get0| functions behave the same but return a non-owning +// pointer. + +OPENSSL_EXPORT int EVP_PKEY_set1_RSA(EVP_PKEY *pkey, RSA *key); +OPENSSL_EXPORT int EVP_PKEY_assign_RSA(EVP_PKEY *pkey, RSA *key); +OPENSSL_EXPORT RSA *EVP_PKEY_get0_RSA(EVP_PKEY *pkey); +OPENSSL_EXPORT RSA *EVP_PKEY_get1_RSA(EVP_PKEY *pkey); + +OPENSSL_EXPORT int EVP_PKEY_set1_DSA(EVP_PKEY *pkey, DSA *key); +OPENSSL_EXPORT int EVP_PKEY_assign_DSA(EVP_PKEY *pkey, DSA *key); +OPENSSL_EXPORT DSA *EVP_PKEY_get0_DSA(EVP_PKEY *pkey); +OPENSSL_EXPORT DSA *EVP_PKEY_get1_DSA(EVP_PKEY *pkey); + +OPENSSL_EXPORT int EVP_PKEY_set1_EC_KEY(EVP_PKEY *pkey, EC_KEY *key); +OPENSSL_EXPORT int EVP_PKEY_assign_EC_KEY(EVP_PKEY *pkey, EC_KEY *key); +OPENSSL_EXPORT EC_KEY *EVP_PKEY_get0_EC_KEY(EVP_PKEY *pkey); +OPENSSL_EXPORT EC_KEY *EVP_PKEY_get1_EC_KEY(EVP_PKEY *pkey); + +// EVP_PKEY_new_ed25519_public returns a newly allocated |EVP_PKEY| wrapping an +// Ed25519 public key, or NULL on allocation error. +OPENSSL_EXPORT EVP_PKEY *EVP_PKEY_new_ed25519_public( + const uint8_t public_key[32]); + +// EVP_PKEY_new_ed25519_private returns a newly allocated |EVP_PKEY| wrapping an +// Ed25519 private key, or NULL on allocation error. +OPENSSL_EXPORT EVP_PKEY *EVP_PKEY_new_ed25519_private( + const uint8_t private_key[64]); + +#define EVP_PKEY_NONE NID_undef +#define EVP_PKEY_RSA NID_rsaEncryption +#define EVP_PKEY_DSA NID_dsa +#define EVP_PKEY_EC NID_X9_62_id_ecPublicKey +#define EVP_PKEY_ED25519 NID_ED25519 + +// EVP_PKEY_assign sets the underlying key of |pkey| to |key|, which must be of +// the given type. The |type| argument should be one of the |EVP_PKEY_*| +// values. +OPENSSL_EXPORT int EVP_PKEY_assign(EVP_PKEY *pkey, int type, void *key); + +// EVP_PKEY_set_type sets the type of |pkey| to |type|, which should be one of +// the |EVP_PKEY_*| values. It returns one if successful or zero otherwise. If +// |pkey| is NULL, it simply reports whether the type is known. +OPENSSL_EXPORT int EVP_PKEY_set_type(EVP_PKEY *pkey, int type); + +// EVP_PKEY_cmp_parameters compares the parameters of |a| and |b|. It returns +// one if they match, zero if not, or a negative number of on error. +// +// WARNING: the return value differs from the usual return value convention. +OPENSSL_EXPORT int EVP_PKEY_cmp_parameters(const EVP_PKEY *a, + const EVP_PKEY *b); + + +// ASN.1 functions + +// EVP_parse_public_key decodes a DER-encoded SubjectPublicKeyInfo structure +// (RFC 5280) from |cbs| and advances |cbs|. It returns a newly-allocated +// |EVP_PKEY| or NULL on error. +// +// The caller must check the type of the parsed public key to ensure it is +// suitable and validate other desired key properties such as RSA modulus size +// or EC curve. +OPENSSL_EXPORT EVP_PKEY *EVP_parse_public_key(CBS *cbs); + +// EVP_marshal_public_key marshals |key| as a DER-encoded SubjectPublicKeyInfo +// structure (RFC 5280) and appends the result to |cbb|. It returns one on +// success and zero on error. +OPENSSL_EXPORT int EVP_marshal_public_key(CBB *cbb, const EVP_PKEY *key); + +// EVP_parse_private_key decodes a DER-encoded PrivateKeyInfo structure (RFC +// 5208) from |cbs| and advances |cbs|. It returns a newly-allocated |EVP_PKEY| +// or NULL on error. +// +// The caller must check the type of the parsed private key to ensure it is +// suitable and validate other desired key properties such as RSA modulus size +// or EC curve. +// +// A PrivateKeyInfo ends with an optional set of attributes. These are not +// processed and so this function will silently ignore any trailing data in the +// structure. +OPENSSL_EXPORT EVP_PKEY *EVP_parse_private_key(CBS *cbs); + +// EVP_marshal_private_key marshals |key| as a DER-encoded PrivateKeyInfo +// structure (RFC 5208) and appends the result to |cbb|. It returns one on +// success and zero on error. +OPENSSL_EXPORT int EVP_marshal_private_key(CBB *cbb, const EVP_PKEY *key); + + +// Signing + +// EVP_DigestSignInit sets up |ctx| for a signing operation with |type| and +// |pkey|. The |ctx| argument must have been initialised with +// |EVP_MD_CTX_init|. If |pctx| is not NULL, the |EVP_PKEY_CTX| of the signing +// operation will be written to |*pctx|; this can be used to set alternative +// signing options. +// +// For single-shot signing algorithms which do not use a pre-hash, such as +// Ed25519, |type| should be NULL. The |EVP_MD_CTX| itself is unused but is +// present so the API is uniform. See |EVP_DigestSign|. +// +// It returns one on success, or zero on error. +OPENSSL_EXPORT int EVP_DigestSignInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, + const EVP_MD *type, ENGINE *e, + EVP_PKEY *pkey); + +// EVP_DigestSignUpdate appends |len| bytes from |data| to the data which will +// be signed in |EVP_DigestSignFinal|. It returns one. +// +// This function performs a streaming signing operation and will fail for +// signature algorithms which do not support this. Use |EVP_DigestSign| for a +// single-shot operation. +OPENSSL_EXPORT int EVP_DigestSignUpdate(EVP_MD_CTX *ctx, const void *data, + size_t len); + +// EVP_DigestSignFinal signs the data that has been included by one or more +// calls to |EVP_DigestSignUpdate|. If |out_sig| is NULL then |*out_sig_len| is +// set to the maximum number of output bytes. Otherwise, on entry, +// |*out_sig_len| must contain the length of the |out_sig| buffer. If the call +// is successful, the signature is written to |out_sig| and |*out_sig_len| is +// set to its length. +// +// This function performs a streaming signing operation and will fail for +// signature algorithms which do not support this. Use |EVP_DigestSign| for a +// single-shot operation. +// +// It returns one on success, or zero on error. +OPENSSL_EXPORT int EVP_DigestSignFinal(EVP_MD_CTX *ctx, uint8_t *out_sig, + size_t *out_sig_len); + +// EVP_DigestSign signs |data_len| bytes from |data| using |ctx|. If |out_sig| +// is NULL then |*out_sig_len| is set to the maximum number of output +// bytes. Otherwise, on entry, |*out_sig_len| must contain the length of the +// |out_sig| buffer. If the call is successful, the signature is written to +// |out_sig| and |*out_sig_len| is set to its length. +// +// It returns one on success and zero on error. +OPENSSL_EXPORT int EVP_DigestSign(EVP_MD_CTX *ctx, uint8_t *out_sig, + size_t *out_sig_len, const uint8_t *data, + size_t data_len); + + +// Verifying + +// EVP_DigestVerifyInit sets up |ctx| for a signature verification operation +// with |type| and |pkey|. The |ctx| argument must have been initialised with +// |EVP_MD_CTX_init|. If |pctx| is not NULL, the |EVP_PKEY_CTX| of the signing +// operation will be written to |*pctx|; this can be used to set alternative +// signing options. +// +// For single-shot signing algorithms which do not use a pre-hash, such as +// Ed25519, |type| should be NULL. The |EVP_MD_CTX| itself is unused but is +// present so the API is uniform. See |EVP_DigestVerify|. +// +// It returns one on success, or zero on error. +OPENSSL_EXPORT int EVP_DigestVerifyInit(EVP_MD_CTX *ctx, EVP_PKEY_CTX **pctx, + const EVP_MD *type, ENGINE *e, + EVP_PKEY *pkey); + +// EVP_DigestVerifyUpdate appends |len| bytes from |data| to the data which +// will be verified by |EVP_DigestVerifyFinal|. It returns one. +// +// This function performs streaming signature verification and will fail for +// signature algorithms which do not support this. Use |EVP_PKEY_verify_message| +// for a single-shot verification. +OPENSSL_EXPORT int EVP_DigestVerifyUpdate(EVP_MD_CTX *ctx, const void *data, + size_t len); + +// EVP_DigestVerifyFinal verifies that |sig_len| bytes of |sig| are a valid +// signature for the data that has been included by one or more calls to +// |EVP_DigestVerifyUpdate|. It returns one on success and zero otherwise. +// +// This function performs streaming signature verification and will fail for +// signature algorithms which do not support this. Use |EVP_PKEY_verify_message| +// for a single-shot verification. +OPENSSL_EXPORT int EVP_DigestVerifyFinal(EVP_MD_CTX *ctx, const uint8_t *sig, + size_t sig_len); + +// EVP_DigestVerify verifies that |sig_len| bytes from |sig| are a valid +// signature for |data|. It returns one on success or zero on error. +OPENSSL_EXPORT int EVP_DigestVerify(EVP_MD_CTX *ctx, const uint8_t *sig, + size_t sig_len, const uint8_t *data, + size_t len); + + +// Signing (old functions) + +// EVP_SignInit_ex configures |ctx|, which must already have been initialised, +// for a fresh signing operation using the hash function |type|. It returns one +// on success and zero otherwise. +// +// (In order to initialise |ctx|, either obtain it initialised with +// |EVP_MD_CTX_create|, or use |EVP_MD_CTX_init|.) +OPENSSL_EXPORT int EVP_SignInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, + ENGINE *impl); + +// EVP_SignInit is a deprecated version of |EVP_SignInit_ex|. +// +// TODO(fork): remove. +OPENSSL_EXPORT int EVP_SignInit(EVP_MD_CTX *ctx, const EVP_MD *type); + +// EVP_SignUpdate appends |len| bytes from |data| to the data which will be +// signed in |EVP_SignFinal|. +OPENSSL_EXPORT int EVP_SignUpdate(EVP_MD_CTX *ctx, const void *data, + size_t len); + +// EVP_SignFinal signs the data that has been included by one or more calls to +// |EVP_SignUpdate|, using the key |pkey|, and writes it to |sig|. On entry, +// |sig| must point to at least |EVP_PKEY_size(pkey)| bytes of space. The +// actual size of the signature is written to |*out_sig_len|. +// +// It returns one on success and zero otherwise. +// +// It does not modify |ctx|, thus it's possible to continue to use |ctx| in +// order to sign a longer message. +OPENSSL_EXPORT int EVP_SignFinal(const EVP_MD_CTX *ctx, uint8_t *sig, + unsigned int *out_sig_len, EVP_PKEY *pkey); + + +// Verifying (old functions) + +// EVP_VerifyInit_ex configures |ctx|, which must already have been +// initialised, for a fresh signature verification operation using the hash +// function |type|. It returns one on success and zero otherwise. +// +// (In order to initialise |ctx|, either obtain it initialised with +// |EVP_MD_CTX_create|, or use |EVP_MD_CTX_init|.) +OPENSSL_EXPORT int EVP_VerifyInit_ex(EVP_MD_CTX *ctx, const EVP_MD *type, + ENGINE *impl); + +// EVP_VerifyInit is a deprecated version of |EVP_VerifyInit_ex|. +// +// TODO(fork): remove. +OPENSSL_EXPORT int EVP_VerifyInit(EVP_MD_CTX *ctx, const EVP_MD *type); + +// EVP_VerifyUpdate appends |len| bytes from |data| to the data which will be +// signed in |EVP_VerifyFinal|. +OPENSSL_EXPORT int EVP_VerifyUpdate(EVP_MD_CTX *ctx, const void *data, + size_t len); + +// EVP_VerifyFinal verifies that |sig_len| bytes of |sig| are a valid +// signature, by |pkey|, for the data that has been included by one or more +// calls to |EVP_VerifyUpdate|. +// +// It returns one on success and zero otherwise. +// +// It does not modify |ctx|, thus it's possible to continue to use |ctx| in +// order to sign a longer message. +OPENSSL_EXPORT int EVP_VerifyFinal(EVP_MD_CTX *ctx, const uint8_t *sig, + size_t sig_len, EVP_PKEY *pkey); + + +// Printing + +// EVP_PKEY_print_public prints a textual representation of the public key in +// |pkey| to |out|. Returns one on success or zero otherwise. +OPENSSL_EXPORT int EVP_PKEY_print_public(BIO *out, const EVP_PKEY *pkey, + int indent, ASN1_PCTX *pctx); + +// EVP_PKEY_print_private prints a textual representation of the private key in +// |pkey| to |out|. Returns one on success or zero otherwise. +OPENSSL_EXPORT int EVP_PKEY_print_private(BIO *out, const EVP_PKEY *pkey, + int indent, ASN1_PCTX *pctx); + +// EVP_PKEY_print_params prints a textual representation of the parameters in +// |pkey| to |out|. Returns one on success or zero otherwise. +OPENSSL_EXPORT int EVP_PKEY_print_params(BIO *out, const EVP_PKEY *pkey, + int indent, ASN1_PCTX *pctx); + + +// Password stretching. +// +// Password stretching functions take a low-entropy password and apply a slow +// function that results in a key suitable for use in symmetric +// cryptography. + +// PKCS5_PBKDF2_HMAC computes |iterations| iterations of PBKDF2 of |password| +// and |salt|, using |digest|, and outputs |key_len| bytes to |out_key|. It +// returns one on success and zero on error. +OPENSSL_EXPORT int PKCS5_PBKDF2_HMAC(const char *password, size_t password_len, + const uint8_t *salt, size_t salt_len, + unsigned iterations, const EVP_MD *digest, + size_t key_len, uint8_t *out_key); + +// PKCS5_PBKDF2_HMAC_SHA1 is the same as PKCS5_PBKDF2_HMAC, but with |digest| +// fixed to |EVP_sha1|. +OPENSSL_EXPORT int PKCS5_PBKDF2_HMAC_SHA1(const char *password, + size_t password_len, + const uint8_t *salt, size_t salt_len, + unsigned iterations, size_t key_len, + uint8_t *out_key); + +// EVP_PBE_scrypt expands |password| into a secret key of length |key_len| using +// scrypt, as described in RFC 7914, and writes the result to |out_key|. It +// returns one on success and zero on error. +// +// |N|, |r|, and |p| are as described in RFC 7914 section 6. They determine the +// cost of the operation. If the memory required exceeds |max_mem|, the +// operation will fail instead. If |max_mem| is zero, a defult limit of 32MiB +// will be used. +OPENSSL_EXPORT int EVP_PBE_scrypt(const char *password, size_t password_len, + const uint8_t *salt, size_t salt_len, + uint64_t N, uint64_t r, uint64_t p, + size_t max_mem, uint8_t *out_key, + size_t key_len); + + +// Public key contexts. +// +// |EVP_PKEY_CTX| objects hold the context of an operation (e.g. signing or +// encrypting) that uses a public key. + +// EVP_PKEY_CTX_new allocates a fresh |EVP_PKEY_CTX| for use with |pkey|. It +// returns the context or NULL on error. +OPENSSL_EXPORT EVP_PKEY_CTX *EVP_PKEY_CTX_new(EVP_PKEY *pkey, ENGINE *e); + +// EVP_PKEY_CTX_new_id allocates a fresh |EVP_PKEY_CTX| for a key of type |id| +// (e.g. |EVP_PKEY_HMAC|). This can be used for key generation where +// |EVP_PKEY_CTX_new| can't be used because there isn't an |EVP_PKEY| to pass +// it. It returns the context or NULL on error. +OPENSSL_EXPORT EVP_PKEY_CTX *EVP_PKEY_CTX_new_id(int id, ENGINE *e); + +// EVP_PKEY_CTX_free frees |ctx| and the data it owns. +OPENSSL_EXPORT void EVP_PKEY_CTX_free(EVP_PKEY_CTX *ctx); + +// EVP_PKEY_CTX_dup allocates a fresh |EVP_PKEY_CTX| and sets it equal to the +// state of |ctx|. It returns the fresh |EVP_PKEY_CTX| or NULL on error. +OPENSSL_EXPORT EVP_PKEY_CTX *EVP_PKEY_CTX_dup(EVP_PKEY_CTX *ctx); + +// EVP_PKEY_CTX_get0_pkey returns the |EVP_PKEY| associated with |ctx|. +OPENSSL_EXPORT EVP_PKEY *EVP_PKEY_CTX_get0_pkey(EVP_PKEY_CTX *ctx); + +// EVP_PKEY_sign_init initialises an |EVP_PKEY_CTX| for a signing operation. It +// should be called before |EVP_PKEY_sign|. +// +// It returns one on success or zero on error. +OPENSSL_EXPORT int EVP_PKEY_sign_init(EVP_PKEY_CTX *ctx); + +// EVP_PKEY_sign signs |digest_len| bytes from |digest| using |ctx|. If |sig| is +// NULL, the maximum size of the signature is written to +// |out_sig_len|. Otherwise, |*sig_len| must contain the number of bytes of +// space available at |sig|. If sufficient, the signature will be written to +// |sig| and |*sig_len| updated with the true length. +// +// This function expects a pre-hashed input and will fail for signature +// algorithms which do not support this. Use |EVP_DigestSignInit| to sign an +// unhashed input. +// +// WARNING: Setting |sig| to NULL only gives the maximum size of the +// signature. The actual signature may be smaller. +// +// It returns one on success or zero on error. (Note: this differs from +// OpenSSL, which can also return negative values to indicate an error. ) +OPENSSL_EXPORT int EVP_PKEY_sign(EVP_PKEY_CTX *ctx, uint8_t *sig, + size_t *sig_len, const uint8_t *digest, + size_t digest_len); + +// EVP_PKEY_verify_init initialises an |EVP_PKEY_CTX| for a signature +// verification operation. It should be called before |EVP_PKEY_verify|. +// +// It returns one on success or zero on error. +OPENSSL_EXPORT int EVP_PKEY_verify_init(EVP_PKEY_CTX *ctx); + +// EVP_PKEY_verify verifies that |sig_len| bytes from |sig| are a valid +// signature for |digest|. +// +// This function expects a pre-hashed input and will fail for signature +// algorithms which do not support this. Use |EVP_DigestVerifyInit| to verify a +// signature given the unhashed input. +// +// It returns one on success or zero on error. +OPENSSL_EXPORT int EVP_PKEY_verify(EVP_PKEY_CTX *ctx, const uint8_t *sig, + size_t sig_len, const uint8_t *digest, + size_t digest_len); + +// EVP_PKEY_encrypt_init initialises an |EVP_PKEY_CTX| for an encryption +// operation. It should be called before |EVP_PKEY_encrypt|. +// +// It returns one on success or zero on error. +OPENSSL_EXPORT int EVP_PKEY_encrypt_init(EVP_PKEY_CTX *ctx); + +// EVP_PKEY_encrypt encrypts |in_len| bytes from |in|. If |out| is NULL, the +// maximum size of the ciphertext is written to |out_len|. Otherwise, |*out_len| +// must contain the number of bytes of space available at |out|. If sufficient, +// the ciphertext will be written to |out| and |*out_len| updated with the true +// length. +// +// WARNING: Setting |out| to NULL only gives the maximum size of the +// ciphertext. The actual ciphertext may be smaller. +// +// It returns one on success or zero on error. +OPENSSL_EXPORT int EVP_PKEY_encrypt(EVP_PKEY_CTX *ctx, uint8_t *out, + size_t *out_len, const uint8_t *in, + size_t in_len); + +// EVP_PKEY_decrypt_init initialises an |EVP_PKEY_CTX| for a decryption +// operation. It should be called before |EVP_PKEY_decrypt|. +// +// It returns one on success or zero on error. +OPENSSL_EXPORT int EVP_PKEY_decrypt_init(EVP_PKEY_CTX *ctx); + +// EVP_PKEY_decrypt decrypts |in_len| bytes from |in|. If |out| is NULL, the +// maximum size of the plaintext is written to |out_len|. Otherwise, |*out_len| +// must contain the number of bytes of space available at |out|. If sufficient, +// the ciphertext will be written to |out| and |*out_len| updated with the true +// length. +// +// WARNING: Setting |out| to NULL only gives the maximum size of the +// plaintext. The actual plaintext may be smaller. +// +// It returns one on success or zero on error. +OPENSSL_EXPORT int EVP_PKEY_decrypt(EVP_PKEY_CTX *ctx, uint8_t *out, + size_t *out_len, const uint8_t *in, + size_t in_len); + +// EVP_PKEY_verify_recover_init initialises an |EVP_PKEY_CTX| for a public-key +// decryption operation. It should be called before |EVP_PKEY_verify_recover|. +// +// Public-key decryption is a very obscure operation that is only implemented +// by RSA keys. It is effectively a signature verification operation that +// returns the signed message directly. It is almost certainly not what you +// want. +// +// It returns one on success or zero on error. +OPENSSL_EXPORT int EVP_PKEY_verify_recover_init(EVP_PKEY_CTX *ctx); + +// EVP_PKEY_verify_recover decrypts |sig_len| bytes from |sig|. If |out| is +// NULL, the maximum size of the plaintext is written to |out_len|. Otherwise, +// |*out_len| must contain the number of bytes of space available at |out|. If +// sufficient, the ciphertext will be written to |out| and |*out_len| updated +// with the true length. +// +// WARNING: Setting |out| to NULL only gives the maximum size of the +// plaintext. The actual plaintext may be smaller. +// +// See the warning about this operation in |EVP_PKEY_verify_recover_init|. It +// is probably not what you want. +// +// It returns one on success or zero on error. +OPENSSL_EXPORT int EVP_PKEY_verify_recover(EVP_PKEY_CTX *ctx, uint8_t *out, + size_t *out_len, const uint8_t *sig, + size_t siglen); + +// EVP_PKEY_derive_init initialises an |EVP_PKEY_CTX| for a key derivation +// operation. It should be called before |EVP_PKEY_derive_set_peer| and +// |EVP_PKEY_derive|. +// +// It returns one on success or zero on error. +OPENSSL_EXPORT int EVP_PKEY_derive_init(EVP_PKEY_CTX *ctx); + +// EVP_PKEY_derive_set_peer sets the peer's key to be used for key derivation +// by |ctx| to |peer|. It should be called after |EVP_PKEY_derive_init|. (For +// example, this is used to set the peer's key in (EC)DH.) It returns one on +// success and zero on error. +OPENSSL_EXPORT int EVP_PKEY_derive_set_peer(EVP_PKEY_CTX *ctx, EVP_PKEY *peer); + +// EVP_PKEY_derive derives a shared key between the two keys configured in +// |ctx|. If |key| is non-NULL then, on entry, |out_key_len| must contain the +// amount of space at |key|. If sufficient then the shared key will be written +// to |key| and |*out_key_len| will be set to the length. If |key| is NULL then +// |out_key_len| will be set to the maximum length. +// +// WARNING: Setting |out| to NULL only gives the maximum size of the key. The +// actual key may be smaller. +// +// It returns one on success and zero on error. +OPENSSL_EXPORT int EVP_PKEY_derive(EVP_PKEY_CTX *ctx, uint8_t *key, + size_t *out_key_len); + +// EVP_PKEY_keygen_init initialises an |EVP_PKEY_CTX| for a key generation +// operation. It should be called before |EVP_PKEY_keygen|. +// +// It returns one on success or zero on error. +OPENSSL_EXPORT int EVP_PKEY_keygen_init(EVP_PKEY_CTX *ctx); + +// EVP_PKEY_keygen performs a key generation operation using the values from +// |ctx| and sets |*ppkey| to a fresh |EVP_PKEY| containing the resulting key. +// It returns one on success or zero on error. +OPENSSL_EXPORT int EVP_PKEY_keygen(EVP_PKEY_CTX *ctx, EVP_PKEY **ppkey); + + +// Generic control functions. + +// EVP_PKEY_CTX_set_signature_md sets |md| as the digest to be used in a +// signature operation. It returns one on success or zero on error. +OPENSSL_EXPORT int EVP_PKEY_CTX_set_signature_md(EVP_PKEY_CTX *ctx, + const EVP_MD *md); + +// EVP_PKEY_CTX_get_signature_md sets |*out_md| to the digest to be used in a +// signature operation. It returns one on success or zero on error. +OPENSSL_EXPORT int EVP_PKEY_CTX_get_signature_md(EVP_PKEY_CTX *ctx, + const EVP_MD **out_md); + + +// RSA specific control functions. + +// EVP_PKEY_CTX_set_rsa_padding sets the padding type to use. It should be one +// of the |RSA_*_PADDING| values. Returns one on success or zero on error. +OPENSSL_EXPORT int EVP_PKEY_CTX_set_rsa_padding(EVP_PKEY_CTX *ctx, int padding); + +// EVP_PKEY_CTX_get_rsa_padding sets |*out_padding| to the current padding +// value, which is one of the |RSA_*_PADDING| values. Returns one on success or +// zero on error. +OPENSSL_EXPORT int EVP_PKEY_CTX_get_rsa_padding(EVP_PKEY_CTX *ctx, + int *out_padding); + +// EVP_PKEY_CTX_set_rsa_pss_saltlen sets the length of the salt in a PSS-padded +// signature. A value of -1 cause the salt to be the same length as the digest +// in the signature. A value of -2 causes the salt to be the maximum length +// that will fit when signing and recovered from the signature when verifying. +// Otherwise the value gives the size of the salt in bytes. +// +// If unsure, use -1. +// +// Returns one on success or zero on error. +OPENSSL_EXPORT int EVP_PKEY_CTX_set_rsa_pss_saltlen(EVP_PKEY_CTX *ctx, + int salt_len); + +// EVP_PKEY_CTX_get_rsa_pss_saltlen sets |*out_salt_len| to the salt length of +// a PSS-padded signature. See the documentation for +// |EVP_PKEY_CTX_set_rsa_pss_saltlen| for details of the special values that it +// can take. +// +// Returns one on success or zero on error. +OPENSSL_EXPORT int EVP_PKEY_CTX_get_rsa_pss_saltlen(EVP_PKEY_CTX *ctx, + int *out_salt_len); + +// EVP_PKEY_CTX_set_rsa_keygen_bits sets the size of the desired RSA modulus, +// in bits, for key generation. Returns one on success or zero on +// error. +OPENSSL_EXPORT int EVP_PKEY_CTX_set_rsa_keygen_bits(EVP_PKEY_CTX *ctx, + int bits); + +// EVP_PKEY_CTX_set_rsa_keygen_pubexp sets |e| as the public exponent for key +// generation. Returns one on success or zero on error. +OPENSSL_EXPORT int EVP_PKEY_CTX_set_rsa_keygen_pubexp(EVP_PKEY_CTX *ctx, + BIGNUM *e); + +// EVP_PKEY_CTX_set_rsa_oaep_md sets |md| as the digest used in OAEP padding. +// Returns one on success or zero on error. +OPENSSL_EXPORT int EVP_PKEY_CTX_set_rsa_oaep_md(EVP_PKEY_CTX *ctx, + const EVP_MD *md); + +// EVP_PKEY_CTX_get_rsa_oaep_md sets |*out_md| to the digest function used in +// OAEP padding. Returns one on success or zero on error. +OPENSSL_EXPORT int EVP_PKEY_CTX_get_rsa_oaep_md(EVP_PKEY_CTX *ctx, + const EVP_MD **out_md); + +// EVP_PKEY_CTX_set_rsa_mgf1_md sets |md| as the digest used in MGF1. Returns +// one on success or zero on error. +OPENSSL_EXPORT int EVP_PKEY_CTX_set_rsa_mgf1_md(EVP_PKEY_CTX *ctx, + const EVP_MD *md); + +// EVP_PKEY_CTX_get_rsa_mgf1_md sets |*out_md| to the digest function used in +// MGF1. Returns one on success or zero on error. +OPENSSL_EXPORT int EVP_PKEY_CTX_get_rsa_mgf1_md(EVP_PKEY_CTX *ctx, + const EVP_MD **out_md); + +// EVP_PKEY_CTX_set0_rsa_oaep_label sets |label_len| bytes from |label| as the +// label used in OAEP. DANGER: On success, this call takes ownership of |label| +// and will call |OPENSSL_free| on it when |ctx| is destroyed. +// +// Returns one on success or zero on error. +OPENSSL_EXPORT int EVP_PKEY_CTX_set0_rsa_oaep_label(EVP_PKEY_CTX *ctx, + uint8_t *label, + size_t label_len); + +// EVP_PKEY_CTX_get0_rsa_oaep_label sets |*out_label| to point to the internal +// buffer containing the OAEP label (which may be NULL) and returns the length +// of the label or a negative value on error. +// +// WARNING: the return value differs from the usual return value convention. +OPENSSL_EXPORT int EVP_PKEY_CTX_get0_rsa_oaep_label(EVP_PKEY_CTX *ctx, + const uint8_t **out_label); + + +// Deprecated functions. + +// EVP_PKEY_DH is defined for compatibility, but it is impossible to create an +// |EVP_PKEY| of that type. +#define EVP_PKEY_DH NID_dhKeyAgreement + +// EVP_PKEY_RSA2 was historically an alternate form for RSA public keys (OID +// 2.5.8.1.1), but is no longer accepted. +#define EVP_PKEY_RSA2 NID_rsa + +// OpenSSL_add_all_algorithms does nothing. +OPENSSL_EXPORT void OpenSSL_add_all_algorithms(void); + +// OPENSSL_add_all_algorithms_conf does nothing. +OPENSSL_EXPORT void OPENSSL_add_all_algorithms_conf(void); + +// OpenSSL_add_all_ciphers does nothing. +OPENSSL_EXPORT void OpenSSL_add_all_ciphers(void); + +// OpenSSL_add_all_digests does nothing. +OPENSSL_EXPORT void OpenSSL_add_all_digests(void); + +// EVP_cleanup does nothing. +OPENSSL_EXPORT void EVP_cleanup(void); + +OPENSSL_EXPORT void EVP_CIPHER_do_all_sorted( + void (*callback)(const EVP_CIPHER *cipher, const char *name, + const char *unused, void *arg), + void *arg); + +OPENSSL_EXPORT void EVP_MD_do_all_sorted(void (*callback)(const EVP_MD *cipher, + const char *name, + const char *unused, + void *arg), + void *arg); + +// i2d_PrivateKey marshals a private key from |key| to an ASN.1, DER +// structure. If |outp| is not NULL then the result is written to |*outp| and +// |*outp| is advanced just past the output. It returns the number of bytes in +// the result, whether written or not, or a negative value on error. +// +// RSA keys are serialized as a DER-encoded RSAPublicKey (RFC 3447) structure. +// EC keys are serialized as a DER-encoded ECPrivateKey (RFC 5915) structure. +// +// Use |RSA_marshal_private_key| or |EC_KEY_marshal_private_key| instead. +OPENSSL_EXPORT int i2d_PrivateKey(const EVP_PKEY *key, uint8_t **outp); + +// i2d_PublicKey marshals a public key from |key| to a type-specific format. +// If |outp| is not NULL then the result is written to |*outp| and +// |*outp| is advanced just past the output. It returns the number of bytes in +// the result, whether written or not, or a negative value on error. +// +// RSA keys are serialized as a DER-encoded RSAPublicKey (RFC 3447) structure. +// EC keys are serialized as an EC point per SEC 1. +// +// Use |RSA_marshal_public_key| or |EC_POINT_point2cbb| instead. +OPENSSL_EXPORT int i2d_PublicKey(EVP_PKEY *key, uint8_t **outp); + +// d2i_PrivateKey parses an ASN.1, DER-encoded, private key from |len| bytes at +// |*inp|. If |out| is not NULL then, on exit, a pointer to the result is in +// |*out|. Note that, even if |*out| is already non-NULL on entry, it will not +// be written to. Rather, a fresh |EVP_PKEY| is allocated and the previous one +// is freed. On successful exit, |*inp| is advanced past the DER structure. It +// returns the result or NULL on error. +// +// This function tries to detect one of several formats. Instead, use +// |EVP_parse_private_key| for a PrivateKeyInfo, |RSA_parse_private_key| for an +// RSAPrivateKey, and |EC_parse_private_key| for an ECPrivateKey. +OPENSSL_EXPORT EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **out, + const uint8_t **inp, long len); + +// d2i_AutoPrivateKey acts the same as |d2i_PrivateKey|, but detects the type +// of the private key. +// +// This function tries to detect one of several formats. Instead, use +// |EVP_parse_private_key| for a PrivateKeyInfo, |RSA_parse_private_key| for an +// RSAPrivateKey, and |EC_parse_private_key| for an ECPrivateKey. +OPENSSL_EXPORT EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **out, const uint8_t **inp, + long len); + +// EVP_PKEY_get0_DH returns NULL. +OPENSSL_EXPORT DH *EVP_PKEY_get0_DH(EVP_PKEY *pkey); + + +// Private structures. + +struct evp_pkey_st { + CRYPTO_refcount_t references; + + // type contains one of the EVP_PKEY_* values or NID_undef and determines + // which element (if any) of the |pkey| union is valid. + int type; + + union { + void *ptr; + RSA *rsa; + DSA *dsa; + DH *dh; + EC_KEY *ec; + } pkey; + + // ameth contains a pointer to a method table that contains many ASN.1 + // methods for the key type. + const EVP_PKEY_ASN1_METHOD *ameth; +} /* EVP_PKEY */; + + +#if defined(__cplusplus) +} // extern C + +extern "C++" { +namespace bssl { + +BORINGSSL_MAKE_DELETER(EVP_PKEY, EVP_PKEY_free) +BORINGSSL_MAKE_DELETER(EVP_PKEY_CTX, EVP_PKEY_CTX_free) + +} // namespace bssl + +} // extern C++ + +#endif + +#define EVP_R_BUFFER_TOO_SMALL 100 +#define EVP_R_COMMAND_NOT_SUPPORTED 101 +#define EVP_R_DECODE_ERROR 102 +#define EVP_R_DIFFERENT_KEY_TYPES 103 +#define EVP_R_DIFFERENT_PARAMETERS 104 +#define EVP_R_ENCODE_ERROR 105 +#define EVP_R_EXPECTING_AN_EC_KEY_KEY 106 +#define EVP_R_EXPECTING_AN_RSA_KEY 107 +#define EVP_R_EXPECTING_A_DSA_KEY 108 +#define EVP_R_ILLEGAL_OR_UNSUPPORTED_PADDING_MODE 109 +#define EVP_R_INVALID_DIGEST_LENGTH 110 +#define EVP_R_INVALID_DIGEST_TYPE 111 +#define EVP_R_INVALID_KEYBITS 112 +#define EVP_R_INVALID_MGF1_MD 113 +#define EVP_R_INVALID_OPERATION 114 +#define EVP_R_INVALID_PADDING_MODE 115 +#define EVP_R_INVALID_PSS_SALTLEN 116 +#define EVP_R_KEYS_NOT_SET 117 +#define EVP_R_MISSING_PARAMETERS 118 +#define EVP_R_NO_DEFAULT_DIGEST 119 +#define EVP_R_NO_KEY_SET 120 +#define EVP_R_NO_MDC2_SUPPORT 121 +#define EVP_R_NO_NID_FOR_CURVE 122 +#define EVP_R_NO_OPERATION_SET 123 +#define EVP_R_NO_PARAMETERS_SET 124 +#define EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE 125 +#define EVP_R_OPERATON_NOT_INITIALIZED 126 +#define EVP_R_UNKNOWN_PUBLIC_KEY_TYPE 127 +#define EVP_R_UNSUPPORTED_ALGORITHM 128 +#define EVP_R_UNSUPPORTED_PUBLIC_KEY_TYPE 129 +#define EVP_R_NOT_A_PRIVATE_KEY 130 +#define EVP_R_INVALID_SIGNATURE 131 +#define EVP_R_MEMORY_LIMIT_EXCEEDED 132 +#define EVP_R_INVALID_PARAMETERS 133 + +#endif // OPENSSL_HEADER_EVP_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/ex_data.h b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/ex_data.h new file mode 100644 index 0000000..fbba1c6 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/ex_data.h @@ -0,0 +1,203 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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). */ + +#ifndef OPENSSL_HEADER_EX_DATA_H +#define OPENSSL_HEADER_EX_DATA_H + +#include + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// ex_data is a mechanism for associating arbitrary extra data with objects. +// For each type of object that supports ex_data, different users can be +// assigned indexes in which to store their data. Each index has callback +// functions that are called when an object of that type is freed or +// duplicated. + + +typedef struct crypto_ex_data_st CRYPTO_EX_DATA; + + +// Type-specific functions. +// +// Each type that supports ex_data provides three functions: + +#if 0 // Sample + +// TYPE_get_ex_new_index allocates a new index for |TYPE|. An optional +// |free_func| argument may be provided which is called when the owning object +// is destroyed. See |CRYPTO_EX_free| for details. The |argl| and |argp| +// arguments are opaque values that are passed to the callback. It returns the +// new index or a negative number on error. +OPENSSL_EXPORT int TYPE_get_ex_new_index(long argl, void *argp, + CRYPTO_EX_unused *unused, + CRYPTO_EX_dup *dup_unused, + CRYPTO_EX_free *free_func); + +// TYPE_set_ex_data sets an extra data pointer on |t|. The |index| argument +// should have been returned from a previous call to |TYPE_get_ex_new_index|. +OPENSSL_EXPORT int TYPE_set_ex_data(TYPE *t, int index, void *arg); + +// TYPE_get_ex_data returns an extra data pointer for |t|, or NULL if no such +// pointer exists. The |index| argument should have been returned from a +// previous call to |TYPE_get_ex_new_index|. +OPENSSL_EXPORT void *TYPE_get_ex_data(const TYPE *t, int index); + +#endif // Sample + + +// Callback types. + +// CRYPTO_EX_free is a callback function that is called when an object of the +// class with extra data pointers is being destroyed. For example, if this +// callback has been passed to |SSL_get_ex_new_index| then it may be called each +// time an |SSL*| is destroyed. +// +// The callback is passed the new object (i.e. the |SSL*|) in |parent|. The +// arguments |argl| and |argp| contain opaque values that were given to +// |CRYPTO_get_ex_new_index|. The callback should return one on success, but +// the value is ignored. +// +// This callback may be called with a NULL value for |ptr| if |parent| has no +// value set for this index. However, the callbacks may also be skipped entirely +// if no extra data pointers are set on |parent| at all. +typedef void CRYPTO_EX_free(void *parent, void *ptr, CRYPTO_EX_DATA *ad, + int index, long argl, void *argp); + + +// Deprecated functions. + +// CRYPTO_cleanup_all_ex_data does nothing. +OPENSSL_EXPORT void CRYPTO_cleanup_all_ex_data(void); + +// CRYPTO_EX_dup is a legacy callback function type which is ignored. +typedef int CRYPTO_EX_dup(CRYPTO_EX_DATA *to, const CRYPTO_EX_DATA *from, + void **from_d, int index, long argl, void *argp); + + +// Private structures. + +// CRYPTO_EX_unused is a placeholder for an unused callback. It is aliased to +// int to ensure non-NULL callers fail to compile rather than fail silently. +typedef int CRYPTO_EX_unused; + +struct crypto_ex_data_st { + STACK_OF(void) *sk; +}; + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_EX_DATA_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/ex_data.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/ex_data.h.grpc_back new file mode 100644 index 0000000..102f8a8 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/ex_data.h.grpc_back @@ -0,0 +1,203 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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). */ + +#ifndef OPENSSL_HEADER_EX_DATA_H +#define OPENSSL_HEADER_EX_DATA_H + +#include + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// ex_data is a mechanism for associating arbitrary extra data with objects. +// For each type of object that supports ex_data, different users can be +// assigned indexes in which to store their data. Each index has callback +// functions that are called when an object of that type is freed or +// duplicated. + + +typedef struct crypto_ex_data_st CRYPTO_EX_DATA; + + +// Type-specific functions. +// +// Each type that supports ex_data provides three functions: + +#if 0 // Sample + +// TYPE_get_ex_new_index allocates a new index for |TYPE|. An optional +// |free_func| argument may be provided which is called when the owning object +// is destroyed. See |CRYPTO_EX_free| for details. The |argl| and |argp| +// arguments are opaque values that are passed to the callback. It returns the +// new index or a negative number on error. +OPENSSL_EXPORT int TYPE_get_ex_new_index(long argl, void *argp, + CRYPTO_EX_unused *unused, + CRYPTO_EX_dup *dup_unused, + CRYPTO_EX_free *free_func); + +// TYPE_set_ex_data sets an extra data pointer on |t|. The |index| argument +// should have been returned from a previous call to |TYPE_get_ex_new_index|. +OPENSSL_EXPORT int TYPE_set_ex_data(TYPE *t, int index, void *arg); + +// TYPE_get_ex_data returns an extra data pointer for |t|, or NULL if no such +// pointer exists. The |index| argument should have been returned from a +// previous call to |TYPE_get_ex_new_index|. +OPENSSL_EXPORT void *TYPE_get_ex_data(const TYPE *t, int index); + +#endif // Sample + + +// Callback types. + +// CRYPTO_EX_free is a callback function that is called when an object of the +// class with extra data pointers is being destroyed. For example, if this +// callback has been passed to |SSL_get_ex_new_index| then it may be called each +// time an |SSL*| is destroyed. +// +// The callback is passed the new object (i.e. the |SSL*|) in |parent|. The +// arguments |argl| and |argp| contain opaque values that were given to +// |CRYPTO_get_ex_new_index|. The callback should return one on success, but +// the value is ignored. +// +// This callback may be called with a NULL value for |ptr| if |parent| has no +// value set for this index. However, the callbacks may also be skipped entirely +// if no extra data pointers are set on |parent| at all. +typedef void CRYPTO_EX_free(void *parent, void *ptr, CRYPTO_EX_DATA *ad, + int index, long argl, void *argp); + + +// Deprecated functions. + +// CRYPTO_cleanup_all_ex_data does nothing. +OPENSSL_EXPORT void CRYPTO_cleanup_all_ex_data(void); + +// CRYPTO_EX_dup is a legacy callback function type which is ignored. +typedef int CRYPTO_EX_dup(CRYPTO_EX_DATA *to, const CRYPTO_EX_DATA *from, + void **from_d, int index, long argl, void *argp); + + +// Private structures. + +// CRYPTO_EX_unused is a placeholder for an unused callback. It is aliased to +// int to ensure non-NULL callers fail to compile rather than fail silently. +typedef int CRYPTO_EX_unused; + +struct crypto_ex_data_st { + STACK_OF(void) *sk; +}; + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_EX_DATA_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/hkdf.h b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/hkdf.h new file mode 100644 index 0000000..fac6965 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/hkdf.h @@ -0,0 +1,64 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_HKDF_H +#define OPENSSL_HEADER_HKDF_H + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// HKDF. + + +// HKDF computes HKDF (as specified by RFC 5869) of initial keying material +// |secret| with |salt| and |info| using |digest|, and outputs |out_len| bytes +// to |out_key|. It returns one on success and zero on error. +// +// HKDF is an Extract-and-Expand algorithm. It does not do any key stretching, +// and as such, is not suited to be used alone to generate a key from a +// password. +OPENSSL_EXPORT int HKDF(uint8_t *out_key, size_t out_len, const EVP_MD *digest, + const uint8_t *secret, size_t secret_len, + const uint8_t *salt, size_t salt_len, + const uint8_t *info, size_t info_len); + +// HKDF_extract computes a HKDF PRK (as specified by RFC 5869) from initial +// keying material |secret| and salt |salt| using |digest|, and outputs +// |out_len| bytes to |out_key|. The maximum output size is |EVP_MAX_MD_SIZE|. +// It returns one on success and zero on error. +OPENSSL_EXPORT int HKDF_extract(uint8_t *out_key, size_t *out_len, + const EVP_MD *digest, const uint8_t *secret, + size_t secret_len, const uint8_t *salt, + size_t salt_len); + +// HKDF_expand computes a HKDF OKM (as specified by RFC 5869) of length +// |out_len| from the PRK |prk| and info |info| using |digest|, and outputs +// the result to |out_key|. It returns one on success and zero on error. +OPENSSL_EXPORT int HKDF_expand(uint8_t *out_key, size_t out_len, + const EVP_MD *digest, const uint8_t *prk, + size_t prk_len, const uint8_t *info, + size_t info_len); + + +#if defined(__cplusplus) +} // extern C +#endif + +#define HKDF_R_OUTPUT_TOO_LARGE 100 + +#endif // OPENSSL_HEADER_HKDF_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/hkdf.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/hkdf.h.grpc_back new file mode 100644 index 0000000..59aaa49 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/hkdf.h.grpc_back @@ -0,0 +1,64 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_HKDF_H +#define OPENSSL_HEADER_HKDF_H + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// HKDF. + + +// HKDF computes HKDF (as specified by RFC 5869) of initial keying material +// |secret| with |salt| and |info| using |digest|, and outputs |out_len| bytes +// to |out_key|. It returns one on success and zero on error. +// +// HKDF is an Extract-and-Expand algorithm. It does not do any key stretching, +// and as such, is not suited to be used alone to generate a key from a +// password. +OPENSSL_EXPORT int HKDF(uint8_t *out_key, size_t out_len, const EVP_MD *digest, + const uint8_t *secret, size_t secret_len, + const uint8_t *salt, size_t salt_len, + const uint8_t *info, size_t info_len); + +// HKDF_extract computes a HKDF PRK (as specified by RFC 5869) from initial +// keying material |secret| and salt |salt| using |digest|, and outputs +// |out_len| bytes to |out_key|. The maximum output size is |EVP_MAX_MD_SIZE|. +// It returns one on success and zero on error. +OPENSSL_EXPORT int HKDF_extract(uint8_t *out_key, size_t *out_len, + const EVP_MD *digest, const uint8_t *secret, + size_t secret_len, const uint8_t *salt, + size_t salt_len); + +// HKDF_expand computes a HKDF OKM (as specified by RFC 5869) of length +// |out_len| from the PRK |prk| and info |info| using |digest|, and outputs +// the result to |out_key|. It returns one on success and zero on error. +OPENSSL_EXPORT int HKDF_expand(uint8_t *out_key, size_t out_len, + const EVP_MD *digest, const uint8_t *prk, + size_t prk_len, const uint8_t *info, + size_t info_len); + + +#if defined(__cplusplus) +} // extern C +#endif + +#define HKDF_R_OUTPUT_TOO_LARGE 100 + +#endif // OPENSSL_HEADER_HKDF_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/hmac.h b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/hmac.h new file mode 100644 index 0000000..bd29128 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/hmac.h @@ -0,0 +1,186 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 OPENSSL_HEADER_HMAC_H +#define OPENSSL_HEADER_HMAC_H + +#include + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// HMAC contains functions for constructing PRFs from Merkle–Damgård hash +// functions using HMAC. + + +// One-shot operation. + +// HMAC calculates the HMAC of |data_len| bytes of |data|, using the given key +// and hash function, and writes the result to |out|. On entry, |out| must +// contain at least |EVP_MD_size| bytes of space. The actual length of the +// result is written to |*out_len|. An output size of |EVP_MAX_MD_SIZE| will +// always be large enough. It returns |out| or NULL on error. +OPENSSL_EXPORT uint8_t *HMAC(const EVP_MD *evp_md, const void *key, + size_t key_len, const uint8_t *data, + size_t data_len, uint8_t *out, + unsigned int *out_len); + + +// Incremental operation. + +// HMAC_CTX_init initialises |ctx| for use in an HMAC operation. It's assumed +// that HMAC_CTX objects will be allocated on the stack thus no allocation +// function is provided. +OPENSSL_EXPORT void HMAC_CTX_init(HMAC_CTX *ctx); + +// HMAC_CTX_new allocates and initialises a new |HMAC_CTX| and returns it, or +// NULL on allocation failure. The caller must use |HMAC_CTX_free| to release +// the resulting object. +OPENSSL_EXPORT HMAC_CTX *HMAC_CTX_new(void); + +// HMAC_CTX_cleanup frees data owned by |ctx|. It does not free |ctx| itself. +OPENSSL_EXPORT void HMAC_CTX_cleanup(HMAC_CTX *ctx); + +// HMAC_CTX_free calls |HMAC_CTX_cleanup| and then frees |ctx| itself. +OPENSSL_EXPORT void HMAC_CTX_free(HMAC_CTX *ctx); + +// HMAC_Init_ex sets up an initialised |HMAC_CTX| to use |md| as the hash +// function and |key| as the key. For a non-initial call, |md| may be NULL, in +// which case the previous hash function will be used. If the hash function has +// not changed and |key| is NULL, |ctx| reuses the previous key. It returns one +// on success or zero otherwise. +// +// WARNING: NULL and empty keys are ambiguous on non-initial calls. Passing NULL +// |key| but repeating the previous |md| reuses the previous key rather than the +// empty key. +OPENSSL_EXPORT int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, size_t key_len, + const EVP_MD *md, ENGINE *impl); + +// HMAC_Update hashes |data_len| bytes from |data| into the current HMAC +// operation in |ctx|. It returns one. +OPENSSL_EXPORT int HMAC_Update(HMAC_CTX *ctx, const uint8_t *data, + size_t data_len); + +// HMAC_Final completes the HMAC operation in |ctx| and writes the result to +// |out| and the sets |*out_len| to the length of the result. On entry, |out| +// must contain at least |HMAC_size| bytes of space. An output size of +// |EVP_MAX_MD_SIZE| will always be large enough. It returns one on success or +// zero on error. +OPENSSL_EXPORT int HMAC_Final(HMAC_CTX *ctx, uint8_t *out, + unsigned int *out_len); + + +// Utility functions. + +// HMAC_size returns the size, in bytes, of the HMAC that will be produced by +// |ctx|. On entry, |ctx| must have been setup with |HMAC_Init_ex|. +OPENSSL_EXPORT size_t HMAC_size(const HMAC_CTX *ctx); + +// HMAC_CTX_copy_ex sets |dest| equal to |src|. On entry, |dest| must have been +// initialised by calling |HMAC_CTX_init|. It returns one on success and zero +// on error. +OPENSSL_EXPORT int HMAC_CTX_copy_ex(HMAC_CTX *dest, const HMAC_CTX *src); + +// HMAC_CTX_reset calls |HMAC_CTX_cleanup| followed by |HMAC_CTX_init|. +OPENSSL_EXPORT void HMAC_CTX_reset(HMAC_CTX *ctx); + + +// Deprecated functions. + +OPENSSL_EXPORT int HMAC_Init(HMAC_CTX *ctx, const void *key, int key_len, + const EVP_MD *md); + +// HMAC_CTX_copy calls |HMAC_CTX_init| on |dest| and then sets it equal to +// |src|. On entry, |dest| must /not/ be initialised for an operation with +// |HMAC_Init_ex|. It returns one on success and zero on error. +OPENSSL_EXPORT int HMAC_CTX_copy(HMAC_CTX *dest, const HMAC_CTX *src); + + +// Private functions + +struct hmac_ctx_st { + const EVP_MD *md; + EVP_MD_CTX md_ctx; + EVP_MD_CTX i_ctx; + EVP_MD_CTX o_ctx; +} /* HMAC_CTX */; + + +#if defined(__cplusplus) +} // extern C + +#if !defined(BORINGSSL_NO_CXX) +extern "C++" { + +namespace bssl { + +BORINGSSL_MAKE_DELETER(HMAC_CTX, HMAC_CTX_free) + +using ScopedHMAC_CTX = + internal::StackAllocated; + +} // namespace bssl + +} // extern C++ +#endif + +#endif + +#endif // OPENSSL_HEADER_HMAC_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/hmac.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/hmac.h.grpc_back new file mode 100644 index 0000000..8491b8d --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/hmac.h.grpc_back @@ -0,0 +1,186 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 OPENSSL_HEADER_HMAC_H +#define OPENSSL_HEADER_HMAC_H + +#include + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// HMAC contains functions for constructing PRFs from Merkle–Damgård hash +// functions using HMAC. + + +// One-shot operation. + +// HMAC calculates the HMAC of |data_len| bytes of |data|, using the given key +// and hash function, and writes the result to |out|. On entry, |out| must +// contain at least |EVP_MD_size| bytes of space. The actual length of the +// result is written to |*out_len|. An output size of |EVP_MAX_MD_SIZE| will +// always be large enough. It returns |out| or NULL on error. +OPENSSL_EXPORT uint8_t *HMAC(const EVP_MD *evp_md, const void *key, + size_t key_len, const uint8_t *data, + size_t data_len, uint8_t *out, + unsigned int *out_len); + + +// Incremental operation. + +// HMAC_CTX_init initialises |ctx| for use in an HMAC operation. It's assumed +// that HMAC_CTX objects will be allocated on the stack thus no allocation +// function is provided. +OPENSSL_EXPORT void HMAC_CTX_init(HMAC_CTX *ctx); + +// HMAC_CTX_new allocates and initialises a new |HMAC_CTX| and returns it, or +// NULL on allocation failure. The caller must use |HMAC_CTX_free| to release +// the resulting object. +OPENSSL_EXPORT HMAC_CTX *HMAC_CTX_new(void); + +// HMAC_CTX_cleanup frees data owned by |ctx|. It does not free |ctx| itself. +OPENSSL_EXPORT void HMAC_CTX_cleanup(HMAC_CTX *ctx); + +// HMAC_CTX_free calls |HMAC_CTX_cleanup| and then frees |ctx| itself. +OPENSSL_EXPORT void HMAC_CTX_free(HMAC_CTX *ctx); + +// HMAC_Init_ex sets up an initialised |HMAC_CTX| to use |md| as the hash +// function and |key| as the key. For a non-initial call, |md| may be NULL, in +// which case the previous hash function will be used. If the hash function has +// not changed and |key| is NULL, |ctx| reuses the previous key. It returns one +// on success or zero otherwise. +// +// WARNING: NULL and empty keys are ambiguous on non-initial calls. Passing NULL +// |key| but repeating the previous |md| reuses the previous key rather than the +// empty key. +OPENSSL_EXPORT int HMAC_Init_ex(HMAC_CTX *ctx, const void *key, size_t key_len, + const EVP_MD *md, ENGINE *impl); + +// HMAC_Update hashes |data_len| bytes from |data| into the current HMAC +// operation in |ctx|. It returns one. +OPENSSL_EXPORT int HMAC_Update(HMAC_CTX *ctx, const uint8_t *data, + size_t data_len); + +// HMAC_Final completes the HMAC operation in |ctx| and writes the result to +// |out| and the sets |*out_len| to the length of the result. On entry, |out| +// must contain at least |HMAC_size| bytes of space. An output size of +// |EVP_MAX_MD_SIZE| will always be large enough. It returns one on success or +// zero on error. +OPENSSL_EXPORT int HMAC_Final(HMAC_CTX *ctx, uint8_t *out, + unsigned int *out_len); + + +// Utility functions. + +// HMAC_size returns the size, in bytes, of the HMAC that will be produced by +// |ctx|. On entry, |ctx| must have been setup with |HMAC_Init_ex|. +OPENSSL_EXPORT size_t HMAC_size(const HMAC_CTX *ctx); + +// HMAC_CTX_copy_ex sets |dest| equal to |src|. On entry, |dest| must have been +// initialised by calling |HMAC_CTX_init|. It returns one on success and zero +// on error. +OPENSSL_EXPORT int HMAC_CTX_copy_ex(HMAC_CTX *dest, const HMAC_CTX *src); + +// HMAC_CTX_reset calls |HMAC_CTX_cleanup| followed by |HMAC_CTX_init|. +OPENSSL_EXPORT void HMAC_CTX_reset(HMAC_CTX *ctx); + + +// Deprecated functions. + +OPENSSL_EXPORT int HMAC_Init(HMAC_CTX *ctx, const void *key, int key_len, + const EVP_MD *md); + +// HMAC_CTX_copy calls |HMAC_CTX_init| on |dest| and then sets it equal to +// |src|. On entry, |dest| must /not/ be initialised for an operation with +// |HMAC_Init_ex|. It returns one on success and zero on error. +OPENSSL_EXPORT int HMAC_CTX_copy(HMAC_CTX *dest, const HMAC_CTX *src); + + +// Private functions + +struct hmac_ctx_st { + const EVP_MD *md; + EVP_MD_CTX md_ctx; + EVP_MD_CTX i_ctx; + EVP_MD_CTX o_ctx; +} /* HMAC_CTX */; + + +#if defined(__cplusplus) +} // extern C + +#if !defined(BORINGSSL_NO_CXX) +extern "C++" { + +namespace bssl { + +BORINGSSL_MAKE_DELETER(HMAC_CTX, HMAC_CTX_free) + +using ScopedHMAC_CTX = + internal::StackAllocated; + +} // namespace bssl + +} // extern C++ +#endif + +#endif + +#endif // OPENSSL_HEADER_HMAC_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/is_boringssl.h b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/is_boringssl.h new file mode 100644 index 0000000..302cbe2 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/is_boringssl.h @@ -0,0 +1,16 @@ +/* Copyright (c) 2017, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +// This header is provided in order to catch include path errors in consuming +// BoringSSL. diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/is_boringssl.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/is_boringssl.h.grpc_back new file mode 100644 index 0000000..302cbe2 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/is_boringssl.h.grpc_back @@ -0,0 +1,16 @@ +/* Copyright (c) 2017, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +// This header is provided in order to catch include path errors in consuming +// BoringSSL. diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/lhash.h b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/lhash.h new file mode 100644 index 0000000..1d75eb7 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/lhash.h @@ -0,0 +1,174 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 OPENSSL_HEADER_LHASH_H +#define OPENSSL_HEADER_LHASH_H + +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// lhash is a traditional, chaining hash table that automatically expands and +// contracts as needed. One should not use the lh_* functions directly, rather +// use the type-safe macro wrappers: +// +// A hash table of a specific type of object has type |LHASH_OF(type)|. This +// can be defined (once) with |DEFINE_LHASH_OF(type)| and declared where needed +// with |DECLARE_LHASH_OF(type)|. For example: +// +// struct foo { +// int bar; +// }; +// +// DEFINE_LHASH_OF(struct foo); +// +// Although note that the hash table will contain /pointers/ to |foo|. +// +// A macro will be defined for each of the lh_* functions below. For +// LHASH_OF(foo), the macros would be lh_foo_new, lh_foo_num_items etc. + + +#define LHASH_OF(type) struct lhash_st_##type + +#define DEFINE_LHASH_OF(type) LHASH_OF(type) { int dummy; } + +#define DECLARE_LHASH_OF(type) LHASH_OF(type); + +// The make_macros.sh script in this directory parses the following lines and +// generates the lhash_macros.h file that contains macros for the following +// types of stacks: +// +// LHASH_OF:ASN1_OBJECT +// LHASH_OF:CONF_VALUE +// LHASH_OF:CRYPTO_BUFFER +// LHASH_OF:SSL_SESSION + +#define IN_LHASH_H +#include +#undef IN_LHASH_H + + +// lhash_item_st is an element of a hash chain. It points to the opaque data +// for this element and to the next item in the chain. The linked-list is NULL +// terminated. +typedef struct lhash_item_st { + void *data; + struct lhash_item_st *next; + // hash contains the cached, hash value of |data|. + uint32_t hash; +} LHASH_ITEM; + +// lhash_cmp_func is a comparison function that returns a value equal, or not +// equal, to zero depending on whether |*a| is equal, or not equal to |*b|, +// respectively. Note the difference between this and |stack_cmp_func| in that +// this takes pointers to the objects directly. +typedef int (*lhash_cmp_func)(const void *a, const void *b); + +// lhash_hash_func is a function that maps an object to a uniformly distributed +// uint32_t. +typedef uint32_t (*lhash_hash_func)(const void *a); + +typedef struct lhash_st _LHASH; + +// lh_new returns a new, empty hash table or NULL on error. +OPENSSL_EXPORT _LHASH *lh_new(lhash_hash_func hash, lhash_cmp_func comp); + +// lh_free frees the hash table itself but none of the elements. See +// |lh_doall|. +OPENSSL_EXPORT void lh_free(_LHASH *lh); + +// lh_num_items returns the number of items in |lh|. +OPENSSL_EXPORT size_t lh_num_items(const _LHASH *lh); + +// lh_retrieve finds an element equal to |data| in the hash table and returns +// it. If no such element exists, it returns NULL. +OPENSSL_EXPORT void *lh_retrieve(const _LHASH *lh, const void *data); + +// lh_insert inserts |data| into the hash table. If an existing element is +// equal to |data| (with respect to the comparison function) then |*old_data| +// will be set to that value and it will be replaced. Otherwise, or in the +// event of an error, |*old_data| will be set to NULL. It returns one on +// success or zero in the case of an allocation error. +OPENSSL_EXPORT int lh_insert(_LHASH *lh, void **old_data, void *data); + +// lh_delete removes an element equal to |data| from the hash table and returns +// it. If no such element is found, it returns NULL. +OPENSSL_EXPORT void *lh_delete(_LHASH *lh, const void *data); + +// lh_doall calls |func| on each element of the hash table. +// TODO(fork): rename this +OPENSSL_EXPORT void lh_doall(_LHASH *lh, void (*func)(void *)); + +// lh_doall_arg calls |func| on each element of the hash table and also passes +// |arg| as the second argument. +// TODO(fork): rename this +OPENSSL_EXPORT void lh_doall_arg(_LHASH *lh, void (*func)(void *, void *), + void *arg); + +// lh_strhash is the default hash function which processes NUL-terminated +// strings. +OPENSSL_EXPORT uint32_t lh_strhash(const char *c); + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_LHASH_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/lhash.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/lhash.h.grpc_back new file mode 100644 index 0000000..1ceeb69 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/lhash.h.grpc_back @@ -0,0 +1,174 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 OPENSSL_HEADER_LHASH_H +#define OPENSSL_HEADER_LHASH_H + +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// lhash is a traditional, chaining hash table that automatically expands and +// contracts as needed. One should not use the lh_* functions directly, rather +// use the type-safe macro wrappers: +// +// A hash table of a specific type of object has type |LHASH_OF(type)|. This +// can be defined (once) with |DEFINE_LHASH_OF(type)| and declared where needed +// with |DECLARE_LHASH_OF(type)|. For example: +// +// struct foo { +// int bar; +// }; +// +// DEFINE_LHASH_OF(struct foo); +// +// Although note that the hash table will contain /pointers/ to |foo|. +// +// A macro will be defined for each of the lh_* functions below. For +// LHASH_OF(foo), the macros would be lh_foo_new, lh_foo_num_items etc. + + +#define LHASH_OF(type) struct lhash_st_##type + +#define DEFINE_LHASH_OF(type) LHASH_OF(type) { int dummy; } + +#define DECLARE_LHASH_OF(type) LHASH_OF(type); + +// The make_macros.sh script in this directory parses the following lines and +// generates the lhash_macros.h file that contains macros for the following +// types of stacks: +// +// LHASH_OF:ASN1_OBJECT +// LHASH_OF:CONF_VALUE +// LHASH_OF:CRYPTO_BUFFER +// LHASH_OF:SSL_SESSION + +#define IN_LHASH_H +#include +#undef IN_LHASH_H + + +// lhash_item_st is an element of a hash chain. It points to the opaque data +// for this element and to the next item in the chain. The linked-list is NULL +// terminated. +typedef struct lhash_item_st { + void *data; + struct lhash_item_st *next; + // hash contains the cached, hash value of |data|. + uint32_t hash; +} LHASH_ITEM; + +// lhash_cmp_func is a comparison function that returns a value equal, or not +// equal, to zero depending on whether |*a| is equal, or not equal to |*b|, +// respectively. Note the difference between this and |stack_cmp_func| in that +// this takes pointers to the objects directly. +typedef int (*lhash_cmp_func)(const void *a, const void *b); + +// lhash_hash_func is a function that maps an object to a uniformly distributed +// uint32_t. +typedef uint32_t (*lhash_hash_func)(const void *a); + +typedef struct lhash_st _LHASH; + +// lh_new returns a new, empty hash table or NULL on error. +OPENSSL_EXPORT _LHASH *lh_new(lhash_hash_func hash, lhash_cmp_func comp); + +// lh_free frees the hash table itself but none of the elements. See +// |lh_doall|. +OPENSSL_EXPORT void lh_free(_LHASH *lh); + +// lh_num_items returns the number of items in |lh|. +OPENSSL_EXPORT size_t lh_num_items(const _LHASH *lh); + +// lh_retrieve finds an element equal to |data| in the hash table and returns +// it. If no such element exists, it returns NULL. +OPENSSL_EXPORT void *lh_retrieve(const _LHASH *lh, const void *data); + +// lh_insert inserts |data| into the hash table. If an existing element is +// equal to |data| (with respect to the comparison function) then |*old_data| +// will be set to that value and it will be replaced. Otherwise, or in the +// event of an error, |*old_data| will be set to NULL. It returns one on +// success or zero in the case of an allocation error. +OPENSSL_EXPORT int lh_insert(_LHASH *lh, void **old_data, void *data); + +// lh_delete removes an element equal to |data| from the hash table and returns +// it. If no such element is found, it returns NULL. +OPENSSL_EXPORT void *lh_delete(_LHASH *lh, const void *data); + +// lh_doall calls |func| on each element of the hash table. +// TODO(fork): rename this +OPENSSL_EXPORT void lh_doall(_LHASH *lh, void (*func)(void *)); + +// lh_doall_arg calls |func| on each element of the hash table and also passes +// |arg| as the second argument. +// TODO(fork): rename this +OPENSSL_EXPORT void lh_doall_arg(_LHASH *lh, void (*func)(void *, void *), + void *arg); + +// lh_strhash is the default hash function which processes NUL-terminated +// strings. +OPENSSL_EXPORT uint32_t lh_strhash(const char *c); + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_LHASH_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/lhash_macros.h b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/lhash_macros.h new file mode 100644 index 0000000..378c839 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/lhash_macros.h @@ -0,0 +1,174 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#if !defined(IN_LHASH_H) +#error "Don't include this file directly. Include lhash.h" +#endif + +// ASN1_OBJECT +#define lh_ASN1_OBJECT_new(hash, comp) \ + ((LHASH_OF(ASN1_OBJECT) *)lh_new( \ + CHECKED_CAST(lhash_hash_func, uint32_t(*)(const ASN1_OBJECT *), hash), \ + CHECKED_CAST(lhash_cmp_func, \ + int (*)(const ASN1_OBJECT *a, const ASN1_OBJECT *b), \ + comp))) + +#define lh_ASN1_OBJECT_free(lh) \ + lh_free(CHECKED_CAST(_LHASH *, LHASH_OF(ASN1_OBJECT) *, lh)); + +#define lh_ASN1_OBJECT_num_items(lh) \ + lh_num_items(CHECKED_CAST(_LHASH *, LHASH_OF(ASN1_OBJECT) *, lh)) + +#define lh_ASN1_OBJECT_retrieve(lh, data) \ + ((ASN1_OBJECT *)lh_retrieve( \ + CHECKED_CAST(_LHASH *, LHASH_OF(ASN1_OBJECT) *, lh), \ + CHECKED_CAST(void *, ASN1_OBJECT *, data))) + +#define lh_ASN1_OBJECT_insert(lh, old_data, data) \ + lh_insert(CHECKED_CAST(_LHASH *, LHASH_OF(ASN1_OBJECT) *, lh), \ + CHECKED_CAST(void **, ASN1_OBJECT **, old_data), \ + CHECKED_CAST(void *, ASN1_OBJECT *, data)) + +#define lh_ASN1_OBJECT_delete(lh, data) \ + ((ASN1_OBJECT *)lh_delete( \ + CHECKED_CAST(_LHASH *, LHASH_OF(ASN1_OBJECT) *, lh), \ + CHECKED_CAST(void *, ASN1_OBJECT *, data))) + +#define lh_ASN1_OBJECT_doall(lh, func) \ + lh_doall(CHECKED_CAST(_LHASH *, LHASH_OF(ASN1_OBJECT) *, lh), \ + CHECKED_CAST(void (*)(void *), void (*)(ASN1_OBJECT *), func)); + +#define lh_ASN1_OBJECT_doall_arg(lh, func, arg) \ + lh_doall_arg(CHECKED_CAST(_LHASH *, LHASH_OF(ASN1_OBJECT) *, lh), \ + CHECKED_CAST(void (*)(void *, void *), \ + void (*)(ASN1_OBJECT *, void *), func), \ + arg); + + +// CONF_VALUE +#define lh_CONF_VALUE_new(hash, comp) \ + ((LHASH_OF(CONF_VALUE) *)lh_new( \ + CHECKED_CAST(lhash_hash_func, uint32_t(*)(const CONF_VALUE *), hash), \ + CHECKED_CAST(lhash_cmp_func, \ + int (*)(const CONF_VALUE *a, const CONF_VALUE *b), comp))) + +#define lh_CONF_VALUE_free(lh) \ + lh_free(CHECKED_CAST(_LHASH *, LHASH_OF(CONF_VALUE) *, lh)); + +#define lh_CONF_VALUE_num_items(lh) \ + lh_num_items(CHECKED_CAST(_LHASH *, LHASH_OF(CONF_VALUE) *, lh)) + +#define lh_CONF_VALUE_retrieve(lh, data) \ + ((CONF_VALUE *)lh_retrieve( \ + CHECKED_CAST(_LHASH *, LHASH_OF(CONF_VALUE) *, lh), \ + CHECKED_CAST(void *, CONF_VALUE *, data))) + +#define lh_CONF_VALUE_insert(lh, old_data, data) \ + lh_insert(CHECKED_CAST(_LHASH *, LHASH_OF(CONF_VALUE) *, lh), \ + CHECKED_CAST(void **, CONF_VALUE **, old_data), \ + CHECKED_CAST(void *, CONF_VALUE *, data)) + +#define lh_CONF_VALUE_delete(lh, data) \ + ((CONF_VALUE *)lh_delete(CHECKED_CAST(_LHASH *, LHASH_OF(CONF_VALUE) *, lh), \ + CHECKED_CAST(void *, CONF_VALUE *, data))) + +#define lh_CONF_VALUE_doall(lh, func) \ + lh_doall(CHECKED_CAST(_LHASH *, LHASH_OF(CONF_VALUE) *, lh), \ + CHECKED_CAST(void (*)(void *), void (*)(CONF_VALUE *), func)); + +#define lh_CONF_VALUE_doall_arg(lh, func, arg) \ + lh_doall_arg(CHECKED_CAST(_LHASH *, LHASH_OF(CONF_VALUE) *, lh), \ + CHECKED_CAST(void (*)(void *, void *), \ + void (*)(CONF_VALUE *, void *), func), \ + arg); + + +// CRYPTO_BUFFER +#define lh_CRYPTO_BUFFER_new(hash, comp) \ + ((LHASH_OF(CRYPTO_BUFFER) *)lh_new( \ + CHECKED_CAST(lhash_hash_func, uint32_t(*)(const CRYPTO_BUFFER *), hash), \ + CHECKED_CAST(lhash_cmp_func, \ + int (*)(const CRYPTO_BUFFER *a, const CRYPTO_BUFFER *b), \ + comp))) + +#define lh_CRYPTO_BUFFER_free(lh) \ + lh_free(CHECKED_CAST(_LHASH *, LHASH_OF(CRYPTO_BUFFER) *, lh)); + +#define lh_CRYPTO_BUFFER_num_items(lh) \ + lh_num_items(CHECKED_CAST(_LHASH *, LHASH_OF(CRYPTO_BUFFER) *, lh)) + +#define lh_CRYPTO_BUFFER_retrieve(lh, data) \ + ((CRYPTO_BUFFER *)lh_retrieve( \ + CHECKED_CAST(_LHASH *, LHASH_OF(CRYPTO_BUFFER) *, lh), \ + CHECKED_CAST(void *, CRYPTO_BUFFER *, data))) + +#define lh_CRYPTO_BUFFER_insert(lh, old_data, data) \ + lh_insert(CHECKED_CAST(_LHASH *, LHASH_OF(CRYPTO_BUFFER) *, lh), \ + CHECKED_CAST(void **, CRYPTO_BUFFER **, old_data), \ + CHECKED_CAST(void *, CRYPTO_BUFFER *, data)) + +#define lh_CRYPTO_BUFFER_delete(lh, data) \ + ((CRYPTO_BUFFER *)lh_delete( \ + CHECKED_CAST(_LHASH *, LHASH_OF(CRYPTO_BUFFER) *, lh), \ + CHECKED_CAST(void *, CRYPTO_BUFFER *, data))) + +#define lh_CRYPTO_BUFFER_doall(lh, func) \ + lh_doall(CHECKED_CAST(_LHASH *, LHASH_OF(CRYPTO_BUFFER) *, lh), \ + CHECKED_CAST(void (*)(void *), void (*)(CRYPTO_BUFFER *), func)); + +#define lh_CRYPTO_BUFFER_doall_arg(lh, func, arg) \ + lh_doall_arg(CHECKED_CAST(_LHASH *, LHASH_OF(CRYPTO_BUFFER) *, lh), \ + CHECKED_CAST(void (*)(void *, void *), \ + void (*)(CRYPTO_BUFFER *, void *), func), \ + arg); + + +// SSL_SESSION +#define lh_SSL_SESSION_new(hash, comp) \ + ((LHASH_OF(SSL_SESSION) *)lh_new( \ + CHECKED_CAST(lhash_hash_func, uint32_t(*)(const SSL_SESSION *), hash), \ + CHECKED_CAST(lhash_cmp_func, \ + int (*)(const SSL_SESSION *a, const SSL_SESSION *b), \ + comp))) + +#define lh_SSL_SESSION_free(lh) \ + lh_free(CHECKED_CAST(_LHASH *, LHASH_OF(SSL_SESSION) *, lh)); + +#define lh_SSL_SESSION_num_items(lh) \ + lh_num_items(CHECKED_CAST(_LHASH *, LHASH_OF(SSL_SESSION) *, lh)) + +#define lh_SSL_SESSION_retrieve(lh, data) \ + ((SSL_SESSION *)lh_retrieve( \ + CHECKED_CAST(_LHASH *, LHASH_OF(SSL_SESSION) *, lh), \ + CHECKED_CAST(void *, SSL_SESSION *, data))) + +#define lh_SSL_SESSION_insert(lh, old_data, data) \ + lh_insert(CHECKED_CAST(_LHASH *, LHASH_OF(SSL_SESSION) *, lh), \ + CHECKED_CAST(void **, SSL_SESSION **, old_data), \ + CHECKED_CAST(void *, SSL_SESSION *, data)) + +#define lh_SSL_SESSION_delete(lh, data) \ + ((SSL_SESSION *)lh_delete( \ + CHECKED_CAST(_LHASH *, LHASH_OF(SSL_SESSION) *, lh), \ + CHECKED_CAST(void *, SSL_SESSION *, data))) + +#define lh_SSL_SESSION_doall(lh, func) \ + lh_doall(CHECKED_CAST(_LHASH *, LHASH_OF(SSL_SESSION) *, lh), \ + CHECKED_CAST(void (*)(void *), void (*)(SSL_SESSION *), func)); + +#define lh_SSL_SESSION_doall_arg(lh, func, arg) \ + lh_doall_arg(CHECKED_CAST(_LHASH *, LHASH_OF(SSL_SESSION) *, lh), \ + CHECKED_CAST(void (*)(void *, void *), \ + void (*)(SSL_SESSION *, void *), func), \ + arg); diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/lhash_macros.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/lhash_macros.h.grpc_back new file mode 100644 index 0000000..378c839 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/lhash_macros.h.grpc_back @@ -0,0 +1,174 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#if !defined(IN_LHASH_H) +#error "Don't include this file directly. Include lhash.h" +#endif + +// ASN1_OBJECT +#define lh_ASN1_OBJECT_new(hash, comp) \ + ((LHASH_OF(ASN1_OBJECT) *)lh_new( \ + CHECKED_CAST(lhash_hash_func, uint32_t(*)(const ASN1_OBJECT *), hash), \ + CHECKED_CAST(lhash_cmp_func, \ + int (*)(const ASN1_OBJECT *a, const ASN1_OBJECT *b), \ + comp))) + +#define lh_ASN1_OBJECT_free(lh) \ + lh_free(CHECKED_CAST(_LHASH *, LHASH_OF(ASN1_OBJECT) *, lh)); + +#define lh_ASN1_OBJECT_num_items(lh) \ + lh_num_items(CHECKED_CAST(_LHASH *, LHASH_OF(ASN1_OBJECT) *, lh)) + +#define lh_ASN1_OBJECT_retrieve(lh, data) \ + ((ASN1_OBJECT *)lh_retrieve( \ + CHECKED_CAST(_LHASH *, LHASH_OF(ASN1_OBJECT) *, lh), \ + CHECKED_CAST(void *, ASN1_OBJECT *, data))) + +#define lh_ASN1_OBJECT_insert(lh, old_data, data) \ + lh_insert(CHECKED_CAST(_LHASH *, LHASH_OF(ASN1_OBJECT) *, lh), \ + CHECKED_CAST(void **, ASN1_OBJECT **, old_data), \ + CHECKED_CAST(void *, ASN1_OBJECT *, data)) + +#define lh_ASN1_OBJECT_delete(lh, data) \ + ((ASN1_OBJECT *)lh_delete( \ + CHECKED_CAST(_LHASH *, LHASH_OF(ASN1_OBJECT) *, lh), \ + CHECKED_CAST(void *, ASN1_OBJECT *, data))) + +#define lh_ASN1_OBJECT_doall(lh, func) \ + lh_doall(CHECKED_CAST(_LHASH *, LHASH_OF(ASN1_OBJECT) *, lh), \ + CHECKED_CAST(void (*)(void *), void (*)(ASN1_OBJECT *), func)); + +#define lh_ASN1_OBJECT_doall_arg(lh, func, arg) \ + lh_doall_arg(CHECKED_CAST(_LHASH *, LHASH_OF(ASN1_OBJECT) *, lh), \ + CHECKED_CAST(void (*)(void *, void *), \ + void (*)(ASN1_OBJECT *, void *), func), \ + arg); + + +// CONF_VALUE +#define lh_CONF_VALUE_new(hash, comp) \ + ((LHASH_OF(CONF_VALUE) *)lh_new( \ + CHECKED_CAST(lhash_hash_func, uint32_t(*)(const CONF_VALUE *), hash), \ + CHECKED_CAST(lhash_cmp_func, \ + int (*)(const CONF_VALUE *a, const CONF_VALUE *b), comp))) + +#define lh_CONF_VALUE_free(lh) \ + lh_free(CHECKED_CAST(_LHASH *, LHASH_OF(CONF_VALUE) *, lh)); + +#define lh_CONF_VALUE_num_items(lh) \ + lh_num_items(CHECKED_CAST(_LHASH *, LHASH_OF(CONF_VALUE) *, lh)) + +#define lh_CONF_VALUE_retrieve(lh, data) \ + ((CONF_VALUE *)lh_retrieve( \ + CHECKED_CAST(_LHASH *, LHASH_OF(CONF_VALUE) *, lh), \ + CHECKED_CAST(void *, CONF_VALUE *, data))) + +#define lh_CONF_VALUE_insert(lh, old_data, data) \ + lh_insert(CHECKED_CAST(_LHASH *, LHASH_OF(CONF_VALUE) *, lh), \ + CHECKED_CAST(void **, CONF_VALUE **, old_data), \ + CHECKED_CAST(void *, CONF_VALUE *, data)) + +#define lh_CONF_VALUE_delete(lh, data) \ + ((CONF_VALUE *)lh_delete(CHECKED_CAST(_LHASH *, LHASH_OF(CONF_VALUE) *, lh), \ + CHECKED_CAST(void *, CONF_VALUE *, data))) + +#define lh_CONF_VALUE_doall(lh, func) \ + lh_doall(CHECKED_CAST(_LHASH *, LHASH_OF(CONF_VALUE) *, lh), \ + CHECKED_CAST(void (*)(void *), void (*)(CONF_VALUE *), func)); + +#define lh_CONF_VALUE_doall_arg(lh, func, arg) \ + lh_doall_arg(CHECKED_CAST(_LHASH *, LHASH_OF(CONF_VALUE) *, lh), \ + CHECKED_CAST(void (*)(void *, void *), \ + void (*)(CONF_VALUE *, void *), func), \ + arg); + + +// CRYPTO_BUFFER +#define lh_CRYPTO_BUFFER_new(hash, comp) \ + ((LHASH_OF(CRYPTO_BUFFER) *)lh_new( \ + CHECKED_CAST(lhash_hash_func, uint32_t(*)(const CRYPTO_BUFFER *), hash), \ + CHECKED_CAST(lhash_cmp_func, \ + int (*)(const CRYPTO_BUFFER *a, const CRYPTO_BUFFER *b), \ + comp))) + +#define lh_CRYPTO_BUFFER_free(lh) \ + lh_free(CHECKED_CAST(_LHASH *, LHASH_OF(CRYPTO_BUFFER) *, lh)); + +#define lh_CRYPTO_BUFFER_num_items(lh) \ + lh_num_items(CHECKED_CAST(_LHASH *, LHASH_OF(CRYPTO_BUFFER) *, lh)) + +#define lh_CRYPTO_BUFFER_retrieve(lh, data) \ + ((CRYPTO_BUFFER *)lh_retrieve( \ + CHECKED_CAST(_LHASH *, LHASH_OF(CRYPTO_BUFFER) *, lh), \ + CHECKED_CAST(void *, CRYPTO_BUFFER *, data))) + +#define lh_CRYPTO_BUFFER_insert(lh, old_data, data) \ + lh_insert(CHECKED_CAST(_LHASH *, LHASH_OF(CRYPTO_BUFFER) *, lh), \ + CHECKED_CAST(void **, CRYPTO_BUFFER **, old_data), \ + CHECKED_CAST(void *, CRYPTO_BUFFER *, data)) + +#define lh_CRYPTO_BUFFER_delete(lh, data) \ + ((CRYPTO_BUFFER *)lh_delete( \ + CHECKED_CAST(_LHASH *, LHASH_OF(CRYPTO_BUFFER) *, lh), \ + CHECKED_CAST(void *, CRYPTO_BUFFER *, data))) + +#define lh_CRYPTO_BUFFER_doall(lh, func) \ + lh_doall(CHECKED_CAST(_LHASH *, LHASH_OF(CRYPTO_BUFFER) *, lh), \ + CHECKED_CAST(void (*)(void *), void (*)(CRYPTO_BUFFER *), func)); + +#define lh_CRYPTO_BUFFER_doall_arg(lh, func, arg) \ + lh_doall_arg(CHECKED_CAST(_LHASH *, LHASH_OF(CRYPTO_BUFFER) *, lh), \ + CHECKED_CAST(void (*)(void *, void *), \ + void (*)(CRYPTO_BUFFER *, void *), func), \ + arg); + + +// SSL_SESSION +#define lh_SSL_SESSION_new(hash, comp) \ + ((LHASH_OF(SSL_SESSION) *)lh_new( \ + CHECKED_CAST(lhash_hash_func, uint32_t(*)(const SSL_SESSION *), hash), \ + CHECKED_CAST(lhash_cmp_func, \ + int (*)(const SSL_SESSION *a, const SSL_SESSION *b), \ + comp))) + +#define lh_SSL_SESSION_free(lh) \ + lh_free(CHECKED_CAST(_LHASH *, LHASH_OF(SSL_SESSION) *, lh)); + +#define lh_SSL_SESSION_num_items(lh) \ + lh_num_items(CHECKED_CAST(_LHASH *, LHASH_OF(SSL_SESSION) *, lh)) + +#define lh_SSL_SESSION_retrieve(lh, data) \ + ((SSL_SESSION *)lh_retrieve( \ + CHECKED_CAST(_LHASH *, LHASH_OF(SSL_SESSION) *, lh), \ + CHECKED_CAST(void *, SSL_SESSION *, data))) + +#define lh_SSL_SESSION_insert(lh, old_data, data) \ + lh_insert(CHECKED_CAST(_LHASH *, LHASH_OF(SSL_SESSION) *, lh), \ + CHECKED_CAST(void **, SSL_SESSION **, old_data), \ + CHECKED_CAST(void *, SSL_SESSION *, data)) + +#define lh_SSL_SESSION_delete(lh, data) \ + ((SSL_SESSION *)lh_delete( \ + CHECKED_CAST(_LHASH *, LHASH_OF(SSL_SESSION) *, lh), \ + CHECKED_CAST(void *, SSL_SESSION *, data))) + +#define lh_SSL_SESSION_doall(lh, func) \ + lh_doall(CHECKED_CAST(_LHASH *, LHASH_OF(SSL_SESSION) *, lh), \ + CHECKED_CAST(void (*)(void *), void (*)(SSL_SESSION *), func)); + +#define lh_SSL_SESSION_doall_arg(lh, func, arg) \ + lh_doall_arg(CHECKED_CAST(_LHASH *, LHASH_OF(SSL_SESSION) *, lh), \ + CHECKED_CAST(void (*)(void *, void *), \ + void (*)(SSL_SESSION *, void *), func), \ + arg); diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/md4.h b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/md4.h new file mode 100644 index 0000000..151f4e4 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/md4.h @@ -0,0 +1,106 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 OPENSSL_HEADER_MD4_H +#define OPENSSL_HEADER_MD4_H + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// MD4. + +// MD4_CBLOCK is the block size of MD4. +#define MD4_CBLOCK 64 + +// MD4_DIGEST_LENGTH is the length of an MD4 digest. +#define MD4_DIGEST_LENGTH 16 + +// MD4_Init initialises |md4| and returns one. +OPENSSL_EXPORT int MD4_Init(MD4_CTX *md4); + +// MD4_Update adds |len| bytes from |data| to |md4| and returns one. +OPENSSL_EXPORT int MD4_Update(MD4_CTX *md4, const void *data, size_t len); + +// MD4_Final adds the final padding to |md4| and writes the resulting digest to +// |md|, which must have at least |MD4_DIGEST_LENGTH| bytes of space. It +// returns one. +OPENSSL_EXPORT int MD4_Final(uint8_t *md, MD4_CTX *md4); + +// MD4 writes the digest of |len| bytes from |data| to |out| and returns |out|. +// There must be at least |MD4_DIGEST_LENGTH| bytes of space in |out|. +OPENSSL_EXPORT uint8_t *MD4(const uint8_t *data, size_t len, uint8_t *out); + +// MD4_Transform is a low-level function that performs a single, MD4 block +// transformation using the state from |md4| and 64 bytes from |block|. +OPENSSL_EXPORT void MD4_Transform(MD4_CTX *md4, const uint8_t *block); + +struct md4_state_st { + uint32_t h[4]; + uint32_t Nl, Nh; + uint8_t data[MD4_CBLOCK]; + unsigned num; +}; + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_MD4_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/md4.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/md4.h.grpc_back new file mode 100644 index 0000000..52b88ca --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/md4.h.grpc_back @@ -0,0 +1,106 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 OPENSSL_HEADER_MD4_H +#define OPENSSL_HEADER_MD4_H + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// MD4. + +// MD4_CBLOCK is the block size of MD4. +#define MD4_CBLOCK 64 + +// MD4_DIGEST_LENGTH is the length of an MD4 digest. +#define MD4_DIGEST_LENGTH 16 + +// MD4_Init initialises |md4| and returns one. +OPENSSL_EXPORT int MD4_Init(MD4_CTX *md4); + +// MD4_Update adds |len| bytes from |data| to |md4| and returns one. +OPENSSL_EXPORT int MD4_Update(MD4_CTX *md4, const void *data, size_t len); + +// MD4_Final adds the final padding to |md4| and writes the resulting digest to +// |md|, which must have at least |MD4_DIGEST_LENGTH| bytes of space. It +// returns one. +OPENSSL_EXPORT int MD4_Final(uint8_t *md, MD4_CTX *md4); + +// MD4 writes the digest of |len| bytes from |data| to |out| and returns |out|. +// There must be at least |MD4_DIGEST_LENGTH| bytes of space in |out|. +OPENSSL_EXPORT uint8_t *MD4(const uint8_t *data, size_t len, uint8_t *out); + +// MD4_Transform is a low-level function that performs a single, MD4 block +// transformation using the state from |md4| and 64 bytes from |block|. +OPENSSL_EXPORT void MD4_Transform(MD4_CTX *md4, const uint8_t *block); + +struct md4_state_st { + uint32_t h[4]; + uint32_t Nl, Nh; + uint8_t data[MD4_CBLOCK]; + unsigned num; +}; + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_MD4_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/md5.h b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/md5.h new file mode 100644 index 0000000..f4f33ee --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/md5.h @@ -0,0 +1,107 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 OPENSSL_HEADER_MD5_H +#define OPENSSL_HEADER_MD5_H + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// MD5. + + +// MD5_CBLOCK is the block size of MD5. +#define MD5_CBLOCK 64 + +// MD5_DIGEST_LENGTH is the length of an MD5 digest. +#define MD5_DIGEST_LENGTH 16 + +// MD5_Init initialises |md5| and returns one. +OPENSSL_EXPORT int MD5_Init(MD5_CTX *md5); + +// MD5_Update adds |len| bytes from |data| to |md5| and returns one. +OPENSSL_EXPORT int MD5_Update(MD5_CTX *md5, const void *data, size_t len); + +// MD5_Final adds the final padding to |md5| and writes the resulting digest to +// |md|, which must have at least |MD5_DIGEST_LENGTH| bytes of space. It +// returns one. +OPENSSL_EXPORT int MD5_Final(uint8_t *md, MD5_CTX *md5); + +// MD5 writes the digest of |len| bytes from |data| to |out| and returns |out|. +// There must be at least |MD5_DIGEST_LENGTH| bytes of space in |out|. +OPENSSL_EXPORT uint8_t *MD5(const uint8_t *data, size_t len, uint8_t *out); + +// MD5_Transform is a low-level function that performs a single, MD5 block +// transformation using the state from |md5| and 64 bytes from |block|. +OPENSSL_EXPORT void MD5_Transform(MD5_CTX *md5, const uint8_t *block); + +struct md5_state_st { + uint32_t h[4]; + uint32_t Nl, Nh; + uint8_t data[MD5_CBLOCK]; + unsigned num; +}; + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_MD5_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/md5.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/md5.h.grpc_back new file mode 100644 index 0000000..de6027f --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/md5.h.grpc_back @@ -0,0 +1,107 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 OPENSSL_HEADER_MD5_H +#define OPENSSL_HEADER_MD5_H + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// MD5. + + +// MD5_CBLOCK is the block size of MD5. +#define MD5_CBLOCK 64 + +// MD5_DIGEST_LENGTH is the length of an MD5 digest. +#define MD5_DIGEST_LENGTH 16 + +// MD5_Init initialises |md5| and returns one. +OPENSSL_EXPORT int MD5_Init(MD5_CTX *md5); + +// MD5_Update adds |len| bytes from |data| to |md5| and returns one. +OPENSSL_EXPORT int MD5_Update(MD5_CTX *md5, const void *data, size_t len); + +// MD5_Final adds the final padding to |md5| and writes the resulting digest to +// |md|, which must have at least |MD5_DIGEST_LENGTH| bytes of space. It +// returns one. +OPENSSL_EXPORT int MD5_Final(uint8_t *md, MD5_CTX *md5); + +// MD5 writes the digest of |len| bytes from |data| to |out| and returns |out|. +// There must be at least |MD5_DIGEST_LENGTH| bytes of space in |out|. +OPENSSL_EXPORT uint8_t *MD5(const uint8_t *data, size_t len, uint8_t *out); + +// MD5_Transform is a low-level function that performs a single, MD5 block +// transformation using the state from |md5| and 64 bytes from |block|. +OPENSSL_EXPORT void MD5_Transform(MD5_CTX *md5, const uint8_t *block); + +struct md5_state_st { + uint32_t h[4]; + uint32_t Nl, Nh; + uint8_t data[MD5_CBLOCK]; + unsigned num; +}; + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_MD5_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/mem.h b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/mem.h new file mode 100644 index 0000000..7b81e56 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/mem.h @@ -0,0 +1,156 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 OPENSSL_HEADER_MEM_H +#define OPENSSL_HEADER_MEM_H + +#include + +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// Memory and string functions, see also buf.h. +// +// BoringSSL has its own set of allocation functions, which keep track of +// allocation lengths and zero them out before freeing. All memory returned by +// BoringSSL API calls must therefore generally be freed using |OPENSSL_free| +// unless stated otherwise. + + +// OPENSSL_malloc acts like a regular |malloc|. +OPENSSL_EXPORT void *OPENSSL_malloc(size_t size); + +// OPENSSL_free does nothing if |ptr| is NULL. Otherwise it zeros out the +// memory allocated at |ptr| and frees it. +OPENSSL_EXPORT void OPENSSL_free(void *ptr); + +// OPENSSL_realloc returns a pointer to a buffer of |new_size| bytes that +// contains the contents of |ptr|. Unlike |realloc|, a new buffer is always +// allocated and the data at |ptr| is always wiped and freed. +OPENSSL_EXPORT void *OPENSSL_realloc(void *ptr, size_t new_size); + +// OPENSSL_cleanse zeros out |len| bytes of memory at |ptr|. This is similar to +// |memset_s| from C11. +OPENSSL_EXPORT void OPENSSL_cleanse(void *ptr, size_t len); + +// 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. +OPENSSL_EXPORT int CRYPTO_memcmp(const void *a, const void *b, size_t len); + +// OPENSSL_hash32 implements the 32 bit, FNV-1a hash. +OPENSSL_EXPORT uint32_t OPENSSL_hash32(const void *ptr, size_t len); + +// OPENSSL_strdup has the same behaviour as strdup(3). +OPENSSL_EXPORT char *OPENSSL_strdup(const char *s); + +// OPENSSL_strnlen has the same behaviour as strnlen(3). +OPENSSL_EXPORT size_t OPENSSL_strnlen(const char *s, size_t len); + +// OPENSSL_tolower is a locale-independent version of tolower(3). +OPENSSL_EXPORT int OPENSSL_tolower(int c); + +// OPENSSL_strcasecmp is a locale-independent version of strcasecmp(3). +OPENSSL_EXPORT int OPENSSL_strcasecmp(const char *a, const char *b); + +// OPENSSL_strncasecmp is a locale-independent version of strncasecmp(3). +OPENSSL_EXPORT int OPENSSL_strncasecmp(const char *a, const char *b, size_t n); + +// DECIMAL_SIZE returns an upper bound for the length of the decimal +// representation of the given type. +#define DECIMAL_SIZE(type) ((sizeof(type)*8+2)/3+1) + +// BIO_snprintf has the same behavior as snprintf(3). +OPENSSL_EXPORT int BIO_snprintf(char *buf, size_t n, const char *format, ...) + OPENSSL_PRINTF_FORMAT_FUNC(3, 4); + +// BIO_vsnprintf has the same behavior as vsnprintf(3). +OPENSSL_EXPORT int BIO_vsnprintf(char *buf, size_t n, const char *format, + va_list args) + OPENSSL_PRINTF_FORMAT_FUNC(3, 0); + + +// Deprecated functions. + +#define CRYPTO_malloc OPENSSL_malloc +#define CRYPTO_realloc OPENSSL_realloc +#define CRYPTO_free OPENSSL_free + + +#if defined(__cplusplus) +} // extern C + +extern "C++" { + +namespace bssl { + +BORINGSSL_MAKE_DELETER(char, OPENSSL_free) +BORINGSSL_MAKE_DELETER(uint8_t, OPENSSL_free) + +} // namespace bssl + +} // extern C++ + +#endif + +#endif // OPENSSL_HEADER_MEM_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/mem.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/mem.h.grpc_back new file mode 100644 index 0000000..7d7087e --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/mem.h.grpc_back @@ -0,0 +1,156 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 OPENSSL_HEADER_MEM_H +#define OPENSSL_HEADER_MEM_H + +#include + +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// Memory and string functions, see also buf.h. +// +// BoringSSL has its own set of allocation functions, which keep track of +// allocation lengths and zero them out before freeing. All memory returned by +// BoringSSL API calls must therefore generally be freed using |OPENSSL_free| +// unless stated otherwise. + + +// OPENSSL_malloc acts like a regular |malloc|. +OPENSSL_EXPORT void *OPENSSL_malloc(size_t size); + +// OPENSSL_free does nothing if |ptr| is NULL. Otherwise it zeros out the +// memory allocated at |ptr| and frees it. +OPENSSL_EXPORT void OPENSSL_free(void *ptr); + +// OPENSSL_realloc returns a pointer to a buffer of |new_size| bytes that +// contains the contents of |ptr|. Unlike |realloc|, a new buffer is always +// allocated and the data at |ptr| is always wiped and freed. +OPENSSL_EXPORT void *OPENSSL_realloc(void *ptr, size_t new_size); + +// OPENSSL_cleanse zeros out |len| bytes of memory at |ptr|. This is similar to +// |memset_s| from C11. +OPENSSL_EXPORT void OPENSSL_cleanse(void *ptr, size_t len); + +// 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. +OPENSSL_EXPORT int CRYPTO_memcmp(const void *a, const void *b, size_t len); + +// OPENSSL_hash32 implements the 32 bit, FNV-1a hash. +OPENSSL_EXPORT uint32_t OPENSSL_hash32(const void *ptr, size_t len); + +// OPENSSL_strdup has the same behaviour as strdup(3). +OPENSSL_EXPORT char *OPENSSL_strdup(const char *s); + +// OPENSSL_strnlen has the same behaviour as strnlen(3). +OPENSSL_EXPORT size_t OPENSSL_strnlen(const char *s, size_t len); + +// OPENSSL_tolower is a locale-independent version of tolower(3). +OPENSSL_EXPORT int OPENSSL_tolower(int c); + +// OPENSSL_strcasecmp is a locale-independent version of strcasecmp(3). +OPENSSL_EXPORT int OPENSSL_strcasecmp(const char *a, const char *b); + +// OPENSSL_strncasecmp is a locale-independent version of strncasecmp(3). +OPENSSL_EXPORT int OPENSSL_strncasecmp(const char *a, const char *b, size_t n); + +// DECIMAL_SIZE returns an upper bound for the length of the decimal +// representation of the given type. +#define DECIMAL_SIZE(type) ((sizeof(type)*8+2)/3+1) + +// BIO_snprintf has the same behavior as snprintf(3). +OPENSSL_EXPORT int BIO_snprintf(char *buf, size_t n, const char *format, ...) + OPENSSL_PRINTF_FORMAT_FUNC(3, 4); + +// BIO_vsnprintf has the same behavior as vsnprintf(3). +OPENSSL_EXPORT int BIO_vsnprintf(char *buf, size_t n, const char *format, + va_list args) + OPENSSL_PRINTF_FORMAT_FUNC(3, 0); + + +// Deprecated functions. + +#define CRYPTO_malloc OPENSSL_malloc +#define CRYPTO_realloc OPENSSL_realloc +#define CRYPTO_free OPENSSL_free + + +#if defined(__cplusplus) +} // extern C + +extern "C++" { + +namespace bssl { + +BORINGSSL_MAKE_DELETER(char, OPENSSL_free) +BORINGSSL_MAKE_DELETER(uint8_t, OPENSSL_free) + +} // namespace bssl + +} // extern C++ + +#endif + +#endif // OPENSSL_HEADER_MEM_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/nid.h b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/nid.h new file mode 100644 index 0000000..f035b5f --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/nid.h @@ -0,0 +1,4242 @@ +/* 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.] */ + +/* This file is generated by crypto/obj/objects.go. */ + +#ifndef OPENSSL_HEADER_NID_H +#define OPENSSL_HEADER_NID_H + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +/* The nid library provides numbered values for ASN.1 object identifiers and + * other symbols. These values are used by other libraries to identify + * cryptographic primitives. + * + * A separate objects library, obj.h, provides functions for converting between + * nids and object identifiers. However it depends on large internal tables with + * the encodings of every nid defined. Consumers concerned with binary size + * should instead embed the encodings of the few consumed OIDs and compare + * against those. + * + * These values should not be used outside of a single process; they are not + * stable identifiers. */ + + +#define SN_undef "UNDEF" +#define LN_undef "undefined" +#define NID_undef 0 +#define OBJ_undef 0L + +#define SN_rsadsi "rsadsi" +#define LN_rsadsi "RSA Data Security, Inc." +#define NID_rsadsi 1 +#define OBJ_rsadsi 1L, 2L, 840L, 113549L + +#define SN_pkcs "pkcs" +#define LN_pkcs "RSA Data Security, Inc. PKCS" +#define NID_pkcs 2 +#define OBJ_pkcs 1L, 2L, 840L, 113549L, 1L + +#define SN_md2 "MD2" +#define LN_md2 "md2" +#define NID_md2 3 +#define OBJ_md2 1L, 2L, 840L, 113549L, 2L, 2L + +#define SN_md5 "MD5" +#define LN_md5 "md5" +#define NID_md5 4 +#define OBJ_md5 1L, 2L, 840L, 113549L, 2L, 5L + +#define SN_rc4 "RC4" +#define LN_rc4 "rc4" +#define NID_rc4 5 +#define OBJ_rc4 1L, 2L, 840L, 113549L, 3L, 4L + +#define LN_rsaEncryption "rsaEncryption" +#define NID_rsaEncryption 6 +#define OBJ_rsaEncryption 1L, 2L, 840L, 113549L, 1L, 1L, 1L + +#define SN_md2WithRSAEncryption "RSA-MD2" +#define LN_md2WithRSAEncryption "md2WithRSAEncryption" +#define NID_md2WithRSAEncryption 7 +#define OBJ_md2WithRSAEncryption 1L, 2L, 840L, 113549L, 1L, 1L, 2L + +#define SN_md5WithRSAEncryption "RSA-MD5" +#define LN_md5WithRSAEncryption "md5WithRSAEncryption" +#define NID_md5WithRSAEncryption 8 +#define OBJ_md5WithRSAEncryption 1L, 2L, 840L, 113549L, 1L, 1L, 4L + +#define SN_pbeWithMD2AndDES_CBC "PBE-MD2-DES" +#define LN_pbeWithMD2AndDES_CBC "pbeWithMD2AndDES-CBC" +#define NID_pbeWithMD2AndDES_CBC 9 +#define OBJ_pbeWithMD2AndDES_CBC 1L, 2L, 840L, 113549L, 1L, 5L, 1L + +#define SN_pbeWithMD5AndDES_CBC "PBE-MD5-DES" +#define LN_pbeWithMD5AndDES_CBC "pbeWithMD5AndDES-CBC" +#define NID_pbeWithMD5AndDES_CBC 10 +#define OBJ_pbeWithMD5AndDES_CBC 1L, 2L, 840L, 113549L, 1L, 5L, 3L + +#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 2L, 5L, 4L + +#define SN_commonName "CN" +#define LN_commonName "commonName" +#define NID_commonName 13 +#define OBJ_commonName 2L, 5L, 4L, 3L + +#define SN_countryName "C" +#define LN_countryName "countryName" +#define NID_countryName 14 +#define OBJ_countryName 2L, 5L, 4L, 6L + +#define SN_localityName "L" +#define LN_localityName "localityName" +#define NID_localityName 15 +#define OBJ_localityName 2L, 5L, 4L, 7L + +#define SN_stateOrProvinceName "ST" +#define LN_stateOrProvinceName "stateOrProvinceName" +#define NID_stateOrProvinceName 16 +#define OBJ_stateOrProvinceName 2L, 5L, 4L, 8L + +#define SN_organizationName "O" +#define LN_organizationName "organizationName" +#define NID_organizationName 17 +#define OBJ_organizationName 2L, 5L, 4L, 10L + +#define SN_organizationalUnitName "OU" +#define LN_organizationalUnitName "organizationalUnitName" +#define NID_organizationalUnitName 18 +#define OBJ_organizationalUnitName 2L, 5L, 4L, 11L + +#define SN_rsa "RSA" +#define LN_rsa "rsa" +#define NID_rsa 19 +#define OBJ_rsa 2L, 5L, 8L, 1L, 1L + +#define SN_pkcs7 "pkcs7" +#define NID_pkcs7 20 +#define OBJ_pkcs7 1L, 2L, 840L, 113549L, 1L, 7L + +#define LN_pkcs7_data "pkcs7-data" +#define NID_pkcs7_data 21 +#define OBJ_pkcs7_data 1L, 2L, 840L, 113549L, 1L, 7L, 1L + +#define LN_pkcs7_signed "pkcs7-signedData" +#define NID_pkcs7_signed 22 +#define OBJ_pkcs7_signed 1L, 2L, 840L, 113549L, 1L, 7L, 2L + +#define LN_pkcs7_enveloped "pkcs7-envelopedData" +#define NID_pkcs7_enveloped 23 +#define OBJ_pkcs7_enveloped 1L, 2L, 840L, 113549L, 1L, 7L, 3L + +#define LN_pkcs7_signedAndEnveloped "pkcs7-signedAndEnvelopedData" +#define NID_pkcs7_signedAndEnveloped 24 +#define OBJ_pkcs7_signedAndEnveloped 1L, 2L, 840L, 113549L, 1L, 7L, 4L + +#define LN_pkcs7_digest "pkcs7-digestData" +#define NID_pkcs7_digest 25 +#define OBJ_pkcs7_digest 1L, 2L, 840L, 113549L, 1L, 7L, 5L + +#define LN_pkcs7_encrypted "pkcs7-encryptedData" +#define NID_pkcs7_encrypted 26 +#define OBJ_pkcs7_encrypted 1L, 2L, 840L, 113549L, 1L, 7L, 6L + +#define SN_pkcs3 "pkcs3" +#define NID_pkcs3 27 +#define OBJ_pkcs3 1L, 2L, 840L, 113549L, 1L, 3L + +#define LN_dhKeyAgreement "dhKeyAgreement" +#define NID_dhKeyAgreement 28 +#define OBJ_dhKeyAgreement 1L, 2L, 840L, 113549L, 1L, 3L, 1L + +#define SN_des_ecb "DES-ECB" +#define LN_des_ecb "des-ecb" +#define NID_des_ecb 29 +#define OBJ_des_ecb 1L, 3L, 14L, 3L, 2L, 6L + +#define SN_des_cfb64 "DES-CFB" +#define LN_des_cfb64 "des-cfb" +#define NID_des_cfb64 30 +#define OBJ_des_cfb64 1L, 3L, 14L, 3L, 2L, 9L + +#define SN_des_cbc "DES-CBC" +#define LN_des_cbc "des-cbc" +#define NID_des_cbc 31 +#define OBJ_des_cbc 1L, 3L, 14L, 3L, 2L, 7L + +#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 1L, 3L, 14L, 3L, 2L, 17L + +#define SN_des_ede3_ecb "DES-EDE3" +#define LN_des_ede3_ecb "des-ede3" +#define NID_des_ede3_ecb 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 1L, 2L, 840L, 113549L, 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 1L, 3L, 14L, 3L, 2L, 18L + +#define SN_shaWithRSAEncryption "RSA-SHA" +#define LN_shaWithRSAEncryption "shaWithRSAEncryption" +#define NID_shaWithRSAEncryption 42 +#define OBJ_shaWithRSAEncryption 1L, 3L, 14L, 3L, 2L, 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 1L, 2L, 840L, 113549L, 3L, 7L + +#define SN_des_ofb64 "DES-OFB" +#define LN_des_ofb64 "des-ofb" +#define NID_des_ofb64 45 +#define OBJ_des_ofb64 1L, 3L, 14L, 3L, 2L, 8L + +#define SN_idea_ofb64 "IDEA-OFB" +#define LN_idea_ofb64 "idea-ofb" +#define NID_idea_ofb64 46 + +#define SN_pkcs9 "pkcs9" +#define NID_pkcs9 47 +#define OBJ_pkcs9 1L, 2L, 840L, 113549L, 1L, 9L + +#define LN_pkcs9_emailAddress "emailAddress" +#define NID_pkcs9_emailAddress 48 +#define OBJ_pkcs9_emailAddress 1L, 2L, 840L, 113549L, 1L, 9L, 1L + +#define LN_pkcs9_unstructuredName "unstructuredName" +#define NID_pkcs9_unstructuredName 49 +#define OBJ_pkcs9_unstructuredName 1L, 2L, 840L, 113549L, 1L, 9L, 2L + +#define LN_pkcs9_contentType "contentType" +#define NID_pkcs9_contentType 50 +#define OBJ_pkcs9_contentType 1L, 2L, 840L, 113549L, 1L, 9L, 3L + +#define LN_pkcs9_messageDigest "messageDigest" +#define NID_pkcs9_messageDigest 51 +#define OBJ_pkcs9_messageDigest 1L, 2L, 840L, 113549L, 1L, 9L, 4L + +#define LN_pkcs9_signingTime "signingTime" +#define NID_pkcs9_signingTime 52 +#define OBJ_pkcs9_signingTime 1L, 2L, 840L, 113549L, 1L, 9L, 5L + +#define LN_pkcs9_countersignature "countersignature" +#define NID_pkcs9_countersignature 53 +#define OBJ_pkcs9_countersignature 1L, 2L, 840L, 113549L, 1L, 9L, 6L + +#define LN_pkcs9_challengePassword "challengePassword" +#define NID_pkcs9_challengePassword 54 +#define OBJ_pkcs9_challengePassword 1L, 2L, 840L, 113549L, 1L, 9L, 7L + +#define LN_pkcs9_unstructuredAddress "unstructuredAddress" +#define NID_pkcs9_unstructuredAddress 55 +#define OBJ_pkcs9_unstructuredAddress 1L, 2L, 840L, 113549L, 1L, 9L, 8L + +#define LN_pkcs9_extCertAttributes "extendedCertificateAttributes" +#define NID_pkcs9_extCertAttributes 56 +#define OBJ_pkcs9_extCertAttributes 1L, 2L, 840L, 113549L, 1L, 9L, 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 2L, 16L, 840L, 1L, 113730L, 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 2L, 16L, 840L, 1L, 113730L, 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 + +#define SN_sha1 "SHA1" +#define LN_sha1 "sha1" +#define NID_sha1 64 +#define OBJ_sha1 1L, 3L, 14L, 3L, 2L, 26L + +#define SN_sha1WithRSAEncryption "RSA-SHA1" +#define LN_sha1WithRSAEncryption "sha1WithRSAEncryption" +#define NID_sha1WithRSAEncryption 65 +#define OBJ_sha1WithRSAEncryption 1L, 2L, 840L, 113549L, 1L, 1L, 5L + +#define SN_dsaWithSHA "DSA-SHA" +#define LN_dsaWithSHA "dsaWithSHA" +#define NID_dsaWithSHA 66 +#define OBJ_dsaWithSHA 1L, 3L, 14L, 3L, 2L, 13L + +#define SN_dsa_2 "DSA-old" +#define LN_dsa_2 "dsaEncryption-old" +#define NID_dsa_2 67 +#define OBJ_dsa_2 1L, 3L, 14L, 3L, 2L, 12L + +#define SN_pbeWithSHA1AndRC2_CBC "PBE-SHA1-RC2-64" +#define LN_pbeWithSHA1AndRC2_CBC "pbeWithSHA1AndRC2-CBC" +#define NID_pbeWithSHA1AndRC2_CBC 68 +#define OBJ_pbeWithSHA1AndRC2_CBC 1L, 2L, 840L, 113549L, 1L, 5L, 11L + +#define LN_id_pbkdf2 "PBKDF2" +#define NID_id_pbkdf2 69 +#define OBJ_id_pbkdf2 1L, 2L, 840L, 113549L, 1L, 5L, 12L + +#define SN_dsaWithSHA1_2 "DSA-SHA1-old" +#define LN_dsaWithSHA1_2 "dsaWithSHA1-old" +#define NID_dsaWithSHA1_2 70 +#define OBJ_dsaWithSHA1_2 1L, 3L, 14L, 3L, 2L, 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 2L, 16L, 840L, 1L, 113730L, 1L, 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 2L, 16L, 840L, 1L, 113730L, 1L, 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 2L, 16L, 840L, 1L, 113730L, 1L, 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 2L, 16L, 840L, 1L, 113730L, 1L, 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 2L, 16L, 840L, 1L, 113730L, 1L, 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 2L, 16L, 840L, 1L, 113730L, 1L, 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 2L, 16L, 840L, 1L, 113730L, 1L, 12L + +#define SN_netscape_comment "nsComment" +#define LN_netscape_comment "Netscape Comment" +#define NID_netscape_comment 78 +#define OBJ_netscape_comment 2L, 16L, 840L, 1L, 113730L, 1L, 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 2L, 16L, 840L, 1L, 113730L, 2L, 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 2L, 5L, 29L, 14L + +#define SN_key_usage "keyUsage" +#define LN_key_usage "X509v3 Key Usage" +#define NID_key_usage 83 +#define OBJ_key_usage 2L, 5L, 29L, 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 2L, 5L, 29L, 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 2L, 5L, 29L, 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 2L, 5L, 29L, 18L + +#define SN_basic_constraints "basicConstraints" +#define LN_basic_constraints "X509v3 Basic Constraints" +#define NID_basic_constraints 87 +#define OBJ_basic_constraints 2L, 5L, 29L, 19L + +#define SN_crl_number "crlNumber" +#define LN_crl_number "X509v3 CRL Number" +#define NID_crl_number 88 +#define OBJ_crl_number 2L, 5L, 29L, 20L + +#define SN_certificate_policies "certificatePolicies" +#define LN_certificate_policies "X509v3 Certificate Policies" +#define NID_certificate_policies 89 +#define OBJ_certificate_policies 2L, 5L, 29L, 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 2L, 5L, 29L, 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 + +#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 "GN" +#define LN_givenName "givenName" +#define NID_givenName 99 +#define OBJ_givenName 2L, 5L, 4L, 42L + +#define SN_surname "SN" +#define LN_surname "surname" +#define NID_surname 100 +#define OBJ_surname 2L, 5L, 4L, 4L + +#define SN_initials "initials" +#define LN_initials "initials" +#define NID_initials 101 +#define OBJ_initials 2L, 5L, 4L, 43L + +#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 2L, 5L, 29L, 31L + +#define SN_md5WithRSA "RSA-NP-MD5" +#define LN_md5WithRSA "md5WithRSA" +#define NID_md5WithRSA 104 +#define OBJ_md5WithRSA 1L, 3L, 14L, 3L, 2L, 3L + +#define LN_serialNumber "serialNumber" +#define NID_serialNumber 105 +#define OBJ_serialNumber 2L, 5L, 4L, 5L + +#define SN_title "title" +#define LN_title "title" +#define NID_title 106 +#define OBJ_title 2L, 5L, 4L, 12L + +#define LN_description "description" +#define NID_description 107 +#define OBJ_description 2L, 5L, 4L, 13L + +#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 + +#define SN_dsaWithSHA1 "DSA-SHA1" +#define LN_dsaWithSHA1 "dsaWithSHA1" +#define NID_dsaWithSHA1 113 +#define OBJ_dsaWithSHA1 1L, 2L, 840L, 10040L, 4L, 3L + +#define SN_md5_sha1 "MD5-SHA1" +#define LN_md5_sha1 "md5-sha1" +#define NID_md5_sha1 114 + +#define SN_sha1WithRSA "RSA-SHA1-2" +#define LN_sha1WithRSA "sha1WithRSA" +#define NID_sha1WithRSA 115 +#define OBJ_sha1WithRSA 1L, 3L, 14L, 3L, 2L, 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 + +#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_rc5_cbc "RC5-CBC" +#define LN_rc5_cbc "rc5-cbc" +#define NID_rc5_cbc 120 +#define OBJ_rc5_cbc 1L, 2L, 840L, 113549L, 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_zlib_compression "ZLIB" +#define LN_zlib_compression "zlib compression" +#define NID_zlib_compression 125 +#define OBJ_zlib_compression 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 3L, 8L + +#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 2L, 5L, 29L, 37L + +#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 1L, 3L, 6L, 1L, 5L, 5L, 7L, 3L + +#define SN_server_auth "serverAuth" +#define LN_server_auth "TLS Web Server Authentication" +#define NID_server_auth 129 +#define OBJ_server_auth 1L, 3L, 6L, 1L, 5L, 5L, 7L, 3L, 1L + +#define SN_client_auth "clientAuth" +#define LN_client_auth "TLS Web Client Authentication" +#define NID_client_auth 130 +#define OBJ_client_auth 1L, 3L, 6L, 1L, 5L, 5L, 7L, 3L, 2L + +#define SN_code_sign "codeSigning" +#define LN_code_sign "Code Signing" +#define NID_code_sign 131 +#define OBJ_code_sign 1L, 3L, 6L, 1L, 5L, 5L, 7L, 3L, 3L + +#define SN_email_protect "emailProtection" +#define LN_email_protect "E-mail Protection" +#define NID_email_protect 132 +#define OBJ_email_protect 1L, 3L, 6L, 1L, 5L, 5L, 7L, 3L, 4L + +#define SN_time_stamp "timeStamping" +#define LN_time_stamp "Time Stamping" +#define NID_time_stamp 133 +#define OBJ_time_stamp 1L, 3L, 6L, 1L, 5L, 5L, 7L, 3L, 8L + +#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_ns_sgc "nsSGC" +#define LN_ns_sgc "Netscape Server Gated Crypto" +#define NID_ns_sgc 139 +#define OBJ_ns_sgc 2L, 16L, 840L, 1L, 113730L, 4L, 1L + +#define SN_delta_crl "deltaCRL" +#define LN_delta_crl "X509v3 Delta CRL Indicator" +#define NID_delta_crl 140 +#define OBJ_delta_crl 2L, 5L, 29L, 27L + +#define SN_crl_reason "CRLReason" +#define LN_crl_reason "X509v3 CRL Reason Code" +#define NID_crl_reason 141 +#define OBJ_crl_reason 2L, 5L, 29L, 21L + +#define SN_invalidity_date "invalidityDate" +#define LN_invalidity_date "Invalidity Date" +#define NID_invalidity_date 142 +#define OBJ_invalidity_date 2L, 5L, 29L, 24L + +#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_pbe_WithSHA1And128BitRC4 "PBE-SHA1-RC4-128" +#define LN_pbe_WithSHA1And128BitRC4 "pbeWithSHA1And128BitRC4" +#define NID_pbe_WithSHA1And128BitRC4 144 +#define OBJ_pbe_WithSHA1And128BitRC4 1L, 2L, 840L, 113549L, 1L, 12L, 1L, 1L + +#define SN_pbe_WithSHA1And40BitRC4 "PBE-SHA1-RC4-40" +#define LN_pbe_WithSHA1And40BitRC4 "pbeWithSHA1And40BitRC4" +#define NID_pbe_WithSHA1And40BitRC4 145 +#define OBJ_pbe_WithSHA1And40BitRC4 1L, 2L, 840L, 113549L, 1L, 12L, 1L, 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 \ + 1L, 2L, 840L, 113549L, 1L, 12L, 1L, 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 \ + 1L, 2L, 840L, 113549L, 1L, 12L, 1L, 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 1L, 2L, 840L, 113549L, 1L, 12L, 1L, 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 1L, 2L, 840L, 113549L, 1L, 12L, 1L, 6L + +#define LN_keyBag "keyBag" +#define NID_keyBag 150 +#define OBJ_keyBag 1L, 2L, 840L, 113549L, 1L, 12L, 10L, 1L, 1L + +#define LN_pkcs8ShroudedKeyBag "pkcs8ShroudedKeyBag" +#define NID_pkcs8ShroudedKeyBag 151 +#define OBJ_pkcs8ShroudedKeyBag 1L, 2L, 840L, 113549L, 1L, 12L, 10L, 1L, 2L + +#define LN_certBag "certBag" +#define NID_certBag 152 +#define OBJ_certBag 1L, 2L, 840L, 113549L, 1L, 12L, 10L, 1L, 3L + +#define LN_crlBag "crlBag" +#define NID_crlBag 153 +#define OBJ_crlBag 1L, 2L, 840L, 113549L, 1L, 12L, 10L, 1L, 4L + +#define LN_secretBag "secretBag" +#define NID_secretBag 154 +#define OBJ_secretBag 1L, 2L, 840L, 113549L, 1L, 12L, 10L, 1L, 5L + +#define LN_safeContentsBag "safeContentsBag" +#define NID_safeContentsBag 155 +#define OBJ_safeContentsBag 1L, 2L, 840L, 113549L, 1L, 12L, 10L, 1L, 6L + +#define LN_friendlyName "friendlyName" +#define NID_friendlyName 156 +#define OBJ_friendlyName 1L, 2L, 840L, 113549L, 1L, 9L, 20L + +#define LN_localKeyID "localKeyID" +#define NID_localKeyID 157 +#define OBJ_localKeyID 1L, 2L, 840L, 113549L, 1L, 9L, 21L + +#define LN_x509Certificate "x509Certificate" +#define NID_x509Certificate 158 +#define OBJ_x509Certificate 1L, 2L, 840L, 113549L, 1L, 9L, 22L, 1L + +#define LN_sdsiCertificate "sdsiCertificate" +#define NID_sdsiCertificate 159 +#define OBJ_sdsiCertificate 1L, 2L, 840L, 113549L, 1L, 9L, 22L, 2L + +#define LN_x509Crl "x509Crl" +#define NID_x509Crl 160 +#define OBJ_x509Crl 1L, 2L, 840L, 113549L, 1L, 9L, 23L, 1L + +#define LN_pbes2 "PBES2" +#define NID_pbes2 161 +#define OBJ_pbes2 1L, 2L, 840L, 113549L, 1L, 5L, 13L + +#define LN_pbmac1 "PBMAC1" +#define NID_pbmac1 162 +#define OBJ_pbmac1 1L, 2L, 840L, 113549L, 1L, 5L, 14L + +#define LN_hmacWithSHA1 "hmacWithSHA1" +#define NID_hmacWithSHA1 163 +#define OBJ_hmacWithSHA1 1L, 2L, 840L, 113549L, 2L, 7L + +#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 1L, 3L, 6L, 1L, 5L, 5L, 7L, 2L, 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 1L, 3L, 6L, 1L, 5L, 5L, 7L, 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 1L, 2L, 840L, 113549L, 1L, 9L, 15L + +#define SN_pbeWithMD2AndRC2_CBC "PBE-MD2-RC2-64" +#define LN_pbeWithMD2AndRC2_CBC "pbeWithMD2AndRC2-CBC" +#define NID_pbeWithMD2AndRC2_CBC 168 +#define OBJ_pbeWithMD2AndRC2_CBC 1L, 2L, 840L, 113549L, 1L, 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 1L, 2L, 840L, 113549L, 1L, 5L, 6L + +#define SN_pbeWithSHA1AndDES_CBC "PBE-SHA1-DES" +#define LN_pbeWithSHA1AndDES_CBC "pbeWithSHA1AndDES-CBC" +#define NID_pbeWithSHA1AndDES_CBC 170 +#define OBJ_pbeWithSHA1AndDES_CBC 1L, 2L, 840L, 113549L, 1L, 5L, 10L + +#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_ext_req "extReq" +#define LN_ext_req "Extension Request" +#define NID_ext_req 172 +#define OBJ_ext_req 1L, 2L, 840L, 113549L, 1L, 9L, 14L + +#define SN_name "name" +#define LN_name "name" +#define NID_name 173 +#define OBJ_name 2L, 5L, 4L, 41L + +#define SN_dnQualifier "dnQualifier" +#define LN_dnQualifier "dnQualifier" +#define NID_dnQualifier 174 +#define OBJ_dnQualifier 2L, 5L, 4L, 46L + +#define SN_id_pe "id-pe" +#define NID_id_pe 175 +#define OBJ_id_pe 1L, 3L, 6L, 1L, 5L, 5L, 7L, 1L + +#define SN_id_ad "id-ad" +#define NID_id_ad 176 +#define OBJ_id_ad 1L, 3L, 6L, 1L, 5L, 5L, 7L, 48L + +#define SN_info_access "authorityInfoAccess" +#define LN_info_access "Authority Information Access" +#define NID_info_access 177 +#define OBJ_info_access 1L, 3L, 6L, 1L, 5L, 5L, 7L, 1L, 1L + +#define SN_ad_OCSP "OCSP" +#define LN_ad_OCSP "OCSP" +#define NID_ad_OCSP 178 +#define OBJ_ad_OCSP 1L, 3L, 6L, 1L, 5L, 5L, 7L, 48L, 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 1L, 3L, 6L, 1L, 5L, 5L, 7L, 48L, 2L + +#define SN_OCSP_sign "OCSPSigning" +#define LN_OCSP_sign "OCSP Signing" +#define NID_OCSP_sign 180 +#define OBJ_OCSP_sign 1L, 3L, 6L, 1L, 5L, 5L, 7L, 3L, 9L + +#define SN_iso "ISO" +#define LN_iso "iso" +#define NID_iso 181 +#define OBJ_iso 1L + +#define SN_member_body "member-body" +#define LN_member_body "ISO Member Body" +#define NID_member_body 182 +#define OBJ_member_body 1L, 2L + +#define SN_ISO_US "ISO-US" +#define LN_ISO_US "ISO US Member Body" +#define NID_ISO_US 183 +#define OBJ_ISO_US 1L, 2L, 840L + +#define SN_X9_57 "X9-57" +#define LN_X9_57 "X9.57" +#define NID_X9_57 184 +#define OBJ_X9_57 1L, 2L, 840L, 10040L + +#define SN_X9cm "X9cm" +#define LN_X9cm "X9.57 CM ?" +#define NID_X9cm 185 +#define OBJ_X9cm 1L, 2L, 840L, 10040L, 4L + +#define SN_pkcs1 "pkcs1" +#define NID_pkcs1 186 +#define OBJ_pkcs1 1L, 2L, 840L, 113549L, 1L, 1L + +#define SN_pkcs5 "pkcs5" +#define NID_pkcs5 187 +#define OBJ_pkcs5 1L, 2L, 840L, 113549L, 1L, 5L + +#define SN_SMIME "SMIME" +#define LN_SMIME "S/MIME" +#define NID_SMIME 188 +#define OBJ_SMIME 1L, 2L, 840L, 113549L, 1L, 9L, 16L + +#define SN_id_smime_mod "id-smime-mod" +#define NID_id_smime_mod 189 +#define OBJ_id_smime_mod 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 0L + +#define SN_id_smime_ct "id-smime-ct" +#define NID_id_smime_ct 190 +#define OBJ_id_smime_ct 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 1L + +#define SN_id_smime_aa "id-smime-aa" +#define NID_id_smime_aa 191 +#define OBJ_id_smime_aa 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 2L + +#define SN_id_smime_alg "id-smime-alg" +#define NID_id_smime_alg 192 +#define OBJ_id_smime_alg 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 3L + +#define SN_id_smime_cd "id-smime-cd" +#define NID_id_smime_cd 193 +#define OBJ_id_smime_cd 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 4L + +#define SN_id_smime_spq "id-smime-spq" +#define NID_id_smime_spq 194 +#define OBJ_id_smime_spq 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 5L + +#define SN_id_smime_cti "id-smime-cti" +#define NID_id_smime_cti 195 +#define OBJ_id_smime_cti 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 6L + +#define SN_id_smime_mod_cms "id-smime-mod-cms" +#define NID_id_smime_mod_cms 196 +#define OBJ_id_smime_mod_cms 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 0L, 1L + +#define SN_id_smime_mod_ess "id-smime-mod-ess" +#define NID_id_smime_mod_ess 197 +#define OBJ_id_smime_mod_ess 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 0L, 2L + +#define SN_id_smime_mod_oid "id-smime-mod-oid" +#define NID_id_smime_mod_oid 198 +#define OBJ_id_smime_mod_oid 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 0L, 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 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 0L, 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 \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 0L, 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 \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 0L, 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 \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 0L, 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 \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 0L, 8L + +#define SN_id_smime_ct_receipt "id-smime-ct-receipt" +#define NID_id_smime_ct_receipt 204 +#define OBJ_id_smime_ct_receipt 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 1L, 1L + +#define SN_id_smime_ct_authData "id-smime-ct-authData" +#define NID_id_smime_ct_authData 205 +#define OBJ_id_smime_ct_authData 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 1L, 2L + +#define SN_id_smime_ct_publishCert "id-smime-ct-publishCert" +#define NID_id_smime_ct_publishCert 206 +#define OBJ_id_smime_ct_publishCert 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 1L, 3L + +#define SN_id_smime_ct_TSTInfo "id-smime-ct-TSTInfo" +#define NID_id_smime_ct_TSTInfo 207 +#define OBJ_id_smime_ct_TSTInfo 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 1L, 4L + +#define SN_id_smime_ct_TDTInfo "id-smime-ct-TDTInfo" +#define NID_id_smime_ct_TDTInfo 208 +#define OBJ_id_smime_ct_TDTInfo 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 1L, 5L + +#define SN_id_smime_ct_contentInfo "id-smime-ct-contentInfo" +#define NID_id_smime_ct_contentInfo 209 +#define OBJ_id_smime_ct_contentInfo 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 1L, 6L + +#define SN_id_smime_ct_DVCSRequestData "id-smime-ct-DVCSRequestData" +#define NID_id_smime_ct_DVCSRequestData 210 +#define OBJ_id_smime_ct_DVCSRequestData \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 1L, 7L + +#define SN_id_smime_ct_DVCSResponseData "id-smime-ct-DVCSResponseData" +#define NID_id_smime_ct_DVCSResponseData 211 +#define OBJ_id_smime_ct_DVCSResponseData \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 1L, 8L + +#define SN_id_smime_aa_receiptRequest "id-smime-aa-receiptRequest" +#define NID_id_smime_aa_receiptRequest 212 +#define OBJ_id_smime_aa_receiptRequest \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 2L, 1L + +#define SN_id_smime_aa_securityLabel "id-smime-aa-securityLabel" +#define NID_id_smime_aa_securityLabel 213 +#define OBJ_id_smime_aa_securityLabel 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 2L, 2L + +#define SN_id_smime_aa_mlExpandHistory "id-smime-aa-mlExpandHistory" +#define NID_id_smime_aa_mlExpandHistory 214 +#define OBJ_id_smime_aa_mlExpandHistory \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 2L, 3L + +#define SN_id_smime_aa_contentHint "id-smime-aa-contentHint" +#define NID_id_smime_aa_contentHint 215 +#define OBJ_id_smime_aa_contentHint 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 2L, 4L + +#define SN_id_smime_aa_msgSigDigest "id-smime-aa-msgSigDigest" +#define NID_id_smime_aa_msgSigDigest 216 +#define OBJ_id_smime_aa_msgSigDigest 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 2L, 5L + +#define SN_id_smime_aa_encapContentType "id-smime-aa-encapContentType" +#define NID_id_smime_aa_encapContentType 217 +#define OBJ_id_smime_aa_encapContentType \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 2L, 6L + +#define SN_id_smime_aa_contentIdentifier "id-smime-aa-contentIdentifier" +#define NID_id_smime_aa_contentIdentifier 218 +#define OBJ_id_smime_aa_contentIdentifier \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 2L, 7L + +#define SN_id_smime_aa_macValue "id-smime-aa-macValue" +#define NID_id_smime_aa_macValue 219 +#define OBJ_id_smime_aa_macValue 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 2L, 8L + +#define SN_id_smime_aa_equivalentLabels "id-smime-aa-equivalentLabels" +#define NID_id_smime_aa_equivalentLabels 220 +#define OBJ_id_smime_aa_equivalentLabels \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 2L, 9L + +#define SN_id_smime_aa_contentReference "id-smime-aa-contentReference" +#define NID_id_smime_aa_contentReference 221 +#define OBJ_id_smime_aa_contentReference \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 2L, 10L + +#define SN_id_smime_aa_encrypKeyPref "id-smime-aa-encrypKeyPref" +#define NID_id_smime_aa_encrypKeyPref 222 +#define OBJ_id_smime_aa_encrypKeyPref \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 2L, 11L + +#define SN_id_smime_aa_signingCertificate "id-smime-aa-signingCertificate" +#define NID_id_smime_aa_signingCertificate 223 +#define OBJ_id_smime_aa_signingCertificate \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 2L, 12L + +#define SN_id_smime_aa_smimeEncryptCerts "id-smime-aa-smimeEncryptCerts" +#define NID_id_smime_aa_smimeEncryptCerts 224 +#define OBJ_id_smime_aa_smimeEncryptCerts \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 2L, 13L + +#define SN_id_smime_aa_timeStampToken "id-smime-aa-timeStampToken" +#define NID_id_smime_aa_timeStampToken 225 +#define OBJ_id_smime_aa_timeStampToken \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 2L, 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 \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 2L, 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 \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 2L, 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 \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 2L, 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 \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 2L, 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 \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 2L, 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 \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 2L, 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 \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 2L, 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 \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 2L, 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 \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 2L, 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 \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 2L, 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 \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 2L, 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 \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 2L, 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 \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 2L, 27L + +#define SN_id_smime_aa_signatureType "id-smime-aa-signatureType" +#define NID_id_smime_aa_signatureType 239 +#define OBJ_id_smime_aa_signatureType \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 2L, 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 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 2L, 29L + +#define SN_id_smime_alg_ESDHwith3DES "id-smime-alg-ESDHwith3DES" +#define NID_id_smime_alg_ESDHwith3DES 241 +#define OBJ_id_smime_alg_ESDHwith3DES 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 3L, 1L + +#define SN_id_smime_alg_ESDHwithRC2 "id-smime-alg-ESDHwithRC2" +#define NID_id_smime_alg_ESDHwithRC2 242 +#define OBJ_id_smime_alg_ESDHwithRC2 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 3L, 2L + +#define SN_id_smime_alg_3DESwrap "id-smime-alg-3DESwrap" +#define NID_id_smime_alg_3DESwrap 243 +#define OBJ_id_smime_alg_3DESwrap 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 3L, 3L + +#define SN_id_smime_alg_RC2wrap "id-smime-alg-RC2wrap" +#define NID_id_smime_alg_RC2wrap 244 +#define OBJ_id_smime_alg_RC2wrap 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 3L, 4L + +#define SN_id_smime_alg_ESDH "id-smime-alg-ESDH" +#define NID_id_smime_alg_ESDH 245 +#define OBJ_id_smime_alg_ESDH 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 3L, 5L + +#define SN_id_smime_alg_CMS3DESwrap "id-smime-alg-CMS3DESwrap" +#define NID_id_smime_alg_CMS3DESwrap 246 +#define OBJ_id_smime_alg_CMS3DESwrap 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 3L, 6L + +#define SN_id_smime_alg_CMSRC2wrap "id-smime-alg-CMSRC2wrap" +#define NID_id_smime_alg_CMSRC2wrap 247 +#define OBJ_id_smime_alg_CMSRC2wrap 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 3L, 7L + +#define SN_id_smime_cd_ldap "id-smime-cd-ldap" +#define NID_id_smime_cd_ldap 248 +#define OBJ_id_smime_cd_ldap 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 4L, 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 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 5L, 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 \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 5L, 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 \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 6L, 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 \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 6L, 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 \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 6L, 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 \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 6L, 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 \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 6L, 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 \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 6L, 6L + +#define SN_md4 "MD4" +#define LN_md4 "md4" +#define NID_md4 257 +#define OBJ_md4 1L, 2L, 840L, 113549L, 2L, 4L + +#define SN_id_pkix_mod "id-pkix-mod" +#define NID_id_pkix_mod 258 +#define OBJ_id_pkix_mod 1L, 3L, 6L, 1L, 5L, 5L, 7L, 0L + +#define SN_id_qt "id-qt" +#define NID_id_qt 259 +#define OBJ_id_qt 1L, 3L, 6L, 1L, 5L, 5L, 7L, 2L + +#define SN_id_it "id-it" +#define NID_id_it 260 +#define OBJ_id_it 1L, 3L, 6L, 1L, 5L, 5L, 7L, 4L + +#define SN_id_pkip "id-pkip" +#define NID_id_pkip 261 +#define OBJ_id_pkip 1L, 3L, 6L, 1L, 5L, 5L, 7L, 5L + +#define SN_id_alg "id-alg" +#define NID_id_alg 262 +#define OBJ_id_alg 1L, 3L, 6L, 1L, 5L, 5L, 7L, 6L + +#define SN_id_cmc "id-cmc" +#define NID_id_cmc 263 +#define OBJ_id_cmc 1L, 3L, 6L, 1L, 5L, 5L, 7L, 7L + +#define SN_id_on "id-on" +#define NID_id_on 264 +#define OBJ_id_on 1L, 3L, 6L, 1L, 5L, 5L, 7L, 8L + +#define SN_id_pda "id-pda" +#define NID_id_pda 265 +#define OBJ_id_pda 1L, 3L, 6L, 1L, 5L, 5L, 7L, 9L + +#define SN_id_aca "id-aca" +#define NID_id_aca 266 +#define OBJ_id_aca 1L, 3L, 6L, 1L, 5L, 5L, 7L, 10L + +#define SN_id_qcs "id-qcs" +#define NID_id_qcs 267 +#define OBJ_id_qcs 1L, 3L, 6L, 1L, 5L, 5L, 7L, 11L + +#define SN_id_cct "id-cct" +#define NID_id_cct 268 +#define OBJ_id_cct 1L, 3L, 6L, 1L, 5L, 5L, 7L, 12L + +#define SN_id_pkix1_explicit_88 "id-pkix1-explicit-88" +#define NID_id_pkix1_explicit_88 269 +#define OBJ_id_pkix1_explicit_88 1L, 3L, 6L, 1L, 5L, 5L, 7L, 0L, 1L + +#define SN_id_pkix1_implicit_88 "id-pkix1-implicit-88" +#define NID_id_pkix1_implicit_88 270 +#define OBJ_id_pkix1_implicit_88 1L, 3L, 6L, 1L, 5L, 5L, 7L, 0L, 2L + +#define SN_id_pkix1_explicit_93 "id-pkix1-explicit-93" +#define NID_id_pkix1_explicit_93 271 +#define OBJ_id_pkix1_explicit_93 1L, 3L, 6L, 1L, 5L, 5L, 7L, 0L, 3L + +#define SN_id_pkix1_implicit_93 "id-pkix1-implicit-93" +#define NID_id_pkix1_implicit_93 272 +#define OBJ_id_pkix1_implicit_93 1L, 3L, 6L, 1L, 5L, 5L, 7L, 0L, 4L + +#define SN_id_mod_crmf "id-mod-crmf" +#define NID_id_mod_crmf 273 +#define OBJ_id_mod_crmf 1L, 3L, 6L, 1L, 5L, 5L, 7L, 0L, 5L + +#define SN_id_mod_cmc "id-mod-cmc" +#define NID_id_mod_cmc 274 +#define OBJ_id_mod_cmc 1L, 3L, 6L, 1L, 5L, 5L, 7L, 0L, 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 1L, 3L, 6L, 1L, 5L, 5L, 7L, 0L, 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 1L, 3L, 6L, 1L, 5L, 5L, 7L, 0L, 8L + +#define SN_id_mod_cmp "id-mod-cmp" +#define NID_id_mod_cmp 277 +#define OBJ_id_mod_cmp 1L, 3L, 6L, 1L, 5L, 5L, 7L, 0L, 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 1L, 3L, 6L, 1L, 5L, 5L, 7L, 0L, 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 1L, 3L, 6L, 1L, 5L, 5L, 7L, 0L, 11L + +#define SN_id_mod_attribute_cert "id-mod-attribute-cert" +#define NID_id_mod_attribute_cert 280 +#define OBJ_id_mod_attribute_cert 1L, 3L, 6L, 1L, 5L, 5L, 7L, 0L, 12L + +#define SN_id_mod_timestamp_protocol "id-mod-timestamp-protocol" +#define NID_id_mod_timestamp_protocol 281 +#define OBJ_id_mod_timestamp_protocol 1L, 3L, 6L, 1L, 5L, 5L, 7L, 0L, 13L + +#define SN_id_mod_ocsp "id-mod-ocsp" +#define NID_id_mod_ocsp 282 +#define OBJ_id_mod_ocsp 1L, 3L, 6L, 1L, 5L, 5L, 7L, 0L, 14L + +#define SN_id_mod_dvcs "id-mod-dvcs" +#define NID_id_mod_dvcs 283 +#define OBJ_id_mod_dvcs 1L, 3L, 6L, 1L, 5L, 5L, 7L, 0L, 15L + +#define SN_id_mod_cmp2000 "id-mod-cmp2000" +#define NID_id_mod_cmp2000 284 +#define OBJ_id_mod_cmp2000 1L, 3L, 6L, 1L, 5L, 5L, 7L, 0L, 16L + +#define SN_biometricInfo "biometricInfo" +#define LN_biometricInfo "Biometric Info" +#define NID_biometricInfo 285 +#define OBJ_biometricInfo 1L, 3L, 6L, 1L, 5L, 5L, 7L, 1L, 2L + +#define SN_qcStatements "qcStatements" +#define NID_qcStatements 286 +#define OBJ_qcStatements 1L, 3L, 6L, 1L, 5L, 5L, 7L, 1L, 3L + +#define SN_ac_auditEntity "ac-auditEntity" +#define NID_ac_auditEntity 287 +#define OBJ_ac_auditEntity 1L, 3L, 6L, 1L, 5L, 5L, 7L, 1L, 4L + +#define SN_ac_targeting "ac-targeting" +#define NID_ac_targeting 288 +#define OBJ_ac_targeting 1L, 3L, 6L, 1L, 5L, 5L, 7L, 1L, 5L + +#define SN_aaControls "aaControls" +#define NID_aaControls 289 +#define OBJ_aaControls 1L, 3L, 6L, 1L, 5L, 5L, 7L, 1L, 6L + +#define SN_sbgp_ipAddrBlock "sbgp-ipAddrBlock" +#define NID_sbgp_ipAddrBlock 290 +#define OBJ_sbgp_ipAddrBlock 1L, 3L, 6L, 1L, 5L, 5L, 7L, 1L, 7L + +#define SN_sbgp_autonomousSysNum "sbgp-autonomousSysNum" +#define NID_sbgp_autonomousSysNum 291 +#define OBJ_sbgp_autonomousSysNum 1L, 3L, 6L, 1L, 5L, 5L, 7L, 1L, 8L + +#define SN_sbgp_routerIdentifier "sbgp-routerIdentifier" +#define NID_sbgp_routerIdentifier 292 +#define OBJ_sbgp_routerIdentifier 1L, 3L, 6L, 1L, 5L, 5L, 7L, 1L, 9L + +#define SN_textNotice "textNotice" +#define NID_textNotice 293 +#define OBJ_textNotice 1L, 3L, 6L, 1L, 5L, 5L, 7L, 2L, 3L + +#define SN_ipsecEndSystem "ipsecEndSystem" +#define LN_ipsecEndSystem "IPSec End System" +#define NID_ipsecEndSystem 294 +#define OBJ_ipsecEndSystem 1L, 3L, 6L, 1L, 5L, 5L, 7L, 3L, 5L + +#define SN_ipsecTunnel "ipsecTunnel" +#define LN_ipsecTunnel "IPSec Tunnel" +#define NID_ipsecTunnel 295 +#define OBJ_ipsecTunnel 1L, 3L, 6L, 1L, 5L, 5L, 7L, 3L, 6L + +#define SN_ipsecUser "ipsecUser" +#define LN_ipsecUser "IPSec User" +#define NID_ipsecUser 296 +#define OBJ_ipsecUser 1L, 3L, 6L, 1L, 5L, 5L, 7L, 3L, 7L + +#define SN_dvcs "DVCS" +#define LN_dvcs "dvcs" +#define NID_dvcs 297 +#define OBJ_dvcs 1L, 3L, 6L, 1L, 5L, 5L, 7L, 3L, 10L + +#define SN_id_it_caProtEncCert "id-it-caProtEncCert" +#define NID_id_it_caProtEncCert 298 +#define OBJ_id_it_caProtEncCert 1L, 3L, 6L, 1L, 5L, 5L, 7L, 4L, 1L + +#define SN_id_it_signKeyPairTypes "id-it-signKeyPairTypes" +#define NID_id_it_signKeyPairTypes 299 +#define OBJ_id_it_signKeyPairTypes 1L, 3L, 6L, 1L, 5L, 5L, 7L, 4L, 2L + +#define SN_id_it_encKeyPairTypes "id-it-encKeyPairTypes" +#define NID_id_it_encKeyPairTypes 300 +#define OBJ_id_it_encKeyPairTypes 1L, 3L, 6L, 1L, 5L, 5L, 7L, 4L, 3L + +#define SN_id_it_preferredSymmAlg "id-it-preferredSymmAlg" +#define NID_id_it_preferredSymmAlg 301 +#define OBJ_id_it_preferredSymmAlg 1L, 3L, 6L, 1L, 5L, 5L, 7L, 4L, 4L + +#define SN_id_it_caKeyUpdateInfo "id-it-caKeyUpdateInfo" +#define NID_id_it_caKeyUpdateInfo 302 +#define OBJ_id_it_caKeyUpdateInfo 1L, 3L, 6L, 1L, 5L, 5L, 7L, 4L, 5L + +#define SN_id_it_currentCRL "id-it-currentCRL" +#define NID_id_it_currentCRL 303 +#define OBJ_id_it_currentCRL 1L, 3L, 6L, 1L, 5L, 5L, 7L, 4L, 6L + +#define SN_id_it_unsupportedOIDs "id-it-unsupportedOIDs" +#define NID_id_it_unsupportedOIDs 304 +#define OBJ_id_it_unsupportedOIDs 1L, 3L, 6L, 1L, 5L, 5L, 7L, 4L, 7L + +#define SN_id_it_subscriptionRequest "id-it-subscriptionRequest" +#define NID_id_it_subscriptionRequest 305 +#define OBJ_id_it_subscriptionRequest 1L, 3L, 6L, 1L, 5L, 5L, 7L, 4L, 8L + +#define SN_id_it_subscriptionResponse "id-it-subscriptionResponse" +#define NID_id_it_subscriptionResponse 306 +#define OBJ_id_it_subscriptionResponse 1L, 3L, 6L, 1L, 5L, 5L, 7L, 4L, 9L + +#define SN_id_it_keyPairParamReq "id-it-keyPairParamReq" +#define NID_id_it_keyPairParamReq 307 +#define OBJ_id_it_keyPairParamReq 1L, 3L, 6L, 1L, 5L, 5L, 7L, 4L, 10L + +#define SN_id_it_keyPairParamRep "id-it-keyPairParamRep" +#define NID_id_it_keyPairParamRep 308 +#define OBJ_id_it_keyPairParamRep 1L, 3L, 6L, 1L, 5L, 5L, 7L, 4L, 11L + +#define SN_id_it_revPassphrase "id-it-revPassphrase" +#define NID_id_it_revPassphrase 309 +#define OBJ_id_it_revPassphrase 1L, 3L, 6L, 1L, 5L, 5L, 7L, 4L, 12L + +#define SN_id_it_implicitConfirm "id-it-implicitConfirm" +#define NID_id_it_implicitConfirm 310 +#define OBJ_id_it_implicitConfirm 1L, 3L, 6L, 1L, 5L, 5L, 7L, 4L, 13L + +#define SN_id_it_confirmWaitTime "id-it-confirmWaitTime" +#define NID_id_it_confirmWaitTime 311 +#define OBJ_id_it_confirmWaitTime 1L, 3L, 6L, 1L, 5L, 5L, 7L, 4L, 14L + +#define SN_id_it_origPKIMessage "id-it-origPKIMessage" +#define NID_id_it_origPKIMessage 312 +#define OBJ_id_it_origPKIMessage 1L, 3L, 6L, 1L, 5L, 5L, 7L, 4L, 15L + +#define SN_id_regCtrl "id-regCtrl" +#define NID_id_regCtrl 313 +#define OBJ_id_regCtrl 1L, 3L, 6L, 1L, 5L, 5L, 7L, 5L, 1L + +#define SN_id_regInfo "id-regInfo" +#define NID_id_regInfo 314 +#define OBJ_id_regInfo 1L, 3L, 6L, 1L, 5L, 5L, 7L, 5L, 2L + +#define SN_id_regCtrl_regToken "id-regCtrl-regToken" +#define NID_id_regCtrl_regToken 315 +#define OBJ_id_regCtrl_regToken 1L, 3L, 6L, 1L, 5L, 5L, 7L, 5L, 1L, 1L + +#define SN_id_regCtrl_authenticator "id-regCtrl-authenticator" +#define NID_id_regCtrl_authenticator 316 +#define OBJ_id_regCtrl_authenticator 1L, 3L, 6L, 1L, 5L, 5L, 7L, 5L, 1L, 2L + +#define SN_id_regCtrl_pkiPublicationInfo "id-regCtrl-pkiPublicationInfo" +#define NID_id_regCtrl_pkiPublicationInfo 317 +#define OBJ_id_regCtrl_pkiPublicationInfo 1L, 3L, 6L, 1L, 5L, 5L, 7L, 5L, 1L, 3L + +#define SN_id_regCtrl_pkiArchiveOptions "id-regCtrl-pkiArchiveOptions" +#define NID_id_regCtrl_pkiArchiveOptions 318 +#define OBJ_id_regCtrl_pkiArchiveOptions 1L, 3L, 6L, 1L, 5L, 5L, 7L, 5L, 1L, 4L + +#define SN_id_regCtrl_oldCertID "id-regCtrl-oldCertID" +#define NID_id_regCtrl_oldCertID 319 +#define OBJ_id_regCtrl_oldCertID 1L, 3L, 6L, 1L, 5L, 5L, 7L, 5L, 1L, 5L + +#define SN_id_regCtrl_protocolEncrKey "id-regCtrl-protocolEncrKey" +#define NID_id_regCtrl_protocolEncrKey 320 +#define OBJ_id_regCtrl_protocolEncrKey 1L, 3L, 6L, 1L, 5L, 5L, 7L, 5L, 1L, 6L + +#define SN_id_regInfo_utf8Pairs "id-regInfo-utf8Pairs" +#define NID_id_regInfo_utf8Pairs 321 +#define OBJ_id_regInfo_utf8Pairs 1L, 3L, 6L, 1L, 5L, 5L, 7L, 5L, 2L, 1L + +#define SN_id_regInfo_certReq "id-regInfo-certReq" +#define NID_id_regInfo_certReq 322 +#define OBJ_id_regInfo_certReq 1L, 3L, 6L, 1L, 5L, 5L, 7L, 5L, 2L, 2L + +#define SN_id_alg_des40 "id-alg-des40" +#define NID_id_alg_des40 323 +#define OBJ_id_alg_des40 1L, 3L, 6L, 1L, 5L, 5L, 7L, 6L, 1L + +#define SN_id_alg_noSignature "id-alg-noSignature" +#define NID_id_alg_noSignature 324 +#define OBJ_id_alg_noSignature 1L, 3L, 6L, 1L, 5L, 5L, 7L, 6L, 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 1L, 3L, 6L, 1L, 5L, 5L, 7L, 6L, 3L + +#define SN_id_alg_dh_pop "id-alg-dh-pop" +#define NID_id_alg_dh_pop 326 +#define OBJ_id_alg_dh_pop 1L, 3L, 6L, 1L, 5L, 5L, 7L, 6L, 4L + +#define SN_id_cmc_statusInfo "id-cmc-statusInfo" +#define NID_id_cmc_statusInfo 327 +#define OBJ_id_cmc_statusInfo 1L, 3L, 6L, 1L, 5L, 5L, 7L, 7L, 1L + +#define SN_id_cmc_identification "id-cmc-identification" +#define NID_id_cmc_identification 328 +#define OBJ_id_cmc_identification 1L, 3L, 6L, 1L, 5L, 5L, 7L, 7L, 2L + +#define SN_id_cmc_identityProof "id-cmc-identityProof" +#define NID_id_cmc_identityProof 329 +#define OBJ_id_cmc_identityProof 1L, 3L, 6L, 1L, 5L, 5L, 7L, 7L, 3L + +#define SN_id_cmc_dataReturn "id-cmc-dataReturn" +#define NID_id_cmc_dataReturn 330 +#define OBJ_id_cmc_dataReturn 1L, 3L, 6L, 1L, 5L, 5L, 7L, 7L, 4L + +#define SN_id_cmc_transactionId "id-cmc-transactionId" +#define NID_id_cmc_transactionId 331 +#define OBJ_id_cmc_transactionId 1L, 3L, 6L, 1L, 5L, 5L, 7L, 7L, 5L + +#define SN_id_cmc_senderNonce "id-cmc-senderNonce" +#define NID_id_cmc_senderNonce 332 +#define OBJ_id_cmc_senderNonce 1L, 3L, 6L, 1L, 5L, 5L, 7L, 7L, 6L + +#define SN_id_cmc_recipientNonce "id-cmc-recipientNonce" +#define NID_id_cmc_recipientNonce 333 +#define OBJ_id_cmc_recipientNonce 1L, 3L, 6L, 1L, 5L, 5L, 7L, 7L, 7L + +#define SN_id_cmc_addExtensions "id-cmc-addExtensions" +#define NID_id_cmc_addExtensions 334 +#define OBJ_id_cmc_addExtensions 1L, 3L, 6L, 1L, 5L, 5L, 7L, 7L, 8L + +#define SN_id_cmc_encryptedPOP "id-cmc-encryptedPOP" +#define NID_id_cmc_encryptedPOP 335 +#define OBJ_id_cmc_encryptedPOP 1L, 3L, 6L, 1L, 5L, 5L, 7L, 7L, 9L + +#define SN_id_cmc_decryptedPOP "id-cmc-decryptedPOP" +#define NID_id_cmc_decryptedPOP 336 +#define OBJ_id_cmc_decryptedPOP 1L, 3L, 6L, 1L, 5L, 5L, 7L, 7L, 10L + +#define SN_id_cmc_lraPOPWitness "id-cmc-lraPOPWitness" +#define NID_id_cmc_lraPOPWitness 337 +#define OBJ_id_cmc_lraPOPWitness 1L, 3L, 6L, 1L, 5L, 5L, 7L, 7L, 11L + +#define SN_id_cmc_getCert "id-cmc-getCert" +#define NID_id_cmc_getCert 338 +#define OBJ_id_cmc_getCert 1L, 3L, 6L, 1L, 5L, 5L, 7L, 7L, 15L + +#define SN_id_cmc_getCRL "id-cmc-getCRL" +#define NID_id_cmc_getCRL 339 +#define OBJ_id_cmc_getCRL 1L, 3L, 6L, 1L, 5L, 5L, 7L, 7L, 16L + +#define SN_id_cmc_revokeRequest "id-cmc-revokeRequest" +#define NID_id_cmc_revokeRequest 340 +#define OBJ_id_cmc_revokeRequest 1L, 3L, 6L, 1L, 5L, 5L, 7L, 7L, 17L + +#define SN_id_cmc_regInfo "id-cmc-regInfo" +#define NID_id_cmc_regInfo 341 +#define OBJ_id_cmc_regInfo 1L, 3L, 6L, 1L, 5L, 5L, 7L, 7L, 18L + +#define SN_id_cmc_responseInfo "id-cmc-responseInfo" +#define NID_id_cmc_responseInfo 342 +#define OBJ_id_cmc_responseInfo 1L, 3L, 6L, 1L, 5L, 5L, 7L, 7L, 19L + +#define SN_id_cmc_queryPending "id-cmc-queryPending" +#define NID_id_cmc_queryPending 343 +#define OBJ_id_cmc_queryPending 1L, 3L, 6L, 1L, 5L, 5L, 7L, 7L, 21L + +#define SN_id_cmc_popLinkRandom "id-cmc-popLinkRandom" +#define NID_id_cmc_popLinkRandom 344 +#define OBJ_id_cmc_popLinkRandom 1L, 3L, 6L, 1L, 5L, 5L, 7L, 7L, 22L + +#define SN_id_cmc_popLinkWitness "id-cmc-popLinkWitness" +#define NID_id_cmc_popLinkWitness 345 +#define OBJ_id_cmc_popLinkWitness 1L, 3L, 6L, 1L, 5L, 5L, 7L, 7L, 23L + +#define SN_id_cmc_confirmCertAcceptance "id-cmc-confirmCertAcceptance" +#define NID_id_cmc_confirmCertAcceptance 346 +#define OBJ_id_cmc_confirmCertAcceptance 1L, 3L, 6L, 1L, 5L, 5L, 7L, 7L, 24L + +#define SN_id_on_personalData "id-on-personalData" +#define NID_id_on_personalData 347 +#define OBJ_id_on_personalData 1L, 3L, 6L, 1L, 5L, 5L, 7L, 8L, 1L + +#define SN_id_pda_dateOfBirth "id-pda-dateOfBirth" +#define NID_id_pda_dateOfBirth 348 +#define OBJ_id_pda_dateOfBirth 1L, 3L, 6L, 1L, 5L, 5L, 7L, 9L, 1L + +#define SN_id_pda_placeOfBirth "id-pda-placeOfBirth" +#define NID_id_pda_placeOfBirth 349 +#define OBJ_id_pda_placeOfBirth 1L, 3L, 6L, 1L, 5L, 5L, 7L, 9L, 2L + +#define SN_id_pda_gender "id-pda-gender" +#define NID_id_pda_gender 351 +#define OBJ_id_pda_gender 1L, 3L, 6L, 1L, 5L, 5L, 7L, 9L, 3L + +#define SN_id_pda_countryOfCitizenship "id-pda-countryOfCitizenship" +#define NID_id_pda_countryOfCitizenship 352 +#define OBJ_id_pda_countryOfCitizenship 1L, 3L, 6L, 1L, 5L, 5L, 7L, 9L, 4L + +#define SN_id_pda_countryOfResidence "id-pda-countryOfResidence" +#define NID_id_pda_countryOfResidence 353 +#define OBJ_id_pda_countryOfResidence 1L, 3L, 6L, 1L, 5L, 5L, 7L, 9L, 5L + +#define SN_id_aca_authenticationInfo "id-aca-authenticationInfo" +#define NID_id_aca_authenticationInfo 354 +#define OBJ_id_aca_authenticationInfo 1L, 3L, 6L, 1L, 5L, 5L, 7L, 10L, 1L + +#define SN_id_aca_accessIdentity "id-aca-accessIdentity" +#define NID_id_aca_accessIdentity 355 +#define OBJ_id_aca_accessIdentity 1L, 3L, 6L, 1L, 5L, 5L, 7L, 10L, 2L + +#define SN_id_aca_chargingIdentity "id-aca-chargingIdentity" +#define NID_id_aca_chargingIdentity 356 +#define OBJ_id_aca_chargingIdentity 1L, 3L, 6L, 1L, 5L, 5L, 7L, 10L, 3L + +#define SN_id_aca_group "id-aca-group" +#define NID_id_aca_group 357 +#define OBJ_id_aca_group 1L, 3L, 6L, 1L, 5L, 5L, 7L, 10L, 4L + +#define SN_id_aca_role "id-aca-role" +#define NID_id_aca_role 358 +#define OBJ_id_aca_role 1L, 3L, 6L, 1L, 5L, 5L, 7L, 10L, 5L + +#define SN_id_qcs_pkixQCSyntax_v1 "id-qcs-pkixQCSyntax-v1" +#define NID_id_qcs_pkixQCSyntax_v1 359 +#define OBJ_id_qcs_pkixQCSyntax_v1 1L, 3L, 6L, 1L, 5L, 5L, 7L, 11L, 1L + +#define SN_id_cct_crs "id-cct-crs" +#define NID_id_cct_crs 360 +#define OBJ_id_cct_crs 1L, 3L, 6L, 1L, 5L, 5L, 7L, 12L, 1L + +#define SN_id_cct_PKIData "id-cct-PKIData" +#define NID_id_cct_PKIData 361 +#define OBJ_id_cct_PKIData 1L, 3L, 6L, 1L, 5L, 5L, 7L, 12L, 2L + +#define SN_id_cct_PKIResponse "id-cct-PKIResponse" +#define NID_id_cct_PKIResponse 362 +#define OBJ_id_cct_PKIResponse 1L, 3L, 6L, 1L, 5L, 5L, 7L, 12L, 3L + +#define SN_ad_timeStamping "ad_timestamping" +#define LN_ad_timeStamping "AD Time Stamping" +#define NID_ad_timeStamping 363 +#define OBJ_ad_timeStamping 1L, 3L, 6L, 1L, 5L, 5L, 7L, 48L, 3L + +#define SN_ad_dvcs "AD_DVCS" +#define LN_ad_dvcs "ad dvcs" +#define NID_ad_dvcs 364 +#define OBJ_ad_dvcs 1L, 3L, 6L, 1L, 5L, 5L, 7L, 48L, 4L + +#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 1L, 3L, 6L, 1L, 5L, 5L, 7L, 48L, 1L, 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 1L, 3L, 6L, 1L, 5L, 5L, 7L, 48L, 1L, 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 1L, 3L, 6L, 1L, 5L, 5L, 7L, 48L, 1L, 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 \ + 1L, 3L, 6L, 1L, 5L, 5L, 7L, 48L, 1L, 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 1L, 3L, 6L, 1L, 5L, 5L, 7L, 48L, 1L, 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 1L, 3L, 6L, 1L, 5L, 5L, 7L, 48L, 1L, 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 1L, 3L, 6L, 1L, 5L, 5L, 7L, 48L, 1L, 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 1L, 3L, 6L, 1L, 5L, 5L, 7L, 48L, 1L, 8L + +#define SN_id_pkix_OCSP_valid "valid" +#define NID_id_pkix_OCSP_valid 373 +#define OBJ_id_pkix_OCSP_valid 1L, 3L, 6L, 1L, 5L, 5L, 7L, 48L, 1L, 9L + +#define SN_id_pkix_OCSP_path "path" +#define NID_id_pkix_OCSP_path 374 +#define OBJ_id_pkix_OCSP_path 1L, 3L, 6L, 1L, 5L, 5L, 7L, 48L, 1L, 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 1L, 3L, 6L, 1L, 5L, 5L, 7L, 48L, 1L, 11L + +#define SN_algorithm "algorithm" +#define LN_algorithm "algorithm" +#define NID_algorithm 376 +#define OBJ_algorithm 1L, 3L, 14L, 3L, 2L + +#define SN_rsaSignature "rsaSignature" +#define NID_rsaSignature 377 +#define OBJ_rsaSignature 1L, 3L, 14L, 3L, 2L, 11L + +#define SN_X500algorithms "X500algorithms" +#define LN_X500algorithms "directory services - algorithms" +#define NID_X500algorithms 378 +#define OBJ_X500algorithms 2L, 5L, 8L + +#define SN_org "ORG" +#define LN_org "org" +#define NID_org 379 +#define OBJ_org 1L, 3L + +#define SN_dod "DOD" +#define LN_dod "dod" +#define NID_dod 380 +#define OBJ_dod 1L, 3L, 6L + +#define SN_iana "IANA" +#define LN_iana "iana" +#define NID_iana 381 +#define OBJ_iana 1L, 3L, 6L, 1L + +#define SN_Directory "directory" +#define LN_Directory "Directory" +#define NID_Directory 382 +#define OBJ_Directory 1L, 3L, 6L, 1L, 1L + +#define SN_Management "mgmt" +#define LN_Management "Management" +#define NID_Management 383 +#define OBJ_Management 1L, 3L, 6L, 1L, 2L + +#define SN_Experimental "experimental" +#define LN_Experimental "Experimental" +#define NID_Experimental 384 +#define OBJ_Experimental 1L, 3L, 6L, 1L, 3L + +#define SN_Private "private" +#define LN_Private "Private" +#define NID_Private 385 +#define OBJ_Private 1L, 3L, 6L, 1L, 4L + +#define SN_Security "security" +#define LN_Security "Security" +#define NID_Security 386 +#define OBJ_Security 1L, 3L, 6L, 1L, 5L + +#define SN_SNMPv2 "snmpv2" +#define LN_SNMPv2 "SNMPv2" +#define NID_SNMPv2 387 +#define OBJ_SNMPv2 1L, 3L, 6L, 1L, 6L + +#define LN_Mail "Mail" +#define NID_Mail 388 +#define OBJ_Mail 1L, 3L, 6L, 1L, 7L + +#define SN_Enterprises "enterprises" +#define LN_Enterprises "Enterprises" +#define NID_Enterprises 389 +#define OBJ_Enterprises 1L, 3L, 6L, 1L, 4L, 1L + +#define SN_dcObject "dcobject" +#define LN_dcObject "dcObject" +#define NID_dcObject 390 +#define OBJ_dcObject 1L, 3L, 6L, 1L, 4L, 1L, 1466L, 344L + +#define SN_domainComponent "DC" +#define LN_domainComponent "domainComponent" +#define NID_domainComponent 391 +#define OBJ_domainComponent 0L, 9L, 2342L, 19200300L, 100L, 1L, 25L + +#define SN_Domain "domain" +#define LN_Domain "Domain" +#define NID_Domain 392 +#define OBJ_Domain 0L, 9L, 2342L, 19200300L, 100L, 4L, 13L + +#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 2L, 5L, 1L, 5L + +#define SN_clearance "clearance" +#define NID_clearance 395 +#define OBJ_clearance 2L, 5L, 1L, 5L, 55L + +#define SN_md4WithRSAEncryption "RSA-MD4" +#define LN_md4WithRSAEncryption "md4WithRSAEncryption" +#define NID_md4WithRSAEncryption 396 +#define OBJ_md4WithRSAEncryption 1L, 2L, 840L, 113549L, 1L, 1L, 3L + +#define SN_ac_proxying "ac-proxying" +#define NID_ac_proxying 397 +#define OBJ_ac_proxying 1L, 3L, 6L, 1L, 5L, 5L, 7L, 1L, 10L + +#define SN_sinfo_access "subjectInfoAccess" +#define LN_sinfo_access "Subject Information Access" +#define NID_sinfo_access 398 +#define OBJ_sinfo_access 1L, 3L, 6L, 1L, 5L, 5L, 7L, 1L, 11L + +#define SN_id_aca_encAttrs "id-aca-encAttrs" +#define NID_id_aca_encAttrs 399 +#define OBJ_id_aca_encAttrs 1L, 3L, 6L, 1L, 5L, 5L, 7L, 10L, 6L + +#define SN_role "role" +#define LN_role "role" +#define NID_role 400 +#define OBJ_role 2L, 5L, 4L, 72L + +#define SN_policy_constraints "policyConstraints" +#define LN_policy_constraints "X509v3 Policy Constraints" +#define NID_policy_constraints 401 +#define OBJ_policy_constraints 2L, 5L, 29L, 36L + +#define SN_target_information "targetInformation" +#define LN_target_information "X509v3 AC Targeting" +#define NID_target_information 402 +#define OBJ_target_information 2L, 5L, 29L, 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 2L, 5L, 29L, 56L + +#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 1L, 2L, 840L, 10045L + +#define SN_X9_62_prime_field "prime-field" +#define NID_X9_62_prime_field 406 +#define OBJ_X9_62_prime_field 1L, 2L, 840L, 10045L, 1L, 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 1L, 2L, 840L, 10045L, 1L, 2L + +#define SN_X9_62_id_ecPublicKey "id-ecPublicKey" +#define NID_X9_62_id_ecPublicKey 408 +#define OBJ_X9_62_id_ecPublicKey 1L, 2L, 840L, 10045L, 2L, 1L + +#define SN_X9_62_prime192v1 "prime192v1" +#define NID_X9_62_prime192v1 409 +#define OBJ_X9_62_prime192v1 1L, 2L, 840L, 10045L, 3L, 1L, 1L + +#define SN_X9_62_prime192v2 "prime192v2" +#define NID_X9_62_prime192v2 410 +#define OBJ_X9_62_prime192v2 1L, 2L, 840L, 10045L, 3L, 1L, 2L + +#define SN_X9_62_prime192v3 "prime192v3" +#define NID_X9_62_prime192v3 411 +#define OBJ_X9_62_prime192v3 1L, 2L, 840L, 10045L, 3L, 1L, 3L + +#define SN_X9_62_prime239v1 "prime239v1" +#define NID_X9_62_prime239v1 412 +#define OBJ_X9_62_prime239v1 1L, 2L, 840L, 10045L, 3L, 1L, 4L + +#define SN_X9_62_prime239v2 "prime239v2" +#define NID_X9_62_prime239v2 413 +#define OBJ_X9_62_prime239v2 1L, 2L, 840L, 10045L, 3L, 1L, 5L + +#define SN_X9_62_prime239v3 "prime239v3" +#define NID_X9_62_prime239v3 414 +#define OBJ_X9_62_prime239v3 1L, 2L, 840L, 10045L, 3L, 1L, 6L + +#define SN_X9_62_prime256v1 "prime256v1" +#define NID_X9_62_prime256v1 415 +#define OBJ_X9_62_prime256v1 1L, 2L, 840L, 10045L, 3L, 1L, 7L + +#define SN_ecdsa_with_SHA1 "ecdsa-with-SHA1" +#define NID_ecdsa_with_SHA1 416 +#define OBJ_ecdsa_with_SHA1 1L, 2L, 840L, 10045L, 4L, 1L + +#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_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 2L, 16L, 840L, 1L, 101L, 3L, 4L, 1L, 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 2L, 16L, 840L, 1L, 101L, 3L, 4L, 1L, 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 2L, 16L, 840L, 1L, 101L, 3L, 4L, 1L, 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 2L, 16L, 840L, 1L, 101L, 3L, 4L, 1L, 4L + +#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 2L, 16L, 840L, 1L, 101L, 3L, 4L, 1L, 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 2L, 16L, 840L, 1L, 101L, 3L, 4L, 1L, 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 2L, 16L, 840L, 1L, 101L, 3L, 4L, 1L, 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 2L, 16L, 840L, 1L, 101L, 3L, 4L, 1L, 24L + +#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 2L, 16L, 840L, 1L, 101L, 3L, 4L, 1L, 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 2L, 16L, 840L, 1L, 101L, 3L, 4L, 1L, 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 2L, 16L, 840L, 1L, 101L, 3L, 4L, 1L, 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 2L, 16L, 840L, 1L, 101L, 3L, 4L, 1L, 44L + +#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 2L, 5L, 29L, 23L + +#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 1L, 2L, 840L, 10040L, 2L, 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 1L, 2L, 840L, 10040L, 2L, 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 1L, 2L, 840L, 10040L, 2L, 3L + +#define SN_data "data" +#define NID_data 434 +#define OBJ_data 0L, 9L + +#define SN_pss "pss" +#define NID_pss 435 +#define OBJ_pss 0L, 9L, 2342L + +#define SN_ucl "ucl" +#define NID_ucl 436 +#define OBJ_ucl 0L, 9L, 2342L, 19200300L + +#define SN_pilot "pilot" +#define NID_pilot 437 +#define OBJ_pilot 0L, 9L, 2342L, 19200300L, 100L + +#define LN_pilotAttributeType "pilotAttributeType" +#define NID_pilotAttributeType 438 +#define OBJ_pilotAttributeType 0L, 9L, 2342L, 19200300L, 100L, 1L + +#define LN_pilotAttributeSyntax "pilotAttributeSyntax" +#define NID_pilotAttributeSyntax 439 +#define OBJ_pilotAttributeSyntax 0L, 9L, 2342L, 19200300L, 100L, 3L + +#define LN_pilotObjectClass "pilotObjectClass" +#define NID_pilotObjectClass 440 +#define OBJ_pilotObjectClass 0L, 9L, 2342L, 19200300L, 100L, 4L + +#define LN_pilotGroups "pilotGroups" +#define NID_pilotGroups 441 +#define OBJ_pilotGroups 0L, 9L, 2342L, 19200300L, 100L, 10L + +#define LN_iA5StringSyntax "iA5StringSyntax" +#define NID_iA5StringSyntax 442 +#define OBJ_iA5StringSyntax 0L, 9L, 2342L, 19200300L, 100L, 3L, 4L + +#define LN_caseIgnoreIA5StringSyntax "caseIgnoreIA5StringSyntax" +#define NID_caseIgnoreIA5StringSyntax 443 +#define OBJ_caseIgnoreIA5StringSyntax 0L, 9L, 2342L, 19200300L, 100L, 3L, 5L + +#define LN_pilotObject "pilotObject" +#define NID_pilotObject 444 +#define OBJ_pilotObject 0L, 9L, 2342L, 19200300L, 100L, 4L, 3L + +#define LN_pilotPerson "pilotPerson" +#define NID_pilotPerson 445 +#define OBJ_pilotPerson 0L, 9L, 2342L, 19200300L, 100L, 4L, 4L + +#define SN_account "account" +#define NID_account 446 +#define OBJ_account 0L, 9L, 2342L, 19200300L, 100L, 4L, 5L + +#define SN_document "document" +#define NID_document 447 +#define OBJ_document 0L, 9L, 2342L, 19200300L, 100L, 4L, 6L + +#define SN_room "room" +#define NID_room 448 +#define OBJ_room 0L, 9L, 2342L, 19200300L, 100L, 4L, 7L + +#define LN_documentSeries "documentSeries" +#define NID_documentSeries 449 +#define OBJ_documentSeries 0L, 9L, 2342L, 19200300L, 100L, 4L, 9L + +#define LN_rFC822localPart "rFC822localPart" +#define NID_rFC822localPart 450 +#define OBJ_rFC822localPart 0L, 9L, 2342L, 19200300L, 100L, 4L, 14L + +#define LN_dNSDomain "dNSDomain" +#define NID_dNSDomain 451 +#define OBJ_dNSDomain 0L, 9L, 2342L, 19200300L, 100L, 4L, 15L + +#define LN_domainRelatedObject "domainRelatedObject" +#define NID_domainRelatedObject 452 +#define OBJ_domainRelatedObject 0L, 9L, 2342L, 19200300L, 100L, 4L, 17L + +#define LN_friendlyCountry "friendlyCountry" +#define NID_friendlyCountry 453 +#define OBJ_friendlyCountry 0L, 9L, 2342L, 19200300L, 100L, 4L, 18L + +#define LN_simpleSecurityObject "simpleSecurityObject" +#define NID_simpleSecurityObject 454 +#define OBJ_simpleSecurityObject 0L, 9L, 2342L, 19200300L, 100L, 4L, 19L + +#define LN_pilotOrganization "pilotOrganization" +#define NID_pilotOrganization 455 +#define OBJ_pilotOrganization 0L, 9L, 2342L, 19200300L, 100L, 4L, 20L + +#define LN_pilotDSA "pilotDSA" +#define NID_pilotDSA 456 +#define OBJ_pilotDSA 0L, 9L, 2342L, 19200300L, 100L, 4L, 21L + +#define LN_qualityLabelledData "qualityLabelledData" +#define NID_qualityLabelledData 457 +#define OBJ_qualityLabelledData 0L, 9L, 2342L, 19200300L, 100L, 4L, 22L + +#define SN_userId "UID" +#define LN_userId "userId" +#define NID_userId 458 +#define OBJ_userId 0L, 9L, 2342L, 19200300L, 100L, 1L, 1L + +#define LN_textEncodedORAddress "textEncodedORAddress" +#define NID_textEncodedORAddress 459 +#define OBJ_textEncodedORAddress 0L, 9L, 2342L, 19200300L, 100L, 1L, 2L + +#define SN_rfc822Mailbox "mail" +#define LN_rfc822Mailbox "rfc822Mailbox" +#define NID_rfc822Mailbox 460 +#define OBJ_rfc822Mailbox 0L, 9L, 2342L, 19200300L, 100L, 1L, 3L + +#define SN_info "info" +#define NID_info 461 +#define OBJ_info 0L, 9L, 2342L, 19200300L, 100L, 1L, 4L + +#define LN_favouriteDrink "favouriteDrink" +#define NID_favouriteDrink 462 +#define OBJ_favouriteDrink 0L, 9L, 2342L, 19200300L, 100L, 1L, 5L + +#define LN_roomNumber "roomNumber" +#define NID_roomNumber 463 +#define OBJ_roomNumber 0L, 9L, 2342L, 19200300L, 100L, 1L, 6L + +#define SN_photo "photo" +#define NID_photo 464 +#define OBJ_photo 0L, 9L, 2342L, 19200300L, 100L, 1L, 7L + +#define LN_userClass "userClass" +#define NID_userClass 465 +#define OBJ_userClass 0L, 9L, 2342L, 19200300L, 100L, 1L, 8L + +#define SN_host "host" +#define NID_host 466 +#define OBJ_host 0L, 9L, 2342L, 19200300L, 100L, 1L, 9L + +#define SN_manager "manager" +#define NID_manager 467 +#define OBJ_manager 0L, 9L, 2342L, 19200300L, 100L, 1L, 10L + +#define LN_documentIdentifier "documentIdentifier" +#define NID_documentIdentifier 468 +#define OBJ_documentIdentifier 0L, 9L, 2342L, 19200300L, 100L, 1L, 11L + +#define LN_documentTitle "documentTitle" +#define NID_documentTitle 469 +#define OBJ_documentTitle 0L, 9L, 2342L, 19200300L, 100L, 1L, 12L + +#define LN_documentVersion "documentVersion" +#define NID_documentVersion 470 +#define OBJ_documentVersion 0L, 9L, 2342L, 19200300L, 100L, 1L, 13L + +#define LN_documentAuthor "documentAuthor" +#define NID_documentAuthor 471 +#define OBJ_documentAuthor 0L, 9L, 2342L, 19200300L, 100L, 1L, 14L + +#define LN_documentLocation "documentLocation" +#define NID_documentLocation 472 +#define OBJ_documentLocation 0L, 9L, 2342L, 19200300L, 100L, 1L, 15L + +#define LN_homeTelephoneNumber "homeTelephoneNumber" +#define NID_homeTelephoneNumber 473 +#define OBJ_homeTelephoneNumber 0L, 9L, 2342L, 19200300L, 100L, 1L, 20L + +#define SN_secretary "secretary" +#define NID_secretary 474 +#define OBJ_secretary 0L, 9L, 2342L, 19200300L, 100L, 1L, 21L + +#define LN_otherMailbox "otherMailbox" +#define NID_otherMailbox 475 +#define OBJ_otherMailbox 0L, 9L, 2342L, 19200300L, 100L, 1L, 22L + +#define LN_lastModifiedTime "lastModifiedTime" +#define NID_lastModifiedTime 476 +#define OBJ_lastModifiedTime 0L, 9L, 2342L, 19200300L, 100L, 1L, 23L + +#define LN_lastModifiedBy "lastModifiedBy" +#define NID_lastModifiedBy 477 +#define OBJ_lastModifiedBy 0L, 9L, 2342L, 19200300L, 100L, 1L, 24L + +#define LN_aRecord "aRecord" +#define NID_aRecord 478 +#define OBJ_aRecord 0L, 9L, 2342L, 19200300L, 100L, 1L, 26L + +#define LN_pilotAttributeType27 "pilotAttributeType27" +#define NID_pilotAttributeType27 479 +#define OBJ_pilotAttributeType27 0L, 9L, 2342L, 19200300L, 100L, 1L, 27L + +#define LN_mXRecord "mXRecord" +#define NID_mXRecord 480 +#define OBJ_mXRecord 0L, 9L, 2342L, 19200300L, 100L, 1L, 28L + +#define LN_nSRecord "nSRecord" +#define NID_nSRecord 481 +#define OBJ_nSRecord 0L, 9L, 2342L, 19200300L, 100L, 1L, 29L + +#define LN_sOARecord "sOARecord" +#define NID_sOARecord 482 +#define OBJ_sOARecord 0L, 9L, 2342L, 19200300L, 100L, 1L, 30L + +#define LN_cNAMERecord "cNAMERecord" +#define NID_cNAMERecord 483 +#define OBJ_cNAMERecord 0L, 9L, 2342L, 19200300L, 100L, 1L, 31L + +#define LN_associatedDomain "associatedDomain" +#define NID_associatedDomain 484 +#define OBJ_associatedDomain 0L, 9L, 2342L, 19200300L, 100L, 1L, 37L + +#define LN_associatedName "associatedName" +#define NID_associatedName 485 +#define OBJ_associatedName 0L, 9L, 2342L, 19200300L, 100L, 1L, 38L + +#define LN_homePostalAddress "homePostalAddress" +#define NID_homePostalAddress 486 +#define OBJ_homePostalAddress 0L, 9L, 2342L, 19200300L, 100L, 1L, 39L + +#define LN_personalTitle "personalTitle" +#define NID_personalTitle 487 +#define OBJ_personalTitle 0L, 9L, 2342L, 19200300L, 100L, 1L, 40L + +#define LN_mobileTelephoneNumber "mobileTelephoneNumber" +#define NID_mobileTelephoneNumber 488 +#define OBJ_mobileTelephoneNumber 0L, 9L, 2342L, 19200300L, 100L, 1L, 41L + +#define LN_pagerTelephoneNumber "pagerTelephoneNumber" +#define NID_pagerTelephoneNumber 489 +#define OBJ_pagerTelephoneNumber 0L, 9L, 2342L, 19200300L, 100L, 1L, 42L + +#define LN_friendlyCountryName "friendlyCountryName" +#define NID_friendlyCountryName 490 +#define OBJ_friendlyCountryName 0L, 9L, 2342L, 19200300L, 100L, 1L, 43L + +#define LN_organizationalStatus "organizationalStatus" +#define NID_organizationalStatus 491 +#define OBJ_organizationalStatus 0L, 9L, 2342L, 19200300L, 100L, 1L, 45L + +#define LN_janetMailbox "janetMailbox" +#define NID_janetMailbox 492 +#define OBJ_janetMailbox 0L, 9L, 2342L, 19200300L, 100L, 1L, 46L + +#define LN_mailPreferenceOption "mailPreferenceOption" +#define NID_mailPreferenceOption 493 +#define OBJ_mailPreferenceOption 0L, 9L, 2342L, 19200300L, 100L, 1L, 47L + +#define LN_buildingName "buildingName" +#define NID_buildingName 494 +#define OBJ_buildingName 0L, 9L, 2342L, 19200300L, 100L, 1L, 48L + +#define LN_dSAQuality "dSAQuality" +#define NID_dSAQuality 495 +#define OBJ_dSAQuality 0L, 9L, 2342L, 19200300L, 100L, 1L, 49L + +#define LN_singleLevelQuality "singleLevelQuality" +#define NID_singleLevelQuality 496 +#define OBJ_singleLevelQuality 0L, 9L, 2342L, 19200300L, 100L, 1L, 50L + +#define LN_subtreeMinimumQuality "subtreeMinimumQuality" +#define NID_subtreeMinimumQuality 497 +#define OBJ_subtreeMinimumQuality 0L, 9L, 2342L, 19200300L, 100L, 1L, 51L + +#define LN_subtreeMaximumQuality "subtreeMaximumQuality" +#define NID_subtreeMaximumQuality 498 +#define OBJ_subtreeMaximumQuality 0L, 9L, 2342L, 19200300L, 100L, 1L, 52L + +#define LN_personalSignature "personalSignature" +#define NID_personalSignature 499 +#define OBJ_personalSignature 0L, 9L, 2342L, 19200300L, 100L, 1L, 53L + +#define LN_dITRedirect "dITRedirect" +#define NID_dITRedirect 500 +#define OBJ_dITRedirect 0L, 9L, 2342L, 19200300L, 100L, 1L, 54L + +#define SN_audio "audio" +#define NID_audio 501 +#define OBJ_audio 0L, 9L, 2342L, 19200300L, 100L, 1L, 55L + +#define LN_documentPublisher "documentPublisher" +#define NID_documentPublisher 502 +#define OBJ_documentPublisher 0L, 9L, 2342L, 19200300L, 100L, 1L, 56L + +#define LN_x500UniqueIdentifier "x500UniqueIdentifier" +#define NID_x500UniqueIdentifier 503 +#define OBJ_x500UniqueIdentifier 2L, 5L, 4L, 45L + +#define SN_mime_mhs "mime-mhs" +#define LN_mime_mhs "MIME MHS" +#define NID_mime_mhs 504 +#define OBJ_mime_mhs 1L, 3L, 6L, 1L, 7L, 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 1L, 3L, 6L, 1L, 7L, 1L, 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 1L, 3L, 6L, 1L, 7L, 1L, 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 1L, 3L, 6L, 1L, 7L, 1L, 1L, 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 1L, 3L, 6L, 1L, 7L, 1L, 1L, 2L + +#define LN_generationQualifier "generationQualifier" +#define NID_generationQualifier 509 +#define OBJ_generationQualifier 2L, 5L, 4L, 44L + +#define LN_pseudonym "pseudonym" +#define NID_pseudonym 510 +#define OBJ_pseudonym 2L, 5L, 4L, 65L + +#define SN_id_set "id-set" +#define LN_id_set "Secure Electronic Transactions" +#define NID_id_set 512 +#define OBJ_id_set 2L, 23L, 42L + +#define SN_set_ctype "set-ctype" +#define LN_set_ctype "content types" +#define NID_set_ctype 513 +#define OBJ_set_ctype 2L, 23L, 42L, 0L + +#define SN_set_msgExt "set-msgExt" +#define LN_set_msgExt "message extensions" +#define NID_set_msgExt 514 +#define OBJ_set_msgExt 2L, 23L, 42L, 1L + +#define SN_set_attr "set-attr" +#define NID_set_attr 515 +#define OBJ_set_attr 2L, 23L, 42L, 3L + +#define SN_set_policy "set-policy" +#define NID_set_policy 516 +#define OBJ_set_policy 2L, 23L, 42L, 5L + +#define SN_set_certExt "set-certExt" +#define LN_set_certExt "certificate extensions" +#define NID_set_certExt 517 +#define OBJ_set_certExt 2L, 23L, 42L, 7L + +#define SN_set_brand "set-brand" +#define NID_set_brand 518 +#define OBJ_set_brand 2L, 23L, 42L, 8L + +#define SN_setct_PANData "setct-PANData" +#define NID_setct_PANData 519 +#define OBJ_setct_PANData 2L, 23L, 42L, 0L, 0L + +#define SN_setct_PANToken "setct-PANToken" +#define NID_setct_PANToken 520 +#define OBJ_setct_PANToken 2L, 23L, 42L, 0L, 1L + +#define SN_setct_PANOnly "setct-PANOnly" +#define NID_setct_PANOnly 521 +#define OBJ_setct_PANOnly 2L, 23L, 42L, 0L, 2L + +#define SN_setct_OIData "setct-OIData" +#define NID_setct_OIData 522 +#define OBJ_setct_OIData 2L, 23L, 42L, 0L, 3L + +#define SN_setct_PI "setct-PI" +#define NID_setct_PI 523 +#define OBJ_setct_PI 2L, 23L, 42L, 0L, 4L + +#define SN_setct_PIData "setct-PIData" +#define NID_setct_PIData 524 +#define OBJ_setct_PIData 2L, 23L, 42L, 0L, 5L + +#define SN_setct_PIDataUnsigned "setct-PIDataUnsigned" +#define NID_setct_PIDataUnsigned 525 +#define OBJ_setct_PIDataUnsigned 2L, 23L, 42L, 0L, 6L + +#define SN_setct_HODInput "setct-HODInput" +#define NID_setct_HODInput 526 +#define OBJ_setct_HODInput 2L, 23L, 42L, 0L, 7L + +#define SN_setct_AuthResBaggage "setct-AuthResBaggage" +#define NID_setct_AuthResBaggage 527 +#define OBJ_setct_AuthResBaggage 2L, 23L, 42L, 0L, 8L + +#define SN_setct_AuthRevReqBaggage "setct-AuthRevReqBaggage" +#define NID_setct_AuthRevReqBaggage 528 +#define OBJ_setct_AuthRevReqBaggage 2L, 23L, 42L, 0L, 9L + +#define SN_setct_AuthRevResBaggage "setct-AuthRevResBaggage" +#define NID_setct_AuthRevResBaggage 529 +#define OBJ_setct_AuthRevResBaggage 2L, 23L, 42L, 0L, 10L + +#define SN_setct_CapTokenSeq "setct-CapTokenSeq" +#define NID_setct_CapTokenSeq 530 +#define OBJ_setct_CapTokenSeq 2L, 23L, 42L, 0L, 11L + +#define SN_setct_PInitResData "setct-PInitResData" +#define NID_setct_PInitResData 531 +#define OBJ_setct_PInitResData 2L, 23L, 42L, 0L, 12L + +#define SN_setct_PI_TBS "setct-PI-TBS" +#define NID_setct_PI_TBS 532 +#define OBJ_setct_PI_TBS 2L, 23L, 42L, 0L, 13L + +#define SN_setct_PResData "setct-PResData" +#define NID_setct_PResData 533 +#define OBJ_setct_PResData 2L, 23L, 42L, 0L, 14L + +#define SN_setct_AuthReqTBS "setct-AuthReqTBS" +#define NID_setct_AuthReqTBS 534 +#define OBJ_setct_AuthReqTBS 2L, 23L, 42L, 0L, 16L + +#define SN_setct_AuthResTBS "setct-AuthResTBS" +#define NID_setct_AuthResTBS 535 +#define OBJ_setct_AuthResTBS 2L, 23L, 42L, 0L, 17L + +#define SN_setct_AuthResTBSX "setct-AuthResTBSX" +#define NID_setct_AuthResTBSX 536 +#define OBJ_setct_AuthResTBSX 2L, 23L, 42L, 0L, 18L + +#define SN_setct_AuthTokenTBS "setct-AuthTokenTBS" +#define NID_setct_AuthTokenTBS 537 +#define OBJ_setct_AuthTokenTBS 2L, 23L, 42L, 0L, 19L + +#define SN_setct_CapTokenData "setct-CapTokenData" +#define NID_setct_CapTokenData 538 +#define OBJ_setct_CapTokenData 2L, 23L, 42L, 0L, 20L + +#define SN_setct_CapTokenTBS "setct-CapTokenTBS" +#define NID_setct_CapTokenTBS 539 +#define OBJ_setct_CapTokenTBS 2L, 23L, 42L, 0L, 21L + +#define SN_setct_AcqCardCodeMsg "setct-AcqCardCodeMsg" +#define NID_setct_AcqCardCodeMsg 540 +#define OBJ_setct_AcqCardCodeMsg 2L, 23L, 42L, 0L, 22L + +#define SN_setct_AuthRevReqTBS "setct-AuthRevReqTBS" +#define NID_setct_AuthRevReqTBS 541 +#define OBJ_setct_AuthRevReqTBS 2L, 23L, 42L, 0L, 23L + +#define SN_setct_AuthRevResData "setct-AuthRevResData" +#define NID_setct_AuthRevResData 542 +#define OBJ_setct_AuthRevResData 2L, 23L, 42L, 0L, 24L + +#define SN_setct_AuthRevResTBS "setct-AuthRevResTBS" +#define NID_setct_AuthRevResTBS 543 +#define OBJ_setct_AuthRevResTBS 2L, 23L, 42L, 0L, 25L + +#define SN_setct_CapReqTBS "setct-CapReqTBS" +#define NID_setct_CapReqTBS 544 +#define OBJ_setct_CapReqTBS 2L, 23L, 42L, 0L, 26L + +#define SN_setct_CapReqTBSX "setct-CapReqTBSX" +#define NID_setct_CapReqTBSX 545 +#define OBJ_setct_CapReqTBSX 2L, 23L, 42L, 0L, 27L + +#define SN_setct_CapResData "setct-CapResData" +#define NID_setct_CapResData 546 +#define OBJ_setct_CapResData 2L, 23L, 42L, 0L, 28L + +#define SN_setct_CapRevReqTBS "setct-CapRevReqTBS" +#define NID_setct_CapRevReqTBS 547 +#define OBJ_setct_CapRevReqTBS 2L, 23L, 42L, 0L, 29L + +#define SN_setct_CapRevReqTBSX "setct-CapRevReqTBSX" +#define NID_setct_CapRevReqTBSX 548 +#define OBJ_setct_CapRevReqTBSX 2L, 23L, 42L, 0L, 30L + +#define SN_setct_CapRevResData "setct-CapRevResData" +#define NID_setct_CapRevResData 549 +#define OBJ_setct_CapRevResData 2L, 23L, 42L, 0L, 31L + +#define SN_setct_CredReqTBS "setct-CredReqTBS" +#define NID_setct_CredReqTBS 550 +#define OBJ_setct_CredReqTBS 2L, 23L, 42L, 0L, 32L + +#define SN_setct_CredReqTBSX "setct-CredReqTBSX" +#define NID_setct_CredReqTBSX 551 +#define OBJ_setct_CredReqTBSX 2L, 23L, 42L, 0L, 33L + +#define SN_setct_CredResData "setct-CredResData" +#define NID_setct_CredResData 552 +#define OBJ_setct_CredResData 2L, 23L, 42L, 0L, 34L + +#define SN_setct_CredRevReqTBS "setct-CredRevReqTBS" +#define NID_setct_CredRevReqTBS 553 +#define OBJ_setct_CredRevReqTBS 2L, 23L, 42L, 0L, 35L + +#define SN_setct_CredRevReqTBSX "setct-CredRevReqTBSX" +#define NID_setct_CredRevReqTBSX 554 +#define OBJ_setct_CredRevReqTBSX 2L, 23L, 42L, 0L, 36L + +#define SN_setct_CredRevResData "setct-CredRevResData" +#define NID_setct_CredRevResData 555 +#define OBJ_setct_CredRevResData 2L, 23L, 42L, 0L, 37L + +#define SN_setct_PCertReqData "setct-PCertReqData" +#define NID_setct_PCertReqData 556 +#define OBJ_setct_PCertReqData 2L, 23L, 42L, 0L, 38L + +#define SN_setct_PCertResTBS "setct-PCertResTBS" +#define NID_setct_PCertResTBS 557 +#define OBJ_setct_PCertResTBS 2L, 23L, 42L, 0L, 39L + +#define SN_setct_BatchAdminReqData "setct-BatchAdminReqData" +#define NID_setct_BatchAdminReqData 558 +#define OBJ_setct_BatchAdminReqData 2L, 23L, 42L, 0L, 40L + +#define SN_setct_BatchAdminResData "setct-BatchAdminResData" +#define NID_setct_BatchAdminResData 559 +#define OBJ_setct_BatchAdminResData 2L, 23L, 42L, 0L, 41L + +#define SN_setct_CardCInitResTBS "setct-CardCInitResTBS" +#define NID_setct_CardCInitResTBS 560 +#define OBJ_setct_CardCInitResTBS 2L, 23L, 42L, 0L, 42L + +#define SN_setct_MeAqCInitResTBS "setct-MeAqCInitResTBS" +#define NID_setct_MeAqCInitResTBS 561 +#define OBJ_setct_MeAqCInitResTBS 2L, 23L, 42L, 0L, 43L + +#define SN_setct_RegFormResTBS "setct-RegFormResTBS" +#define NID_setct_RegFormResTBS 562 +#define OBJ_setct_RegFormResTBS 2L, 23L, 42L, 0L, 44L + +#define SN_setct_CertReqData "setct-CertReqData" +#define NID_setct_CertReqData 563 +#define OBJ_setct_CertReqData 2L, 23L, 42L, 0L, 45L + +#define SN_setct_CertReqTBS "setct-CertReqTBS" +#define NID_setct_CertReqTBS 564 +#define OBJ_setct_CertReqTBS 2L, 23L, 42L, 0L, 46L + +#define SN_setct_CertResData "setct-CertResData" +#define NID_setct_CertResData 565 +#define OBJ_setct_CertResData 2L, 23L, 42L, 0L, 47L + +#define SN_setct_CertInqReqTBS "setct-CertInqReqTBS" +#define NID_setct_CertInqReqTBS 566 +#define OBJ_setct_CertInqReqTBS 2L, 23L, 42L, 0L, 48L + +#define SN_setct_ErrorTBS "setct-ErrorTBS" +#define NID_setct_ErrorTBS 567 +#define OBJ_setct_ErrorTBS 2L, 23L, 42L, 0L, 49L + +#define SN_setct_PIDualSignedTBE "setct-PIDualSignedTBE" +#define NID_setct_PIDualSignedTBE 568 +#define OBJ_setct_PIDualSignedTBE 2L, 23L, 42L, 0L, 50L + +#define SN_setct_PIUnsignedTBE "setct-PIUnsignedTBE" +#define NID_setct_PIUnsignedTBE 569 +#define OBJ_setct_PIUnsignedTBE 2L, 23L, 42L, 0L, 51L + +#define SN_setct_AuthReqTBE "setct-AuthReqTBE" +#define NID_setct_AuthReqTBE 570 +#define OBJ_setct_AuthReqTBE 2L, 23L, 42L, 0L, 52L + +#define SN_setct_AuthResTBE "setct-AuthResTBE" +#define NID_setct_AuthResTBE 571 +#define OBJ_setct_AuthResTBE 2L, 23L, 42L, 0L, 53L + +#define SN_setct_AuthResTBEX "setct-AuthResTBEX" +#define NID_setct_AuthResTBEX 572 +#define OBJ_setct_AuthResTBEX 2L, 23L, 42L, 0L, 54L + +#define SN_setct_AuthTokenTBE "setct-AuthTokenTBE" +#define NID_setct_AuthTokenTBE 573 +#define OBJ_setct_AuthTokenTBE 2L, 23L, 42L, 0L, 55L + +#define SN_setct_CapTokenTBE "setct-CapTokenTBE" +#define NID_setct_CapTokenTBE 574 +#define OBJ_setct_CapTokenTBE 2L, 23L, 42L, 0L, 56L + +#define SN_setct_CapTokenTBEX "setct-CapTokenTBEX" +#define NID_setct_CapTokenTBEX 575 +#define OBJ_setct_CapTokenTBEX 2L, 23L, 42L, 0L, 57L + +#define SN_setct_AcqCardCodeMsgTBE "setct-AcqCardCodeMsgTBE" +#define NID_setct_AcqCardCodeMsgTBE 576 +#define OBJ_setct_AcqCardCodeMsgTBE 2L, 23L, 42L, 0L, 58L + +#define SN_setct_AuthRevReqTBE "setct-AuthRevReqTBE" +#define NID_setct_AuthRevReqTBE 577 +#define OBJ_setct_AuthRevReqTBE 2L, 23L, 42L, 0L, 59L + +#define SN_setct_AuthRevResTBE "setct-AuthRevResTBE" +#define NID_setct_AuthRevResTBE 578 +#define OBJ_setct_AuthRevResTBE 2L, 23L, 42L, 0L, 60L + +#define SN_setct_AuthRevResTBEB "setct-AuthRevResTBEB" +#define NID_setct_AuthRevResTBEB 579 +#define OBJ_setct_AuthRevResTBEB 2L, 23L, 42L, 0L, 61L + +#define SN_setct_CapReqTBE "setct-CapReqTBE" +#define NID_setct_CapReqTBE 580 +#define OBJ_setct_CapReqTBE 2L, 23L, 42L, 0L, 62L + +#define SN_setct_CapReqTBEX "setct-CapReqTBEX" +#define NID_setct_CapReqTBEX 581 +#define OBJ_setct_CapReqTBEX 2L, 23L, 42L, 0L, 63L + +#define SN_setct_CapResTBE "setct-CapResTBE" +#define NID_setct_CapResTBE 582 +#define OBJ_setct_CapResTBE 2L, 23L, 42L, 0L, 64L + +#define SN_setct_CapRevReqTBE "setct-CapRevReqTBE" +#define NID_setct_CapRevReqTBE 583 +#define OBJ_setct_CapRevReqTBE 2L, 23L, 42L, 0L, 65L + +#define SN_setct_CapRevReqTBEX "setct-CapRevReqTBEX" +#define NID_setct_CapRevReqTBEX 584 +#define OBJ_setct_CapRevReqTBEX 2L, 23L, 42L, 0L, 66L + +#define SN_setct_CapRevResTBE "setct-CapRevResTBE" +#define NID_setct_CapRevResTBE 585 +#define OBJ_setct_CapRevResTBE 2L, 23L, 42L, 0L, 67L + +#define SN_setct_CredReqTBE "setct-CredReqTBE" +#define NID_setct_CredReqTBE 586 +#define OBJ_setct_CredReqTBE 2L, 23L, 42L, 0L, 68L + +#define SN_setct_CredReqTBEX "setct-CredReqTBEX" +#define NID_setct_CredReqTBEX 587 +#define OBJ_setct_CredReqTBEX 2L, 23L, 42L, 0L, 69L + +#define SN_setct_CredResTBE "setct-CredResTBE" +#define NID_setct_CredResTBE 588 +#define OBJ_setct_CredResTBE 2L, 23L, 42L, 0L, 70L + +#define SN_setct_CredRevReqTBE "setct-CredRevReqTBE" +#define NID_setct_CredRevReqTBE 589 +#define OBJ_setct_CredRevReqTBE 2L, 23L, 42L, 0L, 71L + +#define SN_setct_CredRevReqTBEX "setct-CredRevReqTBEX" +#define NID_setct_CredRevReqTBEX 590 +#define OBJ_setct_CredRevReqTBEX 2L, 23L, 42L, 0L, 72L + +#define SN_setct_CredRevResTBE "setct-CredRevResTBE" +#define NID_setct_CredRevResTBE 591 +#define OBJ_setct_CredRevResTBE 2L, 23L, 42L, 0L, 73L + +#define SN_setct_BatchAdminReqTBE "setct-BatchAdminReqTBE" +#define NID_setct_BatchAdminReqTBE 592 +#define OBJ_setct_BatchAdminReqTBE 2L, 23L, 42L, 0L, 74L + +#define SN_setct_BatchAdminResTBE "setct-BatchAdminResTBE" +#define NID_setct_BatchAdminResTBE 593 +#define OBJ_setct_BatchAdminResTBE 2L, 23L, 42L, 0L, 75L + +#define SN_setct_RegFormReqTBE "setct-RegFormReqTBE" +#define NID_setct_RegFormReqTBE 594 +#define OBJ_setct_RegFormReqTBE 2L, 23L, 42L, 0L, 76L + +#define SN_setct_CertReqTBE "setct-CertReqTBE" +#define NID_setct_CertReqTBE 595 +#define OBJ_setct_CertReqTBE 2L, 23L, 42L, 0L, 77L + +#define SN_setct_CertReqTBEX "setct-CertReqTBEX" +#define NID_setct_CertReqTBEX 596 +#define OBJ_setct_CertReqTBEX 2L, 23L, 42L, 0L, 78L + +#define SN_setct_CertResTBE "setct-CertResTBE" +#define NID_setct_CertResTBE 597 +#define OBJ_setct_CertResTBE 2L, 23L, 42L, 0L, 79L + +#define SN_setct_CRLNotificationTBS "setct-CRLNotificationTBS" +#define NID_setct_CRLNotificationTBS 598 +#define OBJ_setct_CRLNotificationTBS 2L, 23L, 42L, 0L, 80L + +#define SN_setct_CRLNotificationResTBS "setct-CRLNotificationResTBS" +#define NID_setct_CRLNotificationResTBS 599 +#define OBJ_setct_CRLNotificationResTBS 2L, 23L, 42L, 0L, 81L + +#define SN_setct_BCIDistributionTBS "setct-BCIDistributionTBS" +#define NID_setct_BCIDistributionTBS 600 +#define OBJ_setct_BCIDistributionTBS 2L, 23L, 42L, 0L, 82L + +#define SN_setext_genCrypt "setext-genCrypt" +#define LN_setext_genCrypt "generic cryptogram" +#define NID_setext_genCrypt 601 +#define OBJ_setext_genCrypt 2L, 23L, 42L, 1L, 1L + +#define SN_setext_miAuth "setext-miAuth" +#define LN_setext_miAuth "merchant initiated auth" +#define NID_setext_miAuth 602 +#define OBJ_setext_miAuth 2L, 23L, 42L, 1L, 3L + +#define SN_setext_pinSecure "setext-pinSecure" +#define NID_setext_pinSecure 603 +#define OBJ_setext_pinSecure 2L, 23L, 42L, 1L, 4L + +#define SN_setext_pinAny "setext-pinAny" +#define NID_setext_pinAny 604 +#define OBJ_setext_pinAny 2L, 23L, 42L, 1L, 5L + +#define SN_setext_track2 "setext-track2" +#define NID_setext_track2 605 +#define OBJ_setext_track2 2L, 23L, 42L, 1L, 7L + +#define SN_setext_cv "setext-cv" +#define LN_setext_cv "additional verification" +#define NID_setext_cv 606 +#define OBJ_setext_cv 2L, 23L, 42L, 1L, 8L + +#define SN_set_policy_root "set-policy-root" +#define NID_set_policy_root 607 +#define OBJ_set_policy_root 2L, 23L, 42L, 5L, 0L + +#define SN_setCext_hashedRoot "setCext-hashedRoot" +#define NID_setCext_hashedRoot 608 +#define OBJ_setCext_hashedRoot 2L, 23L, 42L, 7L, 0L + +#define SN_setCext_certType "setCext-certType" +#define NID_setCext_certType 609 +#define OBJ_setCext_certType 2L, 23L, 42L, 7L, 1L + +#define SN_setCext_merchData "setCext-merchData" +#define NID_setCext_merchData 610 +#define OBJ_setCext_merchData 2L, 23L, 42L, 7L, 2L + +#define SN_setCext_cCertRequired "setCext-cCertRequired" +#define NID_setCext_cCertRequired 611 +#define OBJ_setCext_cCertRequired 2L, 23L, 42L, 7L, 3L + +#define SN_setCext_tunneling "setCext-tunneling" +#define NID_setCext_tunneling 612 +#define OBJ_setCext_tunneling 2L, 23L, 42L, 7L, 4L + +#define SN_setCext_setExt "setCext-setExt" +#define NID_setCext_setExt 613 +#define OBJ_setCext_setExt 2L, 23L, 42L, 7L, 5L + +#define SN_setCext_setQualf "setCext-setQualf" +#define NID_setCext_setQualf 614 +#define OBJ_setCext_setQualf 2L, 23L, 42L, 7L, 6L + +#define SN_setCext_PGWYcapabilities "setCext-PGWYcapabilities" +#define NID_setCext_PGWYcapabilities 615 +#define OBJ_setCext_PGWYcapabilities 2L, 23L, 42L, 7L, 7L + +#define SN_setCext_TokenIdentifier "setCext-TokenIdentifier" +#define NID_setCext_TokenIdentifier 616 +#define OBJ_setCext_TokenIdentifier 2L, 23L, 42L, 7L, 8L + +#define SN_setCext_Track2Data "setCext-Track2Data" +#define NID_setCext_Track2Data 617 +#define OBJ_setCext_Track2Data 2L, 23L, 42L, 7L, 9L + +#define SN_setCext_TokenType "setCext-TokenType" +#define NID_setCext_TokenType 618 +#define OBJ_setCext_TokenType 2L, 23L, 42L, 7L, 10L + +#define SN_setCext_IssuerCapabilities "setCext-IssuerCapabilities" +#define NID_setCext_IssuerCapabilities 619 +#define OBJ_setCext_IssuerCapabilities 2L, 23L, 42L, 7L, 11L + +#define SN_setAttr_Cert "setAttr-Cert" +#define NID_setAttr_Cert 620 +#define OBJ_setAttr_Cert 2L, 23L, 42L, 3L, 0L + +#define SN_setAttr_PGWYcap "setAttr-PGWYcap" +#define LN_setAttr_PGWYcap "payment gateway capabilities" +#define NID_setAttr_PGWYcap 621 +#define OBJ_setAttr_PGWYcap 2L, 23L, 42L, 3L, 1L + +#define SN_setAttr_TokenType "setAttr-TokenType" +#define NID_setAttr_TokenType 622 +#define OBJ_setAttr_TokenType 2L, 23L, 42L, 3L, 2L + +#define SN_setAttr_IssCap "setAttr-IssCap" +#define LN_setAttr_IssCap "issuer capabilities" +#define NID_setAttr_IssCap 623 +#define OBJ_setAttr_IssCap 2L, 23L, 42L, 3L, 3L + +#define SN_set_rootKeyThumb "set-rootKeyThumb" +#define NID_set_rootKeyThumb 624 +#define OBJ_set_rootKeyThumb 2L, 23L, 42L, 3L, 0L, 0L + +#define SN_set_addPolicy "set-addPolicy" +#define NID_set_addPolicy 625 +#define OBJ_set_addPolicy 2L, 23L, 42L, 3L, 0L, 1L + +#define SN_setAttr_Token_EMV "setAttr-Token-EMV" +#define NID_setAttr_Token_EMV 626 +#define OBJ_setAttr_Token_EMV 2L, 23L, 42L, 3L, 2L, 1L + +#define SN_setAttr_Token_B0Prime "setAttr-Token-B0Prime" +#define NID_setAttr_Token_B0Prime 627 +#define OBJ_setAttr_Token_B0Prime 2L, 23L, 42L, 3L, 2L, 2L + +#define SN_setAttr_IssCap_CVM "setAttr-IssCap-CVM" +#define NID_setAttr_IssCap_CVM 628 +#define OBJ_setAttr_IssCap_CVM 2L, 23L, 42L, 3L, 3L, 3L + +#define SN_setAttr_IssCap_T2 "setAttr-IssCap-T2" +#define NID_setAttr_IssCap_T2 629 +#define OBJ_setAttr_IssCap_T2 2L, 23L, 42L, 3L, 3L, 4L + +#define SN_setAttr_IssCap_Sig "setAttr-IssCap-Sig" +#define NID_setAttr_IssCap_Sig 630 +#define OBJ_setAttr_IssCap_Sig 2L, 23L, 42L, 3L, 3L, 5L + +#define SN_setAttr_GenCryptgrm "setAttr-GenCryptgrm" +#define LN_setAttr_GenCryptgrm "generate cryptogram" +#define NID_setAttr_GenCryptgrm 631 +#define OBJ_setAttr_GenCryptgrm 2L, 23L, 42L, 3L, 3L, 3L, 1L + +#define SN_setAttr_T2Enc "setAttr-T2Enc" +#define LN_setAttr_T2Enc "encrypted track 2" +#define NID_setAttr_T2Enc 632 +#define OBJ_setAttr_T2Enc 2L, 23L, 42L, 3L, 3L, 4L, 1L + +#define SN_setAttr_T2cleartxt "setAttr-T2cleartxt" +#define LN_setAttr_T2cleartxt "cleartext track 2" +#define NID_setAttr_T2cleartxt 633 +#define OBJ_setAttr_T2cleartxt 2L, 23L, 42L, 3L, 3L, 4L, 2L + +#define SN_setAttr_TokICCsig "setAttr-TokICCsig" +#define LN_setAttr_TokICCsig "ICC or token signature" +#define NID_setAttr_TokICCsig 634 +#define OBJ_setAttr_TokICCsig 2L, 23L, 42L, 3L, 3L, 5L, 1L + +#define SN_setAttr_SecDevSig "setAttr-SecDevSig" +#define LN_setAttr_SecDevSig "secure device signature" +#define NID_setAttr_SecDevSig 635 +#define OBJ_setAttr_SecDevSig 2L, 23L, 42L, 3L, 3L, 5L, 2L + +#define SN_set_brand_IATA_ATA "set-brand-IATA-ATA" +#define NID_set_brand_IATA_ATA 636 +#define OBJ_set_brand_IATA_ATA 2L, 23L, 42L, 8L, 1L + +#define SN_set_brand_Diners "set-brand-Diners" +#define NID_set_brand_Diners 637 +#define OBJ_set_brand_Diners 2L, 23L, 42L, 8L, 30L + +#define SN_set_brand_AmericanExpress "set-brand-AmericanExpress" +#define NID_set_brand_AmericanExpress 638 +#define OBJ_set_brand_AmericanExpress 2L, 23L, 42L, 8L, 34L + +#define SN_set_brand_JCB "set-brand-JCB" +#define NID_set_brand_JCB 639 +#define OBJ_set_brand_JCB 2L, 23L, 42L, 8L, 35L + +#define SN_set_brand_Visa "set-brand-Visa" +#define NID_set_brand_Visa 640 +#define OBJ_set_brand_Visa 2L, 23L, 42L, 8L, 4L + +#define SN_set_brand_MasterCard "set-brand-MasterCard" +#define NID_set_brand_MasterCard 641 +#define OBJ_set_brand_MasterCard 2L, 23L, 42L, 8L, 5L + +#define SN_set_brand_Novus "set-brand-Novus" +#define NID_set_brand_Novus 642 +#define OBJ_set_brand_Novus 2L, 23L, 42L, 8L, 6011L + +#define SN_des_cdmf "DES-CDMF" +#define LN_des_cdmf "des-cdmf" +#define NID_des_cdmf 643 +#define OBJ_des_cdmf 1L, 2L, 840L, 113549L, 3L, 10L + +#define SN_rsaOAEPEncryptionSET "rsaOAEPEncryptionSET" +#define NID_rsaOAEPEncryptionSET 644 +#define OBJ_rsaOAEPEncryptionSET 1L, 2L, 840L, 113549L, 1L, 1L, 6L + +#define SN_itu_t "ITU-T" +#define LN_itu_t "itu-t" +#define NID_itu_t 645 +#define OBJ_itu_t 0L + +#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 SN_international_organizations "international-organizations" +#define LN_international_organizations "International Organizations" +#define NID_international_organizations 647 +#define OBJ_international_organizations 2L, 23L + +#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_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_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 SN_streetAddress "street" +#define LN_streetAddress "streetAddress" +#define NID_streetAddress 660 +#define OBJ_streetAddress 2L, 5L, 4L, 9L + +#define LN_postalCode "postalCode" +#define NID_postalCode 661 +#define OBJ_postalCode 2L, 5L, 4L, 17L + +#define SN_id_ppl "id-ppl" +#define NID_id_ppl 662 +#define OBJ_id_ppl 1L, 3L, 6L, 1L, 5L, 5L, 7L, 21L + +#define SN_proxyCertInfo "proxyCertInfo" +#define LN_proxyCertInfo "Proxy Certificate Information" +#define NID_proxyCertInfo 663 +#define OBJ_proxyCertInfo 1L, 3L, 6L, 1L, 5L, 5L, 7L, 1L, 14L + +#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 1L, 3L, 6L, 1L, 5L, 5L, 7L, 21L, 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 1L, 3L, 6L, 1L, 5L, 5L, 7L, 21L, 1L + +#define SN_name_constraints "nameConstraints" +#define LN_name_constraints "X509v3 Name Constraints" +#define NID_name_constraints 666 +#define OBJ_name_constraints 2L, 5L, 29L, 30L + +#define SN_Independent "id-ppl-independent" +#define LN_Independent "Independent" +#define NID_Independent 667 +#define OBJ_Independent 1L, 3L, 6L, 1L, 5L, 5L, 7L, 21L, 2L + +#define SN_sha256WithRSAEncryption "RSA-SHA256" +#define LN_sha256WithRSAEncryption "sha256WithRSAEncryption" +#define NID_sha256WithRSAEncryption 668 +#define OBJ_sha256WithRSAEncryption 1L, 2L, 840L, 113549L, 1L, 1L, 11L + +#define SN_sha384WithRSAEncryption "RSA-SHA384" +#define LN_sha384WithRSAEncryption "sha384WithRSAEncryption" +#define NID_sha384WithRSAEncryption 669 +#define OBJ_sha384WithRSAEncryption 1L, 2L, 840L, 113549L, 1L, 1L, 12L + +#define SN_sha512WithRSAEncryption "RSA-SHA512" +#define LN_sha512WithRSAEncryption "sha512WithRSAEncryption" +#define NID_sha512WithRSAEncryption 670 +#define OBJ_sha512WithRSAEncryption 1L, 2L, 840L, 113549L, 1L, 1L, 13L + +#define SN_sha224WithRSAEncryption "RSA-SHA224" +#define LN_sha224WithRSAEncryption "sha224WithRSAEncryption" +#define NID_sha224WithRSAEncryption 671 +#define OBJ_sha224WithRSAEncryption 1L, 2L, 840L, 113549L, 1L, 1L, 14L + +#define SN_sha256 "SHA256" +#define LN_sha256 "sha256" +#define NID_sha256 672 +#define OBJ_sha256 2L, 16L, 840L, 1L, 101L, 3L, 4L, 2L, 1L + +#define SN_sha384 "SHA384" +#define LN_sha384 "sha384" +#define NID_sha384 673 +#define OBJ_sha384 2L, 16L, 840L, 1L, 101L, 3L, 4L, 2L, 2L + +#define SN_sha512 "SHA512" +#define LN_sha512 "sha512" +#define NID_sha512 674 +#define OBJ_sha512 2L, 16L, 840L, 1L, 101L, 3L, 4L, 2L, 3L + +#define SN_sha224 "SHA224" +#define LN_sha224 "sha224" +#define NID_sha224 675 +#define OBJ_sha224 2L, 16L, 840L, 1L, 101L, 3L, 4L, 2L, 4L + +#define SN_identified_organization "identified-organization" +#define NID_identified_organization 676 +#define OBJ_identified_organization 1L, 3L + +#define SN_certicom_arc "certicom-arc" +#define NID_certicom_arc 677 +#define OBJ_certicom_arc 1L, 3L, 132L + +#define SN_wap "wap" +#define NID_wap 678 +#define OBJ_wap 2L, 23L, 43L + +#define SN_wap_wsg "wap-wsg" +#define NID_wap_wsg 679 +#define OBJ_wap_wsg 2L, 23L, 43L, 1L + +#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 1L, 2L, 840L, 10045L, 1L, 2L, 3L + +#define SN_X9_62_onBasis "onBasis" +#define NID_X9_62_onBasis 681 +#define OBJ_X9_62_onBasis 1L, 2L, 840L, 10045L, 1L, 2L, 3L, 1L + +#define SN_X9_62_tpBasis "tpBasis" +#define NID_X9_62_tpBasis 682 +#define OBJ_X9_62_tpBasis 1L, 2L, 840L, 10045L, 1L, 2L, 3L, 2L + +#define SN_X9_62_ppBasis "ppBasis" +#define NID_X9_62_ppBasis 683 +#define OBJ_X9_62_ppBasis 1L, 2L, 840L, 10045L, 1L, 2L, 3L, 3L + +#define SN_X9_62_c2pnb163v1 "c2pnb163v1" +#define NID_X9_62_c2pnb163v1 684 +#define OBJ_X9_62_c2pnb163v1 1L, 2L, 840L, 10045L, 3L, 0L, 1L + +#define SN_X9_62_c2pnb163v2 "c2pnb163v2" +#define NID_X9_62_c2pnb163v2 685 +#define OBJ_X9_62_c2pnb163v2 1L, 2L, 840L, 10045L, 3L, 0L, 2L + +#define SN_X9_62_c2pnb163v3 "c2pnb163v3" +#define NID_X9_62_c2pnb163v3 686 +#define OBJ_X9_62_c2pnb163v3 1L, 2L, 840L, 10045L, 3L, 0L, 3L + +#define SN_X9_62_c2pnb176v1 "c2pnb176v1" +#define NID_X9_62_c2pnb176v1 687 +#define OBJ_X9_62_c2pnb176v1 1L, 2L, 840L, 10045L, 3L, 0L, 4L + +#define SN_X9_62_c2tnb191v1 "c2tnb191v1" +#define NID_X9_62_c2tnb191v1 688 +#define OBJ_X9_62_c2tnb191v1 1L, 2L, 840L, 10045L, 3L, 0L, 5L + +#define SN_X9_62_c2tnb191v2 "c2tnb191v2" +#define NID_X9_62_c2tnb191v2 689 +#define OBJ_X9_62_c2tnb191v2 1L, 2L, 840L, 10045L, 3L, 0L, 6L + +#define SN_X9_62_c2tnb191v3 "c2tnb191v3" +#define NID_X9_62_c2tnb191v3 690 +#define OBJ_X9_62_c2tnb191v3 1L, 2L, 840L, 10045L, 3L, 0L, 7L + +#define SN_X9_62_c2onb191v4 "c2onb191v4" +#define NID_X9_62_c2onb191v4 691 +#define OBJ_X9_62_c2onb191v4 1L, 2L, 840L, 10045L, 3L, 0L, 8L + +#define SN_X9_62_c2onb191v5 "c2onb191v5" +#define NID_X9_62_c2onb191v5 692 +#define OBJ_X9_62_c2onb191v5 1L, 2L, 840L, 10045L, 3L, 0L, 9L + +#define SN_X9_62_c2pnb208w1 "c2pnb208w1" +#define NID_X9_62_c2pnb208w1 693 +#define OBJ_X9_62_c2pnb208w1 1L, 2L, 840L, 10045L, 3L, 0L, 10L + +#define SN_X9_62_c2tnb239v1 "c2tnb239v1" +#define NID_X9_62_c2tnb239v1 694 +#define OBJ_X9_62_c2tnb239v1 1L, 2L, 840L, 10045L, 3L, 0L, 11L + +#define SN_X9_62_c2tnb239v2 "c2tnb239v2" +#define NID_X9_62_c2tnb239v2 695 +#define OBJ_X9_62_c2tnb239v2 1L, 2L, 840L, 10045L, 3L, 0L, 12L + +#define SN_X9_62_c2tnb239v3 "c2tnb239v3" +#define NID_X9_62_c2tnb239v3 696 +#define OBJ_X9_62_c2tnb239v3 1L, 2L, 840L, 10045L, 3L, 0L, 13L + +#define SN_X9_62_c2onb239v4 "c2onb239v4" +#define NID_X9_62_c2onb239v4 697 +#define OBJ_X9_62_c2onb239v4 1L, 2L, 840L, 10045L, 3L, 0L, 14L + +#define SN_X9_62_c2onb239v5 "c2onb239v5" +#define NID_X9_62_c2onb239v5 698 +#define OBJ_X9_62_c2onb239v5 1L, 2L, 840L, 10045L, 3L, 0L, 15L + +#define SN_X9_62_c2pnb272w1 "c2pnb272w1" +#define NID_X9_62_c2pnb272w1 699 +#define OBJ_X9_62_c2pnb272w1 1L, 2L, 840L, 10045L, 3L, 0L, 16L + +#define SN_X9_62_c2pnb304w1 "c2pnb304w1" +#define NID_X9_62_c2pnb304w1 700 +#define OBJ_X9_62_c2pnb304w1 1L, 2L, 840L, 10045L, 3L, 0L, 17L + +#define SN_X9_62_c2tnb359v1 "c2tnb359v1" +#define NID_X9_62_c2tnb359v1 701 +#define OBJ_X9_62_c2tnb359v1 1L, 2L, 840L, 10045L, 3L, 0L, 18L + +#define SN_X9_62_c2pnb368w1 "c2pnb368w1" +#define NID_X9_62_c2pnb368w1 702 +#define OBJ_X9_62_c2pnb368w1 1L, 2L, 840L, 10045L, 3L, 0L, 19L + +#define SN_X9_62_c2tnb431r1 "c2tnb431r1" +#define NID_X9_62_c2tnb431r1 703 +#define OBJ_X9_62_c2tnb431r1 1L, 2L, 840L, 10045L, 3L, 0L, 20L + +#define SN_secp112r1 "secp112r1" +#define NID_secp112r1 704 +#define OBJ_secp112r1 1L, 3L, 132L, 0L, 6L + +#define SN_secp112r2 "secp112r2" +#define NID_secp112r2 705 +#define OBJ_secp112r2 1L, 3L, 132L, 0L, 7L + +#define SN_secp128r1 "secp128r1" +#define NID_secp128r1 706 +#define OBJ_secp128r1 1L, 3L, 132L, 0L, 28L + +#define SN_secp128r2 "secp128r2" +#define NID_secp128r2 707 +#define OBJ_secp128r2 1L, 3L, 132L, 0L, 29L + +#define SN_secp160k1 "secp160k1" +#define NID_secp160k1 708 +#define OBJ_secp160k1 1L, 3L, 132L, 0L, 9L + +#define SN_secp160r1 "secp160r1" +#define NID_secp160r1 709 +#define OBJ_secp160r1 1L, 3L, 132L, 0L, 8L + +#define SN_secp160r2 "secp160r2" +#define NID_secp160r2 710 +#define OBJ_secp160r2 1L, 3L, 132L, 0L, 30L + +#define SN_secp192k1 "secp192k1" +#define NID_secp192k1 711 +#define OBJ_secp192k1 1L, 3L, 132L, 0L, 31L + +#define SN_secp224k1 "secp224k1" +#define NID_secp224k1 712 +#define OBJ_secp224k1 1L, 3L, 132L, 0L, 32L + +#define SN_secp224r1 "secp224r1" +#define NID_secp224r1 713 +#define OBJ_secp224r1 1L, 3L, 132L, 0L, 33L + +#define SN_secp256k1 "secp256k1" +#define NID_secp256k1 714 +#define OBJ_secp256k1 1L, 3L, 132L, 0L, 10L + +#define SN_secp384r1 "secp384r1" +#define NID_secp384r1 715 +#define OBJ_secp384r1 1L, 3L, 132L, 0L, 34L + +#define SN_secp521r1 "secp521r1" +#define NID_secp521r1 716 +#define OBJ_secp521r1 1L, 3L, 132L, 0L, 35L + +#define SN_sect113r1 "sect113r1" +#define NID_sect113r1 717 +#define OBJ_sect113r1 1L, 3L, 132L, 0L, 4L + +#define SN_sect113r2 "sect113r2" +#define NID_sect113r2 718 +#define OBJ_sect113r2 1L, 3L, 132L, 0L, 5L + +#define SN_sect131r1 "sect131r1" +#define NID_sect131r1 719 +#define OBJ_sect131r1 1L, 3L, 132L, 0L, 22L + +#define SN_sect131r2 "sect131r2" +#define NID_sect131r2 720 +#define OBJ_sect131r2 1L, 3L, 132L, 0L, 23L + +#define SN_sect163k1 "sect163k1" +#define NID_sect163k1 721 +#define OBJ_sect163k1 1L, 3L, 132L, 0L, 1L + +#define SN_sect163r1 "sect163r1" +#define NID_sect163r1 722 +#define OBJ_sect163r1 1L, 3L, 132L, 0L, 2L + +#define SN_sect163r2 "sect163r2" +#define NID_sect163r2 723 +#define OBJ_sect163r2 1L, 3L, 132L, 0L, 15L + +#define SN_sect193r1 "sect193r1" +#define NID_sect193r1 724 +#define OBJ_sect193r1 1L, 3L, 132L, 0L, 24L + +#define SN_sect193r2 "sect193r2" +#define NID_sect193r2 725 +#define OBJ_sect193r2 1L, 3L, 132L, 0L, 25L + +#define SN_sect233k1 "sect233k1" +#define NID_sect233k1 726 +#define OBJ_sect233k1 1L, 3L, 132L, 0L, 26L + +#define SN_sect233r1 "sect233r1" +#define NID_sect233r1 727 +#define OBJ_sect233r1 1L, 3L, 132L, 0L, 27L + +#define SN_sect239k1 "sect239k1" +#define NID_sect239k1 728 +#define OBJ_sect239k1 1L, 3L, 132L, 0L, 3L + +#define SN_sect283k1 "sect283k1" +#define NID_sect283k1 729 +#define OBJ_sect283k1 1L, 3L, 132L, 0L, 16L + +#define SN_sect283r1 "sect283r1" +#define NID_sect283r1 730 +#define OBJ_sect283r1 1L, 3L, 132L, 0L, 17L + +#define SN_sect409k1 "sect409k1" +#define NID_sect409k1 731 +#define OBJ_sect409k1 1L, 3L, 132L, 0L, 36L + +#define SN_sect409r1 "sect409r1" +#define NID_sect409r1 732 +#define OBJ_sect409r1 1L, 3L, 132L, 0L, 37L + +#define SN_sect571k1 "sect571k1" +#define NID_sect571k1 733 +#define OBJ_sect571k1 1L, 3L, 132L, 0L, 38L + +#define SN_sect571r1 "sect571r1" +#define NID_sect571r1 734 +#define OBJ_sect571r1 1L, 3L, 132L, 0L, 39L + +#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 2L, 23L, 43L, 1L, 4L, 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 2L, 23L, 43L, 1L, 4L, 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 2L, 23L, 43L, 1L, 4L, 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 2L, 23L, 43L, 1L, 4L, 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 2L, 23L, 43L, 1L, 4L, 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 2L, 23L, 43L, 1L, 4L, 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 2L, 23L, 43L, 1L, 4L, 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 2L, 23L, 43L, 1L, 4L, 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 2L, 23L, 43L, 1L, 4L, 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 2L, 23L, 43L, 1L, 4L, 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 2L, 23L, 43L, 1L, 4L, 12L + +#define SN_any_policy "anyPolicy" +#define LN_any_policy "X509v3 Any Policy" +#define NID_any_policy 746 +#define OBJ_any_policy 2L, 5L, 29L, 32L, 0L + +#define SN_policy_mappings "policyMappings" +#define LN_policy_mappings "X509v3 Policy Mappings" +#define NID_policy_mappings 747 +#define OBJ_policy_mappings 2L, 5L, 29L, 33L + +#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 2L, 5L, 29L, 54L + +#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_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_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 0L, 3L, 4401L, 5L, 3L, 1L, 9L, 1L + +#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 0L, 3L, 4401L, 5L, 3L, 1L, 9L, 21L + +#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 0L, 3L, 4401L, 5L, 3L, 1L, 9L, 41L + +#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 0L, 3L, 4401L, 5L, 3L, 1L, 9L, 4L + +#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 0L, 3L, 4401L, 5L, 3L, 1L, 9L, 24L + +#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 0L, 3L, 4401L, 5L, 3L, 1L, 9L, 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_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 0L, 3L, 4401L, 5L, 3L, 1L, 9L, 3L + +#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 0L, 3L, 4401L, 5L, 3L, 1L, 9L, 23L + +#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 0L, 3L, 4401L, 5L, 3L, 1L, 9L, 43L + +#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 2L, 5L, 29L, 9L + +#define SN_issuing_distribution_point "issuingDistributionPoint" +#define LN_issuing_distribution_point "X509v3 Issuing Distribution Point" +#define NID_issuing_distribution_point 770 +#define OBJ_issuing_distribution_point 2L, 5L, 29L, 28L + +#define SN_certificate_issuer "certificateIssuer" +#define LN_certificate_issuer "X509v3 Certificate Issuer" +#define NID_certificate_issuer 771 +#define OBJ_certificate_issuer 2L, 5L, 29L, 29L + +#define SN_kisa "KISA" +#define LN_kisa "kisa" +#define NID_kisa 773 +#define OBJ_kisa 1L, 2L, 410L, 200004L + +#define SN_seed_ecb "SEED-ECB" +#define LN_seed_ecb "seed-ecb" +#define NID_seed_ecb 776 +#define OBJ_seed_ecb 1L, 2L, 410L, 200004L, 1L, 3L + +#define SN_seed_cbc "SEED-CBC" +#define LN_seed_cbc "seed-cbc" +#define NID_seed_cbc 777 +#define OBJ_seed_cbc 1L, 2L, 410L, 200004L, 1L, 4L + +#define SN_seed_ofb128 "SEED-OFB" +#define LN_seed_ofb128 "seed-ofb" +#define NID_seed_ofb128 778 +#define OBJ_seed_ofb128 1L, 2L, 410L, 200004L, 1L, 6L + +#define SN_seed_cfb128 "SEED-CFB" +#define LN_seed_cfb128 "seed-cfb" +#define NID_seed_cfb128 779 +#define OBJ_seed_cfb128 1L, 2L, 410L, 200004L, 1L, 5L + +#define SN_hmac_md5 "HMAC-MD5" +#define LN_hmac_md5 "hmac-md5" +#define NID_hmac_md5 780 +#define OBJ_hmac_md5 1L, 3L, 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 1L, 3L, 6L, 1L, 5L, 5L, 8L, 1L, 2L + +#define SN_id_PasswordBasedMAC "id-PasswordBasedMAC" +#define LN_id_PasswordBasedMAC "password based MAC" +#define NID_id_PasswordBasedMAC 782 +#define OBJ_id_PasswordBasedMAC 1L, 2L, 840L, 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 1L, 2L, 840L, 113533L, 7L, 66L, 30L + +#define SN_id_it_suppLangTags "id-it-suppLangTags" +#define NID_id_it_suppLangTags 784 +#define OBJ_id_it_suppLangTags 1L, 3L, 6L, 1L, 5L, 5L, 7L, 4L, 16L + +#define SN_caRepository "caRepository" +#define LN_caRepository "CA Repository" +#define NID_caRepository 785 +#define OBJ_caRepository 1L, 3L, 6L, 1L, 5L, 5L, 7L, 48L, 5L + +#define SN_id_smime_ct_compressedData "id-smime-ct-compressedData" +#define NID_id_smime_ct_compressedData 786 +#define OBJ_id_smime_ct_compressedData \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 1L, 9L + +#define SN_id_ct_asciiTextWithCRLF "id-ct-asciiTextWithCRLF" +#define NID_id_ct_asciiTextWithCRLF 787 +#define OBJ_id_ct_asciiTextWithCRLF 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 1L, 27L + +#define SN_id_aes128_wrap "id-aes128-wrap" +#define NID_id_aes128_wrap 788 +#define OBJ_id_aes128_wrap 2L, 16L, 840L, 1L, 101L, 3L, 4L, 1L, 5L + +#define SN_id_aes192_wrap "id-aes192-wrap" +#define NID_id_aes192_wrap 789 +#define OBJ_id_aes192_wrap 2L, 16L, 840L, 1L, 101L, 3L, 4L, 1L, 25L + +#define SN_id_aes256_wrap "id-aes256-wrap" +#define NID_id_aes256_wrap 790 +#define OBJ_id_aes256_wrap 2L, 16L, 840L, 1L, 101L, 3L, 4L, 1L, 45L + +#define SN_ecdsa_with_Recommended "ecdsa-with-Recommended" +#define NID_ecdsa_with_Recommended 791 +#define OBJ_ecdsa_with_Recommended 1L, 2L, 840L, 10045L, 4L, 2L + +#define SN_ecdsa_with_Specified "ecdsa-with-Specified" +#define NID_ecdsa_with_Specified 792 +#define OBJ_ecdsa_with_Specified 1L, 2L, 840L, 10045L, 4L, 3L + +#define SN_ecdsa_with_SHA224 "ecdsa-with-SHA224" +#define NID_ecdsa_with_SHA224 793 +#define OBJ_ecdsa_with_SHA224 1L, 2L, 840L, 10045L, 4L, 3L, 1L + +#define SN_ecdsa_with_SHA256 "ecdsa-with-SHA256" +#define NID_ecdsa_with_SHA256 794 +#define OBJ_ecdsa_with_SHA256 1L, 2L, 840L, 10045L, 4L, 3L, 2L + +#define SN_ecdsa_with_SHA384 "ecdsa-with-SHA384" +#define NID_ecdsa_with_SHA384 795 +#define OBJ_ecdsa_with_SHA384 1L, 2L, 840L, 10045L, 4L, 3L, 3L + +#define SN_ecdsa_with_SHA512 "ecdsa-with-SHA512" +#define NID_ecdsa_with_SHA512 796 +#define OBJ_ecdsa_with_SHA512 1L, 2L, 840L, 10045L, 4L, 3L, 4L + +#define LN_hmacWithMD5 "hmacWithMD5" +#define NID_hmacWithMD5 797 +#define OBJ_hmacWithMD5 1L, 2L, 840L, 113549L, 2L, 6L + +#define LN_hmacWithSHA224 "hmacWithSHA224" +#define NID_hmacWithSHA224 798 +#define OBJ_hmacWithSHA224 1L, 2L, 840L, 113549L, 2L, 8L + +#define LN_hmacWithSHA256 "hmacWithSHA256" +#define NID_hmacWithSHA256 799 +#define OBJ_hmacWithSHA256 1L, 2L, 840L, 113549L, 2L, 9L + +#define LN_hmacWithSHA384 "hmacWithSHA384" +#define NID_hmacWithSHA384 800 +#define OBJ_hmacWithSHA384 1L, 2L, 840L, 113549L, 2L, 10L + +#define LN_hmacWithSHA512 "hmacWithSHA512" +#define NID_hmacWithSHA512 801 +#define OBJ_hmacWithSHA512 1L, 2L, 840L, 113549L, 2L, 11L + +#define SN_dsa_with_SHA224 "dsa_with_SHA224" +#define NID_dsa_with_SHA224 802 +#define OBJ_dsa_with_SHA224 2L, 16L, 840L, 1L, 101L, 3L, 4L, 3L, 1L + +#define SN_dsa_with_SHA256 "dsa_with_SHA256" +#define NID_dsa_with_SHA256 803 +#define OBJ_dsa_with_SHA256 2L, 16L, 840L, 1L, 101L, 3L, 4L, 3L, 2L + +#define SN_whirlpool "whirlpool" +#define NID_whirlpool 804 +#define OBJ_whirlpool 1L, 0L, 10118L, 3L, 0L, 55L + +#define SN_cryptopro "cryptopro" +#define NID_cryptopro 805 +#define OBJ_cryptopro 1L, 2L, 643L, 2L, 2L + +#define SN_cryptocom "cryptocom" +#define NID_cryptocom 806 +#define OBJ_cryptocom 1L, 2L, 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 1L, 2L, 643L, 2L, 2L, 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 1L, 2L, 643L, 2L, 2L, 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 1L, 2L, 643L, 2L, 2L, 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 1L, 2L, 643L, 2L, 2L, 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 1L, 2L, 643L, 2L, 2L, 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 1L, 2L, 643L, 2L, 2L, 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 1L, 2L, 643L, 2L, 2L, 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 1L, 2L, 643L, 2L, 2L, 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 1L, 2L, 643L, 2L, 2L, 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 1L, 2L, 643L, 2L, 2L, 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 1L, 2L, 643L, 2L, 2L, 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 1L, 2L, 643L, 2L, 2L, 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 1L, 2L, 643L, 2L, 2L, 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 1L, 2L, 643L, 2L, 2L, 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 1L, 2L, 643L, 2L, 2L, 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 1L, 2L, 643L, 2L, 2L, 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 1L, 2L, 643L, 2L, 2L, 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 1L, 2L, 643L, 2L, 2L, 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 1L, 2L, 643L, 2L, 2L, 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 1L, 2L, 643L, 2L, 2L, 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 \ + 1L, 2L, 643L, 2L, 2L, 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 \ + 1L, 2L, 643L, 2L, 2L, 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 \ + 1L, 2L, 643L, 2L, 2L, 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 1L, 2L, 643L, 2L, 2L, 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 1L, 2L, 643L, 2L, 2L, 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 1L, 2L, 643L, 2L, 2L, 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 1L, 2L, 643L, 2L, 2L, 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 1L, 2L, 643L, 2L, 2L, 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 \ + 1L, 2L, 643L, 2L, 2L, 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 \ + 1L, 2L, 643L, 2L, 2L, 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 \ + 1L, 2L, 643L, 2L, 2L, 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 1L, 2L, 643L, 2L, 2L, 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 1L, 2L, 643L, 2L, 2L, 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 1L, 2L, 643L, 2L, 2L, 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 1L, 2L, 643L, 2L, 2L, 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 \ + 1L, 2L, 643L, 2L, 2L, 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 \ + 1L, 2L, 643L, 2L, 2L, 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 1L, 2L, 643L, 2L, 2L, 20L, 1L + +#define SN_id_GostR3410_94_aBis "id-GostR3410-94-aBis" +#define NID_id_GostR3410_94_aBis 846 +#define OBJ_id_GostR3410_94_aBis 1L, 2L, 643L, 2L, 2L, 20L, 2L + +#define SN_id_GostR3410_94_b "id-GostR3410-94-b" +#define NID_id_GostR3410_94_b 847 +#define OBJ_id_GostR3410_94_b 1L, 2L, 643L, 2L, 2L, 20L, 3L + +#define SN_id_GostR3410_94_bBis "id-GostR3410-94-bBis" +#define NID_id_GostR3410_94_bBis 848 +#define OBJ_id_GostR3410_94_bBis 1L, 2L, 643L, 2L, 2L, 20L, 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 1L, 2L, 643L, 2L, 9L, 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 1L, 2L, 643L, 2L, 9L, 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 1L, 2L, 643L, 2L, 9L, 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 \ + 1L, 2L, 643L, 2L, 9L, 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 \ + 1L, 2L, 643L, 2L, 9L, 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 1L, 2L, 643L, 2L, 9L, 1L, 8L, 1L + +#define SN_hmac "HMAC" +#define LN_hmac "hmac" +#define NID_hmac 855 + +#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 SN_freshest_crl "freshestCRL" +#define LN_freshest_crl "X509v3 Freshest CRL" +#define NID_freshest_crl 857 +#define OBJ_freshest_crl 2L, 5L, 29L, 46L + +#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 1L, 3L, 6L, 1L, 5L, 5L, 7L, 8L, 3L + +#define LN_searchGuide "searchGuide" +#define NID_searchGuide 859 +#define OBJ_searchGuide 2L, 5L, 4L, 14L + +#define LN_businessCategory "businessCategory" +#define NID_businessCategory 860 +#define OBJ_businessCategory 2L, 5L, 4L, 15L + +#define LN_postalAddress "postalAddress" +#define NID_postalAddress 861 +#define OBJ_postalAddress 2L, 5L, 4L, 16L + +#define LN_postOfficeBox "postOfficeBox" +#define NID_postOfficeBox 862 +#define OBJ_postOfficeBox 2L, 5L, 4L, 18L + +#define LN_physicalDeliveryOfficeName "physicalDeliveryOfficeName" +#define NID_physicalDeliveryOfficeName 863 +#define OBJ_physicalDeliveryOfficeName 2L, 5L, 4L, 19L + +#define LN_telephoneNumber "telephoneNumber" +#define NID_telephoneNumber 864 +#define OBJ_telephoneNumber 2L, 5L, 4L, 20L + +#define LN_telexNumber "telexNumber" +#define NID_telexNumber 865 +#define OBJ_telexNumber 2L, 5L, 4L, 21L + +#define LN_teletexTerminalIdentifier "teletexTerminalIdentifier" +#define NID_teletexTerminalIdentifier 866 +#define OBJ_teletexTerminalIdentifier 2L, 5L, 4L, 22L + +#define LN_facsimileTelephoneNumber "facsimileTelephoneNumber" +#define NID_facsimileTelephoneNumber 867 +#define OBJ_facsimileTelephoneNumber 2L, 5L, 4L, 23L + +#define LN_x121Address "x121Address" +#define NID_x121Address 868 +#define OBJ_x121Address 2L, 5L, 4L, 24L + +#define LN_internationaliSDNNumber "internationaliSDNNumber" +#define NID_internationaliSDNNumber 869 +#define OBJ_internationaliSDNNumber 2L, 5L, 4L, 25L + +#define LN_registeredAddress "registeredAddress" +#define NID_registeredAddress 870 +#define OBJ_registeredAddress 2L, 5L, 4L, 26L + +#define LN_destinationIndicator "destinationIndicator" +#define NID_destinationIndicator 871 +#define OBJ_destinationIndicator 2L, 5L, 4L, 27L + +#define LN_preferredDeliveryMethod "preferredDeliveryMethod" +#define NID_preferredDeliveryMethod 872 +#define OBJ_preferredDeliveryMethod 2L, 5L, 4L, 28L + +#define LN_presentationAddress "presentationAddress" +#define NID_presentationAddress 873 +#define OBJ_presentationAddress 2L, 5L, 4L, 29L + +#define LN_supportedApplicationContext "supportedApplicationContext" +#define NID_supportedApplicationContext 874 +#define OBJ_supportedApplicationContext 2L, 5L, 4L, 30L + +#define SN_member "member" +#define NID_member 875 +#define OBJ_member 2L, 5L, 4L, 31L + +#define SN_owner "owner" +#define NID_owner 876 +#define OBJ_owner 2L, 5L, 4L, 32L + +#define LN_roleOccupant "roleOccupant" +#define NID_roleOccupant 877 +#define OBJ_roleOccupant 2L, 5L, 4L, 33L + +#define SN_seeAlso "seeAlso" +#define NID_seeAlso 878 +#define OBJ_seeAlso 2L, 5L, 4L, 34L + +#define LN_userPassword "userPassword" +#define NID_userPassword 879 +#define OBJ_userPassword 2L, 5L, 4L, 35L + +#define LN_userCertificate "userCertificate" +#define NID_userCertificate 880 +#define OBJ_userCertificate 2L, 5L, 4L, 36L + +#define LN_cACertificate "cACertificate" +#define NID_cACertificate 881 +#define OBJ_cACertificate 2L, 5L, 4L, 37L + +#define LN_authorityRevocationList "authorityRevocationList" +#define NID_authorityRevocationList 882 +#define OBJ_authorityRevocationList 2L, 5L, 4L, 38L + +#define LN_certificateRevocationList "certificateRevocationList" +#define NID_certificateRevocationList 883 +#define OBJ_certificateRevocationList 2L, 5L, 4L, 39L + +#define LN_crossCertificatePair "crossCertificatePair" +#define NID_crossCertificatePair 884 +#define OBJ_crossCertificatePair 2L, 5L, 4L, 40L + +#define LN_enhancedSearchGuide "enhancedSearchGuide" +#define NID_enhancedSearchGuide 885 +#define OBJ_enhancedSearchGuide 2L, 5L, 4L, 47L + +#define LN_protocolInformation "protocolInformation" +#define NID_protocolInformation 886 +#define OBJ_protocolInformation 2L, 5L, 4L, 48L + +#define LN_distinguishedName "distinguishedName" +#define NID_distinguishedName 887 +#define OBJ_distinguishedName 2L, 5L, 4L, 49L + +#define LN_uniqueMember "uniqueMember" +#define NID_uniqueMember 888 +#define OBJ_uniqueMember 2L, 5L, 4L, 50L + +#define LN_houseIdentifier "houseIdentifier" +#define NID_houseIdentifier 889 +#define OBJ_houseIdentifier 2L, 5L, 4L, 51L + +#define LN_supportedAlgorithms "supportedAlgorithms" +#define NID_supportedAlgorithms 890 +#define OBJ_supportedAlgorithms 2L, 5L, 4L, 52L + +#define LN_deltaRevocationList "deltaRevocationList" +#define NID_deltaRevocationList 891 +#define OBJ_deltaRevocationList 2L, 5L, 4L, 53L + +#define SN_dmdName "dmdName" +#define NID_dmdName 892 +#define OBJ_dmdName 2L, 5L, 4L, 54L + +#define SN_id_alg_PWRI_KEK "id-alg-PWRI-KEK" +#define NID_id_alg_PWRI_KEK 893 +#define OBJ_id_alg_PWRI_KEK 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 3L, 9L + +#define SN_cmac "CMAC" +#define LN_cmac "cmac" +#define NID_cmac 894 + +#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 2L, 16L, 840L, 1L, 101L, 3L, 4L, 1L, 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 2L, 16L, 840L, 1L, 101L, 3L, 4L, 1L, 7L + +#define SN_id_aes128_wrap_pad "id-aes128-wrap-pad" +#define NID_id_aes128_wrap_pad 897 +#define OBJ_id_aes128_wrap_pad 2L, 16L, 840L, 1L, 101L, 3L, 4L, 1L, 8L + +#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 2L, 16L, 840L, 1L, 101L, 3L, 4L, 1L, 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 2L, 16L, 840L, 1L, 101L, 3L, 4L, 1L, 27L + +#define SN_id_aes192_wrap_pad "id-aes192-wrap-pad" +#define NID_id_aes192_wrap_pad 900 +#define OBJ_id_aes192_wrap_pad 2L, 16L, 840L, 1L, 101L, 3L, 4L, 1L, 28L + +#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 2L, 16L, 840L, 1L, 101L, 3L, 4L, 1L, 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 2L, 16L, 840L, 1L, 101L, 3L, 4L, 1L, 47L + +#define SN_id_aes256_wrap_pad "id-aes256-wrap-pad" +#define NID_id_aes256_wrap_pad 903 +#define OBJ_id_aes256_wrap_pad 2L, 16L, 840L, 1L, 101L, 3L, 4L, 1L, 48L + +#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_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 SN_anyExtendedKeyUsage "anyExtendedKeyUsage" +#define LN_anyExtendedKeyUsage "Any Extended Key Usage" +#define NID_anyExtendedKeyUsage 910 +#define OBJ_anyExtendedKeyUsage 2L, 5L, 29L, 37L, 0L + +#define SN_mgf1 "MGF1" +#define LN_mgf1 "mgf1" +#define NID_mgf1 911 +#define OBJ_mgf1 1L, 2L, 840L, 113549L, 1L, 1L, 8L + +#define SN_rsassaPss "RSASSA-PSS" +#define LN_rsassaPss "rsassaPss" +#define NID_rsassaPss 912 +#define OBJ_rsassaPss 1L, 2L, 840L, 113549L, 1L, 1L, 10L + +#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_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_rsaesOaep "RSAES-OAEP" +#define LN_rsaesOaep "rsaesOaep" +#define NID_rsaesOaep 919 +#define OBJ_rsaesOaep 1L, 2L, 840L, 113549L, 1L, 1L, 7L + +#define SN_dhpublicnumber "dhpublicnumber" +#define LN_dhpublicnumber "X9.42 DH" +#define NID_dhpublicnumber 920 +#define OBJ_dhpublicnumber 1L, 2L, 840L, 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 SN_pSpecified "PSPECIFIED" +#define LN_pSpecified "pSpecified" +#define NID_pSpecified 935 +#define OBJ_pSpecified 1L, 2L, 840L, 113549L, 1L, 1L, 9L + +#define SN_dhSinglePass_stdDH_sha1kdf_scheme "dhSinglePass-stdDH-sha1kdf-scheme" +#define NID_dhSinglePass_stdDH_sha1kdf_scheme 936 +#define OBJ_dhSinglePass_stdDH_sha1kdf_scheme \ + 1L, 3L, 133L, 16L, 840L, 63L, 0L, 2L + +#define SN_dhSinglePass_stdDH_sha224kdf_scheme \ + "dhSinglePass-stdDH-sha224kdf-scheme" +#define NID_dhSinglePass_stdDH_sha224kdf_scheme 937 +#define OBJ_dhSinglePass_stdDH_sha224kdf_scheme 1L, 3L, 132L, 1L, 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 1L, 3L, 132L, 1L, 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 1L, 3L, 132L, 1L, 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 1L, 3L, 132L, 1L, 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 \ + 1L, 3L, 133L, 16L, 840L, 63L, 0L, 3L + +#define SN_dhSinglePass_cofactorDH_sha224kdf_scheme \ + "dhSinglePass-cofactorDH-sha224kdf-scheme" +#define NID_dhSinglePass_cofactorDH_sha224kdf_scheme 942 +#define OBJ_dhSinglePass_cofactorDH_sha224kdf_scheme 1L, 3L, 132L, 1L, 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 1L, 3L, 132L, 1L, 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 1L, 3L, 132L, 1L, 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 1L, 3L, 132L, 1L, 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_X25519 "X25519" +#define NID_X25519 948 + +#define SN_ED25519 "ED25519" +#define NID_ED25519 949 +#define OBJ_ED25519 1L, 3L, 101L, 112L + +#define SN_chacha20_poly1305 "ChaCha20-Poly1305" +#define LN_chacha20_poly1305 "chacha20-poly1305" +#define NID_chacha20_poly1305 950 + +#define SN_kx_rsa "KxRSA" +#define LN_kx_rsa "kx-rsa" +#define NID_kx_rsa 951 + +#define SN_kx_ecdhe "KxECDHE" +#define LN_kx_ecdhe "kx-ecdhe" +#define NID_kx_ecdhe 952 + +#define SN_kx_psk "KxPSK" +#define LN_kx_psk "kx-psk" +#define NID_kx_psk 953 + +#define SN_auth_rsa "AuthRSA" +#define LN_auth_rsa "auth-rsa" +#define NID_auth_rsa 954 + +#define SN_auth_ecdsa "AuthECDSA" +#define LN_auth_ecdsa "auth-ecdsa" +#define NID_auth_ecdsa 955 + +#define SN_auth_psk "AuthPSK" +#define LN_auth_psk "auth-psk" +#define NID_auth_psk 956 + +#define SN_kx_any "KxANY" +#define LN_kx_any "kx-any" +#define NID_kx_any 957 + +#define SN_auth_any "AuthANY" +#define LN_auth_any "auth-any" +#define NID_auth_any 958 + + +#if defined(__cplusplus) +} /* extern C */ +#endif + +#endif /* OPENSSL_HEADER_NID_H */ diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/nid.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/nid.h.grpc_back new file mode 100644 index 0000000..afeb2de --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/nid.h.grpc_back @@ -0,0 +1,4242 @@ +/* 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.] */ + +/* This file is generated by crypto/obj/objects.go. */ + +#ifndef OPENSSL_HEADER_NID_H +#define OPENSSL_HEADER_NID_H + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +/* The nid library provides numbered values for ASN.1 object identifiers and + * other symbols. These values are used by other libraries to identify + * cryptographic primitives. + * + * A separate objects library, obj.h, provides functions for converting between + * nids and object identifiers. However it depends on large internal tables with + * the encodings of every nid defined. Consumers concerned with binary size + * should instead embed the encodings of the few consumed OIDs and compare + * against those. + * + * These values should not be used outside of a single process; they are not + * stable identifiers. */ + + +#define SN_undef "UNDEF" +#define LN_undef "undefined" +#define NID_undef 0 +#define OBJ_undef 0L + +#define SN_rsadsi "rsadsi" +#define LN_rsadsi "RSA Data Security, Inc." +#define NID_rsadsi 1 +#define OBJ_rsadsi 1L, 2L, 840L, 113549L + +#define SN_pkcs "pkcs" +#define LN_pkcs "RSA Data Security, Inc. PKCS" +#define NID_pkcs 2 +#define OBJ_pkcs 1L, 2L, 840L, 113549L, 1L + +#define SN_md2 "MD2" +#define LN_md2 "md2" +#define NID_md2 3 +#define OBJ_md2 1L, 2L, 840L, 113549L, 2L, 2L + +#define SN_md5 "MD5" +#define LN_md5 "md5" +#define NID_md5 4 +#define OBJ_md5 1L, 2L, 840L, 113549L, 2L, 5L + +#define SN_rc4 "RC4" +#define LN_rc4 "rc4" +#define NID_rc4 5 +#define OBJ_rc4 1L, 2L, 840L, 113549L, 3L, 4L + +#define LN_rsaEncryption "rsaEncryption" +#define NID_rsaEncryption 6 +#define OBJ_rsaEncryption 1L, 2L, 840L, 113549L, 1L, 1L, 1L + +#define SN_md2WithRSAEncryption "RSA-MD2" +#define LN_md2WithRSAEncryption "md2WithRSAEncryption" +#define NID_md2WithRSAEncryption 7 +#define OBJ_md2WithRSAEncryption 1L, 2L, 840L, 113549L, 1L, 1L, 2L + +#define SN_md5WithRSAEncryption "RSA-MD5" +#define LN_md5WithRSAEncryption "md5WithRSAEncryption" +#define NID_md5WithRSAEncryption 8 +#define OBJ_md5WithRSAEncryption 1L, 2L, 840L, 113549L, 1L, 1L, 4L + +#define SN_pbeWithMD2AndDES_CBC "PBE-MD2-DES" +#define LN_pbeWithMD2AndDES_CBC "pbeWithMD2AndDES-CBC" +#define NID_pbeWithMD2AndDES_CBC 9 +#define OBJ_pbeWithMD2AndDES_CBC 1L, 2L, 840L, 113549L, 1L, 5L, 1L + +#define SN_pbeWithMD5AndDES_CBC "PBE-MD5-DES" +#define LN_pbeWithMD5AndDES_CBC "pbeWithMD5AndDES-CBC" +#define NID_pbeWithMD5AndDES_CBC 10 +#define OBJ_pbeWithMD5AndDES_CBC 1L, 2L, 840L, 113549L, 1L, 5L, 3L + +#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 2L, 5L, 4L + +#define SN_commonName "CN" +#define LN_commonName "commonName" +#define NID_commonName 13 +#define OBJ_commonName 2L, 5L, 4L, 3L + +#define SN_countryName "C" +#define LN_countryName "countryName" +#define NID_countryName 14 +#define OBJ_countryName 2L, 5L, 4L, 6L + +#define SN_localityName "L" +#define LN_localityName "localityName" +#define NID_localityName 15 +#define OBJ_localityName 2L, 5L, 4L, 7L + +#define SN_stateOrProvinceName "ST" +#define LN_stateOrProvinceName "stateOrProvinceName" +#define NID_stateOrProvinceName 16 +#define OBJ_stateOrProvinceName 2L, 5L, 4L, 8L + +#define SN_organizationName "O" +#define LN_organizationName "organizationName" +#define NID_organizationName 17 +#define OBJ_organizationName 2L, 5L, 4L, 10L + +#define SN_organizationalUnitName "OU" +#define LN_organizationalUnitName "organizationalUnitName" +#define NID_organizationalUnitName 18 +#define OBJ_organizationalUnitName 2L, 5L, 4L, 11L + +#define SN_rsa "RSA" +#define LN_rsa "rsa" +#define NID_rsa 19 +#define OBJ_rsa 2L, 5L, 8L, 1L, 1L + +#define SN_pkcs7 "pkcs7" +#define NID_pkcs7 20 +#define OBJ_pkcs7 1L, 2L, 840L, 113549L, 1L, 7L + +#define LN_pkcs7_data "pkcs7-data" +#define NID_pkcs7_data 21 +#define OBJ_pkcs7_data 1L, 2L, 840L, 113549L, 1L, 7L, 1L + +#define LN_pkcs7_signed "pkcs7-signedData" +#define NID_pkcs7_signed 22 +#define OBJ_pkcs7_signed 1L, 2L, 840L, 113549L, 1L, 7L, 2L + +#define LN_pkcs7_enveloped "pkcs7-envelopedData" +#define NID_pkcs7_enveloped 23 +#define OBJ_pkcs7_enveloped 1L, 2L, 840L, 113549L, 1L, 7L, 3L + +#define LN_pkcs7_signedAndEnveloped "pkcs7-signedAndEnvelopedData" +#define NID_pkcs7_signedAndEnveloped 24 +#define OBJ_pkcs7_signedAndEnveloped 1L, 2L, 840L, 113549L, 1L, 7L, 4L + +#define LN_pkcs7_digest "pkcs7-digestData" +#define NID_pkcs7_digest 25 +#define OBJ_pkcs7_digest 1L, 2L, 840L, 113549L, 1L, 7L, 5L + +#define LN_pkcs7_encrypted "pkcs7-encryptedData" +#define NID_pkcs7_encrypted 26 +#define OBJ_pkcs7_encrypted 1L, 2L, 840L, 113549L, 1L, 7L, 6L + +#define SN_pkcs3 "pkcs3" +#define NID_pkcs3 27 +#define OBJ_pkcs3 1L, 2L, 840L, 113549L, 1L, 3L + +#define LN_dhKeyAgreement "dhKeyAgreement" +#define NID_dhKeyAgreement 28 +#define OBJ_dhKeyAgreement 1L, 2L, 840L, 113549L, 1L, 3L, 1L + +#define SN_des_ecb "DES-ECB" +#define LN_des_ecb "des-ecb" +#define NID_des_ecb 29 +#define OBJ_des_ecb 1L, 3L, 14L, 3L, 2L, 6L + +#define SN_des_cfb64 "DES-CFB" +#define LN_des_cfb64 "des-cfb" +#define NID_des_cfb64 30 +#define OBJ_des_cfb64 1L, 3L, 14L, 3L, 2L, 9L + +#define SN_des_cbc "DES-CBC" +#define LN_des_cbc "des-cbc" +#define NID_des_cbc 31 +#define OBJ_des_cbc 1L, 3L, 14L, 3L, 2L, 7L + +#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 1L, 3L, 14L, 3L, 2L, 17L + +#define SN_des_ede3_ecb "DES-EDE3" +#define LN_des_ede3_ecb "des-ede3" +#define NID_des_ede3_ecb 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 1L, 2L, 840L, 113549L, 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 1L, 3L, 14L, 3L, 2L, 18L + +#define SN_shaWithRSAEncryption "RSA-SHA" +#define LN_shaWithRSAEncryption "shaWithRSAEncryption" +#define NID_shaWithRSAEncryption 42 +#define OBJ_shaWithRSAEncryption 1L, 3L, 14L, 3L, 2L, 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 1L, 2L, 840L, 113549L, 3L, 7L + +#define SN_des_ofb64 "DES-OFB" +#define LN_des_ofb64 "des-ofb" +#define NID_des_ofb64 45 +#define OBJ_des_ofb64 1L, 3L, 14L, 3L, 2L, 8L + +#define SN_idea_ofb64 "IDEA-OFB" +#define LN_idea_ofb64 "idea-ofb" +#define NID_idea_ofb64 46 + +#define SN_pkcs9 "pkcs9" +#define NID_pkcs9 47 +#define OBJ_pkcs9 1L, 2L, 840L, 113549L, 1L, 9L + +#define LN_pkcs9_emailAddress "emailAddress" +#define NID_pkcs9_emailAddress 48 +#define OBJ_pkcs9_emailAddress 1L, 2L, 840L, 113549L, 1L, 9L, 1L + +#define LN_pkcs9_unstructuredName "unstructuredName" +#define NID_pkcs9_unstructuredName 49 +#define OBJ_pkcs9_unstructuredName 1L, 2L, 840L, 113549L, 1L, 9L, 2L + +#define LN_pkcs9_contentType "contentType" +#define NID_pkcs9_contentType 50 +#define OBJ_pkcs9_contentType 1L, 2L, 840L, 113549L, 1L, 9L, 3L + +#define LN_pkcs9_messageDigest "messageDigest" +#define NID_pkcs9_messageDigest 51 +#define OBJ_pkcs9_messageDigest 1L, 2L, 840L, 113549L, 1L, 9L, 4L + +#define LN_pkcs9_signingTime "signingTime" +#define NID_pkcs9_signingTime 52 +#define OBJ_pkcs9_signingTime 1L, 2L, 840L, 113549L, 1L, 9L, 5L + +#define LN_pkcs9_countersignature "countersignature" +#define NID_pkcs9_countersignature 53 +#define OBJ_pkcs9_countersignature 1L, 2L, 840L, 113549L, 1L, 9L, 6L + +#define LN_pkcs9_challengePassword "challengePassword" +#define NID_pkcs9_challengePassword 54 +#define OBJ_pkcs9_challengePassword 1L, 2L, 840L, 113549L, 1L, 9L, 7L + +#define LN_pkcs9_unstructuredAddress "unstructuredAddress" +#define NID_pkcs9_unstructuredAddress 55 +#define OBJ_pkcs9_unstructuredAddress 1L, 2L, 840L, 113549L, 1L, 9L, 8L + +#define LN_pkcs9_extCertAttributes "extendedCertificateAttributes" +#define NID_pkcs9_extCertAttributes 56 +#define OBJ_pkcs9_extCertAttributes 1L, 2L, 840L, 113549L, 1L, 9L, 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 2L, 16L, 840L, 1L, 113730L, 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 2L, 16L, 840L, 1L, 113730L, 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 + +#define SN_sha1 "SHA1" +#define LN_sha1 "sha1" +#define NID_sha1 64 +#define OBJ_sha1 1L, 3L, 14L, 3L, 2L, 26L + +#define SN_sha1WithRSAEncryption "RSA-SHA1" +#define LN_sha1WithRSAEncryption "sha1WithRSAEncryption" +#define NID_sha1WithRSAEncryption 65 +#define OBJ_sha1WithRSAEncryption 1L, 2L, 840L, 113549L, 1L, 1L, 5L + +#define SN_dsaWithSHA "DSA-SHA" +#define LN_dsaWithSHA "dsaWithSHA" +#define NID_dsaWithSHA 66 +#define OBJ_dsaWithSHA 1L, 3L, 14L, 3L, 2L, 13L + +#define SN_dsa_2 "DSA-old" +#define LN_dsa_2 "dsaEncryption-old" +#define NID_dsa_2 67 +#define OBJ_dsa_2 1L, 3L, 14L, 3L, 2L, 12L + +#define SN_pbeWithSHA1AndRC2_CBC "PBE-SHA1-RC2-64" +#define LN_pbeWithSHA1AndRC2_CBC "pbeWithSHA1AndRC2-CBC" +#define NID_pbeWithSHA1AndRC2_CBC 68 +#define OBJ_pbeWithSHA1AndRC2_CBC 1L, 2L, 840L, 113549L, 1L, 5L, 11L + +#define LN_id_pbkdf2 "PBKDF2" +#define NID_id_pbkdf2 69 +#define OBJ_id_pbkdf2 1L, 2L, 840L, 113549L, 1L, 5L, 12L + +#define SN_dsaWithSHA1_2 "DSA-SHA1-old" +#define LN_dsaWithSHA1_2 "dsaWithSHA1-old" +#define NID_dsaWithSHA1_2 70 +#define OBJ_dsaWithSHA1_2 1L, 3L, 14L, 3L, 2L, 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 2L, 16L, 840L, 1L, 113730L, 1L, 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 2L, 16L, 840L, 1L, 113730L, 1L, 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 2L, 16L, 840L, 1L, 113730L, 1L, 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 2L, 16L, 840L, 1L, 113730L, 1L, 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 2L, 16L, 840L, 1L, 113730L, 1L, 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 2L, 16L, 840L, 1L, 113730L, 1L, 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 2L, 16L, 840L, 1L, 113730L, 1L, 12L + +#define SN_netscape_comment "nsComment" +#define LN_netscape_comment "Netscape Comment" +#define NID_netscape_comment 78 +#define OBJ_netscape_comment 2L, 16L, 840L, 1L, 113730L, 1L, 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 2L, 16L, 840L, 1L, 113730L, 2L, 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 2L, 5L, 29L, 14L + +#define SN_key_usage "keyUsage" +#define LN_key_usage "X509v3 Key Usage" +#define NID_key_usage 83 +#define OBJ_key_usage 2L, 5L, 29L, 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 2L, 5L, 29L, 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 2L, 5L, 29L, 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 2L, 5L, 29L, 18L + +#define SN_basic_constraints "basicConstraints" +#define LN_basic_constraints "X509v3 Basic Constraints" +#define NID_basic_constraints 87 +#define OBJ_basic_constraints 2L, 5L, 29L, 19L + +#define SN_crl_number "crlNumber" +#define LN_crl_number "X509v3 CRL Number" +#define NID_crl_number 88 +#define OBJ_crl_number 2L, 5L, 29L, 20L + +#define SN_certificate_policies "certificatePolicies" +#define LN_certificate_policies "X509v3 Certificate Policies" +#define NID_certificate_policies 89 +#define OBJ_certificate_policies 2L, 5L, 29L, 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 2L, 5L, 29L, 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 + +#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 "GN" +#define LN_givenName "givenName" +#define NID_givenName 99 +#define OBJ_givenName 2L, 5L, 4L, 42L + +#define SN_surname "SN" +#define LN_surname "surname" +#define NID_surname 100 +#define OBJ_surname 2L, 5L, 4L, 4L + +#define SN_initials "initials" +#define LN_initials "initials" +#define NID_initials 101 +#define OBJ_initials 2L, 5L, 4L, 43L + +#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 2L, 5L, 29L, 31L + +#define SN_md5WithRSA "RSA-NP-MD5" +#define LN_md5WithRSA "md5WithRSA" +#define NID_md5WithRSA 104 +#define OBJ_md5WithRSA 1L, 3L, 14L, 3L, 2L, 3L + +#define LN_serialNumber "serialNumber" +#define NID_serialNumber 105 +#define OBJ_serialNumber 2L, 5L, 4L, 5L + +#define SN_title "title" +#define LN_title "title" +#define NID_title 106 +#define OBJ_title 2L, 5L, 4L, 12L + +#define LN_description "description" +#define NID_description 107 +#define OBJ_description 2L, 5L, 4L, 13L + +#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 + +#define SN_dsaWithSHA1 "DSA-SHA1" +#define LN_dsaWithSHA1 "dsaWithSHA1" +#define NID_dsaWithSHA1 113 +#define OBJ_dsaWithSHA1 1L, 2L, 840L, 10040L, 4L, 3L + +#define SN_md5_sha1 "MD5-SHA1" +#define LN_md5_sha1 "md5-sha1" +#define NID_md5_sha1 114 + +#define SN_sha1WithRSA "RSA-SHA1-2" +#define LN_sha1WithRSA "sha1WithRSA" +#define NID_sha1WithRSA 115 +#define OBJ_sha1WithRSA 1L, 3L, 14L, 3L, 2L, 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 + +#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_rc5_cbc "RC5-CBC" +#define LN_rc5_cbc "rc5-cbc" +#define NID_rc5_cbc 120 +#define OBJ_rc5_cbc 1L, 2L, 840L, 113549L, 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_zlib_compression "ZLIB" +#define LN_zlib_compression "zlib compression" +#define NID_zlib_compression 125 +#define OBJ_zlib_compression 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 3L, 8L + +#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 2L, 5L, 29L, 37L + +#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 1L, 3L, 6L, 1L, 5L, 5L, 7L, 3L + +#define SN_server_auth "serverAuth" +#define LN_server_auth "TLS Web Server Authentication" +#define NID_server_auth 129 +#define OBJ_server_auth 1L, 3L, 6L, 1L, 5L, 5L, 7L, 3L, 1L + +#define SN_client_auth "clientAuth" +#define LN_client_auth "TLS Web Client Authentication" +#define NID_client_auth 130 +#define OBJ_client_auth 1L, 3L, 6L, 1L, 5L, 5L, 7L, 3L, 2L + +#define SN_code_sign "codeSigning" +#define LN_code_sign "Code Signing" +#define NID_code_sign 131 +#define OBJ_code_sign 1L, 3L, 6L, 1L, 5L, 5L, 7L, 3L, 3L + +#define SN_email_protect "emailProtection" +#define LN_email_protect "E-mail Protection" +#define NID_email_protect 132 +#define OBJ_email_protect 1L, 3L, 6L, 1L, 5L, 5L, 7L, 3L, 4L + +#define SN_time_stamp "timeStamping" +#define LN_time_stamp "Time Stamping" +#define NID_time_stamp 133 +#define OBJ_time_stamp 1L, 3L, 6L, 1L, 5L, 5L, 7L, 3L, 8L + +#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_ns_sgc "nsSGC" +#define LN_ns_sgc "Netscape Server Gated Crypto" +#define NID_ns_sgc 139 +#define OBJ_ns_sgc 2L, 16L, 840L, 1L, 113730L, 4L, 1L + +#define SN_delta_crl "deltaCRL" +#define LN_delta_crl "X509v3 Delta CRL Indicator" +#define NID_delta_crl 140 +#define OBJ_delta_crl 2L, 5L, 29L, 27L + +#define SN_crl_reason "CRLReason" +#define LN_crl_reason "X509v3 CRL Reason Code" +#define NID_crl_reason 141 +#define OBJ_crl_reason 2L, 5L, 29L, 21L + +#define SN_invalidity_date "invalidityDate" +#define LN_invalidity_date "Invalidity Date" +#define NID_invalidity_date 142 +#define OBJ_invalidity_date 2L, 5L, 29L, 24L + +#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_pbe_WithSHA1And128BitRC4 "PBE-SHA1-RC4-128" +#define LN_pbe_WithSHA1And128BitRC4 "pbeWithSHA1And128BitRC4" +#define NID_pbe_WithSHA1And128BitRC4 144 +#define OBJ_pbe_WithSHA1And128BitRC4 1L, 2L, 840L, 113549L, 1L, 12L, 1L, 1L + +#define SN_pbe_WithSHA1And40BitRC4 "PBE-SHA1-RC4-40" +#define LN_pbe_WithSHA1And40BitRC4 "pbeWithSHA1And40BitRC4" +#define NID_pbe_WithSHA1And40BitRC4 145 +#define OBJ_pbe_WithSHA1And40BitRC4 1L, 2L, 840L, 113549L, 1L, 12L, 1L, 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 \ + 1L, 2L, 840L, 113549L, 1L, 12L, 1L, 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 \ + 1L, 2L, 840L, 113549L, 1L, 12L, 1L, 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 1L, 2L, 840L, 113549L, 1L, 12L, 1L, 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 1L, 2L, 840L, 113549L, 1L, 12L, 1L, 6L + +#define LN_keyBag "keyBag" +#define NID_keyBag 150 +#define OBJ_keyBag 1L, 2L, 840L, 113549L, 1L, 12L, 10L, 1L, 1L + +#define LN_pkcs8ShroudedKeyBag "pkcs8ShroudedKeyBag" +#define NID_pkcs8ShroudedKeyBag 151 +#define OBJ_pkcs8ShroudedKeyBag 1L, 2L, 840L, 113549L, 1L, 12L, 10L, 1L, 2L + +#define LN_certBag "certBag" +#define NID_certBag 152 +#define OBJ_certBag 1L, 2L, 840L, 113549L, 1L, 12L, 10L, 1L, 3L + +#define LN_crlBag "crlBag" +#define NID_crlBag 153 +#define OBJ_crlBag 1L, 2L, 840L, 113549L, 1L, 12L, 10L, 1L, 4L + +#define LN_secretBag "secretBag" +#define NID_secretBag 154 +#define OBJ_secretBag 1L, 2L, 840L, 113549L, 1L, 12L, 10L, 1L, 5L + +#define LN_safeContentsBag "safeContentsBag" +#define NID_safeContentsBag 155 +#define OBJ_safeContentsBag 1L, 2L, 840L, 113549L, 1L, 12L, 10L, 1L, 6L + +#define LN_friendlyName "friendlyName" +#define NID_friendlyName 156 +#define OBJ_friendlyName 1L, 2L, 840L, 113549L, 1L, 9L, 20L + +#define LN_localKeyID "localKeyID" +#define NID_localKeyID 157 +#define OBJ_localKeyID 1L, 2L, 840L, 113549L, 1L, 9L, 21L + +#define LN_x509Certificate "x509Certificate" +#define NID_x509Certificate 158 +#define OBJ_x509Certificate 1L, 2L, 840L, 113549L, 1L, 9L, 22L, 1L + +#define LN_sdsiCertificate "sdsiCertificate" +#define NID_sdsiCertificate 159 +#define OBJ_sdsiCertificate 1L, 2L, 840L, 113549L, 1L, 9L, 22L, 2L + +#define LN_x509Crl "x509Crl" +#define NID_x509Crl 160 +#define OBJ_x509Crl 1L, 2L, 840L, 113549L, 1L, 9L, 23L, 1L + +#define LN_pbes2 "PBES2" +#define NID_pbes2 161 +#define OBJ_pbes2 1L, 2L, 840L, 113549L, 1L, 5L, 13L + +#define LN_pbmac1 "PBMAC1" +#define NID_pbmac1 162 +#define OBJ_pbmac1 1L, 2L, 840L, 113549L, 1L, 5L, 14L + +#define LN_hmacWithSHA1 "hmacWithSHA1" +#define NID_hmacWithSHA1 163 +#define OBJ_hmacWithSHA1 1L, 2L, 840L, 113549L, 2L, 7L + +#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 1L, 3L, 6L, 1L, 5L, 5L, 7L, 2L, 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 1L, 3L, 6L, 1L, 5L, 5L, 7L, 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 1L, 2L, 840L, 113549L, 1L, 9L, 15L + +#define SN_pbeWithMD2AndRC2_CBC "PBE-MD2-RC2-64" +#define LN_pbeWithMD2AndRC2_CBC "pbeWithMD2AndRC2-CBC" +#define NID_pbeWithMD2AndRC2_CBC 168 +#define OBJ_pbeWithMD2AndRC2_CBC 1L, 2L, 840L, 113549L, 1L, 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 1L, 2L, 840L, 113549L, 1L, 5L, 6L + +#define SN_pbeWithSHA1AndDES_CBC "PBE-SHA1-DES" +#define LN_pbeWithSHA1AndDES_CBC "pbeWithSHA1AndDES-CBC" +#define NID_pbeWithSHA1AndDES_CBC 170 +#define OBJ_pbeWithSHA1AndDES_CBC 1L, 2L, 840L, 113549L, 1L, 5L, 10L + +#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_ext_req "extReq" +#define LN_ext_req "Extension Request" +#define NID_ext_req 172 +#define OBJ_ext_req 1L, 2L, 840L, 113549L, 1L, 9L, 14L + +#define SN_name "name" +#define LN_name "name" +#define NID_name 173 +#define OBJ_name 2L, 5L, 4L, 41L + +#define SN_dnQualifier "dnQualifier" +#define LN_dnQualifier "dnQualifier" +#define NID_dnQualifier 174 +#define OBJ_dnQualifier 2L, 5L, 4L, 46L + +#define SN_id_pe "id-pe" +#define NID_id_pe 175 +#define OBJ_id_pe 1L, 3L, 6L, 1L, 5L, 5L, 7L, 1L + +#define SN_id_ad "id-ad" +#define NID_id_ad 176 +#define OBJ_id_ad 1L, 3L, 6L, 1L, 5L, 5L, 7L, 48L + +#define SN_info_access "authorityInfoAccess" +#define LN_info_access "Authority Information Access" +#define NID_info_access 177 +#define OBJ_info_access 1L, 3L, 6L, 1L, 5L, 5L, 7L, 1L, 1L + +#define SN_ad_OCSP "OCSP" +#define LN_ad_OCSP "OCSP" +#define NID_ad_OCSP 178 +#define OBJ_ad_OCSP 1L, 3L, 6L, 1L, 5L, 5L, 7L, 48L, 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 1L, 3L, 6L, 1L, 5L, 5L, 7L, 48L, 2L + +#define SN_OCSP_sign "OCSPSigning" +#define LN_OCSP_sign "OCSP Signing" +#define NID_OCSP_sign 180 +#define OBJ_OCSP_sign 1L, 3L, 6L, 1L, 5L, 5L, 7L, 3L, 9L + +#define SN_iso "ISO" +#define LN_iso "iso" +#define NID_iso 181 +#define OBJ_iso 1L + +#define SN_member_body "member-body" +#define LN_member_body "ISO Member Body" +#define NID_member_body 182 +#define OBJ_member_body 1L, 2L + +#define SN_ISO_US "ISO-US" +#define LN_ISO_US "ISO US Member Body" +#define NID_ISO_US 183 +#define OBJ_ISO_US 1L, 2L, 840L + +#define SN_X9_57 "X9-57" +#define LN_X9_57 "X9.57" +#define NID_X9_57 184 +#define OBJ_X9_57 1L, 2L, 840L, 10040L + +#define SN_X9cm "X9cm" +#define LN_X9cm "X9.57 CM ?" +#define NID_X9cm 185 +#define OBJ_X9cm 1L, 2L, 840L, 10040L, 4L + +#define SN_pkcs1 "pkcs1" +#define NID_pkcs1 186 +#define OBJ_pkcs1 1L, 2L, 840L, 113549L, 1L, 1L + +#define SN_pkcs5 "pkcs5" +#define NID_pkcs5 187 +#define OBJ_pkcs5 1L, 2L, 840L, 113549L, 1L, 5L + +#define SN_SMIME "SMIME" +#define LN_SMIME "S/MIME" +#define NID_SMIME 188 +#define OBJ_SMIME 1L, 2L, 840L, 113549L, 1L, 9L, 16L + +#define SN_id_smime_mod "id-smime-mod" +#define NID_id_smime_mod 189 +#define OBJ_id_smime_mod 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 0L + +#define SN_id_smime_ct "id-smime-ct" +#define NID_id_smime_ct 190 +#define OBJ_id_smime_ct 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 1L + +#define SN_id_smime_aa "id-smime-aa" +#define NID_id_smime_aa 191 +#define OBJ_id_smime_aa 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 2L + +#define SN_id_smime_alg "id-smime-alg" +#define NID_id_smime_alg 192 +#define OBJ_id_smime_alg 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 3L + +#define SN_id_smime_cd "id-smime-cd" +#define NID_id_smime_cd 193 +#define OBJ_id_smime_cd 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 4L + +#define SN_id_smime_spq "id-smime-spq" +#define NID_id_smime_spq 194 +#define OBJ_id_smime_spq 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 5L + +#define SN_id_smime_cti "id-smime-cti" +#define NID_id_smime_cti 195 +#define OBJ_id_smime_cti 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 6L + +#define SN_id_smime_mod_cms "id-smime-mod-cms" +#define NID_id_smime_mod_cms 196 +#define OBJ_id_smime_mod_cms 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 0L, 1L + +#define SN_id_smime_mod_ess "id-smime-mod-ess" +#define NID_id_smime_mod_ess 197 +#define OBJ_id_smime_mod_ess 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 0L, 2L + +#define SN_id_smime_mod_oid "id-smime-mod-oid" +#define NID_id_smime_mod_oid 198 +#define OBJ_id_smime_mod_oid 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 0L, 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 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 0L, 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 \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 0L, 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 \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 0L, 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 \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 0L, 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 \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 0L, 8L + +#define SN_id_smime_ct_receipt "id-smime-ct-receipt" +#define NID_id_smime_ct_receipt 204 +#define OBJ_id_smime_ct_receipt 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 1L, 1L + +#define SN_id_smime_ct_authData "id-smime-ct-authData" +#define NID_id_smime_ct_authData 205 +#define OBJ_id_smime_ct_authData 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 1L, 2L + +#define SN_id_smime_ct_publishCert "id-smime-ct-publishCert" +#define NID_id_smime_ct_publishCert 206 +#define OBJ_id_smime_ct_publishCert 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 1L, 3L + +#define SN_id_smime_ct_TSTInfo "id-smime-ct-TSTInfo" +#define NID_id_smime_ct_TSTInfo 207 +#define OBJ_id_smime_ct_TSTInfo 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 1L, 4L + +#define SN_id_smime_ct_TDTInfo "id-smime-ct-TDTInfo" +#define NID_id_smime_ct_TDTInfo 208 +#define OBJ_id_smime_ct_TDTInfo 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 1L, 5L + +#define SN_id_smime_ct_contentInfo "id-smime-ct-contentInfo" +#define NID_id_smime_ct_contentInfo 209 +#define OBJ_id_smime_ct_contentInfo 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 1L, 6L + +#define SN_id_smime_ct_DVCSRequestData "id-smime-ct-DVCSRequestData" +#define NID_id_smime_ct_DVCSRequestData 210 +#define OBJ_id_smime_ct_DVCSRequestData \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 1L, 7L + +#define SN_id_smime_ct_DVCSResponseData "id-smime-ct-DVCSResponseData" +#define NID_id_smime_ct_DVCSResponseData 211 +#define OBJ_id_smime_ct_DVCSResponseData \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 1L, 8L + +#define SN_id_smime_aa_receiptRequest "id-smime-aa-receiptRequest" +#define NID_id_smime_aa_receiptRequest 212 +#define OBJ_id_smime_aa_receiptRequest \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 2L, 1L + +#define SN_id_smime_aa_securityLabel "id-smime-aa-securityLabel" +#define NID_id_smime_aa_securityLabel 213 +#define OBJ_id_smime_aa_securityLabel 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 2L, 2L + +#define SN_id_smime_aa_mlExpandHistory "id-smime-aa-mlExpandHistory" +#define NID_id_smime_aa_mlExpandHistory 214 +#define OBJ_id_smime_aa_mlExpandHistory \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 2L, 3L + +#define SN_id_smime_aa_contentHint "id-smime-aa-contentHint" +#define NID_id_smime_aa_contentHint 215 +#define OBJ_id_smime_aa_contentHint 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 2L, 4L + +#define SN_id_smime_aa_msgSigDigest "id-smime-aa-msgSigDigest" +#define NID_id_smime_aa_msgSigDigest 216 +#define OBJ_id_smime_aa_msgSigDigest 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 2L, 5L + +#define SN_id_smime_aa_encapContentType "id-smime-aa-encapContentType" +#define NID_id_smime_aa_encapContentType 217 +#define OBJ_id_smime_aa_encapContentType \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 2L, 6L + +#define SN_id_smime_aa_contentIdentifier "id-smime-aa-contentIdentifier" +#define NID_id_smime_aa_contentIdentifier 218 +#define OBJ_id_smime_aa_contentIdentifier \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 2L, 7L + +#define SN_id_smime_aa_macValue "id-smime-aa-macValue" +#define NID_id_smime_aa_macValue 219 +#define OBJ_id_smime_aa_macValue 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 2L, 8L + +#define SN_id_smime_aa_equivalentLabels "id-smime-aa-equivalentLabels" +#define NID_id_smime_aa_equivalentLabels 220 +#define OBJ_id_smime_aa_equivalentLabels \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 2L, 9L + +#define SN_id_smime_aa_contentReference "id-smime-aa-contentReference" +#define NID_id_smime_aa_contentReference 221 +#define OBJ_id_smime_aa_contentReference \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 2L, 10L + +#define SN_id_smime_aa_encrypKeyPref "id-smime-aa-encrypKeyPref" +#define NID_id_smime_aa_encrypKeyPref 222 +#define OBJ_id_smime_aa_encrypKeyPref \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 2L, 11L + +#define SN_id_smime_aa_signingCertificate "id-smime-aa-signingCertificate" +#define NID_id_smime_aa_signingCertificate 223 +#define OBJ_id_smime_aa_signingCertificate \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 2L, 12L + +#define SN_id_smime_aa_smimeEncryptCerts "id-smime-aa-smimeEncryptCerts" +#define NID_id_smime_aa_smimeEncryptCerts 224 +#define OBJ_id_smime_aa_smimeEncryptCerts \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 2L, 13L + +#define SN_id_smime_aa_timeStampToken "id-smime-aa-timeStampToken" +#define NID_id_smime_aa_timeStampToken 225 +#define OBJ_id_smime_aa_timeStampToken \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 2L, 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 \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 2L, 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 \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 2L, 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 \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 2L, 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 \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 2L, 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 \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 2L, 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 \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 2L, 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 \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 2L, 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 \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 2L, 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 \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 2L, 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 \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 2L, 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 \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 2L, 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 \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 2L, 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 \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 2L, 27L + +#define SN_id_smime_aa_signatureType "id-smime-aa-signatureType" +#define NID_id_smime_aa_signatureType 239 +#define OBJ_id_smime_aa_signatureType \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 2L, 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 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 2L, 29L + +#define SN_id_smime_alg_ESDHwith3DES "id-smime-alg-ESDHwith3DES" +#define NID_id_smime_alg_ESDHwith3DES 241 +#define OBJ_id_smime_alg_ESDHwith3DES 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 3L, 1L + +#define SN_id_smime_alg_ESDHwithRC2 "id-smime-alg-ESDHwithRC2" +#define NID_id_smime_alg_ESDHwithRC2 242 +#define OBJ_id_smime_alg_ESDHwithRC2 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 3L, 2L + +#define SN_id_smime_alg_3DESwrap "id-smime-alg-3DESwrap" +#define NID_id_smime_alg_3DESwrap 243 +#define OBJ_id_smime_alg_3DESwrap 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 3L, 3L + +#define SN_id_smime_alg_RC2wrap "id-smime-alg-RC2wrap" +#define NID_id_smime_alg_RC2wrap 244 +#define OBJ_id_smime_alg_RC2wrap 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 3L, 4L + +#define SN_id_smime_alg_ESDH "id-smime-alg-ESDH" +#define NID_id_smime_alg_ESDH 245 +#define OBJ_id_smime_alg_ESDH 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 3L, 5L + +#define SN_id_smime_alg_CMS3DESwrap "id-smime-alg-CMS3DESwrap" +#define NID_id_smime_alg_CMS3DESwrap 246 +#define OBJ_id_smime_alg_CMS3DESwrap 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 3L, 6L + +#define SN_id_smime_alg_CMSRC2wrap "id-smime-alg-CMSRC2wrap" +#define NID_id_smime_alg_CMSRC2wrap 247 +#define OBJ_id_smime_alg_CMSRC2wrap 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 3L, 7L + +#define SN_id_smime_cd_ldap "id-smime-cd-ldap" +#define NID_id_smime_cd_ldap 248 +#define OBJ_id_smime_cd_ldap 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 4L, 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 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 5L, 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 \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 5L, 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 \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 6L, 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 \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 6L, 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 \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 6L, 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 \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 6L, 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 \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 6L, 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 \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 6L, 6L + +#define SN_md4 "MD4" +#define LN_md4 "md4" +#define NID_md4 257 +#define OBJ_md4 1L, 2L, 840L, 113549L, 2L, 4L + +#define SN_id_pkix_mod "id-pkix-mod" +#define NID_id_pkix_mod 258 +#define OBJ_id_pkix_mod 1L, 3L, 6L, 1L, 5L, 5L, 7L, 0L + +#define SN_id_qt "id-qt" +#define NID_id_qt 259 +#define OBJ_id_qt 1L, 3L, 6L, 1L, 5L, 5L, 7L, 2L + +#define SN_id_it "id-it" +#define NID_id_it 260 +#define OBJ_id_it 1L, 3L, 6L, 1L, 5L, 5L, 7L, 4L + +#define SN_id_pkip "id-pkip" +#define NID_id_pkip 261 +#define OBJ_id_pkip 1L, 3L, 6L, 1L, 5L, 5L, 7L, 5L + +#define SN_id_alg "id-alg" +#define NID_id_alg 262 +#define OBJ_id_alg 1L, 3L, 6L, 1L, 5L, 5L, 7L, 6L + +#define SN_id_cmc "id-cmc" +#define NID_id_cmc 263 +#define OBJ_id_cmc 1L, 3L, 6L, 1L, 5L, 5L, 7L, 7L + +#define SN_id_on "id-on" +#define NID_id_on 264 +#define OBJ_id_on 1L, 3L, 6L, 1L, 5L, 5L, 7L, 8L + +#define SN_id_pda "id-pda" +#define NID_id_pda 265 +#define OBJ_id_pda 1L, 3L, 6L, 1L, 5L, 5L, 7L, 9L + +#define SN_id_aca "id-aca" +#define NID_id_aca 266 +#define OBJ_id_aca 1L, 3L, 6L, 1L, 5L, 5L, 7L, 10L + +#define SN_id_qcs "id-qcs" +#define NID_id_qcs 267 +#define OBJ_id_qcs 1L, 3L, 6L, 1L, 5L, 5L, 7L, 11L + +#define SN_id_cct "id-cct" +#define NID_id_cct 268 +#define OBJ_id_cct 1L, 3L, 6L, 1L, 5L, 5L, 7L, 12L + +#define SN_id_pkix1_explicit_88 "id-pkix1-explicit-88" +#define NID_id_pkix1_explicit_88 269 +#define OBJ_id_pkix1_explicit_88 1L, 3L, 6L, 1L, 5L, 5L, 7L, 0L, 1L + +#define SN_id_pkix1_implicit_88 "id-pkix1-implicit-88" +#define NID_id_pkix1_implicit_88 270 +#define OBJ_id_pkix1_implicit_88 1L, 3L, 6L, 1L, 5L, 5L, 7L, 0L, 2L + +#define SN_id_pkix1_explicit_93 "id-pkix1-explicit-93" +#define NID_id_pkix1_explicit_93 271 +#define OBJ_id_pkix1_explicit_93 1L, 3L, 6L, 1L, 5L, 5L, 7L, 0L, 3L + +#define SN_id_pkix1_implicit_93 "id-pkix1-implicit-93" +#define NID_id_pkix1_implicit_93 272 +#define OBJ_id_pkix1_implicit_93 1L, 3L, 6L, 1L, 5L, 5L, 7L, 0L, 4L + +#define SN_id_mod_crmf "id-mod-crmf" +#define NID_id_mod_crmf 273 +#define OBJ_id_mod_crmf 1L, 3L, 6L, 1L, 5L, 5L, 7L, 0L, 5L + +#define SN_id_mod_cmc "id-mod-cmc" +#define NID_id_mod_cmc 274 +#define OBJ_id_mod_cmc 1L, 3L, 6L, 1L, 5L, 5L, 7L, 0L, 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 1L, 3L, 6L, 1L, 5L, 5L, 7L, 0L, 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 1L, 3L, 6L, 1L, 5L, 5L, 7L, 0L, 8L + +#define SN_id_mod_cmp "id-mod-cmp" +#define NID_id_mod_cmp 277 +#define OBJ_id_mod_cmp 1L, 3L, 6L, 1L, 5L, 5L, 7L, 0L, 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 1L, 3L, 6L, 1L, 5L, 5L, 7L, 0L, 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 1L, 3L, 6L, 1L, 5L, 5L, 7L, 0L, 11L + +#define SN_id_mod_attribute_cert "id-mod-attribute-cert" +#define NID_id_mod_attribute_cert 280 +#define OBJ_id_mod_attribute_cert 1L, 3L, 6L, 1L, 5L, 5L, 7L, 0L, 12L + +#define SN_id_mod_timestamp_protocol "id-mod-timestamp-protocol" +#define NID_id_mod_timestamp_protocol 281 +#define OBJ_id_mod_timestamp_protocol 1L, 3L, 6L, 1L, 5L, 5L, 7L, 0L, 13L + +#define SN_id_mod_ocsp "id-mod-ocsp" +#define NID_id_mod_ocsp 282 +#define OBJ_id_mod_ocsp 1L, 3L, 6L, 1L, 5L, 5L, 7L, 0L, 14L + +#define SN_id_mod_dvcs "id-mod-dvcs" +#define NID_id_mod_dvcs 283 +#define OBJ_id_mod_dvcs 1L, 3L, 6L, 1L, 5L, 5L, 7L, 0L, 15L + +#define SN_id_mod_cmp2000 "id-mod-cmp2000" +#define NID_id_mod_cmp2000 284 +#define OBJ_id_mod_cmp2000 1L, 3L, 6L, 1L, 5L, 5L, 7L, 0L, 16L + +#define SN_biometricInfo "biometricInfo" +#define LN_biometricInfo "Biometric Info" +#define NID_biometricInfo 285 +#define OBJ_biometricInfo 1L, 3L, 6L, 1L, 5L, 5L, 7L, 1L, 2L + +#define SN_qcStatements "qcStatements" +#define NID_qcStatements 286 +#define OBJ_qcStatements 1L, 3L, 6L, 1L, 5L, 5L, 7L, 1L, 3L + +#define SN_ac_auditEntity "ac-auditEntity" +#define NID_ac_auditEntity 287 +#define OBJ_ac_auditEntity 1L, 3L, 6L, 1L, 5L, 5L, 7L, 1L, 4L + +#define SN_ac_targeting "ac-targeting" +#define NID_ac_targeting 288 +#define OBJ_ac_targeting 1L, 3L, 6L, 1L, 5L, 5L, 7L, 1L, 5L + +#define SN_aaControls "aaControls" +#define NID_aaControls 289 +#define OBJ_aaControls 1L, 3L, 6L, 1L, 5L, 5L, 7L, 1L, 6L + +#define SN_sbgp_ipAddrBlock "sbgp-ipAddrBlock" +#define NID_sbgp_ipAddrBlock 290 +#define OBJ_sbgp_ipAddrBlock 1L, 3L, 6L, 1L, 5L, 5L, 7L, 1L, 7L + +#define SN_sbgp_autonomousSysNum "sbgp-autonomousSysNum" +#define NID_sbgp_autonomousSysNum 291 +#define OBJ_sbgp_autonomousSysNum 1L, 3L, 6L, 1L, 5L, 5L, 7L, 1L, 8L + +#define SN_sbgp_routerIdentifier "sbgp-routerIdentifier" +#define NID_sbgp_routerIdentifier 292 +#define OBJ_sbgp_routerIdentifier 1L, 3L, 6L, 1L, 5L, 5L, 7L, 1L, 9L + +#define SN_textNotice "textNotice" +#define NID_textNotice 293 +#define OBJ_textNotice 1L, 3L, 6L, 1L, 5L, 5L, 7L, 2L, 3L + +#define SN_ipsecEndSystem "ipsecEndSystem" +#define LN_ipsecEndSystem "IPSec End System" +#define NID_ipsecEndSystem 294 +#define OBJ_ipsecEndSystem 1L, 3L, 6L, 1L, 5L, 5L, 7L, 3L, 5L + +#define SN_ipsecTunnel "ipsecTunnel" +#define LN_ipsecTunnel "IPSec Tunnel" +#define NID_ipsecTunnel 295 +#define OBJ_ipsecTunnel 1L, 3L, 6L, 1L, 5L, 5L, 7L, 3L, 6L + +#define SN_ipsecUser "ipsecUser" +#define LN_ipsecUser "IPSec User" +#define NID_ipsecUser 296 +#define OBJ_ipsecUser 1L, 3L, 6L, 1L, 5L, 5L, 7L, 3L, 7L + +#define SN_dvcs "DVCS" +#define LN_dvcs "dvcs" +#define NID_dvcs 297 +#define OBJ_dvcs 1L, 3L, 6L, 1L, 5L, 5L, 7L, 3L, 10L + +#define SN_id_it_caProtEncCert "id-it-caProtEncCert" +#define NID_id_it_caProtEncCert 298 +#define OBJ_id_it_caProtEncCert 1L, 3L, 6L, 1L, 5L, 5L, 7L, 4L, 1L + +#define SN_id_it_signKeyPairTypes "id-it-signKeyPairTypes" +#define NID_id_it_signKeyPairTypes 299 +#define OBJ_id_it_signKeyPairTypes 1L, 3L, 6L, 1L, 5L, 5L, 7L, 4L, 2L + +#define SN_id_it_encKeyPairTypes "id-it-encKeyPairTypes" +#define NID_id_it_encKeyPairTypes 300 +#define OBJ_id_it_encKeyPairTypes 1L, 3L, 6L, 1L, 5L, 5L, 7L, 4L, 3L + +#define SN_id_it_preferredSymmAlg "id-it-preferredSymmAlg" +#define NID_id_it_preferredSymmAlg 301 +#define OBJ_id_it_preferredSymmAlg 1L, 3L, 6L, 1L, 5L, 5L, 7L, 4L, 4L + +#define SN_id_it_caKeyUpdateInfo "id-it-caKeyUpdateInfo" +#define NID_id_it_caKeyUpdateInfo 302 +#define OBJ_id_it_caKeyUpdateInfo 1L, 3L, 6L, 1L, 5L, 5L, 7L, 4L, 5L + +#define SN_id_it_currentCRL "id-it-currentCRL" +#define NID_id_it_currentCRL 303 +#define OBJ_id_it_currentCRL 1L, 3L, 6L, 1L, 5L, 5L, 7L, 4L, 6L + +#define SN_id_it_unsupportedOIDs "id-it-unsupportedOIDs" +#define NID_id_it_unsupportedOIDs 304 +#define OBJ_id_it_unsupportedOIDs 1L, 3L, 6L, 1L, 5L, 5L, 7L, 4L, 7L + +#define SN_id_it_subscriptionRequest "id-it-subscriptionRequest" +#define NID_id_it_subscriptionRequest 305 +#define OBJ_id_it_subscriptionRequest 1L, 3L, 6L, 1L, 5L, 5L, 7L, 4L, 8L + +#define SN_id_it_subscriptionResponse "id-it-subscriptionResponse" +#define NID_id_it_subscriptionResponse 306 +#define OBJ_id_it_subscriptionResponse 1L, 3L, 6L, 1L, 5L, 5L, 7L, 4L, 9L + +#define SN_id_it_keyPairParamReq "id-it-keyPairParamReq" +#define NID_id_it_keyPairParamReq 307 +#define OBJ_id_it_keyPairParamReq 1L, 3L, 6L, 1L, 5L, 5L, 7L, 4L, 10L + +#define SN_id_it_keyPairParamRep "id-it-keyPairParamRep" +#define NID_id_it_keyPairParamRep 308 +#define OBJ_id_it_keyPairParamRep 1L, 3L, 6L, 1L, 5L, 5L, 7L, 4L, 11L + +#define SN_id_it_revPassphrase "id-it-revPassphrase" +#define NID_id_it_revPassphrase 309 +#define OBJ_id_it_revPassphrase 1L, 3L, 6L, 1L, 5L, 5L, 7L, 4L, 12L + +#define SN_id_it_implicitConfirm "id-it-implicitConfirm" +#define NID_id_it_implicitConfirm 310 +#define OBJ_id_it_implicitConfirm 1L, 3L, 6L, 1L, 5L, 5L, 7L, 4L, 13L + +#define SN_id_it_confirmWaitTime "id-it-confirmWaitTime" +#define NID_id_it_confirmWaitTime 311 +#define OBJ_id_it_confirmWaitTime 1L, 3L, 6L, 1L, 5L, 5L, 7L, 4L, 14L + +#define SN_id_it_origPKIMessage "id-it-origPKIMessage" +#define NID_id_it_origPKIMessage 312 +#define OBJ_id_it_origPKIMessage 1L, 3L, 6L, 1L, 5L, 5L, 7L, 4L, 15L + +#define SN_id_regCtrl "id-regCtrl" +#define NID_id_regCtrl 313 +#define OBJ_id_regCtrl 1L, 3L, 6L, 1L, 5L, 5L, 7L, 5L, 1L + +#define SN_id_regInfo "id-regInfo" +#define NID_id_regInfo 314 +#define OBJ_id_regInfo 1L, 3L, 6L, 1L, 5L, 5L, 7L, 5L, 2L + +#define SN_id_regCtrl_regToken "id-regCtrl-regToken" +#define NID_id_regCtrl_regToken 315 +#define OBJ_id_regCtrl_regToken 1L, 3L, 6L, 1L, 5L, 5L, 7L, 5L, 1L, 1L + +#define SN_id_regCtrl_authenticator "id-regCtrl-authenticator" +#define NID_id_regCtrl_authenticator 316 +#define OBJ_id_regCtrl_authenticator 1L, 3L, 6L, 1L, 5L, 5L, 7L, 5L, 1L, 2L + +#define SN_id_regCtrl_pkiPublicationInfo "id-regCtrl-pkiPublicationInfo" +#define NID_id_regCtrl_pkiPublicationInfo 317 +#define OBJ_id_regCtrl_pkiPublicationInfo 1L, 3L, 6L, 1L, 5L, 5L, 7L, 5L, 1L, 3L + +#define SN_id_regCtrl_pkiArchiveOptions "id-regCtrl-pkiArchiveOptions" +#define NID_id_regCtrl_pkiArchiveOptions 318 +#define OBJ_id_regCtrl_pkiArchiveOptions 1L, 3L, 6L, 1L, 5L, 5L, 7L, 5L, 1L, 4L + +#define SN_id_regCtrl_oldCertID "id-regCtrl-oldCertID" +#define NID_id_regCtrl_oldCertID 319 +#define OBJ_id_regCtrl_oldCertID 1L, 3L, 6L, 1L, 5L, 5L, 7L, 5L, 1L, 5L + +#define SN_id_regCtrl_protocolEncrKey "id-regCtrl-protocolEncrKey" +#define NID_id_regCtrl_protocolEncrKey 320 +#define OBJ_id_regCtrl_protocolEncrKey 1L, 3L, 6L, 1L, 5L, 5L, 7L, 5L, 1L, 6L + +#define SN_id_regInfo_utf8Pairs "id-regInfo-utf8Pairs" +#define NID_id_regInfo_utf8Pairs 321 +#define OBJ_id_regInfo_utf8Pairs 1L, 3L, 6L, 1L, 5L, 5L, 7L, 5L, 2L, 1L + +#define SN_id_regInfo_certReq "id-regInfo-certReq" +#define NID_id_regInfo_certReq 322 +#define OBJ_id_regInfo_certReq 1L, 3L, 6L, 1L, 5L, 5L, 7L, 5L, 2L, 2L + +#define SN_id_alg_des40 "id-alg-des40" +#define NID_id_alg_des40 323 +#define OBJ_id_alg_des40 1L, 3L, 6L, 1L, 5L, 5L, 7L, 6L, 1L + +#define SN_id_alg_noSignature "id-alg-noSignature" +#define NID_id_alg_noSignature 324 +#define OBJ_id_alg_noSignature 1L, 3L, 6L, 1L, 5L, 5L, 7L, 6L, 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 1L, 3L, 6L, 1L, 5L, 5L, 7L, 6L, 3L + +#define SN_id_alg_dh_pop "id-alg-dh-pop" +#define NID_id_alg_dh_pop 326 +#define OBJ_id_alg_dh_pop 1L, 3L, 6L, 1L, 5L, 5L, 7L, 6L, 4L + +#define SN_id_cmc_statusInfo "id-cmc-statusInfo" +#define NID_id_cmc_statusInfo 327 +#define OBJ_id_cmc_statusInfo 1L, 3L, 6L, 1L, 5L, 5L, 7L, 7L, 1L + +#define SN_id_cmc_identification "id-cmc-identification" +#define NID_id_cmc_identification 328 +#define OBJ_id_cmc_identification 1L, 3L, 6L, 1L, 5L, 5L, 7L, 7L, 2L + +#define SN_id_cmc_identityProof "id-cmc-identityProof" +#define NID_id_cmc_identityProof 329 +#define OBJ_id_cmc_identityProof 1L, 3L, 6L, 1L, 5L, 5L, 7L, 7L, 3L + +#define SN_id_cmc_dataReturn "id-cmc-dataReturn" +#define NID_id_cmc_dataReturn 330 +#define OBJ_id_cmc_dataReturn 1L, 3L, 6L, 1L, 5L, 5L, 7L, 7L, 4L + +#define SN_id_cmc_transactionId "id-cmc-transactionId" +#define NID_id_cmc_transactionId 331 +#define OBJ_id_cmc_transactionId 1L, 3L, 6L, 1L, 5L, 5L, 7L, 7L, 5L + +#define SN_id_cmc_senderNonce "id-cmc-senderNonce" +#define NID_id_cmc_senderNonce 332 +#define OBJ_id_cmc_senderNonce 1L, 3L, 6L, 1L, 5L, 5L, 7L, 7L, 6L + +#define SN_id_cmc_recipientNonce "id-cmc-recipientNonce" +#define NID_id_cmc_recipientNonce 333 +#define OBJ_id_cmc_recipientNonce 1L, 3L, 6L, 1L, 5L, 5L, 7L, 7L, 7L + +#define SN_id_cmc_addExtensions "id-cmc-addExtensions" +#define NID_id_cmc_addExtensions 334 +#define OBJ_id_cmc_addExtensions 1L, 3L, 6L, 1L, 5L, 5L, 7L, 7L, 8L + +#define SN_id_cmc_encryptedPOP "id-cmc-encryptedPOP" +#define NID_id_cmc_encryptedPOP 335 +#define OBJ_id_cmc_encryptedPOP 1L, 3L, 6L, 1L, 5L, 5L, 7L, 7L, 9L + +#define SN_id_cmc_decryptedPOP "id-cmc-decryptedPOP" +#define NID_id_cmc_decryptedPOP 336 +#define OBJ_id_cmc_decryptedPOP 1L, 3L, 6L, 1L, 5L, 5L, 7L, 7L, 10L + +#define SN_id_cmc_lraPOPWitness "id-cmc-lraPOPWitness" +#define NID_id_cmc_lraPOPWitness 337 +#define OBJ_id_cmc_lraPOPWitness 1L, 3L, 6L, 1L, 5L, 5L, 7L, 7L, 11L + +#define SN_id_cmc_getCert "id-cmc-getCert" +#define NID_id_cmc_getCert 338 +#define OBJ_id_cmc_getCert 1L, 3L, 6L, 1L, 5L, 5L, 7L, 7L, 15L + +#define SN_id_cmc_getCRL "id-cmc-getCRL" +#define NID_id_cmc_getCRL 339 +#define OBJ_id_cmc_getCRL 1L, 3L, 6L, 1L, 5L, 5L, 7L, 7L, 16L + +#define SN_id_cmc_revokeRequest "id-cmc-revokeRequest" +#define NID_id_cmc_revokeRequest 340 +#define OBJ_id_cmc_revokeRequest 1L, 3L, 6L, 1L, 5L, 5L, 7L, 7L, 17L + +#define SN_id_cmc_regInfo "id-cmc-regInfo" +#define NID_id_cmc_regInfo 341 +#define OBJ_id_cmc_regInfo 1L, 3L, 6L, 1L, 5L, 5L, 7L, 7L, 18L + +#define SN_id_cmc_responseInfo "id-cmc-responseInfo" +#define NID_id_cmc_responseInfo 342 +#define OBJ_id_cmc_responseInfo 1L, 3L, 6L, 1L, 5L, 5L, 7L, 7L, 19L + +#define SN_id_cmc_queryPending "id-cmc-queryPending" +#define NID_id_cmc_queryPending 343 +#define OBJ_id_cmc_queryPending 1L, 3L, 6L, 1L, 5L, 5L, 7L, 7L, 21L + +#define SN_id_cmc_popLinkRandom "id-cmc-popLinkRandom" +#define NID_id_cmc_popLinkRandom 344 +#define OBJ_id_cmc_popLinkRandom 1L, 3L, 6L, 1L, 5L, 5L, 7L, 7L, 22L + +#define SN_id_cmc_popLinkWitness "id-cmc-popLinkWitness" +#define NID_id_cmc_popLinkWitness 345 +#define OBJ_id_cmc_popLinkWitness 1L, 3L, 6L, 1L, 5L, 5L, 7L, 7L, 23L + +#define SN_id_cmc_confirmCertAcceptance "id-cmc-confirmCertAcceptance" +#define NID_id_cmc_confirmCertAcceptance 346 +#define OBJ_id_cmc_confirmCertAcceptance 1L, 3L, 6L, 1L, 5L, 5L, 7L, 7L, 24L + +#define SN_id_on_personalData "id-on-personalData" +#define NID_id_on_personalData 347 +#define OBJ_id_on_personalData 1L, 3L, 6L, 1L, 5L, 5L, 7L, 8L, 1L + +#define SN_id_pda_dateOfBirth "id-pda-dateOfBirth" +#define NID_id_pda_dateOfBirth 348 +#define OBJ_id_pda_dateOfBirth 1L, 3L, 6L, 1L, 5L, 5L, 7L, 9L, 1L + +#define SN_id_pda_placeOfBirth "id-pda-placeOfBirth" +#define NID_id_pda_placeOfBirth 349 +#define OBJ_id_pda_placeOfBirth 1L, 3L, 6L, 1L, 5L, 5L, 7L, 9L, 2L + +#define SN_id_pda_gender "id-pda-gender" +#define NID_id_pda_gender 351 +#define OBJ_id_pda_gender 1L, 3L, 6L, 1L, 5L, 5L, 7L, 9L, 3L + +#define SN_id_pda_countryOfCitizenship "id-pda-countryOfCitizenship" +#define NID_id_pda_countryOfCitizenship 352 +#define OBJ_id_pda_countryOfCitizenship 1L, 3L, 6L, 1L, 5L, 5L, 7L, 9L, 4L + +#define SN_id_pda_countryOfResidence "id-pda-countryOfResidence" +#define NID_id_pda_countryOfResidence 353 +#define OBJ_id_pda_countryOfResidence 1L, 3L, 6L, 1L, 5L, 5L, 7L, 9L, 5L + +#define SN_id_aca_authenticationInfo "id-aca-authenticationInfo" +#define NID_id_aca_authenticationInfo 354 +#define OBJ_id_aca_authenticationInfo 1L, 3L, 6L, 1L, 5L, 5L, 7L, 10L, 1L + +#define SN_id_aca_accessIdentity "id-aca-accessIdentity" +#define NID_id_aca_accessIdentity 355 +#define OBJ_id_aca_accessIdentity 1L, 3L, 6L, 1L, 5L, 5L, 7L, 10L, 2L + +#define SN_id_aca_chargingIdentity "id-aca-chargingIdentity" +#define NID_id_aca_chargingIdentity 356 +#define OBJ_id_aca_chargingIdentity 1L, 3L, 6L, 1L, 5L, 5L, 7L, 10L, 3L + +#define SN_id_aca_group "id-aca-group" +#define NID_id_aca_group 357 +#define OBJ_id_aca_group 1L, 3L, 6L, 1L, 5L, 5L, 7L, 10L, 4L + +#define SN_id_aca_role "id-aca-role" +#define NID_id_aca_role 358 +#define OBJ_id_aca_role 1L, 3L, 6L, 1L, 5L, 5L, 7L, 10L, 5L + +#define SN_id_qcs_pkixQCSyntax_v1 "id-qcs-pkixQCSyntax-v1" +#define NID_id_qcs_pkixQCSyntax_v1 359 +#define OBJ_id_qcs_pkixQCSyntax_v1 1L, 3L, 6L, 1L, 5L, 5L, 7L, 11L, 1L + +#define SN_id_cct_crs "id-cct-crs" +#define NID_id_cct_crs 360 +#define OBJ_id_cct_crs 1L, 3L, 6L, 1L, 5L, 5L, 7L, 12L, 1L + +#define SN_id_cct_PKIData "id-cct-PKIData" +#define NID_id_cct_PKIData 361 +#define OBJ_id_cct_PKIData 1L, 3L, 6L, 1L, 5L, 5L, 7L, 12L, 2L + +#define SN_id_cct_PKIResponse "id-cct-PKIResponse" +#define NID_id_cct_PKIResponse 362 +#define OBJ_id_cct_PKIResponse 1L, 3L, 6L, 1L, 5L, 5L, 7L, 12L, 3L + +#define SN_ad_timeStamping "ad_timestamping" +#define LN_ad_timeStamping "AD Time Stamping" +#define NID_ad_timeStamping 363 +#define OBJ_ad_timeStamping 1L, 3L, 6L, 1L, 5L, 5L, 7L, 48L, 3L + +#define SN_ad_dvcs "AD_DVCS" +#define LN_ad_dvcs "ad dvcs" +#define NID_ad_dvcs 364 +#define OBJ_ad_dvcs 1L, 3L, 6L, 1L, 5L, 5L, 7L, 48L, 4L + +#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 1L, 3L, 6L, 1L, 5L, 5L, 7L, 48L, 1L, 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 1L, 3L, 6L, 1L, 5L, 5L, 7L, 48L, 1L, 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 1L, 3L, 6L, 1L, 5L, 5L, 7L, 48L, 1L, 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 \ + 1L, 3L, 6L, 1L, 5L, 5L, 7L, 48L, 1L, 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 1L, 3L, 6L, 1L, 5L, 5L, 7L, 48L, 1L, 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 1L, 3L, 6L, 1L, 5L, 5L, 7L, 48L, 1L, 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 1L, 3L, 6L, 1L, 5L, 5L, 7L, 48L, 1L, 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 1L, 3L, 6L, 1L, 5L, 5L, 7L, 48L, 1L, 8L + +#define SN_id_pkix_OCSP_valid "valid" +#define NID_id_pkix_OCSP_valid 373 +#define OBJ_id_pkix_OCSP_valid 1L, 3L, 6L, 1L, 5L, 5L, 7L, 48L, 1L, 9L + +#define SN_id_pkix_OCSP_path "path" +#define NID_id_pkix_OCSP_path 374 +#define OBJ_id_pkix_OCSP_path 1L, 3L, 6L, 1L, 5L, 5L, 7L, 48L, 1L, 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 1L, 3L, 6L, 1L, 5L, 5L, 7L, 48L, 1L, 11L + +#define SN_algorithm "algorithm" +#define LN_algorithm "algorithm" +#define NID_algorithm 376 +#define OBJ_algorithm 1L, 3L, 14L, 3L, 2L + +#define SN_rsaSignature "rsaSignature" +#define NID_rsaSignature 377 +#define OBJ_rsaSignature 1L, 3L, 14L, 3L, 2L, 11L + +#define SN_X500algorithms "X500algorithms" +#define LN_X500algorithms "directory services - algorithms" +#define NID_X500algorithms 378 +#define OBJ_X500algorithms 2L, 5L, 8L + +#define SN_org "ORG" +#define LN_org "org" +#define NID_org 379 +#define OBJ_org 1L, 3L + +#define SN_dod "DOD" +#define LN_dod "dod" +#define NID_dod 380 +#define OBJ_dod 1L, 3L, 6L + +#define SN_iana "IANA" +#define LN_iana "iana" +#define NID_iana 381 +#define OBJ_iana 1L, 3L, 6L, 1L + +#define SN_Directory "directory" +#define LN_Directory "Directory" +#define NID_Directory 382 +#define OBJ_Directory 1L, 3L, 6L, 1L, 1L + +#define SN_Management "mgmt" +#define LN_Management "Management" +#define NID_Management 383 +#define OBJ_Management 1L, 3L, 6L, 1L, 2L + +#define SN_Experimental "experimental" +#define LN_Experimental "Experimental" +#define NID_Experimental 384 +#define OBJ_Experimental 1L, 3L, 6L, 1L, 3L + +#define SN_Private "private" +#define LN_Private "Private" +#define NID_Private 385 +#define OBJ_Private 1L, 3L, 6L, 1L, 4L + +#define SN_Security "security" +#define LN_Security "Security" +#define NID_Security 386 +#define OBJ_Security 1L, 3L, 6L, 1L, 5L + +#define SN_SNMPv2 "snmpv2" +#define LN_SNMPv2 "SNMPv2" +#define NID_SNMPv2 387 +#define OBJ_SNMPv2 1L, 3L, 6L, 1L, 6L + +#define LN_Mail "Mail" +#define NID_Mail 388 +#define OBJ_Mail 1L, 3L, 6L, 1L, 7L + +#define SN_Enterprises "enterprises" +#define LN_Enterprises "Enterprises" +#define NID_Enterprises 389 +#define OBJ_Enterprises 1L, 3L, 6L, 1L, 4L, 1L + +#define SN_dcObject "dcobject" +#define LN_dcObject "dcObject" +#define NID_dcObject 390 +#define OBJ_dcObject 1L, 3L, 6L, 1L, 4L, 1L, 1466L, 344L + +#define SN_domainComponent "DC" +#define LN_domainComponent "domainComponent" +#define NID_domainComponent 391 +#define OBJ_domainComponent 0L, 9L, 2342L, 19200300L, 100L, 1L, 25L + +#define SN_Domain "domain" +#define LN_Domain "Domain" +#define NID_Domain 392 +#define OBJ_Domain 0L, 9L, 2342L, 19200300L, 100L, 4L, 13L + +#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 2L, 5L, 1L, 5L + +#define SN_clearance "clearance" +#define NID_clearance 395 +#define OBJ_clearance 2L, 5L, 1L, 5L, 55L + +#define SN_md4WithRSAEncryption "RSA-MD4" +#define LN_md4WithRSAEncryption "md4WithRSAEncryption" +#define NID_md4WithRSAEncryption 396 +#define OBJ_md4WithRSAEncryption 1L, 2L, 840L, 113549L, 1L, 1L, 3L + +#define SN_ac_proxying "ac-proxying" +#define NID_ac_proxying 397 +#define OBJ_ac_proxying 1L, 3L, 6L, 1L, 5L, 5L, 7L, 1L, 10L + +#define SN_sinfo_access "subjectInfoAccess" +#define LN_sinfo_access "Subject Information Access" +#define NID_sinfo_access 398 +#define OBJ_sinfo_access 1L, 3L, 6L, 1L, 5L, 5L, 7L, 1L, 11L + +#define SN_id_aca_encAttrs "id-aca-encAttrs" +#define NID_id_aca_encAttrs 399 +#define OBJ_id_aca_encAttrs 1L, 3L, 6L, 1L, 5L, 5L, 7L, 10L, 6L + +#define SN_role "role" +#define LN_role "role" +#define NID_role 400 +#define OBJ_role 2L, 5L, 4L, 72L + +#define SN_policy_constraints "policyConstraints" +#define LN_policy_constraints "X509v3 Policy Constraints" +#define NID_policy_constraints 401 +#define OBJ_policy_constraints 2L, 5L, 29L, 36L + +#define SN_target_information "targetInformation" +#define LN_target_information "X509v3 AC Targeting" +#define NID_target_information 402 +#define OBJ_target_information 2L, 5L, 29L, 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 2L, 5L, 29L, 56L + +#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 1L, 2L, 840L, 10045L + +#define SN_X9_62_prime_field "prime-field" +#define NID_X9_62_prime_field 406 +#define OBJ_X9_62_prime_field 1L, 2L, 840L, 10045L, 1L, 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 1L, 2L, 840L, 10045L, 1L, 2L + +#define SN_X9_62_id_ecPublicKey "id-ecPublicKey" +#define NID_X9_62_id_ecPublicKey 408 +#define OBJ_X9_62_id_ecPublicKey 1L, 2L, 840L, 10045L, 2L, 1L + +#define SN_X9_62_prime192v1 "prime192v1" +#define NID_X9_62_prime192v1 409 +#define OBJ_X9_62_prime192v1 1L, 2L, 840L, 10045L, 3L, 1L, 1L + +#define SN_X9_62_prime192v2 "prime192v2" +#define NID_X9_62_prime192v2 410 +#define OBJ_X9_62_prime192v2 1L, 2L, 840L, 10045L, 3L, 1L, 2L + +#define SN_X9_62_prime192v3 "prime192v3" +#define NID_X9_62_prime192v3 411 +#define OBJ_X9_62_prime192v3 1L, 2L, 840L, 10045L, 3L, 1L, 3L + +#define SN_X9_62_prime239v1 "prime239v1" +#define NID_X9_62_prime239v1 412 +#define OBJ_X9_62_prime239v1 1L, 2L, 840L, 10045L, 3L, 1L, 4L + +#define SN_X9_62_prime239v2 "prime239v2" +#define NID_X9_62_prime239v2 413 +#define OBJ_X9_62_prime239v2 1L, 2L, 840L, 10045L, 3L, 1L, 5L + +#define SN_X9_62_prime239v3 "prime239v3" +#define NID_X9_62_prime239v3 414 +#define OBJ_X9_62_prime239v3 1L, 2L, 840L, 10045L, 3L, 1L, 6L + +#define SN_X9_62_prime256v1 "prime256v1" +#define NID_X9_62_prime256v1 415 +#define OBJ_X9_62_prime256v1 1L, 2L, 840L, 10045L, 3L, 1L, 7L + +#define SN_ecdsa_with_SHA1 "ecdsa-with-SHA1" +#define NID_ecdsa_with_SHA1 416 +#define OBJ_ecdsa_with_SHA1 1L, 2L, 840L, 10045L, 4L, 1L + +#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_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 2L, 16L, 840L, 1L, 101L, 3L, 4L, 1L, 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 2L, 16L, 840L, 1L, 101L, 3L, 4L, 1L, 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 2L, 16L, 840L, 1L, 101L, 3L, 4L, 1L, 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 2L, 16L, 840L, 1L, 101L, 3L, 4L, 1L, 4L + +#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 2L, 16L, 840L, 1L, 101L, 3L, 4L, 1L, 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 2L, 16L, 840L, 1L, 101L, 3L, 4L, 1L, 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 2L, 16L, 840L, 1L, 101L, 3L, 4L, 1L, 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 2L, 16L, 840L, 1L, 101L, 3L, 4L, 1L, 24L + +#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 2L, 16L, 840L, 1L, 101L, 3L, 4L, 1L, 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 2L, 16L, 840L, 1L, 101L, 3L, 4L, 1L, 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 2L, 16L, 840L, 1L, 101L, 3L, 4L, 1L, 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 2L, 16L, 840L, 1L, 101L, 3L, 4L, 1L, 44L + +#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 2L, 5L, 29L, 23L + +#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 1L, 2L, 840L, 10040L, 2L, 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 1L, 2L, 840L, 10040L, 2L, 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 1L, 2L, 840L, 10040L, 2L, 3L + +#define SN_data "data" +#define NID_data 434 +#define OBJ_data 0L, 9L + +#define SN_pss "pss" +#define NID_pss 435 +#define OBJ_pss 0L, 9L, 2342L + +#define SN_ucl "ucl" +#define NID_ucl 436 +#define OBJ_ucl 0L, 9L, 2342L, 19200300L + +#define SN_pilot "pilot" +#define NID_pilot 437 +#define OBJ_pilot 0L, 9L, 2342L, 19200300L, 100L + +#define LN_pilotAttributeType "pilotAttributeType" +#define NID_pilotAttributeType 438 +#define OBJ_pilotAttributeType 0L, 9L, 2342L, 19200300L, 100L, 1L + +#define LN_pilotAttributeSyntax "pilotAttributeSyntax" +#define NID_pilotAttributeSyntax 439 +#define OBJ_pilotAttributeSyntax 0L, 9L, 2342L, 19200300L, 100L, 3L + +#define LN_pilotObjectClass "pilotObjectClass" +#define NID_pilotObjectClass 440 +#define OBJ_pilotObjectClass 0L, 9L, 2342L, 19200300L, 100L, 4L + +#define LN_pilotGroups "pilotGroups" +#define NID_pilotGroups 441 +#define OBJ_pilotGroups 0L, 9L, 2342L, 19200300L, 100L, 10L + +#define LN_iA5StringSyntax "iA5StringSyntax" +#define NID_iA5StringSyntax 442 +#define OBJ_iA5StringSyntax 0L, 9L, 2342L, 19200300L, 100L, 3L, 4L + +#define LN_caseIgnoreIA5StringSyntax "caseIgnoreIA5StringSyntax" +#define NID_caseIgnoreIA5StringSyntax 443 +#define OBJ_caseIgnoreIA5StringSyntax 0L, 9L, 2342L, 19200300L, 100L, 3L, 5L + +#define LN_pilotObject "pilotObject" +#define NID_pilotObject 444 +#define OBJ_pilotObject 0L, 9L, 2342L, 19200300L, 100L, 4L, 3L + +#define LN_pilotPerson "pilotPerson" +#define NID_pilotPerson 445 +#define OBJ_pilotPerson 0L, 9L, 2342L, 19200300L, 100L, 4L, 4L + +#define SN_account "account" +#define NID_account 446 +#define OBJ_account 0L, 9L, 2342L, 19200300L, 100L, 4L, 5L + +#define SN_document "document" +#define NID_document 447 +#define OBJ_document 0L, 9L, 2342L, 19200300L, 100L, 4L, 6L + +#define SN_room "room" +#define NID_room 448 +#define OBJ_room 0L, 9L, 2342L, 19200300L, 100L, 4L, 7L + +#define LN_documentSeries "documentSeries" +#define NID_documentSeries 449 +#define OBJ_documentSeries 0L, 9L, 2342L, 19200300L, 100L, 4L, 9L + +#define LN_rFC822localPart "rFC822localPart" +#define NID_rFC822localPart 450 +#define OBJ_rFC822localPart 0L, 9L, 2342L, 19200300L, 100L, 4L, 14L + +#define LN_dNSDomain "dNSDomain" +#define NID_dNSDomain 451 +#define OBJ_dNSDomain 0L, 9L, 2342L, 19200300L, 100L, 4L, 15L + +#define LN_domainRelatedObject "domainRelatedObject" +#define NID_domainRelatedObject 452 +#define OBJ_domainRelatedObject 0L, 9L, 2342L, 19200300L, 100L, 4L, 17L + +#define LN_friendlyCountry "friendlyCountry" +#define NID_friendlyCountry 453 +#define OBJ_friendlyCountry 0L, 9L, 2342L, 19200300L, 100L, 4L, 18L + +#define LN_simpleSecurityObject "simpleSecurityObject" +#define NID_simpleSecurityObject 454 +#define OBJ_simpleSecurityObject 0L, 9L, 2342L, 19200300L, 100L, 4L, 19L + +#define LN_pilotOrganization "pilotOrganization" +#define NID_pilotOrganization 455 +#define OBJ_pilotOrganization 0L, 9L, 2342L, 19200300L, 100L, 4L, 20L + +#define LN_pilotDSA "pilotDSA" +#define NID_pilotDSA 456 +#define OBJ_pilotDSA 0L, 9L, 2342L, 19200300L, 100L, 4L, 21L + +#define LN_qualityLabelledData "qualityLabelledData" +#define NID_qualityLabelledData 457 +#define OBJ_qualityLabelledData 0L, 9L, 2342L, 19200300L, 100L, 4L, 22L + +#define SN_userId "UID" +#define LN_userId "userId" +#define NID_userId 458 +#define OBJ_userId 0L, 9L, 2342L, 19200300L, 100L, 1L, 1L + +#define LN_textEncodedORAddress "textEncodedORAddress" +#define NID_textEncodedORAddress 459 +#define OBJ_textEncodedORAddress 0L, 9L, 2342L, 19200300L, 100L, 1L, 2L + +#define SN_rfc822Mailbox "mail" +#define LN_rfc822Mailbox "rfc822Mailbox" +#define NID_rfc822Mailbox 460 +#define OBJ_rfc822Mailbox 0L, 9L, 2342L, 19200300L, 100L, 1L, 3L + +#define SN_info "info" +#define NID_info 461 +#define OBJ_info 0L, 9L, 2342L, 19200300L, 100L, 1L, 4L + +#define LN_favouriteDrink "favouriteDrink" +#define NID_favouriteDrink 462 +#define OBJ_favouriteDrink 0L, 9L, 2342L, 19200300L, 100L, 1L, 5L + +#define LN_roomNumber "roomNumber" +#define NID_roomNumber 463 +#define OBJ_roomNumber 0L, 9L, 2342L, 19200300L, 100L, 1L, 6L + +#define SN_photo "photo" +#define NID_photo 464 +#define OBJ_photo 0L, 9L, 2342L, 19200300L, 100L, 1L, 7L + +#define LN_userClass "userClass" +#define NID_userClass 465 +#define OBJ_userClass 0L, 9L, 2342L, 19200300L, 100L, 1L, 8L + +#define SN_host "host" +#define NID_host 466 +#define OBJ_host 0L, 9L, 2342L, 19200300L, 100L, 1L, 9L + +#define SN_manager "manager" +#define NID_manager 467 +#define OBJ_manager 0L, 9L, 2342L, 19200300L, 100L, 1L, 10L + +#define LN_documentIdentifier "documentIdentifier" +#define NID_documentIdentifier 468 +#define OBJ_documentIdentifier 0L, 9L, 2342L, 19200300L, 100L, 1L, 11L + +#define LN_documentTitle "documentTitle" +#define NID_documentTitle 469 +#define OBJ_documentTitle 0L, 9L, 2342L, 19200300L, 100L, 1L, 12L + +#define LN_documentVersion "documentVersion" +#define NID_documentVersion 470 +#define OBJ_documentVersion 0L, 9L, 2342L, 19200300L, 100L, 1L, 13L + +#define LN_documentAuthor "documentAuthor" +#define NID_documentAuthor 471 +#define OBJ_documentAuthor 0L, 9L, 2342L, 19200300L, 100L, 1L, 14L + +#define LN_documentLocation "documentLocation" +#define NID_documentLocation 472 +#define OBJ_documentLocation 0L, 9L, 2342L, 19200300L, 100L, 1L, 15L + +#define LN_homeTelephoneNumber "homeTelephoneNumber" +#define NID_homeTelephoneNumber 473 +#define OBJ_homeTelephoneNumber 0L, 9L, 2342L, 19200300L, 100L, 1L, 20L + +#define SN_secretary "secretary" +#define NID_secretary 474 +#define OBJ_secretary 0L, 9L, 2342L, 19200300L, 100L, 1L, 21L + +#define LN_otherMailbox "otherMailbox" +#define NID_otherMailbox 475 +#define OBJ_otherMailbox 0L, 9L, 2342L, 19200300L, 100L, 1L, 22L + +#define LN_lastModifiedTime "lastModifiedTime" +#define NID_lastModifiedTime 476 +#define OBJ_lastModifiedTime 0L, 9L, 2342L, 19200300L, 100L, 1L, 23L + +#define LN_lastModifiedBy "lastModifiedBy" +#define NID_lastModifiedBy 477 +#define OBJ_lastModifiedBy 0L, 9L, 2342L, 19200300L, 100L, 1L, 24L + +#define LN_aRecord "aRecord" +#define NID_aRecord 478 +#define OBJ_aRecord 0L, 9L, 2342L, 19200300L, 100L, 1L, 26L + +#define LN_pilotAttributeType27 "pilotAttributeType27" +#define NID_pilotAttributeType27 479 +#define OBJ_pilotAttributeType27 0L, 9L, 2342L, 19200300L, 100L, 1L, 27L + +#define LN_mXRecord "mXRecord" +#define NID_mXRecord 480 +#define OBJ_mXRecord 0L, 9L, 2342L, 19200300L, 100L, 1L, 28L + +#define LN_nSRecord "nSRecord" +#define NID_nSRecord 481 +#define OBJ_nSRecord 0L, 9L, 2342L, 19200300L, 100L, 1L, 29L + +#define LN_sOARecord "sOARecord" +#define NID_sOARecord 482 +#define OBJ_sOARecord 0L, 9L, 2342L, 19200300L, 100L, 1L, 30L + +#define LN_cNAMERecord "cNAMERecord" +#define NID_cNAMERecord 483 +#define OBJ_cNAMERecord 0L, 9L, 2342L, 19200300L, 100L, 1L, 31L + +#define LN_associatedDomain "associatedDomain" +#define NID_associatedDomain 484 +#define OBJ_associatedDomain 0L, 9L, 2342L, 19200300L, 100L, 1L, 37L + +#define LN_associatedName "associatedName" +#define NID_associatedName 485 +#define OBJ_associatedName 0L, 9L, 2342L, 19200300L, 100L, 1L, 38L + +#define LN_homePostalAddress "homePostalAddress" +#define NID_homePostalAddress 486 +#define OBJ_homePostalAddress 0L, 9L, 2342L, 19200300L, 100L, 1L, 39L + +#define LN_personalTitle "personalTitle" +#define NID_personalTitle 487 +#define OBJ_personalTitle 0L, 9L, 2342L, 19200300L, 100L, 1L, 40L + +#define LN_mobileTelephoneNumber "mobileTelephoneNumber" +#define NID_mobileTelephoneNumber 488 +#define OBJ_mobileTelephoneNumber 0L, 9L, 2342L, 19200300L, 100L, 1L, 41L + +#define LN_pagerTelephoneNumber "pagerTelephoneNumber" +#define NID_pagerTelephoneNumber 489 +#define OBJ_pagerTelephoneNumber 0L, 9L, 2342L, 19200300L, 100L, 1L, 42L + +#define LN_friendlyCountryName "friendlyCountryName" +#define NID_friendlyCountryName 490 +#define OBJ_friendlyCountryName 0L, 9L, 2342L, 19200300L, 100L, 1L, 43L + +#define LN_organizationalStatus "organizationalStatus" +#define NID_organizationalStatus 491 +#define OBJ_organizationalStatus 0L, 9L, 2342L, 19200300L, 100L, 1L, 45L + +#define LN_janetMailbox "janetMailbox" +#define NID_janetMailbox 492 +#define OBJ_janetMailbox 0L, 9L, 2342L, 19200300L, 100L, 1L, 46L + +#define LN_mailPreferenceOption "mailPreferenceOption" +#define NID_mailPreferenceOption 493 +#define OBJ_mailPreferenceOption 0L, 9L, 2342L, 19200300L, 100L, 1L, 47L + +#define LN_buildingName "buildingName" +#define NID_buildingName 494 +#define OBJ_buildingName 0L, 9L, 2342L, 19200300L, 100L, 1L, 48L + +#define LN_dSAQuality "dSAQuality" +#define NID_dSAQuality 495 +#define OBJ_dSAQuality 0L, 9L, 2342L, 19200300L, 100L, 1L, 49L + +#define LN_singleLevelQuality "singleLevelQuality" +#define NID_singleLevelQuality 496 +#define OBJ_singleLevelQuality 0L, 9L, 2342L, 19200300L, 100L, 1L, 50L + +#define LN_subtreeMinimumQuality "subtreeMinimumQuality" +#define NID_subtreeMinimumQuality 497 +#define OBJ_subtreeMinimumQuality 0L, 9L, 2342L, 19200300L, 100L, 1L, 51L + +#define LN_subtreeMaximumQuality "subtreeMaximumQuality" +#define NID_subtreeMaximumQuality 498 +#define OBJ_subtreeMaximumQuality 0L, 9L, 2342L, 19200300L, 100L, 1L, 52L + +#define LN_personalSignature "personalSignature" +#define NID_personalSignature 499 +#define OBJ_personalSignature 0L, 9L, 2342L, 19200300L, 100L, 1L, 53L + +#define LN_dITRedirect "dITRedirect" +#define NID_dITRedirect 500 +#define OBJ_dITRedirect 0L, 9L, 2342L, 19200300L, 100L, 1L, 54L + +#define SN_audio "audio" +#define NID_audio 501 +#define OBJ_audio 0L, 9L, 2342L, 19200300L, 100L, 1L, 55L + +#define LN_documentPublisher "documentPublisher" +#define NID_documentPublisher 502 +#define OBJ_documentPublisher 0L, 9L, 2342L, 19200300L, 100L, 1L, 56L + +#define LN_x500UniqueIdentifier "x500UniqueIdentifier" +#define NID_x500UniqueIdentifier 503 +#define OBJ_x500UniqueIdentifier 2L, 5L, 4L, 45L + +#define SN_mime_mhs "mime-mhs" +#define LN_mime_mhs "MIME MHS" +#define NID_mime_mhs 504 +#define OBJ_mime_mhs 1L, 3L, 6L, 1L, 7L, 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 1L, 3L, 6L, 1L, 7L, 1L, 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 1L, 3L, 6L, 1L, 7L, 1L, 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 1L, 3L, 6L, 1L, 7L, 1L, 1L, 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 1L, 3L, 6L, 1L, 7L, 1L, 1L, 2L + +#define LN_generationQualifier "generationQualifier" +#define NID_generationQualifier 509 +#define OBJ_generationQualifier 2L, 5L, 4L, 44L + +#define LN_pseudonym "pseudonym" +#define NID_pseudonym 510 +#define OBJ_pseudonym 2L, 5L, 4L, 65L + +#define SN_id_set "id-set" +#define LN_id_set "Secure Electronic Transactions" +#define NID_id_set 512 +#define OBJ_id_set 2L, 23L, 42L + +#define SN_set_ctype "set-ctype" +#define LN_set_ctype "content types" +#define NID_set_ctype 513 +#define OBJ_set_ctype 2L, 23L, 42L, 0L + +#define SN_set_msgExt "set-msgExt" +#define LN_set_msgExt "message extensions" +#define NID_set_msgExt 514 +#define OBJ_set_msgExt 2L, 23L, 42L, 1L + +#define SN_set_attr "set-attr" +#define NID_set_attr 515 +#define OBJ_set_attr 2L, 23L, 42L, 3L + +#define SN_set_policy "set-policy" +#define NID_set_policy 516 +#define OBJ_set_policy 2L, 23L, 42L, 5L + +#define SN_set_certExt "set-certExt" +#define LN_set_certExt "certificate extensions" +#define NID_set_certExt 517 +#define OBJ_set_certExt 2L, 23L, 42L, 7L + +#define SN_set_brand "set-brand" +#define NID_set_brand 518 +#define OBJ_set_brand 2L, 23L, 42L, 8L + +#define SN_setct_PANData "setct-PANData" +#define NID_setct_PANData 519 +#define OBJ_setct_PANData 2L, 23L, 42L, 0L, 0L + +#define SN_setct_PANToken "setct-PANToken" +#define NID_setct_PANToken 520 +#define OBJ_setct_PANToken 2L, 23L, 42L, 0L, 1L + +#define SN_setct_PANOnly "setct-PANOnly" +#define NID_setct_PANOnly 521 +#define OBJ_setct_PANOnly 2L, 23L, 42L, 0L, 2L + +#define SN_setct_OIData "setct-OIData" +#define NID_setct_OIData 522 +#define OBJ_setct_OIData 2L, 23L, 42L, 0L, 3L + +#define SN_setct_PI "setct-PI" +#define NID_setct_PI 523 +#define OBJ_setct_PI 2L, 23L, 42L, 0L, 4L + +#define SN_setct_PIData "setct-PIData" +#define NID_setct_PIData 524 +#define OBJ_setct_PIData 2L, 23L, 42L, 0L, 5L + +#define SN_setct_PIDataUnsigned "setct-PIDataUnsigned" +#define NID_setct_PIDataUnsigned 525 +#define OBJ_setct_PIDataUnsigned 2L, 23L, 42L, 0L, 6L + +#define SN_setct_HODInput "setct-HODInput" +#define NID_setct_HODInput 526 +#define OBJ_setct_HODInput 2L, 23L, 42L, 0L, 7L + +#define SN_setct_AuthResBaggage "setct-AuthResBaggage" +#define NID_setct_AuthResBaggage 527 +#define OBJ_setct_AuthResBaggage 2L, 23L, 42L, 0L, 8L + +#define SN_setct_AuthRevReqBaggage "setct-AuthRevReqBaggage" +#define NID_setct_AuthRevReqBaggage 528 +#define OBJ_setct_AuthRevReqBaggage 2L, 23L, 42L, 0L, 9L + +#define SN_setct_AuthRevResBaggage "setct-AuthRevResBaggage" +#define NID_setct_AuthRevResBaggage 529 +#define OBJ_setct_AuthRevResBaggage 2L, 23L, 42L, 0L, 10L + +#define SN_setct_CapTokenSeq "setct-CapTokenSeq" +#define NID_setct_CapTokenSeq 530 +#define OBJ_setct_CapTokenSeq 2L, 23L, 42L, 0L, 11L + +#define SN_setct_PInitResData "setct-PInitResData" +#define NID_setct_PInitResData 531 +#define OBJ_setct_PInitResData 2L, 23L, 42L, 0L, 12L + +#define SN_setct_PI_TBS "setct-PI-TBS" +#define NID_setct_PI_TBS 532 +#define OBJ_setct_PI_TBS 2L, 23L, 42L, 0L, 13L + +#define SN_setct_PResData "setct-PResData" +#define NID_setct_PResData 533 +#define OBJ_setct_PResData 2L, 23L, 42L, 0L, 14L + +#define SN_setct_AuthReqTBS "setct-AuthReqTBS" +#define NID_setct_AuthReqTBS 534 +#define OBJ_setct_AuthReqTBS 2L, 23L, 42L, 0L, 16L + +#define SN_setct_AuthResTBS "setct-AuthResTBS" +#define NID_setct_AuthResTBS 535 +#define OBJ_setct_AuthResTBS 2L, 23L, 42L, 0L, 17L + +#define SN_setct_AuthResTBSX "setct-AuthResTBSX" +#define NID_setct_AuthResTBSX 536 +#define OBJ_setct_AuthResTBSX 2L, 23L, 42L, 0L, 18L + +#define SN_setct_AuthTokenTBS "setct-AuthTokenTBS" +#define NID_setct_AuthTokenTBS 537 +#define OBJ_setct_AuthTokenTBS 2L, 23L, 42L, 0L, 19L + +#define SN_setct_CapTokenData "setct-CapTokenData" +#define NID_setct_CapTokenData 538 +#define OBJ_setct_CapTokenData 2L, 23L, 42L, 0L, 20L + +#define SN_setct_CapTokenTBS "setct-CapTokenTBS" +#define NID_setct_CapTokenTBS 539 +#define OBJ_setct_CapTokenTBS 2L, 23L, 42L, 0L, 21L + +#define SN_setct_AcqCardCodeMsg "setct-AcqCardCodeMsg" +#define NID_setct_AcqCardCodeMsg 540 +#define OBJ_setct_AcqCardCodeMsg 2L, 23L, 42L, 0L, 22L + +#define SN_setct_AuthRevReqTBS "setct-AuthRevReqTBS" +#define NID_setct_AuthRevReqTBS 541 +#define OBJ_setct_AuthRevReqTBS 2L, 23L, 42L, 0L, 23L + +#define SN_setct_AuthRevResData "setct-AuthRevResData" +#define NID_setct_AuthRevResData 542 +#define OBJ_setct_AuthRevResData 2L, 23L, 42L, 0L, 24L + +#define SN_setct_AuthRevResTBS "setct-AuthRevResTBS" +#define NID_setct_AuthRevResTBS 543 +#define OBJ_setct_AuthRevResTBS 2L, 23L, 42L, 0L, 25L + +#define SN_setct_CapReqTBS "setct-CapReqTBS" +#define NID_setct_CapReqTBS 544 +#define OBJ_setct_CapReqTBS 2L, 23L, 42L, 0L, 26L + +#define SN_setct_CapReqTBSX "setct-CapReqTBSX" +#define NID_setct_CapReqTBSX 545 +#define OBJ_setct_CapReqTBSX 2L, 23L, 42L, 0L, 27L + +#define SN_setct_CapResData "setct-CapResData" +#define NID_setct_CapResData 546 +#define OBJ_setct_CapResData 2L, 23L, 42L, 0L, 28L + +#define SN_setct_CapRevReqTBS "setct-CapRevReqTBS" +#define NID_setct_CapRevReqTBS 547 +#define OBJ_setct_CapRevReqTBS 2L, 23L, 42L, 0L, 29L + +#define SN_setct_CapRevReqTBSX "setct-CapRevReqTBSX" +#define NID_setct_CapRevReqTBSX 548 +#define OBJ_setct_CapRevReqTBSX 2L, 23L, 42L, 0L, 30L + +#define SN_setct_CapRevResData "setct-CapRevResData" +#define NID_setct_CapRevResData 549 +#define OBJ_setct_CapRevResData 2L, 23L, 42L, 0L, 31L + +#define SN_setct_CredReqTBS "setct-CredReqTBS" +#define NID_setct_CredReqTBS 550 +#define OBJ_setct_CredReqTBS 2L, 23L, 42L, 0L, 32L + +#define SN_setct_CredReqTBSX "setct-CredReqTBSX" +#define NID_setct_CredReqTBSX 551 +#define OBJ_setct_CredReqTBSX 2L, 23L, 42L, 0L, 33L + +#define SN_setct_CredResData "setct-CredResData" +#define NID_setct_CredResData 552 +#define OBJ_setct_CredResData 2L, 23L, 42L, 0L, 34L + +#define SN_setct_CredRevReqTBS "setct-CredRevReqTBS" +#define NID_setct_CredRevReqTBS 553 +#define OBJ_setct_CredRevReqTBS 2L, 23L, 42L, 0L, 35L + +#define SN_setct_CredRevReqTBSX "setct-CredRevReqTBSX" +#define NID_setct_CredRevReqTBSX 554 +#define OBJ_setct_CredRevReqTBSX 2L, 23L, 42L, 0L, 36L + +#define SN_setct_CredRevResData "setct-CredRevResData" +#define NID_setct_CredRevResData 555 +#define OBJ_setct_CredRevResData 2L, 23L, 42L, 0L, 37L + +#define SN_setct_PCertReqData "setct-PCertReqData" +#define NID_setct_PCertReqData 556 +#define OBJ_setct_PCertReqData 2L, 23L, 42L, 0L, 38L + +#define SN_setct_PCertResTBS "setct-PCertResTBS" +#define NID_setct_PCertResTBS 557 +#define OBJ_setct_PCertResTBS 2L, 23L, 42L, 0L, 39L + +#define SN_setct_BatchAdminReqData "setct-BatchAdminReqData" +#define NID_setct_BatchAdminReqData 558 +#define OBJ_setct_BatchAdminReqData 2L, 23L, 42L, 0L, 40L + +#define SN_setct_BatchAdminResData "setct-BatchAdminResData" +#define NID_setct_BatchAdminResData 559 +#define OBJ_setct_BatchAdminResData 2L, 23L, 42L, 0L, 41L + +#define SN_setct_CardCInitResTBS "setct-CardCInitResTBS" +#define NID_setct_CardCInitResTBS 560 +#define OBJ_setct_CardCInitResTBS 2L, 23L, 42L, 0L, 42L + +#define SN_setct_MeAqCInitResTBS "setct-MeAqCInitResTBS" +#define NID_setct_MeAqCInitResTBS 561 +#define OBJ_setct_MeAqCInitResTBS 2L, 23L, 42L, 0L, 43L + +#define SN_setct_RegFormResTBS "setct-RegFormResTBS" +#define NID_setct_RegFormResTBS 562 +#define OBJ_setct_RegFormResTBS 2L, 23L, 42L, 0L, 44L + +#define SN_setct_CertReqData "setct-CertReqData" +#define NID_setct_CertReqData 563 +#define OBJ_setct_CertReqData 2L, 23L, 42L, 0L, 45L + +#define SN_setct_CertReqTBS "setct-CertReqTBS" +#define NID_setct_CertReqTBS 564 +#define OBJ_setct_CertReqTBS 2L, 23L, 42L, 0L, 46L + +#define SN_setct_CertResData "setct-CertResData" +#define NID_setct_CertResData 565 +#define OBJ_setct_CertResData 2L, 23L, 42L, 0L, 47L + +#define SN_setct_CertInqReqTBS "setct-CertInqReqTBS" +#define NID_setct_CertInqReqTBS 566 +#define OBJ_setct_CertInqReqTBS 2L, 23L, 42L, 0L, 48L + +#define SN_setct_ErrorTBS "setct-ErrorTBS" +#define NID_setct_ErrorTBS 567 +#define OBJ_setct_ErrorTBS 2L, 23L, 42L, 0L, 49L + +#define SN_setct_PIDualSignedTBE "setct-PIDualSignedTBE" +#define NID_setct_PIDualSignedTBE 568 +#define OBJ_setct_PIDualSignedTBE 2L, 23L, 42L, 0L, 50L + +#define SN_setct_PIUnsignedTBE "setct-PIUnsignedTBE" +#define NID_setct_PIUnsignedTBE 569 +#define OBJ_setct_PIUnsignedTBE 2L, 23L, 42L, 0L, 51L + +#define SN_setct_AuthReqTBE "setct-AuthReqTBE" +#define NID_setct_AuthReqTBE 570 +#define OBJ_setct_AuthReqTBE 2L, 23L, 42L, 0L, 52L + +#define SN_setct_AuthResTBE "setct-AuthResTBE" +#define NID_setct_AuthResTBE 571 +#define OBJ_setct_AuthResTBE 2L, 23L, 42L, 0L, 53L + +#define SN_setct_AuthResTBEX "setct-AuthResTBEX" +#define NID_setct_AuthResTBEX 572 +#define OBJ_setct_AuthResTBEX 2L, 23L, 42L, 0L, 54L + +#define SN_setct_AuthTokenTBE "setct-AuthTokenTBE" +#define NID_setct_AuthTokenTBE 573 +#define OBJ_setct_AuthTokenTBE 2L, 23L, 42L, 0L, 55L + +#define SN_setct_CapTokenTBE "setct-CapTokenTBE" +#define NID_setct_CapTokenTBE 574 +#define OBJ_setct_CapTokenTBE 2L, 23L, 42L, 0L, 56L + +#define SN_setct_CapTokenTBEX "setct-CapTokenTBEX" +#define NID_setct_CapTokenTBEX 575 +#define OBJ_setct_CapTokenTBEX 2L, 23L, 42L, 0L, 57L + +#define SN_setct_AcqCardCodeMsgTBE "setct-AcqCardCodeMsgTBE" +#define NID_setct_AcqCardCodeMsgTBE 576 +#define OBJ_setct_AcqCardCodeMsgTBE 2L, 23L, 42L, 0L, 58L + +#define SN_setct_AuthRevReqTBE "setct-AuthRevReqTBE" +#define NID_setct_AuthRevReqTBE 577 +#define OBJ_setct_AuthRevReqTBE 2L, 23L, 42L, 0L, 59L + +#define SN_setct_AuthRevResTBE "setct-AuthRevResTBE" +#define NID_setct_AuthRevResTBE 578 +#define OBJ_setct_AuthRevResTBE 2L, 23L, 42L, 0L, 60L + +#define SN_setct_AuthRevResTBEB "setct-AuthRevResTBEB" +#define NID_setct_AuthRevResTBEB 579 +#define OBJ_setct_AuthRevResTBEB 2L, 23L, 42L, 0L, 61L + +#define SN_setct_CapReqTBE "setct-CapReqTBE" +#define NID_setct_CapReqTBE 580 +#define OBJ_setct_CapReqTBE 2L, 23L, 42L, 0L, 62L + +#define SN_setct_CapReqTBEX "setct-CapReqTBEX" +#define NID_setct_CapReqTBEX 581 +#define OBJ_setct_CapReqTBEX 2L, 23L, 42L, 0L, 63L + +#define SN_setct_CapResTBE "setct-CapResTBE" +#define NID_setct_CapResTBE 582 +#define OBJ_setct_CapResTBE 2L, 23L, 42L, 0L, 64L + +#define SN_setct_CapRevReqTBE "setct-CapRevReqTBE" +#define NID_setct_CapRevReqTBE 583 +#define OBJ_setct_CapRevReqTBE 2L, 23L, 42L, 0L, 65L + +#define SN_setct_CapRevReqTBEX "setct-CapRevReqTBEX" +#define NID_setct_CapRevReqTBEX 584 +#define OBJ_setct_CapRevReqTBEX 2L, 23L, 42L, 0L, 66L + +#define SN_setct_CapRevResTBE "setct-CapRevResTBE" +#define NID_setct_CapRevResTBE 585 +#define OBJ_setct_CapRevResTBE 2L, 23L, 42L, 0L, 67L + +#define SN_setct_CredReqTBE "setct-CredReqTBE" +#define NID_setct_CredReqTBE 586 +#define OBJ_setct_CredReqTBE 2L, 23L, 42L, 0L, 68L + +#define SN_setct_CredReqTBEX "setct-CredReqTBEX" +#define NID_setct_CredReqTBEX 587 +#define OBJ_setct_CredReqTBEX 2L, 23L, 42L, 0L, 69L + +#define SN_setct_CredResTBE "setct-CredResTBE" +#define NID_setct_CredResTBE 588 +#define OBJ_setct_CredResTBE 2L, 23L, 42L, 0L, 70L + +#define SN_setct_CredRevReqTBE "setct-CredRevReqTBE" +#define NID_setct_CredRevReqTBE 589 +#define OBJ_setct_CredRevReqTBE 2L, 23L, 42L, 0L, 71L + +#define SN_setct_CredRevReqTBEX "setct-CredRevReqTBEX" +#define NID_setct_CredRevReqTBEX 590 +#define OBJ_setct_CredRevReqTBEX 2L, 23L, 42L, 0L, 72L + +#define SN_setct_CredRevResTBE "setct-CredRevResTBE" +#define NID_setct_CredRevResTBE 591 +#define OBJ_setct_CredRevResTBE 2L, 23L, 42L, 0L, 73L + +#define SN_setct_BatchAdminReqTBE "setct-BatchAdminReqTBE" +#define NID_setct_BatchAdminReqTBE 592 +#define OBJ_setct_BatchAdminReqTBE 2L, 23L, 42L, 0L, 74L + +#define SN_setct_BatchAdminResTBE "setct-BatchAdminResTBE" +#define NID_setct_BatchAdminResTBE 593 +#define OBJ_setct_BatchAdminResTBE 2L, 23L, 42L, 0L, 75L + +#define SN_setct_RegFormReqTBE "setct-RegFormReqTBE" +#define NID_setct_RegFormReqTBE 594 +#define OBJ_setct_RegFormReqTBE 2L, 23L, 42L, 0L, 76L + +#define SN_setct_CertReqTBE "setct-CertReqTBE" +#define NID_setct_CertReqTBE 595 +#define OBJ_setct_CertReqTBE 2L, 23L, 42L, 0L, 77L + +#define SN_setct_CertReqTBEX "setct-CertReqTBEX" +#define NID_setct_CertReqTBEX 596 +#define OBJ_setct_CertReqTBEX 2L, 23L, 42L, 0L, 78L + +#define SN_setct_CertResTBE "setct-CertResTBE" +#define NID_setct_CertResTBE 597 +#define OBJ_setct_CertResTBE 2L, 23L, 42L, 0L, 79L + +#define SN_setct_CRLNotificationTBS "setct-CRLNotificationTBS" +#define NID_setct_CRLNotificationTBS 598 +#define OBJ_setct_CRLNotificationTBS 2L, 23L, 42L, 0L, 80L + +#define SN_setct_CRLNotificationResTBS "setct-CRLNotificationResTBS" +#define NID_setct_CRLNotificationResTBS 599 +#define OBJ_setct_CRLNotificationResTBS 2L, 23L, 42L, 0L, 81L + +#define SN_setct_BCIDistributionTBS "setct-BCIDistributionTBS" +#define NID_setct_BCIDistributionTBS 600 +#define OBJ_setct_BCIDistributionTBS 2L, 23L, 42L, 0L, 82L + +#define SN_setext_genCrypt "setext-genCrypt" +#define LN_setext_genCrypt "generic cryptogram" +#define NID_setext_genCrypt 601 +#define OBJ_setext_genCrypt 2L, 23L, 42L, 1L, 1L + +#define SN_setext_miAuth "setext-miAuth" +#define LN_setext_miAuth "merchant initiated auth" +#define NID_setext_miAuth 602 +#define OBJ_setext_miAuth 2L, 23L, 42L, 1L, 3L + +#define SN_setext_pinSecure "setext-pinSecure" +#define NID_setext_pinSecure 603 +#define OBJ_setext_pinSecure 2L, 23L, 42L, 1L, 4L + +#define SN_setext_pinAny "setext-pinAny" +#define NID_setext_pinAny 604 +#define OBJ_setext_pinAny 2L, 23L, 42L, 1L, 5L + +#define SN_setext_track2 "setext-track2" +#define NID_setext_track2 605 +#define OBJ_setext_track2 2L, 23L, 42L, 1L, 7L + +#define SN_setext_cv "setext-cv" +#define LN_setext_cv "additional verification" +#define NID_setext_cv 606 +#define OBJ_setext_cv 2L, 23L, 42L, 1L, 8L + +#define SN_set_policy_root "set-policy-root" +#define NID_set_policy_root 607 +#define OBJ_set_policy_root 2L, 23L, 42L, 5L, 0L + +#define SN_setCext_hashedRoot "setCext-hashedRoot" +#define NID_setCext_hashedRoot 608 +#define OBJ_setCext_hashedRoot 2L, 23L, 42L, 7L, 0L + +#define SN_setCext_certType "setCext-certType" +#define NID_setCext_certType 609 +#define OBJ_setCext_certType 2L, 23L, 42L, 7L, 1L + +#define SN_setCext_merchData "setCext-merchData" +#define NID_setCext_merchData 610 +#define OBJ_setCext_merchData 2L, 23L, 42L, 7L, 2L + +#define SN_setCext_cCertRequired "setCext-cCertRequired" +#define NID_setCext_cCertRequired 611 +#define OBJ_setCext_cCertRequired 2L, 23L, 42L, 7L, 3L + +#define SN_setCext_tunneling "setCext-tunneling" +#define NID_setCext_tunneling 612 +#define OBJ_setCext_tunneling 2L, 23L, 42L, 7L, 4L + +#define SN_setCext_setExt "setCext-setExt" +#define NID_setCext_setExt 613 +#define OBJ_setCext_setExt 2L, 23L, 42L, 7L, 5L + +#define SN_setCext_setQualf "setCext-setQualf" +#define NID_setCext_setQualf 614 +#define OBJ_setCext_setQualf 2L, 23L, 42L, 7L, 6L + +#define SN_setCext_PGWYcapabilities "setCext-PGWYcapabilities" +#define NID_setCext_PGWYcapabilities 615 +#define OBJ_setCext_PGWYcapabilities 2L, 23L, 42L, 7L, 7L + +#define SN_setCext_TokenIdentifier "setCext-TokenIdentifier" +#define NID_setCext_TokenIdentifier 616 +#define OBJ_setCext_TokenIdentifier 2L, 23L, 42L, 7L, 8L + +#define SN_setCext_Track2Data "setCext-Track2Data" +#define NID_setCext_Track2Data 617 +#define OBJ_setCext_Track2Data 2L, 23L, 42L, 7L, 9L + +#define SN_setCext_TokenType "setCext-TokenType" +#define NID_setCext_TokenType 618 +#define OBJ_setCext_TokenType 2L, 23L, 42L, 7L, 10L + +#define SN_setCext_IssuerCapabilities "setCext-IssuerCapabilities" +#define NID_setCext_IssuerCapabilities 619 +#define OBJ_setCext_IssuerCapabilities 2L, 23L, 42L, 7L, 11L + +#define SN_setAttr_Cert "setAttr-Cert" +#define NID_setAttr_Cert 620 +#define OBJ_setAttr_Cert 2L, 23L, 42L, 3L, 0L + +#define SN_setAttr_PGWYcap "setAttr-PGWYcap" +#define LN_setAttr_PGWYcap "payment gateway capabilities" +#define NID_setAttr_PGWYcap 621 +#define OBJ_setAttr_PGWYcap 2L, 23L, 42L, 3L, 1L + +#define SN_setAttr_TokenType "setAttr-TokenType" +#define NID_setAttr_TokenType 622 +#define OBJ_setAttr_TokenType 2L, 23L, 42L, 3L, 2L + +#define SN_setAttr_IssCap "setAttr-IssCap" +#define LN_setAttr_IssCap "issuer capabilities" +#define NID_setAttr_IssCap 623 +#define OBJ_setAttr_IssCap 2L, 23L, 42L, 3L, 3L + +#define SN_set_rootKeyThumb "set-rootKeyThumb" +#define NID_set_rootKeyThumb 624 +#define OBJ_set_rootKeyThumb 2L, 23L, 42L, 3L, 0L, 0L + +#define SN_set_addPolicy "set-addPolicy" +#define NID_set_addPolicy 625 +#define OBJ_set_addPolicy 2L, 23L, 42L, 3L, 0L, 1L + +#define SN_setAttr_Token_EMV "setAttr-Token-EMV" +#define NID_setAttr_Token_EMV 626 +#define OBJ_setAttr_Token_EMV 2L, 23L, 42L, 3L, 2L, 1L + +#define SN_setAttr_Token_B0Prime "setAttr-Token-B0Prime" +#define NID_setAttr_Token_B0Prime 627 +#define OBJ_setAttr_Token_B0Prime 2L, 23L, 42L, 3L, 2L, 2L + +#define SN_setAttr_IssCap_CVM "setAttr-IssCap-CVM" +#define NID_setAttr_IssCap_CVM 628 +#define OBJ_setAttr_IssCap_CVM 2L, 23L, 42L, 3L, 3L, 3L + +#define SN_setAttr_IssCap_T2 "setAttr-IssCap-T2" +#define NID_setAttr_IssCap_T2 629 +#define OBJ_setAttr_IssCap_T2 2L, 23L, 42L, 3L, 3L, 4L + +#define SN_setAttr_IssCap_Sig "setAttr-IssCap-Sig" +#define NID_setAttr_IssCap_Sig 630 +#define OBJ_setAttr_IssCap_Sig 2L, 23L, 42L, 3L, 3L, 5L + +#define SN_setAttr_GenCryptgrm "setAttr-GenCryptgrm" +#define LN_setAttr_GenCryptgrm "generate cryptogram" +#define NID_setAttr_GenCryptgrm 631 +#define OBJ_setAttr_GenCryptgrm 2L, 23L, 42L, 3L, 3L, 3L, 1L + +#define SN_setAttr_T2Enc "setAttr-T2Enc" +#define LN_setAttr_T2Enc "encrypted track 2" +#define NID_setAttr_T2Enc 632 +#define OBJ_setAttr_T2Enc 2L, 23L, 42L, 3L, 3L, 4L, 1L + +#define SN_setAttr_T2cleartxt "setAttr-T2cleartxt" +#define LN_setAttr_T2cleartxt "cleartext track 2" +#define NID_setAttr_T2cleartxt 633 +#define OBJ_setAttr_T2cleartxt 2L, 23L, 42L, 3L, 3L, 4L, 2L + +#define SN_setAttr_TokICCsig "setAttr-TokICCsig" +#define LN_setAttr_TokICCsig "ICC or token signature" +#define NID_setAttr_TokICCsig 634 +#define OBJ_setAttr_TokICCsig 2L, 23L, 42L, 3L, 3L, 5L, 1L + +#define SN_setAttr_SecDevSig "setAttr-SecDevSig" +#define LN_setAttr_SecDevSig "secure device signature" +#define NID_setAttr_SecDevSig 635 +#define OBJ_setAttr_SecDevSig 2L, 23L, 42L, 3L, 3L, 5L, 2L + +#define SN_set_brand_IATA_ATA "set-brand-IATA-ATA" +#define NID_set_brand_IATA_ATA 636 +#define OBJ_set_brand_IATA_ATA 2L, 23L, 42L, 8L, 1L + +#define SN_set_brand_Diners "set-brand-Diners" +#define NID_set_brand_Diners 637 +#define OBJ_set_brand_Diners 2L, 23L, 42L, 8L, 30L + +#define SN_set_brand_AmericanExpress "set-brand-AmericanExpress" +#define NID_set_brand_AmericanExpress 638 +#define OBJ_set_brand_AmericanExpress 2L, 23L, 42L, 8L, 34L + +#define SN_set_brand_JCB "set-brand-JCB" +#define NID_set_brand_JCB 639 +#define OBJ_set_brand_JCB 2L, 23L, 42L, 8L, 35L + +#define SN_set_brand_Visa "set-brand-Visa" +#define NID_set_brand_Visa 640 +#define OBJ_set_brand_Visa 2L, 23L, 42L, 8L, 4L + +#define SN_set_brand_MasterCard "set-brand-MasterCard" +#define NID_set_brand_MasterCard 641 +#define OBJ_set_brand_MasterCard 2L, 23L, 42L, 8L, 5L + +#define SN_set_brand_Novus "set-brand-Novus" +#define NID_set_brand_Novus 642 +#define OBJ_set_brand_Novus 2L, 23L, 42L, 8L, 6011L + +#define SN_des_cdmf "DES-CDMF" +#define LN_des_cdmf "des-cdmf" +#define NID_des_cdmf 643 +#define OBJ_des_cdmf 1L, 2L, 840L, 113549L, 3L, 10L + +#define SN_rsaOAEPEncryptionSET "rsaOAEPEncryptionSET" +#define NID_rsaOAEPEncryptionSET 644 +#define OBJ_rsaOAEPEncryptionSET 1L, 2L, 840L, 113549L, 1L, 1L, 6L + +#define SN_itu_t "ITU-T" +#define LN_itu_t "itu-t" +#define NID_itu_t 645 +#define OBJ_itu_t 0L + +#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 SN_international_organizations "international-organizations" +#define LN_international_organizations "International Organizations" +#define NID_international_organizations 647 +#define OBJ_international_organizations 2L, 23L + +#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_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_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 SN_streetAddress "street" +#define LN_streetAddress "streetAddress" +#define NID_streetAddress 660 +#define OBJ_streetAddress 2L, 5L, 4L, 9L + +#define LN_postalCode "postalCode" +#define NID_postalCode 661 +#define OBJ_postalCode 2L, 5L, 4L, 17L + +#define SN_id_ppl "id-ppl" +#define NID_id_ppl 662 +#define OBJ_id_ppl 1L, 3L, 6L, 1L, 5L, 5L, 7L, 21L + +#define SN_proxyCertInfo "proxyCertInfo" +#define LN_proxyCertInfo "Proxy Certificate Information" +#define NID_proxyCertInfo 663 +#define OBJ_proxyCertInfo 1L, 3L, 6L, 1L, 5L, 5L, 7L, 1L, 14L + +#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 1L, 3L, 6L, 1L, 5L, 5L, 7L, 21L, 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 1L, 3L, 6L, 1L, 5L, 5L, 7L, 21L, 1L + +#define SN_name_constraints "nameConstraints" +#define LN_name_constraints "X509v3 Name Constraints" +#define NID_name_constraints 666 +#define OBJ_name_constraints 2L, 5L, 29L, 30L + +#define SN_Independent "id-ppl-independent" +#define LN_Independent "Independent" +#define NID_Independent 667 +#define OBJ_Independent 1L, 3L, 6L, 1L, 5L, 5L, 7L, 21L, 2L + +#define SN_sha256WithRSAEncryption "RSA-SHA256" +#define LN_sha256WithRSAEncryption "sha256WithRSAEncryption" +#define NID_sha256WithRSAEncryption 668 +#define OBJ_sha256WithRSAEncryption 1L, 2L, 840L, 113549L, 1L, 1L, 11L + +#define SN_sha384WithRSAEncryption "RSA-SHA384" +#define LN_sha384WithRSAEncryption "sha384WithRSAEncryption" +#define NID_sha384WithRSAEncryption 669 +#define OBJ_sha384WithRSAEncryption 1L, 2L, 840L, 113549L, 1L, 1L, 12L + +#define SN_sha512WithRSAEncryption "RSA-SHA512" +#define LN_sha512WithRSAEncryption "sha512WithRSAEncryption" +#define NID_sha512WithRSAEncryption 670 +#define OBJ_sha512WithRSAEncryption 1L, 2L, 840L, 113549L, 1L, 1L, 13L + +#define SN_sha224WithRSAEncryption "RSA-SHA224" +#define LN_sha224WithRSAEncryption "sha224WithRSAEncryption" +#define NID_sha224WithRSAEncryption 671 +#define OBJ_sha224WithRSAEncryption 1L, 2L, 840L, 113549L, 1L, 1L, 14L + +#define SN_sha256 "SHA256" +#define LN_sha256 "sha256" +#define NID_sha256 672 +#define OBJ_sha256 2L, 16L, 840L, 1L, 101L, 3L, 4L, 2L, 1L + +#define SN_sha384 "SHA384" +#define LN_sha384 "sha384" +#define NID_sha384 673 +#define OBJ_sha384 2L, 16L, 840L, 1L, 101L, 3L, 4L, 2L, 2L + +#define SN_sha512 "SHA512" +#define LN_sha512 "sha512" +#define NID_sha512 674 +#define OBJ_sha512 2L, 16L, 840L, 1L, 101L, 3L, 4L, 2L, 3L + +#define SN_sha224 "SHA224" +#define LN_sha224 "sha224" +#define NID_sha224 675 +#define OBJ_sha224 2L, 16L, 840L, 1L, 101L, 3L, 4L, 2L, 4L + +#define SN_identified_organization "identified-organization" +#define NID_identified_organization 676 +#define OBJ_identified_organization 1L, 3L + +#define SN_certicom_arc "certicom-arc" +#define NID_certicom_arc 677 +#define OBJ_certicom_arc 1L, 3L, 132L + +#define SN_wap "wap" +#define NID_wap 678 +#define OBJ_wap 2L, 23L, 43L + +#define SN_wap_wsg "wap-wsg" +#define NID_wap_wsg 679 +#define OBJ_wap_wsg 2L, 23L, 43L, 1L + +#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 1L, 2L, 840L, 10045L, 1L, 2L, 3L + +#define SN_X9_62_onBasis "onBasis" +#define NID_X9_62_onBasis 681 +#define OBJ_X9_62_onBasis 1L, 2L, 840L, 10045L, 1L, 2L, 3L, 1L + +#define SN_X9_62_tpBasis "tpBasis" +#define NID_X9_62_tpBasis 682 +#define OBJ_X9_62_tpBasis 1L, 2L, 840L, 10045L, 1L, 2L, 3L, 2L + +#define SN_X9_62_ppBasis "ppBasis" +#define NID_X9_62_ppBasis 683 +#define OBJ_X9_62_ppBasis 1L, 2L, 840L, 10045L, 1L, 2L, 3L, 3L + +#define SN_X9_62_c2pnb163v1 "c2pnb163v1" +#define NID_X9_62_c2pnb163v1 684 +#define OBJ_X9_62_c2pnb163v1 1L, 2L, 840L, 10045L, 3L, 0L, 1L + +#define SN_X9_62_c2pnb163v2 "c2pnb163v2" +#define NID_X9_62_c2pnb163v2 685 +#define OBJ_X9_62_c2pnb163v2 1L, 2L, 840L, 10045L, 3L, 0L, 2L + +#define SN_X9_62_c2pnb163v3 "c2pnb163v3" +#define NID_X9_62_c2pnb163v3 686 +#define OBJ_X9_62_c2pnb163v3 1L, 2L, 840L, 10045L, 3L, 0L, 3L + +#define SN_X9_62_c2pnb176v1 "c2pnb176v1" +#define NID_X9_62_c2pnb176v1 687 +#define OBJ_X9_62_c2pnb176v1 1L, 2L, 840L, 10045L, 3L, 0L, 4L + +#define SN_X9_62_c2tnb191v1 "c2tnb191v1" +#define NID_X9_62_c2tnb191v1 688 +#define OBJ_X9_62_c2tnb191v1 1L, 2L, 840L, 10045L, 3L, 0L, 5L + +#define SN_X9_62_c2tnb191v2 "c2tnb191v2" +#define NID_X9_62_c2tnb191v2 689 +#define OBJ_X9_62_c2tnb191v2 1L, 2L, 840L, 10045L, 3L, 0L, 6L + +#define SN_X9_62_c2tnb191v3 "c2tnb191v3" +#define NID_X9_62_c2tnb191v3 690 +#define OBJ_X9_62_c2tnb191v3 1L, 2L, 840L, 10045L, 3L, 0L, 7L + +#define SN_X9_62_c2onb191v4 "c2onb191v4" +#define NID_X9_62_c2onb191v4 691 +#define OBJ_X9_62_c2onb191v4 1L, 2L, 840L, 10045L, 3L, 0L, 8L + +#define SN_X9_62_c2onb191v5 "c2onb191v5" +#define NID_X9_62_c2onb191v5 692 +#define OBJ_X9_62_c2onb191v5 1L, 2L, 840L, 10045L, 3L, 0L, 9L + +#define SN_X9_62_c2pnb208w1 "c2pnb208w1" +#define NID_X9_62_c2pnb208w1 693 +#define OBJ_X9_62_c2pnb208w1 1L, 2L, 840L, 10045L, 3L, 0L, 10L + +#define SN_X9_62_c2tnb239v1 "c2tnb239v1" +#define NID_X9_62_c2tnb239v1 694 +#define OBJ_X9_62_c2tnb239v1 1L, 2L, 840L, 10045L, 3L, 0L, 11L + +#define SN_X9_62_c2tnb239v2 "c2tnb239v2" +#define NID_X9_62_c2tnb239v2 695 +#define OBJ_X9_62_c2tnb239v2 1L, 2L, 840L, 10045L, 3L, 0L, 12L + +#define SN_X9_62_c2tnb239v3 "c2tnb239v3" +#define NID_X9_62_c2tnb239v3 696 +#define OBJ_X9_62_c2tnb239v3 1L, 2L, 840L, 10045L, 3L, 0L, 13L + +#define SN_X9_62_c2onb239v4 "c2onb239v4" +#define NID_X9_62_c2onb239v4 697 +#define OBJ_X9_62_c2onb239v4 1L, 2L, 840L, 10045L, 3L, 0L, 14L + +#define SN_X9_62_c2onb239v5 "c2onb239v5" +#define NID_X9_62_c2onb239v5 698 +#define OBJ_X9_62_c2onb239v5 1L, 2L, 840L, 10045L, 3L, 0L, 15L + +#define SN_X9_62_c2pnb272w1 "c2pnb272w1" +#define NID_X9_62_c2pnb272w1 699 +#define OBJ_X9_62_c2pnb272w1 1L, 2L, 840L, 10045L, 3L, 0L, 16L + +#define SN_X9_62_c2pnb304w1 "c2pnb304w1" +#define NID_X9_62_c2pnb304w1 700 +#define OBJ_X9_62_c2pnb304w1 1L, 2L, 840L, 10045L, 3L, 0L, 17L + +#define SN_X9_62_c2tnb359v1 "c2tnb359v1" +#define NID_X9_62_c2tnb359v1 701 +#define OBJ_X9_62_c2tnb359v1 1L, 2L, 840L, 10045L, 3L, 0L, 18L + +#define SN_X9_62_c2pnb368w1 "c2pnb368w1" +#define NID_X9_62_c2pnb368w1 702 +#define OBJ_X9_62_c2pnb368w1 1L, 2L, 840L, 10045L, 3L, 0L, 19L + +#define SN_X9_62_c2tnb431r1 "c2tnb431r1" +#define NID_X9_62_c2tnb431r1 703 +#define OBJ_X9_62_c2tnb431r1 1L, 2L, 840L, 10045L, 3L, 0L, 20L + +#define SN_secp112r1 "secp112r1" +#define NID_secp112r1 704 +#define OBJ_secp112r1 1L, 3L, 132L, 0L, 6L + +#define SN_secp112r2 "secp112r2" +#define NID_secp112r2 705 +#define OBJ_secp112r2 1L, 3L, 132L, 0L, 7L + +#define SN_secp128r1 "secp128r1" +#define NID_secp128r1 706 +#define OBJ_secp128r1 1L, 3L, 132L, 0L, 28L + +#define SN_secp128r2 "secp128r2" +#define NID_secp128r2 707 +#define OBJ_secp128r2 1L, 3L, 132L, 0L, 29L + +#define SN_secp160k1 "secp160k1" +#define NID_secp160k1 708 +#define OBJ_secp160k1 1L, 3L, 132L, 0L, 9L + +#define SN_secp160r1 "secp160r1" +#define NID_secp160r1 709 +#define OBJ_secp160r1 1L, 3L, 132L, 0L, 8L + +#define SN_secp160r2 "secp160r2" +#define NID_secp160r2 710 +#define OBJ_secp160r2 1L, 3L, 132L, 0L, 30L + +#define SN_secp192k1 "secp192k1" +#define NID_secp192k1 711 +#define OBJ_secp192k1 1L, 3L, 132L, 0L, 31L + +#define SN_secp224k1 "secp224k1" +#define NID_secp224k1 712 +#define OBJ_secp224k1 1L, 3L, 132L, 0L, 32L + +#define SN_secp224r1 "secp224r1" +#define NID_secp224r1 713 +#define OBJ_secp224r1 1L, 3L, 132L, 0L, 33L + +#define SN_secp256k1 "secp256k1" +#define NID_secp256k1 714 +#define OBJ_secp256k1 1L, 3L, 132L, 0L, 10L + +#define SN_secp384r1 "secp384r1" +#define NID_secp384r1 715 +#define OBJ_secp384r1 1L, 3L, 132L, 0L, 34L + +#define SN_secp521r1 "secp521r1" +#define NID_secp521r1 716 +#define OBJ_secp521r1 1L, 3L, 132L, 0L, 35L + +#define SN_sect113r1 "sect113r1" +#define NID_sect113r1 717 +#define OBJ_sect113r1 1L, 3L, 132L, 0L, 4L + +#define SN_sect113r2 "sect113r2" +#define NID_sect113r2 718 +#define OBJ_sect113r2 1L, 3L, 132L, 0L, 5L + +#define SN_sect131r1 "sect131r1" +#define NID_sect131r1 719 +#define OBJ_sect131r1 1L, 3L, 132L, 0L, 22L + +#define SN_sect131r2 "sect131r2" +#define NID_sect131r2 720 +#define OBJ_sect131r2 1L, 3L, 132L, 0L, 23L + +#define SN_sect163k1 "sect163k1" +#define NID_sect163k1 721 +#define OBJ_sect163k1 1L, 3L, 132L, 0L, 1L + +#define SN_sect163r1 "sect163r1" +#define NID_sect163r1 722 +#define OBJ_sect163r1 1L, 3L, 132L, 0L, 2L + +#define SN_sect163r2 "sect163r2" +#define NID_sect163r2 723 +#define OBJ_sect163r2 1L, 3L, 132L, 0L, 15L + +#define SN_sect193r1 "sect193r1" +#define NID_sect193r1 724 +#define OBJ_sect193r1 1L, 3L, 132L, 0L, 24L + +#define SN_sect193r2 "sect193r2" +#define NID_sect193r2 725 +#define OBJ_sect193r2 1L, 3L, 132L, 0L, 25L + +#define SN_sect233k1 "sect233k1" +#define NID_sect233k1 726 +#define OBJ_sect233k1 1L, 3L, 132L, 0L, 26L + +#define SN_sect233r1 "sect233r1" +#define NID_sect233r1 727 +#define OBJ_sect233r1 1L, 3L, 132L, 0L, 27L + +#define SN_sect239k1 "sect239k1" +#define NID_sect239k1 728 +#define OBJ_sect239k1 1L, 3L, 132L, 0L, 3L + +#define SN_sect283k1 "sect283k1" +#define NID_sect283k1 729 +#define OBJ_sect283k1 1L, 3L, 132L, 0L, 16L + +#define SN_sect283r1 "sect283r1" +#define NID_sect283r1 730 +#define OBJ_sect283r1 1L, 3L, 132L, 0L, 17L + +#define SN_sect409k1 "sect409k1" +#define NID_sect409k1 731 +#define OBJ_sect409k1 1L, 3L, 132L, 0L, 36L + +#define SN_sect409r1 "sect409r1" +#define NID_sect409r1 732 +#define OBJ_sect409r1 1L, 3L, 132L, 0L, 37L + +#define SN_sect571k1 "sect571k1" +#define NID_sect571k1 733 +#define OBJ_sect571k1 1L, 3L, 132L, 0L, 38L + +#define SN_sect571r1 "sect571r1" +#define NID_sect571r1 734 +#define OBJ_sect571r1 1L, 3L, 132L, 0L, 39L + +#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 2L, 23L, 43L, 1L, 4L, 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 2L, 23L, 43L, 1L, 4L, 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 2L, 23L, 43L, 1L, 4L, 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 2L, 23L, 43L, 1L, 4L, 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 2L, 23L, 43L, 1L, 4L, 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 2L, 23L, 43L, 1L, 4L, 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 2L, 23L, 43L, 1L, 4L, 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 2L, 23L, 43L, 1L, 4L, 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 2L, 23L, 43L, 1L, 4L, 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 2L, 23L, 43L, 1L, 4L, 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 2L, 23L, 43L, 1L, 4L, 12L + +#define SN_any_policy "anyPolicy" +#define LN_any_policy "X509v3 Any Policy" +#define NID_any_policy 746 +#define OBJ_any_policy 2L, 5L, 29L, 32L, 0L + +#define SN_policy_mappings "policyMappings" +#define LN_policy_mappings "X509v3 Policy Mappings" +#define NID_policy_mappings 747 +#define OBJ_policy_mappings 2L, 5L, 29L, 33L + +#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 2L, 5L, 29L, 54L + +#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_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_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 0L, 3L, 4401L, 5L, 3L, 1L, 9L, 1L + +#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 0L, 3L, 4401L, 5L, 3L, 1L, 9L, 21L + +#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 0L, 3L, 4401L, 5L, 3L, 1L, 9L, 41L + +#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 0L, 3L, 4401L, 5L, 3L, 1L, 9L, 4L + +#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 0L, 3L, 4401L, 5L, 3L, 1L, 9L, 24L + +#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 0L, 3L, 4401L, 5L, 3L, 1L, 9L, 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_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 0L, 3L, 4401L, 5L, 3L, 1L, 9L, 3L + +#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 0L, 3L, 4401L, 5L, 3L, 1L, 9L, 23L + +#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 0L, 3L, 4401L, 5L, 3L, 1L, 9L, 43L + +#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 2L, 5L, 29L, 9L + +#define SN_issuing_distribution_point "issuingDistributionPoint" +#define LN_issuing_distribution_point "X509v3 Issuing Distribution Point" +#define NID_issuing_distribution_point 770 +#define OBJ_issuing_distribution_point 2L, 5L, 29L, 28L + +#define SN_certificate_issuer "certificateIssuer" +#define LN_certificate_issuer "X509v3 Certificate Issuer" +#define NID_certificate_issuer 771 +#define OBJ_certificate_issuer 2L, 5L, 29L, 29L + +#define SN_kisa "KISA" +#define LN_kisa "kisa" +#define NID_kisa 773 +#define OBJ_kisa 1L, 2L, 410L, 200004L + +#define SN_seed_ecb "SEED-ECB" +#define LN_seed_ecb "seed-ecb" +#define NID_seed_ecb 776 +#define OBJ_seed_ecb 1L, 2L, 410L, 200004L, 1L, 3L + +#define SN_seed_cbc "SEED-CBC" +#define LN_seed_cbc "seed-cbc" +#define NID_seed_cbc 777 +#define OBJ_seed_cbc 1L, 2L, 410L, 200004L, 1L, 4L + +#define SN_seed_ofb128 "SEED-OFB" +#define LN_seed_ofb128 "seed-ofb" +#define NID_seed_ofb128 778 +#define OBJ_seed_ofb128 1L, 2L, 410L, 200004L, 1L, 6L + +#define SN_seed_cfb128 "SEED-CFB" +#define LN_seed_cfb128 "seed-cfb" +#define NID_seed_cfb128 779 +#define OBJ_seed_cfb128 1L, 2L, 410L, 200004L, 1L, 5L + +#define SN_hmac_md5 "HMAC-MD5" +#define LN_hmac_md5 "hmac-md5" +#define NID_hmac_md5 780 +#define OBJ_hmac_md5 1L, 3L, 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 1L, 3L, 6L, 1L, 5L, 5L, 8L, 1L, 2L + +#define SN_id_PasswordBasedMAC "id-PasswordBasedMAC" +#define LN_id_PasswordBasedMAC "password based MAC" +#define NID_id_PasswordBasedMAC 782 +#define OBJ_id_PasswordBasedMAC 1L, 2L, 840L, 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 1L, 2L, 840L, 113533L, 7L, 66L, 30L + +#define SN_id_it_suppLangTags "id-it-suppLangTags" +#define NID_id_it_suppLangTags 784 +#define OBJ_id_it_suppLangTags 1L, 3L, 6L, 1L, 5L, 5L, 7L, 4L, 16L + +#define SN_caRepository "caRepository" +#define LN_caRepository "CA Repository" +#define NID_caRepository 785 +#define OBJ_caRepository 1L, 3L, 6L, 1L, 5L, 5L, 7L, 48L, 5L + +#define SN_id_smime_ct_compressedData "id-smime-ct-compressedData" +#define NID_id_smime_ct_compressedData 786 +#define OBJ_id_smime_ct_compressedData \ + 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 1L, 9L + +#define SN_id_ct_asciiTextWithCRLF "id-ct-asciiTextWithCRLF" +#define NID_id_ct_asciiTextWithCRLF 787 +#define OBJ_id_ct_asciiTextWithCRLF 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 1L, 27L + +#define SN_id_aes128_wrap "id-aes128-wrap" +#define NID_id_aes128_wrap 788 +#define OBJ_id_aes128_wrap 2L, 16L, 840L, 1L, 101L, 3L, 4L, 1L, 5L + +#define SN_id_aes192_wrap "id-aes192-wrap" +#define NID_id_aes192_wrap 789 +#define OBJ_id_aes192_wrap 2L, 16L, 840L, 1L, 101L, 3L, 4L, 1L, 25L + +#define SN_id_aes256_wrap "id-aes256-wrap" +#define NID_id_aes256_wrap 790 +#define OBJ_id_aes256_wrap 2L, 16L, 840L, 1L, 101L, 3L, 4L, 1L, 45L + +#define SN_ecdsa_with_Recommended "ecdsa-with-Recommended" +#define NID_ecdsa_with_Recommended 791 +#define OBJ_ecdsa_with_Recommended 1L, 2L, 840L, 10045L, 4L, 2L + +#define SN_ecdsa_with_Specified "ecdsa-with-Specified" +#define NID_ecdsa_with_Specified 792 +#define OBJ_ecdsa_with_Specified 1L, 2L, 840L, 10045L, 4L, 3L + +#define SN_ecdsa_with_SHA224 "ecdsa-with-SHA224" +#define NID_ecdsa_with_SHA224 793 +#define OBJ_ecdsa_with_SHA224 1L, 2L, 840L, 10045L, 4L, 3L, 1L + +#define SN_ecdsa_with_SHA256 "ecdsa-with-SHA256" +#define NID_ecdsa_with_SHA256 794 +#define OBJ_ecdsa_with_SHA256 1L, 2L, 840L, 10045L, 4L, 3L, 2L + +#define SN_ecdsa_with_SHA384 "ecdsa-with-SHA384" +#define NID_ecdsa_with_SHA384 795 +#define OBJ_ecdsa_with_SHA384 1L, 2L, 840L, 10045L, 4L, 3L, 3L + +#define SN_ecdsa_with_SHA512 "ecdsa-with-SHA512" +#define NID_ecdsa_with_SHA512 796 +#define OBJ_ecdsa_with_SHA512 1L, 2L, 840L, 10045L, 4L, 3L, 4L + +#define LN_hmacWithMD5 "hmacWithMD5" +#define NID_hmacWithMD5 797 +#define OBJ_hmacWithMD5 1L, 2L, 840L, 113549L, 2L, 6L + +#define LN_hmacWithSHA224 "hmacWithSHA224" +#define NID_hmacWithSHA224 798 +#define OBJ_hmacWithSHA224 1L, 2L, 840L, 113549L, 2L, 8L + +#define LN_hmacWithSHA256 "hmacWithSHA256" +#define NID_hmacWithSHA256 799 +#define OBJ_hmacWithSHA256 1L, 2L, 840L, 113549L, 2L, 9L + +#define LN_hmacWithSHA384 "hmacWithSHA384" +#define NID_hmacWithSHA384 800 +#define OBJ_hmacWithSHA384 1L, 2L, 840L, 113549L, 2L, 10L + +#define LN_hmacWithSHA512 "hmacWithSHA512" +#define NID_hmacWithSHA512 801 +#define OBJ_hmacWithSHA512 1L, 2L, 840L, 113549L, 2L, 11L + +#define SN_dsa_with_SHA224 "dsa_with_SHA224" +#define NID_dsa_with_SHA224 802 +#define OBJ_dsa_with_SHA224 2L, 16L, 840L, 1L, 101L, 3L, 4L, 3L, 1L + +#define SN_dsa_with_SHA256 "dsa_with_SHA256" +#define NID_dsa_with_SHA256 803 +#define OBJ_dsa_with_SHA256 2L, 16L, 840L, 1L, 101L, 3L, 4L, 3L, 2L + +#define SN_whirlpool "whirlpool" +#define NID_whirlpool 804 +#define OBJ_whirlpool 1L, 0L, 10118L, 3L, 0L, 55L + +#define SN_cryptopro "cryptopro" +#define NID_cryptopro 805 +#define OBJ_cryptopro 1L, 2L, 643L, 2L, 2L + +#define SN_cryptocom "cryptocom" +#define NID_cryptocom 806 +#define OBJ_cryptocom 1L, 2L, 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 1L, 2L, 643L, 2L, 2L, 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 1L, 2L, 643L, 2L, 2L, 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 1L, 2L, 643L, 2L, 2L, 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 1L, 2L, 643L, 2L, 2L, 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 1L, 2L, 643L, 2L, 2L, 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 1L, 2L, 643L, 2L, 2L, 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 1L, 2L, 643L, 2L, 2L, 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 1L, 2L, 643L, 2L, 2L, 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 1L, 2L, 643L, 2L, 2L, 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 1L, 2L, 643L, 2L, 2L, 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 1L, 2L, 643L, 2L, 2L, 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 1L, 2L, 643L, 2L, 2L, 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 1L, 2L, 643L, 2L, 2L, 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 1L, 2L, 643L, 2L, 2L, 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 1L, 2L, 643L, 2L, 2L, 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 1L, 2L, 643L, 2L, 2L, 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 1L, 2L, 643L, 2L, 2L, 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 1L, 2L, 643L, 2L, 2L, 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 1L, 2L, 643L, 2L, 2L, 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 1L, 2L, 643L, 2L, 2L, 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 \ + 1L, 2L, 643L, 2L, 2L, 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 \ + 1L, 2L, 643L, 2L, 2L, 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 \ + 1L, 2L, 643L, 2L, 2L, 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 1L, 2L, 643L, 2L, 2L, 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 1L, 2L, 643L, 2L, 2L, 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 1L, 2L, 643L, 2L, 2L, 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 1L, 2L, 643L, 2L, 2L, 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 1L, 2L, 643L, 2L, 2L, 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 \ + 1L, 2L, 643L, 2L, 2L, 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 \ + 1L, 2L, 643L, 2L, 2L, 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 \ + 1L, 2L, 643L, 2L, 2L, 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 1L, 2L, 643L, 2L, 2L, 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 1L, 2L, 643L, 2L, 2L, 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 1L, 2L, 643L, 2L, 2L, 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 1L, 2L, 643L, 2L, 2L, 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 \ + 1L, 2L, 643L, 2L, 2L, 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 \ + 1L, 2L, 643L, 2L, 2L, 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 1L, 2L, 643L, 2L, 2L, 20L, 1L + +#define SN_id_GostR3410_94_aBis "id-GostR3410-94-aBis" +#define NID_id_GostR3410_94_aBis 846 +#define OBJ_id_GostR3410_94_aBis 1L, 2L, 643L, 2L, 2L, 20L, 2L + +#define SN_id_GostR3410_94_b "id-GostR3410-94-b" +#define NID_id_GostR3410_94_b 847 +#define OBJ_id_GostR3410_94_b 1L, 2L, 643L, 2L, 2L, 20L, 3L + +#define SN_id_GostR3410_94_bBis "id-GostR3410-94-bBis" +#define NID_id_GostR3410_94_bBis 848 +#define OBJ_id_GostR3410_94_bBis 1L, 2L, 643L, 2L, 2L, 20L, 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 1L, 2L, 643L, 2L, 9L, 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 1L, 2L, 643L, 2L, 9L, 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 1L, 2L, 643L, 2L, 9L, 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 \ + 1L, 2L, 643L, 2L, 9L, 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 \ + 1L, 2L, 643L, 2L, 9L, 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 1L, 2L, 643L, 2L, 9L, 1L, 8L, 1L + +#define SN_hmac "HMAC" +#define LN_hmac "hmac" +#define NID_hmac 855 + +#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 SN_freshest_crl "freshestCRL" +#define LN_freshest_crl "X509v3 Freshest CRL" +#define NID_freshest_crl 857 +#define OBJ_freshest_crl 2L, 5L, 29L, 46L + +#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 1L, 3L, 6L, 1L, 5L, 5L, 7L, 8L, 3L + +#define LN_searchGuide "searchGuide" +#define NID_searchGuide 859 +#define OBJ_searchGuide 2L, 5L, 4L, 14L + +#define LN_businessCategory "businessCategory" +#define NID_businessCategory 860 +#define OBJ_businessCategory 2L, 5L, 4L, 15L + +#define LN_postalAddress "postalAddress" +#define NID_postalAddress 861 +#define OBJ_postalAddress 2L, 5L, 4L, 16L + +#define LN_postOfficeBox "postOfficeBox" +#define NID_postOfficeBox 862 +#define OBJ_postOfficeBox 2L, 5L, 4L, 18L + +#define LN_physicalDeliveryOfficeName "physicalDeliveryOfficeName" +#define NID_physicalDeliveryOfficeName 863 +#define OBJ_physicalDeliveryOfficeName 2L, 5L, 4L, 19L + +#define LN_telephoneNumber "telephoneNumber" +#define NID_telephoneNumber 864 +#define OBJ_telephoneNumber 2L, 5L, 4L, 20L + +#define LN_telexNumber "telexNumber" +#define NID_telexNumber 865 +#define OBJ_telexNumber 2L, 5L, 4L, 21L + +#define LN_teletexTerminalIdentifier "teletexTerminalIdentifier" +#define NID_teletexTerminalIdentifier 866 +#define OBJ_teletexTerminalIdentifier 2L, 5L, 4L, 22L + +#define LN_facsimileTelephoneNumber "facsimileTelephoneNumber" +#define NID_facsimileTelephoneNumber 867 +#define OBJ_facsimileTelephoneNumber 2L, 5L, 4L, 23L + +#define LN_x121Address "x121Address" +#define NID_x121Address 868 +#define OBJ_x121Address 2L, 5L, 4L, 24L + +#define LN_internationaliSDNNumber "internationaliSDNNumber" +#define NID_internationaliSDNNumber 869 +#define OBJ_internationaliSDNNumber 2L, 5L, 4L, 25L + +#define LN_registeredAddress "registeredAddress" +#define NID_registeredAddress 870 +#define OBJ_registeredAddress 2L, 5L, 4L, 26L + +#define LN_destinationIndicator "destinationIndicator" +#define NID_destinationIndicator 871 +#define OBJ_destinationIndicator 2L, 5L, 4L, 27L + +#define LN_preferredDeliveryMethod "preferredDeliveryMethod" +#define NID_preferredDeliveryMethod 872 +#define OBJ_preferredDeliveryMethod 2L, 5L, 4L, 28L + +#define LN_presentationAddress "presentationAddress" +#define NID_presentationAddress 873 +#define OBJ_presentationAddress 2L, 5L, 4L, 29L + +#define LN_supportedApplicationContext "supportedApplicationContext" +#define NID_supportedApplicationContext 874 +#define OBJ_supportedApplicationContext 2L, 5L, 4L, 30L + +#define SN_member "member" +#define NID_member 875 +#define OBJ_member 2L, 5L, 4L, 31L + +#define SN_owner "owner" +#define NID_owner 876 +#define OBJ_owner 2L, 5L, 4L, 32L + +#define LN_roleOccupant "roleOccupant" +#define NID_roleOccupant 877 +#define OBJ_roleOccupant 2L, 5L, 4L, 33L + +#define SN_seeAlso "seeAlso" +#define NID_seeAlso 878 +#define OBJ_seeAlso 2L, 5L, 4L, 34L + +#define LN_userPassword "userPassword" +#define NID_userPassword 879 +#define OBJ_userPassword 2L, 5L, 4L, 35L + +#define LN_userCertificate "userCertificate" +#define NID_userCertificate 880 +#define OBJ_userCertificate 2L, 5L, 4L, 36L + +#define LN_cACertificate "cACertificate" +#define NID_cACertificate 881 +#define OBJ_cACertificate 2L, 5L, 4L, 37L + +#define LN_authorityRevocationList "authorityRevocationList" +#define NID_authorityRevocationList 882 +#define OBJ_authorityRevocationList 2L, 5L, 4L, 38L + +#define LN_certificateRevocationList "certificateRevocationList" +#define NID_certificateRevocationList 883 +#define OBJ_certificateRevocationList 2L, 5L, 4L, 39L + +#define LN_crossCertificatePair "crossCertificatePair" +#define NID_crossCertificatePair 884 +#define OBJ_crossCertificatePair 2L, 5L, 4L, 40L + +#define LN_enhancedSearchGuide "enhancedSearchGuide" +#define NID_enhancedSearchGuide 885 +#define OBJ_enhancedSearchGuide 2L, 5L, 4L, 47L + +#define LN_protocolInformation "protocolInformation" +#define NID_protocolInformation 886 +#define OBJ_protocolInformation 2L, 5L, 4L, 48L + +#define LN_distinguishedName "distinguishedName" +#define NID_distinguishedName 887 +#define OBJ_distinguishedName 2L, 5L, 4L, 49L + +#define LN_uniqueMember "uniqueMember" +#define NID_uniqueMember 888 +#define OBJ_uniqueMember 2L, 5L, 4L, 50L + +#define LN_houseIdentifier "houseIdentifier" +#define NID_houseIdentifier 889 +#define OBJ_houseIdentifier 2L, 5L, 4L, 51L + +#define LN_supportedAlgorithms "supportedAlgorithms" +#define NID_supportedAlgorithms 890 +#define OBJ_supportedAlgorithms 2L, 5L, 4L, 52L + +#define LN_deltaRevocationList "deltaRevocationList" +#define NID_deltaRevocationList 891 +#define OBJ_deltaRevocationList 2L, 5L, 4L, 53L + +#define SN_dmdName "dmdName" +#define NID_dmdName 892 +#define OBJ_dmdName 2L, 5L, 4L, 54L + +#define SN_id_alg_PWRI_KEK "id-alg-PWRI-KEK" +#define NID_id_alg_PWRI_KEK 893 +#define OBJ_id_alg_PWRI_KEK 1L, 2L, 840L, 113549L, 1L, 9L, 16L, 3L, 9L + +#define SN_cmac "CMAC" +#define LN_cmac "cmac" +#define NID_cmac 894 + +#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 2L, 16L, 840L, 1L, 101L, 3L, 4L, 1L, 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 2L, 16L, 840L, 1L, 101L, 3L, 4L, 1L, 7L + +#define SN_id_aes128_wrap_pad "id-aes128-wrap-pad" +#define NID_id_aes128_wrap_pad 897 +#define OBJ_id_aes128_wrap_pad 2L, 16L, 840L, 1L, 101L, 3L, 4L, 1L, 8L + +#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 2L, 16L, 840L, 1L, 101L, 3L, 4L, 1L, 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 2L, 16L, 840L, 1L, 101L, 3L, 4L, 1L, 27L + +#define SN_id_aes192_wrap_pad "id-aes192-wrap-pad" +#define NID_id_aes192_wrap_pad 900 +#define OBJ_id_aes192_wrap_pad 2L, 16L, 840L, 1L, 101L, 3L, 4L, 1L, 28L + +#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 2L, 16L, 840L, 1L, 101L, 3L, 4L, 1L, 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 2L, 16L, 840L, 1L, 101L, 3L, 4L, 1L, 47L + +#define SN_id_aes256_wrap_pad "id-aes256-wrap-pad" +#define NID_id_aes256_wrap_pad 903 +#define OBJ_id_aes256_wrap_pad 2L, 16L, 840L, 1L, 101L, 3L, 4L, 1L, 48L + +#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_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 SN_anyExtendedKeyUsage "anyExtendedKeyUsage" +#define LN_anyExtendedKeyUsage "Any Extended Key Usage" +#define NID_anyExtendedKeyUsage 910 +#define OBJ_anyExtendedKeyUsage 2L, 5L, 29L, 37L, 0L + +#define SN_mgf1 "MGF1" +#define LN_mgf1 "mgf1" +#define NID_mgf1 911 +#define OBJ_mgf1 1L, 2L, 840L, 113549L, 1L, 1L, 8L + +#define SN_rsassaPss "RSASSA-PSS" +#define LN_rsassaPss "rsassaPss" +#define NID_rsassaPss 912 +#define OBJ_rsassaPss 1L, 2L, 840L, 113549L, 1L, 1L, 10L + +#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_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_rsaesOaep "RSAES-OAEP" +#define LN_rsaesOaep "rsaesOaep" +#define NID_rsaesOaep 919 +#define OBJ_rsaesOaep 1L, 2L, 840L, 113549L, 1L, 1L, 7L + +#define SN_dhpublicnumber "dhpublicnumber" +#define LN_dhpublicnumber "X9.42 DH" +#define NID_dhpublicnumber 920 +#define OBJ_dhpublicnumber 1L, 2L, 840L, 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 SN_pSpecified "PSPECIFIED" +#define LN_pSpecified "pSpecified" +#define NID_pSpecified 935 +#define OBJ_pSpecified 1L, 2L, 840L, 113549L, 1L, 1L, 9L + +#define SN_dhSinglePass_stdDH_sha1kdf_scheme "dhSinglePass-stdDH-sha1kdf-scheme" +#define NID_dhSinglePass_stdDH_sha1kdf_scheme 936 +#define OBJ_dhSinglePass_stdDH_sha1kdf_scheme \ + 1L, 3L, 133L, 16L, 840L, 63L, 0L, 2L + +#define SN_dhSinglePass_stdDH_sha224kdf_scheme \ + "dhSinglePass-stdDH-sha224kdf-scheme" +#define NID_dhSinglePass_stdDH_sha224kdf_scheme 937 +#define OBJ_dhSinglePass_stdDH_sha224kdf_scheme 1L, 3L, 132L, 1L, 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 1L, 3L, 132L, 1L, 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 1L, 3L, 132L, 1L, 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 1L, 3L, 132L, 1L, 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 \ + 1L, 3L, 133L, 16L, 840L, 63L, 0L, 3L + +#define SN_dhSinglePass_cofactorDH_sha224kdf_scheme \ + "dhSinglePass-cofactorDH-sha224kdf-scheme" +#define NID_dhSinglePass_cofactorDH_sha224kdf_scheme 942 +#define OBJ_dhSinglePass_cofactorDH_sha224kdf_scheme 1L, 3L, 132L, 1L, 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 1L, 3L, 132L, 1L, 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 1L, 3L, 132L, 1L, 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 1L, 3L, 132L, 1L, 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_X25519 "X25519" +#define NID_X25519 948 + +#define SN_ED25519 "ED25519" +#define NID_ED25519 949 +#define OBJ_ED25519 1L, 3L, 101L, 112L + +#define SN_chacha20_poly1305 "ChaCha20-Poly1305" +#define LN_chacha20_poly1305 "chacha20-poly1305" +#define NID_chacha20_poly1305 950 + +#define SN_kx_rsa "KxRSA" +#define LN_kx_rsa "kx-rsa" +#define NID_kx_rsa 951 + +#define SN_kx_ecdhe "KxECDHE" +#define LN_kx_ecdhe "kx-ecdhe" +#define NID_kx_ecdhe 952 + +#define SN_kx_psk "KxPSK" +#define LN_kx_psk "kx-psk" +#define NID_kx_psk 953 + +#define SN_auth_rsa "AuthRSA" +#define LN_auth_rsa "auth-rsa" +#define NID_auth_rsa 954 + +#define SN_auth_ecdsa "AuthECDSA" +#define LN_auth_ecdsa "auth-ecdsa" +#define NID_auth_ecdsa 955 + +#define SN_auth_psk "AuthPSK" +#define LN_auth_psk "auth-psk" +#define NID_auth_psk 956 + +#define SN_kx_any "KxANY" +#define LN_kx_any "kx-any" +#define NID_kx_any 957 + +#define SN_auth_any "AuthANY" +#define LN_auth_any "auth-any" +#define NID_auth_any 958 + + +#if defined(__cplusplus) +} /* extern C */ +#endif + +#endif /* OPENSSL_HEADER_NID_H */ diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/obj.h b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/obj.h new file mode 100644 index 0000000..572a21a --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/obj.h @@ -0,0 +1,233 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 OPENSSL_HEADER_OBJ_H +#define OPENSSL_HEADER_OBJ_H + +#include + +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// The objects library deals with the registration and indexing of ASN.1 object +// identifiers. These values are often written as a dotted sequence of numbers, +// e.g. 1.2.840.113549.1.9.16.3.9. +// +// Internally, OpenSSL likes to deal with these values by numbering them with +// numbers called "nids". OpenSSL has a large, built-in database of common +// object identifiers and also has both short and long names for them. +// +// This library provides functions for translating between object identifiers, +// nids, short names and long names. +// +// The nid values should not be used outside of a single process: they are not +// stable identifiers. + + +// Basic operations. + +// OBJ_dup returns a duplicate copy of |obj| or NULL on allocation failure. +OPENSSL_EXPORT ASN1_OBJECT *OBJ_dup(const ASN1_OBJECT *obj); + +// OBJ_cmp returns a value less than, equal to or greater than zero if |a| is +// less than, equal to or greater than |b|, respectively. +OPENSSL_EXPORT int OBJ_cmp(const ASN1_OBJECT *a, const ASN1_OBJECT *b); + +// OBJ_get0_data returns a pointer to the DER representation of |obj|. +OPENSSL_EXPORT const uint8_t *OBJ_get0_data(const ASN1_OBJECT *obj); + +// OBJ_length returns the length of the DER representation of |obj|. +OPENSSL_EXPORT size_t OBJ_length(const ASN1_OBJECT *obj); + + +// Looking up nids. + +// OBJ_obj2nid returns the nid corresponding to |obj|, or |NID_undef| if no +// such object is known. +OPENSSL_EXPORT int OBJ_obj2nid(const ASN1_OBJECT *obj); + +// OBJ_cbs2nid returns the nid corresponding to the DER data in |cbs|, or +// |NID_undef| if no such object is known. +OPENSSL_EXPORT int OBJ_cbs2nid(const CBS *cbs); + +// OBJ_sn2nid returns the nid corresponding to |short_name|, or |NID_undef| if +// no such short name is known. +OPENSSL_EXPORT int OBJ_sn2nid(const char *short_name); + +// OBJ_ln2nid returns the nid corresponding to |long_name|, or |NID_undef| if +// no such long name is known. +OPENSSL_EXPORT int OBJ_ln2nid(const char *long_name); + +// OBJ_txt2nid returns the nid corresponding to |s|, which may be a short name, +// long name, or an ASCII string containing a dotted sequence of numbers. It +// returns the nid or NID_undef if unknown. +OPENSSL_EXPORT int OBJ_txt2nid(const char *s); + + +// Getting information about nids. + +// OBJ_nid2obj returns the ASN1_OBJECT corresponding to |nid|, or NULL if |nid| +// is unknown. +OPENSSL_EXPORT const ASN1_OBJECT *OBJ_nid2obj(int nid); + +// OBJ_nid2sn returns the short name for |nid|, or NULL if |nid| is unknown. +OPENSSL_EXPORT const char *OBJ_nid2sn(int nid); + +// OBJ_nid2ln returns the long name for |nid|, or NULL if |nid| is unknown. +OPENSSL_EXPORT const char *OBJ_nid2ln(int nid); + +// OBJ_nid2cbb writes |nid| as an ASN.1 OBJECT IDENTIFIER to |out|. It returns +// one on success or zero otherwise. +OPENSSL_EXPORT int OBJ_nid2cbb(CBB *out, int nid); + + +// Dealing with textual representations of object identifiers. + +// OBJ_txt2obj returns an ASN1_OBJECT for the textual representation in |s|. +// If |dont_search_names| is zero, then |s| will be matched against the long +// and short names of a known objects to find a match. Otherwise |s| must +// contain an ASCII string with a dotted sequence of numbers. The resulting +// object need not be previously known. It returns a freshly allocated +// |ASN1_OBJECT| or NULL on error. +OPENSSL_EXPORT ASN1_OBJECT *OBJ_txt2obj(const char *s, int dont_search_names); + +// OBJ_obj2txt converts |obj| to a textual representation. If +// |always_return_oid| is zero then |obj| will be matched against known objects +// and the long (preferably) or short name will be used if found. Otherwise +// |obj| will be converted into a dotted sequence of integers. If |out| is not +// NULL, then at most |out_len| bytes of the textual form will be written +// there. If |out_len| is at least one, then string written to |out| will +// always be NUL terminated. It returns the number of characters that could +// have been written, not including the final NUL, or -1 on error. +OPENSSL_EXPORT int OBJ_obj2txt(char *out, int out_len, const ASN1_OBJECT *obj, + int always_return_oid); + + +// Adding objects at runtime. + +// OBJ_create adds a known object and returns the nid of the new object, or +// NID_undef on error. +OPENSSL_EXPORT int OBJ_create(const char *oid, const char *short_name, + const char *long_name); + + +// Handling signature algorithm identifiers. +// +// Some NIDs (e.g. sha256WithRSAEncryption) specify both a digest algorithm and +// a public key algorithm. The following functions map between pairs of digest +// and public-key algorithms and the NIDs that specify their combination. +// +// Sometimes the combination NID leaves the digest unspecified (e.g. +// rsassaPss). In these cases, the digest NID is |NID_undef|. + +// OBJ_find_sigid_algs finds the digest and public-key NIDs that correspond to +// the signing algorithm |sign_nid|. If successful, it sets |*out_digest_nid| +// and |*out_pkey_nid| and returns one. Otherwise it returns zero. Any of +// |out_digest_nid| or |out_pkey_nid| can be NULL if the caller doesn't need +// that output value. +OPENSSL_EXPORT int OBJ_find_sigid_algs(int sign_nid, int *out_digest_nid, + int *out_pkey_nid); + +// OBJ_find_sigid_by_algs finds the signature NID that corresponds to the +// combination of |digest_nid| and |pkey_nid|. If success, it sets +// |*out_sign_nid| and returns one. Otherwise it returns zero. The +// |out_sign_nid| argument can be NULL if the caller only wishes to learn +// whether the combination is valid. +OPENSSL_EXPORT int OBJ_find_sigid_by_algs(int *out_sign_nid, int digest_nid, + int pkey_nid); + + +// Deprecated functions. + +typedef struct obj_name_st { + int type; + int alias; + const char *name; + const char *data; +} OBJ_NAME; + +#define OBJ_NAME_TYPE_MD_METH 1 +#define OBJ_NAME_TYPE_CIPHER_METH 2 + +// OBJ_NAME_do_all_sorted calls |callback| zero or more times, each time with +// the name of a different primitive. If |type| is |OBJ_NAME_TYPE_MD_METH| then +// the primitives will be hash functions, alternatively if |type| is +// |OBJ_NAME_TYPE_CIPHER_METH| then the primitives will be ciphers or cipher +// modes. +// +// This function is ill-specified and should never be used. +OPENSSL_EXPORT void OBJ_NAME_do_all_sorted( + int type, void (*callback)(const OBJ_NAME *, void *arg), void *arg); + +// OBJ_NAME_do_all calls |OBJ_NAME_do_all_sorted|. +OPENSSL_EXPORT void OBJ_NAME_do_all(int type, void (*callback)(const OBJ_NAME *, + void *arg), + void *arg); + + +#if defined(__cplusplus) +} // extern C +#endif + +#define OBJ_R_UNKNOWN_NID 100 +#define OBJ_R_INVALID_OID_STRING 101 + +#endif // OPENSSL_HEADER_OBJ_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/obj.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/obj.h.grpc_back new file mode 100644 index 0000000..374658e --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/obj.h.grpc_back @@ -0,0 +1,233 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 OPENSSL_HEADER_OBJ_H +#define OPENSSL_HEADER_OBJ_H + +#include + +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// The objects library deals with the registration and indexing of ASN.1 object +// identifiers. These values are often written as a dotted sequence of numbers, +// e.g. 1.2.840.113549.1.9.16.3.9. +// +// Internally, OpenSSL likes to deal with these values by numbering them with +// numbers called "nids". OpenSSL has a large, built-in database of common +// object identifiers and also has both short and long names for them. +// +// This library provides functions for translating between object identifiers, +// nids, short names and long names. +// +// The nid values should not be used outside of a single process: they are not +// stable identifiers. + + +// Basic operations. + +// OBJ_dup returns a duplicate copy of |obj| or NULL on allocation failure. +OPENSSL_EXPORT ASN1_OBJECT *OBJ_dup(const ASN1_OBJECT *obj); + +// OBJ_cmp returns a value less than, equal to or greater than zero if |a| is +// less than, equal to or greater than |b|, respectively. +OPENSSL_EXPORT int OBJ_cmp(const ASN1_OBJECT *a, const ASN1_OBJECT *b); + +// OBJ_get0_data returns a pointer to the DER representation of |obj|. +OPENSSL_EXPORT const uint8_t *OBJ_get0_data(const ASN1_OBJECT *obj); + +// OBJ_length returns the length of the DER representation of |obj|. +OPENSSL_EXPORT size_t OBJ_length(const ASN1_OBJECT *obj); + + +// Looking up nids. + +// OBJ_obj2nid returns the nid corresponding to |obj|, or |NID_undef| if no +// such object is known. +OPENSSL_EXPORT int OBJ_obj2nid(const ASN1_OBJECT *obj); + +// OBJ_cbs2nid returns the nid corresponding to the DER data in |cbs|, or +// |NID_undef| if no such object is known. +OPENSSL_EXPORT int OBJ_cbs2nid(const CBS *cbs); + +// OBJ_sn2nid returns the nid corresponding to |short_name|, or |NID_undef| if +// no such short name is known. +OPENSSL_EXPORT int OBJ_sn2nid(const char *short_name); + +// OBJ_ln2nid returns the nid corresponding to |long_name|, or |NID_undef| if +// no such long name is known. +OPENSSL_EXPORT int OBJ_ln2nid(const char *long_name); + +// OBJ_txt2nid returns the nid corresponding to |s|, which may be a short name, +// long name, or an ASCII string containing a dotted sequence of numbers. It +// returns the nid or NID_undef if unknown. +OPENSSL_EXPORT int OBJ_txt2nid(const char *s); + + +// Getting information about nids. + +// OBJ_nid2obj returns the ASN1_OBJECT corresponding to |nid|, or NULL if |nid| +// is unknown. +OPENSSL_EXPORT const ASN1_OBJECT *OBJ_nid2obj(int nid); + +// OBJ_nid2sn returns the short name for |nid|, or NULL if |nid| is unknown. +OPENSSL_EXPORT const char *OBJ_nid2sn(int nid); + +// OBJ_nid2ln returns the long name for |nid|, or NULL if |nid| is unknown. +OPENSSL_EXPORT const char *OBJ_nid2ln(int nid); + +// OBJ_nid2cbb writes |nid| as an ASN.1 OBJECT IDENTIFIER to |out|. It returns +// one on success or zero otherwise. +OPENSSL_EXPORT int OBJ_nid2cbb(CBB *out, int nid); + + +// Dealing with textual representations of object identifiers. + +// OBJ_txt2obj returns an ASN1_OBJECT for the textual representation in |s|. +// If |dont_search_names| is zero, then |s| will be matched against the long +// and short names of a known objects to find a match. Otherwise |s| must +// contain an ASCII string with a dotted sequence of numbers. The resulting +// object need not be previously known. It returns a freshly allocated +// |ASN1_OBJECT| or NULL on error. +OPENSSL_EXPORT ASN1_OBJECT *OBJ_txt2obj(const char *s, int dont_search_names); + +// OBJ_obj2txt converts |obj| to a textual representation. If +// |always_return_oid| is zero then |obj| will be matched against known objects +// and the long (preferably) or short name will be used if found. Otherwise +// |obj| will be converted into a dotted sequence of integers. If |out| is not +// NULL, then at most |out_len| bytes of the textual form will be written +// there. If |out_len| is at least one, then string written to |out| will +// always be NUL terminated. It returns the number of characters that could +// have been written, not including the final NUL, or -1 on error. +OPENSSL_EXPORT int OBJ_obj2txt(char *out, int out_len, const ASN1_OBJECT *obj, + int always_return_oid); + + +// Adding objects at runtime. + +// OBJ_create adds a known object and returns the nid of the new object, or +// NID_undef on error. +OPENSSL_EXPORT int OBJ_create(const char *oid, const char *short_name, + const char *long_name); + + +// Handling signature algorithm identifiers. +// +// Some NIDs (e.g. sha256WithRSAEncryption) specify both a digest algorithm and +// a public key algorithm. The following functions map between pairs of digest +// and public-key algorithms and the NIDs that specify their combination. +// +// Sometimes the combination NID leaves the digest unspecified (e.g. +// rsassaPss). In these cases, the digest NID is |NID_undef|. + +// OBJ_find_sigid_algs finds the digest and public-key NIDs that correspond to +// the signing algorithm |sign_nid|. If successful, it sets |*out_digest_nid| +// and |*out_pkey_nid| and returns one. Otherwise it returns zero. Any of +// |out_digest_nid| or |out_pkey_nid| can be NULL if the caller doesn't need +// that output value. +OPENSSL_EXPORT int OBJ_find_sigid_algs(int sign_nid, int *out_digest_nid, + int *out_pkey_nid); + +// OBJ_find_sigid_by_algs finds the signature NID that corresponds to the +// combination of |digest_nid| and |pkey_nid|. If success, it sets +// |*out_sign_nid| and returns one. Otherwise it returns zero. The +// |out_sign_nid| argument can be NULL if the caller only wishes to learn +// whether the combination is valid. +OPENSSL_EXPORT int OBJ_find_sigid_by_algs(int *out_sign_nid, int digest_nid, + int pkey_nid); + + +// Deprecated functions. + +typedef struct obj_name_st { + int type; + int alias; + const char *name; + const char *data; +} OBJ_NAME; + +#define OBJ_NAME_TYPE_MD_METH 1 +#define OBJ_NAME_TYPE_CIPHER_METH 2 + +// OBJ_NAME_do_all_sorted calls |callback| zero or more times, each time with +// the name of a different primitive. If |type| is |OBJ_NAME_TYPE_MD_METH| then +// the primitives will be hash functions, alternatively if |type| is +// |OBJ_NAME_TYPE_CIPHER_METH| then the primitives will be ciphers or cipher +// modes. +// +// This function is ill-specified and should never be used. +OPENSSL_EXPORT void OBJ_NAME_do_all_sorted( + int type, void (*callback)(const OBJ_NAME *, void *arg), void *arg); + +// OBJ_NAME_do_all calls |OBJ_NAME_do_all_sorted|. +OPENSSL_EXPORT void OBJ_NAME_do_all(int type, void (*callback)(const OBJ_NAME *, + void *arg), + void *arg); + + +#if defined(__cplusplus) +} // extern C +#endif + +#define OBJ_R_UNKNOWN_NID 100 +#define OBJ_R_INVALID_OID_STRING 101 + +#endif // OPENSSL_HEADER_OBJ_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/obj_mac.h b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/obj_mac.h new file mode 100644 index 0000000..e7ccadc --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/obj_mac.h @@ -0,0 +1,18 @@ +/* Copyright (c) 2016, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +/* This header is provided in order to make compiling against code that expects + OpenSSL easier. */ + +#include "nid.h" diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/obj_mac.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/obj_mac.h.grpc_back new file mode 100644 index 0000000..e7ccadc --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/obj_mac.h.grpc_back @@ -0,0 +1,18 @@ +/* Copyright (c) 2016, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +/* This header is provided in order to make compiling against code that expects + OpenSSL easier. */ + +#include "nid.h" diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/objects.h b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/objects.h new file mode 100644 index 0000000..dd6556f --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/objects.h @@ -0,0 +1,18 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +/* This header is provided in order to make compiling against code that expects + OpenSSL easier. */ + +#include "obj.h" diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/objects.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/objects.h.grpc_back new file mode 100644 index 0000000..dd6556f --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/objects.h.grpc_back @@ -0,0 +1,18 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +/* This header is provided in order to make compiling against code that expects + OpenSSL easier. */ + +#include "obj.h" diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/opensslconf.h b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/opensslconf.h new file mode 100644 index 0000000..3c6ffd8 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/opensslconf.h @@ -0,0 +1,67 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +/* This header is provided in order to make compiling against code that expects + OpenSSL easier. */ + +#ifndef OPENSSL_HEADER_OPENSSLCONF_H +#define OPENSSL_HEADER_OPENSSLCONF_H + + +#define OPENSSL_NO_ASYNC +#define OPENSSL_NO_BF +#define OPENSSL_NO_BLAKE2 +#define OPENSSL_NO_BUF_FREELISTS +#define OPENSSL_NO_CAMELLIA +#define OPENSSL_NO_CAPIENG +#define OPENSSL_NO_CAST +#define OPENSSL_NO_CMS +#define OPENSSL_NO_COMP +#define OPENSSL_NO_CT +#define OPENSSL_NO_DANE +#define OPENSSL_NO_DEPRECATED +#define OPENSSL_NO_DGRAM +#define OPENSSL_NO_DYNAMIC_ENGINE +#define OPENSSL_NO_EC_NISTP_64_GCC_128 +#define OPENSSL_NO_EC2M +#define OPENSSL_NO_EGD +#define OPENSSL_NO_ENGINE +#define OPENSSL_NO_GMP +#define OPENSSL_NO_GOST +#define OPENSSL_NO_HEARTBEATS +#define OPENSSL_NO_HW +#define OPENSSL_NO_IDEA +#define OPENSSL_NO_JPAKE +#define OPENSSL_NO_KRB5 +#define OPENSSL_NO_MD2 +#define OPENSSL_NO_MDC2 +#define OPENSSL_NO_OCB +#define OPENSSL_NO_OCSP +#define OPENSSL_NO_RC2 +#define OPENSSL_NO_RC5 +#define OPENSSL_NO_RFC3779 +#define OPENSSL_NO_RIPEMD +#define OPENSSL_NO_RMD160 +#define OPENSSL_NO_SCTP +#define OPENSSL_NO_SEED +#define OPENSSL_NO_SRP +#define OPENSSL_NO_SSL2 +#define OPENSSL_NO_SSL3 +#define OPENSSL_NO_SSL3_METHOD +#define OPENSSL_NO_STATIC_ENGINE +#define OPENSSL_NO_STORE +#define OPENSSL_NO_WHIRLPOOL + + +#endif // OPENSSL_HEADER_OPENSSLCONF_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/opensslconf.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/opensslconf.h.grpc_back new file mode 100644 index 0000000..3c6ffd8 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/opensslconf.h.grpc_back @@ -0,0 +1,67 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +/* This header is provided in order to make compiling against code that expects + OpenSSL easier. */ + +#ifndef OPENSSL_HEADER_OPENSSLCONF_H +#define OPENSSL_HEADER_OPENSSLCONF_H + + +#define OPENSSL_NO_ASYNC +#define OPENSSL_NO_BF +#define OPENSSL_NO_BLAKE2 +#define OPENSSL_NO_BUF_FREELISTS +#define OPENSSL_NO_CAMELLIA +#define OPENSSL_NO_CAPIENG +#define OPENSSL_NO_CAST +#define OPENSSL_NO_CMS +#define OPENSSL_NO_COMP +#define OPENSSL_NO_CT +#define OPENSSL_NO_DANE +#define OPENSSL_NO_DEPRECATED +#define OPENSSL_NO_DGRAM +#define OPENSSL_NO_DYNAMIC_ENGINE +#define OPENSSL_NO_EC_NISTP_64_GCC_128 +#define OPENSSL_NO_EC2M +#define OPENSSL_NO_EGD +#define OPENSSL_NO_ENGINE +#define OPENSSL_NO_GMP +#define OPENSSL_NO_GOST +#define OPENSSL_NO_HEARTBEATS +#define OPENSSL_NO_HW +#define OPENSSL_NO_IDEA +#define OPENSSL_NO_JPAKE +#define OPENSSL_NO_KRB5 +#define OPENSSL_NO_MD2 +#define OPENSSL_NO_MDC2 +#define OPENSSL_NO_OCB +#define OPENSSL_NO_OCSP +#define OPENSSL_NO_RC2 +#define OPENSSL_NO_RC5 +#define OPENSSL_NO_RFC3779 +#define OPENSSL_NO_RIPEMD +#define OPENSSL_NO_RMD160 +#define OPENSSL_NO_SCTP +#define OPENSSL_NO_SEED +#define OPENSSL_NO_SRP +#define OPENSSL_NO_SSL2 +#define OPENSSL_NO_SSL3 +#define OPENSSL_NO_SSL3_METHOD +#define OPENSSL_NO_STATIC_ENGINE +#define OPENSSL_NO_STORE +#define OPENSSL_NO_WHIRLPOOL + + +#endif // OPENSSL_HEADER_OPENSSLCONF_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/opensslv.h b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/opensslv.h new file mode 100644 index 0000000..a3555d4 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/opensslv.h @@ -0,0 +1,18 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +/* This header is provided in order to make compiling against code that expects + OpenSSL easier. */ + +#include "crypto.h" diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/opensslv.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/opensslv.h.grpc_back new file mode 100644 index 0000000..a3555d4 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/opensslv.h.grpc_back @@ -0,0 +1,18 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +/* This header is provided in order to make compiling against code that expects + OpenSSL easier. */ + +#include "crypto.h" diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/ossl_typ.h b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/ossl_typ.h new file mode 100644 index 0000000..c2b3fe7 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/ossl_typ.h @@ -0,0 +1,18 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +/* This header is provided in order to make compiling against code that expects + OpenSSL easier. */ + +#include "base.h" diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/ossl_typ.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/ossl_typ.h.grpc_back new file mode 100644 index 0000000..c2b3fe7 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/ossl_typ.h.grpc_back @@ -0,0 +1,18 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +/* This header is provided in order to make compiling against code that expects + OpenSSL easier. */ + +#include "base.h" diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/pem.h b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/pem.h new file mode 100644 index 0000000..8d2a388 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/pem.h @@ -0,0 +1,397 @@ +/* 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 OPENSSL_HEADER_PEM_H +#define OPENSSL_HEADER_PEM_H + +#include +#include +#include +#include +#include +#include +#include + +/* For compatibility with open-iscsi, which assumes that it can get + * |OPENSSL_malloc| from pem.h or err.h */ +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +#define PEM_BUFSIZE 1024 + +#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_EC "EC PRIVATE 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_SSL_SESSION "SSL SESSION PARAMETERS" +#define PEM_STRING_DSAPARAMS "DSA PARAMETERS" +#define PEM_STRING_ECDSA_PUBLIC "ECDSA PUBLIC KEY" +#define PEM_STRING_ECPRIVATEKEY "EC PRIVATE KEY" +#define PEM_STRING_CMS "CMS" + +/* 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 + +/* 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) \ +OPENSSL_EXPORT type *PEM_read_##name(FILE *fp, type **x, pem_password_cb *cb, void *u)\ +{ \ +return (type *)PEM_ASN1_read((d2i_of_void *)d2i_##asn1, str,fp,(void **)x,cb,u); \ +} + +#define IMPLEMENT_PEM_write_fp(name, type, str, asn1) \ +OPENSSL_EXPORT 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) \ +OPENSSL_EXPORT 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) \ +OPENSSL_EXPORT 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) \ +OPENSSL_EXPORT 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) \ +OPENSSL_EXPORT type *PEM_read_bio_##name(BIO *bp, type **x, pem_password_cb *cb, void *u)\ +{ \ +return (type *)PEM_ASN1_read_bio((d2i_of_void *)d2i_##asn1, str,bp,(void **)x,cb,u); \ +} + +#define IMPLEMENT_PEM_write_bio(name, type, str, asn1) \ +OPENSSL_EXPORT 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) \ +OPENSSL_EXPORT 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) \ +OPENSSL_EXPORT 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) \ +OPENSSL_EXPORT 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) \ + OPENSSL_EXPORT type *PEM_read_##name(FILE *fp, type **x, pem_password_cb *cb, void *u); + +#define DECLARE_PEM_write_fp(name, type) \ + OPENSSL_EXPORT int PEM_write_##name(FILE *fp, type *x); + +#define DECLARE_PEM_write_fp_const(name, type) \ + OPENSSL_EXPORT int PEM_write_##name(FILE *fp, const type *x); + +#define DECLARE_PEM_write_cb_fp(name, type) \ + OPENSSL_EXPORT int PEM_write_##name(FILE *fp, type *x, const EVP_CIPHER *enc, \ + unsigned char *kstr, int klen, pem_password_cb *cb, void *u); + +#endif + +#define DECLARE_PEM_read_bio(name, type) \ + OPENSSL_EXPORT type *PEM_read_bio_##name(BIO *bp, type **x, pem_password_cb *cb, void *u); + +#define DECLARE_PEM_write_bio(name, type) \ + OPENSSL_EXPORT int PEM_write_bio_##name(BIO *bp, type *x); + +#define DECLARE_PEM_write_bio_const(name, type) \ + OPENSSL_EXPORT int PEM_write_bio_##name(BIO *bp, const type *x); + +#define DECLARE_PEM_write_cb_bio(name, type) \ + OPENSSL_EXPORT int PEM_write_bio_##name(BIO *bp, type *x, const EVP_CIPHER *enc, \ + unsigned char *kstr, int klen, pem_password_cb *cb, void *u); + + +#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) + +/* "userdata": new with OpenSSL 0.9.4 */ +typedef int pem_password_cb(char *buf, int size, int rwflag, void *userdata); + +OPENSSL_EXPORT int PEM_get_EVP_CIPHER_INFO(char *header, EVP_CIPHER_INFO *cipher); +OPENSSL_EXPORT int PEM_do_header (EVP_CIPHER_INFO *cipher, unsigned char *data,long *len, pem_password_cb *callback,void *u); + +OPENSSL_EXPORT int PEM_read_bio(BIO *bp, char **name, char **header, unsigned char **data,long *len); +OPENSSL_EXPORT int PEM_write_bio(BIO *bp,const char *name, const char *hdr, const unsigned char *data, long len); +OPENSSL_EXPORT int PEM_bytes_read_bio(unsigned char **pdata, long *plen, char **pnm, const char *name, BIO *bp, pem_password_cb *cb, void *u); +OPENSSL_EXPORT void * PEM_ASN1_read_bio(d2i_of_void *d2i, const char *name, BIO *bp, void **x, pem_password_cb *cb, void *u); +OPENSSL_EXPORT 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); + +OPENSSL_EXPORT STACK_OF(X509_INFO) * PEM_X509_INFO_read_bio(BIO *bp, STACK_OF(X509_INFO) *sk, pem_password_cb *cb, void *u); +OPENSSL_EXPORT 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); + +OPENSSL_EXPORT int PEM_read(FILE *fp, char **name, char **header, unsigned char **data,long *len); +OPENSSL_EXPORT int PEM_write(FILE *fp, const char *name, const char *hdr, const unsigned char *data, long len); +OPENSSL_EXPORT void * PEM_ASN1_read(d2i_of_void *d2i, const char *name, FILE *fp, void **x, pem_password_cb *cb, void *u); +OPENSSL_EXPORT 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); +OPENSSL_EXPORT STACK_OF(X509_INFO) * PEM_X509_INFO_read(FILE *fp, STACK_OF(X509_INFO) *sk, pem_password_cb *cb, void *u); + +/* PEM_def_callback treats |userdata| as a string and copies it into |buf|, + * assuming its |size| is sufficient. Returns the length of the string, or 0 + * if there is not enough room. If either |buf| or |userdata| is NULL, 0 is + * returned. Note that this is different from OpenSSL, which prompts for a + * password. */ +OPENSSL_EXPORT int PEM_def_callback(char *buf, int size, int rwflag, void *userdata); +OPENSSL_EXPORT void PEM_proc_type(char *buf, int type); +OPENSSL_EXPORT void PEM_dek_info(char *buf, const char *type, int len, char *str); + + +DECLARE_PEM_rw(X509, X509) + +DECLARE_PEM_rw(X509_AUX, X509) + +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(PKCS8, X509_SIG) + +DECLARE_PEM_rw(PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO) + +DECLARE_PEM_rw_cb(RSAPrivateKey, RSA) + +DECLARE_PEM_rw_const(RSAPublicKey, RSA) +DECLARE_PEM_rw(RSA_PUBKEY, RSA) + +#ifndef OPENSSL_NO_DSA + +DECLARE_PEM_rw_cb(DSAPrivateKey, DSA) + +DECLARE_PEM_rw(DSA_PUBKEY, DSA) + +DECLARE_PEM_rw_const(DSAparams, DSA) + +#endif + +DECLARE_PEM_rw_cb(ECPrivateKey, EC_KEY) +DECLARE_PEM_rw(EC_PUBKEY, EC_KEY) + + +DECLARE_PEM_rw_const(DHparams, DH) + + +DECLARE_PEM_rw_cb(PrivateKey, EVP_PKEY) + +DECLARE_PEM_rw(PUBKEY, EVP_PKEY) + +OPENSSL_EXPORT int PEM_write_bio_PKCS8PrivateKey_nid(BIO *bp, EVP_PKEY *x, int nid, char *kstr, int klen, pem_password_cb *cb, void *u); +OPENSSL_EXPORT int PEM_write_bio_PKCS8PrivateKey(BIO *, EVP_PKEY *, const EVP_CIPHER *, char *, int, pem_password_cb *, void *); +OPENSSL_EXPORT int i2d_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc, char *kstr, int klen, pem_password_cb *cb, void *u); +OPENSSL_EXPORT int i2d_PKCS8PrivateKey_nid_bio(BIO *bp, EVP_PKEY *x, int nid, char *kstr, int klen, pem_password_cb *cb, void *u); +OPENSSL_EXPORT EVP_PKEY *d2i_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, void *u); + +OPENSSL_EXPORT int i2d_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc, char *kstr, int klen, pem_password_cb *cb, void *u); +OPENSSL_EXPORT int i2d_PKCS8PrivateKey_nid_fp(FILE *fp, EVP_PKEY *x, int nid, char *kstr, int klen, pem_password_cb *cb, void *u); +OPENSSL_EXPORT int PEM_write_PKCS8PrivateKey_nid(FILE *fp, EVP_PKEY *x, int nid, char *kstr, int klen, pem_password_cb *cb, void *u); + +OPENSSL_EXPORT EVP_PKEY *d2i_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY **x, pem_password_cb *cb, void *u); + +OPENSSL_EXPORT int PEM_write_PKCS8PrivateKey(FILE *fp,EVP_PKEY *x,const EVP_CIPHER *enc, char *kstr,int klen, pem_password_cb *cd, void *u); + + +#ifdef __cplusplus +} +#endif + +#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_PASSWORD_READ 104 +#define PEM_R_CIPHER_IS_NULL 105 +#define PEM_R_ERROR_CONVERTING_PRIVATE_KEY 106 +#define PEM_R_NOT_DEK_INFO 107 +#define PEM_R_NOT_ENCRYPTED 108 +#define PEM_R_NOT_PROC_TYPE 109 +#define PEM_R_NO_START_LINE 110 +#define PEM_R_READ_KEY 111 +#define PEM_R_SHORT_HEADER 112 +#define PEM_R_UNSUPPORTED_CIPHER 113 +#define PEM_R_UNSUPPORTED_ENCRYPTION 114 + +#endif /* OPENSSL_HEADER_PEM_H */ diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/pem.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/pem.h.grpc_back new file mode 100644 index 0000000..4868e12 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/pem.h.grpc_back @@ -0,0 +1,397 @@ +/* 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 OPENSSL_HEADER_PEM_H +#define OPENSSL_HEADER_PEM_H + +#include +#include +#include +#include +#include +#include +#include + +/* For compatibility with open-iscsi, which assumes that it can get + * |OPENSSL_malloc| from pem.h or err.h */ +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +#define PEM_BUFSIZE 1024 + +#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_EC "EC PRIVATE 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_SSL_SESSION "SSL SESSION PARAMETERS" +#define PEM_STRING_DSAPARAMS "DSA PARAMETERS" +#define PEM_STRING_ECDSA_PUBLIC "ECDSA PUBLIC KEY" +#define PEM_STRING_ECPRIVATEKEY "EC PRIVATE KEY" +#define PEM_STRING_CMS "CMS" + +/* 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 + +/* 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) \ +OPENSSL_EXPORT type *PEM_read_##name(FILE *fp, type **x, pem_password_cb *cb, void *u)\ +{ \ +return (type *)PEM_ASN1_read((d2i_of_void *)d2i_##asn1, str,fp,(void **)x,cb,u); \ +} + +#define IMPLEMENT_PEM_write_fp(name, type, str, asn1) \ +OPENSSL_EXPORT 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) \ +OPENSSL_EXPORT 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) \ +OPENSSL_EXPORT 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) \ +OPENSSL_EXPORT 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) \ +OPENSSL_EXPORT type *PEM_read_bio_##name(BIO *bp, type **x, pem_password_cb *cb, void *u)\ +{ \ +return (type *)PEM_ASN1_read_bio((d2i_of_void *)d2i_##asn1, str,bp,(void **)x,cb,u); \ +} + +#define IMPLEMENT_PEM_write_bio(name, type, str, asn1) \ +OPENSSL_EXPORT 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) \ +OPENSSL_EXPORT 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) \ +OPENSSL_EXPORT 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) \ +OPENSSL_EXPORT 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) \ + OPENSSL_EXPORT type *PEM_read_##name(FILE *fp, type **x, pem_password_cb *cb, void *u); + +#define DECLARE_PEM_write_fp(name, type) \ + OPENSSL_EXPORT int PEM_write_##name(FILE *fp, type *x); + +#define DECLARE_PEM_write_fp_const(name, type) \ + OPENSSL_EXPORT int PEM_write_##name(FILE *fp, const type *x); + +#define DECLARE_PEM_write_cb_fp(name, type) \ + OPENSSL_EXPORT int PEM_write_##name(FILE *fp, type *x, const EVP_CIPHER *enc, \ + unsigned char *kstr, int klen, pem_password_cb *cb, void *u); + +#endif + +#define DECLARE_PEM_read_bio(name, type) \ + OPENSSL_EXPORT type *PEM_read_bio_##name(BIO *bp, type **x, pem_password_cb *cb, void *u); + +#define DECLARE_PEM_write_bio(name, type) \ + OPENSSL_EXPORT int PEM_write_bio_##name(BIO *bp, type *x); + +#define DECLARE_PEM_write_bio_const(name, type) \ + OPENSSL_EXPORT int PEM_write_bio_##name(BIO *bp, const type *x); + +#define DECLARE_PEM_write_cb_bio(name, type) \ + OPENSSL_EXPORT int PEM_write_bio_##name(BIO *bp, type *x, const EVP_CIPHER *enc, \ + unsigned char *kstr, int klen, pem_password_cb *cb, void *u); + + +#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) + +/* "userdata": new with OpenSSL 0.9.4 */ +typedef int pem_password_cb(char *buf, int size, int rwflag, void *userdata); + +OPENSSL_EXPORT int PEM_get_EVP_CIPHER_INFO(char *header, EVP_CIPHER_INFO *cipher); +OPENSSL_EXPORT int PEM_do_header (EVP_CIPHER_INFO *cipher, unsigned char *data,long *len, pem_password_cb *callback,void *u); + +OPENSSL_EXPORT int PEM_read_bio(BIO *bp, char **name, char **header, unsigned char **data,long *len); +OPENSSL_EXPORT int PEM_write_bio(BIO *bp,const char *name, const char *hdr, const unsigned char *data, long len); +OPENSSL_EXPORT int PEM_bytes_read_bio(unsigned char **pdata, long *plen, char **pnm, const char *name, BIO *bp, pem_password_cb *cb, void *u); +OPENSSL_EXPORT void * PEM_ASN1_read_bio(d2i_of_void *d2i, const char *name, BIO *bp, void **x, pem_password_cb *cb, void *u); +OPENSSL_EXPORT 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); + +OPENSSL_EXPORT STACK_OF(X509_INFO) * PEM_X509_INFO_read_bio(BIO *bp, STACK_OF(X509_INFO) *sk, pem_password_cb *cb, void *u); +OPENSSL_EXPORT 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); + +OPENSSL_EXPORT int PEM_read(FILE *fp, char **name, char **header, unsigned char **data,long *len); +OPENSSL_EXPORT int PEM_write(FILE *fp, const char *name, const char *hdr, const unsigned char *data, long len); +OPENSSL_EXPORT void * PEM_ASN1_read(d2i_of_void *d2i, const char *name, FILE *fp, void **x, pem_password_cb *cb, void *u); +OPENSSL_EXPORT 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); +OPENSSL_EXPORT STACK_OF(X509_INFO) * PEM_X509_INFO_read(FILE *fp, STACK_OF(X509_INFO) *sk, pem_password_cb *cb, void *u); + +/* PEM_def_callback treats |userdata| as a string and copies it into |buf|, + * assuming its |size| is sufficient. Returns the length of the string, or 0 + * if there is not enough room. If either |buf| or |userdata| is NULL, 0 is + * returned. Note that this is different from OpenSSL, which prompts for a + * password. */ +OPENSSL_EXPORT int PEM_def_callback(char *buf, int size, int rwflag, void *userdata); +OPENSSL_EXPORT void PEM_proc_type(char *buf, int type); +OPENSSL_EXPORT void PEM_dek_info(char *buf, const char *type, int len, char *str); + + +DECLARE_PEM_rw(X509, X509) + +DECLARE_PEM_rw(X509_AUX, X509) + +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(PKCS8, X509_SIG) + +DECLARE_PEM_rw(PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO) + +DECLARE_PEM_rw_cb(RSAPrivateKey, RSA) + +DECLARE_PEM_rw_const(RSAPublicKey, RSA) +DECLARE_PEM_rw(RSA_PUBKEY, RSA) + +#ifndef OPENSSL_NO_DSA + +DECLARE_PEM_rw_cb(DSAPrivateKey, DSA) + +DECLARE_PEM_rw(DSA_PUBKEY, DSA) + +DECLARE_PEM_rw_const(DSAparams, DSA) + +#endif + +DECLARE_PEM_rw_cb(ECPrivateKey, EC_KEY) +DECLARE_PEM_rw(EC_PUBKEY, EC_KEY) + + +DECLARE_PEM_rw_const(DHparams, DH) + + +DECLARE_PEM_rw_cb(PrivateKey, EVP_PKEY) + +DECLARE_PEM_rw(PUBKEY, EVP_PKEY) + +OPENSSL_EXPORT int PEM_write_bio_PKCS8PrivateKey_nid(BIO *bp, EVP_PKEY *x, int nid, char *kstr, int klen, pem_password_cb *cb, void *u); +OPENSSL_EXPORT int PEM_write_bio_PKCS8PrivateKey(BIO *, EVP_PKEY *, const EVP_CIPHER *, char *, int, pem_password_cb *, void *); +OPENSSL_EXPORT int i2d_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY *x, const EVP_CIPHER *enc, char *kstr, int klen, pem_password_cb *cb, void *u); +OPENSSL_EXPORT int i2d_PKCS8PrivateKey_nid_bio(BIO *bp, EVP_PKEY *x, int nid, char *kstr, int klen, pem_password_cb *cb, void *u); +OPENSSL_EXPORT EVP_PKEY *d2i_PKCS8PrivateKey_bio(BIO *bp, EVP_PKEY **x, pem_password_cb *cb, void *u); + +OPENSSL_EXPORT int i2d_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY *x, const EVP_CIPHER *enc, char *kstr, int klen, pem_password_cb *cb, void *u); +OPENSSL_EXPORT int i2d_PKCS8PrivateKey_nid_fp(FILE *fp, EVP_PKEY *x, int nid, char *kstr, int klen, pem_password_cb *cb, void *u); +OPENSSL_EXPORT int PEM_write_PKCS8PrivateKey_nid(FILE *fp, EVP_PKEY *x, int nid, char *kstr, int klen, pem_password_cb *cb, void *u); + +OPENSSL_EXPORT EVP_PKEY *d2i_PKCS8PrivateKey_fp(FILE *fp, EVP_PKEY **x, pem_password_cb *cb, void *u); + +OPENSSL_EXPORT int PEM_write_PKCS8PrivateKey(FILE *fp,EVP_PKEY *x,const EVP_CIPHER *enc, char *kstr,int klen, pem_password_cb *cd, void *u); + + +#ifdef __cplusplus +} +#endif + +#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_PASSWORD_READ 104 +#define PEM_R_CIPHER_IS_NULL 105 +#define PEM_R_ERROR_CONVERTING_PRIVATE_KEY 106 +#define PEM_R_NOT_DEK_INFO 107 +#define PEM_R_NOT_ENCRYPTED 108 +#define PEM_R_NOT_PROC_TYPE 109 +#define PEM_R_NO_START_LINE 110 +#define PEM_R_READ_KEY 111 +#define PEM_R_SHORT_HEADER 112 +#define PEM_R_UNSUPPORTED_CIPHER 113 +#define PEM_R_UNSUPPORTED_ENCRYPTION 114 + +#endif /* OPENSSL_HEADER_PEM_H */ diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/pkcs12.h b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/pkcs12.h new file mode 100644 index 0000000..b5e9516 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/pkcs12.h @@ -0,0 +1,18 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +/* This header is provided in order to make compiling against code that expects + OpenSSL easier. */ + +#include "pkcs8.h" diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/pkcs12.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/pkcs12.h.grpc_back new file mode 100644 index 0000000..b5e9516 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/pkcs12.h.grpc_back @@ -0,0 +1,18 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +/* This header is provided in order to make compiling against code that expects + OpenSSL easier. */ + +#include "pkcs8.h" diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/pkcs7.h b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/pkcs7.h new file mode 100644 index 0000000..1a04d38 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/pkcs7.h @@ -0,0 +1,82 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_PKCS7_H +#define OPENSSL_HEADER_PKCS7_H + +#include + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// PKCS#7. +// +// This library contains functions for extracting information from PKCS#7 +// structures (RFC 2315). + +DECLARE_STACK_OF(CRYPTO_BUFFER) +DECLARE_STACK_OF(X509) +DECLARE_STACK_OF(X509_CRL) + +// PKCS7_get_raw_certificates parses a PKCS#7, SignedData structure from |cbs| +// and appends the included certificates to |out_certs|. It returns one on +// success and zero on error. +OPENSSL_EXPORT int PKCS7_get_raw_certificates( + STACK_OF(CRYPTO_BUFFER) *out_certs, CBS *cbs, CRYPTO_BUFFER_POOL *pool); + +// PKCS7_get_certificates behaves like |PKCS7_get_raw_certificates| but parses +// them into |X509| objects. +OPENSSL_EXPORT int PKCS7_get_certificates(STACK_OF(X509) *out_certs, CBS *cbs); + +// PKCS7_bundle_certificates appends a PKCS#7, SignedData structure containing +// |certs| to |out|. It returns one on success and zero on error. +OPENSSL_EXPORT int PKCS7_bundle_certificates( + CBB *out, const STACK_OF(X509) *certs); + +// PKCS7_get_CRLs parses a PKCS#7, SignedData structure from |cbs| and appends +// the included CRLs to |out_crls|. It returns one on success and zero on +// error. +OPENSSL_EXPORT int PKCS7_get_CRLs(STACK_OF(X509_CRL) *out_crls, CBS *cbs); + +// PKCS7_bundle_CRLs appends a PKCS#7, SignedData structure containing +// |crls| to |out|. It returns one on success and zero on error. +OPENSSL_EXPORT int PKCS7_bundle_CRLs(CBB *out, const STACK_OF(X509_CRL) *crls); + +// PKCS7_get_PEM_certificates reads a PEM-encoded, PKCS#7, SignedData structure +// from |pem_bio| and appends the included certificates to |out_certs|. It +// returns one on success and zero on error. +OPENSSL_EXPORT int PKCS7_get_PEM_certificates(STACK_OF(X509) *out_certs, + BIO *pem_bio); + +// PKCS7_get_PEM_CRLs reads a PEM-encoded, PKCS#7, SignedData structure from +// |pem_bio| and appends the included CRLs to |out_crls|. It returns one on +// success and zero on error. +OPENSSL_EXPORT int PKCS7_get_PEM_CRLs(STACK_OF(X509_CRL) *out_crls, + BIO *pem_bio); + + +#if defined(__cplusplus) +} // extern C +#endif + +#define PKCS7_R_BAD_PKCS7_VERSION 100 +#define PKCS7_R_NOT_PKCS7_SIGNED_DATA 101 +#define PKCS7_R_NO_CERTIFICATES_INCLUDED 102 +#define PKCS7_R_NO_CRLS_INCLUDED 103 + +#endif // OPENSSL_HEADER_PKCS7_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/pkcs7.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/pkcs7.h.grpc_back new file mode 100644 index 0000000..d708141 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/pkcs7.h.grpc_back @@ -0,0 +1,82 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_PKCS7_H +#define OPENSSL_HEADER_PKCS7_H + +#include + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// PKCS#7. +// +// This library contains functions for extracting information from PKCS#7 +// structures (RFC 2315). + +DECLARE_STACK_OF(CRYPTO_BUFFER) +DECLARE_STACK_OF(X509) +DECLARE_STACK_OF(X509_CRL) + +// PKCS7_get_raw_certificates parses a PKCS#7, SignedData structure from |cbs| +// and appends the included certificates to |out_certs|. It returns one on +// success and zero on error. +OPENSSL_EXPORT int PKCS7_get_raw_certificates( + STACK_OF(CRYPTO_BUFFER) *out_certs, CBS *cbs, CRYPTO_BUFFER_POOL *pool); + +// PKCS7_get_certificates behaves like |PKCS7_get_raw_certificates| but parses +// them into |X509| objects. +OPENSSL_EXPORT int PKCS7_get_certificates(STACK_OF(X509) *out_certs, CBS *cbs); + +// PKCS7_bundle_certificates appends a PKCS#7, SignedData structure containing +// |certs| to |out|. It returns one on success and zero on error. +OPENSSL_EXPORT int PKCS7_bundle_certificates( + CBB *out, const STACK_OF(X509) *certs); + +// PKCS7_get_CRLs parses a PKCS#7, SignedData structure from |cbs| and appends +// the included CRLs to |out_crls|. It returns one on success and zero on +// error. +OPENSSL_EXPORT int PKCS7_get_CRLs(STACK_OF(X509_CRL) *out_crls, CBS *cbs); + +// PKCS7_bundle_CRLs appends a PKCS#7, SignedData structure containing +// |crls| to |out|. It returns one on success and zero on error. +OPENSSL_EXPORT int PKCS7_bundle_CRLs(CBB *out, const STACK_OF(X509_CRL) *crls); + +// PKCS7_get_PEM_certificates reads a PEM-encoded, PKCS#7, SignedData structure +// from |pem_bio| and appends the included certificates to |out_certs|. It +// returns one on success and zero on error. +OPENSSL_EXPORT int PKCS7_get_PEM_certificates(STACK_OF(X509) *out_certs, + BIO *pem_bio); + +// PKCS7_get_PEM_CRLs reads a PEM-encoded, PKCS#7, SignedData structure from +// |pem_bio| and appends the included CRLs to |out_crls|. It returns one on +// success and zero on error. +OPENSSL_EXPORT int PKCS7_get_PEM_CRLs(STACK_OF(X509_CRL) *out_crls, + BIO *pem_bio); + + +#if defined(__cplusplus) +} // extern C +#endif + +#define PKCS7_R_BAD_PKCS7_VERSION 100 +#define PKCS7_R_NOT_PKCS7_SIGNED_DATA 101 +#define PKCS7_R_NO_CERTIFICATES_INCLUDED 102 +#define PKCS7_R_NO_CRLS_INCLUDED 103 + +#endif // OPENSSL_HEADER_PKCS7_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/pkcs8.h b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/pkcs8.h new file mode 100644 index 0000000..69d0db2 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/pkcs8.h @@ -0,0 +1,230 @@ +/* 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_HEADER_PKCS8_H +#define OPENSSL_HEADER_PKCS8_H + +#include +#include + + +#if defined(__cplusplus) +extern "C" { +#endif + + +// PKCS8_encrypt serializes and encrypts a PKCS8_PRIV_KEY_INFO with PBES1 or +// PBES2 as defined in PKCS #5. Only pbeWithSHAAnd128BitRC4, +// pbeWithSHAAnd3-KeyTripleDES-CBC and pbeWithSHA1And40BitRC2, defined in PKCS +// #12, and PBES2, are supported. PBES2 is selected by setting |cipher| and +// passing -1 for |pbe_nid|. Otherwise, PBES1 is used and |cipher| is ignored. +// +// |pass| is used as the password. If a PBES1 scheme from PKCS #12 is used, this +// will be converted to a raw byte string as specified in B.1 of PKCS #12. If +// |pass| is NULL, it will be encoded as the empty byte string rather than two +// zero bytes, the PKCS #12 encoding of the empty string. +// +// If |salt| is NULL, a random salt of |salt_len| bytes is generated. If +// |salt_len| is zero, a default salt length is used instead. +// +// The resulting structure is stored in an |X509_SIG| which must be freed by the +// caller. +OPENSSL_EXPORT X509_SIG *PKCS8_encrypt(int pbe_nid, const EVP_CIPHER *cipher, + const char *pass, int pass_len, + const uint8_t *salt, size_t salt_len, + int iterations, + PKCS8_PRIV_KEY_INFO *p8inf); + +// PKCS8_marshal_encrypted_private_key behaves like |PKCS8_encrypt| but encrypts +// an |EVP_PKEY| and writes the serialized EncryptedPrivateKeyInfo to |out|. It +// returns one on success and zero on error. +OPENSSL_EXPORT int PKCS8_marshal_encrypted_private_key( + CBB *out, int pbe_nid, const EVP_CIPHER *cipher, const char *pass, + size_t pass_len, const uint8_t *salt, size_t salt_len, int iterations, + const EVP_PKEY *pkey); + +// PKCS8_decrypt decrypts and decodes a PKCS8_PRIV_KEY_INFO with PBES1 or PBES2 +// as defined in PKCS #5. Only pbeWithSHAAnd128BitRC4, +// pbeWithSHAAnd3-KeyTripleDES-CBC and pbeWithSHA1And40BitRC2, and PBES2, +// defined in PKCS #12, are supported. +// +// |pass| is used as the password. If a PBES1 scheme from PKCS #12 is used, this +// will be converted to a raw byte string as specified in B.1 of PKCS #12. If +// |pass| is NULL, it will be encoded as the empty byte string rather than two +// zero bytes, the PKCS #12 encoding of the empty string. +// +// The resulting structure must be freed by the caller. +OPENSSL_EXPORT PKCS8_PRIV_KEY_INFO *PKCS8_decrypt(X509_SIG *pkcs8, + const char *pass, + int pass_len); + +// PKCS8_parse_encrypted_private_key behaves like |PKCS8_decrypt| but it parses +// the EncryptedPrivateKeyInfo structure from |cbs| and advances |cbs|. It +// returns a newly-allocated |EVP_PKEY| on success and zero on error. +OPENSSL_EXPORT EVP_PKEY *PKCS8_parse_encrypted_private_key(CBS *cbs, + const char *pass, + size_t pass_len); + +// PKCS12_get_key_and_certs parses a PKCS#12 structure from |in|, authenticates +// and decrypts it using |password|, sets |*out_key| to the included private +// key and appends the included certificates to |out_certs|. It returns one on +// success and zero on error. The caller takes ownership of the outputs. +OPENSSL_EXPORT int PKCS12_get_key_and_certs(EVP_PKEY **out_key, + STACK_OF(X509) *out_certs, + CBS *in, const char *password); + + +// Deprecated functions. + +// PKCS12_PBE_add does nothing. It exists for compatibility with OpenSSL. +OPENSSL_EXPORT void PKCS12_PBE_add(void); + +// d2i_PKCS12 is a dummy function that copies |*ber_bytes| into a +// |PKCS12| structure. The |out_p12| argument should be NULL(✝). On exit, +// |*ber_bytes| will be advanced by |ber_len|. It returns a fresh |PKCS12| +// structure or NULL on error. +// +// Note: unlike other d2i functions, |d2i_PKCS12| will always consume |ber_len| +// bytes. +// +// (✝) If |out_p12| is not NULL and the function is successful, |*out_p12| will +// be freed if not NULL itself and the result will be written to |*out_p12|. +// New code should not depend on this. +OPENSSL_EXPORT PKCS12 *d2i_PKCS12(PKCS12 **out_p12, const uint8_t **ber_bytes, + size_t ber_len); + +// d2i_PKCS12_bio acts like |d2i_PKCS12| but reads from a |BIO|. +OPENSSL_EXPORT PKCS12* d2i_PKCS12_bio(BIO *bio, PKCS12 **out_p12); + +// d2i_PKCS12_fp acts like |d2i_PKCS12| but reads from a |FILE|. +OPENSSL_EXPORT PKCS12* d2i_PKCS12_fp(FILE *fp, PKCS12 **out_p12); + +// PKCS12_parse calls |PKCS12_get_key_and_certs| on the ASN.1 data stored in +// |p12|. The |out_pkey| and |out_cert| arguments must not be NULL and, on +// successful exit, the private key and first certificate will be stored in +// them. The |out_ca_certs| argument may be NULL but, if not, then any extra +// certificates will be appended to |*out_ca_certs|. If |*out_ca_certs| is NULL +// then it will be set to a freshly allocated stack containing the extra certs. +// +// It returns one on success and zero on error. +OPENSSL_EXPORT int PKCS12_parse(const PKCS12 *p12, const char *password, + EVP_PKEY **out_pkey, X509 **out_cert, + STACK_OF(X509) **out_ca_certs); + +// PKCS12_verify_mac returns one if |password| is a valid password for |p12| +// and zero otherwise. Since |PKCS12_parse| doesn't take a length parameter, +// it's not actually possible to use a non-NUL-terminated password to actually +// get anything from a |PKCS12|. Thus |password| and |password_len| may be +// |NULL| and zero, respectively, or else |password_len| may be -1, or else +// |password[password_len]| must be zero and no other NUL bytes may appear in +// |password|. If the |password_len| checks fail, zero is returned +// immediately. +OPENSSL_EXPORT int PKCS12_verify_mac(const PKCS12 *p12, const char *password, + int password_len); + +// PKCS12_free frees |p12| and its contents. +OPENSSL_EXPORT void PKCS12_free(PKCS12 *p12); + + +#if defined(__cplusplus) +} // extern C + +extern "C++" { + +namespace bssl { + +BORINGSSL_MAKE_DELETER(PKCS12, PKCS12_free) +BORINGSSL_MAKE_DELETER(PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_free) + +} // namespace bssl + +} // extern C++ + +#endif + +#define PKCS8_R_BAD_PKCS12_DATA 100 +#define PKCS8_R_BAD_PKCS12_VERSION 101 +#define PKCS8_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER 102 +#define PKCS8_R_CRYPT_ERROR 103 +#define PKCS8_R_DECODE_ERROR 104 +#define PKCS8_R_ENCODE_ERROR 105 +#define PKCS8_R_ENCRYPT_ERROR 106 +#define PKCS8_R_ERROR_SETTING_CIPHER_PARAMS 107 +#define PKCS8_R_INCORRECT_PASSWORD 108 +#define PKCS8_R_KEYGEN_FAILURE 109 +#define PKCS8_R_KEY_GEN_ERROR 110 +#define PKCS8_R_METHOD_NOT_SUPPORTED 111 +#define PKCS8_R_MISSING_MAC 112 +#define PKCS8_R_MULTIPLE_PRIVATE_KEYS_IN_PKCS12 113 +#define PKCS8_R_PKCS12_PUBLIC_KEY_INTEGRITY_NOT_SUPPORTED 114 +#define PKCS8_R_PKCS12_TOO_DEEPLY_NESTED 115 +#define PKCS8_R_PRIVATE_KEY_DECODE_ERROR 116 +#define PKCS8_R_PRIVATE_KEY_ENCODE_ERROR 117 +#define PKCS8_R_TOO_LONG 118 +#define PKCS8_R_UNKNOWN_ALGORITHM 119 +#define PKCS8_R_UNKNOWN_CIPHER 120 +#define PKCS8_R_UNKNOWN_CIPHER_ALGORITHM 121 +#define PKCS8_R_UNKNOWN_DIGEST 122 +#define PKCS8_R_UNKNOWN_HASH 123 +#define PKCS8_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM 124 +#define PKCS8_R_UNSUPPORTED_KEYLENGTH 125 +#define PKCS8_R_UNSUPPORTED_SALT_TYPE 126 +#define PKCS8_R_UNSUPPORTED_CIPHER 127 +#define PKCS8_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION 128 +#define PKCS8_R_BAD_ITERATION_COUNT 129 +#define PKCS8_R_UNSUPPORTED_PRF 130 + +#endif // OPENSSL_HEADER_PKCS8_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/pkcs8.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/pkcs8.h.grpc_back new file mode 100644 index 0000000..f865c76 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/pkcs8.h.grpc_back @@ -0,0 +1,230 @@ +/* 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_HEADER_PKCS8_H +#define OPENSSL_HEADER_PKCS8_H + +#include +#include + + +#if defined(__cplusplus) +extern "C" { +#endif + + +// PKCS8_encrypt serializes and encrypts a PKCS8_PRIV_KEY_INFO with PBES1 or +// PBES2 as defined in PKCS #5. Only pbeWithSHAAnd128BitRC4, +// pbeWithSHAAnd3-KeyTripleDES-CBC and pbeWithSHA1And40BitRC2, defined in PKCS +// #12, and PBES2, are supported. PBES2 is selected by setting |cipher| and +// passing -1 for |pbe_nid|. Otherwise, PBES1 is used and |cipher| is ignored. +// +// |pass| is used as the password. If a PBES1 scheme from PKCS #12 is used, this +// will be converted to a raw byte string as specified in B.1 of PKCS #12. If +// |pass| is NULL, it will be encoded as the empty byte string rather than two +// zero bytes, the PKCS #12 encoding of the empty string. +// +// If |salt| is NULL, a random salt of |salt_len| bytes is generated. If +// |salt_len| is zero, a default salt length is used instead. +// +// The resulting structure is stored in an |X509_SIG| which must be freed by the +// caller. +OPENSSL_EXPORT X509_SIG *PKCS8_encrypt(int pbe_nid, const EVP_CIPHER *cipher, + const char *pass, int pass_len, + const uint8_t *salt, size_t salt_len, + int iterations, + PKCS8_PRIV_KEY_INFO *p8inf); + +// PKCS8_marshal_encrypted_private_key behaves like |PKCS8_encrypt| but encrypts +// an |EVP_PKEY| and writes the serialized EncryptedPrivateKeyInfo to |out|. It +// returns one on success and zero on error. +OPENSSL_EXPORT int PKCS8_marshal_encrypted_private_key( + CBB *out, int pbe_nid, const EVP_CIPHER *cipher, const char *pass, + size_t pass_len, const uint8_t *salt, size_t salt_len, int iterations, + const EVP_PKEY *pkey); + +// PKCS8_decrypt decrypts and decodes a PKCS8_PRIV_KEY_INFO with PBES1 or PBES2 +// as defined in PKCS #5. Only pbeWithSHAAnd128BitRC4, +// pbeWithSHAAnd3-KeyTripleDES-CBC and pbeWithSHA1And40BitRC2, and PBES2, +// defined in PKCS #12, are supported. +// +// |pass| is used as the password. If a PBES1 scheme from PKCS #12 is used, this +// will be converted to a raw byte string as specified in B.1 of PKCS #12. If +// |pass| is NULL, it will be encoded as the empty byte string rather than two +// zero bytes, the PKCS #12 encoding of the empty string. +// +// The resulting structure must be freed by the caller. +OPENSSL_EXPORT PKCS8_PRIV_KEY_INFO *PKCS8_decrypt(X509_SIG *pkcs8, + const char *pass, + int pass_len); + +// PKCS8_parse_encrypted_private_key behaves like |PKCS8_decrypt| but it parses +// the EncryptedPrivateKeyInfo structure from |cbs| and advances |cbs|. It +// returns a newly-allocated |EVP_PKEY| on success and zero on error. +OPENSSL_EXPORT EVP_PKEY *PKCS8_parse_encrypted_private_key(CBS *cbs, + const char *pass, + size_t pass_len); + +// PKCS12_get_key_and_certs parses a PKCS#12 structure from |in|, authenticates +// and decrypts it using |password|, sets |*out_key| to the included private +// key and appends the included certificates to |out_certs|. It returns one on +// success and zero on error. The caller takes ownership of the outputs. +OPENSSL_EXPORT int PKCS12_get_key_and_certs(EVP_PKEY **out_key, + STACK_OF(X509) *out_certs, + CBS *in, const char *password); + + +// Deprecated functions. + +// PKCS12_PBE_add does nothing. It exists for compatibility with OpenSSL. +OPENSSL_EXPORT void PKCS12_PBE_add(void); + +// d2i_PKCS12 is a dummy function that copies |*ber_bytes| into a +// |PKCS12| structure. The |out_p12| argument should be NULL(✝). On exit, +// |*ber_bytes| will be advanced by |ber_len|. It returns a fresh |PKCS12| +// structure or NULL on error. +// +// Note: unlike other d2i functions, |d2i_PKCS12| will always consume |ber_len| +// bytes. +// +// (✝) If |out_p12| is not NULL and the function is successful, |*out_p12| will +// be freed if not NULL itself and the result will be written to |*out_p12|. +// New code should not depend on this. +OPENSSL_EXPORT PKCS12 *d2i_PKCS12(PKCS12 **out_p12, const uint8_t **ber_bytes, + size_t ber_len); + +// d2i_PKCS12_bio acts like |d2i_PKCS12| but reads from a |BIO|. +OPENSSL_EXPORT PKCS12* d2i_PKCS12_bio(BIO *bio, PKCS12 **out_p12); + +// d2i_PKCS12_fp acts like |d2i_PKCS12| but reads from a |FILE|. +OPENSSL_EXPORT PKCS12* d2i_PKCS12_fp(FILE *fp, PKCS12 **out_p12); + +// PKCS12_parse calls |PKCS12_get_key_and_certs| on the ASN.1 data stored in +// |p12|. The |out_pkey| and |out_cert| arguments must not be NULL and, on +// successful exit, the private key and first certificate will be stored in +// them. The |out_ca_certs| argument may be NULL but, if not, then any extra +// certificates will be appended to |*out_ca_certs|. If |*out_ca_certs| is NULL +// then it will be set to a freshly allocated stack containing the extra certs. +// +// It returns one on success and zero on error. +OPENSSL_EXPORT int PKCS12_parse(const PKCS12 *p12, const char *password, + EVP_PKEY **out_pkey, X509 **out_cert, + STACK_OF(X509) **out_ca_certs); + +// PKCS12_verify_mac returns one if |password| is a valid password for |p12| +// and zero otherwise. Since |PKCS12_parse| doesn't take a length parameter, +// it's not actually possible to use a non-NUL-terminated password to actually +// get anything from a |PKCS12|. Thus |password| and |password_len| may be +// |NULL| and zero, respectively, or else |password_len| may be -1, or else +// |password[password_len]| must be zero and no other NUL bytes may appear in +// |password|. If the |password_len| checks fail, zero is returned +// immediately. +OPENSSL_EXPORT int PKCS12_verify_mac(const PKCS12 *p12, const char *password, + int password_len); + +// PKCS12_free frees |p12| and its contents. +OPENSSL_EXPORT void PKCS12_free(PKCS12 *p12); + + +#if defined(__cplusplus) +} // extern C + +extern "C++" { + +namespace bssl { + +BORINGSSL_MAKE_DELETER(PKCS12, PKCS12_free) +BORINGSSL_MAKE_DELETER(PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO_free) + +} // namespace bssl + +} // extern C++ + +#endif + +#define PKCS8_R_BAD_PKCS12_DATA 100 +#define PKCS8_R_BAD_PKCS12_VERSION 101 +#define PKCS8_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER 102 +#define PKCS8_R_CRYPT_ERROR 103 +#define PKCS8_R_DECODE_ERROR 104 +#define PKCS8_R_ENCODE_ERROR 105 +#define PKCS8_R_ENCRYPT_ERROR 106 +#define PKCS8_R_ERROR_SETTING_CIPHER_PARAMS 107 +#define PKCS8_R_INCORRECT_PASSWORD 108 +#define PKCS8_R_KEYGEN_FAILURE 109 +#define PKCS8_R_KEY_GEN_ERROR 110 +#define PKCS8_R_METHOD_NOT_SUPPORTED 111 +#define PKCS8_R_MISSING_MAC 112 +#define PKCS8_R_MULTIPLE_PRIVATE_KEYS_IN_PKCS12 113 +#define PKCS8_R_PKCS12_PUBLIC_KEY_INTEGRITY_NOT_SUPPORTED 114 +#define PKCS8_R_PKCS12_TOO_DEEPLY_NESTED 115 +#define PKCS8_R_PRIVATE_KEY_DECODE_ERROR 116 +#define PKCS8_R_PRIVATE_KEY_ENCODE_ERROR 117 +#define PKCS8_R_TOO_LONG 118 +#define PKCS8_R_UNKNOWN_ALGORITHM 119 +#define PKCS8_R_UNKNOWN_CIPHER 120 +#define PKCS8_R_UNKNOWN_CIPHER_ALGORITHM 121 +#define PKCS8_R_UNKNOWN_DIGEST 122 +#define PKCS8_R_UNKNOWN_HASH 123 +#define PKCS8_R_UNSUPPORTED_PRIVATE_KEY_ALGORITHM 124 +#define PKCS8_R_UNSUPPORTED_KEYLENGTH 125 +#define PKCS8_R_UNSUPPORTED_SALT_TYPE 126 +#define PKCS8_R_UNSUPPORTED_CIPHER 127 +#define PKCS8_R_UNSUPPORTED_KEY_DERIVATION_FUNCTION 128 +#define PKCS8_R_BAD_ITERATION_COUNT 129 +#define PKCS8_R_UNSUPPORTED_PRF 130 + +#endif // OPENSSL_HEADER_PKCS8_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/poly1305.h b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/poly1305.h new file mode 100644 index 0000000..ae0da81 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/poly1305.h @@ -0,0 +1,51 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_POLY1305_H +#define OPENSSL_HEADER_POLY1305_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +typedef uint8_t poly1305_state[512]; + +// CRYPTO_poly1305_init sets up |state| so that it can be used to calculate an +// authentication tag with the one-time key |key|. Note that |key| is a +// one-time key and therefore there is no `reset' method because that would +// enable several messages to be authenticated with the same key. +OPENSSL_EXPORT void CRYPTO_poly1305_init(poly1305_state* state, + const uint8_t key[32]); + +// CRYPTO_poly1305_update processes |in_len| bytes from |in|. It can be called +// zero or more times after poly1305_init. +OPENSSL_EXPORT void CRYPTO_poly1305_update(poly1305_state* state, + const uint8_t* in, + size_t in_len); + +// CRYPTO_poly1305_finish completes the poly1305 calculation and writes a 16 +// byte authentication tag to |mac|. The |mac| address must be 16-byte +// aligned. +OPENSSL_EXPORT void CRYPTO_poly1305_finish(poly1305_state* state, + uint8_t mac[16]); + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_POLY1305_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/poly1305.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/poly1305.h.grpc_back new file mode 100644 index 0000000..cefe2b1 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/poly1305.h.grpc_back @@ -0,0 +1,51 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_POLY1305_H +#define OPENSSL_HEADER_POLY1305_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +typedef uint8_t poly1305_state[512]; + +// CRYPTO_poly1305_init sets up |state| so that it can be used to calculate an +// authentication tag with the one-time key |key|. Note that |key| is a +// one-time key and therefore there is no `reset' method because that would +// enable several messages to be authenticated with the same key. +OPENSSL_EXPORT void CRYPTO_poly1305_init(poly1305_state* state, + const uint8_t key[32]); + +// CRYPTO_poly1305_update processes |in_len| bytes from |in|. It can be called +// zero or more times after poly1305_init. +OPENSSL_EXPORT void CRYPTO_poly1305_update(poly1305_state* state, + const uint8_t* in, + size_t in_len); + +// CRYPTO_poly1305_finish completes the poly1305 calculation and writes a 16 +// byte authentication tag to |mac|. The |mac| address must be 16-byte +// aligned. +OPENSSL_EXPORT void CRYPTO_poly1305_finish(poly1305_state* state, + uint8_t mac[16]); + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_POLY1305_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/pool.h b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/pool.h new file mode 100644 index 0000000..c9433c8 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/pool.h @@ -0,0 +1,91 @@ +/* Copyright (c) 2016, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_POOL_H +#define OPENSSL_HEADER_POOL_H + +#include + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// Buffers and buffer pools. +// +// |CRYPTO_BUFFER|s are simply reference-counted blobs. A |CRYPTO_BUFFER_POOL| +// is an intern table for |CRYPTO_BUFFER|s. This allows for a single copy of a +// given blob to be kept in memory and referenced from multiple places. + + +DEFINE_STACK_OF(CRYPTO_BUFFER) + +// CRYPTO_BUFFER_POOL_new returns a freshly allocated |CRYPTO_BUFFER_POOL| or +// NULL on error. +OPENSSL_EXPORT CRYPTO_BUFFER_POOL* CRYPTO_BUFFER_POOL_new(void); + +// CRYPTO_BUFFER_POOL_free frees |pool|, which must be empty. +OPENSSL_EXPORT void CRYPTO_BUFFER_POOL_free(CRYPTO_BUFFER_POOL *pool); + +// CRYPTO_BUFFER_new returns a |CRYPTO_BUFFER| containing a copy of |data|, or +// else NULL on error. If |pool| is not NULL then the returned value may be a +// reference to a previously existing |CRYPTO_BUFFER| that contained the same +// data. Otherwise, the returned, fresh |CRYPTO_BUFFER| will be added to the +// pool. +OPENSSL_EXPORT CRYPTO_BUFFER *CRYPTO_BUFFER_new(const uint8_t *data, size_t len, + CRYPTO_BUFFER_POOL *pool); + +// CRYPTO_BUFFER_new_from_CBS acts the same as |CRYPTO_BUFFER_new|. +OPENSSL_EXPORT CRYPTO_BUFFER *CRYPTO_BUFFER_new_from_CBS( + CBS *cbs, CRYPTO_BUFFER_POOL *pool); + +// CRYPTO_BUFFER_free decrements the reference count of |buf|. If there are no +// other references, or if the only remaining reference is from a pool, then +// |buf| will be freed. +OPENSSL_EXPORT void CRYPTO_BUFFER_free(CRYPTO_BUFFER *buf); + +// CRYPTO_BUFFER_up_ref increments the reference count of |buf| and returns +// one. +OPENSSL_EXPORT int CRYPTO_BUFFER_up_ref(CRYPTO_BUFFER *buf); + +// CRYPTO_BUFFER_data returns a pointer to the data contained in |buf|. +OPENSSL_EXPORT const uint8_t *CRYPTO_BUFFER_data(const CRYPTO_BUFFER *buf); + +// CRYPTO_BUFFER_len returns the length, in bytes, of the data contained in +// |buf|. +OPENSSL_EXPORT size_t CRYPTO_BUFFER_len(const CRYPTO_BUFFER *buf); + +// CRYPTO_BUFFER_init_CBS initialises |out| to point at the data from |buf|. +OPENSSL_EXPORT void CRYPTO_BUFFER_init_CBS(const CRYPTO_BUFFER *buf, CBS *out); + + +#if defined(__cplusplus) +} // extern C + +extern "C++" { + +namespace bssl { + +BORINGSSL_MAKE_DELETER(CRYPTO_BUFFER_POOL, CRYPTO_BUFFER_POOL_free) +BORINGSSL_MAKE_DELETER(CRYPTO_BUFFER, CRYPTO_BUFFER_free) + +} // namespace bssl + +} // extern C++ + +#endif + +#endif // OPENSSL_HEADER_POOL_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/pool.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/pool.h.grpc_back new file mode 100644 index 0000000..373952f --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/pool.h.grpc_back @@ -0,0 +1,91 @@ +/* Copyright (c) 2016, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_POOL_H +#define OPENSSL_HEADER_POOL_H + +#include + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// Buffers and buffer pools. +// +// |CRYPTO_BUFFER|s are simply reference-counted blobs. A |CRYPTO_BUFFER_POOL| +// is an intern table for |CRYPTO_BUFFER|s. This allows for a single copy of a +// given blob to be kept in memory and referenced from multiple places. + + +DEFINE_STACK_OF(CRYPTO_BUFFER) + +// CRYPTO_BUFFER_POOL_new returns a freshly allocated |CRYPTO_BUFFER_POOL| or +// NULL on error. +OPENSSL_EXPORT CRYPTO_BUFFER_POOL* CRYPTO_BUFFER_POOL_new(void); + +// CRYPTO_BUFFER_POOL_free frees |pool|, which must be empty. +OPENSSL_EXPORT void CRYPTO_BUFFER_POOL_free(CRYPTO_BUFFER_POOL *pool); + +// CRYPTO_BUFFER_new returns a |CRYPTO_BUFFER| containing a copy of |data|, or +// else NULL on error. If |pool| is not NULL then the returned value may be a +// reference to a previously existing |CRYPTO_BUFFER| that contained the same +// data. Otherwise, the returned, fresh |CRYPTO_BUFFER| will be added to the +// pool. +OPENSSL_EXPORT CRYPTO_BUFFER *CRYPTO_BUFFER_new(const uint8_t *data, size_t len, + CRYPTO_BUFFER_POOL *pool); + +// CRYPTO_BUFFER_new_from_CBS acts the same as |CRYPTO_BUFFER_new|. +OPENSSL_EXPORT CRYPTO_BUFFER *CRYPTO_BUFFER_new_from_CBS( + CBS *cbs, CRYPTO_BUFFER_POOL *pool); + +// CRYPTO_BUFFER_free decrements the reference count of |buf|. If there are no +// other references, or if the only remaining reference is from a pool, then +// |buf| will be freed. +OPENSSL_EXPORT void CRYPTO_BUFFER_free(CRYPTO_BUFFER *buf); + +// CRYPTO_BUFFER_up_ref increments the reference count of |buf| and returns +// one. +OPENSSL_EXPORT int CRYPTO_BUFFER_up_ref(CRYPTO_BUFFER *buf); + +// CRYPTO_BUFFER_data returns a pointer to the data contained in |buf|. +OPENSSL_EXPORT const uint8_t *CRYPTO_BUFFER_data(const CRYPTO_BUFFER *buf); + +// CRYPTO_BUFFER_len returns the length, in bytes, of the data contained in +// |buf|. +OPENSSL_EXPORT size_t CRYPTO_BUFFER_len(const CRYPTO_BUFFER *buf); + +// CRYPTO_BUFFER_init_CBS initialises |out| to point at the data from |buf|. +OPENSSL_EXPORT void CRYPTO_BUFFER_init_CBS(const CRYPTO_BUFFER *buf, CBS *out); + + +#if defined(__cplusplus) +} // extern C + +extern "C++" { + +namespace bssl { + +BORINGSSL_MAKE_DELETER(CRYPTO_BUFFER_POOL, CRYPTO_BUFFER_POOL_free) +BORINGSSL_MAKE_DELETER(CRYPTO_BUFFER, CRYPTO_BUFFER_free) + +} // namespace bssl + +} // extern C++ + +#endif + +#endif // OPENSSL_HEADER_POOL_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/rand.h b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/rand.h new file mode 100644 index 0000000..7daecc2 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/rand.h @@ -0,0 +1,125 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_RAND_H +#define OPENSSL_HEADER_RAND_H + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// Random number generation. + + +// RAND_bytes writes |len| bytes of random data to |buf| and returns one. +OPENSSL_EXPORT int RAND_bytes(uint8_t *buf, size_t len); + +// RAND_cleanup frees any resources used by the RNG. This is not safe if other +// threads might still be calling |RAND_bytes|. +OPENSSL_EXPORT void RAND_cleanup(void); + + +// Obscure functions. + +#if !defined(OPENSSL_WINDOWS) +// RAND_set_urandom_fd causes the module to use a copy of |fd| for system +// randomness rather opening /dev/urandom internally. The caller retains +// ownership of |fd| and is at liberty to close it at any time. This is useful +// if, due to a sandbox, /dev/urandom isn't available. If used, it must be +// called before the first call to |RAND_bytes|, and it is mutually exclusive +// with |RAND_enable_fork_unsafe_buffering|. +// +// |RAND_set_urandom_fd| does not buffer any entropy, so it is safe to call +// |fork| at any time after calling |RAND_set_urandom_fd|. +OPENSSL_EXPORT void RAND_set_urandom_fd(int fd); + +// RAND_enable_fork_unsafe_buffering enables efficient buffered reading of +// /dev/urandom. It adds an overhead of a few KB of memory per thread. It must +// be called before the first call to |RAND_bytes| and it is mutually exclusive +// with calls to |RAND_set_urandom_fd|. +// +// If |fd| is non-negative then a copy of |fd| will be used rather than opening +// /dev/urandom internally. Like |RAND_set_urandom_fd|, the caller retains +// ownership of |fd|. If |fd| is negative then /dev/urandom will be opened and +// any error from open(2) crashes the address space. +// +// It has an unusual name because the buffer is unsafe across calls to |fork|. +// Hence, this function should never be called by libraries. +OPENSSL_EXPORT void RAND_enable_fork_unsafe_buffering(int fd); +#endif + +#if defined(BORINGSSL_UNSAFE_DETERMINISTIC_MODE) +// RAND_reset_for_fuzzing resets the fuzzer-only deterministic RNG. This +// function is only defined in the fuzzer-only build configuration. +OPENSSL_EXPORT void RAND_reset_for_fuzzing(void); +#endif + + +// Deprecated functions + +// RAND_pseudo_bytes is a wrapper around |RAND_bytes|. +OPENSSL_EXPORT int RAND_pseudo_bytes(uint8_t *buf, size_t len); + +// RAND_seed reads a single byte of random data to ensure that any file +// descriptors etc are opened. +OPENSSL_EXPORT void RAND_seed(const void *buf, int num); + +// RAND_load_file returns a nonnegative number. +OPENSSL_EXPORT int RAND_load_file(const char *path, long num); + +// RAND_file_name returns NULL. +OPENSSL_EXPORT const char *RAND_file_name(char *buf, size_t num); + +// RAND_add does nothing. +OPENSSL_EXPORT void RAND_add(const void *buf, int num, double entropy); + +// RAND_egd returns 255. +OPENSSL_EXPORT int RAND_egd(const char *); + +// RAND_poll returns one. +OPENSSL_EXPORT int RAND_poll(void); + +// RAND_status returns one. +OPENSSL_EXPORT int RAND_status(void); + +// rand_meth_st is typedefed to |RAND_METHOD| in base.h. It isn't used; it +// exists only to be the return type of |RAND_SSLeay|. It's +// external so that variables of this type can be initialized. +struct rand_meth_st { + void (*seed) (const void *buf, int num); + int (*bytes) (uint8_t *buf, size_t num); + void (*cleanup) (void); + void (*add) (const void *buf, int num, double entropy); + int (*pseudorand) (uint8_t *buf, size_t num); + int (*status) (void); +}; + +// RAND_SSLeay returns a pointer to a dummy |RAND_METHOD|. +OPENSSL_EXPORT RAND_METHOD *RAND_SSLeay(void); + +// RAND_get_rand_method returns |RAND_SSLeay()|. +OPENSSL_EXPORT const RAND_METHOD *RAND_get_rand_method(void); + +// RAND_set_rand_method does nothing. +OPENSSL_EXPORT void RAND_set_rand_method(const RAND_METHOD *); + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_RAND_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/rand.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/rand.h.grpc_back new file mode 100644 index 0000000..5d02e12 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/rand.h.grpc_back @@ -0,0 +1,125 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_RAND_H +#define OPENSSL_HEADER_RAND_H + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// Random number generation. + + +// RAND_bytes writes |len| bytes of random data to |buf| and returns one. +OPENSSL_EXPORT int RAND_bytes(uint8_t *buf, size_t len); + +// RAND_cleanup frees any resources used by the RNG. This is not safe if other +// threads might still be calling |RAND_bytes|. +OPENSSL_EXPORT void RAND_cleanup(void); + + +// Obscure functions. + +#if !defined(OPENSSL_WINDOWS) +// RAND_set_urandom_fd causes the module to use a copy of |fd| for system +// randomness rather opening /dev/urandom internally. The caller retains +// ownership of |fd| and is at liberty to close it at any time. This is useful +// if, due to a sandbox, /dev/urandom isn't available. If used, it must be +// called before the first call to |RAND_bytes|, and it is mutually exclusive +// with |RAND_enable_fork_unsafe_buffering|. +// +// |RAND_set_urandom_fd| does not buffer any entropy, so it is safe to call +// |fork| at any time after calling |RAND_set_urandom_fd|. +OPENSSL_EXPORT void RAND_set_urandom_fd(int fd); + +// RAND_enable_fork_unsafe_buffering enables efficient buffered reading of +// /dev/urandom. It adds an overhead of a few KB of memory per thread. It must +// be called before the first call to |RAND_bytes| and it is mutually exclusive +// with calls to |RAND_set_urandom_fd|. +// +// If |fd| is non-negative then a copy of |fd| will be used rather than opening +// /dev/urandom internally. Like |RAND_set_urandom_fd|, the caller retains +// ownership of |fd|. If |fd| is negative then /dev/urandom will be opened and +// any error from open(2) crashes the address space. +// +// It has an unusual name because the buffer is unsafe across calls to |fork|. +// Hence, this function should never be called by libraries. +OPENSSL_EXPORT void RAND_enable_fork_unsafe_buffering(int fd); +#endif + +#if defined(BORINGSSL_UNSAFE_DETERMINISTIC_MODE) +// RAND_reset_for_fuzzing resets the fuzzer-only deterministic RNG. This +// function is only defined in the fuzzer-only build configuration. +OPENSSL_EXPORT void RAND_reset_for_fuzzing(void); +#endif + + +// Deprecated functions + +// RAND_pseudo_bytes is a wrapper around |RAND_bytes|. +OPENSSL_EXPORT int RAND_pseudo_bytes(uint8_t *buf, size_t len); + +// RAND_seed reads a single byte of random data to ensure that any file +// descriptors etc are opened. +OPENSSL_EXPORT void RAND_seed(const void *buf, int num); + +// RAND_load_file returns a nonnegative number. +OPENSSL_EXPORT int RAND_load_file(const char *path, long num); + +// RAND_file_name returns NULL. +OPENSSL_EXPORT const char *RAND_file_name(char *buf, size_t num); + +// RAND_add does nothing. +OPENSSL_EXPORT void RAND_add(const void *buf, int num, double entropy); + +// RAND_egd returns 255. +OPENSSL_EXPORT int RAND_egd(const char *); + +// RAND_poll returns one. +OPENSSL_EXPORT int RAND_poll(void); + +// RAND_status returns one. +OPENSSL_EXPORT int RAND_status(void); + +// rand_meth_st is typedefed to |RAND_METHOD| in base.h. It isn't used; it +// exists only to be the return type of |RAND_SSLeay|. It's +// external so that variables of this type can be initialized. +struct rand_meth_st { + void (*seed) (const void *buf, int num); + int (*bytes) (uint8_t *buf, size_t num); + void (*cleanup) (void); + void (*add) (const void *buf, int num, double entropy); + int (*pseudorand) (uint8_t *buf, size_t num); + int (*status) (void); +}; + +// RAND_SSLeay returns a pointer to a dummy |RAND_METHOD|. +OPENSSL_EXPORT RAND_METHOD *RAND_SSLeay(void); + +// RAND_get_rand_method returns |RAND_SSLeay()|. +OPENSSL_EXPORT const RAND_METHOD *RAND_get_rand_method(void); + +// RAND_set_rand_method does nothing. +OPENSSL_EXPORT void RAND_set_rand_method(const RAND_METHOD *); + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_RAND_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/rc4.h b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/rc4.h new file mode 100644 index 0000000..1680e3a --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/rc4.h @@ -0,0 +1,96 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 OPENSSL_HEADER_RC4_H +#define OPENSSL_HEADER_RC4_H + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// RC4. + + +struct rc4_key_st { + uint32_t x, y; + uint32_t data[256]; +} /* RC4_KEY */; + +// RC4_set_key performs an RC4 key schedule and initialises |rc4key| with |len| +// bytes of key material from |key|. +OPENSSL_EXPORT void RC4_set_key(RC4_KEY *rc4key, unsigned len, + const uint8_t *key); + +// RC4 encrypts (or decrypts, it's the same with RC4) |len| bytes from |in| to +// |out|. +OPENSSL_EXPORT void RC4(RC4_KEY *key, size_t len, const uint8_t *in, + uint8_t *out); + + +// Deprecated functions. + +// RC4_options returns the string "rc4(ptr,int)". +OPENSSL_EXPORT const char *RC4_options(void); + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_RC4_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/rc4.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/rc4.h.grpc_back new file mode 100644 index 0000000..acf56ae --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/rc4.h.grpc_back @@ -0,0 +1,96 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 OPENSSL_HEADER_RC4_H +#define OPENSSL_HEADER_RC4_H + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// RC4. + + +struct rc4_key_st { + uint32_t x, y; + uint32_t data[256]; +} /* RC4_KEY */; + +// RC4_set_key performs an RC4 key schedule and initialises |rc4key| with |len| +// bytes of key material from |key|. +OPENSSL_EXPORT void RC4_set_key(RC4_KEY *rc4key, unsigned len, + const uint8_t *key); + +// RC4 encrypts (or decrypts, it's the same with RC4) |len| bytes from |in| to +// |out|. +OPENSSL_EXPORT void RC4(RC4_KEY *key, size_t len, const uint8_t *in, + uint8_t *out); + + +// Deprecated functions. + +// RC4_options returns the string "rc4(ptr,int)". +OPENSSL_EXPORT const char *RC4_options(void); + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_RC4_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/ripemd.h b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/ripemd.h new file mode 100644 index 0000000..f94afa9 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/ripemd.h @@ -0,0 +1,107 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 OPENSSL_HEADER_RIPEMD_H +#define OPENSSL_HEADER_RIPEMD_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +# define RIPEMD160_CBLOCK 64 +# define RIPEMD160_LBLOCK (RIPEMD160_CBLOCK/4) +# define RIPEMD160_DIGEST_LENGTH 20 + +struct RIPEMD160state_st { + uint32_t h[5]; + uint32_t Nl, Nh; + uint8_t data[RIPEMD160_CBLOCK]; + unsigned num; +}; + +// RIPEMD160_Init initialises |ctx| and returns one. +OPENSSL_EXPORT int RIPEMD160_Init(RIPEMD160_CTX *ctx); + +// RIPEMD160_Update adds |len| bytes from |data| to |ctx| and returns one. +OPENSSL_EXPORT int RIPEMD160_Update(RIPEMD160_CTX *ctx, const void *data, + size_t len); + +// RIPEMD160_Final adds the final padding to |ctx| and writes the resulting +// digest to |md|, which must have at least |RIPEMD160_DIGEST_LENGTH| bytes of +// space. It returns one. +OPENSSL_EXPORT int RIPEMD160_Final(uint8_t *md, RIPEMD160_CTX *ctx); + +// RIPEMD160 writes the digest of |len| bytes from |data| to |out| and returns +// |out|. There must be at least |RIPEMD160_DIGEST_LENGTH| bytes of space in +// |out|. +OPENSSL_EXPORT uint8_t *RIPEMD160(const uint8_t *data, size_t len, + uint8_t *out); + +// RIPEMD160_Transform is a low-level function that performs a single, +// RIPEMD160 block transformation using the state from |ctx| and 64 bytes from +// |block|. +OPENSSL_EXPORT void RIPEMD160_Transform(RIPEMD160_CTX *ctx, + const uint8_t *block); + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_RIPEMD_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/ripemd.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/ripemd.h.grpc_back new file mode 100644 index 0000000..fb0b50c --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/ripemd.h.grpc_back @@ -0,0 +1,107 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 OPENSSL_HEADER_RIPEMD_H +#define OPENSSL_HEADER_RIPEMD_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +# define RIPEMD160_CBLOCK 64 +# define RIPEMD160_LBLOCK (RIPEMD160_CBLOCK/4) +# define RIPEMD160_DIGEST_LENGTH 20 + +struct RIPEMD160state_st { + uint32_t h[5]; + uint32_t Nl, Nh; + uint8_t data[RIPEMD160_CBLOCK]; + unsigned num; +}; + +// RIPEMD160_Init initialises |ctx| and returns one. +OPENSSL_EXPORT int RIPEMD160_Init(RIPEMD160_CTX *ctx); + +// RIPEMD160_Update adds |len| bytes from |data| to |ctx| and returns one. +OPENSSL_EXPORT int RIPEMD160_Update(RIPEMD160_CTX *ctx, const void *data, + size_t len); + +// RIPEMD160_Final adds the final padding to |ctx| and writes the resulting +// digest to |md|, which must have at least |RIPEMD160_DIGEST_LENGTH| bytes of +// space. It returns one. +OPENSSL_EXPORT int RIPEMD160_Final(uint8_t *md, RIPEMD160_CTX *ctx); + +// RIPEMD160 writes the digest of |len| bytes from |data| to |out| and returns +// |out|. There must be at least |RIPEMD160_DIGEST_LENGTH| bytes of space in +// |out|. +OPENSSL_EXPORT uint8_t *RIPEMD160(const uint8_t *data, size_t len, + uint8_t *out); + +// RIPEMD160_Transform is a low-level function that performs a single, +// RIPEMD160 block transformation using the state from |ctx| and 64 bytes from +// |block|. +OPENSSL_EXPORT void RIPEMD160_Transform(RIPEMD160_CTX *ctx, + const uint8_t *block); + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_RIPEMD_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/rsa.h b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/rsa.h new file mode 100644 index 0000000..8d5c021 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/rsa.h @@ -0,0 +1,756 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 OPENSSL_HEADER_RSA_H +#define OPENSSL_HEADER_RSA_H + +#include + +#include +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// rsa.h contains functions for handling encryption and signature using RSA. + + +// Allocation and destruction. + +// RSA_new returns a new, empty RSA object or NULL on error. +OPENSSL_EXPORT RSA *RSA_new(void); + +// RSA_new_method acts the same as |RSA_new| but takes an explicit |ENGINE|. +OPENSSL_EXPORT RSA *RSA_new_method(const ENGINE *engine); + +// RSA_free decrements the reference count of |rsa| and frees it if the +// reference count drops to zero. +OPENSSL_EXPORT void RSA_free(RSA *rsa); + +// RSA_up_ref increments the reference count of |rsa| and returns one. +OPENSSL_EXPORT int RSA_up_ref(RSA *rsa); + + +// Properties. + +// RSA_bits returns the size of |rsa|, in bits. +OPENSSL_EXPORT unsigned RSA_bits(const RSA *rsa); + +// RSA_get0_key sets |*out_n|, |*out_e|, and |*out_d|, if non-NULL, to |rsa|'s +// modulus, public exponent, and private exponent, respectively. If |rsa| is a +// public key, the private exponent will be set to NULL. +OPENSSL_EXPORT void RSA_get0_key(const RSA *rsa, const BIGNUM **out_n, + const BIGNUM **out_e, const BIGNUM **out_d); + +// RSA_get0_factors sets |*out_p| and |*out_q|, if non-NULL, to |rsa|'s prime +// factors. If |rsa| is a public key, they will be set to NULL. +OPENSSL_EXPORT void RSA_get0_factors(const RSA *rsa, const BIGNUM **out_p, + const BIGNUM **out_q); + +// RSA_get0_crt_params sets |*out_dmp1|, |*out_dmq1|, and |*out_iqmp|, if +// non-NULL, to |rsa|'s CRT parameters. These are d (mod p-1), d (mod q-1) and +// q^-1 (mod p), respectively. If |rsa| is a public key, each parameter will be +// set to NULL. +OPENSSL_EXPORT void RSA_get0_crt_params(const RSA *rsa, const BIGNUM **out_dmp1, + const BIGNUM **out_dmq1, + const BIGNUM **out_iqmp); + +// RSA_set0_key sets |rsa|'s modulus, public exponent, and private exponent to +// |n|, |e|, and |d| respectively, if non-NULL. On success, it takes ownership +// of each argument and returns one. Otherwise, it returns zero. +// +// |d| may be NULL, but |n| and |e| must either be non-NULL or already +// configured on |rsa|. +// +// It is an error to call this function after |rsa| has been used for a +// cryptographic operation. Construct a new |RSA| object instead. +OPENSSL_EXPORT int RSA_set0_key(RSA *rsa, BIGNUM *n, BIGNUM *e, BIGNUM *d); + +// RSA_set0_factors sets |rsa|'s prime factors to |p| and |q|, if non-NULL, and +// takes ownership of them. On success, it takes ownership of each argument and +// returns one. Otherwise, it returns zero. +// +// Each argument must either be non-NULL or already configured on |rsa|. +// +// It is an error to call this function after |rsa| has been used for a +// cryptographic operation. Construct a new |RSA| object instead. +OPENSSL_EXPORT int RSA_set0_factors(RSA *rsa, BIGNUM *p, BIGNUM *q); + +// RSA_set0_crt_params sets |rsa|'s CRT parameters to |dmp1|, |dmq1|, and +// |iqmp|, if non-NULL, and takes ownership of them. On success, it takes +// ownership of its parameters and returns one. Otherwise, it returns zero. +// +// Each argument must either be non-NULL or already configured on |rsa|. +// +// It is an error to call this function after |rsa| has been used for a +// cryptographic operation. Construct a new |RSA| object instead. +OPENSSL_EXPORT int RSA_set0_crt_params(RSA *rsa, BIGNUM *dmp1, BIGNUM *dmq1, + BIGNUM *iqmp); + + +// Key generation. + +// RSA_generate_key_ex generates a new RSA key where the modulus has size +// |bits| and the public exponent is |e|. If unsure, |RSA_F4| is a good value +// for |e|. If |cb| is not NULL then it is called during the key generation +// process. In addition to the calls documented for |BN_generate_prime_ex|, it +// is called with event=2 when the n'th prime is rejected as unsuitable and +// with event=3 when a suitable value for |p| is found. +// +// It returns one on success or zero on error. +OPENSSL_EXPORT int RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e, + BN_GENCB *cb); + +// RSA_generate_key_fips behaves like |RSA_generate_key_ex| but performs +// additional checks for FIPS compliance. The public exponent is always 65537 +// and |bits| must be either 2048 or 3072. +OPENSSL_EXPORT int RSA_generate_key_fips(RSA *rsa, int bits, BN_GENCB *cb); + + +// Encryption / Decryption + +// Padding types for encryption. +#define RSA_PKCS1_PADDING 1 +#define RSA_NO_PADDING 3 +#define RSA_PKCS1_OAEP_PADDING 4 +// RSA_PKCS1_PSS_PADDING can only be used via the EVP interface. +#define RSA_PKCS1_PSS_PADDING 6 + +// RSA_encrypt encrypts |in_len| bytes from |in| to the public key from |rsa| +// and writes, at most, |max_out| bytes of encrypted data to |out|. The +// |max_out| argument must be, at least, |RSA_size| in order to ensure success. +// +// It returns 1 on success or zero on error. +// +// The |padding| argument must be one of the |RSA_*_PADDING| values. If in +// doubt, use |RSA_PKCS1_OAEP_PADDING| for new protocols but +// |RSA_PKCS1_PADDING| is most common. +OPENSSL_EXPORT int RSA_encrypt(RSA *rsa, size_t *out_len, uint8_t *out, + size_t max_out, const uint8_t *in, size_t in_len, + int padding); + +// RSA_decrypt decrypts |in_len| bytes from |in| with the private key from +// |rsa| and writes, at most, |max_out| bytes of plaintext to |out|. The +// |max_out| argument must be, at least, |RSA_size| in order to ensure success. +// +// It returns 1 on success or zero on error. +// +// The |padding| argument must be one of the |RSA_*_PADDING| values. If in +// doubt, use |RSA_PKCS1_OAEP_PADDING| for new protocols. +// +// Passing |RSA_PKCS1_PADDING| into this function is deprecated and insecure. If +// implementing a protocol using RSAES-PKCS1-V1_5, use |RSA_NO_PADDING| and then +// check padding in constant-time combined with a swap to a random session key +// or other mitigation. See "Chosen Ciphertext Attacks Against Protocols Based +// on the RSA Encryption Standard PKCS #1", Daniel Bleichenbacher, Advances in +// Cryptology (Crypto '98). +OPENSSL_EXPORT int RSA_decrypt(RSA *rsa, size_t *out_len, uint8_t *out, + size_t max_out, const uint8_t *in, size_t in_len, + int padding); + +// RSA_public_encrypt encrypts |flen| bytes from |from| to the public key in +// |rsa| and writes the encrypted data to |to|. The |to| buffer must have at +// least |RSA_size| bytes of space. It returns the number of bytes written, or +// -1 on error. The |padding| argument must be one of the |RSA_*_PADDING| +// values. If in doubt, use |RSA_PKCS1_OAEP_PADDING| for new protocols but +// |RSA_PKCS1_PADDING| is most common. +// +// WARNING: this function is dangerous because it breaks the usual return value +// convention. Use |RSA_encrypt| instead. +OPENSSL_EXPORT int RSA_public_encrypt(size_t flen, const uint8_t *from, + uint8_t *to, RSA *rsa, int padding); + +// RSA_private_decrypt decrypts |flen| bytes from |from| with the public key in +// |rsa| and writes the plaintext to |to|. The |to| buffer must have at least +// |RSA_size| bytes of space. It returns the number of bytes written, or -1 on +// error. The |padding| argument must be one of the |RSA_*_PADDING| values. If +// in doubt, use |RSA_PKCS1_OAEP_PADDING| for new protocols. Passing +// |RSA_PKCS1_PADDING| into this function is deprecated and insecure. See +// |RSA_decrypt|. +// +// WARNING: this function is dangerous because it breaks the usual return value +// convention. Use |RSA_decrypt| instead. +OPENSSL_EXPORT int RSA_private_decrypt(size_t flen, const uint8_t *from, + uint8_t *to, RSA *rsa, int padding); + + +// Signing / Verification + +// RSA_sign signs |in_len| bytes of digest from |in| with |rsa| using +// RSASSA-PKCS1-v1_5. It writes, at most, |RSA_size(rsa)| bytes to |out|. On +// successful return, the actual number of bytes written is written to +// |*out_len|. +// +// The |hash_nid| argument identifies the hash function used to calculate |in| +// and is embedded in the resulting signature. For example, it might be +// |NID_sha256|. +// +// It returns 1 on success and zero on error. +OPENSSL_EXPORT int RSA_sign(int hash_nid, const uint8_t *in, + unsigned int in_len, uint8_t *out, + unsigned int *out_len, RSA *rsa); + +// RSA_sign_pss_mgf1 signs |in_len| bytes from |in| with the public key from +// |rsa| using RSASSA-PSS with MGF1 as the mask generation function. It writes, +// at most, |max_out| bytes of signature data to |out|. The |max_out| argument +// must be, at least, |RSA_size| in order to ensure success. It returns 1 on +// success or zero on error. +// +// The |md| and |mgf1_md| arguments identify the hash used to calculate |msg| +// and the MGF1 hash, respectively. If |mgf1_md| is NULL, |md| is +// used. +// +// |salt_len| specifies the expected salt length in bytes. If |salt_len| is -1, +// then the salt length is the same as the hash length. If -2, then the salt +// length is maximal given the size of |rsa|. If unsure, use -1. +OPENSSL_EXPORT int RSA_sign_pss_mgf1(RSA *rsa, size_t *out_len, uint8_t *out, + size_t max_out, const uint8_t *in, + size_t in_len, const EVP_MD *md, + const EVP_MD *mgf1_md, int salt_len); + +// RSA_sign_raw signs |in_len| bytes from |in| with the public key from |rsa| +// and writes, at most, |max_out| bytes of signature data to |out|. The +// |max_out| argument must be, at least, |RSA_size| in order to ensure success. +// +// It returns 1 on success or zero on error. +// +// The |padding| argument must be one of the |RSA_*_PADDING| values. If in +// doubt, |RSA_PKCS1_PADDING| is the most common but |RSA_PKCS1_PSS_PADDING| +// (via the |EVP_PKEY| interface) is preferred for new protocols. +OPENSSL_EXPORT int RSA_sign_raw(RSA *rsa, size_t *out_len, uint8_t *out, + size_t max_out, const uint8_t *in, + size_t in_len, int padding); + +// RSA_verify verifies that |sig_len| bytes from |sig| are a valid, +// RSASSA-PKCS1-v1_5 signature of |msg_len| bytes at |msg| by |rsa|. +// +// The |hash_nid| argument identifies the hash function used to calculate |msg| +// and is embedded in the resulting signature in order to prevent hash +// confusion attacks. For example, it might be |NID_sha256|. +// +// It returns one if the signature is valid and zero otherwise. +// +// WARNING: this differs from the original, OpenSSL function which additionally +// returned -1 on error. +OPENSSL_EXPORT int RSA_verify(int hash_nid, const uint8_t *msg, size_t msg_len, + const uint8_t *sig, size_t sig_len, RSA *rsa); + +// RSA_verify_pss_mgf1 verifies that |sig_len| bytes from |sig| are a valid, +// RSASSA-PSS signature of |msg_len| bytes at |msg| by |rsa|. It returns one if +// the signature is valid and zero otherwise. MGF1 is used as the mask +// generation function. +// +// The |md| and |mgf1_md| arguments identify the hash used to calculate |msg| +// and the MGF1 hash, respectively. If |mgf1_md| is NULL, |md| is +// used. |salt_len| specifies the expected salt length in bytes. +// +// If |salt_len| is -1, then the salt length is the same as the hash length. If +// -2, then the salt length is recovered and all values accepted. If unsure, use +// -1. +OPENSSL_EXPORT int RSA_verify_pss_mgf1(RSA *rsa, const uint8_t *msg, + size_t msg_len, const EVP_MD *md, + const EVP_MD *mgf1_md, int salt_len, + const uint8_t *sig, size_t sig_len); + +// RSA_verify_raw verifies |in_len| bytes of signature from |in| using the +// public key from |rsa| and writes, at most, |max_out| bytes of plaintext to +// |out|. The |max_out| argument must be, at least, |RSA_size| in order to +// ensure success. +// +// It returns 1 on success or zero on error. +// +// The |padding| argument must be one of the |RSA_*_PADDING| values. If in +// doubt, |RSA_PKCS1_PADDING| is the most common but |RSA_PKCS1_PSS_PADDING| +// (via the |EVP_PKEY| interface) is preferred for new protocols. +OPENSSL_EXPORT int RSA_verify_raw(RSA *rsa, size_t *out_len, uint8_t *out, + size_t max_out, const uint8_t *in, + size_t in_len, int padding); + +// RSA_private_encrypt encrypts |flen| bytes from |from| with the private key in +// |rsa| and writes the encrypted data to |to|. The |to| buffer must have at +// least |RSA_size| bytes of space. It returns the number of bytes written, or +// -1 on error. The |padding| argument must be one of the |RSA_*_PADDING| +// values. If in doubt, |RSA_PKCS1_PADDING| is the most common but +// |RSA_PKCS1_PSS_PADDING| (via the |EVP_PKEY| interface) is preferred for new +// protocols. +// +// WARNING: this function is dangerous because it breaks the usual return value +// convention. Use |RSA_sign_raw| instead. +OPENSSL_EXPORT int RSA_private_encrypt(size_t flen, const uint8_t *from, + uint8_t *to, RSA *rsa, int padding); + +// RSA_public_decrypt verifies |flen| bytes of signature from |from| using the +// public key in |rsa| and writes the plaintext to |to|. The |to| buffer must +// have at least |RSA_size| bytes of space. It returns the number of bytes +// written, or -1 on error. The |padding| argument must be one of the +// |RSA_*_PADDING| values. If in doubt, |RSA_PKCS1_PADDING| is the most common +// but |RSA_PKCS1_PSS_PADDING| (via the |EVP_PKEY| interface) is preferred for +// new protocols. +// +// WARNING: this function is dangerous because it breaks the usual return value +// convention. Use |RSA_verify_raw| instead. +OPENSSL_EXPORT int RSA_public_decrypt(size_t flen, const uint8_t *from, + uint8_t *to, RSA *rsa, int padding); + + +// Utility functions. + +// RSA_size returns the number of bytes in the modulus, which is also the size +// of a signature or encrypted value using |rsa|. +OPENSSL_EXPORT unsigned RSA_size(const RSA *rsa); + +// RSA_is_opaque returns one if |rsa| is opaque and doesn't expose its key +// material. Otherwise it returns zero. +OPENSSL_EXPORT int RSA_is_opaque(const RSA *rsa); + +// RSAPublicKey_dup allocates a fresh |RSA| and copies the public key from +// |rsa| into it. It returns the fresh |RSA| object, or NULL on error. +OPENSSL_EXPORT RSA *RSAPublicKey_dup(const RSA *rsa); + +// RSAPrivateKey_dup allocates a fresh |RSA| and copies the private key from +// |rsa| into it. It returns the fresh |RSA| object, or NULL on error. +OPENSSL_EXPORT RSA *RSAPrivateKey_dup(const RSA *rsa); + +// RSA_check_key performs basic validity tests on |rsa|. It returns one if +// they pass and zero otherwise. Opaque keys and public keys always pass. If it +// returns zero then a more detailed error is available on the error queue. +OPENSSL_EXPORT int RSA_check_key(const RSA *rsa); + +// RSA_check_fips performs public key validity tests on |key|. It returns one +// if they pass and zero otherwise. Opaque keys always fail. +OPENSSL_EXPORT int RSA_check_fips(RSA *key); + +// RSA_verify_PKCS1_PSS_mgf1 verifies that |EM| is a correct PSS padding of +// |mHash|, where |mHash| is a digest produced by |Hash|. |EM| must point to +// exactly |RSA_size(rsa)| bytes of data. The |mgf1Hash| argument specifies the +// hash function for generating the mask. If NULL, |Hash| is used. The |sLen| +// argument specifies the expected salt length in bytes. If |sLen| is -1 then +// the salt length is the same as the hash length. If -2, then the salt length +// is recovered and all values accepted. +// +// If unsure, use -1. +// +// It returns one on success or zero on error. +// +// This function implements only the low-level padding logic. Use +// |RSA_verify_pss_mgf1| instead. +OPENSSL_EXPORT int RSA_verify_PKCS1_PSS_mgf1(RSA *rsa, const uint8_t *mHash, + const EVP_MD *Hash, + const EVP_MD *mgf1Hash, + const uint8_t *EM, int sLen); + +// RSA_padding_add_PKCS1_PSS_mgf1 writes a PSS padding of |mHash| to |EM|, +// where |mHash| is a digest produced by |Hash|. |RSA_size(rsa)| bytes of +// output will be written to |EM|. The |mgf1Hash| argument specifies the hash +// function for generating the mask. If NULL, |Hash| is used. The |sLen| +// argument specifies the expected salt length in bytes. If |sLen| is -1 then +// the salt length is the same as the hash length. If -2, then the salt length +// is maximal given the space in |EM|. +// +// It returns one on success or zero on error. +// +// This function implements only the low-level padding logic. Use +// |RSA_sign_pss_mgf1| instead. +OPENSSL_EXPORT int RSA_padding_add_PKCS1_PSS_mgf1(RSA *rsa, uint8_t *EM, + const uint8_t *mHash, + const EVP_MD *Hash, + const EVP_MD *mgf1Hash, + int sLen); + +// RSA_padding_add_PKCS1_OAEP_mgf1 writes an OAEP padding of |from| to |to| +// with the given parameters and hash functions. If |md| is NULL then SHA-1 is +// used. If |mgf1md| is NULL then the value of |md| is used (which means SHA-1 +// if that, in turn, is NULL). +// +// It returns one on success or zero on error. +OPENSSL_EXPORT int RSA_padding_add_PKCS1_OAEP_mgf1( + uint8_t *to, size_t to_len, const uint8_t *from, size_t from_len, + const uint8_t *param, size_t param_len, const EVP_MD *md, + const EVP_MD *mgf1md); + +// RSA_add_pkcs1_prefix builds a version of |msg| prefixed with the DigestInfo +// header for the given hash function and sets |out_msg| to point to it. On +// successful return, if |*is_alloced| is one, the caller must release +// |*out_msg| with |OPENSSL_free|. +OPENSSL_EXPORT int RSA_add_pkcs1_prefix(uint8_t **out_msg, size_t *out_msg_len, + int *is_alloced, int hash_nid, + const uint8_t *msg, size_t msg_len); + + +// ASN.1 functions. + +// RSA_parse_public_key parses a DER-encoded RSAPublicKey structure (RFC 3447) +// from |cbs| and advances |cbs|. It returns a newly-allocated |RSA| or NULL on +// error. +OPENSSL_EXPORT RSA *RSA_parse_public_key(CBS *cbs); + +// RSA_public_key_from_bytes parses |in| as a DER-encoded RSAPublicKey structure +// (RFC 3447). It returns a newly-allocated |RSA| or NULL on error. +OPENSSL_EXPORT RSA *RSA_public_key_from_bytes(const uint8_t *in, size_t in_len); + +// RSA_marshal_public_key marshals |rsa| as a DER-encoded RSAPublicKey structure +// (RFC 3447) and appends the result to |cbb|. It returns one on success and +// zero on failure. +OPENSSL_EXPORT int RSA_marshal_public_key(CBB *cbb, const RSA *rsa); + +// RSA_public_key_to_bytes marshals |rsa| as a DER-encoded RSAPublicKey +// structure (RFC 3447) and, on success, sets |*out_bytes| to a newly allocated +// buffer containing the result and returns one. Otherwise, it returns zero. The +// result should be freed with |OPENSSL_free|. +OPENSSL_EXPORT int RSA_public_key_to_bytes(uint8_t **out_bytes, size_t *out_len, + const RSA *rsa); + +// RSA_parse_private_key parses a DER-encoded RSAPrivateKey structure (RFC 3447) +// from |cbs| and advances |cbs|. It returns a newly-allocated |RSA| or NULL on +// error. +OPENSSL_EXPORT RSA *RSA_parse_private_key(CBS *cbs); + +// RSA_private_key_from_bytes parses |in| as a DER-encoded RSAPrivateKey +// structure (RFC 3447). It returns a newly-allocated |RSA| or NULL on error. +OPENSSL_EXPORT RSA *RSA_private_key_from_bytes(const uint8_t *in, + size_t in_len); + +// RSA_marshal_private_key marshals |rsa| as a DER-encoded RSAPrivateKey +// structure (RFC 3447) and appends the result to |cbb|. It returns one on +// success and zero on failure. +OPENSSL_EXPORT int RSA_marshal_private_key(CBB *cbb, const RSA *rsa); + +// RSA_private_key_to_bytes marshals |rsa| as a DER-encoded RSAPrivateKey +// structure (RFC 3447) and, on success, sets |*out_bytes| to a newly allocated +// buffer containing the result and returns one. Otherwise, it returns zero. The +// result should be freed with |OPENSSL_free|. +OPENSSL_EXPORT int RSA_private_key_to_bytes(uint8_t **out_bytes, + size_t *out_len, const RSA *rsa); + + +// ex_data functions. +// +// See |ex_data.h| for details. + +OPENSSL_EXPORT int RSA_get_ex_new_index(long argl, void *argp, + CRYPTO_EX_unused *unused, + CRYPTO_EX_dup *dup_unused, + CRYPTO_EX_free *free_func); +OPENSSL_EXPORT int RSA_set_ex_data(RSA *rsa, int idx, void *arg); +OPENSSL_EXPORT void *RSA_get_ex_data(const RSA *rsa, int idx); + + +// Flags. + +// RSA_FLAG_OPAQUE specifies that this RSA_METHOD does not expose its key +// material. This may be set if, for instance, it is wrapping some other crypto +// API, like a platform key store. +#define RSA_FLAG_OPAQUE 1 + +// RSA_FLAG_NO_BLINDING disables blinding of private operations, which is a +// dangerous thing to do. It is deprecated and should not be used. It will +// be ignored whenever possible. +// +// This flag must be used if a key without the public exponent |e| is used for +// private key operations; avoid using such keys whenever possible. +#define RSA_FLAG_NO_BLINDING 8 + +// RSA_FLAG_EXT_PKEY is deprecated and ignored. +#define RSA_FLAG_EXT_PKEY 0x20 + + +// RSA public exponent values. + +#define RSA_3 0x3 +#define RSA_F4 0x10001 + + +// Deprecated functions. + +#define RSA_METHOD_FLAG_NO_CHECK RSA_FLAG_OPAQUE + +// RSA_flags returns the flags for |rsa|. These are a bitwise OR of |RSA_FLAG_*| +// constants. +OPENSSL_EXPORT int RSA_flags(const RSA *rsa); + +// RSA_blinding_on returns one. +OPENSSL_EXPORT int RSA_blinding_on(RSA *rsa, BN_CTX *ctx); + +// RSA_generate_key behaves like |RSA_generate_key_ex|, which is what you +// should use instead. It returns NULL on error, or a newly-allocated |RSA| on +// success. This function is provided for compatibility only. The |callback| +// and |cb_arg| parameters must be NULL. +OPENSSL_EXPORT RSA *RSA_generate_key(int bits, unsigned long e, void *callback, + void *cb_arg); + +// d2i_RSAPublicKey parses an ASN.1, DER-encoded, RSA public key from |len| +// bytes at |*inp|. If |out| is not NULL then, on exit, a pointer to the result +// is in |*out|. Note that, even if |*out| is already non-NULL on entry, it +// will not be written to. Rather, a fresh |RSA| is allocated and the previous +// one is freed. On successful exit, |*inp| is advanced past the DER structure. +// It returns the result or NULL on error. +OPENSSL_EXPORT RSA *d2i_RSAPublicKey(RSA **out, const uint8_t **inp, long len); + +// i2d_RSAPublicKey marshals |in| to an ASN.1, DER structure. If |outp| is not +// NULL then the result is written to |*outp| and |*outp| is advanced just past +// the output. It returns the number of bytes in the result, whether written or +// not, or a negative value on error. +OPENSSL_EXPORT int i2d_RSAPublicKey(const RSA *in, uint8_t **outp); + +// d2i_RSAPrivateKey parses an ASN.1, DER-encoded, RSA private key from |len| +// bytes at |*inp|. If |out| is not NULL then, on exit, a pointer to the result +// is in |*out|. Note that, even if |*out| is already non-NULL on entry, it +// will not be written to. Rather, a fresh |RSA| is allocated and the previous +// one is freed. On successful exit, |*inp| is advanced past the DER structure. +// It returns the result or NULL on error. +OPENSSL_EXPORT RSA *d2i_RSAPrivateKey(RSA **out, const uint8_t **inp, long len); + +// i2d_RSAPrivateKey marshals |in| to an ASN.1, DER structure. If |outp| is not +// NULL then the result is written to |*outp| and |*outp| is advanced just past +// the output. It returns the number of bytes in the result, whether written or +// not, or a negative value on error. +OPENSSL_EXPORT int i2d_RSAPrivateKey(const RSA *in, uint8_t **outp); + +// RSA_padding_add_PKCS1_PSS acts like |RSA_padding_add_PKCS1_PSS_mgf1| but the +// |mgf1Hash| parameter of the latter is implicitly set to |Hash|. +// +// This function implements only the low-level padding logic. Use +// |RSA_sign_pss_mgf1| instead. +OPENSSL_EXPORT int RSA_padding_add_PKCS1_PSS(RSA *rsa, uint8_t *EM, + const uint8_t *mHash, + const EVP_MD *Hash, int sLen); + +// RSA_verify_PKCS1_PSS acts like |RSA_verify_PKCS1_PSS_mgf1| but the +// |mgf1Hash| parameter of the latter is implicitly set to |Hash|. +// +// This function implements only the low-level padding logic. Use +// |RSA_verify_pss_mgf1| instead. +OPENSSL_EXPORT int RSA_verify_PKCS1_PSS(RSA *rsa, const uint8_t *mHash, + const EVP_MD *Hash, const uint8_t *EM, + int sLen); + +// RSA_padding_add_PKCS1_OAEP acts like |RSA_padding_add_PKCS1_OAEP_mgf1| but +// the |md| and |mgf1md| parameters of the latter are implicitly set to NULL, +// which means SHA-1. +OPENSSL_EXPORT int RSA_padding_add_PKCS1_OAEP(uint8_t *to, size_t to_len, + const uint8_t *from, + size_t from_len, + const uint8_t *param, + size_t param_len); + + +struct rsa_meth_st { + struct openssl_method_common_st common; + + void *app_data; + + int (*init)(RSA *rsa); + int (*finish)(RSA *rsa); + + // size returns the size of the RSA modulus in bytes. + size_t (*size)(const RSA *rsa); + + int (*sign)(int type, const uint8_t *m, unsigned int m_length, + uint8_t *sigret, unsigned int *siglen, const RSA *rsa); + + // These functions mirror the |RSA_*| functions of the same name. + int (*sign_raw)(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out, + const uint8_t *in, size_t in_len, int padding); + int (*decrypt)(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out, + const uint8_t *in, size_t in_len, int padding); + + // private_transform takes a big-endian integer from |in|, calculates the + // d'th power of it, modulo the RSA modulus and writes the result as a + // big-endian integer to |out|. Both |in| and |out| are |len| bytes long and + // |len| is always equal to |RSA_size(rsa)|. If the result of the transform + // can be represented in fewer than |len| bytes, then |out| must be zero + // padded on the left. + // + // It returns one on success and zero otherwise. + // + // RSA decrypt and sign operations will call this, thus an ENGINE might wish + // to override it in order to avoid having to implement the padding + // functionality demanded by those, higher level, operations. + int (*private_transform)(RSA *rsa, uint8_t *out, const uint8_t *in, + size_t len); + + int flags; +}; + + +// Private functions. + +typedef struct bn_blinding_st BN_BLINDING; + +struct rsa_st { + RSA_METHOD *meth; + + // Access to the following fields was historically allowed, but + // deprecated. Use |RSA_get0_*| and |RSA_set0_*| instead. Access to all other + // fields is forbidden and will cause threading errors. + 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; + CRYPTO_refcount_t references; + int flags; + + CRYPTO_MUTEX lock; + + // Used to cache montgomery values. The creation of these values is protected + // by |lock|. + BN_MONT_CTX *mont_n; + BN_MONT_CTX *mont_p; + BN_MONT_CTX *mont_q; + + // The following fields are copies of |d|, |dmp1|, and |dmq1|, respectively, + // but with the correct widths to prevent side channels. These must use + // separate copies due to threading concerns caused by OpenSSL's API + // mistakes. See https://github.com/openssl/openssl/issues/5158 and + // the |freeze_private_key| implementation. + BIGNUM *d_fixed, *dmp1_fixed, *dmq1_fixed; + + // inv_small_mod_large_mont is q^-1 mod p in Montgomery form, using |mont_p|, + // if |p| >= |q|. Otherwise, it is p^-1 mod q in Montgomery form, using + // |mont_q|. + BIGNUM *inv_small_mod_large_mont; + + // num_blindings contains the size of the |blindings| and |blindings_inuse| + // arrays. This member and the |blindings_inuse| array are protected by + // |lock|. + unsigned num_blindings; + // blindings is an array of BN_BLINDING structures that can be reserved by a + // thread by locking |lock| and changing the corresponding element in + // |blindings_inuse| from 0 to 1. + BN_BLINDING **blindings; + unsigned char *blindings_inuse; + + // private_key_frozen is one if the key has been used for a private key + // operation and may no longer be mutated. + unsigned private_key_frozen:1; +}; + + +#if defined(__cplusplus) +} // extern C + +extern "C++" { + +namespace bssl { + +BORINGSSL_MAKE_DELETER(RSA, RSA_free) + +} // namespace bssl + +} // extern C++ + +#endif + +#define RSA_R_BAD_ENCODING 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_RSA_PARAMETERS 104 +#define RSA_R_BAD_SIGNATURE 105 +#define RSA_R_BAD_VERSION 106 +#define RSA_R_BLOCK_TYPE_IS_NOT_01 107 +#define RSA_R_BN_NOT_INITIALIZED 108 +#define RSA_R_CANNOT_RECOVER_MULTI_PRIME_KEY 109 +#define RSA_R_CRT_PARAMS_ALREADY_GIVEN 110 +#define RSA_R_CRT_VALUES_INCORRECT 111 +#define RSA_R_DATA_LEN_NOT_EQUAL_TO_MOD_LEN 112 +#define RSA_R_DATA_TOO_LARGE 113 +#define RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE 114 +#define RSA_R_DATA_TOO_LARGE_FOR_MODULUS 115 +#define RSA_R_DATA_TOO_SMALL 116 +#define RSA_R_DATA_TOO_SMALL_FOR_KEY_SIZE 117 +#define RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY 118 +#define RSA_R_D_E_NOT_CONGRUENT_TO_1 119 +#define RSA_R_EMPTY_PUBLIC_KEY 120 +#define RSA_R_ENCODE_ERROR 121 +#define RSA_R_FIRST_OCTET_INVALID 122 +#define RSA_R_INCONSISTENT_SET_OF_CRT_VALUES 123 +#define RSA_R_INTERNAL_ERROR 124 +#define RSA_R_INVALID_MESSAGE_LENGTH 125 +#define RSA_R_KEY_SIZE_TOO_SMALL 126 +#define RSA_R_LAST_OCTET_INVALID 127 +#define RSA_R_MODULUS_TOO_LARGE 128 +#define RSA_R_MUST_HAVE_AT_LEAST_TWO_PRIMES 129 +#define RSA_R_NO_PUBLIC_EXPONENT 130 +#define RSA_R_NULL_BEFORE_BLOCK_MISSING 131 +#define RSA_R_N_NOT_EQUAL_P_Q 132 +#define RSA_R_OAEP_DECODING_ERROR 133 +#define RSA_R_ONLY_ONE_OF_P_Q_GIVEN 134 +#define RSA_R_OUTPUT_BUFFER_TOO_SMALL 135 +#define RSA_R_PADDING_CHECK_FAILED 136 +#define RSA_R_PKCS_DECODING_ERROR 137 +#define RSA_R_SLEN_CHECK_FAILED 138 +#define RSA_R_SLEN_RECOVERY_FAILED 139 +#define RSA_R_TOO_LONG 140 +#define RSA_R_TOO_MANY_ITERATIONS 141 +#define RSA_R_UNKNOWN_ALGORITHM_TYPE 142 +#define RSA_R_UNKNOWN_PADDING_TYPE 143 +#define RSA_R_VALUE_MISSING 144 +#define RSA_R_WRONG_SIGNATURE_LENGTH 145 +#define RSA_R_PUBLIC_KEY_VALIDATION_FAILED 146 +#define RSA_R_D_OUT_OF_RANGE 147 + +#endif // OPENSSL_HEADER_RSA_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/rsa.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/rsa.h.grpc_back new file mode 100644 index 0000000..a52fa53 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/rsa.h.grpc_back @@ -0,0 +1,756 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 OPENSSL_HEADER_RSA_H +#define OPENSSL_HEADER_RSA_H + +#include + +#include +#include +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// rsa.h contains functions for handling encryption and signature using RSA. + + +// Allocation and destruction. + +// RSA_new returns a new, empty RSA object or NULL on error. +OPENSSL_EXPORT RSA *RSA_new(void); + +// RSA_new_method acts the same as |RSA_new| but takes an explicit |ENGINE|. +OPENSSL_EXPORT RSA *RSA_new_method(const ENGINE *engine); + +// RSA_free decrements the reference count of |rsa| and frees it if the +// reference count drops to zero. +OPENSSL_EXPORT void RSA_free(RSA *rsa); + +// RSA_up_ref increments the reference count of |rsa| and returns one. +OPENSSL_EXPORT int RSA_up_ref(RSA *rsa); + + +// Properties. + +// RSA_bits returns the size of |rsa|, in bits. +OPENSSL_EXPORT unsigned RSA_bits(const RSA *rsa); + +// RSA_get0_key sets |*out_n|, |*out_e|, and |*out_d|, if non-NULL, to |rsa|'s +// modulus, public exponent, and private exponent, respectively. If |rsa| is a +// public key, the private exponent will be set to NULL. +OPENSSL_EXPORT void RSA_get0_key(const RSA *rsa, const BIGNUM **out_n, + const BIGNUM **out_e, const BIGNUM **out_d); + +// RSA_get0_factors sets |*out_p| and |*out_q|, if non-NULL, to |rsa|'s prime +// factors. If |rsa| is a public key, they will be set to NULL. +OPENSSL_EXPORT void RSA_get0_factors(const RSA *rsa, const BIGNUM **out_p, + const BIGNUM **out_q); + +// RSA_get0_crt_params sets |*out_dmp1|, |*out_dmq1|, and |*out_iqmp|, if +// non-NULL, to |rsa|'s CRT parameters. These are d (mod p-1), d (mod q-1) and +// q^-1 (mod p), respectively. If |rsa| is a public key, each parameter will be +// set to NULL. +OPENSSL_EXPORT void RSA_get0_crt_params(const RSA *rsa, const BIGNUM **out_dmp1, + const BIGNUM **out_dmq1, + const BIGNUM **out_iqmp); + +// RSA_set0_key sets |rsa|'s modulus, public exponent, and private exponent to +// |n|, |e|, and |d| respectively, if non-NULL. On success, it takes ownership +// of each argument and returns one. Otherwise, it returns zero. +// +// |d| may be NULL, but |n| and |e| must either be non-NULL or already +// configured on |rsa|. +// +// It is an error to call this function after |rsa| has been used for a +// cryptographic operation. Construct a new |RSA| object instead. +OPENSSL_EXPORT int RSA_set0_key(RSA *rsa, BIGNUM *n, BIGNUM *e, BIGNUM *d); + +// RSA_set0_factors sets |rsa|'s prime factors to |p| and |q|, if non-NULL, and +// takes ownership of them. On success, it takes ownership of each argument and +// returns one. Otherwise, it returns zero. +// +// Each argument must either be non-NULL or already configured on |rsa|. +// +// It is an error to call this function after |rsa| has been used for a +// cryptographic operation. Construct a new |RSA| object instead. +OPENSSL_EXPORT int RSA_set0_factors(RSA *rsa, BIGNUM *p, BIGNUM *q); + +// RSA_set0_crt_params sets |rsa|'s CRT parameters to |dmp1|, |dmq1|, and +// |iqmp|, if non-NULL, and takes ownership of them. On success, it takes +// ownership of its parameters and returns one. Otherwise, it returns zero. +// +// Each argument must either be non-NULL or already configured on |rsa|. +// +// It is an error to call this function after |rsa| has been used for a +// cryptographic operation. Construct a new |RSA| object instead. +OPENSSL_EXPORT int RSA_set0_crt_params(RSA *rsa, BIGNUM *dmp1, BIGNUM *dmq1, + BIGNUM *iqmp); + + +// Key generation. + +// RSA_generate_key_ex generates a new RSA key where the modulus has size +// |bits| and the public exponent is |e|. If unsure, |RSA_F4| is a good value +// for |e|. If |cb| is not NULL then it is called during the key generation +// process. In addition to the calls documented for |BN_generate_prime_ex|, it +// is called with event=2 when the n'th prime is rejected as unsuitable and +// with event=3 when a suitable value for |p| is found. +// +// It returns one on success or zero on error. +OPENSSL_EXPORT int RSA_generate_key_ex(RSA *rsa, int bits, BIGNUM *e, + BN_GENCB *cb); + +// RSA_generate_key_fips behaves like |RSA_generate_key_ex| but performs +// additional checks for FIPS compliance. The public exponent is always 65537 +// and |bits| must be either 2048 or 3072. +OPENSSL_EXPORT int RSA_generate_key_fips(RSA *rsa, int bits, BN_GENCB *cb); + + +// Encryption / Decryption + +// Padding types for encryption. +#define RSA_PKCS1_PADDING 1 +#define RSA_NO_PADDING 3 +#define RSA_PKCS1_OAEP_PADDING 4 +// RSA_PKCS1_PSS_PADDING can only be used via the EVP interface. +#define RSA_PKCS1_PSS_PADDING 6 + +// RSA_encrypt encrypts |in_len| bytes from |in| to the public key from |rsa| +// and writes, at most, |max_out| bytes of encrypted data to |out|. The +// |max_out| argument must be, at least, |RSA_size| in order to ensure success. +// +// It returns 1 on success or zero on error. +// +// The |padding| argument must be one of the |RSA_*_PADDING| values. If in +// doubt, use |RSA_PKCS1_OAEP_PADDING| for new protocols but +// |RSA_PKCS1_PADDING| is most common. +OPENSSL_EXPORT int RSA_encrypt(RSA *rsa, size_t *out_len, uint8_t *out, + size_t max_out, const uint8_t *in, size_t in_len, + int padding); + +// RSA_decrypt decrypts |in_len| bytes from |in| with the private key from +// |rsa| and writes, at most, |max_out| bytes of plaintext to |out|. The +// |max_out| argument must be, at least, |RSA_size| in order to ensure success. +// +// It returns 1 on success or zero on error. +// +// The |padding| argument must be one of the |RSA_*_PADDING| values. If in +// doubt, use |RSA_PKCS1_OAEP_PADDING| for new protocols. +// +// Passing |RSA_PKCS1_PADDING| into this function is deprecated and insecure. If +// implementing a protocol using RSAES-PKCS1-V1_5, use |RSA_NO_PADDING| and then +// check padding in constant-time combined with a swap to a random session key +// or other mitigation. See "Chosen Ciphertext Attacks Against Protocols Based +// on the RSA Encryption Standard PKCS #1", Daniel Bleichenbacher, Advances in +// Cryptology (Crypto '98). +OPENSSL_EXPORT int RSA_decrypt(RSA *rsa, size_t *out_len, uint8_t *out, + size_t max_out, const uint8_t *in, size_t in_len, + int padding); + +// RSA_public_encrypt encrypts |flen| bytes from |from| to the public key in +// |rsa| and writes the encrypted data to |to|. The |to| buffer must have at +// least |RSA_size| bytes of space. It returns the number of bytes written, or +// -1 on error. The |padding| argument must be one of the |RSA_*_PADDING| +// values. If in doubt, use |RSA_PKCS1_OAEP_PADDING| for new protocols but +// |RSA_PKCS1_PADDING| is most common. +// +// WARNING: this function is dangerous because it breaks the usual return value +// convention. Use |RSA_encrypt| instead. +OPENSSL_EXPORT int RSA_public_encrypt(size_t flen, const uint8_t *from, + uint8_t *to, RSA *rsa, int padding); + +// RSA_private_decrypt decrypts |flen| bytes from |from| with the public key in +// |rsa| and writes the plaintext to |to|. The |to| buffer must have at least +// |RSA_size| bytes of space. It returns the number of bytes written, or -1 on +// error. The |padding| argument must be one of the |RSA_*_PADDING| values. If +// in doubt, use |RSA_PKCS1_OAEP_PADDING| for new protocols. Passing +// |RSA_PKCS1_PADDING| into this function is deprecated and insecure. See +// |RSA_decrypt|. +// +// WARNING: this function is dangerous because it breaks the usual return value +// convention. Use |RSA_decrypt| instead. +OPENSSL_EXPORT int RSA_private_decrypt(size_t flen, const uint8_t *from, + uint8_t *to, RSA *rsa, int padding); + + +// Signing / Verification + +// RSA_sign signs |in_len| bytes of digest from |in| with |rsa| using +// RSASSA-PKCS1-v1_5. It writes, at most, |RSA_size(rsa)| bytes to |out|. On +// successful return, the actual number of bytes written is written to +// |*out_len|. +// +// The |hash_nid| argument identifies the hash function used to calculate |in| +// and is embedded in the resulting signature. For example, it might be +// |NID_sha256|. +// +// It returns 1 on success and zero on error. +OPENSSL_EXPORT int RSA_sign(int hash_nid, const uint8_t *in, + unsigned int in_len, uint8_t *out, + unsigned int *out_len, RSA *rsa); + +// RSA_sign_pss_mgf1 signs |in_len| bytes from |in| with the public key from +// |rsa| using RSASSA-PSS with MGF1 as the mask generation function. It writes, +// at most, |max_out| bytes of signature data to |out|. The |max_out| argument +// must be, at least, |RSA_size| in order to ensure success. It returns 1 on +// success or zero on error. +// +// The |md| and |mgf1_md| arguments identify the hash used to calculate |msg| +// and the MGF1 hash, respectively. If |mgf1_md| is NULL, |md| is +// used. +// +// |salt_len| specifies the expected salt length in bytes. If |salt_len| is -1, +// then the salt length is the same as the hash length. If -2, then the salt +// length is maximal given the size of |rsa|. If unsure, use -1. +OPENSSL_EXPORT int RSA_sign_pss_mgf1(RSA *rsa, size_t *out_len, uint8_t *out, + size_t max_out, const uint8_t *in, + size_t in_len, const EVP_MD *md, + const EVP_MD *mgf1_md, int salt_len); + +// RSA_sign_raw signs |in_len| bytes from |in| with the public key from |rsa| +// and writes, at most, |max_out| bytes of signature data to |out|. The +// |max_out| argument must be, at least, |RSA_size| in order to ensure success. +// +// It returns 1 on success or zero on error. +// +// The |padding| argument must be one of the |RSA_*_PADDING| values. If in +// doubt, |RSA_PKCS1_PADDING| is the most common but |RSA_PKCS1_PSS_PADDING| +// (via the |EVP_PKEY| interface) is preferred for new protocols. +OPENSSL_EXPORT int RSA_sign_raw(RSA *rsa, size_t *out_len, uint8_t *out, + size_t max_out, const uint8_t *in, + size_t in_len, int padding); + +// RSA_verify verifies that |sig_len| bytes from |sig| are a valid, +// RSASSA-PKCS1-v1_5 signature of |msg_len| bytes at |msg| by |rsa|. +// +// The |hash_nid| argument identifies the hash function used to calculate |msg| +// and is embedded in the resulting signature in order to prevent hash +// confusion attacks. For example, it might be |NID_sha256|. +// +// It returns one if the signature is valid and zero otherwise. +// +// WARNING: this differs from the original, OpenSSL function which additionally +// returned -1 on error. +OPENSSL_EXPORT int RSA_verify(int hash_nid, const uint8_t *msg, size_t msg_len, + const uint8_t *sig, size_t sig_len, RSA *rsa); + +// RSA_verify_pss_mgf1 verifies that |sig_len| bytes from |sig| are a valid, +// RSASSA-PSS signature of |msg_len| bytes at |msg| by |rsa|. It returns one if +// the signature is valid and zero otherwise. MGF1 is used as the mask +// generation function. +// +// The |md| and |mgf1_md| arguments identify the hash used to calculate |msg| +// and the MGF1 hash, respectively. If |mgf1_md| is NULL, |md| is +// used. |salt_len| specifies the expected salt length in bytes. +// +// If |salt_len| is -1, then the salt length is the same as the hash length. If +// -2, then the salt length is recovered and all values accepted. If unsure, use +// -1. +OPENSSL_EXPORT int RSA_verify_pss_mgf1(RSA *rsa, const uint8_t *msg, + size_t msg_len, const EVP_MD *md, + const EVP_MD *mgf1_md, int salt_len, + const uint8_t *sig, size_t sig_len); + +// RSA_verify_raw verifies |in_len| bytes of signature from |in| using the +// public key from |rsa| and writes, at most, |max_out| bytes of plaintext to +// |out|. The |max_out| argument must be, at least, |RSA_size| in order to +// ensure success. +// +// It returns 1 on success or zero on error. +// +// The |padding| argument must be one of the |RSA_*_PADDING| values. If in +// doubt, |RSA_PKCS1_PADDING| is the most common but |RSA_PKCS1_PSS_PADDING| +// (via the |EVP_PKEY| interface) is preferred for new protocols. +OPENSSL_EXPORT int RSA_verify_raw(RSA *rsa, size_t *out_len, uint8_t *out, + size_t max_out, const uint8_t *in, + size_t in_len, int padding); + +// RSA_private_encrypt encrypts |flen| bytes from |from| with the private key in +// |rsa| and writes the encrypted data to |to|. The |to| buffer must have at +// least |RSA_size| bytes of space. It returns the number of bytes written, or +// -1 on error. The |padding| argument must be one of the |RSA_*_PADDING| +// values. If in doubt, |RSA_PKCS1_PADDING| is the most common but +// |RSA_PKCS1_PSS_PADDING| (via the |EVP_PKEY| interface) is preferred for new +// protocols. +// +// WARNING: this function is dangerous because it breaks the usual return value +// convention. Use |RSA_sign_raw| instead. +OPENSSL_EXPORT int RSA_private_encrypt(size_t flen, const uint8_t *from, + uint8_t *to, RSA *rsa, int padding); + +// RSA_public_decrypt verifies |flen| bytes of signature from |from| using the +// public key in |rsa| and writes the plaintext to |to|. The |to| buffer must +// have at least |RSA_size| bytes of space. It returns the number of bytes +// written, or -1 on error. The |padding| argument must be one of the +// |RSA_*_PADDING| values. If in doubt, |RSA_PKCS1_PADDING| is the most common +// but |RSA_PKCS1_PSS_PADDING| (via the |EVP_PKEY| interface) is preferred for +// new protocols. +// +// WARNING: this function is dangerous because it breaks the usual return value +// convention. Use |RSA_verify_raw| instead. +OPENSSL_EXPORT int RSA_public_decrypt(size_t flen, const uint8_t *from, + uint8_t *to, RSA *rsa, int padding); + + +// Utility functions. + +// RSA_size returns the number of bytes in the modulus, which is also the size +// of a signature or encrypted value using |rsa|. +OPENSSL_EXPORT unsigned RSA_size(const RSA *rsa); + +// RSA_is_opaque returns one if |rsa| is opaque and doesn't expose its key +// material. Otherwise it returns zero. +OPENSSL_EXPORT int RSA_is_opaque(const RSA *rsa); + +// RSAPublicKey_dup allocates a fresh |RSA| and copies the public key from +// |rsa| into it. It returns the fresh |RSA| object, or NULL on error. +OPENSSL_EXPORT RSA *RSAPublicKey_dup(const RSA *rsa); + +// RSAPrivateKey_dup allocates a fresh |RSA| and copies the private key from +// |rsa| into it. It returns the fresh |RSA| object, or NULL on error. +OPENSSL_EXPORT RSA *RSAPrivateKey_dup(const RSA *rsa); + +// RSA_check_key performs basic validity tests on |rsa|. It returns one if +// they pass and zero otherwise. Opaque keys and public keys always pass. If it +// returns zero then a more detailed error is available on the error queue. +OPENSSL_EXPORT int RSA_check_key(const RSA *rsa); + +// RSA_check_fips performs public key validity tests on |key|. It returns one +// if they pass and zero otherwise. Opaque keys always fail. +OPENSSL_EXPORT int RSA_check_fips(RSA *key); + +// RSA_verify_PKCS1_PSS_mgf1 verifies that |EM| is a correct PSS padding of +// |mHash|, where |mHash| is a digest produced by |Hash|. |EM| must point to +// exactly |RSA_size(rsa)| bytes of data. The |mgf1Hash| argument specifies the +// hash function for generating the mask. If NULL, |Hash| is used. The |sLen| +// argument specifies the expected salt length in bytes. If |sLen| is -1 then +// the salt length is the same as the hash length. If -2, then the salt length +// is recovered and all values accepted. +// +// If unsure, use -1. +// +// It returns one on success or zero on error. +// +// This function implements only the low-level padding logic. Use +// |RSA_verify_pss_mgf1| instead. +OPENSSL_EXPORT int RSA_verify_PKCS1_PSS_mgf1(RSA *rsa, const uint8_t *mHash, + const EVP_MD *Hash, + const EVP_MD *mgf1Hash, + const uint8_t *EM, int sLen); + +// RSA_padding_add_PKCS1_PSS_mgf1 writes a PSS padding of |mHash| to |EM|, +// where |mHash| is a digest produced by |Hash|. |RSA_size(rsa)| bytes of +// output will be written to |EM|. The |mgf1Hash| argument specifies the hash +// function for generating the mask. If NULL, |Hash| is used. The |sLen| +// argument specifies the expected salt length in bytes. If |sLen| is -1 then +// the salt length is the same as the hash length. If -2, then the salt length +// is maximal given the space in |EM|. +// +// It returns one on success or zero on error. +// +// This function implements only the low-level padding logic. Use +// |RSA_sign_pss_mgf1| instead. +OPENSSL_EXPORT int RSA_padding_add_PKCS1_PSS_mgf1(RSA *rsa, uint8_t *EM, + const uint8_t *mHash, + const EVP_MD *Hash, + const EVP_MD *mgf1Hash, + int sLen); + +// RSA_padding_add_PKCS1_OAEP_mgf1 writes an OAEP padding of |from| to |to| +// with the given parameters and hash functions. If |md| is NULL then SHA-1 is +// used. If |mgf1md| is NULL then the value of |md| is used (which means SHA-1 +// if that, in turn, is NULL). +// +// It returns one on success or zero on error. +OPENSSL_EXPORT int RSA_padding_add_PKCS1_OAEP_mgf1( + uint8_t *to, size_t to_len, const uint8_t *from, size_t from_len, + const uint8_t *param, size_t param_len, const EVP_MD *md, + const EVP_MD *mgf1md); + +// RSA_add_pkcs1_prefix builds a version of |msg| prefixed with the DigestInfo +// header for the given hash function and sets |out_msg| to point to it. On +// successful return, if |*is_alloced| is one, the caller must release +// |*out_msg| with |OPENSSL_free|. +OPENSSL_EXPORT int RSA_add_pkcs1_prefix(uint8_t **out_msg, size_t *out_msg_len, + int *is_alloced, int hash_nid, + const uint8_t *msg, size_t msg_len); + + +// ASN.1 functions. + +// RSA_parse_public_key parses a DER-encoded RSAPublicKey structure (RFC 3447) +// from |cbs| and advances |cbs|. It returns a newly-allocated |RSA| or NULL on +// error. +OPENSSL_EXPORT RSA *RSA_parse_public_key(CBS *cbs); + +// RSA_public_key_from_bytes parses |in| as a DER-encoded RSAPublicKey structure +// (RFC 3447). It returns a newly-allocated |RSA| or NULL on error. +OPENSSL_EXPORT RSA *RSA_public_key_from_bytes(const uint8_t *in, size_t in_len); + +// RSA_marshal_public_key marshals |rsa| as a DER-encoded RSAPublicKey structure +// (RFC 3447) and appends the result to |cbb|. It returns one on success and +// zero on failure. +OPENSSL_EXPORT int RSA_marshal_public_key(CBB *cbb, const RSA *rsa); + +// RSA_public_key_to_bytes marshals |rsa| as a DER-encoded RSAPublicKey +// structure (RFC 3447) and, on success, sets |*out_bytes| to a newly allocated +// buffer containing the result and returns one. Otherwise, it returns zero. The +// result should be freed with |OPENSSL_free|. +OPENSSL_EXPORT int RSA_public_key_to_bytes(uint8_t **out_bytes, size_t *out_len, + const RSA *rsa); + +// RSA_parse_private_key parses a DER-encoded RSAPrivateKey structure (RFC 3447) +// from |cbs| and advances |cbs|. It returns a newly-allocated |RSA| or NULL on +// error. +OPENSSL_EXPORT RSA *RSA_parse_private_key(CBS *cbs); + +// RSA_private_key_from_bytes parses |in| as a DER-encoded RSAPrivateKey +// structure (RFC 3447). It returns a newly-allocated |RSA| or NULL on error. +OPENSSL_EXPORT RSA *RSA_private_key_from_bytes(const uint8_t *in, + size_t in_len); + +// RSA_marshal_private_key marshals |rsa| as a DER-encoded RSAPrivateKey +// structure (RFC 3447) and appends the result to |cbb|. It returns one on +// success and zero on failure. +OPENSSL_EXPORT int RSA_marshal_private_key(CBB *cbb, const RSA *rsa); + +// RSA_private_key_to_bytes marshals |rsa| as a DER-encoded RSAPrivateKey +// structure (RFC 3447) and, on success, sets |*out_bytes| to a newly allocated +// buffer containing the result and returns one. Otherwise, it returns zero. The +// result should be freed with |OPENSSL_free|. +OPENSSL_EXPORT int RSA_private_key_to_bytes(uint8_t **out_bytes, + size_t *out_len, const RSA *rsa); + + +// ex_data functions. +// +// See |ex_data.h| for details. + +OPENSSL_EXPORT int RSA_get_ex_new_index(long argl, void *argp, + CRYPTO_EX_unused *unused, + CRYPTO_EX_dup *dup_unused, + CRYPTO_EX_free *free_func); +OPENSSL_EXPORT int RSA_set_ex_data(RSA *rsa, int idx, void *arg); +OPENSSL_EXPORT void *RSA_get_ex_data(const RSA *rsa, int idx); + + +// Flags. + +// RSA_FLAG_OPAQUE specifies that this RSA_METHOD does not expose its key +// material. This may be set if, for instance, it is wrapping some other crypto +// API, like a platform key store. +#define RSA_FLAG_OPAQUE 1 + +// RSA_FLAG_NO_BLINDING disables blinding of private operations, which is a +// dangerous thing to do. It is deprecated and should not be used. It will +// be ignored whenever possible. +// +// This flag must be used if a key without the public exponent |e| is used for +// private key operations; avoid using such keys whenever possible. +#define RSA_FLAG_NO_BLINDING 8 + +// RSA_FLAG_EXT_PKEY is deprecated and ignored. +#define RSA_FLAG_EXT_PKEY 0x20 + + +// RSA public exponent values. + +#define RSA_3 0x3 +#define RSA_F4 0x10001 + + +// Deprecated functions. + +#define RSA_METHOD_FLAG_NO_CHECK RSA_FLAG_OPAQUE + +// RSA_flags returns the flags for |rsa|. These are a bitwise OR of |RSA_FLAG_*| +// constants. +OPENSSL_EXPORT int RSA_flags(const RSA *rsa); + +// RSA_blinding_on returns one. +OPENSSL_EXPORT int RSA_blinding_on(RSA *rsa, BN_CTX *ctx); + +// RSA_generate_key behaves like |RSA_generate_key_ex|, which is what you +// should use instead. It returns NULL on error, or a newly-allocated |RSA| on +// success. This function is provided for compatibility only. The |callback| +// and |cb_arg| parameters must be NULL. +OPENSSL_EXPORT RSA *RSA_generate_key(int bits, unsigned long e, void *callback, + void *cb_arg); + +// d2i_RSAPublicKey parses an ASN.1, DER-encoded, RSA public key from |len| +// bytes at |*inp|. If |out| is not NULL then, on exit, a pointer to the result +// is in |*out|. Note that, even if |*out| is already non-NULL on entry, it +// will not be written to. Rather, a fresh |RSA| is allocated and the previous +// one is freed. On successful exit, |*inp| is advanced past the DER structure. +// It returns the result or NULL on error. +OPENSSL_EXPORT RSA *d2i_RSAPublicKey(RSA **out, const uint8_t **inp, long len); + +// i2d_RSAPublicKey marshals |in| to an ASN.1, DER structure. If |outp| is not +// NULL then the result is written to |*outp| and |*outp| is advanced just past +// the output. It returns the number of bytes in the result, whether written or +// not, or a negative value on error. +OPENSSL_EXPORT int i2d_RSAPublicKey(const RSA *in, uint8_t **outp); + +// d2i_RSAPrivateKey parses an ASN.1, DER-encoded, RSA private key from |len| +// bytes at |*inp|. If |out| is not NULL then, on exit, a pointer to the result +// is in |*out|. Note that, even if |*out| is already non-NULL on entry, it +// will not be written to. Rather, a fresh |RSA| is allocated and the previous +// one is freed. On successful exit, |*inp| is advanced past the DER structure. +// It returns the result or NULL on error. +OPENSSL_EXPORT RSA *d2i_RSAPrivateKey(RSA **out, const uint8_t **inp, long len); + +// i2d_RSAPrivateKey marshals |in| to an ASN.1, DER structure. If |outp| is not +// NULL then the result is written to |*outp| and |*outp| is advanced just past +// the output. It returns the number of bytes in the result, whether written or +// not, or a negative value on error. +OPENSSL_EXPORT int i2d_RSAPrivateKey(const RSA *in, uint8_t **outp); + +// RSA_padding_add_PKCS1_PSS acts like |RSA_padding_add_PKCS1_PSS_mgf1| but the +// |mgf1Hash| parameter of the latter is implicitly set to |Hash|. +// +// This function implements only the low-level padding logic. Use +// |RSA_sign_pss_mgf1| instead. +OPENSSL_EXPORT int RSA_padding_add_PKCS1_PSS(RSA *rsa, uint8_t *EM, + const uint8_t *mHash, + const EVP_MD *Hash, int sLen); + +// RSA_verify_PKCS1_PSS acts like |RSA_verify_PKCS1_PSS_mgf1| but the +// |mgf1Hash| parameter of the latter is implicitly set to |Hash|. +// +// This function implements only the low-level padding logic. Use +// |RSA_verify_pss_mgf1| instead. +OPENSSL_EXPORT int RSA_verify_PKCS1_PSS(RSA *rsa, const uint8_t *mHash, + const EVP_MD *Hash, const uint8_t *EM, + int sLen); + +// RSA_padding_add_PKCS1_OAEP acts like |RSA_padding_add_PKCS1_OAEP_mgf1| but +// the |md| and |mgf1md| parameters of the latter are implicitly set to NULL, +// which means SHA-1. +OPENSSL_EXPORT int RSA_padding_add_PKCS1_OAEP(uint8_t *to, size_t to_len, + const uint8_t *from, + size_t from_len, + const uint8_t *param, + size_t param_len); + + +struct rsa_meth_st { + struct openssl_method_common_st common; + + void *app_data; + + int (*init)(RSA *rsa); + int (*finish)(RSA *rsa); + + // size returns the size of the RSA modulus in bytes. + size_t (*size)(const RSA *rsa); + + int (*sign)(int type, const uint8_t *m, unsigned int m_length, + uint8_t *sigret, unsigned int *siglen, const RSA *rsa); + + // These functions mirror the |RSA_*| functions of the same name. + int (*sign_raw)(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out, + const uint8_t *in, size_t in_len, int padding); + int (*decrypt)(RSA *rsa, size_t *out_len, uint8_t *out, size_t max_out, + const uint8_t *in, size_t in_len, int padding); + + // private_transform takes a big-endian integer from |in|, calculates the + // d'th power of it, modulo the RSA modulus and writes the result as a + // big-endian integer to |out|. Both |in| and |out| are |len| bytes long and + // |len| is always equal to |RSA_size(rsa)|. If the result of the transform + // can be represented in fewer than |len| bytes, then |out| must be zero + // padded on the left. + // + // It returns one on success and zero otherwise. + // + // RSA decrypt and sign operations will call this, thus an ENGINE might wish + // to override it in order to avoid having to implement the padding + // functionality demanded by those, higher level, operations. + int (*private_transform)(RSA *rsa, uint8_t *out, const uint8_t *in, + size_t len); + + int flags; +}; + + +// Private functions. + +typedef struct bn_blinding_st BN_BLINDING; + +struct rsa_st { + RSA_METHOD *meth; + + // Access to the following fields was historically allowed, but + // deprecated. Use |RSA_get0_*| and |RSA_set0_*| instead. Access to all other + // fields is forbidden and will cause threading errors. + 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; + CRYPTO_refcount_t references; + int flags; + + CRYPTO_MUTEX lock; + + // Used to cache montgomery values. The creation of these values is protected + // by |lock|. + BN_MONT_CTX *mont_n; + BN_MONT_CTX *mont_p; + BN_MONT_CTX *mont_q; + + // The following fields are copies of |d|, |dmp1|, and |dmq1|, respectively, + // but with the correct widths to prevent side channels. These must use + // separate copies due to threading concerns caused by OpenSSL's API + // mistakes. See https://github.com/openssl/openssl/issues/5158 and + // the |freeze_private_key| implementation. + BIGNUM *d_fixed, *dmp1_fixed, *dmq1_fixed; + + // inv_small_mod_large_mont is q^-1 mod p in Montgomery form, using |mont_p|, + // if |p| >= |q|. Otherwise, it is p^-1 mod q in Montgomery form, using + // |mont_q|. + BIGNUM *inv_small_mod_large_mont; + + // num_blindings contains the size of the |blindings| and |blindings_inuse| + // arrays. This member and the |blindings_inuse| array are protected by + // |lock|. + unsigned num_blindings; + // blindings is an array of BN_BLINDING structures that can be reserved by a + // thread by locking |lock| and changing the corresponding element in + // |blindings_inuse| from 0 to 1. + BN_BLINDING **blindings; + unsigned char *blindings_inuse; + + // private_key_frozen is one if the key has been used for a private key + // operation and may no longer be mutated. + unsigned private_key_frozen:1; +}; + + +#if defined(__cplusplus) +} // extern C + +extern "C++" { + +namespace bssl { + +BORINGSSL_MAKE_DELETER(RSA, RSA_free) + +} // namespace bssl + +} // extern C++ + +#endif + +#define RSA_R_BAD_ENCODING 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_RSA_PARAMETERS 104 +#define RSA_R_BAD_SIGNATURE 105 +#define RSA_R_BAD_VERSION 106 +#define RSA_R_BLOCK_TYPE_IS_NOT_01 107 +#define RSA_R_BN_NOT_INITIALIZED 108 +#define RSA_R_CANNOT_RECOVER_MULTI_PRIME_KEY 109 +#define RSA_R_CRT_PARAMS_ALREADY_GIVEN 110 +#define RSA_R_CRT_VALUES_INCORRECT 111 +#define RSA_R_DATA_LEN_NOT_EQUAL_TO_MOD_LEN 112 +#define RSA_R_DATA_TOO_LARGE 113 +#define RSA_R_DATA_TOO_LARGE_FOR_KEY_SIZE 114 +#define RSA_R_DATA_TOO_LARGE_FOR_MODULUS 115 +#define RSA_R_DATA_TOO_SMALL 116 +#define RSA_R_DATA_TOO_SMALL_FOR_KEY_SIZE 117 +#define RSA_R_DIGEST_TOO_BIG_FOR_RSA_KEY 118 +#define RSA_R_D_E_NOT_CONGRUENT_TO_1 119 +#define RSA_R_EMPTY_PUBLIC_KEY 120 +#define RSA_R_ENCODE_ERROR 121 +#define RSA_R_FIRST_OCTET_INVALID 122 +#define RSA_R_INCONSISTENT_SET_OF_CRT_VALUES 123 +#define RSA_R_INTERNAL_ERROR 124 +#define RSA_R_INVALID_MESSAGE_LENGTH 125 +#define RSA_R_KEY_SIZE_TOO_SMALL 126 +#define RSA_R_LAST_OCTET_INVALID 127 +#define RSA_R_MODULUS_TOO_LARGE 128 +#define RSA_R_MUST_HAVE_AT_LEAST_TWO_PRIMES 129 +#define RSA_R_NO_PUBLIC_EXPONENT 130 +#define RSA_R_NULL_BEFORE_BLOCK_MISSING 131 +#define RSA_R_N_NOT_EQUAL_P_Q 132 +#define RSA_R_OAEP_DECODING_ERROR 133 +#define RSA_R_ONLY_ONE_OF_P_Q_GIVEN 134 +#define RSA_R_OUTPUT_BUFFER_TOO_SMALL 135 +#define RSA_R_PADDING_CHECK_FAILED 136 +#define RSA_R_PKCS_DECODING_ERROR 137 +#define RSA_R_SLEN_CHECK_FAILED 138 +#define RSA_R_SLEN_RECOVERY_FAILED 139 +#define RSA_R_TOO_LONG 140 +#define RSA_R_TOO_MANY_ITERATIONS 141 +#define RSA_R_UNKNOWN_ALGORITHM_TYPE 142 +#define RSA_R_UNKNOWN_PADDING_TYPE 143 +#define RSA_R_VALUE_MISSING 144 +#define RSA_R_WRONG_SIGNATURE_LENGTH 145 +#define RSA_R_PUBLIC_KEY_VALIDATION_FAILED 146 +#define RSA_R_D_OUT_OF_RANGE 147 + +#endif // OPENSSL_HEADER_RSA_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/safestack.h b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/safestack.h new file mode 100644 index 0000000..6e5e433 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/safestack.h @@ -0,0 +1,16 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +/* This header is provided in order to make compiling against code that expects + OpenSSL easier. */ diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/safestack.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/safestack.h.grpc_back new file mode 100644 index 0000000..6e5e433 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/safestack.h.grpc_back @@ -0,0 +1,16 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +/* This header is provided in order to make compiling against code that expects + OpenSSL easier. */ diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/sha.h b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/sha.h new file mode 100644 index 0000000..620e35b --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/sha.h @@ -0,0 +1,256 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 OPENSSL_HEADER_SHA_H +#define OPENSSL_HEADER_SHA_H + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// The SHA family of hash functions (SHA-1 and SHA-2). + + +// SHA_CBLOCK is the block size of SHA-1. +#define SHA_CBLOCK 64 + +// SHA_DIGEST_LENGTH is the length of a SHA-1 digest. +#define SHA_DIGEST_LENGTH 20 + +// SHA1_Init initialises |sha| and returns one. +OPENSSL_EXPORT int SHA1_Init(SHA_CTX *sha); + +// SHA1_Update adds |len| bytes from |data| to |sha| and returns one. +OPENSSL_EXPORT int SHA1_Update(SHA_CTX *sha, const void *data, size_t len); + +// SHA1_Final adds the final padding to |sha| and writes the resulting digest +// to |md|, which must have at least |SHA_DIGEST_LENGTH| bytes of space. It +// returns one. +OPENSSL_EXPORT int SHA1_Final(uint8_t *md, SHA_CTX *sha); + +// SHA1 writes the digest of |len| bytes from |data| to |out| and returns +// |out|. There must be at least |SHA_DIGEST_LENGTH| bytes of space in +// |out|. +OPENSSL_EXPORT uint8_t *SHA1(const uint8_t *data, size_t len, uint8_t *out); + +// SHA1_Transform is a low-level function that performs a single, SHA-1 block +// transformation using the state from |sha| and |SHA_CBLOCK| bytes from +// |block|. +OPENSSL_EXPORT void SHA1_Transform(SHA_CTX *sha, const uint8_t *block); + +struct sha_state_st { +#if defined(OPENSSL_WINDOWS) + uint32_t h[5]; +#else + // wpa_supplicant accesses |h0|..|h4| so we must support those names + // for compatibility with it until it can be updated. + union { + uint32_t h[5]; + struct { + uint32_t h0; + uint32_t h1; + uint32_t h2; + uint32_t h3; + uint32_t h4; + }; + }; +#endif + uint32_t Nl, Nh; + uint8_t data[SHA_CBLOCK]; + unsigned num; +}; + + +// SHA-224. + +// SHA224_CBLOCK is the block size of SHA-224. +#define SHA224_CBLOCK 64 + +// SHA224_DIGEST_LENGTH is the length of a SHA-224 digest. +#define SHA224_DIGEST_LENGTH 28 + +// SHA224_Init initialises |sha| and returns 1. +OPENSSL_EXPORT int SHA224_Init(SHA256_CTX *sha); + +// SHA224_Update adds |len| bytes from |data| to |sha| and returns 1. +OPENSSL_EXPORT int SHA224_Update(SHA256_CTX *sha, const void *data, size_t len); + +// SHA224_Final adds the final padding to |sha| and writes the resulting digest +// to |md|, which must have at least |SHA224_DIGEST_LENGTH| bytes of space. It +// returns one on success and zero on programmer error. +OPENSSL_EXPORT int SHA224_Final(uint8_t *md, SHA256_CTX *sha); + +// SHA224 writes the digest of |len| bytes from |data| to |out| and returns +// |out|. There must be at least |SHA224_DIGEST_LENGTH| bytes of space in +// |out|. +OPENSSL_EXPORT uint8_t *SHA224(const uint8_t *data, size_t len, uint8_t *out); + + +// SHA-256. + +// SHA256_CBLOCK is the block size of SHA-256. +#define SHA256_CBLOCK 64 + +// SHA256_DIGEST_LENGTH is the length of a SHA-256 digest. +#define SHA256_DIGEST_LENGTH 32 + +// SHA256_Init initialises |sha| and returns 1. +OPENSSL_EXPORT int SHA256_Init(SHA256_CTX *sha); + +// SHA256_Update adds |len| bytes from |data| to |sha| and returns 1. +OPENSSL_EXPORT int SHA256_Update(SHA256_CTX *sha, const void *data, size_t len); + +// SHA256_Final adds the final padding to |sha| and writes the resulting digest +// to |md|, which must have at least |SHA256_DIGEST_LENGTH| bytes of space. It +// returns one on success and zero on programmer error. +OPENSSL_EXPORT int SHA256_Final(uint8_t *md, SHA256_CTX *sha); + +// SHA256 writes the digest of |len| bytes from |data| to |out| and returns +// |out|. There must be at least |SHA256_DIGEST_LENGTH| bytes of space in +// |out|. +OPENSSL_EXPORT uint8_t *SHA256(const uint8_t *data, size_t len, uint8_t *out); + +// SHA256_Transform is a low-level function that performs a single, SHA-256 +// block transformation using the state from |sha| and |SHA256_CBLOCK| bytes +// from |block|. +OPENSSL_EXPORT void SHA256_Transform(SHA256_CTX *sha, const uint8_t *block); + +struct sha256_state_st { + uint32_t h[8]; + uint32_t Nl, Nh; + uint8_t data[SHA256_CBLOCK]; + unsigned num, md_len; +}; + + +// SHA-384. + +// SHA384_CBLOCK is the block size of SHA-384. +#define SHA384_CBLOCK 128 + +// SHA384_DIGEST_LENGTH is the length of a SHA-384 digest. +#define SHA384_DIGEST_LENGTH 48 + +// SHA384_Init initialises |sha| and returns 1. +OPENSSL_EXPORT int SHA384_Init(SHA512_CTX *sha); + +// SHA384_Update adds |len| bytes from |data| to |sha| and returns 1. +OPENSSL_EXPORT int SHA384_Update(SHA512_CTX *sha, const void *data, size_t len); + +// SHA384_Final adds the final padding to |sha| and writes the resulting digest +// to |md|, which must have at least |SHA384_DIGEST_LENGTH| bytes of space. It +// returns one on success and zero on programmer error. +OPENSSL_EXPORT int SHA384_Final(uint8_t *md, SHA512_CTX *sha); + +// SHA384 writes the digest of |len| bytes from |data| to |out| and returns +// |out|. There must be at least |SHA384_DIGEST_LENGTH| bytes of space in +// |out|. +OPENSSL_EXPORT uint8_t *SHA384(const uint8_t *data, size_t len, uint8_t *out); + +// SHA384_Transform is a low-level function that performs a single, SHA-384 +// block transformation using the state from |sha| and |SHA384_CBLOCK| bytes +// from |block|. +OPENSSL_EXPORT void SHA384_Transform(SHA512_CTX *sha, const uint8_t *block); + + +// SHA-512. + +// SHA512_CBLOCK is the block size of SHA-512. +#define SHA512_CBLOCK 128 + +// SHA512_DIGEST_LENGTH is the length of a SHA-512 digest. +#define SHA512_DIGEST_LENGTH 64 + +// SHA512_Init initialises |sha| and returns 1. +OPENSSL_EXPORT int SHA512_Init(SHA512_CTX *sha); + +// SHA512_Update adds |len| bytes from |data| to |sha| and returns 1. +OPENSSL_EXPORT int SHA512_Update(SHA512_CTX *sha, const void *data, size_t len); + +// SHA512_Final adds the final padding to |sha| and writes the resulting digest +// to |md|, which must have at least |SHA512_DIGEST_LENGTH| bytes of space. It +// returns one on success and zero on programmer error. +OPENSSL_EXPORT int SHA512_Final(uint8_t *md, SHA512_CTX *sha); + +// SHA512 writes the digest of |len| bytes from |data| to |out| and returns +// |out|. There must be at least |SHA512_DIGEST_LENGTH| bytes of space in +// |out|. +OPENSSL_EXPORT uint8_t *SHA512(const uint8_t *data, size_t len, uint8_t *out); + +// SHA512_Transform is a low-level function that performs a single, SHA-512 +// block transformation using the state from |sha| and |SHA512_CBLOCK| bytes +// from |block|. +OPENSSL_EXPORT void SHA512_Transform(SHA512_CTX *sha, const uint8_t *block); + +struct sha512_state_st { + uint64_t h[8]; + uint64_t Nl, Nh; + union { + uint64_t d[16]; + uint8_t p[128]; + } u; + unsigned num, md_len; +}; + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_SHA_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/sha.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/sha.h.grpc_back new file mode 100644 index 0000000..fc4644b --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/sha.h.grpc_back @@ -0,0 +1,256 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 OPENSSL_HEADER_SHA_H +#define OPENSSL_HEADER_SHA_H + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// The SHA family of hash functions (SHA-1 and SHA-2). + + +// SHA_CBLOCK is the block size of SHA-1. +#define SHA_CBLOCK 64 + +// SHA_DIGEST_LENGTH is the length of a SHA-1 digest. +#define SHA_DIGEST_LENGTH 20 + +// SHA1_Init initialises |sha| and returns one. +OPENSSL_EXPORT int SHA1_Init(SHA_CTX *sha); + +// SHA1_Update adds |len| bytes from |data| to |sha| and returns one. +OPENSSL_EXPORT int SHA1_Update(SHA_CTX *sha, const void *data, size_t len); + +// SHA1_Final adds the final padding to |sha| and writes the resulting digest +// to |md|, which must have at least |SHA_DIGEST_LENGTH| bytes of space. It +// returns one. +OPENSSL_EXPORT int SHA1_Final(uint8_t *md, SHA_CTX *sha); + +// SHA1 writes the digest of |len| bytes from |data| to |out| and returns +// |out|. There must be at least |SHA_DIGEST_LENGTH| bytes of space in +// |out|. +OPENSSL_EXPORT uint8_t *SHA1(const uint8_t *data, size_t len, uint8_t *out); + +// SHA1_Transform is a low-level function that performs a single, SHA-1 block +// transformation using the state from |sha| and |SHA_CBLOCK| bytes from +// |block|. +OPENSSL_EXPORT void SHA1_Transform(SHA_CTX *sha, const uint8_t *block); + +struct sha_state_st { +#if defined(OPENSSL_WINDOWS) + uint32_t h[5]; +#else + // wpa_supplicant accesses |h0|..|h4| so we must support those names + // for compatibility with it until it can be updated. + union { + uint32_t h[5]; + struct { + uint32_t h0; + uint32_t h1; + uint32_t h2; + uint32_t h3; + uint32_t h4; + }; + }; +#endif + uint32_t Nl, Nh; + uint8_t data[SHA_CBLOCK]; + unsigned num; +}; + + +// SHA-224. + +// SHA224_CBLOCK is the block size of SHA-224. +#define SHA224_CBLOCK 64 + +// SHA224_DIGEST_LENGTH is the length of a SHA-224 digest. +#define SHA224_DIGEST_LENGTH 28 + +// SHA224_Init initialises |sha| and returns 1. +OPENSSL_EXPORT int SHA224_Init(SHA256_CTX *sha); + +// SHA224_Update adds |len| bytes from |data| to |sha| and returns 1. +OPENSSL_EXPORT int SHA224_Update(SHA256_CTX *sha, const void *data, size_t len); + +// SHA224_Final adds the final padding to |sha| and writes the resulting digest +// to |md|, which must have at least |SHA224_DIGEST_LENGTH| bytes of space. It +// returns one on success and zero on programmer error. +OPENSSL_EXPORT int SHA224_Final(uint8_t *md, SHA256_CTX *sha); + +// SHA224 writes the digest of |len| bytes from |data| to |out| and returns +// |out|. There must be at least |SHA224_DIGEST_LENGTH| bytes of space in +// |out|. +OPENSSL_EXPORT uint8_t *SHA224(const uint8_t *data, size_t len, uint8_t *out); + + +// SHA-256. + +// SHA256_CBLOCK is the block size of SHA-256. +#define SHA256_CBLOCK 64 + +// SHA256_DIGEST_LENGTH is the length of a SHA-256 digest. +#define SHA256_DIGEST_LENGTH 32 + +// SHA256_Init initialises |sha| and returns 1. +OPENSSL_EXPORT int SHA256_Init(SHA256_CTX *sha); + +// SHA256_Update adds |len| bytes from |data| to |sha| and returns 1. +OPENSSL_EXPORT int SHA256_Update(SHA256_CTX *sha, const void *data, size_t len); + +// SHA256_Final adds the final padding to |sha| and writes the resulting digest +// to |md|, which must have at least |SHA256_DIGEST_LENGTH| bytes of space. It +// returns one on success and zero on programmer error. +OPENSSL_EXPORT int SHA256_Final(uint8_t *md, SHA256_CTX *sha); + +// SHA256 writes the digest of |len| bytes from |data| to |out| and returns +// |out|. There must be at least |SHA256_DIGEST_LENGTH| bytes of space in +// |out|. +OPENSSL_EXPORT uint8_t *SHA256(const uint8_t *data, size_t len, uint8_t *out); + +// SHA256_Transform is a low-level function that performs a single, SHA-256 +// block transformation using the state from |sha| and |SHA256_CBLOCK| bytes +// from |block|. +OPENSSL_EXPORT void SHA256_Transform(SHA256_CTX *sha, const uint8_t *block); + +struct sha256_state_st { + uint32_t h[8]; + uint32_t Nl, Nh; + uint8_t data[SHA256_CBLOCK]; + unsigned num, md_len; +}; + + +// SHA-384. + +// SHA384_CBLOCK is the block size of SHA-384. +#define SHA384_CBLOCK 128 + +// SHA384_DIGEST_LENGTH is the length of a SHA-384 digest. +#define SHA384_DIGEST_LENGTH 48 + +// SHA384_Init initialises |sha| and returns 1. +OPENSSL_EXPORT int SHA384_Init(SHA512_CTX *sha); + +// SHA384_Update adds |len| bytes from |data| to |sha| and returns 1. +OPENSSL_EXPORT int SHA384_Update(SHA512_CTX *sha, const void *data, size_t len); + +// SHA384_Final adds the final padding to |sha| and writes the resulting digest +// to |md|, which must have at least |SHA384_DIGEST_LENGTH| bytes of space. It +// returns one on success and zero on programmer error. +OPENSSL_EXPORT int SHA384_Final(uint8_t *md, SHA512_CTX *sha); + +// SHA384 writes the digest of |len| bytes from |data| to |out| and returns +// |out|. There must be at least |SHA384_DIGEST_LENGTH| bytes of space in +// |out|. +OPENSSL_EXPORT uint8_t *SHA384(const uint8_t *data, size_t len, uint8_t *out); + +// SHA384_Transform is a low-level function that performs a single, SHA-384 +// block transformation using the state from |sha| and |SHA384_CBLOCK| bytes +// from |block|. +OPENSSL_EXPORT void SHA384_Transform(SHA512_CTX *sha, const uint8_t *block); + + +// SHA-512. + +// SHA512_CBLOCK is the block size of SHA-512. +#define SHA512_CBLOCK 128 + +// SHA512_DIGEST_LENGTH is the length of a SHA-512 digest. +#define SHA512_DIGEST_LENGTH 64 + +// SHA512_Init initialises |sha| and returns 1. +OPENSSL_EXPORT int SHA512_Init(SHA512_CTX *sha); + +// SHA512_Update adds |len| bytes from |data| to |sha| and returns 1. +OPENSSL_EXPORT int SHA512_Update(SHA512_CTX *sha, const void *data, size_t len); + +// SHA512_Final adds the final padding to |sha| and writes the resulting digest +// to |md|, which must have at least |SHA512_DIGEST_LENGTH| bytes of space. It +// returns one on success and zero on programmer error. +OPENSSL_EXPORT int SHA512_Final(uint8_t *md, SHA512_CTX *sha); + +// SHA512 writes the digest of |len| bytes from |data| to |out| and returns +// |out|. There must be at least |SHA512_DIGEST_LENGTH| bytes of space in +// |out|. +OPENSSL_EXPORT uint8_t *SHA512(const uint8_t *data, size_t len, uint8_t *out); + +// SHA512_Transform is a low-level function that performs a single, SHA-512 +// block transformation using the state from |sha| and |SHA512_CBLOCK| bytes +// from |block|. +OPENSSL_EXPORT void SHA512_Transform(SHA512_CTX *sha, const uint8_t *block); + +struct sha512_state_st { + uint64_t h[8]; + uint64_t Nl, Nh; + union { + uint64_t d[16]; + uint8_t p[128]; + } u; + unsigned num, md_len; +}; + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_SHA_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/span.h b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/span.h new file mode 100644 index 0000000..f1ec876 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/span.h @@ -0,0 +1,191 @@ +/* Copyright (c) 2017, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_SSL_SPAN_H +#define OPENSSL_HEADER_SSL_SPAN_H + +#include + +#if !defined(BORINGSSL_NO_CXX) + +extern "C++" { + +#include +#include +#include +#include + +namespace bssl { + +template +class Span; + +namespace internal { +template +class SpanBase { + // Put comparison operator implementations into a base class with const T, so + // they can be used with any type that implicitly converts into a Span. + static_assert(std::is_const::value, + "Span must be derived from SpanBase"); + + friend bool operator==(Span lhs, Span rhs) { + // MSVC issues warning C4996 because std::equal is unsafe. The pragma to + // suppress the warning mysteriously has no effect, hence this + // implementation. See + // https://msdn.microsoft.com/en-us/library/aa985974.aspx. + if (lhs.size() != rhs.size()) { + return false; + } + for (T *l = lhs.begin(), *r = rhs.begin(); l != lhs.end() && r != rhs.end(); + ++l, ++r) { + if (*l != *r) { + return false; + } + } + return true; + } + + friend bool operator!=(Span lhs, Span rhs) { return !(lhs == rhs); } +}; +} // namespace internal + +// A Span is a non-owning reference to a contiguous array of objects of type +// |T|. Conceptually, a Span is a simple a pointer to |T| and a count of +// elements accessible via that pointer. The elements referenced by the Span can +// be mutated if |T| is mutable. +// +// A Span can be constructed from container types implementing |data()| and +// |size()| methods. If |T| is constant, construction from a container type is +// implicit. This allows writing methods that accept data from some unspecified +// container type: +// +// // Foo views data referenced by v. +// void Foo(bssl::Span v) { ... } +// +// std::vector vec; +// Foo(vec); +// +// For mutable Spans, conversion is explicit: +// +// // FooMutate mutates data referenced by v. +// void FooMutate(bssl::Span v) { ... } +// +// FooMutate(bssl::Span(vec)); +// +// You can also use the |MakeSpan| and |MakeConstSpan| factory methods to +// construct Spans in order to deduce the type of the Span automatically. +// +// FooMutate(bssl::MakeSpan(vec)); +// +// Note that Spans have value type sematics. They are cheap to construct and +// copy, and should be passed by value whenever a method would otherwise accept +// a reference or pointer to a container or array. +template +class Span : private internal::SpanBase { + private: + // Heuristically test whether C is a container type that can be converted into + // a Span by checking for data() and size() member functions. + // + // TODO(davidben): Switch everything to std::enable_if_t when we remove + // support for MSVC 2015. Although we could write our own enable_if_t and MSVC + // 2015 has std::enable_if_t anyway, MSVC 2015's SFINAE implementation is + // problematic and does not work below unless we write the ::type at use. + template + using EnableIfContainer = std::enable_if< + std::is_convertible().data()), T *>::value && + std::is_integral().size())>::value>; + + static const size_t npos = static_cast(-1); + + public: + constexpr Span() : Span(nullptr, 0) {} + constexpr Span(T *ptr, size_t len) : data_(ptr), size_(len) {} + + template + constexpr Span(T (&array)[N]) : Span(array, N) {} + + template < + typename C, typename = typename EnableIfContainer::type, + typename = typename std::enable_if::value, C>::type> + Span(const C &container) : data_(container.data()), size_(container.size()) {} + + template < + typename C, typename = typename EnableIfContainer::type, + typename = typename std::enable_if::value, C>::type> + explicit Span(C &container) + : data_(container.data()), size_(container.size()) {} + + T *data() const { return data_; } + size_t size() const { return size_; } + bool empty() const { return size_ == 0; } + + T *begin() const { return data_; } + const T *cbegin() const { return data_; } + T *end() const { return data_ + size_; }; + const T *cend() const { return end(); }; + + T &front() const { + assert(size_ != 0); + return data_[0]; + } + T &back() const { + assert(size_ != 0); + return data_[size_ - 1]; + } + + T &operator[](size_t i) const { return data_[i]; } + T &at(size_t i) const { return data_[i]; } + + Span subspan(size_t pos = 0, size_t len = npos) const { + if (pos > size_) { + abort(); // absl::Span throws an exception here. + } + return Span(data_ + pos, std::min(size_ - pos, len)); + } + + private: + T *data_; + size_t size_; +}; + +template +const size_t Span::npos; + +template +Span MakeSpan(T *ptr, size_t size) { + return Span(ptr, size); +} + +template +auto MakeSpan(C &c) -> decltype(MakeSpan(c.data(), c.size())) { + return MakeSpan(c.data(), c.size()); +} + +template +Span MakeConstSpan(T *ptr, size_t size) { + return Span(ptr, size); +} + +template +auto MakeConstSpan(const C &c) -> decltype(MakeConstSpan(c.data(), c.size())) { + return MakeConstSpan(c.data(), c.size()); +} + +} // namespace bssl + +} // extern C++ + +#endif // !defined(BORINGSSL_NO_CXX) + +#endif // OPENSSL_HEADER_SSL_SPAN_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/span.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/span.h.grpc_back new file mode 100644 index 0000000..3a629f7 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/span.h.grpc_back @@ -0,0 +1,191 @@ +/* Copyright (c) 2017, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#ifndef OPENSSL_HEADER_SSL_SPAN_H +#define OPENSSL_HEADER_SSL_SPAN_H + +#include + +#if !defined(BORINGSSL_NO_CXX) + +extern "C++" { + +#include +#include +#include +#include + +namespace bssl { + +template +class Span; + +namespace internal { +template +class SpanBase { + // Put comparison operator implementations into a base class with const T, so + // they can be used with any type that implicitly converts into a Span. + static_assert(std::is_const::value, + "Span must be derived from SpanBase"); + + friend bool operator==(Span lhs, Span rhs) { + // MSVC issues warning C4996 because std::equal is unsafe. The pragma to + // suppress the warning mysteriously has no effect, hence this + // implementation. See + // https://msdn.microsoft.com/en-us/library/aa985974.aspx. + if (lhs.size() != rhs.size()) { + return false; + } + for (T *l = lhs.begin(), *r = rhs.begin(); l != lhs.end() && r != rhs.end(); + ++l, ++r) { + if (*l != *r) { + return false; + } + } + return true; + } + + friend bool operator!=(Span lhs, Span rhs) { return !(lhs == rhs); } +}; +} // namespace internal + +// A Span is a non-owning reference to a contiguous array of objects of type +// |T|. Conceptually, a Span is a simple a pointer to |T| and a count of +// elements accessible via that pointer. The elements referenced by the Span can +// be mutated if |T| is mutable. +// +// A Span can be constructed from container types implementing |data()| and +// |size()| methods. If |T| is constant, construction from a container type is +// implicit. This allows writing methods that accept data from some unspecified +// container type: +// +// // Foo views data referenced by v. +// void Foo(bssl::Span v) { ... } +// +// std::vector vec; +// Foo(vec); +// +// For mutable Spans, conversion is explicit: +// +// // FooMutate mutates data referenced by v. +// void FooMutate(bssl::Span v) { ... } +// +// FooMutate(bssl::Span(vec)); +// +// You can also use the |MakeSpan| and |MakeConstSpan| factory methods to +// construct Spans in order to deduce the type of the Span automatically. +// +// FooMutate(bssl::MakeSpan(vec)); +// +// Note that Spans have value type sematics. They are cheap to construct and +// copy, and should be passed by value whenever a method would otherwise accept +// a reference or pointer to a container or array. +template +class Span : private internal::SpanBase { + private: + // Heuristically test whether C is a container type that can be converted into + // a Span by checking for data() and size() member functions. + // + // TODO(davidben): Switch everything to std::enable_if_t when we remove + // support for MSVC 2015. Although we could write our own enable_if_t and MSVC + // 2015 has std::enable_if_t anyway, MSVC 2015's SFINAE implementation is + // problematic and does not work below unless we write the ::type at use. + template + using EnableIfContainer = std::enable_if< + std::is_convertible().data()), T *>::value && + std::is_integral().size())>::value>; + + static const size_t npos = static_cast(-1); + + public: + constexpr Span() : Span(nullptr, 0) {} + constexpr Span(T *ptr, size_t len) : data_(ptr), size_(len) {} + + template + constexpr Span(T (&array)[N]) : Span(array, N) {} + + template < + typename C, typename = typename EnableIfContainer::type, + typename = typename std::enable_if::value, C>::type> + Span(const C &container) : data_(container.data()), size_(container.size()) {} + + template < + typename C, typename = typename EnableIfContainer::type, + typename = typename std::enable_if::value, C>::type> + explicit Span(C &container) + : data_(container.data()), size_(container.size()) {} + + T *data() const { return data_; } + size_t size() const { return size_; } + bool empty() const { return size_ == 0; } + + T *begin() const { return data_; } + const T *cbegin() const { return data_; } + T *end() const { return data_ + size_; }; + const T *cend() const { return end(); }; + + T &front() const { + assert(size_ != 0); + return data_[0]; + } + T &back() const { + assert(size_ != 0); + return data_[size_ - 1]; + } + + T &operator[](size_t i) const { return data_[i]; } + T &at(size_t i) const { return data_[i]; } + + Span subspan(size_t pos = 0, size_t len = npos) const { + if (pos > size_) { + abort(); // absl::Span throws an exception here. + } + return Span(data_ + pos, std::min(size_ - pos, len)); + } + + private: + T *data_; + size_t size_; +}; + +template +const size_t Span::npos; + +template +Span MakeSpan(T *ptr, size_t size) { + return Span(ptr, size); +} + +template +auto MakeSpan(C &c) -> decltype(MakeSpan(c.data(), c.size())) { + return MakeSpan(c.data(), c.size()); +} + +template +Span MakeConstSpan(T *ptr, size_t size) { + return Span(ptr, size); +} + +template +auto MakeConstSpan(const C &c) -> decltype(MakeConstSpan(c.data(), c.size())) { + return MakeConstSpan(c.data(), c.size()); +} + +} // namespace bssl + +} // extern C++ + +#endif // !defined(BORINGSSL_NO_CXX) + +#endif // OPENSSL_HEADER_SSL_SPAN_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/srtp.h b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/srtp.h new file mode 100644 index 0000000..39f6a85 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/srtp.h @@ -0,0 +1,18 @@ +/* Copyright (c) 2015, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +/* This header is provided in order to make compiling against code that expects + OpenSSL easier. */ + +#include "ssl.h" diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/srtp.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/srtp.h.grpc_back new file mode 100644 index 0000000..39f6a85 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/srtp.h.grpc_back @@ -0,0 +1,18 @@ +/* Copyright (c) 2015, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +/* This header is provided in order to make compiling against code that expects + OpenSSL easier. */ + +#include "ssl.h" diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/ssl.h b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/ssl.h new file mode 100644 index 0000000..571a980 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/ssl.h @@ -0,0 +1,4672 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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. + */ +/* ==================================================================== + * 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 OPENSSL_HEADER_SSL_H +#define OPENSSL_HEADER_SSL_H + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#if !defined(OPENSSL_WINDOWS) +#include +#endif + +// NGINX needs this #include. Consider revisiting this after NGINX 1.14.0 has +// been out for a year or so (assuming that they fix it in that release.) See +// https://boringssl-review.googlesource.com/c/boringssl/+/21664. +#include + +// Forward-declare struct timeval. On Windows, it is defined in winsock2.h and +// Windows headers define too many macros to be included in public headers. +// However, only a forward declaration is needed. +struct timeval; + +#if defined(__cplusplus) +extern "C" { +#endif + + +// SSL implementation. + + +// SSL contexts. +// +// |SSL_CTX| objects manage shared state and configuration between multiple TLS +// or DTLS connections. Whether the connections are TLS or DTLS is selected by +// an |SSL_METHOD| on creation. +// +// |SSL_CTX| are reference-counted and may be shared by connections across +// multiple threads. Once shared, functions which change the |SSL_CTX|'s +// configuration may not be used. + +// TLS_method is the |SSL_METHOD| used for TLS (and SSLv3) connections. +OPENSSL_EXPORT const SSL_METHOD *TLS_method(void); + +// DTLS_method is the |SSL_METHOD| used for DTLS connections. +OPENSSL_EXPORT const SSL_METHOD *DTLS_method(void); + +// TLS_with_buffers_method is like |TLS_method|, but avoids all use of +// crypto/x509. All client connections created with |TLS_with_buffers_method| +// will fail unless a certificate verifier is installed with +// |SSL_set_custom_verify| or |SSL_CTX_set_custom_verify|. +OPENSSL_EXPORT const SSL_METHOD *TLS_with_buffers_method(void); + +// DTLS_with_buffers_method is like |DTLS_method|, but avoids all use of +// crypto/x509. +OPENSSL_EXPORT const SSL_METHOD *DTLS_with_buffers_method(void); + +// SSL_CTX_new returns a newly-allocated |SSL_CTX| with default settings or NULL +// on error. +OPENSSL_EXPORT SSL_CTX *SSL_CTX_new(const SSL_METHOD *method); + +// SSL_CTX_up_ref increments the reference count of |ctx|. It returns one. +OPENSSL_EXPORT int SSL_CTX_up_ref(SSL_CTX *ctx); + +// SSL_CTX_free releases memory associated with |ctx|. +OPENSSL_EXPORT void SSL_CTX_free(SSL_CTX *ctx); + + +// SSL connections. +// +// An |SSL| object represents a single TLS or DTLS connection. Although the +// shared |SSL_CTX| is thread-safe, an |SSL| is not thread-safe and may only be +// used on one thread at a time. + +// SSL_new returns a newly-allocated |SSL| using |ctx| or NULL on error. The new +// connection inherits settings from |ctx| at the time of creation. Settings may +// also be individually configured on the connection. +// +// On creation, an |SSL| is not configured to be either a client or server. Call +// |SSL_set_connect_state| or |SSL_set_accept_state| to set this. +OPENSSL_EXPORT SSL *SSL_new(SSL_CTX *ctx); + +// SSL_free releases memory associated with |ssl|. +OPENSSL_EXPORT void SSL_free(SSL *ssl); + +// SSL_get_SSL_CTX returns the |SSL_CTX| associated with |ssl|. If +// |SSL_set_SSL_CTX| is called, it returns the new |SSL_CTX|, not the initial +// one. +OPENSSL_EXPORT SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl); + +// SSL_set_connect_state configures |ssl| to be a client. +OPENSSL_EXPORT void SSL_set_connect_state(SSL *ssl); + +// SSL_set_accept_state configures |ssl| to be a server. +OPENSSL_EXPORT void SSL_set_accept_state(SSL *ssl); + +// SSL_is_server returns one if |ssl| is configured as a server and zero +// otherwise. +OPENSSL_EXPORT int SSL_is_server(const SSL *ssl); + +// SSL_is_dtls returns one if |ssl| is a DTLS connection and zero otherwise. +OPENSSL_EXPORT int SSL_is_dtls(const SSL *ssl); + +// SSL_set_bio configures |ssl| to read from |rbio| and write to |wbio|. |ssl| +// takes ownership of the two |BIO|s. If |rbio| and |wbio| are the same, |ssl| +// only takes ownership of one reference. +// +// In DTLS, |rbio| must be non-blocking to properly handle timeouts and +// retransmits. +// +// If |rbio| is the same as the currently configured |BIO| for reading, that +// side is left untouched and is not freed. +// +// If |wbio| is the same as the currently configured |BIO| for writing AND |ssl| +// is not currently configured to read from and write to the same |BIO|, that +// side is left untouched and is not freed. This asymmetry is present for +// historical reasons. +// +// Due to the very complex historical behavior of this function, calling this +// function if |ssl| already has |BIO|s configured is deprecated. Prefer +// |SSL_set0_rbio| and |SSL_set0_wbio| instead. +OPENSSL_EXPORT void SSL_set_bio(SSL *ssl, BIO *rbio, BIO *wbio); + +// SSL_set0_rbio configures |ssl| to write to |rbio|. It takes ownership of +// |rbio|. +// +// Note that, although this function and |SSL_set0_wbio| may be called on the +// same |BIO|, each call takes a reference. Use |BIO_up_ref| to balance this. +OPENSSL_EXPORT void SSL_set0_rbio(SSL *ssl, BIO *rbio); + +// SSL_set0_wbio configures |ssl| to write to |wbio|. It takes ownership of +// |wbio|. +// +// Note that, although this function and |SSL_set0_rbio| may be called on the +// same |BIO|, each call takes a reference. Use |BIO_up_ref| to balance this. +OPENSSL_EXPORT void SSL_set0_wbio(SSL *ssl, BIO *wbio); + +// SSL_get_rbio returns the |BIO| that |ssl| reads from. +OPENSSL_EXPORT BIO *SSL_get_rbio(const SSL *ssl); + +// SSL_get_wbio returns the |BIO| that |ssl| writes to. +OPENSSL_EXPORT BIO *SSL_get_wbio(const SSL *ssl); + +// SSL_get_fd calls |SSL_get_rfd|. +OPENSSL_EXPORT int SSL_get_fd(const SSL *ssl); + +// SSL_get_rfd returns the file descriptor that |ssl| is configured to read +// from. If |ssl|'s read |BIO| is not configured or doesn't wrap a file +// descriptor then it returns -1. +// +// Note: On Windows, this may return either a file descriptor or a socket (cast +// to int), depending on whether |ssl| was configured with a file descriptor or +// socket |BIO|. +OPENSSL_EXPORT int SSL_get_rfd(const SSL *ssl); + +// SSL_get_wfd returns the file descriptor that |ssl| is configured to write +// to. If |ssl|'s write |BIO| is not configured or doesn't wrap a file +// descriptor then it returns -1. +// +// Note: On Windows, this may return either a file descriptor or a socket (cast +// to int), depending on whether |ssl| was configured with a file descriptor or +// socket |BIO|. +OPENSSL_EXPORT int SSL_get_wfd(const SSL *ssl); + +// SSL_set_fd configures |ssl| to read from and write to |fd|. It returns one +// on success and zero on allocation error. The caller retains ownership of +// |fd|. +// +// On Windows, |fd| is cast to a |SOCKET| and used with Winsock APIs. +OPENSSL_EXPORT int SSL_set_fd(SSL *ssl, int fd); + +// SSL_set_rfd configures |ssl| to read from |fd|. It returns one on success and +// zero on allocation error. The caller retains ownership of |fd|. +// +// On Windows, |fd| is cast to a |SOCKET| and used with Winsock APIs. +OPENSSL_EXPORT int SSL_set_rfd(SSL *ssl, int fd); + +// SSL_set_wfd configures |ssl| to write to |fd|. It returns one on success and +// zero on allocation error. The caller retains ownership of |fd|. +// +// On Windows, |fd| is cast to a |SOCKET| and used with Winsock APIs. +OPENSSL_EXPORT int SSL_set_wfd(SSL *ssl, int fd); + +// SSL_do_handshake continues the current handshake. If there is none or the +// handshake has completed or False Started, it returns one. Otherwise, it +// returns <= 0. The caller should pass the value into |SSL_get_error| to +// determine how to proceed. +// +// In DTLS, the caller must drive retransmissions. Whenever |SSL_get_error| +// signals |SSL_ERROR_WANT_READ|, use |DTLSv1_get_timeout| to determine the +// current timeout. If it expires before the next retry, call +// |DTLSv1_handle_timeout|. Note that DTLS handshake retransmissions use fresh +// sequence numbers, so it is not sufficient to replay packets at the transport. +// +// TODO(davidben): Ensure 0 is only returned on transport EOF. +// https://crbug.com/466303. +OPENSSL_EXPORT int SSL_do_handshake(SSL *ssl); + +// SSL_connect configures |ssl| as a client, if unconfigured, and calls +// |SSL_do_handshake|. +OPENSSL_EXPORT int SSL_connect(SSL *ssl); + +// SSL_accept configures |ssl| as a server, if unconfigured, and calls +// |SSL_do_handshake|. +OPENSSL_EXPORT int SSL_accept(SSL *ssl); + +// SSL_read reads up to |num| bytes from |ssl| into |buf|. It implicitly runs +// any pending handshakes, including renegotiations when enabled. On success, it +// returns the number of bytes read. Otherwise, it returns <= 0. The caller +// should pass the value into |SSL_get_error| to determine how to proceed. +// +// TODO(davidben): Ensure 0 is only returned on transport EOF. +// https://crbug.com/466303. +OPENSSL_EXPORT int SSL_read(SSL *ssl, void *buf, int num); + +// SSL_peek behaves like |SSL_read| but does not consume any bytes returned. +OPENSSL_EXPORT int SSL_peek(SSL *ssl, void *buf, int num); + +// SSL_pending returns the number of bytes available in |ssl|. It does not read +// from the transport. +OPENSSL_EXPORT int SSL_pending(const SSL *ssl); + +// SSL_write writes up to |num| bytes from |buf| into |ssl|. It implicitly runs +// any pending handshakes, including renegotiations when enabled. On success, it +// returns the number of bytes written. Otherwise, it returns <= 0. The caller +// should pass the value into |SSL_get_error| to determine how to proceed. +// +// In TLS, a non-blocking |SSL_write| differs from non-blocking |write| in that +// a failed |SSL_write| still commits to the data passed in. When retrying, the +// caller must supply the original write buffer (or a larger one containing the +// original as a prefix). By default, retries will fail if they also do not +// reuse the same |buf| pointer. This may be relaxed with +// |SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER|, but the buffer contents still must be +// unchanged. +// +// By default, in TLS, |SSL_write| will not return success until all |num| bytes +// are written. This may be relaxed with |SSL_MODE_ENABLE_PARTIAL_WRITE|. It +// allows |SSL_write| to complete with a partial result when only part of the +// input was written in a single record. +// +// In DTLS, neither |SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER| and +// |SSL_MODE_ENABLE_PARTIAL_WRITE| do anything. The caller may retry with a +// different buffer freely. A single call to |SSL_write| only ever writes a +// single record in a single packet, so |num| must be at most +// |SSL3_RT_MAX_PLAIN_LENGTH|. +// +// TODO(davidben): Ensure 0 is only returned on transport EOF. +// https://crbug.com/466303. +OPENSSL_EXPORT int SSL_write(SSL *ssl, const void *buf, int num); + +// SSL_shutdown shuts down |ssl|. On success, it completes in two stages. First, +// it returns 0 if |ssl| completed uni-directional shutdown; close_notify has +// been sent, but the peer's close_notify has not been received. Most callers +// may stop at this point. For bi-directional shutdown, call |SSL_shutdown| +// again. It returns 1 if close_notify has been both sent and received. +// +// If the peer's close_notify arrived first, the first stage is skipped. +// |SSL_shutdown| will return 1 once close_notify is sent and skip 0. Callers +// only interested in uni-directional shutdown must therefore allow for the +// first stage returning either 0 or 1. +// +// |SSL_shutdown| returns -1 on failure. The caller should pass the return value +// into |SSL_get_error| to determine how to proceed. If the underlying |BIO| is +// non-blocking, both stages may require retry. +OPENSSL_EXPORT int SSL_shutdown(SSL *ssl); + +// SSL_CTX_set_quiet_shutdown sets quiet shutdown on |ctx| to |mode|. If +// enabled, |SSL_shutdown| will not send a close_notify alert or wait for one +// from the peer. It will instead synchronously return one. +OPENSSL_EXPORT void SSL_CTX_set_quiet_shutdown(SSL_CTX *ctx, int mode); + +// SSL_CTX_get_quiet_shutdown returns whether quiet shutdown is enabled for +// |ctx|. +OPENSSL_EXPORT int SSL_CTX_get_quiet_shutdown(const SSL_CTX *ctx); + +// SSL_set_quiet_shutdown sets quiet shutdown on |ssl| to |mode|. If enabled, +// |SSL_shutdown| will not send a close_notify alert or wait for one from the +// peer. It will instead synchronously return one. +OPENSSL_EXPORT void SSL_set_quiet_shutdown(SSL *ssl, int mode); + +// SSL_get_quiet_shutdown returns whether quiet shutdown is enabled for +// |ssl|. +OPENSSL_EXPORT int SSL_get_quiet_shutdown(const SSL *ssl); + +// SSL_get_error returns a |SSL_ERROR_*| value for the most recent operation on +// |ssl|. It should be called after an operation failed to determine whether the +// error was fatal and, if not, when to retry. +OPENSSL_EXPORT int SSL_get_error(const SSL *ssl, int ret_code); + +// SSL_ERROR_NONE indicates the operation succeeded. +#define SSL_ERROR_NONE 0 + +// SSL_ERROR_SSL indicates the operation failed within the library. The caller +// may inspect the error queue for more information. +#define SSL_ERROR_SSL 1 + +// SSL_ERROR_WANT_READ indicates the operation failed attempting to read from +// the transport. The caller may retry the operation when the transport is ready +// for reading. +// +// If signaled by a DTLS handshake, the caller must also call +// |DTLSv1_get_timeout| and |DTLSv1_handle_timeout| as appropriate. See +// |SSL_do_handshake|. +#define SSL_ERROR_WANT_READ 2 + +// SSL_ERROR_WANT_WRITE indicates the operation failed attempting to write to +// the transport. The caller may retry the operation when the transport is ready +// for writing. +#define SSL_ERROR_WANT_WRITE 3 + +// SSL_ERROR_WANT_X509_LOOKUP indicates the operation failed in calling the +// |cert_cb| or |client_cert_cb|. The caller may retry the operation when the +// callback is ready to return a certificate or one has been configured +// externally. +// +// See also |SSL_CTX_set_cert_cb| and |SSL_CTX_set_client_cert_cb|. +#define SSL_ERROR_WANT_X509_LOOKUP 4 + +// SSL_ERROR_SYSCALL indicates the operation failed externally to the library. +// The caller should consult the system-specific error mechanism. This is +// typically |errno| but may be something custom if using a custom |BIO|. It +// may also be signaled if the transport returned EOF, in which case the +// operation's return value will be zero. +#define SSL_ERROR_SYSCALL 5 + +// SSL_ERROR_ZERO_RETURN indicates the operation failed because the connection +// was cleanly shut down with a close_notify alert. +#define SSL_ERROR_ZERO_RETURN 6 + +// SSL_ERROR_WANT_CONNECT indicates the operation failed attempting to connect +// the transport (the |BIO| signaled |BIO_RR_CONNECT|). The caller may retry the +// operation when the transport is ready. +#define SSL_ERROR_WANT_CONNECT 7 + +// SSL_ERROR_WANT_ACCEPT indicates the operation failed attempting to accept a +// connection from the transport (the |BIO| signaled |BIO_RR_ACCEPT|). The +// caller may retry the operation when the transport is ready. +// +// TODO(davidben): Remove this. It's used by accept BIOs which are bizarre. +#define SSL_ERROR_WANT_ACCEPT 8 + +// SSL_ERROR_WANT_CHANNEL_ID_LOOKUP indicates the operation failed looking up +// the Channel ID key. The caller may retry the operation when |channel_id_cb| +// is ready to return a key or one has been configured with +// |SSL_set1_tls_channel_id|. +// +// See also |SSL_CTX_set_channel_id_cb|. +#define SSL_ERROR_WANT_CHANNEL_ID_LOOKUP 9 + +// SSL_ERROR_PENDING_SESSION indicates the operation failed because the session +// lookup callback indicated the session was unavailable. The caller may retry +// the operation when lookup has completed. +// +// See also |SSL_CTX_sess_set_get_cb| and |SSL_magic_pending_session_ptr|. +#define SSL_ERROR_PENDING_SESSION 11 + +// SSL_ERROR_PENDING_CERTIFICATE indicates the operation failed because the +// early callback indicated certificate lookup was incomplete. The caller may +// retry the operation when lookup has completed. +// +// See also |SSL_CTX_set_select_certificate_cb|. +#define SSL_ERROR_PENDING_CERTIFICATE 12 + +// SSL_ERROR_WANT_PRIVATE_KEY_OPERATION indicates the operation failed because +// a private key operation was unfinished. The caller may retry the operation +// when the private key operation is complete. +// +// See also |SSL_set_private_key_method| and +// |SSL_CTX_set_private_key_method|. +#define SSL_ERROR_WANT_PRIVATE_KEY_OPERATION 13 + +// SSL_ERROR_PENDING_TICKET indicates that a ticket decryption is pending. The +// caller may retry the operation when the decryption is ready. +// +// See also |SSL_CTX_set_ticket_aead_method|. +#define SSL_ERROR_PENDING_TICKET 14 + +// SSL_ERROR_EARLY_DATA_REJECTED indicates that early data was rejected. The +// caller should treat this as a connection failure and retry any operations +// associated with the rejected early data. |SSL_reset_early_data_reject| may be +// used to reuse the underlying connection for the retry. +#define SSL_ERROR_EARLY_DATA_REJECTED 15 + +// SSL_ERROR_WANT_CERTIFICATE_VERIFY indicates the operation failed because +// certificate verification was incomplete. The caller may retry the operation +// when certificate verification is complete. +// +// See also |SSL_CTX_set_custom_verify|. +#define SSL_ERROR_WANT_CERTIFICATE_VERIFY 16 + +#define SSL_ERROR_HANDOFF 17 + +// SSL_set_mtu sets the |ssl|'s MTU in DTLS to |mtu|. It returns one on success +// and zero on failure. +OPENSSL_EXPORT int SSL_set_mtu(SSL *ssl, unsigned mtu); + +// DTLSv1_set_initial_timeout_duration sets the initial duration for a DTLS +// handshake timeout. +// +// This duration overrides the default of 1 second, which is the strong +// recommendation of RFC 6347 (see section 4.2.4.1). However, there may exist +// situations where a shorter timeout would be beneficial, such as for +// time-sensitive applications. +OPENSSL_EXPORT void DTLSv1_set_initial_timeout_duration(SSL *ssl, + unsigned duration_ms); + +// DTLSv1_get_timeout queries the next DTLS handshake timeout. If there is a +// timeout in progress, it sets |*out| to the time remaining and returns one. +// Otherwise, it returns zero. +// +// When the timeout expires, call |DTLSv1_handle_timeout| to handle the +// retransmit behavior. +// +// NOTE: This function must be queried again whenever the handshake state +// machine changes, including when |DTLSv1_handle_timeout| is called. +OPENSSL_EXPORT int DTLSv1_get_timeout(const SSL *ssl, struct timeval *out); + +// DTLSv1_handle_timeout is called when a DTLS handshake timeout expires. If no +// timeout had expired, it returns 0. Otherwise, it retransmits the previous +// flight of handshake messages and returns 1. If too many timeouts had expired +// without progress or an error occurs, it returns -1. +// +// The caller's external timer should be compatible with the one |ssl| queries +// within some fudge factor. Otherwise, the call will be a no-op, but +// |DTLSv1_get_timeout| will return an updated timeout. +// +// If the function returns -1, checking if |SSL_get_error| returns +// |SSL_ERROR_WANT_WRITE| may be used to determine if the retransmit failed due +// to a non-fatal error at the write |BIO|. However, the operation may not be +// retried until the next timeout fires. +// +// WARNING: This function breaks the usual return value convention. +// +// TODO(davidben): This |SSL_ERROR_WANT_WRITE| behavior is kind of bizarre. +OPENSSL_EXPORT int DTLSv1_handle_timeout(SSL *ssl); + + +// Protocol versions. + +#define DTLS1_VERSION_MAJOR 0xfe +#define SSL3_VERSION_MAJOR 0x03 + +#define SSL3_VERSION 0x0300 +#define TLS1_VERSION 0x0301 +#define TLS1_1_VERSION 0x0302 +#define TLS1_2_VERSION 0x0303 +#define TLS1_3_VERSION 0x0304 + +#define DTLS1_VERSION 0xfeff +#define DTLS1_2_VERSION 0xfefd + +#define TLS1_3_DRAFT23_VERSION 0x7f17 + +// SSL_CTX_set_min_proto_version sets the minimum protocol version for |ctx| to +// |version|. If |version| is zero, the default minimum version is used. It +// returns one on success and zero if |version| is invalid. +OPENSSL_EXPORT int SSL_CTX_set_min_proto_version(SSL_CTX *ctx, + uint16_t version); + +// SSL_CTX_set_max_proto_version sets the maximum protocol version for |ctx| to +// |version|. If |version| is zero, the default maximum version is used. It +// returns one on success and zero if |version| is invalid. +OPENSSL_EXPORT int SSL_CTX_set_max_proto_version(SSL_CTX *ctx, + uint16_t version); + +// SSL_set_min_proto_version sets the minimum protocol version for |ssl| to +// |version|. If |version| is zero, the default minimum version is used. It +// returns one on success and zero if |version| is invalid. +OPENSSL_EXPORT int SSL_set_min_proto_version(SSL *ssl, uint16_t version); + +// SSL_set_max_proto_version sets the maximum protocol version for |ssl| to +// |version|. If |version| is zero, the default maximum version is used. It +// returns one on success and zero if |version| is invalid. +OPENSSL_EXPORT int SSL_set_max_proto_version(SSL *ssl, uint16_t version); + +// SSL_version returns the TLS or DTLS protocol version used by |ssl|, which is +// one of the |*_VERSION| values. (E.g. |TLS1_2_VERSION|.) Before the version +// is negotiated, the result is undefined. +OPENSSL_EXPORT int SSL_version(const SSL *ssl); + + +// Options. +// +// Options configure protocol behavior. + +// SSL_OP_NO_QUERY_MTU, in DTLS, disables querying the MTU from the underlying +// |BIO|. Instead, the MTU is configured with |SSL_set_mtu|. +#define SSL_OP_NO_QUERY_MTU 0x00001000L + +// SSL_OP_NO_TICKET disables session ticket support (RFC 5077). +#define SSL_OP_NO_TICKET 0x00004000L + +// SSL_OP_CIPHER_SERVER_PREFERENCE configures servers to select ciphers and +// ECDHE curves according to the server's preferences instead of the +// client's. +#define SSL_OP_CIPHER_SERVER_PREFERENCE 0x00400000L + +// The following flags toggle individual protocol versions. This is deprecated. +// Use |SSL_CTX_set_min_proto_version| and |SSL_CTX_set_max_proto_version| +// instead. +#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_TLSv1_3 0x20000000L +#define SSL_OP_NO_DTLSv1 SSL_OP_NO_TLSv1 +#define SSL_OP_NO_DTLSv1_2 SSL_OP_NO_TLSv1_2 + +// SSL_CTX_set_options enables all options set in |options| (which should be one +// or more of the |SSL_OP_*| values, ORed together) in |ctx|. It returns a +// bitmask representing the resulting enabled options. +OPENSSL_EXPORT uint32_t SSL_CTX_set_options(SSL_CTX *ctx, uint32_t options); + +// SSL_CTX_clear_options disables all options set in |options| (which should be +// one or more of the |SSL_OP_*| values, ORed together) in |ctx|. It returns a +// bitmask representing the resulting enabled options. +OPENSSL_EXPORT uint32_t SSL_CTX_clear_options(SSL_CTX *ctx, uint32_t options); + +// SSL_CTX_get_options returns a bitmask of |SSL_OP_*| values that represent all +// the options enabled for |ctx|. +OPENSSL_EXPORT uint32_t SSL_CTX_get_options(const SSL_CTX *ctx); + +// SSL_set_options enables all options set in |options| (which should be one or +// more of the |SSL_OP_*| values, ORed together) in |ssl|. It returns a bitmask +// representing the resulting enabled options. +OPENSSL_EXPORT uint32_t SSL_set_options(SSL *ssl, uint32_t options); + +// SSL_clear_options disables all options set in |options| (which should be one +// or more of the |SSL_OP_*| values, ORed together) in |ssl|. It returns a +// bitmask representing the resulting enabled options. +OPENSSL_EXPORT uint32_t SSL_clear_options(SSL *ssl, uint32_t options); + +// SSL_get_options returns a bitmask of |SSL_OP_*| values that represent all the +// options enabled for |ssl|. +OPENSSL_EXPORT uint32_t SSL_get_options(const SSL *ssl); + + +// Modes. +// +// Modes configure API behavior. + +// SSL_MODE_ENABLE_PARTIAL_WRITE, in TLS, allows |SSL_write| to complete with a +// partial result when the only part of the input was written in a single +// record. In DTLS, it does nothing. +#define SSL_MODE_ENABLE_PARTIAL_WRITE 0x00000001L + +// SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER, in TLS, allows retrying an incomplete +// |SSL_write| with a different buffer. However, |SSL_write| still assumes the +// buffer contents are unchanged. This is not the default to avoid the +// misconception that non-blocking |SSL_write| behaves like non-blocking +// |write|. In DTLS, it does nothing. +#define SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER 0x00000002L + +// SSL_MODE_NO_AUTO_CHAIN disables automatically building a certificate chain +// before sending certificates to the peer. This flag is set (and the feature +// disabled) by default. +// TODO(davidben): Remove this behavior. https://crbug.com/boringssl/42. +#define SSL_MODE_NO_AUTO_CHAIN 0x00000008L + +// SSL_MODE_ENABLE_FALSE_START allows clients to send application data before +// receipt of ChangeCipherSpec and Finished. This mode enables full handshakes +// to 'complete' in one RTT. See RFC 7918. +// +// When False Start is enabled, |SSL_do_handshake| may succeed before the +// handshake has completely finished. |SSL_write| will function at this point, +// and |SSL_read| will transparently wait for the final handshake leg before +// returning application data. To determine if False Start occurred or when the +// handshake is completely finished, see |SSL_in_false_start|, |SSL_in_init|, +// and |SSL_CB_HANDSHAKE_DONE| from |SSL_CTX_set_info_callback|. +#define SSL_MODE_ENABLE_FALSE_START 0x00000080L + +// SSL_MODE_CBC_RECORD_SPLITTING causes multi-byte CBC records in SSL 3.0 and +// TLS 1.0 to be split in two: the first record will contain a single byte and +// the second will contain the remainder. This effectively randomises the IV and +// prevents BEAST attacks. +#define SSL_MODE_CBC_RECORD_SPLITTING 0x00000100L + +// SSL_MODE_NO_SESSION_CREATION will cause any attempts to create a session to +// fail with SSL_R_SESSION_MAY_NOT_BE_CREATED. This can be used to enforce that +// session resumption is used for a given SSL*. +#define SSL_MODE_NO_SESSION_CREATION 0x00000200L + +// SSL_MODE_SEND_FALLBACK_SCSV sends TLS_FALLBACK_SCSV in the ClientHello. +// To be set only by applications that reconnect with a downgraded protocol +// version; see RFC 7507 for details. +// +// DO NOT ENABLE THIS if your application attempts a normal handshake. Only use +// this in explicit fallback retries, following the guidance in RFC 7507. +#define SSL_MODE_SEND_FALLBACK_SCSV 0x00000400L + +// SSL_CTX_set_mode enables all modes set in |mode| (which should be one or more +// of the |SSL_MODE_*| values, ORed together) in |ctx|. It returns a bitmask +// representing the resulting enabled modes. +OPENSSL_EXPORT uint32_t SSL_CTX_set_mode(SSL_CTX *ctx, uint32_t mode); + +// SSL_CTX_clear_mode disables all modes set in |mode| (which should be one or +// more of the |SSL_MODE_*| values, ORed together) in |ctx|. It returns a +// bitmask representing the resulting enabled modes. +OPENSSL_EXPORT uint32_t SSL_CTX_clear_mode(SSL_CTX *ctx, uint32_t mode); + +// SSL_CTX_get_mode returns a bitmask of |SSL_MODE_*| values that represent all +// the modes enabled for |ssl|. +OPENSSL_EXPORT uint32_t SSL_CTX_get_mode(const SSL_CTX *ctx); + +// SSL_set_mode enables all modes set in |mode| (which should be one or more of +// the |SSL_MODE_*| values, ORed together) in |ssl|. It returns a bitmask +// representing the resulting enabled modes. +OPENSSL_EXPORT uint32_t SSL_set_mode(SSL *ssl, uint32_t mode); + +// SSL_clear_mode disables all modes set in |mode| (which should be one or more +// of the |SSL_MODE_*| values, ORed together) in |ssl|. It returns a bitmask +// representing the resulting enabled modes. +OPENSSL_EXPORT uint32_t SSL_clear_mode(SSL *ssl, uint32_t mode); + +// SSL_get_mode returns a bitmask of |SSL_MODE_*| values that represent all the +// modes enabled for |ssl|. +OPENSSL_EXPORT uint32_t SSL_get_mode(const SSL *ssl); + +// SSL_CTX_set0_buffer_pool sets a |CRYPTO_BUFFER_POOL| that will be used to +// store certificates. This can allow multiple connections to share +// certificates and thus save memory. +// +// The SSL_CTX does not take ownership of |pool| and the caller must ensure +// that |pool| outlives |ctx| and all objects linked to it, including |SSL|, +// |X509| and |SSL_SESSION| objects. Basically, don't ever free |pool|. +OPENSSL_EXPORT void SSL_CTX_set0_buffer_pool(SSL_CTX *ctx, + CRYPTO_BUFFER_POOL *pool); + + +// Configuring certificates and private keys. +// +// These functions configure the connection's leaf certificate, private key, and +// certificate chain. The certificate chain is ordered leaf to root (as sent on +// the wire) but does not include the leaf. Both client and server certificates +// use these functions. +// +// Certificates and keys may be configured before the handshake or dynamically +// in the early callback and certificate callback. + +// SSL_CTX_use_certificate sets |ctx|'s leaf certificate to |x509|. It returns +// one on success and zero on failure. +OPENSSL_EXPORT int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x509); + +// SSL_use_certificate sets |ssl|'s leaf certificate to |x509|. It returns one +// on success and zero on failure. +OPENSSL_EXPORT int SSL_use_certificate(SSL *ssl, X509 *x509); + +// SSL_CTX_use_PrivateKey sets |ctx|'s private key to |pkey|. It returns one on +// success and zero on failure. +OPENSSL_EXPORT int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey); + +// SSL_use_PrivateKey sets |ssl|'s private key to |pkey|. It returns one on +// success and zero on failure. +OPENSSL_EXPORT int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey); + +// SSL_CTX_set0_chain sets |ctx|'s certificate chain, excluding the leaf, to +// |chain|. On success, it returns one and takes ownership of |chain|. +// Otherwise, it returns zero. +OPENSSL_EXPORT int SSL_CTX_set0_chain(SSL_CTX *ctx, STACK_OF(X509) *chain); + +// SSL_CTX_set1_chain sets |ctx|'s certificate chain, excluding the leaf, to +// |chain|. It returns one on success and zero on failure. The caller retains +// ownership of |chain| and may release it freely. +OPENSSL_EXPORT int SSL_CTX_set1_chain(SSL_CTX *ctx, STACK_OF(X509) *chain); + +// SSL_set0_chain sets |ssl|'s certificate chain, excluding the leaf, to +// |chain|. On success, it returns one and takes ownership of |chain|. +// Otherwise, it returns zero. +OPENSSL_EXPORT int SSL_set0_chain(SSL *ssl, STACK_OF(X509) *chain); + +// SSL_set1_chain sets |ssl|'s certificate chain, excluding the leaf, to +// |chain|. It returns one on success and zero on failure. The caller retains +// ownership of |chain| and may release it freely. +OPENSSL_EXPORT int SSL_set1_chain(SSL *ssl, STACK_OF(X509) *chain); + +// SSL_CTX_add0_chain_cert appends |x509| to |ctx|'s certificate chain. On +// success, it returns one and takes ownership of |x509|. Otherwise, it returns +// zero. +OPENSSL_EXPORT int SSL_CTX_add0_chain_cert(SSL_CTX *ctx, X509 *x509); + +// SSL_CTX_add1_chain_cert appends |x509| to |ctx|'s certificate chain. It +// returns one on success and zero on failure. The caller retains ownership of +// |x509| and may release it freely. +OPENSSL_EXPORT int SSL_CTX_add1_chain_cert(SSL_CTX *ctx, X509 *x509); + +// SSL_add0_chain_cert appends |x509| to |ctx|'s certificate chain. On success, +// it returns one and takes ownership of |x509|. Otherwise, it returns zero. +OPENSSL_EXPORT int SSL_add0_chain_cert(SSL *ssl, X509 *x509); + +// SSL_CTX_add_extra_chain_cert calls |SSL_CTX_add0_chain_cert|. +OPENSSL_EXPORT int SSL_CTX_add_extra_chain_cert(SSL_CTX *ctx, X509 *x509); + +// SSL_add1_chain_cert appends |x509| to |ctx|'s certificate chain. It returns +// one on success and zero on failure. The caller retains ownership of |x509| +// and may release it freely. +OPENSSL_EXPORT int SSL_add1_chain_cert(SSL *ssl, X509 *x509); + +// SSL_CTX_clear_chain_certs clears |ctx|'s certificate chain and returns +// one. +OPENSSL_EXPORT int SSL_CTX_clear_chain_certs(SSL_CTX *ctx); + +// SSL_CTX_clear_extra_chain_certs calls |SSL_CTX_clear_chain_certs|. +OPENSSL_EXPORT int SSL_CTX_clear_extra_chain_certs(SSL_CTX *ctx); + +// SSL_clear_chain_certs clears |ssl|'s certificate chain and returns one. +OPENSSL_EXPORT int SSL_clear_chain_certs(SSL *ssl); + +// SSL_CTX_set_cert_cb sets a callback that is called to select a certificate. +// The callback returns one on success, zero on internal error, and a negative +// number on failure or to pause the handshake. If the handshake is paused, +// |SSL_get_error| will return |SSL_ERROR_WANT_X509_LOOKUP|. +// +// On the client, the callback may call |SSL_get0_certificate_types| and +// |SSL_get_client_CA_list| for information on the server's certificate +// request. +// +// On the server, the callback will be called on non-resumption handshakes, +// after extensions have been processed. +OPENSSL_EXPORT void SSL_CTX_set_cert_cb(SSL_CTX *ctx, + int (*cb)(SSL *ssl, void *arg), + void *arg); + +// SSL_set_cert_cb sets a callback that is called to select a certificate. The +// callback returns one on success, zero on internal error, and a negative +// number on failure or to pause the handshake. If the handshake is paused, +// |SSL_get_error| will return |SSL_ERROR_WANT_X509_LOOKUP|. +// +// On the client, the callback may call |SSL_get0_certificate_types| and +// |SSL_get_client_CA_list| for information on the server's certificate +// request. +OPENSSL_EXPORT void SSL_set_cert_cb(SSL *ssl, int (*cb)(SSL *ssl, void *arg), + void *arg); + +// SSL_get0_certificate_types, for a client, sets |*out_types| to an array +// containing the client certificate types requested by a server. It returns the +// length of the array. +// +// The behavior of this function is undefined except during the callbacks set by +// by |SSL_CTX_set_cert_cb| and |SSL_CTX_set_client_cert_cb| or when the +// handshake is paused because of them. +OPENSSL_EXPORT size_t SSL_get0_certificate_types(SSL *ssl, + const uint8_t **out_types); + +// SSL_certs_clear resets the private key, leaf certificate, and certificate +// chain of |ssl|. +OPENSSL_EXPORT void SSL_certs_clear(SSL *ssl); + +// SSL_CTX_check_private_key returns one if the certificate and private key +// configured in |ctx| are consistent and zero otherwise. +OPENSSL_EXPORT int SSL_CTX_check_private_key(const SSL_CTX *ctx); + +// SSL_check_private_key returns one if the certificate and private key +// configured in |ssl| are consistent and zero otherwise. +OPENSSL_EXPORT int SSL_check_private_key(const SSL *ssl); + +// SSL_CTX_get0_certificate returns |ctx|'s leaf certificate. +OPENSSL_EXPORT X509 *SSL_CTX_get0_certificate(const SSL_CTX *ctx); + +// SSL_get_certificate returns |ssl|'s leaf certificate. +OPENSSL_EXPORT X509 *SSL_get_certificate(const SSL *ssl); + +// SSL_CTX_get0_privatekey returns |ctx|'s private key. +OPENSSL_EXPORT EVP_PKEY *SSL_CTX_get0_privatekey(const SSL_CTX *ctx); + +// SSL_get_privatekey returns |ssl|'s private key. +OPENSSL_EXPORT EVP_PKEY *SSL_get_privatekey(const SSL *ssl); + +// SSL_CTX_get0_chain_certs sets |*out_chain| to |ctx|'s certificate chain and +// returns one. +OPENSSL_EXPORT int SSL_CTX_get0_chain_certs(const SSL_CTX *ctx, + STACK_OF(X509) **out_chain); + +// SSL_CTX_get_extra_chain_certs calls |SSL_CTX_get0_chain_certs|. +OPENSSL_EXPORT int SSL_CTX_get_extra_chain_certs(const SSL_CTX *ctx, + STACK_OF(X509) **out_chain); + +// SSL_get0_chain_certs sets |*out_chain| to |ssl|'s certificate chain and +// returns one. +OPENSSL_EXPORT int SSL_get0_chain_certs(const SSL *ssl, + STACK_OF(X509) **out_chain); + +// SSL_CTX_set_signed_cert_timestamp_list sets the list of signed certificate +// timestamps that is sent to clients that request it. The |list| argument must +// contain one or more SCT structures serialised as a SignedCertificateTimestamp +// List (see https://tools.ietf.org/html/rfc6962#section-3.3) – i.e. each SCT +// is prefixed by a big-endian, uint16 length and the concatenation of one or +// more such prefixed SCTs are themselves also prefixed by a uint16 length. It +// returns one on success and zero on error. The caller retains ownership of +// |list|. +OPENSSL_EXPORT int SSL_CTX_set_signed_cert_timestamp_list(SSL_CTX *ctx, + const uint8_t *list, + size_t list_len); + +// SSL_set_signed_cert_timestamp_list sets the list of signed certificate +// timestamps that is sent to clients that request is. The same format as the +// one used for |SSL_CTX_set_signed_cert_timestamp_list| applies. The caller +// retains ownership of |list|. +OPENSSL_EXPORT int SSL_set_signed_cert_timestamp_list(SSL *ctx, + const uint8_t *list, + size_t list_len); + +// SSL_CTX_set_ocsp_response sets the OCSP response that is sent to clients +// which request it. It returns one on success and zero on error. The caller +// retains ownership of |response|. +OPENSSL_EXPORT int SSL_CTX_set_ocsp_response(SSL_CTX *ctx, + const uint8_t *response, + size_t response_len); + +// SSL_set_ocsp_response sets the OCSP response that is sent to clients which +// request it. It returns one on success and zero on error. The caller retains +// ownership of |response|. +OPENSSL_EXPORT int SSL_set_ocsp_response(SSL *ssl, + const uint8_t *response, + size_t response_len); + +// SSL_SIGN_* are signature algorithm values as defined in TLS 1.3. +#define SSL_SIGN_RSA_PKCS1_SHA1 0x0201 +#define SSL_SIGN_RSA_PKCS1_SHA256 0x0401 +#define SSL_SIGN_RSA_PKCS1_SHA384 0x0501 +#define SSL_SIGN_RSA_PKCS1_SHA512 0x0601 +#define SSL_SIGN_ECDSA_SHA1 0x0203 +#define SSL_SIGN_ECDSA_SECP256R1_SHA256 0x0403 +#define SSL_SIGN_ECDSA_SECP384R1_SHA384 0x0503 +#define SSL_SIGN_ECDSA_SECP521R1_SHA512 0x0603 +#define SSL_SIGN_RSA_PSS_SHA256 0x0804 +#define SSL_SIGN_RSA_PSS_SHA384 0x0805 +#define SSL_SIGN_RSA_PSS_SHA512 0x0806 +#define SSL_SIGN_ED25519 0x0807 + +// SSL_SIGN_RSA_PKCS1_MD5_SHA1 is an internal signature algorithm used to +// specify raw RSASSA-PKCS1-v1_5 with an MD5/SHA-1 concatenation, as used in TLS +// before TLS 1.2. +#define SSL_SIGN_RSA_PKCS1_MD5_SHA1 0xff01 + +// SSL_get_signature_algorithm_name returns a human-readable name for |sigalg|, +// or NULL if unknown. If |include_curve| is one, the curve for ECDSA algorithms +// is included as in TLS 1.3. Otherwise, it is excluded as in TLS 1.2. +OPENSSL_EXPORT const char *SSL_get_signature_algorithm_name(uint16_t sigalg, + int include_curve); + +// SSL_get_signature_algorithm_key_type returns the key type associated with +// |sigalg| as an |EVP_PKEY_*| constant or |EVP_PKEY_NONE| if unknown. +OPENSSL_EXPORT int SSL_get_signature_algorithm_key_type(uint16_t sigalg); + +// SSL_get_signature_algorithm_digest returns the digest function associated +// with |sigalg| or |NULL| if |sigalg| has no prehash (Ed25519) or is unknown. +OPENSSL_EXPORT const EVP_MD *SSL_get_signature_algorithm_digest( + uint16_t sigalg); + +// SSL_is_signature_algorithm_rsa_pss returns one if |sigalg| is an RSA-PSS +// signature algorithm and zero otherwise. +OPENSSL_EXPORT int SSL_is_signature_algorithm_rsa_pss(uint16_t sigalg); + +// SSL_CTX_set_signing_algorithm_prefs configures |ctx| to use |prefs| as the +// preference list when signing with |ctx|'s private key. It returns one on +// success and zero on error. |prefs| should not include the internal-only value +// |SSL_SIGN_RSA_PKCS1_MD5_SHA1|. +OPENSSL_EXPORT int SSL_CTX_set_signing_algorithm_prefs(SSL_CTX *ctx, + const uint16_t *prefs, + size_t num_prefs); + +// SSL_set_signing_algorithm_prefs configures |ssl| to use |prefs| as the +// preference list when signing with |ssl|'s private key. It returns one on +// success and zero on error. |prefs| should not include the internal-only value +// |SSL_SIGN_RSA_PKCS1_MD5_SHA1|. +OPENSSL_EXPORT int SSL_set_signing_algorithm_prefs(SSL *ssl, + const uint16_t *prefs, + size_t num_prefs); + + +// Certificate and private key convenience functions. + +// SSL_CTX_set_chain_and_key sets the certificate chain and private key for a +// TLS client or server. References to the given |CRYPTO_BUFFER| and |EVP_PKEY| +// objects are added as needed. Exactly one of |privkey| or |privkey_method| +// may be non-NULL. Returns one on success and zero on error. +OPENSSL_EXPORT int SSL_CTX_set_chain_and_key( + SSL_CTX *ctx, CRYPTO_BUFFER *const *certs, size_t num_certs, + EVP_PKEY *privkey, const SSL_PRIVATE_KEY_METHOD *privkey_method); + +// SSL_set_chain_and_key sets the certificate chain and private key for a TLS +// client or server. References to the given |CRYPTO_BUFFER| and |EVP_PKEY| +// objects are added as needed. Exactly one of |privkey| or |privkey_method| +// may be non-NULL. Returns one on success and zero on error. +OPENSSL_EXPORT int SSL_set_chain_and_key( + SSL *ssl, CRYPTO_BUFFER *const *certs, size_t num_certs, EVP_PKEY *privkey, + const SSL_PRIVATE_KEY_METHOD *privkey_method); + +// SSL_CTX_use_RSAPrivateKey sets |ctx|'s private key to |rsa|. It returns one +// on success and zero on failure. +OPENSSL_EXPORT int SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa); + +// SSL_use_RSAPrivateKey sets |ctx|'s private key to |rsa|. It returns one on +// success and zero on failure. +OPENSSL_EXPORT int SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa); + +// The following functions configure certificates or private keys but take as +// input DER-encoded structures. They return one on success and zero on +// failure. + +OPENSSL_EXPORT int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, size_t der_len, + const uint8_t *der); +OPENSSL_EXPORT int SSL_use_certificate_ASN1(SSL *ssl, const uint8_t *der, + size_t der_len); + +OPENSSL_EXPORT int SSL_CTX_use_PrivateKey_ASN1(int pk, SSL_CTX *ctx, + const uint8_t *der, + size_t der_len); +OPENSSL_EXPORT int SSL_use_PrivateKey_ASN1(int type, SSL *ssl, + const uint8_t *der, size_t der_len); + +OPENSSL_EXPORT int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, + const uint8_t *der, + size_t der_len); +OPENSSL_EXPORT int SSL_use_RSAPrivateKey_ASN1(SSL *ssl, const uint8_t *der, + size_t der_len); + +// The following functions configure certificates or private keys but take as +// input files to read from. They return one on success and zero on failure. The +// |type| parameter is one of the |SSL_FILETYPE_*| values and determines whether +// the file's contents are read as PEM or DER. + +#define SSL_FILETYPE_PEM 1 +#define SSL_FILETYPE_ASN1 2 + +OPENSSL_EXPORT int SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx, + const char *file, + int type); +OPENSSL_EXPORT int SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, + int type); + +OPENSSL_EXPORT int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, + int type); +OPENSSL_EXPORT int SSL_use_certificate_file(SSL *ssl, const char *file, + int type); + +OPENSSL_EXPORT int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, + int type); +OPENSSL_EXPORT int SSL_use_PrivateKey_file(SSL *ssl, const char *file, + int type); + +// SSL_CTX_use_certificate_chain_file configures certificates for |ctx|. It +// reads the contents of |file| as a PEM-encoded leaf certificate followed +// optionally by the certificate chain to send to the peer. It returns one on +// success and zero on failure. +OPENSSL_EXPORT int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, + const char *file); + +// SSL_CTX_set_default_passwd_cb sets the password callback for PEM-based +// convenience functions called on |ctx|. +OPENSSL_EXPORT void SSL_CTX_set_default_passwd_cb(SSL_CTX *ctx, + pem_password_cb *cb); + +// SSL_CTX_get_default_passwd_cb returns the callback set by +// |SSL_CTX_set_default_passwd_cb|. +OPENSSL_EXPORT pem_password_cb *SSL_CTX_get_default_passwd_cb( + const SSL_CTX *ctx); + +// SSL_CTX_set_default_passwd_cb_userdata sets the userdata parameter for +// |ctx|'s password callback. +OPENSSL_EXPORT void SSL_CTX_set_default_passwd_cb_userdata(SSL_CTX *ctx, + void *data); + +// SSL_CTX_get_default_passwd_cb_userdata returns the userdata parameter set by +// |SSL_CTX_set_default_passwd_cb_userdata|. +OPENSSL_EXPORT void *SSL_CTX_get_default_passwd_cb_userdata(const SSL_CTX *ctx); + + +// Custom private keys. + +enum ssl_private_key_result_t { + ssl_private_key_success, + ssl_private_key_retry, + ssl_private_key_failure, +}; + +// ssl_private_key_method_st (aka |SSL_PRIVATE_KEY_METHOD|) describes private +// key hooks. This is used to off-load signing operations to a custom, +// potentially asynchronous, backend. Metadata about the key such as the type +// and size are parsed out of the certificate. +struct ssl_private_key_method_st { + // sign signs the message |in| in using the specified signature algorithm. On + // success, it returns |ssl_private_key_success| and writes at most |max_out| + // bytes of signature data to |out| and sets |*out_len| to the number of bytes + // written. On failure, it returns |ssl_private_key_failure|. If the operation + // has not completed, it returns |ssl_private_key_retry|. |sign| should + // arrange for the high-level operation on |ssl| to be retried when the + // operation is completed. This will result in a call to |complete|. + // + // |signature_algorithm| is one of the |SSL_SIGN_*| values, as defined in TLS + // 1.3. Note that, in TLS 1.2, ECDSA algorithms do not require that curve + // sizes match hash sizes, so the curve portion of |SSL_SIGN_ECDSA_*| values + // must be ignored. BoringSSL will internally handle the curve matching logic + // where appropriate. + // + // It is an error to call |sign| while another private key operation is in + // progress on |ssl|. + enum ssl_private_key_result_t (*sign)(SSL *ssl, uint8_t *out, size_t *out_len, + size_t max_out, + uint16_t signature_algorithm, + const uint8_t *in, size_t in_len); + + // decrypt decrypts |in_len| bytes of encrypted data from |in|. On success it + // returns |ssl_private_key_success|, writes at most |max_out| bytes of + // decrypted data to |out| and sets |*out_len| to the actual number of bytes + // written. On failure it returns |ssl_private_key_failure|. If the operation + // has not completed, it returns |ssl_private_key_retry|. The caller should + // arrange for the high-level operation on |ssl| to be retried when the + // operation is completed, which will result in a call to |complete|. This + // function only works with RSA keys and should perform a raw RSA decryption + // operation with no padding. + // + // It is an error to call |decrypt| while another private key operation is in + // progress on |ssl|. + enum ssl_private_key_result_t (*decrypt)(SSL *ssl, uint8_t *out, + size_t *out_len, size_t max_out, + const uint8_t *in, size_t in_len); + + // complete completes a pending operation. If the operation has completed, it + // returns |ssl_private_key_success| and writes the result to |out| as in + // |sign|. Otherwise, it returns |ssl_private_key_failure| on failure and + // |ssl_private_key_retry| if the operation is still in progress. + // + // |complete| may be called arbitrarily many times before completion, but it + // is an error to call |complete| if there is no pending operation in progress + // on |ssl|. + enum ssl_private_key_result_t (*complete)(SSL *ssl, uint8_t *out, + size_t *out_len, size_t max_out); +}; + +// SSL_set_private_key_method configures a custom private key on |ssl|. +// |key_method| must remain valid for the lifetime of |ssl|. +OPENSSL_EXPORT void SSL_set_private_key_method( + SSL *ssl, const SSL_PRIVATE_KEY_METHOD *key_method); + +// SSL_CTX_set_private_key_method configures a custom private key on |ctx|. +// |key_method| must remain valid for the lifetime of |ctx|. +OPENSSL_EXPORT void SSL_CTX_set_private_key_method( + SSL_CTX *ctx, const SSL_PRIVATE_KEY_METHOD *key_method); + + +// Cipher suites. +// +// |SSL_CIPHER| objects represent cipher suites. + +DEFINE_CONST_STACK_OF(SSL_CIPHER) + +// SSL_get_cipher_by_value returns the structure representing a TLS cipher +// suite based on its assigned number, or NULL if unknown. See +// https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-4. +OPENSSL_EXPORT const SSL_CIPHER *SSL_get_cipher_by_value(uint16_t value); + +// SSL_CIPHER_get_id returns |cipher|'s id. It may be cast to a |uint16_t| to +// get the cipher suite value. +OPENSSL_EXPORT uint32_t SSL_CIPHER_get_id(const SSL_CIPHER *cipher); + +// SSL_CIPHER_is_aead returns one if |cipher| uses an AEAD cipher. +OPENSSL_EXPORT int SSL_CIPHER_is_aead(const SSL_CIPHER *cipher); + +// SSL_CIPHER_is_block_cipher returns one if |cipher| is a block cipher. +OPENSSL_EXPORT int SSL_CIPHER_is_block_cipher(const SSL_CIPHER *cipher); + +// SSL_CIPHER_get_cipher_nid returns the NID for |cipher|'s bulk +// cipher. Possible values are |NID_aes_128_gcm|, |NID_aes_256_gcm|, +// |NID_chacha20_poly1305|, |NID_aes_128_cbc|, |NID_aes_256_cbc|, and +// |NID_des_ede3_cbc|. +OPENSSL_EXPORT int SSL_CIPHER_get_cipher_nid(const SSL_CIPHER *cipher); + +// SSL_CIPHER_get_digest_nid returns the NID for |cipher|'s HMAC if it is a +// legacy cipher suite. For modern AEAD-based ciphers (see +// |SSL_CIPHER_is_aead|), it returns |NID_undef|. +// +// Note this function only returns the legacy HMAC digest, not the PRF hash. +OPENSSL_EXPORT int SSL_CIPHER_get_digest_nid(const SSL_CIPHER *cipher); + +// SSL_CIPHER_get_kx_nid returns the NID for |cipher|'s key exchange. This may +// be |NID_kx_rsa|, |NID_kx_ecdhe|, or |NID_kx_psk| for TLS 1.2. In TLS 1.3, +// cipher suites do not specify the key exchange, so this function returns +// |NID_kx_any|. +OPENSSL_EXPORT int SSL_CIPHER_get_kx_nid(const SSL_CIPHER *cipher); + +// SSL_CIPHER_get_auth_nid returns the NID for |cipher|'s authentication +// type. This may be |NID_auth_rsa|, |NID_auth_ecdsa|, or |NID_auth_psk| for TLS +// 1.2. In TLS 1.3, cipher suites do not specify authentication, so this +// function returns |NID_auth_any|. +OPENSSL_EXPORT int SSL_CIPHER_get_auth_nid(const SSL_CIPHER *cipher); + +// SSL_CIPHER_get_prf_nid retuns the NID for |cipher|'s PRF hash. If |cipher| is +// a pre-TLS-1.2 cipher, it returns |NID_md5_sha1| but note these ciphers use +// SHA-256 in TLS 1.2. Other return values may be treated uniformly in all +// applicable versions. +OPENSSL_EXPORT int SSL_CIPHER_get_prf_nid(const SSL_CIPHER *cipher); + +// SSL_CIPHER_get_min_version returns the minimum protocol version required +// for |cipher|. +OPENSSL_EXPORT uint16_t SSL_CIPHER_get_min_version(const SSL_CIPHER *cipher); + +// SSL_CIPHER_get_max_version returns the maximum protocol version that +// supports |cipher|. +OPENSSL_EXPORT uint16_t SSL_CIPHER_get_max_version(const SSL_CIPHER *cipher); + +// SSL_CIPHER_standard_name returns the standard IETF name for |cipher|. For +// example, "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256". +OPENSSL_EXPORT const char *SSL_CIPHER_standard_name(const SSL_CIPHER *cipher); + +// SSL_CIPHER_get_name returns the OpenSSL name of |cipher|. For example, +// "ECDHE-RSA-AES128-GCM-SHA256". +OPENSSL_EXPORT const char *SSL_CIPHER_get_name(const SSL_CIPHER *cipher); + +// SSL_CIPHER_get_kx_name returns a string that describes the key-exchange +// method used by |cipher|. For example, "ECDHE_ECDSA". TLS 1.3 AEAD-only +// ciphers return the string "GENERIC". +OPENSSL_EXPORT const char *SSL_CIPHER_get_kx_name(const SSL_CIPHER *cipher); + +// SSL_CIPHER_get_bits returns the strength, in bits, of |cipher|. If +// |out_alg_bits| is not NULL, it writes the number of bits consumed by the +// symmetric algorithm to |*out_alg_bits|. +OPENSSL_EXPORT int SSL_CIPHER_get_bits(const SSL_CIPHER *cipher, + int *out_alg_bits); + + +// Cipher suite configuration. +// +// OpenSSL uses a mini-language to configure cipher suites. The language +// maintains an ordered list of enabled ciphers, along with an ordered list of +// disabled but available ciphers. Initially, all ciphers are disabled with a +// default ordering. The cipher string is then interpreted as a sequence of +// directives, separated by colons, each of which modifies this state. +// +// Most directives consist of a one character or empty opcode followed by a +// selector which matches a subset of available ciphers. +// +// Available opcodes are: +// +// The empty opcode enables and appends all matching disabled ciphers to the +// end of the enabled list. The newly appended ciphers are ordered relative to +// each other matching their order in the disabled list. +// +// |-| disables all matching enabled ciphers and prepends them to the disabled +// list, with relative order from the enabled list preserved. This means the +// most recently disabled ciphers get highest preference relative to other +// disabled ciphers if re-enabled. +// +// |+| moves all matching enabled ciphers to the end of the enabled list, with +// relative order preserved. +// +// |!| deletes all matching ciphers, enabled or not, from either list. Deleted +// ciphers will not matched by future operations. +// +// A selector may be a specific cipher (using either the standard or OpenSSL +// name for the cipher) or one or more rules separated by |+|. The final +// selector matches the intersection of each rule. For instance, |AESGCM+aECDSA| +// matches ECDSA-authenticated AES-GCM ciphers. +// +// Available cipher rules are: +// +// |ALL| matches all ciphers. +// +// |kRSA|, |kDHE|, |kECDHE|, and |kPSK| match ciphers using plain RSA, DHE, +// ECDHE, and plain PSK key exchanges, respectively. Note that ECDHE_PSK is +// matched by |kECDHE| and not |kPSK|. +// +// |aRSA|, |aECDSA|, and |aPSK| match ciphers authenticated by RSA, ECDSA, and +// a pre-shared key, respectively. +// +// |RSA|, |DHE|, |ECDHE|, |PSK|, |ECDSA|, and |PSK| are aliases for the +// corresponding |k*| or |a*| cipher rule. |RSA| is an alias for |kRSA|, not +// |aRSA|. +// +// |3DES|, |AES128|, |AES256|, |AES|, |AESGCM|, |CHACHA20| match ciphers +// whose bulk cipher use the corresponding encryption scheme. Note that +// |AES|, |AES128|, and |AES256| match both CBC and GCM ciphers. +// +// |SHA1|, |SHA256|, and |SHA384| match legacy cipher suites using the +// corresponding hash function in their MAC. AEADs are matched by none of +// these. +// +// |SHA| is an alias for |SHA1|. +// +// Although implemented, authentication-only ciphers match no rules and must be +// explicitly selected by name. +// +// Deprecated cipher rules: +// +// |kEDH|, |EDH|, |kEECDH|, and |EECDH| are legacy aliases for |kDHE|, |DHE|, +// |kECDHE|, and |ECDHE|, respectively. +// +// |HIGH| is an alias for |ALL|. +// +// |FIPS| is an alias for |HIGH|. +// +// |SSLv3| and |TLSv1| match ciphers available in TLS 1.1 or earlier. +// |TLSv1_2| matches ciphers new in TLS 1.2. This is confusing and should not +// be used. +// +// Unknown rules are silently ignored by legacy APIs, and rejected by APIs with +// "strict" in the name, which should be preferred. Cipher lists can be long +// and it's easy to commit typos. Strict functions will also reject the use of +// spaces, semi-colons and commas as alternative separators. +// +// The special |@STRENGTH| directive will sort all enabled ciphers by strength. +// +// The |DEFAULT| directive, when appearing at the front of the string, expands +// to the default ordering of available ciphers. +// +// If configuring a server, one may also configure equal-preference groups to +// partially respect the client's preferences when +// |SSL_OP_CIPHER_SERVER_PREFERENCE| is enabled. Ciphers in an equal-preference +// group have equal priority and use the client order. This may be used to +// enforce that AEADs are preferred but select AES-GCM vs. ChaCha20-Poly1305 +// based on client preferences. An equal-preference is specified with square +// brackets, combining multiple selectors separated by |. For example: +// +// [ECDHE-ECDSA-CHACHA20-POLY1305|ECDHE-ECDSA-AES128-GCM-SHA256] +// +// Once an equal-preference group is used, future directives must be +// opcode-less. Inside an equal-preference group, spaces are not allowed. +// +// TLS 1.3 ciphers do not participate in this mechanism and instead have a +// built-in preference order. Functions to set cipher lists do not affect TLS +// 1.3, and functions to query the cipher list do not include TLS 1.3 +// ciphers. + +// SSL_DEFAULT_CIPHER_LIST is the default cipher suite configuration. It is +// substituted when a cipher string starts with 'DEFAULT'. +#define SSL_DEFAULT_CIPHER_LIST "ALL" + +// SSL_CTX_set_strict_cipher_list configures the cipher list for |ctx|, +// evaluating |str| as a cipher string and returning error if |str| contains +// anything meaningless. It returns one on success and zero on failure. +OPENSSL_EXPORT int SSL_CTX_set_strict_cipher_list(SSL_CTX *ctx, + const char *str); + +// SSL_CTX_set_cipher_list configures the cipher list for |ctx|, evaluating +// |str| as a cipher string. It returns one on success and zero on failure. +// +// Prefer to use |SSL_CTX_set_strict_cipher_list|. This function tolerates +// garbage inputs, unless an empty cipher list results. +OPENSSL_EXPORT int SSL_CTX_set_cipher_list(SSL_CTX *ctx, const char *str); + +// SSL_set_strict_cipher_list configures the cipher list for |ssl|, evaluating +// |str| as a cipher string and returning error if |str| contains anything +// meaningless. It returns one on success and zero on failure. +OPENSSL_EXPORT int SSL_set_strict_cipher_list(SSL *ssl, const char *str); + +// SSL_set_cipher_list configures the cipher list for |ssl|, evaluating |str| as +// a cipher string. It returns one on success and zero on failure. +// +// Prefer to use |SSL_set_strict_cipher_list|. This function tolerates garbage +// inputs, unless an empty cipher list results. +OPENSSL_EXPORT int SSL_set_cipher_list(SSL *ssl, const char *str); + +// SSL_CTX_get_ciphers returns the cipher list for |ctx|, in order of +// preference. +OPENSSL_EXPORT STACK_OF(SSL_CIPHER) *SSL_CTX_get_ciphers(const SSL_CTX *ctx); + +// SSL_CTX_cipher_in_group returns one if the |i|th cipher (see +// |SSL_CTX_get_ciphers|) is in the same equipreference group as the one +// following it and zero otherwise. +OPENSSL_EXPORT int SSL_CTX_cipher_in_group(const SSL_CTX *ctx, size_t i); + +// SSL_get_ciphers returns the cipher list for |ssl|, in order of preference. +OPENSSL_EXPORT STACK_OF(SSL_CIPHER) *SSL_get_ciphers(const SSL *ssl); + + +// Connection information. + +// SSL_is_init_finished returns one if |ssl| has completed its initial handshake +// and has no pending handshake. It returns zero otherwise. +OPENSSL_EXPORT int SSL_is_init_finished(const SSL *ssl); + +// SSL_in_init returns one if |ssl| has a pending handshake and zero +// otherwise. +OPENSSL_EXPORT int SSL_in_init(const SSL *ssl); + +// SSL_in_false_start returns one if |ssl| has a pending handshake that is in +// False Start. |SSL_write| may be called at this point without waiting for the +// peer, but |SSL_read| will complete the handshake before accepting application +// data. +// +// See also |SSL_MODE_ENABLE_FALSE_START|. +OPENSSL_EXPORT int SSL_in_false_start(const SSL *ssl); + +// SSL_get_peer_certificate returns the peer's leaf certificate or NULL if the +// peer did not use certificates. The caller must call |X509_free| on the +// result to release it. +OPENSSL_EXPORT X509 *SSL_get_peer_certificate(const SSL *ssl); + +// SSL_get_peer_cert_chain returns the peer's certificate chain or NULL if +// unavailable or the peer did not use certificates. This is the unverified list +// of certificates as sent by the peer, not the final chain built during +// verification. The caller does not take ownership of the result. +// +// WARNING: This function behaves differently between client and server. If +// |ssl| is a server, the returned chain does not include the leaf certificate. +// If a client, it does. +OPENSSL_EXPORT STACK_OF(X509) *SSL_get_peer_cert_chain(const SSL *ssl); + +// SSL_get_peer_full_cert_chain returns the peer's certificate chain, or NULL if +// unavailable or the peer did not use certificates. This is the unverified list +// of certificates as sent by the peer, not the final chain built during +// verification. The caller does not take ownership of the result. +// +// This is the same as |SSL_get_peer_cert_chain| except that this function +// always returns the full chain, i.e. the first element of the return value +// (if any) will be the leaf certificate. In constrast, +// |SSL_get_peer_cert_chain| returns only the intermediate certificates if the +// |ssl| is a server. +OPENSSL_EXPORT STACK_OF(X509) *SSL_get_peer_full_cert_chain(const SSL *ssl); + +// SSL_get0_peer_certificates returns the peer's certificate chain, or NULL if +// unavailable or the peer did not use certificates. This is the unverified list +// of certificates as sent by the peer, not the final chain built during +// verification. The caller does not take ownership of the result. +// +// This is the |CRYPTO_BUFFER| variant of |SSL_get_peer_full_cert_chain|. +OPENSSL_EXPORT STACK_OF(CRYPTO_BUFFER) * + SSL_get0_peer_certificates(const SSL *ssl); + +// SSL_get0_signed_cert_timestamp_list sets |*out| and |*out_len| to point to +// |*out_len| bytes of SCT information from the server. This is only valid if +// |ssl| is a client. The SCT information is a SignedCertificateTimestampList +// (including the two leading length bytes). +// See https://tools.ietf.org/html/rfc6962#section-3.3 +// If no SCT was received then |*out_len| will be zero on return. +// +// WARNING: the returned data is not guaranteed to be well formed. +OPENSSL_EXPORT void SSL_get0_signed_cert_timestamp_list(const SSL *ssl, + const uint8_t **out, + size_t *out_len); + +// SSL_get0_ocsp_response sets |*out| and |*out_len| to point to |*out_len| +// bytes of an OCSP response from the server. This is the DER encoding of an +// OCSPResponse type as defined in RFC 2560. +// +// WARNING: the returned data is not guaranteed to be well formed. +OPENSSL_EXPORT void SSL_get0_ocsp_response(const SSL *ssl, const uint8_t **out, + size_t *out_len); + +// SSL_get_tls_unique writes at most |max_out| bytes of the tls-unique value +// for |ssl| to |out| and sets |*out_len| to the number of bytes written. It +// returns one on success or zero on error. In general |max_out| should be at +// least 12. +// +// This function will always fail if the initial handshake has not completed. +// The tls-unique value will change after a renegotiation but, since +// renegotiations can be initiated by the server at any point, the higher-level +// protocol must either leave them disabled or define states in which the +// tls-unique value can be read. +// +// The tls-unique value is defined by +// https://tools.ietf.org/html/rfc5929#section-3.1. Due to a weakness in the +// TLS protocol, tls-unique is broken for resumed connections unless the +// Extended Master Secret extension is negotiated. Thus this function will +// return zero if |ssl| performed session resumption unless EMS was used when +// negotiating the original session. +OPENSSL_EXPORT int SSL_get_tls_unique(const SSL *ssl, uint8_t *out, + size_t *out_len, size_t max_out); + +// SSL_get_extms_support returns one if the Extended Master Secret extension or +// TLS 1.3 was negotiated. Otherwise, it returns zero. +OPENSSL_EXPORT int SSL_get_extms_support(const SSL *ssl); + +// SSL_get_current_cipher returns the cipher used in the current outgoing +// connection state, or NULL if the null cipher is active. +OPENSSL_EXPORT const SSL_CIPHER *SSL_get_current_cipher(const SSL *ssl); + +// SSL_session_reused returns one if |ssl| performed an abbreviated handshake +// and zero otherwise. +// +// TODO(davidben): Hammer down the semantics of this API while a handshake, +// initial or renego, is in progress. +OPENSSL_EXPORT int SSL_session_reused(const SSL *ssl); + +// SSL_get_secure_renegotiation_support returns one if the peer supports secure +// renegotiation (RFC 5746) or TLS 1.3. Otherwise, it returns zero. +OPENSSL_EXPORT int SSL_get_secure_renegotiation_support(const SSL *ssl); + +// SSL_export_keying_material exports a value derived from the master secret, as +// specified in RFC 5705. It writes |out_len| 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 one on success and zero otherwise. +OPENSSL_EXPORT int SSL_export_keying_material( + SSL *ssl, uint8_t *out, size_t out_len, const char *label, size_t label_len, + const uint8_t *context, size_t context_len, int use_context); + + +// Custom extensions. +// +// The custom extension functions allow TLS extensions to be added to +// ClientHello and ServerHello messages. + +// SSL_custom_ext_add_cb is a callback function that is called when the +// ClientHello (for clients) or ServerHello (for servers) is constructed. In +// the case of a server, this callback will only be called for a given +// extension if the ClientHello contained that extension – it's not possible to +// inject extensions into a ServerHello that the client didn't request. +// +// When called, |extension_value| will contain the extension number that is +// being considered for addition (so that a single callback can handle multiple +// extensions). If the callback wishes to include the extension, it must set +// |*out| to point to |*out_len| bytes of extension contents and return one. In +// this case, the corresponding |SSL_custom_ext_free_cb| callback will later be +// called with the value of |*out| once that data has been copied. +// +// If the callback does not wish to add an extension it must return zero. +// +// Alternatively, the callback can abort the connection by setting +// |*out_alert_value| to a TLS alert number and returning -1. +typedef int (*SSL_custom_ext_add_cb)(SSL *ssl, unsigned extension_value, + const uint8_t **out, size_t *out_len, + int *out_alert_value, void *add_arg); + +// SSL_custom_ext_free_cb is a callback function that is called by OpenSSL iff +// an |SSL_custom_ext_add_cb| callback previously returned one. In that case, +// this callback is called and passed the |out| pointer that was returned by +// the add callback. This is to free any dynamically allocated data created by +// the add callback. +typedef void (*SSL_custom_ext_free_cb)(SSL *ssl, unsigned extension_value, + const uint8_t *out, void *add_arg); + +// SSL_custom_ext_parse_cb is a callback function that is called by OpenSSL to +// parse an extension from the peer: that is from the ServerHello for a client +// and from the ClientHello for a server. +// +// When called, |extension_value| will contain the extension number and the +// contents of the extension are |contents_len| bytes at |contents|. +// +// The callback must return one to continue the handshake. Otherwise, if it +// returns zero, a fatal alert with value |*out_alert_value| is sent and the +// handshake is aborted. +typedef int (*SSL_custom_ext_parse_cb)(SSL *ssl, unsigned extension_value, + const uint8_t *contents, + size_t contents_len, + int *out_alert_value, void *parse_arg); + +// SSL_extension_supported returns one iff OpenSSL internally handles +// extensions of type |extension_value|. This can be used to avoid registering +// custom extension handlers for extensions that a future version of OpenSSL +// may handle internally. +OPENSSL_EXPORT int SSL_extension_supported(unsigned extension_value); + +// SSL_CTX_add_client_custom_ext registers callback functions for handling +// custom TLS extensions for client connections. +// +// If |add_cb| is NULL then an empty extension will be added in each +// ClientHello. Otherwise, see the comment for |SSL_custom_ext_add_cb| about +// this callback. +// +// The |free_cb| may be NULL if |add_cb| doesn't dynamically allocate data that +// needs to be freed. +// +// It returns one on success or zero on error. It's always an error to register +// callbacks for the same extension twice, or to register callbacks for an +// extension that OpenSSL handles internally. See |SSL_extension_supported| to +// discover, at runtime, which extensions OpenSSL handles internally. +OPENSSL_EXPORT int SSL_CTX_add_client_custom_ext( + SSL_CTX *ctx, unsigned extension_value, SSL_custom_ext_add_cb add_cb, + SSL_custom_ext_free_cb free_cb, void *add_arg, + SSL_custom_ext_parse_cb parse_cb, void *parse_arg); + +// SSL_CTX_add_server_custom_ext is the same as +// |SSL_CTX_add_client_custom_ext|, but for server connections. +// +// Unlike on the client side, if |add_cb| is NULL no extension will be added. +// The |add_cb|, if any, will only be called if the ClientHello contained a +// matching extension. +OPENSSL_EXPORT int SSL_CTX_add_server_custom_ext( + SSL_CTX *ctx, unsigned extension_value, SSL_custom_ext_add_cb add_cb, + SSL_custom_ext_free_cb free_cb, void *add_arg, + SSL_custom_ext_parse_cb parse_cb, void *parse_arg); + + +// Sessions. +// +// An |SSL_SESSION| represents an SSL session that may be resumed in an +// abbreviated handshake. It is reference-counted and immutable. Once +// established, an |SSL_SESSION| may be shared by multiple |SSL| objects on +// different threads and must not be modified. + +DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION) + +// SSL_SESSION_new returns a newly-allocated blank |SSL_SESSION| or NULL on +// error. This may be useful when writing tests but should otherwise not be +// used. +OPENSSL_EXPORT SSL_SESSION *SSL_SESSION_new(const SSL_CTX *ctx); + +// SSL_SESSION_up_ref increments the reference count of |session| and returns +// one. +OPENSSL_EXPORT int SSL_SESSION_up_ref(SSL_SESSION *session); + +// SSL_SESSION_free decrements the reference count of |session|. If it reaches +// zero, all data referenced by |session| and |session| itself are released. +OPENSSL_EXPORT void SSL_SESSION_free(SSL_SESSION *session); + +// SSL_SESSION_to_bytes serializes |in| into a newly allocated buffer and sets +// |*out_data| to that buffer and |*out_len| to its length. The caller takes +// ownership of the buffer and must call |OPENSSL_free| when done. It returns +// one on success and zero on error. +OPENSSL_EXPORT int SSL_SESSION_to_bytes(const SSL_SESSION *in, + uint8_t **out_data, size_t *out_len); + +// SSL_SESSION_to_bytes_for_ticket serializes |in|, but excludes the session +// identification information, namely the session ID and ticket. +OPENSSL_EXPORT int SSL_SESSION_to_bytes_for_ticket(const SSL_SESSION *in, + uint8_t **out_data, + size_t *out_len); + +// SSL_SESSION_from_bytes parses |in_len| bytes from |in| as an SSL_SESSION. It +// returns a newly-allocated |SSL_SESSION| on success or NULL on error. +OPENSSL_EXPORT SSL_SESSION *SSL_SESSION_from_bytes( + const uint8_t *in, size_t in_len, const SSL_CTX *ctx); + +// SSL_SESSION_get_version returns a string describing the TLS or DTLS version +// |session| was established at. For example, "TLSv1.2" or "SSLv3". +OPENSSL_EXPORT const char *SSL_SESSION_get_version(const SSL_SESSION *session); + +// SSL_SESSION_get_protocol_version returns the TLS or DTLS version |session| +// was established at. +OPENSSL_EXPORT uint16_t +SSL_SESSION_get_protocol_version(const SSL_SESSION *session); + +// SSL_SESSION_set_protocol_version sets |session|'s TLS or DTLS version to +// |version|. This may be useful when writing tests but should otherwise not be +// used. It returns one on success and zero on error. +OPENSSL_EXPORT int SSL_SESSION_set_protocol_version(SSL_SESSION *session, + uint16_t version); + +// SSL_SESSION_get_id returns a pointer to a buffer containing |session|'s +// session ID and sets |*out_len| to its length. +OPENSSL_EXPORT const uint8_t *SSL_SESSION_get_id(const SSL_SESSION *session, + unsigned *out_len); + +// SSL_SESSION_get_time returns the time at which |session| was established in +// seconds since the UNIX epoch. +OPENSSL_EXPORT uint64_t SSL_SESSION_get_time(const SSL_SESSION *session); + +// SSL_SESSION_get_timeout returns the lifetime of |session| in seconds. +OPENSSL_EXPORT uint32_t SSL_SESSION_get_timeout(const SSL_SESSION *session); + +// SSL_SESSION_get0_peer returns the peer leaf certificate stored in +// |session|. +// +// TODO(davidben): This should return a const X509 *. +OPENSSL_EXPORT X509 *SSL_SESSION_get0_peer(const SSL_SESSION *session); + +// SSL_SESSION_get_master_key writes up to |max_out| bytes of |session|'s master +// secret to |out| and returns the number of bytes written. If |max_out| is +// zero, it returns the size of the master secret. +OPENSSL_EXPORT size_t SSL_SESSION_get_master_key(const SSL_SESSION *session, + uint8_t *out, size_t max_out); + +// SSL_SESSION_set_time sets |session|'s creation time to |time| and returns +// |time|. This function may be useful in writing tests but otherwise should not +// be used. +OPENSSL_EXPORT uint64_t SSL_SESSION_set_time(SSL_SESSION *session, + uint64_t time); + +// SSL_SESSION_set_timeout sets |session|'s timeout to |timeout| and returns +// one. This function may be useful in writing tests but otherwise should not +// be used. +OPENSSL_EXPORT uint32_t SSL_SESSION_set_timeout(SSL_SESSION *session, + uint32_t timeout); + +// SSL_SESSION_set1_id_context sets |session|'s session ID context (see +// |SSL_CTX_set_session_id_context|) to |sid_ctx|. It returns one on success and +// zero on error. This function may be useful in writing tests but otherwise +// should not be used. +OPENSSL_EXPORT int SSL_SESSION_set1_id_context(SSL_SESSION *session, + const uint8_t *sid_ctx, + size_t sid_ctx_len); + +// SSL_SESSION_should_be_single_use returns one if |session| should be +// single-use (TLS 1.3 and later) and zero otherwise. +// +// If this function returns one, clients retain multiple sessions and use each +// only once. This prevents passive observers from correlating connections with +// tickets. See draft-ietf-tls-tls13-18, appendix B.5. If it returns zero, +// |session| cannot be used without leaking a correlator. +OPENSSL_EXPORT int SSL_SESSION_should_be_single_use(const SSL_SESSION *session); + +// SSL_SESSION_is_resumable returns one if |session| is resumable and zero +// otherwise. +OPENSSL_EXPORT int SSL_SESSION_is_resumable(const SSL_SESSION *session); + +// SSL_SESSION_has_ticket returns one if |session| has a ticket and zero +// otherwise. +OPENSSL_EXPORT int SSL_SESSION_has_ticket(const SSL_SESSION *session); + +// SSL_SESSION_get0_ticket sets |*out_ticket| and |*out_len| to |session|'s +// ticket, or NULL and zero if it does not have one. |out_ticket| may be NULL +// if only the ticket length is needed. +OPENSSL_EXPORT void SSL_SESSION_get0_ticket(const SSL_SESSION *session, + const uint8_t **out_ticket, + size_t *out_len); + +// SSL_SESSION_get_ticket_lifetime_hint returns ticket lifetime hint of +// |session| in seconds or zero if none was set. +OPENSSL_EXPORT uint32_t +SSL_SESSION_get_ticket_lifetime_hint(const SSL_SESSION *session); + + +// Session caching. +// +// Session caching allows connections to be established more efficiently based +// on saved parameters from a previous connection, called a session (see +// |SSL_SESSION|). The client offers a saved session, using an opaque identifier +// from a previous connection. The server may accept the session, if it has the +// parameters available. Otherwise, it will decline and continue with a full +// handshake. +// +// This requires both the client and the server to retain session state. A +// client does so with a stateful session cache. A server may do the same or, if +// supported by both sides, statelessly using session tickets. For more +// information on the latter, see the next section. +// +// For a server, the library implements a built-in internal session cache as an +// in-memory hash table. Servers may also use |SSL_CTX_sess_set_get_cb| and +// |SSL_CTX_sess_set_new_cb| to implement a custom external session cache. In +// particular, this may be used to share a session cache between multiple +// servers in a large deployment. An external cache may be used in addition to +// or instead of the internal one. Use |SSL_CTX_set_session_cache_mode| to +// toggle the internal cache. +// +// For a client, the only option is an external session cache. Clients may use +// |SSL_CTX_sess_set_new_cb| to register a callback for when new sessions are +// available. These may be cached and, in subsequent compatible connections, +// configured with |SSL_set_session|. +// +// Note that offering or accepting a session short-circuits certificate +// verification and most parameter negotiation. Resuming sessions across +// different contexts may result in security failures and surprising +// behavior. For a typical client, this means sessions for different hosts must +// be cached under different keys. A client that connects to the same host with, +// e.g., different cipher suite settings or client certificates should also use +// separate session caches between those contexts. Servers should also partition +// session caches between SNI hosts with |SSL_CTX_set_session_id_context|. +// +// Note also, in TLS 1.2 and earlier, offering sessions allows passive observers +// to correlate different client connections. TLS 1.3 and later fix this, +// provided clients use sessions at most once. Session caches are managed by the +// caller in BoringSSL, so this must be implemented externally. See +// |SSL_SESSION_should_be_single_use| for details. + +// SSL_SESS_CACHE_OFF disables all session caching. +#define SSL_SESS_CACHE_OFF 0x0000 + +// SSL_SESS_CACHE_CLIENT enables session caching for a client. The internal +// cache is never used on a client, so this only enables the callbacks. +#define SSL_SESS_CACHE_CLIENT 0x0001 + +// SSL_SESS_CACHE_SERVER enables session caching for a server. +#define SSL_SESS_CACHE_SERVER 0x0002 + +// SSL_SESS_CACHE_BOTH enables session caching for both client and server. +#define SSL_SESS_CACHE_BOTH (SSL_SESS_CACHE_CLIENT | SSL_SESS_CACHE_SERVER) + +// SSL_SESS_CACHE_NO_AUTO_CLEAR disables automatically calling +// |SSL_CTX_flush_sessions| every 255 connections. +#define SSL_SESS_CACHE_NO_AUTO_CLEAR 0x0080 + +// SSL_SESS_CACHE_NO_INTERNAL_LOOKUP, on a server, disables looking up a session +// from the internal session cache. +#define SSL_SESS_CACHE_NO_INTERNAL_LOOKUP 0x0100 + +// SSL_SESS_CACHE_NO_INTERNAL_STORE, on a server, disables storing sessions in +// the internal session cache. +#define SSL_SESS_CACHE_NO_INTERNAL_STORE 0x0200 + +// SSL_SESS_CACHE_NO_INTERNAL, on a server, disables the internal session +// cache. +#define SSL_SESS_CACHE_NO_INTERNAL \ + (SSL_SESS_CACHE_NO_INTERNAL_LOOKUP | SSL_SESS_CACHE_NO_INTERNAL_STORE) + +// SSL_CTX_set_session_cache_mode sets the session cache mode bits for |ctx| to +// |mode|. It returns the previous value. +OPENSSL_EXPORT int SSL_CTX_set_session_cache_mode(SSL_CTX *ctx, int mode); + +// SSL_CTX_get_session_cache_mode returns the session cache mode bits for +// |ctx| +OPENSSL_EXPORT int SSL_CTX_get_session_cache_mode(const SSL_CTX *ctx); + +// SSL_set_session, for a client, configures |ssl| to offer to resume |session| +// in the initial handshake and returns one. The caller retains ownership of +// |session|. +// +// It is an error to call this function after the handshake has begun. +OPENSSL_EXPORT int SSL_set_session(SSL *ssl, SSL_SESSION *session); + +// SSL_DEFAULT_SESSION_TIMEOUT is the default lifetime, in seconds, of a +// session in TLS 1.2 or earlier. This is how long we are willing to use the +// secret to encrypt traffic without fresh key material. +#define SSL_DEFAULT_SESSION_TIMEOUT (2 * 60 * 60) + +// SSL_DEFAULT_SESSION_PSK_DHE_TIMEOUT is the default lifetime, in seconds, of a +// session for TLS 1.3 psk_dhe_ke. This is how long we are willing to use the +// secret as an authenticator. +#define SSL_DEFAULT_SESSION_PSK_DHE_TIMEOUT (2 * 24 * 60 * 60) + +// SSL_DEFAULT_SESSION_AUTH_TIMEOUT is the default non-renewable lifetime, in +// seconds, of a TLS 1.3 session. This is how long we are willing to trust the +// signature in the initial handshake. +#define SSL_DEFAULT_SESSION_AUTH_TIMEOUT (7 * 24 * 60 * 60) + +// SSL_CTX_set_timeout sets the lifetime, in seconds, of TLS 1.2 (or earlier) +// sessions created in |ctx| to |timeout|. +OPENSSL_EXPORT uint32_t SSL_CTX_set_timeout(SSL_CTX *ctx, uint32_t timeout); + +// SSL_CTX_set_session_psk_dhe_timeout sets the lifetime, in seconds, of TLS 1.3 +// sessions created in |ctx| to |timeout|. +OPENSSL_EXPORT void SSL_CTX_set_session_psk_dhe_timeout(SSL_CTX *ctx, + uint32_t timeout); + +// SSL_CTX_get_timeout returns the lifetime, in seconds, of TLS 1.2 (or earlier) +// sessions created in |ctx|. +OPENSSL_EXPORT uint32_t SSL_CTX_get_timeout(const SSL_CTX *ctx); + +// SSL_CTX_set_session_id_context sets |ctx|'s session ID context to |sid_ctx|. +// It returns one on success and zero on error. The session ID context is an +// application-defined opaque byte string. A session will not be used in a +// connection without a matching session ID context. +// +// For a server, if |SSL_VERIFY_PEER| is enabled, it is an error to not set a +// session ID context. +OPENSSL_EXPORT int SSL_CTX_set_session_id_context(SSL_CTX *ctx, + const uint8_t *sid_ctx, + size_t sid_ctx_len); + +// SSL_set_session_id_context sets |ssl|'s session ID context to |sid_ctx|. It +// returns one on success and zero on error. See also +// |SSL_CTX_set_session_id_context|. +OPENSSL_EXPORT int SSL_set_session_id_context(SSL *ssl, const uint8_t *sid_ctx, + size_t sid_ctx_len); + +// SSL_get0_session_id_context returns a pointer to |ssl|'s session ID context +// and sets |*out_len| to its length. +OPENSSL_EXPORT const uint8_t *SSL_get0_session_id_context(const SSL *ssl, + size_t *out_len); + +// SSL_SESSION_CACHE_MAX_SIZE_DEFAULT is the default maximum size of a session +// cache. +#define SSL_SESSION_CACHE_MAX_SIZE_DEFAULT (1024 * 20) + +// SSL_CTX_sess_set_cache_size sets the maximum size of |ctx|'s internal session +// cache to |size|. It returns the previous value. +OPENSSL_EXPORT unsigned long SSL_CTX_sess_set_cache_size(SSL_CTX *ctx, + unsigned long size); + +// SSL_CTX_sess_get_cache_size returns the maximum size of |ctx|'s internal +// session cache. +OPENSSL_EXPORT unsigned long SSL_CTX_sess_get_cache_size(const SSL_CTX *ctx); + +// SSL_CTX_sess_number returns the number of sessions in |ctx|'s internal +// session cache. +OPENSSL_EXPORT size_t SSL_CTX_sess_number(const SSL_CTX *ctx); + +// SSL_CTX_add_session inserts |session| into |ctx|'s internal session cache. It +// returns one on success and zero on error or if |session| is already in the +// cache. The caller retains its reference to |session|. +OPENSSL_EXPORT int SSL_CTX_add_session(SSL_CTX *ctx, SSL_SESSION *session); + +// SSL_CTX_remove_session removes |session| from |ctx|'s internal session cache. +// It returns one on success and zero if |session| was not in the cache. +OPENSSL_EXPORT int SSL_CTX_remove_session(SSL_CTX *ctx, SSL_SESSION *session); + +// SSL_CTX_flush_sessions removes all sessions from |ctx| which have expired as +// of time |time|. If |time| is zero, all sessions are removed. +OPENSSL_EXPORT void SSL_CTX_flush_sessions(SSL_CTX *ctx, uint64_t time); + +// SSL_CTX_sess_set_new_cb sets the callback to be called when a new session is +// established and ready to be cached. If the session cache is disabled (the +// appropriate one of |SSL_SESS_CACHE_CLIENT| or |SSL_SESS_CACHE_SERVER| is +// unset), the callback is not called. +// +// The callback is passed a reference to |session|. It returns one if it takes +// ownership (and then calls |SSL_SESSION_free| when done) and zero otherwise. A +// consumer which places |session| into an in-memory cache will likely return +// one, with the cache calling |SSL_SESSION_free|. A consumer which serializes +// |session| with |SSL_SESSION_to_bytes| may not need to retain |session| and +// will likely return zero. Returning one is equivalent to calling +// |SSL_SESSION_up_ref| and then returning zero. +// +// Note: For a client, the callback may be called on abbreviated handshakes if a +// ticket is renewed. Further, it may not be called until some time after +// |SSL_do_handshake| or |SSL_connect| completes if False Start is enabled. Thus +// it's recommended to use this callback over calling |SSL_get_session| on +// handshake completion. +OPENSSL_EXPORT void SSL_CTX_sess_set_new_cb( + SSL_CTX *ctx, int (*new_session_cb)(SSL *ssl, SSL_SESSION *session)); + +// SSL_CTX_sess_get_new_cb returns the callback set by +// |SSL_CTX_sess_set_new_cb|. +OPENSSL_EXPORT int (*SSL_CTX_sess_get_new_cb(SSL_CTX *ctx))( + SSL *ssl, SSL_SESSION *session); + +// SSL_CTX_sess_set_remove_cb sets a callback which is called when a session is +// removed from the internal session cache. +// +// TODO(davidben): What is the point of this callback? It seems useless since it +// only fires on sessions in the internal cache. +OPENSSL_EXPORT void SSL_CTX_sess_set_remove_cb( + SSL_CTX *ctx, + void (*remove_session_cb)(SSL_CTX *ctx, SSL_SESSION *session)); + +// SSL_CTX_sess_get_remove_cb returns the callback set by +// |SSL_CTX_sess_set_remove_cb|. +OPENSSL_EXPORT void (*SSL_CTX_sess_get_remove_cb(SSL_CTX *ctx))( + SSL_CTX *ctx, SSL_SESSION *session); + +// SSL_CTX_sess_set_get_cb sets a callback to look up a session by ID for a +// server. The callback is passed the session ID and should return a matching +// |SSL_SESSION| or NULL if not found. It should set |*out_copy| to zero and +// return a new reference to the session. This callback is not used for a +// client. +// +// For historical reasons, if |*out_copy| is set to one (default), the SSL +// library will take a new reference to the returned |SSL_SESSION|, expecting +// the callback to return a non-owning pointer. This is not recommended. If +// |ctx| and thus the callback is used on multiple threads, the session may be +// removed and invalidated before the SSL library calls |SSL_SESSION_up_ref|, +// whereas the callback may synchronize internally. +// +// To look up a session asynchronously, the callback may return +// |SSL_magic_pending_session_ptr|. See the documentation for that function and +// |SSL_ERROR_PENDING_SESSION|. +// +// If the internal session cache is enabled, the callback is only consulted if +// the internal cache does not return a match. +OPENSSL_EXPORT void SSL_CTX_sess_set_get_cb( + SSL_CTX *ctx, SSL_SESSION *(*get_session_cb)(SSL *ssl, const uint8_t *id, + int id_len, int *out_copy)); + +// SSL_CTX_sess_get_get_cb returns the callback set by +// |SSL_CTX_sess_set_get_cb|. +OPENSSL_EXPORT SSL_SESSION *(*SSL_CTX_sess_get_get_cb(SSL_CTX *ctx))( + SSL *ssl, const uint8_t *id, int id_len, int *out_copy); + +// SSL_magic_pending_session_ptr returns a magic |SSL_SESSION|* which indicates +// that the session isn't currently unavailable. |SSL_get_error| will then +// return |SSL_ERROR_PENDING_SESSION| and the handshake can be retried later +// when the lookup has completed. +OPENSSL_EXPORT SSL_SESSION *SSL_magic_pending_session_ptr(void); + + +// Session tickets. +// +// Session tickets, from RFC 5077, allow session resumption without server-side +// state. The server maintains a secret ticket key and sends the client opaque +// encrypted session parameters, called a ticket. When offering the session, the +// client sends the ticket which the server decrypts to recover session state. +// Session tickets are enabled by default but may be disabled with +// |SSL_OP_NO_TICKET|. +// +// On the client, ticket-based sessions use the same APIs as ID-based tickets. +// Callers do not need to handle them differently. +// +// On the server, tickets are encrypted and authenticated with a secret key. By +// default, an |SSL_CTX| generates a key on creation and uses it for the +// lifetime of the |SSL_CTX|. Tickets are minted and processed +// transparently. The following functions may be used to configure a persistent +// key or implement more custom behavior, including key rotation and sharing +// keys between multiple servers in a large deployment. There are three levels +// of customisation possible: +// +// 1) One can simply set the keys with |SSL_CTX_set_tlsext_ticket_keys|. +// 2) One can configure an |EVP_CIPHER_CTX| and |HMAC_CTX| directly for +// encryption and authentication. +// 3) One can configure an |SSL_TICKET_AEAD_METHOD| to have more control +// and the option of asynchronous decryption. +// +// An attacker that compromises a server's session ticket key can impersonate +// the server and, prior to TLS 1.3, retroactively decrypt all application +// traffic from sessions using that ticket key. Thus ticket keys must be +// regularly rotated for forward secrecy. Note the default key is rotated +// automatically once every 48 hours but manually configured keys are not. + +// SSL_DEFAULT_TICKET_KEY_ROTATION_INTERVAL is the interval with which the +// default session ticket encryption key is rotated, if in use. If any +// non-default ticket encryption mechanism is configured, automatic rotation is +// disabled. +#define SSL_DEFAULT_TICKET_KEY_ROTATION_INTERVAL (2 * 24 * 60 * 60) + +// SSL_CTX_get_tlsext_ticket_keys writes |ctx|'s session ticket key material to +// |len| bytes of |out|. It returns one on success and zero if |len| is not +// 48. If |out| is NULL, it returns 48 instead. +OPENSSL_EXPORT int SSL_CTX_get_tlsext_ticket_keys(SSL_CTX *ctx, void *out, + size_t len); + +// SSL_CTX_set_tlsext_ticket_keys sets |ctx|'s session ticket key material to +// |len| bytes of |in|. It returns one on success and zero if |len| is not +// 48. If |in| is NULL, it returns 48 instead. +OPENSSL_EXPORT int SSL_CTX_set_tlsext_ticket_keys(SSL_CTX *ctx, const void *in, + size_t len); + +// SSL_TICKET_KEY_NAME_LEN is the length of the key name prefix of a session +// ticket. +#define SSL_TICKET_KEY_NAME_LEN 16 + +// SSL_CTX_set_tlsext_ticket_key_cb sets the ticket callback to |callback| and +// returns one. |callback| will be called when encrypting a new ticket and when +// decrypting a ticket from the client. +// +// In both modes, |ctx| and |hmac_ctx| will already have been initialized with +// |EVP_CIPHER_CTX_init| and |HMAC_CTX_init|, respectively. |callback| +// configures |hmac_ctx| with an HMAC digest and key, and configures |ctx| +// for encryption or decryption, based on the mode. +// +// When encrypting a new ticket, |encrypt| will be one. It writes a public +// 16-byte key name to |key_name| and a fresh IV to |iv|. The output IV length +// must match |EVP_CIPHER_CTX_iv_length| of the cipher selected. In this mode, +// |callback| returns 1 on success and -1 on error. +// +// When decrypting a ticket, |encrypt| will be zero. |key_name| will point to a +// 16-byte key name and |iv| points to an IV. The length of the IV consumed must +// match |EVP_CIPHER_CTX_iv_length| of the cipher selected. In this mode, +// |callback| returns -1 to abort the handshake, 0 if decrypting the ticket +// failed, and 1 or 2 on success. If it returns 2, the ticket will be renewed. +// This may be used to re-key the ticket. +// +// WARNING: |callback| wildly breaks the usual return value convention and is +// called in two different modes. +OPENSSL_EXPORT int SSL_CTX_set_tlsext_ticket_key_cb( + SSL_CTX *ctx, int (*callback)(SSL *ssl, uint8_t *key_name, uint8_t *iv, + EVP_CIPHER_CTX *ctx, HMAC_CTX *hmac_ctx, + int encrypt)); + +// ssl_ticket_aead_result_t enumerates the possible results from decrypting a +// ticket with an |SSL_TICKET_AEAD_METHOD|. +enum ssl_ticket_aead_result_t { + // ssl_ticket_aead_success indicates that the ticket was successfully + // decrypted. + ssl_ticket_aead_success, + // ssl_ticket_aead_retry indicates that the operation could not be + // immediately completed and must be reattempted, via |open|, at a later + // point. + ssl_ticket_aead_retry, + // ssl_ticket_aead_ignore_ticket indicates that the ticket should be ignored + // (i.e. is corrupt or otherwise undecryptable). + ssl_ticket_aead_ignore_ticket, + // ssl_ticket_aead_error indicates that a fatal error occured and the + // handshake should be terminated. + ssl_ticket_aead_error, +}; + +// ssl_ticket_aead_method_st (aka |SSL_TICKET_AEAD_METHOD|) contains methods +// for encrypting and decrypting session tickets. +struct ssl_ticket_aead_method_st { + // max_overhead returns the maximum number of bytes of overhead that |seal| + // may add. + size_t (*max_overhead)(SSL *ssl); + + // seal encrypts and authenticates |in_len| bytes from |in|, writes, at most, + // |max_out_len| bytes to |out|, and puts the number of bytes written in + // |*out_len|. The |in| and |out| buffers may be equal but will not otherwise + // alias. It returns one on success or zero on error. + int (*seal)(SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out_len, + const uint8_t *in, size_t in_len); + + // open authenticates and decrypts |in_len| bytes from |in|, writes, at most, + // |max_out_len| bytes of plaintext to |out|, and puts the number of bytes + // written in |*out_len|. The |in| and |out| buffers may be equal but will + // not otherwise alias. See |ssl_ticket_aead_result_t| for details of the + // return values. In the case that a retry is indicated, the caller should + // arrange for the high-level operation on |ssl| to be retried when the + // operation is completed, which will result in another call to |open|. + enum ssl_ticket_aead_result_t (*open)(SSL *ssl, uint8_t *out, size_t *out_len, + size_t max_out_len, const uint8_t *in, + size_t in_len); +}; + +// SSL_CTX_set_ticket_aead_method configures a custom ticket AEAD method table +// on |ctx|. |aead_method| must remain valid for the lifetime of |ctx|. +OPENSSL_EXPORT void SSL_CTX_set_ticket_aead_method( + SSL_CTX *ctx, const SSL_TICKET_AEAD_METHOD *aead_method); + + +// Elliptic curve Diffie-Hellman. +// +// Cipher suites using an ECDHE key exchange perform Diffie-Hellman over an +// elliptic curve negotiated by both endpoints. See RFC 4492. Only named curves +// are supported. ECDHE is always enabled, but the curve preferences may be +// configured with these functions. +// +// Note that TLS 1.3 renames these from curves to groups. For consistency, we +// currently use the TLS 1.2 name in the API. + +// SSL_CTX_set1_curves sets the preferred curves for |ctx| to be |curves|. Each +// element of |curves| should be a curve nid. It returns one on success and +// zero on failure. +// +// Note that this API uses nid values from nid.h and not the |SSL_CURVE_*| +// values defined below. +OPENSSL_EXPORT int SSL_CTX_set1_curves(SSL_CTX *ctx, const int *curves, + size_t curves_len); + +// SSL_set1_curves sets the preferred curves for |ssl| to be |curves|. Each +// element of |curves| should be a curve nid. It returns one on success and +// zero on failure. +// +// Note that this API uses nid values from nid.h and not the |SSL_CURVE_*| +// values defined below. +OPENSSL_EXPORT int SSL_set1_curves(SSL *ssl, const int *curves, + size_t curves_len); + +// SSL_CTX_set1_curves_list sets the preferred curves for |ctx| to be the +// colon-separated list |curves|. Each element of |curves| should be a curve +// name (e.g. P-256, X25519, ...). It returns one on success and zero on +// failure. +OPENSSL_EXPORT int SSL_CTX_set1_curves_list(SSL_CTX *ctx, const char *curves); + +// SSL_set1_curves_list sets the preferred curves for |ssl| to be the +// colon-separated list |curves|. Each element of |curves| should be a curve +// name (e.g. P-256, X25519, ...). It returns one on success and zero on +// failure. +OPENSSL_EXPORT int SSL_set1_curves_list(SSL *ssl, const char *curves); + +// SSL_CURVE_* define TLS curve IDs. +#define SSL_CURVE_SECP224R1 21 +#define SSL_CURVE_SECP256R1 23 +#define SSL_CURVE_SECP384R1 24 +#define SSL_CURVE_SECP521R1 25 +#define SSL_CURVE_X25519 29 + +// SSL_get_curve_id returns the ID of the curve used by |ssl|'s most recently +// completed handshake or 0 if not applicable. +// +// TODO(davidben): This API currently does not work correctly if there is a +// renegotiation in progress. Fix this. +OPENSSL_EXPORT uint16_t SSL_get_curve_id(const SSL *ssl); + +// SSL_get_curve_name returns a human-readable name for the curve specified by +// the given TLS curve id, or NULL if the curve is unknown. +OPENSSL_EXPORT const char *SSL_get_curve_name(uint16_t curve_id); + + +// Certificate verification. +// +// SSL may authenticate either endpoint with an X.509 certificate. Typically +// this is used to authenticate the server to the client. These functions +// configure certificate verification. +// +// WARNING: By default, certificate verification errors on a client are not +// fatal. See |SSL_VERIFY_NONE| This may be configured with +// |SSL_CTX_set_verify|. +// +// By default clients are anonymous but a server may request a certificate from +// the client by setting |SSL_VERIFY_PEER|. +// +// Many of these functions use OpenSSL's legacy X.509 stack which is +// underdocumented and deprecated, but the replacement isn't ready yet. For +// now, consumers may use the existing stack or bypass it by performing +// certificate verification externally. This may be done with +// |SSL_CTX_set_cert_verify_callback| or by extracting the chain with +// |SSL_get_peer_cert_chain| after the handshake. In the future, functions will +// be added to use the SSL stack without dependency on any part of the legacy +// X.509 and ASN.1 stack. +// +// To augment certificate verification, a client may also enable OCSP stapling +// (RFC 6066) and Certificate Transparency (RFC 6962) extensions. + +// SSL_VERIFY_NONE, on a client, verifies the server certificate but does not +// make errors fatal. The result may be checked with |SSL_get_verify_result|. On +// a server it does not request a client certificate. This is the default. +#define SSL_VERIFY_NONE 0x00 + +// SSL_VERIFY_PEER, on a client, makes server certificate errors fatal. On a +// server it requests a client certificate and makes errors fatal. However, +// anonymous clients are still allowed. See +// |SSL_VERIFY_FAIL_IF_NO_PEER_CERT|. +#define SSL_VERIFY_PEER 0x01 + +// SSL_VERIFY_FAIL_IF_NO_PEER_CERT configures a server to reject connections if +// the client declines to send a certificate. This flag must be used together +// with |SSL_VERIFY_PEER|, otherwise it won't work. +#define SSL_VERIFY_FAIL_IF_NO_PEER_CERT 0x02 + +// SSL_VERIFY_PEER_IF_NO_OBC configures a server to request a client certificate +// if and only if Channel ID is not negotiated. +#define SSL_VERIFY_PEER_IF_NO_OBC 0x04 + +// SSL_CTX_set_verify configures certificate verification behavior. |mode| is +// one of the |SSL_VERIFY_*| values defined above. |callback|, if not NULL, is +// used to customize certificate verification. See the behavior of +// |X509_STORE_CTX_set_verify_cb|. +// +// The callback may use |SSL_get_ex_data_X509_STORE_CTX_idx| with +// |X509_STORE_CTX_get_ex_data| to look up the |SSL| from |store_ctx|. +OPENSSL_EXPORT void SSL_CTX_set_verify( + SSL_CTX *ctx, int mode, int (*callback)(int ok, X509_STORE_CTX *store_ctx)); + +// SSL_set_verify configures certificate verification behavior. |mode| is one of +// the |SSL_VERIFY_*| values defined above. |callback|, if not NULL, is used to +// customize certificate verification. See the behavior of +// |X509_STORE_CTX_set_verify_cb|. +// +// The callback may use |SSL_get_ex_data_X509_STORE_CTX_idx| with +// |X509_STORE_CTX_get_ex_data| to look up the |SSL| from |store_ctx|. +OPENSSL_EXPORT void SSL_set_verify(SSL *ssl, int mode, + int (*callback)(int ok, + X509_STORE_CTX *store_ctx)); + +enum ssl_verify_result_t { + ssl_verify_ok, + ssl_verify_invalid, + ssl_verify_retry, +}; + +// SSL_CTX_set_custom_verify configures certificate verification. |mode| is one +// of the |SSL_VERIFY_*| values defined above. |callback| performs the +// certificate verification. +// +// The callback may call |SSL_get0_peer_certificates| for the certificate chain +// to validate. The callback should return |ssl_verify_ok| if the certificate is +// valid. If the certificate is invalid, the callback should return +// |ssl_verify_invalid| and optionally set |*out_alert| to an alert to send to +// the peer. Some useful alerts include |SSL_AD_CERTIFICATE_EXPIRED|, +// |SSL_AD_CERTIFICATE_REVOKED|, |SSL_AD_UNKNOWN_CA|, |SSL_AD_BAD_CERTIFICATE|, +// |SSL_AD_CERTIFICATE_UNKNOWN|, and |SSL_AD_INTERNAL_ERROR|. See RFC 5246 +// section 7.2.2 for their precise meanings. If unspecified, +// |SSL_AD_CERTIFICATE_UNKNOWN| will be sent by default. +// +// To verify a certificate asynchronously, the callback may return +// |ssl_verify_retry|. The handshake will then pause with |SSL_get_error| +// returning |SSL_ERROR_WANT_CERTIFICATE_VERIFY|. +OPENSSL_EXPORT void SSL_CTX_set_custom_verify( + SSL_CTX *ctx, int mode, + enum ssl_verify_result_t (*callback)(SSL *ssl, uint8_t *out_alert)); + +// SSL_set_custom_verify behaves like |SSL_CTX_set_custom_verify| but configures +// an individual |SSL|. +OPENSSL_EXPORT void SSL_set_custom_verify( + SSL *ssl, int mode, + enum ssl_verify_result_t (*callback)(SSL *ssl, uint8_t *out_alert)); + +// SSL_CTX_get_verify_mode returns |ctx|'s verify mode, set by +// |SSL_CTX_set_verify|. +OPENSSL_EXPORT int SSL_CTX_get_verify_mode(const SSL_CTX *ctx); + +// SSL_get_verify_mode returns |ssl|'s verify mode, set by |SSL_CTX_set_verify| +// or |SSL_set_verify|. +OPENSSL_EXPORT int SSL_get_verify_mode(const SSL *ssl); + +// SSL_CTX_get_verify_callback returns the callback set by +// |SSL_CTX_set_verify|. +OPENSSL_EXPORT int (*SSL_CTX_get_verify_callback(const SSL_CTX *ctx))( + int ok, X509_STORE_CTX *store_ctx); + +// SSL_get_verify_callback returns the callback set by |SSL_CTX_set_verify| or +// |SSL_set_verify|. +OPENSSL_EXPORT int (*SSL_get_verify_callback(const SSL *ssl))( + int ok, X509_STORE_CTX *store_ctx); + +// SSL_CTX_set_verify_depth sets the maximum depth of a certificate chain +// accepted in verification. This number does not include the leaf, so a depth +// of 1 allows the leaf and one CA certificate. +OPENSSL_EXPORT void SSL_CTX_set_verify_depth(SSL_CTX *ctx, int depth); + +// SSL_set_verify_depth sets the maximum depth of a certificate chain accepted +// in verification. This number does not include the leaf, so a depth of 1 +// allows the leaf and one CA certificate. +OPENSSL_EXPORT void SSL_set_verify_depth(SSL *ssl, int depth); + +// SSL_CTX_get_verify_depth returns the maximum depth of a certificate accepted +// in verification. +OPENSSL_EXPORT int SSL_CTX_get_verify_depth(const SSL_CTX *ctx); + +// SSL_get_verify_depth returns the maximum depth of a certificate accepted in +// verification. +OPENSSL_EXPORT int SSL_get_verify_depth(const SSL *ssl); + +// SSL_CTX_set1_param sets verification parameters from |param|. It returns one +// on success and zero on failure. The caller retains ownership of |param|. +OPENSSL_EXPORT int SSL_CTX_set1_param(SSL_CTX *ctx, + const X509_VERIFY_PARAM *param); + +// SSL_set1_param sets verification parameters from |param|. It returns one on +// success and zero on failure. The caller retains ownership of |param|. +OPENSSL_EXPORT int SSL_set1_param(SSL *ssl, + const X509_VERIFY_PARAM *param); + +// SSL_CTX_get0_param returns |ctx|'s |X509_VERIFY_PARAM| for certificate +// verification. The caller must not release the returned pointer but may call +// functions on it to configure it. +OPENSSL_EXPORT X509_VERIFY_PARAM *SSL_CTX_get0_param(SSL_CTX *ctx); + +// SSL_get0_param returns |ssl|'s |X509_VERIFY_PARAM| for certificate +// verification. The caller must not release the returned pointer but may call +// functions on it to configure it. +OPENSSL_EXPORT X509_VERIFY_PARAM *SSL_get0_param(SSL *ssl); + +// SSL_CTX_set_purpose sets |ctx|'s |X509_VERIFY_PARAM|'s 'purpose' parameter to +// |purpose|. It returns one on success and zero on error. +OPENSSL_EXPORT int SSL_CTX_set_purpose(SSL_CTX *ctx, int purpose); + +// SSL_set_purpose sets |ssl|'s |X509_VERIFY_PARAM|'s 'purpose' parameter to +// |purpose|. It returns one on success and zero on error. +OPENSSL_EXPORT int SSL_set_purpose(SSL *ssl, int purpose); + +// SSL_CTX_set_trust sets |ctx|'s |X509_VERIFY_PARAM|'s 'trust' parameter to +// |trust|. It returns one on success and zero on error. +OPENSSL_EXPORT int SSL_CTX_set_trust(SSL_CTX *ctx, int trust); + +// SSL_set_trust sets |ssl|'s |X509_VERIFY_PARAM|'s 'trust' parameter to +// |trust|. It returns one on success and zero on error. +OPENSSL_EXPORT int SSL_set_trust(SSL *ssl, int trust); + +// SSL_CTX_set_cert_store sets |ctx|'s certificate store to |store|. It takes +// ownership of |store|. The store is used for certificate verification. +// +// The store is also used for the auto-chaining feature, but this is deprecated. +// See also |SSL_MODE_NO_AUTO_CHAIN|. +OPENSSL_EXPORT void SSL_CTX_set_cert_store(SSL_CTX *ctx, X509_STORE *store); + +// SSL_CTX_get_cert_store returns |ctx|'s certificate store. +OPENSSL_EXPORT X509_STORE *SSL_CTX_get_cert_store(const SSL_CTX *ctx); + +// SSL_CTX_set_default_verify_paths loads the OpenSSL system-default trust +// anchors into |ctx|'s store. It returns one on success and zero on failure. +OPENSSL_EXPORT int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx); + +// SSL_CTX_load_verify_locations loads trust anchors into |ctx|'s store from +// |ca_file| and |ca_dir|, either of which may be NULL. If |ca_file| is passed, +// it is opened and PEM-encoded CA certificates are read. If |ca_dir| is passed, +// it is treated as a directory in OpenSSL's hashed directory format. It returns +// one on success and zero on failure. +// +// See +// https://www.openssl.org/docs/manmaster/ssl/SSL_CTX_load_verify_locations.html +// for documentation on the directory format. +OPENSSL_EXPORT int SSL_CTX_load_verify_locations(SSL_CTX *ctx, + const char *ca_file, + const char *ca_dir); + +// SSL_get_verify_result returns the result of certificate verification. It is +// either |X509_V_OK| or a |X509_V_ERR_*| value. +OPENSSL_EXPORT long SSL_get_verify_result(const SSL *ssl); + +// SSL_alert_from_verify_result returns the SSL alert code, such as +// |SSL_AD_CERTIFICATE_EXPIRED|, that corresponds to an |X509_V_ERR_*| value. +// The return value is always an alert, even when |result| is |X509_V_OK|. +OPENSSL_EXPORT int SSL_alert_from_verify_result(long result); + +// SSL_get_ex_data_X509_STORE_CTX_idx returns the ex_data index used to look up +// the |SSL| associated with an |X509_STORE_CTX| in the verify callback. +OPENSSL_EXPORT int SSL_get_ex_data_X509_STORE_CTX_idx(void); + +// SSL_CTX_set_cert_verify_callback sets a custom callback to be called on +// certificate verification rather than |X509_verify_cert|. |store_ctx| contains +// the verification parameters. The callback should return one on success and +// zero on fatal error. It may use |X509_STORE_CTX_set_error| to set a +// verification result. +// +// The callback may use |SSL_get_ex_data_X509_STORE_CTX_idx| to recover the +// |SSL| object from |store_ctx|. +OPENSSL_EXPORT void SSL_CTX_set_cert_verify_callback( + SSL_CTX *ctx, int (*callback)(X509_STORE_CTX *store_ctx, void *arg), + void *arg); + +// SSL_enable_signed_cert_timestamps causes |ssl| (which must be the client end +// of a connection) to request SCTs from the server. See +// https://tools.ietf.org/html/rfc6962. +// +// Call |SSL_get0_signed_cert_timestamp_list| to recover the SCT after the +// handshake. +OPENSSL_EXPORT void SSL_enable_signed_cert_timestamps(SSL *ssl); + +// SSL_CTX_enable_signed_cert_timestamps enables SCT requests on all client SSL +// objects created from |ctx|. +// +// Call |SSL_get0_signed_cert_timestamp_list| to recover the SCT after the +// handshake. +OPENSSL_EXPORT void SSL_CTX_enable_signed_cert_timestamps(SSL_CTX *ctx); + +// SSL_enable_ocsp_stapling causes |ssl| (which must be the client end of a +// connection) to request a stapled OCSP response from the server. +// +// Call |SSL_get0_ocsp_response| to recover the OCSP response after the +// handshake. +OPENSSL_EXPORT void SSL_enable_ocsp_stapling(SSL *ssl); + +// SSL_CTX_enable_ocsp_stapling enables OCSP stapling on all client SSL objects +// created from |ctx|. +// +// Call |SSL_get0_ocsp_response| to recover the OCSP response after the +// handshake. +OPENSSL_EXPORT void SSL_CTX_enable_ocsp_stapling(SSL_CTX *ctx); + +// SSL_CTX_set0_verify_cert_store sets an |X509_STORE| that will be used +// exclusively for certificate verification and returns one. Ownership of +// |store| is transferred to the |SSL_CTX|. +OPENSSL_EXPORT int SSL_CTX_set0_verify_cert_store(SSL_CTX *ctx, + X509_STORE *store); + +// SSL_CTX_set1_verify_cert_store sets an |X509_STORE| that will be used +// exclusively for certificate verification and returns one. An additional +// reference to |store| will be taken. +OPENSSL_EXPORT int SSL_CTX_set1_verify_cert_store(SSL_CTX *ctx, + X509_STORE *store); + +// SSL_set0_verify_cert_store sets an |X509_STORE| that will be used +// exclusively for certificate verification and returns one. Ownership of +// |store| is transferred to the |SSL|. +OPENSSL_EXPORT int SSL_set0_verify_cert_store(SSL *ssl, X509_STORE *store); + +// SSL_set1_verify_cert_store sets an |X509_STORE| that will be used +// exclusively for certificate verification and returns one. An additional +// reference to |store| will be taken. +OPENSSL_EXPORT int SSL_set1_verify_cert_store(SSL *ssl, X509_STORE *store); + +// SSL_CTX_set_ed25519_enabled configures whether |ctx| advertises support for +// the Ed25519 signature algorithm when using the default preference list. +OPENSSL_EXPORT void SSL_CTX_set_ed25519_enabled(SSL_CTX *ctx, int enabled); + +// SSL_CTX_set_verify_algorithm_prefs confingures |ctx| to use |prefs| as the +// preference list when verifying signature's from the peer's long-term key. It +// returns one on zero on error. |prefs| should not include the internal-only +// value |SSL_SIGN_RSA_PKCS1_MD5_SHA1|. +OPENSSL_EXPORT int SSL_CTX_set_verify_algorithm_prefs(SSL_CTX *ctx, + const uint16_t *prefs, + size_t num_prefs); + + +// Client certificate CA list. +// +// When requesting a client certificate, a server may advertise a list of +// certificate authorities which are accepted. These functions may be used to +// configure this list. + +// SSL_set_client_CA_list sets |ssl|'s client certificate CA list to +// |name_list|. It takes ownership of |name_list|. +OPENSSL_EXPORT void SSL_set_client_CA_list(SSL *ssl, + STACK_OF(X509_NAME) *name_list); + +// SSL_CTX_set_client_CA_list sets |ctx|'s client certificate CA list to +// |name_list|. It takes ownership of |name_list|. +OPENSSL_EXPORT void SSL_CTX_set_client_CA_list(SSL_CTX *ctx, + STACK_OF(X509_NAME) *name_list); + +// SSL_set0_client_CAs sets |ssl|'s client certificate CA list to |name_list|, +// which should contain DER-encoded distinguished names (RFC 5280). It takes +// ownership of |name_list|. +OPENSSL_EXPORT void SSL_set0_client_CAs(SSL *ssl, + STACK_OF(CRYPTO_BUFFER) *name_list); + +// SSL_CTX_set0_client_CAs sets |ctx|'s client certificate CA list to +// |name_list|, which should contain DER-encoded distinguished names (RFC 5280). +// It takes ownership of |name_list|. +OPENSSL_EXPORT void SSL_CTX_set0_client_CAs(SSL_CTX *ctx, + STACK_OF(CRYPTO_BUFFER) *name_list); + +// SSL_get_client_CA_list returns |ssl|'s client certificate CA list. If |ssl| +// has not been configured as a client, this is the list configured by +// |SSL_CTX_set_client_CA_list|. +// +// If configured as a client, it returns the client certificate CA list sent by +// the server. In this mode, the behavior is undefined except during the +// callbacks set by |SSL_CTX_set_cert_cb| and |SSL_CTX_set_client_cert_cb| or +// when the handshake is paused because of them. +OPENSSL_EXPORT STACK_OF(X509_NAME) *SSL_get_client_CA_list(const SSL *ssl); + +// SSL_get0_server_requested_CAs returns the CAs sent by a server to guide a +// client in certificate selection. They are a series of DER-encoded X.509 +// names. This function may only be called during a callback set by +// |SSL_CTX_set_cert_cb| or when the handshake is paused because of it. +// +// The returned stack is owned by |ssl|, as are its contents. It should not be +// used past the point where the handshake is restarted after the callback. +OPENSSL_EXPORT STACK_OF(CRYPTO_BUFFER) *SSL_get0_server_requested_CAs( + const SSL *ssl); + +// SSL_CTX_get_client_CA_list returns |ctx|'s client certificate CA list. +OPENSSL_EXPORT STACK_OF(X509_NAME) * + SSL_CTX_get_client_CA_list(const SSL_CTX *ctx); + +// SSL_add_client_CA appends |x509|'s subject to the client certificate CA list. +// It returns one on success or zero on error. The caller retains ownership of +// |x509|. +OPENSSL_EXPORT int SSL_add_client_CA(SSL *ssl, X509 *x509); + +// SSL_CTX_add_client_CA appends |x509|'s subject to the client certificate CA +// list. It returns one on success or zero on error. The caller retains +// ownership of |x509|. +OPENSSL_EXPORT int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x509); + +// SSL_load_client_CA_file opens |file| and reads PEM-encoded certificates from +// it. It returns a newly-allocated stack of the certificate subjects or NULL +// on error. +OPENSSL_EXPORT STACK_OF(X509_NAME) *SSL_load_client_CA_file(const char *file); + +// SSL_dup_CA_list makes a deep copy of |list|. It returns the new list on +// success or NULL on allocation error. +OPENSSL_EXPORT STACK_OF(X509_NAME) *SSL_dup_CA_list(STACK_OF(X509_NAME) *list); + +// SSL_add_file_cert_subjects_to_stack behaves like |SSL_load_client_CA_file| +// but appends the result to |out|. It returns one on success or zero on +// error. +OPENSSL_EXPORT int SSL_add_file_cert_subjects_to_stack(STACK_OF(X509_NAME) *out, + const char *file); + + +// Server name indication. +// +// The server_name extension (RFC 3546) allows the client to advertise the name +// of the server it is connecting to. This is used in virtual hosting +// deployments to select one of a several certificates on a single IP. Only the +// host_name name type is supported. + +#define TLSEXT_NAMETYPE_host_name 0 + +// SSL_set_tlsext_host_name, for a client, configures |ssl| to advertise |name| +// in the server_name extension. It returns one on success and zero on error. +OPENSSL_EXPORT int SSL_set_tlsext_host_name(SSL *ssl, const char *name); + +// SSL_get_servername, for a server, returns the hostname supplied by the +// client or NULL if there was none. The |type| argument must be +// |TLSEXT_NAMETYPE_host_name|. +OPENSSL_EXPORT const char *SSL_get_servername(const SSL *ssl, const int type); + +// SSL_get_servername_type, for a server, returns |TLSEXT_NAMETYPE_host_name| +// if the client sent a hostname and -1 otherwise. +OPENSSL_EXPORT int SSL_get_servername_type(const SSL *ssl); + +// SSL_CTX_set_tlsext_servername_callback configures |callback| to be called on +// the server after ClientHello extensions have been parsed and returns one. +// The callback may use |SSL_get_servername| to examine the server_name +// extension and returns a |SSL_TLSEXT_ERR_*| value. The value of |arg| may be +// set by calling |SSL_CTX_set_tlsext_servername_arg|. +// +// If the callback returns |SSL_TLSEXT_ERR_NOACK|, the server_name extension is +// not acknowledged in the ServerHello. If the return value is +// |SSL_TLSEXT_ERR_ALERT_FATAL|, then |*out_alert| is the alert to send, +// defaulting to |SSL_AD_UNRECOGNIZED_NAME|. |SSL_TLSEXT_ERR_ALERT_WARNING| is +// ignored and treated as |SSL_TLSEXT_ERR_OK|. +OPENSSL_EXPORT int SSL_CTX_set_tlsext_servername_callback( + SSL_CTX *ctx, int (*callback)(SSL *ssl, int *out_alert, void *arg)); + +// SSL_CTX_set_tlsext_servername_arg sets the argument to the servername +// callback and returns one. See |SSL_CTX_set_tlsext_servername_callback|. +OPENSSL_EXPORT int SSL_CTX_set_tlsext_servername_arg(SSL_CTX *ctx, void *arg); + +// SSL_TLSEXT_ERR_* are values returned by some extension-related callbacks. +#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 + +// SSL_set_SSL_CTX changes |ssl|'s |SSL_CTX|. |ssl| will use the +// certificate-related settings from |ctx|, and |SSL_get_SSL_CTX| will report +// |ctx|. This function may be used during the callbacks registered by +// |SSL_CTX_set_select_certificate_cb|, +// |SSL_CTX_set_tlsext_servername_callback|, and |SSL_CTX_set_cert_cb| or when +// the handshake is paused from them. It is typically used to switch +// certificates based on SNI. +// +// Note the session cache and related settings will continue to use the initial +// |SSL_CTX|. Callers should use |SSL_CTX_set_session_id_context| to partition +// the session cache between different domains. +// +// TODO(davidben): Should other settings change after this call? +OPENSSL_EXPORT SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX *ctx); + + +// Application-layer protocol negotiation. +// +// The ALPN extension (RFC 7301) allows negotiating different application-layer +// protocols over a single port. This is used, for example, to negotiate +// HTTP/2. + +// SSL_CTX_set_alpn_protos sets the client 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). It returns zero on success and one on failure. +// Configuring this list enables ALPN on a client. +// +// WARNING: this function is dangerous because it breaks the usual return value +// convention. +OPENSSL_EXPORT int SSL_CTX_set_alpn_protos(SSL_CTX *ctx, const uint8_t *protos, + unsigned protos_len); + +// SSL_set_alpn_protos sets the client 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). It returns zero on success and one on failure. +// Configuring this list enables ALPN on a client. +// +// WARNING: this function is dangerous because it breaks the usual return value +// convention. +OPENSSL_EXPORT int SSL_set_alpn_protos(SSL *ssl, const uint8_t *protos, + unsigned protos_len); + +// 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. Configuring this callback enables ALPN on +// a server. +// +// The callback is passed a wire-format (i.e. a series of non-empty, 8-bit +// length-prefixed strings) ALPN protocol list in |in|. It should set |*out| and +// |*out_len| to the selected protocol and return |SSL_TLSEXT_ERR_OK| on +// success. It does not pass ownership of the buffer. Otherwise, it should +// return |SSL_TLSEXT_ERR_NOACK|. Other |SSL_TLSEXT_ERR_*| values are +// unimplemented and will be treated as |SSL_TLSEXT_ERR_NOACK|. +// +// The cipher suite is selected before negotiating ALPN. The callback may use +// |SSL_get_pending_cipher| to query the cipher suite. +OPENSSL_EXPORT void SSL_CTX_set_alpn_select_cb( + SSL_CTX *ctx, int (*cb)(SSL *ssl, const uint8_t **out, uint8_t *out_len, + const uint8_t *in, unsigned in_len, void *arg), + void *arg); + +// SSL_get0_alpn_selected gets the selected ALPN protocol (if any) from |ssl|. +// On return it sets |*out_data| to point to |*out_len| bytes of protocol name +// (not including the leading length-prefix byte). If the server didn't respond +// with a negotiated protocol then |*out_len| will be zero. +OPENSSL_EXPORT void SSL_get0_alpn_selected(const SSL *ssl, + const uint8_t **out_data, + unsigned *out_len); + +// SSL_CTX_set_allow_unknown_alpn_protos configures client connections on |ctx| +// to allow unknown ALPN protocols from the server. Otherwise, by default, the +// client will require that the protocol be advertised in +// |SSL_CTX_set_alpn_protos|. +OPENSSL_EXPORT void SSL_CTX_set_allow_unknown_alpn_protos(SSL_CTX *ctx, + int enabled); + + +// Next protocol negotiation. +// +// The NPN extension (draft-agl-tls-nextprotoneg-03) is the predecessor to ALPN +// and deprecated in favor of it. + +// 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 |*out_len| to its length. This memory +// will not be modified, but one should assume that |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. +OPENSSL_EXPORT void SSL_CTX_set_next_protos_advertised_cb( + SSL_CTX *ctx, + int (*cb)(SSL *ssl, const uint8_t **out, unsigned *out_len, void *arg), + void *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 |*out_len|. The server's advertised +// protocols are provided in |in| and |in_len|. 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|. +// +// Configuring this callback enables NPN on a client. +OPENSSL_EXPORT void SSL_CTX_set_next_proto_select_cb( + SSL_CTX *ctx, int (*cb)(SSL *ssl, uint8_t **out, uint8_t *out_len, + const uint8_t *in, unsigned in_len, void *arg), + void *arg); + +// SSL_get0_next_proto_negotiated sets |*out_data| and |*out_len| to point to +// the client's requested protocol for this connection. If the client didn't +// request any protocol, then |*out_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 server. +OPENSSL_EXPORT void SSL_get0_next_proto_negotiated(const SSL *ssl, + const uint8_t **out_data, + unsigned *out_len); + +// 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|. +// +// |peer| and |supported| must be vectors of 8-bit, length-prefixed byte strings +// containing the peer and locally-configured protocols, respectively. The +// length byte itself is not included in the length. A byte string of length 0 +// is invalid. No byte string may be truncated. |supported| is assumed to be +// non-empty. +// +// This function finds the first protocol in |peer| which is also in +// |supported|. If one was found, it sets |*out| and |*out_len| to point to it +// and returns |OPENSSL_NPN_NEGOTIATED|. Otherwise, it returns +// |OPENSSL_NPN_NO_OVERLAP| and sets |*out| and |*out_len| to the first +// supported protocol. +OPENSSL_EXPORT int SSL_select_next_proto(uint8_t **out, uint8_t *out_len, + const uint8_t *peer, unsigned peer_len, + const uint8_t *supported, + unsigned supported_len); + +#define OPENSSL_NPN_UNSUPPORTED 0 +#define OPENSSL_NPN_NEGOTIATED 1 +#define OPENSSL_NPN_NO_OVERLAP 2 + + +// Channel ID. +// +// See draft-balfanz-tls-channelid-01. + +// SSL_CTX_set_tls_channel_id_enabled configures whether connections associated +// with |ctx| should enable Channel ID. +OPENSSL_EXPORT void SSL_CTX_set_tls_channel_id_enabled(SSL_CTX *ctx, + int enabled); + +// SSL_set_tls_channel_id_enabled configures whether |ssl| should enable Channel +// ID. +OPENSSL_EXPORT void SSL_set_tls_channel_id_enabled(SSL *ssl, int enabled); + +// SSL_CTX_set1_tls_channel_id configures a TLS client to send a TLS Channel ID +// to compatible servers. |private_key| must be a P-256 EC key. It returns one +// on success and zero on error. +OPENSSL_EXPORT int SSL_CTX_set1_tls_channel_id(SSL_CTX *ctx, + EVP_PKEY *private_key); + +// SSL_set1_tls_channel_id configures a TLS client to send a TLS Channel ID to +// compatible servers. |private_key| must be a P-256 EC key. It returns one on +// success and zero on error. +OPENSSL_EXPORT int SSL_set1_tls_channel_id(SSL *ssl, EVP_PKEY *private_key); + +// SSL_get_tls_channel_id gets the client's TLS Channel ID from a server |SSL*| +// and copies up to the first |max_out| bytes into |out|. The Channel ID +// consists of the client's P-256 public key as an (x,y) pair where each is a +// 32-byte, big-endian field element. It returns 0 if the client didn't offer a +// Channel ID and the length of the complete Channel ID otherwise. +OPENSSL_EXPORT size_t SSL_get_tls_channel_id(SSL *ssl, uint8_t *out, + size_t max_out); + +// SSL_CTX_set_channel_id_cb sets a callback to be called when a TLS Channel ID +// is requested. The callback may set |*out_pkey| to a key, passing a reference +// to the caller. If none is returned, the handshake will pause and +// |SSL_get_error| will return |SSL_ERROR_WANT_CHANNEL_ID_LOOKUP|. +// +// See also |SSL_ERROR_WANT_CHANNEL_ID_LOOKUP|. +OPENSSL_EXPORT void SSL_CTX_set_channel_id_cb( + SSL_CTX *ctx, void (*channel_id_cb)(SSL *ssl, EVP_PKEY **out_pkey)); + +// SSL_CTX_get_channel_id_cb returns the callback set by +// |SSL_CTX_set_channel_id_cb|. +OPENSSL_EXPORT void (*SSL_CTX_get_channel_id_cb(SSL_CTX *ctx))( + SSL *ssl, EVP_PKEY **out_pkey); + + +// Token Binding. +// +// See draft-ietf-tokbind-protocol-16. + +// SSL_set_token_binding_params sets |params| as the Token Binding Key +// parameters (section 3 of draft-ietf-tokbind-protocol-16) to negotiate on the +// connection. If this function is not called, or if |len| is 0, then this +// endpoint will not attempt to negotiate Token Binding. |params| are provided +// in preference order, with the more preferred parameters at the beginning of +// the list. This function returns 1 on success and 0 on failure. +OPENSSL_EXPORT int SSL_set_token_binding_params(SSL *ssl, const uint8_t *params, + size_t len); + +// SSL_is_token_binding_negotiated returns 1 if Token Binding was negotiated +// on this connection and 0 otherwise. On a server, it is possible for this +// function to return 1 when the client's view of the connection is that Token +// Binding was not negotiated. This occurs when the server indicates a version +// of Token Binding less than the client's minimum version. +OPENSSL_EXPORT int SSL_is_token_binding_negotiated(const SSL *ssl); + +// SSL_get_negotiated_token_binding_param returns the TokenBindingKeyParameters +// enum value that was negotiated. It is only valid to call this function if +// SSL_is_token_binding_negotiated returned 1, otherwise this function returns +// an undefined value. +OPENSSL_EXPORT uint8_t SSL_get_negotiated_token_binding_param(const SSL *ssl); + + +// DTLS-SRTP. +// +// See RFC 5764. + +// srtp_protection_profile_st (aka |SRTP_PROTECTION_PROFILE|) is an SRTP +// profile for use with the use_srtp extension. +struct srtp_protection_profile_st { + const char *name; + unsigned long id; +} /* SRTP_PROTECTION_PROFILE */; + +DEFINE_CONST_STACK_OF(SRTP_PROTECTION_PROFILE) + +// SRTP_* define constants for SRTP profiles. +#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 +#define SRTP_AEAD_AES_128_GCM 0x0007 +#define SRTP_AEAD_AES_256_GCM 0x0008 + +// SSL_CTX_set_srtp_profiles enables SRTP for all SSL objects created from +// |ctx|. |profile| contains a colon-separated list of profile names. It returns +// one on success and zero on failure. +OPENSSL_EXPORT int SSL_CTX_set_srtp_profiles(SSL_CTX *ctx, + const char *profiles); + +// SSL_set_srtp_profiles enables SRTP for |ssl|. |profile| contains a +// colon-separated list of profile names. It returns one on success and zero on +// failure. +OPENSSL_EXPORT int SSL_set_srtp_profiles(SSL *ssl, const char *profiles); + +// SSL_get_srtp_profiles returns the SRTP profiles supported by |ssl|. +OPENSSL_EXPORT STACK_OF(SRTP_PROTECTION_PROFILE) *SSL_get_srtp_profiles( + SSL *ssl); + +// SSL_get_selected_srtp_profile returns the selected SRTP profile, or NULL if +// SRTP was not negotiated. +OPENSSL_EXPORT const SRTP_PROTECTION_PROFILE *SSL_get_selected_srtp_profile( + SSL *ssl); + + +// Pre-shared keys. +// +// Connections may be configured with PSK (Pre-Shared Key) cipher suites. These +// authenticate using out-of-band pre-shared keys rather than certificates. See +// RFC 4279. +// +// This implementation uses NUL-terminated C strings for identities and identity +// hints, so values with a NUL character are not supported. (RFC 4279 does not +// specify the format of an identity.) + +// PSK_MAX_IDENTITY_LEN is the maximum supported length of a PSK identity, +// excluding the NUL terminator. +#define PSK_MAX_IDENTITY_LEN 128 + +// PSK_MAX_PSK_LEN is the maximum supported length of a pre-shared key. +#define PSK_MAX_PSK_LEN 256 + +// SSL_CTX_set_psk_client_callback sets the callback to be called when PSK is +// negotiated on the client. This callback must be set to enable PSK cipher +// suites on the client. +// +// The callback is passed the identity hint in |hint| or NULL if none was +// provided. It should select a PSK identity and write the identity and the +// corresponding PSK to |identity| and |psk|, respectively. The identity is +// written as a NUL-terminated C string of length (excluding the NUL terminator) +// at most |max_identity_len|. The PSK's length must be at most |max_psk_len|. +// The callback returns the length of the PSK or 0 if no suitable identity was +// found. +OPENSSL_EXPORT void SSL_CTX_set_psk_client_callback( + SSL_CTX *ctx, unsigned (*cb)(SSL *ssl, const char *hint, char *identity, + unsigned max_identity_len, uint8_t *psk, + unsigned max_psk_len)); + +// SSL_set_psk_client_callback sets the callback to be called when PSK is +// negotiated on the client. This callback must be set to enable PSK cipher +// suites on the client. See also |SSL_CTX_set_psk_client_callback|. +OPENSSL_EXPORT void SSL_set_psk_client_callback( + SSL *ssl, unsigned (*cb)(SSL *ssl, const char *hint, char *identity, + unsigned max_identity_len, uint8_t *psk, + unsigned max_psk_len)); + +// SSL_CTX_set_psk_server_callback sets the callback to be called when PSK is +// negotiated on the server. This callback must be set to enable PSK cipher +// suites on the server. +// +// The callback is passed the identity in |identity|. It should write a PSK of +// length at most |max_psk_len| to |psk| and return the number of bytes written +// or zero if the PSK identity is unknown. +OPENSSL_EXPORT void SSL_CTX_set_psk_server_callback( + SSL_CTX *ctx, unsigned (*cb)(SSL *ssl, const char *identity, uint8_t *psk, + unsigned max_psk_len)); + +// SSL_set_psk_server_callback sets the callback to be called when PSK is +// negotiated on the server. This callback must be set to enable PSK cipher +// suites on the server. See also |SSL_CTX_set_psk_server_callback|. +OPENSSL_EXPORT void SSL_set_psk_server_callback( + SSL *ssl, unsigned (*cb)(SSL *ssl, const char *identity, uint8_t *psk, + unsigned max_psk_len)); + +// SSL_CTX_use_psk_identity_hint configures server connections to advertise an +// identity hint of |identity_hint|. It returns one on success and zero on +// error. +OPENSSL_EXPORT int SSL_CTX_use_psk_identity_hint(SSL_CTX *ctx, + const char *identity_hint); + +// SSL_use_psk_identity_hint configures server connections to advertise an +// identity hint of |identity_hint|. It returns one on success and zero on +// error. +OPENSSL_EXPORT int SSL_use_psk_identity_hint(SSL *ssl, + const char *identity_hint); + +// SSL_get_psk_identity_hint returns the PSK identity hint advertised for |ssl| +// or NULL if there is none. +OPENSSL_EXPORT const char *SSL_get_psk_identity_hint(const SSL *ssl); + +// SSL_get_psk_identity, after the handshake completes, returns the PSK identity +// that was negotiated by |ssl| or NULL if PSK was not used. +OPENSSL_EXPORT const char *SSL_get_psk_identity(const SSL *ssl); + + +// Dummy post-quantum padding. +// +// Dummy post-quantum padding invovles the client (and later server) sending +// useless, random-looking bytes in an extension in their ClientHello or +// ServerHello. These extensions are sized to simulate a post-quantum +// key-exchange and so enable measurement of the latency impact of the +// additional bandwidth. + +// SSL_set_dummy_pq_padding_size enables the sending of a dummy PQ padding +// extension and configures its size. This is only effective for a client: a +// server will echo an extension with one of equal length when we get to that +// phase of the experiment. It returns one for success and zero otherwise. +OPENSSL_EXPORT int SSL_set_dummy_pq_padding_size(SSL *ssl, size_t num_bytes); + +// SSL_dummy_pq_padding_used returns one if the server echoed a dummy PQ padding +// extension and zero otherwise. It may only be called on a client connection +// once the ServerHello has been processed, otherwise it'll return zero. +OPENSSL_EXPORT int SSL_dummy_pq_padding_used(SSL *ssl); + + +// QUIC Transport Parameters. +// +// draft-ietf-quic-tls defines a new TLS extension quic_transport_parameters +// used by QUIC for each endpoint to unilaterally declare its supported +// transport parameters. draft-ietf-quic-transport (section 7.4) defines the +// contents of that extension (a TransportParameters struct) and describes how +// to handle it and its semantic meaning. +// +// BoringSSL handles this extension as an opaque byte string. The caller is +// responsible for serializing and parsing it. + +// SSL_set_quic_transport_params configures |ssl| to send |params| (of length +// |params_len|) in the quic_transport_parameters extension in either the +// ClientHello or EncryptedExtensions handshake message. This extension will +// only be sent if the TLS version is at least 1.3, and for a server, only if +// the client sent the extension. The buffer pointed to by |params| only need be +// valid for the duration of the call to this function. This function returns 1 +// on success and 0 on failure. +OPENSSL_EXPORT int SSL_set_quic_transport_params(SSL *ssl, + const uint8_t *params, + size_t params_len); + +// SSL_get_peer_quic_transport_params provides the caller with the value of the +// quic_transport_parameters extension sent by the peer. A pointer to the buffer +// containing the TransportParameters will be put in |*out_params|, and its +// length in |*params_len|. This buffer will be valid for the lifetime of the +// |SSL|. If no params were received from the peer, |*out_params_len| will be 0. +OPENSSL_EXPORT void SSL_get_peer_quic_transport_params(const SSL *ssl, + const uint8_t **out_params, + size_t *out_params_len); + + +// Early data. +// +// WARNING: 0-RTT support in BoringSSL is currently experimental and not fully +// implemented. It may cause interoperability or security failures when used. +// +// Early data, or 0-RTT, is a feature in TLS 1.3 which allows clients to send +// data on the first flight during a resumption handshake. This can save a +// round-trip in some application protocols. +// +// WARNING: A 0-RTT handshake has different security properties from normal +// handshake, so it is off by default unless opted in. In particular, early data +// is replayable by a network attacker. Callers must account for this when +// sending or processing data before the handshake is confirmed. See +// draft-ietf-tls-tls13-18 for more information. +// +// As a server, if early data is accepted, |SSL_do_handshake| will complete as +// soon as the ClientHello is processed and server flight sent. |SSL_write| may +// be used to send half-RTT data. |SSL_read| will consume early data and +// transition to 1-RTT data as appropriate. Prior to the transition, +// |SSL_in_init| will report the handshake is still in progress. Callers may use +// it or |SSL_in_early_data| to defer or reject requests as needed. +// +// Early data as a client is more complex. If the offered session (see +// |SSL_set_session|) is 0-RTT-capable, the handshake will return after sending +// the ClientHello. The predicted peer certificates and ALPN protocol will be +// available via the usual APIs. |SSL_write| will write early data, up to the +// session's limit. Writes past this limit and |SSL_read| will complete the +// handshake before continuing. Callers may also call |SSL_do_handshake| again +// to complete the handshake sooner. +// +// If the server accepts early data, the handshake will succeed. |SSL_read| and +// |SSL_write| will then act as in a 1-RTT handshake. The peer certificates and +// ALPN protocol will be as predicted and need not be re-queried. +// +// If the server rejects early data, |SSL_do_handshake| (and thus |SSL_read| and +// |SSL_write|) will then fail with |SSL_get_error| returning +// |SSL_ERROR_EARLY_DATA_REJECTED|. The caller should treat this as a connection +// error and most likely perform a high-level retry. Note the server may still +// have processed the early data due to attacker replays. +// +// To then continue the handshake on the original connection, use +// |SSL_reset_early_data_reject|. The connection will then behave as one which +// had not yet completed the handshake. This allows a faster retry than making a +// fresh connection. |SSL_do_handshake| will complete the full handshake, +// possibly resulting in different peer certificates, ALPN protocol, and other +// properties. The caller must disregard any values from before the reset and +// query again. +// +// Finally, to implement the fallback described in draft-ietf-tls-tls13-18 +// appendix C.3, retry on a fresh connection without 0-RTT if the handshake +// fails with |SSL_R_WRONG_VERSION_ON_EARLY_DATA|. + +// SSL_CTX_set_early_data_enabled sets whether early data is allowed to be used +// with resumptions using |ctx|. +OPENSSL_EXPORT void SSL_CTX_set_early_data_enabled(SSL_CTX *ctx, int enabled); + +// SSL_set_early_data_enabled sets whether early data is allowed to be used +// with resumptions using |ssl|. See |SSL_CTX_set_early_data_enabled| for more +// information. +OPENSSL_EXPORT void SSL_set_early_data_enabled(SSL *ssl, int enabled); + +// SSL_in_early_data returns one if |ssl| has a pending handshake that has +// progressed enough to send or receive early data. Clients may call |SSL_write| +// to send early data, but |SSL_read| will complete the handshake before +// accepting application data. Servers may call |SSL_read| to read early data +// and |SSL_write| to send half-RTT data. +OPENSSL_EXPORT int SSL_in_early_data(const SSL *ssl); + +// SSL_early_data_accepted returns whether early data was accepted on the +// handshake performed by |ssl|. +OPENSSL_EXPORT int SSL_early_data_accepted(const SSL *ssl); + +// SSL_reset_early_data_reject resets |ssl| after an early data reject. All +// 0-RTT state is discarded, including any pending |SSL_write| calls. The caller +// should treat |ssl| as a logically fresh connection, usually by driving the +// handshake to completion using |SSL_do_handshake|. +// +// It is an error to call this function on an |SSL| object that is not signaling +// |SSL_ERROR_EARLY_DATA_REJECTED|. +OPENSSL_EXPORT void SSL_reset_early_data_reject(SSL *ssl); + +// SSL_export_early_keying_material behaves like |SSL_export_keying_material|, +// but it uses the early exporter. The operation will fail if |ssl| did not +// negotiate TLS 1.3 or 0-RTT. +OPENSSL_EXPORT int SSL_export_early_keying_material( + SSL *ssl, uint8_t *out, size_t out_len, const char *label, size_t label_len, + const uint8_t *context, size_t context_len); + + +// Alerts. +// +// TLS and SSL 3.0 use alerts to signal error conditions. Alerts have a type +// (warning or fatal) and description. OpenSSL internally handles fatal alerts +// with dedicated error codes (see |SSL_AD_REASON_OFFSET|). Except for +// close_notify, warning alerts are silently ignored and may only be surfaced +// with |SSL_CTX_set_info_callback|. + +// SSL_AD_REASON_OFFSET is the offset between error reasons and |SSL_AD_*| +// values. Any error code under |ERR_LIB_SSL| with an error reason above this +// value corresponds to an alert description. Consumers may add or subtract +// |SSL_AD_REASON_OFFSET| to convert between them. +// +// make_errors.go reserves error codes above 1000 for manually-assigned errors. +// This value must be kept in sync with reservedReasonCode in make_errors.h +#define SSL_AD_REASON_OFFSET 1000 + +// SSL_AD_* are alert descriptions for SSL 3.0 and TLS. +#define SSL_AD_CLOSE_NOTIFY SSL3_AD_CLOSE_NOTIFY +#define SSL_AD_UNEXPECTED_MESSAGE SSL3_AD_UNEXPECTED_MESSAGE +#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 +#define SSL_AD_DECOMPRESSION_FAILURE SSL3_AD_DECOMPRESSION_FAILURE +#define SSL_AD_HANDSHAKE_FAILURE SSL3_AD_HANDSHAKE_FAILURE +#define SSL_AD_NO_CERTIFICATE SSL3_AD_NO_CERTIFICATE // Not used in TLS +#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 +#define SSL_AD_ILLEGAL_PARAMETER SSL3_AD_ILLEGAL_PARAMETER +#define SSL_AD_UNKNOWN_CA TLS1_AD_UNKNOWN_CA +#define SSL_AD_ACCESS_DENIED TLS1_AD_ACCESS_DENIED +#define SSL_AD_DECODE_ERROR TLS1_AD_DECODE_ERROR +#define SSL_AD_DECRYPT_ERROR TLS1_AD_DECRYPT_ERROR +#define SSL_AD_EXPORT_RESTRICTION TLS1_AD_EXPORT_RESTRICTION +#define SSL_AD_PROTOCOL_VERSION TLS1_AD_PROTOCOL_VERSION +#define SSL_AD_INSUFFICIENT_SECURITY TLS1_AD_INSUFFICIENT_SECURITY +#define SSL_AD_INTERNAL_ERROR TLS1_AD_INTERNAL_ERROR +#define SSL_AD_INAPPROPRIATE_FALLBACK SSL3_AD_INAPPROPRIATE_FALLBACK +#define SSL_AD_USER_CANCELLED TLS1_AD_USER_CANCELLED +#define SSL_AD_NO_RENEGOTIATION TLS1_AD_NO_RENEGOTIATION +#define SSL_AD_MISSING_EXTENSION TLS1_AD_MISSING_EXTENSION +#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 +#define SSL_AD_UNKNOWN_PSK_IDENTITY TLS1_AD_UNKNOWN_PSK_IDENTITY +#define SSL_AD_CERTIFICATE_REQUIRED TLS1_AD_CERTIFICATE_REQUIRED + +// SSL_alert_type_string_long returns a string description of |value| as an +// alert type (warning or fatal). +OPENSSL_EXPORT const char *SSL_alert_type_string_long(int value); + +// SSL_alert_desc_string_long returns a string description of |value| as an +// alert description or "unknown" if unknown. +OPENSSL_EXPORT const char *SSL_alert_desc_string_long(int value); + +// SSL_send_fatal_alert sends a fatal alert over |ssl| of the specified type, +// which should be one of the |SSL_AD_*| constants. It returns one on success +// and <= 0 on error. The caller should pass the return value into +// |SSL_get_error| to determine how to proceed. Once this function has been +// called, future calls to |SSL_write| will fail. +// +// If retrying a failed operation due to |SSL_ERROR_WANT_WRITE|, subsequent +// calls must use the same |alert| parameter. +OPENSSL_EXPORT int SSL_send_fatal_alert(SSL *ssl, uint8_t alert); + + +// ex_data functions. +// +// See |ex_data.h| for details. + +OPENSSL_EXPORT int SSL_set_ex_data(SSL *ssl, int idx, void *data); +OPENSSL_EXPORT void *SSL_get_ex_data(const SSL *ssl, int idx); +OPENSSL_EXPORT int SSL_get_ex_new_index(long argl, void *argp, + CRYPTO_EX_unused *unused, + CRYPTO_EX_dup *dup_unused, + CRYPTO_EX_free *free_func); + +OPENSSL_EXPORT int SSL_SESSION_set_ex_data(SSL_SESSION *session, int idx, + void *data); +OPENSSL_EXPORT void *SSL_SESSION_get_ex_data(const SSL_SESSION *session, + int idx); +OPENSSL_EXPORT int SSL_SESSION_get_ex_new_index(long argl, void *argp, + CRYPTO_EX_unused *unused, + CRYPTO_EX_dup *dup_unused, + CRYPTO_EX_free *free_func); + +OPENSSL_EXPORT int SSL_CTX_set_ex_data(SSL_CTX *ctx, int idx, void *data); +OPENSSL_EXPORT void *SSL_CTX_get_ex_data(const SSL_CTX *ctx, int idx); +OPENSSL_EXPORT int SSL_CTX_get_ex_new_index(long argl, void *argp, + CRYPTO_EX_unused *unused, + CRYPTO_EX_dup *dup_unused, + CRYPTO_EX_free *free_func); + + +// Low-level record-layer state. + +// SSL_get_ivs sets |*out_iv_len| to the length of the IVs for the ciphers +// underlying |ssl| and sets |*out_read_iv| and |*out_write_iv| to point to the +// current IVs for the read and write directions. This is only meaningful for +// connections with implicit IVs (i.e. CBC mode with SSLv3 or TLS 1.0). +// +// It returns one on success or zero on error. +OPENSSL_EXPORT int SSL_get_ivs(const SSL *ssl, const uint8_t **out_read_iv, + const uint8_t **out_write_iv, + size_t *out_iv_len); + +// SSL_get_key_block_len returns the length of |ssl|'s key block. +OPENSSL_EXPORT size_t SSL_get_key_block_len(const SSL *ssl); + +// SSL_generate_key_block generates |out_len| bytes of key material for |ssl|'s +// current connection state. +OPENSSL_EXPORT int SSL_generate_key_block(const SSL *ssl, uint8_t *out, + size_t out_len); + +// SSL_get_read_sequence returns, in TLS, the expected sequence number of the +// next incoming record in the current epoch. In DTLS, it returns the maximum +// sequence number received in the current epoch and includes the epoch number +// in the two most significant bytes. +OPENSSL_EXPORT uint64_t SSL_get_read_sequence(const SSL *ssl); + +// SSL_get_write_sequence returns the sequence number of the next outgoing +// record in the current epoch. In DTLS, it includes the epoch number in the +// two most significant bytes. +OPENSSL_EXPORT uint64_t SSL_get_write_sequence(const SSL *ssl); + + +// Obscure functions. + +// SSL_get_structure_sizes returns the sizes of the SSL, SSL_CTX and +// SSL_SESSION structures so that a test can ensure that outside code agrees on +// these values. +OPENSSL_EXPORT void SSL_get_structure_sizes(size_t *ssl_size, + size_t *ssl_ctx_size, + size_t *ssl_session_size); + +// SSL_CTX_set_msg_callback installs |cb| as the message callback for |ctx|. +// This callback will be called when sending or receiving low-level record +// headers, complete handshake messages, ChangeCipherSpec, and alerts. +// |write_p| is one for outgoing messages and zero for incoming messages. +// +// For each record header, |cb| is called with |version| = 0 and |content_type| +// = |SSL3_RT_HEADER|. The |len| bytes from |buf| contain the header. Note that +// this does not include the record body. If the record is sealed, the length +// in the header is the length of the ciphertext. +// +// For each handshake message, ChangeCipherSpec, and alert, |version| is the +// protocol version and |content_type| is the corresponding record type. The +// |len| bytes from |buf| contain the handshake message, one-byte +// ChangeCipherSpec body, and two-byte alert, respectively. +// +// For a V2ClientHello, |version| is |SSL2_VERSION|, |content_type| is zero, and +// the |len| bytes from |buf| contain the V2ClientHello structure. +OPENSSL_EXPORT 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_set_msg_callback_arg sets the |arg| parameter of the message +// callback. +OPENSSL_EXPORT void SSL_CTX_set_msg_callback_arg(SSL_CTX *ctx, void *arg); + +// SSL_set_msg_callback installs |cb| as the message callback of |ssl|. See +// |SSL_CTX_set_msg_callback| for when this callback is called. +OPENSSL_EXPORT 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_set_msg_callback_arg sets the |arg| parameter of the message callback. +OPENSSL_EXPORT void SSL_set_msg_callback_arg(SSL *ssl, void *arg); + +// SSL_CTX_set_keylog_callback configures a callback to log key material. This +// is intended for debugging use with tools like Wireshark. The |cb| function +// should log |line| followed by a newline, synchronizing with any concurrent +// access to the log. +// +// The format is described in +// https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS/Key_Log_Format. +OPENSSL_EXPORT void SSL_CTX_set_keylog_callback( + SSL_CTX *ctx, void (*cb)(const SSL *ssl, const char *line)); + +// SSL_CTX_get_keylog_callback returns the callback configured by +// |SSL_CTX_set_keylog_callback|. +OPENSSL_EXPORT void (*SSL_CTX_get_keylog_callback(const SSL_CTX *ctx))( + const SSL *ssl, const char *line); + +// SSL_CTX_set_current_time_cb configures a callback to retrieve the current +// time, which should be set in |*out_clock|. This can be used for testing +// purposes; for example, a callback can be configured that returns a time +// set explicitly by the test. The |ssl| pointer passed to |cb| is always null. +OPENSSL_EXPORT void SSL_CTX_set_current_time_cb( + SSL_CTX *ctx, void (*cb)(const SSL *ssl, struct timeval *out_clock)); + +enum ssl_renegotiate_mode_t { + ssl_renegotiate_never = 0, + ssl_renegotiate_once, + ssl_renegotiate_freely, + ssl_renegotiate_ignore, +}; + +// SSL_set_renegotiate_mode configures how |ssl|, a client, reacts to +// renegotiation attempts by a server. If |ssl| is a server, peer-initiated +// renegotiations are *always* rejected and this function does nothing. +// +// The renegotiation mode defaults to |ssl_renegotiate_never|, but may be set +// at any point in a connection's lifetime. Set it to |ssl_renegotiate_once| to +// allow one renegotiation, |ssl_renegotiate_freely| to allow all +// renegotiations or |ssl_renegotiate_ignore| to ignore HelloRequest messages. +// Note that ignoring HelloRequest messages may cause the connection to stall +// if the server waits for the renegotiation to complete. +// +// There is no support in BoringSSL for initiating renegotiations as a client +// or server. +OPENSSL_EXPORT void SSL_set_renegotiate_mode(SSL *ssl, + enum ssl_renegotiate_mode_t mode); + +// SSL_renegotiate_pending returns one if |ssl| is in the middle of a +// renegotiation. +OPENSSL_EXPORT int SSL_renegotiate_pending(SSL *ssl); + +// SSL_total_renegotiations returns the total number of renegotiation handshakes +// performed by |ssl|. This includes the pending renegotiation, if any. +OPENSSL_EXPORT int SSL_total_renegotiations(const SSL *ssl); + +enum tls13_variant_t { + tls13_default = 0, +}; + +// SSL_CTX_set_tls13_variant sets which variant of TLS 1.3 we negotiate. On the +// server, if |variant| is not |tls13_default|, all variants are enabled. On the +// client, only the configured variant is enabled. +OPENSSL_EXPORT void SSL_CTX_set_tls13_variant(SSL_CTX *ctx, + enum tls13_variant_t variant); + +// SSL_set_tls13_variant sets which variant of TLS 1.3 we negotiate. On the +// server, if |variant| is not |tls13_default|, all variants are enabled. On the +// client, only the configured variant is enabled. +OPENSSL_EXPORT void SSL_set_tls13_variant(SSL *ssl, + enum tls13_variant_t variant); + +// SSL_MAX_CERT_LIST_DEFAULT is the default maximum length, in bytes, of a peer +// certificate chain. +#define SSL_MAX_CERT_LIST_DEFAULT (1024 * 100) + +// SSL_CTX_get_max_cert_list returns the maximum length, in bytes, of a peer +// certificate chain accepted by |ctx|. +OPENSSL_EXPORT size_t SSL_CTX_get_max_cert_list(const SSL_CTX *ctx); + +// SSL_CTX_set_max_cert_list sets the maximum length, in bytes, of a peer +// certificate chain to |max_cert_list|. This affects how much memory may be +// consumed during the handshake. +OPENSSL_EXPORT void SSL_CTX_set_max_cert_list(SSL_CTX *ctx, + size_t max_cert_list); + +// SSL_get_max_cert_list returns the maximum length, in bytes, of a peer +// certificate chain accepted by |ssl|. +OPENSSL_EXPORT size_t SSL_get_max_cert_list(const SSL *ssl); + +// SSL_set_max_cert_list sets the maximum length, in bytes, of a peer +// certificate chain to |max_cert_list|. This affects how much memory may be +// consumed during the handshake. +OPENSSL_EXPORT void SSL_set_max_cert_list(SSL *ssl, size_t max_cert_list); + +// SSL_CTX_set_max_send_fragment sets the maximum length, in bytes, of records +// sent by |ctx|. Beyond this length, handshake messages and application data +// will be split into multiple records. It returns one on success or zero on +// error. +OPENSSL_EXPORT int SSL_CTX_set_max_send_fragment(SSL_CTX *ctx, + size_t max_send_fragment); + +// SSL_set_max_send_fragment sets the maximum length, in bytes, of records sent +// by |ssl|. Beyond this length, handshake messages and application data will +// be split into multiple records. It returns one on success or zero on +// error. +OPENSSL_EXPORT int SSL_set_max_send_fragment(SSL *ssl, + size_t max_send_fragment); + +// ssl_early_callback_ctx (aka |SSL_CLIENT_HELLO|) is passed to certain +// callbacks that are called very early on during the server handshake. At this +// point, much of the SSL* hasn't been filled out and only the ClientHello can +// be depended on. +typedef struct ssl_early_callback_ctx { + SSL *ssl; + const uint8_t *client_hello; + size_t client_hello_len; + uint16_t version; + const uint8_t *random; + size_t random_len; + const uint8_t *session_id; + size_t session_id_len; + const uint8_t *cipher_suites; + size_t cipher_suites_len; + const uint8_t *compression_methods; + size_t compression_methods_len; + const uint8_t *extensions; + size_t extensions_len; +} SSL_CLIENT_HELLO; + +// ssl_select_cert_result_t enumerates the possible results from selecting a +// certificate with |select_certificate_cb|. +enum ssl_select_cert_result_t { + // ssl_select_cert_success indicates that the certificate selection was + // successful. + ssl_select_cert_success = 1, + // ssl_select_cert_retry indicates that the operation could not be + // immediately completed and must be reattempted at a later point. + ssl_select_cert_retry = 0, + // ssl_select_cert_error indicates that a fatal error occured and the + // handshake should be terminated. + ssl_select_cert_error = -1, +}; + +// SSL_early_callback_ctx_extension_get searches the extensions in +// |client_hello| for an extension of the given type. If not found, it returns +// zero. Otherwise it sets |out_data| to point to the extension contents (not +// including the type and length bytes), sets |out_len| to the length of the +// extension contents and returns one. +OPENSSL_EXPORT int SSL_early_callback_ctx_extension_get( + const SSL_CLIENT_HELLO *client_hello, uint16_t extension_type, + const uint8_t **out_data, size_t *out_len); + +// SSL_CTX_set_select_certificate_cb sets a callback that is called before most +// ClientHello processing and before the decision whether to resume a session +// is made. The callback may inspect the ClientHello and configure the +// connection. See |ssl_select_cert_result_t| for details of the return values. +// +// In the case that a retry is indicated, |SSL_get_error| will return +// |SSL_ERROR_PENDING_CERTIFICATE| and the caller should arrange for the +// high-level operation on |ssl| to be retried at a later time, which will +// result in another call to |cb|. +// +// Note: The |SSL_CLIENT_HELLO| is only valid for the duration of the callback +// and is not valid while the handshake is paused. +OPENSSL_EXPORT void SSL_CTX_set_select_certificate_cb( + SSL_CTX *ctx, + enum ssl_select_cert_result_t (*cb)(const SSL_CLIENT_HELLO *)); + +// SSL_CTX_set_dos_protection_cb sets a callback that is called once the +// resumption decision for a ClientHello has been made. It can return one to +// allow the handshake to continue or zero to cause the handshake to abort. +OPENSSL_EXPORT void SSL_CTX_set_dos_protection_cb( + SSL_CTX *ctx, int (*cb)(const SSL_CLIENT_HELLO *)); + +// SSL_ST_* are possible values for |SSL_state| and the bitmasks that make them +// up. +#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_OK 0x03 +#define SSL_ST_RENEGOTIATE (0x04 | SSL_ST_INIT) + +// SSL_CB_* are possible values for the |type| parameter in the info +// callback and the bitmasks that make them up. +#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 +#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 + +// SSL_CTX_set_info_callback configures a callback to be run when various +// events occur during a connection's lifetime. The |type| argument determines +// the type of event and the meaning of the |value| argument. Callbacks must +// ignore unexpected |type| values. +// +// |SSL_CB_READ_ALERT| is signaled for each alert received, warning or fatal. +// The |value| argument is a 16-bit value where the alert level (either +// |SSL3_AL_WARNING| or |SSL3_AL_FATAL|) is in the most-significant eight bits +// and the alert type (one of |SSL_AD_*|) is in the least-significant eight. +// +// |SSL_CB_WRITE_ALERT| is signaled for each alert sent. The |value| argument +// is constructed as with |SSL_CB_READ_ALERT|. +// +// |SSL_CB_HANDSHAKE_START| is signaled when a handshake begins. The |value| +// argument is always one. +// +// |SSL_CB_HANDSHAKE_DONE| is signaled when a handshake completes successfully. +// The |value| argument is always one. If a handshake False Starts, this event +// may be used to determine when the Finished message is received. +// +// The following event types expose implementation details of the handshake +// state machine. Consuming them is deprecated. +// +// |SSL_CB_ACCEPT_LOOP| (respectively, |SSL_CB_CONNECT_LOOP|) is signaled when +// a server (respectively, client) handshake progresses. The |value| argument +// is always one. +// +// |SSL_CB_ACCEPT_EXIT| (respectively, |SSL_CB_CONNECT_EXIT|) is signaled when +// a server (respectively, client) handshake completes, fails, or is paused. +// The |value| argument is one if the handshake succeeded and <= 0 +// otherwise. +OPENSSL_EXPORT void SSL_CTX_set_info_callback( + SSL_CTX *ctx, void (*cb)(const SSL *ssl, int type, int value)); + +// SSL_CTX_get_info_callback returns the callback set by +// |SSL_CTX_set_info_callback|. +OPENSSL_EXPORT void (*SSL_CTX_get_info_callback(SSL_CTX *ctx))(const SSL *ssl, + int type, + int value); + +// SSL_set_info_callback configures a callback to be run at various events +// during a connection's lifetime. See |SSL_CTX_set_info_callback|. +OPENSSL_EXPORT void SSL_set_info_callback( + SSL *ssl, void (*cb)(const SSL *ssl, int type, int value)); + +// SSL_get_info_callback returns the callback set by |SSL_set_info_callback|. +OPENSSL_EXPORT void (*SSL_get_info_callback(const SSL *ssl))(const SSL *ssl, + int type, + int value); + +// SSL_state_string_long returns the current state of the handshake state +// machine as a string. This may be useful for debugging and logging. +OPENSSL_EXPORT const char *SSL_state_string_long(const SSL *ssl); + +#define SSL_SENT_SHUTDOWN 1 +#define SSL_RECEIVED_SHUTDOWN 2 + +// SSL_get_shutdown returns a bitmask with a subset of |SSL_SENT_SHUTDOWN| and +// |SSL_RECEIVED_SHUTDOWN| to query whether close_notify was sent or received, +// respectively. +OPENSSL_EXPORT int SSL_get_shutdown(const SSL *ssl); + +// SSL_get_peer_signature_algorithm returns the signature algorithm used by the +// peer. If not applicable, it returns zero. +OPENSSL_EXPORT uint16_t SSL_get_peer_signature_algorithm(const SSL *ssl); + +// SSL_get_client_random writes up to |max_out| bytes of the most recent +// handshake's client_random to |out| and returns the number of bytes written. +// If |max_out| is zero, it returns the size of the client_random. +OPENSSL_EXPORT size_t SSL_get_client_random(const SSL *ssl, uint8_t *out, + size_t max_out); + +// SSL_get_server_random writes up to |max_out| bytes of the most recent +// handshake's server_random to |out| and returns the number of bytes written. +// If |max_out| is zero, it returns the size of the server_random. +OPENSSL_EXPORT size_t SSL_get_server_random(const SSL *ssl, uint8_t *out, + size_t max_out); + +// SSL_get_pending_cipher returns the cipher suite for the current handshake or +// NULL if one has not been negotiated yet or there is no pending handshake. +OPENSSL_EXPORT const SSL_CIPHER *SSL_get_pending_cipher(const SSL *ssl); + +// SSL_set_retain_only_sha256_of_client_certs, on a server, sets whether only +// the SHA-256 hash of peer's certificate should be saved in memory and in the +// session. This can save memory, ticket size and session cache space. If +// enabled, |SSL_get_peer_certificate| will return NULL after the handshake +// completes. See the |peer_sha256| field of |SSL_SESSION| for the hash. +OPENSSL_EXPORT void SSL_set_retain_only_sha256_of_client_certs(SSL *ssl, + int enable); + +// SSL_CTX_set_retain_only_sha256_of_client_certs, on a server, sets whether +// only the SHA-256 hash of peer's certificate should be saved in memory and in +// the session. This can save memory, ticket size and session cache space. If +// enabled, |SSL_get_peer_certificate| will return NULL after the handshake +// completes. See the |peer_sha256| field of |SSL_SESSION| for the hash. +OPENSSL_EXPORT void SSL_CTX_set_retain_only_sha256_of_client_certs(SSL_CTX *ctx, + int enable); + +// SSL_CTX_set_grease_enabled configures whether sockets on |ctx| should enable +// GREASE. See draft-davidben-tls-grease-01. +OPENSSL_EXPORT void SSL_CTX_set_grease_enabled(SSL_CTX *ctx, int enabled); + +// SSL_max_seal_overhead returns the maximum overhead, in bytes, of sealing a +// record with |ssl|. +OPENSSL_EXPORT size_t SSL_max_seal_overhead(const SSL *ssl); + +// SSL_get_ticket_age_skew returns the difference, in seconds, between the +// client-sent ticket age and the server-computed value in TLS 1.3 server +// connections which resumed a session. +OPENSSL_EXPORT int32_t SSL_get_ticket_age_skew(const SSL *ssl); + +// SSL_CTX_set_false_start_allowed_without_alpn configures whether connections +// on |ctx| may use False Start (if |SSL_MODE_ENABLE_FALSE_START| is enabled) +// without negotiating ALPN. +OPENSSL_EXPORT void SSL_CTX_set_false_start_allowed_without_alpn(SSL_CTX *ctx, + int allowed); + +// SSL_is_draft_downgrade returns one if the TLS 1.3 anti-downgrade mechanism +// would have aborted |ssl|'s handshake and zero otherwise. +OPENSSL_EXPORT int SSL_is_draft_downgrade(const SSL *ssl); + + +// Deprecated functions. + +// SSL_library_init calls |CRYPTO_library_init| and returns one. +OPENSSL_EXPORT int SSL_library_init(void); + +// SSL_CIPHER_description writes a description of |cipher| into |buf| and +// returns |buf|. If |buf| is NULL, it returns a newly allocated string, to be +// freed with |OPENSSL_free|, or NULL on error. +// +// The description includes a trailing newline and has the form: +// AES128-SHA Kx=RSA Au=RSA Enc=AES(128) Mac=SHA1 +// +// Consider |SSL_CIPHER_standard_name| or |SSL_CIPHER_get_name| instead. +OPENSSL_EXPORT const char *SSL_CIPHER_description(const SSL_CIPHER *cipher, + char *buf, int len); + +// SSL_CIPHER_get_version returns the string "TLSv1/SSLv3". +OPENSSL_EXPORT const char *SSL_CIPHER_get_version(const SSL_CIPHER *cipher); + +// SSL_CIPHER_get_rfc_name returns a newly-allocated string containing the +// result of |SSL_CIPHER_standard_name| or NULL on error. The caller is +// responsible for calling |OPENSSL_free| on the result. +// +// Use |SSL_CIPHER_standard_name| instead. +OPENSSL_EXPORT char *SSL_CIPHER_get_rfc_name(const SSL_CIPHER *cipher); + +typedef void COMP_METHOD; +typedef struct ssl_comp_st SSL_COMP; + +// SSL_COMP_get_compression_methods returns NULL. +OPENSSL_EXPORT STACK_OF(SSL_COMP) *SSL_COMP_get_compression_methods(void); + +// SSL_COMP_add_compression_method returns one. +OPENSSL_EXPORT int SSL_COMP_add_compression_method(int id, COMP_METHOD *cm); + +// SSL_COMP_get_name returns NULL. +OPENSSL_EXPORT const char *SSL_COMP_get_name(const COMP_METHOD *comp); + +// SSL_COMP_get0_name returns the |name| member of |comp|. +OPENSSL_EXPORT const char *SSL_COMP_get0_name(const SSL_COMP *comp); + +// SSL_COMP_get_id returns the |id| member of |comp|. +OPENSSL_EXPORT int SSL_COMP_get_id(const SSL_COMP *comp); + +// SSL_COMP_free_compression_methods does nothing. +OPENSSL_EXPORT void SSL_COMP_free_compression_methods(void); + +// SSLv23_method calls |TLS_method|. +OPENSSL_EXPORT const SSL_METHOD *SSLv23_method(void); + +// These version-specific methods behave exactly like |TLS_method| and +// |DTLS_method| except they also call |SSL_CTX_set_min_proto_version| and +// |SSL_CTX_set_max_proto_version| to lock connections to that protocol +// version. +OPENSSL_EXPORT const SSL_METHOD *TLSv1_method(void); +OPENSSL_EXPORT const SSL_METHOD *TLSv1_1_method(void); +OPENSSL_EXPORT const SSL_METHOD *TLSv1_2_method(void); +OPENSSL_EXPORT const SSL_METHOD *DTLSv1_method(void); +OPENSSL_EXPORT const SSL_METHOD *DTLSv1_2_method(void); + +// These client- and server-specific methods call their corresponding generic +// methods. +OPENSSL_EXPORT const SSL_METHOD *TLS_server_method(void); +OPENSSL_EXPORT const SSL_METHOD *TLS_client_method(void); +OPENSSL_EXPORT const SSL_METHOD *SSLv23_server_method(void); +OPENSSL_EXPORT const SSL_METHOD *SSLv23_client_method(void); +OPENSSL_EXPORT const SSL_METHOD *TLSv1_server_method(void); +OPENSSL_EXPORT const SSL_METHOD *TLSv1_client_method(void); +OPENSSL_EXPORT const SSL_METHOD *TLSv1_1_server_method(void); +OPENSSL_EXPORT const SSL_METHOD *TLSv1_1_client_method(void); +OPENSSL_EXPORT const SSL_METHOD *TLSv1_2_server_method(void); +OPENSSL_EXPORT const SSL_METHOD *TLSv1_2_client_method(void); +OPENSSL_EXPORT const SSL_METHOD *DTLS_server_method(void); +OPENSSL_EXPORT const SSL_METHOD *DTLS_client_method(void); +OPENSSL_EXPORT const SSL_METHOD *DTLSv1_server_method(void); +OPENSSL_EXPORT const SSL_METHOD *DTLSv1_client_method(void); +OPENSSL_EXPORT const SSL_METHOD *DTLSv1_2_server_method(void); +OPENSSL_EXPORT const SSL_METHOD *DTLSv1_2_client_method(void); + +// SSL_clear resets |ssl| to allow another connection and returns one on success +// or zero on failure. It returns most configuration state but releases memory +// associated with the current connection. +// +// Free |ssl| and create a new one instead. +OPENSSL_EXPORT int SSL_clear(SSL *ssl); + +// SSL_CTX_set_tmp_rsa_callback does nothing. +OPENSSL_EXPORT void SSL_CTX_set_tmp_rsa_callback( + SSL_CTX *ctx, RSA *(*cb)(SSL *ssl, int is_export, int keylength)); + +// SSL_set_tmp_rsa_callback does nothing. +OPENSSL_EXPORT void SSL_set_tmp_rsa_callback(SSL *ssl, + RSA *(*cb)(SSL *ssl, int is_export, + int keylength)); + +// SSL_CTX_sess_connect returns zero. +OPENSSL_EXPORT int SSL_CTX_sess_connect(const SSL_CTX *ctx); + +// SSL_CTX_sess_connect_good returns zero. +OPENSSL_EXPORT int SSL_CTX_sess_connect_good(const SSL_CTX *ctx); + +// SSL_CTX_sess_connect_renegotiate returns zero. +OPENSSL_EXPORT int SSL_CTX_sess_connect_renegotiate(const SSL_CTX *ctx); + +// SSL_CTX_sess_accept returns zero. +OPENSSL_EXPORT int SSL_CTX_sess_accept(const SSL_CTX *ctx); + +// SSL_CTX_sess_accept_renegotiate returns zero. +OPENSSL_EXPORT int SSL_CTX_sess_accept_renegotiate(const SSL_CTX *ctx); + +// SSL_CTX_sess_accept_good returns zero. +OPENSSL_EXPORT int SSL_CTX_sess_accept_good(const SSL_CTX *ctx); + +// SSL_CTX_sess_hits returns zero. +OPENSSL_EXPORT int SSL_CTX_sess_hits(const SSL_CTX *ctx); + +// SSL_CTX_sess_cb_hits returns zero. +OPENSSL_EXPORT int SSL_CTX_sess_cb_hits(const SSL_CTX *ctx); + +// SSL_CTX_sess_misses returns zero. +OPENSSL_EXPORT int SSL_CTX_sess_misses(const SSL_CTX *ctx); + +// SSL_CTX_sess_timeouts returns zero. +OPENSSL_EXPORT int SSL_CTX_sess_timeouts(const SSL_CTX *ctx); + +// SSL_CTX_sess_cache_full returns zero. +OPENSSL_EXPORT int SSL_CTX_sess_cache_full(const SSL_CTX *ctx); + +// SSL_cutthrough_complete calls |SSL_in_false_start|. +OPENSSL_EXPORT int SSL_cutthrough_complete(const SSL *ssl); + +// SSL_num_renegotiations calls |SSL_total_renegotiations|. +OPENSSL_EXPORT int SSL_num_renegotiations(const SSL *ssl); + +// SSL_CTX_need_tmp_RSA returns zero. +OPENSSL_EXPORT int SSL_CTX_need_tmp_RSA(const SSL_CTX *ctx); + +// SSL_need_tmp_RSA returns zero. +OPENSSL_EXPORT int SSL_need_tmp_RSA(const SSL *ssl); + +// SSL_CTX_set_tmp_rsa returns one. +OPENSSL_EXPORT int SSL_CTX_set_tmp_rsa(SSL_CTX *ctx, const RSA *rsa); + +// SSL_set_tmp_rsa returns one. +OPENSSL_EXPORT int SSL_set_tmp_rsa(SSL *ssl, const RSA *rsa); + +// SSL_CTX_get_read_ahead returns zero. +OPENSSL_EXPORT int SSL_CTX_get_read_ahead(const SSL_CTX *ctx); + +// SSL_CTX_set_read_ahead does nothing. +OPENSSL_EXPORT void SSL_CTX_set_read_ahead(SSL_CTX *ctx, int yes); + +// SSL_get_read_ahead returns zero. +OPENSSL_EXPORT int SSL_get_read_ahead(const SSL *ssl); + +// SSL_set_read_ahead does nothing. +OPENSSL_EXPORT void SSL_set_read_ahead(SSL *ssl, int yes); + +// SSL_renegotiate put an error on the error queue and returns zero. +OPENSSL_EXPORT int SSL_renegotiate(SSL *ssl); + +// SSL_set_state does nothing. +OPENSSL_EXPORT void SSL_set_state(SSL *ssl, int state); + +// SSL_get_shared_ciphers writes an empty string to |buf| and returns a +// pointer to |buf|, or NULL if |len| is less than or equal to zero. +OPENSSL_EXPORT char *SSL_get_shared_ciphers(const SSL *ssl, char *buf, int len); + +// SSL_MODE_HANDSHAKE_CUTTHROUGH is the same as SSL_MODE_ENABLE_FALSE_START. +#define SSL_MODE_HANDSHAKE_CUTTHROUGH SSL_MODE_ENABLE_FALSE_START + +// i2d_SSL_SESSION serializes |in| to the bytes pointed to by |*pp|. On success, +// it returns the number of bytes written and advances |*pp| by that many bytes. +// On failure, it returns -1. If |pp| is NULL, no bytes are written and only the +// length is returned. +// +// Use |SSL_SESSION_to_bytes| instead. +OPENSSL_EXPORT int i2d_SSL_SESSION(SSL_SESSION *in, uint8_t **pp); + +// d2i_SSL_SESSION parses a serialized session from the |length| bytes pointed +// to by |*pp|. It returns the new |SSL_SESSION| and advances |*pp| by the +// number of bytes consumed on success and NULL on failure. The caller takes +// ownership of the new session and must call |SSL_SESSION_free| when done. +// +// If |a| is non-NULL, |*a| is released and set the new |SSL_SESSION|. +// +// Use |SSL_SESSION_from_bytes| instead. +OPENSSL_EXPORT SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const uint8_t **pp, + long length); + +// i2d_SSL_SESSION_bio serializes |session| and writes the result to |bio|. It +// returns the number of bytes written on success and <= 0 on error. +OPENSSL_EXPORT int i2d_SSL_SESSION_bio(BIO *bio, const SSL_SESSION *session); + +// d2i_SSL_SESSION_bio reads a serialized |SSL_SESSION| from |bio| and returns a +// newly-allocated |SSL_SESSION| or NULL on error. If |out| is not NULL, it also +// frees |*out| and sets |*out| to the new |SSL_SESSION|. +OPENSSL_EXPORT SSL_SESSION *d2i_SSL_SESSION_bio(BIO *bio, SSL_SESSION **out); + +// ERR_load_SSL_strings does nothing. +OPENSSL_EXPORT void ERR_load_SSL_strings(void); + +// SSL_load_error_strings does nothing. +OPENSSL_EXPORT void SSL_load_error_strings(void); + +// SSL_CTX_set_tlsext_use_srtp calls |SSL_CTX_set_srtp_profiles|. It returns +// zero on success and one on failure. +// +// WARNING: this function is dangerous because it breaks the usual return value +// convention. Use |SSL_CTX_set_srtp_profiles| instead. +OPENSSL_EXPORT int SSL_CTX_set_tlsext_use_srtp(SSL_CTX *ctx, + const char *profiles); + +// SSL_set_tlsext_use_srtp calls |SSL_set_srtp_profiles|. It returns zero on +// success and one on failure. +// +// WARNING: this function is dangerous because it breaks the usual return value +// convention. Use |SSL_set_srtp_profiles| instead. +OPENSSL_EXPORT int SSL_set_tlsext_use_srtp(SSL *ssl, const char *profiles); + +// SSL_get_current_compression returns NULL. +OPENSSL_EXPORT const COMP_METHOD *SSL_get_current_compression(SSL *ssl); + +// SSL_get_current_expansion returns NULL. +OPENSSL_EXPORT const COMP_METHOD *SSL_get_current_expansion(SSL *ssl); + +// SSL_get_server_tmp_key returns zero. +OPENSSL_EXPORT int *SSL_get_server_tmp_key(SSL *ssl, EVP_PKEY **out_key); + +// SSL_CTX_set_tmp_dh returns 1. +OPENSSL_EXPORT int SSL_CTX_set_tmp_dh(SSL_CTX *ctx, const DH *dh); + +// SSL_set_tmp_dh returns 1. +OPENSSL_EXPORT int SSL_set_tmp_dh(SSL *ssl, const DH *dh); + +// SSL_CTX_set_tmp_dh_callback does nothing. +OPENSSL_EXPORT void SSL_CTX_set_tmp_dh_callback( + SSL_CTX *ctx, DH *(*cb)(SSL *ssl, int is_export, int keylength)); + +// SSL_set_tmp_dh_callback does nothing. +OPENSSL_EXPORT void SSL_set_tmp_dh_callback(SSL *ssl, + DH *(*cb)(SSL *ssl, int is_export, + int keylength)); + + +#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))) + +#define OpenSSL_add_ssl_algorithms() SSL_library_init() +#define SSLeay_add_ssl_algorithms() SSL_library_init() + +#define SSL_get_cipher(ssl) SSL_CIPHER_get_name(SSL_get_current_cipher(ssl)) +#define SSL_get_cipher_bits(ssl, out_alg_bits) \ + SSL_CIPHER_get_bits(SSL_get_current_cipher(ssl), out_alg_bits) +#define SSL_get_cipher_version(ssl) \ + SSL_CIPHER_get_version(SSL_get_current_cipher(ssl)) +#define SSL_get_cipher_name(ssl) \ + SSL_CIPHER_get_name(SSL_get_current_cipher(ssl)) +#define SSL_get_time(session) SSL_SESSION_get_time(session) +#define SSL_set_time(session, time) SSL_SESSION_set_time((session), (time)) +#define SSL_get_timeout(session) SSL_SESSION_get_timeout(session) +#define SSL_set_timeout(session, timeout) \ + SSL_SESSION_set_timeout((session), (timeout)) + +struct ssl_comp_st { + int id; + const char *name; + char *method; +}; + +DEFINE_STACK_OF(SSL_COMP) + +// The following flags do nothing and are included only to make it easier to +// compile code with BoringSSL. +#define SSL_MODE_AUTO_RETRY 0 +#define SSL_MODE_RELEASE_BUFFERS 0 +#define SSL_MODE_SEND_CLIENTHELLO_TIME 0 +#define SSL_MODE_SEND_SERVERHELLO_TIME 0 +#define SSL_OP_ALL 0 +#define SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION 0 +#define SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS 0 +#define SSL_OP_EPHEMERAL_RSA 0 +#define SSL_OP_LEGACY_SERVER_CONNECT 0 +#define SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER 0 +#define SSL_OP_MICROSOFT_SESS_ID_BUG 0 +#define SSL_OP_MSIE_SSLV2_RSA_PADDING 0 +#define SSL_OP_NETSCAPE_CA_DN_BUG 0 +#define SSL_OP_NETSCAPE_CHALLENGE_BUG 0 +#define SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG 0 +#define SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG 0 +#define SSL_OP_NO_COMPRESSION 0 +#define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0 +#define SSL_OP_NO_SSLv2 0 +#define SSL_OP_PKCS1_CHECK_1 0 +#define SSL_OP_PKCS1_CHECK_2 0 +#define SSL_OP_SINGLE_DH_USE 0 +#define SSL_OP_SINGLE_ECDH_USE 0 +#define SSL_OP_SSLEAY_080_CLIENT_DH_BUG 0 +#define SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG 0 +#define SSL_OP_TLS_BLOCK_PADDING_BUG 0 +#define SSL_OP_TLS_D5_BUG 0 +#define SSL_OP_TLS_ROLLBACK_BUG 0 +#define SSL_VERIFY_CLIENT_ONCE 0 + +// SSL_cache_hit calls |SSL_session_reused|. +OPENSSL_EXPORT int SSL_cache_hit(SSL *ssl); + +// SSL_get_default_timeout returns |SSL_DEFAULT_SESSION_TIMEOUT|. +OPENSSL_EXPORT long SSL_get_default_timeout(const SSL *ssl); + +// SSL_get_version returns a string describing the TLS version used by |ssl|. +// For example, "TLSv1.2" or "SSLv3". +OPENSSL_EXPORT const char *SSL_get_version(const SSL *ssl); + +// SSL_get_cipher_list returns the name of the |n|th cipher in the output of +// |SSL_get_ciphers| or NULL if out of range. Use |SSL_get_ciphers| instead. +OPENSSL_EXPORT const char *SSL_get_cipher_list(const SSL *ssl, int n); + +// SSL_CTX_set_client_cert_cb sets a callback which is called on the client if +// the server requests a client certificate and none is configured. On success, +// the callback should return one and set |*out_x509| to |*out_pkey| to a leaf +// certificate and private key, respectively, passing ownership. It should +// return zero to send no certificate and -1 to fail or pause the handshake. If +// the handshake is paused, |SSL_get_error| will return +// |SSL_ERROR_WANT_X509_LOOKUP|. +// +// The callback may call |SSL_get0_certificate_types| and +// |SSL_get_client_CA_list| for information on the server's certificate request. +// +// Use |SSL_CTX_set_cert_cb| instead. Configuring intermediate certificates with +// this function is confusing. This callback may not be registered concurrently +// with |SSL_CTX_set_cert_cb| or |SSL_set_cert_cb|. +OPENSSL_EXPORT void SSL_CTX_set_client_cert_cb( + SSL_CTX *ctx, int (*cb)(SSL *ssl, X509 **out_x509, EVP_PKEY **out_pkey)); + +#define SSL_NOTHING 1 +#define SSL_WRITING 2 +#define SSL_READING 3 +#define SSL_X509_LOOKUP 4 +#define SSL_CHANNEL_ID_LOOKUP 5 +#define SSL_PENDING_SESSION 7 +#define SSL_CERTIFICATE_SELECTION_PENDING 8 +#define SSL_PRIVATE_KEY_OPERATION 9 +#define SSL_PENDING_TICKET 10 +#define SSL_EARLY_DATA_REJECTED 11 +#define SSL_CERTIFICATE_VERIFY 12 +#define SSL_HANDOFF 13 + +// SSL_want returns one of the above values to determine what the most recent +// operation on |ssl| was blocked on. Use |SSL_get_error| instead. +OPENSSL_EXPORT int SSL_want(const SSL *ssl); + +#define SSL_want_read(ssl) (SSL_want(ssl) == SSL_READING) +#define SSL_want_write(ssl) (SSL_want(ssl) == SSL_WRITING) + + // SSL_get_finished writes up to |count| bytes of the Finished message sent by + // |ssl| to |buf|. It returns the total untruncated length or zero if none has + // been sent yet. At SSL 3.0 or TLS 1.3 and later, it returns zero. + // + // Use |SSL_get_tls_unique| instead. +OPENSSL_EXPORT size_t SSL_get_finished(const SSL *ssl, void *buf, size_t count); + + // SSL_get_peer_finished writes up to |count| bytes of the Finished message + // received from |ssl|'s peer to |buf|. It returns the total untruncated length + // or zero if none has been received yet. At SSL 3.0 or TLS 1.3 and later, it + // returns zero. + // + // Use |SSL_get_tls_unique| instead. +OPENSSL_EXPORT size_t SSL_get_peer_finished(const SSL *ssl, void *buf, + size_t count); + +// SSL_alert_type_string returns "!". Use |SSL_alert_type_string_long| +// instead. +OPENSSL_EXPORT const char *SSL_alert_type_string(int value); + +// SSL_alert_desc_string returns "!!". Use |SSL_alert_desc_string_long| +// instead. +OPENSSL_EXPORT const char *SSL_alert_desc_string(int value); + +// SSL_state_string returns "!!!!!!". Use |SSL_state_string_long| for a more +// intelligible string. +OPENSSL_EXPORT const char *SSL_state_string(const SSL *ssl); + +// SSL_TXT_* expand to strings. +#define SSL_TXT_MEDIUM "MEDIUM" +#define SSL_TXT_HIGH "HIGH" +#define SSL_TXT_FIPS "FIPS" +#define SSL_TXT_kRSA "kRSA" +#define SSL_TXT_kDHE "kDHE" +#define SSL_TXT_kEDH "kEDH" +#define SSL_TXT_kECDHE "kECDHE" +#define SSL_TXT_kEECDH "kEECDH" +#define SSL_TXT_kPSK "kPSK" +#define SSL_TXT_aRSA "aRSA" +#define SSL_TXT_aECDSA "aECDSA" +#define SSL_TXT_aPSK "aPSK" +#define SSL_TXT_DH "DH" +#define SSL_TXT_DHE "DHE" +#define SSL_TXT_EDH "EDH" +#define SSL_TXT_RSA "RSA" +#define SSL_TXT_ECDH "ECDH" +#define SSL_TXT_ECDHE "ECDHE" +#define SSL_TXT_EECDH "EECDH" +#define SSL_TXT_ECDSA "ECDSA" +#define SSL_TXT_PSK "PSK" +#define SSL_TXT_3DES "3DES" +#define SSL_TXT_RC4 "RC4" +#define SSL_TXT_AES128 "AES128" +#define SSL_TXT_AES256 "AES256" +#define SSL_TXT_AES "AES" +#define SSL_TXT_AES_GCM "AESGCM" +#define SSL_TXT_CHACHA20 "CHACHA20" +#define SSL_TXT_MD5 "MD5" +#define SSL_TXT_SHA1 "SHA1" +#define SSL_TXT_SHA "SHA" +#define SSL_TXT_SHA256 "SHA256" +#define SSL_TXT_SHA384 "SHA384" +#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_TLSV1_3 "TLSv1.3" +#define SSL_TXT_ALL "ALL" +#define SSL_TXT_CMPDEF "COMPLEMENTOFDEFAULT" + +typedef struct ssl_conf_ctx_st SSL_CONF_CTX; + +// SSL_state returns |SSL_ST_INIT| if a handshake is in progress and |SSL_ST_OK| +// otherwise. +// +// Use |SSL_is_init| instead. +OPENSSL_EXPORT int SSL_state(const SSL *ssl); + +#define SSL_get_state(ssl) SSL_state(ssl) + +// SSL_set_shutdown causes |ssl| to behave as if the shutdown bitmask (see +// |SSL_get_shutdown|) were |mode|. This may be used to skip sending or +// receiving close_notify in |SSL_shutdown| by causing the implementation to +// believe the events already happened. +// +// It is an error to use |SSL_set_shutdown| to unset a bit that has already been +// set. Doing so will trigger an |assert| in debug builds and otherwise be +// ignored. +// +// Use |SSL_CTX_set_quiet_shutdown| instead. +OPENSSL_EXPORT void SSL_set_shutdown(SSL *ssl, int mode); + +// SSL_CTX_set_tmp_ecdh calls |SSL_CTX_set1_curves| with a one-element list +// containing |ec_key|'s curve. +OPENSSL_EXPORT int SSL_CTX_set_tmp_ecdh(SSL_CTX *ctx, const EC_KEY *ec_key); + +// SSL_set_tmp_ecdh calls |SSL_set1_curves| with a one-element list containing +// |ec_key|'s curve. +OPENSSL_EXPORT int SSL_set_tmp_ecdh(SSL *ssl, const EC_KEY *ec_key); + +// SSL_add_dir_cert_subjects_to_stack lists files in directory |dir|. It calls +// |SSL_add_file_cert_subjects_to_stack| on each file and returns one on success +// or zero on error. This function is only available from the libdecrepit +// library. +OPENSSL_EXPORT int SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *out, + const char *dir); + +// SSL_set_verify_result calls |abort| unless |result| is |X509_V_OK|. +// +// TODO(davidben): Remove this function once it has been removed from +// netty-tcnative. +OPENSSL_EXPORT void SSL_set_verify_result(SSL *ssl, long result); + +// SSL_CTX_enable_tls_channel_id calls |SSL_CTX_set_tls_channel_id_enabled|. +OPENSSL_EXPORT int SSL_CTX_enable_tls_channel_id(SSL_CTX *ctx); + +// SSL_enable_tls_channel_id calls |SSL_set_tls_channel_id_enabled|. +OPENSSL_EXPORT int SSL_enable_tls_channel_id(SSL *ssl); + +// BIO_f_ssl returns a |BIO_METHOD| that can wrap an |SSL*| in a |BIO*|. Note +// that this has quite different behaviour from the version in OpenSSL (notably +// that it doesn't try to auto renegotiate). +// +// IMPORTANT: if you are not curl, don't use this. +OPENSSL_EXPORT const BIO_METHOD *BIO_f_ssl(void); + +// BIO_set_ssl sets |ssl| as the underlying connection for |bio|, which must +// have been created using |BIO_f_ssl|. If |take_owership| is true, |bio| will +// call |SSL_free| on |ssl| when closed. It returns one on success or something +// other than one on error. +OPENSSL_EXPORT long BIO_set_ssl(BIO *bio, SSL *ssl, int take_owership); + +// SSL_CTX_set_ecdh_auto returns one. +#define SSL_CTX_set_ecdh_auto(ctx, onoff) 1 + +// SSL_set_ecdh_auto returns one. +#define SSL_set_ecdh_auto(ssl, onoff) 1 + +// SSL_get_session returns a non-owning pointer to |ssl|'s session. For +// historical reasons, which session it returns depends on |ssl|'s state. +// +// Prior to the start of the initial handshake, it returns the session the +// caller set with |SSL_set_session|. After the initial handshake has finished +// and if no additional handshakes are in progress, it returns the currently +// active session. Its behavior is undefined while a handshake is in progress. +// +// If trying to add new sessions to an external session cache, use +// |SSL_CTX_sess_set_new_cb| instead. In particular, using the callback is +// required as of TLS 1.3. For compatibility, this function will return an +// unresumable session which may be cached, but will never be resumed. +// +// If querying properties of the connection, use APIs on the |SSL| object. +OPENSSL_EXPORT SSL_SESSION *SSL_get_session(const SSL *ssl); + +// SSL_get0_session is an alias for |SSL_get_session|. +#define SSL_get0_session SSL_get_session + +// SSL_get1_session acts like |SSL_get_session| but returns a new reference to +// the session. +OPENSSL_EXPORT SSL_SESSION *SSL_get1_session(SSL *ssl); + +#define OPENSSL_INIT_NO_LOAD_SSL_STRINGS 0 +#define OPENSSL_INIT_LOAD_SSL_STRINGS 0 +#define OPENSSL_INIT_SSL_DEFAULT 0 + +// OPENSSL_init_ssl calls |CRYPTO_library_init| and returns one. +OPENSSL_EXPORT int OPENSSL_init_ssl(uint64_t opts, + const OPENSSL_INIT_SETTINGS *settings); + +#if !defined(BORINGSSL_NO_CXX) +// SSL_CTX_sess_set_get_cb is a legacy C++ overload of |SSL_CTX_sess_set_get_cb| +// which supports the old callback signature. +// +// TODO(davidben): Remove this once Node is compatible with OpenSSL 1.1.0. +extern "C++" OPENSSL_EXPORT void SSL_CTX_sess_set_get_cb( + SSL_CTX *ctx, SSL_SESSION *(*get_session_cb)(SSL *ssl, uint8_t *id, + int id_len, int *out_copy)); +#endif + + +// Private structures. +// +// This structures are exposed for historical reasons, but access to them is +// deprecated. + +// TODO(davidben): Remove this forward declaration when |SSL_SESSION| is opaque. +typedef struct ssl_x509_method_st SSL_X509_METHOD; + +#define SSL_MAX_SSL_SESSION_ID_LENGTH 32 +#define SSL_MAX_SID_CTX_LENGTH 32 +#define SSL_MAX_MASTER_KEY_LENGTH 48 + +struct ssl_session_st { + CRYPTO_refcount_t references; + uint16_t ssl_version; // what ssl version session info is being kept in here? + + // group_id is the ID of the ECDH group used to establish this session or zero + // if not applicable or unknown. + uint16_t group_id; + + // peer_signature_algorithm is the signature algorithm used to authenticate + // the peer, or zero if not applicable or unknown. + uint16_t peer_signature_algorithm; + + // master_key, in TLS 1.2 and below, is the master secret associated with the + // session. In TLS 1.3 and up, it is the resumption secret. + int master_key_length; + uint8_t master_key[SSL_MAX_MASTER_KEY_LENGTH]; + + // session_id - valid? + unsigned int session_id_length; + uint8_t 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 + uint8_t sid_ctx_length; + uint8_t sid_ctx[SSL_MAX_SID_CTX_LENGTH]; + + char *psk_identity; + + // certs contains the certificate chain from the peer, starting with the leaf + // certificate. + STACK_OF(CRYPTO_BUFFER) *certs; + + const SSL_X509_METHOD *x509_method; + + // x509_peer is the peer's certificate. + X509 *x509_peer; + + // x509_chain is the certificate chain sent by the peer. NOTE: for historical + // reasons, when a client (so the peer is a server), the chain includes + // |peer|, but when a server it does not. + STACK_OF(X509) *x509_chain; + + // x509_chain_without_leaf is a lazily constructed copy of |x509_chain| that + // omits the leaf certificate. This exists because OpenSSL, historically, + // didn't include the leaf certificate in the chain for a server, but did for + // a client. The |x509_chain| always includes it and, if an API call requires + // a chain without, it is stored here. + STACK_OF(X509) *x509_chain_without_leaf; + + // verify_result is the result of certificate verification in the case of + // non-fatal certificate errors. + long verify_result; + + // timeout is the lifetime of the session in seconds, measured from |time|. + // This is renewable up to |auth_timeout|. + uint32_t timeout; + + // auth_timeout is the non-renewable lifetime of the session in seconds, + // measured from |time|. + uint32_t auth_timeout; + + // time is the time the session was issued, measured in seconds from the UNIX + // epoch. + uint64_t time; + + const SSL_CIPHER *cipher; + + 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. + SSL_SESSION *prev, *next; + + // RFC4507 info + uint8_t *tlsext_tick; // Session ticket + size_t tlsext_ticklen; // Session ticket length + + CRYPTO_BUFFER *signed_cert_timestamp_list; + + // The OCSP response that came with the session. + CRYPTO_BUFFER *ocsp_response; + + // peer_sha256 contains the SHA-256 hash of the peer's certificate if + // |peer_sha256_valid| is true. + uint8_t peer_sha256[SHA256_DIGEST_LENGTH]; + + // original_handshake_hash contains the handshake hash (either SHA-1+MD5 or + // SHA-2, depending on TLS version) for the original, full handshake that + // created a session. This is used by Channel IDs during resumption. + uint8_t original_handshake_hash[EVP_MAX_MD_SIZE]; + uint8_t original_handshake_hash_len; + + uint32_t tlsext_tick_lifetime_hint; // Session lifetime hint in seconds + + uint32_t ticket_age_add; + + // ticket_max_early_data is the maximum amount of data allowed to be sent as + // early data. If zero, 0-RTT is disallowed. + uint32_t ticket_max_early_data; + + // early_alpn is the ALPN protocol from the initial handshake. This is only + // stored for TLS 1.3 and above in order to enforce ALPN matching for 0-RTT + // resumptions. + uint8_t *early_alpn; + size_t early_alpn_len; + + // extended_master_secret is true if the master secret in this session was + // generated using EMS and thus isn't vulnerable to the Triple Handshake + // attack. + unsigned extended_master_secret:1; + + // peer_sha256_valid is non-zero if |peer_sha256| is valid. + unsigned peer_sha256_valid:1; // Non-zero if peer_sha256 is valid + + // not_resumable is used to indicate that session resumption is disallowed. + unsigned not_resumable:1; + + // ticket_age_add_valid is non-zero if |ticket_age_add| is valid. + unsigned ticket_age_add_valid:1; + + // is_server is true if this session was created by a server. + unsigned is_server:1; +}; + + +// Nodejs compatibility section (hidden). +// +// These defines exist for node.js, with the hope that we can eliminate the +// need for them over time. +#define SSLerr(function, reason) \ + ERR_put_error(ERR_LIB_SSL, 0, reason, __FILE__, __LINE__) + + +// Preprocessor compatibility section (hidden). +// +// Historically, a number of APIs were implemented in OpenSSL as macros and +// constants to 'ctrl' functions. To avoid breaking #ifdefs in consumers, this +// section defines a number of legacy macros. +// +// Although using either the CTRL values or their wrapper macros in #ifdefs is +// still supported, the CTRL values may not be passed to |SSL_ctrl| and +// |SSL_CTX_ctrl|. Call the functions (previously wrapper macros) instead. +// +// See PORTING.md in the BoringSSL source tree for a table of corresponding +// functions. +// https://boringssl.googlesource.com/boringssl/+/master/PORTING.md#Replacements-for-values + +#define DTLS_CTRL_GET_TIMEOUT doesnt_exist +#define DTLS_CTRL_HANDLE_TIMEOUT doesnt_exist +#define SSL_CTRL_CHAIN doesnt_exist +#define SSL_CTRL_CHAIN_CERT doesnt_exist +#define SSL_CTRL_CHANNEL_ID doesnt_exist +#define SSL_CTRL_CLEAR_EXTRA_CHAIN_CERTS doesnt_exist +#define SSL_CTRL_CLEAR_MODE doesnt_exist +#define SSL_CTRL_CLEAR_OPTIONS doesnt_exist +#define SSL_CTRL_EXTRA_CHAIN_CERT doesnt_exist +#define SSL_CTRL_GET_CHAIN_CERTS doesnt_exist +#define SSL_CTRL_GET_CHANNEL_ID doesnt_exist +#define SSL_CTRL_GET_CLIENT_CERT_TYPES doesnt_exist +#define SSL_CTRL_GET_EXTRA_CHAIN_CERTS doesnt_exist +#define SSL_CTRL_GET_MAX_CERT_LIST doesnt_exist +#define SSL_CTRL_GET_NUM_RENEGOTIATIONS doesnt_exist +#define SSL_CTRL_GET_READ_AHEAD doesnt_exist +#define SSL_CTRL_GET_RI_SUPPORT doesnt_exist +#define SSL_CTRL_GET_SESSION_REUSED doesnt_exist +#define SSL_CTRL_GET_SESS_CACHE_MODE doesnt_exist +#define SSL_CTRL_GET_SESS_CACHE_SIZE doesnt_exist +#define SSL_CTRL_GET_TLSEXT_TICKET_KEYS doesnt_exist +#define SSL_CTRL_GET_TOTAL_RENEGOTIATIONS doesnt_exist +#define SSL_CTRL_MODE doesnt_exist +#define SSL_CTRL_NEED_TMP_RSA doesnt_exist +#define SSL_CTRL_OPTIONS doesnt_exist +#define SSL_CTRL_SESS_NUMBER doesnt_exist +#define SSL_CTRL_SET_CURVES doesnt_exist +#define SSL_CTRL_SET_CURVES_LIST doesnt_exist +#define SSL_CTRL_SET_ECDH_AUTO doesnt_exist +#define SSL_CTRL_SET_MAX_CERT_LIST doesnt_exist +#define SSL_CTRL_SET_MAX_SEND_FRAGMENT doesnt_exist +#define SSL_CTRL_SET_MSG_CALLBACK doesnt_exist +#define SSL_CTRL_SET_MSG_CALLBACK_ARG doesnt_exist +#define SSL_CTRL_SET_MTU doesnt_exist +#define SSL_CTRL_SET_READ_AHEAD doesnt_exist +#define SSL_CTRL_SET_SESS_CACHE_MODE doesnt_exist +#define SSL_CTRL_SET_SESS_CACHE_SIZE doesnt_exist +#define SSL_CTRL_SET_TLSEXT_HOSTNAME doesnt_exist +#define SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG doesnt_exist +#define SSL_CTRL_SET_TLSEXT_SERVERNAME_CB doesnt_exist +#define SSL_CTRL_SET_TLSEXT_TICKET_KEYS doesnt_exist +#define SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB doesnt_exist +#define SSL_CTRL_SET_TMP_DH doesnt_exist +#define SSL_CTRL_SET_TMP_DH_CB doesnt_exist +#define SSL_CTRL_SET_TMP_ECDH doesnt_exist +#define SSL_CTRL_SET_TMP_ECDH_CB doesnt_exist +#define SSL_CTRL_SET_TMP_RSA doesnt_exist +#define SSL_CTRL_SET_TMP_RSA_CB doesnt_exist + + + +#if defined(__cplusplus) +} // extern C + +#if !defined(BORINGSSL_NO_CXX) + +extern "C++" { + +namespace bssl { + +BORINGSSL_MAKE_DELETER(SSL, SSL_free) +BORINGSSL_MAKE_DELETER(SSL_CTX, SSL_CTX_free) +BORINGSSL_MAKE_DELETER(SSL_SESSION, SSL_SESSION_free) + +enum class OpenRecordResult { + kOK, + kDiscard, + kIncompleteRecord, + kAlertCloseNotify, + kError, +}; + +// *** EXPERIMENTAL -- DO NOT USE *** +// +// OpenRecord decrypts the first complete SSL record from |in| in-place, sets +// |out| to the decrypted application data, and |out_record_len| to the length +// of the encrypted record. Returns: +// - kOK if an application-data record was successfully decrypted and verified. +// - kDiscard if a record was sucessfully processed, but should be discarded. +// - kIncompleteRecord if |in| did not contain a complete record. +// - kAlertCloseNotify if a record was successfully processed but is a +// close_notify alert. +// - kError if an error occurred or the record is invalid. |*out_alert| will be +// set to an alert to emit, or zero if no alert should be emitted. +OPENSSL_EXPORT OpenRecordResult OpenRecord(SSL *ssl, Span *out, + size_t *out_record_len, + uint8_t *out_alert, + Span in); + +OPENSSL_EXPORT size_t SealRecordPrefixLen(const SSL *ssl, size_t plaintext_len); + +// SealRecordSuffixLen returns the length of the suffix written by |SealRecord|. +// +// |plaintext_len| must be equal to the size of the plaintext passed to +// |SealRecord|. +// +// |plaintext_len| must not exceed |SSL3_RT_MAX_PLAINTEXT_LENGTH|. The returned +// suffix length will not exceed |SSL3_RT_MAX_ENCRYPTED_OVERHEAD|. +OPENSSL_EXPORT size_t SealRecordSuffixLen(const SSL *ssl, size_t plaintext_len); + +// *** EXPERIMENTAL -- DO NOT USE *** +// +// SealRecord encrypts the cleartext of |in| and scatters the resulting TLS +// application data record between |out_prefix|, |out|, and |out_suffix|. It +// returns true on success or false if an error occurred. +// +// The length of |out_prefix| must equal |SealRecordPrefixLen|. The length of +// |out| must equal the length of |in|, which must not exceed +// |SSL3_RT_MAX_PLAINTEXT_LENGTH|. The length of |out_suffix| must equal +// |SealRecordSuffixLen|. +// +// If enabled, |SealRecord| may perform TLS 1.0 CBC 1/n-1 record splitting. +// |SealRecordPrefixLen| accounts for the required overhead if that is the case. +// +// |out| may equal |in| to encrypt in-place but may not otherwise alias. +// |out_prefix| and |out_suffix| may not alias anything. +OPENSSL_EXPORT bool SealRecord(SSL *ssl, Span out_prefix, + Span out, Span out_suffix, + Span in); + + +// *** EXPERIMENTAL — DO NOT USE WITHOUT CHECKING *** +// +// Split handshakes. +// +// Split handshakes allows the handshake part of a TLS connection to be +// performed in a different process (or on a different machine) than the data +// exchange. This only applies to servers. +// +// In the first part of a split handshake, an |SSL| (where the |SSL_CTX| has +// been configured with |SSL_CTX_set_handoff_mode|) is used normally. Once the +// ClientHello message has been received, the handshake will stop and +// |SSL_get_error| will indicate |SSL_ERROR_HANDOFF|. At this point (and only +// at this point), |SSL_serialize_handoff| can be called to write the “handoff” +// state of the connection. +// +// Elsewhere, a fresh |SSL| can be used with |SSL_apply_handoff| to continue +// the connection. The connection from the client is fed into this |SSL| until +// the handshake completes normally. At this point (and only at this point), +// |SSL_serialize_handback| can be called to serialize the result of the +// handshake. +// +// Back at the first location, a fresh |SSL| can be used with +// |SSL_apply_handback|. Then the client's connection can be processed mostly +// as normal. +// +// Lastly, when a connection is in the handoff state, whether or not +// |SSL_serialize_handoff| is called, |SSL_decline_handoff| will move it back +// into a normal state where the connection can procede without impact. +// +// WARNING: Currently only works with TLS 1.0–1.2. +// WARNING: The serialisation formats are not yet stable: version skew may be +// fatal. +// WARNING: The handback data contains sensitive key material and must be +// protected. +// WARNING: Some calls on the final |SSL| will not work. Just as an example, +// calls like |SSL_get0_session_id_context| and |SSL_get_privatekey| won't +// work because the certificate used for handshaking isn't available. +// WARNING: |SSL_apply_handoff| may trigger “msg” callback calls. + +OPENSSL_EXPORT void SSL_CTX_set_handoff_mode(SSL_CTX *ctx, bool on); +OPENSSL_EXPORT bool SSL_serialize_handoff(const SSL *ssl, CBB *out); +OPENSSL_EXPORT bool SSL_decline_handoff(SSL *ssl); +OPENSSL_EXPORT bool SSL_apply_handoff(SSL *ssl, Span handoff); +OPENSSL_EXPORT bool SSL_serialize_handback(const SSL *ssl, CBB *out); +OPENSSL_EXPORT bool SSL_apply_handback(SSL *ssl, Span handback); + +} // namespace bssl + +} // extern C++ + +#endif // !defined(BORINGSSL_NO_CXX) + +#endif + +#define SSL_R_APP_DATA_IN_HANDSHAKE 100 +#define SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT 101 +#define SSL_R_BAD_ALERT 102 +#define SSL_R_BAD_CHANGE_CIPHER_SPEC 103 +#define SSL_R_BAD_DATA_RETURNED_BY_CALLBACK 104 +#define SSL_R_BAD_DH_P_LENGTH 105 +#define SSL_R_BAD_DIGEST_LENGTH 106 +#define SSL_R_BAD_ECC_CERT 107 +#define SSL_R_BAD_ECPOINT 108 +#define SSL_R_BAD_HANDSHAKE_RECORD 109 +#define SSL_R_BAD_HELLO_REQUEST 110 +#define SSL_R_BAD_LENGTH 111 +#define SSL_R_BAD_PACKET_LENGTH 112 +#define SSL_R_BAD_RSA_ENCRYPT 113 +#define SSL_R_BAD_SIGNATURE 114 +#define SSL_R_BAD_SRTP_MKI_VALUE 115 +#define SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST 116 +#define SSL_R_BAD_SSL_FILETYPE 117 +#define SSL_R_BAD_WRITE_RETRY 118 +#define SSL_R_BIO_NOT_SET 119 +#define SSL_R_BN_LIB 120 +#define SSL_R_BUFFER_TOO_SMALL 121 +#define SSL_R_CA_DN_LENGTH_MISMATCH 122 +#define SSL_R_CA_DN_TOO_LONG 123 +#define SSL_R_CCS_RECEIVED_EARLY 124 +#define SSL_R_CERTIFICATE_VERIFY_FAILED 125 +#define SSL_R_CERT_CB_ERROR 126 +#define SSL_R_CERT_LENGTH_MISMATCH 127 +#define SSL_R_CHANNEL_ID_NOT_P256 128 +#define SSL_R_CHANNEL_ID_SIGNATURE_INVALID 129 +#define SSL_R_CIPHER_OR_HASH_UNAVAILABLE 130 +#define SSL_R_CLIENTHELLO_PARSE_FAILED 131 +#define SSL_R_CLIENTHELLO_TLSEXT 132 +#define SSL_R_CONNECTION_REJECTED 133 +#define SSL_R_CONNECTION_TYPE_NOT_SET 134 +#define SSL_R_CUSTOM_EXTENSION_ERROR 135 +#define SSL_R_DATA_LENGTH_TOO_LONG 136 +#define SSL_R_DECODE_ERROR 137 +#define SSL_R_DECRYPTION_FAILED 138 +#define SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC 139 +#define SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG 140 +#define SSL_R_DH_P_TOO_LONG 141 +#define SSL_R_DIGEST_CHECK_FAILED 142 +#define SSL_R_DTLS_MESSAGE_TOO_BIG 143 +#define SSL_R_ECC_CERT_NOT_FOR_SIGNING 144 +#define SSL_R_EMS_STATE_INCONSISTENT 145 +#define SSL_R_ENCRYPTED_LENGTH_TOO_LONG 146 +#define SSL_R_ERROR_ADDING_EXTENSION 147 +#define SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST 148 +#define SSL_R_ERROR_PARSING_EXTENSION 149 +#define SSL_R_EXCESSIVE_MESSAGE_SIZE 150 +#define SSL_R_EXTRA_DATA_IN_MESSAGE 151 +#define SSL_R_FRAGMENT_MISMATCH 152 +#define SSL_R_GOT_NEXT_PROTO_WITHOUT_EXTENSION 153 +#define SSL_R_HANDSHAKE_FAILURE_ON_CLIENT_HELLO 154 +#define SSL_R_HTTPS_PROXY_REQUEST 155 +#define SSL_R_HTTP_REQUEST 156 +#define SSL_R_INAPPROPRIATE_FALLBACK 157 +#define SSL_R_INVALID_COMMAND 158 +#define SSL_R_INVALID_MESSAGE 159 +#define SSL_R_INVALID_SSL_SESSION 160 +#define SSL_R_INVALID_TICKET_KEYS_LENGTH 161 +#define SSL_R_LENGTH_MISMATCH 162 +#define SSL_R_MISSING_EXTENSION 164 +#define SSL_R_MISSING_RSA_CERTIFICATE 165 +#define SSL_R_MISSING_TMP_DH_KEY 166 +#define SSL_R_MISSING_TMP_ECDH_KEY 167 +#define SSL_R_MIXED_SPECIAL_OPERATOR_WITH_GROUPS 168 +#define SSL_R_MTU_TOO_SMALL 169 +#define SSL_R_NEGOTIATED_BOTH_NPN_AND_ALPN 170 +#define SSL_R_NESTED_GROUP 171 +#define SSL_R_NO_CERTIFICATES_RETURNED 172 +#define SSL_R_NO_CERTIFICATE_ASSIGNED 173 +#define SSL_R_NO_CERTIFICATE_SET 174 +#define SSL_R_NO_CIPHERS_AVAILABLE 175 +#define SSL_R_NO_CIPHERS_PASSED 176 +#define SSL_R_NO_CIPHER_MATCH 177 +#define SSL_R_NO_COMPRESSION_SPECIFIED 178 +#define SSL_R_NO_METHOD_SPECIFIED 179 +#define SSL_R_NO_P256_SUPPORT 180 +#define SSL_R_NO_PRIVATE_KEY_ASSIGNED 181 +#define SSL_R_NO_RENEGOTIATION 182 +#define SSL_R_NO_REQUIRED_DIGEST 183 +#define SSL_R_NO_SHARED_CIPHER 184 +#define SSL_R_NULL_SSL_CTX 185 +#define SSL_R_NULL_SSL_METHOD_PASSED 186 +#define SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED 187 +#define SSL_R_OLD_SESSION_VERSION_NOT_RETURNED 188 +#define SSL_R_OUTPUT_ALIASES_INPUT 189 +#define SSL_R_PARSE_TLSEXT 190 +#define SSL_R_PATH_TOO_LONG 191 +#define SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE 192 +#define SSL_R_PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE 193 +#define SSL_R_PROTOCOL_IS_SHUTDOWN 194 +#define SSL_R_PSK_IDENTITY_NOT_FOUND 195 +#define SSL_R_PSK_NO_CLIENT_CB 196 +#define SSL_R_PSK_NO_SERVER_CB 197 +#define SSL_R_READ_TIMEOUT_EXPIRED 198 +#define SSL_R_RECORD_LENGTH_MISMATCH 199 +#define SSL_R_RECORD_TOO_LARGE 200 +#define SSL_R_RENEGOTIATION_ENCODING_ERR 201 +#define SSL_R_RENEGOTIATION_MISMATCH 202 +#define SSL_R_REQUIRED_CIPHER_MISSING 203 +#define SSL_R_RESUMED_EMS_SESSION_WITHOUT_EMS_EXTENSION 204 +#define SSL_R_RESUMED_NON_EMS_SESSION_WITH_EMS_EXTENSION 205 +#define SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING 206 +#define SSL_R_SERVERHELLO_TLSEXT 207 +#define SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED 208 +#define SSL_R_SESSION_MAY_NOT_BE_CREATED 209 +#define SSL_R_SIGNATURE_ALGORITHMS_EXTENSION_SENT_BY_SERVER 210 +#define SSL_R_SRTP_COULD_NOT_ALLOCATE_PROFILES 211 +#define SSL_R_SRTP_UNKNOWN_PROTECTION_PROFILE 212 +#define SSL_R_SSL3_EXT_INVALID_SERVERNAME 213 +#define SSL_R_SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION 214 +#define SSL_R_SSL_HANDSHAKE_FAILURE 215 +#define SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG 216 +#define SSL_R_TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST 217 +#define SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG 218 +#define SSL_R_TOO_MANY_EMPTY_FRAGMENTS 219 +#define SSL_R_TOO_MANY_WARNING_ALERTS 220 +#define SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS 221 +#define SSL_R_UNEXPECTED_EXTENSION 222 +#define SSL_R_UNEXPECTED_MESSAGE 223 +#define SSL_R_UNEXPECTED_OPERATOR_IN_GROUP 224 +#define SSL_R_UNEXPECTED_RECORD 225 +#define SSL_R_UNINITIALIZED 226 +#define SSL_R_UNKNOWN_ALERT_TYPE 227 +#define SSL_R_UNKNOWN_CERTIFICATE_TYPE 228 +#define SSL_R_UNKNOWN_CIPHER_RETURNED 229 +#define SSL_R_UNKNOWN_CIPHER_TYPE 230 +#define SSL_R_UNKNOWN_DIGEST 231 +#define SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE 232 +#define SSL_R_UNKNOWN_PROTOCOL 233 +#define SSL_R_UNKNOWN_SSL_VERSION 234 +#define SSL_R_UNKNOWN_STATE 235 +#define SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED 236 +#define SSL_R_UNSUPPORTED_CIPHER 237 +#define SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM 238 +#define SSL_R_UNSUPPORTED_ELLIPTIC_CURVE 239 +#define SSL_R_UNSUPPORTED_PROTOCOL 240 +#define SSL_R_WRONG_CERTIFICATE_TYPE 241 +#define SSL_R_WRONG_CIPHER_RETURNED 242 +#define SSL_R_WRONG_CURVE 243 +#define SSL_R_WRONG_MESSAGE_TYPE 244 +#define SSL_R_WRONG_SIGNATURE_TYPE 245 +#define SSL_R_WRONG_SSL_VERSION 246 +#define SSL_R_WRONG_VERSION_NUMBER 247 +#define SSL_R_X509_LIB 248 +#define SSL_R_X509_VERIFICATION_SETUP_PROBLEMS 249 +#define SSL_R_SHUTDOWN_WHILE_IN_INIT 250 +#define SSL_R_INVALID_OUTER_RECORD_TYPE 251 +#define SSL_R_UNSUPPORTED_PROTOCOL_FOR_CUSTOM_KEY 252 +#define SSL_R_NO_COMMON_SIGNATURE_ALGORITHMS 253 +#define SSL_R_DOWNGRADE_DETECTED 254 +#define SSL_R_BUFFERED_MESSAGES_ON_CIPHER_CHANGE 255 +#define SSL_R_INVALID_COMPRESSION_LIST 256 +#define SSL_R_DUPLICATE_EXTENSION 257 +#define SSL_R_MISSING_KEY_SHARE 258 +#define SSL_R_INVALID_ALPN_PROTOCOL 259 +#define SSL_R_TOO_MANY_KEY_UPDATES 260 +#define SSL_R_BLOCK_CIPHER_PAD_IS_WRONG 261 +#define SSL_R_NO_CIPHERS_SPECIFIED 262 +#define SSL_R_RENEGOTIATION_EMS_MISMATCH 263 +#define SSL_R_DUPLICATE_KEY_SHARE 264 +#define SSL_R_NO_GROUPS_SPECIFIED 265 +#define SSL_R_NO_SHARED_GROUP 266 +#define SSL_R_PRE_SHARED_KEY_MUST_BE_LAST 267 +#define SSL_R_OLD_SESSION_PRF_HASH_MISMATCH 268 +#define SSL_R_INVALID_SCT_LIST 269 +#define SSL_R_TOO_MUCH_SKIPPED_EARLY_DATA 270 +#define SSL_R_PSK_IDENTITY_BINDER_COUNT_MISMATCH 271 +#define SSL_R_CANNOT_PARSE_LEAF_CERT 272 +#define SSL_R_SERVER_CERT_CHANGED 273 +#define SSL_R_CERTIFICATE_AND_PRIVATE_KEY_MISMATCH 274 +#define SSL_R_CANNOT_HAVE_BOTH_PRIVKEY_AND_METHOD 275 +#define SSL_R_TICKET_ENCRYPTION_FAILED 276 +#define SSL_R_ALPN_MISMATCH_ON_EARLY_DATA 277 +#define SSL_R_WRONG_VERSION_ON_EARLY_DATA 278 +#define SSL_R_UNEXPECTED_EXTENSION_ON_EARLY_DATA 279 +#define SSL_R_NO_SUPPORTED_VERSIONS_ENABLED 280 +#define SSL_R_APPLICATION_DATA_INSTEAD_OF_HANDSHAKE 281 +#define SSL_R_EMPTY_HELLO_RETRY_REQUEST 282 +#define SSL_R_EARLY_DATA_NOT_IN_USE 283 +#define SSL_R_HANDSHAKE_NOT_COMPLETE 284 +#define SSL_R_NEGOTIATED_TB_WITHOUT_EMS_OR_RI 285 +#define SSL_R_SERVER_ECHOED_INVALID_SESSION_ID 286 +#define SSL_R_PRIVATE_KEY_OPERATION_FAILED 287 +#define SSL_R_SSLV3_ALERT_CLOSE_NOTIFY 1000 +#define SSL_R_SSLV3_ALERT_UNEXPECTED_MESSAGE 1010 +#define SSL_R_SSLV3_ALERT_BAD_RECORD_MAC 1020 +#define SSL_R_TLSV1_ALERT_DECRYPTION_FAILED 1021 +#define SSL_R_TLSV1_ALERT_RECORD_OVERFLOW 1022 +#define SSL_R_SSLV3_ALERT_DECOMPRESSION_FAILURE 1030 +#define SSL_R_SSLV3_ALERT_HANDSHAKE_FAILURE 1040 +#define SSL_R_SSLV3_ALERT_NO_CERTIFICATE 1041 +#define SSL_R_SSLV3_ALERT_BAD_CERTIFICATE 1042 +#define SSL_R_SSLV3_ALERT_UNSUPPORTED_CERTIFICATE 1043 +#define SSL_R_SSLV3_ALERT_CERTIFICATE_REVOKED 1044 +#define SSL_R_SSLV3_ALERT_CERTIFICATE_EXPIRED 1045 +#define SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN 1046 +#define SSL_R_SSLV3_ALERT_ILLEGAL_PARAMETER 1047 +#define SSL_R_TLSV1_ALERT_UNKNOWN_CA 1048 +#define SSL_R_TLSV1_ALERT_ACCESS_DENIED 1049 +#define SSL_R_TLSV1_ALERT_DECODE_ERROR 1050 +#define SSL_R_TLSV1_ALERT_DECRYPT_ERROR 1051 +#define SSL_R_TLSV1_ALERT_EXPORT_RESTRICTION 1060 +#define SSL_R_TLSV1_ALERT_PROTOCOL_VERSION 1070 +#define SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY 1071 +#define SSL_R_TLSV1_ALERT_INTERNAL_ERROR 1080 +#define SSL_R_TLSV1_ALERT_INAPPROPRIATE_FALLBACK 1086 +#define SSL_R_TLSV1_ALERT_USER_CANCELLED 1090 +#define SSL_R_TLSV1_ALERT_NO_RENEGOTIATION 1100 +#define SSL_R_TLSV1_UNSUPPORTED_EXTENSION 1110 +#define SSL_R_TLSV1_CERTIFICATE_UNOBTAINABLE 1111 +#define SSL_R_TLSV1_UNRECOGNIZED_NAME 1112 +#define SSL_R_TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE 1113 +#define SSL_R_TLSV1_BAD_CERTIFICATE_HASH_VALUE 1114 +#define SSL_R_TLSV1_UNKNOWN_PSK_IDENTITY 1115 +#define SSL_R_TLSV1_CERTIFICATE_REQUIRED 1116 +#define SSL_R_TOO_MUCH_READ_EARLY_DATA 1117 + +#endif // OPENSSL_HEADER_SSL_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/ssl.h.back b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/ssl.h.back new file mode 100644 index 0000000..902d41d --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/ssl.h.back @@ -0,0 +1,4676 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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. + */ +/* ==================================================================== + * 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 OPENSSL_HEADER_SSL_H +#define OPENSSL_HEADER_SSL_H + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#if !defined(OPENSSL_WINDOWS) +#include +#endif + +// NGINX needs this #include. Consider revisiting this after NGINX 1.14.0 has +// been out for a year or so (assuming that they fix it in that release.) See +// https://boringssl-review.googlesource.com/c/boringssl/+/21664. +#include + +// Forward-declare struct timeval. On Windows, it is defined in winsock2.h and +// Windows headers define too many macros to be included in public headers. +// However, only a forward declaration is needed. +struct timeval; + +#if defined(__cplusplus) +extern "C" { +#endif + + +// SSL implementation. + + +// SSL contexts. +// +// |SSL_CTX| objects manage shared state and configuration between multiple TLS +// or DTLS connections. Whether the connections are TLS or DTLS is selected by +// an |SSL_METHOD| on creation. +// +// |SSL_CTX| are reference-counted and may be shared by connections across +// multiple threads. Once shared, functions which change the |SSL_CTX|'s +// configuration may not be used. + +// TLS_method is the |SSL_METHOD| used for TLS (and SSLv3) connections. +OPENSSL_EXPORT const SSL_METHOD *TLS_method(void); + +// DTLS_method is the |SSL_METHOD| used for DTLS connections. +OPENSSL_EXPORT const SSL_METHOD *DTLS_method(void); + +// TLS_with_buffers_method is like |TLS_method|, but avoids all use of +// crypto/x509. All client connections created with |TLS_with_buffers_method| +// will fail unless a certificate verifier is installed with +// |SSL_set_custom_verify| or |SSL_CTX_set_custom_verify|. +OPENSSL_EXPORT const SSL_METHOD *TLS_with_buffers_method(void); + +// DTLS_with_buffers_method is like |DTLS_method|, but avoids all use of +// crypto/x509. +OPENSSL_EXPORT const SSL_METHOD *DTLS_with_buffers_method(void); + +// SSL_CTX_new returns a newly-allocated |SSL_CTX| with default settings or NULL +// on error. +OPENSSL_EXPORT SSL_CTX *SSL_CTX_new(const SSL_METHOD *method); + +// SSL_CTX_up_ref increments the reference count of |ctx|. It returns one. +OPENSSL_EXPORT int SSL_CTX_up_ref(SSL_CTX *ctx); + +// SSL_CTX_free releases memory associated with |ctx|. +OPENSSL_EXPORT void SSL_CTX_free(SSL_CTX *ctx); + + +// SSL connections. +// +// An |SSL| object represents a single TLS or DTLS connection. Although the +// shared |SSL_CTX| is thread-safe, an |SSL| is not thread-safe and may only be +// used on one thread at a time. + +// SSL_new returns a newly-allocated |SSL| using |ctx| or NULL on error. The new +// connection inherits settings from |ctx| at the time of creation. Settings may +// also be individually configured on the connection. +// +// On creation, an |SSL| is not configured to be either a client or server. Call +// |SSL_set_connect_state| or |SSL_set_accept_state| to set this. +OPENSSL_EXPORT SSL *SSL_new(SSL_CTX *ctx); + +// SSL_free releases memory associated with |ssl|. +OPENSSL_EXPORT void SSL_free(SSL *ssl); + +// SSL_get_SSL_CTX returns the |SSL_CTX| associated with |ssl|. If +// |SSL_set_SSL_CTX| is called, it returns the new |SSL_CTX|, not the initial +// one. +OPENSSL_EXPORT SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl); + +// SSL_set_connect_state configures |ssl| to be a client. +OPENSSL_EXPORT void SSL_set_connect_state(SSL *ssl); + +// SSL_set_accept_state configures |ssl| to be a server. +OPENSSL_EXPORT void SSL_set_accept_state(SSL *ssl); + +// SSL_is_server returns one if |ssl| is configured as a server and zero +// otherwise. +OPENSSL_EXPORT int SSL_is_server(const SSL *ssl); + +// SSL_is_dtls returns one if |ssl| is a DTLS connection and zero otherwise. +OPENSSL_EXPORT int SSL_is_dtls(const SSL *ssl); + +// SSL_set_bio configures |ssl| to read from |rbio| and write to |wbio|. |ssl| +// takes ownership of the two |BIO|s. If |rbio| and |wbio| are the same, |ssl| +// only takes ownership of one reference. +// +// In DTLS, |rbio| must be non-blocking to properly handle timeouts and +// retransmits. +// +// If |rbio| is the same as the currently configured |BIO| for reading, that +// side is left untouched and is not freed. +// +// If |wbio| is the same as the currently configured |BIO| for writing AND |ssl| +// is not currently configured to read from and write to the same |BIO|, that +// side is left untouched and is not freed. This asymmetry is present for +// historical reasons. +// +// Due to the very complex historical behavior of this function, calling this +// function if |ssl| already has |BIO|s configured is deprecated. Prefer +// |SSL_set0_rbio| and |SSL_set0_wbio| instead. +OPENSSL_EXPORT void SSL_set_bio(SSL *ssl, BIO *rbio, BIO *wbio); + +// SSL_set0_rbio configures |ssl| to write to |rbio|. It takes ownership of +// |rbio|. +// +// Note that, although this function and |SSL_set0_wbio| may be called on the +// same |BIO|, each call takes a reference. Use |BIO_up_ref| to balance this. +OPENSSL_EXPORT void SSL_set0_rbio(SSL *ssl, BIO *rbio); + +// SSL_set0_wbio configures |ssl| to write to |wbio|. It takes ownership of +// |wbio|. +// +// Note that, although this function and |SSL_set0_rbio| may be called on the +// same |BIO|, each call takes a reference. Use |BIO_up_ref| to balance this. +OPENSSL_EXPORT void SSL_set0_wbio(SSL *ssl, BIO *wbio); + +// SSL_get_rbio returns the |BIO| that |ssl| reads from. +OPENSSL_EXPORT BIO *SSL_get_rbio(const SSL *ssl); + +// SSL_get_wbio returns the |BIO| that |ssl| writes to. +OPENSSL_EXPORT BIO *SSL_get_wbio(const SSL *ssl); + +// SSL_get_fd calls |SSL_get_rfd|. +OPENSSL_EXPORT int SSL_get_fd(const SSL *ssl); + +// SSL_get_rfd returns the file descriptor that |ssl| is configured to read +// from. If |ssl|'s read |BIO| is not configured or doesn't wrap a file +// descriptor then it returns -1. +// +// Note: On Windows, this may return either a file descriptor or a socket (cast +// to int), depending on whether |ssl| was configured with a file descriptor or +// socket |BIO|. +OPENSSL_EXPORT int SSL_get_rfd(const SSL *ssl); + +// SSL_get_wfd returns the file descriptor that |ssl| is configured to write +// to. If |ssl|'s write |BIO| is not configured or doesn't wrap a file +// descriptor then it returns -1. +// +// Note: On Windows, this may return either a file descriptor or a socket (cast +// to int), depending on whether |ssl| was configured with a file descriptor or +// socket |BIO|. +OPENSSL_EXPORT int SSL_get_wfd(const SSL *ssl); + +// SSL_set_fd configures |ssl| to read from and write to |fd|. It returns one +// on success and zero on allocation error. The caller retains ownership of +// |fd|. +// +// On Windows, |fd| is cast to a |SOCKET| and used with Winsock APIs. +OPENSSL_EXPORT int SSL_set_fd(SSL *ssl, int fd); + +// SSL_set_rfd configures |ssl| to read from |fd|. It returns one on success and +// zero on allocation error. The caller retains ownership of |fd|. +// +// On Windows, |fd| is cast to a |SOCKET| and used with Winsock APIs. +OPENSSL_EXPORT int SSL_set_rfd(SSL *ssl, int fd); + +// SSL_set_wfd configures |ssl| to write to |fd|. It returns one on success and +// zero on allocation error. The caller retains ownership of |fd|. +// +// On Windows, |fd| is cast to a |SOCKET| and used with Winsock APIs. +OPENSSL_EXPORT int SSL_set_wfd(SSL *ssl, int fd); + +// SSL_do_handshake continues the current handshake. If there is none or the +// handshake has completed or False Started, it returns one. Otherwise, it +// returns <= 0. The caller should pass the value into |SSL_get_error| to +// determine how to proceed. +// +// In DTLS, the caller must drive retransmissions. Whenever |SSL_get_error| +// signals |SSL_ERROR_WANT_READ|, use |DTLSv1_get_timeout| to determine the +// current timeout. If it expires before the next retry, call +// |DTLSv1_handle_timeout|. Note that DTLS handshake retransmissions use fresh +// sequence numbers, so it is not sufficient to replay packets at the transport. +// +// TODO(davidben): Ensure 0 is only returned on transport EOF. +// https://crbug.com/466303. +OPENSSL_EXPORT int SSL_do_handshake(SSL *ssl); + +// SSL_connect configures |ssl| as a client, if unconfigured, and calls +// |SSL_do_handshake|. +OPENSSL_EXPORT int SSL_connect(SSL *ssl); + +// SSL_accept configures |ssl| as a server, if unconfigured, and calls +// |SSL_do_handshake|. +OPENSSL_EXPORT int SSL_accept(SSL *ssl); + +// SSL_read reads up to |num| bytes from |ssl| into |buf|. It implicitly runs +// any pending handshakes, including renegotiations when enabled. On success, it +// returns the number of bytes read. Otherwise, it returns <= 0. The caller +// should pass the value into |SSL_get_error| to determine how to proceed. +// +// TODO(davidben): Ensure 0 is only returned on transport EOF. +// https://crbug.com/466303. +OPENSSL_EXPORT int SSL_read(SSL *ssl, void *buf, int num); + +// SSL_peek behaves like |SSL_read| but does not consume any bytes returned. +OPENSSL_EXPORT int SSL_peek(SSL *ssl, void *buf, int num); + +// SSL_pending returns the number of bytes available in |ssl|. It does not read +// from the transport. +OPENSSL_EXPORT int SSL_pending(const SSL *ssl); + +// SSL_write writes up to |num| bytes from |buf| into |ssl|. It implicitly runs +// any pending handshakes, including renegotiations when enabled. On success, it +// returns the number of bytes written. Otherwise, it returns <= 0. The caller +// should pass the value into |SSL_get_error| to determine how to proceed. +// +// In TLS, a non-blocking |SSL_write| differs from non-blocking |write| in that +// a failed |SSL_write| still commits to the data passed in. When retrying, the +// caller must supply the original write buffer (or a larger one containing the +// original as a prefix). By default, retries will fail if they also do not +// reuse the same |buf| pointer. This may be relaxed with +// |SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER|, but the buffer contents still must be +// unchanged. +// +// By default, in TLS, |SSL_write| will not return success until all |num| bytes +// are written. This may be relaxed with |SSL_MODE_ENABLE_PARTIAL_WRITE|. It +// allows |SSL_write| to complete with a partial result when only part of the +// input was written in a single record. +// +// In DTLS, neither |SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER| and +// |SSL_MODE_ENABLE_PARTIAL_WRITE| do anything. The caller may retry with a +// different buffer freely. A single call to |SSL_write| only ever writes a +// single record in a single packet, so |num| must be at most +// |SSL3_RT_MAX_PLAIN_LENGTH|. +// +// TODO(davidben): Ensure 0 is only returned on transport EOF. +// https://crbug.com/466303. +OPENSSL_EXPORT int SSL_write(SSL *ssl, const void *buf, int num); + +// SSL_shutdown shuts down |ssl|. On success, it completes in two stages. First, +// it returns 0 if |ssl| completed uni-directional shutdown; close_notify has +// been sent, but the peer's close_notify has not been received. Most callers +// may stop at this point. For bi-directional shutdown, call |SSL_shutdown| +// again. It returns 1 if close_notify has been both sent and received. +// +// If the peer's close_notify arrived first, the first stage is skipped. +// |SSL_shutdown| will return 1 once close_notify is sent and skip 0. Callers +// only interested in uni-directional shutdown must therefore allow for the +// first stage returning either 0 or 1. +// +// |SSL_shutdown| returns -1 on failure. The caller should pass the return value +// into |SSL_get_error| to determine how to proceed. If the underlying |BIO| is +// non-blocking, both stages may require retry. +OPENSSL_EXPORT int SSL_shutdown(SSL *ssl); + +// SSL_CTX_set_quiet_shutdown sets quiet shutdown on |ctx| to |mode|. If +// enabled, |SSL_shutdown| will not send a close_notify alert or wait for one +// from the peer. It will instead synchronously return one. +OPENSSL_EXPORT void SSL_CTX_set_quiet_shutdown(SSL_CTX *ctx, int mode); + +// SSL_CTX_get_quiet_shutdown returns whether quiet shutdown is enabled for +// |ctx|. +OPENSSL_EXPORT int SSL_CTX_get_quiet_shutdown(const SSL_CTX *ctx); + +// SSL_set_quiet_shutdown sets quiet shutdown on |ssl| to |mode|. If enabled, +// |SSL_shutdown| will not send a close_notify alert or wait for one from the +// peer. It will instead synchronously return one. +OPENSSL_EXPORT void SSL_set_quiet_shutdown(SSL *ssl, int mode); + +// SSL_get_quiet_shutdown returns whether quiet shutdown is enabled for +// |ssl|. +OPENSSL_EXPORT int SSL_get_quiet_shutdown(const SSL *ssl); + +// SSL_get_error returns a |SSL_ERROR_*| value for the most recent operation on +// |ssl|. It should be called after an operation failed to determine whether the +// error was fatal and, if not, when to retry. +OPENSSL_EXPORT int SSL_get_error(const SSL *ssl, int ret_code); + +// SSL_ERROR_NONE indicates the operation succeeded. +#define SSL_ERROR_NONE 0 + +// SSL_ERROR_SSL indicates the operation failed within the library. The caller +// may inspect the error queue for more information. +#define SSL_ERROR_SSL 1 + +// SSL_ERROR_WANT_READ indicates the operation failed attempting to read from +// the transport. The caller may retry the operation when the transport is ready +// for reading. +// +// If signaled by a DTLS handshake, the caller must also call +// |DTLSv1_get_timeout| and |DTLSv1_handle_timeout| as appropriate. See +// |SSL_do_handshake|. +#define SSL_ERROR_WANT_READ 2 + +// SSL_ERROR_WANT_WRITE indicates the operation failed attempting to write to +// the transport. The caller may retry the operation when the transport is ready +// for writing. +#define SSL_ERROR_WANT_WRITE 3 + +// SSL_ERROR_WANT_X509_LOOKUP indicates the operation failed in calling the +// |cert_cb| or |client_cert_cb|. The caller may retry the operation when the +// callback is ready to return a certificate or one has been configured +// externally. +// +// See also |SSL_CTX_set_cert_cb| and |SSL_CTX_set_client_cert_cb|. +#define SSL_ERROR_WANT_X509_LOOKUP 4 + +// SSL_ERROR_SYSCALL indicates the operation failed externally to the library. +// The caller should consult the system-specific error mechanism. This is +// typically |errno| but may be something custom if using a custom |BIO|. It +// may also be signaled if the transport returned EOF, in which case the +// operation's return value will be zero. +#define SSL_ERROR_SYSCALL 5 + +// SSL_ERROR_ZERO_RETURN indicates the operation failed because the connection +// was cleanly shut down with a close_notify alert. +#define SSL_ERROR_ZERO_RETURN 6 + +// SSL_ERROR_WANT_CONNECT indicates the operation failed attempting to connect +// the transport (the |BIO| signaled |BIO_RR_CONNECT|). The caller may retry the +// operation when the transport is ready. +#define SSL_ERROR_WANT_CONNECT 7 + +// SSL_ERROR_WANT_ACCEPT indicates the operation failed attempting to accept a +// connection from the transport (the |BIO| signaled |BIO_RR_ACCEPT|). The +// caller may retry the operation when the transport is ready. +// +// TODO(davidben): Remove this. It's used by accept BIOs which are bizarre. +#define SSL_ERROR_WANT_ACCEPT 8 + +// SSL_ERROR_WANT_CHANNEL_ID_LOOKUP indicates the operation failed looking up +// the Channel ID key. The caller may retry the operation when |channel_id_cb| +// is ready to return a key or one has been configured with +// |SSL_set1_tls_channel_id|. +// +// See also |SSL_CTX_set_channel_id_cb|. +#define SSL_ERROR_WANT_CHANNEL_ID_LOOKUP 9 + +// SSL_ERROR_PENDING_SESSION indicates the operation failed because the session +// lookup callback indicated the session was unavailable. The caller may retry +// the operation when lookup has completed. +// +// See also |SSL_CTX_sess_set_get_cb| and |SSL_magic_pending_session_ptr|. +#define SSL_ERROR_PENDING_SESSION 11 + +// SSL_ERROR_PENDING_CERTIFICATE indicates the operation failed because the +// early callback indicated certificate lookup was incomplete. The caller may +// retry the operation when lookup has completed. +// +// See also |SSL_CTX_set_select_certificate_cb|. +#define SSL_ERROR_PENDING_CERTIFICATE 12 + +// SSL_ERROR_WANT_PRIVATE_KEY_OPERATION indicates the operation failed because +// a private key operation was unfinished. The caller may retry the operation +// when the private key operation is complete. +// +// See also |SSL_set_private_key_method| and +// |SSL_CTX_set_private_key_method|. +#define SSL_ERROR_WANT_PRIVATE_KEY_OPERATION 13 + +// SSL_ERROR_PENDING_TICKET indicates that a ticket decryption is pending. The +// caller may retry the operation when the decryption is ready. +// +// See also |SSL_CTX_set_ticket_aead_method|. +#define SSL_ERROR_PENDING_TICKET 14 + +// SSL_ERROR_EARLY_DATA_REJECTED indicates that early data was rejected. The +// caller should treat this as a connection failure and retry any operations +// associated with the rejected early data. |SSL_reset_early_data_reject| may be +// used to reuse the underlying connection for the retry. +#define SSL_ERROR_EARLY_DATA_REJECTED 15 + +// SSL_ERROR_WANT_CERTIFICATE_VERIFY indicates the operation failed because +// certificate verification was incomplete. The caller may retry the operation +// when certificate verification is complete. +// +// See also |SSL_CTX_set_custom_verify|. +#define SSL_ERROR_WANT_CERTIFICATE_VERIFY 16 + +#define SSL_ERROR_HANDOFF 17 + +// SSL_set_mtu sets the |ssl|'s MTU in DTLS to |mtu|. It returns one on success +// and zero on failure. +OPENSSL_EXPORT int SSL_set_mtu(SSL *ssl, unsigned mtu); + +// DTLSv1_set_initial_timeout_duration sets the initial duration for a DTLS +// handshake timeout. +// +// This duration overrides the default of 1 second, which is the strong +// recommendation of RFC 6347 (see section 4.2.4.1). However, there may exist +// situations where a shorter timeout would be beneficial, such as for +// time-sensitive applications. +OPENSSL_EXPORT void DTLSv1_set_initial_timeout_duration(SSL *ssl, + unsigned duration_ms); + +// DTLSv1_get_timeout queries the next DTLS handshake timeout. If there is a +// timeout in progress, it sets |*out| to the time remaining and returns one. +// Otherwise, it returns zero. +// +// When the timeout expires, call |DTLSv1_handle_timeout| to handle the +// retransmit behavior. +// +// NOTE: This function must be queried again whenever the handshake state +// machine changes, including when |DTLSv1_handle_timeout| is called. +OPENSSL_EXPORT int DTLSv1_get_timeout(const SSL *ssl, struct timeval *out); + +// DTLSv1_handle_timeout is called when a DTLS handshake timeout expires. If no +// timeout had expired, it returns 0. Otherwise, it retransmits the previous +// flight of handshake messages and returns 1. If too many timeouts had expired +// without progress or an error occurs, it returns -1. +// +// The caller's external timer should be compatible with the one |ssl| queries +// within some fudge factor. Otherwise, the call will be a no-op, but +// |DTLSv1_get_timeout| will return an updated timeout. +// +// If the function returns -1, checking if |SSL_get_error| returns +// |SSL_ERROR_WANT_WRITE| may be used to determine if the retransmit failed due +// to a non-fatal error at the write |BIO|. However, the operation may not be +// retried until the next timeout fires. +// +// WARNING: This function breaks the usual return value convention. +// +// TODO(davidben): This |SSL_ERROR_WANT_WRITE| behavior is kind of bizarre. +OPENSSL_EXPORT int DTLSv1_handle_timeout(SSL *ssl); + + +// Protocol versions. + +#define DTLS1_VERSION_MAJOR 0xfe +#define SSL3_VERSION_MAJOR 0x03 + +#define SSL3_VERSION 0x0300 +#define TLS1_VERSION 0x0301 +#define TLS1_1_VERSION 0x0302 +#define TLS1_2_VERSION 0x0303 +#define TLS1_3_VERSION 0x0304 + +#define DTLS1_VERSION 0xfeff +#define DTLS1_2_VERSION 0xfefd + +#define TLS1_3_DRAFT23_VERSION 0x7f17 + +// SSL_CTX_set_min_proto_version sets the minimum protocol version for |ctx| to +// |version|. If |version| is zero, the default minimum version is used. It +// returns one on success and zero if |version| is invalid. +OPENSSL_EXPORT int SSL_CTX_set_min_proto_version(SSL_CTX *ctx, + uint16_t version); + +// SSL_CTX_set_max_proto_version sets the maximum protocol version for |ctx| to +// |version|. If |version| is zero, the default maximum version is used. It +// returns one on success and zero if |version| is invalid. +OPENSSL_EXPORT int SSL_CTX_set_max_proto_version(SSL_CTX *ctx, + uint16_t version); + +// SSL_set_min_proto_version sets the minimum protocol version for |ssl| to +// |version|. If |version| is zero, the default minimum version is used. It +// returns one on success and zero if |version| is invalid. +OPENSSL_EXPORT int SSL_set_min_proto_version(SSL *ssl, uint16_t version); + +// SSL_set_max_proto_version sets the maximum protocol version for |ssl| to +// |version|. If |version| is zero, the default maximum version is used. It +// returns one on success and zero if |version| is invalid. +OPENSSL_EXPORT int SSL_set_max_proto_version(SSL *ssl, uint16_t version); + +// SSL_version returns the TLS or DTLS protocol version used by |ssl|, which is +// one of the |*_VERSION| values. (E.g. |TLS1_2_VERSION|.) Before the version +// is negotiated, the result is undefined. +OPENSSL_EXPORT int SSL_version(const SSL *ssl); + + +// Options. +// +// Options configure protocol behavior. + +// SSL_OP_NO_QUERY_MTU, in DTLS, disables querying the MTU from the underlying +// |BIO|. Instead, the MTU is configured with |SSL_set_mtu|. +#define SSL_OP_NO_QUERY_MTU 0x00001000L + +// SSL_OP_NO_TICKET disables session ticket support (RFC 5077). +#define SSL_OP_NO_TICKET 0x00004000L + +// SSL_OP_CIPHER_SERVER_PREFERENCE configures servers to select ciphers and +// ECDHE curves according to the server's preferences instead of the +// client's. +#define SSL_OP_CIPHER_SERVER_PREFERENCE 0x00400000L + +// The following flags toggle individual protocol versions. This is deprecated. +// Use |SSL_CTX_set_min_proto_version| and |SSL_CTX_set_max_proto_version| +// instead. +#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_TLSv1_3 0x20000000L +#define SSL_OP_NO_DTLSv1 SSL_OP_NO_TLSv1 +#define SSL_OP_NO_DTLSv1_2 SSL_OP_NO_TLSv1_2 + +// SSL_CTX_set_options enables all options set in |options| (which should be one +// or more of the |SSL_OP_*| values, ORed together) in |ctx|. It returns a +// bitmask representing the resulting enabled options. +OPENSSL_EXPORT uint32_t SSL_CTX_set_options(SSL_CTX *ctx, uint32_t options); + +// SSL_CTX_clear_options disables all options set in |options| (which should be +// one or more of the |SSL_OP_*| values, ORed together) in |ctx|. It returns a +// bitmask representing the resulting enabled options. +OPENSSL_EXPORT uint32_t SSL_CTX_clear_options(SSL_CTX *ctx, uint32_t options); + +// SSL_CTX_get_options returns a bitmask of |SSL_OP_*| values that represent all +// the options enabled for |ctx|. +OPENSSL_EXPORT uint32_t SSL_CTX_get_options(const SSL_CTX *ctx); + +// SSL_set_options enables all options set in |options| (which should be one or +// more of the |SSL_OP_*| values, ORed together) in |ssl|. It returns a bitmask +// representing the resulting enabled options. +OPENSSL_EXPORT uint32_t SSL_set_options(SSL *ssl, uint32_t options); + +// SSL_clear_options disables all options set in |options| (which should be one +// or more of the |SSL_OP_*| values, ORed together) in |ssl|. It returns a +// bitmask representing the resulting enabled options. +OPENSSL_EXPORT uint32_t SSL_clear_options(SSL *ssl, uint32_t options); + +// SSL_get_options returns a bitmask of |SSL_OP_*| values that represent all the +// options enabled for |ssl|. +OPENSSL_EXPORT uint32_t SSL_get_options(const SSL *ssl); + + +// Modes. +// +// Modes configure API behavior. + +// SSL_MODE_ENABLE_PARTIAL_WRITE, in TLS, allows |SSL_write| to complete with a +// partial result when the only part of the input was written in a single +// record. In DTLS, it does nothing. +#define SSL_MODE_ENABLE_PARTIAL_WRITE 0x00000001L + +// SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER, in TLS, allows retrying an incomplete +// |SSL_write| with a different buffer. However, |SSL_write| still assumes the +// buffer contents are unchanged. This is not the default to avoid the +// misconception that non-blocking |SSL_write| behaves like non-blocking +// |write|. In DTLS, it does nothing. +#define SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER 0x00000002L + +// SSL_MODE_NO_AUTO_CHAIN disables automatically building a certificate chain +// before sending certificates to the peer. This flag is set (and the feature +// disabled) by default. +// TODO(davidben): Remove this behavior. https://crbug.com/boringssl/42. +#define SSL_MODE_NO_AUTO_CHAIN 0x00000008L + +// SSL_MODE_ENABLE_FALSE_START allows clients to send application data before +// receipt of ChangeCipherSpec and Finished. This mode enables full handshakes +// to 'complete' in one RTT. See RFC 7918. +// +// When False Start is enabled, |SSL_do_handshake| may succeed before the +// handshake has completely finished. |SSL_write| will function at this point, +// and |SSL_read| will transparently wait for the final handshake leg before +// returning application data. To determine if False Start occurred or when the +// handshake is completely finished, see |SSL_in_false_start|, |SSL_in_init|, +// and |SSL_CB_HANDSHAKE_DONE| from |SSL_CTX_set_info_callback|. +#define SSL_MODE_ENABLE_FALSE_START 0x00000080L + +// SSL_MODE_CBC_RECORD_SPLITTING causes multi-byte CBC records in SSL 3.0 and +// TLS 1.0 to be split in two: the first record will contain a single byte and +// the second will contain the remainder. This effectively randomises the IV and +// prevents BEAST attacks. +#define SSL_MODE_CBC_RECORD_SPLITTING 0x00000100L + +// SSL_MODE_NO_SESSION_CREATION will cause any attempts to create a session to +// fail with SSL_R_SESSION_MAY_NOT_BE_CREATED. This can be used to enforce that +// session resumption is used for a given SSL*. +#define SSL_MODE_NO_SESSION_CREATION 0x00000200L + +// SSL_MODE_SEND_FALLBACK_SCSV sends TLS_FALLBACK_SCSV in the ClientHello. +// To be set only by applications that reconnect with a downgraded protocol +// version; see RFC 7507 for details. +// +// DO NOT ENABLE THIS if your application attempts a normal handshake. Only use +// this in explicit fallback retries, following the guidance in RFC 7507. +#define SSL_MODE_SEND_FALLBACK_SCSV 0x00000400L + +// SSL_CTX_set_mode enables all modes set in |mode| (which should be one or more +// of the |SSL_MODE_*| values, ORed together) in |ctx|. It returns a bitmask +// representing the resulting enabled modes. +OPENSSL_EXPORT uint32_t SSL_CTX_set_mode(SSL_CTX *ctx, uint32_t mode); + +// SSL_CTX_clear_mode disables all modes set in |mode| (which should be one or +// more of the |SSL_MODE_*| values, ORed together) in |ctx|. It returns a +// bitmask representing the resulting enabled modes. +OPENSSL_EXPORT uint32_t SSL_CTX_clear_mode(SSL_CTX *ctx, uint32_t mode); + +// SSL_CTX_get_mode returns a bitmask of |SSL_MODE_*| values that represent all +// the modes enabled for |ssl|. +OPENSSL_EXPORT uint32_t SSL_CTX_get_mode(const SSL_CTX *ctx); + +// SSL_set_mode enables all modes set in |mode| (which should be one or more of +// the |SSL_MODE_*| values, ORed together) in |ssl|. It returns a bitmask +// representing the resulting enabled modes. +OPENSSL_EXPORT uint32_t SSL_set_mode(SSL *ssl, uint32_t mode); + +// SSL_clear_mode disables all modes set in |mode| (which should be one or more +// of the |SSL_MODE_*| values, ORed together) in |ssl|. It returns a bitmask +// representing the resulting enabled modes. +OPENSSL_EXPORT uint32_t SSL_clear_mode(SSL *ssl, uint32_t mode); + +// SSL_get_mode returns a bitmask of |SSL_MODE_*| values that represent all the +// modes enabled for |ssl|. +OPENSSL_EXPORT uint32_t SSL_get_mode(const SSL *ssl); + +// SSL_CTX_set0_buffer_pool sets a |CRYPTO_BUFFER_POOL| that will be used to +// store certificates. This can allow multiple connections to share +// certificates and thus save memory. +// +// The SSL_CTX does not take ownership of |pool| and the caller must ensure +// that |pool| outlives |ctx| and all objects linked to it, including |SSL|, +// |X509| and |SSL_SESSION| objects. Basically, don't ever free |pool|. +OPENSSL_EXPORT void SSL_CTX_set0_buffer_pool(SSL_CTX *ctx, + CRYPTO_BUFFER_POOL *pool); + + +// Configuring certificates and private keys. +// +// These functions configure the connection's leaf certificate, private key, and +// certificate chain. The certificate chain is ordered leaf to root (as sent on +// the wire) but does not include the leaf. Both client and server certificates +// use these functions. +// +// Certificates and keys may be configured before the handshake or dynamically +// in the early callback and certificate callback. + +// SSL_CTX_use_certificate sets |ctx|'s leaf certificate to |x509|. It returns +// one on success and zero on failure. +OPENSSL_EXPORT int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x509); + +// SSL_use_certificate sets |ssl|'s leaf certificate to |x509|. It returns one +// on success and zero on failure. +OPENSSL_EXPORT int SSL_use_certificate(SSL *ssl, X509 *x509); + +// SSL_CTX_use_PrivateKey sets |ctx|'s private key to |pkey|. It returns one on +// success and zero on failure. +OPENSSL_EXPORT int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey); + +// SSL_use_PrivateKey sets |ssl|'s private key to |pkey|. It returns one on +// success and zero on failure. +OPENSSL_EXPORT int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey); + +// SSL_CTX_set0_chain sets |ctx|'s certificate chain, excluding the leaf, to +// |chain|. On success, it returns one and takes ownership of |chain|. +// Otherwise, it returns zero. +OPENSSL_EXPORT int SSL_CTX_set0_chain(SSL_CTX *ctx, STACK_OF(X509) *chain); + +// SSL_CTX_set1_chain sets |ctx|'s certificate chain, excluding the leaf, to +// |chain|. It returns one on success and zero on failure. The caller retains +// ownership of |chain| and may release it freely. +OPENSSL_EXPORT int SSL_CTX_set1_chain(SSL_CTX *ctx, STACK_OF(X509) *chain); + +// SSL_set0_chain sets |ssl|'s certificate chain, excluding the leaf, to +// |chain|. On success, it returns one and takes ownership of |chain|. +// Otherwise, it returns zero. +OPENSSL_EXPORT int SSL_set0_chain(SSL *ssl, STACK_OF(X509) *chain); + +// SSL_set1_chain sets |ssl|'s certificate chain, excluding the leaf, to +// |chain|. It returns one on success and zero on failure. The caller retains +// ownership of |chain| and may release it freely. +OPENSSL_EXPORT int SSL_set1_chain(SSL *ssl, STACK_OF(X509) *chain); + +// SSL_CTX_add0_chain_cert appends |x509| to |ctx|'s certificate chain. On +// success, it returns one and takes ownership of |x509|. Otherwise, it returns +// zero. +OPENSSL_EXPORT int SSL_CTX_add0_chain_cert(SSL_CTX *ctx, X509 *x509); + +// SSL_CTX_add1_chain_cert appends |x509| to |ctx|'s certificate chain. It +// returns one on success and zero on failure. The caller retains ownership of +// |x509| and may release it freely. +OPENSSL_EXPORT int SSL_CTX_add1_chain_cert(SSL_CTX *ctx, X509 *x509); + +// SSL_add0_chain_cert appends |x509| to |ctx|'s certificate chain. On success, +// it returns one and takes ownership of |x509|. Otherwise, it returns zero. +OPENSSL_EXPORT int SSL_add0_chain_cert(SSL *ssl, X509 *x509); + +// SSL_CTX_add_extra_chain_cert calls |SSL_CTX_add0_chain_cert|. +OPENSSL_EXPORT int SSL_CTX_add_extra_chain_cert(SSL_CTX *ctx, X509 *x509); + +// SSL_add1_chain_cert appends |x509| to |ctx|'s certificate chain. It returns +// one on success and zero on failure. The caller retains ownership of |x509| +// and may release it freely. +OPENSSL_EXPORT int SSL_add1_chain_cert(SSL *ssl, X509 *x509); + +// SSL_CTX_clear_chain_certs clears |ctx|'s certificate chain and returns +// one. +OPENSSL_EXPORT int SSL_CTX_clear_chain_certs(SSL_CTX *ctx); + +// SSL_CTX_clear_extra_chain_certs calls |SSL_CTX_clear_chain_certs|. +OPENSSL_EXPORT int SSL_CTX_clear_extra_chain_certs(SSL_CTX *ctx); + +// SSL_clear_chain_certs clears |ssl|'s certificate chain and returns one. +OPENSSL_EXPORT int SSL_clear_chain_certs(SSL *ssl); + +// SSL_CTX_set_cert_cb sets a callback that is called to select a certificate. +// The callback returns one on success, zero on internal error, and a negative +// number on failure or to pause the handshake. If the handshake is paused, +// |SSL_get_error| will return |SSL_ERROR_WANT_X509_LOOKUP|. +// +// On the client, the callback may call |SSL_get0_certificate_types| and +// |SSL_get_client_CA_list| for information on the server's certificate +// request. +// +// On the server, the callback will be called on non-resumption handshakes, +// after extensions have been processed. +OPENSSL_EXPORT void SSL_CTX_set_cert_cb(SSL_CTX *ctx, + int (*cb)(SSL *ssl, void *arg), + void *arg); + +// SSL_set_cert_cb sets a callback that is called to select a certificate. The +// callback returns one on success, zero on internal error, and a negative +// number on failure or to pause the handshake. If the handshake is paused, +// |SSL_get_error| will return |SSL_ERROR_WANT_X509_LOOKUP|. +// +// On the client, the callback may call |SSL_get0_certificate_types| and +// |SSL_get_client_CA_list| for information on the server's certificate +// request. +OPENSSL_EXPORT void SSL_set_cert_cb(SSL *ssl, int (*cb)(SSL *ssl, void *arg), + void *arg); + +// SSL_get0_certificate_types, for a client, sets |*out_types| to an array +// containing the client certificate types requested by a server. It returns the +// length of the array. +// +// The behavior of this function is undefined except during the callbacks set by +// by |SSL_CTX_set_cert_cb| and |SSL_CTX_set_client_cert_cb| or when the +// handshake is paused because of them. +OPENSSL_EXPORT size_t SSL_get0_certificate_types(SSL *ssl, + const uint8_t **out_types); + +// SSL_certs_clear resets the private key, leaf certificate, and certificate +// chain of |ssl|. +OPENSSL_EXPORT void SSL_certs_clear(SSL *ssl); + +// SSL_CTX_check_private_key returns one if the certificate and private key +// configured in |ctx| are consistent and zero otherwise. +OPENSSL_EXPORT int SSL_CTX_check_private_key(const SSL_CTX *ctx); + +// SSL_check_private_key returns one if the certificate and private key +// configured in |ssl| are consistent and zero otherwise. +OPENSSL_EXPORT int SSL_check_private_key(const SSL *ssl); + +// SSL_CTX_get0_certificate returns |ctx|'s leaf certificate. +OPENSSL_EXPORT X509 *SSL_CTX_get0_certificate(const SSL_CTX *ctx); + +// SSL_get_certificate returns |ssl|'s leaf certificate. +OPENSSL_EXPORT X509 *SSL_get_certificate(const SSL *ssl); + +// SSL_CTX_get0_privatekey returns |ctx|'s private key. +OPENSSL_EXPORT EVP_PKEY *SSL_CTX_get0_privatekey(const SSL_CTX *ctx); + +// SSL_get_privatekey returns |ssl|'s private key. +OPENSSL_EXPORT EVP_PKEY *SSL_get_privatekey(const SSL *ssl); + +// SSL_CTX_get0_chain_certs sets |*out_chain| to |ctx|'s certificate chain and +// returns one. +OPENSSL_EXPORT int SSL_CTX_get0_chain_certs(const SSL_CTX *ctx, + STACK_OF(X509) **out_chain); + +// SSL_CTX_get_extra_chain_certs calls |SSL_CTX_get0_chain_certs|. +OPENSSL_EXPORT int SSL_CTX_get_extra_chain_certs(const SSL_CTX *ctx, + STACK_OF(X509) **out_chain); + +// SSL_get0_chain_certs sets |*out_chain| to |ssl|'s certificate chain and +// returns one. +OPENSSL_EXPORT int SSL_get0_chain_certs(const SSL *ssl, + STACK_OF(X509) **out_chain); + +// SSL_CTX_set_signed_cert_timestamp_list sets the list of signed certificate +// timestamps that is sent to clients that request it. The |list| argument must +// contain one or more SCT structures serialised as a SignedCertificateTimestamp +// List (see https://tools.ietf.org/html/rfc6962#section-3.3) – i.e. each SCT +// is prefixed by a big-endian, uint16 length and the concatenation of one or +// more such prefixed SCTs are themselves also prefixed by a uint16 length. It +// returns one on success and zero on error. The caller retains ownership of +// |list|. +OPENSSL_EXPORT int SSL_CTX_set_signed_cert_timestamp_list(SSL_CTX *ctx, + const uint8_t *list, + size_t list_len); + +// SSL_set_signed_cert_timestamp_list sets the list of signed certificate +// timestamps that is sent to clients that request is. The same format as the +// one used for |SSL_CTX_set_signed_cert_timestamp_list| applies. The caller +// retains ownership of |list|. +OPENSSL_EXPORT int SSL_set_signed_cert_timestamp_list(SSL *ctx, + const uint8_t *list, + size_t list_len); + +// SSL_CTX_set_ocsp_response sets the OCSP response that is sent to clients +// which request it. It returns one on success and zero on error. The caller +// retains ownership of |response|. +OPENSSL_EXPORT int SSL_CTX_set_ocsp_response(SSL_CTX *ctx, + const uint8_t *response, + size_t response_len); + +// SSL_set_ocsp_response sets the OCSP response that is sent to clients which +// request it. It returns one on success and zero on error. The caller retains +// ownership of |response|. +OPENSSL_EXPORT int SSL_set_ocsp_response(SSL *ssl, + const uint8_t *response, + size_t response_len); + +// SSL_SIGN_* are signature algorithm values as defined in TLS 1.3. +#define SSL_SIGN_RSA_PKCS1_SHA1 0x0201 +#define SSL_SIGN_RSA_PKCS1_SHA256 0x0401 +#define SSL_SIGN_RSA_PKCS1_SHA384 0x0501 +#define SSL_SIGN_RSA_PKCS1_SHA512 0x0601 +#define SSL_SIGN_ECDSA_SHA1 0x0203 +#define SSL_SIGN_ECDSA_SECP256R1_SHA256 0x0403 +#define SSL_SIGN_ECDSA_SECP384R1_SHA384 0x0503 +#define SSL_SIGN_ECDSA_SECP521R1_SHA512 0x0603 +#define SSL_SIGN_RSA_PSS_SHA256 0x0804 +#define SSL_SIGN_RSA_PSS_SHA384 0x0805 +#define SSL_SIGN_RSA_PSS_SHA512 0x0806 +#define SSL_SIGN_ED25519 0x0807 + +// SSL_SIGN_RSA_PKCS1_MD5_SHA1 is an internal signature algorithm used to +// specify raw RSASSA-PKCS1-v1_5 with an MD5/SHA-1 concatenation, as used in TLS +// before TLS 1.2. +#define SSL_SIGN_RSA_PKCS1_MD5_SHA1 0xff01 + +// SSL_get_signature_algorithm_name returns a human-readable name for |sigalg|, +// or NULL if unknown. If |include_curve| is one, the curve for ECDSA algorithms +// is included as in TLS 1.3. Otherwise, it is excluded as in TLS 1.2. +OPENSSL_EXPORT const char *SSL_get_signature_algorithm_name(uint16_t sigalg, + int include_curve); + +// SSL_get_signature_algorithm_key_type returns the key type associated with +// |sigalg| as an |EVP_PKEY_*| constant or |EVP_PKEY_NONE| if unknown. +OPENSSL_EXPORT int SSL_get_signature_algorithm_key_type(uint16_t sigalg); + +// SSL_get_signature_algorithm_digest returns the digest function associated +// with |sigalg| or |NULL| if |sigalg| has no prehash (Ed25519) or is unknown. +OPENSSL_EXPORT const EVP_MD *SSL_get_signature_algorithm_digest( + uint16_t sigalg); + +// SSL_is_signature_algorithm_rsa_pss returns one if |sigalg| is an RSA-PSS +// signature algorithm and zero otherwise. +OPENSSL_EXPORT int SSL_is_signature_algorithm_rsa_pss(uint16_t sigalg); + +// SSL_CTX_set_signing_algorithm_prefs configures |ctx| to use |prefs| as the +// preference list when signing with |ctx|'s private key. It returns one on +// success and zero on error. |prefs| should not include the internal-only value +// |SSL_SIGN_RSA_PKCS1_MD5_SHA1|. +OPENSSL_EXPORT int SSL_CTX_set_signing_algorithm_prefs(SSL_CTX *ctx, + const uint16_t *prefs, + size_t num_prefs); + +// SSL_set_signing_algorithm_prefs configures |ssl| to use |prefs| as the +// preference list when signing with |ssl|'s private key. It returns one on +// success and zero on error. |prefs| should not include the internal-only value +// |SSL_SIGN_RSA_PKCS1_MD5_SHA1|. +OPENSSL_EXPORT int SSL_set_signing_algorithm_prefs(SSL *ssl, + const uint16_t *prefs, + size_t num_prefs); + + +// Certificate and private key convenience functions. + +// SSL_CTX_set_chain_and_key sets the certificate chain and private key for a +// TLS client or server. References to the given |CRYPTO_BUFFER| and |EVP_PKEY| +// objects are added as needed. Exactly one of |privkey| or |privkey_method| +// may be non-NULL. Returns one on success and zero on error. +OPENSSL_EXPORT int SSL_CTX_set_chain_and_key( + SSL_CTX *ctx, CRYPTO_BUFFER *const *certs, size_t num_certs, + EVP_PKEY *privkey, const SSL_PRIVATE_KEY_METHOD *privkey_method); + +// SSL_set_chain_and_key sets the certificate chain and private key for a TLS +// client or server. References to the given |CRYPTO_BUFFER| and |EVP_PKEY| +// objects are added as needed. Exactly one of |privkey| or |privkey_method| +// may be non-NULL. Returns one on success and zero on error. +OPENSSL_EXPORT int SSL_set_chain_and_key( + SSL *ssl, CRYPTO_BUFFER *const *certs, size_t num_certs, EVP_PKEY *privkey, + const SSL_PRIVATE_KEY_METHOD *privkey_method); + +// SSL_CTX_use_RSAPrivateKey sets |ctx|'s private key to |rsa|. It returns one +// on success and zero on failure. +OPENSSL_EXPORT int SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa); + +// SSL_use_RSAPrivateKey sets |ctx|'s private key to |rsa|. It returns one on +// success and zero on failure. +OPENSSL_EXPORT int SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa); + +// The following functions configure certificates or private keys but take as +// input DER-encoded structures. They return one on success and zero on +// failure. + +OPENSSL_EXPORT int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, size_t der_len, + const uint8_t *der); +OPENSSL_EXPORT int SSL_use_certificate_ASN1(SSL *ssl, const uint8_t *der, + size_t der_len); + +OPENSSL_EXPORT int SSL_CTX_use_PrivateKey_ASN1(int pk, SSL_CTX *ctx, + const uint8_t *der, + size_t der_len); +OPENSSL_EXPORT int SSL_use_PrivateKey_ASN1(int type, SSL *ssl, + const uint8_t *der, size_t der_len); + +OPENSSL_EXPORT int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, + const uint8_t *der, + size_t der_len); +OPENSSL_EXPORT int SSL_use_RSAPrivateKey_ASN1(SSL *ssl, const uint8_t *der, + size_t der_len); + +// The following functions configure certificates or private keys but take as +// input files to read from. They return one on success and zero on failure. The +// |type| parameter is one of the |SSL_FILETYPE_*| values and determines whether +// the file's contents are read as PEM or DER. + +#define SSL_FILETYPE_PEM 1 +#define SSL_FILETYPE_ASN1 2 + +OPENSSL_EXPORT int SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx, + const char *file, + int type); +OPENSSL_EXPORT int SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, + int type); + +OPENSSL_EXPORT int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, + int type); +OPENSSL_EXPORT int SSL_use_certificate_file(SSL *ssl, const char *file, + int type); + +OPENSSL_EXPORT int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, + int type); +OPENSSL_EXPORT int SSL_use_PrivateKey_file(SSL *ssl, const char *file, + int type); + +// SSL_CTX_use_certificate_chain_file configures certificates for |ctx|. It +// reads the contents of |file| as a PEM-encoded leaf certificate followed +// optionally by the certificate chain to send to the peer. It returns one on +// success and zero on failure. +OPENSSL_EXPORT int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, + const char *file); + +// SSL_CTX_set_default_passwd_cb sets the password callback for PEM-based +// convenience functions called on |ctx|. +OPENSSL_EXPORT void SSL_CTX_set_default_passwd_cb(SSL_CTX *ctx, + pem_password_cb *cb); + +// SSL_CTX_get_default_passwd_cb returns the callback set by +// |SSL_CTX_set_default_passwd_cb|. +OPENSSL_EXPORT pem_password_cb *SSL_CTX_get_default_passwd_cb( + const SSL_CTX *ctx); + +// SSL_CTX_set_default_passwd_cb_userdata sets the userdata parameter for +// |ctx|'s password callback. +OPENSSL_EXPORT void SSL_CTX_set_default_passwd_cb_userdata(SSL_CTX *ctx, + void *data); + +// SSL_CTX_get_default_passwd_cb_userdata returns the userdata parameter set by +// |SSL_CTX_set_default_passwd_cb_userdata|. +OPENSSL_EXPORT void *SSL_CTX_get_default_passwd_cb_userdata(const SSL_CTX *ctx); + + +// Custom private keys. + +enum ssl_private_key_result_t { + ssl_private_key_success, + ssl_private_key_retry, + ssl_private_key_failure, +}; + +// ssl_private_key_method_st (aka |SSL_PRIVATE_KEY_METHOD|) describes private +// key hooks. This is used to off-load signing operations to a custom, +// potentially asynchronous, backend. Metadata about the key such as the type +// and size are parsed out of the certificate. +struct ssl_private_key_method_st { + // sign signs the message |in| in using the specified signature algorithm. On + // success, it returns |ssl_private_key_success| and writes at most |max_out| + // bytes of signature data to |out| and sets |*out_len| to the number of bytes + // written. On failure, it returns |ssl_private_key_failure|. If the operation + // has not completed, it returns |ssl_private_key_retry|. |sign| should + // arrange for the high-level operation on |ssl| to be retried when the + // operation is completed. This will result in a call to |complete|. + // + // |signature_algorithm| is one of the |SSL_SIGN_*| values, as defined in TLS + // 1.3. Note that, in TLS 1.2, ECDSA algorithms do not require that curve + // sizes match hash sizes, so the curve portion of |SSL_SIGN_ECDSA_*| values + // must be ignored. BoringSSL will internally handle the curve matching logic + // where appropriate. + // + // It is an error to call |sign| while another private key operation is in + // progress on |ssl|. + enum ssl_private_key_result_t (*sign)(SSL *ssl, uint8_t *out, size_t *out_len, + size_t max_out, + uint16_t signature_algorithm, + const uint8_t *in, size_t in_len); + + // decrypt decrypts |in_len| bytes of encrypted data from |in|. On success it + // returns |ssl_private_key_success|, writes at most |max_out| bytes of + // decrypted data to |out| and sets |*out_len| to the actual number of bytes + // written. On failure it returns |ssl_private_key_failure|. If the operation + // has not completed, it returns |ssl_private_key_retry|. The caller should + // arrange for the high-level operation on |ssl| to be retried when the + // operation is completed, which will result in a call to |complete|. This + // function only works with RSA keys and should perform a raw RSA decryption + // operation with no padding. + // + // It is an error to call |decrypt| while another private key operation is in + // progress on |ssl|. + enum ssl_private_key_result_t (*decrypt)(SSL *ssl, uint8_t *out, + size_t *out_len, size_t max_out, + const uint8_t *in, size_t in_len); + + // complete completes a pending operation. If the operation has completed, it + // returns |ssl_private_key_success| and writes the result to |out| as in + // |sign|. Otherwise, it returns |ssl_private_key_failure| on failure and + // |ssl_private_key_retry| if the operation is still in progress. + // + // |complete| may be called arbitrarily many times before completion, but it + // is an error to call |complete| if there is no pending operation in progress + // on |ssl|. + enum ssl_private_key_result_t (*complete)(SSL *ssl, uint8_t *out, + size_t *out_len, size_t max_out); +}; + +// SSL_set_private_key_method configures a custom private key on |ssl|. +// |key_method| must remain valid for the lifetime of |ssl|. +OPENSSL_EXPORT void SSL_set_private_key_method( + SSL *ssl, const SSL_PRIVATE_KEY_METHOD *key_method); + +// SSL_CTX_set_private_key_method configures a custom private key on |ctx|. +// |key_method| must remain valid for the lifetime of |ctx|. +OPENSSL_EXPORT void SSL_CTX_set_private_key_method( + SSL_CTX *ctx, const SSL_PRIVATE_KEY_METHOD *key_method); + + +// Cipher suites. +// +// |SSL_CIPHER| objects represent cipher suites. + +DEFINE_CONST_STACK_OF(SSL_CIPHER) + +// SSL_get_cipher_by_value returns the structure representing a TLS cipher +// suite based on its assigned number, or NULL if unknown. See +// https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-4. +OPENSSL_EXPORT const SSL_CIPHER *SSL_get_cipher_by_value(uint16_t value); + +// SSL_CIPHER_get_id returns |cipher|'s id. It may be cast to a |uint16_t| to +// get the cipher suite value. +OPENSSL_EXPORT uint32_t SSL_CIPHER_get_id(const SSL_CIPHER *cipher); + +// SSL_CIPHER_is_aead returns one if |cipher| uses an AEAD cipher. +OPENSSL_EXPORT int SSL_CIPHER_is_aead(const SSL_CIPHER *cipher); + +// SSL_CIPHER_is_block_cipher returns one if |cipher| is a block cipher. +OPENSSL_EXPORT int SSL_CIPHER_is_block_cipher(const SSL_CIPHER *cipher); + +// SSL_CIPHER_get_cipher_nid returns the NID for |cipher|'s bulk +// cipher. Possible values are |NID_aes_128_gcm|, |NID_aes_256_gcm|, +// |NID_chacha20_poly1305|, |NID_aes_128_cbc|, |NID_aes_256_cbc|, and +// |NID_des_ede3_cbc|. +OPENSSL_EXPORT int SSL_CIPHER_get_cipher_nid(const SSL_CIPHER *cipher); + +// SSL_CIPHER_get_digest_nid returns the NID for |cipher|'s HMAC if it is a +// legacy cipher suite. For modern AEAD-based ciphers (see +// |SSL_CIPHER_is_aead|), it returns |NID_undef|. +// +// Note this function only returns the legacy HMAC digest, not the PRF hash. +OPENSSL_EXPORT int SSL_CIPHER_get_digest_nid(const SSL_CIPHER *cipher); + +// SSL_CIPHER_get_kx_nid returns the NID for |cipher|'s key exchange. This may +// be |NID_kx_rsa|, |NID_kx_ecdhe|, or |NID_kx_psk| for TLS 1.2. In TLS 1.3, +// cipher suites do not specify the key exchange, so this function returns +// |NID_kx_any|. +OPENSSL_EXPORT int SSL_CIPHER_get_kx_nid(const SSL_CIPHER *cipher); + +// SSL_CIPHER_get_auth_nid returns the NID for |cipher|'s authentication +// type. This may be |NID_auth_rsa|, |NID_auth_ecdsa|, or |NID_auth_psk| for TLS +// 1.2. In TLS 1.3, cipher suites do not specify authentication, so this +// function returns |NID_auth_any|. +OPENSSL_EXPORT int SSL_CIPHER_get_auth_nid(const SSL_CIPHER *cipher); + +// SSL_CIPHER_get_prf_nid retuns the NID for |cipher|'s PRF hash. If |cipher| is +// a pre-TLS-1.2 cipher, it returns |NID_md5_sha1| but note these ciphers use +// SHA-256 in TLS 1.2. Other return values may be treated uniformly in all +// applicable versions. +OPENSSL_EXPORT int SSL_CIPHER_get_prf_nid(const SSL_CIPHER *cipher); + +// SSL_CIPHER_get_min_version returns the minimum protocol version required +// for |cipher|. +OPENSSL_EXPORT uint16_t SSL_CIPHER_get_min_version(const SSL_CIPHER *cipher); + +// SSL_CIPHER_get_max_version returns the maximum protocol version that +// supports |cipher|. +OPENSSL_EXPORT uint16_t SSL_CIPHER_get_max_version(const SSL_CIPHER *cipher); + +// SSL_CIPHER_standard_name returns the standard IETF name for |cipher|. For +// example, "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256". +OPENSSL_EXPORT const char *SSL_CIPHER_standard_name(const SSL_CIPHER *cipher); + +// SSL_CIPHER_get_name returns the OpenSSL name of |cipher|. For example, +// "ECDHE-RSA-AES128-GCM-SHA256". +OPENSSL_EXPORT const char *SSL_CIPHER_get_name(const SSL_CIPHER *cipher); + +// SSL_CIPHER_get_kx_name returns a string that describes the key-exchange +// method used by |cipher|. For example, "ECDHE_ECDSA". TLS 1.3 AEAD-only +// ciphers return the string "GENERIC". +OPENSSL_EXPORT const char *SSL_CIPHER_get_kx_name(const SSL_CIPHER *cipher); + +// SSL_CIPHER_get_bits returns the strength, in bits, of |cipher|. If +// |out_alg_bits| is not NULL, it writes the number of bits consumed by the +// symmetric algorithm to |*out_alg_bits|. +OPENSSL_EXPORT int SSL_CIPHER_get_bits(const SSL_CIPHER *cipher, + int *out_alg_bits); + + +// Cipher suite configuration. +// +// OpenSSL uses a mini-language to configure cipher suites. The language +// maintains an ordered list of enabled ciphers, along with an ordered list of +// disabled but available ciphers. Initially, all ciphers are disabled with a +// default ordering. The cipher string is then interpreted as a sequence of +// directives, separated by colons, each of which modifies this state. +// +// Most directives consist of a one character or empty opcode followed by a +// selector which matches a subset of available ciphers. +// +// Available opcodes are: +// +// The empty opcode enables and appends all matching disabled ciphers to the +// end of the enabled list. The newly appended ciphers are ordered relative to +// each other matching their order in the disabled list. +// +// |-| disables all matching enabled ciphers and prepends them to the disabled +// list, with relative order from the enabled list preserved. This means the +// most recently disabled ciphers get highest preference relative to other +// disabled ciphers if re-enabled. +// +// |+| moves all matching enabled ciphers to the end of the enabled list, with +// relative order preserved. +// +// |!| deletes all matching ciphers, enabled or not, from either list. Deleted +// ciphers will not matched by future operations. +// +// A selector may be a specific cipher (using either the standard or OpenSSL +// name for the cipher) or one or more rules separated by |+|. The final +// selector matches the intersection of each rule. For instance, |AESGCM+aECDSA| +// matches ECDSA-authenticated AES-GCM ciphers. +// +// Available cipher rules are: +// +// |ALL| matches all ciphers. +// +// |kRSA|, |kDHE|, |kECDHE|, and |kPSK| match ciphers using plain RSA, DHE, +// ECDHE, and plain PSK key exchanges, respectively. Note that ECDHE_PSK is +// matched by |kECDHE| and not |kPSK|. +// +// |aRSA|, |aECDSA|, and |aPSK| match ciphers authenticated by RSA, ECDSA, and +// a pre-shared key, respectively. +// +// |RSA|, |DHE|, |ECDHE|, |PSK|, |ECDSA|, and |PSK| are aliases for the +// corresponding |k*| or |a*| cipher rule. |RSA| is an alias for |kRSA|, not +// |aRSA|. +// +// |3DES|, |AES128|, |AES256|, |AES|, |AESGCM|, |CHACHA20| match ciphers +// whose bulk cipher use the corresponding encryption scheme. Note that +// |AES|, |AES128|, and |AES256| match both CBC and GCM ciphers. +// +// |SHA1|, |SHA256|, and |SHA384| match legacy cipher suites using the +// corresponding hash function in their MAC. AEADs are matched by none of +// these. +// +// |SHA| is an alias for |SHA1|. +// +// Although implemented, authentication-only ciphers match no rules and must be +// explicitly selected by name. +// +// Deprecated cipher rules: +// +// |kEDH|, |EDH|, |kEECDH|, and |EECDH| are legacy aliases for |kDHE|, |DHE|, +// |kECDHE|, and |ECDHE|, respectively. +// +// |HIGH| is an alias for |ALL|. +// +// |FIPS| is an alias for |HIGH|. +// +// |SSLv3| and |TLSv1| match ciphers available in TLS 1.1 or earlier. +// |TLSv1_2| matches ciphers new in TLS 1.2. This is confusing and should not +// be used. +// +// Unknown rules are silently ignored by legacy APIs, and rejected by APIs with +// "strict" in the name, which should be preferred. Cipher lists can be long +// and it's easy to commit typos. Strict functions will also reject the use of +// spaces, semi-colons and commas as alternative separators. +// +// The special |@STRENGTH| directive will sort all enabled ciphers by strength. +// +// The |DEFAULT| directive, when appearing at the front of the string, expands +// to the default ordering of available ciphers. +// +// If configuring a server, one may also configure equal-preference groups to +// partially respect the client's preferences when +// |SSL_OP_CIPHER_SERVER_PREFERENCE| is enabled. Ciphers in an equal-preference +// group have equal priority and use the client order. This may be used to +// enforce that AEADs are preferred but select AES-GCM vs. ChaCha20-Poly1305 +// based on client preferences. An equal-preference is specified with square +// brackets, combining multiple selectors separated by |. For example: +// +// [ECDHE-ECDSA-CHACHA20-POLY1305|ECDHE-ECDSA-AES128-GCM-SHA256] +// +// Once an equal-preference group is used, future directives must be +// opcode-less. Inside an equal-preference group, spaces are not allowed. +// +// TLS 1.3 ciphers do not participate in this mechanism and instead have a +// built-in preference order. Functions to set cipher lists do not affect TLS +// 1.3, and functions to query the cipher list do not include TLS 1.3 +// ciphers. + +// SSL_DEFAULT_CIPHER_LIST is the default cipher suite configuration. It is +// substituted when a cipher string starts with 'DEFAULT'. +#define SSL_DEFAULT_CIPHER_LIST "ALL" + +// SSL_CTX_set_strict_cipher_list configures the cipher list for |ctx|, +// evaluating |str| as a cipher string and returning error if |str| contains +// anything meaningless. It returns one on success and zero on failure. +OPENSSL_EXPORT int SSL_CTX_set_strict_cipher_list(SSL_CTX *ctx, + const char *str); + +// SSL_CTX_set_cipher_list configures the cipher list for |ctx|, evaluating +// |str| as a cipher string. It returns one on success and zero on failure. +// +// Prefer to use |SSL_CTX_set_strict_cipher_list|. This function tolerates +// garbage inputs, unless an empty cipher list results. +OPENSSL_EXPORT int SSL_CTX_set_cipher_list(SSL_CTX *ctx, const char *str); + +// SSL_set_strict_cipher_list configures the cipher list for |ssl|, evaluating +// |str| as a cipher string and returning error if |str| contains anything +// meaningless. It returns one on success and zero on failure. +OPENSSL_EXPORT int SSL_set_strict_cipher_list(SSL *ssl, const char *str); + +// SSL_set_cipher_list configures the cipher list for |ssl|, evaluating |str| as +// a cipher string. It returns one on success and zero on failure. +// +// Prefer to use |SSL_set_strict_cipher_list|. This function tolerates garbage +// inputs, unless an empty cipher list results. +OPENSSL_EXPORT int SSL_set_cipher_list(SSL *ssl, const char *str); + +// SSL_CTX_get_ciphers returns the cipher list for |ctx|, in order of +// preference. +OPENSSL_EXPORT STACK_OF(SSL_CIPHER) *SSL_CTX_get_ciphers(const SSL_CTX *ctx); + +// SSL_CTX_cipher_in_group returns one if the |i|th cipher (see +// |SSL_CTX_get_ciphers|) is in the same equipreference group as the one +// following it and zero otherwise. +OPENSSL_EXPORT int SSL_CTX_cipher_in_group(const SSL_CTX *ctx, size_t i); + +// SSL_get_ciphers returns the cipher list for |ssl|, in order of preference. +OPENSSL_EXPORT STACK_OF(SSL_CIPHER) *SSL_get_ciphers(const SSL *ssl); + + +// Connection information. + +// SSL_is_init_finished returns one if |ssl| has completed its initial handshake +// and has no pending handshake. It returns zero otherwise. +OPENSSL_EXPORT int SSL_is_init_finished(const SSL *ssl); + +// SSL_in_init returns one if |ssl| has a pending handshake and zero +// otherwise. +OPENSSL_EXPORT int SSL_in_init(const SSL *ssl); + +// SSL_in_false_start returns one if |ssl| has a pending handshake that is in +// False Start. |SSL_write| may be called at this point without waiting for the +// peer, but |SSL_read| will complete the handshake before accepting application +// data. +// +// See also |SSL_MODE_ENABLE_FALSE_START|. +OPENSSL_EXPORT int SSL_in_false_start(const SSL *ssl); + +// SSL_get_peer_certificate returns the peer's leaf certificate or NULL if the +// peer did not use certificates. The caller must call |X509_free| on the +// result to release it. +OPENSSL_EXPORT X509 *SSL_get_peer_certificate(const SSL *ssl); + +// SSL_get_peer_cert_chain returns the peer's certificate chain or NULL if +// unavailable or the peer did not use certificates. This is the unverified list +// of certificates as sent by the peer, not the final chain built during +// verification. The caller does not take ownership of the result. +// +// WARNING: This function behaves differently between client and server. If +// |ssl| is a server, the returned chain does not include the leaf certificate. +// If a client, it does. +OPENSSL_EXPORT STACK_OF(X509) *SSL_get_peer_cert_chain(const SSL *ssl); + +// SSL_get_peer_full_cert_chain returns the peer's certificate chain, or NULL if +// unavailable or the peer did not use certificates. This is the unverified list +// of certificates as sent by the peer, not the final chain built during +// verification. The caller does not take ownership of the result. +// +// This is the same as |SSL_get_peer_cert_chain| except that this function +// always returns the full chain, i.e. the first element of the return value +// (if any) will be the leaf certificate. In constrast, +// |SSL_get_peer_cert_chain| returns only the intermediate certificates if the +// |ssl| is a server. +OPENSSL_EXPORT STACK_OF(X509) *SSL_get_peer_full_cert_chain(const SSL *ssl); + +// SSL_get0_peer_certificates returns the peer's certificate chain, or NULL if +// unavailable or the peer did not use certificates. This is the unverified list +// of certificates as sent by the peer, not the final chain built during +// verification. The caller does not take ownership of the result. +// +// This is the |CRYPTO_BUFFER| variant of |SSL_get_peer_full_cert_chain|. +OPENSSL_EXPORT STACK_OF(CRYPTO_BUFFER) * + SSL_get0_peer_certificates(const SSL *ssl); + +// SSL_get0_signed_cert_timestamp_list sets |*out| and |*out_len| to point to +// |*out_len| bytes of SCT information from the server. This is only valid if +// |ssl| is a client. The SCT information is a SignedCertificateTimestampList +// (including the two leading length bytes). +// See https://tools.ietf.org/html/rfc6962#section-3.3 +// If no SCT was received then |*out_len| will be zero on return. +// +// WARNING: the returned data is not guaranteed to be well formed. +OPENSSL_EXPORT void SSL_get0_signed_cert_timestamp_list(const SSL *ssl, + const uint8_t **out, + size_t *out_len); + +// SSL_get0_ocsp_response sets |*out| and |*out_len| to point to |*out_len| +// bytes of an OCSP response from the server. This is the DER encoding of an +// OCSPResponse type as defined in RFC 2560. +// +// WARNING: the returned data is not guaranteed to be well formed. +OPENSSL_EXPORT void SSL_get0_ocsp_response(const SSL *ssl, const uint8_t **out, + size_t *out_len); + +// SSL_get_tls_unique writes at most |max_out| bytes of the tls-unique value +// for |ssl| to |out| and sets |*out_len| to the number of bytes written. It +// returns one on success or zero on error. In general |max_out| should be at +// least 12. +// +// This function will always fail if the initial handshake has not completed. +// The tls-unique value will change after a renegotiation but, since +// renegotiations can be initiated by the server at any point, the higher-level +// protocol must either leave them disabled or define states in which the +// tls-unique value can be read. +// +// The tls-unique value is defined by +// https://tools.ietf.org/html/rfc5929#section-3.1. Due to a weakness in the +// TLS protocol, tls-unique is broken for resumed connections unless the +// Extended Master Secret extension is negotiated. Thus this function will +// return zero if |ssl| performed session resumption unless EMS was used when +// negotiating the original session. +OPENSSL_EXPORT int SSL_get_tls_unique(const SSL *ssl, uint8_t *out, + size_t *out_len, size_t max_out); + +// SSL_get_extms_support returns one if the Extended Master Secret extension or +// TLS 1.3 was negotiated. Otherwise, it returns zero. +OPENSSL_EXPORT int SSL_get_extms_support(const SSL *ssl); + +// SSL_get_current_cipher returns the cipher used in the current outgoing +// connection state, or NULL if the null cipher is active. +OPENSSL_EXPORT const SSL_CIPHER *SSL_get_current_cipher(const SSL *ssl); + +// SSL_session_reused returns one if |ssl| performed an abbreviated handshake +// and zero otherwise. +// +// TODO(davidben): Hammer down the semantics of this API while a handshake, +// initial or renego, is in progress. +OPENSSL_EXPORT int SSL_session_reused(const SSL *ssl); + +// SSL_get_secure_renegotiation_support returns one if the peer supports secure +// renegotiation (RFC 5746) or TLS 1.3. Otherwise, it returns zero. +OPENSSL_EXPORT int SSL_get_secure_renegotiation_support(const SSL *ssl); + +// SSL_export_keying_material exports a value derived from the master secret, as +// specified in RFC 5705. It writes |out_len| 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 one on success and zero otherwise. +OPENSSL_EXPORT int SSL_export_keying_material( + SSL *ssl, uint8_t *out, size_t out_len, const char *label, size_t label_len, + const uint8_t *context, size_t context_len, int use_context); + + +// Custom extensions. +// +// The custom extension functions allow TLS extensions to be added to +// ClientHello and ServerHello messages. + +// SSL_custom_ext_add_cb is a callback function that is called when the +// ClientHello (for clients) or ServerHello (for servers) is constructed. In +// the case of a server, this callback will only be called for a given +// extension if the ClientHello contained that extension – it's not possible to +// inject extensions into a ServerHello that the client didn't request. +// +// When called, |extension_value| will contain the extension number that is +// being considered for addition (so that a single callback can handle multiple +// extensions). If the callback wishes to include the extension, it must set +// |*out| to point to |*out_len| bytes of extension contents and return one. In +// this case, the corresponding |SSL_custom_ext_free_cb| callback will later be +// called with the value of |*out| once that data has been copied. +// +// If the callback does not wish to add an extension it must return zero. +// +// Alternatively, the callback can abort the connection by setting +// |*out_alert_value| to a TLS alert number and returning -1. +typedef int (*SSL_custom_ext_add_cb)(SSL *ssl, unsigned extension_value, + const uint8_t **out, size_t *out_len, + int *out_alert_value, void *add_arg); + +// SSL_custom_ext_free_cb is a callback function that is called by OpenSSL iff +// an |SSL_custom_ext_add_cb| callback previously returned one. In that case, +// this callback is called and passed the |out| pointer that was returned by +// the add callback. This is to free any dynamically allocated data created by +// the add callback. +typedef void (*SSL_custom_ext_free_cb)(SSL *ssl, unsigned extension_value, + const uint8_t *out, void *add_arg); + +// SSL_custom_ext_parse_cb is a callback function that is called by OpenSSL to +// parse an extension from the peer: that is from the ServerHello for a client +// and from the ClientHello for a server. +// +// When called, |extension_value| will contain the extension number and the +// contents of the extension are |contents_len| bytes at |contents|. +// +// The callback must return one to continue the handshake. Otherwise, if it +// returns zero, a fatal alert with value |*out_alert_value| is sent and the +// handshake is aborted. +typedef int (*SSL_custom_ext_parse_cb)(SSL *ssl, unsigned extension_value, + const uint8_t *contents, + size_t contents_len, + int *out_alert_value, void *parse_arg); + +// SSL_extension_supported returns one iff OpenSSL internally handles +// extensions of type |extension_value|. This can be used to avoid registering +// custom extension handlers for extensions that a future version of OpenSSL +// may handle internally. +OPENSSL_EXPORT int SSL_extension_supported(unsigned extension_value); + +// SSL_CTX_add_client_custom_ext registers callback functions for handling +// custom TLS extensions for client connections. +// +// If |add_cb| is NULL then an empty extension will be added in each +// ClientHello. Otherwise, see the comment for |SSL_custom_ext_add_cb| about +// this callback. +// +// The |free_cb| may be NULL if |add_cb| doesn't dynamically allocate data that +// needs to be freed. +// +// It returns one on success or zero on error. It's always an error to register +// callbacks for the same extension twice, or to register callbacks for an +// extension that OpenSSL handles internally. See |SSL_extension_supported| to +// discover, at runtime, which extensions OpenSSL handles internally. +OPENSSL_EXPORT int SSL_CTX_add_client_custom_ext( + SSL_CTX *ctx, unsigned extension_value, SSL_custom_ext_add_cb add_cb, + SSL_custom_ext_free_cb free_cb, void *add_arg, + SSL_custom_ext_parse_cb parse_cb, void *parse_arg); + +// SSL_CTX_add_server_custom_ext is the same as +// |SSL_CTX_add_client_custom_ext|, but for server connections. +// +// Unlike on the client side, if |add_cb| is NULL no extension will be added. +// The |add_cb|, if any, will only be called if the ClientHello contained a +// matching extension. +OPENSSL_EXPORT int SSL_CTX_add_server_custom_ext( + SSL_CTX *ctx, unsigned extension_value, SSL_custom_ext_add_cb add_cb, + SSL_custom_ext_free_cb free_cb, void *add_arg, + SSL_custom_ext_parse_cb parse_cb, void *parse_arg); + + +// Sessions. +// +// An |SSL_SESSION| represents an SSL session that may be resumed in an +// abbreviated handshake. It is reference-counted and immutable. Once +// established, an |SSL_SESSION| may be shared by multiple |SSL| objects on +// different threads and must not be modified. + +DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION) + +// SSL_SESSION_new returns a newly-allocated blank |SSL_SESSION| or NULL on +// error. This may be useful when writing tests but should otherwise not be +// used. +OPENSSL_EXPORT SSL_SESSION *SSL_SESSION_new(const SSL_CTX *ctx); + +// SSL_SESSION_up_ref increments the reference count of |session| and returns +// one. +OPENSSL_EXPORT int SSL_SESSION_up_ref(SSL_SESSION *session); + +// SSL_SESSION_free decrements the reference count of |session|. If it reaches +// zero, all data referenced by |session| and |session| itself are released. +OPENSSL_EXPORT void SSL_SESSION_free(SSL_SESSION *session); + +// SSL_SESSION_to_bytes serializes |in| into a newly allocated buffer and sets +// |*out_data| to that buffer and |*out_len| to its length. The caller takes +// ownership of the buffer and must call |OPENSSL_free| when done. It returns +// one on success and zero on error. +OPENSSL_EXPORT int SSL_SESSION_to_bytes(const SSL_SESSION *in, + uint8_t **out_data, size_t *out_len); + +// SSL_SESSION_to_bytes_for_ticket serializes |in|, but excludes the session +// identification information, namely the session ID and ticket. +OPENSSL_EXPORT int SSL_SESSION_to_bytes_for_ticket(const SSL_SESSION *in, + uint8_t **out_data, + size_t *out_len); + +// SSL_SESSION_from_bytes parses |in_len| bytes from |in| as an SSL_SESSION. It +// returns a newly-allocated |SSL_SESSION| on success or NULL on error. +OPENSSL_EXPORT SSL_SESSION *SSL_SESSION_from_bytes( + const uint8_t *in, size_t in_len, const SSL_CTX *ctx); + +// SSL_SESSION_get_version returns a string describing the TLS or DTLS version +// |session| was established at. For example, "TLSv1.2" or "SSLv3". +OPENSSL_EXPORT const char *SSL_SESSION_get_version(const SSL_SESSION *session); + +// SSL_SESSION_get_protocol_version returns the TLS or DTLS version |session| +// was established at. +OPENSSL_EXPORT uint16_t +SSL_SESSION_get_protocol_version(const SSL_SESSION *session); + +// SSL_SESSION_set_protocol_version sets |session|'s TLS or DTLS version to +// |version|. This may be useful when writing tests but should otherwise not be +// used. It returns one on success and zero on error. +OPENSSL_EXPORT int SSL_SESSION_set_protocol_version(SSL_SESSION *session, + uint16_t version); + +// SSL_SESSION_get_id returns a pointer to a buffer containing |session|'s +// session ID and sets |*out_len| to its length. +OPENSSL_EXPORT const uint8_t *SSL_SESSION_get_id(const SSL_SESSION *session, + unsigned *out_len); + +// SSL_SESSION_get_time returns the time at which |session| was established in +// seconds since the UNIX epoch. +OPENSSL_EXPORT uint64_t SSL_SESSION_get_time(const SSL_SESSION *session); + +// SSL_SESSION_get_timeout returns the lifetime of |session| in seconds. +OPENSSL_EXPORT uint32_t SSL_SESSION_get_timeout(const SSL_SESSION *session); + +// SSL_SESSION_get0_peer returns the peer leaf certificate stored in +// |session|. +// +// TODO(davidben): This should return a const X509 *. +OPENSSL_EXPORT X509 *SSL_SESSION_get0_peer(const SSL_SESSION *session); + +// SSL_SESSION_get_master_key writes up to |max_out| bytes of |session|'s master +// secret to |out| and returns the number of bytes written. If |max_out| is +// zero, it returns the size of the master secret. +OPENSSL_EXPORT size_t SSL_SESSION_get_master_key(const SSL_SESSION *session, + uint8_t *out, size_t max_out); + +// SSL_SESSION_set_time sets |session|'s creation time to |time| and returns +// |time|. This function may be useful in writing tests but otherwise should not +// be used. +OPENSSL_EXPORT uint64_t SSL_SESSION_set_time(SSL_SESSION *session, + uint64_t time); + +// SSL_SESSION_set_timeout sets |session|'s timeout to |timeout| and returns +// one. This function may be useful in writing tests but otherwise should not +// be used. +OPENSSL_EXPORT uint32_t SSL_SESSION_set_timeout(SSL_SESSION *session, + uint32_t timeout); + +// SSL_SESSION_set1_id_context sets |session|'s session ID context (see +// |SSL_CTX_set_session_id_context|) to |sid_ctx|. It returns one on success and +// zero on error. This function may be useful in writing tests but otherwise +// should not be used. +OPENSSL_EXPORT int SSL_SESSION_set1_id_context(SSL_SESSION *session, + const uint8_t *sid_ctx, + size_t sid_ctx_len); + +// SSL_SESSION_should_be_single_use returns one if |session| should be +// single-use (TLS 1.3 and later) and zero otherwise. +// +// If this function returns one, clients retain multiple sessions and use each +// only once. This prevents passive observers from correlating connections with +// tickets. See draft-ietf-tls-tls13-18, appendix B.5. If it returns zero, +// |session| cannot be used without leaking a correlator. +OPENSSL_EXPORT int SSL_SESSION_should_be_single_use(const SSL_SESSION *session); + +// SSL_SESSION_is_resumable returns one if |session| is resumable and zero +// otherwise. +OPENSSL_EXPORT int SSL_SESSION_is_resumable(const SSL_SESSION *session); + +// SSL_SESSION_has_ticket returns one if |session| has a ticket and zero +// otherwise. +OPENSSL_EXPORT int SSL_SESSION_has_ticket(const SSL_SESSION *session); + +// SSL_SESSION_get0_ticket sets |*out_ticket| and |*out_len| to |session|'s +// ticket, or NULL and zero if it does not have one. |out_ticket| may be NULL +// if only the ticket length is needed. +OPENSSL_EXPORT void SSL_SESSION_get0_ticket(const SSL_SESSION *session, + const uint8_t **out_ticket, + size_t *out_len); + +// SSL_SESSION_get_ticket_lifetime_hint returns ticket lifetime hint of +// |session| in seconds or zero if none was set. +OPENSSL_EXPORT uint32_t +SSL_SESSION_get_ticket_lifetime_hint(const SSL_SESSION *session); + + +// Session caching. +// +// Session caching allows connections to be established more efficiently based +// on saved parameters from a previous connection, called a session (see +// |SSL_SESSION|). The client offers a saved session, using an opaque identifier +// from a previous connection. The server may accept the session, if it has the +// parameters available. Otherwise, it will decline and continue with a full +// handshake. +// +// This requires both the client and the server to retain session state. A +// client does so with a stateful session cache. A server may do the same or, if +// supported by both sides, statelessly using session tickets. For more +// information on the latter, see the next section. +// +// For a server, the library implements a built-in internal session cache as an +// in-memory hash table. Servers may also use |SSL_CTX_sess_set_get_cb| and +// |SSL_CTX_sess_set_new_cb| to implement a custom external session cache. In +// particular, this may be used to share a session cache between multiple +// servers in a large deployment. An external cache may be used in addition to +// or instead of the internal one. Use |SSL_CTX_set_session_cache_mode| to +// toggle the internal cache. +// +// For a client, the only option is an external session cache. Clients may use +// |SSL_CTX_sess_set_new_cb| to register a callback for when new sessions are +// available. These may be cached and, in subsequent compatible connections, +// configured with |SSL_set_session|. +// +// Note that offering or accepting a session short-circuits certificate +// verification and most parameter negotiation. Resuming sessions across +// different contexts may result in security failures and surprising +// behavior. For a typical client, this means sessions for different hosts must +// be cached under different keys. A client that connects to the same host with, +// e.g., different cipher suite settings or client certificates should also use +// separate session caches between those contexts. Servers should also partition +// session caches between SNI hosts with |SSL_CTX_set_session_id_context|. +// +// Note also, in TLS 1.2 and earlier, offering sessions allows passive observers +// to correlate different client connections. TLS 1.3 and later fix this, +// provided clients use sessions at most once. Session caches are managed by the +// caller in BoringSSL, so this must be implemented externally. See +// |SSL_SESSION_should_be_single_use| for details. + +// SSL_SESS_CACHE_OFF disables all session caching. +#define SSL_SESS_CACHE_OFF 0x0000 + +// SSL_SESS_CACHE_CLIENT enables session caching for a client. The internal +// cache is never used on a client, so this only enables the callbacks. +#define SSL_SESS_CACHE_CLIENT 0x0001 + +// SSL_SESS_CACHE_SERVER enables session caching for a server. +#define SSL_SESS_CACHE_SERVER 0x0002 + +// SSL_SESS_CACHE_BOTH enables session caching for both client and server. +#define SSL_SESS_CACHE_BOTH (SSL_SESS_CACHE_CLIENT | SSL_SESS_CACHE_SERVER) + +// SSL_SESS_CACHE_NO_AUTO_CLEAR disables automatically calling +// |SSL_CTX_flush_sessions| every 255 connections. +#define SSL_SESS_CACHE_NO_AUTO_CLEAR 0x0080 + +// SSL_SESS_CACHE_NO_INTERNAL_LOOKUP, on a server, disables looking up a session +// from the internal session cache. +#define SSL_SESS_CACHE_NO_INTERNAL_LOOKUP 0x0100 + +// SSL_SESS_CACHE_NO_INTERNAL_STORE, on a server, disables storing sessions in +// the internal session cache. +#define SSL_SESS_CACHE_NO_INTERNAL_STORE 0x0200 + +// SSL_SESS_CACHE_NO_INTERNAL, on a server, disables the internal session +// cache. +#define SSL_SESS_CACHE_NO_INTERNAL \ + (SSL_SESS_CACHE_NO_INTERNAL_LOOKUP | SSL_SESS_CACHE_NO_INTERNAL_STORE) + +// SSL_CTX_set_session_cache_mode sets the session cache mode bits for |ctx| to +// |mode|. It returns the previous value. +OPENSSL_EXPORT int SSL_CTX_set_session_cache_mode(SSL_CTX *ctx, int mode); + +// SSL_CTX_get_session_cache_mode returns the session cache mode bits for +// |ctx| +OPENSSL_EXPORT int SSL_CTX_get_session_cache_mode(const SSL_CTX *ctx); + +// SSL_set_session, for a client, configures |ssl| to offer to resume |session| +// in the initial handshake and returns one. The caller retains ownership of +// |session|. +// +// It is an error to call this function after the handshake has begun. +OPENSSL_EXPORT int SSL_set_session(SSL *ssl, SSL_SESSION *session); + +// SSL_DEFAULT_SESSION_TIMEOUT is the default lifetime, in seconds, of a +// session in TLS 1.2 or earlier. This is how long we are willing to use the +// secret to encrypt traffic without fresh key material. +#define SSL_DEFAULT_SESSION_TIMEOUT (2 * 60 * 60) + +// SSL_DEFAULT_SESSION_PSK_DHE_TIMEOUT is the default lifetime, in seconds, of a +// session for TLS 1.3 psk_dhe_ke. This is how long we are willing to use the +// secret as an authenticator. +#define SSL_DEFAULT_SESSION_PSK_DHE_TIMEOUT (2 * 24 * 60 * 60) + +// SSL_DEFAULT_SESSION_AUTH_TIMEOUT is the default non-renewable lifetime, in +// seconds, of a TLS 1.3 session. This is how long we are willing to trust the +// signature in the initial handshake. +#define SSL_DEFAULT_SESSION_AUTH_TIMEOUT (7 * 24 * 60 * 60) + +// SSL_CTX_set_timeout sets the lifetime, in seconds, of TLS 1.2 (or earlier) +// sessions created in |ctx| to |timeout|. +OPENSSL_EXPORT uint32_t SSL_CTX_set_timeout(SSL_CTX *ctx, uint32_t timeout); + +// SSL_CTX_set_session_psk_dhe_timeout sets the lifetime, in seconds, of TLS 1.3 +// sessions created in |ctx| to |timeout|. +OPENSSL_EXPORT void SSL_CTX_set_session_psk_dhe_timeout(SSL_CTX *ctx, + uint32_t timeout); + +// SSL_CTX_get_timeout returns the lifetime, in seconds, of TLS 1.2 (or earlier) +// sessions created in |ctx|. +OPENSSL_EXPORT uint32_t SSL_CTX_get_timeout(const SSL_CTX *ctx); + +// SSL_CTX_set_session_id_context sets |ctx|'s session ID context to |sid_ctx|. +// It returns one on success and zero on error. The session ID context is an +// application-defined opaque byte string. A session will not be used in a +// connection without a matching session ID context. +// +// For a server, if |SSL_VERIFY_PEER| is enabled, it is an error to not set a +// session ID context. +OPENSSL_EXPORT int SSL_CTX_set_session_id_context(SSL_CTX *ctx, + const uint8_t *sid_ctx, + size_t sid_ctx_len); + +// SSL_set_session_id_context sets |ssl|'s session ID context to |sid_ctx|. It +// returns one on success and zero on error. See also +// |SSL_CTX_set_session_id_context|. +OPENSSL_EXPORT int SSL_set_session_id_context(SSL *ssl, const uint8_t *sid_ctx, + size_t sid_ctx_len); + +// SSL_get0_session_id_context returns a pointer to |ssl|'s session ID context +// and sets |*out_len| to its length. +OPENSSL_EXPORT const uint8_t *SSL_get0_session_id_context(const SSL *ssl, + size_t *out_len); + +// SSL_SESSION_CACHE_MAX_SIZE_DEFAULT is the default maximum size of a session +// cache. +#define SSL_SESSION_CACHE_MAX_SIZE_DEFAULT (1024 * 20) + +// SSL_CTX_sess_set_cache_size sets the maximum size of |ctx|'s internal session +// cache to |size|. It returns the previous value. +OPENSSL_EXPORT unsigned long SSL_CTX_sess_set_cache_size(SSL_CTX *ctx, + unsigned long size); + +// SSL_CTX_sess_get_cache_size returns the maximum size of |ctx|'s internal +// session cache. +OPENSSL_EXPORT unsigned long SSL_CTX_sess_get_cache_size(const SSL_CTX *ctx); + +// SSL_CTX_sess_number returns the number of sessions in |ctx|'s internal +// session cache. +OPENSSL_EXPORT size_t SSL_CTX_sess_number(const SSL_CTX *ctx); + +// SSL_CTX_add_session inserts |session| into |ctx|'s internal session cache. It +// returns one on success and zero on error or if |session| is already in the +// cache. The caller retains its reference to |session|. +OPENSSL_EXPORT int SSL_CTX_add_session(SSL_CTX *ctx, SSL_SESSION *session); + +// SSL_CTX_remove_session removes |session| from |ctx|'s internal session cache. +// It returns one on success and zero if |session| was not in the cache. +OPENSSL_EXPORT int SSL_CTX_remove_session(SSL_CTX *ctx, SSL_SESSION *session); + +// SSL_CTX_flush_sessions removes all sessions from |ctx| which have expired as +// of time |time|. If |time| is zero, all sessions are removed. +OPENSSL_EXPORT void SSL_CTX_flush_sessions(SSL_CTX *ctx, uint64_t time); + +// SSL_CTX_sess_set_new_cb sets the callback to be called when a new session is +// established and ready to be cached. If the session cache is disabled (the +// appropriate one of |SSL_SESS_CACHE_CLIENT| or |SSL_SESS_CACHE_SERVER| is +// unset), the callback is not called. +// +// The callback is passed a reference to |session|. It returns one if it takes +// ownership (and then calls |SSL_SESSION_free| when done) and zero otherwise. A +// consumer which places |session| into an in-memory cache will likely return +// one, with the cache calling |SSL_SESSION_free|. A consumer which serializes +// |session| with |SSL_SESSION_to_bytes| may not need to retain |session| and +// will likely return zero. Returning one is equivalent to calling +// |SSL_SESSION_up_ref| and then returning zero. +// +// Note: For a client, the callback may be called on abbreviated handshakes if a +// ticket is renewed. Further, it may not be called until some time after +// |SSL_do_handshake| or |SSL_connect| completes if False Start is enabled. Thus +// it's recommended to use this callback over calling |SSL_get_session| on +// handshake completion. +OPENSSL_EXPORT void SSL_CTX_sess_set_new_cb( + SSL_CTX *ctx, int (*new_session_cb)(SSL *ssl, SSL_SESSION *session)); + +// SSL_CTX_sess_get_new_cb returns the callback set by +// |SSL_CTX_sess_set_new_cb|. +OPENSSL_EXPORT int (*SSL_CTX_sess_get_new_cb(SSL_CTX *ctx))( + SSL *ssl, SSL_SESSION *session); + +// SSL_CTX_sess_set_remove_cb sets a callback which is called when a session is +// removed from the internal session cache. +// +// TODO(davidben): What is the point of this callback? It seems useless since it +// only fires on sessions in the internal cache. +OPENSSL_EXPORT void SSL_CTX_sess_set_remove_cb( + SSL_CTX *ctx, + void (*remove_session_cb)(SSL_CTX *ctx, SSL_SESSION *session)); + +// SSL_CTX_sess_get_remove_cb returns the callback set by +// |SSL_CTX_sess_set_remove_cb|. +OPENSSL_EXPORT void (*SSL_CTX_sess_get_remove_cb(SSL_CTX *ctx))( + SSL_CTX *ctx, SSL_SESSION *session); + +// SSL_CTX_sess_set_get_cb sets a callback to look up a session by ID for a +// server. The callback is passed the session ID and should return a matching +// |SSL_SESSION| or NULL if not found. It should set |*out_copy| to zero and +// return a new reference to the session. This callback is not used for a +// client. +// +// For historical reasons, if |*out_copy| is set to one (default), the SSL +// library will take a new reference to the returned |SSL_SESSION|, expecting +// the callback to return a non-owning pointer. This is not recommended. If +// |ctx| and thus the callback is used on multiple threads, the session may be +// removed and invalidated before the SSL library calls |SSL_SESSION_up_ref|, +// whereas the callback may synchronize internally. +// +// To look up a session asynchronously, the callback may return +// |SSL_magic_pending_session_ptr|. See the documentation for that function and +// |SSL_ERROR_PENDING_SESSION|. +// +// If the internal session cache is enabled, the callback is only consulted if +// the internal cache does not return a match. +OPENSSL_EXPORT void SSL_CTX_sess_set_get_cb( + SSL_CTX *ctx, SSL_SESSION *(*get_session_cb)(SSL *ssl, const uint8_t *id, + int id_len, int *out_copy)); + +// SSL_CTX_sess_get_get_cb returns the callback set by +// |SSL_CTX_sess_set_get_cb|. +OPENSSL_EXPORT SSL_SESSION *(*SSL_CTX_sess_get_get_cb(SSL_CTX *ctx))( + SSL *ssl, const uint8_t *id, int id_len, int *out_copy); + +// SSL_magic_pending_session_ptr returns a magic |SSL_SESSION|* which indicates +// that the session isn't currently unavailable. |SSL_get_error| will then +// return |SSL_ERROR_PENDING_SESSION| and the handshake can be retried later +// when the lookup has completed. +OPENSSL_EXPORT SSL_SESSION *SSL_magic_pending_session_ptr(void); + + +// Session tickets. +// +// Session tickets, from RFC 5077, allow session resumption without server-side +// state. The server maintains a secret ticket key and sends the client opaque +// encrypted session parameters, called a ticket. When offering the session, the +// client sends the ticket which the server decrypts to recover session state. +// Session tickets are enabled by default but may be disabled with +// |SSL_OP_NO_TICKET|. +// +// On the client, ticket-based sessions use the same APIs as ID-based tickets. +// Callers do not need to handle them differently. +// +// On the server, tickets are encrypted and authenticated with a secret key. By +// default, an |SSL_CTX| generates a key on creation and uses it for the +// lifetime of the |SSL_CTX|. Tickets are minted and processed +// transparently. The following functions may be used to configure a persistent +// key or implement more custom behavior, including key rotation and sharing +// keys between multiple servers in a large deployment. There are three levels +// of customisation possible: +// +// 1) One can simply set the keys with |SSL_CTX_set_tlsext_ticket_keys|. +// 2) One can configure an |EVP_CIPHER_CTX| and |HMAC_CTX| directly for +// encryption and authentication. +// 3) One can configure an |SSL_TICKET_AEAD_METHOD| to have more control +// and the option of asynchronous decryption. +// +// An attacker that compromises a server's session ticket key can impersonate +// the server and, prior to TLS 1.3, retroactively decrypt all application +// traffic from sessions using that ticket key. Thus ticket keys must be +// regularly rotated for forward secrecy. Note the default key is rotated +// automatically once every 48 hours but manually configured keys are not. + +// SSL_DEFAULT_TICKET_KEY_ROTATION_INTERVAL is the interval with which the +// default session ticket encryption key is rotated, if in use. If any +// non-default ticket encryption mechanism is configured, automatic rotation is +// disabled. +#define SSL_DEFAULT_TICKET_KEY_ROTATION_INTERVAL (2 * 24 * 60 * 60) + +// SSL_CTX_get_tlsext_ticket_keys writes |ctx|'s session ticket key material to +// |len| bytes of |out|. It returns one on success and zero if |len| is not +// 48. If |out| is NULL, it returns 48 instead. +OPENSSL_EXPORT int SSL_CTX_get_tlsext_ticket_keys(SSL_CTX *ctx, void *out, + size_t len); + +// SSL_CTX_set_tlsext_ticket_keys sets |ctx|'s session ticket key material to +// |len| bytes of |in|. It returns one on success and zero if |len| is not +// 48. If |in| is NULL, it returns 48 instead. +OPENSSL_EXPORT int SSL_CTX_set_tlsext_ticket_keys(SSL_CTX *ctx, const void *in, + size_t len); + +// SSL_TICKET_KEY_NAME_LEN is the length of the key name prefix of a session +// ticket. +#define SSL_TICKET_KEY_NAME_LEN 16 + +// SSL_CTX_set_tlsext_ticket_key_cb sets the ticket callback to |callback| and +// returns one. |callback| will be called when encrypting a new ticket and when +// decrypting a ticket from the client. +// +// In both modes, |ctx| and |hmac_ctx| will already have been initialized with +// |EVP_CIPHER_CTX_init| and |HMAC_CTX_init|, respectively. |callback| +// configures |hmac_ctx| with an HMAC digest and key, and configures |ctx| +// for encryption or decryption, based on the mode. +// +// When encrypting a new ticket, |encrypt| will be one. It writes a public +// 16-byte key name to |key_name| and a fresh IV to |iv|. The output IV length +// must match |EVP_CIPHER_CTX_iv_length| of the cipher selected. In this mode, +// |callback| returns 1 on success and -1 on error. +// +// When decrypting a ticket, |encrypt| will be zero. |key_name| will point to a +// 16-byte key name and |iv| points to an IV. The length of the IV consumed must +// match |EVP_CIPHER_CTX_iv_length| of the cipher selected. In this mode, +// |callback| returns -1 to abort the handshake, 0 if decrypting the ticket +// failed, and 1 or 2 on success. If it returns 2, the ticket will be renewed. +// This may be used to re-key the ticket. +// +// WARNING: |callback| wildly breaks the usual return value convention and is +// called in two different modes. +OPENSSL_EXPORT int SSL_CTX_set_tlsext_ticket_key_cb( + SSL_CTX *ctx, int (*callback)(SSL *ssl, uint8_t *key_name, uint8_t *iv, + EVP_CIPHER_CTX *ctx, HMAC_CTX *hmac_ctx, + int encrypt)); + +// ssl_ticket_aead_result_t enumerates the possible results from decrypting a +// ticket with an |SSL_TICKET_AEAD_METHOD|. +enum ssl_ticket_aead_result_t { + // ssl_ticket_aead_success indicates that the ticket was successfully + // decrypted. + ssl_ticket_aead_success, + // ssl_ticket_aead_retry indicates that the operation could not be + // immediately completed and must be reattempted, via |open|, at a later + // point. + ssl_ticket_aead_retry, + // ssl_ticket_aead_ignore_ticket indicates that the ticket should be ignored + // (i.e. is corrupt or otherwise undecryptable). + ssl_ticket_aead_ignore_ticket, + // ssl_ticket_aead_error indicates that a fatal error occured and the + // handshake should be terminated. + ssl_ticket_aead_error, +}; + +// ssl_ticket_aead_method_st (aka |SSL_TICKET_AEAD_METHOD|) contains methods +// for encrypting and decrypting session tickets. +struct ssl_ticket_aead_method_st { + // max_overhead returns the maximum number of bytes of overhead that |seal| + // may add. + size_t (*max_overhead)(SSL *ssl); + + // seal encrypts and authenticates |in_len| bytes from |in|, writes, at most, + // |max_out_len| bytes to |out|, and puts the number of bytes written in + // |*out_len|. The |in| and |out| buffers may be equal but will not otherwise + // alias. It returns one on success or zero on error. + int (*seal)(SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out_len, + const uint8_t *in, size_t in_len); + + // open authenticates and decrypts |in_len| bytes from |in|, writes, at most, + // |max_out_len| bytes of plaintext to |out|, and puts the number of bytes + // written in |*out_len|. The |in| and |out| buffers may be equal but will + // not otherwise alias. See |ssl_ticket_aead_result_t| for details of the + // return values. In the case that a retry is indicated, the caller should + // arrange for the high-level operation on |ssl| to be retried when the + // operation is completed, which will result in another call to |open|. + enum ssl_ticket_aead_result_t (*open)(SSL *ssl, uint8_t *out, size_t *out_len, + size_t max_out_len, const uint8_t *in, + size_t in_len); +}; + +// SSL_CTX_set_ticket_aead_method configures a custom ticket AEAD method table +// on |ctx|. |aead_method| must remain valid for the lifetime of |ctx|. +OPENSSL_EXPORT void SSL_CTX_set_ticket_aead_method( + SSL_CTX *ctx, const SSL_TICKET_AEAD_METHOD *aead_method); + + +// Elliptic curve Diffie-Hellman. +// +// Cipher suites using an ECDHE key exchange perform Diffie-Hellman over an +// elliptic curve negotiated by both endpoints. See RFC 4492. Only named curves +// are supported. ECDHE is always enabled, but the curve preferences may be +// configured with these functions. +// +// Note that TLS 1.3 renames these from curves to groups. For consistency, we +// currently use the TLS 1.2 name in the API. + +// SSL_CTX_set1_curves sets the preferred curves for |ctx| to be |curves|. Each +// element of |curves| should be a curve nid. It returns one on success and +// zero on failure. +// +// Note that this API uses nid values from nid.h and not the |SSL_CURVE_*| +// values defined below. +OPENSSL_EXPORT int SSL_CTX_set1_curves(SSL_CTX *ctx, const int *curves, + size_t curves_len); + +// SSL_set1_curves sets the preferred curves for |ssl| to be |curves|. Each +// element of |curves| should be a curve nid. It returns one on success and +// zero on failure. +// +// Note that this API uses nid values from nid.h and not the |SSL_CURVE_*| +// values defined below. +OPENSSL_EXPORT int SSL_set1_curves(SSL *ssl, const int *curves, + size_t curves_len); + +// SSL_CTX_set1_curves_list sets the preferred curves for |ctx| to be the +// colon-separated list |curves|. Each element of |curves| should be a curve +// name (e.g. P-256, X25519, ...). It returns one on success and zero on +// failure. +OPENSSL_EXPORT int SSL_CTX_set1_curves_list(SSL_CTX *ctx, const char *curves); + +// SSL_set1_curves_list sets the preferred curves for |ssl| to be the +// colon-separated list |curves|. Each element of |curves| should be a curve +// name (e.g. P-256, X25519, ...). It returns one on success and zero on +// failure. +OPENSSL_EXPORT int SSL_set1_curves_list(SSL *ssl, const char *curves); + +// SSL_CURVE_* define TLS curve IDs. +#define SSL_CURVE_SECP224R1 21 +#define SSL_CURVE_SECP256R1 23 +#define SSL_CURVE_SECP384R1 24 +#define SSL_CURVE_SECP521R1 25 +#define SSL_CURVE_X25519 29 + +// SSL_get_curve_id returns the ID of the curve used by |ssl|'s most recently +// completed handshake or 0 if not applicable. +// +// TODO(davidben): This API currently does not work correctly if there is a +// renegotiation in progress. Fix this. +OPENSSL_EXPORT uint16_t SSL_get_curve_id(const SSL *ssl); + +// SSL_get_curve_name returns a human-readable name for the curve specified by +// the given TLS curve id, or NULL if the curve is unknown. +OPENSSL_EXPORT const char *SSL_get_curve_name(uint16_t curve_id); + + +// Certificate verification. +// +// SSL may authenticate either endpoint with an X.509 certificate. Typically +// this is used to authenticate the server to the client. These functions +// configure certificate verification. +// +// WARNING: By default, certificate verification errors on a client are not +// fatal. See |SSL_VERIFY_NONE| This may be configured with +// |SSL_CTX_set_verify|. +// +// By default clients are anonymous but a server may request a certificate from +// the client by setting |SSL_VERIFY_PEER|. +// +// Many of these functions use OpenSSL's legacy X.509 stack which is +// underdocumented and deprecated, but the replacement isn't ready yet. For +// now, consumers may use the existing stack or bypass it by performing +// certificate verification externally. This may be done with +// |SSL_CTX_set_cert_verify_callback| or by extracting the chain with +// |SSL_get_peer_cert_chain| after the handshake. In the future, functions will +// be added to use the SSL stack without dependency on any part of the legacy +// X.509 and ASN.1 stack. +// +// To augment certificate verification, a client may also enable OCSP stapling +// (RFC 6066) and Certificate Transparency (RFC 6962) extensions. + +// SSL_VERIFY_NONE, on a client, verifies the server certificate but does not +// make errors fatal. The result may be checked with |SSL_get_verify_result|. On +// a server it does not request a client certificate. This is the default. +#define SSL_VERIFY_NONE 0x00 + +// SSL_VERIFY_PEER, on a client, makes server certificate errors fatal. On a +// server it requests a client certificate and makes errors fatal. However, +// anonymous clients are still allowed. See +// |SSL_VERIFY_FAIL_IF_NO_PEER_CERT|. +#define SSL_VERIFY_PEER 0x01 + +// SSL_VERIFY_FAIL_IF_NO_PEER_CERT configures a server to reject connections if +// the client declines to send a certificate. This flag must be used together +// with |SSL_VERIFY_PEER|, otherwise it won't work. +#define SSL_VERIFY_FAIL_IF_NO_PEER_CERT 0x02 + +// SSL_VERIFY_PEER_IF_NO_OBC configures a server to request a client certificate +// if and only if Channel ID is not negotiated. +#define SSL_VERIFY_PEER_IF_NO_OBC 0x04 + +// SSL_CTX_set_verify configures certificate verification behavior. |mode| is +// one of the |SSL_VERIFY_*| values defined above. |callback|, if not NULL, is +// used to customize certificate verification. See the behavior of +// |X509_STORE_CTX_set_verify_cb|. +// +// The callback may use |SSL_get_ex_data_X509_STORE_CTX_idx| with +// |X509_STORE_CTX_get_ex_data| to look up the |SSL| from |store_ctx|. +OPENSSL_EXPORT void SSL_CTX_set_verify( + SSL_CTX *ctx, int mode, int (*callback)(int ok, X509_STORE_CTX *store_ctx)); + +// SSL_set_verify configures certificate verification behavior. |mode| is one of +// the |SSL_VERIFY_*| values defined above. |callback|, if not NULL, is used to +// customize certificate verification. See the behavior of +// |X509_STORE_CTX_set_verify_cb|. +// +// The callback may use |SSL_get_ex_data_X509_STORE_CTX_idx| with +// |X509_STORE_CTX_get_ex_data| to look up the |SSL| from |store_ctx|. +OPENSSL_EXPORT void SSL_set_verify(SSL *ssl, int mode, + int (*callback)(int ok, + X509_STORE_CTX *store_ctx)); + +enum ssl_verify_result_t { + ssl_verify_ok, + ssl_verify_invalid, + ssl_verify_retry, +}; + +// SSL_CTX_set_custom_verify configures certificate verification. |mode| is one +// of the |SSL_VERIFY_*| values defined above. |callback| performs the +// certificate verification. +// +// The callback may call |SSL_get0_peer_certificates| for the certificate chain +// to validate. The callback should return |ssl_verify_ok| if the certificate is +// valid. If the certificate is invalid, the callback should return +// |ssl_verify_invalid| and optionally set |*out_alert| to an alert to send to +// the peer. Some useful alerts include |SSL_AD_CERTIFICATE_EXPIRED|, +// |SSL_AD_CERTIFICATE_REVOKED|, |SSL_AD_UNKNOWN_CA|, |SSL_AD_BAD_CERTIFICATE|, +// |SSL_AD_CERTIFICATE_UNKNOWN|, and |SSL_AD_INTERNAL_ERROR|. See RFC 5246 +// section 7.2.2 for their precise meanings. If unspecified, +// |SSL_AD_CERTIFICATE_UNKNOWN| will be sent by default. +// +// To verify a certificate asynchronously, the callback may return +// |ssl_verify_retry|. The handshake will then pause with |SSL_get_error| +// returning |SSL_ERROR_WANT_CERTIFICATE_VERIFY|. +OPENSSL_EXPORT void SSL_CTX_set_custom_verify( + SSL_CTX *ctx, int mode, + enum ssl_verify_result_t (*callback)(SSL *ssl, uint8_t *out_alert)); + +// SSL_set_custom_verify behaves like |SSL_CTX_set_custom_verify| but configures +// an individual |SSL|. +OPENSSL_EXPORT void SSL_set_custom_verify( + SSL *ssl, int mode, + enum ssl_verify_result_t (*callback)(SSL *ssl, uint8_t *out_alert)); + +// SSL_CTX_get_verify_mode returns |ctx|'s verify mode, set by +// |SSL_CTX_set_verify|. +OPENSSL_EXPORT int SSL_CTX_get_verify_mode(const SSL_CTX *ctx); + +// SSL_get_verify_mode returns |ssl|'s verify mode, set by |SSL_CTX_set_verify| +// or |SSL_set_verify|. +OPENSSL_EXPORT int SSL_get_verify_mode(const SSL *ssl); + +// SSL_CTX_get_verify_callback returns the callback set by +// |SSL_CTX_set_verify|. +OPENSSL_EXPORT int (*SSL_CTX_get_verify_callback(const SSL_CTX *ctx))( + int ok, X509_STORE_CTX *store_ctx); + +// SSL_get_verify_callback returns the callback set by |SSL_CTX_set_verify| or +// |SSL_set_verify|. +OPENSSL_EXPORT int (*SSL_get_verify_callback(const SSL *ssl))( + int ok, X509_STORE_CTX *store_ctx); + +// SSL_CTX_set_verify_depth sets the maximum depth of a certificate chain +// accepted in verification. This number does not include the leaf, so a depth +// of 1 allows the leaf and one CA certificate. +OPENSSL_EXPORT void SSL_CTX_set_verify_depth(SSL_CTX *ctx, int depth); + +// SSL_set_verify_depth sets the maximum depth of a certificate chain accepted +// in verification. This number does not include the leaf, so a depth of 1 +// allows the leaf and one CA certificate. +OPENSSL_EXPORT void SSL_set_verify_depth(SSL *ssl, int depth); + +// SSL_CTX_get_verify_depth returns the maximum depth of a certificate accepted +// in verification. +OPENSSL_EXPORT int SSL_CTX_get_verify_depth(const SSL_CTX *ctx); + +// SSL_get_verify_depth returns the maximum depth of a certificate accepted in +// verification. +OPENSSL_EXPORT int SSL_get_verify_depth(const SSL *ssl); + +// SSL_CTX_set1_param sets verification parameters from |param|. It returns one +// on success and zero on failure. The caller retains ownership of |param|. +OPENSSL_EXPORT int SSL_CTX_set1_param(SSL_CTX *ctx, + const X509_VERIFY_PARAM *param); + +// SSL_set1_param sets verification parameters from |param|. It returns one on +// success and zero on failure. The caller retains ownership of |param|. +OPENSSL_EXPORT int SSL_set1_param(SSL *ssl, + const X509_VERIFY_PARAM *param); + +// SSL_CTX_get0_param returns |ctx|'s |X509_VERIFY_PARAM| for certificate +// verification. The caller must not release the returned pointer but may call +// functions on it to configure it. +OPENSSL_EXPORT X509_VERIFY_PARAM *SSL_CTX_get0_param(SSL_CTX *ctx); + +// SSL_get0_param returns |ssl|'s |X509_VERIFY_PARAM| for certificate +// verification. The caller must not release the returned pointer but may call +// functions on it to configure it. +OPENSSL_EXPORT X509_VERIFY_PARAM *SSL_get0_param(SSL *ssl); + +// SSL_CTX_set_purpose sets |ctx|'s |X509_VERIFY_PARAM|'s 'purpose' parameter to +// |purpose|. It returns one on success and zero on error. +OPENSSL_EXPORT int SSL_CTX_set_purpose(SSL_CTX *ctx, int purpose); + +// SSL_set_purpose sets |ssl|'s |X509_VERIFY_PARAM|'s 'purpose' parameter to +// |purpose|. It returns one on success and zero on error. +OPENSSL_EXPORT int SSL_set_purpose(SSL *ssl, int purpose); + +// SSL_CTX_set_trust sets |ctx|'s |X509_VERIFY_PARAM|'s 'trust' parameter to +// |trust|. It returns one on success and zero on error. +OPENSSL_EXPORT int SSL_CTX_set_trust(SSL_CTX *ctx, int trust); + +// SSL_set_trust sets |ssl|'s |X509_VERIFY_PARAM|'s 'trust' parameter to +// |trust|. It returns one on success and zero on error. +OPENSSL_EXPORT int SSL_set_trust(SSL *ssl, int trust); + +// SSL_CTX_set_cert_store sets |ctx|'s certificate store to |store|. It takes +// ownership of |store|. The store is used for certificate verification. +// +// The store is also used for the auto-chaining feature, but this is deprecated. +// See also |SSL_MODE_NO_AUTO_CHAIN|. +OPENSSL_EXPORT void SSL_CTX_set_cert_store(SSL_CTX *ctx, X509_STORE *store); + +// SSL_CTX_get_cert_store returns |ctx|'s certificate store. +OPENSSL_EXPORT X509_STORE *SSL_CTX_get_cert_store(const SSL_CTX *ctx); + +// SSL_CTX_set_default_verify_paths loads the OpenSSL system-default trust +// anchors into |ctx|'s store. It returns one on success and zero on failure. +OPENSSL_EXPORT int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx); + +// SSL_CTX_load_verify_locations loads trust anchors into |ctx|'s store from +// |ca_file| and |ca_dir|, either of which may be NULL. If |ca_file| is passed, +// it is opened and PEM-encoded CA certificates are read. If |ca_dir| is passed, +// it is treated as a directory in OpenSSL's hashed directory format. It returns +// one on success and zero on failure. +// +// See +// https://www.openssl.org/docs/manmaster/ssl/SSL_CTX_load_verify_locations.html +// for documentation on the directory format. +OPENSSL_EXPORT int SSL_CTX_load_verify_locations(SSL_CTX *ctx, + const char *ca_file, + const char *ca_dir); + +// SSL_get_verify_result returns the result of certificate verification. It is +// either |X509_V_OK| or a |X509_V_ERR_*| value. +OPENSSL_EXPORT long SSL_get_verify_result(const SSL *ssl); + +// SSL_alert_from_verify_result returns the SSL alert code, such as +// |SSL_AD_CERTIFICATE_EXPIRED|, that corresponds to an |X509_V_ERR_*| value. +// The return value is always an alert, even when |result| is |X509_V_OK|. +OPENSSL_EXPORT int SSL_alert_from_verify_result(long result); + +// SSL_get_ex_data_X509_STORE_CTX_idx returns the ex_data index used to look up +// the |SSL| associated with an |X509_STORE_CTX| in the verify callback. +OPENSSL_EXPORT int SSL_get_ex_data_X509_STORE_CTX_idx(void); + +// SSL_CTX_set_cert_verify_callback sets a custom callback to be called on +// certificate verification rather than |X509_verify_cert|. |store_ctx| contains +// the verification parameters. The callback should return one on success and +// zero on fatal error. It may use |X509_STORE_CTX_set_error| to set a +// verification result. +// +// The callback may use |SSL_get_ex_data_X509_STORE_CTX_idx| to recover the +// |SSL| object from |store_ctx|. +OPENSSL_EXPORT void SSL_CTX_set_cert_verify_callback( + SSL_CTX *ctx, int (*callback)(X509_STORE_CTX *store_ctx, void *arg), + void *arg); + +// SSL_enable_signed_cert_timestamps causes |ssl| (which must be the client end +// of a connection) to request SCTs from the server. See +// https://tools.ietf.org/html/rfc6962. +// +// Call |SSL_get0_signed_cert_timestamp_list| to recover the SCT after the +// handshake. +OPENSSL_EXPORT void SSL_enable_signed_cert_timestamps(SSL *ssl); + +// SSL_CTX_enable_signed_cert_timestamps enables SCT requests on all client SSL +// objects created from |ctx|. +// +// Call |SSL_get0_signed_cert_timestamp_list| to recover the SCT after the +// handshake. +OPENSSL_EXPORT void SSL_CTX_enable_signed_cert_timestamps(SSL_CTX *ctx); + +// SSL_enable_ocsp_stapling causes |ssl| (which must be the client end of a +// connection) to request a stapled OCSP response from the server. +// +// Call |SSL_get0_ocsp_response| to recover the OCSP response after the +// handshake. +OPENSSL_EXPORT void SSL_enable_ocsp_stapling(SSL *ssl); + +// SSL_CTX_enable_ocsp_stapling enables OCSP stapling on all client SSL objects +// created from |ctx|. +// +// Call |SSL_get0_ocsp_response| to recover the OCSP response after the +// handshake. +OPENSSL_EXPORT void SSL_CTX_enable_ocsp_stapling(SSL_CTX *ctx); + +// SSL_CTX_set0_verify_cert_store sets an |X509_STORE| that will be used +// exclusively for certificate verification and returns one. Ownership of +// |store| is transferred to the |SSL_CTX|. +OPENSSL_EXPORT int SSL_CTX_set0_verify_cert_store(SSL_CTX *ctx, + X509_STORE *store); + +// SSL_CTX_set1_verify_cert_store sets an |X509_STORE| that will be used +// exclusively for certificate verification and returns one. An additional +// reference to |store| will be taken. +OPENSSL_EXPORT int SSL_CTX_set1_verify_cert_store(SSL_CTX *ctx, + X509_STORE *store); + +// SSL_set0_verify_cert_store sets an |X509_STORE| that will be used +// exclusively for certificate verification and returns one. Ownership of +// |store| is transferred to the |SSL|. +OPENSSL_EXPORT int SSL_set0_verify_cert_store(SSL *ssl, X509_STORE *store); + +// SSL_set1_verify_cert_store sets an |X509_STORE| that will be used +// exclusively for certificate verification and returns one. An additional +// reference to |store| will be taken. +OPENSSL_EXPORT int SSL_set1_verify_cert_store(SSL *ssl, X509_STORE *store); + +// SSL_CTX_set_ed25519_enabled configures whether |ctx| advertises support for +// the Ed25519 signature algorithm when using the default preference list. +OPENSSL_EXPORT void SSL_CTX_set_ed25519_enabled(SSL_CTX *ctx, int enabled); + +// SSL_CTX_set_verify_algorithm_prefs confingures |ctx| to use |prefs| as the +// preference list when verifying signature's from the peer's long-term key. It +// returns one on zero on error. |prefs| should not include the internal-only +// value |SSL_SIGN_RSA_PKCS1_MD5_SHA1|. +OPENSSL_EXPORT int SSL_CTX_set_verify_algorithm_prefs(SSL_CTX *ctx, + const uint16_t *prefs, + size_t num_prefs); + + +// Client certificate CA list. +// +// When requesting a client certificate, a server may advertise a list of +// certificate authorities which are accepted. These functions may be used to +// configure this list. + +// SSL_set_client_CA_list sets |ssl|'s client certificate CA list to +// |name_list|. It takes ownership of |name_list|. +OPENSSL_EXPORT void SSL_set_client_CA_list(SSL *ssl, + STACK_OF(X509_NAME) *name_list); + +// SSL_CTX_set_client_CA_list sets |ctx|'s client certificate CA list to +// |name_list|. It takes ownership of |name_list|. +OPENSSL_EXPORT void SSL_CTX_set_client_CA_list(SSL_CTX *ctx, + STACK_OF(X509_NAME) *name_list); + +// SSL_set0_client_CAs sets |ssl|'s client certificate CA list to |name_list|, +// which should contain DER-encoded distinguished names (RFC 5280). It takes +// ownership of |name_list|. +OPENSSL_EXPORT void SSL_set0_client_CAs(SSL *ssl, + STACK_OF(CRYPTO_BUFFER) *name_list); + +// SSL_CTX_set0_client_CAs sets |ctx|'s client certificate CA list to +// |name_list|, which should contain DER-encoded distinguished names (RFC 5280). +// It takes ownership of |name_list|. +OPENSSL_EXPORT void SSL_CTX_set0_client_CAs(SSL_CTX *ctx, + STACK_OF(CRYPTO_BUFFER) *name_list); + +// SSL_get_client_CA_list returns |ssl|'s client certificate CA list. If |ssl| +// has not been configured as a client, this is the list configured by +// |SSL_CTX_set_client_CA_list|. +// +// If configured as a client, it returns the client certificate CA list sent by +// the server. In this mode, the behavior is undefined except during the +// callbacks set by |SSL_CTX_set_cert_cb| and |SSL_CTX_set_client_cert_cb| or +// when the handshake is paused because of them. +OPENSSL_EXPORT STACK_OF(X509_NAME) *SSL_get_client_CA_list(const SSL *ssl); + +// SSL_get0_server_requested_CAs returns the CAs sent by a server to guide a +// client in certificate selection. They are a series of DER-encoded X.509 +// names. This function may only be called during a callback set by +// |SSL_CTX_set_cert_cb| or when the handshake is paused because of it. +// +// The returned stack is owned by |ssl|, as are its contents. It should not be +// used past the point where the handshake is restarted after the callback. +OPENSSL_EXPORT STACK_OF(CRYPTO_BUFFER) *SSL_get0_server_requested_CAs( + const SSL *ssl); + +// SSL_CTX_get_client_CA_list returns |ctx|'s client certificate CA list. +OPENSSL_EXPORT STACK_OF(X509_NAME) * + SSL_CTX_get_client_CA_list(const SSL_CTX *ctx); + +// SSL_add_client_CA appends |x509|'s subject to the client certificate CA list. +// It returns one on success or zero on error. The caller retains ownership of +// |x509|. +OPENSSL_EXPORT int SSL_add_client_CA(SSL *ssl, X509 *x509); + +// SSL_CTX_add_client_CA appends |x509|'s subject to the client certificate CA +// list. It returns one on success or zero on error. The caller retains +// ownership of |x509|. +OPENSSL_EXPORT int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x509); + +// SSL_load_client_CA_file opens |file| and reads PEM-encoded certificates from +// it. It returns a newly-allocated stack of the certificate subjects or NULL +// on error. +OPENSSL_EXPORT STACK_OF(X509_NAME) *SSL_load_client_CA_file(const char *file); + +// SSL_dup_CA_list makes a deep copy of |list|. It returns the new list on +// success or NULL on allocation error. +OPENSSL_EXPORT STACK_OF(X509_NAME) *SSL_dup_CA_list(STACK_OF(X509_NAME) *list); + +// SSL_add_file_cert_subjects_to_stack behaves like |SSL_load_client_CA_file| +// but appends the result to |out|. It returns one on success or zero on +// error. +OPENSSL_EXPORT int SSL_add_file_cert_subjects_to_stack(STACK_OF(X509_NAME) *out, + const char *file); + + +// Server name indication. +// +// The server_name extension (RFC 3546) allows the client to advertise the name +// of the server it is connecting to. This is used in virtual hosting +// deployments to select one of a several certificates on a single IP. Only the +// host_name name type is supported. + +#define TLSEXT_NAMETYPE_host_name 0 + +// SSL_set_tlsext_host_name, for a client, configures |ssl| to advertise |name| +// in the server_name extension. It returns one on success and zero on error. +OPENSSL_EXPORT int SSL_set_tlsext_host_name(SSL *ssl, const char *name); + +// SSL_get_servername, for a server, returns the hostname supplied by the +// client or NULL if there was none. The |type| argument must be +// |TLSEXT_NAMETYPE_host_name|. +OPENSSL_EXPORT const char *SSL_get_servername(const SSL *ssl, const int type); + +// SSL_get_servername_type, for a server, returns |TLSEXT_NAMETYPE_host_name| +// if the client sent a hostname and -1 otherwise. +OPENSSL_EXPORT int SSL_get_servername_type(const SSL *ssl); + +// SSL_CTX_set_tlsext_servername_callback configures |callback| to be called on +// the server after ClientHello extensions have been parsed and returns one. +// The callback may use |SSL_get_servername| to examine the server_name +// extension and returns a |SSL_TLSEXT_ERR_*| value. The value of |arg| may be +// set by calling |SSL_CTX_set_tlsext_servername_arg|. +// +// If the callback returns |SSL_TLSEXT_ERR_NOACK|, the server_name extension is +// not acknowledged in the ServerHello. If the return value is +// |SSL_TLSEXT_ERR_ALERT_FATAL|, then |*out_alert| is the alert to send, +// defaulting to |SSL_AD_UNRECOGNIZED_NAME|. |SSL_TLSEXT_ERR_ALERT_WARNING| is +// ignored and treated as |SSL_TLSEXT_ERR_OK|. +OPENSSL_EXPORT int SSL_CTX_set_tlsext_servername_callback( + SSL_CTX *ctx, int (*callback)(SSL *ssl, int *out_alert, void *arg)); + +// SSL_CTX_set_tlsext_servername_arg sets the argument to the servername +// callback and returns one. See |SSL_CTX_set_tlsext_servername_callback|. +OPENSSL_EXPORT int SSL_CTX_set_tlsext_servername_arg(SSL_CTX *ctx, void *arg); + +// SSL_TLSEXT_ERR_* are values returned by some extension-related callbacks. +#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 + +// SSL_set_SSL_CTX changes |ssl|'s |SSL_CTX|. |ssl| will use the +// certificate-related settings from |ctx|, and |SSL_get_SSL_CTX| will report +// |ctx|. This function may be used during the callbacks registered by +// |SSL_CTX_set_select_certificate_cb|, +// |SSL_CTX_set_tlsext_servername_callback|, and |SSL_CTX_set_cert_cb| or when +// the handshake is paused from them. It is typically used to switch +// certificates based on SNI. +// +// Note the session cache and related settings will continue to use the initial +// |SSL_CTX|. Callers should use |SSL_CTX_set_session_id_context| to partition +// the session cache between different domains. +// +// TODO(davidben): Should other settings change after this call? +OPENSSL_EXPORT SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX *ctx); + + +// Application-layer protocol negotiation. +// +// The ALPN extension (RFC 7301) allows negotiating different application-layer +// protocols over a single port. This is used, for example, to negotiate +// HTTP/2. + +// SSL_CTX_set_alpn_protos sets the client 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). It returns zero on success and one on failure. +// Configuring this list enables ALPN on a client. +// +// WARNING: this function is dangerous because it breaks the usual return value +// convention. +OPENSSL_EXPORT int SSL_CTX_set_alpn_protos(SSL_CTX *ctx, const uint8_t *protos, + unsigned protos_len); + +// SSL_set_alpn_protos sets the client 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). It returns zero on success and one on failure. +// Configuring this list enables ALPN on a client. +// +// WARNING: this function is dangerous because it breaks the usual return value +// convention. +OPENSSL_EXPORT int SSL_set_alpn_protos(SSL *ssl, const uint8_t *protos, + unsigned protos_len); + +// 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. Configuring this callback enables ALPN on +// a server. +// +// The callback is passed a wire-format (i.e. a series of non-empty, 8-bit +// length-prefixed strings) ALPN protocol list in |in|. It should set |*out| and +// |*out_len| to the selected protocol and return |SSL_TLSEXT_ERR_OK| on +// success. It does not pass ownership of the buffer. Otherwise, it should +// return |SSL_TLSEXT_ERR_NOACK|. Other |SSL_TLSEXT_ERR_*| values are +// unimplemented and will be treated as |SSL_TLSEXT_ERR_NOACK|. +// +// The cipher suite is selected before negotiating ALPN. The callback may use +// |SSL_get_pending_cipher| to query the cipher suite. +OPENSSL_EXPORT void SSL_CTX_set_alpn_select_cb( + SSL_CTX *ctx, int (*cb)(SSL *ssl, const uint8_t **out, uint8_t *out_len, + const uint8_t *in, unsigned in_len, void *arg), + void *arg); + +// SSL_get0_alpn_selected gets the selected ALPN protocol (if any) from |ssl|. +// On return it sets |*out_data| to point to |*out_len| bytes of protocol name +// (not including the leading length-prefix byte). If the server didn't respond +// with a negotiated protocol then |*out_len| will be zero. +OPENSSL_EXPORT void SSL_get0_alpn_selected(const SSL *ssl, + const uint8_t **out_data, + unsigned *out_len); + +// SSL_CTX_set_allow_unknown_alpn_protos configures client connections on |ctx| +// to allow unknown ALPN protocols from the server. Otherwise, by default, the +// client will require that the protocol be advertised in +// |SSL_CTX_set_alpn_protos|. +OPENSSL_EXPORT void SSL_CTX_set_allow_unknown_alpn_protos(SSL_CTX *ctx, + int enabled); + + +// Next protocol negotiation. +// +// The NPN extension (draft-agl-tls-nextprotoneg-03) is the predecessor to ALPN +// and deprecated in favor of it. + +// 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 |*out_len| to its length. This memory +// will not be modified, but one should assume that |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. +OPENSSL_EXPORT void SSL_CTX_set_next_protos_advertised_cb( + SSL_CTX *ctx, + int (*cb)(SSL *ssl, const uint8_t **out, unsigned *out_len, void *arg), + void *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 |*out_len|. The server's advertised +// protocols are provided in |in| and |in_len|. 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|. +// +// Configuring this callback enables NPN on a client. +OPENSSL_EXPORT void SSL_CTX_set_next_proto_select_cb( + SSL_CTX *ctx, int (*cb)(SSL *ssl, uint8_t **out, uint8_t *out_len, + const uint8_t *in, unsigned in_len, void *arg), + void *arg); + +// SSL_get0_next_proto_negotiated sets |*out_data| and |*out_len| to point to +// the client's requested protocol for this connection. If the client didn't +// request any protocol, then |*out_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 server. +OPENSSL_EXPORT void SSL_get0_next_proto_negotiated(const SSL *ssl, + const uint8_t **out_data, + unsigned *out_len); + +// 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|. +// +// |peer| and |supported| must be vectors of 8-bit, length-prefixed byte strings +// containing the peer and locally-configured protocols, respectively. The +// length byte itself is not included in the length. A byte string of length 0 +// is invalid. No byte string may be truncated. |supported| is assumed to be +// non-empty. +// +// This function finds the first protocol in |peer| which is also in +// |supported|. If one was found, it sets |*out| and |*out_len| to point to it +// and returns |OPENSSL_NPN_NEGOTIATED|. Otherwise, it returns +// |OPENSSL_NPN_NO_OVERLAP| and sets |*out| and |*out_len| to the first +// supported protocol. +OPENSSL_EXPORT int SSL_select_next_proto(uint8_t **out, uint8_t *out_len, + const uint8_t *peer, unsigned peer_len, + const uint8_t *supported, + unsigned supported_len); + +#define OPENSSL_NPN_UNSUPPORTED 0 +#define OPENSSL_NPN_NEGOTIATED 1 +#define OPENSSL_NPN_NO_OVERLAP 2 + + +// Channel ID. +// +// See draft-balfanz-tls-channelid-01. + +// SSL_CTX_set_tls_channel_id_enabled configures whether connections associated +// with |ctx| should enable Channel ID. +OPENSSL_EXPORT void SSL_CTX_set_tls_channel_id_enabled(SSL_CTX *ctx, + int enabled); + +// SSL_set_tls_channel_id_enabled configures whether |ssl| should enable Channel +// ID. +OPENSSL_EXPORT void SSL_set_tls_channel_id_enabled(SSL *ssl, int enabled); + +// SSL_CTX_set1_tls_channel_id configures a TLS client to send a TLS Channel ID +// to compatible servers. |private_key| must be a P-256 EC key. It returns one +// on success and zero on error. +OPENSSL_EXPORT int SSL_CTX_set1_tls_channel_id(SSL_CTX *ctx, + EVP_PKEY *private_key); + +// SSL_set1_tls_channel_id configures a TLS client to send a TLS Channel ID to +// compatible servers. |private_key| must be a P-256 EC key. It returns one on +// success and zero on error. +OPENSSL_EXPORT int SSL_set1_tls_channel_id(SSL *ssl, EVP_PKEY *private_key); + +// SSL_get_tls_channel_id gets the client's TLS Channel ID from a server |SSL*| +// and copies up to the first |max_out| bytes into |out|. The Channel ID +// consists of the client's P-256 public key as an (x,y) pair where each is a +// 32-byte, big-endian field element. It returns 0 if the client didn't offer a +// Channel ID and the length of the complete Channel ID otherwise. +OPENSSL_EXPORT size_t SSL_get_tls_channel_id(SSL *ssl, uint8_t *out, + size_t max_out); + +// SSL_CTX_set_channel_id_cb sets a callback to be called when a TLS Channel ID +// is requested. The callback may set |*out_pkey| to a key, passing a reference +// to the caller. If none is returned, the handshake will pause and +// |SSL_get_error| will return |SSL_ERROR_WANT_CHANNEL_ID_LOOKUP|. +// +// See also |SSL_ERROR_WANT_CHANNEL_ID_LOOKUP|. +OPENSSL_EXPORT void SSL_CTX_set_channel_id_cb( + SSL_CTX *ctx, void (*channel_id_cb)(SSL *ssl, EVP_PKEY **out_pkey)); + +// SSL_CTX_get_channel_id_cb returns the callback set by +// |SSL_CTX_set_channel_id_cb|. +OPENSSL_EXPORT void (*SSL_CTX_get_channel_id_cb(SSL_CTX *ctx))( + SSL *ssl, EVP_PKEY **out_pkey); + + +// Token Binding. +// +// See draft-ietf-tokbind-protocol-16. + +// SSL_set_token_binding_params sets |params| as the Token Binding Key +// parameters (section 3 of draft-ietf-tokbind-protocol-16) to negotiate on the +// connection. If this function is not called, or if |len| is 0, then this +// endpoint will not attempt to negotiate Token Binding. |params| are provided +// in preference order, with the more preferred parameters at the beginning of +// the list. This function returns 1 on success and 0 on failure. +OPENSSL_EXPORT int SSL_set_token_binding_params(SSL *ssl, const uint8_t *params, + size_t len); + +// SSL_is_token_binding_negotiated returns 1 if Token Binding was negotiated +// on this connection and 0 otherwise. On a server, it is possible for this +// function to return 1 when the client's view of the connection is that Token +// Binding was not negotiated. This occurs when the server indicates a version +// of Token Binding less than the client's minimum version. +OPENSSL_EXPORT int SSL_is_token_binding_negotiated(const SSL *ssl); + +// SSL_get_negotiated_token_binding_param returns the TokenBindingKeyParameters +// enum value that was negotiated. It is only valid to call this function if +// SSL_is_token_binding_negotiated returned 1, otherwise this function returns +// an undefined value. +OPENSSL_EXPORT uint8_t SSL_get_negotiated_token_binding_param(const SSL *ssl); + + +// DTLS-SRTP. +// +// See RFC 5764. + +// srtp_protection_profile_st (aka |SRTP_PROTECTION_PROFILE|) is an SRTP +// profile for use with the use_srtp extension. +struct srtp_protection_profile_st { + const char *name; + unsigned long id; +} /* SRTP_PROTECTION_PROFILE */; + +DEFINE_CONST_STACK_OF(SRTP_PROTECTION_PROFILE) + +// SRTP_* define constants for SRTP profiles. +#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 +#define SRTP_AEAD_AES_128_GCM 0x0007 +#define SRTP_AEAD_AES_256_GCM 0x0008 + +// SSL_CTX_set_srtp_profiles enables SRTP for all SSL objects created from +// |ctx|. |profile| contains a colon-separated list of profile names. It returns +// one on success and zero on failure. +OPENSSL_EXPORT int SSL_CTX_set_srtp_profiles(SSL_CTX *ctx, + const char *profiles); + +// SSL_set_srtp_profiles enables SRTP for |ssl|. |profile| contains a +// colon-separated list of profile names. It returns one on success and zero on +// failure. +OPENSSL_EXPORT int SSL_set_srtp_profiles(SSL *ssl, const char *profiles); + +// SSL_get_srtp_profiles returns the SRTP profiles supported by |ssl|. +OPENSSL_EXPORT STACK_OF(SRTP_PROTECTION_PROFILE) *SSL_get_srtp_profiles( + SSL *ssl); + +// SSL_get_selected_srtp_profile returns the selected SRTP profile, or NULL if +// SRTP was not negotiated. +OPENSSL_EXPORT const SRTP_PROTECTION_PROFILE *SSL_get_selected_srtp_profile( + SSL *ssl); + + +// Pre-shared keys. +// +// Connections may be configured with PSK (Pre-Shared Key) cipher suites. These +// authenticate using out-of-band pre-shared keys rather than certificates. See +// RFC 4279. +// +// This implementation uses NUL-terminated C strings for identities and identity +// hints, so values with a NUL character are not supported. (RFC 4279 does not +// specify the format of an identity.) + +// PSK_MAX_IDENTITY_LEN is the maximum supported length of a PSK identity, +// excluding the NUL terminator. +#define PSK_MAX_IDENTITY_LEN 128 + +// PSK_MAX_PSK_LEN is the maximum supported length of a pre-shared key. +#define PSK_MAX_PSK_LEN 256 + +// SSL_CTX_set_psk_client_callback sets the callback to be called when PSK is +// negotiated on the client. This callback must be set to enable PSK cipher +// suites on the client. +// +// The callback is passed the identity hint in |hint| or NULL if none was +// provided. It should select a PSK identity and write the identity and the +// corresponding PSK to |identity| and |psk|, respectively. The identity is +// written as a NUL-terminated C string of length (excluding the NUL terminator) +// at most |max_identity_len|. The PSK's length must be at most |max_psk_len|. +// The callback returns the length of the PSK or 0 if no suitable identity was +// found. +OPENSSL_EXPORT void SSL_CTX_set_psk_client_callback( + SSL_CTX *ctx, unsigned (*cb)(SSL *ssl, const char *hint, char *identity, + unsigned max_identity_len, uint8_t *psk, + unsigned max_psk_len)); + +// SSL_set_psk_client_callback sets the callback to be called when PSK is +// negotiated on the client. This callback must be set to enable PSK cipher +// suites on the client. See also |SSL_CTX_set_psk_client_callback|. +OPENSSL_EXPORT void SSL_set_psk_client_callback( + SSL *ssl, unsigned (*cb)(SSL *ssl, const char *hint, char *identity, + unsigned max_identity_len, uint8_t *psk, + unsigned max_psk_len)); + +// SSL_CTX_set_psk_server_callback sets the callback to be called when PSK is +// negotiated on the server. This callback must be set to enable PSK cipher +// suites on the server. +// +// The callback is passed the identity in |identity|. It should write a PSK of +// length at most |max_psk_len| to |psk| and return the number of bytes written +// or zero if the PSK identity is unknown. +OPENSSL_EXPORT void SSL_CTX_set_psk_server_callback( + SSL_CTX *ctx, unsigned (*cb)(SSL *ssl, const char *identity, uint8_t *psk, + unsigned max_psk_len)); + +// SSL_set_psk_server_callback sets the callback to be called when PSK is +// negotiated on the server. This callback must be set to enable PSK cipher +// suites on the server. See also |SSL_CTX_set_psk_server_callback|. +OPENSSL_EXPORT void SSL_set_psk_server_callback( + SSL *ssl, unsigned (*cb)(SSL *ssl, const char *identity, uint8_t *psk, + unsigned max_psk_len)); + +// SSL_CTX_use_psk_identity_hint configures server connections to advertise an +// identity hint of |identity_hint|. It returns one on success and zero on +// error. +OPENSSL_EXPORT int SSL_CTX_use_psk_identity_hint(SSL_CTX *ctx, + const char *identity_hint); + +// SSL_use_psk_identity_hint configures server connections to advertise an +// identity hint of |identity_hint|. It returns one on success and zero on +// error. +OPENSSL_EXPORT int SSL_use_psk_identity_hint(SSL *ssl, + const char *identity_hint); + +// SSL_get_psk_identity_hint returns the PSK identity hint advertised for |ssl| +// or NULL if there is none. +OPENSSL_EXPORT const char *SSL_get_psk_identity_hint(const SSL *ssl); + +// SSL_get_psk_identity, after the handshake completes, returns the PSK identity +// that was negotiated by |ssl| or NULL if PSK was not used. +OPENSSL_EXPORT const char *SSL_get_psk_identity(const SSL *ssl); + + +// Dummy post-quantum padding. +// +// Dummy post-quantum padding invovles the client (and later server) sending +// useless, random-looking bytes in an extension in their ClientHello or +// ServerHello. These extensions are sized to simulate a post-quantum +// key-exchange and so enable measurement of the latency impact of the +// additional bandwidth. + +// SSL_set_dummy_pq_padding_size enables the sending of a dummy PQ padding +// extension and configures its size. This is only effective for a client: a +// server will echo an extension with one of equal length when we get to that +// phase of the experiment. It returns one for success and zero otherwise. +OPENSSL_EXPORT int SSL_set_dummy_pq_padding_size(SSL *ssl, size_t num_bytes); + +// SSL_dummy_pq_padding_used returns one if the server echoed a dummy PQ padding +// extension and zero otherwise. It may only be called on a client connection +// once the ServerHello has been processed, otherwise it'll return zero. +OPENSSL_EXPORT int SSL_dummy_pq_padding_used(SSL *ssl); + + +// QUIC Transport Parameters. +// +// draft-ietf-quic-tls defines a new TLS extension quic_transport_parameters +// used by QUIC for each endpoint to unilaterally declare its supported +// transport parameters. draft-ietf-quic-transport (section 7.4) defines the +// contents of that extension (a TransportParameters struct) and describes how +// to handle it and its semantic meaning. +// +// BoringSSL handles this extension as an opaque byte string. The caller is +// responsible for serializing and parsing it. + +// SSL_set_quic_transport_params configures |ssl| to send |params| (of length +// |params_len|) in the quic_transport_parameters extension in either the +// ClientHello or EncryptedExtensions handshake message. This extension will +// only be sent if the TLS version is at least 1.3, and for a server, only if +// the client sent the extension. The buffer pointed to by |params| only need be +// valid for the duration of the call to this function. This function returns 1 +// on success and 0 on failure. +OPENSSL_EXPORT int SSL_set_quic_transport_params(SSL *ssl, + const uint8_t *params, + size_t params_len); + +// SSL_get_peer_quic_transport_params provides the caller with the value of the +// quic_transport_parameters extension sent by the peer. A pointer to the buffer +// containing the TransportParameters will be put in |*out_params|, and its +// length in |*params_len|. This buffer will be valid for the lifetime of the +// |SSL|. If no params were received from the peer, |*out_params_len| will be 0. +OPENSSL_EXPORT void SSL_get_peer_quic_transport_params(const SSL *ssl, + const uint8_t **out_params, + size_t *out_params_len); + + +// Early data. +// +// WARNING: 0-RTT support in BoringSSL is currently experimental and not fully +// implemented. It may cause interoperability or security failures when used. +// +// Early data, or 0-RTT, is a feature in TLS 1.3 which allows clients to send +// data on the first flight during a resumption handshake. This can save a +// round-trip in some application protocols. +// +// WARNING: A 0-RTT handshake has different security properties from normal +// handshake, so it is off by default unless opted in. In particular, early data +// is replayable by a network attacker. Callers must account for this when +// sending or processing data before the handshake is confirmed. See +// draft-ietf-tls-tls13-18 for more information. +// +// As a server, if early data is accepted, |SSL_do_handshake| will complete as +// soon as the ClientHello is processed and server flight sent. |SSL_write| may +// be used to send half-RTT data. |SSL_read| will consume early data and +// transition to 1-RTT data as appropriate. Prior to the transition, +// |SSL_in_init| will report the handshake is still in progress. Callers may use +// it or |SSL_in_early_data| to defer or reject requests as needed. +// +// Early data as a client is more complex. If the offered session (see +// |SSL_set_session|) is 0-RTT-capable, the handshake will return after sending +// the ClientHello. The predicted peer certificates and ALPN protocol will be +// available via the usual APIs. |SSL_write| will write early data, up to the +// session's limit. Writes past this limit and |SSL_read| will complete the +// handshake before continuing. Callers may also call |SSL_do_handshake| again +// to complete the handshake sooner. +// +// If the server accepts early data, the handshake will succeed. |SSL_read| and +// |SSL_write| will then act as in a 1-RTT handshake. The peer certificates and +// ALPN protocol will be as predicted and need not be re-queried. +// +// If the server rejects early data, |SSL_do_handshake| (and thus |SSL_read| and +// |SSL_write|) will then fail with |SSL_get_error| returning +// |SSL_ERROR_EARLY_DATA_REJECTED|. The caller should treat this as a connection +// error and most likely perform a high-level retry. Note the server may still +// have processed the early data due to attacker replays. +// +// To then continue the handshake on the original connection, use +// |SSL_reset_early_data_reject|. The connection will then behave as one which +// had not yet completed the handshake. This allows a faster retry than making a +// fresh connection. |SSL_do_handshake| will complete the full handshake, +// possibly resulting in different peer certificates, ALPN protocol, and other +// properties. The caller must disregard any values from before the reset and +// query again. +// +// Finally, to implement the fallback described in draft-ietf-tls-tls13-18 +// appendix C.3, retry on a fresh connection without 0-RTT if the handshake +// fails with |SSL_R_WRONG_VERSION_ON_EARLY_DATA|. + +// SSL_CTX_set_early_data_enabled sets whether early data is allowed to be used +// with resumptions using |ctx|. +OPENSSL_EXPORT void SSL_CTX_set_early_data_enabled(SSL_CTX *ctx, int enabled); + +// SSL_set_early_data_enabled sets whether early data is allowed to be used +// with resumptions using |ssl|. See |SSL_CTX_set_early_data_enabled| for more +// information. +OPENSSL_EXPORT void SSL_set_early_data_enabled(SSL *ssl, int enabled); + +// SSL_in_early_data returns one if |ssl| has a pending handshake that has +// progressed enough to send or receive early data. Clients may call |SSL_write| +// to send early data, but |SSL_read| will complete the handshake before +// accepting application data. Servers may call |SSL_read| to read early data +// and |SSL_write| to send half-RTT data. +OPENSSL_EXPORT int SSL_in_early_data(const SSL *ssl); + +// SSL_early_data_accepted returns whether early data was accepted on the +// handshake performed by |ssl|. +OPENSSL_EXPORT int SSL_early_data_accepted(const SSL *ssl); + +// SSL_reset_early_data_reject resets |ssl| after an early data reject. All +// 0-RTT state is discarded, including any pending |SSL_write| calls. The caller +// should treat |ssl| as a logically fresh connection, usually by driving the +// handshake to completion using |SSL_do_handshake|. +// +// It is an error to call this function on an |SSL| object that is not signaling +// |SSL_ERROR_EARLY_DATA_REJECTED|. +OPENSSL_EXPORT void SSL_reset_early_data_reject(SSL *ssl); + +// SSL_export_early_keying_material behaves like |SSL_export_keying_material|, +// but it uses the early exporter. The operation will fail if |ssl| did not +// negotiate TLS 1.3 or 0-RTT. +OPENSSL_EXPORT int SSL_export_early_keying_material( + SSL *ssl, uint8_t *out, size_t out_len, const char *label, size_t label_len, + const uint8_t *context, size_t context_len); + + +// Alerts. +// +// TLS and SSL 3.0 use alerts to signal error conditions. Alerts have a type +// (warning or fatal) and description. OpenSSL internally handles fatal alerts +// with dedicated error codes (see |SSL_AD_REASON_OFFSET|). Except for +// close_notify, warning alerts are silently ignored and may only be surfaced +// with |SSL_CTX_set_info_callback|. + +// SSL_AD_REASON_OFFSET is the offset between error reasons and |SSL_AD_*| +// values. Any error code under |ERR_LIB_SSL| with an error reason above this +// value corresponds to an alert description. Consumers may add or subtract +// |SSL_AD_REASON_OFFSET| to convert between them. +// +// make_errors.go reserves error codes above 1000 for manually-assigned errors. +// This value must be kept in sync with reservedReasonCode in make_errors.h +#define SSL_AD_REASON_OFFSET 1000 + +// SSL_AD_* are alert descriptions for SSL 3.0 and TLS. +#define SSL_AD_CLOSE_NOTIFY SSL3_AD_CLOSE_NOTIFY +#define SSL_AD_UNEXPECTED_MESSAGE SSL3_AD_UNEXPECTED_MESSAGE +#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 +#define SSL_AD_DECOMPRESSION_FAILURE SSL3_AD_DECOMPRESSION_FAILURE +#define SSL_AD_HANDSHAKE_FAILURE SSL3_AD_HANDSHAKE_FAILURE +#define SSL_AD_NO_CERTIFICATE SSL3_AD_NO_CERTIFICATE // Not used in TLS +#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 +#define SSL_AD_ILLEGAL_PARAMETER SSL3_AD_ILLEGAL_PARAMETER +#define SSL_AD_UNKNOWN_CA TLS1_AD_UNKNOWN_CA +#define SSL_AD_ACCESS_DENIED TLS1_AD_ACCESS_DENIED +#define SSL_AD_DECODE_ERROR TLS1_AD_DECODE_ERROR +#define SSL_AD_DECRYPT_ERROR TLS1_AD_DECRYPT_ERROR +#define SSL_AD_EXPORT_RESTRICTION TLS1_AD_EXPORT_RESTRICTION +#define SSL_AD_PROTOCOL_VERSION TLS1_AD_PROTOCOL_VERSION +#define SSL_AD_INSUFFICIENT_SECURITY TLS1_AD_INSUFFICIENT_SECURITY +#define SSL_AD_INTERNAL_ERROR TLS1_AD_INTERNAL_ERROR +#define SSL_AD_INAPPROPRIATE_FALLBACK SSL3_AD_INAPPROPRIATE_FALLBACK +#define SSL_AD_USER_CANCELLED TLS1_AD_USER_CANCELLED +#define SSL_AD_NO_RENEGOTIATION TLS1_AD_NO_RENEGOTIATION +#define SSL_AD_MISSING_EXTENSION TLS1_AD_MISSING_EXTENSION +#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 +#define SSL_AD_UNKNOWN_PSK_IDENTITY TLS1_AD_UNKNOWN_PSK_IDENTITY +#define SSL_AD_CERTIFICATE_REQUIRED TLS1_AD_CERTIFICATE_REQUIRED + +// SSL_alert_type_string_long returns a string description of |value| as an +// alert type (warning or fatal). +OPENSSL_EXPORT const char *SSL_alert_type_string_long(int value); + +// SSL_alert_desc_string_long returns a string description of |value| as an +// alert description or "unknown" if unknown. +OPENSSL_EXPORT const char *SSL_alert_desc_string_long(int value); + +// SSL_send_fatal_alert sends a fatal alert over |ssl| of the specified type, +// which should be one of the |SSL_AD_*| constants. It returns one on success +// and <= 0 on error. The caller should pass the return value into +// |SSL_get_error| to determine how to proceed. Once this function has been +// called, future calls to |SSL_write| will fail. +// +// If retrying a failed operation due to |SSL_ERROR_WANT_WRITE|, subsequent +// calls must use the same |alert| parameter. +OPENSSL_EXPORT int SSL_send_fatal_alert(SSL *ssl, uint8_t alert); + + +// ex_data functions. +// +// See |ex_data.h| for details. + +OPENSSL_EXPORT int SSL_set_ex_data(SSL *ssl, int idx, void *data); +OPENSSL_EXPORT void *SSL_get_ex_data(const SSL *ssl, int idx); +OPENSSL_EXPORT int SSL_get_ex_new_index(long argl, void *argp, + CRYPTO_EX_unused *unused, + CRYPTO_EX_dup *dup_unused, + CRYPTO_EX_free *free_func); + +OPENSSL_EXPORT int SSL_SESSION_set_ex_data(SSL_SESSION *session, int idx, + void *data); +OPENSSL_EXPORT void *SSL_SESSION_get_ex_data(const SSL_SESSION *session, + int idx); +OPENSSL_EXPORT int SSL_SESSION_get_ex_new_index(long argl, void *argp, + CRYPTO_EX_unused *unused, + CRYPTO_EX_dup *dup_unused, + CRYPTO_EX_free *free_func); + +OPENSSL_EXPORT int SSL_CTX_set_ex_data(SSL_CTX *ctx, int idx, void *data); +OPENSSL_EXPORT void *SSL_CTX_get_ex_data(const SSL_CTX *ctx, int idx); +OPENSSL_EXPORT int SSL_CTX_get_ex_new_index(long argl, void *argp, + CRYPTO_EX_unused *unused, + CRYPTO_EX_dup *dup_unused, + CRYPTO_EX_free *free_func); + + +// Low-level record-layer state. + +// SSL_get_ivs sets |*out_iv_len| to the length of the IVs for the ciphers +// underlying |ssl| and sets |*out_read_iv| and |*out_write_iv| to point to the +// current IVs for the read and write directions. This is only meaningful for +// connections with implicit IVs (i.e. CBC mode with SSLv3 or TLS 1.0). +// +// It returns one on success or zero on error. +OPENSSL_EXPORT int SSL_get_ivs(const SSL *ssl, const uint8_t **out_read_iv, + const uint8_t **out_write_iv, + size_t *out_iv_len); + +// SSL_get_key_block_len returns the length of |ssl|'s key block. +OPENSSL_EXPORT size_t SSL_get_key_block_len(const SSL *ssl); + +// SSL_generate_key_block generates |out_len| bytes of key material for |ssl|'s +// current connection state. +OPENSSL_EXPORT int SSL_generate_key_block(const SSL *ssl, uint8_t *out, + size_t out_len); + +// SSL_get_read_sequence returns, in TLS, the expected sequence number of the +// next incoming record in the current epoch. In DTLS, it returns the maximum +// sequence number received in the current epoch and includes the epoch number +// in the two most significant bytes. +OPENSSL_EXPORT uint64_t SSL_get_read_sequence(const SSL *ssl); + +// SSL_get_write_sequence returns the sequence number of the next outgoing +// record in the current epoch. In DTLS, it includes the epoch number in the +// two most significant bytes. +OPENSSL_EXPORT uint64_t SSL_get_write_sequence(const SSL *ssl); + + +// Obscure functions. + +// SSL_get_structure_sizes returns the sizes of the SSL, SSL_CTX and +// SSL_SESSION structures so that a test can ensure that outside code agrees on +// these values. +OPENSSL_EXPORT void SSL_get_structure_sizes(size_t *ssl_size, + size_t *ssl_ctx_size, + size_t *ssl_session_size); + +// SSL_CTX_set_msg_callback installs |cb| as the message callback for |ctx|. +// This callback will be called when sending or receiving low-level record +// headers, complete handshake messages, ChangeCipherSpec, and alerts. +// |write_p| is one for outgoing messages and zero for incoming messages. +// +// For each record header, |cb| is called with |version| = 0 and |content_type| +// = |SSL3_RT_HEADER|. The |len| bytes from |buf| contain the header. Note that +// this does not include the record body. If the record is sealed, the length +// in the header is the length of the ciphertext. +// +// For each handshake message, ChangeCipherSpec, and alert, |version| is the +// protocol version and |content_type| is the corresponding record type. The +// |len| bytes from |buf| contain the handshake message, one-byte +// ChangeCipherSpec body, and two-byte alert, respectively. +// +// For a V2ClientHello, |version| is |SSL2_VERSION|, |content_type| is zero, and +// the |len| bytes from |buf| contain the V2ClientHello structure. +OPENSSL_EXPORT 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_set_msg_callback_arg sets the |arg| parameter of the message +// callback. +OPENSSL_EXPORT void SSL_CTX_set_msg_callback_arg(SSL_CTX *ctx, void *arg); + +// SSL_set_msg_callback installs |cb| as the message callback of |ssl|. See +// |SSL_CTX_set_msg_callback| for when this callback is called. +OPENSSL_EXPORT 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_set_msg_callback_arg sets the |arg| parameter of the message callback. +OPENSSL_EXPORT void SSL_set_msg_callback_arg(SSL *ssl, void *arg); + +// SSL_CTX_set_keylog_callback configures a callback to log key material. This +// is intended for debugging use with tools like Wireshark. The |cb| function +// should log |line| followed by a newline, synchronizing with any concurrent +// access to the log. +// +// The format is described in +// https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS/Key_Log_Format. +OPENSSL_EXPORT void SSL_CTX_set_keylog_callback( + SSL_CTX *ctx, void (*cb)(const SSL *ssl, const char *line)); + +// SSL_CTX_get_keylog_callback returns the callback configured by +// |SSL_CTX_set_keylog_callback|. +OPENSSL_EXPORT void (*SSL_CTX_get_keylog_callback(const SSL_CTX *ctx))( + const SSL *ssl, const char *line); + +// SSL_CTX_set_current_time_cb configures a callback to retrieve the current +// time, which should be set in |*out_clock|. This can be used for testing +// purposes; for example, a callback can be configured that returns a time +// set explicitly by the test. The |ssl| pointer passed to |cb| is always null. +OPENSSL_EXPORT void SSL_CTX_set_current_time_cb( + SSL_CTX *ctx, void (*cb)(const SSL *ssl, struct timeval *out_clock)); + +enum ssl_renegotiate_mode_t { + ssl_renegotiate_never = 0, + ssl_renegotiate_once, + ssl_renegotiate_freely, + ssl_renegotiate_ignore, +}; + +// SSL_set_renegotiate_mode configures how |ssl|, a client, reacts to +// renegotiation attempts by a server. If |ssl| is a server, peer-initiated +// renegotiations are *always* rejected and this function does nothing. +// +// The renegotiation mode defaults to |ssl_renegotiate_never|, but may be set +// at any point in a connection's lifetime. Set it to |ssl_renegotiate_once| to +// allow one renegotiation, |ssl_renegotiate_freely| to allow all +// renegotiations or |ssl_renegotiate_ignore| to ignore HelloRequest messages. +// Note that ignoring HelloRequest messages may cause the connection to stall +// if the server waits for the renegotiation to complete. +// +// There is no support in BoringSSL for initiating renegotiations as a client +// or server. +OPENSSL_EXPORT void SSL_set_renegotiate_mode(SSL *ssl, + enum ssl_renegotiate_mode_t mode); + +// SSL_renegotiate_pending returns one if |ssl| is in the middle of a +// renegotiation. +OPENSSL_EXPORT int SSL_renegotiate_pending(SSL *ssl); + +// SSL_total_renegotiations returns the total number of renegotiation handshakes +// performed by |ssl|. This includes the pending renegotiation, if any. +OPENSSL_EXPORT int SSL_total_renegotiations(const SSL *ssl); + +enum tls13_variant_t { + tls13_default = 0, +}; + +// SSL_CTX_set_tls13_variant sets which variant of TLS 1.3 we negotiate. On the +// server, if |variant| is not |tls13_default|, all variants are enabled. On the +// client, only the configured variant is enabled. +OPENSSL_EXPORT void SSL_CTX_set_tls13_variant(SSL_CTX *ctx, + enum tls13_variant_t variant); + +// SSL_set_tls13_variant sets which variant of TLS 1.3 we negotiate. On the +// server, if |variant| is not |tls13_default|, all variants are enabled. On the +// client, only the configured variant is enabled. +OPENSSL_EXPORT void SSL_set_tls13_variant(SSL *ssl, + enum tls13_variant_t variant); + +// SSL_MAX_CERT_LIST_DEFAULT is the default maximum length, in bytes, of a peer +// certificate chain. +#define SSL_MAX_CERT_LIST_DEFAULT (1024 * 100) + +// SSL_CTX_get_max_cert_list returns the maximum length, in bytes, of a peer +// certificate chain accepted by |ctx|. +OPENSSL_EXPORT size_t SSL_CTX_get_max_cert_list(const SSL_CTX *ctx); + +// SSL_CTX_set_max_cert_list sets the maximum length, in bytes, of a peer +// certificate chain to |max_cert_list|. This affects how much memory may be +// consumed during the handshake. +OPENSSL_EXPORT void SSL_CTX_set_max_cert_list(SSL_CTX *ctx, + size_t max_cert_list); + +// SSL_get_max_cert_list returns the maximum length, in bytes, of a peer +// certificate chain accepted by |ssl|. +OPENSSL_EXPORT size_t SSL_get_max_cert_list(const SSL *ssl); + +// SSL_set_max_cert_list sets the maximum length, in bytes, of a peer +// certificate chain to |max_cert_list|. This affects how much memory may be +// consumed during the handshake. +OPENSSL_EXPORT void SSL_set_max_cert_list(SSL *ssl, size_t max_cert_list); + +// SSL_CTX_set_max_send_fragment sets the maximum length, in bytes, of records +// sent by |ctx|. Beyond this length, handshake messages and application data +// will be split into multiple records. It returns one on success or zero on +// error. +OPENSSL_EXPORT int SSL_CTX_set_max_send_fragment(SSL_CTX *ctx, + size_t max_send_fragment); + +// SSL_set_max_send_fragment sets the maximum length, in bytes, of records sent +// by |ssl|. Beyond this length, handshake messages and application data will +// be split into multiple records. It returns one on success or zero on +// error. +OPENSSL_EXPORT int SSL_set_max_send_fragment(SSL *ssl, + size_t max_send_fragment); + +// ssl_early_callback_ctx (aka |SSL_CLIENT_HELLO|) is passed to certain +// callbacks that are called very early on during the server handshake. At this +// point, much of the SSL* hasn't been filled out and only the ClientHello can +// be depended on. +typedef struct ssl_early_callback_ctx { + SSL *ssl; + const uint8_t *client_hello; + size_t client_hello_len; + uint16_t version; + const uint8_t *random; + size_t random_len; + const uint8_t *session_id; + size_t session_id_len; + const uint8_t *cipher_suites; + size_t cipher_suites_len; + const uint8_t *compression_methods; + size_t compression_methods_len; + const uint8_t *extensions; + size_t extensions_len; +} SSL_CLIENT_HELLO; + +// ssl_select_cert_result_t enumerates the possible results from selecting a +// certificate with |select_certificate_cb|. +enum ssl_select_cert_result_t { + // ssl_select_cert_success indicates that the certificate selection was + // successful. + ssl_select_cert_success = 1, + // ssl_select_cert_retry indicates that the operation could not be + // immediately completed and must be reattempted at a later point. + ssl_select_cert_retry = 0, + // ssl_select_cert_error indicates that a fatal error occured and the + // handshake should be terminated. + ssl_select_cert_error = -1, +}; + +// SSL_early_callback_ctx_extension_get searches the extensions in +// |client_hello| for an extension of the given type. If not found, it returns +// zero. Otherwise it sets |out_data| to point to the extension contents (not +// including the type and length bytes), sets |out_len| to the length of the +// extension contents and returns one. +OPENSSL_EXPORT int SSL_early_callback_ctx_extension_get( + const SSL_CLIENT_HELLO *client_hello, uint16_t extension_type, + const uint8_t **out_data, size_t *out_len); + +// SSL_CTX_set_select_certificate_cb sets a callback that is called before most +// ClientHello processing and before the decision whether to resume a session +// is made. The callback may inspect the ClientHello and configure the +// connection. See |ssl_select_cert_result_t| for details of the return values. +// +// In the case that a retry is indicated, |SSL_get_error| will return +// |SSL_ERROR_PENDING_CERTIFICATE| and the caller should arrange for the +// high-level operation on |ssl| to be retried at a later time, which will +// result in another call to |cb|. +// +// Note: The |SSL_CLIENT_HELLO| is only valid for the duration of the callback +// and is not valid while the handshake is paused. +OPENSSL_EXPORT void SSL_CTX_set_select_certificate_cb( + SSL_CTX *ctx, + enum ssl_select_cert_result_t (*cb)(const SSL_CLIENT_HELLO *)); + +// SSL_CTX_set_dos_protection_cb sets a callback that is called once the +// resumption decision for a ClientHello has been made. It can return one to +// allow the handshake to continue or zero to cause the handshake to abort. +OPENSSL_EXPORT void SSL_CTX_set_dos_protection_cb( + SSL_CTX *ctx, int (*cb)(const SSL_CLIENT_HELLO *)); + +// SSL_ST_* are possible values for |SSL_state| and the bitmasks that make them +// up. +#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_OK 0x03 +#define SSL_ST_RENEGOTIATE (0x04 | SSL_ST_INIT) + +// SSL_CB_* are possible values for the |type| parameter in the info +// callback and the bitmasks that make them up. +#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 +#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 + +// SSL_CTX_set_info_callback configures a callback to be run when various +// events occur during a connection's lifetime. The |type| argument determines +// the type of event and the meaning of the |value| argument. Callbacks must +// ignore unexpected |type| values. +// +// |SSL_CB_READ_ALERT| is signaled for each alert received, warning or fatal. +// The |value| argument is a 16-bit value where the alert level (either +// |SSL3_AL_WARNING| or |SSL3_AL_FATAL|) is in the most-significant eight bits +// and the alert type (one of |SSL_AD_*|) is in the least-significant eight. +// +// |SSL_CB_WRITE_ALERT| is signaled for each alert sent. The |value| argument +// is constructed as with |SSL_CB_READ_ALERT|. +// +// |SSL_CB_HANDSHAKE_START| is signaled when a handshake begins. The |value| +// argument is always one. +// +// |SSL_CB_HANDSHAKE_DONE| is signaled when a handshake completes successfully. +// The |value| argument is always one. If a handshake False Starts, this event +// may be used to determine when the Finished message is received. +// +// The following event types expose implementation details of the handshake +// state machine. Consuming them is deprecated. +// +// |SSL_CB_ACCEPT_LOOP| (respectively, |SSL_CB_CONNECT_LOOP|) is signaled when +// a server (respectively, client) handshake progresses. The |value| argument +// is always one. +// +// |SSL_CB_ACCEPT_EXIT| (respectively, |SSL_CB_CONNECT_EXIT|) is signaled when +// a server (respectively, client) handshake completes, fails, or is paused. +// The |value| argument is one if the handshake succeeded and <= 0 +// otherwise. +OPENSSL_EXPORT void SSL_CTX_set_info_callback( + SSL_CTX *ctx, void (*cb)(const SSL *ssl, int type, int value)); + +// SSL_CTX_get_info_callback returns the callback set by +// |SSL_CTX_set_info_callback|. +OPENSSL_EXPORT void (*SSL_CTX_get_info_callback(SSL_CTX *ctx))(const SSL *ssl, + int type, + int value); + +// SSL_set_info_callback configures a callback to be run at various events +// during a connection's lifetime. See |SSL_CTX_set_info_callback|. +OPENSSL_EXPORT void SSL_set_info_callback( + SSL *ssl, void (*cb)(const SSL *ssl, int type, int value)); + +// SSL_get_info_callback returns the callback set by |SSL_set_info_callback|. +OPENSSL_EXPORT void (*SSL_get_info_callback(const SSL *ssl))(const SSL *ssl, + int type, + int value); + +// SSL_state_string_long returns the current state of the handshake state +// machine as a string. This may be useful for debugging and logging. +OPENSSL_EXPORT const char *SSL_state_string_long(const SSL *ssl); + +#define SSL_SENT_SHUTDOWN 1 +#define SSL_RECEIVED_SHUTDOWN 2 + +// SSL_get_shutdown returns a bitmask with a subset of |SSL_SENT_SHUTDOWN| and +// |SSL_RECEIVED_SHUTDOWN| to query whether close_notify was sent or received, +// respectively. +OPENSSL_EXPORT int SSL_get_shutdown(const SSL *ssl); + +// SSL_get_peer_signature_algorithm returns the signature algorithm used by the +// peer. If not applicable, it returns zero. +OPENSSL_EXPORT uint16_t SSL_get_peer_signature_algorithm(const SSL *ssl); + +// SSL_get_client_random writes up to |max_out| bytes of the most recent +// handshake's client_random to |out| and returns the number of bytes written. +// If |max_out| is zero, it returns the size of the client_random. +OPENSSL_EXPORT size_t SSL_get_client_random(const SSL *ssl, uint8_t *out, + size_t max_out); + +// SSL_get_server_random writes up to |max_out| bytes of the most recent +// handshake's server_random to |out| and returns the number of bytes written. +// If |max_out| is zero, it returns the size of the server_random. +OPENSSL_EXPORT size_t SSL_get_server_random(const SSL *ssl, uint8_t *out, + size_t max_out); + +// SSL_get_pending_cipher returns the cipher suite for the current handshake or +// NULL if one has not been negotiated yet or there is no pending handshake. +OPENSSL_EXPORT const SSL_CIPHER *SSL_get_pending_cipher(const SSL *ssl); + +// SSL_set_retain_only_sha256_of_client_certs, on a server, sets whether only +// the SHA-256 hash of peer's certificate should be saved in memory and in the +// session. This can save memory, ticket size and session cache space. If +// enabled, |SSL_get_peer_certificate| will return NULL after the handshake +// completes. See the |peer_sha256| field of |SSL_SESSION| for the hash. +OPENSSL_EXPORT void SSL_set_retain_only_sha256_of_client_certs(SSL *ssl, + int enable); + +// SSL_CTX_set_retain_only_sha256_of_client_certs, on a server, sets whether +// only the SHA-256 hash of peer's certificate should be saved in memory and in +// the session. This can save memory, ticket size and session cache space. If +// enabled, |SSL_get_peer_certificate| will return NULL after the handshake +// completes. See the |peer_sha256| field of |SSL_SESSION| for the hash. +OPENSSL_EXPORT void SSL_CTX_set_retain_only_sha256_of_client_certs(SSL_CTX *ctx, + int enable); + +// SSL_CTX_set_grease_enabled configures whether sockets on |ctx| should enable +// GREASE. See draft-davidben-tls-grease-01. +OPENSSL_EXPORT void SSL_CTX_set_grease_enabled(SSL_CTX *ctx, int enabled); + +// SSL_max_seal_overhead returns the maximum overhead, in bytes, of sealing a +// record with |ssl|. +OPENSSL_EXPORT size_t SSL_max_seal_overhead(const SSL *ssl); + +// SSL_get_ticket_age_skew returns the difference, in seconds, between the +// client-sent ticket age and the server-computed value in TLS 1.3 server +// connections which resumed a session. +OPENSSL_EXPORT int32_t SSL_get_ticket_age_skew(const SSL *ssl); + +// SSL_CTX_set_false_start_allowed_without_alpn configures whether connections +// on |ctx| may use False Start (if |SSL_MODE_ENABLE_FALSE_START| is enabled) +// without negotiating ALPN. +OPENSSL_EXPORT void SSL_CTX_set_false_start_allowed_without_alpn(SSL_CTX *ctx, + int allowed); + +// SSL_is_draft_downgrade returns one if the TLS 1.3 anti-downgrade mechanism +// would have aborted |ssl|'s handshake and zero otherwise. +OPENSSL_EXPORT int SSL_is_draft_downgrade(const SSL *ssl); + + +// Deprecated functions. + +// SSL_library_init calls |CRYPTO_library_init| and returns one. +OPENSSL_EXPORT int SSL_library_init(void); + +// SSL_CIPHER_description writes a description of |cipher| into |buf| and +// returns |buf|. If |buf| is NULL, it returns a newly allocated string, to be +// freed with |OPENSSL_free|, or NULL on error. +// +// The description includes a trailing newline and has the form: +// AES128-SHA Kx=RSA Au=RSA Enc=AES(128) Mac=SHA1 +// +// Consider |SSL_CIPHER_standard_name| or |SSL_CIPHER_get_name| instead. +OPENSSL_EXPORT const char *SSL_CIPHER_description(const SSL_CIPHER *cipher, + char *buf, int len); + +// SSL_CIPHER_get_version returns the string "TLSv1/SSLv3". +OPENSSL_EXPORT const char *SSL_CIPHER_get_version(const SSL_CIPHER *cipher); + +// SSL_CIPHER_get_rfc_name returns a newly-allocated string containing the +// result of |SSL_CIPHER_standard_name| or NULL on error. The caller is +// responsible for calling |OPENSSL_free| on the result. +// +// Use |SSL_CIPHER_standard_name| instead. +OPENSSL_EXPORT char *SSL_CIPHER_get_rfc_name(const SSL_CIPHER *cipher); + +typedef void COMP_METHOD; +typedef struct ssl_comp_st SSL_COMP; + +// SSL_COMP_get_compression_methods returns NULL. +OPENSSL_EXPORT STACK_OF(SSL_COMP) *SSL_COMP_get_compression_methods(void); + +// SSL_COMP_add_compression_method returns one. +OPENSSL_EXPORT int SSL_COMP_add_compression_method(int id, COMP_METHOD *cm); + +// SSL_COMP_get_name returns NULL. +OPENSSL_EXPORT const char *SSL_COMP_get_name(const COMP_METHOD *comp); + +// SSL_COMP_get0_name returns the |name| member of |comp|. +OPENSSL_EXPORT const char *SSL_COMP_get0_name(const SSL_COMP *comp); + +// SSL_COMP_get_id returns the |id| member of |comp|. +OPENSSL_EXPORT int SSL_COMP_get_id(const SSL_COMP *comp); + +// SSL_COMP_free_compression_methods does nothing. +OPENSSL_EXPORT void SSL_COMP_free_compression_methods(void); + +// SSLv23_method calls |TLS_method|. +OPENSSL_EXPORT const SSL_METHOD *SSLv23_method(void); + +// These version-specific methods behave exactly like |TLS_method| and +// |DTLS_method| except they also call |SSL_CTX_set_min_proto_version| and +// |SSL_CTX_set_max_proto_version| to lock connections to that protocol +// version. +OPENSSL_EXPORT const SSL_METHOD *TLSv1_method(void); +OPENSSL_EXPORT const SSL_METHOD *TLSv1_1_method(void); +OPENSSL_EXPORT const SSL_METHOD *TLSv1_2_method(void); +OPENSSL_EXPORT const SSL_METHOD *DTLSv1_method(void); +OPENSSL_EXPORT const SSL_METHOD *DTLSv1_2_method(void); + +// These client- and server-specific methods call their corresponding generic +// methods. +OPENSSL_EXPORT const SSL_METHOD *TLS_server_method(void); +OPENSSL_EXPORT const SSL_METHOD *TLS_client_method(void); +OPENSSL_EXPORT const SSL_METHOD *SSLv23_server_method(void); +OPENSSL_EXPORT const SSL_METHOD *SSLv23_client_method(void); +OPENSSL_EXPORT const SSL_METHOD *TLSv1_server_method(void); +OPENSSL_EXPORT const SSL_METHOD *TLSv1_client_method(void); +OPENSSL_EXPORT const SSL_METHOD *TLSv1_1_server_method(void); +OPENSSL_EXPORT const SSL_METHOD *TLSv1_1_client_method(void); +OPENSSL_EXPORT const SSL_METHOD *TLSv1_2_server_method(void); +OPENSSL_EXPORT const SSL_METHOD *TLSv1_2_client_method(void); +OPENSSL_EXPORT const SSL_METHOD *DTLS_server_method(void); +OPENSSL_EXPORT const SSL_METHOD *DTLS_client_method(void); +OPENSSL_EXPORT const SSL_METHOD *DTLSv1_server_method(void); +OPENSSL_EXPORT const SSL_METHOD *DTLSv1_client_method(void); +OPENSSL_EXPORT const SSL_METHOD *DTLSv1_2_server_method(void); +OPENSSL_EXPORT const SSL_METHOD *DTLSv1_2_client_method(void); + +// SSL_clear resets |ssl| to allow another connection and returns one on success +// or zero on failure. It returns most configuration state but releases memory +// associated with the current connection. +// +// Free |ssl| and create a new one instead. +OPENSSL_EXPORT int SSL_clear(SSL *ssl); + +// SSL_CTX_set_tmp_rsa_callback does nothing. +OPENSSL_EXPORT void SSL_CTX_set_tmp_rsa_callback( + SSL_CTX *ctx, RSA *(*cb)(SSL *ssl, int is_export, int keylength)); + +// SSL_set_tmp_rsa_callback does nothing. +OPENSSL_EXPORT void SSL_set_tmp_rsa_callback(SSL *ssl, + RSA *(*cb)(SSL *ssl, int is_export, + int keylength)); + +// SSL_CTX_sess_connect returns zero. +OPENSSL_EXPORT int SSL_CTX_sess_connect(const SSL_CTX *ctx); + +// SSL_CTX_sess_connect_good returns zero. +OPENSSL_EXPORT int SSL_CTX_sess_connect_good(const SSL_CTX *ctx); + +// SSL_CTX_sess_connect_renegotiate returns zero. +OPENSSL_EXPORT int SSL_CTX_sess_connect_renegotiate(const SSL_CTX *ctx); + +// SSL_CTX_sess_accept returns zero. +OPENSSL_EXPORT int SSL_CTX_sess_accept(const SSL_CTX *ctx); + +// SSL_CTX_sess_accept_renegotiate returns zero. +OPENSSL_EXPORT int SSL_CTX_sess_accept_renegotiate(const SSL_CTX *ctx); + +// SSL_CTX_sess_accept_good returns zero. +OPENSSL_EXPORT int SSL_CTX_sess_accept_good(const SSL_CTX *ctx); + +// SSL_CTX_sess_hits returns zero. +OPENSSL_EXPORT int SSL_CTX_sess_hits(const SSL_CTX *ctx); + +// SSL_CTX_sess_cb_hits returns zero. +OPENSSL_EXPORT int SSL_CTX_sess_cb_hits(const SSL_CTX *ctx); + +// SSL_CTX_sess_misses returns zero. +OPENSSL_EXPORT int SSL_CTX_sess_misses(const SSL_CTX *ctx); + +// SSL_CTX_sess_timeouts returns zero. +OPENSSL_EXPORT int SSL_CTX_sess_timeouts(const SSL_CTX *ctx); + +// SSL_CTX_sess_cache_full returns zero. +OPENSSL_EXPORT int SSL_CTX_sess_cache_full(const SSL_CTX *ctx); + +// SSL_cutthrough_complete calls |SSL_in_false_start|. +OPENSSL_EXPORT int SSL_cutthrough_complete(const SSL *ssl); + +// SSL_num_renegotiations calls |SSL_total_renegotiations|. +OPENSSL_EXPORT int SSL_num_renegotiations(const SSL *ssl); + +// SSL_CTX_need_tmp_RSA returns zero. +OPENSSL_EXPORT int SSL_CTX_need_tmp_RSA(const SSL_CTX *ctx); + +// SSL_need_tmp_RSA returns zero. +OPENSSL_EXPORT int SSL_need_tmp_RSA(const SSL *ssl); + +// SSL_CTX_set_tmp_rsa returns one. +OPENSSL_EXPORT int SSL_CTX_set_tmp_rsa(SSL_CTX *ctx, const RSA *rsa); + +// SSL_set_tmp_rsa returns one. +OPENSSL_EXPORT int SSL_set_tmp_rsa(SSL *ssl, const RSA *rsa); + +// SSL_CTX_get_read_ahead returns zero. +OPENSSL_EXPORT int SSL_CTX_get_read_ahead(const SSL_CTX *ctx); + +// SSL_CTX_set_read_ahead does nothing. +OPENSSL_EXPORT void SSL_CTX_set_read_ahead(SSL_CTX *ctx, int yes); + +// SSL_get_read_ahead returns zero. +OPENSSL_EXPORT int SSL_get_read_ahead(const SSL *ssl); + +// SSL_set_read_ahead does nothing. +OPENSSL_EXPORT void SSL_set_read_ahead(SSL *ssl, int yes); + +// SSL_renegotiate put an error on the error queue and returns zero. +OPENSSL_EXPORT int SSL_renegotiate(SSL *ssl); + +// SSL_set_state does nothing. +OPENSSL_EXPORT void SSL_set_state(SSL *ssl, int state); + +// SSL_get_shared_ciphers writes an empty string to |buf| and returns a +// pointer to |buf|, or NULL if |len| is less than or equal to zero. +OPENSSL_EXPORT char *SSL_get_shared_ciphers(const SSL *ssl, char *buf, int len); + +// SSL_MODE_HANDSHAKE_CUTTHROUGH is the same as SSL_MODE_ENABLE_FALSE_START. +#define SSL_MODE_HANDSHAKE_CUTTHROUGH SSL_MODE_ENABLE_FALSE_START + +// i2d_SSL_SESSION serializes |in| to the bytes pointed to by |*pp|. On success, +// it returns the number of bytes written and advances |*pp| by that many bytes. +// On failure, it returns -1. If |pp| is NULL, no bytes are written and only the +// length is returned. +// +// Use |SSL_SESSION_to_bytes| instead. +OPENSSL_EXPORT int i2d_SSL_SESSION(SSL_SESSION *in, uint8_t **pp); + +// d2i_SSL_SESSION parses a serialized session from the |length| bytes pointed +// to by |*pp|. It returns the new |SSL_SESSION| and advances |*pp| by the +// number of bytes consumed on success and NULL on failure. The caller takes +// ownership of the new session and must call |SSL_SESSION_free| when done. +// +// If |a| is non-NULL, |*a| is released and set the new |SSL_SESSION|. +// +// Use |SSL_SESSION_from_bytes| instead. +OPENSSL_EXPORT SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const uint8_t **pp, + long length); + +// i2d_SSL_SESSION_bio serializes |session| and writes the result to |bio|. It +// returns the number of bytes written on success and <= 0 on error. +OPENSSL_EXPORT int i2d_SSL_SESSION_bio(BIO *bio, const SSL_SESSION *session); + +// d2i_SSL_SESSION_bio reads a serialized |SSL_SESSION| from |bio| and returns a +// newly-allocated |SSL_SESSION| or NULL on error. If |out| is not NULL, it also +// frees |*out| and sets |*out| to the new |SSL_SESSION|. +OPENSSL_EXPORT SSL_SESSION *d2i_SSL_SESSION_bio(BIO *bio, SSL_SESSION **out); + +// ERR_load_SSL_strings does nothing. +OPENSSL_EXPORT void ERR_load_SSL_strings(void); + +// SSL_load_error_strings does nothing. +OPENSSL_EXPORT void SSL_load_error_strings(void); + +// SSL_CTX_set_tlsext_use_srtp calls |SSL_CTX_set_srtp_profiles|. It returns +// zero on success and one on failure. +// +// WARNING: this function is dangerous because it breaks the usual return value +// convention. Use |SSL_CTX_set_srtp_profiles| instead. +OPENSSL_EXPORT int SSL_CTX_set_tlsext_use_srtp(SSL_CTX *ctx, + const char *profiles); + +// SSL_set_tlsext_use_srtp calls |SSL_set_srtp_profiles|. It returns zero on +// success and one on failure. +// +// WARNING: this function is dangerous because it breaks the usual return value +// convention. Use |SSL_set_srtp_profiles| instead. +OPENSSL_EXPORT int SSL_set_tlsext_use_srtp(SSL *ssl, const char *profiles); + +// SSL_get_current_compression returns NULL. +OPENSSL_EXPORT const COMP_METHOD *SSL_get_current_compression(SSL *ssl); + +// SSL_get_current_expansion returns NULL. +OPENSSL_EXPORT const COMP_METHOD *SSL_get_current_expansion(SSL *ssl); + +// SSL_get_server_tmp_key returns zero. +OPENSSL_EXPORT int *SSL_get_server_tmp_key(SSL *ssl, EVP_PKEY **out_key); + +// SSL_CTX_set_tmp_dh returns 1. +OPENSSL_EXPORT int SSL_CTX_set_tmp_dh(SSL_CTX *ctx, const DH *dh); + +// SSL_set_tmp_dh returns 1. +OPENSSL_EXPORT int SSL_set_tmp_dh(SSL *ssl, const DH *dh); + +// SSL_CTX_set_tmp_dh_callback does nothing. +OPENSSL_EXPORT void SSL_CTX_set_tmp_dh_callback( + SSL_CTX *ctx, DH *(*cb)(SSL *ssl, int is_export, int keylength)); + +// SSL_set_tmp_dh_callback does nothing. +OPENSSL_EXPORT void SSL_set_tmp_dh_callback(SSL *ssl, + DH *(*cb)(SSL *ssl, int is_export, + int keylength)); + + +#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))) + +#define OpenSSL_add_ssl_algorithms() SSL_library_init() +#define SSLeay_add_ssl_algorithms() SSL_library_init() + +#define SSL_get_cipher(ssl) SSL_CIPHER_get_name(SSL_get_current_cipher(ssl)) +#define SSL_get_cipher_bits(ssl, out_alg_bits) \ + SSL_CIPHER_get_bits(SSL_get_current_cipher(ssl), out_alg_bits) +#define SSL_get_cipher_version(ssl) \ + SSL_CIPHER_get_version(SSL_get_current_cipher(ssl)) +#define SSL_get_cipher_name(ssl) \ + SSL_CIPHER_get_name(SSL_get_current_cipher(ssl)) +#define SSL_get_time(session) SSL_SESSION_get_time(session) +#define SSL_set_time(session, time) SSL_SESSION_set_time((session), (time)) +#define SSL_get_timeout(session) SSL_SESSION_get_timeout(session) +#define SSL_set_timeout(session, timeout) \ + SSL_SESSION_set_timeout((session), (timeout)) + +struct ssl_comp_st { + int id; + const char *name; + char *method; +}; + +DEFINE_STACK_OF(SSL_COMP) + +// The following flags do nothing and are included only to make it easier to +// compile code with BoringSSL. +#define SSL_MODE_AUTO_RETRY 0 +#define SSL_MODE_RELEASE_BUFFERS 0 +#define SSL_MODE_SEND_CLIENTHELLO_TIME 0 +#define SSL_MODE_SEND_SERVERHELLO_TIME 0 +#define SSL_OP_ALL 0 +#define SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION 0 +#define SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS 0 +#define SSL_OP_EPHEMERAL_RSA 0 +#define SSL_OP_LEGACY_SERVER_CONNECT 0 +#define SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER 0 +#define SSL_OP_MICROSOFT_SESS_ID_BUG 0 +#define SSL_OP_MSIE_SSLV2_RSA_PADDING 0 +#define SSL_OP_NETSCAPE_CA_DN_BUG 0 +#define SSL_OP_NETSCAPE_CHALLENGE_BUG 0 +#define SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG 0 +#define SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG 0 +#define SSL_OP_NO_COMPRESSION 0 +#define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0 +#define SSL_OP_NO_SSLv2 0 +#define SSL_OP_PKCS1_CHECK_1 0 +#define SSL_OP_PKCS1_CHECK_2 0 +#define SSL_OP_SINGLE_DH_USE 0 +#define SSL_OP_SINGLE_ECDH_USE 0 +#define SSL_OP_SSLEAY_080_CLIENT_DH_BUG 0 +#define SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG 0 +#define SSL_OP_TLS_BLOCK_PADDING_BUG 0 +#define SSL_OP_TLS_D5_BUG 0 +#define SSL_OP_TLS_ROLLBACK_BUG 0 +#define SSL_VERIFY_CLIENT_ONCE 0 + +// SSL_cache_hit calls |SSL_session_reused|. +OPENSSL_EXPORT int SSL_cache_hit(SSL *ssl); + +// SSL_get_default_timeout returns |SSL_DEFAULT_SESSION_TIMEOUT|. +OPENSSL_EXPORT long SSL_get_default_timeout(const SSL *ssl); + +// SSL_get_version returns a string describing the TLS version used by |ssl|. +// For example, "TLSv1.2" or "SSLv3". +OPENSSL_EXPORT const char *SSL_get_version(const SSL *ssl); + +// SSL_get_cipher_list returns the name of the |n|th cipher in the output of +// |SSL_get_ciphers| or NULL if out of range. Use |SSL_get_ciphers| instead. +OPENSSL_EXPORT const char *SSL_get_cipher_list(const SSL *ssl, int n); + +// SSL_CTX_set_client_cert_cb sets a callback which is called on the client if +// the server requests a client certificate and none is configured. On success, +// the callback should return one and set |*out_x509| to |*out_pkey| to a leaf +// certificate and private key, respectively, passing ownership. It should +// return zero to send no certificate and -1 to fail or pause the handshake. If +// the handshake is paused, |SSL_get_error| will return +// |SSL_ERROR_WANT_X509_LOOKUP|. +// +// The callback may call |SSL_get0_certificate_types| and +// |SSL_get_client_CA_list| for information on the server's certificate request. +// +// Use |SSL_CTX_set_cert_cb| instead. Configuring intermediate certificates with +// this function is confusing. This callback may not be registered concurrently +// with |SSL_CTX_set_cert_cb| or |SSL_set_cert_cb|. +OPENSSL_EXPORT void SSL_CTX_set_client_cert_cb( + SSL_CTX *ctx, int (*cb)(SSL *ssl, X509 **out_x509, EVP_PKEY **out_pkey)); + +#define SSL_NOTHING 1 +#define SSL_WRITING 2 +#define SSL_READING 3 +#define SSL_X509_LOOKUP 4 +#define SSL_CHANNEL_ID_LOOKUP 5 +#define SSL_PENDING_SESSION 7 +#define SSL_CERTIFICATE_SELECTION_PENDING 8 +#define SSL_PRIVATE_KEY_OPERATION 9 +#define SSL_PENDING_TICKET 10 +#define SSL_EARLY_DATA_REJECTED 11 +#define SSL_CERTIFICATE_VERIFY 12 +#define SSL_HANDOFF 13 + +// SSL_want returns one of the above values to determine what the most recent +// operation on |ssl| was blocked on. Use |SSL_get_error| instead. +OPENSSL_EXPORT int SSL_want(const SSL *ssl); + +#define SSL_want_read(ssl) (SSL_want(ssl) == SSL_READING) +#define SSL_want_write(ssl) (SSL_want(ssl) == SSL_WRITING) + + // SSL_get_finished writes up to |count| bytes of the Finished message sent by + // |ssl| to |buf|. It returns the total untruncated length or zero if none has + // been sent yet. At SSL 3.0 or TLS 1.3 and later, it returns zero. + // + // Use |SSL_get_tls_unique| instead. +OPENSSL_EXPORT size_t SSL_get_finished(const SSL *ssl, void *buf, size_t count); + + // SSL_get_peer_finished writes up to |count| bytes of the Finished message + // received from |ssl|'s peer to |buf|. It returns the total untruncated length + // or zero if none has been received yet. At SSL 3.0 or TLS 1.3 and later, it + // returns zero. + // + // Use |SSL_get_tls_unique| instead. +OPENSSL_EXPORT size_t SSL_get_peer_finished(const SSL *ssl, void *buf, + size_t count); + +// SSL_alert_type_string returns "!". Use |SSL_alert_type_string_long| +// instead. +OPENSSL_EXPORT const char *SSL_alert_type_string(int value); + +// SSL_alert_desc_string returns "!!". Use |SSL_alert_desc_string_long| +// instead. +OPENSSL_EXPORT const char *SSL_alert_desc_string(int value); + +// SSL_state_string returns "!!!!!!". Use |SSL_state_string_long| for a more +// intelligible string. +OPENSSL_EXPORT const char *SSL_state_string(const SSL *ssl); + +// SSL_TXT_* expand to strings. +#define SSL_TXT_MEDIUM "MEDIUM" +#define SSL_TXT_HIGH "HIGH" +#define SSL_TXT_FIPS "FIPS" +#define SSL_TXT_kRSA "kRSA" +#define SSL_TXT_kDHE "kDHE" +#define SSL_TXT_kEDH "kEDH" +#define SSL_TXT_kECDHE "kECDHE" +#define SSL_TXT_kEECDH "kEECDH" +#define SSL_TXT_kPSK "kPSK" +#define SSL_TXT_aRSA "aRSA" +#define SSL_TXT_aECDSA "aECDSA" +#define SSL_TXT_aPSK "aPSK" +#define SSL_TXT_DH "DH" +#define SSL_TXT_DHE "DHE" +#define SSL_TXT_EDH "EDH" +#define SSL_TXT_RSA "RSA" +#define SSL_TXT_ECDH "ECDH" +#define SSL_TXT_ECDHE "ECDHE" +#define SSL_TXT_EECDH "EECDH" +#define SSL_TXT_ECDSA "ECDSA" +#define SSL_TXT_PSK "PSK" +#define SSL_TXT_3DES "3DES" +#define SSL_TXT_RC4 "RC4" +#define SSL_TXT_AES128 "AES128" +#define SSL_TXT_AES256 "AES256" +#define SSL_TXT_AES "AES" +#define SSL_TXT_AES_GCM "AESGCM" +#define SSL_TXT_CHACHA20 "CHACHA20" +#define SSL_TXT_MD5 "MD5" +#define SSL_TXT_SHA1 "SHA1" +#define SSL_TXT_SHA "SHA" +#define SSL_TXT_SHA256 "SHA256" +#define SSL_TXT_SHA384 "SHA384" +#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_TLSV1_3 "TLSv1.3" +#define SSL_TXT_ALL "ALL" +#define SSL_TXT_CMPDEF "COMPLEMENTOFDEFAULT" + +typedef struct ssl_conf_ctx_st SSL_CONF_CTX; + +// SSL_state returns |SSL_ST_INIT| if a handshake is in progress and |SSL_ST_OK| +// otherwise. +// +// Use |SSL_is_init| instead. +OPENSSL_EXPORT int SSL_state(const SSL *ssl); + +#define SSL_get_state(ssl) SSL_state(ssl) + +// SSL_set_shutdown causes |ssl| to behave as if the shutdown bitmask (see +// |SSL_get_shutdown|) were |mode|. This may be used to skip sending or +// receiving close_notify in |SSL_shutdown| by causing the implementation to +// believe the events already happened. +// +// It is an error to use |SSL_set_shutdown| to unset a bit that has already been +// set. Doing so will trigger an |assert| in debug builds and otherwise be +// ignored. +// +// Use |SSL_CTX_set_quiet_shutdown| instead. +OPENSSL_EXPORT void SSL_set_shutdown(SSL *ssl, int mode); + +// SSL_CTX_set_tmp_ecdh calls |SSL_CTX_set1_curves| with a one-element list +// containing |ec_key|'s curve. +OPENSSL_EXPORT int SSL_CTX_set_tmp_ecdh(SSL_CTX *ctx, const EC_KEY *ec_key); + +// SSL_set_tmp_ecdh calls |SSL_set1_curves| with a one-element list containing +// |ec_key|'s curve. +OPENSSL_EXPORT int SSL_set_tmp_ecdh(SSL *ssl, const EC_KEY *ec_key); + +// SSL_add_dir_cert_subjects_to_stack lists files in directory |dir|. It calls +// |SSL_add_file_cert_subjects_to_stack| on each file and returns one on success +// or zero on error. This function is only available from the libdecrepit +// library. +OPENSSL_EXPORT int SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *out, + const char *dir); + +// SSL_set_verify_result calls |abort| unless |result| is |X509_V_OK|. +// +// TODO(davidben): Remove this function once it has been removed from +// netty-tcnative. +OPENSSL_EXPORT void SSL_set_verify_result(SSL *ssl, long result); + +// SSL_CTX_enable_tls_channel_id calls |SSL_CTX_set_tls_channel_id_enabled|. +OPENSSL_EXPORT int SSL_CTX_enable_tls_channel_id(SSL_CTX *ctx); + +// SSL_enable_tls_channel_id calls |SSL_set_tls_channel_id_enabled|. +OPENSSL_EXPORT int SSL_enable_tls_channel_id(SSL *ssl); + +// BIO_f_ssl returns a |BIO_METHOD| that can wrap an |SSL*| in a |BIO*|. Note +// that this has quite different behaviour from the version in OpenSSL (notably +// that it doesn't try to auto renegotiate). +// +// IMPORTANT: if you are not curl, don't use this. +OPENSSL_EXPORT const BIO_METHOD *BIO_f_ssl(void); + +// BIO_set_ssl sets |ssl| as the underlying connection for |bio|, which must +// have been created using |BIO_f_ssl|. If |take_owership| is true, |bio| will +// call |SSL_free| on |ssl| when closed. It returns one on success or something +// other than one on error. +OPENSSL_EXPORT long BIO_set_ssl(BIO *bio, SSL *ssl, int take_owership); + +// SSL_CTX_set_ecdh_auto returns one. +#define SSL_CTX_set_ecdh_auto(ctx, onoff) 1 + +// SSL_set_ecdh_auto returns one. +#define SSL_set_ecdh_auto(ssl, onoff) 1 + +// SSL_get_session returns a non-owning pointer to |ssl|'s session. For +// historical reasons, which session it returns depends on |ssl|'s state. +// +// Prior to the start of the initial handshake, it returns the session the +// caller set with |SSL_set_session|. After the initial handshake has finished +// and if no additional handshakes are in progress, it returns the currently +// active session. Its behavior is undefined while a handshake is in progress. +// +// If trying to add new sessions to an external session cache, use +// |SSL_CTX_sess_set_new_cb| instead. In particular, using the callback is +// required as of TLS 1.3. For compatibility, this function will return an +// unresumable session which may be cached, but will never be resumed. +// +// If querying properties of the connection, use APIs on the |SSL| object. +OPENSSL_EXPORT SSL_SESSION *SSL_get_session(const SSL *ssl); + +// SSL_get0_session is an alias for |SSL_get_session|. +#define SSL_get0_session SSL_get_session + +// SSL_get1_session acts like |SSL_get_session| but returns a new reference to +// the session. +OPENSSL_EXPORT SSL_SESSION *SSL_get1_session(SSL *ssl); + +#define OPENSSL_INIT_NO_LOAD_SSL_STRINGS 0 +#define OPENSSL_INIT_LOAD_SSL_STRINGS 0 +#define OPENSSL_INIT_SSL_DEFAULT 0 + +// OPENSSL_init_ssl calls |CRYPTO_library_init| and returns one. +OPENSSL_EXPORT int OPENSSL_init_ssl(uint64_t opts, + const OPENSSL_INIT_SETTINGS *settings); + +#if !defined(BORINGSSL_NO_CXX) +// SSL_CTX_sess_set_get_cb is a legacy C++ overload of |SSL_CTX_sess_set_get_cb| +// which supports the old callback signature. +// +// TODO(davidben): Remove this once Node is compatible with OpenSSL 1.1.0. +extern "C++" OPENSSL_EXPORT void SSL_CTX_sess_set_get_cb( + SSL_CTX *ctx, SSL_SESSION *(*get_session_cb)(SSL *ssl, uint8_t *id, + int id_len, int *out_copy)); +#endif + + +// Private structures. +// +// This structures are exposed for historical reasons, but access to them is +// deprecated. + +// TODO(davidben): Remove this forward declaration when |SSL_SESSION| is opaque. +typedef struct ssl_x509_method_st SSL_X509_METHOD; + +#define SSL_MAX_SSL_SESSION_ID_LENGTH 32 +#define SSL_MAX_SID_CTX_LENGTH 32 +#define SSL_MAX_MASTER_KEY_LENGTH 48 + +struct ssl_session_st { + CRYPTO_refcount_t references; + uint16_t ssl_version; // what ssl version session info is being kept in here? + + // group_id is the ID of the ECDH group used to establish this session or zero + // if not applicable or unknown. + uint16_t group_id; + + // peer_signature_algorithm is the signature algorithm used to authenticate + // the peer, or zero if not applicable or unknown. + uint16_t peer_signature_algorithm; + + // master_key, in TLS 1.2 and below, is the master secret associated with the + // session. In TLS 1.3 and up, it is the resumption secret. + int master_key_length; + uint8_t master_key[SSL_MAX_MASTER_KEY_LENGTH]; + + // session_id - valid? + unsigned int session_id_length; + uint8_t 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 + uint8_t sid_ctx_length; + uint8_t sid_ctx[SSL_MAX_SID_CTX_LENGTH]; + + char *psk_identity; + + // certs contains the certificate chain from the peer, starting with the leaf + // certificate. + STACK_OF(CRYPTO_BUFFER) *certs; + + const SSL_X509_METHOD *x509_method; + + // x509_peer is the peer's certificate. + X509 *x509_peer; + + // x509_chain is the certificate chain sent by the peer. NOTE: for historical + // reasons, when a client (so the peer is a server), the chain includes + // |peer|, but when a server it does not. + STACK_OF(X509) *x509_chain; + + // x509_chain_without_leaf is a lazily constructed copy of |x509_chain| that + // omits the leaf certificate. This exists because OpenSSL, historically, + // didn't include the leaf certificate in the chain for a server, but did for + // a client. The |x509_chain| always includes it and, if an API call requires + // a chain without, it is stored here. + STACK_OF(X509) *x509_chain_without_leaf; + + // verify_result is the result of certificate verification in the case of + // non-fatal certificate errors. + long verify_result; + + // timeout is the lifetime of the session in seconds, measured from |time|. + // This is renewable up to |auth_timeout|. + uint32_t timeout; + + // auth_timeout is the non-renewable lifetime of the session in seconds, + // measured from |time|. + uint32_t auth_timeout; + + // time is the time the session was issued, measured in seconds from the UNIX + // epoch. + uint64_t time; + + const SSL_CIPHER *cipher; + + 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. + SSL_SESSION *prev, *next; + + // RFC4507 info + uint8_t *tlsext_tick; // Session ticket + size_t tlsext_ticklen; // Session ticket length + + CRYPTO_BUFFER *signed_cert_timestamp_list; + + // The OCSP response that came with the session. + CRYPTO_BUFFER *ocsp_response; + + // peer_sha256 contains the SHA-256 hash of the peer's certificate if + // |peer_sha256_valid| is true. + uint8_t peer_sha256[SHA256_DIGEST_LENGTH]; + + // original_handshake_hash contains the handshake hash (either SHA-1+MD5 or + // SHA-2, depending on TLS version) for the original, full handshake that + // created a session. This is used by Channel IDs during resumption. + uint8_t original_handshake_hash[EVP_MAX_MD_SIZE]; + uint8_t original_handshake_hash_len; + + uint32_t tlsext_tick_lifetime_hint; // Session lifetime hint in seconds + + uint32_t ticket_age_add; + + // ticket_max_early_data is the maximum amount of data allowed to be sent as + // early data. If zero, 0-RTT is disallowed. + uint32_t ticket_max_early_data; + + // early_alpn is the ALPN protocol from the initial handshake. This is only + // stored for TLS 1.3 and above in order to enforce ALPN matching for 0-RTT + // resumptions. + uint8_t *early_alpn; + size_t early_alpn_len; + + // extended_master_secret is true if the master secret in this session was + // generated using EMS and thus isn't vulnerable to the Triple Handshake + // attack. + unsigned extended_master_secret:1; + + // peer_sha256_valid is non-zero if |peer_sha256| is valid. + unsigned peer_sha256_valid:1; // Non-zero if peer_sha256 is valid + + // not_resumable is used to indicate that session resumption is disallowed. + unsigned not_resumable:1; + + // ticket_age_add_valid is non-zero if |ticket_age_add| is valid. + unsigned ticket_age_add_valid:1; + + // is_server is true if this session was created by a server. + unsigned is_server:1; +}; + + +// Nodejs compatibility section (hidden). +// +// These defines exist for node.js, with the hope that we can eliminate the +// need for them over time. +#define SSLerr(function, reason) \ + ERR_put_error(ERR_LIB_SSL, 0, reason, __FILE__, __LINE__) + + +// Preprocessor compatibility section (hidden). +// +// Historically, a number of APIs were implemented in OpenSSL as macros and +// constants to 'ctrl' functions. To avoid breaking #ifdefs in consumers, this +// section defines a number of legacy macros. +// +// Although using either the CTRL values or their wrapper macros in #ifdefs is +// still supported, the CTRL values may not be passed to |SSL_ctrl| and +// |SSL_CTX_ctrl|. Call the functions (previously wrapper macros) instead. +// +// See PORTING.md in the BoringSSL source tree for a table of corresponding +// functions. +// https://boringssl.googlesource.com/boringssl/+/master/PORTING.md#Replacements-for-values + +#define DTLS_CTRL_GET_TIMEOUT doesnt_exist +#define DTLS_CTRL_HANDLE_TIMEOUT doesnt_exist +#define SSL_CTRL_CHAIN doesnt_exist +#define SSL_CTRL_CHAIN_CERT doesnt_exist +#define SSL_CTRL_CHANNEL_ID doesnt_exist +#define SSL_CTRL_CLEAR_EXTRA_CHAIN_CERTS doesnt_exist +#define SSL_CTRL_CLEAR_MODE doesnt_exist +#define SSL_CTRL_CLEAR_OPTIONS doesnt_exist +#define SSL_CTRL_EXTRA_CHAIN_CERT doesnt_exist +#define SSL_CTRL_GET_CHAIN_CERTS doesnt_exist +#define SSL_CTRL_GET_CHANNEL_ID doesnt_exist +#define SSL_CTRL_GET_CLIENT_CERT_TYPES doesnt_exist +#define SSL_CTRL_GET_EXTRA_CHAIN_CERTS doesnt_exist +#define SSL_CTRL_GET_MAX_CERT_LIST doesnt_exist +#define SSL_CTRL_GET_NUM_RENEGOTIATIONS doesnt_exist +#define SSL_CTRL_GET_READ_AHEAD doesnt_exist +#define SSL_CTRL_GET_RI_SUPPORT doesnt_exist +#define SSL_CTRL_GET_SESSION_REUSED doesnt_exist +#define SSL_CTRL_GET_SESS_CACHE_MODE doesnt_exist +#define SSL_CTRL_GET_SESS_CACHE_SIZE doesnt_exist +#define SSL_CTRL_GET_TLSEXT_TICKET_KEYS doesnt_exist +#define SSL_CTRL_GET_TOTAL_RENEGOTIATIONS doesnt_exist +#define SSL_CTRL_MODE doesnt_exist +#define SSL_CTRL_NEED_TMP_RSA doesnt_exist +#define SSL_CTRL_OPTIONS doesnt_exist +#define SSL_CTRL_SESS_NUMBER doesnt_exist +#define SSL_CTRL_SET_CURVES doesnt_exist +#define SSL_CTRL_SET_CURVES_LIST doesnt_exist +#define SSL_CTRL_SET_ECDH_AUTO doesnt_exist +#define SSL_CTRL_SET_MAX_CERT_LIST doesnt_exist +#define SSL_CTRL_SET_MAX_SEND_FRAGMENT doesnt_exist +#define SSL_CTRL_SET_MSG_CALLBACK doesnt_exist +#define SSL_CTRL_SET_MSG_CALLBACK_ARG doesnt_exist +#define SSL_CTRL_SET_MTU doesnt_exist +#define SSL_CTRL_SET_READ_AHEAD doesnt_exist +#define SSL_CTRL_SET_SESS_CACHE_MODE doesnt_exist +#define SSL_CTRL_SET_SESS_CACHE_SIZE doesnt_exist +#define SSL_CTRL_SET_TLSEXT_HOSTNAME doesnt_exist +#define SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG doesnt_exist +#define SSL_CTRL_SET_TLSEXT_SERVERNAME_CB doesnt_exist +#define SSL_CTRL_SET_TLSEXT_TICKET_KEYS doesnt_exist +#define SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB doesnt_exist +#define SSL_CTRL_SET_TMP_DH doesnt_exist +#define SSL_CTRL_SET_TMP_DH_CB doesnt_exist +#define SSL_CTRL_SET_TMP_ECDH doesnt_exist +#define SSL_CTRL_SET_TMP_ECDH_CB doesnt_exist +#define SSL_CTRL_SET_TMP_RSA doesnt_exist +#define SSL_CTRL_SET_TMP_RSA_CB doesnt_exist + +#define SSL_CTX_set_tlsext_servername_callback \ + SSL_CTX_set_tlsext_servername_callback +#define SSL_get_secure_renegotiation_support \ + SSL_get_secure_renegotiation_support + + +#if defined(__cplusplus) +} // extern C + +#if !defined(BORINGSSL_NO_CXX) + +extern "C++" { + +namespace bssl { + +BORINGSSL_MAKE_DELETER(SSL, SSL_free) +BORINGSSL_MAKE_DELETER(SSL_CTX, SSL_CTX_free) +BORINGSSL_MAKE_DELETER(SSL_SESSION, SSL_SESSION_free) + +enum class OpenRecordResult { + kOK, + kDiscard, + kIncompleteRecord, + kAlertCloseNotify, + kError, +}; + +// *** EXPERIMENTAL -- DO NOT USE *** +// +// OpenRecord decrypts the first complete SSL record from |in| in-place, sets +// |out| to the decrypted application data, and |out_record_len| to the length +// of the encrypted record. Returns: +// - kOK if an application-data record was successfully decrypted and verified. +// - kDiscard if a record was sucessfully processed, but should be discarded. +// - kIncompleteRecord if |in| did not contain a complete record. +// - kAlertCloseNotify if a record was successfully processed but is a +// close_notify alert. +// - kError if an error occurred or the record is invalid. |*out_alert| will be +// set to an alert to emit, or zero if no alert should be emitted. +OPENSSL_EXPORT OpenRecordResult OpenRecord(SSL *ssl, Span *out, + size_t *out_record_len, + uint8_t *out_alert, + Span in); + +OPENSSL_EXPORT size_t SealRecordPrefixLen(const SSL *ssl, size_t plaintext_len); + +// SealRecordSuffixLen returns the length of the suffix written by |SealRecord|. +// +// |plaintext_len| must be equal to the size of the plaintext passed to +// |SealRecord|. +// +// |plaintext_len| must not exceed |SSL3_RT_MAX_PLAINTEXT_LENGTH|. The returned +// suffix length will not exceed |SSL3_RT_MAX_ENCRYPTED_OVERHEAD|. +OPENSSL_EXPORT size_t SealRecordSuffixLen(const SSL *ssl, size_t plaintext_len); + +// *** EXPERIMENTAL -- DO NOT USE *** +// +// SealRecord encrypts the cleartext of |in| and scatters the resulting TLS +// application data record between |out_prefix|, |out|, and |out_suffix|. It +// returns true on success or false if an error occurred. +// +// The length of |out_prefix| must equal |SealRecordPrefixLen|. The length of +// |out| must equal the length of |in|, which must not exceed +// |SSL3_RT_MAX_PLAINTEXT_LENGTH|. The length of |out_suffix| must equal +// |SealRecordSuffixLen|. +// +// If enabled, |SealRecord| may perform TLS 1.0 CBC 1/n-1 record splitting. +// |SealRecordPrefixLen| accounts for the required overhead if that is the case. +// +// |out| may equal |in| to encrypt in-place but may not otherwise alias. +// |out_prefix| and |out_suffix| may not alias anything. +OPENSSL_EXPORT bool SealRecord(SSL *ssl, Span out_prefix, + Span out, Span out_suffix, + Span in); + + +// *** EXPERIMENTAL — DO NOT USE WITHOUT CHECKING *** +// +// Split handshakes. +// +// Split handshakes allows the handshake part of a TLS connection to be +// performed in a different process (or on a different machine) than the data +// exchange. This only applies to servers. +// +// In the first part of a split handshake, an |SSL| (where the |SSL_CTX| has +// been configured with |SSL_CTX_set_handoff_mode|) is used normally. Once the +// ClientHello message has been received, the handshake will stop and +// |SSL_get_error| will indicate |SSL_ERROR_HANDOFF|. At this point (and only +// at this point), |SSL_serialize_handoff| can be called to write the “handoff” +// state of the connection. +// +// Elsewhere, a fresh |SSL| can be used with |SSL_apply_handoff| to continue +// the connection. The connection from the client is fed into this |SSL| until +// the handshake completes normally. At this point (and only at this point), +// |SSL_serialize_handback| can be called to serialize the result of the +// handshake. +// +// Back at the first location, a fresh |SSL| can be used with +// |SSL_apply_handback|. Then the client's connection can be processed mostly +// as normal. +// +// Lastly, when a connection is in the handoff state, whether or not +// |SSL_serialize_handoff| is called, |SSL_decline_handoff| will move it back +// into a normal state where the connection can procede without impact. +// +// WARNING: Currently only works with TLS 1.0–1.2. +// WARNING: The serialisation formats are not yet stable: version skew may be +// fatal. +// WARNING: The handback data contains sensitive key material and must be +// protected. +// WARNING: Some calls on the final |SSL| will not work. Just as an example, +// calls like |SSL_get0_session_id_context| and |SSL_get_privatekey| won't +// work because the certificate used for handshaking isn't available. +// WARNING: |SSL_apply_handoff| may trigger “msg” callback calls. + +OPENSSL_EXPORT void SSL_CTX_set_handoff_mode(SSL_CTX *ctx, bool on); +OPENSSL_EXPORT bool SSL_serialize_handoff(const SSL *ssl, CBB *out); +OPENSSL_EXPORT bool SSL_decline_handoff(SSL *ssl); +OPENSSL_EXPORT bool SSL_apply_handoff(SSL *ssl, Span handoff); +OPENSSL_EXPORT bool SSL_serialize_handback(const SSL *ssl, CBB *out); +OPENSSL_EXPORT bool SSL_apply_handback(SSL *ssl, Span handback); + +} // namespace bssl + +} // extern C++ + +#endif // !defined(BORINGSSL_NO_CXX) + +#endif + +#define SSL_R_APP_DATA_IN_HANDSHAKE 100 +#define SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT 101 +#define SSL_R_BAD_ALERT 102 +#define SSL_R_BAD_CHANGE_CIPHER_SPEC 103 +#define SSL_R_BAD_DATA_RETURNED_BY_CALLBACK 104 +#define SSL_R_BAD_DH_P_LENGTH 105 +#define SSL_R_BAD_DIGEST_LENGTH 106 +#define SSL_R_BAD_ECC_CERT 107 +#define SSL_R_BAD_ECPOINT 108 +#define SSL_R_BAD_HANDSHAKE_RECORD 109 +#define SSL_R_BAD_HELLO_REQUEST 110 +#define SSL_R_BAD_LENGTH 111 +#define SSL_R_BAD_PACKET_LENGTH 112 +#define SSL_R_BAD_RSA_ENCRYPT 113 +#define SSL_R_BAD_SIGNATURE 114 +#define SSL_R_BAD_SRTP_MKI_VALUE 115 +#define SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST 116 +#define SSL_R_BAD_SSL_FILETYPE 117 +#define SSL_R_BAD_WRITE_RETRY 118 +#define SSL_R_BIO_NOT_SET 119 +#define SSL_R_BN_LIB 120 +#define SSL_R_BUFFER_TOO_SMALL 121 +#define SSL_R_CA_DN_LENGTH_MISMATCH 122 +#define SSL_R_CA_DN_TOO_LONG 123 +#define SSL_R_CCS_RECEIVED_EARLY 124 +#define SSL_R_CERTIFICATE_VERIFY_FAILED 125 +#define SSL_R_CERT_CB_ERROR 126 +#define SSL_R_CERT_LENGTH_MISMATCH 127 +#define SSL_R_CHANNEL_ID_NOT_P256 128 +#define SSL_R_CHANNEL_ID_SIGNATURE_INVALID 129 +#define SSL_R_CIPHER_OR_HASH_UNAVAILABLE 130 +#define SSL_R_CLIENTHELLO_PARSE_FAILED 131 +#define SSL_R_CLIENTHELLO_TLSEXT 132 +#define SSL_R_CONNECTION_REJECTED 133 +#define SSL_R_CONNECTION_TYPE_NOT_SET 134 +#define SSL_R_CUSTOM_EXTENSION_ERROR 135 +#define SSL_R_DATA_LENGTH_TOO_LONG 136 +#define SSL_R_DECODE_ERROR 137 +#define SSL_R_DECRYPTION_FAILED 138 +#define SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC 139 +#define SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG 140 +#define SSL_R_DH_P_TOO_LONG 141 +#define SSL_R_DIGEST_CHECK_FAILED 142 +#define SSL_R_DTLS_MESSAGE_TOO_BIG 143 +#define SSL_R_ECC_CERT_NOT_FOR_SIGNING 144 +#define SSL_R_EMS_STATE_INCONSISTENT 145 +#define SSL_R_ENCRYPTED_LENGTH_TOO_LONG 146 +#define SSL_R_ERROR_ADDING_EXTENSION 147 +#define SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST 148 +#define SSL_R_ERROR_PARSING_EXTENSION 149 +#define SSL_R_EXCESSIVE_MESSAGE_SIZE 150 +#define SSL_R_EXTRA_DATA_IN_MESSAGE 151 +#define SSL_R_FRAGMENT_MISMATCH 152 +#define SSL_R_GOT_NEXT_PROTO_WITHOUT_EXTENSION 153 +#define SSL_R_HANDSHAKE_FAILURE_ON_CLIENT_HELLO 154 +#define SSL_R_HTTPS_PROXY_REQUEST 155 +#define SSL_R_HTTP_REQUEST 156 +#define SSL_R_INAPPROPRIATE_FALLBACK 157 +#define SSL_R_INVALID_COMMAND 158 +#define SSL_R_INVALID_MESSAGE 159 +#define SSL_R_INVALID_SSL_SESSION 160 +#define SSL_R_INVALID_TICKET_KEYS_LENGTH 161 +#define SSL_R_LENGTH_MISMATCH 162 +#define SSL_R_MISSING_EXTENSION 164 +#define SSL_R_MISSING_RSA_CERTIFICATE 165 +#define SSL_R_MISSING_TMP_DH_KEY 166 +#define SSL_R_MISSING_TMP_ECDH_KEY 167 +#define SSL_R_MIXED_SPECIAL_OPERATOR_WITH_GROUPS 168 +#define SSL_R_MTU_TOO_SMALL 169 +#define SSL_R_NEGOTIATED_BOTH_NPN_AND_ALPN 170 +#define SSL_R_NESTED_GROUP 171 +#define SSL_R_NO_CERTIFICATES_RETURNED 172 +#define SSL_R_NO_CERTIFICATE_ASSIGNED 173 +#define SSL_R_NO_CERTIFICATE_SET 174 +#define SSL_R_NO_CIPHERS_AVAILABLE 175 +#define SSL_R_NO_CIPHERS_PASSED 176 +#define SSL_R_NO_CIPHER_MATCH 177 +#define SSL_R_NO_COMPRESSION_SPECIFIED 178 +#define SSL_R_NO_METHOD_SPECIFIED 179 +#define SSL_R_NO_P256_SUPPORT 180 +#define SSL_R_NO_PRIVATE_KEY_ASSIGNED 181 +#define SSL_R_NO_RENEGOTIATION 182 +#define SSL_R_NO_REQUIRED_DIGEST 183 +#define SSL_R_NO_SHARED_CIPHER 184 +#define SSL_R_NULL_SSL_CTX 185 +#define SSL_R_NULL_SSL_METHOD_PASSED 186 +#define SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED 187 +#define SSL_R_OLD_SESSION_VERSION_NOT_RETURNED 188 +#define SSL_R_OUTPUT_ALIASES_INPUT 189 +#define SSL_R_PARSE_TLSEXT 190 +#define SSL_R_PATH_TOO_LONG 191 +#define SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE 192 +#define SSL_R_PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE 193 +#define SSL_R_PROTOCOL_IS_SHUTDOWN 194 +#define SSL_R_PSK_IDENTITY_NOT_FOUND 195 +#define SSL_R_PSK_NO_CLIENT_CB 196 +#define SSL_R_PSK_NO_SERVER_CB 197 +#define SSL_R_READ_TIMEOUT_EXPIRED 198 +#define SSL_R_RECORD_LENGTH_MISMATCH 199 +#define SSL_R_RECORD_TOO_LARGE 200 +#define SSL_R_RENEGOTIATION_ENCODING_ERR 201 +#define SSL_R_RENEGOTIATION_MISMATCH 202 +#define SSL_R_REQUIRED_CIPHER_MISSING 203 +#define SSL_R_RESUMED_EMS_SESSION_WITHOUT_EMS_EXTENSION 204 +#define SSL_R_RESUMED_NON_EMS_SESSION_WITH_EMS_EXTENSION 205 +#define SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING 206 +#define SSL_R_SERVERHELLO_TLSEXT 207 +#define SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED 208 +#define SSL_R_SESSION_MAY_NOT_BE_CREATED 209 +#define SSL_R_SIGNATURE_ALGORITHMS_EXTENSION_SENT_BY_SERVER 210 +#define SSL_R_SRTP_COULD_NOT_ALLOCATE_PROFILES 211 +#define SSL_R_SRTP_UNKNOWN_PROTECTION_PROFILE 212 +#define SSL_R_SSL3_EXT_INVALID_SERVERNAME 213 +#define SSL_R_SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION 214 +#define SSL_R_SSL_HANDSHAKE_FAILURE 215 +#define SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG 216 +#define SSL_R_TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST 217 +#define SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG 218 +#define SSL_R_TOO_MANY_EMPTY_FRAGMENTS 219 +#define SSL_R_TOO_MANY_WARNING_ALERTS 220 +#define SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS 221 +#define SSL_R_UNEXPECTED_EXTENSION 222 +#define SSL_R_UNEXPECTED_MESSAGE 223 +#define SSL_R_UNEXPECTED_OPERATOR_IN_GROUP 224 +#define SSL_R_UNEXPECTED_RECORD 225 +#define SSL_R_UNINITIALIZED 226 +#define SSL_R_UNKNOWN_ALERT_TYPE 227 +#define SSL_R_UNKNOWN_CERTIFICATE_TYPE 228 +#define SSL_R_UNKNOWN_CIPHER_RETURNED 229 +#define SSL_R_UNKNOWN_CIPHER_TYPE 230 +#define SSL_R_UNKNOWN_DIGEST 231 +#define SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE 232 +#define SSL_R_UNKNOWN_PROTOCOL 233 +#define SSL_R_UNKNOWN_SSL_VERSION 234 +#define SSL_R_UNKNOWN_STATE 235 +#define SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED 236 +#define SSL_R_UNSUPPORTED_CIPHER 237 +#define SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM 238 +#define SSL_R_UNSUPPORTED_ELLIPTIC_CURVE 239 +#define SSL_R_UNSUPPORTED_PROTOCOL 240 +#define SSL_R_WRONG_CERTIFICATE_TYPE 241 +#define SSL_R_WRONG_CIPHER_RETURNED 242 +#define SSL_R_WRONG_CURVE 243 +#define SSL_R_WRONG_MESSAGE_TYPE 244 +#define SSL_R_WRONG_SIGNATURE_TYPE 245 +#define SSL_R_WRONG_SSL_VERSION 246 +#define SSL_R_WRONG_VERSION_NUMBER 247 +#define SSL_R_X509_LIB 248 +#define SSL_R_X509_VERIFICATION_SETUP_PROBLEMS 249 +#define SSL_R_SHUTDOWN_WHILE_IN_INIT 250 +#define SSL_R_INVALID_OUTER_RECORD_TYPE 251 +#define SSL_R_UNSUPPORTED_PROTOCOL_FOR_CUSTOM_KEY 252 +#define SSL_R_NO_COMMON_SIGNATURE_ALGORITHMS 253 +#define SSL_R_DOWNGRADE_DETECTED 254 +#define SSL_R_BUFFERED_MESSAGES_ON_CIPHER_CHANGE 255 +#define SSL_R_INVALID_COMPRESSION_LIST 256 +#define SSL_R_DUPLICATE_EXTENSION 257 +#define SSL_R_MISSING_KEY_SHARE 258 +#define SSL_R_INVALID_ALPN_PROTOCOL 259 +#define SSL_R_TOO_MANY_KEY_UPDATES 260 +#define SSL_R_BLOCK_CIPHER_PAD_IS_WRONG 261 +#define SSL_R_NO_CIPHERS_SPECIFIED 262 +#define SSL_R_RENEGOTIATION_EMS_MISMATCH 263 +#define SSL_R_DUPLICATE_KEY_SHARE 264 +#define SSL_R_NO_GROUPS_SPECIFIED 265 +#define SSL_R_NO_SHARED_GROUP 266 +#define SSL_R_PRE_SHARED_KEY_MUST_BE_LAST 267 +#define SSL_R_OLD_SESSION_PRF_HASH_MISMATCH 268 +#define SSL_R_INVALID_SCT_LIST 269 +#define SSL_R_TOO_MUCH_SKIPPED_EARLY_DATA 270 +#define SSL_R_PSK_IDENTITY_BINDER_COUNT_MISMATCH 271 +#define SSL_R_CANNOT_PARSE_LEAF_CERT 272 +#define SSL_R_SERVER_CERT_CHANGED 273 +#define SSL_R_CERTIFICATE_AND_PRIVATE_KEY_MISMATCH 274 +#define SSL_R_CANNOT_HAVE_BOTH_PRIVKEY_AND_METHOD 275 +#define SSL_R_TICKET_ENCRYPTION_FAILED 276 +#define SSL_R_ALPN_MISMATCH_ON_EARLY_DATA 277 +#define SSL_R_WRONG_VERSION_ON_EARLY_DATA 278 +#define SSL_R_UNEXPECTED_EXTENSION_ON_EARLY_DATA 279 +#define SSL_R_NO_SUPPORTED_VERSIONS_ENABLED 280 +#define SSL_R_APPLICATION_DATA_INSTEAD_OF_HANDSHAKE 281 +#define SSL_R_EMPTY_HELLO_RETRY_REQUEST 282 +#define SSL_R_EARLY_DATA_NOT_IN_USE 283 +#define SSL_R_HANDSHAKE_NOT_COMPLETE 284 +#define SSL_R_NEGOTIATED_TB_WITHOUT_EMS_OR_RI 285 +#define SSL_R_SERVER_ECHOED_INVALID_SESSION_ID 286 +#define SSL_R_PRIVATE_KEY_OPERATION_FAILED 287 +#define SSL_R_SSLV3_ALERT_CLOSE_NOTIFY 1000 +#define SSL_R_SSLV3_ALERT_UNEXPECTED_MESSAGE 1010 +#define SSL_R_SSLV3_ALERT_BAD_RECORD_MAC 1020 +#define SSL_R_TLSV1_ALERT_DECRYPTION_FAILED 1021 +#define SSL_R_TLSV1_ALERT_RECORD_OVERFLOW 1022 +#define SSL_R_SSLV3_ALERT_DECOMPRESSION_FAILURE 1030 +#define SSL_R_SSLV3_ALERT_HANDSHAKE_FAILURE 1040 +#define SSL_R_SSLV3_ALERT_NO_CERTIFICATE 1041 +#define SSL_R_SSLV3_ALERT_BAD_CERTIFICATE 1042 +#define SSL_R_SSLV3_ALERT_UNSUPPORTED_CERTIFICATE 1043 +#define SSL_R_SSLV3_ALERT_CERTIFICATE_REVOKED 1044 +#define SSL_R_SSLV3_ALERT_CERTIFICATE_EXPIRED 1045 +#define SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN 1046 +#define SSL_R_SSLV3_ALERT_ILLEGAL_PARAMETER 1047 +#define SSL_R_TLSV1_ALERT_UNKNOWN_CA 1048 +#define SSL_R_TLSV1_ALERT_ACCESS_DENIED 1049 +#define SSL_R_TLSV1_ALERT_DECODE_ERROR 1050 +#define SSL_R_TLSV1_ALERT_DECRYPT_ERROR 1051 +#define SSL_R_TLSV1_ALERT_EXPORT_RESTRICTION 1060 +#define SSL_R_TLSV1_ALERT_PROTOCOL_VERSION 1070 +#define SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY 1071 +#define SSL_R_TLSV1_ALERT_INTERNAL_ERROR 1080 +#define SSL_R_TLSV1_ALERT_INAPPROPRIATE_FALLBACK 1086 +#define SSL_R_TLSV1_ALERT_USER_CANCELLED 1090 +#define SSL_R_TLSV1_ALERT_NO_RENEGOTIATION 1100 +#define SSL_R_TLSV1_UNSUPPORTED_EXTENSION 1110 +#define SSL_R_TLSV1_CERTIFICATE_UNOBTAINABLE 1111 +#define SSL_R_TLSV1_UNRECOGNIZED_NAME 1112 +#define SSL_R_TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE 1113 +#define SSL_R_TLSV1_BAD_CERTIFICATE_HASH_VALUE 1114 +#define SSL_R_TLSV1_UNKNOWN_PSK_IDENTITY 1115 +#define SSL_R_TLSV1_CERTIFICATE_REQUIRED 1116 +#define SSL_R_TOO_MUCH_READ_EARLY_DATA 1117 + +#endif // OPENSSL_HEADER_SSL_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/ssl.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/ssl.h.grpc_back new file mode 100644 index 0000000..b377c45 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/ssl.h.grpc_back @@ -0,0 +1,4672 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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. + */ +/* ==================================================================== + * 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 OPENSSL_HEADER_SSL_H +#define OPENSSL_HEADER_SSL_H + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#if !defined(OPENSSL_WINDOWS) +#include +#endif + +// NGINX needs this #include. Consider revisiting this after NGINX 1.14.0 has +// been out for a year or so (assuming that they fix it in that release.) See +// https://boringssl-review.googlesource.com/c/boringssl/+/21664. +#include + +// Forward-declare struct timeval. On Windows, it is defined in winsock2.h and +// Windows headers define too many macros to be included in public headers. +// However, only a forward declaration is needed. +struct timeval; + +#if defined(__cplusplus) +extern "C" { +#endif + + +// SSL implementation. + + +// SSL contexts. +// +// |SSL_CTX| objects manage shared state and configuration between multiple TLS +// or DTLS connections. Whether the connections are TLS or DTLS is selected by +// an |SSL_METHOD| on creation. +// +// |SSL_CTX| are reference-counted and may be shared by connections across +// multiple threads. Once shared, functions which change the |SSL_CTX|'s +// configuration may not be used. + +// TLS_method is the |SSL_METHOD| used for TLS (and SSLv3) connections. +OPENSSL_EXPORT const SSL_METHOD *TLS_method(void); + +// DTLS_method is the |SSL_METHOD| used for DTLS connections. +OPENSSL_EXPORT const SSL_METHOD *DTLS_method(void); + +// TLS_with_buffers_method is like |TLS_method|, but avoids all use of +// crypto/x509. All client connections created with |TLS_with_buffers_method| +// will fail unless a certificate verifier is installed with +// |SSL_set_custom_verify| or |SSL_CTX_set_custom_verify|. +OPENSSL_EXPORT const SSL_METHOD *TLS_with_buffers_method(void); + +// DTLS_with_buffers_method is like |DTLS_method|, but avoids all use of +// crypto/x509. +OPENSSL_EXPORT const SSL_METHOD *DTLS_with_buffers_method(void); + +// SSL_CTX_new returns a newly-allocated |SSL_CTX| with default settings or NULL +// on error. +OPENSSL_EXPORT SSL_CTX *SSL_CTX_new(const SSL_METHOD *method); + +// SSL_CTX_up_ref increments the reference count of |ctx|. It returns one. +OPENSSL_EXPORT int SSL_CTX_up_ref(SSL_CTX *ctx); + +// SSL_CTX_free releases memory associated with |ctx|. +OPENSSL_EXPORT void SSL_CTX_free(SSL_CTX *ctx); + + +// SSL connections. +// +// An |SSL| object represents a single TLS or DTLS connection. Although the +// shared |SSL_CTX| is thread-safe, an |SSL| is not thread-safe and may only be +// used on one thread at a time. + +// SSL_new returns a newly-allocated |SSL| using |ctx| or NULL on error. The new +// connection inherits settings from |ctx| at the time of creation. Settings may +// also be individually configured on the connection. +// +// On creation, an |SSL| is not configured to be either a client or server. Call +// |SSL_set_connect_state| or |SSL_set_accept_state| to set this. +OPENSSL_EXPORT SSL *SSL_new(SSL_CTX *ctx); + +// SSL_free releases memory associated with |ssl|. +OPENSSL_EXPORT void SSL_free(SSL *ssl); + +// SSL_get_SSL_CTX returns the |SSL_CTX| associated with |ssl|. If +// |SSL_set_SSL_CTX| is called, it returns the new |SSL_CTX|, not the initial +// one. +OPENSSL_EXPORT SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl); + +// SSL_set_connect_state configures |ssl| to be a client. +OPENSSL_EXPORT void SSL_set_connect_state(SSL *ssl); + +// SSL_set_accept_state configures |ssl| to be a server. +OPENSSL_EXPORT void SSL_set_accept_state(SSL *ssl); + +// SSL_is_server returns one if |ssl| is configured as a server and zero +// otherwise. +OPENSSL_EXPORT int SSL_is_server(const SSL *ssl); + +// SSL_is_dtls returns one if |ssl| is a DTLS connection and zero otherwise. +OPENSSL_EXPORT int SSL_is_dtls(const SSL *ssl); + +// SSL_set_bio configures |ssl| to read from |rbio| and write to |wbio|. |ssl| +// takes ownership of the two |BIO|s. If |rbio| and |wbio| are the same, |ssl| +// only takes ownership of one reference. +// +// In DTLS, |rbio| must be non-blocking to properly handle timeouts and +// retransmits. +// +// If |rbio| is the same as the currently configured |BIO| for reading, that +// side is left untouched and is not freed. +// +// If |wbio| is the same as the currently configured |BIO| for writing AND |ssl| +// is not currently configured to read from and write to the same |BIO|, that +// side is left untouched and is not freed. This asymmetry is present for +// historical reasons. +// +// Due to the very complex historical behavior of this function, calling this +// function if |ssl| already has |BIO|s configured is deprecated. Prefer +// |SSL_set0_rbio| and |SSL_set0_wbio| instead. +OPENSSL_EXPORT void SSL_set_bio(SSL *ssl, BIO *rbio, BIO *wbio); + +// SSL_set0_rbio configures |ssl| to write to |rbio|. It takes ownership of +// |rbio|. +// +// Note that, although this function and |SSL_set0_wbio| may be called on the +// same |BIO|, each call takes a reference. Use |BIO_up_ref| to balance this. +OPENSSL_EXPORT void SSL_set0_rbio(SSL *ssl, BIO *rbio); + +// SSL_set0_wbio configures |ssl| to write to |wbio|. It takes ownership of +// |wbio|. +// +// Note that, although this function and |SSL_set0_rbio| may be called on the +// same |BIO|, each call takes a reference. Use |BIO_up_ref| to balance this. +OPENSSL_EXPORT void SSL_set0_wbio(SSL *ssl, BIO *wbio); + +// SSL_get_rbio returns the |BIO| that |ssl| reads from. +OPENSSL_EXPORT BIO *SSL_get_rbio(const SSL *ssl); + +// SSL_get_wbio returns the |BIO| that |ssl| writes to. +OPENSSL_EXPORT BIO *SSL_get_wbio(const SSL *ssl); + +// SSL_get_fd calls |SSL_get_rfd|. +OPENSSL_EXPORT int SSL_get_fd(const SSL *ssl); + +// SSL_get_rfd returns the file descriptor that |ssl| is configured to read +// from. If |ssl|'s read |BIO| is not configured or doesn't wrap a file +// descriptor then it returns -1. +// +// Note: On Windows, this may return either a file descriptor or a socket (cast +// to int), depending on whether |ssl| was configured with a file descriptor or +// socket |BIO|. +OPENSSL_EXPORT int SSL_get_rfd(const SSL *ssl); + +// SSL_get_wfd returns the file descriptor that |ssl| is configured to write +// to. If |ssl|'s write |BIO| is not configured or doesn't wrap a file +// descriptor then it returns -1. +// +// Note: On Windows, this may return either a file descriptor or a socket (cast +// to int), depending on whether |ssl| was configured with a file descriptor or +// socket |BIO|. +OPENSSL_EXPORT int SSL_get_wfd(const SSL *ssl); + +// SSL_set_fd configures |ssl| to read from and write to |fd|. It returns one +// on success and zero on allocation error. The caller retains ownership of +// |fd|. +// +// On Windows, |fd| is cast to a |SOCKET| and used with Winsock APIs. +OPENSSL_EXPORT int SSL_set_fd(SSL *ssl, int fd); + +// SSL_set_rfd configures |ssl| to read from |fd|. It returns one on success and +// zero on allocation error. The caller retains ownership of |fd|. +// +// On Windows, |fd| is cast to a |SOCKET| and used with Winsock APIs. +OPENSSL_EXPORT int SSL_set_rfd(SSL *ssl, int fd); + +// SSL_set_wfd configures |ssl| to write to |fd|. It returns one on success and +// zero on allocation error. The caller retains ownership of |fd|. +// +// On Windows, |fd| is cast to a |SOCKET| and used with Winsock APIs. +OPENSSL_EXPORT int SSL_set_wfd(SSL *ssl, int fd); + +// SSL_do_handshake continues the current handshake. If there is none or the +// handshake has completed or False Started, it returns one. Otherwise, it +// returns <= 0. The caller should pass the value into |SSL_get_error| to +// determine how to proceed. +// +// In DTLS, the caller must drive retransmissions. Whenever |SSL_get_error| +// signals |SSL_ERROR_WANT_READ|, use |DTLSv1_get_timeout| to determine the +// current timeout. If it expires before the next retry, call +// |DTLSv1_handle_timeout|. Note that DTLS handshake retransmissions use fresh +// sequence numbers, so it is not sufficient to replay packets at the transport. +// +// TODO(davidben): Ensure 0 is only returned on transport EOF. +// https://crbug.com/466303. +OPENSSL_EXPORT int SSL_do_handshake(SSL *ssl); + +// SSL_connect configures |ssl| as a client, if unconfigured, and calls +// |SSL_do_handshake|. +OPENSSL_EXPORT int SSL_connect(SSL *ssl); + +// SSL_accept configures |ssl| as a server, if unconfigured, and calls +// |SSL_do_handshake|. +OPENSSL_EXPORT int SSL_accept(SSL *ssl); + +// SSL_read reads up to |num| bytes from |ssl| into |buf|. It implicitly runs +// any pending handshakes, including renegotiations when enabled. On success, it +// returns the number of bytes read. Otherwise, it returns <= 0. The caller +// should pass the value into |SSL_get_error| to determine how to proceed. +// +// TODO(davidben): Ensure 0 is only returned on transport EOF. +// https://crbug.com/466303. +OPENSSL_EXPORT int SSL_read(SSL *ssl, void *buf, int num); + +// SSL_peek behaves like |SSL_read| but does not consume any bytes returned. +OPENSSL_EXPORT int SSL_peek(SSL *ssl, void *buf, int num); + +// SSL_pending returns the number of bytes available in |ssl|. It does not read +// from the transport. +OPENSSL_EXPORT int SSL_pending(const SSL *ssl); + +// SSL_write writes up to |num| bytes from |buf| into |ssl|. It implicitly runs +// any pending handshakes, including renegotiations when enabled. On success, it +// returns the number of bytes written. Otherwise, it returns <= 0. The caller +// should pass the value into |SSL_get_error| to determine how to proceed. +// +// In TLS, a non-blocking |SSL_write| differs from non-blocking |write| in that +// a failed |SSL_write| still commits to the data passed in. When retrying, the +// caller must supply the original write buffer (or a larger one containing the +// original as a prefix). By default, retries will fail if they also do not +// reuse the same |buf| pointer. This may be relaxed with +// |SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER|, but the buffer contents still must be +// unchanged. +// +// By default, in TLS, |SSL_write| will not return success until all |num| bytes +// are written. This may be relaxed with |SSL_MODE_ENABLE_PARTIAL_WRITE|. It +// allows |SSL_write| to complete with a partial result when only part of the +// input was written in a single record. +// +// In DTLS, neither |SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER| and +// |SSL_MODE_ENABLE_PARTIAL_WRITE| do anything. The caller may retry with a +// different buffer freely. A single call to |SSL_write| only ever writes a +// single record in a single packet, so |num| must be at most +// |SSL3_RT_MAX_PLAIN_LENGTH|. +// +// TODO(davidben): Ensure 0 is only returned on transport EOF. +// https://crbug.com/466303. +OPENSSL_EXPORT int SSL_write(SSL *ssl, const void *buf, int num); + +// SSL_shutdown shuts down |ssl|. On success, it completes in two stages. First, +// it returns 0 if |ssl| completed uni-directional shutdown; close_notify has +// been sent, but the peer's close_notify has not been received. Most callers +// may stop at this point. For bi-directional shutdown, call |SSL_shutdown| +// again. It returns 1 if close_notify has been both sent and received. +// +// If the peer's close_notify arrived first, the first stage is skipped. +// |SSL_shutdown| will return 1 once close_notify is sent and skip 0. Callers +// only interested in uni-directional shutdown must therefore allow for the +// first stage returning either 0 or 1. +// +// |SSL_shutdown| returns -1 on failure. The caller should pass the return value +// into |SSL_get_error| to determine how to proceed. If the underlying |BIO| is +// non-blocking, both stages may require retry. +OPENSSL_EXPORT int SSL_shutdown(SSL *ssl); + +// SSL_CTX_set_quiet_shutdown sets quiet shutdown on |ctx| to |mode|. If +// enabled, |SSL_shutdown| will not send a close_notify alert or wait for one +// from the peer. It will instead synchronously return one. +OPENSSL_EXPORT void SSL_CTX_set_quiet_shutdown(SSL_CTX *ctx, int mode); + +// SSL_CTX_get_quiet_shutdown returns whether quiet shutdown is enabled for +// |ctx|. +OPENSSL_EXPORT int SSL_CTX_get_quiet_shutdown(const SSL_CTX *ctx); + +// SSL_set_quiet_shutdown sets quiet shutdown on |ssl| to |mode|. If enabled, +// |SSL_shutdown| will not send a close_notify alert or wait for one from the +// peer. It will instead synchronously return one. +OPENSSL_EXPORT void SSL_set_quiet_shutdown(SSL *ssl, int mode); + +// SSL_get_quiet_shutdown returns whether quiet shutdown is enabled for +// |ssl|. +OPENSSL_EXPORT int SSL_get_quiet_shutdown(const SSL *ssl); + +// SSL_get_error returns a |SSL_ERROR_*| value for the most recent operation on +// |ssl|. It should be called after an operation failed to determine whether the +// error was fatal and, if not, when to retry. +OPENSSL_EXPORT int SSL_get_error(const SSL *ssl, int ret_code); + +// SSL_ERROR_NONE indicates the operation succeeded. +#define SSL_ERROR_NONE 0 + +// SSL_ERROR_SSL indicates the operation failed within the library. The caller +// may inspect the error queue for more information. +#define SSL_ERROR_SSL 1 + +// SSL_ERROR_WANT_READ indicates the operation failed attempting to read from +// the transport. The caller may retry the operation when the transport is ready +// for reading. +// +// If signaled by a DTLS handshake, the caller must also call +// |DTLSv1_get_timeout| and |DTLSv1_handle_timeout| as appropriate. See +// |SSL_do_handshake|. +#define SSL_ERROR_WANT_READ 2 + +// SSL_ERROR_WANT_WRITE indicates the operation failed attempting to write to +// the transport. The caller may retry the operation when the transport is ready +// for writing. +#define SSL_ERROR_WANT_WRITE 3 + +// SSL_ERROR_WANT_X509_LOOKUP indicates the operation failed in calling the +// |cert_cb| or |client_cert_cb|. The caller may retry the operation when the +// callback is ready to return a certificate or one has been configured +// externally. +// +// See also |SSL_CTX_set_cert_cb| and |SSL_CTX_set_client_cert_cb|. +#define SSL_ERROR_WANT_X509_LOOKUP 4 + +// SSL_ERROR_SYSCALL indicates the operation failed externally to the library. +// The caller should consult the system-specific error mechanism. This is +// typically |errno| but may be something custom if using a custom |BIO|. It +// may also be signaled if the transport returned EOF, in which case the +// operation's return value will be zero. +#define SSL_ERROR_SYSCALL 5 + +// SSL_ERROR_ZERO_RETURN indicates the operation failed because the connection +// was cleanly shut down with a close_notify alert. +#define SSL_ERROR_ZERO_RETURN 6 + +// SSL_ERROR_WANT_CONNECT indicates the operation failed attempting to connect +// the transport (the |BIO| signaled |BIO_RR_CONNECT|). The caller may retry the +// operation when the transport is ready. +#define SSL_ERROR_WANT_CONNECT 7 + +// SSL_ERROR_WANT_ACCEPT indicates the operation failed attempting to accept a +// connection from the transport (the |BIO| signaled |BIO_RR_ACCEPT|). The +// caller may retry the operation when the transport is ready. +// +// TODO(davidben): Remove this. It's used by accept BIOs which are bizarre. +#define SSL_ERROR_WANT_ACCEPT 8 + +// SSL_ERROR_WANT_CHANNEL_ID_LOOKUP indicates the operation failed looking up +// the Channel ID key. The caller may retry the operation when |channel_id_cb| +// is ready to return a key or one has been configured with +// |SSL_set1_tls_channel_id|. +// +// See also |SSL_CTX_set_channel_id_cb|. +#define SSL_ERROR_WANT_CHANNEL_ID_LOOKUP 9 + +// SSL_ERROR_PENDING_SESSION indicates the operation failed because the session +// lookup callback indicated the session was unavailable. The caller may retry +// the operation when lookup has completed. +// +// See also |SSL_CTX_sess_set_get_cb| and |SSL_magic_pending_session_ptr|. +#define SSL_ERROR_PENDING_SESSION 11 + +// SSL_ERROR_PENDING_CERTIFICATE indicates the operation failed because the +// early callback indicated certificate lookup was incomplete. The caller may +// retry the operation when lookup has completed. +// +// See also |SSL_CTX_set_select_certificate_cb|. +#define SSL_ERROR_PENDING_CERTIFICATE 12 + +// SSL_ERROR_WANT_PRIVATE_KEY_OPERATION indicates the operation failed because +// a private key operation was unfinished. The caller may retry the operation +// when the private key operation is complete. +// +// See also |SSL_set_private_key_method| and +// |SSL_CTX_set_private_key_method|. +#define SSL_ERROR_WANT_PRIVATE_KEY_OPERATION 13 + +// SSL_ERROR_PENDING_TICKET indicates that a ticket decryption is pending. The +// caller may retry the operation when the decryption is ready. +// +// See also |SSL_CTX_set_ticket_aead_method|. +#define SSL_ERROR_PENDING_TICKET 14 + +// SSL_ERROR_EARLY_DATA_REJECTED indicates that early data was rejected. The +// caller should treat this as a connection failure and retry any operations +// associated with the rejected early data. |SSL_reset_early_data_reject| may be +// used to reuse the underlying connection for the retry. +#define SSL_ERROR_EARLY_DATA_REJECTED 15 + +// SSL_ERROR_WANT_CERTIFICATE_VERIFY indicates the operation failed because +// certificate verification was incomplete. The caller may retry the operation +// when certificate verification is complete. +// +// See also |SSL_CTX_set_custom_verify|. +#define SSL_ERROR_WANT_CERTIFICATE_VERIFY 16 + +#define SSL_ERROR_HANDOFF 17 + +// SSL_set_mtu sets the |ssl|'s MTU in DTLS to |mtu|. It returns one on success +// and zero on failure. +OPENSSL_EXPORT int SSL_set_mtu(SSL *ssl, unsigned mtu); + +// DTLSv1_set_initial_timeout_duration sets the initial duration for a DTLS +// handshake timeout. +// +// This duration overrides the default of 1 second, which is the strong +// recommendation of RFC 6347 (see section 4.2.4.1). However, there may exist +// situations where a shorter timeout would be beneficial, such as for +// time-sensitive applications. +OPENSSL_EXPORT void DTLSv1_set_initial_timeout_duration(SSL *ssl, + unsigned duration_ms); + +// DTLSv1_get_timeout queries the next DTLS handshake timeout. If there is a +// timeout in progress, it sets |*out| to the time remaining and returns one. +// Otherwise, it returns zero. +// +// When the timeout expires, call |DTLSv1_handle_timeout| to handle the +// retransmit behavior. +// +// NOTE: This function must be queried again whenever the handshake state +// machine changes, including when |DTLSv1_handle_timeout| is called. +OPENSSL_EXPORT int DTLSv1_get_timeout(const SSL *ssl, struct timeval *out); + +// DTLSv1_handle_timeout is called when a DTLS handshake timeout expires. If no +// timeout had expired, it returns 0. Otherwise, it retransmits the previous +// flight of handshake messages and returns 1. If too many timeouts had expired +// without progress or an error occurs, it returns -1. +// +// The caller's external timer should be compatible with the one |ssl| queries +// within some fudge factor. Otherwise, the call will be a no-op, but +// |DTLSv1_get_timeout| will return an updated timeout. +// +// If the function returns -1, checking if |SSL_get_error| returns +// |SSL_ERROR_WANT_WRITE| may be used to determine if the retransmit failed due +// to a non-fatal error at the write |BIO|. However, the operation may not be +// retried until the next timeout fires. +// +// WARNING: This function breaks the usual return value convention. +// +// TODO(davidben): This |SSL_ERROR_WANT_WRITE| behavior is kind of bizarre. +OPENSSL_EXPORT int DTLSv1_handle_timeout(SSL *ssl); + + +// Protocol versions. + +#define DTLS1_VERSION_MAJOR 0xfe +#define SSL3_VERSION_MAJOR 0x03 + +#define SSL3_VERSION 0x0300 +#define TLS1_VERSION 0x0301 +#define TLS1_1_VERSION 0x0302 +#define TLS1_2_VERSION 0x0303 +#define TLS1_3_VERSION 0x0304 + +#define DTLS1_VERSION 0xfeff +#define DTLS1_2_VERSION 0xfefd + +#define TLS1_3_DRAFT23_VERSION 0x7f17 + +// SSL_CTX_set_min_proto_version sets the minimum protocol version for |ctx| to +// |version|. If |version| is zero, the default minimum version is used. It +// returns one on success and zero if |version| is invalid. +OPENSSL_EXPORT int SSL_CTX_set_min_proto_version(SSL_CTX *ctx, + uint16_t version); + +// SSL_CTX_set_max_proto_version sets the maximum protocol version for |ctx| to +// |version|. If |version| is zero, the default maximum version is used. It +// returns one on success and zero if |version| is invalid. +OPENSSL_EXPORT int SSL_CTX_set_max_proto_version(SSL_CTX *ctx, + uint16_t version); + +// SSL_set_min_proto_version sets the minimum protocol version for |ssl| to +// |version|. If |version| is zero, the default minimum version is used. It +// returns one on success and zero if |version| is invalid. +OPENSSL_EXPORT int SSL_set_min_proto_version(SSL *ssl, uint16_t version); + +// SSL_set_max_proto_version sets the maximum protocol version for |ssl| to +// |version|. If |version| is zero, the default maximum version is used. It +// returns one on success and zero if |version| is invalid. +OPENSSL_EXPORT int SSL_set_max_proto_version(SSL *ssl, uint16_t version); + +// SSL_version returns the TLS or DTLS protocol version used by |ssl|, which is +// one of the |*_VERSION| values. (E.g. |TLS1_2_VERSION|.) Before the version +// is negotiated, the result is undefined. +OPENSSL_EXPORT int SSL_version(const SSL *ssl); + + +// Options. +// +// Options configure protocol behavior. + +// SSL_OP_NO_QUERY_MTU, in DTLS, disables querying the MTU from the underlying +// |BIO|. Instead, the MTU is configured with |SSL_set_mtu|. +#define SSL_OP_NO_QUERY_MTU 0x00001000L + +// SSL_OP_NO_TICKET disables session ticket support (RFC 5077). +#define SSL_OP_NO_TICKET 0x00004000L + +// SSL_OP_CIPHER_SERVER_PREFERENCE configures servers to select ciphers and +// ECDHE curves according to the server's preferences instead of the +// client's. +#define SSL_OP_CIPHER_SERVER_PREFERENCE 0x00400000L + +// The following flags toggle individual protocol versions. This is deprecated. +// Use |SSL_CTX_set_min_proto_version| and |SSL_CTX_set_max_proto_version| +// instead. +#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_TLSv1_3 0x20000000L +#define SSL_OP_NO_DTLSv1 SSL_OP_NO_TLSv1 +#define SSL_OP_NO_DTLSv1_2 SSL_OP_NO_TLSv1_2 + +// SSL_CTX_set_options enables all options set in |options| (which should be one +// or more of the |SSL_OP_*| values, ORed together) in |ctx|. It returns a +// bitmask representing the resulting enabled options. +OPENSSL_EXPORT uint32_t SSL_CTX_set_options(SSL_CTX *ctx, uint32_t options); + +// SSL_CTX_clear_options disables all options set in |options| (which should be +// one or more of the |SSL_OP_*| values, ORed together) in |ctx|. It returns a +// bitmask representing the resulting enabled options. +OPENSSL_EXPORT uint32_t SSL_CTX_clear_options(SSL_CTX *ctx, uint32_t options); + +// SSL_CTX_get_options returns a bitmask of |SSL_OP_*| values that represent all +// the options enabled for |ctx|. +OPENSSL_EXPORT uint32_t SSL_CTX_get_options(const SSL_CTX *ctx); + +// SSL_set_options enables all options set in |options| (which should be one or +// more of the |SSL_OP_*| values, ORed together) in |ssl|. It returns a bitmask +// representing the resulting enabled options. +OPENSSL_EXPORT uint32_t SSL_set_options(SSL *ssl, uint32_t options); + +// SSL_clear_options disables all options set in |options| (which should be one +// or more of the |SSL_OP_*| values, ORed together) in |ssl|. It returns a +// bitmask representing the resulting enabled options. +OPENSSL_EXPORT uint32_t SSL_clear_options(SSL *ssl, uint32_t options); + +// SSL_get_options returns a bitmask of |SSL_OP_*| values that represent all the +// options enabled for |ssl|. +OPENSSL_EXPORT uint32_t SSL_get_options(const SSL *ssl); + + +// Modes. +// +// Modes configure API behavior. + +// SSL_MODE_ENABLE_PARTIAL_WRITE, in TLS, allows |SSL_write| to complete with a +// partial result when the only part of the input was written in a single +// record. In DTLS, it does nothing. +#define SSL_MODE_ENABLE_PARTIAL_WRITE 0x00000001L + +// SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER, in TLS, allows retrying an incomplete +// |SSL_write| with a different buffer. However, |SSL_write| still assumes the +// buffer contents are unchanged. This is not the default to avoid the +// misconception that non-blocking |SSL_write| behaves like non-blocking +// |write|. In DTLS, it does nothing. +#define SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER 0x00000002L + +// SSL_MODE_NO_AUTO_CHAIN disables automatically building a certificate chain +// before sending certificates to the peer. This flag is set (and the feature +// disabled) by default. +// TODO(davidben): Remove this behavior. https://crbug.com/boringssl/42. +#define SSL_MODE_NO_AUTO_CHAIN 0x00000008L + +// SSL_MODE_ENABLE_FALSE_START allows clients to send application data before +// receipt of ChangeCipherSpec and Finished. This mode enables full handshakes +// to 'complete' in one RTT. See RFC 7918. +// +// When False Start is enabled, |SSL_do_handshake| may succeed before the +// handshake has completely finished. |SSL_write| will function at this point, +// and |SSL_read| will transparently wait for the final handshake leg before +// returning application data. To determine if False Start occurred or when the +// handshake is completely finished, see |SSL_in_false_start|, |SSL_in_init|, +// and |SSL_CB_HANDSHAKE_DONE| from |SSL_CTX_set_info_callback|. +#define SSL_MODE_ENABLE_FALSE_START 0x00000080L + +// SSL_MODE_CBC_RECORD_SPLITTING causes multi-byte CBC records in SSL 3.0 and +// TLS 1.0 to be split in two: the first record will contain a single byte and +// the second will contain the remainder. This effectively randomises the IV and +// prevents BEAST attacks. +#define SSL_MODE_CBC_RECORD_SPLITTING 0x00000100L + +// SSL_MODE_NO_SESSION_CREATION will cause any attempts to create a session to +// fail with SSL_R_SESSION_MAY_NOT_BE_CREATED. This can be used to enforce that +// session resumption is used for a given SSL*. +#define SSL_MODE_NO_SESSION_CREATION 0x00000200L + +// SSL_MODE_SEND_FALLBACK_SCSV sends TLS_FALLBACK_SCSV in the ClientHello. +// To be set only by applications that reconnect with a downgraded protocol +// version; see RFC 7507 for details. +// +// DO NOT ENABLE THIS if your application attempts a normal handshake. Only use +// this in explicit fallback retries, following the guidance in RFC 7507. +#define SSL_MODE_SEND_FALLBACK_SCSV 0x00000400L + +// SSL_CTX_set_mode enables all modes set in |mode| (which should be one or more +// of the |SSL_MODE_*| values, ORed together) in |ctx|. It returns a bitmask +// representing the resulting enabled modes. +OPENSSL_EXPORT uint32_t SSL_CTX_set_mode(SSL_CTX *ctx, uint32_t mode); + +// SSL_CTX_clear_mode disables all modes set in |mode| (which should be one or +// more of the |SSL_MODE_*| values, ORed together) in |ctx|. It returns a +// bitmask representing the resulting enabled modes. +OPENSSL_EXPORT uint32_t SSL_CTX_clear_mode(SSL_CTX *ctx, uint32_t mode); + +// SSL_CTX_get_mode returns a bitmask of |SSL_MODE_*| values that represent all +// the modes enabled for |ssl|. +OPENSSL_EXPORT uint32_t SSL_CTX_get_mode(const SSL_CTX *ctx); + +// SSL_set_mode enables all modes set in |mode| (which should be one or more of +// the |SSL_MODE_*| values, ORed together) in |ssl|. It returns a bitmask +// representing the resulting enabled modes. +OPENSSL_EXPORT uint32_t SSL_set_mode(SSL *ssl, uint32_t mode); + +// SSL_clear_mode disables all modes set in |mode| (which should be one or more +// of the |SSL_MODE_*| values, ORed together) in |ssl|. It returns a bitmask +// representing the resulting enabled modes. +OPENSSL_EXPORT uint32_t SSL_clear_mode(SSL *ssl, uint32_t mode); + +// SSL_get_mode returns a bitmask of |SSL_MODE_*| values that represent all the +// modes enabled for |ssl|. +OPENSSL_EXPORT uint32_t SSL_get_mode(const SSL *ssl); + +// SSL_CTX_set0_buffer_pool sets a |CRYPTO_BUFFER_POOL| that will be used to +// store certificates. This can allow multiple connections to share +// certificates and thus save memory. +// +// The SSL_CTX does not take ownership of |pool| and the caller must ensure +// that |pool| outlives |ctx| and all objects linked to it, including |SSL|, +// |X509| and |SSL_SESSION| objects. Basically, don't ever free |pool|. +OPENSSL_EXPORT void SSL_CTX_set0_buffer_pool(SSL_CTX *ctx, + CRYPTO_BUFFER_POOL *pool); + + +// Configuring certificates and private keys. +// +// These functions configure the connection's leaf certificate, private key, and +// certificate chain. The certificate chain is ordered leaf to root (as sent on +// the wire) but does not include the leaf. Both client and server certificates +// use these functions. +// +// Certificates and keys may be configured before the handshake or dynamically +// in the early callback and certificate callback. + +// SSL_CTX_use_certificate sets |ctx|'s leaf certificate to |x509|. It returns +// one on success and zero on failure. +OPENSSL_EXPORT int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x509); + +// SSL_use_certificate sets |ssl|'s leaf certificate to |x509|. It returns one +// on success and zero on failure. +OPENSSL_EXPORT int SSL_use_certificate(SSL *ssl, X509 *x509); + +// SSL_CTX_use_PrivateKey sets |ctx|'s private key to |pkey|. It returns one on +// success and zero on failure. +OPENSSL_EXPORT int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey); + +// SSL_use_PrivateKey sets |ssl|'s private key to |pkey|. It returns one on +// success and zero on failure. +OPENSSL_EXPORT int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey); + +// SSL_CTX_set0_chain sets |ctx|'s certificate chain, excluding the leaf, to +// |chain|. On success, it returns one and takes ownership of |chain|. +// Otherwise, it returns zero. +OPENSSL_EXPORT int SSL_CTX_set0_chain(SSL_CTX *ctx, STACK_OF(X509) *chain); + +// SSL_CTX_set1_chain sets |ctx|'s certificate chain, excluding the leaf, to +// |chain|. It returns one on success and zero on failure. The caller retains +// ownership of |chain| and may release it freely. +OPENSSL_EXPORT int SSL_CTX_set1_chain(SSL_CTX *ctx, STACK_OF(X509) *chain); + +// SSL_set0_chain sets |ssl|'s certificate chain, excluding the leaf, to +// |chain|. On success, it returns one and takes ownership of |chain|. +// Otherwise, it returns zero. +OPENSSL_EXPORT int SSL_set0_chain(SSL *ssl, STACK_OF(X509) *chain); + +// SSL_set1_chain sets |ssl|'s certificate chain, excluding the leaf, to +// |chain|. It returns one on success and zero on failure. The caller retains +// ownership of |chain| and may release it freely. +OPENSSL_EXPORT int SSL_set1_chain(SSL *ssl, STACK_OF(X509) *chain); + +// SSL_CTX_add0_chain_cert appends |x509| to |ctx|'s certificate chain. On +// success, it returns one and takes ownership of |x509|. Otherwise, it returns +// zero. +OPENSSL_EXPORT int SSL_CTX_add0_chain_cert(SSL_CTX *ctx, X509 *x509); + +// SSL_CTX_add1_chain_cert appends |x509| to |ctx|'s certificate chain. It +// returns one on success and zero on failure. The caller retains ownership of +// |x509| and may release it freely. +OPENSSL_EXPORT int SSL_CTX_add1_chain_cert(SSL_CTX *ctx, X509 *x509); + +// SSL_add0_chain_cert appends |x509| to |ctx|'s certificate chain. On success, +// it returns one and takes ownership of |x509|. Otherwise, it returns zero. +OPENSSL_EXPORT int SSL_add0_chain_cert(SSL *ssl, X509 *x509); + +// SSL_CTX_add_extra_chain_cert calls |SSL_CTX_add0_chain_cert|. +OPENSSL_EXPORT int SSL_CTX_add_extra_chain_cert(SSL_CTX *ctx, X509 *x509); + +// SSL_add1_chain_cert appends |x509| to |ctx|'s certificate chain. It returns +// one on success and zero on failure. The caller retains ownership of |x509| +// and may release it freely. +OPENSSL_EXPORT int SSL_add1_chain_cert(SSL *ssl, X509 *x509); + +// SSL_CTX_clear_chain_certs clears |ctx|'s certificate chain and returns +// one. +OPENSSL_EXPORT int SSL_CTX_clear_chain_certs(SSL_CTX *ctx); + +// SSL_CTX_clear_extra_chain_certs calls |SSL_CTX_clear_chain_certs|. +OPENSSL_EXPORT int SSL_CTX_clear_extra_chain_certs(SSL_CTX *ctx); + +// SSL_clear_chain_certs clears |ssl|'s certificate chain and returns one. +OPENSSL_EXPORT int SSL_clear_chain_certs(SSL *ssl); + +// SSL_CTX_set_cert_cb sets a callback that is called to select a certificate. +// The callback returns one on success, zero on internal error, and a negative +// number on failure or to pause the handshake. If the handshake is paused, +// |SSL_get_error| will return |SSL_ERROR_WANT_X509_LOOKUP|. +// +// On the client, the callback may call |SSL_get0_certificate_types| and +// |SSL_get_client_CA_list| for information on the server's certificate +// request. +// +// On the server, the callback will be called on non-resumption handshakes, +// after extensions have been processed. +OPENSSL_EXPORT void SSL_CTX_set_cert_cb(SSL_CTX *ctx, + int (*cb)(SSL *ssl, void *arg), + void *arg); + +// SSL_set_cert_cb sets a callback that is called to select a certificate. The +// callback returns one on success, zero on internal error, and a negative +// number on failure or to pause the handshake. If the handshake is paused, +// |SSL_get_error| will return |SSL_ERROR_WANT_X509_LOOKUP|. +// +// On the client, the callback may call |SSL_get0_certificate_types| and +// |SSL_get_client_CA_list| for information on the server's certificate +// request. +OPENSSL_EXPORT void SSL_set_cert_cb(SSL *ssl, int (*cb)(SSL *ssl, void *arg), + void *arg); + +// SSL_get0_certificate_types, for a client, sets |*out_types| to an array +// containing the client certificate types requested by a server. It returns the +// length of the array. +// +// The behavior of this function is undefined except during the callbacks set by +// by |SSL_CTX_set_cert_cb| and |SSL_CTX_set_client_cert_cb| or when the +// handshake is paused because of them. +OPENSSL_EXPORT size_t SSL_get0_certificate_types(SSL *ssl, + const uint8_t **out_types); + +// SSL_certs_clear resets the private key, leaf certificate, and certificate +// chain of |ssl|. +OPENSSL_EXPORT void SSL_certs_clear(SSL *ssl); + +// SSL_CTX_check_private_key returns one if the certificate and private key +// configured in |ctx| are consistent and zero otherwise. +OPENSSL_EXPORT int SSL_CTX_check_private_key(const SSL_CTX *ctx); + +// SSL_check_private_key returns one if the certificate and private key +// configured in |ssl| are consistent and zero otherwise. +OPENSSL_EXPORT int SSL_check_private_key(const SSL *ssl); + +// SSL_CTX_get0_certificate returns |ctx|'s leaf certificate. +OPENSSL_EXPORT X509 *SSL_CTX_get0_certificate(const SSL_CTX *ctx); + +// SSL_get_certificate returns |ssl|'s leaf certificate. +OPENSSL_EXPORT X509 *SSL_get_certificate(const SSL *ssl); + +// SSL_CTX_get0_privatekey returns |ctx|'s private key. +OPENSSL_EXPORT EVP_PKEY *SSL_CTX_get0_privatekey(const SSL_CTX *ctx); + +// SSL_get_privatekey returns |ssl|'s private key. +OPENSSL_EXPORT EVP_PKEY *SSL_get_privatekey(const SSL *ssl); + +// SSL_CTX_get0_chain_certs sets |*out_chain| to |ctx|'s certificate chain and +// returns one. +OPENSSL_EXPORT int SSL_CTX_get0_chain_certs(const SSL_CTX *ctx, + STACK_OF(X509) **out_chain); + +// SSL_CTX_get_extra_chain_certs calls |SSL_CTX_get0_chain_certs|. +OPENSSL_EXPORT int SSL_CTX_get_extra_chain_certs(const SSL_CTX *ctx, + STACK_OF(X509) **out_chain); + +// SSL_get0_chain_certs sets |*out_chain| to |ssl|'s certificate chain and +// returns one. +OPENSSL_EXPORT int SSL_get0_chain_certs(const SSL *ssl, + STACK_OF(X509) **out_chain); + +// SSL_CTX_set_signed_cert_timestamp_list sets the list of signed certificate +// timestamps that is sent to clients that request it. The |list| argument must +// contain one or more SCT structures serialised as a SignedCertificateTimestamp +// List (see https://tools.ietf.org/html/rfc6962#section-3.3) – i.e. each SCT +// is prefixed by a big-endian, uint16 length and the concatenation of one or +// more such prefixed SCTs are themselves also prefixed by a uint16 length. It +// returns one on success and zero on error. The caller retains ownership of +// |list|. +OPENSSL_EXPORT int SSL_CTX_set_signed_cert_timestamp_list(SSL_CTX *ctx, + const uint8_t *list, + size_t list_len); + +// SSL_set_signed_cert_timestamp_list sets the list of signed certificate +// timestamps that is sent to clients that request is. The same format as the +// one used for |SSL_CTX_set_signed_cert_timestamp_list| applies. The caller +// retains ownership of |list|. +OPENSSL_EXPORT int SSL_set_signed_cert_timestamp_list(SSL *ctx, + const uint8_t *list, + size_t list_len); + +// SSL_CTX_set_ocsp_response sets the OCSP response that is sent to clients +// which request it. It returns one on success and zero on error. The caller +// retains ownership of |response|. +OPENSSL_EXPORT int SSL_CTX_set_ocsp_response(SSL_CTX *ctx, + const uint8_t *response, + size_t response_len); + +// SSL_set_ocsp_response sets the OCSP response that is sent to clients which +// request it. It returns one on success and zero on error. The caller retains +// ownership of |response|. +OPENSSL_EXPORT int SSL_set_ocsp_response(SSL *ssl, + const uint8_t *response, + size_t response_len); + +// SSL_SIGN_* are signature algorithm values as defined in TLS 1.3. +#define SSL_SIGN_RSA_PKCS1_SHA1 0x0201 +#define SSL_SIGN_RSA_PKCS1_SHA256 0x0401 +#define SSL_SIGN_RSA_PKCS1_SHA384 0x0501 +#define SSL_SIGN_RSA_PKCS1_SHA512 0x0601 +#define SSL_SIGN_ECDSA_SHA1 0x0203 +#define SSL_SIGN_ECDSA_SECP256R1_SHA256 0x0403 +#define SSL_SIGN_ECDSA_SECP384R1_SHA384 0x0503 +#define SSL_SIGN_ECDSA_SECP521R1_SHA512 0x0603 +#define SSL_SIGN_RSA_PSS_SHA256 0x0804 +#define SSL_SIGN_RSA_PSS_SHA384 0x0805 +#define SSL_SIGN_RSA_PSS_SHA512 0x0806 +#define SSL_SIGN_ED25519 0x0807 + +// SSL_SIGN_RSA_PKCS1_MD5_SHA1 is an internal signature algorithm used to +// specify raw RSASSA-PKCS1-v1_5 with an MD5/SHA-1 concatenation, as used in TLS +// before TLS 1.2. +#define SSL_SIGN_RSA_PKCS1_MD5_SHA1 0xff01 + +// SSL_get_signature_algorithm_name returns a human-readable name for |sigalg|, +// or NULL if unknown. If |include_curve| is one, the curve for ECDSA algorithms +// is included as in TLS 1.3. Otherwise, it is excluded as in TLS 1.2. +OPENSSL_EXPORT const char *SSL_get_signature_algorithm_name(uint16_t sigalg, + int include_curve); + +// SSL_get_signature_algorithm_key_type returns the key type associated with +// |sigalg| as an |EVP_PKEY_*| constant or |EVP_PKEY_NONE| if unknown. +OPENSSL_EXPORT int SSL_get_signature_algorithm_key_type(uint16_t sigalg); + +// SSL_get_signature_algorithm_digest returns the digest function associated +// with |sigalg| or |NULL| if |sigalg| has no prehash (Ed25519) or is unknown. +OPENSSL_EXPORT const EVP_MD *SSL_get_signature_algorithm_digest( + uint16_t sigalg); + +// SSL_is_signature_algorithm_rsa_pss returns one if |sigalg| is an RSA-PSS +// signature algorithm and zero otherwise. +OPENSSL_EXPORT int SSL_is_signature_algorithm_rsa_pss(uint16_t sigalg); + +// SSL_CTX_set_signing_algorithm_prefs configures |ctx| to use |prefs| as the +// preference list when signing with |ctx|'s private key. It returns one on +// success and zero on error. |prefs| should not include the internal-only value +// |SSL_SIGN_RSA_PKCS1_MD5_SHA1|. +OPENSSL_EXPORT int SSL_CTX_set_signing_algorithm_prefs(SSL_CTX *ctx, + const uint16_t *prefs, + size_t num_prefs); + +// SSL_set_signing_algorithm_prefs configures |ssl| to use |prefs| as the +// preference list when signing with |ssl|'s private key. It returns one on +// success and zero on error. |prefs| should not include the internal-only value +// |SSL_SIGN_RSA_PKCS1_MD5_SHA1|. +OPENSSL_EXPORT int SSL_set_signing_algorithm_prefs(SSL *ssl, + const uint16_t *prefs, + size_t num_prefs); + + +// Certificate and private key convenience functions. + +// SSL_CTX_set_chain_and_key sets the certificate chain and private key for a +// TLS client or server. References to the given |CRYPTO_BUFFER| and |EVP_PKEY| +// objects are added as needed. Exactly one of |privkey| or |privkey_method| +// may be non-NULL. Returns one on success and zero on error. +OPENSSL_EXPORT int SSL_CTX_set_chain_and_key( + SSL_CTX *ctx, CRYPTO_BUFFER *const *certs, size_t num_certs, + EVP_PKEY *privkey, const SSL_PRIVATE_KEY_METHOD *privkey_method); + +// SSL_set_chain_and_key sets the certificate chain and private key for a TLS +// client or server. References to the given |CRYPTO_BUFFER| and |EVP_PKEY| +// objects are added as needed. Exactly one of |privkey| or |privkey_method| +// may be non-NULL. Returns one on success and zero on error. +OPENSSL_EXPORT int SSL_set_chain_and_key( + SSL *ssl, CRYPTO_BUFFER *const *certs, size_t num_certs, EVP_PKEY *privkey, + const SSL_PRIVATE_KEY_METHOD *privkey_method); + +// SSL_CTX_use_RSAPrivateKey sets |ctx|'s private key to |rsa|. It returns one +// on success and zero on failure. +OPENSSL_EXPORT int SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa); + +// SSL_use_RSAPrivateKey sets |ctx|'s private key to |rsa|. It returns one on +// success and zero on failure. +OPENSSL_EXPORT int SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa); + +// The following functions configure certificates or private keys but take as +// input DER-encoded structures. They return one on success and zero on +// failure. + +OPENSSL_EXPORT int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, size_t der_len, + const uint8_t *der); +OPENSSL_EXPORT int SSL_use_certificate_ASN1(SSL *ssl, const uint8_t *der, + size_t der_len); + +OPENSSL_EXPORT int SSL_CTX_use_PrivateKey_ASN1(int pk, SSL_CTX *ctx, + const uint8_t *der, + size_t der_len); +OPENSSL_EXPORT int SSL_use_PrivateKey_ASN1(int type, SSL *ssl, + const uint8_t *der, size_t der_len); + +OPENSSL_EXPORT int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, + const uint8_t *der, + size_t der_len); +OPENSSL_EXPORT int SSL_use_RSAPrivateKey_ASN1(SSL *ssl, const uint8_t *der, + size_t der_len); + +// The following functions configure certificates or private keys but take as +// input files to read from. They return one on success and zero on failure. The +// |type| parameter is one of the |SSL_FILETYPE_*| values and determines whether +// the file's contents are read as PEM or DER. + +#define SSL_FILETYPE_PEM 1 +#define SSL_FILETYPE_ASN1 2 + +OPENSSL_EXPORT int SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx, + const char *file, + int type); +OPENSSL_EXPORT int SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, + int type); + +OPENSSL_EXPORT int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, + int type); +OPENSSL_EXPORT int SSL_use_certificate_file(SSL *ssl, const char *file, + int type); + +OPENSSL_EXPORT int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, + int type); +OPENSSL_EXPORT int SSL_use_PrivateKey_file(SSL *ssl, const char *file, + int type); + +// SSL_CTX_use_certificate_chain_file configures certificates for |ctx|. It +// reads the contents of |file| as a PEM-encoded leaf certificate followed +// optionally by the certificate chain to send to the peer. It returns one on +// success and zero on failure. +OPENSSL_EXPORT int SSL_CTX_use_certificate_chain_file(SSL_CTX *ctx, + const char *file); + +// SSL_CTX_set_default_passwd_cb sets the password callback for PEM-based +// convenience functions called on |ctx|. +OPENSSL_EXPORT void SSL_CTX_set_default_passwd_cb(SSL_CTX *ctx, + pem_password_cb *cb); + +// SSL_CTX_get_default_passwd_cb returns the callback set by +// |SSL_CTX_set_default_passwd_cb|. +OPENSSL_EXPORT pem_password_cb *SSL_CTX_get_default_passwd_cb( + const SSL_CTX *ctx); + +// SSL_CTX_set_default_passwd_cb_userdata sets the userdata parameter for +// |ctx|'s password callback. +OPENSSL_EXPORT void SSL_CTX_set_default_passwd_cb_userdata(SSL_CTX *ctx, + void *data); + +// SSL_CTX_get_default_passwd_cb_userdata returns the userdata parameter set by +// |SSL_CTX_set_default_passwd_cb_userdata|. +OPENSSL_EXPORT void *SSL_CTX_get_default_passwd_cb_userdata(const SSL_CTX *ctx); + + +// Custom private keys. + +enum ssl_private_key_result_t { + ssl_private_key_success, + ssl_private_key_retry, + ssl_private_key_failure, +}; + +// ssl_private_key_method_st (aka |SSL_PRIVATE_KEY_METHOD|) describes private +// key hooks. This is used to off-load signing operations to a custom, +// potentially asynchronous, backend. Metadata about the key such as the type +// and size are parsed out of the certificate. +struct ssl_private_key_method_st { + // sign signs the message |in| in using the specified signature algorithm. On + // success, it returns |ssl_private_key_success| and writes at most |max_out| + // bytes of signature data to |out| and sets |*out_len| to the number of bytes + // written. On failure, it returns |ssl_private_key_failure|. If the operation + // has not completed, it returns |ssl_private_key_retry|. |sign| should + // arrange for the high-level operation on |ssl| to be retried when the + // operation is completed. This will result in a call to |complete|. + // + // |signature_algorithm| is one of the |SSL_SIGN_*| values, as defined in TLS + // 1.3. Note that, in TLS 1.2, ECDSA algorithms do not require that curve + // sizes match hash sizes, so the curve portion of |SSL_SIGN_ECDSA_*| values + // must be ignored. BoringSSL will internally handle the curve matching logic + // where appropriate. + // + // It is an error to call |sign| while another private key operation is in + // progress on |ssl|. + enum ssl_private_key_result_t (*sign)(SSL *ssl, uint8_t *out, size_t *out_len, + size_t max_out, + uint16_t signature_algorithm, + const uint8_t *in, size_t in_len); + + // decrypt decrypts |in_len| bytes of encrypted data from |in|. On success it + // returns |ssl_private_key_success|, writes at most |max_out| bytes of + // decrypted data to |out| and sets |*out_len| to the actual number of bytes + // written. On failure it returns |ssl_private_key_failure|. If the operation + // has not completed, it returns |ssl_private_key_retry|. The caller should + // arrange for the high-level operation on |ssl| to be retried when the + // operation is completed, which will result in a call to |complete|. This + // function only works with RSA keys and should perform a raw RSA decryption + // operation with no padding. + // + // It is an error to call |decrypt| while another private key operation is in + // progress on |ssl|. + enum ssl_private_key_result_t (*decrypt)(SSL *ssl, uint8_t *out, + size_t *out_len, size_t max_out, + const uint8_t *in, size_t in_len); + + // complete completes a pending operation. If the operation has completed, it + // returns |ssl_private_key_success| and writes the result to |out| as in + // |sign|. Otherwise, it returns |ssl_private_key_failure| on failure and + // |ssl_private_key_retry| if the operation is still in progress. + // + // |complete| may be called arbitrarily many times before completion, but it + // is an error to call |complete| if there is no pending operation in progress + // on |ssl|. + enum ssl_private_key_result_t (*complete)(SSL *ssl, uint8_t *out, + size_t *out_len, size_t max_out); +}; + +// SSL_set_private_key_method configures a custom private key on |ssl|. +// |key_method| must remain valid for the lifetime of |ssl|. +OPENSSL_EXPORT void SSL_set_private_key_method( + SSL *ssl, const SSL_PRIVATE_KEY_METHOD *key_method); + +// SSL_CTX_set_private_key_method configures a custom private key on |ctx|. +// |key_method| must remain valid for the lifetime of |ctx|. +OPENSSL_EXPORT void SSL_CTX_set_private_key_method( + SSL_CTX *ctx, const SSL_PRIVATE_KEY_METHOD *key_method); + + +// Cipher suites. +// +// |SSL_CIPHER| objects represent cipher suites. + +DEFINE_CONST_STACK_OF(SSL_CIPHER) + +// SSL_get_cipher_by_value returns the structure representing a TLS cipher +// suite based on its assigned number, or NULL if unknown. See +// https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-4. +OPENSSL_EXPORT const SSL_CIPHER *SSL_get_cipher_by_value(uint16_t value); + +// SSL_CIPHER_get_id returns |cipher|'s id. It may be cast to a |uint16_t| to +// get the cipher suite value. +OPENSSL_EXPORT uint32_t SSL_CIPHER_get_id(const SSL_CIPHER *cipher); + +// SSL_CIPHER_is_aead returns one if |cipher| uses an AEAD cipher. +OPENSSL_EXPORT int SSL_CIPHER_is_aead(const SSL_CIPHER *cipher); + +// SSL_CIPHER_is_block_cipher returns one if |cipher| is a block cipher. +OPENSSL_EXPORT int SSL_CIPHER_is_block_cipher(const SSL_CIPHER *cipher); + +// SSL_CIPHER_get_cipher_nid returns the NID for |cipher|'s bulk +// cipher. Possible values are |NID_aes_128_gcm|, |NID_aes_256_gcm|, +// |NID_chacha20_poly1305|, |NID_aes_128_cbc|, |NID_aes_256_cbc|, and +// |NID_des_ede3_cbc|. +OPENSSL_EXPORT int SSL_CIPHER_get_cipher_nid(const SSL_CIPHER *cipher); + +// SSL_CIPHER_get_digest_nid returns the NID for |cipher|'s HMAC if it is a +// legacy cipher suite. For modern AEAD-based ciphers (see +// |SSL_CIPHER_is_aead|), it returns |NID_undef|. +// +// Note this function only returns the legacy HMAC digest, not the PRF hash. +OPENSSL_EXPORT int SSL_CIPHER_get_digest_nid(const SSL_CIPHER *cipher); + +// SSL_CIPHER_get_kx_nid returns the NID for |cipher|'s key exchange. This may +// be |NID_kx_rsa|, |NID_kx_ecdhe|, or |NID_kx_psk| for TLS 1.2. In TLS 1.3, +// cipher suites do not specify the key exchange, so this function returns +// |NID_kx_any|. +OPENSSL_EXPORT int SSL_CIPHER_get_kx_nid(const SSL_CIPHER *cipher); + +// SSL_CIPHER_get_auth_nid returns the NID for |cipher|'s authentication +// type. This may be |NID_auth_rsa|, |NID_auth_ecdsa|, or |NID_auth_psk| for TLS +// 1.2. In TLS 1.3, cipher suites do not specify authentication, so this +// function returns |NID_auth_any|. +OPENSSL_EXPORT int SSL_CIPHER_get_auth_nid(const SSL_CIPHER *cipher); + +// SSL_CIPHER_get_prf_nid retuns the NID for |cipher|'s PRF hash. If |cipher| is +// a pre-TLS-1.2 cipher, it returns |NID_md5_sha1| but note these ciphers use +// SHA-256 in TLS 1.2. Other return values may be treated uniformly in all +// applicable versions. +OPENSSL_EXPORT int SSL_CIPHER_get_prf_nid(const SSL_CIPHER *cipher); + +// SSL_CIPHER_get_min_version returns the minimum protocol version required +// for |cipher|. +OPENSSL_EXPORT uint16_t SSL_CIPHER_get_min_version(const SSL_CIPHER *cipher); + +// SSL_CIPHER_get_max_version returns the maximum protocol version that +// supports |cipher|. +OPENSSL_EXPORT uint16_t SSL_CIPHER_get_max_version(const SSL_CIPHER *cipher); + +// SSL_CIPHER_standard_name returns the standard IETF name for |cipher|. For +// example, "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256". +OPENSSL_EXPORT const char *SSL_CIPHER_standard_name(const SSL_CIPHER *cipher); + +// SSL_CIPHER_get_name returns the OpenSSL name of |cipher|. For example, +// "ECDHE-RSA-AES128-GCM-SHA256". +OPENSSL_EXPORT const char *SSL_CIPHER_get_name(const SSL_CIPHER *cipher); + +// SSL_CIPHER_get_kx_name returns a string that describes the key-exchange +// method used by |cipher|. For example, "ECDHE_ECDSA". TLS 1.3 AEAD-only +// ciphers return the string "GENERIC". +OPENSSL_EXPORT const char *SSL_CIPHER_get_kx_name(const SSL_CIPHER *cipher); + +// SSL_CIPHER_get_bits returns the strength, in bits, of |cipher|. If +// |out_alg_bits| is not NULL, it writes the number of bits consumed by the +// symmetric algorithm to |*out_alg_bits|. +OPENSSL_EXPORT int SSL_CIPHER_get_bits(const SSL_CIPHER *cipher, + int *out_alg_bits); + + +// Cipher suite configuration. +// +// OpenSSL uses a mini-language to configure cipher suites. The language +// maintains an ordered list of enabled ciphers, along with an ordered list of +// disabled but available ciphers. Initially, all ciphers are disabled with a +// default ordering. The cipher string is then interpreted as a sequence of +// directives, separated by colons, each of which modifies this state. +// +// Most directives consist of a one character or empty opcode followed by a +// selector which matches a subset of available ciphers. +// +// Available opcodes are: +// +// The empty opcode enables and appends all matching disabled ciphers to the +// end of the enabled list. The newly appended ciphers are ordered relative to +// each other matching their order in the disabled list. +// +// |-| disables all matching enabled ciphers and prepends them to the disabled +// list, with relative order from the enabled list preserved. This means the +// most recently disabled ciphers get highest preference relative to other +// disabled ciphers if re-enabled. +// +// |+| moves all matching enabled ciphers to the end of the enabled list, with +// relative order preserved. +// +// |!| deletes all matching ciphers, enabled or not, from either list. Deleted +// ciphers will not matched by future operations. +// +// A selector may be a specific cipher (using either the standard or OpenSSL +// name for the cipher) or one or more rules separated by |+|. The final +// selector matches the intersection of each rule. For instance, |AESGCM+aECDSA| +// matches ECDSA-authenticated AES-GCM ciphers. +// +// Available cipher rules are: +// +// |ALL| matches all ciphers. +// +// |kRSA|, |kDHE|, |kECDHE|, and |kPSK| match ciphers using plain RSA, DHE, +// ECDHE, and plain PSK key exchanges, respectively. Note that ECDHE_PSK is +// matched by |kECDHE| and not |kPSK|. +// +// |aRSA|, |aECDSA|, and |aPSK| match ciphers authenticated by RSA, ECDSA, and +// a pre-shared key, respectively. +// +// |RSA|, |DHE|, |ECDHE|, |PSK|, |ECDSA|, and |PSK| are aliases for the +// corresponding |k*| or |a*| cipher rule. |RSA| is an alias for |kRSA|, not +// |aRSA|. +// +// |3DES|, |AES128|, |AES256|, |AES|, |AESGCM|, |CHACHA20| match ciphers +// whose bulk cipher use the corresponding encryption scheme. Note that +// |AES|, |AES128|, and |AES256| match both CBC and GCM ciphers. +// +// |SHA1|, |SHA256|, and |SHA384| match legacy cipher suites using the +// corresponding hash function in their MAC. AEADs are matched by none of +// these. +// +// |SHA| is an alias for |SHA1|. +// +// Although implemented, authentication-only ciphers match no rules and must be +// explicitly selected by name. +// +// Deprecated cipher rules: +// +// |kEDH|, |EDH|, |kEECDH|, and |EECDH| are legacy aliases for |kDHE|, |DHE|, +// |kECDHE|, and |ECDHE|, respectively. +// +// |HIGH| is an alias for |ALL|. +// +// |FIPS| is an alias for |HIGH|. +// +// |SSLv3| and |TLSv1| match ciphers available in TLS 1.1 or earlier. +// |TLSv1_2| matches ciphers new in TLS 1.2. This is confusing and should not +// be used. +// +// Unknown rules are silently ignored by legacy APIs, and rejected by APIs with +// "strict" in the name, which should be preferred. Cipher lists can be long +// and it's easy to commit typos. Strict functions will also reject the use of +// spaces, semi-colons and commas as alternative separators. +// +// The special |@STRENGTH| directive will sort all enabled ciphers by strength. +// +// The |DEFAULT| directive, when appearing at the front of the string, expands +// to the default ordering of available ciphers. +// +// If configuring a server, one may also configure equal-preference groups to +// partially respect the client's preferences when +// |SSL_OP_CIPHER_SERVER_PREFERENCE| is enabled. Ciphers in an equal-preference +// group have equal priority and use the client order. This may be used to +// enforce that AEADs are preferred but select AES-GCM vs. ChaCha20-Poly1305 +// based on client preferences. An equal-preference is specified with square +// brackets, combining multiple selectors separated by |. For example: +// +// [ECDHE-ECDSA-CHACHA20-POLY1305|ECDHE-ECDSA-AES128-GCM-SHA256] +// +// Once an equal-preference group is used, future directives must be +// opcode-less. Inside an equal-preference group, spaces are not allowed. +// +// TLS 1.3 ciphers do not participate in this mechanism and instead have a +// built-in preference order. Functions to set cipher lists do not affect TLS +// 1.3, and functions to query the cipher list do not include TLS 1.3 +// ciphers. + +// SSL_DEFAULT_CIPHER_LIST is the default cipher suite configuration. It is +// substituted when a cipher string starts with 'DEFAULT'. +#define SSL_DEFAULT_CIPHER_LIST "ALL" + +// SSL_CTX_set_strict_cipher_list configures the cipher list for |ctx|, +// evaluating |str| as a cipher string and returning error if |str| contains +// anything meaningless. It returns one on success and zero on failure. +OPENSSL_EXPORT int SSL_CTX_set_strict_cipher_list(SSL_CTX *ctx, + const char *str); + +// SSL_CTX_set_cipher_list configures the cipher list for |ctx|, evaluating +// |str| as a cipher string. It returns one on success and zero on failure. +// +// Prefer to use |SSL_CTX_set_strict_cipher_list|. This function tolerates +// garbage inputs, unless an empty cipher list results. +OPENSSL_EXPORT int SSL_CTX_set_cipher_list(SSL_CTX *ctx, const char *str); + +// SSL_set_strict_cipher_list configures the cipher list for |ssl|, evaluating +// |str| as a cipher string and returning error if |str| contains anything +// meaningless. It returns one on success and zero on failure. +OPENSSL_EXPORT int SSL_set_strict_cipher_list(SSL *ssl, const char *str); + +// SSL_set_cipher_list configures the cipher list for |ssl|, evaluating |str| as +// a cipher string. It returns one on success and zero on failure. +// +// Prefer to use |SSL_set_strict_cipher_list|. This function tolerates garbage +// inputs, unless an empty cipher list results. +OPENSSL_EXPORT int SSL_set_cipher_list(SSL *ssl, const char *str); + +// SSL_CTX_get_ciphers returns the cipher list for |ctx|, in order of +// preference. +OPENSSL_EXPORT STACK_OF(SSL_CIPHER) *SSL_CTX_get_ciphers(const SSL_CTX *ctx); + +// SSL_CTX_cipher_in_group returns one if the |i|th cipher (see +// |SSL_CTX_get_ciphers|) is in the same equipreference group as the one +// following it and zero otherwise. +OPENSSL_EXPORT int SSL_CTX_cipher_in_group(const SSL_CTX *ctx, size_t i); + +// SSL_get_ciphers returns the cipher list for |ssl|, in order of preference. +OPENSSL_EXPORT STACK_OF(SSL_CIPHER) *SSL_get_ciphers(const SSL *ssl); + + +// Connection information. + +// SSL_is_init_finished returns one if |ssl| has completed its initial handshake +// and has no pending handshake. It returns zero otherwise. +OPENSSL_EXPORT int SSL_is_init_finished(const SSL *ssl); + +// SSL_in_init returns one if |ssl| has a pending handshake and zero +// otherwise. +OPENSSL_EXPORT int SSL_in_init(const SSL *ssl); + +// SSL_in_false_start returns one if |ssl| has a pending handshake that is in +// False Start. |SSL_write| may be called at this point without waiting for the +// peer, but |SSL_read| will complete the handshake before accepting application +// data. +// +// See also |SSL_MODE_ENABLE_FALSE_START|. +OPENSSL_EXPORT int SSL_in_false_start(const SSL *ssl); + +// SSL_get_peer_certificate returns the peer's leaf certificate or NULL if the +// peer did not use certificates. The caller must call |X509_free| on the +// result to release it. +OPENSSL_EXPORT X509 *SSL_get_peer_certificate(const SSL *ssl); + +// SSL_get_peer_cert_chain returns the peer's certificate chain or NULL if +// unavailable or the peer did not use certificates. This is the unverified list +// of certificates as sent by the peer, not the final chain built during +// verification. The caller does not take ownership of the result. +// +// WARNING: This function behaves differently between client and server. If +// |ssl| is a server, the returned chain does not include the leaf certificate. +// If a client, it does. +OPENSSL_EXPORT STACK_OF(X509) *SSL_get_peer_cert_chain(const SSL *ssl); + +// SSL_get_peer_full_cert_chain returns the peer's certificate chain, or NULL if +// unavailable or the peer did not use certificates. This is the unverified list +// of certificates as sent by the peer, not the final chain built during +// verification. The caller does not take ownership of the result. +// +// This is the same as |SSL_get_peer_cert_chain| except that this function +// always returns the full chain, i.e. the first element of the return value +// (if any) will be the leaf certificate. In constrast, +// |SSL_get_peer_cert_chain| returns only the intermediate certificates if the +// |ssl| is a server. +OPENSSL_EXPORT STACK_OF(X509) *SSL_get_peer_full_cert_chain(const SSL *ssl); + +// SSL_get0_peer_certificates returns the peer's certificate chain, or NULL if +// unavailable or the peer did not use certificates. This is the unverified list +// of certificates as sent by the peer, not the final chain built during +// verification. The caller does not take ownership of the result. +// +// This is the |CRYPTO_BUFFER| variant of |SSL_get_peer_full_cert_chain|. +OPENSSL_EXPORT STACK_OF(CRYPTO_BUFFER) * + SSL_get0_peer_certificates(const SSL *ssl); + +// SSL_get0_signed_cert_timestamp_list sets |*out| and |*out_len| to point to +// |*out_len| bytes of SCT information from the server. This is only valid if +// |ssl| is a client. The SCT information is a SignedCertificateTimestampList +// (including the two leading length bytes). +// See https://tools.ietf.org/html/rfc6962#section-3.3 +// If no SCT was received then |*out_len| will be zero on return. +// +// WARNING: the returned data is not guaranteed to be well formed. +OPENSSL_EXPORT void SSL_get0_signed_cert_timestamp_list(const SSL *ssl, + const uint8_t **out, + size_t *out_len); + +// SSL_get0_ocsp_response sets |*out| and |*out_len| to point to |*out_len| +// bytes of an OCSP response from the server. This is the DER encoding of an +// OCSPResponse type as defined in RFC 2560. +// +// WARNING: the returned data is not guaranteed to be well formed. +OPENSSL_EXPORT void SSL_get0_ocsp_response(const SSL *ssl, const uint8_t **out, + size_t *out_len); + +// SSL_get_tls_unique writes at most |max_out| bytes of the tls-unique value +// for |ssl| to |out| and sets |*out_len| to the number of bytes written. It +// returns one on success or zero on error. In general |max_out| should be at +// least 12. +// +// This function will always fail if the initial handshake has not completed. +// The tls-unique value will change after a renegotiation but, since +// renegotiations can be initiated by the server at any point, the higher-level +// protocol must either leave them disabled or define states in which the +// tls-unique value can be read. +// +// The tls-unique value is defined by +// https://tools.ietf.org/html/rfc5929#section-3.1. Due to a weakness in the +// TLS protocol, tls-unique is broken for resumed connections unless the +// Extended Master Secret extension is negotiated. Thus this function will +// return zero if |ssl| performed session resumption unless EMS was used when +// negotiating the original session. +OPENSSL_EXPORT int SSL_get_tls_unique(const SSL *ssl, uint8_t *out, + size_t *out_len, size_t max_out); + +// SSL_get_extms_support returns one if the Extended Master Secret extension or +// TLS 1.3 was negotiated. Otherwise, it returns zero. +OPENSSL_EXPORT int SSL_get_extms_support(const SSL *ssl); + +// SSL_get_current_cipher returns the cipher used in the current outgoing +// connection state, or NULL if the null cipher is active. +OPENSSL_EXPORT const SSL_CIPHER *SSL_get_current_cipher(const SSL *ssl); + +// SSL_session_reused returns one if |ssl| performed an abbreviated handshake +// and zero otherwise. +// +// TODO(davidben): Hammer down the semantics of this API while a handshake, +// initial or renego, is in progress. +OPENSSL_EXPORT int SSL_session_reused(const SSL *ssl); + +// SSL_get_secure_renegotiation_support returns one if the peer supports secure +// renegotiation (RFC 5746) or TLS 1.3. Otherwise, it returns zero. +OPENSSL_EXPORT int SSL_get_secure_renegotiation_support(const SSL *ssl); + +// SSL_export_keying_material exports a value derived from the master secret, as +// specified in RFC 5705. It writes |out_len| 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 one on success and zero otherwise. +OPENSSL_EXPORT int SSL_export_keying_material( + SSL *ssl, uint8_t *out, size_t out_len, const char *label, size_t label_len, + const uint8_t *context, size_t context_len, int use_context); + + +// Custom extensions. +// +// The custom extension functions allow TLS extensions to be added to +// ClientHello and ServerHello messages. + +// SSL_custom_ext_add_cb is a callback function that is called when the +// ClientHello (for clients) or ServerHello (for servers) is constructed. In +// the case of a server, this callback will only be called for a given +// extension if the ClientHello contained that extension – it's not possible to +// inject extensions into a ServerHello that the client didn't request. +// +// When called, |extension_value| will contain the extension number that is +// being considered for addition (so that a single callback can handle multiple +// extensions). If the callback wishes to include the extension, it must set +// |*out| to point to |*out_len| bytes of extension contents and return one. In +// this case, the corresponding |SSL_custom_ext_free_cb| callback will later be +// called with the value of |*out| once that data has been copied. +// +// If the callback does not wish to add an extension it must return zero. +// +// Alternatively, the callback can abort the connection by setting +// |*out_alert_value| to a TLS alert number and returning -1. +typedef int (*SSL_custom_ext_add_cb)(SSL *ssl, unsigned extension_value, + const uint8_t **out, size_t *out_len, + int *out_alert_value, void *add_arg); + +// SSL_custom_ext_free_cb is a callback function that is called by OpenSSL iff +// an |SSL_custom_ext_add_cb| callback previously returned one. In that case, +// this callback is called and passed the |out| pointer that was returned by +// the add callback. This is to free any dynamically allocated data created by +// the add callback. +typedef void (*SSL_custom_ext_free_cb)(SSL *ssl, unsigned extension_value, + const uint8_t *out, void *add_arg); + +// SSL_custom_ext_parse_cb is a callback function that is called by OpenSSL to +// parse an extension from the peer: that is from the ServerHello for a client +// and from the ClientHello for a server. +// +// When called, |extension_value| will contain the extension number and the +// contents of the extension are |contents_len| bytes at |contents|. +// +// The callback must return one to continue the handshake. Otherwise, if it +// returns zero, a fatal alert with value |*out_alert_value| is sent and the +// handshake is aborted. +typedef int (*SSL_custom_ext_parse_cb)(SSL *ssl, unsigned extension_value, + const uint8_t *contents, + size_t contents_len, + int *out_alert_value, void *parse_arg); + +// SSL_extension_supported returns one iff OpenSSL internally handles +// extensions of type |extension_value|. This can be used to avoid registering +// custom extension handlers for extensions that a future version of OpenSSL +// may handle internally. +OPENSSL_EXPORT int SSL_extension_supported(unsigned extension_value); + +// SSL_CTX_add_client_custom_ext registers callback functions for handling +// custom TLS extensions for client connections. +// +// If |add_cb| is NULL then an empty extension will be added in each +// ClientHello. Otherwise, see the comment for |SSL_custom_ext_add_cb| about +// this callback. +// +// The |free_cb| may be NULL if |add_cb| doesn't dynamically allocate data that +// needs to be freed. +// +// It returns one on success or zero on error. It's always an error to register +// callbacks for the same extension twice, or to register callbacks for an +// extension that OpenSSL handles internally. See |SSL_extension_supported| to +// discover, at runtime, which extensions OpenSSL handles internally. +OPENSSL_EXPORT int SSL_CTX_add_client_custom_ext( + SSL_CTX *ctx, unsigned extension_value, SSL_custom_ext_add_cb add_cb, + SSL_custom_ext_free_cb free_cb, void *add_arg, + SSL_custom_ext_parse_cb parse_cb, void *parse_arg); + +// SSL_CTX_add_server_custom_ext is the same as +// |SSL_CTX_add_client_custom_ext|, but for server connections. +// +// Unlike on the client side, if |add_cb| is NULL no extension will be added. +// The |add_cb|, if any, will only be called if the ClientHello contained a +// matching extension. +OPENSSL_EXPORT int SSL_CTX_add_server_custom_ext( + SSL_CTX *ctx, unsigned extension_value, SSL_custom_ext_add_cb add_cb, + SSL_custom_ext_free_cb free_cb, void *add_arg, + SSL_custom_ext_parse_cb parse_cb, void *parse_arg); + + +// Sessions. +// +// An |SSL_SESSION| represents an SSL session that may be resumed in an +// abbreviated handshake. It is reference-counted and immutable. Once +// established, an |SSL_SESSION| may be shared by multiple |SSL| objects on +// different threads and must not be modified. + +DECLARE_PEM_rw(SSL_SESSION, SSL_SESSION) + +// SSL_SESSION_new returns a newly-allocated blank |SSL_SESSION| or NULL on +// error. This may be useful when writing tests but should otherwise not be +// used. +OPENSSL_EXPORT SSL_SESSION *SSL_SESSION_new(const SSL_CTX *ctx); + +// SSL_SESSION_up_ref increments the reference count of |session| and returns +// one. +OPENSSL_EXPORT int SSL_SESSION_up_ref(SSL_SESSION *session); + +// SSL_SESSION_free decrements the reference count of |session|. If it reaches +// zero, all data referenced by |session| and |session| itself are released. +OPENSSL_EXPORT void SSL_SESSION_free(SSL_SESSION *session); + +// SSL_SESSION_to_bytes serializes |in| into a newly allocated buffer and sets +// |*out_data| to that buffer and |*out_len| to its length. The caller takes +// ownership of the buffer and must call |OPENSSL_free| when done. It returns +// one on success and zero on error. +OPENSSL_EXPORT int SSL_SESSION_to_bytes(const SSL_SESSION *in, + uint8_t **out_data, size_t *out_len); + +// SSL_SESSION_to_bytes_for_ticket serializes |in|, but excludes the session +// identification information, namely the session ID and ticket. +OPENSSL_EXPORT int SSL_SESSION_to_bytes_for_ticket(const SSL_SESSION *in, + uint8_t **out_data, + size_t *out_len); + +// SSL_SESSION_from_bytes parses |in_len| bytes from |in| as an SSL_SESSION. It +// returns a newly-allocated |SSL_SESSION| on success or NULL on error. +OPENSSL_EXPORT SSL_SESSION *SSL_SESSION_from_bytes( + const uint8_t *in, size_t in_len, const SSL_CTX *ctx); + +// SSL_SESSION_get_version returns a string describing the TLS or DTLS version +// |session| was established at. For example, "TLSv1.2" or "SSLv3". +OPENSSL_EXPORT const char *SSL_SESSION_get_version(const SSL_SESSION *session); + +// SSL_SESSION_get_protocol_version returns the TLS or DTLS version |session| +// was established at. +OPENSSL_EXPORT uint16_t +SSL_SESSION_get_protocol_version(const SSL_SESSION *session); + +// SSL_SESSION_set_protocol_version sets |session|'s TLS or DTLS version to +// |version|. This may be useful when writing tests but should otherwise not be +// used. It returns one on success and zero on error. +OPENSSL_EXPORT int SSL_SESSION_set_protocol_version(SSL_SESSION *session, + uint16_t version); + +// SSL_SESSION_get_id returns a pointer to a buffer containing |session|'s +// session ID and sets |*out_len| to its length. +OPENSSL_EXPORT const uint8_t *SSL_SESSION_get_id(const SSL_SESSION *session, + unsigned *out_len); + +// SSL_SESSION_get_time returns the time at which |session| was established in +// seconds since the UNIX epoch. +OPENSSL_EXPORT uint64_t SSL_SESSION_get_time(const SSL_SESSION *session); + +// SSL_SESSION_get_timeout returns the lifetime of |session| in seconds. +OPENSSL_EXPORT uint32_t SSL_SESSION_get_timeout(const SSL_SESSION *session); + +// SSL_SESSION_get0_peer returns the peer leaf certificate stored in +// |session|. +// +// TODO(davidben): This should return a const X509 *. +OPENSSL_EXPORT X509 *SSL_SESSION_get0_peer(const SSL_SESSION *session); + +// SSL_SESSION_get_master_key writes up to |max_out| bytes of |session|'s master +// secret to |out| and returns the number of bytes written. If |max_out| is +// zero, it returns the size of the master secret. +OPENSSL_EXPORT size_t SSL_SESSION_get_master_key(const SSL_SESSION *session, + uint8_t *out, size_t max_out); + +// SSL_SESSION_set_time sets |session|'s creation time to |time| and returns +// |time|. This function may be useful in writing tests but otherwise should not +// be used. +OPENSSL_EXPORT uint64_t SSL_SESSION_set_time(SSL_SESSION *session, + uint64_t time); + +// SSL_SESSION_set_timeout sets |session|'s timeout to |timeout| and returns +// one. This function may be useful in writing tests but otherwise should not +// be used. +OPENSSL_EXPORT uint32_t SSL_SESSION_set_timeout(SSL_SESSION *session, + uint32_t timeout); + +// SSL_SESSION_set1_id_context sets |session|'s session ID context (see +// |SSL_CTX_set_session_id_context|) to |sid_ctx|. It returns one on success and +// zero on error. This function may be useful in writing tests but otherwise +// should not be used. +OPENSSL_EXPORT int SSL_SESSION_set1_id_context(SSL_SESSION *session, + const uint8_t *sid_ctx, + size_t sid_ctx_len); + +// SSL_SESSION_should_be_single_use returns one if |session| should be +// single-use (TLS 1.3 and later) and zero otherwise. +// +// If this function returns one, clients retain multiple sessions and use each +// only once. This prevents passive observers from correlating connections with +// tickets. See draft-ietf-tls-tls13-18, appendix B.5. If it returns zero, +// |session| cannot be used without leaking a correlator. +OPENSSL_EXPORT int SSL_SESSION_should_be_single_use(const SSL_SESSION *session); + +// SSL_SESSION_is_resumable returns one if |session| is resumable and zero +// otherwise. +OPENSSL_EXPORT int SSL_SESSION_is_resumable(const SSL_SESSION *session); + +// SSL_SESSION_has_ticket returns one if |session| has a ticket and zero +// otherwise. +OPENSSL_EXPORT int SSL_SESSION_has_ticket(const SSL_SESSION *session); + +// SSL_SESSION_get0_ticket sets |*out_ticket| and |*out_len| to |session|'s +// ticket, or NULL and zero if it does not have one. |out_ticket| may be NULL +// if only the ticket length is needed. +OPENSSL_EXPORT void SSL_SESSION_get0_ticket(const SSL_SESSION *session, + const uint8_t **out_ticket, + size_t *out_len); + +// SSL_SESSION_get_ticket_lifetime_hint returns ticket lifetime hint of +// |session| in seconds or zero if none was set. +OPENSSL_EXPORT uint32_t +SSL_SESSION_get_ticket_lifetime_hint(const SSL_SESSION *session); + + +// Session caching. +// +// Session caching allows connections to be established more efficiently based +// on saved parameters from a previous connection, called a session (see +// |SSL_SESSION|). The client offers a saved session, using an opaque identifier +// from a previous connection. The server may accept the session, if it has the +// parameters available. Otherwise, it will decline and continue with a full +// handshake. +// +// This requires both the client and the server to retain session state. A +// client does so with a stateful session cache. A server may do the same or, if +// supported by both sides, statelessly using session tickets. For more +// information on the latter, see the next section. +// +// For a server, the library implements a built-in internal session cache as an +// in-memory hash table. Servers may also use |SSL_CTX_sess_set_get_cb| and +// |SSL_CTX_sess_set_new_cb| to implement a custom external session cache. In +// particular, this may be used to share a session cache between multiple +// servers in a large deployment. An external cache may be used in addition to +// or instead of the internal one. Use |SSL_CTX_set_session_cache_mode| to +// toggle the internal cache. +// +// For a client, the only option is an external session cache. Clients may use +// |SSL_CTX_sess_set_new_cb| to register a callback for when new sessions are +// available. These may be cached and, in subsequent compatible connections, +// configured with |SSL_set_session|. +// +// Note that offering or accepting a session short-circuits certificate +// verification and most parameter negotiation. Resuming sessions across +// different contexts may result in security failures and surprising +// behavior. For a typical client, this means sessions for different hosts must +// be cached under different keys. A client that connects to the same host with, +// e.g., different cipher suite settings or client certificates should also use +// separate session caches between those contexts. Servers should also partition +// session caches between SNI hosts with |SSL_CTX_set_session_id_context|. +// +// Note also, in TLS 1.2 and earlier, offering sessions allows passive observers +// to correlate different client connections. TLS 1.3 and later fix this, +// provided clients use sessions at most once. Session caches are managed by the +// caller in BoringSSL, so this must be implemented externally. See +// |SSL_SESSION_should_be_single_use| for details. + +// SSL_SESS_CACHE_OFF disables all session caching. +#define SSL_SESS_CACHE_OFF 0x0000 + +// SSL_SESS_CACHE_CLIENT enables session caching for a client. The internal +// cache is never used on a client, so this only enables the callbacks. +#define SSL_SESS_CACHE_CLIENT 0x0001 + +// SSL_SESS_CACHE_SERVER enables session caching for a server. +#define SSL_SESS_CACHE_SERVER 0x0002 + +// SSL_SESS_CACHE_BOTH enables session caching for both client and server. +#define SSL_SESS_CACHE_BOTH (SSL_SESS_CACHE_CLIENT | SSL_SESS_CACHE_SERVER) + +// SSL_SESS_CACHE_NO_AUTO_CLEAR disables automatically calling +// |SSL_CTX_flush_sessions| every 255 connections. +#define SSL_SESS_CACHE_NO_AUTO_CLEAR 0x0080 + +// SSL_SESS_CACHE_NO_INTERNAL_LOOKUP, on a server, disables looking up a session +// from the internal session cache. +#define SSL_SESS_CACHE_NO_INTERNAL_LOOKUP 0x0100 + +// SSL_SESS_CACHE_NO_INTERNAL_STORE, on a server, disables storing sessions in +// the internal session cache. +#define SSL_SESS_CACHE_NO_INTERNAL_STORE 0x0200 + +// SSL_SESS_CACHE_NO_INTERNAL, on a server, disables the internal session +// cache. +#define SSL_SESS_CACHE_NO_INTERNAL \ + (SSL_SESS_CACHE_NO_INTERNAL_LOOKUP | SSL_SESS_CACHE_NO_INTERNAL_STORE) + +// SSL_CTX_set_session_cache_mode sets the session cache mode bits for |ctx| to +// |mode|. It returns the previous value. +OPENSSL_EXPORT int SSL_CTX_set_session_cache_mode(SSL_CTX *ctx, int mode); + +// SSL_CTX_get_session_cache_mode returns the session cache mode bits for +// |ctx| +OPENSSL_EXPORT int SSL_CTX_get_session_cache_mode(const SSL_CTX *ctx); + +// SSL_set_session, for a client, configures |ssl| to offer to resume |session| +// in the initial handshake and returns one. The caller retains ownership of +// |session|. +// +// It is an error to call this function after the handshake has begun. +OPENSSL_EXPORT int SSL_set_session(SSL *ssl, SSL_SESSION *session); + +// SSL_DEFAULT_SESSION_TIMEOUT is the default lifetime, in seconds, of a +// session in TLS 1.2 or earlier. This is how long we are willing to use the +// secret to encrypt traffic without fresh key material. +#define SSL_DEFAULT_SESSION_TIMEOUT (2 * 60 * 60) + +// SSL_DEFAULT_SESSION_PSK_DHE_TIMEOUT is the default lifetime, in seconds, of a +// session for TLS 1.3 psk_dhe_ke. This is how long we are willing to use the +// secret as an authenticator. +#define SSL_DEFAULT_SESSION_PSK_DHE_TIMEOUT (2 * 24 * 60 * 60) + +// SSL_DEFAULT_SESSION_AUTH_TIMEOUT is the default non-renewable lifetime, in +// seconds, of a TLS 1.3 session. This is how long we are willing to trust the +// signature in the initial handshake. +#define SSL_DEFAULT_SESSION_AUTH_TIMEOUT (7 * 24 * 60 * 60) + +// SSL_CTX_set_timeout sets the lifetime, in seconds, of TLS 1.2 (or earlier) +// sessions created in |ctx| to |timeout|. +OPENSSL_EXPORT uint32_t SSL_CTX_set_timeout(SSL_CTX *ctx, uint32_t timeout); + +// SSL_CTX_set_session_psk_dhe_timeout sets the lifetime, in seconds, of TLS 1.3 +// sessions created in |ctx| to |timeout|. +OPENSSL_EXPORT void SSL_CTX_set_session_psk_dhe_timeout(SSL_CTX *ctx, + uint32_t timeout); + +// SSL_CTX_get_timeout returns the lifetime, in seconds, of TLS 1.2 (or earlier) +// sessions created in |ctx|. +OPENSSL_EXPORT uint32_t SSL_CTX_get_timeout(const SSL_CTX *ctx); + +// SSL_CTX_set_session_id_context sets |ctx|'s session ID context to |sid_ctx|. +// It returns one on success and zero on error. The session ID context is an +// application-defined opaque byte string. A session will not be used in a +// connection without a matching session ID context. +// +// For a server, if |SSL_VERIFY_PEER| is enabled, it is an error to not set a +// session ID context. +OPENSSL_EXPORT int SSL_CTX_set_session_id_context(SSL_CTX *ctx, + const uint8_t *sid_ctx, + size_t sid_ctx_len); + +// SSL_set_session_id_context sets |ssl|'s session ID context to |sid_ctx|. It +// returns one on success and zero on error. See also +// |SSL_CTX_set_session_id_context|. +OPENSSL_EXPORT int SSL_set_session_id_context(SSL *ssl, const uint8_t *sid_ctx, + size_t sid_ctx_len); + +// SSL_get0_session_id_context returns a pointer to |ssl|'s session ID context +// and sets |*out_len| to its length. +OPENSSL_EXPORT const uint8_t *SSL_get0_session_id_context(const SSL *ssl, + size_t *out_len); + +// SSL_SESSION_CACHE_MAX_SIZE_DEFAULT is the default maximum size of a session +// cache. +#define SSL_SESSION_CACHE_MAX_SIZE_DEFAULT (1024 * 20) + +// SSL_CTX_sess_set_cache_size sets the maximum size of |ctx|'s internal session +// cache to |size|. It returns the previous value. +OPENSSL_EXPORT unsigned long SSL_CTX_sess_set_cache_size(SSL_CTX *ctx, + unsigned long size); + +// SSL_CTX_sess_get_cache_size returns the maximum size of |ctx|'s internal +// session cache. +OPENSSL_EXPORT unsigned long SSL_CTX_sess_get_cache_size(const SSL_CTX *ctx); + +// SSL_CTX_sess_number returns the number of sessions in |ctx|'s internal +// session cache. +OPENSSL_EXPORT size_t SSL_CTX_sess_number(const SSL_CTX *ctx); + +// SSL_CTX_add_session inserts |session| into |ctx|'s internal session cache. It +// returns one on success and zero on error or if |session| is already in the +// cache. The caller retains its reference to |session|. +OPENSSL_EXPORT int SSL_CTX_add_session(SSL_CTX *ctx, SSL_SESSION *session); + +// SSL_CTX_remove_session removes |session| from |ctx|'s internal session cache. +// It returns one on success and zero if |session| was not in the cache. +OPENSSL_EXPORT int SSL_CTX_remove_session(SSL_CTX *ctx, SSL_SESSION *session); + +// SSL_CTX_flush_sessions removes all sessions from |ctx| which have expired as +// of time |time|. If |time| is zero, all sessions are removed. +OPENSSL_EXPORT void SSL_CTX_flush_sessions(SSL_CTX *ctx, uint64_t time); + +// SSL_CTX_sess_set_new_cb sets the callback to be called when a new session is +// established and ready to be cached. If the session cache is disabled (the +// appropriate one of |SSL_SESS_CACHE_CLIENT| or |SSL_SESS_CACHE_SERVER| is +// unset), the callback is not called. +// +// The callback is passed a reference to |session|. It returns one if it takes +// ownership (and then calls |SSL_SESSION_free| when done) and zero otherwise. A +// consumer which places |session| into an in-memory cache will likely return +// one, with the cache calling |SSL_SESSION_free|. A consumer which serializes +// |session| with |SSL_SESSION_to_bytes| may not need to retain |session| and +// will likely return zero. Returning one is equivalent to calling +// |SSL_SESSION_up_ref| and then returning zero. +// +// Note: For a client, the callback may be called on abbreviated handshakes if a +// ticket is renewed. Further, it may not be called until some time after +// |SSL_do_handshake| or |SSL_connect| completes if False Start is enabled. Thus +// it's recommended to use this callback over calling |SSL_get_session| on +// handshake completion. +OPENSSL_EXPORT void SSL_CTX_sess_set_new_cb( + SSL_CTX *ctx, int (*new_session_cb)(SSL *ssl, SSL_SESSION *session)); + +// SSL_CTX_sess_get_new_cb returns the callback set by +// |SSL_CTX_sess_set_new_cb|. +OPENSSL_EXPORT int (*SSL_CTX_sess_get_new_cb(SSL_CTX *ctx))( + SSL *ssl, SSL_SESSION *session); + +// SSL_CTX_sess_set_remove_cb sets a callback which is called when a session is +// removed from the internal session cache. +// +// TODO(davidben): What is the point of this callback? It seems useless since it +// only fires on sessions in the internal cache. +OPENSSL_EXPORT void SSL_CTX_sess_set_remove_cb( + SSL_CTX *ctx, + void (*remove_session_cb)(SSL_CTX *ctx, SSL_SESSION *session)); + +// SSL_CTX_sess_get_remove_cb returns the callback set by +// |SSL_CTX_sess_set_remove_cb|. +OPENSSL_EXPORT void (*SSL_CTX_sess_get_remove_cb(SSL_CTX *ctx))( + SSL_CTX *ctx, SSL_SESSION *session); + +// SSL_CTX_sess_set_get_cb sets a callback to look up a session by ID for a +// server. The callback is passed the session ID and should return a matching +// |SSL_SESSION| or NULL if not found. It should set |*out_copy| to zero and +// return a new reference to the session. This callback is not used for a +// client. +// +// For historical reasons, if |*out_copy| is set to one (default), the SSL +// library will take a new reference to the returned |SSL_SESSION|, expecting +// the callback to return a non-owning pointer. This is not recommended. If +// |ctx| and thus the callback is used on multiple threads, the session may be +// removed and invalidated before the SSL library calls |SSL_SESSION_up_ref|, +// whereas the callback may synchronize internally. +// +// To look up a session asynchronously, the callback may return +// |SSL_magic_pending_session_ptr|. See the documentation for that function and +// |SSL_ERROR_PENDING_SESSION|. +// +// If the internal session cache is enabled, the callback is only consulted if +// the internal cache does not return a match. +OPENSSL_EXPORT void SSL_CTX_sess_set_get_cb( + SSL_CTX *ctx, SSL_SESSION *(*get_session_cb)(SSL *ssl, const uint8_t *id, + int id_len, int *out_copy)); + +// SSL_CTX_sess_get_get_cb returns the callback set by +// |SSL_CTX_sess_set_get_cb|. +OPENSSL_EXPORT SSL_SESSION *(*SSL_CTX_sess_get_get_cb(SSL_CTX *ctx))( + SSL *ssl, const uint8_t *id, int id_len, int *out_copy); + +// SSL_magic_pending_session_ptr returns a magic |SSL_SESSION|* which indicates +// that the session isn't currently unavailable. |SSL_get_error| will then +// return |SSL_ERROR_PENDING_SESSION| and the handshake can be retried later +// when the lookup has completed. +OPENSSL_EXPORT SSL_SESSION *SSL_magic_pending_session_ptr(void); + + +// Session tickets. +// +// Session tickets, from RFC 5077, allow session resumption without server-side +// state. The server maintains a secret ticket key and sends the client opaque +// encrypted session parameters, called a ticket. When offering the session, the +// client sends the ticket which the server decrypts to recover session state. +// Session tickets are enabled by default but may be disabled with +// |SSL_OP_NO_TICKET|. +// +// On the client, ticket-based sessions use the same APIs as ID-based tickets. +// Callers do not need to handle them differently. +// +// On the server, tickets are encrypted and authenticated with a secret key. By +// default, an |SSL_CTX| generates a key on creation and uses it for the +// lifetime of the |SSL_CTX|. Tickets are minted and processed +// transparently. The following functions may be used to configure a persistent +// key or implement more custom behavior, including key rotation and sharing +// keys between multiple servers in a large deployment. There are three levels +// of customisation possible: +// +// 1) One can simply set the keys with |SSL_CTX_set_tlsext_ticket_keys|. +// 2) One can configure an |EVP_CIPHER_CTX| and |HMAC_CTX| directly for +// encryption and authentication. +// 3) One can configure an |SSL_TICKET_AEAD_METHOD| to have more control +// and the option of asynchronous decryption. +// +// An attacker that compromises a server's session ticket key can impersonate +// the server and, prior to TLS 1.3, retroactively decrypt all application +// traffic from sessions using that ticket key. Thus ticket keys must be +// regularly rotated for forward secrecy. Note the default key is rotated +// automatically once every 48 hours but manually configured keys are not. + +// SSL_DEFAULT_TICKET_KEY_ROTATION_INTERVAL is the interval with which the +// default session ticket encryption key is rotated, if in use. If any +// non-default ticket encryption mechanism is configured, automatic rotation is +// disabled. +#define SSL_DEFAULT_TICKET_KEY_ROTATION_INTERVAL (2 * 24 * 60 * 60) + +// SSL_CTX_get_tlsext_ticket_keys writes |ctx|'s session ticket key material to +// |len| bytes of |out|. It returns one on success and zero if |len| is not +// 48. If |out| is NULL, it returns 48 instead. +OPENSSL_EXPORT int SSL_CTX_get_tlsext_ticket_keys(SSL_CTX *ctx, void *out, + size_t len); + +// SSL_CTX_set_tlsext_ticket_keys sets |ctx|'s session ticket key material to +// |len| bytes of |in|. It returns one on success and zero if |len| is not +// 48. If |in| is NULL, it returns 48 instead. +OPENSSL_EXPORT int SSL_CTX_set_tlsext_ticket_keys(SSL_CTX *ctx, const void *in, + size_t len); + +// SSL_TICKET_KEY_NAME_LEN is the length of the key name prefix of a session +// ticket. +#define SSL_TICKET_KEY_NAME_LEN 16 + +// SSL_CTX_set_tlsext_ticket_key_cb sets the ticket callback to |callback| and +// returns one. |callback| will be called when encrypting a new ticket and when +// decrypting a ticket from the client. +// +// In both modes, |ctx| and |hmac_ctx| will already have been initialized with +// |EVP_CIPHER_CTX_init| and |HMAC_CTX_init|, respectively. |callback| +// configures |hmac_ctx| with an HMAC digest and key, and configures |ctx| +// for encryption or decryption, based on the mode. +// +// When encrypting a new ticket, |encrypt| will be one. It writes a public +// 16-byte key name to |key_name| and a fresh IV to |iv|. The output IV length +// must match |EVP_CIPHER_CTX_iv_length| of the cipher selected. In this mode, +// |callback| returns 1 on success and -1 on error. +// +// When decrypting a ticket, |encrypt| will be zero. |key_name| will point to a +// 16-byte key name and |iv| points to an IV. The length of the IV consumed must +// match |EVP_CIPHER_CTX_iv_length| of the cipher selected. In this mode, +// |callback| returns -1 to abort the handshake, 0 if decrypting the ticket +// failed, and 1 or 2 on success. If it returns 2, the ticket will be renewed. +// This may be used to re-key the ticket. +// +// WARNING: |callback| wildly breaks the usual return value convention and is +// called in two different modes. +OPENSSL_EXPORT int SSL_CTX_set_tlsext_ticket_key_cb( + SSL_CTX *ctx, int (*callback)(SSL *ssl, uint8_t *key_name, uint8_t *iv, + EVP_CIPHER_CTX *ctx, HMAC_CTX *hmac_ctx, + int encrypt)); + +// ssl_ticket_aead_result_t enumerates the possible results from decrypting a +// ticket with an |SSL_TICKET_AEAD_METHOD|. +enum ssl_ticket_aead_result_t { + // ssl_ticket_aead_success indicates that the ticket was successfully + // decrypted. + ssl_ticket_aead_success, + // ssl_ticket_aead_retry indicates that the operation could not be + // immediately completed and must be reattempted, via |open|, at a later + // point. + ssl_ticket_aead_retry, + // ssl_ticket_aead_ignore_ticket indicates that the ticket should be ignored + // (i.e. is corrupt or otherwise undecryptable). + ssl_ticket_aead_ignore_ticket, + // ssl_ticket_aead_error indicates that a fatal error occured and the + // handshake should be terminated. + ssl_ticket_aead_error, +}; + +// ssl_ticket_aead_method_st (aka |SSL_TICKET_AEAD_METHOD|) contains methods +// for encrypting and decrypting session tickets. +struct ssl_ticket_aead_method_st { + // max_overhead returns the maximum number of bytes of overhead that |seal| + // may add. + size_t (*max_overhead)(SSL *ssl); + + // seal encrypts and authenticates |in_len| bytes from |in|, writes, at most, + // |max_out_len| bytes to |out|, and puts the number of bytes written in + // |*out_len|. The |in| and |out| buffers may be equal but will not otherwise + // alias. It returns one on success or zero on error. + int (*seal)(SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out_len, + const uint8_t *in, size_t in_len); + + // open authenticates and decrypts |in_len| bytes from |in|, writes, at most, + // |max_out_len| bytes of plaintext to |out|, and puts the number of bytes + // written in |*out_len|. The |in| and |out| buffers may be equal but will + // not otherwise alias. See |ssl_ticket_aead_result_t| for details of the + // return values. In the case that a retry is indicated, the caller should + // arrange for the high-level operation on |ssl| to be retried when the + // operation is completed, which will result in another call to |open|. + enum ssl_ticket_aead_result_t (*open)(SSL *ssl, uint8_t *out, size_t *out_len, + size_t max_out_len, const uint8_t *in, + size_t in_len); +}; + +// SSL_CTX_set_ticket_aead_method configures a custom ticket AEAD method table +// on |ctx|. |aead_method| must remain valid for the lifetime of |ctx|. +OPENSSL_EXPORT void SSL_CTX_set_ticket_aead_method( + SSL_CTX *ctx, const SSL_TICKET_AEAD_METHOD *aead_method); + + +// Elliptic curve Diffie-Hellman. +// +// Cipher suites using an ECDHE key exchange perform Diffie-Hellman over an +// elliptic curve negotiated by both endpoints. See RFC 4492. Only named curves +// are supported. ECDHE is always enabled, but the curve preferences may be +// configured with these functions. +// +// Note that TLS 1.3 renames these from curves to groups. For consistency, we +// currently use the TLS 1.2 name in the API. + +// SSL_CTX_set1_curves sets the preferred curves for |ctx| to be |curves|. Each +// element of |curves| should be a curve nid. It returns one on success and +// zero on failure. +// +// Note that this API uses nid values from nid.h and not the |SSL_CURVE_*| +// values defined below. +OPENSSL_EXPORT int SSL_CTX_set1_curves(SSL_CTX *ctx, const int *curves, + size_t curves_len); + +// SSL_set1_curves sets the preferred curves for |ssl| to be |curves|. Each +// element of |curves| should be a curve nid. It returns one on success and +// zero on failure. +// +// Note that this API uses nid values from nid.h and not the |SSL_CURVE_*| +// values defined below. +OPENSSL_EXPORT int SSL_set1_curves(SSL *ssl, const int *curves, + size_t curves_len); + +// SSL_CTX_set1_curves_list sets the preferred curves for |ctx| to be the +// colon-separated list |curves|. Each element of |curves| should be a curve +// name (e.g. P-256, X25519, ...). It returns one on success and zero on +// failure. +OPENSSL_EXPORT int SSL_CTX_set1_curves_list(SSL_CTX *ctx, const char *curves); + +// SSL_set1_curves_list sets the preferred curves for |ssl| to be the +// colon-separated list |curves|. Each element of |curves| should be a curve +// name (e.g. P-256, X25519, ...). It returns one on success and zero on +// failure. +OPENSSL_EXPORT int SSL_set1_curves_list(SSL *ssl, const char *curves); + +// SSL_CURVE_* define TLS curve IDs. +#define SSL_CURVE_SECP224R1 21 +#define SSL_CURVE_SECP256R1 23 +#define SSL_CURVE_SECP384R1 24 +#define SSL_CURVE_SECP521R1 25 +#define SSL_CURVE_X25519 29 + +// SSL_get_curve_id returns the ID of the curve used by |ssl|'s most recently +// completed handshake or 0 if not applicable. +// +// TODO(davidben): This API currently does not work correctly if there is a +// renegotiation in progress. Fix this. +OPENSSL_EXPORT uint16_t SSL_get_curve_id(const SSL *ssl); + +// SSL_get_curve_name returns a human-readable name for the curve specified by +// the given TLS curve id, or NULL if the curve is unknown. +OPENSSL_EXPORT const char *SSL_get_curve_name(uint16_t curve_id); + + +// Certificate verification. +// +// SSL may authenticate either endpoint with an X.509 certificate. Typically +// this is used to authenticate the server to the client. These functions +// configure certificate verification. +// +// WARNING: By default, certificate verification errors on a client are not +// fatal. See |SSL_VERIFY_NONE| This may be configured with +// |SSL_CTX_set_verify|. +// +// By default clients are anonymous but a server may request a certificate from +// the client by setting |SSL_VERIFY_PEER|. +// +// Many of these functions use OpenSSL's legacy X.509 stack which is +// underdocumented and deprecated, but the replacement isn't ready yet. For +// now, consumers may use the existing stack or bypass it by performing +// certificate verification externally. This may be done with +// |SSL_CTX_set_cert_verify_callback| or by extracting the chain with +// |SSL_get_peer_cert_chain| after the handshake. In the future, functions will +// be added to use the SSL stack without dependency on any part of the legacy +// X.509 and ASN.1 stack. +// +// To augment certificate verification, a client may also enable OCSP stapling +// (RFC 6066) and Certificate Transparency (RFC 6962) extensions. + +// SSL_VERIFY_NONE, on a client, verifies the server certificate but does not +// make errors fatal. The result may be checked with |SSL_get_verify_result|. On +// a server it does not request a client certificate. This is the default. +#define SSL_VERIFY_NONE 0x00 + +// SSL_VERIFY_PEER, on a client, makes server certificate errors fatal. On a +// server it requests a client certificate and makes errors fatal. However, +// anonymous clients are still allowed. See +// |SSL_VERIFY_FAIL_IF_NO_PEER_CERT|. +#define SSL_VERIFY_PEER 0x01 + +// SSL_VERIFY_FAIL_IF_NO_PEER_CERT configures a server to reject connections if +// the client declines to send a certificate. This flag must be used together +// with |SSL_VERIFY_PEER|, otherwise it won't work. +#define SSL_VERIFY_FAIL_IF_NO_PEER_CERT 0x02 + +// SSL_VERIFY_PEER_IF_NO_OBC configures a server to request a client certificate +// if and only if Channel ID is not negotiated. +#define SSL_VERIFY_PEER_IF_NO_OBC 0x04 + +// SSL_CTX_set_verify configures certificate verification behavior. |mode| is +// one of the |SSL_VERIFY_*| values defined above. |callback|, if not NULL, is +// used to customize certificate verification. See the behavior of +// |X509_STORE_CTX_set_verify_cb|. +// +// The callback may use |SSL_get_ex_data_X509_STORE_CTX_idx| with +// |X509_STORE_CTX_get_ex_data| to look up the |SSL| from |store_ctx|. +OPENSSL_EXPORT void SSL_CTX_set_verify( + SSL_CTX *ctx, int mode, int (*callback)(int ok, X509_STORE_CTX *store_ctx)); + +// SSL_set_verify configures certificate verification behavior. |mode| is one of +// the |SSL_VERIFY_*| values defined above. |callback|, if not NULL, is used to +// customize certificate verification. See the behavior of +// |X509_STORE_CTX_set_verify_cb|. +// +// The callback may use |SSL_get_ex_data_X509_STORE_CTX_idx| with +// |X509_STORE_CTX_get_ex_data| to look up the |SSL| from |store_ctx|. +OPENSSL_EXPORT void SSL_set_verify(SSL *ssl, int mode, + int (*callback)(int ok, + X509_STORE_CTX *store_ctx)); + +enum ssl_verify_result_t { + ssl_verify_ok, + ssl_verify_invalid, + ssl_verify_retry, +}; + +// SSL_CTX_set_custom_verify configures certificate verification. |mode| is one +// of the |SSL_VERIFY_*| values defined above. |callback| performs the +// certificate verification. +// +// The callback may call |SSL_get0_peer_certificates| for the certificate chain +// to validate. The callback should return |ssl_verify_ok| if the certificate is +// valid. If the certificate is invalid, the callback should return +// |ssl_verify_invalid| and optionally set |*out_alert| to an alert to send to +// the peer. Some useful alerts include |SSL_AD_CERTIFICATE_EXPIRED|, +// |SSL_AD_CERTIFICATE_REVOKED|, |SSL_AD_UNKNOWN_CA|, |SSL_AD_BAD_CERTIFICATE|, +// |SSL_AD_CERTIFICATE_UNKNOWN|, and |SSL_AD_INTERNAL_ERROR|. See RFC 5246 +// section 7.2.2 for their precise meanings. If unspecified, +// |SSL_AD_CERTIFICATE_UNKNOWN| will be sent by default. +// +// To verify a certificate asynchronously, the callback may return +// |ssl_verify_retry|. The handshake will then pause with |SSL_get_error| +// returning |SSL_ERROR_WANT_CERTIFICATE_VERIFY|. +OPENSSL_EXPORT void SSL_CTX_set_custom_verify( + SSL_CTX *ctx, int mode, + enum ssl_verify_result_t (*callback)(SSL *ssl, uint8_t *out_alert)); + +// SSL_set_custom_verify behaves like |SSL_CTX_set_custom_verify| but configures +// an individual |SSL|. +OPENSSL_EXPORT void SSL_set_custom_verify( + SSL *ssl, int mode, + enum ssl_verify_result_t (*callback)(SSL *ssl, uint8_t *out_alert)); + +// SSL_CTX_get_verify_mode returns |ctx|'s verify mode, set by +// |SSL_CTX_set_verify|. +OPENSSL_EXPORT int SSL_CTX_get_verify_mode(const SSL_CTX *ctx); + +// SSL_get_verify_mode returns |ssl|'s verify mode, set by |SSL_CTX_set_verify| +// or |SSL_set_verify|. +OPENSSL_EXPORT int SSL_get_verify_mode(const SSL *ssl); + +// SSL_CTX_get_verify_callback returns the callback set by +// |SSL_CTX_set_verify|. +OPENSSL_EXPORT int (*SSL_CTX_get_verify_callback(const SSL_CTX *ctx))( + int ok, X509_STORE_CTX *store_ctx); + +// SSL_get_verify_callback returns the callback set by |SSL_CTX_set_verify| or +// |SSL_set_verify|. +OPENSSL_EXPORT int (*SSL_get_verify_callback(const SSL *ssl))( + int ok, X509_STORE_CTX *store_ctx); + +// SSL_CTX_set_verify_depth sets the maximum depth of a certificate chain +// accepted in verification. This number does not include the leaf, so a depth +// of 1 allows the leaf and one CA certificate. +OPENSSL_EXPORT void SSL_CTX_set_verify_depth(SSL_CTX *ctx, int depth); + +// SSL_set_verify_depth sets the maximum depth of a certificate chain accepted +// in verification. This number does not include the leaf, so a depth of 1 +// allows the leaf and one CA certificate. +OPENSSL_EXPORT void SSL_set_verify_depth(SSL *ssl, int depth); + +// SSL_CTX_get_verify_depth returns the maximum depth of a certificate accepted +// in verification. +OPENSSL_EXPORT int SSL_CTX_get_verify_depth(const SSL_CTX *ctx); + +// SSL_get_verify_depth returns the maximum depth of a certificate accepted in +// verification. +OPENSSL_EXPORT int SSL_get_verify_depth(const SSL *ssl); + +// SSL_CTX_set1_param sets verification parameters from |param|. It returns one +// on success and zero on failure. The caller retains ownership of |param|. +OPENSSL_EXPORT int SSL_CTX_set1_param(SSL_CTX *ctx, + const X509_VERIFY_PARAM *param); + +// SSL_set1_param sets verification parameters from |param|. It returns one on +// success and zero on failure. The caller retains ownership of |param|. +OPENSSL_EXPORT int SSL_set1_param(SSL *ssl, + const X509_VERIFY_PARAM *param); + +// SSL_CTX_get0_param returns |ctx|'s |X509_VERIFY_PARAM| for certificate +// verification. The caller must not release the returned pointer but may call +// functions on it to configure it. +OPENSSL_EXPORT X509_VERIFY_PARAM *SSL_CTX_get0_param(SSL_CTX *ctx); + +// SSL_get0_param returns |ssl|'s |X509_VERIFY_PARAM| for certificate +// verification. The caller must not release the returned pointer but may call +// functions on it to configure it. +OPENSSL_EXPORT X509_VERIFY_PARAM *SSL_get0_param(SSL *ssl); + +// SSL_CTX_set_purpose sets |ctx|'s |X509_VERIFY_PARAM|'s 'purpose' parameter to +// |purpose|. It returns one on success and zero on error. +OPENSSL_EXPORT int SSL_CTX_set_purpose(SSL_CTX *ctx, int purpose); + +// SSL_set_purpose sets |ssl|'s |X509_VERIFY_PARAM|'s 'purpose' parameter to +// |purpose|. It returns one on success and zero on error. +OPENSSL_EXPORT int SSL_set_purpose(SSL *ssl, int purpose); + +// SSL_CTX_set_trust sets |ctx|'s |X509_VERIFY_PARAM|'s 'trust' parameter to +// |trust|. It returns one on success and zero on error. +OPENSSL_EXPORT int SSL_CTX_set_trust(SSL_CTX *ctx, int trust); + +// SSL_set_trust sets |ssl|'s |X509_VERIFY_PARAM|'s 'trust' parameter to +// |trust|. It returns one on success and zero on error. +OPENSSL_EXPORT int SSL_set_trust(SSL *ssl, int trust); + +// SSL_CTX_set_cert_store sets |ctx|'s certificate store to |store|. It takes +// ownership of |store|. The store is used for certificate verification. +// +// The store is also used for the auto-chaining feature, but this is deprecated. +// See also |SSL_MODE_NO_AUTO_CHAIN|. +OPENSSL_EXPORT void SSL_CTX_set_cert_store(SSL_CTX *ctx, X509_STORE *store); + +// SSL_CTX_get_cert_store returns |ctx|'s certificate store. +OPENSSL_EXPORT X509_STORE *SSL_CTX_get_cert_store(const SSL_CTX *ctx); + +// SSL_CTX_set_default_verify_paths loads the OpenSSL system-default trust +// anchors into |ctx|'s store. It returns one on success and zero on failure. +OPENSSL_EXPORT int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx); + +// SSL_CTX_load_verify_locations loads trust anchors into |ctx|'s store from +// |ca_file| and |ca_dir|, either of which may be NULL. If |ca_file| is passed, +// it is opened and PEM-encoded CA certificates are read. If |ca_dir| is passed, +// it is treated as a directory in OpenSSL's hashed directory format. It returns +// one on success and zero on failure. +// +// See +// https://www.openssl.org/docs/manmaster/ssl/SSL_CTX_load_verify_locations.html +// for documentation on the directory format. +OPENSSL_EXPORT int SSL_CTX_load_verify_locations(SSL_CTX *ctx, + const char *ca_file, + const char *ca_dir); + +// SSL_get_verify_result returns the result of certificate verification. It is +// either |X509_V_OK| or a |X509_V_ERR_*| value. +OPENSSL_EXPORT long SSL_get_verify_result(const SSL *ssl); + +// SSL_alert_from_verify_result returns the SSL alert code, such as +// |SSL_AD_CERTIFICATE_EXPIRED|, that corresponds to an |X509_V_ERR_*| value. +// The return value is always an alert, even when |result| is |X509_V_OK|. +OPENSSL_EXPORT int SSL_alert_from_verify_result(long result); + +// SSL_get_ex_data_X509_STORE_CTX_idx returns the ex_data index used to look up +// the |SSL| associated with an |X509_STORE_CTX| in the verify callback. +OPENSSL_EXPORT int SSL_get_ex_data_X509_STORE_CTX_idx(void); + +// SSL_CTX_set_cert_verify_callback sets a custom callback to be called on +// certificate verification rather than |X509_verify_cert|. |store_ctx| contains +// the verification parameters. The callback should return one on success and +// zero on fatal error. It may use |X509_STORE_CTX_set_error| to set a +// verification result. +// +// The callback may use |SSL_get_ex_data_X509_STORE_CTX_idx| to recover the +// |SSL| object from |store_ctx|. +OPENSSL_EXPORT void SSL_CTX_set_cert_verify_callback( + SSL_CTX *ctx, int (*callback)(X509_STORE_CTX *store_ctx, void *arg), + void *arg); + +// SSL_enable_signed_cert_timestamps causes |ssl| (which must be the client end +// of a connection) to request SCTs from the server. See +// https://tools.ietf.org/html/rfc6962. +// +// Call |SSL_get0_signed_cert_timestamp_list| to recover the SCT after the +// handshake. +OPENSSL_EXPORT void SSL_enable_signed_cert_timestamps(SSL *ssl); + +// SSL_CTX_enable_signed_cert_timestamps enables SCT requests on all client SSL +// objects created from |ctx|. +// +// Call |SSL_get0_signed_cert_timestamp_list| to recover the SCT after the +// handshake. +OPENSSL_EXPORT void SSL_CTX_enable_signed_cert_timestamps(SSL_CTX *ctx); + +// SSL_enable_ocsp_stapling causes |ssl| (which must be the client end of a +// connection) to request a stapled OCSP response from the server. +// +// Call |SSL_get0_ocsp_response| to recover the OCSP response after the +// handshake. +OPENSSL_EXPORT void SSL_enable_ocsp_stapling(SSL *ssl); + +// SSL_CTX_enable_ocsp_stapling enables OCSP stapling on all client SSL objects +// created from |ctx|. +// +// Call |SSL_get0_ocsp_response| to recover the OCSP response after the +// handshake. +OPENSSL_EXPORT void SSL_CTX_enable_ocsp_stapling(SSL_CTX *ctx); + +// SSL_CTX_set0_verify_cert_store sets an |X509_STORE| that will be used +// exclusively for certificate verification and returns one. Ownership of +// |store| is transferred to the |SSL_CTX|. +OPENSSL_EXPORT int SSL_CTX_set0_verify_cert_store(SSL_CTX *ctx, + X509_STORE *store); + +// SSL_CTX_set1_verify_cert_store sets an |X509_STORE| that will be used +// exclusively for certificate verification and returns one. An additional +// reference to |store| will be taken. +OPENSSL_EXPORT int SSL_CTX_set1_verify_cert_store(SSL_CTX *ctx, + X509_STORE *store); + +// SSL_set0_verify_cert_store sets an |X509_STORE| that will be used +// exclusively for certificate verification and returns one. Ownership of +// |store| is transferred to the |SSL|. +OPENSSL_EXPORT int SSL_set0_verify_cert_store(SSL *ssl, X509_STORE *store); + +// SSL_set1_verify_cert_store sets an |X509_STORE| that will be used +// exclusively for certificate verification and returns one. An additional +// reference to |store| will be taken. +OPENSSL_EXPORT int SSL_set1_verify_cert_store(SSL *ssl, X509_STORE *store); + +// SSL_CTX_set_ed25519_enabled configures whether |ctx| advertises support for +// the Ed25519 signature algorithm when using the default preference list. +OPENSSL_EXPORT void SSL_CTX_set_ed25519_enabled(SSL_CTX *ctx, int enabled); + +// SSL_CTX_set_verify_algorithm_prefs confingures |ctx| to use |prefs| as the +// preference list when verifying signature's from the peer's long-term key. It +// returns one on zero on error. |prefs| should not include the internal-only +// value |SSL_SIGN_RSA_PKCS1_MD5_SHA1|. +OPENSSL_EXPORT int SSL_CTX_set_verify_algorithm_prefs(SSL_CTX *ctx, + const uint16_t *prefs, + size_t num_prefs); + + +// Client certificate CA list. +// +// When requesting a client certificate, a server may advertise a list of +// certificate authorities which are accepted. These functions may be used to +// configure this list. + +// SSL_set_client_CA_list sets |ssl|'s client certificate CA list to +// |name_list|. It takes ownership of |name_list|. +OPENSSL_EXPORT void SSL_set_client_CA_list(SSL *ssl, + STACK_OF(X509_NAME) *name_list); + +// SSL_CTX_set_client_CA_list sets |ctx|'s client certificate CA list to +// |name_list|. It takes ownership of |name_list|. +OPENSSL_EXPORT void SSL_CTX_set_client_CA_list(SSL_CTX *ctx, + STACK_OF(X509_NAME) *name_list); + +// SSL_set0_client_CAs sets |ssl|'s client certificate CA list to |name_list|, +// which should contain DER-encoded distinguished names (RFC 5280). It takes +// ownership of |name_list|. +OPENSSL_EXPORT void SSL_set0_client_CAs(SSL *ssl, + STACK_OF(CRYPTO_BUFFER) *name_list); + +// SSL_CTX_set0_client_CAs sets |ctx|'s client certificate CA list to +// |name_list|, which should contain DER-encoded distinguished names (RFC 5280). +// It takes ownership of |name_list|. +OPENSSL_EXPORT void SSL_CTX_set0_client_CAs(SSL_CTX *ctx, + STACK_OF(CRYPTO_BUFFER) *name_list); + +// SSL_get_client_CA_list returns |ssl|'s client certificate CA list. If |ssl| +// has not been configured as a client, this is the list configured by +// |SSL_CTX_set_client_CA_list|. +// +// If configured as a client, it returns the client certificate CA list sent by +// the server. In this mode, the behavior is undefined except during the +// callbacks set by |SSL_CTX_set_cert_cb| and |SSL_CTX_set_client_cert_cb| or +// when the handshake is paused because of them. +OPENSSL_EXPORT STACK_OF(X509_NAME) *SSL_get_client_CA_list(const SSL *ssl); + +// SSL_get0_server_requested_CAs returns the CAs sent by a server to guide a +// client in certificate selection. They are a series of DER-encoded X.509 +// names. This function may only be called during a callback set by +// |SSL_CTX_set_cert_cb| or when the handshake is paused because of it. +// +// The returned stack is owned by |ssl|, as are its contents. It should not be +// used past the point where the handshake is restarted after the callback. +OPENSSL_EXPORT STACK_OF(CRYPTO_BUFFER) *SSL_get0_server_requested_CAs( + const SSL *ssl); + +// SSL_CTX_get_client_CA_list returns |ctx|'s client certificate CA list. +OPENSSL_EXPORT STACK_OF(X509_NAME) * + SSL_CTX_get_client_CA_list(const SSL_CTX *ctx); + +// SSL_add_client_CA appends |x509|'s subject to the client certificate CA list. +// It returns one on success or zero on error. The caller retains ownership of +// |x509|. +OPENSSL_EXPORT int SSL_add_client_CA(SSL *ssl, X509 *x509); + +// SSL_CTX_add_client_CA appends |x509|'s subject to the client certificate CA +// list. It returns one on success or zero on error. The caller retains +// ownership of |x509|. +OPENSSL_EXPORT int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x509); + +// SSL_load_client_CA_file opens |file| and reads PEM-encoded certificates from +// it. It returns a newly-allocated stack of the certificate subjects or NULL +// on error. +OPENSSL_EXPORT STACK_OF(X509_NAME) *SSL_load_client_CA_file(const char *file); + +// SSL_dup_CA_list makes a deep copy of |list|. It returns the new list on +// success or NULL on allocation error. +OPENSSL_EXPORT STACK_OF(X509_NAME) *SSL_dup_CA_list(STACK_OF(X509_NAME) *list); + +// SSL_add_file_cert_subjects_to_stack behaves like |SSL_load_client_CA_file| +// but appends the result to |out|. It returns one on success or zero on +// error. +OPENSSL_EXPORT int SSL_add_file_cert_subjects_to_stack(STACK_OF(X509_NAME) *out, + const char *file); + + +// Server name indication. +// +// The server_name extension (RFC 3546) allows the client to advertise the name +// of the server it is connecting to. This is used in virtual hosting +// deployments to select one of a several certificates on a single IP. Only the +// host_name name type is supported. + +#define TLSEXT_NAMETYPE_host_name 0 + +// SSL_set_tlsext_host_name, for a client, configures |ssl| to advertise |name| +// in the server_name extension. It returns one on success and zero on error. +OPENSSL_EXPORT int SSL_set_tlsext_host_name(SSL *ssl, const char *name); + +// SSL_get_servername, for a server, returns the hostname supplied by the +// client or NULL if there was none. The |type| argument must be +// |TLSEXT_NAMETYPE_host_name|. +OPENSSL_EXPORT const char *SSL_get_servername(const SSL *ssl, const int type); + +// SSL_get_servername_type, for a server, returns |TLSEXT_NAMETYPE_host_name| +// if the client sent a hostname and -1 otherwise. +OPENSSL_EXPORT int SSL_get_servername_type(const SSL *ssl); + +// SSL_CTX_set_tlsext_servername_callback configures |callback| to be called on +// the server after ClientHello extensions have been parsed and returns one. +// The callback may use |SSL_get_servername| to examine the server_name +// extension and returns a |SSL_TLSEXT_ERR_*| value. The value of |arg| may be +// set by calling |SSL_CTX_set_tlsext_servername_arg|. +// +// If the callback returns |SSL_TLSEXT_ERR_NOACK|, the server_name extension is +// not acknowledged in the ServerHello. If the return value is +// |SSL_TLSEXT_ERR_ALERT_FATAL|, then |*out_alert| is the alert to send, +// defaulting to |SSL_AD_UNRECOGNIZED_NAME|. |SSL_TLSEXT_ERR_ALERT_WARNING| is +// ignored and treated as |SSL_TLSEXT_ERR_OK|. +OPENSSL_EXPORT int SSL_CTX_set_tlsext_servername_callback( + SSL_CTX *ctx, int (*callback)(SSL *ssl, int *out_alert, void *arg)); + +// SSL_CTX_set_tlsext_servername_arg sets the argument to the servername +// callback and returns one. See |SSL_CTX_set_tlsext_servername_callback|. +OPENSSL_EXPORT int SSL_CTX_set_tlsext_servername_arg(SSL_CTX *ctx, void *arg); + +// SSL_TLSEXT_ERR_* are values returned by some extension-related callbacks. +#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 + +// SSL_set_SSL_CTX changes |ssl|'s |SSL_CTX|. |ssl| will use the +// certificate-related settings from |ctx|, and |SSL_get_SSL_CTX| will report +// |ctx|. This function may be used during the callbacks registered by +// |SSL_CTX_set_select_certificate_cb|, +// |SSL_CTX_set_tlsext_servername_callback|, and |SSL_CTX_set_cert_cb| or when +// the handshake is paused from them. It is typically used to switch +// certificates based on SNI. +// +// Note the session cache and related settings will continue to use the initial +// |SSL_CTX|. Callers should use |SSL_CTX_set_session_id_context| to partition +// the session cache between different domains. +// +// TODO(davidben): Should other settings change after this call? +OPENSSL_EXPORT SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX *ctx); + + +// Application-layer protocol negotiation. +// +// The ALPN extension (RFC 7301) allows negotiating different application-layer +// protocols over a single port. This is used, for example, to negotiate +// HTTP/2. + +// SSL_CTX_set_alpn_protos sets the client 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). It returns zero on success and one on failure. +// Configuring this list enables ALPN on a client. +// +// WARNING: this function is dangerous because it breaks the usual return value +// convention. +OPENSSL_EXPORT int SSL_CTX_set_alpn_protos(SSL_CTX *ctx, const uint8_t *protos, + unsigned protos_len); + +// SSL_set_alpn_protos sets the client 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). It returns zero on success and one on failure. +// Configuring this list enables ALPN on a client. +// +// WARNING: this function is dangerous because it breaks the usual return value +// convention. +OPENSSL_EXPORT int SSL_set_alpn_protos(SSL *ssl, const uint8_t *protos, + unsigned protos_len); + +// 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. Configuring this callback enables ALPN on +// a server. +// +// The callback is passed a wire-format (i.e. a series of non-empty, 8-bit +// length-prefixed strings) ALPN protocol list in |in|. It should set |*out| and +// |*out_len| to the selected protocol and return |SSL_TLSEXT_ERR_OK| on +// success. It does not pass ownership of the buffer. Otherwise, it should +// return |SSL_TLSEXT_ERR_NOACK|. Other |SSL_TLSEXT_ERR_*| values are +// unimplemented and will be treated as |SSL_TLSEXT_ERR_NOACK|. +// +// The cipher suite is selected before negotiating ALPN. The callback may use +// |SSL_get_pending_cipher| to query the cipher suite. +OPENSSL_EXPORT void SSL_CTX_set_alpn_select_cb( + SSL_CTX *ctx, int (*cb)(SSL *ssl, const uint8_t **out, uint8_t *out_len, + const uint8_t *in, unsigned in_len, void *arg), + void *arg); + +// SSL_get0_alpn_selected gets the selected ALPN protocol (if any) from |ssl|. +// On return it sets |*out_data| to point to |*out_len| bytes of protocol name +// (not including the leading length-prefix byte). If the server didn't respond +// with a negotiated protocol then |*out_len| will be zero. +OPENSSL_EXPORT void SSL_get0_alpn_selected(const SSL *ssl, + const uint8_t **out_data, + unsigned *out_len); + +// SSL_CTX_set_allow_unknown_alpn_protos configures client connections on |ctx| +// to allow unknown ALPN protocols from the server. Otherwise, by default, the +// client will require that the protocol be advertised in +// |SSL_CTX_set_alpn_protos|. +OPENSSL_EXPORT void SSL_CTX_set_allow_unknown_alpn_protos(SSL_CTX *ctx, + int enabled); + + +// Next protocol negotiation. +// +// The NPN extension (draft-agl-tls-nextprotoneg-03) is the predecessor to ALPN +// and deprecated in favor of it. + +// 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 |*out_len| to its length. This memory +// will not be modified, but one should assume that |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. +OPENSSL_EXPORT void SSL_CTX_set_next_protos_advertised_cb( + SSL_CTX *ctx, + int (*cb)(SSL *ssl, const uint8_t **out, unsigned *out_len, void *arg), + void *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 |*out_len|. The server's advertised +// protocols are provided in |in| and |in_len|. 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|. +// +// Configuring this callback enables NPN on a client. +OPENSSL_EXPORT void SSL_CTX_set_next_proto_select_cb( + SSL_CTX *ctx, int (*cb)(SSL *ssl, uint8_t **out, uint8_t *out_len, + const uint8_t *in, unsigned in_len, void *arg), + void *arg); + +// SSL_get0_next_proto_negotiated sets |*out_data| and |*out_len| to point to +// the client's requested protocol for this connection. If the client didn't +// request any protocol, then |*out_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 server. +OPENSSL_EXPORT void SSL_get0_next_proto_negotiated(const SSL *ssl, + const uint8_t **out_data, + unsigned *out_len); + +// 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|. +// +// |peer| and |supported| must be vectors of 8-bit, length-prefixed byte strings +// containing the peer and locally-configured protocols, respectively. The +// length byte itself is not included in the length. A byte string of length 0 +// is invalid. No byte string may be truncated. |supported| is assumed to be +// non-empty. +// +// This function finds the first protocol in |peer| which is also in +// |supported|. If one was found, it sets |*out| and |*out_len| to point to it +// and returns |OPENSSL_NPN_NEGOTIATED|. Otherwise, it returns +// |OPENSSL_NPN_NO_OVERLAP| and sets |*out| and |*out_len| to the first +// supported protocol. +OPENSSL_EXPORT int SSL_select_next_proto(uint8_t **out, uint8_t *out_len, + const uint8_t *peer, unsigned peer_len, + const uint8_t *supported, + unsigned supported_len); + +#define OPENSSL_NPN_UNSUPPORTED 0 +#define OPENSSL_NPN_NEGOTIATED 1 +#define OPENSSL_NPN_NO_OVERLAP 2 + + +// Channel ID. +// +// See draft-balfanz-tls-channelid-01. + +// SSL_CTX_set_tls_channel_id_enabled configures whether connections associated +// with |ctx| should enable Channel ID. +OPENSSL_EXPORT void SSL_CTX_set_tls_channel_id_enabled(SSL_CTX *ctx, + int enabled); + +// SSL_set_tls_channel_id_enabled configures whether |ssl| should enable Channel +// ID. +OPENSSL_EXPORT void SSL_set_tls_channel_id_enabled(SSL *ssl, int enabled); + +// SSL_CTX_set1_tls_channel_id configures a TLS client to send a TLS Channel ID +// to compatible servers. |private_key| must be a P-256 EC key. It returns one +// on success and zero on error. +OPENSSL_EXPORT int SSL_CTX_set1_tls_channel_id(SSL_CTX *ctx, + EVP_PKEY *private_key); + +// SSL_set1_tls_channel_id configures a TLS client to send a TLS Channel ID to +// compatible servers. |private_key| must be a P-256 EC key. It returns one on +// success and zero on error. +OPENSSL_EXPORT int SSL_set1_tls_channel_id(SSL *ssl, EVP_PKEY *private_key); + +// SSL_get_tls_channel_id gets the client's TLS Channel ID from a server |SSL*| +// and copies up to the first |max_out| bytes into |out|. The Channel ID +// consists of the client's P-256 public key as an (x,y) pair where each is a +// 32-byte, big-endian field element. It returns 0 if the client didn't offer a +// Channel ID and the length of the complete Channel ID otherwise. +OPENSSL_EXPORT size_t SSL_get_tls_channel_id(SSL *ssl, uint8_t *out, + size_t max_out); + +// SSL_CTX_set_channel_id_cb sets a callback to be called when a TLS Channel ID +// is requested. The callback may set |*out_pkey| to a key, passing a reference +// to the caller. If none is returned, the handshake will pause and +// |SSL_get_error| will return |SSL_ERROR_WANT_CHANNEL_ID_LOOKUP|. +// +// See also |SSL_ERROR_WANT_CHANNEL_ID_LOOKUP|. +OPENSSL_EXPORT void SSL_CTX_set_channel_id_cb( + SSL_CTX *ctx, void (*channel_id_cb)(SSL *ssl, EVP_PKEY **out_pkey)); + +// SSL_CTX_get_channel_id_cb returns the callback set by +// |SSL_CTX_set_channel_id_cb|. +OPENSSL_EXPORT void (*SSL_CTX_get_channel_id_cb(SSL_CTX *ctx))( + SSL *ssl, EVP_PKEY **out_pkey); + + +// Token Binding. +// +// See draft-ietf-tokbind-protocol-16. + +// SSL_set_token_binding_params sets |params| as the Token Binding Key +// parameters (section 3 of draft-ietf-tokbind-protocol-16) to negotiate on the +// connection. If this function is not called, or if |len| is 0, then this +// endpoint will not attempt to negotiate Token Binding. |params| are provided +// in preference order, with the more preferred parameters at the beginning of +// the list. This function returns 1 on success and 0 on failure. +OPENSSL_EXPORT int SSL_set_token_binding_params(SSL *ssl, const uint8_t *params, + size_t len); + +// SSL_is_token_binding_negotiated returns 1 if Token Binding was negotiated +// on this connection and 0 otherwise. On a server, it is possible for this +// function to return 1 when the client's view of the connection is that Token +// Binding was not negotiated. This occurs when the server indicates a version +// of Token Binding less than the client's minimum version. +OPENSSL_EXPORT int SSL_is_token_binding_negotiated(const SSL *ssl); + +// SSL_get_negotiated_token_binding_param returns the TokenBindingKeyParameters +// enum value that was negotiated. It is only valid to call this function if +// SSL_is_token_binding_negotiated returned 1, otherwise this function returns +// an undefined value. +OPENSSL_EXPORT uint8_t SSL_get_negotiated_token_binding_param(const SSL *ssl); + + +// DTLS-SRTP. +// +// See RFC 5764. + +// srtp_protection_profile_st (aka |SRTP_PROTECTION_PROFILE|) is an SRTP +// profile for use with the use_srtp extension. +struct srtp_protection_profile_st { + const char *name; + unsigned long id; +} /* SRTP_PROTECTION_PROFILE */; + +DEFINE_CONST_STACK_OF(SRTP_PROTECTION_PROFILE) + +// SRTP_* define constants for SRTP profiles. +#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 +#define SRTP_AEAD_AES_128_GCM 0x0007 +#define SRTP_AEAD_AES_256_GCM 0x0008 + +// SSL_CTX_set_srtp_profiles enables SRTP for all SSL objects created from +// |ctx|. |profile| contains a colon-separated list of profile names. It returns +// one on success and zero on failure. +OPENSSL_EXPORT int SSL_CTX_set_srtp_profiles(SSL_CTX *ctx, + const char *profiles); + +// SSL_set_srtp_profiles enables SRTP for |ssl|. |profile| contains a +// colon-separated list of profile names. It returns one on success and zero on +// failure. +OPENSSL_EXPORT int SSL_set_srtp_profiles(SSL *ssl, const char *profiles); + +// SSL_get_srtp_profiles returns the SRTP profiles supported by |ssl|. +OPENSSL_EXPORT STACK_OF(SRTP_PROTECTION_PROFILE) *SSL_get_srtp_profiles( + SSL *ssl); + +// SSL_get_selected_srtp_profile returns the selected SRTP profile, or NULL if +// SRTP was not negotiated. +OPENSSL_EXPORT const SRTP_PROTECTION_PROFILE *SSL_get_selected_srtp_profile( + SSL *ssl); + + +// Pre-shared keys. +// +// Connections may be configured with PSK (Pre-Shared Key) cipher suites. These +// authenticate using out-of-band pre-shared keys rather than certificates. See +// RFC 4279. +// +// This implementation uses NUL-terminated C strings for identities and identity +// hints, so values with a NUL character are not supported. (RFC 4279 does not +// specify the format of an identity.) + +// PSK_MAX_IDENTITY_LEN is the maximum supported length of a PSK identity, +// excluding the NUL terminator. +#define PSK_MAX_IDENTITY_LEN 128 + +// PSK_MAX_PSK_LEN is the maximum supported length of a pre-shared key. +#define PSK_MAX_PSK_LEN 256 + +// SSL_CTX_set_psk_client_callback sets the callback to be called when PSK is +// negotiated on the client. This callback must be set to enable PSK cipher +// suites on the client. +// +// The callback is passed the identity hint in |hint| or NULL if none was +// provided. It should select a PSK identity and write the identity and the +// corresponding PSK to |identity| and |psk|, respectively. The identity is +// written as a NUL-terminated C string of length (excluding the NUL terminator) +// at most |max_identity_len|. The PSK's length must be at most |max_psk_len|. +// The callback returns the length of the PSK or 0 if no suitable identity was +// found. +OPENSSL_EXPORT void SSL_CTX_set_psk_client_callback( + SSL_CTX *ctx, unsigned (*cb)(SSL *ssl, const char *hint, char *identity, + unsigned max_identity_len, uint8_t *psk, + unsigned max_psk_len)); + +// SSL_set_psk_client_callback sets the callback to be called when PSK is +// negotiated on the client. This callback must be set to enable PSK cipher +// suites on the client. See also |SSL_CTX_set_psk_client_callback|. +OPENSSL_EXPORT void SSL_set_psk_client_callback( + SSL *ssl, unsigned (*cb)(SSL *ssl, const char *hint, char *identity, + unsigned max_identity_len, uint8_t *psk, + unsigned max_psk_len)); + +// SSL_CTX_set_psk_server_callback sets the callback to be called when PSK is +// negotiated on the server. This callback must be set to enable PSK cipher +// suites on the server. +// +// The callback is passed the identity in |identity|. It should write a PSK of +// length at most |max_psk_len| to |psk| and return the number of bytes written +// or zero if the PSK identity is unknown. +OPENSSL_EXPORT void SSL_CTX_set_psk_server_callback( + SSL_CTX *ctx, unsigned (*cb)(SSL *ssl, const char *identity, uint8_t *psk, + unsigned max_psk_len)); + +// SSL_set_psk_server_callback sets the callback to be called when PSK is +// negotiated on the server. This callback must be set to enable PSK cipher +// suites on the server. See also |SSL_CTX_set_psk_server_callback|. +OPENSSL_EXPORT void SSL_set_psk_server_callback( + SSL *ssl, unsigned (*cb)(SSL *ssl, const char *identity, uint8_t *psk, + unsigned max_psk_len)); + +// SSL_CTX_use_psk_identity_hint configures server connections to advertise an +// identity hint of |identity_hint|. It returns one on success and zero on +// error. +OPENSSL_EXPORT int SSL_CTX_use_psk_identity_hint(SSL_CTX *ctx, + const char *identity_hint); + +// SSL_use_psk_identity_hint configures server connections to advertise an +// identity hint of |identity_hint|. It returns one on success and zero on +// error. +OPENSSL_EXPORT int SSL_use_psk_identity_hint(SSL *ssl, + const char *identity_hint); + +// SSL_get_psk_identity_hint returns the PSK identity hint advertised for |ssl| +// or NULL if there is none. +OPENSSL_EXPORT const char *SSL_get_psk_identity_hint(const SSL *ssl); + +// SSL_get_psk_identity, after the handshake completes, returns the PSK identity +// that was negotiated by |ssl| or NULL if PSK was not used. +OPENSSL_EXPORT const char *SSL_get_psk_identity(const SSL *ssl); + + +// Dummy post-quantum padding. +// +// Dummy post-quantum padding invovles the client (and later server) sending +// useless, random-looking bytes in an extension in their ClientHello or +// ServerHello. These extensions are sized to simulate a post-quantum +// key-exchange and so enable measurement of the latency impact of the +// additional bandwidth. + +// SSL_set_dummy_pq_padding_size enables the sending of a dummy PQ padding +// extension and configures its size. This is only effective for a client: a +// server will echo an extension with one of equal length when we get to that +// phase of the experiment. It returns one for success and zero otherwise. +OPENSSL_EXPORT int SSL_set_dummy_pq_padding_size(SSL *ssl, size_t num_bytes); + +// SSL_dummy_pq_padding_used returns one if the server echoed a dummy PQ padding +// extension and zero otherwise. It may only be called on a client connection +// once the ServerHello has been processed, otherwise it'll return zero. +OPENSSL_EXPORT int SSL_dummy_pq_padding_used(SSL *ssl); + + +// QUIC Transport Parameters. +// +// draft-ietf-quic-tls defines a new TLS extension quic_transport_parameters +// used by QUIC for each endpoint to unilaterally declare its supported +// transport parameters. draft-ietf-quic-transport (section 7.4) defines the +// contents of that extension (a TransportParameters struct) and describes how +// to handle it and its semantic meaning. +// +// BoringSSL handles this extension as an opaque byte string. The caller is +// responsible for serializing and parsing it. + +// SSL_set_quic_transport_params configures |ssl| to send |params| (of length +// |params_len|) in the quic_transport_parameters extension in either the +// ClientHello or EncryptedExtensions handshake message. This extension will +// only be sent if the TLS version is at least 1.3, and for a server, only if +// the client sent the extension. The buffer pointed to by |params| only need be +// valid for the duration of the call to this function. This function returns 1 +// on success and 0 on failure. +OPENSSL_EXPORT int SSL_set_quic_transport_params(SSL *ssl, + const uint8_t *params, + size_t params_len); + +// SSL_get_peer_quic_transport_params provides the caller with the value of the +// quic_transport_parameters extension sent by the peer. A pointer to the buffer +// containing the TransportParameters will be put in |*out_params|, and its +// length in |*params_len|. This buffer will be valid for the lifetime of the +// |SSL|. If no params were received from the peer, |*out_params_len| will be 0. +OPENSSL_EXPORT void SSL_get_peer_quic_transport_params(const SSL *ssl, + const uint8_t **out_params, + size_t *out_params_len); + + +// Early data. +// +// WARNING: 0-RTT support in BoringSSL is currently experimental and not fully +// implemented. It may cause interoperability or security failures when used. +// +// Early data, or 0-RTT, is a feature in TLS 1.3 which allows clients to send +// data on the first flight during a resumption handshake. This can save a +// round-trip in some application protocols. +// +// WARNING: A 0-RTT handshake has different security properties from normal +// handshake, so it is off by default unless opted in. In particular, early data +// is replayable by a network attacker. Callers must account for this when +// sending or processing data before the handshake is confirmed. See +// draft-ietf-tls-tls13-18 for more information. +// +// As a server, if early data is accepted, |SSL_do_handshake| will complete as +// soon as the ClientHello is processed and server flight sent. |SSL_write| may +// be used to send half-RTT data. |SSL_read| will consume early data and +// transition to 1-RTT data as appropriate. Prior to the transition, +// |SSL_in_init| will report the handshake is still in progress. Callers may use +// it or |SSL_in_early_data| to defer or reject requests as needed. +// +// Early data as a client is more complex. If the offered session (see +// |SSL_set_session|) is 0-RTT-capable, the handshake will return after sending +// the ClientHello. The predicted peer certificates and ALPN protocol will be +// available via the usual APIs. |SSL_write| will write early data, up to the +// session's limit. Writes past this limit and |SSL_read| will complete the +// handshake before continuing. Callers may also call |SSL_do_handshake| again +// to complete the handshake sooner. +// +// If the server accepts early data, the handshake will succeed. |SSL_read| and +// |SSL_write| will then act as in a 1-RTT handshake. The peer certificates and +// ALPN protocol will be as predicted and need not be re-queried. +// +// If the server rejects early data, |SSL_do_handshake| (and thus |SSL_read| and +// |SSL_write|) will then fail with |SSL_get_error| returning +// |SSL_ERROR_EARLY_DATA_REJECTED|. The caller should treat this as a connection +// error and most likely perform a high-level retry. Note the server may still +// have processed the early data due to attacker replays. +// +// To then continue the handshake on the original connection, use +// |SSL_reset_early_data_reject|. The connection will then behave as one which +// had not yet completed the handshake. This allows a faster retry than making a +// fresh connection. |SSL_do_handshake| will complete the full handshake, +// possibly resulting in different peer certificates, ALPN protocol, and other +// properties. The caller must disregard any values from before the reset and +// query again. +// +// Finally, to implement the fallback described in draft-ietf-tls-tls13-18 +// appendix C.3, retry on a fresh connection without 0-RTT if the handshake +// fails with |SSL_R_WRONG_VERSION_ON_EARLY_DATA|. + +// SSL_CTX_set_early_data_enabled sets whether early data is allowed to be used +// with resumptions using |ctx|. +OPENSSL_EXPORT void SSL_CTX_set_early_data_enabled(SSL_CTX *ctx, int enabled); + +// SSL_set_early_data_enabled sets whether early data is allowed to be used +// with resumptions using |ssl|. See |SSL_CTX_set_early_data_enabled| for more +// information. +OPENSSL_EXPORT void SSL_set_early_data_enabled(SSL *ssl, int enabled); + +// SSL_in_early_data returns one if |ssl| has a pending handshake that has +// progressed enough to send or receive early data. Clients may call |SSL_write| +// to send early data, but |SSL_read| will complete the handshake before +// accepting application data. Servers may call |SSL_read| to read early data +// and |SSL_write| to send half-RTT data. +OPENSSL_EXPORT int SSL_in_early_data(const SSL *ssl); + +// SSL_early_data_accepted returns whether early data was accepted on the +// handshake performed by |ssl|. +OPENSSL_EXPORT int SSL_early_data_accepted(const SSL *ssl); + +// SSL_reset_early_data_reject resets |ssl| after an early data reject. All +// 0-RTT state is discarded, including any pending |SSL_write| calls. The caller +// should treat |ssl| as a logically fresh connection, usually by driving the +// handshake to completion using |SSL_do_handshake|. +// +// It is an error to call this function on an |SSL| object that is not signaling +// |SSL_ERROR_EARLY_DATA_REJECTED|. +OPENSSL_EXPORT void SSL_reset_early_data_reject(SSL *ssl); + +// SSL_export_early_keying_material behaves like |SSL_export_keying_material|, +// but it uses the early exporter. The operation will fail if |ssl| did not +// negotiate TLS 1.3 or 0-RTT. +OPENSSL_EXPORT int SSL_export_early_keying_material( + SSL *ssl, uint8_t *out, size_t out_len, const char *label, size_t label_len, + const uint8_t *context, size_t context_len); + + +// Alerts. +// +// TLS and SSL 3.0 use alerts to signal error conditions. Alerts have a type +// (warning or fatal) and description. OpenSSL internally handles fatal alerts +// with dedicated error codes (see |SSL_AD_REASON_OFFSET|). Except for +// close_notify, warning alerts are silently ignored and may only be surfaced +// with |SSL_CTX_set_info_callback|. + +// SSL_AD_REASON_OFFSET is the offset between error reasons and |SSL_AD_*| +// values. Any error code under |ERR_LIB_SSL| with an error reason above this +// value corresponds to an alert description. Consumers may add or subtract +// |SSL_AD_REASON_OFFSET| to convert between them. +// +// make_errors.go reserves error codes above 1000 for manually-assigned errors. +// This value must be kept in sync with reservedReasonCode in make_errors.h +#define SSL_AD_REASON_OFFSET 1000 + +// SSL_AD_* are alert descriptions for SSL 3.0 and TLS. +#define SSL_AD_CLOSE_NOTIFY SSL3_AD_CLOSE_NOTIFY +#define SSL_AD_UNEXPECTED_MESSAGE SSL3_AD_UNEXPECTED_MESSAGE +#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 +#define SSL_AD_DECOMPRESSION_FAILURE SSL3_AD_DECOMPRESSION_FAILURE +#define SSL_AD_HANDSHAKE_FAILURE SSL3_AD_HANDSHAKE_FAILURE +#define SSL_AD_NO_CERTIFICATE SSL3_AD_NO_CERTIFICATE // Not used in TLS +#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 +#define SSL_AD_ILLEGAL_PARAMETER SSL3_AD_ILLEGAL_PARAMETER +#define SSL_AD_UNKNOWN_CA TLS1_AD_UNKNOWN_CA +#define SSL_AD_ACCESS_DENIED TLS1_AD_ACCESS_DENIED +#define SSL_AD_DECODE_ERROR TLS1_AD_DECODE_ERROR +#define SSL_AD_DECRYPT_ERROR TLS1_AD_DECRYPT_ERROR +#define SSL_AD_EXPORT_RESTRICTION TLS1_AD_EXPORT_RESTRICTION +#define SSL_AD_PROTOCOL_VERSION TLS1_AD_PROTOCOL_VERSION +#define SSL_AD_INSUFFICIENT_SECURITY TLS1_AD_INSUFFICIENT_SECURITY +#define SSL_AD_INTERNAL_ERROR TLS1_AD_INTERNAL_ERROR +#define SSL_AD_INAPPROPRIATE_FALLBACK SSL3_AD_INAPPROPRIATE_FALLBACK +#define SSL_AD_USER_CANCELLED TLS1_AD_USER_CANCELLED +#define SSL_AD_NO_RENEGOTIATION TLS1_AD_NO_RENEGOTIATION +#define SSL_AD_MISSING_EXTENSION TLS1_AD_MISSING_EXTENSION +#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 +#define SSL_AD_UNKNOWN_PSK_IDENTITY TLS1_AD_UNKNOWN_PSK_IDENTITY +#define SSL_AD_CERTIFICATE_REQUIRED TLS1_AD_CERTIFICATE_REQUIRED + +// SSL_alert_type_string_long returns a string description of |value| as an +// alert type (warning or fatal). +OPENSSL_EXPORT const char *SSL_alert_type_string_long(int value); + +// SSL_alert_desc_string_long returns a string description of |value| as an +// alert description or "unknown" if unknown. +OPENSSL_EXPORT const char *SSL_alert_desc_string_long(int value); + +// SSL_send_fatal_alert sends a fatal alert over |ssl| of the specified type, +// which should be one of the |SSL_AD_*| constants. It returns one on success +// and <= 0 on error. The caller should pass the return value into +// |SSL_get_error| to determine how to proceed. Once this function has been +// called, future calls to |SSL_write| will fail. +// +// If retrying a failed operation due to |SSL_ERROR_WANT_WRITE|, subsequent +// calls must use the same |alert| parameter. +OPENSSL_EXPORT int SSL_send_fatal_alert(SSL *ssl, uint8_t alert); + + +// ex_data functions. +// +// See |ex_data.h| for details. + +OPENSSL_EXPORT int SSL_set_ex_data(SSL *ssl, int idx, void *data); +OPENSSL_EXPORT void *SSL_get_ex_data(const SSL *ssl, int idx); +OPENSSL_EXPORT int SSL_get_ex_new_index(long argl, void *argp, + CRYPTO_EX_unused *unused, + CRYPTO_EX_dup *dup_unused, + CRYPTO_EX_free *free_func); + +OPENSSL_EXPORT int SSL_SESSION_set_ex_data(SSL_SESSION *session, int idx, + void *data); +OPENSSL_EXPORT void *SSL_SESSION_get_ex_data(const SSL_SESSION *session, + int idx); +OPENSSL_EXPORT int SSL_SESSION_get_ex_new_index(long argl, void *argp, + CRYPTO_EX_unused *unused, + CRYPTO_EX_dup *dup_unused, + CRYPTO_EX_free *free_func); + +OPENSSL_EXPORT int SSL_CTX_set_ex_data(SSL_CTX *ctx, int idx, void *data); +OPENSSL_EXPORT void *SSL_CTX_get_ex_data(const SSL_CTX *ctx, int idx); +OPENSSL_EXPORT int SSL_CTX_get_ex_new_index(long argl, void *argp, + CRYPTO_EX_unused *unused, + CRYPTO_EX_dup *dup_unused, + CRYPTO_EX_free *free_func); + + +// Low-level record-layer state. + +// SSL_get_ivs sets |*out_iv_len| to the length of the IVs for the ciphers +// underlying |ssl| and sets |*out_read_iv| and |*out_write_iv| to point to the +// current IVs for the read and write directions. This is only meaningful for +// connections with implicit IVs (i.e. CBC mode with SSLv3 or TLS 1.0). +// +// It returns one on success or zero on error. +OPENSSL_EXPORT int SSL_get_ivs(const SSL *ssl, const uint8_t **out_read_iv, + const uint8_t **out_write_iv, + size_t *out_iv_len); + +// SSL_get_key_block_len returns the length of |ssl|'s key block. +OPENSSL_EXPORT size_t SSL_get_key_block_len(const SSL *ssl); + +// SSL_generate_key_block generates |out_len| bytes of key material for |ssl|'s +// current connection state. +OPENSSL_EXPORT int SSL_generate_key_block(const SSL *ssl, uint8_t *out, + size_t out_len); + +// SSL_get_read_sequence returns, in TLS, the expected sequence number of the +// next incoming record in the current epoch. In DTLS, it returns the maximum +// sequence number received in the current epoch and includes the epoch number +// in the two most significant bytes. +OPENSSL_EXPORT uint64_t SSL_get_read_sequence(const SSL *ssl); + +// SSL_get_write_sequence returns the sequence number of the next outgoing +// record in the current epoch. In DTLS, it includes the epoch number in the +// two most significant bytes. +OPENSSL_EXPORT uint64_t SSL_get_write_sequence(const SSL *ssl); + + +// Obscure functions. + +// SSL_get_structure_sizes returns the sizes of the SSL, SSL_CTX and +// SSL_SESSION structures so that a test can ensure that outside code agrees on +// these values. +OPENSSL_EXPORT void SSL_get_structure_sizes(size_t *ssl_size, + size_t *ssl_ctx_size, + size_t *ssl_session_size); + +// SSL_CTX_set_msg_callback installs |cb| as the message callback for |ctx|. +// This callback will be called when sending or receiving low-level record +// headers, complete handshake messages, ChangeCipherSpec, and alerts. +// |write_p| is one for outgoing messages and zero for incoming messages. +// +// For each record header, |cb| is called with |version| = 0 and |content_type| +// = |SSL3_RT_HEADER|. The |len| bytes from |buf| contain the header. Note that +// this does not include the record body. If the record is sealed, the length +// in the header is the length of the ciphertext. +// +// For each handshake message, ChangeCipherSpec, and alert, |version| is the +// protocol version and |content_type| is the corresponding record type. The +// |len| bytes from |buf| contain the handshake message, one-byte +// ChangeCipherSpec body, and two-byte alert, respectively. +// +// For a V2ClientHello, |version| is |SSL2_VERSION|, |content_type| is zero, and +// the |len| bytes from |buf| contain the V2ClientHello structure. +OPENSSL_EXPORT 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_set_msg_callback_arg sets the |arg| parameter of the message +// callback. +OPENSSL_EXPORT void SSL_CTX_set_msg_callback_arg(SSL_CTX *ctx, void *arg); + +// SSL_set_msg_callback installs |cb| as the message callback of |ssl|. See +// |SSL_CTX_set_msg_callback| for when this callback is called. +OPENSSL_EXPORT 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_set_msg_callback_arg sets the |arg| parameter of the message callback. +OPENSSL_EXPORT void SSL_set_msg_callback_arg(SSL *ssl, void *arg); + +// SSL_CTX_set_keylog_callback configures a callback to log key material. This +// is intended for debugging use with tools like Wireshark. The |cb| function +// should log |line| followed by a newline, synchronizing with any concurrent +// access to the log. +// +// The format is described in +// https://developer.mozilla.org/en-US/docs/Mozilla/Projects/NSS/Key_Log_Format. +OPENSSL_EXPORT void SSL_CTX_set_keylog_callback( + SSL_CTX *ctx, void (*cb)(const SSL *ssl, const char *line)); + +// SSL_CTX_get_keylog_callback returns the callback configured by +// |SSL_CTX_set_keylog_callback|. +OPENSSL_EXPORT void (*SSL_CTX_get_keylog_callback(const SSL_CTX *ctx))( + const SSL *ssl, const char *line); + +// SSL_CTX_set_current_time_cb configures a callback to retrieve the current +// time, which should be set in |*out_clock|. This can be used for testing +// purposes; for example, a callback can be configured that returns a time +// set explicitly by the test. The |ssl| pointer passed to |cb| is always null. +OPENSSL_EXPORT void SSL_CTX_set_current_time_cb( + SSL_CTX *ctx, void (*cb)(const SSL *ssl, struct timeval *out_clock)); + +enum ssl_renegotiate_mode_t { + ssl_renegotiate_never = 0, + ssl_renegotiate_once, + ssl_renegotiate_freely, + ssl_renegotiate_ignore, +}; + +// SSL_set_renegotiate_mode configures how |ssl|, a client, reacts to +// renegotiation attempts by a server. If |ssl| is a server, peer-initiated +// renegotiations are *always* rejected and this function does nothing. +// +// The renegotiation mode defaults to |ssl_renegotiate_never|, but may be set +// at any point in a connection's lifetime. Set it to |ssl_renegotiate_once| to +// allow one renegotiation, |ssl_renegotiate_freely| to allow all +// renegotiations or |ssl_renegotiate_ignore| to ignore HelloRequest messages. +// Note that ignoring HelloRequest messages may cause the connection to stall +// if the server waits for the renegotiation to complete. +// +// There is no support in BoringSSL for initiating renegotiations as a client +// or server. +OPENSSL_EXPORT void SSL_set_renegotiate_mode(SSL *ssl, + enum ssl_renegotiate_mode_t mode); + +// SSL_renegotiate_pending returns one if |ssl| is in the middle of a +// renegotiation. +OPENSSL_EXPORT int SSL_renegotiate_pending(SSL *ssl); + +// SSL_total_renegotiations returns the total number of renegotiation handshakes +// performed by |ssl|. This includes the pending renegotiation, if any. +OPENSSL_EXPORT int SSL_total_renegotiations(const SSL *ssl); + +enum tls13_variant_t { + tls13_default = 0, +}; + +// SSL_CTX_set_tls13_variant sets which variant of TLS 1.3 we negotiate. On the +// server, if |variant| is not |tls13_default|, all variants are enabled. On the +// client, only the configured variant is enabled. +OPENSSL_EXPORT void SSL_CTX_set_tls13_variant(SSL_CTX *ctx, + enum tls13_variant_t variant); + +// SSL_set_tls13_variant sets which variant of TLS 1.3 we negotiate. On the +// server, if |variant| is not |tls13_default|, all variants are enabled. On the +// client, only the configured variant is enabled. +OPENSSL_EXPORT void SSL_set_tls13_variant(SSL *ssl, + enum tls13_variant_t variant); + +// SSL_MAX_CERT_LIST_DEFAULT is the default maximum length, in bytes, of a peer +// certificate chain. +#define SSL_MAX_CERT_LIST_DEFAULT (1024 * 100) + +// SSL_CTX_get_max_cert_list returns the maximum length, in bytes, of a peer +// certificate chain accepted by |ctx|. +OPENSSL_EXPORT size_t SSL_CTX_get_max_cert_list(const SSL_CTX *ctx); + +// SSL_CTX_set_max_cert_list sets the maximum length, in bytes, of a peer +// certificate chain to |max_cert_list|. This affects how much memory may be +// consumed during the handshake. +OPENSSL_EXPORT void SSL_CTX_set_max_cert_list(SSL_CTX *ctx, + size_t max_cert_list); + +// SSL_get_max_cert_list returns the maximum length, in bytes, of a peer +// certificate chain accepted by |ssl|. +OPENSSL_EXPORT size_t SSL_get_max_cert_list(const SSL *ssl); + +// SSL_set_max_cert_list sets the maximum length, in bytes, of a peer +// certificate chain to |max_cert_list|. This affects how much memory may be +// consumed during the handshake. +OPENSSL_EXPORT void SSL_set_max_cert_list(SSL *ssl, size_t max_cert_list); + +// SSL_CTX_set_max_send_fragment sets the maximum length, in bytes, of records +// sent by |ctx|. Beyond this length, handshake messages and application data +// will be split into multiple records. It returns one on success or zero on +// error. +OPENSSL_EXPORT int SSL_CTX_set_max_send_fragment(SSL_CTX *ctx, + size_t max_send_fragment); + +// SSL_set_max_send_fragment sets the maximum length, in bytes, of records sent +// by |ssl|. Beyond this length, handshake messages and application data will +// be split into multiple records. It returns one on success or zero on +// error. +OPENSSL_EXPORT int SSL_set_max_send_fragment(SSL *ssl, + size_t max_send_fragment); + +// ssl_early_callback_ctx (aka |SSL_CLIENT_HELLO|) is passed to certain +// callbacks that are called very early on during the server handshake. At this +// point, much of the SSL* hasn't been filled out and only the ClientHello can +// be depended on. +typedef struct ssl_early_callback_ctx { + SSL *ssl; + const uint8_t *client_hello; + size_t client_hello_len; + uint16_t version; + const uint8_t *random; + size_t random_len; + const uint8_t *session_id; + size_t session_id_len; + const uint8_t *cipher_suites; + size_t cipher_suites_len; + const uint8_t *compression_methods; + size_t compression_methods_len; + const uint8_t *extensions; + size_t extensions_len; +} SSL_CLIENT_HELLO; + +// ssl_select_cert_result_t enumerates the possible results from selecting a +// certificate with |select_certificate_cb|. +enum ssl_select_cert_result_t { + // ssl_select_cert_success indicates that the certificate selection was + // successful. + ssl_select_cert_success = 1, + // ssl_select_cert_retry indicates that the operation could not be + // immediately completed and must be reattempted at a later point. + ssl_select_cert_retry = 0, + // ssl_select_cert_error indicates that a fatal error occured and the + // handshake should be terminated. + ssl_select_cert_error = -1, +}; + +// SSL_early_callback_ctx_extension_get searches the extensions in +// |client_hello| for an extension of the given type. If not found, it returns +// zero. Otherwise it sets |out_data| to point to the extension contents (not +// including the type and length bytes), sets |out_len| to the length of the +// extension contents and returns one. +OPENSSL_EXPORT int SSL_early_callback_ctx_extension_get( + const SSL_CLIENT_HELLO *client_hello, uint16_t extension_type, + const uint8_t **out_data, size_t *out_len); + +// SSL_CTX_set_select_certificate_cb sets a callback that is called before most +// ClientHello processing and before the decision whether to resume a session +// is made. The callback may inspect the ClientHello and configure the +// connection. See |ssl_select_cert_result_t| for details of the return values. +// +// In the case that a retry is indicated, |SSL_get_error| will return +// |SSL_ERROR_PENDING_CERTIFICATE| and the caller should arrange for the +// high-level operation on |ssl| to be retried at a later time, which will +// result in another call to |cb|. +// +// Note: The |SSL_CLIENT_HELLO| is only valid for the duration of the callback +// and is not valid while the handshake is paused. +OPENSSL_EXPORT void SSL_CTX_set_select_certificate_cb( + SSL_CTX *ctx, + enum ssl_select_cert_result_t (*cb)(const SSL_CLIENT_HELLO *)); + +// SSL_CTX_set_dos_protection_cb sets a callback that is called once the +// resumption decision for a ClientHello has been made. It can return one to +// allow the handshake to continue or zero to cause the handshake to abort. +OPENSSL_EXPORT void SSL_CTX_set_dos_protection_cb( + SSL_CTX *ctx, int (*cb)(const SSL_CLIENT_HELLO *)); + +// SSL_ST_* are possible values for |SSL_state| and the bitmasks that make them +// up. +#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_OK 0x03 +#define SSL_ST_RENEGOTIATE (0x04 | SSL_ST_INIT) + +// SSL_CB_* are possible values for the |type| parameter in the info +// callback and the bitmasks that make them up. +#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 +#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 + +// SSL_CTX_set_info_callback configures a callback to be run when various +// events occur during a connection's lifetime. The |type| argument determines +// the type of event and the meaning of the |value| argument. Callbacks must +// ignore unexpected |type| values. +// +// |SSL_CB_READ_ALERT| is signaled for each alert received, warning or fatal. +// The |value| argument is a 16-bit value where the alert level (either +// |SSL3_AL_WARNING| or |SSL3_AL_FATAL|) is in the most-significant eight bits +// and the alert type (one of |SSL_AD_*|) is in the least-significant eight. +// +// |SSL_CB_WRITE_ALERT| is signaled for each alert sent. The |value| argument +// is constructed as with |SSL_CB_READ_ALERT|. +// +// |SSL_CB_HANDSHAKE_START| is signaled when a handshake begins. The |value| +// argument is always one. +// +// |SSL_CB_HANDSHAKE_DONE| is signaled when a handshake completes successfully. +// The |value| argument is always one. If a handshake False Starts, this event +// may be used to determine when the Finished message is received. +// +// The following event types expose implementation details of the handshake +// state machine. Consuming them is deprecated. +// +// |SSL_CB_ACCEPT_LOOP| (respectively, |SSL_CB_CONNECT_LOOP|) is signaled when +// a server (respectively, client) handshake progresses. The |value| argument +// is always one. +// +// |SSL_CB_ACCEPT_EXIT| (respectively, |SSL_CB_CONNECT_EXIT|) is signaled when +// a server (respectively, client) handshake completes, fails, or is paused. +// The |value| argument is one if the handshake succeeded and <= 0 +// otherwise. +OPENSSL_EXPORT void SSL_CTX_set_info_callback( + SSL_CTX *ctx, void (*cb)(const SSL *ssl, int type, int value)); + +// SSL_CTX_get_info_callback returns the callback set by +// |SSL_CTX_set_info_callback|. +OPENSSL_EXPORT void (*SSL_CTX_get_info_callback(SSL_CTX *ctx))(const SSL *ssl, + int type, + int value); + +// SSL_set_info_callback configures a callback to be run at various events +// during a connection's lifetime. See |SSL_CTX_set_info_callback|. +OPENSSL_EXPORT void SSL_set_info_callback( + SSL *ssl, void (*cb)(const SSL *ssl, int type, int value)); + +// SSL_get_info_callback returns the callback set by |SSL_set_info_callback|. +OPENSSL_EXPORT void (*SSL_get_info_callback(const SSL *ssl))(const SSL *ssl, + int type, + int value); + +// SSL_state_string_long returns the current state of the handshake state +// machine as a string. This may be useful for debugging and logging. +OPENSSL_EXPORT const char *SSL_state_string_long(const SSL *ssl); + +#define SSL_SENT_SHUTDOWN 1 +#define SSL_RECEIVED_SHUTDOWN 2 + +// SSL_get_shutdown returns a bitmask with a subset of |SSL_SENT_SHUTDOWN| and +// |SSL_RECEIVED_SHUTDOWN| to query whether close_notify was sent or received, +// respectively. +OPENSSL_EXPORT int SSL_get_shutdown(const SSL *ssl); + +// SSL_get_peer_signature_algorithm returns the signature algorithm used by the +// peer. If not applicable, it returns zero. +OPENSSL_EXPORT uint16_t SSL_get_peer_signature_algorithm(const SSL *ssl); + +// SSL_get_client_random writes up to |max_out| bytes of the most recent +// handshake's client_random to |out| and returns the number of bytes written. +// If |max_out| is zero, it returns the size of the client_random. +OPENSSL_EXPORT size_t SSL_get_client_random(const SSL *ssl, uint8_t *out, + size_t max_out); + +// SSL_get_server_random writes up to |max_out| bytes of the most recent +// handshake's server_random to |out| and returns the number of bytes written. +// If |max_out| is zero, it returns the size of the server_random. +OPENSSL_EXPORT size_t SSL_get_server_random(const SSL *ssl, uint8_t *out, + size_t max_out); + +// SSL_get_pending_cipher returns the cipher suite for the current handshake or +// NULL if one has not been negotiated yet or there is no pending handshake. +OPENSSL_EXPORT const SSL_CIPHER *SSL_get_pending_cipher(const SSL *ssl); + +// SSL_set_retain_only_sha256_of_client_certs, on a server, sets whether only +// the SHA-256 hash of peer's certificate should be saved in memory and in the +// session. This can save memory, ticket size and session cache space. If +// enabled, |SSL_get_peer_certificate| will return NULL after the handshake +// completes. See the |peer_sha256| field of |SSL_SESSION| for the hash. +OPENSSL_EXPORT void SSL_set_retain_only_sha256_of_client_certs(SSL *ssl, + int enable); + +// SSL_CTX_set_retain_only_sha256_of_client_certs, on a server, sets whether +// only the SHA-256 hash of peer's certificate should be saved in memory and in +// the session. This can save memory, ticket size and session cache space. If +// enabled, |SSL_get_peer_certificate| will return NULL after the handshake +// completes. See the |peer_sha256| field of |SSL_SESSION| for the hash. +OPENSSL_EXPORT void SSL_CTX_set_retain_only_sha256_of_client_certs(SSL_CTX *ctx, + int enable); + +// SSL_CTX_set_grease_enabled configures whether sockets on |ctx| should enable +// GREASE. See draft-davidben-tls-grease-01. +OPENSSL_EXPORT void SSL_CTX_set_grease_enabled(SSL_CTX *ctx, int enabled); + +// SSL_max_seal_overhead returns the maximum overhead, in bytes, of sealing a +// record with |ssl|. +OPENSSL_EXPORT size_t SSL_max_seal_overhead(const SSL *ssl); + +// SSL_get_ticket_age_skew returns the difference, in seconds, between the +// client-sent ticket age and the server-computed value in TLS 1.3 server +// connections which resumed a session. +OPENSSL_EXPORT int32_t SSL_get_ticket_age_skew(const SSL *ssl); + +// SSL_CTX_set_false_start_allowed_without_alpn configures whether connections +// on |ctx| may use False Start (if |SSL_MODE_ENABLE_FALSE_START| is enabled) +// without negotiating ALPN. +OPENSSL_EXPORT void SSL_CTX_set_false_start_allowed_without_alpn(SSL_CTX *ctx, + int allowed); + +// SSL_is_draft_downgrade returns one if the TLS 1.3 anti-downgrade mechanism +// would have aborted |ssl|'s handshake and zero otherwise. +OPENSSL_EXPORT int SSL_is_draft_downgrade(const SSL *ssl); + + +// Deprecated functions. + +// SSL_library_init calls |CRYPTO_library_init| and returns one. +OPENSSL_EXPORT int SSL_library_init(void); + +// SSL_CIPHER_description writes a description of |cipher| into |buf| and +// returns |buf|. If |buf| is NULL, it returns a newly allocated string, to be +// freed with |OPENSSL_free|, or NULL on error. +// +// The description includes a trailing newline and has the form: +// AES128-SHA Kx=RSA Au=RSA Enc=AES(128) Mac=SHA1 +// +// Consider |SSL_CIPHER_standard_name| or |SSL_CIPHER_get_name| instead. +OPENSSL_EXPORT const char *SSL_CIPHER_description(const SSL_CIPHER *cipher, + char *buf, int len); + +// SSL_CIPHER_get_version returns the string "TLSv1/SSLv3". +OPENSSL_EXPORT const char *SSL_CIPHER_get_version(const SSL_CIPHER *cipher); + +// SSL_CIPHER_get_rfc_name returns a newly-allocated string containing the +// result of |SSL_CIPHER_standard_name| or NULL on error. The caller is +// responsible for calling |OPENSSL_free| on the result. +// +// Use |SSL_CIPHER_standard_name| instead. +OPENSSL_EXPORT char *SSL_CIPHER_get_rfc_name(const SSL_CIPHER *cipher); + +typedef void COMP_METHOD; +typedef struct ssl_comp_st SSL_COMP; + +// SSL_COMP_get_compression_methods returns NULL. +OPENSSL_EXPORT STACK_OF(SSL_COMP) *SSL_COMP_get_compression_methods(void); + +// SSL_COMP_add_compression_method returns one. +OPENSSL_EXPORT int SSL_COMP_add_compression_method(int id, COMP_METHOD *cm); + +// SSL_COMP_get_name returns NULL. +OPENSSL_EXPORT const char *SSL_COMP_get_name(const COMP_METHOD *comp); + +// SSL_COMP_get0_name returns the |name| member of |comp|. +OPENSSL_EXPORT const char *SSL_COMP_get0_name(const SSL_COMP *comp); + +// SSL_COMP_get_id returns the |id| member of |comp|. +OPENSSL_EXPORT int SSL_COMP_get_id(const SSL_COMP *comp); + +// SSL_COMP_free_compression_methods does nothing. +OPENSSL_EXPORT void SSL_COMP_free_compression_methods(void); + +// SSLv23_method calls |TLS_method|. +OPENSSL_EXPORT const SSL_METHOD *SSLv23_method(void); + +// These version-specific methods behave exactly like |TLS_method| and +// |DTLS_method| except they also call |SSL_CTX_set_min_proto_version| and +// |SSL_CTX_set_max_proto_version| to lock connections to that protocol +// version. +OPENSSL_EXPORT const SSL_METHOD *TLSv1_method(void); +OPENSSL_EXPORT const SSL_METHOD *TLSv1_1_method(void); +OPENSSL_EXPORT const SSL_METHOD *TLSv1_2_method(void); +OPENSSL_EXPORT const SSL_METHOD *DTLSv1_method(void); +OPENSSL_EXPORT const SSL_METHOD *DTLSv1_2_method(void); + +// These client- and server-specific methods call their corresponding generic +// methods. +OPENSSL_EXPORT const SSL_METHOD *TLS_server_method(void); +OPENSSL_EXPORT const SSL_METHOD *TLS_client_method(void); +OPENSSL_EXPORT const SSL_METHOD *SSLv23_server_method(void); +OPENSSL_EXPORT const SSL_METHOD *SSLv23_client_method(void); +OPENSSL_EXPORT const SSL_METHOD *TLSv1_server_method(void); +OPENSSL_EXPORT const SSL_METHOD *TLSv1_client_method(void); +OPENSSL_EXPORT const SSL_METHOD *TLSv1_1_server_method(void); +OPENSSL_EXPORT const SSL_METHOD *TLSv1_1_client_method(void); +OPENSSL_EXPORT const SSL_METHOD *TLSv1_2_server_method(void); +OPENSSL_EXPORT const SSL_METHOD *TLSv1_2_client_method(void); +OPENSSL_EXPORT const SSL_METHOD *DTLS_server_method(void); +OPENSSL_EXPORT const SSL_METHOD *DTLS_client_method(void); +OPENSSL_EXPORT const SSL_METHOD *DTLSv1_server_method(void); +OPENSSL_EXPORT const SSL_METHOD *DTLSv1_client_method(void); +OPENSSL_EXPORT const SSL_METHOD *DTLSv1_2_server_method(void); +OPENSSL_EXPORT const SSL_METHOD *DTLSv1_2_client_method(void); + +// SSL_clear resets |ssl| to allow another connection and returns one on success +// or zero on failure. It returns most configuration state but releases memory +// associated with the current connection. +// +// Free |ssl| and create a new one instead. +OPENSSL_EXPORT int SSL_clear(SSL *ssl); + +// SSL_CTX_set_tmp_rsa_callback does nothing. +OPENSSL_EXPORT void SSL_CTX_set_tmp_rsa_callback( + SSL_CTX *ctx, RSA *(*cb)(SSL *ssl, int is_export, int keylength)); + +// SSL_set_tmp_rsa_callback does nothing. +OPENSSL_EXPORT void SSL_set_tmp_rsa_callback(SSL *ssl, + RSA *(*cb)(SSL *ssl, int is_export, + int keylength)); + +// SSL_CTX_sess_connect returns zero. +OPENSSL_EXPORT int SSL_CTX_sess_connect(const SSL_CTX *ctx); + +// SSL_CTX_sess_connect_good returns zero. +OPENSSL_EXPORT int SSL_CTX_sess_connect_good(const SSL_CTX *ctx); + +// SSL_CTX_sess_connect_renegotiate returns zero. +OPENSSL_EXPORT int SSL_CTX_sess_connect_renegotiate(const SSL_CTX *ctx); + +// SSL_CTX_sess_accept returns zero. +OPENSSL_EXPORT int SSL_CTX_sess_accept(const SSL_CTX *ctx); + +// SSL_CTX_sess_accept_renegotiate returns zero. +OPENSSL_EXPORT int SSL_CTX_sess_accept_renegotiate(const SSL_CTX *ctx); + +// SSL_CTX_sess_accept_good returns zero. +OPENSSL_EXPORT int SSL_CTX_sess_accept_good(const SSL_CTX *ctx); + +// SSL_CTX_sess_hits returns zero. +OPENSSL_EXPORT int SSL_CTX_sess_hits(const SSL_CTX *ctx); + +// SSL_CTX_sess_cb_hits returns zero. +OPENSSL_EXPORT int SSL_CTX_sess_cb_hits(const SSL_CTX *ctx); + +// SSL_CTX_sess_misses returns zero. +OPENSSL_EXPORT int SSL_CTX_sess_misses(const SSL_CTX *ctx); + +// SSL_CTX_sess_timeouts returns zero. +OPENSSL_EXPORT int SSL_CTX_sess_timeouts(const SSL_CTX *ctx); + +// SSL_CTX_sess_cache_full returns zero. +OPENSSL_EXPORT int SSL_CTX_sess_cache_full(const SSL_CTX *ctx); + +// SSL_cutthrough_complete calls |SSL_in_false_start|. +OPENSSL_EXPORT int SSL_cutthrough_complete(const SSL *ssl); + +// SSL_num_renegotiations calls |SSL_total_renegotiations|. +OPENSSL_EXPORT int SSL_num_renegotiations(const SSL *ssl); + +// SSL_CTX_need_tmp_RSA returns zero. +OPENSSL_EXPORT int SSL_CTX_need_tmp_RSA(const SSL_CTX *ctx); + +// SSL_need_tmp_RSA returns zero. +OPENSSL_EXPORT int SSL_need_tmp_RSA(const SSL *ssl); + +// SSL_CTX_set_tmp_rsa returns one. +OPENSSL_EXPORT int SSL_CTX_set_tmp_rsa(SSL_CTX *ctx, const RSA *rsa); + +// SSL_set_tmp_rsa returns one. +OPENSSL_EXPORT int SSL_set_tmp_rsa(SSL *ssl, const RSA *rsa); + +// SSL_CTX_get_read_ahead returns zero. +OPENSSL_EXPORT int SSL_CTX_get_read_ahead(const SSL_CTX *ctx); + +// SSL_CTX_set_read_ahead does nothing. +OPENSSL_EXPORT void SSL_CTX_set_read_ahead(SSL_CTX *ctx, int yes); + +// SSL_get_read_ahead returns zero. +OPENSSL_EXPORT int SSL_get_read_ahead(const SSL *ssl); + +// SSL_set_read_ahead does nothing. +OPENSSL_EXPORT void SSL_set_read_ahead(SSL *ssl, int yes); + +// SSL_renegotiate put an error on the error queue and returns zero. +OPENSSL_EXPORT int SSL_renegotiate(SSL *ssl); + +// SSL_set_state does nothing. +OPENSSL_EXPORT void SSL_set_state(SSL *ssl, int state); + +// SSL_get_shared_ciphers writes an empty string to |buf| and returns a +// pointer to |buf|, or NULL if |len| is less than or equal to zero. +OPENSSL_EXPORT char *SSL_get_shared_ciphers(const SSL *ssl, char *buf, int len); + +// SSL_MODE_HANDSHAKE_CUTTHROUGH is the same as SSL_MODE_ENABLE_FALSE_START. +#define SSL_MODE_HANDSHAKE_CUTTHROUGH SSL_MODE_ENABLE_FALSE_START + +// i2d_SSL_SESSION serializes |in| to the bytes pointed to by |*pp|. On success, +// it returns the number of bytes written and advances |*pp| by that many bytes. +// On failure, it returns -1. If |pp| is NULL, no bytes are written and only the +// length is returned. +// +// Use |SSL_SESSION_to_bytes| instead. +OPENSSL_EXPORT int i2d_SSL_SESSION(SSL_SESSION *in, uint8_t **pp); + +// d2i_SSL_SESSION parses a serialized session from the |length| bytes pointed +// to by |*pp|. It returns the new |SSL_SESSION| and advances |*pp| by the +// number of bytes consumed on success and NULL on failure. The caller takes +// ownership of the new session and must call |SSL_SESSION_free| when done. +// +// If |a| is non-NULL, |*a| is released and set the new |SSL_SESSION|. +// +// Use |SSL_SESSION_from_bytes| instead. +OPENSSL_EXPORT SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const uint8_t **pp, + long length); + +// i2d_SSL_SESSION_bio serializes |session| and writes the result to |bio|. It +// returns the number of bytes written on success and <= 0 on error. +OPENSSL_EXPORT int i2d_SSL_SESSION_bio(BIO *bio, const SSL_SESSION *session); + +// d2i_SSL_SESSION_bio reads a serialized |SSL_SESSION| from |bio| and returns a +// newly-allocated |SSL_SESSION| or NULL on error. If |out| is not NULL, it also +// frees |*out| and sets |*out| to the new |SSL_SESSION|. +OPENSSL_EXPORT SSL_SESSION *d2i_SSL_SESSION_bio(BIO *bio, SSL_SESSION **out); + +// ERR_load_SSL_strings does nothing. +OPENSSL_EXPORT void ERR_load_SSL_strings(void); + +// SSL_load_error_strings does nothing. +OPENSSL_EXPORT void SSL_load_error_strings(void); + +// SSL_CTX_set_tlsext_use_srtp calls |SSL_CTX_set_srtp_profiles|. It returns +// zero on success and one on failure. +// +// WARNING: this function is dangerous because it breaks the usual return value +// convention. Use |SSL_CTX_set_srtp_profiles| instead. +OPENSSL_EXPORT int SSL_CTX_set_tlsext_use_srtp(SSL_CTX *ctx, + const char *profiles); + +// SSL_set_tlsext_use_srtp calls |SSL_set_srtp_profiles|. It returns zero on +// success and one on failure. +// +// WARNING: this function is dangerous because it breaks the usual return value +// convention. Use |SSL_set_srtp_profiles| instead. +OPENSSL_EXPORT int SSL_set_tlsext_use_srtp(SSL *ssl, const char *profiles); + +// SSL_get_current_compression returns NULL. +OPENSSL_EXPORT const COMP_METHOD *SSL_get_current_compression(SSL *ssl); + +// SSL_get_current_expansion returns NULL. +OPENSSL_EXPORT const COMP_METHOD *SSL_get_current_expansion(SSL *ssl); + +// SSL_get_server_tmp_key returns zero. +OPENSSL_EXPORT int *SSL_get_server_tmp_key(SSL *ssl, EVP_PKEY **out_key); + +// SSL_CTX_set_tmp_dh returns 1. +OPENSSL_EXPORT int SSL_CTX_set_tmp_dh(SSL_CTX *ctx, const DH *dh); + +// SSL_set_tmp_dh returns 1. +OPENSSL_EXPORT int SSL_set_tmp_dh(SSL *ssl, const DH *dh); + +// SSL_CTX_set_tmp_dh_callback does nothing. +OPENSSL_EXPORT void SSL_CTX_set_tmp_dh_callback( + SSL_CTX *ctx, DH *(*cb)(SSL *ssl, int is_export, int keylength)); + +// SSL_set_tmp_dh_callback does nothing. +OPENSSL_EXPORT void SSL_set_tmp_dh_callback(SSL *ssl, + DH *(*cb)(SSL *ssl, int is_export, + int keylength)); + + +#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))) + +#define OpenSSL_add_ssl_algorithms() SSL_library_init() +#define SSLeay_add_ssl_algorithms() SSL_library_init() + +#define SSL_get_cipher(ssl) SSL_CIPHER_get_name(SSL_get_current_cipher(ssl)) +#define SSL_get_cipher_bits(ssl, out_alg_bits) \ + SSL_CIPHER_get_bits(SSL_get_current_cipher(ssl), out_alg_bits) +#define SSL_get_cipher_version(ssl) \ + SSL_CIPHER_get_version(SSL_get_current_cipher(ssl)) +#define SSL_get_cipher_name(ssl) \ + SSL_CIPHER_get_name(SSL_get_current_cipher(ssl)) +#define SSL_get_time(session) SSL_SESSION_get_time(session) +#define SSL_set_time(session, time) SSL_SESSION_set_time((session), (time)) +#define SSL_get_timeout(session) SSL_SESSION_get_timeout(session) +#define SSL_set_timeout(session, timeout) \ + SSL_SESSION_set_timeout((session), (timeout)) + +struct ssl_comp_st { + int id; + const char *name; + char *method; +}; + +DEFINE_STACK_OF(SSL_COMP) + +// The following flags do nothing and are included only to make it easier to +// compile code with BoringSSL. +#define SSL_MODE_AUTO_RETRY 0 +#define SSL_MODE_RELEASE_BUFFERS 0 +#define SSL_MODE_SEND_CLIENTHELLO_TIME 0 +#define SSL_MODE_SEND_SERVERHELLO_TIME 0 +#define SSL_OP_ALL 0 +#define SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION 0 +#define SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS 0 +#define SSL_OP_EPHEMERAL_RSA 0 +#define SSL_OP_LEGACY_SERVER_CONNECT 0 +#define SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER 0 +#define SSL_OP_MICROSOFT_SESS_ID_BUG 0 +#define SSL_OP_MSIE_SSLV2_RSA_PADDING 0 +#define SSL_OP_NETSCAPE_CA_DN_BUG 0 +#define SSL_OP_NETSCAPE_CHALLENGE_BUG 0 +#define SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG 0 +#define SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG 0 +#define SSL_OP_NO_COMPRESSION 0 +#define SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION 0 +#define SSL_OP_NO_SSLv2 0 +#define SSL_OP_PKCS1_CHECK_1 0 +#define SSL_OP_PKCS1_CHECK_2 0 +#define SSL_OP_SINGLE_DH_USE 0 +#define SSL_OP_SINGLE_ECDH_USE 0 +#define SSL_OP_SSLEAY_080_CLIENT_DH_BUG 0 +#define SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG 0 +#define SSL_OP_TLS_BLOCK_PADDING_BUG 0 +#define SSL_OP_TLS_D5_BUG 0 +#define SSL_OP_TLS_ROLLBACK_BUG 0 +#define SSL_VERIFY_CLIENT_ONCE 0 + +// SSL_cache_hit calls |SSL_session_reused|. +OPENSSL_EXPORT int SSL_cache_hit(SSL *ssl); + +// SSL_get_default_timeout returns |SSL_DEFAULT_SESSION_TIMEOUT|. +OPENSSL_EXPORT long SSL_get_default_timeout(const SSL *ssl); + +// SSL_get_version returns a string describing the TLS version used by |ssl|. +// For example, "TLSv1.2" or "SSLv3". +OPENSSL_EXPORT const char *SSL_get_version(const SSL *ssl); + +// SSL_get_cipher_list returns the name of the |n|th cipher in the output of +// |SSL_get_ciphers| or NULL if out of range. Use |SSL_get_ciphers| instead. +OPENSSL_EXPORT const char *SSL_get_cipher_list(const SSL *ssl, int n); + +// SSL_CTX_set_client_cert_cb sets a callback which is called on the client if +// the server requests a client certificate and none is configured. On success, +// the callback should return one and set |*out_x509| to |*out_pkey| to a leaf +// certificate and private key, respectively, passing ownership. It should +// return zero to send no certificate and -1 to fail or pause the handshake. If +// the handshake is paused, |SSL_get_error| will return +// |SSL_ERROR_WANT_X509_LOOKUP|. +// +// The callback may call |SSL_get0_certificate_types| and +// |SSL_get_client_CA_list| for information on the server's certificate request. +// +// Use |SSL_CTX_set_cert_cb| instead. Configuring intermediate certificates with +// this function is confusing. This callback may not be registered concurrently +// with |SSL_CTX_set_cert_cb| or |SSL_set_cert_cb|. +OPENSSL_EXPORT void SSL_CTX_set_client_cert_cb( + SSL_CTX *ctx, int (*cb)(SSL *ssl, X509 **out_x509, EVP_PKEY **out_pkey)); + +#define SSL_NOTHING 1 +#define SSL_WRITING 2 +#define SSL_READING 3 +#define SSL_X509_LOOKUP 4 +#define SSL_CHANNEL_ID_LOOKUP 5 +#define SSL_PENDING_SESSION 7 +#define SSL_CERTIFICATE_SELECTION_PENDING 8 +#define SSL_PRIVATE_KEY_OPERATION 9 +#define SSL_PENDING_TICKET 10 +#define SSL_EARLY_DATA_REJECTED 11 +#define SSL_CERTIFICATE_VERIFY 12 +#define SSL_HANDOFF 13 + +// SSL_want returns one of the above values to determine what the most recent +// operation on |ssl| was blocked on. Use |SSL_get_error| instead. +OPENSSL_EXPORT int SSL_want(const SSL *ssl); + +#define SSL_want_read(ssl) (SSL_want(ssl) == SSL_READING) +#define SSL_want_write(ssl) (SSL_want(ssl) == SSL_WRITING) + + // SSL_get_finished writes up to |count| bytes of the Finished message sent by + // |ssl| to |buf|. It returns the total untruncated length or zero if none has + // been sent yet. At SSL 3.0 or TLS 1.3 and later, it returns zero. + // + // Use |SSL_get_tls_unique| instead. +OPENSSL_EXPORT size_t SSL_get_finished(const SSL *ssl, void *buf, size_t count); + + // SSL_get_peer_finished writes up to |count| bytes of the Finished message + // received from |ssl|'s peer to |buf|. It returns the total untruncated length + // or zero if none has been received yet. At SSL 3.0 or TLS 1.3 and later, it + // returns zero. + // + // Use |SSL_get_tls_unique| instead. +OPENSSL_EXPORT size_t SSL_get_peer_finished(const SSL *ssl, void *buf, + size_t count); + +// SSL_alert_type_string returns "!". Use |SSL_alert_type_string_long| +// instead. +OPENSSL_EXPORT const char *SSL_alert_type_string(int value); + +// SSL_alert_desc_string returns "!!". Use |SSL_alert_desc_string_long| +// instead. +OPENSSL_EXPORT const char *SSL_alert_desc_string(int value); + +// SSL_state_string returns "!!!!!!". Use |SSL_state_string_long| for a more +// intelligible string. +OPENSSL_EXPORT const char *SSL_state_string(const SSL *ssl); + +// SSL_TXT_* expand to strings. +#define SSL_TXT_MEDIUM "MEDIUM" +#define SSL_TXT_HIGH "HIGH" +#define SSL_TXT_FIPS "FIPS" +#define SSL_TXT_kRSA "kRSA" +#define SSL_TXT_kDHE "kDHE" +#define SSL_TXT_kEDH "kEDH" +#define SSL_TXT_kECDHE "kECDHE" +#define SSL_TXT_kEECDH "kEECDH" +#define SSL_TXT_kPSK "kPSK" +#define SSL_TXT_aRSA "aRSA" +#define SSL_TXT_aECDSA "aECDSA" +#define SSL_TXT_aPSK "aPSK" +#define SSL_TXT_DH "DH" +#define SSL_TXT_DHE "DHE" +#define SSL_TXT_EDH "EDH" +#define SSL_TXT_RSA "RSA" +#define SSL_TXT_ECDH "ECDH" +#define SSL_TXT_ECDHE "ECDHE" +#define SSL_TXT_EECDH "EECDH" +#define SSL_TXT_ECDSA "ECDSA" +#define SSL_TXT_PSK "PSK" +#define SSL_TXT_3DES "3DES" +#define SSL_TXT_RC4 "RC4" +#define SSL_TXT_AES128 "AES128" +#define SSL_TXT_AES256 "AES256" +#define SSL_TXT_AES "AES" +#define SSL_TXT_AES_GCM "AESGCM" +#define SSL_TXT_CHACHA20 "CHACHA20" +#define SSL_TXT_MD5 "MD5" +#define SSL_TXT_SHA1 "SHA1" +#define SSL_TXT_SHA "SHA" +#define SSL_TXT_SHA256 "SHA256" +#define SSL_TXT_SHA384 "SHA384" +#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_TLSV1_3 "TLSv1.3" +#define SSL_TXT_ALL "ALL" +#define SSL_TXT_CMPDEF "COMPLEMENTOFDEFAULT" + +typedef struct ssl_conf_ctx_st SSL_CONF_CTX; + +// SSL_state returns |SSL_ST_INIT| if a handshake is in progress and |SSL_ST_OK| +// otherwise. +// +// Use |SSL_is_init| instead. +OPENSSL_EXPORT int SSL_state(const SSL *ssl); + +#define SSL_get_state(ssl) SSL_state(ssl) + +// SSL_set_shutdown causes |ssl| to behave as if the shutdown bitmask (see +// |SSL_get_shutdown|) were |mode|. This may be used to skip sending or +// receiving close_notify in |SSL_shutdown| by causing the implementation to +// believe the events already happened. +// +// It is an error to use |SSL_set_shutdown| to unset a bit that has already been +// set. Doing so will trigger an |assert| in debug builds and otherwise be +// ignored. +// +// Use |SSL_CTX_set_quiet_shutdown| instead. +OPENSSL_EXPORT void SSL_set_shutdown(SSL *ssl, int mode); + +// SSL_CTX_set_tmp_ecdh calls |SSL_CTX_set1_curves| with a one-element list +// containing |ec_key|'s curve. +OPENSSL_EXPORT int SSL_CTX_set_tmp_ecdh(SSL_CTX *ctx, const EC_KEY *ec_key); + +// SSL_set_tmp_ecdh calls |SSL_set1_curves| with a one-element list containing +// |ec_key|'s curve. +OPENSSL_EXPORT int SSL_set_tmp_ecdh(SSL *ssl, const EC_KEY *ec_key); + +// SSL_add_dir_cert_subjects_to_stack lists files in directory |dir|. It calls +// |SSL_add_file_cert_subjects_to_stack| on each file and returns one on success +// or zero on error. This function is only available from the libdecrepit +// library. +OPENSSL_EXPORT int SSL_add_dir_cert_subjects_to_stack(STACK_OF(X509_NAME) *out, + const char *dir); + +// SSL_set_verify_result calls |abort| unless |result| is |X509_V_OK|. +// +// TODO(davidben): Remove this function once it has been removed from +// netty-tcnative. +OPENSSL_EXPORT void SSL_set_verify_result(SSL *ssl, long result); + +// SSL_CTX_enable_tls_channel_id calls |SSL_CTX_set_tls_channel_id_enabled|. +OPENSSL_EXPORT int SSL_CTX_enable_tls_channel_id(SSL_CTX *ctx); + +// SSL_enable_tls_channel_id calls |SSL_set_tls_channel_id_enabled|. +OPENSSL_EXPORT int SSL_enable_tls_channel_id(SSL *ssl); + +// BIO_f_ssl returns a |BIO_METHOD| that can wrap an |SSL*| in a |BIO*|. Note +// that this has quite different behaviour from the version in OpenSSL (notably +// that it doesn't try to auto renegotiate). +// +// IMPORTANT: if you are not curl, don't use this. +OPENSSL_EXPORT const BIO_METHOD *BIO_f_ssl(void); + +// BIO_set_ssl sets |ssl| as the underlying connection for |bio|, which must +// have been created using |BIO_f_ssl|. If |take_owership| is true, |bio| will +// call |SSL_free| on |ssl| when closed. It returns one on success or something +// other than one on error. +OPENSSL_EXPORT long BIO_set_ssl(BIO *bio, SSL *ssl, int take_owership); + +// SSL_CTX_set_ecdh_auto returns one. +#define SSL_CTX_set_ecdh_auto(ctx, onoff) 1 + +// SSL_set_ecdh_auto returns one. +#define SSL_set_ecdh_auto(ssl, onoff) 1 + +// SSL_get_session returns a non-owning pointer to |ssl|'s session. For +// historical reasons, which session it returns depends on |ssl|'s state. +// +// Prior to the start of the initial handshake, it returns the session the +// caller set with |SSL_set_session|. After the initial handshake has finished +// and if no additional handshakes are in progress, it returns the currently +// active session. Its behavior is undefined while a handshake is in progress. +// +// If trying to add new sessions to an external session cache, use +// |SSL_CTX_sess_set_new_cb| instead. In particular, using the callback is +// required as of TLS 1.3. For compatibility, this function will return an +// unresumable session which may be cached, but will never be resumed. +// +// If querying properties of the connection, use APIs on the |SSL| object. +OPENSSL_EXPORT SSL_SESSION *SSL_get_session(const SSL *ssl); + +// SSL_get0_session is an alias for |SSL_get_session|. +#define SSL_get0_session SSL_get_session + +// SSL_get1_session acts like |SSL_get_session| but returns a new reference to +// the session. +OPENSSL_EXPORT SSL_SESSION *SSL_get1_session(SSL *ssl); + +#define OPENSSL_INIT_NO_LOAD_SSL_STRINGS 0 +#define OPENSSL_INIT_LOAD_SSL_STRINGS 0 +#define OPENSSL_INIT_SSL_DEFAULT 0 + +// OPENSSL_init_ssl calls |CRYPTO_library_init| and returns one. +OPENSSL_EXPORT int OPENSSL_init_ssl(uint64_t opts, + const OPENSSL_INIT_SETTINGS *settings); + +#if !defined(BORINGSSL_NO_CXX) +// SSL_CTX_sess_set_get_cb is a legacy C++ overload of |SSL_CTX_sess_set_get_cb| +// which supports the old callback signature. +// +// TODO(davidben): Remove this once Node is compatible with OpenSSL 1.1.0. +extern "C++" OPENSSL_EXPORT void SSL_CTX_sess_set_get_cb( + SSL_CTX *ctx, SSL_SESSION *(*get_session_cb)(SSL *ssl, uint8_t *id, + int id_len, int *out_copy)); +#endif + + +// Private structures. +// +// This structures are exposed for historical reasons, but access to them is +// deprecated. + +// TODO(davidben): Remove this forward declaration when |SSL_SESSION| is opaque. +typedef struct ssl_x509_method_st SSL_X509_METHOD; + +#define SSL_MAX_SSL_SESSION_ID_LENGTH 32 +#define SSL_MAX_SID_CTX_LENGTH 32 +#define SSL_MAX_MASTER_KEY_LENGTH 48 + +struct ssl_session_st { + CRYPTO_refcount_t references; + uint16_t ssl_version; // what ssl version session info is being kept in here? + + // group_id is the ID of the ECDH group used to establish this session or zero + // if not applicable or unknown. + uint16_t group_id; + + // peer_signature_algorithm is the signature algorithm used to authenticate + // the peer, or zero if not applicable or unknown. + uint16_t peer_signature_algorithm; + + // master_key, in TLS 1.2 and below, is the master secret associated with the + // session. In TLS 1.3 and up, it is the resumption secret. + int master_key_length; + uint8_t master_key[SSL_MAX_MASTER_KEY_LENGTH]; + + // session_id - valid? + unsigned int session_id_length; + uint8_t 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 + uint8_t sid_ctx_length; + uint8_t sid_ctx[SSL_MAX_SID_CTX_LENGTH]; + + char *psk_identity; + + // certs contains the certificate chain from the peer, starting with the leaf + // certificate. + STACK_OF(CRYPTO_BUFFER) *certs; + + const SSL_X509_METHOD *x509_method; + + // x509_peer is the peer's certificate. + X509 *x509_peer; + + // x509_chain is the certificate chain sent by the peer. NOTE: for historical + // reasons, when a client (so the peer is a server), the chain includes + // |peer|, but when a server it does not. + STACK_OF(X509) *x509_chain; + + // x509_chain_without_leaf is a lazily constructed copy of |x509_chain| that + // omits the leaf certificate. This exists because OpenSSL, historically, + // didn't include the leaf certificate in the chain for a server, but did for + // a client. The |x509_chain| always includes it and, if an API call requires + // a chain without, it is stored here. + STACK_OF(X509) *x509_chain_without_leaf; + + // verify_result is the result of certificate verification in the case of + // non-fatal certificate errors. + long verify_result; + + // timeout is the lifetime of the session in seconds, measured from |time|. + // This is renewable up to |auth_timeout|. + uint32_t timeout; + + // auth_timeout is the non-renewable lifetime of the session in seconds, + // measured from |time|. + uint32_t auth_timeout; + + // time is the time the session was issued, measured in seconds from the UNIX + // epoch. + uint64_t time; + + const SSL_CIPHER *cipher; + + 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. + SSL_SESSION *prev, *next; + + // RFC4507 info + uint8_t *tlsext_tick; // Session ticket + size_t tlsext_ticklen; // Session ticket length + + CRYPTO_BUFFER *signed_cert_timestamp_list; + + // The OCSP response that came with the session. + CRYPTO_BUFFER *ocsp_response; + + // peer_sha256 contains the SHA-256 hash of the peer's certificate if + // |peer_sha256_valid| is true. + uint8_t peer_sha256[SHA256_DIGEST_LENGTH]; + + // original_handshake_hash contains the handshake hash (either SHA-1+MD5 or + // SHA-2, depending on TLS version) for the original, full handshake that + // created a session. This is used by Channel IDs during resumption. + uint8_t original_handshake_hash[EVP_MAX_MD_SIZE]; + uint8_t original_handshake_hash_len; + + uint32_t tlsext_tick_lifetime_hint; // Session lifetime hint in seconds + + uint32_t ticket_age_add; + + // ticket_max_early_data is the maximum amount of data allowed to be sent as + // early data. If zero, 0-RTT is disallowed. + uint32_t ticket_max_early_data; + + // early_alpn is the ALPN protocol from the initial handshake. This is only + // stored for TLS 1.3 and above in order to enforce ALPN matching for 0-RTT + // resumptions. + uint8_t *early_alpn; + size_t early_alpn_len; + + // extended_master_secret is true if the master secret in this session was + // generated using EMS and thus isn't vulnerable to the Triple Handshake + // attack. + unsigned extended_master_secret:1; + + // peer_sha256_valid is non-zero if |peer_sha256| is valid. + unsigned peer_sha256_valid:1; // Non-zero if peer_sha256 is valid + + // not_resumable is used to indicate that session resumption is disallowed. + unsigned not_resumable:1; + + // ticket_age_add_valid is non-zero if |ticket_age_add| is valid. + unsigned ticket_age_add_valid:1; + + // is_server is true if this session was created by a server. + unsigned is_server:1; +}; + + +// Nodejs compatibility section (hidden). +// +// These defines exist for node.js, with the hope that we can eliminate the +// need for them over time. +#define SSLerr(function, reason) \ + ERR_put_error(ERR_LIB_SSL, 0, reason, __FILE__, __LINE__) + + +// Preprocessor compatibility section (hidden). +// +// Historically, a number of APIs were implemented in OpenSSL as macros and +// constants to 'ctrl' functions. To avoid breaking #ifdefs in consumers, this +// section defines a number of legacy macros. +// +// Although using either the CTRL values or their wrapper macros in #ifdefs is +// still supported, the CTRL values may not be passed to |SSL_ctrl| and +// |SSL_CTX_ctrl|. Call the functions (previously wrapper macros) instead. +// +// See PORTING.md in the BoringSSL source tree for a table of corresponding +// functions. +// https://boringssl.googlesource.com/boringssl/+/master/PORTING.md#Replacements-for-values + +#define DTLS_CTRL_GET_TIMEOUT doesnt_exist +#define DTLS_CTRL_HANDLE_TIMEOUT doesnt_exist +#define SSL_CTRL_CHAIN doesnt_exist +#define SSL_CTRL_CHAIN_CERT doesnt_exist +#define SSL_CTRL_CHANNEL_ID doesnt_exist +#define SSL_CTRL_CLEAR_EXTRA_CHAIN_CERTS doesnt_exist +#define SSL_CTRL_CLEAR_MODE doesnt_exist +#define SSL_CTRL_CLEAR_OPTIONS doesnt_exist +#define SSL_CTRL_EXTRA_CHAIN_CERT doesnt_exist +#define SSL_CTRL_GET_CHAIN_CERTS doesnt_exist +#define SSL_CTRL_GET_CHANNEL_ID doesnt_exist +#define SSL_CTRL_GET_CLIENT_CERT_TYPES doesnt_exist +#define SSL_CTRL_GET_EXTRA_CHAIN_CERTS doesnt_exist +#define SSL_CTRL_GET_MAX_CERT_LIST doesnt_exist +#define SSL_CTRL_GET_NUM_RENEGOTIATIONS doesnt_exist +#define SSL_CTRL_GET_READ_AHEAD doesnt_exist +#define SSL_CTRL_GET_RI_SUPPORT doesnt_exist +#define SSL_CTRL_GET_SESSION_REUSED doesnt_exist +#define SSL_CTRL_GET_SESS_CACHE_MODE doesnt_exist +#define SSL_CTRL_GET_SESS_CACHE_SIZE doesnt_exist +#define SSL_CTRL_GET_TLSEXT_TICKET_KEYS doesnt_exist +#define SSL_CTRL_GET_TOTAL_RENEGOTIATIONS doesnt_exist +#define SSL_CTRL_MODE doesnt_exist +#define SSL_CTRL_NEED_TMP_RSA doesnt_exist +#define SSL_CTRL_OPTIONS doesnt_exist +#define SSL_CTRL_SESS_NUMBER doesnt_exist +#define SSL_CTRL_SET_CURVES doesnt_exist +#define SSL_CTRL_SET_CURVES_LIST doesnt_exist +#define SSL_CTRL_SET_ECDH_AUTO doesnt_exist +#define SSL_CTRL_SET_MAX_CERT_LIST doesnt_exist +#define SSL_CTRL_SET_MAX_SEND_FRAGMENT doesnt_exist +#define SSL_CTRL_SET_MSG_CALLBACK doesnt_exist +#define SSL_CTRL_SET_MSG_CALLBACK_ARG doesnt_exist +#define SSL_CTRL_SET_MTU doesnt_exist +#define SSL_CTRL_SET_READ_AHEAD doesnt_exist +#define SSL_CTRL_SET_SESS_CACHE_MODE doesnt_exist +#define SSL_CTRL_SET_SESS_CACHE_SIZE doesnt_exist +#define SSL_CTRL_SET_TLSEXT_HOSTNAME doesnt_exist +#define SSL_CTRL_SET_TLSEXT_SERVERNAME_ARG doesnt_exist +#define SSL_CTRL_SET_TLSEXT_SERVERNAME_CB doesnt_exist +#define SSL_CTRL_SET_TLSEXT_TICKET_KEYS doesnt_exist +#define SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB doesnt_exist +#define SSL_CTRL_SET_TMP_DH doesnt_exist +#define SSL_CTRL_SET_TMP_DH_CB doesnt_exist +#define SSL_CTRL_SET_TMP_ECDH doesnt_exist +#define SSL_CTRL_SET_TMP_ECDH_CB doesnt_exist +#define SSL_CTRL_SET_TMP_RSA doesnt_exist +#define SSL_CTRL_SET_TMP_RSA_CB doesnt_exist + + + +#if defined(__cplusplus) +} // extern C + +#if !defined(BORINGSSL_NO_CXX) + +extern "C++" { + +namespace bssl { + +BORINGSSL_MAKE_DELETER(SSL, SSL_free) +BORINGSSL_MAKE_DELETER(SSL_CTX, SSL_CTX_free) +BORINGSSL_MAKE_DELETER(SSL_SESSION, SSL_SESSION_free) + +enum class OpenRecordResult { + kOK, + kDiscard, + kIncompleteRecord, + kAlertCloseNotify, + kError, +}; + +// *** EXPERIMENTAL -- DO NOT USE *** +// +// OpenRecord decrypts the first complete SSL record from |in| in-place, sets +// |out| to the decrypted application data, and |out_record_len| to the length +// of the encrypted record. Returns: +// - kOK if an application-data record was successfully decrypted and verified. +// - kDiscard if a record was sucessfully processed, but should be discarded. +// - kIncompleteRecord if |in| did not contain a complete record. +// - kAlertCloseNotify if a record was successfully processed but is a +// close_notify alert. +// - kError if an error occurred or the record is invalid. |*out_alert| will be +// set to an alert to emit, or zero if no alert should be emitted. +OPENSSL_EXPORT OpenRecordResult OpenRecord(SSL *ssl, Span *out, + size_t *out_record_len, + uint8_t *out_alert, + Span in); + +OPENSSL_EXPORT size_t SealRecordPrefixLen(const SSL *ssl, size_t plaintext_len); + +// SealRecordSuffixLen returns the length of the suffix written by |SealRecord|. +// +// |plaintext_len| must be equal to the size of the plaintext passed to +// |SealRecord|. +// +// |plaintext_len| must not exceed |SSL3_RT_MAX_PLAINTEXT_LENGTH|. The returned +// suffix length will not exceed |SSL3_RT_MAX_ENCRYPTED_OVERHEAD|. +OPENSSL_EXPORT size_t SealRecordSuffixLen(const SSL *ssl, size_t plaintext_len); + +// *** EXPERIMENTAL -- DO NOT USE *** +// +// SealRecord encrypts the cleartext of |in| and scatters the resulting TLS +// application data record between |out_prefix|, |out|, and |out_suffix|. It +// returns true on success or false if an error occurred. +// +// The length of |out_prefix| must equal |SealRecordPrefixLen|. The length of +// |out| must equal the length of |in|, which must not exceed +// |SSL3_RT_MAX_PLAINTEXT_LENGTH|. The length of |out_suffix| must equal +// |SealRecordSuffixLen|. +// +// If enabled, |SealRecord| may perform TLS 1.0 CBC 1/n-1 record splitting. +// |SealRecordPrefixLen| accounts for the required overhead if that is the case. +// +// |out| may equal |in| to encrypt in-place but may not otherwise alias. +// |out_prefix| and |out_suffix| may not alias anything. +OPENSSL_EXPORT bool SealRecord(SSL *ssl, Span out_prefix, + Span out, Span out_suffix, + Span in); + + +// *** EXPERIMENTAL — DO NOT USE WITHOUT CHECKING *** +// +// Split handshakes. +// +// Split handshakes allows the handshake part of a TLS connection to be +// performed in a different process (or on a different machine) than the data +// exchange. This only applies to servers. +// +// In the first part of a split handshake, an |SSL| (where the |SSL_CTX| has +// been configured with |SSL_CTX_set_handoff_mode|) is used normally. Once the +// ClientHello message has been received, the handshake will stop and +// |SSL_get_error| will indicate |SSL_ERROR_HANDOFF|. At this point (and only +// at this point), |SSL_serialize_handoff| can be called to write the “handoff” +// state of the connection. +// +// Elsewhere, a fresh |SSL| can be used with |SSL_apply_handoff| to continue +// the connection. The connection from the client is fed into this |SSL| until +// the handshake completes normally. At this point (and only at this point), +// |SSL_serialize_handback| can be called to serialize the result of the +// handshake. +// +// Back at the first location, a fresh |SSL| can be used with +// |SSL_apply_handback|. Then the client's connection can be processed mostly +// as normal. +// +// Lastly, when a connection is in the handoff state, whether or not +// |SSL_serialize_handoff| is called, |SSL_decline_handoff| will move it back +// into a normal state where the connection can procede without impact. +// +// WARNING: Currently only works with TLS 1.0–1.2. +// WARNING: The serialisation formats are not yet stable: version skew may be +// fatal. +// WARNING: The handback data contains sensitive key material and must be +// protected. +// WARNING: Some calls on the final |SSL| will not work. Just as an example, +// calls like |SSL_get0_session_id_context| and |SSL_get_privatekey| won't +// work because the certificate used for handshaking isn't available. +// WARNING: |SSL_apply_handoff| may trigger “msg” callback calls. + +OPENSSL_EXPORT void SSL_CTX_set_handoff_mode(SSL_CTX *ctx, bool on); +OPENSSL_EXPORT bool SSL_serialize_handoff(const SSL *ssl, CBB *out); +OPENSSL_EXPORT bool SSL_decline_handoff(SSL *ssl); +OPENSSL_EXPORT bool SSL_apply_handoff(SSL *ssl, Span handoff); +OPENSSL_EXPORT bool SSL_serialize_handback(const SSL *ssl, CBB *out); +OPENSSL_EXPORT bool SSL_apply_handback(SSL *ssl, Span handback); + +} // namespace bssl + +} // extern C++ + +#endif // !defined(BORINGSSL_NO_CXX) + +#endif + +#define SSL_R_APP_DATA_IN_HANDSHAKE 100 +#define SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT 101 +#define SSL_R_BAD_ALERT 102 +#define SSL_R_BAD_CHANGE_CIPHER_SPEC 103 +#define SSL_R_BAD_DATA_RETURNED_BY_CALLBACK 104 +#define SSL_R_BAD_DH_P_LENGTH 105 +#define SSL_R_BAD_DIGEST_LENGTH 106 +#define SSL_R_BAD_ECC_CERT 107 +#define SSL_R_BAD_ECPOINT 108 +#define SSL_R_BAD_HANDSHAKE_RECORD 109 +#define SSL_R_BAD_HELLO_REQUEST 110 +#define SSL_R_BAD_LENGTH 111 +#define SSL_R_BAD_PACKET_LENGTH 112 +#define SSL_R_BAD_RSA_ENCRYPT 113 +#define SSL_R_BAD_SIGNATURE 114 +#define SSL_R_BAD_SRTP_MKI_VALUE 115 +#define SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST 116 +#define SSL_R_BAD_SSL_FILETYPE 117 +#define SSL_R_BAD_WRITE_RETRY 118 +#define SSL_R_BIO_NOT_SET 119 +#define SSL_R_BN_LIB 120 +#define SSL_R_BUFFER_TOO_SMALL 121 +#define SSL_R_CA_DN_LENGTH_MISMATCH 122 +#define SSL_R_CA_DN_TOO_LONG 123 +#define SSL_R_CCS_RECEIVED_EARLY 124 +#define SSL_R_CERTIFICATE_VERIFY_FAILED 125 +#define SSL_R_CERT_CB_ERROR 126 +#define SSL_R_CERT_LENGTH_MISMATCH 127 +#define SSL_R_CHANNEL_ID_NOT_P256 128 +#define SSL_R_CHANNEL_ID_SIGNATURE_INVALID 129 +#define SSL_R_CIPHER_OR_HASH_UNAVAILABLE 130 +#define SSL_R_CLIENTHELLO_PARSE_FAILED 131 +#define SSL_R_CLIENTHELLO_TLSEXT 132 +#define SSL_R_CONNECTION_REJECTED 133 +#define SSL_R_CONNECTION_TYPE_NOT_SET 134 +#define SSL_R_CUSTOM_EXTENSION_ERROR 135 +#define SSL_R_DATA_LENGTH_TOO_LONG 136 +#define SSL_R_DECODE_ERROR 137 +#define SSL_R_DECRYPTION_FAILED 138 +#define SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC 139 +#define SSL_R_DH_PUBLIC_VALUE_LENGTH_IS_WRONG 140 +#define SSL_R_DH_P_TOO_LONG 141 +#define SSL_R_DIGEST_CHECK_FAILED 142 +#define SSL_R_DTLS_MESSAGE_TOO_BIG 143 +#define SSL_R_ECC_CERT_NOT_FOR_SIGNING 144 +#define SSL_R_EMS_STATE_INCONSISTENT 145 +#define SSL_R_ENCRYPTED_LENGTH_TOO_LONG 146 +#define SSL_R_ERROR_ADDING_EXTENSION 147 +#define SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST 148 +#define SSL_R_ERROR_PARSING_EXTENSION 149 +#define SSL_R_EXCESSIVE_MESSAGE_SIZE 150 +#define SSL_R_EXTRA_DATA_IN_MESSAGE 151 +#define SSL_R_FRAGMENT_MISMATCH 152 +#define SSL_R_GOT_NEXT_PROTO_WITHOUT_EXTENSION 153 +#define SSL_R_HANDSHAKE_FAILURE_ON_CLIENT_HELLO 154 +#define SSL_R_HTTPS_PROXY_REQUEST 155 +#define SSL_R_HTTP_REQUEST 156 +#define SSL_R_INAPPROPRIATE_FALLBACK 157 +#define SSL_R_INVALID_COMMAND 158 +#define SSL_R_INVALID_MESSAGE 159 +#define SSL_R_INVALID_SSL_SESSION 160 +#define SSL_R_INVALID_TICKET_KEYS_LENGTH 161 +#define SSL_R_LENGTH_MISMATCH 162 +#define SSL_R_MISSING_EXTENSION 164 +#define SSL_R_MISSING_RSA_CERTIFICATE 165 +#define SSL_R_MISSING_TMP_DH_KEY 166 +#define SSL_R_MISSING_TMP_ECDH_KEY 167 +#define SSL_R_MIXED_SPECIAL_OPERATOR_WITH_GROUPS 168 +#define SSL_R_MTU_TOO_SMALL 169 +#define SSL_R_NEGOTIATED_BOTH_NPN_AND_ALPN 170 +#define SSL_R_NESTED_GROUP 171 +#define SSL_R_NO_CERTIFICATES_RETURNED 172 +#define SSL_R_NO_CERTIFICATE_ASSIGNED 173 +#define SSL_R_NO_CERTIFICATE_SET 174 +#define SSL_R_NO_CIPHERS_AVAILABLE 175 +#define SSL_R_NO_CIPHERS_PASSED 176 +#define SSL_R_NO_CIPHER_MATCH 177 +#define SSL_R_NO_COMPRESSION_SPECIFIED 178 +#define SSL_R_NO_METHOD_SPECIFIED 179 +#define SSL_R_NO_P256_SUPPORT 180 +#define SSL_R_NO_PRIVATE_KEY_ASSIGNED 181 +#define SSL_R_NO_RENEGOTIATION 182 +#define SSL_R_NO_REQUIRED_DIGEST 183 +#define SSL_R_NO_SHARED_CIPHER 184 +#define SSL_R_NULL_SSL_CTX 185 +#define SSL_R_NULL_SSL_METHOD_PASSED 186 +#define SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED 187 +#define SSL_R_OLD_SESSION_VERSION_NOT_RETURNED 188 +#define SSL_R_OUTPUT_ALIASES_INPUT 189 +#define SSL_R_PARSE_TLSEXT 190 +#define SSL_R_PATH_TOO_LONG 191 +#define SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE 192 +#define SSL_R_PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE 193 +#define SSL_R_PROTOCOL_IS_SHUTDOWN 194 +#define SSL_R_PSK_IDENTITY_NOT_FOUND 195 +#define SSL_R_PSK_NO_CLIENT_CB 196 +#define SSL_R_PSK_NO_SERVER_CB 197 +#define SSL_R_READ_TIMEOUT_EXPIRED 198 +#define SSL_R_RECORD_LENGTH_MISMATCH 199 +#define SSL_R_RECORD_TOO_LARGE 200 +#define SSL_R_RENEGOTIATION_ENCODING_ERR 201 +#define SSL_R_RENEGOTIATION_MISMATCH 202 +#define SSL_R_REQUIRED_CIPHER_MISSING 203 +#define SSL_R_RESUMED_EMS_SESSION_WITHOUT_EMS_EXTENSION 204 +#define SSL_R_RESUMED_NON_EMS_SESSION_WITH_EMS_EXTENSION 205 +#define SSL_R_SCSV_RECEIVED_WHEN_RENEGOTIATING 206 +#define SSL_R_SERVERHELLO_TLSEXT 207 +#define SSL_R_SESSION_ID_CONTEXT_UNINITIALIZED 208 +#define SSL_R_SESSION_MAY_NOT_BE_CREATED 209 +#define SSL_R_SIGNATURE_ALGORITHMS_EXTENSION_SENT_BY_SERVER 210 +#define SSL_R_SRTP_COULD_NOT_ALLOCATE_PROFILES 211 +#define SSL_R_SRTP_UNKNOWN_PROTECTION_PROFILE 212 +#define SSL_R_SSL3_EXT_INVALID_SERVERNAME 213 +#define SSL_R_SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION 214 +#define SSL_R_SSL_HANDSHAKE_FAILURE 215 +#define SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG 216 +#define SSL_R_TLS_PEER_DID_NOT_RESPOND_WITH_CERTIFICATE_LIST 217 +#define SSL_R_TLS_RSA_ENCRYPTED_VALUE_LENGTH_IS_WRONG 218 +#define SSL_R_TOO_MANY_EMPTY_FRAGMENTS 219 +#define SSL_R_TOO_MANY_WARNING_ALERTS 220 +#define SSL_R_UNABLE_TO_FIND_ECDH_PARAMETERS 221 +#define SSL_R_UNEXPECTED_EXTENSION 222 +#define SSL_R_UNEXPECTED_MESSAGE 223 +#define SSL_R_UNEXPECTED_OPERATOR_IN_GROUP 224 +#define SSL_R_UNEXPECTED_RECORD 225 +#define SSL_R_UNINITIALIZED 226 +#define SSL_R_UNKNOWN_ALERT_TYPE 227 +#define SSL_R_UNKNOWN_CERTIFICATE_TYPE 228 +#define SSL_R_UNKNOWN_CIPHER_RETURNED 229 +#define SSL_R_UNKNOWN_CIPHER_TYPE 230 +#define SSL_R_UNKNOWN_DIGEST 231 +#define SSL_R_UNKNOWN_KEY_EXCHANGE_TYPE 232 +#define SSL_R_UNKNOWN_PROTOCOL 233 +#define SSL_R_UNKNOWN_SSL_VERSION 234 +#define SSL_R_UNKNOWN_STATE 235 +#define SSL_R_UNSAFE_LEGACY_RENEGOTIATION_DISABLED 236 +#define SSL_R_UNSUPPORTED_CIPHER 237 +#define SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM 238 +#define SSL_R_UNSUPPORTED_ELLIPTIC_CURVE 239 +#define SSL_R_UNSUPPORTED_PROTOCOL 240 +#define SSL_R_WRONG_CERTIFICATE_TYPE 241 +#define SSL_R_WRONG_CIPHER_RETURNED 242 +#define SSL_R_WRONG_CURVE 243 +#define SSL_R_WRONG_MESSAGE_TYPE 244 +#define SSL_R_WRONG_SIGNATURE_TYPE 245 +#define SSL_R_WRONG_SSL_VERSION 246 +#define SSL_R_WRONG_VERSION_NUMBER 247 +#define SSL_R_X509_LIB 248 +#define SSL_R_X509_VERIFICATION_SETUP_PROBLEMS 249 +#define SSL_R_SHUTDOWN_WHILE_IN_INIT 250 +#define SSL_R_INVALID_OUTER_RECORD_TYPE 251 +#define SSL_R_UNSUPPORTED_PROTOCOL_FOR_CUSTOM_KEY 252 +#define SSL_R_NO_COMMON_SIGNATURE_ALGORITHMS 253 +#define SSL_R_DOWNGRADE_DETECTED 254 +#define SSL_R_BUFFERED_MESSAGES_ON_CIPHER_CHANGE 255 +#define SSL_R_INVALID_COMPRESSION_LIST 256 +#define SSL_R_DUPLICATE_EXTENSION 257 +#define SSL_R_MISSING_KEY_SHARE 258 +#define SSL_R_INVALID_ALPN_PROTOCOL 259 +#define SSL_R_TOO_MANY_KEY_UPDATES 260 +#define SSL_R_BLOCK_CIPHER_PAD_IS_WRONG 261 +#define SSL_R_NO_CIPHERS_SPECIFIED 262 +#define SSL_R_RENEGOTIATION_EMS_MISMATCH 263 +#define SSL_R_DUPLICATE_KEY_SHARE 264 +#define SSL_R_NO_GROUPS_SPECIFIED 265 +#define SSL_R_NO_SHARED_GROUP 266 +#define SSL_R_PRE_SHARED_KEY_MUST_BE_LAST 267 +#define SSL_R_OLD_SESSION_PRF_HASH_MISMATCH 268 +#define SSL_R_INVALID_SCT_LIST 269 +#define SSL_R_TOO_MUCH_SKIPPED_EARLY_DATA 270 +#define SSL_R_PSK_IDENTITY_BINDER_COUNT_MISMATCH 271 +#define SSL_R_CANNOT_PARSE_LEAF_CERT 272 +#define SSL_R_SERVER_CERT_CHANGED 273 +#define SSL_R_CERTIFICATE_AND_PRIVATE_KEY_MISMATCH 274 +#define SSL_R_CANNOT_HAVE_BOTH_PRIVKEY_AND_METHOD 275 +#define SSL_R_TICKET_ENCRYPTION_FAILED 276 +#define SSL_R_ALPN_MISMATCH_ON_EARLY_DATA 277 +#define SSL_R_WRONG_VERSION_ON_EARLY_DATA 278 +#define SSL_R_UNEXPECTED_EXTENSION_ON_EARLY_DATA 279 +#define SSL_R_NO_SUPPORTED_VERSIONS_ENABLED 280 +#define SSL_R_APPLICATION_DATA_INSTEAD_OF_HANDSHAKE 281 +#define SSL_R_EMPTY_HELLO_RETRY_REQUEST 282 +#define SSL_R_EARLY_DATA_NOT_IN_USE 283 +#define SSL_R_HANDSHAKE_NOT_COMPLETE 284 +#define SSL_R_NEGOTIATED_TB_WITHOUT_EMS_OR_RI 285 +#define SSL_R_SERVER_ECHOED_INVALID_SESSION_ID 286 +#define SSL_R_PRIVATE_KEY_OPERATION_FAILED 287 +#define SSL_R_SSLV3_ALERT_CLOSE_NOTIFY 1000 +#define SSL_R_SSLV3_ALERT_UNEXPECTED_MESSAGE 1010 +#define SSL_R_SSLV3_ALERT_BAD_RECORD_MAC 1020 +#define SSL_R_TLSV1_ALERT_DECRYPTION_FAILED 1021 +#define SSL_R_TLSV1_ALERT_RECORD_OVERFLOW 1022 +#define SSL_R_SSLV3_ALERT_DECOMPRESSION_FAILURE 1030 +#define SSL_R_SSLV3_ALERT_HANDSHAKE_FAILURE 1040 +#define SSL_R_SSLV3_ALERT_NO_CERTIFICATE 1041 +#define SSL_R_SSLV3_ALERT_BAD_CERTIFICATE 1042 +#define SSL_R_SSLV3_ALERT_UNSUPPORTED_CERTIFICATE 1043 +#define SSL_R_SSLV3_ALERT_CERTIFICATE_REVOKED 1044 +#define SSL_R_SSLV3_ALERT_CERTIFICATE_EXPIRED 1045 +#define SSL_R_SSLV3_ALERT_CERTIFICATE_UNKNOWN 1046 +#define SSL_R_SSLV3_ALERT_ILLEGAL_PARAMETER 1047 +#define SSL_R_TLSV1_ALERT_UNKNOWN_CA 1048 +#define SSL_R_TLSV1_ALERT_ACCESS_DENIED 1049 +#define SSL_R_TLSV1_ALERT_DECODE_ERROR 1050 +#define SSL_R_TLSV1_ALERT_DECRYPT_ERROR 1051 +#define SSL_R_TLSV1_ALERT_EXPORT_RESTRICTION 1060 +#define SSL_R_TLSV1_ALERT_PROTOCOL_VERSION 1070 +#define SSL_R_TLSV1_ALERT_INSUFFICIENT_SECURITY 1071 +#define SSL_R_TLSV1_ALERT_INTERNAL_ERROR 1080 +#define SSL_R_TLSV1_ALERT_INAPPROPRIATE_FALLBACK 1086 +#define SSL_R_TLSV1_ALERT_USER_CANCELLED 1090 +#define SSL_R_TLSV1_ALERT_NO_RENEGOTIATION 1100 +#define SSL_R_TLSV1_UNSUPPORTED_EXTENSION 1110 +#define SSL_R_TLSV1_CERTIFICATE_UNOBTAINABLE 1111 +#define SSL_R_TLSV1_UNRECOGNIZED_NAME 1112 +#define SSL_R_TLSV1_BAD_CERTIFICATE_STATUS_RESPONSE 1113 +#define SSL_R_TLSV1_BAD_CERTIFICATE_HASH_VALUE 1114 +#define SSL_R_TLSV1_UNKNOWN_PSK_IDENTITY 1115 +#define SSL_R_TLSV1_CERTIFICATE_REQUIRED 1116 +#define SSL_R_TOO_MUCH_READ_EARLY_DATA 1117 + +#endif // OPENSSL_HEADER_SSL_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/ssl3.h b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/ssl3.h new file mode 100644 index 0000000..509c2a4 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/ssl3.h @@ -0,0 +1,332 @@ +/* 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 OPENSSL_HEADER_SSL3_H +#define OPENSSL_HEADER_SSL3_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +// These are kept to support clients that negotiates higher protocol versions +// using SSLv2 client hello records. +#define SSL2_MT_CLIENT_HELLO 1 +#define SSL2_VERSION 0x0002 + +// Signalling cipher suite value from RFC 5746. +#define SSL3_CK_SCSV 0x030000FF +// Fallback signalling cipher suite value from RFC 7507. +#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_EDH_DSS_DES_64_CBC_SHA 0x03000012 +#define SSL3_CK_EDH_DSS_DES_192_CBC3_SHA 0x03000013 +#define SSL3_CK_EDH_RSA_DES_40_CBC_SHA 0x03000014 +#define SSL3_CK_EDH_RSA_DES_64_CBC_SHA 0x03000015 +#define SSL3_CK_EDH_RSA_DES_192_CBC3_SHA 0x03000016 + +#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 + +#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_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" + +#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 + +// 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. +// +// TODO(davidben): This derivation doesn't take AEADs into account, or TLS 1.1 +// explicit nonces. It happens to work because |SSL3_RT_MAX_MD_SIZE| is larger +// than necessary and no true AEAD has variable overhead in TLS 1.2. +#define SSL3_RT_MAX_ENCRYPTED_OVERHEAD (256 + SSL3_RT_MAX_MD_SIZE) + +// SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD is the maximum overhead in encrypting a +// record. This does not include the record header. Some ciphers use explicit +// nonces, so it includes both the AEAD overhead as well as the nonce. +#define SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD \ + (EVP_AEAD_MAX_OVERHEAD + EVP_AEAD_MAX_NONCE_LENGTH) + +OPENSSL_COMPILE_ASSERT( + SSL3_RT_MAX_ENCRYPTED_OVERHEAD >= SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD, + max_overheads_are_consistent); + +// SSL3_RT_MAX_COMPRESSED_LENGTH is an alias for +// |SSL3_RT_MAX_PLAIN_LENGTH|. Compression is gone, so don't include the +// compression overhead. +#define SSL3_RT_MAX_COMPRESSED_LENGTH SSL3_RT_MAX_PLAIN_LENGTH + +#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_RT_CHANGE_CIPHER_SPEC 20 +#define SSL3_RT_ALERT 21 +#define SSL3_RT_HANDSHAKE 22 +#define SSL3_RT_APPLICATION_DATA 23 + +// 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 SSL3_AD_INAPPROPRIATE_FALLBACK 86 // fatal + +#define SSL3_CT_RSA_SIGN 1 + +#define SSL3_MT_HELLO_REQUEST 0 +#define SSL3_MT_CLIENT_HELLO 1 +#define SSL3_MT_SERVER_HELLO 2 +#define SSL3_MT_NEW_SESSION_TICKET 4 +#define SSL3_MT_END_OF_EARLY_DATA 5 +#define SSL3_MT_ENCRYPTED_EXTENSIONS 8 +#define SSL3_MT_CERTIFICATE 11 +#define SSL3_MT_SERVER_KEY_EXCHANGE 12 +#define SSL3_MT_CERTIFICATE_REQUEST 13 +#define SSL3_MT_SERVER_HELLO_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 +#define SSL3_MT_SUPPLEMENTAL_DATA 23 +#define SSL3_MT_KEY_UPDATE 24 +#define SSL3_MT_NEXT_PROTO 67 +#define SSL3_MT_CHANNEL_ID 203 +#define SSL3_MT_MESSAGE_HASH 254 +#define DTLS1_MT_HELLO_VERIFY_REQUEST 3 + +// The following are legacy aliases for consumers which use +// |SSL_CTX_set_msg_callback|. +#define SSL3_MT_SERVER_DONE SSL3_MT_SERVER_HELLO_DONE +#define SSL3_MT_NEWSESSION_TICKET SSL3_MT_NEW_SESSION_TICKET + + +#define SSL3_MT_CCS 1 + + +#ifdef __cplusplus +} // extern C +#endif + +#endif // OPENSSL_HEADER_SSL3_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/ssl3.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/ssl3.h.grpc_back new file mode 100644 index 0000000..e32a6d7 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/ssl3.h.grpc_back @@ -0,0 +1,332 @@ +/* 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 OPENSSL_HEADER_SSL3_H +#define OPENSSL_HEADER_SSL3_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +// These are kept to support clients that negotiates higher protocol versions +// using SSLv2 client hello records. +#define SSL2_MT_CLIENT_HELLO 1 +#define SSL2_VERSION 0x0002 + +// Signalling cipher suite value from RFC 5746. +#define SSL3_CK_SCSV 0x030000FF +// Fallback signalling cipher suite value from RFC 7507. +#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_EDH_DSS_DES_64_CBC_SHA 0x03000012 +#define SSL3_CK_EDH_DSS_DES_192_CBC3_SHA 0x03000013 +#define SSL3_CK_EDH_RSA_DES_40_CBC_SHA 0x03000014 +#define SSL3_CK_EDH_RSA_DES_64_CBC_SHA 0x03000015 +#define SSL3_CK_EDH_RSA_DES_192_CBC3_SHA 0x03000016 + +#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 + +#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_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" + +#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 + +// 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. +// +// TODO(davidben): This derivation doesn't take AEADs into account, or TLS 1.1 +// explicit nonces. It happens to work because |SSL3_RT_MAX_MD_SIZE| is larger +// than necessary and no true AEAD has variable overhead in TLS 1.2. +#define SSL3_RT_MAX_ENCRYPTED_OVERHEAD (256 + SSL3_RT_MAX_MD_SIZE) + +// SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD is the maximum overhead in encrypting a +// record. This does not include the record header. Some ciphers use explicit +// nonces, so it includes both the AEAD overhead as well as the nonce. +#define SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD \ + (EVP_AEAD_MAX_OVERHEAD + EVP_AEAD_MAX_NONCE_LENGTH) + +OPENSSL_COMPILE_ASSERT( + SSL3_RT_MAX_ENCRYPTED_OVERHEAD >= SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD, + max_overheads_are_consistent); + +// SSL3_RT_MAX_COMPRESSED_LENGTH is an alias for +// |SSL3_RT_MAX_PLAIN_LENGTH|. Compression is gone, so don't include the +// compression overhead. +#define SSL3_RT_MAX_COMPRESSED_LENGTH SSL3_RT_MAX_PLAIN_LENGTH + +#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_RT_CHANGE_CIPHER_SPEC 20 +#define SSL3_RT_ALERT 21 +#define SSL3_RT_HANDSHAKE 22 +#define SSL3_RT_APPLICATION_DATA 23 + +// 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 SSL3_AD_INAPPROPRIATE_FALLBACK 86 // fatal + +#define SSL3_CT_RSA_SIGN 1 + +#define SSL3_MT_HELLO_REQUEST 0 +#define SSL3_MT_CLIENT_HELLO 1 +#define SSL3_MT_SERVER_HELLO 2 +#define SSL3_MT_NEW_SESSION_TICKET 4 +#define SSL3_MT_END_OF_EARLY_DATA 5 +#define SSL3_MT_ENCRYPTED_EXTENSIONS 8 +#define SSL3_MT_CERTIFICATE 11 +#define SSL3_MT_SERVER_KEY_EXCHANGE 12 +#define SSL3_MT_CERTIFICATE_REQUEST 13 +#define SSL3_MT_SERVER_HELLO_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 +#define SSL3_MT_SUPPLEMENTAL_DATA 23 +#define SSL3_MT_KEY_UPDATE 24 +#define SSL3_MT_NEXT_PROTO 67 +#define SSL3_MT_CHANNEL_ID 203 +#define SSL3_MT_MESSAGE_HASH 254 +#define DTLS1_MT_HELLO_VERIFY_REQUEST 3 + +// The following are legacy aliases for consumers which use +// |SSL_CTX_set_msg_callback|. +#define SSL3_MT_SERVER_DONE SSL3_MT_SERVER_HELLO_DONE +#define SSL3_MT_NEWSESSION_TICKET SSL3_MT_NEW_SESSION_TICKET + + +#define SSL3_MT_CCS 1 + + +#ifdef __cplusplus +} // extern C +#endif + +#endif // OPENSSL_HEADER_SSL3_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/stack.h b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/stack.h new file mode 100644 index 0000000..8902fc0 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/stack.h @@ -0,0 +1,485 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 OPENSSL_HEADER_STACK_H +#define OPENSSL_HEADER_STACK_H + +#include + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// A stack, in OpenSSL, is an array of pointers. They are the most commonly +// used collection object. +// +// This file defines macros for type safe use of the stack functions. A stack +// of a specific type of object has type |STACK_OF(type)|. This can be defined +// (once) with |DEFINE_STACK_OF(type)| and declared where needed with +// |DECLARE_STACK_OF(type)|. For example: +// +// typedef struct foo_st { +// int bar; +// } FOO; +// +// DEFINE_STACK_OF(FOO); +// +// Although note that the stack will contain /pointers/ to |FOO|. +// +// A macro will be defined for each of the sk_* functions below. For +// STACK_OF(FOO), the macros would be sk_FOO_new, sk_FOO_pop etc. + + +// stack_cmp_func is a comparison function that returns a value < 0, 0 or > 0 +// if |*a| is less than, equal to or greater than |*b|, respectively. Note the +// extra indirection - the function is given a pointer to a pointer to the +// element. This differs from the usual qsort/bsearch comparison function. +typedef int (*stack_cmp_func)(const void **a, const void **b); + +// stack_st contains an array of pointers. It is not designed to be used +// directly, rather the wrapper macros should be used. +typedef struct stack_st { + // num contains the number of valid pointers in |data|. + size_t num; + void **data; + // sorted is non-zero if the values pointed to by |data| are in ascending + // order, based on |comp|. + int sorted; + // num_alloc contains the number of pointers allocated in the buffer pointed + // to by |data|, which may be larger than |num|. + size_t num_alloc; + // comp is an optional comparison function. + stack_cmp_func comp; +} _STACK; + + +#define STACK_OF(type) struct stack_st_##type + +#define DECLARE_STACK_OF(type) STACK_OF(type); + +// These are the raw stack functions, you shouldn't be using them. Rather you +// should be using the type stack macros implemented above. + +// sk_new creates a new, empty stack with the given comparison function, which +// may be zero. It returns the new stack or NULL on allocation failure. +OPENSSL_EXPORT _STACK *sk_new(stack_cmp_func comp); + +// sk_new_null creates a new, empty stack. It returns the new stack or NULL on +// allocation failure. +OPENSSL_EXPORT _STACK *sk_new_null(void); + +// sk_num returns the number of elements in |s|. +OPENSSL_EXPORT size_t sk_num(const _STACK *sk); + +// sk_zero resets |sk| to the empty state but does nothing to free the +// individual elements themselves. +OPENSSL_EXPORT void sk_zero(_STACK *sk); + +// sk_value returns the |i|th pointer in |sk|, or NULL if |i| is out of +// range. +OPENSSL_EXPORT void *sk_value(const _STACK *sk, size_t i); + +// sk_set sets the |i|th pointer in |sk| to |p| and returns |p|. If |i| is out +// of range, it returns NULL. +OPENSSL_EXPORT void *sk_set(_STACK *sk, size_t i, void *p); + +// sk_free frees the given stack and array of pointers, but does nothing to +// free the individual elements. Also see |sk_pop_free|. +OPENSSL_EXPORT void sk_free(_STACK *sk); + +// sk_pop_free calls |free_func| on each element in the stack and then frees +// the stack itself. +OPENSSL_EXPORT void sk_pop_free(_STACK *sk, void (*free_func)(void *)); + +// sk_insert inserts |p| into the stack at index |where|, moving existing +// elements if needed. It returns the length of the new stack, or zero on +// error. +OPENSSL_EXPORT size_t sk_insert(_STACK *sk, void *p, size_t where); + +// sk_delete removes the pointer at index |where|, moving other elements down +// if needed. It returns the removed pointer, or NULL if |where| is out of +// range. +OPENSSL_EXPORT void *sk_delete(_STACK *sk, size_t where); + +// sk_delete_ptr removes, at most, one instance of |p| from the stack based on +// pointer equality. If an instance of |p| is found then |p| is returned, +// otherwise it returns NULL. +OPENSSL_EXPORT void *sk_delete_ptr(_STACK *sk, void *p); + +// sk_find returns the first value in the stack equal to |p|. If a comparison +// function has been set on the stack, then equality is defined by it and the +// stack will be sorted if need be so that a binary search can be used. +// Otherwise pointer equality is used. If a matching element is found, its +// index is written to |*out_index| (if |out_index| is not NULL) and one is +// returned. Otherwise zero is returned. +OPENSSL_EXPORT int sk_find(_STACK *sk, size_t *out_index, void *p); + +// sk_shift removes and returns the first element in the stack, or returns NULL +// if the stack is empty. +OPENSSL_EXPORT void *sk_shift(_STACK *sk); + +// sk_push appends |p| to the stack and returns the length of the new stack, or +// 0 on allocation failure. +OPENSSL_EXPORT size_t sk_push(_STACK *sk, void *p); + +// sk_pop returns and removes the last element on the stack, or NULL if the +// stack is empty. +OPENSSL_EXPORT void *sk_pop(_STACK *sk); + +// sk_dup performs a shallow copy of a stack and returns the new stack, or NULL +// on error. +OPENSSL_EXPORT _STACK *sk_dup(const _STACK *sk); + +// sk_sort sorts the elements of |sk| into ascending order based on the +// comparison function. The stack maintains a |sorted| flag and sorting an +// already sorted stack is a no-op. +OPENSSL_EXPORT void sk_sort(_STACK *sk); + +// sk_is_sorted returns one if |sk| is known to be sorted and zero +// otherwise. +OPENSSL_EXPORT int sk_is_sorted(const _STACK *sk); + +// sk_set_cmp_func sets the comparison function to be used by |sk| and returns +// the previous one. +OPENSSL_EXPORT stack_cmp_func sk_set_cmp_func(_STACK *sk, stack_cmp_func comp); + +// sk_deep_copy performs a copy of |sk| and of each of the non-NULL elements in +// |sk| by using |copy_func|. If an error occurs, |free_func| is used to free +// any copies already made and NULL is returned. +OPENSSL_EXPORT _STACK *sk_deep_copy(const _STACK *sk, + void *(*copy_func)(void *), + void (*free_func)(void *)); + + +// Defining stack types. +// +// This set of macros is used to emit the typed functions that act on a +// |STACK_OF(T)|. + +#if !defined(BORINGSSL_NO_CXX) +extern "C++" { +namespace bssl { +namespace internal { +template +struct StackTraits {}; +} +} +} + +#define BORINGSSL_DEFINE_STACK_TRAITS(name, type, is_const) \ + extern "C++" { \ + namespace bssl { \ + namespace internal { \ + template <> \ + struct StackTraits { \ + static constexpr bool kIsStack = true; \ + using Type = type; \ + static constexpr bool kIsConst = is_const; \ + }; \ + } \ + } \ + } + +#else +#define BORINGSSL_DEFINE_STACK_TRAITS(name, type, is_const) +#endif + +// Stack functions must be tagged unused to support file-local stack types. +// Clang's -Wunused-function only allows unused static inline functions if they +// are defined in a header. + +#define BORINGSSL_DEFINE_STACK_OF_IMPL(name, ptrtype, constptrtype) \ + DECLARE_STACK_OF(name) \ + \ + typedef int (*stack_##name##_cmp_func)(constptrtype *a, constptrtype *b); \ + \ + static inline OPENSSL_UNUSED STACK_OF(name) * \ + sk_##name##_new(stack_##name##_cmp_func comp) { \ + return (STACK_OF(name) *)sk_new((stack_cmp_func)comp); \ + } \ + \ + static inline OPENSSL_UNUSED STACK_OF(name) *sk_##name##_new_null(void) { \ + return (STACK_OF(name) *)sk_new_null(); \ + } \ + \ + static inline OPENSSL_UNUSED size_t sk_##name##_num( \ + const STACK_OF(name) *sk) { \ + return sk_num((const _STACK *)sk); \ + } \ + \ + static inline OPENSSL_UNUSED void sk_##name##_zero(STACK_OF(name) *sk) { \ + sk_zero((_STACK *)sk); \ + } \ + \ + static inline OPENSSL_UNUSED ptrtype sk_##name##_value( \ + const STACK_OF(name) *sk, size_t i) { \ + return (ptrtype)sk_value((const _STACK *)sk, i); \ + } \ + \ + static inline OPENSSL_UNUSED ptrtype sk_##name##_set(STACK_OF(name) *sk, \ + size_t i, ptrtype p) { \ + return (ptrtype)sk_set((_STACK *)sk, i, (void *)p); \ + } \ + \ + static inline OPENSSL_UNUSED void sk_##name##_free(STACK_OF(name) *sk) { \ + sk_free((_STACK *)sk); \ + } \ + \ + static inline OPENSSL_UNUSED void sk_##name##_pop_free( \ + STACK_OF(name) *sk, void (*free_func)(ptrtype p)) { \ + sk_pop_free((_STACK *)sk, (void (*)(void *))free_func); \ + } \ + \ + static inline OPENSSL_UNUSED size_t sk_##name##_insert( \ + STACK_OF(name) *sk, ptrtype p, size_t where) { \ + return sk_insert((_STACK *)sk, (void *)p, where); \ + } \ + \ + static inline OPENSSL_UNUSED ptrtype sk_##name##_delete(STACK_OF(name) *sk, \ + size_t where) { \ + return (ptrtype)sk_delete((_STACK *)sk, where); \ + } \ + \ + static inline OPENSSL_UNUSED ptrtype sk_##name##_delete_ptr( \ + STACK_OF(name) *sk, ptrtype p) { \ + return (ptrtype)sk_delete_ptr((_STACK *)sk, (void *)p); \ + } \ + \ + static inline OPENSSL_UNUSED int sk_##name##_find( \ + STACK_OF(name) *sk, size_t *out_index, ptrtype p) { \ + return sk_find((_STACK *)sk, out_index, (void *)p); \ + } \ + \ + static inline OPENSSL_UNUSED ptrtype sk_##name##_shift(STACK_OF(name) *sk) { \ + return (ptrtype)sk_shift((_STACK *)sk); \ + } \ + \ + static inline OPENSSL_UNUSED size_t sk_##name##_push(STACK_OF(name) *sk, \ + ptrtype p) { \ + return sk_push((_STACK *)sk, (void *)p); \ + } \ + \ + static inline OPENSSL_UNUSED ptrtype sk_##name##_pop(STACK_OF(name) *sk) { \ + return (ptrtype)sk_pop((_STACK *)sk); \ + } \ + \ + static inline OPENSSL_UNUSED STACK_OF(name) * \ + sk_##name##_dup(const STACK_OF(name) *sk) { \ + return (STACK_OF(name) *)sk_dup((const _STACK *)sk); \ + } \ + \ + static inline OPENSSL_UNUSED void sk_##name##_sort(STACK_OF(name) *sk) { \ + sk_sort((_STACK *)sk); \ + } \ + \ + static inline OPENSSL_UNUSED int sk_##name##_is_sorted( \ + const STACK_OF(name) *sk) { \ + return sk_is_sorted((const _STACK *)sk); \ + } \ + \ + static inline OPENSSL_UNUSED stack_##name##_cmp_func \ + sk_##name##_set_cmp_func(STACK_OF(name) *sk, \ + stack_##name##_cmp_func comp) { \ + return (stack_##name##_cmp_func)sk_set_cmp_func((_STACK *)sk, \ + (stack_cmp_func)comp); \ + } \ + \ + static inline OPENSSL_UNUSED STACK_OF(name) * \ + sk_##name##_deep_copy(const STACK_OF(name) *sk, \ + ptrtype(*copy_func)(ptrtype), \ + void (*free_func)(ptrtype)) { \ + return (STACK_OF(name) *)sk_deep_copy((const _STACK *)sk, \ + (void *(*)(void *))copy_func, \ + (void (*)(void *))free_func); \ + } + +// DEFINE_STACK_OF defines |STACK_OF(type)| to be a stack whose elements are +// |type| *. +#define DEFINE_STACK_OF(type) \ + BORINGSSL_DEFINE_STACK_OF_IMPL(type, type *, const type *) \ + BORINGSSL_DEFINE_STACK_TRAITS(type, type, false) + +// DEFINE_CONST_STACK_OF defines |STACK_OF(type)| to be a stack whose elements +// are const |type| *. +#define DEFINE_CONST_STACK_OF(type) \ + BORINGSSL_DEFINE_STACK_OF_IMPL(type, const type *, const type *) \ + BORINGSSL_DEFINE_STACK_TRAITS(type, const type, true) + +// DEFINE_SPECIAL_STACK_OF defines |STACK_OF(type)| to be a stack whose elements +// are |type|, where |type| must be a typedef for a pointer. +#define DEFINE_SPECIAL_STACK_OF(type) \ + OPENSSL_COMPILE_ASSERT(sizeof(type) == sizeof(void *), \ + special_stack_of_non_pointer_##type); \ + BORINGSSL_DEFINE_STACK_OF_IMPL(type, type, const type) + + +typedef char *OPENSSL_STRING; + +DEFINE_STACK_OF(void) +DEFINE_SPECIAL_STACK_OF(OPENSSL_STRING) + + +#if defined(__cplusplus) +} // extern C +#endif + +#if !defined(BORINGSSL_NO_CXX) +extern "C++" { + +#include + +namespace bssl { + +namespace internal { + +// Stacks defined with |DEFINE_CONST_STACK_OF| are freed with |sk_free|. +template +struct DeleterImpl< + Stack, typename std::enable_if::kIsConst>::type> { + static void Free(Stack *sk) { sk_free(reinterpret_cast<_STACK *>(sk)); } +}; + +// Stacks defined with |DEFINE_STACK_OF| are freed with |sk_pop_free| and the +// corresponding type's deleter. +template +struct DeleterImpl< + Stack, typename std::enable_if::kIsConst>::type> { + static void Free(Stack *sk) { + sk_pop_free( + reinterpret_cast<_STACK *>(sk), + reinterpret_cast( + DeleterImpl::Type>::Free)); + } +}; + +template +class StackIteratorImpl { + public: + using Type = typename StackTraits::Type; + // Iterators must be default-constructable. + StackIteratorImpl() : sk_(nullptr), idx_(0) {} + StackIteratorImpl(const Stack *sk, size_t idx) : sk_(sk), idx_(idx) {} + + bool operator==(StackIteratorImpl other) const { + return sk_ == other.sk_ && idx_ == other.idx_; + } + bool operator!=(StackIteratorImpl other) const { + return !(*this == other); + } + + Type *operator*() const { + return reinterpret_cast( + sk_value(reinterpret_cast(sk_), idx_)); + } + + StackIteratorImpl &operator++(/* prefix */) { + idx_++; + return *this; + } + + StackIteratorImpl operator++(int /* postfix */) { + StackIteratorImpl copy(*this); + ++(*this); + return copy; + } + + private: + const Stack *sk_; + size_t idx_; +}; + +template +using StackIterator = typename std::enable_if::kIsStack, + StackIteratorImpl>::type; + +} // namespace internal + +// PushToStack pushes |elem| to |sk|. It returns true on success and false on +// allocation failure. +template +static inline + typename std::enable_if::kIsConst, bool>::type + PushToStack(Stack *sk, + UniquePtr::Type> elem) { + if (!sk_push(reinterpret_cast<_STACK *>(sk), elem.get())) { + return false; + } + // sk_push takes ownership on success. + elem.release(); + return true; +} + +} // namespace bssl + +// Define begin() and end() for stack types so C++ range for loops work. +template +static inline bssl::internal::StackIterator begin(const Stack *sk) { + return bssl::internal::StackIterator(sk, 0); +} + +template +static inline bssl::internal::StackIterator end(const Stack *sk) { + return bssl::internal::StackIterator( + sk, sk_num(reinterpret_cast(sk))); +} + +} // extern C++ +#endif + +#endif // OPENSSL_HEADER_STACK_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/stack.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/stack.h.grpc_back new file mode 100644 index 0000000..625f66e --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/stack.h.grpc_back @@ -0,0 +1,485 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 OPENSSL_HEADER_STACK_H +#define OPENSSL_HEADER_STACK_H + +#include + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// A stack, in OpenSSL, is an array of pointers. They are the most commonly +// used collection object. +// +// This file defines macros for type safe use of the stack functions. A stack +// of a specific type of object has type |STACK_OF(type)|. This can be defined +// (once) with |DEFINE_STACK_OF(type)| and declared where needed with +// |DECLARE_STACK_OF(type)|. For example: +// +// typedef struct foo_st { +// int bar; +// } FOO; +// +// DEFINE_STACK_OF(FOO); +// +// Although note that the stack will contain /pointers/ to |FOO|. +// +// A macro will be defined for each of the sk_* functions below. For +// STACK_OF(FOO), the macros would be sk_FOO_new, sk_FOO_pop etc. + + +// stack_cmp_func is a comparison function that returns a value < 0, 0 or > 0 +// if |*a| is less than, equal to or greater than |*b|, respectively. Note the +// extra indirection - the function is given a pointer to a pointer to the +// element. This differs from the usual qsort/bsearch comparison function. +typedef int (*stack_cmp_func)(const void **a, const void **b); + +// stack_st contains an array of pointers. It is not designed to be used +// directly, rather the wrapper macros should be used. +typedef struct stack_st { + // num contains the number of valid pointers in |data|. + size_t num; + void **data; + // sorted is non-zero if the values pointed to by |data| are in ascending + // order, based on |comp|. + int sorted; + // num_alloc contains the number of pointers allocated in the buffer pointed + // to by |data|, which may be larger than |num|. + size_t num_alloc; + // comp is an optional comparison function. + stack_cmp_func comp; +} _STACK; + + +#define STACK_OF(type) struct stack_st_##type + +#define DECLARE_STACK_OF(type) STACK_OF(type); + +// These are the raw stack functions, you shouldn't be using them. Rather you +// should be using the type stack macros implemented above. + +// sk_new creates a new, empty stack with the given comparison function, which +// may be zero. It returns the new stack or NULL on allocation failure. +OPENSSL_EXPORT _STACK *sk_new(stack_cmp_func comp); + +// sk_new_null creates a new, empty stack. It returns the new stack or NULL on +// allocation failure. +OPENSSL_EXPORT _STACK *sk_new_null(void); + +// sk_num returns the number of elements in |s|. +OPENSSL_EXPORT size_t sk_num(const _STACK *sk); + +// sk_zero resets |sk| to the empty state but does nothing to free the +// individual elements themselves. +OPENSSL_EXPORT void sk_zero(_STACK *sk); + +// sk_value returns the |i|th pointer in |sk|, or NULL if |i| is out of +// range. +OPENSSL_EXPORT void *sk_value(const _STACK *sk, size_t i); + +// sk_set sets the |i|th pointer in |sk| to |p| and returns |p|. If |i| is out +// of range, it returns NULL. +OPENSSL_EXPORT void *sk_set(_STACK *sk, size_t i, void *p); + +// sk_free frees the given stack and array of pointers, but does nothing to +// free the individual elements. Also see |sk_pop_free|. +OPENSSL_EXPORT void sk_free(_STACK *sk); + +// sk_pop_free calls |free_func| on each element in the stack and then frees +// the stack itself. +OPENSSL_EXPORT void sk_pop_free(_STACK *sk, void (*free_func)(void *)); + +// sk_insert inserts |p| into the stack at index |where|, moving existing +// elements if needed. It returns the length of the new stack, or zero on +// error. +OPENSSL_EXPORT size_t sk_insert(_STACK *sk, void *p, size_t where); + +// sk_delete removes the pointer at index |where|, moving other elements down +// if needed. It returns the removed pointer, or NULL if |where| is out of +// range. +OPENSSL_EXPORT void *sk_delete(_STACK *sk, size_t where); + +// sk_delete_ptr removes, at most, one instance of |p| from the stack based on +// pointer equality. If an instance of |p| is found then |p| is returned, +// otherwise it returns NULL. +OPENSSL_EXPORT void *sk_delete_ptr(_STACK *sk, void *p); + +// sk_find returns the first value in the stack equal to |p|. If a comparison +// function has been set on the stack, then equality is defined by it and the +// stack will be sorted if need be so that a binary search can be used. +// Otherwise pointer equality is used. If a matching element is found, its +// index is written to |*out_index| (if |out_index| is not NULL) and one is +// returned. Otherwise zero is returned. +OPENSSL_EXPORT int sk_find(_STACK *sk, size_t *out_index, void *p); + +// sk_shift removes and returns the first element in the stack, or returns NULL +// if the stack is empty. +OPENSSL_EXPORT void *sk_shift(_STACK *sk); + +// sk_push appends |p| to the stack and returns the length of the new stack, or +// 0 on allocation failure. +OPENSSL_EXPORT size_t sk_push(_STACK *sk, void *p); + +// sk_pop returns and removes the last element on the stack, or NULL if the +// stack is empty. +OPENSSL_EXPORT void *sk_pop(_STACK *sk); + +// sk_dup performs a shallow copy of a stack and returns the new stack, or NULL +// on error. +OPENSSL_EXPORT _STACK *sk_dup(const _STACK *sk); + +// sk_sort sorts the elements of |sk| into ascending order based on the +// comparison function. The stack maintains a |sorted| flag and sorting an +// already sorted stack is a no-op. +OPENSSL_EXPORT void sk_sort(_STACK *sk); + +// sk_is_sorted returns one if |sk| is known to be sorted and zero +// otherwise. +OPENSSL_EXPORT int sk_is_sorted(const _STACK *sk); + +// sk_set_cmp_func sets the comparison function to be used by |sk| and returns +// the previous one. +OPENSSL_EXPORT stack_cmp_func sk_set_cmp_func(_STACK *sk, stack_cmp_func comp); + +// sk_deep_copy performs a copy of |sk| and of each of the non-NULL elements in +// |sk| by using |copy_func|. If an error occurs, |free_func| is used to free +// any copies already made and NULL is returned. +OPENSSL_EXPORT _STACK *sk_deep_copy(const _STACK *sk, + void *(*copy_func)(void *), + void (*free_func)(void *)); + + +// Defining stack types. +// +// This set of macros is used to emit the typed functions that act on a +// |STACK_OF(T)|. + +#if !defined(BORINGSSL_NO_CXX) +extern "C++" { +namespace bssl { +namespace internal { +template +struct StackTraits {}; +} +} +} + +#define BORINGSSL_DEFINE_STACK_TRAITS(name, type, is_const) \ + extern "C++" { \ + namespace bssl { \ + namespace internal { \ + template <> \ + struct StackTraits { \ + static constexpr bool kIsStack = true; \ + using Type = type; \ + static constexpr bool kIsConst = is_const; \ + }; \ + } \ + } \ + } + +#else +#define BORINGSSL_DEFINE_STACK_TRAITS(name, type, is_const) +#endif + +// Stack functions must be tagged unused to support file-local stack types. +// Clang's -Wunused-function only allows unused static inline functions if they +// are defined in a header. + +#define BORINGSSL_DEFINE_STACK_OF_IMPL(name, ptrtype, constptrtype) \ + DECLARE_STACK_OF(name) \ + \ + typedef int (*stack_##name##_cmp_func)(constptrtype *a, constptrtype *b); \ + \ + static inline OPENSSL_UNUSED STACK_OF(name) * \ + sk_##name##_new(stack_##name##_cmp_func comp) { \ + return (STACK_OF(name) *)sk_new((stack_cmp_func)comp); \ + } \ + \ + static inline OPENSSL_UNUSED STACK_OF(name) *sk_##name##_new_null(void) { \ + return (STACK_OF(name) *)sk_new_null(); \ + } \ + \ + static inline OPENSSL_UNUSED size_t sk_##name##_num( \ + const STACK_OF(name) *sk) { \ + return sk_num((const _STACK *)sk); \ + } \ + \ + static inline OPENSSL_UNUSED void sk_##name##_zero(STACK_OF(name) *sk) { \ + sk_zero((_STACK *)sk); \ + } \ + \ + static inline OPENSSL_UNUSED ptrtype sk_##name##_value( \ + const STACK_OF(name) *sk, size_t i) { \ + return (ptrtype)sk_value((const _STACK *)sk, i); \ + } \ + \ + static inline OPENSSL_UNUSED ptrtype sk_##name##_set(STACK_OF(name) *sk, \ + size_t i, ptrtype p) { \ + return (ptrtype)sk_set((_STACK *)sk, i, (void *)p); \ + } \ + \ + static inline OPENSSL_UNUSED void sk_##name##_free(STACK_OF(name) *sk) { \ + sk_free((_STACK *)sk); \ + } \ + \ + static inline OPENSSL_UNUSED void sk_##name##_pop_free( \ + STACK_OF(name) *sk, void (*free_func)(ptrtype p)) { \ + sk_pop_free((_STACK *)sk, (void (*)(void *))free_func); \ + } \ + \ + static inline OPENSSL_UNUSED size_t sk_##name##_insert( \ + STACK_OF(name) *sk, ptrtype p, size_t where) { \ + return sk_insert((_STACK *)sk, (void *)p, where); \ + } \ + \ + static inline OPENSSL_UNUSED ptrtype sk_##name##_delete(STACK_OF(name) *sk, \ + size_t where) { \ + return (ptrtype)sk_delete((_STACK *)sk, where); \ + } \ + \ + static inline OPENSSL_UNUSED ptrtype sk_##name##_delete_ptr( \ + STACK_OF(name) *sk, ptrtype p) { \ + return (ptrtype)sk_delete_ptr((_STACK *)sk, (void *)p); \ + } \ + \ + static inline OPENSSL_UNUSED int sk_##name##_find( \ + STACK_OF(name) *sk, size_t *out_index, ptrtype p) { \ + return sk_find((_STACK *)sk, out_index, (void *)p); \ + } \ + \ + static inline OPENSSL_UNUSED ptrtype sk_##name##_shift(STACK_OF(name) *sk) { \ + return (ptrtype)sk_shift((_STACK *)sk); \ + } \ + \ + static inline OPENSSL_UNUSED size_t sk_##name##_push(STACK_OF(name) *sk, \ + ptrtype p) { \ + return sk_push((_STACK *)sk, (void *)p); \ + } \ + \ + static inline OPENSSL_UNUSED ptrtype sk_##name##_pop(STACK_OF(name) *sk) { \ + return (ptrtype)sk_pop((_STACK *)sk); \ + } \ + \ + static inline OPENSSL_UNUSED STACK_OF(name) * \ + sk_##name##_dup(const STACK_OF(name) *sk) { \ + return (STACK_OF(name) *)sk_dup((const _STACK *)sk); \ + } \ + \ + static inline OPENSSL_UNUSED void sk_##name##_sort(STACK_OF(name) *sk) { \ + sk_sort((_STACK *)sk); \ + } \ + \ + static inline OPENSSL_UNUSED int sk_##name##_is_sorted( \ + const STACK_OF(name) *sk) { \ + return sk_is_sorted((const _STACK *)sk); \ + } \ + \ + static inline OPENSSL_UNUSED stack_##name##_cmp_func \ + sk_##name##_set_cmp_func(STACK_OF(name) *sk, \ + stack_##name##_cmp_func comp) { \ + return (stack_##name##_cmp_func)sk_set_cmp_func((_STACK *)sk, \ + (stack_cmp_func)comp); \ + } \ + \ + static inline OPENSSL_UNUSED STACK_OF(name) * \ + sk_##name##_deep_copy(const STACK_OF(name) *sk, \ + ptrtype(*copy_func)(ptrtype), \ + void (*free_func)(ptrtype)) { \ + return (STACK_OF(name) *)sk_deep_copy((const _STACK *)sk, \ + (void *(*)(void *))copy_func, \ + (void (*)(void *))free_func); \ + } + +// DEFINE_STACK_OF defines |STACK_OF(type)| to be a stack whose elements are +// |type| *. +#define DEFINE_STACK_OF(type) \ + BORINGSSL_DEFINE_STACK_OF_IMPL(type, type *, const type *) \ + BORINGSSL_DEFINE_STACK_TRAITS(type, type, false) + +// DEFINE_CONST_STACK_OF defines |STACK_OF(type)| to be a stack whose elements +// are const |type| *. +#define DEFINE_CONST_STACK_OF(type) \ + BORINGSSL_DEFINE_STACK_OF_IMPL(type, const type *, const type *) \ + BORINGSSL_DEFINE_STACK_TRAITS(type, const type, true) + +// DEFINE_SPECIAL_STACK_OF defines |STACK_OF(type)| to be a stack whose elements +// are |type|, where |type| must be a typedef for a pointer. +#define DEFINE_SPECIAL_STACK_OF(type) \ + OPENSSL_COMPILE_ASSERT(sizeof(type) == sizeof(void *), \ + special_stack_of_non_pointer_##type); \ + BORINGSSL_DEFINE_STACK_OF_IMPL(type, type, const type) + + +typedef char *OPENSSL_STRING; + +DEFINE_STACK_OF(void) +DEFINE_SPECIAL_STACK_OF(OPENSSL_STRING) + + +#if defined(__cplusplus) +} // extern C +#endif + +#if !defined(BORINGSSL_NO_CXX) +extern "C++" { + +#include + +namespace bssl { + +namespace internal { + +// Stacks defined with |DEFINE_CONST_STACK_OF| are freed with |sk_free|. +template +struct DeleterImpl< + Stack, typename std::enable_if::kIsConst>::type> { + static void Free(Stack *sk) { sk_free(reinterpret_cast<_STACK *>(sk)); } +}; + +// Stacks defined with |DEFINE_STACK_OF| are freed with |sk_pop_free| and the +// corresponding type's deleter. +template +struct DeleterImpl< + Stack, typename std::enable_if::kIsConst>::type> { + static void Free(Stack *sk) { + sk_pop_free( + reinterpret_cast<_STACK *>(sk), + reinterpret_cast( + DeleterImpl::Type>::Free)); + } +}; + +template +class StackIteratorImpl { + public: + using Type = typename StackTraits::Type; + // Iterators must be default-constructable. + StackIteratorImpl() : sk_(nullptr), idx_(0) {} + StackIteratorImpl(const Stack *sk, size_t idx) : sk_(sk), idx_(idx) {} + + bool operator==(StackIteratorImpl other) const { + return sk_ == other.sk_ && idx_ == other.idx_; + } + bool operator!=(StackIteratorImpl other) const { + return !(*this == other); + } + + Type *operator*() const { + return reinterpret_cast( + sk_value(reinterpret_cast(sk_), idx_)); + } + + StackIteratorImpl &operator++(/* prefix */) { + idx_++; + return *this; + } + + StackIteratorImpl operator++(int /* postfix */) { + StackIteratorImpl copy(*this); + ++(*this); + return copy; + } + + private: + const Stack *sk_; + size_t idx_; +}; + +template +using StackIterator = typename std::enable_if::kIsStack, + StackIteratorImpl>::type; + +} // namespace internal + +// PushToStack pushes |elem| to |sk|. It returns true on success and false on +// allocation failure. +template +static inline + typename std::enable_if::kIsConst, bool>::type + PushToStack(Stack *sk, + UniquePtr::Type> elem) { + if (!sk_push(reinterpret_cast<_STACK *>(sk), elem.get())) { + return false; + } + // sk_push takes ownership on success. + elem.release(); + return true; +} + +} // namespace bssl + +// Define begin() and end() for stack types so C++ range for loops work. +template +static inline bssl::internal::StackIterator begin(const Stack *sk) { + return bssl::internal::StackIterator(sk, 0); +} + +template +static inline bssl::internal::StackIterator end(const Stack *sk) { + return bssl::internal::StackIterator( + sk, sk_num(reinterpret_cast(sk))); +} + +} // extern C++ +#endif + +#endif // OPENSSL_HEADER_STACK_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/thread.h b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/thread.h new file mode 100644 index 0000000..6f62a9f --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/thread.h @@ -0,0 +1,191 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 OPENSSL_HEADER_THREAD_H +#define OPENSSL_HEADER_THREAD_H + +#include + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +#if defined(OPENSSL_NO_THREADS) +typedef struct crypto_mutex_st { + char padding; // Empty structs have different sizes in C and C++. +} CRYPTO_MUTEX; +#elif defined(OPENSSL_WINDOWS) +// CRYPTO_MUTEX can appear in public header files so we really don't want to +// pull in windows.h. It's statically asserted that this structure is large +// enough to contain a Windows SRWLOCK by thread_win.c. +typedef union crypto_mutex_st { + void *handle; +} CRYPTO_MUTEX; +#elif defined(__MACH__) && defined(__APPLE__) +typedef pthread_rwlock_t CRYPTO_MUTEX; +#else +// It is reasonable to include pthread.h on non-Windows systems, however the +// |pthread_rwlock_t| that we need is hidden under feature flags, and we can't +// ensure that we'll be able to get it. It's statically asserted that this +// structure is large enough to contain a |pthread_rwlock_t| by +// thread_pthread.c. +typedef union crypto_mutex_st { + double alignment; + uint8_t padding[3*sizeof(int) + 5*sizeof(unsigned) + 16 + 8]; +} CRYPTO_MUTEX; +#endif + +// CRYPTO_refcount_t is the type of a reference count. +// +// Since some platforms use C11 atomics to access this, it should have the +// _Atomic qualifier. However, this header is included by C++ programs as well +// as C code that might not set -std=c11. So, in practice, it's not possible to +// do that. Instead we statically assert that the size and native alignment of +// a plain uint32_t and an _Atomic uint32_t are equal in refcount_c11.c. +typedef uint32_t CRYPTO_refcount_t; + + +// Deprecated functions. +// +// Historically, OpenSSL required callers to provide locking callbacks. +// BoringSSL is thread-safe by default, but some old code calls these functions +// and so no-op implementations are provided. + +// These defines do nothing but are provided to make old code easier to +// compile. +#define CRYPTO_LOCK 1 +#define CRYPTO_UNLOCK 2 +#define CRYPTO_READ 4 +#define CRYPTO_WRITE 8 + +// CRYPTO_num_locks returns one. (This is non-zero that callers who allocate +// sizeof(lock) times this value don't get zero and then fail because malloc(0) +// returned NULL.) +OPENSSL_EXPORT int CRYPTO_num_locks(void); + +// CRYPTO_set_locking_callback does nothing. +OPENSSL_EXPORT void CRYPTO_set_locking_callback( + void (*func)(int mode, int lock_num, const char *file, int line)); + +// CRYPTO_set_add_lock_callback does nothing. +OPENSSL_EXPORT void CRYPTO_set_add_lock_callback(int (*func)( + int *num, int amount, int lock_num, const char *file, int line)); + +// CRYPTO_get_locking_callback returns NULL. +OPENSSL_EXPORT void (*CRYPTO_get_locking_callback(void))(int mode, int lock_num, + const char *file, + int line); + +// CRYPTO_get_lock_name returns a fixed, dummy string. +OPENSSL_EXPORT const char *CRYPTO_get_lock_name(int lock_num); + +// CRYPTO_THREADID_set_callback returns one. +OPENSSL_EXPORT int CRYPTO_THREADID_set_callback( + void (*threadid_func)(CRYPTO_THREADID *threadid)); + +// CRYPTO_THREADID_set_numeric does nothing. +OPENSSL_EXPORT void CRYPTO_THREADID_set_numeric(CRYPTO_THREADID *id, + unsigned long val); + +// CRYPTO_THREADID_set_pointer does nothing. +OPENSSL_EXPORT void CRYPTO_THREADID_set_pointer(CRYPTO_THREADID *id, void *ptr); + +// CRYPTO_THREADID_current does nothing. +OPENSSL_EXPORT void CRYPTO_THREADID_current(CRYPTO_THREADID *id); + +// CRYPTO_set_id_callback does nothing. +OPENSSL_EXPORT void CRYPTO_set_id_callback(unsigned long (*func)(void)); + +typedef struct { + int references; + struct CRYPTO_dynlock_value *data; +} CRYPTO_dynlock; + +// CRYPTO_set_dynlock_create_callback does nothing. +OPENSSL_EXPORT void CRYPTO_set_dynlock_create_callback( + struct CRYPTO_dynlock_value *(*dyn_create_function)(const char *file, + int line)); + +// CRYPTO_set_dynlock_lock_callback does nothing. +OPENSSL_EXPORT void CRYPTO_set_dynlock_lock_callback(void (*dyn_lock_function)( + int mode, struct CRYPTO_dynlock_value *l, const char *file, int line)); + +// CRYPTO_set_dynlock_destroy_callback does nothing. +OPENSSL_EXPORT void CRYPTO_set_dynlock_destroy_callback( + void (*dyn_destroy_function)(struct CRYPTO_dynlock_value *l, + const char *file, int line)); + +// CRYPTO_get_dynlock_create_callback returns NULL. +OPENSSL_EXPORT struct CRYPTO_dynlock_value *( + *CRYPTO_get_dynlock_create_callback(void))(const char *file, int line); + +// CRYPTO_get_dynlock_lock_callback returns NULL. +OPENSSL_EXPORT void (*CRYPTO_get_dynlock_lock_callback(void))( + int mode, struct CRYPTO_dynlock_value *l, const char *file, int line); + +// CRYPTO_get_dynlock_destroy_callback returns NULL. +OPENSSL_EXPORT void (*CRYPTO_get_dynlock_destroy_callback(void))( + struct CRYPTO_dynlock_value *l, const char *file, int line); + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_THREAD_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/thread.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/thread.h.grpc_back new file mode 100644 index 0000000..98073b0 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/thread.h.grpc_back @@ -0,0 +1,191 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 OPENSSL_HEADER_THREAD_H +#define OPENSSL_HEADER_THREAD_H + +#include + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +#if defined(OPENSSL_NO_THREADS) +typedef struct crypto_mutex_st { + char padding; // Empty structs have different sizes in C and C++. +} CRYPTO_MUTEX; +#elif defined(OPENSSL_WINDOWS) +// CRYPTO_MUTEX can appear in public header files so we really don't want to +// pull in windows.h. It's statically asserted that this structure is large +// enough to contain a Windows SRWLOCK by thread_win.c. +typedef union crypto_mutex_st { + void *handle; +} CRYPTO_MUTEX; +#elif defined(__MACH__) && defined(__APPLE__) +typedef pthread_rwlock_t CRYPTO_MUTEX; +#else +// It is reasonable to include pthread.h on non-Windows systems, however the +// |pthread_rwlock_t| that we need is hidden under feature flags, and we can't +// ensure that we'll be able to get it. It's statically asserted that this +// structure is large enough to contain a |pthread_rwlock_t| by +// thread_pthread.c. +typedef union crypto_mutex_st { + double alignment; + uint8_t padding[3*sizeof(int) + 5*sizeof(unsigned) + 16 + 8]; +} CRYPTO_MUTEX; +#endif + +// CRYPTO_refcount_t is the type of a reference count. +// +// Since some platforms use C11 atomics to access this, it should have the +// _Atomic qualifier. However, this header is included by C++ programs as well +// as C code that might not set -std=c11. So, in practice, it's not possible to +// do that. Instead we statically assert that the size and native alignment of +// a plain uint32_t and an _Atomic uint32_t are equal in refcount_c11.c. +typedef uint32_t CRYPTO_refcount_t; + + +// Deprecated functions. +// +// Historically, OpenSSL required callers to provide locking callbacks. +// BoringSSL is thread-safe by default, but some old code calls these functions +// and so no-op implementations are provided. + +// These defines do nothing but are provided to make old code easier to +// compile. +#define CRYPTO_LOCK 1 +#define CRYPTO_UNLOCK 2 +#define CRYPTO_READ 4 +#define CRYPTO_WRITE 8 + +// CRYPTO_num_locks returns one. (This is non-zero that callers who allocate +// sizeof(lock) times this value don't get zero and then fail because malloc(0) +// returned NULL.) +OPENSSL_EXPORT int CRYPTO_num_locks(void); + +// CRYPTO_set_locking_callback does nothing. +OPENSSL_EXPORT void CRYPTO_set_locking_callback( + void (*func)(int mode, int lock_num, const char *file, int line)); + +// CRYPTO_set_add_lock_callback does nothing. +OPENSSL_EXPORT void CRYPTO_set_add_lock_callback(int (*func)( + int *num, int amount, int lock_num, const char *file, int line)); + +// CRYPTO_get_locking_callback returns NULL. +OPENSSL_EXPORT void (*CRYPTO_get_locking_callback(void))(int mode, int lock_num, + const char *file, + int line); + +// CRYPTO_get_lock_name returns a fixed, dummy string. +OPENSSL_EXPORT const char *CRYPTO_get_lock_name(int lock_num); + +// CRYPTO_THREADID_set_callback returns one. +OPENSSL_EXPORT int CRYPTO_THREADID_set_callback( + void (*threadid_func)(CRYPTO_THREADID *threadid)); + +// CRYPTO_THREADID_set_numeric does nothing. +OPENSSL_EXPORT void CRYPTO_THREADID_set_numeric(CRYPTO_THREADID *id, + unsigned long val); + +// CRYPTO_THREADID_set_pointer does nothing. +OPENSSL_EXPORT void CRYPTO_THREADID_set_pointer(CRYPTO_THREADID *id, void *ptr); + +// CRYPTO_THREADID_current does nothing. +OPENSSL_EXPORT void CRYPTO_THREADID_current(CRYPTO_THREADID *id); + +// CRYPTO_set_id_callback does nothing. +OPENSSL_EXPORT void CRYPTO_set_id_callback(unsigned long (*func)(void)); + +typedef struct { + int references; + struct CRYPTO_dynlock_value *data; +} CRYPTO_dynlock; + +// CRYPTO_set_dynlock_create_callback does nothing. +OPENSSL_EXPORT void CRYPTO_set_dynlock_create_callback( + struct CRYPTO_dynlock_value *(*dyn_create_function)(const char *file, + int line)); + +// CRYPTO_set_dynlock_lock_callback does nothing. +OPENSSL_EXPORT void CRYPTO_set_dynlock_lock_callback(void (*dyn_lock_function)( + int mode, struct CRYPTO_dynlock_value *l, const char *file, int line)); + +// CRYPTO_set_dynlock_destroy_callback does nothing. +OPENSSL_EXPORT void CRYPTO_set_dynlock_destroy_callback( + void (*dyn_destroy_function)(struct CRYPTO_dynlock_value *l, + const char *file, int line)); + +// CRYPTO_get_dynlock_create_callback returns NULL. +OPENSSL_EXPORT struct CRYPTO_dynlock_value *( + *CRYPTO_get_dynlock_create_callback(void))(const char *file, int line); + +// CRYPTO_get_dynlock_lock_callback returns NULL. +OPENSSL_EXPORT void (*CRYPTO_get_dynlock_lock_callback(void))( + int mode, struct CRYPTO_dynlock_value *l, const char *file, int line); + +// CRYPTO_get_dynlock_destroy_callback returns NULL. +OPENSSL_EXPORT void (*CRYPTO_get_dynlock_destroy_callback(void))( + struct CRYPTO_dynlock_value *l, const char *file, int line); + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_THREAD_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/tls1.h b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/tls1.h new file mode 100644 index 0000000..67dbf77 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/tls1.h @@ -0,0 +1,618 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 OPENSSL_HEADER_TLS1_H +#define OPENSSL_HEADER_TLS1_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +#define TLS1_AD_END_OF_EARLY_DATA 1 +#define TLS1_AD_DECRYPTION_FAILED 21 +#define TLS1_AD_RECORD_OVERFLOW 22 +#define TLS1_AD_UNKNOWN_CA 48 +#define TLS1_AD_ACCESS_DENIED 49 +#define TLS1_AD_DECODE_ERROR 50 +#define TLS1_AD_DECRYPT_ERROR 51 +#define TLS1_AD_EXPORT_RESTRICTION 60 +#define TLS1_AD_PROTOCOL_VERSION 70 +#define TLS1_AD_INSUFFICIENT_SECURITY 71 +#define TLS1_AD_INTERNAL_ERROR 80 +#define TLS1_AD_USER_CANCELLED 90 +#define TLS1_AD_NO_RENEGOTIATION 100 +#define TLS1_AD_MISSING_EXTENSION 109 +// 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 +#define TLS1_AD_CERTIFICATE_REQUIRED 116 + +// ExtensionType values from RFC6066 +#define TLSEXT_TYPE_server_name 0 +#define TLSEXT_TYPE_status_request 5 + +// ExtensionType values from RFC4492 +#define TLSEXT_TYPE_ec_point_formats 11 + +// ExtensionType values from RFC5246 +#define TLSEXT_TYPE_signature_algorithms 13 + +// ExtensionType value from RFC5764 +#define TLSEXT_TYPE_srtp 14 + +// ExtensionType value from RFC7301 +#define TLSEXT_TYPE_application_layer_protocol_negotiation 16 + +// ExtensionType value from RFC7685 +#define TLSEXT_TYPE_padding 21 + +// ExtensionType value from RFC7627 +#define TLSEXT_TYPE_extended_master_secret 23 + +// ExtensionType value from draft-ietf-tokbind-negotiation-10 +#define TLSEXT_TYPE_token_binding 24 + +// ExtensionType value from draft-ietf-quic-tls +#define TLSEXT_TYPE_quic_transport_parameters 26 + +// ExtensionType value from RFC4507 +#define TLSEXT_TYPE_session_ticket 35 + +// ExtensionType values from draft-ietf-tls-tls13-18 +#define TLSEXT_TYPE_supported_groups 10 +#define TLSEXT_TYPE_pre_shared_key 41 +#define TLSEXT_TYPE_early_data 42 +#define TLSEXT_TYPE_supported_versions 43 +#define TLSEXT_TYPE_cookie 44 +#define TLSEXT_TYPE_psk_key_exchange_modes 45 +#define TLSEXT_TYPE_certificate_authorities 47 +#define TLSEXT_TYPE_key_share 51 + +// ExtensionType value from RFC5746 +#define TLSEXT_TYPE_renegotiate 0xff01 + +// ExtensionType value from RFC6962 +#define TLSEXT_TYPE_certificate_timestamp 18 + +// This is not an IANA defined extension number +#define TLSEXT_TYPE_next_proto_neg 13172 + +// This is not an IANA defined extension number +#define TLSEXT_TYPE_channel_id 30032 + +// This is not an IANA defined extension number +#define TLSEXT_TYPE_dummy_pq_padding 54537 + +// status request value from RFC 3546 +#define TLSEXT_STATUSTYPE_ocsp 1 + +// ECPointFormat values from RFC 4492 +#define TLSEXT_ECPOINTFORMAT_uncompressed 0 +#define TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime 1 + +// Signature and hash algorithms from RFC 5246 + +#define TLSEXT_signature_anonymous 0 +#define TLSEXT_signature_rsa 1 +#define TLSEXT_signature_dsa 2 +#define TLSEXT_signature_ecdsa 3 + +#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 + +#define TLSEXT_MAXLEN_host_name 255 + +// 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 + +// PSK ciphersuites from RFC 5489 +#define TLS1_CK_ECDHE_PSK_WITH_AES_128_CBC_SHA 0x0300C035 +#define TLS1_CK_ECDHE_PSK_WITH_AES_256_CBC_SHA 0x0300C036 + +// 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 RFC4492 +#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 + +// ChaCha20-Poly1305 cipher suites from RFC 7905. +#define TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 0x0300CCA8 +#define TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 0x0300CCA9 +#define TLS1_CK_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256 0x0300CCAC + +// TLS 1.3 ciphersuites from draft-ietf-tls-tls13-16 +#define TLS1_CK_AES_128_GCM_SHA256 0x03001301 +#define TLS1_CK_AES_256_GCM_SHA384 0x03001302 +#define TLS1_CK_CHACHA20_POLY1305_SHA256 0x03001303 + +// XXX +// Inconsistency alert: +// The OpenSSL names of ciphers with ephemeral DH here include the string +// "DHE", while elsewhere it has always been "EDH". +// (The alias for the list of all such ciphers also is "EDH".) +// The specifications speak of "EDH"; maybe we should allow both forms +// for everything. +#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" + +// PSK ciphersuites from RFC 5489 +#define TLS1_TXT_ECDHE_PSK_WITH_AES_128_CBC_SHA "ECDHE-PSK-AES128-CBC-SHA" +#define TLS1_TXT_ECDHE_PSK_WITH_AES_256_CBC_SHA "ECDHE-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 TLS1_TXT_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 \ + "ECDHE-RSA-CHACHA20-POLY1305" +#define TLS1_TXT_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 \ + "ECDHE-ECDSA-CHACHA20-POLY1305" +#define TLS1_TXT_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256 \ + "ECDHE-PSK-CHACHA20-POLY1305" + +// TLS 1.3 ciphersuites from draft-ietf-tls-tls13-16 +#define TLS1_TXT_AES_128_GCM_SHA256 "AEAD-AES128-GCM-SHA256" +#define TLS1_TXT_AES_256_GCM_SHA384 "AEAD-AES256-GCM-SHA384" +#define TLS1_TXT_CHACHA20_POLY1305_SHA256 "AEAD-CHACHA20-POLY1305-SHA256" + + +#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_MD_MAX_CONST_SIZE 20 + + +#ifdef __cplusplus +} // extern C +#endif + +#endif // OPENSSL_HEADER_TLS1_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/tls1.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/tls1.h.grpc_back new file mode 100644 index 0000000..3424f3d --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/tls1.h.grpc_back @@ -0,0 +1,618 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 OPENSSL_HEADER_TLS1_H +#define OPENSSL_HEADER_TLS1_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +#define TLS1_AD_END_OF_EARLY_DATA 1 +#define TLS1_AD_DECRYPTION_FAILED 21 +#define TLS1_AD_RECORD_OVERFLOW 22 +#define TLS1_AD_UNKNOWN_CA 48 +#define TLS1_AD_ACCESS_DENIED 49 +#define TLS1_AD_DECODE_ERROR 50 +#define TLS1_AD_DECRYPT_ERROR 51 +#define TLS1_AD_EXPORT_RESTRICTION 60 +#define TLS1_AD_PROTOCOL_VERSION 70 +#define TLS1_AD_INSUFFICIENT_SECURITY 71 +#define TLS1_AD_INTERNAL_ERROR 80 +#define TLS1_AD_USER_CANCELLED 90 +#define TLS1_AD_NO_RENEGOTIATION 100 +#define TLS1_AD_MISSING_EXTENSION 109 +// 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 +#define TLS1_AD_CERTIFICATE_REQUIRED 116 + +// ExtensionType values from RFC6066 +#define TLSEXT_TYPE_server_name 0 +#define TLSEXT_TYPE_status_request 5 + +// ExtensionType values from RFC4492 +#define TLSEXT_TYPE_ec_point_formats 11 + +// ExtensionType values from RFC5246 +#define TLSEXT_TYPE_signature_algorithms 13 + +// ExtensionType value from RFC5764 +#define TLSEXT_TYPE_srtp 14 + +// ExtensionType value from RFC7301 +#define TLSEXT_TYPE_application_layer_protocol_negotiation 16 + +// ExtensionType value from RFC7685 +#define TLSEXT_TYPE_padding 21 + +// ExtensionType value from RFC7627 +#define TLSEXT_TYPE_extended_master_secret 23 + +// ExtensionType value from draft-ietf-tokbind-negotiation-10 +#define TLSEXT_TYPE_token_binding 24 + +// ExtensionType value from draft-ietf-quic-tls +#define TLSEXT_TYPE_quic_transport_parameters 26 + +// ExtensionType value from RFC4507 +#define TLSEXT_TYPE_session_ticket 35 + +// ExtensionType values from draft-ietf-tls-tls13-18 +#define TLSEXT_TYPE_supported_groups 10 +#define TLSEXT_TYPE_pre_shared_key 41 +#define TLSEXT_TYPE_early_data 42 +#define TLSEXT_TYPE_supported_versions 43 +#define TLSEXT_TYPE_cookie 44 +#define TLSEXT_TYPE_psk_key_exchange_modes 45 +#define TLSEXT_TYPE_certificate_authorities 47 +#define TLSEXT_TYPE_key_share 51 + +// ExtensionType value from RFC5746 +#define TLSEXT_TYPE_renegotiate 0xff01 + +// ExtensionType value from RFC6962 +#define TLSEXT_TYPE_certificate_timestamp 18 + +// This is not an IANA defined extension number +#define TLSEXT_TYPE_next_proto_neg 13172 + +// This is not an IANA defined extension number +#define TLSEXT_TYPE_channel_id 30032 + +// This is not an IANA defined extension number +#define TLSEXT_TYPE_dummy_pq_padding 54537 + +// status request value from RFC 3546 +#define TLSEXT_STATUSTYPE_ocsp 1 + +// ECPointFormat values from RFC 4492 +#define TLSEXT_ECPOINTFORMAT_uncompressed 0 +#define TLSEXT_ECPOINTFORMAT_ansiX962_compressed_prime 1 + +// Signature and hash algorithms from RFC 5246 + +#define TLSEXT_signature_anonymous 0 +#define TLSEXT_signature_rsa 1 +#define TLSEXT_signature_dsa 2 +#define TLSEXT_signature_ecdsa 3 + +#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 + +#define TLSEXT_MAXLEN_host_name 255 + +// 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 + +// PSK ciphersuites from RFC 5489 +#define TLS1_CK_ECDHE_PSK_WITH_AES_128_CBC_SHA 0x0300C035 +#define TLS1_CK_ECDHE_PSK_WITH_AES_256_CBC_SHA 0x0300C036 + +// 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 RFC4492 +#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 + +// ChaCha20-Poly1305 cipher suites from RFC 7905. +#define TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 0x0300CCA8 +#define TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 0x0300CCA9 +#define TLS1_CK_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256 0x0300CCAC + +// TLS 1.3 ciphersuites from draft-ietf-tls-tls13-16 +#define TLS1_CK_AES_128_GCM_SHA256 0x03001301 +#define TLS1_CK_AES_256_GCM_SHA384 0x03001302 +#define TLS1_CK_CHACHA20_POLY1305_SHA256 0x03001303 + +// XXX +// Inconsistency alert: +// The OpenSSL names of ciphers with ephemeral DH here include the string +// "DHE", while elsewhere it has always been "EDH". +// (The alias for the list of all such ciphers also is "EDH".) +// The specifications speak of "EDH"; maybe we should allow both forms +// for everything. +#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" + +// PSK ciphersuites from RFC 5489 +#define TLS1_TXT_ECDHE_PSK_WITH_AES_128_CBC_SHA "ECDHE-PSK-AES128-CBC-SHA" +#define TLS1_TXT_ECDHE_PSK_WITH_AES_256_CBC_SHA "ECDHE-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 TLS1_TXT_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 \ + "ECDHE-RSA-CHACHA20-POLY1305" +#define TLS1_TXT_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 \ + "ECDHE-ECDSA-CHACHA20-POLY1305" +#define TLS1_TXT_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256 \ + "ECDHE-PSK-CHACHA20-POLY1305" + +// TLS 1.3 ciphersuites from draft-ietf-tls-tls13-16 +#define TLS1_TXT_AES_128_GCM_SHA256 "AEAD-AES128-GCM-SHA256" +#define TLS1_TXT_AES_256_GCM_SHA384 "AEAD-AES256-GCM-SHA384" +#define TLS1_TXT_CHACHA20_POLY1305_SHA256 "AEAD-CHACHA20-POLY1305-SHA256" + + +#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_MD_MAX_CONST_SIZE 20 + + +#ifdef __cplusplus +} // extern C +#endif + +#endif // OPENSSL_HEADER_TLS1_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/type_check.h b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/type_check.h new file mode 100644 index 0000000..928ebca --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/type_check.h @@ -0,0 +1,91 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 OPENSSL_HEADER_TYPE_CHECK_H +#define OPENSSL_HEADER_TYPE_CHECK_H + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// This header file contains some common macros for enforcing type checking. +// Several, common OpenSSL structures (i.e. stack and lhash) operate on void +// pointers, but we wish to have type checking when they are used with a +// specific type. + +// CHECKED_CAST casts |p| from type |from| to type |to|. +#define CHECKED_CAST(to, from, p) ((to) (1 ? (p) : (from)0)) + +// CHECKED_PTR_OF casts a given pointer to void* and statically checks that it +// was a pointer to |type|. +#define CHECKED_PTR_OF(type, p) CHECKED_CAST(void*, type*, (p)) + +#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L +#define OPENSSL_COMPILE_ASSERT(cond, msg) _Static_assert(cond, #msg) +#else +#define OPENSSL_COMPILE_ASSERT(cond, msg) \ + typedef char OPENSSL_COMPILE_ASSERT_##msg[((cond) ? 1 : -1)] OPENSSL_UNUSED +#endif + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_TYPE_CHECK_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/type_check.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/type_check.h.grpc_back new file mode 100644 index 0000000..da78d70 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/type_check.h.grpc_back @@ -0,0 +1,91 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 OPENSSL_HEADER_TYPE_CHECK_H +#define OPENSSL_HEADER_TYPE_CHECK_H + +#include + +#if defined(__cplusplus) +extern "C" { +#endif + + +// This header file contains some common macros for enforcing type checking. +// Several, common OpenSSL structures (i.e. stack and lhash) operate on void +// pointers, but we wish to have type checking when they are used with a +// specific type. + +// CHECKED_CAST casts |p| from type |from| to type |to|. +#define CHECKED_CAST(to, from, p) ((to) (1 ? (p) : (from)0)) + +// CHECKED_PTR_OF casts a given pointer to void* and statically checks that it +// was a pointer to |type|. +#define CHECKED_PTR_OF(type, p) CHECKED_CAST(void*, type*, (p)) + +#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L +#define OPENSSL_COMPILE_ASSERT(cond, msg) _Static_assert(cond, #msg) +#else +#define OPENSSL_COMPILE_ASSERT(cond, msg) \ + typedef char OPENSSL_COMPILE_ASSERT_##msg[((cond) ? 1 : -1)] OPENSSL_UNUSED +#endif + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_TYPE_CHECK_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/umbrella.h b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/umbrella.h new file mode 100644 index 0000000..b61d902 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/umbrella.h @@ -0,0 +1,38 @@ + #include "ssl.h" + #include "crypto.h" + #include "aes.h" + /* The following macros are defined by base.h. The latter is the first file included by the + other headers. */ + #if defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64) + # include "arm_arch.h" + #endif + #include "asn1.h" + #include "asn1_mac.h" + #include "asn1t.h" + #include "blowfish.h" + #include "cast.h" + #include "chacha.h" + #include "cmac.h" + #include "conf.h" + #include "cpu.h" + #include "curve25519.h" + #include "des.h" + #include "dtls1.h" + #include "hkdf.h" + #include "md4.h" + #include "md5.h" + #include "obj_mac.h" + #include "objects.h" + #include "opensslv.h" + #include "ossl_typ.h" + #include "pkcs12.h" + #include "pkcs7.h" + #include "pkcs8.h" + #include "poly1305.h" + #include "rand.h" + #include "rc4.h" + #include "ripemd.h" + #include "safestack.h" + #include "srtp.h" + #include "x509.h" + #include "x509v3.h" diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/umbrella.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/umbrella.h.grpc_back new file mode 100644 index 0000000..b61d902 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/umbrella.h.grpc_back @@ -0,0 +1,38 @@ + #include "ssl.h" + #include "crypto.h" + #include "aes.h" + /* The following macros are defined by base.h. The latter is the first file included by the + other headers. */ + #if defined(OPENSSL_ARM) || defined(OPENSSL_AARCH64) + # include "arm_arch.h" + #endif + #include "asn1.h" + #include "asn1_mac.h" + #include "asn1t.h" + #include "blowfish.h" + #include "cast.h" + #include "chacha.h" + #include "cmac.h" + #include "conf.h" + #include "cpu.h" + #include "curve25519.h" + #include "des.h" + #include "dtls1.h" + #include "hkdf.h" + #include "md4.h" + #include "md5.h" + #include "obj_mac.h" + #include "objects.h" + #include "opensslv.h" + #include "ossl_typ.h" + #include "pkcs12.h" + #include "pkcs7.h" + #include "pkcs8.h" + #include "poly1305.h" + #include "rand.h" + #include "rc4.h" + #include "ripemd.h" + #include "safestack.h" + #include "srtp.h" + #include "x509.h" + #include "x509v3.h" diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/x509.h b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/x509.h new file mode 100644 index 0000000..7276ce6 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/x509.h @@ -0,0 +1,1180 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Legacy X.509 library. + * + * This header is part of OpenSSL's X.509 implementation. It is retained for + * compatibility but otherwise underdocumented and not actively maintained. In + * the future, a replacement library will be available. Meanwhile, minimize + * dependencies on this header where possible. */ + + +#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 + +DEFINE_STACK_OF(X509_ALGOR) +DECLARE_ASN1_SET_OF(X509_ALGOR) + +typedef STACK_OF(X509_ALGOR) X509_ALGORS; + +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; + }; + +struct X509_sig_st + { + X509_ALGOR *algor; + ASN1_OCTET_STRING *digest; + } /* X509_SIG */; + +struct X509_name_entry_st + { + ASN1_OBJECT *object; + ASN1_STRING *value; + int set; + int size; /* temp variable */ + } /* X509_NAME_ENTRY */; + +DEFINE_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 */ + BUF_MEM *bytes; +/* unsigned long hash; Keep the hash around for lookups */ + unsigned char *canon_enc; + int canon_enclen; + } /* X509_NAME */; + +DEFINE_STACK_OF(X509_NAME) + +struct X509_extension_st + { + ASN1_OBJECT *object; + ASN1_BOOLEAN critical; + ASN1_OCTET_STRING *value; + } /* X509_EXTENSION */; + +typedef STACK_OF(X509_EXTENSION) X509_EXTENSIONS; + +DEFINE_STACK_OF(X509_EXTENSION) +DECLARE_ASN1_SET_OF(X509_EXTENSION) + +/* a sequence of these are used */ +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 */; + +DEFINE_STACK_OF(X509_ATTRIBUTE) +DECLARE_ASN1_SET_OF(X509_ATTRIBUTE) + + +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 */; + +struct X509_req_st + { + X509_REQ_INFO *req_info; + X509_ALGOR *sig_alg; + ASN1_BIT_STRING *signature; + CRYPTO_refcount_t references; + } /* X509_REQ */; + +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 + */ + +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 */; + +DECLARE_STACK_OF(DIST_POINT) +DECLARE_STACK_OF(GENERAL_NAME) + +struct x509_st + { + X509_CINF *cert_info; + X509_ALGOR *sig_alg; + ASN1_BIT_STRING *signature; + CRYPTO_refcount_t 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; + unsigned char sha1_hash[SHA_DIGEST_LENGTH]; + X509_CERT_AUX *aux; + CRYPTO_BUFFER *buf; + CRYPTO_MUTEX lock; + } /* X509 */; + +DEFINE_STACK_OF(X509) +DECLARE_ASN1_SET_OF(X509) + +/* This is used for a table of trust checking functions */ + +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 */; + +DEFINE_STACK_OF(X509_TRUST) + +/* 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 */ + }; + +DEFINE_STACK_OF(X509_REVOKED) +DECLARE_ASN1_SET_OF(X509_REVOKED) + +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 */; + +DECLARE_STACK_OF(GENERAL_NAMES) + +struct X509_crl_st + { + /* actual signature */ + X509_CRL_INFO *crl; + X509_ALGOR *sig_alg; + ASN1_BIT_STRING *signature; + CRYPTO_refcount_t 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; + unsigned char sha1_hash[SHA_DIGEST_LENGTH]; + STACK_OF(GENERAL_NAMES) *issuers; + const X509_CRL_METHOD *meth; + void *meth_data; + } /* X509_CRL */; + +DEFINE_STACK_OF(X509_CRL) +DECLARE_ASN1_SET_OF(X509_CRL) + +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; + } /* X509_PKEY */; + +#ifndef OPENSSL_NO_EVP +struct X509_info_st + { + X509 *x509; + X509_CRL *crl; + X509_PKEY *x_pkey; + + EVP_CIPHER_INFO enc_cipher; + int enc_len; + char *enc_data; + + } /* X509_INFO */; + +DEFINE_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 + */ +struct Netscape_spkac_st + { + X509_PUBKEY *pubkey; + ASN1_IA5STRING *challenge; /* challenge sent in atlas >= PR2 */ + } /* NETSCAPE_SPKAC */; + +struct Netscape_spki_st + { + NETSCAPE_SPKAC *spkac; /* signed public key and challenge */ + X509_ALGOR *sig_algor; + ASN1_BIT_STRING *signature; + } /* NETSCAPE_SPKI */; + +/* PKCS#8 private key info structure */ + +struct pkcs8_priv_key_info_st + { + int broken; /* Flag for various broken formats */ +#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; + ASN1_TYPE *pkey; /* Should be OCTET STRING but some are broken */ + STACK_OF(X509_ATTRIBUTE) *attributes; + }; + +#ifdef __cplusplus +} +#endif + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#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_get_cert_info(x) ((x)->cert_info) +#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) + +#define X509_CINF_set_modified(c) ((c)->enc.modified = 1) +#define X509_CINF_get_issuer(c) (&(c)->issuer) +#define X509_CINF_get_extensions(c) ((c)->extensions) +#define X509_CINF_get_signature(c) ((c)->signature) + +OPENSSL_EXPORT void X509_CRL_set_default_method(const X509_CRL_METHOD *meth); +OPENSSL_EXPORT 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)); +OPENSSL_EXPORT void X509_CRL_METHOD_free(X509_CRL_METHOD *m); + +OPENSSL_EXPORT void X509_CRL_set_meth_data(X509_CRL *crl, void *dat); +OPENSSL_EXPORT 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) + + +OPENSSL_EXPORT const char *X509_verify_cert_error_string(long n); + +#ifndef OPENSSL_NO_EVP +OPENSSL_EXPORT int X509_verify(X509 *a, EVP_PKEY *r); + +OPENSSL_EXPORT int X509_REQ_verify(X509_REQ *a, EVP_PKEY *r); +OPENSSL_EXPORT int X509_CRL_verify(X509_CRL *a, EVP_PKEY *r); +OPENSSL_EXPORT int NETSCAPE_SPKI_verify(NETSCAPE_SPKI *a, EVP_PKEY *r); + +OPENSSL_EXPORT NETSCAPE_SPKI * NETSCAPE_SPKI_b64_decode(const char *str, int len); +OPENSSL_EXPORT char * NETSCAPE_SPKI_b64_encode(NETSCAPE_SPKI *x); +OPENSSL_EXPORT EVP_PKEY *NETSCAPE_SPKI_get_pubkey(NETSCAPE_SPKI *x); +OPENSSL_EXPORT int NETSCAPE_SPKI_set_pubkey(NETSCAPE_SPKI *x, EVP_PKEY *pkey); + +OPENSSL_EXPORT int NETSCAPE_SPKI_print(BIO *out, NETSCAPE_SPKI *spki); + +OPENSSL_EXPORT int X509_signature_dump(BIO *bp,const ASN1_STRING *sig, int indent); +OPENSSL_EXPORT int X509_signature_print(BIO *bp, const X509_ALGOR *alg, + const ASN1_STRING *sig); + +OPENSSL_EXPORT int X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md); +OPENSSL_EXPORT int X509_sign_ctx(X509 *x, EVP_MD_CTX *ctx); +OPENSSL_EXPORT int X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md); +OPENSSL_EXPORT int X509_REQ_sign_ctx(X509_REQ *x, EVP_MD_CTX *ctx); +OPENSSL_EXPORT int X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md); +OPENSSL_EXPORT int X509_CRL_sign_ctx(X509_CRL *x, EVP_MD_CTX *ctx); +OPENSSL_EXPORT int NETSCAPE_SPKI_sign(NETSCAPE_SPKI *x, EVP_PKEY *pkey, const EVP_MD *md); + +OPENSSL_EXPORT int X509_pubkey_digest(const X509 *data,const EVP_MD *type, + unsigned char *md, unsigned int *len); +OPENSSL_EXPORT int X509_digest(const X509 *data,const EVP_MD *type, + unsigned char *md, unsigned int *len); +OPENSSL_EXPORT int X509_CRL_digest(const X509_CRL *data,const EVP_MD *type, + unsigned char *md, unsigned int *len); +OPENSSL_EXPORT int X509_REQ_digest(const X509_REQ *data,const EVP_MD *type, + unsigned char *md, unsigned int *len); +OPENSSL_EXPORT int X509_NAME_digest(const X509_NAME *data,const EVP_MD *type, + unsigned char *md, unsigned int *len); +#endif + +/* X509_parse_from_buffer parses an X.509 structure from |buf| and returns a + * fresh X509 or NULL on error. There must not be any trailing data in |buf|. + * The returned structure (if any) holds a reference to |buf| rather than + * copying parts of it as a normal |d2i_X509| call would do. */ +OPENSSL_EXPORT X509 *X509_parse_from_buffer(CRYPTO_BUFFER *buf); + +#ifndef OPENSSL_NO_FP_API +OPENSSL_EXPORT X509 *d2i_X509_fp(FILE *fp, X509 **x509); +OPENSSL_EXPORT int i2d_X509_fp(FILE *fp,X509 *x509); +OPENSSL_EXPORT X509_CRL *d2i_X509_CRL_fp(FILE *fp,X509_CRL **crl); +OPENSSL_EXPORT int i2d_X509_CRL_fp(FILE *fp,X509_CRL *crl); +OPENSSL_EXPORT X509_REQ *d2i_X509_REQ_fp(FILE *fp,X509_REQ **req); +OPENSSL_EXPORT int i2d_X509_REQ_fp(FILE *fp,X509_REQ *req); +OPENSSL_EXPORT RSA *d2i_RSAPrivateKey_fp(FILE *fp,RSA **rsa); +OPENSSL_EXPORT int i2d_RSAPrivateKey_fp(FILE *fp,RSA *rsa); +OPENSSL_EXPORT RSA *d2i_RSAPublicKey_fp(FILE *fp,RSA **rsa); +OPENSSL_EXPORT int i2d_RSAPublicKey_fp(FILE *fp,RSA *rsa); +OPENSSL_EXPORT RSA *d2i_RSA_PUBKEY_fp(FILE *fp,RSA **rsa); +OPENSSL_EXPORT int i2d_RSA_PUBKEY_fp(FILE *fp,RSA *rsa); +#ifndef OPENSSL_NO_DSA +OPENSSL_EXPORT DSA *d2i_DSA_PUBKEY_fp(FILE *fp, DSA **dsa); +OPENSSL_EXPORT int i2d_DSA_PUBKEY_fp(FILE *fp, DSA *dsa); +OPENSSL_EXPORT DSA *d2i_DSAPrivateKey_fp(FILE *fp, DSA **dsa); +OPENSSL_EXPORT int i2d_DSAPrivateKey_fp(FILE *fp, DSA *dsa); +#endif +OPENSSL_EXPORT EC_KEY *d2i_EC_PUBKEY_fp(FILE *fp, EC_KEY **eckey); +OPENSSL_EXPORT int i2d_EC_PUBKEY_fp(FILE *fp, EC_KEY *eckey); +OPENSSL_EXPORT EC_KEY *d2i_ECPrivateKey_fp(FILE *fp, EC_KEY **eckey); +OPENSSL_EXPORT int i2d_ECPrivateKey_fp(FILE *fp, EC_KEY *eckey); +OPENSSL_EXPORT X509_SIG *d2i_PKCS8_fp(FILE *fp,X509_SIG **p8); +OPENSSL_EXPORT int i2d_PKCS8_fp(FILE *fp,X509_SIG *p8); +OPENSSL_EXPORT PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_fp(FILE *fp, + PKCS8_PRIV_KEY_INFO **p8inf); +OPENSSL_EXPORT int i2d_PKCS8_PRIV_KEY_INFO_fp(FILE *fp,PKCS8_PRIV_KEY_INFO *p8inf); +OPENSSL_EXPORT int i2d_PKCS8PrivateKeyInfo_fp(FILE *fp, EVP_PKEY *key); +OPENSSL_EXPORT int i2d_PrivateKey_fp(FILE *fp, EVP_PKEY *pkey); +OPENSSL_EXPORT EVP_PKEY *d2i_PrivateKey_fp(FILE *fp, EVP_PKEY **a); +OPENSSL_EXPORT int i2d_PUBKEY_fp(FILE *fp, EVP_PKEY *pkey); +OPENSSL_EXPORT EVP_PKEY *d2i_PUBKEY_fp(FILE *fp, EVP_PKEY **a); +#endif + +OPENSSL_EXPORT X509 *d2i_X509_bio(BIO *bp,X509 **x509); +OPENSSL_EXPORT int i2d_X509_bio(BIO *bp,X509 *x509); +OPENSSL_EXPORT X509_CRL *d2i_X509_CRL_bio(BIO *bp,X509_CRL **crl); +OPENSSL_EXPORT int i2d_X509_CRL_bio(BIO *bp,X509_CRL *crl); +OPENSSL_EXPORT X509_REQ *d2i_X509_REQ_bio(BIO *bp,X509_REQ **req); +OPENSSL_EXPORT int i2d_X509_REQ_bio(BIO *bp,X509_REQ *req); +OPENSSL_EXPORT RSA *d2i_RSAPrivateKey_bio(BIO *bp,RSA **rsa); +OPENSSL_EXPORT int i2d_RSAPrivateKey_bio(BIO *bp,RSA *rsa); +OPENSSL_EXPORT RSA *d2i_RSAPublicKey_bio(BIO *bp,RSA **rsa); +OPENSSL_EXPORT int i2d_RSAPublicKey_bio(BIO *bp,RSA *rsa); +OPENSSL_EXPORT RSA *d2i_RSA_PUBKEY_bio(BIO *bp,RSA **rsa); +OPENSSL_EXPORT int i2d_RSA_PUBKEY_bio(BIO *bp,RSA *rsa); +#ifndef OPENSSL_NO_DSA +OPENSSL_EXPORT DSA *d2i_DSA_PUBKEY_bio(BIO *bp, DSA **dsa); +OPENSSL_EXPORT int i2d_DSA_PUBKEY_bio(BIO *bp, DSA *dsa); +OPENSSL_EXPORT DSA *d2i_DSAPrivateKey_bio(BIO *bp, DSA **dsa); +OPENSSL_EXPORT int i2d_DSAPrivateKey_bio(BIO *bp, DSA *dsa); +#endif +OPENSSL_EXPORT EC_KEY *d2i_EC_PUBKEY_bio(BIO *bp, EC_KEY **eckey); +OPENSSL_EXPORT int i2d_EC_PUBKEY_bio(BIO *bp, EC_KEY *eckey); +OPENSSL_EXPORT EC_KEY *d2i_ECPrivateKey_bio(BIO *bp, EC_KEY **eckey); +OPENSSL_EXPORT int i2d_ECPrivateKey_bio(BIO *bp, EC_KEY *eckey); +OPENSSL_EXPORT X509_SIG *d2i_PKCS8_bio(BIO *bp,X509_SIG **p8); +OPENSSL_EXPORT int i2d_PKCS8_bio(BIO *bp,X509_SIG *p8); +OPENSSL_EXPORT PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_bio(BIO *bp, + PKCS8_PRIV_KEY_INFO **p8inf); +OPENSSL_EXPORT int i2d_PKCS8_PRIV_KEY_INFO_bio(BIO *bp,PKCS8_PRIV_KEY_INFO *p8inf); +OPENSSL_EXPORT int i2d_PKCS8PrivateKeyInfo_bio(BIO *bp, EVP_PKEY *key); +OPENSSL_EXPORT int i2d_PrivateKey_bio(BIO *bp, EVP_PKEY *pkey); +OPENSSL_EXPORT EVP_PKEY *d2i_PrivateKey_bio(BIO *bp, EVP_PKEY **a); +OPENSSL_EXPORT int i2d_PUBKEY_bio(BIO *bp, EVP_PKEY *pkey); +OPENSSL_EXPORT EVP_PKEY *d2i_PUBKEY_bio(BIO *bp, EVP_PKEY **a); + +OPENSSL_EXPORT X509 *X509_dup(X509 *x509); +OPENSSL_EXPORT X509_ATTRIBUTE *X509_ATTRIBUTE_dup(X509_ATTRIBUTE *xa); +OPENSSL_EXPORT X509_EXTENSION *X509_EXTENSION_dup(X509_EXTENSION *ex); +OPENSSL_EXPORT X509_CRL *X509_CRL_dup(X509_CRL *crl); +OPENSSL_EXPORT X509_REVOKED *X509_REVOKED_dup(X509_REVOKED *rev); +OPENSSL_EXPORT X509_REQ *X509_REQ_dup(X509_REQ *req); +OPENSSL_EXPORT X509_ALGOR *X509_ALGOR_dup(X509_ALGOR *xn); +OPENSSL_EXPORT int X509_ALGOR_set0(X509_ALGOR *alg, const ASN1_OBJECT *aobj, int ptype, void *pval); +OPENSSL_EXPORT void X509_ALGOR_get0(const ASN1_OBJECT **paobj, int *pptype, + const void **ppval, + const X509_ALGOR *algor); +OPENSSL_EXPORT void X509_ALGOR_set_md(X509_ALGOR *alg, const EVP_MD *md); +OPENSSL_EXPORT int X509_ALGOR_cmp(const X509_ALGOR *a, const X509_ALGOR *b); + +OPENSSL_EXPORT X509_NAME *X509_NAME_dup(X509_NAME *xn); +OPENSSL_EXPORT X509_NAME_ENTRY *X509_NAME_ENTRY_dup(X509_NAME_ENTRY *ne); +OPENSSL_EXPORT int X509_NAME_ENTRY_set(const X509_NAME_ENTRY *ne); + +OPENSSL_EXPORT int X509_NAME_get0_der(X509_NAME *nm, const unsigned char **pder, + size_t *pderlen); + +OPENSSL_EXPORT int X509_cmp_time(const ASN1_TIME *s, time_t *t); +OPENSSL_EXPORT int X509_cmp_current_time(const ASN1_TIME *s); +OPENSSL_EXPORT ASN1_TIME * X509_time_adj(ASN1_TIME *s, long adj, time_t *t); +OPENSSL_EXPORT ASN1_TIME * X509_time_adj_ex(ASN1_TIME *s, int offset_day, long offset_sec, time_t *t); +OPENSSL_EXPORT ASN1_TIME * X509_gmtime_adj(ASN1_TIME *s, long adj); + +OPENSSL_EXPORT const char * X509_get_default_cert_area(void ); +OPENSSL_EXPORT const char * X509_get_default_cert_dir(void ); +OPENSSL_EXPORT const char * X509_get_default_cert_file(void ); +OPENSSL_EXPORT const char * X509_get_default_cert_dir_env(void ); +OPENSSL_EXPORT const char * X509_get_default_cert_file_env(void ); +OPENSSL_EXPORT const char * X509_get_default_private_dir(void ); + +OPENSSL_EXPORT X509_REQ * X509_to_X509_REQ(X509 *x, EVP_PKEY *pkey, const EVP_MD *md); +OPENSSL_EXPORT X509 * X509_REQ_to_X509(X509_REQ *r, int days,EVP_PKEY *pkey); + +DECLARE_ASN1_ENCODE_FUNCTIONS(X509_ALGORS, X509_ALGORS, X509_ALGORS) +DECLARE_ASN1_FUNCTIONS(X509_VAL) + +DECLARE_ASN1_FUNCTIONS(X509_PUBKEY) + +OPENSSL_EXPORT int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey); +OPENSSL_EXPORT EVP_PKEY * X509_PUBKEY_get(X509_PUBKEY *key); +OPENSSL_EXPORT int i2d_PUBKEY(const EVP_PKEY *a,unsigned char **pp); +OPENSSL_EXPORT EVP_PKEY * d2i_PUBKEY(EVP_PKEY **a,const unsigned char **pp, + long length); +OPENSSL_EXPORT int i2d_RSA_PUBKEY(const RSA *a,unsigned char **pp); +OPENSSL_EXPORT RSA * d2i_RSA_PUBKEY(RSA **a,const unsigned char **pp, + long length); +#ifndef OPENSSL_NO_DSA +OPENSSL_EXPORT int i2d_DSA_PUBKEY(const DSA *a,unsigned char **pp); +OPENSSL_EXPORT DSA * d2i_DSA_PUBKEY(DSA **a,const unsigned char **pp, + long length); +#endif +OPENSSL_EXPORT int i2d_EC_PUBKEY(const EC_KEY *a, unsigned char **pp); +OPENSSL_EXPORT EC_KEY *d2i_EC_PUBKEY(EC_KEY **a, const unsigned char **pp, + long length); + +DECLARE_ASN1_FUNCTIONS(X509_SIG) +DECLARE_ASN1_FUNCTIONS(X509_REQ_INFO) +DECLARE_ASN1_FUNCTIONS(X509_REQ) + +DECLARE_ASN1_FUNCTIONS(X509_ATTRIBUTE) +OPENSSL_EXPORT 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) + +OPENSSL_EXPORT 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) + +/* X509_up_ref adds one to the reference count of |x| and returns one. */ +OPENSSL_EXPORT int X509_up_ref(X509 *x); + +OPENSSL_EXPORT int X509_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused *unused, + CRYPTO_EX_dup *dup_unused, CRYPTO_EX_free *free_func); +OPENSSL_EXPORT int X509_set_ex_data(X509 *r, int idx, void *arg); +OPENSSL_EXPORT void *X509_get_ex_data(X509 *r, int idx); +OPENSSL_EXPORT int i2d_X509_AUX(X509 *a,unsigned char **pp); +OPENSSL_EXPORT X509 * d2i_X509_AUX(X509 **a,const unsigned char **pp,long length); + +OPENSSL_EXPORT void X509_get0_signature(const ASN1_BIT_STRING **psig, + const X509_ALGOR **palg, const X509 *x); +OPENSSL_EXPORT int X509_get_signature_nid(const X509 *x); + +OPENSSL_EXPORT int X509_alias_set1(X509 *x, unsigned char *name, int len); +OPENSSL_EXPORT int X509_keyid_set1(X509 *x, unsigned char *id, int len); +OPENSSL_EXPORT unsigned char * X509_alias_get0(X509 *x, int *len); +OPENSSL_EXPORT unsigned char * X509_keyid_get0(X509 *x, int *len); +OPENSSL_EXPORT int (*X509_TRUST_set_default(int (*trust)(int , X509 *, int)))(int, X509 *, int); +OPENSSL_EXPORT int X509_TRUST_set(int *t, int trust); +OPENSSL_EXPORT int X509_add1_trust_object(X509 *x, ASN1_OBJECT *obj); +OPENSSL_EXPORT int X509_add1_reject_object(X509 *x, ASN1_OBJECT *obj); +OPENSSL_EXPORT void X509_trust_clear(X509 *x); +OPENSSL_EXPORT void X509_reject_clear(X509 *x); + +DECLARE_ASN1_FUNCTIONS(X509_REVOKED) +DECLARE_ASN1_FUNCTIONS(X509_CRL_INFO) +DECLARE_ASN1_FUNCTIONS(X509_CRL) + +OPENSSL_EXPORT int X509_CRL_add0_revoked(X509_CRL *crl, X509_REVOKED *rev); +OPENSSL_EXPORT int X509_CRL_get0_by_serial(X509_CRL *crl, + X509_REVOKED **ret, ASN1_INTEGER *serial); +OPENSSL_EXPORT int X509_CRL_get0_by_cert(X509_CRL *crl, X509_REVOKED **ret, X509 *x); + +OPENSSL_EXPORT X509_PKEY * X509_PKEY_new(void ); +OPENSSL_EXPORT void X509_PKEY_free(X509_PKEY *a); + +DECLARE_ASN1_FUNCTIONS(NETSCAPE_SPKI) +DECLARE_ASN1_FUNCTIONS(NETSCAPE_SPKAC) + +#ifndef OPENSSL_NO_EVP +OPENSSL_EXPORT X509_INFO * X509_INFO_new(void); +OPENSSL_EXPORT void X509_INFO_free(X509_INFO *a); +OPENSSL_EXPORT char * X509_NAME_oneline(X509_NAME *a,char *buf,int size); + +OPENSSL_EXPORT int ASN1_digest(i2d_of_void *i2d,const EVP_MD *type,char *data, + unsigned char *md,unsigned int *len); + +OPENSSL_EXPORT int ASN1_item_digest(const ASN1_ITEM *it,const EVP_MD *type,void *data, + unsigned char *md,unsigned int *len); + +OPENSSL_EXPORT int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *algor1, + ASN1_BIT_STRING *signature,void *data,EVP_PKEY *pkey); + +OPENSSL_EXPORT 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); +OPENSSL_EXPORT 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 + +OPENSSL_EXPORT int X509_set_version(X509 *x,long version); +OPENSSL_EXPORT int X509_set_serialNumber(X509 *x, ASN1_INTEGER *serial); +OPENSSL_EXPORT ASN1_INTEGER * X509_get_serialNumber(X509 *x); +OPENSSL_EXPORT int X509_set_issuer_name(X509 *x, X509_NAME *name); +OPENSSL_EXPORT X509_NAME * X509_get_issuer_name(X509 *a); +OPENSSL_EXPORT int X509_set_subject_name(X509 *x, X509_NAME *name); +OPENSSL_EXPORT X509_NAME * X509_get_subject_name(X509 *a); +OPENSSL_EXPORT int X509_set_notBefore(X509 *x, const ASN1_TIME *tm); +OPENSSL_EXPORT const ASN1_TIME *X509_get0_notBefore(const X509 *x); +OPENSSL_EXPORT int X509_set_notAfter(X509 *x, const ASN1_TIME *tm); +OPENSSL_EXPORT const ASN1_TIME *X509_get0_notAfter(const X509 *x); +OPENSSL_EXPORT int X509_set_pubkey(X509 *x, EVP_PKEY *pkey); +OPENSSL_EXPORT EVP_PKEY * X509_get_pubkey(X509 *x); +OPENSSL_EXPORT ASN1_BIT_STRING * X509_get0_pubkey_bitstr(const X509 *x); +OPENSSL_EXPORT STACK_OF(X509_EXTENSION) *X509_get0_extensions(const X509 *x); + +OPENSSL_EXPORT int X509_REQ_set_version(X509_REQ *x,long version); +OPENSSL_EXPORT int X509_REQ_set_subject_name(X509_REQ *req,X509_NAME *name); +OPENSSL_EXPORT int X509_REQ_set_pubkey(X509_REQ *x, EVP_PKEY *pkey); +OPENSSL_EXPORT EVP_PKEY * X509_REQ_get_pubkey(X509_REQ *req); +OPENSSL_EXPORT int X509_REQ_extension_nid(int nid); +OPENSSL_EXPORT const int * X509_REQ_get_extension_nids(void); +OPENSSL_EXPORT void X509_REQ_set_extension_nids(const int *nids); +OPENSSL_EXPORT STACK_OF(X509_EXTENSION) *X509_REQ_get_extensions(X509_REQ *req); +OPENSSL_EXPORT int X509_REQ_add_extensions_nid(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts, + int nid); +OPENSSL_EXPORT int X509_REQ_add_extensions(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts); +OPENSSL_EXPORT int X509_REQ_get_attr_count(const X509_REQ *req); +OPENSSL_EXPORT int X509_REQ_get_attr_by_NID(const X509_REQ *req, int nid, + int lastpos); +OPENSSL_EXPORT int X509_REQ_get_attr_by_OBJ(const X509_REQ *req, ASN1_OBJECT *obj, + int lastpos); +OPENSSL_EXPORT X509_ATTRIBUTE *X509_REQ_get_attr(const X509_REQ *req, int loc); +OPENSSL_EXPORT X509_ATTRIBUTE *X509_REQ_delete_attr(X509_REQ *req, int loc); +OPENSSL_EXPORT int X509_REQ_add1_attr(X509_REQ *req, X509_ATTRIBUTE *attr); +OPENSSL_EXPORT int X509_REQ_add1_attr_by_OBJ(X509_REQ *req, + const ASN1_OBJECT *obj, int type, + const unsigned char *bytes, int len); +OPENSSL_EXPORT int X509_REQ_add1_attr_by_NID(X509_REQ *req, + int nid, int type, + const unsigned char *bytes, int len); +OPENSSL_EXPORT int X509_REQ_add1_attr_by_txt(X509_REQ *req, + const char *attrname, int type, + const unsigned char *bytes, int len); + +OPENSSL_EXPORT int X509_CRL_set_version(X509_CRL *x, long version); +OPENSSL_EXPORT int X509_CRL_set_issuer_name(X509_CRL *x, X509_NAME *name); +OPENSSL_EXPORT int X509_CRL_set_lastUpdate(X509_CRL *x, const ASN1_TIME *tm); +OPENSSL_EXPORT int X509_CRL_set_nextUpdate(X509_CRL *x, const ASN1_TIME *tm); +OPENSSL_EXPORT int X509_CRL_sort(X509_CRL *crl); +OPENSSL_EXPORT int X509_CRL_up_ref(X509_CRL *crl); + +OPENSSL_EXPORT int X509_REVOKED_set_serialNumber(X509_REVOKED *x, ASN1_INTEGER *serial); +OPENSSL_EXPORT int X509_REVOKED_set_revocationDate(X509_REVOKED *r, ASN1_TIME *tm); + +OPENSSL_EXPORT X509_CRL *X509_CRL_diff(X509_CRL *base, X509_CRL *newer, + EVP_PKEY *skey, const EVP_MD *md, unsigned int flags); + +OPENSSL_EXPORT int X509_REQ_check_private_key(X509_REQ *x509,EVP_PKEY *pkey); + +OPENSSL_EXPORT int X509_check_private_key(X509 *x509,EVP_PKEY *pkey); +OPENSSL_EXPORT int X509_chain_check_suiteb(int *perror_depth, + X509 *x, STACK_OF(X509) *chain, + unsigned long flags); +OPENSSL_EXPORT int X509_CRL_check_suiteb(X509_CRL *crl, EVP_PKEY *pk, + unsigned long flags); +OPENSSL_EXPORT STACK_OF(X509) *X509_chain_up_ref(STACK_OF(X509) *chain); + +OPENSSL_EXPORT int X509_issuer_and_serial_cmp(const X509 *a, const X509 *b); +OPENSSL_EXPORT unsigned long X509_issuer_and_serial_hash(X509 *a); + +OPENSSL_EXPORT int X509_issuer_name_cmp(const X509 *a, const X509 *b); +OPENSSL_EXPORT unsigned long X509_issuer_name_hash(X509 *a); + +OPENSSL_EXPORT int X509_subject_name_cmp(const X509 *a, const X509 *b); +OPENSSL_EXPORT unsigned long X509_subject_name_hash(X509 *x); + +OPENSSL_EXPORT unsigned long X509_issuer_name_hash_old(X509 *a); +OPENSSL_EXPORT unsigned long X509_subject_name_hash_old(X509 *x); + +OPENSSL_EXPORT int X509_cmp(const X509 *a, const X509 *b); +OPENSSL_EXPORT int X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b); +OPENSSL_EXPORT unsigned long X509_NAME_hash(X509_NAME *x); +OPENSSL_EXPORT unsigned long X509_NAME_hash_old(X509_NAME *x); + +OPENSSL_EXPORT int X509_CRL_cmp(const X509_CRL *a, const X509_CRL *b); +OPENSSL_EXPORT int X509_CRL_match(const X509_CRL *a, const X509_CRL *b); +#ifndef OPENSSL_NO_FP_API +OPENSSL_EXPORT int X509_print_ex_fp(FILE *bp,X509 *x, unsigned long nmflag, unsigned long cflag); +OPENSSL_EXPORT int X509_print_fp(FILE *bp,X509 *x); +OPENSSL_EXPORT int X509_CRL_print_fp(FILE *bp,X509_CRL *x); +OPENSSL_EXPORT int X509_REQ_print_fp(FILE *bp,X509_REQ *req); +OPENSSL_EXPORT int X509_NAME_print_ex_fp(FILE *fp, X509_NAME *nm, int indent, unsigned long flags); +#endif + +OPENSSL_EXPORT int X509_NAME_print(BIO *bp, X509_NAME *name, int obase); +OPENSSL_EXPORT int X509_NAME_print_ex(BIO *out, X509_NAME *nm, int indent, unsigned long flags); +OPENSSL_EXPORT int X509_print_ex(BIO *bp,X509 *x, unsigned long nmflag, unsigned long cflag); +OPENSSL_EXPORT int X509_print(BIO *bp,X509 *x); +OPENSSL_EXPORT int X509_ocspid_print(BIO *bp,X509 *x); +OPENSSL_EXPORT int X509_CERT_AUX_print(BIO *bp,X509_CERT_AUX *x, int indent); +OPENSSL_EXPORT int X509_CRL_print(BIO *bp,X509_CRL *x); +OPENSSL_EXPORT int X509_REQ_print_ex(BIO *bp, X509_REQ *x, unsigned long nmflag, unsigned long cflag); +OPENSSL_EXPORT int X509_REQ_print(BIO *bp,X509_REQ *req); + +OPENSSL_EXPORT int X509_NAME_entry_count(X509_NAME *name); +OPENSSL_EXPORT int X509_NAME_get_text_by_NID(X509_NAME *name, int nid, + char *buf,int len); +OPENSSL_EXPORT int X509_NAME_get_text_by_OBJ(X509_NAME *name, const 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. */ +OPENSSL_EXPORT int X509_NAME_get_index_by_NID(X509_NAME *name,int nid,int lastpos); +OPENSSL_EXPORT int X509_NAME_get_index_by_OBJ(X509_NAME *name, const ASN1_OBJECT *obj, + int lastpos); +OPENSSL_EXPORT X509_NAME_ENTRY *X509_NAME_get_entry(X509_NAME *name, int loc); +OPENSSL_EXPORT X509_NAME_ENTRY *X509_NAME_delete_entry(X509_NAME *name, int loc); +OPENSSL_EXPORT int X509_NAME_add_entry(X509_NAME *name,X509_NAME_ENTRY *ne, + int loc, int set); +OPENSSL_EXPORT int X509_NAME_add_entry_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj, int type, + unsigned char *bytes, int len, int loc, int set); +OPENSSL_EXPORT int X509_NAME_add_entry_by_NID(X509_NAME *name, int nid, int type, + unsigned char *bytes, int len, int loc, int set); +OPENSSL_EXPORT X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_txt(X509_NAME_ENTRY **ne, + const char *field, int type, const unsigned char *bytes, int len); +OPENSSL_EXPORT X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_NID(X509_NAME_ENTRY **ne, int nid, + int type,unsigned char *bytes, int len); +OPENSSL_EXPORT 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); +OPENSSL_EXPORT X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_OBJ(X509_NAME_ENTRY **ne, + const ASN1_OBJECT *obj, int type,const unsigned char *bytes, + int len); +OPENSSL_EXPORT int X509_NAME_ENTRY_set_object(X509_NAME_ENTRY *ne, + const ASN1_OBJECT *obj); +OPENSSL_EXPORT int X509_NAME_ENTRY_set_data(X509_NAME_ENTRY *ne, int type, + const unsigned char *bytes, int len); +OPENSSL_EXPORT ASN1_OBJECT * X509_NAME_ENTRY_get_object(X509_NAME_ENTRY *ne); +OPENSSL_EXPORT ASN1_STRING * X509_NAME_ENTRY_get_data(X509_NAME_ENTRY *ne); + +OPENSSL_EXPORT int X509v3_get_ext_count(const STACK_OF(X509_EXTENSION) *x); +OPENSSL_EXPORT int X509v3_get_ext_by_NID(const STACK_OF(X509_EXTENSION) *x, + int nid, int lastpos); +OPENSSL_EXPORT int X509v3_get_ext_by_OBJ(const STACK_OF(X509_EXTENSION) *x, + const ASN1_OBJECT *obj,int lastpos); +OPENSSL_EXPORT int X509v3_get_ext_by_critical(const STACK_OF(X509_EXTENSION) *x, + int crit, int lastpos); +OPENSSL_EXPORT X509_EXTENSION *X509v3_get_ext(const STACK_OF(X509_EXTENSION) *x, int loc); +OPENSSL_EXPORT X509_EXTENSION *X509v3_delete_ext(STACK_OF(X509_EXTENSION) *x, int loc); +OPENSSL_EXPORT STACK_OF(X509_EXTENSION) *X509v3_add_ext(STACK_OF(X509_EXTENSION) **x, + X509_EXTENSION *ex, int loc); + +OPENSSL_EXPORT int X509_get_ext_count(X509 *x); +OPENSSL_EXPORT int X509_get_ext_by_NID(X509 *x, int nid, int lastpos); +OPENSSL_EXPORT int X509_get_ext_by_OBJ(X509 *x,ASN1_OBJECT *obj,int lastpos); +OPENSSL_EXPORT int X509_get_ext_by_critical(X509 *x, int crit, int lastpos); +OPENSSL_EXPORT X509_EXTENSION *X509_get_ext(X509 *x, int loc); +OPENSSL_EXPORT X509_EXTENSION *X509_delete_ext(X509 *x, int loc); +OPENSSL_EXPORT int X509_add_ext(X509 *x, X509_EXTENSION *ex, int loc); +OPENSSL_EXPORT void * X509_get_ext_d2i(X509 *x, int nid, int *crit, int *idx); +OPENSSL_EXPORT int X509_add1_ext_i2d(X509 *x, int nid, void *value, int crit, + unsigned long flags); + +OPENSSL_EXPORT int X509_CRL_get_ext_count(X509_CRL *x); +OPENSSL_EXPORT int X509_CRL_get_ext_by_NID(X509_CRL *x, int nid, int lastpos); +OPENSSL_EXPORT int X509_CRL_get_ext_by_OBJ(X509_CRL *x,ASN1_OBJECT *obj,int lastpos); +OPENSSL_EXPORT int X509_CRL_get_ext_by_critical(X509_CRL *x, int crit, int lastpos); +OPENSSL_EXPORT X509_EXTENSION *X509_CRL_get_ext(X509_CRL *x, int loc); +OPENSSL_EXPORT X509_EXTENSION *X509_CRL_delete_ext(X509_CRL *x, int loc); +OPENSSL_EXPORT int X509_CRL_add_ext(X509_CRL *x, X509_EXTENSION *ex, int loc); +OPENSSL_EXPORT void * X509_CRL_get_ext_d2i(X509_CRL *x, int nid, int *crit, int *idx); +OPENSSL_EXPORT int X509_CRL_add1_ext_i2d(X509_CRL *x, int nid, void *value, int crit, + unsigned long flags); + +OPENSSL_EXPORT int X509_REVOKED_get_ext_count(X509_REVOKED *x); +OPENSSL_EXPORT int X509_REVOKED_get_ext_by_NID(X509_REVOKED *x, int nid, int lastpos); +OPENSSL_EXPORT int X509_REVOKED_get_ext_by_OBJ(X509_REVOKED *x,ASN1_OBJECT *obj,int lastpos); +OPENSSL_EXPORT int X509_REVOKED_get_ext_by_critical(X509_REVOKED *x, int crit, int lastpos); +OPENSSL_EXPORT X509_EXTENSION *X509_REVOKED_get_ext(X509_REVOKED *x, int loc); +OPENSSL_EXPORT X509_EXTENSION *X509_REVOKED_delete_ext(X509_REVOKED *x, int loc); +OPENSSL_EXPORT int X509_REVOKED_add_ext(X509_REVOKED *x, X509_EXTENSION *ex, int loc); +OPENSSL_EXPORT void * X509_REVOKED_get_ext_d2i(X509_REVOKED *x, int nid, int *crit, int *idx); +OPENSSL_EXPORT int X509_REVOKED_add1_ext_i2d(X509_REVOKED *x, int nid, void *value, int crit, + unsigned long flags); + +OPENSSL_EXPORT X509_EXTENSION *X509_EXTENSION_create_by_NID(X509_EXTENSION **ex, + int nid, int crit, ASN1_OCTET_STRING *data); +OPENSSL_EXPORT X509_EXTENSION *X509_EXTENSION_create_by_OBJ(X509_EXTENSION **ex, + const ASN1_OBJECT *obj,int crit,ASN1_OCTET_STRING *data); +OPENSSL_EXPORT int X509_EXTENSION_set_object(X509_EXTENSION *ex,const ASN1_OBJECT *obj); +OPENSSL_EXPORT int X509_EXTENSION_set_critical(X509_EXTENSION *ex, int crit); +OPENSSL_EXPORT int X509_EXTENSION_set_data(X509_EXTENSION *ex, + ASN1_OCTET_STRING *data); +OPENSSL_EXPORT ASN1_OBJECT * X509_EXTENSION_get_object(X509_EXTENSION *ex); +OPENSSL_EXPORT ASN1_OCTET_STRING *X509_EXTENSION_get_data(X509_EXTENSION *ne); +OPENSSL_EXPORT int X509_EXTENSION_get_critical(X509_EXTENSION *ex); + +OPENSSL_EXPORT int X509at_get_attr_count(const STACK_OF(X509_ATTRIBUTE) *x); +OPENSSL_EXPORT int X509at_get_attr_by_NID(const STACK_OF(X509_ATTRIBUTE) *x, int nid, + int lastpos); +OPENSSL_EXPORT int X509at_get_attr_by_OBJ(const STACK_OF(X509_ATTRIBUTE) *sk, const ASN1_OBJECT *obj, + int lastpos); +OPENSSL_EXPORT X509_ATTRIBUTE *X509at_get_attr(const STACK_OF(X509_ATTRIBUTE) *x, int loc); +OPENSSL_EXPORT X509_ATTRIBUTE *X509at_delete_attr(STACK_OF(X509_ATTRIBUTE) *x, int loc); +OPENSSL_EXPORT STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr(STACK_OF(X509_ATTRIBUTE) **x, + X509_ATTRIBUTE *attr); +OPENSSL_EXPORT 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); +OPENSSL_EXPORT STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_NID(STACK_OF(X509_ATTRIBUTE) **x, + int nid, int type, + const unsigned char *bytes, int len); +OPENSSL_EXPORT 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); +OPENSSL_EXPORT void *X509at_get0_data_by_OBJ(STACK_OF(X509_ATTRIBUTE) *x, + ASN1_OBJECT *obj, int lastpos, int type); +OPENSSL_EXPORT X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_NID(X509_ATTRIBUTE **attr, int nid, + int atrtype, const void *data, int len); +OPENSSL_EXPORT X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_OBJ(X509_ATTRIBUTE **attr, + const ASN1_OBJECT *obj, int atrtype, const void *data, int len); +OPENSSL_EXPORT X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_txt(X509_ATTRIBUTE **attr, + const char *atrname, int type, const unsigned char *bytes, int len); +OPENSSL_EXPORT int X509_ATTRIBUTE_set1_object(X509_ATTRIBUTE *attr, const ASN1_OBJECT *obj); +OPENSSL_EXPORT int X509_ATTRIBUTE_set1_data(X509_ATTRIBUTE *attr, int attrtype, const void *data, int len); +OPENSSL_EXPORT void *X509_ATTRIBUTE_get0_data(X509_ATTRIBUTE *attr, int idx, + int atrtype, void *data); +OPENSSL_EXPORT int X509_ATTRIBUTE_count(X509_ATTRIBUTE *attr); +OPENSSL_EXPORT ASN1_OBJECT *X509_ATTRIBUTE_get0_object(X509_ATTRIBUTE *attr); +OPENSSL_EXPORT ASN1_TYPE *X509_ATTRIBUTE_get0_type(X509_ATTRIBUTE *attr, int idx); + +OPENSSL_EXPORT int X509_verify_cert(X509_STORE_CTX *ctx); + +/* lookup a cert from a X509 STACK */ +OPENSSL_EXPORT X509 *X509_find_by_issuer_and_serial(STACK_OF(X509) *sk,X509_NAME *name, + ASN1_INTEGER *serial); +OPENSSL_EXPORT X509 *X509_find_by_subject(STACK_OF(X509) *sk,X509_NAME *name); + +/* PKCS#8 utilities */ + +DECLARE_ASN1_FUNCTIONS(PKCS8_PRIV_KEY_INFO) + +OPENSSL_EXPORT EVP_PKEY *EVP_PKCS82PKEY(PKCS8_PRIV_KEY_INFO *p8); +OPENSSL_EXPORT PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(EVP_PKEY *pkey); +OPENSSL_EXPORT PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8_broken(EVP_PKEY *pkey, int broken); +OPENSSL_EXPORT PKCS8_PRIV_KEY_INFO *PKCS8_set_broken(PKCS8_PRIV_KEY_INFO *p8, int broken); + +OPENSSL_EXPORT int PKCS8_pkey_set0(PKCS8_PRIV_KEY_INFO *priv, ASN1_OBJECT *aobj, + int version, int ptype, void *pval, + unsigned char *penc, int penclen); +OPENSSL_EXPORT int PKCS8_pkey_get0(ASN1_OBJECT **ppkalg, + const unsigned char **pk, int *ppklen, + X509_ALGOR **pa, + PKCS8_PRIV_KEY_INFO *p8); + +OPENSSL_EXPORT int X509_PUBKEY_set0_param(X509_PUBKEY *pub, const ASN1_OBJECT *aobj, + int ptype, void *pval, + unsigned char *penc, int penclen); +OPENSSL_EXPORT int X509_PUBKEY_get0_param(ASN1_OBJECT **ppkalg, + const unsigned char **pk, int *ppklen, + X509_ALGOR **pa, + X509_PUBKEY *pub); + +OPENSSL_EXPORT int X509_check_trust(X509 *x, int id, int flags); +OPENSSL_EXPORT int X509_TRUST_get_count(void); +OPENSSL_EXPORT X509_TRUST * X509_TRUST_get0(int idx); +OPENSSL_EXPORT int X509_TRUST_get_by_id(int id); +OPENSSL_EXPORT int X509_TRUST_add(int id, int flags, int (*ck)(X509_TRUST *, X509 *, int), + char *name, int arg1, void *arg2); +OPENSSL_EXPORT void X509_TRUST_cleanup(void); +OPENSSL_EXPORT int X509_TRUST_get_flags(X509_TRUST *xp); +OPENSSL_EXPORT char *X509_TRUST_get0_name(X509_TRUST *xp); +OPENSSL_EXPORT int X509_TRUST_get_trust(X509_TRUST *xp); + + +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) + + + +#ifdef __cplusplus +} +#endif + +#if !defined(BORINGSSL_NO_CXX) +extern "C++" { + +namespace bssl { + +BORINGSSL_MAKE_DELETER(NETSCAPE_SPKI, NETSCAPE_SPKI_free) +BORINGSSL_MAKE_DELETER(RSA_PSS_PARAMS, RSA_PSS_PARAMS_free) +BORINGSSL_MAKE_DELETER(X509, X509_free) +BORINGSSL_MAKE_DELETER(X509_ALGOR, X509_ALGOR_free) +BORINGSSL_MAKE_DELETER(X509_CRL, X509_CRL_free) +BORINGSSL_MAKE_DELETER(X509_CRL_METHOD, X509_CRL_METHOD_free) +BORINGSSL_MAKE_DELETER(X509_EXTENSION, X509_EXTENSION_free) +BORINGSSL_MAKE_DELETER(X509_INFO, X509_INFO_free) +BORINGSSL_MAKE_DELETER(X509_LOOKUP, X509_LOOKUP_free) +BORINGSSL_MAKE_DELETER(X509_NAME, X509_NAME_free) +BORINGSSL_MAKE_DELETER(X509_NAME_ENTRY, X509_NAME_ENTRY_free) +BORINGSSL_MAKE_DELETER(X509_PKEY, X509_PKEY_free) +BORINGSSL_MAKE_DELETER(X509_POLICY_TREE, X509_policy_tree_free) +BORINGSSL_MAKE_DELETER(X509_PUBKEY, X509_PUBKEY_free) +BORINGSSL_MAKE_DELETER(X509_REQ, X509_REQ_free) +BORINGSSL_MAKE_DELETER(X509_REVOKED, X509_REVOKED_free) +BORINGSSL_MAKE_DELETER(X509_SIG, X509_SIG_free) +BORINGSSL_MAKE_DELETER(X509_STORE, X509_STORE_free) +BORINGSSL_MAKE_DELETER(X509_STORE_CTX, X509_STORE_CTX_free) +BORINGSSL_MAKE_DELETER(X509_VERIFY_PARAM, X509_VERIFY_PARAM_free) + +using ScopedX509_STORE_CTX = + internal::StackAllocated; + +} // namespace bssl + +} /* extern C++ */ +#endif /* !BORINGSSL_NO_CXX */ + +#define X509_R_AKID_MISMATCH 100 +#define X509_R_BAD_PKCS7_VERSION 101 +#define X509_R_BAD_X509_FILETYPE 102 +#define X509_R_BASE64_DECODE_ERROR 103 +#define X509_R_CANT_CHECK_DH_KEY 104 +#define X509_R_CERT_ALREADY_IN_HASH_TABLE 105 +#define X509_R_CRL_ALREADY_DELTA 106 +#define X509_R_CRL_VERIFY_FAILURE 107 +#define X509_R_IDP_MISMATCH 108 +#define X509_R_INVALID_BIT_STRING_BITS_LEFT 109 +#define X509_R_INVALID_DIRECTORY 110 +#define X509_R_INVALID_FIELD_NAME 111 +#define X509_R_INVALID_PSS_PARAMETERS 112 +#define X509_R_INVALID_TRUST 113 +#define X509_R_ISSUER_MISMATCH 114 +#define X509_R_KEY_TYPE_MISMATCH 115 +#define X509_R_KEY_VALUES_MISMATCH 116 +#define X509_R_LOADING_CERT_DIR 117 +#define X509_R_LOADING_DEFAULTS 118 +#define X509_R_NEWER_CRL_NOT_NEWER 119 +#define X509_R_NOT_PKCS7_SIGNED_DATA 120 +#define X509_R_NO_CERTIFICATES_INCLUDED 121 +#define X509_R_NO_CERT_SET_FOR_US_TO_VERIFY 122 +#define X509_R_NO_CRLS_INCLUDED 123 +#define X509_R_NO_CRL_NUMBER 124 +#define X509_R_PUBLIC_KEY_DECODE_ERROR 125 +#define X509_R_PUBLIC_KEY_ENCODE_ERROR 126 +#define X509_R_SHOULD_RETRY 127 +#define X509_R_UNKNOWN_KEY_TYPE 128 +#define X509_R_UNKNOWN_NID 129 +#define X509_R_UNKNOWN_PURPOSE_ID 130 +#define X509_R_UNKNOWN_TRUST_ID 131 +#define X509_R_UNSUPPORTED_ALGORITHM 132 +#define X509_R_WRONG_LOOKUP_TYPE 133 +#define X509_R_WRONG_TYPE 134 +#define X509_R_NAME_TOO_LONG 135 +#define X509_R_INVALID_PARAMETER 136 + +#endif diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/x509.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/x509.h.grpc_back new file mode 100644 index 0000000..b336e0f --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/x509.h.grpc_back @@ -0,0 +1,1180 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Legacy X.509 library. + * + * This header is part of OpenSSL's X.509 implementation. It is retained for + * compatibility but otherwise underdocumented and not actively maintained. In + * the future, a replacement library will be available. Meanwhile, minimize + * dependencies on this header where possible. */ + + +#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 + +DEFINE_STACK_OF(X509_ALGOR) +DECLARE_ASN1_SET_OF(X509_ALGOR) + +typedef STACK_OF(X509_ALGOR) X509_ALGORS; + +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; + }; + +struct X509_sig_st + { + X509_ALGOR *algor; + ASN1_OCTET_STRING *digest; + } /* X509_SIG */; + +struct X509_name_entry_st + { + ASN1_OBJECT *object; + ASN1_STRING *value; + int set; + int size; /* temp variable */ + } /* X509_NAME_ENTRY */; + +DEFINE_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 */ + BUF_MEM *bytes; +/* unsigned long hash; Keep the hash around for lookups */ + unsigned char *canon_enc; + int canon_enclen; + } /* X509_NAME */; + +DEFINE_STACK_OF(X509_NAME) + +struct X509_extension_st + { + ASN1_OBJECT *object; + ASN1_BOOLEAN critical; + ASN1_OCTET_STRING *value; + } /* X509_EXTENSION */; + +typedef STACK_OF(X509_EXTENSION) X509_EXTENSIONS; + +DEFINE_STACK_OF(X509_EXTENSION) +DECLARE_ASN1_SET_OF(X509_EXTENSION) + +/* a sequence of these are used */ +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 */; + +DEFINE_STACK_OF(X509_ATTRIBUTE) +DECLARE_ASN1_SET_OF(X509_ATTRIBUTE) + + +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 */; + +struct X509_req_st + { + X509_REQ_INFO *req_info; + X509_ALGOR *sig_alg; + ASN1_BIT_STRING *signature; + CRYPTO_refcount_t references; + } /* X509_REQ */; + +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 + */ + +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 */; + +DECLARE_STACK_OF(DIST_POINT) +DECLARE_STACK_OF(GENERAL_NAME) + +struct x509_st + { + X509_CINF *cert_info; + X509_ALGOR *sig_alg; + ASN1_BIT_STRING *signature; + CRYPTO_refcount_t 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; + unsigned char sha1_hash[SHA_DIGEST_LENGTH]; + X509_CERT_AUX *aux; + CRYPTO_BUFFER *buf; + CRYPTO_MUTEX lock; + } /* X509 */; + +DEFINE_STACK_OF(X509) +DECLARE_ASN1_SET_OF(X509) + +/* This is used for a table of trust checking functions */ + +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 */; + +DEFINE_STACK_OF(X509_TRUST) + +/* 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 */ + }; + +DEFINE_STACK_OF(X509_REVOKED) +DECLARE_ASN1_SET_OF(X509_REVOKED) + +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 */; + +DECLARE_STACK_OF(GENERAL_NAMES) + +struct X509_crl_st + { + /* actual signature */ + X509_CRL_INFO *crl; + X509_ALGOR *sig_alg; + ASN1_BIT_STRING *signature; + CRYPTO_refcount_t 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; + unsigned char sha1_hash[SHA_DIGEST_LENGTH]; + STACK_OF(GENERAL_NAMES) *issuers; + const X509_CRL_METHOD *meth; + void *meth_data; + } /* X509_CRL */; + +DEFINE_STACK_OF(X509_CRL) +DECLARE_ASN1_SET_OF(X509_CRL) + +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; + } /* X509_PKEY */; + +#ifndef OPENSSL_NO_EVP +struct X509_info_st + { + X509 *x509; + X509_CRL *crl; + X509_PKEY *x_pkey; + + EVP_CIPHER_INFO enc_cipher; + int enc_len; + char *enc_data; + + } /* X509_INFO */; + +DEFINE_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 + */ +struct Netscape_spkac_st + { + X509_PUBKEY *pubkey; + ASN1_IA5STRING *challenge; /* challenge sent in atlas >= PR2 */ + } /* NETSCAPE_SPKAC */; + +struct Netscape_spki_st + { + NETSCAPE_SPKAC *spkac; /* signed public key and challenge */ + X509_ALGOR *sig_algor; + ASN1_BIT_STRING *signature; + } /* NETSCAPE_SPKI */; + +/* PKCS#8 private key info structure */ + +struct pkcs8_priv_key_info_st + { + int broken; /* Flag for various broken formats */ +#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; + ASN1_TYPE *pkey; /* Should be OCTET STRING but some are broken */ + STACK_OF(X509_ATTRIBUTE) *attributes; + }; + +#ifdef __cplusplus +} +#endif + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#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_get_cert_info(x) ((x)->cert_info) +#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) + +#define X509_CINF_set_modified(c) ((c)->enc.modified = 1) +#define X509_CINF_get_issuer(c) (&(c)->issuer) +#define X509_CINF_get_extensions(c) ((c)->extensions) +#define X509_CINF_get_signature(c) ((c)->signature) + +OPENSSL_EXPORT void X509_CRL_set_default_method(const X509_CRL_METHOD *meth); +OPENSSL_EXPORT 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)); +OPENSSL_EXPORT void X509_CRL_METHOD_free(X509_CRL_METHOD *m); + +OPENSSL_EXPORT void X509_CRL_set_meth_data(X509_CRL *crl, void *dat); +OPENSSL_EXPORT 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) + + +OPENSSL_EXPORT const char *X509_verify_cert_error_string(long n); + +#ifndef OPENSSL_NO_EVP +OPENSSL_EXPORT int X509_verify(X509 *a, EVP_PKEY *r); + +OPENSSL_EXPORT int X509_REQ_verify(X509_REQ *a, EVP_PKEY *r); +OPENSSL_EXPORT int X509_CRL_verify(X509_CRL *a, EVP_PKEY *r); +OPENSSL_EXPORT int NETSCAPE_SPKI_verify(NETSCAPE_SPKI *a, EVP_PKEY *r); + +OPENSSL_EXPORT NETSCAPE_SPKI * NETSCAPE_SPKI_b64_decode(const char *str, int len); +OPENSSL_EXPORT char * NETSCAPE_SPKI_b64_encode(NETSCAPE_SPKI *x); +OPENSSL_EXPORT EVP_PKEY *NETSCAPE_SPKI_get_pubkey(NETSCAPE_SPKI *x); +OPENSSL_EXPORT int NETSCAPE_SPKI_set_pubkey(NETSCAPE_SPKI *x, EVP_PKEY *pkey); + +OPENSSL_EXPORT int NETSCAPE_SPKI_print(BIO *out, NETSCAPE_SPKI *spki); + +OPENSSL_EXPORT int X509_signature_dump(BIO *bp,const ASN1_STRING *sig, int indent); +OPENSSL_EXPORT int X509_signature_print(BIO *bp, const X509_ALGOR *alg, + const ASN1_STRING *sig); + +OPENSSL_EXPORT int X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md); +OPENSSL_EXPORT int X509_sign_ctx(X509 *x, EVP_MD_CTX *ctx); +OPENSSL_EXPORT int X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md); +OPENSSL_EXPORT int X509_REQ_sign_ctx(X509_REQ *x, EVP_MD_CTX *ctx); +OPENSSL_EXPORT int X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md); +OPENSSL_EXPORT int X509_CRL_sign_ctx(X509_CRL *x, EVP_MD_CTX *ctx); +OPENSSL_EXPORT int NETSCAPE_SPKI_sign(NETSCAPE_SPKI *x, EVP_PKEY *pkey, const EVP_MD *md); + +OPENSSL_EXPORT int X509_pubkey_digest(const X509 *data,const EVP_MD *type, + unsigned char *md, unsigned int *len); +OPENSSL_EXPORT int X509_digest(const X509 *data,const EVP_MD *type, + unsigned char *md, unsigned int *len); +OPENSSL_EXPORT int X509_CRL_digest(const X509_CRL *data,const EVP_MD *type, + unsigned char *md, unsigned int *len); +OPENSSL_EXPORT int X509_REQ_digest(const X509_REQ *data,const EVP_MD *type, + unsigned char *md, unsigned int *len); +OPENSSL_EXPORT int X509_NAME_digest(const X509_NAME *data,const EVP_MD *type, + unsigned char *md, unsigned int *len); +#endif + +/* X509_parse_from_buffer parses an X.509 structure from |buf| and returns a + * fresh X509 or NULL on error. There must not be any trailing data in |buf|. + * The returned structure (if any) holds a reference to |buf| rather than + * copying parts of it as a normal |d2i_X509| call would do. */ +OPENSSL_EXPORT X509 *X509_parse_from_buffer(CRYPTO_BUFFER *buf); + +#ifndef OPENSSL_NO_FP_API +OPENSSL_EXPORT X509 *d2i_X509_fp(FILE *fp, X509 **x509); +OPENSSL_EXPORT int i2d_X509_fp(FILE *fp,X509 *x509); +OPENSSL_EXPORT X509_CRL *d2i_X509_CRL_fp(FILE *fp,X509_CRL **crl); +OPENSSL_EXPORT int i2d_X509_CRL_fp(FILE *fp,X509_CRL *crl); +OPENSSL_EXPORT X509_REQ *d2i_X509_REQ_fp(FILE *fp,X509_REQ **req); +OPENSSL_EXPORT int i2d_X509_REQ_fp(FILE *fp,X509_REQ *req); +OPENSSL_EXPORT RSA *d2i_RSAPrivateKey_fp(FILE *fp,RSA **rsa); +OPENSSL_EXPORT int i2d_RSAPrivateKey_fp(FILE *fp,RSA *rsa); +OPENSSL_EXPORT RSA *d2i_RSAPublicKey_fp(FILE *fp,RSA **rsa); +OPENSSL_EXPORT int i2d_RSAPublicKey_fp(FILE *fp,RSA *rsa); +OPENSSL_EXPORT RSA *d2i_RSA_PUBKEY_fp(FILE *fp,RSA **rsa); +OPENSSL_EXPORT int i2d_RSA_PUBKEY_fp(FILE *fp,RSA *rsa); +#ifndef OPENSSL_NO_DSA +OPENSSL_EXPORT DSA *d2i_DSA_PUBKEY_fp(FILE *fp, DSA **dsa); +OPENSSL_EXPORT int i2d_DSA_PUBKEY_fp(FILE *fp, DSA *dsa); +OPENSSL_EXPORT DSA *d2i_DSAPrivateKey_fp(FILE *fp, DSA **dsa); +OPENSSL_EXPORT int i2d_DSAPrivateKey_fp(FILE *fp, DSA *dsa); +#endif +OPENSSL_EXPORT EC_KEY *d2i_EC_PUBKEY_fp(FILE *fp, EC_KEY **eckey); +OPENSSL_EXPORT int i2d_EC_PUBKEY_fp(FILE *fp, EC_KEY *eckey); +OPENSSL_EXPORT EC_KEY *d2i_ECPrivateKey_fp(FILE *fp, EC_KEY **eckey); +OPENSSL_EXPORT int i2d_ECPrivateKey_fp(FILE *fp, EC_KEY *eckey); +OPENSSL_EXPORT X509_SIG *d2i_PKCS8_fp(FILE *fp,X509_SIG **p8); +OPENSSL_EXPORT int i2d_PKCS8_fp(FILE *fp,X509_SIG *p8); +OPENSSL_EXPORT PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_fp(FILE *fp, + PKCS8_PRIV_KEY_INFO **p8inf); +OPENSSL_EXPORT int i2d_PKCS8_PRIV_KEY_INFO_fp(FILE *fp,PKCS8_PRIV_KEY_INFO *p8inf); +OPENSSL_EXPORT int i2d_PKCS8PrivateKeyInfo_fp(FILE *fp, EVP_PKEY *key); +OPENSSL_EXPORT int i2d_PrivateKey_fp(FILE *fp, EVP_PKEY *pkey); +OPENSSL_EXPORT EVP_PKEY *d2i_PrivateKey_fp(FILE *fp, EVP_PKEY **a); +OPENSSL_EXPORT int i2d_PUBKEY_fp(FILE *fp, EVP_PKEY *pkey); +OPENSSL_EXPORT EVP_PKEY *d2i_PUBKEY_fp(FILE *fp, EVP_PKEY **a); +#endif + +OPENSSL_EXPORT X509 *d2i_X509_bio(BIO *bp,X509 **x509); +OPENSSL_EXPORT int i2d_X509_bio(BIO *bp,X509 *x509); +OPENSSL_EXPORT X509_CRL *d2i_X509_CRL_bio(BIO *bp,X509_CRL **crl); +OPENSSL_EXPORT int i2d_X509_CRL_bio(BIO *bp,X509_CRL *crl); +OPENSSL_EXPORT X509_REQ *d2i_X509_REQ_bio(BIO *bp,X509_REQ **req); +OPENSSL_EXPORT int i2d_X509_REQ_bio(BIO *bp,X509_REQ *req); +OPENSSL_EXPORT RSA *d2i_RSAPrivateKey_bio(BIO *bp,RSA **rsa); +OPENSSL_EXPORT int i2d_RSAPrivateKey_bio(BIO *bp,RSA *rsa); +OPENSSL_EXPORT RSA *d2i_RSAPublicKey_bio(BIO *bp,RSA **rsa); +OPENSSL_EXPORT int i2d_RSAPublicKey_bio(BIO *bp,RSA *rsa); +OPENSSL_EXPORT RSA *d2i_RSA_PUBKEY_bio(BIO *bp,RSA **rsa); +OPENSSL_EXPORT int i2d_RSA_PUBKEY_bio(BIO *bp,RSA *rsa); +#ifndef OPENSSL_NO_DSA +OPENSSL_EXPORT DSA *d2i_DSA_PUBKEY_bio(BIO *bp, DSA **dsa); +OPENSSL_EXPORT int i2d_DSA_PUBKEY_bio(BIO *bp, DSA *dsa); +OPENSSL_EXPORT DSA *d2i_DSAPrivateKey_bio(BIO *bp, DSA **dsa); +OPENSSL_EXPORT int i2d_DSAPrivateKey_bio(BIO *bp, DSA *dsa); +#endif +OPENSSL_EXPORT EC_KEY *d2i_EC_PUBKEY_bio(BIO *bp, EC_KEY **eckey); +OPENSSL_EXPORT int i2d_EC_PUBKEY_bio(BIO *bp, EC_KEY *eckey); +OPENSSL_EXPORT EC_KEY *d2i_ECPrivateKey_bio(BIO *bp, EC_KEY **eckey); +OPENSSL_EXPORT int i2d_ECPrivateKey_bio(BIO *bp, EC_KEY *eckey); +OPENSSL_EXPORT X509_SIG *d2i_PKCS8_bio(BIO *bp,X509_SIG **p8); +OPENSSL_EXPORT int i2d_PKCS8_bio(BIO *bp,X509_SIG *p8); +OPENSSL_EXPORT PKCS8_PRIV_KEY_INFO *d2i_PKCS8_PRIV_KEY_INFO_bio(BIO *bp, + PKCS8_PRIV_KEY_INFO **p8inf); +OPENSSL_EXPORT int i2d_PKCS8_PRIV_KEY_INFO_bio(BIO *bp,PKCS8_PRIV_KEY_INFO *p8inf); +OPENSSL_EXPORT int i2d_PKCS8PrivateKeyInfo_bio(BIO *bp, EVP_PKEY *key); +OPENSSL_EXPORT int i2d_PrivateKey_bio(BIO *bp, EVP_PKEY *pkey); +OPENSSL_EXPORT EVP_PKEY *d2i_PrivateKey_bio(BIO *bp, EVP_PKEY **a); +OPENSSL_EXPORT int i2d_PUBKEY_bio(BIO *bp, EVP_PKEY *pkey); +OPENSSL_EXPORT EVP_PKEY *d2i_PUBKEY_bio(BIO *bp, EVP_PKEY **a); + +OPENSSL_EXPORT X509 *X509_dup(X509 *x509); +OPENSSL_EXPORT X509_ATTRIBUTE *X509_ATTRIBUTE_dup(X509_ATTRIBUTE *xa); +OPENSSL_EXPORT X509_EXTENSION *X509_EXTENSION_dup(X509_EXTENSION *ex); +OPENSSL_EXPORT X509_CRL *X509_CRL_dup(X509_CRL *crl); +OPENSSL_EXPORT X509_REVOKED *X509_REVOKED_dup(X509_REVOKED *rev); +OPENSSL_EXPORT X509_REQ *X509_REQ_dup(X509_REQ *req); +OPENSSL_EXPORT X509_ALGOR *X509_ALGOR_dup(X509_ALGOR *xn); +OPENSSL_EXPORT int X509_ALGOR_set0(X509_ALGOR *alg, const ASN1_OBJECT *aobj, int ptype, void *pval); +OPENSSL_EXPORT void X509_ALGOR_get0(const ASN1_OBJECT **paobj, int *pptype, + const void **ppval, + const X509_ALGOR *algor); +OPENSSL_EXPORT void X509_ALGOR_set_md(X509_ALGOR *alg, const EVP_MD *md); +OPENSSL_EXPORT int X509_ALGOR_cmp(const X509_ALGOR *a, const X509_ALGOR *b); + +OPENSSL_EXPORT X509_NAME *X509_NAME_dup(X509_NAME *xn); +OPENSSL_EXPORT X509_NAME_ENTRY *X509_NAME_ENTRY_dup(X509_NAME_ENTRY *ne); +OPENSSL_EXPORT int X509_NAME_ENTRY_set(const X509_NAME_ENTRY *ne); + +OPENSSL_EXPORT int X509_NAME_get0_der(X509_NAME *nm, const unsigned char **pder, + size_t *pderlen); + +OPENSSL_EXPORT int X509_cmp_time(const ASN1_TIME *s, time_t *t); +OPENSSL_EXPORT int X509_cmp_current_time(const ASN1_TIME *s); +OPENSSL_EXPORT ASN1_TIME * X509_time_adj(ASN1_TIME *s, long adj, time_t *t); +OPENSSL_EXPORT ASN1_TIME * X509_time_adj_ex(ASN1_TIME *s, int offset_day, long offset_sec, time_t *t); +OPENSSL_EXPORT ASN1_TIME * X509_gmtime_adj(ASN1_TIME *s, long adj); + +OPENSSL_EXPORT const char * X509_get_default_cert_area(void ); +OPENSSL_EXPORT const char * X509_get_default_cert_dir(void ); +OPENSSL_EXPORT const char * X509_get_default_cert_file(void ); +OPENSSL_EXPORT const char * X509_get_default_cert_dir_env(void ); +OPENSSL_EXPORT const char * X509_get_default_cert_file_env(void ); +OPENSSL_EXPORT const char * X509_get_default_private_dir(void ); + +OPENSSL_EXPORT X509_REQ * X509_to_X509_REQ(X509 *x, EVP_PKEY *pkey, const EVP_MD *md); +OPENSSL_EXPORT X509 * X509_REQ_to_X509(X509_REQ *r, int days,EVP_PKEY *pkey); + +DECLARE_ASN1_ENCODE_FUNCTIONS(X509_ALGORS, X509_ALGORS, X509_ALGORS) +DECLARE_ASN1_FUNCTIONS(X509_VAL) + +DECLARE_ASN1_FUNCTIONS(X509_PUBKEY) + +OPENSSL_EXPORT int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey); +OPENSSL_EXPORT EVP_PKEY * X509_PUBKEY_get(X509_PUBKEY *key); +OPENSSL_EXPORT int i2d_PUBKEY(const EVP_PKEY *a,unsigned char **pp); +OPENSSL_EXPORT EVP_PKEY * d2i_PUBKEY(EVP_PKEY **a,const unsigned char **pp, + long length); +OPENSSL_EXPORT int i2d_RSA_PUBKEY(const RSA *a,unsigned char **pp); +OPENSSL_EXPORT RSA * d2i_RSA_PUBKEY(RSA **a,const unsigned char **pp, + long length); +#ifndef OPENSSL_NO_DSA +OPENSSL_EXPORT int i2d_DSA_PUBKEY(const DSA *a,unsigned char **pp); +OPENSSL_EXPORT DSA * d2i_DSA_PUBKEY(DSA **a,const unsigned char **pp, + long length); +#endif +OPENSSL_EXPORT int i2d_EC_PUBKEY(const EC_KEY *a, unsigned char **pp); +OPENSSL_EXPORT EC_KEY *d2i_EC_PUBKEY(EC_KEY **a, const unsigned char **pp, + long length); + +DECLARE_ASN1_FUNCTIONS(X509_SIG) +DECLARE_ASN1_FUNCTIONS(X509_REQ_INFO) +DECLARE_ASN1_FUNCTIONS(X509_REQ) + +DECLARE_ASN1_FUNCTIONS(X509_ATTRIBUTE) +OPENSSL_EXPORT 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) + +OPENSSL_EXPORT 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) + +/* X509_up_ref adds one to the reference count of |x| and returns one. */ +OPENSSL_EXPORT int X509_up_ref(X509 *x); + +OPENSSL_EXPORT int X509_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused *unused, + CRYPTO_EX_dup *dup_unused, CRYPTO_EX_free *free_func); +OPENSSL_EXPORT int X509_set_ex_data(X509 *r, int idx, void *arg); +OPENSSL_EXPORT void *X509_get_ex_data(X509 *r, int idx); +OPENSSL_EXPORT int i2d_X509_AUX(X509 *a,unsigned char **pp); +OPENSSL_EXPORT X509 * d2i_X509_AUX(X509 **a,const unsigned char **pp,long length); + +OPENSSL_EXPORT void X509_get0_signature(const ASN1_BIT_STRING **psig, + const X509_ALGOR **palg, const X509 *x); +OPENSSL_EXPORT int X509_get_signature_nid(const X509 *x); + +OPENSSL_EXPORT int X509_alias_set1(X509 *x, unsigned char *name, int len); +OPENSSL_EXPORT int X509_keyid_set1(X509 *x, unsigned char *id, int len); +OPENSSL_EXPORT unsigned char * X509_alias_get0(X509 *x, int *len); +OPENSSL_EXPORT unsigned char * X509_keyid_get0(X509 *x, int *len); +OPENSSL_EXPORT int (*X509_TRUST_set_default(int (*trust)(int , X509 *, int)))(int, X509 *, int); +OPENSSL_EXPORT int X509_TRUST_set(int *t, int trust); +OPENSSL_EXPORT int X509_add1_trust_object(X509 *x, ASN1_OBJECT *obj); +OPENSSL_EXPORT int X509_add1_reject_object(X509 *x, ASN1_OBJECT *obj); +OPENSSL_EXPORT void X509_trust_clear(X509 *x); +OPENSSL_EXPORT void X509_reject_clear(X509 *x); + +DECLARE_ASN1_FUNCTIONS(X509_REVOKED) +DECLARE_ASN1_FUNCTIONS(X509_CRL_INFO) +DECLARE_ASN1_FUNCTIONS(X509_CRL) + +OPENSSL_EXPORT int X509_CRL_add0_revoked(X509_CRL *crl, X509_REVOKED *rev); +OPENSSL_EXPORT int X509_CRL_get0_by_serial(X509_CRL *crl, + X509_REVOKED **ret, ASN1_INTEGER *serial); +OPENSSL_EXPORT int X509_CRL_get0_by_cert(X509_CRL *crl, X509_REVOKED **ret, X509 *x); + +OPENSSL_EXPORT X509_PKEY * X509_PKEY_new(void ); +OPENSSL_EXPORT void X509_PKEY_free(X509_PKEY *a); + +DECLARE_ASN1_FUNCTIONS(NETSCAPE_SPKI) +DECLARE_ASN1_FUNCTIONS(NETSCAPE_SPKAC) + +#ifndef OPENSSL_NO_EVP +OPENSSL_EXPORT X509_INFO * X509_INFO_new(void); +OPENSSL_EXPORT void X509_INFO_free(X509_INFO *a); +OPENSSL_EXPORT char * X509_NAME_oneline(X509_NAME *a,char *buf,int size); + +OPENSSL_EXPORT int ASN1_digest(i2d_of_void *i2d,const EVP_MD *type,char *data, + unsigned char *md,unsigned int *len); + +OPENSSL_EXPORT int ASN1_item_digest(const ASN1_ITEM *it,const EVP_MD *type,void *data, + unsigned char *md,unsigned int *len); + +OPENSSL_EXPORT int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *algor1, + ASN1_BIT_STRING *signature,void *data,EVP_PKEY *pkey); + +OPENSSL_EXPORT 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); +OPENSSL_EXPORT 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 + +OPENSSL_EXPORT int X509_set_version(X509 *x,long version); +OPENSSL_EXPORT int X509_set_serialNumber(X509 *x, ASN1_INTEGER *serial); +OPENSSL_EXPORT ASN1_INTEGER * X509_get_serialNumber(X509 *x); +OPENSSL_EXPORT int X509_set_issuer_name(X509 *x, X509_NAME *name); +OPENSSL_EXPORT X509_NAME * X509_get_issuer_name(X509 *a); +OPENSSL_EXPORT int X509_set_subject_name(X509 *x, X509_NAME *name); +OPENSSL_EXPORT X509_NAME * X509_get_subject_name(X509 *a); +OPENSSL_EXPORT int X509_set_notBefore(X509 *x, const ASN1_TIME *tm); +OPENSSL_EXPORT const ASN1_TIME *X509_get0_notBefore(const X509 *x); +OPENSSL_EXPORT int X509_set_notAfter(X509 *x, const ASN1_TIME *tm); +OPENSSL_EXPORT const ASN1_TIME *X509_get0_notAfter(const X509 *x); +OPENSSL_EXPORT int X509_set_pubkey(X509 *x, EVP_PKEY *pkey); +OPENSSL_EXPORT EVP_PKEY * X509_get_pubkey(X509 *x); +OPENSSL_EXPORT ASN1_BIT_STRING * X509_get0_pubkey_bitstr(const X509 *x); +OPENSSL_EXPORT STACK_OF(X509_EXTENSION) *X509_get0_extensions(const X509 *x); + +OPENSSL_EXPORT int X509_REQ_set_version(X509_REQ *x,long version); +OPENSSL_EXPORT int X509_REQ_set_subject_name(X509_REQ *req,X509_NAME *name); +OPENSSL_EXPORT int X509_REQ_set_pubkey(X509_REQ *x, EVP_PKEY *pkey); +OPENSSL_EXPORT EVP_PKEY * X509_REQ_get_pubkey(X509_REQ *req); +OPENSSL_EXPORT int X509_REQ_extension_nid(int nid); +OPENSSL_EXPORT const int * X509_REQ_get_extension_nids(void); +OPENSSL_EXPORT void X509_REQ_set_extension_nids(const int *nids); +OPENSSL_EXPORT STACK_OF(X509_EXTENSION) *X509_REQ_get_extensions(X509_REQ *req); +OPENSSL_EXPORT int X509_REQ_add_extensions_nid(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts, + int nid); +OPENSSL_EXPORT int X509_REQ_add_extensions(X509_REQ *req, STACK_OF(X509_EXTENSION) *exts); +OPENSSL_EXPORT int X509_REQ_get_attr_count(const X509_REQ *req); +OPENSSL_EXPORT int X509_REQ_get_attr_by_NID(const X509_REQ *req, int nid, + int lastpos); +OPENSSL_EXPORT int X509_REQ_get_attr_by_OBJ(const X509_REQ *req, ASN1_OBJECT *obj, + int lastpos); +OPENSSL_EXPORT X509_ATTRIBUTE *X509_REQ_get_attr(const X509_REQ *req, int loc); +OPENSSL_EXPORT X509_ATTRIBUTE *X509_REQ_delete_attr(X509_REQ *req, int loc); +OPENSSL_EXPORT int X509_REQ_add1_attr(X509_REQ *req, X509_ATTRIBUTE *attr); +OPENSSL_EXPORT int X509_REQ_add1_attr_by_OBJ(X509_REQ *req, + const ASN1_OBJECT *obj, int type, + const unsigned char *bytes, int len); +OPENSSL_EXPORT int X509_REQ_add1_attr_by_NID(X509_REQ *req, + int nid, int type, + const unsigned char *bytes, int len); +OPENSSL_EXPORT int X509_REQ_add1_attr_by_txt(X509_REQ *req, + const char *attrname, int type, + const unsigned char *bytes, int len); + +OPENSSL_EXPORT int X509_CRL_set_version(X509_CRL *x, long version); +OPENSSL_EXPORT int X509_CRL_set_issuer_name(X509_CRL *x, X509_NAME *name); +OPENSSL_EXPORT int X509_CRL_set_lastUpdate(X509_CRL *x, const ASN1_TIME *tm); +OPENSSL_EXPORT int X509_CRL_set_nextUpdate(X509_CRL *x, const ASN1_TIME *tm); +OPENSSL_EXPORT int X509_CRL_sort(X509_CRL *crl); +OPENSSL_EXPORT int X509_CRL_up_ref(X509_CRL *crl); + +OPENSSL_EXPORT int X509_REVOKED_set_serialNumber(X509_REVOKED *x, ASN1_INTEGER *serial); +OPENSSL_EXPORT int X509_REVOKED_set_revocationDate(X509_REVOKED *r, ASN1_TIME *tm); + +OPENSSL_EXPORT X509_CRL *X509_CRL_diff(X509_CRL *base, X509_CRL *newer, + EVP_PKEY *skey, const EVP_MD *md, unsigned int flags); + +OPENSSL_EXPORT int X509_REQ_check_private_key(X509_REQ *x509,EVP_PKEY *pkey); + +OPENSSL_EXPORT int X509_check_private_key(X509 *x509,EVP_PKEY *pkey); +OPENSSL_EXPORT int X509_chain_check_suiteb(int *perror_depth, + X509 *x, STACK_OF(X509) *chain, + unsigned long flags); +OPENSSL_EXPORT int X509_CRL_check_suiteb(X509_CRL *crl, EVP_PKEY *pk, + unsigned long flags); +OPENSSL_EXPORT STACK_OF(X509) *X509_chain_up_ref(STACK_OF(X509) *chain); + +OPENSSL_EXPORT int X509_issuer_and_serial_cmp(const X509 *a, const X509 *b); +OPENSSL_EXPORT unsigned long X509_issuer_and_serial_hash(X509 *a); + +OPENSSL_EXPORT int X509_issuer_name_cmp(const X509 *a, const X509 *b); +OPENSSL_EXPORT unsigned long X509_issuer_name_hash(X509 *a); + +OPENSSL_EXPORT int X509_subject_name_cmp(const X509 *a, const X509 *b); +OPENSSL_EXPORT unsigned long X509_subject_name_hash(X509 *x); + +OPENSSL_EXPORT unsigned long X509_issuer_name_hash_old(X509 *a); +OPENSSL_EXPORT unsigned long X509_subject_name_hash_old(X509 *x); + +OPENSSL_EXPORT int X509_cmp(const X509 *a, const X509 *b); +OPENSSL_EXPORT int X509_NAME_cmp(const X509_NAME *a, const X509_NAME *b); +OPENSSL_EXPORT unsigned long X509_NAME_hash(X509_NAME *x); +OPENSSL_EXPORT unsigned long X509_NAME_hash_old(X509_NAME *x); + +OPENSSL_EXPORT int X509_CRL_cmp(const X509_CRL *a, const X509_CRL *b); +OPENSSL_EXPORT int X509_CRL_match(const X509_CRL *a, const X509_CRL *b); +#ifndef OPENSSL_NO_FP_API +OPENSSL_EXPORT int X509_print_ex_fp(FILE *bp,X509 *x, unsigned long nmflag, unsigned long cflag); +OPENSSL_EXPORT int X509_print_fp(FILE *bp,X509 *x); +OPENSSL_EXPORT int X509_CRL_print_fp(FILE *bp,X509_CRL *x); +OPENSSL_EXPORT int X509_REQ_print_fp(FILE *bp,X509_REQ *req); +OPENSSL_EXPORT int X509_NAME_print_ex_fp(FILE *fp, X509_NAME *nm, int indent, unsigned long flags); +#endif + +OPENSSL_EXPORT int X509_NAME_print(BIO *bp, X509_NAME *name, int obase); +OPENSSL_EXPORT int X509_NAME_print_ex(BIO *out, X509_NAME *nm, int indent, unsigned long flags); +OPENSSL_EXPORT int X509_print_ex(BIO *bp,X509 *x, unsigned long nmflag, unsigned long cflag); +OPENSSL_EXPORT int X509_print(BIO *bp,X509 *x); +OPENSSL_EXPORT int X509_ocspid_print(BIO *bp,X509 *x); +OPENSSL_EXPORT int X509_CERT_AUX_print(BIO *bp,X509_CERT_AUX *x, int indent); +OPENSSL_EXPORT int X509_CRL_print(BIO *bp,X509_CRL *x); +OPENSSL_EXPORT int X509_REQ_print_ex(BIO *bp, X509_REQ *x, unsigned long nmflag, unsigned long cflag); +OPENSSL_EXPORT int X509_REQ_print(BIO *bp,X509_REQ *req); + +OPENSSL_EXPORT int X509_NAME_entry_count(X509_NAME *name); +OPENSSL_EXPORT int X509_NAME_get_text_by_NID(X509_NAME *name, int nid, + char *buf,int len); +OPENSSL_EXPORT int X509_NAME_get_text_by_OBJ(X509_NAME *name, const 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. */ +OPENSSL_EXPORT int X509_NAME_get_index_by_NID(X509_NAME *name,int nid,int lastpos); +OPENSSL_EXPORT int X509_NAME_get_index_by_OBJ(X509_NAME *name, const ASN1_OBJECT *obj, + int lastpos); +OPENSSL_EXPORT X509_NAME_ENTRY *X509_NAME_get_entry(X509_NAME *name, int loc); +OPENSSL_EXPORT X509_NAME_ENTRY *X509_NAME_delete_entry(X509_NAME *name, int loc); +OPENSSL_EXPORT int X509_NAME_add_entry(X509_NAME *name,X509_NAME_ENTRY *ne, + int loc, int set); +OPENSSL_EXPORT int X509_NAME_add_entry_by_OBJ(X509_NAME *name, ASN1_OBJECT *obj, int type, + unsigned char *bytes, int len, int loc, int set); +OPENSSL_EXPORT int X509_NAME_add_entry_by_NID(X509_NAME *name, int nid, int type, + unsigned char *bytes, int len, int loc, int set); +OPENSSL_EXPORT X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_txt(X509_NAME_ENTRY **ne, + const char *field, int type, const unsigned char *bytes, int len); +OPENSSL_EXPORT X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_NID(X509_NAME_ENTRY **ne, int nid, + int type,unsigned char *bytes, int len); +OPENSSL_EXPORT 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); +OPENSSL_EXPORT X509_NAME_ENTRY *X509_NAME_ENTRY_create_by_OBJ(X509_NAME_ENTRY **ne, + const ASN1_OBJECT *obj, int type,const unsigned char *bytes, + int len); +OPENSSL_EXPORT int X509_NAME_ENTRY_set_object(X509_NAME_ENTRY *ne, + const ASN1_OBJECT *obj); +OPENSSL_EXPORT int X509_NAME_ENTRY_set_data(X509_NAME_ENTRY *ne, int type, + const unsigned char *bytes, int len); +OPENSSL_EXPORT ASN1_OBJECT * X509_NAME_ENTRY_get_object(X509_NAME_ENTRY *ne); +OPENSSL_EXPORT ASN1_STRING * X509_NAME_ENTRY_get_data(X509_NAME_ENTRY *ne); + +OPENSSL_EXPORT int X509v3_get_ext_count(const STACK_OF(X509_EXTENSION) *x); +OPENSSL_EXPORT int X509v3_get_ext_by_NID(const STACK_OF(X509_EXTENSION) *x, + int nid, int lastpos); +OPENSSL_EXPORT int X509v3_get_ext_by_OBJ(const STACK_OF(X509_EXTENSION) *x, + const ASN1_OBJECT *obj,int lastpos); +OPENSSL_EXPORT int X509v3_get_ext_by_critical(const STACK_OF(X509_EXTENSION) *x, + int crit, int lastpos); +OPENSSL_EXPORT X509_EXTENSION *X509v3_get_ext(const STACK_OF(X509_EXTENSION) *x, int loc); +OPENSSL_EXPORT X509_EXTENSION *X509v3_delete_ext(STACK_OF(X509_EXTENSION) *x, int loc); +OPENSSL_EXPORT STACK_OF(X509_EXTENSION) *X509v3_add_ext(STACK_OF(X509_EXTENSION) **x, + X509_EXTENSION *ex, int loc); + +OPENSSL_EXPORT int X509_get_ext_count(X509 *x); +OPENSSL_EXPORT int X509_get_ext_by_NID(X509 *x, int nid, int lastpos); +OPENSSL_EXPORT int X509_get_ext_by_OBJ(X509 *x,ASN1_OBJECT *obj,int lastpos); +OPENSSL_EXPORT int X509_get_ext_by_critical(X509 *x, int crit, int lastpos); +OPENSSL_EXPORT X509_EXTENSION *X509_get_ext(X509 *x, int loc); +OPENSSL_EXPORT X509_EXTENSION *X509_delete_ext(X509 *x, int loc); +OPENSSL_EXPORT int X509_add_ext(X509 *x, X509_EXTENSION *ex, int loc); +OPENSSL_EXPORT void * X509_get_ext_d2i(X509 *x, int nid, int *crit, int *idx); +OPENSSL_EXPORT int X509_add1_ext_i2d(X509 *x, int nid, void *value, int crit, + unsigned long flags); + +OPENSSL_EXPORT int X509_CRL_get_ext_count(X509_CRL *x); +OPENSSL_EXPORT int X509_CRL_get_ext_by_NID(X509_CRL *x, int nid, int lastpos); +OPENSSL_EXPORT int X509_CRL_get_ext_by_OBJ(X509_CRL *x,ASN1_OBJECT *obj,int lastpos); +OPENSSL_EXPORT int X509_CRL_get_ext_by_critical(X509_CRL *x, int crit, int lastpos); +OPENSSL_EXPORT X509_EXTENSION *X509_CRL_get_ext(X509_CRL *x, int loc); +OPENSSL_EXPORT X509_EXTENSION *X509_CRL_delete_ext(X509_CRL *x, int loc); +OPENSSL_EXPORT int X509_CRL_add_ext(X509_CRL *x, X509_EXTENSION *ex, int loc); +OPENSSL_EXPORT void * X509_CRL_get_ext_d2i(X509_CRL *x, int nid, int *crit, int *idx); +OPENSSL_EXPORT int X509_CRL_add1_ext_i2d(X509_CRL *x, int nid, void *value, int crit, + unsigned long flags); + +OPENSSL_EXPORT int X509_REVOKED_get_ext_count(X509_REVOKED *x); +OPENSSL_EXPORT int X509_REVOKED_get_ext_by_NID(X509_REVOKED *x, int nid, int lastpos); +OPENSSL_EXPORT int X509_REVOKED_get_ext_by_OBJ(X509_REVOKED *x,ASN1_OBJECT *obj,int lastpos); +OPENSSL_EXPORT int X509_REVOKED_get_ext_by_critical(X509_REVOKED *x, int crit, int lastpos); +OPENSSL_EXPORT X509_EXTENSION *X509_REVOKED_get_ext(X509_REVOKED *x, int loc); +OPENSSL_EXPORT X509_EXTENSION *X509_REVOKED_delete_ext(X509_REVOKED *x, int loc); +OPENSSL_EXPORT int X509_REVOKED_add_ext(X509_REVOKED *x, X509_EXTENSION *ex, int loc); +OPENSSL_EXPORT void * X509_REVOKED_get_ext_d2i(X509_REVOKED *x, int nid, int *crit, int *idx); +OPENSSL_EXPORT int X509_REVOKED_add1_ext_i2d(X509_REVOKED *x, int nid, void *value, int crit, + unsigned long flags); + +OPENSSL_EXPORT X509_EXTENSION *X509_EXTENSION_create_by_NID(X509_EXTENSION **ex, + int nid, int crit, ASN1_OCTET_STRING *data); +OPENSSL_EXPORT X509_EXTENSION *X509_EXTENSION_create_by_OBJ(X509_EXTENSION **ex, + const ASN1_OBJECT *obj,int crit,ASN1_OCTET_STRING *data); +OPENSSL_EXPORT int X509_EXTENSION_set_object(X509_EXTENSION *ex,const ASN1_OBJECT *obj); +OPENSSL_EXPORT int X509_EXTENSION_set_critical(X509_EXTENSION *ex, int crit); +OPENSSL_EXPORT int X509_EXTENSION_set_data(X509_EXTENSION *ex, + ASN1_OCTET_STRING *data); +OPENSSL_EXPORT ASN1_OBJECT * X509_EXTENSION_get_object(X509_EXTENSION *ex); +OPENSSL_EXPORT ASN1_OCTET_STRING *X509_EXTENSION_get_data(X509_EXTENSION *ne); +OPENSSL_EXPORT int X509_EXTENSION_get_critical(X509_EXTENSION *ex); + +OPENSSL_EXPORT int X509at_get_attr_count(const STACK_OF(X509_ATTRIBUTE) *x); +OPENSSL_EXPORT int X509at_get_attr_by_NID(const STACK_OF(X509_ATTRIBUTE) *x, int nid, + int lastpos); +OPENSSL_EXPORT int X509at_get_attr_by_OBJ(const STACK_OF(X509_ATTRIBUTE) *sk, const ASN1_OBJECT *obj, + int lastpos); +OPENSSL_EXPORT X509_ATTRIBUTE *X509at_get_attr(const STACK_OF(X509_ATTRIBUTE) *x, int loc); +OPENSSL_EXPORT X509_ATTRIBUTE *X509at_delete_attr(STACK_OF(X509_ATTRIBUTE) *x, int loc); +OPENSSL_EXPORT STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr(STACK_OF(X509_ATTRIBUTE) **x, + X509_ATTRIBUTE *attr); +OPENSSL_EXPORT 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); +OPENSSL_EXPORT STACK_OF(X509_ATTRIBUTE) *X509at_add1_attr_by_NID(STACK_OF(X509_ATTRIBUTE) **x, + int nid, int type, + const unsigned char *bytes, int len); +OPENSSL_EXPORT 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); +OPENSSL_EXPORT void *X509at_get0_data_by_OBJ(STACK_OF(X509_ATTRIBUTE) *x, + ASN1_OBJECT *obj, int lastpos, int type); +OPENSSL_EXPORT X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_NID(X509_ATTRIBUTE **attr, int nid, + int atrtype, const void *data, int len); +OPENSSL_EXPORT X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_OBJ(X509_ATTRIBUTE **attr, + const ASN1_OBJECT *obj, int atrtype, const void *data, int len); +OPENSSL_EXPORT X509_ATTRIBUTE *X509_ATTRIBUTE_create_by_txt(X509_ATTRIBUTE **attr, + const char *atrname, int type, const unsigned char *bytes, int len); +OPENSSL_EXPORT int X509_ATTRIBUTE_set1_object(X509_ATTRIBUTE *attr, const ASN1_OBJECT *obj); +OPENSSL_EXPORT int X509_ATTRIBUTE_set1_data(X509_ATTRIBUTE *attr, int attrtype, const void *data, int len); +OPENSSL_EXPORT void *X509_ATTRIBUTE_get0_data(X509_ATTRIBUTE *attr, int idx, + int atrtype, void *data); +OPENSSL_EXPORT int X509_ATTRIBUTE_count(X509_ATTRIBUTE *attr); +OPENSSL_EXPORT ASN1_OBJECT *X509_ATTRIBUTE_get0_object(X509_ATTRIBUTE *attr); +OPENSSL_EXPORT ASN1_TYPE *X509_ATTRIBUTE_get0_type(X509_ATTRIBUTE *attr, int idx); + +OPENSSL_EXPORT int X509_verify_cert(X509_STORE_CTX *ctx); + +/* lookup a cert from a X509 STACK */ +OPENSSL_EXPORT X509 *X509_find_by_issuer_and_serial(STACK_OF(X509) *sk,X509_NAME *name, + ASN1_INTEGER *serial); +OPENSSL_EXPORT X509 *X509_find_by_subject(STACK_OF(X509) *sk,X509_NAME *name); + +/* PKCS#8 utilities */ + +DECLARE_ASN1_FUNCTIONS(PKCS8_PRIV_KEY_INFO) + +OPENSSL_EXPORT EVP_PKEY *EVP_PKCS82PKEY(PKCS8_PRIV_KEY_INFO *p8); +OPENSSL_EXPORT PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8(EVP_PKEY *pkey); +OPENSSL_EXPORT PKCS8_PRIV_KEY_INFO *EVP_PKEY2PKCS8_broken(EVP_PKEY *pkey, int broken); +OPENSSL_EXPORT PKCS8_PRIV_KEY_INFO *PKCS8_set_broken(PKCS8_PRIV_KEY_INFO *p8, int broken); + +OPENSSL_EXPORT int PKCS8_pkey_set0(PKCS8_PRIV_KEY_INFO *priv, ASN1_OBJECT *aobj, + int version, int ptype, void *pval, + unsigned char *penc, int penclen); +OPENSSL_EXPORT int PKCS8_pkey_get0(ASN1_OBJECT **ppkalg, + const unsigned char **pk, int *ppklen, + X509_ALGOR **pa, + PKCS8_PRIV_KEY_INFO *p8); + +OPENSSL_EXPORT int X509_PUBKEY_set0_param(X509_PUBKEY *pub, const ASN1_OBJECT *aobj, + int ptype, void *pval, + unsigned char *penc, int penclen); +OPENSSL_EXPORT int X509_PUBKEY_get0_param(ASN1_OBJECT **ppkalg, + const unsigned char **pk, int *ppklen, + X509_ALGOR **pa, + X509_PUBKEY *pub); + +OPENSSL_EXPORT int X509_check_trust(X509 *x, int id, int flags); +OPENSSL_EXPORT int X509_TRUST_get_count(void); +OPENSSL_EXPORT X509_TRUST * X509_TRUST_get0(int idx); +OPENSSL_EXPORT int X509_TRUST_get_by_id(int id); +OPENSSL_EXPORT int X509_TRUST_add(int id, int flags, int (*ck)(X509_TRUST *, X509 *, int), + char *name, int arg1, void *arg2); +OPENSSL_EXPORT void X509_TRUST_cleanup(void); +OPENSSL_EXPORT int X509_TRUST_get_flags(X509_TRUST *xp); +OPENSSL_EXPORT char *X509_TRUST_get0_name(X509_TRUST *xp); +OPENSSL_EXPORT int X509_TRUST_get_trust(X509_TRUST *xp); + + +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) + + + +#ifdef __cplusplus +} +#endif + +#if !defined(BORINGSSL_NO_CXX) +extern "C++" { + +namespace bssl { + +BORINGSSL_MAKE_DELETER(NETSCAPE_SPKI, NETSCAPE_SPKI_free) +BORINGSSL_MAKE_DELETER(RSA_PSS_PARAMS, RSA_PSS_PARAMS_free) +BORINGSSL_MAKE_DELETER(X509, X509_free) +BORINGSSL_MAKE_DELETER(X509_ALGOR, X509_ALGOR_free) +BORINGSSL_MAKE_DELETER(X509_CRL, X509_CRL_free) +BORINGSSL_MAKE_DELETER(X509_CRL_METHOD, X509_CRL_METHOD_free) +BORINGSSL_MAKE_DELETER(X509_EXTENSION, X509_EXTENSION_free) +BORINGSSL_MAKE_DELETER(X509_INFO, X509_INFO_free) +BORINGSSL_MAKE_DELETER(X509_LOOKUP, X509_LOOKUP_free) +BORINGSSL_MAKE_DELETER(X509_NAME, X509_NAME_free) +BORINGSSL_MAKE_DELETER(X509_NAME_ENTRY, X509_NAME_ENTRY_free) +BORINGSSL_MAKE_DELETER(X509_PKEY, X509_PKEY_free) +BORINGSSL_MAKE_DELETER(X509_POLICY_TREE, X509_policy_tree_free) +BORINGSSL_MAKE_DELETER(X509_PUBKEY, X509_PUBKEY_free) +BORINGSSL_MAKE_DELETER(X509_REQ, X509_REQ_free) +BORINGSSL_MAKE_DELETER(X509_REVOKED, X509_REVOKED_free) +BORINGSSL_MAKE_DELETER(X509_SIG, X509_SIG_free) +BORINGSSL_MAKE_DELETER(X509_STORE, X509_STORE_free) +BORINGSSL_MAKE_DELETER(X509_STORE_CTX, X509_STORE_CTX_free) +BORINGSSL_MAKE_DELETER(X509_VERIFY_PARAM, X509_VERIFY_PARAM_free) + +using ScopedX509_STORE_CTX = + internal::StackAllocated; + +} // namespace bssl + +} /* extern C++ */ +#endif /* !BORINGSSL_NO_CXX */ + +#define X509_R_AKID_MISMATCH 100 +#define X509_R_BAD_PKCS7_VERSION 101 +#define X509_R_BAD_X509_FILETYPE 102 +#define X509_R_BASE64_DECODE_ERROR 103 +#define X509_R_CANT_CHECK_DH_KEY 104 +#define X509_R_CERT_ALREADY_IN_HASH_TABLE 105 +#define X509_R_CRL_ALREADY_DELTA 106 +#define X509_R_CRL_VERIFY_FAILURE 107 +#define X509_R_IDP_MISMATCH 108 +#define X509_R_INVALID_BIT_STRING_BITS_LEFT 109 +#define X509_R_INVALID_DIRECTORY 110 +#define X509_R_INVALID_FIELD_NAME 111 +#define X509_R_INVALID_PSS_PARAMETERS 112 +#define X509_R_INVALID_TRUST 113 +#define X509_R_ISSUER_MISMATCH 114 +#define X509_R_KEY_TYPE_MISMATCH 115 +#define X509_R_KEY_VALUES_MISMATCH 116 +#define X509_R_LOADING_CERT_DIR 117 +#define X509_R_LOADING_DEFAULTS 118 +#define X509_R_NEWER_CRL_NOT_NEWER 119 +#define X509_R_NOT_PKCS7_SIGNED_DATA 120 +#define X509_R_NO_CERTIFICATES_INCLUDED 121 +#define X509_R_NO_CERT_SET_FOR_US_TO_VERIFY 122 +#define X509_R_NO_CRLS_INCLUDED 123 +#define X509_R_NO_CRL_NUMBER 124 +#define X509_R_PUBLIC_KEY_DECODE_ERROR 125 +#define X509_R_PUBLIC_KEY_ENCODE_ERROR 126 +#define X509_R_SHOULD_RETRY 127 +#define X509_R_UNKNOWN_KEY_TYPE 128 +#define X509_R_UNKNOWN_NID 129 +#define X509_R_UNKNOWN_PURPOSE_ID 130 +#define X509_R_UNKNOWN_TRUST_ID 131 +#define X509_R_UNSUPPORTED_ALGORITHM 132 +#define X509_R_WRONG_LOOKUP_TYPE 133 +#define X509_R_WRONG_TYPE 134 +#define X509_R_NAME_TOO_LONG 135 +#define X509_R_INVALID_PARAMETER 136 + +#endif diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/x509_vfy.h b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/x509_vfy.h new file mode 100644 index 0000000..10b4e00 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/x509_vfy.h @@ -0,0 +1,614 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 +/* 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 + +#ifdef __cplusplus +extern "C" { +#endif + +/* Legacy X.509 library. + * + * This header is part of OpenSSL's X.509 implementation. It is retained for + * compatibility but otherwise underdocumented and not actively maintained. In + * the future, a replacement library will be available. Meanwhile, minimize + * dependencies on this header where possible. */ + + +/*******************************/ +/* +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_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; + +DEFINE_STACK_OF(X509_LOOKUP) +DEFINE_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 + */ + +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 */ + }; + +DEFINE_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 */ + CRYPTO_MUTEX objs_lock; + STACK_OF(X509) *additional_untrusted; + + /* These are external lookup methods */ + STACK_OF(X509_LOOKUP) *get_cert_methods; + + X509_VERIFY_PARAM *param; + + /* Callbacks for various operations */ + int (*verify)(X509_STORE_CTX *ctx); /* called to verify a certificate */ + int (*verify_cb)(int ok,X509_STORE_CTX *ctx); /* error callback */ + int (*get_issuer)(X509 **issuer, X509_STORE_CTX *ctx, X509 *x); /* get issuers cert from ctx */ + int (*check_issued)(X509_STORE_CTX *ctx, X509 *x, X509 *issuer); /* check issued */ + int (*check_revocation)(X509_STORE_CTX *ctx); /* Check revocation status of chain */ + int (*get_crl)(X509_STORE_CTX *ctx, X509_CRL **crl, X509 *x); /* retrieve CRL */ + int (*check_crl)(X509_STORE_CTX *ctx, X509_CRL *crl); /* Check CRL validity */ + int (*cert_crl)(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x); /* Check certificate against CRL */ + 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_refcount_t references; + } /* X509_STORE */; + +OPENSSL_EXPORT 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; + + /* The following are set by the caller */ + X509 *cert; /* The cert to check */ + STACK_OF(X509) *untrusted; /* chain of X509s - untrusted - passed in */ + STACK_OF(X509_CRL) *crls; /* set of CRLs passed in */ + + X509_VERIFY_PARAM *param; + void *other_ctx; /* Other info for use with get_issuer() */ + + /* Callbacks for various operations */ + int (*verify)(X509_STORE_CTX *ctx); /* called to verify a certificate */ + int (*verify_cb)(int ok,X509_STORE_CTX *ctx); /* error callback */ + int (*get_issuer)(X509 **issuer, X509_STORE_CTX *ctx, X509 *x); /* get issuers cert from ctx */ + int (*check_issued)(X509_STORE_CTX *ctx, X509 *x, X509 *issuer); /* check issued */ + int (*check_revocation)(X509_STORE_CTX *ctx); /* Check revocation status of chain */ + int (*get_crl)(X509_STORE_CTX *ctx, X509_CRL **crl, X509 *x); /* retrieve CRL */ + int (*check_crl)(X509_STORE_CTX *ctx, X509_CRL *crl); /* Check CRL validity */ + int (*cert_crl)(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x); /* Check certificate against CRL */ + 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 */ + int valid; /* if 0, rebuild chain */ + int last_untrusted; /* index of last untrusted cert */ + STACK_OF(X509) *chain; /* chain of X509s - built up and trusted */ + X509_POLICY_TREE *tree; /* Valid policy tree */ + + int explicit_policy; /* Require explicit policy value */ + + /* When something goes wrong, this is why */ + int error_depth; + int error; + X509 *current_cert; + X509 *current_issuer; /* cert currently being tested as valid issuer */ + X509_CRL *current_crl; /* current CRL */ + + int current_crl_score; /* score of current CRL */ + unsigned int current_reasons; /* Reason mask */ + + X509_STORE_CTX *parent; /* For CRL path validation: parent context */ + + CRYPTO_EX_DATA ex_data; + } /* X509_STORE_CTX */; + +OPENSSL_EXPORT 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 + +/* 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) + +OPENSSL_EXPORT int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, int type, + X509_NAME *name); +OPENSSL_EXPORT X509_OBJECT *X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h,int type,X509_NAME *name); +OPENSSL_EXPORT X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h, X509_OBJECT *x); +OPENSSL_EXPORT int X509_OBJECT_up_ref_count(X509_OBJECT *a); +OPENSSL_EXPORT void X509_OBJECT_free_contents(X509_OBJECT *a); +OPENSSL_EXPORT int X509_OBJECT_get_type(const X509_OBJECT *a); +OPENSSL_EXPORT X509 *X509_OBJECT_get0_X509(const X509_OBJECT *a); +OPENSSL_EXPORT X509_STORE *X509_STORE_new(void ); +OPENSSL_EXPORT int X509_STORE_up_ref(X509_STORE *store); +OPENSSL_EXPORT void X509_STORE_free(X509_STORE *v); + +OPENSSL_EXPORT STACK_OF(X509_OBJECT) *X509_STORE_get0_objects(X509_STORE *st); +OPENSSL_EXPORT STACK_OF(X509)* X509_STORE_get1_certs(X509_STORE_CTX *st, X509_NAME *nm); +OPENSSL_EXPORT STACK_OF(X509_CRL)* X509_STORE_get1_crls(X509_STORE_CTX *st, X509_NAME *nm); +OPENSSL_EXPORT int X509_STORE_set_flags(X509_STORE *ctx, unsigned long flags); +OPENSSL_EXPORT int X509_STORE_set_purpose(X509_STORE *ctx, int purpose); +OPENSSL_EXPORT int X509_STORE_set_trust(X509_STORE *ctx, int trust); +OPENSSL_EXPORT int X509_STORE_set1_param(X509_STORE *ctx, X509_VERIFY_PARAM *pm); +OPENSSL_EXPORT X509_VERIFY_PARAM *X509_STORE_get0_param(X509_STORE *ctx); +/* X509_STORE_set0_additional_untrusted sets a stack of additional, untrusted + * certificates that are available for chain building. This function does not + * take ownership of the stack. */ +OPENSSL_EXPORT void X509_STORE_set0_additional_untrusted( + X509_STORE *ctx, STACK_OF(X509) *untrusted); + +OPENSSL_EXPORT void X509_STORE_set_verify_cb(X509_STORE *ctx, + int (*verify_cb)(int, X509_STORE_CTX *)); + +OPENSSL_EXPORT void X509_STORE_set_lookup_crls_cb(X509_STORE *ctx, + STACK_OF(X509_CRL)* (*cb)(X509_STORE_CTX *ctx, X509_NAME *nm)); + +OPENSSL_EXPORT X509_STORE_CTX *X509_STORE_CTX_new(void); + +OPENSSL_EXPORT int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x); + +OPENSSL_EXPORT void X509_STORE_CTX_zero(X509_STORE_CTX *ctx); +OPENSSL_EXPORT void X509_STORE_CTX_free(X509_STORE_CTX *ctx); +OPENSSL_EXPORT int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, + X509 *x509, STACK_OF(X509) *chain); +OPENSSL_EXPORT void X509_STORE_CTX_trusted_stack(X509_STORE_CTX *ctx, STACK_OF(X509) *sk); +OPENSSL_EXPORT void X509_STORE_CTX_cleanup(X509_STORE_CTX *ctx); + +OPENSSL_EXPORT X509_STORE *X509_STORE_CTX_get0_store(X509_STORE_CTX *ctx); + +OPENSSL_EXPORT X509_LOOKUP *X509_STORE_add_lookup(X509_STORE *v, X509_LOOKUP_METHOD *m); + +OPENSSL_EXPORT X509_LOOKUP_METHOD *X509_LOOKUP_hash_dir(void); +OPENSSL_EXPORT X509_LOOKUP_METHOD *X509_LOOKUP_file(void); + +OPENSSL_EXPORT int X509_STORE_add_cert(X509_STORE *ctx, X509 *x); +OPENSSL_EXPORT int X509_STORE_add_crl(X509_STORE *ctx, X509_CRL *x); + +OPENSSL_EXPORT int X509_STORE_get_by_subject(X509_STORE_CTX *vs,int type,X509_NAME *name, + X509_OBJECT *ret); + +OPENSSL_EXPORT int X509_LOOKUP_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, + long argl, char **ret); + +#ifndef OPENSSL_NO_STDIO +OPENSSL_EXPORT int X509_load_cert_file(X509_LOOKUP *ctx, const char *file, int type); +OPENSSL_EXPORT int X509_load_crl_file(X509_LOOKUP *ctx, const char *file, int type); +OPENSSL_EXPORT int X509_load_cert_crl_file(X509_LOOKUP *ctx, const char *file, int type); +#endif + + +OPENSSL_EXPORT X509_LOOKUP *X509_LOOKUP_new(X509_LOOKUP_METHOD *method); +OPENSSL_EXPORT void X509_LOOKUP_free(X509_LOOKUP *ctx); +OPENSSL_EXPORT int X509_LOOKUP_init(X509_LOOKUP *ctx); +OPENSSL_EXPORT int X509_LOOKUP_by_subject(X509_LOOKUP *ctx, int type, X509_NAME *name, + X509_OBJECT *ret); +OPENSSL_EXPORT int X509_LOOKUP_by_issuer_serial(X509_LOOKUP *ctx, int type, X509_NAME *name, + ASN1_INTEGER *serial, X509_OBJECT *ret); +OPENSSL_EXPORT int X509_LOOKUP_by_fingerprint(X509_LOOKUP *ctx, int type, + unsigned char *bytes, int len, X509_OBJECT *ret); +OPENSSL_EXPORT int X509_LOOKUP_by_alias(X509_LOOKUP *ctx, int type, char *str, + int len, X509_OBJECT *ret); +OPENSSL_EXPORT int X509_LOOKUP_shutdown(X509_LOOKUP *ctx); + +#ifndef OPENSSL_NO_STDIO +OPENSSL_EXPORT int X509_STORE_load_locations (X509_STORE *ctx, + const char *file, const char *dir); +OPENSSL_EXPORT int X509_STORE_set_default_paths(X509_STORE *ctx); +#endif + +OPENSSL_EXPORT int X509_STORE_CTX_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused *unused, + CRYPTO_EX_dup *dup_unused, CRYPTO_EX_free *free_func); +OPENSSL_EXPORT int X509_STORE_CTX_set_ex_data(X509_STORE_CTX *ctx,int idx,void *data); +OPENSSL_EXPORT void * X509_STORE_CTX_get_ex_data(X509_STORE_CTX *ctx,int idx); +OPENSSL_EXPORT int X509_STORE_CTX_get_error(X509_STORE_CTX *ctx); +OPENSSL_EXPORT void X509_STORE_CTX_set_error(X509_STORE_CTX *ctx,int s); +OPENSSL_EXPORT int X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx); +OPENSSL_EXPORT X509 * X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx); +OPENSSL_EXPORT X509 *X509_STORE_CTX_get0_current_issuer(X509_STORE_CTX *ctx); +OPENSSL_EXPORT X509_CRL *X509_STORE_CTX_get0_current_crl(X509_STORE_CTX *ctx); +OPENSSL_EXPORT X509_STORE_CTX *X509_STORE_CTX_get0_parent_ctx(X509_STORE_CTX *ctx); +OPENSSL_EXPORT STACK_OF(X509) *X509_STORE_CTX_get_chain(X509_STORE_CTX *ctx); +OPENSSL_EXPORT STACK_OF(X509) *X509_STORE_CTX_get1_chain(X509_STORE_CTX *ctx); +OPENSSL_EXPORT void X509_STORE_CTX_set_cert(X509_STORE_CTX *c,X509 *x); +OPENSSL_EXPORT void X509_STORE_CTX_set_chain(X509_STORE_CTX *c,STACK_OF(X509) *sk); +OPENSSL_EXPORT STACK_OF(X509) * + X509_STORE_CTX_get0_untrusted(X509_STORE_CTX *ctx); +OPENSSL_EXPORT void X509_STORE_CTX_set0_crls(X509_STORE_CTX *c,STACK_OF(X509_CRL) *sk); +OPENSSL_EXPORT int X509_STORE_CTX_set_purpose(X509_STORE_CTX *ctx, int purpose); +OPENSSL_EXPORT int X509_STORE_CTX_set_trust(X509_STORE_CTX *ctx, int trust); +OPENSSL_EXPORT int X509_STORE_CTX_purpose_inherit(X509_STORE_CTX *ctx, int def_purpose, + int purpose, int trust); +OPENSSL_EXPORT void X509_STORE_CTX_set_flags(X509_STORE_CTX *ctx, unsigned long flags); +OPENSSL_EXPORT void X509_STORE_CTX_set_time(X509_STORE_CTX *ctx, unsigned long flags, + time_t t); +OPENSSL_EXPORT void X509_STORE_CTX_set_verify_cb(X509_STORE_CTX *ctx, + int (*verify_cb)(int, X509_STORE_CTX *)); + +OPENSSL_EXPORT X509_POLICY_TREE *X509_STORE_CTX_get0_policy_tree(X509_STORE_CTX *ctx); +OPENSSL_EXPORT int X509_STORE_CTX_get_explicit_policy(X509_STORE_CTX *ctx); + +OPENSSL_EXPORT X509_VERIFY_PARAM *X509_STORE_CTX_get0_param(X509_STORE_CTX *ctx); +OPENSSL_EXPORT void X509_STORE_CTX_set0_param(X509_STORE_CTX *ctx, X509_VERIFY_PARAM *param); +OPENSSL_EXPORT int X509_STORE_CTX_set_default(X509_STORE_CTX *ctx, const char *name); + +/* X509_VERIFY_PARAM functions */ + +OPENSSL_EXPORT X509_VERIFY_PARAM *X509_VERIFY_PARAM_new(void); +OPENSSL_EXPORT void X509_VERIFY_PARAM_free(X509_VERIFY_PARAM *param); +OPENSSL_EXPORT int X509_VERIFY_PARAM_inherit(X509_VERIFY_PARAM *to, + const X509_VERIFY_PARAM *from); +OPENSSL_EXPORT int X509_VERIFY_PARAM_set1(X509_VERIFY_PARAM *to, + const X509_VERIFY_PARAM *from); +OPENSSL_EXPORT int X509_VERIFY_PARAM_set1_name(X509_VERIFY_PARAM *param, const char *name); +OPENSSL_EXPORT int X509_VERIFY_PARAM_set_flags(X509_VERIFY_PARAM *param, unsigned long flags); +OPENSSL_EXPORT int X509_VERIFY_PARAM_clear_flags(X509_VERIFY_PARAM *param, + unsigned long flags); +OPENSSL_EXPORT unsigned long X509_VERIFY_PARAM_get_flags(X509_VERIFY_PARAM *param); +OPENSSL_EXPORT int X509_VERIFY_PARAM_set_purpose(X509_VERIFY_PARAM *param, int purpose); +OPENSSL_EXPORT int X509_VERIFY_PARAM_set_trust(X509_VERIFY_PARAM *param, int trust); +OPENSSL_EXPORT void X509_VERIFY_PARAM_set_depth(X509_VERIFY_PARAM *param, int depth); +OPENSSL_EXPORT void X509_VERIFY_PARAM_set_time(X509_VERIFY_PARAM *param, time_t t); +OPENSSL_EXPORT int X509_VERIFY_PARAM_add0_policy(X509_VERIFY_PARAM *param, + ASN1_OBJECT *policy); +OPENSSL_EXPORT int X509_VERIFY_PARAM_set1_policies(X509_VERIFY_PARAM *param, + STACK_OF(ASN1_OBJECT) *policies); + +OPENSSL_EXPORT int X509_VERIFY_PARAM_set1_host(X509_VERIFY_PARAM *param, + const char *name, size_t namelen); +OPENSSL_EXPORT int X509_VERIFY_PARAM_add1_host(X509_VERIFY_PARAM *param, + const char *name, + size_t namelen); +OPENSSL_EXPORT void X509_VERIFY_PARAM_set_hostflags(X509_VERIFY_PARAM *param, + unsigned int flags); +OPENSSL_EXPORT char *X509_VERIFY_PARAM_get0_peername(X509_VERIFY_PARAM *); +OPENSSL_EXPORT int X509_VERIFY_PARAM_set1_email(X509_VERIFY_PARAM *param, + const char *email, size_t emaillen); +OPENSSL_EXPORT int X509_VERIFY_PARAM_set1_ip(X509_VERIFY_PARAM *param, + const unsigned char *ip, size_t iplen); +OPENSSL_EXPORT int X509_VERIFY_PARAM_set1_ip_asc(X509_VERIFY_PARAM *param, const char *ipasc); + +OPENSSL_EXPORT int X509_VERIFY_PARAM_get_depth(const X509_VERIFY_PARAM *param); +OPENSSL_EXPORT const char *X509_VERIFY_PARAM_get0_name(const X509_VERIFY_PARAM *param); + +OPENSSL_EXPORT int X509_VERIFY_PARAM_add0_table(X509_VERIFY_PARAM *param); +OPENSSL_EXPORT int X509_VERIFY_PARAM_get_count(void); +OPENSSL_EXPORT const X509_VERIFY_PARAM *X509_VERIFY_PARAM_get0(int id); +OPENSSL_EXPORT const X509_VERIFY_PARAM *X509_VERIFY_PARAM_lookup(const char *name); +OPENSSL_EXPORT void X509_VERIFY_PARAM_table_cleanup(void); + +OPENSSL_EXPORT int X509_policy_check(X509_POLICY_TREE **ptree, int *pexplicit_policy, + STACK_OF(X509) *certs, + STACK_OF(ASN1_OBJECT) *policy_oids, + unsigned int flags); + +OPENSSL_EXPORT void X509_policy_tree_free(X509_POLICY_TREE *tree); + +OPENSSL_EXPORT int X509_policy_tree_level_count(const X509_POLICY_TREE *tree); +OPENSSL_EXPORT X509_POLICY_LEVEL * + X509_policy_tree_get0_level(const X509_POLICY_TREE *tree, int i); + +OPENSSL_EXPORT STACK_OF(X509_POLICY_NODE) * + X509_policy_tree_get0_policies(const X509_POLICY_TREE *tree); + +OPENSSL_EXPORT STACK_OF(X509_POLICY_NODE) * + X509_policy_tree_get0_user_policies(const X509_POLICY_TREE *tree); + +OPENSSL_EXPORT int X509_policy_level_node_count(X509_POLICY_LEVEL *level); + +OPENSSL_EXPORT X509_POLICY_NODE *X509_policy_level_get0_node(X509_POLICY_LEVEL *level, int i); + +OPENSSL_EXPORT const ASN1_OBJECT *X509_policy_node_get0_policy(const X509_POLICY_NODE *node); + +OPENSSL_EXPORT STACK_OF(POLICYQUALINFO) * + X509_policy_node_get0_qualifiers(const X509_POLICY_NODE *node); +OPENSSL_EXPORT const X509_POLICY_NODE * + X509_policy_node_get0_parent(const X509_POLICY_NODE *node); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/x509_vfy.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/x509_vfy.h.grpc_back new file mode 100644 index 0000000..208a380 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/x509_vfy.h.grpc_back @@ -0,0 +1,614 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 +/* 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 + +#ifdef __cplusplus +extern "C" { +#endif + +/* Legacy X.509 library. + * + * This header is part of OpenSSL's X.509 implementation. It is retained for + * compatibility but otherwise underdocumented and not actively maintained. In + * the future, a replacement library will be available. Meanwhile, minimize + * dependencies on this header where possible. */ + + +/*******************************/ +/* +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_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; + +DEFINE_STACK_OF(X509_LOOKUP) +DEFINE_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 + */ + +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 */ + }; + +DEFINE_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 */ + CRYPTO_MUTEX objs_lock; + STACK_OF(X509) *additional_untrusted; + + /* These are external lookup methods */ + STACK_OF(X509_LOOKUP) *get_cert_methods; + + X509_VERIFY_PARAM *param; + + /* Callbacks for various operations */ + int (*verify)(X509_STORE_CTX *ctx); /* called to verify a certificate */ + int (*verify_cb)(int ok,X509_STORE_CTX *ctx); /* error callback */ + int (*get_issuer)(X509 **issuer, X509_STORE_CTX *ctx, X509 *x); /* get issuers cert from ctx */ + int (*check_issued)(X509_STORE_CTX *ctx, X509 *x, X509 *issuer); /* check issued */ + int (*check_revocation)(X509_STORE_CTX *ctx); /* Check revocation status of chain */ + int (*get_crl)(X509_STORE_CTX *ctx, X509_CRL **crl, X509 *x); /* retrieve CRL */ + int (*check_crl)(X509_STORE_CTX *ctx, X509_CRL *crl); /* Check CRL validity */ + int (*cert_crl)(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x); /* Check certificate against CRL */ + 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_refcount_t references; + } /* X509_STORE */; + +OPENSSL_EXPORT 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; + + /* The following are set by the caller */ + X509 *cert; /* The cert to check */ + STACK_OF(X509) *untrusted; /* chain of X509s - untrusted - passed in */ + STACK_OF(X509_CRL) *crls; /* set of CRLs passed in */ + + X509_VERIFY_PARAM *param; + void *other_ctx; /* Other info for use with get_issuer() */ + + /* Callbacks for various operations */ + int (*verify)(X509_STORE_CTX *ctx); /* called to verify a certificate */ + int (*verify_cb)(int ok,X509_STORE_CTX *ctx); /* error callback */ + int (*get_issuer)(X509 **issuer, X509_STORE_CTX *ctx, X509 *x); /* get issuers cert from ctx */ + int (*check_issued)(X509_STORE_CTX *ctx, X509 *x, X509 *issuer); /* check issued */ + int (*check_revocation)(X509_STORE_CTX *ctx); /* Check revocation status of chain */ + int (*get_crl)(X509_STORE_CTX *ctx, X509_CRL **crl, X509 *x); /* retrieve CRL */ + int (*check_crl)(X509_STORE_CTX *ctx, X509_CRL *crl); /* Check CRL validity */ + int (*cert_crl)(X509_STORE_CTX *ctx, X509_CRL *crl, X509 *x); /* Check certificate against CRL */ + 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 */ + int valid; /* if 0, rebuild chain */ + int last_untrusted; /* index of last untrusted cert */ + STACK_OF(X509) *chain; /* chain of X509s - built up and trusted */ + X509_POLICY_TREE *tree; /* Valid policy tree */ + + int explicit_policy; /* Require explicit policy value */ + + /* When something goes wrong, this is why */ + int error_depth; + int error; + X509 *current_cert; + X509 *current_issuer; /* cert currently being tested as valid issuer */ + X509_CRL *current_crl; /* current CRL */ + + int current_crl_score; /* score of current CRL */ + unsigned int current_reasons; /* Reason mask */ + + X509_STORE_CTX *parent; /* For CRL path validation: parent context */ + + CRYPTO_EX_DATA ex_data; + } /* X509_STORE_CTX */; + +OPENSSL_EXPORT 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 + +/* 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) + +OPENSSL_EXPORT int X509_OBJECT_idx_by_subject(STACK_OF(X509_OBJECT) *h, int type, + X509_NAME *name); +OPENSSL_EXPORT X509_OBJECT *X509_OBJECT_retrieve_by_subject(STACK_OF(X509_OBJECT) *h,int type,X509_NAME *name); +OPENSSL_EXPORT X509_OBJECT *X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h, X509_OBJECT *x); +OPENSSL_EXPORT int X509_OBJECT_up_ref_count(X509_OBJECT *a); +OPENSSL_EXPORT void X509_OBJECT_free_contents(X509_OBJECT *a); +OPENSSL_EXPORT int X509_OBJECT_get_type(const X509_OBJECT *a); +OPENSSL_EXPORT X509 *X509_OBJECT_get0_X509(const X509_OBJECT *a); +OPENSSL_EXPORT X509_STORE *X509_STORE_new(void ); +OPENSSL_EXPORT int X509_STORE_up_ref(X509_STORE *store); +OPENSSL_EXPORT void X509_STORE_free(X509_STORE *v); + +OPENSSL_EXPORT STACK_OF(X509_OBJECT) *X509_STORE_get0_objects(X509_STORE *st); +OPENSSL_EXPORT STACK_OF(X509)* X509_STORE_get1_certs(X509_STORE_CTX *st, X509_NAME *nm); +OPENSSL_EXPORT STACK_OF(X509_CRL)* X509_STORE_get1_crls(X509_STORE_CTX *st, X509_NAME *nm); +OPENSSL_EXPORT int X509_STORE_set_flags(X509_STORE *ctx, unsigned long flags); +OPENSSL_EXPORT int X509_STORE_set_purpose(X509_STORE *ctx, int purpose); +OPENSSL_EXPORT int X509_STORE_set_trust(X509_STORE *ctx, int trust); +OPENSSL_EXPORT int X509_STORE_set1_param(X509_STORE *ctx, X509_VERIFY_PARAM *pm); +OPENSSL_EXPORT X509_VERIFY_PARAM *X509_STORE_get0_param(X509_STORE *ctx); +/* X509_STORE_set0_additional_untrusted sets a stack of additional, untrusted + * certificates that are available for chain building. This function does not + * take ownership of the stack. */ +OPENSSL_EXPORT void X509_STORE_set0_additional_untrusted( + X509_STORE *ctx, STACK_OF(X509) *untrusted); + +OPENSSL_EXPORT void X509_STORE_set_verify_cb(X509_STORE *ctx, + int (*verify_cb)(int, X509_STORE_CTX *)); + +OPENSSL_EXPORT void X509_STORE_set_lookup_crls_cb(X509_STORE *ctx, + STACK_OF(X509_CRL)* (*cb)(X509_STORE_CTX *ctx, X509_NAME *nm)); + +OPENSSL_EXPORT X509_STORE_CTX *X509_STORE_CTX_new(void); + +OPENSSL_EXPORT int X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x); + +OPENSSL_EXPORT void X509_STORE_CTX_zero(X509_STORE_CTX *ctx); +OPENSSL_EXPORT void X509_STORE_CTX_free(X509_STORE_CTX *ctx); +OPENSSL_EXPORT int X509_STORE_CTX_init(X509_STORE_CTX *ctx, X509_STORE *store, + X509 *x509, STACK_OF(X509) *chain); +OPENSSL_EXPORT void X509_STORE_CTX_trusted_stack(X509_STORE_CTX *ctx, STACK_OF(X509) *sk); +OPENSSL_EXPORT void X509_STORE_CTX_cleanup(X509_STORE_CTX *ctx); + +OPENSSL_EXPORT X509_STORE *X509_STORE_CTX_get0_store(X509_STORE_CTX *ctx); + +OPENSSL_EXPORT X509_LOOKUP *X509_STORE_add_lookup(X509_STORE *v, X509_LOOKUP_METHOD *m); + +OPENSSL_EXPORT X509_LOOKUP_METHOD *X509_LOOKUP_hash_dir(void); +OPENSSL_EXPORT X509_LOOKUP_METHOD *X509_LOOKUP_file(void); + +OPENSSL_EXPORT int X509_STORE_add_cert(X509_STORE *ctx, X509 *x); +OPENSSL_EXPORT int X509_STORE_add_crl(X509_STORE *ctx, X509_CRL *x); + +OPENSSL_EXPORT int X509_STORE_get_by_subject(X509_STORE_CTX *vs,int type,X509_NAME *name, + X509_OBJECT *ret); + +OPENSSL_EXPORT int X509_LOOKUP_ctrl(X509_LOOKUP *ctx, int cmd, const char *argc, + long argl, char **ret); + +#ifndef OPENSSL_NO_STDIO +OPENSSL_EXPORT int X509_load_cert_file(X509_LOOKUP *ctx, const char *file, int type); +OPENSSL_EXPORT int X509_load_crl_file(X509_LOOKUP *ctx, const char *file, int type); +OPENSSL_EXPORT int X509_load_cert_crl_file(X509_LOOKUP *ctx, const char *file, int type); +#endif + + +OPENSSL_EXPORT X509_LOOKUP *X509_LOOKUP_new(X509_LOOKUP_METHOD *method); +OPENSSL_EXPORT void X509_LOOKUP_free(X509_LOOKUP *ctx); +OPENSSL_EXPORT int X509_LOOKUP_init(X509_LOOKUP *ctx); +OPENSSL_EXPORT int X509_LOOKUP_by_subject(X509_LOOKUP *ctx, int type, X509_NAME *name, + X509_OBJECT *ret); +OPENSSL_EXPORT int X509_LOOKUP_by_issuer_serial(X509_LOOKUP *ctx, int type, X509_NAME *name, + ASN1_INTEGER *serial, X509_OBJECT *ret); +OPENSSL_EXPORT int X509_LOOKUP_by_fingerprint(X509_LOOKUP *ctx, int type, + unsigned char *bytes, int len, X509_OBJECT *ret); +OPENSSL_EXPORT int X509_LOOKUP_by_alias(X509_LOOKUP *ctx, int type, char *str, + int len, X509_OBJECT *ret); +OPENSSL_EXPORT int X509_LOOKUP_shutdown(X509_LOOKUP *ctx); + +#ifndef OPENSSL_NO_STDIO +OPENSSL_EXPORT int X509_STORE_load_locations (X509_STORE *ctx, + const char *file, const char *dir); +OPENSSL_EXPORT int X509_STORE_set_default_paths(X509_STORE *ctx); +#endif + +OPENSSL_EXPORT int X509_STORE_CTX_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused *unused, + CRYPTO_EX_dup *dup_unused, CRYPTO_EX_free *free_func); +OPENSSL_EXPORT int X509_STORE_CTX_set_ex_data(X509_STORE_CTX *ctx,int idx,void *data); +OPENSSL_EXPORT void * X509_STORE_CTX_get_ex_data(X509_STORE_CTX *ctx,int idx); +OPENSSL_EXPORT int X509_STORE_CTX_get_error(X509_STORE_CTX *ctx); +OPENSSL_EXPORT void X509_STORE_CTX_set_error(X509_STORE_CTX *ctx,int s); +OPENSSL_EXPORT int X509_STORE_CTX_get_error_depth(X509_STORE_CTX *ctx); +OPENSSL_EXPORT X509 * X509_STORE_CTX_get_current_cert(X509_STORE_CTX *ctx); +OPENSSL_EXPORT X509 *X509_STORE_CTX_get0_current_issuer(X509_STORE_CTX *ctx); +OPENSSL_EXPORT X509_CRL *X509_STORE_CTX_get0_current_crl(X509_STORE_CTX *ctx); +OPENSSL_EXPORT X509_STORE_CTX *X509_STORE_CTX_get0_parent_ctx(X509_STORE_CTX *ctx); +OPENSSL_EXPORT STACK_OF(X509) *X509_STORE_CTX_get_chain(X509_STORE_CTX *ctx); +OPENSSL_EXPORT STACK_OF(X509) *X509_STORE_CTX_get1_chain(X509_STORE_CTX *ctx); +OPENSSL_EXPORT void X509_STORE_CTX_set_cert(X509_STORE_CTX *c,X509 *x); +OPENSSL_EXPORT void X509_STORE_CTX_set_chain(X509_STORE_CTX *c,STACK_OF(X509) *sk); +OPENSSL_EXPORT STACK_OF(X509) * + X509_STORE_CTX_get0_untrusted(X509_STORE_CTX *ctx); +OPENSSL_EXPORT void X509_STORE_CTX_set0_crls(X509_STORE_CTX *c,STACK_OF(X509_CRL) *sk); +OPENSSL_EXPORT int X509_STORE_CTX_set_purpose(X509_STORE_CTX *ctx, int purpose); +OPENSSL_EXPORT int X509_STORE_CTX_set_trust(X509_STORE_CTX *ctx, int trust); +OPENSSL_EXPORT int X509_STORE_CTX_purpose_inherit(X509_STORE_CTX *ctx, int def_purpose, + int purpose, int trust); +OPENSSL_EXPORT void X509_STORE_CTX_set_flags(X509_STORE_CTX *ctx, unsigned long flags); +OPENSSL_EXPORT void X509_STORE_CTX_set_time(X509_STORE_CTX *ctx, unsigned long flags, + time_t t); +OPENSSL_EXPORT void X509_STORE_CTX_set_verify_cb(X509_STORE_CTX *ctx, + int (*verify_cb)(int, X509_STORE_CTX *)); + +OPENSSL_EXPORT X509_POLICY_TREE *X509_STORE_CTX_get0_policy_tree(X509_STORE_CTX *ctx); +OPENSSL_EXPORT int X509_STORE_CTX_get_explicit_policy(X509_STORE_CTX *ctx); + +OPENSSL_EXPORT X509_VERIFY_PARAM *X509_STORE_CTX_get0_param(X509_STORE_CTX *ctx); +OPENSSL_EXPORT void X509_STORE_CTX_set0_param(X509_STORE_CTX *ctx, X509_VERIFY_PARAM *param); +OPENSSL_EXPORT int X509_STORE_CTX_set_default(X509_STORE_CTX *ctx, const char *name); + +/* X509_VERIFY_PARAM functions */ + +OPENSSL_EXPORT X509_VERIFY_PARAM *X509_VERIFY_PARAM_new(void); +OPENSSL_EXPORT void X509_VERIFY_PARAM_free(X509_VERIFY_PARAM *param); +OPENSSL_EXPORT int X509_VERIFY_PARAM_inherit(X509_VERIFY_PARAM *to, + const X509_VERIFY_PARAM *from); +OPENSSL_EXPORT int X509_VERIFY_PARAM_set1(X509_VERIFY_PARAM *to, + const X509_VERIFY_PARAM *from); +OPENSSL_EXPORT int X509_VERIFY_PARAM_set1_name(X509_VERIFY_PARAM *param, const char *name); +OPENSSL_EXPORT int X509_VERIFY_PARAM_set_flags(X509_VERIFY_PARAM *param, unsigned long flags); +OPENSSL_EXPORT int X509_VERIFY_PARAM_clear_flags(X509_VERIFY_PARAM *param, + unsigned long flags); +OPENSSL_EXPORT unsigned long X509_VERIFY_PARAM_get_flags(X509_VERIFY_PARAM *param); +OPENSSL_EXPORT int X509_VERIFY_PARAM_set_purpose(X509_VERIFY_PARAM *param, int purpose); +OPENSSL_EXPORT int X509_VERIFY_PARAM_set_trust(X509_VERIFY_PARAM *param, int trust); +OPENSSL_EXPORT void X509_VERIFY_PARAM_set_depth(X509_VERIFY_PARAM *param, int depth); +OPENSSL_EXPORT void X509_VERIFY_PARAM_set_time(X509_VERIFY_PARAM *param, time_t t); +OPENSSL_EXPORT int X509_VERIFY_PARAM_add0_policy(X509_VERIFY_PARAM *param, + ASN1_OBJECT *policy); +OPENSSL_EXPORT int X509_VERIFY_PARAM_set1_policies(X509_VERIFY_PARAM *param, + STACK_OF(ASN1_OBJECT) *policies); + +OPENSSL_EXPORT int X509_VERIFY_PARAM_set1_host(X509_VERIFY_PARAM *param, + const char *name, size_t namelen); +OPENSSL_EXPORT int X509_VERIFY_PARAM_add1_host(X509_VERIFY_PARAM *param, + const char *name, + size_t namelen); +OPENSSL_EXPORT void X509_VERIFY_PARAM_set_hostflags(X509_VERIFY_PARAM *param, + unsigned int flags); +OPENSSL_EXPORT char *X509_VERIFY_PARAM_get0_peername(X509_VERIFY_PARAM *); +OPENSSL_EXPORT int X509_VERIFY_PARAM_set1_email(X509_VERIFY_PARAM *param, + const char *email, size_t emaillen); +OPENSSL_EXPORT int X509_VERIFY_PARAM_set1_ip(X509_VERIFY_PARAM *param, + const unsigned char *ip, size_t iplen); +OPENSSL_EXPORT int X509_VERIFY_PARAM_set1_ip_asc(X509_VERIFY_PARAM *param, const char *ipasc); + +OPENSSL_EXPORT int X509_VERIFY_PARAM_get_depth(const X509_VERIFY_PARAM *param); +OPENSSL_EXPORT const char *X509_VERIFY_PARAM_get0_name(const X509_VERIFY_PARAM *param); + +OPENSSL_EXPORT int X509_VERIFY_PARAM_add0_table(X509_VERIFY_PARAM *param); +OPENSSL_EXPORT int X509_VERIFY_PARAM_get_count(void); +OPENSSL_EXPORT const X509_VERIFY_PARAM *X509_VERIFY_PARAM_get0(int id); +OPENSSL_EXPORT const X509_VERIFY_PARAM *X509_VERIFY_PARAM_lookup(const char *name); +OPENSSL_EXPORT void X509_VERIFY_PARAM_table_cleanup(void); + +OPENSSL_EXPORT int X509_policy_check(X509_POLICY_TREE **ptree, int *pexplicit_policy, + STACK_OF(X509) *certs, + STACK_OF(ASN1_OBJECT) *policy_oids, + unsigned int flags); + +OPENSSL_EXPORT void X509_policy_tree_free(X509_POLICY_TREE *tree); + +OPENSSL_EXPORT int X509_policy_tree_level_count(const X509_POLICY_TREE *tree); +OPENSSL_EXPORT X509_POLICY_LEVEL * + X509_policy_tree_get0_level(const X509_POLICY_TREE *tree, int i); + +OPENSSL_EXPORT STACK_OF(X509_POLICY_NODE) * + X509_policy_tree_get0_policies(const X509_POLICY_TREE *tree); + +OPENSSL_EXPORT STACK_OF(X509_POLICY_NODE) * + X509_policy_tree_get0_user_policies(const X509_POLICY_TREE *tree); + +OPENSSL_EXPORT int X509_policy_level_node_count(X509_POLICY_LEVEL *level); + +OPENSSL_EXPORT X509_POLICY_NODE *X509_policy_level_get0_node(X509_POLICY_LEVEL *level, int i); + +OPENSSL_EXPORT const ASN1_OBJECT *X509_policy_node_get0_policy(const X509_POLICY_NODE *node); + +OPENSSL_EXPORT STACK_OF(POLICYQUALINFO) * + X509_policy_node_get0_qualifiers(const X509_POLICY_NODE *node); +OPENSSL_EXPORT const X509_POLICY_NODE * + X509_policy_node_get0_parent(const X509_POLICY_NODE *node); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/x509v3.h b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/x509v3.h new file mode 100644 index 0000000..6392995 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/x509v3.h @@ -0,0 +1,827 @@ +/* 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 +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Legacy X.509 library. + * + * This header is part of OpenSSL's X.509 implementation. It is retained for + * compatibility but otherwise underdocumented and not actively maintained. In + * the future, a replacement library will be available. Meanwhile, minimize + * dependencies on this header where possible. */ + + +/* 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; +const X509V3_CONF_METHOD *db_meth; +void *db; +/* Maybe more here */ +}; + +typedef struct v3_ext_method X509V3_EXT_METHOD; + +DEFINE_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; + +struct BASIC_CONSTRAINTS_st { +int ca; +ASN1_INTEGER *pathlen; +}; + + +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; + +DEFINE_STACK_OF(GENERAL_NAME) +DECLARE_ASN1_SET_OF(GENERAL_NAME) + +typedef STACK_OF(GENERAL_NAME) GENERAL_NAMES; + +DEFINE_STACK_OF(GENERAL_NAMES) + +typedef struct ACCESS_DESCRIPTION_st { + ASN1_OBJECT *method; + GENERAL_NAME *location; +} ACCESS_DESCRIPTION; + +DEFINE_STACK_OF(ACCESS_DESCRIPTION) +DECLARE_ASN1_SET_OF(ACCESS_DESCRIPTION) + +typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS; + +typedef STACK_OF(ASN1_OBJECT) EXTENDED_KEY_USAGE; + +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; + +DEFINE_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; + +DEFINE_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; + +DEFINE_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; + +DEFINE_STACK_OF(POLICYINFO) +DECLARE_ASN1_SET_OF(POLICYINFO) + +typedef struct POLICY_MAPPING_st { + ASN1_OBJECT *issuerDomainPolicy; + ASN1_OBJECT *subjectDomainPolicy; +} POLICY_MAPPING; + +DEFINE_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; + +DEFINE_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, \ + (void *)(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 + +DEFINE_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) +OPENSSL_EXPORT GENERAL_NAME *GENERAL_NAME_dup(GENERAL_NAME *a); +OPENSSL_EXPORT int GENERAL_NAME_cmp(GENERAL_NAME *a, GENERAL_NAME *b); + + + +OPENSSL_EXPORT ASN1_BIT_STRING *v2i_ASN1_BIT_STRING(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); +OPENSSL_EXPORT STACK_OF(CONF_VALUE) *i2v_ASN1_BIT_STRING(X509V3_EXT_METHOD *method, + ASN1_BIT_STRING *bits, + STACK_OF(CONF_VALUE) *extlist); + +OPENSSL_EXPORT STACK_OF(CONF_VALUE) *i2v_GENERAL_NAME(X509V3_EXT_METHOD *method, GENERAL_NAME *gen, STACK_OF(CONF_VALUE) *ret); +OPENSSL_EXPORT int GENERAL_NAME_print(BIO *out, GENERAL_NAME *gen); + +DECLARE_ASN1_FUNCTIONS(GENERAL_NAMES) + +OPENSSL_EXPORT STACK_OF(CONF_VALUE) *i2v_GENERAL_NAMES(X509V3_EXT_METHOD *method, + GENERAL_NAMES *gen, STACK_OF(CONF_VALUE) *extlist); +OPENSSL_EXPORT 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) +OPENSSL_EXPORT int OTHERNAME_cmp(OTHERNAME *a, OTHERNAME *b); +OPENSSL_EXPORT void GENERAL_NAME_set0_value(GENERAL_NAME *a, int type, void *value); +OPENSSL_EXPORT void *GENERAL_NAME_get0_value(GENERAL_NAME *a, int *ptype); +OPENSSL_EXPORT int GENERAL_NAME_set0_othername(GENERAL_NAME *gen, + ASN1_OBJECT *oid, ASN1_TYPE *value); +OPENSSL_EXPORT int GENERAL_NAME_get0_otherName(GENERAL_NAME *gen, + ASN1_OBJECT **poid, ASN1_TYPE **pvalue); + +OPENSSL_EXPORT char *i2s_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, ASN1_OCTET_STRING *ia5); +OPENSSL_EXPORT ASN1_OCTET_STRING *s2i_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, char *str); + +DECLARE_ASN1_FUNCTIONS(EXTENDED_KEY_USAGE) +OPENSSL_EXPORT 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) + +OPENSSL_EXPORT int DIST_POINT_set_dpname(DIST_POINT_NAME *dpn, X509_NAME *iname); + +OPENSSL_EXPORT 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) + +OPENSSL_EXPORT GENERAL_NAME *a2i_GENERAL_NAME(GENERAL_NAME *out, + const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, + int gen_type, char *value, int is_nc); + +OPENSSL_EXPORT GENERAL_NAME *v2i_GENERAL_NAME(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, + CONF_VALUE *cnf); +OPENSSL_EXPORT GENERAL_NAME *v2i_GENERAL_NAME_ex(GENERAL_NAME *out, + const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, CONF_VALUE *cnf, int is_nc); +OPENSSL_EXPORT void X509V3_conf_free(CONF_VALUE *val); + +OPENSSL_EXPORT X509_EXTENSION *X509V3_EXT_conf_nid(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, int ext_nid, char *value); +OPENSSL_EXPORT X509_EXTENSION *X509V3_EXT_nconf_nid(CONF *conf, X509V3_CTX *ctx, int ext_nid, char *value); +OPENSSL_EXPORT X509_EXTENSION *X509V3_EXT_nconf(CONF *conf, X509V3_CTX *ctx, char *name, char *value); +OPENSSL_EXPORT int X509V3_EXT_add_nconf_sk(CONF *conf, X509V3_CTX *ctx, char *section, STACK_OF(X509_EXTENSION) **sk); +OPENSSL_EXPORT int X509V3_EXT_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section, X509 *cert); +OPENSSL_EXPORT int X509V3_EXT_REQ_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section, X509_REQ *req); +OPENSSL_EXPORT int X509V3_EXT_CRL_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section, X509_CRL *crl); + +OPENSSL_EXPORT int X509V3_EXT_CRL_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, + char *section, X509_CRL *crl); + +OPENSSL_EXPORT int X509V3_add_value_bool_nf(char *name, int asn1_bool, + STACK_OF(CONF_VALUE) **extlist); +OPENSSL_EXPORT int X509V3_get_value_bool(CONF_VALUE *value, int *asn1_bool); +OPENSSL_EXPORT int X509V3_get_value_int(CONF_VALUE *value, ASN1_INTEGER **aint); +OPENSSL_EXPORT void X509V3_set_nconf(X509V3_CTX *ctx, CONF *conf); + +OPENSSL_EXPORT char * X509V3_get_string(X509V3_CTX *ctx, char *name, char *section); +OPENSSL_EXPORT STACK_OF(CONF_VALUE) * X509V3_get_section(X509V3_CTX *ctx, char *section); +OPENSSL_EXPORT void X509V3_string_free(X509V3_CTX *ctx, char *str); +OPENSSL_EXPORT void X509V3_section_free( X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *section); +OPENSSL_EXPORT void X509V3_set_ctx(X509V3_CTX *ctx, X509 *issuer, X509 *subject, + X509_REQ *req, X509_CRL *crl, int flags); + +OPENSSL_EXPORT int X509V3_add_value(const char *name, const char *value, + STACK_OF(CONF_VALUE) **extlist); +OPENSSL_EXPORT int X509V3_add_value_uchar(const char *name, const unsigned char *value, + STACK_OF(CONF_VALUE) **extlist); +OPENSSL_EXPORT int X509V3_add_value_bool(const char *name, int asn1_bool, + STACK_OF(CONF_VALUE) **extlist); +OPENSSL_EXPORT int X509V3_add_value_int(const char *name, ASN1_INTEGER *aint, + STACK_OF(CONF_VALUE) **extlist); +OPENSSL_EXPORT char * i2s_ASN1_INTEGER(X509V3_EXT_METHOD *meth, ASN1_INTEGER *aint); +OPENSSL_EXPORT ASN1_INTEGER * s2i_ASN1_INTEGER(X509V3_EXT_METHOD *meth, char *value); +OPENSSL_EXPORT char * i2s_ASN1_ENUMERATED(X509V3_EXT_METHOD *meth, ASN1_ENUMERATED *aint); +OPENSSL_EXPORT char * i2s_ASN1_ENUMERATED_TABLE(X509V3_EXT_METHOD *meth, ASN1_ENUMERATED *aint); +OPENSSL_EXPORT int X509V3_EXT_add(X509V3_EXT_METHOD *ext); +OPENSSL_EXPORT int X509V3_EXT_add_list(X509V3_EXT_METHOD *extlist); +OPENSSL_EXPORT int X509V3_EXT_add_alias(int nid_to, int nid_from); +OPENSSL_EXPORT void X509V3_EXT_cleanup(void); + +OPENSSL_EXPORT const X509V3_EXT_METHOD *X509V3_EXT_get(X509_EXTENSION *ext); +OPENSSL_EXPORT const X509V3_EXT_METHOD *X509V3_EXT_get_nid(int nid); +OPENSSL_EXPORT int X509V3_add_standard_extensions(void); +OPENSSL_EXPORT STACK_OF(CONF_VALUE) *X509V3_parse_list(const char *line); +OPENSSL_EXPORT void *X509V3_EXT_d2i(X509_EXTENSION *ext); +OPENSSL_EXPORT void *X509V3_get_d2i(STACK_OF(X509_EXTENSION) *x, int nid, int *crit, int *idx); +OPENSSL_EXPORT int X509V3_EXT_free(int nid, void *ext_data); + + +OPENSSL_EXPORT X509_EXTENSION *X509V3_EXT_i2d(int ext_nid, int crit, void *ext_struc); +OPENSSL_EXPORT 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); + +OPENSSL_EXPORT void X509V3_EXT_val_prn(BIO *out, STACK_OF(CONF_VALUE) *val, int indent, + int ml); +OPENSSL_EXPORT int X509V3_EXT_print(BIO *out, X509_EXTENSION *ext, unsigned long flag, int indent); +OPENSSL_EXPORT int X509V3_EXT_print_fp(FILE *out, X509_EXTENSION *ext, int flag, int indent); + +OPENSSL_EXPORT int X509V3_extensions_print(BIO *out, const char *title, STACK_OF(X509_EXTENSION) *exts, unsigned long flag, int indent); + +OPENSSL_EXPORT int X509_check_ca(X509 *x); +OPENSSL_EXPORT int X509_check_purpose(X509 *x, int id, int ca); +OPENSSL_EXPORT int X509_supported_extension(X509_EXTENSION *ex); +OPENSSL_EXPORT int X509_PURPOSE_set(int *p, int purpose); +OPENSSL_EXPORT int X509_check_issued(X509 *issuer, X509 *subject); +OPENSSL_EXPORT int X509_check_akid(X509 *issuer, AUTHORITY_KEYID *akid); +OPENSSL_EXPORT int X509_PURPOSE_get_count(void); +OPENSSL_EXPORT X509_PURPOSE * X509_PURPOSE_get0(int idx); +OPENSSL_EXPORT int X509_PURPOSE_get_by_sname(char *sname); +OPENSSL_EXPORT int X509_PURPOSE_get_by_id(int id); +OPENSSL_EXPORT int X509_PURPOSE_add(int id, int trust, int flags, + int (*ck)(const X509_PURPOSE *, const X509 *, int), + char *name, char *sname, void *arg); +OPENSSL_EXPORT char *X509_PURPOSE_get0_name(X509_PURPOSE *xp); +OPENSSL_EXPORT char *X509_PURPOSE_get0_sname(X509_PURPOSE *xp); +OPENSSL_EXPORT int X509_PURPOSE_get_trust(X509_PURPOSE *xp); +OPENSSL_EXPORT void X509_PURPOSE_cleanup(void); +OPENSSL_EXPORT int X509_PURPOSE_get_id(X509_PURPOSE *); + +OPENSSL_EXPORT STACK_OF(OPENSSL_STRING) *X509_get1_email(X509 *x); +OPENSSL_EXPORT STACK_OF(OPENSSL_STRING) *X509_REQ_get1_email(X509_REQ *x); +OPENSSL_EXPORT void X509_email_free(STACK_OF(OPENSSL_STRING) *sk); +OPENSSL_EXPORT 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 + +OPENSSL_EXPORT int X509_check_host(X509 *x, const char *chk, size_t chklen, + unsigned int flags, char **peername); +OPENSSL_EXPORT int X509_check_email(X509 *x, const char *chk, size_t chklen, + unsigned int flags); +OPENSSL_EXPORT int X509_check_ip(X509 *x, const unsigned char *chk, size_t chklen, + unsigned int flags); +OPENSSL_EXPORT int X509_check_ip_asc(X509 *x, const char *ipasc, unsigned int flags); + +OPENSSL_EXPORT ASN1_OCTET_STRING *a2i_IPADDRESS(const char *ipasc); +OPENSSL_EXPORT ASN1_OCTET_STRING *a2i_IPADDRESS_NC(const char *ipasc); +OPENSSL_EXPORT int a2i_ipadd(unsigned char *ipout, const char *ipasc); +OPENSSL_EXPORT int X509V3_NAME_from_section(X509_NAME *nm, STACK_OF(CONF_VALUE)*dn_sk, + unsigned long chtype); + +OPENSSL_EXPORT void X509_POLICY_NODE_print(BIO *out, X509_POLICY_NODE *node, int indent); +DEFINE_STACK_OF(X509_POLICY_NODE) + +/* 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 +} + +extern "C++" { + +namespace bssl { + +BORINGSSL_MAKE_DELETER(AUTHORITY_INFO_ACCESS, AUTHORITY_INFO_ACCESS_free) +BORINGSSL_MAKE_DELETER(AUTHORITY_KEYID, AUTHORITY_KEYID_free) +BORINGSSL_MAKE_DELETER(BASIC_CONSTRAINTS, BASIC_CONSTRAINTS_free) +BORINGSSL_MAKE_DELETER(DIST_POINT, DIST_POINT_free) +BORINGSSL_MAKE_DELETER(GENERAL_NAME, GENERAL_NAME_free) +BORINGSSL_MAKE_DELETER(POLICYINFO, POLICYINFO_free) + +} // namespace bssl + +} /* extern C++ */ +#endif + +#define X509V3_R_BAD_IP_ADDRESS 100 +#define X509V3_R_BAD_OBJECT 101 +#define X509V3_R_BN_DEC2BN_ERROR 102 +#define X509V3_R_BN_TO_ASN1_INTEGER_ERROR 103 +#define X509V3_R_CANNOT_FIND_FREE_FUNCTION 104 +#define X509V3_R_DIRNAME_ERROR 105 +#define X509V3_R_DISTPOINT_ALREADY_SET 106 +#define X509V3_R_DUPLICATE_ZONE_ID 107 +#define X509V3_R_ERROR_CONVERTING_ZONE 108 +#define X509V3_R_ERROR_CREATING_EXTENSION 109 +#define X509V3_R_ERROR_IN_EXTENSION 110 +#define X509V3_R_EXPECTED_A_SECTION_NAME 111 +#define X509V3_R_EXTENSION_EXISTS 112 +#define X509V3_R_EXTENSION_NAME_ERROR 113 +#define X509V3_R_EXTENSION_NOT_FOUND 114 +#define X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED 115 +#define X509V3_R_EXTENSION_VALUE_ERROR 116 +#define X509V3_R_ILLEGAL_EMPTY_EXTENSION 117 +#define X509V3_R_ILLEGAL_HEX_DIGIT 118 +#define X509V3_R_INCORRECT_POLICY_SYNTAX_TAG 119 +#define X509V3_R_INVALID_BOOLEAN_STRING 120 +#define X509V3_R_INVALID_EXTENSION_STRING 121 +#define X509V3_R_INVALID_MULTIPLE_RDNS 122 +#define X509V3_R_INVALID_NAME 123 +#define X509V3_R_INVALID_NULL_ARGUMENT 124 +#define X509V3_R_INVALID_NULL_NAME 125 +#define X509V3_R_INVALID_NULL_VALUE 126 +#define X509V3_R_INVALID_NUMBER 127 +#define X509V3_R_INVALID_NUMBERS 128 +#define X509V3_R_INVALID_OBJECT_IDENTIFIER 129 +#define X509V3_R_INVALID_OPTION 130 +#define X509V3_R_INVALID_POLICY_IDENTIFIER 131 +#define X509V3_R_INVALID_PROXY_POLICY_SETTING 132 +#define X509V3_R_INVALID_PURPOSE 133 +#define X509V3_R_INVALID_SECTION 134 +#define X509V3_R_INVALID_SYNTAX 135 +#define X509V3_R_ISSUER_DECODE_ERROR 136 +#define X509V3_R_MISSING_VALUE 137 +#define X509V3_R_NEED_ORGANIZATION_AND_NUMBERS 138 +#define X509V3_R_NO_CONFIG_DATABASE 139 +#define X509V3_R_NO_ISSUER_CERTIFICATE 140 +#define X509V3_R_NO_ISSUER_DETAILS 141 +#define X509V3_R_NO_POLICY_IDENTIFIER 142 +#define X509V3_R_NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED 143 +#define X509V3_R_NO_PUBLIC_KEY 144 +#define X509V3_R_NO_SUBJECT_DETAILS 145 +#define X509V3_R_ODD_NUMBER_OF_DIGITS 146 +#define X509V3_R_OPERATION_NOT_DEFINED 147 +#define X509V3_R_OTHERNAME_ERROR 148 +#define X509V3_R_POLICY_LANGUAGE_ALREADY_DEFINED 149 +#define X509V3_R_POLICY_PATH_LENGTH 150 +#define X509V3_R_POLICY_PATH_LENGTH_ALREADY_DEFINED 151 +#define X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY 152 +#define X509V3_R_SECTION_NOT_FOUND 153 +#define X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS 154 +#define X509V3_R_UNABLE_TO_GET_ISSUER_KEYID 155 +#define X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT 156 +#define X509V3_R_UNKNOWN_EXTENSION 157 +#define X509V3_R_UNKNOWN_EXTENSION_NAME 158 +#define X509V3_R_UNKNOWN_OPTION 159 +#define X509V3_R_UNSUPPORTED_OPTION 160 +#define X509V3_R_UNSUPPORTED_TYPE 161 +#define X509V3_R_USER_TOO_LONG 162 + +#endif diff --git a/FoodApp/Pods/BoringSSL-GRPC/include/openssl/x509v3.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/x509v3.h.grpc_back new file mode 100644 index 0000000..4a1fe7b --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/include/openssl/x509v3.h.grpc_back @@ -0,0 +1,827 @@ +/* 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 +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + + +/* Legacy X.509 library. + * + * This header is part of OpenSSL's X.509 implementation. It is retained for + * compatibility but otherwise underdocumented and not actively maintained. In + * the future, a replacement library will be available. Meanwhile, minimize + * dependencies on this header where possible. */ + + +/* 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; +const X509V3_CONF_METHOD *db_meth; +void *db; +/* Maybe more here */ +}; + +typedef struct v3_ext_method X509V3_EXT_METHOD; + +DEFINE_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; + +struct BASIC_CONSTRAINTS_st { +int ca; +ASN1_INTEGER *pathlen; +}; + + +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; + +DEFINE_STACK_OF(GENERAL_NAME) +DECLARE_ASN1_SET_OF(GENERAL_NAME) + +typedef STACK_OF(GENERAL_NAME) GENERAL_NAMES; + +DEFINE_STACK_OF(GENERAL_NAMES) + +typedef struct ACCESS_DESCRIPTION_st { + ASN1_OBJECT *method; + GENERAL_NAME *location; +} ACCESS_DESCRIPTION; + +DEFINE_STACK_OF(ACCESS_DESCRIPTION) +DECLARE_ASN1_SET_OF(ACCESS_DESCRIPTION) + +typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS; + +typedef STACK_OF(ASN1_OBJECT) EXTENDED_KEY_USAGE; + +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; + +DEFINE_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; + +DEFINE_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; + +DEFINE_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; + +DEFINE_STACK_OF(POLICYINFO) +DECLARE_ASN1_SET_OF(POLICYINFO) + +typedef struct POLICY_MAPPING_st { + ASN1_OBJECT *issuerDomainPolicy; + ASN1_OBJECT *subjectDomainPolicy; +} POLICY_MAPPING; + +DEFINE_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; + +DEFINE_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, \ + (void *)(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 + +DEFINE_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) +OPENSSL_EXPORT GENERAL_NAME *GENERAL_NAME_dup(GENERAL_NAME *a); +OPENSSL_EXPORT int GENERAL_NAME_cmp(GENERAL_NAME *a, GENERAL_NAME *b); + + + +OPENSSL_EXPORT ASN1_BIT_STRING *v2i_ASN1_BIT_STRING(X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *nval); +OPENSSL_EXPORT STACK_OF(CONF_VALUE) *i2v_ASN1_BIT_STRING(X509V3_EXT_METHOD *method, + ASN1_BIT_STRING *bits, + STACK_OF(CONF_VALUE) *extlist); + +OPENSSL_EXPORT STACK_OF(CONF_VALUE) *i2v_GENERAL_NAME(X509V3_EXT_METHOD *method, GENERAL_NAME *gen, STACK_OF(CONF_VALUE) *ret); +OPENSSL_EXPORT int GENERAL_NAME_print(BIO *out, GENERAL_NAME *gen); + +DECLARE_ASN1_FUNCTIONS(GENERAL_NAMES) + +OPENSSL_EXPORT STACK_OF(CONF_VALUE) *i2v_GENERAL_NAMES(X509V3_EXT_METHOD *method, + GENERAL_NAMES *gen, STACK_OF(CONF_VALUE) *extlist); +OPENSSL_EXPORT 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) +OPENSSL_EXPORT int OTHERNAME_cmp(OTHERNAME *a, OTHERNAME *b); +OPENSSL_EXPORT void GENERAL_NAME_set0_value(GENERAL_NAME *a, int type, void *value); +OPENSSL_EXPORT void *GENERAL_NAME_get0_value(GENERAL_NAME *a, int *ptype); +OPENSSL_EXPORT int GENERAL_NAME_set0_othername(GENERAL_NAME *gen, + ASN1_OBJECT *oid, ASN1_TYPE *value); +OPENSSL_EXPORT int GENERAL_NAME_get0_otherName(GENERAL_NAME *gen, + ASN1_OBJECT **poid, ASN1_TYPE **pvalue); + +OPENSSL_EXPORT char *i2s_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, ASN1_OCTET_STRING *ia5); +OPENSSL_EXPORT ASN1_OCTET_STRING *s2i_ASN1_OCTET_STRING(X509V3_EXT_METHOD *method, X509V3_CTX *ctx, char *str); + +DECLARE_ASN1_FUNCTIONS(EXTENDED_KEY_USAGE) +OPENSSL_EXPORT 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) + +OPENSSL_EXPORT int DIST_POINT_set_dpname(DIST_POINT_NAME *dpn, X509_NAME *iname); + +OPENSSL_EXPORT 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) + +OPENSSL_EXPORT GENERAL_NAME *a2i_GENERAL_NAME(GENERAL_NAME *out, + const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, + int gen_type, char *value, int is_nc); + +OPENSSL_EXPORT GENERAL_NAME *v2i_GENERAL_NAME(const X509V3_EXT_METHOD *method, X509V3_CTX *ctx, + CONF_VALUE *cnf); +OPENSSL_EXPORT GENERAL_NAME *v2i_GENERAL_NAME_ex(GENERAL_NAME *out, + const X509V3_EXT_METHOD *method, + X509V3_CTX *ctx, CONF_VALUE *cnf, int is_nc); +OPENSSL_EXPORT void X509V3_conf_free(CONF_VALUE *val); + +OPENSSL_EXPORT X509_EXTENSION *X509V3_EXT_conf_nid(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, int ext_nid, char *value); +OPENSSL_EXPORT X509_EXTENSION *X509V3_EXT_nconf_nid(CONF *conf, X509V3_CTX *ctx, int ext_nid, char *value); +OPENSSL_EXPORT X509_EXTENSION *X509V3_EXT_nconf(CONF *conf, X509V3_CTX *ctx, char *name, char *value); +OPENSSL_EXPORT int X509V3_EXT_add_nconf_sk(CONF *conf, X509V3_CTX *ctx, char *section, STACK_OF(X509_EXTENSION) **sk); +OPENSSL_EXPORT int X509V3_EXT_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section, X509 *cert); +OPENSSL_EXPORT int X509V3_EXT_REQ_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section, X509_REQ *req); +OPENSSL_EXPORT int X509V3_EXT_CRL_add_nconf(CONF *conf, X509V3_CTX *ctx, char *section, X509_CRL *crl); + +OPENSSL_EXPORT int X509V3_EXT_CRL_add_conf(LHASH_OF(CONF_VALUE) *conf, X509V3_CTX *ctx, + char *section, X509_CRL *crl); + +OPENSSL_EXPORT int X509V3_add_value_bool_nf(char *name, int asn1_bool, + STACK_OF(CONF_VALUE) **extlist); +OPENSSL_EXPORT int X509V3_get_value_bool(CONF_VALUE *value, int *asn1_bool); +OPENSSL_EXPORT int X509V3_get_value_int(CONF_VALUE *value, ASN1_INTEGER **aint); +OPENSSL_EXPORT void X509V3_set_nconf(X509V3_CTX *ctx, CONF *conf); + +OPENSSL_EXPORT char * X509V3_get_string(X509V3_CTX *ctx, char *name, char *section); +OPENSSL_EXPORT STACK_OF(CONF_VALUE) * X509V3_get_section(X509V3_CTX *ctx, char *section); +OPENSSL_EXPORT void X509V3_string_free(X509V3_CTX *ctx, char *str); +OPENSSL_EXPORT void X509V3_section_free( X509V3_CTX *ctx, STACK_OF(CONF_VALUE) *section); +OPENSSL_EXPORT void X509V3_set_ctx(X509V3_CTX *ctx, X509 *issuer, X509 *subject, + X509_REQ *req, X509_CRL *crl, int flags); + +OPENSSL_EXPORT int X509V3_add_value(const char *name, const char *value, + STACK_OF(CONF_VALUE) **extlist); +OPENSSL_EXPORT int X509V3_add_value_uchar(const char *name, const unsigned char *value, + STACK_OF(CONF_VALUE) **extlist); +OPENSSL_EXPORT int X509V3_add_value_bool(const char *name, int asn1_bool, + STACK_OF(CONF_VALUE) **extlist); +OPENSSL_EXPORT int X509V3_add_value_int(const char *name, ASN1_INTEGER *aint, + STACK_OF(CONF_VALUE) **extlist); +OPENSSL_EXPORT char * i2s_ASN1_INTEGER(X509V3_EXT_METHOD *meth, ASN1_INTEGER *aint); +OPENSSL_EXPORT ASN1_INTEGER * s2i_ASN1_INTEGER(X509V3_EXT_METHOD *meth, char *value); +OPENSSL_EXPORT char * i2s_ASN1_ENUMERATED(X509V3_EXT_METHOD *meth, ASN1_ENUMERATED *aint); +OPENSSL_EXPORT char * i2s_ASN1_ENUMERATED_TABLE(X509V3_EXT_METHOD *meth, ASN1_ENUMERATED *aint); +OPENSSL_EXPORT int X509V3_EXT_add(X509V3_EXT_METHOD *ext); +OPENSSL_EXPORT int X509V3_EXT_add_list(X509V3_EXT_METHOD *extlist); +OPENSSL_EXPORT int X509V3_EXT_add_alias(int nid_to, int nid_from); +OPENSSL_EXPORT void X509V3_EXT_cleanup(void); + +OPENSSL_EXPORT const X509V3_EXT_METHOD *X509V3_EXT_get(X509_EXTENSION *ext); +OPENSSL_EXPORT const X509V3_EXT_METHOD *X509V3_EXT_get_nid(int nid); +OPENSSL_EXPORT int X509V3_add_standard_extensions(void); +OPENSSL_EXPORT STACK_OF(CONF_VALUE) *X509V3_parse_list(const char *line); +OPENSSL_EXPORT void *X509V3_EXT_d2i(X509_EXTENSION *ext); +OPENSSL_EXPORT void *X509V3_get_d2i(STACK_OF(X509_EXTENSION) *x, int nid, int *crit, int *idx); +OPENSSL_EXPORT int X509V3_EXT_free(int nid, void *ext_data); + + +OPENSSL_EXPORT X509_EXTENSION *X509V3_EXT_i2d(int ext_nid, int crit, void *ext_struc); +OPENSSL_EXPORT 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); + +OPENSSL_EXPORT void X509V3_EXT_val_prn(BIO *out, STACK_OF(CONF_VALUE) *val, int indent, + int ml); +OPENSSL_EXPORT int X509V3_EXT_print(BIO *out, X509_EXTENSION *ext, unsigned long flag, int indent); +OPENSSL_EXPORT int X509V3_EXT_print_fp(FILE *out, X509_EXTENSION *ext, int flag, int indent); + +OPENSSL_EXPORT int X509V3_extensions_print(BIO *out, const char *title, STACK_OF(X509_EXTENSION) *exts, unsigned long flag, int indent); + +OPENSSL_EXPORT int X509_check_ca(X509 *x); +OPENSSL_EXPORT int X509_check_purpose(X509 *x, int id, int ca); +OPENSSL_EXPORT int X509_supported_extension(X509_EXTENSION *ex); +OPENSSL_EXPORT int X509_PURPOSE_set(int *p, int purpose); +OPENSSL_EXPORT int X509_check_issued(X509 *issuer, X509 *subject); +OPENSSL_EXPORT int X509_check_akid(X509 *issuer, AUTHORITY_KEYID *akid); +OPENSSL_EXPORT int X509_PURPOSE_get_count(void); +OPENSSL_EXPORT X509_PURPOSE * X509_PURPOSE_get0(int idx); +OPENSSL_EXPORT int X509_PURPOSE_get_by_sname(char *sname); +OPENSSL_EXPORT int X509_PURPOSE_get_by_id(int id); +OPENSSL_EXPORT int X509_PURPOSE_add(int id, int trust, int flags, + int (*ck)(const X509_PURPOSE *, const X509 *, int), + char *name, char *sname, void *arg); +OPENSSL_EXPORT char *X509_PURPOSE_get0_name(X509_PURPOSE *xp); +OPENSSL_EXPORT char *X509_PURPOSE_get0_sname(X509_PURPOSE *xp); +OPENSSL_EXPORT int X509_PURPOSE_get_trust(X509_PURPOSE *xp); +OPENSSL_EXPORT void X509_PURPOSE_cleanup(void); +OPENSSL_EXPORT int X509_PURPOSE_get_id(X509_PURPOSE *); + +OPENSSL_EXPORT STACK_OF(OPENSSL_STRING) *X509_get1_email(X509 *x); +OPENSSL_EXPORT STACK_OF(OPENSSL_STRING) *X509_REQ_get1_email(X509_REQ *x); +OPENSSL_EXPORT void X509_email_free(STACK_OF(OPENSSL_STRING) *sk); +OPENSSL_EXPORT 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 + +OPENSSL_EXPORT int X509_check_host(X509 *x, const char *chk, size_t chklen, + unsigned int flags, char **peername); +OPENSSL_EXPORT int X509_check_email(X509 *x, const char *chk, size_t chklen, + unsigned int flags); +OPENSSL_EXPORT int X509_check_ip(X509 *x, const unsigned char *chk, size_t chklen, + unsigned int flags); +OPENSSL_EXPORT int X509_check_ip_asc(X509 *x, const char *ipasc, unsigned int flags); + +OPENSSL_EXPORT ASN1_OCTET_STRING *a2i_IPADDRESS(const char *ipasc); +OPENSSL_EXPORT ASN1_OCTET_STRING *a2i_IPADDRESS_NC(const char *ipasc); +OPENSSL_EXPORT int a2i_ipadd(unsigned char *ipout, const char *ipasc); +OPENSSL_EXPORT int X509V3_NAME_from_section(X509_NAME *nm, STACK_OF(CONF_VALUE)*dn_sk, + unsigned long chtype); + +OPENSSL_EXPORT void X509_POLICY_NODE_print(BIO *out, X509_POLICY_NODE *node, int indent); +DEFINE_STACK_OF(X509_POLICY_NODE) + +/* 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 +} + +extern "C++" { + +namespace bssl { + +BORINGSSL_MAKE_DELETER(AUTHORITY_INFO_ACCESS, AUTHORITY_INFO_ACCESS_free) +BORINGSSL_MAKE_DELETER(AUTHORITY_KEYID, AUTHORITY_KEYID_free) +BORINGSSL_MAKE_DELETER(BASIC_CONSTRAINTS, BASIC_CONSTRAINTS_free) +BORINGSSL_MAKE_DELETER(DIST_POINT, DIST_POINT_free) +BORINGSSL_MAKE_DELETER(GENERAL_NAME, GENERAL_NAME_free) +BORINGSSL_MAKE_DELETER(POLICYINFO, POLICYINFO_free) + +} // namespace bssl + +} /* extern C++ */ +#endif + +#define X509V3_R_BAD_IP_ADDRESS 100 +#define X509V3_R_BAD_OBJECT 101 +#define X509V3_R_BN_DEC2BN_ERROR 102 +#define X509V3_R_BN_TO_ASN1_INTEGER_ERROR 103 +#define X509V3_R_CANNOT_FIND_FREE_FUNCTION 104 +#define X509V3_R_DIRNAME_ERROR 105 +#define X509V3_R_DISTPOINT_ALREADY_SET 106 +#define X509V3_R_DUPLICATE_ZONE_ID 107 +#define X509V3_R_ERROR_CONVERTING_ZONE 108 +#define X509V3_R_ERROR_CREATING_EXTENSION 109 +#define X509V3_R_ERROR_IN_EXTENSION 110 +#define X509V3_R_EXPECTED_A_SECTION_NAME 111 +#define X509V3_R_EXTENSION_EXISTS 112 +#define X509V3_R_EXTENSION_NAME_ERROR 113 +#define X509V3_R_EXTENSION_NOT_FOUND 114 +#define X509V3_R_EXTENSION_SETTING_NOT_SUPPORTED 115 +#define X509V3_R_EXTENSION_VALUE_ERROR 116 +#define X509V3_R_ILLEGAL_EMPTY_EXTENSION 117 +#define X509V3_R_ILLEGAL_HEX_DIGIT 118 +#define X509V3_R_INCORRECT_POLICY_SYNTAX_TAG 119 +#define X509V3_R_INVALID_BOOLEAN_STRING 120 +#define X509V3_R_INVALID_EXTENSION_STRING 121 +#define X509V3_R_INVALID_MULTIPLE_RDNS 122 +#define X509V3_R_INVALID_NAME 123 +#define X509V3_R_INVALID_NULL_ARGUMENT 124 +#define X509V3_R_INVALID_NULL_NAME 125 +#define X509V3_R_INVALID_NULL_VALUE 126 +#define X509V3_R_INVALID_NUMBER 127 +#define X509V3_R_INVALID_NUMBERS 128 +#define X509V3_R_INVALID_OBJECT_IDENTIFIER 129 +#define X509V3_R_INVALID_OPTION 130 +#define X509V3_R_INVALID_POLICY_IDENTIFIER 131 +#define X509V3_R_INVALID_PROXY_POLICY_SETTING 132 +#define X509V3_R_INVALID_PURPOSE 133 +#define X509V3_R_INVALID_SECTION 134 +#define X509V3_R_INVALID_SYNTAX 135 +#define X509V3_R_ISSUER_DECODE_ERROR 136 +#define X509V3_R_MISSING_VALUE 137 +#define X509V3_R_NEED_ORGANIZATION_AND_NUMBERS 138 +#define X509V3_R_NO_CONFIG_DATABASE 139 +#define X509V3_R_NO_ISSUER_CERTIFICATE 140 +#define X509V3_R_NO_ISSUER_DETAILS 141 +#define X509V3_R_NO_POLICY_IDENTIFIER 142 +#define X509V3_R_NO_PROXY_CERT_POLICY_LANGUAGE_DEFINED 143 +#define X509V3_R_NO_PUBLIC_KEY 144 +#define X509V3_R_NO_SUBJECT_DETAILS 145 +#define X509V3_R_ODD_NUMBER_OF_DIGITS 146 +#define X509V3_R_OPERATION_NOT_DEFINED 147 +#define X509V3_R_OTHERNAME_ERROR 148 +#define X509V3_R_POLICY_LANGUAGE_ALREADY_DEFINED 149 +#define X509V3_R_POLICY_PATH_LENGTH 150 +#define X509V3_R_POLICY_PATH_LENGTH_ALREADY_DEFINED 151 +#define X509V3_R_POLICY_WHEN_PROXY_LANGUAGE_REQUIRES_NO_POLICY 152 +#define X509V3_R_SECTION_NOT_FOUND 153 +#define X509V3_R_UNABLE_TO_GET_ISSUER_DETAILS 154 +#define X509V3_R_UNABLE_TO_GET_ISSUER_KEYID 155 +#define X509V3_R_UNKNOWN_BIT_STRING_ARGUMENT 156 +#define X509V3_R_UNKNOWN_EXTENSION 157 +#define X509V3_R_UNKNOWN_EXTENSION_NAME 158 +#define X509V3_R_UNKNOWN_OPTION 159 +#define X509V3_R_UNSUPPORTED_OPTION 160 +#define X509V3_R_UNSUPPORTED_TYPE 161 +#define X509V3_R_USER_TOO_LONG 162 + +#endif diff --git a/FoodApp/Pods/BoringSSL-GRPC/ssl/bio_ssl.cc b/FoodApp/Pods/BoringSSL-GRPC/ssl/bio_ssl.cc new file mode 100644 index 0000000..4cb6146 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/ssl/bio_ssl.cc @@ -0,0 +1,179 @@ +/* + * Copyright 1995-2016 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 + */ + +#include + +#include + + +static SSL *get_ssl(BIO *bio) { + return reinterpret_cast(bio->ptr); +} + +static int ssl_read(BIO *bio, char *out, int outl) { + SSL *ssl = get_ssl(bio); + if (ssl == NULL) { + return 0; + } + + BIO_clear_retry_flags(bio); + + const int ret = SSL_read(ssl, out, outl); + + switch (SSL_get_error(ssl, ret)) { + case SSL_ERROR_WANT_READ: + BIO_set_retry_read(bio); + break; + + case SSL_ERROR_WANT_WRITE: + BIO_set_retry_write(bio); + break; + + case SSL_ERROR_WANT_ACCEPT: + BIO_set_retry_special(bio); + bio->retry_reason = BIO_RR_ACCEPT; + break; + + case SSL_ERROR_WANT_CONNECT: + BIO_set_retry_special(bio); + bio->retry_reason = BIO_RR_CONNECT; + break; + + case SSL_ERROR_NONE: + case SSL_ERROR_SYSCALL: + case SSL_ERROR_SSL: + case SSL_ERROR_ZERO_RETURN: + default: + break; + } + + return ret; +} + +static int ssl_write(BIO *bio, const char *out, int outl) { + SSL *ssl = get_ssl(bio); + if (ssl == NULL) { + return 0; + } + + BIO_clear_retry_flags(bio); + + const int ret = SSL_write(ssl, out, outl); + + switch (SSL_get_error(ssl, ret)) { + case SSL_ERROR_WANT_WRITE: + BIO_set_retry_write(bio); + break; + + case SSL_ERROR_WANT_READ: + BIO_set_retry_read(bio); + break; + + case SSL_ERROR_WANT_CONNECT: + BIO_set_retry_special(bio); + bio->retry_reason = BIO_RR_CONNECT; + break; + + case SSL_ERROR_NONE: + case SSL_ERROR_SYSCALL: + case SSL_ERROR_SSL: + default: + break; + } + + return ret; +} + +static long ssl_ctrl(BIO *bio, int cmd, long num, void *ptr) { + SSL *ssl = get_ssl(bio); + if (ssl == NULL && cmd != BIO_C_SET_SSL) { + return 0; + } + + switch (cmd) { + case BIO_C_SET_SSL: + bio->shutdown = num; + bio->ptr = ptr; + bio->init = 1; + return 1; + + case BIO_CTRL_GET_CLOSE: + return bio->shutdown; + + case BIO_CTRL_SET_CLOSE: + bio->shutdown = num; + return 1; + + case BIO_CTRL_WPENDING: + return BIO_ctrl(SSL_get_wbio(ssl), cmd, num, ptr); + + case BIO_CTRL_PENDING: + return SSL_pending(ssl); + + case BIO_CTRL_FLUSH: { + BIO_clear_retry_flags(bio); + long ret = BIO_ctrl(SSL_get_wbio(ssl), cmd, num, ptr); + BIO_copy_next_retry(bio); + return ret; + } + + case BIO_CTRL_PUSH: + case BIO_CTRL_POP: + case BIO_CTRL_DUP: + return -1; + + default: + return BIO_ctrl(SSL_get_rbio(ssl), cmd, num, ptr); + } +} + +static int ssl_new(BIO *bio) { + return 1; +} + +static int ssl_free(BIO *bio) { + SSL *ssl = get_ssl(bio); + + if (ssl == NULL) { + return 1; + } + + SSL_shutdown(ssl); + if (bio->shutdown) { + SSL_free(ssl); + } + + return 1; +} + +static long ssl_callback_ctrl(BIO *bio, int cmd, bio_info_cb fp) { + SSL *ssl = get_ssl(bio); + if (ssl == NULL) { + return 0; + } + + switch (cmd) { + case BIO_CTRL_SET_CALLBACK: + return -1; + + default: + return BIO_callback_ctrl(SSL_get_rbio(ssl), cmd, fp); + } +} + +static const BIO_METHOD ssl_method = { + BIO_TYPE_SSL, "SSL", ssl_write, ssl_read, NULL, + NULL, ssl_ctrl, ssl_new, ssl_free, ssl_callback_ctrl, +}; + +const BIO_METHOD *BIO_f_ssl(void) { return &ssl_method; } + +long BIO_set_ssl(BIO *bio, SSL *ssl, int take_owership) { + return BIO_ctrl(bio, BIO_C_SET_SSL, take_owership, ssl); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/ssl/bio_ssl.cc.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/ssl/bio_ssl.cc.grpc_back new file mode 100644 index 0000000..61afee5 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/ssl/bio_ssl.cc.grpc_back @@ -0,0 +1,179 @@ +/* + * Copyright 1995-2016 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 + */ + +#include + +#include + + +static SSL *get_ssl(BIO *bio) { + return reinterpret_cast(bio->ptr); +} + +static int ssl_read(BIO *bio, char *out, int outl) { + SSL *ssl = get_ssl(bio); + if (ssl == NULL) { + return 0; + } + + BIO_clear_retry_flags(bio); + + const int ret = SSL_read(ssl, out, outl); + + switch (SSL_get_error(ssl, ret)) { + case SSL_ERROR_WANT_READ: + BIO_set_retry_read(bio); + break; + + case SSL_ERROR_WANT_WRITE: + BIO_set_retry_write(bio); + break; + + case SSL_ERROR_WANT_ACCEPT: + BIO_set_retry_special(bio); + bio->retry_reason = BIO_RR_ACCEPT; + break; + + case SSL_ERROR_WANT_CONNECT: + BIO_set_retry_special(bio); + bio->retry_reason = BIO_RR_CONNECT; + break; + + case SSL_ERROR_NONE: + case SSL_ERROR_SYSCALL: + case SSL_ERROR_SSL: + case SSL_ERROR_ZERO_RETURN: + default: + break; + } + + return ret; +} + +static int ssl_write(BIO *bio, const char *out, int outl) { + SSL *ssl = get_ssl(bio); + if (ssl == NULL) { + return 0; + } + + BIO_clear_retry_flags(bio); + + const int ret = SSL_write(ssl, out, outl); + + switch (SSL_get_error(ssl, ret)) { + case SSL_ERROR_WANT_WRITE: + BIO_set_retry_write(bio); + break; + + case SSL_ERROR_WANT_READ: + BIO_set_retry_read(bio); + break; + + case SSL_ERROR_WANT_CONNECT: + BIO_set_retry_special(bio); + bio->retry_reason = BIO_RR_CONNECT; + break; + + case SSL_ERROR_NONE: + case SSL_ERROR_SYSCALL: + case SSL_ERROR_SSL: + default: + break; + } + + return ret; +} + +static long ssl_ctrl(BIO *bio, int cmd, long num, void *ptr) { + SSL *ssl = get_ssl(bio); + if (ssl == NULL && cmd != BIO_C_SET_SSL) { + return 0; + } + + switch (cmd) { + case BIO_C_SET_SSL: + bio->shutdown = num; + bio->ptr = ptr; + bio->init = 1; + return 1; + + case BIO_CTRL_GET_CLOSE: + return bio->shutdown; + + case BIO_CTRL_SET_CLOSE: + bio->shutdown = num; + return 1; + + case BIO_CTRL_WPENDING: + return BIO_ctrl(SSL_get_wbio(ssl), cmd, num, ptr); + + case BIO_CTRL_PENDING: + return SSL_pending(ssl); + + case BIO_CTRL_FLUSH: { + BIO_clear_retry_flags(bio); + long ret = BIO_ctrl(SSL_get_wbio(ssl), cmd, num, ptr); + BIO_copy_next_retry(bio); + return ret; + } + + case BIO_CTRL_PUSH: + case BIO_CTRL_POP: + case BIO_CTRL_DUP: + return -1; + + default: + return BIO_ctrl(SSL_get_rbio(ssl), cmd, num, ptr); + } +} + +static int ssl_new(BIO *bio) { + return 1; +} + +static int ssl_free(BIO *bio) { + SSL *ssl = get_ssl(bio); + + if (ssl == NULL) { + return 1; + } + + SSL_shutdown(ssl); + if (bio->shutdown) { + SSL_free(ssl); + } + + return 1; +} + +static long ssl_callback_ctrl(BIO *bio, int cmd, bio_info_cb fp) { + SSL *ssl = get_ssl(bio); + if (ssl == NULL) { + return 0; + } + + switch (cmd) { + case BIO_CTRL_SET_CALLBACK: + return -1; + + default: + return BIO_callback_ctrl(SSL_get_rbio(ssl), cmd, fp); + } +} + +static const BIO_METHOD ssl_method = { + BIO_TYPE_SSL, "SSL", ssl_write, ssl_read, NULL, + NULL, ssl_ctrl, ssl_new, ssl_free, ssl_callback_ctrl, +}; + +const BIO_METHOD *BIO_f_ssl(void) { return &ssl_method; } + +long BIO_set_ssl(BIO *bio, SSL *ssl, int take_owership) { + return BIO_ctrl(bio, BIO_C_SET_SSL, take_owership, ssl); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/ssl/custom_extensions.cc b/FoodApp/Pods/BoringSSL-GRPC/ssl/custom_extensions.cc new file mode 100644 index 0000000..4e501ce --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/ssl/custom_extensions.cc @@ -0,0 +1,265 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include +#include + +#include +#include +#include +#include + +#include "internal.h" + + +namespace bssl { + +void SSL_CUSTOM_EXTENSION_free(SSL_CUSTOM_EXTENSION *custom_extension) { + OPENSSL_free(custom_extension); +} + +static const SSL_CUSTOM_EXTENSION *custom_ext_find( + STACK_OF(SSL_CUSTOM_EXTENSION) *stack, + unsigned *out_index, uint16_t value) { + for (size_t i = 0; i < sk_SSL_CUSTOM_EXTENSION_num(stack); i++) { + const SSL_CUSTOM_EXTENSION *ext = sk_SSL_CUSTOM_EXTENSION_value(stack, i); + if (ext->value == value) { + if (out_index != NULL) { + *out_index = i; + } + return ext; + } + } + + return NULL; +} + +// default_add_callback is used as the |add_callback| when the user doesn't +// provide one. For servers, it does nothing while, for clients, it causes an +// empty extension to be included. +static int default_add_callback(SSL *ssl, unsigned extension_value, + const uint8_t **out, size_t *out_len, + int *out_alert_value, void *add_arg) { + if (ssl->server) { + return 0; + } + *out_len = 0; + return 1; +} + +static int custom_ext_add_hello(SSL_HANDSHAKE *hs, CBB *extensions) { + SSL *const ssl = hs->ssl; + STACK_OF(SSL_CUSTOM_EXTENSION) *stack = ssl->ctx->client_custom_extensions; + if (ssl->server) { + stack = ssl->ctx->server_custom_extensions; + } + + if (stack == NULL) { + return 1; + } + + for (size_t i = 0; i < sk_SSL_CUSTOM_EXTENSION_num(stack); i++) { + const SSL_CUSTOM_EXTENSION *ext = sk_SSL_CUSTOM_EXTENSION_value(stack, i); + + if (ssl->server && + !(hs->custom_extensions.received & (1u << i))) { + // Servers cannot echo extensions that the client didn't send. + continue; + } + + const uint8_t *contents; + size_t contents_len; + int alert = SSL_AD_DECODE_ERROR; + CBB contents_cbb; + + switch (ext->add_callback(ssl, ext->value, &contents, &contents_len, &alert, + ext->add_arg)) { + case 1: + if (!CBB_add_u16(extensions, ext->value) || + !CBB_add_u16_length_prefixed(extensions, &contents_cbb) || + !CBB_add_bytes(&contents_cbb, contents, contents_len) || + !CBB_flush(extensions)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + ERR_add_error_dataf("extension %u", (unsigned) ext->value); + if (ext->free_callback && 0 < contents_len) { + ext->free_callback(ssl, ext->value, contents, ext->add_arg); + } + return 0; + } + + if (ext->free_callback && 0 < contents_len) { + ext->free_callback(ssl, ext->value, contents, ext->add_arg); + } + + if (!ssl->server) { + assert((hs->custom_extensions.sent & (1u << i)) == 0); + hs->custom_extensions.sent |= (1u << i); + } + break; + + case 0: + break; + + default: + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + OPENSSL_PUT_ERROR(SSL, SSL_R_CUSTOM_EXTENSION_ERROR); + ERR_add_error_dataf("extension %u", (unsigned) ext->value); + return 0; + } + } + + return 1; +} + +int custom_ext_add_clienthello(SSL_HANDSHAKE *hs, CBB *extensions) { + return custom_ext_add_hello(hs, extensions); +} + +int custom_ext_parse_serverhello(SSL_HANDSHAKE *hs, int *out_alert, + uint16_t value, const CBS *extension) { + SSL *const ssl = hs->ssl; + unsigned index; + const SSL_CUSTOM_EXTENSION *ext = + custom_ext_find(ssl->ctx->client_custom_extensions, &index, value); + + if (// Unknown extensions are not allowed in a ServerHello. + ext == NULL || + // Also, if we didn't send the extension, that's also unacceptable. + !(hs->custom_extensions.sent & (1u << index))) { + OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION); + ERR_add_error_dataf("extension %u", (unsigned)value); + *out_alert = SSL_AD_UNSUPPORTED_EXTENSION; + return 0; + } + + if (ext->parse_callback != NULL && + !ext->parse_callback(ssl, value, CBS_data(extension), CBS_len(extension), + out_alert, ext->parse_arg)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_CUSTOM_EXTENSION_ERROR); + ERR_add_error_dataf("extension %u", (unsigned)ext->value); + return 0; + } + + return 1; +} + +int custom_ext_parse_clienthello(SSL_HANDSHAKE *hs, int *out_alert, + uint16_t value, const CBS *extension) { + SSL *const ssl = hs->ssl; + unsigned index; + const SSL_CUSTOM_EXTENSION *ext = + custom_ext_find(ssl->ctx->server_custom_extensions, &index, value); + + if (ext == NULL) { + return 1; + } + + assert((hs->custom_extensions.received & (1u << index)) == 0); + hs->custom_extensions.received |= (1u << index); + + if (ext->parse_callback && + !ext->parse_callback(ssl, value, CBS_data(extension), CBS_len(extension), + out_alert, ext->parse_arg)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_CUSTOM_EXTENSION_ERROR); + ERR_add_error_dataf("extension %u", (unsigned)ext->value); + return 0; + } + + return 1; +} + +int custom_ext_add_serverhello(SSL_HANDSHAKE *hs, CBB *extensions) { + return custom_ext_add_hello(hs, extensions); +} + +// MAX_NUM_CUSTOM_EXTENSIONS is the maximum number of custom extensions that +// can be set on an |SSL_CTX|. It's determined by the size of the bitset used +// to track when an extension has been sent. +#define MAX_NUM_CUSTOM_EXTENSIONS \ + (sizeof(((SSL_HANDSHAKE *)NULL)->custom_extensions.sent) * 8) + +static int custom_ext_append(STACK_OF(SSL_CUSTOM_EXTENSION) **stack, + unsigned extension_value, + SSL_custom_ext_add_cb add_cb, + SSL_custom_ext_free_cb free_cb, void *add_arg, + SSL_custom_ext_parse_cb parse_cb, + void *parse_arg) { + if (add_cb == NULL || + 0xffff < extension_value || + SSL_extension_supported(extension_value) || + // Specifying a free callback without an add callback is nonsensical + // and an error. + (*stack != NULL && + (MAX_NUM_CUSTOM_EXTENSIONS <= sk_SSL_CUSTOM_EXTENSION_num(*stack) || + custom_ext_find(*stack, NULL, extension_value) != NULL))) { + return 0; + } + + SSL_CUSTOM_EXTENSION *ext = + (SSL_CUSTOM_EXTENSION *)OPENSSL_malloc(sizeof(SSL_CUSTOM_EXTENSION)); + if (ext == NULL) { + return 0; + } + ext->add_callback = add_cb; + ext->add_arg = add_arg; + ext->free_callback = free_cb; + ext->parse_callback = parse_cb; + ext->parse_arg = parse_arg; + ext->value = extension_value; + + if (*stack == NULL) { + *stack = sk_SSL_CUSTOM_EXTENSION_new_null(); + if (*stack == NULL) { + SSL_CUSTOM_EXTENSION_free(ext); + return 0; + } + } + + if (!sk_SSL_CUSTOM_EXTENSION_push(*stack, ext)) { + SSL_CUSTOM_EXTENSION_free(ext); + if (sk_SSL_CUSTOM_EXTENSION_num(*stack) == 0) { + sk_SSL_CUSTOM_EXTENSION_free(*stack); + *stack = NULL; + } + return 0; + } + + return 1; +} + +} // namespace bssl + +using namespace bssl; + +int SSL_CTX_add_client_custom_ext(SSL_CTX *ctx, unsigned extension_value, + SSL_custom_ext_add_cb add_cb, + SSL_custom_ext_free_cb free_cb, void *add_arg, + SSL_custom_ext_parse_cb parse_cb, + void *parse_arg) { + return custom_ext_append(&ctx->client_custom_extensions, extension_value, + add_cb ? add_cb : default_add_callback, free_cb, + add_arg, parse_cb, parse_arg); +} + +int SSL_CTX_add_server_custom_ext(SSL_CTX *ctx, unsigned extension_value, + SSL_custom_ext_add_cb add_cb, + SSL_custom_ext_free_cb free_cb, void *add_arg, + SSL_custom_ext_parse_cb parse_cb, + void *parse_arg) { + return custom_ext_append(&ctx->server_custom_extensions, extension_value, + add_cb ? add_cb : default_add_callback, free_cb, + add_arg, parse_cb, parse_arg); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/ssl/custom_extensions.cc.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/ssl/custom_extensions.cc.grpc_back new file mode 100644 index 0000000..85b8a33 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/ssl/custom_extensions.cc.grpc_back @@ -0,0 +1,265 @@ +/* Copyright (c) 2014, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include +#include + +#include +#include +#include +#include + +#include "internal.h" + + +namespace bssl { + +void SSL_CUSTOM_EXTENSION_free(SSL_CUSTOM_EXTENSION *custom_extension) { + OPENSSL_free(custom_extension); +} + +static const SSL_CUSTOM_EXTENSION *custom_ext_find( + STACK_OF(SSL_CUSTOM_EXTENSION) *stack, + unsigned *out_index, uint16_t value) { + for (size_t i = 0; i < sk_SSL_CUSTOM_EXTENSION_num(stack); i++) { + const SSL_CUSTOM_EXTENSION *ext = sk_SSL_CUSTOM_EXTENSION_value(stack, i); + if (ext->value == value) { + if (out_index != NULL) { + *out_index = i; + } + return ext; + } + } + + return NULL; +} + +// default_add_callback is used as the |add_callback| when the user doesn't +// provide one. For servers, it does nothing while, for clients, it causes an +// empty extension to be included. +static int default_add_callback(SSL *ssl, unsigned extension_value, + const uint8_t **out, size_t *out_len, + int *out_alert_value, void *add_arg) { + if (ssl->server) { + return 0; + } + *out_len = 0; + return 1; +} + +static int custom_ext_add_hello(SSL_HANDSHAKE *hs, CBB *extensions) { + SSL *const ssl = hs->ssl; + STACK_OF(SSL_CUSTOM_EXTENSION) *stack = ssl->ctx->client_custom_extensions; + if (ssl->server) { + stack = ssl->ctx->server_custom_extensions; + } + + if (stack == NULL) { + return 1; + } + + for (size_t i = 0; i < sk_SSL_CUSTOM_EXTENSION_num(stack); i++) { + const SSL_CUSTOM_EXTENSION *ext = sk_SSL_CUSTOM_EXTENSION_value(stack, i); + + if (ssl->server && + !(hs->custom_extensions.received & (1u << i))) { + // Servers cannot echo extensions that the client didn't send. + continue; + } + + const uint8_t *contents; + size_t contents_len; + int alert = SSL_AD_DECODE_ERROR; + CBB contents_cbb; + + switch (ext->add_callback(ssl, ext->value, &contents, &contents_len, &alert, + ext->add_arg)) { + case 1: + if (!CBB_add_u16(extensions, ext->value) || + !CBB_add_u16_length_prefixed(extensions, &contents_cbb) || + !CBB_add_bytes(&contents_cbb, contents, contents_len) || + !CBB_flush(extensions)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + ERR_add_error_dataf("extension %u", (unsigned) ext->value); + if (ext->free_callback && 0 < contents_len) { + ext->free_callback(ssl, ext->value, contents, ext->add_arg); + } + return 0; + } + + if (ext->free_callback && 0 < contents_len) { + ext->free_callback(ssl, ext->value, contents, ext->add_arg); + } + + if (!ssl->server) { + assert((hs->custom_extensions.sent & (1u << i)) == 0); + hs->custom_extensions.sent |= (1u << i); + } + break; + + case 0: + break; + + default: + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + OPENSSL_PUT_ERROR(SSL, SSL_R_CUSTOM_EXTENSION_ERROR); + ERR_add_error_dataf("extension %u", (unsigned) ext->value); + return 0; + } + } + + return 1; +} + +int custom_ext_add_clienthello(SSL_HANDSHAKE *hs, CBB *extensions) { + return custom_ext_add_hello(hs, extensions); +} + +int custom_ext_parse_serverhello(SSL_HANDSHAKE *hs, int *out_alert, + uint16_t value, const CBS *extension) { + SSL *const ssl = hs->ssl; + unsigned index; + const SSL_CUSTOM_EXTENSION *ext = + custom_ext_find(ssl->ctx->client_custom_extensions, &index, value); + + if (// Unknown extensions are not allowed in a ServerHello. + ext == NULL || + // Also, if we didn't send the extension, that's also unacceptable. + !(hs->custom_extensions.sent & (1u << index))) { + OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION); + ERR_add_error_dataf("extension %u", (unsigned)value); + *out_alert = SSL_AD_UNSUPPORTED_EXTENSION; + return 0; + } + + if (ext->parse_callback != NULL && + !ext->parse_callback(ssl, value, CBS_data(extension), CBS_len(extension), + out_alert, ext->parse_arg)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_CUSTOM_EXTENSION_ERROR); + ERR_add_error_dataf("extension %u", (unsigned)ext->value); + return 0; + } + + return 1; +} + +int custom_ext_parse_clienthello(SSL_HANDSHAKE *hs, int *out_alert, + uint16_t value, const CBS *extension) { + SSL *const ssl = hs->ssl; + unsigned index; + const SSL_CUSTOM_EXTENSION *ext = + custom_ext_find(ssl->ctx->server_custom_extensions, &index, value); + + if (ext == NULL) { + return 1; + } + + assert((hs->custom_extensions.received & (1u << index)) == 0); + hs->custom_extensions.received |= (1u << index); + + if (ext->parse_callback && + !ext->parse_callback(ssl, value, CBS_data(extension), CBS_len(extension), + out_alert, ext->parse_arg)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_CUSTOM_EXTENSION_ERROR); + ERR_add_error_dataf("extension %u", (unsigned)ext->value); + return 0; + } + + return 1; +} + +int custom_ext_add_serverhello(SSL_HANDSHAKE *hs, CBB *extensions) { + return custom_ext_add_hello(hs, extensions); +} + +// MAX_NUM_CUSTOM_EXTENSIONS is the maximum number of custom extensions that +// can be set on an |SSL_CTX|. It's determined by the size of the bitset used +// to track when an extension has been sent. +#define MAX_NUM_CUSTOM_EXTENSIONS \ + (sizeof(((SSL_HANDSHAKE *)NULL)->custom_extensions.sent) * 8) + +static int custom_ext_append(STACK_OF(SSL_CUSTOM_EXTENSION) **stack, + unsigned extension_value, + SSL_custom_ext_add_cb add_cb, + SSL_custom_ext_free_cb free_cb, void *add_arg, + SSL_custom_ext_parse_cb parse_cb, + void *parse_arg) { + if (add_cb == NULL || + 0xffff < extension_value || + SSL_extension_supported(extension_value) || + // Specifying a free callback without an add callback is nonsensical + // and an error. + (*stack != NULL && + (MAX_NUM_CUSTOM_EXTENSIONS <= sk_SSL_CUSTOM_EXTENSION_num(*stack) || + custom_ext_find(*stack, NULL, extension_value) != NULL))) { + return 0; + } + + SSL_CUSTOM_EXTENSION *ext = + (SSL_CUSTOM_EXTENSION *)OPENSSL_malloc(sizeof(SSL_CUSTOM_EXTENSION)); + if (ext == NULL) { + return 0; + } + ext->add_callback = add_cb; + ext->add_arg = add_arg; + ext->free_callback = free_cb; + ext->parse_callback = parse_cb; + ext->parse_arg = parse_arg; + ext->value = extension_value; + + if (*stack == NULL) { + *stack = sk_SSL_CUSTOM_EXTENSION_new_null(); + if (*stack == NULL) { + SSL_CUSTOM_EXTENSION_free(ext); + return 0; + } + } + + if (!sk_SSL_CUSTOM_EXTENSION_push(*stack, ext)) { + SSL_CUSTOM_EXTENSION_free(ext); + if (sk_SSL_CUSTOM_EXTENSION_num(*stack) == 0) { + sk_SSL_CUSTOM_EXTENSION_free(*stack); + *stack = NULL; + } + return 0; + } + + return 1; +} + +} // namespace bssl + +using namespace bssl; + +int SSL_CTX_add_client_custom_ext(SSL_CTX *ctx, unsigned extension_value, + SSL_custom_ext_add_cb add_cb, + SSL_custom_ext_free_cb free_cb, void *add_arg, + SSL_custom_ext_parse_cb parse_cb, + void *parse_arg) { + return custom_ext_append(&ctx->client_custom_extensions, extension_value, + add_cb ? add_cb : default_add_callback, free_cb, + add_arg, parse_cb, parse_arg); +} + +int SSL_CTX_add_server_custom_ext(SSL_CTX *ctx, unsigned extension_value, + SSL_custom_ext_add_cb add_cb, + SSL_custom_ext_free_cb free_cb, void *add_arg, + SSL_custom_ext_parse_cb parse_cb, + void *parse_arg) { + return custom_ext_append(&ctx->server_custom_extensions, extension_value, + add_cb ? add_cb : default_add_callback, free_cb, + add_arg, parse_cb, parse_arg); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/ssl/d1_both.cc b/FoodApp/Pods/BoringSSL-GRPC/ssl/d1_both.cc new file mode 100644 index 0000000..91f9b23 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/ssl/d1_both.cc @@ -0,0 +1,851 @@ +/* + * DTLS implementation written by Nagendra Modadugu + * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. + */ +/* ==================================================================== + * 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 (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 +#include +#include +#include +#include + +#include "../crypto/internal.h" +#include "internal.h" + + +namespace bssl { + +// TODO(davidben): 28 comes from the size of IP + UDP header. Is this reasonable +// for these values? Notably, why is kMinMTU a function of the transport +// protocol's overhead rather than, say, what's needed to hold a minimally-sized +// handshake fragment plus protocol overhead. + +// kMinMTU is the minimum acceptable MTU value. +static const unsigned int kMinMTU = 256 - 28; + +// kDefaultMTU is the default MTU value to use if neither the user nor +// the underlying BIO supplies one. +static const unsigned int kDefaultMTU = 1500 - 28; + + +// Receiving handshake messages. + +hm_fragment::~hm_fragment() { + OPENSSL_free(data); + OPENSSL_free(reassembly); +} + +static UniquePtr dtls1_hm_fragment_new( + const struct hm_header_st *msg_hdr) { + ScopedCBB cbb; + UniquePtr frag = MakeUnique(); + if (!frag) { + return nullptr; + } + frag->type = msg_hdr->type; + frag->seq = msg_hdr->seq; + frag->msg_len = msg_hdr->msg_len; + + // Allocate space for the reassembled message and fill in the header. + frag->data = + (uint8_t *)OPENSSL_malloc(DTLS1_HM_HEADER_LENGTH + msg_hdr->msg_len); + if (frag->data == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return nullptr; + } + + if (!CBB_init_fixed(cbb.get(), frag->data, DTLS1_HM_HEADER_LENGTH) || + !CBB_add_u8(cbb.get(), msg_hdr->type) || + !CBB_add_u24(cbb.get(), msg_hdr->msg_len) || + !CBB_add_u16(cbb.get(), msg_hdr->seq) || + !CBB_add_u24(cbb.get(), 0 /* frag_off */) || + !CBB_add_u24(cbb.get(), msg_hdr->msg_len) || + !CBB_finish(cbb.get(), NULL, NULL)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return nullptr; + } + + // If the handshake message is empty, |frag->reassembly| is NULL. + if (msg_hdr->msg_len > 0) { + // Initialize reassembly bitmask. + if (msg_hdr->msg_len + 7 < msg_hdr->msg_len) { + OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW); + return nullptr; + } + size_t bitmask_len = (msg_hdr->msg_len + 7) / 8; + frag->reassembly = (uint8_t *)OPENSSL_malloc(bitmask_len); + if (frag->reassembly == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return nullptr; + } + OPENSSL_memset(frag->reassembly, 0, bitmask_len); + } + + return frag; +} + +// bit_range returns a |uint8_t| with bits |start|, inclusive, to |end|, +// exclusive, set. +static uint8_t bit_range(size_t start, size_t end) { + return (uint8_t)(~((1u << start) - 1) & ((1u << end) - 1)); +} + +// dtls1_hm_fragment_mark marks bytes |start|, inclusive, to |end|, exclusive, +// as received in |frag|. If |frag| becomes complete, it clears +// |frag->reassembly|. The range must be within the bounds of |frag|'s message +// and |frag->reassembly| must not be NULL. +static void dtls1_hm_fragment_mark(hm_fragment *frag, size_t start, + size_t end) { + size_t msg_len = frag->msg_len; + + if (frag->reassembly == NULL || start > end || end > msg_len) { + assert(0); + return; + } + // A zero-length message will never have a pending reassembly. + assert(msg_len > 0); + + if (start == end) { + return; + } + + if ((start >> 3) == (end >> 3)) { + frag->reassembly[start >> 3] |= bit_range(start & 7, end & 7); + } else { + frag->reassembly[start >> 3] |= bit_range(start & 7, 8); + for (size_t i = (start >> 3) + 1; i < (end >> 3); i++) { + frag->reassembly[i] = 0xff; + } + if ((end & 7) != 0) { + frag->reassembly[end >> 3] |= bit_range(0, end & 7); + } + } + + // Check if the fragment is complete. + for (size_t i = 0; i < (msg_len >> 3); i++) { + if (frag->reassembly[i] != 0xff) { + return; + } + } + if ((msg_len & 7) != 0 && + frag->reassembly[msg_len >> 3] != bit_range(0, msg_len & 7)) { + return; + } + + OPENSSL_free(frag->reassembly); + frag->reassembly = NULL; +} + +// dtls1_is_current_message_complete returns whether the current handshake +// message is complete. +static bool dtls1_is_current_message_complete(const SSL *ssl) { + size_t idx = ssl->d1->handshake_read_seq % SSL_MAX_HANDSHAKE_FLIGHT; + hm_fragment *frag = ssl->d1->incoming_messages[idx].get(); + return frag != NULL && frag->reassembly == NULL; +} + +// dtls1_get_incoming_message returns the incoming message corresponding to +// |msg_hdr|. If none exists, it creates a new one and inserts it in the +// queue. Otherwise, it checks |msg_hdr| is consistent with the existing one. It +// returns NULL on failure. The caller does not take ownership of the result. +static hm_fragment *dtls1_get_incoming_message( + SSL *ssl, uint8_t *out_alert, const struct hm_header_st *msg_hdr) { + if (msg_hdr->seq < ssl->d1->handshake_read_seq || + msg_hdr->seq - ssl->d1->handshake_read_seq >= SSL_MAX_HANDSHAKE_FLIGHT) { + *out_alert = SSL_AD_INTERNAL_ERROR; + return NULL; + } + + size_t idx = msg_hdr->seq % SSL_MAX_HANDSHAKE_FLIGHT; + hm_fragment *frag = ssl->d1->incoming_messages[idx].get(); + if (frag != NULL) { + assert(frag->seq == msg_hdr->seq); + // The new fragment must be compatible with the previous fragments from this + // message. + if (frag->type != msg_hdr->type || + frag->msg_len != msg_hdr->msg_len) { + OPENSSL_PUT_ERROR(SSL, SSL_R_FRAGMENT_MISMATCH); + *out_alert = SSL_AD_ILLEGAL_PARAMETER; + return NULL; + } + return frag; + } + + // This is the first fragment from this message. + ssl->d1->incoming_messages[idx] = dtls1_hm_fragment_new(msg_hdr); + if (!ssl->d1->incoming_messages[idx]) { + *out_alert = SSL_AD_INTERNAL_ERROR; + return NULL; + } + return ssl->d1->incoming_messages[idx].get(); +} + +ssl_open_record_t dtls1_open_handshake(SSL *ssl, size_t *out_consumed, + uint8_t *out_alert, Span in) { + uint8_t type; + Span record; + auto ret = dtls_open_record(ssl, &type, &record, out_consumed, out_alert, in); + if (ret != ssl_open_record_success) { + return ret; + } + + switch (type) { + case SSL3_RT_APPLICATION_DATA: + // Unencrypted application data records are always illegal. + if (ssl->s3->aead_read_ctx->is_null_cipher()) { + OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_RECORD); + *out_alert = SSL_AD_UNEXPECTED_MESSAGE; + return ssl_open_record_error; + } + + // Out-of-order application data may be received between ChangeCipherSpec + // and finished. Discard it. + return ssl_open_record_discard; + + case SSL3_RT_CHANGE_CIPHER_SPEC: + // We do not support renegotiation, so encrypted ChangeCipherSpec records + // are illegal. + if (!ssl->s3->aead_read_ctx->is_null_cipher()) { + OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_RECORD); + *out_alert = SSL_AD_UNEXPECTED_MESSAGE; + return ssl_open_record_error; + } + + if (record.size() != 1u || record[0] != SSL3_MT_CCS) { + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_CHANGE_CIPHER_SPEC); + *out_alert = SSL_AD_ILLEGAL_PARAMETER; + return ssl_open_record_error; + } + + // Flag the ChangeCipherSpec for later. + ssl->d1->has_change_cipher_spec = true; + ssl_do_msg_callback(ssl, 0 /* read */, SSL3_RT_CHANGE_CIPHER_SPEC, + record); + return ssl_open_record_success; + + case SSL3_RT_HANDSHAKE: + // Break out to main processing. + break; + + default: + OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_RECORD); + *out_alert = SSL_AD_UNEXPECTED_MESSAGE; + return ssl_open_record_error; + } + + CBS cbs; + CBS_init(&cbs, record.data(), record.size()); + while (CBS_len(&cbs) > 0) { + // Read a handshake fragment. + struct hm_header_st msg_hdr; + CBS body; + if (!dtls1_parse_fragment(&cbs, &msg_hdr, &body)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_HANDSHAKE_RECORD); + *out_alert = SSL_AD_DECODE_ERROR; + return ssl_open_record_error; + } + + const size_t frag_off = msg_hdr.frag_off; + const size_t frag_len = msg_hdr.frag_len; + const size_t msg_len = msg_hdr.msg_len; + if (frag_off > msg_len || frag_off + frag_len < frag_off || + frag_off + frag_len > msg_len || + msg_len > ssl_max_handshake_message_len(ssl)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_EXCESSIVE_MESSAGE_SIZE); + *out_alert = SSL_AD_ILLEGAL_PARAMETER; + return ssl_open_record_error; + } + + // The encrypted epoch in DTLS has only one handshake message. + if (ssl->d1->r_epoch == 1 && msg_hdr.seq != ssl->d1->handshake_read_seq) { + OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_RECORD); + *out_alert = SSL_AD_UNEXPECTED_MESSAGE; + return ssl_open_record_error; + } + + if (msg_hdr.seq < ssl->d1->handshake_read_seq || + msg_hdr.seq > + (unsigned)ssl->d1->handshake_read_seq + SSL_MAX_HANDSHAKE_FLIGHT) { + // Ignore fragments from the past, or ones too far in the future. + continue; + } + + hm_fragment *frag = dtls1_get_incoming_message(ssl, out_alert, &msg_hdr); + if (frag == NULL) { + return ssl_open_record_error; + } + assert(frag->msg_len == msg_len); + + if (frag->reassembly == NULL) { + // The message is already assembled. + continue; + } + assert(msg_len > 0); + + // Copy the body into the fragment. + OPENSSL_memcpy(frag->data + DTLS1_HM_HEADER_LENGTH + frag_off, + CBS_data(&body), CBS_len(&body)); + dtls1_hm_fragment_mark(frag, frag_off, frag_off + frag_len); + } + + return ssl_open_record_success; +} + +bool dtls1_get_message(SSL *ssl, SSLMessage *out) { + if (!dtls1_is_current_message_complete(ssl)) { + return false; + } + + size_t idx = ssl->d1->handshake_read_seq % SSL_MAX_HANDSHAKE_FLIGHT; + hm_fragment *frag = ssl->d1->incoming_messages[idx].get(); + out->type = frag->type; + CBS_init(&out->body, frag->data + DTLS1_HM_HEADER_LENGTH, frag->msg_len); + CBS_init(&out->raw, frag->data, DTLS1_HM_HEADER_LENGTH + frag->msg_len); + out->is_v2_hello = false; + if (!ssl->s3->has_message) { + ssl_do_msg_callback(ssl, 0 /* read */, SSL3_RT_HANDSHAKE, out->raw); + ssl->s3->has_message = true; + } + return true; +} + +void dtls1_next_message(SSL *ssl) { + assert(ssl->s3->has_message); + assert(dtls1_is_current_message_complete(ssl)); + size_t index = ssl->d1->handshake_read_seq % SSL_MAX_HANDSHAKE_FLIGHT; + ssl->d1->incoming_messages[index].reset(); + ssl->d1->handshake_read_seq++; + ssl->s3->has_message = false; + // If we previously sent a flight, mark it as having a reply, so + // |on_handshake_complete| can manage post-handshake retransmission. + if (ssl->d1->outgoing_messages_complete) { + ssl->d1->flight_has_reply = true; + } +} + +bool dtls_has_unprocessed_handshake_data(const SSL *ssl) { + if (ssl->d1->has_change_cipher_spec) { + return true; + } + + size_t current = ssl->d1->handshake_read_seq % SSL_MAX_HANDSHAKE_FLIGHT; + for (size_t i = 0; i < SSL_MAX_HANDSHAKE_FLIGHT; i++) { + // Skip the current message. + if (ssl->s3->has_message && i == current) { + assert(dtls1_is_current_message_complete(ssl)); + continue; + } + if (ssl->d1->incoming_messages[i] != nullptr) { + return true; + } + } + return false; +} + +bool dtls1_parse_fragment(CBS *cbs, struct hm_header_st *out_hdr, + CBS *out_body) { + OPENSSL_memset(out_hdr, 0x00, sizeof(struct hm_header_st)); + + if (!CBS_get_u8(cbs, &out_hdr->type) || + !CBS_get_u24(cbs, &out_hdr->msg_len) || + !CBS_get_u16(cbs, &out_hdr->seq) || + !CBS_get_u24(cbs, &out_hdr->frag_off) || + !CBS_get_u24(cbs, &out_hdr->frag_len) || + !CBS_get_bytes(cbs, out_body, out_hdr->frag_len)) { + return false; + } + + return true; +} + +ssl_open_record_t dtls1_open_change_cipher_spec(SSL *ssl, size_t *out_consumed, + uint8_t *out_alert, + Span in) { + if (!ssl->d1->has_change_cipher_spec) { + // dtls1_open_handshake processes both handshake and ChangeCipherSpec. + auto ret = dtls1_open_handshake(ssl, out_consumed, out_alert, in); + if (ret != ssl_open_record_success) { + return ret; + } + } + if (ssl->d1->has_change_cipher_spec) { + ssl->d1->has_change_cipher_spec = false; + return ssl_open_record_success; + } + return ssl_open_record_discard; +} + + +// Sending handshake messages. + +void DTLS_OUTGOING_MESSAGE::Clear() { + OPENSSL_free(data); + data = nullptr; +} + +void dtls_clear_outgoing_messages(SSL *ssl) { + for (size_t i = 0; i < ssl->d1->outgoing_messages_len; i++) { + ssl->d1->outgoing_messages[i].Clear(); + } + ssl->d1->outgoing_messages_len = 0; + ssl->d1->outgoing_written = 0; + ssl->d1->outgoing_offset = 0; + ssl->d1->outgoing_messages_complete = false; + ssl->d1->flight_has_reply = false; +} + +bool dtls1_init_message(SSL *ssl, CBB *cbb, CBB *body, uint8_t type) { + // Pick a modest size hint to save most of the |realloc| calls. + if (!CBB_init(cbb, 64) || + !CBB_add_u8(cbb, type) || + !CBB_add_u24(cbb, 0 /* length (filled in later) */) || + !CBB_add_u16(cbb, ssl->d1->handshake_write_seq) || + !CBB_add_u24(cbb, 0 /* offset */) || + !CBB_add_u24_length_prefixed(cbb, body)) { + return false; + } + + return true; +} + +bool dtls1_finish_message(SSL *ssl, CBB *cbb, Array *out_msg) { + if (!CBBFinishArray(cbb, out_msg) || + out_msg->size() < DTLS1_HM_HEADER_LENGTH) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return false; + } + + // Fix up the header. Copy the fragment length into the total message + // length. + OPENSSL_memcpy(out_msg->data() + 1, + out_msg->data() + DTLS1_HM_HEADER_LENGTH - 3, 3); + return true; +} + +// ssl_size_t_greater_than_32_bits returns whether |v| exceeds the bounds of a +// 32-bit value. The obvious thing doesn't work because, in some 32-bit build +// configurations, the compiler warns that the test is always false and breaks +// the build. +static bool ssl_size_t_greater_than_32_bits(size_t v) { +#if defined(OPENSSL_64_BIT) + return v > 0xffffffff; +#elif defined(OPENSSL_32_BIT) + return false; +#else +#error "Building for neither 32- nor 64-bits." +#endif +} + +// add_outgoing adds a new handshake message or ChangeCipherSpec to the current +// outgoing flight. It returns true on success and false on error. +static bool add_outgoing(SSL *ssl, bool is_ccs, Array data) { + if (ssl->d1->outgoing_messages_complete) { + // If we've begun writing a new flight, we received the peer flight. Discard + // the timer and the our flight. + dtls1_stop_timer(ssl); + dtls_clear_outgoing_messages(ssl); + } + + static_assert(SSL_MAX_HANDSHAKE_FLIGHT < + (1 << 8 * sizeof(ssl->d1->outgoing_messages_len)), + "outgoing_messages_len is too small"); + if (ssl->d1->outgoing_messages_len >= SSL_MAX_HANDSHAKE_FLIGHT || + ssl_size_t_greater_than_32_bits(data.size())) { + assert(false); + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return false; + } + + if (!is_ccs) { + // TODO(svaldez): Move this up a layer to fix abstraction for SSLTranscript + // on hs. + if (ssl->s3->hs != NULL && + !ssl->s3->hs->transcript.Update(data)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return false; + } + ssl->d1->handshake_write_seq++; + } + + DTLS_OUTGOING_MESSAGE *msg = + &ssl->d1->outgoing_messages[ssl->d1->outgoing_messages_len]; + size_t len; + data.Release(&msg->data, &len); + msg->len = len; + msg->epoch = ssl->d1->w_epoch; + msg->is_ccs = is_ccs; + + ssl->d1->outgoing_messages_len++; + return true; +} + +bool dtls1_add_message(SSL *ssl, Array data) { + return add_outgoing(ssl, false /* handshake */, std::move(data)); +} + +bool dtls1_add_change_cipher_spec(SSL *ssl) { + return add_outgoing(ssl, true /* ChangeCipherSpec */, Array()); +} + +bool dtls1_add_alert(SSL *ssl, uint8_t level, uint8_t desc) { + // The |add_alert| path is only used for warning alerts for now, which DTLS + // never sends. This will be implemented later once closure alerts are + // converted. + assert(false); + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return false; +} + +// dtls1_update_mtu updates the current MTU from the BIO, ensuring it is above +// the minimum. +static void dtls1_update_mtu(SSL *ssl) { + // TODO(davidben): No consumer implements |BIO_CTRL_DGRAM_SET_MTU| and the + // only |BIO_CTRL_DGRAM_QUERY_MTU| implementation could use + // |SSL_set_mtu|. Does this need to be so complex? + if (ssl->d1->mtu < dtls1_min_mtu() && + !(SSL_get_options(ssl) & SSL_OP_NO_QUERY_MTU)) { + long mtu = BIO_ctrl(ssl->wbio, BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL); + if (mtu >= 0 && mtu <= (1 << 30) && (unsigned)mtu >= dtls1_min_mtu()) { + ssl->d1->mtu = (unsigned)mtu; + } else { + ssl->d1->mtu = kDefaultMTU; + BIO_ctrl(ssl->wbio, BIO_CTRL_DGRAM_SET_MTU, ssl->d1->mtu, NULL); + } + } + + // The MTU should be above the minimum now. + assert(ssl->d1->mtu >= dtls1_min_mtu()); +} + +enum seal_result_t { + seal_error, + seal_no_progress, + seal_partial, + seal_success, +}; + +// seal_next_message seals |msg|, which must be the next message, to |out|. If +// progress was made, it returns |seal_partial| or |seal_success| and sets +// |*out_len| to the number of bytes written. +static enum seal_result_t seal_next_message(SSL *ssl, uint8_t *out, + size_t *out_len, size_t max_out, + const DTLS_OUTGOING_MESSAGE *msg) { + assert(ssl->d1->outgoing_written < ssl->d1->outgoing_messages_len); + assert(msg == &ssl->d1->outgoing_messages[ssl->d1->outgoing_written]); + + enum dtls1_use_epoch_t use_epoch = dtls1_use_current_epoch; + if (ssl->d1->w_epoch >= 1 && msg->epoch == ssl->d1->w_epoch - 1) { + use_epoch = dtls1_use_previous_epoch; + } else if (msg->epoch != ssl->d1->w_epoch) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return seal_error; + } + + size_t overhead = dtls_max_seal_overhead(ssl, use_epoch); + size_t prefix = dtls_seal_prefix_len(ssl, use_epoch); + + if (msg->is_ccs) { + // Check there is room for the ChangeCipherSpec. + static const uint8_t kChangeCipherSpec[1] = {SSL3_MT_CCS}; + if (max_out < sizeof(kChangeCipherSpec) + overhead) { + return seal_no_progress; + } + + if (!dtls_seal_record(ssl, out, out_len, max_out, + SSL3_RT_CHANGE_CIPHER_SPEC, kChangeCipherSpec, + sizeof(kChangeCipherSpec), use_epoch)) { + return seal_error; + } + + ssl_do_msg_callback(ssl, 1 /* write */, SSL3_RT_CHANGE_CIPHER_SPEC, + kChangeCipherSpec); + return seal_success; + } + + // DTLS messages are serialized as a single fragment in |msg|. + CBS cbs, body; + struct hm_header_st hdr; + CBS_init(&cbs, msg->data, msg->len); + if (!dtls1_parse_fragment(&cbs, &hdr, &body) || + hdr.frag_off != 0 || + hdr.frag_len != CBS_len(&body) || + hdr.msg_len != CBS_len(&body) || + !CBS_skip(&body, ssl->d1->outgoing_offset) || + CBS_len(&cbs) != 0) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return seal_error; + } + + // Determine how much progress can be made. + if (max_out < DTLS1_HM_HEADER_LENGTH + 1 + overhead || max_out < prefix) { + return seal_no_progress; + } + size_t todo = CBS_len(&body); + if (todo > max_out - DTLS1_HM_HEADER_LENGTH - overhead) { + todo = max_out - DTLS1_HM_HEADER_LENGTH - overhead; + } + + // Assemble a fragment, to be sealed in-place. + ScopedCBB cbb; + uint8_t *frag = out + prefix; + size_t max_frag = max_out - prefix, frag_len; + if (!CBB_init_fixed(cbb.get(), frag, max_frag) || + !CBB_add_u8(cbb.get(), hdr.type) || + !CBB_add_u24(cbb.get(), hdr.msg_len) || + !CBB_add_u16(cbb.get(), hdr.seq) || + !CBB_add_u24(cbb.get(), ssl->d1->outgoing_offset) || + !CBB_add_u24(cbb.get(), todo) || + !CBB_add_bytes(cbb.get(), CBS_data(&body), todo) || + !CBB_finish(cbb.get(), NULL, &frag_len)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return seal_error; + } + + ssl_do_msg_callback(ssl, 1 /* write */, SSL3_RT_HANDSHAKE, + MakeSpan(frag, frag_len)); + + if (!dtls_seal_record(ssl, out, out_len, max_out, SSL3_RT_HANDSHAKE, + out + prefix, frag_len, use_epoch)) { + return seal_error; + } + + if (todo == CBS_len(&body)) { + // The next message is complete. + ssl->d1->outgoing_offset = 0; + return seal_success; + } + + ssl->d1->outgoing_offset += todo; + return seal_partial; +} + +// seal_next_packet writes as much of the next flight as possible to |out| and +// advances |ssl->d1->outgoing_written| and |ssl->d1->outgoing_offset| as +// appropriate. +static bool seal_next_packet(SSL *ssl, uint8_t *out, size_t *out_len, + size_t max_out) { + bool made_progress = false; + size_t total = 0; + assert(ssl->d1->outgoing_written < ssl->d1->outgoing_messages_len); + for (; ssl->d1->outgoing_written < ssl->d1->outgoing_messages_len; + ssl->d1->outgoing_written++) { + const DTLS_OUTGOING_MESSAGE *msg = + &ssl->d1->outgoing_messages[ssl->d1->outgoing_written]; + size_t len; + enum seal_result_t ret = seal_next_message(ssl, out, &len, max_out, msg); + switch (ret) { + case seal_error: + return false; + + case seal_no_progress: + goto packet_full; + + case seal_partial: + case seal_success: + out += len; + max_out -= len; + total += len; + made_progress = true; + + if (ret == seal_partial) { + goto packet_full; + } + break; + } + } + +packet_full: + // The MTU was too small to make any progress. + if (!made_progress) { + OPENSSL_PUT_ERROR(SSL, SSL_R_MTU_TOO_SMALL); + return false; + } + + *out_len = total; + return true; +} + +static int send_flight(SSL *ssl) { + if (ssl->s3->write_shutdown != ssl_shutdown_none) { + OPENSSL_PUT_ERROR(SSL, SSL_R_PROTOCOL_IS_SHUTDOWN); + return -1; + } + + dtls1_update_mtu(ssl); + + int ret = -1; + uint8_t *packet = (uint8_t *)OPENSSL_malloc(ssl->d1->mtu); + if (packet == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + goto err; + } + + while (ssl->d1->outgoing_written < ssl->d1->outgoing_messages_len) { + uint8_t old_written = ssl->d1->outgoing_written; + uint32_t old_offset = ssl->d1->outgoing_offset; + + size_t packet_len; + if (!seal_next_packet(ssl, packet, &packet_len, ssl->d1->mtu)) { + goto err; + } + + int bio_ret = BIO_write(ssl->wbio, packet, packet_len); + if (bio_ret <= 0) { + // Retry this packet the next time around. + ssl->d1->outgoing_written = old_written; + ssl->d1->outgoing_offset = old_offset; + ssl->s3->rwstate = SSL_WRITING; + ret = bio_ret; + goto err; + } + } + + if (BIO_flush(ssl->wbio) <= 0) { + ssl->s3->rwstate = SSL_WRITING; + goto err; + } + + ret = 1; + +err: + OPENSSL_free(packet); + return ret; +} + +int dtls1_flush_flight(SSL *ssl) { + ssl->d1->outgoing_messages_complete = true; + // Start the retransmission timer for the next flight (if any). + dtls1_start_timer(ssl); + return send_flight(ssl); +} + +int dtls1_retransmit_outgoing_messages(SSL *ssl) { + // Rewind to the start of the flight and write it again. + // + // TODO(davidben): This does not allow retransmits to be resumed on + // non-blocking write. + ssl->d1->outgoing_written = 0; + ssl->d1->outgoing_offset = 0; + + return send_flight(ssl); +} + +unsigned int dtls1_min_mtu(void) { + return kMinMTU; +} + +} // namespace bssl diff --git a/FoodApp/Pods/BoringSSL-GRPC/ssl/d1_both.cc.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/ssl/d1_both.cc.grpc_back new file mode 100644 index 0000000..31c83c6 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/ssl/d1_both.cc.grpc_back @@ -0,0 +1,851 @@ +/* + * DTLS implementation written by Nagendra Modadugu + * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. + */ +/* ==================================================================== + * 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 (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 +#include +#include +#include +#include + +#include "../crypto/internal.h" +#include "internal.h" + + +namespace bssl { + +// TODO(davidben): 28 comes from the size of IP + UDP header. Is this reasonable +// for these values? Notably, why is kMinMTU a function of the transport +// protocol's overhead rather than, say, what's needed to hold a minimally-sized +// handshake fragment plus protocol overhead. + +// kMinMTU is the minimum acceptable MTU value. +static const unsigned int kMinMTU = 256 - 28; + +// kDefaultMTU is the default MTU value to use if neither the user nor +// the underlying BIO supplies one. +static const unsigned int kDefaultMTU = 1500 - 28; + + +// Receiving handshake messages. + +hm_fragment::~hm_fragment() { + OPENSSL_free(data); + OPENSSL_free(reassembly); +} + +static UniquePtr dtls1_hm_fragment_new( + const struct hm_header_st *msg_hdr) { + ScopedCBB cbb; + UniquePtr frag = MakeUnique(); + if (!frag) { + return nullptr; + } + frag->type = msg_hdr->type; + frag->seq = msg_hdr->seq; + frag->msg_len = msg_hdr->msg_len; + + // Allocate space for the reassembled message and fill in the header. + frag->data = + (uint8_t *)OPENSSL_malloc(DTLS1_HM_HEADER_LENGTH + msg_hdr->msg_len); + if (frag->data == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return nullptr; + } + + if (!CBB_init_fixed(cbb.get(), frag->data, DTLS1_HM_HEADER_LENGTH) || + !CBB_add_u8(cbb.get(), msg_hdr->type) || + !CBB_add_u24(cbb.get(), msg_hdr->msg_len) || + !CBB_add_u16(cbb.get(), msg_hdr->seq) || + !CBB_add_u24(cbb.get(), 0 /* frag_off */) || + !CBB_add_u24(cbb.get(), msg_hdr->msg_len) || + !CBB_finish(cbb.get(), NULL, NULL)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return nullptr; + } + + // If the handshake message is empty, |frag->reassembly| is NULL. + if (msg_hdr->msg_len > 0) { + // Initialize reassembly bitmask. + if (msg_hdr->msg_len + 7 < msg_hdr->msg_len) { + OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW); + return nullptr; + } + size_t bitmask_len = (msg_hdr->msg_len + 7) / 8; + frag->reassembly = (uint8_t *)OPENSSL_malloc(bitmask_len); + if (frag->reassembly == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return nullptr; + } + OPENSSL_memset(frag->reassembly, 0, bitmask_len); + } + + return frag; +} + +// bit_range returns a |uint8_t| with bits |start|, inclusive, to |end|, +// exclusive, set. +static uint8_t bit_range(size_t start, size_t end) { + return (uint8_t)(~((1u << start) - 1) & ((1u << end) - 1)); +} + +// dtls1_hm_fragment_mark marks bytes |start|, inclusive, to |end|, exclusive, +// as received in |frag|. If |frag| becomes complete, it clears +// |frag->reassembly|. The range must be within the bounds of |frag|'s message +// and |frag->reassembly| must not be NULL. +static void dtls1_hm_fragment_mark(hm_fragment *frag, size_t start, + size_t end) { + size_t msg_len = frag->msg_len; + + if (frag->reassembly == NULL || start > end || end > msg_len) { + assert(0); + return; + } + // A zero-length message will never have a pending reassembly. + assert(msg_len > 0); + + if (start == end) { + return; + } + + if ((start >> 3) == (end >> 3)) { + frag->reassembly[start >> 3] |= bit_range(start & 7, end & 7); + } else { + frag->reassembly[start >> 3] |= bit_range(start & 7, 8); + for (size_t i = (start >> 3) + 1; i < (end >> 3); i++) { + frag->reassembly[i] = 0xff; + } + if ((end & 7) != 0) { + frag->reassembly[end >> 3] |= bit_range(0, end & 7); + } + } + + // Check if the fragment is complete. + for (size_t i = 0; i < (msg_len >> 3); i++) { + if (frag->reassembly[i] != 0xff) { + return; + } + } + if ((msg_len & 7) != 0 && + frag->reassembly[msg_len >> 3] != bit_range(0, msg_len & 7)) { + return; + } + + OPENSSL_free(frag->reassembly); + frag->reassembly = NULL; +} + +// dtls1_is_current_message_complete returns whether the current handshake +// message is complete. +static bool dtls1_is_current_message_complete(const SSL *ssl) { + size_t idx = ssl->d1->handshake_read_seq % SSL_MAX_HANDSHAKE_FLIGHT; + hm_fragment *frag = ssl->d1->incoming_messages[idx].get(); + return frag != NULL && frag->reassembly == NULL; +} + +// dtls1_get_incoming_message returns the incoming message corresponding to +// |msg_hdr|. If none exists, it creates a new one and inserts it in the +// queue. Otherwise, it checks |msg_hdr| is consistent with the existing one. It +// returns NULL on failure. The caller does not take ownership of the result. +static hm_fragment *dtls1_get_incoming_message( + SSL *ssl, uint8_t *out_alert, const struct hm_header_st *msg_hdr) { + if (msg_hdr->seq < ssl->d1->handshake_read_seq || + msg_hdr->seq - ssl->d1->handshake_read_seq >= SSL_MAX_HANDSHAKE_FLIGHT) { + *out_alert = SSL_AD_INTERNAL_ERROR; + return NULL; + } + + size_t idx = msg_hdr->seq % SSL_MAX_HANDSHAKE_FLIGHT; + hm_fragment *frag = ssl->d1->incoming_messages[idx].get(); + if (frag != NULL) { + assert(frag->seq == msg_hdr->seq); + // The new fragment must be compatible with the previous fragments from this + // message. + if (frag->type != msg_hdr->type || + frag->msg_len != msg_hdr->msg_len) { + OPENSSL_PUT_ERROR(SSL, SSL_R_FRAGMENT_MISMATCH); + *out_alert = SSL_AD_ILLEGAL_PARAMETER; + return NULL; + } + return frag; + } + + // This is the first fragment from this message. + ssl->d1->incoming_messages[idx] = dtls1_hm_fragment_new(msg_hdr); + if (!ssl->d1->incoming_messages[idx]) { + *out_alert = SSL_AD_INTERNAL_ERROR; + return NULL; + } + return ssl->d1->incoming_messages[idx].get(); +} + +ssl_open_record_t dtls1_open_handshake(SSL *ssl, size_t *out_consumed, + uint8_t *out_alert, Span in) { + uint8_t type; + Span record; + auto ret = dtls_open_record(ssl, &type, &record, out_consumed, out_alert, in); + if (ret != ssl_open_record_success) { + return ret; + } + + switch (type) { + case SSL3_RT_APPLICATION_DATA: + // Unencrypted application data records are always illegal. + if (ssl->s3->aead_read_ctx->is_null_cipher()) { + OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_RECORD); + *out_alert = SSL_AD_UNEXPECTED_MESSAGE; + return ssl_open_record_error; + } + + // Out-of-order application data may be received between ChangeCipherSpec + // and finished. Discard it. + return ssl_open_record_discard; + + case SSL3_RT_CHANGE_CIPHER_SPEC: + // We do not support renegotiation, so encrypted ChangeCipherSpec records + // are illegal. + if (!ssl->s3->aead_read_ctx->is_null_cipher()) { + OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_RECORD); + *out_alert = SSL_AD_UNEXPECTED_MESSAGE; + return ssl_open_record_error; + } + + if (record.size() != 1u || record[0] != SSL3_MT_CCS) { + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_CHANGE_CIPHER_SPEC); + *out_alert = SSL_AD_ILLEGAL_PARAMETER; + return ssl_open_record_error; + } + + // Flag the ChangeCipherSpec for later. + ssl->d1->has_change_cipher_spec = true; + ssl_do_msg_callback(ssl, 0 /* read */, SSL3_RT_CHANGE_CIPHER_SPEC, + record); + return ssl_open_record_success; + + case SSL3_RT_HANDSHAKE: + // Break out to main processing. + break; + + default: + OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_RECORD); + *out_alert = SSL_AD_UNEXPECTED_MESSAGE; + return ssl_open_record_error; + } + + CBS cbs; + CBS_init(&cbs, record.data(), record.size()); + while (CBS_len(&cbs) > 0) { + // Read a handshake fragment. + struct hm_header_st msg_hdr; + CBS body; + if (!dtls1_parse_fragment(&cbs, &msg_hdr, &body)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_HANDSHAKE_RECORD); + *out_alert = SSL_AD_DECODE_ERROR; + return ssl_open_record_error; + } + + const size_t frag_off = msg_hdr.frag_off; + const size_t frag_len = msg_hdr.frag_len; + const size_t msg_len = msg_hdr.msg_len; + if (frag_off > msg_len || frag_off + frag_len < frag_off || + frag_off + frag_len > msg_len || + msg_len > ssl_max_handshake_message_len(ssl)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_EXCESSIVE_MESSAGE_SIZE); + *out_alert = SSL_AD_ILLEGAL_PARAMETER; + return ssl_open_record_error; + } + + // The encrypted epoch in DTLS has only one handshake message. + if (ssl->d1->r_epoch == 1 && msg_hdr.seq != ssl->d1->handshake_read_seq) { + OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_RECORD); + *out_alert = SSL_AD_UNEXPECTED_MESSAGE; + return ssl_open_record_error; + } + + if (msg_hdr.seq < ssl->d1->handshake_read_seq || + msg_hdr.seq > + (unsigned)ssl->d1->handshake_read_seq + SSL_MAX_HANDSHAKE_FLIGHT) { + // Ignore fragments from the past, or ones too far in the future. + continue; + } + + hm_fragment *frag = dtls1_get_incoming_message(ssl, out_alert, &msg_hdr); + if (frag == NULL) { + return ssl_open_record_error; + } + assert(frag->msg_len == msg_len); + + if (frag->reassembly == NULL) { + // The message is already assembled. + continue; + } + assert(msg_len > 0); + + // Copy the body into the fragment. + OPENSSL_memcpy(frag->data + DTLS1_HM_HEADER_LENGTH + frag_off, + CBS_data(&body), CBS_len(&body)); + dtls1_hm_fragment_mark(frag, frag_off, frag_off + frag_len); + } + + return ssl_open_record_success; +} + +bool dtls1_get_message(SSL *ssl, SSLMessage *out) { + if (!dtls1_is_current_message_complete(ssl)) { + return false; + } + + size_t idx = ssl->d1->handshake_read_seq % SSL_MAX_HANDSHAKE_FLIGHT; + hm_fragment *frag = ssl->d1->incoming_messages[idx].get(); + out->type = frag->type; + CBS_init(&out->body, frag->data + DTLS1_HM_HEADER_LENGTH, frag->msg_len); + CBS_init(&out->raw, frag->data, DTLS1_HM_HEADER_LENGTH + frag->msg_len); + out->is_v2_hello = false; + if (!ssl->s3->has_message) { + ssl_do_msg_callback(ssl, 0 /* read */, SSL3_RT_HANDSHAKE, out->raw); + ssl->s3->has_message = true; + } + return true; +} + +void dtls1_next_message(SSL *ssl) { + assert(ssl->s3->has_message); + assert(dtls1_is_current_message_complete(ssl)); + size_t index = ssl->d1->handshake_read_seq % SSL_MAX_HANDSHAKE_FLIGHT; + ssl->d1->incoming_messages[index].reset(); + ssl->d1->handshake_read_seq++; + ssl->s3->has_message = false; + // If we previously sent a flight, mark it as having a reply, so + // |on_handshake_complete| can manage post-handshake retransmission. + if (ssl->d1->outgoing_messages_complete) { + ssl->d1->flight_has_reply = true; + } +} + +bool dtls_has_unprocessed_handshake_data(const SSL *ssl) { + if (ssl->d1->has_change_cipher_spec) { + return true; + } + + size_t current = ssl->d1->handshake_read_seq % SSL_MAX_HANDSHAKE_FLIGHT; + for (size_t i = 0; i < SSL_MAX_HANDSHAKE_FLIGHT; i++) { + // Skip the current message. + if (ssl->s3->has_message && i == current) { + assert(dtls1_is_current_message_complete(ssl)); + continue; + } + if (ssl->d1->incoming_messages[i] != nullptr) { + return true; + } + } + return false; +} + +bool dtls1_parse_fragment(CBS *cbs, struct hm_header_st *out_hdr, + CBS *out_body) { + OPENSSL_memset(out_hdr, 0x00, sizeof(struct hm_header_st)); + + if (!CBS_get_u8(cbs, &out_hdr->type) || + !CBS_get_u24(cbs, &out_hdr->msg_len) || + !CBS_get_u16(cbs, &out_hdr->seq) || + !CBS_get_u24(cbs, &out_hdr->frag_off) || + !CBS_get_u24(cbs, &out_hdr->frag_len) || + !CBS_get_bytes(cbs, out_body, out_hdr->frag_len)) { + return false; + } + + return true; +} + +ssl_open_record_t dtls1_open_change_cipher_spec(SSL *ssl, size_t *out_consumed, + uint8_t *out_alert, + Span in) { + if (!ssl->d1->has_change_cipher_spec) { + // dtls1_open_handshake processes both handshake and ChangeCipherSpec. + auto ret = dtls1_open_handshake(ssl, out_consumed, out_alert, in); + if (ret != ssl_open_record_success) { + return ret; + } + } + if (ssl->d1->has_change_cipher_spec) { + ssl->d1->has_change_cipher_spec = false; + return ssl_open_record_success; + } + return ssl_open_record_discard; +} + + +// Sending handshake messages. + +void DTLS_OUTGOING_MESSAGE::Clear() { + OPENSSL_free(data); + data = nullptr; +} + +void dtls_clear_outgoing_messages(SSL *ssl) { + for (size_t i = 0; i < ssl->d1->outgoing_messages_len; i++) { + ssl->d1->outgoing_messages[i].Clear(); + } + ssl->d1->outgoing_messages_len = 0; + ssl->d1->outgoing_written = 0; + ssl->d1->outgoing_offset = 0; + ssl->d1->outgoing_messages_complete = false; + ssl->d1->flight_has_reply = false; +} + +bool dtls1_init_message(SSL *ssl, CBB *cbb, CBB *body, uint8_t type) { + // Pick a modest size hint to save most of the |realloc| calls. + if (!CBB_init(cbb, 64) || + !CBB_add_u8(cbb, type) || + !CBB_add_u24(cbb, 0 /* length (filled in later) */) || + !CBB_add_u16(cbb, ssl->d1->handshake_write_seq) || + !CBB_add_u24(cbb, 0 /* offset */) || + !CBB_add_u24_length_prefixed(cbb, body)) { + return false; + } + + return true; +} + +bool dtls1_finish_message(SSL *ssl, CBB *cbb, Array *out_msg) { + if (!CBBFinishArray(cbb, out_msg) || + out_msg->size() < DTLS1_HM_HEADER_LENGTH) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return false; + } + + // Fix up the header. Copy the fragment length into the total message + // length. + OPENSSL_memcpy(out_msg->data() + 1, + out_msg->data() + DTLS1_HM_HEADER_LENGTH - 3, 3); + return true; +} + +// ssl_size_t_greater_than_32_bits returns whether |v| exceeds the bounds of a +// 32-bit value. The obvious thing doesn't work because, in some 32-bit build +// configurations, the compiler warns that the test is always false and breaks +// the build. +static bool ssl_size_t_greater_than_32_bits(size_t v) { +#if defined(OPENSSL_64_BIT) + return v > 0xffffffff; +#elif defined(OPENSSL_32_BIT) + return false; +#else +#error "Building for neither 32- nor 64-bits." +#endif +} + +// add_outgoing adds a new handshake message or ChangeCipherSpec to the current +// outgoing flight. It returns true on success and false on error. +static bool add_outgoing(SSL *ssl, bool is_ccs, Array data) { + if (ssl->d1->outgoing_messages_complete) { + // If we've begun writing a new flight, we received the peer flight. Discard + // the timer and the our flight. + dtls1_stop_timer(ssl); + dtls_clear_outgoing_messages(ssl); + } + + static_assert(SSL_MAX_HANDSHAKE_FLIGHT < + (1 << 8 * sizeof(ssl->d1->outgoing_messages_len)), + "outgoing_messages_len is too small"); + if (ssl->d1->outgoing_messages_len >= SSL_MAX_HANDSHAKE_FLIGHT || + ssl_size_t_greater_than_32_bits(data.size())) { + assert(false); + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return false; + } + + if (!is_ccs) { + // TODO(svaldez): Move this up a layer to fix abstraction for SSLTranscript + // on hs. + if (ssl->s3->hs != NULL && + !ssl->s3->hs->transcript.Update(data)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return false; + } + ssl->d1->handshake_write_seq++; + } + + DTLS_OUTGOING_MESSAGE *msg = + &ssl->d1->outgoing_messages[ssl->d1->outgoing_messages_len]; + size_t len; + data.Release(&msg->data, &len); + msg->len = len; + msg->epoch = ssl->d1->w_epoch; + msg->is_ccs = is_ccs; + + ssl->d1->outgoing_messages_len++; + return true; +} + +bool dtls1_add_message(SSL *ssl, Array data) { + return add_outgoing(ssl, false /* handshake */, std::move(data)); +} + +bool dtls1_add_change_cipher_spec(SSL *ssl) { + return add_outgoing(ssl, true /* ChangeCipherSpec */, Array()); +} + +bool dtls1_add_alert(SSL *ssl, uint8_t level, uint8_t desc) { + // The |add_alert| path is only used for warning alerts for now, which DTLS + // never sends. This will be implemented later once closure alerts are + // converted. + assert(false); + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return false; +} + +// dtls1_update_mtu updates the current MTU from the BIO, ensuring it is above +// the minimum. +static void dtls1_update_mtu(SSL *ssl) { + // TODO(davidben): No consumer implements |BIO_CTRL_DGRAM_SET_MTU| and the + // only |BIO_CTRL_DGRAM_QUERY_MTU| implementation could use + // |SSL_set_mtu|. Does this need to be so complex? + if (ssl->d1->mtu < dtls1_min_mtu() && + !(SSL_get_options(ssl) & SSL_OP_NO_QUERY_MTU)) { + long mtu = BIO_ctrl(ssl->wbio, BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL); + if (mtu >= 0 && mtu <= (1 << 30) && (unsigned)mtu >= dtls1_min_mtu()) { + ssl->d1->mtu = (unsigned)mtu; + } else { + ssl->d1->mtu = kDefaultMTU; + BIO_ctrl(ssl->wbio, BIO_CTRL_DGRAM_SET_MTU, ssl->d1->mtu, NULL); + } + } + + // The MTU should be above the minimum now. + assert(ssl->d1->mtu >= dtls1_min_mtu()); +} + +enum seal_result_t { + seal_error, + seal_no_progress, + seal_partial, + seal_success, +}; + +// seal_next_message seals |msg|, which must be the next message, to |out|. If +// progress was made, it returns |seal_partial| or |seal_success| and sets +// |*out_len| to the number of bytes written. +static enum seal_result_t seal_next_message(SSL *ssl, uint8_t *out, + size_t *out_len, size_t max_out, + const DTLS_OUTGOING_MESSAGE *msg) { + assert(ssl->d1->outgoing_written < ssl->d1->outgoing_messages_len); + assert(msg == &ssl->d1->outgoing_messages[ssl->d1->outgoing_written]); + + enum dtls1_use_epoch_t use_epoch = dtls1_use_current_epoch; + if (ssl->d1->w_epoch >= 1 && msg->epoch == ssl->d1->w_epoch - 1) { + use_epoch = dtls1_use_previous_epoch; + } else if (msg->epoch != ssl->d1->w_epoch) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return seal_error; + } + + size_t overhead = dtls_max_seal_overhead(ssl, use_epoch); + size_t prefix = dtls_seal_prefix_len(ssl, use_epoch); + + if (msg->is_ccs) { + // Check there is room for the ChangeCipherSpec. + static const uint8_t kChangeCipherSpec[1] = {SSL3_MT_CCS}; + if (max_out < sizeof(kChangeCipherSpec) + overhead) { + return seal_no_progress; + } + + if (!dtls_seal_record(ssl, out, out_len, max_out, + SSL3_RT_CHANGE_CIPHER_SPEC, kChangeCipherSpec, + sizeof(kChangeCipherSpec), use_epoch)) { + return seal_error; + } + + ssl_do_msg_callback(ssl, 1 /* write */, SSL3_RT_CHANGE_CIPHER_SPEC, + kChangeCipherSpec); + return seal_success; + } + + // DTLS messages are serialized as a single fragment in |msg|. + CBS cbs, body; + struct hm_header_st hdr; + CBS_init(&cbs, msg->data, msg->len); + if (!dtls1_parse_fragment(&cbs, &hdr, &body) || + hdr.frag_off != 0 || + hdr.frag_len != CBS_len(&body) || + hdr.msg_len != CBS_len(&body) || + !CBS_skip(&body, ssl->d1->outgoing_offset) || + CBS_len(&cbs) != 0) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return seal_error; + } + + // Determine how much progress can be made. + if (max_out < DTLS1_HM_HEADER_LENGTH + 1 + overhead || max_out < prefix) { + return seal_no_progress; + } + size_t todo = CBS_len(&body); + if (todo > max_out - DTLS1_HM_HEADER_LENGTH - overhead) { + todo = max_out - DTLS1_HM_HEADER_LENGTH - overhead; + } + + // Assemble a fragment, to be sealed in-place. + ScopedCBB cbb; + uint8_t *frag = out + prefix; + size_t max_frag = max_out - prefix, frag_len; + if (!CBB_init_fixed(cbb.get(), frag, max_frag) || + !CBB_add_u8(cbb.get(), hdr.type) || + !CBB_add_u24(cbb.get(), hdr.msg_len) || + !CBB_add_u16(cbb.get(), hdr.seq) || + !CBB_add_u24(cbb.get(), ssl->d1->outgoing_offset) || + !CBB_add_u24(cbb.get(), todo) || + !CBB_add_bytes(cbb.get(), CBS_data(&body), todo) || + !CBB_finish(cbb.get(), NULL, &frag_len)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return seal_error; + } + + ssl_do_msg_callback(ssl, 1 /* write */, SSL3_RT_HANDSHAKE, + MakeSpan(frag, frag_len)); + + if (!dtls_seal_record(ssl, out, out_len, max_out, SSL3_RT_HANDSHAKE, + out + prefix, frag_len, use_epoch)) { + return seal_error; + } + + if (todo == CBS_len(&body)) { + // The next message is complete. + ssl->d1->outgoing_offset = 0; + return seal_success; + } + + ssl->d1->outgoing_offset += todo; + return seal_partial; +} + +// seal_next_packet writes as much of the next flight as possible to |out| and +// advances |ssl->d1->outgoing_written| and |ssl->d1->outgoing_offset| as +// appropriate. +static bool seal_next_packet(SSL *ssl, uint8_t *out, size_t *out_len, + size_t max_out) { + bool made_progress = false; + size_t total = 0; + assert(ssl->d1->outgoing_written < ssl->d1->outgoing_messages_len); + for (; ssl->d1->outgoing_written < ssl->d1->outgoing_messages_len; + ssl->d1->outgoing_written++) { + const DTLS_OUTGOING_MESSAGE *msg = + &ssl->d1->outgoing_messages[ssl->d1->outgoing_written]; + size_t len; + enum seal_result_t ret = seal_next_message(ssl, out, &len, max_out, msg); + switch (ret) { + case seal_error: + return false; + + case seal_no_progress: + goto packet_full; + + case seal_partial: + case seal_success: + out += len; + max_out -= len; + total += len; + made_progress = true; + + if (ret == seal_partial) { + goto packet_full; + } + break; + } + } + +packet_full: + // The MTU was too small to make any progress. + if (!made_progress) { + OPENSSL_PUT_ERROR(SSL, SSL_R_MTU_TOO_SMALL); + return false; + } + + *out_len = total; + return true; +} + +static int send_flight(SSL *ssl) { + if (ssl->s3->write_shutdown != ssl_shutdown_none) { + OPENSSL_PUT_ERROR(SSL, SSL_R_PROTOCOL_IS_SHUTDOWN); + return -1; + } + + dtls1_update_mtu(ssl); + + int ret = -1; + uint8_t *packet = (uint8_t *)OPENSSL_malloc(ssl->d1->mtu); + if (packet == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + goto err; + } + + while (ssl->d1->outgoing_written < ssl->d1->outgoing_messages_len) { + uint8_t old_written = ssl->d1->outgoing_written; + uint32_t old_offset = ssl->d1->outgoing_offset; + + size_t packet_len; + if (!seal_next_packet(ssl, packet, &packet_len, ssl->d1->mtu)) { + goto err; + } + + int bio_ret = BIO_write(ssl->wbio, packet, packet_len); + if (bio_ret <= 0) { + // Retry this packet the next time around. + ssl->d1->outgoing_written = old_written; + ssl->d1->outgoing_offset = old_offset; + ssl->s3->rwstate = SSL_WRITING; + ret = bio_ret; + goto err; + } + } + + if (BIO_flush(ssl->wbio) <= 0) { + ssl->s3->rwstate = SSL_WRITING; + goto err; + } + + ret = 1; + +err: + OPENSSL_free(packet); + return ret; +} + +int dtls1_flush_flight(SSL *ssl) { + ssl->d1->outgoing_messages_complete = true; + // Start the retransmission timer for the next flight (if any). + dtls1_start_timer(ssl); + return send_flight(ssl); +} + +int dtls1_retransmit_outgoing_messages(SSL *ssl) { + // Rewind to the start of the flight and write it again. + // + // TODO(davidben): This does not allow retransmits to be resumed on + // non-blocking write. + ssl->d1->outgoing_written = 0; + ssl->d1->outgoing_offset = 0; + + return send_flight(ssl); +} + +unsigned int dtls1_min_mtu(void) { + return kMinMTU; +} + +} // namespace bssl diff --git a/FoodApp/Pods/BoringSSL-GRPC/ssl/d1_lib.cc b/FoodApp/Pods/BoringSSL-GRPC/ssl/d1_lib.cc new file mode 100644 index 0000000..2c3e642 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/ssl/d1_lib.cc @@ -0,0 +1,267 @@ +/* + * 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 +#include +#include + +#include +#include +#include + +#include "../crypto/internal.h" +#include "internal.h" + + +namespace bssl { + +// DTLS1_MTU_TIMEOUTS is the maximum number of timeouts to expire +// before starting to decrease the MTU. +#define DTLS1_MTU_TIMEOUTS 2 + +// DTLS1_MAX_TIMEOUTS is the maximum number of timeouts to expire +// before failing the DTLS handshake. +#define DTLS1_MAX_TIMEOUTS 12 + +DTLS1_STATE::DTLS1_STATE() + : has_change_cipher_spec(false), + outgoing_messages_complete(false), + flight_has_reply(false) {} + +DTLS1_STATE::~DTLS1_STATE() {} + +bool dtls1_new(SSL *ssl) { + if (!ssl3_new(ssl)) { + return false; + } + UniquePtr d1 = MakeUnique(); + if (!d1) { + ssl3_free(ssl); + return false; + } + + ssl->d1 = d1.release(); + + // Set the version to the highest supported version. + // + // TODO(davidben): Move this field into |s3|, have it store the normalized + // protocol version, and implement this pre-negotiation quirk in |SSL_version| + // at the API boundary rather than in internal state. + ssl->version = DTLS1_2_VERSION; + return true; +} + +void dtls1_free(SSL *ssl) { + ssl3_free(ssl); + + if (ssl == NULL) { + return; + } + + Delete(ssl->d1); + ssl->d1 = NULL; +} + +void dtls1_start_timer(SSL *ssl) { + // If timer is not set, initialize duration (by default, 1 second) + if (ssl->d1->next_timeout.tv_sec == 0 && ssl->d1->next_timeout.tv_usec == 0) { + ssl->d1->timeout_duration_ms = ssl->initial_timeout_duration_ms; + } + + // Set timeout to current time + ssl_get_current_time(ssl, &ssl->d1->next_timeout); + + // Add duration to current time + ssl->d1->next_timeout.tv_sec += ssl->d1->timeout_duration_ms / 1000; + ssl->d1->next_timeout.tv_usec += (ssl->d1->timeout_duration_ms % 1000) * 1000; + if (ssl->d1->next_timeout.tv_usec >= 1000000) { + ssl->d1->next_timeout.tv_sec++; + ssl->d1->next_timeout.tv_usec -= 1000000; + } +} + +bool dtls1_is_timer_expired(SSL *ssl) { + struct timeval timeleft; + + // Get time left until timeout, return false if no timer running + if (!DTLSv1_get_timeout(ssl, &timeleft)) { + return false; + } + + // Return false if timer is not expired yet + if (timeleft.tv_sec > 0 || timeleft.tv_usec > 0) { + return false; + } + + // Timer expired, so return true + return true; +} + +static void dtls1_double_timeout(SSL *ssl) { + ssl->d1->timeout_duration_ms *= 2; + if (ssl->d1->timeout_duration_ms > 60000) { + ssl->d1->timeout_duration_ms = 60000; + } +} + +void dtls1_stop_timer(SSL *ssl) { + ssl->d1->num_timeouts = 0; + OPENSSL_memset(&ssl->d1->next_timeout, 0, sizeof(ssl->d1->next_timeout)); + ssl->d1->timeout_duration_ms = ssl->initial_timeout_duration_ms; +} + +bool dtls1_check_timeout_num(SSL *ssl) { + ssl->d1->num_timeouts++; + + // Reduce MTU after 2 unsuccessful retransmissions + if (ssl->d1->num_timeouts > DTLS1_MTU_TIMEOUTS && + !(SSL_get_options(ssl) & SSL_OP_NO_QUERY_MTU)) { + long mtu = BIO_ctrl(ssl->wbio, BIO_CTRL_DGRAM_GET_FALLBACK_MTU, 0, NULL); + if (mtu >= 0 && mtu <= (1 << 30) && (unsigned)mtu >= dtls1_min_mtu()) { + ssl->d1->mtu = (unsigned)mtu; + } + } + + if (ssl->d1->num_timeouts > DTLS1_MAX_TIMEOUTS) { + // fail the connection, enough alerts have been sent + OPENSSL_PUT_ERROR(SSL, SSL_R_READ_TIMEOUT_EXPIRED); + return false; + } + + return true; +} + +} // namespace bssl + +using namespace bssl; + +void DTLSv1_set_initial_timeout_duration(SSL *ssl, unsigned int duration_ms) { + ssl->initial_timeout_duration_ms = duration_ms; +} + +int DTLSv1_get_timeout(const SSL *ssl, struct timeval *out) { + if (!SSL_is_dtls(ssl)) { + return 0; + } + + // If no timeout is set, just return 0. + if (ssl->d1->next_timeout.tv_sec == 0 && ssl->d1->next_timeout.tv_usec == 0) { + return 0; + } + + struct OPENSSL_timeval timenow; + ssl_get_current_time(ssl, &timenow); + + // If timer already expired, set remaining time to 0. + if (ssl->d1->next_timeout.tv_sec < timenow.tv_sec || + (ssl->d1->next_timeout.tv_sec == timenow.tv_sec && + ssl->d1->next_timeout.tv_usec <= timenow.tv_usec)) { + OPENSSL_memset(out, 0, sizeof(*out)); + return 1; + } + + // Calculate time left until timer expires. + struct OPENSSL_timeval ret; + OPENSSL_memcpy(&ret, &ssl->d1->next_timeout, sizeof(ret)); + ret.tv_sec -= timenow.tv_sec; + if (ret.tv_usec >= timenow.tv_usec) { + ret.tv_usec -= timenow.tv_usec; + } else { + ret.tv_usec = 1000000 + ret.tv_usec - timenow.tv_usec; + ret.tv_sec--; + } + + // If remaining time is less than 15 ms, set it to 0 to prevent issues + // because of small divergences with socket timeouts. + if (ret.tv_sec == 0 && ret.tv_usec < 15000) { + OPENSSL_memset(&ret, 0, sizeof(ret)); + } + + // Clamp the result in case of overflow. + if (ret.tv_sec > INT_MAX) { + assert(0); + out->tv_sec = INT_MAX; + } else { + out->tv_sec = ret.tv_sec; + } + + out->tv_usec = ret.tv_usec; + return 1; +} + +int DTLSv1_handle_timeout(SSL *ssl) { + ssl_reset_error_state(ssl); + + if (!SSL_is_dtls(ssl)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return -1; + } + + // If no timer is expired, don't do anything. + if (!dtls1_is_timer_expired(ssl)) { + return 0; + } + + if (!dtls1_check_timeout_num(ssl)) { + return -1; + } + + dtls1_double_timeout(ssl); + dtls1_start_timer(ssl); + return dtls1_retransmit_outgoing_messages(ssl); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/ssl/d1_lib.cc.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/ssl/d1_lib.cc.grpc_back new file mode 100644 index 0000000..eff06ee --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/ssl/d1_lib.cc.grpc_back @@ -0,0 +1,267 @@ +/* + * 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 +#include +#include + +#include +#include +#include + +#include "../crypto/internal.h" +#include "internal.h" + + +namespace bssl { + +// DTLS1_MTU_TIMEOUTS is the maximum number of timeouts to expire +// before starting to decrease the MTU. +#define DTLS1_MTU_TIMEOUTS 2 + +// DTLS1_MAX_TIMEOUTS is the maximum number of timeouts to expire +// before failing the DTLS handshake. +#define DTLS1_MAX_TIMEOUTS 12 + +DTLS1_STATE::DTLS1_STATE() + : has_change_cipher_spec(false), + outgoing_messages_complete(false), + flight_has_reply(false) {} + +DTLS1_STATE::~DTLS1_STATE() {} + +bool dtls1_new(SSL *ssl) { + if (!ssl3_new(ssl)) { + return false; + } + UniquePtr d1 = MakeUnique(); + if (!d1) { + ssl3_free(ssl); + return false; + } + + ssl->d1 = d1.release(); + + // Set the version to the highest supported version. + // + // TODO(davidben): Move this field into |s3|, have it store the normalized + // protocol version, and implement this pre-negotiation quirk in |SSL_version| + // at the API boundary rather than in internal state. + ssl->version = DTLS1_2_VERSION; + return true; +} + +void dtls1_free(SSL *ssl) { + ssl3_free(ssl); + + if (ssl == NULL) { + return; + } + + Delete(ssl->d1); + ssl->d1 = NULL; +} + +void dtls1_start_timer(SSL *ssl) { + // If timer is not set, initialize duration (by default, 1 second) + if (ssl->d1->next_timeout.tv_sec == 0 && ssl->d1->next_timeout.tv_usec == 0) { + ssl->d1->timeout_duration_ms = ssl->initial_timeout_duration_ms; + } + + // Set timeout to current time + ssl_get_current_time(ssl, &ssl->d1->next_timeout); + + // Add duration to current time + ssl->d1->next_timeout.tv_sec += ssl->d1->timeout_duration_ms / 1000; + ssl->d1->next_timeout.tv_usec += (ssl->d1->timeout_duration_ms % 1000) * 1000; + if (ssl->d1->next_timeout.tv_usec >= 1000000) { + ssl->d1->next_timeout.tv_sec++; + ssl->d1->next_timeout.tv_usec -= 1000000; + } +} + +bool dtls1_is_timer_expired(SSL *ssl) { + struct timeval timeleft; + + // Get time left until timeout, return false if no timer running + if (!DTLSv1_get_timeout(ssl, &timeleft)) { + return false; + } + + // Return false if timer is not expired yet + if (timeleft.tv_sec > 0 || timeleft.tv_usec > 0) { + return false; + } + + // Timer expired, so return true + return true; +} + +static void dtls1_double_timeout(SSL *ssl) { + ssl->d1->timeout_duration_ms *= 2; + if (ssl->d1->timeout_duration_ms > 60000) { + ssl->d1->timeout_duration_ms = 60000; + } +} + +void dtls1_stop_timer(SSL *ssl) { + ssl->d1->num_timeouts = 0; + OPENSSL_memset(&ssl->d1->next_timeout, 0, sizeof(ssl->d1->next_timeout)); + ssl->d1->timeout_duration_ms = ssl->initial_timeout_duration_ms; +} + +bool dtls1_check_timeout_num(SSL *ssl) { + ssl->d1->num_timeouts++; + + // Reduce MTU after 2 unsuccessful retransmissions + if (ssl->d1->num_timeouts > DTLS1_MTU_TIMEOUTS && + !(SSL_get_options(ssl) & SSL_OP_NO_QUERY_MTU)) { + long mtu = BIO_ctrl(ssl->wbio, BIO_CTRL_DGRAM_GET_FALLBACK_MTU, 0, NULL); + if (mtu >= 0 && mtu <= (1 << 30) && (unsigned)mtu >= dtls1_min_mtu()) { + ssl->d1->mtu = (unsigned)mtu; + } + } + + if (ssl->d1->num_timeouts > DTLS1_MAX_TIMEOUTS) { + // fail the connection, enough alerts have been sent + OPENSSL_PUT_ERROR(SSL, SSL_R_READ_TIMEOUT_EXPIRED); + return false; + } + + return true; +} + +} // namespace bssl + +using namespace bssl; + +void DTLSv1_set_initial_timeout_duration(SSL *ssl, unsigned int duration_ms) { + ssl->initial_timeout_duration_ms = duration_ms; +} + +int DTLSv1_get_timeout(const SSL *ssl, struct timeval *out) { + if (!SSL_is_dtls(ssl)) { + return 0; + } + + // If no timeout is set, just return 0. + if (ssl->d1->next_timeout.tv_sec == 0 && ssl->d1->next_timeout.tv_usec == 0) { + return 0; + } + + struct OPENSSL_timeval timenow; + ssl_get_current_time(ssl, &timenow); + + // If timer already expired, set remaining time to 0. + if (ssl->d1->next_timeout.tv_sec < timenow.tv_sec || + (ssl->d1->next_timeout.tv_sec == timenow.tv_sec && + ssl->d1->next_timeout.tv_usec <= timenow.tv_usec)) { + OPENSSL_memset(out, 0, sizeof(*out)); + return 1; + } + + // Calculate time left until timer expires. + struct OPENSSL_timeval ret; + OPENSSL_memcpy(&ret, &ssl->d1->next_timeout, sizeof(ret)); + ret.tv_sec -= timenow.tv_sec; + if (ret.tv_usec >= timenow.tv_usec) { + ret.tv_usec -= timenow.tv_usec; + } else { + ret.tv_usec = 1000000 + ret.tv_usec - timenow.tv_usec; + ret.tv_sec--; + } + + // If remaining time is less than 15 ms, set it to 0 to prevent issues + // because of small divergences with socket timeouts. + if (ret.tv_sec == 0 && ret.tv_usec < 15000) { + OPENSSL_memset(&ret, 0, sizeof(ret)); + } + + // Clamp the result in case of overflow. + if (ret.tv_sec > INT_MAX) { + assert(0); + out->tv_sec = INT_MAX; + } else { + out->tv_sec = ret.tv_sec; + } + + out->tv_usec = ret.tv_usec; + return 1; +} + +int DTLSv1_handle_timeout(SSL *ssl) { + ssl_reset_error_state(ssl); + + if (!SSL_is_dtls(ssl)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return -1; + } + + // If no timer is expired, don't do anything. + if (!dtls1_is_timer_expired(ssl)) { + return 0; + } + + if (!dtls1_check_timeout_num(ssl)) { + return -1; + } + + dtls1_double_timeout(ssl); + dtls1_start_timer(ssl); + return dtls1_retransmit_outgoing_messages(ssl); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/ssl/d1_pkt.cc b/FoodApp/Pods/BoringSSL-GRPC/ssl/d1_pkt.cc new file mode 100644 index 0000000..8fef21f --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/ssl/d1_pkt.cc @@ -0,0 +1,274 @@ +/* DTLS implementation written by Nagendra Modadugu + * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. */ +/* ==================================================================== + * 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 (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 +#include +#include +#include +#include +#include + +#include "../crypto/internal.h" +#include "internal.h" + + +namespace bssl { + +ssl_open_record_t dtls1_open_app_data(SSL *ssl, Span *out, + size_t *out_consumed, uint8_t *out_alert, + Span in) { + assert(!SSL_in_init(ssl)); + + uint8_t type; + Span record; + auto ret = dtls_open_record(ssl, &type, &record, out_consumed, out_alert, in); + if (ret != ssl_open_record_success) { + return ret; + } + + if (type == SSL3_RT_HANDSHAKE) { + // Parse the first fragment header to determine if this is a pre-CCS or + // post-CCS handshake record. DTLS resets handshake message numbers on each + // handshake, so renegotiations and retransmissions are ambiguous. + CBS cbs, body; + struct hm_header_st msg_hdr; + CBS_init(&cbs, record.data(), record.size()); + if (!dtls1_parse_fragment(&cbs, &msg_hdr, &body)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_HANDSHAKE_RECORD); + *out_alert = SSL_AD_DECODE_ERROR; + return ssl_open_record_error; + } + + if (msg_hdr.type == SSL3_MT_FINISHED && + msg_hdr.seq == ssl->d1->handshake_read_seq - 1) { + if (msg_hdr.frag_off == 0) { + // Retransmit our last flight of messages. If the peer sends the second + // Finished, they may not have received ours. Only do this for the + // first fragment, in case the Finished was fragmented. + if (!dtls1_check_timeout_num(ssl)) { + *out_alert = 0; // TODO(davidben): Send an alert? + return ssl_open_record_error; + } + + dtls1_retransmit_outgoing_messages(ssl); + } + return ssl_open_record_discard; + } + + // Otherwise, this is a pre-CCS handshake message from an unsupported + // renegotiation attempt. Fall through to the error path. + } + + if (type != SSL3_RT_APPLICATION_DATA) { + OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_RECORD); + *out_alert = SSL_AD_UNEXPECTED_MESSAGE; + return ssl_open_record_error; + } + + if (record.empty()) { + return ssl_open_record_discard; + } + + *out = record; + return ssl_open_record_success; +} + +int dtls1_write_app_data(SSL *ssl, bool *out_needs_handshake, const uint8_t *in, + int len) { + assert(!SSL_in_init(ssl)); + *out_needs_handshake = false; + + if (ssl->s3->write_shutdown != ssl_shutdown_none) { + OPENSSL_PUT_ERROR(SSL, SSL_R_PROTOCOL_IS_SHUTDOWN); + return -1; + } + + if (len > SSL3_RT_MAX_PLAIN_LENGTH) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DTLS_MESSAGE_TOO_BIG); + return -1; + } + + if (len < 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_LENGTH); + return -1; + } + + if (len == 0) { + return 0; + } + + int ret = dtls1_write_record(ssl, SSL3_RT_APPLICATION_DATA, in, (size_t)len, + dtls1_use_current_epoch); + if (ret <= 0) { + return ret; + } + return len; +} + +int dtls1_write_record(SSL *ssl, int type, const uint8_t *in, size_t len, + enum dtls1_use_epoch_t use_epoch) { + SSLBuffer *buf = &ssl->s3->write_buffer; + assert(len <= SSL3_RT_MAX_PLAIN_LENGTH); + // There should never be a pending write buffer in DTLS. One can't write half + // a datagram, so the write buffer is always dropped in + // |ssl_write_buffer_flush|. + assert(buf->empty()); + + if (len > SSL3_RT_MAX_PLAIN_LENGTH) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return -1; + } + + size_t ciphertext_len; + if (!buf->EnsureCap(ssl_seal_align_prefix_len(ssl), + len + SSL_max_seal_overhead(ssl)) || + !dtls_seal_record(ssl, buf->remaining().data(), &ciphertext_len, + buf->remaining().size(), type, in, len, use_epoch)) { + buf->Clear(); + return -1; + } + buf->DidWrite(ciphertext_len); + + int ret = ssl_write_buffer_flush(ssl); + if (ret <= 0) { + return ret; + } + return 1; +} + +int dtls1_dispatch_alert(SSL *ssl) { + int ret = dtls1_write_record(ssl, SSL3_RT_ALERT, &ssl->s3->send_alert[0], 2, + dtls1_use_current_epoch); + if (ret <= 0) { + return ret; + } + ssl->s3->alert_dispatch = 0; + + // If the alert is fatal, flush the BIO now. + if (ssl->s3->send_alert[0] == SSL3_AL_FATAL) { + BIO_flush(ssl->wbio); + } + + ssl_do_msg_callback(ssl, 1 /* write */, SSL3_RT_ALERT, ssl->s3->send_alert); + + int alert = (ssl->s3->send_alert[0] << 8) | ssl->s3->send_alert[1]; + ssl_do_info_callback(ssl, SSL_CB_WRITE_ALERT, alert); + + return 1; +} + +} // namespace bssl diff --git a/FoodApp/Pods/BoringSSL-GRPC/ssl/d1_pkt.cc.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/ssl/d1_pkt.cc.grpc_back new file mode 100644 index 0000000..d29a5c2 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/ssl/d1_pkt.cc.grpc_back @@ -0,0 +1,274 @@ +/* DTLS implementation written by Nagendra Modadugu + * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. */ +/* ==================================================================== + * 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 (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 +#include +#include +#include +#include +#include + +#include "../crypto/internal.h" +#include "internal.h" + + +namespace bssl { + +ssl_open_record_t dtls1_open_app_data(SSL *ssl, Span *out, + size_t *out_consumed, uint8_t *out_alert, + Span in) { + assert(!SSL_in_init(ssl)); + + uint8_t type; + Span record; + auto ret = dtls_open_record(ssl, &type, &record, out_consumed, out_alert, in); + if (ret != ssl_open_record_success) { + return ret; + } + + if (type == SSL3_RT_HANDSHAKE) { + // Parse the first fragment header to determine if this is a pre-CCS or + // post-CCS handshake record. DTLS resets handshake message numbers on each + // handshake, so renegotiations and retransmissions are ambiguous. + CBS cbs, body; + struct hm_header_st msg_hdr; + CBS_init(&cbs, record.data(), record.size()); + if (!dtls1_parse_fragment(&cbs, &msg_hdr, &body)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_HANDSHAKE_RECORD); + *out_alert = SSL_AD_DECODE_ERROR; + return ssl_open_record_error; + } + + if (msg_hdr.type == SSL3_MT_FINISHED && + msg_hdr.seq == ssl->d1->handshake_read_seq - 1) { + if (msg_hdr.frag_off == 0) { + // Retransmit our last flight of messages. If the peer sends the second + // Finished, they may not have received ours. Only do this for the + // first fragment, in case the Finished was fragmented. + if (!dtls1_check_timeout_num(ssl)) { + *out_alert = 0; // TODO(davidben): Send an alert? + return ssl_open_record_error; + } + + dtls1_retransmit_outgoing_messages(ssl); + } + return ssl_open_record_discard; + } + + // Otherwise, this is a pre-CCS handshake message from an unsupported + // renegotiation attempt. Fall through to the error path. + } + + if (type != SSL3_RT_APPLICATION_DATA) { + OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_RECORD); + *out_alert = SSL_AD_UNEXPECTED_MESSAGE; + return ssl_open_record_error; + } + + if (record.empty()) { + return ssl_open_record_discard; + } + + *out = record; + return ssl_open_record_success; +} + +int dtls1_write_app_data(SSL *ssl, bool *out_needs_handshake, const uint8_t *in, + int len) { + assert(!SSL_in_init(ssl)); + *out_needs_handshake = false; + + if (ssl->s3->write_shutdown != ssl_shutdown_none) { + OPENSSL_PUT_ERROR(SSL, SSL_R_PROTOCOL_IS_SHUTDOWN); + return -1; + } + + if (len > SSL3_RT_MAX_PLAIN_LENGTH) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DTLS_MESSAGE_TOO_BIG); + return -1; + } + + if (len < 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_LENGTH); + return -1; + } + + if (len == 0) { + return 0; + } + + int ret = dtls1_write_record(ssl, SSL3_RT_APPLICATION_DATA, in, (size_t)len, + dtls1_use_current_epoch); + if (ret <= 0) { + return ret; + } + return len; +} + +int dtls1_write_record(SSL *ssl, int type, const uint8_t *in, size_t len, + enum dtls1_use_epoch_t use_epoch) { + SSLBuffer *buf = &ssl->s3->write_buffer; + assert(len <= SSL3_RT_MAX_PLAIN_LENGTH); + // There should never be a pending write buffer in DTLS. One can't write half + // a datagram, so the write buffer is always dropped in + // |ssl_write_buffer_flush|. + assert(buf->empty()); + + if (len > SSL3_RT_MAX_PLAIN_LENGTH) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return -1; + } + + size_t ciphertext_len; + if (!buf->EnsureCap(ssl_seal_align_prefix_len(ssl), + len + SSL_max_seal_overhead(ssl)) || + !dtls_seal_record(ssl, buf->remaining().data(), &ciphertext_len, + buf->remaining().size(), type, in, len, use_epoch)) { + buf->Clear(); + return -1; + } + buf->DidWrite(ciphertext_len); + + int ret = ssl_write_buffer_flush(ssl); + if (ret <= 0) { + return ret; + } + return 1; +} + +int dtls1_dispatch_alert(SSL *ssl) { + int ret = dtls1_write_record(ssl, SSL3_RT_ALERT, &ssl->s3->send_alert[0], 2, + dtls1_use_current_epoch); + if (ret <= 0) { + return ret; + } + ssl->s3->alert_dispatch = 0; + + // If the alert is fatal, flush the BIO now. + if (ssl->s3->send_alert[0] == SSL3_AL_FATAL) { + BIO_flush(ssl->wbio); + } + + ssl_do_msg_callback(ssl, 1 /* write */, SSL3_RT_ALERT, ssl->s3->send_alert); + + int alert = (ssl->s3->send_alert[0] << 8) | ssl->s3->send_alert[1]; + ssl_do_info_callback(ssl, SSL_CB_WRITE_ALERT, alert); + + return 1; +} + +} // namespace bssl diff --git a/FoodApp/Pods/BoringSSL-GRPC/ssl/d1_srtp.cc b/FoodApp/Pods/BoringSSL-GRPC/ssl/d1_srtp.cc new file mode 100644 index 0000000..5015e6f --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/ssl/d1_srtp.cc @@ -0,0 +1,232 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 + +#include +#include + +#include "internal.h" + + +using namespace bssl; + +static const SRTP_PROTECTION_PROFILE kSRTPProfiles[] = { + { + "SRTP_AES128_CM_SHA1_80", SRTP_AES128_CM_SHA1_80, + }, + { + "SRTP_AES128_CM_SHA1_32", SRTP_AES128_CM_SHA1_32, + }, + { + "SRTP_AEAD_AES_128_GCM", SRTP_AEAD_AES_128_GCM, + }, + { + "SRTP_AEAD_AES_256_GCM", SRTP_AEAD_AES_256_GCM, + }, + {0, 0}, +}; + +static int find_profile_by_name(const char *profile_name, + const SRTP_PROTECTION_PROFILE **pptr, + size_t len) { + const SRTP_PROTECTION_PROFILE *p = kSRTPProfiles; + while (p->name) { + if (len == strlen(p->name) && !strncmp(p->name, profile_name, len)) { + *pptr = p; + return 1; + } + + p++; + } + + return 0; +} + +static int ssl_ctx_make_profiles(const char *profiles_string, + STACK_OF(SRTP_PROTECTION_PROFILE) **out) { + UniquePtr profiles( + sk_SRTP_PROTECTION_PROFILE_new_null()); + if (profiles == nullptr) { + OPENSSL_PUT_ERROR(SSL, SSL_R_SRTP_COULD_NOT_ALLOCATE_PROFILES); + return 0; + } + + const char *col; + const char *ptr = profiles_string; + do { + col = strchr(ptr, ':'); + + const SRTP_PROTECTION_PROFILE *profile; + if (!find_profile_by_name(ptr, &profile, + col ? (size_t)(col - ptr) : strlen(ptr))) { + OPENSSL_PUT_ERROR(SSL, SSL_R_SRTP_UNKNOWN_PROTECTION_PROFILE); + return 0; + } + + if (!sk_SRTP_PROTECTION_PROFILE_push(profiles.get(), profile)) { + return 0; + } + + if (col) { + ptr = col + 1; + } + } while (col); + + sk_SRTP_PROTECTION_PROFILE_free(*out); + *out = profiles.release(); + return 1; +} + +int SSL_CTX_set_srtp_profiles(SSL_CTX *ctx, const char *profiles) { + return ssl_ctx_make_profiles(profiles, &ctx->srtp_profiles); +} + +int SSL_set_srtp_profiles(SSL *ssl, const char *profiles) { + return ssl_ctx_make_profiles(profiles, &ssl->srtp_profiles); +} + +STACK_OF(SRTP_PROTECTION_PROFILE) *SSL_get_srtp_profiles(SSL *ssl) { + if (ssl == NULL) { + return NULL; + } + + if (ssl->srtp_profiles != NULL) { + return ssl->srtp_profiles; + } + + if (ssl->ctx->srtp_profiles != NULL) { + return ssl->ctx->srtp_profiles; + } + + return NULL; +} + +const SRTP_PROTECTION_PROFILE *SSL_get_selected_srtp_profile(SSL *ssl) { + return ssl->srtp_profile; +} + +int SSL_CTX_set_tlsext_use_srtp(SSL_CTX *ctx, const char *profiles) { + // This API inverts its return value. + return !SSL_CTX_set_srtp_profiles(ctx, profiles); +} + +int SSL_set_tlsext_use_srtp(SSL *ssl, const char *profiles) { + // This API inverts its return value. + return !SSL_set_srtp_profiles(ssl, profiles); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/ssl/d1_srtp.cc.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/ssl/d1_srtp.cc.grpc_back new file mode 100644 index 0000000..1a8e084 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/ssl/d1_srtp.cc.grpc_back @@ -0,0 +1,232 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 + +#include +#include + +#include "internal.h" + + +using namespace bssl; + +static const SRTP_PROTECTION_PROFILE kSRTPProfiles[] = { + { + "SRTP_AES128_CM_SHA1_80", SRTP_AES128_CM_SHA1_80, + }, + { + "SRTP_AES128_CM_SHA1_32", SRTP_AES128_CM_SHA1_32, + }, + { + "SRTP_AEAD_AES_128_GCM", SRTP_AEAD_AES_128_GCM, + }, + { + "SRTP_AEAD_AES_256_GCM", SRTP_AEAD_AES_256_GCM, + }, + {0, 0}, +}; + +static int find_profile_by_name(const char *profile_name, + const SRTP_PROTECTION_PROFILE **pptr, + size_t len) { + const SRTP_PROTECTION_PROFILE *p = kSRTPProfiles; + while (p->name) { + if (len == strlen(p->name) && !strncmp(p->name, profile_name, len)) { + *pptr = p; + return 1; + } + + p++; + } + + return 0; +} + +static int ssl_ctx_make_profiles(const char *profiles_string, + STACK_OF(SRTP_PROTECTION_PROFILE) **out) { + UniquePtr profiles( + sk_SRTP_PROTECTION_PROFILE_new_null()); + if (profiles == nullptr) { + OPENSSL_PUT_ERROR(SSL, SSL_R_SRTP_COULD_NOT_ALLOCATE_PROFILES); + return 0; + } + + const char *col; + const char *ptr = profiles_string; + do { + col = strchr(ptr, ':'); + + const SRTP_PROTECTION_PROFILE *profile; + if (!find_profile_by_name(ptr, &profile, + col ? (size_t)(col - ptr) : strlen(ptr))) { + OPENSSL_PUT_ERROR(SSL, SSL_R_SRTP_UNKNOWN_PROTECTION_PROFILE); + return 0; + } + + if (!sk_SRTP_PROTECTION_PROFILE_push(profiles.get(), profile)) { + return 0; + } + + if (col) { + ptr = col + 1; + } + } while (col); + + sk_SRTP_PROTECTION_PROFILE_free(*out); + *out = profiles.release(); + return 1; +} + +int SSL_CTX_set_srtp_profiles(SSL_CTX *ctx, const char *profiles) { + return ssl_ctx_make_profiles(profiles, &ctx->srtp_profiles); +} + +int SSL_set_srtp_profiles(SSL *ssl, const char *profiles) { + return ssl_ctx_make_profiles(profiles, &ssl->srtp_profiles); +} + +STACK_OF(SRTP_PROTECTION_PROFILE) *SSL_get_srtp_profiles(SSL *ssl) { + if (ssl == NULL) { + return NULL; + } + + if (ssl->srtp_profiles != NULL) { + return ssl->srtp_profiles; + } + + if (ssl->ctx->srtp_profiles != NULL) { + return ssl->ctx->srtp_profiles; + } + + return NULL; +} + +const SRTP_PROTECTION_PROFILE *SSL_get_selected_srtp_profile(SSL *ssl) { + return ssl->srtp_profile; +} + +int SSL_CTX_set_tlsext_use_srtp(SSL_CTX *ctx, const char *profiles) { + // This API inverts its return value. + return !SSL_CTX_set_srtp_profiles(ctx, profiles); +} + +int SSL_set_tlsext_use_srtp(SSL *ssl, const char *profiles) { + // This API inverts its return value. + return !SSL_set_srtp_profiles(ssl, profiles); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/ssl/dtls_method.cc b/FoodApp/Pods/BoringSSL-GRPC/ssl/dtls_method.cc new file mode 100644 index 0000000..0294928 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/ssl/dtls_method.cc @@ -0,0 +1,193 @@ +/* + * 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 +#include + +#include +#include + +#include "../crypto/internal.h" +#include "internal.h" + + +using namespace bssl; + +static void dtls1_on_handshake_complete(SSL *ssl) { + // Stop the reply timer left by the last flight we sent. + dtls1_stop_timer(ssl); + // If the final flight had a reply, we know the peer has received it. If not, + // we must leave the flight around for post-handshake retransmission. + if (ssl->d1->flight_has_reply) { + dtls_clear_outgoing_messages(ssl); + } +} + +static bool dtls1_set_read_state(SSL *ssl, UniquePtr aead_ctx) { + // Cipher changes are forbidden if the current epoch has leftover data. + if (dtls_has_unprocessed_handshake_data(ssl)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_BUFFERED_MESSAGES_ON_CIPHER_CHANGE); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE); + return false; + } + + ssl->d1->r_epoch++; + OPENSSL_memset(&ssl->d1->bitmap, 0, sizeof(ssl->d1->bitmap)); + OPENSSL_memset(ssl->s3->read_sequence, 0, sizeof(ssl->s3->read_sequence)); + + ssl->s3->aead_read_ctx = std::move(aead_ctx); + return true; +} + +static bool dtls1_set_write_state(SSL *ssl, + UniquePtr aead_ctx) { + ssl->d1->w_epoch++; + OPENSSL_memcpy(ssl->d1->last_write_sequence, ssl->s3->write_sequence, + sizeof(ssl->s3->write_sequence)); + OPENSSL_memset(ssl->s3->write_sequence, 0, sizeof(ssl->s3->write_sequence)); + + ssl->d1->last_aead_write_ctx = std::move(ssl->s3->aead_write_ctx); + ssl->s3->aead_write_ctx = std::move(aead_ctx); + return true; +} + +static const SSL_PROTOCOL_METHOD kDTLSProtocolMethod = { + true /* is_dtls */, + dtls1_new, + dtls1_free, + dtls1_get_message, + dtls1_next_message, + dtls1_open_handshake, + dtls1_open_change_cipher_spec, + dtls1_open_app_data, + dtls1_write_app_data, + dtls1_dispatch_alert, + dtls1_init_message, + dtls1_finish_message, + dtls1_add_message, + dtls1_add_change_cipher_spec, + dtls1_add_alert, + dtls1_flush_flight, + dtls1_on_handshake_complete, + dtls1_set_read_state, + dtls1_set_write_state, +}; + +const SSL_METHOD *DTLS_method(void) { + static const SSL_METHOD kMethod = { + 0, + &kDTLSProtocolMethod, + &ssl_crypto_x509_method, + }; + return &kMethod; +} + +const SSL_METHOD *DTLS_with_buffers_method(void) { + static const SSL_METHOD kMethod = { + 0, + &kDTLSProtocolMethod, + &ssl_noop_x509_method, + }; + return &kMethod; +} + +// Legacy version-locked methods. + +const SSL_METHOD *DTLSv1_2_method(void) { + static const SSL_METHOD kMethod = { + DTLS1_2_VERSION, + &kDTLSProtocolMethod, + &ssl_crypto_x509_method, + }; + return &kMethod; +} + +const SSL_METHOD *DTLSv1_method(void) { + static const SSL_METHOD kMethod = { + DTLS1_VERSION, + &kDTLSProtocolMethod, + &ssl_crypto_x509_method, + }; + return &kMethod; +} + +// Legacy side-specific methods. + +const SSL_METHOD *DTLSv1_2_server_method(void) { + return DTLSv1_2_method(); +} + +const SSL_METHOD *DTLSv1_server_method(void) { + return DTLSv1_method(); +} + +const SSL_METHOD *DTLSv1_2_client_method(void) { + return DTLSv1_2_method(); +} + +const SSL_METHOD *DTLSv1_client_method(void) { + return DTLSv1_method(); +} + +const SSL_METHOD *DTLS_server_method(void) { + return DTLS_method(); +} + +const SSL_METHOD *DTLS_client_method(void) { + return DTLS_method(); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/ssl/dtls_method.cc.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/ssl/dtls_method.cc.grpc_back new file mode 100644 index 0000000..8d40edf --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/ssl/dtls_method.cc.grpc_back @@ -0,0 +1,193 @@ +/* + * 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 +#include + +#include +#include + +#include "../crypto/internal.h" +#include "internal.h" + + +using namespace bssl; + +static void dtls1_on_handshake_complete(SSL *ssl) { + // Stop the reply timer left by the last flight we sent. + dtls1_stop_timer(ssl); + // If the final flight had a reply, we know the peer has received it. If not, + // we must leave the flight around for post-handshake retransmission. + if (ssl->d1->flight_has_reply) { + dtls_clear_outgoing_messages(ssl); + } +} + +static bool dtls1_set_read_state(SSL *ssl, UniquePtr aead_ctx) { + // Cipher changes are forbidden if the current epoch has leftover data. + if (dtls_has_unprocessed_handshake_data(ssl)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_BUFFERED_MESSAGES_ON_CIPHER_CHANGE); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE); + return false; + } + + ssl->d1->r_epoch++; + OPENSSL_memset(&ssl->d1->bitmap, 0, sizeof(ssl->d1->bitmap)); + OPENSSL_memset(ssl->s3->read_sequence, 0, sizeof(ssl->s3->read_sequence)); + + ssl->s3->aead_read_ctx = std::move(aead_ctx); + return true; +} + +static bool dtls1_set_write_state(SSL *ssl, + UniquePtr aead_ctx) { + ssl->d1->w_epoch++; + OPENSSL_memcpy(ssl->d1->last_write_sequence, ssl->s3->write_sequence, + sizeof(ssl->s3->write_sequence)); + OPENSSL_memset(ssl->s3->write_sequence, 0, sizeof(ssl->s3->write_sequence)); + + ssl->d1->last_aead_write_ctx = std::move(ssl->s3->aead_write_ctx); + ssl->s3->aead_write_ctx = std::move(aead_ctx); + return true; +} + +static const SSL_PROTOCOL_METHOD kDTLSProtocolMethod = { + true /* is_dtls */, + dtls1_new, + dtls1_free, + dtls1_get_message, + dtls1_next_message, + dtls1_open_handshake, + dtls1_open_change_cipher_spec, + dtls1_open_app_data, + dtls1_write_app_data, + dtls1_dispatch_alert, + dtls1_init_message, + dtls1_finish_message, + dtls1_add_message, + dtls1_add_change_cipher_spec, + dtls1_add_alert, + dtls1_flush_flight, + dtls1_on_handshake_complete, + dtls1_set_read_state, + dtls1_set_write_state, +}; + +const SSL_METHOD *DTLS_method(void) { + static const SSL_METHOD kMethod = { + 0, + &kDTLSProtocolMethod, + &ssl_crypto_x509_method, + }; + return &kMethod; +} + +const SSL_METHOD *DTLS_with_buffers_method(void) { + static const SSL_METHOD kMethod = { + 0, + &kDTLSProtocolMethod, + &ssl_noop_x509_method, + }; + return &kMethod; +} + +// Legacy version-locked methods. + +const SSL_METHOD *DTLSv1_2_method(void) { + static const SSL_METHOD kMethod = { + DTLS1_2_VERSION, + &kDTLSProtocolMethod, + &ssl_crypto_x509_method, + }; + return &kMethod; +} + +const SSL_METHOD *DTLSv1_method(void) { + static const SSL_METHOD kMethod = { + DTLS1_VERSION, + &kDTLSProtocolMethod, + &ssl_crypto_x509_method, + }; + return &kMethod; +} + +// Legacy side-specific methods. + +const SSL_METHOD *DTLSv1_2_server_method(void) { + return DTLSv1_2_method(); +} + +const SSL_METHOD *DTLSv1_server_method(void) { + return DTLSv1_method(); +} + +const SSL_METHOD *DTLSv1_2_client_method(void) { + return DTLSv1_2_method(); +} + +const SSL_METHOD *DTLSv1_client_method(void) { + return DTLSv1_method(); +} + +const SSL_METHOD *DTLS_server_method(void) { + return DTLS_method(); +} + +const SSL_METHOD *DTLS_client_method(void) { + return DTLS_method(); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/ssl/dtls_record.cc b/FoodApp/Pods/BoringSSL-GRPC/ssl/dtls_record.cc new file mode 100644 index 0000000..007f4c6 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/ssl/dtls_record.cc @@ -0,0 +1,353 @@ +/* DTLS implementation written by Nagendra Modadugu + * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. */ +/* ==================================================================== + * 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 (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 + +#include "internal.h" +#include "../crypto/internal.h" + + +namespace bssl { + +// to_u64_be treats |in| as a 8-byte big-endian integer and returns the value as +// a |uint64_t|. +static uint64_t to_u64_be(const uint8_t in[8]) { + uint64_t ret = 0; + unsigned i; + for (i = 0; i < 8; i++) { + ret <<= 8; + ret |= in[i]; + } + return ret; +} + +// dtls1_bitmap_should_discard returns one if |seq_num| has been seen in +// |bitmap| or is stale. Otherwise it returns zero. +static int dtls1_bitmap_should_discard(DTLS1_BITMAP *bitmap, + const uint8_t seq_num[8]) { + const unsigned kWindowSize = sizeof(bitmap->map) * 8; + + uint64_t seq_num_u = to_u64_be(seq_num); + if (seq_num_u > bitmap->max_seq_num) { + return 0; + } + uint64_t idx = bitmap->max_seq_num - seq_num_u; + return idx >= kWindowSize || (bitmap->map & (((uint64_t)1) << idx)); +} + +// dtls1_bitmap_record updates |bitmap| to record receipt of sequence number +// |seq_num|. It slides the window forward if needed. It is an error to call +// this function on a stale sequence number. +static void dtls1_bitmap_record(DTLS1_BITMAP *bitmap, + const uint8_t seq_num[8]) { + const unsigned kWindowSize = sizeof(bitmap->map) * 8; + + uint64_t seq_num_u = to_u64_be(seq_num); + // Shift the window if necessary. + if (seq_num_u > bitmap->max_seq_num) { + uint64_t shift = seq_num_u - bitmap->max_seq_num; + if (shift >= kWindowSize) { + bitmap->map = 0; + } else { + bitmap->map <<= shift; + } + bitmap->max_seq_num = seq_num_u; + } + + uint64_t idx = bitmap->max_seq_num - seq_num_u; + if (idx < kWindowSize) { + bitmap->map |= ((uint64_t)1) << idx; + } +} + +enum ssl_open_record_t dtls_open_record(SSL *ssl, uint8_t *out_type, + Span *out, + size_t *out_consumed, + uint8_t *out_alert, Span in) { + *out_consumed = 0; + if (ssl->s3->read_shutdown == ssl_shutdown_close_notify) { + return ssl_open_record_close_notify; + } + + if (in.empty()) { + return ssl_open_record_partial; + } + + CBS cbs = CBS(in); + + // Decode the record. + uint8_t type; + uint16_t version; + uint8_t sequence[8]; + CBS body; + if (!CBS_get_u8(&cbs, &type) || + !CBS_get_u16(&cbs, &version) || + !CBS_copy_bytes(&cbs, sequence, 8) || + !CBS_get_u16_length_prefixed(&cbs, &body) || + CBS_len(&body) > SSL3_RT_MAX_ENCRYPTED_LENGTH) { + // The record header was incomplete or malformed. Drop the entire packet. + *out_consumed = in.size(); + return ssl_open_record_discard; + } + + bool version_ok; + if (ssl->s3->aead_read_ctx->is_null_cipher()) { + // Only check the first byte. Enforcing beyond that can prevent decoding + // version negotiation failure alerts. + version_ok = (version >> 8) == DTLS1_VERSION_MAJOR; + } else { + version_ok = version == ssl->s3->aead_read_ctx->RecordVersion(); + } + + if (!version_ok) { + // The record header was incomplete or malformed. Drop the entire packet. + *out_consumed = in.size(); + return ssl_open_record_discard; + } + + ssl_do_msg_callback(ssl, 0 /* read */, SSL3_RT_HEADER, + in.subspan(0, DTLS1_RT_HEADER_LENGTH)); + + uint16_t epoch = (((uint16_t)sequence[0]) << 8) | sequence[1]; + if (epoch != ssl->d1->r_epoch || + dtls1_bitmap_should_discard(&ssl->d1->bitmap, sequence)) { + // Drop this record. It's from the wrong epoch or is a replay. Note that if + // |epoch| is the next epoch, the record could be buffered for later. For + // simplicity, drop it and expect retransmit to handle it later; DTLS must + // handle packet loss anyway. + *out_consumed = in.size() - CBS_len(&cbs); + return ssl_open_record_discard; + } + + // discard the body in-place. + if (!ssl->s3->aead_read_ctx->Open( + out, type, version, sequence, + MakeSpan(const_cast(CBS_data(&body)), CBS_len(&body)))) { + // Bad packets are silently dropped in DTLS. See section 4.2.1 of RFC 6347. + // Clear the error queue of any errors decryption may have added. Drop the + // entire packet as it must not have come from the peer. + // + // TODO(davidben): This doesn't distinguish malloc failures from encryption + // failures. + ERR_clear_error(); + *out_consumed = in.size() - CBS_len(&cbs); + return ssl_open_record_discard; + } + *out_consumed = in.size() - CBS_len(&cbs); + + // Check the plaintext length. + if (out->size() > SSL3_RT_MAX_PLAIN_LENGTH) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DATA_LENGTH_TOO_LONG); + *out_alert = SSL_AD_RECORD_OVERFLOW; + return ssl_open_record_error; + } + + dtls1_bitmap_record(&ssl->d1->bitmap, sequence); + + // TODO(davidben): Limit the number of empty records as in TLS? This is only + // useful if we also limit discarded packets. + + if (type == SSL3_RT_ALERT) { + return ssl_process_alert(ssl, out_alert, *out); + } + + ssl->s3->warning_alert_count = 0; + + *out_type = type; + return ssl_open_record_success; +} + +static const SSLAEADContext *get_write_aead(const SSL *ssl, + enum dtls1_use_epoch_t use_epoch) { + if (use_epoch == dtls1_use_previous_epoch) { + assert(ssl->d1->w_epoch >= 1); + return ssl->d1->last_aead_write_ctx.get(); + } + + return ssl->s3->aead_write_ctx.get(); +} + +size_t dtls_max_seal_overhead(const SSL *ssl, + enum dtls1_use_epoch_t use_epoch) { + return DTLS1_RT_HEADER_LENGTH + get_write_aead(ssl, use_epoch)->MaxOverhead(); +} + +size_t dtls_seal_prefix_len(const SSL *ssl, enum dtls1_use_epoch_t use_epoch) { + return DTLS1_RT_HEADER_LENGTH + + get_write_aead(ssl, use_epoch)->ExplicitNonceLen(); +} + +int dtls_seal_record(SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out, + uint8_t type, const uint8_t *in, size_t in_len, + enum dtls1_use_epoch_t use_epoch) { + const size_t prefix = dtls_seal_prefix_len(ssl, use_epoch); + if (buffers_alias(in, in_len, out, max_out) && + (max_out < prefix || out + prefix != in)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_OUTPUT_ALIASES_INPUT); + return 0; + } + + // Determine the parameters for the current epoch. + uint16_t epoch = ssl->d1->w_epoch; + SSLAEADContext *aead = ssl->s3->aead_write_ctx.get(); + uint8_t *seq = ssl->s3->write_sequence; + if (use_epoch == dtls1_use_previous_epoch) { + assert(ssl->d1->w_epoch >= 1); + epoch = ssl->d1->w_epoch - 1; + aead = ssl->d1->last_aead_write_ctx.get(); + seq = ssl->d1->last_write_sequence; + } + + if (max_out < DTLS1_RT_HEADER_LENGTH) { + OPENSSL_PUT_ERROR(SSL, SSL_R_BUFFER_TOO_SMALL); + return 0; + } + + out[0] = type; + + uint16_t record_version = ssl->s3->aead_write_ctx->RecordVersion(); + out[1] = record_version >> 8; + out[2] = record_version & 0xff; + + out[3] = epoch >> 8; + out[4] = epoch & 0xff; + OPENSSL_memcpy(&out[5], &seq[2], 6); + + size_t ciphertext_len; + if (!aead->Seal(out + DTLS1_RT_HEADER_LENGTH, &ciphertext_len, + max_out - DTLS1_RT_HEADER_LENGTH, type, record_version, + &out[3] /* seq */, in, in_len) || + !ssl_record_sequence_update(&seq[2], 6)) { + return 0; + } + + if (ciphertext_len >= 1 << 16) { + OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW); + return 0; + } + out[11] = ciphertext_len >> 8; + out[12] = ciphertext_len & 0xff; + + *out_len = DTLS1_RT_HEADER_LENGTH + ciphertext_len; + + ssl_do_msg_callback(ssl, 1 /* write */, SSL3_RT_HEADER, + MakeSpan(out, DTLS1_RT_HEADER_LENGTH)); + + return 1; +} + +} // namespace bssl diff --git a/FoodApp/Pods/BoringSSL-GRPC/ssl/dtls_record.cc.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/ssl/dtls_record.cc.grpc_back new file mode 100644 index 0000000..5e795fa --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/ssl/dtls_record.cc.grpc_back @@ -0,0 +1,353 @@ +/* DTLS implementation written by Nagendra Modadugu + * (nagendra@cs.stanford.edu) for the OpenSSL project 2005. */ +/* ==================================================================== + * 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 (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 + +#include "internal.h" +#include "../crypto/internal.h" + + +namespace bssl { + +// to_u64_be treats |in| as a 8-byte big-endian integer and returns the value as +// a |uint64_t|. +static uint64_t to_u64_be(const uint8_t in[8]) { + uint64_t ret = 0; + unsigned i; + for (i = 0; i < 8; i++) { + ret <<= 8; + ret |= in[i]; + } + return ret; +} + +// dtls1_bitmap_should_discard returns one if |seq_num| has been seen in +// |bitmap| or is stale. Otherwise it returns zero. +static int dtls1_bitmap_should_discard(DTLS1_BITMAP *bitmap, + const uint8_t seq_num[8]) { + const unsigned kWindowSize = sizeof(bitmap->map) * 8; + + uint64_t seq_num_u = to_u64_be(seq_num); + if (seq_num_u > bitmap->max_seq_num) { + return 0; + } + uint64_t idx = bitmap->max_seq_num - seq_num_u; + return idx >= kWindowSize || (bitmap->map & (((uint64_t)1) << idx)); +} + +// dtls1_bitmap_record updates |bitmap| to record receipt of sequence number +// |seq_num|. It slides the window forward if needed. It is an error to call +// this function on a stale sequence number. +static void dtls1_bitmap_record(DTLS1_BITMAP *bitmap, + const uint8_t seq_num[8]) { + const unsigned kWindowSize = sizeof(bitmap->map) * 8; + + uint64_t seq_num_u = to_u64_be(seq_num); + // Shift the window if necessary. + if (seq_num_u > bitmap->max_seq_num) { + uint64_t shift = seq_num_u - bitmap->max_seq_num; + if (shift >= kWindowSize) { + bitmap->map = 0; + } else { + bitmap->map <<= shift; + } + bitmap->max_seq_num = seq_num_u; + } + + uint64_t idx = bitmap->max_seq_num - seq_num_u; + if (idx < kWindowSize) { + bitmap->map |= ((uint64_t)1) << idx; + } +} + +enum ssl_open_record_t dtls_open_record(SSL *ssl, uint8_t *out_type, + Span *out, + size_t *out_consumed, + uint8_t *out_alert, Span in) { + *out_consumed = 0; + if (ssl->s3->read_shutdown == ssl_shutdown_close_notify) { + return ssl_open_record_close_notify; + } + + if (in.empty()) { + return ssl_open_record_partial; + } + + CBS cbs = CBS(in); + + // Decode the record. + uint8_t type; + uint16_t version; + uint8_t sequence[8]; + CBS body; + if (!CBS_get_u8(&cbs, &type) || + !CBS_get_u16(&cbs, &version) || + !CBS_copy_bytes(&cbs, sequence, 8) || + !CBS_get_u16_length_prefixed(&cbs, &body) || + CBS_len(&body) > SSL3_RT_MAX_ENCRYPTED_LENGTH) { + // The record header was incomplete or malformed. Drop the entire packet. + *out_consumed = in.size(); + return ssl_open_record_discard; + } + + bool version_ok; + if (ssl->s3->aead_read_ctx->is_null_cipher()) { + // Only check the first byte. Enforcing beyond that can prevent decoding + // version negotiation failure alerts. + version_ok = (version >> 8) == DTLS1_VERSION_MAJOR; + } else { + version_ok = version == ssl->s3->aead_read_ctx->RecordVersion(); + } + + if (!version_ok) { + // The record header was incomplete or malformed. Drop the entire packet. + *out_consumed = in.size(); + return ssl_open_record_discard; + } + + ssl_do_msg_callback(ssl, 0 /* read */, SSL3_RT_HEADER, + in.subspan(0, DTLS1_RT_HEADER_LENGTH)); + + uint16_t epoch = (((uint16_t)sequence[0]) << 8) | sequence[1]; + if (epoch != ssl->d1->r_epoch || + dtls1_bitmap_should_discard(&ssl->d1->bitmap, sequence)) { + // Drop this record. It's from the wrong epoch or is a replay. Note that if + // |epoch| is the next epoch, the record could be buffered for later. For + // simplicity, drop it and expect retransmit to handle it later; DTLS must + // handle packet loss anyway. + *out_consumed = in.size() - CBS_len(&cbs); + return ssl_open_record_discard; + } + + // discard the body in-place. + if (!ssl->s3->aead_read_ctx->Open( + out, type, version, sequence, + MakeSpan(const_cast(CBS_data(&body)), CBS_len(&body)))) { + // Bad packets are silently dropped in DTLS. See section 4.2.1 of RFC 6347. + // Clear the error queue of any errors decryption may have added. Drop the + // entire packet as it must not have come from the peer. + // + // TODO(davidben): This doesn't distinguish malloc failures from encryption + // failures. + ERR_clear_error(); + *out_consumed = in.size() - CBS_len(&cbs); + return ssl_open_record_discard; + } + *out_consumed = in.size() - CBS_len(&cbs); + + // Check the plaintext length. + if (out->size() > SSL3_RT_MAX_PLAIN_LENGTH) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DATA_LENGTH_TOO_LONG); + *out_alert = SSL_AD_RECORD_OVERFLOW; + return ssl_open_record_error; + } + + dtls1_bitmap_record(&ssl->d1->bitmap, sequence); + + // TODO(davidben): Limit the number of empty records as in TLS? This is only + // useful if we also limit discarded packets. + + if (type == SSL3_RT_ALERT) { + return ssl_process_alert(ssl, out_alert, *out); + } + + ssl->s3->warning_alert_count = 0; + + *out_type = type; + return ssl_open_record_success; +} + +static const SSLAEADContext *get_write_aead(const SSL *ssl, + enum dtls1_use_epoch_t use_epoch) { + if (use_epoch == dtls1_use_previous_epoch) { + assert(ssl->d1->w_epoch >= 1); + return ssl->d1->last_aead_write_ctx.get(); + } + + return ssl->s3->aead_write_ctx.get(); +} + +size_t dtls_max_seal_overhead(const SSL *ssl, + enum dtls1_use_epoch_t use_epoch) { + return DTLS1_RT_HEADER_LENGTH + get_write_aead(ssl, use_epoch)->MaxOverhead(); +} + +size_t dtls_seal_prefix_len(const SSL *ssl, enum dtls1_use_epoch_t use_epoch) { + return DTLS1_RT_HEADER_LENGTH + + get_write_aead(ssl, use_epoch)->ExplicitNonceLen(); +} + +int dtls_seal_record(SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out, + uint8_t type, const uint8_t *in, size_t in_len, + enum dtls1_use_epoch_t use_epoch) { + const size_t prefix = dtls_seal_prefix_len(ssl, use_epoch); + if (buffers_alias(in, in_len, out, max_out) && + (max_out < prefix || out + prefix != in)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_OUTPUT_ALIASES_INPUT); + return 0; + } + + // Determine the parameters for the current epoch. + uint16_t epoch = ssl->d1->w_epoch; + SSLAEADContext *aead = ssl->s3->aead_write_ctx.get(); + uint8_t *seq = ssl->s3->write_sequence; + if (use_epoch == dtls1_use_previous_epoch) { + assert(ssl->d1->w_epoch >= 1); + epoch = ssl->d1->w_epoch - 1; + aead = ssl->d1->last_aead_write_ctx.get(); + seq = ssl->d1->last_write_sequence; + } + + if (max_out < DTLS1_RT_HEADER_LENGTH) { + OPENSSL_PUT_ERROR(SSL, SSL_R_BUFFER_TOO_SMALL); + return 0; + } + + out[0] = type; + + uint16_t record_version = ssl->s3->aead_write_ctx->RecordVersion(); + out[1] = record_version >> 8; + out[2] = record_version & 0xff; + + out[3] = epoch >> 8; + out[4] = epoch & 0xff; + OPENSSL_memcpy(&out[5], &seq[2], 6); + + size_t ciphertext_len; + if (!aead->Seal(out + DTLS1_RT_HEADER_LENGTH, &ciphertext_len, + max_out - DTLS1_RT_HEADER_LENGTH, type, record_version, + &out[3] /* seq */, in, in_len) || + !ssl_record_sequence_update(&seq[2], 6)) { + return 0; + } + + if (ciphertext_len >= 1 << 16) { + OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW); + return 0; + } + out[11] = ciphertext_len >> 8; + out[12] = ciphertext_len & 0xff; + + *out_len = DTLS1_RT_HEADER_LENGTH + ciphertext_len; + + ssl_do_msg_callback(ssl, 1 /* write */, SSL3_RT_HEADER, + MakeSpan(out, DTLS1_RT_HEADER_LENGTH)); + + return 1; +} + +} // namespace bssl diff --git a/FoodApp/Pods/BoringSSL-GRPC/ssl/handoff.cc b/FoodApp/Pods/BoringSSL-GRPC/ssl/handoff.cc new file mode 100644 index 0000000..2b97f7e --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/ssl/handoff.cc @@ -0,0 +1,285 @@ +/* Copyright (c) 2018, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include + +#include "internal.h" + + +namespace bssl { + +constexpr int kHandoffVersion = 0; +constexpr int kHandbackVersion = 0; + +bool SSL_serialize_handoff(const SSL *ssl, CBB *out) { + const SSL3_STATE *const s3 = ssl->s3; + if (!ssl->server || + s3->hs == nullptr || + s3->rwstate != SSL_HANDOFF) { + return false; + } + + CBB seq; + Span transcript = s3->hs->transcript.buffer(); + if (!CBB_add_asn1(out, &seq, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1_uint64(&seq, kHandoffVersion) || + !CBB_add_asn1_octet_string(&seq, transcript.data(), transcript.size()) || + !CBB_add_asn1_octet_string(&seq, + reinterpret_cast(s3->hs_buf->data), + s3->hs_buf->length) || + !CBB_flush(out)) { + return false; + } + + return true; +} + +bool SSL_decline_handoff(SSL *ssl) { + const SSL3_STATE *const s3 = ssl->s3; + if (!ssl->server || + s3->hs == nullptr || + s3->rwstate != SSL_HANDOFF) { + return false; + } + + ssl->handoff = false; + return true; +} + +bool SSL_apply_handoff(SSL *ssl, Span handoff) { + if (ssl->method->is_dtls) { + return false; + } + + CBS seq, handoff_cbs(handoff); + uint64_t handoff_version; + if (!CBS_get_asn1(&handoff_cbs, &seq, CBS_ASN1_SEQUENCE) || + !CBS_get_asn1_uint64(&seq, &handoff_version) || + handoff_version != kHandoffVersion) { + return false; + } + + CBS transcript, hs_buf; + if (!CBS_get_asn1(&seq, &transcript, CBS_ASN1_OCTETSTRING) || + !CBS_get_asn1(&seq, &hs_buf, CBS_ASN1_OCTETSTRING)) { + return false; + } + + SSL_set_accept_state(ssl); + + SSL3_STATE *const s3 = ssl->s3; + s3->v2_hello_done = true; + s3->has_message = true; + + s3->hs_buf.reset(BUF_MEM_new()); + if (!s3->hs_buf || + !BUF_MEM_append(s3->hs_buf.get(), CBS_data(&hs_buf), CBS_len(&hs_buf))) { + return false; + } + + if (CBS_len(&transcript) != 0) { + s3->hs->transcript.Update(transcript); + s3->is_v2_hello = true; + ssl_do_msg_callback(ssl, 0 /* read */, 0 /* V2ClientHello */, transcript); + } + + return true; +} + +bool SSL_serialize_handback(const SSL *ssl, CBB *out) { + if (!ssl->server || + !ssl->s3->initial_handshake_complete || + ssl->method->is_dtls || + ssl->version < TLS1_VERSION) { + return false; + } + + const SSL3_STATE *const s3 = ssl->s3; + size_t hostname_len = 0; + if (s3->hostname) { + hostname_len = strlen(s3->hostname.get()); + } + + size_t iv_len = 0; + const uint8_t *read_iv = nullptr, *write_iv = nullptr; + if (ssl->version == TLS1_VERSION && + SSL_CIPHER_is_block_cipher(s3->aead_read_ctx->cipher()) && + (!s3->aead_read_ctx->GetIV(&read_iv, &iv_len) || + !s3->aead_write_ctx->GetIV(&write_iv, &iv_len))) { + return false; + } + + CBB seq; + if (!CBB_add_asn1(out, &seq, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1_uint64(&seq, kHandbackVersion) || + !CBB_add_asn1_uint64(&seq, ssl->version) || + !CBB_add_asn1_uint64(&seq, ssl->conf_max_version) || + !CBB_add_asn1_uint64(&seq, ssl->conf_min_version) || + !CBB_add_asn1_uint64(&seq, ssl->max_send_fragment) || + !CBB_add_asn1_octet_string(&seq, s3->read_sequence, + sizeof(s3->read_sequence)) || + !CBB_add_asn1_octet_string(&seq, s3->write_sequence, + sizeof(s3->write_sequence)) || + !CBB_add_asn1_octet_string(&seq, s3->server_random, + sizeof(s3->server_random)) || + !CBB_add_asn1_octet_string(&seq, s3->client_random, + sizeof(s3->client_random)) || + !CBB_add_asn1_octet_string(&seq, read_iv, iv_len) || + !CBB_add_asn1_octet_string(&seq, write_iv, iv_len) || + !CBB_add_asn1_bool(&seq, s3->session_reused) || + !CBB_add_asn1_bool(&seq, s3->send_connection_binding) || + !CBB_add_asn1_bool(&seq, s3->tlsext_channel_id_valid) || + !ssl_session_serialize(s3->established_session.get(), &seq) || + !CBB_add_asn1_octet_string(&seq, s3->next_proto_negotiated.data(), + s3->next_proto_negotiated.size()) || + !CBB_add_asn1_octet_string(&seq, s3->alpn_selected.data(), + s3->alpn_selected.size()) || + !CBB_add_asn1_octet_string( + &seq, reinterpret_cast(s3->hostname.get()), + hostname_len) || + !CBB_add_asn1_octet_string(&seq, s3->tlsext_channel_id, + sizeof(s3->tlsext_channel_id)) || + !CBB_add_asn1_uint64(&seq, ssl->options) || + !CBB_add_asn1_uint64(&seq, ssl->mode) || + !CBB_add_asn1_uint64(&seq, ssl->max_cert_list) || + !CBB_add_asn1_bool(&seq, ssl->quiet_shutdown) || + !CBB_add_asn1_bool(&seq, ssl->tlsext_channel_id_enabled) || + !CBB_add_asn1_bool(&seq, ssl->retain_only_sha256_of_client_certs) || + !CBB_flush(out)) { + return false; + } + + return true; +} + +bool SSL_apply_handback(SSL *ssl, Span handback) { + if (ssl->do_handshake != nullptr || + ssl->method->is_dtls) { + return false; + } + + SSL3_STATE *const s3 = ssl->s3; + uint64_t handback_version, version, conf_max_version, conf_min_version, + max_send_fragment, options, mode, max_cert_list; + CBS seq, read_seq, write_seq, server_rand, client_rand, read_iv, write_iv, + next_proto, alpn, hostname, channel_id; + int session_reused, send_connection_binding, channel_id_valid, + quiet_shutdown, channel_id_enabled, retain_only_sha256; + + CBS handback_cbs(handback); + if (!CBS_get_asn1(&handback_cbs, &seq, CBS_ASN1_SEQUENCE) || + !CBS_get_asn1_uint64(&seq, &handback_version) || + handback_version != kHandbackVersion) { + return false; + } + + if (!CBS_get_asn1_uint64(&seq, &version) || + !CBS_get_asn1_uint64(&seq, &conf_max_version) || + !CBS_get_asn1_uint64(&seq, &conf_min_version) || + !CBS_get_asn1_uint64(&seq, &max_send_fragment) || + !CBS_get_asn1(&seq, &read_seq, CBS_ASN1_OCTETSTRING) || + CBS_len(&read_seq) != sizeof(s3->read_sequence) || + !CBS_get_asn1(&seq, &write_seq, CBS_ASN1_OCTETSTRING) || + CBS_len(&write_seq) != sizeof(s3->write_sequence) || + !CBS_get_asn1(&seq, &server_rand, CBS_ASN1_OCTETSTRING) || + CBS_len(&server_rand) != sizeof(s3->server_random) || + !CBS_copy_bytes(&server_rand, s3->server_random, + sizeof(s3->server_random)) || + !CBS_get_asn1(&seq, &client_rand, CBS_ASN1_OCTETSTRING) || + CBS_len(&client_rand) != sizeof(s3->client_random) || + !CBS_copy_bytes(&client_rand, s3->client_random, + sizeof(s3->client_random)) || + !CBS_get_asn1(&seq, &read_iv, CBS_ASN1_OCTETSTRING) || + !CBS_get_asn1(&seq, &write_iv, CBS_ASN1_OCTETSTRING) || + !CBS_get_asn1_bool(&seq, &session_reused) || + !CBS_get_asn1_bool(&seq, &send_connection_binding) || + !CBS_get_asn1_bool(&seq, &channel_id_valid)) { + return false; + } + + s3->established_session = + SSL_SESSION_parse(&seq, ssl->ctx->x509_method, ssl->ctx->pool); + + if (!s3->established_session || + !CBS_get_asn1(&seq, &next_proto, CBS_ASN1_OCTETSTRING) || + !CBS_get_asn1(&seq, &alpn, CBS_ASN1_OCTETSTRING) || + !CBS_get_asn1(&seq, &hostname, CBS_ASN1_OCTETSTRING) || + !CBS_get_asn1(&seq, &channel_id, CBS_ASN1_OCTETSTRING) || + CBS_len(&channel_id) != sizeof(s3->tlsext_channel_id) || + !CBS_copy_bytes(&channel_id, s3->tlsext_channel_id, + sizeof(s3->tlsext_channel_id)) || + !CBS_get_asn1_uint64(&seq, &options) || + !CBS_get_asn1_uint64(&seq, &mode) || + !CBS_get_asn1_uint64(&seq, &max_cert_list) || + !CBS_get_asn1_bool(&seq, &quiet_shutdown) || + !CBS_get_asn1_bool(&seq, &channel_id_enabled) || + !CBS_get_asn1_bool(&seq, &retain_only_sha256)) { + return false; + } + + ssl->version = version; + ssl->conf_max_version = conf_max_version; + ssl->conf_min_version = conf_min_version; + ssl->max_send_fragment = max_send_fragment; + ssl->do_handshake = ssl_server_handshake; + ssl->server = true; + ssl->options = options; + ssl->mode = mode; + ssl->max_cert_list = max_cert_list; + + s3->hs.reset(); + s3->have_version = true; + s3->initial_handshake_complete = true; + s3->session_reused = session_reused; + s3->send_connection_binding = send_connection_binding; + s3->tlsext_channel_id_valid = channel_id_valid; + s3->next_proto_negotiated.CopyFrom(next_proto); + s3->alpn_selected.CopyFrom(alpn); + + const size_t hostname_len = CBS_len(&hostname); + if (hostname_len == 0) { + s3->hostname.reset(); + } else { + char *hostname_str = nullptr; + if (!CBS_strdup(&hostname, &hostname_str)) { + return false; + } + s3->hostname.reset(hostname_str); + } + + ssl->quiet_shutdown = quiet_shutdown; + ssl->tlsext_channel_id_enabled = channel_id_enabled; + ssl->retain_only_sha256_of_client_certs = retain_only_sha256; + + Array key_block; + if (!tls1_configure_aead(ssl, evp_aead_open, &key_block, + s3->established_session->cipher, read_iv) || + !tls1_configure_aead(ssl, evp_aead_seal, &key_block, + s3->established_session->cipher, write_iv)) { + return false; + } + + if (!CBS_copy_bytes(&read_seq, s3->read_sequence, + sizeof(s3->read_sequence)) || + !CBS_copy_bytes(&write_seq, s3->write_sequence, + sizeof(s3->write_sequence))) { + return false; + } + + return true; +} + +} // namespace bssl diff --git a/FoodApp/Pods/BoringSSL-GRPC/ssl/handoff.cc.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/ssl/handoff.cc.grpc_back new file mode 100644 index 0000000..b19d443 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/ssl/handoff.cc.grpc_back @@ -0,0 +1,285 @@ +/* Copyright (c) 2018, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include + +#include "internal.h" + + +namespace bssl { + +constexpr int kHandoffVersion = 0; +constexpr int kHandbackVersion = 0; + +bool SSL_serialize_handoff(const SSL *ssl, CBB *out) { + const SSL3_STATE *const s3 = ssl->s3; + if (!ssl->server || + s3->hs == nullptr || + s3->rwstate != SSL_HANDOFF) { + return false; + } + + CBB seq; + Span transcript = s3->hs->transcript.buffer(); + if (!CBB_add_asn1(out, &seq, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1_uint64(&seq, kHandoffVersion) || + !CBB_add_asn1_octet_string(&seq, transcript.data(), transcript.size()) || + !CBB_add_asn1_octet_string(&seq, + reinterpret_cast(s3->hs_buf->data), + s3->hs_buf->length) || + !CBB_flush(out)) { + return false; + } + + return true; +} + +bool SSL_decline_handoff(SSL *ssl) { + const SSL3_STATE *const s3 = ssl->s3; + if (!ssl->server || + s3->hs == nullptr || + s3->rwstate != SSL_HANDOFF) { + return false; + } + + ssl->handoff = false; + return true; +} + +bool SSL_apply_handoff(SSL *ssl, Span handoff) { + if (ssl->method->is_dtls) { + return false; + } + + CBS seq, handoff_cbs(handoff); + uint64_t handoff_version; + if (!CBS_get_asn1(&handoff_cbs, &seq, CBS_ASN1_SEQUENCE) || + !CBS_get_asn1_uint64(&seq, &handoff_version) || + handoff_version != kHandoffVersion) { + return false; + } + + CBS transcript, hs_buf; + if (!CBS_get_asn1(&seq, &transcript, CBS_ASN1_OCTETSTRING) || + !CBS_get_asn1(&seq, &hs_buf, CBS_ASN1_OCTETSTRING)) { + return false; + } + + SSL_set_accept_state(ssl); + + SSL3_STATE *const s3 = ssl->s3; + s3->v2_hello_done = true; + s3->has_message = true; + + s3->hs_buf.reset(BUF_MEM_new()); + if (!s3->hs_buf || + !BUF_MEM_append(s3->hs_buf.get(), CBS_data(&hs_buf), CBS_len(&hs_buf))) { + return false; + } + + if (CBS_len(&transcript) != 0) { + s3->hs->transcript.Update(transcript); + s3->is_v2_hello = true; + ssl_do_msg_callback(ssl, 0 /* read */, 0 /* V2ClientHello */, transcript); + } + + return true; +} + +bool SSL_serialize_handback(const SSL *ssl, CBB *out) { + if (!ssl->server || + !ssl->s3->initial_handshake_complete || + ssl->method->is_dtls || + ssl->version < TLS1_VERSION) { + return false; + } + + const SSL3_STATE *const s3 = ssl->s3; + size_t hostname_len = 0; + if (s3->hostname) { + hostname_len = strlen(s3->hostname.get()); + } + + size_t iv_len = 0; + const uint8_t *read_iv = nullptr, *write_iv = nullptr; + if (ssl->version == TLS1_VERSION && + SSL_CIPHER_is_block_cipher(s3->aead_read_ctx->cipher()) && + (!s3->aead_read_ctx->GetIV(&read_iv, &iv_len) || + !s3->aead_write_ctx->GetIV(&write_iv, &iv_len))) { + return false; + } + + CBB seq; + if (!CBB_add_asn1(out, &seq, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1_uint64(&seq, kHandbackVersion) || + !CBB_add_asn1_uint64(&seq, ssl->version) || + !CBB_add_asn1_uint64(&seq, ssl->conf_max_version) || + !CBB_add_asn1_uint64(&seq, ssl->conf_min_version) || + !CBB_add_asn1_uint64(&seq, ssl->max_send_fragment) || + !CBB_add_asn1_octet_string(&seq, s3->read_sequence, + sizeof(s3->read_sequence)) || + !CBB_add_asn1_octet_string(&seq, s3->write_sequence, + sizeof(s3->write_sequence)) || + !CBB_add_asn1_octet_string(&seq, s3->server_random, + sizeof(s3->server_random)) || + !CBB_add_asn1_octet_string(&seq, s3->client_random, + sizeof(s3->client_random)) || + !CBB_add_asn1_octet_string(&seq, read_iv, iv_len) || + !CBB_add_asn1_octet_string(&seq, write_iv, iv_len) || + !CBB_add_asn1_bool(&seq, s3->session_reused) || + !CBB_add_asn1_bool(&seq, s3->send_connection_binding) || + !CBB_add_asn1_bool(&seq, s3->tlsext_channel_id_valid) || + !ssl_session_serialize(s3->established_session.get(), &seq) || + !CBB_add_asn1_octet_string(&seq, s3->next_proto_negotiated.data(), + s3->next_proto_negotiated.size()) || + !CBB_add_asn1_octet_string(&seq, s3->alpn_selected.data(), + s3->alpn_selected.size()) || + !CBB_add_asn1_octet_string( + &seq, reinterpret_cast(s3->hostname.get()), + hostname_len) || + !CBB_add_asn1_octet_string(&seq, s3->tlsext_channel_id, + sizeof(s3->tlsext_channel_id)) || + !CBB_add_asn1_uint64(&seq, ssl->options) || + !CBB_add_asn1_uint64(&seq, ssl->mode) || + !CBB_add_asn1_uint64(&seq, ssl->max_cert_list) || + !CBB_add_asn1_bool(&seq, ssl->quiet_shutdown) || + !CBB_add_asn1_bool(&seq, ssl->tlsext_channel_id_enabled) || + !CBB_add_asn1_bool(&seq, ssl->retain_only_sha256_of_client_certs) || + !CBB_flush(out)) { + return false; + } + + return true; +} + +bool SSL_apply_handback(SSL *ssl, Span handback) { + if (ssl->do_handshake != nullptr || + ssl->method->is_dtls) { + return false; + } + + SSL3_STATE *const s3 = ssl->s3; + uint64_t handback_version, version, conf_max_version, conf_min_version, + max_send_fragment, options, mode, max_cert_list; + CBS seq, read_seq, write_seq, server_rand, client_rand, read_iv, write_iv, + next_proto, alpn, hostname, channel_id; + int session_reused, send_connection_binding, channel_id_valid, + quiet_shutdown, channel_id_enabled, retain_only_sha256; + + CBS handback_cbs(handback); + if (!CBS_get_asn1(&handback_cbs, &seq, CBS_ASN1_SEQUENCE) || + !CBS_get_asn1_uint64(&seq, &handback_version) || + handback_version != kHandbackVersion) { + return false; + } + + if (!CBS_get_asn1_uint64(&seq, &version) || + !CBS_get_asn1_uint64(&seq, &conf_max_version) || + !CBS_get_asn1_uint64(&seq, &conf_min_version) || + !CBS_get_asn1_uint64(&seq, &max_send_fragment) || + !CBS_get_asn1(&seq, &read_seq, CBS_ASN1_OCTETSTRING) || + CBS_len(&read_seq) != sizeof(s3->read_sequence) || + !CBS_get_asn1(&seq, &write_seq, CBS_ASN1_OCTETSTRING) || + CBS_len(&write_seq) != sizeof(s3->write_sequence) || + !CBS_get_asn1(&seq, &server_rand, CBS_ASN1_OCTETSTRING) || + CBS_len(&server_rand) != sizeof(s3->server_random) || + !CBS_copy_bytes(&server_rand, s3->server_random, + sizeof(s3->server_random)) || + !CBS_get_asn1(&seq, &client_rand, CBS_ASN1_OCTETSTRING) || + CBS_len(&client_rand) != sizeof(s3->client_random) || + !CBS_copy_bytes(&client_rand, s3->client_random, + sizeof(s3->client_random)) || + !CBS_get_asn1(&seq, &read_iv, CBS_ASN1_OCTETSTRING) || + !CBS_get_asn1(&seq, &write_iv, CBS_ASN1_OCTETSTRING) || + !CBS_get_asn1_bool(&seq, &session_reused) || + !CBS_get_asn1_bool(&seq, &send_connection_binding) || + !CBS_get_asn1_bool(&seq, &channel_id_valid)) { + return false; + } + + s3->established_session = + SSL_SESSION_parse(&seq, ssl->ctx->x509_method, ssl->ctx->pool); + + if (!s3->established_session || + !CBS_get_asn1(&seq, &next_proto, CBS_ASN1_OCTETSTRING) || + !CBS_get_asn1(&seq, &alpn, CBS_ASN1_OCTETSTRING) || + !CBS_get_asn1(&seq, &hostname, CBS_ASN1_OCTETSTRING) || + !CBS_get_asn1(&seq, &channel_id, CBS_ASN1_OCTETSTRING) || + CBS_len(&channel_id) != sizeof(s3->tlsext_channel_id) || + !CBS_copy_bytes(&channel_id, s3->tlsext_channel_id, + sizeof(s3->tlsext_channel_id)) || + !CBS_get_asn1_uint64(&seq, &options) || + !CBS_get_asn1_uint64(&seq, &mode) || + !CBS_get_asn1_uint64(&seq, &max_cert_list) || + !CBS_get_asn1_bool(&seq, &quiet_shutdown) || + !CBS_get_asn1_bool(&seq, &channel_id_enabled) || + !CBS_get_asn1_bool(&seq, &retain_only_sha256)) { + return false; + } + + ssl->version = version; + ssl->conf_max_version = conf_max_version; + ssl->conf_min_version = conf_min_version; + ssl->max_send_fragment = max_send_fragment; + ssl->do_handshake = ssl_server_handshake; + ssl->server = true; + ssl->options = options; + ssl->mode = mode; + ssl->max_cert_list = max_cert_list; + + s3->hs.reset(); + s3->have_version = true; + s3->initial_handshake_complete = true; + s3->session_reused = session_reused; + s3->send_connection_binding = send_connection_binding; + s3->tlsext_channel_id_valid = channel_id_valid; + s3->next_proto_negotiated.CopyFrom(next_proto); + s3->alpn_selected.CopyFrom(alpn); + + const size_t hostname_len = CBS_len(&hostname); + if (hostname_len == 0) { + s3->hostname.reset(); + } else { + char *hostname_str = nullptr; + if (!CBS_strdup(&hostname, &hostname_str)) { + return false; + } + s3->hostname.reset(hostname_str); + } + + ssl->quiet_shutdown = quiet_shutdown; + ssl->tlsext_channel_id_enabled = channel_id_enabled; + ssl->retain_only_sha256_of_client_certs = retain_only_sha256; + + Array key_block; + if (!tls1_configure_aead(ssl, evp_aead_open, &key_block, + s3->established_session->cipher, read_iv) || + !tls1_configure_aead(ssl, evp_aead_seal, &key_block, + s3->established_session->cipher, write_iv)) { + return false; + } + + if (!CBS_copy_bytes(&read_seq, s3->read_sequence, + sizeof(s3->read_sequence)) || + !CBS_copy_bytes(&write_seq, s3->write_sequence, + sizeof(s3->write_sequence))) { + return false; + } + + return true; +} + +} // namespace bssl diff --git a/FoodApp/Pods/BoringSSL-GRPC/ssl/handshake.cc b/FoodApp/Pods/BoringSSL-GRPC/ssl/handshake.cc new file mode 100644 index 0000000..610ae36 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/ssl/handshake.cc @@ -0,0 +1,630 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 + +#include "../crypto/internal.h" +#include "internal.h" + + +namespace bssl { + +SSL_HANDSHAKE::SSL_HANDSHAKE(SSL *ssl_arg) + : ssl(ssl_arg), + scts_requested(false), + needs_psk_binder(false), + received_hello_retry_request(false), + sent_hello_retry_request(false), + received_custom_extension(false), + handshake_finalized(false), + accept_psk_mode(false), + cert_request(false), + certificate_status_expected(false), + ocsp_stapling_requested(false), + should_ack_sni(false), + in_false_start(false), + in_early_data(false), + early_data_offered(false), + can_early_read(false), + can_early_write(false), + next_proto_neg_seen(false), + ticket_expected(false), + extended_master_secret(false), + pending_private_key_op(false), + grease_seeded(false) { +} + +SSL_HANDSHAKE::~SSL_HANDSHAKE() { + ssl->ctx->x509_method->hs_flush_cached_ca_names(this); +} + +UniquePtr ssl_handshake_new(SSL *ssl) { + UniquePtr hs = MakeUnique(ssl); + if (!hs || + !hs->transcript.Init()) { + return nullptr; + } + return hs; +} + +bool ssl_check_message_type(SSL *ssl, const SSLMessage &msg, int type) { + if (msg.type != type) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE); + OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_MESSAGE); + ERR_add_error_dataf("got type %d, wanted type %d", msg.type, type); + return false; + } + + return true; +} + +bool ssl_add_message_cbb(SSL *ssl, CBB *cbb) { + Array msg; + if (!ssl->method->finish_message(ssl, cbb, &msg) || + !ssl->method->add_message(ssl, std::move(msg))) { + return false; + } + + return true; +} + +size_t ssl_max_handshake_message_len(const SSL *ssl) { + // kMaxMessageLen is the default maximum message size for handshakes which do + // not accept peer certificate chains. + static const size_t kMaxMessageLen = 16384; + + if (SSL_in_init(ssl)) { + if ((!ssl->server || (ssl->verify_mode & SSL_VERIFY_PEER)) && + kMaxMessageLen < ssl->max_cert_list) { + return ssl->max_cert_list; + } + return kMaxMessageLen; + } + + if (ssl_protocol_version(ssl) < TLS1_3_VERSION) { + // In TLS 1.2 and below, the largest acceptable post-handshake message is + // a HelloRequest. + return 0; + } + + if (ssl->server) { + // The largest acceptable post-handshake message for a server is a + // KeyUpdate. We will never initiate post-handshake auth. + return 1; + } + + // Clients must accept NewSessionTicket, so allow the default size. + return kMaxMessageLen; +} + +bool ssl_hash_message(SSL_HANDSHAKE *hs, const SSLMessage &msg) { + // V2ClientHello messages are pre-hashed. + if (msg.is_v2_hello) { + return true; + } + + return hs->transcript.Update(msg.raw); +} + +int ssl_parse_extensions(const CBS *cbs, uint8_t *out_alert, + const SSL_EXTENSION_TYPE *ext_types, + size_t num_ext_types, int ignore_unknown) { + // Reset everything. + for (size_t i = 0; i < num_ext_types; i++) { + *ext_types[i].out_present = 0; + CBS_init(ext_types[i].out_data, NULL, 0); + } + + CBS copy = *cbs; + while (CBS_len(©) != 0) { + uint16_t type; + CBS data; + if (!CBS_get_u16(©, &type) || + !CBS_get_u16_length_prefixed(©, &data)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_PARSE_TLSEXT); + *out_alert = SSL_AD_DECODE_ERROR; + return 0; + } + + const SSL_EXTENSION_TYPE *ext_type = NULL; + for (size_t i = 0; i < num_ext_types; i++) { + if (type == ext_types[i].type) { + ext_type = &ext_types[i]; + break; + } + } + + if (ext_type == NULL) { + if (ignore_unknown) { + continue; + } + OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION); + *out_alert = SSL_AD_UNSUPPORTED_EXTENSION; + return 0; + } + + // Duplicate ext_types are forbidden. + if (*ext_type->out_present) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DUPLICATE_EXTENSION); + *out_alert = SSL_AD_ILLEGAL_PARAMETER; + return 0; + } + + *ext_type->out_present = 1; + *ext_type->out_data = data; + } + + return 1; +} + +static void set_crypto_buffer(CRYPTO_BUFFER **dest, CRYPTO_BUFFER *src) { + // TODO(davidben): Remove this helper once |SSL_SESSION| can use |UniquePtr| + // and |UniquePtr| has up_ref helpers. + CRYPTO_BUFFER_free(*dest); + *dest = src; + if (src != nullptr) { + CRYPTO_BUFFER_up_ref(src); + } +} + +enum ssl_verify_result_t ssl_verify_peer_cert(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + const SSL_SESSION *prev_session = ssl->s3->established_session.get(); + if (prev_session != NULL) { + // If renegotiating, the server must not change the server certificate. See + // https://mitls.org/pages/attacks/3SHAKE. We never resume on renegotiation, + // so this check is sufficient to ensure the reported peer certificate never + // changes on renegotiation. + assert(!ssl->server); + if (sk_CRYPTO_BUFFER_num(prev_session->certs) != + sk_CRYPTO_BUFFER_num(hs->new_session->certs)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_SERVER_CERT_CHANGED); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + return ssl_verify_invalid; + } + + for (size_t i = 0; i < sk_CRYPTO_BUFFER_num(hs->new_session->certs); i++) { + const CRYPTO_BUFFER *old_cert = + sk_CRYPTO_BUFFER_value(prev_session->certs, i); + const CRYPTO_BUFFER *new_cert = + sk_CRYPTO_BUFFER_value(hs->new_session->certs, i); + if (CRYPTO_BUFFER_len(old_cert) != CRYPTO_BUFFER_len(new_cert) || + OPENSSL_memcmp(CRYPTO_BUFFER_data(old_cert), + CRYPTO_BUFFER_data(new_cert), + CRYPTO_BUFFER_len(old_cert)) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_SERVER_CERT_CHANGED); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + return ssl_verify_invalid; + } + } + + // The certificate is identical, so we may skip re-verifying the + // certificate. Since we only authenticated the previous one, copy other + // authentication from the established session and ignore what was newly + // received. + set_crypto_buffer(&hs->new_session->ocsp_response, + prev_session->ocsp_response); + set_crypto_buffer(&hs->new_session->signed_cert_timestamp_list, + prev_session->signed_cert_timestamp_list); + hs->new_session->verify_result = prev_session->verify_result; + return ssl_verify_ok; + } + + uint8_t alert = SSL_AD_CERTIFICATE_UNKNOWN; + enum ssl_verify_result_t ret; + if (ssl->custom_verify_callback != nullptr) { + ret = ssl->custom_verify_callback(ssl, &alert); + switch (ret) { + case ssl_verify_ok: + hs->new_session->verify_result = X509_V_OK; + break; + case ssl_verify_invalid: + // If |SSL_VERIFY_NONE|, the error is non-fatal, but we keep the result. + if (ssl->verify_mode == SSL_VERIFY_NONE) { + ERR_clear_error(); + ret = ssl_verify_ok; + } + hs->new_session->verify_result = X509_V_ERR_APPLICATION_VERIFICATION; + break; + case ssl_verify_retry: + break; + } + } else { + ret = ssl->ctx->x509_method->session_verify_cert_chain( + hs->new_session.get(), ssl, &alert) + ? ssl_verify_ok + : ssl_verify_invalid; + } + + if (ret == ssl_verify_invalid) { + OPENSSL_PUT_ERROR(SSL, SSL_R_CERTIFICATE_VERIFY_FAILED); + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + } + + return ret; +} + +uint16_t ssl_get_grease_value(SSL_HANDSHAKE *hs, + enum ssl_grease_index_t index) { + // Draw entropy for all GREASE values at once. This avoids calling + // |RAND_bytes| repeatedly and makes the values consistent within a + // connection. The latter is so the second ClientHello matches after + // HelloRetryRequest and so supported_groups and key_shares are consistent. + if (!hs->grease_seeded) { + RAND_bytes(hs->grease_seed, sizeof(hs->grease_seed)); + hs->grease_seeded = true; + } + + // This generates a random value of the form 0xωaωa, for all 0 ≤ ω < 16. + uint16_t ret = hs->grease_seed[index]; + ret = (ret & 0xf0) | 0x0a; + ret |= ret << 8; + return ret; +} + +enum ssl_hs_wait_t ssl_get_finished(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + SSLMessage msg; + if (!ssl->method->get_message(ssl, &msg)) { + return ssl_hs_read_message; + } + + if (!ssl_check_message_type(ssl, msg, SSL3_MT_FINISHED)) { + return ssl_hs_error; + } + + // Snapshot the finished hash before incorporating the new message. + uint8_t finished[EVP_MAX_MD_SIZE]; + size_t finished_len; + if (!hs->transcript.GetFinishedMAC(finished, &finished_len, + SSL_get_session(ssl), !ssl->server) || + !ssl_hash_message(hs, msg)) { + return ssl_hs_error; + } + + int finished_ok = CBS_mem_equal(&msg.body, finished, finished_len); +#if defined(BORINGSSL_UNSAFE_FUZZER_MODE) + finished_ok = 1; +#endif + if (!finished_ok) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECRYPT_ERROR); + OPENSSL_PUT_ERROR(SSL, SSL_R_DIGEST_CHECK_FAILED); + return ssl_hs_error; + } + + // Copy the Finished so we can use it for renegotiation checks. + if (ssl->version != SSL3_VERSION) { + if (finished_len > sizeof(ssl->s3->previous_client_finished) || + finished_len > sizeof(ssl->s3->previous_server_finished)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return ssl_hs_error; + } + + if (ssl->server) { + OPENSSL_memcpy(ssl->s3->previous_client_finished, finished, finished_len); + ssl->s3->previous_client_finished_len = finished_len; + } else { + OPENSSL_memcpy(ssl->s3->previous_server_finished, finished, finished_len); + ssl->s3->previous_server_finished_len = finished_len; + } + } + + ssl->method->next_message(ssl); + return ssl_hs_ok; +} + +bool ssl_send_finished(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + const SSL_SESSION *session = SSL_get_session(ssl); + + uint8_t finished[EVP_MAX_MD_SIZE]; + size_t finished_len; + if (!hs->transcript.GetFinishedMAC(finished, &finished_len, session, + ssl->server)) { + return 0; + } + + // Log the master secret, if logging is enabled. + if (!ssl_log_secret(ssl, "CLIENT_RANDOM", + session->master_key, + session->master_key_length)) { + return 0; + } + + // Copy the Finished so we can use it for renegotiation checks. + if (ssl->version != SSL3_VERSION) { + if (finished_len > sizeof(ssl->s3->previous_client_finished) || + finished_len > sizeof(ssl->s3->previous_server_finished)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return 0; + } + + if (ssl->server) { + OPENSSL_memcpy(ssl->s3->previous_server_finished, finished, finished_len); + ssl->s3->previous_server_finished_len = finished_len; + } else { + OPENSSL_memcpy(ssl->s3->previous_client_finished, finished, finished_len); + ssl->s3->previous_client_finished_len = finished_len; + } + } + + ScopedCBB cbb; + CBB body; + if (!ssl->method->init_message(ssl, cbb.get(), &body, SSL3_MT_FINISHED) || + !CBB_add_bytes(&body, finished, finished_len) || + !ssl_add_message_cbb(ssl, cbb.get())) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return 0; + } + + return 1; +} + +bool ssl_output_cert_chain(SSL *ssl) { + ScopedCBB cbb; + CBB body; + if (!ssl->method->init_message(ssl, cbb.get(), &body, SSL3_MT_CERTIFICATE) || + !ssl_add_cert_chain(ssl, &body) || + !ssl_add_message_cbb(ssl, cbb.get())) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return false; + } + + return true; +} + +int ssl_run_handshake(SSL_HANDSHAKE *hs, bool *out_early_return) { + SSL *const ssl = hs->ssl; + for (;;) { + // Resolve the operation the handshake was waiting on. + switch (hs->wait) { + case ssl_hs_error: + ERR_restore_state(hs->error.get()); + return -1; + + case ssl_hs_flush: { + int ret = ssl->method->flush_flight(ssl); + if (ret <= 0) { + return ret; + } + break; + } + + case ssl_hs_read_server_hello: + case ssl_hs_read_message: + case ssl_hs_read_change_cipher_spec: { + uint8_t alert = SSL_AD_DECODE_ERROR; + size_t consumed = 0; + ssl_open_record_t ret; + if (hs->wait == ssl_hs_read_change_cipher_spec) { + ret = ssl_open_change_cipher_spec(ssl, &consumed, &alert, + ssl->s3->read_buffer.span()); + } else { + ret = ssl_open_handshake(ssl, &consumed, &alert, + ssl->s3->read_buffer.span()); + } + if (ret == ssl_open_record_error && + hs->wait == ssl_hs_read_server_hello) { + uint32_t err = ERR_peek_error(); + if (ERR_GET_LIB(err) == ERR_LIB_SSL && + ERR_GET_REASON(err) == SSL_R_SSLV3_ALERT_HANDSHAKE_FAILURE) { + // Add a dedicated error code to the queue for a handshake_failure + // alert in response to ClientHello. This matches NSS's client + // behavior and gives a better error on a (probable) failure to + // negotiate initial parameters. Note: this error code comes after + // the original one. + // + // See https://crbug.com/446505. + OPENSSL_PUT_ERROR(SSL, SSL_R_HANDSHAKE_FAILURE_ON_CLIENT_HELLO); + } + } + bool retry; + int bio_ret = ssl_handle_open_record(ssl, &retry, ret, consumed, alert); + if (bio_ret <= 0) { + return bio_ret; + } + if (retry) { + continue; + } + ssl->s3->read_buffer.DiscardConsumed(); + break; + } + + case ssl_hs_read_end_of_early_data: { + if (ssl->s3->hs->can_early_read) { + // While we are processing early data, the handshake returns early. + *out_early_return = true; + return 1; + } + hs->wait = ssl_hs_ok; + break; + } + + case ssl_hs_certificate_selection_pending: + ssl->s3->rwstate = SSL_CERTIFICATE_SELECTION_PENDING; + hs->wait = ssl_hs_ok; + return -1; + + case ssl_hs_handoff: + ssl->s3->rwstate = SSL_HANDOFF; + hs->wait = ssl_hs_ok; + return -1; + + case ssl_hs_x509_lookup: + ssl->s3->rwstate = SSL_X509_LOOKUP; + hs->wait = ssl_hs_ok; + return -1; + + case ssl_hs_channel_id_lookup: + ssl->s3->rwstate = SSL_CHANNEL_ID_LOOKUP; + hs->wait = ssl_hs_ok; + return -1; + + case ssl_hs_private_key_operation: + ssl->s3->rwstate = SSL_PRIVATE_KEY_OPERATION; + hs->wait = ssl_hs_ok; + return -1; + + case ssl_hs_pending_session: + ssl->s3->rwstate = SSL_PENDING_SESSION; + hs->wait = ssl_hs_ok; + return -1; + + case ssl_hs_pending_ticket: + ssl->s3->rwstate = SSL_PENDING_TICKET; + hs->wait = ssl_hs_ok; + return -1; + + case ssl_hs_certificate_verify: + ssl->s3->rwstate = SSL_CERTIFICATE_VERIFY; + hs->wait = ssl_hs_ok; + return -1; + + case ssl_hs_early_data_rejected: + ssl->s3->rwstate = SSL_EARLY_DATA_REJECTED; + // Cause |SSL_write| to start failing immediately. + hs->can_early_write = false; + return -1; + + case ssl_hs_early_return: + *out_early_return = true; + hs->wait = ssl_hs_ok; + return 1; + + case ssl_hs_ok: + break; + } + + // Run the state machine again. + hs->wait = ssl->do_handshake(hs); + if (hs->wait == ssl_hs_error) { + hs->error.reset(ERR_save_state()); + return -1; + } + if (hs->wait == ssl_hs_ok) { + // The handshake has completed. + *out_early_return = false; + return 1; + } + + // Otherwise, loop to the beginning and resolve what was blocking the + // handshake. + } +} + +} // namespace bssl diff --git a/FoodApp/Pods/BoringSSL-GRPC/ssl/handshake.cc.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/ssl/handshake.cc.grpc_back new file mode 100644 index 0000000..6432424 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/ssl/handshake.cc.grpc_back @@ -0,0 +1,630 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 + +#include "../crypto/internal.h" +#include "internal.h" + + +namespace bssl { + +SSL_HANDSHAKE::SSL_HANDSHAKE(SSL *ssl_arg) + : ssl(ssl_arg), + scts_requested(false), + needs_psk_binder(false), + received_hello_retry_request(false), + sent_hello_retry_request(false), + received_custom_extension(false), + handshake_finalized(false), + accept_psk_mode(false), + cert_request(false), + certificate_status_expected(false), + ocsp_stapling_requested(false), + should_ack_sni(false), + in_false_start(false), + in_early_data(false), + early_data_offered(false), + can_early_read(false), + can_early_write(false), + next_proto_neg_seen(false), + ticket_expected(false), + extended_master_secret(false), + pending_private_key_op(false), + grease_seeded(false) { +} + +SSL_HANDSHAKE::~SSL_HANDSHAKE() { + ssl->ctx->x509_method->hs_flush_cached_ca_names(this); +} + +UniquePtr ssl_handshake_new(SSL *ssl) { + UniquePtr hs = MakeUnique(ssl); + if (!hs || + !hs->transcript.Init()) { + return nullptr; + } + return hs; +} + +bool ssl_check_message_type(SSL *ssl, const SSLMessage &msg, int type) { + if (msg.type != type) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE); + OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_MESSAGE); + ERR_add_error_dataf("got type %d, wanted type %d", msg.type, type); + return false; + } + + return true; +} + +bool ssl_add_message_cbb(SSL *ssl, CBB *cbb) { + Array msg; + if (!ssl->method->finish_message(ssl, cbb, &msg) || + !ssl->method->add_message(ssl, std::move(msg))) { + return false; + } + + return true; +} + +size_t ssl_max_handshake_message_len(const SSL *ssl) { + // kMaxMessageLen is the default maximum message size for handshakes which do + // not accept peer certificate chains. + static const size_t kMaxMessageLen = 16384; + + if (SSL_in_init(ssl)) { + if ((!ssl->server || (ssl->verify_mode & SSL_VERIFY_PEER)) && + kMaxMessageLen < ssl->max_cert_list) { + return ssl->max_cert_list; + } + return kMaxMessageLen; + } + + if (ssl_protocol_version(ssl) < TLS1_3_VERSION) { + // In TLS 1.2 and below, the largest acceptable post-handshake message is + // a HelloRequest. + return 0; + } + + if (ssl->server) { + // The largest acceptable post-handshake message for a server is a + // KeyUpdate. We will never initiate post-handshake auth. + return 1; + } + + // Clients must accept NewSessionTicket, so allow the default size. + return kMaxMessageLen; +} + +bool ssl_hash_message(SSL_HANDSHAKE *hs, const SSLMessage &msg) { + // V2ClientHello messages are pre-hashed. + if (msg.is_v2_hello) { + return true; + } + + return hs->transcript.Update(msg.raw); +} + +int ssl_parse_extensions(const CBS *cbs, uint8_t *out_alert, + const SSL_EXTENSION_TYPE *ext_types, + size_t num_ext_types, int ignore_unknown) { + // Reset everything. + for (size_t i = 0; i < num_ext_types; i++) { + *ext_types[i].out_present = 0; + CBS_init(ext_types[i].out_data, NULL, 0); + } + + CBS copy = *cbs; + while (CBS_len(©) != 0) { + uint16_t type; + CBS data; + if (!CBS_get_u16(©, &type) || + !CBS_get_u16_length_prefixed(©, &data)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_PARSE_TLSEXT); + *out_alert = SSL_AD_DECODE_ERROR; + return 0; + } + + const SSL_EXTENSION_TYPE *ext_type = NULL; + for (size_t i = 0; i < num_ext_types; i++) { + if (type == ext_types[i].type) { + ext_type = &ext_types[i]; + break; + } + } + + if (ext_type == NULL) { + if (ignore_unknown) { + continue; + } + OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION); + *out_alert = SSL_AD_UNSUPPORTED_EXTENSION; + return 0; + } + + // Duplicate ext_types are forbidden. + if (*ext_type->out_present) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DUPLICATE_EXTENSION); + *out_alert = SSL_AD_ILLEGAL_PARAMETER; + return 0; + } + + *ext_type->out_present = 1; + *ext_type->out_data = data; + } + + return 1; +} + +static void set_crypto_buffer(CRYPTO_BUFFER **dest, CRYPTO_BUFFER *src) { + // TODO(davidben): Remove this helper once |SSL_SESSION| can use |UniquePtr| + // and |UniquePtr| has up_ref helpers. + CRYPTO_BUFFER_free(*dest); + *dest = src; + if (src != nullptr) { + CRYPTO_BUFFER_up_ref(src); + } +} + +enum ssl_verify_result_t ssl_verify_peer_cert(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + const SSL_SESSION *prev_session = ssl->s3->established_session.get(); + if (prev_session != NULL) { + // If renegotiating, the server must not change the server certificate. See + // https://mitls.org/pages/attacks/3SHAKE. We never resume on renegotiation, + // so this check is sufficient to ensure the reported peer certificate never + // changes on renegotiation. + assert(!ssl->server); + if (sk_CRYPTO_BUFFER_num(prev_session->certs) != + sk_CRYPTO_BUFFER_num(hs->new_session->certs)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_SERVER_CERT_CHANGED); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + return ssl_verify_invalid; + } + + for (size_t i = 0; i < sk_CRYPTO_BUFFER_num(hs->new_session->certs); i++) { + const CRYPTO_BUFFER *old_cert = + sk_CRYPTO_BUFFER_value(prev_session->certs, i); + const CRYPTO_BUFFER *new_cert = + sk_CRYPTO_BUFFER_value(hs->new_session->certs, i); + if (CRYPTO_BUFFER_len(old_cert) != CRYPTO_BUFFER_len(new_cert) || + OPENSSL_memcmp(CRYPTO_BUFFER_data(old_cert), + CRYPTO_BUFFER_data(new_cert), + CRYPTO_BUFFER_len(old_cert)) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_SERVER_CERT_CHANGED); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + return ssl_verify_invalid; + } + } + + // The certificate is identical, so we may skip re-verifying the + // certificate. Since we only authenticated the previous one, copy other + // authentication from the established session and ignore what was newly + // received. + set_crypto_buffer(&hs->new_session->ocsp_response, + prev_session->ocsp_response); + set_crypto_buffer(&hs->new_session->signed_cert_timestamp_list, + prev_session->signed_cert_timestamp_list); + hs->new_session->verify_result = prev_session->verify_result; + return ssl_verify_ok; + } + + uint8_t alert = SSL_AD_CERTIFICATE_UNKNOWN; + enum ssl_verify_result_t ret; + if (ssl->custom_verify_callback != nullptr) { + ret = ssl->custom_verify_callback(ssl, &alert); + switch (ret) { + case ssl_verify_ok: + hs->new_session->verify_result = X509_V_OK; + break; + case ssl_verify_invalid: + // If |SSL_VERIFY_NONE|, the error is non-fatal, but we keep the result. + if (ssl->verify_mode == SSL_VERIFY_NONE) { + ERR_clear_error(); + ret = ssl_verify_ok; + } + hs->new_session->verify_result = X509_V_ERR_APPLICATION_VERIFICATION; + break; + case ssl_verify_retry: + break; + } + } else { + ret = ssl->ctx->x509_method->session_verify_cert_chain( + hs->new_session.get(), ssl, &alert) + ? ssl_verify_ok + : ssl_verify_invalid; + } + + if (ret == ssl_verify_invalid) { + OPENSSL_PUT_ERROR(SSL, SSL_R_CERTIFICATE_VERIFY_FAILED); + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + } + + return ret; +} + +uint16_t ssl_get_grease_value(SSL_HANDSHAKE *hs, + enum ssl_grease_index_t index) { + // Draw entropy for all GREASE values at once. This avoids calling + // |RAND_bytes| repeatedly and makes the values consistent within a + // connection. The latter is so the second ClientHello matches after + // HelloRetryRequest and so supported_groups and key_shares are consistent. + if (!hs->grease_seeded) { + RAND_bytes(hs->grease_seed, sizeof(hs->grease_seed)); + hs->grease_seeded = true; + } + + // This generates a random value of the form 0xωaωa, for all 0 ≤ ω < 16. + uint16_t ret = hs->grease_seed[index]; + ret = (ret & 0xf0) | 0x0a; + ret |= ret << 8; + return ret; +} + +enum ssl_hs_wait_t ssl_get_finished(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + SSLMessage msg; + if (!ssl->method->get_message(ssl, &msg)) { + return ssl_hs_read_message; + } + + if (!ssl_check_message_type(ssl, msg, SSL3_MT_FINISHED)) { + return ssl_hs_error; + } + + // Snapshot the finished hash before incorporating the new message. + uint8_t finished[EVP_MAX_MD_SIZE]; + size_t finished_len; + if (!hs->transcript.GetFinishedMAC(finished, &finished_len, + SSL_get_session(ssl), !ssl->server) || + !ssl_hash_message(hs, msg)) { + return ssl_hs_error; + } + + int finished_ok = CBS_mem_equal(&msg.body, finished, finished_len); +#if defined(BORINGSSL_UNSAFE_FUZZER_MODE) + finished_ok = 1; +#endif + if (!finished_ok) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECRYPT_ERROR); + OPENSSL_PUT_ERROR(SSL, SSL_R_DIGEST_CHECK_FAILED); + return ssl_hs_error; + } + + // Copy the Finished so we can use it for renegotiation checks. + if (ssl->version != SSL3_VERSION) { + if (finished_len > sizeof(ssl->s3->previous_client_finished) || + finished_len > sizeof(ssl->s3->previous_server_finished)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return ssl_hs_error; + } + + if (ssl->server) { + OPENSSL_memcpy(ssl->s3->previous_client_finished, finished, finished_len); + ssl->s3->previous_client_finished_len = finished_len; + } else { + OPENSSL_memcpy(ssl->s3->previous_server_finished, finished, finished_len); + ssl->s3->previous_server_finished_len = finished_len; + } + } + + ssl->method->next_message(ssl); + return ssl_hs_ok; +} + +bool ssl_send_finished(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + const SSL_SESSION *session = SSL_get_session(ssl); + + uint8_t finished[EVP_MAX_MD_SIZE]; + size_t finished_len; + if (!hs->transcript.GetFinishedMAC(finished, &finished_len, session, + ssl->server)) { + return 0; + } + + // Log the master secret, if logging is enabled. + if (!ssl_log_secret(ssl, "CLIENT_RANDOM", + session->master_key, + session->master_key_length)) { + return 0; + } + + // Copy the Finished so we can use it for renegotiation checks. + if (ssl->version != SSL3_VERSION) { + if (finished_len > sizeof(ssl->s3->previous_client_finished) || + finished_len > sizeof(ssl->s3->previous_server_finished)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return 0; + } + + if (ssl->server) { + OPENSSL_memcpy(ssl->s3->previous_server_finished, finished, finished_len); + ssl->s3->previous_server_finished_len = finished_len; + } else { + OPENSSL_memcpy(ssl->s3->previous_client_finished, finished, finished_len); + ssl->s3->previous_client_finished_len = finished_len; + } + } + + ScopedCBB cbb; + CBB body; + if (!ssl->method->init_message(ssl, cbb.get(), &body, SSL3_MT_FINISHED) || + !CBB_add_bytes(&body, finished, finished_len) || + !ssl_add_message_cbb(ssl, cbb.get())) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return 0; + } + + return 1; +} + +bool ssl_output_cert_chain(SSL *ssl) { + ScopedCBB cbb; + CBB body; + if (!ssl->method->init_message(ssl, cbb.get(), &body, SSL3_MT_CERTIFICATE) || + !ssl_add_cert_chain(ssl, &body) || + !ssl_add_message_cbb(ssl, cbb.get())) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return false; + } + + return true; +} + +int ssl_run_handshake(SSL_HANDSHAKE *hs, bool *out_early_return) { + SSL *const ssl = hs->ssl; + for (;;) { + // Resolve the operation the handshake was waiting on. + switch (hs->wait) { + case ssl_hs_error: + ERR_restore_state(hs->error.get()); + return -1; + + case ssl_hs_flush: { + int ret = ssl->method->flush_flight(ssl); + if (ret <= 0) { + return ret; + } + break; + } + + case ssl_hs_read_server_hello: + case ssl_hs_read_message: + case ssl_hs_read_change_cipher_spec: { + uint8_t alert = SSL_AD_DECODE_ERROR; + size_t consumed = 0; + ssl_open_record_t ret; + if (hs->wait == ssl_hs_read_change_cipher_spec) { + ret = ssl_open_change_cipher_spec(ssl, &consumed, &alert, + ssl->s3->read_buffer.span()); + } else { + ret = ssl_open_handshake(ssl, &consumed, &alert, + ssl->s3->read_buffer.span()); + } + if (ret == ssl_open_record_error && + hs->wait == ssl_hs_read_server_hello) { + uint32_t err = ERR_peek_error(); + if (ERR_GET_LIB(err) == ERR_LIB_SSL && + ERR_GET_REASON(err) == SSL_R_SSLV3_ALERT_HANDSHAKE_FAILURE) { + // Add a dedicated error code to the queue for a handshake_failure + // alert in response to ClientHello. This matches NSS's client + // behavior and gives a better error on a (probable) failure to + // negotiate initial parameters. Note: this error code comes after + // the original one. + // + // See https://crbug.com/446505. + OPENSSL_PUT_ERROR(SSL, SSL_R_HANDSHAKE_FAILURE_ON_CLIENT_HELLO); + } + } + bool retry; + int bio_ret = ssl_handle_open_record(ssl, &retry, ret, consumed, alert); + if (bio_ret <= 0) { + return bio_ret; + } + if (retry) { + continue; + } + ssl->s3->read_buffer.DiscardConsumed(); + break; + } + + case ssl_hs_read_end_of_early_data: { + if (ssl->s3->hs->can_early_read) { + // While we are processing early data, the handshake returns early. + *out_early_return = true; + return 1; + } + hs->wait = ssl_hs_ok; + break; + } + + case ssl_hs_certificate_selection_pending: + ssl->s3->rwstate = SSL_CERTIFICATE_SELECTION_PENDING; + hs->wait = ssl_hs_ok; + return -1; + + case ssl_hs_handoff: + ssl->s3->rwstate = SSL_HANDOFF; + hs->wait = ssl_hs_ok; + return -1; + + case ssl_hs_x509_lookup: + ssl->s3->rwstate = SSL_X509_LOOKUP; + hs->wait = ssl_hs_ok; + return -1; + + case ssl_hs_channel_id_lookup: + ssl->s3->rwstate = SSL_CHANNEL_ID_LOOKUP; + hs->wait = ssl_hs_ok; + return -1; + + case ssl_hs_private_key_operation: + ssl->s3->rwstate = SSL_PRIVATE_KEY_OPERATION; + hs->wait = ssl_hs_ok; + return -1; + + case ssl_hs_pending_session: + ssl->s3->rwstate = SSL_PENDING_SESSION; + hs->wait = ssl_hs_ok; + return -1; + + case ssl_hs_pending_ticket: + ssl->s3->rwstate = SSL_PENDING_TICKET; + hs->wait = ssl_hs_ok; + return -1; + + case ssl_hs_certificate_verify: + ssl->s3->rwstate = SSL_CERTIFICATE_VERIFY; + hs->wait = ssl_hs_ok; + return -1; + + case ssl_hs_early_data_rejected: + ssl->s3->rwstate = SSL_EARLY_DATA_REJECTED; + // Cause |SSL_write| to start failing immediately. + hs->can_early_write = false; + return -1; + + case ssl_hs_early_return: + *out_early_return = true; + hs->wait = ssl_hs_ok; + return 1; + + case ssl_hs_ok: + break; + } + + // Run the state machine again. + hs->wait = ssl->do_handshake(hs); + if (hs->wait == ssl_hs_error) { + hs->error.reset(ERR_save_state()); + return -1; + } + if (hs->wait == ssl_hs_ok) { + // The handshake has completed. + *out_early_return = false; + return 1; + } + + // Otherwise, loop to the beginning and resolve what was blocking the + // handshake. + } +} + +} // namespace bssl diff --git a/FoodApp/Pods/BoringSSL-GRPC/ssl/handshake_client.cc b/FoodApp/Pods/BoringSSL-GRPC/ssl/handshake_client.cc new file mode 100644 index 0000000..8ac40cb --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/ssl/handshake_client.cc @@ -0,0 +1,1842 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../crypto/internal.h" +#include "internal.h" + + +namespace bssl { + +enum ssl_client_hs_state_t { + state_start_connect = 0, + state_enter_early_data, + state_read_hello_verify_request, + state_read_server_hello, + state_tls13, + state_read_server_certificate, + state_read_certificate_status, + state_verify_server_certificate, + state_read_server_key_exchange, + state_read_certificate_request, + state_read_server_hello_done, + state_send_client_certificate, + state_send_client_key_exchange, + state_send_client_certificate_verify, + state_send_client_finished, + state_finish_flight, + state_read_session_ticket, + state_process_change_cipher_spec, + state_read_server_finished, + state_finish_client_handshake, + state_done, +}; + +// ssl_get_client_disabled sets |*out_mask_a| and |*out_mask_k| to masks of +// disabled algorithms. +static void ssl_get_client_disabled(SSL *ssl, uint32_t *out_mask_a, + uint32_t *out_mask_k) { + *out_mask_a = 0; + *out_mask_k = 0; + + // PSK requires a client callback. + if (ssl->psk_client_callback == NULL) { + *out_mask_a |= SSL_aPSK; + *out_mask_k |= SSL_kPSK; + } +} + +static int ssl_write_client_cipher_list(SSL_HANDSHAKE *hs, CBB *out) { + SSL *const ssl = hs->ssl; + uint32_t mask_a, mask_k; + ssl_get_client_disabled(ssl, &mask_a, &mask_k); + + CBB child; + if (!CBB_add_u16_length_prefixed(out, &child)) { + return 0; + } + + // Add a fake cipher suite. See draft-davidben-tls-grease-01. + if (ssl->ctx->grease_enabled && + !CBB_add_u16(&child, ssl_get_grease_value(hs, ssl_grease_cipher))) { + return 0; + } + + // Add TLS 1.3 ciphers. Order ChaCha20-Poly1305 relative to AES-GCM based on + // hardware support. + if (hs->max_version >= TLS1_3_VERSION) { + if (!EVP_has_aes_hardware() && + !CBB_add_u16(&child, TLS1_CK_CHACHA20_POLY1305_SHA256 & 0xffff)) { + return 0; + } + if (!CBB_add_u16(&child, TLS1_CK_AES_128_GCM_SHA256 & 0xffff) || + !CBB_add_u16(&child, TLS1_CK_AES_256_GCM_SHA384 & 0xffff)) { + return 0; + } + if (EVP_has_aes_hardware() && + !CBB_add_u16(&child, TLS1_CK_CHACHA20_POLY1305_SHA256 & 0xffff)) { + return 0; + } + } + + if (hs->min_version < TLS1_3_VERSION) { + int any_enabled = 0; + for (const SSL_CIPHER *cipher : SSL_get_ciphers(ssl)) { + // Skip disabled ciphers + if ((cipher->algorithm_mkey & mask_k) || + (cipher->algorithm_auth & mask_a)) { + continue; + } + if (SSL_CIPHER_get_min_version(cipher) > hs->max_version || + SSL_CIPHER_get_max_version(cipher) < hs->min_version) { + continue; + } + any_enabled = 1; + if (!CBB_add_u16(&child, ssl_cipher_get_value(cipher))) { + return 0; + } + } + + // If all ciphers were disabled, return the error to the caller. + if (!any_enabled && hs->max_version < TLS1_3_VERSION) { + OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CIPHERS_AVAILABLE); + return 0; + } + } + + // For SSLv3, the SCSV is added. Otherwise the renegotiation extension is + // added. + if (hs->max_version == SSL3_VERSION && + !ssl->s3->initial_handshake_complete) { + if (!CBB_add_u16(&child, SSL3_CK_SCSV & 0xffff)) { + return 0; + } + } + + if (ssl->mode & SSL_MODE_SEND_FALLBACK_SCSV) { + if (!CBB_add_u16(&child, SSL3_CK_FALLBACK_SCSV & 0xffff)) { + return 0; + } + } + + return CBB_flush(out); +} + +int ssl_write_client_hello(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + ScopedCBB cbb; + CBB body; + if (!ssl->method->init_message(ssl, cbb.get(), &body, SSL3_MT_CLIENT_HELLO)) { + return 0; + } + + CBB child; + if (!CBB_add_u16(&body, hs->client_version) || + !CBB_add_bytes(&body, ssl->s3->client_random, SSL3_RANDOM_SIZE) || + !CBB_add_u8_length_prefixed(&body, &child)) { + return 0; + } + + // Do not send a session ID on renegotiation. + if (!ssl->s3->initial_handshake_complete && + !CBB_add_bytes(&child, hs->session_id, hs->session_id_len)) { + return 0; + } + + if (SSL_is_dtls(ssl)) { + if (!CBB_add_u8_length_prefixed(&body, &child) || + !CBB_add_bytes(&child, ssl->d1->cookie, ssl->d1->cookie_len)) { + return 0; + } + } + + size_t header_len = + SSL_is_dtls(ssl) ? DTLS1_HM_HEADER_LENGTH : SSL3_HM_HEADER_LENGTH; + if (!ssl_write_client_cipher_list(hs, &body) || + !CBB_add_u8(&body, 1 /* one compression method */) || + !CBB_add_u8(&body, 0 /* null compression */) || + !ssl_add_clienthello_tlsext(hs, &body, header_len + CBB_len(&body))) { + return 0; + } + + Array msg; + if (!ssl->method->finish_message(ssl, cbb.get(), &msg)) { + return 0; + } + + // Now that the length prefixes have been computed, fill in the placeholder + // PSK binder. + if (hs->needs_psk_binder && + !tls13_write_psk_binder(hs, msg.data(), msg.size())) { + return 0; + } + + return ssl->method->add_message(ssl, std::move(msg)); +} + +static bool parse_supported_versions(SSL_HANDSHAKE *hs, uint16_t *version, + const CBS *in) { + // If the outer version is not TLS 1.2, or there is no extensions block, use + // the outer version. + if (*version != TLS1_2_VERSION || CBS_len(in) == 0) { + return true; + } + + SSL *const ssl = hs->ssl; + CBS copy = *in, extensions; + if (!CBS_get_u16_length_prefixed(©, &extensions) || + CBS_len(©) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return false; + } + + bool have_supported_versions; + CBS supported_versions; + const SSL_EXTENSION_TYPE ext_types[] = { + {TLSEXT_TYPE_supported_versions, &have_supported_versions, + &supported_versions}, + }; + + uint8_t alert = SSL_AD_DECODE_ERROR; + if (!ssl_parse_extensions(&extensions, &alert, ext_types, + OPENSSL_ARRAY_SIZE(ext_types), + 1 /* ignore unknown */)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + return false; + } + + // Override the outer version with the extension, if present. + if (have_supported_versions && + (!CBS_get_u16(&supported_versions, version) || + CBS_len(&supported_versions) != 0)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return false; + } + + return true; +} + +static enum ssl_hs_wait_t do_start_connect(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + + ssl_do_info_callback(ssl, SSL_CB_HANDSHAKE_START, 1); + // |session_reused| must be reset in case this is a renegotiation. + ssl->s3->session_reused = false; + + // Freeze the version range. + if (!ssl_get_version_range(ssl, &hs->min_version, &hs->max_version)) { + return ssl_hs_error; + } + + // SSL 3.0 ClientHellos should use SSL 3.0 not TLS 1.0, for the record-layer + // version. + if (hs->max_version == SSL3_VERSION) { + ssl->s3->aead_write_ctx->SetVersionIfNullCipher(SSL3_VERSION); + } + + // Always advertise the ClientHello version from the original maximum version, + // even on renegotiation. The static RSA key exchange uses this field, and + // some servers fail when it changes across handshakes. + if (SSL_is_dtls(hs->ssl)) { + hs->client_version = + hs->max_version >= TLS1_2_VERSION ? DTLS1_2_VERSION : DTLS1_VERSION; + } else { + hs->client_version = + hs->max_version >= TLS1_2_VERSION ? TLS1_2_VERSION : hs->max_version; + } + + // If the configured session has expired or was created at a disabled + // version, drop it. + if (ssl->session != NULL) { + if (ssl->session->is_server || + !ssl_supports_version(hs, ssl->session->ssl_version) || + (ssl->session->session_id_length == 0 && + ssl->session->tlsext_ticklen == 0) || + ssl->session->not_resumable || + !ssl_session_is_time_valid(ssl, ssl->session)) { + ssl_set_session(ssl, NULL); + } + } + + if (!RAND_bytes(ssl->s3->client_random, sizeof(ssl->s3->client_random))) { + return ssl_hs_error; + } + + // Initialize a random session ID for the experimental TLS 1.3 variant + // requiring a session id. + if (ssl->session != nullptr && + !ssl->s3->initial_handshake_complete && + ssl->session->session_id_length > 0) { + hs->session_id_len = ssl->session->session_id_length; + OPENSSL_memcpy(hs->session_id, ssl->session->session_id, + hs->session_id_len); + } else if (hs->max_version >= TLS1_3_VERSION) { + hs->session_id_len = sizeof(hs->session_id); + if (!RAND_bytes(hs->session_id, hs->session_id_len)) { + return ssl_hs_error; + } + } + + if (!ssl_write_client_hello(hs)) { + return ssl_hs_error; + } + + hs->state = state_enter_early_data; + return ssl_hs_flush; +} + +static enum ssl_hs_wait_t do_enter_early_data(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + + if (SSL_is_dtls(ssl)) { + hs->state = state_read_hello_verify_request; + return ssl_hs_ok; + } + + if (!hs->early_data_offered) { + hs->state = state_read_server_hello; + return ssl_hs_ok; + } + + ssl->s3->aead_write_ctx->SetVersionIfNullCipher(ssl->session->ssl_version); + if (!ssl->method->add_change_cipher_spec(ssl)) { + return ssl_hs_error; + } + + if (!tls13_init_early_key_schedule(hs, ssl->session->master_key, + ssl->session->master_key_length) || + !tls13_derive_early_secrets(hs) || + !tls13_set_traffic_key(ssl, evp_aead_seal, hs->early_traffic_secret, + hs->hash_len)) { + return ssl_hs_error; + } + + // Stash the early data session, so connection properties may be queried out + // of it. + hs->in_early_data = true; + SSL_SESSION_up_ref(ssl->session); + hs->early_session.reset(ssl->session); + hs->can_early_write = true; + + hs->state = state_read_server_hello; + return ssl_hs_early_return; +} + +static enum ssl_hs_wait_t do_read_hello_verify_request(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + + assert(SSL_is_dtls(ssl)); + + SSLMessage msg; + if (!ssl->method->get_message(ssl, &msg)) { + return ssl_hs_read_message; + } + + if (msg.type != DTLS1_MT_HELLO_VERIFY_REQUEST) { + hs->state = state_read_server_hello; + return ssl_hs_ok; + } + + CBS hello_verify_request = msg.body, cookie; + uint16_t server_version; + if (!CBS_get_u16(&hello_verify_request, &server_version) || + !CBS_get_u8_length_prefixed(&hello_verify_request, &cookie) || + CBS_len(&cookie) > sizeof(ssl->d1->cookie) || + CBS_len(&hello_verify_request) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return ssl_hs_error; + } + + OPENSSL_memcpy(ssl->d1->cookie, CBS_data(&cookie), CBS_len(&cookie)); + ssl->d1->cookie_len = CBS_len(&cookie); + + ssl->method->next_message(ssl); + + // DTLS resets the handshake buffer after HelloVerifyRequest. + if (!hs->transcript.Init()) { + return ssl_hs_error; + } + + if (!ssl_write_client_hello(hs)) { + return ssl_hs_error; + } + + hs->state = state_read_server_hello; + return ssl_hs_flush; +} + +static enum ssl_hs_wait_t do_read_server_hello(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + SSLMessage msg; + if (!ssl->method->get_message(ssl, &msg)) { + return ssl_hs_read_server_hello; + } + + if (!ssl_check_message_type(ssl, msg, SSL3_MT_SERVER_HELLO)) { + return ssl_hs_error; + } + + CBS server_hello = msg.body, server_random, session_id; + uint16_t server_version, cipher_suite; + uint8_t compression_method; + if (!CBS_get_u16(&server_hello, &server_version) || + !CBS_get_bytes(&server_hello, &server_random, SSL3_RANDOM_SIZE) || + !CBS_get_u8_length_prefixed(&server_hello, &session_id) || + CBS_len(&session_id) > SSL3_SESSION_ID_SIZE || + !CBS_get_u16(&server_hello, &cipher_suite) || + !CBS_get_u8(&server_hello, &compression_method)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return ssl_hs_error; + } + + // Use the supported_versions extension if applicable. + if (!parse_supported_versions(hs, &server_version, &server_hello)) { + return ssl_hs_error; + } + + if (!ssl_supports_version(hs, server_version)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_UNSUPPORTED_PROTOCOL); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_PROTOCOL_VERSION); + return ssl_hs_error; + } + + assert(ssl->s3->have_version == ssl->s3->initial_handshake_complete); + if (!ssl->s3->have_version) { + ssl->version = server_version; + // At this point, the connection's version is known and ssl->version is + // fixed. Begin enforcing the record-layer version. + ssl->s3->have_version = true; + ssl->s3->aead_write_ctx->SetVersionIfNullCipher(ssl->version); + } else if (server_version != ssl->version) { + OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_SSL_VERSION); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_PROTOCOL_VERSION); + return ssl_hs_error; + } + + if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) { + hs->state = state_tls13; + return ssl_hs_ok; + } + + // Clear some TLS 1.3 state that no longer needs to be retained. + hs->key_share.reset(); + hs->key_share_bytes.Reset(); + + // A TLS 1.2 server would not know to skip the early data we offered. Report + // an error code sooner. The caller may use this error code to implement the + // fallback described in draft-ietf-tls-tls13-18 appendix C.3. + if (hs->early_data_offered) { + OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_VERSION_ON_EARLY_DATA); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_PROTOCOL_VERSION); + return ssl_hs_error; + } + + // Copy over the server random. + OPENSSL_memcpy(ssl->s3->server_random, CBS_data(&server_random), + SSL3_RANDOM_SIZE); + + // Measure, but do not enforce, the TLS 1.3 anti-downgrade feature, with a + // different value. + // + // For draft TLS 1.3 versions, it is not safe to deploy this feature. However, + // some TLS terminators are non-compliant and copy the origin server's value, + // so we wish to measure eventual compatibility impact. + if (!ssl->s3->initial_handshake_complete && + hs->max_version >= TLS1_3_VERSION && + OPENSSL_memcmp(ssl->s3->server_random + SSL3_RANDOM_SIZE - + sizeof(kDraftDowngradeRandom), + kDraftDowngradeRandom, + sizeof(kDraftDowngradeRandom)) == 0) { + ssl->s3->draft_downgrade = true; + } + + if (!ssl->s3->initial_handshake_complete && ssl->session != NULL && + ssl->session->session_id_length != 0 && + CBS_mem_equal(&session_id, ssl->session->session_id, + ssl->session->session_id_length)) { + ssl->s3->session_reused = true; + } else { + // The server may also have echoed back the TLS 1.3 compatibility mode + // session ID. As we know this is not a session the server knows about, any + // server resuming it is in error. Reject the first connection + // deterministicly, rather than installing an invalid session into the + // session cache. https://crbug.com/796910 + if (hs->session_id_len != 0 && + CBS_mem_equal(&session_id, hs->session_id, hs->session_id_len)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_SERVER_ECHOED_INVALID_SESSION_ID); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + return ssl_hs_error; + } + + // The session wasn't resumed. Create a fresh SSL_SESSION to + // fill out. + ssl_set_session(ssl, NULL); + if (!ssl_get_new_session(hs, 0 /* client */)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return ssl_hs_error; + } + // Note: session_id could be empty. + hs->new_session->session_id_length = CBS_len(&session_id); + OPENSSL_memcpy(hs->new_session->session_id, CBS_data(&session_id), + CBS_len(&session_id)); + } + + const SSL_CIPHER *cipher = SSL_get_cipher_by_value(cipher_suite); + if (cipher == NULL) { + // unknown cipher + OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_CIPHER_RETURNED); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + return ssl_hs_error; + } + + // The cipher must be allowed in the selected version and enabled. + uint32_t mask_a, mask_k; + ssl_get_client_disabled(ssl, &mask_a, &mask_k); + if ((cipher->algorithm_mkey & mask_k) || (cipher->algorithm_auth & mask_a) || + SSL_CIPHER_get_min_version(cipher) > ssl_protocol_version(ssl) || + SSL_CIPHER_get_max_version(cipher) < ssl_protocol_version(ssl) || + !sk_SSL_CIPHER_find(SSL_get_ciphers(ssl), NULL, cipher)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CIPHER_RETURNED); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + return ssl_hs_error; + } + + if (ssl->session != NULL) { + if (ssl->session->ssl_version != ssl->version) { + OPENSSL_PUT_ERROR(SSL, SSL_R_OLD_SESSION_VERSION_NOT_RETURNED); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + return ssl_hs_error; + } + if (ssl->session->cipher != cipher) { + OPENSSL_PUT_ERROR(SSL, SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + return ssl_hs_error; + } + if (!ssl_session_is_context_valid(ssl, ssl->session)) { + // This is actually a client application bug. + OPENSSL_PUT_ERROR(SSL, + SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + return ssl_hs_error; + } + } else { + hs->new_session->cipher = cipher; + } + hs->new_cipher = cipher; + + // Now that the cipher is known, initialize the handshake hash and hash the + // ServerHello. + if (!hs->transcript.InitHash(ssl_protocol_version(ssl), hs->new_cipher) || + !ssl_hash_message(hs, msg)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return ssl_hs_error; + } + + // If doing a full handshake, the server may request a client certificate + // which requires hashing the handshake transcript. Otherwise, the handshake + // buffer may be released. + if (ssl->session != NULL || + !ssl_cipher_uses_certificate_auth(hs->new_cipher)) { + hs->transcript.FreeBuffer(); + } + + // Only the NULL compression algorithm is supported. + if (compression_method != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + return ssl_hs_error; + } + + // TLS extensions + if (!ssl_parse_serverhello_tlsext(hs, &server_hello)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_PARSE_TLSEXT); + return ssl_hs_error; + } + + // There should be nothing left over in the record. + if (CBS_len(&server_hello) != 0) { + // wrong packet length + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return ssl_hs_error; + } + + if (ssl->session != NULL && + hs->extended_master_secret != ssl->session->extended_master_secret) { + if (ssl->session->extended_master_secret) { + OPENSSL_PUT_ERROR(SSL, SSL_R_RESUMED_EMS_SESSION_WITHOUT_EMS_EXTENSION); + } else { + OPENSSL_PUT_ERROR(SSL, SSL_R_RESUMED_NON_EMS_SESSION_WITH_EMS_EXTENSION); + } + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); + return ssl_hs_error; + } + + if (ssl->token_binding_negotiated && + (!hs->extended_master_secret || !ssl->s3->send_connection_binding)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_NEGOTIATED_TB_WITHOUT_EMS_OR_RI); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNSUPPORTED_EXTENSION); + return ssl_hs_error; + } + + ssl->method->next_message(ssl); + + if (ssl->session != NULL) { + hs->state = state_read_session_ticket; + return ssl_hs_ok; + } + + hs->state = state_read_server_certificate; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_tls13(SSL_HANDSHAKE *hs) { + enum ssl_hs_wait_t wait = tls13_client_handshake(hs); + if (wait == ssl_hs_ok) { + hs->state = state_finish_client_handshake; + return ssl_hs_ok; + } + + return wait; +} + +static enum ssl_hs_wait_t do_read_server_certificate(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + + if (!ssl_cipher_uses_certificate_auth(hs->new_cipher)) { + hs->state = state_read_certificate_status; + return ssl_hs_ok; + } + + SSLMessage msg; + if (!ssl->method->get_message(ssl, &msg)) { + return ssl_hs_read_message; + } + + if (!ssl_check_message_type(ssl, msg, SSL3_MT_CERTIFICATE) || + !ssl_hash_message(hs, msg)) { + return ssl_hs_error; + } + + CBS body = msg.body; + uint8_t alert = SSL_AD_DECODE_ERROR; + UniquePtr chain; + if (!ssl_parse_cert_chain(&alert, &chain, &hs->peer_pubkey, NULL, &body, + ssl->ctx->pool)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + return ssl_hs_error; + } + sk_CRYPTO_BUFFER_pop_free(hs->new_session->certs, CRYPTO_BUFFER_free); + hs->new_session->certs = chain.release(); + + if (sk_CRYPTO_BUFFER_num(hs->new_session->certs) == 0 || + CBS_len(&body) != 0 || + !ssl->ctx->x509_method->session_cache_objects(hs->new_session.get())) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return ssl_hs_error; + } + + if (!ssl_check_leaf_certificate( + hs, hs->peer_pubkey.get(), + sk_CRYPTO_BUFFER_value(hs->new_session->certs, 0))) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + return ssl_hs_error; + } + + ssl->method->next_message(ssl); + + hs->state = state_read_certificate_status; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_read_certificate_status(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + + if (!hs->certificate_status_expected) { + hs->state = state_verify_server_certificate; + return ssl_hs_ok; + } + + SSLMessage msg; + if (!ssl->method->get_message(ssl, &msg)) { + return ssl_hs_read_message; + } + + if (msg.type != SSL3_MT_CERTIFICATE_STATUS) { + // A server may send status_request in ServerHello and then change its mind + // about sending CertificateStatus. + hs->state = state_verify_server_certificate; + return ssl_hs_ok; + } + + if (!ssl_hash_message(hs, msg)) { + return ssl_hs_error; + } + + CBS certificate_status = msg.body, ocsp_response; + uint8_t status_type; + if (!CBS_get_u8(&certificate_status, &status_type) || + status_type != TLSEXT_STATUSTYPE_ocsp || + !CBS_get_u24_length_prefixed(&certificate_status, &ocsp_response) || + CBS_len(&ocsp_response) == 0 || + CBS_len(&certificate_status) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return ssl_hs_error; + } + + CRYPTO_BUFFER_free(hs->new_session->ocsp_response); + hs->new_session->ocsp_response = + CRYPTO_BUFFER_new_from_CBS(&ocsp_response, ssl->ctx->pool); + if (hs->new_session->ocsp_response == nullptr) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return ssl_hs_error; + } + + ssl->method->next_message(ssl); + + hs->state = state_verify_server_certificate; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_verify_server_certificate(SSL_HANDSHAKE *hs) { + if (!ssl_cipher_uses_certificate_auth(hs->new_cipher)) { + hs->state = state_read_server_key_exchange; + return ssl_hs_ok; + } + + switch (ssl_verify_peer_cert(hs)) { + case ssl_verify_ok: + break; + case ssl_verify_invalid: + return ssl_hs_error; + case ssl_verify_retry: + hs->state = state_verify_server_certificate; + return ssl_hs_certificate_verify; + } + + hs->state = state_read_server_key_exchange; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_read_server_key_exchange(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + SSLMessage msg; + if (!ssl->method->get_message(ssl, &msg)) { + return ssl_hs_read_message; + } + + if (msg.type != SSL3_MT_SERVER_KEY_EXCHANGE) { + // Some ciphers (pure PSK) have an optional ServerKeyExchange message. + if (ssl_cipher_requires_server_key_exchange(hs->new_cipher)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_MESSAGE); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE); + return ssl_hs_error; + } + + hs->state = state_read_certificate_request; + return ssl_hs_ok; + } + + if (!ssl_hash_message(hs, msg)) { + return ssl_hs_error; + } + + uint32_t alg_k = hs->new_cipher->algorithm_mkey; + uint32_t alg_a = hs->new_cipher->algorithm_auth; + CBS server_key_exchange = msg.body; + if (alg_a & SSL_aPSK) { + CBS psk_identity_hint; + + // Each of the PSK key exchanges begins with a psk_identity_hint. + if (!CBS_get_u16_length_prefixed(&server_key_exchange, + &psk_identity_hint)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return ssl_hs_error; + } + + // Store the PSK identity hint for the ClientKeyExchange. Assume that the + // maximum length of a PSK identity hint can be as long as the maximum + // length of a PSK identity. Also do not allow NULL characters; identities + // are saved as C strings. + // + // TODO(davidben): Should invalid hints be ignored? It's a hint rather than + // a specific identity. + if (CBS_len(&psk_identity_hint) > PSK_MAX_IDENTITY_LEN || + CBS_contains_zero_byte(&psk_identity_hint)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DATA_LENGTH_TOO_LONG); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); + return ssl_hs_error; + } + + // Save non-empty identity hints as a C string. Empty identity hints we + // treat as missing. Plain PSK makes it possible to send either no hint + // (omit ServerKeyExchange) or an empty hint, while ECDHE_PSK can only spell + // empty hint. Having different capabilities is odd, so we interpret empty + // and missing as identical. + char *raw = nullptr; + if (CBS_len(&psk_identity_hint) != 0 && + !CBS_strdup(&psk_identity_hint, &raw)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return ssl_hs_error; + } + hs->peer_psk_identity_hint.reset(raw); + } + + if (alg_k & SSL_kECDHE) { + // Parse the server parameters. + uint8_t group_type; + uint16_t group_id; + CBS point; + if (!CBS_get_u8(&server_key_exchange, &group_type) || + group_type != NAMED_CURVE_TYPE || + !CBS_get_u16(&server_key_exchange, &group_id) || + !CBS_get_u8_length_prefixed(&server_key_exchange, &point)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return ssl_hs_error; + } + hs->new_session->group_id = group_id; + + // Ensure the group is consistent with preferences. + if (!tls1_check_group_id(ssl, group_id)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CURVE); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + return ssl_hs_error; + } + + // Initialize ECDH and save the peer public key for later. + hs->key_share = SSLKeyShare::Create(group_id); + if (!hs->key_share || + !hs->peer_key.CopyFrom(point)) { + return ssl_hs_error; + } + } else if (!(alg_k & SSL_kPSK)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_MESSAGE); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE); + return ssl_hs_error; + } + + // At this point, |server_key_exchange| contains the signature, if any, while + // |msg.body| contains the entire message. From that, derive a CBS containing + // just the parameter. + CBS parameter; + CBS_init(¶meter, CBS_data(&msg.body), + CBS_len(&msg.body) - CBS_len(&server_key_exchange)); + + // ServerKeyExchange should be signed by the server's public key. + if (ssl_cipher_uses_certificate_auth(hs->new_cipher)) { + uint16_t signature_algorithm = 0; + if (ssl_protocol_version(ssl) >= TLS1_2_VERSION) { + if (!CBS_get_u16(&server_key_exchange, &signature_algorithm)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return ssl_hs_error; + } + uint8_t alert = SSL_AD_DECODE_ERROR; + if (!tls12_check_peer_sigalg(ssl, &alert, signature_algorithm)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + return ssl_hs_error; + } + hs->new_session->peer_signature_algorithm = signature_algorithm; + } else if (!tls1_get_legacy_signature_algorithm(&signature_algorithm, + hs->peer_pubkey.get())) { + OPENSSL_PUT_ERROR(SSL, SSL_R_PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNSUPPORTED_CERTIFICATE); + return ssl_hs_error; + } + + // The last field in |server_key_exchange| is the signature. + CBS signature; + if (!CBS_get_u16_length_prefixed(&server_key_exchange, &signature) || + CBS_len(&server_key_exchange) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return ssl_hs_error; + } + + ScopedCBB transcript; + Array transcript_data; + if (!CBB_init(transcript.get(), + 2 * SSL3_RANDOM_SIZE + CBS_len(¶meter)) || + !CBB_add_bytes(transcript.get(), ssl->s3->client_random, + SSL3_RANDOM_SIZE) || + !CBB_add_bytes(transcript.get(), ssl->s3->server_random, + SSL3_RANDOM_SIZE) || + !CBB_add_bytes(transcript.get(), CBS_data(¶meter), + CBS_len(¶meter)) || + !CBBFinishArray(transcript.get(), &transcript_data)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return ssl_hs_error; + } + + bool sig_ok = ssl_public_key_verify(ssl, signature, signature_algorithm, + hs->peer_pubkey.get(), transcript_data); +#if defined(BORINGSSL_UNSAFE_FUZZER_MODE) + sig_ok = true; + ERR_clear_error(); +#endif + if (!sig_ok) { + // bad signature + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SIGNATURE); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECRYPT_ERROR); + return ssl_hs_error; + } + } else { + // PSK ciphers are the only supported certificate-less ciphers. + assert(alg_a == SSL_aPSK); + + if (CBS_len(&server_key_exchange) > 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_EXTRA_DATA_IN_MESSAGE); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return ssl_hs_error; + } + } + + ssl->method->next_message(ssl); + hs->state = state_read_certificate_request; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_read_certificate_request(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + + if (!ssl_cipher_uses_certificate_auth(hs->new_cipher)) { + hs->state = state_read_server_hello_done; + return ssl_hs_ok; + } + + SSLMessage msg; + if (!ssl->method->get_message(ssl, &msg)) { + return ssl_hs_read_message; + } + + if (msg.type == SSL3_MT_SERVER_HELLO_DONE) { + // If we get here we don't need the handshake buffer as we won't be doing + // client auth. + hs->transcript.FreeBuffer(); + hs->state = state_read_server_hello_done; + return ssl_hs_ok; + } + + if (!ssl_check_message_type(ssl, msg, SSL3_MT_CERTIFICATE_REQUEST) || + !ssl_hash_message(hs, msg)) { + return ssl_hs_error; + } + + // Get the certificate types. + CBS body = msg.body, certificate_types; + if (!CBS_get_u8_length_prefixed(&body, &certificate_types)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + return ssl_hs_error; + } + + if (!hs->certificate_types.CopyFrom(certificate_types)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return ssl_hs_error; + } + + if (ssl_protocol_version(ssl) >= TLS1_2_VERSION) { + CBS supported_signature_algorithms; + if (!CBS_get_u16_length_prefixed(&body, &supported_signature_algorithms) || + !tls1_parse_peer_sigalgs(hs, &supported_signature_algorithms)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + return ssl_hs_error; + } + } + + uint8_t alert = SSL_AD_DECODE_ERROR; + UniquePtr ca_names = + ssl_parse_client_CA_list(ssl, &alert, &body); + if (!ca_names) { + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + return ssl_hs_error; + } + + if (CBS_len(&body) != 0) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + return ssl_hs_error; + } + + hs->cert_request = true; + hs->ca_names = std::move(ca_names); + ssl->ctx->x509_method->hs_flush_cached_ca_names(hs); + + ssl->method->next_message(ssl); + hs->state = state_read_server_hello_done; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_read_server_hello_done(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + SSLMessage msg; + if (!ssl->method->get_message(ssl, &msg)) { + return ssl_hs_read_message; + } + + if (!ssl_check_message_type(ssl, msg, SSL3_MT_SERVER_HELLO_DONE) || + !ssl_hash_message(hs, msg)) { + return ssl_hs_error; + } + + // ServerHelloDone is empty. + if (CBS_len(&msg.body) != 0) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + return ssl_hs_error; + } + + ssl->method->next_message(ssl); + hs->state = state_send_client_certificate; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_send_client_certificate(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + + // The peer didn't request a certificate. + if (!hs->cert_request) { + hs->state = state_send_client_key_exchange; + return ssl_hs_ok; + } + + // Call cert_cb to update the certificate. + if (ssl->cert->cert_cb != NULL) { + int rv = ssl->cert->cert_cb(ssl, ssl->cert->cert_cb_arg); + if (rv == 0) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + OPENSSL_PUT_ERROR(SSL, SSL_R_CERT_CB_ERROR); + return ssl_hs_error; + } + if (rv < 0) { + hs->state = state_send_client_certificate; + return ssl_hs_x509_lookup; + } + } + + if (!ssl_has_certificate(ssl)) { + // Without a client certificate, the handshake buffer may be released. + hs->transcript.FreeBuffer(); + + // In SSL 3.0, the Certificate message is replaced with a warning alert. + if (ssl->version == SSL3_VERSION) { + if (!ssl->method->add_alert(ssl, SSL3_AL_WARNING, + SSL_AD_NO_CERTIFICATE)) { + return ssl_hs_error; + } + hs->state = state_send_client_key_exchange; + return ssl_hs_ok; + } + } + + if (!ssl_on_certificate_selected(hs) || + !ssl_output_cert_chain(ssl)) { + return ssl_hs_error; + } + + + hs->state = state_send_client_key_exchange; + return ssl_hs_ok; +} + +static_assert(sizeof(size_t) >= sizeof(unsigned), + "size_t is smaller than unsigned"); + +static enum ssl_hs_wait_t do_send_client_key_exchange(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + ScopedCBB cbb; + CBB body; + if (!ssl->method->init_message(ssl, cbb.get(), &body, + SSL3_MT_CLIENT_KEY_EXCHANGE)) { + return ssl_hs_error; + } + + Array pms; + uint32_t alg_k = hs->new_cipher->algorithm_mkey; + uint32_t alg_a = hs->new_cipher->algorithm_auth; + + // If using a PSK key exchange, prepare the pre-shared key. + unsigned psk_len = 0; + uint8_t psk[PSK_MAX_PSK_LEN]; + if (alg_a & SSL_aPSK) { + if (ssl->psk_client_callback == NULL) { + OPENSSL_PUT_ERROR(SSL, SSL_R_PSK_NO_CLIENT_CB); + return ssl_hs_error; + } + + char identity[PSK_MAX_IDENTITY_LEN + 1]; + OPENSSL_memset(identity, 0, sizeof(identity)); + psk_len = + ssl->psk_client_callback(ssl, hs->peer_psk_identity_hint.get(), + identity, sizeof(identity), psk, sizeof(psk)); + if (psk_len == 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_PSK_IDENTITY_NOT_FOUND); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); + return ssl_hs_error; + } + assert(psk_len <= PSK_MAX_PSK_LEN); + + OPENSSL_free(hs->new_session->psk_identity); + hs->new_session->psk_identity = BUF_strdup(identity); + if (hs->new_session->psk_identity == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return ssl_hs_error; + } + + // Write out psk_identity. + CBB child; + if (!CBB_add_u16_length_prefixed(&body, &child) || + !CBB_add_bytes(&child, (const uint8_t *)identity, + OPENSSL_strnlen(identity, sizeof(identity))) || + !CBB_flush(&body)) { + return ssl_hs_error; + } + } + + // Depending on the key exchange method, compute |pms|. + if (alg_k & SSL_kRSA) { + if (!pms.Init(SSL_MAX_MASTER_KEY_LENGTH)) { + return ssl_hs_error; + } + + RSA *rsa = EVP_PKEY_get0_RSA(hs->peer_pubkey.get()); + if (rsa == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return ssl_hs_error; + } + + pms[0] = hs->client_version >> 8; + pms[1] = hs->client_version & 0xff; + if (!RAND_bytes(&pms[2], SSL_MAX_MASTER_KEY_LENGTH - 2)) { + return ssl_hs_error; + } + + CBB child, *enc_pms = &body; + size_t enc_pms_len; + // In TLS, there is a length prefix. + if (ssl->version > SSL3_VERSION) { + if (!CBB_add_u16_length_prefixed(&body, &child)) { + return ssl_hs_error; + } + enc_pms = &child; + } + + uint8_t *ptr; + if (!CBB_reserve(enc_pms, &ptr, RSA_size(rsa)) || + !RSA_encrypt(rsa, &enc_pms_len, ptr, RSA_size(rsa), pms.data(), + pms.size(), RSA_PKCS1_PADDING) || + !CBB_did_write(enc_pms, enc_pms_len) || + !CBB_flush(&body)) { + return ssl_hs_error; + } + } else if (alg_k & SSL_kECDHE) { + // Generate a keypair and serialize the public half. + CBB child; + if (!CBB_add_u8_length_prefixed(&body, &child)) { + return ssl_hs_error; + } + + // Compute the premaster. + uint8_t alert = SSL_AD_DECODE_ERROR; + if (!hs->key_share->Accept(&child, &pms, &alert, hs->peer_key)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + return ssl_hs_error; + } + if (!CBB_flush(&body)) { + return ssl_hs_error; + } + + // The key exchange state may now be discarded. + hs->key_share.reset(); + hs->peer_key.Reset(); + } else if (alg_k & SSL_kPSK) { + // For plain PSK, other_secret is a block of 0s with the same length as + // the pre-shared key. + if (!pms.Init(psk_len)) { + return ssl_hs_error; + } + OPENSSL_memset(pms.data(), 0, pms.size()); + } else { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return ssl_hs_error; + } + + // For a PSK cipher suite, other_secret is combined with the pre-shared + // key. + if (alg_a & SSL_aPSK) { + ScopedCBB pms_cbb; + CBB child; + if (!CBB_init(pms_cbb.get(), 2 + psk_len + 2 + pms.size()) || + !CBB_add_u16_length_prefixed(pms_cbb.get(), &child) || + !CBB_add_bytes(&child, pms.data(), pms.size()) || + !CBB_add_u16_length_prefixed(pms_cbb.get(), &child) || + !CBB_add_bytes(&child, psk, psk_len) || + !CBBFinishArray(pms_cbb.get(), &pms)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return ssl_hs_error; + } + } + + // The message must be added to the finished hash before calculating the + // master secret. + if (!ssl_add_message_cbb(ssl, cbb.get())) { + return ssl_hs_error; + } + + hs->new_session->master_key_length = + tls1_generate_master_secret(hs, hs->new_session->master_key, pms); + if (hs->new_session->master_key_length == 0) { + return ssl_hs_error; + } + hs->new_session->extended_master_secret = hs->extended_master_secret; + + hs->state = state_send_client_certificate_verify; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_send_client_certificate_verify(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + + if (!hs->cert_request || !ssl_has_certificate(ssl)) { + hs->state = state_send_client_finished; + return ssl_hs_ok; + } + + assert(ssl_has_private_key(ssl)); + ScopedCBB cbb; + CBB body, child; + if (!ssl->method->init_message(ssl, cbb.get(), &body, + SSL3_MT_CERTIFICATE_VERIFY)) { + return ssl_hs_error; + } + + uint16_t signature_algorithm; + if (!tls1_choose_signature_algorithm(hs, &signature_algorithm)) { + return ssl_hs_error; + } + if (ssl_protocol_version(ssl) >= TLS1_2_VERSION) { + // Write out the digest type in TLS 1.2. + if (!CBB_add_u16(&body, signature_algorithm)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return ssl_hs_error; + } + } + + // Set aside space for the signature. + const size_t max_sig_len = EVP_PKEY_size(hs->local_pubkey.get()); + uint8_t *ptr; + if (!CBB_add_u16_length_prefixed(&body, &child) || + !CBB_reserve(&child, &ptr, max_sig_len)) { + return ssl_hs_error; + } + + size_t sig_len = max_sig_len; + // The SSL3 construction for CertificateVerify does not decompose into a + // single final digest and signature, and must be special-cased. + if (ssl_protocol_version(ssl) == SSL3_VERSION) { + if (ssl->cert->key_method != NULL) { + OPENSSL_PUT_ERROR(SSL, SSL_R_UNSUPPORTED_PROTOCOL_FOR_CUSTOM_KEY); + return ssl_hs_error; + } + + uint8_t digest[EVP_MAX_MD_SIZE]; + size_t digest_len; + if (!hs->transcript.GetSSL3CertVerifyHash( + digest, &digest_len, hs->new_session.get(), signature_algorithm)) { + return ssl_hs_error; + } + + UniquePtr pctx(EVP_PKEY_CTX_new(ssl->cert->privatekey, NULL)); + if (!pctx || + !EVP_PKEY_sign_init(pctx.get()) || + !EVP_PKEY_sign(pctx.get(), ptr, &sig_len, digest, digest_len)) { + return ssl_hs_error; + } + } else { + switch (ssl_private_key_sign(hs, ptr, &sig_len, max_sig_len, + signature_algorithm, + hs->transcript.buffer())) { + case ssl_private_key_success: + break; + case ssl_private_key_failure: + return ssl_hs_error; + case ssl_private_key_retry: + hs->state = state_send_client_certificate_verify; + return ssl_hs_private_key_operation; + } + } + + if (!CBB_did_write(&child, sig_len) || + !ssl_add_message_cbb(ssl, cbb.get())) { + return ssl_hs_error; + } + + // The handshake buffer is no longer necessary. + hs->transcript.FreeBuffer(); + + hs->state = state_send_client_finished; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_send_client_finished(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + // Resolve Channel ID first, before any non-idempotent operations. + if (ssl->s3->tlsext_channel_id_valid) { + if (!ssl_do_channel_id_callback(ssl)) { + return ssl_hs_error; + } + + if (ssl->tlsext_channel_id_private == NULL) { + hs->state = state_send_client_finished; + return ssl_hs_channel_id_lookup; + } + } + + if (!ssl->method->add_change_cipher_spec(ssl) || + !tls1_change_cipher_state(hs, evp_aead_seal)) { + return ssl_hs_error; + } + + if (hs->next_proto_neg_seen) { + static const uint8_t kZero[32] = {0}; + size_t padding_len = + 32 - ((ssl->s3->next_proto_negotiated.size() + 2) % 32); + + ScopedCBB cbb; + CBB body, child; + if (!ssl->method->init_message(ssl, cbb.get(), &body, SSL3_MT_NEXT_PROTO) || + !CBB_add_u8_length_prefixed(&body, &child) || + !CBB_add_bytes(&child, ssl->s3->next_proto_negotiated.data(), + ssl->s3->next_proto_negotiated.size()) || + !CBB_add_u8_length_prefixed(&body, &child) || + !CBB_add_bytes(&child, kZero, padding_len) || + !ssl_add_message_cbb(ssl, cbb.get())) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return ssl_hs_error; + } + } + + if (ssl->s3->tlsext_channel_id_valid) { + ScopedCBB cbb; + CBB body; + if (!ssl->method->init_message(ssl, cbb.get(), &body, SSL3_MT_CHANNEL_ID) || + !tls1_write_channel_id(hs, &body) || + !ssl_add_message_cbb(ssl, cbb.get())) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return ssl_hs_error; + } + } + + if (!ssl_send_finished(hs)) { + return ssl_hs_error; + } + + hs->state = state_finish_flight; + return ssl_hs_flush; +} + +static bool can_false_start(const SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + + // False Start only for TLS 1.2 with an ECDHE+AEAD cipher. + if (SSL_is_dtls(ssl) || + SSL_version(ssl) != TLS1_2_VERSION || + hs->new_cipher->algorithm_mkey != SSL_kECDHE || + hs->new_cipher->algorithm_mac != SSL_AEAD) { + return false; + } + + // Additionally require ALPN or NPN by default. + // + // TODO(davidben): Can this constraint be relaxed globally now that cipher + // suite requirements have been relaxed? + if (!ssl->ctx->false_start_allowed_without_alpn && + ssl->s3->alpn_selected.empty() && + ssl->s3->next_proto_negotiated.empty()) { + return false; + } + + return true; +} + +static enum ssl_hs_wait_t do_finish_flight(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + if (ssl->session != NULL) { + hs->state = state_finish_client_handshake; + return ssl_hs_ok; + } + + // This is a full handshake. If it involves ChannelID, then record the + // handshake hashes at this point in the session so that any resumption of + // this session with ChannelID can sign those hashes. + if (!tls1_record_handshake_hashes_for_channel_id(hs)) { + return ssl_hs_error; + } + + hs->state = state_read_session_ticket; + + if ((SSL_get_mode(ssl) & SSL_MODE_ENABLE_FALSE_START) && + can_false_start(hs) && + // No False Start on renegotiation (would complicate the state machine). + !ssl->s3->initial_handshake_complete) { + hs->in_false_start = true; + hs->can_early_write = true; + return ssl_hs_early_return; + } + + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_read_session_ticket(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + + if (!hs->ticket_expected) { + hs->state = state_process_change_cipher_spec; + return ssl_hs_read_change_cipher_spec; + } + + SSLMessage msg; + if (!ssl->method->get_message(ssl, &msg)) { + return ssl_hs_read_message; + } + + if (!ssl_check_message_type(ssl, msg, SSL3_MT_NEW_SESSION_TICKET) || + !ssl_hash_message(hs, msg)) { + return ssl_hs_error; + } + + CBS new_session_ticket = msg.body, ticket; + uint32_t tlsext_tick_lifetime_hint; + if (!CBS_get_u32(&new_session_ticket, &tlsext_tick_lifetime_hint) || + !CBS_get_u16_length_prefixed(&new_session_ticket, &ticket) || + CBS_len(&new_session_ticket) != 0) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + return ssl_hs_error; + } + + if (CBS_len(&ticket) == 0) { + // RFC 5077 allows a server to change its mind and send no ticket after + // negotiating the extension. The value of |ticket_expected| is checked in + // |ssl_update_cache| so is cleared here to avoid an unnecessary update. + hs->ticket_expected = false; + ssl->method->next_message(ssl); + hs->state = state_process_change_cipher_spec; + return ssl_hs_read_change_cipher_spec; + } + + SSL_SESSION *session = hs->new_session.get(); + UniquePtr renewed_session; + if (ssl->session != NULL) { + // The server is sending a new ticket for an existing session. Sessions are + // immutable once established, so duplicate all but the ticket of the + // existing session. + renewed_session = + SSL_SESSION_dup(ssl->session, SSL_SESSION_INCLUDE_NONAUTH); + if (!renewed_session) { + // This should never happen. + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return ssl_hs_error; + } + session = renewed_session.get(); + } + + // |tlsext_tick_lifetime_hint| is measured from when the ticket was issued. + ssl_session_rebase_time(ssl, session); + + if (!CBS_stow(&ticket, &session->tlsext_tick, &session->tlsext_ticklen)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return ssl_hs_error; + } + session->tlsext_tick_lifetime_hint = tlsext_tick_lifetime_hint; + + // Generate a session ID for this session based on the session ticket. We use + // the session ID mechanism for detecting ticket resumption. This also fits in + // with assumptions elsewhere in OpenSSL. + if (!EVP_Digest(CBS_data(&ticket), CBS_len(&ticket), + session->session_id, &session->session_id_length, + EVP_sha256(), NULL)) { + return ssl_hs_error; + } + + if (renewed_session) { + session->not_resumable = 0; + SSL_SESSION_free(ssl->session); + ssl->session = renewed_session.release(); + } + + ssl->method->next_message(ssl); + hs->state = state_process_change_cipher_spec; + return ssl_hs_read_change_cipher_spec; +} + +static enum ssl_hs_wait_t do_process_change_cipher_spec(SSL_HANDSHAKE *hs) { + if (!tls1_change_cipher_state(hs, evp_aead_open)) { + return ssl_hs_error; + } + + hs->state = state_read_server_finished; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_read_server_finished(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + enum ssl_hs_wait_t wait = ssl_get_finished(hs); + if (wait != ssl_hs_ok) { + return wait; + } + + if (ssl->session != NULL) { + hs->state = state_send_client_finished; + return ssl_hs_ok; + } + + hs->state = state_finish_client_handshake; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_finish_client_handshake(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + + ssl->method->on_handshake_complete(ssl); + + if (ssl->session != NULL) { + SSL_SESSION_up_ref(ssl->session); + ssl->s3->established_session.reset(ssl->session); + } else { + // We make a copy of the session in order to maintain the immutability + // of the new established_session due to False Start. The caller may + // have taken a reference to the temporary session. + ssl->s3->established_session = + SSL_SESSION_dup(hs->new_session.get(), SSL_SESSION_DUP_ALL); + if (!ssl->s3->established_session) { + return ssl_hs_error; + } + // Renegotiations do not participate in session resumption. + if (!ssl->s3->initial_handshake_complete) { + ssl->s3->established_session->not_resumable = 0; + } + + hs->new_session.reset(); + } + + hs->handshake_finalized = true; + ssl->s3->initial_handshake_complete = true; + ssl_update_cache(hs, SSL_SESS_CACHE_CLIENT); + + hs->state = state_done; + return ssl_hs_ok; +} + +enum ssl_hs_wait_t ssl_client_handshake(SSL_HANDSHAKE *hs) { + while (hs->state != state_done) { + enum ssl_hs_wait_t ret = ssl_hs_error; + enum ssl_client_hs_state_t state = + static_cast(hs->state); + switch (state) { + case state_start_connect: + ret = do_start_connect(hs); + break; + case state_enter_early_data: + ret = do_enter_early_data(hs); + break; + case state_read_hello_verify_request: + ret = do_read_hello_verify_request(hs); + break; + case state_read_server_hello: + ret = do_read_server_hello(hs); + break; + case state_tls13: + ret = do_tls13(hs); + break; + case state_read_server_certificate: + ret = do_read_server_certificate(hs); + break; + case state_read_certificate_status: + ret = do_read_certificate_status(hs); + break; + case state_verify_server_certificate: + ret = do_verify_server_certificate(hs); + break; + case state_read_server_key_exchange: + ret = do_read_server_key_exchange(hs); + break; + case state_read_certificate_request: + ret = do_read_certificate_request(hs); + break; + case state_read_server_hello_done: + ret = do_read_server_hello_done(hs); + break; + case state_send_client_certificate: + ret = do_send_client_certificate(hs); + break; + case state_send_client_key_exchange: + ret = do_send_client_key_exchange(hs); + break; + case state_send_client_certificate_verify: + ret = do_send_client_certificate_verify(hs); + break; + case state_send_client_finished: + ret = do_send_client_finished(hs); + break; + case state_finish_flight: + ret = do_finish_flight(hs); + break; + case state_read_session_ticket: + ret = do_read_session_ticket(hs); + break; + case state_process_change_cipher_spec: + ret = do_process_change_cipher_spec(hs); + break; + case state_read_server_finished: + ret = do_read_server_finished(hs); + break; + case state_finish_client_handshake: + ret = do_finish_client_handshake(hs); + break; + case state_done: + ret = ssl_hs_ok; + break; + } + + if (hs->state != state) { + ssl_do_info_callback(hs->ssl, SSL_CB_CONNECT_LOOP, 1); + } + + if (ret != ssl_hs_ok) { + return ret; + } + } + + ssl_do_info_callback(hs->ssl, SSL_CB_HANDSHAKE_DONE, 1); + return ssl_hs_ok; +} + +const char *ssl_client_handshake_state(SSL_HANDSHAKE *hs) { + enum ssl_client_hs_state_t state = + static_cast(hs->state); + switch (state) { + case state_start_connect: + return "TLS client start_connect"; + case state_enter_early_data: + return "TLS client enter_early_data"; + case state_read_hello_verify_request: + return "TLS client read_hello_verify_request"; + case state_read_server_hello: + return "TLS client read_server_hello"; + case state_tls13: + return tls13_client_handshake_state(hs); + case state_read_server_certificate: + return "TLS client read_server_certificate"; + case state_read_certificate_status: + return "TLS client read_certificate_status"; + case state_verify_server_certificate: + return "TLS client verify_server_certificate"; + case state_read_server_key_exchange: + return "TLS client read_server_key_exchange"; + case state_read_certificate_request: + return "TLS client read_certificate_request"; + case state_read_server_hello_done: + return "TLS client read_server_hello_done"; + case state_send_client_certificate: + return "TLS client send_client_certificate"; + case state_send_client_key_exchange: + return "TLS client send_client_key_exchange"; + case state_send_client_certificate_verify: + return "TLS client send_client_certificate_verify"; + case state_send_client_finished: + return "TLS client send_client_finished"; + case state_finish_flight: + return "TLS client finish_flight"; + case state_read_session_ticket: + return "TLS client read_session_ticket"; + case state_process_change_cipher_spec: + return "TLS client process_change_cipher_spec"; + case state_read_server_finished: + return "TLS client read_server_finished"; + case state_finish_client_handshake: + return "TLS client finish_client_handshake"; + case state_done: + return "TLS client done"; + } + + return "TLS client unknown"; +} + +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/ssl/handshake_client.cc.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/ssl/handshake_client.cc.grpc_back new file mode 100644 index 0000000..0b352c2 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/ssl/handshake_client.cc.grpc_back @@ -0,0 +1,1842 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../crypto/internal.h" +#include "internal.h" + + +namespace bssl { + +enum ssl_client_hs_state_t { + state_start_connect = 0, + state_enter_early_data, + state_read_hello_verify_request, + state_read_server_hello, + state_tls13, + state_read_server_certificate, + state_read_certificate_status, + state_verify_server_certificate, + state_read_server_key_exchange, + state_read_certificate_request, + state_read_server_hello_done, + state_send_client_certificate, + state_send_client_key_exchange, + state_send_client_certificate_verify, + state_send_client_finished, + state_finish_flight, + state_read_session_ticket, + state_process_change_cipher_spec, + state_read_server_finished, + state_finish_client_handshake, + state_done, +}; + +// ssl_get_client_disabled sets |*out_mask_a| and |*out_mask_k| to masks of +// disabled algorithms. +static void ssl_get_client_disabled(SSL *ssl, uint32_t *out_mask_a, + uint32_t *out_mask_k) { + *out_mask_a = 0; + *out_mask_k = 0; + + // PSK requires a client callback. + if (ssl->psk_client_callback == NULL) { + *out_mask_a |= SSL_aPSK; + *out_mask_k |= SSL_kPSK; + } +} + +static int ssl_write_client_cipher_list(SSL_HANDSHAKE *hs, CBB *out) { + SSL *const ssl = hs->ssl; + uint32_t mask_a, mask_k; + ssl_get_client_disabled(ssl, &mask_a, &mask_k); + + CBB child; + if (!CBB_add_u16_length_prefixed(out, &child)) { + return 0; + } + + // Add a fake cipher suite. See draft-davidben-tls-grease-01. + if (ssl->ctx->grease_enabled && + !CBB_add_u16(&child, ssl_get_grease_value(hs, ssl_grease_cipher))) { + return 0; + } + + // Add TLS 1.3 ciphers. Order ChaCha20-Poly1305 relative to AES-GCM based on + // hardware support. + if (hs->max_version >= TLS1_3_VERSION) { + if (!EVP_has_aes_hardware() && + !CBB_add_u16(&child, TLS1_CK_CHACHA20_POLY1305_SHA256 & 0xffff)) { + return 0; + } + if (!CBB_add_u16(&child, TLS1_CK_AES_128_GCM_SHA256 & 0xffff) || + !CBB_add_u16(&child, TLS1_CK_AES_256_GCM_SHA384 & 0xffff)) { + return 0; + } + if (EVP_has_aes_hardware() && + !CBB_add_u16(&child, TLS1_CK_CHACHA20_POLY1305_SHA256 & 0xffff)) { + return 0; + } + } + + if (hs->min_version < TLS1_3_VERSION) { + int any_enabled = 0; + for (const SSL_CIPHER *cipher : SSL_get_ciphers(ssl)) { + // Skip disabled ciphers + if ((cipher->algorithm_mkey & mask_k) || + (cipher->algorithm_auth & mask_a)) { + continue; + } + if (SSL_CIPHER_get_min_version(cipher) > hs->max_version || + SSL_CIPHER_get_max_version(cipher) < hs->min_version) { + continue; + } + any_enabled = 1; + if (!CBB_add_u16(&child, ssl_cipher_get_value(cipher))) { + return 0; + } + } + + // If all ciphers were disabled, return the error to the caller. + if (!any_enabled && hs->max_version < TLS1_3_VERSION) { + OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CIPHERS_AVAILABLE); + return 0; + } + } + + // For SSLv3, the SCSV is added. Otherwise the renegotiation extension is + // added. + if (hs->max_version == SSL3_VERSION && + !ssl->s3->initial_handshake_complete) { + if (!CBB_add_u16(&child, SSL3_CK_SCSV & 0xffff)) { + return 0; + } + } + + if (ssl->mode & SSL_MODE_SEND_FALLBACK_SCSV) { + if (!CBB_add_u16(&child, SSL3_CK_FALLBACK_SCSV & 0xffff)) { + return 0; + } + } + + return CBB_flush(out); +} + +int ssl_write_client_hello(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + ScopedCBB cbb; + CBB body; + if (!ssl->method->init_message(ssl, cbb.get(), &body, SSL3_MT_CLIENT_HELLO)) { + return 0; + } + + CBB child; + if (!CBB_add_u16(&body, hs->client_version) || + !CBB_add_bytes(&body, ssl->s3->client_random, SSL3_RANDOM_SIZE) || + !CBB_add_u8_length_prefixed(&body, &child)) { + return 0; + } + + // Do not send a session ID on renegotiation. + if (!ssl->s3->initial_handshake_complete && + !CBB_add_bytes(&child, hs->session_id, hs->session_id_len)) { + return 0; + } + + if (SSL_is_dtls(ssl)) { + if (!CBB_add_u8_length_prefixed(&body, &child) || + !CBB_add_bytes(&child, ssl->d1->cookie, ssl->d1->cookie_len)) { + return 0; + } + } + + size_t header_len = + SSL_is_dtls(ssl) ? DTLS1_HM_HEADER_LENGTH : SSL3_HM_HEADER_LENGTH; + if (!ssl_write_client_cipher_list(hs, &body) || + !CBB_add_u8(&body, 1 /* one compression method */) || + !CBB_add_u8(&body, 0 /* null compression */) || + !ssl_add_clienthello_tlsext(hs, &body, header_len + CBB_len(&body))) { + return 0; + } + + Array msg; + if (!ssl->method->finish_message(ssl, cbb.get(), &msg)) { + return 0; + } + + // Now that the length prefixes have been computed, fill in the placeholder + // PSK binder. + if (hs->needs_psk_binder && + !tls13_write_psk_binder(hs, msg.data(), msg.size())) { + return 0; + } + + return ssl->method->add_message(ssl, std::move(msg)); +} + +static bool parse_supported_versions(SSL_HANDSHAKE *hs, uint16_t *version, + const CBS *in) { + // If the outer version is not TLS 1.2, or there is no extensions block, use + // the outer version. + if (*version != TLS1_2_VERSION || CBS_len(in) == 0) { + return true; + } + + SSL *const ssl = hs->ssl; + CBS copy = *in, extensions; + if (!CBS_get_u16_length_prefixed(©, &extensions) || + CBS_len(©) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return false; + } + + bool have_supported_versions; + CBS supported_versions; + const SSL_EXTENSION_TYPE ext_types[] = { + {TLSEXT_TYPE_supported_versions, &have_supported_versions, + &supported_versions}, + }; + + uint8_t alert = SSL_AD_DECODE_ERROR; + if (!ssl_parse_extensions(&extensions, &alert, ext_types, + OPENSSL_ARRAY_SIZE(ext_types), + 1 /* ignore unknown */)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + return false; + } + + // Override the outer version with the extension, if present. + if (have_supported_versions && + (!CBS_get_u16(&supported_versions, version) || + CBS_len(&supported_versions) != 0)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return false; + } + + return true; +} + +static enum ssl_hs_wait_t do_start_connect(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + + ssl_do_info_callback(ssl, SSL_CB_HANDSHAKE_START, 1); + // |session_reused| must be reset in case this is a renegotiation. + ssl->s3->session_reused = false; + + // Freeze the version range. + if (!ssl_get_version_range(ssl, &hs->min_version, &hs->max_version)) { + return ssl_hs_error; + } + + // SSL 3.0 ClientHellos should use SSL 3.0 not TLS 1.0, for the record-layer + // version. + if (hs->max_version == SSL3_VERSION) { + ssl->s3->aead_write_ctx->SetVersionIfNullCipher(SSL3_VERSION); + } + + // Always advertise the ClientHello version from the original maximum version, + // even on renegotiation. The static RSA key exchange uses this field, and + // some servers fail when it changes across handshakes. + if (SSL_is_dtls(hs->ssl)) { + hs->client_version = + hs->max_version >= TLS1_2_VERSION ? DTLS1_2_VERSION : DTLS1_VERSION; + } else { + hs->client_version = + hs->max_version >= TLS1_2_VERSION ? TLS1_2_VERSION : hs->max_version; + } + + // If the configured session has expired or was created at a disabled + // version, drop it. + if (ssl->session != NULL) { + if (ssl->session->is_server || + !ssl_supports_version(hs, ssl->session->ssl_version) || + (ssl->session->session_id_length == 0 && + ssl->session->tlsext_ticklen == 0) || + ssl->session->not_resumable || + !ssl_session_is_time_valid(ssl, ssl->session)) { + ssl_set_session(ssl, NULL); + } + } + + if (!RAND_bytes(ssl->s3->client_random, sizeof(ssl->s3->client_random))) { + return ssl_hs_error; + } + + // Initialize a random session ID for the experimental TLS 1.3 variant + // requiring a session id. + if (ssl->session != nullptr && + !ssl->s3->initial_handshake_complete && + ssl->session->session_id_length > 0) { + hs->session_id_len = ssl->session->session_id_length; + OPENSSL_memcpy(hs->session_id, ssl->session->session_id, + hs->session_id_len); + } else if (hs->max_version >= TLS1_3_VERSION) { + hs->session_id_len = sizeof(hs->session_id); + if (!RAND_bytes(hs->session_id, hs->session_id_len)) { + return ssl_hs_error; + } + } + + if (!ssl_write_client_hello(hs)) { + return ssl_hs_error; + } + + hs->state = state_enter_early_data; + return ssl_hs_flush; +} + +static enum ssl_hs_wait_t do_enter_early_data(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + + if (SSL_is_dtls(ssl)) { + hs->state = state_read_hello_verify_request; + return ssl_hs_ok; + } + + if (!hs->early_data_offered) { + hs->state = state_read_server_hello; + return ssl_hs_ok; + } + + ssl->s3->aead_write_ctx->SetVersionIfNullCipher(ssl->session->ssl_version); + if (!ssl->method->add_change_cipher_spec(ssl)) { + return ssl_hs_error; + } + + if (!tls13_init_early_key_schedule(hs, ssl->session->master_key, + ssl->session->master_key_length) || + !tls13_derive_early_secrets(hs) || + !tls13_set_traffic_key(ssl, evp_aead_seal, hs->early_traffic_secret, + hs->hash_len)) { + return ssl_hs_error; + } + + // Stash the early data session, so connection properties may be queried out + // of it. + hs->in_early_data = true; + SSL_SESSION_up_ref(ssl->session); + hs->early_session.reset(ssl->session); + hs->can_early_write = true; + + hs->state = state_read_server_hello; + return ssl_hs_early_return; +} + +static enum ssl_hs_wait_t do_read_hello_verify_request(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + + assert(SSL_is_dtls(ssl)); + + SSLMessage msg; + if (!ssl->method->get_message(ssl, &msg)) { + return ssl_hs_read_message; + } + + if (msg.type != DTLS1_MT_HELLO_VERIFY_REQUEST) { + hs->state = state_read_server_hello; + return ssl_hs_ok; + } + + CBS hello_verify_request = msg.body, cookie; + uint16_t server_version; + if (!CBS_get_u16(&hello_verify_request, &server_version) || + !CBS_get_u8_length_prefixed(&hello_verify_request, &cookie) || + CBS_len(&cookie) > sizeof(ssl->d1->cookie) || + CBS_len(&hello_verify_request) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return ssl_hs_error; + } + + OPENSSL_memcpy(ssl->d1->cookie, CBS_data(&cookie), CBS_len(&cookie)); + ssl->d1->cookie_len = CBS_len(&cookie); + + ssl->method->next_message(ssl); + + // DTLS resets the handshake buffer after HelloVerifyRequest. + if (!hs->transcript.Init()) { + return ssl_hs_error; + } + + if (!ssl_write_client_hello(hs)) { + return ssl_hs_error; + } + + hs->state = state_read_server_hello; + return ssl_hs_flush; +} + +static enum ssl_hs_wait_t do_read_server_hello(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + SSLMessage msg; + if (!ssl->method->get_message(ssl, &msg)) { + return ssl_hs_read_server_hello; + } + + if (!ssl_check_message_type(ssl, msg, SSL3_MT_SERVER_HELLO)) { + return ssl_hs_error; + } + + CBS server_hello = msg.body, server_random, session_id; + uint16_t server_version, cipher_suite; + uint8_t compression_method; + if (!CBS_get_u16(&server_hello, &server_version) || + !CBS_get_bytes(&server_hello, &server_random, SSL3_RANDOM_SIZE) || + !CBS_get_u8_length_prefixed(&server_hello, &session_id) || + CBS_len(&session_id) > SSL3_SESSION_ID_SIZE || + !CBS_get_u16(&server_hello, &cipher_suite) || + !CBS_get_u8(&server_hello, &compression_method)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return ssl_hs_error; + } + + // Use the supported_versions extension if applicable. + if (!parse_supported_versions(hs, &server_version, &server_hello)) { + return ssl_hs_error; + } + + if (!ssl_supports_version(hs, server_version)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_UNSUPPORTED_PROTOCOL); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_PROTOCOL_VERSION); + return ssl_hs_error; + } + + assert(ssl->s3->have_version == ssl->s3->initial_handshake_complete); + if (!ssl->s3->have_version) { + ssl->version = server_version; + // At this point, the connection's version is known and ssl->version is + // fixed. Begin enforcing the record-layer version. + ssl->s3->have_version = true; + ssl->s3->aead_write_ctx->SetVersionIfNullCipher(ssl->version); + } else if (server_version != ssl->version) { + OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_SSL_VERSION); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_PROTOCOL_VERSION); + return ssl_hs_error; + } + + if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) { + hs->state = state_tls13; + return ssl_hs_ok; + } + + // Clear some TLS 1.3 state that no longer needs to be retained. + hs->key_share.reset(); + hs->key_share_bytes.Reset(); + + // A TLS 1.2 server would not know to skip the early data we offered. Report + // an error code sooner. The caller may use this error code to implement the + // fallback described in draft-ietf-tls-tls13-18 appendix C.3. + if (hs->early_data_offered) { + OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_VERSION_ON_EARLY_DATA); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_PROTOCOL_VERSION); + return ssl_hs_error; + } + + // Copy over the server random. + OPENSSL_memcpy(ssl->s3->server_random, CBS_data(&server_random), + SSL3_RANDOM_SIZE); + + // Measure, but do not enforce, the TLS 1.3 anti-downgrade feature, with a + // different value. + // + // For draft TLS 1.3 versions, it is not safe to deploy this feature. However, + // some TLS terminators are non-compliant and copy the origin server's value, + // so we wish to measure eventual compatibility impact. + if (!ssl->s3->initial_handshake_complete && + hs->max_version >= TLS1_3_VERSION && + OPENSSL_memcmp(ssl->s3->server_random + SSL3_RANDOM_SIZE - + sizeof(kDraftDowngradeRandom), + kDraftDowngradeRandom, + sizeof(kDraftDowngradeRandom)) == 0) { + ssl->s3->draft_downgrade = true; + } + + if (!ssl->s3->initial_handshake_complete && ssl->session != NULL && + ssl->session->session_id_length != 0 && + CBS_mem_equal(&session_id, ssl->session->session_id, + ssl->session->session_id_length)) { + ssl->s3->session_reused = true; + } else { + // The server may also have echoed back the TLS 1.3 compatibility mode + // session ID. As we know this is not a session the server knows about, any + // server resuming it is in error. Reject the first connection + // deterministicly, rather than installing an invalid session into the + // session cache. https://crbug.com/796910 + if (hs->session_id_len != 0 && + CBS_mem_equal(&session_id, hs->session_id, hs->session_id_len)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_SERVER_ECHOED_INVALID_SESSION_ID); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + return ssl_hs_error; + } + + // The session wasn't resumed. Create a fresh SSL_SESSION to + // fill out. + ssl_set_session(ssl, NULL); + if (!ssl_get_new_session(hs, 0 /* client */)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return ssl_hs_error; + } + // Note: session_id could be empty. + hs->new_session->session_id_length = CBS_len(&session_id); + OPENSSL_memcpy(hs->new_session->session_id, CBS_data(&session_id), + CBS_len(&session_id)); + } + + const SSL_CIPHER *cipher = SSL_get_cipher_by_value(cipher_suite); + if (cipher == NULL) { + // unknown cipher + OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_CIPHER_RETURNED); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + return ssl_hs_error; + } + + // The cipher must be allowed in the selected version and enabled. + uint32_t mask_a, mask_k; + ssl_get_client_disabled(ssl, &mask_a, &mask_k); + if ((cipher->algorithm_mkey & mask_k) || (cipher->algorithm_auth & mask_a) || + SSL_CIPHER_get_min_version(cipher) > ssl_protocol_version(ssl) || + SSL_CIPHER_get_max_version(cipher) < ssl_protocol_version(ssl) || + !sk_SSL_CIPHER_find(SSL_get_ciphers(ssl), NULL, cipher)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CIPHER_RETURNED); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + return ssl_hs_error; + } + + if (ssl->session != NULL) { + if (ssl->session->ssl_version != ssl->version) { + OPENSSL_PUT_ERROR(SSL, SSL_R_OLD_SESSION_VERSION_NOT_RETURNED); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + return ssl_hs_error; + } + if (ssl->session->cipher != cipher) { + OPENSSL_PUT_ERROR(SSL, SSL_R_OLD_SESSION_CIPHER_NOT_RETURNED); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + return ssl_hs_error; + } + if (!ssl_session_is_context_valid(ssl, ssl->session)) { + // This is actually a client application bug. + OPENSSL_PUT_ERROR(SSL, + SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + return ssl_hs_error; + } + } else { + hs->new_session->cipher = cipher; + } + hs->new_cipher = cipher; + + // Now that the cipher is known, initialize the handshake hash and hash the + // ServerHello. + if (!hs->transcript.InitHash(ssl_protocol_version(ssl), hs->new_cipher) || + !ssl_hash_message(hs, msg)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return ssl_hs_error; + } + + // If doing a full handshake, the server may request a client certificate + // which requires hashing the handshake transcript. Otherwise, the handshake + // buffer may be released. + if (ssl->session != NULL || + !ssl_cipher_uses_certificate_auth(hs->new_cipher)) { + hs->transcript.FreeBuffer(); + } + + // Only the NULL compression algorithm is supported. + if (compression_method != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_UNSUPPORTED_COMPRESSION_ALGORITHM); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + return ssl_hs_error; + } + + // TLS extensions + if (!ssl_parse_serverhello_tlsext(hs, &server_hello)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_PARSE_TLSEXT); + return ssl_hs_error; + } + + // There should be nothing left over in the record. + if (CBS_len(&server_hello) != 0) { + // wrong packet length + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return ssl_hs_error; + } + + if (ssl->session != NULL && + hs->extended_master_secret != ssl->session->extended_master_secret) { + if (ssl->session->extended_master_secret) { + OPENSSL_PUT_ERROR(SSL, SSL_R_RESUMED_EMS_SESSION_WITHOUT_EMS_EXTENSION); + } else { + OPENSSL_PUT_ERROR(SSL, SSL_R_RESUMED_NON_EMS_SESSION_WITH_EMS_EXTENSION); + } + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); + return ssl_hs_error; + } + + if (ssl->token_binding_negotiated && + (!hs->extended_master_secret || !ssl->s3->send_connection_binding)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_NEGOTIATED_TB_WITHOUT_EMS_OR_RI); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNSUPPORTED_EXTENSION); + return ssl_hs_error; + } + + ssl->method->next_message(ssl); + + if (ssl->session != NULL) { + hs->state = state_read_session_ticket; + return ssl_hs_ok; + } + + hs->state = state_read_server_certificate; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_tls13(SSL_HANDSHAKE *hs) { + enum ssl_hs_wait_t wait = tls13_client_handshake(hs); + if (wait == ssl_hs_ok) { + hs->state = state_finish_client_handshake; + return ssl_hs_ok; + } + + return wait; +} + +static enum ssl_hs_wait_t do_read_server_certificate(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + + if (!ssl_cipher_uses_certificate_auth(hs->new_cipher)) { + hs->state = state_read_certificate_status; + return ssl_hs_ok; + } + + SSLMessage msg; + if (!ssl->method->get_message(ssl, &msg)) { + return ssl_hs_read_message; + } + + if (!ssl_check_message_type(ssl, msg, SSL3_MT_CERTIFICATE) || + !ssl_hash_message(hs, msg)) { + return ssl_hs_error; + } + + CBS body = msg.body; + uint8_t alert = SSL_AD_DECODE_ERROR; + UniquePtr chain; + if (!ssl_parse_cert_chain(&alert, &chain, &hs->peer_pubkey, NULL, &body, + ssl->ctx->pool)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + return ssl_hs_error; + } + sk_CRYPTO_BUFFER_pop_free(hs->new_session->certs, CRYPTO_BUFFER_free); + hs->new_session->certs = chain.release(); + + if (sk_CRYPTO_BUFFER_num(hs->new_session->certs) == 0 || + CBS_len(&body) != 0 || + !ssl->ctx->x509_method->session_cache_objects(hs->new_session.get())) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return ssl_hs_error; + } + + if (!ssl_check_leaf_certificate( + hs, hs->peer_pubkey.get(), + sk_CRYPTO_BUFFER_value(hs->new_session->certs, 0))) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + return ssl_hs_error; + } + + ssl->method->next_message(ssl); + + hs->state = state_read_certificate_status; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_read_certificate_status(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + + if (!hs->certificate_status_expected) { + hs->state = state_verify_server_certificate; + return ssl_hs_ok; + } + + SSLMessage msg; + if (!ssl->method->get_message(ssl, &msg)) { + return ssl_hs_read_message; + } + + if (msg.type != SSL3_MT_CERTIFICATE_STATUS) { + // A server may send status_request in ServerHello and then change its mind + // about sending CertificateStatus. + hs->state = state_verify_server_certificate; + return ssl_hs_ok; + } + + if (!ssl_hash_message(hs, msg)) { + return ssl_hs_error; + } + + CBS certificate_status = msg.body, ocsp_response; + uint8_t status_type; + if (!CBS_get_u8(&certificate_status, &status_type) || + status_type != TLSEXT_STATUSTYPE_ocsp || + !CBS_get_u24_length_prefixed(&certificate_status, &ocsp_response) || + CBS_len(&ocsp_response) == 0 || + CBS_len(&certificate_status) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return ssl_hs_error; + } + + CRYPTO_BUFFER_free(hs->new_session->ocsp_response); + hs->new_session->ocsp_response = + CRYPTO_BUFFER_new_from_CBS(&ocsp_response, ssl->ctx->pool); + if (hs->new_session->ocsp_response == nullptr) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return ssl_hs_error; + } + + ssl->method->next_message(ssl); + + hs->state = state_verify_server_certificate; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_verify_server_certificate(SSL_HANDSHAKE *hs) { + if (!ssl_cipher_uses_certificate_auth(hs->new_cipher)) { + hs->state = state_read_server_key_exchange; + return ssl_hs_ok; + } + + switch (ssl_verify_peer_cert(hs)) { + case ssl_verify_ok: + break; + case ssl_verify_invalid: + return ssl_hs_error; + case ssl_verify_retry: + hs->state = state_verify_server_certificate; + return ssl_hs_certificate_verify; + } + + hs->state = state_read_server_key_exchange; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_read_server_key_exchange(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + SSLMessage msg; + if (!ssl->method->get_message(ssl, &msg)) { + return ssl_hs_read_message; + } + + if (msg.type != SSL3_MT_SERVER_KEY_EXCHANGE) { + // Some ciphers (pure PSK) have an optional ServerKeyExchange message. + if (ssl_cipher_requires_server_key_exchange(hs->new_cipher)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_MESSAGE); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE); + return ssl_hs_error; + } + + hs->state = state_read_certificate_request; + return ssl_hs_ok; + } + + if (!ssl_hash_message(hs, msg)) { + return ssl_hs_error; + } + + uint32_t alg_k = hs->new_cipher->algorithm_mkey; + uint32_t alg_a = hs->new_cipher->algorithm_auth; + CBS server_key_exchange = msg.body; + if (alg_a & SSL_aPSK) { + CBS psk_identity_hint; + + // Each of the PSK key exchanges begins with a psk_identity_hint. + if (!CBS_get_u16_length_prefixed(&server_key_exchange, + &psk_identity_hint)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return ssl_hs_error; + } + + // Store the PSK identity hint for the ClientKeyExchange. Assume that the + // maximum length of a PSK identity hint can be as long as the maximum + // length of a PSK identity. Also do not allow NULL characters; identities + // are saved as C strings. + // + // TODO(davidben): Should invalid hints be ignored? It's a hint rather than + // a specific identity. + if (CBS_len(&psk_identity_hint) > PSK_MAX_IDENTITY_LEN || + CBS_contains_zero_byte(&psk_identity_hint)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DATA_LENGTH_TOO_LONG); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); + return ssl_hs_error; + } + + // Save non-empty identity hints as a C string. Empty identity hints we + // treat as missing. Plain PSK makes it possible to send either no hint + // (omit ServerKeyExchange) or an empty hint, while ECDHE_PSK can only spell + // empty hint. Having different capabilities is odd, so we interpret empty + // and missing as identical. + char *raw = nullptr; + if (CBS_len(&psk_identity_hint) != 0 && + !CBS_strdup(&psk_identity_hint, &raw)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return ssl_hs_error; + } + hs->peer_psk_identity_hint.reset(raw); + } + + if (alg_k & SSL_kECDHE) { + // Parse the server parameters. + uint8_t group_type; + uint16_t group_id; + CBS point; + if (!CBS_get_u8(&server_key_exchange, &group_type) || + group_type != NAMED_CURVE_TYPE || + !CBS_get_u16(&server_key_exchange, &group_id) || + !CBS_get_u8_length_prefixed(&server_key_exchange, &point)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return ssl_hs_error; + } + hs->new_session->group_id = group_id; + + // Ensure the group is consistent with preferences. + if (!tls1_check_group_id(ssl, group_id)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CURVE); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + return ssl_hs_error; + } + + // Initialize ECDH and save the peer public key for later. + hs->key_share = SSLKeyShare::Create(group_id); + if (!hs->key_share || + !hs->peer_key.CopyFrom(point)) { + return ssl_hs_error; + } + } else if (!(alg_k & SSL_kPSK)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_MESSAGE); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE); + return ssl_hs_error; + } + + // At this point, |server_key_exchange| contains the signature, if any, while + // |msg.body| contains the entire message. From that, derive a CBS containing + // just the parameter. + CBS parameter; + CBS_init(¶meter, CBS_data(&msg.body), + CBS_len(&msg.body) - CBS_len(&server_key_exchange)); + + // ServerKeyExchange should be signed by the server's public key. + if (ssl_cipher_uses_certificate_auth(hs->new_cipher)) { + uint16_t signature_algorithm = 0; + if (ssl_protocol_version(ssl) >= TLS1_2_VERSION) { + if (!CBS_get_u16(&server_key_exchange, &signature_algorithm)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return ssl_hs_error; + } + uint8_t alert = SSL_AD_DECODE_ERROR; + if (!tls12_check_peer_sigalg(ssl, &alert, signature_algorithm)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + return ssl_hs_error; + } + hs->new_session->peer_signature_algorithm = signature_algorithm; + } else if (!tls1_get_legacy_signature_algorithm(&signature_algorithm, + hs->peer_pubkey.get())) { + OPENSSL_PUT_ERROR(SSL, SSL_R_PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNSUPPORTED_CERTIFICATE); + return ssl_hs_error; + } + + // The last field in |server_key_exchange| is the signature. + CBS signature; + if (!CBS_get_u16_length_prefixed(&server_key_exchange, &signature) || + CBS_len(&server_key_exchange) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return ssl_hs_error; + } + + ScopedCBB transcript; + Array transcript_data; + if (!CBB_init(transcript.get(), + 2 * SSL3_RANDOM_SIZE + CBS_len(¶meter)) || + !CBB_add_bytes(transcript.get(), ssl->s3->client_random, + SSL3_RANDOM_SIZE) || + !CBB_add_bytes(transcript.get(), ssl->s3->server_random, + SSL3_RANDOM_SIZE) || + !CBB_add_bytes(transcript.get(), CBS_data(¶meter), + CBS_len(¶meter)) || + !CBBFinishArray(transcript.get(), &transcript_data)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return ssl_hs_error; + } + + bool sig_ok = ssl_public_key_verify(ssl, signature, signature_algorithm, + hs->peer_pubkey.get(), transcript_data); +#if defined(BORINGSSL_UNSAFE_FUZZER_MODE) + sig_ok = true; + ERR_clear_error(); +#endif + if (!sig_ok) { + // bad signature + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SIGNATURE); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECRYPT_ERROR); + return ssl_hs_error; + } + } else { + // PSK ciphers are the only supported certificate-less ciphers. + assert(alg_a == SSL_aPSK); + + if (CBS_len(&server_key_exchange) > 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_EXTRA_DATA_IN_MESSAGE); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return ssl_hs_error; + } + } + + ssl->method->next_message(ssl); + hs->state = state_read_certificate_request; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_read_certificate_request(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + + if (!ssl_cipher_uses_certificate_auth(hs->new_cipher)) { + hs->state = state_read_server_hello_done; + return ssl_hs_ok; + } + + SSLMessage msg; + if (!ssl->method->get_message(ssl, &msg)) { + return ssl_hs_read_message; + } + + if (msg.type == SSL3_MT_SERVER_HELLO_DONE) { + // If we get here we don't need the handshake buffer as we won't be doing + // client auth. + hs->transcript.FreeBuffer(); + hs->state = state_read_server_hello_done; + return ssl_hs_ok; + } + + if (!ssl_check_message_type(ssl, msg, SSL3_MT_CERTIFICATE_REQUEST) || + !ssl_hash_message(hs, msg)) { + return ssl_hs_error; + } + + // Get the certificate types. + CBS body = msg.body, certificate_types; + if (!CBS_get_u8_length_prefixed(&body, &certificate_types)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + return ssl_hs_error; + } + + if (!hs->certificate_types.CopyFrom(certificate_types)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return ssl_hs_error; + } + + if (ssl_protocol_version(ssl) >= TLS1_2_VERSION) { + CBS supported_signature_algorithms; + if (!CBS_get_u16_length_prefixed(&body, &supported_signature_algorithms) || + !tls1_parse_peer_sigalgs(hs, &supported_signature_algorithms)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + return ssl_hs_error; + } + } + + uint8_t alert = SSL_AD_DECODE_ERROR; + UniquePtr ca_names = + ssl_parse_client_CA_list(ssl, &alert, &body); + if (!ca_names) { + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + return ssl_hs_error; + } + + if (CBS_len(&body) != 0) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + return ssl_hs_error; + } + + hs->cert_request = true; + hs->ca_names = std::move(ca_names); + ssl->ctx->x509_method->hs_flush_cached_ca_names(hs); + + ssl->method->next_message(ssl); + hs->state = state_read_server_hello_done; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_read_server_hello_done(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + SSLMessage msg; + if (!ssl->method->get_message(ssl, &msg)) { + return ssl_hs_read_message; + } + + if (!ssl_check_message_type(ssl, msg, SSL3_MT_SERVER_HELLO_DONE) || + !ssl_hash_message(hs, msg)) { + return ssl_hs_error; + } + + // ServerHelloDone is empty. + if (CBS_len(&msg.body) != 0) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + return ssl_hs_error; + } + + ssl->method->next_message(ssl); + hs->state = state_send_client_certificate; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_send_client_certificate(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + + // The peer didn't request a certificate. + if (!hs->cert_request) { + hs->state = state_send_client_key_exchange; + return ssl_hs_ok; + } + + // Call cert_cb to update the certificate. + if (ssl->cert->cert_cb != NULL) { + int rv = ssl->cert->cert_cb(ssl, ssl->cert->cert_cb_arg); + if (rv == 0) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + OPENSSL_PUT_ERROR(SSL, SSL_R_CERT_CB_ERROR); + return ssl_hs_error; + } + if (rv < 0) { + hs->state = state_send_client_certificate; + return ssl_hs_x509_lookup; + } + } + + if (!ssl_has_certificate(ssl)) { + // Without a client certificate, the handshake buffer may be released. + hs->transcript.FreeBuffer(); + + // In SSL 3.0, the Certificate message is replaced with a warning alert. + if (ssl->version == SSL3_VERSION) { + if (!ssl->method->add_alert(ssl, SSL3_AL_WARNING, + SSL_AD_NO_CERTIFICATE)) { + return ssl_hs_error; + } + hs->state = state_send_client_key_exchange; + return ssl_hs_ok; + } + } + + if (!ssl_on_certificate_selected(hs) || + !ssl_output_cert_chain(ssl)) { + return ssl_hs_error; + } + + + hs->state = state_send_client_key_exchange; + return ssl_hs_ok; +} + +static_assert(sizeof(size_t) >= sizeof(unsigned), + "size_t is smaller than unsigned"); + +static enum ssl_hs_wait_t do_send_client_key_exchange(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + ScopedCBB cbb; + CBB body; + if (!ssl->method->init_message(ssl, cbb.get(), &body, + SSL3_MT_CLIENT_KEY_EXCHANGE)) { + return ssl_hs_error; + } + + Array pms; + uint32_t alg_k = hs->new_cipher->algorithm_mkey; + uint32_t alg_a = hs->new_cipher->algorithm_auth; + + // If using a PSK key exchange, prepare the pre-shared key. + unsigned psk_len = 0; + uint8_t psk[PSK_MAX_PSK_LEN]; + if (alg_a & SSL_aPSK) { + if (ssl->psk_client_callback == NULL) { + OPENSSL_PUT_ERROR(SSL, SSL_R_PSK_NO_CLIENT_CB); + return ssl_hs_error; + } + + char identity[PSK_MAX_IDENTITY_LEN + 1]; + OPENSSL_memset(identity, 0, sizeof(identity)); + psk_len = + ssl->psk_client_callback(ssl, hs->peer_psk_identity_hint.get(), + identity, sizeof(identity), psk, sizeof(psk)); + if (psk_len == 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_PSK_IDENTITY_NOT_FOUND); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); + return ssl_hs_error; + } + assert(psk_len <= PSK_MAX_PSK_LEN); + + OPENSSL_free(hs->new_session->psk_identity); + hs->new_session->psk_identity = BUF_strdup(identity); + if (hs->new_session->psk_identity == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return ssl_hs_error; + } + + // Write out psk_identity. + CBB child; + if (!CBB_add_u16_length_prefixed(&body, &child) || + !CBB_add_bytes(&child, (const uint8_t *)identity, + OPENSSL_strnlen(identity, sizeof(identity))) || + !CBB_flush(&body)) { + return ssl_hs_error; + } + } + + // Depending on the key exchange method, compute |pms|. + if (alg_k & SSL_kRSA) { + if (!pms.Init(SSL_MAX_MASTER_KEY_LENGTH)) { + return ssl_hs_error; + } + + RSA *rsa = EVP_PKEY_get0_RSA(hs->peer_pubkey.get()); + if (rsa == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return ssl_hs_error; + } + + pms[0] = hs->client_version >> 8; + pms[1] = hs->client_version & 0xff; + if (!RAND_bytes(&pms[2], SSL_MAX_MASTER_KEY_LENGTH - 2)) { + return ssl_hs_error; + } + + CBB child, *enc_pms = &body; + size_t enc_pms_len; + // In TLS, there is a length prefix. + if (ssl->version > SSL3_VERSION) { + if (!CBB_add_u16_length_prefixed(&body, &child)) { + return ssl_hs_error; + } + enc_pms = &child; + } + + uint8_t *ptr; + if (!CBB_reserve(enc_pms, &ptr, RSA_size(rsa)) || + !RSA_encrypt(rsa, &enc_pms_len, ptr, RSA_size(rsa), pms.data(), + pms.size(), RSA_PKCS1_PADDING) || + !CBB_did_write(enc_pms, enc_pms_len) || + !CBB_flush(&body)) { + return ssl_hs_error; + } + } else if (alg_k & SSL_kECDHE) { + // Generate a keypair and serialize the public half. + CBB child; + if (!CBB_add_u8_length_prefixed(&body, &child)) { + return ssl_hs_error; + } + + // Compute the premaster. + uint8_t alert = SSL_AD_DECODE_ERROR; + if (!hs->key_share->Accept(&child, &pms, &alert, hs->peer_key)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + return ssl_hs_error; + } + if (!CBB_flush(&body)) { + return ssl_hs_error; + } + + // The key exchange state may now be discarded. + hs->key_share.reset(); + hs->peer_key.Reset(); + } else if (alg_k & SSL_kPSK) { + // For plain PSK, other_secret is a block of 0s with the same length as + // the pre-shared key. + if (!pms.Init(psk_len)) { + return ssl_hs_error; + } + OPENSSL_memset(pms.data(), 0, pms.size()); + } else { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return ssl_hs_error; + } + + // For a PSK cipher suite, other_secret is combined with the pre-shared + // key. + if (alg_a & SSL_aPSK) { + ScopedCBB pms_cbb; + CBB child; + if (!CBB_init(pms_cbb.get(), 2 + psk_len + 2 + pms.size()) || + !CBB_add_u16_length_prefixed(pms_cbb.get(), &child) || + !CBB_add_bytes(&child, pms.data(), pms.size()) || + !CBB_add_u16_length_prefixed(pms_cbb.get(), &child) || + !CBB_add_bytes(&child, psk, psk_len) || + !CBBFinishArray(pms_cbb.get(), &pms)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return ssl_hs_error; + } + } + + // The message must be added to the finished hash before calculating the + // master secret. + if (!ssl_add_message_cbb(ssl, cbb.get())) { + return ssl_hs_error; + } + + hs->new_session->master_key_length = + tls1_generate_master_secret(hs, hs->new_session->master_key, pms); + if (hs->new_session->master_key_length == 0) { + return ssl_hs_error; + } + hs->new_session->extended_master_secret = hs->extended_master_secret; + + hs->state = state_send_client_certificate_verify; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_send_client_certificate_verify(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + + if (!hs->cert_request || !ssl_has_certificate(ssl)) { + hs->state = state_send_client_finished; + return ssl_hs_ok; + } + + assert(ssl_has_private_key(ssl)); + ScopedCBB cbb; + CBB body, child; + if (!ssl->method->init_message(ssl, cbb.get(), &body, + SSL3_MT_CERTIFICATE_VERIFY)) { + return ssl_hs_error; + } + + uint16_t signature_algorithm; + if (!tls1_choose_signature_algorithm(hs, &signature_algorithm)) { + return ssl_hs_error; + } + if (ssl_protocol_version(ssl) >= TLS1_2_VERSION) { + // Write out the digest type in TLS 1.2. + if (!CBB_add_u16(&body, signature_algorithm)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return ssl_hs_error; + } + } + + // Set aside space for the signature. + const size_t max_sig_len = EVP_PKEY_size(hs->local_pubkey.get()); + uint8_t *ptr; + if (!CBB_add_u16_length_prefixed(&body, &child) || + !CBB_reserve(&child, &ptr, max_sig_len)) { + return ssl_hs_error; + } + + size_t sig_len = max_sig_len; + // The SSL3 construction for CertificateVerify does not decompose into a + // single final digest and signature, and must be special-cased. + if (ssl_protocol_version(ssl) == SSL3_VERSION) { + if (ssl->cert->key_method != NULL) { + OPENSSL_PUT_ERROR(SSL, SSL_R_UNSUPPORTED_PROTOCOL_FOR_CUSTOM_KEY); + return ssl_hs_error; + } + + uint8_t digest[EVP_MAX_MD_SIZE]; + size_t digest_len; + if (!hs->transcript.GetSSL3CertVerifyHash( + digest, &digest_len, hs->new_session.get(), signature_algorithm)) { + return ssl_hs_error; + } + + UniquePtr pctx(EVP_PKEY_CTX_new(ssl->cert->privatekey, NULL)); + if (!pctx || + !EVP_PKEY_sign_init(pctx.get()) || + !EVP_PKEY_sign(pctx.get(), ptr, &sig_len, digest, digest_len)) { + return ssl_hs_error; + } + } else { + switch (ssl_private_key_sign(hs, ptr, &sig_len, max_sig_len, + signature_algorithm, + hs->transcript.buffer())) { + case ssl_private_key_success: + break; + case ssl_private_key_failure: + return ssl_hs_error; + case ssl_private_key_retry: + hs->state = state_send_client_certificate_verify; + return ssl_hs_private_key_operation; + } + } + + if (!CBB_did_write(&child, sig_len) || + !ssl_add_message_cbb(ssl, cbb.get())) { + return ssl_hs_error; + } + + // The handshake buffer is no longer necessary. + hs->transcript.FreeBuffer(); + + hs->state = state_send_client_finished; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_send_client_finished(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + // Resolve Channel ID first, before any non-idempotent operations. + if (ssl->s3->tlsext_channel_id_valid) { + if (!ssl_do_channel_id_callback(ssl)) { + return ssl_hs_error; + } + + if (ssl->tlsext_channel_id_private == NULL) { + hs->state = state_send_client_finished; + return ssl_hs_channel_id_lookup; + } + } + + if (!ssl->method->add_change_cipher_spec(ssl) || + !tls1_change_cipher_state(hs, evp_aead_seal)) { + return ssl_hs_error; + } + + if (hs->next_proto_neg_seen) { + static const uint8_t kZero[32] = {0}; + size_t padding_len = + 32 - ((ssl->s3->next_proto_negotiated.size() + 2) % 32); + + ScopedCBB cbb; + CBB body, child; + if (!ssl->method->init_message(ssl, cbb.get(), &body, SSL3_MT_NEXT_PROTO) || + !CBB_add_u8_length_prefixed(&body, &child) || + !CBB_add_bytes(&child, ssl->s3->next_proto_negotiated.data(), + ssl->s3->next_proto_negotiated.size()) || + !CBB_add_u8_length_prefixed(&body, &child) || + !CBB_add_bytes(&child, kZero, padding_len) || + !ssl_add_message_cbb(ssl, cbb.get())) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return ssl_hs_error; + } + } + + if (ssl->s3->tlsext_channel_id_valid) { + ScopedCBB cbb; + CBB body; + if (!ssl->method->init_message(ssl, cbb.get(), &body, SSL3_MT_CHANNEL_ID) || + !tls1_write_channel_id(hs, &body) || + !ssl_add_message_cbb(ssl, cbb.get())) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return ssl_hs_error; + } + } + + if (!ssl_send_finished(hs)) { + return ssl_hs_error; + } + + hs->state = state_finish_flight; + return ssl_hs_flush; +} + +static bool can_false_start(const SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + + // False Start only for TLS 1.2 with an ECDHE+AEAD cipher. + if (SSL_is_dtls(ssl) || + SSL_version(ssl) != TLS1_2_VERSION || + hs->new_cipher->algorithm_mkey != SSL_kECDHE || + hs->new_cipher->algorithm_mac != SSL_AEAD) { + return false; + } + + // Additionally require ALPN or NPN by default. + // + // TODO(davidben): Can this constraint be relaxed globally now that cipher + // suite requirements have been relaxed? + if (!ssl->ctx->false_start_allowed_without_alpn && + ssl->s3->alpn_selected.empty() && + ssl->s3->next_proto_negotiated.empty()) { + return false; + } + + return true; +} + +static enum ssl_hs_wait_t do_finish_flight(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + if (ssl->session != NULL) { + hs->state = state_finish_client_handshake; + return ssl_hs_ok; + } + + // This is a full handshake. If it involves ChannelID, then record the + // handshake hashes at this point in the session so that any resumption of + // this session with ChannelID can sign those hashes. + if (!tls1_record_handshake_hashes_for_channel_id(hs)) { + return ssl_hs_error; + } + + hs->state = state_read_session_ticket; + + if ((SSL_get_mode(ssl) & SSL_MODE_ENABLE_FALSE_START) && + can_false_start(hs) && + // No False Start on renegotiation (would complicate the state machine). + !ssl->s3->initial_handshake_complete) { + hs->in_false_start = true; + hs->can_early_write = true; + return ssl_hs_early_return; + } + + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_read_session_ticket(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + + if (!hs->ticket_expected) { + hs->state = state_process_change_cipher_spec; + return ssl_hs_read_change_cipher_spec; + } + + SSLMessage msg; + if (!ssl->method->get_message(ssl, &msg)) { + return ssl_hs_read_message; + } + + if (!ssl_check_message_type(ssl, msg, SSL3_MT_NEW_SESSION_TICKET) || + !ssl_hash_message(hs, msg)) { + return ssl_hs_error; + } + + CBS new_session_ticket = msg.body, ticket; + uint32_t tlsext_tick_lifetime_hint; + if (!CBS_get_u32(&new_session_ticket, &tlsext_tick_lifetime_hint) || + !CBS_get_u16_length_prefixed(&new_session_ticket, &ticket) || + CBS_len(&new_session_ticket) != 0) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + return ssl_hs_error; + } + + if (CBS_len(&ticket) == 0) { + // RFC 5077 allows a server to change its mind and send no ticket after + // negotiating the extension. The value of |ticket_expected| is checked in + // |ssl_update_cache| so is cleared here to avoid an unnecessary update. + hs->ticket_expected = false; + ssl->method->next_message(ssl); + hs->state = state_process_change_cipher_spec; + return ssl_hs_read_change_cipher_spec; + } + + SSL_SESSION *session = hs->new_session.get(); + UniquePtr renewed_session; + if (ssl->session != NULL) { + // The server is sending a new ticket for an existing session. Sessions are + // immutable once established, so duplicate all but the ticket of the + // existing session. + renewed_session = + SSL_SESSION_dup(ssl->session, SSL_SESSION_INCLUDE_NONAUTH); + if (!renewed_session) { + // This should never happen. + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return ssl_hs_error; + } + session = renewed_session.get(); + } + + // |tlsext_tick_lifetime_hint| is measured from when the ticket was issued. + ssl_session_rebase_time(ssl, session); + + if (!CBS_stow(&ticket, &session->tlsext_tick, &session->tlsext_ticklen)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return ssl_hs_error; + } + session->tlsext_tick_lifetime_hint = tlsext_tick_lifetime_hint; + + // Generate a session ID for this session based on the session ticket. We use + // the session ID mechanism for detecting ticket resumption. This also fits in + // with assumptions elsewhere in OpenSSL. + if (!EVP_Digest(CBS_data(&ticket), CBS_len(&ticket), + session->session_id, &session->session_id_length, + EVP_sha256(), NULL)) { + return ssl_hs_error; + } + + if (renewed_session) { + session->not_resumable = 0; + SSL_SESSION_free(ssl->session); + ssl->session = renewed_session.release(); + } + + ssl->method->next_message(ssl); + hs->state = state_process_change_cipher_spec; + return ssl_hs_read_change_cipher_spec; +} + +static enum ssl_hs_wait_t do_process_change_cipher_spec(SSL_HANDSHAKE *hs) { + if (!tls1_change_cipher_state(hs, evp_aead_open)) { + return ssl_hs_error; + } + + hs->state = state_read_server_finished; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_read_server_finished(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + enum ssl_hs_wait_t wait = ssl_get_finished(hs); + if (wait != ssl_hs_ok) { + return wait; + } + + if (ssl->session != NULL) { + hs->state = state_send_client_finished; + return ssl_hs_ok; + } + + hs->state = state_finish_client_handshake; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_finish_client_handshake(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + + ssl->method->on_handshake_complete(ssl); + + if (ssl->session != NULL) { + SSL_SESSION_up_ref(ssl->session); + ssl->s3->established_session.reset(ssl->session); + } else { + // We make a copy of the session in order to maintain the immutability + // of the new established_session due to False Start. The caller may + // have taken a reference to the temporary session. + ssl->s3->established_session = + SSL_SESSION_dup(hs->new_session.get(), SSL_SESSION_DUP_ALL); + if (!ssl->s3->established_session) { + return ssl_hs_error; + } + // Renegotiations do not participate in session resumption. + if (!ssl->s3->initial_handshake_complete) { + ssl->s3->established_session->not_resumable = 0; + } + + hs->new_session.reset(); + } + + hs->handshake_finalized = true; + ssl->s3->initial_handshake_complete = true; + ssl_update_cache(hs, SSL_SESS_CACHE_CLIENT); + + hs->state = state_done; + return ssl_hs_ok; +} + +enum ssl_hs_wait_t ssl_client_handshake(SSL_HANDSHAKE *hs) { + while (hs->state != state_done) { + enum ssl_hs_wait_t ret = ssl_hs_error; + enum ssl_client_hs_state_t state = + static_cast(hs->state); + switch (state) { + case state_start_connect: + ret = do_start_connect(hs); + break; + case state_enter_early_data: + ret = do_enter_early_data(hs); + break; + case state_read_hello_verify_request: + ret = do_read_hello_verify_request(hs); + break; + case state_read_server_hello: + ret = do_read_server_hello(hs); + break; + case state_tls13: + ret = do_tls13(hs); + break; + case state_read_server_certificate: + ret = do_read_server_certificate(hs); + break; + case state_read_certificate_status: + ret = do_read_certificate_status(hs); + break; + case state_verify_server_certificate: + ret = do_verify_server_certificate(hs); + break; + case state_read_server_key_exchange: + ret = do_read_server_key_exchange(hs); + break; + case state_read_certificate_request: + ret = do_read_certificate_request(hs); + break; + case state_read_server_hello_done: + ret = do_read_server_hello_done(hs); + break; + case state_send_client_certificate: + ret = do_send_client_certificate(hs); + break; + case state_send_client_key_exchange: + ret = do_send_client_key_exchange(hs); + break; + case state_send_client_certificate_verify: + ret = do_send_client_certificate_verify(hs); + break; + case state_send_client_finished: + ret = do_send_client_finished(hs); + break; + case state_finish_flight: + ret = do_finish_flight(hs); + break; + case state_read_session_ticket: + ret = do_read_session_ticket(hs); + break; + case state_process_change_cipher_spec: + ret = do_process_change_cipher_spec(hs); + break; + case state_read_server_finished: + ret = do_read_server_finished(hs); + break; + case state_finish_client_handshake: + ret = do_finish_client_handshake(hs); + break; + case state_done: + ret = ssl_hs_ok; + break; + } + + if (hs->state != state) { + ssl_do_info_callback(hs->ssl, SSL_CB_CONNECT_LOOP, 1); + } + + if (ret != ssl_hs_ok) { + return ret; + } + } + + ssl_do_info_callback(hs->ssl, SSL_CB_HANDSHAKE_DONE, 1); + return ssl_hs_ok; +} + +const char *ssl_client_handshake_state(SSL_HANDSHAKE *hs) { + enum ssl_client_hs_state_t state = + static_cast(hs->state); + switch (state) { + case state_start_connect: + return "TLS client start_connect"; + case state_enter_early_data: + return "TLS client enter_early_data"; + case state_read_hello_verify_request: + return "TLS client read_hello_verify_request"; + case state_read_server_hello: + return "TLS client read_server_hello"; + case state_tls13: + return tls13_client_handshake_state(hs); + case state_read_server_certificate: + return "TLS client read_server_certificate"; + case state_read_certificate_status: + return "TLS client read_certificate_status"; + case state_verify_server_certificate: + return "TLS client verify_server_certificate"; + case state_read_server_key_exchange: + return "TLS client read_server_key_exchange"; + case state_read_certificate_request: + return "TLS client read_certificate_request"; + case state_read_server_hello_done: + return "TLS client read_server_hello_done"; + case state_send_client_certificate: + return "TLS client send_client_certificate"; + case state_send_client_key_exchange: + return "TLS client send_client_key_exchange"; + case state_send_client_certificate_verify: + return "TLS client send_client_certificate_verify"; + case state_send_client_finished: + return "TLS client send_client_finished"; + case state_finish_flight: + return "TLS client finish_flight"; + case state_read_session_ticket: + return "TLS client read_session_ticket"; + case state_process_change_cipher_spec: + return "TLS client process_change_cipher_spec"; + case state_read_server_finished: + return "TLS client read_server_finished"; + case state_finish_client_handshake: + return "TLS client finish_client_handshake"; + case state_done: + return "TLS client done"; + } + + return "TLS client unknown"; +} + +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/ssl/handshake_server.cc b/FoodApp/Pods/BoringSSL-GRPC/ssl/handshake_server.cc new file mode 100644 index 0000000..eff28f6 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/ssl/handshake_server.cc @@ -0,0 +1,1674 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "internal.h" +#include "../crypto/internal.h" + + +namespace bssl { + +enum ssl_server_hs_state_t { + state_start_accept = 0, + state_read_client_hello, + state_select_certificate, + state_tls13, + state_select_parameters, + state_send_server_hello, + state_send_server_certificate, + state_send_server_key_exchange, + state_send_server_hello_done, + state_read_client_certificate, + state_verify_client_certificate, + state_read_client_key_exchange, + state_read_client_certificate_verify, + state_read_change_cipher_spec, + state_process_change_cipher_spec, + state_read_next_proto, + state_read_channel_id, + state_read_client_finished, + state_send_server_finished, + state_finish_server_handshake, + state_done, +}; + +int ssl_client_cipher_list_contains_cipher(const SSL_CLIENT_HELLO *client_hello, + uint16_t id) { + CBS cipher_suites; + CBS_init(&cipher_suites, client_hello->cipher_suites, + client_hello->cipher_suites_len); + + while (CBS_len(&cipher_suites) > 0) { + uint16_t got_id; + if (!CBS_get_u16(&cipher_suites, &got_id)) { + return 0; + } + + if (got_id == id) { + return 1; + } + } + + return 0; +} + +static int negotiate_version(SSL_HANDSHAKE *hs, uint8_t *out_alert, + const SSL_CLIENT_HELLO *client_hello) { + SSL *const ssl = hs->ssl; + assert(!ssl->s3->have_version); + CBS supported_versions, versions; + if (ssl_client_hello_get_extension(client_hello, &supported_versions, + TLSEXT_TYPE_supported_versions)) { + if (!CBS_get_u8_length_prefixed(&supported_versions, &versions) || + CBS_len(&supported_versions) != 0 || + CBS_len(&versions) == 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + *out_alert = SSL_AD_DECODE_ERROR; + return 0; + } + } else { + // Convert the ClientHello version to an equivalent supported_versions + // extension. + static const uint8_t kTLSVersions[] = { + 0x03, 0x03, // TLS 1.2 + 0x03, 0x02, // TLS 1.1 + 0x03, 0x01, // TLS 1 + 0x03, 0x00, // SSL 3 + }; + + static const uint8_t kDTLSVersions[] = { + 0xfe, 0xfd, // DTLS 1.2 + 0xfe, 0xff, // DTLS 1.0 + }; + + size_t versions_len = 0; + if (SSL_is_dtls(ssl)) { + if (client_hello->version <= DTLS1_2_VERSION) { + versions_len = 4; + } else if (client_hello->version <= DTLS1_VERSION) { + versions_len = 2; + } + CBS_init(&versions, kDTLSVersions + sizeof(kDTLSVersions) - versions_len, + versions_len); + } else { + if (client_hello->version >= TLS1_2_VERSION) { + versions_len = 8; + } else if (client_hello->version >= TLS1_1_VERSION) { + versions_len = 6; + } else if (client_hello->version >= TLS1_VERSION) { + versions_len = 4; + } else if (client_hello->version >= SSL3_VERSION) { + versions_len = 2; + } + CBS_init(&versions, kTLSVersions + sizeof(kTLSVersions) - versions_len, + versions_len); + } + } + + if (!ssl_negotiate_version(hs, out_alert, &ssl->version, &versions)) { + return 0; + } + + // At this point, the connection's version is known and |ssl->version| is + // fixed. Begin enforcing the record-layer version. + ssl->s3->have_version = true; + ssl->s3->aead_write_ctx->SetVersionIfNullCipher(ssl->version); + + // Handle FALLBACK_SCSV. + if (ssl_client_cipher_list_contains_cipher(client_hello, + SSL3_CK_FALLBACK_SCSV & 0xffff) && + ssl_protocol_version(ssl) < hs->max_version) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INAPPROPRIATE_FALLBACK); + *out_alert = SSL3_AD_INAPPROPRIATE_FALLBACK; + return 0; + } + + return 1; +} + +static UniquePtr ssl_parse_client_cipher_list( + const SSL_CLIENT_HELLO *client_hello) { + CBS cipher_suites; + CBS_init(&cipher_suites, client_hello->cipher_suites, + client_hello->cipher_suites_len); + + UniquePtr sk(sk_SSL_CIPHER_new_null()); + if (!sk) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return nullptr; + } + + while (CBS_len(&cipher_suites) > 0) { + uint16_t cipher_suite; + + if (!CBS_get_u16(&cipher_suites, &cipher_suite)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST); + return nullptr; + } + + const SSL_CIPHER *c = SSL_get_cipher_by_value(cipher_suite); + if (c != NULL && !sk_SSL_CIPHER_push(sk.get(), c)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return nullptr; + } + } + + return sk; +} + +// ssl_get_compatible_server_ciphers determines the key exchange and +// authentication cipher suite masks compatible with the server configuration +// and current ClientHello parameters of |hs|. It sets |*out_mask_k| to the key +// exchange mask and |*out_mask_a| to the authentication mask. +static void ssl_get_compatible_server_ciphers(SSL_HANDSHAKE *hs, + uint32_t *out_mask_k, + uint32_t *out_mask_a) { + SSL *const ssl = hs->ssl; + uint32_t mask_k = 0; + uint32_t mask_a = 0; + + if (ssl_has_certificate(ssl)) { + mask_a |= ssl_cipher_auth_mask_for_key(hs->local_pubkey.get()); + if (EVP_PKEY_id(hs->local_pubkey.get()) == EVP_PKEY_RSA) { + mask_k |= SSL_kRSA; + } + } + + // Check for a shared group to consider ECDHE ciphers. + uint16_t unused; + if (tls1_get_shared_group(hs, &unused)) { + mask_k |= SSL_kECDHE; + } + + // PSK requires a server callback. + if (ssl->psk_server_callback != NULL) { + mask_k |= SSL_kPSK; + mask_a |= SSL_aPSK; + } + + *out_mask_k = mask_k; + *out_mask_a = mask_a; +} + +static const SSL_CIPHER *ssl3_choose_cipher( + SSL_HANDSHAKE *hs, const SSL_CLIENT_HELLO *client_hello, + const struct ssl_cipher_preference_list_st *server_pref) { + SSL *const ssl = hs->ssl; + STACK_OF(SSL_CIPHER) *prio, *allow; + // in_group_flags will either be NULL, or will point to an array of bytes + // which indicate equal-preference groups in the |prio| stack. See the + // comment about |in_group_flags| in the |ssl_cipher_preference_list_st| + // struct. + const uint8_t *in_group_flags; + // group_min contains the minimal index so far found in a group, or -1 if no + // such value exists yet. + int group_min = -1; + + UniquePtr client_pref = + ssl_parse_client_cipher_list(client_hello); + if (!client_pref) { + return nullptr; + } + + if (ssl->options & SSL_OP_CIPHER_SERVER_PREFERENCE) { + prio = server_pref->ciphers; + in_group_flags = server_pref->in_group_flags; + allow = client_pref.get(); + } else { + prio = client_pref.get(); + in_group_flags = NULL; + allow = server_pref->ciphers; + } + + uint32_t mask_k, mask_a; + ssl_get_compatible_server_ciphers(hs, &mask_k, &mask_a); + + for (size_t i = 0; i < sk_SSL_CIPHER_num(prio); i++) { + const SSL_CIPHER *c = sk_SSL_CIPHER_value(prio, i); + + size_t cipher_index; + if (// Check if the cipher is supported for the current version. + SSL_CIPHER_get_min_version(c) <= ssl_protocol_version(ssl) && + ssl_protocol_version(ssl) <= SSL_CIPHER_get_max_version(c) && + // Check the cipher is supported for the server configuration. + (c->algorithm_mkey & mask_k) && + (c->algorithm_auth & mask_a) && + // Check the cipher is in the |allow| list. + sk_SSL_CIPHER_find(allow, &cipher_index, c)) { + if (in_group_flags != NULL && in_group_flags[i] == 1) { + // This element of |prio| is in a group. Update the minimum index found + // so far and continue looking. + if (group_min == -1 || (size_t)group_min > cipher_index) { + group_min = cipher_index; + } + } else { + if (group_min != -1 && (size_t)group_min < cipher_index) { + cipher_index = group_min; + } + return sk_SSL_CIPHER_value(allow, cipher_index); + } + } + + if (in_group_flags != NULL && in_group_flags[i] == 0 && group_min != -1) { + // We are about to leave a group, but we found a match in it, so that's + // our answer. + return sk_SSL_CIPHER_value(allow, group_min); + } + } + + return nullptr; +} + +static enum ssl_hs_wait_t do_start_accept(SSL_HANDSHAKE *hs) { + ssl_do_info_callback(hs->ssl, SSL_CB_HANDSHAKE_START, 1); + hs->state = state_read_client_hello; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_read_client_hello(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + + SSLMessage msg; + if (!ssl->method->get_message(ssl, &msg)) { + return ssl_hs_read_message; + } + + if (!ssl_check_message_type(ssl, msg, SSL3_MT_CLIENT_HELLO)) { + return ssl_hs_error; + } + + if (ssl->handoff) { + return ssl_hs_handoff; + } + + SSL_CLIENT_HELLO client_hello; + if (!ssl_client_hello_init(ssl, &client_hello, msg)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return ssl_hs_error; + } + + // Run the early callback. + if (ssl->ctx->select_certificate_cb != NULL) { + switch (ssl->ctx->select_certificate_cb(&client_hello)) { + case ssl_select_cert_retry: + return ssl_hs_certificate_selection_pending; + + case ssl_select_cert_error: + // Connection rejected. + OPENSSL_PUT_ERROR(SSL, SSL_R_CONNECTION_REJECTED); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); + return ssl_hs_error; + + default: + /* fallthrough */; + } + } + + // Freeze the version range after the early callback. + if (!ssl_get_version_range(ssl, &hs->min_version, &hs->max_version)) { + return ssl_hs_error; + } + + uint8_t alert = SSL_AD_DECODE_ERROR; + if (!negotiate_version(hs, &alert, &client_hello)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + return ssl_hs_error; + } + + hs->client_version = client_hello.version; + if (client_hello.random_len != SSL3_RANDOM_SIZE) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return ssl_hs_error; + } + OPENSSL_memcpy(ssl->s3->client_random, client_hello.random, + client_hello.random_len); + + // Only null compression is supported. TLS 1.3 further requires the peer + // advertise no other compression. + if (OPENSSL_memchr(client_hello.compression_methods, 0, + client_hello.compression_methods_len) == NULL || + (ssl_protocol_version(ssl) >= TLS1_3_VERSION && + client_hello.compression_methods_len != 1)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_COMPRESSION_LIST); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + return ssl_hs_error; + } + + // TLS extensions. + if (!ssl_parse_clienthello_tlsext(hs, &client_hello)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_PARSE_TLSEXT); + return ssl_hs_error; + } + + hs->state = state_select_certificate; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_select_certificate(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + + SSLMessage msg; + if (!ssl->method->get_message(ssl, &msg)) { + return ssl_hs_read_message; + } + + // Call |cert_cb| to update server certificates if required. + if (ssl->cert->cert_cb != NULL) { + int rv = ssl->cert->cert_cb(ssl, ssl->cert->cert_cb_arg); + if (rv == 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_CERT_CB_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return ssl_hs_error; + } + if (rv < 0) { + return ssl_hs_x509_lookup; + } + } + + if (!ssl_on_certificate_selected(hs)) { + return ssl_hs_error; + } + + if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) { + // Jump to the TLS 1.3 state machine. + hs->state = state_tls13; + return ssl_hs_ok; + } + + SSL_CLIENT_HELLO client_hello; + if (!ssl_client_hello_init(ssl, &client_hello, msg)) { + return ssl_hs_error; + } + + // Negotiate the cipher suite. This must be done after |cert_cb| so the + // certificate is finalized. + hs->new_cipher = + ssl3_choose_cipher(hs, &client_hello, ssl_get_cipher_preferences(ssl)); + if (hs->new_cipher == NULL) { + OPENSSL_PUT_ERROR(SSL, SSL_R_NO_SHARED_CIPHER); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); + return ssl_hs_error; + } + + hs->state = state_select_parameters; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_tls13(SSL_HANDSHAKE *hs) { + enum ssl_hs_wait_t wait = tls13_server_handshake(hs); + if (wait == ssl_hs_ok) { + hs->state = state_finish_server_handshake; + return ssl_hs_ok; + } + + return wait; +} + +static enum ssl_hs_wait_t do_select_parameters(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + + SSLMessage msg; + if (!ssl->method->get_message(ssl, &msg)) { + return ssl_hs_read_message; + } + + SSL_CLIENT_HELLO client_hello; + if (!ssl_client_hello_init(ssl, &client_hello, msg)) { + return ssl_hs_error; + } + + // Determine whether we are doing session resumption. + UniquePtr session; + bool tickets_supported = false, renew_ticket = false; + enum ssl_hs_wait_t wait = ssl_get_prev_session( + ssl, &session, &tickets_supported, &renew_ticket, &client_hello); + if (wait != ssl_hs_ok) { + return wait; + } + + if (session) { + if (session->extended_master_secret && !hs->extended_master_secret) { + // A ClientHello without EMS that attempts to resume a session with EMS + // is fatal to the connection. + OPENSSL_PUT_ERROR(SSL, SSL_R_RESUMED_EMS_SESSION_WITHOUT_EMS_EXTENSION); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); + return ssl_hs_error; + } + + if (!ssl_session_is_resumable(hs, session.get()) || + // If the client offers the EMS extension, but the previous session + // didn't use it, then negotiate a new session. + hs->extended_master_secret != session->extended_master_secret) { + session.reset(); + } + } + + if (session) { + // Use the old session. + hs->ticket_expected = renew_ticket; + ssl->session = session.release(); + ssl->s3->session_reused = true; + } else { + hs->ticket_expected = tickets_supported; + ssl_set_session(ssl, NULL); + if (!ssl_get_new_session(hs, 1 /* server */)) { + return ssl_hs_error; + } + + // Clear the session ID if we want the session to be single-use. + if (!(ssl->ctx->session_cache_mode & SSL_SESS_CACHE_SERVER)) { + hs->new_session->session_id_length = 0; + } + } + + if (ssl->ctx->dos_protection_cb != NULL && + ssl->ctx->dos_protection_cb(&client_hello) == 0) { + // Connection rejected for DOS reasons. + OPENSSL_PUT_ERROR(SSL, SSL_R_CONNECTION_REJECTED); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return ssl_hs_error; + } + + if (ssl->session == NULL) { + hs->new_session->cipher = hs->new_cipher; + + // Determine whether to request a client certificate. + hs->cert_request = !!(ssl->verify_mode & SSL_VERIFY_PEER); + // Only request a certificate if Channel ID isn't negotiated. + if ((ssl->verify_mode & SSL_VERIFY_PEER_IF_NO_OBC) && + ssl->s3->tlsext_channel_id_valid) { + hs->cert_request = false; + } + // CertificateRequest may only be sent in certificate-based ciphers. + if (!ssl_cipher_uses_certificate_auth(hs->new_cipher)) { + hs->cert_request = false; + } + + if (!hs->cert_request) { + // OpenSSL returns X509_V_OK when no certificates are requested. This is + // classed by them as a bug, but it's assumed by at least NGINX. + hs->new_session->verify_result = X509_V_OK; + } + } + + // HTTP/2 negotiation depends on the cipher suite, so ALPN negotiation was + // deferred. Complete it now. + uint8_t alert = SSL_AD_DECODE_ERROR; + if (!ssl_negotiate_alpn(hs, &alert, &client_hello)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + return ssl_hs_error; + } + + // Now that all parameters are known, initialize the handshake hash and hash + // the ClientHello. + if (!hs->transcript.InitHash(ssl_protocol_version(ssl), hs->new_cipher) || + !ssl_hash_message(hs, msg)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return ssl_hs_error; + } + + // Release the handshake buffer if client authentication isn't required. + if (!hs->cert_request) { + hs->transcript.FreeBuffer(); + } + + ssl->method->next_message(ssl); + + hs->state = state_send_server_hello; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_send_server_hello(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + + // We only accept ChannelIDs on connections with ECDHE in order to avoid a + // known attack while we fix ChannelID itself. + if (ssl->s3->tlsext_channel_id_valid && + (hs->new_cipher->algorithm_mkey & SSL_kECDHE) == 0) { + ssl->s3->tlsext_channel_id_valid = false; + } + + // If this is a resumption and the original handshake didn't support + // ChannelID then we didn't record the original handshake hashes in the + // session and so cannot resume with ChannelIDs. + if (ssl->session != NULL && + ssl->session->original_handshake_hash_len == 0) { + ssl->s3->tlsext_channel_id_valid = false; + } + + struct OPENSSL_timeval now; + ssl_get_current_time(ssl, &now); + ssl->s3->server_random[0] = now.tv_sec >> 24; + ssl->s3->server_random[1] = now.tv_sec >> 16; + ssl->s3->server_random[2] = now.tv_sec >> 8; + ssl->s3->server_random[3] = now.tv_sec; + if (!RAND_bytes(ssl->s3->server_random + 4, SSL3_RANDOM_SIZE - 4)) { + return ssl_hs_error; + } + + // Implement the TLS 1.3 anti-downgrade feature, but with a different value. + // + // For draft TLS 1.3 versions, it is not safe to deploy this feature. However, + // some TLS terminators are non-compliant and copy the origin server's value, + // so we wish to measure eventual compatibility impact. + if (hs->max_version >= TLS1_3_VERSION) { + OPENSSL_memcpy(ssl->s3->server_random + SSL3_RANDOM_SIZE - + sizeof(kDraftDowngradeRandom), + kDraftDowngradeRandom, sizeof(kDraftDowngradeRandom)); + } + + const SSL_SESSION *session = hs->new_session.get(); + if (ssl->session != NULL) { + session = ssl->session; + } + + ScopedCBB cbb; + CBB body, session_id; + if (!ssl->method->init_message(ssl, cbb.get(), &body, SSL3_MT_SERVER_HELLO) || + !CBB_add_u16(&body, ssl->version) || + !CBB_add_bytes(&body, ssl->s3->server_random, SSL3_RANDOM_SIZE) || + !CBB_add_u8_length_prefixed(&body, &session_id) || + !CBB_add_bytes(&session_id, session->session_id, + session->session_id_length) || + !CBB_add_u16(&body, ssl_cipher_get_value(hs->new_cipher)) || + !CBB_add_u8(&body, 0 /* no compression */) || + !ssl_add_serverhello_tlsext(hs, &body) || + !ssl_add_message_cbb(ssl, cbb.get())) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return ssl_hs_error; + } + + if (ssl->session != NULL) { + hs->state = state_send_server_finished; + } else { + hs->state = state_send_server_certificate; + } + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_send_server_certificate(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + ScopedCBB cbb; + + if (ssl_cipher_uses_certificate_auth(hs->new_cipher)) { + if (!ssl_has_certificate(ssl)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CERTIFICATE_SET); + return ssl_hs_error; + } + + if (!ssl_output_cert_chain(ssl)) { + return ssl_hs_error; + } + + if (hs->certificate_status_expected) { + CBB body, ocsp_response; + if (!ssl->method->init_message(ssl, cbb.get(), &body, + SSL3_MT_CERTIFICATE_STATUS) || + !CBB_add_u8(&body, TLSEXT_STATUSTYPE_ocsp) || + !CBB_add_u24_length_prefixed(&body, &ocsp_response) || + !CBB_add_bytes(&ocsp_response, + CRYPTO_BUFFER_data(ssl->cert->ocsp_response), + CRYPTO_BUFFER_len(ssl->cert->ocsp_response)) || + !ssl_add_message_cbb(ssl, cbb.get())) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return ssl_hs_error; + } + } + } + + // Assemble ServerKeyExchange parameters if needed. + uint32_t alg_k = hs->new_cipher->algorithm_mkey; + uint32_t alg_a = hs->new_cipher->algorithm_auth; + if (ssl_cipher_requires_server_key_exchange(hs->new_cipher) || + ((alg_a & SSL_aPSK) && ssl->psk_identity_hint)) { + + // Pre-allocate enough room to comfortably fit an ECDHE public key. Prepend + // the client and server randoms for the signing transcript. + CBB child; + if (!CBB_init(cbb.get(), SSL3_RANDOM_SIZE * 2 + 128) || + !CBB_add_bytes(cbb.get(), ssl->s3->client_random, SSL3_RANDOM_SIZE) || + !CBB_add_bytes(cbb.get(), ssl->s3->server_random, SSL3_RANDOM_SIZE)) { + return ssl_hs_error; + } + + // PSK ciphers begin with an identity hint. + if (alg_a & SSL_aPSK) { + size_t len = + (ssl->psk_identity_hint == NULL) ? 0 : strlen(ssl->psk_identity_hint); + if (!CBB_add_u16_length_prefixed(cbb.get(), &child) || + !CBB_add_bytes(&child, (const uint8_t *)ssl->psk_identity_hint, + len)) { + return ssl_hs_error; + } + } + + if (alg_k & SSL_kECDHE) { + // Determine the group to use. + uint16_t group_id; + if (!tls1_get_shared_group(hs, &group_id)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); + return ssl_hs_error; + } + hs->new_session->group_id = group_id; + + // Set up ECDH, generate a key, and emit the public half. + hs->key_share = SSLKeyShare::Create(group_id); + if (!hs->key_share || + !CBB_add_u8(cbb.get(), NAMED_CURVE_TYPE) || + !CBB_add_u16(cbb.get(), group_id) || + !CBB_add_u8_length_prefixed(cbb.get(), &child) || + !hs->key_share->Offer(&child)) { + return ssl_hs_error; + } + } else { + assert(alg_k & SSL_kPSK); + } + + if (!CBBFinishArray(cbb.get(), &hs->server_params)) { + return ssl_hs_error; + } + } + + hs->state = state_send_server_key_exchange; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_send_server_key_exchange(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + + if (hs->server_params.size() == 0) { + hs->state = state_send_server_hello_done; + return ssl_hs_ok; + } + + ScopedCBB cbb; + CBB body, child; + if (!ssl->method->init_message(ssl, cbb.get(), &body, + SSL3_MT_SERVER_KEY_EXCHANGE) || + // |hs->server_params| contains a prefix for signing. + hs->server_params.size() < 2 * SSL3_RANDOM_SIZE || + !CBB_add_bytes(&body, hs->server_params.data() + 2 * SSL3_RANDOM_SIZE, + hs->server_params.size() - 2 * SSL3_RANDOM_SIZE)) { + return ssl_hs_error; + } + + // Add a signature. + if (ssl_cipher_uses_certificate_auth(hs->new_cipher)) { + if (!ssl_has_private_key(ssl)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return ssl_hs_error; + } + + // Determine the signature algorithm. + uint16_t signature_algorithm; + if (!tls1_choose_signature_algorithm(hs, &signature_algorithm)) { + return ssl_hs_error; + } + if (ssl_protocol_version(ssl) >= TLS1_2_VERSION) { + if (!CBB_add_u16(&body, signature_algorithm)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return ssl_hs_error; + } + } + + // Add space for the signature. + const size_t max_sig_len = EVP_PKEY_size(hs->local_pubkey.get()); + uint8_t *ptr; + if (!CBB_add_u16_length_prefixed(&body, &child) || + !CBB_reserve(&child, &ptr, max_sig_len)) { + return ssl_hs_error; + } + + size_t sig_len; + switch (ssl_private_key_sign(hs, ptr, &sig_len, max_sig_len, + signature_algorithm, hs->server_params)) { + case ssl_private_key_success: + if (!CBB_did_write(&child, sig_len)) { + return ssl_hs_error; + } + break; + case ssl_private_key_failure: + return ssl_hs_error; + case ssl_private_key_retry: + return ssl_hs_private_key_operation; + } + } + + if (!ssl_add_message_cbb(ssl, cbb.get())) { + return ssl_hs_error; + } + + hs->server_params.Reset(); + + hs->state = state_send_server_hello_done; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_send_server_hello_done(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + + ScopedCBB cbb; + CBB body; + + if (hs->cert_request) { + CBB cert_types, sigalgs_cbb; + if (!ssl->method->init_message(ssl, cbb.get(), &body, + SSL3_MT_CERTIFICATE_REQUEST) || + !CBB_add_u8_length_prefixed(&body, &cert_types) || + !CBB_add_u8(&cert_types, SSL3_CT_RSA_SIGN) || + (ssl_protocol_version(ssl) >= TLS1_VERSION && + !CBB_add_u8(&cert_types, TLS_CT_ECDSA_SIGN)) || + (ssl_protocol_version(ssl) >= TLS1_2_VERSION && + (!CBB_add_u16_length_prefixed(&body, &sigalgs_cbb) || + !tls12_add_verify_sigalgs(ssl, &sigalgs_cbb))) || + !ssl_add_client_CA_list(ssl, &body) || + !ssl_add_message_cbb(ssl, cbb.get())) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return ssl_hs_error; + } + } + + if (!ssl->method->init_message(ssl, cbb.get(), &body, + SSL3_MT_SERVER_HELLO_DONE) || + !ssl_add_message_cbb(ssl, cbb.get())) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return ssl_hs_error; + } + + hs->state = state_read_client_certificate; + return ssl_hs_flush; +} + +static enum ssl_hs_wait_t do_read_client_certificate(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + + if (!hs->cert_request) { + hs->state = state_verify_client_certificate; + return ssl_hs_ok; + } + + SSLMessage msg; + if (!ssl->method->get_message(ssl, &msg)) { + return ssl_hs_read_message; + } + + if (msg.type != SSL3_MT_CERTIFICATE) { + if (ssl->version == SSL3_VERSION && + msg.type == SSL3_MT_CLIENT_KEY_EXCHANGE) { + // In SSL 3.0, the Certificate message is omitted to signal no + // certificate. + if (ssl->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) { + OPENSSL_PUT_ERROR(SSL, SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); + return ssl_hs_error; + } + + // OpenSSL returns X509_V_OK when no certificates are received. This is + // classed by them as a bug, but it's assumed by at least NGINX. + hs->new_session->verify_result = X509_V_OK; + hs->state = state_verify_client_certificate; + return ssl_hs_ok; + } + + OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_MESSAGE); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE); + return ssl_hs_error; + } + + if (!ssl_hash_message(hs, msg)) { + return ssl_hs_error; + } + + CBS certificate_msg = msg.body; + uint8_t alert = SSL_AD_DECODE_ERROR; + UniquePtr chain; + if (!ssl_parse_cert_chain(&alert, &chain, &hs->peer_pubkey, + ssl->retain_only_sha256_of_client_certs + ? hs->new_session->peer_sha256 + : NULL, + &certificate_msg, ssl->ctx->pool)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + return ssl_hs_error; + } + sk_CRYPTO_BUFFER_pop_free(hs->new_session->certs, CRYPTO_BUFFER_free); + hs->new_session->certs = chain.release(); + + if (CBS_len(&certificate_msg) != 0 || + !ssl->ctx->x509_method->session_cache_objects(hs->new_session.get())) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return ssl_hs_error; + } + + if (sk_CRYPTO_BUFFER_num(hs->new_session->certs) == 0) { + // No client certificate so the handshake buffer may be discarded. + hs->transcript.FreeBuffer(); + + // In SSL 3.0, sending no certificate is signaled by omitting the + // Certificate message. + if (ssl->version == SSL3_VERSION) { + OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CERTIFICATES_RETURNED); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); + return ssl_hs_error; + } + + if (ssl->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) { + // Fail for TLS only if we required a certificate + OPENSSL_PUT_ERROR(SSL, SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); + return ssl_hs_error; + } + + // OpenSSL returns X509_V_OK when no certificates are received. This is + // classed by them as a bug, but it's assumed by at least NGINX. + hs->new_session->verify_result = X509_V_OK; + } else if (ssl->retain_only_sha256_of_client_certs) { + // The hash will have been filled in. + hs->new_session->peer_sha256_valid = 1; + } + + ssl->method->next_message(ssl); + hs->state = state_verify_client_certificate; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_verify_client_certificate(SSL_HANDSHAKE *hs) { + if (sk_CRYPTO_BUFFER_num(hs->new_session->certs) > 0) { + switch (ssl_verify_peer_cert(hs)) { + case ssl_verify_ok: + break; + case ssl_verify_invalid: + return ssl_hs_error; + case ssl_verify_retry: + return ssl_hs_certificate_verify; + } + } + + hs->state = state_read_client_key_exchange; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_read_client_key_exchange(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + SSLMessage msg; + if (!ssl->method->get_message(ssl, &msg)) { + return ssl_hs_read_message; + } + + if (!ssl_check_message_type(ssl, msg, SSL3_MT_CLIENT_KEY_EXCHANGE)) { + return ssl_hs_error; + } + + CBS client_key_exchange = msg.body; + uint32_t alg_k = hs->new_cipher->algorithm_mkey; + uint32_t alg_a = hs->new_cipher->algorithm_auth; + + // If using a PSK key exchange, parse the PSK identity. + if (alg_a & SSL_aPSK) { + CBS psk_identity; + + // If using PSK, the ClientKeyExchange contains a psk_identity. If PSK, + // then this is the only field in the message. + if (!CBS_get_u16_length_prefixed(&client_key_exchange, &psk_identity) || + ((alg_k & SSL_kPSK) && CBS_len(&client_key_exchange) != 0)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return ssl_hs_error; + } + + if (CBS_len(&psk_identity) > PSK_MAX_IDENTITY_LEN || + CBS_contains_zero_byte(&psk_identity)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DATA_LENGTH_TOO_LONG); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + return ssl_hs_error; + } + + if (!CBS_strdup(&psk_identity, &hs->new_session->psk_identity)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return ssl_hs_error; + } + } + + // Depending on the key exchange method, compute |premaster_secret|. + Array premaster_secret; + if (alg_k & SSL_kRSA) { + CBS encrypted_premaster_secret; + if (ssl->version > SSL3_VERSION) { + if (!CBS_get_u16_length_prefixed(&client_key_exchange, + &encrypted_premaster_secret) || + CBS_len(&client_key_exchange) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return ssl_hs_error; + } + } else { + encrypted_premaster_secret = client_key_exchange; + } + + // Allocate a buffer large enough for an RSA decryption. + Array decrypt_buf; + if (!decrypt_buf.Init(EVP_PKEY_size(hs->local_pubkey.get()))) { + return ssl_hs_error; + } + + // Decrypt with no padding. PKCS#1 padding will be removed as part of the + // timing-sensitive code below. + size_t decrypt_len; + switch (ssl_private_key_decrypt(hs, decrypt_buf.data(), &decrypt_len, + decrypt_buf.size(), + encrypted_premaster_secret)) { + case ssl_private_key_success: + break; + case ssl_private_key_failure: + return ssl_hs_error; + case ssl_private_key_retry: + return ssl_hs_private_key_operation; + } + + if (decrypt_len != decrypt_buf.size()) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECRYPTION_FAILED); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECRYPT_ERROR); + return ssl_hs_error; + } + + // Prepare a random premaster, to be used on invalid padding. See RFC 5246, + // section 7.4.7.1. + if (!premaster_secret.Init(SSL_MAX_MASTER_KEY_LENGTH) || + !RAND_bytes(premaster_secret.data(), premaster_secret.size())) { + return ssl_hs_error; + } + + // The smallest padded premaster is 11 bytes of overhead. Small keys are + // publicly invalid. + if (decrypt_len < 11 + premaster_secret.size()) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECRYPTION_FAILED); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECRYPT_ERROR); + return ssl_hs_error; + } + + // Check the padding. See RFC 3447, section 7.2.2. + size_t padding_len = decrypt_len - premaster_secret.size(); + uint8_t good = constant_time_eq_int_8(decrypt_buf[0], 0) & + constant_time_eq_int_8(decrypt_buf[1], 2); + for (size_t i = 2; i < padding_len - 1; i++) { + good &= ~constant_time_is_zero_8(decrypt_buf[i]); + } + good &= constant_time_is_zero_8(decrypt_buf[padding_len - 1]); + + // The premaster secret must begin with |client_version|. This too must be + // checked in constant time (http://eprint.iacr.org/2003/052/). + good &= constant_time_eq_8(decrypt_buf[padding_len], + (unsigned)(hs->client_version >> 8)); + good &= constant_time_eq_8(decrypt_buf[padding_len + 1], + (unsigned)(hs->client_version & 0xff)); + + // Select, in constant time, either the decrypted premaster or the random + // premaster based on |good|. + for (size_t i = 0; i < premaster_secret.size(); i++) { + premaster_secret[i] = constant_time_select_8( + good, decrypt_buf[padding_len + i], premaster_secret[i]); + } + } else if (alg_k & SSL_kECDHE) { + // Parse the ClientKeyExchange. + CBS peer_key; + if (!CBS_get_u8_length_prefixed(&client_key_exchange, &peer_key) || + CBS_len(&client_key_exchange) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return ssl_hs_error; + } + + // Compute the premaster. + uint8_t alert = SSL_AD_DECODE_ERROR; + if (!hs->key_share->Finish(&premaster_secret, &alert, peer_key)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + return ssl_hs_error; + } + + // The key exchange state may now be discarded. + hs->key_share.reset(); + } else if (!(alg_k & SSL_kPSK)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); + return ssl_hs_error; + } + + // For a PSK cipher suite, the actual pre-master secret is combined with the + // pre-shared key. + if (alg_a & SSL_aPSK) { + if (ssl->psk_server_callback == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return ssl_hs_error; + } + + // Look up the key for the identity. + uint8_t psk[PSK_MAX_PSK_LEN]; + unsigned psk_len = ssl->psk_server_callback( + ssl, hs->new_session->psk_identity, psk, sizeof(psk)); + if (psk_len > PSK_MAX_PSK_LEN) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return ssl_hs_error; + } else if (psk_len == 0) { + // PSK related to the given identity not found. + OPENSSL_PUT_ERROR(SSL, SSL_R_PSK_IDENTITY_NOT_FOUND); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNKNOWN_PSK_IDENTITY); + return ssl_hs_error; + } + + if (alg_k & SSL_kPSK) { + // In plain PSK, other_secret is a block of 0s with the same length as the + // pre-shared key. + if (!premaster_secret.Init(psk_len)) { + return ssl_hs_error; + } + OPENSSL_memset(premaster_secret.data(), 0, premaster_secret.size()); + } + + ScopedCBB new_premaster; + CBB child; + if (!CBB_init(new_premaster.get(), + 2 + psk_len + 2 + premaster_secret.size()) || + !CBB_add_u16_length_prefixed(new_premaster.get(), &child) || + !CBB_add_bytes(&child, premaster_secret.data(), + premaster_secret.size()) || + !CBB_add_u16_length_prefixed(new_premaster.get(), &child) || + !CBB_add_bytes(&child, psk, psk_len) || + !CBBFinishArray(new_premaster.get(), &premaster_secret)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return ssl_hs_error; + } + } + + if (!ssl_hash_message(hs, msg)) { + return ssl_hs_error; + } + + // Compute the master secret. + hs->new_session->master_key_length = tls1_generate_master_secret( + hs, hs->new_session->master_key, premaster_secret); + if (hs->new_session->master_key_length == 0) { + return ssl_hs_error; + } + hs->new_session->extended_master_secret = hs->extended_master_secret; + + ssl->method->next_message(ssl); + hs->state = state_read_client_certificate_verify; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_read_client_certificate_verify(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + + // Only RSA and ECDSA client certificates are supported, so a + // CertificateVerify is required if and only if there's a client certificate. + if (!hs->peer_pubkey) { + hs->transcript.FreeBuffer(); + hs->state = state_read_change_cipher_spec; + return ssl_hs_ok; + } + + SSLMessage msg; + if (!ssl->method->get_message(ssl, &msg)) { + return ssl_hs_read_message; + } + + if (!ssl_check_message_type(ssl, msg, SSL3_MT_CERTIFICATE_VERIFY)) { + return ssl_hs_error; + } + + CBS certificate_verify = msg.body, signature; + + // Determine the signature algorithm. + uint16_t signature_algorithm = 0; + if (ssl_protocol_version(ssl) >= TLS1_2_VERSION) { + if (!CBS_get_u16(&certificate_verify, &signature_algorithm)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return ssl_hs_error; + } + uint8_t alert = SSL_AD_DECODE_ERROR; + if (!tls12_check_peer_sigalg(ssl, &alert, signature_algorithm)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + return ssl_hs_error; + } + hs->new_session->peer_signature_algorithm = signature_algorithm; + } else if (!tls1_get_legacy_signature_algorithm(&signature_algorithm, + hs->peer_pubkey.get())) { + OPENSSL_PUT_ERROR(SSL, SSL_R_PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNSUPPORTED_CERTIFICATE); + return ssl_hs_error; + } + + // Parse and verify the signature. + if (!CBS_get_u16_length_prefixed(&certificate_verify, &signature) || + CBS_len(&certificate_verify) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return ssl_hs_error; + } + + bool sig_ok; + // The SSL3 construction for CertificateVerify does not decompose into a + // single final digest and signature, and must be special-cased. + if (ssl_protocol_version(ssl) == SSL3_VERSION) { + uint8_t digest[EVP_MAX_MD_SIZE]; + size_t digest_len; + if (!hs->transcript.GetSSL3CertVerifyHash( + digest, &digest_len, hs->new_session.get(), signature_algorithm)) { + return ssl_hs_error; + } + + UniquePtr pctx( + EVP_PKEY_CTX_new(hs->peer_pubkey.get(), nullptr)); + sig_ok = pctx && + EVP_PKEY_verify_init(pctx.get()) && + EVP_PKEY_verify(pctx.get(), CBS_data(&signature), + CBS_len(&signature), digest, digest_len); + } else { + sig_ok = + ssl_public_key_verify(ssl, signature, signature_algorithm, + hs->peer_pubkey.get(), hs->transcript.buffer()); + } + +#if defined(BORINGSSL_UNSAFE_FUZZER_MODE) + sig_ok = true; + ERR_clear_error(); +#endif + if (!sig_ok) { + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SIGNATURE); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECRYPT_ERROR); + return ssl_hs_error; + } + + // The handshake buffer is no longer necessary, and we may hash the current + // message. + hs->transcript.FreeBuffer(); + if (!ssl_hash_message(hs, msg)) { + return ssl_hs_error; + } + + ssl->method->next_message(ssl); + hs->state = state_read_change_cipher_spec; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_read_change_cipher_spec(SSL_HANDSHAKE *hs) { + hs->state = state_process_change_cipher_spec; + return ssl_hs_read_change_cipher_spec; +} + +static enum ssl_hs_wait_t do_process_change_cipher_spec(SSL_HANDSHAKE *hs) { + if (!tls1_change_cipher_state(hs, evp_aead_open)) { + return ssl_hs_error; + } + + hs->state = state_read_next_proto; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_read_next_proto(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + + if (!hs->next_proto_neg_seen) { + hs->state = state_read_channel_id; + return ssl_hs_ok; + } + + SSLMessage msg; + if (!ssl->method->get_message(ssl, &msg)) { + return ssl_hs_read_message; + } + + if (!ssl_check_message_type(ssl, msg, SSL3_MT_NEXT_PROTO) || + !ssl_hash_message(hs, msg)) { + return ssl_hs_error; + } + + CBS next_protocol = msg.body, selected_protocol, padding; + if (!CBS_get_u8_length_prefixed(&next_protocol, &selected_protocol) || + !CBS_get_u8_length_prefixed(&next_protocol, &padding) || + CBS_len(&next_protocol) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return ssl_hs_error; + } + + if (!ssl->s3->next_proto_negotiated.CopyFrom(selected_protocol)) { + return ssl_hs_error; + } + + ssl->method->next_message(ssl); + hs->state = state_read_channel_id; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_read_channel_id(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + + if (!ssl->s3->tlsext_channel_id_valid) { + hs->state = state_read_client_finished; + return ssl_hs_ok; + } + + SSLMessage msg; + if (!ssl->method->get_message(ssl, &msg)) { + return ssl_hs_read_message; + } + + if (!ssl_check_message_type(ssl, msg, SSL3_MT_CHANNEL_ID) || + !tls1_verify_channel_id(hs, msg) || + !ssl_hash_message(hs, msg)) { + return ssl_hs_error; + } + + ssl->method->next_message(ssl); + hs->state = state_read_client_finished; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_read_client_finished(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + enum ssl_hs_wait_t wait = ssl_get_finished(hs); + if (wait != ssl_hs_ok) { + return wait; + } + + if (ssl->session != NULL) { + hs->state = state_finish_server_handshake; + } else { + hs->state = state_send_server_finished; + } + + // If this is a full handshake with ChannelID then record the handshake + // hashes in |hs->new_session| in case we need them to verify a + // ChannelID signature on a resumption of this session in the future. + if (ssl->session == NULL && ssl->s3->tlsext_channel_id_valid && + !tls1_record_handshake_hashes_for_channel_id(hs)) { + return ssl_hs_error; + } + + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_send_server_finished(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + + if (hs->ticket_expected) { + const SSL_SESSION *session; + UniquePtr session_copy; + if (ssl->session == NULL) { + // Fix the timeout to measure from the ticket issuance time. + ssl_session_rebase_time(ssl, hs->new_session.get()); + session = hs->new_session.get(); + } else { + // We are renewing an existing session. Duplicate the session to adjust + // the timeout. + session_copy = SSL_SESSION_dup(ssl->session, SSL_SESSION_INCLUDE_NONAUTH); + if (!session_copy) { + return ssl_hs_error; + } + + ssl_session_rebase_time(ssl, session_copy.get()); + session = session_copy.get(); + } + + ScopedCBB cbb; + CBB body, ticket; + if (!ssl->method->init_message(ssl, cbb.get(), &body, + SSL3_MT_NEW_SESSION_TICKET) || + !CBB_add_u32(&body, session->timeout) || + !CBB_add_u16_length_prefixed(&body, &ticket) || + !ssl_encrypt_ticket(ssl, &ticket, session) || + !ssl_add_message_cbb(ssl, cbb.get())) { + return ssl_hs_error; + } + } + + if (!ssl->method->add_change_cipher_spec(ssl) || + !tls1_change_cipher_state(hs, evp_aead_seal) || + !ssl_send_finished(hs)) { + return ssl_hs_error; + } + + if (ssl->session != NULL) { + hs->state = state_read_change_cipher_spec; + } else { + hs->state = state_finish_server_handshake; + } + return ssl_hs_flush; +} + +static enum ssl_hs_wait_t do_finish_server_handshake(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + + ssl->method->on_handshake_complete(ssl); + + // If we aren't retaining peer certificates then we can discard it now. + if (hs->new_session != NULL && ssl->retain_only_sha256_of_client_certs) { + sk_CRYPTO_BUFFER_pop_free(hs->new_session->certs, CRYPTO_BUFFER_free); + hs->new_session->certs = NULL; + ssl->ctx->x509_method->session_clear(hs->new_session.get()); + } + + if (ssl->session != NULL) { + SSL_SESSION_up_ref(ssl->session); + ssl->s3->established_session.reset(ssl->session); + } else { + ssl->s3->established_session = std::move(hs->new_session); + ssl->s3->established_session->not_resumable = 0; + } + + hs->handshake_finalized = true; + ssl->s3->initial_handshake_complete = true; + ssl_update_cache(hs, SSL_SESS_CACHE_SERVER); + + hs->state = state_done; + return ssl_hs_ok; +} + +enum ssl_hs_wait_t ssl_server_handshake(SSL_HANDSHAKE *hs) { + while (hs->state != state_done) { + enum ssl_hs_wait_t ret = ssl_hs_error; + enum ssl_server_hs_state_t state = + static_cast(hs->state); + switch (state) { + case state_start_accept: + ret = do_start_accept(hs); + break; + case state_read_client_hello: + ret = do_read_client_hello(hs); + break; + case state_select_certificate: + ret = do_select_certificate(hs); + break; + case state_tls13: + ret = do_tls13(hs); + break; + case state_select_parameters: + ret = do_select_parameters(hs); + break; + case state_send_server_hello: + ret = do_send_server_hello(hs); + break; + case state_send_server_certificate: + ret = do_send_server_certificate(hs); + break; + case state_send_server_key_exchange: + ret = do_send_server_key_exchange(hs); + break; + case state_send_server_hello_done: + ret = do_send_server_hello_done(hs); + break; + case state_read_client_certificate: + ret = do_read_client_certificate(hs); + break; + case state_verify_client_certificate: + ret = do_verify_client_certificate(hs); + break; + case state_read_client_key_exchange: + ret = do_read_client_key_exchange(hs); + break; + case state_read_client_certificate_verify: + ret = do_read_client_certificate_verify(hs); + break; + case state_read_change_cipher_spec: + ret = do_read_change_cipher_spec(hs); + break; + case state_process_change_cipher_spec: + ret = do_process_change_cipher_spec(hs); + break; + case state_read_next_proto: + ret = do_read_next_proto(hs); + break; + case state_read_channel_id: + ret = do_read_channel_id(hs); + break; + case state_read_client_finished: + ret = do_read_client_finished(hs); + break; + case state_send_server_finished: + ret = do_send_server_finished(hs); + break; + case state_finish_server_handshake: + ret = do_finish_server_handshake(hs); + break; + case state_done: + ret = ssl_hs_ok; + break; + } + + if (hs->state != state) { + ssl_do_info_callback(hs->ssl, SSL_CB_ACCEPT_LOOP, 1); + } + + if (ret != ssl_hs_ok) { + return ret; + } + } + + ssl_do_info_callback(hs->ssl, SSL_CB_HANDSHAKE_DONE, 1); + return ssl_hs_ok; +} + +const char *ssl_server_handshake_state(SSL_HANDSHAKE *hs) { + enum ssl_server_hs_state_t state = + static_cast(hs->state); + switch (state) { + case state_start_accept: + return "TLS server start_accept"; + case state_read_client_hello: + return "TLS server read_client_hello"; + case state_select_certificate: + return "TLS server select_certificate"; + case state_tls13: + return tls13_server_handshake_state(hs); + case state_select_parameters: + return "TLS server select_parameters"; + case state_send_server_hello: + return "TLS server send_server_hello"; + case state_send_server_certificate: + return "TLS server send_server_certificate"; + case state_send_server_key_exchange: + return "TLS server send_server_key_exchange"; + case state_send_server_hello_done: + return "TLS server send_server_hello_done"; + case state_read_client_certificate: + return "TLS server read_client_certificate"; + case state_verify_client_certificate: + return "TLS server verify_client_certificate"; + case state_read_client_key_exchange: + return "TLS server read_client_key_exchange"; + case state_read_client_certificate_verify: + return "TLS server read_client_certificate_verify"; + case state_read_change_cipher_spec: + return "TLS server read_change_cipher_spec"; + case state_process_change_cipher_spec: + return "TLS server process_change_cipher_spec"; + case state_read_next_proto: + return "TLS server read_next_proto"; + case state_read_channel_id: + return "TLS server read_channel_id"; + case state_read_client_finished: + return "TLS server read_client_finished"; + case state_send_server_finished: + return "TLS server send_server_finished"; + case state_finish_server_handshake: + return "TLS server finish_server_handshake"; + case state_done: + return "TLS server done"; + } + + return "TLS server unknown"; +} + +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/ssl/handshake_server.cc.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/ssl/handshake_server.cc.grpc_back new file mode 100644 index 0000000..fa8a241 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/ssl/handshake_server.cc.grpc_back @@ -0,0 +1,1674 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "internal.h" +#include "../crypto/internal.h" + + +namespace bssl { + +enum ssl_server_hs_state_t { + state_start_accept = 0, + state_read_client_hello, + state_select_certificate, + state_tls13, + state_select_parameters, + state_send_server_hello, + state_send_server_certificate, + state_send_server_key_exchange, + state_send_server_hello_done, + state_read_client_certificate, + state_verify_client_certificate, + state_read_client_key_exchange, + state_read_client_certificate_verify, + state_read_change_cipher_spec, + state_process_change_cipher_spec, + state_read_next_proto, + state_read_channel_id, + state_read_client_finished, + state_send_server_finished, + state_finish_server_handshake, + state_done, +}; + +int ssl_client_cipher_list_contains_cipher(const SSL_CLIENT_HELLO *client_hello, + uint16_t id) { + CBS cipher_suites; + CBS_init(&cipher_suites, client_hello->cipher_suites, + client_hello->cipher_suites_len); + + while (CBS_len(&cipher_suites) > 0) { + uint16_t got_id; + if (!CBS_get_u16(&cipher_suites, &got_id)) { + return 0; + } + + if (got_id == id) { + return 1; + } + } + + return 0; +} + +static int negotiate_version(SSL_HANDSHAKE *hs, uint8_t *out_alert, + const SSL_CLIENT_HELLO *client_hello) { + SSL *const ssl = hs->ssl; + assert(!ssl->s3->have_version); + CBS supported_versions, versions; + if (ssl_client_hello_get_extension(client_hello, &supported_versions, + TLSEXT_TYPE_supported_versions)) { + if (!CBS_get_u8_length_prefixed(&supported_versions, &versions) || + CBS_len(&supported_versions) != 0 || + CBS_len(&versions) == 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + *out_alert = SSL_AD_DECODE_ERROR; + return 0; + } + } else { + // Convert the ClientHello version to an equivalent supported_versions + // extension. + static const uint8_t kTLSVersions[] = { + 0x03, 0x03, // TLS 1.2 + 0x03, 0x02, // TLS 1.1 + 0x03, 0x01, // TLS 1 + 0x03, 0x00, // SSL 3 + }; + + static const uint8_t kDTLSVersions[] = { + 0xfe, 0xfd, // DTLS 1.2 + 0xfe, 0xff, // DTLS 1.0 + }; + + size_t versions_len = 0; + if (SSL_is_dtls(ssl)) { + if (client_hello->version <= DTLS1_2_VERSION) { + versions_len = 4; + } else if (client_hello->version <= DTLS1_VERSION) { + versions_len = 2; + } + CBS_init(&versions, kDTLSVersions + sizeof(kDTLSVersions) - versions_len, + versions_len); + } else { + if (client_hello->version >= TLS1_2_VERSION) { + versions_len = 8; + } else if (client_hello->version >= TLS1_1_VERSION) { + versions_len = 6; + } else if (client_hello->version >= TLS1_VERSION) { + versions_len = 4; + } else if (client_hello->version >= SSL3_VERSION) { + versions_len = 2; + } + CBS_init(&versions, kTLSVersions + sizeof(kTLSVersions) - versions_len, + versions_len); + } + } + + if (!ssl_negotiate_version(hs, out_alert, &ssl->version, &versions)) { + return 0; + } + + // At this point, the connection's version is known and |ssl->version| is + // fixed. Begin enforcing the record-layer version. + ssl->s3->have_version = true; + ssl->s3->aead_write_ctx->SetVersionIfNullCipher(ssl->version); + + // Handle FALLBACK_SCSV. + if (ssl_client_cipher_list_contains_cipher(client_hello, + SSL3_CK_FALLBACK_SCSV & 0xffff) && + ssl_protocol_version(ssl) < hs->max_version) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INAPPROPRIATE_FALLBACK); + *out_alert = SSL3_AD_INAPPROPRIATE_FALLBACK; + return 0; + } + + return 1; +} + +static UniquePtr ssl_parse_client_cipher_list( + const SSL_CLIENT_HELLO *client_hello) { + CBS cipher_suites; + CBS_init(&cipher_suites, client_hello->cipher_suites, + client_hello->cipher_suites_len); + + UniquePtr sk(sk_SSL_CIPHER_new_null()); + if (!sk) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return nullptr; + } + + while (CBS_len(&cipher_suites) > 0) { + uint16_t cipher_suite; + + if (!CBS_get_u16(&cipher_suites, &cipher_suite)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_ERROR_IN_RECEIVED_CIPHER_LIST); + return nullptr; + } + + const SSL_CIPHER *c = SSL_get_cipher_by_value(cipher_suite); + if (c != NULL && !sk_SSL_CIPHER_push(sk.get(), c)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return nullptr; + } + } + + return sk; +} + +// ssl_get_compatible_server_ciphers determines the key exchange and +// authentication cipher suite masks compatible with the server configuration +// and current ClientHello parameters of |hs|. It sets |*out_mask_k| to the key +// exchange mask and |*out_mask_a| to the authentication mask. +static void ssl_get_compatible_server_ciphers(SSL_HANDSHAKE *hs, + uint32_t *out_mask_k, + uint32_t *out_mask_a) { + SSL *const ssl = hs->ssl; + uint32_t mask_k = 0; + uint32_t mask_a = 0; + + if (ssl_has_certificate(ssl)) { + mask_a |= ssl_cipher_auth_mask_for_key(hs->local_pubkey.get()); + if (EVP_PKEY_id(hs->local_pubkey.get()) == EVP_PKEY_RSA) { + mask_k |= SSL_kRSA; + } + } + + // Check for a shared group to consider ECDHE ciphers. + uint16_t unused; + if (tls1_get_shared_group(hs, &unused)) { + mask_k |= SSL_kECDHE; + } + + // PSK requires a server callback. + if (ssl->psk_server_callback != NULL) { + mask_k |= SSL_kPSK; + mask_a |= SSL_aPSK; + } + + *out_mask_k = mask_k; + *out_mask_a = mask_a; +} + +static const SSL_CIPHER *ssl3_choose_cipher( + SSL_HANDSHAKE *hs, const SSL_CLIENT_HELLO *client_hello, + const struct ssl_cipher_preference_list_st *server_pref) { + SSL *const ssl = hs->ssl; + STACK_OF(SSL_CIPHER) *prio, *allow; + // in_group_flags will either be NULL, or will point to an array of bytes + // which indicate equal-preference groups in the |prio| stack. See the + // comment about |in_group_flags| in the |ssl_cipher_preference_list_st| + // struct. + const uint8_t *in_group_flags; + // group_min contains the minimal index so far found in a group, or -1 if no + // such value exists yet. + int group_min = -1; + + UniquePtr client_pref = + ssl_parse_client_cipher_list(client_hello); + if (!client_pref) { + return nullptr; + } + + if (ssl->options & SSL_OP_CIPHER_SERVER_PREFERENCE) { + prio = server_pref->ciphers; + in_group_flags = server_pref->in_group_flags; + allow = client_pref.get(); + } else { + prio = client_pref.get(); + in_group_flags = NULL; + allow = server_pref->ciphers; + } + + uint32_t mask_k, mask_a; + ssl_get_compatible_server_ciphers(hs, &mask_k, &mask_a); + + for (size_t i = 0; i < sk_SSL_CIPHER_num(prio); i++) { + const SSL_CIPHER *c = sk_SSL_CIPHER_value(prio, i); + + size_t cipher_index; + if (// Check if the cipher is supported for the current version. + SSL_CIPHER_get_min_version(c) <= ssl_protocol_version(ssl) && + ssl_protocol_version(ssl) <= SSL_CIPHER_get_max_version(c) && + // Check the cipher is supported for the server configuration. + (c->algorithm_mkey & mask_k) && + (c->algorithm_auth & mask_a) && + // Check the cipher is in the |allow| list. + sk_SSL_CIPHER_find(allow, &cipher_index, c)) { + if (in_group_flags != NULL && in_group_flags[i] == 1) { + // This element of |prio| is in a group. Update the minimum index found + // so far and continue looking. + if (group_min == -1 || (size_t)group_min > cipher_index) { + group_min = cipher_index; + } + } else { + if (group_min != -1 && (size_t)group_min < cipher_index) { + cipher_index = group_min; + } + return sk_SSL_CIPHER_value(allow, cipher_index); + } + } + + if (in_group_flags != NULL && in_group_flags[i] == 0 && group_min != -1) { + // We are about to leave a group, but we found a match in it, so that's + // our answer. + return sk_SSL_CIPHER_value(allow, group_min); + } + } + + return nullptr; +} + +static enum ssl_hs_wait_t do_start_accept(SSL_HANDSHAKE *hs) { + ssl_do_info_callback(hs->ssl, SSL_CB_HANDSHAKE_START, 1); + hs->state = state_read_client_hello; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_read_client_hello(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + + SSLMessage msg; + if (!ssl->method->get_message(ssl, &msg)) { + return ssl_hs_read_message; + } + + if (!ssl_check_message_type(ssl, msg, SSL3_MT_CLIENT_HELLO)) { + return ssl_hs_error; + } + + if (ssl->handoff) { + return ssl_hs_handoff; + } + + SSL_CLIENT_HELLO client_hello; + if (!ssl_client_hello_init(ssl, &client_hello, msg)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return ssl_hs_error; + } + + // Run the early callback. + if (ssl->ctx->select_certificate_cb != NULL) { + switch (ssl->ctx->select_certificate_cb(&client_hello)) { + case ssl_select_cert_retry: + return ssl_hs_certificate_selection_pending; + + case ssl_select_cert_error: + // Connection rejected. + OPENSSL_PUT_ERROR(SSL, SSL_R_CONNECTION_REJECTED); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); + return ssl_hs_error; + + default: + /* fallthrough */; + } + } + + // Freeze the version range after the early callback. + if (!ssl_get_version_range(ssl, &hs->min_version, &hs->max_version)) { + return ssl_hs_error; + } + + uint8_t alert = SSL_AD_DECODE_ERROR; + if (!negotiate_version(hs, &alert, &client_hello)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + return ssl_hs_error; + } + + hs->client_version = client_hello.version; + if (client_hello.random_len != SSL3_RANDOM_SIZE) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return ssl_hs_error; + } + OPENSSL_memcpy(ssl->s3->client_random, client_hello.random, + client_hello.random_len); + + // Only null compression is supported. TLS 1.3 further requires the peer + // advertise no other compression. + if (OPENSSL_memchr(client_hello.compression_methods, 0, + client_hello.compression_methods_len) == NULL || + (ssl_protocol_version(ssl) >= TLS1_3_VERSION && + client_hello.compression_methods_len != 1)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_COMPRESSION_LIST); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + return ssl_hs_error; + } + + // TLS extensions. + if (!ssl_parse_clienthello_tlsext(hs, &client_hello)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_PARSE_TLSEXT); + return ssl_hs_error; + } + + hs->state = state_select_certificate; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_select_certificate(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + + SSLMessage msg; + if (!ssl->method->get_message(ssl, &msg)) { + return ssl_hs_read_message; + } + + // Call |cert_cb| to update server certificates if required. + if (ssl->cert->cert_cb != NULL) { + int rv = ssl->cert->cert_cb(ssl, ssl->cert->cert_cb_arg); + if (rv == 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_CERT_CB_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return ssl_hs_error; + } + if (rv < 0) { + return ssl_hs_x509_lookup; + } + } + + if (!ssl_on_certificate_selected(hs)) { + return ssl_hs_error; + } + + if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) { + // Jump to the TLS 1.3 state machine. + hs->state = state_tls13; + return ssl_hs_ok; + } + + SSL_CLIENT_HELLO client_hello; + if (!ssl_client_hello_init(ssl, &client_hello, msg)) { + return ssl_hs_error; + } + + // Negotiate the cipher suite. This must be done after |cert_cb| so the + // certificate is finalized. + hs->new_cipher = + ssl3_choose_cipher(hs, &client_hello, ssl_get_cipher_preferences(ssl)); + if (hs->new_cipher == NULL) { + OPENSSL_PUT_ERROR(SSL, SSL_R_NO_SHARED_CIPHER); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); + return ssl_hs_error; + } + + hs->state = state_select_parameters; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_tls13(SSL_HANDSHAKE *hs) { + enum ssl_hs_wait_t wait = tls13_server_handshake(hs); + if (wait == ssl_hs_ok) { + hs->state = state_finish_server_handshake; + return ssl_hs_ok; + } + + return wait; +} + +static enum ssl_hs_wait_t do_select_parameters(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + + SSLMessage msg; + if (!ssl->method->get_message(ssl, &msg)) { + return ssl_hs_read_message; + } + + SSL_CLIENT_HELLO client_hello; + if (!ssl_client_hello_init(ssl, &client_hello, msg)) { + return ssl_hs_error; + } + + // Determine whether we are doing session resumption. + UniquePtr session; + bool tickets_supported = false, renew_ticket = false; + enum ssl_hs_wait_t wait = ssl_get_prev_session( + ssl, &session, &tickets_supported, &renew_ticket, &client_hello); + if (wait != ssl_hs_ok) { + return wait; + } + + if (session) { + if (session->extended_master_secret && !hs->extended_master_secret) { + // A ClientHello without EMS that attempts to resume a session with EMS + // is fatal to the connection. + OPENSSL_PUT_ERROR(SSL, SSL_R_RESUMED_EMS_SESSION_WITHOUT_EMS_EXTENSION); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); + return ssl_hs_error; + } + + if (!ssl_session_is_resumable(hs, session.get()) || + // If the client offers the EMS extension, but the previous session + // didn't use it, then negotiate a new session. + hs->extended_master_secret != session->extended_master_secret) { + session.reset(); + } + } + + if (session) { + // Use the old session. + hs->ticket_expected = renew_ticket; + ssl->session = session.release(); + ssl->s3->session_reused = true; + } else { + hs->ticket_expected = tickets_supported; + ssl_set_session(ssl, NULL); + if (!ssl_get_new_session(hs, 1 /* server */)) { + return ssl_hs_error; + } + + // Clear the session ID if we want the session to be single-use. + if (!(ssl->ctx->session_cache_mode & SSL_SESS_CACHE_SERVER)) { + hs->new_session->session_id_length = 0; + } + } + + if (ssl->ctx->dos_protection_cb != NULL && + ssl->ctx->dos_protection_cb(&client_hello) == 0) { + // Connection rejected for DOS reasons. + OPENSSL_PUT_ERROR(SSL, SSL_R_CONNECTION_REJECTED); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return ssl_hs_error; + } + + if (ssl->session == NULL) { + hs->new_session->cipher = hs->new_cipher; + + // Determine whether to request a client certificate. + hs->cert_request = !!(ssl->verify_mode & SSL_VERIFY_PEER); + // Only request a certificate if Channel ID isn't negotiated. + if ((ssl->verify_mode & SSL_VERIFY_PEER_IF_NO_OBC) && + ssl->s3->tlsext_channel_id_valid) { + hs->cert_request = false; + } + // CertificateRequest may only be sent in certificate-based ciphers. + if (!ssl_cipher_uses_certificate_auth(hs->new_cipher)) { + hs->cert_request = false; + } + + if (!hs->cert_request) { + // OpenSSL returns X509_V_OK when no certificates are requested. This is + // classed by them as a bug, but it's assumed by at least NGINX. + hs->new_session->verify_result = X509_V_OK; + } + } + + // HTTP/2 negotiation depends on the cipher suite, so ALPN negotiation was + // deferred. Complete it now. + uint8_t alert = SSL_AD_DECODE_ERROR; + if (!ssl_negotiate_alpn(hs, &alert, &client_hello)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + return ssl_hs_error; + } + + // Now that all parameters are known, initialize the handshake hash and hash + // the ClientHello. + if (!hs->transcript.InitHash(ssl_protocol_version(ssl), hs->new_cipher) || + !ssl_hash_message(hs, msg)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return ssl_hs_error; + } + + // Release the handshake buffer if client authentication isn't required. + if (!hs->cert_request) { + hs->transcript.FreeBuffer(); + } + + ssl->method->next_message(ssl); + + hs->state = state_send_server_hello; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_send_server_hello(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + + // We only accept ChannelIDs on connections with ECDHE in order to avoid a + // known attack while we fix ChannelID itself. + if (ssl->s3->tlsext_channel_id_valid && + (hs->new_cipher->algorithm_mkey & SSL_kECDHE) == 0) { + ssl->s3->tlsext_channel_id_valid = false; + } + + // If this is a resumption and the original handshake didn't support + // ChannelID then we didn't record the original handshake hashes in the + // session and so cannot resume with ChannelIDs. + if (ssl->session != NULL && + ssl->session->original_handshake_hash_len == 0) { + ssl->s3->tlsext_channel_id_valid = false; + } + + struct OPENSSL_timeval now; + ssl_get_current_time(ssl, &now); + ssl->s3->server_random[0] = now.tv_sec >> 24; + ssl->s3->server_random[1] = now.tv_sec >> 16; + ssl->s3->server_random[2] = now.tv_sec >> 8; + ssl->s3->server_random[3] = now.tv_sec; + if (!RAND_bytes(ssl->s3->server_random + 4, SSL3_RANDOM_SIZE - 4)) { + return ssl_hs_error; + } + + // Implement the TLS 1.3 anti-downgrade feature, but with a different value. + // + // For draft TLS 1.3 versions, it is not safe to deploy this feature. However, + // some TLS terminators are non-compliant and copy the origin server's value, + // so we wish to measure eventual compatibility impact. + if (hs->max_version >= TLS1_3_VERSION) { + OPENSSL_memcpy(ssl->s3->server_random + SSL3_RANDOM_SIZE - + sizeof(kDraftDowngradeRandom), + kDraftDowngradeRandom, sizeof(kDraftDowngradeRandom)); + } + + const SSL_SESSION *session = hs->new_session.get(); + if (ssl->session != NULL) { + session = ssl->session; + } + + ScopedCBB cbb; + CBB body, session_id; + if (!ssl->method->init_message(ssl, cbb.get(), &body, SSL3_MT_SERVER_HELLO) || + !CBB_add_u16(&body, ssl->version) || + !CBB_add_bytes(&body, ssl->s3->server_random, SSL3_RANDOM_SIZE) || + !CBB_add_u8_length_prefixed(&body, &session_id) || + !CBB_add_bytes(&session_id, session->session_id, + session->session_id_length) || + !CBB_add_u16(&body, ssl_cipher_get_value(hs->new_cipher)) || + !CBB_add_u8(&body, 0 /* no compression */) || + !ssl_add_serverhello_tlsext(hs, &body) || + !ssl_add_message_cbb(ssl, cbb.get())) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return ssl_hs_error; + } + + if (ssl->session != NULL) { + hs->state = state_send_server_finished; + } else { + hs->state = state_send_server_certificate; + } + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_send_server_certificate(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + ScopedCBB cbb; + + if (ssl_cipher_uses_certificate_auth(hs->new_cipher)) { + if (!ssl_has_certificate(ssl)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CERTIFICATE_SET); + return ssl_hs_error; + } + + if (!ssl_output_cert_chain(ssl)) { + return ssl_hs_error; + } + + if (hs->certificate_status_expected) { + CBB body, ocsp_response; + if (!ssl->method->init_message(ssl, cbb.get(), &body, + SSL3_MT_CERTIFICATE_STATUS) || + !CBB_add_u8(&body, TLSEXT_STATUSTYPE_ocsp) || + !CBB_add_u24_length_prefixed(&body, &ocsp_response) || + !CBB_add_bytes(&ocsp_response, + CRYPTO_BUFFER_data(ssl->cert->ocsp_response), + CRYPTO_BUFFER_len(ssl->cert->ocsp_response)) || + !ssl_add_message_cbb(ssl, cbb.get())) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return ssl_hs_error; + } + } + } + + // Assemble ServerKeyExchange parameters if needed. + uint32_t alg_k = hs->new_cipher->algorithm_mkey; + uint32_t alg_a = hs->new_cipher->algorithm_auth; + if (ssl_cipher_requires_server_key_exchange(hs->new_cipher) || + ((alg_a & SSL_aPSK) && ssl->psk_identity_hint)) { + + // Pre-allocate enough room to comfortably fit an ECDHE public key. Prepend + // the client and server randoms for the signing transcript. + CBB child; + if (!CBB_init(cbb.get(), SSL3_RANDOM_SIZE * 2 + 128) || + !CBB_add_bytes(cbb.get(), ssl->s3->client_random, SSL3_RANDOM_SIZE) || + !CBB_add_bytes(cbb.get(), ssl->s3->server_random, SSL3_RANDOM_SIZE)) { + return ssl_hs_error; + } + + // PSK ciphers begin with an identity hint. + if (alg_a & SSL_aPSK) { + size_t len = + (ssl->psk_identity_hint == NULL) ? 0 : strlen(ssl->psk_identity_hint); + if (!CBB_add_u16_length_prefixed(cbb.get(), &child) || + !CBB_add_bytes(&child, (const uint8_t *)ssl->psk_identity_hint, + len)) { + return ssl_hs_error; + } + } + + if (alg_k & SSL_kECDHE) { + // Determine the group to use. + uint16_t group_id; + if (!tls1_get_shared_group(hs, &group_id)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); + return ssl_hs_error; + } + hs->new_session->group_id = group_id; + + // Set up ECDH, generate a key, and emit the public half. + hs->key_share = SSLKeyShare::Create(group_id); + if (!hs->key_share || + !CBB_add_u8(cbb.get(), NAMED_CURVE_TYPE) || + !CBB_add_u16(cbb.get(), group_id) || + !CBB_add_u8_length_prefixed(cbb.get(), &child) || + !hs->key_share->Offer(&child)) { + return ssl_hs_error; + } + } else { + assert(alg_k & SSL_kPSK); + } + + if (!CBBFinishArray(cbb.get(), &hs->server_params)) { + return ssl_hs_error; + } + } + + hs->state = state_send_server_key_exchange; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_send_server_key_exchange(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + + if (hs->server_params.size() == 0) { + hs->state = state_send_server_hello_done; + return ssl_hs_ok; + } + + ScopedCBB cbb; + CBB body, child; + if (!ssl->method->init_message(ssl, cbb.get(), &body, + SSL3_MT_SERVER_KEY_EXCHANGE) || + // |hs->server_params| contains a prefix for signing. + hs->server_params.size() < 2 * SSL3_RANDOM_SIZE || + !CBB_add_bytes(&body, hs->server_params.data() + 2 * SSL3_RANDOM_SIZE, + hs->server_params.size() - 2 * SSL3_RANDOM_SIZE)) { + return ssl_hs_error; + } + + // Add a signature. + if (ssl_cipher_uses_certificate_auth(hs->new_cipher)) { + if (!ssl_has_private_key(ssl)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return ssl_hs_error; + } + + // Determine the signature algorithm. + uint16_t signature_algorithm; + if (!tls1_choose_signature_algorithm(hs, &signature_algorithm)) { + return ssl_hs_error; + } + if (ssl_protocol_version(ssl) >= TLS1_2_VERSION) { + if (!CBB_add_u16(&body, signature_algorithm)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return ssl_hs_error; + } + } + + // Add space for the signature. + const size_t max_sig_len = EVP_PKEY_size(hs->local_pubkey.get()); + uint8_t *ptr; + if (!CBB_add_u16_length_prefixed(&body, &child) || + !CBB_reserve(&child, &ptr, max_sig_len)) { + return ssl_hs_error; + } + + size_t sig_len; + switch (ssl_private_key_sign(hs, ptr, &sig_len, max_sig_len, + signature_algorithm, hs->server_params)) { + case ssl_private_key_success: + if (!CBB_did_write(&child, sig_len)) { + return ssl_hs_error; + } + break; + case ssl_private_key_failure: + return ssl_hs_error; + case ssl_private_key_retry: + return ssl_hs_private_key_operation; + } + } + + if (!ssl_add_message_cbb(ssl, cbb.get())) { + return ssl_hs_error; + } + + hs->server_params.Reset(); + + hs->state = state_send_server_hello_done; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_send_server_hello_done(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + + ScopedCBB cbb; + CBB body; + + if (hs->cert_request) { + CBB cert_types, sigalgs_cbb; + if (!ssl->method->init_message(ssl, cbb.get(), &body, + SSL3_MT_CERTIFICATE_REQUEST) || + !CBB_add_u8_length_prefixed(&body, &cert_types) || + !CBB_add_u8(&cert_types, SSL3_CT_RSA_SIGN) || + (ssl_protocol_version(ssl) >= TLS1_VERSION && + !CBB_add_u8(&cert_types, TLS_CT_ECDSA_SIGN)) || + (ssl_protocol_version(ssl) >= TLS1_2_VERSION && + (!CBB_add_u16_length_prefixed(&body, &sigalgs_cbb) || + !tls12_add_verify_sigalgs(ssl, &sigalgs_cbb))) || + !ssl_add_client_CA_list(ssl, &body) || + !ssl_add_message_cbb(ssl, cbb.get())) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return ssl_hs_error; + } + } + + if (!ssl->method->init_message(ssl, cbb.get(), &body, + SSL3_MT_SERVER_HELLO_DONE) || + !ssl_add_message_cbb(ssl, cbb.get())) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return ssl_hs_error; + } + + hs->state = state_read_client_certificate; + return ssl_hs_flush; +} + +static enum ssl_hs_wait_t do_read_client_certificate(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + + if (!hs->cert_request) { + hs->state = state_verify_client_certificate; + return ssl_hs_ok; + } + + SSLMessage msg; + if (!ssl->method->get_message(ssl, &msg)) { + return ssl_hs_read_message; + } + + if (msg.type != SSL3_MT_CERTIFICATE) { + if (ssl->version == SSL3_VERSION && + msg.type == SSL3_MT_CLIENT_KEY_EXCHANGE) { + // In SSL 3.0, the Certificate message is omitted to signal no + // certificate. + if (ssl->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) { + OPENSSL_PUT_ERROR(SSL, SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); + return ssl_hs_error; + } + + // OpenSSL returns X509_V_OK when no certificates are received. This is + // classed by them as a bug, but it's assumed by at least NGINX. + hs->new_session->verify_result = X509_V_OK; + hs->state = state_verify_client_certificate; + return ssl_hs_ok; + } + + OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_MESSAGE); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE); + return ssl_hs_error; + } + + if (!ssl_hash_message(hs, msg)) { + return ssl_hs_error; + } + + CBS certificate_msg = msg.body; + uint8_t alert = SSL_AD_DECODE_ERROR; + UniquePtr chain; + if (!ssl_parse_cert_chain(&alert, &chain, &hs->peer_pubkey, + ssl->retain_only_sha256_of_client_certs + ? hs->new_session->peer_sha256 + : NULL, + &certificate_msg, ssl->ctx->pool)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + return ssl_hs_error; + } + sk_CRYPTO_BUFFER_pop_free(hs->new_session->certs, CRYPTO_BUFFER_free); + hs->new_session->certs = chain.release(); + + if (CBS_len(&certificate_msg) != 0 || + !ssl->ctx->x509_method->session_cache_objects(hs->new_session.get())) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return ssl_hs_error; + } + + if (sk_CRYPTO_BUFFER_num(hs->new_session->certs) == 0) { + // No client certificate so the handshake buffer may be discarded. + hs->transcript.FreeBuffer(); + + // In SSL 3.0, sending no certificate is signaled by omitting the + // Certificate message. + if (ssl->version == SSL3_VERSION) { + OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CERTIFICATES_RETURNED); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); + return ssl_hs_error; + } + + if (ssl->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) { + // Fail for TLS only if we required a certificate + OPENSSL_PUT_ERROR(SSL, SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); + return ssl_hs_error; + } + + // OpenSSL returns X509_V_OK when no certificates are received. This is + // classed by them as a bug, but it's assumed by at least NGINX. + hs->new_session->verify_result = X509_V_OK; + } else if (ssl->retain_only_sha256_of_client_certs) { + // The hash will have been filled in. + hs->new_session->peer_sha256_valid = 1; + } + + ssl->method->next_message(ssl); + hs->state = state_verify_client_certificate; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_verify_client_certificate(SSL_HANDSHAKE *hs) { + if (sk_CRYPTO_BUFFER_num(hs->new_session->certs) > 0) { + switch (ssl_verify_peer_cert(hs)) { + case ssl_verify_ok: + break; + case ssl_verify_invalid: + return ssl_hs_error; + case ssl_verify_retry: + return ssl_hs_certificate_verify; + } + } + + hs->state = state_read_client_key_exchange; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_read_client_key_exchange(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + SSLMessage msg; + if (!ssl->method->get_message(ssl, &msg)) { + return ssl_hs_read_message; + } + + if (!ssl_check_message_type(ssl, msg, SSL3_MT_CLIENT_KEY_EXCHANGE)) { + return ssl_hs_error; + } + + CBS client_key_exchange = msg.body; + uint32_t alg_k = hs->new_cipher->algorithm_mkey; + uint32_t alg_a = hs->new_cipher->algorithm_auth; + + // If using a PSK key exchange, parse the PSK identity. + if (alg_a & SSL_aPSK) { + CBS psk_identity; + + // If using PSK, the ClientKeyExchange contains a psk_identity. If PSK, + // then this is the only field in the message. + if (!CBS_get_u16_length_prefixed(&client_key_exchange, &psk_identity) || + ((alg_k & SSL_kPSK) && CBS_len(&client_key_exchange) != 0)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return ssl_hs_error; + } + + if (CBS_len(&psk_identity) > PSK_MAX_IDENTITY_LEN || + CBS_contains_zero_byte(&psk_identity)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DATA_LENGTH_TOO_LONG); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + return ssl_hs_error; + } + + if (!CBS_strdup(&psk_identity, &hs->new_session->psk_identity)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return ssl_hs_error; + } + } + + // Depending on the key exchange method, compute |premaster_secret|. + Array premaster_secret; + if (alg_k & SSL_kRSA) { + CBS encrypted_premaster_secret; + if (ssl->version > SSL3_VERSION) { + if (!CBS_get_u16_length_prefixed(&client_key_exchange, + &encrypted_premaster_secret) || + CBS_len(&client_key_exchange) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return ssl_hs_error; + } + } else { + encrypted_premaster_secret = client_key_exchange; + } + + // Allocate a buffer large enough for an RSA decryption. + Array decrypt_buf; + if (!decrypt_buf.Init(EVP_PKEY_size(hs->local_pubkey.get()))) { + return ssl_hs_error; + } + + // Decrypt with no padding. PKCS#1 padding will be removed as part of the + // timing-sensitive code below. + size_t decrypt_len; + switch (ssl_private_key_decrypt(hs, decrypt_buf.data(), &decrypt_len, + decrypt_buf.size(), + encrypted_premaster_secret)) { + case ssl_private_key_success: + break; + case ssl_private_key_failure: + return ssl_hs_error; + case ssl_private_key_retry: + return ssl_hs_private_key_operation; + } + + if (decrypt_len != decrypt_buf.size()) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECRYPTION_FAILED); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECRYPT_ERROR); + return ssl_hs_error; + } + + // Prepare a random premaster, to be used on invalid padding. See RFC 5246, + // section 7.4.7.1. + if (!premaster_secret.Init(SSL_MAX_MASTER_KEY_LENGTH) || + !RAND_bytes(premaster_secret.data(), premaster_secret.size())) { + return ssl_hs_error; + } + + // The smallest padded premaster is 11 bytes of overhead. Small keys are + // publicly invalid. + if (decrypt_len < 11 + premaster_secret.size()) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECRYPTION_FAILED); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECRYPT_ERROR); + return ssl_hs_error; + } + + // Check the padding. See RFC 3447, section 7.2.2. + size_t padding_len = decrypt_len - premaster_secret.size(); + uint8_t good = constant_time_eq_int_8(decrypt_buf[0], 0) & + constant_time_eq_int_8(decrypt_buf[1], 2); + for (size_t i = 2; i < padding_len - 1; i++) { + good &= ~constant_time_is_zero_8(decrypt_buf[i]); + } + good &= constant_time_is_zero_8(decrypt_buf[padding_len - 1]); + + // The premaster secret must begin with |client_version|. This too must be + // checked in constant time (http://eprint.iacr.org/2003/052/). + good &= constant_time_eq_8(decrypt_buf[padding_len], + (unsigned)(hs->client_version >> 8)); + good &= constant_time_eq_8(decrypt_buf[padding_len + 1], + (unsigned)(hs->client_version & 0xff)); + + // Select, in constant time, either the decrypted premaster or the random + // premaster based on |good|. + for (size_t i = 0; i < premaster_secret.size(); i++) { + premaster_secret[i] = constant_time_select_8( + good, decrypt_buf[padding_len + i], premaster_secret[i]); + } + } else if (alg_k & SSL_kECDHE) { + // Parse the ClientKeyExchange. + CBS peer_key; + if (!CBS_get_u8_length_prefixed(&client_key_exchange, &peer_key) || + CBS_len(&client_key_exchange) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return ssl_hs_error; + } + + // Compute the premaster. + uint8_t alert = SSL_AD_DECODE_ERROR; + if (!hs->key_share->Finish(&premaster_secret, &alert, peer_key)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + return ssl_hs_error; + } + + // The key exchange state may now be discarded. + hs->key_share.reset(); + } else if (!(alg_k & SSL_kPSK)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); + return ssl_hs_error; + } + + // For a PSK cipher suite, the actual pre-master secret is combined with the + // pre-shared key. + if (alg_a & SSL_aPSK) { + if (ssl->psk_server_callback == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return ssl_hs_error; + } + + // Look up the key for the identity. + uint8_t psk[PSK_MAX_PSK_LEN]; + unsigned psk_len = ssl->psk_server_callback( + ssl, hs->new_session->psk_identity, psk, sizeof(psk)); + if (psk_len > PSK_MAX_PSK_LEN) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return ssl_hs_error; + } else if (psk_len == 0) { + // PSK related to the given identity not found. + OPENSSL_PUT_ERROR(SSL, SSL_R_PSK_IDENTITY_NOT_FOUND); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNKNOWN_PSK_IDENTITY); + return ssl_hs_error; + } + + if (alg_k & SSL_kPSK) { + // In plain PSK, other_secret is a block of 0s with the same length as the + // pre-shared key. + if (!premaster_secret.Init(psk_len)) { + return ssl_hs_error; + } + OPENSSL_memset(premaster_secret.data(), 0, premaster_secret.size()); + } + + ScopedCBB new_premaster; + CBB child; + if (!CBB_init(new_premaster.get(), + 2 + psk_len + 2 + premaster_secret.size()) || + !CBB_add_u16_length_prefixed(new_premaster.get(), &child) || + !CBB_add_bytes(&child, premaster_secret.data(), + premaster_secret.size()) || + !CBB_add_u16_length_prefixed(new_premaster.get(), &child) || + !CBB_add_bytes(&child, psk, psk_len) || + !CBBFinishArray(new_premaster.get(), &premaster_secret)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return ssl_hs_error; + } + } + + if (!ssl_hash_message(hs, msg)) { + return ssl_hs_error; + } + + // Compute the master secret. + hs->new_session->master_key_length = tls1_generate_master_secret( + hs, hs->new_session->master_key, premaster_secret); + if (hs->new_session->master_key_length == 0) { + return ssl_hs_error; + } + hs->new_session->extended_master_secret = hs->extended_master_secret; + + ssl->method->next_message(ssl); + hs->state = state_read_client_certificate_verify; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_read_client_certificate_verify(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + + // Only RSA and ECDSA client certificates are supported, so a + // CertificateVerify is required if and only if there's a client certificate. + if (!hs->peer_pubkey) { + hs->transcript.FreeBuffer(); + hs->state = state_read_change_cipher_spec; + return ssl_hs_ok; + } + + SSLMessage msg; + if (!ssl->method->get_message(ssl, &msg)) { + return ssl_hs_read_message; + } + + if (!ssl_check_message_type(ssl, msg, SSL3_MT_CERTIFICATE_VERIFY)) { + return ssl_hs_error; + } + + CBS certificate_verify = msg.body, signature; + + // Determine the signature algorithm. + uint16_t signature_algorithm = 0; + if (ssl_protocol_version(ssl) >= TLS1_2_VERSION) { + if (!CBS_get_u16(&certificate_verify, &signature_algorithm)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return ssl_hs_error; + } + uint8_t alert = SSL_AD_DECODE_ERROR; + if (!tls12_check_peer_sigalg(ssl, &alert, signature_algorithm)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + return ssl_hs_error; + } + hs->new_session->peer_signature_algorithm = signature_algorithm; + } else if (!tls1_get_legacy_signature_algorithm(&signature_algorithm, + hs->peer_pubkey.get())) { + OPENSSL_PUT_ERROR(SSL, SSL_R_PEER_ERROR_UNSUPPORTED_CERTIFICATE_TYPE); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNSUPPORTED_CERTIFICATE); + return ssl_hs_error; + } + + // Parse and verify the signature. + if (!CBS_get_u16_length_prefixed(&certificate_verify, &signature) || + CBS_len(&certificate_verify) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return ssl_hs_error; + } + + bool sig_ok; + // The SSL3 construction for CertificateVerify does not decompose into a + // single final digest and signature, and must be special-cased. + if (ssl_protocol_version(ssl) == SSL3_VERSION) { + uint8_t digest[EVP_MAX_MD_SIZE]; + size_t digest_len; + if (!hs->transcript.GetSSL3CertVerifyHash( + digest, &digest_len, hs->new_session.get(), signature_algorithm)) { + return ssl_hs_error; + } + + UniquePtr pctx( + EVP_PKEY_CTX_new(hs->peer_pubkey.get(), nullptr)); + sig_ok = pctx && + EVP_PKEY_verify_init(pctx.get()) && + EVP_PKEY_verify(pctx.get(), CBS_data(&signature), + CBS_len(&signature), digest, digest_len); + } else { + sig_ok = + ssl_public_key_verify(ssl, signature, signature_algorithm, + hs->peer_pubkey.get(), hs->transcript.buffer()); + } + +#if defined(BORINGSSL_UNSAFE_FUZZER_MODE) + sig_ok = true; + ERR_clear_error(); +#endif + if (!sig_ok) { + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SIGNATURE); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECRYPT_ERROR); + return ssl_hs_error; + } + + // The handshake buffer is no longer necessary, and we may hash the current + // message. + hs->transcript.FreeBuffer(); + if (!ssl_hash_message(hs, msg)) { + return ssl_hs_error; + } + + ssl->method->next_message(ssl); + hs->state = state_read_change_cipher_spec; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_read_change_cipher_spec(SSL_HANDSHAKE *hs) { + hs->state = state_process_change_cipher_spec; + return ssl_hs_read_change_cipher_spec; +} + +static enum ssl_hs_wait_t do_process_change_cipher_spec(SSL_HANDSHAKE *hs) { + if (!tls1_change_cipher_state(hs, evp_aead_open)) { + return ssl_hs_error; + } + + hs->state = state_read_next_proto; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_read_next_proto(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + + if (!hs->next_proto_neg_seen) { + hs->state = state_read_channel_id; + return ssl_hs_ok; + } + + SSLMessage msg; + if (!ssl->method->get_message(ssl, &msg)) { + return ssl_hs_read_message; + } + + if (!ssl_check_message_type(ssl, msg, SSL3_MT_NEXT_PROTO) || + !ssl_hash_message(hs, msg)) { + return ssl_hs_error; + } + + CBS next_protocol = msg.body, selected_protocol, padding; + if (!CBS_get_u8_length_prefixed(&next_protocol, &selected_protocol) || + !CBS_get_u8_length_prefixed(&next_protocol, &padding) || + CBS_len(&next_protocol) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return ssl_hs_error; + } + + if (!ssl->s3->next_proto_negotiated.CopyFrom(selected_protocol)) { + return ssl_hs_error; + } + + ssl->method->next_message(ssl); + hs->state = state_read_channel_id; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_read_channel_id(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + + if (!ssl->s3->tlsext_channel_id_valid) { + hs->state = state_read_client_finished; + return ssl_hs_ok; + } + + SSLMessage msg; + if (!ssl->method->get_message(ssl, &msg)) { + return ssl_hs_read_message; + } + + if (!ssl_check_message_type(ssl, msg, SSL3_MT_CHANNEL_ID) || + !tls1_verify_channel_id(hs, msg) || + !ssl_hash_message(hs, msg)) { + return ssl_hs_error; + } + + ssl->method->next_message(ssl); + hs->state = state_read_client_finished; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_read_client_finished(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + enum ssl_hs_wait_t wait = ssl_get_finished(hs); + if (wait != ssl_hs_ok) { + return wait; + } + + if (ssl->session != NULL) { + hs->state = state_finish_server_handshake; + } else { + hs->state = state_send_server_finished; + } + + // If this is a full handshake with ChannelID then record the handshake + // hashes in |hs->new_session| in case we need them to verify a + // ChannelID signature on a resumption of this session in the future. + if (ssl->session == NULL && ssl->s3->tlsext_channel_id_valid && + !tls1_record_handshake_hashes_for_channel_id(hs)) { + return ssl_hs_error; + } + + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_send_server_finished(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + + if (hs->ticket_expected) { + const SSL_SESSION *session; + UniquePtr session_copy; + if (ssl->session == NULL) { + // Fix the timeout to measure from the ticket issuance time. + ssl_session_rebase_time(ssl, hs->new_session.get()); + session = hs->new_session.get(); + } else { + // We are renewing an existing session. Duplicate the session to adjust + // the timeout. + session_copy = SSL_SESSION_dup(ssl->session, SSL_SESSION_INCLUDE_NONAUTH); + if (!session_copy) { + return ssl_hs_error; + } + + ssl_session_rebase_time(ssl, session_copy.get()); + session = session_copy.get(); + } + + ScopedCBB cbb; + CBB body, ticket; + if (!ssl->method->init_message(ssl, cbb.get(), &body, + SSL3_MT_NEW_SESSION_TICKET) || + !CBB_add_u32(&body, session->timeout) || + !CBB_add_u16_length_prefixed(&body, &ticket) || + !ssl_encrypt_ticket(ssl, &ticket, session) || + !ssl_add_message_cbb(ssl, cbb.get())) { + return ssl_hs_error; + } + } + + if (!ssl->method->add_change_cipher_spec(ssl) || + !tls1_change_cipher_state(hs, evp_aead_seal) || + !ssl_send_finished(hs)) { + return ssl_hs_error; + } + + if (ssl->session != NULL) { + hs->state = state_read_change_cipher_spec; + } else { + hs->state = state_finish_server_handshake; + } + return ssl_hs_flush; +} + +static enum ssl_hs_wait_t do_finish_server_handshake(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + + ssl->method->on_handshake_complete(ssl); + + // If we aren't retaining peer certificates then we can discard it now. + if (hs->new_session != NULL && ssl->retain_only_sha256_of_client_certs) { + sk_CRYPTO_BUFFER_pop_free(hs->new_session->certs, CRYPTO_BUFFER_free); + hs->new_session->certs = NULL; + ssl->ctx->x509_method->session_clear(hs->new_session.get()); + } + + if (ssl->session != NULL) { + SSL_SESSION_up_ref(ssl->session); + ssl->s3->established_session.reset(ssl->session); + } else { + ssl->s3->established_session = std::move(hs->new_session); + ssl->s3->established_session->not_resumable = 0; + } + + hs->handshake_finalized = true; + ssl->s3->initial_handshake_complete = true; + ssl_update_cache(hs, SSL_SESS_CACHE_SERVER); + + hs->state = state_done; + return ssl_hs_ok; +} + +enum ssl_hs_wait_t ssl_server_handshake(SSL_HANDSHAKE *hs) { + while (hs->state != state_done) { + enum ssl_hs_wait_t ret = ssl_hs_error; + enum ssl_server_hs_state_t state = + static_cast(hs->state); + switch (state) { + case state_start_accept: + ret = do_start_accept(hs); + break; + case state_read_client_hello: + ret = do_read_client_hello(hs); + break; + case state_select_certificate: + ret = do_select_certificate(hs); + break; + case state_tls13: + ret = do_tls13(hs); + break; + case state_select_parameters: + ret = do_select_parameters(hs); + break; + case state_send_server_hello: + ret = do_send_server_hello(hs); + break; + case state_send_server_certificate: + ret = do_send_server_certificate(hs); + break; + case state_send_server_key_exchange: + ret = do_send_server_key_exchange(hs); + break; + case state_send_server_hello_done: + ret = do_send_server_hello_done(hs); + break; + case state_read_client_certificate: + ret = do_read_client_certificate(hs); + break; + case state_verify_client_certificate: + ret = do_verify_client_certificate(hs); + break; + case state_read_client_key_exchange: + ret = do_read_client_key_exchange(hs); + break; + case state_read_client_certificate_verify: + ret = do_read_client_certificate_verify(hs); + break; + case state_read_change_cipher_spec: + ret = do_read_change_cipher_spec(hs); + break; + case state_process_change_cipher_spec: + ret = do_process_change_cipher_spec(hs); + break; + case state_read_next_proto: + ret = do_read_next_proto(hs); + break; + case state_read_channel_id: + ret = do_read_channel_id(hs); + break; + case state_read_client_finished: + ret = do_read_client_finished(hs); + break; + case state_send_server_finished: + ret = do_send_server_finished(hs); + break; + case state_finish_server_handshake: + ret = do_finish_server_handshake(hs); + break; + case state_done: + ret = ssl_hs_ok; + break; + } + + if (hs->state != state) { + ssl_do_info_callback(hs->ssl, SSL_CB_ACCEPT_LOOP, 1); + } + + if (ret != ssl_hs_ok) { + return ret; + } + } + + ssl_do_info_callback(hs->ssl, SSL_CB_HANDSHAKE_DONE, 1); + return ssl_hs_ok; +} + +const char *ssl_server_handshake_state(SSL_HANDSHAKE *hs) { + enum ssl_server_hs_state_t state = + static_cast(hs->state); + switch (state) { + case state_start_accept: + return "TLS server start_accept"; + case state_read_client_hello: + return "TLS server read_client_hello"; + case state_select_certificate: + return "TLS server select_certificate"; + case state_tls13: + return tls13_server_handshake_state(hs); + case state_select_parameters: + return "TLS server select_parameters"; + case state_send_server_hello: + return "TLS server send_server_hello"; + case state_send_server_certificate: + return "TLS server send_server_certificate"; + case state_send_server_key_exchange: + return "TLS server send_server_key_exchange"; + case state_send_server_hello_done: + return "TLS server send_server_hello_done"; + case state_read_client_certificate: + return "TLS server read_client_certificate"; + case state_verify_client_certificate: + return "TLS server verify_client_certificate"; + case state_read_client_key_exchange: + return "TLS server read_client_key_exchange"; + case state_read_client_certificate_verify: + return "TLS server read_client_certificate_verify"; + case state_read_change_cipher_spec: + return "TLS server read_change_cipher_spec"; + case state_process_change_cipher_spec: + return "TLS server process_change_cipher_spec"; + case state_read_next_proto: + return "TLS server read_next_proto"; + case state_read_channel_id: + return "TLS server read_channel_id"; + case state_read_client_finished: + return "TLS server read_client_finished"; + case state_send_server_finished: + return "TLS server send_server_finished"; + case state_finish_server_handshake: + return "TLS server finish_server_handshake"; + case state_done: + return "TLS server done"; + } + + return "TLS server unknown"; +} + +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/ssl/internal.h b/FoodApp/Pods/BoringSSL-GRPC/ssl/internal.h new file mode 100644 index 0000000..955107c --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/ssl/internal.h @@ -0,0 +1,3064 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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. + */ +/* ==================================================================== + * 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 OPENSSL_HEADER_SSL_INTERNAL_H +#define OPENSSL_HEADER_SSL_INTERNAL_H + +#include + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "../crypto/err/internal.h" +#include "../crypto/internal.h" + + +#if defined(OPENSSL_WINDOWS) +// Windows defines struct timeval in winsock2.h. +OPENSSL_MSVC_PRAGMA(warning(push, 3)) +#include +OPENSSL_MSVC_PRAGMA(warning(pop)) +#else +#include +#endif + + +namespace bssl { + +struct SSL_HANDSHAKE; +struct SSL_PROTOCOL_METHOD; + +// C++ utilities. + +// New behaves like |new| but uses |OPENSSL_malloc| for memory allocation. It +// returns nullptr on allocation error. It only implements single-object +// allocation and not new T[n]. +// +// Note: unlike |new|, this does not support non-public constructors. +template +T *New(Args &&... args) { + void *t = OPENSSL_malloc(sizeof(T)); + if (t == nullptr) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return nullptr; + } + return new (t) T(std::forward(args)...); +} + +// Delete behaves like |delete| but uses |OPENSSL_free| to release memory. +// +// Note: unlike |delete| this does not support non-public destructors. +template +void Delete(T *t) { + if (t != nullptr) { + t->~T(); + OPENSSL_free(t); + } +} + +// All types with kAllowUniquePtr set may be used with UniquePtr. Other types +// may be C structs which require a |BORINGSSL_MAKE_DELETER| registration. +namespace internal { +template +struct DeleterImpl::type> { + static void Free(T *t) { Delete(t); } +}; +} + +// MakeUnique behaves like |std::make_unique| but returns nullptr on allocation +// error. +template +UniquePtr MakeUnique(Args &&... args) { + return UniquePtr(New(std::forward(args)...)); +} + +#if defined(BORINGSSL_ALLOW_CXX_RUNTIME) +#define HAS_VIRTUAL_DESTRUCTOR +#define PURE_VIRTUAL = 0 +#else +// HAS_VIRTUAL_DESTRUCTOR should be declared in any base class which defines a +// virtual destructor. This avoids a dependency on |_ZdlPv| and prevents the +// class from being used with |delete|. +#define HAS_VIRTUAL_DESTRUCTOR \ + void operator delete(void *) { abort(); } + +// PURE_VIRTUAL should be used instead of = 0 when defining pure-virtual +// functions. This avoids a dependency on |__cxa_pure_virtual| but loses +// compile-time checking. +#define PURE_VIRTUAL { abort(); } +#endif + +// CONSTEXPR_ARRAY works around a VS 2015 bug where ranged for loops don't work +// on constexpr arrays. +#if defined(_MSC_VER) && !defined(__clang__) && _MSC_VER < 1910 +#define CONSTEXPR_ARRAY const +#else +#define CONSTEXPR_ARRAY constexpr +#endif + +// Array is an owning array of elements of |T|. +template +class Array { + public: + // Array's default constructor creates an empty array. + Array() {} + Array(const Array &) = delete; + Array(Array &&other) { *this = std::move(other); } + + ~Array() { Reset(); } + + Array &operator=(const Array &) = delete; + Array &operator=(Array &&other) { + Reset(); + other.Release(&data_, &size_); + return *this; + } + + const T *data() const { return data_; } + T *data() { return data_; } + size_t size() const { return size_; } + bool empty() const { return size_ == 0; } + + const T &operator[](size_t i) const { return data_[i]; } + T &operator[](size_t i) { return data_[i]; } + + T *begin() { return data_; } + const T *cbegin() const { return data_; } + T *end() { return data_ + size_; } + const T *cend() const { return data_ + size_; } + + void Reset() { Reset(nullptr, 0); } + + // Reset releases the current contents of the array and takes ownership of the + // raw pointer supplied by the caller. + void Reset(T *new_data, size_t new_size) { + for (size_t i = 0; i < size_; i++) { + data_[i].~T(); + } + OPENSSL_free(data_); + data_ = new_data; + size_ = new_size; + } + + // Release releases ownership of the array to a raw pointer supplied by the + // caller. + void Release(T **out, size_t *out_size) { + *out = data_; + *out_size = size_; + data_ = nullptr; + size_ = 0; + } + + // Init replaces the array with a newly-allocated array of |new_size| + // default-constructed copies of |T|. It returns true on success and false on + // error. + // + // Note that if |T| is a primitive type like |uint8_t|, it is uninitialized. + bool Init(size_t new_size) { + Reset(); + if (new_size == 0) { + return true; + } + + if (new_size > std::numeric_limits::max() / sizeof(T)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW); + return false; + } + data_ = reinterpret_cast(OPENSSL_malloc(new_size * sizeof(T))); + if (data_ == nullptr) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return false; + } + size_ = new_size; + for (size_t i = 0; i < size_; i++) { + new (&data_[i]) T; + } + return true; + } + + // CopyFrom replaces the array with a newly-allocated copy of |in|. It returns + // true on success and false on error. + bool CopyFrom(Span in) { + if (!Init(in.size())) { + return false; + } + OPENSSL_memcpy(data_, in.data(), in.size()); + return true; + } + + private: + T *data_ = nullptr; + size_t size_ = 0; +}; + +// CBBFinishArray behaves like |CBB_finish| but stores the result in an Array. +OPENSSL_EXPORT bool CBBFinishArray(CBB *cbb, Array *out); + + +// Protocol versions. +// +// Due to DTLS's historical wire version differences and to support multiple +// variants of the same protocol during development, we maintain two notions of +// version. +// +// The "version" or "wire version" is the actual 16-bit value that appears on +// the wire. It uniquely identifies a version and is also used at API +// boundaries. The set of supported versions differs between TLS and DTLS. Wire +// versions are opaque values and may not be compared numerically. +// +// The "protocol version" identifies the high-level handshake variant being +// used. DTLS versions map to the corresponding TLS versions. Draft TLS 1.3 +// variants all map to TLS 1.3. Protocol versions are sequential and may be +// compared numerically. + +// ssl_protocol_version_from_wire sets |*out| to the protocol version +// corresponding to wire version |version| and returns true. If |version| is not +// a valid TLS or DTLS version, it returns false. +// +// Note this simultaneously handles both DTLS and TLS. Use one of the +// higher-level functions below for most operations. +bool ssl_protocol_version_from_wire(uint16_t *out, uint16_t version); + +// ssl_get_version_range sets |*out_min_version| and |*out_max_version| to the +// minimum and maximum enabled protocol versions, respectively. +bool ssl_get_version_range(const SSL *ssl, uint16_t *out_min_version, + uint16_t *out_max_version); + +// ssl_supports_version returns whether |hs| supports |version|. +bool ssl_supports_version(SSL_HANDSHAKE *hs, uint16_t version); + +// ssl_add_supported_versions writes the supported versions of |hs| to |cbb|, in +// decreasing preference order. +bool ssl_add_supported_versions(SSL_HANDSHAKE *hs, CBB *cbb); + +// ssl_negotiate_version negotiates a common version based on |hs|'s preferences +// and the peer preference list in |peer_versions|. On success, it returns true +// and sets |*out_version| to the selected version. Otherwise, it returns false +// and sets |*out_alert| to an alert to send. +bool ssl_negotiate_version(SSL_HANDSHAKE *hs, uint8_t *out_alert, + uint16_t *out_version, const CBS *peer_versions); + +// ssl_protocol_version returns |ssl|'s protocol version. It is an error to +// call this function before the version is determined. +uint16_t ssl_protocol_version(const SSL *ssl); + +// Cipher suites. + +} // namespace bssl + +struct ssl_cipher_st { + // name is the OpenSSL name for the cipher. + const char *name; + // standard_name is the IETF name for the cipher. + const char *standard_name; + // id is the cipher suite value bitwise OR-d with 0x03000000. + uint32_t id; + + // algorithm_* determine the cipher suite. See constants below for the values. + uint32_t algorithm_mkey; + uint32_t algorithm_auth; + uint32_t algorithm_enc; + uint32_t algorithm_mac; + uint32_t algorithm_prf; +}; + +namespace bssl { + +// Bits for |algorithm_mkey| (key exchange algorithm). +#define SSL_kRSA 0x00000001u +#define SSL_kECDHE 0x00000002u +// SSL_kPSK is only set for plain PSK, not ECDHE_PSK. +#define SSL_kPSK 0x00000004u +#define SSL_kGENERIC 0x00000008u + +// Bits for |algorithm_auth| (server authentication). +#define SSL_aRSA 0x00000001u +#define SSL_aECDSA 0x00000002u +// SSL_aPSK is set for both PSK and ECDHE_PSK. +#define SSL_aPSK 0x00000004u +#define SSL_aGENERIC 0x00000008u + +#define SSL_aCERT (SSL_aRSA | SSL_aECDSA) + +// Bits for |algorithm_enc| (symmetric encryption). +#define SSL_3DES 0x00000001u +#define SSL_AES128 0x00000002u +#define SSL_AES256 0x00000004u +#define SSL_AES128GCM 0x00000008u +#define SSL_AES256GCM 0x00000010u +#define SSL_eNULL 0x00000020u +#define SSL_CHACHA20POLY1305 0x00000040u + +#define SSL_AES (SSL_AES128 | SSL_AES256 | SSL_AES128GCM | SSL_AES256GCM) + +// Bits for |algorithm_mac| (symmetric authentication). +#define SSL_SHA1 0x00000001u +#define SSL_SHA256 0x00000002u +#define SSL_SHA384 0x00000004u +// SSL_AEAD is set for all AEADs. +#define SSL_AEAD 0x00000008u + +// Bits for |algorithm_prf| (handshake digest). +#define SSL_HANDSHAKE_MAC_DEFAULT 0x1 +#define SSL_HANDSHAKE_MAC_SHA256 0x2 +#define SSL_HANDSHAKE_MAC_SHA384 0x4 + +// SSL_MAX_DIGEST is the number of digest types which exist. When adding a new +// one, update the table in ssl_cipher.c. +#define SSL_MAX_DIGEST 4 + +// ssl_cipher_get_evp_aead sets |*out_aead| to point to the correct EVP_AEAD +// object for |cipher| protocol version |version|. It sets |*out_mac_secret_len| +// and |*out_fixed_iv_len| to the MAC key length and fixed IV length, +// respectively. The MAC key length is zero except for legacy block and stream +// ciphers. It returns true on success and false on error. +bool ssl_cipher_get_evp_aead(const EVP_AEAD **out_aead, + size_t *out_mac_secret_len, + size_t *out_fixed_iv_len, const SSL_CIPHER *cipher, + uint16_t version, int is_dtls); + +// ssl_get_handshake_digest returns the |EVP_MD| corresponding to |version| and +// |cipher|. +const EVP_MD *ssl_get_handshake_digest(uint16_t version, + const SSL_CIPHER *cipher); + +// ssl_create_cipher_list evaluates |rule_str|. It sets |*out_cipher_list| to a +// newly-allocated |ssl_cipher_preference_list_st| containing the result. It +// returns true on success and false on failure. If |strict| is true, nonsense +// will be rejected. If false, nonsense will be silently ignored. An empty +// result is considered an error regardless of |strict|. +bool ssl_create_cipher_list( + struct ssl_cipher_preference_list_st **out_cipher_list, + const char *rule_str, bool strict); + +// ssl_cipher_get_value returns the cipher suite id of |cipher|. +uint16_t ssl_cipher_get_value(const SSL_CIPHER *cipher); + +// ssl_cipher_auth_mask_for_key returns the mask of cipher |algorithm_auth| +// values suitable for use with |key| in TLS 1.2 and below. +uint32_t ssl_cipher_auth_mask_for_key(const EVP_PKEY *key); + +// ssl_cipher_uses_certificate_auth returns whether |cipher| authenticates the +// server and, optionally, the client with a certificate. +bool ssl_cipher_uses_certificate_auth(const SSL_CIPHER *cipher); + +// ssl_cipher_requires_server_key_exchange returns whether |cipher| requires a +// ServerKeyExchange message. +// +// This function may return false while still allowing |cipher| an optional +// ServerKeyExchange. This is the case for plain PSK ciphers. +bool ssl_cipher_requires_server_key_exchange(const SSL_CIPHER *cipher); + +// ssl_cipher_get_record_split_len, for TLS 1.0 CBC mode ciphers, returns the +// length of an encrypted 1-byte record, for use in record-splitting. Otherwise +// it returns zero. +size_t ssl_cipher_get_record_split_len(const SSL_CIPHER *cipher); + + +// Transcript layer. + +// SSLTranscript maintains the handshake transcript as a combination of a +// buffer and running hash. +class SSLTranscript { + public: + SSLTranscript(); + ~SSLTranscript(); + + // Init initializes the handshake transcript. If called on an existing + // transcript, it resets the transcript and hash. It returns true on success + // and false on failure. + bool Init(); + + // InitHash initializes the handshake hash based on the PRF and contents of + // the handshake transcript. Subsequent calls to |Update| will update the + // rolling hash. It returns one on success and zero on failure. It is an error + // to call this function after the handshake buffer is released. + bool InitHash(uint16_t version, const SSL_CIPHER *cipher); + + // UpdateForHelloRetryRequest resets the rolling hash with the + // HelloRetryRequest construction. It returns true on success and false on + // failure. It is an error to call this function before the handshake buffer + // is released. + bool UpdateForHelloRetryRequest(); + + // CopyHashContext copies the hash context into |ctx| and returns true on + // success. + bool CopyHashContext(EVP_MD_CTX *ctx); + + Span buffer() { + return MakeConstSpan(reinterpret_cast(buffer_->data), + buffer_->length); + } + + // FreeBuffer releases the handshake buffer. Subsequent calls to + // |Update| will not update the handshake buffer. + void FreeBuffer(); + + // DigestLen returns the length of the PRF hash. + size_t DigestLen() const; + + // Digest returns the PRF hash. For TLS 1.1 and below, this is + // |EVP_md5_sha1|. + const EVP_MD *Digest() const; + + // Update adds |in| to the handshake buffer and handshake hash, whichever is + // enabled. It returns true on success and false on failure. + bool Update(Span in); + + // GetHash writes the handshake hash to |out| which must have room for at + // least |DigestLen| bytes. On success, it returns true and sets |*out_len| to + // the number of bytes written. Otherwise, it returns false. + bool GetHash(uint8_t *out, size_t *out_len); + + // GetSSL3CertVerifyHash writes the SSL 3.0 CertificateVerify hash into the + // bytes pointed to by |out| and writes the number of bytes to + // |*out_len|. |out| must have room for |EVP_MAX_MD_SIZE| bytes. It returns + // one on success and zero on failure. + bool GetSSL3CertVerifyHash(uint8_t *out, size_t *out_len, + const SSL_SESSION *session, + uint16_t signature_algorithm); + + // GetFinishedMAC computes the MAC for the Finished message into the bytes + // pointed by |out| and writes the number of bytes to |*out_len|. |out| must + // have room for |EVP_MAX_MD_SIZE| bytes. It returns true on success and false + // on failure. + bool GetFinishedMAC(uint8_t *out, size_t *out_len, const SSL_SESSION *session, + bool from_server); + + private: + // buffer_, if non-null, contains the handshake transcript. + UniquePtr buffer_; + // hash, if initialized with an |EVP_MD|, maintains the handshake hash. For + // TLS 1.1 and below, it is the SHA-1 half. + ScopedEVP_MD_CTX hash_; + // md5, if initialized with an |EVP_MD|, maintains the MD5 half of the + // handshake hash for TLS 1.1 and below. + ScopedEVP_MD_CTX md5_; +}; + +// tls1_prf computes the PRF function for |ssl|. It fills |out|, using |secret| +// as the secret and |label| as the label. |seed1| and |seed2| are concatenated +// to form the seed parameter. It returns true on success and false on failure. +bool tls1_prf(const EVP_MD *digest, Span out, + Span secret, Span label, + Span seed1, Span seed2); + + +// Encryption layer. + +// SSLAEADContext contains information about an AEAD that is being used to +// encrypt an SSL connection. +class SSLAEADContext { + public: + SSLAEADContext(uint16_t version, bool is_dtls, const SSL_CIPHER *cipher); + ~SSLAEADContext(); + static constexpr bool kAllowUniquePtr = true; + + SSLAEADContext(const SSLAEADContext &&) = delete; + SSLAEADContext &operator=(const SSLAEADContext &&) = delete; + + // CreateNullCipher creates an |SSLAEADContext| for the null cipher. + static UniquePtr CreateNullCipher(bool is_dtls); + + // Create creates an |SSLAEADContext| using the supplied key material. It + // returns nullptr on error. Only one of |Open| or |Seal| may be used with the + // resulting object, depending on |direction|. |version| is the normalized + // protocol version, so DTLS 1.0 is represented as 0x0301, not 0xffef. + static UniquePtr Create(enum evp_aead_direction_t direction, + uint16_t version, int is_dtls, + const SSL_CIPHER *cipher, + Span enc_key, + Span mac_key, + Span fixed_iv); + + // SetVersionIfNullCipher sets the version the SSLAEADContext for the null + // cipher, to make version-specific determinations in the record layer prior + // to a cipher being selected. + void SetVersionIfNullCipher(uint16_t version); + + // ProtocolVersion returns the protocol version associated with this + // SSLAEADContext. It can only be called once |version_| has been set to a + // valid value. + uint16_t ProtocolVersion() const; + + // RecordVersion returns the record version that should be used with this + // SSLAEADContext for record construction and crypto. + uint16_t RecordVersion() const; + + const SSL_CIPHER *cipher() const { return cipher_; } + + // is_null_cipher returns true if this is the null cipher. + bool is_null_cipher() const { return !cipher_; } + + // ExplicitNonceLen returns the length of the explicit nonce. + size_t ExplicitNonceLen() const; + + // MaxOverhead returns the maximum overhead of calling |Seal|. + size_t MaxOverhead() const; + + // SuffixLen calculates the suffix length written by |SealScatter| and writes + // it to |*out_suffix_len|. It returns true on success and false on error. + // |in_len| and |extra_in_len| should equal the argument of the same names + // passed to |SealScatter|. + bool SuffixLen(size_t *out_suffix_len, size_t in_len, + size_t extra_in_len) const; + + // Open authenticates and decrypts |in| in-place. On success, it sets |*out| + // to the plaintext in |in| and returns true. Otherwise, it returns + // false. The output will always be |ExplicitNonceLen| bytes ahead of |in|. + bool Open(Span *out, uint8_t type, uint16_t record_version, + const uint8_t seqnum[8], Span in); + + // Seal encrypts and authenticates |in_len| bytes from |in| and writes the + // result to |out|. It returns true on success and false on error. + // + // If |in| and |out| alias then |out| + |ExplicitNonceLen| must be == |in|. + bool Seal(uint8_t *out, size_t *out_len, size_t max_out, uint8_t type, + uint16_t record_version, const uint8_t seqnum[8], const uint8_t *in, + size_t in_len); + + // SealScatter encrypts and authenticates |in_len| bytes from |in| and splits + // the result between |out_prefix|, |out| and |out_suffix|. It returns one on + // success and zero on error. + // + // On successful return, exactly |ExplicitNonceLen| bytes are written to + // |out_prefix|, |in_len| bytes to |out|, and |SuffixLen| bytes to + // |out_suffix|. + // + // |extra_in| may point to an additional plaintext buffer. If present, + // |extra_in_len| additional bytes are encrypted and authenticated, and the + // ciphertext is written to the beginning of |out_suffix|. |SuffixLen| should + // be used to size |out_suffix| accordingly. + // + // If |in| and |out| alias then |out| must be == |in|. Other arguments may not + // alias anything. + bool SealScatter(uint8_t *out_prefix, uint8_t *out, uint8_t *out_suffix, + uint8_t type, uint16_t record_version, + const uint8_t seqnum[8], const uint8_t *in, size_t in_len, + const uint8_t *extra_in, size_t extra_in_len); + + bool GetIV(const uint8_t **out_iv, size_t *out_iv_len) const; + + private: + // GetAdditionalData writes the additional data into |out| and returns the + // number of bytes written. + size_t GetAdditionalData(uint8_t out[13], uint8_t type, + uint16_t record_version, const uint8_t seqnum[8], + size_t plaintext_len); + + const SSL_CIPHER *cipher_; + ScopedEVP_AEAD_CTX ctx_; + // fixed_nonce_ contains any bytes of the nonce that are fixed for all + // records. + uint8_t fixed_nonce_[12]; + uint8_t fixed_nonce_len_ = 0, variable_nonce_len_ = 0; + // version_ is the wire version that should be used with this AEAD. + uint16_t version_; + // is_dtls_ is whether DTLS is being used with this AEAD. + bool is_dtls_; + // variable_nonce_included_in_record_ is true if the variable nonce + // for a record is included as a prefix before the ciphertext. + bool variable_nonce_included_in_record_ : 1; + // random_variable_nonce_ is true if the variable nonce is + // randomly generated, rather than derived from the sequence + // number. + bool random_variable_nonce_ : 1; + // omit_length_in_ad_ is true if the length should be omitted in the + // AEAD's ad parameter. + bool omit_length_in_ad_ : 1; + // omit_version_in_ad_ is true if the version should be omitted + // in the AEAD's ad parameter. + bool omit_version_in_ad_ : 1; + // omit_ad_ is true if the AEAD's ad parameter should be omitted. + bool omit_ad_ : 1; + // xor_fixed_nonce_ is true if the fixed nonce should be XOR'd into the + // variable nonce rather than prepended. + bool xor_fixed_nonce_ : 1; +}; + + +// DTLS replay bitmap. + +// DTLS1_BITMAP maintains a sliding window of 64 sequence numbers to detect +// replayed packets. It should be initialized by zeroing every field. +struct DTLS1_BITMAP { + // map is a bit mask of the last 64 sequence numbers. Bit + // |1< *out, size_t *out_consumed, + uint8_t *out_alert, Span in); + +// dtls_open_record implements |tls_open_record| for DTLS. It only returns +// |ssl_open_record_partial| if |in| was empty and sets |*out_consumed| to +// zero. The caller should read one packet and try again. +enum ssl_open_record_t dtls_open_record(SSL *ssl, uint8_t *out_type, + Span *out, + size_t *out_consumed, + uint8_t *out_alert, Span in); + +// ssl_seal_align_prefix_len returns the length of the prefix before the start +// of the bulk of the ciphertext when sealing a record with |ssl|. Callers may +// use this to align buffers. +// +// Note when TLS 1.0 CBC record-splitting is enabled, this includes the one byte +// record and is the offset into second record's ciphertext. Thus sealing a +// small record may result in a smaller output than this value. +// +// TODO(davidben): Is this alignment valuable? Record-splitting makes this a +// mess. +size_t ssl_seal_align_prefix_len(const SSL *ssl); + +// tls_seal_record seals a new record of type |type| and body |in| and writes it +// to |out|. At most |max_out| bytes will be written. It returns one on success +// and zero on error. If enabled, |tls_seal_record| implements TLS 1.0 CBC 1/n-1 +// record splitting and may write two records concatenated. +// +// For a large record, the bulk of the ciphertext will begin +// |ssl_seal_align_prefix_len| bytes into out. Aligning |out| appropriately may +// improve performance. It writes at most |in_len| + |SSL_max_seal_overhead| +// bytes to |out|. +// +// |in| and |out| may not alias. +int tls_seal_record(SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out, + uint8_t type, const uint8_t *in, size_t in_len); + +enum dtls1_use_epoch_t { + dtls1_use_previous_epoch, + dtls1_use_current_epoch, +}; + +// dtls_max_seal_overhead returns the maximum overhead, in bytes, of sealing a +// record. +size_t dtls_max_seal_overhead(const SSL *ssl, enum dtls1_use_epoch_t use_epoch); + +// dtls_seal_prefix_len returns the number of bytes of prefix to reserve in +// front of the plaintext when sealing a record in-place. +size_t dtls_seal_prefix_len(const SSL *ssl, enum dtls1_use_epoch_t use_epoch); + +// dtls_seal_record implements |tls_seal_record| for DTLS. |use_epoch| selects +// which epoch's cipher state to use. Unlike |tls_seal_record|, |in| and |out| +// may alias but, if they do, |in| must be exactly |dtls_seal_prefix_len| bytes +// ahead of |out|. +int dtls_seal_record(SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out, + uint8_t type, const uint8_t *in, size_t in_len, + enum dtls1_use_epoch_t use_epoch); + +// ssl_process_alert processes |in| as an alert and updates |ssl|'s shutdown +// state. It returns one of |ssl_open_record_discard|, |ssl_open_record_error|, +// |ssl_open_record_close_notify|, or |ssl_open_record_fatal_alert| as +// appropriate. +enum ssl_open_record_t ssl_process_alert(SSL *ssl, uint8_t *out_alert, + Span in); + + +// Private key operations. + +// ssl_has_private_key returns one if |ssl| has a private key +// configured and zero otherwise. +int ssl_has_private_key(const SSL *ssl); + +// ssl_private_key_* perform the corresponding operation on +// |SSL_PRIVATE_KEY_METHOD|. If there is a custom private key configured, they +// call the corresponding function or |complete| depending on whether there is a +// pending operation. Otherwise, they implement the operation with +// |EVP_PKEY|. + +enum ssl_private_key_result_t ssl_private_key_sign( + SSL_HANDSHAKE *hs, uint8_t *out, size_t *out_len, size_t max_out, + uint16_t sigalg, Span in); + +enum ssl_private_key_result_t ssl_private_key_decrypt(SSL_HANDSHAKE *hs, + uint8_t *out, + size_t *out_len, + size_t max_out, + Span in); + +// ssl_private_key_supports_signature_algorithm returns whether |hs|'s private +// key supports |sigalg|. +bool ssl_private_key_supports_signature_algorithm(SSL_HANDSHAKE *hs, + uint16_t sigalg); + +// ssl_public_key_verify verifies that the |signature| is valid for the public +// key |pkey| and input |in|, using the signature algorithm |sigalg|. +bool ssl_public_key_verify(SSL *ssl, Span signature, + uint16_t sigalg, EVP_PKEY *pkey, + Span in); + + +// Custom extensions + +} // namespace bssl + +// |SSL_CUSTOM_EXTENSION| is a structure that contains information about +// custom-extension callbacks. It is defined unnamespaced for compatibility with +// |STACK_OF(SSL_CUSTOM_EXTENSION)|. +typedef struct ssl_custom_extension { + SSL_custom_ext_add_cb add_callback; + void *add_arg; + SSL_custom_ext_free_cb free_callback; + SSL_custom_ext_parse_cb parse_callback; + void *parse_arg; + uint16_t value; +} SSL_CUSTOM_EXTENSION; + +DEFINE_STACK_OF(SSL_CUSTOM_EXTENSION) + +namespace bssl { + +void SSL_CUSTOM_EXTENSION_free(SSL_CUSTOM_EXTENSION *custom_extension); + +int custom_ext_add_clienthello(SSL_HANDSHAKE *hs, CBB *extensions); +int custom_ext_parse_serverhello(SSL_HANDSHAKE *hs, int *out_alert, + uint16_t value, const CBS *extension); +int custom_ext_parse_clienthello(SSL_HANDSHAKE *hs, int *out_alert, + uint16_t value, const CBS *extension); +int custom_ext_add_serverhello(SSL_HANDSHAKE *hs, CBB *extensions); + + +// Key shares. + +// SSLKeyShare abstracts over Diffie-Hellman-like key exchanges. +class SSLKeyShare { + public: + virtual ~SSLKeyShare() {} + static constexpr bool kAllowUniquePtr = true; + HAS_VIRTUAL_DESTRUCTOR + + // Create returns a SSLKeyShare instance for use with group |group_id| or + // nullptr on error. + static UniquePtr Create(uint16_t group_id); + + // GroupID returns the group ID. + virtual uint16_t GroupID() const PURE_VIRTUAL; + + // Offer generates a keypair and writes the public value to + // |out_public_key|. It returns true on success and false on error. + virtual bool Offer(CBB *out_public_key) PURE_VIRTUAL; + + // Accept performs a key exchange against the |peer_key| generated by |offer|. + // On success, it returns true, writes the public value to |out_public_key|, + // and sets |*out_secret| the shared secret. On failure, it returns false and + // sets |*out_alert| to an alert to send to the peer. + // + // The default implementation calls |Offer| and then |Finish|, assuming a key + // exchange protocol where the peers are symmetric. + virtual bool Accept(CBB *out_public_key, Array *out_secret, + uint8_t *out_alert, Span peer_key); + + // Finish performs a key exchange against the |peer_key| generated by + // |Accept|. On success, it returns true and sets |*out_secret| to the shared + // secret. On failure, it returns zero and sets |*out_alert| to an alert to + // send to the peer. + virtual bool Finish(Array *out_secret, uint8_t *out_alert, + Span peer_key) PURE_VIRTUAL; +}; + +// ssl_nid_to_group_id looks up the group corresponding to |nid|. On success, it +// sets |*out_group_id| to the group ID and returns one. Otherwise, it returns +// zero. +int ssl_nid_to_group_id(uint16_t *out_group_id, int nid); + +// ssl_name_to_group_id looks up the group corresponding to the |name| string +// of length |len|. On success, it sets |*out_group_id| to the group ID and +// returns one. Otherwise, it returns zero. +int ssl_name_to_group_id(uint16_t *out_group_id, const char *name, size_t len); + + +// Handshake messages. + +struct SSLMessage { + bool is_v2_hello; + uint8_t type; + CBS body; + // raw is the entire serialized handshake message, including the TLS or DTLS + // message header. + CBS raw; +}; + +// SSL_MAX_HANDSHAKE_FLIGHT is the number of messages, including +// ChangeCipherSpec, in the longest handshake flight. Currently this is the +// client's second leg in a full handshake when client certificates, NPN, and +// Channel ID, are all enabled. +#define SSL_MAX_HANDSHAKE_FLIGHT 7 + +extern const uint8_t kHelloRetryRequest[SSL3_RANDOM_SIZE]; +extern const uint8_t kDraftDowngradeRandom[8]; + +// ssl_max_handshake_message_len returns the maximum number of bytes permitted +// in a handshake message for |ssl|. +size_t ssl_max_handshake_message_len(const SSL *ssl); + +// tls_can_accept_handshake_data returns whether |ssl| is able to accept more +// data into handshake buffer. +bool tls_can_accept_handshake_data(const SSL *ssl, uint8_t *out_alert); + +// tls_has_unprocessed_handshake_data returns whether there is buffered +// handshake data that has not been consumed by |get_message|. +bool tls_has_unprocessed_handshake_data(const SSL *ssl); + +// dtls_has_unprocessed_handshake_data behaves like +// |tls_has_unprocessed_handshake_data| for DTLS. +bool dtls_has_unprocessed_handshake_data(const SSL *ssl); + +struct DTLS_OUTGOING_MESSAGE { + DTLS_OUTGOING_MESSAGE() {} + DTLS_OUTGOING_MESSAGE(const DTLS_OUTGOING_MESSAGE &) = delete; + DTLS_OUTGOING_MESSAGE &operator=(const DTLS_OUTGOING_MESSAGE &) = delete; + ~DTLS_OUTGOING_MESSAGE() { Clear(); } + + void Clear(); + + uint8_t *data = nullptr; + uint32_t len = 0; + uint16_t epoch = 0; + bool is_ccs = false; +}; + +// dtls_clear_outgoing_messages releases all buffered outgoing messages. +void dtls_clear_outgoing_messages(SSL *ssl); + + +// Callbacks. + +// ssl_do_info_callback calls |ssl|'s info callback, if set. +void ssl_do_info_callback(const SSL *ssl, int type, int value); + +// ssl_do_msg_callback calls |ssl|'s message callback, if set. +void ssl_do_msg_callback(SSL *ssl, int is_write, int content_type, + Span in); + + +// Transport buffers. + +class SSLBuffer { + public: + SSLBuffer() {} + ~SSLBuffer() { Clear(); } + + SSLBuffer(const SSLBuffer &) = delete; + SSLBuffer &operator=(const SSLBuffer &) = delete; + + uint8_t *data() { return buf_ + offset_; } + size_t size() const { return size_; } + bool empty() const { return size_ == 0; } + size_t cap() const { return cap_; } + + Span span() { return MakeSpan(data(), size()); } + + Span remaining() { + return MakeSpan(data() + size(), cap() - size()); + } + + // Clear releases the buffer. + void Clear(); + + // EnsureCap ensures the buffer has capacity at least |new_cap|, aligned such + // that data written after |header_len| is aligned to a + // |SSL3_ALIGN_PAYLOAD|-byte boundary. It returns true on success and false + // on error. + bool EnsureCap(size_t header_len, size_t new_cap); + + // DidWrite extends the buffer by |len|. The caller must have filled in to + // this point. + void DidWrite(size_t len); + + // Consume consumes |len| bytes from the front of the buffer. The memory + // consumed will remain valid until the next call to |DiscardConsumed| or + // |Clear|. + void Consume(size_t len); + + // DiscardConsumed discards the consumed bytes from the buffer. If the buffer + // is now empty, it releases memory used by it. + void DiscardConsumed(); + + private: + // buf_ is the memory allocated for this buffer. + uint8_t *buf_ = nullptr; + // offset_ is the offset into |buf_| which the buffer contents start at. + uint16_t offset_ = 0; + // size_ is the size of the buffer contents from |buf_| + |offset_|. + uint16_t size_ = 0; + // cap_ is how much memory beyond |buf_| + |offset_| is available. + uint16_t cap_ = 0; +}; + +// ssl_read_buffer_extend_to extends the read buffer to the desired length. For +// TLS, it reads to the end of the buffer until the buffer is |len| bytes +// long. For DTLS, it reads a new packet and ignores |len|. It returns one on +// success, zero on EOF, and a negative number on error. +// +// It is an error to call |ssl_read_buffer_extend_to| in DTLS when the buffer is +// non-empty. +int ssl_read_buffer_extend_to(SSL *ssl, size_t len); + +// ssl_handle_open_record handles the result of passing |ssl->s3->read_buffer| +// to a record-processing function. If |ret| is a success or if the caller +// should retry, it returns one and sets |*out_retry|. Otherwise, it returns <= +// 0. +int ssl_handle_open_record(SSL *ssl, bool *out_retry, ssl_open_record_t ret, + size_t consumed, uint8_t alert); + +// ssl_write_buffer_flush flushes the write buffer to the transport. It returns +// one on success and <= 0 on error. For DTLS, whether or not the write +// succeeds, the write buffer will be cleared. +int ssl_write_buffer_flush(SSL *ssl); + + +// Certificate functions. + +// ssl_has_certificate returns one if a certificate and private key are +// configured and zero otherwise. +int ssl_has_certificate(const SSL *ssl); + +// ssl_parse_cert_chain parses a certificate list from |cbs| in the format used +// by a TLS Certificate message. On success, it advances |cbs| and returns +// true. Otherwise, it returns false and sets |*out_alert| to an alert to send +// to the peer. +// +// If the list is non-empty then |*out_chain| and |*out_pubkey| will be set to +// the certificate chain and the leaf certificate's public key +// respectively. Otherwise, both will be set to nullptr. +// +// If the list is non-empty and |out_leaf_sha256| is non-NULL, it writes the +// SHA-256 hash of the leaf to |out_leaf_sha256|. +bool ssl_parse_cert_chain(uint8_t *out_alert, + UniquePtr *out_chain, + UniquePtr *out_pubkey, + uint8_t *out_leaf_sha256, CBS *cbs, + CRYPTO_BUFFER_POOL *pool); + +// ssl_add_cert_chain adds |ssl|'s certificate chain to |cbb| in the format used +// by a TLS Certificate message. If there is no certificate chain, it emits an +// empty certificate list. It returns one on success and zero on error. +int ssl_add_cert_chain(SSL *ssl, CBB *cbb); + +// ssl_cert_check_digital_signature_key_usage parses the DER-encoded, X.509 +// certificate in |in| and returns one if doesn't specify a key usage or, if it +// does, if it includes digitalSignature. Otherwise it pushes to the error +// queue and returns zero. +int ssl_cert_check_digital_signature_key_usage(const CBS *in); + +// ssl_cert_parse_pubkey extracts the public key from the DER-encoded, X.509 +// certificate in |in|. It returns an allocated |EVP_PKEY| or else returns +// nullptr and pushes to the error queue. +UniquePtr ssl_cert_parse_pubkey(const CBS *in); + +// ssl_parse_client_CA_list parses a CA list from |cbs| in the format used by a +// TLS CertificateRequest message. On success, it returns a newly-allocated +// |CRYPTO_BUFFER| list and advances |cbs|. Otherwise, it returns nullptr and +// sets |*out_alert| to an alert to send to the peer. +UniquePtr ssl_parse_client_CA_list(SSL *ssl, + uint8_t *out_alert, + CBS *cbs); + +// ssl_has_client_CAs returns there are configured CAs. +bool ssl_has_client_CAs(SSL *ssl); + +// ssl_add_client_CA_list adds the configured CA list to |cbb| in the format +// used by a TLS CertificateRequest message. It returns one on success and zero +// on error. +int ssl_add_client_CA_list(SSL *ssl, CBB *cbb); + +// ssl_check_leaf_certificate returns one if |pkey| and |leaf| are suitable as +// a server's leaf certificate for |hs|. Otherwise, it returns zero and pushes +// an error on the error queue. +int ssl_check_leaf_certificate(SSL_HANDSHAKE *hs, EVP_PKEY *pkey, + const CRYPTO_BUFFER *leaf); + +// ssl_on_certificate_selected is called once the certificate has been selected. +// It finalizes the certificate and initializes |hs->local_pubkey|. It returns +// one on success and zero on error. +int ssl_on_certificate_selected(SSL_HANDSHAKE *hs); + + +// TLS 1.3 key derivation. + +// tls13_init_key_schedule initializes the handshake hash and key derivation +// state, and incorporates the PSK. The cipher suite and PRF hash must have been +// selected at this point. It returns one on success and zero on error. +int tls13_init_key_schedule(SSL_HANDSHAKE *hs, const uint8_t *psk, + size_t psk_len); + +// tls13_init_early_key_schedule initializes the handshake hash and key +// derivation state from the resumption secret and incorporates the PSK to +// derive the early secrets. It returns one on success and zero on error. +int tls13_init_early_key_schedule(SSL_HANDSHAKE *hs, const uint8_t *psk, + size_t psk_len); + +// tls13_advance_key_schedule incorporates |in| into the key schedule with +// HKDF-Extract. It returns one on success and zero on error. +int tls13_advance_key_schedule(SSL_HANDSHAKE *hs, const uint8_t *in, + size_t len); + +// tls13_set_traffic_key sets the read or write traffic keys to +// |traffic_secret|. It returns one on success and zero on error. +int tls13_set_traffic_key(SSL *ssl, enum evp_aead_direction_t direction, + const uint8_t *traffic_secret, + size_t traffic_secret_len); + +// tls13_derive_early_secrets derives the early traffic secret. It returns one +// on success and zero on error. +int tls13_derive_early_secrets(SSL_HANDSHAKE *hs); + +// tls13_derive_handshake_secrets derives the handshake traffic secret. It +// returns one on success and zero on error. +int tls13_derive_handshake_secrets(SSL_HANDSHAKE *hs); + +// tls13_rotate_traffic_key derives the next read or write traffic secret. It +// returns one on success and zero on error. +int tls13_rotate_traffic_key(SSL *ssl, enum evp_aead_direction_t direction); + +// tls13_derive_application_secrets derives the initial application data traffic +// and exporter secrets based on the handshake transcripts and |master_secret|. +// It returns one on success and zero on error. +int tls13_derive_application_secrets(SSL_HANDSHAKE *hs); + +// tls13_derive_resumption_secret derives the |resumption_secret|. +int tls13_derive_resumption_secret(SSL_HANDSHAKE *hs); + +// tls13_export_keying_material provides an exporter interface to use the +// |exporter_secret|. +int tls13_export_keying_material(SSL *ssl, Span out, + Span secret, + Span label, + Span context); + +// tls13_finished_mac calculates the MAC of the handshake transcript to verify +// the integrity of the Finished message, and stores the result in |out| and +// length in |out_len|. |is_server| is 1 if this is for the Server Finished and +// 0 for the Client Finished. +int tls13_finished_mac(SSL_HANDSHAKE *hs, uint8_t *out, + size_t *out_len, int is_server); + +// tls13_derive_session_psk calculates the PSK for this session based on the +// resumption master secret and |nonce|. It returns true on success, and false +// on failure. +bool tls13_derive_session_psk(SSL_SESSION *session, Span nonce); + +// tls13_write_psk_binder calculates the PSK binder value and replaces the last +// bytes of |msg| with the resulting value. It returns 1 on success, and 0 on +// failure. +int tls13_write_psk_binder(SSL_HANDSHAKE *hs, uint8_t *msg, size_t len); + +// tls13_verify_psk_binder verifies that the handshake transcript, truncated +// up to the binders has a valid signature using the value of |session|'s +// resumption secret. It returns 1 on success, and 0 on failure. +int tls13_verify_psk_binder(SSL_HANDSHAKE *hs, SSL_SESSION *session, + const SSLMessage &msg, CBS *binders); + + +// Handshake functions. + +enum ssl_hs_wait_t { + ssl_hs_error, + ssl_hs_ok, + ssl_hs_read_server_hello, + ssl_hs_read_message, + ssl_hs_flush, + ssl_hs_certificate_selection_pending, + ssl_hs_handoff, + ssl_hs_x509_lookup, + ssl_hs_channel_id_lookup, + ssl_hs_private_key_operation, + ssl_hs_pending_session, + ssl_hs_pending_ticket, + ssl_hs_early_return, + ssl_hs_early_data_rejected, + ssl_hs_read_end_of_early_data, + ssl_hs_read_change_cipher_spec, + ssl_hs_certificate_verify, +}; + +enum ssl_grease_index_t { + ssl_grease_cipher = 0, + ssl_grease_group, + ssl_grease_extension1, + ssl_grease_extension2, + ssl_grease_version, + ssl_grease_ticket_extension, + ssl_grease_last_index = ssl_grease_ticket_extension, +}; + +struct SSL_HANDSHAKE { + explicit SSL_HANDSHAKE(SSL *ssl); + ~SSL_HANDSHAKE(); + static constexpr bool kAllowUniquePtr = true; + + // ssl is a non-owning pointer to the parent |SSL| object. + SSL *ssl; + + // wait contains the operation the handshake is currently blocking on or + // |ssl_hs_ok| if none. + enum ssl_hs_wait_t wait = ssl_hs_ok; + + // state is the internal state for the TLS 1.2 and below handshake. Its + // values depend on |do_handshake| but the starting state is always zero. + int state = 0; + + // tls13_state is the internal state for the TLS 1.3 handshake. Its values + // depend on |do_handshake| but the starting state is always zero. + int tls13_state = 0; + + // min_version is the minimum accepted protocol version, taking account both + // |SSL_OP_NO_*| and |SSL_CTX_set_min_proto_version| APIs. + uint16_t min_version = 0; + + // max_version is the maximum accepted protocol version, taking account both + // |SSL_OP_NO_*| and |SSL_CTX_set_max_proto_version| APIs. + uint16_t max_version = 0; + + size_t hash_len = 0; + uint8_t secret[EVP_MAX_MD_SIZE] = {0}; + uint8_t early_traffic_secret[EVP_MAX_MD_SIZE] = {0}; + uint8_t client_handshake_secret[EVP_MAX_MD_SIZE] = {0}; + uint8_t server_handshake_secret[EVP_MAX_MD_SIZE] = {0}; + uint8_t client_traffic_secret_0[EVP_MAX_MD_SIZE] = {0}; + uint8_t server_traffic_secret_0[EVP_MAX_MD_SIZE] = {0}; + uint8_t expected_client_finished[EVP_MAX_MD_SIZE] = {0}; + + union { + // sent is a bitset where the bits correspond to elements of kExtensions + // in t1_lib.c. Each bit is set if that extension was sent in a + // ClientHello. It's not used by servers. + uint32_t sent = 0; + // received is a bitset, like |sent|, but is used by servers to record + // which extensions were received from a client. + uint32_t received; + } extensions; + + union { + // sent is a bitset where the bits correspond to elements of + // |client_custom_extensions| in the |SSL_CTX|. Each bit is set if that + // extension was sent in a ClientHello. It's not used by servers. + uint16_t sent = 0; + // received is a bitset, like |sent|, but is used by servers to record + // which custom extensions were received from a client. The bits here + // correspond to |server_custom_extensions|. + uint16_t received; + } custom_extensions; + + // retry_group is the group ID selected by the server in HelloRetryRequest in + // TLS 1.3. + uint16_t retry_group = 0; + + // error, if |wait| is |ssl_hs_error|, is the error the handshake failed on. + UniquePtr error; + + // key_share is the current key exchange instance. + UniquePtr key_share; + + // transcript is the current handshake transcript. + SSLTranscript transcript; + + // cookie is the value of the cookie received from the server, if any. + Array cookie; + + // key_share_bytes is the value of the previously sent KeyShare extension by + // the client in TLS 1.3. + Array key_share_bytes; + + // ecdh_public_key, for servers, is the key share to be sent to the client in + // TLS 1.3. + Array ecdh_public_key; + + // peer_sigalgs are the signature algorithms that the peer supports. These are + // taken from the contents of the signature algorithms extension for a server + // or from the CertificateRequest for a client. + Array peer_sigalgs; + + // peer_supported_group_list contains the supported group IDs advertised by + // the peer. This is only set on the server's end. The server does not + // advertise this extension to the client. + Array peer_supported_group_list; + + // peer_key is the peer's ECDH key for a TLS 1.2 client. + Array peer_key; + + // negotiated_token_binding_version is used by a server to store the + // on-the-wire encoding of the Token Binding protocol version to advertise in + // the ServerHello/EncryptedExtensions if the Token Binding extension is to be + // sent. + uint16_t negotiated_token_binding_version; + + // server_params, in a TLS 1.2 server, stores the ServerKeyExchange + // parameters. It has client and server randoms prepended for signing + // convenience. + Array server_params; + + // peer_psk_identity_hint, on the client, is the psk_identity_hint sent by the + // server when using a TLS 1.2 PSK key exchange. + UniquePtr peer_psk_identity_hint; + + // ca_names, on the client, contains the list of CAs received in a + // CertificateRequest message. + UniquePtr ca_names; + + // cached_x509_ca_names contains a cache of parsed versions of the elements of + // |ca_names|. This pointer is left non-owning so only + // |ssl_crypto_x509_method| needs to link against crypto/x509. + STACK_OF(X509_NAME) *cached_x509_ca_names = nullptr; + + // certificate_types, on the client, contains the set of certificate types + // received in a CertificateRequest message. + Array certificate_types; + + // local_pubkey is the public key we are authenticating as. + UniquePtr local_pubkey; + + // peer_pubkey is the public key parsed from the peer's leaf certificate. + UniquePtr peer_pubkey; + + // new_session is the new mutable session being established by the current + // handshake. It should not be cached. + UniquePtr new_session; + + // early_session is the session corresponding to the current 0-RTT state on + // the client if |in_early_data| is true. + UniquePtr early_session; + + // new_cipher is the cipher being negotiated in this handshake. + const SSL_CIPHER *new_cipher = nullptr; + + // key_block is the record-layer key block for TLS 1.2 and earlier. + Array key_block; + + // scts_requested is true if the SCT extension is in the ClientHello. + bool scts_requested:1; + + // needs_psk_binder is true if the ClientHello has a placeholder PSK binder to + // be filled in. + bool needs_psk_binder:1; + + bool received_hello_retry_request:1; + bool sent_hello_retry_request:1; + + bool received_custom_extension:1; + + // handshake_finalized is true once the handshake has completed, at which + // point accessors should use the established state. + bool handshake_finalized:1; + + // accept_psk_mode stores whether the client's PSK mode is compatible with our + // preferences. + bool accept_psk_mode:1; + + // cert_request is true if a client certificate was requested. + bool cert_request:1; + + // certificate_status_expected is true if OCSP stapling was negotiated and the + // server is expected to send a CertificateStatus message. (This is used on + // both the client and server sides.) + bool certificate_status_expected:1; + + // ocsp_stapling_requested is true if a client requested OCSP stapling. + bool ocsp_stapling_requested:1; + + // should_ack_sni is used by a server and indicates that the SNI extension + // should be echoed in the ServerHello. + bool should_ack_sni:1; + + // in_false_start is true if there is a pending client handshake in False + // Start. The client may write data at this point. + bool in_false_start:1; + + // in_early_data is true if there is a pending handshake that has progressed + // enough to send and receive early data. + bool in_early_data:1; + + // early_data_offered is true if the client sent the early_data extension. + bool early_data_offered:1; + + // can_early_read is true if application data may be read at this point in the + // handshake. + bool can_early_read:1; + + // can_early_write is true if application data may be written at this point in + // the handshake. + bool can_early_write:1; + + // next_proto_neg_seen is one of NPN was negotiated. + bool next_proto_neg_seen:1; + + // ticket_expected is true if a TLS 1.2 NewSessionTicket message is to be sent + // or received. + bool ticket_expected:1; + + // extended_master_secret is true if the extended master secret extension is + // negotiated in this handshake. + bool extended_master_secret:1; + + // pending_private_key_op is true if there is a pending private key operation + // in progress. + bool pending_private_key_op:1; + + // grease_seeded is true if |grease_seed| has been initialized. + bool grease_seeded:1; + + // client_version is the value sent or received in the ClientHello version. + uint16_t client_version = 0; + + // early_data_read is the amount of early data that has been read by the + // record layer. + uint16_t early_data_read = 0; + + // early_data_written is the amount of early data that has been written by the + // record layer. + uint16_t early_data_written = 0; + + // session_id is the session ID in the ClientHello, used for the experimental + // TLS 1.3 variant. + uint8_t session_id[SSL_MAX_SSL_SESSION_ID_LENGTH] = {0}; + uint8_t session_id_len = 0; + + // grease_seed is the entropy for GREASE values. It is valid if + // |grease_seeded| is true. + uint8_t grease_seed[ssl_grease_last_index + 1] = {0}; + + // dummy_pq_padding_len, in a server, is the length of the extension that + // should be echoed in a ServerHello, or zero if no extension should be + // echoed. + uint16_t dummy_pq_padding_len = 0; +}; + +UniquePtr ssl_handshake_new(SSL *ssl); + +// ssl_check_message_type checks if |msg| has type |type|. If so it returns +// one. Otherwise, it sends an alert and returns zero. +bool ssl_check_message_type(SSL *ssl, const SSLMessage &msg, int type); + +// ssl_run_handshake runs the TLS handshake. It returns one on success and <= 0 +// on error. It sets |out_early_return| to one if we've completed the handshake +// early. +int ssl_run_handshake(SSL_HANDSHAKE *hs, bool *out_early_return); + +// The following are implementations of |do_handshake| for the client and +// server. +enum ssl_hs_wait_t ssl_client_handshake(SSL_HANDSHAKE *hs); +enum ssl_hs_wait_t ssl_server_handshake(SSL_HANDSHAKE *hs); +enum ssl_hs_wait_t tls13_client_handshake(SSL_HANDSHAKE *hs); +enum ssl_hs_wait_t tls13_server_handshake(SSL_HANDSHAKE *hs); + +// The following functions return human-readable representations of the TLS +// handshake states for debugging. +const char *ssl_client_handshake_state(SSL_HANDSHAKE *hs); +const char *ssl_server_handshake_state(SSL_HANDSHAKE *hs); +const char *tls13_client_handshake_state(SSL_HANDSHAKE *hs); +const char *tls13_server_handshake_state(SSL_HANDSHAKE *hs); + +// tls13_post_handshake processes a post-handshake message. It returns one on +// success and zero on failure. +int tls13_post_handshake(SSL *ssl, const SSLMessage &msg); + +int tls13_process_certificate(SSL_HANDSHAKE *hs, const SSLMessage &msg, + int allow_anonymous); +int tls13_process_certificate_verify(SSL_HANDSHAKE *hs, const SSLMessage &msg); + +// tls13_process_finished processes |msg| as a Finished message from the +// peer. If |use_saved_value| is one, the verify_data is compared against +// |hs->expected_client_finished| rather than computed fresh. +int tls13_process_finished(SSL_HANDSHAKE *hs, const SSLMessage &msg, + int use_saved_value); + +int tls13_add_certificate(SSL_HANDSHAKE *hs); + +// tls13_add_certificate_verify adds a TLS 1.3 CertificateVerify message to the +// handshake. If it returns |ssl_private_key_retry|, it should be called again +// to retry when the signing operation is completed. +enum ssl_private_key_result_t tls13_add_certificate_verify(SSL_HANDSHAKE *hs); + +int tls13_add_finished(SSL_HANDSHAKE *hs); +int tls13_process_new_session_ticket(SSL *ssl, const SSLMessage &msg); + +bool ssl_ext_key_share_parse_serverhello(SSL_HANDSHAKE *hs, + Array *out_secret, + uint8_t *out_alert, CBS *contents); +bool ssl_ext_key_share_parse_clienthello(SSL_HANDSHAKE *hs, bool *out_found, + Array *out_secret, + uint8_t *out_alert, CBS *contents); +bool ssl_ext_key_share_add_serverhello(SSL_HANDSHAKE *hs, CBB *out); + +bool ssl_ext_pre_shared_key_parse_serverhello(SSL_HANDSHAKE *hs, + uint8_t *out_alert, + CBS *contents); +bool ssl_ext_pre_shared_key_parse_clienthello( + SSL_HANDSHAKE *hs, CBS *out_ticket, CBS *out_binders, + uint32_t *out_obfuscated_ticket_age, uint8_t *out_alert, CBS *contents); +bool ssl_ext_pre_shared_key_add_serverhello(SSL_HANDSHAKE *hs, CBB *out); + +// ssl_is_sct_list_valid does a shallow parse of the SCT list in |contents| and +// returns one iff it's valid. +int ssl_is_sct_list_valid(const CBS *contents); + +int ssl_write_client_hello(SSL_HANDSHAKE *hs); + +enum ssl_cert_verify_context_t { + ssl_cert_verify_server, + ssl_cert_verify_client, + ssl_cert_verify_channel_id, +}; + +// tls13_get_cert_verify_signature_input generates the message to be signed for +// TLS 1.3's CertificateVerify message. |cert_verify_context| determines the +// type of signature. It sets |*out| to a newly allocated buffer containing the +// result. This function returns true on success and false on failure. +bool tls13_get_cert_verify_signature_input( + SSL_HANDSHAKE *hs, Array *out, + enum ssl_cert_verify_context_t cert_verify_context); + +// ssl_is_alpn_protocol_allowed returns whether |protocol| is a valid server +// selection for |ssl|'s client preferences. +bool ssl_is_alpn_protocol_allowed(const SSL *ssl, Span protocol); + +// ssl_negotiate_alpn negotiates the ALPN extension, if applicable. It returns +// true on successful negotiation or if nothing was negotiated. It returns false +// and sets |*out_alert| to an alert on error. +bool ssl_negotiate_alpn(SSL_HANDSHAKE *hs, uint8_t *out_alert, + const SSL_CLIENT_HELLO *client_hello); + +struct SSL_EXTENSION_TYPE { + uint16_t type; + bool *out_present; + CBS *out_data; +}; + +// ssl_parse_extensions parses a TLS extensions block out of |cbs| and advances +// it. It writes the parsed extensions to pointers denoted by |ext_types|. On +// success, it fills in the |out_present| and |out_data| fields and returns one. +// Otherwise, it sets |*out_alert| to an alert to send and returns zero. Unknown +// extensions are rejected unless |ignore_unknown| is 1. +int ssl_parse_extensions(const CBS *cbs, uint8_t *out_alert, + const SSL_EXTENSION_TYPE *ext_types, + size_t num_ext_types, int ignore_unknown); + +// ssl_verify_peer_cert verifies the peer certificate for |hs|. +enum ssl_verify_result_t ssl_verify_peer_cert(SSL_HANDSHAKE *hs); + +enum ssl_hs_wait_t ssl_get_finished(SSL_HANDSHAKE *hs); +bool ssl_send_finished(SSL_HANDSHAKE *hs); +bool ssl_output_cert_chain(SSL *ssl); + + +// SSLKEYLOGFILE functions. + +// ssl_log_secret logs |secret| with label |label|, if logging is enabled for +// |ssl|. It returns one on success and zero on failure. +int ssl_log_secret(const SSL *ssl, const char *label, const uint8_t *secret, + size_t secret_len); + + +// ClientHello functions. + +int ssl_client_hello_init(SSL *ssl, SSL_CLIENT_HELLO *out, + const SSLMessage &msg); + +int ssl_client_hello_get_extension(const SSL_CLIENT_HELLO *client_hello, + CBS *out, uint16_t extension_type); + +int ssl_client_cipher_list_contains_cipher(const SSL_CLIENT_HELLO *client_hello, + uint16_t id); + + +// GREASE. + +// ssl_get_grease_value returns a GREASE value for |hs|. For a given +// connection, the values for each index will be deterministic. This allows the +// same ClientHello be sent twice for a HelloRetryRequest or the same group be +// advertised in both supported_groups and key_shares. +uint16_t ssl_get_grease_value(SSL_HANDSHAKE *hs, enum ssl_grease_index_t index); + + +// Signature algorithms. + +// tls1_parse_peer_sigalgs parses |sigalgs| as the list of peer signature +// algorithms and saves them on |hs|. It returns true on success and false on +// error. +bool tls1_parse_peer_sigalgs(SSL_HANDSHAKE *hs, const CBS *sigalgs); + +// tls1_get_legacy_signature_algorithm sets |*out| to the signature algorithm +// that should be used with |pkey| in TLS 1.1 and earlier. It returns true on +// success and false if |pkey| may not be used at those versions. +bool tls1_get_legacy_signature_algorithm(uint16_t *out, const EVP_PKEY *pkey); + +// tls1_choose_signature_algorithm sets |*out| to a signature algorithm for use +// with |hs|'s private key based on the peer's preferences and the algorithms +// supported. It returns true on success and false on error. +bool tls1_choose_signature_algorithm(SSL_HANDSHAKE *hs, uint16_t *out); + +// tls12_add_verify_sigalgs adds the signature algorithms acceptable for the +// peer signature to |out|. It returns true on success and false on error. +bool tls12_add_verify_sigalgs(const SSL *ssl, CBB *out); + +// tls12_check_peer_sigalg checks if |sigalg| is acceptable for the peer +// signature. It returns true on success and false on error, setting +// |*out_alert| to an alert to send. +bool tls12_check_peer_sigalg(const SSL *ssl, uint8_t *out_alert, + uint16_t sigalg); + + +// Underdocumented functions. +// +// Functions below here haven't been touched up and may be underdocumented. + +#define TLSEXT_CHANNEL_ID_SIZE 128 + +// From RFC4492, used in encoding the curve type in ECParameters +#define NAMED_CURVE_TYPE 3 + +struct CERT { + EVP_PKEY *privatekey; + + // chain contains the certificate chain, with the leaf at the beginning. The + // first element of |chain| may be NULL to indicate that the leaf certificate + // has not yet been set. + // If |chain| != NULL -> len(chain) >= 1 + // If |chain[0]| == NULL -> len(chain) >= 2. + // |chain[1..]| != NULL + STACK_OF(CRYPTO_BUFFER) *chain; + + // x509_chain may contain a parsed copy of |chain[1..]|. This is only used as + // a cache in order to implement “get0” functions that return a non-owning + // pointer to the certificate chain. + STACK_OF(X509) *x509_chain; + + // x509_leaf may contain a parsed copy of the first element of |chain|. This + // is only used as a cache in order to implement “get0” functions that return + // a non-owning pointer to the certificate chain. + X509 *x509_leaf; + + // x509_stash contains the last |X509| object append to the chain. This is a + // workaround for some third-party code that continue to use an |X509| object + // even after passing ownership with an “add0” function. + X509 *x509_stash; + + // key_method, if non-NULL, is a set of callbacks to call for private key + // operations. + const SSL_PRIVATE_KEY_METHOD *key_method; + + // x509_method contains pointers to functions that might deal with |X509| + // compatibility, or might be a no-op, depending on the application. + const SSL_X509_METHOD *x509_method; + + // sigalgs, if non-NULL, is the set of signature algorithms supported by + // |privatekey| in decreasing order of preference. + uint16_t *sigalgs; + size_t num_sigalgs; + + // 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 certificate validation. If NULL the parent SSL_CTX + // store is used instead. + X509_STORE *verify_store; + + // Signed certificate timestamp list to be sent to the client, if requested + CRYPTO_BUFFER *signed_cert_timestamp_list; + + // OCSP response to be sent to the client, if requested. + CRYPTO_BUFFER *ocsp_response; + + // sid_ctx partitions the session space within a shared session cache or + // ticket key. Only sessions with a matching value will be accepted. + uint8_t sid_ctx_length; + uint8_t sid_ctx[SSL_MAX_SID_CTX_LENGTH]; + + // If enable_early_data is true, early data can be sent and accepted. + bool enable_early_data:1; +}; + +// |SSL_PROTOCOL_METHOD| abstracts between TLS and DTLS. +struct SSL_PROTOCOL_METHOD { + bool is_dtls; + bool (*ssl_new)(SSL *ssl); + void (*ssl_free)(SSL *ssl); + // get_message sets |*out| to the current handshake message and returns true + // if one has been received. It returns false if more input is needed. + bool (*get_message)(SSL *ssl, SSLMessage *out); + // next_message is called to release the current handshake message. + void (*next_message)(SSL *ssl); + // Use the |ssl_open_handshake| wrapper. + ssl_open_record_t (*open_handshake)(SSL *ssl, size_t *out_consumed, + uint8_t *out_alert, Span in); + // Use the |ssl_open_change_cipher_spec| wrapper. + ssl_open_record_t (*open_change_cipher_spec)(SSL *ssl, size_t *out_consumed, + uint8_t *out_alert, + Span in); + // Use the |ssl_open_app_data| wrapper. + ssl_open_record_t (*open_app_data)(SSL *ssl, Span *out, + size_t *out_consumed, uint8_t *out_alert, + Span in); + int (*write_app_data)(SSL *ssl, bool *out_needs_handshake, const uint8_t *buf, + int len); + int (*dispatch_alert)(SSL *ssl); + // init_message begins a new handshake message of type |type|. |cbb| is the + // root CBB to be passed into |finish_message|. |*body| is set to a child CBB + // the caller should write to. It returns true on success and false on error. + bool (*init_message)(SSL *ssl, CBB *cbb, CBB *body, uint8_t type); + // finish_message finishes a handshake message. It sets |*out_msg| to the + // serialized message. It returns true on success and false on error. + bool (*finish_message)(SSL *ssl, CBB *cbb, bssl::Array *out_msg); + // add_message adds a handshake message to the pending flight. It returns + // true on success and false on error. + bool (*add_message)(SSL *ssl, bssl::Array msg); + // add_change_cipher_spec adds a ChangeCipherSpec record to the pending + // flight. It returns true on success and false on error. + bool (*add_change_cipher_spec)(SSL *ssl); + // add_alert adds an alert to the pending flight. It returns true on success + // and false on error. + bool (*add_alert)(SSL *ssl, uint8_t level, uint8_t desc); + // flush_flight flushes the pending flight to the transport. It returns one on + // success and <= 0 on error. + int (*flush_flight)(SSL *ssl); + // on_handshake_complete is called when the handshake is complete. + void (*on_handshake_complete)(SSL *ssl); + // set_read_state sets |ssl|'s read cipher state to |aead_ctx|. It returns + // true on success and false if changing the read state is forbidden at this + // point. + bool (*set_read_state)(SSL *ssl, UniquePtr aead_ctx); + // set_write_state sets |ssl|'s write cipher state to |aead_ctx|. It returns + // true on success and false if changing the write state is forbidden at this + // point. + bool (*set_write_state)(SSL *ssl, UniquePtr aead_ctx); +}; + +// The following wrappers call |open_*| but handle |read_shutdown| correctly. + +// ssl_open_handshake processes a record from |in| for reading a handshake +// message. +ssl_open_record_t ssl_open_handshake(SSL *ssl, size_t *out_consumed, + uint8_t *out_alert, Span in); + +// ssl_open_change_cipher_spec processes a record from |in| for reading a +// ChangeCipherSpec. +ssl_open_record_t ssl_open_change_cipher_spec(SSL *ssl, size_t *out_consumed, + uint8_t *out_alert, + Span in); + +// ssl_open_app_data processes a record from |in| for reading application data. +// On success, it returns |ssl_open_record_success| and sets |*out| to the +// input. If it encounters a post-handshake message, it returns +// |ssl_open_record_discard|. The caller should then retry, after processing any +// messages received with |get_message|. +ssl_open_record_t ssl_open_app_data(SSL *ssl, Span *out, + size_t *out_consumed, uint8_t *out_alert, + Span in); + +// ssl_crypto_x509_method provides the |SSL_X509_METHOD| functions using +// crypto/x509. +extern const SSL_X509_METHOD ssl_crypto_x509_method; + +// ssl_noop_x509_method provides the |SSL_X509_METHOD| functions that avoid +// crypto/x509. +extern const SSL_X509_METHOD ssl_noop_x509_method; + +// ssl_cipher_preference_list_st contains a list of SSL_CIPHERs with +// equal-preference groups. For TLS clients, the groups are moot because the +// server picks the cipher and groups cannot be expressed on the wire. However, +// for servers, the equal-preference groups allow the client's preferences to +// be partially respected. (This only has an effect with +// SSL_OP_CIPHER_SERVER_PREFERENCE). +// +// The equal-preference groups are expressed by grouping SSL_CIPHERs together. +// All elements of a group have the same priority: no ordering is expressed +// within a group. +// +// The values in |ciphers| are in one-to-one correspondence with +// |in_group_flags|. (That is, sk_SSL_CIPHER_num(ciphers) is the number of +// bytes in |in_group_flags|.) The bytes in |in_group_flags| are either 1, to +// indicate that the corresponding SSL_CIPHER is not the last element of a +// group, or 0 to indicate that it is. +// +// For example, if |in_group_flags| contains all zeros then that indicates a +// traditional, fully-ordered preference. Every SSL_CIPHER is the last element +// of the group (i.e. they are all in a one-element group). +// +// For a more complex example, consider: +// ciphers: A B C D E F +// in_group_flags: 1 1 0 0 1 0 +// +// That would express the following, order: +// +// A E +// B -> D -> F +// C +struct ssl_cipher_preference_list_st { + STACK_OF(SSL_CIPHER) *ciphers; + uint8_t *in_group_flags; +}; + +struct tlsext_ticket_key { + static constexpr bool kAllowUniquePtr = true; + + uint8_t name[SSL_TICKET_KEY_NAME_LEN]; + uint8_t hmac_key[16]; + uint8_t aes_key[16]; + // next_rotation_tv_sec is the time (in seconds from the epoch) when the + // current key should be superseded by a new key, or the time when a previous + // key should be dropped. If zero, then the key should not be automatically + // rotated. + uint64_t next_rotation_tv_sec; +}; + +} // namespace bssl + +DECLARE_LHASH_OF(SSL_SESSION) + +namespace bssl { + +// SSLContext backs the public |SSL_CTX| type. Due to compatibility constraints, +// it is a base class for |ssl_ctx_st|. +struct SSLContext { + const SSL_PROTOCOL_METHOD *method; + const SSL_X509_METHOD *x509_method; + + // lock is used to protect various operations on this object. + CRYPTO_MUTEX lock; + + // conf_max_version is the maximum acceptable protocol version configured by + // |SSL_CTX_set_max_proto_version|. Note this version is normalized in DTLS + // and is further constrainted by |SSL_OP_NO_*|. + uint16_t conf_max_version; + + // conf_min_version is the minimum acceptable protocol version configured by + // |SSL_CTX_set_min_proto_version|. Note this version is normalized in DTLS + // and is further constrainted by |SSL_OP_NO_*|. + uint16_t conf_min_version; + + // tls13_variant is the variant of TLS 1.3 we are using for this + // configuration. + enum tls13_variant_t tls13_variant; + + struct ssl_cipher_preference_list_st *cipher_list; + + 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; + SSL_SESSION *session_cache_head; + SSL_SESSION *session_cache_tail; + + // handshakes_since_cache_flush is the number of successful handshakes since + // the last cache flush. + int handshakes_since_cache_flush; + + // 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; + + // session_timeout is the default lifetime for new sessions in TLS 1.2 and + // earlier, in seconds. + uint32_t session_timeout; + + // session_psk_dhe_timeout is the default lifetime for new sessions in TLS + // 1.3, in seconds. + uint32_t session_psk_dhe_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)(SSL *ssl, SSL_SESSION *sess); + void (*remove_session_cb)(SSL_CTX *ctx, SSL_SESSION *sess); + SSL_SESSION *(*get_session_cb)(SSL *ssl, const uint8_t *data, int len, + int *copy); + SSL_SESSION *(*get_session_cb_legacy)(SSL *ssl, uint8_t *data, int len, + int *copy); + + CRYPTO_refcount_t references; + + // if defined, these override the X509_verify_cert() calls + int (*app_verify_callback)(X509_STORE_CTX *store_ctx, void *arg); + void *app_verify_arg; + + enum ssl_verify_result_t (*custom_verify_callback)(SSL *ssl, + uint8_t *out_alert); + + // 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 **out_x509, EVP_PKEY **out_pkey); + + // get channel id callback + void (*channel_id_cb)(SSL *ssl, EVP_PKEY **out_pkey); + + CRYPTO_EX_DATA ex_data; + + // custom_*_extensions stores any callback sets for custom extensions. Note + // that these pointers will be NULL if the stack would otherwise be empty. + STACK_OF(SSL_CUSTOM_EXTENSION) *client_custom_extensions; + STACK_OF(SSL_CUSTOM_EXTENSION) *server_custom_extensions; + + // Default values used when no per-SSL value is defined follow + + void (*info_callback)(const SSL *ssl, int type, int value); + + // what we put in client cert requests + STACK_OF(CRYPTO_BUFFER) *client_CA; + + // cached_x509_client_CA is a cache of parsed versions of the elements of + // |client_CA|. + STACK_OF(X509_NAME) *cached_x509_client_CA; + + + // Default values to use in SSL structures follow (these are copied by + // SSL_new) + + uint32_t options; + uint32_t mode; + uint32_t max_cert_list; + + CERT *cert; + + // 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; + int (*default_verify_callback)( + int ok, X509_STORE_CTX *ctx); // called 'verify_callback' in the SSL + + X509_VERIFY_PARAM *param; + + // select_certificate_cb is called before most ClientHello processing and + // before the decision whether to resume a session is made. See + // |ssl_select_cert_result_t| for details of the return values. + enum ssl_select_cert_result_t (*select_certificate_cb)( + const SSL_CLIENT_HELLO *); + + // dos_protection_cb is called once the resumption decision for a ClientHello + // has been made. It returns one to continue the handshake or zero to + // abort. + int (*dos_protection_cb) (const SSL_CLIENT_HELLO *); + + // Maximum amount of data to send in one fragment. actual record size can be + // more than this due to padding and MAC overheads. + uint16_t max_send_fragment; + + // TLS extensions servername callback + int (*tlsext_servername_callback)(SSL *, int *, void *); + void *tlsext_servername_arg; + + // RFC 4507 session ticket keys. |tlsext_ticket_key_current| may be NULL + // before the first handshake and |tlsext_ticket_key_prev| may be NULL at any + // time. Automatically generated ticket keys are rotated as needed at + // handshake time. Hence, all access must be synchronized through |lock|. + struct tlsext_ticket_key *tlsext_ticket_key_current; + struct tlsext_ticket_key *tlsext_ticket_key_prev; + + // Callback to support customisation of ticket key setting + int (*tlsext_ticket_key_cb)(SSL *ssl, uint8_t *name, uint8_t *iv, + EVP_CIPHER_CTX *ectx, HMAC_CTX *hctx, int enc); + + // Server-only: psk_identity_hint is the default identity hint to send in + // PSK-based key exchanges. + char *psk_identity_hint; + + unsigned int (*psk_client_callback)(SSL *ssl, const char *hint, + char *identity, + unsigned int max_identity_len, + uint8_t *psk, unsigned int max_psk_len); + unsigned int (*psk_server_callback)(SSL *ssl, const char *identity, + uint8_t *psk, unsigned int max_psk_len); + + + // 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 *ssl, const uint8_t **out, + unsigned *out_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 *ssl, uint8_t **out, uint8_t *out_len, + const uint8_t *in, unsigned in_len, void *arg); + void *next_proto_select_cb_arg; + + // 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 *ssl, const uint8_t **out, uint8_t *out_len, + const uint8_t *in, unsigned in_len, void *arg); + void *alpn_select_cb_arg; + + // For a client, this contains the list of supported protocols in wire + // format. + uint8_t *alpn_client_proto_list; + unsigned alpn_client_proto_list_len; + + // SRTP profiles we are willing to do from RFC 5764 + STACK_OF(SRTP_PROTECTION_PROFILE) *srtp_profiles; + + // Supported group values inherited by SSL structure + size_t supported_group_list_len; + uint16_t *supported_group_list; + + // The client's Channel ID private key. + EVP_PKEY *tlsext_channel_id_private; + + // keylog_callback, if not NULL, is the key logging callback. See + // |SSL_CTX_set_keylog_callback|. + void (*keylog_callback)(const SSL *ssl, const char *line); + + // current_time_cb, if not NULL, is the function to use to get the current + // time. It sets |*out_clock| to the current time. The |ssl| argument is + // always NULL. See |SSL_CTX_set_current_time_cb|. + void (*current_time_cb)(const SSL *ssl, struct timeval *out_clock); + + // pool is used for all |CRYPTO_BUFFER|s in case we wish to share certificate + // memory. + CRYPTO_BUFFER_POOL *pool; + + // ticket_aead_method contains function pointers for opening and sealing + // session tickets. + const SSL_TICKET_AEAD_METHOD *ticket_aead_method; + + // verify_sigalgs, if not empty, is the set of signature algorithms + // accepted from the peer in decreasing order of preference. + uint16_t *verify_sigalgs; + size_t num_verify_sigalgs; + + // retain_only_sha256_of_client_certs is true if we should compute the SHA256 + // hash of the peer's certificate and then discard it to save memory and + // session space. Only effective on the server side. + bool retain_only_sha256_of_client_certs:1; + + // quiet_shutdown is true if the connection should not send a close_notify on + // shutdown. + bool quiet_shutdown:1; + + // ocsp_stapling_enabled is only used by client connections and indicates + // whether OCSP stapling will be requested. + bool ocsp_stapling_enabled:1; + + // If true, a client will request certificate timestamps. + bool signed_cert_timestamps_enabled:1; + + // tlsext_channel_id_enabled is whether Channel ID is enabled. For a server, + // means that we'll accept Channel IDs from clients. For a client, means that + // we'll advertise support. + bool tlsext_channel_id_enabled:1; + + // grease_enabled is whether draft-davidben-tls-grease-01 is enabled. + bool grease_enabled:1; + + // allow_unknown_alpn_protos is whether the client allows unsolicited ALPN + // protocols from the peer. + bool allow_unknown_alpn_protos:1; + + // ed25519_enabled is whether Ed25519 is advertised in the handshake. + bool ed25519_enabled:1; + + // false_start_allowed_without_alpn is whether False Start (if + // |SSL_MODE_ENABLE_FALSE_START| is enabled) is allowed without ALPN. + bool false_start_allowed_without_alpn:1; + + // handoff indicates that a server should stop after receiving the + // ClientHello and pause the handshake in such a way that |SSL_get_error| + // returns |SSL_HANDOFF|. + bool handoff:1; +}; + +// An ssl_shutdown_t describes the shutdown state of one end of the connection, +// whether it is alive or has been shutdown via close_notify or fatal alert. +enum ssl_shutdown_t { + ssl_shutdown_none = 0, + ssl_shutdown_close_notify = 1, + ssl_shutdown_error = 2, +}; + +struct SSL3_STATE { + static constexpr bool kAllowUniquePtr = true; + + SSL3_STATE(); + ~SSL3_STATE(); + + uint8_t read_sequence[8] = {0}; + uint8_t write_sequence[8] = {0}; + + uint8_t server_random[SSL3_RANDOM_SIZE] = {0}; + uint8_t client_random[SSL3_RANDOM_SIZE] = {0}; + + // read_buffer holds data from the transport to be processed. + SSLBuffer read_buffer; + // write_buffer holds data to be written to the transport. + SSLBuffer write_buffer; + + // pending_app_data is the unconsumed application data. It points into + // |read_buffer|. + Span pending_app_data; + + // partial write - check the numbers match + unsigned int wnum = 0; // number of bytes sent so far + int wpend_tot = 0; // number bytes written + int wpend_type = 0; + int wpend_ret = 0; // number of bytes submitted + const uint8_t *wpend_buf = nullptr; + + // read_shutdown is the shutdown state for the read half of the connection. + enum ssl_shutdown_t read_shutdown = ssl_shutdown_none; + + // write_shutdown is the shutdown state for the write half of the connection. + enum ssl_shutdown_t write_shutdown = ssl_shutdown_none; + + // read_error, if |read_shutdown| is |ssl_shutdown_error|, is the error for + // the receive half of the connection. + UniquePtr read_error; + + int alert_dispatch = 0; + + int total_renegotiations = 0; + + // 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 = SSL_NOTHING; + + // early_data_skipped is the amount of early data that has been skipped by the + // record layer. + uint16_t early_data_skipped = 0; + + // empty_record_count is the number of consecutive empty records received. + uint8_t empty_record_count = 0; + + // warning_alert_count is the number of consecutive warning alerts + // received. + uint8_t warning_alert_count = 0; + + // key_update_count is the number of consecutive KeyUpdates received. + uint8_t key_update_count = 0; + + // skip_early_data instructs the record layer to skip unexpected early data + // messages when 0RTT is rejected. + bool skip_early_data:1; + + // have_version is true if the connection's final version is known. Otherwise + // the version has not been negotiated yet. + bool have_version:1; + + // v2_hello_done is true if the peer's V2ClientHello, if any, has been handled + // and future messages should use the record layer. + bool v2_hello_done:1; + + // is_v2_hello is true if the current handshake message was derived from a + // V2ClientHello rather than received from the peer directly. + bool is_v2_hello:1; + + // has_message is true if the current handshake message has been returned + // at least once by |get_message| and false otherwise. + bool has_message:1; + + // initial_handshake_complete is true if the initial handshake has + // completed. + bool initial_handshake_complete:1; + + // session_reused indicates whether a session was resumed. + bool session_reused:1; + + bool send_connection_binding:1; + + // In a client, this means that the server supported Channel ID and that a + // Channel ID was sent. In a server it means that we echoed support for + // Channel IDs and that tlsext_channel_id will be valid after the + // handshake. + bool tlsext_channel_id_valid:1; + + // key_update_pending is true if we have a KeyUpdate acknowledgment + // outstanding. + bool key_update_pending:1; + + // wpend_pending is true if we have a pending write outstanding. + bool wpend_pending:1; + + // early_data_accepted is true if early data was accepted by the server. + bool early_data_accepted:1; + + // draft_downgrade is whether the TLS 1.3 anti-downgrade logic would have + // fired, were it not a draft. + bool draft_downgrade:1; + + // hs_buf is the buffer of handshake data to process. + UniquePtr hs_buf; + + // pending_flight is the pending outgoing flight. This is used to flush each + // handshake flight in a single write. |write_buffer| must be written out + // before this data. + UniquePtr pending_flight; + + // pending_flight_offset is the number of bytes of |pending_flight| which have + // been successfully written. + uint32_t pending_flight_offset = 0; + + // ticket_age_skew is the difference, in seconds, between the client-sent + // ticket age and the server-computed value in TLS 1.3 server connections + // which resumed a session. + int32_t ticket_age_skew = 0; + + // aead_read_ctx is the current read cipher state. + UniquePtr aead_read_ctx; + + // aead_write_ctx is the current write cipher state. + UniquePtr aead_write_ctx; + + // hs is the handshake state for the current handshake or NULL if there isn't + // one. + UniquePtr hs; + + uint8_t write_traffic_secret[EVP_MAX_MD_SIZE] = {0}; + uint8_t read_traffic_secret[EVP_MAX_MD_SIZE] = {0}; + uint8_t exporter_secret[EVP_MAX_MD_SIZE] = {0}; + uint8_t early_exporter_secret[EVP_MAX_MD_SIZE] = {0}; + uint8_t write_traffic_secret_len = 0; + uint8_t read_traffic_secret_len = 0; + uint8_t exporter_secret_len = 0; + uint8_t early_exporter_secret_len = 0; + + // Connection binding to prevent renegotiation attacks + uint8_t previous_client_finished[12] = {0}; + uint8_t previous_client_finished_len = 0; + uint8_t previous_server_finished_len = 0; + uint8_t previous_server_finished[12] = {0}; + + uint8_t send_alert[2] = {0}; + + // established_session is the session established by the connection. This + // session is only filled upon the completion of the handshake and is + // immutable. + UniquePtr established_session; + + // 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. + Array next_proto_negotiated; + + // 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. + Array alpn_selected; + + // hostname, on the server, is the value of the SNI extension. + UniquePtr hostname; + + // For a server: + // If |tlsext_channel_id_valid| is true, then this contains the + // verified Channel ID from the client: a P256 point, (x,y), where + // each are big-endian values. + uint8_t tlsext_channel_id[64] = {0}; + + // Contains the QUIC transport params received by the peer. + Array peer_quic_transport_params; +}; + +// lengths of messages +#define DTLS1_COOKIE_LENGTH 256 + +#define DTLS1_RT_HEADER_LENGTH 13 + +#define DTLS1_HM_HEADER_LENGTH 12 + +#define DTLS1_CCS_HEADER_LENGTH 1 + +#define DTLS1_AL_HEADER_LENGTH 2 + +struct hm_header_st { + uint8_t type; + uint32_t msg_len; + uint16_t seq; + uint32_t frag_off; + uint32_t frag_len; +}; + +// An hm_fragment is an incoming DTLS message, possibly not yet assembled. +struct hm_fragment { + static constexpr bool kAllowUniquePtr = true; + + hm_fragment() {} + hm_fragment(const hm_fragment &) = delete; + hm_fragment &operator=(const hm_fragment &) = delete; + + ~hm_fragment(); + + // type is the type of the message. + uint8_t type = 0; + // seq is the sequence number of this message. + uint16_t seq = 0; + // msg_len is the length of the message body. + uint32_t msg_len = 0; + // data is a pointer to the message, including message header. It has length + // |DTLS1_HM_HEADER_LENGTH| + |msg_len|. + uint8_t *data = nullptr; + // reassembly is a bitmask of |msg_len| bits corresponding to which parts of + // the message have been received. It is NULL if the message is complete. + uint8_t *reassembly = nullptr; +}; + +struct OPENSSL_timeval { + uint64_t tv_sec; + uint32_t tv_usec; +}; + +struct DTLS1_STATE { + static constexpr bool kAllowUniquePtr = true; + + DTLS1_STATE(); + ~DTLS1_STATE(); + + // has_change_cipher_spec is true if we have received a ChangeCipherSpec from + // the peer in this epoch. + bool has_change_cipher_spec:1; + + // outgoing_messages_complete is true if |outgoing_messages| has been + // completed by an attempt to flush it. Future calls to |add_message| and + // |add_change_cipher_spec| will start a new flight. + bool outgoing_messages_complete:1; + + // flight_has_reply is true if the current outgoing flight is complete and has + // processed at least one message. This is used to detect whether we or the + // peer sent the final flight. + bool flight_has_reply:1; + + uint8_t cookie[DTLS1_COOKIE_LENGTH] = {0}; + size_t cookie_len = 0; + + // The current data and handshake epoch. This is initially undefined, and + // starts at zero once the initial handshake is completed. + uint16_t r_epoch = 0; + uint16_t w_epoch = 0; + + // records being received in the current epoch + DTLS1_BITMAP bitmap; + + uint16_t handshake_write_seq = 0; + uint16_t handshake_read_seq = 0; + + // save last sequence number for retransmissions + uint8_t last_write_sequence[8] = {0}; + UniquePtr last_aead_write_ctx; + + // incoming_messages is a ring buffer of incoming handshake messages that have + // yet to be processed. The front of the ring buffer is message number + // |handshake_read_seq|, at position |handshake_read_seq| % + // |SSL_MAX_HANDSHAKE_FLIGHT|. + UniquePtr incoming_messages[SSL_MAX_HANDSHAKE_FLIGHT]; + + // outgoing_messages is the queue of outgoing messages from the last handshake + // flight. + DTLS_OUTGOING_MESSAGE outgoing_messages[SSL_MAX_HANDSHAKE_FLIGHT]; + uint8_t outgoing_messages_len = 0; + + // outgoing_written is the number of outgoing messages that have been + // written. + uint8_t outgoing_written = 0; + // outgoing_offset is the number of bytes of the next outgoing message have + // been written. + uint32_t outgoing_offset = 0; + + unsigned mtu = 0; // max DTLS packet size + + // num_timeouts is the number of times the retransmit timer has fired since + // the last time it was reset. + unsigned num_timeouts = 0; + + // Indicates when the last handshake msg or heartbeat sent will + // timeout. + struct OPENSSL_timeval next_timeout = {0, 0}; + + // timeout_duration_ms is the timeout duration in milliseconds. + unsigned timeout_duration_ms = 0; +}; + +// SSLConnection backs the public |SSL| type. Due to compatibility constraints, +// it is a base class for |ssl_st|. +struct SSLConnection { + // method is the method table corresponding to the current protocol (DTLS or + // TLS). + const SSL_PROTOCOL_METHOD *method; + + // version is the protocol version. + uint16_t version; + + // conf_max_version is the maximum acceptable protocol version configured by + // |SSL_set_max_proto_version|. Note this version is normalized in DTLS and is + // further constrainted by |SSL_OP_NO_*|. + uint16_t conf_max_version; + + // conf_min_version is the minimum acceptable protocol version configured by + // |SSL_set_min_proto_version|. Note this version is normalized in DTLS and is + // further constrainted by |SSL_OP_NO_*|. + uint16_t conf_min_version; + + uint16_t max_send_fragment; + + // 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 + + BIO *rbio; // used by SSL_read + BIO *wbio; // used by SSL_write + + // do_handshake runs the handshake. On completion, it returns |ssl_hs_ok|. + // Otherwise, it returns a value corresponding to what operation is needed to + // progress. + enum ssl_hs_wait_t (*do_handshake)(SSL_HANDSHAKE *hs); + + SSL3_STATE *s3; // SSLv3 variables + DTLS1_STATE *d1; // DTLSv1 variables + + // 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; + + X509_VERIFY_PARAM *param; + + // crypto + struct ssl_cipher_preference_list_st *cipher_list; + + // session info + + // This is used to hold the local certificate used (i.e. the server + // certificate for a server or the client certificate for a client). + CERT *cert; + + // initial_timeout_duration_ms is the default DTLS timeout duration in + // milliseconds. It's used to initialize the timer any time it's restarted. + unsigned initial_timeout_duration_ms; + + // tls13_variant is the variant of TLS 1.3 we are using for this + // configuration. + enum tls13_variant_t tls13_variant; + + // session is the configured session to be offered by the client. This session + // is immutable. + SSL_SESSION *session; + + int (*verify_callback)(int ok, + X509_STORE_CTX *ctx); // fail if callback returns 0 + + enum ssl_verify_result_t (*custom_verify_callback)(SSL *ssl, + uint8_t *out_alert); + + void (*info_callback)(const SSL *ssl, int type, int value); + + // Server-only: psk_identity_hint is the identity hint to send in + // PSK-based key exchanges. + char *psk_identity_hint; + + unsigned int (*psk_client_callback)(SSL *ssl, const char *hint, + char *identity, + unsigned int max_identity_len, + uint8_t *psk, unsigned int max_psk_len); + unsigned int (*psk_server_callback)(SSL *ssl, const char *identity, + uint8_t *psk, unsigned int max_psk_len); + + SSL_CTX *ctx; + + // extra application data + CRYPTO_EX_DATA ex_data; + + // for server side, keep the list of CA_dn we can use + STACK_OF(CRYPTO_BUFFER) *client_CA; + + // cached_x509_client_CA is a cache of parsed versions of the elements of + // |client_CA|. + STACK_OF(X509_NAME) *cached_x509_client_CA; + + uint32_t options; // protocol behaviour + uint32_t mode; // API behaviour + uint32_t max_cert_list; + uint16_t dummy_pq_padding_len; + char *tlsext_hostname; + size_t supported_group_list_len; + uint16_t *supported_group_list; // our list + + // session_ctx is the |SSL_CTX| used for the session cache and related + // settings. + SSL_CTX *session_ctx; + + // srtp_profiles is the list of configured SRTP protection profiles for + // DTLS-SRTP. + STACK_OF(SRTP_PROTECTION_PROFILE) *srtp_profiles; + + // srtp_profile is the selected SRTP protection profile for + // DTLS-SRTP. + const SRTP_PROTECTION_PROFILE *srtp_profile; + + // The client's Channel ID private key. + EVP_PKEY *tlsext_channel_id_private; + + // For a client, this contains the list of supported protocols in wire + // format. + uint8_t *alpn_client_proto_list; + unsigned alpn_client_proto_list_len; + + // Contains a list of supported Token Binding key parameters. + uint8_t *token_binding_params; + size_t token_binding_params_len; + + // The negotiated Token Binding key parameter. Only valid if + // |token_binding_negotiated| is set. + uint8_t negotiated_token_binding_param; + + // Contains the QUIC transport params that this endpoint will send. + uint8_t *quic_transport_params; + size_t quic_transport_params_len; + + // renegotiate_mode controls how peer renegotiation attempts are handled. + enum ssl_renegotiate_mode_t renegotiate_mode; + + // verify_mode is a bitmask of |SSL_VERIFY_*| values. + uint8_t verify_mode; + + // server is true iff the this SSL* is the server half. Note: before the SSL* + // is initialized by either SSL_set_accept_state or SSL_set_connect_state, + // the side is not determined. In this state, server is always false. + bool server:1; + + // quiet_shutdown is true if the connection should not send a close_notify on + // shutdown. + bool quiet_shutdown:1; + + // Enable signed certificate time stamps. Currently client only. + bool signed_cert_timestamps_enabled:1; + + // ocsp_stapling_enabled is only used by client connections and indicates + // whether OCSP stapling will be requested. + bool ocsp_stapling_enabled:1; + + // tlsext_channel_id_enabled is copied from the |SSL_CTX|. For a server, + // means that we'll accept Channel IDs from clients. For a client, means that + // we'll advertise support. + bool tlsext_channel_id_enabled:1; + + // token_binding_negotiated is set if Token Binding was negotiated. + bool token_binding_negotiated:1; + + // retain_only_sha256_of_client_certs is true if we should compute the SHA256 + // hash of the peer's certificate and then discard it to save memory and + // session space. Only effective on the server side. + bool retain_only_sha256_of_client_certs:1; + + // handoff indicates that a server should stop after receiving the + // ClientHello and pause the handshake in such a way that |SSL_get_error| + // returns |SSL_HANDOFF|. This is copied in |SSL_new| from the |SSL_CTX| + // element of the same name and may be cleared if the handoff is declined. + bool handoff:1; + + // did_dummy_pq_padding is only valid for a client. In that context, it is + // true iff the client observed the server echoing a dummy PQ padding + // extension. + bool did_dummy_pq_padding:1; +}; + +// From draft-ietf-tls-tls13-18, used in determining PSK modes. +#define SSL_PSK_DHE_KE 0x1 + +// From draft-ietf-tls-tls13-16, used in determining whether to respond with a +// KeyUpdate. +#define SSL_KEY_UPDATE_NOT_REQUESTED 0 +#define SSL_KEY_UPDATE_REQUESTED 1 + +// kMaxEarlyDataAccepted is the advertised number of plaintext bytes of early +// data that will be accepted. This value should be slightly below +// kMaxEarlyDataSkipped in tls_record.c, which is measured in ciphertext. +static const size_t kMaxEarlyDataAccepted = 14336; + +CERT *ssl_cert_new(const SSL_X509_METHOD *x509_method); +CERT *ssl_cert_dup(CERT *cert); +void ssl_cert_clear_certs(CERT *cert); +void ssl_cert_free(CERT *cert); +int ssl_set_cert(CERT *cert, UniquePtr buffer); +int ssl_is_key_type_supported(int key_type); +// ssl_compare_public_and_private_key returns one if |pubkey| is the public +// counterpart to |privkey|. Otherwise it returns zero and pushes a helpful +// message on the error queue. +int ssl_compare_public_and_private_key(const EVP_PKEY *pubkey, + const EVP_PKEY *privkey); +int ssl_cert_check_private_key(const CERT *cert, const EVP_PKEY *privkey); +int ssl_get_new_session(SSL_HANDSHAKE *hs, int is_server); +int ssl_encrypt_ticket(SSL *ssl, CBB *out, const SSL_SESSION *session); +int ssl_ctx_rotate_ticket_encryption_key(SSL_CTX *ctx); + +// ssl_session_new returns a newly-allocated blank |SSL_SESSION| or nullptr on +// error. +UniquePtr ssl_session_new(const SSL_X509_METHOD *x509_method); + +// SSL_SESSION_parse parses an |SSL_SESSION| from |cbs| and advances |cbs| over +// the parsed data. +UniquePtr SSL_SESSION_parse(CBS *cbs, + const SSL_X509_METHOD *x509_method, + CRYPTO_BUFFER_POOL *pool); + +// ssl_session_serialize writes |in| to |cbb| as if it were serialising a +// session for Session-ID resumption. It returns one on success and zero on +// error. +int ssl_session_serialize(const SSL_SESSION *in, CBB *cbb); + +// ssl_session_is_context_valid returns one if |session|'s session ID context +// matches the one set on |ssl| and zero otherwise. +int ssl_session_is_context_valid(const SSL *ssl, const SSL_SESSION *session); + +// ssl_session_is_time_valid returns one if |session| is still valid and zero if +// it has expired. +int ssl_session_is_time_valid(const SSL *ssl, const SSL_SESSION *session); + +// ssl_session_is_resumable returns one if |session| is resumable for |hs| and +// zero otherwise. +int ssl_session_is_resumable(const SSL_HANDSHAKE *hs, + const SSL_SESSION *session); + +// ssl_session_protocol_version returns the protocol version associated with +// |session|. Note that despite the name, this is not the same as +// |SSL_SESSION_get_protocol_version|. The latter is based on upstream's name. +uint16_t ssl_session_protocol_version(const SSL_SESSION *session); + +// ssl_session_get_digest returns the digest used in |session|. +const EVP_MD *ssl_session_get_digest(const SSL_SESSION *session); + +void ssl_set_session(SSL *ssl, SSL_SESSION *session); + +// ssl_get_prev_session looks up the previous session based on |client_hello|. +// On success, it sets |*out_session| to the session or nullptr if none was +// found. If the session could not be looked up synchronously, it returns +// |ssl_hs_pending_session| and should be called again. If a ticket could not be +// decrypted immediately it returns |ssl_hs_pending_ticket| and should also +// be called again. Otherwise, it returns |ssl_hs_error|. +enum ssl_hs_wait_t ssl_get_prev_session(SSL *ssl, + UniquePtr *out_session, + bool *out_tickets_supported, + bool *out_renew_ticket, + const SSL_CLIENT_HELLO *client_hello); + +// The following flags determine which parts of the session are duplicated. +#define SSL_SESSION_DUP_AUTH_ONLY 0x0 +#define SSL_SESSION_INCLUDE_TICKET 0x1 +#define SSL_SESSION_INCLUDE_NONAUTH 0x2 +#define SSL_SESSION_DUP_ALL \ + (SSL_SESSION_INCLUDE_TICKET | SSL_SESSION_INCLUDE_NONAUTH) + +// SSL_SESSION_dup returns a newly-allocated |SSL_SESSION| with a copy of the +// fields in |session| or nullptr on error. The new session is non-resumable and +// must be explicitly marked resumable once it has been filled in. +OPENSSL_EXPORT UniquePtr SSL_SESSION_dup(SSL_SESSION *session, + int dup_flags); + +// ssl_session_rebase_time updates |session|'s start time to the current time, +// adjusting the timeout so the expiration time is unchanged. +void ssl_session_rebase_time(SSL *ssl, SSL_SESSION *session); + +// ssl_session_renew_timeout calls |ssl_session_rebase_time| and renews +// |session|'s timeout to |timeout| (measured from the current time). The +// renewal is clamped to the session's auth_timeout. +void ssl_session_renew_timeout(SSL *ssl, SSL_SESSION *session, + uint32_t timeout); + +void ssl_cipher_preference_list_free( + struct ssl_cipher_preference_list_st *cipher_list); + +// ssl_get_cipher_preferences returns the cipher preference list for TLS 1.2 and +// below. +const struct ssl_cipher_preference_list_st *ssl_get_cipher_preferences( + const SSL *ssl); + +void ssl_update_cache(SSL_HANDSHAKE *hs, int mode); + +int ssl_send_alert(SSL *ssl, int level, int desc); +bool ssl3_get_message(SSL *ssl, SSLMessage *out); +ssl_open_record_t ssl3_open_handshake(SSL *ssl, size_t *out_consumed, + uint8_t *out_alert, Span in); +void ssl3_next_message(SSL *ssl); + +int ssl3_dispatch_alert(SSL *ssl); +ssl_open_record_t ssl3_open_app_data(SSL *ssl, Span *out, + size_t *out_consumed, uint8_t *out_alert, + Span in); +ssl_open_record_t ssl3_open_change_cipher_spec(SSL *ssl, size_t *out_consumed, + uint8_t *out_alert, + Span in); +int ssl3_write_app_data(SSL *ssl, bool *out_needs_handshake, const uint8_t *buf, + int len); + +bool ssl3_new(SSL *ssl); +void ssl3_free(SSL *ssl); + +bool ssl3_init_message(SSL *ssl, CBB *cbb, CBB *body, uint8_t type); +bool ssl3_finish_message(SSL *ssl, CBB *cbb, Array *out_msg); +bool ssl3_add_message(SSL *ssl, Array msg); +bool ssl3_add_change_cipher_spec(SSL *ssl); +bool ssl3_add_alert(SSL *ssl, uint8_t level, uint8_t desc); +int ssl3_flush_flight(SSL *ssl); + +bool dtls1_init_message(SSL *ssl, CBB *cbb, CBB *body, uint8_t type); +bool dtls1_finish_message(SSL *ssl, CBB *cbb, Array *out_msg); +bool dtls1_add_message(SSL *ssl, Array msg); +bool dtls1_add_change_cipher_spec(SSL *ssl); +bool dtls1_add_alert(SSL *ssl, uint8_t level, uint8_t desc); +int dtls1_flush_flight(SSL *ssl); + +// ssl_add_message_cbb finishes the handshake message in |cbb| and adds it to +// the pending flight. It returns true on success and false on error. +bool ssl_add_message_cbb(SSL *ssl, CBB *cbb); + +// ssl_hash_message incorporates |msg| into the handshake hash. It returns true +// on success and false on allocation failure. +bool ssl_hash_message(SSL_HANDSHAKE *hs, const SSLMessage &msg); + +ssl_open_record_t dtls1_open_app_data(SSL *ssl, Span *out, + size_t *out_consumed, uint8_t *out_alert, + Span in); +ssl_open_record_t dtls1_open_change_cipher_spec(SSL *ssl, size_t *out_consumed, + uint8_t *out_alert, + Span in); + +int dtls1_write_app_data(SSL *ssl, bool *out_needs_handshake, + const uint8_t *buf, int len); + +// dtls1_write_record sends a record. It returns one on success and <= 0 on +// error. +int dtls1_write_record(SSL *ssl, int type, const uint8_t *buf, size_t len, + enum dtls1_use_epoch_t use_epoch); + +int dtls1_retransmit_outgoing_messages(SSL *ssl); +bool dtls1_parse_fragment(CBS *cbs, struct hm_header_st *out_hdr, + CBS *out_body); +bool dtls1_check_timeout_num(SSL *ssl); + +void dtls1_start_timer(SSL *ssl); +void dtls1_stop_timer(SSL *ssl); +bool dtls1_is_timer_expired(SSL *ssl); +unsigned int dtls1_min_mtu(void); + +bool dtls1_new(SSL *ssl); +void dtls1_free(SSL *ssl); + +bool dtls1_get_message(SSL *ssl, SSLMessage *out); +ssl_open_record_t dtls1_open_handshake(SSL *ssl, size_t *out_consumed, + uint8_t *out_alert, Span in); +void dtls1_next_message(SSL *ssl); +int dtls1_dispatch_alert(SSL *ssl); + +// tls1_configure_aead configures either the read or write direction AEAD (as +// determined by |direction|) using the keys generated by the TLS KDF. The +// |key_block_cache| argument is used to store the generated key block, if +// empty. Otherwise it's assumed that the key block is already contained within +// it. Returns one on success or zero on error. +int tls1_configure_aead(SSL *ssl, evp_aead_direction_t direction, + Array *key_block_cache, + const SSL_CIPHER *cipher, + Span iv_override); + +int tls1_change_cipher_state(SSL_HANDSHAKE *hs, evp_aead_direction_t direction); +int tls1_generate_master_secret(SSL_HANDSHAKE *hs, uint8_t *out, + Span premaster); + +// tls1_get_grouplist returns the locally-configured group preference list. +Span tls1_get_grouplist(const SSL *ssl); + +// tls1_check_group_id returns one if |group_id| is consistent with +// locally-configured group preferences. +int tls1_check_group_id(const SSL *ssl, uint16_t group_id); + +// tls1_get_shared_group sets |*out_group_id| to the first preferred shared +// group between client and server preferences and returns one. If none may be +// found, it returns zero. +int tls1_get_shared_group(SSL_HANDSHAKE *hs, uint16_t *out_group_id); + +// tls1_set_curves converts the array of |ncurves| NIDs pointed to by |curves| +// into a newly allocated array of TLS group IDs. On success, the function +// returns one and writes the array to |*out_group_ids| and its size to +// |*out_group_ids_len|. Otherwise, it returns zero. +int tls1_set_curves(uint16_t **out_group_ids, size_t *out_group_ids_len, + const int *curves, size_t ncurves); + +// tls1_set_curves_list converts the string of curves pointed to by |curves| +// into a newly allocated array of TLS group IDs. On success, the function +// returns one and writes the array to |*out_group_ids| and its size to +// |*out_group_ids_len|. Otherwise, it returns zero. +int tls1_set_curves_list(uint16_t **out_group_ids, size_t *out_group_ids_len, + const char *curves); + +// ssl_add_clienthello_tlsext writes ClientHello extensions to |out|. It +// returns one on success and zero on failure. The |header_len| argument is the +// length of the ClientHello written so far and is used to compute the padding +// length. (It does not include the record header.) +int ssl_add_clienthello_tlsext(SSL_HANDSHAKE *hs, CBB *out, size_t header_len); + +int ssl_add_serverhello_tlsext(SSL_HANDSHAKE *hs, CBB *out); +int ssl_parse_clienthello_tlsext(SSL_HANDSHAKE *hs, + const SSL_CLIENT_HELLO *client_hello); +int ssl_parse_serverhello_tlsext(SSL_HANDSHAKE *hs, CBS *cbs); + +#define tlsext_tick_md EVP_sha256 + +// ssl_process_ticket processes a session ticket from the client. It returns +// one of: +// |ssl_ticket_aead_success|: |*out_session| is set to the parsed session and +// |*out_renew_ticket| is set to whether the ticket should be renewed. +// |ssl_ticket_aead_ignore_ticket|: |*out_renew_ticket| is set to whether a +// fresh ticket should be sent, but the given ticket cannot be used. +// |ssl_ticket_aead_retry|: the ticket could not be immediately decrypted. +// Retry later. +// |ssl_ticket_aead_error|: an error occured that is fatal to the connection. +enum ssl_ticket_aead_result_t ssl_process_ticket( + SSL *ssl, UniquePtr *out_session, bool *out_renew_ticket, + const uint8_t *ticket, size_t ticket_len, const uint8_t *session_id, + size_t session_id_len); + +// tls1_verify_channel_id processes |msg| as a Channel ID message, and verifies +// the signature. If the key is valid, it saves the Channel ID and returns +// one. Otherwise, it returns zero. +int tls1_verify_channel_id(SSL_HANDSHAKE *hs, const SSLMessage &msg); + +// tls1_write_channel_id generates a Channel ID message and puts the output in +// |cbb|. |ssl->tlsext_channel_id_private| must already be set before calling. +// This function returns true on success and false on error. +bool tls1_write_channel_id(SSL_HANDSHAKE *hs, CBB *cbb); + +// tls1_channel_id_hash computes the hash to be signed by Channel ID and writes +// it to |out|, which must contain at least |EVP_MAX_MD_SIZE| bytes. It returns +// one on success and zero on failure. +int tls1_channel_id_hash(SSL_HANDSHAKE *hs, uint8_t *out, size_t *out_len); + +int tls1_record_handshake_hashes_for_channel_id(SSL_HANDSHAKE *hs); + +// ssl_do_channel_id_callback checks runs |ssl->ctx->channel_id_cb| if +// necessary. It returns one on success and zero on fatal error. Note that, on +// success, |ssl->tlsext_channel_id_private| may be unset, in which case the +// operation should be retried later. +int ssl_do_channel_id_callback(SSL *ssl); + +// ssl_can_write returns one if |ssl| is allowed to write and zero otherwise. +int ssl_can_write(const SSL *ssl); + +// ssl_can_read returns one if |ssl| is allowed to read and zero otherwise. +int ssl_can_read(const SSL *ssl); + +void ssl_get_current_time(const SSL *ssl, struct OPENSSL_timeval *out_clock); +void ssl_ctx_get_current_time(const SSL_CTX *ctx, + struct OPENSSL_timeval *out_clock); + +// ssl_reset_error_state resets state for |SSL_get_error|. +void ssl_reset_error_state(SSL *ssl); + +// ssl_set_read_error sets |ssl|'s read half into an error state, saving the +// current state of the error queue. +void ssl_set_read_error(SSL* ssl); + +} // namespace bssl + + +// Opaque C types. +// +// The following types are exported to C code as public typedefs, so they must +// be defined outside of the namespace. + +// ssl_method_st backs the public |SSL_METHOD| type. It is a compatibility +// structure to support the legacy version-locked methods. +struct ssl_method_st { + // version, if non-zero, is the only protocol version acceptable to an + // SSL_CTX initialized from this method. + uint16_t version; + // method is the underlying SSL_PROTOCOL_METHOD that initializes the + // SSL_CTX. + const bssl::SSL_PROTOCOL_METHOD *method; + // x509_method contains pointers to functions that might deal with |X509| + // compatibility, or might be a no-op, depending on the application. + const SSL_X509_METHOD *x509_method; +}; + +struct ssl_x509_method_st { + // check_client_CA_list returns one if |names| is a good list of X.509 + // distinguished names and zero otherwise. This is used to ensure that we can + // reject unparsable values at handshake time when using crypto/x509. + int (*check_client_CA_list)(STACK_OF(CRYPTO_BUFFER) *names); + + // cert_clear frees and NULLs all X509 certificate-related state. + void (*cert_clear)(bssl::CERT *cert); + // cert_free frees all X509-related state. + void (*cert_free)(bssl::CERT *cert); + // cert_flush_cached_chain drops any cached |X509|-based certificate chain + // from |cert|. + // cert_dup duplicates any needed fields from |cert| to |new_cert|. + void (*cert_dup)(bssl::CERT *new_cert, const bssl::CERT *cert); + void (*cert_flush_cached_chain)(bssl::CERT *cert); + // cert_flush_cached_chain drops any cached |X509|-based leaf certificate + // from |cert|. + void (*cert_flush_cached_leaf)(bssl::CERT *cert); + + // session_cache_objects fills out |sess->x509_peer| and |sess->x509_chain| + // from |sess->certs| and erases |sess->x509_chain_without_leaf|. It returns + // one on success or zero on error. + int (*session_cache_objects)(SSL_SESSION *session); + // session_dup duplicates any needed fields from |session| to |new_session|. + // It returns one on success or zero on error. + int (*session_dup)(SSL_SESSION *new_session, const SSL_SESSION *session); + // session_clear frees any X509-related state from |session|. + void (*session_clear)(SSL_SESSION *session); + // session_verify_cert_chain verifies the certificate chain in |session|, + // sets |session->verify_result| and returns one on success or zero on + // error. + int (*session_verify_cert_chain)(SSL_SESSION *session, SSL *ssl, + uint8_t *out_alert); + + // hs_flush_cached_ca_names drops any cached |X509_NAME|s from |hs|. + void (*hs_flush_cached_ca_names)(bssl::SSL_HANDSHAKE *hs); + // ssl_new does any neccessary initialisation of |ssl|. It returns one on + // success or zero on error. + int (*ssl_new)(SSL *ssl); + // ssl_free frees anything created by |ssl_new|. + void (*ssl_free)(SSL *ssl); + // ssl_flush_cached_client_CA drops any cached |X509_NAME|s from |ssl|. + void (*ssl_flush_cached_client_CA)(SSL *ssl); + // ssl_auto_chain_if_needed runs the deprecated auto-chaining logic if + // necessary. On success, it updates |ssl|'s certificate configuration as + // needed and returns one. Otherwise, it returns zero. + int (*ssl_auto_chain_if_needed)(SSL *ssl); + // ssl_ctx_new does any neccessary initialisation of |ctx|. It returns one on + // success or zero on error. + int (*ssl_ctx_new)(SSL_CTX *ctx); + // ssl_ctx_free frees anything created by |ssl_ctx_new|. + void (*ssl_ctx_free)(SSL_CTX *ctx); + // ssl_ctx_flush_cached_client_CA drops any cached |X509_NAME|s from |ctx|. + void (*ssl_ctx_flush_cached_client_CA)(SSL_CTX *ssl); +}; + +// The following types back public C-exposed types which must live in the global +// namespace. We use subclassing so the implementations may be C++ types with +// methods and destructor without polluting the global namespace. +struct ssl_ctx_st : public bssl::SSLContext {}; +struct ssl_st : public bssl::SSLConnection {}; + + +#endif // OPENSSL_HEADER_SSL_INTERNAL_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/ssl/internal.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/ssl/internal.h.grpc_back new file mode 100644 index 0000000..d13d5f2 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/ssl/internal.h.grpc_back @@ -0,0 +1,3064 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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. + */ +/* ==================================================================== + * 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 OPENSSL_HEADER_SSL_INTERNAL_H +#define OPENSSL_HEADER_SSL_INTERNAL_H + +#include + +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "../crypto/err/internal.h" +#include "../crypto/internal.h" + + +#if defined(OPENSSL_WINDOWS) +// Windows defines struct timeval in winsock2.h. +OPENSSL_MSVC_PRAGMA(warning(push, 3)) +#include +OPENSSL_MSVC_PRAGMA(warning(pop)) +#else +#include +#endif + + +namespace bssl { + +struct SSL_HANDSHAKE; +struct SSL_PROTOCOL_METHOD; + +// C++ utilities. + +// New behaves like |new| but uses |OPENSSL_malloc| for memory allocation. It +// returns nullptr on allocation error. It only implements single-object +// allocation and not new T[n]. +// +// Note: unlike |new|, this does not support non-public constructors. +template +T *New(Args &&... args) { + void *t = OPENSSL_malloc(sizeof(T)); + if (t == nullptr) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return nullptr; + } + return new (t) T(std::forward(args)...); +} + +// Delete behaves like |delete| but uses |OPENSSL_free| to release memory. +// +// Note: unlike |delete| this does not support non-public destructors. +template +void Delete(T *t) { + if (t != nullptr) { + t->~T(); + OPENSSL_free(t); + } +} + +// All types with kAllowUniquePtr set may be used with UniquePtr. Other types +// may be C structs which require a |BORINGSSL_MAKE_DELETER| registration. +namespace internal { +template +struct DeleterImpl::type> { + static void Free(T *t) { Delete(t); } +}; +} + +// MakeUnique behaves like |std::make_unique| but returns nullptr on allocation +// error. +template +UniquePtr MakeUnique(Args &&... args) { + return UniquePtr(New(std::forward(args)...)); +} + +#if defined(BORINGSSL_ALLOW_CXX_RUNTIME) +#define HAS_VIRTUAL_DESTRUCTOR +#define PURE_VIRTUAL = 0 +#else +// HAS_VIRTUAL_DESTRUCTOR should be declared in any base class which defines a +// virtual destructor. This avoids a dependency on |_ZdlPv| and prevents the +// class from being used with |delete|. +#define HAS_VIRTUAL_DESTRUCTOR \ + void operator delete(void *) { abort(); } + +// PURE_VIRTUAL should be used instead of = 0 when defining pure-virtual +// functions. This avoids a dependency on |__cxa_pure_virtual| but loses +// compile-time checking. +#define PURE_VIRTUAL { abort(); } +#endif + +// CONSTEXPR_ARRAY works around a VS 2015 bug where ranged for loops don't work +// on constexpr arrays. +#if defined(_MSC_VER) && !defined(__clang__) && _MSC_VER < 1910 +#define CONSTEXPR_ARRAY const +#else +#define CONSTEXPR_ARRAY constexpr +#endif + +// Array is an owning array of elements of |T|. +template +class Array { + public: + // Array's default constructor creates an empty array. + Array() {} + Array(const Array &) = delete; + Array(Array &&other) { *this = std::move(other); } + + ~Array() { Reset(); } + + Array &operator=(const Array &) = delete; + Array &operator=(Array &&other) { + Reset(); + other.Release(&data_, &size_); + return *this; + } + + const T *data() const { return data_; } + T *data() { return data_; } + size_t size() const { return size_; } + bool empty() const { return size_ == 0; } + + const T &operator[](size_t i) const { return data_[i]; } + T &operator[](size_t i) { return data_[i]; } + + T *begin() { return data_; } + const T *cbegin() const { return data_; } + T *end() { return data_ + size_; } + const T *cend() const { return data_ + size_; } + + void Reset() { Reset(nullptr, 0); } + + // Reset releases the current contents of the array and takes ownership of the + // raw pointer supplied by the caller. + void Reset(T *new_data, size_t new_size) { + for (size_t i = 0; i < size_; i++) { + data_[i].~T(); + } + OPENSSL_free(data_); + data_ = new_data; + size_ = new_size; + } + + // Release releases ownership of the array to a raw pointer supplied by the + // caller. + void Release(T **out, size_t *out_size) { + *out = data_; + *out_size = size_; + data_ = nullptr; + size_ = 0; + } + + // Init replaces the array with a newly-allocated array of |new_size| + // default-constructed copies of |T|. It returns true on success and false on + // error. + // + // Note that if |T| is a primitive type like |uint8_t|, it is uninitialized. + bool Init(size_t new_size) { + Reset(); + if (new_size == 0) { + return true; + } + + if (new_size > std::numeric_limits::max() / sizeof(T)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW); + return false; + } + data_ = reinterpret_cast(OPENSSL_malloc(new_size * sizeof(T))); + if (data_ == nullptr) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return false; + } + size_ = new_size; + for (size_t i = 0; i < size_; i++) { + new (&data_[i]) T; + } + return true; + } + + // CopyFrom replaces the array with a newly-allocated copy of |in|. It returns + // true on success and false on error. + bool CopyFrom(Span in) { + if (!Init(in.size())) { + return false; + } + OPENSSL_memcpy(data_, in.data(), in.size()); + return true; + } + + private: + T *data_ = nullptr; + size_t size_ = 0; +}; + +// CBBFinishArray behaves like |CBB_finish| but stores the result in an Array. +OPENSSL_EXPORT bool CBBFinishArray(CBB *cbb, Array *out); + + +// Protocol versions. +// +// Due to DTLS's historical wire version differences and to support multiple +// variants of the same protocol during development, we maintain two notions of +// version. +// +// The "version" or "wire version" is the actual 16-bit value that appears on +// the wire. It uniquely identifies a version and is also used at API +// boundaries. The set of supported versions differs between TLS and DTLS. Wire +// versions are opaque values and may not be compared numerically. +// +// The "protocol version" identifies the high-level handshake variant being +// used. DTLS versions map to the corresponding TLS versions. Draft TLS 1.3 +// variants all map to TLS 1.3. Protocol versions are sequential and may be +// compared numerically. + +// ssl_protocol_version_from_wire sets |*out| to the protocol version +// corresponding to wire version |version| and returns true. If |version| is not +// a valid TLS or DTLS version, it returns false. +// +// Note this simultaneously handles both DTLS and TLS. Use one of the +// higher-level functions below for most operations. +bool ssl_protocol_version_from_wire(uint16_t *out, uint16_t version); + +// ssl_get_version_range sets |*out_min_version| and |*out_max_version| to the +// minimum and maximum enabled protocol versions, respectively. +bool ssl_get_version_range(const SSL *ssl, uint16_t *out_min_version, + uint16_t *out_max_version); + +// ssl_supports_version returns whether |hs| supports |version|. +bool ssl_supports_version(SSL_HANDSHAKE *hs, uint16_t version); + +// ssl_add_supported_versions writes the supported versions of |hs| to |cbb|, in +// decreasing preference order. +bool ssl_add_supported_versions(SSL_HANDSHAKE *hs, CBB *cbb); + +// ssl_negotiate_version negotiates a common version based on |hs|'s preferences +// and the peer preference list in |peer_versions|. On success, it returns true +// and sets |*out_version| to the selected version. Otherwise, it returns false +// and sets |*out_alert| to an alert to send. +bool ssl_negotiate_version(SSL_HANDSHAKE *hs, uint8_t *out_alert, + uint16_t *out_version, const CBS *peer_versions); + +// ssl_protocol_version returns |ssl|'s protocol version. It is an error to +// call this function before the version is determined. +uint16_t ssl_protocol_version(const SSL *ssl); + +// Cipher suites. + +} // namespace bssl + +struct ssl_cipher_st { + // name is the OpenSSL name for the cipher. + const char *name; + // standard_name is the IETF name for the cipher. + const char *standard_name; + // id is the cipher suite value bitwise OR-d with 0x03000000. + uint32_t id; + + // algorithm_* determine the cipher suite. See constants below for the values. + uint32_t algorithm_mkey; + uint32_t algorithm_auth; + uint32_t algorithm_enc; + uint32_t algorithm_mac; + uint32_t algorithm_prf; +}; + +namespace bssl { + +// Bits for |algorithm_mkey| (key exchange algorithm). +#define SSL_kRSA 0x00000001u +#define SSL_kECDHE 0x00000002u +// SSL_kPSK is only set for plain PSK, not ECDHE_PSK. +#define SSL_kPSK 0x00000004u +#define SSL_kGENERIC 0x00000008u + +// Bits for |algorithm_auth| (server authentication). +#define SSL_aRSA 0x00000001u +#define SSL_aECDSA 0x00000002u +// SSL_aPSK is set for both PSK and ECDHE_PSK. +#define SSL_aPSK 0x00000004u +#define SSL_aGENERIC 0x00000008u + +#define SSL_aCERT (SSL_aRSA | SSL_aECDSA) + +// Bits for |algorithm_enc| (symmetric encryption). +#define SSL_3DES 0x00000001u +#define SSL_AES128 0x00000002u +#define SSL_AES256 0x00000004u +#define SSL_AES128GCM 0x00000008u +#define SSL_AES256GCM 0x00000010u +#define SSL_eNULL 0x00000020u +#define SSL_CHACHA20POLY1305 0x00000040u + +#define SSL_AES (SSL_AES128 | SSL_AES256 | SSL_AES128GCM | SSL_AES256GCM) + +// Bits for |algorithm_mac| (symmetric authentication). +#define SSL_SHA1 0x00000001u +#define SSL_SHA256 0x00000002u +#define SSL_SHA384 0x00000004u +// SSL_AEAD is set for all AEADs. +#define SSL_AEAD 0x00000008u + +// Bits for |algorithm_prf| (handshake digest). +#define SSL_HANDSHAKE_MAC_DEFAULT 0x1 +#define SSL_HANDSHAKE_MAC_SHA256 0x2 +#define SSL_HANDSHAKE_MAC_SHA384 0x4 + +// SSL_MAX_DIGEST is the number of digest types which exist. When adding a new +// one, update the table in ssl_cipher.c. +#define SSL_MAX_DIGEST 4 + +// ssl_cipher_get_evp_aead sets |*out_aead| to point to the correct EVP_AEAD +// object for |cipher| protocol version |version|. It sets |*out_mac_secret_len| +// and |*out_fixed_iv_len| to the MAC key length and fixed IV length, +// respectively. The MAC key length is zero except for legacy block and stream +// ciphers. It returns true on success and false on error. +bool ssl_cipher_get_evp_aead(const EVP_AEAD **out_aead, + size_t *out_mac_secret_len, + size_t *out_fixed_iv_len, const SSL_CIPHER *cipher, + uint16_t version, int is_dtls); + +// ssl_get_handshake_digest returns the |EVP_MD| corresponding to |version| and +// |cipher|. +const EVP_MD *ssl_get_handshake_digest(uint16_t version, + const SSL_CIPHER *cipher); + +// ssl_create_cipher_list evaluates |rule_str|. It sets |*out_cipher_list| to a +// newly-allocated |ssl_cipher_preference_list_st| containing the result. It +// returns true on success and false on failure. If |strict| is true, nonsense +// will be rejected. If false, nonsense will be silently ignored. An empty +// result is considered an error regardless of |strict|. +bool ssl_create_cipher_list( + struct ssl_cipher_preference_list_st **out_cipher_list, + const char *rule_str, bool strict); + +// ssl_cipher_get_value returns the cipher suite id of |cipher|. +uint16_t ssl_cipher_get_value(const SSL_CIPHER *cipher); + +// ssl_cipher_auth_mask_for_key returns the mask of cipher |algorithm_auth| +// values suitable for use with |key| in TLS 1.2 and below. +uint32_t ssl_cipher_auth_mask_for_key(const EVP_PKEY *key); + +// ssl_cipher_uses_certificate_auth returns whether |cipher| authenticates the +// server and, optionally, the client with a certificate. +bool ssl_cipher_uses_certificate_auth(const SSL_CIPHER *cipher); + +// ssl_cipher_requires_server_key_exchange returns whether |cipher| requires a +// ServerKeyExchange message. +// +// This function may return false while still allowing |cipher| an optional +// ServerKeyExchange. This is the case for plain PSK ciphers. +bool ssl_cipher_requires_server_key_exchange(const SSL_CIPHER *cipher); + +// ssl_cipher_get_record_split_len, for TLS 1.0 CBC mode ciphers, returns the +// length of an encrypted 1-byte record, for use in record-splitting. Otherwise +// it returns zero. +size_t ssl_cipher_get_record_split_len(const SSL_CIPHER *cipher); + + +// Transcript layer. + +// SSLTranscript maintains the handshake transcript as a combination of a +// buffer and running hash. +class SSLTranscript { + public: + SSLTranscript(); + ~SSLTranscript(); + + // Init initializes the handshake transcript. If called on an existing + // transcript, it resets the transcript and hash. It returns true on success + // and false on failure. + bool Init(); + + // InitHash initializes the handshake hash based on the PRF and contents of + // the handshake transcript. Subsequent calls to |Update| will update the + // rolling hash. It returns one on success and zero on failure. It is an error + // to call this function after the handshake buffer is released. + bool InitHash(uint16_t version, const SSL_CIPHER *cipher); + + // UpdateForHelloRetryRequest resets the rolling hash with the + // HelloRetryRequest construction. It returns true on success and false on + // failure. It is an error to call this function before the handshake buffer + // is released. + bool UpdateForHelloRetryRequest(); + + // CopyHashContext copies the hash context into |ctx| and returns true on + // success. + bool CopyHashContext(EVP_MD_CTX *ctx); + + Span buffer() { + return MakeConstSpan(reinterpret_cast(buffer_->data), + buffer_->length); + } + + // FreeBuffer releases the handshake buffer. Subsequent calls to + // |Update| will not update the handshake buffer. + void FreeBuffer(); + + // DigestLen returns the length of the PRF hash. + size_t DigestLen() const; + + // Digest returns the PRF hash. For TLS 1.1 and below, this is + // |EVP_md5_sha1|. + const EVP_MD *Digest() const; + + // Update adds |in| to the handshake buffer and handshake hash, whichever is + // enabled. It returns true on success and false on failure. + bool Update(Span in); + + // GetHash writes the handshake hash to |out| which must have room for at + // least |DigestLen| bytes. On success, it returns true and sets |*out_len| to + // the number of bytes written. Otherwise, it returns false. + bool GetHash(uint8_t *out, size_t *out_len); + + // GetSSL3CertVerifyHash writes the SSL 3.0 CertificateVerify hash into the + // bytes pointed to by |out| and writes the number of bytes to + // |*out_len|. |out| must have room for |EVP_MAX_MD_SIZE| bytes. It returns + // one on success and zero on failure. + bool GetSSL3CertVerifyHash(uint8_t *out, size_t *out_len, + const SSL_SESSION *session, + uint16_t signature_algorithm); + + // GetFinishedMAC computes the MAC for the Finished message into the bytes + // pointed by |out| and writes the number of bytes to |*out_len|. |out| must + // have room for |EVP_MAX_MD_SIZE| bytes. It returns true on success and false + // on failure. + bool GetFinishedMAC(uint8_t *out, size_t *out_len, const SSL_SESSION *session, + bool from_server); + + private: + // buffer_, if non-null, contains the handshake transcript. + UniquePtr buffer_; + // hash, if initialized with an |EVP_MD|, maintains the handshake hash. For + // TLS 1.1 and below, it is the SHA-1 half. + ScopedEVP_MD_CTX hash_; + // md5, if initialized with an |EVP_MD|, maintains the MD5 half of the + // handshake hash for TLS 1.1 and below. + ScopedEVP_MD_CTX md5_; +}; + +// tls1_prf computes the PRF function for |ssl|. It fills |out|, using |secret| +// as the secret and |label| as the label. |seed1| and |seed2| are concatenated +// to form the seed parameter. It returns true on success and false on failure. +bool tls1_prf(const EVP_MD *digest, Span out, + Span secret, Span label, + Span seed1, Span seed2); + + +// Encryption layer. + +// SSLAEADContext contains information about an AEAD that is being used to +// encrypt an SSL connection. +class SSLAEADContext { + public: + SSLAEADContext(uint16_t version, bool is_dtls, const SSL_CIPHER *cipher); + ~SSLAEADContext(); + static constexpr bool kAllowUniquePtr = true; + + SSLAEADContext(const SSLAEADContext &&) = delete; + SSLAEADContext &operator=(const SSLAEADContext &&) = delete; + + // CreateNullCipher creates an |SSLAEADContext| for the null cipher. + static UniquePtr CreateNullCipher(bool is_dtls); + + // Create creates an |SSLAEADContext| using the supplied key material. It + // returns nullptr on error. Only one of |Open| or |Seal| may be used with the + // resulting object, depending on |direction|. |version| is the normalized + // protocol version, so DTLS 1.0 is represented as 0x0301, not 0xffef. + static UniquePtr Create(enum evp_aead_direction_t direction, + uint16_t version, int is_dtls, + const SSL_CIPHER *cipher, + Span enc_key, + Span mac_key, + Span fixed_iv); + + // SetVersionIfNullCipher sets the version the SSLAEADContext for the null + // cipher, to make version-specific determinations in the record layer prior + // to a cipher being selected. + void SetVersionIfNullCipher(uint16_t version); + + // ProtocolVersion returns the protocol version associated with this + // SSLAEADContext. It can only be called once |version_| has been set to a + // valid value. + uint16_t ProtocolVersion() const; + + // RecordVersion returns the record version that should be used with this + // SSLAEADContext for record construction and crypto. + uint16_t RecordVersion() const; + + const SSL_CIPHER *cipher() const { return cipher_; } + + // is_null_cipher returns true if this is the null cipher. + bool is_null_cipher() const { return !cipher_; } + + // ExplicitNonceLen returns the length of the explicit nonce. + size_t ExplicitNonceLen() const; + + // MaxOverhead returns the maximum overhead of calling |Seal|. + size_t MaxOverhead() const; + + // SuffixLen calculates the suffix length written by |SealScatter| and writes + // it to |*out_suffix_len|. It returns true on success and false on error. + // |in_len| and |extra_in_len| should equal the argument of the same names + // passed to |SealScatter|. + bool SuffixLen(size_t *out_suffix_len, size_t in_len, + size_t extra_in_len) const; + + // Open authenticates and decrypts |in| in-place. On success, it sets |*out| + // to the plaintext in |in| and returns true. Otherwise, it returns + // false. The output will always be |ExplicitNonceLen| bytes ahead of |in|. + bool Open(Span *out, uint8_t type, uint16_t record_version, + const uint8_t seqnum[8], Span in); + + // Seal encrypts and authenticates |in_len| bytes from |in| and writes the + // result to |out|. It returns true on success and false on error. + // + // If |in| and |out| alias then |out| + |ExplicitNonceLen| must be == |in|. + bool Seal(uint8_t *out, size_t *out_len, size_t max_out, uint8_t type, + uint16_t record_version, const uint8_t seqnum[8], const uint8_t *in, + size_t in_len); + + // SealScatter encrypts and authenticates |in_len| bytes from |in| and splits + // the result between |out_prefix|, |out| and |out_suffix|. It returns one on + // success and zero on error. + // + // On successful return, exactly |ExplicitNonceLen| bytes are written to + // |out_prefix|, |in_len| bytes to |out|, and |SuffixLen| bytes to + // |out_suffix|. + // + // |extra_in| may point to an additional plaintext buffer. If present, + // |extra_in_len| additional bytes are encrypted and authenticated, and the + // ciphertext is written to the beginning of |out_suffix|. |SuffixLen| should + // be used to size |out_suffix| accordingly. + // + // If |in| and |out| alias then |out| must be == |in|. Other arguments may not + // alias anything. + bool SealScatter(uint8_t *out_prefix, uint8_t *out, uint8_t *out_suffix, + uint8_t type, uint16_t record_version, + const uint8_t seqnum[8], const uint8_t *in, size_t in_len, + const uint8_t *extra_in, size_t extra_in_len); + + bool GetIV(const uint8_t **out_iv, size_t *out_iv_len) const; + + private: + // GetAdditionalData writes the additional data into |out| and returns the + // number of bytes written. + size_t GetAdditionalData(uint8_t out[13], uint8_t type, + uint16_t record_version, const uint8_t seqnum[8], + size_t plaintext_len); + + const SSL_CIPHER *cipher_; + ScopedEVP_AEAD_CTX ctx_; + // fixed_nonce_ contains any bytes of the nonce that are fixed for all + // records. + uint8_t fixed_nonce_[12]; + uint8_t fixed_nonce_len_ = 0, variable_nonce_len_ = 0; + // version_ is the wire version that should be used with this AEAD. + uint16_t version_; + // is_dtls_ is whether DTLS is being used with this AEAD. + bool is_dtls_; + // variable_nonce_included_in_record_ is true if the variable nonce + // for a record is included as a prefix before the ciphertext. + bool variable_nonce_included_in_record_ : 1; + // random_variable_nonce_ is true if the variable nonce is + // randomly generated, rather than derived from the sequence + // number. + bool random_variable_nonce_ : 1; + // omit_length_in_ad_ is true if the length should be omitted in the + // AEAD's ad parameter. + bool omit_length_in_ad_ : 1; + // omit_version_in_ad_ is true if the version should be omitted + // in the AEAD's ad parameter. + bool omit_version_in_ad_ : 1; + // omit_ad_ is true if the AEAD's ad parameter should be omitted. + bool omit_ad_ : 1; + // xor_fixed_nonce_ is true if the fixed nonce should be XOR'd into the + // variable nonce rather than prepended. + bool xor_fixed_nonce_ : 1; +}; + + +// DTLS replay bitmap. + +// DTLS1_BITMAP maintains a sliding window of 64 sequence numbers to detect +// replayed packets. It should be initialized by zeroing every field. +struct DTLS1_BITMAP { + // map is a bit mask of the last 64 sequence numbers. Bit + // |1< *out, size_t *out_consumed, + uint8_t *out_alert, Span in); + +// dtls_open_record implements |tls_open_record| for DTLS. It only returns +// |ssl_open_record_partial| if |in| was empty and sets |*out_consumed| to +// zero. The caller should read one packet and try again. +enum ssl_open_record_t dtls_open_record(SSL *ssl, uint8_t *out_type, + Span *out, + size_t *out_consumed, + uint8_t *out_alert, Span in); + +// ssl_seal_align_prefix_len returns the length of the prefix before the start +// of the bulk of the ciphertext when sealing a record with |ssl|. Callers may +// use this to align buffers. +// +// Note when TLS 1.0 CBC record-splitting is enabled, this includes the one byte +// record and is the offset into second record's ciphertext. Thus sealing a +// small record may result in a smaller output than this value. +// +// TODO(davidben): Is this alignment valuable? Record-splitting makes this a +// mess. +size_t ssl_seal_align_prefix_len(const SSL *ssl); + +// tls_seal_record seals a new record of type |type| and body |in| and writes it +// to |out|. At most |max_out| bytes will be written. It returns one on success +// and zero on error. If enabled, |tls_seal_record| implements TLS 1.0 CBC 1/n-1 +// record splitting and may write two records concatenated. +// +// For a large record, the bulk of the ciphertext will begin +// |ssl_seal_align_prefix_len| bytes into out. Aligning |out| appropriately may +// improve performance. It writes at most |in_len| + |SSL_max_seal_overhead| +// bytes to |out|. +// +// |in| and |out| may not alias. +int tls_seal_record(SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out, + uint8_t type, const uint8_t *in, size_t in_len); + +enum dtls1_use_epoch_t { + dtls1_use_previous_epoch, + dtls1_use_current_epoch, +}; + +// dtls_max_seal_overhead returns the maximum overhead, in bytes, of sealing a +// record. +size_t dtls_max_seal_overhead(const SSL *ssl, enum dtls1_use_epoch_t use_epoch); + +// dtls_seal_prefix_len returns the number of bytes of prefix to reserve in +// front of the plaintext when sealing a record in-place. +size_t dtls_seal_prefix_len(const SSL *ssl, enum dtls1_use_epoch_t use_epoch); + +// dtls_seal_record implements |tls_seal_record| for DTLS. |use_epoch| selects +// which epoch's cipher state to use. Unlike |tls_seal_record|, |in| and |out| +// may alias but, if they do, |in| must be exactly |dtls_seal_prefix_len| bytes +// ahead of |out|. +int dtls_seal_record(SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out, + uint8_t type, const uint8_t *in, size_t in_len, + enum dtls1_use_epoch_t use_epoch); + +// ssl_process_alert processes |in| as an alert and updates |ssl|'s shutdown +// state. It returns one of |ssl_open_record_discard|, |ssl_open_record_error|, +// |ssl_open_record_close_notify|, or |ssl_open_record_fatal_alert| as +// appropriate. +enum ssl_open_record_t ssl_process_alert(SSL *ssl, uint8_t *out_alert, + Span in); + + +// Private key operations. + +// ssl_has_private_key returns one if |ssl| has a private key +// configured and zero otherwise. +int ssl_has_private_key(const SSL *ssl); + +// ssl_private_key_* perform the corresponding operation on +// |SSL_PRIVATE_KEY_METHOD|. If there is a custom private key configured, they +// call the corresponding function or |complete| depending on whether there is a +// pending operation. Otherwise, they implement the operation with +// |EVP_PKEY|. + +enum ssl_private_key_result_t ssl_private_key_sign( + SSL_HANDSHAKE *hs, uint8_t *out, size_t *out_len, size_t max_out, + uint16_t sigalg, Span in); + +enum ssl_private_key_result_t ssl_private_key_decrypt(SSL_HANDSHAKE *hs, + uint8_t *out, + size_t *out_len, + size_t max_out, + Span in); + +// ssl_private_key_supports_signature_algorithm returns whether |hs|'s private +// key supports |sigalg|. +bool ssl_private_key_supports_signature_algorithm(SSL_HANDSHAKE *hs, + uint16_t sigalg); + +// ssl_public_key_verify verifies that the |signature| is valid for the public +// key |pkey| and input |in|, using the signature algorithm |sigalg|. +bool ssl_public_key_verify(SSL *ssl, Span signature, + uint16_t sigalg, EVP_PKEY *pkey, + Span in); + + +// Custom extensions + +} // namespace bssl + +// |SSL_CUSTOM_EXTENSION| is a structure that contains information about +// custom-extension callbacks. It is defined unnamespaced for compatibility with +// |STACK_OF(SSL_CUSTOM_EXTENSION)|. +typedef struct ssl_custom_extension { + SSL_custom_ext_add_cb add_callback; + void *add_arg; + SSL_custom_ext_free_cb free_callback; + SSL_custom_ext_parse_cb parse_callback; + void *parse_arg; + uint16_t value; +} SSL_CUSTOM_EXTENSION; + +DEFINE_STACK_OF(SSL_CUSTOM_EXTENSION) + +namespace bssl { + +void SSL_CUSTOM_EXTENSION_free(SSL_CUSTOM_EXTENSION *custom_extension); + +int custom_ext_add_clienthello(SSL_HANDSHAKE *hs, CBB *extensions); +int custom_ext_parse_serverhello(SSL_HANDSHAKE *hs, int *out_alert, + uint16_t value, const CBS *extension); +int custom_ext_parse_clienthello(SSL_HANDSHAKE *hs, int *out_alert, + uint16_t value, const CBS *extension); +int custom_ext_add_serverhello(SSL_HANDSHAKE *hs, CBB *extensions); + + +// Key shares. + +// SSLKeyShare abstracts over Diffie-Hellman-like key exchanges. +class SSLKeyShare { + public: + virtual ~SSLKeyShare() {} + static constexpr bool kAllowUniquePtr = true; + HAS_VIRTUAL_DESTRUCTOR + + // Create returns a SSLKeyShare instance for use with group |group_id| or + // nullptr on error. + static UniquePtr Create(uint16_t group_id); + + // GroupID returns the group ID. + virtual uint16_t GroupID() const PURE_VIRTUAL; + + // Offer generates a keypair and writes the public value to + // |out_public_key|. It returns true on success and false on error. + virtual bool Offer(CBB *out_public_key) PURE_VIRTUAL; + + // Accept performs a key exchange against the |peer_key| generated by |offer|. + // On success, it returns true, writes the public value to |out_public_key|, + // and sets |*out_secret| the shared secret. On failure, it returns false and + // sets |*out_alert| to an alert to send to the peer. + // + // The default implementation calls |Offer| and then |Finish|, assuming a key + // exchange protocol where the peers are symmetric. + virtual bool Accept(CBB *out_public_key, Array *out_secret, + uint8_t *out_alert, Span peer_key); + + // Finish performs a key exchange against the |peer_key| generated by + // |Accept|. On success, it returns true and sets |*out_secret| to the shared + // secret. On failure, it returns zero and sets |*out_alert| to an alert to + // send to the peer. + virtual bool Finish(Array *out_secret, uint8_t *out_alert, + Span peer_key) PURE_VIRTUAL; +}; + +// ssl_nid_to_group_id looks up the group corresponding to |nid|. On success, it +// sets |*out_group_id| to the group ID and returns one. Otherwise, it returns +// zero. +int ssl_nid_to_group_id(uint16_t *out_group_id, int nid); + +// ssl_name_to_group_id looks up the group corresponding to the |name| string +// of length |len|. On success, it sets |*out_group_id| to the group ID and +// returns one. Otherwise, it returns zero. +int ssl_name_to_group_id(uint16_t *out_group_id, const char *name, size_t len); + + +// Handshake messages. + +struct SSLMessage { + bool is_v2_hello; + uint8_t type; + CBS body; + // raw is the entire serialized handshake message, including the TLS or DTLS + // message header. + CBS raw; +}; + +// SSL_MAX_HANDSHAKE_FLIGHT is the number of messages, including +// ChangeCipherSpec, in the longest handshake flight. Currently this is the +// client's second leg in a full handshake when client certificates, NPN, and +// Channel ID, are all enabled. +#define SSL_MAX_HANDSHAKE_FLIGHT 7 + +extern const uint8_t kHelloRetryRequest[SSL3_RANDOM_SIZE]; +extern const uint8_t kDraftDowngradeRandom[8]; + +// ssl_max_handshake_message_len returns the maximum number of bytes permitted +// in a handshake message for |ssl|. +size_t ssl_max_handshake_message_len(const SSL *ssl); + +// tls_can_accept_handshake_data returns whether |ssl| is able to accept more +// data into handshake buffer. +bool tls_can_accept_handshake_data(const SSL *ssl, uint8_t *out_alert); + +// tls_has_unprocessed_handshake_data returns whether there is buffered +// handshake data that has not been consumed by |get_message|. +bool tls_has_unprocessed_handshake_data(const SSL *ssl); + +// dtls_has_unprocessed_handshake_data behaves like +// |tls_has_unprocessed_handshake_data| for DTLS. +bool dtls_has_unprocessed_handshake_data(const SSL *ssl); + +struct DTLS_OUTGOING_MESSAGE { + DTLS_OUTGOING_MESSAGE() {} + DTLS_OUTGOING_MESSAGE(const DTLS_OUTGOING_MESSAGE &) = delete; + DTLS_OUTGOING_MESSAGE &operator=(const DTLS_OUTGOING_MESSAGE &) = delete; + ~DTLS_OUTGOING_MESSAGE() { Clear(); } + + void Clear(); + + uint8_t *data = nullptr; + uint32_t len = 0; + uint16_t epoch = 0; + bool is_ccs = false; +}; + +// dtls_clear_outgoing_messages releases all buffered outgoing messages. +void dtls_clear_outgoing_messages(SSL *ssl); + + +// Callbacks. + +// ssl_do_info_callback calls |ssl|'s info callback, if set. +void ssl_do_info_callback(const SSL *ssl, int type, int value); + +// ssl_do_msg_callback calls |ssl|'s message callback, if set. +void ssl_do_msg_callback(SSL *ssl, int is_write, int content_type, + Span in); + + +// Transport buffers. + +class SSLBuffer { + public: + SSLBuffer() {} + ~SSLBuffer() { Clear(); } + + SSLBuffer(const SSLBuffer &) = delete; + SSLBuffer &operator=(const SSLBuffer &) = delete; + + uint8_t *data() { return buf_ + offset_; } + size_t size() const { return size_; } + bool empty() const { return size_ == 0; } + size_t cap() const { return cap_; } + + Span span() { return MakeSpan(data(), size()); } + + Span remaining() { + return MakeSpan(data() + size(), cap() - size()); + } + + // Clear releases the buffer. + void Clear(); + + // EnsureCap ensures the buffer has capacity at least |new_cap|, aligned such + // that data written after |header_len| is aligned to a + // |SSL3_ALIGN_PAYLOAD|-byte boundary. It returns true on success and false + // on error. + bool EnsureCap(size_t header_len, size_t new_cap); + + // DidWrite extends the buffer by |len|. The caller must have filled in to + // this point. + void DidWrite(size_t len); + + // Consume consumes |len| bytes from the front of the buffer. The memory + // consumed will remain valid until the next call to |DiscardConsumed| or + // |Clear|. + void Consume(size_t len); + + // DiscardConsumed discards the consumed bytes from the buffer. If the buffer + // is now empty, it releases memory used by it. + void DiscardConsumed(); + + private: + // buf_ is the memory allocated for this buffer. + uint8_t *buf_ = nullptr; + // offset_ is the offset into |buf_| which the buffer contents start at. + uint16_t offset_ = 0; + // size_ is the size of the buffer contents from |buf_| + |offset_|. + uint16_t size_ = 0; + // cap_ is how much memory beyond |buf_| + |offset_| is available. + uint16_t cap_ = 0; +}; + +// ssl_read_buffer_extend_to extends the read buffer to the desired length. For +// TLS, it reads to the end of the buffer until the buffer is |len| bytes +// long. For DTLS, it reads a new packet and ignores |len|. It returns one on +// success, zero on EOF, and a negative number on error. +// +// It is an error to call |ssl_read_buffer_extend_to| in DTLS when the buffer is +// non-empty. +int ssl_read_buffer_extend_to(SSL *ssl, size_t len); + +// ssl_handle_open_record handles the result of passing |ssl->s3->read_buffer| +// to a record-processing function. If |ret| is a success or if the caller +// should retry, it returns one and sets |*out_retry|. Otherwise, it returns <= +// 0. +int ssl_handle_open_record(SSL *ssl, bool *out_retry, ssl_open_record_t ret, + size_t consumed, uint8_t alert); + +// ssl_write_buffer_flush flushes the write buffer to the transport. It returns +// one on success and <= 0 on error. For DTLS, whether or not the write +// succeeds, the write buffer will be cleared. +int ssl_write_buffer_flush(SSL *ssl); + + +// Certificate functions. + +// ssl_has_certificate returns one if a certificate and private key are +// configured and zero otherwise. +int ssl_has_certificate(const SSL *ssl); + +// ssl_parse_cert_chain parses a certificate list from |cbs| in the format used +// by a TLS Certificate message. On success, it advances |cbs| and returns +// true. Otherwise, it returns false and sets |*out_alert| to an alert to send +// to the peer. +// +// If the list is non-empty then |*out_chain| and |*out_pubkey| will be set to +// the certificate chain and the leaf certificate's public key +// respectively. Otherwise, both will be set to nullptr. +// +// If the list is non-empty and |out_leaf_sha256| is non-NULL, it writes the +// SHA-256 hash of the leaf to |out_leaf_sha256|. +bool ssl_parse_cert_chain(uint8_t *out_alert, + UniquePtr *out_chain, + UniquePtr *out_pubkey, + uint8_t *out_leaf_sha256, CBS *cbs, + CRYPTO_BUFFER_POOL *pool); + +// ssl_add_cert_chain adds |ssl|'s certificate chain to |cbb| in the format used +// by a TLS Certificate message. If there is no certificate chain, it emits an +// empty certificate list. It returns one on success and zero on error. +int ssl_add_cert_chain(SSL *ssl, CBB *cbb); + +// ssl_cert_check_digital_signature_key_usage parses the DER-encoded, X.509 +// certificate in |in| and returns one if doesn't specify a key usage or, if it +// does, if it includes digitalSignature. Otherwise it pushes to the error +// queue and returns zero. +int ssl_cert_check_digital_signature_key_usage(const CBS *in); + +// ssl_cert_parse_pubkey extracts the public key from the DER-encoded, X.509 +// certificate in |in|. It returns an allocated |EVP_PKEY| or else returns +// nullptr and pushes to the error queue. +UniquePtr ssl_cert_parse_pubkey(const CBS *in); + +// ssl_parse_client_CA_list parses a CA list from |cbs| in the format used by a +// TLS CertificateRequest message. On success, it returns a newly-allocated +// |CRYPTO_BUFFER| list and advances |cbs|. Otherwise, it returns nullptr and +// sets |*out_alert| to an alert to send to the peer. +UniquePtr ssl_parse_client_CA_list(SSL *ssl, + uint8_t *out_alert, + CBS *cbs); + +// ssl_has_client_CAs returns there are configured CAs. +bool ssl_has_client_CAs(SSL *ssl); + +// ssl_add_client_CA_list adds the configured CA list to |cbb| in the format +// used by a TLS CertificateRequest message. It returns one on success and zero +// on error. +int ssl_add_client_CA_list(SSL *ssl, CBB *cbb); + +// ssl_check_leaf_certificate returns one if |pkey| and |leaf| are suitable as +// a server's leaf certificate for |hs|. Otherwise, it returns zero and pushes +// an error on the error queue. +int ssl_check_leaf_certificate(SSL_HANDSHAKE *hs, EVP_PKEY *pkey, + const CRYPTO_BUFFER *leaf); + +// ssl_on_certificate_selected is called once the certificate has been selected. +// It finalizes the certificate and initializes |hs->local_pubkey|. It returns +// one on success and zero on error. +int ssl_on_certificate_selected(SSL_HANDSHAKE *hs); + + +// TLS 1.3 key derivation. + +// tls13_init_key_schedule initializes the handshake hash and key derivation +// state, and incorporates the PSK. The cipher suite and PRF hash must have been +// selected at this point. It returns one on success and zero on error. +int tls13_init_key_schedule(SSL_HANDSHAKE *hs, const uint8_t *psk, + size_t psk_len); + +// tls13_init_early_key_schedule initializes the handshake hash and key +// derivation state from the resumption secret and incorporates the PSK to +// derive the early secrets. It returns one on success and zero on error. +int tls13_init_early_key_schedule(SSL_HANDSHAKE *hs, const uint8_t *psk, + size_t psk_len); + +// tls13_advance_key_schedule incorporates |in| into the key schedule with +// HKDF-Extract. It returns one on success and zero on error. +int tls13_advance_key_schedule(SSL_HANDSHAKE *hs, const uint8_t *in, + size_t len); + +// tls13_set_traffic_key sets the read or write traffic keys to +// |traffic_secret|. It returns one on success and zero on error. +int tls13_set_traffic_key(SSL *ssl, enum evp_aead_direction_t direction, + const uint8_t *traffic_secret, + size_t traffic_secret_len); + +// tls13_derive_early_secrets derives the early traffic secret. It returns one +// on success and zero on error. +int tls13_derive_early_secrets(SSL_HANDSHAKE *hs); + +// tls13_derive_handshake_secrets derives the handshake traffic secret. It +// returns one on success and zero on error. +int tls13_derive_handshake_secrets(SSL_HANDSHAKE *hs); + +// tls13_rotate_traffic_key derives the next read or write traffic secret. It +// returns one on success and zero on error. +int tls13_rotate_traffic_key(SSL *ssl, enum evp_aead_direction_t direction); + +// tls13_derive_application_secrets derives the initial application data traffic +// and exporter secrets based on the handshake transcripts and |master_secret|. +// It returns one on success and zero on error. +int tls13_derive_application_secrets(SSL_HANDSHAKE *hs); + +// tls13_derive_resumption_secret derives the |resumption_secret|. +int tls13_derive_resumption_secret(SSL_HANDSHAKE *hs); + +// tls13_export_keying_material provides an exporter interface to use the +// |exporter_secret|. +int tls13_export_keying_material(SSL *ssl, Span out, + Span secret, + Span label, + Span context); + +// tls13_finished_mac calculates the MAC of the handshake transcript to verify +// the integrity of the Finished message, and stores the result in |out| and +// length in |out_len|. |is_server| is 1 if this is for the Server Finished and +// 0 for the Client Finished. +int tls13_finished_mac(SSL_HANDSHAKE *hs, uint8_t *out, + size_t *out_len, int is_server); + +// tls13_derive_session_psk calculates the PSK for this session based on the +// resumption master secret and |nonce|. It returns true on success, and false +// on failure. +bool tls13_derive_session_psk(SSL_SESSION *session, Span nonce); + +// tls13_write_psk_binder calculates the PSK binder value and replaces the last +// bytes of |msg| with the resulting value. It returns 1 on success, and 0 on +// failure. +int tls13_write_psk_binder(SSL_HANDSHAKE *hs, uint8_t *msg, size_t len); + +// tls13_verify_psk_binder verifies that the handshake transcript, truncated +// up to the binders has a valid signature using the value of |session|'s +// resumption secret. It returns 1 on success, and 0 on failure. +int tls13_verify_psk_binder(SSL_HANDSHAKE *hs, SSL_SESSION *session, + const SSLMessage &msg, CBS *binders); + + +// Handshake functions. + +enum ssl_hs_wait_t { + ssl_hs_error, + ssl_hs_ok, + ssl_hs_read_server_hello, + ssl_hs_read_message, + ssl_hs_flush, + ssl_hs_certificate_selection_pending, + ssl_hs_handoff, + ssl_hs_x509_lookup, + ssl_hs_channel_id_lookup, + ssl_hs_private_key_operation, + ssl_hs_pending_session, + ssl_hs_pending_ticket, + ssl_hs_early_return, + ssl_hs_early_data_rejected, + ssl_hs_read_end_of_early_data, + ssl_hs_read_change_cipher_spec, + ssl_hs_certificate_verify, +}; + +enum ssl_grease_index_t { + ssl_grease_cipher = 0, + ssl_grease_group, + ssl_grease_extension1, + ssl_grease_extension2, + ssl_grease_version, + ssl_grease_ticket_extension, + ssl_grease_last_index = ssl_grease_ticket_extension, +}; + +struct SSL_HANDSHAKE { + explicit SSL_HANDSHAKE(SSL *ssl); + ~SSL_HANDSHAKE(); + static constexpr bool kAllowUniquePtr = true; + + // ssl is a non-owning pointer to the parent |SSL| object. + SSL *ssl; + + // wait contains the operation the handshake is currently blocking on or + // |ssl_hs_ok| if none. + enum ssl_hs_wait_t wait = ssl_hs_ok; + + // state is the internal state for the TLS 1.2 and below handshake. Its + // values depend on |do_handshake| but the starting state is always zero. + int state = 0; + + // tls13_state is the internal state for the TLS 1.3 handshake. Its values + // depend on |do_handshake| but the starting state is always zero. + int tls13_state = 0; + + // min_version is the minimum accepted protocol version, taking account both + // |SSL_OP_NO_*| and |SSL_CTX_set_min_proto_version| APIs. + uint16_t min_version = 0; + + // max_version is the maximum accepted protocol version, taking account both + // |SSL_OP_NO_*| and |SSL_CTX_set_max_proto_version| APIs. + uint16_t max_version = 0; + + size_t hash_len = 0; + uint8_t secret[EVP_MAX_MD_SIZE] = {0}; + uint8_t early_traffic_secret[EVP_MAX_MD_SIZE] = {0}; + uint8_t client_handshake_secret[EVP_MAX_MD_SIZE] = {0}; + uint8_t server_handshake_secret[EVP_MAX_MD_SIZE] = {0}; + uint8_t client_traffic_secret_0[EVP_MAX_MD_SIZE] = {0}; + uint8_t server_traffic_secret_0[EVP_MAX_MD_SIZE] = {0}; + uint8_t expected_client_finished[EVP_MAX_MD_SIZE] = {0}; + + union { + // sent is a bitset where the bits correspond to elements of kExtensions + // in t1_lib.c. Each bit is set if that extension was sent in a + // ClientHello. It's not used by servers. + uint32_t sent = 0; + // received is a bitset, like |sent|, but is used by servers to record + // which extensions were received from a client. + uint32_t received; + } extensions; + + union { + // sent is a bitset where the bits correspond to elements of + // |client_custom_extensions| in the |SSL_CTX|. Each bit is set if that + // extension was sent in a ClientHello. It's not used by servers. + uint16_t sent = 0; + // received is a bitset, like |sent|, but is used by servers to record + // which custom extensions were received from a client. The bits here + // correspond to |server_custom_extensions|. + uint16_t received; + } custom_extensions; + + // retry_group is the group ID selected by the server in HelloRetryRequest in + // TLS 1.3. + uint16_t retry_group = 0; + + // error, if |wait| is |ssl_hs_error|, is the error the handshake failed on. + UniquePtr error; + + // key_share is the current key exchange instance. + UniquePtr key_share; + + // transcript is the current handshake transcript. + SSLTranscript transcript; + + // cookie is the value of the cookie received from the server, if any. + Array cookie; + + // key_share_bytes is the value of the previously sent KeyShare extension by + // the client in TLS 1.3. + Array key_share_bytes; + + // ecdh_public_key, for servers, is the key share to be sent to the client in + // TLS 1.3. + Array ecdh_public_key; + + // peer_sigalgs are the signature algorithms that the peer supports. These are + // taken from the contents of the signature algorithms extension for a server + // or from the CertificateRequest for a client. + Array peer_sigalgs; + + // peer_supported_group_list contains the supported group IDs advertised by + // the peer. This is only set on the server's end. The server does not + // advertise this extension to the client. + Array peer_supported_group_list; + + // peer_key is the peer's ECDH key for a TLS 1.2 client. + Array peer_key; + + // negotiated_token_binding_version is used by a server to store the + // on-the-wire encoding of the Token Binding protocol version to advertise in + // the ServerHello/EncryptedExtensions if the Token Binding extension is to be + // sent. + uint16_t negotiated_token_binding_version; + + // server_params, in a TLS 1.2 server, stores the ServerKeyExchange + // parameters. It has client and server randoms prepended for signing + // convenience. + Array server_params; + + // peer_psk_identity_hint, on the client, is the psk_identity_hint sent by the + // server when using a TLS 1.2 PSK key exchange. + UniquePtr peer_psk_identity_hint; + + // ca_names, on the client, contains the list of CAs received in a + // CertificateRequest message. + UniquePtr ca_names; + + // cached_x509_ca_names contains a cache of parsed versions of the elements of + // |ca_names|. This pointer is left non-owning so only + // |ssl_crypto_x509_method| needs to link against crypto/x509. + STACK_OF(X509_NAME) *cached_x509_ca_names = nullptr; + + // certificate_types, on the client, contains the set of certificate types + // received in a CertificateRequest message. + Array certificate_types; + + // local_pubkey is the public key we are authenticating as. + UniquePtr local_pubkey; + + // peer_pubkey is the public key parsed from the peer's leaf certificate. + UniquePtr peer_pubkey; + + // new_session is the new mutable session being established by the current + // handshake. It should not be cached. + UniquePtr new_session; + + // early_session is the session corresponding to the current 0-RTT state on + // the client if |in_early_data| is true. + UniquePtr early_session; + + // new_cipher is the cipher being negotiated in this handshake. + const SSL_CIPHER *new_cipher = nullptr; + + // key_block is the record-layer key block for TLS 1.2 and earlier. + Array key_block; + + // scts_requested is true if the SCT extension is in the ClientHello. + bool scts_requested:1; + + // needs_psk_binder is true if the ClientHello has a placeholder PSK binder to + // be filled in. + bool needs_psk_binder:1; + + bool received_hello_retry_request:1; + bool sent_hello_retry_request:1; + + bool received_custom_extension:1; + + // handshake_finalized is true once the handshake has completed, at which + // point accessors should use the established state. + bool handshake_finalized:1; + + // accept_psk_mode stores whether the client's PSK mode is compatible with our + // preferences. + bool accept_psk_mode:1; + + // cert_request is true if a client certificate was requested. + bool cert_request:1; + + // certificate_status_expected is true if OCSP stapling was negotiated and the + // server is expected to send a CertificateStatus message. (This is used on + // both the client and server sides.) + bool certificate_status_expected:1; + + // ocsp_stapling_requested is true if a client requested OCSP stapling. + bool ocsp_stapling_requested:1; + + // should_ack_sni is used by a server and indicates that the SNI extension + // should be echoed in the ServerHello. + bool should_ack_sni:1; + + // in_false_start is true if there is a pending client handshake in False + // Start. The client may write data at this point. + bool in_false_start:1; + + // in_early_data is true if there is a pending handshake that has progressed + // enough to send and receive early data. + bool in_early_data:1; + + // early_data_offered is true if the client sent the early_data extension. + bool early_data_offered:1; + + // can_early_read is true if application data may be read at this point in the + // handshake. + bool can_early_read:1; + + // can_early_write is true if application data may be written at this point in + // the handshake. + bool can_early_write:1; + + // next_proto_neg_seen is one of NPN was negotiated. + bool next_proto_neg_seen:1; + + // ticket_expected is true if a TLS 1.2 NewSessionTicket message is to be sent + // or received. + bool ticket_expected:1; + + // extended_master_secret is true if the extended master secret extension is + // negotiated in this handshake. + bool extended_master_secret:1; + + // pending_private_key_op is true if there is a pending private key operation + // in progress. + bool pending_private_key_op:1; + + // grease_seeded is true if |grease_seed| has been initialized. + bool grease_seeded:1; + + // client_version is the value sent or received in the ClientHello version. + uint16_t client_version = 0; + + // early_data_read is the amount of early data that has been read by the + // record layer. + uint16_t early_data_read = 0; + + // early_data_written is the amount of early data that has been written by the + // record layer. + uint16_t early_data_written = 0; + + // session_id is the session ID in the ClientHello, used for the experimental + // TLS 1.3 variant. + uint8_t session_id[SSL_MAX_SSL_SESSION_ID_LENGTH] = {0}; + uint8_t session_id_len = 0; + + // grease_seed is the entropy for GREASE values. It is valid if + // |grease_seeded| is true. + uint8_t grease_seed[ssl_grease_last_index + 1] = {0}; + + // dummy_pq_padding_len, in a server, is the length of the extension that + // should be echoed in a ServerHello, or zero if no extension should be + // echoed. + uint16_t dummy_pq_padding_len = 0; +}; + +UniquePtr ssl_handshake_new(SSL *ssl); + +// ssl_check_message_type checks if |msg| has type |type|. If so it returns +// one. Otherwise, it sends an alert and returns zero. +bool ssl_check_message_type(SSL *ssl, const SSLMessage &msg, int type); + +// ssl_run_handshake runs the TLS handshake. It returns one on success and <= 0 +// on error. It sets |out_early_return| to one if we've completed the handshake +// early. +int ssl_run_handshake(SSL_HANDSHAKE *hs, bool *out_early_return); + +// The following are implementations of |do_handshake| for the client and +// server. +enum ssl_hs_wait_t ssl_client_handshake(SSL_HANDSHAKE *hs); +enum ssl_hs_wait_t ssl_server_handshake(SSL_HANDSHAKE *hs); +enum ssl_hs_wait_t tls13_client_handshake(SSL_HANDSHAKE *hs); +enum ssl_hs_wait_t tls13_server_handshake(SSL_HANDSHAKE *hs); + +// The following functions return human-readable representations of the TLS +// handshake states for debugging. +const char *ssl_client_handshake_state(SSL_HANDSHAKE *hs); +const char *ssl_server_handshake_state(SSL_HANDSHAKE *hs); +const char *tls13_client_handshake_state(SSL_HANDSHAKE *hs); +const char *tls13_server_handshake_state(SSL_HANDSHAKE *hs); + +// tls13_post_handshake processes a post-handshake message. It returns one on +// success and zero on failure. +int tls13_post_handshake(SSL *ssl, const SSLMessage &msg); + +int tls13_process_certificate(SSL_HANDSHAKE *hs, const SSLMessage &msg, + int allow_anonymous); +int tls13_process_certificate_verify(SSL_HANDSHAKE *hs, const SSLMessage &msg); + +// tls13_process_finished processes |msg| as a Finished message from the +// peer. If |use_saved_value| is one, the verify_data is compared against +// |hs->expected_client_finished| rather than computed fresh. +int tls13_process_finished(SSL_HANDSHAKE *hs, const SSLMessage &msg, + int use_saved_value); + +int tls13_add_certificate(SSL_HANDSHAKE *hs); + +// tls13_add_certificate_verify adds a TLS 1.3 CertificateVerify message to the +// handshake. If it returns |ssl_private_key_retry|, it should be called again +// to retry when the signing operation is completed. +enum ssl_private_key_result_t tls13_add_certificate_verify(SSL_HANDSHAKE *hs); + +int tls13_add_finished(SSL_HANDSHAKE *hs); +int tls13_process_new_session_ticket(SSL *ssl, const SSLMessage &msg); + +bool ssl_ext_key_share_parse_serverhello(SSL_HANDSHAKE *hs, + Array *out_secret, + uint8_t *out_alert, CBS *contents); +bool ssl_ext_key_share_parse_clienthello(SSL_HANDSHAKE *hs, bool *out_found, + Array *out_secret, + uint8_t *out_alert, CBS *contents); +bool ssl_ext_key_share_add_serverhello(SSL_HANDSHAKE *hs, CBB *out); + +bool ssl_ext_pre_shared_key_parse_serverhello(SSL_HANDSHAKE *hs, + uint8_t *out_alert, + CBS *contents); +bool ssl_ext_pre_shared_key_parse_clienthello( + SSL_HANDSHAKE *hs, CBS *out_ticket, CBS *out_binders, + uint32_t *out_obfuscated_ticket_age, uint8_t *out_alert, CBS *contents); +bool ssl_ext_pre_shared_key_add_serverhello(SSL_HANDSHAKE *hs, CBB *out); + +// ssl_is_sct_list_valid does a shallow parse of the SCT list in |contents| and +// returns one iff it's valid. +int ssl_is_sct_list_valid(const CBS *contents); + +int ssl_write_client_hello(SSL_HANDSHAKE *hs); + +enum ssl_cert_verify_context_t { + ssl_cert_verify_server, + ssl_cert_verify_client, + ssl_cert_verify_channel_id, +}; + +// tls13_get_cert_verify_signature_input generates the message to be signed for +// TLS 1.3's CertificateVerify message. |cert_verify_context| determines the +// type of signature. It sets |*out| to a newly allocated buffer containing the +// result. This function returns true on success and false on failure. +bool tls13_get_cert_verify_signature_input( + SSL_HANDSHAKE *hs, Array *out, + enum ssl_cert_verify_context_t cert_verify_context); + +// ssl_is_alpn_protocol_allowed returns whether |protocol| is a valid server +// selection for |ssl|'s client preferences. +bool ssl_is_alpn_protocol_allowed(const SSL *ssl, Span protocol); + +// ssl_negotiate_alpn negotiates the ALPN extension, if applicable. It returns +// true on successful negotiation or if nothing was negotiated. It returns false +// and sets |*out_alert| to an alert on error. +bool ssl_negotiate_alpn(SSL_HANDSHAKE *hs, uint8_t *out_alert, + const SSL_CLIENT_HELLO *client_hello); + +struct SSL_EXTENSION_TYPE { + uint16_t type; + bool *out_present; + CBS *out_data; +}; + +// ssl_parse_extensions parses a TLS extensions block out of |cbs| and advances +// it. It writes the parsed extensions to pointers denoted by |ext_types|. On +// success, it fills in the |out_present| and |out_data| fields and returns one. +// Otherwise, it sets |*out_alert| to an alert to send and returns zero. Unknown +// extensions are rejected unless |ignore_unknown| is 1. +int ssl_parse_extensions(const CBS *cbs, uint8_t *out_alert, + const SSL_EXTENSION_TYPE *ext_types, + size_t num_ext_types, int ignore_unknown); + +// ssl_verify_peer_cert verifies the peer certificate for |hs|. +enum ssl_verify_result_t ssl_verify_peer_cert(SSL_HANDSHAKE *hs); + +enum ssl_hs_wait_t ssl_get_finished(SSL_HANDSHAKE *hs); +bool ssl_send_finished(SSL_HANDSHAKE *hs); +bool ssl_output_cert_chain(SSL *ssl); + + +// SSLKEYLOGFILE functions. + +// ssl_log_secret logs |secret| with label |label|, if logging is enabled for +// |ssl|. It returns one on success and zero on failure. +int ssl_log_secret(const SSL *ssl, const char *label, const uint8_t *secret, + size_t secret_len); + + +// ClientHello functions. + +int ssl_client_hello_init(SSL *ssl, SSL_CLIENT_HELLO *out, + const SSLMessage &msg); + +int ssl_client_hello_get_extension(const SSL_CLIENT_HELLO *client_hello, + CBS *out, uint16_t extension_type); + +int ssl_client_cipher_list_contains_cipher(const SSL_CLIENT_HELLO *client_hello, + uint16_t id); + + +// GREASE. + +// ssl_get_grease_value returns a GREASE value for |hs|. For a given +// connection, the values for each index will be deterministic. This allows the +// same ClientHello be sent twice for a HelloRetryRequest or the same group be +// advertised in both supported_groups and key_shares. +uint16_t ssl_get_grease_value(SSL_HANDSHAKE *hs, enum ssl_grease_index_t index); + + +// Signature algorithms. + +// tls1_parse_peer_sigalgs parses |sigalgs| as the list of peer signature +// algorithms and saves them on |hs|. It returns true on success and false on +// error. +bool tls1_parse_peer_sigalgs(SSL_HANDSHAKE *hs, const CBS *sigalgs); + +// tls1_get_legacy_signature_algorithm sets |*out| to the signature algorithm +// that should be used with |pkey| in TLS 1.1 and earlier. It returns true on +// success and false if |pkey| may not be used at those versions. +bool tls1_get_legacy_signature_algorithm(uint16_t *out, const EVP_PKEY *pkey); + +// tls1_choose_signature_algorithm sets |*out| to a signature algorithm for use +// with |hs|'s private key based on the peer's preferences and the algorithms +// supported. It returns true on success and false on error. +bool tls1_choose_signature_algorithm(SSL_HANDSHAKE *hs, uint16_t *out); + +// tls12_add_verify_sigalgs adds the signature algorithms acceptable for the +// peer signature to |out|. It returns true on success and false on error. +bool tls12_add_verify_sigalgs(const SSL *ssl, CBB *out); + +// tls12_check_peer_sigalg checks if |sigalg| is acceptable for the peer +// signature. It returns true on success and false on error, setting +// |*out_alert| to an alert to send. +bool tls12_check_peer_sigalg(const SSL *ssl, uint8_t *out_alert, + uint16_t sigalg); + + +// Underdocumented functions. +// +// Functions below here haven't been touched up and may be underdocumented. + +#define TLSEXT_CHANNEL_ID_SIZE 128 + +// From RFC4492, used in encoding the curve type in ECParameters +#define NAMED_CURVE_TYPE 3 + +struct CERT { + EVP_PKEY *privatekey; + + // chain contains the certificate chain, with the leaf at the beginning. The + // first element of |chain| may be NULL to indicate that the leaf certificate + // has not yet been set. + // If |chain| != NULL -> len(chain) >= 1 + // If |chain[0]| == NULL -> len(chain) >= 2. + // |chain[1..]| != NULL + STACK_OF(CRYPTO_BUFFER) *chain; + + // x509_chain may contain a parsed copy of |chain[1..]|. This is only used as + // a cache in order to implement “get0” functions that return a non-owning + // pointer to the certificate chain. + STACK_OF(X509) *x509_chain; + + // x509_leaf may contain a parsed copy of the first element of |chain|. This + // is only used as a cache in order to implement “get0” functions that return + // a non-owning pointer to the certificate chain. + X509 *x509_leaf; + + // x509_stash contains the last |X509| object append to the chain. This is a + // workaround for some third-party code that continue to use an |X509| object + // even after passing ownership with an “add0” function. + X509 *x509_stash; + + // key_method, if non-NULL, is a set of callbacks to call for private key + // operations. + const SSL_PRIVATE_KEY_METHOD *key_method; + + // x509_method contains pointers to functions that might deal with |X509| + // compatibility, or might be a no-op, depending on the application. + const SSL_X509_METHOD *x509_method; + + // sigalgs, if non-NULL, is the set of signature algorithms supported by + // |privatekey| in decreasing order of preference. + uint16_t *sigalgs; + size_t num_sigalgs; + + // 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 certificate validation. If NULL the parent SSL_CTX + // store is used instead. + X509_STORE *verify_store; + + // Signed certificate timestamp list to be sent to the client, if requested + CRYPTO_BUFFER *signed_cert_timestamp_list; + + // OCSP response to be sent to the client, if requested. + CRYPTO_BUFFER *ocsp_response; + + // sid_ctx partitions the session space within a shared session cache or + // ticket key. Only sessions with a matching value will be accepted. + uint8_t sid_ctx_length; + uint8_t sid_ctx[SSL_MAX_SID_CTX_LENGTH]; + + // If enable_early_data is true, early data can be sent and accepted. + bool enable_early_data:1; +}; + +// |SSL_PROTOCOL_METHOD| abstracts between TLS and DTLS. +struct SSL_PROTOCOL_METHOD { + bool is_dtls; + bool (*ssl_new)(SSL *ssl); + void (*ssl_free)(SSL *ssl); + // get_message sets |*out| to the current handshake message and returns true + // if one has been received. It returns false if more input is needed. + bool (*get_message)(SSL *ssl, SSLMessage *out); + // next_message is called to release the current handshake message. + void (*next_message)(SSL *ssl); + // Use the |ssl_open_handshake| wrapper. + ssl_open_record_t (*open_handshake)(SSL *ssl, size_t *out_consumed, + uint8_t *out_alert, Span in); + // Use the |ssl_open_change_cipher_spec| wrapper. + ssl_open_record_t (*open_change_cipher_spec)(SSL *ssl, size_t *out_consumed, + uint8_t *out_alert, + Span in); + // Use the |ssl_open_app_data| wrapper. + ssl_open_record_t (*open_app_data)(SSL *ssl, Span *out, + size_t *out_consumed, uint8_t *out_alert, + Span in); + int (*write_app_data)(SSL *ssl, bool *out_needs_handshake, const uint8_t *buf, + int len); + int (*dispatch_alert)(SSL *ssl); + // init_message begins a new handshake message of type |type|. |cbb| is the + // root CBB to be passed into |finish_message|. |*body| is set to a child CBB + // the caller should write to. It returns true on success and false on error. + bool (*init_message)(SSL *ssl, CBB *cbb, CBB *body, uint8_t type); + // finish_message finishes a handshake message. It sets |*out_msg| to the + // serialized message. It returns true on success and false on error. + bool (*finish_message)(SSL *ssl, CBB *cbb, bssl::Array *out_msg); + // add_message adds a handshake message to the pending flight. It returns + // true on success and false on error. + bool (*add_message)(SSL *ssl, bssl::Array msg); + // add_change_cipher_spec adds a ChangeCipherSpec record to the pending + // flight. It returns true on success and false on error. + bool (*add_change_cipher_spec)(SSL *ssl); + // add_alert adds an alert to the pending flight. It returns true on success + // and false on error. + bool (*add_alert)(SSL *ssl, uint8_t level, uint8_t desc); + // flush_flight flushes the pending flight to the transport. It returns one on + // success and <= 0 on error. + int (*flush_flight)(SSL *ssl); + // on_handshake_complete is called when the handshake is complete. + void (*on_handshake_complete)(SSL *ssl); + // set_read_state sets |ssl|'s read cipher state to |aead_ctx|. It returns + // true on success and false if changing the read state is forbidden at this + // point. + bool (*set_read_state)(SSL *ssl, UniquePtr aead_ctx); + // set_write_state sets |ssl|'s write cipher state to |aead_ctx|. It returns + // true on success and false if changing the write state is forbidden at this + // point. + bool (*set_write_state)(SSL *ssl, UniquePtr aead_ctx); +}; + +// The following wrappers call |open_*| but handle |read_shutdown| correctly. + +// ssl_open_handshake processes a record from |in| for reading a handshake +// message. +ssl_open_record_t ssl_open_handshake(SSL *ssl, size_t *out_consumed, + uint8_t *out_alert, Span in); + +// ssl_open_change_cipher_spec processes a record from |in| for reading a +// ChangeCipherSpec. +ssl_open_record_t ssl_open_change_cipher_spec(SSL *ssl, size_t *out_consumed, + uint8_t *out_alert, + Span in); + +// ssl_open_app_data processes a record from |in| for reading application data. +// On success, it returns |ssl_open_record_success| and sets |*out| to the +// input. If it encounters a post-handshake message, it returns +// |ssl_open_record_discard|. The caller should then retry, after processing any +// messages received with |get_message|. +ssl_open_record_t ssl_open_app_data(SSL *ssl, Span *out, + size_t *out_consumed, uint8_t *out_alert, + Span in); + +// ssl_crypto_x509_method provides the |SSL_X509_METHOD| functions using +// crypto/x509. +extern const SSL_X509_METHOD ssl_crypto_x509_method; + +// ssl_noop_x509_method provides the |SSL_X509_METHOD| functions that avoid +// crypto/x509. +extern const SSL_X509_METHOD ssl_noop_x509_method; + +// ssl_cipher_preference_list_st contains a list of SSL_CIPHERs with +// equal-preference groups. For TLS clients, the groups are moot because the +// server picks the cipher and groups cannot be expressed on the wire. However, +// for servers, the equal-preference groups allow the client's preferences to +// be partially respected. (This only has an effect with +// SSL_OP_CIPHER_SERVER_PREFERENCE). +// +// The equal-preference groups are expressed by grouping SSL_CIPHERs together. +// All elements of a group have the same priority: no ordering is expressed +// within a group. +// +// The values in |ciphers| are in one-to-one correspondence with +// |in_group_flags|. (That is, sk_SSL_CIPHER_num(ciphers) is the number of +// bytes in |in_group_flags|.) The bytes in |in_group_flags| are either 1, to +// indicate that the corresponding SSL_CIPHER is not the last element of a +// group, or 0 to indicate that it is. +// +// For example, if |in_group_flags| contains all zeros then that indicates a +// traditional, fully-ordered preference. Every SSL_CIPHER is the last element +// of the group (i.e. they are all in a one-element group). +// +// For a more complex example, consider: +// ciphers: A B C D E F +// in_group_flags: 1 1 0 0 1 0 +// +// That would express the following, order: +// +// A E +// B -> D -> F +// C +struct ssl_cipher_preference_list_st { + STACK_OF(SSL_CIPHER) *ciphers; + uint8_t *in_group_flags; +}; + +struct tlsext_ticket_key { + static constexpr bool kAllowUniquePtr = true; + + uint8_t name[SSL_TICKET_KEY_NAME_LEN]; + uint8_t hmac_key[16]; + uint8_t aes_key[16]; + // next_rotation_tv_sec is the time (in seconds from the epoch) when the + // current key should be superseded by a new key, or the time when a previous + // key should be dropped. If zero, then the key should not be automatically + // rotated. + uint64_t next_rotation_tv_sec; +}; + +} // namespace bssl + +DECLARE_LHASH_OF(SSL_SESSION) + +namespace bssl { + +// SSLContext backs the public |SSL_CTX| type. Due to compatibility constraints, +// it is a base class for |ssl_ctx_st|. +struct SSLContext { + const SSL_PROTOCOL_METHOD *method; + const SSL_X509_METHOD *x509_method; + + // lock is used to protect various operations on this object. + CRYPTO_MUTEX lock; + + // conf_max_version is the maximum acceptable protocol version configured by + // |SSL_CTX_set_max_proto_version|. Note this version is normalized in DTLS + // and is further constrainted by |SSL_OP_NO_*|. + uint16_t conf_max_version; + + // conf_min_version is the minimum acceptable protocol version configured by + // |SSL_CTX_set_min_proto_version|. Note this version is normalized in DTLS + // and is further constrainted by |SSL_OP_NO_*|. + uint16_t conf_min_version; + + // tls13_variant is the variant of TLS 1.3 we are using for this + // configuration. + enum tls13_variant_t tls13_variant; + + struct ssl_cipher_preference_list_st *cipher_list; + + 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; + SSL_SESSION *session_cache_head; + SSL_SESSION *session_cache_tail; + + // handshakes_since_cache_flush is the number of successful handshakes since + // the last cache flush. + int handshakes_since_cache_flush; + + // 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; + + // session_timeout is the default lifetime for new sessions in TLS 1.2 and + // earlier, in seconds. + uint32_t session_timeout; + + // session_psk_dhe_timeout is the default lifetime for new sessions in TLS + // 1.3, in seconds. + uint32_t session_psk_dhe_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)(SSL *ssl, SSL_SESSION *sess); + void (*remove_session_cb)(SSL_CTX *ctx, SSL_SESSION *sess); + SSL_SESSION *(*get_session_cb)(SSL *ssl, const uint8_t *data, int len, + int *copy); + SSL_SESSION *(*get_session_cb_legacy)(SSL *ssl, uint8_t *data, int len, + int *copy); + + CRYPTO_refcount_t references; + + // if defined, these override the X509_verify_cert() calls + int (*app_verify_callback)(X509_STORE_CTX *store_ctx, void *arg); + void *app_verify_arg; + + enum ssl_verify_result_t (*custom_verify_callback)(SSL *ssl, + uint8_t *out_alert); + + // 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 **out_x509, EVP_PKEY **out_pkey); + + // get channel id callback + void (*channel_id_cb)(SSL *ssl, EVP_PKEY **out_pkey); + + CRYPTO_EX_DATA ex_data; + + // custom_*_extensions stores any callback sets for custom extensions. Note + // that these pointers will be NULL if the stack would otherwise be empty. + STACK_OF(SSL_CUSTOM_EXTENSION) *client_custom_extensions; + STACK_OF(SSL_CUSTOM_EXTENSION) *server_custom_extensions; + + // Default values used when no per-SSL value is defined follow + + void (*info_callback)(const SSL *ssl, int type, int value); + + // what we put in client cert requests + STACK_OF(CRYPTO_BUFFER) *client_CA; + + // cached_x509_client_CA is a cache of parsed versions of the elements of + // |client_CA|. + STACK_OF(X509_NAME) *cached_x509_client_CA; + + + // Default values to use in SSL structures follow (these are copied by + // SSL_new) + + uint32_t options; + uint32_t mode; + uint32_t max_cert_list; + + CERT *cert; + + // 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; + int (*default_verify_callback)( + int ok, X509_STORE_CTX *ctx); // called 'verify_callback' in the SSL + + X509_VERIFY_PARAM *param; + + // select_certificate_cb is called before most ClientHello processing and + // before the decision whether to resume a session is made. See + // |ssl_select_cert_result_t| for details of the return values. + enum ssl_select_cert_result_t (*select_certificate_cb)( + const SSL_CLIENT_HELLO *); + + // dos_protection_cb is called once the resumption decision for a ClientHello + // has been made. It returns one to continue the handshake or zero to + // abort. + int (*dos_protection_cb) (const SSL_CLIENT_HELLO *); + + // Maximum amount of data to send in one fragment. actual record size can be + // more than this due to padding and MAC overheads. + uint16_t max_send_fragment; + + // TLS extensions servername callback + int (*tlsext_servername_callback)(SSL *, int *, void *); + void *tlsext_servername_arg; + + // RFC 4507 session ticket keys. |tlsext_ticket_key_current| may be NULL + // before the first handshake and |tlsext_ticket_key_prev| may be NULL at any + // time. Automatically generated ticket keys are rotated as needed at + // handshake time. Hence, all access must be synchronized through |lock|. + struct tlsext_ticket_key *tlsext_ticket_key_current; + struct tlsext_ticket_key *tlsext_ticket_key_prev; + + // Callback to support customisation of ticket key setting + int (*tlsext_ticket_key_cb)(SSL *ssl, uint8_t *name, uint8_t *iv, + EVP_CIPHER_CTX *ectx, HMAC_CTX *hctx, int enc); + + // Server-only: psk_identity_hint is the default identity hint to send in + // PSK-based key exchanges. + char *psk_identity_hint; + + unsigned int (*psk_client_callback)(SSL *ssl, const char *hint, + char *identity, + unsigned int max_identity_len, + uint8_t *psk, unsigned int max_psk_len); + unsigned int (*psk_server_callback)(SSL *ssl, const char *identity, + uint8_t *psk, unsigned int max_psk_len); + + + // 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 *ssl, const uint8_t **out, + unsigned *out_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 *ssl, uint8_t **out, uint8_t *out_len, + const uint8_t *in, unsigned in_len, void *arg); + void *next_proto_select_cb_arg; + + // 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 *ssl, const uint8_t **out, uint8_t *out_len, + const uint8_t *in, unsigned in_len, void *arg); + void *alpn_select_cb_arg; + + // For a client, this contains the list of supported protocols in wire + // format. + uint8_t *alpn_client_proto_list; + unsigned alpn_client_proto_list_len; + + // SRTP profiles we are willing to do from RFC 5764 + STACK_OF(SRTP_PROTECTION_PROFILE) *srtp_profiles; + + // Supported group values inherited by SSL structure + size_t supported_group_list_len; + uint16_t *supported_group_list; + + // The client's Channel ID private key. + EVP_PKEY *tlsext_channel_id_private; + + // keylog_callback, if not NULL, is the key logging callback. See + // |SSL_CTX_set_keylog_callback|. + void (*keylog_callback)(const SSL *ssl, const char *line); + + // current_time_cb, if not NULL, is the function to use to get the current + // time. It sets |*out_clock| to the current time. The |ssl| argument is + // always NULL. See |SSL_CTX_set_current_time_cb|. + void (*current_time_cb)(const SSL *ssl, struct timeval *out_clock); + + // pool is used for all |CRYPTO_BUFFER|s in case we wish to share certificate + // memory. + CRYPTO_BUFFER_POOL *pool; + + // ticket_aead_method contains function pointers for opening and sealing + // session tickets. + const SSL_TICKET_AEAD_METHOD *ticket_aead_method; + + // verify_sigalgs, if not empty, is the set of signature algorithms + // accepted from the peer in decreasing order of preference. + uint16_t *verify_sigalgs; + size_t num_verify_sigalgs; + + // retain_only_sha256_of_client_certs is true if we should compute the SHA256 + // hash of the peer's certificate and then discard it to save memory and + // session space. Only effective on the server side. + bool retain_only_sha256_of_client_certs:1; + + // quiet_shutdown is true if the connection should not send a close_notify on + // shutdown. + bool quiet_shutdown:1; + + // ocsp_stapling_enabled is only used by client connections and indicates + // whether OCSP stapling will be requested. + bool ocsp_stapling_enabled:1; + + // If true, a client will request certificate timestamps. + bool signed_cert_timestamps_enabled:1; + + // tlsext_channel_id_enabled is whether Channel ID is enabled. For a server, + // means that we'll accept Channel IDs from clients. For a client, means that + // we'll advertise support. + bool tlsext_channel_id_enabled:1; + + // grease_enabled is whether draft-davidben-tls-grease-01 is enabled. + bool grease_enabled:1; + + // allow_unknown_alpn_protos is whether the client allows unsolicited ALPN + // protocols from the peer. + bool allow_unknown_alpn_protos:1; + + // ed25519_enabled is whether Ed25519 is advertised in the handshake. + bool ed25519_enabled:1; + + // false_start_allowed_without_alpn is whether False Start (if + // |SSL_MODE_ENABLE_FALSE_START| is enabled) is allowed without ALPN. + bool false_start_allowed_without_alpn:1; + + // handoff indicates that a server should stop after receiving the + // ClientHello and pause the handshake in such a way that |SSL_get_error| + // returns |SSL_HANDOFF|. + bool handoff:1; +}; + +// An ssl_shutdown_t describes the shutdown state of one end of the connection, +// whether it is alive or has been shutdown via close_notify or fatal alert. +enum ssl_shutdown_t { + ssl_shutdown_none = 0, + ssl_shutdown_close_notify = 1, + ssl_shutdown_error = 2, +}; + +struct SSL3_STATE { + static constexpr bool kAllowUniquePtr = true; + + SSL3_STATE(); + ~SSL3_STATE(); + + uint8_t read_sequence[8] = {0}; + uint8_t write_sequence[8] = {0}; + + uint8_t server_random[SSL3_RANDOM_SIZE] = {0}; + uint8_t client_random[SSL3_RANDOM_SIZE] = {0}; + + // read_buffer holds data from the transport to be processed. + SSLBuffer read_buffer; + // write_buffer holds data to be written to the transport. + SSLBuffer write_buffer; + + // pending_app_data is the unconsumed application data. It points into + // |read_buffer|. + Span pending_app_data; + + // partial write - check the numbers match + unsigned int wnum = 0; // number of bytes sent so far + int wpend_tot = 0; // number bytes written + int wpend_type = 0; + int wpend_ret = 0; // number of bytes submitted + const uint8_t *wpend_buf = nullptr; + + // read_shutdown is the shutdown state for the read half of the connection. + enum ssl_shutdown_t read_shutdown = ssl_shutdown_none; + + // write_shutdown is the shutdown state for the write half of the connection. + enum ssl_shutdown_t write_shutdown = ssl_shutdown_none; + + // read_error, if |read_shutdown| is |ssl_shutdown_error|, is the error for + // the receive half of the connection. + UniquePtr read_error; + + int alert_dispatch = 0; + + int total_renegotiations = 0; + + // 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 = SSL_NOTHING; + + // early_data_skipped is the amount of early data that has been skipped by the + // record layer. + uint16_t early_data_skipped = 0; + + // empty_record_count is the number of consecutive empty records received. + uint8_t empty_record_count = 0; + + // warning_alert_count is the number of consecutive warning alerts + // received. + uint8_t warning_alert_count = 0; + + // key_update_count is the number of consecutive KeyUpdates received. + uint8_t key_update_count = 0; + + // skip_early_data instructs the record layer to skip unexpected early data + // messages when 0RTT is rejected. + bool skip_early_data:1; + + // have_version is true if the connection's final version is known. Otherwise + // the version has not been negotiated yet. + bool have_version:1; + + // v2_hello_done is true if the peer's V2ClientHello, if any, has been handled + // and future messages should use the record layer. + bool v2_hello_done:1; + + // is_v2_hello is true if the current handshake message was derived from a + // V2ClientHello rather than received from the peer directly. + bool is_v2_hello:1; + + // has_message is true if the current handshake message has been returned + // at least once by |get_message| and false otherwise. + bool has_message:1; + + // initial_handshake_complete is true if the initial handshake has + // completed. + bool initial_handshake_complete:1; + + // session_reused indicates whether a session was resumed. + bool session_reused:1; + + bool send_connection_binding:1; + + // In a client, this means that the server supported Channel ID and that a + // Channel ID was sent. In a server it means that we echoed support for + // Channel IDs and that tlsext_channel_id will be valid after the + // handshake. + bool tlsext_channel_id_valid:1; + + // key_update_pending is true if we have a KeyUpdate acknowledgment + // outstanding. + bool key_update_pending:1; + + // wpend_pending is true if we have a pending write outstanding. + bool wpend_pending:1; + + // early_data_accepted is true if early data was accepted by the server. + bool early_data_accepted:1; + + // draft_downgrade is whether the TLS 1.3 anti-downgrade logic would have + // fired, were it not a draft. + bool draft_downgrade:1; + + // hs_buf is the buffer of handshake data to process. + UniquePtr hs_buf; + + // pending_flight is the pending outgoing flight. This is used to flush each + // handshake flight in a single write. |write_buffer| must be written out + // before this data. + UniquePtr pending_flight; + + // pending_flight_offset is the number of bytes of |pending_flight| which have + // been successfully written. + uint32_t pending_flight_offset = 0; + + // ticket_age_skew is the difference, in seconds, between the client-sent + // ticket age and the server-computed value in TLS 1.3 server connections + // which resumed a session. + int32_t ticket_age_skew = 0; + + // aead_read_ctx is the current read cipher state. + UniquePtr aead_read_ctx; + + // aead_write_ctx is the current write cipher state. + UniquePtr aead_write_ctx; + + // hs is the handshake state for the current handshake or NULL if there isn't + // one. + UniquePtr hs; + + uint8_t write_traffic_secret[EVP_MAX_MD_SIZE] = {0}; + uint8_t read_traffic_secret[EVP_MAX_MD_SIZE] = {0}; + uint8_t exporter_secret[EVP_MAX_MD_SIZE] = {0}; + uint8_t early_exporter_secret[EVP_MAX_MD_SIZE] = {0}; + uint8_t write_traffic_secret_len = 0; + uint8_t read_traffic_secret_len = 0; + uint8_t exporter_secret_len = 0; + uint8_t early_exporter_secret_len = 0; + + // Connection binding to prevent renegotiation attacks + uint8_t previous_client_finished[12] = {0}; + uint8_t previous_client_finished_len = 0; + uint8_t previous_server_finished_len = 0; + uint8_t previous_server_finished[12] = {0}; + + uint8_t send_alert[2] = {0}; + + // established_session is the session established by the connection. This + // session is only filled upon the completion of the handshake and is + // immutable. + UniquePtr established_session; + + // 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. + Array next_proto_negotiated; + + // 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. + Array alpn_selected; + + // hostname, on the server, is the value of the SNI extension. + UniquePtr hostname; + + // For a server: + // If |tlsext_channel_id_valid| is true, then this contains the + // verified Channel ID from the client: a P256 point, (x,y), where + // each are big-endian values. + uint8_t tlsext_channel_id[64] = {0}; + + // Contains the QUIC transport params received by the peer. + Array peer_quic_transport_params; +}; + +// lengths of messages +#define DTLS1_COOKIE_LENGTH 256 + +#define DTLS1_RT_HEADER_LENGTH 13 + +#define DTLS1_HM_HEADER_LENGTH 12 + +#define DTLS1_CCS_HEADER_LENGTH 1 + +#define DTLS1_AL_HEADER_LENGTH 2 + +struct hm_header_st { + uint8_t type; + uint32_t msg_len; + uint16_t seq; + uint32_t frag_off; + uint32_t frag_len; +}; + +// An hm_fragment is an incoming DTLS message, possibly not yet assembled. +struct hm_fragment { + static constexpr bool kAllowUniquePtr = true; + + hm_fragment() {} + hm_fragment(const hm_fragment &) = delete; + hm_fragment &operator=(const hm_fragment &) = delete; + + ~hm_fragment(); + + // type is the type of the message. + uint8_t type = 0; + // seq is the sequence number of this message. + uint16_t seq = 0; + // msg_len is the length of the message body. + uint32_t msg_len = 0; + // data is a pointer to the message, including message header. It has length + // |DTLS1_HM_HEADER_LENGTH| + |msg_len|. + uint8_t *data = nullptr; + // reassembly is a bitmask of |msg_len| bits corresponding to which parts of + // the message have been received. It is NULL if the message is complete. + uint8_t *reassembly = nullptr; +}; + +struct OPENSSL_timeval { + uint64_t tv_sec; + uint32_t tv_usec; +}; + +struct DTLS1_STATE { + static constexpr bool kAllowUniquePtr = true; + + DTLS1_STATE(); + ~DTLS1_STATE(); + + // has_change_cipher_spec is true if we have received a ChangeCipherSpec from + // the peer in this epoch. + bool has_change_cipher_spec:1; + + // outgoing_messages_complete is true if |outgoing_messages| has been + // completed by an attempt to flush it. Future calls to |add_message| and + // |add_change_cipher_spec| will start a new flight. + bool outgoing_messages_complete:1; + + // flight_has_reply is true if the current outgoing flight is complete and has + // processed at least one message. This is used to detect whether we or the + // peer sent the final flight. + bool flight_has_reply:1; + + uint8_t cookie[DTLS1_COOKIE_LENGTH] = {0}; + size_t cookie_len = 0; + + // The current data and handshake epoch. This is initially undefined, and + // starts at zero once the initial handshake is completed. + uint16_t r_epoch = 0; + uint16_t w_epoch = 0; + + // records being received in the current epoch + DTLS1_BITMAP bitmap; + + uint16_t handshake_write_seq = 0; + uint16_t handshake_read_seq = 0; + + // save last sequence number for retransmissions + uint8_t last_write_sequence[8] = {0}; + UniquePtr last_aead_write_ctx; + + // incoming_messages is a ring buffer of incoming handshake messages that have + // yet to be processed. The front of the ring buffer is message number + // |handshake_read_seq|, at position |handshake_read_seq| % + // |SSL_MAX_HANDSHAKE_FLIGHT|. + UniquePtr incoming_messages[SSL_MAX_HANDSHAKE_FLIGHT]; + + // outgoing_messages is the queue of outgoing messages from the last handshake + // flight. + DTLS_OUTGOING_MESSAGE outgoing_messages[SSL_MAX_HANDSHAKE_FLIGHT]; + uint8_t outgoing_messages_len = 0; + + // outgoing_written is the number of outgoing messages that have been + // written. + uint8_t outgoing_written = 0; + // outgoing_offset is the number of bytes of the next outgoing message have + // been written. + uint32_t outgoing_offset = 0; + + unsigned mtu = 0; // max DTLS packet size + + // num_timeouts is the number of times the retransmit timer has fired since + // the last time it was reset. + unsigned num_timeouts = 0; + + // Indicates when the last handshake msg or heartbeat sent will + // timeout. + struct OPENSSL_timeval next_timeout = {0, 0}; + + // timeout_duration_ms is the timeout duration in milliseconds. + unsigned timeout_duration_ms = 0; +}; + +// SSLConnection backs the public |SSL| type. Due to compatibility constraints, +// it is a base class for |ssl_st|. +struct SSLConnection { + // method is the method table corresponding to the current protocol (DTLS or + // TLS). + const SSL_PROTOCOL_METHOD *method; + + // version is the protocol version. + uint16_t version; + + // conf_max_version is the maximum acceptable protocol version configured by + // |SSL_set_max_proto_version|. Note this version is normalized in DTLS and is + // further constrainted by |SSL_OP_NO_*|. + uint16_t conf_max_version; + + // conf_min_version is the minimum acceptable protocol version configured by + // |SSL_set_min_proto_version|. Note this version is normalized in DTLS and is + // further constrainted by |SSL_OP_NO_*|. + uint16_t conf_min_version; + + uint16_t max_send_fragment; + + // 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 + + BIO *rbio; // used by SSL_read + BIO *wbio; // used by SSL_write + + // do_handshake runs the handshake. On completion, it returns |ssl_hs_ok|. + // Otherwise, it returns a value corresponding to what operation is needed to + // progress. + enum ssl_hs_wait_t (*do_handshake)(SSL_HANDSHAKE *hs); + + SSL3_STATE *s3; // SSLv3 variables + DTLS1_STATE *d1; // DTLSv1 variables + + // 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; + + X509_VERIFY_PARAM *param; + + // crypto + struct ssl_cipher_preference_list_st *cipher_list; + + // session info + + // This is used to hold the local certificate used (i.e. the server + // certificate for a server or the client certificate for a client). + CERT *cert; + + // initial_timeout_duration_ms is the default DTLS timeout duration in + // milliseconds. It's used to initialize the timer any time it's restarted. + unsigned initial_timeout_duration_ms; + + // tls13_variant is the variant of TLS 1.3 we are using for this + // configuration. + enum tls13_variant_t tls13_variant; + + // session is the configured session to be offered by the client. This session + // is immutable. + SSL_SESSION *session; + + int (*verify_callback)(int ok, + X509_STORE_CTX *ctx); // fail if callback returns 0 + + enum ssl_verify_result_t (*custom_verify_callback)(SSL *ssl, + uint8_t *out_alert); + + void (*info_callback)(const SSL *ssl, int type, int value); + + // Server-only: psk_identity_hint is the identity hint to send in + // PSK-based key exchanges. + char *psk_identity_hint; + + unsigned int (*psk_client_callback)(SSL *ssl, const char *hint, + char *identity, + unsigned int max_identity_len, + uint8_t *psk, unsigned int max_psk_len); + unsigned int (*psk_server_callback)(SSL *ssl, const char *identity, + uint8_t *psk, unsigned int max_psk_len); + + SSL_CTX *ctx; + + // extra application data + CRYPTO_EX_DATA ex_data; + + // for server side, keep the list of CA_dn we can use + STACK_OF(CRYPTO_BUFFER) *client_CA; + + // cached_x509_client_CA is a cache of parsed versions of the elements of + // |client_CA|. + STACK_OF(X509_NAME) *cached_x509_client_CA; + + uint32_t options; // protocol behaviour + uint32_t mode; // API behaviour + uint32_t max_cert_list; + uint16_t dummy_pq_padding_len; + char *tlsext_hostname; + size_t supported_group_list_len; + uint16_t *supported_group_list; // our list + + // session_ctx is the |SSL_CTX| used for the session cache and related + // settings. + SSL_CTX *session_ctx; + + // srtp_profiles is the list of configured SRTP protection profiles for + // DTLS-SRTP. + STACK_OF(SRTP_PROTECTION_PROFILE) *srtp_profiles; + + // srtp_profile is the selected SRTP protection profile for + // DTLS-SRTP. + const SRTP_PROTECTION_PROFILE *srtp_profile; + + // The client's Channel ID private key. + EVP_PKEY *tlsext_channel_id_private; + + // For a client, this contains the list of supported protocols in wire + // format. + uint8_t *alpn_client_proto_list; + unsigned alpn_client_proto_list_len; + + // Contains a list of supported Token Binding key parameters. + uint8_t *token_binding_params; + size_t token_binding_params_len; + + // The negotiated Token Binding key parameter. Only valid if + // |token_binding_negotiated| is set. + uint8_t negotiated_token_binding_param; + + // Contains the QUIC transport params that this endpoint will send. + uint8_t *quic_transport_params; + size_t quic_transport_params_len; + + // renegotiate_mode controls how peer renegotiation attempts are handled. + enum ssl_renegotiate_mode_t renegotiate_mode; + + // verify_mode is a bitmask of |SSL_VERIFY_*| values. + uint8_t verify_mode; + + // server is true iff the this SSL* is the server half. Note: before the SSL* + // is initialized by either SSL_set_accept_state or SSL_set_connect_state, + // the side is not determined. In this state, server is always false. + bool server:1; + + // quiet_shutdown is true if the connection should not send a close_notify on + // shutdown. + bool quiet_shutdown:1; + + // Enable signed certificate time stamps. Currently client only. + bool signed_cert_timestamps_enabled:1; + + // ocsp_stapling_enabled is only used by client connections and indicates + // whether OCSP stapling will be requested. + bool ocsp_stapling_enabled:1; + + // tlsext_channel_id_enabled is copied from the |SSL_CTX|. For a server, + // means that we'll accept Channel IDs from clients. For a client, means that + // we'll advertise support. + bool tlsext_channel_id_enabled:1; + + // token_binding_negotiated is set if Token Binding was negotiated. + bool token_binding_negotiated:1; + + // retain_only_sha256_of_client_certs is true if we should compute the SHA256 + // hash of the peer's certificate and then discard it to save memory and + // session space. Only effective on the server side. + bool retain_only_sha256_of_client_certs:1; + + // handoff indicates that a server should stop after receiving the + // ClientHello and pause the handshake in such a way that |SSL_get_error| + // returns |SSL_HANDOFF|. This is copied in |SSL_new| from the |SSL_CTX| + // element of the same name and may be cleared if the handoff is declined. + bool handoff:1; + + // did_dummy_pq_padding is only valid for a client. In that context, it is + // true iff the client observed the server echoing a dummy PQ padding + // extension. + bool did_dummy_pq_padding:1; +}; + +// From draft-ietf-tls-tls13-18, used in determining PSK modes. +#define SSL_PSK_DHE_KE 0x1 + +// From draft-ietf-tls-tls13-16, used in determining whether to respond with a +// KeyUpdate. +#define SSL_KEY_UPDATE_NOT_REQUESTED 0 +#define SSL_KEY_UPDATE_REQUESTED 1 + +// kMaxEarlyDataAccepted is the advertised number of plaintext bytes of early +// data that will be accepted. This value should be slightly below +// kMaxEarlyDataSkipped in tls_record.c, which is measured in ciphertext. +static const size_t kMaxEarlyDataAccepted = 14336; + +CERT *ssl_cert_new(const SSL_X509_METHOD *x509_method); +CERT *ssl_cert_dup(CERT *cert); +void ssl_cert_clear_certs(CERT *cert); +void ssl_cert_free(CERT *cert); +int ssl_set_cert(CERT *cert, UniquePtr buffer); +int ssl_is_key_type_supported(int key_type); +// ssl_compare_public_and_private_key returns one if |pubkey| is the public +// counterpart to |privkey|. Otherwise it returns zero and pushes a helpful +// message on the error queue. +int ssl_compare_public_and_private_key(const EVP_PKEY *pubkey, + const EVP_PKEY *privkey); +int ssl_cert_check_private_key(const CERT *cert, const EVP_PKEY *privkey); +int ssl_get_new_session(SSL_HANDSHAKE *hs, int is_server); +int ssl_encrypt_ticket(SSL *ssl, CBB *out, const SSL_SESSION *session); +int ssl_ctx_rotate_ticket_encryption_key(SSL_CTX *ctx); + +// ssl_session_new returns a newly-allocated blank |SSL_SESSION| or nullptr on +// error. +UniquePtr ssl_session_new(const SSL_X509_METHOD *x509_method); + +// SSL_SESSION_parse parses an |SSL_SESSION| from |cbs| and advances |cbs| over +// the parsed data. +UniquePtr SSL_SESSION_parse(CBS *cbs, + const SSL_X509_METHOD *x509_method, + CRYPTO_BUFFER_POOL *pool); + +// ssl_session_serialize writes |in| to |cbb| as if it were serialising a +// session for Session-ID resumption. It returns one on success and zero on +// error. +int ssl_session_serialize(const SSL_SESSION *in, CBB *cbb); + +// ssl_session_is_context_valid returns one if |session|'s session ID context +// matches the one set on |ssl| and zero otherwise. +int ssl_session_is_context_valid(const SSL *ssl, const SSL_SESSION *session); + +// ssl_session_is_time_valid returns one if |session| is still valid and zero if +// it has expired. +int ssl_session_is_time_valid(const SSL *ssl, const SSL_SESSION *session); + +// ssl_session_is_resumable returns one if |session| is resumable for |hs| and +// zero otherwise. +int ssl_session_is_resumable(const SSL_HANDSHAKE *hs, + const SSL_SESSION *session); + +// ssl_session_protocol_version returns the protocol version associated with +// |session|. Note that despite the name, this is not the same as +// |SSL_SESSION_get_protocol_version|. The latter is based on upstream's name. +uint16_t ssl_session_protocol_version(const SSL_SESSION *session); + +// ssl_session_get_digest returns the digest used in |session|. +const EVP_MD *ssl_session_get_digest(const SSL_SESSION *session); + +void ssl_set_session(SSL *ssl, SSL_SESSION *session); + +// ssl_get_prev_session looks up the previous session based on |client_hello|. +// On success, it sets |*out_session| to the session or nullptr if none was +// found. If the session could not be looked up synchronously, it returns +// |ssl_hs_pending_session| and should be called again. If a ticket could not be +// decrypted immediately it returns |ssl_hs_pending_ticket| and should also +// be called again. Otherwise, it returns |ssl_hs_error|. +enum ssl_hs_wait_t ssl_get_prev_session(SSL *ssl, + UniquePtr *out_session, + bool *out_tickets_supported, + bool *out_renew_ticket, + const SSL_CLIENT_HELLO *client_hello); + +// The following flags determine which parts of the session are duplicated. +#define SSL_SESSION_DUP_AUTH_ONLY 0x0 +#define SSL_SESSION_INCLUDE_TICKET 0x1 +#define SSL_SESSION_INCLUDE_NONAUTH 0x2 +#define SSL_SESSION_DUP_ALL \ + (SSL_SESSION_INCLUDE_TICKET | SSL_SESSION_INCLUDE_NONAUTH) + +// SSL_SESSION_dup returns a newly-allocated |SSL_SESSION| with a copy of the +// fields in |session| or nullptr on error. The new session is non-resumable and +// must be explicitly marked resumable once it has been filled in. +OPENSSL_EXPORT UniquePtr SSL_SESSION_dup(SSL_SESSION *session, + int dup_flags); + +// ssl_session_rebase_time updates |session|'s start time to the current time, +// adjusting the timeout so the expiration time is unchanged. +void ssl_session_rebase_time(SSL *ssl, SSL_SESSION *session); + +// ssl_session_renew_timeout calls |ssl_session_rebase_time| and renews +// |session|'s timeout to |timeout| (measured from the current time). The +// renewal is clamped to the session's auth_timeout. +void ssl_session_renew_timeout(SSL *ssl, SSL_SESSION *session, + uint32_t timeout); + +void ssl_cipher_preference_list_free( + struct ssl_cipher_preference_list_st *cipher_list); + +// ssl_get_cipher_preferences returns the cipher preference list for TLS 1.2 and +// below. +const struct ssl_cipher_preference_list_st *ssl_get_cipher_preferences( + const SSL *ssl); + +void ssl_update_cache(SSL_HANDSHAKE *hs, int mode); + +int ssl_send_alert(SSL *ssl, int level, int desc); +bool ssl3_get_message(SSL *ssl, SSLMessage *out); +ssl_open_record_t ssl3_open_handshake(SSL *ssl, size_t *out_consumed, + uint8_t *out_alert, Span in); +void ssl3_next_message(SSL *ssl); + +int ssl3_dispatch_alert(SSL *ssl); +ssl_open_record_t ssl3_open_app_data(SSL *ssl, Span *out, + size_t *out_consumed, uint8_t *out_alert, + Span in); +ssl_open_record_t ssl3_open_change_cipher_spec(SSL *ssl, size_t *out_consumed, + uint8_t *out_alert, + Span in); +int ssl3_write_app_data(SSL *ssl, bool *out_needs_handshake, const uint8_t *buf, + int len); + +bool ssl3_new(SSL *ssl); +void ssl3_free(SSL *ssl); + +bool ssl3_init_message(SSL *ssl, CBB *cbb, CBB *body, uint8_t type); +bool ssl3_finish_message(SSL *ssl, CBB *cbb, Array *out_msg); +bool ssl3_add_message(SSL *ssl, Array msg); +bool ssl3_add_change_cipher_spec(SSL *ssl); +bool ssl3_add_alert(SSL *ssl, uint8_t level, uint8_t desc); +int ssl3_flush_flight(SSL *ssl); + +bool dtls1_init_message(SSL *ssl, CBB *cbb, CBB *body, uint8_t type); +bool dtls1_finish_message(SSL *ssl, CBB *cbb, Array *out_msg); +bool dtls1_add_message(SSL *ssl, Array msg); +bool dtls1_add_change_cipher_spec(SSL *ssl); +bool dtls1_add_alert(SSL *ssl, uint8_t level, uint8_t desc); +int dtls1_flush_flight(SSL *ssl); + +// ssl_add_message_cbb finishes the handshake message in |cbb| and adds it to +// the pending flight. It returns true on success and false on error. +bool ssl_add_message_cbb(SSL *ssl, CBB *cbb); + +// ssl_hash_message incorporates |msg| into the handshake hash. It returns true +// on success and false on allocation failure. +bool ssl_hash_message(SSL_HANDSHAKE *hs, const SSLMessage &msg); + +ssl_open_record_t dtls1_open_app_data(SSL *ssl, Span *out, + size_t *out_consumed, uint8_t *out_alert, + Span in); +ssl_open_record_t dtls1_open_change_cipher_spec(SSL *ssl, size_t *out_consumed, + uint8_t *out_alert, + Span in); + +int dtls1_write_app_data(SSL *ssl, bool *out_needs_handshake, + const uint8_t *buf, int len); + +// dtls1_write_record sends a record. It returns one on success and <= 0 on +// error. +int dtls1_write_record(SSL *ssl, int type, const uint8_t *buf, size_t len, + enum dtls1_use_epoch_t use_epoch); + +int dtls1_retransmit_outgoing_messages(SSL *ssl); +bool dtls1_parse_fragment(CBS *cbs, struct hm_header_st *out_hdr, + CBS *out_body); +bool dtls1_check_timeout_num(SSL *ssl); + +void dtls1_start_timer(SSL *ssl); +void dtls1_stop_timer(SSL *ssl); +bool dtls1_is_timer_expired(SSL *ssl); +unsigned int dtls1_min_mtu(void); + +bool dtls1_new(SSL *ssl); +void dtls1_free(SSL *ssl); + +bool dtls1_get_message(SSL *ssl, SSLMessage *out); +ssl_open_record_t dtls1_open_handshake(SSL *ssl, size_t *out_consumed, + uint8_t *out_alert, Span in); +void dtls1_next_message(SSL *ssl); +int dtls1_dispatch_alert(SSL *ssl); + +// tls1_configure_aead configures either the read or write direction AEAD (as +// determined by |direction|) using the keys generated by the TLS KDF. The +// |key_block_cache| argument is used to store the generated key block, if +// empty. Otherwise it's assumed that the key block is already contained within +// it. Returns one on success or zero on error. +int tls1_configure_aead(SSL *ssl, evp_aead_direction_t direction, + Array *key_block_cache, + const SSL_CIPHER *cipher, + Span iv_override); + +int tls1_change_cipher_state(SSL_HANDSHAKE *hs, evp_aead_direction_t direction); +int tls1_generate_master_secret(SSL_HANDSHAKE *hs, uint8_t *out, + Span premaster); + +// tls1_get_grouplist returns the locally-configured group preference list. +Span tls1_get_grouplist(const SSL *ssl); + +// tls1_check_group_id returns one if |group_id| is consistent with +// locally-configured group preferences. +int tls1_check_group_id(const SSL *ssl, uint16_t group_id); + +// tls1_get_shared_group sets |*out_group_id| to the first preferred shared +// group between client and server preferences and returns one. If none may be +// found, it returns zero. +int tls1_get_shared_group(SSL_HANDSHAKE *hs, uint16_t *out_group_id); + +// tls1_set_curves converts the array of |ncurves| NIDs pointed to by |curves| +// into a newly allocated array of TLS group IDs. On success, the function +// returns one and writes the array to |*out_group_ids| and its size to +// |*out_group_ids_len|. Otherwise, it returns zero. +int tls1_set_curves(uint16_t **out_group_ids, size_t *out_group_ids_len, + const int *curves, size_t ncurves); + +// tls1_set_curves_list converts the string of curves pointed to by |curves| +// into a newly allocated array of TLS group IDs. On success, the function +// returns one and writes the array to |*out_group_ids| and its size to +// |*out_group_ids_len|. Otherwise, it returns zero. +int tls1_set_curves_list(uint16_t **out_group_ids, size_t *out_group_ids_len, + const char *curves); + +// ssl_add_clienthello_tlsext writes ClientHello extensions to |out|. It +// returns one on success and zero on failure. The |header_len| argument is the +// length of the ClientHello written so far and is used to compute the padding +// length. (It does not include the record header.) +int ssl_add_clienthello_tlsext(SSL_HANDSHAKE *hs, CBB *out, size_t header_len); + +int ssl_add_serverhello_tlsext(SSL_HANDSHAKE *hs, CBB *out); +int ssl_parse_clienthello_tlsext(SSL_HANDSHAKE *hs, + const SSL_CLIENT_HELLO *client_hello); +int ssl_parse_serverhello_tlsext(SSL_HANDSHAKE *hs, CBS *cbs); + +#define tlsext_tick_md EVP_sha256 + +// ssl_process_ticket processes a session ticket from the client. It returns +// one of: +// |ssl_ticket_aead_success|: |*out_session| is set to the parsed session and +// |*out_renew_ticket| is set to whether the ticket should be renewed. +// |ssl_ticket_aead_ignore_ticket|: |*out_renew_ticket| is set to whether a +// fresh ticket should be sent, but the given ticket cannot be used. +// |ssl_ticket_aead_retry|: the ticket could not be immediately decrypted. +// Retry later. +// |ssl_ticket_aead_error|: an error occured that is fatal to the connection. +enum ssl_ticket_aead_result_t ssl_process_ticket( + SSL *ssl, UniquePtr *out_session, bool *out_renew_ticket, + const uint8_t *ticket, size_t ticket_len, const uint8_t *session_id, + size_t session_id_len); + +// tls1_verify_channel_id processes |msg| as a Channel ID message, and verifies +// the signature. If the key is valid, it saves the Channel ID and returns +// one. Otherwise, it returns zero. +int tls1_verify_channel_id(SSL_HANDSHAKE *hs, const SSLMessage &msg); + +// tls1_write_channel_id generates a Channel ID message and puts the output in +// |cbb|. |ssl->tlsext_channel_id_private| must already be set before calling. +// This function returns true on success and false on error. +bool tls1_write_channel_id(SSL_HANDSHAKE *hs, CBB *cbb); + +// tls1_channel_id_hash computes the hash to be signed by Channel ID and writes +// it to |out|, which must contain at least |EVP_MAX_MD_SIZE| bytes. It returns +// one on success and zero on failure. +int tls1_channel_id_hash(SSL_HANDSHAKE *hs, uint8_t *out, size_t *out_len); + +int tls1_record_handshake_hashes_for_channel_id(SSL_HANDSHAKE *hs); + +// ssl_do_channel_id_callback checks runs |ssl->ctx->channel_id_cb| if +// necessary. It returns one on success and zero on fatal error. Note that, on +// success, |ssl->tlsext_channel_id_private| may be unset, in which case the +// operation should be retried later. +int ssl_do_channel_id_callback(SSL *ssl); + +// ssl_can_write returns one if |ssl| is allowed to write and zero otherwise. +int ssl_can_write(const SSL *ssl); + +// ssl_can_read returns one if |ssl| is allowed to read and zero otherwise. +int ssl_can_read(const SSL *ssl); + +void ssl_get_current_time(const SSL *ssl, struct OPENSSL_timeval *out_clock); +void ssl_ctx_get_current_time(const SSL_CTX *ctx, + struct OPENSSL_timeval *out_clock); + +// ssl_reset_error_state resets state for |SSL_get_error|. +void ssl_reset_error_state(SSL *ssl); + +// ssl_set_read_error sets |ssl|'s read half into an error state, saving the +// current state of the error queue. +void ssl_set_read_error(SSL* ssl); + +} // namespace bssl + + +// Opaque C types. +// +// The following types are exported to C code as public typedefs, so they must +// be defined outside of the namespace. + +// ssl_method_st backs the public |SSL_METHOD| type. It is a compatibility +// structure to support the legacy version-locked methods. +struct ssl_method_st { + // version, if non-zero, is the only protocol version acceptable to an + // SSL_CTX initialized from this method. + uint16_t version; + // method is the underlying SSL_PROTOCOL_METHOD that initializes the + // SSL_CTX. + const bssl::SSL_PROTOCOL_METHOD *method; + // x509_method contains pointers to functions that might deal with |X509| + // compatibility, or might be a no-op, depending on the application. + const SSL_X509_METHOD *x509_method; +}; + +struct ssl_x509_method_st { + // check_client_CA_list returns one if |names| is a good list of X.509 + // distinguished names and zero otherwise. This is used to ensure that we can + // reject unparsable values at handshake time when using crypto/x509. + int (*check_client_CA_list)(STACK_OF(CRYPTO_BUFFER) *names); + + // cert_clear frees and NULLs all X509 certificate-related state. + void (*cert_clear)(bssl::CERT *cert); + // cert_free frees all X509-related state. + void (*cert_free)(bssl::CERT *cert); + // cert_flush_cached_chain drops any cached |X509|-based certificate chain + // from |cert|. + // cert_dup duplicates any needed fields from |cert| to |new_cert|. + void (*cert_dup)(bssl::CERT *new_cert, const bssl::CERT *cert); + void (*cert_flush_cached_chain)(bssl::CERT *cert); + // cert_flush_cached_chain drops any cached |X509|-based leaf certificate + // from |cert|. + void (*cert_flush_cached_leaf)(bssl::CERT *cert); + + // session_cache_objects fills out |sess->x509_peer| and |sess->x509_chain| + // from |sess->certs| and erases |sess->x509_chain_without_leaf|. It returns + // one on success or zero on error. + int (*session_cache_objects)(SSL_SESSION *session); + // session_dup duplicates any needed fields from |session| to |new_session|. + // It returns one on success or zero on error. + int (*session_dup)(SSL_SESSION *new_session, const SSL_SESSION *session); + // session_clear frees any X509-related state from |session|. + void (*session_clear)(SSL_SESSION *session); + // session_verify_cert_chain verifies the certificate chain in |session|, + // sets |session->verify_result| and returns one on success or zero on + // error. + int (*session_verify_cert_chain)(SSL_SESSION *session, SSL *ssl, + uint8_t *out_alert); + + // hs_flush_cached_ca_names drops any cached |X509_NAME|s from |hs|. + void (*hs_flush_cached_ca_names)(bssl::SSL_HANDSHAKE *hs); + // ssl_new does any neccessary initialisation of |ssl|. It returns one on + // success or zero on error. + int (*ssl_new)(SSL *ssl); + // ssl_free frees anything created by |ssl_new|. + void (*ssl_free)(SSL *ssl); + // ssl_flush_cached_client_CA drops any cached |X509_NAME|s from |ssl|. + void (*ssl_flush_cached_client_CA)(SSL *ssl); + // ssl_auto_chain_if_needed runs the deprecated auto-chaining logic if + // necessary. On success, it updates |ssl|'s certificate configuration as + // needed and returns one. Otherwise, it returns zero. + int (*ssl_auto_chain_if_needed)(SSL *ssl); + // ssl_ctx_new does any neccessary initialisation of |ctx|. It returns one on + // success or zero on error. + int (*ssl_ctx_new)(SSL_CTX *ctx); + // ssl_ctx_free frees anything created by |ssl_ctx_new|. + void (*ssl_ctx_free)(SSL_CTX *ctx); + // ssl_ctx_flush_cached_client_CA drops any cached |X509_NAME|s from |ctx|. + void (*ssl_ctx_flush_cached_client_CA)(SSL_CTX *ssl); +}; + +// The following types back public C-exposed types which must live in the global +// namespace. We use subclassing so the implementations may be C++ types with +// methods and destructor without polluting the global namespace. +struct ssl_ctx_st : public bssl::SSLContext {}; +struct ssl_st : public bssl::SSLConnection {}; + + +#endif // OPENSSL_HEADER_SSL_INTERNAL_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/ssl/s3_both.cc b/FoodApp/Pods/BoringSSL-GRPC/ssl/s3_both.cc new file mode 100644 index 0000000..8c4ed70 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/ssl/s3_both.cc @@ -0,0 +1,585 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../crypto/internal.h" +#include "internal.h" + + +namespace bssl { + +static bool add_record_to_flight(SSL *ssl, uint8_t type, + Span in) { + // We'll never add a flight while in the process of writing it out. + assert(ssl->s3->pending_flight_offset == 0); + + if (ssl->s3->pending_flight == nullptr) { + ssl->s3->pending_flight.reset(BUF_MEM_new()); + if (ssl->s3->pending_flight == nullptr) { + return false; + } + } + + size_t max_out = in.size() + SSL_max_seal_overhead(ssl); + size_t new_cap = ssl->s3->pending_flight->length + max_out; + if (max_out < in.size() || new_cap < max_out) { + OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW); + return false; + } + + size_t len; + if (!BUF_MEM_reserve(ssl->s3->pending_flight.get(), new_cap) || + !tls_seal_record(ssl, + (uint8_t *)ssl->s3->pending_flight->data + + ssl->s3->pending_flight->length, + &len, max_out, type, in.data(), in.size())) { + return false; + } + + ssl->s3->pending_flight->length += len; + return true; +} + +bool ssl3_init_message(SSL *ssl, CBB *cbb, CBB *body, uint8_t type) { + // Pick a modest size hint to save most of the |realloc| calls. + if (!CBB_init(cbb, 64) || + !CBB_add_u8(cbb, type) || + !CBB_add_u24_length_prefixed(cbb, body)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + CBB_cleanup(cbb); + return false; + } + + return true; +} + +bool ssl3_finish_message(SSL *ssl, CBB *cbb, Array *out_msg) { + return CBBFinishArray(cbb, out_msg); +} + +bool ssl3_add_message(SSL *ssl, Array msg) { + // Add the message to the current flight, splitting into several records if + // needed. + Span rest = msg; + do { + Span chunk = rest.subspan(0, ssl->max_send_fragment); + rest = rest.subspan(chunk.size()); + + if (!add_record_to_flight(ssl, SSL3_RT_HANDSHAKE, chunk)) { + return false; + } + } while (!rest.empty()); + + ssl_do_msg_callback(ssl, 1 /* write */, SSL3_RT_HANDSHAKE, msg); + // TODO(svaldez): Move this up a layer to fix abstraction for SSLTranscript on + // hs. + if (ssl->s3->hs != NULL && + !ssl->s3->hs->transcript.Update(msg)) { + return false; + } + return true; +} + +bool ssl3_add_change_cipher_spec(SSL *ssl) { + static const uint8_t kChangeCipherSpec[1] = {SSL3_MT_CCS}; + + if (!add_record_to_flight(ssl, SSL3_RT_CHANGE_CIPHER_SPEC, + kChangeCipherSpec)) { + return false; + } + + ssl_do_msg_callback(ssl, 1 /* write */, SSL3_RT_CHANGE_CIPHER_SPEC, + kChangeCipherSpec); + return true; +} + +bool ssl3_add_alert(SSL *ssl, uint8_t level, uint8_t desc) { + uint8_t alert[2] = {level, desc}; + if (!add_record_to_flight(ssl, SSL3_RT_ALERT, alert)) { + return false; + } + + ssl_do_msg_callback(ssl, 1 /* write */, SSL3_RT_ALERT, alert); + ssl_do_info_callback(ssl, SSL_CB_WRITE_ALERT, ((int)level << 8) | desc); + return true; +} + +int ssl3_flush_flight(SSL *ssl) { + if (ssl->s3->pending_flight == nullptr) { + return 1; + } + + if (ssl->s3->write_shutdown != ssl_shutdown_none) { + OPENSSL_PUT_ERROR(SSL, SSL_R_PROTOCOL_IS_SHUTDOWN); + return -1; + } + + static_assert(INT_MAX <= 0xffffffff, "int is larger than 32 bits"); + if (ssl->s3->pending_flight->length > INT_MAX) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return -1; + } + + // If there is pending data in the write buffer, it must be flushed out before + // any new data in pending_flight. + if (!ssl->s3->write_buffer.empty()) { + int ret = ssl_write_buffer_flush(ssl); + if (ret <= 0) { + ssl->s3->rwstate = SSL_WRITING; + return ret; + } + } + + // Write the pending flight. + while (ssl->s3->pending_flight_offset < ssl->s3->pending_flight->length) { + int ret = BIO_write( + ssl->wbio, + ssl->s3->pending_flight->data + ssl->s3->pending_flight_offset, + ssl->s3->pending_flight->length - ssl->s3->pending_flight_offset); + if (ret <= 0) { + ssl->s3->rwstate = SSL_WRITING; + return ret; + } + + ssl->s3->pending_flight_offset += ret; + } + + if (BIO_flush(ssl->wbio) <= 0) { + ssl->s3->rwstate = SSL_WRITING; + return -1; + } + + ssl->s3->pending_flight.reset(); + ssl->s3->pending_flight_offset = 0; + return 1; +} + +static ssl_open_record_t read_v2_client_hello(SSL *ssl, size_t *out_consumed, + Span in) { + *out_consumed = 0; + assert(in.size() >= SSL3_RT_HEADER_LENGTH); + // Determine the length of the V2ClientHello. + size_t msg_length = ((in[0] & 0x7f) << 8) | in[1]; + if (msg_length > (1024 * 4)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_RECORD_TOO_LARGE); + return ssl_open_record_error; + } + if (msg_length < SSL3_RT_HEADER_LENGTH - 2) { + // Reject lengths that are too short early. We have already read + // |SSL3_RT_HEADER_LENGTH| bytes, so we should not attempt to process an + // (invalid) V2ClientHello which would be shorter than that. + OPENSSL_PUT_ERROR(SSL, SSL_R_RECORD_LENGTH_MISMATCH); + return ssl_open_record_error; + } + + // Ask for the remainder of the V2ClientHello. + if (in.size() < 2 + msg_length) { + *out_consumed = 2 + msg_length; + return ssl_open_record_partial; + } + + CBS v2_client_hello = CBS(ssl->s3->read_buffer.span().subspan(2, msg_length)); + // The V2ClientHello without the length is incorporated into the handshake + // hash. This is only ever called at the start of the handshake, so hs is + // guaranteed to be non-NULL. + if (!ssl->s3->hs->transcript.Update(v2_client_hello)) { + return ssl_open_record_error; + } + + ssl_do_msg_callback(ssl, 0 /* read */, 0 /* V2ClientHello */, + v2_client_hello); + + uint8_t msg_type; + uint16_t version, cipher_spec_length, session_id_length, challenge_length; + CBS cipher_specs, session_id, challenge; + if (!CBS_get_u8(&v2_client_hello, &msg_type) || + !CBS_get_u16(&v2_client_hello, &version) || + !CBS_get_u16(&v2_client_hello, &cipher_spec_length) || + !CBS_get_u16(&v2_client_hello, &session_id_length) || + !CBS_get_u16(&v2_client_hello, &challenge_length) || + !CBS_get_bytes(&v2_client_hello, &cipher_specs, cipher_spec_length) || + !CBS_get_bytes(&v2_client_hello, &session_id, session_id_length) || + !CBS_get_bytes(&v2_client_hello, &challenge, challenge_length) || + CBS_len(&v2_client_hello) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + return ssl_open_record_error; + } + + // msg_type has already been checked. + assert(msg_type == SSL2_MT_CLIENT_HELLO); + + // The client_random is the V2ClientHello challenge. Truncate or left-pad with + // zeros as needed. + size_t rand_len = CBS_len(&challenge); + if (rand_len > SSL3_RANDOM_SIZE) { + rand_len = SSL3_RANDOM_SIZE; + } + uint8_t random[SSL3_RANDOM_SIZE]; + OPENSSL_memset(random, 0, SSL3_RANDOM_SIZE); + OPENSSL_memcpy(random + (SSL3_RANDOM_SIZE - rand_len), CBS_data(&challenge), + rand_len); + + // Write out an equivalent SSLv3 ClientHello. + size_t max_v3_client_hello = SSL3_HM_HEADER_LENGTH + 2 /* version */ + + SSL3_RANDOM_SIZE + 1 /* session ID length */ + + 2 /* cipher list length */ + + CBS_len(&cipher_specs) / 3 * 2 + + 1 /* compression length */ + 1 /* compression */; + ScopedCBB client_hello; + CBB hello_body, cipher_suites; + if (!BUF_MEM_reserve(ssl->s3->hs_buf.get(), max_v3_client_hello) || + !CBB_init_fixed(client_hello.get(), (uint8_t *)ssl->s3->hs_buf->data, + ssl->s3->hs_buf->max) || + !CBB_add_u8(client_hello.get(), SSL3_MT_CLIENT_HELLO) || + !CBB_add_u24_length_prefixed(client_hello.get(), &hello_body) || + !CBB_add_u16(&hello_body, version) || + !CBB_add_bytes(&hello_body, random, SSL3_RANDOM_SIZE) || + // No session id. + !CBB_add_u8(&hello_body, 0) || + !CBB_add_u16_length_prefixed(&hello_body, &cipher_suites)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return ssl_open_record_error; + } + + // Copy the cipher suites. + while (CBS_len(&cipher_specs) > 0) { + uint32_t cipher_spec; + if (!CBS_get_u24(&cipher_specs, &cipher_spec)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + return ssl_open_record_error; + } + + // Skip SSLv2 ciphers. + if ((cipher_spec & 0xff0000) != 0) { + continue; + } + if (!CBB_add_u16(&cipher_suites, cipher_spec)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return ssl_open_record_error; + } + } + + // Add the null compression scheme and finish. + if (!CBB_add_u8(&hello_body, 1) || + !CBB_add_u8(&hello_body, 0) || + !CBB_finish(client_hello.get(), NULL, &ssl->s3->hs_buf->length)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return ssl_open_record_error; + } + + *out_consumed = 2 + msg_length; + ssl->s3->is_v2_hello = true; + return ssl_open_record_success; +} + +static bool parse_message(const SSL *ssl, SSLMessage *out, + size_t *out_bytes_needed) { + if (!ssl->s3->hs_buf) { + *out_bytes_needed = 4; + return false; + } + + CBS cbs; + uint32_t len; + CBS_init(&cbs, reinterpret_cast(ssl->s3->hs_buf->data), + ssl->s3->hs_buf->length); + if (!CBS_get_u8(&cbs, &out->type) || + !CBS_get_u24(&cbs, &len)) { + *out_bytes_needed = 4; + return false; + } + + if (!CBS_get_bytes(&cbs, &out->body, len)) { + *out_bytes_needed = 4 + len; + return false; + } + + CBS_init(&out->raw, reinterpret_cast(ssl->s3->hs_buf->data), + 4 + len); + out->is_v2_hello = ssl->s3->is_v2_hello; + return true; +} + +bool ssl3_get_message(SSL *ssl, SSLMessage *out) { + size_t unused; + if (!parse_message(ssl, out, &unused)) { + return false; + } + if (!ssl->s3->has_message) { + if (!out->is_v2_hello) { + ssl_do_msg_callback(ssl, 0 /* read */, SSL3_RT_HANDSHAKE, out->raw); + } + ssl->s3->has_message = true; + } + return true; +} + +bool tls_can_accept_handshake_data(const SSL *ssl, uint8_t *out_alert) { + // If there is a complete message, the caller must have consumed it first. + SSLMessage msg; + size_t bytes_needed; + if (parse_message(ssl, &msg, &bytes_needed)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + *out_alert = SSL_AD_INTERNAL_ERROR; + return false; + } + + // Enforce the limit so the peer cannot force us to buffer 16MB. + if (bytes_needed > 4 + ssl_max_handshake_message_len(ssl)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_EXCESSIVE_MESSAGE_SIZE); + *out_alert = SSL_AD_ILLEGAL_PARAMETER; + return false; + } + + return true; +} + +bool tls_has_unprocessed_handshake_data(const SSL *ssl) { + size_t msg_len = 0; + if (ssl->s3->has_message) { + SSLMessage msg; + size_t unused; + if (parse_message(ssl, &msg, &unused)) { + msg_len = CBS_len(&msg.raw); + } + } + + return ssl->s3->hs_buf && ssl->s3->hs_buf->length > msg_len; +} + +ssl_open_record_t ssl3_open_handshake(SSL *ssl, size_t *out_consumed, + uint8_t *out_alert, Span in) { + *out_consumed = 0; + // Re-create the handshake buffer if needed. + if (!ssl->s3->hs_buf) { + ssl->s3->hs_buf.reset(BUF_MEM_new()); + if (!ssl->s3->hs_buf) { + *out_alert = SSL_AD_INTERNAL_ERROR; + return ssl_open_record_error; + } + } + + // Bypass the record layer for the first message to handle V2ClientHello. + if (ssl->server && !ssl->s3->v2_hello_done) { + // Ask for the first 5 bytes, the size of the TLS record header. This is + // sufficient to detect a V2ClientHello and ensures that we never read + // beyond the first record. + if (in.size() < SSL3_RT_HEADER_LENGTH) { + *out_consumed = SSL3_RT_HEADER_LENGTH; + return ssl_open_record_partial; + } + + // Some dedicated error codes for protocol mixups should the application + // wish to interpret them differently. (These do not overlap with + // ClientHello or V2ClientHello.) + const char *str = reinterpret_cast(in.data()); + if (strncmp("GET ", str, 4) == 0 || + strncmp("POST ", str, 5) == 0 || + strncmp("HEAD ", str, 5) == 0 || + strncmp("PUT ", str, 4) == 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_HTTP_REQUEST); + *out_alert = 0; + return ssl_open_record_error; + } + if (strncmp("CONNE", str, 5) == 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_HTTPS_PROXY_REQUEST); + *out_alert = 0; + return ssl_open_record_error; + } + + // Check for a V2ClientHello. + if ((in[0] & 0x80) != 0 && in[2] == SSL2_MT_CLIENT_HELLO && + in[3] == SSL3_VERSION_MAJOR) { + auto ret = read_v2_client_hello(ssl, out_consumed, in); + if (ret == ssl_open_record_error) { + *out_alert = 0; + } else if (ret == ssl_open_record_success) { + ssl->s3->v2_hello_done = true; + } + return ret; + } + + ssl->s3->v2_hello_done = true; + } + + uint8_t type; + Span body; + auto ret = tls_open_record(ssl, &type, &body, out_consumed, out_alert, in); + if (ret != ssl_open_record_success) { + return ret; + } + + // WatchGuard's TLS 1.3 interference bug is very distinctive: they drop the + // ServerHello and send the remaining encrypted application data records + // as-is. This manifests as an application data record when we expect + // handshake. Report a dedicated error code for this case. + if (!ssl->server && type == SSL3_RT_APPLICATION_DATA && + ssl->s3->aead_read_ctx->is_null_cipher()) { + OPENSSL_PUT_ERROR(SSL, SSL_R_APPLICATION_DATA_INSTEAD_OF_HANDSHAKE); + *out_alert = SSL_AD_UNEXPECTED_MESSAGE; + return ssl_open_record_error; + } + + if (type != SSL3_RT_HANDSHAKE) { + OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_RECORD); + *out_alert = SSL_AD_UNEXPECTED_MESSAGE; + return ssl_open_record_error; + } + + // Append the entire handshake record to the buffer. + if (!BUF_MEM_append(ssl->s3->hs_buf.get(), body.data(), body.size())) { + *out_alert = SSL_AD_INTERNAL_ERROR; + return ssl_open_record_error; + } + + return ssl_open_record_success; +} + +void ssl3_next_message(SSL *ssl) { + SSLMessage msg; + if (!ssl3_get_message(ssl, &msg) || + !ssl->s3->hs_buf || + ssl->s3->hs_buf->length < CBS_len(&msg.raw)) { + assert(0); + return; + } + + OPENSSL_memmove(ssl->s3->hs_buf->data, + ssl->s3->hs_buf->data + CBS_len(&msg.raw), + ssl->s3->hs_buf->length - CBS_len(&msg.raw)); + ssl->s3->hs_buf->length -= CBS_len(&msg.raw); + ssl->s3->is_v2_hello = false; + ssl->s3->has_message = false; + + // Post-handshake messages are rare, so release the buffer after every + // message. During the handshake, |on_handshake_complete| will release it. + if (!SSL_in_init(ssl) && ssl->s3->hs_buf->length == 0) { + ssl->s3->hs_buf.reset(); + } +} + +} // namespace bssl diff --git a/FoodApp/Pods/BoringSSL-GRPC/ssl/s3_both.cc.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/ssl/s3_both.cc.grpc_back new file mode 100644 index 0000000..9d1218c --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/ssl/s3_both.cc.grpc_back @@ -0,0 +1,585 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../crypto/internal.h" +#include "internal.h" + + +namespace bssl { + +static bool add_record_to_flight(SSL *ssl, uint8_t type, + Span in) { + // We'll never add a flight while in the process of writing it out. + assert(ssl->s3->pending_flight_offset == 0); + + if (ssl->s3->pending_flight == nullptr) { + ssl->s3->pending_flight.reset(BUF_MEM_new()); + if (ssl->s3->pending_flight == nullptr) { + return false; + } + } + + size_t max_out = in.size() + SSL_max_seal_overhead(ssl); + size_t new_cap = ssl->s3->pending_flight->length + max_out; + if (max_out < in.size() || new_cap < max_out) { + OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW); + return false; + } + + size_t len; + if (!BUF_MEM_reserve(ssl->s3->pending_flight.get(), new_cap) || + !tls_seal_record(ssl, + (uint8_t *)ssl->s3->pending_flight->data + + ssl->s3->pending_flight->length, + &len, max_out, type, in.data(), in.size())) { + return false; + } + + ssl->s3->pending_flight->length += len; + return true; +} + +bool ssl3_init_message(SSL *ssl, CBB *cbb, CBB *body, uint8_t type) { + // Pick a modest size hint to save most of the |realloc| calls. + if (!CBB_init(cbb, 64) || + !CBB_add_u8(cbb, type) || + !CBB_add_u24_length_prefixed(cbb, body)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + CBB_cleanup(cbb); + return false; + } + + return true; +} + +bool ssl3_finish_message(SSL *ssl, CBB *cbb, Array *out_msg) { + return CBBFinishArray(cbb, out_msg); +} + +bool ssl3_add_message(SSL *ssl, Array msg) { + // Add the message to the current flight, splitting into several records if + // needed. + Span rest = msg; + do { + Span chunk = rest.subspan(0, ssl->max_send_fragment); + rest = rest.subspan(chunk.size()); + + if (!add_record_to_flight(ssl, SSL3_RT_HANDSHAKE, chunk)) { + return false; + } + } while (!rest.empty()); + + ssl_do_msg_callback(ssl, 1 /* write */, SSL3_RT_HANDSHAKE, msg); + // TODO(svaldez): Move this up a layer to fix abstraction for SSLTranscript on + // hs. + if (ssl->s3->hs != NULL && + !ssl->s3->hs->transcript.Update(msg)) { + return false; + } + return true; +} + +bool ssl3_add_change_cipher_spec(SSL *ssl) { + static const uint8_t kChangeCipherSpec[1] = {SSL3_MT_CCS}; + + if (!add_record_to_flight(ssl, SSL3_RT_CHANGE_CIPHER_SPEC, + kChangeCipherSpec)) { + return false; + } + + ssl_do_msg_callback(ssl, 1 /* write */, SSL3_RT_CHANGE_CIPHER_SPEC, + kChangeCipherSpec); + return true; +} + +bool ssl3_add_alert(SSL *ssl, uint8_t level, uint8_t desc) { + uint8_t alert[2] = {level, desc}; + if (!add_record_to_flight(ssl, SSL3_RT_ALERT, alert)) { + return false; + } + + ssl_do_msg_callback(ssl, 1 /* write */, SSL3_RT_ALERT, alert); + ssl_do_info_callback(ssl, SSL_CB_WRITE_ALERT, ((int)level << 8) | desc); + return true; +} + +int ssl3_flush_flight(SSL *ssl) { + if (ssl->s3->pending_flight == nullptr) { + return 1; + } + + if (ssl->s3->write_shutdown != ssl_shutdown_none) { + OPENSSL_PUT_ERROR(SSL, SSL_R_PROTOCOL_IS_SHUTDOWN); + return -1; + } + + static_assert(INT_MAX <= 0xffffffff, "int is larger than 32 bits"); + if (ssl->s3->pending_flight->length > INT_MAX) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return -1; + } + + // If there is pending data in the write buffer, it must be flushed out before + // any new data in pending_flight. + if (!ssl->s3->write_buffer.empty()) { + int ret = ssl_write_buffer_flush(ssl); + if (ret <= 0) { + ssl->s3->rwstate = SSL_WRITING; + return ret; + } + } + + // Write the pending flight. + while (ssl->s3->pending_flight_offset < ssl->s3->pending_flight->length) { + int ret = BIO_write( + ssl->wbio, + ssl->s3->pending_flight->data + ssl->s3->pending_flight_offset, + ssl->s3->pending_flight->length - ssl->s3->pending_flight_offset); + if (ret <= 0) { + ssl->s3->rwstate = SSL_WRITING; + return ret; + } + + ssl->s3->pending_flight_offset += ret; + } + + if (BIO_flush(ssl->wbio) <= 0) { + ssl->s3->rwstate = SSL_WRITING; + return -1; + } + + ssl->s3->pending_flight.reset(); + ssl->s3->pending_flight_offset = 0; + return 1; +} + +static ssl_open_record_t read_v2_client_hello(SSL *ssl, size_t *out_consumed, + Span in) { + *out_consumed = 0; + assert(in.size() >= SSL3_RT_HEADER_LENGTH); + // Determine the length of the V2ClientHello. + size_t msg_length = ((in[0] & 0x7f) << 8) | in[1]; + if (msg_length > (1024 * 4)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_RECORD_TOO_LARGE); + return ssl_open_record_error; + } + if (msg_length < SSL3_RT_HEADER_LENGTH - 2) { + // Reject lengths that are too short early. We have already read + // |SSL3_RT_HEADER_LENGTH| bytes, so we should not attempt to process an + // (invalid) V2ClientHello which would be shorter than that. + OPENSSL_PUT_ERROR(SSL, SSL_R_RECORD_LENGTH_MISMATCH); + return ssl_open_record_error; + } + + // Ask for the remainder of the V2ClientHello. + if (in.size() < 2 + msg_length) { + *out_consumed = 2 + msg_length; + return ssl_open_record_partial; + } + + CBS v2_client_hello = CBS(ssl->s3->read_buffer.span().subspan(2, msg_length)); + // The V2ClientHello without the length is incorporated into the handshake + // hash. This is only ever called at the start of the handshake, so hs is + // guaranteed to be non-NULL. + if (!ssl->s3->hs->transcript.Update(v2_client_hello)) { + return ssl_open_record_error; + } + + ssl_do_msg_callback(ssl, 0 /* read */, 0 /* V2ClientHello */, + v2_client_hello); + + uint8_t msg_type; + uint16_t version, cipher_spec_length, session_id_length, challenge_length; + CBS cipher_specs, session_id, challenge; + if (!CBS_get_u8(&v2_client_hello, &msg_type) || + !CBS_get_u16(&v2_client_hello, &version) || + !CBS_get_u16(&v2_client_hello, &cipher_spec_length) || + !CBS_get_u16(&v2_client_hello, &session_id_length) || + !CBS_get_u16(&v2_client_hello, &challenge_length) || + !CBS_get_bytes(&v2_client_hello, &cipher_specs, cipher_spec_length) || + !CBS_get_bytes(&v2_client_hello, &session_id, session_id_length) || + !CBS_get_bytes(&v2_client_hello, &challenge, challenge_length) || + CBS_len(&v2_client_hello) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + return ssl_open_record_error; + } + + // msg_type has already been checked. + assert(msg_type == SSL2_MT_CLIENT_HELLO); + + // The client_random is the V2ClientHello challenge. Truncate or left-pad with + // zeros as needed. + size_t rand_len = CBS_len(&challenge); + if (rand_len > SSL3_RANDOM_SIZE) { + rand_len = SSL3_RANDOM_SIZE; + } + uint8_t random[SSL3_RANDOM_SIZE]; + OPENSSL_memset(random, 0, SSL3_RANDOM_SIZE); + OPENSSL_memcpy(random + (SSL3_RANDOM_SIZE - rand_len), CBS_data(&challenge), + rand_len); + + // Write out an equivalent SSLv3 ClientHello. + size_t max_v3_client_hello = SSL3_HM_HEADER_LENGTH + 2 /* version */ + + SSL3_RANDOM_SIZE + 1 /* session ID length */ + + 2 /* cipher list length */ + + CBS_len(&cipher_specs) / 3 * 2 + + 1 /* compression length */ + 1 /* compression */; + ScopedCBB client_hello; + CBB hello_body, cipher_suites; + if (!BUF_MEM_reserve(ssl->s3->hs_buf.get(), max_v3_client_hello) || + !CBB_init_fixed(client_hello.get(), (uint8_t *)ssl->s3->hs_buf->data, + ssl->s3->hs_buf->max) || + !CBB_add_u8(client_hello.get(), SSL3_MT_CLIENT_HELLO) || + !CBB_add_u24_length_prefixed(client_hello.get(), &hello_body) || + !CBB_add_u16(&hello_body, version) || + !CBB_add_bytes(&hello_body, random, SSL3_RANDOM_SIZE) || + // No session id. + !CBB_add_u8(&hello_body, 0) || + !CBB_add_u16_length_prefixed(&hello_body, &cipher_suites)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return ssl_open_record_error; + } + + // Copy the cipher suites. + while (CBS_len(&cipher_specs) > 0) { + uint32_t cipher_spec; + if (!CBS_get_u24(&cipher_specs, &cipher_spec)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + return ssl_open_record_error; + } + + // Skip SSLv2 ciphers. + if ((cipher_spec & 0xff0000) != 0) { + continue; + } + if (!CBB_add_u16(&cipher_suites, cipher_spec)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return ssl_open_record_error; + } + } + + // Add the null compression scheme and finish. + if (!CBB_add_u8(&hello_body, 1) || + !CBB_add_u8(&hello_body, 0) || + !CBB_finish(client_hello.get(), NULL, &ssl->s3->hs_buf->length)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return ssl_open_record_error; + } + + *out_consumed = 2 + msg_length; + ssl->s3->is_v2_hello = true; + return ssl_open_record_success; +} + +static bool parse_message(const SSL *ssl, SSLMessage *out, + size_t *out_bytes_needed) { + if (!ssl->s3->hs_buf) { + *out_bytes_needed = 4; + return false; + } + + CBS cbs; + uint32_t len; + CBS_init(&cbs, reinterpret_cast(ssl->s3->hs_buf->data), + ssl->s3->hs_buf->length); + if (!CBS_get_u8(&cbs, &out->type) || + !CBS_get_u24(&cbs, &len)) { + *out_bytes_needed = 4; + return false; + } + + if (!CBS_get_bytes(&cbs, &out->body, len)) { + *out_bytes_needed = 4 + len; + return false; + } + + CBS_init(&out->raw, reinterpret_cast(ssl->s3->hs_buf->data), + 4 + len); + out->is_v2_hello = ssl->s3->is_v2_hello; + return true; +} + +bool ssl3_get_message(SSL *ssl, SSLMessage *out) { + size_t unused; + if (!parse_message(ssl, out, &unused)) { + return false; + } + if (!ssl->s3->has_message) { + if (!out->is_v2_hello) { + ssl_do_msg_callback(ssl, 0 /* read */, SSL3_RT_HANDSHAKE, out->raw); + } + ssl->s3->has_message = true; + } + return true; +} + +bool tls_can_accept_handshake_data(const SSL *ssl, uint8_t *out_alert) { + // If there is a complete message, the caller must have consumed it first. + SSLMessage msg; + size_t bytes_needed; + if (parse_message(ssl, &msg, &bytes_needed)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + *out_alert = SSL_AD_INTERNAL_ERROR; + return false; + } + + // Enforce the limit so the peer cannot force us to buffer 16MB. + if (bytes_needed > 4 + ssl_max_handshake_message_len(ssl)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_EXCESSIVE_MESSAGE_SIZE); + *out_alert = SSL_AD_ILLEGAL_PARAMETER; + return false; + } + + return true; +} + +bool tls_has_unprocessed_handshake_data(const SSL *ssl) { + size_t msg_len = 0; + if (ssl->s3->has_message) { + SSLMessage msg; + size_t unused; + if (parse_message(ssl, &msg, &unused)) { + msg_len = CBS_len(&msg.raw); + } + } + + return ssl->s3->hs_buf && ssl->s3->hs_buf->length > msg_len; +} + +ssl_open_record_t ssl3_open_handshake(SSL *ssl, size_t *out_consumed, + uint8_t *out_alert, Span in) { + *out_consumed = 0; + // Re-create the handshake buffer if needed. + if (!ssl->s3->hs_buf) { + ssl->s3->hs_buf.reset(BUF_MEM_new()); + if (!ssl->s3->hs_buf) { + *out_alert = SSL_AD_INTERNAL_ERROR; + return ssl_open_record_error; + } + } + + // Bypass the record layer for the first message to handle V2ClientHello. + if (ssl->server && !ssl->s3->v2_hello_done) { + // Ask for the first 5 bytes, the size of the TLS record header. This is + // sufficient to detect a V2ClientHello and ensures that we never read + // beyond the first record. + if (in.size() < SSL3_RT_HEADER_LENGTH) { + *out_consumed = SSL3_RT_HEADER_LENGTH; + return ssl_open_record_partial; + } + + // Some dedicated error codes for protocol mixups should the application + // wish to interpret them differently. (These do not overlap with + // ClientHello or V2ClientHello.) + const char *str = reinterpret_cast(in.data()); + if (strncmp("GET ", str, 4) == 0 || + strncmp("POST ", str, 5) == 0 || + strncmp("HEAD ", str, 5) == 0 || + strncmp("PUT ", str, 4) == 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_HTTP_REQUEST); + *out_alert = 0; + return ssl_open_record_error; + } + if (strncmp("CONNE", str, 5) == 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_HTTPS_PROXY_REQUEST); + *out_alert = 0; + return ssl_open_record_error; + } + + // Check for a V2ClientHello. + if ((in[0] & 0x80) != 0 && in[2] == SSL2_MT_CLIENT_HELLO && + in[3] == SSL3_VERSION_MAJOR) { + auto ret = read_v2_client_hello(ssl, out_consumed, in); + if (ret == ssl_open_record_error) { + *out_alert = 0; + } else if (ret == ssl_open_record_success) { + ssl->s3->v2_hello_done = true; + } + return ret; + } + + ssl->s3->v2_hello_done = true; + } + + uint8_t type; + Span body; + auto ret = tls_open_record(ssl, &type, &body, out_consumed, out_alert, in); + if (ret != ssl_open_record_success) { + return ret; + } + + // WatchGuard's TLS 1.3 interference bug is very distinctive: they drop the + // ServerHello and send the remaining encrypted application data records + // as-is. This manifests as an application data record when we expect + // handshake. Report a dedicated error code for this case. + if (!ssl->server && type == SSL3_RT_APPLICATION_DATA && + ssl->s3->aead_read_ctx->is_null_cipher()) { + OPENSSL_PUT_ERROR(SSL, SSL_R_APPLICATION_DATA_INSTEAD_OF_HANDSHAKE); + *out_alert = SSL_AD_UNEXPECTED_MESSAGE; + return ssl_open_record_error; + } + + if (type != SSL3_RT_HANDSHAKE) { + OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_RECORD); + *out_alert = SSL_AD_UNEXPECTED_MESSAGE; + return ssl_open_record_error; + } + + // Append the entire handshake record to the buffer. + if (!BUF_MEM_append(ssl->s3->hs_buf.get(), body.data(), body.size())) { + *out_alert = SSL_AD_INTERNAL_ERROR; + return ssl_open_record_error; + } + + return ssl_open_record_success; +} + +void ssl3_next_message(SSL *ssl) { + SSLMessage msg; + if (!ssl3_get_message(ssl, &msg) || + !ssl->s3->hs_buf || + ssl->s3->hs_buf->length < CBS_len(&msg.raw)) { + assert(0); + return; + } + + OPENSSL_memmove(ssl->s3->hs_buf->data, + ssl->s3->hs_buf->data + CBS_len(&msg.raw), + ssl->s3->hs_buf->length - CBS_len(&msg.raw)); + ssl->s3->hs_buf->length -= CBS_len(&msg.raw); + ssl->s3->is_v2_hello = false; + ssl->s3->has_message = false; + + // Post-handshake messages are rare, so release the buffer after every + // message. During the handshake, |on_handshake_complete| will release it. + if (!SSL_in_init(ssl) && ssl->s3->hs_buf->length == 0) { + ssl->s3->hs_buf.reset(); + } +} + +} // namespace bssl diff --git a/FoodApp/Pods/BoringSSL-GRPC/ssl/s3_lib.cc b/FoodApp/Pods/BoringSSL-GRPC/ssl/s3_lib.cc new file mode 100644 index 0000000..1f1bcc0 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/ssl/s3_lib.cc @@ -0,0 +1,226 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 +#include + +#include +#include +#include +#include +#include +#include + +#include "../crypto/internal.h" +#include "internal.h" + + +namespace bssl { + +SSL3_STATE::SSL3_STATE() + : skip_early_data(false), + have_version(false), + v2_hello_done(false), + is_v2_hello(false), + has_message(false), + initial_handshake_complete(false), + session_reused(false), + send_connection_binding(false), + tlsext_channel_id_valid(false), + key_update_pending(false), + wpend_pending(false), + early_data_accepted(false), + draft_downgrade(false) {} + +SSL3_STATE::~SSL3_STATE() {} + +bool ssl3_new(SSL *ssl) { + UniquePtr s3 = MakeUnique(); + if (!s3) { + return false; + } + + s3->aead_read_ctx = SSLAEADContext::CreateNullCipher(SSL_is_dtls(ssl)); + s3->aead_write_ctx = SSLAEADContext::CreateNullCipher(SSL_is_dtls(ssl)); + s3->hs = ssl_handshake_new(ssl); + if (!s3->aead_read_ctx || !s3->aead_write_ctx || !s3->hs) { + return false; + } + + ssl->s3 = s3.release(); + + // Set the version to the highest supported version. + // + // TODO(davidben): Move this field into |s3|, have it store the normalized + // protocol version, and implement this pre-negotiation quirk in |SSL_version| + // at the API boundary rather than in internal state. + ssl->version = TLS1_2_VERSION; + return true; +} + +void ssl3_free(SSL *ssl) { + if (ssl == NULL || ssl->s3 == NULL) { + return; + } + + Delete(ssl->s3); + ssl->s3 = NULL; +} + +const struct ssl_cipher_preference_list_st *ssl_get_cipher_preferences( + const SSL *ssl) { + if (ssl->cipher_list != NULL) { + return ssl->cipher_list; + } + + return ssl->ctx->cipher_list; +} + +} // namespace bssl diff --git a/FoodApp/Pods/BoringSSL-GRPC/ssl/s3_lib.cc.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/ssl/s3_lib.cc.grpc_back new file mode 100644 index 0000000..a3fc8d7 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/ssl/s3_lib.cc.grpc_back @@ -0,0 +1,226 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 +#include + +#include +#include +#include +#include +#include +#include + +#include "../crypto/internal.h" +#include "internal.h" + + +namespace bssl { + +SSL3_STATE::SSL3_STATE() + : skip_early_data(false), + have_version(false), + v2_hello_done(false), + is_v2_hello(false), + has_message(false), + initial_handshake_complete(false), + session_reused(false), + send_connection_binding(false), + tlsext_channel_id_valid(false), + key_update_pending(false), + wpend_pending(false), + early_data_accepted(false), + draft_downgrade(false) {} + +SSL3_STATE::~SSL3_STATE() {} + +bool ssl3_new(SSL *ssl) { + UniquePtr s3 = MakeUnique(); + if (!s3) { + return false; + } + + s3->aead_read_ctx = SSLAEADContext::CreateNullCipher(SSL_is_dtls(ssl)); + s3->aead_write_ctx = SSLAEADContext::CreateNullCipher(SSL_is_dtls(ssl)); + s3->hs = ssl_handshake_new(ssl); + if (!s3->aead_read_ctx || !s3->aead_write_ctx || !s3->hs) { + return false; + } + + ssl->s3 = s3.release(); + + // Set the version to the highest supported version. + // + // TODO(davidben): Move this field into |s3|, have it store the normalized + // protocol version, and implement this pre-negotiation quirk in |SSL_version| + // at the API boundary rather than in internal state. + ssl->version = TLS1_2_VERSION; + return true; +} + +void ssl3_free(SSL *ssl) { + if (ssl == NULL || ssl->s3 == NULL) { + return; + } + + Delete(ssl->s3); + ssl->s3 = NULL; +} + +const struct ssl_cipher_preference_list_st *ssl_get_cipher_preferences( + const SSL *ssl) { + if (ssl->cipher_list != NULL) { + return ssl->cipher_list; + } + + return ssl->ctx->cipher_list; +} + +} // namespace bssl diff --git a/FoodApp/Pods/BoringSSL-GRPC/ssl/s3_pkt.cc b/FoodApp/Pods/BoringSSL-GRPC/ssl/s3_pkt.cc new file mode 100644 index 0000000..598a4a9 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/ssl/s3_pkt.cc @@ -0,0 +1,425 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 +#include +#include + +#include +#include +#include +#include +#include + +#include "../crypto/internal.h" +#include "internal.h" + + +namespace bssl { + +static int do_ssl3_write(SSL *ssl, int type, const uint8_t *in, unsigned len); + +int ssl3_write_app_data(SSL *ssl, bool *out_needs_handshake, const uint8_t *in, + int len) { + assert(ssl_can_write(ssl)); + assert(!ssl->s3->aead_write_ctx->is_null_cipher()); + + *out_needs_handshake = false; + + if (ssl->s3->write_shutdown != ssl_shutdown_none) { + OPENSSL_PUT_ERROR(SSL, SSL_R_PROTOCOL_IS_SHUTDOWN); + return -1; + } + + unsigned tot, n, nw; + + assert(ssl->s3->wnum <= INT_MAX); + tot = ssl->s3->wnum; + ssl->s3->wnum = 0; + + // 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 < 0 || (size_t)len < tot) { + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_LENGTH); + return -1; + } + + const int is_early_data_write = + !ssl->server && SSL_in_early_data(ssl) && ssl->s3->hs->can_early_write; + + n = len - tot; + for (;;) { + // max contains the maximum number of bytes that we can put into a record. + unsigned max = ssl->max_send_fragment; + if (is_early_data_write && max > ssl->session->ticket_max_early_data - + ssl->s3->hs->early_data_written) { + max = ssl->session->ticket_max_early_data - ssl->s3->hs->early_data_written; + if (max == 0) { + ssl->s3->wnum = tot; + ssl->s3->hs->can_early_write = false; + *out_needs_handshake = true; + return -1; + } + } + + if (n > max) { + nw = max; + } else { + nw = n; + } + + int ret = do_ssl3_write(ssl, SSL3_RT_APPLICATION_DATA, &in[tot], nw); + if (ret <= 0) { + ssl->s3->wnum = tot; + return ret; + } + + if (is_early_data_write) { + ssl->s3->hs->early_data_written += ret; + } + + if (ret == (int)n || (ssl->mode & SSL_MODE_ENABLE_PARTIAL_WRITE)) { + return tot + ret; + } + + n -= ret; + tot += ret; + } +} + +static int ssl3_write_pending(SSL *ssl, int type, const uint8_t *in, + unsigned int len) { + if (ssl->s3->wpend_tot > (int)len || + (!(ssl->mode & SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER) && + ssl->s3->wpend_buf != in) || + ssl->s3->wpend_type != type) { + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_WRITE_RETRY); + return -1; + } + + int ret = ssl_write_buffer_flush(ssl); + if (ret <= 0) { + return ret; + } + ssl->s3->wpend_pending = false; + return ssl->s3->wpend_ret; +} + +// do_ssl3_write writes an SSL record of the given type. +static int do_ssl3_write(SSL *ssl, int type, const uint8_t *in, unsigned len) { + // If there is still data from the previous record, flush it. + if (ssl->s3->wpend_pending) { + return ssl3_write_pending(ssl, type, in, len); + } + + SSLBuffer *buf = &ssl->s3->write_buffer; + if (len > SSL3_RT_MAX_PLAIN_LENGTH || buf->size() > 0) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return -1; + } + + if (len == 0) { + return 0; + } + + size_t flight_len = 0; + if (ssl->s3->pending_flight != nullptr) { + flight_len = + ssl->s3->pending_flight->length - ssl->s3->pending_flight_offset; + } + + size_t max_out = len + SSL_max_seal_overhead(ssl); + if (max_out < len || max_out + flight_len < max_out) { + OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW); + return -1; + } + max_out += flight_len; + + if (!buf->EnsureCap(flight_len + ssl_seal_align_prefix_len(ssl), max_out)) { + return -1; + } + + // Add any unflushed handshake data as a prefix. This may be a KeyUpdate + // acknowledgment or 0-RTT key change messages. |pending_flight| must be clear + // when data is added to |write_buffer| or it will be written in the wrong + // order. + if (ssl->s3->pending_flight != nullptr) { + OPENSSL_memcpy( + buf->remaining().data(), + ssl->s3->pending_flight->data + ssl->s3->pending_flight_offset, + flight_len); + ssl->s3->pending_flight.reset(); + ssl->s3->pending_flight_offset = 0; + buf->DidWrite(flight_len); + } + + size_t ciphertext_len; + if (!tls_seal_record(ssl, buf->remaining().data(), &ciphertext_len, + buf->remaining().size(), type, in, len)) { + return -1; + } + buf->DidWrite(ciphertext_len); + + // Now that we've made progress on the connection, uncork KeyUpdate + // acknowledgments. + ssl->s3->key_update_pending = false; + + // Memorize arguments so that ssl3_write_pending can detect bad write retries + // later. + ssl->s3->wpend_tot = len; + ssl->s3->wpend_buf = in; + ssl->s3->wpend_type = type; + ssl->s3->wpend_ret = len; + ssl->s3->wpend_pending = true; + + // We now just need to write the buffer. + return ssl3_write_pending(ssl, type, in, len); +} + +ssl_open_record_t ssl3_open_app_data(SSL *ssl, Span *out, + size_t *out_consumed, uint8_t *out_alert, + Span in) { + assert(ssl_can_read(ssl)); + assert(!ssl->s3->aead_read_ctx->is_null_cipher()); + + uint8_t type; + Span body; + auto ret = tls_open_record(ssl, &type, &body, out_consumed, out_alert, in); + if (ret != ssl_open_record_success) { + return ret; + } + + const bool is_early_data_read = ssl->server && SSL_in_early_data(ssl); + + if (type == SSL3_RT_HANDSHAKE) { + // Post-handshake data prior to TLS 1.3 is always renegotiation, which we + // never accept as a server. Otherwise |ssl3_get_message| will send + // |SSL_R_EXCESSIVE_MESSAGE_SIZE|. + if (ssl->server && ssl_protocol_version(ssl) < TLS1_3_VERSION) { + OPENSSL_PUT_ERROR(SSL, SSL_R_NO_RENEGOTIATION); + *out_alert = SSL_AD_NO_RENEGOTIATION; + return ssl_open_record_error; + } + + if (!ssl->s3->hs_buf) { + ssl->s3->hs_buf.reset(BUF_MEM_new()); + } + if (!ssl->s3->hs_buf || + !BUF_MEM_append(ssl->s3->hs_buf.get(), body.data(), body.size())) { + *out_alert = SSL_AD_INTERNAL_ERROR; + return ssl_open_record_error; + } + return ssl_open_record_discard; + } + + if (type != SSL3_RT_APPLICATION_DATA) { + OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_RECORD); + *out_alert = SSL_AD_UNEXPECTED_MESSAGE; + return ssl_open_record_error; + } + + if (is_early_data_read) { + if (body.size() > kMaxEarlyDataAccepted - ssl->s3->hs->early_data_read) { + OPENSSL_PUT_ERROR(SSL, SSL_R_TOO_MUCH_READ_EARLY_DATA); + *out_alert = SSL3_AD_UNEXPECTED_MESSAGE; + return ssl_open_record_error; + } + + ssl->s3->hs->early_data_read += body.size(); + } + + if (body.empty()) { + return ssl_open_record_discard; + } + + *out = body; + return ssl_open_record_success; +} + +ssl_open_record_t ssl3_open_change_cipher_spec(SSL *ssl, size_t *out_consumed, + uint8_t *out_alert, + Span in) { + uint8_t type; + Span body; + auto ret = tls_open_record(ssl, &type, &body, out_consumed, out_alert, in); + if (ret != ssl_open_record_success) { + return ret; + } + + if (type != SSL3_RT_CHANGE_CIPHER_SPEC) { + OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_RECORD); + *out_alert = SSL_AD_UNEXPECTED_MESSAGE; + return ssl_open_record_error; + } + + if (body.size() != 1 || body[0] != SSL3_MT_CCS) { + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_CHANGE_CIPHER_SPEC); + *out_alert = SSL_AD_ILLEGAL_PARAMETER; + return ssl_open_record_error; + } + + ssl_do_msg_callback(ssl, 0 /* read */, SSL3_RT_CHANGE_CIPHER_SPEC, body); + return ssl_open_record_success; +} + +int ssl_send_alert(SSL *ssl, int level, int desc) { + // It is illegal to send an alert when we've already sent a closing one. + if (ssl->s3->write_shutdown != ssl_shutdown_none) { + OPENSSL_PUT_ERROR(SSL, SSL_R_PROTOCOL_IS_SHUTDOWN); + return -1; + } + + if (level == SSL3_AL_WARNING && desc == SSL_AD_CLOSE_NOTIFY) { + ssl->s3->write_shutdown = ssl_shutdown_close_notify; + } else { + assert(level == SSL3_AL_FATAL); + assert(desc != SSL_AD_CLOSE_NOTIFY); + ssl->s3->write_shutdown = ssl_shutdown_error; + } + + ssl->s3->alert_dispatch = 1; + ssl->s3->send_alert[0] = level; + ssl->s3->send_alert[1] = desc; + if (ssl->s3->write_buffer.empty()) { + // Nothing is being written out, so the alert may be dispatched + // immediately. + return ssl->method->dispatch_alert(ssl); + } + + // The alert will be dispatched later. + return -1; +} + +int ssl3_dispatch_alert(SSL *ssl) { + int ret = do_ssl3_write(ssl, SSL3_RT_ALERT, &ssl->s3->send_alert[0], 2); + if (ret <= 0) { + return ret; + } + ssl->s3->alert_dispatch = 0; + + // If the alert is fatal, flush the BIO now. + if (ssl->s3->send_alert[0] == SSL3_AL_FATAL) { + BIO_flush(ssl->wbio); + } + + ssl_do_msg_callback(ssl, 1 /* write */, SSL3_RT_ALERT, ssl->s3->send_alert); + + int alert = (ssl->s3->send_alert[0] << 8) | ssl->s3->send_alert[1]; + ssl_do_info_callback(ssl, SSL_CB_WRITE_ALERT, alert); + + return 1; +} + +} // namespace bssl diff --git a/FoodApp/Pods/BoringSSL-GRPC/ssl/s3_pkt.cc.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/ssl/s3_pkt.cc.grpc_back new file mode 100644 index 0000000..5eb68f6 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/ssl/s3_pkt.cc.grpc_back @@ -0,0 +1,425 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 +#include +#include + +#include +#include +#include +#include +#include + +#include "../crypto/internal.h" +#include "internal.h" + + +namespace bssl { + +static int do_ssl3_write(SSL *ssl, int type, const uint8_t *in, unsigned len); + +int ssl3_write_app_data(SSL *ssl, bool *out_needs_handshake, const uint8_t *in, + int len) { + assert(ssl_can_write(ssl)); + assert(!ssl->s3->aead_write_ctx->is_null_cipher()); + + *out_needs_handshake = false; + + if (ssl->s3->write_shutdown != ssl_shutdown_none) { + OPENSSL_PUT_ERROR(SSL, SSL_R_PROTOCOL_IS_SHUTDOWN); + return -1; + } + + unsigned tot, n, nw; + + assert(ssl->s3->wnum <= INT_MAX); + tot = ssl->s3->wnum; + ssl->s3->wnum = 0; + + // 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 < 0 || (size_t)len < tot) { + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_LENGTH); + return -1; + } + + const int is_early_data_write = + !ssl->server && SSL_in_early_data(ssl) && ssl->s3->hs->can_early_write; + + n = len - tot; + for (;;) { + // max contains the maximum number of bytes that we can put into a record. + unsigned max = ssl->max_send_fragment; + if (is_early_data_write && max > ssl->session->ticket_max_early_data - + ssl->s3->hs->early_data_written) { + max = ssl->session->ticket_max_early_data - ssl->s3->hs->early_data_written; + if (max == 0) { + ssl->s3->wnum = tot; + ssl->s3->hs->can_early_write = false; + *out_needs_handshake = true; + return -1; + } + } + + if (n > max) { + nw = max; + } else { + nw = n; + } + + int ret = do_ssl3_write(ssl, SSL3_RT_APPLICATION_DATA, &in[tot], nw); + if (ret <= 0) { + ssl->s3->wnum = tot; + return ret; + } + + if (is_early_data_write) { + ssl->s3->hs->early_data_written += ret; + } + + if (ret == (int)n || (ssl->mode & SSL_MODE_ENABLE_PARTIAL_WRITE)) { + return tot + ret; + } + + n -= ret; + tot += ret; + } +} + +static int ssl3_write_pending(SSL *ssl, int type, const uint8_t *in, + unsigned int len) { + if (ssl->s3->wpend_tot > (int)len || + (!(ssl->mode & SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER) && + ssl->s3->wpend_buf != in) || + ssl->s3->wpend_type != type) { + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_WRITE_RETRY); + return -1; + } + + int ret = ssl_write_buffer_flush(ssl); + if (ret <= 0) { + return ret; + } + ssl->s3->wpend_pending = false; + return ssl->s3->wpend_ret; +} + +// do_ssl3_write writes an SSL record of the given type. +static int do_ssl3_write(SSL *ssl, int type, const uint8_t *in, unsigned len) { + // If there is still data from the previous record, flush it. + if (ssl->s3->wpend_pending) { + return ssl3_write_pending(ssl, type, in, len); + } + + SSLBuffer *buf = &ssl->s3->write_buffer; + if (len > SSL3_RT_MAX_PLAIN_LENGTH || buf->size() > 0) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return -1; + } + + if (len == 0) { + return 0; + } + + size_t flight_len = 0; + if (ssl->s3->pending_flight != nullptr) { + flight_len = + ssl->s3->pending_flight->length - ssl->s3->pending_flight_offset; + } + + size_t max_out = len + SSL_max_seal_overhead(ssl); + if (max_out < len || max_out + flight_len < max_out) { + OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW); + return -1; + } + max_out += flight_len; + + if (!buf->EnsureCap(flight_len + ssl_seal_align_prefix_len(ssl), max_out)) { + return -1; + } + + // Add any unflushed handshake data as a prefix. This may be a KeyUpdate + // acknowledgment or 0-RTT key change messages. |pending_flight| must be clear + // when data is added to |write_buffer| or it will be written in the wrong + // order. + if (ssl->s3->pending_flight != nullptr) { + OPENSSL_memcpy( + buf->remaining().data(), + ssl->s3->pending_flight->data + ssl->s3->pending_flight_offset, + flight_len); + ssl->s3->pending_flight.reset(); + ssl->s3->pending_flight_offset = 0; + buf->DidWrite(flight_len); + } + + size_t ciphertext_len; + if (!tls_seal_record(ssl, buf->remaining().data(), &ciphertext_len, + buf->remaining().size(), type, in, len)) { + return -1; + } + buf->DidWrite(ciphertext_len); + + // Now that we've made progress on the connection, uncork KeyUpdate + // acknowledgments. + ssl->s3->key_update_pending = false; + + // Memorize arguments so that ssl3_write_pending can detect bad write retries + // later. + ssl->s3->wpend_tot = len; + ssl->s3->wpend_buf = in; + ssl->s3->wpend_type = type; + ssl->s3->wpend_ret = len; + ssl->s3->wpend_pending = true; + + // We now just need to write the buffer. + return ssl3_write_pending(ssl, type, in, len); +} + +ssl_open_record_t ssl3_open_app_data(SSL *ssl, Span *out, + size_t *out_consumed, uint8_t *out_alert, + Span in) { + assert(ssl_can_read(ssl)); + assert(!ssl->s3->aead_read_ctx->is_null_cipher()); + + uint8_t type; + Span body; + auto ret = tls_open_record(ssl, &type, &body, out_consumed, out_alert, in); + if (ret != ssl_open_record_success) { + return ret; + } + + const bool is_early_data_read = ssl->server && SSL_in_early_data(ssl); + + if (type == SSL3_RT_HANDSHAKE) { + // Post-handshake data prior to TLS 1.3 is always renegotiation, which we + // never accept as a server. Otherwise |ssl3_get_message| will send + // |SSL_R_EXCESSIVE_MESSAGE_SIZE|. + if (ssl->server && ssl_protocol_version(ssl) < TLS1_3_VERSION) { + OPENSSL_PUT_ERROR(SSL, SSL_R_NO_RENEGOTIATION); + *out_alert = SSL_AD_NO_RENEGOTIATION; + return ssl_open_record_error; + } + + if (!ssl->s3->hs_buf) { + ssl->s3->hs_buf.reset(BUF_MEM_new()); + } + if (!ssl->s3->hs_buf || + !BUF_MEM_append(ssl->s3->hs_buf.get(), body.data(), body.size())) { + *out_alert = SSL_AD_INTERNAL_ERROR; + return ssl_open_record_error; + } + return ssl_open_record_discard; + } + + if (type != SSL3_RT_APPLICATION_DATA) { + OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_RECORD); + *out_alert = SSL_AD_UNEXPECTED_MESSAGE; + return ssl_open_record_error; + } + + if (is_early_data_read) { + if (body.size() > kMaxEarlyDataAccepted - ssl->s3->hs->early_data_read) { + OPENSSL_PUT_ERROR(SSL, SSL_R_TOO_MUCH_READ_EARLY_DATA); + *out_alert = SSL3_AD_UNEXPECTED_MESSAGE; + return ssl_open_record_error; + } + + ssl->s3->hs->early_data_read += body.size(); + } + + if (body.empty()) { + return ssl_open_record_discard; + } + + *out = body; + return ssl_open_record_success; +} + +ssl_open_record_t ssl3_open_change_cipher_spec(SSL *ssl, size_t *out_consumed, + uint8_t *out_alert, + Span in) { + uint8_t type; + Span body; + auto ret = tls_open_record(ssl, &type, &body, out_consumed, out_alert, in); + if (ret != ssl_open_record_success) { + return ret; + } + + if (type != SSL3_RT_CHANGE_CIPHER_SPEC) { + OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_RECORD); + *out_alert = SSL_AD_UNEXPECTED_MESSAGE; + return ssl_open_record_error; + } + + if (body.size() != 1 || body[0] != SSL3_MT_CCS) { + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_CHANGE_CIPHER_SPEC); + *out_alert = SSL_AD_ILLEGAL_PARAMETER; + return ssl_open_record_error; + } + + ssl_do_msg_callback(ssl, 0 /* read */, SSL3_RT_CHANGE_CIPHER_SPEC, body); + return ssl_open_record_success; +} + +int ssl_send_alert(SSL *ssl, int level, int desc) { + // It is illegal to send an alert when we've already sent a closing one. + if (ssl->s3->write_shutdown != ssl_shutdown_none) { + OPENSSL_PUT_ERROR(SSL, SSL_R_PROTOCOL_IS_SHUTDOWN); + return -1; + } + + if (level == SSL3_AL_WARNING && desc == SSL_AD_CLOSE_NOTIFY) { + ssl->s3->write_shutdown = ssl_shutdown_close_notify; + } else { + assert(level == SSL3_AL_FATAL); + assert(desc != SSL_AD_CLOSE_NOTIFY); + ssl->s3->write_shutdown = ssl_shutdown_error; + } + + ssl->s3->alert_dispatch = 1; + ssl->s3->send_alert[0] = level; + ssl->s3->send_alert[1] = desc; + if (ssl->s3->write_buffer.empty()) { + // Nothing is being written out, so the alert may be dispatched + // immediately. + return ssl->method->dispatch_alert(ssl); + } + + // The alert will be dispatched later. + return -1; +} + +int ssl3_dispatch_alert(SSL *ssl) { + int ret = do_ssl3_write(ssl, SSL3_RT_ALERT, &ssl->s3->send_alert[0], 2); + if (ret <= 0) { + return ret; + } + ssl->s3->alert_dispatch = 0; + + // If the alert is fatal, flush the BIO now. + if (ssl->s3->send_alert[0] == SSL3_AL_FATAL) { + BIO_flush(ssl->wbio); + } + + ssl_do_msg_callback(ssl, 1 /* write */, SSL3_RT_ALERT, ssl->s3->send_alert); + + int alert = (ssl->s3->send_alert[0] << 8) | ssl->s3->send_alert[1]; + ssl_do_info_callback(ssl, SSL_CB_WRITE_ALERT, alert); + + return 1; +} + +} // namespace bssl diff --git a/FoodApp/Pods/BoringSSL-GRPC/ssl/ssl_aead_ctx.cc b/FoodApp/Pods/BoringSSL-GRPC/ssl/ssl_aead_ctx.cc new file mode 100644 index 0000000..2705bc8 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/ssl/ssl_aead_ctx.cc @@ -0,0 +1,412 @@ +/* Copyright (c) 2015, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include +#include + +#include +#include +#include + +#include "../crypto/internal.h" +#include "internal.h" + + +#if defined(BORINGSSL_UNSAFE_FUZZER_MODE) +#define FUZZER_MODE true +#else +#define FUZZER_MODE false +#endif + +namespace bssl { + +SSLAEADContext::SSLAEADContext(uint16_t version_arg, bool is_dtls_arg, + const SSL_CIPHER *cipher_arg) + : cipher_(cipher_arg), + version_(version_arg), + is_dtls_(is_dtls_arg), + variable_nonce_included_in_record_(false), + random_variable_nonce_(false), + omit_length_in_ad_(false), + omit_version_in_ad_(false), + omit_ad_(false), + xor_fixed_nonce_(false) { + OPENSSL_memset(fixed_nonce_, 0, sizeof(fixed_nonce_)); +} + +SSLAEADContext::~SSLAEADContext() {} + +UniquePtr SSLAEADContext::CreateNullCipher(bool is_dtls) { + return MakeUnique(0 /* version */, is_dtls, + nullptr /* cipher */); +} + +UniquePtr SSLAEADContext::Create( + enum evp_aead_direction_t direction, uint16_t version, int is_dtls, + const SSL_CIPHER *cipher, Span enc_key, + Span mac_key, Span fixed_iv) { + const EVP_AEAD *aead; + uint16_t protocol_version; + size_t expected_mac_key_len, expected_fixed_iv_len; + if (!ssl_protocol_version_from_wire(&protocol_version, version) || + !ssl_cipher_get_evp_aead(&aead, &expected_mac_key_len, + &expected_fixed_iv_len, cipher, protocol_version, + is_dtls) || + // Ensure the caller returned correct key sizes. + expected_fixed_iv_len != fixed_iv.size() || + expected_mac_key_len != mac_key.size()) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return nullptr; + } + + uint8_t merged_key[EVP_AEAD_MAX_KEY_LENGTH]; + if (!mac_key.empty()) { + // This is a "stateful" AEAD (for compatibility with pre-AEAD cipher + // suites). + if (mac_key.size() + enc_key.size() + fixed_iv.size() > + sizeof(merged_key)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return nullptr; + } + OPENSSL_memcpy(merged_key, mac_key.data(), mac_key.size()); + OPENSSL_memcpy(merged_key + mac_key.size(), enc_key.data(), enc_key.size()); + OPENSSL_memcpy(merged_key + mac_key.size() + enc_key.size(), + fixed_iv.data(), fixed_iv.size()); + enc_key = MakeConstSpan(merged_key, + enc_key.size() + mac_key.size() + fixed_iv.size()); + } + + UniquePtr aead_ctx = + MakeUnique(version, is_dtls, cipher); + if (!aead_ctx) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return nullptr; + } + + assert(aead_ctx->ProtocolVersion() == protocol_version); + + if (!EVP_AEAD_CTX_init_with_direction( + aead_ctx->ctx_.get(), aead, enc_key.data(), enc_key.size(), + EVP_AEAD_DEFAULT_TAG_LENGTH, direction)) { + return nullptr; + } + + assert(EVP_AEAD_nonce_length(aead) <= EVP_AEAD_MAX_NONCE_LENGTH); + static_assert(EVP_AEAD_MAX_NONCE_LENGTH < 256, + "variable_nonce_len doesn't fit in uint8_t"); + aead_ctx->variable_nonce_len_ = (uint8_t)EVP_AEAD_nonce_length(aead); + if (mac_key.empty()) { + assert(fixed_iv.size() <= sizeof(aead_ctx->fixed_nonce_)); + OPENSSL_memcpy(aead_ctx->fixed_nonce_, fixed_iv.data(), fixed_iv.size()); + aead_ctx->fixed_nonce_len_ = fixed_iv.size(); + + if (cipher->algorithm_enc & SSL_CHACHA20POLY1305) { + // The fixed nonce into the actual nonce (the sequence number). + aead_ctx->xor_fixed_nonce_ = true; + aead_ctx->variable_nonce_len_ = 8; + } else { + // The fixed IV is prepended to the nonce. + assert(fixed_iv.size() <= aead_ctx->variable_nonce_len_); + aead_ctx->variable_nonce_len_ -= fixed_iv.size(); + } + + // AES-GCM uses an explicit nonce. + if (cipher->algorithm_enc & (SSL_AES128GCM | SSL_AES256GCM)) { + aead_ctx->variable_nonce_included_in_record_ = true; + } + + // The TLS 1.3 construction XORs the fixed nonce into the sequence number + // and omits the additional data. + if (protocol_version >= TLS1_3_VERSION) { + aead_ctx->xor_fixed_nonce_ = true; + aead_ctx->variable_nonce_len_ = 8; + aead_ctx->variable_nonce_included_in_record_ = false; + aead_ctx->omit_ad_ = true; + assert(fixed_iv.size() >= aead_ctx->variable_nonce_len_); + } + } else { + assert(protocol_version < TLS1_3_VERSION); + aead_ctx->variable_nonce_included_in_record_ = true; + aead_ctx->random_variable_nonce_ = true; + aead_ctx->omit_length_in_ad_ = true; + aead_ctx->omit_version_in_ad_ = (protocol_version == SSL3_VERSION); + } + + return aead_ctx; +} + +void SSLAEADContext::SetVersionIfNullCipher(uint16_t version) { + if (is_null_cipher()) { + version_ = version; + } +} + +uint16_t SSLAEADContext::ProtocolVersion() const { + uint16_t protocol_version; + if(!ssl_protocol_version_from_wire(&protocol_version, version_)) { + assert(false); + return 0; + } + return protocol_version; +} + +uint16_t SSLAEADContext::RecordVersion() const { + if (version_ == 0) { + assert(is_null_cipher()); + return is_dtls_ ? DTLS1_VERSION : TLS1_VERSION; + } + + if (ProtocolVersion() <= TLS1_2_VERSION) { + return version_; + } + + return TLS1_2_VERSION; +} + +size_t SSLAEADContext::ExplicitNonceLen() const { + if (!FUZZER_MODE && variable_nonce_included_in_record_) { + return variable_nonce_len_; + } + return 0; +} + +bool SSLAEADContext::SuffixLen(size_t *out_suffix_len, const size_t in_len, + const size_t extra_in_len) const { + if (is_null_cipher() || FUZZER_MODE) { + *out_suffix_len = extra_in_len; + return true; + } + return !!EVP_AEAD_CTX_tag_len(ctx_.get(), out_suffix_len, in_len, + extra_in_len); +} + +size_t SSLAEADContext::MaxOverhead() const { + return ExplicitNonceLen() + + (is_null_cipher() || FUZZER_MODE + ? 0 + : EVP_AEAD_max_overhead(EVP_AEAD_CTX_aead(ctx_.get()))); +} + +size_t SSLAEADContext::GetAdditionalData(uint8_t out[13], uint8_t type, + uint16_t record_version, + const uint8_t seqnum[8], + size_t plaintext_len) { + if (omit_ad_) { + return 0; + } + + OPENSSL_memcpy(out, seqnum, 8); + size_t len = 8; + out[len++] = type; + if (!omit_version_in_ad_) { + out[len++] = static_cast((record_version >> 8)); + out[len++] = static_cast(record_version); + } + if (!omit_length_in_ad_) { + out[len++] = static_cast((plaintext_len >> 8)); + out[len++] = static_cast(plaintext_len); + } + return len; +} + +bool SSLAEADContext::Open(Span *out, uint8_t type, + uint16_t record_version, const uint8_t seqnum[8], + Span in) { + if (is_null_cipher() || FUZZER_MODE) { + // Handle the initial NULL cipher. + *out = in; + return true; + } + + // TLS 1.2 AEADs include the length in the AD and are assumed to have fixed + // overhead. Otherwise the parameter is unused. + size_t plaintext_len = 0; + if (!omit_length_in_ad_) { + size_t overhead = MaxOverhead(); + if (in.size() < overhead) { + // Publicly invalid. + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_PACKET_LENGTH); + return false; + } + plaintext_len = in.size() - overhead; + } + uint8_t ad[13]; + size_t ad_len = + GetAdditionalData(ad, type, record_version, seqnum, plaintext_len); + + // Assemble the nonce. + uint8_t nonce[EVP_AEAD_MAX_NONCE_LENGTH]; + size_t nonce_len = 0; + + // Prepend the fixed nonce, or left-pad with zeros if XORing. + if (xor_fixed_nonce_) { + nonce_len = fixed_nonce_len_ - variable_nonce_len_; + OPENSSL_memset(nonce, 0, nonce_len); + } else { + OPENSSL_memcpy(nonce, fixed_nonce_, fixed_nonce_len_); + nonce_len += fixed_nonce_len_; + } + + // Add the variable nonce. + if (variable_nonce_included_in_record_) { + if (in.size() < variable_nonce_len_) { + // Publicly invalid. + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_PACKET_LENGTH); + return false; + } + OPENSSL_memcpy(nonce + nonce_len, in.data(), variable_nonce_len_); + in = in.subspan(variable_nonce_len_); + } else { + assert(variable_nonce_len_ == 8); + OPENSSL_memcpy(nonce + nonce_len, seqnum, variable_nonce_len_); + } + nonce_len += variable_nonce_len_; + + // XOR the fixed nonce, if necessary. + if (xor_fixed_nonce_) { + assert(nonce_len == fixed_nonce_len_); + for (size_t i = 0; i < fixed_nonce_len_; i++) { + nonce[i] ^= fixed_nonce_[i]; + } + } + + // Decrypt in-place. + size_t len; + if (!EVP_AEAD_CTX_open(ctx_.get(), in.data(), &len, in.size(), nonce, + nonce_len, in.data(), in.size(), ad, ad_len)) { + return false; + } + *out = in.subspan(0, len); + return true; +} + +bool SSLAEADContext::SealScatter(uint8_t *out_prefix, uint8_t *out, + uint8_t *out_suffix, uint8_t type, + uint16_t record_version, + const uint8_t seqnum[8], const uint8_t *in, + size_t in_len, const uint8_t *extra_in, + size_t extra_in_len) { + const size_t prefix_len = ExplicitNonceLen(); + size_t suffix_len; + if (!SuffixLen(&suffix_len, in_len, extra_in_len)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_RECORD_TOO_LARGE); + return false; + } + if ((in != out && buffers_alias(in, in_len, out, in_len)) || + buffers_alias(in, in_len, out_prefix, prefix_len) || + buffers_alias(in, in_len, out_suffix, suffix_len)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_OUTPUT_ALIASES_INPUT); + return false; + } + + if (is_null_cipher() || FUZZER_MODE) { + // Handle the initial NULL cipher. + OPENSSL_memmove(out, in, in_len); + OPENSSL_memmove(out_suffix, extra_in, extra_in_len); + return true; + } + + uint8_t ad[13]; + size_t ad_len = GetAdditionalData(ad, type, record_version, seqnum, in_len); + + // Assemble the nonce. + uint8_t nonce[EVP_AEAD_MAX_NONCE_LENGTH]; + size_t nonce_len = 0; + + // Prepend the fixed nonce, or left-pad with zeros if XORing. + if (xor_fixed_nonce_) { + nonce_len = fixed_nonce_len_ - variable_nonce_len_; + OPENSSL_memset(nonce, 0, nonce_len); + } else { + OPENSSL_memcpy(nonce, fixed_nonce_, fixed_nonce_len_); + nonce_len += fixed_nonce_len_; + } + + // Select the variable nonce. + if (random_variable_nonce_) { + assert(variable_nonce_included_in_record_); + if (!RAND_bytes(nonce + nonce_len, variable_nonce_len_)) { + return false; + } + } else { + // When sending we use the sequence number as the variable part of the + // nonce. + assert(variable_nonce_len_ == 8); + OPENSSL_memcpy(nonce + nonce_len, seqnum, variable_nonce_len_); + } + nonce_len += variable_nonce_len_; + + // Emit the variable nonce if included in the record. + if (variable_nonce_included_in_record_) { + assert(!xor_fixed_nonce_); + if (buffers_alias(in, in_len, out_prefix, variable_nonce_len_)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_OUTPUT_ALIASES_INPUT); + return false; + } + OPENSSL_memcpy(out_prefix, nonce + fixed_nonce_len_, + variable_nonce_len_); + } + + // XOR the fixed nonce, if necessary. + if (xor_fixed_nonce_) { + assert(nonce_len == fixed_nonce_len_); + for (size_t i = 0; i < fixed_nonce_len_; i++) { + nonce[i] ^= fixed_nonce_[i]; + } + } + + size_t written_suffix_len; + bool result = !!EVP_AEAD_CTX_seal_scatter( + ctx_.get(), out, out_suffix, &written_suffix_len, suffix_len, nonce, + nonce_len, in, in_len, extra_in, extra_in_len, ad, ad_len); + assert(!result || written_suffix_len == suffix_len); + return result; +} + +bool SSLAEADContext::Seal(uint8_t *out, size_t *out_len, size_t max_out_len, + uint8_t type, uint16_t record_version, + const uint8_t seqnum[8], const uint8_t *in, + size_t in_len) { + const size_t prefix_len = ExplicitNonceLen(); + size_t suffix_len; + if (!SuffixLen(&suffix_len, in_len, 0)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_RECORD_TOO_LARGE); + return false; + } + if (in_len + prefix_len < in_len || + in_len + prefix_len + suffix_len < in_len + prefix_len) { + OPENSSL_PUT_ERROR(CIPHER, SSL_R_RECORD_TOO_LARGE); + return false; + } + if (in_len + prefix_len + suffix_len > max_out_len) { + OPENSSL_PUT_ERROR(SSL, SSL_R_BUFFER_TOO_SMALL); + return false; + } + + if (!SealScatter(out, out + prefix_len, out + prefix_len + in_len, type, + record_version, seqnum, in, in_len, 0, 0)) { + return false; + } + *out_len = prefix_len + in_len + suffix_len; + return true; +} + +bool SSLAEADContext::GetIV(const uint8_t **out_iv, size_t *out_iv_len) const { + return !is_null_cipher() && + EVP_AEAD_CTX_get_iv(ctx_.get(), out_iv, out_iv_len); +} + +} // namespace bssl diff --git a/FoodApp/Pods/BoringSSL-GRPC/ssl/ssl_aead_ctx.cc.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/ssl/ssl_aead_ctx.cc.grpc_back new file mode 100644 index 0000000..247e889 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/ssl/ssl_aead_ctx.cc.grpc_back @@ -0,0 +1,412 @@ +/* Copyright (c) 2015, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include +#include + +#include +#include +#include + +#include "../crypto/internal.h" +#include "internal.h" + + +#if defined(BORINGSSL_UNSAFE_FUZZER_MODE) +#define FUZZER_MODE true +#else +#define FUZZER_MODE false +#endif + +namespace bssl { + +SSLAEADContext::SSLAEADContext(uint16_t version_arg, bool is_dtls_arg, + const SSL_CIPHER *cipher_arg) + : cipher_(cipher_arg), + version_(version_arg), + is_dtls_(is_dtls_arg), + variable_nonce_included_in_record_(false), + random_variable_nonce_(false), + omit_length_in_ad_(false), + omit_version_in_ad_(false), + omit_ad_(false), + xor_fixed_nonce_(false) { + OPENSSL_memset(fixed_nonce_, 0, sizeof(fixed_nonce_)); +} + +SSLAEADContext::~SSLAEADContext() {} + +UniquePtr SSLAEADContext::CreateNullCipher(bool is_dtls) { + return MakeUnique(0 /* version */, is_dtls, + nullptr /* cipher */); +} + +UniquePtr SSLAEADContext::Create( + enum evp_aead_direction_t direction, uint16_t version, int is_dtls, + const SSL_CIPHER *cipher, Span enc_key, + Span mac_key, Span fixed_iv) { + const EVP_AEAD *aead; + uint16_t protocol_version; + size_t expected_mac_key_len, expected_fixed_iv_len; + if (!ssl_protocol_version_from_wire(&protocol_version, version) || + !ssl_cipher_get_evp_aead(&aead, &expected_mac_key_len, + &expected_fixed_iv_len, cipher, protocol_version, + is_dtls) || + // Ensure the caller returned correct key sizes. + expected_fixed_iv_len != fixed_iv.size() || + expected_mac_key_len != mac_key.size()) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return nullptr; + } + + uint8_t merged_key[EVP_AEAD_MAX_KEY_LENGTH]; + if (!mac_key.empty()) { + // This is a "stateful" AEAD (for compatibility with pre-AEAD cipher + // suites). + if (mac_key.size() + enc_key.size() + fixed_iv.size() > + sizeof(merged_key)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return nullptr; + } + OPENSSL_memcpy(merged_key, mac_key.data(), mac_key.size()); + OPENSSL_memcpy(merged_key + mac_key.size(), enc_key.data(), enc_key.size()); + OPENSSL_memcpy(merged_key + mac_key.size() + enc_key.size(), + fixed_iv.data(), fixed_iv.size()); + enc_key = MakeConstSpan(merged_key, + enc_key.size() + mac_key.size() + fixed_iv.size()); + } + + UniquePtr aead_ctx = + MakeUnique(version, is_dtls, cipher); + if (!aead_ctx) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return nullptr; + } + + assert(aead_ctx->ProtocolVersion() == protocol_version); + + if (!EVP_AEAD_CTX_init_with_direction( + aead_ctx->ctx_.get(), aead, enc_key.data(), enc_key.size(), + EVP_AEAD_DEFAULT_TAG_LENGTH, direction)) { + return nullptr; + } + + assert(EVP_AEAD_nonce_length(aead) <= EVP_AEAD_MAX_NONCE_LENGTH); + static_assert(EVP_AEAD_MAX_NONCE_LENGTH < 256, + "variable_nonce_len doesn't fit in uint8_t"); + aead_ctx->variable_nonce_len_ = (uint8_t)EVP_AEAD_nonce_length(aead); + if (mac_key.empty()) { + assert(fixed_iv.size() <= sizeof(aead_ctx->fixed_nonce_)); + OPENSSL_memcpy(aead_ctx->fixed_nonce_, fixed_iv.data(), fixed_iv.size()); + aead_ctx->fixed_nonce_len_ = fixed_iv.size(); + + if (cipher->algorithm_enc & SSL_CHACHA20POLY1305) { + // The fixed nonce into the actual nonce (the sequence number). + aead_ctx->xor_fixed_nonce_ = true; + aead_ctx->variable_nonce_len_ = 8; + } else { + // The fixed IV is prepended to the nonce. + assert(fixed_iv.size() <= aead_ctx->variable_nonce_len_); + aead_ctx->variable_nonce_len_ -= fixed_iv.size(); + } + + // AES-GCM uses an explicit nonce. + if (cipher->algorithm_enc & (SSL_AES128GCM | SSL_AES256GCM)) { + aead_ctx->variable_nonce_included_in_record_ = true; + } + + // The TLS 1.3 construction XORs the fixed nonce into the sequence number + // and omits the additional data. + if (protocol_version >= TLS1_3_VERSION) { + aead_ctx->xor_fixed_nonce_ = true; + aead_ctx->variable_nonce_len_ = 8; + aead_ctx->variable_nonce_included_in_record_ = false; + aead_ctx->omit_ad_ = true; + assert(fixed_iv.size() >= aead_ctx->variable_nonce_len_); + } + } else { + assert(protocol_version < TLS1_3_VERSION); + aead_ctx->variable_nonce_included_in_record_ = true; + aead_ctx->random_variable_nonce_ = true; + aead_ctx->omit_length_in_ad_ = true; + aead_ctx->omit_version_in_ad_ = (protocol_version == SSL3_VERSION); + } + + return aead_ctx; +} + +void SSLAEADContext::SetVersionIfNullCipher(uint16_t version) { + if (is_null_cipher()) { + version_ = version; + } +} + +uint16_t SSLAEADContext::ProtocolVersion() const { + uint16_t protocol_version; + if(!ssl_protocol_version_from_wire(&protocol_version, version_)) { + assert(false); + return 0; + } + return protocol_version; +} + +uint16_t SSLAEADContext::RecordVersion() const { + if (version_ == 0) { + assert(is_null_cipher()); + return is_dtls_ ? DTLS1_VERSION : TLS1_VERSION; + } + + if (ProtocolVersion() <= TLS1_2_VERSION) { + return version_; + } + + return TLS1_2_VERSION; +} + +size_t SSLAEADContext::ExplicitNonceLen() const { + if (!FUZZER_MODE && variable_nonce_included_in_record_) { + return variable_nonce_len_; + } + return 0; +} + +bool SSLAEADContext::SuffixLen(size_t *out_suffix_len, const size_t in_len, + const size_t extra_in_len) const { + if (is_null_cipher() || FUZZER_MODE) { + *out_suffix_len = extra_in_len; + return true; + } + return !!EVP_AEAD_CTX_tag_len(ctx_.get(), out_suffix_len, in_len, + extra_in_len); +} + +size_t SSLAEADContext::MaxOverhead() const { + return ExplicitNonceLen() + + (is_null_cipher() || FUZZER_MODE + ? 0 + : EVP_AEAD_max_overhead(EVP_AEAD_CTX_aead(ctx_.get()))); +} + +size_t SSLAEADContext::GetAdditionalData(uint8_t out[13], uint8_t type, + uint16_t record_version, + const uint8_t seqnum[8], + size_t plaintext_len) { + if (omit_ad_) { + return 0; + } + + OPENSSL_memcpy(out, seqnum, 8); + size_t len = 8; + out[len++] = type; + if (!omit_version_in_ad_) { + out[len++] = static_cast((record_version >> 8)); + out[len++] = static_cast(record_version); + } + if (!omit_length_in_ad_) { + out[len++] = static_cast((plaintext_len >> 8)); + out[len++] = static_cast(plaintext_len); + } + return len; +} + +bool SSLAEADContext::Open(Span *out, uint8_t type, + uint16_t record_version, const uint8_t seqnum[8], + Span in) { + if (is_null_cipher() || FUZZER_MODE) { + // Handle the initial NULL cipher. + *out = in; + return true; + } + + // TLS 1.2 AEADs include the length in the AD and are assumed to have fixed + // overhead. Otherwise the parameter is unused. + size_t plaintext_len = 0; + if (!omit_length_in_ad_) { + size_t overhead = MaxOverhead(); + if (in.size() < overhead) { + // Publicly invalid. + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_PACKET_LENGTH); + return false; + } + plaintext_len = in.size() - overhead; + } + uint8_t ad[13]; + size_t ad_len = + GetAdditionalData(ad, type, record_version, seqnum, plaintext_len); + + // Assemble the nonce. + uint8_t nonce[EVP_AEAD_MAX_NONCE_LENGTH]; + size_t nonce_len = 0; + + // Prepend the fixed nonce, or left-pad with zeros if XORing. + if (xor_fixed_nonce_) { + nonce_len = fixed_nonce_len_ - variable_nonce_len_; + OPENSSL_memset(nonce, 0, nonce_len); + } else { + OPENSSL_memcpy(nonce, fixed_nonce_, fixed_nonce_len_); + nonce_len += fixed_nonce_len_; + } + + // Add the variable nonce. + if (variable_nonce_included_in_record_) { + if (in.size() < variable_nonce_len_) { + // Publicly invalid. + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_PACKET_LENGTH); + return false; + } + OPENSSL_memcpy(nonce + nonce_len, in.data(), variable_nonce_len_); + in = in.subspan(variable_nonce_len_); + } else { + assert(variable_nonce_len_ == 8); + OPENSSL_memcpy(nonce + nonce_len, seqnum, variable_nonce_len_); + } + nonce_len += variable_nonce_len_; + + // XOR the fixed nonce, if necessary. + if (xor_fixed_nonce_) { + assert(nonce_len == fixed_nonce_len_); + for (size_t i = 0; i < fixed_nonce_len_; i++) { + nonce[i] ^= fixed_nonce_[i]; + } + } + + // Decrypt in-place. + size_t len; + if (!EVP_AEAD_CTX_open(ctx_.get(), in.data(), &len, in.size(), nonce, + nonce_len, in.data(), in.size(), ad, ad_len)) { + return false; + } + *out = in.subspan(0, len); + return true; +} + +bool SSLAEADContext::SealScatter(uint8_t *out_prefix, uint8_t *out, + uint8_t *out_suffix, uint8_t type, + uint16_t record_version, + const uint8_t seqnum[8], const uint8_t *in, + size_t in_len, const uint8_t *extra_in, + size_t extra_in_len) { + const size_t prefix_len = ExplicitNonceLen(); + size_t suffix_len; + if (!SuffixLen(&suffix_len, in_len, extra_in_len)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_RECORD_TOO_LARGE); + return false; + } + if ((in != out && buffers_alias(in, in_len, out, in_len)) || + buffers_alias(in, in_len, out_prefix, prefix_len) || + buffers_alias(in, in_len, out_suffix, suffix_len)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_OUTPUT_ALIASES_INPUT); + return false; + } + + if (is_null_cipher() || FUZZER_MODE) { + // Handle the initial NULL cipher. + OPENSSL_memmove(out, in, in_len); + OPENSSL_memmove(out_suffix, extra_in, extra_in_len); + return true; + } + + uint8_t ad[13]; + size_t ad_len = GetAdditionalData(ad, type, record_version, seqnum, in_len); + + // Assemble the nonce. + uint8_t nonce[EVP_AEAD_MAX_NONCE_LENGTH]; + size_t nonce_len = 0; + + // Prepend the fixed nonce, or left-pad with zeros if XORing. + if (xor_fixed_nonce_) { + nonce_len = fixed_nonce_len_ - variable_nonce_len_; + OPENSSL_memset(nonce, 0, nonce_len); + } else { + OPENSSL_memcpy(nonce, fixed_nonce_, fixed_nonce_len_); + nonce_len += fixed_nonce_len_; + } + + // Select the variable nonce. + if (random_variable_nonce_) { + assert(variable_nonce_included_in_record_); + if (!RAND_bytes(nonce + nonce_len, variable_nonce_len_)) { + return false; + } + } else { + // When sending we use the sequence number as the variable part of the + // nonce. + assert(variable_nonce_len_ == 8); + OPENSSL_memcpy(nonce + nonce_len, seqnum, variable_nonce_len_); + } + nonce_len += variable_nonce_len_; + + // Emit the variable nonce if included in the record. + if (variable_nonce_included_in_record_) { + assert(!xor_fixed_nonce_); + if (buffers_alias(in, in_len, out_prefix, variable_nonce_len_)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_OUTPUT_ALIASES_INPUT); + return false; + } + OPENSSL_memcpy(out_prefix, nonce + fixed_nonce_len_, + variable_nonce_len_); + } + + // XOR the fixed nonce, if necessary. + if (xor_fixed_nonce_) { + assert(nonce_len == fixed_nonce_len_); + for (size_t i = 0; i < fixed_nonce_len_; i++) { + nonce[i] ^= fixed_nonce_[i]; + } + } + + size_t written_suffix_len; + bool result = !!EVP_AEAD_CTX_seal_scatter( + ctx_.get(), out, out_suffix, &written_suffix_len, suffix_len, nonce, + nonce_len, in, in_len, extra_in, extra_in_len, ad, ad_len); + assert(!result || written_suffix_len == suffix_len); + return result; +} + +bool SSLAEADContext::Seal(uint8_t *out, size_t *out_len, size_t max_out_len, + uint8_t type, uint16_t record_version, + const uint8_t seqnum[8], const uint8_t *in, + size_t in_len) { + const size_t prefix_len = ExplicitNonceLen(); + size_t suffix_len; + if (!SuffixLen(&suffix_len, in_len, 0)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_RECORD_TOO_LARGE); + return false; + } + if (in_len + prefix_len < in_len || + in_len + prefix_len + suffix_len < in_len + prefix_len) { + OPENSSL_PUT_ERROR(CIPHER, SSL_R_RECORD_TOO_LARGE); + return false; + } + if (in_len + prefix_len + suffix_len > max_out_len) { + OPENSSL_PUT_ERROR(SSL, SSL_R_BUFFER_TOO_SMALL); + return false; + } + + if (!SealScatter(out, out + prefix_len, out + prefix_len + in_len, type, + record_version, seqnum, in, in_len, 0, 0)) { + return false; + } + *out_len = prefix_len + in_len + suffix_len; + return true; +} + +bool SSLAEADContext::GetIV(const uint8_t **out_iv, size_t *out_iv_len) const { + return !is_null_cipher() && + EVP_AEAD_CTX_get_iv(ctx_.get(), out_iv, out_iv_len); +} + +} // namespace bssl diff --git a/FoodApp/Pods/BoringSSL-GRPC/ssl/ssl_asn1.cc b/FoodApp/Pods/BoringSSL-GRPC/ssl/ssl_asn1.cc new file mode 100644 index 0000000..a15b510 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/ssl/ssl_asn1.cc @@ -0,0 +1,844 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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. */ + +// Per C99, various stdint.h macros are unavailable in C++ unless some macros +// are defined. C++11 overruled this decision, but older Android NDKs still +// require it. +#if !defined(__STDC_LIMIT_MACROS) +#define __STDC_LIMIT_MACROS +#endif + +#include + +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include "../crypto/internal.h" +#include "internal.h" + + +namespace bssl { + +// An SSL_SESSION is serialized as the following ASN.1 structure: +// +// SSLSession ::= SEQUENCE { +// version INTEGER (1), -- session structure version +// sslVersion INTEGER, -- protocol version number +// cipher OCTET STRING, -- two bytes long +// sessionID OCTET STRING, +// masterKey OCTET STRING, +// time [1] INTEGER, -- seconds since UNIX epoch +// timeout [2] INTEGER, -- in seconds +// peer [3] Certificate OPTIONAL, +// sessionIDContext [4] OCTET STRING OPTIONAL, +// verifyResult [5] INTEGER OPTIONAL, -- one of X509_V_* codes +// pskIdentity [8] OCTET STRING OPTIONAL, +// ticketLifetimeHint [9] INTEGER OPTIONAL, -- client-only +// ticket [10] OCTET STRING OPTIONAL, -- client-only +// peerSHA256 [13] OCTET STRING OPTIONAL, +// originalHandshakeHash [14] OCTET STRING OPTIONAL, +// signedCertTimestampList [15] OCTET STRING OPTIONAL, +// -- contents of SCT extension +// ocspResponse [16] OCTET STRING OPTIONAL, +// -- stapled OCSP response from the server +// extendedMasterSecret [17] BOOLEAN OPTIONAL, +// groupID [18] INTEGER OPTIONAL, +// certChain [19] SEQUENCE OF Certificate OPTIONAL, +// ticketAgeAdd [21] OCTET STRING OPTIONAL, +// isServer [22] BOOLEAN DEFAULT TRUE, +// peerSignatureAlgorithm [23] INTEGER OPTIONAL, +// ticketMaxEarlyData [24] INTEGER OPTIONAL, +// authTimeout [25] INTEGER OPTIONAL, -- defaults to timeout +// earlyALPN [26] OCTET STRING OPTIONAL, +// } +// +// Note: historically this serialization has included other optional +// fields. Their presence is currently treated as a parse error, except for +// hostName, which is ignored. +// +// keyArg [0] IMPLICIT OCTET STRING OPTIONAL, +// hostName [6] OCTET STRING OPTIONAL, +// pskIdentityHint [7] OCTET STRING OPTIONAL, +// compressionMethod [11] OCTET STRING OPTIONAL, +// srpUsername [12] OCTET STRING OPTIONAL, +// ticketFlags [20] INTEGER OPTIONAL, + +static const unsigned kVersion = 1; + +static const unsigned kTimeTag = + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 1; +static const unsigned kTimeoutTag = + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 2; +static const unsigned kPeerTag = + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 3; +static const unsigned kSessionIDContextTag = + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 4; +static const unsigned kVerifyResultTag = + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 5; +static const unsigned kHostNameTag = + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 6; +static const unsigned kPSKIdentityTag = + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 8; +static const unsigned kTicketLifetimeHintTag = + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 9; +static const unsigned kTicketTag = + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 10; +static const unsigned kPeerSHA256Tag = + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 13; +static const unsigned kOriginalHandshakeHashTag = + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 14; +static const unsigned kSignedCertTimestampListTag = + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 15; +static const unsigned kOCSPResponseTag = + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 16; +static const unsigned kExtendedMasterSecretTag = + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 17; +static const unsigned kGroupIDTag = + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 18; +static const unsigned kCertChainTag = + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 19; +static const unsigned kTicketAgeAddTag = + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 21; +static const unsigned kIsServerTag = + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 22; +static const unsigned kPeerSignatureAlgorithmTag = + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 23; +static const unsigned kTicketMaxEarlyDataTag = + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 24; +static const unsigned kAuthTimeoutTag = + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 25; +static const unsigned kEarlyALPNTag = + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 26; + +static int SSL_SESSION_to_bytes_full(const SSL_SESSION *in, CBB *cbb, + int for_ticket) { + if (in == NULL || in->cipher == NULL) { + return 0; + } + + CBB session, child, child2; + if (!CBB_add_asn1(cbb, &session, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1_uint64(&session, kVersion) || + !CBB_add_asn1_uint64(&session, in->ssl_version) || + !CBB_add_asn1(&session, &child, CBS_ASN1_OCTETSTRING) || + !CBB_add_u16(&child, (uint16_t)(in->cipher->id & 0xffff)) || + // The session ID is irrelevant for a session ticket. + !CBB_add_asn1_octet_string(&session, in->session_id, + for_ticket ? 0 : in->session_id_length) || + !CBB_add_asn1_octet_string(&session, in->master_key, + in->master_key_length) || + !CBB_add_asn1(&session, &child, kTimeTag) || + !CBB_add_asn1_uint64(&child, in->time) || + !CBB_add_asn1(&session, &child, kTimeoutTag) || + !CBB_add_asn1_uint64(&child, in->timeout)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + + // The peer certificate is only serialized if the SHA-256 isn't + // serialized instead. + if (sk_CRYPTO_BUFFER_num(in->certs) > 0 && !in->peer_sha256_valid) { + const CRYPTO_BUFFER *buffer = sk_CRYPTO_BUFFER_value(in->certs, 0); + if (!CBB_add_asn1(&session, &child, kPeerTag) || + !CBB_add_bytes(&child, CRYPTO_BUFFER_data(buffer), + CRYPTO_BUFFER_len(buffer))) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + } + + // Although it is OPTIONAL and usually empty, OpenSSL has + // historically always encoded the sid_ctx. + if (!CBB_add_asn1(&session, &child, kSessionIDContextTag) || + !CBB_add_asn1_octet_string(&child, in->sid_ctx, in->sid_ctx_length)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + + if (in->verify_result != X509_V_OK) { + if (!CBB_add_asn1(&session, &child, kVerifyResultTag) || + !CBB_add_asn1_uint64(&child, in->verify_result)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + } + + if (in->psk_identity) { + if (!CBB_add_asn1(&session, &child, kPSKIdentityTag) || + !CBB_add_asn1_octet_string(&child, (const uint8_t *)in->psk_identity, + strlen(in->psk_identity))) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + } + + if (in->tlsext_tick_lifetime_hint > 0) { + if (!CBB_add_asn1(&session, &child, kTicketLifetimeHintTag) || + !CBB_add_asn1_uint64(&child, in->tlsext_tick_lifetime_hint)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + } + + if (in->tlsext_tick && !for_ticket) { + if (!CBB_add_asn1(&session, &child, kTicketTag) || + !CBB_add_asn1_octet_string(&child, in->tlsext_tick, + in->tlsext_ticklen)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + } + + if (in->peer_sha256_valid) { + if (!CBB_add_asn1(&session, &child, kPeerSHA256Tag) || + !CBB_add_asn1_octet_string(&child, in->peer_sha256, + sizeof(in->peer_sha256))) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + } + + if (in->original_handshake_hash_len > 0) { + if (!CBB_add_asn1(&session, &child, kOriginalHandshakeHashTag) || + !CBB_add_asn1_octet_string(&child, in->original_handshake_hash, + in->original_handshake_hash_len)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + } + + if (in->signed_cert_timestamp_list != nullptr) { + if (!CBB_add_asn1(&session, &child, kSignedCertTimestampListTag) || + !CBB_add_asn1_octet_string( + &child, CRYPTO_BUFFER_data(in->signed_cert_timestamp_list), + CRYPTO_BUFFER_len(in->signed_cert_timestamp_list))) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + } + + if (in->ocsp_response != nullptr) { + if (!CBB_add_asn1(&session, &child, kOCSPResponseTag) || + !CBB_add_asn1_octet_string(&child, + CRYPTO_BUFFER_data(in->ocsp_response), + CRYPTO_BUFFER_len(in->ocsp_response))) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + } + + if (in->extended_master_secret) { + if (!CBB_add_asn1(&session, &child, kExtendedMasterSecretTag) || + !CBB_add_asn1_bool(&child, true)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + } + + if (in->group_id > 0 && + (!CBB_add_asn1(&session, &child, kGroupIDTag) || + !CBB_add_asn1_uint64(&child, in->group_id))) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + + // The certificate chain is only serialized if the leaf's SHA-256 isn't + // serialized instead. + if (in->certs != NULL && + !in->peer_sha256_valid && + sk_CRYPTO_BUFFER_num(in->certs) >= 2) { + if (!CBB_add_asn1(&session, &child, kCertChainTag)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + for (size_t i = 1; i < sk_CRYPTO_BUFFER_num(in->certs); i++) { + const CRYPTO_BUFFER *buffer = sk_CRYPTO_BUFFER_value(in->certs, i); + if (!CBB_add_bytes(&child, CRYPTO_BUFFER_data(buffer), + CRYPTO_BUFFER_len(buffer))) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + } + } + + if (in->ticket_age_add_valid) { + if (!CBB_add_asn1(&session, &child, kTicketAgeAddTag) || + !CBB_add_asn1(&child, &child2, CBS_ASN1_OCTETSTRING) || + !CBB_add_u32(&child2, in->ticket_age_add)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + } + + if (!in->is_server) { + if (!CBB_add_asn1(&session, &child, kIsServerTag) || + !CBB_add_asn1_bool(&child, false)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + } + + if (in->peer_signature_algorithm != 0 && + (!CBB_add_asn1(&session, &child, kPeerSignatureAlgorithmTag) || + !CBB_add_asn1_uint64(&child, in->peer_signature_algorithm))) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + + if (in->ticket_max_early_data != 0 && + (!CBB_add_asn1(&session, &child, kTicketMaxEarlyDataTag) || + !CBB_add_asn1_uint64(&child, in->ticket_max_early_data))) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + + if (in->timeout != in->auth_timeout && + (!CBB_add_asn1(&session, &child, kAuthTimeoutTag) || + !CBB_add_asn1_uint64(&child, in->auth_timeout))) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + + if (in->early_alpn) { + if (!CBB_add_asn1(&session, &child, kEarlyALPNTag) || + !CBB_add_asn1_octet_string(&child, (const uint8_t *)in->early_alpn, + in->early_alpn_len)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + } + + return CBB_flush(cbb); +} + +// SSL_SESSION_parse_string gets an optional ASN.1 OCTET STRING +// explicitly tagged with |tag| from |cbs| and saves it in |*out|. On +// entry, if |*out| is not NULL, it frees the existing contents. If +// the element was not found, it sets |*out| to NULL. It returns one +// on success, whether or not the element was found, and zero on +// decode error. +static int SSL_SESSION_parse_string(CBS *cbs, char **out, unsigned tag) { + CBS value; + int present; + if (!CBS_get_optional_asn1_octet_string(cbs, &value, &present, tag)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION); + return 0; + } + if (present) { + if (CBS_contains_zero_byte(&value)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION); + return 0; + } + if (!CBS_strdup(&value, out)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + } else { + OPENSSL_free(*out); + *out = NULL; + } + return 1; +} + +// SSL_SESSION_parse_string gets an optional ASN.1 OCTET STRING +// explicitly tagged with |tag| from |cbs| and stows it in |*out_ptr| +// and |*out_len|. If |*out_ptr| is not NULL, it frees the existing +// contents. On entry, if the element was not found, it sets +// |*out_ptr| to NULL. It returns one on success, whether or not the +// element was found, and zero on decode error. +static int SSL_SESSION_parse_octet_string(CBS *cbs, uint8_t **out_ptr, + size_t *out_len, unsigned tag) { + CBS value; + if (!CBS_get_optional_asn1_octet_string(cbs, &value, NULL, tag)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION); + return 0; + } + if (!CBS_stow(&value, out_ptr, out_len)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + return 1; +} + +static int SSL_SESSION_parse_crypto_buffer(CBS *cbs, CRYPTO_BUFFER **out, + unsigned tag, + CRYPTO_BUFFER_POOL *pool) { + if (!CBS_peek_asn1_tag(cbs, tag)) { + return 1; + } + + CBS child, value; + if (!CBS_get_asn1(cbs, &child, tag) || + !CBS_get_asn1(&child, &value, CBS_ASN1_OCTETSTRING) || + CBS_len(&child) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION); + return 0; + } + CRYPTO_BUFFER_free(*out); + *out = CRYPTO_BUFFER_new_from_CBS(&value, pool); + if (*out == nullptr) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + return 1; +} + +// SSL_SESSION_parse_bounded_octet_string parses an optional ASN.1 OCTET STRING +// explicitly tagged with |tag| of size at most |max_out|. +static int SSL_SESSION_parse_bounded_octet_string( + CBS *cbs, uint8_t *out, uint8_t *out_len, uint8_t max_out, unsigned tag) { + CBS value; + if (!CBS_get_optional_asn1_octet_string(cbs, &value, NULL, tag) || + CBS_len(&value) > max_out) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION); + return 0; + } + OPENSSL_memcpy(out, CBS_data(&value), CBS_len(&value)); + *out_len = (uint8_t)CBS_len(&value); + return 1; +} + +static int SSL_SESSION_parse_long(CBS *cbs, long *out, unsigned tag, + long default_value) { + uint64_t value; + if (!CBS_get_optional_asn1_uint64(cbs, &value, tag, + (uint64_t)default_value) || + value > LONG_MAX) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION); + return 0; + } + *out = (long)value; + return 1; +} + +static int SSL_SESSION_parse_u32(CBS *cbs, uint32_t *out, unsigned tag, + uint32_t default_value) { + uint64_t value; + if (!CBS_get_optional_asn1_uint64(cbs, &value, tag, + (uint64_t)default_value) || + value > 0xffffffff) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION); + return 0; + } + *out = (uint32_t)value; + return 1; +} + +static int SSL_SESSION_parse_u16(CBS *cbs, uint16_t *out, unsigned tag, + uint16_t default_value) { + uint64_t value; + if (!CBS_get_optional_asn1_uint64(cbs, &value, tag, + (uint64_t)default_value) || + value > 0xffff) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION); + return 0; + } + *out = (uint16_t)value; + return 1; +} + +UniquePtr SSL_SESSION_parse(CBS *cbs, + const SSL_X509_METHOD *x509_method, + CRYPTO_BUFFER_POOL *pool) { + UniquePtr ret = ssl_session_new(x509_method); + if (!ret) { + return nullptr; + } + + CBS session; + uint64_t version, ssl_version; + uint16_t unused; + if (!CBS_get_asn1(cbs, &session, CBS_ASN1_SEQUENCE) || + !CBS_get_asn1_uint64(&session, &version) || + version != kVersion || + !CBS_get_asn1_uint64(&session, &ssl_version) || + // Require sessions have versions valid in either TLS or DTLS. The session + // will not be used by the handshake if not applicable, but, for + // simplicity, never parse a session that does not pass + // |ssl_protocol_version_from_wire|. + ssl_version > UINT16_MAX || + !ssl_protocol_version_from_wire(&unused, ssl_version)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION); + return nullptr; + } + ret->ssl_version = ssl_version; + + CBS cipher; + uint16_t cipher_value; + if (!CBS_get_asn1(&session, &cipher, CBS_ASN1_OCTETSTRING) || + !CBS_get_u16(&cipher, &cipher_value) || + CBS_len(&cipher) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION); + return nullptr; + } + ret->cipher = SSL_get_cipher_by_value(cipher_value); + if (ret->cipher == NULL) { + OPENSSL_PUT_ERROR(SSL, SSL_R_UNSUPPORTED_CIPHER); + return nullptr; + } + + CBS session_id, master_key; + if (!CBS_get_asn1(&session, &session_id, CBS_ASN1_OCTETSTRING) || + CBS_len(&session_id) > SSL3_MAX_SSL_SESSION_ID_LENGTH || + !CBS_get_asn1(&session, &master_key, CBS_ASN1_OCTETSTRING) || + CBS_len(&master_key) > SSL_MAX_MASTER_KEY_LENGTH) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION); + return nullptr; + } + OPENSSL_memcpy(ret->session_id, CBS_data(&session_id), CBS_len(&session_id)); + ret->session_id_length = CBS_len(&session_id); + OPENSSL_memcpy(ret->master_key, CBS_data(&master_key), CBS_len(&master_key)); + ret->master_key_length = CBS_len(&master_key); + + CBS child; + uint64_t timeout; + if (!CBS_get_asn1(&session, &child, kTimeTag) || + !CBS_get_asn1_uint64(&child, &ret->time) || + !CBS_get_asn1(&session, &child, kTimeoutTag) || + !CBS_get_asn1_uint64(&child, &timeout) || + timeout > UINT32_MAX) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION); + return nullptr; + } + + ret->timeout = (uint32_t)timeout; + + CBS peer; + int has_peer; + if (!CBS_get_optional_asn1(&session, &peer, &has_peer, kPeerTag) || + (has_peer && CBS_len(&peer) == 0)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION); + return nullptr; + } + // |peer| is processed with the certificate chain. + + if (!SSL_SESSION_parse_bounded_octet_string( + &session, ret->sid_ctx, &ret->sid_ctx_length, sizeof(ret->sid_ctx), + kSessionIDContextTag) || + !SSL_SESSION_parse_long(&session, &ret->verify_result, kVerifyResultTag, + X509_V_OK)) { + return nullptr; + } + + // Skip the historical hostName field. + CBS unused_hostname; + if (!CBS_get_optional_asn1(&session, &unused_hostname, nullptr, + kHostNameTag)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION); + return nullptr; + } + + if (!SSL_SESSION_parse_string(&session, &ret->psk_identity, + kPSKIdentityTag) || + !SSL_SESSION_parse_u32(&session, &ret->tlsext_tick_lifetime_hint, + kTicketLifetimeHintTag, 0) || + !SSL_SESSION_parse_octet_string(&session, &ret->tlsext_tick, + &ret->tlsext_ticklen, kTicketTag)) { + return nullptr; + } + + if (CBS_peek_asn1_tag(&session, kPeerSHA256Tag)) { + CBS peer_sha256; + if (!CBS_get_asn1(&session, &child, kPeerSHA256Tag) || + !CBS_get_asn1(&child, &peer_sha256, CBS_ASN1_OCTETSTRING) || + CBS_len(&peer_sha256) != sizeof(ret->peer_sha256) || + CBS_len(&child) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION); + return nullptr; + } + OPENSSL_memcpy(ret->peer_sha256, CBS_data(&peer_sha256), + sizeof(ret->peer_sha256)); + ret->peer_sha256_valid = 1; + } else { + ret->peer_sha256_valid = 0; + } + + if (!SSL_SESSION_parse_bounded_octet_string( + &session, ret->original_handshake_hash, + &ret->original_handshake_hash_len, + sizeof(ret->original_handshake_hash), kOriginalHandshakeHashTag) || + !SSL_SESSION_parse_crypto_buffer(&session, + &ret->signed_cert_timestamp_list, + kSignedCertTimestampListTag, pool) || + !SSL_SESSION_parse_crypto_buffer(&session, &ret->ocsp_response, + kOCSPResponseTag, pool)) { + return nullptr; + } + + int extended_master_secret; + if (!CBS_get_optional_asn1_bool(&session, &extended_master_secret, + kExtendedMasterSecretTag, + 0 /* default to false */)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION); + return nullptr; + } + ret->extended_master_secret = !!extended_master_secret; + + if (!SSL_SESSION_parse_u16(&session, &ret->group_id, kGroupIDTag, 0)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION); + return nullptr; + } + + CBS cert_chain; + CBS_init(&cert_chain, NULL, 0); + int has_cert_chain; + if (!CBS_get_optional_asn1(&session, &cert_chain, &has_cert_chain, + kCertChainTag) || + (has_cert_chain && CBS_len(&cert_chain) == 0)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION); + return nullptr; + } + if (has_cert_chain && !has_peer) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION); + return nullptr; + } + if (has_peer || has_cert_chain) { + ret->certs = sk_CRYPTO_BUFFER_new_null(); + if (ret->certs == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return nullptr; + } + + if (has_peer) { + UniquePtr buffer(CRYPTO_BUFFER_new_from_CBS(&peer, pool)); + if (!buffer || + !PushToStack(ret->certs, std::move(buffer))) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return nullptr; + } + } + + while (CBS_len(&cert_chain) > 0) { + CBS cert; + if (!CBS_get_any_asn1_element(&cert_chain, &cert, NULL, NULL) || + CBS_len(&cert) == 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION); + return nullptr; + } + + CRYPTO_BUFFER *buffer = CRYPTO_BUFFER_new_from_CBS(&cert, pool); + if (buffer == NULL || + !sk_CRYPTO_BUFFER_push(ret->certs, buffer)) { + CRYPTO_BUFFER_free(buffer); + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return nullptr; + } + } + } + + if (!x509_method->session_cache_objects(ret.get())) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION); + return nullptr; + } + + CBS age_add; + int age_add_present; + if (!CBS_get_optional_asn1_octet_string(&session, &age_add, &age_add_present, + kTicketAgeAddTag) || + (age_add_present && + !CBS_get_u32(&age_add, &ret->ticket_age_add)) || + CBS_len(&age_add) != 0) { + return nullptr; + } + ret->ticket_age_add_valid = age_add_present; + + int is_server; + if (!CBS_get_optional_asn1_bool(&session, &is_server, kIsServerTag, + 1 /* default to true */)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION); + return nullptr; + } + /* TODO: in time we can include |is_server| for servers too, then we can + enforce that client and server sessions are never mixed up. */ + + ret->is_server = is_server; + + if (!SSL_SESSION_parse_u16(&session, &ret->peer_signature_algorithm, + kPeerSignatureAlgorithmTag, 0) || + !SSL_SESSION_parse_u32(&session, &ret->ticket_max_early_data, + kTicketMaxEarlyDataTag, 0) || + !SSL_SESSION_parse_u32(&session, &ret->auth_timeout, kAuthTimeoutTag, + ret->timeout) || + !SSL_SESSION_parse_octet_string(&session, &ret->early_alpn, + &ret->early_alpn_len, kEarlyALPNTag) || + CBS_len(&session) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION); + return nullptr; + } + + return ret; +} + +int ssl_session_serialize(const SSL_SESSION *in, CBB *cbb) { + return SSL_SESSION_to_bytes_full(in, cbb, 0); +} + +} // namespace bssl + +using namespace bssl; + +int SSL_SESSION_to_bytes(const SSL_SESSION *in, uint8_t **out_data, + size_t *out_len) { + if (in->not_resumable) { + // If the caller has an unresumable session, e.g. if |SSL_get_session| were + // called on a TLS 1.3 or False Started connection, serialize with a + // placeholder value so it is not accidentally deserialized into a resumable + // one. + static const char kNotResumableSession[] = "NOT RESUMABLE"; + + *out_len = strlen(kNotResumableSession); + *out_data = (uint8_t *)BUF_memdup(kNotResumableSession, *out_len); + if (*out_data == NULL) { + return 0; + } + + return 1; + } + + ScopedCBB cbb; + if (!CBB_init(cbb.get(), 256) || + !SSL_SESSION_to_bytes_full(in, cbb.get(), 0) || + !CBB_finish(cbb.get(), out_data, out_len)) { + return 0; + } + + return 1; +} + +int SSL_SESSION_to_bytes_for_ticket(const SSL_SESSION *in, uint8_t **out_data, + size_t *out_len) { + ScopedCBB cbb; + if (!CBB_init(cbb.get(), 256) || + !SSL_SESSION_to_bytes_full(in, cbb.get(), 1) || + !CBB_finish(cbb.get(), out_data, out_len)) { + return 0; + } + + return 1; +} + +int i2d_SSL_SESSION(SSL_SESSION *in, uint8_t **pp) { + uint8_t *out; + size_t len; + + if (!SSL_SESSION_to_bytes(in, &out, &len)) { + return -1; + } + + if (len > INT_MAX) { + OPENSSL_free(out); + OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW); + return -1; + } + + if (pp) { + OPENSSL_memcpy(*pp, out, len); + *pp += len; + } + OPENSSL_free(out); + + return len; +} + +SSL_SESSION *SSL_SESSION_from_bytes(const uint8_t *in, size_t in_len, + const SSL_CTX *ctx) { + CBS cbs; + CBS_init(&cbs, in, in_len); + UniquePtr ret = + SSL_SESSION_parse(&cbs, ctx->x509_method, ctx->pool); + if (!ret) { + return NULL; + } + if (CBS_len(&cbs) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION); + return NULL; + } + return ret.release(); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/ssl/ssl_asn1.cc.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/ssl/ssl_asn1.cc.grpc_back new file mode 100644 index 0000000..078ad1f --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/ssl/ssl_asn1.cc.grpc_back @@ -0,0 +1,844 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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. */ + +// Per C99, various stdint.h macros are unavailable in C++ unless some macros +// are defined. C++11 overruled this decision, but older Android NDKs still +// require it. +#if !defined(__STDC_LIMIT_MACROS) +#define __STDC_LIMIT_MACROS +#endif + +#include + +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include "../crypto/internal.h" +#include "internal.h" + + +namespace bssl { + +// An SSL_SESSION is serialized as the following ASN.1 structure: +// +// SSLSession ::= SEQUENCE { +// version INTEGER (1), -- session structure version +// sslVersion INTEGER, -- protocol version number +// cipher OCTET STRING, -- two bytes long +// sessionID OCTET STRING, +// masterKey OCTET STRING, +// time [1] INTEGER, -- seconds since UNIX epoch +// timeout [2] INTEGER, -- in seconds +// peer [3] Certificate OPTIONAL, +// sessionIDContext [4] OCTET STRING OPTIONAL, +// verifyResult [5] INTEGER OPTIONAL, -- one of X509_V_* codes +// pskIdentity [8] OCTET STRING OPTIONAL, +// ticketLifetimeHint [9] INTEGER OPTIONAL, -- client-only +// ticket [10] OCTET STRING OPTIONAL, -- client-only +// peerSHA256 [13] OCTET STRING OPTIONAL, +// originalHandshakeHash [14] OCTET STRING OPTIONAL, +// signedCertTimestampList [15] OCTET STRING OPTIONAL, +// -- contents of SCT extension +// ocspResponse [16] OCTET STRING OPTIONAL, +// -- stapled OCSP response from the server +// extendedMasterSecret [17] BOOLEAN OPTIONAL, +// groupID [18] INTEGER OPTIONAL, +// certChain [19] SEQUENCE OF Certificate OPTIONAL, +// ticketAgeAdd [21] OCTET STRING OPTIONAL, +// isServer [22] BOOLEAN DEFAULT TRUE, +// peerSignatureAlgorithm [23] INTEGER OPTIONAL, +// ticketMaxEarlyData [24] INTEGER OPTIONAL, +// authTimeout [25] INTEGER OPTIONAL, -- defaults to timeout +// earlyALPN [26] OCTET STRING OPTIONAL, +// } +// +// Note: historically this serialization has included other optional +// fields. Their presence is currently treated as a parse error, except for +// hostName, which is ignored. +// +// keyArg [0] IMPLICIT OCTET STRING OPTIONAL, +// hostName [6] OCTET STRING OPTIONAL, +// pskIdentityHint [7] OCTET STRING OPTIONAL, +// compressionMethod [11] OCTET STRING OPTIONAL, +// srpUsername [12] OCTET STRING OPTIONAL, +// ticketFlags [20] INTEGER OPTIONAL, + +static const unsigned kVersion = 1; + +static const unsigned kTimeTag = + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 1; +static const unsigned kTimeoutTag = + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 2; +static const unsigned kPeerTag = + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 3; +static const unsigned kSessionIDContextTag = + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 4; +static const unsigned kVerifyResultTag = + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 5; +static const unsigned kHostNameTag = + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 6; +static const unsigned kPSKIdentityTag = + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 8; +static const unsigned kTicketLifetimeHintTag = + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 9; +static const unsigned kTicketTag = + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 10; +static const unsigned kPeerSHA256Tag = + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 13; +static const unsigned kOriginalHandshakeHashTag = + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 14; +static const unsigned kSignedCertTimestampListTag = + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 15; +static const unsigned kOCSPResponseTag = + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 16; +static const unsigned kExtendedMasterSecretTag = + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 17; +static const unsigned kGroupIDTag = + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 18; +static const unsigned kCertChainTag = + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 19; +static const unsigned kTicketAgeAddTag = + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 21; +static const unsigned kIsServerTag = + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 22; +static const unsigned kPeerSignatureAlgorithmTag = + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 23; +static const unsigned kTicketMaxEarlyDataTag = + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 24; +static const unsigned kAuthTimeoutTag = + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 25; +static const unsigned kEarlyALPNTag = + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 26; + +static int SSL_SESSION_to_bytes_full(const SSL_SESSION *in, CBB *cbb, + int for_ticket) { + if (in == NULL || in->cipher == NULL) { + return 0; + } + + CBB session, child, child2; + if (!CBB_add_asn1(cbb, &session, CBS_ASN1_SEQUENCE) || + !CBB_add_asn1_uint64(&session, kVersion) || + !CBB_add_asn1_uint64(&session, in->ssl_version) || + !CBB_add_asn1(&session, &child, CBS_ASN1_OCTETSTRING) || + !CBB_add_u16(&child, (uint16_t)(in->cipher->id & 0xffff)) || + // The session ID is irrelevant for a session ticket. + !CBB_add_asn1_octet_string(&session, in->session_id, + for_ticket ? 0 : in->session_id_length) || + !CBB_add_asn1_octet_string(&session, in->master_key, + in->master_key_length) || + !CBB_add_asn1(&session, &child, kTimeTag) || + !CBB_add_asn1_uint64(&child, in->time) || + !CBB_add_asn1(&session, &child, kTimeoutTag) || + !CBB_add_asn1_uint64(&child, in->timeout)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + + // The peer certificate is only serialized if the SHA-256 isn't + // serialized instead. + if (sk_CRYPTO_BUFFER_num(in->certs) > 0 && !in->peer_sha256_valid) { + const CRYPTO_BUFFER *buffer = sk_CRYPTO_BUFFER_value(in->certs, 0); + if (!CBB_add_asn1(&session, &child, kPeerTag) || + !CBB_add_bytes(&child, CRYPTO_BUFFER_data(buffer), + CRYPTO_BUFFER_len(buffer))) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + } + + // Although it is OPTIONAL and usually empty, OpenSSL has + // historically always encoded the sid_ctx. + if (!CBB_add_asn1(&session, &child, kSessionIDContextTag) || + !CBB_add_asn1_octet_string(&child, in->sid_ctx, in->sid_ctx_length)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + + if (in->verify_result != X509_V_OK) { + if (!CBB_add_asn1(&session, &child, kVerifyResultTag) || + !CBB_add_asn1_uint64(&child, in->verify_result)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + } + + if (in->psk_identity) { + if (!CBB_add_asn1(&session, &child, kPSKIdentityTag) || + !CBB_add_asn1_octet_string(&child, (const uint8_t *)in->psk_identity, + strlen(in->psk_identity))) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + } + + if (in->tlsext_tick_lifetime_hint > 0) { + if (!CBB_add_asn1(&session, &child, kTicketLifetimeHintTag) || + !CBB_add_asn1_uint64(&child, in->tlsext_tick_lifetime_hint)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + } + + if (in->tlsext_tick && !for_ticket) { + if (!CBB_add_asn1(&session, &child, kTicketTag) || + !CBB_add_asn1_octet_string(&child, in->tlsext_tick, + in->tlsext_ticklen)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + } + + if (in->peer_sha256_valid) { + if (!CBB_add_asn1(&session, &child, kPeerSHA256Tag) || + !CBB_add_asn1_octet_string(&child, in->peer_sha256, + sizeof(in->peer_sha256))) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + } + + if (in->original_handshake_hash_len > 0) { + if (!CBB_add_asn1(&session, &child, kOriginalHandshakeHashTag) || + !CBB_add_asn1_octet_string(&child, in->original_handshake_hash, + in->original_handshake_hash_len)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + } + + if (in->signed_cert_timestamp_list != nullptr) { + if (!CBB_add_asn1(&session, &child, kSignedCertTimestampListTag) || + !CBB_add_asn1_octet_string( + &child, CRYPTO_BUFFER_data(in->signed_cert_timestamp_list), + CRYPTO_BUFFER_len(in->signed_cert_timestamp_list))) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + } + + if (in->ocsp_response != nullptr) { + if (!CBB_add_asn1(&session, &child, kOCSPResponseTag) || + !CBB_add_asn1_octet_string(&child, + CRYPTO_BUFFER_data(in->ocsp_response), + CRYPTO_BUFFER_len(in->ocsp_response))) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + } + + if (in->extended_master_secret) { + if (!CBB_add_asn1(&session, &child, kExtendedMasterSecretTag) || + !CBB_add_asn1_bool(&child, true)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + } + + if (in->group_id > 0 && + (!CBB_add_asn1(&session, &child, kGroupIDTag) || + !CBB_add_asn1_uint64(&child, in->group_id))) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + + // The certificate chain is only serialized if the leaf's SHA-256 isn't + // serialized instead. + if (in->certs != NULL && + !in->peer_sha256_valid && + sk_CRYPTO_BUFFER_num(in->certs) >= 2) { + if (!CBB_add_asn1(&session, &child, kCertChainTag)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + for (size_t i = 1; i < sk_CRYPTO_BUFFER_num(in->certs); i++) { + const CRYPTO_BUFFER *buffer = sk_CRYPTO_BUFFER_value(in->certs, i); + if (!CBB_add_bytes(&child, CRYPTO_BUFFER_data(buffer), + CRYPTO_BUFFER_len(buffer))) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + } + } + + if (in->ticket_age_add_valid) { + if (!CBB_add_asn1(&session, &child, kTicketAgeAddTag) || + !CBB_add_asn1(&child, &child2, CBS_ASN1_OCTETSTRING) || + !CBB_add_u32(&child2, in->ticket_age_add)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + } + + if (!in->is_server) { + if (!CBB_add_asn1(&session, &child, kIsServerTag) || + !CBB_add_asn1_bool(&child, false)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + } + + if (in->peer_signature_algorithm != 0 && + (!CBB_add_asn1(&session, &child, kPeerSignatureAlgorithmTag) || + !CBB_add_asn1_uint64(&child, in->peer_signature_algorithm))) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + + if (in->ticket_max_early_data != 0 && + (!CBB_add_asn1(&session, &child, kTicketMaxEarlyDataTag) || + !CBB_add_asn1_uint64(&child, in->ticket_max_early_data))) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + + if (in->timeout != in->auth_timeout && + (!CBB_add_asn1(&session, &child, kAuthTimeoutTag) || + !CBB_add_asn1_uint64(&child, in->auth_timeout))) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + + if (in->early_alpn) { + if (!CBB_add_asn1(&session, &child, kEarlyALPNTag) || + !CBB_add_asn1_octet_string(&child, (const uint8_t *)in->early_alpn, + in->early_alpn_len)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + } + + return CBB_flush(cbb); +} + +// SSL_SESSION_parse_string gets an optional ASN.1 OCTET STRING +// explicitly tagged with |tag| from |cbs| and saves it in |*out|. On +// entry, if |*out| is not NULL, it frees the existing contents. If +// the element was not found, it sets |*out| to NULL. It returns one +// on success, whether or not the element was found, and zero on +// decode error. +static int SSL_SESSION_parse_string(CBS *cbs, char **out, unsigned tag) { + CBS value; + int present; + if (!CBS_get_optional_asn1_octet_string(cbs, &value, &present, tag)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION); + return 0; + } + if (present) { + if (CBS_contains_zero_byte(&value)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION); + return 0; + } + if (!CBS_strdup(&value, out)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + } else { + OPENSSL_free(*out); + *out = NULL; + } + return 1; +} + +// SSL_SESSION_parse_string gets an optional ASN.1 OCTET STRING +// explicitly tagged with |tag| from |cbs| and stows it in |*out_ptr| +// and |*out_len|. If |*out_ptr| is not NULL, it frees the existing +// contents. On entry, if the element was not found, it sets +// |*out_ptr| to NULL. It returns one on success, whether or not the +// element was found, and zero on decode error. +static int SSL_SESSION_parse_octet_string(CBS *cbs, uint8_t **out_ptr, + size_t *out_len, unsigned tag) { + CBS value; + if (!CBS_get_optional_asn1_octet_string(cbs, &value, NULL, tag)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION); + return 0; + } + if (!CBS_stow(&value, out_ptr, out_len)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + return 1; +} + +static int SSL_SESSION_parse_crypto_buffer(CBS *cbs, CRYPTO_BUFFER **out, + unsigned tag, + CRYPTO_BUFFER_POOL *pool) { + if (!CBS_peek_asn1_tag(cbs, tag)) { + return 1; + } + + CBS child, value; + if (!CBS_get_asn1(cbs, &child, tag) || + !CBS_get_asn1(&child, &value, CBS_ASN1_OCTETSTRING) || + CBS_len(&child) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION); + return 0; + } + CRYPTO_BUFFER_free(*out); + *out = CRYPTO_BUFFER_new_from_CBS(&value, pool); + if (*out == nullptr) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + return 1; +} + +// SSL_SESSION_parse_bounded_octet_string parses an optional ASN.1 OCTET STRING +// explicitly tagged with |tag| of size at most |max_out|. +static int SSL_SESSION_parse_bounded_octet_string( + CBS *cbs, uint8_t *out, uint8_t *out_len, uint8_t max_out, unsigned tag) { + CBS value; + if (!CBS_get_optional_asn1_octet_string(cbs, &value, NULL, tag) || + CBS_len(&value) > max_out) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION); + return 0; + } + OPENSSL_memcpy(out, CBS_data(&value), CBS_len(&value)); + *out_len = (uint8_t)CBS_len(&value); + return 1; +} + +static int SSL_SESSION_parse_long(CBS *cbs, long *out, unsigned tag, + long default_value) { + uint64_t value; + if (!CBS_get_optional_asn1_uint64(cbs, &value, tag, + (uint64_t)default_value) || + value > LONG_MAX) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION); + return 0; + } + *out = (long)value; + return 1; +} + +static int SSL_SESSION_parse_u32(CBS *cbs, uint32_t *out, unsigned tag, + uint32_t default_value) { + uint64_t value; + if (!CBS_get_optional_asn1_uint64(cbs, &value, tag, + (uint64_t)default_value) || + value > 0xffffffff) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION); + return 0; + } + *out = (uint32_t)value; + return 1; +} + +static int SSL_SESSION_parse_u16(CBS *cbs, uint16_t *out, unsigned tag, + uint16_t default_value) { + uint64_t value; + if (!CBS_get_optional_asn1_uint64(cbs, &value, tag, + (uint64_t)default_value) || + value > 0xffff) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION); + return 0; + } + *out = (uint16_t)value; + return 1; +} + +UniquePtr SSL_SESSION_parse(CBS *cbs, + const SSL_X509_METHOD *x509_method, + CRYPTO_BUFFER_POOL *pool) { + UniquePtr ret = ssl_session_new(x509_method); + if (!ret) { + return nullptr; + } + + CBS session; + uint64_t version, ssl_version; + uint16_t unused; + if (!CBS_get_asn1(cbs, &session, CBS_ASN1_SEQUENCE) || + !CBS_get_asn1_uint64(&session, &version) || + version != kVersion || + !CBS_get_asn1_uint64(&session, &ssl_version) || + // Require sessions have versions valid in either TLS or DTLS. The session + // will not be used by the handshake if not applicable, but, for + // simplicity, never parse a session that does not pass + // |ssl_protocol_version_from_wire|. + ssl_version > UINT16_MAX || + !ssl_protocol_version_from_wire(&unused, ssl_version)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION); + return nullptr; + } + ret->ssl_version = ssl_version; + + CBS cipher; + uint16_t cipher_value; + if (!CBS_get_asn1(&session, &cipher, CBS_ASN1_OCTETSTRING) || + !CBS_get_u16(&cipher, &cipher_value) || + CBS_len(&cipher) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION); + return nullptr; + } + ret->cipher = SSL_get_cipher_by_value(cipher_value); + if (ret->cipher == NULL) { + OPENSSL_PUT_ERROR(SSL, SSL_R_UNSUPPORTED_CIPHER); + return nullptr; + } + + CBS session_id, master_key; + if (!CBS_get_asn1(&session, &session_id, CBS_ASN1_OCTETSTRING) || + CBS_len(&session_id) > SSL3_MAX_SSL_SESSION_ID_LENGTH || + !CBS_get_asn1(&session, &master_key, CBS_ASN1_OCTETSTRING) || + CBS_len(&master_key) > SSL_MAX_MASTER_KEY_LENGTH) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION); + return nullptr; + } + OPENSSL_memcpy(ret->session_id, CBS_data(&session_id), CBS_len(&session_id)); + ret->session_id_length = CBS_len(&session_id); + OPENSSL_memcpy(ret->master_key, CBS_data(&master_key), CBS_len(&master_key)); + ret->master_key_length = CBS_len(&master_key); + + CBS child; + uint64_t timeout; + if (!CBS_get_asn1(&session, &child, kTimeTag) || + !CBS_get_asn1_uint64(&child, &ret->time) || + !CBS_get_asn1(&session, &child, kTimeoutTag) || + !CBS_get_asn1_uint64(&child, &timeout) || + timeout > UINT32_MAX) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION); + return nullptr; + } + + ret->timeout = (uint32_t)timeout; + + CBS peer; + int has_peer; + if (!CBS_get_optional_asn1(&session, &peer, &has_peer, kPeerTag) || + (has_peer && CBS_len(&peer) == 0)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION); + return nullptr; + } + // |peer| is processed with the certificate chain. + + if (!SSL_SESSION_parse_bounded_octet_string( + &session, ret->sid_ctx, &ret->sid_ctx_length, sizeof(ret->sid_ctx), + kSessionIDContextTag) || + !SSL_SESSION_parse_long(&session, &ret->verify_result, kVerifyResultTag, + X509_V_OK)) { + return nullptr; + } + + // Skip the historical hostName field. + CBS unused_hostname; + if (!CBS_get_optional_asn1(&session, &unused_hostname, nullptr, + kHostNameTag)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION); + return nullptr; + } + + if (!SSL_SESSION_parse_string(&session, &ret->psk_identity, + kPSKIdentityTag) || + !SSL_SESSION_parse_u32(&session, &ret->tlsext_tick_lifetime_hint, + kTicketLifetimeHintTag, 0) || + !SSL_SESSION_parse_octet_string(&session, &ret->tlsext_tick, + &ret->tlsext_ticklen, kTicketTag)) { + return nullptr; + } + + if (CBS_peek_asn1_tag(&session, kPeerSHA256Tag)) { + CBS peer_sha256; + if (!CBS_get_asn1(&session, &child, kPeerSHA256Tag) || + !CBS_get_asn1(&child, &peer_sha256, CBS_ASN1_OCTETSTRING) || + CBS_len(&peer_sha256) != sizeof(ret->peer_sha256) || + CBS_len(&child) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION); + return nullptr; + } + OPENSSL_memcpy(ret->peer_sha256, CBS_data(&peer_sha256), + sizeof(ret->peer_sha256)); + ret->peer_sha256_valid = 1; + } else { + ret->peer_sha256_valid = 0; + } + + if (!SSL_SESSION_parse_bounded_octet_string( + &session, ret->original_handshake_hash, + &ret->original_handshake_hash_len, + sizeof(ret->original_handshake_hash), kOriginalHandshakeHashTag) || + !SSL_SESSION_parse_crypto_buffer(&session, + &ret->signed_cert_timestamp_list, + kSignedCertTimestampListTag, pool) || + !SSL_SESSION_parse_crypto_buffer(&session, &ret->ocsp_response, + kOCSPResponseTag, pool)) { + return nullptr; + } + + int extended_master_secret; + if (!CBS_get_optional_asn1_bool(&session, &extended_master_secret, + kExtendedMasterSecretTag, + 0 /* default to false */)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION); + return nullptr; + } + ret->extended_master_secret = !!extended_master_secret; + + if (!SSL_SESSION_parse_u16(&session, &ret->group_id, kGroupIDTag, 0)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION); + return nullptr; + } + + CBS cert_chain; + CBS_init(&cert_chain, NULL, 0); + int has_cert_chain; + if (!CBS_get_optional_asn1(&session, &cert_chain, &has_cert_chain, + kCertChainTag) || + (has_cert_chain && CBS_len(&cert_chain) == 0)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION); + return nullptr; + } + if (has_cert_chain && !has_peer) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION); + return nullptr; + } + if (has_peer || has_cert_chain) { + ret->certs = sk_CRYPTO_BUFFER_new_null(); + if (ret->certs == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return nullptr; + } + + if (has_peer) { + UniquePtr buffer(CRYPTO_BUFFER_new_from_CBS(&peer, pool)); + if (!buffer || + !PushToStack(ret->certs, std::move(buffer))) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return nullptr; + } + } + + while (CBS_len(&cert_chain) > 0) { + CBS cert; + if (!CBS_get_any_asn1_element(&cert_chain, &cert, NULL, NULL) || + CBS_len(&cert) == 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION); + return nullptr; + } + + CRYPTO_BUFFER *buffer = CRYPTO_BUFFER_new_from_CBS(&cert, pool); + if (buffer == NULL || + !sk_CRYPTO_BUFFER_push(ret->certs, buffer)) { + CRYPTO_BUFFER_free(buffer); + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return nullptr; + } + } + } + + if (!x509_method->session_cache_objects(ret.get())) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION); + return nullptr; + } + + CBS age_add; + int age_add_present; + if (!CBS_get_optional_asn1_octet_string(&session, &age_add, &age_add_present, + kTicketAgeAddTag) || + (age_add_present && + !CBS_get_u32(&age_add, &ret->ticket_age_add)) || + CBS_len(&age_add) != 0) { + return nullptr; + } + ret->ticket_age_add_valid = age_add_present; + + int is_server; + if (!CBS_get_optional_asn1_bool(&session, &is_server, kIsServerTag, + 1 /* default to true */)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION); + return nullptr; + } + /* TODO: in time we can include |is_server| for servers too, then we can + enforce that client and server sessions are never mixed up. */ + + ret->is_server = is_server; + + if (!SSL_SESSION_parse_u16(&session, &ret->peer_signature_algorithm, + kPeerSignatureAlgorithmTag, 0) || + !SSL_SESSION_parse_u32(&session, &ret->ticket_max_early_data, + kTicketMaxEarlyDataTag, 0) || + !SSL_SESSION_parse_u32(&session, &ret->auth_timeout, kAuthTimeoutTag, + ret->timeout) || + !SSL_SESSION_parse_octet_string(&session, &ret->early_alpn, + &ret->early_alpn_len, kEarlyALPNTag) || + CBS_len(&session) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION); + return nullptr; + } + + return ret; +} + +int ssl_session_serialize(const SSL_SESSION *in, CBB *cbb) { + return SSL_SESSION_to_bytes_full(in, cbb, 0); +} + +} // namespace bssl + +using namespace bssl; + +int SSL_SESSION_to_bytes(const SSL_SESSION *in, uint8_t **out_data, + size_t *out_len) { + if (in->not_resumable) { + // If the caller has an unresumable session, e.g. if |SSL_get_session| were + // called on a TLS 1.3 or False Started connection, serialize with a + // placeholder value so it is not accidentally deserialized into a resumable + // one. + static const char kNotResumableSession[] = "NOT RESUMABLE"; + + *out_len = strlen(kNotResumableSession); + *out_data = (uint8_t *)BUF_memdup(kNotResumableSession, *out_len); + if (*out_data == NULL) { + return 0; + } + + return 1; + } + + ScopedCBB cbb; + if (!CBB_init(cbb.get(), 256) || + !SSL_SESSION_to_bytes_full(in, cbb.get(), 0) || + !CBB_finish(cbb.get(), out_data, out_len)) { + return 0; + } + + return 1; +} + +int SSL_SESSION_to_bytes_for_ticket(const SSL_SESSION *in, uint8_t **out_data, + size_t *out_len) { + ScopedCBB cbb; + if (!CBB_init(cbb.get(), 256) || + !SSL_SESSION_to_bytes_full(in, cbb.get(), 1) || + !CBB_finish(cbb.get(), out_data, out_len)) { + return 0; + } + + return 1; +} + +int i2d_SSL_SESSION(SSL_SESSION *in, uint8_t **pp) { + uint8_t *out; + size_t len; + + if (!SSL_SESSION_to_bytes(in, &out, &len)) { + return -1; + } + + if (len > INT_MAX) { + OPENSSL_free(out); + OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW); + return -1; + } + + if (pp) { + OPENSSL_memcpy(*pp, out, len); + *pp += len; + } + OPENSSL_free(out); + + return len; +} + +SSL_SESSION *SSL_SESSION_from_bytes(const uint8_t *in, size_t in_len, + const SSL_CTX *ctx) { + CBS cbs; + CBS_init(&cbs, in, in_len); + UniquePtr ret = + SSL_SESSION_parse(&cbs, ctx->x509_method, ctx->pool); + if (!ret) { + return NULL; + } + if (CBS_len(&cbs) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SSL_SESSION); + return NULL; + } + return ret.release(); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/ssl/ssl_buffer.cc b/FoodApp/Pods/BoringSSL-GRPC/ssl/ssl_buffer.cc new file mode 100644 index 0000000..a1feb22 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/ssl/ssl_buffer.cc @@ -0,0 +1,286 @@ +/* Copyright (c) 2015, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include "../crypto/internal.h" +#include "internal.h" + + +namespace bssl { + +// BIO uses int instead of size_t. No lengths will exceed uint16_t, so this will +// not overflow. +static_assert(0xffff <= INT_MAX, "uint16_t does not fit in int"); + +static_assert((SSL3_ALIGN_PAYLOAD & (SSL3_ALIGN_PAYLOAD - 1)) == 0, + "SSL3_ALIGN_PAYLOAD must be a power of 2"); + +void SSLBuffer::Clear() { + free(buf_); // Allocated with malloc(). + buf_ = nullptr; + offset_ = 0; + size_ = 0; + cap_ = 0; +} + +bool SSLBuffer::EnsureCap(size_t header_len, size_t new_cap) { + if (new_cap > 0xffff) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return false; + } + + if (cap_ >= new_cap) { + return true; + } + + // Add up to |SSL3_ALIGN_PAYLOAD| - 1 bytes of slack for alignment. + // + // Since this buffer gets allocated quite frequently and doesn't contain any + // sensitive data, we allocate with malloc rather than |OPENSSL_malloc| and + // avoid zeroing on free. + uint8_t *new_buf = (uint8_t *)malloc(new_cap + SSL3_ALIGN_PAYLOAD - 1); + if (new_buf == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return false; + } + + // Offset the buffer such that the record body is aligned. + size_t new_offset = + (0 - header_len - (uintptr_t)new_buf) & (SSL3_ALIGN_PAYLOAD - 1); + + if (buf_ != NULL) { + OPENSSL_memcpy(new_buf + new_offset, buf_ + offset_, size_); + free(buf_); // Allocated with malloc(). + } + + buf_ = new_buf; + offset_ = new_offset; + cap_ = new_cap; + return true; +} + +void SSLBuffer::DidWrite(size_t new_size) { + if (new_size > cap() - size()) { + abort(); + } + size_ += new_size; +} + +void SSLBuffer::Consume(size_t len) { + if (len > size_) { + abort(); + } + offset_ += (uint16_t)len; + size_ -= (uint16_t)len; + cap_ -= (uint16_t)len; +} + +void SSLBuffer::DiscardConsumed() { + if (size_ == 0) { + Clear(); + } +} + +static int dtls_read_buffer_next_packet(SSL *ssl) { + SSLBuffer *buf = &ssl->s3->read_buffer; + + if (!buf->empty()) { + // It is an error to call |dtls_read_buffer_extend| when the read buffer is + // not empty. + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return -1; + } + + // Read a single packet from |ssl->rbio|. |buf->cap()| must fit in an int. + int ret = BIO_read(ssl->rbio, buf->data(), static_cast(buf->cap())); + if (ret <= 0) { + ssl->s3->rwstate = SSL_READING; + return ret; + } + buf->DidWrite(static_cast(ret)); + return 1; +} + +static int tls_read_buffer_extend_to(SSL *ssl, size_t len) { + SSLBuffer *buf = &ssl->s3->read_buffer; + + if (len > buf->cap()) { + OPENSSL_PUT_ERROR(SSL, SSL_R_BUFFER_TOO_SMALL); + return -1; + } + + // Read until the target length is reached. + while (buf->size() < len) { + // The amount of data to read is bounded by |buf->cap|, which must fit in an + // int. + int ret = BIO_read(ssl->rbio, buf->data() + buf->size(), + static_cast(len - buf->size())); + if (ret <= 0) { + ssl->s3->rwstate = SSL_READING; + return ret; + } + buf->DidWrite(static_cast(ret)); + } + + return 1; +} + +int ssl_read_buffer_extend_to(SSL *ssl, size_t len) { + // |ssl_read_buffer_extend_to| implicitly discards any consumed data. + ssl->s3->read_buffer.DiscardConsumed(); + + if (SSL_is_dtls(ssl)) { + static_assert( + DTLS1_RT_HEADER_LENGTH + SSL3_RT_MAX_ENCRYPTED_LENGTH <= 0xffff, + "DTLS read buffer is too large"); + + // The |len| parameter is ignored in DTLS. + len = DTLS1_RT_HEADER_LENGTH + SSL3_RT_MAX_ENCRYPTED_LENGTH; + } + + if (!ssl->s3->read_buffer.EnsureCap(ssl_record_prefix_len(ssl), len)) { + return -1; + } + + if (ssl->rbio == NULL) { + OPENSSL_PUT_ERROR(SSL, SSL_R_BIO_NOT_SET); + return -1; + } + + int ret; + if (SSL_is_dtls(ssl)) { + // |len| is ignored for a datagram transport. + ret = dtls_read_buffer_next_packet(ssl); + } else { + ret = tls_read_buffer_extend_to(ssl, len); + } + + if (ret <= 0) { + // If the buffer was empty originally and remained empty after attempting to + // extend it, release the buffer until the next attempt. + ssl->s3->read_buffer.DiscardConsumed(); + } + return ret; +} + +int ssl_handle_open_record(SSL *ssl, bool *out_retry, ssl_open_record_t ret, + size_t consumed, uint8_t alert) { + *out_retry = false; + if (ret != ssl_open_record_partial) { + ssl->s3->read_buffer.Consume(consumed); + } + if (ret != ssl_open_record_success) { + // Nothing was returned to the caller, so discard anything marked consumed. + ssl->s3->read_buffer.DiscardConsumed(); + } + switch (ret) { + case ssl_open_record_success: + return 1; + + case ssl_open_record_partial: { + int read_ret = ssl_read_buffer_extend_to(ssl, consumed); + if (read_ret <= 0) { + return read_ret; + } + *out_retry = true; + return 1; + } + + case ssl_open_record_discard: + *out_retry = true; + return 1; + + case ssl_open_record_close_notify: + return 0; + + case ssl_open_record_error: + if (alert != 0) { + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + } + return -1; + } + assert(0); + return -1; +} + + +static_assert(SSL3_RT_HEADER_LENGTH * 2 + + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD * 2 + + SSL3_RT_MAX_PLAIN_LENGTH <= + 0xffff, + "maximum TLS write buffer is too large"); + +static_assert(DTLS1_RT_HEADER_LENGTH + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD + + SSL3_RT_MAX_PLAIN_LENGTH <= + 0xffff, + "maximum DTLS write buffer is too large"); + +static int tls_write_buffer_flush(SSL *ssl) { + SSLBuffer *buf = &ssl->s3->write_buffer; + + while (!buf->empty()) { + int ret = BIO_write(ssl->wbio, buf->data(), buf->size()); + if (ret <= 0) { + ssl->s3->rwstate = SSL_WRITING; + return ret; + } + buf->Consume(static_cast(ret)); + } + buf->Clear(); + return 1; +} + +static int dtls_write_buffer_flush(SSL *ssl) { + SSLBuffer *buf = &ssl->s3->write_buffer; + if (buf->empty()) { + return 1; + } + + int ret = BIO_write(ssl->wbio, buf->data(), buf->size()); + if (ret <= 0) { + ssl->s3->rwstate = SSL_WRITING; + // If the write failed, drop the write buffer anyway. Datagram transports + // can't write half a packet, so the caller is expected to retry from the + // top. + buf->Clear(); + return ret; + } + buf->Clear(); + return 1; +} + +int ssl_write_buffer_flush(SSL *ssl) { + if (ssl->wbio == NULL) { + OPENSSL_PUT_ERROR(SSL, SSL_R_BIO_NOT_SET); + return -1; + } + + if (SSL_is_dtls(ssl)) { + return dtls_write_buffer_flush(ssl); + } else { + return tls_write_buffer_flush(ssl); + } +} + +} // namespace bssl diff --git a/FoodApp/Pods/BoringSSL-GRPC/ssl/ssl_buffer.cc.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/ssl/ssl_buffer.cc.grpc_back new file mode 100644 index 0000000..da1de93 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/ssl/ssl_buffer.cc.grpc_back @@ -0,0 +1,286 @@ +/* Copyright (c) 2015, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include +#include +#include +#include + +#include +#include +#include + +#include "../crypto/internal.h" +#include "internal.h" + + +namespace bssl { + +// BIO uses int instead of size_t. No lengths will exceed uint16_t, so this will +// not overflow. +static_assert(0xffff <= INT_MAX, "uint16_t does not fit in int"); + +static_assert((SSL3_ALIGN_PAYLOAD & (SSL3_ALIGN_PAYLOAD - 1)) == 0, + "SSL3_ALIGN_PAYLOAD must be a power of 2"); + +void SSLBuffer::Clear() { + free(buf_); // Allocated with malloc(). + buf_ = nullptr; + offset_ = 0; + size_ = 0; + cap_ = 0; +} + +bool SSLBuffer::EnsureCap(size_t header_len, size_t new_cap) { + if (new_cap > 0xffff) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return false; + } + + if (cap_ >= new_cap) { + return true; + } + + // Add up to |SSL3_ALIGN_PAYLOAD| - 1 bytes of slack for alignment. + // + // Since this buffer gets allocated quite frequently and doesn't contain any + // sensitive data, we allocate with malloc rather than |OPENSSL_malloc| and + // avoid zeroing on free. + uint8_t *new_buf = (uint8_t *)malloc(new_cap + SSL3_ALIGN_PAYLOAD - 1); + if (new_buf == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return false; + } + + // Offset the buffer such that the record body is aligned. + size_t new_offset = + (0 - header_len - (uintptr_t)new_buf) & (SSL3_ALIGN_PAYLOAD - 1); + + if (buf_ != NULL) { + OPENSSL_memcpy(new_buf + new_offset, buf_ + offset_, size_); + free(buf_); // Allocated with malloc(). + } + + buf_ = new_buf; + offset_ = new_offset; + cap_ = new_cap; + return true; +} + +void SSLBuffer::DidWrite(size_t new_size) { + if (new_size > cap() - size()) { + abort(); + } + size_ += new_size; +} + +void SSLBuffer::Consume(size_t len) { + if (len > size_) { + abort(); + } + offset_ += (uint16_t)len; + size_ -= (uint16_t)len; + cap_ -= (uint16_t)len; +} + +void SSLBuffer::DiscardConsumed() { + if (size_ == 0) { + Clear(); + } +} + +static int dtls_read_buffer_next_packet(SSL *ssl) { + SSLBuffer *buf = &ssl->s3->read_buffer; + + if (!buf->empty()) { + // It is an error to call |dtls_read_buffer_extend| when the read buffer is + // not empty. + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return -1; + } + + // Read a single packet from |ssl->rbio|. |buf->cap()| must fit in an int. + int ret = BIO_read(ssl->rbio, buf->data(), static_cast(buf->cap())); + if (ret <= 0) { + ssl->s3->rwstate = SSL_READING; + return ret; + } + buf->DidWrite(static_cast(ret)); + return 1; +} + +static int tls_read_buffer_extend_to(SSL *ssl, size_t len) { + SSLBuffer *buf = &ssl->s3->read_buffer; + + if (len > buf->cap()) { + OPENSSL_PUT_ERROR(SSL, SSL_R_BUFFER_TOO_SMALL); + return -1; + } + + // Read until the target length is reached. + while (buf->size() < len) { + // The amount of data to read is bounded by |buf->cap|, which must fit in an + // int. + int ret = BIO_read(ssl->rbio, buf->data() + buf->size(), + static_cast(len - buf->size())); + if (ret <= 0) { + ssl->s3->rwstate = SSL_READING; + return ret; + } + buf->DidWrite(static_cast(ret)); + } + + return 1; +} + +int ssl_read_buffer_extend_to(SSL *ssl, size_t len) { + // |ssl_read_buffer_extend_to| implicitly discards any consumed data. + ssl->s3->read_buffer.DiscardConsumed(); + + if (SSL_is_dtls(ssl)) { + static_assert( + DTLS1_RT_HEADER_LENGTH + SSL3_RT_MAX_ENCRYPTED_LENGTH <= 0xffff, + "DTLS read buffer is too large"); + + // The |len| parameter is ignored in DTLS. + len = DTLS1_RT_HEADER_LENGTH + SSL3_RT_MAX_ENCRYPTED_LENGTH; + } + + if (!ssl->s3->read_buffer.EnsureCap(ssl_record_prefix_len(ssl), len)) { + return -1; + } + + if (ssl->rbio == NULL) { + OPENSSL_PUT_ERROR(SSL, SSL_R_BIO_NOT_SET); + return -1; + } + + int ret; + if (SSL_is_dtls(ssl)) { + // |len| is ignored for a datagram transport. + ret = dtls_read_buffer_next_packet(ssl); + } else { + ret = tls_read_buffer_extend_to(ssl, len); + } + + if (ret <= 0) { + // If the buffer was empty originally and remained empty after attempting to + // extend it, release the buffer until the next attempt. + ssl->s3->read_buffer.DiscardConsumed(); + } + return ret; +} + +int ssl_handle_open_record(SSL *ssl, bool *out_retry, ssl_open_record_t ret, + size_t consumed, uint8_t alert) { + *out_retry = false; + if (ret != ssl_open_record_partial) { + ssl->s3->read_buffer.Consume(consumed); + } + if (ret != ssl_open_record_success) { + // Nothing was returned to the caller, so discard anything marked consumed. + ssl->s3->read_buffer.DiscardConsumed(); + } + switch (ret) { + case ssl_open_record_success: + return 1; + + case ssl_open_record_partial: { + int read_ret = ssl_read_buffer_extend_to(ssl, consumed); + if (read_ret <= 0) { + return read_ret; + } + *out_retry = true; + return 1; + } + + case ssl_open_record_discard: + *out_retry = true; + return 1; + + case ssl_open_record_close_notify: + return 0; + + case ssl_open_record_error: + if (alert != 0) { + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + } + return -1; + } + assert(0); + return -1; +} + + +static_assert(SSL3_RT_HEADER_LENGTH * 2 + + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD * 2 + + SSL3_RT_MAX_PLAIN_LENGTH <= + 0xffff, + "maximum TLS write buffer is too large"); + +static_assert(DTLS1_RT_HEADER_LENGTH + SSL3_RT_SEND_MAX_ENCRYPTED_OVERHEAD + + SSL3_RT_MAX_PLAIN_LENGTH <= + 0xffff, + "maximum DTLS write buffer is too large"); + +static int tls_write_buffer_flush(SSL *ssl) { + SSLBuffer *buf = &ssl->s3->write_buffer; + + while (!buf->empty()) { + int ret = BIO_write(ssl->wbio, buf->data(), buf->size()); + if (ret <= 0) { + ssl->s3->rwstate = SSL_WRITING; + return ret; + } + buf->Consume(static_cast(ret)); + } + buf->Clear(); + return 1; +} + +static int dtls_write_buffer_flush(SSL *ssl) { + SSLBuffer *buf = &ssl->s3->write_buffer; + if (buf->empty()) { + return 1; + } + + int ret = BIO_write(ssl->wbio, buf->data(), buf->size()); + if (ret <= 0) { + ssl->s3->rwstate = SSL_WRITING; + // If the write failed, drop the write buffer anyway. Datagram transports + // can't write half a packet, so the caller is expected to retry from the + // top. + buf->Clear(); + return ret; + } + buf->Clear(); + return 1; +} + +int ssl_write_buffer_flush(SSL *ssl) { + if (ssl->wbio == NULL) { + OPENSSL_PUT_ERROR(SSL, SSL_R_BIO_NOT_SET); + return -1; + } + + if (SSL_is_dtls(ssl)) { + return dtls_write_buffer_flush(ssl); + } else { + return tls_write_buffer_flush(ssl); + } +} + +} // namespace bssl diff --git a/FoodApp/Pods/BoringSSL-GRPC/ssl/ssl_cert.cc b/FoodApp/Pods/BoringSSL-GRPC/ssl/ssl_cert.cc new file mode 100644 index 0000000..a0862d9 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/ssl/ssl_cert.cc @@ -0,0 +1,913 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../crypto/internal.h" +#include "internal.h" + + +namespace bssl { + +CERT *ssl_cert_new(const SSL_X509_METHOD *x509_method) { + CERT *ret = (CERT *)OPENSSL_malloc(sizeof(CERT)); + if (ret == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return NULL; + } + OPENSSL_memset(ret, 0, sizeof(CERT)); + ret->x509_method = x509_method; + + return ret; +} + +static CRYPTO_BUFFER *buffer_up_ref(CRYPTO_BUFFER *buffer) { + CRYPTO_BUFFER_up_ref(buffer); + return buffer; +} + +CERT *ssl_cert_dup(CERT *cert) { + CERT *ret = (CERT *)OPENSSL_malloc(sizeof(CERT)); + if (ret == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return NULL; + } + OPENSSL_memset(ret, 0, sizeof(CERT)); + + ret->chain = sk_CRYPTO_BUFFER_deep_copy(cert->chain, buffer_up_ref, + CRYPTO_BUFFER_free); + + if (cert->privatekey != NULL) { + EVP_PKEY_up_ref(cert->privatekey); + ret->privatekey = cert->privatekey; + } + + ret->key_method = cert->key_method; + ret->x509_method = cert->x509_method; + + if (cert->sigalgs != NULL) { + ret->sigalgs = (uint16_t *)BUF_memdup( + cert->sigalgs, cert->num_sigalgs * sizeof(cert->sigalgs[0])); + if (ret->sigalgs == NULL) { + goto err; + } + } + ret->num_sigalgs = cert->num_sigalgs; + + ret->cert_cb = cert->cert_cb; + ret->cert_cb_arg = cert->cert_cb_arg; + + ret->x509_method->cert_dup(ret, cert); + + if (cert->signed_cert_timestamp_list != NULL) { + CRYPTO_BUFFER_up_ref(cert->signed_cert_timestamp_list); + ret->signed_cert_timestamp_list = cert->signed_cert_timestamp_list; + } + + if (cert->ocsp_response != NULL) { + CRYPTO_BUFFER_up_ref(cert->ocsp_response); + ret->ocsp_response = cert->ocsp_response; + } + + ret->sid_ctx_length = cert->sid_ctx_length; + OPENSSL_memcpy(ret->sid_ctx, cert->sid_ctx, sizeof(ret->sid_ctx)); + + ret->enable_early_data = cert->enable_early_data; + + return ret; + +err: + ssl_cert_free(ret); + return NULL; +} + +// Free up and clear all certificates and chains +void ssl_cert_clear_certs(CERT *cert) { + if (cert == NULL) { + return; + } + + cert->x509_method->cert_clear(cert); + + sk_CRYPTO_BUFFER_pop_free(cert->chain, CRYPTO_BUFFER_free); + cert->chain = NULL; + EVP_PKEY_free(cert->privatekey); + cert->privatekey = NULL; + cert->key_method = NULL; +} + +void ssl_cert_free(CERT *cert) { + if (cert == NULL) { + return; + } + + ssl_cert_clear_certs(cert); + cert->x509_method->cert_free(cert); + OPENSSL_free(cert->sigalgs); + CRYPTO_BUFFER_free(cert->signed_cert_timestamp_list); + CRYPTO_BUFFER_free(cert->ocsp_response); + + OPENSSL_free(cert); +} + +static void ssl_cert_set_cert_cb(CERT *cert, int (*cb)(SSL *ssl, void *arg), + void *arg) { + cert->cert_cb = cb; + cert->cert_cb_arg = arg; +} + +enum leaf_cert_and_privkey_result_t { + leaf_cert_and_privkey_error, + leaf_cert_and_privkey_ok, + leaf_cert_and_privkey_mismatch, +}; + +// check_leaf_cert_and_privkey checks whether the certificate in |leaf_buffer| +// and the private key in |privkey| are suitable and coherent. It returns +// |leaf_cert_and_privkey_error| and pushes to the error queue if a problem is +// found. If the certificate and private key are valid, but incoherent, it +// returns |leaf_cert_and_privkey_mismatch|. Otherwise it returns +// |leaf_cert_and_privkey_ok|. +static enum leaf_cert_and_privkey_result_t check_leaf_cert_and_privkey( + CRYPTO_BUFFER *leaf_buffer, EVP_PKEY *privkey) { + CBS cert_cbs; + CRYPTO_BUFFER_init_CBS(leaf_buffer, &cert_cbs); + UniquePtr pubkey = ssl_cert_parse_pubkey(&cert_cbs); + if (!pubkey) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + return leaf_cert_and_privkey_error; + } + + if (!ssl_is_key_type_supported(pubkey->type)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_CERTIFICATE_TYPE); + return leaf_cert_and_privkey_error; + } + + // An ECC certificate may be usable for ECDH or ECDSA. We only support ECDSA + // certificates, so sanity-check the key usage extension. + if (pubkey->type == EVP_PKEY_EC && + !ssl_cert_check_digital_signature_key_usage(&cert_cbs)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_CERTIFICATE_TYPE); + return leaf_cert_and_privkey_error; + } + + if (privkey != NULL && + // Sanity-check that the private key and the certificate match. + !ssl_compare_public_and_private_key(pubkey.get(), privkey)) { + ERR_clear_error(); + return leaf_cert_and_privkey_mismatch; + } + + return leaf_cert_and_privkey_ok; +} + +static int cert_set_chain_and_key( + CERT *cert, CRYPTO_BUFFER *const *certs, size_t num_certs, + EVP_PKEY *privkey, const SSL_PRIVATE_KEY_METHOD *privkey_method) { + if (num_certs == 0 || + (privkey == NULL && privkey_method == NULL)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + if (privkey != NULL && privkey_method != NULL) { + OPENSSL_PUT_ERROR(SSL, SSL_R_CANNOT_HAVE_BOTH_PRIVKEY_AND_METHOD); + return 0; + } + + switch (check_leaf_cert_and_privkey(certs[0], privkey)) { + case leaf_cert_and_privkey_error: + return 0; + case leaf_cert_and_privkey_mismatch: + OPENSSL_PUT_ERROR(SSL, SSL_R_CERTIFICATE_AND_PRIVATE_KEY_MISMATCH); + return 0; + case leaf_cert_and_privkey_ok: + break; + } + + STACK_OF(CRYPTO_BUFFER) *certs_sk = sk_CRYPTO_BUFFER_new_null(); + if (certs_sk == NULL) { + return 0; + } + + for (size_t i = 0; i < num_certs; i++) { + if (!sk_CRYPTO_BUFFER_push(certs_sk, certs[i])) { + sk_CRYPTO_BUFFER_pop_free(certs_sk, CRYPTO_BUFFER_free); + return 0; + } + CRYPTO_BUFFER_up_ref(certs[i]); + } + + EVP_PKEY_free(cert->privatekey); + cert->privatekey = privkey; + if (privkey != NULL) { + EVP_PKEY_up_ref(privkey); + } + cert->key_method = privkey_method; + + sk_CRYPTO_BUFFER_pop_free(cert->chain, CRYPTO_BUFFER_free); + cert->chain = certs_sk; + + return 1; +} + +int ssl_set_cert(CERT *cert, UniquePtr buffer) { + switch (check_leaf_cert_and_privkey(buffer.get(), cert->privatekey)) { + case leaf_cert_and_privkey_error: + return 0; + case leaf_cert_and_privkey_mismatch: + // 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(cert->privatekey); + cert->privatekey = NULL; + break; + case leaf_cert_and_privkey_ok: + break; + } + + cert->x509_method->cert_flush_cached_leaf(cert); + + if (cert->chain != NULL) { + CRYPTO_BUFFER_free(sk_CRYPTO_BUFFER_value(cert->chain, 0)); + sk_CRYPTO_BUFFER_set(cert->chain, 0, buffer.release()); + return 1; + } + + cert->chain = sk_CRYPTO_BUFFER_new_null(); + if (cert->chain == NULL) { + return 0; + } + + if (!PushToStack(cert->chain, std::move(buffer))) { + sk_CRYPTO_BUFFER_free(cert->chain); + cert->chain = NULL; + return 0; + } + + return 1; +} + +int ssl_has_certificate(const SSL *ssl) { + return ssl->cert->chain != NULL && + sk_CRYPTO_BUFFER_value(ssl->cert->chain, 0) != NULL && + ssl_has_private_key(ssl); +} + +bool ssl_parse_cert_chain(uint8_t *out_alert, + UniquePtr *out_chain, + UniquePtr *out_pubkey, + uint8_t *out_leaf_sha256, CBS *cbs, + CRYPTO_BUFFER_POOL *pool) { + out_chain->reset(); + out_pubkey->reset(); + + CBS certificate_list; + if (!CBS_get_u24_length_prefixed(cbs, &certificate_list)) { + *out_alert = SSL_AD_DECODE_ERROR; + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + return false; + } + + if (CBS_len(&certificate_list) == 0) { + return true; + } + + UniquePtr chain(sk_CRYPTO_BUFFER_new_null()); + if (!chain) { + *out_alert = SSL_AD_INTERNAL_ERROR; + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return false; + } + + UniquePtr pubkey; + while (CBS_len(&certificate_list) > 0) { + CBS certificate; + if (!CBS_get_u24_length_prefixed(&certificate_list, &certificate) || + CBS_len(&certificate) == 0) { + *out_alert = SSL_AD_DECODE_ERROR; + OPENSSL_PUT_ERROR(SSL, SSL_R_CERT_LENGTH_MISMATCH); + return false; + } + + if (sk_CRYPTO_BUFFER_num(chain.get()) == 0) { + pubkey = ssl_cert_parse_pubkey(&certificate); + if (!pubkey) { + *out_alert = SSL_AD_DECODE_ERROR; + return false; + } + + // Retain the hash of the leaf certificate if requested. + if (out_leaf_sha256 != NULL) { + SHA256(CBS_data(&certificate), CBS_len(&certificate), out_leaf_sha256); + } + } + + UniquePtr buf( + CRYPTO_BUFFER_new_from_CBS(&certificate, pool)); + if (!buf || + !PushToStack(chain.get(), std::move(buf))) { + *out_alert = SSL_AD_INTERNAL_ERROR; + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return false; + } + } + + *out_chain = std::move(chain); + *out_pubkey = std::move(pubkey); + return true; +} + +int ssl_add_cert_chain(SSL *ssl, CBB *cbb) { + if (!ssl_has_certificate(ssl)) { + return CBB_add_u24(cbb, 0); + } + + CBB certs; + if (!CBB_add_u24_length_prefixed(cbb, &certs)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return 0; + } + + STACK_OF(CRYPTO_BUFFER) *chain = ssl->cert->chain; + for (size_t i = 0; i < sk_CRYPTO_BUFFER_num(chain); i++) { + CRYPTO_BUFFER *buffer = sk_CRYPTO_BUFFER_value(chain, i); + CBB child; + if (!CBB_add_u24_length_prefixed(&certs, &child) || + !CBB_add_bytes(&child, CRYPTO_BUFFER_data(buffer), + CRYPTO_BUFFER_len(buffer)) || + !CBB_flush(&certs)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return 0; + } + } + + return CBB_flush(cbb); +} + +// ssl_cert_skip_to_spki parses a DER-encoded, X.509 certificate from |in| and +// positions |*out_tbs_cert| to cover the TBSCertificate, starting at the +// subjectPublicKeyInfo. +static int ssl_cert_skip_to_spki(const CBS *in, CBS *out_tbs_cert) { + /* From RFC 5280, section 4.1 + * Certificate ::= SEQUENCE { + * tbsCertificate TBSCertificate, + * signatureAlgorithm AlgorithmIdentifier, + * signatureValue BIT STRING } + + * TBSCertificate ::= SEQUENCE { + * version [0] EXPLICIT Version DEFAULT v1, + * serialNumber CertificateSerialNumber, + * signature AlgorithmIdentifier, + * issuer Name, + * validity Validity, + * subject Name, + * subjectPublicKeyInfo SubjectPublicKeyInfo, + * ... } */ + CBS buf = *in; + + CBS toplevel; + if (!CBS_get_asn1(&buf, &toplevel, CBS_ASN1_SEQUENCE) || + CBS_len(&buf) != 0 || + !CBS_get_asn1(&toplevel, out_tbs_cert, CBS_ASN1_SEQUENCE) || + // version + !CBS_get_optional_asn1( + out_tbs_cert, NULL, NULL, + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 0) || + // serialNumber + !CBS_get_asn1(out_tbs_cert, NULL, CBS_ASN1_INTEGER) || + // signature algorithm + !CBS_get_asn1(out_tbs_cert, NULL, CBS_ASN1_SEQUENCE) || + // issuer + !CBS_get_asn1(out_tbs_cert, NULL, CBS_ASN1_SEQUENCE) || + // validity + !CBS_get_asn1(out_tbs_cert, NULL, CBS_ASN1_SEQUENCE) || + // subject + !CBS_get_asn1(out_tbs_cert, NULL, CBS_ASN1_SEQUENCE)) { + return 0; + } + + return 1; +} + +UniquePtr ssl_cert_parse_pubkey(const CBS *in) { + CBS buf = *in, tbs_cert; + if (!ssl_cert_skip_to_spki(&buf, &tbs_cert)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_CANNOT_PARSE_LEAF_CERT); + return nullptr; + } + + return UniquePtr(EVP_parse_public_key(&tbs_cert)); +} + +int ssl_compare_public_and_private_key(const EVP_PKEY *pubkey, + const EVP_PKEY *privkey) { + if (EVP_PKEY_is_opaque(privkey)) { + // We cannot check an opaque private key and have to trust that it + // matches. + return 1; + } + + int ret = 0; + + switch (EVP_PKEY_cmp(pubkey, privkey)) { + case 1: + ret = 1; + break; + case 0: + OPENSSL_PUT_ERROR(X509, X509_R_KEY_VALUES_MISMATCH); + break; + case -1: + OPENSSL_PUT_ERROR(X509, X509_R_KEY_TYPE_MISMATCH); + break; + case -2: + OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_KEY_TYPE); + break; + default: + assert(0); + break; + } + + return ret; +} + +int ssl_cert_check_private_key(const CERT *cert, const EVP_PKEY *privkey) { + if (privkey == NULL) { + OPENSSL_PUT_ERROR(SSL, SSL_R_NO_PRIVATE_KEY_ASSIGNED); + return 0; + } + + if (cert->chain == NULL || + sk_CRYPTO_BUFFER_value(cert->chain, 0) == NULL) { + OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CERTIFICATE_ASSIGNED); + return 0; + } + + CBS cert_cbs; + CRYPTO_BUFFER_init_CBS(sk_CRYPTO_BUFFER_value(cert->chain, 0), &cert_cbs); + UniquePtr pubkey = ssl_cert_parse_pubkey(&cert_cbs); + if (!pubkey) { + OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_KEY_TYPE); + return 0; + } + + return ssl_compare_public_and_private_key(pubkey.get(), privkey); +} + +int ssl_cert_check_digital_signature_key_usage(const CBS *in) { + CBS buf = *in; + + CBS tbs_cert, outer_extensions; + int has_extensions; + if (!ssl_cert_skip_to_spki(&buf, &tbs_cert) || + // subjectPublicKeyInfo + !CBS_get_asn1(&tbs_cert, NULL, CBS_ASN1_SEQUENCE) || + // issuerUniqueID + !CBS_get_optional_asn1( + &tbs_cert, NULL, NULL, + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 1) || + // subjectUniqueID + !CBS_get_optional_asn1( + &tbs_cert, NULL, NULL, + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 2) || + !CBS_get_optional_asn1( + &tbs_cert, &outer_extensions, &has_extensions, + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 3)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_CANNOT_PARSE_LEAF_CERT); + return 0; + } + + if (!has_extensions) { + return 1; + } + + CBS extensions; + if (!CBS_get_asn1(&outer_extensions, &extensions, CBS_ASN1_SEQUENCE)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_CANNOT_PARSE_LEAF_CERT); + return 0; + } + + while (CBS_len(&extensions) > 0) { + CBS extension, oid, contents; + if (!CBS_get_asn1(&extensions, &extension, CBS_ASN1_SEQUENCE) || + !CBS_get_asn1(&extension, &oid, CBS_ASN1_OBJECT) || + (CBS_peek_asn1_tag(&extension, CBS_ASN1_BOOLEAN) && + !CBS_get_asn1(&extension, NULL, CBS_ASN1_BOOLEAN)) || + !CBS_get_asn1(&extension, &contents, CBS_ASN1_OCTETSTRING) || + CBS_len(&extension) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_CANNOT_PARSE_LEAF_CERT); + return 0; + } + + static const uint8_t kKeyUsageOID[3] = {0x55, 0x1d, 0x0f}; + if (CBS_len(&oid) != sizeof(kKeyUsageOID) || + OPENSSL_memcmp(CBS_data(&oid), kKeyUsageOID, sizeof(kKeyUsageOID)) != + 0) { + continue; + } + + CBS bit_string; + if (!CBS_get_asn1(&contents, &bit_string, CBS_ASN1_BITSTRING) || + CBS_len(&contents) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_CANNOT_PARSE_LEAF_CERT); + return 0; + } + + // This is the KeyUsage extension. See + // https://tools.ietf.org/html/rfc5280#section-4.2.1.3 + if (!CBS_is_valid_asn1_bitstring(&bit_string)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_CANNOT_PARSE_LEAF_CERT); + return 0; + } + + if (!CBS_asn1_bitstring_has_bit(&bit_string, 0)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_ECC_CERT_NOT_FOR_SIGNING); + return 0; + } + + return 1; + } + + // No KeyUsage extension found. + return 1; +} + +UniquePtr ssl_parse_client_CA_list(SSL *ssl, + uint8_t *out_alert, + CBS *cbs) { + CRYPTO_BUFFER_POOL *const pool = ssl->ctx->pool; + + UniquePtr ret(sk_CRYPTO_BUFFER_new_null()); + if (!ret) { + *out_alert = SSL_AD_INTERNAL_ERROR; + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return nullptr; + } + + CBS child; + if (!CBS_get_u16_length_prefixed(cbs, &child)) { + *out_alert = SSL_AD_DECODE_ERROR; + OPENSSL_PUT_ERROR(SSL, SSL_R_LENGTH_MISMATCH); + return nullptr; + } + + while (CBS_len(&child) > 0) { + CBS distinguished_name; + if (!CBS_get_u16_length_prefixed(&child, &distinguished_name)) { + *out_alert = SSL_AD_DECODE_ERROR; + OPENSSL_PUT_ERROR(SSL, SSL_R_CA_DN_TOO_LONG); + return nullptr; + } + + UniquePtr buffer( + CRYPTO_BUFFER_new_from_CBS(&distinguished_name, pool)); + if (!buffer || + !PushToStack(ret.get(), std::move(buffer))) { + *out_alert = SSL_AD_INTERNAL_ERROR; + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return nullptr; + } + } + + if (!ssl->ctx->x509_method->check_client_CA_list(ret.get())) { + *out_alert = SSL_AD_INTERNAL_ERROR; + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + return nullptr; + } + + return ret; +} + +bool ssl_has_client_CAs(SSL *ssl) { + STACK_OF(CRYPTO_BUFFER) *names = ssl->client_CA; + if (names == NULL) { + names = ssl->ctx->client_CA; + } + if (names == NULL) { + return false; + } + return sk_CRYPTO_BUFFER_num(names) > 0; +} + +int ssl_add_client_CA_list(SSL *ssl, CBB *cbb) { + CBB child, name_cbb; + if (!CBB_add_u16_length_prefixed(cbb, &child)) { + return 0; + } + + STACK_OF(CRYPTO_BUFFER) *names = ssl->client_CA; + if (names == NULL) { + names = ssl->ctx->client_CA; + } + if (names == NULL) { + return CBB_flush(cbb); + } + + for (const CRYPTO_BUFFER *name : names) { + if (!CBB_add_u16_length_prefixed(&child, &name_cbb) || + !CBB_add_bytes(&name_cbb, CRYPTO_BUFFER_data(name), + CRYPTO_BUFFER_len(name))) { + return 0; + } + } + + return CBB_flush(cbb); +} + +int ssl_check_leaf_certificate(SSL_HANDSHAKE *hs, EVP_PKEY *pkey, + const CRYPTO_BUFFER *leaf) { + SSL *const ssl = hs->ssl; + assert(ssl_protocol_version(ssl) < TLS1_3_VERSION); + + // Check the certificate's type matches the cipher. + if (!(hs->new_cipher->algorithm_auth & ssl_cipher_auth_mask_for_key(pkey))) { + OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CERTIFICATE_TYPE); + return 0; + } + + // Check key usages for all key types but RSA. This is needed to distinguish + // ECDH certificates, which we do not support, from ECDSA certificates. In + // principle, we should check RSA key usages based on cipher, but this breaks + // buggy antivirus deployments. Other key types are always used for signing. + // + // TODO(davidben): Get more recent data on RSA key usages. + if (EVP_PKEY_id(pkey) != EVP_PKEY_RSA) { + CBS leaf_cbs; + CBS_init(&leaf_cbs, CRYPTO_BUFFER_data(leaf), CRYPTO_BUFFER_len(leaf)); + if (!ssl_cert_check_digital_signature_key_usage(&leaf_cbs)) { + return 0; + } + } + + if (EVP_PKEY_id(pkey) == EVP_PKEY_EC) { + // Check the key's group and point format are acceptable. + EC_KEY *ec_key = EVP_PKEY_get0_EC_KEY(pkey); + uint16_t group_id; + if (!ssl_nid_to_group_id( + &group_id, EC_GROUP_get_curve_name(EC_KEY_get0_group(ec_key))) || + !tls1_check_group_id(ssl, group_id) || + EC_KEY_get_conv_form(ec_key) != POINT_CONVERSION_UNCOMPRESSED) { + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_ECC_CERT); + return 0; + } + } + + return 1; +} + +int ssl_on_certificate_selected(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + if (!ssl_has_certificate(ssl)) { + // Nothing to do. + return 1; + } + + if (!ssl->ctx->x509_method->ssl_auto_chain_if_needed(ssl)) { + return 0; + } + + CBS leaf; + CRYPTO_BUFFER_init_CBS(sk_CRYPTO_BUFFER_value(ssl->cert->chain, 0), &leaf); + + hs->local_pubkey = ssl_cert_parse_pubkey(&leaf); + return hs->local_pubkey != NULL; +} + +} // namespace bssl + +using namespace bssl; + +int SSL_set_chain_and_key(SSL *ssl, CRYPTO_BUFFER *const *certs, + size_t num_certs, EVP_PKEY *privkey, + const SSL_PRIVATE_KEY_METHOD *privkey_method) { + return cert_set_chain_and_key(ssl->cert, certs, num_certs, privkey, + privkey_method); +} + +int SSL_CTX_set_chain_and_key(SSL_CTX *ctx, CRYPTO_BUFFER *const *certs, + size_t num_certs, EVP_PKEY *privkey, + const SSL_PRIVATE_KEY_METHOD *privkey_method) { + return cert_set_chain_and_key(ctx->cert, certs, num_certs, privkey, + privkey_method); +} + +int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, size_t der_len, + const uint8_t *der) { + UniquePtr buffer(CRYPTO_BUFFER_new(der, der_len, NULL)); + if (!buffer) { + return 0; + } + + return ssl_set_cert(ctx->cert, std::move(buffer)); +} + +int SSL_use_certificate_ASN1(SSL *ssl, const uint8_t *der, size_t der_len) { + UniquePtr buffer(CRYPTO_BUFFER_new(der, der_len, NULL)); + if (!buffer) { + return 0; + } + + return ssl_set_cert(ssl->cert, std::move(buffer)); +} + +void SSL_CTX_set_cert_cb(SSL_CTX *ctx, int (*cb)(SSL *ssl, void *arg), + void *arg) { + ssl_cert_set_cert_cb(ctx->cert, cb, arg); +} + +void SSL_set_cert_cb(SSL *ssl, int (*cb)(SSL *ssl, void *arg), void *arg) { + ssl_cert_set_cert_cb(ssl->cert, cb, arg); +} + +STACK_OF(CRYPTO_BUFFER) *SSL_get0_peer_certificates(const SSL *ssl) { + SSL_SESSION *session = SSL_get_session(ssl); + if (session == NULL) { + return NULL; + } + + return session->certs; +} + +STACK_OF(CRYPTO_BUFFER) *SSL_get0_server_requested_CAs(const SSL *ssl) { + if (ssl->s3->hs == NULL) { + return NULL; + } + return ssl->s3->hs->ca_names.get(); +} + +static int set_signed_cert_timestamp_list(CERT *cert, const uint8_t *list, + size_t list_len) { + CBS sct_list; + CBS_init(&sct_list, list, list_len); + if (!ssl_is_sct_list_valid(&sct_list)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SCT_LIST); + return 0; + } + + CRYPTO_BUFFER_free(cert->signed_cert_timestamp_list); + cert->signed_cert_timestamp_list = + CRYPTO_BUFFER_new(CBS_data(&sct_list), CBS_len(&sct_list), NULL); + return cert->signed_cert_timestamp_list != NULL; +} + +int SSL_CTX_set_signed_cert_timestamp_list(SSL_CTX *ctx, const uint8_t *list, + size_t list_len) { + return set_signed_cert_timestamp_list(ctx->cert, list, list_len); +} + +int SSL_set_signed_cert_timestamp_list(SSL *ssl, const uint8_t *list, + size_t list_len) { + return set_signed_cert_timestamp_list(ssl->cert, list, list_len); +} + +int SSL_CTX_set_ocsp_response(SSL_CTX *ctx, const uint8_t *response, + size_t response_len) { + CRYPTO_BUFFER_free(ctx->cert->ocsp_response); + ctx->cert->ocsp_response = CRYPTO_BUFFER_new(response, response_len, NULL); + return ctx->cert->ocsp_response != NULL; +} + +int SSL_set_ocsp_response(SSL *ssl, const uint8_t *response, + size_t response_len) { + CRYPTO_BUFFER_free(ssl->cert->ocsp_response); + ssl->cert->ocsp_response = CRYPTO_BUFFER_new(response, response_len, NULL); + return ssl->cert->ocsp_response != NULL; +} + +void SSL_CTX_set0_client_CAs(SSL_CTX *ctx, STACK_OF(CRYPTO_BUFFER) *name_list) { + ctx->x509_method->ssl_ctx_flush_cached_client_CA(ctx); + sk_CRYPTO_BUFFER_pop_free(ctx->client_CA, CRYPTO_BUFFER_free); + ctx->client_CA = name_list; +} + +void SSL_set0_client_CAs(SSL *ssl, STACK_OF(CRYPTO_BUFFER) *name_list) { + ssl->ctx->x509_method->ssl_flush_cached_client_CA(ssl); + sk_CRYPTO_BUFFER_pop_free(ssl->client_CA, CRYPTO_BUFFER_free); + ssl->client_CA = name_list; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/ssl/ssl_cert.cc.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/ssl/ssl_cert.cc.grpc_back new file mode 100644 index 0000000..9a3eef3 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/ssl/ssl_cert.cc.grpc_back @@ -0,0 +1,913 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../crypto/internal.h" +#include "internal.h" + + +namespace bssl { + +CERT *ssl_cert_new(const SSL_X509_METHOD *x509_method) { + CERT *ret = (CERT *)OPENSSL_malloc(sizeof(CERT)); + if (ret == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return NULL; + } + OPENSSL_memset(ret, 0, sizeof(CERT)); + ret->x509_method = x509_method; + + return ret; +} + +static CRYPTO_BUFFER *buffer_up_ref(CRYPTO_BUFFER *buffer) { + CRYPTO_BUFFER_up_ref(buffer); + return buffer; +} + +CERT *ssl_cert_dup(CERT *cert) { + CERT *ret = (CERT *)OPENSSL_malloc(sizeof(CERT)); + if (ret == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return NULL; + } + OPENSSL_memset(ret, 0, sizeof(CERT)); + + ret->chain = sk_CRYPTO_BUFFER_deep_copy(cert->chain, buffer_up_ref, + CRYPTO_BUFFER_free); + + if (cert->privatekey != NULL) { + EVP_PKEY_up_ref(cert->privatekey); + ret->privatekey = cert->privatekey; + } + + ret->key_method = cert->key_method; + ret->x509_method = cert->x509_method; + + if (cert->sigalgs != NULL) { + ret->sigalgs = (uint16_t *)BUF_memdup( + cert->sigalgs, cert->num_sigalgs * sizeof(cert->sigalgs[0])); + if (ret->sigalgs == NULL) { + goto err; + } + } + ret->num_sigalgs = cert->num_sigalgs; + + ret->cert_cb = cert->cert_cb; + ret->cert_cb_arg = cert->cert_cb_arg; + + ret->x509_method->cert_dup(ret, cert); + + if (cert->signed_cert_timestamp_list != NULL) { + CRYPTO_BUFFER_up_ref(cert->signed_cert_timestamp_list); + ret->signed_cert_timestamp_list = cert->signed_cert_timestamp_list; + } + + if (cert->ocsp_response != NULL) { + CRYPTO_BUFFER_up_ref(cert->ocsp_response); + ret->ocsp_response = cert->ocsp_response; + } + + ret->sid_ctx_length = cert->sid_ctx_length; + OPENSSL_memcpy(ret->sid_ctx, cert->sid_ctx, sizeof(ret->sid_ctx)); + + ret->enable_early_data = cert->enable_early_data; + + return ret; + +err: + ssl_cert_free(ret); + return NULL; +} + +// Free up and clear all certificates and chains +void ssl_cert_clear_certs(CERT *cert) { + if (cert == NULL) { + return; + } + + cert->x509_method->cert_clear(cert); + + sk_CRYPTO_BUFFER_pop_free(cert->chain, CRYPTO_BUFFER_free); + cert->chain = NULL; + EVP_PKEY_free(cert->privatekey); + cert->privatekey = NULL; + cert->key_method = NULL; +} + +void ssl_cert_free(CERT *cert) { + if (cert == NULL) { + return; + } + + ssl_cert_clear_certs(cert); + cert->x509_method->cert_free(cert); + OPENSSL_free(cert->sigalgs); + CRYPTO_BUFFER_free(cert->signed_cert_timestamp_list); + CRYPTO_BUFFER_free(cert->ocsp_response); + + OPENSSL_free(cert); +} + +static void ssl_cert_set_cert_cb(CERT *cert, int (*cb)(SSL *ssl, void *arg), + void *arg) { + cert->cert_cb = cb; + cert->cert_cb_arg = arg; +} + +enum leaf_cert_and_privkey_result_t { + leaf_cert_and_privkey_error, + leaf_cert_and_privkey_ok, + leaf_cert_and_privkey_mismatch, +}; + +// check_leaf_cert_and_privkey checks whether the certificate in |leaf_buffer| +// and the private key in |privkey| are suitable and coherent. It returns +// |leaf_cert_and_privkey_error| and pushes to the error queue if a problem is +// found. If the certificate and private key are valid, but incoherent, it +// returns |leaf_cert_and_privkey_mismatch|. Otherwise it returns +// |leaf_cert_and_privkey_ok|. +static enum leaf_cert_and_privkey_result_t check_leaf_cert_and_privkey( + CRYPTO_BUFFER *leaf_buffer, EVP_PKEY *privkey) { + CBS cert_cbs; + CRYPTO_BUFFER_init_CBS(leaf_buffer, &cert_cbs); + UniquePtr pubkey = ssl_cert_parse_pubkey(&cert_cbs); + if (!pubkey) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + return leaf_cert_and_privkey_error; + } + + if (!ssl_is_key_type_supported(pubkey->type)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_CERTIFICATE_TYPE); + return leaf_cert_and_privkey_error; + } + + // An ECC certificate may be usable for ECDH or ECDSA. We only support ECDSA + // certificates, so sanity-check the key usage extension. + if (pubkey->type == EVP_PKEY_EC && + !ssl_cert_check_digital_signature_key_usage(&cert_cbs)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_CERTIFICATE_TYPE); + return leaf_cert_and_privkey_error; + } + + if (privkey != NULL && + // Sanity-check that the private key and the certificate match. + !ssl_compare_public_and_private_key(pubkey.get(), privkey)) { + ERR_clear_error(); + return leaf_cert_and_privkey_mismatch; + } + + return leaf_cert_and_privkey_ok; +} + +static int cert_set_chain_and_key( + CERT *cert, CRYPTO_BUFFER *const *certs, size_t num_certs, + EVP_PKEY *privkey, const SSL_PRIVATE_KEY_METHOD *privkey_method) { + if (num_certs == 0 || + (privkey == NULL && privkey_method == NULL)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + if (privkey != NULL && privkey_method != NULL) { + OPENSSL_PUT_ERROR(SSL, SSL_R_CANNOT_HAVE_BOTH_PRIVKEY_AND_METHOD); + return 0; + } + + switch (check_leaf_cert_and_privkey(certs[0], privkey)) { + case leaf_cert_and_privkey_error: + return 0; + case leaf_cert_and_privkey_mismatch: + OPENSSL_PUT_ERROR(SSL, SSL_R_CERTIFICATE_AND_PRIVATE_KEY_MISMATCH); + return 0; + case leaf_cert_and_privkey_ok: + break; + } + + STACK_OF(CRYPTO_BUFFER) *certs_sk = sk_CRYPTO_BUFFER_new_null(); + if (certs_sk == NULL) { + return 0; + } + + for (size_t i = 0; i < num_certs; i++) { + if (!sk_CRYPTO_BUFFER_push(certs_sk, certs[i])) { + sk_CRYPTO_BUFFER_pop_free(certs_sk, CRYPTO_BUFFER_free); + return 0; + } + CRYPTO_BUFFER_up_ref(certs[i]); + } + + EVP_PKEY_free(cert->privatekey); + cert->privatekey = privkey; + if (privkey != NULL) { + EVP_PKEY_up_ref(privkey); + } + cert->key_method = privkey_method; + + sk_CRYPTO_BUFFER_pop_free(cert->chain, CRYPTO_BUFFER_free); + cert->chain = certs_sk; + + return 1; +} + +int ssl_set_cert(CERT *cert, UniquePtr buffer) { + switch (check_leaf_cert_and_privkey(buffer.get(), cert->privatekey)) { + case leaf_cert_and_privkey_error: + return 0; + case leaf_cert_and_privkey_mismatch: + // 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(cert->privatekey); + cert->privatekey = NULL; + break; + case leaf_cert_and_privkey_ok: + break; + } + + cert->x509_method->cert_flush_cached_leaf(cert); + + if (cert->chain != NULL) { + CRYPTO_BUFFER_free(sk_CRYPTO_BUFFER_value(cert->chain, 0)); + sk_CRYPTO_BUFFER_set(cert->chain, 0, buffer.release()); + return 1; + } + + cert->chain = sk_CRYPTO_BUFFER_new_null(); + if (cert->chain == NULL) { + return 0; + } + + if (!PushToStack(cert->chain, std::move(buffer))) { + sk_CRYPTO_BUFFER_free(cert->chain); + cert->chain = NULL; + return 0; + } + + return 1; +} + +int ssl_has_certificate(const SSL *ssl) { + return ssl->cert->chain != NULL && + sk_CRYPTO_BUFFER_value(ssl->cert->chain, 0) != NULL && + ssl_has_private_key(ssl); +} + +bool ssl_parse_cert_chain(uint8_t *out_alert, + UniquePtr *out_chain, + UniquePtr *out_pubkey, + uint8_t *out_leaf_sha256, CBS *cbs, + CRYPTO_BUFFER_POOL *pool) { + out_chain->reset(); + out_pubkey->reset(); + + CBS certificate_list; + if (!CBS_get_u24_length_prefixed(cbs, &certificate_list)) { + *out_alert = SSL_AD_DECODE_ERROR; + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + return false; + } + + if (CBS_len(&certificate_list) == 0) { + return true; + } + + UniquePtr chain(sk_CRYPTO_BUFFER_new_null()); + if (!chain) { + *out_alert = SSL_AD_INTERNAL_ERROR; + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return false; + } + + UniquePtr pubkey; + while (CBS_len(&certificate_list) > 0) { + CBS certificate; + if (!CBS_get_u24_length_prefixed(&certificate_list, &certificate) || + CBS_len(&certificate) == 0) { + *out_alert = SSL_AD_DECODE_ERROR; + OPENSSL_PUT_ERROR(SSL, SSL_R_CERT_LENGTH_MISMATCH); + return false; + } + + if (sk_CRYPTO_BUFFER_num(chain.get()) == 0) { + pubkey = ssl_cert_parse_pubkey(&certificate); + if (!pubkey) { + *out_alert = SSL_AD_DECODE_ERROR; + return false; + } + + // Retain the hash of the leaf certificate if requested. + if (out_leaf_sha256 != NULL) { + SHA256(CBS_data(&certificate), CBS_len(&certificate), out_leaf_sha256); + } + } + + UniquePtr buf( + CRYPTO_BUFFER_new_from_CBS(&certificate, pool)); + if (!buf || + !PushToStack(chain.get(), std::move(buf))) { + *out_alert = SSL_AD_INTERNAL_ERROR; + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return false; + } + } + + *out_chain = std::move(chain); + *out_pubkey = std::move(pubkey); + return true; +} + +int ssl_add_cert_chain(SSL *ssl, CBB *cbb) { + if (!ssl_has_certificate(ssl)) { + return CBB_add_u24(cbb, 0); + } + + CBB certs; + if (!CBB_add_u24_length_prefixed(cbb, &certs)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return 0; + } + + STACK_OF(CRYPTO_BUFFER) *chain = ssl->cert->chain; + for (size_t i = 0; i < sk_CRYPTO_BUFFER_num(chain); i++) { + CRYPTO_BUFFER *buffer = sk_CRYPTO_BUFFER_value(chain, i); + CBB child; + if (!CBB_add_u24_length_prefixed(&certs, &child) || + !CBB_add_bytes(&child, CRYPTO_BUFFER_data(buffer), + CRYPTO_BUFFER_len(buffer)) || + !CBB_flush(&certs)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return 0; + } + } + + return CBB_flush(cbb); +} + +// ssl_cert_skip_to_spki parses a DER-encoded, X.509 certificate from |in| and +// positions |*out_tbs_cert| to cover the TBSCertificate, starting at the +// subjectPublicKeyInfo. +static int ssl_cert_skip_to_spki(const CBS *in, CBS *out_tbs_cert) { + /* From RFC 5280, section 4.1 + * Certificate ::= SEQUENCE { + * tbsCertificate TBSCertificate, + * signatureAlgorithm AlgorithmIdentifier, + * signatureValue BIT STRING } + + * TBSCertificate ::= SEQUENCE { + * version [0] EXPLICIT Version DEFAULT v1, + * serialNumber CertificateSerialNumber, + * signature AlgorithmIdentifier, + * issuer Name, + * validity Validity, + * subject Name, + * subjectPublicKeyInfo SubjectPublicKeyInfo, + * ... } */ + CBS buf = *in; + + CBS toplevel; + if (!CBS_get_asn1(&buf, &toplevel, CBS_ASN1_SEQUENCE) || + CBS_len(&buf) != 0 || + !CBS_get_asn1(&toplevel, out_tbs_cert, CBS_ASN1_SEQUENCE) || + // version + !CBS_get_optional_asn1( + out_tbs_cert, NULL, NULL, + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 0) || + // serialNumber + !CBS_get_asn1(out_tbs_cert, NULL, CBS_ASN1_INTEGER) || + // signature algorithm + !CBS_get_asn1(out_tbs_cert, NULL, CBS_ASN1_SEQUENCE) || + // issuer + !CBS_get_asn1(out_tbs_cert, NULL, CBS_ASN1_SEQUENCE) || + // validity + !CBS_get_asn1(out_tbs_cert, NULL, CBS_ASN1_SEQUENCE) || + // subject + !CBS_get_asn1(out_tbs_cert, NULL, CBS_ASN1_SEQUENCE)) { + return 0; + } + + return 1; +} + +UniquePtr ssl_cert_parse_pubkey(const CBS *in) { + CBS buf = *in, tbs_cert; + if (!ssl_cert_skip_to_spki(&buf, &tbs_cert)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_CANNOT_PARSE_LEAF_CERT); + return nullptr; + } + + return UniquePtr(EVP_parse_public_key(&tbs_cert)); +} + +int ssl_compare_public_and_private_key(const EVP_PKEY *pubkey, + const EVP_PKEY *privkey) { + if (EVP_PKEY_is_opaque(privkey)) { + // We cannot check an opaque private key and have to trust that it + // matches. + return 1; + } + + int ret = 0; + + switch (EVP_PKEY_cmp(pubkey, privkey)) { + case 1: + ret = 1; + break; + case 0: + OPENSSL_PUT_ERROR(X509, X509_R_KEY_VALUES_MISMATCH); + break; + case -1: + OPENSSL_PUT_ERROR(X509, X509_R_KEY_TYPE_MISMATCH); + break; + case -2: + OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_KEY_TYPE); + break; + default: + assert(0); + break; + } + + return ret; +} + +int ssl_cert_check_private_key(const CERT *cert, const EVP_PKEY *privkey) { + if (privkey == NULL) { + OPENSSL_PUT_ERROR(SSL, SSL_R_NO_PRIVATE_KEY_ASSIGNED); + return 0; + } + + if (cert->chain == NULL || + sk_CRYPTO_BUFFER_value(cert->chain, 0) == NULL) { + OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CERTIFICATE_ASSIGNED); + return 0; + } + + CBS cert_cbs; + CRYPTO_BUFFER_init_CBS(sk_CRYPTO_BUFFER_value(cert->chain, 0), &cert_cbs); + UniquePtr pubkey = ssl_cert_parse_pubkey(&cert_cbs); + if (!pubkey) { + OPENSSL_PUT_ERROR(X509, X509_R_UNKNOWN_KEY_TYPE); + return 0; + } + + return ssl_compare_public_and_private_key(pubkey.get(), privkey); +} + +int ssl_cert_check_digital_signature_key_usage(const CBS *in) { + CBS buf = *in; + + CBS tbs_cert, outer_extensions; + int has_extensions; + if (!ssl_cert_skip_to_spki(&buf, &tbs_cert) || + // subjectPublicKeyInfo + !CBS_get_asn1(&tbs_cert, NULL, CBS_ASN1_SEQUENCE) || + // issuerUniqueID + !CBS_get_optional_asn1( + &tbs_cert, NULL, NULL, + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 1) || + // subjectUniqueID + !CBS_get_optional_asn1( + &tbs_cert, NULL, NULL, + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 2) || + !CBS_get_optional_asn1( + &tbs_cert, &outer_extensions, &has_extensions, + CBS_ASN1_CONSTRUCTED | CBS_ASN1_CONTEXT_SPECIFIC | 3)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_CANNOT_PARSE_LEAF_CERT); + return 0; + } + + if (!has_extensions) { + return 1; + } + + CBS extensions; + if (!CBS_get_asn1(&outer_extensions, &extensions, CBS_ASN1_SEQUENCE)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_CANNOT_PARSE_LEAF_CERT); + return 0; + } + + while (CBS_len(&extensions) > 0) { + CBS extension, oid, contents; + if (!CBS_get_asn1(&extensions, &extension, CBS_ASN1_SEQUENCE) || + !CBS_get_asn1(&extension, &oid, CBS_ASN1_OBJECT) || + (CBS_peek_asn1_tag(&extension, CBS_ASN1_BOOLEAN) && + !CBS_get_asn1(&extension, NULL, CBS_ASN1_BOOLEAN)) || + !CBS_get_asn1(&extension, &contents, CBS_ASN1_OCTETSTRING) || + CBS_len(&extension) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_CANNOT_PARSE_LEAF_CERT); + return 0; + } + + static const uint8_t kKeyUsageOID[3] = {0x55, 0x1d, 0x0f}; + if (CBS_len(&oid) != sizeof(kKeyUsageOID) || + OPENSSL_memcmp(CBS_data(&oid), kKeyUsageOID, sizeof(kKeyUsageOID)) != + 0) { + continue; + } + + CBS bit_string; + if (!CBS_get_asn1(&contents, &bit_string, CBS_ASN1_BITSTRING) || + CBS_len(&contents) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_CANNOT_PARSE_LEAF_CERT); + return 0; + } + + // This is the KeyUsage extension. See + // https://tools.ietf.org/html/rfc5280#section-4.2.1.3 + if (!CBS_is_valid_asn1_bitstring(&bit_string)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_CANNOT_PARSE_LEAF_CERT); + return 0; + } + + if (!CBS_asn1_bitstring_has_bit(&bit_string, 0)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_ECC_CERT_NOT_FOR_SIGNING); + return 0; + } + + return 1; + } + + // No KeyUsage extension found. + return 1; +} + +UniquePtr ssl_parse_client_CA_list(SSL *ssl, + uint8_t *out_alert, + CBS *cbs) { + CRYPTO_BUFFER_POOL *const pool = ssl->ctx->pool; + + UniquePtr ret(sk_CRYPTO_BUFFER_new_null()); + if (!ret) { + *out_alert = SSL_AD_INTERNAL_ERROR; + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return nullptr; + } + + CBS child; + if (!CBS_get_u16_length_prefixed(cbs, &child)) { + *out_alert = SSL_AD_DECODE_ERROR; + OPENSSL_PUT_ERROR(SSL, SSL_R_LENGTH_MISMATCH); + return nullptr; + } + + while (CBS_len(&child) > 0) { + CBS distinguished_name; + if (!CBS_get_u16_length_prefixed(&child, &distinguished_name)) { + *out_alert = SSL_AD_DECODE_ERROR; + OPENSSL_PUT_ERROR(SSL, SSL_R_CA_DN_TOO_LONG); + return nullptr; + } + + UniquePtr buffer( + CRYPTO_BUFFER_new_from_CBS(&distinguished_name, pool)); + if (!buffer || + !PushToStack(ret.get(), std::move(buffer))) { + *out_alert = SSL_AD_INTERNAL_ERROR; + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return nullptr; + } + } + + if (!ssl->ctx->x509_method->check_client_CA_list(ret.get())) { + *out_alert = SSL_AD_INTERNAL_ERROR; + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + return nullptr; + } + + return ret; +} + +bool ssl_has_client_CAs(SSL *ssl) { + STACK_OF(CRYPTO_BUFFER) *names = ssl->client_CA; + if (names == NULL) { + names = ssl->ctx->client_CA; + } + if (names == NULL) { + return false; + } + return sk_CRYPTO_BUFFER_num(names) > 0; +} + +int ssl_add_client_CA_list(SSL *ssl, CBB *cbb) { + CBB child, name_cbb; + if (!CBB_add_u16_length_prefixed(cbb, &child)) { + return 0; + } + + STACK_OF(CRYPTO_BUFFER) *names = ssl->client_CA; + if (names == NULL) { + names = ssl->ctx->client_CA; + } + if (names == NULL) { + return CBB_flush(cbb); + } + + for (const CRYPTO_BUFFER *name : names) { + if (!CBB_add_u16_length_prefixed(&child, &name_cbb) || + !CBB_add_bytes(&name_cbb, CRYPTO_BUFFER_data(name), + CRYPTO_BUFFER_len(name))) { + return 0; + } + } + + return CBB_flush(cbb); +} + +int ssl_check_leaf_certificate(SSL_HANDSHAKE *hs, EVP_PKEY *pkey, + const CRYPTO_BUFFER *leaf) { + SSL *const ssl = hs->ssl; + assert(ssl_protocol_version(ssl) < TLS1_3_VERSION); + + // Check the certificate's type matches the cipher. + if (!(hs->new_cipher->algorithm_auth & ssl_cipher_auth_mask_for_key(pkey))) { + OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CERTIFICATE_TYPE); + return 0; + } + + // Check key usages for all key types but RSA. This is needed to distinguish + // ECDH certificates, which we do not support, from ECDSA certificates. In + // principle, we should check RSA key usages based on cipher, but this breaks + // buggy antivirus deployments. Other key types are always used for signing. + // + // TODO(davidben): Get more recent data on RSA key usages. + if (EVP_PKEY_id(pkey) != EVP_PKEY_RSA) { + CBS leaf_cbs; + CBS_init(&leaf_cbs, CRYPTO_BUFFER_data(leaf), CRYPTO_BUFFER_len(leaf)); + if (!ssl_cert_check_digital_signature_key_usage(&leaf_cbs)) { + return 0; + } + } + + if (EVP_PKEY_id(pkey) == EVP_PKEY_EC) { + // Check the key's group and point format are acceptable. + EC_KEY *ec_key = EVP_PKEY_get0_EC_KEY(pkey); + uint16_t group_id; + if (!ssl_nid_to_group_id( + &group_id, EC_GROUP_get_curve_name(EC_KEY_get0_group(ec_key))) || + !tls1_check_group_id(ssl, group_id) || + EC_KEY_get_conv_form(ec_key) != POINT_CONVERSION_UNCOMPRESSED) { + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_ECC_CERT); + return 0; + } + } + + return 1; +} + +int ssl_on_certificate_selected(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + if (!ssl_has_certificate(ssl)) { + // Nothing to do. + return 1; + } + + if (!ssl->ctx->x509_method->ssl_auto_chain_if_needed(ssl)) { + return 0; + } + + CBS leaf; + CRYPTO_BUFFER_init_CBS(sk_CRYPTO_BUFFER_value(ssl->cert->chain, 0), &leaf); + + hs->local_pubkey = ssl_cert_parse_pubkey(&leaf); + return hs->local_pubkey != NULL; +} + +} // namespace bssl + +using namespace bssl; + +int SSL_set_chain_and_key(SSL *ssl, CRYPTO_BUFFER *const *certs, + size_t num_certs, EVP_PKEY *privkey, + const SSL_PRIVATE_KEY_METHOD *privkey_method) { + return cert_set_chain_and_key(ssl->cert, certs, num_certs, privkey, + privkey_method); +} + +int SSL_CTX_set_chain_and_key(SSL_CTX *ctx, CRYPTO_BUFFER *const *certs, + size_t num_certs, EVP_PKEY *privkey, + const SSL_PRIVATE_KEY_METHOD *privkey_method) { + return cert_set_chain_and_key(ctx->cert, certs, num_certs, privkey, + privkey_method); +} + +int SSL_CTX_use_certificate_ASN1(SSL_CTX *ctx, size_t der_len, + const uint8_t *der) { + UniquePtr buffer(CRYPTO_BUFFER_new(der, der_len, NULL)); + if (!buffer) { + return 0; + } + + return ssl_set_cert(ctx->cert, std::move(buffer)); +} + +int SSL_use_certificate_ASN1(SSL *ssl, const uint8_t *der, size_t der_len) { + UniquePtr buffer(CRYPTO_BUFFER_new(der, der_len, NULL)); + if (!buffer) { + return 0; + } + + return ssl_set_cert(ssl->cert, std::move(buffer)); +} + +void SSL_CTX_set_cert_cb(SSL_CTX *ctx, int (*cb)(SSL *ssl, void *arg), + void *arg) { + ssl_cert_set_cert_cb(ctx->cert, cb, arg); +} + +void SSL_set_cert_cb(SSL *ssl, int (*cb)(SSL *ssl, void *arg), void *arg) { + ssl_cert_set_cert_cb(ssl->cert, cb, arg); +} + +STACK_OF(CRYPTO_BUFFER) *SSL_get0_peer_certificates(const SSL *ssl) { + SSL_SESSION *session = SSL_get_session(ssl); + if (session == NULL) { + return NULL; + } + + return session->certs; +} + +STACK_OF(CRYPTO_BUFFER) *SSL_get0_server_requested_CAs(const SSL *ssl) { + if (ssl->s3->hs == NULL) { + return NULL; + } + return ssl->s3->hs->ca_names.get(); +} + +static int set_signed_cert_timestamp_list(CERT *cert, const uint8_t *list, + size_t list_len) { + CBS sct_list; + CBS_init(&sct_list, list, list_len); + if (!ssl_is_sct_list_valid(&sct_list)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_SCT_LIST); + return 0; + } + + CRYPTO_BUFFER_free(cert->signed_cert_timestamp_list); + cert->signed_cert_timestamp_list = + CRYPTO_BUFFER_new(CBS_data(&sct_list), CBS_len(&sct_list), NULL); + return cert->signed_cert_timestamp_list != NULL; +} + +int SSL_CTX_set_signed_cert_timestamp_list(SSL_CTX *ctx, const uint8_t *list, + size_t list_len) { + return set_signed_cert_timestamp_list(ctx->cert, list, list_len); +} + +int SSL_set_signed_cert_timestamp_list(SSL *ssl, const uint8_t *list, + size_t list_len) { + return set_signed_cert_timestamp_list(ssl->cert, list, list_len); +} + +int SSL_CTX_set_ocsp_response(SSL_CTX *ctx, const uint8_t *response, + size_t response_len) { + CRYPTO_BUFFER_free(ctx->cert->ocsp_response); + ctx->cert->ocsp_response = CRYPTO_BUFFER_new(response, response_len, NULL); + return ctx->cert->ocsp_response != NULL; +} + +int SSL_set_ocsp_response(SSL *ssl, const uint8_t *response, + size_t response_len) { + CRYPTO_BUFFER_free(ssl->cert->ocsp_response); + ssl->cert->ocsp_response = CRYPTO_BUFFER_new(response, response_len, NULL); + return ssl->cert->ocsp_response != NULL; +} + +void SSL_CTX_set0_client_CAs(SSL_CTX *ctx, STACK_OF(CRYPTO_BUFFER) *name_list) { + ctx->x509_method->ssl_ctx_flush_cached_client_CA(ctx); + sk_CRYPTO_BUFFER_pop_free(ctx->client_CA, CRYPTO_BUFFER_free); + ctx->client_CA = name_list; +} + +void SSL_set0_client_CAs(SSL *ssl, STACK_OF(CRYPTO_BUFFER) *name_list) { + ssl->ctx->x509_method->ssl_flush_cached_client_CA(ssl); + sk_CRYPTO_BUFFER_pop_free(ssl->client_CA, CRYPTO_BUFFER_free); + ssl->client_CA = name_list; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/ssl/ssl_cipher.cc b/FoodApp/Pods/BoringSSL-GRPC/ssl/ssl_cipher.cc new file mode 100644 index 0000000..a7c5a03 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/ssl/ssl_cipher.cc @@ -0,0 +1,1781 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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. + */ +/* ==================================================================== + * 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 + +#include +#include +#include +#include +#include +#include + +#include "internal.h" +#include "../crypto/internal.h" + + +namespace bssl { + +// kCiphers is an array of all supported ciphers, sorted by id. +static const SSL_CIPHER kCiphers[] = { + // The RSA ciphers + // Cipher 02 + { + SSL3_TXT_RSA_NULL_SHA, + "TLS_RSA_WITH_NULL_SHA", + SSL3_CK_RSA_NULL_SHA, + SSL_kRSA, + SSL_aRSA, + SSL_eNULL, + SSL_SHA1, + SSL_HANDSHAKE_MAC_DEFAULT, + }, + + // Cipher 0A + { + SSL3_TXT_RSA_DES_192_CBC3_SHA, + "TLS_RSA_WITH_3DES_EDE_CBC_SHA", + SSL3_CK_RSA_DES_192_CBC3_SHA, + SSL_kRSA, + SSL_aRSA, + SSL_3DES, + SSL_SHA1, + SSL_HANDSHAKE_MAC_DEFAULT, + }, + + + // New AES ciphersuites + + // Cipher 2F + { + TLS1_TXT_RSA_WITH_AES_128_SHA, + "TLS_RSA_WITH_AES_128_CBC_SHA", + TLS1_CK_RSA_WITH_AES_128_SHA, + SSL_kRSA, + SSL_aRSA, + SSL_AES128, + SSL_SHA1, + SSL_HANDSHAKE_MAC_DEFAULT, + }, + + // Cipher 35 + { + TLS1_TXT_RSA_WITH_AES_256_SHA, + "TLS_RSA_WITH_AES_256_CBC_SHA", + TLS1_CK_RSA_WITH_AES_256_SHA, + SSL_kRSA, + SSL_aRSA, + SSL_AES256, + SSL_SHA1, + SSL_HANDSHAKE_MAC_DEFAULT, + }, + + + // TLS v1.2 ciphersuites + + // Cipher 3C + { + TLS1_TXT_RSA_WITH_AES_128_SHA256, + "TLS_RSA_WITH_AES_128_CBC_SHA256", + TLS1_CK_RSA_WITH_AES_128_SHA256, + SSL_kRSA, + SSL_aRSA, + SSL_AES128, + SSL_SHA256, + SSL_HANDSHAKE_MAC_SHA256, + }, + + // Cipher 3D + { + TLS1_TXT_RSA_WITH_AES_256_SHA256, + "TLS_RSA_WITH_AES_256_CBC_SHA256", + TLS1_CK_RSA_WITH_AES_256_SHA256, + SSL_kRSA, + SSL_aRSA, + SSL_AES256, + SSL_SHA256, + SSL_HANDSHAKE_MAC_SHA256, + }, + + // PSK cipher suites. + + // Cipher 8C + { + TLS1_TXT_PSK_WITH_AES_128_CBC_SHA, + "TLS_PSK_WITH_AES_128_CBC_SHA", + TLS1_CK_PSK_WITH_AES_128_CBC_SHA, + SSL_kPSK, + SSL_aPSK, + SSL_AES128, + SSL_SHA1, + SSL_HANDSHAKE_MAC_DEFAULT, + }, + + // Cipher 8D + { + TLS1_TXT_PSK_WITH_AES_256_CBC_SHA, + "TLS_PSK_WITH_AES_256_CBC_SHA", + TLS1_CK_PSK_WITH_AES_256_CBC_SHA, + SSL_kPSK, + SSL_aPSK, + SSL_AES256, + SSL_SHA1, + SSL_HANDSHAKE_MAC_DEFAULT, + }, + + // GCM ciphersuites from RFC5288 + + // Cipher 9C + { + TLS1_TXT_RSA_WITH_AES_128_GCM_SHA256, + "TLS_RSA_WITH_AES_128_GCM_SHA256", + TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, + SSL_kRSA, + SSL_aRSA, + SSL_AES128GCM, + SSL_AEAD, + SSL_HANDSHAKE_MAC_SHA256, + }, + + // Cipher 9D + { + TLS1_TXT_RSA_WITH_AES_256_GCM_SHA384, + "TLS_RSA_WITH_AES_256_GCM_SHA384", + TLS1_CK_RSA_WITH_AES_256_GCM_SHA384, + SSL_kRSA, + SSL_aRSA, + SSL_AES256GCM, + SSL_AEAD, + SSL_HANDSHAKE_MAC_SHA384, + }, + + // TLS 1.3 suites. + + // Cipher 1301 + { + TLS1_TXT_AES_128_GCM_SHA256, + "TLS_AES_128_GCM_SHA256", + TLS1_CK_AES_128_GCM_SHA256, + SSL_kGENERIC, + SSL_aGENERIC, + SSL_AES128GCM, + SSL_AEAD, + SSL_HANDSHAKE_MAC_SHA256, + }, + + // Cipher 1302 + { + TLS1_TXT_AES_256_GCM_SHA384, + "TLS_AES_256_GCM_SHA384", + TLS1_CK_AES_256_GCM_SHA384, + SSL_kGENERIC, + SSL_aGENERIC, + SSL_AES256GCM, + SSL_AEAD, + SSL_HANDSHAKE_MAC_SHA384, + }, + + // Cipher 1303 + { + TLS1_TXT_CHACHA20_POLY1305_SHA256, + "TLS_CHACHA20_POLY1305_SHA256", + TLS1_CK_CHACHA20_POLY1305_SHA256, + SSL_kGENERIC, + SSL_aGENERIC, + SSL_CHACHA20POLY1305, + SSL_AEAD, + SSL_HANDSHAKE_MAC_SHA256, + }, + + // Cipher C009 + { + TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, + "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", + TLS1_CK_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, + SSL_kECDHE, + SSL_aECDSA, + SSL_AES128, + SSL_SHA1, + SSL_HANDSHAKE_MAC_DEFAULT, + }, + + // Cipher C00A + { + TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, + "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", + TLS1_CK_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, + SSL_kECDHE, + SSL_aECDSA, + SSL_AES256, + SSL_SHA1, + SSL_HANDSHAKE_MAC_DEFAULT, + }, + + // Cipher C013 + { + TLS1_TXT_ECDHE_RSA_WITH_AES_128_CBC_SHA, + "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", + TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA, + SSL_kECDHE, + SSL_aRSA, + SSL_AES128, + SSL_SHA1, + SSL_HANDSHAKE_MAC_DEFAULT, + }, + + // Cipher C014 + { + TLS1_TXT_ECDHE_RSA_WITH_AES_256_CBC_SHA, + "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", + TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA, + SSL_kECDHE, + SSL_aRSA, + SSL_AES256, + SSL_SHA1, + SSL_HANDSHAKE_MAC_DEFAULT, + }, + + + // HMAC based TLS v1.2 ciphersuites from RFC5289 + + // Cipher C023 + { + TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_SHA256, + "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", + TLS1_CK_ECDHE_ECDSA_WITH_AES_128_SHA256, + SSL_kECDHE, + SSL_aECDSA, + SSL_AES128, + SSL_SHA256, + SSL_HANDSHAKE_MAC_SHA256, + }, + + // Cipher C024 + { + TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_SHA384, + "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384", + TLS1_CK_ECDHE_ECDSA_WITH_AES_256_SHA384, + SSL_kECDHE, + SSL_aECDSA, + SSL_AES256, + SSL_SHA384, + SSL_HANDSHAKE_MAC_SHA384, + }, + + // Cipher C027 + { + TLS1_TXT_ECDHE_RSA_WITH_AES_128_SHA256, + "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", + TLS1_CK_ECDHE_RSA_WITH_AES_128_SHA256, + SSL_kECDHE, + SSL_aRSA, + SSL_AES128, + SSL_SHA256, + SSL_HANDSHAKE_MAC_SHA256, + }, + + // Cipher C028 + { + TLS1_TXT_ECDHE_RSA_WITH_AES_256_SHA384, + "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384", + TLS1_CK_ECDHE_RSA_WITH_AES_256_SHA384, + SSL_kECDHE, + SSL_aRSA, + SSL_AES256, + SSL_SHA384, + SSL_HANDSHAKE_MAC_SHA384, + }, + + + // GCM based TLS v1.2 ciphersuites from RFC5289 + + // Cipher C02B + { + TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", + TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + SSL_kECDHE, + SSL_aECDSA, + SSL_AES128GCM, + SSL_AEAD, + SSL_HANDSHAKE_MAC_SHA256, + }, + + // Cipher C02C + { + TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", + TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + SSL_kECDHE, + SSL_aECDSA, + SSL_AES256GCM, + SSL_AEAD, + SSL_HANDSHAKE_MAC_SHA384, + }, + + // Cipher C02F + { + TLS1_TXT_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", + TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + SSL_kECDHE, + SSL_aRSA, + SSL_AES128GCM, + SSL_AEAD, + SSL_HANDSHAKE_MAC_SHA256, + }, + + // Cipher C030 + { + TLS1_TXT_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", + TLS1_CK_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + SSL_kECDHE, + SSL_aRSA, + SSL_AES256GCM, + SSL_AEAD, + SSL_HANDSHAKE_MAC_SHA384, + }, + + // ECDHE-PSK cipher suites. + + // Cipher C035 + { + TLS1_TXT_ECDHE_PSK_WITH_AES_128_CBC_SHA, + "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA", + TLS1_CK_ECDHE_PSK_WITH_AES_128_CBC_SHA, + SSL_kECDHE, + SSL_aPSK, + SSL_AES128, + SSL_SHA1, + SSL_HANDSHAKE_MAC_DEFAULT, + }, + + // Cipher C036 + { + TLS1_TXT_ECDHE_PSK_WITH_AES_256_CBC_SHA, + "TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA", + TLS1_CK_ECDHE_PSK_WITH_AES_256_CBC_SHA, + SSL_kECDHE, + SSL_aPSK, + SSL_AES256, + SSL_SHA1, + SSL_HANDSHAKE_MAC_DEFAULT, + }, + + // ChaCha20-Poly1305 cipher suites. + + // Cipher CCA8 + { + TLS1_TXT_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, + "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256", + TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, + SSL_kECDHE, + SSL_aRSA, + SSL_CHACHA20POLY1305, + SSL_AEAD, + SSL_HANDSHAKE_MAC_SHA256, + }, + + // Cipher CCA9 + { + TLS1_TXT_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, + "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256", + TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, + SSL_kECDHE, + SSL_aECDSA, + SSL_CHACHA20POLY1305, + SSL_AEAD, + SSL_HANDSHAKE_MAC_SHA256, + }, + + // Cipher CCAB + { + TLS1_TXT_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256, + "TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256", + TLS1_CK_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256, + SSL_kECDHE, + SSL_aPSK, + SSL_CHACHA20POLY1305, + SSL_AEAD, + SSL_HANDSHAKE_MAC_SHA256, + }, + +}; + +static const size_t kCiphersLen = OPENSSL_ARRAY_SIZE(kCiphers); + +#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; + bool active; + bool in_group; + struct cipher_order_st *next, *prev; +} CIPHER_ORDER; + +typedef struct cipher_alias_st { + // name is the name of the cipher alias. + const char *name; + + // The following fields are bitmasks for the corresponding fields on + // |SSL_CIPHER|. A cipher matches a cipher alias iff, for each bitmask, the + // bit corresponding to the cipher's value is set to 1. If any bitmask is + // all zeroes, the alias matches nothing. Use |~0u| for the default value. + uint32_t algorithm_mkey; + uint32_t algorithm_auth; + uint32_t algorithm_enc; + uint32_t algorithm_mac; + + // min_version, if non-zero, matches all ciphers which were added in that + // particular protocol version. + uint16_t min_version; +} CIPHER_ALIAS; + +static const CIPHER_ALIAS kCipherAliases[] = { + // "ALL" doesn't include eNULL. It must be explicitly enabled. + {"ALL", ~0u, ~0u, ~0u, ~0u, 0}, + + // The "COMPLEMENTOFDEFAULT" rule is omitted. It matches nothing. + + // key exchange aliases + // (some of those using only a single bit here combine + // multiple key exchange algs according to the RFCs. + {"kRSA", SSL_kRSA, ~0u, ~0u, ~0u, 0}, + + {"kECDHE", SSL_kECDHE, ~0u, ~0u, ~0u, 0}, + {"kEECDH", SSL_kECDHE, ~0u, ~0u, ~0u, 0}, + {"ECDH", SSL_kECDHE, ~0u, ~0u, ~0u, 0}, + + {"kPSK", SSL_kPSK, ~0u, ~0u, ~0u, 0}, + + // server authentication aliases + {"aRSA", ~0u, SSL_aRSA, ~0u, ~0u, 0}, + {"aECDSA", ~0u, SSL_aECDSA, ~0u, ~0u, 0}, + {"ECDSA", ~0u, SSL_aECDSA, ~0u, ~0u, 0}, + {"aPSK", ~0u, SSL_aPSK, ~0u, ~0u, 0}, + + // aliases combining key exchange and server authentication + {"ECDHE", SSL_kECDHE, ~0u, ~0u, ~0u, 0}, + {"EECDH", SSL_kECDHE, ~0u, ~0u, ~0u, 0}, + {"RSA", SSL_kRSA, SSL_aRSA, ~0u, ~0u, 0}, + {"PSK", SSL_kPSK, SSL_aPSK, ~0u, ~0u, 0}, + + // symmetric encryption aliases + {"3DES", ~0u, ~0u, SSL_3DES, ~0u, 0}, + {"AES128", ~0u, ~0u, SSL_AES128 | SSL_AES128GCM, ~0u, 0}, + {"AES256", ~0u, ~0u, SSL_AES256 | SSL_AES256GCM, ~0u, 0}, + {"AES", ~0u, ~0u, SSL_AES, ~0u, 0}, + {"AESGCM", ~0u, ~0u, SSL_AES128GCM | SSL_AES256GCM, ~0u, 0}, + {"CHACHA20", ~0u, ~0u, SSL_CHACHA20POLY1305, ~0u, 0}, + + // MAC aliases + {"SHA1", ~0u, ~0u, ~0u, SSL_SHA1, 0}, + {"SHA", ~0u, ~0u, ~0u, SSL_SHA1, 0}, + {"SHA256", ~0u, ~0u, ~0u, SSL_SHA256, 0}, + {"SHA384", ~0u, ~0u, ~0u, SSL_SHA384, 0}, + + // Legacy protocol minimum version aliases. "TLSv1" is intentionally the + // same as "SSLv3". + {"SSLv3", ~0u, ~0u, ~0u, ~0u, SSL3_VERSION}, + {"TLSv1", ~0u, ~0u, ~0u, ~0u, SSL3_VERSION}, + {"TLSv1.2", ~0u, ~0u, ~0u, ~0u, TLS1_2_VERSION}, + + // Legacy strength classes. + {"HIGH", ~0u, ~0u, ~0u, ~0u, 0}, + {"FIPS", ~0u, ~0u, ~0u, ~0u, 0}, +}; + +static const size_t kCipherAliasesLen = OPENSSL_ARRAY_SIZE(kCipherAliases); + +static int ssl_cipher_id_cmp(const void *in_a, const void *in_b) { + const SSL_CIPHER *a = reinterpret_cast(in_a); + const SSL_CIPHER *b = reinterpret_cast(in_b); + + if (a->id > b->id) { + return 1; + } else if (a->id < b->id) { + return -1; + } else { + return 0; + } +} + +bool ssl_cipher_get_evp_aead(const EVP_AEAD **out_aead, + size_t *out_mac_secret_len, + size_t *out_fixed_iv_len, const SSL_CIPHER *cipher, + uint16_t version, int is_dtls) { + *out_aead = NULL; + *out_mac_secret_len = 0; + *out_fixed_iv_len = 0; + + const int is_tls12 = version == TLS1_2_VERSION && !is_dtls; + + if (cipher->algorithm_mac == SSL_AEAD) { + if (cipher->algorithm_enc == SSL_AES128GCM) { + *out_aead = + is_tls12 ? EVP_aead_aes_128_gcm_tls12() : EVP_aead_aes_128_gcm(); + *out_fixed_iv_len = 4; + } else if (cipher->algorithm_enc == SSL_AES256GCM) { + *out_aead = + is_tls12 ? EVP_aead_aes_256_gcm_tls12() : EVP_aead_aes_256_gcm(); + *out_fixed_iv_len = 4; + } else if (cipher->algorithm_enc == SSL_CHACHA20POLY1305) { + *out_aead = EVP_aead_chacha20_poly1305(); + *out_fixed_iv_len = 12; + } else { + return false; + } + + // In TLS 1.3, the iv_len is equal to the AEAD nonce length whereas the code + // above computes the TLS 1.2 construction. + if (version >= TLS1_3_VERSION) { + *out_fixed_iv_len = EVP_AEAD_nonce_length(*out_aead); + } + } else if (cipher->algorithm_mac == SSL_SHA1) { + if (cipher->algorithm_enc == SSL_eNULL) { + if (version == SSL3_VERSION) { + *out_aead = EVP_aead_null_sha1_ssl3(); + } else { + *out_aead = EVP_aead_null_sha1_tls(); + } + } else if (cipher->algorithm_enc == SSL_3DES) { + if (version == SSL3_VERSION) { + *out_aead = EVP_aead_des_ede3_cbc_sha1_ssl3(); + *out_fixed_iv_len = 8; + } else if (version == TLS1_VERSION) { + *out_aead = EVP_aead_des_ede3_cbc_sha1_tls_implicit_iv(); + *out_fixed_iv_len = 8; + } else { + *out_aead = EVP_aead_des_ede3_cbc_sha1_tls(); + } + } else if (cipher->algorithm_enc == SSL_AES128) { + if (version == SSL3_VERSION) { + *out_aead = EVP_aead_aes_128_cbc_sha1_ssl3(); + *out_fixed_iv_len = 16; + } else if (version == TLS1_VERSION) { + *out_aead = EVP_aead_aes_128_cbc_sha1_tls_implicit_iv(); + *out_fixed_iv_len = 16; + } else { + *out_aead = EVP_aead_aes_128_cbc_sha1_tls(); + } + } else if (cipher->algorithm_enc == SSL_AES256) { + if (version == SSL3_VERSION) { + *out_aead = EVP_aead_aes_256_cbc_sha1_ssl3(); + *out_fixed_iv_len = 16; + } else if (version == TLS1_VERSION) { + *out_aead = EVP_aead_aes_256_cbc_sha1_tls_implicit_iv(); + *out_fixed_iv_len = 16; + } else { + *out_aead = EVP_aead_aes_256_cbc_sha1_tls(); + } + } else { + return false; + } + + *out_mac_secret_len = SHA_DIGEST_LENGTH; + } else if (cipher->algorithm_mac == SSL_SHA256) { + if (cipher->algorithm_enc == SSL_AES128) { + *out_aead = EVP_aead_aes_128_cbc_sha256_tls(); + } else if (cipher->algorithm_enc == SSL_AES256) { + *out_aead = EVP_aead_aes_256_cbc_sha256_tls(); + } else { + return false; + } + + *out_mac_secret_len = SHA256_DIGEST_LENGTH; + } else if (cipher->algorithm_mac == SSL_SHA384) { + if (cipher->algorithm_enc != SSL_AES256) { + return false; + } + + *out_aead = EVP_aead_aes_256_cbc_sha384_tls(); + *out_mac_secret_len = SHA384_DIGEST_LENGTH; + } else { + return false; + } + + return true; +} + +const EVP_MD *ssl_get_handshake_digest(uint16_t version, + const SSL_CIPHER *cipher) { + switch (cipher->algorithm_prf) { + case SSL_HANDSHAKE_MAC_DEFAULT: + return version >= TLS1_2_VERSION ? EVP_sha256() : EVP_md5_sha1(); + case SSL_HANDSHAKE_MAC_SHA256: + return EVP_sha256(); + case SSL_HANDSHAKE_MAC_SHA384: + return EVP_sha384(); + default: + assert(0); + return NULL; + } +} + +static bool is_cipher_list_separator(char c, int is_strict) { + if (c == ':') { + return true; + } + return !is_strict && (c == ' ' || c == ';' || c == ','); +} + +// rule_equals returns whether the NUL-terminated string |rule| is equal to the +// |buf_len| bytes at |buf|. +static bool rule_equals(const char *rule, const char *buf, size_t buf_len) { + // |strncmp| alone only checks that |buf| is a prefix of |rule|. + return strncmp(rule, buf, buf_len) == 0 && rule[buf_len] == '\0'; +} + +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_collect_ciphers(CIPHER_ORDER *co_list, + CIPHER_ORDER **head_p, + CIPHER_ORDER **tail_p) { + size_t co_list_num = 0; + for (const SSL_CIPHER &cipher : kCiphers) { + // TLS 1.3 ciphers do not participate in this mechanism. + if (cipher.algorithm_mkey != SSL_kGENERIC) { + co_list[co_list_num].cipher = &cipher; + co_list[co_list_num].next = NULL; + co_list[co_list_num].prev = NULL; + co_list[co_list_num].active = false; + co_list[co_list_num].in_group = false; + co_list_num++; + } + } + + // 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 (size_t 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]; + } +} + +// ssl_cipher_apply_rule applies the rule type |rule| to ciphers matching its +// parameters in the linked list from |*head_p| to |*tail_p|. It writes the new +// head and tail of the list to |*head_p| and |*tail_p|, respectively. +// +// - If |cipher_id| is non-zero, only that cipher is selected. +// - Otherwise, if |strength_bits| is non-negative, it selects ciphers +// of that strength. +// - Otherwise, it selects ciphers that match each bitmasks in |alg_*| and +// |min_version|. +static void ssl_cipher_apply_rule( + uint32_t cipher_id, uint32_t alg_mkey, uint32_t alg_auth, + uint32_t alg_enc, uint32_t alg_mac, uint16_t min_version, int rule, + int strength_bits, bool in_group, CIPHER_ORDER **head_p, + CIPHER_ORDER **tail_p) { + CIPHER_ORDER *head, *tail, *curr, *next, *last; + const SSL_CIPHER *cp; + bool reverse = false; + + if (cipher_id == 0 && strength_bits == -1 && min_version == 0 && + (alg_mkey == 0 || alg_auth == 0 || alg_enc == 0 || alg_mac == 0)) { + // The rule matches nothing, so bail early. + return; + } + + if (rule == CIPHER_DEL) { + // needed to maintain sorting between currently deleted ciphers + reverse = true; + } + + 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 a specific cipher, the value of + // |strength_bits|, or the algorithms used. + if (cipher_id != 0) { + if (cipher_id != cp->id) { + continue; + } + } else if (strength_bits >= 0) { + if (strength_bits != SSL_CIPHER_get_bits(cp, NULL)) { + continue; + } + } else { + if (!(alg_mkey & cp->algorithm_mkey) || + !(alg_auth & cp->algorithm_auth) || + !(alg_enc & cp->algorithm_enc) || + !(alg_mac & cp->algorithm_mac) || + (min_version != 0 && SSL_CIPHER_get_min_version(cp) != min_version) || + // The NULL cipher must be selected explicitly. + cp->algorithm_enc == SSL_eNULL) { + continue; + } + } + + // add the cipher if it has not been added yet. + if (rule == CIPHER_ADD) { + // reverse == false + if (!curr->active) { + ll_append_tail(&head, curr, &tail); + curr->active = true; + curr->in_group = in_group; + } + } + + // Move the added cipher to this location + else if (rule == CIPHER_ORD) { + // reverse == false + if (curr->active) { + ll_append_tail(&head, curr, &tail); + curr->in_group = false; + } + } else if (rule == CIPHER_DEL) { + // reverse == true + 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 = false; + curr->in_group = false; + } + } else if (rule == CIPHER_KILL) { + // reverse == false + if (head == curr) { + head = curr->next; + } else { + curr->prev->next = curr->next; + } + + if (tail == curr) { + tail = curr->prev; + } + curr->active = false; + 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 bool ssl_cipher_strength_sort(CIPHER_ORDER **head_p, + CIPHER_ORDER **tail_p) { + // 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. + int max_strength_bits = 0; + CIPHER_ORDER *curr = *head_p; + while (curr != NULL) { + if (curr->active && + SSL_CIPHER_get_bits(curr->cipher, NULL) > max_strength_bits) { + max_strength_bits = SSL_CIPHER_get_bits(curr->cipher, NULL); + } + curr = curr->next; + } + + Array number_uses; + if (!number_uses.Init(max_strength_bits + 1)) { + return false; + } + OPENSSL_memset(number_uses.data(), 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[SSL_CIPHER_get_bits(curr->cipher, NULL)]++; + } + curr = curr->next; + } + + // Go through the list of used strength_bits values in descending order. + for (int i = max_strength_bits; i >= 0; i--) { + if (number_uses[i] > 0) { + ssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, CIPHER_ORD, i, false, head_p, + tail_p); + } + } + + return true; +} + +static bool ssl_cipher_process_rulestr(const char *rule_str, + CIPHER_ORDER **head_p, + CIPHER_ORDER **tail_p, bool strict) { + uint32_t alg_mkey, alg_auth, alg_enc, alg_mac; + uint16_t min_version; + const char *l, *buf; + int rule; + bool multi, skip_rule, in_group = false, has_group = false; + size_t j, buf_len; + uint32_t cipher_id; + char ch; + + l = rule_str; + for (;;) { + ch = *l; + + if (ch == '\0') { + break; // done + } + + if (in_group) { + if (ch == ']') { + if (*tail_p) { + (*tail_p)->in_group = false; + } + in_group = false; + l++; + continue; + } + + if (ch == '|') { + rule = CIPHER_ADD; + l++; + continue; + } else if (!(ch >= 'a' && ch <= 'z') && !(ch >= 'A' && ch <= 'Z') && + !(ch >= '0' && ch <= '9')) { + OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_OPERATOR_IN_GROUP); + return false; + } else { + rule = CIPHER_ADD; + } + } else 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 if (ch == '[') { + assert(!in_group); + in_group = true; + has_group = true; + l++; + continue; + } else { + rule = CIPHER_ADD; + } + + // If preference groups are enabled, the only legal operator is +. + // Otherwise the in_group bits will get mixed up. + if (has_group && rule != CIPHER_ADD) { + OPENSSL_PUT_ERROR(SSL, SSL_R_MIXED_SPECIAL_OPERATOR_WITH_GROUPS); + return false; + } + + if (is_cipher_list_separator(ch, strict)) { + l++; + continue; + } + + multi = false; + cipher_id = 0; + alg_mkey = ~0u; + alg_auth = ~0u; + alg_enc = ~0u; + alg_mac = ~0u; + min_version = 0; + skip_rule = false; + + for (;;) { + ch = *l; + buf = l; + buf_len = 0; + while ((ch >= 'A' && ch <= 'Z') || (ch >= '0' && ch <= '9') || + (ch >= 'a' && ch <= 'z') || ch == '-' || ch == '.' || ch == '_') { + ch = *(++l); + buf_len++; + } + + if (buf_len == 0) { + // We hit something we cannot deal with, it is no command or separator + // nor alphanumeric, so we call this an error. + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_COMMAND); + return false; + } + + if (rule == CIPHER_SPECIAL) { + break; + } + + // Look for a matching exact cipher. These aren't allowed in multipart + // rules. + if (!multi && ch != '+') { + for (j = 0; j < kCiphersLen; j++) { + const SSL_CIPHER *cipher = &kCiphers[j]; + if (rule_equals(cipher->name, buf, buf_len) || + rule_equals(cipher->standard_name, buf, buf_len)) { + cipher_id = cipher->id; + break; + } + } + } + if (cipher_id == 0) { + // If not an exact cipher, look for a matching cipher alias. + for (j = 0; j < kCipherAliasesLen; j++) { + if (rule_equals(kCipherAliases[j].name, buf, buf_len)) { + alg_mkey &= kCipherAliases[j].algorithm_mkey; + alg_auth &= kCipherAliases[j].algorithm_auth; + alg_enc &= kCipherAliases[j].algorithm_enc; + alg_mac &= kCipherAliases[j].algorithm_mac; + + if (min_version != 0 && + min_version != kCipherAliases[j].min_version) { + skip_rule = true; + } else { + min_version = kCipherAliases[j].min_version; + } + break; + } + } + if (j == kCipherAliasesLen) { + skip_rule = true; + if (strict) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_COMMAND); + return false; + } + } + } + + // Check for a multipart rule. + if (ch != '+') { + break; + } + l++; + multi = true; + } + + // Ok, we have the rule, now apply it. + if (rule == CIPHER_SPECIAL) { + if (buf_len != 8 || strncmp(buf, "STRENGTH", 8) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_COMMAND); + return false; + } + if (!ssl_cipher_strength_sort(head_p, tail_p)) { + return false; + } + + // 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' && !is_cipher_list_separator(*l, strict)) { + l++; + } + } else if (!skip_rule) { + ssl_cipher_apply_rule(cipher_id, alg_mkey, alg_auth, alg_enc, alg_mac, + min_version, rule, -1, in_group, head_p, tail_p); + } + } + + if (in_group) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_COMMAND); + return false; + } + + return true; +} + +bool ssl_create_cipher_list( + struct ssl_cipher_preference_list_st **out_cipher_list, + const char *rule_str, bool strict) { + STACK_OF(SSL_CIPHER) *cipherstack = NULL; + CIPHER_ORDER *co_list = NULL, *head = NULL, *tail = NULL, *curr; + uint8_t *in_group_flags = NULL; + unsigned int num_in_group_flags = 0; + struct ssl_cipher_preference_list_st *pref_list = NULL; + + // Return with error if nothing to do. + if (rule_str == NULL || out_cipher_list == NULL) { + return false; + } + + // 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. + co_list = (CIPHER_ORDER *)OPENSSL_malloc(sizeof(CIPHER_ORDER) * kCiphersLen); + if (co_list == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return false; + } + + ssl_cipher_collect_ciphers(co_list, &head, &tail); + + // Now arrange all ciphers by preference: + // TODO(davidben): Compute this order once and copy it. + + // Everything else being equal, prefer ECDHE_ECDSA and ECDHE_RSA over other + // key exchange mechanisms + ssl_cipher_apply_rule(0, SSL_kECDHE, SSL_aECDSA, ~0u, ~0u, 0, CIPHER_ADD, -1, + false, &head, &tail); + ssl_cipher_apply_rule(0, SSL_kECDHE, ~0u, ~0u, ~0u, 0, CIPHER_ADD, -1, false, + &head, &tail); + ssl_cipher_apply_rule(0, ~0u, ~0u, ~0u, ~0u, 0, CIPHER_DEL, -1, false, &head, + &tail); + + // Order the bulk ciphers. First the preferred AEAD ciphers. We prefer + // CHACHA20 unless there is hardware support for fast and constant-time + // AES_GCM. Of the two CHACHA20 variants, the new one is preferred over the + // old one. + if (EVP_has_aes_hardware()) { + ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_AES128GCM, ~0u, 0, CIPHER_ADD, -1, + false, &head, &tail); + ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_AES256GCM, ~0u, 0, CIPHER_ADD, -1, + false, &head, &tail); + ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_CHACHA20POLY1305, ~0u, 0, CIPHER_ADD, + -1, false, &head, &tail); + } else { + ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_CHACHA20POLY1305, ~0u, 0, CIPHER_ADD, + -1, false, &head, &tail); + ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_AES128GCM, ~0u, 0, CIPHER_ADD, -1, + false, &head, &tail); + ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_AES256GCM, ~0u, 0, CIPHER_ADD, -1, + false, &head, &tail); + } + + // Then the legacy non-AEAD ciphers: AES_128_CBC, AES_256_CBC, + // 3DES_EDE_CBC_SHA. + ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_AES128, ~0u, 0, CIPHER_ADD, -1, false, + &head, &tail); + ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_AES256, ~0u, 0, CIPHER_ADD, -1, false, + &head, &tail); + ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_3DES, ~0u, 0, CIPHER_ADD, -1, false, + &head, &tail); + + // Temporarily enable everything else for sorting + ssl_cipher_apply_rule(0, ~0u, ~0u, ~0u, ~0u, 0, CIPHER_ADD, -1, false, &head, + &tail); + + // Move ciphers without forward secrecy to the end. + ssl_cipher_apply_rule(0, (SSL_kRSA | SSL_kPSK), ~0u, ~0u, ~0u, 0, CIPHER_ORD, + -1, false, &head, &tail); + + // Now disable everything (maintaining the ordering!) + ssl_cipher_apply_rule(0, ~0u, ~0u, ~0u, ~0u, 0, CIPHER_DEL, -1, false, &head, + &tail); + + // If the rule_string begins with DEFAULT, apply the default rule before + // using the (possibly available) additional rules. + const char *rule_p = rule_str; + if (strncmp(rule_str, "DEFAULT", 7) == 0) { + if (!ssl_cipher_process_rulestr(SSL_DEFAULT_CIPHER_LIST, &head, &tail, + strict)) { + goto err; + } + rule_p += 7; + if (*rule_p == ':') { + rule_p++; + } + } + + if (*rule_p != '\0' && + !ssl_cipher_process_rulestr(rule_p, &head, &tail, strict)) { + goto err; + } + + // Allocate new "cipherstack" for the result, return with error + // if we cannot get one. + cipherstack = sk_SSL_CIPHER_new_null(); + if (cipherstack == NULL) { + goto err; + } + + in_group_flags = (uint8_t *)OPENSSL_malloc(kCiphersLen); + if (!in_group_flags) { + goto err; + } + + // 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) { + if (curr->active) { + if (!sk_SSL_CIPHER_push(cipherstack, curr->cipher)) { + goto err; + } + in_group_flags[num_in_group_flags++] = curr->in_group; + } + } + OPENSSL_free(co_list); // Not needed any longer + co_list = NULL; + + pref_list = (ssl_cipher_preference_list_st *)OPENSSL_malloc( + sizeof(struct ssl_cipher_preference_list_st)); + if (!pref_list) { + goto err; + } + pref_list->ciphers = cipherstack; + pref_list->in_group_flags = NULL; + if (num_in_group_flags) { + pref_list->in_group_flags = (uint8_t *)OPENSSL_malloc(num_in_group_flags); + if (!pref_list->in_group_flags) { + goto err; + } + OPENSSL_memcpy(pref_list->in_group_flags, in_group_flags, + num_in_group_flags); + } + OPENSSL_free(in_group_flags); + in_group_flags = NULL; + if (*out_cipher_list != NULL) { + ssl_cipher_preference_list_free(*out_cipher_list); + } + *out_cipher_list = pref_list; + pref_list = NULL; + + // Configuring an empty cipher list is an error but still updates the + // output. + if (sk_SSL_CIPHER_num((*out_cipher_list)->ciphers) == 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CIPHER_MATCH); + return false; + } + + return true; + +err: + OPENSSL_free(co_list); + OPENSSL_free(in_group_flags); + sk_SSL_CIPHER_free(cipherstack); + if (pref_list) { + OPENSSL_free(pref_list->in_group_flags); + } + OPENSSL_free(pref_list); + return false; +} + +uint16_t ssl_cipher_get_value(const SSL_CIPHER *cipher) { + uint32_t id = cipher->id; + // All ciphers are SSLv3. + assert((id & 0xff000000) == 0x03000000); + return id & 0xffff; +} + +uint32_t ssl_cipher_auth_mask_for_key(const EVP_PKEY *key) { + switch (EVP_PKEY_id(key)) { + case EVP_PKEY_RSA: + return SSL_aRSA; + case EVP_PKEY_EC: + case EVP_PKEY_ED25519: + // Ed25519 keys in TLS 1.2 repurpose the ECDSA ciphers. + return SSL_aECDSA; + default: + return 0; + } +} + +bool ssl_cipher_uses_certificate_auth(const SSL_CIPHER *cipher) { + return (cipher->algorithm_auth & SSL_aCERT) != 0; +} + +bool ssl_cipher_requires_server_key_exchange(const SSL_CIPHER *cipher) { + // Ephemeral Diffie-Hellman key exchanges require a ServerKeyExchange. It is + // optional or omitted in all others. + return (cipher->algorithm_mkey & SSL_kECDHE) != 0; +} + +size_t ssl_cipher_get_record_split_len(const SSL_CIPHER *cipher) { + size_t block_size; + switch (cipher->algorithm_enc) { + case SSL_3DES: + block_size = 8; + break; + case SSL_AES128: + case SSL_AES256: + block_size = 16; + break; + default: + return 0; + } + + // All supported TLS 1.0 ciphers use SHA-1. + assert(cipher->algorithm_mac == SSL_SHA1); + size_t ret = 1 + SHA_DIGEST_LENGTH; + ret += block_size - (ret % block_size); + return ret; +} + +} // namespace bssl + +using namespace bssl; + +const SSL_CIPHER *SSL_get_cipher_by_value(uint16_t value) { + SSL_CIPHER c; + + c.id = 0x03000000L | value; + return reinterpret_cast(bsearch( + &c, kCiphers, kCiphersLen, sizeof(SSL_CIPHER), ssl_cipher_id_cmp)); +} + +uint32_t SSL_CIPHER_get_id(const SSL_CIPHER *cipher) { return cipher->id; } + +int SSL_CIPHER_is_aead(const SSL_CIPHER *cipher) { + return (cipher->algorithm_mac & SSL_AEAD) != 0; +} + +int SSL_CIPHER_get_cipher_nid(const SSL_CIPHER *cipher) { + switch (cipher->algorithm_enc) { + case SSL_eNULL: + return NID_undef; + case SSL_3DES: + return NID_des_ede3_cbc; + case SSL_AES128: + return NID_aes_128_cbc; + case SSL_AES256: + return NID_aes_256_cbc; + case SSL_AES128GCM: + return NID_aes_128_gcm; + case SSL_AES256GCM: + return NID_aes_256_gcm; + case SSL_CHACHA20POLY1305: + return NID_chacha20_poly1305; + } + assert(0); + return NID_undef; +} + +int SSL_CIPHER_get_digest_nid(const SSL_CIPHER *cipher) { + switch (cipher->algorithm_mac) { + case SSL_AEAD: + return NID_undef; + case SSL_SHA1: + return NID_sha1; + case SSL_SHA256: + return NID_sha256; + case SSL_SHA384: + return NID_sha384; + } + assert(0); + return NID_undef; +} + +int SSL_CIPHER_get_kx_nid(const SSL_CIPHER *cipher) { + switch (cipher->algorithm_mkey) { + case SSL_kRSA: + return NID_kx_rsa; + case SSL_kECDHE: + return NID_kx_ecdhe; + case SSL_kPSK: + return NID_kx_psk; + case SSL_kGENERIC: + return NID_kx_any; + } + assert(0); + return NID_undef; +} + +int SSL_CIPHER_get_auth_nid(const SSL_CIPHER *cipher) { + switch (cipher->algorithm_auth) { + case SSL_aRSA: + return NID_auth_rsa; + case SSL_aECDSA: + return NID_auth_ecdsa; + case SSL_aPSK: + return NID_auth_psk; + case SSL_aGENERIC: + return NID_auth_any; + } + assert(0); + return NID_undef; +} + +int SSL_CIPHER_get_prf_nid(const SSL_CIPHER *cipher) { + switch (cipher->algorithm_prf) { + case SSL_HANDSHAKE_MAC_DEFAULT: + return NID_md5_sha1; + case SSL_HANDSHAKE_MAC_SHA256: + return NID_sha256; + case SSL_HANDSHAKE_MAC_SHA384: + return NID_sha384; + } + assert(0); + return NID_undef; +} + +int SSL_CIPHER_is_block_cipher(const SSL_CIPHER *cipher) { + return (cipher->algorithm_enc & SSL_eNULL) == 0 && + cipher->algorithm_mac != SSL_AEAD; +} + +uint16_t SSL_CIPHER_get_min_version(const SSL_CIPHER *cipher) { + if (cipher->algorithm_mkey == SSL_kGENERIC || + cipher->algorithm_auth == SSL_aGENERIC) { + return TLS1_3_VERSION; + } + + if (cipher->algorithm_prf != SSL_HANDSHAKE_MAC_DEFAULT) { + // Cipher suites before TLS 1.2 use the default PRF, while all those added + // afterwards specify a particular hash. + return TLS1_2_VERSION; + } + return SSL3_VERSION; +} + +uint16_t SSL_CIPHER_get_max_version(const SSL_CIPHER *cipher) { + if (cipher->algorithm_mkey == SSL_kGENERIC || + cipher->algorithm_auth == SSL_aGENERIC) { + return TLS1_3_VERSION; + } + return TLS1_2_VERSION; +} + +// return the actual cipher being used +const char *SSL_CIPHER_get_name(const SSL_CIPHER *cipher) { + if (cipher != NULL) { + return cipher->name; + } + + return "(NONE)"; +} + +const char *SSL_CIPHER_standard_name(const SSL_CIPHER *cipher) { + return cipher->standard_name; +} + +const char *SSL_CIPHER_get_kx_name(const SSL_CIPHER *cipher) { + if (cipher == NULL) { + return ""; + } + + switch (cipher->algorithm_mkey) { + case SSL_kRSA: + return "RSA"; + + case SSL_kECDHE: + switch (cipher->algorithm_auth) { + case SSL_aECDSA: + return "ECDHE_ECDSA"; + case SSL_aRSA: + return "ECDHE_RSA"; + case SSL_aPSK: + return "ECDHE_PSK"; + default: + assert(0); + return "UNKNOWN"; + } + + case SSL_kPSK: + assert(cipher->algorithm_auth == SSL_aPSK); + return "PSK"; + + case SSL_kGENERIC: + assert(cipher->algorithm_auth == SSL_aGENERIC); + return "GENERIC"; + + default: + assert(0); + return "UNKNOWN"; + } +} + +char *SSL_CIPHER_get_rfc_name(const SSL_CIPHER *cipher) { + if (cipher == NULL) { + return NULL; + } + + return OPENSSL_strdup(SSL_CIPHER_standard_name(cipher)); +} + +int SSL_CIPHER_get_bits(const SSL_CIPHER *cipher, int *out_alg_bits) { + if (cipher == NULL) { + return 0; + } + + int alg_bits, strength_bits; + switch (cipher->algorithm_enc) { + case SSL_AES128: + case SSL_AES128GCM: + alg_bits = 128; + strength_bits = 128; + break; + + case SSL_AES256: + case SSL_AES256GCM: + case SSL_CHACHA20POLY1305: + alg_bits = 256; + strength_bits = 256; + break; + + case SSL_3DES: + alg_bits = 168; + strength_bits = 112; + break; + + case SSL_eNULL: + alg_bits = 0; + strength_bits = 0; + break; + + default: + assert(0); + alg_bits = 0; + strength_bits = 0; + } + + if (out_alg_bits != NULL) { + *out_alg_bits = alg_bits; + } + return strength_bits; +} + +const char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, + int len) { + const char *kx, *au, *enc, *mac; + uint32_t alg_mkey, alg_auth, alg_enc, alg_mac; + + alg_mkey = cipher->algorithm_mkey; + alg_auth = cipher->algorithm_auth; + alg_enc = cipher->algorithm_enc; + alg_mac = cipher->algorithm_mac; + + switch (alg_mkey) { + case SSL_kRSA: + kx = "RSA"; + break; + + case SSL_kECDHE: + kx = "ECDH"; + break; + + case SSL_kPSK: + kx = "PSK"; + break; + + case SSL_kGENERIC: + kx = "GENERIC"; + break; + + default: + kx = "unknown"; + } + + switch (alg_auth) { + case SSL_aRSA: + au = "RSA"; + break; + + case SSL_aECDSA: + au = "ECDSA"; + break; + + case SSL_aPSK: + au = "PSK"; + break; + + case SSL_aGENERIC: + au = "GENERIC"; + break; + + default: + au = "unknown"; + break; + } + + switch (alg_enc) { + case SSL_3DES: + enc = "3DES(168)"; + 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_CHACHA20POLY1305: + enc = "ChaCha20-Poly1305"; + break; + + case SSL_eNULL: + enc="None"; + break; + + default: + enc = "unknown"; + break; + } + + switch (alg_mac) { + case SSL_SHA1: + mac = "SHA1"; + break; + + case SSL_SHA256: + mac = "SHA256"; + break; + + case SSL_SHA384: + mac = "SHA384"; + break; + + case SSL_AEAD: + mac = "AEAD"; + break; + + default: + mac = "unknown"; + break; + } + + if (buf == NULL) { + len = 128; + buf = (char *)OPENSSL_malloc(len); + if (buf == NULL) { + return NULL; + } + } else if (len < 128) { + return "Buffer too small"; + } + + BIO_snprintf(buf, len, "%-23s Kx=%-8s Au=%-4s Enc=%-9s Mac=%-4s\n", + cipher->name, kx, au, enc, mac); + return buf; +} + +const char *SSL_CIPHER_get_version(const SSL_CIPHER *cipher) { + return "TLSv1/SSLv3"; +} + +STACK_OF(SSL_COMP) *SSL_COMP_get_compression_methods(void) { return NULL; } + +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; } + +const char *SSL_COMP_get0_name(const SSL_COMP *comp) { return comp->name; } + +int SSL_COMP_get_id(const SSL_COMP *comp) { return comp->id; } + +void SSL_COMP_free_compression_methods(void) {} diff --git a/FoodApp/Pods/BoringSSL-GRPC/ssl/ssl_cipher.cc.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/ssl/ssl_cipher.cc.grpc_back new file mode 100644 index 0000000..32e6c2c --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/ssl/ssl_cipher.cc.grpc_back @@ -0,0 +1,1781 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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. + */ +/* ==================================================================== + * 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 + +#include +#include +#include +#include +#include +#include + +#include "internal.h" +#include "../crypto/internal.h" + + +namespace bssl { + +// kCiphers is an array of all supported ciphers, sorted by id. +static const SSL_CIPHER kCiphers[] = { + // The RSA ciphers + // Cipher 02 + { + SSL3_TXT_RSA_NULL_SHA, + "TLS_RSA_WITH_NULL_SHA", + SSL3_CK_RSA_NULL_SHA, + SSL_kRSA, + SSL_aRSA, + SSL_eNULL, + SSL_SHA1, + SSL_HANDSHAKE_MAC_DEFAULT, + }, + + // Cipher 0A + { + SSL3_TXT_RSA_DES_192_CBC3_SHA, + "TLS_RSA_WITH_3DES_EDE_CBC_SHA", + SSL3_CK_RSA_DES_192_CBC3_SHA, + SSL_kRSA, + SSL_aRSA, + SSL_3DES, + SSL_SHA1, + SSL_HANDSHAKE_MAC_DEFAULT, + }, + + + // New AES ciphersuites + + // Cipher 2F + { + TLS1_TXT_RSA_WITH_AES_128_SHA, + "TLS_RSA_WITH_AES_128_CBC_SHA", + TLS1_CK_RSA_WITH_AES_128_SHA, + SSL_kRSA, + SSL_aRSA, + SSL_AES128, + SSL_SHA1, + SSL_HANDSHAKE_MAC_DEFAULT, + }, + + // Cipher 35 + { + TLS1_TXT_RSA_WITH_AES_256_SHA, + "TLS_RSA_WITH_AES_256_CBC_SHA", + TLS1_CK_RSA_WITH_AES_256_SHA, + SSL_kRSA, + SSL_aRSA, + SSL_AES256, + SSL_SHA1, + SSL_HANDSHAKE_MAC_DEFAULT, + }, + + + // TLS v1.2 ciphersuites + + // Cipher 3C + { + TLS1_TXT_RSA_WITH_AES_128_SHA256, + "TLS_RSA_WITH_AES_128_CBC_SHA256", + TLS1_CK_RSA_WITH_AES_128_SHA256, + SSL_kRSA, + SSL_aRSA, + SSL_AES128, + SSL_SHA256, + SSL_HANDSHAKE_MAC_SHA256, + }, + + // Cipher 3D + { + TLS1_TXT_RSA_WITH_AES_256_SHA256, + "TLS_RSA_WITH_AES_256_CBC_SHA256", + TLS1_CK_RSA_WITH_AES_256_SHA256, + SSL_kRSA, + SSL_aRSA, + SSL_AES256, + SSL_SHA256, + SSL_HANDSHAKE_MAC_SHA256, + }, + + // PSK cipher suites. + + // Cipher 8C + { + TLS1_TXT_PSK_WITH_AES_128_CBC_SHA, + "TLS_PSK_WITH_AES_128_CBC_SHA", + TLS1_CK_PSK_WITH_AES_128_CBC_SHA, + SSL_kPSK, + SSL_aPSK, + SSL_AES128, + SSL_SHA1, + SSL_HANDSHAKE_MAC_DEFAULT, + }, + + // Cipher 8D + { + TLS1_TXT_PSK_WITH_AES_256_CBC_SHA, + "TLS_PSK_WITH_AES_256_CBC_SHA", + TLS1_CK_PSK_WITH_AES_256_CBC_SHA, + SSL_kPSK, + SSL_aPSK, + SSL_AES256, + SSL_SHA1, + SSL_HANDSHAKE_MAC_DEFAULT, + }, + + // GCM ciphersuites from RFC5288 + + // Cipher 9C + { + TLS1_TXT_RSA_WITH_AES_128_GCM_SHA256, + "TLS_RSA_WITH_AES_128_GCM_SHA256", + TLS1_CK_RSA_WITH_AES_128_GCM_SHA256, + SSL_kRSA, + SSL_aRSA, + SSL_AES128GCM, + SSL_AEAD, + SSL_HANDSHAKE_MAC_SHA256, + }, + + // Cipher 9D + { + TLS1_TXT_RSA_WITH_AES_256_GCM_SHA384, + "TLS_RSA_WITH_AES_256_GCM_SHA384", + TLS1_CK_RSA_WITH_AES_256_GCM_SHA384, + SSL_kRSA, + SSL_aRSA, + SSL_AES256GCM, + SSL_AEAD, + SSL_HANDSHAKE_MAC_SHA384, + }, + + // TLS 1.3 suites. + + // Cipher 1301 + { + TLS1_TXT_AES_128_GCM_SHA256, + "TLS_AES_128_GCM_SHA256", + TLS1_CK_AES_128_GCM_SHA256, + SSL_kGENERIC, + SSL_aGENERIC, + SSL_AES128GCM, + SSL_AEAD, + SSL_HANDSHAKE_MAC_SHA256, + }, + + // Cipher 1302 + { + TLS1_TXT_AES_256_GCM_SHA384, + "TLS_AES_256_GCM_SHA384", + TLS1_CK_AES_256_GCM_SHA384, + SSL_kGENERIC, + SSL_aGENERIC, + SSL_AES256GCM, + SSL_AEAD, + SSL_HANDSHAKE_MAC_SHA384, + }, + + // Cipher 1303 + { + TLS1_TXT_CHACHA20_POLY1305_SHA256, + "TLS_CHACHA20_POLY1305_SHA256", + TLS1_CK_CHACHA20_POLY1305_SHA256, + SSL_kGENERIC, + SSL_aGENERIC, + SSL_CHACHA20POLY1305, + SSL_AEAD, + SSL_HANDSHAKE_MAC_SHA256, + }, + + // Cipher C009 + { + TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, + "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", + TLS1_CK_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, + SSL_kECDHE, + SSL_aECDSA, + SSL_AES128, + SSL_SHA1, + SSL_HANDSHAKE_MAC_DEFAULT, + }, + + // Cipher C00A + { + TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, + "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", + TLS1_CK_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, + SSL_kECDHE, + SSL_aECDSA, + SSL_AES256, + SSL_SHA1, + SSL_HANDSHAKE_MAC_DEFAULT, + }, + + // Cipher C013 + { + TLS1_TXT_ECDHE_RSA_WITH_AES_128_CBC_SHA, + "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", + TLS1_CK_ECDHE_RSA_WITH_AES_128_CBC_SHA, + SSL_kECDHE, + SSL_aRSA, + SSL_AES128, + SSL_SHA1, + SSL_HANDSHAKE_MAC_DEFAULT, + }, + + // Cipher C014 + { + TLS1_TXT_ECDHE_RSA_WITH_AES_256_CBC_SHA, + "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", + TLS1_CK_ECDHE_RSA_WITH_AES_256_CBC_SHA, + SSL_kECDHE, + SSL_aRSA, + SSL_AES256, + SSL_SHA1, + SSL_HANDSHAKE_MAC_DEFAULT, + }, + + + // HMAC based TLS v1.2 ciphersuites from RFC5289 + + // Cipher C023 + { + TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_SHA256, + "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", + TLS1_CK_ECDHE_ECDSA_WITH_AES_128_SHA256, + SSL_kECDHE, + SSL_aECDSA, + SSL_AES128, + SSL_SHA256, + SSL_HANDSHAKE_MAC_SHA256, + }, + + // Cipher C024 + { + TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_SHA384, + "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384", + TLS1_CK_ECDHE_ECDSA_WITH_AES_256_SHA384, + SSL_kECDHE, + SSL_aECDSA, + SSL_AES256, + SSL_SHA384, + SSL_HANDSHAKE_MAC_SHA384, + }, + + // Cipher C027 + { + TLS1_TXT_ECDHE_RSA_WITH_AES_128_SHA256, + "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", + TLS1_CK_ECDHE_RSA_WITH_AES_128_SHA256, + SSL_kECDHE, + SSL_aRSA, + SSL_AES128, + SSL_SHA256, + SSL_HANDSHAKE_MAC_SHA256, + }, + + // Cipher C028 + { + TLS1_TXT_ECDHE_RSA_WITH_AES_256_SHA384, + "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384", + TLS1_CK_ECDHE_RSA_WITH_AES_256_SHA384, + SSL_kECDHE, + SSL_aRSA, + SSL_AES256, + SSL_SHA384, + SSL_HANDSHAKE_MAC_SHA384, + }, + + + // GCM based TLS v1.2 ciphersuites from RFC5289 + + // Cipher C02B + { + TLS1_TXT_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", + TLS1_CK_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + SSL_kECDHE, + SSL_aECDSA, + SSL_AES128GCM, + SSL_AEAD, + SSL_HANDSHAKE_MAC_SHA256, + }, + + // Cipher C02C + { + TLS1_TXT_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", + TLS1_CK_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + SSL_kECDHE, + SSL_aECDSA, + SSL_AES256GCM, + SSL_AEAD, + SSL_HANDSHAKE_MAC_SHA384, + }, + + // Cipher C02F + { + TLS1_TXT_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", + TLS1_CK_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + SSL_kECDHE, + SSL_aRSA, + SSL_AES128GCM, + SSL_AEAD, + SSL_HANDSHAKE_MAC_SHA256, + }, + + // Cipher C030 + { + TLS1_TXT_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", + TLS1_CK_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + SSL_kECDHE, + SSL_aRSA, + SSL_AES256GCM, + SSL_AEAD, + SSL_HANDSHAKE_MAC_SHA384, + }, + + // ECDHE-PSK cipher suites. + + // Cipher C035 + { + TLS1_TXT_ECDHE_PSK_WITH_AES_128_CBC_SHA, + "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA", + TLS1_CK_ECDHE_PSK_WITH_AES_128_CBC_SHA, + SSL_kECDHE, + SSL_aPSK, + SSL_AES128, + SSL_SHA1, + SSL_HANDSHAKE_MAC_DEFAULT, + }, + + // Cipher C036 + { + TLS1_TXT_ECDHE_PSK_WITH_AES_256_CBC_SHA, + "TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA", + TLS1_CK_ECDHE_PSK_WITH_AES_256_CBC_SHA, + SSL_kECDHE, + SSL_aPSK, + SSL_AES256, + SSL_SHA1, + SSL_HANDSHAKE_MAC_DEFAULT, + }, + + // ChaCha20-Poly1305 cipher suites. + + // Cipher CCA8 + { + TLS1_TXT_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, + "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256", + TLS1_CK_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, + SSL_kECDHE, + SSL_aRSA, + SSL_CHACHA20POLY1305, + SSL_AEAD, + SSL_HANDSHAKE_MAC_SHA256, + }, + + // Cipher CCA9 + { + TLS1_TXT_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, + "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256", + TLS1_CK_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, + SSL_kECDHE, + SSL_aECDSA, + SSL_CHACHA20POLY1305, + SSL_AEAD, + SSL_HANDSHAKE_MAC_SHA256, + }, + + // Cipher CCAB + { + TLS1_TXT_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256, + "TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256", + TLS1_CK_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256, + SSL_kECDHE, + SSL_aPSK, + SSL_CHACHA20POLY1305, + SSL_AEAD, + SSL_HANDSHAKE_MAC_SHA256, + }, + +}; + +static const size_t kCiphersLen = OPENSSL_ARRAY_SIZE(kCiphers); + +#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; + bool active; + bool in_group; + struct cipher_order_st *next, *prev; +} CIPHER_ORDER; + +typedef struct cipher_alias_st { + // name is the name of the cipher alias. + const char *name; + + // The following fields are bitmasks for the corresponding fields on + // |SSL_CIPHER|. A cipher matches a cipher alias iff, for each bitmask, the + // bit corresponding to the cipher's value is set to 1. If any bitmask is + // all zeroes, the alias matches nothing. Use |~0u| for the default value. + uint32_t algorithm_mkey; + uint32_t algorithm_auth; + uint32_t algorithm_enc; + uint32_t algorithm_mac; + + // min_version, if non-zero, matches all ciphers which were added in that + // particular protocol version. + uint16_t min_version; +} CIPHER_ALIAS; + +static const CIPHER_ALIAS kCipherAliases[] = { + // "ALL" doesn't include eNULL. It must be explicitly enabled. + {"ALL", ~0u, ~0u, ~0u, ~0u, 0}, + + // The "COMPLEMENTOFDEFAULT" rule is omitted. It matches nothing. + + // key exchange aliases + // (some of those using only a single bit here combine + // multiple key exchange algs according to the RFCs. + {"kRSA", SSL_kRSA, ~0u, ~0u, ~0u, 0}, + + {"kECDHE", SSL_kECDHE, ~0u, ~0u, ~0u, 0}, + {"kEECDH", SSL_kECDHE, ~0u, ~0u, ~0u, 0}, + {"ECDH", SSL_kECDHE, ~0u, ~0u, ~0u, 0}, + + {"kPSK", SSL_kPSK, ~0u, ~0u, ~0u, 0}, + + // server authentication aliases + {"aRSA", ~0u, SSL_aRSA, ~0u, ~0u, 0}, + {"aECDSA", ~0u, SSL_aECDSA, ~0u, ~0u, 0}, + {"ECDSA", ~0u, SSL_aECDSA, ~0u, ~0u, 0}, + {"aPSK", ~0u, SSL_aPSK, ~0u, ~0u, 0}, + + // aliases combining key exchange and server authentication + {"ECDHE", SSL_kECDHE, ~0u, ~0u, ~0u, 0}, + {"EECDH", SSL_kECDHE, ~0u, ~0u, ~0u, 0}, + {"RSA", SSL_kRSA, SSL_aRSA, ~0u, ~0u, 0}, + {"PSK", SSL_kPSK, SSL_aPSK, ~0u, ~0u, 0}, + + // symmetric encryption aliases + {"3DES", ~0u, ~0u, SSL_3DES, ~0u, 0}, + {"AES128", ~0u, ~0u, SSL_AES128 | SSL_AES128GCM, ~0u, 0}, + {"AES256", ~0u, ~0u, SSL_AES256 | SSL_AES256GCM, ~0u, 0}, + {"AES", ~0u, ~0u, SSL_AES, ~0u, 0}, + {"AESGCM", ~0u, ~0u, SSL_AES128GCM | SSL_AES256GCM, ~0u, 0}, + {"CHACHA20", ~0u, ~0u, SSL_CHACHA20POLY1305, ~0u, 0}, + + // MAC aliases + {"SHA1", ~0u, ~0u, ~0u, SSL_SHA1, 0}, + {"SHA", ~0u, ~0u, ~0u, SSL_SHA1, 0}, + {"SHA256", ~0u, ~0u, ~0u, SSL_SHA256, 0}, + {"SHA384", ~0u, ~0u, ~0u, SSL_SHA384, 0}, + + // Legacy protocol minimum version aliases. "TLSv1" is intentionally the + // same as "SSLv3". + {"SSLv3", ~0u, ~0u, ~0u, ~0u, SSL3_VERSION}, + {"TLSv1", ~0u, ~0u, ~0u, ~0u, SSL3_VERSION}, + {"TLSv1.2", ~0u, ~0u, ~0u, ~0u, TLS1_2_VERSION}, + + // Legacy strength classes. + {"HIGH", ~0u, ~0u, ~0u, ~0u, 0}, + {"FIPS", ~0u, ~0u, ~0u, ~0u, 0}, +}; + +static const size_t kCipherAliasesLen = OPENSSL_ARRAY_SIZE(kCipherAliases); + +static int ssl_cipher_id_cmp(const void *in_a, const void *in_b) { + const SSL_CIPHER *a = reinterpret_cast(in_a); + const SSL_CIPHER *b = reinterpret_cast(in_b); + + if (a->id > b->id) { + return 1; + } else if (a->id < b->id) { + return -1; + } else { + return 0; + } +} + +bool ssl_cipher_get_evp_aead(const EVP_AEAD **out_aead, + size_t *out_mac_secret_len, + size_t *out_fixed_iv_len, const SSL_CIPHER *cipher, + uint16_t version, int is_dtls) { + *out_aead = NULL; + *out_mac_secret_len = 0; + *out_fixed_iv_len = 0; + + const int is_tls12 = version == TLS1_2_VERSION && !is_dtls; + + if (cipher->algorithm_mac == SSL_AEAD) { + if (cipher->algorithm_enc == SSL_AES128GCM) { + *out_aead = + is_tls12 ? EVP_aead_aes_128_gcm_tls12() : EVP_aead_aes_128_gcm(); + *out_fixed_iv_len = 4; + } else if (cipher->algorithm_enc == SSL_AES256GCM) { + *out_aead = + is_tls12 ? EVP_aead_aes_256_gcm_tls12() : EVP_aead_aes_256_gcm(); + *out_fixed_iv_len = 4; + } else if (cipher->algorithm_enc == SSL_CHACHA20POLY1305) { + *out_aead = EVP_aead_chacha20_poly1305(); + *out_fixed_iv_len = 12; + } else { + return false; + } + + // In TLS 1.3, the iv_len is equal to the AEAD nonce length whereas the code + // above computes the TLS 1.2 construction. + if (version >= TLS1_3_VERSION) { + *out_fixed_iv_len = EVP_AEAD_nonce_length(*out_aead); + } + } else if (cipher->algorithm_mac == SSL_SHA1) { + if (cipher->algorithm_enc == SSL_eNULL) { + if (version == SSL3_VERSION) { + *out_aead = EVP_aead_null_sha1_ssl3(); + } else { + *out_aead = EVP_aead_null_sha1_tls(); + } + } else if (cipher->algorithm_enc == SSL_3DES) { + if (version == SSL3_VERSION) { + *out_aead = EVP_aead_des_ede3_cbc_sha1_ssl3(); + *out_fixed_iv_len = 8; + } else if (version == TLS1_VERSION) { + *out_aead = EVP_aead_des_ede3_cbc_sha1_tls_implicit_iv(); + *out_fixed_iv_len = 8; + } else { + *out_aead = EVP_aead_des_ede3_cbc_sha1_tls(); + } + } else if (cipher->algorithm_enc == SSL_AES128) { + if (version == SSL3_VERSION) { + *out_aead = EVP_aead_aes_128_cbc_sha1_ssl3(); + *out_fixed_iv_len = 16; + } else if (version == TLS1_VERSION) { + *out_aead = EVP_aead_aes_128_cbc_sha1_tls_implicit_iv(); + *out_fixed_iv_len = 16; + } else { + *out_aead = EVP_aead_aes_128_cbc_sha1_tls(); + } + } else if (cipher->algorithm_enc == SSL_AES256) { + if (version == SSL3_VERSION) { + *out_aead = EVP_aead_aes_256_cbc_sha1_ssl3(); + *out_fixed_iv_len = 16; + } else if (version == TLS1_VERSION) { + *out_aead = EVP_aead_aes_256_cbc_sha1_tls_implicit_iv(); + *out_fixed_iv_len = 16; + } else { + *out_aead = EVP_aead_aes_256_cbc_sha1_tls(); + } + } else { + return false; + } + + *out_mac_secret_len = SHA_DIGEST_LENGTH; + } else if (cipher->algorithm_mac == SSL_SHA256) { + if (cipher->algorithm_enc == SSL_AES128) { + *out_aead = EVP_aead_aes_128_cbc_sha256_tls(); + } else if (cipher->algorithm_enc == SSL_AES256) { + *out_aead = EVP_aead_aes_256_cbc_sha256_tls(); + } else { + return false; + } + + *out_mac_secret_len = SHA256_DIGEST_LENGTH; + } else if (cipher->algorithm_mac == SSL_SHA384) { + if (cipher->algorithm_enc != SSL_AES256) { + return false; + } + + *out_aead = EVP_aead_aes_256_cbc_sha384_tls(); + *out_mac_secret_len = SHA384_DIGEST_LENGTH; + } else { + return false; + } + + return true; +} + +const EVP_MD *ssl_get_handshake_digest(uint16_t version, + const SSL_CIPHER *cipher) { + switch (cipher->algorithm_prf) { + case SSL_HANDSHAKE_MAC_DEFAULT: + return version >= TLS1_2_VERSION ? EVP_sha256() : EVP_md5_sha1(); + case SSL_HANDSHAKE_MAC_SHA256: + return EVP_sha256(); + case SSL_HANDSHAKE_MAC_SHA384: + return EVP_sha384(); + default: + assert(0); + return NULL; + } +} + +static bool is_cipher_list_separator(char c, int is_strict) { + if (c == ':') { + return true; + } + return !is_strict && (c == ' ' || c == ';' || c == ','); +} + +// rule_equals returns whether the NUL-terminated string |rule| is equal to the +// |buf_len| bytes at |buf|. +static bool rule_equals(const char *rule, const char *buf, size_t buf_len) { + // |strncmp| alone only checks that |buf| is a prefix of |rule|. + return strncmp(rule, buf, buf_len) == 0 && rule[buf_len] == '\0'; +} + +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_collect_ciphers(CIPHER_ORDER *co_list, + CIPHER_ORDER **head_p, + CIPHER_ORDER **tail_p) { + size_t co_list_num = 0; + for (const SSL_CIPHER &cipher : kCiphers) { + // TLS 1.3 ciphers do not participate in this mechanism. + if (cipher.algorithm_mkey != SSL_kGENERIC) { + co_list[co_list_num].cipher = &cipher; + co_list[co_list_num].next = NULL; + co_list[co_list_num].prev = NULL; + co_list[co_list_num].active = false; + co_list[co_list_num].in_group = false; + co_list_num++; + } + } + + // 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 (size_t 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]; + } +} + +// ssl_cipher_apply_rule applies the rule type |rule| to ciphers matching its +// parameters in the linked list from |*head_p| to |*tail_p|. It writes the new +// head and tail of the list to |*head_p| and |*tail_p|, respectively. +// +// - If |cipher_id| is non-zero, only that cipher is selected. +// - Otherwise, if |strength_bits| is non-negative, it selects ciphers +// of that strength. +// - Otherwise, it selects ciphers that match each bitmasks in |alg_*| and +// |min_version|. +static void ssl_cipher_apply_rule( + uint32_t cipher_id, uint32_t alg_mkey, uint32_t alg_auth, + uint32_t alg_enc, uint32_t alg_mac, uint16_t min_version, int rule, + int strength_bits, bool in_group, CIPHER_ORDER **head_p, + CIPHER_ORDER **tail_p) { + CIPHER_ORDER *head, *tail, *curr, *next, *last; + const SSL_CIPHER *cp; + bool reverse = false; + + if (cipher_id == 0 && strength_bits == -1 && min_version == 0 && + (alg_mkey == 0 || alg_auth == 0 || alg_enc == 0 || alg_mac == 0)) { + // The rule matches nothing, so bail early. + return; + } + + if (rule == CIPHER_DEL) { + // needed to maintain sorting between currently deleted ciphers + reverse = true; + } + + 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 a specific cipher, the value of + // |strength_bits|, or the algorithms used. + if (cipher_id != 0) { + if (cipher_id != cp->id) { + continue; + } + } else if (strength_bits >= 0) { + if (strength_bits != SSL_CIPHER_get_bits(cp, NULL)) { + continue; + } + } else { + if (!(alg_mkey & cp->algorithm_mkey) || + !(alg_auth & cp->algorithm_auth) || + !(alg_enc & cp->algorithm_enc) || + !(alg_mac & cp->algorithm_mac) || + (min_version != 0 && SSL_CIPHER_get_min_version(cp) != min_version) || + // The NULL cipher must be selected explicitly. + cp->algorithm_enc == SSL_eNULL) { + continue; + } + } + + // add the cipher if it has not been added yet. + if (rule == CIPHER_ADD) { + // reverse == false + if (!curr->active) { + ll_append_tail(&head, curr, &tail); + curr->active = true; + curr->in_group = in_group; + } + } + + // Move the added cipher to this location + else if (rule == CIPHER_ORD) { + // reverse == false + if (curr->active) { + ll_append_tail(&head, curr, &tail); + curr->in_group = false; + } + } else if (rule == CIPHER_DEL) { + // reverse == true + 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 = false; + curr->in_group = false; + } + } else if (rule == CIPHER_KILL) { + // reverse == false + if (head == curr) { + head = curr->next; + } else { + curr->prev->next = curr->next; + } + + if (tail == curr) { + tail = curr->prev; + } + curr->active = false; + 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 bool ssl_cipher_strength_sort(CIPHER_ORDER **head_p, + CIPHER_ORDER **tail_p) { + // 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. + int max_strength_bits = 0; + CIPHER_ORDER *curr = *head_p; + while (curr != NULL) { + if (curr->active && + SSL_CIPHER_get_bits(curr->cipher, NULL) > max_strength_bits) { + max_strength_bits = SSL_CIPHER_get_bits(curr->cipher, NULL); + } + curr = curr->next; + } + + Array number_uses; + if (!number_uses.Init(max_strength_bits + 1)) { + return false; + } + OPENSSL_memset(number_uses.data(), 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[SSL_CIPHER_get_bits(curr->cipher, NULL)]++; + } + curr = curr->next; + } + + // Go through the list of used strength_bits values in descending order. + for (int i = max_strength_bits; i >= 0; i--) { + if (number_uses[i] > 0) { + ssl_cipher_apply_rule(0, 0, 0, 0, 0, 0, CIPHER_ORD, i, false, head_p, + tail_p); + } + } + + return true; +} + +static bool ssl_cipher_process_rulestr(const char *rule_str, + CIPHER_ORDER **head_p, + CIPHER_ORDER **tail_p, bool strict) { + uint32_t alg_mkey, alg_auth, alg_enc, alg_mac; + uint16_t min_version; + const char *l, *buf; + int rule; + bool multi, skip_rule, in_group = false, has_group = false; + size_t j, buf_len; + uint32_t cipher_id; + char ch; + + l = rule_str; + for (;;) { + ch = *l; + + if (ch == '\0') { + break; // done + } + + if (in_group) { + if (ch == ']') { + if (*tail_p) { + (*tail_p)->in_group = false; + } + in_group = false; + l++; + continue; + } + + if (ch == '|') { + rule = CIPHER_ADD; + l++; + continue; + } else if (!(ch >= 'a' && ch <= 'z') && !(ch >= 'A' && ch <= 'Z') && + !(ch >= '0' && ch <= '9')) { + OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_OPERATOR_IN_GROUP); + return false; + } else { + rule = CIPHER_ADD; + } + } else 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 if (ch == '[') { + assert(!in_group); + in_group = true; + has_group = true; + l++; + continue; + } else { + rule = CIPHER_ADD; + } + + // If preference groups are enabled, the only legal operator is +. + // Otherwise the in_group bits will get mixed up. + if (has_group && rule != CIPHER_ADD) { + OPENSSL_PUT_ERROR(SSL, SSL_R_MIXED_SPECIAL_OPERATOR_WITH_GROUPS); + return false; + } + + if (is_cipher_list_separator(ch, strict)) { + l++; + continue; + } + + multi = false; + cipher_id = 0; + alg_mkey = ~0u; + alg_auth = ~0u; + alg_enc = ~0u; + alg_mac = ~0u; + min_version = 0; + skip_rule = false; + + for (;;) { + ch = *l; + buf = l; + buf_len = 0; + while ((ch >= 'A' && ch <= 'Z') || (ch >= '0' && ch <= '9') || + (ch >= 'a' && ch <= 'z') || ch == '-' || ch == '.' || ch == '_') { + ch = *(++l); + buf_len++; + } + + if (buf_len == 0) { + // We hit something we cannot deal with, it is no command or separator + // nor alphanumeric, so we call this an error. + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_COMMAND); + return false; + } + + if (rule == CIPHER_SPECIAL) { + break; + } + + // Look for a matching exact cipher. These aren't allowed in multipart + // rules. + if (!multi && ch != '+') { + for (j = 0; j < kCiphersLen; j++) { + const SSL_CIPHER *cipher = &kCiphers[j]; + if (rule_equals(cipher->name, buf, buf_len) || + rule_equals(cipher->standard_name, buf, buf_len)) { + cipher_id = cipher->id; + break; + } + } + } + if (cipher_id == 0) { + // If not an exact cipher, look for a matching cipher alias. + for (j = 0; j < kCipherAliasesLen; j++) { + if (rule_equals(kCipherAliases[j].name, buf, buf_len)) { + alg_mkey &= kCipherAliases[j].algorithm_mkey; + alg_auth &= kCipherAliases[j].algorithm_auth; + alg_enc &= kCipherAliases[j].algorithm_enc; + alg_mac &= kCipherAliases[j].algorithm_mac; + + if (min_version != 0 && + min_version != kCipherAliases[j].min_version) { + skip_rule = true; + } else { + min_version = kCipherAliases[j].min_version; + } + break; + } + } + if (j == kCipherAliasesLen) { + skip_rule = true; + if (strict) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_COMMAND); + return false; + } + } + } + + // Check for a multipart rule. + if (ch != '+') { + break; + } + l++; + multi = true; + } + + // Ok, we have the rule, now apply it. + if (rule == CIPHER_SPECIAL) { + if (buf_len != 8 || strncmp(buf, "STRENGTH", 8) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_COMMAND); + return false; + } + if (!ssl_cipher_strength_sort(head_p, tail_p)) { + return false; + } + + // 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' && !is_cipher_list_separator(*l, strict)) { + l++; + } + } else if (!skip_rule) { + ssl_cipher_apply_rule(cipher_id, alg_mkey, alg_auth, alg_enc, alg_mac, + min_version, rule, -1, in_group, head_p, tail_p); + } + } + + if (in_group) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_COMMAND); + return false; + } + + return true; +} + +bool ssl_create_cipher_list( + struct ssl_cipher_preference_list_st **out_cipher_list, + const char *rule_str, bool strict) { + STACK_OF(SSL_CIPHER) *cipherstack = NULL; + CIPHER_ORDER *co_list = NULL, *head = NULL, *tail = NULL, *curr; + uint8_t *in_group_flags = NULL; + unsigned int num_in_group_flags = 0; + struct ssl_cipher_preference_list_st *pref_list = NULL; + + // Return with error if nothing to do. + if (rule_str == NULL || out_cipher_list == NULL) { + return false; + } + + // 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. + co_list = (CIPHER_ORDER *)OPENSSL_malloc(sizeof(CIPHER_ORDER) * kCiphersLen); + if (co_list == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return false; + } + + ssl_cipher_collect_ciphers(co_list, &head, &tail); + + // Now arrange all ciphers by preference: + // TODO(davidben): Compute this order once and copy it. + + // Everything else being equal, prefer ECDHE_ECDSA and ECDHE_RSA over other + // key exchange mechanisms + ssl_cipher_apply_rule(0, SSL_kECDHE, SSL_aECDSA, ~0u, ~0u, 0, CIPHER_ADD, -1, + false, &head, &tail); + ssl_cipher_apply_rule(0, SSL_kECDHE, ~0u, ~0u, ~0u, 0, CIPHER_ADD, -1, false, + &head, &tail); + ssl_cipher_apply_rule(0, ~0u, ~0u, ~0u, ~0u, 0, CIPHER_DEL, -1, false, &head, + &tail); + + // Order the bulk ciphers. First the preferred AEAD ciphers. We prefer + // CHACHA20 unless there is hardware support for fast and constant-time + // AES_GCM. Of the two CHACHA20 variants, the new one is preferred over the + // old one. + if (EVP_has_aes_hardware()) { + ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_AES128GCM, ~0u, 0, CIPHER_ADD, -1, + false, &head, &tail); + ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_AES256GCM, ~0u, 0, CIPHER_ADD, -1, + false, &head, &tail); + ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_CHACHA20POLY1305, ~0u, 0, CIPHER_ADD, + -1, false, &head, &tail); + } else { + ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_CHACHA20POLY1305, ~0u, 0, CIPHER_ADD, + -1, false, &head, &tail); + ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_AES128GCM, ~0u, 0, CIPHER_ADD, -1, + false, &head, &tail); + ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_AES256GCM, ~0u, 0, CIPHER_ADD, -1, + false, &head, &tail); + } + + // Then the legacy non-AEAD ciphers: AES_128_CBC, AES_256_CBC, + // 3DES_EDE_CBC_SHA. + ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_AES128, ~0u, 0, CIPHER_ADD, -1, false, + &head, &tail); + ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_AES256, ~0u, 0, CIPHER_ADD, -1, false, + &head, &tail); + ssl_cipher_apply_rule(0, ~0u, ~0u, SSL_3DES, ~0u, 0, CIPHER_ADD, -1, false, + &head, &tail); + + // Temporarily enable everything else for sorting + ssl_cipher_apply_rule(0, ~0u, ~0u, ~0u, ~0u, 0, CIPHER_ADD, -1, false, &head, + &tail); + + // Move ciphers without forward secrecy to the end. + ssl_cipher_apply_rule(0, (SSL_kRSA | SSL_kPSK), ~0u, ~0u, ~0u, 0, CIPHER_ORD, + -1, false, &head, &tail); + + // Now disable everything (maintaining the ordering!) + ssl_cipher_apply_rule(0, ~0u, ~0u, ~0u, ~0u, 0, CIPHER_DEL, -1, false, &head, + &tail); + + // If the rule_string begins with DEFAULT, apply the default rule before + // using the (possibly available) additional rules. + const char *rule_p = rule_str; + if (strncmp(rule_str, "DEFAULT", 7) == 0) { + if (!ssl_cipher_process_rulestr(SSL_DEFAULT_CIPHER_LIST, &head, &tail, + strict)) { + goto err; + } + rule_p += 7; + if (*rule_p == ':') { + rule_p++; + } + } + + if (*rule_p != '\0' && + !ssl_cipher_process_rulestr(rule_p, &head, &tail, strict)) { + goto err; + } + + // Allocate new "cipherstack" for the result, return with error + // if we cannot get one. + cipherstack = sk_SSL_CIPHER_new_null(); + if (cipherstack == NULL) { + goto err; + } + + in_group_flags = (uint8_t *)OPENSSL_malloc(kCiphersLen); + if (!in_group_flags) { + goto err; + } + + // 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) { + if (curr->active) { + if (!sk_SSL_CIPHER_push(cipherstack, curr->cipher)) { + goto err; + } + in_group_flags[num_in_group_flags++] = curr->in_group; + } + } + OPENSSL_free(co_list); // Not needed any longer + co_list = NULL; + + pref_list = (ssl_cipher_preference_list_st *)OPENSSL_malloc( + sizeof(struct ssl_cipher_preference_list_st)); + if (!pref_list) { + goto err; + } + pref_list->ciphers = cipherstack; + pref_list->in_group_flags = NULL; + if (num_in_group_flags) { + pref_list->in_group_flags = (uint8_t *)OPENSSL_malloc(num_in_group_flags); + if (!pref_list->in_group_flags) { + goto err; + } + OPENSSL_memcpy(pref_list->in_group_flags, in_group_flags, + num_in_group_flags); + } + OPENSSL_free(in_group_flags); + in_group_flags = NULL; + if (*out_cipher_list != NULL) { + ssl_cipher_preference_list_free(*out_cipher_list); + } + *out_cipher_list = pref_list; + pref_list = NULL; + + // Configuring an empty cipher list is an error but still updates the + // output. + if (sk_SSL_CIPHER_num((*out_cipher_list)->ciphers) == 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CIPHER_MATCH); + return false; + } + + return true; + +err: + OPENSSL_free(co_list); + OPENSSL_free(in_group_flags); + sk_SSL_CIPHER_free(cipherstack); + if (pref_list) { + OPENSSL_free(pref_list->in_group_flags); + } + OPENSSL_free(pref_list); + return false; +} + +uint16_t ssl_cipher_get_value(const SSL_CIPHER *cipher) { + uint32_t id = cipher->id; + // All ciphers are SSLv3. + assert((id & 0xff000000) == 0x03000000); + return id & 0xffff; +} + +uint32_t ssl_cipher_auth_mask_for_key(const EVP_PKEY *key) { + switch (EVP_PKEY_id(key)) { + case EVP_PKEY_RSA: + return SSL_aRSA; + case EVP_PKEY_EC: + case EVP_PKEY_ED25519: + // Ed25519 keys in TLS 1.2 repurpose the ECDSA ciphers. + return SSL_aECDSA; + default: + return 0; + } +} + +bool ssl_cipher_uses_certificate_auth(const SSL_CIPHER *cipher) { + return (cipher->algorithm_auth & SSL_aCERT) != 0; +} + +bool ssl_cipher_requires_server_key_exchange(const SSL_CIPHER *cipher) { + // Ephemeral Diffie-Hellman key exchanges require a ServerKeyExchange. It is + // optional or omitted in all others. + return (cipher->algorithm_mkey & SSL_kECDHE) != 0; +} + +size_t ssl_cipher_get_record_split_len(const SSL_CIPHER *cipher) { + size_t block_size; + switch (cipher->algorithm_enc) { + case SSL_3DES: + block_size = 8; + break; + case SSL_AES128: + case SSL_AES256: + block_size = 16; + break; + default: + return 0; + } + + // All supported TLS 1.0 ciphers use SHA-1. + assert(cipher->algorithm_mac == SSL_SHA1); + size_t ret = 1 + SHA_DIGEST_LENGTH; + ret += block_size - (ret % block_size); + return ret; +} + +} // namespace bssl + +using namespace bssl; + +const SSL_CIPHER *SSL_get_cipher_by_value(uint16_t value) { + SSL_CIPHER c; + + c.id = 0x03000000L | value; + return reinterpret_cast(bsearch( + &c, kCiphers, kCiphersLen, sizeof(SSL_CIPHER), ssl_cipher_id_cmp)); +} + +uint32_t SSL_CIPHER_get_id(const SSL_CIPHER *cipher) { return cipher->id; } + +int SSL_CIPHER_is_aead(const SSL_CIPHER *cipher) { + return (cipher->algorithm_mac & SSL_AEAD) != 0; +} + +int SSL_CIPHER_get_cipher_nid(const SSL_CIPHER *cipher) { + switch (cipher->algorithm_enc) { + case SSL_eNULL: + return NID_undef; + case SSL_3DES: + return NID_des_ede3_cbc; + case SSL_AES128: + return NID_aes_128_cbc; + case SSL_AES256: + return NID_aes_256_cbc; + case SSL_AES128GCM: + return NID_aes_128_gcm; + case SSL_AES256GCM: + return NID_aes_256_gcm; + case SSL_CHACHA20POLY1305: + return NID_chacha20_poly1305; + } + assert(0); + return NID_undef; +} + +int SSL_CIPHER_get_digest_nid(const SSL_CIPHER *cipher) { + switch (cipher->algorithm_mac) { + case SSL_AEAD: + return NID_undef; + case SSL_SHA1: + return NID_sha1; + case SSL_SHA256: + return NID_sha256; + case SSL_SHA384: + return NID_sha384; + } + assert(0); + return NID_undef; +} + +int SSL_CIPHER_get_kx_nid(const SSL_CIPHER *cipher) { + switch (cipher->algorithm_mkey) { + case SSL_kRSA: + return NID_kx_rsa; + case SSL_kECDHE: + return NID_kx_ecdhe; + case SSL_kPSK: + return NID_kx_psk; + case SSL_kGENERIC: + return NID_kx_any; + } + assert(0); + return NID_undef; +} + +int SSL_CIPHER_get_auth_nid(const SSL_CIPHER *cipher) { + switch (cipher->algorithm_auth) { + case SSL_aRSA: + return NID_auth_rsa; + case SSL_aECDSA: + return NID_auth_ecdsa; + case SSL_aPSK: + return NID_auth_psk; + case SSL_aGENERIC: + return NID_auth_any; + } + assert(0); + return NID_undef; +} + +int SSL_CIPHER_get_prf_nid(const SSL_CIPHER *cipher) { + switch (cipher->algorithm_prf) { + case SSL_HANDSHAKE_MAC_DEFAULT: + return NID_md5_sha1; + case SSL_HANDSHAKE_MAC_SHA256: + return NID_sha256; + case SSL_HANDSHAKE_MAC_SHA384: + return NID_sha384; + } + assert(0); + return NID_undef; +} + +int SSL_CIPHER_is_block_cipher(const SSL_CIPHER *cipher) { + return (cipher->algorithm_enc & SSL_eNULL) == 0 && + cipher->algorithm_mac != SSL_AEAD; +} + +uint16_t SSL_CIPHER_get_min_version(const SSL_CIPHER *cipher) { + if (cipher->algorithm_mkey == SSL_kGENERIC || + cipher->algorithm_auth == SSL_aGENERIC) { + return TLS1_3_VERSION; + } + + if (cipher->algorithm_prf != SSL_HANDSHAKE_MAC_DEFAULT) { + // Cipher suites before TLS 1.2 use the default PRF, while all those added + // afterwards specify a particular hash. + return TLS1_2_VERSION; + } + return SSL3_VERSION; +} + +uint16_t SSL_CIPHER_get_max_version(const SSL_CIPHER *cipher) { + if (cipher->algorithm_mkey == SSL_kGENERIC || + cipher->algorithm_auth == SSL_aGENERIC) { + return TLS1_3_VERSION; + } + return TLS1_2_VERSION; +} + +// return the actual cipher being used +const char *SSL_CIPHER_get_name(const SSL_CIPHER *cipher) { + if (cipher != NULL) { + return cipher->name; + } + + return "(NONE)"; +} + +const char *SSL_CIPHER_standard_name(const SSL_CIPHER *cipher) { + return cipher->standard_name; +} + +const char *SSL_CIPHER_get_kx_name(const SSL_CIPHER *cipher) { + if (cipher == NULL) { + return ""; + } + + switch (cipher->algorithm_mkey) { + case SSL_kRSA: + return "RSA"; + + case SSL_kECDHE: + switch (cipher->algorithm_auth) { + case SSL_aECDSA: + return "ECDHE_ECDSA"; + case SSL_aRSA: + return "ECDHE_RSA"; + case SSL_aPSK: + return "ECDHE_PSK"; + default: + assert(0); + return "UNKNOWN"; + } + + case SSL_kPSK: + assert(cipher->algorithm_auth == SSL_aPSK); + return "PSK"; + + case SSL_kGENERIC: + assert(cipher->algorithm_auth == SSL_aGENERIC); + return "GENERIC"; + + default: + assert(0); + return "UNKNOWN"; + } +} + +char *SSL_CIPHER_get_rfc_name(const SSL_CIPHER *cipher) { + if (cipher == NULL) { + return NULL; + } + + return OPENSSL_strdup(SSL_CIPHER_standard_name(cipher)); +} + +int SSL_CIPHER_get_bits(const SSL_CIPHER *cipher, int *out_alg_bits) { + if (cipher == NULL) { + return 0; + } + + int alg_bits, strength_bits; + switch (cipher->algorithm_enc) { + case SSL_AES128: + case SSL_AES128GCM: + alg_bits = 128; + strength_bits = 128; + break; + + case SSL_AES256: + case SSL_AES256GCM: + case SSL_CHACHA20POLY1305: + alg_bits = 256; + strength_bits = 256; + break; + + case SSL_3DES: + alg_bits = 168; + strength_bits = 112; + break; + + case SSL_eNULL: + alg_bits = 0; + strength_bits = 0; + break; + + default: + assert(0); + alg_bits = 0; + strength_bits = 0; + } + + if (out_alg_bits != NULL) { + *out_alg_bits = alg_bits; + } + return strength_bits; +} + +const char *SSL_CIPHER_description(const SSL_CIPHER *cipher, char *buf, + int len) { + const char *kx, *au, *enc, *mac; + uint32_t alg_mkey, alg_auth, alg_enc, alg_mac; + + alg_mkey = cipher->algorithm_mkey; + alg_auth = cipher->algorithm_auth; + alg_enc = cipher->algorithm_enc; + alg_mac = cipher->algorithm_mac; + + switch (alg_mkey) { + case SSL_kRSA: + kx = "RSA"; + break; + + case SSL_kECDHE: + kx = "ECDH"; + break; + + case SSL_kPSK: + kx = "PSK"; + break; + + case SSL_kGENERIC: + kx = "GENERIC"; + break; + + default: + kx = "unknown"; + } + + switch (alg_auth) { + case SSL_aRSA: + au = "RSA"; + break; + + case SSL_aECDSA: + au = "ECDSA"; + break; + + case SSL_aPSK: + au = "PSK"; + break; + + case SSL_aGENERIC: + au = "GENERIC"; + break; + + default: + au = "unknown"; + break; + } + + switch (alg_enc) { + case SSL_3DES: + enc = "3DES(168)"; + 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_CHACHA20POLY1305: + enc = "ChaCha20-Poly1305"; + break; + + case SSL_eNULL: + enc="None"; + break; + + default: + enc = "unknown"; + break; + } + + switch (alg_mac) { + case SSL_SHA1: + mac = "SHA1"; + break; + + case SSL_SHA256: + mac = "SHA256"; + break; + + case SSL_SHA384: + mac = "SHA384"; + break; + + case SSL_AEAD: + mac = "AEAD"; + break; + + default: + mac = "unknown"; + break; + } + + if (buf == NULL) { + len = 128; + buf = (char *)OPENSSL_malloc(len); + if (buf == NULL) { + return NULL; + } + } else if (len < 128) { + return "Buffer too small"; + } + + BIO_snprintf(buf, len, "%-23s Kx=%-8s Au=%-4s Enc=%-9s Mac=%-4s\n", + cipher->name, kx, au, enc, mac); + return buf; +} + +const char *SSL_CIPHER_get_version(const SSL_CIPHER *cipher) { + return "TLSv1/SSLv3"; +} + +STACK_OF(SSL_COMP) *SSL_COMP_get_compression_methods(void) { return NULL; } + +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; } + +const char *SSL_COMP_get0_name(const SSL_COMP *comp) { return comp->name; } + +int SSL_COMP_get_id(const SSL_COMP *comp) { return comp->id; } + +void SSL_COMP_free_compression_methods(void) {} diff --git a/FoodApp/Pods/BoringSSL-GRPC/ssl/ssl_file.cc b/FoodApp/Pods/BoringSSL-GRPC/ssl/ssl_file.cc new file mode 100644 index 0000000..2df6e05 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/ssl/ssl_file.cc @@ -0,0 +1,583 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "internal.h" + + +static int xname_cmp(const X509_NAME **a, const X509_NAME **b) { + return X509_NAME_cmp(*a, *b); +} + +// TODO(davidben): Is there any reason this doesn't call +// |SSL_add_file_cert_subjects_to_stack|? +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()); + + if (sk == NULL || in == NULL) { + OPENSSL_PUT_ERROR(SSL, 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) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + goto err; + } + } + xn = X509_get_subject_name(x); + if (xn == NULL) { + goto err; + } + + // Check for duplicates. + if (sk_X509_NAME_find(sk, NULL, xn)) { + continue; + } + + xn = X509_NAME_dup(xn); + if (xn == NULL || + !sk_X509_NAME_push(sk /* non-owning */, xn) || + !sk_X509_NAME_push(ret /* owning */, xn)) { + X509_NAME_free(xn); + goto err; + } + } + + if (0) { + err: + sk_X509_NAME_pop_free(ret, X509_NAME_free); + ret = NULL; + } + + sk_X509_NAME_free(sk); + BIO_free(in); + X509_free(x); + if (ret != NULL) { + ERR_clear_error(); + } + return ret; +} + +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 = 0; + int (*oldcmp)(const X509_NAME **a, const X509_NAME **b); + + oldcmp = sk_X509_NAME_set_cmp_func(stack, xname_cmp); + in = BIO_new(BIO_s_file()); + + if (in == NULL) { + OPENSSL_PUT_ERROR(SSL, 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; + } + xn = X509_get_subject_name(x); + if (xn == NULL) { + goto err; + } + + // Check for duplicates. + if (sk_X509_NAME_find(stack, NULL, xn)) { + continue; + } + + xn = X509_NAME_dup(xn); + if (xn == NULL || + !sk_X509_NAME_push(stack, xn)) { + X509_NAME_free(xn); + goto err; + } + } + + ERR_clear_error(); + ret = 1; + +err: + BIO_free(in); + X509_free(x); + + (void) sk_X509_NAME_set_cmp_func(stack, oldcmp); + + return ret; +} + +int SSL_use_certificate_file(SSL *ssl, const char *file, int type) { + int reason_code; + BIO *in; + int ret = 0; + X509 *x = NULL; + + in = BIO_new(BIO_s_file()); + if (in == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB); + goto end; + } + + if (BIO_read_filename(in, file) <= 0) { + OPENSSL_PUT_ERROR(SSL, ERR_R_SYS_LIB); + goto end; + } + + if (type == SSL_FILETYPE_ASN1) { + reason_code = ERR_R_ASN1_LIB; + x = d2i_X509_bio(in, NULL); + } else if (type == SSL_FILETYPE_PEM) { + reason_code = ERR_R_PEM_LIB; + x = PEM_read_bio_X509(in, NULL, ssl->ctx->default_passwd_callback, + ssl->ctx->default_passwd_callback_userdata); + } else { + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SSL_FILETYPE); + goto end; + } + + if (x == NULL) { + OPENSSL_PUT_ERROR(SSL, reason_code); + goto end; + } + + ret = SSL_use_certificate(ssl, x); + +end: + X509_free(x); + BIO_free(in); + + return ret; +} + +int SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, int type) { + int reason_code, ret = 0; + BIO *in; + RSA *rsa = NULL; + + in = BIO_new(BIO_s_file()); + if (in == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB); + goto end; + } + + if (BIO_read_filename(in, file) <= 0) { + OPENSSL_PUT_ERROR(SSL, ERR_R_SYS_LIB); + goto end; + } + + if (type == SSL_FILETYPE_ASN1) { + reason_code = ERR_R_ASN1_LIB; + rsa = d2i_RSAPrivateKey_bio(in, NULL); + } else if (type == SSL_FILETYPE_PEM) { + reason_code = ERR_R_PEM_LIB; + rsa = + PEM_read_bio_RSAPrivateKey(in, NULL, ssl->ctx->default_passwd_callback, + ssl->ctx->default_passwd_callback_userdata); + } else { + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SSL_FILETYPE); + goto end; + } + + if (rsa == NULL) { + OPENSSL_PUT_ERROR(SSL, reason_code); + goto end; + } + ret = SSL_use_RSAPrivateKey(ssl, rsa); + RSA_free(rsa); + +end: + BIO_free(in); + return ret; +} + +int SSL_use_PrivateKey_file(SSL *ssl, const char *file, int type) { + int reason_code, ret = 0; + BIO *in; + EVP_PKEY *pkey = NULL; + + in = BIO_new(BIO_s_file()); + if (in == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB); + goto end; + } + + if (BIO_read_filename(in, file) <= 0) { + OPENSSL_PUT_ERROR(SSL, ERR_R_SYS_LIB); + goto end; + } + + if (type == SSL_FILETYPE_PEM) { + reason_code = 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) { + reason_code = ERR_R_ASN1_LIB; + pkey = d2i_PrivateKey_bio(in, NULL); + } else { + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SSL_FILETYPE); + goto end; + } + + if (pkey == NULL) { + OPENSSL_PUT_ERROR(SSL, reason_code); + goto end; + } + ret = SSL_use_PrivateKey(ssl, pkey); + EVP_PKEY_free(pkey); + +end: + BIO_free(in); + return ret; +} + +int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type) { + int reason_code; + BIO *in; + int ret = 0; + X509 *x = NULL; + + in = BIO_new(BIO_s_file()); + if (in == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB); + goto end; + } + + if (BIO_read_filename(in, file) <= 0) { + OPENSSL_PUT_ERROR(SSL, ERR_R_SYS_LIB); + goto end; + } + + if (type == SSL_FILETYPE_ASN1) { + reason_code = ERR_R_ASN1_LIB; + x = d2i_X509_bio(in, NULL); + } else if (type == SSL_FILETYPE_PEM) { + reason_code = ERR_R_PEM_LIB; + x = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback, + ctx->default_passwd_callback_userdata); + } else { + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SSL_FILETYPE); + goto end; + } + + if (x == NULL) { + OPENSSL_PUT_ERROR(SSL, reason_code); + goto end; + } + + ret = SSL_CTX_use_certificate(ctx, x); + +end: + X509_free(x); + BIO_free(in); + return ret; +} + +int SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx, const char *file, int type) { + int reason_code, ret = 0; + BIO *in; + RSA *rsa = NULL; + + in = BIO_new(BIO_s_file()); + if (in == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB); + goto end; + } + + if (BIO_read_filename(in, file) <= 0) { + OPENSSL_PUT_ERROR(SSL, ERR_R_SYS_LIB); + goto end; + } + + if (type == SSL_FILETYPE_ASN1) { + reason_code = ERR_R_ASN1_LIB; + rsa = d2i_RSAPrivateKey_bio(in, NULL); + } else if (type == SSL_FILETYPE_PEM) { + reason_code = ERR_R_PEM_LIB; + rsa = PEM_read_bio_RSAPrivateKey(in, NULL, ctx->default_passwd_callback, + ctx->default_passwd_callback_userdata); + } else { + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SSL_FILETYPE); + goto end; + } + + if (rsa == NULL) { + OPENSSL_PUT_ERROR(SSL, reason_code); + goto end; + } + ret = SSL_CTX_use_RSAPrivateKey(ctx, rsa); + RSA_free(rsa); + +end: + BIO_free(in); + return ret; +} + +int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type) { + int reason_code, ret = 0; + BIO *in; + EVP_PKEY *pkey = NULL; + + in = BIO_new(BIO_s_file()); + if (in == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB); + goto end; + } + + if (BIO_read_filename(in, file) <= 0) { + OPENSSL_PUT_ERROR(SSL, ERR_R_SYS_LIB); + goto end; + } + + if (type == SSL_FILETYPE_PEM) { + reason_code = 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) { + reason_code = ERR_R_ASN1_LIB; + pkey = d2i_PrivateKey_bio(in, NULL); + } else { + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SSL_FILETYPE); + goto end; + } + + if (pkey == NULL) { + OPENSSL_PUT_ERROR(SSL, reason_code); + goto end; + } + ret = SSL_CTX_use_PrivateKey(ctx, pkey); + EVP_PKEY_free(pkey); + +end: + BIO_free(in); + return ret; +} + +// 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()); + if (in == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB); + goto end; + } + + if (BIO_read_filename(in, file) <= 0) { + OPENSSL_PUT_ERROR(SSL, 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) { + OPENSSL_PUT_ERROR(SSL, 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; + uint32_t 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: + X509_free(x); + BIO_free(in); + return ret; +} + +void SSL_CTX_set_default_passwd_cb(SSL_CTX *ctx, pem_password_cb *cb) { + ctx->default_passwd_callback = cb; +} + +pem_password_cb *SSL_CTX_get_default_passwd_cb(const SSL_CTX *ctx) { + return ctx->default_passwd_callback; +} + +void SSL_CTX_set_default_passwd_cb_userdata(SSL_CTX *ctx, void *data) { + ctx->default_passwd_callback_userdata = data; +} + +void *SSL_CTX_get_default_passwd_cb_userdata(const SSL_CTX *ctx) { + return ctx->default_passwd_callback_userdata; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/ssl/ssl_file.cc.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/ssl/ssl_file.cc.grpc_back new file mode 100644 index 0000000..bafa64a --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/ssl/ssl_file.cc.grpc_back @@ -0,0 +1,583 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "internal.h" + + +static int xname_cmp(const X509_NAME **a, const X509_NAME **b) { + return X509_NAME_cmp(*a, *b); +} + +// TODO(davidben): Is there any reason this doesn't call +// |SSL_add_file_cert_subjects_to_stack|? +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()); + + if (sk == NULL || in == NULL) { + OPENSSL_PUT_ERROR(SSL, 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) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + goto err; + } + } + xn = X509_get_subject_name(x); + if (xn == NULL) { + goto err; + } + + // Check for duplicates. + if (sk_X509_NAME_find(sk, NULL, xn)) { + continue; + } + + xn = X509_NAME_dup(xn); + if (xn == NULL || + !sk_X509_NAME_push(sk /* non-owning */, xn) || + !sk_X509_NAME_push(ret /* owning */, xn)) { + X509_NAME_free(xn); + goto err; + } + } + + if (0) { + err: + sk_X509_NAME_pop_free(ret, X509_NAME_free); + ret = NULL; + } + + sk_X509_NAME_free(sk); + BIO_free(in); + X509_free(x); + if (ret != NULL) { + ERR_clear_error(); + } + return ret; +} + +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 = 0; + int (*oldcmp)(const X509_NAME **a, const X509_NAME **b); + + oldcmp = sk_X509_NAME_set_cmp_func(stack, xname_cmp); + in = BIO_new(BIO_s_file()); + + if (in == NULL) { + OPENSSL_PUT_ERROR(SSL, 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; + } + xn = X509_get_subject_name(x); + if (xn == NULL) { + goto err; + } + + // Check for duplicates. + if (sk_X509_NAME_find(stack, NULL, xn)) { + continue; + } + + xn = X509_NAME_dup(xn); + if (xn == NULL || + !sk_X509_NAME_push(stack, xn)) { + X509_NAME_free(xn); + goto err; + } + } + + ERR_clear_error(); + ret = 1; + +err: + BIO_free(in); + X509_free(x); + + (void) sk_X509_NAME_set_cmp_func(stack, oldcmp); + + return ret; +} + +int SSL_use_certificate_file(SSL *ssl, const char *file, int type) { + int reason_code; + BIO *in; + int ret = 0; + X509 *x = NULL; + + in = BIO_new(BIO_s_file()); + if (in == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB); + goto end; + } + + if (BIO_read_filename(in, file) <= 0) { + OPENSSL_PUT_ERROR(SSL, ERR_R_SYS_LIB); + goto end; + } + + if (type == SSL_FILETYPE_ASN1) { + reason_code = ERR_R_ASN1_LIB; + x = d2i_X509_bio(in, NULL); + } else if (type == SSL_FILETYPE_PEM) { + reason_code = ERR_R_PEM_LIB; + x = PEM_read_bio_X509(in, NULL, ssl->ctx->default_passwd_callback, + ssl->ctx->default_passwd_callback_userdata); + } else { + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SSL_FILETYPE); + goto end; + } + + if (x == NULL) { + OPENSSL_PUT_ERROR(SSL, reason_code); + goto end; + } + + ret = SSL_use_certificate(ssl, x); + +end: + X509_free(x); + BIO_free(in); + + return ret; +} + +int SSL_use_RSAPrivateKey_file(SSL *ssl, const char *file, int type) { + int reason_code, ret = 0; + BIO *in; + RSA *rsa = NULL; + + in = BIO_new(BIO_s_file()); + if (in == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB); + goto end; + } + + if (BIO_read_filename(in, file) <= 0) { + OPENSSL_PUT_ERROR(SSL, ERR_R_SYS_LIB); + goto end; + } + + if (type == SSL_FILETYPE_ASN1) { + reason_code = ERR_R_ASN1_LIB; + rsa = d2i_RSAPrivateKey_bio(in, NULL); + } else if (type == SSL_FILETYPE_PEM) { + reason_code = ERR_R_PEM_LIB; + rsa = + PEM_read_bio_RSAPrivateKey(in, NULL, ssl->ctx->default_passwd_callback, + ssl->ctx->default_passwd_callback_userdata); + } else { + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SSL_FILETYPE); + goto end; + } + + if (rsa == NULL) { + OPENSSL_PUT_ERROR(SSL, reason_code); + goto end; + } + ret = SSL_use_RSAPrivateKey(ssl, rsa); + RSA_free(rsa); + +end: + BIO_free(in); + return ret; +} + +int SSL_use_PrivateKey_file(SSL *ssl, const char *file, int type) { + int reason_code, ret = 0; + BIO *in; + EVP_PKEY *pkey = NULL; + + in = BIO_new(BIO_s_file()); + if (in == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB); + goto end; + } + + if (BIO_read_filename(in, file) <= 0) { + OPENSSL_PUT_ERROR(SSL, ERR_R_SYS_LIB); + goto end; + } + + if (type == SSL_FILETYPE_PEM) { + reason_code = 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) { + reason_code = ERR_R_ASN1_LIB; + pkey = d2i_PrivateKey_bio(in, NULL); + } else { + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SSL_FILETYPE); + goto end; + } + + if (pkey == NULL) { + OPENSSL_PUT_ERROR(SSL, reason_code); + goto end; + } + ret = SSL_use_PrivateKey(ssl, pkey); + EVP_PKEY_free(pkey); + +end: + BIO_free(in); + return ret; +} + +int SSL_CTX_use_certificate_file(SSL_CTX *ctx, const char *file, int type) { + int reason_code; + BIO *in; + int ret = 0; + X509 *x = NULL; + + in = BIO_new(BIO_s_file()); + if (in == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB); + goto end; + } + + if (BIO_read_filename(in, file) <= 0) { + OPENSSL_PUT_ERROR(SSL, ERR_R_SYS_LIB); + goto end; + } + + if (type == SSL_FILETYPE_ASN1) { + reason_code = ERR_R_ASN1_LIB; + x = d2i_X509_bio(in, NULL); + } else if (type == SSL_FILETYPE_PEM) { + reason_code = ERR_R_PEM_LIB; + x = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback, + ctx->default_passwd_callback_userdata); + } else { + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SSL_FILETYPE); + goto end; + } + + if (x == NULL) { + OPENSSL_PUT_ERROR(SSL, reason_code); + goto end; + } + + ret = SSL_CTX_use_certificate(ctx, x); + +end: + X509_free(x); + BIO_free(in); + return ret; +} + +int SSL_CTX_use_RSAPrivateKey_file(SSL_CTX *ctx, const char *file, int type) { + int reason_code, ret = 0; + BIO *in; + RSA *rsa = NULL; + + in = BIO_new(BIO_s_file()); + if (in == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB); + goto end; + } + + if (BIO_read_filename(in, file) <= 0) { + OPENSSL_PUT_ERROR(SSL, ERR_R_SYS_LIB); + goto end; + } + + if (type == SSL_FILETYPE_ASN1) { + reason_code = ERR_R_ASN1_LIB; + rsa = d2i_RSAPrivateKey_bio(in, NULL); + } else if (type == SSL_FILETYPE_PEM) { + reason_code = ERR_R_PEM_LIB; + rsa = PEM_read_bio_RSAPrivateKey(in, NULL, ctx->default_passwd_callback, + ctx->default_passwd_callback_userdata); + } else { + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SSL_FILETYPE); + goto end; + } + + if (rsa == NULL) { + OPENSSL_PUT_ERROR(SSL, reason_code); + goto end; + } + ret = SSL_CTX_use_RSAPrivateKey(ctx, rsa); + RSA_free(rsa); + +end: + BIO_free(in); + return ret; +} + +int SSL_CTX_use_PrivateKey_file(SSL_CTX *ctx, const char *file, int type) { + int reason_code, ret = 0; + BIO *in; + EVP_PKEY *pkey = NULL; + + in = BIO_new(BIO_s_file()); + if (in == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB); + goto end; + } + + if (BIO_read_filename(in, file) <= 0) { + OPENSSL_PUT_ERROR(SSL, ERR_R_SYS_LIB); + goto end; + } + + if (type == SSL_FILETYPE_PEM) { + reason_code = 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) { + reason_code = ERR_R_ASN1_LIB; + pkey = d2i_PrivateKey_bio(in, NULL); + } else { + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SSL_FILETYPE); + goto end; + } + + if (pkey == NULL) { + OPENSSL_PUT_ERROR(SSL, reason_code); + goto end; + } + ret = SSL_CTX_use_PrivateKey(ctx, pkey); + EVP_PKEY_free(pkey); + +end: + BIO_free(in); + return ret; +} + +// 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()); + if (in == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB); + goto end; + } + + if (BIO_read_filename(in, file) <= 0) { + OPENSSL_PUT_ERROR(SSL, 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) { + OPENSSL_PUT_ERROR(SSL, 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; + uint32_t 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: + X509_free(x); + BIO_free(in); + return ret; +} + +void SSL_CTX_set_default_passwd_cb(SSL_CTX *ctx, pem_password_cb *cb) { + ctx->default_passwd_callback = cb; +} + +pem_password_cb *SSL_CTX_get_default_passwd_cb(const SSL_CTX *ctx) { + return ctx->default_passwd_callback; +} + +void SSL_CTX_set_default_passwd_cb_userdata(SSL_CTX *ctx, void *data) { + ctx->default_passwd_callback_userdata = data; +} + +void *SSL_CTX_get_default_passwd_cb_userdata(const SSL_CTX *ctx) { + return ctx->default_passwd_callback_userdata; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/ssl/ssl_key_share.cc b/FoodApp/Pods/BoringSSL-GRPC/ssl/ssl_key_share.cc new file mode 100644 index 0000000..8b750ae --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/ssl/ssl_key_share.cc @@ -0,0 +1,252 @@ +/* Copyright (c) 2015, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "internal.h" +#include "../crypto/internal.h" + + +namespace bssl { + +namespace { + +class ECKeyShare : public SSLKeyShare { + public: + ECKeyShare(int nid, uint16_t group_id) : nid_(nid), group_id_(group_id) {} + ~ECKeyShare() override {} + + uint16_t GroupID() const override { return group_id_; } + + bool Offer(CBB *out) override { + assert(!private_key_); + // Set up a shared |BN_CTX| for all operations. + UniquePtr bn_ctx(BN_CTX_new()); + if (!bn_ctx) { + return false; + } + BN_CTXScope scope(bn_ctx.get()); + + // Generate a private key. + UniquePtr group(EC_GROUP_new_by_curve_name(nid_)); + private_key_.reset(BN_new()); + if (!group || !private_key_ || + !BN_rand_range_ex(private_key_.get(), 1, + EC_GROUP_get0_order(group.get()))) { + return false; + } + + // Compute the corresponding public key and serialize it. + UniquePtr public_key(EC_POINT_new(group.get())); + if (!public_key || + !EC_POINT_mul(group.get(), public_key.get(), private_key_.get(), NULL, + NULL, bn_ctx.get()) || + !EC_POINT_point2cbb(out, group.get(), public_key.get(), + POINT_CONVERSION_UNCOMPRESSED, bn_ctx.get())) { + return false; + } + + return true; + } + + bool Finish(Array *out_secret, uint8_t *out_alert, + Span peer_key) override { + assert(private_key_); + *out_alert = SSL_AD_INTERNAL_ERROR; + + // Set up a shared |BN_CTX| for all operations. + UniquePtr bn_ctx(BN_CTX_new()); + if (!bn_ctx) { + return false; + } + BN_CTXScope scope(bn_ctx.get()); + + UniquePtr group(EC_GROUP_new_by_curve_name(nid_)); + if (!group) { + return false; + } + + UniquePtr peer_point(EC_POINT_new(group.get())); + UniquePtr result(EC_POINT_new(group.get())); + BIGNUM *x = BN_CTX_get(bn_ctx.get()); + if (!peer_point || !result || !x) { + return false; + } + + if (peer_key.empty() || peer_key[0] != POINT_CONVERSION_UNCOMPRESSED || + !EC_POINT_oct2point(group.get(), peer_point.get(), peer_key.data(), + peer_key.size(), bn_ctx.get())) { + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_ECPOINT); + *out_alert = SSL_AD_DECODE_ERROR; + return false; + } + + // Compute the x-coordinate of |peer_key| * |private_key_|. + if (!EC_POINT_mul(group.get(), result.get(), NULL, peer_point.get(), + private_key_.get(), bn_ctx.get()) || + !EC_POINT_get_affine_coordinates_GFp(group.get(), result.get(), x, NULL, + bn_ctx.get())) { + return false; + } + + // Encode the x-coordinate left-padded with zeros. + Array secret; + if (!secret.Init((EC_GROUP_get_degree(group.get()) + 7) / 8) || + !BN_bn2bin_padded(secret.data(), secret.size(), x)) { + return false; + } + + *out_secret = std::move(secret); + return true; + } + + private: + UniquePtr private_key_; + int nid_; + uint16_t group_id_; +}; + +class X25519KeyShare : public SSLKeyShare { + public: + X25519KeyShare() {} + ~X25519KeyShare() override { + OPENSSL_cleanse(private_key_, sizeof(private_key_)); + } + + uint16_t GroupID() const override { return SSL_CURVE_X25519; } + + bool Offer(CBB *out) override { + uint8_t public_key[32]; + X25519_keypair(public_key, private_key_); + return !!CBB_add_bytes(out, public_key, sizeof(public_key)); + } + + bool Finish(Array *out_secret, uint8_t *out_alert, + Span peer_key) override { + *out_alert = SSL_AD_INTERNAL_ERROR; + + Array secret; + if (!secret.Init(32)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return false; + } + + if (peer_key.size() != 32 || + !X25519(secret.data(), private_key_, peer_key.data())) { + *out_alert = SSL_AD_DECODE_ERROR; + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_ECPOINT); + return false; + } + + *out_secret = std::move(secret); + return true; + } + + private: + uint8_t private_key_[32]; +}; + +CONSTEXPR_ARRAY struct { + int nid; + uint16_t group_id; + const char name[8], alias[11]; +} kNamedGroups[] = { + {NID_secp224r1, SSL_CURVE_SECP224R1, "P-224", "secp224r1"}, + {NID_X9_62_prime256v1, SSL_CURVE_SECP256R1, "P-256", "prime256v1"}, + {NID_secp384r1, SSL_CURVE_SECP384R1, "P-384", "secp384r1"}, + {NID_secp521r1, SSL_CURVE_SECP521R1, "P-521", "secp521r1"}, + {NID_X25519, SSL_CURVE_X25519, "X25519", "x25519"}, +}; + +} // namespace + +UniquePtr SSLKeyShare::Create(uint16_t group_id) { + switch (group_id) { + case SSL_CURVE_SECP224R1: + return UniquePtr( + New(NID_secp224r1, SSL_CURVE_SECP224R1)); + case SSL_CURVE_SECP256R1: + return UniquePtr( + New(NID_X9_62_prime256v1, SSL_CURVE_SECP256R1)); + case SSL_CURVE_SECP384R1: + return UniquePtr( + New(NID_secp384r1, SSL_CURVE_SECP384R1)); + case SSL_CURVE_SECP521R1: + return UniquePtr( + New(NID_secp521r1, SSL_CURVE_SECP521R1)); + case SSL_CURVE_X25519: + return UniquePtr(New()); + default: + return nullptr; + } +} + +bool SSLKeyShare::Accept(CBB *out_public_key, Array *out_secret, + uint8_t *out_alert, Span peer_key) { + *out_alert = SSL_AD_INTERNAL_ERROR; + return Offer(out_public_key) && + Finish(out_secret, out_alert, peer_key); +} + +int ssl_nid_to_group_id(uint16_t *out_group_id, int nid) { + for (const auto &group : kNamedGroups) { + if (group.nid == nid) { + *out_group_id = group.group_id; + return 1; + } + } + return 0; +} + +int ssl_name_to_group_id(uint16_t *out_group_id, const char *name, size_t len) { + for (const auto &group : kNamedGroups) { + if (len == strlen(group.name) && + !strncmp(group.name, name, len)) { + *out_group_id = group.group_id; + return 1; + } + if (len == strlen(group.alias) && + !strncmp(group.alias, name, len)) { + *out_group_id = group.group_id; + return 1; + } + } + return 0; +} + +} // namespace bssl + +using namespace bssl; + +const char* SSL_get_curve_name(uint16_t group_id) { + for (const auto &group : kNamedGroups) { + if (group.group_id == group_id) { + return group.name; + } + } + return nullptr; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/ssl/ssl_key_share.cc.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/ssl/ssl_key_share.cc.grpc_back new file mode 100644 index 0000000..4d76bb2 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/ssl/ssl_key_share.cc.grpc_back @@ -0,0 +1,252 @@ +/* Copyright (c) 2015, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "internal.h" +#include "../crypto/internal.h" + + +namespace bssl { + +namespace { + +class ECKeyShare : public SSLKeyShare { + public: + ECKeyShare(int nid, uint16_t group_id) : nid_(nid), group_id_(group_id) {} + ~ECKeyShare() override {} + + uint16_t GroupID() const override { return group_id_; } + + bool Offer(CBB *out) override { + assert(!private_key_); + // Set up a shared |BN_CTX| for all operations. + UniquePtr bn_ctx(BN_CTX_new()); + if (!bn_ctx) { + return false; + } + BN_CTXScope scope(bn_ctx.get()); + + // Generate a private key. + UniquePtr group(EC_GROUP_new_by_curve_name(nid_)); + private_key_.reset(BN_new()); + if (!group || !private_key_ || + !BN_rand_range_ex(private_key_.get(), 1, + EC_GROUP_get0_order(group.get()))) { + return false; + } + + // Compute the corresponding public key and serialize it. + UniquePtr public_key(EC_POINT_new(group.get())); + if (!public_key || + !EC_POINT_mul(group.get(), public_key.get(), private_key_.get(), NULL, + NULL, bn_ctx.get()) || + !EC_POINT_point2cbb(out, group.get(), public_key.get(), + POINT_CONVERSION_UNCOMPRESSED, bn_ctx.get())) { + return false; + } + + return true; + } + + bool Finish(Array *out_secret, uint8_t *out_alert, + Span peer_key) override { + assert(private_key_); + *out_alert = SSL_AD_INTERNAL_ERROR; + + // Set up a shared |BN_CTX| for all operations. + UniquePtr bn_ctx(BN_CTX_new()); + if (!bn_ctx) { + return false; + } + BN_CTXScope scope(bn_ctx.get()); + + UniquePtr group(EC_GROUP_new_by_curve_name(nid_)); + if (!group) { + return false; + } + + UniquePtr peer_point(EC_POINT_new(group.get())); + UniquePtr result(EC_POINT_new(group.get())); + BIGNUM *x = BN_CTX_get(bn_ctx.get()); + if (!peer_point || !result || !x) { + return false; + } + + if (peer_key.empty() || peer_key[0] != POINT_CONVERSION_UNCOMPRESSED || + !EC_POINT_oct2point(group.get(), peer_point.get(), peer_key.data(), + peer_key.size(), bn_ctx.get())) { + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_ECPOINT); + *out_alert = SSL_AD_DECODE_ERROR; + return false; + } + + // Compute the x-coordinate of |peer_key| * |private_key_|. + if (!EC_POINT_mul(group.get(), result.get(), NULL, peer_point.get(), + private_key_.get(), bn_ctx.get()) || + !EC_POINT_get_affine_coordinates_GFp(group.get(), result.get(), x, NULL, + bn_ctx.get())) { + return false; + } + + // Encode the x-coordinate left-padded with zeros. + Array secret; + if (!secret.Init((EC_GROUP_get_degree(group.get()) + 7) / 8) || + !BN_bn2bin_padded(secret.data(), secret.size(), x)) { + return false; + } + + *out_secret = std::move(secret); + return true; + } + + private: + UniquePtr private_key_; + int nid_; + uint16_t group_id_; +}; + +class X25519KeyShare : public SSLKeyShare { + public: + X25519KeyShare() {} + ~X25519KeyShare() override { + OPENSSL_cleanse(private_key_, sizeof(private_key_)); + } + + uint16_t GroupID() const override { return SSL_CURVE_X25519; } + + bool Offer(CBB *out) override { + uint8_t public_key[32]; + X25519_keypair(public_key, private_key_); + return !!CBB_add_bytes(out, public_key, sizeof(public_key)); + } + + bool Finish(Array *out_secret, uint8_t *out_alert, + Span peer_key) override { + *out_alert = SSL_AD_INTERNAL_ERROR; + + Array secret; + if (!secret.Init(32)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return false; + } + + if (peer_key.size() != 32 || + !X25519(secret.data(), private_key_, peer_key.data())) { + *out_alert = SSL_AD_DECODE_ERROR; + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_ECPOINT); + return false; + } + + *out_secret = std::move(secret); + return true; + } + + private: + uint8_t private_key_[32]; +}; + +CONSTEXPR_ARRAY struct { + int nid; + uint16_t group_id; + const char name[8], alias[11]; +} kNamedGroups[] = { + {NID_secp224r1, SSL_CURVE_SECP224R1, "P-224", "secp224r1"}, + {NID_X9_62_prime256v1, SSL_CURVE_SECP256R1, "P-256", "prime256v1"}, + {NID_secp384r1, SSL_CURVE_SECP384R1, "P-384", "secp384r1"}, + {NID_secp521r1, SSL_CURVE_SECP521R1, "P-521", "secp521r1"}, + {NID_X25519, SSL_CURVE_X25519, "X25519", "x25519"}, +}; + +} // namespace + +UniquePtr SSLKeyShare::Create(uint16_t group_id) { + switch (group_id) { + case SSL_CURVE_SECP224R1: + return UniquePtr( + New(NID_secp224r1, SSL_CURVE_SECP224R1)); + case SSL_CURVE_SECP256R1: + return UniquePtr( + New(NID_X9_62_prime256v1, SSL_CURVE_SECP256R1)); + case SSL_CURVE_SECP384R1: + return UniquePtr( + New(NID_secp384r1, SSL_CURVE_SECP384R1)); + case SSL_CURVE_SECP521R1: + return UniquePtr( + New(NID_secp521r1, SSL_CURVE_SECP521R1)); + case SSL_CURVE_X25519: + return UniquePtr(New()); + default: + return nullptr; + } +} + +bool SSLKeyShare::Accept(CBB *out_public_key, Array *out_secret, + uint8_t *out_alert, Span peer_key) { + *out_alert = SSL_AD_INTERNAL_ERROR; + return Offer(out_public_key) && + Finish(out_secret, out_alert, peer_key); +} + +int ssl_nid_to_group_id(uint16_t *out_group_id, int nid) { + for (const auto &group : kNamedGroups) { + if (group.nid == nid) { + *out_group_id = group.group_id; + return 1; + } + } + return 0; +} + +int ssl_name_to_group_id(uint16_t *out_group_id, const char *name, size_t len) { + for (const auto &group : kNamedGroups) { + if (len == strlen(group.name) && + !strncmp(group.name, name, len)) { + *out_group_id = group.group_id; + return 1; + } + if (len == strlen(group.alias) && + !strncmp(group.alias, name, len)) { + *out_group_id = group.group_id; + return 1; + } + } + return 0; +} + +} // namespace bssl + +using namespace bssl; + +const char* SSL_get_curve_name(uint16_t group_id) { + for (const auto &group : kNamedGroups) { + if (group.group_id == group_id) { + return group.name; + } + } + return nullptr; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/ssl/ssl_lib.cc b/FoodApp/Pods/BoringSSL-GRPC/ssl/ssl_lib.cc new file mode 100644 index 0000000..31aa5b3 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/ssl/ssl_lib.cc @@ -0,0 +1,2719 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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. + */ +/* ==================================================================== + * 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 +#include + +#include +#include +#include +#include +#include +#include + +#include "internal.h" +#include "../crypto/internal.h" + +#if defined(OPENSSL_WINDOWS) +#include +#else +#include +#include +#endif + + +namespace bssl { + +// |SSL_R_UNKNOWN_PROTOCOL| is no longer emitted, but continue to define it +// to avoid downstream churn. +OPENSSL_DECLARE_ERROR_REASON(SSL, UNKNOWN_PROTOCOL) + +// The following errors are no longer emitted, but are used in nginx without +// #ifdefs. +OPENSSL_DECLARE_ERROR_REASON(SSL, BLOCK_CIPHER_PAD_IS_WRONG) +OPENSSL_DECLARE_ERROR_REASON(SSL, NO_CIPHERS_SPECIFIED) + +// Some error codes are special. Ensure the make_errors.go script never +// regresses this. +static_assert(SSL_R_TLSV1_ALERT_NO_RENEGOTIATION == + SSL_AD_NO_RENEGOTIATION + SSL_AD_REASON_OFFSET, + "alert reason code mismatch"); + +// kMaxHandshakeSize is the maximum size, in bytes, of a handshake message. +static const size_t kMaxHandshakeSize = (1u << 24) - 1; + +static CRYPTO_EX_DATA_CLASS g_ex_data_class_ssl = + CRYPTO_EX_DATA_CLASS_INIT_WITH_APP_DATA; +static CRYPTO_EX_DATA_CLASS g_ex_data_class_ssl_ctx = + CRYPTO_EX_DATA_CLASS_INIT_WITH_APP_DATA; + +bool CBBFinishArray(CBB *cbb, Array *out) { + uint8_t *ptr; + size_t len; + if (!CBB_finish(cbb, &ptr, &len)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return false; + } + out->Reset(ptr, len); + return true; +} + +void ssl_reset_error_state(SSL *ssl) { + // Functions which use |SSL_get_error| must reset I/O and error state on + // entry. + ssl->s3->rwstate = SSL_NOTHING; + ERR_clear_error(); + ERR_clear_system_error(); +} + +void ssl_set_read_error(SSL* ssl) { + ssl->s3->read_shutdown = ssl_shutdown_error; + ssl->s3->read_error.reset(ERR_save_state()); +} + +static bool check_read_error(const SSL *ssl) { + if (ssl->s3->read_shutdown == ssl_shutdown_error) { + ERR_restore_state(ssl->s3->read_error.get()); + return false; + } + return true; +} + +int ssl_can_write(const SSL *ssl) { + return !SSL_in_init(ssl) || ssl->s3->hs->can_early_write; +} + +int ssl_can_read(const SSL *ssl) { + return !SSL_in_init(ssl) || ssl->s3->hs->can_early_read; +} + +ssl_open_record_t ssl_open_handshake(SSL *ssl, size_t *out_consumed, + uint8_t *out_alert, Span in) { + *out_consumed = 0; + if (!check_read_error(ssl)) { + *out_alert = 0; + return ssl_open_record_error; + } + auto ret = ssl->method->open_handshake(ssl, out_consumed, out_alert, in); + if (ret == ssl_open_record_error) { + ssl_set_read_error(ssl); + } + return ret; +} + +ssl_open_record_t ssl_open_change_cipher_spec(SSL *ssl, size_t *out_consumed, + uint8_t *out_alert, + Span in) { + *out_consumed = 0; + if (!check_read_error(ssl)) { + *out_alert = 0; + return ssl_open_record_error; + } + auto ret = + ssl->method->open_change_cipher_spec(ssl, out_consumed, out_alert, in); + if (ret == ssl_open_record_error) { + ssl_set_read_error(ssl); + } + return ret; +} + +ssl_open_record_t ssl_open_app_data(SSL *ssl, Span *out, + size_t *out_consumed, uint8_t *out_alert, + Span in) { + *out_consumed = 0; + if (!check_read_error(ssl)) { + *out_alert = 0; + return ssl_open_record_error; + } + auto ret = ssl->method->open_app_data(ssl, out, out_consumed, out_alert, in); + if (ret == ssl_open_record_error) { + ssl_set_read_error(ssl); + } + return ret; +} + +void ssl_cipher_preference_list_free( + struct ssl_cipher_preference_list_st *cipher_list) { + if (cipher_list == NULL) { + return; + } + sk_SSL_CIPHER_free(cipher_list->ciphers); + OPENSSL_free(cipher_list->in_group_flags); + OPENSSL_free(cipher_list); +} + +void ssl_update_cache(SSL_HANDSHAKE *hs, int mode) { + SSL *const ssl = hs->ssl; + SSL_CTX *ctx = ssl->session_ctx; + // Never cache sessions with empty session IDs. + if (ssl->s3->established_session->session_id_length == 0 || + ssl->s3->established_session->not_resumable || + (ctx->session_cache_mode & mode) != mode) { + return; + } + + // Clients never use the internal session cache. + int use_internal_cache = ssl->server && !(ctx->session_cache_mode & + SSL_SESS_CACHE_NO_INTERNAL_STORE); + + // A client may see new sessions on abbreviated handshakes if the server + // decides to renew the ticket. Once the handshake is completed, it should be + // inserted into the cache. + if (ssl->s3->established_session.get() != ssl->session || + (!ssl->server && hs->ticket_expected)) { + if (use_internal_cache) { + SSL_CTX_add_session(ctx, ssl->s3->established_session.get()); + } + if (ctx->new_session_cb != NULL) { + SSL_SESSION_up_ref(ssl->s3->established_session.get()); + if (!ctx->new_session_cb(ssl, ssl->s3->established_session.get())) { + // |new_session_cb|'s return value signals whether it took ownership. + SSL_SESSION_free(ssl->s3->established_session.get()); + } + } + } + + if (use_internal_cache && + !(ctx->session_cache_mode & SSL_SESS_CACHE_NO_AUTO_CLEAR)) { + // Automatically flush the internal session cache every 255 connections. + int flush_cache = 0; + CRYPTO_MUTEX_lock_write(&ctx->lock); + ctx->handshakes_since_cache_flush++; + if (ctx->handshakes_since_cache_flush >= 255) { + flush_cache = 1; + ctx->handshakes_since_cache_flush = 0; + } + CRYPTO_MUTEX_unlock_write(&ctx->lock); + + if (flush_cache) { + struct OPENSSL_timeval now; + ssl_get_current_time(ssl, &now); + SSL_CTX_flush_sessions(ctx, now.tv_sec); + } + } +} + +static int cbb_add_hex(CBB *cbb, const uint8_t *in, size_t in_len) { + static const char hextable[] = "0123456789abcdef"; + uint8_t *out; + + if (!CBB_add_space(cbb, &out, in_len * 2)) { + return 0; + } + + for (size_t i = 0; i < in_len; i++) { + *(out++) = (uint8_t)hextable[in[i] >> 4]; + *(out++) = (uint8_t)hextable[in[i] & 0xf]; + } + + return 1; +} + +int ssl_log_secret(const SSL *ssl, const char *label, const uint8_t *secret, + size_t secret_len) { + if (ssl->ctx->keylog_callback == NULL) { + return 1; + } + + ScopedCBB cbb; + uint8_t *out; + size_t out_len; + if (!CBB_init(cbb.get(), strlen(label) + 1 + SSL3_RANDOM_SIZE * 2 + 1 + + secret_len * 2 + 1) || + !CBB_add_bytes(cbb.get(), (const uint8_t *)label, strlen(label)) || + !CBB_add_bytes(cbb.get(), (const uint8_t *)" ", 1) || + !cbb_add_hex(cbb.get(), ssl->s3->client_random, SSL3_RANDOM_SIZE) || + !CBB_add_bytes(cbb.get(), (const uint8_t *)" ", 1) || + !cbb_add_hex(cbb.get(), secret, secret_len) || + !CBB_add_u8(cbb.get(), 0 /* NUL */) || + !CBB_finish(cbb.get(), &out, &out_len)) { + return 0; + } + + ssl->ctx->keylog_callback(ssl, (const char *)out); + OPENSSL_free(out); + return 1; +} + +void ssl_do_info_callback(const SSL *ssl, int type, int value) { + void (*cb)(const SSL *ssl, int type, int value) = NULL; + if (ssl->info_callback != NULL) { + cb = ssl->info_callback; + } else if (ssl->ctx->info_callback != NULL) { + cb = ssl->ctx->info_callback; + } + + if (cb != NULL) { + cb(ssl, type, value); + } +} + +void ssl_do_msg_callback(SSL *ssl, int is_write, int content_type, + Span in) { + if (ssl->msg_callback == NULL) { + return; + } + + // |version| is zero when calling for |SSL3_RT_HEADER| and |SSL2_VERSION| for + // a V2ClientHello. + int version; + switch (content_type) { + case 0: + // V2ClientHello + version = SSL2_VERSION; + break; + case SSL3_RT_HEADER: + version = 0; + break; + default: + version = SSL_version(ssl); + } + + ssl->msg_callback(is_write, version, content_type, in.data(), in.size(), ssl, + ssl->msg_callback_arg); +} + +void ssl_get_current_time(const SSL *ssl, struct OPENSSL_timeval *out_clock) { + // TODO(martinkr): Change callers to |ssl_ctx_get_current_time| and drop the + // |ssl| arg from |current_time_cb| if possible. + ssl_ctx_get_current_time(ssl->ctx, out_clock); +} + +void ssl_ctx_get_current_time(const SSL_CTX *ctx, + struct OPENSSL_timeval *out_clock) { + if (ctx->current_time_cb != NULL) { + // TODO(davidben): Update current_time_cb to use OPENSSL_timeval. See + // https://crbug.com/boringssl/155. + struct timeval clock; + ctx->current_time_cb(nullptr /* ssl */, &clock); + if (clock.tv_sec < 0) { + assert(0); + out_clock->tv_sec = 0; + out_clock->tv_usec = 0; + } else { + out_clock->tv_sec = (uint64_t)clock.tv_sec; + out_clock->tv_usec = (uint32_t)clock.tv_usec; + } + return; + } + +#if defined(BORINGSSL_UNSAFE_DETERMINISTIC_MODE) + out_clock->tv_sec = 1234; + out_clock->tv_usec = 1234; +#elif defined(OPENSSL_WINDOWS) + struct _timeb time; + _ftime(&time); + if (time.time < 0) { + assert(0); + out_clock->tv_sec = 0; + out_clock->tv_usec = 0; + } else { + out_clock->tv_sec = time.time; + out_clock->tv_usec = time.millitm * 1000; + } +#else + struct timeval clock; + gettimeofday(&clock, NULL); + if (clock.tv_sec < 0) { + assert(0); + out_clock->tv_sec = 0; + out_clock->tv_usec = 0; + } else { + out_clock->tv_sec = (uint64_t)clock.tv_sec; + out_clock->tv_usec = (uint32_t)clock.tv_usec; + } +#endif +} + +void SSL_CTX_set_handoff_mode(SSL_CTX *ctx, bool on) { + ctx->handoff = on; +} + +} // namespace bssl + +using namespace bssl; + +int SSL_library_init(void) { + CRYPTO_library_init(); + return 1; +} + +int OPENSSL_init_ssl(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings) { + CRYPTO_library_init(); + return 1; +} + +static uint32_t ssl_session_hash(const SSL_SESSION *sess) { + const uint8_t *session_id = sess->session_id; + + uint8_t tmp_storage[sizeof(uint32_t)]; + if (sess->session_id_length < sizeof(tmp_storage)) { + OPENSSL_memset(tmp_storage, 0, sizeof(tmp_storage)); + OPENSSL_memcpy(tmp_storage, sess->session_id, sess->session_id_length); + session_id = tmp_storage; + } + + uint32_t hash = + ((uint32_t)session_id[0]) | + ((uint32_t)session_id[1] << 8) | + ((uint32_t)session_id[2] << 16) | + ((uint32_t)session_id[3] << 24); + + return hash; +} + +// 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 OPENSSL_memcmp(a->session_id, b->session_id, a->session_id_length); +} + +SSL_CTX *SSL_CTX_new(const SSL_METHOD *method) { + SSL_CTX *ret = NULL; + + if (method == NULL) { + OPENSSL_PUT_ERROR(SSL, SSL_R_NULL_SSL_METHOD_PASSED); + return NULL; + } + + ret = (SSL_CTX *)OPENSSL_malloc(sizeof(SSL_CTX)); + if (ret == NULL) { + goto err; + } + + OPENSSL_memset(ret, 0, sizeof(SSL_CTX)); + + ret->method = method->method; + ret->x509_method = method->x509_method; + + CRYPTO_MUTEX_init(&ret->lock); + + ret->session_cache_mode = SSL_SESS_CACHE_SERVER; + ret->session_cache_size = SSL_SESSION_CACHE_MAX_SIZE_DEFAULT; + + ret->session_timeout = SSL_DEFAULT_SESSION_TIMEOUT; + ret->session_psk_dhe_timeout = SSL_DEFAULT_SESSION_PSK_DHE_TIMEOUT; + + ret->references = 1; + + ret->max_cert_list = SSL_MAX_CERT_LIST_DEFAULT; + ret->verify_mode = SSL_VERIFY_NONE; + ret->cert = ssl_cert_new(method->x509_method); + if (ret->cert == NULL) { + goto err; + } + + ret->sessions = lh_SSL_SESSION_new(ssl_session_hash, ssl_session_cmp); + if (ret->sessions == NULL) { + goto err; + } + + if (!ret->x509_method->ssl_ctx_new(ret)) { + goto err; + } + + if (!SSL_CTX_set_strict_cipher_list(ret, SSL_DEFAULT_CIPHER_LIST)) { + goto err2; + } + + ret->client_CA = sk_CRYPTO_BUFFER_new_null(); + if (ret->client_CA == NULL) { + goto err; + } + + CRYPTO_new_ex_data(&ret->ex_data); + + ret->max_send_fragment = SSL3_RT_MAX_PLAIN_LENGTH; + + // Disable the auto-chaining feature by default. Once this has stuck without + // problems, the feature will be removed entirely. + ret->mode = SSL_MODE_NO_AUTO_CHAIN; + + // Lock the SSL_CTX to the specified version, for compatibility with legacy + // uses of SSL_METHOD. + if (!SSL_CTX_set_max_proto_version(ret, method->version) || + !SSL_CTX_set_min_proto_version(ret, method->version)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + goto err2; + } + + return ret; + +err: + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); +err2: + SSL_CTX_free(ret); + return NULL; +} + +int SSL_CTX_up_ref(SSL_CTX *ctx) { + CRYPTO_refcount_inc(&ctx->references); + return 1; +} + +void SSL_CTX_free(SSL_CTX *ctx) { + if (ctx == NULL || + !CRYPTO_refcount_dec_and_test_zero(&ctx->references)) { + return; + } + + // 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].) + SSL_CTX_flush_sessions(ctx, 0); + + CRYPTO_free_ex_data(&g_ex_data_class_ssl_ctx, ctx, &ctx->ex_data); + + CRYPTO_MUTEX_cleanup(&ctx->lock); + lh_SSL_SESSION_free(ctx->sessions); + ssl_cipher_preference_list_free(ctx->cipher_list); + ssl_cert_free(ctx->cert); + sk_SSL_CUSTOM_EXTENSION_pop_free(ctx->client_custom_extensions, + SSL_CUSTOM_EXTENSION_free); + sk_SSL_CUSTOM_EXTENSION_pop_free(ctx->server_custom_extensions, + SSL_CUSTOM_EXTENSION_free); + sk_CRYPTO_BUFFER_pop_free(ctx->client_CA, CRYPTO_BUFFER_free); + ctx->x509_method->ssl_ctx_free(ctx); + sk_SRTP_PROTECTION_PROFILE_free(ctx->srtp_profiles); + OPENSSL_free(ctx->psk_identity_hint); + OPENSSL_free(ctx->supported_group_list); + OPENSSL_free(ctx->alpn_client_proto_list); + EVP_PKEY_free(ctx->tlsext_channel_id_private); + OPENSSL_free(ctx->verify_sigalgs); + OPENSSL_free(ctx->tlsext_ticket_key_current); + OPENSSL_free(ctx->tlsext_ticket_key_prev); + + OPENSSL_free(ctx); +} + +SSL *SSL_new(SSL_CTX *ctx) { + if (ctx == NULL) { + OPENSSL_PUT_ERROR(SSL, SSL_R_NULL_SSL_CTX); + return NULL; + } + if (ctx->method == NULL) { + OPENSSL_PUT_ERROR(SSL, SSL_R_SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION); + return NULL; + } + + SSL *ssl = (SSL *)OPENSSL_malloc(sizeof(SSL)); + if (ssl == NULL) { + goto err; + } + OPENSSL_memset(ssl, 0, sizeof(SSL)); + + ssl->conf_min_version = ctx->conf_min_version; + ssl->conf_max_version = ctx->conf_max_version; + ssl->tls13_variant = ctx->tls13_variant; + + // RFC 6347 states that implementations SHOULD use an initial timer value of + // 1 second. + ssl->initial_timeout_duration_ms = 1000; + + ssl->options = ctx->options; + ssl->mode = ctx->mode; + ssl->max_cert_list = ctx->max_cert_list; + + ssl->cert = ssl_cert_dup(ctx->cert); + if (ssl->cert == NULL) { + goto err; + } + + ssl->msg_callback = ctx->msg_callback; + ssl->msg_callback_arg = ctx->msg_callback_arg; + ssl->verify_mode = ctx->verify_mode; + ssl->verify_callback = ctx->default_verify_callback; + ssl->custom_verify_callback = ctx->custom_verify_callback; + ssl->retain_only_sha256_of_client_certs = + ctx->retain_only_sha256_of_client_certs; + + ssl->quiet_shutdown = ctx->quiet_shutdown; + ssl->max_send_fragment = ctx->max_send_fragment; + + SSL_CTX_up_ref(ctx); + ssl->ctx = ctx; + SSL_CTX_up_ref(ctx); + ssl->session_ctx = ctx; + + if (!ssl->ctx->x509_method->ssl_new(ssl)) { + goto err; + } + + if (ctx->supported_group_list) { + ssl->supported_group_list = (uint16_t *)BUF_memdup( + ctx->supported_group_list, ctx->supported_group_list_len * 2); + if (!ssl->supported_group_list) { + goto err; + } + ssl->supported_group_list_len = ctx->supported_group_list_len; + } + + if (ctx->alpn_client_proto_list) { + ssl->alpn_client_proto_list = (uint8_t *)BUF_memdup( + ctx->alpn_client_proto_list, ctx->alpn_client_proto_list_len); + if (ssl->alpn_client_proto_list == NULL) { + goto err; + } + ssl->alpn_client_proto_list_len = ctx->alpn_client_proto_list_len; + } + + ssl->method = ctx->method; + + if (!ssl->method->ssl_new(ssl)) { + goto err; + } + + CRYPTO_new_ex_data(&ssl->ex_data); + + ssl->psk_identity_hint = NULL; + if (ctx->psk_identity_hint) { + ssl->psk_identity_hint = BUF_strdup(ctx->psk_identity_hint); + if (ssl->psk_identity_hint == NULL) { + goto err; + } + } + ssl->psk_client_callback = ctx->psk_client_callback; + ssl->psk_server_callback = ctx->psk_server_callback; + + ssl->tlsext_channel_id_enabled = ctx->tlsext_channel_id_enabled; + if (ctx->tlsext_channel_id_private) { + EVP_PKEY_up_ref(ctx->tlsext_channel_id_private); + ssl->tlsext_channel_id_private = ctx->tlsext_channel_id_private; + } + + ssl->signed_cert_timestamps_enabled = ctx->signed_cert_timestamps_enabled; + ssl->ocsp_stapling_enabled = ctx->ocsp_stapling_enabled; + ssl->handoff = ctx->handoff; + + return ssl; + +err: + SSL_free(ssl); + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + + return NULL; +} + +void SSL_free(SSL *ssl) { + if (ssl == NULL) { + return; + } + + if (ssl->ctx != NULL) { + ssl->ctx->x509_method->ssl_free(ssl); + } + + CRYPTO_free_ex_data(&g_ex_data_class_ssl, ssl, &ssl->ex_data); + + BIO_free_all(ssl->rbio); + BIO_free_all(ssl->wbio); + + // add extra stuff + ssl_cipher_preference_list_free(ssl->cipher_list); + + SSL_SESSION_free(ssl->session); + + ssl_cert_free(ssl->cert); + + OPENSSL_free(ssl->tlsext_hostname); + SSL_CTX_free(ssl->session_ctx); + OPENSSL_free(ssl->supported_group_list); + OPENSSL_free(ssl->alpn_client_proto_list); + OPENSSL_free(ssl->token_binding_params); + OPENSSL_free(ssl->quic_transport_params); + EVP_PKEY_free(ssl->tlsext_channel_id_private); + OPENSSL_free(ssl->psk_identity_hint); + sk_CRYPTO_BUFFER_pop_free(ssl->client_CA, CRYPTO_BUFFER_free); + sk_SRTP_PROTECTION_PROFILE_free(ssl->srtp_profiles); + + if (ssl->method != NULL) { + ssl->method->ssl_free(ssl); + } + SSL_CTX_free(ssl->ctx); + + OPENSSL_free(ssl); +} + +void SSL_set_connect_state(SSL *ssl) { + ssl->server = false; + ssl->do_handshake = ssl_client_handshake; +} + +void SSL_set_accept_state(SSL *ssl) { + ssl->server = true; + ssl->do_handshake = ssl_server_handshake; +} + +void SSL_set0_rbio(SSL *ssl, BIO *rbio) { + BIO_free_all(ssl->rbio); + ssl->rbio = rbio; +} + +void SSL_set0_wbio(SSL *ssl, BIO *wbio) { + BIO_free_all(ssl->wbio); + ssl->wbio = wbio; +} + +void SSL_set_bio(SSL *ssl, BIO *rbio, BIO *wbio) { + // For historical reasons, this function has many different cases in ownership + // handling. + + // If nothing has changed, do nothing + if (rbio == SSL_get_rbio(ssl) && wbio == SSL_get_wbio(ssl)) { + return; + } + + // If the two arguments are equal, one fewer reference is granted than + // taken. + if (rbio != NULL && rbio == wbio) { + BIO_up_ref(rbio); + } + + // If only the wbio is changed, adopt only one reference. + if (rbio == SSL_get_rbio(ssl)) { + SSL_set0_wbio(ssl, wbio); + return; + } + + // There is an asymmetry here for historical reasons. If only the rbio is + // changed AND the rbio and wbio were originally different, then we only adopt + // one reference. + if (wbio == SSL_get_wbio(ssl) && SSL_get_rbio(ssl) != SSL_get_wbio(ssl)) { + SSL_set0_rbio(ssl, rbio); + return; + } + + // Otherwise, adopt both references. + SSL_set0_rbio(ssl, rbio); + SSL_set0_wbio(ssl, wbio); +} + +BIO *SSL_get_rbio(const SSL *ssl) { return ssl->rbio; } + +BIO *SSL_get_wbio(const SSL *ssl) { return ssl->wbio; } + +int SSL_do_handshake(SSL *ssl) { + ssl_reset_error_state(ssl); + + if (ssl->do_handshake == NULL) { + OPENSSL_PUT_ERROR(SSL, SSL_R_CONNECTION_TYPE_NOT_SET); + return -1; + } + + if (!SSL_in_init(ssl)) { + return 1; + } + + // Run the handshake. + SSL_HANDSHAKE *hs = ssl->s3->hs.get(); + + bool early_return = false; + int ret = ssl_run_handshake(hs, &early_return); + ssl_do_info_callback( + ssl, ssl->server ? SSL_CB_ACCEPT_EXIT : SSL_CB_CONNECT_EXIT, ret); + if (ret <= 0) { + return ret; + } + + // Destroy the handshake object if the handshake has completely finished. + if (!early_return) { + ssl->s3->hs.reset(); + } + + return 1; +} + +int SSL_connect(SSL *ssl) { + if (ssl->do_handshake == NULL) { + // Not properly initialized yet + SSL_set_connect_state(ssl); + } + + return SSL_do_handshake(ssl); +} + +int SSL_accept(SSL *ssl) { + if (ssl->do_handshake == NULL) { + // Not properly initialized yet + SSL_set_accept_state(ssl); + } + + return SSL_do_handshake(ssl); +} + +static int ssl_do_post_handshake(SSL *ssl, const SSLMessage &msg) { + if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) { + return tls13_post_handshake(ssl, msg); + } + + // We do not accept renegotiations as a server or SSL 3.0. SSL 3.0 will be + // removed entirely in the future and requires retaining more data for + // renegotiation_info. + if (ssl->server || ssl->version == SSL3_VERSION) { + goto no_renegotiation; + } + + if (msg.type != SSL3_MT_HELLO_REQUEST || CBS_len(&msg.body) != 0) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_HELLO_REQUEST); + return 0; + } + + switch (ssl->renegotiate_mode) { + case ssl_renegotiate_ignore: + // Ignore the HelloRequest. + return 1; + + case ssl_renegotiate_once: + if (ssl->s3->total_renegotiations != 0) { + goto no_renegotiation; + } + break; + + case ssl_renegotiate_never: + goto no_renegotiation; + + case ssl_renegotiate_freely: + break; + } + + // Renegotiation is only supported at quiescent points in the application + // protocol, namely in HTTPS, just before reading the HTTP response. Require + // the record-layer be idle and avoid complexities of sending a handshake + // record while an application_data record is being written. + if (!ssl->s3->write_buffer.empty() || + ssl->s3->write_shutdown != ssl_shutdown_none) { + goto no_renegotiation; + } + + // Begin a new handshake. + if (ssl->s3->hs != nullptr) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return 0; + } + ssl->s3->hs = ssl_handshake_new(ssl); + if (ssl->s3->hs == nullptr) { + return 0; + } + + ssl->s3->total_renegotiations++; + return 1; + +no_renegotiation: + OPENSSL_PUT_ERROR(SSL, SSL_R_NO_RENEGOTIATION); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_NO_RENEGOTIATION); + return 0; +} + +static int ssl_read_impl(SSL *ssl) { + ssl_reset_error_state(ssl); + + if (ssl->do_handshake == NULL) { + OPENSSL_PUT_ERROR(SSL, SSL_R_UNINITIALIZED); + return -1; + } + + // Replay post-handshake message errors. + if (!check_read_error(ssl)) { + return -1; + } + + while (ssl->s3->pending_app_data.empty()) { + // Complete the current handshake, if any. False Start will cause + // |SSL_do_handshake| to return mid-handshake, so this may require multiple + // iterations. + while (!ssl_can_read(ssl)) { + int ret = SSL_do_handshake(ssl); + if (ret < 0) { + return ret; + } + if (ret == 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_SSL_HANDSHAKE_FAILURE); + return -1; + } + } + + // Process any buffered post-handshake messages. + SSLMessage msg; + if (ssl->method->get_message(ssl, &msg)) { + // If we received an interrupt in early read (EndOfEarlyData), loop again + // for the handshake to process it. + if (SSL_in_init(ssl)) { + ssl->s3->hs->can_early_read = false; + continue; + } + + // Handle the post-handshake message and try again. + if (!ssl_do_post_handshake(ssl, msg)) { + ssl_set_read_error(ssl); + return -1; + } + ssl->method->next_message(ssl); + continue; // Loop again. We may have begun a new handshake. + } + + uint8_t alert = SSL_AD_DECODE_ERROR; + size_t consumed = 0; + auto ret = ssl_open_app_data(ssl, &ssl->s3->pending_app_data, &consumed, + &alert, ssl->s3->read_buffer.span()); + bool retry; + int bio_ret = ssl_handle_open_record(ssl, &retry, ret, consumed, alert); + if (bio_ret <= 0) { + return bio_ret; + } + if (!retry) { + assert(!ssl->s3->pending_app_data.empty()); + ssl->s3->key_update_count = 0; + } + } + + return 1; +} + +int SSL_read(SSL *ssl, void *buf, int num) { + int ret = SSL_peek(ssl, buf, num); + if (ret <= 0) { + return ret; + } + // TODO(davidben): In DTLS, should the rest of the record be discarded? DTLS + // is not a stream. See https://crbug.com/boringssl/65. + ssl->s3->pending_app_data = + ssl->s3->pending_app_data.subspan(static_cast(ret)); + if (ssl->s3->pending_app_data.empty()) { + ssl->s3->read_buffer.DiscardConsumed(); + } + return ret; +} + +int SSL_peek(SSL *ssl, void *buf, int num) { + int ret = ssl_read_impl(ssl); + if (ret <= 0) { + return ret; + } + if (num <= 0) { + return num; + } + size_t todo = + std::min(ssl->s3->pending_app_data.size(), static_cast(num)); + OPENSSL_memcpy(buf, ssl->s3->pending_app_data.data(), todo); + return static_cast(todo); +} + +int SSL_write(SSL *ssl, const void *buf, int num) { + ssl_reset_error_state(ssl); + + if (ssl->do_handshake == NULL) { + OPENSSL_PUT_ERROR(SSL, SSL_R_UNINITIALIZED); + return -1; + } + + if (ssl->s3->write_shutdown != ssl_shutdown_none) { + OPENSSL_PUT_ERROR(SSL, SSL_R_PROTOCOL_IS_SHUTDOWN); + return -1; + } + + int ret = 0; + bool needs_handshake = false; + do { + // If necessary, complete the handshake implicitly. + if (!ssl_can_write(ssl)) { + ret = SSL_do_handshake(ssl); + if (ret < 0) { + return ret; + } + if (ret == 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_SSL_HANDSHAKE_FAILURE); + return -1; + } + } + + ret = ssl->method->write_app_data(ssl, &needs_handshake, + (const uint8_t *)buf, num); + } while (needs_handshake); + return ret; +} + +int SSL_shutdown(SSL *ssl) { + ssl_reset_error_state(ssl); + + if (ssl->do_handshake == NULL) { + OPENSSL_PUT_ERROR(SSL, SSL_R_UNINITIALIZED); + return -1; + } + + // If we are in the middle of a handshake, silently succeed. Consumers often + // call this function before |SSL_free|, whether the handshake succeeded or + // not. We assume the caller has already handled failed handshakes. + if (SSL_in_init(ssl)) { + return 1; + } + + if (ssl->quiet_shutdown) { + // Do nothing if configured not to send a close_notify. + ssl->s3->write_shutdown = ssl_shutdown_close_notify; + ssl->s3->read_shutdown = ssl_shutdown_close_notify; + return 1; + } + + // This function completes in two stages. It sends a close_notify and then it + // waits for a close_notify to come in. Perform exactly one action and return + // whether or not it succeeds. + + if (ssl->s3->write_shutdown != ssl_shutdown_close_notify) { + // Send a close_notify. + if (ssl_send_alert(ssl, SSL3_AL_WARNING, SSL_AD_CLOSE_NOTIFY) <= 0) { + return -1; + } + } else if (ssl->s3->alert_dispatch) { + // Finish sending the close_notify. + if (ssl->method->dispatch_alert(ssl) <= 0) { + return -1; + } + } else if (ssl->s3->read_shutdown != ssl_shutdown_close_notify) { + if (SSL_is_dtls(ssl)) { + // Bidirectional shutdown doesn't make sense for an unordered + // transport. DTLS alerts also aren't delivered reliably, so we may even + // time out because the peer never received our close_notify. Report to + // the caller that the channel has fully shut down. + if (ssl->s3->read_shutdown == ssl_shutdown_error) { + ERR_restore_state(ssl->s3->read_error.get()); + return -1; + } + ssl->s3->read_shutdown = ssl_shutdown_close_notify; + } else { + // Keep discarding data until we see a close_notify. + for (;;) { + ssl->s3->pending_app_data = Span(); + int ret = ssl_read_impl(ssl); + if (ret <= 0) { + break; + } + } + if (ssl->s3->read_shutdown != ssl_shutdown_close_notify) { + return -1; + } + } + } + + // Return 0 for unidirectional shutdown and 1 for bidirectional shutdown. + return ssl->s3->read_shutdown == ssl_shutdown_close_notify; +} + +int SSL_send_fatal_alert(SSL *ssl, uint8_t alert) { + if (ssl->s3->alert_dispatch) { + if (ssl->s3->send_alert[0] != SSL3_AL_FATAL || + ssl->s3->send_alert[1] != alert) { + // We are already attempting to write a different alert. + OPENSSL_PUT_ERROR(SSL, SSL_R_PROTOCOL_IS_SHUTDOWN); + return -1; + } + return ssl->method->dispatch_alert(ssl); + } + + return ssl_send_alert(ssl, SSL3_AL_FATAL, alert); +} + +int SSL_set_quic_transport_params(SSL *ssl, const uint8_t *params, + size_t params_len) { + ssl->quic_transport_params = (uint8_t *)BUF_memdup(params, params_len); + if (!ssl->quic_transport_params) { + return 0; + } + ssl->quic_transport_params_len = params_len; + return 1; +} + +void SSL_get_peer_quic_transport_params(const SSL *ssl, + const uint8_t **out_params, + size_t *out_params_len) { + *out_params = ssl->s3->peer_quic_transport_params.data(); + *out_params_len = ssl->s3->peer_quic_transport_params.size(); +} + +void SSL_CTX_set_early_data_enabled(SSL_CTX *ctx, int enabled) { + ctx->cert->enable_early_data = !!enabled; +} + +void SSL_CTX_set_tls13_variant(SSL_CTX *ctx, enum tls13_variant_t variant) { + ctx->tls13_variant = variant; +} + +void SSL_set_tls13_variant(SSL *ssl, enum tls13_variant_t variant) { + ssl->tls13_variant = variant; +} + +void SSL_set_early_data_enabled(SSL *ssl, int enabled) { + ssl->cert->enable_early_data = !!enabled; +} + +int SSL_in_early_data(const SSL *ssl) { + if (ssl->s3->hs == NULL) { + return 0; + } + return ssl->s3->hs->in_early_data; +} + +int SSL_early_data_accepted(const SSL *ssl) { + return ssl->s3->early_data_accepted; +} + +void SSL_reset_early_data_reject(SSL *ssl) { + SSL_HANDSHAKE *hs = ssl->s3->hs.get(); + if (hs == NULL || + hs->wait != ssl_hs_early_data_rejected) { + abort(); + } + + hs->wait = ssl_hs_ok; + hs->in_early_data = false; + hs->early_session.reset(); + + // Discard any unfinished writes from the perspective of |SSL_write|'s + // retry. The handshake will transparently flush out the pending record + // (discarded by the server) to keep the framing correct. + ssl->s3->wpend_pending = false; +} + +static int bio_retry_reason_to_error(int reason) { + switch (reason) { + case BIO_RR_CONNECT: + return SSL_ERROR_WANT_CONNECT; + case BIO_RR_ACCEPT: + return SSL_ERROR_WANT_ACCEPT; + default: + return SSL_ERROR_SYSCALL; + } +} + +int SSL_get_error(const SSL *ssl, int ret_code) { + if (ret_code > 0) { + return SSL_ERROR_NONE; + } + + // Make things return SSL_ERROR_SYSCALL when doing SSL_do_handshake etc, + // where we do encode the error + uint32_t err = ERR_peek_error(); + if (err != 0) { + if (ERR_GET_LIB(err) == ERR_LIB_SYS) { + return SSL_ERROR_SYSCALL; + } + return SSL_ERROR_SSL; + } + + if (ret_code == 0) { + if (ssl->s3->read_shutdown == ssl_shutdown_close_notify) { + return SSL_ERROR_ZERO_RETURN; + } + // An EOF was observed which violates the protocol, and the underlying + // transport does not participate in the error queue. Bubble up to the + // caller. + return SSL_ERROR_SYSCALL; + } + + switch (ssl->s3->rwstate) { + case SSL_PENDING_SESSION: + return SSL_ERROR_PENDING_SESSION; + + case SSL_CERTIFICATE_SELECTION_PENDING: + return SSL_ERROR_PENDING_CERTIFICATE; + + case SSL_HANDOFF: + return SSL_ERROR_HANDOFF; + + case SSL_READING: { + BIO *bio = SSL_get_rbio(ssl); + if (BIO_should_read(bio)) { + return SSL_ERROR_WANT_READ; + } + + if (BIO_should_write(bio)) { + // TODO(davidben): OpenSSL historically checked for writes on the read + // BIO. Can this be removed? + return SSL_ERROR_WANT_WRITE; + } + + if (BIO_should_io_special(bio)) { + return bio_retry_reason_to_error(BIO_get_retry_reason(bio)); + } + + break; + } + + case SSL_WRITING: { + BIO *bio = SSL_get_wbio(ssl); + if (BIO_should_write(bio)) { + return SSL_ERROR_WANT_WRITE; + } + + if (BIO_should_read(bio)) { + // TODO(davidben): OpenSSL historically checked for reads on the write + // BIO. Can this be removed? + return SSL_ERROR_WANT_READ; + } + + if (BIO_should_io_special(bio)) { + return bio_retry_reason_to_error(BIO_get_retry_reason(bio)); + } + + break; + } + + case SSL_X509_LOOKUP: + return SSL_ERROR_WANT_X509_LOOKUP; + + case SSL_CHANNEL_ID_LOOKUP: + return SSL_ERROR_WANT_CHANNEL_ID_LOOKUP; + + case SSL_PRIVATE_KEY_OPERATION: + return SSL_ERROR_WANT_PRIVATE_KEY_OPERATION; + + case SSL_PENDING_TICKET: + return SSL_ERROR_PENDING_TICKET; + + case SSL_EARLY_DATA_REJECTED: + return SSL_ERROR_EARLY_DATA_REJECTED; + + case SSL_CERTIFICATE_VERIFY: + return SSL_ERROR_WANT_CERTIFICATE_VERIFY; + } + + return SSL_ERROR_SYSCALL; +} + +uint32_t SSL_CTX_set_options(SSL_CTX *ctx, uint32_t options) { + ctx->options |= options; + return ctx->options; +} + +uint32_t SSL_CTX_clear_options(SSL_CTX *ctx, uint32_t options) { + ctx->options &= ~options; + return ctx->options; +} + +uint32_t SSL_CTX_get_options(const SSL_CTX *ctx) { return ctx->options; } + +uint32_t SSL_set_options(SSL *ssl, uint32_t options) { + ssl->options |= options; + return ssl->options; +} + +uint32_t SSL_clear_options(SSL *ssl, uint32_t options) { + ssl->options &= ~options; + return ssl->options; +} + +uint32_t SSL_get_options(const SSL *ssl) { return ssl->options; } + +uint32_t SSL_CTX_set_mode(SSL_CTX *ctx, uint32_t mode) { + ctx->mode |= mode; + return ctx->mode; +} + +uint32_t SSL_CTX_clear_mode(SSL_CTX *ctx, uint32_t mode) { + ctx->mode &= ~mode; + return ctx->mode; +} + +uint32_t SSL_CTX_get_mode(const SSL_CTX *ctx) { return ctx->mode; } + +uint32_t SSL_set_mode(SSL *ssl, uint32_t mode) { + ssl->mode |= mode; + return ssl->mode; +} + +uint32_t SSL_clear_mode(SSL *ssl, uint32_t mode) { + ssl->mode &= ~mode; + return ssl->mode; +} + +uint32_t SSL_get_mode(const SSL *ssl) { return ssl->mode; } + +void SSL_CTX_set0_buffer_pool(SSL_CTX *ctx, CRYPTO_BUFFER_POOL *pool) { + ctx->pool = pool; +} + +int SSL_get_tls_unique(const SSL *ssl, uint8_t *out, size_t *out_len, + size_t max_out) { + *out_len = 0; + OPENSSL_memset(out, 0, max_out); + + // tls-unique is not defined for SSL 3.0 or TLS 1.3. + if (!ssl->s3->initial_handshake_complete || + ssl_protocol_version(ssl) < TLS1_VERSION || + ssl_protocol_version(ssl) >= TLS1_3_VERSION) { + return 0; + } + + // The tls-unique value is the first Finished message in the handshake, which + // is the client's in a full handshake and the server's for a resumption. See + // https://tools.ietf.org/html/rfc5929#section-3.1. + const uint8_t *finished = ssl->s3->previous_client_finished; + size_t finished_len = ssl->s3->previous_client_finished_len; + if (ssl->session != NULL) { + // tls-unique is broken for resumed sessions unless EMS is used. + if (!ssl->session->extended_master_secret) { + return 0; + } + finished = ssl->s3->previous_server_finished; + finished_len = ssl->s3->previous_server_finished_len; + } + + *out_len = finished_len; + if (finished_len > max_out) { + *out_len = max_out; + } + + OPENSSL_memcpy(out, finished, *out_len); + return 1; +} + +static int set_session_id_context(CERT *cert, const uint8_t *sid_ctx, + size_t sid_ctx_len) { + if (sid_ctx_len > sizeof(cert->sid_ctx)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG); + return 0; + } + + static_assert(sizeof(cert->sid_ctx) < 256, "sid_ctx too large"); + cert->sid_ctx_length = (uint8_t)sid_ctx_len; + OPENSSL_memcpy(cert->sid_ctx, sid_ctx, sid_ctx_len); + return 1; +} + +int SSL_CTX_set_session_id_context(SSL_CTX *ctx, const uint8_t *sid_ctx, + size_t sid_ctx_len) { + return set_session_id_context(ctx->cert, sid_ctx, sid_ctx_len); +} + +int SSL_set_session_id_context(SSL *ssl, const uint8_t *sid_ctx, + size_t sid_ctx_len) { + return set_session_id_context(ssl->cert, sid_ctx, sid_ctx_len); +} + +const uint8_t *SSL_get0_session_id_context(const SSL *ssl, size_t *out_len) { + *out_len = ssl->cert->sid_ctx_length; + return ssl->cert->sid_ctx; +} + +void SSL_certs_clear(SSL *ssl) { ssl_cert_clear_certs(ssl->cert); } + +int SSL_get_fd(const SSL *ssl) { return SSL_get_rfd(ssl); } + +int SSL_get_rfd(const SSL *ssl) { + int ret = -1; + BIO *b = BIO_find_type(SSL_get_rbio(ssl), BIO_TYPE_DESCRIPTOR); + if (b != NULL) { + BIO_get_fd(b, &ret); + } + return ret; +} + +int SSL_get_wfd(const SSL *ssl) { + int ret = -1; + BIO *b = BIO_find_type(SSL_get_wbio(ssl), BIO_TYPE_DESCRIPTOR); + if (b != NULL) { + BIO_get_fd(b, &ret); + } + return ret; +} + +int SSL_set_fd(SSL *ssl, int fd) { + BIO *bio = BIO_new(BIO_s_socket()); + if (bio == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB); + return 0; + } + BIO_set_fd(bio, fd, BIO_NOCLOSE); + SSL_set_bio(ssl, bio, bio); + return 1; +} + +int SSL_set_wfd(SSL *ssl, int fd) { + BIO *rbio = SSL_get_rbio(ssl); + if (rbio == NULL || BIO_method_type(rbio) != BIO_TYPE_SOCKET || + BIO_get_fd(rbio, NULL) != fd) { + BIO *bio = BIO_new(BIO_s_socket()); + if (bio == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB); + return 0; + } + BIO_set_fd(bio, fd, BIO_NOCLOSE); + SSL_set0_wbio(ssl, bio); + } else { + // Copy the rbio over to the wbio. + BIO_up_ref(rbio); + SSL_set0_wbio(ssl, rbio); + } + + return 1; +} + +int SSL_set_rfd(SSL *ssl, int fd) { + BIO *wbio = SSL_get_wbio(ssl); + if (wbio == NULL || BIO_method_type(wbio) != BIO_TYPE_SOCKET || + BIO_get_fd(wbio, NULL) != fd) { + BIO *bio = BIO_new(BIO_s_socket()); + if (bio == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB); + return 0; + } + BIO_set_fd(bio, fd, BIO_NOCLOSE); + SSL_set0_rbio(ssl, bio); + } else { + // Copy the wbio over to the rbio. + BIO_up_ref(wbio); + SSL_set0_rbio(ssl, wbio); + } + return 1; +} + +static size_t copy_finished(void *out, size_t out_len, const uint8_t *in, + size_t in_len) { + if (out_len > in_len) { + out_len = in_len; + } + OPENSSL_memcpy(out, in, out_len); + return in_len; +} + +size_t SSL_get_finished(const SSL *ssl, void *buf, size_t count) { + if (!ssl->s3->initial_handshake_complete || + ssl_protocol_version(ssl) < TLS1_VERSION || + ssl_protocol_version(ssl) >= TLS1_3_VERSION) { + return 0; + } + + if (ssl->server) { + return copy_finished(buf, count, ssl->s3->previous_server_finished, + ssl->s3->previous_server_finished_len); + } + + return copy_finished(buf, count, ssl->s3->previous_client_finished, + ssl->s3->previous_client_finished_len); +} + +size_t SSL_get_peer_finished(const SSL *ssl, void *buf, size_t count) { + if (!ssl->s3->initial_handshake_complete || + ssl_protocol_version(ssl) < TLS1_VERSION || + ssl_protocol_version(ssl) >= TLS1_3_VERSION) { + return 0; + } + + if (ssl->server) { + return copy_finished(buf, count, ssl->s3->previous_client_finished, + ssl->s3->previous_client_finished_len); + } + + return copy_finished(buf, count, ssl->s3->previous_server_finished, + ssl->s3->previous_server_finished_len); +} + +int SSL_get_verify_mode(const SSL *ssl) { return ssl->verify_mode; } + +int SSL_get_extms_support(const SSL *ssl) { + // TLS 1.3 does not require extended master secret and always reports as + // supporting it. + if (!ssl->s3->have_version) { + return 0; + } + if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) { + return 1; + } + + // If the initial handshake completed, query the established session. + if (ssl->s3->established_session != NULL) { + return ssl->s3->established_session->extended_master_secret; + } + + // Otherwise, query the in-progress handshake. + if (ssl->s3->hs != NULL) { + return ssl->s3->hs->extended_master_secret; + } + assert(0); + return 0; +} + +int SSL_CTX_get_read_ahead(const SSL_CTX *ctx) { return 0; } + +int SSL_get_read_ahead(const SSL *ssl) { return 0; } + +void SSL_CTX_set_read_ahead(SSL_CTX *ctx, int yes) { } + +void SSL_set_read_ahead(SSL *ssl, int yes) { } + +int SSL_pending(const SSL *ssl) { + return static_cast(ssl->s3->pending_app_data.size()); +} + +// Fix this so it checks all the valid key/cert options +int SSL_CTX_check_private_key(const SSL_CTX *ctx) { + return ssl_cert_check_private_key(ctx->cert, ctx->cert->privatekey); +} + +// Fix this function so that it takes an optional type parameter +int SSL_check_private_key(const SSL *ssl) { + return ssl_cert_check_private_key(ssl->cert, ssl->cert->privatekey); +} + +long SSL_get_default_timeout(const SSL *ssl) { + return SSL_DEFAULT_SESSION_TIMEOUT; +} + +int SSL_renegotiate(SSL *ssl) { + // Caller-initiated renegotiation is not supported. + OPENSSL_PUT_ERROR(SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; +} + +int SSL_renegotiate_pending(SSL *ssl) { + return SSL_in_init(ssl) && ssl->s3->initial_handshake_complete; +} + +int SSL_total_renegotiations(const SSL *ssl) { + return ssl->s3->total_renegotiations; +} + +size_t SSL_CTX_get_max_cert_list(const SSL_CTX *ctx) { + return ctx->max_cert_list; +} + +void SSL_CTX_set_max_cert_list(SSL_CTX *ctx, size_t max_cert_list) { + if (max_cert_list > kMaxHandshakeSize) { + max_cert_list = kMaxHandshakeSize; + } + ctx->max_cert_list = (uint32_t)max_cert_list; +} + +size_t SSL_get_max_cert_list(const SSL *ssl) { + return ssl->max_cert_list; +} + +void SSL_set_max_cert_list(SSL *ssl, size_t max_cert_list) { + if (max_cert_list > kMaxHandshakeSize) { + max_cert_list = kMaxHandshakeSize; + } + ssl->max_cert_list = (uint32_t)max_cert_list; +} + +int SSL_CTX_set_max_send_fragment(SSL_CTX *ctx, size_t max_send_fragment) { + if (max_send_fragment < 512) { + max_send_fragment = 512; + } + if (max_send_fragment > SSL3_RT_MAX_PLAIN_LENGTH) { + max_send_fragment = SSL3_RT_MAX_PLAIN_LENGTH; + } + ctx->max_send_fragment = (uint16_t)max_send_fragment; + + return 1; +} + +int SSL_set_max_send_fragment(SSL *ssl, size_t max_send_fragment) { + if (max_send_fragment < 512) { + max_send_fragment = 512; + } + if (max_send_fragment > SSL3_RT_MAX_PLAIN_LENGTH) { + max_send_fragment = SSL3_RT_MAX_PLAIN_LENGTH; + } + ssl->max_send_fragment = (uint16_t)max_send_fragment; + + return 1; +} + +int SSL_set_mtu(SSL *ssl, unsigned mtu) { + if (!SSL_is_dtls(ssl) || mtu < dtls1_min_mtu()) { + return 0; + } + ssl->d1->mtu = mtu; + return 1; +} + +int SSL_get_secure_renegotiation_support(const SSL *ssl) { + if (!ssl->s3->have_version) { + return 0; + } + return ssl_protocol_version(ssl) >= TLS1_3_VERSION || + ssl->s3->send_connection_binding; +} + +size_t SSL_CTX_sess_number(const SSL_CTX *ctx) { + MutexReadLock lock(const_cast(&ctx->lock)); + return lh_SSL_SESSION_num_items(ctx->sessions); +} + +unsigned long SSL_CTX_sess_set_cache_size(SSL_CTX *ctx, unsigned long size) { + unsigned long ret = ctx->session_cache_size; + ctx->session_cache_size = size; + return ret; +} + +unsigned long SSL_CTX_sess_get_cache_size(const SSL_CTX *ctx) { + return ctx->session_cache_size; +} + +int SSL_CTX_set_session_cache_mode(SSL_CTX *ctx, int mode) { + int ret = ctx->session_cache_mode; + ctx->session_cache_mode = mode; + return ret; +} + +int SSL_CTX_get_session_cache_mode(const SSL_CTX *ctx) { + return ctx->session_cache_mode; +} + + +int SSL_CTX_get_tlsext_ticket_keys(SSL_CTX *ctx, void *out, size_t len) { + if (out == NULL) { + return 48; + } + if (len != 48) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_TICKET_KEYS_LENGTH); + return 0; + } + + // The default ticket keys are initialized lazily. Trigger a key + // rotation to initialize them. + if (!ssl_ctx_rotate_ticket_encryption_key(ctx)) { + return 0; + } + + uint8_t *out_bytes = reinterpret_cast(out); + MutexReadLock lock(&ctx->lock); + OPENSSL_memcpy(out_bytes, ctx->tlsext_ticket_key_current->name, 16); + OPENSSL_memcpy(out_bytes + 16, ctx->tlsext_ticket_key_current->hmac_key, 16); + OPENSSL_memcpy(out_bytes + 32, ctx->tlsext_ticket_key_current->aes_key, 16); + return 1; +} + +int SSL_CTX_set_tlsext_ticket_keys(SSL_CTX *ctx, const void *in, size_t len) { + if (in == NULL) { + return 48; + } + if (len != 48) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_TICKET_KEYS_LENGTH); + return 0; + } + if (!ctx->tlsext_ticket_key_current) { + ctx->tlsext_ticket_key_current = + (tlsext_ticket_key *)OPENSSL_malloc(sizeof(tlsext_ticket_key)); + if (!ctx->tlsext_ticket_key_current) { + return 0; + } + } + OPENSSL_memset(ctx->tlsext_ticket_key_current, 0, sizeof(tlsext_ticket_key)); + const uint8_t *in_bytes = reinterpret_cast(in); + OPENSSL_memcpy(ctx->tlsext_ticket_key_current->name, in_bytes, 16); + OPENSSL_memcpy(ctx->tlsext_ticket_key_current->hmac_key, in_bytes + 16, 16); + OPENSSL_memcpy(ctx->tlsext_ticket_key_current->aes_key, in_bytes + 32, 16); + OPENSSL_free(ctx->tlsext_ticket_key_prev); + ctx->tlsext_ticket_key_prev = nullptr; + // Disable automatic key rotation. + ctx->tlsext_ticket_key_current->next_rotation_tv_sec = 0; + return 1; +} + +int SSL_CTX_set_tlsext_ticket_key_cb( + SSL_CTX *ctx, int (*callback)(SSL *ssl, uint8_t *key_name, uint8_t *iv, + EVP_CIPHER_CTX *ctx, HMAC_CTX *hmac_ctx, + int encrypt)) { + ctx->tlsext_ticket_key_cb = callback; + return 1; +} + +int SSL_CTX_set1_curves(SSL_CTX *ctx, const int *curves, size_t curves_len) { + return tls1_set_curves(&ctx->supported_group_list, + &ctx->supported_group_list_len, curves, + curves_len); +} + +int SSL_set1_curves(SSL *ssl, const int *curves, size_t curves_len) { + return tls1_set_curves(&ssl->supported_group_list, + &ssl->supported_group_list_len, curves, + curves_len); +} + +int SSL_CTX_set1_curves_list(SSL_CTX *ctx, const char *curves) { + return tls1_set_curves_list(&ctx->supported_group_list, + &ctx->supported_group_list_len, curves); +} + +int SSL_set1_curves_list(SSL *ssl, const char *curves) { + return tls1_set_curves_list(&ssl->supported_group_list, + &ssl->supported_group_list_len, curves); +} + +uint16_t SSL_get_curve_id(const SSL *ssl) { + // TODO(davidben): This checks the wrong session if there is a renegotiation + // in progress. + SSL_SESSION *session = SSL_get_session(ssl); + if (session == NULL) { + return 0; + } + + return session->group_id; +} + +int SSL_CTX_set_tmp_dh(SSL_CTX *ctx, const DH *dh) { + return 1; +} + +int SSL_set_tmp_dh(SSL *ssl, const DH *dh) { + return 1; +} + +STACK_OF(SSL_CIPHER) *SSL_CTX_get_ciphers(const SSL_CTX *ctx) { + return ctx->cipher_list->ciphers; +} + +int SSL_CTX_cipher_in_group(const SSL_CTX *ctx, size_t i) { + if (i >= sk_SSL_CIPHER_num(ctx->cipher_list->ciphers)) { + return 0; + } + return ctx->cipher_list->in_group_flags[i]; +} + +STACK_OF(SSL_CIPHER) *SSL_get_ciphers(const SSL *ssl) { + if (ssl == NULL) { + return NULL; + } + + const struct ssl_cipher_preference_list_st *prefs = + ssl_get_cipher_preferences(ssl); + if (prefs == NULL) { + return NULL; + } + + return prefs->ciphers; +} + +const char *SSL_get_cipher_list(const SSL *ssl, int n) { + if (ssl == NULL) { + return NULL; + } + + STACK_OF(SSL_CIPHER) *sk = SSL_get_ciphers(ssl); + if (sk == NULL || n < 0 || (size_t)n >= sk_SSL_CIPHER_num(sk)) { + return NULL; + } + + const SSL_CIPHER *c = sk_SSL_CIPHER_value(sk, n); + if (c == NULL) { + return NULL; + } + + return c->name; +} + +int SSL_CTX_set_cipher_list(SSL_CTX *ctx, const char *str) { + return ssl_create_cipher_list(&ctx->cipher_list, str, false /* not strict */); +} + +int SSL_CTX_set_strict_cipher_list(SSL_CTX *ctx, const char *str) { + return ssl_create_cipher_list(&ctx->cipher_list, str, true /* strict */); +} + +int SSL_set_cipher_list(SSL *ssl, const char *str) { + return ssl_create_cipher_list(&ssl->cipher_list, str, false /* not strict */); +} + +int SSL_set_strict_cipher_list(SSL *ssl, const char *str) { + return ssl_create_cipher_list(&ssl->cipher_list, str, true /* strict */); +} + +const char *SSL_get_servername(const SSL *ssl, const int type) { + if (type != TLSEXT_NAMETYPE_host_name) { + return NULL; + } + + // Historically, |SSL_get_servername| was also the configuration getter + // corresponding to |SSL_set_tlsext_host_name|. + if (ssl->tlsext_hostname != NULL) { + return ssl->tlsext_hostname; + } + + return ssl->s3->hostname.get(); +} + +int SSL_get_servername_type(const SSL *ssl) { + if (SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name) == NULL) { + return -1; + } + return TLSEXT_NAMETYPE_host_name; +} + +void SSL_CTX_set_custom_verify( + SSL_CTX *ctx, int mode, + enum ssl_verify_result_t (*callback)(SSL *ssl, uint8_t *out_alert)) { + ctx->verify_mode = mode; + ctx->custom_verify_callback = callback; +} + +void SSL_set_custom_verify( + SSL *ssl, int mode, + enum ssl_verify_result_t (*callback)(SSL *ssl, uint8_t *out_alert)) { + ssl->verify_mode = mode; + ssl->custom_verify_callback = callback; +} + +void SSL_CTX_enable_signed_cert_timestamps(SSL_CTX *ctx) { + ctx->signed_cert_timestamps_enabled = true; +} + +void SSL_enable_signed_cert_timestamps(SSL *ssl) { + ssl->signed_cert_timestamps_enabled = true; +} + +void SSL_CTX_enable_ocsp_stapling(SSL_CTX *ctx) { + ctx->ocsp_stapling_enabled = true; +} + +void SSL_enable_ocsp_stapling(SSL *ssl) { + ssl->ocsp_stapling_enabled = true; +} + +void SSL_get0_signed_cert_timestamp_list(const SSL *ssl, const uint8_t **out, + size_t *out_len) { + SSL_SESSION *session = SSL_get_session(ssl); + if (ssl->server || !session || !session->signed_cert_timestamp_list) { + *out_len = 0; + *out = NULL; + return; + } + + *out = CRYPTO_BUFFER_data(session->signed_cert_timestamp_list); + *out_len = CRYPTO_BUFFER_len(session->signed_cert_timestamp_list); +} + +void SSL_get0_ocsp_response(const SSL *ssl, const uint8_t **out, + size_t *out_len) { + SSL_SESSION *session = SSL_get_session(ssl); + if (ssl->server || !session || !session->ocsp_response) { + *out_len = 0; + *out = NULL; + return; + } + + *out = CRYPTO_BUFFER_data(session->ocsp_response); + *out_len = CRYPTO_BUFFER_len(session->ocsp_response); +} + +int SSL_set_tlsext_host_name(SSL *ssl, const char *name) { + OPENSSL_free(ssl->tlsext_hostname); + ssl->tlsext_hostname = NULL; + + if (name == NULL) { + return 1; + } + + size_t len = strlen(name); + if (len == 0 || len > TLSEXT_MAXLEN_host_name) { + OPENSSL_PUT_ERROR(SSL, SSL_R_SSL3_EXT_INVALID_SERVERNAME); + return 0; + } + ssl->tlsext_hostname = BUF_strdup(name); + if (ssl->tlsext_hostname == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + return 1; +} + +int SSL_CTX_set_tlsext_servername_callback( + SSL_CTX *ctx, int (*callback)(SSL *ssl, int *out_alert, void *arg)) { + ctx->tlsext_servername_callback = callback; + return 1; +} + +int SSL_CTX_set_tlsext_servername_arg(SSL_CTX *ctx, void *arg) { + ctx->tlsext_servername_arg = arg; + return 1; +} + +int SSL_select_next_proto(uint8_t **out, uint8_t *out_len, const uint8_t *peer, + unsigned peer_len, const uint8_t *supported, + unsigned supported_len) { + const uint8_t *result; + int status; + + // For each protocol in peer preference order, see if we support it. + for (unsigned i = 0; i < peer_len;) { + for (unsigned j = 0; j < supported_len;) { + if (peer[i] == supported[j] && + OPENSSL_memcmp(&peer[i + 1], &supported[j + 1], peer[i]) == 0) { + // We found a match + result = &peer[i]; + status = OPENSSL_NPN_NEGOTIATED; + goto found; + } + j += supported[j]; + j++; + } + i += peer[i]; + i++; + } + + // There's no overlap between our protocols and the peer's list. + result = supported; + status = OPENSSL_NPN_NO_OVERLAP; + +found: + *out = (uint8_t *)result + 1; + *out_len = result[0]; + return status; +} + +void SSL_get0_next_proto_negotiated(const SSL *ssl, const uint8_t **out_data, + unsigned *out_len) { + *out_data = ssl->s3->next_proto_negotiated.data(); + *out_len = ssl->s3->next_proto_negotiated.size(); +} + +void SSL_CTX_set_next_protos_advertised_cb( + SSL_CTX *ctx, + int (*cb)(SSL *ssl, const uint8_t **out, unsigned *out_len, void *arg), + void *arg) { + ctx->next_protos_advertised_cb = cb; + ctx->next_protos_advertised_cb_arg = arg; +} + +void SSL_CTX_set_next_proto_select_cb( + SSL_CTX *ctx, int (*cb)(SSL *ssl, uint8_t **out, uint8_t *out_len, + const uint8_t *in, unsigned in_len, void *arg), + void *arg) { + ctx->next_proto_select_cb = cb; + ctx->next_proto_select_cb_arg = arg; +} + +int SSL_CTX_set_alpn_protos(SSL_CTX *ctx, const uint8_t *protos, + unsigned protos_len) { + OPENSSL_free(ctx->alpn_client_proto_list); + ctx->alpn_client_proto_list = (uint8_t *)BUF_memdup(protos, protos_len); + if (!ctx->alpn_client_proto_list) { + return 1; + } + ctx->alpn_client_proto_list_len = protos_len; + + return 0; +} + +int SSL_set_alpn_protos(SSL *ssl, const uint8_t *protos, unsigned protos_len) { + OPENSSL_free(ssl->alpn_client_proto_list); + ssl->alpn_client_proto_list = (uint8_t *)BUF_memdup(protos, protos_len); + if (!ssl->alpn_client_proto_list) { + return 1; + } + ssl->alpn_client_proto_list_len = protos_len; + + return 0; +} + +void SSL_CTX_set_alpn_select_cb(SSL_CTX *ctx, + int (*cb)(SSL *ssl, const uint8_t **out, + uint8_t *out_len, const uint8_t *in, + unsigned in_len, void *arg), + void *arg) { + ctx->alpn_select_cb = cb; + ctx->alpn_select_cb_arg = arg; +} + +void SSL_get0_alpn_selected(const SSL *ssl, const uint8_t **out_data, + unsigned *out_len) { + if (SSL_in_early_data(ssl) && !ssl->server) { + *out_data = ssl->s3->hs->early_session->early_alpn; + *out_len = ssl->s3->hs->early_session->early_alpn_len; + } else { + *out_data = ssl->s3->alpn_selected.data(); + *out_len = ssl->s3->alpn_selected.size(); + } +} + +void SSL_CTX_set_allow_unknown_alpn_protos(SSL_CTX *ctx, int enabled) { + ctx->allow_unknown_alpn_protos = !!enabled; +} + +void SSL_CTX_set_tls_channel_id_enabled(SSL_CTX *ctx, int enabled) { + ctx->tlsext_channel_id_enabled = !!enabled; +} + +int SSL_CTX_enable_tls_channel_id(SSL_CTX *ctx) { + SSL_CTX_set_tls_channel_id_enabled(ctx, 1); + return 1; +} + +void SSL_set_tls_channel_id_enabled(SSL *ssl, int enabled) { + ssl->tlsext_channel_id_enabled = !!enabled; +} + +int SSL_enable_tls_channel_id(SSL *ssl) { + SSL_set_tls_channel_id_enabled(ssl, 1); + return 1; +} + +static int is_p256_key(EVP_PKEY *private_key) { + const EC_KEY *ec_key = EVP_PKEY_get0_EC_KEY(private_key); + return ec_key != NULL && + EC_GROUP_get_curve_name(EC_KEY_get0_group(ec_key)) == + NID_X9_62_prime256v1; +} + +int SSL_CTX_set1_tls_channel_id(SSL_CTX *ctx, EVP_PKEY *private_key) { + if (!is_p256_key(private_key)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_CHANNEL_ID_NOT_P256); + return 0; + } + + EVP_PKEY_free(ctx->tlsext_channel_id_private); + EVP_PKEY_up_ref(private_key); + ctx->tlsext_channel_id_private = private_key; + ctx->tlsext_channel_id_enabled = true; + + return 1; +} + +int SSL_set1_tls_channel_id(SSL *ssl, EVP_PKEY *private_key) { + if (!is_p256_key(private_key)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_CHANNEL_ID_NOT_P256); + return 0; + } + + EVP_PKEY_free(ssl->tlsext_channel_id_private); + EVP_PKEY_up_ref(private_key); + ssl->tlsext_channel_id_private = private_key; + ssl->tlsext_channel_id_enabled = true; + + return 1; +} + +size_t SSL_get_tls_channel_id(SSL *ssl, uint8_t *out, size_t max_out) { + if (!ssl->s3->tlsext_channel_id_valid) { + return 0; + } + OPENSSL_memcpy(out, ssl->s3->tlsext_channel_id, + (max_out < 64) ? max_out : 64); + return 64; +} + +int SSL_set_token_binding_params(SSL *ssl, const uint8_t *params, size_t len) { + if (len > 256) { + OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW); + return 0; + } + OPENSSL_free(ssl->token_binding_params); + ssl->token_binding_params = (uint8_t *)BUF_memdup(params, len); + if (!ssl->token_binding_params) { + return 0; + } + ssl->token_binding_params_len = len; + return 1; +} + +int SSL_is_token_binding_negotiated(const SSL *ssl) { + return ssl->token_binding_negotiated; +} + +uint8_t SSL_get_negotiated_token_binding_param(const SSL *ssl) { + return ssl->negotiated_token_binding_param; +} + +size_t SSL_get0_certificate_types(SSL *ssl, const uint8_t **out_types) { + if (ssl->server || ssl->s3->hs == NULL) { + *out_types = NULL; + return 0; + } + *out_types = ssl->s3->hs->certificate_types.data(); + return ssl->s3->hs->certificate_types.size(); +} + +EVP_PKEY *SSL_get_privatekey(const SSL *ssl) { + if (ssl->cert != NULL) { + return ssl->cert->privatekey; + } + + return NULL; +} + +EVP_PKEY *SSL_CTX_get0_privatekey(const SSL_CTX *ctx) { + if (ctx->cert != NULL) { + return ctx->cert->privatekey; + } + + return NULL; +} + +const SSL_CIPHER *SSL_get_current_cipher(const SSL *ssl) { + return ssl->s3->aead_write_ctx->cipher(); +} + +int SSL_session_reused(const SSL *ssl) { + return ssl->s3->session_reused || SSL_in_early_data(ssl); +} + +const COMP_METHOD *SSL_get_current_compression(SSL *ssl) { return NULL; } + +const COMP_METHOD *SSL_get_current_expansion(SSL *ssl) { return NULL; } + +int *SSL_get_server_tmp_key(SSL *ssl, EVP_PKEY **out_key) { return 0; } + +void SSL_CTX_set_quiet_shutdown(SSL_CTX *ctx, int mode) { + ctx->quiet_shutdown = (mode != 0); +} + +int SSL_CTX_get_quiet_shutdown(const SSL_CTX *ctx) { + return ctx->quiet_shutdown; +} + +void SSL_set_quiet_shutdown(SSL *ssl, int mode) { + ssl->quiet_shutdown = (mode != 0); +} + +int SSL_get_quiet_shutdown(const SSL *ssl) { return ssl->quiet_shutdown; } + +void SSL_set_shutdown(SSL *ssl, int mode) { + // It is an error to clear any bits that have already been set. (We can't try + // to get a second close_notify or send two.) + assert((SSL_get_shutdown(ssl) & mode) == SSL_get_shutdown(ssl)); + + if (mode & SSL_RECEIVED_SHUTDOWN && + ssl->s3->read_shutdown == ssl_shutdown_none) { + ssl->s3->read_shutdown = ssl_shutdown_close_notify; + } + + if (mode & SSL_SENT_SHUTDOWN && + ssl->s3->write_shutdown == ssl_shutdown_none) { + ssl->s3->write_shutdown = ssl_shutdown_close_notify; + } +} + +int SSL_get_shutdown(const SSL *ssl) { + int ret = 0; + if (ssl->s3->read_shutdown != ssl_shutdown_none) { + // Historically, OpenSSL set |SSL_RECEIVED_SHUTDOWN| on both close_notify + // and fatal alert. + ret |= SSL_RECEIVED_SHUTDOWN; + } + if (ssl->s3->write_shutdown == ssl_shutdown_close_notify) { + // Historically, OpenSSL set |SSL_SENT_SHUTDOWN| on only close_notify. + ret |= SSL_SENT_SHUTDOWN; + } + return ret; +} + +SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl) { return ssl->ctx; } + +SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX *ctx) { + if (ssl->ctx == ctx) { + return ssl->ctx; + } + + // One cannot change the X.509 callbacks during a connection. + if (ssl->ctx->x509_method != ctx->x509_method) { + assert(0); + return NULL; + } + + if (ctx == NULL) { + ctx = ssl->session_ctx; + } + + ssl_cert_free(ssl->cert); + ssl->cert = ssl_cert_dup(ctx->cert); + + SSL_CTX_up_ref(ctx); + SSL_CTX_free(ssl->ctx); + ssl->ctx = ctx; + + return ssl->ctx; +} + +void SSL_set_info_callback(SSL *ssl, + void (*cb)(const SSL *ssl, int type, int value)) { + ssl->info_callback = cb; +} + +void (*SSL_get_info_callback(const SSL *ssl))(const SSL *ssl, int type, + int value) { + return ssl->info_callback; +} + +int SSL_state(const SSL *ssl) { + return SSL_in_init(ssl) ? SSL_ST_INIT : SSL_ST_OK; +} + +void SSL_set_state(SSL *ssl, int state) { } + +char *SSL_get_shared_ciphers(const SSL *ssl, char *buf, int len) { + if (len <= 0) { + return NULL; + } + buf[0] = '\0'; + return buf; +} + +int SSL_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused *unused, + CRYPTO_EX_dup *dup_unused, CRYPTO_EX_free *free_func) { + int index; + if (!CRYPTO_get_ex_new_index(&g_ex_data_class_ssl, &index, argl, argp, + free_func)) { + return -1; + } + return index; +} + +int SSL_set_ex_data(SSL *ssl, int idx, void *data) { + return CRYPTO_set_ex_data(&ssl->ex_data, idx, data); +} + +void *SSL_get_ex_data(const SSL *ssl, int idx) { + return CRYPTO_get_ex_data(&ssl->ex_data, idx); +} + +int SSL_CTX_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused *unused, + CRYPTO_EX_dup *dup_unused, + CRYPTO_EX_free *free_func) { + int index; + if (!CRYPTO_get_ex_new_index(&g_ex_data_class_ssl_ctx, &index, argl, argp, + free_func)) { + return -1; + } + return index; +} + +int SSL_CTX_set_ex_data(SSL_CTX *ctx, int idx, void *data) { + return CRYPTO_set_ex_data(&ctx->ex_data, idx, data); +} + +void *SSL_CTX_get_ex_data(const SSL_CTX *ctx, int idx) { + return CRYPTO_get_ex_data(&ctx->ex_data, idx); +} + +int SSL_want(const SSL *ssl) { return ssl->s3->rwstate; } + +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)) {} + +void SSL_CTX_set_tmp_dh_callback(SSL_CTX *ctx, + DH *(*cb)(SSL *ssl, int is_export, + int keylength)) {} + +void SSL_set_tmp_dh_callback(SSL *ssl, DH *(*cb)(SSL *ssl, int is_export, + int keylength)) {} + +static int use_psk_identity_hint(char **out, const char *identity_hint) { + if (identity_hint != NULL && strlen(identity_hint) > PSK_MAX_IDENTITY_LEN) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DATA_LENGTH_TOO_LONG); + return 0; + } + + // Clear currently configured hint, if any. + OPENSSL_free(*out); + *out = NULL; + + // Treat the empty hint as not supplying one. Plain PSK makes it possible to + // send either no hint (omit ServerKeyExchange) or an empty hint, while + // ECDHE_PSK can only spell empty hint. Having different capabilities is odd, + // so we interpret empty and missing as identical. + if (identity_hint != NULL && identity_hint[0] != '\0') { + *out = BUF_strdup(identity_hint); + if (*out == NULL) { + return 0; + } + } + + return 1; +} + +int SSL_CTX_use_psk_identity_hint(SSL_CTX *ctx, const char *identity_hint) { + return use_psk_identity_hint(&ctx->psk_identity_hint, identity_hint); +} + +int SSL_use_psk_identity_hint(SSL *ssl, const char *identity_hint) { + return use_psk_identity_hint(&ssl->psk_identity_hint, identity_hint); +} + +const char *SSL_get_psk_identity_hint(const SSL *ssl) { + if (ssl == NULL) { + return NULL; + } + return ssl->psk_identity_hint; +} + +const char *SSL_get_psk_identity(const SSL *ssl) { + if (ssl == NULL) { + return NULL; + } + SSL_SESSION *session = SSL_get_session(ssl); + if (session == NULL) { + return NULL; + } + return session->psk_identity; +} + +void SSL_set_psk_client_callback( + SSL *ssl, unsigned (*cb)(SSL *ssl, const char *hint, char *identity, + unsigned max_identity_len, uint8_t *psk, + unsigned max_psk_len)) { + ssl->psk_client_callback = cb; +} + +void SSL_CTX_set_psk_client_callback( + SSL_CTX *ctx, unsigned (*cb)(SSL *ssl, const char *hint, char *identity, + unsigned max_identity_len, uint8_t *psk, + unsigned max_psk_len)) { + ctx->psk_client_callback = cb; +} + +void SSL_set_psk_server_callback( + SSL *ssl, unsigned (*cb)(SSL *ssl, const char *identity, uint8_t *psk, + unsigned max_psk_len)) { + ssl->psk_server_callback = cb; +} + +void SSL_CTX_set_psk_server_callback( + SSL_CTX *ctx, unsigned (*cb)(SSL *ssl, const char *identity, + uint8_t *psk, unsigned max_psk_len)) { + ctx->psk_server_callback = cb; +} + +int SSL_set_dummy_pq_padding_size(SSL *ssl, size_t num_bytes) { + if (num_bytes > 0xffff) { + return 0; + } + + ssl->dummy_pq_padding_len = num_bytes; + return 1; +} + +int SSL_dummy_pq_padding_used(SSL *ssl) { + if (ssl->server) { + return 0; + } + + return ssl->did_dummy_pq_padding; +} + +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)) { + ctx->msg_callback = cb; +} + +void SSL_CTX_set_msg_callback_arg(SSL_CTX *ctx, void *arg) { + ctx->msg_callback_arg = 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)) { + ssl->msg_callback = cb; +} + +void SSL_set_msg_callback_arg(SSL *ssl, void *arg) { + ssl->msg_callback_arg = arg; +} + +void SSL_CTX_set_keylog_callback(SSL_CTX *ctx, + void (*cb)(const SSL *ssl, const char *line)) { + ctx->keylog_callback = cb; +} + +void (*SSL_CTX_get_keylog_callback(const SSL_CTX *ctx))(const SSL *ssl, + const char *line) { + return ctx->keylog_callback; +} + +void SSL_CTX_set_current_time_cb(SSL_CTX *ctx, + void (*cb)(const SSL *ssl, + struct timeval *out_clock)) { + ctx->current_time_cb = cb; +} + +int SSL_is_init_finished(const SSL *ssl) { + return !SSL_in_init(ssl); +} + +int SSL_in_init(const SSL *ssl) { + // This returns false once all the handshake state has been finalized, to + // allow callbacks and getters based on SSL_in_init to return the correct + // values. + SSL_HANDSHAKE *hs = ssl->s3->hs.get(); + return hs != nullptr && !hs->handshake_finalized; +} + +int SSL_in_false_start(const SSL *ssl) { + if (ssl->s3->hs == NULL) { + return 0; + } + return ssl->s3->hs->in_false_start; +} + +int SSL_cutthrough_complete(const SSL *ssl) { + return SSL_in_false_start(ssl); +} + +void SSL_get_structure_sizes(size_t *ssl_size, size_t *ssl_ctx_size, + size_t *ssl_session_size) { + *ssl_size = sizeof(SSL); + *ssl_ctx_size = sizeof(SSL_CTX); + *ssl_session_size = sizeof(SSL_SESSION); +} + +int SSL_is_server(const SSL *ssl) { return ssl->server; } + +int SSL_is_dtls(const SSL *ssl) { return ssl->method->is_dtls; } + +void SSL_CTX_set_select_certificate_cb( + SSL_CTX *ctx, + enum ssl_select_cert_result_t (*cb)(const SSL_CLIENT_HELLO *)) { + ctx->select_certificate_cb = cb; +} + +void SSL_CTX_set_dos_protection_cb(SSL_CTX *ctx, + int (*cb)(const SSL_CLIENT_HELLO *)) { + ctx->dos_protection_cb = cb; +} + +void SSL_set_renegotiate_mode(SSL *ssl, enum ssl_renegotiate_mode_t mode) { + ssl->renegotiate_mode = mode; +} + +int SSL_get_ivs(const SSL *ssl, const uint8_t **out_read_iv, + const uint8_t **out_write_iv, size_t *out_iv_len) { + size_t write_iv_len; + if (!ssl->s3->aead_read_ctx->GetIV(out_read_iv, out_iv_len) || + !ssl->s3->aead_write_ctx->GetIV(out_write_iv, &write_iv_len) || + *out_iv_len != write_iv_len) { + return 0; + } + + return 1; +} + +static uint64_t be_to_u64(const uint8_t in[8]) { + return (((uint64_t)in[0]) << 56) | (((uint64_t)in[1]) << 48) | + (((uint64_t)in[2]) << 40) | (((uint64_t)in[3]) << 32) | + (((uint64_t)in[4]) << 24) | (((uint64_t)in[5]) << 16) | + (((uint64_t)in[6]) << 8) | ((uint64_t)in[7]); +} + +uint64_t SSL_get_read_sequence(const SSL *ssl) { + // TODO(davidben): Internally represent sequence numbers as uint64_t. + if (SSL_is_dtls(ssl)) { + // max_seq_num already includes the epoch. + assert(ssl->d1->r_epoch == (ssl->d1->bitmap.max_seq_num >> 48)); + return ssl->d1->bitmap.max_seq_num; + } + return be_to_u64(ssl->s3->read_sequence); +} + +uint64_t SSL_get_write_sequence(const SSL *ssl) { + uint64_t ret = be_to_u64(ssl->s3->write_sequence); + if (SSL_is_dtls(ssl)) { + assert((ret >> 48) == 0); + ret |= ((uint64_t)ssl->d1->w_epoch) << 48; + } + return ret; +} + +uint16_t SSL_get_peer_signature_algorithm(const SSL *ssl) { + // TODO(davidben): This checks the wrong session if there is a renegotiation + // in progress. + SSL_SESSION *session = SSL_get_session(ssl); + if (session == NULL) { + return 0; + } + + return session->peer_signature_algorithm; +} + +size_t SSL_get_client_random(const SSL *ssl, uint8_t *out, size_t max_out) { + if (max_out == 0) { + return sizeof(ssl->s3->client_random); + } + if (max_out > sizeof(ssl->s3->client_random)) { + max_out = sizeof(ssl->s3->client_random); + } + OPENSSL_memcpy(out, ssl->s3->client_random, max_out); + return max_out; +} + +size_t SSL_get_server_random(const SSL *ssl, uint8_t *out, size_t max_out) { + if (max_out == 0) { + return sizeof(ssl->s3->server_random); + } + if (max_out > sizeof(ssl->s3->server_random)) { + max_out = sizeof(ssl->s3->server_random); + } + OPENSSL_memcpy(out, ssl->s3->server_random, max_out); + return max_out; +} + +const SSL_CIPHER *SSL_get_pending_cipher(const SSL *ssl) { + SSL_HANDSHAKE *hs = ssl->s3->hs.get(); + if (hs == NULL) { + return NULL; + } + return hs->new_cipher; +} + +void SSL_set_retain_only_sha256_of_client_certs(SSL *ssl, int enabled) { + ssl->retain_only_sha256_of_client_certs = !!enabled; +} + +void SSL_CTX_set_retain_only_sha256_of_client_certs(SSL_CTX *ctx, int enabled) { + ctx->retain_only_sha256_of_client_certs = !!enabled; +} + +void SSL_CTX_set_grease_enabled(SSL_CTX *ctx, int enabled) { + ctx->grease_enabled = !!enabled; +} + +int32_t SSL_get_ticket_age_skew(const SSL *ssl) { + return ssl->s3->ticket_age_skew; +} + +void SSL_CTX_set_false_start_allowed_without_alpn(SSL_CTX *ctx, int allowed) { + ctx->false_start_allowed_without_alpn = !!allowed; +} + +int SSL_is_draft_downgrade(const SSL *ssl) { return ssl->s3->draft_downgrade; } + +int SSL_clear(SSL *ssl) { + // In OpenSSL, reusing a client |SSL| with |SSL_clear| causes the previously + // established session to be offered the next time around. wpa_supplicant + // depends on this behavior, so emulate it. + UniquePtr session; + if (!ssl->server && ssl->s3->established_session != NULL) { + session.reset(ssl->s3->established_session.get()); + SSL_SESSION_up_ref(session.get()); + } + + // The ssl->d1->mtu is simultaneously configuration (preserved across + // clear) and connection-specific state (gets reset). + // + // TODO(davidben): Avoid this. + unsigned mtu = 0; + if (ssl->d1 != NULL) { + mtu = ssl->d1->mtu; + } + + ssl->method->ssl_free(ssl); + if (!ssl->method->ssl_new(ssl)) { + return 0; + } + + if (SSL_is_dtls(ssl) && (SSL_get_options(ssl) & SSL_OP_NO_QUERY_MTU)) { + ssl->d1->mtu = mtu; + } + + if (session != nullptr) { + SSL_set_session(ssl, session.get()); + } + + return 1; +} + +int SSL_CTX_sess_connect(const SSL_CTX *ctx) { return 0; } +int SSL_CTX_sess_connect_good(const SSL_CTX *ctx) { return 0; } +int SSL_CTX_sess_connect_renegotiate(const SSL_CTX *ctx) { return 0; } +int SSL_CTX_sess_accept(const SSL_CTX *ctx) { return 0; } +int SSL_CTX_sess_accept_renegotiate(const SSL_CTX *ctx) { return 0; } +int SSL_CTX_sess_accept_good(const SSL_CTX *ctx) { return 0; } +int SSL_CTX_sess_hits(const SSL_CTX *ctx) { return 0; } +int SSL_CTX_sess_cb_hits(const SSL_CTX *ctx) { return 0; } +int SSL_CTX_sess_misses(const SSL_CTX *ctx) { return 0; } +int SSL_CTX_sess_timeouts(const SSL_CTX *ctx) { return 0; } +int SSL_CTX_sess_cache_full(const SSL_CTX *ctx) { return 0; } + +int SSL_num_renegotiations(const SSL *ssl) { + return SSL_total_renegotiations(ssl); +} + +int SSL_CTX_need_tmp_RSA(const SSL_CTX *ctx) { return 0; } +int SSL_need_tmp_RSA(const SSL *ssl) { return 0; } +int SSL_CTX_set_tmp_rsa(SSL_CTX *ctx, const RSA *rsa) { return 1; } +int SSL_set_tmp_rsa(SSL *ssl, const RSA *rsa) { return 1; } +void ERR_load_SSL_strings(void) {} +void SSL_load_error_strings(void) {} +int SSL_cache_hit(SSL *ssl) { return SSL_session_reused(ssl); } + +int SSL_CTX_set_tmp_ecdh(SSL_CTX *ctx, const EC_KEY *ec_key) { + if (ec_key == NULL || EC_KEY_get0_group(ec_key) == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + int nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec_key)); + return SSL_CTX_set1_curves(ctx, &nid, 1); +} + +int SSL_set_tmp_ecdh(SSL *ssl, const EC_KEY *ec_key) { + if (ec_key == NULL || EC_KEY_get0_group(ec_key) == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + int nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec_key)); + return SSL_set1_curves(ssl, &nid, 1); +} + +void SSL_CTX_set_ticket_aead_method(SSL_CTX *ctx, + const SSL_TICKET_AEAD_METHOD *aead_method) { + ctx->ticket_aead_method = aead_method; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/ssl/ssl_lib.cc.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/ssl/ssl_lib.cc.grpc_back new file mode 100644 index 0000000..ef79831 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/ssl/ssl_lib.cc.grpc_back @@ -0,0 +1,2719 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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. + */ +/* ==================================================================== + * 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 +#include + +#include +#include +#include +#include +#include +#include + +#include "internal.h" +#include "../crypto/internal.h" + +#if defined(OPENSSL_WINDOWS) +#include +#else +#include +#include +#endif + + +namespace bssl { + +// |SSL_R_UNKNOWN_PROTOCOL| is no longer emitted, but continue to define it +// to avoid downstream churn. +OPENSSL_DECLARE_ERROR_REASON(SSL, UNKNOWN_PROTOCOL) + +// The following errors are no longer emitted, but are used in nginx without +// #ifdefs. +OPENSSL_DECLARE_ERROR_REASON(SSL, BLOCK_CIPHER_PAD_IS_WRONG) +OPENSSL_DECLARE_ERROR_REASON(SSL, NO_CIPHERS_SPECIFIED) + +// Some error codes are special. Ensure the make_errors.go script never +// regresses this. +static_assert(SSL_R_TLSV1_ALERT_NO_RENEGOTIATION == + SSL_AD_NO_RENEGOTIATION + SSL_AD_REASON_OFFSET, + "alert reason code mismatch"); + +// kMaxHandshakeSize is the maximum size, in bytes, of a handshake message. +static const size_t kMaxHandshakeSize = (1u << 24) - 1; + +static CRYPTO_EX_DATA_CLASS g_ex_data_class_ssl = + CRYPTO_EX_DATA_CLASS_INIT_WITH_APP_DATA; +static CRYPTO_EX_DATA_CLASS g_ex_data_class_ssl_ctx = + CRYPTO_EX_DATA_CLASS_INIT_WITH_APP_DATA; + +bool CBBFinishArray(CBB *cbb, Array *out) { + uint8_t *ptr; + size_t len; + if (!CBB_finish(cbb, &ptr, &len)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return false; + } + out->Reset(ptr, len); + return true; +} + +void ssl_reset_error_state(SSL *ssl) { + // Functions which use |SSL_get_error| must reset I/O and error state on + // entry. + ssl->s3->rwstate = SSL_NOTHING; + ERR_clear_error(); + ERR_clear_system_error(); +} + +void ssl_set_read_error(SSL* ssl) { + ssl->s3->read_shutdown = ssl_shutdown_error; + ssl->s3->read_error.reset(ERR_save_state()); +} + +static bool check_read_error(const SSL *ssl) { + if (ssl->s3->read_shutdown == ssl_shutdown_error) { + ERR_restore_state(ssl->s3->read_error.get()); + return false; + } + return true; +} + +int ssl_can_write(const SSL *ssl) { + return !SSL_in_init(ssl) || ssl->s3->hs->can_early_write; +} + +int ssl_can_read(const SSL *ssl) { + return !SSL_in_init(ssl) || ssl->s3->hs->can_early_read; +} + +ssl_open_record_t ssl_open_handshake(SSL *ssl, size_t *out_consumed, + uint8_t *out_alert, Span in) { + *out_consumed = 0; + if (!check_read_error(ssl)) { + *out_alert = 0; + return ssl_open_record_error; + } + auto ret = ssl->method->open_handshake(ssl, out_consumed, out_alert, in); + if (ret == ssl_open_record_error) { + ssl_set_read_error(ssl); + } + return ret; +} + +ssl_open_record_t ssl_open_change_cipher_spec(SSL *ssl, size_t *out_consumed, + uint8_t *out_alert, + Span in) { + *out_consumed = 0; + if (!check_read_error(ssl)) { + *out_alert = 0; + return ssl_open_record_error; + } + auto ret = + ssl->method->open_change_cipher_spec(ssl, out_consumed, out_alert, in); + if (ret == ssl_open_record_error) { + ssl_set_read_error(ssl); + } + return ret; +} + +ssl_open_record_t ssl_open_app_data(SSL *ssl, Span *out, + size_t *out_consumed, uint8_t *out_alert, + Span in) { + *out_consumed = 0; + if (!check_read_error(ssl)) { + *out_alert = 0; + return ssl_open_record_error; + } + auto ret = ssl->method->open_app_data(ssl, out, out_consumed, out_alert, in); + if (ret == ssl_open_record_error) { + ssl_set_read_error(ssl); + } + return ret; +} + +void ssl_cipher_preference_list_free( + struct ssl_cipher_preference_list_st *cipher_list) { + if (cipher_list == NULL) { + return; + } + sk_SSL_CIPHER_free(cipher_list->ciphers); + OPENSSL_free(cipher_list->in_group_flags); + OPENSSL_free(cipher_list); +} + +void ssl_update_cache(SSL_HANDSHAKE *hs, int mode) { + SSL *const ssl = hs->ssl; + SSL_CTX *ctx = ssl->session_ctx; + // Never cache sessions with empty session IDs. + if (ssl->s3->established_session->session_id_length == 0 || + ssl->s3->established_session->not_resumable || + (ctx->session_cache_mode & mode) != mode) { + return; + } + + // Clients never use the internal session cache. + int use_internal_cache = ssl->server && !(ctx->session_cache_mode & + SSL_SESS_CACHE_NO_INTERNAL_STORE); + + // A client may see new sessions on abbreviated handshakes if the server + // decides to renew the ticket. Once the handshake is completed, it should be + // inserted into the cache. + if (ssl->s3->established_session.get() != ssl->session || + (!ssl->server && hs->ticket_expected)) { + if (use_internal_cache) { + SSL_CTX_add_session(ctx, ssl->s3->established_session.get()); + } + if (ctx->new_session_cb != NULL) { + SSL_SESSION_up_ref(ssl->s3->established_session.get()); + if (!ctx->new_session_cb(ssl, ssl->s3->established_session.get())) { + // |new_session_cb|'s return value signals whether it took ownership. + SSL_SESSION_free(ssl->s3->established_session.get()); + } + } + } + + if (use_internal_cache && + !(ctx->session_cache_mode & SSL_SESS_CACHE_NO_AUTO_CLEAR)) { + // Automatically flush the internal session cache every 255 connections. + int flush_cache = 0; + CRYPTO_MUTEX_lock_write(&ctx->lock); + ctx->handshakes_since_cache_flush++; + if (ctx->handshakes_since_cache_flush >= 255) { + flush_cache = 1; + ctx->handshakes_since_cache_flush = 0; + } + CRYPTO_MUTEX_unlock_write(&ctx->lock); + + if (flush_cache) { + struct OPENSSL_timeval now; + ssl_get_current_time(ssl, &now); + SSL_CTX_flush_sessions(ctx, now.tv_sec); + } + } +} + +static int cbb_add_hex(CBB *cbb, const uint8_t *in, size_t in_len) { + static const char hextable[] = "0123456789abcdef"; + uint8_t *out; + + if (!CBB_add_space(cbb, &out, in_len * 2)) { + return 0; + } + + for (size_t i = 0; i < in_len; i++) { + *(out++) = (uint8_t)hextable[in[i] >> 4]; + *(out++) = (uint8_t)hextable[in[i] & 0xf]; + } + + return 1; +} + +int ssl_log_secret(const SSL *ssl, const char *label, const uint8_t *secret, + size_t secret_len) { + if (ssl->ctx->keylog_callback == NULL) { + return 1; + } + + ScopedCBB cbb; + uint8_t *out; + size_t out_len; + if (!CBB_init(cbb.get(), strlen(label) + 1 + SSL3_RANDOM_SIZE * 2 + 1 + + secret_len * 2 + 1) || + !CBB_add_bytes(cbb.get(), (const uint8_t *)label, strlen(label)) || + !CBB_add_bytes(cbb.get(), (const uint8_t *)" ", 1) || + !cbb_add_hex(cbb.get(), ssl->s3->client_random, SSL3_RANDOM_SIZE) || + !CBB_add_bytes(cbb.get(), (const uint8_t *)" ", 1) || + !cbb_add_hex(cbb.get(), secret, secret_len) || + !CBB_add_u8(cbb.get(), 0 /* NUL */) || + !CBB_finish(cbb.get(), &out, &out_len)) { + return 0; + } + + ssl->ctx->keylog_callback(ssl, (const char *)out); + OPENSSL_free(out); + return 1; +} + +void ssl_do_info_callback(const SSL *ssl, int type, int value) { + void (*cb)(const SSL *ssl, int type, int value) = NULL; + if (ssl->info_callback != NULL) { + cb = ssl->info_callback; + } else if (ssl->ctx->info_callback != NULL) { + cb = ssl->ctx->info_callback; + } + + if (cb != NULL) { + cb(ssl, type, value); + } +} + +void ssl_do_msg_callback(SSL *ssl, int is_write, int content_type, + Span in) { + if (ssl->msg_callback == NULL) { + return; + } + + // |version| is zero when calling for |SSL3_RT_HEADER| and |SSL2_VERSION| for + // a V2ClientHello. + int version; + switch (content_type) { + case 0: + // V2ClientHello + version = SSL2_VERSION; + break; + case SSL3_RT_HEADER: + version = 0; + break; + default: + version = SSL_version(ssl); + } + + ssl->msg_callback(is_write, version, content_type, in.data(), in.size(), ssl, + ssl->msg_callback_arg); +} + +void ssl_get_current_time(const SSL *ssl, struct OPENSSL_timeval *out_clock) { + // TODO(martinkr): Change callers to |ssl_ctx_get_current_time| and drop the + // |ssl| arg from |current_time_cb| if possible. + ssl_ctx_get_current_time(ssl->ctx, out_clock); +} + +void ssl_ctx_get_current_time(const SSL_CTX *ctx, + struct OPENSSL_timeval *out_clock) { + if (ctx->current_time_cb != NULL) { + // TODO(davidben): Update current_time_cb to use OPENSSL_timeval. See + // https://crbug.com/boringssl/155. + struct timeval clock; + ctx->current_time_cb(nullptr /* ssl */, &clock); + if (clock.tv_sec < 0) { + assert(0); + out_clock->tv_sec = 0; + out_clock->tv_usec = 0; + } else { + out_clock->tv_sec = (uint64_t)clock.tv_sec; + out_clock->tv_usec = (uint32_t)clock.tv_usec; + } + return; + } + +#if defined(BORINGSSL_UNSAFE_DETERMINISTIC_MODE) + out_clock->tv_sec = 1234; + out_clock->tv_usec = 1234; +#elif defined(OPENSSL_WINDOWS) + struct _timeb time; + _ftime(&time); + if (time.time < 0) { + assert(0); + out_clock->tv_sec = 0; + out_clock->tv_usec = 0; + } else { + out_clock->tv_sec = time.time; + out_clock->tv_usec = time.millitm * 1000; + } +#else + struct timeval clock; + gettimeofday(&clock, NULL); + if (clock.tv_sec < 0) { + assert(0); + out_clock->tv_sec = 0; + out_clock->tv_usec = 0; + } else { + out_clock->tv_sec = (uint64_t)clock.tv_sec; + out_clock->tv_usec = (uint32_t)clock.tv_usec; + } +#endif +} + +void SSL_CTX_set_handoff_mode(SSL_CTX *ctx, bool on) { + ctx->handoff = on; +} + +} // namespace bssl + +using namespace bssl; + +int SSL_library_init(void) { + CRYPTO_library_init(); + return 1; +} + +int OPENSSL_init_ssl(uint64_t opts, const OPENSSL_INIT_SETTINGS *settings) { + CRYPTO_library_init(); + return 1; +} + +static uint32_t ssl_session_hash(const SSL_SESSION *sess) { + const uint8_t *session_id = sess->session_id; + + uint8_t tmp_storage[sizeof(uint32_t)]; + if (sess->session_id_length < sizeof(tmp_storage)) { + OPENSSL_memset(tmp_storage, 0, sizeof(tmp_storage)); + OPENSSL_memcpy(tmp_storage, sess->session_id, sess->session_id_length); + session_id = tmp_storage; + } + + uint32_t hash = + ((uint32_t)session_id[0]) | + ((uint32_t)session_id[1] << 8) | + ((uint32_t)session_id[2] << 16) | + ((uint32_t)session_id[3] << 24); + + return hash; +} + +// 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 OPENSSL_memcmp(a->session_id, b->session_id, a->session_id_length); +} + +SSL_CTX *SSL_CTX_new(const SSL_METHOD *method) { + SSL_CTX *ret = NULL; + + if (method == NULL) { + OPENSSL_PUT_ERROR(SSL, SSL_R_NULL_SSL_METHOD_PASSED); + return NULL; + } + + ret = (SSL_CTX *)OPENSSL_malloc(sizeof(SSL_CTX)); + if (ret == NULL) { + goto err; + } + + OPENSSL_memset(ret, 0, sizeof(SSL_CTX)); + + ret->method = method->method; + ret->x509_method = method->x509_method; + + CRYPTO_MUTEX_init(&ret->lock); + + ret->session_cache_mode = SSL_SESS_CACHE_SERVER; + ret->session_cache_size = SSL_SESSION_CACHE_MAX_SIZE_DEFAULT; + + ret->session_timeout = SSL_DEFAULT_SESSION_TIMEOUT; + ret->session_psk_dhe_timeout = SSL_DEFAULT_SESSION_PSK_DHE_TIMEOUT; + + ret->references = 1; + + ret->max_cert_list = SSL_MAX_CERT_LIST_DEFAULT; + ret->verify_mode = SSL_VERIFY_NONE; + ret->cert = ssl_cert_new(method->x509_method); + if (ret->cert == NULL) { + goto err; + } + + ret->sessions = lh_SSL_SESSION_new(ssl_session_hash, ssl_session_cmp); + if (ret->sessions == NULL) { + goto err; + } + + if (!ret->x509_method->ssl_ctx_new(ret)) { + goto err; + } + + if (!SSL_CTX_set_strict_cipher_list(ret, SSL_DEFAULT_CIPHER_LIST)) { + goto err2; + } + + ret->client_CA = sk_CRYPTO_BUFFER_new_null(); + if (ret->client_CA == NULL) { + goto err; + } + + CRYPTO_new_ex_data(&ret->ex_data); + + ret->max_send_fragment = SSL3_RT_MAX_PLAIN_LENGTH; + + // Disable the auto-chaining feature by default. Once this has stuck without + // problems, the feature will be removed entirely. + ret->mode = SSL_MODE_NO_AUTO_CHAIN; + + // Lock the SSL_CTX to the specified version, for compatibility with legacy + // uses of SSL_METHOD. + if (!SSL_CTX_set_max_proto_version(ret, method->version) || + !SSL_CTX_set_min_proto_version(ret, method->version)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + goto err2; + } + + return ret; + +err: + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); +err2: + SSL_CTX_free(ret); + return NULL; +} + +int SSL_CTX_up_ref(SSL_CTX *ctx) { + CRYPTO_refcount_inc(&ctx->references); + return 1; +} + +void SSL_CTX_free(SSL_CTX *ctx) { + if (ctx == NULL || + !CRYPTO_refcount_dec_and_test_zero(&ctx->references)) { + return; + } + + // 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].) + SSL_CTX_flush_sessions(ctx, 0); + + CRYPTO_free_ex_data(&g_ex_data_class_ssl_ctx, ctx, &ctx->ex_data); + + CRYPTO_MUTEX_cleanup(&ctx->lock); + lh_SSL_SESSION_free(ctx->sessions); + ssl_cipher_preference_list_free(ctx->cipher_list); + ssl_cert_free(ctx->cert); + sk_SSL_CUSTOM_EXTENSION_pop_free(ctx->client_custom_extensions, + SSL_CUSTOM_EXTENSION_free); + sk_SSL_CUSTOM_EXTENSION_pop_free(ctx->server_custom_extensions, + SSL_CUSTOM_EXTENSION_free); + sk_CRYPTO_BUFFER_pop_free(ctx->client_CA, CRYPTO_BUFFER_free); + ctx->x509_method->ssl_ctx_free(ctx); + sk_SRTP_PROTECTION_PROFILE_free(ctx->srtp_profiles); + OPENSSL_free(ctx->psk_identity_hint); + OPENSSL_free(ctx->supported_group_list); + OPENSSL_free(ctx->alpn_client_proto_list); + EVP_PKEY_free(ctx->tlsext_channel_id_private); + OPENSSL_free(ctx->verify_sigalgs); + OPENSSL_free(ctx->tlsext_ticket_key_current); + OPENSSL_free(ctx->tlsext_ticket_key_prev); + + OPENSSL_free(ctx); +} + +SSL *SSL_new(SSL_CTX *ctx) { + if (ctx == NULL) { + OPENSSL_PUT_ERROR(SSL, SSL_R_NULL_SSL_CTX); + return NULL; + } + if (ctx->method == NULL) { + OPENSSL_PUT_ERROR(SSL, SSL_R_SSL_CTX_HAS_NO_DEFAULT_SSL_VERSION); + return NULL; + } + + SSL *ssl = (SSL *)OPENSSL_malloc(sizeof(SSL)); + if (ssl == NULL) { + goto err; + } + OPENSSL_memset(ssl, 0, sizeof(SSL)); + + ssl->conf_min_version = ctx->conf_min_version; + ssl->conf_max_version = ctx->conf_max_version; + ssl->tls13_variant = ctx->tls13_variant; + + // RFC 6347 states that implementations SHOULD use an initial timer value of + // 1 second. + ssl->initial_timeout_duration_ms = 1000; + + ssl->options = ctx->options; + ssl->mode = ctx->mode; + ssl->max_cert_list = ctx->max_cert_list; + + ssl->cert = ssl_cert_dup(ctx->cert); + if (ssl->cert == NULL) { + goto err; + } + + ssl->msg_callback = ctx->msg_callback; + ssl->msg_callback_arg = ctx->msg_callback_arg; + ssl->verify_mode = ctx->verify_mode; + ssl->verify_callback = ctx->default_verify_callback; + ssl->custom_verify_callback = ctx->custom_verify_callback; + ssl->retain_only_sha256_of_client_certs = + ctx->retain_only_sha256_of_client_certs; + + ssl->quiet_shutdown = ctx->quiet_shutdown; + ssl->max_send_fragment = ctx->max_send_fragment; + + SSL_CTX_up_ref(ctx); + ssl->ctx = ctx; + SSL_CTX_up_ref(ctx); + ssl->session_ctx = ctx; + + if (!ssl->ctx->x509_method->ssl_new(ssl)) { + goto err; + } + + if (ctx->supported_group_list) { + ssl->supported_group_list = (uint16_t *)BUF_memdup( + ctx->supported_group_list, ctx->supported_group_list_len * 2); + if (!ssl->supported_group_list) { + goto err; + } + ssl->supported_group_list_len = ctx->supported_group_list_len; + } + + if (ctx->alpn_client_proto_list) { + ssl->alpn_client_proto_list = (uint8_t *)BUF_memdup( + ctx->alpn_client_proto_list, ctx->alpn_client_proto_list_len); + if (ssl->alpn_client_proto_list == NULL) { + goto err; + } + ssl->alpn_client_proto_list_len = ctx->alpn_client_proto_list_len; + } + + ssl->method = ctx->method; + + if (!ssl->method->ssl_new(ssl)) { + goto err; + } + + CRYPTO_new_ex_data(&ssl->ex_data); + + ssl->psk_identity_hint = NULL; + if (ctx->psk_identity_hint) { + ssl->psk_identity_hint = BUF_strdup(ctx->psk_identity_hint); + if (ssl->psk_identity_hint == NULL) { + goto err; + } + } + ssl->psk_client_callback = ctx->psk_client_callback; + ssl->psk_server_callback = ctx->psk_server_callback; + + ssl->tlsext_channel_id_enabled = ctx->tlsext_channel_id_enabled; + if (ctx->tlsext_channel_id_private) { + EVP_PKEY_up_ref(ctx->tlsext_channel_id_private); + ssl->tlsext_channel_id_private = ctx->tlsext_channel_id_private; + } + + ssl->signed_cert_timestamps_enabled = ctx->signed_cert_timestamps_enabled; + ssl->ocsp_stapling_enabled = ctx->ocsp_stapling_enabled; + ssl->handoff = ctx->handoff; + + return ssl; + +err: + SSL_free(ssl); + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + + return NULL; +} + +void SSL_free(SSL *ssl) { + if (ssl == NULL) { + return; + } + + if (ssl->ctx != NULL) { + ssl->ctx->x509_method->ssl_free(ssl); + } + + CRYPTO_free_ex_data(&g_ex_data_class_ssl, ssl, &ssl->ex_data); + + BIO_free_all(ssl->rbio); + BIO_free_all(ssl->wbio); + + // add extra stuff + ssl_cipher_preference_list_free(ssl->cipher_list); + + SSL_SESSION_free(ssl->session); + + ssl_cert_free(ssl->cert); + + OPENSSL_free(ssl->tlsext_hostname); + SSL_CTX_free(ssl->session_ctx); + OPENSSL_free(ssl->supported_group_list); + OPENSSL_free(ssl->alpn_client_proto_list); + OPENSSL_free(ssl->token_binding_params); + OPENSSL_free(ssl->quic_transport_params); + EVP_PKEY_free(ssl->tlsext_channel_id_private); + OPENSSL_free(ssl->psk_identity_hint); + sk_CRYPTO_BUFFER_pop_free(ssl->client_CA, CRYPTO_BUFFER_free); + sk_SRTP_PROTECTION_PROFILE_free(ssl->srtp_profiles); + + if (ssl->method != NULL) { + ssl->method->ssl_free(ssl); + } + SSL_CTX_free(ssl->ctx); + + OPENSSL_free(ssl); +} + +void SSL_set_connect_state(SSL *ssl) { + ssl->server = false; + ssl->do_handshake = ssl_client_handshake; +} + +void SSL_set_accept_state(SSL *ssl) { + ssl->server = true; + ssl->do_handshake = ssl_server_handshake; +} + +void SSL_set0_rbio(SSL *ssl, BIO *rbio) { + BIO_free_all(ssl->rbio); + ssl->rbio = rbio; +} + +void SSL_set0_wbio(SSL *ssl, BIO *wbio) { + BIO_free_all(ssl->wbio); + ssl->wbio = wbio; +} + +void SSL_set_bio(SSL *ssl, BIO *rbio, BIO *wbio) { + // For historical reasons, this function has many different cases in ownership + // handling. + + // If nothing has changed, do nothing + if (rbio == SSL_get_rbio(ssl) && wbio == SSL_get_wbio(ssl)) { + return; + } + + // If the two arguments are equal, one fewer reference is granted than + // taken. + if (rbio != NULL && rbio == wbio) { + BIO_up_ref(rbio); + } + + // If only the wbio is changed, adopt only one reference. + if (rbio == SSL_get_rbio(ssl)) { + SSL_set0_wbio(ssl, wbio); + return; + } + + // There is an asymmetry here for historical reasons. If only the rbio is + // changed AND the rbio and wbio were originally different, then we only adopt + // one reference. + if (wbio == SSL_get_wbio(ssl) && SSL_get_rbio(ssl) != SSL_get_wbio(ssl)) { + SSL_set0_rbio(ssl, rbio); + return; + } + + // Otherwise, adopt both references. + SSL_set0_rbio(ssl, rbio); + SSL_set0_wbio(ssl, wbio); +} + +BIO *SSL_get_rbio(const SSL *ssl) { return ssl->rbio; } + +BIO *SSL_get_wbio(const SSL *ssl) { return ssl->wbio; } + +int SSL_do_handshake(SSL *ssl) { + ssl_reset_error_state(ssl); + + if (ssl->do_handshake == NULL) { + OPENSSL_PUT_ERROR(SSL, SSL_R_CONNECTION_TYPE_NOT_SET); + return -1; + } + + if (!SSL_in_init(ssl)) { + return 1; + } + + // Run the handshake. + SSL_HANDSHAKE *hs = ssl->s3->hs.get(); + + bool early_return = false; + int ret = ssl_run_handshake(hs, &early_return); + ssl_do_info_callback( + ssl, ssl->server ? SSL_CB_ACCEPT_EXIT : SSL_CB_CONNECT_EXIT, ret); + if (ret <= 0) { + return ret; + } + + // Destroy the handshake object if the handshake has completely finished. + if (!early_return) { + ssl->s3->hs.reset(); + } + + return 1; +} + +int SSL_connect(SSL *ssl) { + if (ssl->do_handshake == NULL) { + // Not properly initialized yet + SSL_set_connect_state(ssl); + } + + return SSL_do_handshake(ssl); +} + +int SSL_accept(SSL *ssl) { + if (ssl->do_handshake == NULL) { + // Not properly initialized yet + SSL_set_accept_state(ssl); + } + + return SSL_do_handshake(ssl); +} + +static int ssl_do_post_handshake(SSL *ssl, const SSLMessage &msg) { + if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) { + return tls13_post_handshake(ssl, msg); + } + + // We do not accept renegotiations as a server or SSL 3.0. SSL 3.0 will be + // removed entirely in the future and requires retaining more data for + // renegotiation_info. + if (ssl->server || ssl->version == SSL3_VERSION) { + goto no_renegotiation; + } + + if (msg.type != SSL3_MT_HELLO_REQUEST || CBS_len(&msg.body) != 0) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_HELLO_REQUEST); + return 0; + } + + switch (ssl->renegotiate_mode) { + case ssl_renegotiate_ignore: + // Ignore the HelloRequest. + return 1; + + case ssl_renegotiate_once: + if (ssl->s3->total_renegotiations != 0) { + goto no_renegotiation; + } + break; + + case ssl_renegotiate_never: + goto no_renegotiation; + + case ssl_renegotiate_freely: + break; + } + + // Renegotiation is only supported at quiescent points in the application + // protocol, namely in HTTPS, just before reading the HTTP response. Require + // the record-layer be idle and avoid complexities of sending a handshake + // record while an application_data record is being written. + if (!ssl->s3->write_buffer.empty() || + ssl->s3->write_shutdown != ssl_shutdown_none) { + goto no_renegotiation; + } + + // Begin a new handshake. + if (ssl->s3->hs != nullptr) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return 0; + } + ssl->s3->hs = ssl_handshake_new(ssl); + if (ssl->s3->hs == nullptr) { + return 0; + } + + ssl->s3->total_renegotiations++; + return 1; + +no_renegotiation: + OPENSSL_PUT_ERROR(SSL, SSL_R_NO_RENEGOTIATION); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_NO_RENEGOTIATION); + return 0; +} + +static int ssl_read_impl(SSL *ssl) { + ssl_reset_error_state(ssl); + + if (ssl->do_handshake == NULL) { + OPENSSL_PUT_ERROR(SSL, SSL_R_UNINITIALIZED); + return -1; + } + + // Replay post-handshake message errors. + if (!check_read_error(ssl)) { + return -1; + } + + while (ssl->s3->pending_app_data.empty()) { + // Complete the current handshake, if any. False Start will cause + // |SSL_do_handshake| to return mid-handshake, so this may require multiple + // iterations. + while (!ssl_can_read(ssl)) { + int ret = SSL_do_handshake(ssl); + if (ret < 0) { + return ret; + } + if (ret == 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_SSL_HANDSHAKE_FAILURE); + return -1; + } + } + + // Process any buffered post-handshake messages. + SSLMessage msg; + if (ssl->method->get_message(ssl, &msg)) { + // If we received an interrupt in early read (EndOfEarlyData), loop again + // for the handshake to process it. + if (SSL_in_init(ssl)) { + ssl->s3->hs->can_early_read = false; + continue; + } + + // Handle the post-handshake message and try again. + if (!ssl_do_post_handshake(ssl, msg)) { + ssl_set_read_error(ssl); + return -1; + } + ssl->method->next_message(ssl); + continue; // Loop again. We may have begun a new handshake. + } + + uint8_t alert = SSL_AD_DECODE_ERROR; + size_t consumed = 0; + auto ret = ssl_open_app_data(ssl, &ssl->s3->pending_app_data, &consumed, + &alert, ssl->s3->read_buffer.span()); + bool retry; + int bio_ret = ssl_handle_open_record(ssl, &retry, ret, consumed, alert); + if (bio_ret <= 0) { + return bio_ret; + } + if (!retry) { + assert(!ssl->s3->pending_app_data.empty()); + ssl->s3->key_update_count = 0; + } + } + + return 1; +} + +int SSL_read(SSL *ssl, void *buf, int num) { + int ret = SSL_peek(ssl, buf, num); + if (ret <= 0) { + return ret; + } + // TODO(davidben): In DTLS, should the rest of the record be discarded? DTLS + // is not a stream. See https://crbug.com/boringssl/65. + ssl->s3->pending_app_data = + ssl->s3->pending_app_data.subspan(static_cast(ret)); + if (ssl->s3->pending_app_data.empty()) { + ssl->s3->read_buffer.DiscardConsumed(); + } + return ret; +} + +int SSL_peek(SSL *ssl, void *buf, int num) { + int ret = ssl_read_impl(ssl); + if (ret <= 0) { + return ret; + } + if (num <= 0) { + return num; + } + size_t todo = + std::min(ssl->s3->pending_app_data.size(), static_cast(num)); + OPENSSL_memcpy(buf, ssl->s3->pending_app_data.data(), todo); + return static_cast(todo); +} + +int SSL_write(SSL *ssl, const void *buf, int num) { + ssl_reset_error_state(ssl); + + if (ssl->do_handshake == NULL) { + OPENSSL_PUT_ERROR(SSL, SSL_R_UNINITIALIZED); + return -1; + } + + if (ssl->s3->write_shutdown != ssl_shutdown_none) { + OPENSSL_PUT_ERROR(SSL, SSL_R_PROTOCOL_IS_SHUTDOWN); + return -1; + } + + int ret = 0; + bool needs_handshake = false; + do { + // If necessary, complete the handshake implicitly. + if (!ssl_can_write(ssl)) { + ret = SSL_do_handshake(ssl); + if (ret < 0) { + return ret; + } + if (ret == 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_SSL_HANDSHAKE_FAILURE); + return -1; + } + } + + ret = ssl->method->write_app_data(ssl, &needs_handshake, + (const uint8_t *)buf, num); + } while (needs_handshake); + return ret; +} + +int SSL_shutdown(SSL *ssl) { + ssl_reset_error_state(ssl); + + if (ssl->do_handshake == NULL) { + OPENSSL_PUT_ERROR(SSL, SSL_R_UNINITIALIZED); + return -1; + } + + // If we are in the middle of a handshake, silently succeed. Consumers often + // call this function before |SSL_free|, whether the handshake succeeded or + // not. We assume the caller has already handled failed handshakes. + if (SSL_in_init(ssl)) { + return 1; + } + + if (ssl->quiet_shutdown) { + // Do nothing if configured not to send a close_notify. + ssl->s3->write_shutdown = ssl_shutdown_close_notify; + ssl->s3->read_shutdown = ssl_shutdown_close_notify; + return 1; + } + + // This function completes in two stages. It sends a close_notify and then it + // waits for a close_notify to come in. Perform exactly one action and return + // whether or not it succeeds. + + if (ssl->s3->write_shutdown != ssl_shutdown_close_notify) { + // Send a close_notify. + if (ssl_send_alert(ssl, SSL3_AL_WARNING, SSL_AD_CLOSE_NOTIFY) <= 0) { + return -1; + } + } else if (ssl->s3->alert_dispatch) { + // Finish sending the close_notify. + if (ssl->method->dispatch_alert(ssl) <= 0) { + return -1; + } + } else if (ssl->s3->read_shutdown != ssl_shutdown_close_notify) { + if (SSL_is_dtls(ssl)) { + // Bidirectional shutdown doesn't make sense for an unordered + // transport. DTLS alerts also aren't delivered reliably, so we may even + // time out because the peer never received our close_notify. Report to + // the caller that the channel has fully shut down. + if (ssl->s3->read_shutdown == ssl_shutdown_error) { + ERR_restore_state(ssl->s3->read_error.get()); + return -1; + } + ssl->s3->read_shutdown = ssl_shutdown_close_notify; + } else { + // Keep discarding data until we see a close_notify. + for (;;) { + ssl->s3->pending_app_data = Span(); + int ret = ssl_read_impl(ssl); + if (ret <= 0) { + break; + } + } + if (ssl->s3->read_shutdown != ssl_shutdown_close_notify) { + return -1; + } + } + } + + // Return 0 for unidirectional shutdown and 1 for bidirectional shutdown. + return ssl->s3->read_shutdown == ssl_shutdown_close_notify; +} + +int SSL_send_fatal_alert(SSL *ssl, uint8_t alert) { + if (ssl->s3->alert_dispatch) { + if (ssl->s3->send_alert[0] != SSL3_AL_FATAL || + ssl->s3->send_alert[1] != alert) { + // We are already attempting to write a different alert. + OPENSSL_PUT_ERROR(SSL, SSL_R_PROTOCOL_IS_SHUTDOWN); + return -1; + } + return ssl->method->dispatch_alert(ssl); + } + + return ssl_send_alert(ssl, SSL3_AL_FATAL, alert); +} + +int SSL_set_quic_transport_params(SSL *ssl, const uint8_t *params, + size_t params_len) { + ssl->quic_transport_params = (uint8_t *)BUF_memdup(params, params_len); + if (!ssl->quic_transport_params) { + return 0; + } + ssl->quic_transport_params_len = params_len; + return 1; +} + +void SSL_get_peer_quic_transport_params(const SSL *ssl, + const uint8_t **out_params, + size_t *out_params_len) { + *out_params = ssl->s3->peer_quic_transport_params.data(); + *out_params_len = ssl->s3->peer_quic_transport_params.size(); +} + +void SSL_CTX_set_early_data_enabled(SSL_CTX *ctx, int enabled) { + ctx->cert->enable_early_data = !!enabled; +} + +void SSL_CTX_set_tls13_variant(SSL_CTX *ctx, enum tls13_variant_t variant) { + ctx->tls13_variant = variant; +} + +void SSL_set_tls13_variant(SSL *ssl, enum tls13_variant_t variant) { + ssl->tls13_variant = variant; +} + +void SSL_set_early_data_enabled(SSL *ssl, int enabled) { + ssl->cert->enable_early_data = !!enabled; +} + +int SSL_in_early_data(const SSL *ssl) { + if (ssl->s3->hs == NULL) { + return 0; + } + return ssl->s3->hs->in_early_data; +} + +int SSL_early_data_accepted(const SSL *ssl) { + return ssl->s3->early_data_accepted; +} + +void SSL_reset_early_data_reject(SSL *ssl) { + SSL_HANDSHAKE *hs = ssl->s3->hs.get(); + if (hs == NULL || + hs->wait != ssl_hs_early_data_rejected) { + abort(); + } + + hs->wait = ssl_hs_ok; + hs->in_early_data = false; + hs->early_session.reset(); + + // Discard any unfinished writes from the perspective of |SSL_write|'s + // retry. The handshake will transparently flush out the pending record + // (discarded by the server) to keep the framing correct. + ssl->s3->wpend_pending = false; +} + +static int bio_retry_reason_to_error(int reason) { + switch (reason) { + case BIO_RR_CONNECT: + return SSL_ERROR_WANT_CONNECT; + case BIO_RR_ACCEPT: + return SSL_ERROR_WANT_ACCEPT; + default: + return SSL_ERROR_SYSCALL; + } +} + +int SSL_get_error(const SSL *ssl, int ret_code) { + if (ret_code > 0) { + return SSL_ERROR_NONE; + } + + // Make things return SSL_ERROR_SYSCALL when doing SSL_do_handshake etc, + // where we do encode the error + uint32_t err = ERR_peek_error(); + if (err != 0) { + if (ERR_GET_LIB(err) == ERR_LIB_SYS) { + return SSL_ERROR_SYSCALL; + } + return SSL_ERROR_SSL; + } + + if (ret_code == 0) { + if (ssl->s3->read_shutdown == ssl_shutdown_close_notify) { + return SSL_ERROR_ZERO_RETURN; + } + // An EOF was observed which violates the protocol, and the underlying + // transport does not participate in the error queue. Bubble up to the + // caller. + return SSL_ERROR_SYSCALL; + } + + switch (ssl->s3->rwstate) { + case SSL_PENDING_SESSION: + return SSL_ERROR_PENDING_SESSION; + + case SSL_CERTIFICATE_SELECTION_PENDING: + return SSL_ERROR_PENDING_CERTIFICATE; + + case SSL_HANDOFF: + return SSL_ERROR_HANDOFF; + + case SSL_READING: { + BIO *bio = SSL_get_rbio(ssl); + if (BIO_should_read(bio)) { + return SSL_ERROR_WANT_READ; + } + + if (BIO_should_write(bio)) { + // TODO(davidben): OpenSSL historically checked for writes on the read + // BIO. Can this be removed? + return SSL_ERROR_WANT_WRITE; + } + + if (BIO_should_io_special(bio)) { + return bio_retry_reason_to_error(BIO_get_retry_reason(bio)); + } + + break; + } + + case SSL_WRITING: { + BIO *bio = SSL_get_wbio(ssl); + if (BIO_should_write(bio)) { + return SSL_ERROR_WANT_WRITE; + } + + if (BIO_should_read(bio)) { + // TODO(davidben): OpenSSL historically checked for reads on the write + // BIO. Can this be removed? + return SSL_ERROR_WANT_READ; + } + + if (BIO_should_io_special(bio)) { + return bio_retry_reason_to_error(BIO_get_retry_reason(bio)); + } + + break; + } + + case SSL_X509_LOOKUP: + return SSL_ERROR_WANT_X509_LOOKUP; + + case SSL_CHANNEL_ID_LOOKUP: + return SSL_ERROR_WANT_CHANNEL_ID_LOOKUP; + + case SSL_PRIVATE_KEY_OPERATION: + return SSL_ERROR_WANT_PRIVATE_KEY_OPERATION; + + case SSL_PENDING_TICKET: + return SSL_ERROR_PENDING_TICKET; + + case SSL_EARLY_DATA_REJECTED: + return SSL_ERROR_EARLY_DATA_REJECTED; + + case SSL_CERTIFICATE_VERIFY: + return SSL_ERROR_WANT_CERTIFICATE_VERIFY; + } + + return SSL_ERROR_SYSCALL; +} + +uint32_t SSL_CTX_set_options(SSL_CTX *ctx, uint32_t options) { + ctx->options |= options; + return ctx->options; +} + +uint32_t SSL_CTX_clear_options(SSL_CTX *ctx, uint32_t options) { + ctx->options &= ~options; + return ctx->options; +} + +uint32_t SSL_CTX_get_options(const SSL_CTX *ctx) { return ctx->options; } + +uint32_t SSL_set_options(SSL *ssl, uint32_t options) { + ssl->options |= options; + return ssl->options; +} + +uint32_t SSL_clear_options(SSL *ssl, uint32_t options) { + ssl->options &= ~options; + return ssl->options; +} + +uint32_t SSL_get_options(const SSL *ssl) { return ssl->options; } + +uint32_t SSL_CTX_set_mode(SSL_CTX *ctx, uint32_t mode) { + ctx->mode |= mode; + return ctx->mode; +} + +uint32_t SSL_CTX_clear_mode(SSL_CTX *ctx, uint32_t mode) { + ctx->mode &= ~mode; + return ctx->mode; +} + +uint32_t SSL_CTX_get_mode(const SSL_CTX *ctx) { return ctx->mode; } + +uint32_t SSL_set_mode(SSL *ssl, uint32_t mode) { + ssl->mode |= mode; + return ssl->mode; +} + +uint32_t SSL_clear_mode(SSL *ssl, uint32_t mode) { + ssl->mode &= ~mode; + return ssl->mode; +} + +uint32_t SSL_get_mode(const SSL *ssl) { return ssl->mode; } + +void SSL_CTX_set0_buffer_pool(SSL_CTX *ctx, CRYPTO_BUFFER_POOL *pool) { + ctx->pool = pool; +} + +int SSL_get_tls_unique(const SSL *ssl, uint8_t *out, size_t *out_len, + size_t max_out) { + *out_len = 0; + OPENSSL_memset(out, 0, max_out); + + // tls-unique is not defined for SSL 3.0 or TLS 1.3. + if (!ssl->s3->initial_handshake_complete || + ssl_protocol_version(ssl) < TLS1_VERSION || + ssl_protocol_version(ssl) >= TLS1_3_VERSION) { + return 0; + } + + // The tls-unique value is the first Finished message in the handshake, which + // is the client's in a full handshake and the server's for a resumption. See + // https://tools.ietf.org/html/rfc5929#section-3.1. + const uint8_t *finished = ssl->s3->previous_client_finished; + size_t finished_len = ssl->s3->previous_client_finished_len; + if (ssl->session != NULL) { + // tls-unique is broken for resumed sessions unless EMS is used. + if (!ssl->session->extended_master_secret) { + return 0; + } + finished = ssl->s3->previous_server_finished; + finished_len = ssl->s3->previous_server_finished_len; + } + + *out_len = finished_len; + if (finished_len > max_out) { + *out_len = max_out; + } + + OPENSSL_memcpy(out, finished, *out_len); + return 1; +} + +static int set_session_id_context(CERT *cert, const uint8_t *sid_ctx, + size_t sid_ctx_len) { + if (sid_ctx_len > sizeof(cert->sid_ctx)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG); + return 0; + } + + static_assert(sizeof(cert->sid_ctx) < 256, "sid_ctx too large"); + cert->sid_ctx_length = (uint8_t)sid_ctx_len; + OPENSSL_memcpy(cert->sid_ctx, sid_ctx, sid_ctx_len); + return 1; +} + +int SSL_CTX_set_session_id_context(SSL_CTX *ctx, const uint8_t *sid_ctx, + size_t sid_ctx_len) { + return set_session_id_context(ctx->cert, sid_ctx, sid_ctx_len); +} + +int SSL_set_session_id_context(SSL *ssl, const uint8_t *sid_ctx, + size_t sid_ctx_len) { + return set_session_id_context(ssl->cert, sid_ctx, sid_ctx_len); +} + +const uint8_t *SSL_get0_session_id_context(const SSL *ssl, size_t *out_len) { + *out_len = ssl->cert->sid_ctx_length; + return ssl->cert->sid_ctx; +} + +void SSL_certs_clear(SSL *ssl) { ssl_cert_clear_certs(ssl->cert); } + +int SSL_get_fd(const SSL *ssl) { return SSL_get_rfd(ssl); } + +int SSL_get_rfd(const SSL *ssl) { + int ret = -1; + BIO *b = BIO_find_type(SSL_get_rbio(ssl), BIO_TYPE_DESCRIPTOR); + if (b != NULL) { + BIO_get_fd(b, &ret); + } + return ret; +} + +int SSL_get_wfd(const SSL *ssl) { + int ret = -1; + BIO *b = BIO_find_type(SSL_get_wbio(ssl), BIO_TYPE_DESCRIPTOR); + if (b != NULL) { + BIO_get_fd(b, &ret); + } + return ret; +} + +int SSL_set_fd(SSL *ssl, int fd) { + BIO *bio = BIO_new(BIO_s_socket()); + if (bio == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB); + return 0; + } + BIO_set_fd(bio, fd, BIO_NOCLOSE); + SSL_set_bio(ssl, bio, bio); + return 1; +} + +int SSL_set_wfd(SSL *ssl, int fd) { + BIO *rbio = SSL_get_rbio(ssl); + if (rbio == NULL || BIO_method_type(rbio) != BIO_TYPE_SOCKET || + BIO_get_fd(rbio, NULL) != fd) { + BIO *bio = BIO_new(BIO_s_socket()); + if (bio == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB); + return 0; + } + BIO_set_fd(bio, fd, BIO_NOCLOSE); + SSL_set0_wbio(ssl, bio); + } else { + // Copy the rbio over to the wbio. + BIO_up_ref(rbio); + SSL_set0_wbio(ssl, rbio); + } + + return 1; +} + +int SSL_set_rfd(SSL *ssl, int fd) { + BIO *wbio = SSL_get_wbio(ssl); + if (wbio == NULL || BIO_method_type(wbio) != BIO_TYPE_SOCKET || + BIO_get_fd(wbio, NULL) != fd) { + BIO *bio = BIO_new(BIO_s_socket()); + if (bio == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_BUF_LIB); + return 0; + } + BIO_set_fd(bio, fd, BIO_NOCLOSE); + SSL_set0_rbio(ssl, bio); + } else { + // Copy the wbio over to the rbio. + BIO_up_ref(wbio); + SSL_set0_rbio(ssl, wbio); + } + return 1; +} + +static size_t copy_finished(void *out, size_t out_len, const uint8_t *in, + size_t in_len) { + if (out_len > in_len) { + out_len = in_len; + } + OPENSSL_memcpy(out, in, out_len); + return in_len; +} + +size_t SSL_get_finished(const SSL *ssl, void *buf, size_t count) { + if (!ssl->s3->initial_handshake_complete || + ssl_protocol_version(ssl) < TLS1_VERSION || + ssl_protocol_version(ssl) >= TLS1_3_VERSION) { + return 0; + } + + if (ssl->server) { + return copy_finished(buf, count, ssl->s3->previous_server_finished, + ssl->s3->previous_server_finished_len); + } + + return copy_finished(buf, count, ssl->s3->previous_client_finished, + ssl->s3->previous_client_finished_len); +} + +size_t SSL_get_peer_finished(const SSL *ssl, void *buf, size_t count) { + if (!ssl->s3->initial_handshake_complete || + ssl_protocol_version(ssl) < TLS1_VERSION || + ssl_protocol_version(ssl) >= TLS1_3_VERSION) { + return 0; + } + + if (ssl->server) { + return copy_finished(buf, count, ssl->s3->previous_client_finished, + ssl->s3->previous_client_finished_len); + } + + return copy_finished(buf, count, ssl->s3->previous_server_finished, + ssl->s3->previous_server_finished_len); +} + +int SSL_get_verify_mode(const SSL *ssl) { return ssl->verify_mode; } + +int SSL_get_extms_support(const SSL *ssl) { + // TLS 1.3 does not require extended master secret and always reports as + // supporting it. + if (!ssl->s3->have_version) { + return 0; + } + if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) { + return 1; + } + + // If the initial handshake completed, query the established session. + if (ssl->s3->established_session != NULL) { + return ssl->s3->established_session->extended_master_secret; + } + + // Otherwise, query the in-progress handshake. + if (ssl->s3->hs != NULL) { + return ssl->s3->hs->extended_master_secret; + } + assert(0); + return 0; +} + +int SSL_CTX_get_read_ahead(const SSL_CTX *ctx) { return 0; } + +int SSL_get_read_ahead(const SSL *ssl) { return 0; } + +void SSL_CTX_set_read_ahead(SSL_CTX *ctx, int yes) { } + +void SSL_set_read_ahead(SSL *ssl, int yes) { } + +int SSL_pending(const SSL *ssl) { + return static_cast(ssl->s3->pending_app_data.size()); +} + +// Fix this so it checks all the valid key/cert options +int SSL_CTX_check_private_key(const SSL_CTX *ctx) { + return ssl_cert_check_private_key(ctx->cert, ctx->cert->privatekey); +} + +// Fix this function so that it takes an optional type parameter +int SSL_check_private_key(const SSL *ssl) { + return ssl_cert_check_private_key(ssl->cert, ssl->cert->privatekey); +} + +long SSL_get_default_timeout(const SSL *ssl) { + return SSL_DEFAULT_SESSION_TIMEOUT; +} + +int SSL_renegotiate(SSL *ssl) { + // Caller-initiated renegotiation is not supported. + OPENSSL_PUT_ERROR(SSL, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED); + return 0; +} + +int SSL_renegotiate_pending(SSL *ssl) { + return SSL_in_init(ssl) && ssl->s3->initial_handshake_complete; +} + +int SSL_total_renegotiations(const SSL *ssl) { + return ssl->s3->total_renegotiations; +} + +size_t SSL_CTX_get_max_cert_list(const SSL_CTX *ctx) { + return ctx->max_cert_list; +} + +void SSL_CTX_set_max_cert_list(SSL_CTX *ctx, size_t max_cert_list) { + if (max_cert_list > kMaxHandshakeSize) { + max_cert_list = kMaxHandshakeSize; + } + ctx->max_cert_list = (uint32_t)max_cert_list; +} + +size_t SSL_get_max_cert_list(const SSL *ssl) { + return ssl->max_cert_list; +} + +void SSL_set_max_cert_list(SSL *ssl, size_t max_cert_list) { + if (max_cert_list > kMaxHandshakeSize) { + max_cert_list = kMaxHandshakeSize; + } + ssl->max_cert_list = (uint32_t)max_cert_list; +} + +int SSL_CTX_set_max_send_fragment(SSL_CTX *ctx, size_t max_send_fragment) { + if (max_send_fragment < 512) { + max_send_fragment = 512; + } + if (max_send_fragment > SSL3_RT_MAX_PLAIN_LENGTH) { + max_send_fragment = SSL3_RT_MAX_PLAIN_LENGTH; + } + ctx->max_send_fragment = (uint16_t)max_send_fragment; + + return 1; +} + +int SSL_set_max_send_fragment(SSL *ssl, size_t max_send_fragment) { + if (max_send_fragment < 512) { + max_send_fragment = 512; + } + if (max_send_fragment > SSL3_RT_MAX_PLAIN_LENGTH) { + max_send_fragment = SSL3_RT_MAX_PLAIN_LENGTH; + } + ssl->max_send_fragment = (uint16_t)max_send_fragment; + + return 1; +} + +int SSL_set_mtu(SSL *ssl, unsigned mtu) { + if (!SSL_is_dtls(ssl) || mtu < dtls1_min_mtu()) { + return 0; + } + ssl->d1->mtu = mtu; + return 1; +} + +int SSL_get_secure_renegotiation_support(const SSL *ssl) { + if (!ssl->s3->have_version) { + return 0; + } + return ssl_protocol_version(ssl) >= TLS1_3_VERSION || + ssl->s3->send_connection_binding; +} + +size_t SSL_CTX_sess_number(const SSL_CTX *ctx) { + MutexReadLock lock(const_cast(&ctx->lock)); + return lh_SSL_SESSION_num_items(ctx->sessions); +} + +unsigned long SSL_CTX_sess_set_cache_size(SSL_CTX *ctx, unsigned long size) { + unsigned long ret = ctx->session_cache_size; + ctx->session_cache_size = size; + return ret; +} + +unsigned long SSL_CTX_sess_get_cache_size(const SSL_CTX *ctx) { + return ctx->session_cache_size; +} + +int SSL_CTX_set_session_cache_mode(SSL_CTX *ctx, int mode) { + int ret = ctx->session_cache_mode; + ctx->session_cache_mode = mode; + return ret; +} + +int SSL_CTX_get_session_cache_mode(const SSL_CTX *ctx) { + return ctx->session_cache_mode; +} + + +int SSL_CTX_get_tlsext_ticket_keys(SSL_CTX *ctx, void *out, size_t len) { + if (out == NULL) { + return 48; + } + if (len != 48) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_TICKET_KEYS_LENGTH); + return 0; + } + + // The default ticket keys are initialized lazily. Trigger a key + // rotation to initialize them. + if (!ssl_ctx_rotate_ticket_encryption_key(ctx)) { + return 0; + } + + uint8_t *out_bytes = reinterpret_cast(out); + MutexReadLock lock(&ctx->lock); + OPENSSL_memcpy(out_bytes, ctx->tlsext_ticket_key_current->name, 16); + OPENSSL_memcpy(out_bytes + 16, ctx->tlsext_ticket_key_current->hmac_key, 16); + OPENSSL_memcpy(out_bytes + 32, ctx->tlsext_ticket_key_current->aes_key, 16); + return 1; +} + +int SSL_CTX_set_tlsext_ticket_keys(SSL_CTX *ctx, const void *in, size_t len) { + if (in == NULL) { + return 48; + } + if (len != 48) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_TICKET_KEYS_LENGTH); + return 0; + } + if (!ctx->tlsext_ticket_key_current) { + ctx->tlsext_ticket_key_current = + (tlsext_ticket_key *)OPENSSL_malloc(sizeof(tlsext_ticket_key)); + if (!ctx->tlsext_ticket_key_current) { + return 0; + } + } + OPENSSL_memset(ctx->tlsext_ticket_key_current, 0, sizeof(tlsext_ticket_key)); + const uint8_t *in_bytes = reinterpret_cast(in); + OPENSSL_memcpy(ctx->tlsext_ticket_key_current->name, in_bytes, 16); + OPENSSL_memcpy(ctx->tlsext_ticket_key_current->hmac_key, in_bytes + 16, 16); + OPENSSL_memcpy(ctx->tlsext_ticket_key_current->aes_key, in_bytes + 32, 16); + OPENSSL_free(ctx->tlsext_ticket_key_prev); + ctx->tlsext_ticket_key_prev = nullptr; + // Disable automatic key rotation. + ctx->tlsext_ticket_key_current->next_rotation_tv_sec = 0; + return 1; +} + +int SSL_CTX_set_tlsext_ticket_key_cb( + SSL_CTX *ctx, int (*callback)(SSL *ssl, uint8_t *key_name, uint8_t *iv, + EVP_CIPHER_CTX *ctx, HMAC_CTX *hmac_ctx, + int encrypt)) { + ctx->tlsext_ticket_key_cb = callback; + return 1; +} + +int SSL_CTX_set1_curves(SSL_CTX *ctx, const int *curves, size_t curves_len) { + return tls1_set_curves(&ctx->supported_group_list, + &ctx->supported_group_list_len, curves, + curves_len); +} + +int SSL_set1_curves(SSL *ssl, const int *curves, size_t curves_len) { + return tls1_set_curves(&ssl->supported_group_list, + &ssl->supported_group_list_len, curves, + curves_len); +} + +int SSL_CTX_set1_curves_list(SSL_CTX *ctx, const char *curves) { + return tls1_set_curves_list(&ctx->supported_group_list, + &ctx->supported_group_list_len, curves); +} + +int SSL_set1_curves_list(SSL *ssl, const char *curves) { + return tls1_set_curves_list(&ssl->supported_group_list, + &ssl->supported_group_list_len, curves); +} + +uint16_t SSL_get_curve_id(const SSL *ssl) { + // TODO(davidben): This checks the wrong session if there is a renegotiation + // in progress. + SSL_SESSION *session = SSL_get_session(ssl); + if (session == NULL) { + return 0; + } + + return session->group_id; +} + +int SSL_CTX_set_tmp_dh(SSL_CTX *ctx, const DH *dh) { + return 1; +} + +int SSL_set_tmp_dh(SSL *ssl, const DH *dh) { + return 1; +} + +STACK_OF(SSL_CIPHER) *SSL_CTX_get_ciphers(const SSL_CTX *ctx) { + return ctx->cipher_list->ciphers; +} + +int SSL_CTX_cipher_in_group(const SSL_CTX *ctx, size_t i) { + if (i >= sk_SSL_CIPHER_num(ctx->cipher_list->ciphers)) { + return 0; + } + return ctx->cipher_list->in_group_flags[i]; +} + +STACK_OF(SSL_CIPHER) *SSL_get_ciphers(const SSL *ssl) { + if (ssl == NULL) { + return NULL; + } + + const struct ssl_cipher_preference_list_st *prefs = + ssl_get_cipher_preferences(ssl); + if (prefs == NULL) { + return NULL; + } + + return prefs->ciphers; +} + +const char *SSL_get_cipher_list(const SSL *ssl, int n) { + if (ssl == NULL) { + return NULL; + } + + STACK_OF(SSL_CIPHER) *sk = SSL_get_ciphers(ssl); + if (sk == NULL || n < 0 || (size_t)n >= sk_SSL_CIPHER_num(sk)) { + return NULL; + } + + const SSL_CIPHER *c = sk_SSL_CIPHER_value(sk, n); + if (c == NULL) { + return NULL; + } + + return c->name; +} + +int SSL_CTX_set_cipher_list(SSL_CTX *ctx, const char *str) { + return ssl_create_cipher_list(&ctx->cipher_list, str, false /* not strict */); +} + +int SSL_CTX_set_strict_cipher_list(SSL_CTX *ctx, const char *str) { + return ssl_create_cipher_list(&ctx->cipher_list, str, true /* strict */); +} + +int SSL_set_cipher_list(SSL *ssl, const char *str) { + return ssl_create_cipher_list(&ssl->cipher_list, str, false /* not strict */); +} + +int SSL_set_strict_cipher_list(SSL *ssl, const char *str) { + return ssl_create_cipher_list(&ssl->cipher_list, str, true /* strict */); +} + +const char *SSL_get_servername(const SSL *ssl, const int type) { + if (type != TLSEXT_NAMETYPE_host_name) { + return NULL; + } + + // Historically, |SSL_get_servername| was also the configuration getter + // corresponding to |SSL_set_tlsext_host_name|. + if (ssl->tlsext_hostname != NULL) { + return ssl->tlsext_hostname; + } + + return ssl->s3->hostname.get(); +} + +int SSL_get_servername_type(const SSL *ssl) { + if (SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name) == NULL) { + return -1; + } + return TLSEXT_NAMETYPE_host_name; +} + +void SSL_CTX_set_custom_verify( + SSL_CTX *ctx, int mode, + enum ssl_verify_result_t (*callback)(SSL *ssl, uint8_t *out_alert)) { + ctx->verify_mode = mode; + ctx->custom_verify_callback = callback; +} + +void SSL_set_custom_verify( + SSL *ssl, int mode, + enum ssl_verify_result_t (*callback)(SSL *ssl, uint8_t *out_alert)) { + ssl->verify_mode = mode; + ssl->custom_verify_callback = callback; +} + +void SSL_CTX_enable_signed_cert_timestamps(SSL_CTX *ctx) { + ctx->signed_cert_timestamps_enabled = true; +} + +void SSL_enable_signed_cert_timestamps(SSL *ssl) { + ssl->signed_cert_timestamps_enabled = true; +} + +void SSL_CTX_enable_ocsp_stapling(SSL_CTX *ctx) { + ctx->ocsp_stapling_enabled = true; +} + +void SSL_enable_ocsp_stapling(SSL *ssl) { + ssl->ocsp_stapling_enabled = true; +} + +void SSL_get0_signed_cert_timestamp_list(const SSL *ssl, const uint8_t **out, + size_t *out_len) { + SSL_SESSION *session = SSL_get_session(ssl); + if (ssl->server || !session || !session->signed_cert_timestamp_list) { + *out_len = 0; + *out = NULL; + return; + } + + *out = CRYPTO_BUFFER_data(session->signed_cert_timestamp_list); + *out_len = CRYPTO_BUFFER_len(session->signed_cert_timestamp_list); +} + +void SSL_get0_ocsp_response(const SSL *ssl, const uint8_t **out, + size_t *out_len) { + SSL_SESSION *session = SSL_get_session(ssl); + if (ssl->server || !session || !session->ocsp_response) { + *out_len = 0; + *out = NULL; + return; + } + + *out = CRYPTO_BUFFER_data(session->ocsp_response); + *out_len = CRYPTO_BUFFER_len(session->ocsp_response); +} + +int SSL_set_tlsext_host_name(SSL *ssl, const char *name) { + OPENSSL_free(ssl->tlsext_hostname); + ssl->tlsext_hostname = NULL; + + if (name == NULL) { + return 1; + } + + size_t len = strlen(name); + if (len == 0 || len > TLSEXT_MAXLEN_host_name) { + OPENSSL_PUT_ERROR(SSL, SSL_R_SSL3_EXT_INVALID_SERVERNAME); + return 0; + } + ssl->tlsext_hostname = BUF_strdup(name); + if (ssl->tlsext_hostname == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + return 1; +} + +int SSL_CTX_set_tlsext_servername_callback( + SSL_CTX *ctx, int (*callback)(SSL *ssl, int *out_alert, void *arg)) { + ctx->tlsext_servername_callback = callback; + return 1; +} + +int SSL_CTX_set_tlsext_servername_arg(SSL_CTX *ctx, void *arg) { + ctx->tlsext_servername_arg = arg; + return 1; +} + +int SSL_select_next_proto(uint8_t **out, uint8_t *out_len, const uint8_t *peer, + unsigned peer_len, const uint8_t *supported, + unsigned supported_len) { + const uint8_t *result; + int status; + + // For each protocol in peer preference order, see if we support it. + for (unsigned i = 0; i < peer_len;) { + for (unsigned j = 0; j < supported_len;) { + if (peer[i] == supported[j] && + OPENSSL_memcmp(&peer[i + 1], &supported[j + 1], peer[i]) == 0) { + // We found a match + result = &peer[i]; + status = OPENSSL_NPN_NEGOTIATED; + goto found; + } + j += supported[j]; + j++; + } + i += peer[i]; + i++; + } + + // There's no overlap between our protocols and the peer's list. + result = supported; + status = OPENSSL_NPN_NO_OVERLAP; + +found: + *out = (uint8_t *)result + 1; + *out_len = result[0]; + return status; +} + +void SSL_get0_next_proto_negotiated(const SSL *ssl, const uint8_t **out_data, + unsigned *out_len) { + *out_data = ssl->s3->next_proto_negotiated.data(); + *out_len = ssl->s3->next_proto_negotiated.size(); +} + +void SSL_CTX_set_next_protos_advertised_cb( + SSL_CTX *ctx, + int (*cb)(SSL *ssl, const uint8_t **out, unsigned *out_len, void *arg), + void *arg) { + ctx->next_protos_advertised_cb = cb; + ctx->next_protos_advertised_cb_arg = arg; +} + +void SSL_CTX_set_next_proto_select_cb( + SSL_CTX *ctx, int (*cb)(SSL *ssl, uint8_t **out, uint8_t *out_len, + const uint8_t *in, unsigned in_len, void *arg), + void *arg) { + ctx->next_proto_select_cb = cb; + ctx->next_proto_select_cb_arg = arg; +} + +int SSL_CTX_set_alpn_protos(SSL_CTX *ctx, const uint8_t *protos, + unsigned protos_len) { + OPENSSL_free(ctx->alpn_client_proto_list); + ctx->alpn_client_proto_list = (uint8_t *)BUF_memdup(protos, protos_len); + if (!ctx->alpn_client_proto_list) { + return 1; + } + ctx->alpn_client_proto_list_len = protos_len; + + return 0; +} + +int SSL_set_alpn_protos(SSL *ssl, const uint8_t *protos, unsigned protos_len) { + OPENSSL_free(ssl->alpn_client_proto_list); + ssl->alpn_client_proto_list = (uint8_t *)BUF_memdup(protos, protos_len); + if (!ssl->alpn_client_proto_list) { + return 1; + } + ssl->alpn_client_proto_list_len = protos_len; + + return 0; +} + +void SSL_CTX_set_alpn_select_cb(SSL_CTX *ctx, + int (*cb)(SSL *ssl, const uint8_t **out, + uint8_t *out_len, const uint8_t *in, + unsigned in_len, void *arg), + void *arg) { + ctx->alpn_select_cb = cb; + ctx->alpn_select_cb_arg = arg; +} + +void SSL_get0_alpn_selected(const SSL *ssl, const uint8_t **out_data, + unsigned *out_len) { + if (SSL_in_early_data(ssl) && !ssl->server) { + *out_data = ssl->s3->hs->early_session->early_alpn; + *out_len = ssl->s3->hs->early_session->early_alpn_len; + } else { + *out_data = ssl->s3->alpn_selected.data(); + *out_len = ssl->s3->alpn_selected.size(); + } +} + +void SSL_CTX_set_allow_unknown_alpn_protos(SSL_CTX *ctx, int enabled) { + ctx->allow_unknown_alpn_protos = !!enabled; +} + +void SSL_CTX_set_tls_channel_id_enabled(SSL_CTX *ctx, int enabled) { + ctx->tlsext_channel_id_enabled = !!enabled; +} + +int SSL_CTX_enable_tls_channel_id(SSL_CTX *ctx) { + SSL_CTX_set_tls_channel_id_enabled(ctx, 1); + return 1; +} + +void SSL_set_tls_channel_id_enabled(SSL *ssl, int enabled) { + ssl->tlsext_channel_id_enabled = !!enabled; +} + +int SSL_enable_tls_channel_id(SSL *ssl) { + SSL_set_tls_channel_id_enabled(ssl, 1); + return 1; +} + +static int is_p256_key(EVP_PKEY *private_key) { + const EC_KEY *ec_key = EVP_PKEY_get0_EC_KEY(private_key); + return ec_key != NULL && + EC_GROUP_get_curve_name(EC_KEY_get0_group(ec_key)) == + NID_X9_62_prime256v1; +} + +int SSL_CTX_set1_tls_channel_id(SSL_CTX *ctx, EVP_PKEY *private_key) { + if (!is_p256_key(private_key)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_CHANNEL_ID_NOT_P256); + return 0; + } + + EVP_PKEY_free(ctx->tlsext_channel_id_private); + EVP_PKEY_up_ref(private_key); + ctx->tlsext_channel_id_private = private_key; + ctx->tlsext_channel_id_enabled = true; + + return 1; +} + +int SSL_set1_tls_channel_id(SSL *ssl, EVP_PKEY *private_key) { + if (!is_p256_key(private_key)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_CHANNEL_ID_NOT_P256); + return 0; + } + + EVP_PKEY_free(ssl->tlsext_channel_id_private); + EVP_PKEY_up_ref(private_key); + ssl->tlsext_channel_id_private = private_key; + ssl->tlsext_channel_id_enabled = true; + + return 1; +} + +size_t SSL_get_tls_channel_id(SSL *ssl, uint8_t *out, size_t max_out) { + if (!ssl->s3->tlsext_channel_id_valid) { + return 0; + } + OPENSSL_memcpy(out, ssl->s3->tlsext_channel_id, + (max_out < 64) ? max_out : 64); + return 64; +} + +int SSL_set_token_binding_params(SSL *ssl, const uint8_t *params, size_t len) { + if (len > 256) { + OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW); + return 0; + } + OPENSSL_free(ssl->token_binding_params); + ssl->token_binding_params = (uint8_t *)BUF_memdup(params, len); + if (!ssl->token_binding_params) { + return 0; + } + ssl->token_binding_params_len = len; + return 1; +} + +int SSL_is_token_binding_negotiated(const SSL *ssl) { + return ssl->token_binding_negotiated; +} + +uint8_t SSL_get_negotiated_token_binding_param(const SSL *ssl) { + return ssl->negotiated_token_binding_param; +} + +size_t SSL_get0_certificate_types(SSL *ssl, const uint8_t **out_types) { + if (ssl->server || ssl->s3->hs == NULL) { + *out_types = NULL; + return 0; + } + *out_types = ssl->s3->hs->certificate_types.data(); + return ssl->s3->hs->certificate_types.size(); +} + +EVP_PKEY *SSL_get_privatekey(const SSL *ssl) { + if (ssl->cert != NULL) { + return ssl->cert->privatekey; + } + + return NULL; +} + +EVP_PKEY *SSL_CTX_get0_privatekey(const SSL_CTX *ctx) { + if (ctx->cert != NULL) { + return ctx->cert->privatekey; + } + + return NULL; +} + +const SSL_CIPHER *SSL_get_current_cipher(const SSL *ssl) { + return ssl->s3->aead_write_ctx->cipher(); +} + +int SSL_session_reused(const SSL *ssl) { + return ssl->s3->session_reused || SSL_in_early_data(ssl); +} + +const COMP_METHOD *SSL_get_current_compression(SSL *ssl) { return NULL; } + +const COMP_METHOD *SSL_get_current_expansion(SSL *ssl) { return NULL; } + +int *SSL_get_server_tmp_key(SSL *ssl, EVP_PKEY **out_key) { return 0; } + +void SSL_CTX_set_quiet_shutdown(SSL_CTX *ctx, int mode) { + ctx->quiet_shutdown = (mode != 0); +} + +int SSL_CTX_get_quiet_shutdown(const SSL_CTX *ctx) { + return ctx->quiet_shutdown; +} + +void SSL_set_quiet_shutdown(SSL *ssl, int mode) { + ssl->quiet_shutdown = (mode != 0); +} + +int SSL_get_quiet_shutdown(const SSL *ssl) { return ssl->quiet_shutdown; } + +void SSL_set_shutdown(SSL *ssl, int mode) { + // It is an error to clear any bits that have already been set. (We can't try + // to get a second close_notify or send two.) + assert((SSL_get_shutdown(ssl) & mode) == SSL_get_shutdown(ssl)); + + if (mode & SSL_RECEIVED_SHUTDOWN && + ssl->s3->read_shutdown == ssl_shutdown_none) { + ssl->s3->read_shutdown = ssl_shutdown_close_notify; + } + + if (mode & SSL_SENT_SHUTDOWN && + ssl->s3->write_shutdown == ssl_shutdown_none) { + ssl->s3->write_shutdown = ssl_shutdown_close_notify; + } +} + +int SSL_get_shutdown(const SSL *ssl) { + int ret = 0; + if (ssl->s3->read_shutdown != ssl_shutdown_none) { + // Historically, OpenSSL set |SSL_RECEIVED_SHUTDOWN| on both close_notify + // and fatal alert. + ret |= SSL_RECEIVED_SHUTDOWN; + } + if (ssl->s3->write_shutdown == ssl_shutdown_close_notify) { + // Historically, OpenSSL set |SSL_SENT_SHUTDOWN| on only close_notify. + ret |= SSL_SENT_SHUTDOWN; + } + return ret; +} + +SSL_CTX *SSL_get_SSL_CTX(const SSL *ssl) { return ssl->ctx; } + +SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX *ctx) { + if (ssl->ctx == ctx) { + return ssl->ctx; + } + + // One cannot change the X.509 callbacks during a connection. + if (ssl->ctx->x509_method != ctx->x509_method) { + assert(0); + return NULL; + } + + if (ctx == NULL) { + ctx = ssl->session_ctx; + } + + ssl_cert_free(ssl->cert); + ssl->cert = ssl_cert_dup(ctx->cert); + + SSL_CTX_up_ref(ctx); + SSL_CTX_free(ssl->ctx); + ssl->ctx = ctx; + + return ssl->ctx; +} + +void SSL_set_info_callback(SSL *ssl, + void (*cb)(const SSL *ssl, int type, int value)) { + ssl->info_callback = cb; +} + +void (*SSL_get_info_callback(const SSL *ssl))(const SSL *ssl, int type, + int value) { + return ssl->info_callback; +} + +int SSL_state(const SSL *ssl) { + return SSL_in_init(ssl) ? SSL_ST_INIT : SSL_ST_OK; +} + +void SSL_set_state(SSL *ssl, int state) { } + +char *SSL_get_shared_ciphers(const SSL *ssl, char *buf, int len) { + if (len <= 0) { + return NULL; + } + buf[0] = '\0'; + return buf; +} + +int SSL_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused *unused, + CRYPTO_EX_dup *dup_unused, CRYPTO_EX_free *free_func) { + int index; + if (!CRYPTO_get_ex_new_index(&g_ex_data_class_ssl, &index, argl, argp, + free_func)) { + return -1; + } + return index; +} + +int SSL_set_ex_data(SSL *ssl, int idx, void *data) { + return CRYPTO_set_ex_data(&ssl->ex_data, idx, data); +} + +void *SSL_get_ex_data(const SSL *ssl, int idx) { + return CRYPTO_get_ex_data(&ssl->ex_data, idx); +} + +int SSL_CTX_get_ex_new_index(long argl, void *argp, CRYPTO_EX_unused *unused, + CRYPTO_EX_dup *dup_unused, + CRYPTO_EX_free *free_func) { + int index; + if (!CRYPTO_get_ex_new_index(&g_ex_data_class_ssl_ctx, &index, argl, argp, + free_func)) { + return -1; + } + return index; +} + +int SSL_CTX_set_ex_data(SSL_CTX *ctx, int idx, void *data) { + return CRYPTO_set_ex_data(&ctx->ex_data, idx, data); +} + +void *SSL_CTX_get_ex_data(const SSL_CTX *ctx, int idx) { + return CRYPTO_get_ex_data(&ctx->ex_data, idx); +} + +int SSL_want(const SSL *ssl) { return ssl->s3->rwstate; } + +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)) {} + +void SSL_CTX_set_tmp_dh_callback(SSL_CTX *ctx, + DH *(*cb)(SSL *ssl, int is_export, + int keylength)) {} + +void SSL_set_tmp_dh_callback(SSL *ssl, DH *(*cb)(SSL *ssl, int is_export, + int keylength)) {} + +static int use_psk_identity_hint(char **out, const char *identity_hint) { + if (identity_hint != NULL && strlen(identity_hint) > PSK_MAX_IDENTITY_LEN) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DATA_LENGTH_TOO_LONG); + return 0; + } + + // Clear currently configured hint, if any. + OPENSSL_free(*out); + *out = NULL; + + // Treat the empty hint as not supplying one. Plain PSK makes it possible to + // send either no hint (omit ServerKeyExchange) or an empty hint, while + // ECDHE_PSK can only spell empty hint. Having different capabilities is odd, + // so we interpret empty and missing as identical. + if (identity_hint != NULL && identity_hint[0] != '\0') { + *out = BUF_strdup(identity_hint); + if (*out == NULL) { + return 0; + } + } + + return 1; +} + +int SSL_CTX_use_psk_identity_hint(SSL_CTX *ctx, const char *identity_hint) { + return use_psk_identity_hint(&ctx->psk_identity_hint, identity_hint); +} + +int SSL_use_psk_identity_hint(SSL *ssl, const char *identity_hint) { + return use_psk_identity_hint(&ssl->psk_identity_hint, identity_hint); +} + +const char *SSL_get_psk_identity_hint(const SSL *ssl) { + if (ssl == NULL) { + return NULL; + } + return ssl->psk_identity_hint; +} + +const char *SSL_get_psk_identity(const SSL *ssl) { + if (ssl == NULL) { + return NULL; + } + SSL_SESSION *session = SSL_get_session(ssl); + if (session == NULL) { + return NULL; + } + return session->psk_identity; +} + +void SSL_set_psk_client_callback( + SSL *ssl, unsigned (*cb)(SSL *ssl, const char *hint, char *identity, + unsigned max_identity_len, uint8_t *psk, + unsigned max_psk_len)) { + ssl->psk_client_callback = cb; +} + +void SSL_CTX_set_psk_client_callback( + SSL_CTX *ctx, unsigned (*cb)(SSL *ssl, const char *hint, char *identity, + unsigned max_identity_len, uint8_t *psk, + unsigned max_psk_len)) { + ctx->psk_client_callback = cb; +} + +void SSL_set_psk_server_callback( + SSL *ssl, unsigned (*cb)(SSL *ssl, const char *identity, uint8_t *psk, + unsigned max_psk_len)) { + ssl->psk_server_callback = cb; +} + +void SSL_CTX_set_psk_server_callback( + SSL_CTX *ctx, unsigned (*cb)(SSL *ssl, const char *identity, + uint8_t *psk, unsigned max_psk_len)) { + ctx->psk_server_callback = cb; +} + +int SSL_set_dummy_pq_padding_size(SSL *ssl, size_t num_bytes) { + if (num_bytes > 0xffff) { + return 0; + } + + ssl->dummy_pq_padding_len = num_bytes; + return 1; +} + +int SSL_dummy_pq_padding_used(SSL *ssl) { + if (ssl->server) { + return 0; + } + + return ssl->did_dummy_pq_padding; +} + +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)) { + ctx->msg_callback = cb; +} + +void SSL_CTX_set_msg_callback_arg(SSL_CTX *ctx, void *arg) { + ctx->msg_callback_arg = 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)) { + ssl->msg_callback = cb; +} + +void SSL_set_msg_callback_arg(SSL *ssl, void *arg) { + ssl->msg_callback_arg = arg; +} + +void SSL_CTX_set_keylog_callback(SSL_CTX *ctx, + void (*cb)(const SSL *ssl, const char *line)) { + ctx->keylog_callback = cb; +} + +void (*SSL_CTX_get_keylog_callback(const SSL_CTX *ctx))(const SSL *ssl, + const char *line) { + return ctx->keylog_callback; +} + +void SSL_CTX_set_current_time_cb(SSL_CTX *ctx, + void (*cb)(const SSL *ssl, + struct timeval *out_clock)) { + ctx->current_time_cb = cb; +} + +int SSL_is_init_finished(const SSL *ssl) { + return !SSL_in_init(ssl); +} + +int SSL_in_init(const SSL *ssl) { + // This returns false once all the handshake state has been finalized, to + // allow callbacks and getters based on SSL_in_init to return the correct + // values. + SSL_HANDSHAKE *hs = ssl->s3->hs.get(); + return hs != nullptr && !hs->handshake_finalized; +} + +int SSL_in_false_start(const SSL *ssl) { + if (ssl->s3->hs == NULL) { + return 0; + } + return ssl->s3->hs->in_false_start; +} + +int SSL_cutthrough_complete(const SSL *ssl) { + return SSL_in_false_start(ssl); +} + +void SSL_get_structure_sizes(size_t *ssl_size, size_t *ssl_ctx_size, + size_t *ssl_session_size) { + *ssl_size = sizeof(SSL); + *ssl_ctx_size = sizeof(SSL_CTX); + *ssl_session_size = sizeof(SSL_SESSION); +} + +int SSL_is_server(const SSL *ssl) { return ssl->server; } + +int SSL_is_dtls(const SSL *ssl) { return ssl->method->is_dtls; } + +void SSL_CTX_set_select_certificate_cb( + SSL_CTX *ctx, + enum ssl_select_cert_result_t (*cb)(const SSL_CLIENT_HELLO *)) { + ctx->select_certificate_cb = cb; +} + +void SSL_CTX_set_dos_protection_cb(SSL_CTX *ctx, + int (*cb)(const SSL_CLIENT_HELLO *)) { + ctx->dos_protection_cb = cb; +} + +void SSL_set_renegotiate_mode(SSL *ssl, enum ssl_renegotiate_mode_t mode) { + ssl->renegotiate_mode = mode; +} + +int SSL_get_ivs(const SSL *ssl, const uint8_t **out_read_iv, + const uint8_t **out_write_iv, size_t *out_iv_len) { + size_t write_iv_len; + if (!ssl->s3->aead_read_ctx->GetIV(out_read_iv, out_iv_len) || + !ssl->s3->aead_write_ctx->GetIV(out_write_iv, &write_iv_len) || + *out_iv_len != write_iv_len) { + return 0; + } + + return 1; +} + +static uint64_t be_to_u64(const uint8_t in[8]) { + return (((uint64_t)in[0]) << 56) | (((uint64_t)in[1]) << 48) | + (((uint64_t)in[2]) << 40) | (((uint64_t)in[3]) << 32) | + (((uint64_t)in[4]) << 24) | (((uint64_t)in[5]) << 16) | + (((uint64_t)in[6]) << 8) | ((uint64_t)in[7]); +} + +uint64_t SSL_get_read_sequence(const SSL *ssl) { + // TODO(davidben): Internally represent sequence numbers as uint64_t. + if (SSL_is_dtls(ssl)) { + // max_seq_num already includes the epoch. + assert(ssl->d1->r_epoch == (ssl->d1->bitmap.max_seq_num >> 48)); + return ssl->d1->bitmap.max_seq_num; + } + return be_to_u64(ssl->s3->read_sequence); +} + +uint64_t SSL_get_write_sequence(const SSL *ssl) { + uint64_t ret = be_to_u64(ssl->s3->write_sequence); + if (SSL_is_dtls(ssl)) { + assert((ret >> 48) == 0); + ret |= ((uint64_t)ssl->d1->w_epoch) << 48; + } + return ret; +} + +uint16_t SSL_get_peer_signature_algorithm(const SSL *ssl) { + // TODO(davidben): This checks the wrong session if there is a renegotiation + // in progress. + SSL_SESSION *session = SSL_get_session(ssl); + if (session == NULL) { + return 0; + } + + return session->peer_signature_algorithm; +} + +size_t SSL_get_client_random(const SSL *ssl, uint8_t *out, size_t max_out) { + if (max_out == 0) { + return sizeof(ssl->s3->client_random); + } + if (max_out > sizeof(ssl->s3->client_random)) { + max_out = sizeof(ssl->s3->client_random); + } + OPENSSL_memcpy(out, ssl->s3->client_random, max_out); + return max_out; +} + +size_t SSL_get_server_random(const SSL *ssl, uint8_t *out, size_t max_out) { + if (max_out == 0) { + return sizeof(ssl->s3->server_random); + } + if (max_out > sizeof(ssl->s3->server_random)) { + max_out = sizeof(ssl->s3->server_random); + } + OPENSSL_memcpy(out, ssl->s3->server_random, max_out); + return max_out; +} + +const SSL_CIPHER *SSL_get_pending_cipher(const SSL *ssl) { + SSL_HANDSHAKE *hs = ssl->s3->hs.get(); + if (hs == NULL) { + return NULL; + } + return hs->new_cipher; +} + +void SSL_set_retain_only_sha256_of_client_certs(SSL *ssl, int enabled) { + ssl->retain_only_sha256_of_client_certs = !!enabled; +} + +void SSL_CTX_set_retain_only_sha256_of_client_certs(SSL_CTX *ctx, int enabled) { + ctx->retain_only_sha256_of_client_certs = !!enabled; +} + +void SSL_CTX_set_grease_enabled(SSL_CTX *ctx, int enabled) { + ctx->grease_enabled = !!enabled; +} + +int32_t SSL_get_ticket_age_skew(const SSL *ssl) { + return ssl->s3->ticket_age_skew; +} + +void SSL_CTX_set_false_start_allowed_without_alpn(SSL_CTX *ctx, int allowed) { + ctx->false_start_allowed_without_alpn = !!allowed; +} + +int SSL_is_draft_downgrade(const SSL *ssl) { return ssl->s3->draft_downgrade; } + +int SSL_clear(SSL *ssl) { + // In OpenSSL, reusing a client |SSL| with |SSL_clear| causes the previously + // established session to be offered the next time around. wpa_supplicant + // depends on this behavior, so emulate it. + UniquePtr session; + if (!ssl->server && ssl->s3->established_session != NULL) { + session.reset(ssl->s3->established_session.get()); + SSL_SESSION_up_ref(session.get()); + } + + // The ssl->d1->mtu is simultaneously configuration (preserved across + // clear) and connection-specific state (gets reset). + // + // TODO(davidben): Avoid this. + unsigned mtu = 0; + if (ssl->d1 != NULL) { + mtu = ssl->d1->mtu; + } + + ssl->method->ssl_free(ssl); + if (!ssl->method->ssl_new(ssl)) { + return 0; + } + + if (SSL_is_dtls(ssl) && (SSL_get_options(ssl) & SSL_OP_NO_QUERY_MTU)) { + ssl->d1->mtu = mtu; + } + + if (session != nullptr) { + SSL_set_session(ssl, session.get()); + } + + return 1; +} + +int SSL_CTX_sess_connect(const SSL_CTX *ctx) { return 0; } +int SSL_CTX_sess_connect_good(const SSL_CTX *ctx) { return 0; } +int SSL_CTX_sess_connect_renegotiate(const SSL_CTX *ctx) { return 0; } +int SSL_CTX_sess_accept(const SSL_CTX *ctx) { return 0; } +int SSL_CTX_sess_accept_renegotiate(const SSL_CTX *ctx) { return 0; } +int SSL_CTX_sess_accept_good(const SSL_CTX *ctx) { return 0; } +int SSL_CTX_sess_hits(const SSL_CTX *ctx) { return 0; } +int SSL_CTX_sess_cb_hits(const SSL_CTX *ctx) { return 0; } +int SSL_CTX_sess_misses(const SSL_CTX *ctx) { return 0; } +int SSL_CTX_sess_timeouts(const SSL_CTX *ctx) { return 0; } +int SSL_CTX_sess_cache_full(const SSL_CTX *ctx) { return 0; } + +int SSL_num_renegotiations(const SSL *ssl) { + return SSL_total_renegotiations(ssl); +} + +int SSL_CTX_need_tmp_RSA(const SSL_CTX *ctx) { return 0; } +int SSL_need_tmp_RSA(const SSL *ssl) { return 0; } +int SSL_CTX_set_tmp_rsa(SSL_CTX *ctx, const RSA *rsa) { return 1; } +int SSL_set_tmp_rsa(SSL *ssl, const RSA *rsa) { return 1; } +void ERR_load_SSL_strings(void) {} +void SSL_load_error_strings(void) {} +int SSL_cache_hit(SSL *ssl) { return SSL_session_reused(ssl); } + +int SSL_CTX_set_tmp_ecdh(SSL_CTX *ctx, const EC_KEY *ec_key) { + if (ec_key == NULL || EC_KEY_get0_group(ec_key) == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + int nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec_key)); + return SSL_CTX_set1_curves(ctx, &nid, 1); +} + +int SSL_set_tmp_ecdh(SSL *ssl, const EC_KEY *ec_key) { + if (ec_key == NULL || EC_KEY_get0_group(ec_key) == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + int nid = EC_GROUP_get_curve_name(EC_KEY_get0_group(ec_key)); + return SSL_set1_curves(ssl, &nid, 1); +} + +void SSL_CTX_set_ticket_aead_method(SSL_CTX *ctx, + const SSL_TICKET_AEAD_METHOD *aead_method) { + ctx->ticket_aead_method = aead_method; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/ssl/ssl_privkey.cc b/FoodApp/Pods/BoringSSL-GRPC/ssl/ssl_privkey.cc new file mode 100644 index 0000000..a5de161 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/ssl/ssl_privkey.cc @@ -0,0 +1,494 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 +#include +#include +#include + +#include "internal.h" +#include "../crypto/internal.h" + + +namespace bssl { + +int ssl_is_key_type_supported(int key_type) { + return key_type == EVP_PKEY_RSA || key_type == EVP_PKEY_EC || + key_type == EVP_PKEY_ED25519; +} + +static int ssl_set_pkey(CERT *cert, EVP_PKEY *pkey) { + if (!ssl_is_key_type_supported(pkey->type)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_CERTIFICATE_TYPE); + return 0; + } + + if (cert->chain != NULL && + sk_CRYPTO_BUFFER_value(cert->chain, 0) != NULL && + // Sanity-check that the private key and the certificate match. + !ssl_cert_check_private_key(cert, pkey)) { + return 0; + } + + EVP_PKEY_free(cert->privatekey); + EVP_PKEY_up_ref(pkey); + cert->privatekey = pkey; + + return 1; +} + +typedef struct { + uint16_t sigalg; + int pkey_type; + int curve; + const EVP_MD *(*digest_func)(void); + char is_rsa_pss; +} SSL_SIGNATURE_ALGORITHM; + +static const SSL_SIGNATURE_ALGORITHM kSignatureAlgorithms[] = { + {SSL_SIGN_RSA_PKCS1_MD5_SHA1, EVP_PKEY_RSA, NID_undef, &EVP_md5_sha1, 0}, + {SSL_SIGN_RSA_PKCS1_SHA1, EVP_PKEY_RSA, NID_undef, &EVP_sha1, 0}, + {SSL_SIGN_RSA_PKCS1_SHA256, EVP_PKEY_RSA, NID_undef, &EVP_sha256, 0}, + {SSL_SIGN_RSA_PKCS1_SHA384, EVP_PKEY_RSA, NID_undef, &EVP_sha384, 0}, + {SSL_SIGN_RSA_PKCS1_SHA512, EVP_PKEY_RSA, NID_undef, &EVP_sha512, 0}, + + {SSL_SIGN_RSA_PSS_SHA256, EVP_PKEY_RSA, NID_undef, &EVP_sha256, 1}, + {SSL_SIGN_RSA_PSS_SHA384, EVP_PKEY_RSA, NID_undef, &EVP_sha384, 1}, + {SSL_SIGN_RSA_PSS_SHA512, EVP_PKEY_RSA, NID_undef, &EVP_sha512, 1}, + + {SSL_SIGN_ECDSA_SHA1, EVP_PKEY_EC, NID_undef, &EVP_sha1, 0}, + {SSL_SIGN_ECDSA_SECP256R1_SHA256, EVP_PKEY_EC, NID_X9_62_prime256v1, + &EVP_sha256, 0}, + {SSL_SIGN_ECDSA_SECP384R1_SHA384, EVP_PKEY_EC, NID_secp384r1, &EVP_sha384, + 0}, + {SSL_SIGN_ECDSA_SECP521R1_SHA512, EVP_PKEY_EC, NID_secp521r1, &EVP_sha512, + 0}, + + {SSL_SIGN_ED25519, EVP_PKEY_ED25519, NID_undef, NULL, 0}, +}; + +static const SSL_SIGNATURE_ALGORITHM *get_signature_algorithm(uint16_t sigalg) { + for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kSignatureAlgorithms); i++) { + if (kSignatureAlgorithms[i].sigalg == sigalg) { + return &kSignatureAlgorithms[i]; + } + } + return NULL; +} + +int ssl_has_private_key(const SSL *ssl) { + return ssl->cert->privatekey != NULL || ssl->cert->key_method != NULL; +} + +static int pkey_supports_algorithm(const SSL *ssl, EVP_PKEY *pkey, + uint16_t sigalg) { + const SSL_SIGNATURE_ALGORITHM *alg = get_signature_algorithm(sigalg); + if (alg == NULL || + EVP_PKEY_id(pkey) != alg->pkey_type) { + return 0; + } + + if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) { + // RSA keys may only be used with RSA-PSS. + if (alg->pkey_type == EVP_PKEY_RSA && !alg->is_rsa_pss) { + return 0; + } + + // EC keys have a curve requirement. + if (alg->pkey_type == EVP_PKEY_EC && + (alg->curve == NID_undef || + EC_GROUP_get_curve_name( + EC_KEY_get0_group(EVP_PKEY_get0_EC_KEY(pkey))) != alg->curve)) { + return 0; + } + } + + return 1; +} + +static int setup_ctx(SSL *ssl, EVP_MD_CTX *ctx, EVP_PKEY *pkey, uint16_t sigalg, + int is_verify) { + if (!pkey_supports_algorithm(ssl, pkey, sigalg)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_SIGNATURE_TYPE); + return 0; + } + + const SSL_SIGNATURE_ALGORITHM *alg = get_signature_algorithm(sigalg); + const EVP_MD *digest = alg->digest_func != NULL ? alg->digest_func() : NULL; + EVP_PKEY_CTX *pctx; + if (is_verify) { + if (!EVP_DigestVerifyInit(ctx, &pctx, digest, NULL, pkey)) { + return 0; + } + } else if (!EVP_DigestSignInit(ctx, &pctx, digest, NULL, pkey)) { + return 0; + } + + if (alg->is_rsa_pss) { + if (!EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PSS_PADDING) || + !EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, -1 /* salt len = hash len */)) { + return 0; + } + } + + return 1; +} + +enum ssl_private_key_result_t ssl_private_key_sign( + SSL_HANDSHAKE *hs, uint8_t *out, size_t *out_len, size_t max_out, + uint16_t sigalg, Span in) { + SSL *const ssl = hs->ssl; + if (ssl->cert->key_method != NULL) { + enum ssl_private_key_result_t ret; + if (hs->pending_private_key_op) { + ret = ssl->cert->key_method->complete(ssl, out, out_len, max_out); + } else { + ret = ssl->cert->key_method->sign(ssl, out, out_len, max_out, sigalg, + in.data(), in.size()); + } + if (ret == ssl_private_key_failure) { + OPENSSL_PUT_ERROR(SSL, SSL_R_PRIVATE_KEY_OPERATION_FAILED); + } + hs->pending_private_key_op = ret == ssl_private_key_retry; + return ret; + } + + *out_len = max_out; + ScopedEVP_MD_CTX ctx; + if (!setup_ctx(ssl, ctx.get(), ssl->cert->privatekey, sigalg, 0 /* sign */) || + !EVP_DigestSign(ctx.get(), out, out_len, in.data(), in.size())) { + return ssl_private_key_failure; + } + return ssl_private_key_success; +} + +bool ssl_public_key_verify(SSL *ssl, Span signature, + uint16_t sigalg, EVP_PKEY *pkey, + Span in) { + ScopedEVP_MD_CTX ctx; + return setup_ctx(ssl, ctx.get(), pkey, sigalg, 1 /* verify */) && + EVP_DigestVerify(ctx.get(), signature.data(), signature.size(), + in.data(), in.size()); +} + +enum ssl_private_key_result_t ssl_private_key_decrypt(SSL_HANDSHAKE *hs, + uint8_t *out, + size_t *out_len, + size_t max_out, + Span in) { + SSL *const ssl = hs->ssl; + if (ssl->cert->key_method != NULL) { + enum ssl_private_key_result_t ret; + if (hs->pending_private_key_op) { + ret = ssl->cert->key_method->complete(ssl, out, out_len, max_out); + } else { + ret = ssl->cert->key_method->decrypt(ssl, out, out_len, max_out, + in.data(), in.size()); + } + if (ret == ssl_private_key_failure) { + OPENSSL_PUT_ERROR(SSL, SSL_R_PRIVATE_KEY_OPERATION_FAILED); + } + hs->pending_private_key_op = ret == ssl_private_key_retry; + return ret; + } + + RSA *rsa = EVP_PKEY_get0_RSA(ssl->cert->privatekey); + if (rsa == NULL) { + // Decrypt operations are only supported for RSA keys. + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return ssl_private_key_failure; + } + + // Decrypt with no padding. PKCS#1 padding will be removed as part of the + // timing-sensitive code by the caller. + if (!RSA_decrypt(rsa, out_len, out, max_out, in.data(), in.size(), + RSA_NO_PADDING)) { + return ssl_private_key_failure; + } + return ssl_private_key_success; +} + +bool ssl_private_key_supports_signature_algorithm(SSL_HANDSHAKE *hs, + uint16_t sigalg) { + SSL *const ssl = hs->ssl; + if (!pkey_supports_algorithm(ssl, hs->local_pubkey.get(), sigalg)) { + return false; + } + + // Ensure the RSA key is large enough for the hash. RSASSA-PSS requires that + // emLen be at least hLen + sLen + 2. Both hLen and sLen are the size of the + // hash in TLS. Reasonable RSA key sizes are large enough for the largest + // defined RSASSA-PSS algorithm, but 1024-bit RSA is slightly too small for + // SHA-512. 1024-bit RSA is sometimes used for test credentials, so check the + // size so that we can fall back to another algorithm in that case. + const SSL_SIGNATURE_ALGORITHM *alg = get_signature_algorithm(sigalg); + if (alg->is_rsa_pss && (size_t)EVP_PKEY_size(hs->local_pubkey.get()) < + 2 * EVP_MD_size(alg->digest_func()) + 2) { + return false; + } + + return true; +} + +} // namespace bssl + +using namespace bssl; + +int SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa) { + if (rsa == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + UniquePtr pkey(EVP_PKEY_new()); + if (!pkey || + !EVP_PKEY_set1_RSA(pkey.get(), rsa)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_EVP_LIB); + return 0; + } + + return ssl_set_pkey(ssl->cert, pkey.get()); +} + +int SSL_use_RSAPrivateKey_ASN1(SSL *ssl, const uint8_t *der, size_t der_len) { + UniquePtr rsa(RSA_private_key_from_bytes(der, der_len)); + if (!rsa) { + OPENSSL_PUT_ERROR(SSL, ERR_R_ASN1_LIB); + return 0; + } + + return SSL_use_RSAPrivateKey(ssl, rsa.get()); +} + +int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey) { + if (pkey == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + return ssl_set_pkey(ssl->cert, pkey); +} + +int SSL_use_PrivateKey_ASN1(int type, SSL *ssl, const uint8_t *der, + size_t der_len) { + if (der_len > LONG_MAX) { + OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW); + return 0; + } + + const uint8_t *p = der; + UniquePtr pkey(d2i_PrivateKey(type, NULL, &p, (long)der_len)); + if (!pkey || p != der + der_len) { + OPENSSL_PUT_ERROR(SSL, ERR_R_ASN1_LIB); + return 0; + } + + return SSL_use_PrivateKey(ssl, pkey.get()); +} + +int SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa) { + if (rsa == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + UniquePtr pkey(EVP_PKEY_new()); + if (!pkey || + !EVP_PKEY_set1_RSA(pkey.get(), rsa)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_EVP_LIB); + return 0; + } + + return ssl_set_pkey(ctx->cert, pkey.get()); +} + +int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const uint8_t *der, + size_t der_len) { + UniquePtr rsa(RSA_private_key_from_bytes(der, der_len)); + if (!rsa) { + OPENSSL_PUT_ERROR(SSL, ERR_R_ASN1_LIB); + return 0; + } + + return SSL_CTX_use_RSAPrivateKey(ctx, rsa.get()); +} + +int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey) { + if (pkey == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + return ssl_set_pkey(ctx->cert, pkey); +} + +int SSL_CTX_use_PrivateKey_ASN1(int type, SSL_CTX *ctx, const uint8_t *der, + size_t der_len) { + if (der_len > LONG_MAX) { + OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW); + return 0; + } + + const uint8_t *p = der; + UniquePtr pkey(d2i_PrivateKey(type, NULL, &p, (long)der_len)); + if (!pkey || p != der + der_len) { + OPENSSL_PUT_ERROR(SSL, ERR_R_ASN1_LIB); + return 0; + } + + return SSL_CTX_use_PrivateKey(ctx, pkey.get()); +} + +void SSL_set_private_key_method(SSL *ssl, + const SSL_PRIVATE_KEY_METHOD *key_method) { + ssl->cert->key_method = key_method; +} + +void SSL_CTX_set_private_key_method(SSL_CTX *ctx, + const SSL_PRIVATE_KEY_METHOD *key_method) { + ctx->cert->key_method = key_method; +} + +const char *SSL_get_signature_algorithm_name(uint16_t sigalg, + int include_curve) { + switch (sigalg) { + case SSL_SIGN_RSA_PKCS1_MD5_SHA1: + return "rsa_pkcs1_md5_sha1"; + case SSL_SIGN_RSA_PKCS1_SHA1: + return "rsa_pkcs1_sha1"; + case SSL_SIGN_RSA_PKCS1_SHA256: + return "rsa_pkcs1_sha256"; + case SSL_SIGN_RSA_PKCS1_SHA384: + return "rsa_pkcs1_sha384"; + case SSL_SIGN_RSA_PKCS1_SHA512: + return "rsa_pkcs1_sha512"; + case SSL_SIGN_ECDSA_SHA1: + return "ecdsa_sha1"; + case SSL_SIGN_ECDSA_SECP256R1_SHA256: + return include_curve ? "ecdsa_secp256r1_sha256" : "ecdsa_sha256"; + case SSL_SIGN_ECDSA_SECP384R1_SHA384: + return include_curve ? "ecdsa_secp384r1_sha384" : "ecdsa_sha384"; + case SSL_SIGN_ECDSA_SECP521R1_SHA512: + return include_curve ? "ecdsa_secp521r1_sha512" : "ecdsa_sha512"; + case SSL_SIGN_RSA_PSS_SHA256: + return "rsa_pss_sha256"; + case SSL_SIGN_RSA_PSS_SHA384: + return "rsa_pss_sha384"; + case SSL_SIGN_RSA_PSS_SHA512: + return "rsa_pss_sha512"; + case SSL_SIGN_ED25519: + return "ed25519"; + default: + return NULL; + } +} + +int SSL_get_signature_algorithm_key_type(uint16_t sigalg) { + const SSL_SIGNATURE_ALGORITHM *alg = get_signature_algorithm(sigalg); + return alg != nullptr ? alg->pkey_type : EVP_PKEY_NONE; +} + +const EVP_MD *SSL_get_signature_algorithm_digest(uint16_t sigalg) { + const SSL_SIGNATURE_ALGORITHM *alg = get_signature_algorithm(sigalg); + if (alg == nullptr || alg->digest_func == nullptr) { + return nullptr; + } + return alg->digest_func(); +} + +int SSL_is_signature_algorithm_rsa_pss(uint16_t sigalg) { + const SSL_SIGNATURE_ALGORITHM *alg = get_signature_algorithm(sigalg); + return alg != nullptr && alg->is_rsa_pss; +} + +static int set_algorithm_prefs(uint16_t **out_prefs, size_t *out_num_prefs, + const uint16_t *prefs, size_t num_prefs) { + OPENSSL_free(*out_prefs); + + *out_num_prefs = 0; + *out_prefs = (uint16_t *)BUF_memdup(prefs, num_prefs * sizeof(prefs[0])); + if (*out_prefs == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + *out_num_prefs = num_prefs; + + return 1; +} + +int SSL_CTX_set_signing_algorithm_prefs(SSL_CTX *ctx, const uint16_t *prefs, + size_t num_prefs) { + return set_algorithm_prefs(&ctx->cert->sigalgs, &ctx->cert->num_sigalgs, + prefs, num_prefs); +} + +int SSL_set_signing_algorithm_prefs(SSL *ssl, const uint16_t *prefs, + size_t num_prefs) { + return set_algorithm_prefs(&ssl->cert->sigalgs, &ssl->cert->num_sigalgs, + prefs, num_prefs); +} + +int SSL_CTX_set_verify_algorithm_prefs(SSL_CTX *ctx, const uint16_t *prefs, + size_t num_prefs) { + return set_algorithm_prefs(&ctx->verify_sigalgs, &ctx->num_verify_sigalgs, + prefs, num_prefs); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/ssl/ssl_privkey.cc.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/ssl/ssl_privkey.cc.grpc_back new file mode 100644 index 0000000..33cc720 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/ssl/ssl_privkey.cc.grpc_back @@ -0,0 +1,494 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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 +#include +#include +#include + +#include "internal.h" +#include "../crypto/internal.h" + + +namespace bssl { + +int ssl_is_key_type_supported(int key_type) { + return key_type == EVP_PKEY_RSA || key_type == EVP_PKEY_EC || + key_type == EVP_PKEY_ED25519; +} + +static int ssl_set_pkey(CERT *cert, EVP_PKEY *pkey) { + if (!ssl_is_key_type_supported(pkey->type)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_CERTIFICATE_TYPE); + return 0; + } + + if (cert->chain != NULL && + sk_CRYPTO_BUFFER_value(cert->chain, 0) != NULL && + // Sanity-check that the private key and the certificate match. + !ssl_cert_check_private_key(cert, pkey)) { + return 0; + } + + EVP_PKEY_free(cert->privatekey); + EVP_PKEY_up_ref(pkey); + cert->privatekey = pkey; + + return 1; +} + +typedef struct { + uint16_t sigalg; + int pkey_type; + int curve; + const EVP_MD *(*digest_func)(void); + char is_rsa_pss; +} SSL_SIGNATURE_ALGORITHM; + +static const SSL_SIGNATURE_ALGORITHM kSignatureAlgorithms[] = { + {SSL_SIGN_RSA_PKCS1_MD5_SHA1, EVP_PKEY_RSA, NID_undef, &EVP_md5_sha1, 0}, + {SSL_SIGN_RSA_PKCS1_SHA1, EVP_PKEY_RSA, NID_undef, &EVP_sha1, 0}, + {SSL_SIGN_RSA_PKCS1_SHA256, EVP_PKEY_RSA, NID_undef, &EVP_sha256, 0}, + {SSL_SIGN_RSA_PKCS1_SHA384, EVP_PKEY_RSA, NID_undef, &EVP_sha384, 0}, + {SSL_SIGN_RSA_PKCS1_SHA512, EVP_PKEY_RSA, NID_undef, &EVP_sha512, 0}, + + {SSL_SIGN_RSA_PSS_SHA256, EVP_PKEY_RSA, NID_undef, &EVP_sha256, 1}, + {SSL_SIGN_RSA_PSS_SHA384, EVP_PKEY_RSA, NID_undef, &EVP_sha384, 1}, + {SSL_SIGN_RSA_PSS_SHA512, EVP_PKEY_RSA, NID_undef, &EVP_sha512, 1}, + + {SSL_SIGN_ECDSA_SHA1, EVP_PKEY_EC, NID_undef, &EVP_sha1, 0}, + {SSL_SIGN_ECDSA_SECP256R1_SHA256, EVP_PKEY_EC, NID_X9_62_prime256v1, + &EVP_sha256, 0}, + {SSL_SIGN_ECDSA_SECP384R1_SHA384, EVP_PKEY_EC, NID_secp384r1, &EVP_sha384, + 0}, + {SSL_SIGN_ECDSA_SECP521R1_SHA512, EVP_PKEY_EC, NID_secp521r1, &EVP_sha512, + 0}, + + {SSL_SIGN_ED25519, EVP_PKEY_ED25519, NID_undef, NULL, 0}, +}; + +static const SSL_SIGNATURE_ALGORITHM *get_signature_algorithm(uint16_t sigalg) { + for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kSignatureAlgorithms); i++) { + if (kSignatureAlgorithms[i].sigalg == sigalg) { + return &kSignatureAlgorithms[i]; + } + } + return NULL; +} + +int ssl_has_private_key(const SSL *ssl) { + return ssl->cert->privatekey != NULL || ssl->cert->key_method != NULL; +} + +static int pkey_supports_algorithm(const SSL *ssl, EVP_PKEY *pkey, + uint16_t sigalg) { + const SSL_SIGNATURE_ALGORITHM *alg = get_signature_algorithm(sigalg); + if (alg == NULL || + EVP_PKEY_id(pkey) != alg->pkey_type) { + return 0; + } + + if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) { + // RSA keys may only be used with RSA-PSS. + if (alg->pkey_type == EVP_PKEY_RSA && !alg->is_rsa_pss) { + return 0; + } + + // EC keys have a curve requirement. + if (alg->pkey_type == EVP_PKEY_EC && + (alg->curve == NID_undef || + EC_GROUP_get_curve_name( + EC_KEY_get0_group(EVP_PKEY_get0_EC_KEY(pkey))) != alg->curve)) { + return 0; + } + } + + return 1; +} + +static int setup_ctx(SSL *ssl, EVP_MD_CTX *ctx, EVP_PKEY *pkey, uint16_t sigalg, + int is_verify) { + if (!pkey_supports_algorithm(ssl, pkey, sigalg)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_SIGNATURE_TYPE); + return 0; + } + + const SSL_SIGNATURE_ALGORITHM *alg = get_signature_algorithm(sigalg); + const EVP_MD *digest = alg->digest_func != NULL ? alg->digest_func() : NULL; + EVP_PKEY_CTX *pctx; + if (is_verify) { + if (!EVP_DigestVerifyInit(ctx, &pctx, digest, NULL, pkey)) { + return 0; + } + } else if (!EVP_DigestSignInit(ctx, &pctx, digest, NULL, pkey)) { + return 0; + } + + if (alg->is_rsa_pss) { + if (!EVP_PKEY_CTX_set_rsa_padding(pctx, RSA_PKCS1_PSS_PADDING) || + !EVP_PKEY_CTX_set_rsa_pss_saltlen(pctx, -1 /* salt len = hash len */)) { + return 0; + } + } + + return 1; +} + +enum ssl_private_key_result_t ssl_private_key_sign( + SSL_HANDSHAKE *hs, uint8_t *out, size_t *out_len, size_t max_out, + uint16_t sigalg, Span in) { + SSL *const ssl = hs->ssl; + if (ssl->cert->key_method != NULL) { + enum ssl_private_key_result_t ret; + if (hs->pending_private_key_op) { + ret = ssl->cert->key_method->complete(ssl, out, out_len, max_out); + } else { + ret = ssl->cert->key_method->sign(ssl, out, out_len, max_out, sigalg, + in.data(), in.size()); + } + if (ret == ssl_private_key_failure) { + OPENSSL_PUT_ERROR(SSL, SSL_R_PRIVATE_KEY_OPERATION_FAILED); + } + hs->pending_private_key_op = ret == ssl_private_key_retry; + return ret; + } + + *out_len = max_out; + ScopedEVP_MD_CTX ctx; + if (!setup_ctx(ssl, ctx.get(), ssl->cert->privatekey, sigalg, 0 /* sign */) || + !EVP_DigestSign(ctx.get(), out, out_len, in.data(), in.size())) { + return ssl_private_key_failure; + } + return ssl_private_key_success; +} + +bool ssl_public_key_verify(SSL *ssl, Span signature, + uint16_t sigalg, EVP_PKEY *pkey, + Span in) { + ScopedEVP_MD_CTX ctx; + return setup_ctx(ssl, ctx.get(), pkey, sigalg, 1 /* verify */) && + EVP_DigestVerify(ctx.get(), signature.data(), signature.size(), + in.data(), in.size()); +} + +enum ssl_private_key_result_t ssl_private_key_decrypt(SSL_HANDSHAKE *hs, + uint8_t *out, + size_t *out_len, + size_t max_out, + Span in) { + SSL *const ssl = hs->ssl; + if (ssl->cert->key_method != NULL) { + enum ssl_private_key_result_t ret; + if (hs->pending_private_key_op) { + ret = ssl->cert->key_method->complete(ssl, out, out_len, max_out); + } else { + ret = ssl->cert->key_method->decrypt(ssl, out, out_len, max_out, + in.data(), in.size()); + } + if (ret == ssl_private_key_failure) { + OPENSSL_PUT_ERROR(SSL, SSL_R_PRIVATE_KEY_OPERATION_FAILED); + } + hs->pending_private_key_op = ret == ssl_private_key_retry; + return ret; + } + + RSA *rsa = EVP_PKEY_get0_RSA(ssl->cert->privatekey); + if (rsa == NULL) { + // Decrypt operations are only supported for RSA keys. + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return ssl_private_key_failure; + } + + // Decrypt with no padding. PKCS#1 padding will be removed as part of the + // timing-sensitive code by the caller. + if (!RSA_decrypt(rsa, out_len, out, max_out, in.data(), in.size(), + RSA_NO_PADDING)) { + return ssl_private_key_failure; + } + return ssl_private_key_success; +} + +bool ssl_private_key_supports_signature_algorithm(SSL_HANDSHAKE *hs, + uint16_t sigalg) { + SSL *const ssl = hs->ssl; + if (!pkey_supports_algorithm(ssl, hs->local_pubkey.get(), sigalg)) { + return false; + } + + // Ensure the RSA key is large enough for the hash. RSASSA-PSS requires that + // emLen be at least hLen + sLen + 2. Both hLen and sLen are the size of the + // hash in TLS. Reasonable RSA key sizes are large enough for the largest + // defined RSASSA-PSS algorithm, but 1024-bit RSA is slightly too small for + // SHA-512. 1024-bit RSA is sometimes used for test credentials, so check the + // size so that we can fall back to another algorithm in that case. + const SSL_SIGNATURE_ALGORITHM *alg = get_signature_algorithm(sigalg); + if (alg->is_rsa_pss && (size_t)EVP_PKEY_size(hs->local_pubkey.get()) < + 2 * EVP_MD_size(alg->digest_func()) + 2) { + return false; + } + + return true; +} + +} // namespace bssl + +using namespace bssl; + +int SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa) { + if (rsa == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + UniquePtr pkey(EVP_PKEY_new()); + if (!pkey || + !EVP_PKEY_set1_RSA(pkey.get(), rsa)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_EVP_LIB); + return 0; + } + + return ssl_set_pkey(ssl->cert, pkey.get()); +} + +int SSL_use_RSAPrivateKey_ASN1(SSL *ssl, const uint8_t *der, size_t der_len) { + UniquePtr rsa(RSA_private_key_from_bytes(der, der_len)); + if (!rsa) { + OPENSSL_PUT_ERROR(SSL, ERR_R_ASN1_LIB); + return 0; + } + + return SSL_use_RSAPrivateKey(ssl, rsa.get()); +} + +int SSL_use_PrivateKey(SSL *ssl, EVP_PKEY *pkey) { + if (pkey == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + return ssl_set_pkey(ssl->cert, pkey); +} + +int SSL_use_PrivateKey_ASN1(int type, SSL *ssl, const uint8_t *der, + size_t der_len) { + if (der_len > LONG_MAX) { + OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW); + return 0; + } + + const uint8_t *p = der; + UniquePtr pkey(d2i_PrivateKey(type, NULL, &p, (long)der_len)); + if (!pkey || p != der + der_len) { + OPENSSL_PUT_ERROR(SSL, ERR_R_ASN1_LIB); + return 0; + } + + return SSL_use_PrivateKey(ssl, pkey.get()); +} + +int SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa) { + if (rsa == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + UniquePtr pkey(EVP_PKEY_new()); + if (!pkey || + !EVP_PKEY_set1_RSA(pkey.get(), rsa)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_EVP_LIB); + return 0; + } + + return ssl_set_pkey(ctx->cert, pkey.get()); +} + +int SSL_CTX_use_RSAPrivateKey_ASN1(SSL_CTX *ctx, const uint8_t *der, + size_t der_len) { + UniquePtr rsa(RSA_private_key_from_bytes(der, der_len)); + if (!rsa) { + OPENSSL_PUT_ERROR(SSL, ERR_R_ASN1_LIB); + return 0; + } + + return SSL_CTX_use_RSAPrivateKey(ctx, rsa.get()); +} + +int SSL_CTX_use_PrivateKey(SSL_CTX *ctx, EVP_PKEY *pkey) { + if (pkey == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + return ssl_set_pkey(ctx->cert, pkey); +} + +int SSL_CTX_use_PrivateKey_ASN1(int type, SSL_CTX *ctx, const uint8_t *der, + size_t der_len) { + if (der_len > LONG_MAX) { + OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW); + return 0; + } + + const uint8_t *p = der; + UniquePtr pkey(d2i_PrivateKey(type, NULL, &p, (long)der_len)); + if (!pkey || p != der + der_len) { + OPENSSL_PUT_ERROR(SSL, ERR_R_ASN1_LIB); + return 0; + } + + return SSL_CTX_use_PrivateKey(ctx, pkey.get()); +} + +void SSL_set_private_key_method(SSL *ssl, + const SSL_PRIVATE_KEY_METHOD *key_method) { + ssl->cert->key_method = key_method; +} + +void SSL_CTX_set_private_key_method(SSL_CTX *ctx, + const SSL_PRIVATE_KEY_METHOD *key_method) { + ctx->cert->key_method = key_method; +} + +const char *SSL_get_signature_algorithm_name(uint16_t sigalg, + int include_curve) { + switch (sigalg) { + case SSL_SIGN_RSA_PKCS1_MD5_SHA1: + return "rsa_pkcs1_md5_sha1"; + case SSL_SIGN_RSA_PKCS1_SHA1: + return "rsa_pkcs1_sha1"; + case SSL_SIGN_RSA_PKCS1_SHA256: + return "rsa_pkcs1_sha256"; + case SSL_SIGN_RSA_PKCS1_SHA384: + return "rsa_pkcs1_sha384"; + case SSL_SIGN_RSA_PKCS1_SHA512: + return "rsa_pkcs1_sha512"; + case SSL_SIGN_ECDSA_SHA1: + return "ecdsa_sha1"; + case SSL_SIGN_ECDSA_SECP256R1_SHA256: + return include_curve ? "ecdsa_secp256r1_sha256" : "ecdsa_sha256"; + case SSL_SIGN_ECDSA_SECP384R1_SHA384: + return include_curve ? "ecdsa_secp384r1_sha384" : "ecdsa_sha384"; + case SSL_SIGN_ECDSA_SECP521R1_SHA512: + return include_curve ? "ecdsa_secp521r1_sha512" : "ecdsa_sha512"; + case SSL_SIGN_RSA_PSS_SHA256: + return "rsa_pss_sha256"; + case SSL_SIGN_RSA_PSS_SHA384: + return "rsa_pss_sha384"; + case SSL_SIGN_RSA_PSS_SHA512: + return "rsa_pss_sha512"; + case SSL_SIGN_ED25519: + return "ed25519"; + default: + return NULL; + } +} + +int SSL_get_signature_algorithm_key_type(uint16_t sigalg) { + const SSL_SIGNATURE_ALGORITHM *alg = get_signature_algorithm(sigalg); + return alg != nullptr ? alg->pkey_type : EVP_PKEY_NONE; +} + +const EVP_MD *SSL_get_signature_algorithm_digest(uint16_t sigalg) { + const SSL_SIGNATURE_ALGORITHM *alg = get_signature_algorithm(sigalg); + if (alg == nullptr || alg->digest_func == nullptr) { + return nullptr; + } + return alg->digest_func(); +} + +int SSL_is_signature_algorithm_rsa_pss(uint16_t sigalg) { + const SSL_SIGNATURE_ALGORITHM *alg = get_signature_algorithm(sigalg); + return alg != nullptr && alg->is_rsa_pss; +} + +static int set_algorithm_prefs(uint16_t **out_prefs, size_t *out_num_prefs, + const uint16_t *prefs, size_t num_prefs) { + OPENSSL_free(*out_prefs); + + *out_num_prefs = 0; + *out_prefs = (uint16_t *)BUF_memdup(prefs, num_prefs * sizeof(prefs[0])); + if (*out_prefs == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + *out_num_prefs = num_prefs; + + return 1; +} + +int SSL_CTX_set_signing_algorithm_prefs(SSL_CTX *ctx, const uint16_t *prefs, + size_t num_prefs) { + return set_algorithm_prefs(&ctx->cert->sigalgs, &ctx->cert->num_sigalgs, + prefs, num_prefs); +} + +int SSL_set_signing_algorithm_prefs(SSL *ssl, const uint16_t *prefs, + size_t num_prefs) { + return set_algorithm_prefs(&ssl->cert->sigalgs, &ssl->cert->num_sigalgs, + prefs, num_prefs); +} + +int SSL_CTX_set_verify_algorithm_prefs(SSL_CTX *ctx, const uint16_t *prefs, + size_t num_prefs) { + return set_algorithm_prefs(&ctx->verify_sigalgs, &ctx->num_verify_sigalgs, + prefs, num_prefs); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/ssl/ssl_session.cc b/FoodApp/Pods/BoringSSL-GRPC/ssl/ssl_session.cc new file mode 100644 index 0000000..0c93c4f --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/ssl/ssl_session.cc @@ -0,0 +1,1221 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include "internal.h" +#include "../crypto/internal.h" + + +namespace bssl { + +// The address of this is a magic value, a pointer to which is returned by +// SSL_magic_pending_session_ptr(). It allows a session callback to indicate +// that it needs to asynchronously fetch session information. +static const char g_pending_session_magic = 0; + +static CRYPTO_EX_DATA_CLASS g_ex_data_class = + CRYPTO_EX_DATA_CLASS_INIT_WITH_APP_DATA; + +static void SSL_SESSION_list_remove(SSL_CTX *ctx, SSL_SESSION *session); +static void SSL_SESSION_list_add(SSL_CTX *ctx, SSL_SESSION *session); +static int remove_session_lock(SSL_CTX *ctx, SSL_SESSION *session, int lock); + +UniquePtr ssl_session_new(const SSL_X509_METHOD *x509_method) { + UniquePtr session( + (SSL_SESSION *)OPENSSL_malloc(sizeof(SSL_SESSION))); + if (!session) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + OPENSSL_memset(session.get(), 0, sizeof(SSL_SESSION)); + + session->x509_method = x509_method; + session->verify_result = X509_V_ERR_INVALID_CALL; + session->references = 1; + session->timeout = SSL_DEFAULT_SESSION_TIMEOUT; + session->auth_timeout = SSL_DEFAULT_SESSION_TIMEOUT; + session->time = time(NULL); + CRYPTO_new_ex_data(&session->ex_data); + return session; +} + +UniquePtr SSL_SESSION_dup(SSL_SESSION *session, int dup_flags) { + UniquePtr new_session = ssl_session_new(session->x509_method); + if (!new_session) { + return nullptr; + } + + new_session->is_server = session->is_server; + new_session->ssl_version = session->ssl_version; + new_session->sid_ctx_length = session->sid_ctx_length; + OPENSSL_memcpy(new_session->sid_ctx, session->sid_ctx, session->sid_ctx_length); + + // Copy the key material. + new_session->master_key_length = session->master_key_length; + OPENSSL_memcpy(new_session->master_key, session->master_key, + session->master_key_length); + new_session->cipher = session->cipher; + + // Copy authentication state. + if (session->psk_identity != NULL) { + new_session->psk_identity = BUF_strdup(session->psk_identity); + if (new_session->psk_identity == NULL) { + return nullptr; + } + } + if (session->certs != NULL) { + new_session->certs = sk_CRYPTO_BUFFER_new_null(); + if (new_session->certs == NULL) { + return nullptr; + } + for (size_t i = 0; i < sk_CRYPTO_BUFFER_num(session->certs); i++) { + CRYPTO_BUFFER *buffer = sk_CRYPTO_BUFFER_value(session->certs, i); + if (!sk_CRYPTO_BUFFER_push(new_session->certs, buffer)) { + return nullptr; + } + CRYPTO_BUFFER_up_ref(buffer); + } + } + + if (!session->x509_method->session_dup(new_session.get(), session)) { + return nullptr; + } + + new_session->verify_result = session->verify_result; + + if (session->ocsp_response != NULL) { + new_session->ocsp_response = session->ocsp_response; + CRYPTO_BUFFER_up_ref(new_session->ocsp_response); + } + + if (session->signed_cert_timestamp_list != NULL) { + new_session->signed_cert_timestamp_list = + session->signed_cert_timestamp_list; + CRYPTO_BUFFER_up_ref(new_session->signed_cert_timestamp_list); + } + + OPENSSL_memcpy(new_session->peer_sha256, session->peer_sha256, + SHA256_DIGEST_LENGTH); + new_session->peer_sha256_valid = session->peer_sha256_valid; + + new_session->peer_signature_algorithm = session->peer_signature_algorithm; + + new_session->timeout = session->timeout; + new_session->auth_timeout = session->auth_timeout; + new_session->time = session->time; + + // Copy non-authentication connection properties. + if (dup_flags & SSL_SESSION_INCLUDE_NONAUTH) { + new_session->session_id_length = session->session_id_length; + OPENSSL_memcpy(new_session->session_id, session->session_id, + session->session_id_length); + + new_session->group_id = session->group_id; + + OPENSSL_memcpy(new_session->original_handshake_hash, + session->original_handshake_hash, + session->original_handshake_hash_len); + new_session->original_handshake_hash_len = + session->original_handshake_hash_len; + new_session->tlsext_tick_lifetime_hint = session->tlsext_tick_lifetime_hint; + new_session->ticket_age_add = session->ticket_age_add; + new_session->ticket_max_early_data = session->ticket_max_early_data; + new_session->extended_master_secret = session->extended_master_secret; + + if (session->early_alpn != NULL) { + new_session->early_alpn = + (uint8_t *)BUF_memdup(session->early_alpn, session->early_alpn_len); + if (new_session->early_alpn == NULL) { + return nullptr; + } + } + new_session->early_alpn_len = session->early_alpn_len; + } + + // Copy the ticket. + if (dup_flags & SSL_SESSION_INCLUDE_TICKET) { + if (session->tlsext_tick != NULL) { + new_session->tlsext_tick = + (uint8_t *)BUF_memdup(session->tlsext_tick, session->tlsext_ticklen); + if (new_session->tlsext_tick == NULL) { + return nullptr; + } + } + new_session->tlsext_ticklen = session->tlsext_ticklen; + } + + // The new_session does not get a copy of the ex_data. + + new_session->not_resumable = 1; + return new_session; +} + +void ssl_session_rebase_time(SSL *ssl, SSL_SESSION *session) { + struct OPENSSL_timeval now; + ssl_get_current_time(ssl, &now); + + // To avoid overflows and underflows, if we've gone back in time, update the + // time, but mark the session expired. + if (session->time > now.tv_sec) { + session->time = now.tv_sec; + session->timeout = 0; + session->auth_timeout = 0; + return; + } + + // Adjust the session time and timeouts. If the session has already expired, + // clamp the timeouts at zero. + uint64_t delta = now.tv_sec - session->time; + session->time = now.tv_sec; + if (session->timeout < delta) { + session->timeout = 0; + } else { + session->timeout -= delta; + } + if (session->auth_timeout < delta) { + session->auth_timeout = 0; + } else { + session->auth_timeout -= delta; + } +} + +void ssl_session_renew_timeout(SSL *ssl, SSL_SESSION *session, + uint32_t timeout) { + // Rebase the timestamp relative to the current time so |timeout| is measured + // correctly. + ssl_session_rebase_time(ssl, session); + + if (session->timeout > timeout) { + return; + } + + session->timeout = timeout; + if (session->timeout > session->auth_timeout) { + session->timeout = session->auth_timeout; + } +} + +uint16_t ssl_session_protocol_version(const SSL_SESSION *session) { + uint16_t ret; + if (!ssl_protocol_version_from_wire(&ret, session->ssl_version)) { + // An |SSL_SESSION| will never have an invalid version. This is enforced by + // the parser. + assert(0); + return 0; + } + + return ret; +} + +const EVP_MD *ssl_session_get_digest(const SSL_SESSION *session) { + return ssl_get_handshake_digest(ssl_session_protocol_version(session), + session->cipher); +} + +int ssl_get_new_session(SSL_HANDSHAKE *hs, int is_server) { + SSL *const ssl = hs->ssl; + if (ssl->mode & SSL_MODE_NO_SESSION_CREATION) { + OPENSSL_PUT_ERROR(SSL, SSL_R_SESSION_MAY_NOT_BE_CREATED); + return 0; + } + + UniquePtr session = ssl_session_new(ssl->ctx->x509_method); + if (session == NULL) { + return 0; + } + + session->is_server = is_server; + session->ssl_version = ssl->version; + + // Fill in the time from the |SSL_CTX|'s clock. + struct OPENSSL_timeval now; + ssl_get_current_time(ssl, &now); + session->time = now.tv_sec; + + uint16_t version = ssl_protocol_version(ssl); + if (version >= TLS1_3_VERSION) { + // TLS 1.3 uses tickets as authenticators, so we are willing to use them for + // longer. + session->timeout = ssl->session_ctx->session_psk_dhe_timeout; + session->auth_timeout = SSL_DEFAULT_SESSION_AUTH_TIMEOUT; + } else { + // TLS 1.2 resumption does not incorporate new key material, so we use a + // much shorter timeout. + session->timeout = ssl->session_ctx->session_timeout; + session->auth_timeout = ssl->session_ctx->session_timeout; + } + + if (is_server) { + if (hs->ticket_expected || version >= TLS1_3_VERSION) { + // Don't set session IDs for sessions resumed with tickets. This will keep + // them out of the session cache. + session->session_id_length = 0; + } else { + session->session_id_length = SSL3_SSL_SESSION_ID_LENGTH; + if (!RAND_bytes(session->session_id, session->session_id_length)) { + return 0; + } + } + } else { + session->session_id_length = 0; + } + + if (ssl->cert->sid_ctx_length > sizeof(session->sid_ctx)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return 0; + } + OPENSSL_memcpy(session->sid_ctx, ssl->cert->sid_ctx, + ssl->cert->sid_ctx_length); + session->sid_ctx_length = ssl->cert->sid_ctx_length; + + // The session is marked not resumable until it is completely filled in. + session->not_resumable = 1; + session->verify_result = X509_V_ERR_INVALID_CALL; + + hs->new_session = std::move(session); + ssl_set_session(ssl, NULL); + return 1; +} + +int ssl_ctx_rotate_ticket_encryption_key(SSL_CTX *ctx) { + OPENSSL_timeval now; + ssl_ctx_get_current_time(ctx, &now); + { + // Avoid acquiring a write lock in the common case (i.e. a non-default key + // is used or the default keys have not expired yet). + MutexReadLock lock(&ctx->lock); + if (ctx->tlsext_ticket_key_current && + (ctx->tlsext_ticket_key_current->next_rotation_tv_sec == 0 || + ctx->tlsext_ticket_key_current->next_rotation_tv_sec > now.tv_sec) && + (!ctx->tlsext_ticket_key_prev || + ctx->tlsext_ticket_key_prev->next_rotation_tv_sec > now.tv_sec)) { + return 1; + } + } + + MutexWriteLock lock(&ctx->lock); + if (!ctx->tlsext_ticket_key_current || + (ctx->tlsext_ticket_key_current->next_rotation_tv_sec != 0 && + ctx->tlsext_ticket_key_current->next_rotation_tv_sec <= now.tv_sec)) { + // The current key has not been initialized or it is expired. + auto new_key = bssl::MakeUnique(); + if (!new_key) { + return 0; + } + OPENSSL_memset(new_key.get(), 0, sizeof(struct tlsext_ticket_key)); + if (ctx->tlsext_ticket_key_current) { + // The current key expired. Rotate it to prev and bump up its rotation + // timestamp. Note that even with the new rotation time it may still be + // expired and get droppped below. + ctx->tlsext_ticket_key_current->next_rotation_tv_sec += + SSL_DEFAULT_TICKET_KEY_ROTATION_INTERVAL; + OPENSSL_free(ctx->tlsext_ticket_key_prev); + ctx->tlsext_ticket_key_prev = ctx->tlsext_ticket_key_current; + } + ctx->tlsext_ticket_key_current = new_key.release(); + RAND_bytes(ctx->tlsext_ticket_key_current->name, 16); + RAND_bytes(ctx->tlsext_ticket_key_current->hmac_key, 16); + RAND_bytes(ctx->tlsext_ticket_key_current->aes_key, 16); + ctx->tlsext_ticket_key_current->next_rotation_tv_sec = + now.tv_sec + SSL_DEFAULT_TICKET_KEY_ROTATION_INTERVAL; + } + + // Drop an expired prev key. + if (ctx->tlsext_ticket_key_prev && + ctx->tlsext_ticket_key_prev->next_rotation_tv_sec <= now.tv_sec) { + OPENSSL_free(ctx->tlsext_ticket_key_prev); + ctx->tlsext_ticket_key_prev = nullptr; + } + + return 1; +} + +static int ssl_encrypt_ticket_with_cipher_ctx(SSL *ssl, CBB *out, + const uint8_t *session_buf, + size_t session_len) { + ScopedEVP_CIPHER_CTX ctx; + ScopedHMAC_CTX hctx; + + // If the session is too long, emit a dummy value rather than abort the + // connection. + static const size_t kMaxTicketOverhead = + 16 + EVP_MAX_IV_LENGTH + EVP_MAX_BLOCK_LENGTH + EVP_MAX_MD_SIZE; + if (session_len > 0xffff - kMaxTicketOverhead) { + static const char kTicketPlaceholder[] = "TICKET TOO LARGE"; + return CBB_add_bytes(out, (const uint8_t *)kTicketPlaceholder, + strlen(kTicketPlaceholder)); + } + + // Initialize HMAC and cipher contexts. If callback present it does all the + // work otherwise use generated values from parent ctx. + SSL_CTX *tctx = ssl->session_ctx; + uint8_t iv[EVP_MAX_IV_LENGTH]; + uint8_t key_name[16]; + if (tctx->tlsext_ticket_key_cb != NULL) { + if (tctx->tlsext_ticket_key_cb(ssl, key_name, iv, ctx.get(), hctx.get(), + 1 /* encrypt */) < 0) { + return 0; + } + } else { + // Rotate ticket key if necessary. + if (!ssl_ctx_rotate_ticket_encryption_key(tctx)) { + return 0; + } + MutexReadLock lock(&tctx->lock); + if (!RAND_bytes(iv, 16) || + !EVP_EncryptInit_ex(ctx.get(), EVP_aes_128_cbc(), NULL, + tctx->tlsext_ticket_key_current->aes_key, iv) || + !HMAC_Init_ex(hctx.get(), tctx->tlsext_ticket_key_current->hmac_key, 16, + tlsext_tick_md(), NULL)) { + return 0; + } + OPENSSL_memcpy(key_name, tctx->tlsext_ticket_key_current->name, 16); + } + + uint8_t *ptr; + if (!CBB_add_bytes(out, key_name, 16) || + !CBB_add_bytes(out, iv, EVP_CIPHER_CTX_iv_length(ctx.get())) || + !CBB_reserve(out, &ptr, session_len + EVP_MAX_BLOCK_LENGTH)) { + return 0; + } + + size_t total = 0; +#if defined(BORINGSSL_UNSAFE_FUZZER_MODE) + OPENSSL_memcpy(ptr, session_buf, session_len); + total = session_len; +#else + int len; + if (!EVP_EncryptUpdate(ctx.get(), ptr + total, &len, session_buf, session_len)) { + return 0; + } + total += len; + if (!EVP_EncryptFinal_ex(ctx.get(), ptr + total, &len)) { + return 0; + } + total += len; +#endif + if (!CBB_did_write(out, total)) { + return 0; + } + + unsigned hlen; + if (!HMAC_Update(hctx.get(), CBB_data(out), CBB_len(out)) || + !CBB_reserve(out, &ptr, EVP_MAX_MD_SIZE) || + !HMAC_Final(hctx.get(), ptr, &hlen) || + !CBB_did_write(out, hlen)) { + return 0; + } + + return 1; +} + +static int ssl_encrypt_ticket_with_method(SSL *ssl, CBB *out, + const uint8_t *session_buf, + size_t session_len) { + const SSL_TICKET_AEAD_METHOD *method = ssl->session_ctx->ticket_aead_method; + const size_t max_overhead = method->max_overhead(ssl); + const size_t max_out = session_len + max_overhead; + if (max_out < max_overhead) { + OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW); + return 0; + } + + uint8_t *ptr; + if (!CBB_reserve(out, &ptr, max_out)) { + return 0; + } + + size_t out_len; + if (!method->seal(ssl, ptr, &out_len, max_out, session_buf, session_len)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_TICKET_ENCRYPTION_FAILED); + return 0; + } + + if (!CBB_did_write(out, out_len)) { + return 0; + } + + return 1; +} + +int ssl_encrypt_ticket(SSL *ssl, CBB *out, const SSL_SESSION *session) { + // Serialize the SSL_SESSION to be encoded into the ticket. + uint8_t *session_buf = NULL; + size_t session_len; + if (!SSL_SESSION_to_bytes_for_ticket(session, &session_buf, &session_len)) { + return -1; + } + + int ret = 0; + if (ssl->session_ctx->ticket_aead_method) { + ret = ssl_encrypt_ticket_with_method(ssl, out, session_buf, session_len); + } else { + ret = + ssl_encrypt_ticket_with_cipher_ctx(ssl, out, session_buf, session_len); + } + + OPENSSL_free(session_buf); + return ret; +} + +int ssl_session_is_context_valid(const SSL *ssl, const SSL_SESSION *session) { + if (session == NULL) { + return 0; + } + + return session->sid_ctx_length == ssl->cert->sid_ctx_length && + OPENSSL_memcmp(session->sid_ctx, ssl->cert->sid_ctx, + ssl->cert->sid_ctx_length) == 0; +} + +int ssl_session_is_time_valid(const SSL *ssl, const SSL_SESSION *session) { + if (session == NULL) { + return 0; + } + + struct OPENSSL_timeval now; + ssl_get_current_time(ssl, &now); + + // Reject tickets from the future to avoid underflow. + if (now.tv_sec < session->time) { + return 0; + } + + return session->timeout > now.tv_sec - session->time; +} + +int ssl_session_is_resumable(const SSL_HANDSHAKE *hs, + const SSL_SESSION *session) { + const SSL *const ssl = hs->ssl; + return ssl_session_is_context_valid(ssl, session) && + // The session must have been created by the same type of end point as + // we're now using it with. + ssl->server == session->is_server && + // The session must not be expired. + ssl_session_is_time_valid(ssl, session) && + /* Only resume if the session's version matches the negotiated + * version. */ + ssl->version == session->ssl_version && + // Only resume if the session's cipher matches the negotiated one. + hs->new_cipher == session->cipher && + // If the session contains a client certificate (either the full + // certificate or just the hash) then require that the form of the + // certificate matches the current configuration. + ((sk_CRYPTO_BUFFER_num(session->certs) == 0 && + !session->peer_sha256_valid) || + session->peer_sha256_valid == + ssl->retain_only_sha256_of_client_certs); +} + +// ssl_lookup_session looks up |session_id| in the session cache and sets +// |*out_session| to an |SSL_SESSION| object if found. +static enum ssl_hs_wait_t ssl_lookup_session( + SSL *ssl, UniquePtr *out_session, const uint8_t *session_id, + size_t session_id_len) { + out_session->reset(); + + if (session_id_len == 0 || session_id_len > SSL_MAX_SSL_SESSION_ID_LENGTH) { + return ssl_hs_ok; + } + + UniquePtr session; + // Try the internal cache, if it exists. + if (!(ssl->session_ctx->session_cache_mode & + SSL_SESS_CACHE_NO_INTERNAL_LOOKUP)) { + SSL_SESSION data; + data.ssl_version = ssl->version; + data.session_id_length = session_id_len; + OPENSSL_memcpy(data.session_id, session_id, session_id_len); + + MutexReadLock lock(&ssl->session_ctx->lock); + session.reset(lh_SSL_SESSION_retrieve(ssl->session_ctx->sessions, &data)); + if (session) { + // |lh_SSL_SESSION_retrieve| returns a non-owning pointer. + SSL_SESSION_up_ref(session.get()); + } + // TODO(davidben): This should probably move it to the front of the list. + } + + // Fall back to the external cache, if it exists. + if (!session && (ssl->session_ctx->get_session_cb != nullptr || + ssl->session_ctx->get_session_cb_legacy != nullptr)) { + int copy = 1; + if (ssl->session_ctx->get_session_cb != nullptr) { + session.reset(ssl->session_ctx->get_session_cb(ssl, session_id, + session_id_len, ©)); + } else { + session.reset(ssl->session_ctx->get_session_cb_legacy( + ssl, const_cast(session_id), session_id_len, ©)); + } + + if (!session) { + return ssl_hs_ok; + } + + if (session.get() == SSL_magic_pending_session_ptr()) { + session.release(); // This pointer is not actually owned. + return ssl_hs_pending_session; + } + + // 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) { + SSL_SESSION_up_ref(session.get()); + } + + // Add the externally cached session to the internal cache if necessary. + if (!(ssl->session_ctx->session_cache_mode & + SSL_SESS_CACHE_NO_INTERNAL_STORE)) { + SSL_CTX_add_session(ssl->session_ctx, session.get()); + } + } + + if (session && !ssl_session_is_time_valid(ssl, session.get())) { + // The session was from the cache, so remove it. + SSL_CTX_remove_session(ssl->session_ctx, session.get()); + session.reset(); + } + + *out_session = std::move(session); + return ssl_hs_ok; +} + +enum ssl_hs_wait_t ssl_get_prev_session(SSL *ssl, + UniquePtr *out_session, + bool *out_tickets_supported, + bool *out_renew_ticket, + const SSL_CLIENT_HELLO *client_hello) { + // This is used only by servers. + assert(ssl->server); + UniquePtr session; + bool renew_ticket = false; + + // If tickets are disabled, always behave as if no tickets are present. + const uint8_t *ticket = NULL; + size_t ticket_len = 0; + const bool tickets_supported = + !(SSL_get_options(ssl) & SSL_OP_NO_TICKET) && + ssl->version > SSL3_VERSION && + SSL_early_callback_ctx_extension_get( + client_hello, TLSEXT_TYPE_session_ticket, &ticket, &ticket_len); + if (tickets_supported && ticket_len > 0) { + switch (ssl_process_ticket(ssl, &session, &renew_ticket, ticket, ticket_len, + client_hello->session_id, + client_hello->session_id_len)) { + case ssl_ticket_aead_success: + break; + case ssl_ticket_aead_ignore_ticket: + assert(!session); + break; + case ssl_ticket_aead_error: + return ssl_hs_error; + case ssl_ticket_aead_retry: + return ssl_hs_pending_ticket; + } + } else { + // The client didn't send a ticket, so the session ID is a real ID. + enum ssl_hs_wait_t lookup_ret = ssl_lookup_session( + ssl, &session, client_hello->session_id, client_hello->session_id_len); + if (lookup_ret != ssl_hs_ok) { + return lookup_ret; + } + } + + *out_session = std::move(session); + *out_tickets_supported = tickets_supported; + *out_renew_ticket = renew_ticket; + return ssl_hs_ok; +} + +static int remove_session_lock(SSL_CTX *ctx, SSL_SESSION *session, int lock) { + int ret = 0; + + if (session != NULL && session->session_id_length != 0) { + if (lock) { + CRYPTO_MUTEX_lock_write(&ctx->lock); + } + SSL_SESSION *found_session = lh_SSL_SESSION_retrieve(ctx->sessions, + session); + if (found_session == session) { + ret = 1; + found_session = lh_SSL_SESSION_delete(ctx->sessions, session); + SSL_SESSION_list_remove(ctx, session); + } + + if (lock) { + CRYPTO_MUTEX_unlock_write(&ctx->lock); + } + + if (ret) { + if (ctx->remove_session_cb != NULL) { + ctx->remove_session_cb(ctx, found_session); + } + SSL_SESSION_free(found_session); + } + } + + return ret; +} + +void ssl_set_session(SSL *ssl, SSL_SESSION *session) { + if (ssl->session == session) { + return; + } + + SSL_SESSION_free(ssl->session); + ssl->session = session; + if (session != NULL) { + SSL_SESSION_up_ref(session); + } +} + +// locked by SSL_CTX in the calling function +static void SSL_SESSION_list_remove(SSL_CTX *ctx, SSL_SESSION *session) { + if (session->next == NULL || session->prev == NULL) { + return; + } + + if (session->next == (SSL_SESSION *)&ctx->session_cache_tail) { + // last element in list + if (session->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 = session->prev; + session->prev->next = (SSL_SESSION *)&(ctx->session_cache_tail); + } + } else { + if (session->prev == (SSL_SESSION *)&ctx->session_cache_head) { + // first element in list + ctx->session_cache_head = session->next; + session->next->prev = (SSL_SESSION *)&(ctx->session_cache_head); + } else { // middle of list + session->next->prev = session->prev; + session->prev->next = session->next; + } + } + session->prev = session->next = NULL; +} + +static void SSL_SESSION_list_add(SSL_CTX *ctx, SSL_SESSION *session) { + if (session->next != NULL && session->prev != NULL) { + SSL_SESSION_list_remove(ctx, session); + } + + if (ctx->session_cache_head == NULL) { + ctx->session_cache_head = session; + ctx->session_cache_tail = session; + session->prev = (SSL_SESSION *)&(ctx->session_cache_head); + session->next = (SSL_SESSION *)&(ctx->session_cache_tail); + } else { + session->next = ctx->session_cache_head; + session->next->prev = session; + session->prev = (SSL_SESSION *)&(ctx->session_cache_head); + ctx->session_cache_head = session; + } +} + +} // namespace bssl + +using namespace bssl; + +SSL_SESSION *SSL_SESSION_new(const SSL_CTX *ctx) { + return ssl_session_new(ctx->x509_method).release(); +} + +int SSL_SESSION_up_ref(SSL_SESSION *session) { + CRYPTO_refcount_inc(&session->references); + return 1; +} + +void SSL_SESSION_free(SSL_SESSION *session) { + if (session == NULL || + !CRYPTO_refcount_dec_and_test_zero(&session->references)) { + return; + } + + CRYPTO_free_ex_data(&g_ex_data_class, session, &session->ex_data); + + OPENSSL_cleanse(session->master_key, sizeof(session->master_key)); + OPENSSL_cleanse(session->session_id, sizeof(session->session_id)); + sk_CRYPTO_BUFFER_pop_free(session->certs, CRYPTO_BUFFER_free); + session->x509_method->session_clear(session); + OPENSSL_free(session->tlsext_tick); + CRYPTO_BUFFER_free(session->signed_cert_timestamp_list); + CRYPTO_BUFFER_free(session->ocsp_response); + OPENSSL_free(session->psk_identity); + OPENSSL_free(session->early_alpn); + OPENSSL_free(session); +} + +const uint8_t *SSL_SESSION_get_id(const SSL_SESSION *session, + unsigned *out_len) { + if (out_len != NULL) { + *out_len = session->session_id_length; + } + return session->session_id; +} + +uint32_t SSL_SESSION_get_timeout(const SSL_SESSION *session) { + return session->timeout; +} + +uint64_t SSL_SESSION_get_time(const SSL_SESSION *session) { + if (session == NULL) { + // NULL should crash, but silently accept it here for compatibility. + return 0; + } + return session->time; +} + +X509 *SSL_SESSION_get0_peer(const SSL_SESSION *session) { + return session->x509_peer; +} + +size_t SSL_SESSION_get_master_key(const SSL_SESSION *session, uint8_t *out, + size_t max_out) { + // TODO(davidben): Fix master_key_length's type and remove these casts. + if (max_out == 0) { + return (size_t)session->master_key_length; + } + if (max_out > (size_t)session->master_key_length) { + max_out = (size_t)session->master_key_length; + } + OPENSSL_memcpy(out, session->master_key, max_out); + return max_out; +} + +uint64_t SSL_SESSION_set_time(SSL_SESSION *session, uint64_t time) { + if (session == NULL) { + return 0; + } + + session->time = time; + return time; +} + +uint32_t SSL_SESSION_set_timeout(SSL_SESSION *session, uint32_t timeout) { + if (session == NULL) { + return 0; + } + + session->timeout = timeout; + session->auth_timeout = timeout; + return 1; +} + +int SSL_SESSION_set1_id_context(SSL_SESSION *session, const uint8_t *sid_ctx, + size_t sid_ctx_len) { + if (sid_ctx_len > sizeof(session->sid_ctx)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG); + return 0; + } + + static_assert(sizeof(session->sid_ctx) < 256, "sid_ctx_len does not fit"); + session->sid_ctx_length = (uint8_t)sid_ctx_len; + OPENSSL_memcpy(session->sid_ctx, sid_ctx, sid_ctx_len); + + return 1; +} + +int SSL_SESSION_should_be_single_use(const SSL_SESSION *session) { + return ssl_session_protocol_version(session) >= TLS1_3_VERSION; +} + +int SSL_SESSION_is_resumable(const SSL_SESSION *session) { + return !session->not_resumable; +} + +int SSL_SESSION_has_ticket(const SSL_SESSION *session) { + return session->tlsext_ticklen > 0; +} + +void SSL_SESSION_get0_ticket(const SSL_SESSION *session, + const uint8_t **out_ticket, size_t *out_len) { + if (out_ticket != nullptr) { + *out_ticket = session->tlsext_tick; + } + *out_len = session->tlsext_ticklen; +} + +uint32_t SSL_SESSION_get_ticket_lifetime_hint(const SSL_SESSION *session) { + return session->tlsext_tick_lifetime_hint; +} + +SSL_SESSION *SSL_magic_pending_session_ptr(void) { + return (SSL_SESSION *)&g_pending_session_magic; +} + +SSL_SESSION *SSL_get_session(const SSL *ssl) { + // Once the handshake completes we return the established session. Otherwise + // we return the intermediate session, either |session| (for resumption) or + // |new_session| if doing a full handshake. + if (!SSL_in_init(ssl)) { + return ssl->s3->established_session.get(); + } + SSL_HANDSHAKE *hs = ssl->s3->hs.get(); + if (hs->early_session) { + return hs->early_session.get(); + } + if (hs->new_session) { + return hs->new_session.get(); + } + return ssl->session; +} + +SSL_SESSION *SSL_get1_session(SSL *ssl) { + SSL_SESSION *ret = SSL_get_session(ssl); + if (ret != NULL) { + SSL_SESSION_up_ref(ret); + } + return ret; +} + +int SSL_SESSION_get_ex_new_index(long argl, void *argp, + CRYPTO_EX_unused *unused, + CRYPTO_EX_dup *dup_unused, + CRYPTO_EX_free *free_func) { + int index; + if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp, + free_func)) { + return -1; + } + return index; +} + +int SSL_SESSION_set_ex_data(SSL_SESSION *session, int idx, void *arg) { + return CRYPTO_set_ex_data(&session->ex_data, idx, arg); +} + +void *SSL_SESSION_get_ex_data(const SSL_SESSION *session, int idx) { + return CRYPTO_get_ex_data(&session->ex_data, idx); +} + +int SSL_CTX_add_session(SSL_CTX *ctx, SSL_SESSION *session) { + // Although |session| is inserted into two structures (a doubly-linked list + // and the hash table), |ctx| only takes one reference. + SSL_SESSION_up_ref(session); + UniquePtr owned_session(session); + + SSL_SESSION *old_session; + MutexWriteLock lock(&ctx->lock); + if (!lh_SSL_SESSION_insert(ctx->sessions, &old_session, session)) { + return 0; + } + // |ctx->sessions| took ownership of |session| and gave us back a reference to + // |old_session|. (|old_session| may be the same as |session|, in which case + // we traded identical references with |ctx->sessions|.) + owned_session.release(); + owned_session.reset(old_session); + + if (old_session != NULL) { + if (old_session == session) { + // |session| was already in the cache. There are no linked list pointers + // to update. + return 0; + } + + // There was a session ID collision. |old_session| was replaced with + // |session| in the hash table, so |old_session| must be removed from the + // linked list to match. + SSL_SESSION_list_remove(ctx, old_session); + } + + SSL_SESSION_list_add(ctx, session); + + // Enforce any cache size limits. + if (SSL_CTX_sess_get_cache_size(ctx) > 0) { + while (lh_SSL_SESSION_num_items(ctx->sessions) > + SSL_CTX_sess_get_cache_size(ctx)) { + if (!remove_session_lock(ctx, ctx->session_cache_tail, 0)) { + break; + } + } + } + + return 1; +} + +int SSL_CTX_remove_session(SSL_CTX *ctx, SSL_SESSION *session) { + return remove_session_lock(ctx, session, 1); +} + +int SSL_set_session(SSL *ssl, SSL_SESSION *session) { + // SSL_set_session may only be called before the handshake has started. + if (ssl->s3->initial_handshake_complete || + ssl->s3->hs == NULL || + ssl->s3->hs->state != 0) { + abort(); + } + + ssl_set_session(ssl, session); + return 1; +} + +uint32_t SSL_CTX_set_timeout(SSL_CTX *ctx, uint32_t timeout) { + if (ctx == NULL) { + return 0; + } + + // Historically, zero was treated as |SSL_DEFAULT_SESSION_TIMEOUT|. + if (timeout == 0) { + timeout = SSL_DEFAULT_SESSION_TIMEOUT; + } + + uint32_t old_timeout = ctx->session_timeout; + ctx->session_timeout = timeout; + return old_timeout; +} + +uint32_t SSL_CTX_get_timeout(const SSL_CTX *ctx) { + if (ctx == NULL) { + return 0; + } + + return ctx->session_timeout; +} + +void SSL_CTX_set_session_psk_dhe_timeout(SSL_CTX *ctx, uint32_t timeout) { + ctx->session_psk_dhe_timeout = timeout; +} + +typedef struct timeout_param_st { + SSL_CTX *ctx; + uint64_t time; + LHASH_OF(SSL_SESSION) *cache; +} TIMEOUT_PARAM; + +static void timeout_doall_arg(SSL_SESSION *session, void *void_param) { + TIMEOUT_PARAM *param = reinterpret_cast(void_param); + + if (param->time == 0 || + session->time + session->timeout < session->time || + param->time > (session->time + session->timeout)) { + // The reason we don't call SSL_CTX_remove_session() is to + // save on locking overhead + (void) lh_SSL_SESSION_delete(param->cache, session); + SSL_SESSION_list_remove(param->ctx, session); + if (param->ctx->remove_session_cb != NULL) { + param->ctx->remove_session_cb(param->ctx, session); + } + SSL_SESSION_free(session); + } +} + +void SSL_CTX_flush_sessions(SSL_CTX *ctx, uint64_t time) { + TIMEOUT_PARAM tp; + + tp.ctx = ctx; + tp.cache = ctx->sessions; + if (tp.cache == NULL) { + return; + } + tp.time = time; + MutexWriteLock lock(&ctx->lock); + lh_SSL_SESSION_doall_arg(tp.cache, timeout_doall_arg, &tp); +} + +void SSL_CTX_sess_set_new_cb(SSL_CTX *ctx, + int (*cb)(SSL *ssl, SSL_SESSION *session)) { + ctx->new_session_cb = cb; +} + +int (*SSL_CTX_sess_get_new_cb(SSL_CTX *ctx))(SSL *ssl, SSL_SESSION *session) { + return ctx->new_session_cb; +} + +void SSL_CTX_sess_set_remove_cb( + SSL_CTX *ctx, void (*cb)(SSL_CTX *ctx, SSL_SESSION *session)) { + ctx->remove_session_cb = cb; +} + +void (*SSL_CTX_sess_get_remove_cb(SSL_CTX *ctx))(SSL_CTX *ctx, + SSL_SESSION *session) { + return ctx->remove_session_cb; +} + +void SSL_CTX_sess_set_get_cb(SSL_CTX *ctx, + SSL_SESSION *(*cb)(SSL *ssl, const uint8_t *id, + int id_len, int *out_copy)) { + ctx->get_session_cb = cb; +} + +void SSL_CTX_sess_set_get_cb(SSL_CTX *ctx, + SSL_SESSION *(*cb)(SSL *ssl, uint8_t *id, + int id_len, int *out_copy)) { + ctx->get_session_cb_legacy = cb; +} + +SSL_SESSION *(*SSL_CTX_sess_get_get_cb(SSL_CTX *ctx))(SSL *ssl, + const uint8_t *id, + int id_len, + int *out_copy) { + return ctx->get_session_cb; +} + +void SSL_CTX_set_info_callback( + SSL_CTX *ctx, void (*cb)(const SSL *ssl, int type, int value)) { + ctx->info_callback = cb; +} + +void (*SSL_CTX_get_info_callback(SSL_CTX *ctx))(const SSL *ssl, int type, + int value) { + return ctx->info_callback; +} + +void SSL_CTX_set_channel_id_cb(SSL_CTX *ctx, + void (*cb)(SSL *ssl, EVP_PKEY **pkey)) { + ctx->channel_id_cb = cb; +} + +void (*SSL_CTX_get_channel_id_cb(SSL_CTX *ctx))(SSL *ssl, EVP_PKEY **pkey) { + return ctx->channel_id_cb; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/ssl/ssl_session.cc.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/ssl/ssl_session.cc.grpc_back new file mode 100644 index 0000000..34e7b31 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/ssl/ssl_session.cc.grpc_back @@ -0,0 +1,1221 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include "internal.h" +#include "../crypto/internal.h" + + +namespace bssl { + +// The address of this is a magic value, a pointer to which is returned by +// SSL_magic_pending_session_ptr(). It allows a session callback to indicate +// that it needs to asynchronously fetch session information. +static const char g_pending_session_magic = 0; + +static CRYPTO_EX_DATA_CLASS g_ex_data_class = + CRYPTO_EX_DATA_CLASS_INIT_WITH_APP_DATA; + +static void SSL_SESSION_list_remove(SSL_CTX *ctx, SSL_SESSION *session); +static void SSL_SESSION_list_add(SSL_CTX *ctx, SSL_SESSION *session); +static int remove_session_lock(SSL_CTX *ctx, SSL_SESSION *session, int lock); + +UniquePtr ssl_session_new(const SSL_X509_METHOD *x509_method) { + UniquePtr session( + (SSL_SESSION *)OPENSSL_malloc(sizeof(SSL_SESSION))); + if (!session) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + OPENSSL_memset(session.get(), 0, sizeof(SSL_SESSION)); + + session->x509_method = x509_method; + session->verify_result = X509_V_ERR_INVALID_CALL; + session->references = 1; + session->timeout = SSL_DEFAULT_SESSION_TIMEOUT; + session->auth_timeout = SSL_DEFAULT_SESSION_TIMEOUT; + session->time = time(NULL); + CRYPTO_new_ex_data(&session->ex_data); + return session; +} + +UniquePtr SSL_SESSION_dup(SSL_SESSION *session, int dup_flags) { + UniquePtr new_session = ssl_session_new(session->x509_method); + if (!new_session) { + return nullptr; + } + + new_session->is_server = session->is_server; + new_session->ssl_version = session->ssl_version; + new_session->sid_ctx_length = session->sid_ctx_length; + OPENSSL_memcpy(new_session->sid_ctx, session->sid_ctx, session->sid_ctx_length); + + // Copy the key material. + new_session->master_key_length = session->master_key_length; + OPENSSL_memcpy(new_session->master_key, session->master_key, + session->master_key_length); + new_session->cipher = session->cipher; + + // Copy authentication state. + if (session->psk_identity != NULL) { + new_session->psk_identity = BUF_strdup(session->psk_identity); + if (new_session->psk_identity == NULL) { + return nullptr; + } + } + if (session->certs != NULL) { + new_session->certs = sk_CRYPTO_BUFFER_new_null(); + if (new_session->certs == NULL) { + return nullptr; + } + for (size_t i = 0; i < sk_CRYPTO_BUFFER_num(session->certs); i++) { + CRYPTO_BUFFER *buffer = sk_CRYPTO_BUFFER_value(session->certs, i); + if (!sk_CRYPTO_BUFFER_push(new_session->certs, buffer)) { + return nullptr; + } + CRYPTO_BUFFER_up_ref(buffer); + } + } + + if (!session->x509_method->session_dup(new_session.get(), session)) { + return nullptr; + } + + new_session->verify_result = session->verify_result; + + if (session->ocsp_response != NULL) { + new_session->ocsp_response = session->ocsp_response; + CRYPTO_BUFFER_up_ref(new_session->ocsp_response); + } + + if (session->signed_cert_timestamp_list != NULL) { + new_session->signed_cert_timestamp_list = + session->signed_cert_timestamp_list; + CRYPTO_BUFFER_up_ref(new_session->signed_cert_timestamp_list); + } + + OPENSSL_memcpy(new_session->peer_sha256, session->peer_sha256, + SHA256_DIGEST_LENGTH); + new_session->peer_sha256_valid = session->peer_sha256_valid; + + new_session->peer_signature_algorithm = session->peer_signature_algorithm; + + new_session->timeout = session->timeout; + new_session->auth_timeout = session->auth_timeout; + new_session->time = session->time; + + // Copy non-authentication connection properties. + if (dup_flags & SSL_SESSION_INCLUDE_NONAUTH) { + new_session->session_id_length = session->session_id_length; + OPENSSL_memcpy(new_session->session_id, session->session_id, + session->session_id_length); + + new_session->group_id = session->group_id; + + OPENSSL_memcpy(new_session->original_handshake_hash, + session->original_handshake_hash, + session->original_handshake_hash_len); + new_session->original_handshake_hash_len = + session->original_handshake_hash_len; + new_session->tlsext_tick_lifetime_hint = session->tlsext_tick_lifetime_hint; + new_session->ticket_age_add = session->ticket_age_add; + new_session->ticket_max_early_data = session->ticket_max_early_data; + new_session->extended_master_secret = session->extended_master_secret; + + if (session->early_alpn != NULL) { + new_session->early_alpn = + (uint8_t *)BUF_memdup(session->early_alpn, session->early_alpn_len); + if (new_session->early_alpn == NULL) { + return nullptr; + } + } + new_session->early_alpn_len = session->early_alpn_len; + } + + // Copy the ticket. + if (dup_flags & SSL_SESSION_INCLUDE_TICKET) { + if (session->tlsext_tick != NULL) { + new_session->tlsext_tick = + (uint8_t *)BUF_memdup(session->tlsext_tick, session->tlsext_ticklen); + if (new_session->tlsext_tick == NULL) { + return nullptr; + } + } + new_session->tlsext_ticklen = session->tlsext_ticklen; + } + + // The new_session does not get a copy of the ex_data. + + new_session->not_resumable = 1; + return new_session; +} + +void ssl_session_rebase_time(SSL *ssl, SSL_SESSION *session) { + struct OPENSSL_timeval now; + ssl_get_current_time(ssl, &now); + + // To avoid overflows and underflows, if we've gone back in time, update the + // time, but mark the session expired. + if (session->time > now.tv_sec) { + session->time = now.tv_sec; + session->timeout = 0; + session->auth_timeout = 0; + return; + } + + // Adjust the session time and timeouts. If the session has already expired, + // clamp the timeouts at zero. + uint64_t delta = now.tv_sec - session->time; + session->time = now.tv_sec; + if (session->timeout < delta) { + session->timeout = 0; + } else { + session->timeout -= delta; + } + if (session->auth_timeout < delta) { + session->auth_timeout = 0; + } else { + session->auth_timeout -= delta; + } +} + +void ssl_session_renew_timeout(SSL *ssl, SSL_SESSION *session, + uint32_t timeout) { + // Rebase the timestamp relative to the current time so |timeout| is measured + // correctly. + ssl_session_rebase_time(ssl, session); + + if (session->timeout > timeout) { + return; + } + + session->timeout = timeout; + if (session->timeout > session->auth_timeout) { + session->timeout = session->auth_timeout; + } +} + +uint16_t ssl_session_protocol_version(const SSL_SESSION *session) { + uint16_t ret; + if (!ssl_protocol_version_from_wire(&ret, session->ssl_version)) { + // An |SSL_SESSION| will never have an invalid version. This is enforced by + // the parser. + assert(0); + return 0; + } + + return ret; +} + +const EVP_MD *ssl_session_get_digest(const SSL_SESSION *session) { + return ssl_get_handshake_digest(ssl_session_protocol_version(session), + session->cipher); +} + +int ssl_get_new_session(SSL_HANDSHAKE *hs, int is_server) { + SSL *const ssl = hs->ssl; + if (ssl->mode & SSL_MODE_NO_SESSION_CREATION) { + OPENSSL_PUT_ERROR(SSL, SSL_R_SESSION_MAY_NOT_BE_CREATED); + return 0; + } + + UniquePtr session = ssl_session_new(ssl->ctx->x509_method); + if (session == NULL) { + return 0; + } + + session->is_server = is_server; + session->ssl_version = ssl->version; + + // Fill in the time from the |SSL_CTX|'s clock. + struct OPENSSL_timeval now; + ssl_get_current_time(ssl, &now); + session->time = now.tv_sec; + + uint16_t version = ssl_protocol_version(ssl); + if (version >= TLS1_3_VERSION) { + // TLS 1.3 uses tickets as authenticators, so we are willing to use them for + // longer. + session->timeout = ssl->session_ctx->session_psk_dhe_timeout; + session->auth_timeout = SSL_DEFAULT_SESSION_AUTH_TIMEOUT; + } else { + // TLS 1.2 resumption does not incorporate new key material, so we use a + // much shorter timeout. + session->timeout = ssl->session_ctx->session_timeout; + session->auth_timeout = ssl->session_ctx->session_timeout; + } + + if (is_server) { + if (hs->ticket_expected || version >= TLS1_3_VERSION) { + // Don't set session IDs for sessions resumed with tickets. This will keep + // them out of the session cache. + session->session_id_length = 0; + } else { + session->session_id_length = SSL3_SSL_SESSION_ID_LENGTH; + if (!RAND_bytes(session->session_id, session->session_id_length)) { + return 0; + } + } + } else { + session->session_id_length = 0; + } + + if (ssl->cert->sid_ctx_length > sizeof(session->sid_ctx)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return 0; + } + OPENSSL_memcpy(session->sid_ctx, ssl->cert->sid_ctx, + ssl->cert->sid_ctx_length); + session->sid_ctx_length = ssl->cert->sid_ctx_length; + + // The session is marked not resumable until it is completely filled in. + session->not_resumable = 1; + session->verify_result = X509_V_ERR_INVALID_CALL; + + hs->new_session = std::move(session); + ssl_set_session(ssl, NULL); + return 1; +} + +int ssl_ctx_rotate_ticket_encryption_key(SSL_CTX *ctx) { + OPENSSL_timeval now; + ssl_ctx_get_current_time(ctx, &now); + { + // Avoid acquiring a write lock in the common case (i.e. a non-default key + // is used or the default keys have not expired yet). + MutexReadLock lock(&ctx->lock); + if (ctx->tlsext_ticket_key_current && + (ctx->tlsext_ticket_key_current->next_rotation_tv_sec == 0 || + ctx->tlsext_ticket_key_current->next_rotation_tv_sec > now.tv_sec) && + (!ctx->tlsext_ticket_key_prev || + ctx->tlsext_ticket_key_prev->next_rotation_tv_sec > now.tv_sec)) { + return 1; + } + } + + MutexWriteLock lock(&ctx->lock); + if (!ctx->tlsext_ticket_key_current || + (ctx->tlsext_ticket_key_current->next_rotation_tv_sec != 0 && + ctx->tlsext_ticket_key_current->next_rotation_tv_sec <= now.tv_sec)) { + // The current key has not been initialized or it is expired. + auto new_key = bssl::MakeUnique(); + if (!new_key) { + return 0; + } + OPENSSL_memset(new_key.get(), 0, sizeof(struct tlsext_ticket_key)); + if (ctx->tlsext_ticket_key_current) { + // The current key expired. Rotate it to prev and bump up its rotation + // timestamp. Note that even with the new rotation time it may still be + // expired and get droppped below. + ctx->tlsext_ticket_key_current->next_rotation_tv_sec += + SSL_DEFAULT_TICKET_KEY_ROTATION_INTERVAL; + OPENSSL_free(ctx->tlsext_ticket_key_prev); + ctx->tlsext_ticket_key_prev = ctx->tlsext_ticket_key_current; + } + ctx->tlsext_ticket_key_current = new_key.release(); + RAND_bytes(ctx->tlsext_ticket_key_current->name, 16); + RAND_bytes(ctx->tlsext_ticket_key_current->hmac_key, 16); + RAND_bytes(ctx->tlsext_ticket_key_current->aes_key, 16); + ctx->tlsext_ticket_key_current->next_rotation_tv_sec = + now.tv_sec + SSL_DEFAULT_TICKET_KEY_ROTATION_INTERVAL; + } + + // Drop an expired prev key. + if (ctx->tlsext_ticket_key_prev && + ctx->tlsext_ticket_key_prev->next_rotation_tv_sec <= now.tv_sec) { + OPENSSL_free(ctx->tlsext_ticket_key_prev); + ctx->tlsext_ticket_key_prev = nullptr; + } + + return 1; +} + +static int ssl_encrypt_ticket_with_cipher_ctx(SSL *ssl, CBB *out, + const uint8_t *session_buf, + size_t session_len) { + ScopedEVP_CIPHER_CTX ctx; + ScopedHMAC_CTX hctx; + + // If the session is too long, emit a dummy value rather than abort the + // connection. + static const size_t kMaxTicketOverhead = + 16 + EVP_MAX_IV_LENGTH + EVP_MAX_BLOCK_LENGTH + EVP_MAX_MD_SIZE; + if (session_len > 0xffff - kMaxTicketOverhead) { + static const char kTicketPlaceholder[] = "TICKET TOO LARGE"; + return CBB_add_bytes(out, (const uint8_t *)kTicketPlaceholder, + strlen(kTicketPlaceholder)); + } + + // Initialize HMAC and cipher contexts. If callback present it does all the + // work otherwise use generated values from parent ctx. + SSL_CTX *tctx = ssl->session_ctx; + uint8_t iv[EVP_MAX_IV_LENGTH]; + uint8_t key_name[16]; + if (tctx->tlsext_ticket_key_cb != NULL) { + if (tctx->tlsext_ticket_key_cb(ssl, key_name, iv, ctx.get(), hctx.get(), + 1 /* encrypt */) < 0) { + return 0; + } + } else { + // Rotate ticket key if necessary. + if (!ssl_ctx_rotate_ticket_encryption_key(tctx)) { + return 0; + } + MutexReadLock lock(&tctx->lock); + if (!RAND_bytes(iv, 16) || + !EVP_EncryptInit_ex(ctx.get(), EVP_aes_128_cbc(), NULL, + tctx->tlsext_ticket_key_current->aes_key, iv) || + !HMAC_Init_ex(hctx.get(), tctx->tlsext_ticket_key_current->hmac_key, 16, + tlsext_tick_md(), NULL)) { + return 0; + } + OPENSSL_memcpy(key_name, tctx->tlsext_ticket_key_current->name, 16); + } + + uint8_t *ptr; + if (!CBB_add_bytes(out, key_name, 16) || + !CBB_add_bytes(out, iv, EVP_CIPHER_CTX_iv_length(ctx.get())) || + !CBB_reserve(out, &ptr, session_len + EVP_MAX_BLOCK_LENGTH)) { + return 0; + } + + size_t total = 0; +#if defined(BORINGSSL_UNSAFE_FUZZER_MODE) + OPENSSL_memcpy(ptr, session_buf, session_len); + total = session_len; +#else + int len; + if (!EVP_EncryptUpdate(ctx.get(), ptr + total, &len, session_buf, session_len)) { + return 0; + } + total += len; + if (!EVP_EncryptFinal_ex(ctx.get(), ptr + total, &len)) { + return 0; + } + total += len; +#endif + if (!CBB_did_write(out, total)) { + return 0; + } + + unsigned hlen; + if (!HMAC_Update(hctx.get(), CBB_data(out), CBB_len(out)) || + !CBB_reserve(out, &ptr, EVP_MAX_MD_SIZE) || + !HMAC_Final(hctx.get(), ptr, &hlen) || + !CBB_did_write(out, hlen)) { + return 0; + } + + return 1; +} + +static int ssl_encrypt_ticket_with_method(SSL *ssl, CBB *out, + const uint8_t *session_buf, + size_t session_len) { + const SSL_TICKET_AEAD_METHOD *method = ssl->session_ctx->ticket_aead_method; + const size_t max_overhead = method->max_overhead(ssl); + const size_t max_out = session_len + max_overhead; + if (max_out < max_overhead) { + OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW); + return 0; + } + + uint8_t *ptr; + if (!CBB_reserve(out, &ptr, max_out)) { + return 0; + } + + size_t out_len; + if (!method->seal(ssl, ptr, &out_len, max_out, session_buf, session_len)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_TICKET_ENCRYPTION_FAILED); + return 0; + } + + if (!CBB_did_write(out, out_len)) { + return 0; + } + + return 1; +} + +int ssl_encrypt_ticket(SSL *ssl, CBB *out, const SSL_SESSION *session) { + // Serialize the SSL_SESSION to be encoded into the ticket. + uint8_t *session_buf = NULL; + size_t session_len; + if (!SSL_SESSION_to_bytes_for_ticket(session, &session_buf, &session_len)) { + return -1; + } + + int ret = 0; + if (ssl->session_ctx->ticket_aead_method) { + ret = ssl_encrypt_ticket_with_method(ssl, out, session_buf, session_len); + } else { + ret = + ssl_encrypt_ticket_with_cipher_ctx(ssl, out, session_buf, session_len); + } + + OPENSSL_free(session_buf); + return ret; +} + +int ssl_session_is_context_valid(const SSL *ssl, const SSL_SESSION *session) { + if (session == NULL) { + return 0; + } + + return session->sid_ctx_length == ssl->cert->sid_ctx_length && + OPENSSL_memcmp(session->sid_ctx, ssl->cert->sid_ctx, + ssl->cert->sid_ctx_length) == 0; +} + +int ssl_session_is_time_valid(const SSL *ssl, const SSL_SESSION *session) { + if (session == NULL) { + return 0; + } + + struct OPENSSL_timeval now; + ssl_get_current_time(ssl, &now); + + // Reject tickets from the future to avoid underflow. + if (now.tv_sec < session->time) { + return 0; + } + + return session->timeout > now.tv_sec - session->time; +} + +int ssl_session_is_resumable(const SSL_HANDSHAKE *hs, + const SSL_SESSION *session) { + const SSL *const ssl = hs->ssl; + return ssl_session_is_context_valid(ssl, session) && + // The session must have been created by the same type of end point as + // we're now using it with. + ssl->server == session->is_server && + // The session must not be expired. + ssl_session_is_time_valid(ssl, session) && + /* Only resume if the session's version matches the negotiated + * version. */ + ssl->version == session->ssl_version && + // Only resume if the session's cipher matches the negotiated one. + hs->new_cipher == session->cipher && + // If the session contains a client certificate (either the full + // certificate or just the hash) then require that the form of the + // certificate matches the current configuration. + ((sk_CRYPTO_BUFFER_num(session->certs) == 0 && + !session->peer_sha256_valid) || + session->peer_sha256_valid == + ssl->retain_only_sha256_of_client_certs); +} + +// ssl_lookup_session looks up |session_id| in the session cache and sets +// |*out_session| to an |SSL_SESSION| object if found. +static enum ssl_hs_wait_t ssl_lookup_session( + SSL *ssl, UniquePtr *out_session, const uint8_t *session_id, + size_t session_id_len) { + out_session->reset(); + + if (session_id_len == 0 || session_id_len > SSL_MAX_SSL_SESSION_ID_LENGTH) { + return ssl_hs_ok; + } + + UniquePtr session; + // Try the internal cache, if it exists. + if (!(ssl->session_ctx->session_cache_mode & + SSL_SESS_CACHE_NO_INTERNAL_LOOKUP)) { + SSL_SESSION data; + data.ssl_version = ssl->version; + data.session_id_length = session_id_len; + OPENSSL_memcpy(data.session_id, session_id, session_id_len); + + MutexReadLock lock(&ssl->session_ctx->lock); + session.reset(lh_SSL_SESSION_retrieve(ssl->session_ctx->sessions, &data)); + if (session) { + // |lh_SSL_SESSION_retrieve| returns a non-owning pointer. + SSL_SESSION_up_ref(session.get()); + } + // TODO(davidben): This should probably move it to the front of the list. + } + + // Fall back to the external cache, if it exists. + if (!session && (ssl->session_ctx->get_session_cb != nullptr || + ssl->session_ctx->get_session_cb_legacy != nullptr)) { + int copy = 1; + if (ssl->session_ctx->get_session_cb != nullptr) { + session.reset(ssl->session_ctx->get_session_cb(ssl, session_id, + session_id_len, ©)); + } else { + session.reset(ssl->session_ctx->get_session_cb_legacy( + ssl, const_cast(session_id), session_id_len, ©)); + } + + if (!session) { + return ssl_hs_ok; + } + + if (session.get() == SSL_magic_pending_session_ptr()) { + session.release(); // This pointer is not actually owned. + return ssl_hs_pending_session; + } + + // 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) { + SSL_SESSION_up_ref(session.get()); + } + + // Add the externally cached session to the internal cache if necessary. + if (!(ssl->session_ctx->session_cache_mode & + SSL_SESS_CACHE_NO_INTERNAL_STORE)) { + SSL_CTX_add_session(ssl->session_ctx, session.get()); + } + } + + if (session && !ssl_session_is_time_valid(ssl, session.get())) { + // The session was from the cache, so remove it. + SSL_CTX_remove_session(ssl->session_ctx, session.get()); + session.reset(); + } + + *out_session = std::move(session); + return ssl_hs_ok; +} + +enum ssl_hs_wait_t ssl_get_prev_session(SSL *ssl, + UniquePtr *out_session, + bool *out_tickets_supported, + bool *out_renew_ticket, + const SSL_CLIENT_HELLO *client_hello) { + // This is used only by servers. + assert(ssl->server); + UniquePtr session; + bool renew_ticket = false; + + // If tickets are disabled, always behave as if no tickets are present. + const uint8_t *ticket = NULL; + size_t ticket_len = 0; + const bool tickets_supported = + !(SSL_get_options(ssl) & SSL_OP_NO_TICKET) && + ssl->version > SSL3_VERSION && + SSL_early_callback_ctx_extension_get( + client_hello, TLSEXT_TYPE_session_ticket, &ticket, &ticket_len); + if (tickets_supported && ticket_len > 0) { + switch (ssl_process_ticket(ssl, &session, &renew_ticket, ticket, ticket_len, + client_hello->session_id, + client_hello->session_id_len)) { + case ssl_ticket_aead_success: + break; + case ssl_ticket_aead_ignore_ticket: + assert(!session); + break; + case ssl_ticket_aead_error: + return ssl_hs_error; + case ssl_ticket_aead_retry: + return ssl_hs_pending_ticket; + } + } else { + // The client didn't send a ticket, so the session ID is a real ID. + enum ssl_hs_wait_t lookup_ret = ssl_lookup_session( + ssl, &session, client_hello->session_id, client_hello->session_id_len); + if (lookup_ret != ssl_hs_ok) { + return lookup_ret; + } + } + + *out_session = std::move(session); + *out_tickets_supported = tickets_supported; + *out_renew_ticket = renew_ticket; + return ssl_hs_ok; +} + +static int remove_session_lock(SSL_CTX *ctx, SSL_SESSION *session, int lock) { + int ret = 0; + + if (session != NULL && session->session_id_length != 0) { + if (lock) { + CRYPTO_MUTEX_lock_write(&ctx->lock); + } + SSL_SESSION *found_session = lh_SSL_SESSION_retrieve(ctx->sessions, + session); + if (found_session == session) { + ret = 1; + found_session = lh_SSL_SESSION_delete(ctx->sessions, session); + SSL_SESSION_list_remove(ctx, session); + } + + if (lock) { + CRYPTO_MUTEX_unlock_write(&ctx->lock); + } + + if (ret) { + if (ctx->remove_session_cb != NULL) { + ctx->remove_session_cb(ctx, found_session); + } + SSL_SESSION_free(found_session); + } + } + + return ret; +} + +void ssl_set_session(SSL *ssl, SSL_SESSION *session) { + if (ssl->session == session) { + return; + } + + SSL_SESSION_free(ssl->session); + ssl->session = session; + if (session != NULL) { + SSL_SESSION_up_ref(session); + } +} + +// locked by SSL_CTX in the calling function +static void SSL_SESSION_list_remove(SSL_CTX *ctx, SSL_SESSION *session) { + if (session->next == NULL || session->prev == NULL) { + return; + } + + if (session->next == (SSL_SESSION *)&ctx->session_cache_tail) { + // last element in list + if (session->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 = session->prev; + session->prev->next = (SSL_SESSION *)&(ctx->session_cache_tail); + } + } else { + if (session->prev == (SSL_SESSION *)&ctx->session_cache_head) { + // first element in list + ctx->session_cache_head = session->next; + session->next->prev = (SSL_SESSION *)&(ctx->session_cache_head); + } else { // middle of list + session->next->prev = session->prev; + session->prev->next = session->next; + } + } + session->prev = session->next = NULL; +} + +static void SSL_SESSION_list_add(SSL_CTX *ctx, SSL_SESSION *session) { + if (session->next != NULL && session->prev != NULL) { + SSL_SESSION_list_remove(ctx, session); + } + + if (ctx->session_cache_head == NULL) { + ctx->session_cache_head = session; + ctx->session_cache_tail = session; + session->prev = (SSL_SESSION *)&(ctx->session_cache_head); + session->next = (SSL_SESSION *)&(ctx->session_cache_tail); + } else { + session->next = ctx->session_cache_head; + session->next->prev = session; + session->prev = (SSL_SESSION *)&(ctx->session_cache_head); + ctx->session_cache_head = session; + } +} + +} // namespace bssl + +using namespace bssl; + +SSL_SESSION *SSL_SESSION_new(const SSL_CTX *ctx) { + return ssl_session_new(ctx->x509_method).release(); +} + +int SSL_SESSION_up_ref(SSL_SESSION *session) { + CRYPTO_refcount_inc(&session->references); + return 1; +} + +void SSL_SESSION_free(SSL_SESSION *session) { + if (session == NULL || + !CRYPTO_refcount_dec_and_test_zero(&session->references)) { + return; + } + + CRYPTO_free_ex_data(&g_ex_data_class, session, &session->ex_data); + + OPENSSL_cleanse(session->master_key, sizeof(session->master_key)); + OPENSSL_cleanse(session->session_id, sizeof(session->session_id)); + sk_CRYPTO_BUFFER_pop_free(session->certs, CRYPTO_BUFFER_free); + session->x509_method->session_clear(session); + OPENSSL_free(session->tlsext_tick); + CRYPTO_BUFFER_free(session->signed_cert_timestamp_list); + CRYPTO_BUFFER_free(session->ocsp_response); + OPENSSL_free(session->psk_identity); + OPENSSL_free(session->early_alpn); + OPENSSL_free(session); +} + +const uint8_t *SSL_SESSION_get_id(const SSL_SESSION *session, + unsigned *out_len) { + if (out_len != NULL) { + *out_len = session->session_id_length; + } + return session->session_id; +} + +uint32_t SSL_SESSION_get_timeout(const SSL_SESSION *session) { + return session->timeout; +} + +uint64_t SSL_SESSION_get_time(const SSL_SESSION *session) { + if (session == NULL) { + // NULL should crash, but silently accept it here for compatibility. + return 0; + } + return session->time; +} + +X509 *SSL_SESSION_get0_peer(const SSL_SESSION *session) { + return session->x509_peer; +} + +size_t SSL_SESSION_get_master_key(const SSL_SESSION *session, uint8_t *out, + size_t max_out) { + // TODO(davidben): Fix master_key_length's type and remove these casts. + if (max_out == 0) { + return (size_t)session->master_key_length; + } + if (max_out > (size_t)session->master_key_length) { + max_out = (size_t)session->master_key_length; + } + OPENSSL_memcpy(out, session->master_key, max_out); + return max_out; +} + +uint64_t SSL_SESSION_set_time(SSL_SESSION *session, uint64_t time) { + if (session == NULL) { + return 0; + } + + session->time = time; + return time; +} + +uint32_t SSL_SESSION_set_timeout(SSL_SESSION *session, uint32_t timeout) { + if (session == NULL) { + return 0; + } + + session->timeout = timeout; + session->auth_timeout = timeout; + return 1; +} + +int SSL_SESSION_set1_id_context(SSL_SESSION *session, const uint8_t *sid_ctx, + size_t sid_ctx_len) { + if (sid_ctx_len > sizeof(session->sid_ctx)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_SSL_SESSION_ID_CONTEXT_TOO_LONG); + return 0; + } + + static_assert(sizeof(session->sid_ctx) < 256, "sid_ctx_len does not fit"); + session->sid_ctx_length = (uint8_t)sid_ctx_len; + OPENSSL_memcpy(session->sid_ctx, sid_ctx, sid_ctx_len); + + return 1; +} + +int SSL_SESSION_should_be_single_use(const SSL_SESSION *session) { + return ssl_session_protocol_version(session) >= TLS1_3_VERSION; +} + +int SSL_SESSION_is_resumable(const SSL_SESSION *session) { + return !session->not_resumable; +} + +int SSL_SESSION_has_ticket(const SSL_SESSION *session) { + return session->tlsext_ticklen > 0; +} + +void SSL_SESSION_get0_ticket(const SSL_SESSION *session, + const uint8_t **out_ticket, size_t *out_len) { + if (out_ticket != nullptr) { + *out_ticket = session->tlsext_tick; + } + *out_len = session->tlsext_ticklen; +} + +uint32_t SSL_SESSION_get_ticket_lifetime_hint(const SSL_SESSION *session) { + return session->tlsext_tick_lifetime_hint; +} + +SSL_SESSION *SSL_magic_pending_session_ptr(void) { + return (SSL_SESSION *)&g_pending_session_magic; +} + +SSL_SESSION *SSL_get_session(const SSL *ssl) { + // Once the handshake completes we return the established session. Otherwise + // we return the intermediate session, either |session| (for resumption) or + // |new_session| if doing a full handshake. + if (!SSL_in_init(ssl)) { + return ssl->s3->established_session.get(); + } + SSL_HANDSHAKE *hs = ssl->s3->hs.get(); + if (hs->early_session) { + return hs->early_session.get(); + } + if (hs->new_session) { + return hs->new_session.get(); + } + return ssl->session; +} + +SSL_SESSION *SSL_get1_session(SSL *ssl) { + SSL_SESSION *ret = SSL_get_session(ssl); + if (ret != NULL) { + SSL_SESSION_up_ref(ret); + } + return ret; +} + +int SSL_SESSION_get_ex_new_index(long argl, void *argp, + CRYPTO_EX_unused *unused, + CRYPTO_EX_dup *dup_unused, + CRYPTO_EX_free *free_func) { + int index; + if (!CRYPTO_get_ex_new_index(&g_ex_data_class, &index, argl, argp, + free_func)) { + return -1; + } + return index; +} + +int SSL_SESSION_set_ex_data(SSL_SESSION *session, int idx, void *arg) { + return CRYPTO_set_ex_data(&session->ex_data, idx, arg); +} + +void *SSL_SESSION_get_ex_data(const SSL_SESSION *session, int idx) { + return CRYPTO_get_ex_data(&session->ex_data, idx); +} + +int SSL_CTX_add_session(SSL_CTX *ctx, SSL_SESSION *session) { + // Although |session| is inserted into two structures (a doubly-linked list + // and the hash table), |ctx| only takes one reference. + SSL_SESSION_up_ref(session); + UniquePtr owned_session(session); + + SSL_SESSION *old_session; + MutexWriteLock lock(&ctx->lock); + if (!lh_SSL_SESSION_insert(ctx->sessions, &old_session, session)) { + return 0; + } + // |ctx->sessions| took ownership of |session| and gave us back a reference to + // |old_session|. (|old_session| may be the same as |session|, in which case + // we traded identical references with |ctx->sessions|.) + owned_session.release(); + owned_session.reset(old_session); + + if (old_session != NULL) { + if (old_session == session) { + // |session| was already in the cache. There are no linked list pointers + // to update. + return 0; + } + + // There was a session ID collision. |old_session| was replaced with + // |session| in the hash table, so |old_session| must be removed from the + // linked list to match. + SSL_SESSION_list_remove(ctx, old_session); + } + + SSL_SESSION_list_add(ctx, session); + + // Enforce any cache size limits. + if (SSL_CTX_sess_get_cache_size(ctx) > 0) { + while (lh_SSL_SESSION_num_items(ctx->sessions) > + SSL_CTX_sess_get_cache_size(ctx)) { + if (!remove_session_lock(ctx, ctx->session_cache_tail, 0)) { + break; + } + } + } + + return 1; +} + +int SSL_CTX_remove_session(SSL_CTX *ctx, SSL_SESSION *session) { + return remove_session_lock(ctx, session, 1); +} + +int SSL_set_session(SSL *ssl, SSL_SESSION *session) { + // SSL_set_session may only be called before the handshake has started. + if (ssl->s3->initial_handshake_complete || + ssl->s3->hs == NULL || + ssl->s3->hs->state != 0) { + abort(); + } + + ssl_set_session(ssl, session); + return 1; +} + +uint32_t SSL_CTX_set_timeout(SSL_CTX *ctx, uint32_t timeout) { + if (ctx == NULL) { + return 0; + } + + // Historically, zero was treated as |SSL_DEFAULT_SESSION_TIMEOUT|. + if (timeout == 0) { + timeout = SSL_DEFAULT_SESSION_TIMEOUT; + } + + uint32_t old_timeout = ctx->session_timeout; + ctx->session_timeout = timeout; + return old_timeout; +} + +uint32_t SSL_CTX_get_timeout(const SSL_CTX *ctx) { + if (ctx == NULL) { + return 0; + } + + return ctx->session_timeout; +} + +void SSL_CTX_set_session_psk_dhe_timeout(SSL_CTX *ctx, uint32_t timeout) { + ctx->session_psk_dhe_timeout = timeout; +} + +typedef struct timeout_param_st { + SSL_CTX *ctx; + uint64_t time; + LHASH_OF(SSL_SESSION) *cache; +} TIMEOUT_PARAM; + +static void timeout_doall_arg(SSL_SESSION *session, void *void_param) { + TIMEOUT_PARAM *param = reinterpret_cast(void_param); + + if (param->time == 0 || + session->time + session->timeout < session->time || + param->time > (session->time + session->timeout)) { + // The reason we don't call SSL_CTX_remove_session() is to + // save on locking overhead + (void) lh_SSL_SESSION_delete(param->cache, session); + SSL_SESSION_list_remove(param->ctx, session); + if (param->ctx->remove_session_cb != NULL) { + param->ctx->remove_session_cb(param->ctx, session); + } + SSL_SESSION_free(session); + } +} + +void SSL_CTX_flush_sessions(SSL_CTX *ctx, uint64_t time) { + TIMEOUT_PARAM tp; + + tp.ctx = ctx; + tp.cache = ctx->sessions; + if (tp.cache == NULL) { + return; + } + tp.time = time; + MutexWriteLock lock(&ctx->lock); + lh_SSL_SESSION_doall_arg(tp.cache, timeout_doall_arg, &tp); +} + +void SSL_CTX_sess_set_new_cb(SSL_CTX *ctx, + int (*cb)(SSL *ssl, SSL_SESSION *session)) { + ctx->new_session_cb = cb; +} + +int (*SSL_CTX_sess_get_new_cb(SSL_CTX *ctx))(SSL *ssl, SSL_SESSION *session) { + return ctx->new_session_cb; +} + +void SSL_CTX_sess_set_remove_cb( + SSL_CTX *ctx, void (*cb)(SSL_CTX *ctx, SSL_SESSION *session)) { + ctx->remove_session_cb = cb; +} + +void (*SSL_CTX_sess_get_remove_cb(SSL_CTX *ctx))(SSL_CTX *ctx, + SSL_SESSION *session) { + return ctx->remove_session_cb; +} + +void SSL_CTX_sess_set_get_cb(SSL_CTX *ctx, + SSL_SESSION *(*cb)(SSL *ssl, const uint8_t *id, + int id_len, int *out_copy)) { + ctx->get_session_cb = cb; +} + +void SSL_CTX_sess_set_get_cb(SSL_CTX *ctx, + SSL_SESSION *(*cb)(SSL *ssl, uint8_t *id, + int id_len, int *out_copy)) { + ctx->get_session_cb_legacy = cb; +} + +SSL_SESSION *(*SSL_CTX_sess_get_get_cb(SSL_CTX *ctx))(SSL *ssl, + const uint8_t *id, + int id_len, + int *out_copy) { + return ctx->get_session_cb; +} + +void SSL_CTX_set_info_callback( + SSL_CTX *ctx, void (*cb)(const SSL *ssl, int type, int value)) { + ctx->info_callback = cb; +} + +void (*SSL_CTX_get_info_callback(SSL_CTX *ctx))(const SSL *ssl, int type, + int value) { + return ctx->info_callback; +} + +void SSL_CTX_set_channel_id_cb(SSL_CTX *ctx, + void (*cb)(SSL *ssl, EVP_PKEY **pkey)) { + ctx->channel_id_cb = cb; +} + +void (*SSL_CTX_get_channel_id_cb(SSL_CTX *ctx))(SSL *ssl, EVP_PKEY **pkey) { + return ctx->channel_id_cb; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/ssl/ssl_stat.cc b/FoodApp/Pods/BoringSSL-GRPC/ssl/ssl_stat.cc new file mode 100644 index 0000000..26cfa80 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/ssl/ssl_stat.cc @@ -0,0 +1,224 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 "internal.h" + + +const char *SSL_state_string_long(const SSL *ssl) { + if (ssl->s3->hs == nullptr) { + return "SSL negotiation finished successfully"; + } + + return ssl->server ? ssl_server_handshake_state(ssl->s3->hs.get()) + : ssl_client_handshake_state(ssl->s3->hs.get()); +} + +const char *SSL_state_string(const SSL *ssl) { + return "!!!!!!"; +} + +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"; + } + + return "unknown"; +} + +const char *SSL_alert_type_string(int value) { + return "!"; +} + +const char *SSL_alert_desc_string(int value) { + return "!!"; +} + +const char *SSL_alert_desc_string_long(int value) { + switch (value & 0xff) { + case SSL3_AD_CLOSE_NOTIFY: + return "close notify"; + + case SSL3_AD_UNEXPECTED_MESSAGE: + return "unexpected_message"; + + case SSL3_AD_BAD_RECORD_MAC: + return "bad record mac"; + + case SSL3_AD_DECOMPRESSION_FAILURE: + return "decompression failure"; + + case SSL3_AD_HANDSHAKE_FAILURE: + return "handshake failure"; + + case SSL3_AD_NO_CERTIFICATE: + return "no certificate"; + + case SSL3_AD_BAD_CERTIFICATE: + return "bad certificate"; + + case SSL3_AD_UNSUPPORTED_CERTIFICATE: + return "unsupported certificate"; + + case SSL3_AD_CERTIFICATE_REVOKED: + return "certificate revoked"; + + case SSL3_AD_CERTIFICATE_EXPIRED: + return "certificate expired"; + + case SSL3_AD_CERTIFICATE_UNKNOWN: + return "certificate unknown"; + + case SSL3_AD_ILLEGAL_PARAMETER: + return "illegal parameter"; + + case TLS1_AD_DECRYPTION_FAILED: + return "decryption failed"; + + case TLS1_AD_RECORD_OVERFLOW: + return "record overflow"; + + case TLS1_AD_UNKNOWN_CA: + return "unknown CA"; + + case TLS1_AD_ACCESS_DENIED: + return "access denied"; + + case TLS1_AD_DECODE_ERROR: + return "decode error"; + + case TLS1_AD_DECRYPT_ERROR: + return "decrypt error"; + + case TLS1_AD_EXPORT_RESTRICTION: + return "export restriction"; + + case TLS1_AD_PROTOCOL_VERSION: + return "protocol version"; + + case TLS1_AD_INSUFFICIENT_SECURITY: + return "insufficient security"; + + case TLS1_AD_INTERNAL_ERROR: + return "internal error"; + + case SSL3_AD_INAPPROPRIATE_FALLBACK: + return "inappropriate fallback"; + + case TLS1_AD_USER_CANCELLED: + return "user canceled"; + + case TLS1_AD_NO_RENEGOTIATION: + return "no renegotiation"; + + case TLS1_AD_UNSUPPORTED_EXTENSION: + return "unsupported extension"; + + case TLS1_AD_CERTIFICATE_UNOBTAINABLE: + return "certificate unobtainable"; + + case TLS1_AD_UNRECOGNIZED_NAME: + return "unrecognized name"; + + case TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE: + return "bad certificate status response"; + + case TLS1_AD_BAD_CERTIFICATE_HASH_VALUE: + return "bad certificate hash value"; + + case TLS1_AD_UNKNOWN_PSK_IDENTITY: + return "unknown PSK identity"; + + case TLS1_AD_CERTIFICATE_REQUIRED: + return "certificate required"; + + default: + return "unknown"; + } +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/ssl/ssl_stat.cc.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/ssl/ssl_stat.cc.grpc_back new file mode 100644 index 0000000..e1677f0 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/ssl/ssl_stat.cc.grpc_back @@ -0,0 +1,224 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 "internal.h" + + +const char *SSL_state_string_long(const SSL *ssl) { + if (ssl->s3->hs == nullptr) { + return "SSL negotiation finished successfully"; + } + + return ssl->server ? ssl_server_handshake_state(ssl->s3->hs.get()) + : ssl_client_handshake_state(ssl->s3->hs.get()); +} + +const char *SSL_state_string(const SSL *ssl) { + return "!!!!!!"; +} + +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"; + } + + return "unknown"; +} + +const char *SSL_alert_type_string(int value) { + return "!"; +} + +const char *SSL_alert_desc_string(int value) { + return "!!"; +} + +const char *SSL_alert_desc_string_long(int value) { + switch (value & 0xff) { + case SSL3_AD_CLOSE_NOTIFY: + return "close notify"; + + case SSL3_AD_UNEXPECTED_MESSAGE: + return "unexpected_message"; + + case SSL3_AD_BAD_RECORD_MAC: + return "bad record mac"; + + case SSL3_AD_DECOMPRESSION_FAILURE: + return "decompression failure"; + + case SSL3_AD_HANDSHAKE_FAILURE: + return "handshake failure"; + + case SSL3_AD_NO_CERTIFICATE: + return "no certificate"; + + case SSL3_AD_BAD_CERTIFICATE: + return "bad certificate"; + + case SSL3_AD_UNSUPPORTED_CERTIFICATE: + return "unsupported certificate"; + + case SSL3_AD_CERTIFICATE_REVOKED: + return "certificate revoked"; + + case SSL3_AD_CERTIFICATE_EXPIRED: + return "certificate expired"; + + case SSL3_AD_CERTIFICATE_UNKNOWN: + return "certificate unknown"; + + case SSL3_AD_ILLEGAL_PARAMETER: + return "illegal parameter"; + + case TLS1_AD_DECRYPTION_FAILED: + return "decryption failed"; + + case TLS1_AD_RECORD_OVERFLOW: + return "record overflow"; + + case TLS1_AD_UNKNOWN_CA: + return "unknown CA"; + + case TLS1_AD_ACCESS_DENIED: + return "access denied"; + + case TLS1_AD_DECODE_ERROR: + return "decode error"; + + case TLS1_AD_DECRYPT_ERROR: + return "decrypt error"; + + case TLS1_AD_EXPORT_RESTRICTION: + return "export restriction"; + + case TLS1_AD_PROTOCOL_VERSION: + return "protocol version"; + + case TLS1_AD_INSUFFICIENT_SECURITY: + return "insufficient security"; + + case TLS1_AD_INTERNAL_ERROR: + return "internal error"; + + case SSL3_AD_INAPPROPRIATE_FALLBACK: + return "inappropriate fallback"; + + case TLS1_AD_USER_CANCELLED: + return "user canceled"; + + case TLS1_AD_NO_RENEGOTIATION: + return "no renegotiation"; + + case TLS1_AD_UNSUPPORTED_EXTENSION: + return "unsupported extension"; + + case TLS1_AD_CERTIFICATE_UNOBTAINABLE: + return "certificate unobtainable"; + + case TLS1_AD_UNRECOGNIZED_NAME: + return "unrecognized name"; + + case TLS1_AD_BAD_CERTIFICATE_STATUS_RESPONSE: + return "bad certificate status response"; + + case TLS1_AD_BAD_CERTIFICATE_HASH_VALUE: + return "bad certificate hash value"; + + case TLS1_AD_UNKNOWN_PSK_IDENTITY: + return "unknown PSK identity"; + + case TLS1_AD_CERTIFICATE_REQUIRED: + return "certificate required"; + + default: + return "unknown"; + } +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/ssl/ssl_transcript.cc b/FoodApp/Pods/BoringSSL-GRPC/ssl/ssl_transcript.cc new file mode 100644 index 0000000..36ffde1 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/ssl/ssl_transcript.cc @@ -0,0 +1,398 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "../crypto/internal.h" +#include "internal.h" + + +namespace bssl { + +SSLTranscript::SSLTranscript() {} + +SSLTranscript::~SSLTranscript() {} + +bool SSLTranscript::Init() { + buffer_.reset(BUF_MEM_new()); + if (!buffer_) { + return false; + } + + hash_.Reset(); + md5_.Reset(); + return true; +} + +// InitDigestWithData calls |EVP_DigestInit_ex| on |ctx| with |md| and then +// writes the data in |buf| to it. +static bool InitDigestWithData(EVP_MD_CTX *ctx, const EVP_MD *md, + const BUF_MEM *buf) { + if (!EVP_DigestInit_ex(ctx, md, NULL)) { + return false; + } + EVP_DigestUpdate(ctx, buf->data, buf->length); + return true; +} + +bool SSLTranscript::InitHash(uint16_t version, const SSL_CIPHER *cipher) { + const EVP_MD *md = ssl_get_handshake_digest(version, cipher); + + // To support SSL 3.0's Finished and CertificateVerify constructions, + // EVP_md5_sha1() is split into MD5 and SHA-1 halves. When SSL 3.0 is removed, + // we can simplify this. + if (md == EVP_md5_sha1()) { + if (!InitDigestWithData(md5_.get(), EVP_md5(), buffer_.get())) { + return false; + } + md = EVP_sha1(); + } + + return InitDigestWithData(hash_.get(), md, buffer_.get()); +} + +void SSLTranscript::FreeBuffer() { + buffer_.reset(); +} + +size_t SSLTranscript::DigestLen() const { + return EVP_MD_size(Digest()); +} + +const EVP_MD *SSLTranscript::Digest() const { + if (EVP_MD_CTX_md(md5_.get()) != nullptr) { + return EVP_md5_sha1(); + } + return EVP_MD_CTX_md(hash_.get()); +} + +bool SSLTranscript::UpdateForHelloRetryRequest() { + if (buffer_) { + buffer_->length = 0; + } + + uint8_t old_hash[EVP_MAX_MD_SIZE]; + size_t hash_len; + if (!GetHash(old_hash, &hash_len)) { + return false; + } + const uint8_t header[4] = {SSL3_MT_MESSAGE_HASH, 0, 0, + static_cast(hash_len)}; + if (!EVP_DigestInit_ex(hash_.get(), Digest(), nullptr) || + !Update(header) || + !Update(MakeConstSpan(old_hash, hash_len))) { + return false; + } + return true; +} + +bool SSLTranscript::CopyHashContext(EVP_MD_CTX *ctx) { + return EVP_MD_CTX_copy_ex(ctx, hash_.get()); +} + +bool SSLTranscript::Update(Span in) { + // Depending on the state of the handshake, either the handshake buffer may be + // active, the rolling hash, or both. + if (buffer_ && + !BUF_MEM_append(buffer_.get(), in.data(), in.size())) { + return false; + } + + if (EVP_MD_CTX_md(hash_.get()) != NULL) { + EVP_DigestUpdate(hash_.get(), in.data(), in.size()); + } + if (EVP_MD_CTX_md(md5_.get()) != NULL) { + EVP_DigestUpdate(md5_.get(), in.data(), in.size()); + } + + return true; +} + +bool SSLTranscript::GetHash(uint8_t *out, size_t *out_len) { + ScopedEVP_MD_CTX ctx; + unsigned md5_len = 0; + if (EVP_MD_CTX_md(md5_.get()) != NULL) { + if (!EVP_MD_CTX_copy_ex(ctx.get(), md5_.get()) || + !EVP_DigestFinal_ex(ctx.get(), out, &md5_len)) { + return false; + } + } + + unsigned len; + if (!EVP_MD_CTX_copy_ex(ctx.get(), hash_.get()) || + !EVP_DigestFinal_ex(ctx.get(), out + md5_len, &len)) { + return false; + } + + *out_len = md5_len + len; + return true; +} + +static bool SSL3HandshakeMAC(const SSL_SESSION *session, + const EVP_MD_CTX *ctx_template, const char *sender, + size_t sender_len, uint8_t *p, size_t *out_len) { + ScopedEVP_MD_CTX ctx; + if (!EVP_MD_CTX_copy_ex(ctx.get(), ctx_template)) { + OPENSSL_PUT_ERROR(SSL, ERR_LIB_EVP); + return false; + } + + static const uint8_t kPad1[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 const uint8_t kPad2[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, + }; + + size_t n = EVP_MD_CTX_size(ctx.get()); + + size_t npad = (48 / n) * n; + EVP_DigestUpdate(ctx.get(), sender, sender_len); + EVP_DigestUpdate(ctx.get(), session->master_key, session->master_key_length); + EVP_DigestUpdate(ctx.get(), kPad1, npad); + unsigned md_buf_len; + uint8_t md_buf[EVP_MAX_MD_SIZE]; + EVP_DigestFinal_ex(ctx.get(), md_buf, &md_buf_len); + + if (!EVP_DigestInit_ex(ctx.get(), EVP_MD_CTX_md(ctx.get()), NULL)) { + OPENSSL_PUT_ERROR(SSL, ERR_LIB_EVP); + return false; + } + EVP_DigestUpdate(ctx.get(), session->master_key, session->master_key_length); + EVP_DigestUpdate(ctx.get(), kPad2, npad); + EVP_DigestUpdate(ctx.get(), md_buf, md_buf_len); + unsigned len; + EVP_DigestFinal_ex(ctx.get(), p, &len); + + *out_len = len; + return true; +} + +bool SSLTranscript::GetSSL3CertVerifyHash(uint8_t *out, size_t *out_len, + const SSL_SESSION *session, + uint16_t signature_algorithm) { + if (Digest() != EVP_md5_sha1()) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return false; + } + + if (signature_algorithm == SSL_SIGN_RSA_PKCS1_MD5_SHA1) { + size_t md5_len, len; + if (!SSL3HandshakeMAC(session, md5_.get(), NULL, 0, out, &md5_len) || + !SSL3HandshakeMAC(session, hash_.get(), NULL, 0, out + md5_len, &len)) { + return false; + } + *out_len = md5_len + len; + return true; + } + + if (signature_algorithm == SSL_SIGN_ECDSA_SHA1) { + return SSL3HandshakeMAC(session, hash_.get(), NULL, 0, out, out_len); + } + + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return false; +} + +bool SSLTranscript::GetFinishedMAC(uint8_t *out, size_t *out_len, + const SSL_SESSION *session, + bool from_server) { + if (session->ssl_version == SSL3_VERSION) { + if (Digest() != EVP_md5_sha1()) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return false; + } + + const char *sender = from_server ? SSL3_MD_SERVER_FINISHED_CONST + : SSL3_MD_CLIENT_FINISHED_CONST; + const size_t sender_len = 4; + size_t md5_len, len; + if (!SSL3HandshakeMAC(session, md5_.get(), sender, sender_len, out, + &md5_len) || + !SSL3HandshakeMAC(session, hash_.get(), sender, sender_len, + out + md5_len, &len)) { + return false; + } + + *out_len = md5_len + len; + return true; + } + + // At this point, the handshake should have released the handshake buffer on + // its own. + assert(!buffer_); + + static const char kClientLabel[] = "client finished"; + static const char kServerLabel[] = "server finished"; + auto label = from_server + ? MakeConstSpan(kServerLabel, sizeof(kServerLabel) - 1) + : MakeConstSpan(kClientLabel, sizeof(kClientLabel) - 1); + + uint8_t digests[EVP_MAX_MD_SIZE]; + size_t digests_len; + if (!GetHash(digests, &digests_len)) { + return false; + } + + static const size_t kFinishedLen = 12; + if (!tls1_prf(Digest(), MakeSpan(out, kFinishedLen), + MakeConstSpan(session->master_key, session->master_key_length), + label, MakeConstSpan(digests, digests_len), {})) { + return false; + } + + *out_len = kFinishedLen; + return true; +} + +} // namespace bssl diff --git a/FoodApp/Pods/BoringSSL-GRPC/ssl/ssl_transcript.cc.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/ssl/ssl_transcript.cc.grpc_back new file mode 100644 index 0000000..2033dfd --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/ssl/ssl_transcript.cc.grpc_back @@ -0,0 +1,398 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "../crypto/internal.h" +#include "internal.h" + + +namespace bssl { + +SSLTranscript::SSLTranscript() {} + +SSLTranscript::~SSLTranscript() {} + +bool SSLTranscript::Init() { + buffer_.reset(BUF_MEM_new()); + if (!buffer_) { + return false; + } + + hash_.Reset(); + md5_.Reset(); + return true; +} + +// InitDigestWithData calls |EVP_DigestInit_ex| on |ctx| with |md| and then +// writes the data in |buf| to it. +static bool InitDigestWithData(EVP_MD_CTX *ctx, const EVP_MD *md, + const BUF_MEM *buf) { + if (!EVP_DigestInit_ex(ctx, md, NULL)) { + return false; + } + EVP_DigestUpdate(ctx, buf->data, buf->length); + return true; +} + +bool SSLTranscript::InitHash(uint16_t version, const SSL_CIPHER *cipher) { + const EVP_MD *md = ssl_get_handshake_digest(version, cipher); + + // To support SSL 3.0's Finished and CertificateVerify constructions, + // EVP_md5_sha1() is split into MD5 and SHA-1 halves. When SSL 3.0 is removed, + // we can simplify this. + if (md == EVP_md5_sha1()) { + if (!InitDigestWithData(md5_.get(), EVP_md5(), buffer_.get())) { + return false; + } + md = EVP_sha1(); + } + + return InitDigestWithData(hash_.get(), md, buffer_.get()); +} + +void SSLTranscript::FreeBuffer() { + buffer_.reset(); +} + +size_t SSLTranscript::DigestLen() const { + return EVP_MD_size(Digest()); +} + +const EVP_MD *SSLTranscript::Digest() const { + if (EVP_MD_CTX_md(md5_.get()) != nullptr) { + return EVP_md5_sha1(); + } + return EVP_MD_CTX_md(hash_.get()); +} + +bool SSLTranscript::UpdateForHelloRetryRequest() { + if (buffer_) { + buffer_->length = 0; + } + + uint8_t old_hash[EVP_MAX_MD_SIZE]; + size_t hash_len; + if (!GetHash(old_hash, &hash_len)) { + return false; + } + const uint8_t header[4] = {SSL3_MT_MESSAGE_HASH, 0, 0, + static_cast(hash_len)}; + if (!EVP_DigestInit_ex(hash_.get(), Digest(), nullptr) || + !Update(header) || + !Update(MakeConstSpan(old_hash, hash_len))) { + return false; + } + return true; +} + +bool SSLTranscript::CopyHashContext(EVP_MD_CTX *ctx) { + return EVP_MD_CTX_copy_ex(ctx, hash_.get()); +} + +bool SSLTranscript::Update(Span in) { + // Depending on the state of the handshake, either the handshake buffer may be + // active, the rolling hash, or both. + if (buffer_ && + !BUF_MEM_append(buffer_.get(), in.data(), in.size())) { + return false; + } + + if (EVP_MD_CTX_md(hash_.get()) != NULL) { + EVP_DigestUpdate(hash_.get(), in.data(), in.size()); + } + if (EVP_MD_CTX_md(md5_.get()) != NULL) { + EVP_DigestUpdate(md5_.get(), in.data(), in.size()); + } + + return true; +} + +bool SSLTranscript::GetHash(uint8_t *out, size_t *out_len) { + ScopedEVP_MD_CTX ctx; + unsigned md5_len = 0; + if (EVP_MD_CTX_md(md5_.get()) != NULL) { + if (!EVP_MD_CTX_copy_ex(ctx.get(), md5_.get()) || + !EVP_DigestFinal_ex(ctx.get(), out, &md5_len)) { + return false; + } + } + + unsigned len; + if (!EVP_MD_CTX_copy_ex(ctx.get(), hash_.get()) || + !EVP_DigestFinal_ex(ctx.get(), out + md5_len, &len)) { + return false; + } + + *out_len = md5_len + len; + return true; +} + +static bool SSL3HandshakeMAC(const SSL_SESSION *session, + const EVP_MD_CTX *ctx_template, const char *sender, + size_t sender_len, uint8_t *p, size_t *out_len) { + ScopedEVP_MD_CTX ctx; + if (!EVP_MD_CTX_copy_ex(ctx.get(), ctx_template)) { + OPENSSL_PUT_ERROR(SSL, ERR_LIB_EVP); + return false; + } + + static const uint8_t kPad1[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 const uint8_t kPad2[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, + }; + + size_t n = EVP_MD_CTX_size(ctx.get()); + + size_t npad = (48 / n) * n; + EVP_DigestUpdate(ctx.get(), sender, sender_len); + EVP_DigestUpdate(ctx.get(), session->master_key, session->master_key_length); + EVP_DigestUpdate(ctx.get(), kPad1, npad); + unsigned md_buf_len; + uint8_t md_buf[EVP_MAX_MD_SIZE]; + EVP_DigestFinal_ex(ctx.get(), md_buf, &md_buf_len); + + if (!EVP_DigestInit_ex(ctx.get(), EVP_MD_CTX_md(ctx.get()), NULL)) { + OPENSSL_PUT_ERROR(SSL, ERR_LIB_EVP); + return false; + } + EVP_DigestUpdate(ctx.get(), session->master_key, session->master_key_length); + EVP_DigestUpdate(ctx.get(), kPad2, npad); + EVP_DigestUpdate(ctx.get(), md_buf, md_buf_len); + unsigned len; + EVP_DigestFinal_ex(ctx.get(), p, &len); + + *out_len = len; + return true; +} + +bool SSLTranscript::GetSSL3CertVerifyHash(uint8_t *out, size_t *out_len, + const SSL_SESSION *session, + uint16_t signature_algorithm) { + if (Digest() != EVP_md5_sha1()) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return false; + } + + if (signature_algorithm == SSL_SIGN_RSA_PKCS1_MD5_SHA1) { + size_t md5_len, len; + if (!SSL3HandshakeMAC(session, md5_.get(), NULL, 0, out, &md5_len) || + !SSL3HandshakeMAC(session, hash_.get(), NULL, 0, out + md5_len, &len)) { + return false; + } + *out_len = md5_len + len; + return true; + } + + if (signature_algorithm == SSL_SIGN_ECDSA_SHA1) { + return SSL3HandshakeMAC(session, hash_.get(), NULL, 0, out, out_len); + } + + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return false; +} + +bool SSLTranscript::GetFinishedMAC(uint8_t *out, size_t *out_len, + const SSL_SESSION *session, + bool from_server) { + if (session->ssl_version == SSL3_VERSION) { + if (Digest() != EVP_md5_sha1()) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return false; + } + + const char *sender = from_server ? SSL3_MD_SERVER_FINISHED_CONST + : SSL3_MD_CLIENT_FINISHED_CONST; + const size_t sender_len = 4; + size_t md5_len, len; + if (!SSL3HandshakeMAC(session, md5_.get(), sender, sender_len, out, + &md5_len) || + !SSL3HandshakeMAC(session, hash_.get(), sender, sender_len, + out + md5_len, &len)) { + return false; + } + + *out_len = md5_len + len; + return true; + } + + // At this point, the handshake should have released the handshake buffer on + // its own. + assert(!buffer_); + + static const char kClientLabel[] = "client finished"; + static const char kServerLabel[] = "server finished"; + auto label = from_server + ? MakeConstSpan(kServerLabel, sizeof(kServerLabel) - 1) + : MakeConstSpan(kClientLabel, sizeof(kClientLabel) - 1); + + uint8_t digests[EVP_MAX_MD_SIZE]; + size_t digests_len; + if (!GetHash(digests, &digests_len)) { + return false; + } + + static const size_t kFinishedLen = 12; + if (!tls1_prf(Digest(), MakeSpan(out, kFinishedLen), + MakeConstSpan(session->master_key, session->master_key_length), + label, MakeConstSpan(digests, digests_len), {})) { + return false; + } + + *out_len = kFinishedLen; + return true; +} + +} // namespace bssl diff --git a/FoodApp/Pods/BoringSSL-GRPC/ssl/ssl_versions.cc b/FoodApp/Pods/BoringSSL-GRPC/ssl/ssl_versions.cc new file mode 100644 index 0000000..8764322 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/ssl/ssl_versions.cc @@ -0,0 +1,399 @@ +/* Copyright (c) 2017, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include + +#include +#include + +#include "internal.h" +#include "../crypto/internal.h" + + +namespace bssl { + +bool ssl_protocol_version_from_wire(uint16_t *out, uint16_t version) { + switch (version) { + case SSL3_VERSION: + case TLS1_VERSION: + case TLS1_1_VERSION: + case TLS1_2_VERSION: + *out = version; + return true; + + case TLS1_3_DRAFT23_VERSION: + *out = TLS1_3_VERSION; + return true; + + case DTLS1_VERSION: + // DTLS 1.0 is analogous to TLS 1.1, not TLS 1.0. + *out = TLS1_1_VERSION; + return true; + + case DTLS1_2_VERSION: + *out = TLS1_2_VERSION; + return true; + + default: + return false; + } +} + +// The follow arrays are the supported versions for TLS and DTLS, in order of +// decreasing preference. + +static const uint16_t kTLSVersions[] = { + TLS1_3_DRAFT23_VERSION, + TLS1_2_VERSION, + TLS1_1_VERSION, + TLS1_VERSION, + SSL3_VERSION, +}; + +static const uint16_t kDTLSVersions[] = { + DTLS1_2_VERSION, + DTLS1_VERSION, +}; + +static void get_method_versions(const SSL_PROTOCOL_METHOD *method, + const uint16_t **out, size_t *out_num) { + if (method->is_dtls) { + *out = kDTLSVersions; + *out_num = OPENSSL_ARRAY_SIZE(kDTLSVersions); + } else { + *out = kTLSVersions; + *out_num = OPENSSL_ARRAY_SIZE(kTLSVersions); + } +} + +static bool method_supports_version(const SSL_PROTOCOL_METHOD *method, + uint16_t version) { + const uint16_t *versions; + size_t num_versions; + get_method_versions(method, &versions, &num_versions); + for (size_t i = 0; i < num_versions; i++) { + if (versions[i] == version) { + return true; + } + } + return false; +} + +// The following functions map between API versions and wire versions. The +// public API works on wire versions, except that TLS 1.3 draft versions all +// appear as TLS 1.3. This will get collapsed back down when TLS 1.3 is +// finalized. + +static const char *ssl_version_to_string(uint16_t version) { + switch (version) { + case TLS1_3_DRAFT23_VERSION: + return "TLSv1.3"; + + case TLS1_2_VERSION: + return "TLSv1.2"; + + case TLS1_1_VERSION: + return "TLSv1.1"; + + case TLS1_VERSION: + return "TLSv1"; + + case SSL3_VERSION: + return "SSLv3"; + + case DTLS1_VERSION: + return "DTLSv1"; + + case DTLS1_2_VERSION: + return "DTLSv1.2"; + + default: + return "unknown"; + } +} + +static uint16_t wire_version_to_api(uint16_t version) { + switch (version) { + // Report TLS 1.3 draft versions as TLS 1.3 in the public API. + case TLS1_3_DRAFT23_VERSION: + return TLS1_3_VERSION; + default: + return version; + } +} + +// api_version_to_wire maps |version| to some representative wire version. In +// particular, it picks an arbitrary TLS 1.3 representative. This should only be +// used in context where that does not matter. +static bool api_version_to_wire(uint16_t *out, uint16_t version) { + if (version == TLS1_3_DRAFT23_VERSION) { + return false; + } + if (version == TLS1_3_VERSION) { + version = TLS1_3_DRAFT23_VERSION; + } + + // Check it is a real protocol version. + uint16_t unused; + if (!ssl_protocol_version_from_wire(&unused, version)) { + return false; + } + + *out = version; + return true; +} + +static bool set_version_bound(const SSL_PROTOCOL_METHOD *method, uint16_t *out, + uint16_t version) { + if (!api_version_to_wire(&version, version) || + !method_supports_version(method, version) || + !ssl_protocol_version_from_wire(out, version)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_SSL_VERSION); + return false; + } + + return true; +} + +static bool set_min_version(const SSL_PROTOCOL_METHOD *method, uint16_t *out, + uint16_t version) { + // Zero is interpreted as the default minimum version. + if (version == 0) { + // SSL 3.0 is disabled by default and TLS 1.0 does not exist in DTLS. + *out = method->is_dtls ? TLS1_1_VERSION : TLS1_VERSION; + return true; + } + + return set_version_bound(method, out, version); +} + +static bool set_max_version(const SSL_PROTOCOL_METHOD *method, uint16_t *out, + uint16_t version) { + // Zero is interpreted as the default maximum version. + if (version == 0) { + *out = TLS1_2_VERSION; + return true; + } + + return set_version_bound(method, out, version); +} + +const struct { + uint16_t version; + uint32_t flag; +} kProtocolVersions[] = { + {SSL3_VERSION, SSL_OP_NO_SSLv3}, + {TLS1_VERSION, SSL_OP_NO_TLSv1}, + {TLS1_1_VERSION, SSL_OP_NO_TLSv1_1}, + {TLS1_2_VERSION, SSL_OP_NO_TLSv1_2}, + {TLS1_3_VERSION, SSL_OP_NO_TLSv1_3}, +}; + +bool ssl_get_version_range(const SSL *ssl, uint16_t *out_min_version, + uint16_t *out_max_version) { + // For historical reasons, |SSL_OP_NO_DTLSv1| aliases |SSL_OP_NO_TLSv1|, but + // DTLS 1.0 should be mapped to TLS 1.1. + uint32_t options = ssl->options; + if (SSL_is_dtls(ssl)) { + options &= ~SSL_OP_NO_TLSv1_1; + if (options & SSL_OP_NO_DTLSv1) { + options |= SSL_OP_NO_TLSv1_1; + } + } + + uint16_t min_version = ssl->conf_min_version; + uint16_t max_version = ssl->conf_max_version; + + // OpenSSL's API for controlling versions entails blacklisting individual + // protocols. This has two problems. First, on the client, the protocol can + // only express a contiguous range of versions. Second, a library consumer + // trying to set a maximum version cannot disable protocol versions that get + // added in a future version of the library. + // + // To account for both of these, OpenSSL interprets the client-side bitmask + // as a min/max range by picking the lowest contiguous non-empty range of + // enabled protocols. Note that this means it is impossible to set a maximum + // version of the higest supported TLS version in a future-proof way. + bool any_enabled = false; + for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kProtocolVersions); i++) { + // Only look at the versions already enabled. + if (min_version > kProtocolVersions[i].version) { + continue; + } + if (max_version < kProtocolVersions[i].version) { + break; + } + + if (!(options & kProtocolVersions[i].flag)) { + // The minimum version is the first enabled version. + if (!any_enabled) { + any_enabled = true; + min_version = kProtocolVersions[i].version; + } + continue; + } + + // If there is a disabled version after the first enabled one, all versions + // after it are implicitly disabled. + if (any_enabled) { + max_version = kProtocolVersions[i-1].version; + break; + } + } + + if (!any_enabled) { + OPENSSL_PUT_ERROR(SSL, SSL_R_NO_SUPPORTED_VERSIONS_ENABLED); + return false; + } + + *out_min_version = min_version; + *out_max_version = max_version; + return true; +} + +static uint16_t ssl_version(const SSL *ssl) { + // In early data, we report the predicted version. + if (SSL_in_early_data(ssl) && !ssl->server) { + return ssl->s3->hs->early_session->ssl_version; + } + return ssl->version; +} + +uint16_t ssl_protocol_version(const SSL *ssl) { + assert(ssl->s3->have_version); + uint16_t version; + if (!ssl_protocol_version_from_wire(&version, ssl->version)) { + // |ssl->version| will always be set to a valid version. + assert(0); + return 0; + } + + return version; +} + +bool ssl_supports_version(SSL_HANDSHAKE *hs, uint16_t version) { + SSL *const ssl = hs->ssl; + uint16_t protocol_version; + if (!method_supports_version(ssl->method, version) || + !ssl_protocol_version_from_wire(&protocol_version, version) || + hs->min_version > protocol_version || + protocol_version > hs->max_version) { + return false; + } + + // This logic is part of the TLS 1.3 variants mechanism used in TLS 1.3 + // experimentation. Although we currently only have one variant, TLS 1.3 does + // not a final stable deployment yet, so leave the logic in place for now. + if (protocol_version != TLS1_3_VERSION || + (ssl->tls13_variant == tls13_default && + version == TLS1_3_DRAFT23_VERSION)) { + return true; + } + + // The server, when not configured at |tls13_default|, should additionally + // enable all variants. + if (ssl->server && ssl->tls13_variant != tls13_default) { + return true; + } + + return false; +} + +bool ssl_add_supported_versions(SSL_HANDSHAKE *hs, CBB *cbb) { + const uint16_t *versions; + size_t num_versions; + get_method_versions(hs->ssl->method, &versions, &num_versions); + for (size_t i = 0; i < num_versions; i++) { + if (ssl_supports_version(hs, versions[i]) && + !CBB_add_u16(cbb, versions[i])) { + return false; + } + } + return true; +} + +bool ssl_negotiate_version(SSL_HANDSHAKE *hs, uint8_t *out_alert, + uint16_t *out_version, const CBS *peer_versions) { + const uint16_t *versions; + size_t num_versions; + get_method_versions(hs->ssl->method, &versions, &num_versions); + for (size_t i = 0; i < num_versions; i++) { + if (!ssl_supports_version(hs, versions[i])) { + continue; + } + + CBS copy = *peer_versions; + while (CBS_len(©) != 0) { + uint16_t version; + if (!CBS_get_u16(©, &version)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + *out_alert = SSL_AD_DECODE_ERROR; + return false; + } + + if (version == versions[i]) { + *out_version = version; + return true; + } + } + } + + OPENSSL_PUT_ERROR(SSL, SSL_R_UNSUPPORTED_PROTOCOL); + *out_alert = SSL_AD_PROTOCOL_VERSION; + return false; +} + +} // namespace bssl + +using namespace bssl; + +int SSL_CTX_set_min_proto_version(SSL_CTX *ctx, uint16_t version) { + return set_min_version(ctx->method, &ctx->conf_min_version, version); +} + +int SSL_CTX_set_max_proto_version(SSL_CTX *ctx, uint16_t version) { + return set_max_version(ctx->method, &ctx->conf_max_version, version); +} + +int SSL_set_min_proto_version(SSL *ssl, uint16_t version) { + return set_min_version(ssl->method, &ssl->conf_min_version, version); +} + +int SSL_set_max_proto_version(SSL *ssl, uint16_t version) { + return set_max_version(ssl->method, &ssl->conf_max_version, version); +} + +int SSL_version(const SSL *ssl) { + return wire_version_to_api(ssl_version(ssl)); +} + +const char *SSL_get_version(const SSL *ssl) { + return ssl_version_to_string(ssl_version(ssl)); +} + +const char *SSL_SESSION_get_version(const SSL_SESSION *session) { + return ssl_version_to_string(session->ssl_version); +} + +uint16_t SSL_SESSION_get_protocol_version(const SSL_SESSION *session) { + return wire_version_to_api(session->ssl_version); +} + +int SSL_SESSION_set_protocol_version(SSL_SESSION *session, uint16_t version) { + // This picks a representative TLS 1.3 version, but this API should only be + // used on unit test sessions anyway. + return api_version_to_wire(&session->ssl_version, version); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/ssl/ssl_versions.cc.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/ssl/ssl_versions.cc.grpc_back new file mode 100644 index 0000000..aeb41d3 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/ssl/ssl_versions.cc.grpc_back @@ -0,0 +1,399 @@ +/* Copyright (c) 2017, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include + +#include +#include + +#include "internal.h" +#include "../crypto/internal.h" + + +namespace bssl { + +bool ssl_protocol_version_from_wire(uint16_t *out, uint16_t version) { + switch (version) { + case SSL3_VERSION: + case TLS1_VERSION: + case TLS1_1_VERSION: + case TLS1_2_VERSION: + *out = version; + return true; + + case TLS1_3_DRAFT23_VERSION: + *out = TLS1_3_VERSION; + return true; + + case DTLS1_VERSION: + // DTLS 1.0 is analogous to TLS 1.1, not TLS 1.0. + *out = TLS1_1_VERSION; + return true; + + case DTLS1_2_VERSION: + *out = TLS1_2_VERSION; + return true; + + default: + return false; + } +} + +// The follow arrays are the supported versions for TLS and DTLS, in order of +// decreasing preference. + +static const uint16_t kTLSVersions[] = { + TLS1_3_DRAFT23_VERSION, + TLS1_2_VERSION, + TLS1_1_VERSION, + TLS1_VERSION, + SSL3_VERSION, +}; + +static const uint16_t kDTLSVersions[] = { + DTLS1_2_VERSION, + DTLS1_VERSION, +}; + +static void get_method_versions(const SSL_PROTOCOL_METHOD *method, + const uint16_t **out, size_t *out_num) { + if (method->is_dtls) { + *out = kDTLSVersions; + *out_num = OPENSSL_ARRAY_SIZE(kDTLSVersions); + } else { + *out = kTLSVersions; + *out_num = OPENSSL_ARRAY_SIZE(kTLSVersions); + } +} + +static bool method_supports_version(const SSL_PROTOCOL_METHOD *method, + uint16_t version) { + const uint16_t *versions; + size_t num_versions; + get_method_versions(method, &versions, &num_versions); + for (size_t i = 0; i < num_versions; i++) { + if (versions[i] == version) { + return true; + } + } + return false; +} + +// The following functions map between API versions and wire versions. The +// public API works on wire versions, except that TLS 1.3 draft versions all +// appear as TLS 1.3. This will get collapsed back down when TLS 1.3 is +// finalized. + +static const char *ssl_version_to_string(uint16_t version) { + switch (version) { + case TLS1_3_DRAFT23_VERSION: + return "TLSv1.3"; + + case TLS1_2_VERSION: + return "TLSv1.2"; + + case TLS1_1_VERSION: + return "TLSv1.1"; + + case TLS1_VERSION: + return "TLSv1"; + + case SSL3_VERSION: + return "SSLv3"; + + case DTLS1_VERSION: + return "DTLSv1"; + + case DTLS1_2_VERSION: + return "DTLSv1.2"; + + default: + return "unknown"; + } +} + +static uint16_t wire_version_to_api(uint16_t version) { + switch (version) { + // Report TLS 1.3 draft versions as TLS 1.3 in the public API. + case TLS1_3_DRAFT23_VERSION: + return TLS1_3_VERSION; + default: + return version; + } +} + +// api_version_to_wire maps |version| to some representative wire version. In +// particular, it picks an arbitrary TLS 1.3 representative. This should only be +// used in context where that does not matter. +static bool api_version_to_wire(uint16_t *out, uint16_t version) { + if (version == TLS1_3_DRAFT23_VERSION) { + return false; + } + if (version == TLS1_3_VERSION) { + version = TLS1_3_DRAFT23_VERSION; + } + + // Check it is a real protocol version. + uint16_t unused; + if (!ssl_protocol_version_from_wire(&unused, version)) { + return false; + } + + *out = version; + return true; +} + +static bool set_version_bound(const SSL_PROTOCOL_METHOD *method, uint16_t *out, + uint16_t version) { + if (!api_version_to_wire(&version, version) || + !method_supports_version(method, version) || + !ssl_protocol_version_from_wire(out, version)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_SSL_VERSION); + return false; + } + + return true; +} + +static bool set_min_version(const SSL_PROTOCOL_METHOD *method, uint16_t *out, + uint16_t version) { + // Zero is interpreted as the default minimum version. + if (version == 0) { + // SSL 3.0 is disabled by default and TLS 1.0 does not exist in DTLS. + *out = method->is_dtls ? TLS1_1_VERSION : TLS1_VERSION; + return true; + } + + return set_version_bound(method, out, version); +} + +static bool set_max_version(const SSL_PROTOCOL_METHOD *method, uint16_t *out, + uint16_t version) { + // Zero is interpreted as the default maximum version. + if (version == 0) { + *out = TLS1_2_VERSION; + return true; + } + + return set_version_bound(method, out, version); +} + +const struct { + uint16_t version; + uint32_t flag; +} kProtocolVersions[] = { + {SSL3_VERSION, SSL_OP_NO_SSLv3}, + {TLS1_VERSION, SSL_OP_NO_TLSv1}, + {TLS1_1_VERSION, SSL_OP_NO_TLSv1_1}, + {TLS1_2_VERSION, SSL_OP_NO_TLSv1_2}, + {TLS1_3_VERSION, SSL_OP_NO_TLSv1_3}, +}; + +bool ssl_get_version_range(const SSL *ssl, uint16_t *out_min_version, + uint16_t *out_max_version) { + // For historical reasons, |SSL_OP_NO_DTLSv1| aliases |SSL_OP_NO_TLSv1|, but + // DTLS 1.0 should be mapped to TLS 1.1. + uint32_t options = ssl->options; + if (SSL_is_dtls(ssl)) { + options &= ~SSL_OP_NO_TLSv1_1; + if (options & SSL_OP_NO_DTLSv1) { + options |= SSL_OP_NO_TLSv1_1; + } + } + + uint16_t min_version = ssl->conf_min_version; + uint16_t max_version = ssl->conf_max_version; + + // OpenSSL's API for controlling versions entails blacklisting individual + // protocols. This has two problems. First, on the client, the protocol can + // only express a contiguous range of versions. Second, a library consumer + // trying to set a maximum version cannot disable protocol versions that get + // added in a future version of the library. + // + // To account for both of these, OpenSSL interprets the client-side bitmask + // as a min/max range by picking the lowest contiguous non-empty range of + // enabled protocols. Note that this means it is impossible to set a maximum + // version of the higest supported TLS version in a future-proof way. + bool any_enabled = false; + for (size_t i = 0; i < OPENSSL_ARRAY_SIZE(kProtocolVersions); i++) { + // Only look at the versions already enabled. + if (min_version > kProtocolVersions[i].version) { + continue; + } + if (max_version < kProtocolVersions[i].version) { + break; + } + + if (!(options & kProtocolVersions[i].flag)) { + // The minimum version is the first enabled version. + if (!any_enabled) { + any_enabled = true; + min_version = kProtocolVersions[i].version; + } + continue; + } + + // If there is a disabled version after the first enabled one, all versions + // after it are implicitly disabled. + if (any_enabled) { + max_version = kProtocolVersions[i-1].version; + break; + } + } + + if (!any_enabled) { + OPENSSL_PUT_ERROR(SSL, SSL_R_NO_SUPPORTED_VERSIONS_ENABLED); + return false; + } + + *out_min_version = min_version; + *out_max_version = max_version; + return true; +} + +static uint16_t ssl_version(const SSL *ssl) { + // In early data, we report the predicted version. + if (SSL_in_early_data(ssl) && !ssl->server) { + return ssl->s3->hs->early_session->ssl_version; + } + return ssl->version; +} + +uint16_t ssl_protocol_version(const SSL *ssl) { + assert(ssl->s3->have_version); + uint16_t version; + if (!ssl_protocol_version_from_wire(&version, ssl->version)) { + // |ssl->version| will always be set to a valid version. + assert(0); + return 0; + } + + return version; +} + +bool ssl_supports_version(SSL_HANDSHAKE *hs, uint16_t version) { + SSL *const ssl = hs->ssl; + uint16_t protocol_version; + if (!method_supports_version(ssl->method, version) || + !ssl_protocol_version_from_wire(&protocol_version, version) || + hs->min_version > protocol_version || + protocol_version > hs->max_version) { + return false; + } + + // This logic is part of the TLS 1.3 variants mechanism used in TLS 1.3 + // experimentation. Although we currently only have one variant, TLS 1.3 does + // not a final stable deployment yet, so leave the logic in place for now. + if (protocol_version != TLS1_3_VERSION || + (ssl->tls13_variant == tls13_default && + version == TLS1_3_DRAFT23_VERSION)) { + return true; + } + + // The server, when not configured at |tls13_default|, should additionally + // enable all variants. + if (ssl->server && ssl->tls13_variant != tls13_default) { + return true; + } + + return false; +} + +bool ssl_add_supported_versions(SSL_HANDSHAKE *hs, CBB *cbb) { + const uint16_t *versions; + size_t num_versions; + get_method_versions(hs->ssl->method, &versions, &num_versions); + for (size_t i = 0; i < num_versions; i++) { + if (ssl_supports_version(hs, versions[i]) && + !CBB_add_u16(cbb, versions[i])) { + return false; + } + } + return true; +} + +bool ssl_negotiate_version(SSL_HANDSHAKE *hs, uint8_t *out_alert, + uint16_t *out_version, const CBS *peer_versions) { + const uint16_t *versions; + size_t num_versions; + get_method_versions(hs->ssl->method, &versions, &num_versions); + for (size_t i = 0; i < num_versions; i++) { + if (!ssl_supports_version(hs, versions[i])) { + continue; + } + + CBS copy = *peer_versions; + while (CBS_len(©) != 0) { + uint16_t version; + if (!CBS_get_u16(©, &version)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + *out_alert = SSL_AD_DECODE_ERROR; + return false; + } + + if (version == versions[i]) { + *out_version = version; + return true; + } + } + } + + OPENSSL_PUT_ERROR(SSL, SSL_R_UNSUPPORTED_PROTOCOL); + *out_alert = SSL_AD_PROTOCOL_VERSION; + return false; +} + +} // namespace bssl + +using namespace bssl; + +int SSL_CTX_set_min_proto_version(SSL_CTX *ctx, uint16_t version) { + return set_min_version(ctx->method, &ctx->conf_min_version, version); +} + +int SSL_CTX_set_max_proto_version(SSL_CTX *ctx, uint16_t version) { + return set_max_version(ctx->method, &ctx->conf_max_version, version); +} + +int SSL_set_min_proto_version(SSL *ssl, uint16_t version) { + return set_min_version(ssl->method, &ssl->conf_min_version, version); +} + +int SSL_set_max_proto_version(SSL *ssl, uint16_t version) { + return set_max_version(ssl->method, &ssl->conf_max_version, version); +} + +int SSL_version(const SSL *ssl) { + return wire_version_to_api(ssl_version(ssl)); +} + +const char *SSL_get_version(const SSL *ssl) { + return ssl_version_to_string(ssl_version(ssl)); +} + +const char *SSL_SESSION_get_version(const SSL_SESSION *session) { + return ssl_version_to_string(session->ssl_version); +} + +uint16_t SSL_SESSION_get_protocol_version(const SSL_SESSION *session) { + return wire_version_to_api(session->ssl_version); +} + +int SSL_SESSION_set_protocol_version(SSL_SESSION *session, uint16_t version) { + // This picks a representative TLS 1.3 version, but this API should only be + // used on unit test sessions anyway. + return api_version_to_wire(&session->ssl_version, version); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/ssl/ssl_x509.cc b/FoodApp/Pods/BoringSSL-GRPC/ssl/ssl_x509.cc new file mode 100644 index 0000000..2d85cd0 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/ssl/ssl_x509.cc @@ -0,0 +1,1297 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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. + */ +/* ==================================================================== + * 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 +#include +#include +#include +#include +#include +#include +#include + +#include "internal.h" +#include "../crypto/internal.h" + + +namespace bssl { + +// check_ssl_x509_method asserts that |ssl| has the X509-based method +// installed. Calling an X509-based method on an |ssl| with a different method +// will likely misbehave and possibly crash or leak memory. +static void check_ssl_x509_method(const SSL *ssl) { + assert(ssl == NULL || ssl->ctx->x509_method == &ssl_crypto_x509_method); +} + +// check_ssl_ctx_x509_method acts like |check_ssl_x509_method|, but for an +// |SSL_CTX|. +static void check_ssl_ctx_x509_method(const SSL_CTX *ctx) { + assert(ctx == NULL || ctx->x509_method == &ssl_crypto_x509_method); +} + +// x509_to_buffer returns a |CRYPTO_BUFFER| that contains the serialised +// contents of |x509|. +static UniquePtr x509_to_buffer(X509 *x509) { + uint8_t *buf = NULL; + int cert_len = i2d_X509(x509, &buf); + if (cert_len <= 0) { + return 0; + } + + UniquePtr buffer(CRYPTO_BUFFER_new(buf, cert_len, NULL)); + OPENSSL_free(buf); + + return buffer; +} + +// new_leafless_chain returns a fresh stack of buffers set to {NULL}. +static STACK_OF(CRYPTO_BUFFER) *new_leafless_chain(void) { + STACK_OF(CRYPTO_BUFFER) *chain = sk_CRYPTO_BUFFER_new_null(); + if (chain == NULL) { + return NULL; + } + + if (!sk_CRYPTO_BUFFER_push(chain, NULL)) { + sk_CRYPTO_BUFFER_free(chain); + return NULL; + } + + return chain; +} + +// ssl_cert_set_chain sets elements 1.. of |cert->chain| to the serialised +// forms of elements of |chain|. It returns one on success or zero on error, in +// which case no change to |cert->chain| is made. It preverses the existing +// leaf from |cert->chain|, if any. +static int ssl_cert_set_chain(CERT *cert, STACK_OF(X509) *chain) { + UniquePtr new_chain; + + if (cert->chain != NULL) { + new_chain.reset(sk_CRYPTO_BUFFER_new_null()); + if (!new_chain) { + return 0; + } + + CRYPTO_BUFFER *leaf = sk_CRYPTO_BUFFER_value(cert->chain, 0); + if (!sk_CRYPTO_BUFFER_push(new_chain.get(), leaf)) { + return 0; + } + // |leaf| might be NULL if it's a “leafless” chain. + if (leaf != NULL) { + CRYPTO_BUFFER_up_ref(leaf); + } + } + + for (X509 *x509 : chain) { + if (!new_chain) { + new_chain.reset(new_leafless_chain()); + if (!new_chain) { + return 0; + } + } + + UniquePtr buffer = x509_to_buffer(x509); + if (!buffer || + !PushToStack(new_chain.get(), std::move(buffer))) { + return 0; + } + } + + sk_CRYPTO_BUFFER_pop_free(cert->chain, CRYPTO_BUFFER_free); + cert->chain = new_chain.release(); + + return 1; +} + +static void ssl_crypto_x509_cert_flush_cached_leaf(CERT *cert) { + X509_free(cert->x509_leaf); + cert->x509_leaf = NULL; +} + +static void ssl_crypto_x509_cert_flush_cached_chain(CERT *cert) { + sk_X509_pop_free(cert->x509_chain, X509_free); + cert->x509_chain = NULL; +} + +static int ssl_crypto_x509_check_client_CA_list( + STACK_OF(CRYPTO_BUFFER) *names) { + for (const CRYPTO_BUFFER *buffer : names) { + const uint8_t *inp = CRYPTO_BUFFER_data(buffer); + X509_NAME *name = d2i_X509_NAME(NULL, &inp, CRYPTO_BUFFER_len(buffer)); + const int ok = name != NULL && inp == CRYPTO_BUFFER_data(buffer) + + CRYPTO_BUFFER_len(buffer); + X509_NAME_free(name); + if (!ok) { + return 0; + } + } + + return 1; +} + +static void ssl_crypto_x509_cert_clear(CERT *cert) { + ssl_crypto_x509_cert_flush_cached_leaf(cert); + ssl_crypto_x509_cert_flush_cached_chain(cert); + + X509_free(cert->x509_stash); + cert->x509_stash = NULL; +} + +static void ssl_crypto_x509_cert_free(CERT *cert) { + ssl_crypto_x509_cert_clear(cert); + X509_STORE_free(cert->verify_store); +} + +static void ssl_crypto_x509_cert_dup(CERT *new_cert, const CERT *cert) { + if (cert->verify_store != NULL) { + X509_STORE_up_ref(cert->verify_store); + new_cert->verify_store = cert->verify_store; + } +} + +static int ssl_crypto_x509_session_cache_objects(SSL_SESSION *sess) { + bssl::UniquePtr chain; + if (sk_CRYPTO_BUFFER_num(sess->certs) > 0) { + chain.reset(sk_X509_new_null()); + if (!chain) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + } + + X509 *leaf = nullptr; + for (CRYPTO_BUFFER *cert : sess->certs) { + UniquePtr x509(X509_parse_from_buffer(cert)); + if (!x509) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + return 0; + } + if (leaf == nullptr) { + leaf = x509.get(); + } + if (!PushToStack(chain.get(), std::move(x509))) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + } + + sk_X509_pop_free(sess->x509_chain, X509_free); + sess->x509_chain = chain.release(); + sk_X509_pop_free(sess->x509_chain_without_leaf, X509_free); + sess->x509_chain_without_leaf = NULL; + + X509_free(sess->x509_peer); + if (leaf != NULL) { + X509_up_ref(leaf); + } + sess->x509_peer = leaf; + return 1; +} + +static int ssl_crypto_x509_session_dup(SSL_SESSION *new_session, + const SSL_SESSION *session) { + if (session->x509_peer != NULL) { + X509_up_ref(session->x509_peer); + new_session->x509_peer = session->x509_peer; + } + if (session->x509_chain != NULL) { + new_session->x509_chain = X509_chain_up_ref(session->x509_chain); + if (new_session->x509_chain == NULL) { + return 0; + } + } + + return 1; +} + +static void ssl_crypto_x509_session_clear(SSL_SESSION *session) { + X509_free(session->x509_peer); + session->x509_peer = NULL; + sk_X509_pop_free(session->x509_chain, X509_free); + session->x509_chain = NULL; + sk_X509_pop_free(session->x509_chain_without_leaf, X509_free); + session->x509_chain_without_leaf = NULL; +} + +static int ssl_crypto_x509_session_verify_cert_chain(SSL_SESSION *session, + SSL *ssl, + uint8_t *out_alert) { + *out_alert = SSL_AD_INTERNAL_ERROR; + STACK_OF(X509) *const cert_chain = session->x509_chain; + if (cert_chain == NULL || sk_X509_num(cert_chain) == 0) { + return 0; + } + + X509_STORE *verify_store = ssl->ctx->cert_store; + if (ssl->cert->verify_store != NULL) { + verify_store = ssl->cert->verify_store; + } + + X509 *leaf = sk_X509_value(cert_chain, 0); + ScopedX509_STORE_CTX ctx; + if (!X509_STORE_CTX_init(ctx.get(), verify_store, leaf, cert_chain)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_X509_LIB); + return 0; + } + if (!X509_STORE_CTX_set_ex_data(ctx.get(), + SSL_get_ex_data_X509_STORE_CTX_idx(), ssl)) { + return 0; + } + + // 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.get(), + ssl->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.get()), ssl->param); + + if (ssl->verify_callback) { + X509_STORE_CTX_set_verify_cb(ctx.get(), ssl->verify_callback); + } + + int verify_ret; + if (ssl->ctx->app_verify_callback != NULL) { + verify_ret = + ssl->ctx->app_verify_callback(ctx.get(), ssl->ctx->app_verify_arg); + } else { + verify_ret = X509_verify_cert(ctx.get()); + } + + session->verify_result = ctx->error; + + // If |SSL_VERIFY_NONE|, the error is non-fatal, but we keep the result. + if (verify_ret <= 0 && ssl->verify_mode != SSL_VERIFY_NONE) { + *out_alert = SSL_alert_from_verify_result(ctx->error); + return 0; + } + + ERR_clear_error(); + return 1; +} + +static void ssl_crypto_x509_hs_flush_cached_ca_names(SSL_HANDSHAKE *hs) { + sk_X509_NAME_pop_free(hs->cached_x509_ca_names, X509_NAME_free); + hs->cached_x509_ca_names = NULL; +} + +static int ssl_crypto_x509_ssl_new(SSL *ssl) { + ssl->param = X509_VERIFY_PARAM_new(); + if (ssl->param == NULL) { + return 0; + } + X509_VERIFY_PARAM_inherit(ssl->param, ssl->ctx->param); + return 1; +} + +static void ssl_crypto_x509_ssl_flush_cached_client_CA(SSL *ssl) { + sk_X509_NAME_pop_free(ssl->cached_x509_client_CA, X509_NAME_free); + ssl->cached_x509_client_CA = NULL; +} + +static void ssl_crypto_x509_ssl_free(SSL *ssl) { + ssl_crypto_x509_ssl_flush_cached_client_CA(ssl); + X509_VERIFY_PARAM_free(ssl->param); +} + +static int ssl_crypto_x509_ssl_auto_chain_if_needed(SSL *ssl) { + // Only build a chain if there are no intermediates configured and the feature + // isn't disabled. + if ((ssl->mode & SSL_MODE_NO_AUTO_CHAIN) || + !ssl_has_certificate(ssl) || + ssl->cert->chain == NULL || + sk_CRYPTO_BUFFER_num(ssl->cert->chain) > 1) { + return 1; + } + + UniquePtr leaf( + X509_parse_from_buffer(sk_CRYPTO_BUFFER_value(ssl->cert->chain, 0))); + if (!leaf) { + OPENSSL_PUT_ERROR(SSL, ERR_R_X509_LIB); + return 0; + } + + ScopedX509_STORE_CTX ctx; + if (!X509_STORE_CTX_init(ctx.get(), ssl->ctx->cert_store, leaf.get(), NULL)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_X509_LIB); + return 0; + } + + // Attempt to build a chain, ignoring the result. + X509_verify_cert(ctx.get()); + ERR_clear_error(); + + // Remove the leaf from the generated chain. + X509_free(sk_X509_shift(ctx->chain)); + + if (!ssl_cert_set_chain(ssl->cert, ctx->chain)) { + return 0; + } + + ssl_crypto_x509_cert_flush_cached_chain(ssl->cert); + + return 1; +} + +static void ssl_crypto_x509_ssl_ctx_flush_cached_client_CA(SSL_CTX *ctx) { + sk_X509_NAME_pop_free(ctx->cached_x509_client_CA, X509_NAME_free); + ctx->cached_x509_client_CA = NULL; +} + +static int ssl_crypto_x509_ssl_ctx_new(SSL_CTX *ctx) { + ctx->cert_store = X509_STORE_new(); + ctx->param = X509_VERIFY_PARAM_new(); + return (ctx->cert_store != NULL && ctx->param != NULL); +} + +static void ssl_crypto_x509_ssl_ctx_free(SSL_CTX *ctx) { + ssl_crypto_x509_ssl_ctx_flush_cached_client_CA(ctx); + X509_VERIFY_PARAM_free(ctx->param); + X509_STORE_free(ctx->cert_store); +} + +const SSL_X509_METHOD ssl_crypto_x509_method = { + ssl_crypto_x509_check_client_CA_list, + ssl_crypto_x509_cert_clear, + ssl_crypto_x509_cert_free, + ssl_crypto_x509_cert_dup, + ssl_crypto_x509_cert_flush_cached_chain, + ssl_crypto_x509_cert_flush_cached_leaf, + ssl_crypto_x509_session_cache_objects, + ssl_crypto_x509_session_dup, + ssl_crypto_x509_session_clear, + ssl_crypto_x509_session_verify_cert_chain, + ssl_crypto_x509_hs_flush_cached_ca_names, + ssl_crypto_x509_ssl_new, + ssl_crypto_x509_ssl_free, + ssl_crypto_x509_ssl_flush_cached_client_CA, + ssl_crypto_x509_ssl_auto_chain_if_needed, + ssl_crypto_x509_ssl_ctx_new, + ssl_crypto_x509_ssl_ctx_free, + ssl_crypto_x509_ssl_ctx_flush_cached_client_CA, +}; + +} // namespace bssl + +using namespace bssl; + +X509 *SSL_get_peer_certificate(const SSL *ssl) { + check_ssl_x509_method(ssl); + if (ssl == NULL) { + return NULL; + } + SSL_SESSION *session = SSL_get_session(ssl); + if (session == NULL || session->x509_peer == NULL) { + return NULL; + } + X509_up_ref(session->x509_peer); + return session->x509_peer; +} + +STACK_OF(X509) *SSL_get_peer_cert_chain(const SSL *ssl) { + check_ssl_x509_method(ssl); + if (ssl == NULL) { + return NULL; + } + SSL_SESSION *session = SSL_get_session(ssl); + if (session == NULL || + session->x509_chain == NULL) { + return NULL; + } + + if (!ssl->server) { + return session->x509_chain; + } + + // OpenSSL historically didn't include the leaf certificate in the returned + // certificate chain, but only for servers. + if (session->x509_chain_without_leaf == NULL) { + session->x509_chain_without_leaf = sk_X509_new_null(); + if (session->x509_chain_without_leaf == NULL) { + return NULL; + } + + for (size_t i = 1; i < sk_X509_num(session->x509_chain); i++) { + X509 *cert = sk_X509_value(session->x509_chain, i); + if (!sk_X509_push(session->x509_chain_without_leaf, cert)) { + sk_X509_pop_free(session->x509_chain_without_leaf, X509_free); + session->x509_chain_without_leaf = NULL; + return NULL; + } + X509_up_ref(cert); + } + } + + return session->x509_chain_without_leaf; +} + +STACK_OF(X509) *SSL_get_peer_full_cert_chain(const SSL *ssl) { + check_ssl_x509_method(ssl); + SSL_SESSION *session = SSL_get_session(ssl); + if (session == NULL) { + return NULL; + } + + return session->x509_chain; +} + +int SSL_CTX_set_purpose(SSL_CTX *ctx, int purpose) { + check_ssl_ctx_x509_method(ctx); + return X509_VERIFY_PARAM_set_purpose(ctx->param, purpose); +} + +int SSL_set_purpose(SSL *ssl, int purpose) { + check_ssl_x509_method(ssl); + return X509_VERIFY_PARAM_set_purpose(ssl->param, purpose); +} + +int SSL_CTX_set_trust(SSL_CTX *ctx, int trust) { + check_ssl_ctx_x509_method(ctx); + return X509_VERIFY_PARAM_set_trust(ctx->param, trust); +} + +int SSL_set_trust(SSL *ssl, int trust) { + check_ssl_x509_method(ssl); + return X509_VERIFY_PARAM_set_trust(ssl->param, trust); +} + +int SSL_CTX_set1_param(SSL_CTX *ctx, const X509_VERIFY_PARAM *param) { + check_ssl_ctx_x509_method(ctx); + return X509_VERIFY_PARAM_set1(ctx->param, param); +} + +int SSL_set1_param(SSL *ssl, const X509_VERIFY_PARAM *param) { + check_ssl_x509_method(ssl); + return X509_VERIFY_PARAM_set1(ssl->param, param); +} + +X509_VERIFY_PARAM *SSL_CTX_get0_param(SSL_CTX *ctx) { + check_ssl_ctx_x509_method(ctx); + return ctx->param; +} + +X509_VERIFY_PARAM *SSL_get0_param(SSL *ssl) { + check_ssl_x509_method(ssl); + return ssl->param; +} + +int SSL_get_verify_depth(const SSL *ssl) { + check_ssl_x509_method(ssl); + return X509_VERIFY_PARAM_get_depth(ssl->param); +} + +int (*SSL_get_verify_callback(const SSL *ssl))(int, X509_STORE_CTX *) { + check_ssl_x509_method(ssl); + return ssl->verify_callback; +} + +int SSL_CTX_get_verify_mode(const SSL_CTX *ctx) { + check_ssl_ctx_x509_method(ctx); + return ctx->verify_mode; +} + +int SSL_CTX_get_verify_depth(const SSL_CTX *ctx) { + check_ssl_ctx_x509_method(ctx); + return X509_VERIFY_PARAM_get_depth(ctx->param); +} + +int (*SSL_CTX_get_verify_callback(const SSL_CTX *ctx))( + int ok, X509_STORE_CTX *store_ctx) { + check_ssl_ctx_x509_method(ctx); + return ctx->default_verify_callback; +} + +void SSL_set_verify(SSL *ssl, int mode, + int (*callback)(int ok, X509_STORE_CTX *store_ctx)) { + check_ssl_x509_method(ssl); + ssl->verify_mode = mode; + if (callback != NULL) { + ssl->verify_callback = callback; + } +} + +void SSL_set_verify_depth(SSL *ssl, int depth) { + check_ssl_x509_method(ssl); + X509_VERIFY_PARAM_set_depth(ssl->param, depth); +} + +void SSL_CTX_set_cert_verify_callback(SSL_CTX *ctx, + int (*cb)(X509_STORE_CTX *store_ctx, + void *arg), + void *arg) { + check_ssl_ctx_x509_method(ctx); + 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 *)) { + check_ssl_ctx_x509_method(ctx); + ctx->verify_mode = mode; + ctx->default_verify_callback = cb; +} + +void SSL_CTX_set_verify_depth(SSL_CTX *ctx, int depth) { + check_ssl_ctx_x509_method(ctx); + X509_VERIFY_PARAM_set_depth(ctx->param, depth); +} + +int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx) { + check_ssl_ctx_x509_method(ctx); + return X509_STORE_set_default_paths(ctx->cert_store); +} + +int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *ca_file, + const char *ca_dir) { + check_ssl_ctx_x509_method(ctx); + return X509_STORE_load_locations(ctx->cert_store, ca_file, ca_dir); +} + +void SSL_set_verify_result(SSL *ssl, long result) { + check_ssl_x509_method(ssl); + if (result != X509_V_OK) { + abort(); + } +} + +long SSL_get_verify_result(const SSL *ssl) { + check_ssl_x509_method(ssl); + SSL_SESSION *session = SSL_get_session(ssl); + if (session == NULL) { + return X509_V_ERR_INVALID_CALL; + } + return session->verify_result; +} + +X509_STORE *SSL_CTX_get_cert_store(const SSL_CTX *ctx) { + check_ssl_ctx_x509_method(ctx); + return ctx->cert_store; +} + +void SSL_CTX_set_cert_store(SSL_CTX *ctx, X509_STORE *store) { + check_ssl_ctx_x509_method(ctx); + X509_STORE_free(ctx->cert_store); + ctx->cert_store = store; +} + +static int ssl_use_certificate(CERT *cert, X509 *x) { + if (x == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + UniquePtr buffer = x509_to_buffer(x); + if (!buffer) { + return 0; + } + + return ssl_set_cert(cert, std::move(buffer)); +} + +int SSL_use_certificate(SSL *ssl, X509 *x) { + check_ssl_x509_method(ssl); + return ssl_use_certificate(ssl->cert, x); +} + +int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x) { + check_ssl_ctx_x509_method(ctx); + return ssl_use_certificate(ctx->cert, x); +} + +// ssl_cert_cache_leaf_cert sets |cert->x509_leaf|, if currently NULL, from the +// first element of |cert->chain|. +static int ssl_cert_cache_leaf_cert(CERT *cert) { + assert(cert->x509_method); + + if (cert->x509_leaf != NULL || + cert->chain == NULL) { + return 1; + } + + CRYPTO_BUFFER *leaf = sk_CRYPTO_BUFFER_value(cert->chain, 0); + if (!leaf) { + return 1; + } + + cert->x509_leaf = X509_parse_from_buffer(leaf); + return cert->x509_leaf != NULL; +} + +static X509 *ssl_cert_get0_leaf(CERT *cert) { + if (cert->x509_leaf == NULL && + !ssl_cert_cache_leaf_cert(cert)) { + return NULL; + } + + return cert->x509_leaf; +} + +X509 *SSL_get_certificate(const SSL *ssl) { + check_ssl_x509_method(ssl); + return ssl_cert_get0_leaf(ssl->cert); +} + +X509 *SSL_CTX_get0_certificate(const SSL_CTX *ctx) { + check_ssl_ctx_x509_method(ctx); + MutexWriteLock lock(const_cast(&ctx->lock)); + return ssl_cert_get0_leaf(ctx->cert); +} + +static int ssl_cert_set0_chain(CERT *cert, STACK_OF(X509) *chain) { + if (!ssl_cert_set_chain(cert, chain)) { + return 0; + } + + sk_X509_pop_free(chain, X509_free); + ssl_crypto_x509_cert_flush_cached_chain(cert); + return 1; +} + +static int ssl_cert_set1_chain(CERT *cert, STACK_OF(X509) *chain) { + if (!ssl_cert_set_chain(cert, chain)) { + return 0; + } + + ssl_crypto_x509_cert_flush_cached_chain(cert); + return 1; +} + +static int ssl_cert_append_cert(CERT *cert, X509 *x509) { + assert(cert->x509_method); + + UniquePtr buffer = x509_to_buffer(x509); + if (!buffer) { + return 0; + } + + if (cert->chain != NULL) { + return PushToStack(cert->chain, std::move(buffer)); + } + + cert->chain = new_leafless_chain(); + if (cert->chain == NULL || + !PushToStack(cert->chain, std::move(buffer))) { + sk_CRYPTO_BUFFER_free(cert->chain); + cert->chain = NULL; + return 0; + } + + return 1; +} + +static int ssl_cert_add0_chain_cert(CERT *cert, X509 *x509) { + if (!ssl_cert_append_cert(cert, x509)) { + return 0; + } + + X509_free(cert->x509_stash); + cert->x509_stash = x509; + ssl_crypto_x509_cert_flush_cached_chain(cert); + return 1; +} + +static int ssl_cert_add1_chain_cert(CERT *cert, X509 *x509) { + if (!ssl_cert_append_cert(cert, x509)) { + return 0; + } + + ssl_crypto_x509_cert_flush_cached_chain(cert); + return 1; +} + +int SSL_CTX_set0_chain(SSL_CTX *ctx, STACK_OF(X509) *chain) { + check_ssl_ctx_x509_method(ctx); + return ssl_cert_set0_chain(ctx->cert, chain); +} + +int SSL_CTX_set1_chain(SSL_CTX *ctx, STACK_OF(X509) *chain) { + check_ssl_ctx_x509_method(ctx); + return ssl_cert_set1_chain(ctx->cert, chain); +} + +int SSL_set0_chain(SSL *ssl, STACK_OF(X509) *chain) { + check_ssl_x509_method(ssl); + return ssl_cert_set0_chain(ssl->cert, chain); +} + +int SSL_set1_chain(SSL *ssl, STACK_OF(X509) *chain) { + check_ssl_x509_method(ssl); + return ssl_cert_set1_chain(ssl->cert, chain); +} + +int SSL_CTX_add0_chain_cert(SSL_CTX *ctx, X509 *x509) { + check_ssl_ctx_x509_method(ctx); + return ssl_cert_add0_chain_cert(ctx->cert, x509); +} + +int SSL_CTX_add1_chain_cert(SSL_CTX *ctx, X509 *x509) { + check_ssl_ctx_x509_method(ctx); + return ssl_cert_add1_chain_cert(ctx->cert, x509); +} + +int SSL_CTX_add_extra_chain_cert(SSL_CTX *ctx, X509 *x509) { + check_ssl_ctx_x509_method(ctx); + return SSL_CTX_add0_chain_cert(ctx, x509); +} + +int SSL_add0_chain_cert(SSL *ssl, X509 *x509) { + check_ssl_x509_method(ssl); + return ssl_cert_add0_chain_cert(ssl->cert, x509); +} + +int SSL_add1_chain_cert(SSL *ssl, X509 *x509) { + check_ssl_x509_method(ssl); + return ssl_cert_add1_chain_cert(ssl->cert, x509); +} + +int SSL_CTX_clear_chain_certs(SSL_CTX *ctx) { + check_ssl_ctx_x509_method(ctx); + return SSL_CTX_set0_chain(ctx, NULL); +} + +int SSL_CTX_clear_extra_chain_certs(SSL_CTX *ctx) { + check_ssl_ctx_x509_method(ctx); + return SSL_CTX_clear_chain_certs(ctx); +} + +int SSL_clear_chain_certs(SSL *ssl) { + check_ssl_x509_method(ssl); + return SSL_set0_chain(ssl, NULL); +} + +// ssl_cert_cache_chain_certs fills in |cert->x509_chain| from elements 1.. of +// |cert->chain|. +static int ssl_cert_cache_chain_certs(CERT *cert) { + assert(cert->x509_method); + + if (cert->x509_chain != NULL || + cert->chain == NULL || + sk_CRYPTO_BUFFER_num(cert->chain) < 2) { + return 1; + } + + UniquePtr chain(sk_X509_new_null()); + if (!chain) { + return 0; + } + + for (size_t i = 1; i < sk_CRYPTO_BUFFER_num(cert->chain); i++) { + CRYPTO_BUFFER *buffer = sk_CRYPTO_BUFFER_value(cert->chain, i); + UniquePtr x509(X509_parse_from_buffer(buffer)); + if (!x509 || + !PushToStack(chain.get(), std::move(x509))) { + return 0; + } + } + + cert->x509_chain = chain.release(); + return 1; +} + +int SSL_CTX_get0_chain_certs(const SSL_CTX *ctx, STACK_OF(X509) **out_chain) { + check_ssl_ctx_x509_method(ctx); + MutexWriteLock lock(const_cast(&ctx->lock)); + if (!ssl_cert_cache_chain_certs(ctx->cert)) { + *out_chain = NULL; + return 0; + } + + *out_chain = ctx->cert->x509_chain; + return 1; +} + +int SSL_CTX_get_extra_chain_certs(const SSL_CTX *ctx, + STACK_OF(X509) **out_chain) { + return SSL_CTX_get0_chain_certs(ctx, out_chain); +} + +int SSL_get0_chain_certs(const SSL *ssl, STACK_OF(X509) **out_chain) { + check_ssl_x509_method(ssl); + if (!ssl_cert_cache_chain_certs(ssl->cert)) { + *out_chain = NULL; + return 0; + } + + *out_chain = ssl->cert->x509_chain; + return 1; +} + +static SSL_SESSION *ssl_session_new_with_crypto_x509(void) { + return ssl_session_new(&ssl_crypto_x509_method).release(); +} + +SSL_SESSION *d2i_SSL_SESSION_bio(BIO *bio, SSL_SESSION **out) { + return ASN1_d2i_bio_of(SSL_SESSION, ssl_session_new_with_crypto_x509, + d2i_SSL_SESSION, bio, out); +} + +int i2d_SSL_SESSION_bio(BIO *bio, const SSL_SESSION *session) { + return ASN1_i2d_bio_of(SSL_SESSION, i2d_SSL_SESSION, bio, session); +} + +IMPLEMENT_PEM_rw(SSL_SESSION, SSL_SESSION, PEM_STRING_SSL_SESSION, SSL_SESSION) + +SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const uint8_t **pp, long length) { + if (length < 0) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return NULL; + } + + CBS cbs; + CBS_init(&cbs, *pp, length); + + UniquePtr ret = SSL_SESSION_parse(&cbs, &ssl_crypto_x509_method, + NULL /* no buffer pool */); + if (!ret) { + return NULL; + } + + if (a) { + SSL_SESSION_free(*a); + *a = ret.get(); + } + *pp = CBS_data(&cbs); + return ret.release(); +} + +STACK_OF(X509_NAME) *SSL_dup_CA_list(STACK_OF(X509_NAME) *list) { + return sk_X509_NAME_deep_copy(list, X509_NAME_dup, X509_NAME_free); +} + +static void set_client_CA_list(STACK_OF(CRYPTO_BUFFER) **ca_list, + const STACK_OF(X509_NAME) *name_list, + CRYPTO_BUFFER_POOL *pool) { + UniquePtr buffers(sk_CRYPTO_BUFFER_new_null()); + if (!buffers) { + return; + } + + for (X509_NAME *name : name_list) { + uint8_t *outp = NULL; + int len = i2d_X509_NAME(name, &outp); + if (len < 0) { + return; + } + + UniquePtr buffer(CRYPTO_BUFFER_new(outp, len, pool)); + OPENSSL_free(outp); + if (!buffer || + !PushToStack(buffers.get(), std::move(buffer))) { + return; + } + } + + sk_CRYPTO_BUFFER_pop_free(*ca_list, CRYPTO_BUFFER_free); + *ca_list = buffers.release(); +} + +void SSL_set_client_CA_list(SSL *ssl, STACK_OF(X509_NAME) *name_list) { + check_ssl_x509_method(ssl); + ssl->ctx->x509_method->ssl_flush_cached_client_CA(ssl); + set_client_CA_list(&ssl->client_CA, name_list, ssl->ctx->pool); + sk_X509_NAME_pop_free(name_list, X509_NAME_free); +} + +void SSL_CTX_set_client_CA_list(SSL_CTX *ctx, STACK_OF(X509_NAME) *name_list) { + check_ssl_ctx_x509_method(ctx); + ctx->x509_method->ssl_ctx_flush_cached_client_CA(ctx); + set_client_CA_list(&ctx->client_CA, name_list, ctx->pool); + sk_X509_NAME_pop_free(name_list, X509_NAME_free); +} + +static STACK_OF(X509_NAME) * + buffer_names_to_x509(const STACK_OF(CRYPTO_BUFFER) *names, + STACK_OF(X509_NAME) **cached) { + if (names == NULL) { + return NULL; + } + + if (*cached != NULL) { + return *cached; + } + + UniquePtr new_cache(sk_X509_NAME_new_null()); + if (!new_cache) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return NULL; + } + + for (const CRYPTO_BUFFER *buffer : names) { + const uint8_t *inp = CRYPTO_BUFFER_data(buffer); + UniquePtr name( + d2i_X509_NAME(nullptr, &inp, CRYPTO_BUFFER_len(buffer))); + if (!name || + inp != CRYPTO_BUFFER_data(buffer) + CRYPTO_BUFFER_len(buffer) || + !PushToStack(new_cache.get(), std::move(name))) { + return NULL; + } + } + + *cached = new_cache.release(); + return *cached; +} + +STACK_OF(X509_NAME) *SSL_get_client_CA_list(const SSL *ssl) { + check_ssl_x509_method(ssl); + // For historical reasons, this function is used both to query configuration + // state on a server as well as handshake state on a client. However, whether + // |ssl| is a client or server is not known until explicitly configured with + // |SSL_set_connect_state|. If |do_handshake| is NULL, |ssl| is in an + // indeterminate mode and |ssl->server| is unset. + if (ssl->do_handshake != NULL && !ssl->server) { + if (ssl->s3->hs != NULL) { + return buffer_names_to_x509(ssl->s3->hs->ca_names.get(), + &ssl->s3->hs->cached_x509_ca_names); + } + + return NULL; + } + + if (ssl->client_CA != NULL) { + return buffer_names_to_x509( + ssl->client_CA, (STACK_OF(X509_NAME) **)&ssl->cached_x509_client_CA); + } + return SSL_CTX_get_client_CA_list(ssl->ctx); +} + +STACK_OF(X509_NAME) *SSL_CTX_get_client_CA_list(const SSL_CTX *ctx) { + check_ssl_ctx_x509_method(ctx); + // This is a logically const operation that may be called on multiple threads, + // so it needs to lock around updating |cached_x509_client_CA|. + MutexWriteLock lock(const_cast(&ctx->lock)); + return buffer_names_to_x509( + ctx->client_CA, + const_cast(&ctx->cached_x509_client_CA)); +} + +static int add_client_CA(STACK_OF(CRYPTO_BUFFER) **names, X509 *x509, + CRYPTO_BUFFER_POOL *pool) { + if (x509 == NULL) { + return 0; + } + + uint8_t *outp = NULL; + int len = i2d_X509_NAME(X509_get_subject_name(x509), &outp); + if (len < 0) { + return 0; + } + + UniquePtr buffer(CRYPTO_BUFFER_new(outp, len, pool)); + OPENSSL_free(outp); + if (!buffer) { + return 0; + } + + int alloced = 0; + if (*names == NULL) { + *names = sk_CRYPTO_BUFFER_new_null(); + alloced = 1; + + if (*names == NULL) { + return 0; + } + } + + if (!PushToStack(*names, std::move(buffer))) { + if (alloced) { + sk_CRYPTO_BUFFER_pop_free(*names, CRYPTO_BUFFER_free); + *names = NULL; + } + return 0; + } + + return 1; +} + +int SSL_add_client_CA(SSL *ssl, X509 *x509) { + check_ssl_x509_method(ssl); + if (!add_client_CA(&ssl->client_CA, x509, ssl->ctx->pool)) { + return 0; + } + + ssl_crypto_x509_ssl_flush_cached_client_CA(ssl); + return 1; +} + +int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x509) { + check_ssl_ctx_x509_method(ctx); + if (!add_client_CA(&ctx->client_CA, x509, ctx->pool)) { + return 0; + } + + ssl_crypto_x509_ssl_ctx_flush_cached_client_CA(ctx); + return 1; +} + +static int do_client_cert_cb(SSL *ssl, void *arg) { + if (ssl_has_certificate(ssl) || ssl->ctx->client_cert_cb == NULL) { + return 1; + } + + X509 *x509 = NULL; + EVP_PKEY *pkey = NULL; + int ret = ssl->ctx->client_cert_cb(ssl, &x509, &pkey); + if (ret < 0) { + return -1; + } + UniquePtr free_x509(x509); + UniquePtr free_pkey(pkey); + + if (ret != 0) { + if (!SSL_use_certificate(ssl, x509) || + !SSL_use_PrivateKey(ssl, pkey)) { + return 0; + } + } + + return 1; +} + +void SSL_CTX_set_client_cert_cb(SSL_CTX *ctx, int (*cb)(SSL *ssl, + X509 **out_x509, + EVP_PKEY **out_pkey)) { + check_ssl_ctx_x509_method(ctx); + // Emulate the old client certificate callback with the new one. + SSL_CTX_set_cert_cb(ctx, do_client_cert_cb, NULL); + ctx->client_cert_cb = cb; +} + +static int set_cert_store(X509_STORE **store_ptr, X509_STORE *new_store, + int take_ref) { + X509_STORE_free(*store_ptr); + *store_ptr = new_store; + + if (new_store != NULL && take_ref) { + X509_STORE_up_ref(new_store); + } + + return 1; +} + +int SSL_get_ex_data_X509_STORE_CTX_idx(void) { + // The ex_data index to go from |X509_STORE_CTX| to |SSL| always uses the + // reserved app_data slot. Before ex_data was introduced, app_data was used. + // Avoid breaking any software which assumes |X509_STORE_CTX_get_app_data| + // works. + return 0; +} + +int SSL_CTX_set0_verify_cert_store(SSL_CTX *ctx, X509_STORE *store) { + check_ssl_ctx_x509_method(ctx); + return set_cert_store(&ctx->cert->verify_store, store, 0); +} + +int SSL_CTX_set1_verify_cert_store(SSL_CTX *ctx, X509_STORE *store) { + check_ssl_ctx_x509_method(ctx); + return set_cert_store(&ctx->cert->verify_store, store, 1); +} + +int SSL_set0_verify_cert_store(SSL *ssl, X509_STORE *store) { + check_ssl_x509_method(ssl); + return set_cert_store(&ssl->cert->verify_store, store, 0); +} + +int SSL_set1_verify_cert_store(SSL *ssl, X509_STORE *store) { + check_ssl_x509_method(ssl); + return set_cert_store(&ssl->cert->verify_store, store, 1); +} + +int SSL_alert_from_verify_result(long result) { + switch (result) { + case X509_V_ERR_CERT_CHAIN_TOO_LONG: + case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: + case X509_V_ERR_INVALID_CA: + case X509_V_ERR_PATH_LENGTH_EXCEEDED: + case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN: + case X509_V_ERR_UNABLE_TO_GET_CRL: + case X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER: + case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: + case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY: + case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE: + return SSL_AD_UNKNOWN_CA; + + 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_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: + return SSL_AD_BAD_CERTIFICATE; + + case X509_V_ERR_CERT_SIGNATURE_FAILURE: + case X509_V_ERR_CRL_SIGNATURE_FAILURE: + return SSL_AD_DECRYPT_ERROR; + + case X509_V_ERR_CERT_HAS_EXPIRED: + case X509_V_ERR_CERT_NOT_YET_VALID: + case X509_V_ERR_CRL_HAS_EXPIRED: + case X509_V_ERR_CRL_NOT_YET_VALID: + return SSL_AD_CERTIFICATE_EXPIRED; + + case X509_V_ERR_CERT_REVOKED: + return SSL_AD_CERTIFICATE_REVOKED; + + case X509_V_ERR_UNSPECIFIED: + case X509_V_ERR_OUT_OF_MEM: + case X509_V_ERR_INVALID_CALL: + case X509_V_ERR_STORE_LOOKUP: + return SSL_AD_INTERNAL_ERROR; + + case X509_V_ERR_APPLICATION_VERIFICATION: + return SSL_AD_HANDSHAKE_FAILURE; + + case X509_V_ERR_INVALID_PURPOSE: + return SSL_AD_UNSUPPORTED_CERTIFICATE; + + default: + return SSL_AD_CERTIFICATE_UNKNOWN; + } +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/ssl/ssl_x509.cc.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/ssl/ssl_x509.cc.grpc_back new file mode 100644 index 0000000..cc27a60 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/ssl/ssl_x509.cc.grpc_back @@ -0,0 +1,1297 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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. + */ +/* ==================================================================== + * 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 +#include +#include +#include +#include +#include +#include +#include + +#include "internal.h" +#include "../crypto/internal.h" + + +namespace bssl { + +// check_ssl_x509_method asserts that |ssl| has the X509-based method +// installed. Calling an X509-based method on an |ssl| with a different method +// will likely misbehave and possibly crash or leak memory. +static void check_ssl_x509_method(const SSL *ssl) { + assert(ssl == NULL || ssl->ctx->x509_method == &ssl_crypto_x509_method); +} + +// check_ssl_ctx_x509_method acts like |check_ssl_x509_method|, but for an +// |SSL_CTX|. +static void check_ssl_ctx_x509_method(const SSL_CTX *ctx) { + assert(ctx == NULL || ctx->x509_method == &ssl_crypto_x509_method); +} + +// x509_to_buffer returns a |CRYPTO_BUFFER| that contains the serialised +// contents of |x509|. +static UniquePtr x509_to_buffer(X509 *x509) { + uint8_t *buf = NULL; + int cert_len = i2d_X509(x509, &buf); + if (cert_len <= 0) { + return 0; + } + + UniquePtr buffer(CRYPTO_BUFFER_new(buf, cert_len, NULL)); + OPENSSL_free(buf); + + return buffer; +} + +// new_leafless_chain returns a fresh stack of buffers set to {NULL}. +static STACK_OF(CRYPTO_BUFFER) *new_leafless_chain(void) { + STACK_OF(CRYPTO_BUFFER) *chain = sk_CRYPTO_BUFFER_new_null(); + if (chain == NULL) { + return NULL; + } + + if (!sk_CRYPTO_BUFFER_push(chain, NULL)) { + sk_CRYPTO_BUFFER_free(chain); + return NULL; + } + + return chain; +} + +// ssl_cert_set_chain sets elements 1.. of |cert->chain| to the serialised +// forms of elements of |chain|. It returns one on success or zero on error, in +// which case no change to |cert->chain| is made. It preverses the existing +// leaf from |cert->chain|, if any. +static int ssl_cert_set_chain(CERT *cert, STACK_OF(X509) *chain) { + UniquePtr new_chain; + + if (cert->chain != NULL) { + new_chain.reset(sk_CRYPTO_BUFFER_new_null()); + if (!new_chain) { + return 0; + } + + CRYPTO_BUFFER *leaf = sk_CRYPTO_BUFFER_value(cert->chain, 0); + if (!sk_CRYPTO_BUFFER_push(new_chain.get(), leaf)) { + return 0; + } + // |leaf| might be NULL if it's a “leafless” chain. + if (leaf != NULL) { + CRYPTO_BUFFER_up_ref(leaf); + } + } + + for (X509 *x509 : chain) { + if (!new_chain) { + new_chain.reset(new_leafless_chain()); + if (!new_chain) { + return 0; + } + } + + UniquePtr buffer = x509_to_buffer(x509); + if (!buffer || + !PushToStack(new_chain.get(), std::move(buffer))) { + return 0; + } + } + + sk_CRYPTO_BUFFER_pop_free(cert->chain, CRYPTO_BUFFER_free); + cert->chain = new_chain.release(); + + return 1; +} + +static void ssl_crypto_x509_cert_flush_cached_leaf(CERT *cert) { + X509_free(cert->x509_leaf); + cert->x509_leaf = NULL; +} + +static void ssl_crypto_x509_cert_flush_cached_chain(CERT *cert) { + sk_X509_pop_free(cert->x509_chain, X509_free); + cert->x509_chain = NULL; +} + +static int ssl_crypto_x509_check_client_CA_list( + STACK_OF(CRYPTO_BUFFER) *names) { + for (const CRYPTO_BUFFER *buffer : names) { + const uint8_t *inp = CRYPTO_BUFFER_data(buffer); + X509_NAME *name = d2i_X509_NAME(NULL, &inp, CRYPTO_BUFFER_len(buffer)); + const int ok = name != NULL && inp == CRYPTO_BUFFER_data(buffer) + + CRYPTO_BUFFER_len(buffer); + X509_NAME_free(name); + if (!ok) { + return 0; + } + } + + return 1; +} + +static void ssl_crypto_x509_cert_clear(CERT *cert) { + ssl_crypto_x509_cert_flush_cached_leaf(cert); + ssl_crypto_x509_cert_flush_cached_chain(cert); + + X509_free(cert->x509_stash); + cert->x509_stash = NULL; +} + +static void ssl_crypto_x509_cert_free(CERT *cert) { + ssl_crypto_x509_cert_clear(cert); + X509_STORE_free(cert->verify_store); +} + +static void ssl_crypto_x509_cert_dup(CERT *new_cert, const CERT *cert) { + if (cert->verify_store != NULL) { + X509_STORE_up_ref(cert->verify_store); + new_cert->verify_store = cert->verify_store; + } +} + +static int ssl_crypto_x509_session_cache_objects(SSL_SESSION *sess) { + bssl::UniquePtr chain; + if (sk_CRYPTO_BUFFER_num(sess->certs) > 0) { + chain.reset(sk_X509_new_null()); + if (!chain) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + } + + X509 *leaf = nullptr; + for (CRYPTO_BUFFER *cert : sess->certs) { + UniquePtr x509(X509_parse_from_buffer(cert)); + if (!x509) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + return 0; + } + if (leaf == nullptr) { + leaf = x509.get(); + } + if (!PushToStack(chain.get(), std::move(x509))) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + } + + sk_X509_pop_free(sess->x509_chain, X509_free); + sess->x509_chain = chain.release(); + sk_X509_pop_free(sess->x509_chain_without_leaf, X509_free); + sess->x509_chain_without_leaf = NULL; + + X509_free(sess->x509_peer); + if (leaf != NULL) { + X509_up_ref(leaf); + } + sess->x509_peer = leaf; + return 1; +} + +static int ssl_crypto_x509_session_dup(SSL_SESSION *new_session, + const SSL_SESSION *session) { + if (session->x509_peer != NULL) { + X509_up_ref(session->x509_peer); + new_session->x509_peer = session->x509_peer; + } + if (session->x509_chain != NULL) { + new_session->x509_chain = X509_chain_up_ref(session->x509_chain); + if (new_session->x509_chain == NULL) { + return 0; + } + } + + return 1; +} + +static void ssl_crypto_x509_session_clear(SSL_SESSION *session) { + X509_free(session->x509_peer); + session->x509_peer = NULL; + sk_X509_pop_free(session->x509_chain, X509_free); + session->x509_chain = NULL; + sk_X509_pop_free(session->x509_chain_without_leaf, X509_free); + session->x509_chain_without_leaf = NULL; +} + +static int ssl_crypto_x509_session_verify_cert_chain(SSL_SESSION *session, + SSL *ssl, + uint8_t *out_alert) { + *out_alert = SSL_AD_INTERNAL_ERROR; + STACK_OF(X509) *const cert_chain = session->x509_chain; + if (cert_chain == NULL || sk_X509_num(cert_chain) == 0) { + return 0; + } + + X509_STORE *verify_store = ssl->ctx->cert_store; + if (ssl->cert->verify_store != NULL) { + verify_store = ssl->cert->verify_store; + } + + X509 *leaf = sk_X509_value(cert_chain, 0); + ScopedX509_STORE_CTX ctx; + if (!X509_STORE_CTX_init(ctx.get(), verify_store, leaf, cert_chain)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_X509_LIB); + return 0; + } + if (!X509_STORE_CTX_set_ex_data(ctx.get(), + SSL_get_ex_data_X509_STORE_CTX_idx(), ssl)) { + return 0; + } + + // 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.get(), + ssl->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.get()), ssl->param); + + if (ssl->verify_callback) { + X509_STORE_CTX_set_verify_cb(ctx.get(), ssl->verify_callback); + } + + int verify_ret; + if (ssl->ctx->app_verify_callback != NULL) { + verify_ret = + ssl->ctx->app_verify_callback(ctx.get(), ssl->ctx->app_verify_arg); + } else { + verify_ret = X509_verify_cert(ctx.get()); + } + + session->verify_result = ctx->error; + + // If |SSL_VERIFY_NONE|, the error is non-fatal, but we keep the result. + if (verify_ret <= 0 && ssl->verify_mode != SSL_VERIFY_NONE) { + *out_alert = SSL_alert_from_verify_result(ctx->error); + return 0; + } + + ERR_clear_error(); + return 1; +} + +static void ssl_crypto_x509_hs_flush_cached_ca_names(SSL_HANDSHAKE *hs) { + sk_X509_NAME_pop_free(hs->cached_x509_ca_names, X509_NAME_free); + hs->cached_x509_ca_names = NULL; +} + +static int ssl_crypto_x509_ssl_new(SSL *ssl) { + ssl->param = X509_VERIFY_PARAM_new(); + if (ssl->param == NULL) { + return 0; + } + X509_VERIFY_PARAM_inherit(ssl->param, ssl->ctx->param); + return 1; +} + +static void ssl_crypto_x509_ssl_flush_cached_client_CA(SSL *ssl) { + sk_X509_NAME_pop_free(ssl->cached_x509_client_CA, X509_NAME_free); + ssl->cached_x509_client_CA = NULL; +} + +static void ssl_crypto_x509_ssl_free(SSL *ssl) { + ssl_crypto_x509_ssl_flush_cached_client_CA(ssl); + X509_VERIFY_PARAM_free(ssl->param); +} + +static int ssl_crypto_x509_ssl_auto_chain_if_needed(SSL *ssl) { + // Only build a chain if there are no intermediates configured and the feature + // isn't disabled. + if ((ssl->mode & SSL_MODE_NO_AUTO_CHAIN) || + !ssl_has_certificate(ssl) || + ssl->cert->chain == NULL || + sk_CRYPTO_BUFFER_num(ssl->cert->chain) > 1) { + return 1; + } + + UniquePtr leaf( + X509_parse_from_buffer(sk_CRYPTO_BUFFER_value(ssl->cert->chain, 0))); + if (!leaf) { + OPENSSL_PUT_ERROR(SSL, ERR_R_X509_LIB); + return 0; + } + + ScopedX509_STORE_CTX ctx; + if (!X509_STORE_CTX_init(ctx.get(), ssl->ctx->cert_store, leaf.get(), NULL)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_X509_LIB); + return 0; + } + + // Attempt to build a chain, ignoring the result. + X509_verify_cert(ctx.get()); + ERR_clear_error(); + + // Remove the leaf from the generated chain. + X509_free(sk_X509_shift(ctx->chain)); + + if (!ssl_cert_set_chain(ssl->cert, ctx->chain)) { + return 0; + } + + ssl_crypto_x509_cert_flush_cached_chain(ssl->cert); + + return 1; +} + +static void ssl_crypto_x509_ssl_ctx_flush_cached_client_CA(SSL_CTX *ctx) { + sk_X509_NAME_pop_free(ctx->cached_x509_client_CA, X509_NAME_free); + ctx->cached_x509_client_CA = NULL; +} + +static int ssl_crypto_x509_ssl_ctx_new(SSL_CTX *ctx) { + ctx->cert_store = X509_STORE_new(); + ctx->param = X509_VERIFY_PARAM_new(); + return (ctx->cert_store != NULL && ctx->param != NULL); +} + +static void ssl_crypto_x509_ssl_ctx_free(SSL_CTX *ctx) { + ssl_crypto_x509_ssl_ctx_flush_cached_client_CA(ctx); + X509_VERIFY_PARAM_free(ctx->param); + X509_STORE_free(ctx->cert_store); +} + +const SSL_X509_METHOD ssl_crypto_x509_method = { + ssl_crypto_x509_check_client_CA_list, + ssl_crypto_x509_cert_clear, + ssl_crypto_x509_cert_free, + ssl_crypto_x509_cert_dup, + ssl_crypto_x509_cert_flush_cached_chain, + ssl_crypto_x509_cert_flush_cached_leaf, + ssl_crypto_x509_session_cache_objects, + ssl_crypto_x509_session_dup, + ssl_crypto_x509_session_clear, + ssl_crypto_x509_session_verify_cert_chain, + ssl_crypto_x509_hs_flush_cached_ca_names, + ssl_crypto_x509_ssl_new, + ssl_crypto_x509_ssl_free, + ssl_crypto_x509_ssl_flush_cached_client_CA, + ssl_crypto_x509_ssl_auto_chain_if_needed, + ssl_crypto_x509_ssl_ctx_new, + ssl_crypto_x509_ssl_ctx_free, + ssl_crypto_x509_ssl_ctx_flush_cached_client_CA, +}; + +} // namespace bssl + +using namespace bssl; + +X509 *SSL_get_peer_certificate(const SSL *ssl) { + check_ssl_x509_method(ssl); + if (ssl == NULL) { + return NULL; + } + SSL_SESSION *session = SSL_get_session(ssl); + if (session == NULL || session->x509_peer == NULL) { + return NULL; + } + X509_up_ref(session->x509_peer); + return session->x509_peer; +} + +STACK_OF(X509) *SSL_get_peer_cert_chain(const SSL *ssl) { + check_ssl_x509_method(ssl); + if (ssl == NULL) { + return NULL; + } + SSL_SESSION *session = SSL_get_session(ssl); + if (session == NULL || + session->x509_chain == NULL) { + return NULL; + } + + if (!ssl->server) { + return session->x509_chain; + } + + // OpenSSL historically didn't include the leaf certificate in the returned + // certificate chain, but only for servers. + if (session->x509_chain_without_leaf == NULL) { + session->x509_chain_without_leaf = sk_X509_new_null(); + if (session->x509_chain_without_leaf == NULL) { + return NULL; + } + + for (size_t i = 1; i < sk_X509_num(session->x509_chain); i++) { + X509 *cert = sk_X509_value(session->x509_chain, i); + if (!sk_X509_push(session->x509_chain_without_leaf, cert)) { + sk_X509_pop_free(session->x509_chain_without_leaf, X509_free); + session->x509_chain_without_leaf = NULL; + return NULL; + } + X509_up_ref(cert); + } + } + + return session->x509_chain_without_leaf; +} + +STACK_OF(X509) *SSL_get_peer_full_cert_chain(const SSL *ssl) { + check_ssl_x509_method(ssl); + SSL_SESSION *session = SSL_get_session(ssl); + if (session == NULL) { + return NULL; + } + + return session->x509_chain; +} + +int SSL_CTX_set_purpose(SSL_CTX *ctx, int purpose) { + check_ssl_ctx_x509_method(ctx); + return X509_VERIFY_PARAM_set_purpose(ctx->param, purpose); +} + +int SSL_set_purpose(SSL *ssl, int purpose) { + check_ssl_x509_method(ssl); + return X509_VERIFY_PARAM_set_purpose(ssl->param, purpose); +} + +int SSL_CTX_set_trust(SSL_CTX *ctx, int trust) { + check_ssl_ctx_x509_method(ctx); + return X509_VERIFY_PARAM_set_trust(ctx->param, trust); +} + +int SSL_set_trust(SSL *ssl, int trust) { + check_ssl_x509_method(ssl); + return X509_VERIFY_PARAM_set_trust(ssl->param, trust); +} + +int SSL_CTX_set1_param(SSL_CTX *ctx, const X509_VERIFY_PARAM *param) { + check_ssl_ctx_x509_method(ctx); + return X509_VERIFY_PARAM_set1(ctx->param, param); +} + +int SSL_set1_param(SSL *ssl, const X509_VERIFY_PARAM *param) { + check_ssl_x509_method(ssl); + return X509_VERIFY_PARAM_set1(ssl->param, param); +} + +X509_VERIFY_PARAM *SSL_CTX_get0_param(SSL_CTX *ctx) { + check_ssl_ctx_x509_method(ctx); + return ctx->param; +} + +X509_VERIFY_PARAM *SSL_get0_param(SSL *ssl) { + check_ssl_x509_method(ssl); + return ssl->param; +} + +int SSL_get_verify_depth(const SSL *ssl) { + check_ssl_x509_method(ssl); + return X509_VERIFY_PARAM_get_depth(ssl->param); +} + +int (*SSL_get_verify_callback(const SSL *ssl))(int, X509_STORE_CTX *) { + check_ssl_x509_method(ssl); + return ssl->verify_callback; +} + +int SSL_CTX_get_verify_mode(const SSL_CTX *ctx) { + check_ssl_ctx_x509_method(ctx); + return ctx->verify_mode; +} + +int SSL_CTX_get_verify_depth(const SSL_CTX *ctx) { + check_ssl_ctx_x509_method(ctx); + return X509_VERIFY_PARAM_get_depth(ctx->param); +} + +int (*SSL_CTX_get_verify_callback(const SSL_CTX *ctx))( + int ok, X509_STORE_CTX *store_ctx) { + check_ssl_ctx_x509_method(ctx); + return ctx->default_verify_callback; +} + +void SSL_set_verify(SSL *ssl, int mode, + int (*callback)(int ok, X509_STORE_CTX *store_ctx)) { + check_ssl_x509_method(ssl); + ssl->verify_mode = mode; + if (callback != NULL) { + ssl->verify_callback = callback; + } +} + +void SSL_set_verify_depth(SSL *ssl, int depth) { + check_ssl_x509_method(ssl); + X509_VERIFY_PARAM_set_depth(ssl->param, depth); +} + +void SSL_CTX_set_cert_verify_callback(SSL_CTX *ctx, + int (*cb)(X509_STORE_CTX *store_ctx, + void *arg), + void *arg) { + check_ssl_ctx_x509_method(ctx); + 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 *)) { + check_ssl_ctx_x509_method(ctx); + ctx->verify_mode = mode; + ctx->default_verify_callback = cb; +} + +void SSL_CTX_set_verify_depth(SSL_CTX *ctx, int depth) { + check_ssl_ctx_x509_method(ctx); + X509_VERIFY_PARAM_set_depth(ctx->param, depth); +} + +int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx) { + check_ssl_ctx_x509_method(ctx); + return X509_STORE_set_default_paths(ctx->cert_store); +} + +int SSL_CTX_load_verify_locations(SSL_CTX *ctx, const char *ca_file, + const char *ca_dir) { + check_ssl_ctx_x509_method(ctx); + return X509_STORE_load_locations(ctx->cert_store, ca_file, ca_dir); +} + +void SSL_set_verify_result(SSL *ssl, long result) { + check_ssl_x509_method(ssl); + if (result != X509_V_OK) { + abort(); + } +} + +long SSL_get_verify_result(const SSL *ssl) { + check_ssl_x509_method(ssl); + SSL_SESSION *session = SSL_get_session(ssl); + if (session == NULL) { + return X509_V_ERR_INVALID_CALL; + } + return session->verify_result; +} + +X509_STORE *SSL_CTX_get_cert_store(const SSL_CTX *ctx) { + check_ssl_ctx_x509_method(ctx); + return ctx->cert_store; +} + +void SSL_CTX_set_cert_store(SSL_CTX *ctx, X509_STORE *store) { + check_ssl_ctx_x509_method(ctx); + X509_STORE_free(ctx->cert_store); + ctx->cert_store = store; +} + +static int ssl_use_certificate(CERT *cert, X509 *x) { + if (x == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + UniquePtr buffer = x509_to_buffer(x); + if (!buffer) { + return 0; + } + + return ssl_set_cert(cert, std::move(buffer)); +} + +int SSL_use_certificate(SSL *ssl, X509 *x) { + check_ssl_x509_method(ssl); + return ssl_use_certificate(ssl->cert, x); +} + +int SSL_CTX_use_certificate(SSL_CTX *ctx, X509 *x) { + check_ssl_ctx_x509_method(ctx); + return ssl_use_certificate(ctx->cert, x); +} + +// ssl_cert_cache_leaf_cert sets |cert->x509_leaf|, if currently NULL, from the +// first element of |cert->chain|. +static int ssl_cert_cache_leaf_cert(CERT *cert) { + assert(cert->x509_method); + + if (cert->x509_leaf != NULL || + cert->chain == NULL) { + return 1; + } + + CRYPTO_BUFFER *leaf = sk_CRYPTO_BUFFER_value(cert->chain, 0); + if (!leaf) { + return 1; + } + + cert->x509_leaf = X509_parse_from_buffer(leaf); + return cert->x509_leaf != NULL; +} + +static X509 *ssl_cert_get0_leaf(CERT *cert) { + if (cert->x509_leaf == NULL && + !ssl_cert_cache_leaf_cert(cert)) { + return NULL; + } + + return cert->x509_leaf; +} + +X509 *SSL_get_certificate(const SSL *ssl) { + check_ssl_x509_method(ssl); + return ssl_cert_get0_leaf(ssl->cert); +} + +X509 *SSL_CTX_get0_certificate(const SSL_CTX *ctx) { + check_ssl_ctx_x509_method(ctx); + MutexWriteLock lock(const_cast(&ctx->lock)); + return ssl_cert_get0_leaf(ctx->cert); +} + +static int ssl_cert_set0_chain(CERT *cert, STACK_OF(X509) *chain) { + if (!ssl_cert_set_chain(cert, chain)) { + return 0; + } + + sk_X509_pop_free(chain, X509_free); + ssl_crypto_x509_cert_flush_cached_chain(cert); + return 1; +} + +static int ssl_cert_set1_chain(CERT *cert, STACK_OF(X509) *chain) { + if (!ssl_cert_set_chain(cert, chain)) { + return 0; + } + + ssl_crypto_x509_cert_flush_cached_chain(cert); + return 1; +} + +static int ssl_cert_append_cert(CERT *cert, X509 *x509) { + assert(cert->x509_method); + + UniquePtr buffer = x509_to_buffer(x509); + if (!buffer) { + return 0; + } + + if (cert->chain != NULL) { + return PushToStack(cert->chain, std::move(buffer)); + } + + cert->chain = new_leafless_chain(); + if (cert->chain == NULL || + !PushToStack(cert->chain, std::move(buffer))) { + sk_CRYPTO_BUFFER_free(cert->chain); + cert->chain = NULL; + return 0; + } + + return 1; +} + +static int ssl_cert_add0_chain_cert(CERT *cert, X509 *x509) { + if (!ssl_cert_append_cert(cert, x509)) { + return 0; + } + + X509_free(cert->x509_stash); + cert->x509_stash = x509; + ssl_crypto_x509_cert_flush_cached_chain(cert); + return 1; +} + +static int ssl_cert_add1_chain_cert(CERT *cert, X509 *x509) { + if (!ssl_cert_append_cert(cert, x509)) { + return 0; + } + + ssl_crypto_x509_cert_flush_cached_chain(cert); + return 1; +} + +int SSL_CTX_set0_chain(SSL_CTX *ctx, STACK_OF(X509) *chain) { + check_ssl_ctx_x509_method(ctx); + return ssl_cert_set0_chain(ctx->cert, chain); +} + +int SSL_CTX_set1_chain(SSL_CTX *ctx, STACK_OF(X509) *chain) { + check_ssl_ctx_x509_method(ctx); + return ssl_cert_set1_chain(ctx->cert, chain); +} + +int SSL_set0_chain(SSL *ssl, STACK_OF(X509) *chain) { + check_ssl_x509_method(ssl); + return ssl_cert_set0_chain(ssl->cert, chain); +} + +int SSL_set1_chain(SSL *ssl, STACK_OF(X509) *chain) { + check_ssl_x509_method(ssl); + return ssl_cert_set1_chain(ssl->cert, chain); +} + +int SSL_CTX_add0_chain_cert(SSL_CTX *ctx, X509 *x509) { + check_ssl_ctx_x509_method(ctx); + return ssl_cert_add0_chain_cert(ctx->cert, x509); +} + +int SSL_CTX_add1_chain_cert(SSL_CTX *ctx, X509 *x509) { + check_ssl_ctx_x509_method(ctx); + return ssl_cert_add1_chain_cert(ctx->cert, x509); +} + +int SSL_CTX_add_extra_chain_cert(SSL_CTX *ctx, X509 *x509) { + check_ssl_ctx_x509_method(ctx); + return SSL_CTX_add0_chain_cert(ctx, x509); +} + +int SSL_add0_chain_cert(SSL *ssl, X509 *x509) { + check_ssl_x509_method(ssl); + return ssl_cert_add0_chain_cert(ssl->cert, x509); +} + +int SSL_add1_chain_cert(SSL *ssl, X509 *x509) { + check_ssl_x509_method(ssl); + return ssl_cert_add1_chain_cert(ssl->cert, x509); +} + +int SSL_CTX_clear_chain_certs(SSL_CTX *ctx) { + check_ssl_ctx_x509_method(ctx); + return SSL_CTX_set0_chain(ctx, NULL); +} + +int SSL_CTX_clear_extra_chain_certs(SSL_CTX *ctx) { + check_ssl_ctx_x509_method(ctx); + return SSL_CTX_clear_chain_certs(ctx); +} + +int SSL_clear_chain_certs(SSL *ssl) { + check_ssl_x509_method(ssl); + return SSL_set0_chain(ssl, NULL); +} + +// ssl_cert_cache_chain_certs fills in |cert->x509_chain| from elements 1.. of +// |cert->chain|. +static int ssl_cert_cache_chain_certs(CERT *cert) { + assert(cert->x509_method); + + if (cert->x509_chain != NULL || + cert->chain == NULL || + sk_CRYPTO_BUFFER_num(cert->chain) < 2) { + return 1; + } + + UniquePtr chain(sk_X509_new_null()); + if (!chain) { + return 0; + } + + for (size_t i = 1; i < sk_CRYPTO_BUFFER_num(cert->chain); i++) { + CRYPTO_BUFFER *buffer = sk_CRYPTO_BUFFER_value(cert->chain, i); + UniquePtr x509(X509_parse_from_buffer(buffer)); + if (!x509 || + !PushToStack(chain.get(), std::move(x509))) { + return 0; + } + } + + cert->x509_chain = chain.release(); + return 1; +} + +int SSL_CTX_get0_chain_certs(const SSL_CTX *ctx, STACK_OF(X509) **out_chain) { + check_ssl_ctx_x509_method(ctx); + MutexWriteLock lock(const_cast(&ctx->lock)); + if (!ssl_cert_cache_chain_certs(ctx->cert)) { + *out_chain = NULL; + return 0; + } + + *out_chain = ctx->cert->x509_chain; + return 1; +} + +int SSL_CTX_get_extra_chain_certs(const SSL_CTX *ctx, + STACK_OF(X509) **out_chain) { + return SSL_CTX_get0_chain_certs(ctx, out_chain); +} + +int SSL_get0_chain_certs(const SSL *ssl, STACK_OF(X509) **out_chain) { + check_ssl_x509_method(ssl); + if (!ssl_cert_cache_chain_certs(ssl->cert)) { + *out_chain = NULL; + return 0; + } + + *out_chain = ssl->cert->x509_chain; + return 1; +} + +static SSL_SESSION *ssl_session_new_with_crypto_x509(void) { + return ssl_session_new(&ssl_crypto_x509_method).release(); +} + +SSL_SESSION *d2i_SSL_SESSION_bio(BIO *bio, SSL_SESSION **out) { + return ASN1_d2i_bio_of(SSL_SESSION, ssl_session_new_with_crypto_x509, + d2i_SSL_SESSION, bio, out); +} + +int i2d_SSL_SESSION_bio(BIO *bio, const SSL_SESSION *session) { + return ASN1_i2d_bio_of(SSL_SESSION, i2d_SSL_SESSION, bio, session); +} + +IMPLEMENT_PEM_rw(SSL_SESSION, SSL_SESSION, PEM_STRING_SSL_SESSION, SSL_SESSION) + +SSL_SESSION *d2i_SSL_SESSION(SSL_SESSION **a, const uint8_t **pp, long length) { + if (length < 0) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return NULL; + } + + CBS cbs; + CBS_init(&cbs, *pp, length); + + UniquePtr ret = SSL_SESSION_parse(&cbs, &ssl_crypto_x509_method, + NULL /* no buffer pool */); + if (!ret) { + return NULL; + } + + if (a) { + SSL_SESSION_free(*a); + *a = ret.get(); + } + *pp = CBS_data(&cbs); + return ret.release(); +} + +STACK_OF(X509_NAME) *SSL_dup_CA_list(STACK_OF(X509_NAME) *list) { + return sk_X509_NAME_deep_copy(list, X509_NAME_dup, X509_NAME_free); +} + +static void set_client_CA_list(STACK_OF(CRYPTO_BUFFER) **ca_list, + const STACK_OF(X509_NAME) *name_list, + CRYPTO_BUFFER_POOL *pool) { + UniquePtr buffers(sk_CRYPTO_BUFFER_new_null()); + if (!buffers) { + return; + } + + for (X509_NAME *name : name_list) { + uint8_t *outp = NULL; + int len = i2d_X509_NAME(name, &outp); + if (len < 0) { + return; + } + + UniquePtr buffer(CRYPTO_BUFFER_new(outp, len, pool)); + OPENSSL_free(outp); + if (!buffer || + !PushToStack(buffers.get(), std::move(buffer))) { + return; + } + } + + sk_CRYPTO_BUFFER_pop_free(*ca_list, CRYPTO_BUFFER_free); + *ca_list = buffers.release(); +} + +void SSL_set_client_CA_list(SSL *ssl, STACK_OF(X509_NAME) *name_list) { + check_ssl_x509_method(ssl); + ssl->ctx->x509_method->ssl_flush_cached_client_CA(ssl); + set_client_CA_list(&ssl->client_CA, name_list, ssl->ctx->pool); + sk_X509_NAME_pop_free(name_list, X509_NAME_free); +} + +void SSL_CTX_set_client_CA_list(SSL_CTX *ctx, STACK_OF(X509_NAME) *name_list) { + check_ssl_ctx_x509_method(ctx); + ctx->x509_method->ssl_ctx_flush_cached_client_CA(ctx); + set_client_CA_list(&ctx->client_CA, name_list, ctx->pool); + sk_X509_NAME_pop_free(name_list, X509_NAME_free); +} + +static STACK_OF(X509_NAME) * + buffer_names_to_x509(const STACK_OF(CRYPTO_BUFFER) *names, + STACK_OF(X509_NAME) **cached) { + if (names == NULL) { + return NULL; + } + + if (*cached != NULL) { + return *cached; + } + + UniquePtr new_cache(sk_X509_NAME_new_null()); + if (!new_cache) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return NULL; + } + + for (const CRYPTO_BUFFER *buffer : names) { + const uint8_t *inp = CRYPTO_BUFFER_data(buffer); + UniquePtr name( + d2i_X509_NAME(nullptr, &inp, CRYPTO_BUFFER_len(buffer))); + if (!name || + inp != CRYPTO_BUFFER_data(buffer) + CRYPTO_BUFFER_len(buffer) || + !PushToStack(new_cache.get(), std::move(name))) { + return NULL; + } + } + + *cached = new_cache.release(); + return *cached; +} + +STACK_OF(X509_NAME) *SSL_get_client_CA_list(const SSL *ssl) { + check_ssl_x509_method(ssl); + // For historical reasons, this function is used both to query configuration + // state on a server as well as handshake state on a client. However, whether + // |ssl| is a client or server is not known until explicitly configured with + // |SSL_set_connect_state|. If |do_handshake| is NULL, |ssl| is in an + // indeterminate mode and |ssl->server| is unset. + if (ssl->do_handshake != NULL && !ssl->server) { + if (ssl->s3->hs != NULL) { + return buffer_names_to_x509(ssl->s3->hs->ca_names.get(), + &ssl->s3->hs->cached_x509_ca_names); + } + + return NULL; + } + + if (ssl->client_CA != NULL) { + return buffer_names_to_x509( + ssl->client_CA, (STACK_OF(X509_NAME) **)&ssl->cached_x509_client_CA); + } + return SSL_CTX_get_client_CA_list(ssl->ctx); +} + +STACK_OF(X509_NAME) *SSL_CTX_get_client_CA_list(const SSL_CTX *ctx) { + check_ssl_ctx_x509_method(ctx); + // This is a logically const operation that may be called on multiple threads, + // so it needs to lock around updating |cached_x509_client_CA|. + MutexWriteLock lock(const_cast(&ctx->lock)); + return buffer_names_to_x509( + ctx->client_CA, + const_cast(&ctx->cached_x509_client_CA)); +} + +static int add_client_CA(STACK_OF(CRYPTO_BUFFER) **names, X509 *x509, + CRYPTO_BUFFER_POOL *pool) { + if (x509 == NULL) { + return 0; + } + + uint8_t *outp = NULL; + int len = i2d_X509_NAME(X509_get_subject_name(x509), &outp); + if (len < 0) { + return 0; + } + + UniquePtr buffer(CRYPTO_BUFFER_new(outp, len, pool)); + OPENSSL_free(outp); + if (!buffer) { + return 0; + } + + int alloced = 0; + if (*names == NULL) { + *names = sk_CRYPTO_BUFFER_new_null(); + alloced = 1; + + if (*names == NULL) { + return 0; + } + } + + if (!PushToStack(*names, std::move(buffer))) { + if (alloced) { + sk_CRYPTO_BUFFER_pop_free(*names, CRYPTO_BUFFER_free); + *names = NULL; + } + return 0; + } + + return 1; +} + +int SSL_add_client_CA(SSL *ssl, X509 *x509) { + check_ssl_x509_method(ssl); + if (!add_client_CA(&ssl->client_CA, x509, ssl->ctx->pool)) { + return 0; + } + + ssl_crypto_x509_ssl_flush_cached_client_CA(ssl); + return 1; +} + +int SSL_CTX_add_client_CA(SSL_CTX *ctx, X509 *x509) { + check_ssl_ctx_x509_method(ctx); + if (!add_client_CA(&ctx->client_CA, x509, ctx->pool)) { + return 0; + } + + ssl_crypto_x509_ssl_ctx_flush_cached_client_CA(ctx); + return 1; +} + +static int do_client_cert_cb(SSL *ssl, void *arg) { + if (ssl_has_certificate(ssl) || ssl->ctx->client_cert_cb == NULL) { + return 1; + } + + X509 *x509 = NULL; + EVP_PKEY *pkey = NULL; + int ret = ssl->ctx->client_cert_cb(ssl, &x509, &pkey); + if (ret < 0) { + return -1; + } + UniquePtr free_x509(x509); + UniquePtr free_pkey(pkey); + + if (ret != 0) { + if (!SSL_use_certificate(ssl, x509) || + !SSL_use_PrivateKey(ssl, pkey)) { + return 0; + } + } + + return 1; +} + +void SSL_CTX_set_client_cert_cb(SSL_CTX *ctx, int (*cb)(SSL *ssl, + X509 **out_x509, + EVP_PKEY **out_pkey)) { + check_ssl_ctx_x509_method(ctx); + // Emulate the old client certificate callback with the new one. + SSL_CTX_set_cert_cb(ctx, do_client_cert_cb, NULL); + ctx->client_cert_cb = cb; +} + +static int set_cert_store(X509_STORE **store_ptr, X509_STORE *new_store, + int take_ref) { + X509_STORE_free(*store_ptr); + *store_ptr = new_store; + + if (new_store != NULL && take_ref) { + X509_STORE_up_ref(new_store); + } + + return 1; +} + +int SSL_get_ex_data_X509_STORE_CTX_idx(void) { + // The ex_data index to go from |X509_STORE_CTX| to |SSL| always uses the + // reserved app_data slot. Before ex_data was introduced, app_data was used. + // Avoid breaking any software which assumes |X509_STORE_CTX_get_app_data| + // works. + return 0; +} + +int SSL_CTX_set0_verify_cert_store(SSL_CTX *ctx, X509_STORE *store) { + check_ssl_ctx_x509_method(ctx); + return set_cert_store(&ctx->cert->verify_store, store, 0); +} + +int SSL_CTX_set1_verify_cert_store(SSL_CTX *ctx, X509_STORE *store) { + check_ssl_ctx_x509_method(ctx); + return set_cert_store(&ctx->cert->verify_store, store, 1); +} + +int SSL_set0_verify_cert_store(SSL *ssl, X509_STORE *store) { + check_ssl_x509_method(ssl); + return set_cert_store(&ssl->cert->verify_store, store, 0); +} + +int SSL_set1_verify_cert_store(SSL *ssl, X509_STORE *store) { + check_ssl_x509_method(ssl); + return set_cert_store(&ssl->cert->verify_store, store, 1); +} + +int SSL_alert_from_verify_result(long result) { + switch (result) { + case X509_V_ERR_CERT_CHAIN_TOO_LONG: + case X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT: + case X509_V_ERR_INVALID_CA: + case X509_V_ERR_PATH_LENGTH_EXCEEDED: + case X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN: + case X509_V_ERR_UNABLE_TO_GET_CRL: + case X509_V_ERR_UNABLE_TO_GET_CRL_ISSUER: + case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT: + case X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY: + case X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE: + return SSL_AD_UNKNOWN_CA; + + 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_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: + return SSL_AD_BAD_CERTIFICATE; + + case X509_V_ERR_CERT_SIGNATURE_FAILURE: + case X509_V_ERR_CRL_SIGNATURE_FAILURE: + return SSL_AD_DECRYPT_ERROR; + + case X509_V_ERR_CERT_HAS_EXPIRED: + case X509_V_ERR_CERT_NOT_YET_VALID: + case X509_V_ERR_CRL_HAS_EXPIRED: + case X509_V_ERR_CRL_NOT_YET_VALID: + return SSL_AD_CERTIFICATE_EXPIRED; + + case X509_V_ERR_CERT_REVOKED: + return SSL_AD_CERTIFICATE_REVOKED; + + case X509_V_ERR_UNSPECIFIED: + case X509_V_ERR_OUT_OF_MEM: + case X509_V_ERR_INVALID_CALL: + case X509_V_ERR_STORE_LOOKUP: + return SSL_AD_INTERNAL_ERROR; + + case X509_V_ERR_APPLICATION_VERIFICATION: + return SSL_AD_HANDSHAKE_FAILURE; + + case X509_V_ERR_INVALID_PURPOSE: + return SSL_AD_UNSUPPORTED_CERTIFICATE; + + default: + return SSL_AD_CERTIFICATE_UNKNOWN; + } +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/ssl/t1_enc.cc b/FoodApp/Pods/BoringSSL-GRPC/ssl/t1_enc.cc new file mode 100644 index 0000000..ab70309 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/ssl/t1_enc.cc @@ -0,0 +1,452 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "../crypto/fipsmodule/tls/internal.h" +#include "../crypto/internal.h" +#include "internal.h" + + +namespace bssl { + +bool tls1_prf(const EVP_MD *digest, Span out, + Span secret, Span label, + Span seed1, Span seed2) { + return 1 == CRYPTO_tls1_prf(digest, out.data(), out.size(), secret.data(), + secret.size(), label.data(), label.size(), + seed1.data(), seed1.size(), seed2.data(), + seed2.size()); +} + +static bool ssl3_prf(Span out, Span secret, + Span label, Span seed1, + Span seed2) { + ScopedEVP_MD_CTX md5; + ScopedEVP_MD_CTX sha1; + uint8_t buf[16], smd[SHA_DIGEST_LENGTH]; + uint8_t c = 'A'; + size_t k = 0; + while (!out.empty()) { + k++; + if (k > sizeof(buf)) { + // bug: 'buf' is too small for this ciphersuite + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return false; + } + + for (size_t j = 0; j < k; j++) { + buf[j] = c; + } + c++; + if (!EVP_DigestInit_ex(sha1.get(), EVP_sha1(), NULL)) { + OPENSSL_PUT_ERROR(SSL, ERR_LIB_EVP); + return false; + } + EVP_DigestUpdate(sha1.get(), buf, k); + EVP_DigestUpdate(sha1.get(), secret.data(), secret.size()); + // |label| is ignored for SSLv3. + EVP_DigestUpdate(sha1.get(), seed1.data(), seed1.size()); + EVP_DigestUpdate(sha1.get(), seed2.data(), seed2.size()); + EVP_DigestFinal_ex(sha1.get(), smd, NULL); + + if (!EVP_DigestInit_ex(md5.get(), EVP_md5(), NULL)) { + OPENSSL_PUT_ERROR(SSL, ERR_LIB_EVP); + return false; + } + EVP_DigestUpdate(md5.get(), secret.data(), secret.size()); + EVP_DigestUpdate(md5.get(), smd, SHA_DIGEST_LENGTH); + if (out.size() < MD5_DIGEST_LENGTH) { + EVP_DigestFinal_ex(md5.get(), smd, NULL); + OPENSSL_memcpy(out.data(), smd, out.size()); + break; + } + EVP_DigestFinal_ex(md5.get(), out.data(), NULL); + out = out.subspan(MD5_DIGEST_LENGTH); + } + + OPENSSL_cleanse(smd, SHA_DIGEST_LENGTH); + return true; +} + +static bool get_key_block_lengths(const SSL *ssl, size_t *out_mac_secret_len, + size_t *out_key_len, size_t *out_iv_len, + const SSL_CIPHER *cipher) { + const EVP_AEAD *aead = NULL; + if (!ssl_cipher_get_evp_aead(&aead, out_mac_secret_len, out_iv_len, cipher, + ssl_protocol_version(ssl), SSL_is_dtls(ssl))) { + OPENSSL_PUT_ERROR(SSL, SSL_R_CIPHER_OR_HASH_UNAVAILABLE); + return false; + } + + *out_key_len = EVP_AEAD_key_length(aead); + if (*out_mac_secret_len > 0) { + // For "stateful" AEADs (i.e. compatibility with pre-AEAD cipher suites) the + // key length reported by |EVP_AEAD_key_length| will include the MAC key + // bytes and initial implicit IV. + if (*out_key_len < *out_mac_secret_len + *out_iv_len) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return false; + } + *out_key_len -= *out_mac_secret_len + *out_iv_len; + } + + return true; +} + +int tls1_configure_aead(SSL *ssl, evp_aead_direction_t direction, + Array *key_block_cache, + const SSL_CIPHER *cipher, + Span iv_override) { + size_t mac_secret_len, key_len, iv_len; + if (!get_key_block_lengths(ssl, &mac_secret_len, &key_len, &iv_len, cipher)) { + return 0; + } + + // Ensure that |key_block_cache| is set up. + const size_t key_block_size = 2 * (mac_secret_len + key_len + iv_len); + if (key_block_cache->empty()) { + if (!key_block_cache->Init(key_block_size) || + !SSL_generate_key_block(ssl, key_block_cache->data(), key_block_size)) { + return 0; + } + } + assert(key_block_cache->size() == key_block_size); + + Span key_block = *key_block_cache; + Span mac_secret, key, iv; + if (direction == (ssl->server ? evp_aead_open : evp_aead_seal)) { + // Use the client write (server read) keys. + mac_secret = key_block.subspan(0, mac_secret_len); + key = key_block.subspan(2 * mac_secret_len, key_len); + iv = key_block.subspan(2 * mac_secret_len + 2 * key_len, iv_len); + } else { + // Use the server write (client read) keys. + mac_secret = key_block.subspan(mac_secret_len, mac_secret_len); + key = key_block.subspan(2 * mac_secret_len + key_len, key_len); + iv = key_block.subspan(2 * mac_secret_len + 2 * key_len + iv_len, iv_len); + } + + if (!iv_override.empty()) { + if (iv_override.size() != iv_len) { + return 0; + } + iv = iv_override; + } + + UniquePtr aead_ctx = SSLAEADContext::Create( + direction, ssl->version, SSL_is_dtls(ssl), cipher, key, mac_secret, iv); + if (!aead_ctx) { + return 0; + } + + if (direction == evp_aead_open) { + return ssl->method->set_read_state(ssl, std::move(aead_ctx)); + } + + return ssl->method->set_write_state(ssl, std::move(aead_ctx)); +} + +int tls1_change_cipher_state(SSL_HANDSHAKE *hs, + evp_aead_direction_t direction) { + return tls1_configure_aead(hs->ssl, direction, &hs->key_block, + hs->new_cipher, {}); +} + +int tls1_generate_master_secret(SSL_HANDSHAKE *hs, uint8_t *out, + Span premaster) { + static const char kMasterSecretLabel[] = "master secret"; + static const char kExtendedMasterSecretLabel[] = "extended master secret"; + + const SSL *ssl = hs->ssl; + auto out_span = MakeSpan(out, SSL3_MASTER_SECRET_SIZE); + if (hs->extended_master_secret) { + auto label = MakeConstSpan(kExtendedMasterSecretLabel, + sizeof(kExtendedMasterSecretLabel) - 1); + uint8_t digests[EVP_MAX_MD_SIZE]; + size_t digests_len; + if (!hs->transcript.GetHash(digests, &digests_len) || + !tls1_prf(hs->transcript.Digest(), out_span, premaster, label, + MakeConstSpan(digests, digests_len), {})) { + return 0; + } + } else { + auto label = + MakeConstSpan(kMasterSecretLabel, sizeof(kMasterSecretLabel) - 1); + if (ssl_protocol_version(ssl) == SSL3_VERSION) { + if (!ssl3_prf(out_span, premaster, label, ssl->s3->client_random, + ssl->s3->server_random)) { + return 0; + } + } else { + if (!tls1_prf(hs->transcript.Digest(), out_span, premaster, label, + ssl->s3->client_random, ssl->s3->server_random)) { + return 0; + } + } + } + + return SSL3_MASTER_SECRET_SIZE; +} + +} // namespace bssl + +using namespace bssl; + +size_t SSL_get_key_block_len(const SSL *ssl) { + size_t mac_secret_len, key_len, fixed_iv_len; + if (!get_key_block_lengths(ssl, &mac_secret_len, &key_len, &fixed_iv_len, + SSL_get_current_cipher(ssl))) { + ERR_clear_error(); + return 0; + } + + return 2 * (mac_secret_len + key_len + fixed_iv_len); +} + +int SSL_generate_key_block(const SSL *ssl, uint8_t *out, size_t out_len) { + const SSL_SESSION *session = SSL_get_session(ssl); + auto out_span = MakeSpan(out, out_len); + auto master_key = + MakeConstSpan(session->master_key, session->master_key_length); + static const char kLabel[] = "key expansion"; + auto label = MakeConstSpan(kLabel, sizeof(kLabel) - 1); + + if (ssl_protocol_version(ssl) == SSL3_VERSION) { + return ssl3_prf(out_span, master_key, label, ssl->s3->server_random, + ssl->s3->client_random); + } + + const EVP_MD *digest = ssl_session_get_digest(session); + return tls1_prf(digest, out_span, master_key, label, ssl->s3->server_random, + ssl->s3->client_random); +} + +int SSL_export_keying_material(SSL *ssl, uint8_t *out, size_t out_len, + const char *label, size_t label_len, + const uint8_t *context, size_t context_len, + int use_context) { + if (!ssl->s3->have_version || ssl->version == SSL3_VERSION) { + OPENSSL_PUT_ERROR(SSL, SSL_R_HANDSHAKE_NOT_COMPLETE); + return 0; + } + + // Exporters may be used in False Start and server 0-RTT, where the handshake + // has progressed enough. Otherwise, they may not be used during a handshake. + if (SSL_in_init(ssl) && + !SSL_in_false_start(ssl) && + !(SSL_is_server(ssl) && SSL_in_early_data(ssl))) { + OPENSSL_PUT_ERROR(SSL, SSL_R_HANDSHAKE_NOT_COMPLETE); + return 0; + } + + if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) { + if (!use_context) { + context = nullptr; + context_len = 0; + } + return tls13_export_keying_material( + ssl, MakeSpan(out, out_len), + MakeConstSpan(ssl->s3->exporter_secret, ssl->s3->exporter_secret_len), + MakeConstSpan(label, label_len), MakeConstSpan(context, context_len)); + } + + size_t seed_len = 2 * SSL3_RANDOM_SIZE; + if (use_context) { + if (context_len >= 1u << 16) { + OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW); + return 0; + } + seed_len += 2 + context_len; + } + Array seed; + if (!seed.Init(seed_len)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + + OPENSSL_memcpy(seed.data(), ssl->s3->client_random, SSL3_RANDOM_SIZE); + OPENSSL_memcpy(seed.data() + SSL3_RANDOM_SIZE, ssl->s3->server_random, + SSL3_RANDOM_SIZE); + if (use_context) { + seed[2 * SSL3_RANDOM_SIZE] = static_cast(context_len >> 8); + seed[2 * SSL3_RANDOM_SIZE + 1] = static_cast(context_len); + OPENSSL_memcpy(seed.data() + 2 * SSL3_RANDOM_SIZE + 2, context, context_len); + } + + const SSL_SESSION *session = SSL_get_session(ssl); + const EVP_MD *digest = ssl_session_get_digest(session); + return tls1_prf( + digest, MakeSpan(out, out_len), + MakeConstSpan(session->master_key, session->master_key_length), + MakeConstSpan(label, label_len), seed, {}); +} + +int SSL_export_early_keying_material( + SSL *ssl, uint8_t *out, size_t out_len, const char *label, size_t label_len, + const uint8_t *context, size_t context_len) { + if (!SSL_in_early_data(ssl) && + (!ssl->s3->have_version || + ssl_protocol_version(ssl) < TLS1_3_VERSION)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_SSL_VERSION); + return 0; + } + + // The early exporter only exists if we accepted early data or offered it as + // a client. + if (!SSL_in_early_data(ssl) && !SSL_early_data_accepted(ssl)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_EARLY_DATA_NOT_IN_USE); + return 0; + } + + return tls13_export_keying_material( + ssl, MakeSpan(out, out_len), + MakeConstSpan(ssl->s3->early_exporter_secret, + ssl->s3->early_exporter_secret_len), + MakeConstSpan(label, label_len), MakeConstSpan(context, context_len)); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/ssl/t1_enc.cc.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/ssl/t1_enc.cc.grpc_back new file mode 100644 index 0000000..5947627 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/ssl/t1_enc.cc.grpc_back @@ -0,0 +1,452 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 +#include + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "../crypto/fipsmodule/tls/internal.h" +#include "../crypto/internal.h" +#include "internal.h" + + +namespace bssl { + +bool tls1_prf(const EVP_MD *digest, Span out, + Span secret, Span label, + Span seed1, Span seed2) { + return 1 == CRYPTO_tls1_prf(digest, out.data(), out.size(), secret.data(), + secret.size(), label.data(), label.size(), + seed1.data(), seed1.size(), seed2.data(), + seed2.size()); +} + +static bool ssl3_prf(Span out, Span secret, + Span label, Span seed1, + Span seed2) { + ScopedEVP_MD_CTX md5; + ScopedEVP_MD_CTX sha1; + uint8_t buf[16], smd[SHA_DIGEST_LENGTH]; + uint8_t c = 'A'; + size_t k = 0; + while (!out.empty()) { + k++; + if (k > sizeof(buf)) { + // bug: 'buf' is too small for this ciphersuite + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return false; + } + + for (size_t j = 0; j < k; j++) { + buf[j] = c; + } + c++; + if (!EVP_DigestInit_ex(sha1.get(), EVP_sha1(), NULL)) { + OPENSSL_PUT_ERROR(SSL, ERR_LIB_EVP); + return false; + } + EVP_DigestUpdate(sha1.get(), buf, k); + EVP_DigestUpdate(sha1.get(), secret.data(), secret.size()); + // |label| is ignored for SSLv3. + EVP_DigestUpdate(sha1.get(), seed1.data(), seed1.size()); + EVP_DigestUpdate(sha1.get(), seed2.data(), seed2.size()); + EVP_DigestFinal_ex(sha1.get(), smd, NULL); + + if (!EVP_DigestInit_ex(md5.get(), EVP_md5(), NULL)) { + OPENSSL_PUT_ERROR(SSL, ERR_LIB_EVP); + return false; + } + EVP_DigestUpdate(md5.get(), secret.data(), secret.size()); + EVP_DigestUpdate(md5.get(), smd, SHA_DIGEST_LENGTH); + if (out.size() < MD5_DIGEST_LENGTH) { + EVP_DigestFinal_ex(md5.get(), smd, NULL); + OPENSSL_memcpy(out.data(), smd, out.size()); + break; + } + EVP_DigestFinal_ex(md5.get(), out.data(), NULL); + out = out.subspan(MD5_DIGEST_LENGTH); + } + + OPENSSL_cleanse(smd, SHA_DIGEST_LENGTH); + return true; +} + +static bool get_key_block_lengths(const SSL *ssl, size_t *out_mac_secret_len, + size_t *out_key_len, size_t *out_iv_len, + const SSL_CIPHER *cipher) { + const EVP_AEAD *aead = NULL; + if (!ssl_cipher_get_evp_aead(&aead, out_mac_secret_len, out_iv_len, cipher, + ssl_protocol_version(ssl), SSL_is_dtls(ssl))) { + OPENSSL_PUT_ERROR(SSL, SSL_R_CIPHER_OR_HASH_UNAVAILABLE); + return false; + } + + *out_key_len = EVP_AEAD_key_length(aead); + if (*out_mac_secret_len > 0) { + // For "stateful" AEADs (i.e. compatibility with pre-AEAD cipher suites) the + // key length reported by |EVP_AEAD_key_length| will include the MAC key + // bytes and initial implicit IV. + if (*out_key_len < *out_mac_secret_len + *out_iv_len) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return false; + } + *out_key_len -= *out_mac_secret_len + *out_iv_len; + } + + return true; +} + +int tls1_configure_aead(SSL *ssl, evp_aead_direction_t direction, + Array *key_block_cache, + const SSL_CIPHER *cipher, + Span iv_override) { + size_t mac_secret_len, key_len, iv_len; + if (!get_key_block_lengths(ssl, &mac_secret_len, &key_len, &iv_len, cipher)) { + return 0; + } + + // Ensure that |key_block_cache| is set up. + const size_t key_block_size = 2 * (mac_secret_len + key_len + iv_len); + if (key_block_cache->empty()) { + if (!key_block_cache->Init(key_block_size) || + !SSL_generate_key_block(ssl, key_block_cache->data(), key_block_size)) { + return 0; + } + } + assert(key_block_cache->size() == key_block_size); + + Span key_block = *key_block_cache; + Span mac_secret, key, iv; + if (direction == (ssl->server ? evp_aead_open : evp_aead_seal)) { + // Use the client write (server read) keys. + mac_secret = key_block.subspan(0, mac_secret_len); + key = key_block.subspan(2 * mac_secret_len, key_len); + iv = key_block.subspan(2 * mac_secret_len + 2 * key_len, iv_len); + } else { + // Use the server write (client read) keys. + mac_secret = key_block.subspan(mac_secret_len, mac_secret_len); + key = key_block.subspan(2 * mac_secret_len + key_len, key_len); + iv = key_block.subspan(2 * mac_secret_len + 2 * key_len + iv_len, iv_len); + } + + if (!iv_override.empty()) { + if (iv_override.size() != iv_len) { + return 0; + } + iv = iv_override; + } + + UniquePtr aead_ctx = SSLAEADContext::Create( + direction, ssl->version, SSL_is_dtls(ssl), cipher, key, mac_secret, iv); + if (!aead_ctx) { + return 0; + } + + if (direction == evp_aead_open) { + return ssl->method->set_read_state(ssl, std::move(aead_ctx)); + } + + return ssl->method->set_write_state(ssl, std::move(aead_ctx)); +} + +int tls1_change_cipher_state(SSL_HANDSHAKE *hs, + evp_aead_direction_t direction) { + return tls1_configure_aead(hs->ssl, direction, &hs->key_block, + hs->new_cipher, {}); +} + +int tls1_generate_master_secret(SSL_HANDSHAKE *hs, uint8_t *out, + Span premaster) { + static const char kMasterSecretLabel[] = "master secret"; + static const char kExtendedMasterSecretLabel[] = "extended master secret"; + + const SSL *ssl = hs->ssl; + auto out_span = MakeSpan(out, SSL3_MASTER_SECRET_SIZE); + if (hs->extended_master_secret) { + auto label = MakeConstSpan(kExtendedMasterSecretLabel, + sizeof(kExtendedMasterSecretLabel) - 1); + uint8_t digests[EVP_MAX_MD_SIZE]; + size_t digests_len; + if (!hs->transcript.GetHash(digests, &digests_len) || + !tls1_prf(hs->transcript.Digest(), out_span, premaster, label, + MakeConstSpan(digests, digests_len), {})) { + return 0; + } + } else { + auto label = + MakeConstSpan(kMasterSecretLabel, sizeof(kMasterSecretLabel) - 1); + if (ssl_protocol_version(ssl) == SSL3_VERSION) { + if (!ssl3_prf(out_span, premaster, label, ssl->s3->client_random, + ssl->s3->server_random)) { + return 0; + } + } else { + if (!tls1_prf(hs->transcript.Digest(), out_span, premaster, label, + ssl->s3->client_random, ssl->s3->server_random)) { + return 0; + } + } + } + + return SSL3_MASTER_SECRET_SIZE; +} + +} // namespace bssl + +using namespace bssl; + +size_t SSL_get_key_block_len(const SSL *ssl) { + size_t mac_secret_len, key_len, fixed_iv_len; + if (!get_key_block_lengths(ssl, &mac_secret_len, &key_len, &fixed_iv_len, + SSL_get_current_cipher(ssl))) { + ERR_clear_error(); + return 0; + } + + return 2 * (mac_secret_len + key_len + fixed_iv_len); +} + +int SSL_generate_key_block(const SSL *ssl, uint8_t *out, size_t out_len) { + const SSL_SESSION *session = SSL_get_session(ssl); + auto out_span = MakeSpan(out, out_len); + auto master_key = + MakeConstSpan(session->master_key, session->master_key_length); + static const char kLabel[] = "key expansion"; + auto label = MakeConstSpan(kLabel, sizeof(kLabel) - 1); + + if (ssl_protocol_version(ssl) == SSL3_VERSION) { + return ssl3_prf(out_span, master_key, label, ssl->s3->server_random, + ssl->s3->client_random); + } + + const EVP_MD *digest = ssl_session_get_digest(session); + return tls1_prf(digest, out_span, master_key, label, ssl->s3->server_random, + ssl->s3->client_random); +} + +int SSL_export_keying_material(SSL *ssl, uint8_t *out, size_t out_len, + const char *label, size_t label_len, + const uint8_t *context, size_t context_len, + int use_context) { + if (!ssl->s3->have_version || ssl->version == SSL3_VERSION) { + OPENSSL_PUT_ERROR(SSL, SSL_R_HANDSHAKE_NOT_COMPLETE); + return 0; + } + + // Exporters may be used in False Start and server 0-RTT, where the handshake + // has progressed enough. Otherwise, they may not be used during a handshake. + if (SSL_in_init(ssl) && + !SSL_in_false_start(ssl) && + !(SSL_is_server(ssl) && SSL_in_early_data(ssl))) { + OPENSSL_PUT_ERROR(SSL, SSL_R_HANDSHAKE_NOT_COMPLETE); + return 0; + } + + if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) { + if (!use_context) { + context = nullptr; + context_len = 0; + } + return tls13_export_keying_material( + ssl, MakeSpan(out, out_len), + MakeConstSpan(ssl->s3->exporter_secret, ssl->s3->exporter_secret_len), + MakeConstSpan(label, label_len), MakeConstSpan(context, context_len)); + } + + size_t seed_len = 2 * SSL3_RANDOM_SIZE; + if (use_context) { + if (context_len >= 1u << 16) { + OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW); + return 0; + } + seed_len += 2 + context_len; + } + Array seed; + if (!seed.Init(seed_len)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + + OPENSSL_memcpy(seed.data(), ssl->s3->client_random, SSL3_RANDOM_SIZE); + OPENSSL_memcpy(seed.data() + SSL3_RANDOM_SIZE, ssl->s3->server_random, + SSL3_RANDOM_SIZE); + if (use_context) { + seed[2 * SSL3_RANDOM_SIZE] = static_cast(context_len >> 8); + seed[2 * SSL3_RANDOM_SIZE + 1] = static_cast(context_len); + OPENSSL_memcpy(seed.data() + 2 * SSL3_RANDOM_SIZE + 2, context, context_len); + } + + const SSL_SESSION *session = SSL_get_session(ssl); + const EVP_MD *digest = ssl_session_get_digest(session); + return tls1_prf( + digest, MakeSpan(out, out_len), + MakeConstSpan(session->master_key, session->master_key_length), + MakeConstSpan(label, label_len), seed, {}); +} + +int SSL_export_early_keying_material( + SSL *ssl, uint8_t *out, size_t out_len, const char *label, size_t label_len, + const uint8_t *context, size_t context_len) { + if (!SSL_in_early_data(ssl) && + (!ssl->s3->have_version || + ssl_protocol_version(ssl) < TLS1_3_VERSION)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_SSL_VERSION); + return 0; + } + + // The early exporter only exists if we accepted early data or offered it as + // a client. + if (!SSL_in_early_data(ssl) && !SSL_early_data_accepted(ssl)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_EARLY_DATA_NOT_IN_USE); + return 0; + } + + return tls13_export_keying_material( + ssl, MakeSpan(out, out_len), + MakeConstSpan(ssl->s3->early_exporter_secret, + ssl->s3->early_exporter_secret_len), + MakeConstSpan(label, label_len), MakeConstSpan(context, context_len)); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/ssl/t1_lib.cc b/FoodApp/Pods/BoringSSL-GRPC/ssl/t1_lib.cc new file mode 100644 index 0000000..56955d8 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/ssl/t1_lib.cc @@ -0,0 +1,3783 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 + +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "internal.h" +#include "../crypto/internal.h" + + +namespace bssl { + +static int ssl_check_clienthello_tlsext(SSL_HANDSHAKE *hs); + +static int compare_uint16_t(const void *p1, const void *p2) { + uint16_t u1 = *((const uint16_t *)p1); + uint16_t u2 = *((const uint16_t *)p2); + if (u1 < u2) { + return -1; + } else if (u1 > u2) { + return 1; + } else { + return 0; + } +} + +// Per http://tools.ietf.org/html/rfc5246#section-7.4.1.4, there may not be +// more than one extension of the same type in a ClientHello or ServerHello. +// This function does an initial scan over the extensions block to filter those +// out. +static int tls1_check_duplicate_extensions(const CBS *cbs) { + // First pass: count the extensions. + size_t num_extensions = 0; + CBS extensions = *cbs; + while (CBS_len(&extensions) > 0) { + uint16_t type; + CBS extension; + + if (!CBS_get_u16(&extensions, &type) || + !CBS_get_u16_length_prefixed(&extensions, &extension)) { + return 0; + } + + num_extensions++; + } + + if (num_extensions == 0) { + return 1; + } + + Array extension_types; + if (!extension_types.Init(num_extensions)) { + return 0; + } + + // Second pass: gather the extension types. + extensions = *cbs; + for (size_t i = 0; i < extension_types.size(); i++) { + CBS extension; + + if (!CBS_get_u16(&extensions, &extension_types[i]) || + !CBS_get_u16_length_prefixed(&extensions, &extension)) { + // This should not happen. + return 0; + } + } + assert(CBS_len(&extensions) == 0); + + // Sort the extensions and make sure there are no duplicates. + qsort(extension_types.data(), extension_types.size(), sizeof(uint16_t), + compare_uint16_t); + for (size_t i = 1; i < num_extensions; i++) { + if (extension_types[i - 1] == extension_types[i]) { + return 0; + } + } + + return 1; +} + +int ssl_client_hello_init(SSL *ssl, SSL_CLIENT_HELLO *out, + const SSLMessage &msg) { + OPENSSL_memset(out, 0, sizeof(*out)); + out->ssl = ssl; + out->client_hello = CBS_data(&msg.body); + out->client_hello_len = CBS_len(&msg.body); + + CBS client_hello, random, session_id; + CBS_init(&client_hello, out->client_hello, out->client_hello_len); + if (!CBS_get_u16(&client_hello, &out->version) || + !CBS_get_bytes(&client_hello, &random, SSL3_RANDOM_SIZE) || + !CBS_get_u8_length_prefixed(&client_hello, &session_id) || + CBS_len(&session_id) > SSL_MAX_SSL_SESSION_ID_LENGTH) { + return 0; + } + + out->random = CBS_data(&random); + out->random_len = CBS_len(&random); + out->session_id = CBS_data(&session_id); + out->session_id_len = CBS_len(&session_id); + + // Skip past DTLS cookie + if (SSL_is_dtls(out->ssl)) { + CBS cookie; + if (!CBS_get_u8_length_prefixed(&client_hello, &cookie) || + CBS_len(&cookie) > DTLS1_COOKIE_LENGTH) { + return 0; + } + } + + CBS cipher_suites, compression_methods; + if (!CBS_get_u16_length_prefixed(&client_hello, &cipher_suites) || + CBS_len(&cipher_suites) < 2 || (CBS_len(&cipher_suites) & 1) != 0 || + !CBS_get_u8_length_prefixed(&client_hello, &compression_methods) || + CBS_len(&compression_methods) < 1) { + return 0; + } + + out->cipher_suites = CBS_data(&cipher_suites); + out->cipher_suites_len = CBS_len(&cipher_suites); + out->compression_methods = CBS_data(&compression_methods); + out->compression_methods_len = CBS_len(&compression_methods); + + // If the ClientHello ends here then it's valid, but doesn't have any + // extensions. (E.g. SSLv3.) + if (CBS_len(&client_hello) == 0) { + out->extensions = NULL; + out->extensions_len = 0; + return 1; + } + + // Extract extensions and check it is valid. + CBS extensions; + if (!CBS_get_u16_length_prefixed(&client_hello, &extensions) || + !tls1_check_duplicate_extensions(&extensions) || + CBS_len(&client_hello) != 0) { + return 0; + } + + out->extensions = CBS_data(&extensions); + out->extensions_len = CBS_len(&extensions); + + return 1; +} + +int ssl_client_hello_get_extension(const SSL_CLIENT_HELLO *client_hello, + CBS *out, uint16_t extension_type) { + CBS extensions; + CBS_init(&extensions, client_hello->extensions, client_hello->extensions_len); + while (CBS_len(&extensions) != 0) { + // Decode the next extension. + uint16_t type; + CBS extension; + if (!CBS_get_u16(&extensions, &type) || + !CBS_get_u16_length_prefixed(&extensions, &extension)) { + return 0; + } + + if (type == extension_type) { + *out = extension; + return 1; + } + } + + return 0; +} + +static const uint16_t kDefaultGroups[] = { + SSL_CURVE_X25519, + SSL_CURVE_SECP256R1, + SSL_CURVE_SECP384R1, +}; + +Span tls1_get_grouplist(const SSL *ssl) { + if (ssl->supported_group_list != nullptr) { + return MakeConstSpan(ssl->supported_group_list, + ssl->supported_group_list_len); + } + return Span(kDefaultGroups); +} + +int tls1_get_shared_group(SSL_HANDSHAKE *hs, uint16_t *out_group_id) { + SSL *const ssl = hs->ssl; + assert(ssl->server); + + // Clients are not required to send a supported_groups extension. In this + // case, the server is free to pick any group it likes. See RFC 4492, + // section 4, paragraph 3. + // + // However, in the interests of compatibility, we will skip ECDH if the + // client didn't send an extension because we can't be sure that they'll + // support our favoured group. Thus we do not special-case an emtpy + // |peer_supported_group_list|. + + Span groups = tls1_get_grouplist(ssl); + Span pref, supp; + if (ssl->options & SSL_OP_CIPHER_SERVER_PREFERENCE) { + pref = groups; + supp = hs->peer_supported_group_list; + } else { + pref = hs->peer_supported_group_list; + supp = groups; + } + + for (uint16_t pref_group : pref) { + for (uint16_t supp_group : supp) { + if (pref_group == supp_group) { + *out_group_id = pref_group; + return 1; + } + } + } + + return 0; +} + +int tls1_set_curves(uint16_t **out_group_ids, size_t *out_group_ids_len, + const int *curves, size_t ncurves) { + uint16_t *group_ids = (uint16_t *)OPENSSL_malloc(ncurves * sizeof(uint16_t)); + if (group_ids == NULL) { + return 0; + } + + for (size_t i = 0; i < ncurves; i++) { + if (!ssl_nid_to_group_id(&group_ids[i], curves[i])) { + OPENSSL_free(group_ids); + return 0; + } + } + + OPENSSL_free(*out_group_ids); + *out_group_ids = group_ids; + *out_group_ids_len = ncurves; + + return 1; +} + +int tls1_set_curves_list(uint16_t **out_group_ids, size_t *out_group_ids_len, + const char *curves) { + uint16_t *group_ids = NULL; + size_t ncurves = 0; + + const char *col; + const char *ptr = curves; + + do { + col = strchr(ptr, ':'); + + uint16_t group_id; + if (!ssl_name_to_group_id(&group_id, ptr, + col ? (size_t)(col - ptr) : strlen(ptr))) { + goto err; + } + + uint16_t *new_group_ids = (uint16_t *)OPENSSL_realloc( + group_ids, (ncurves + 1) * sizeof(uint16_t)); + if (new_group_ids == NULL) { + goto err; + } + group_ids = new_group_ids; + + group_ids[ncurves] = group_id; + ncurves++; + + if (col) { + ptr = col + 1; + } + } while (col); + + OPENSSL_free(*out_group_ids); + *out_group_ids = group_ids; + *out_group_ids_len = ncurves; + + return 1; + +err: + OPENSSL_free(group_ids); + return 0; +} + +int tls1_check_group_id(const SSL *ssl, uint16_t group_id) { + for (uint16_t supported : tls1_get_grouplist(ssl)) { + if (supported == group_id) { + return 1; + } + } + + return 0; +} + +// kVerifySignatureAlgorithms is the default list of accepted signature +// algorithms for verifying. +// +// For now, RSA-PSS signature algorithms are not enabled on Android's system +// BoringSSL. Once the change in Chrome has stuck and the values are finalized, +// restore them. +static const uint16_t kVerifySignatureAlgorithms[] = { + // List our preferred algorithms first. + SSL_SIGN_ED25519, + SSL_SIGN_ECDSA_SECP256R1_SHA256, + SSL_SIGN_RSA_PSS_SHA256, + SSL_SIGN_RSA_PKCS1_SHA256, + + // Larger hashes are acceptable. + SSL_SIGN_ECDSA_SECP384R1_SHA384, + SSL_SIGN_RSA_PSS_SHA384, + SSL_SIGN_RSA_PKCS1_SHA384, + + SSL_SIGN_RSA_PSS_SHA512, + SSL_SIGN_RSA_PKCS1_SHA512, + + // For now, SHA-1 is still accepted but least preferable. + SSL_SIGN_RSA_PKCS1_SHA1, + +}; + +// kSignSignatureAlgorithms is the default list of supported signature +// algorithms for signing. +// +// For now, RSA-PSS signature algorithms are not enabled on Android's system +// BoringSSL. Once the change in Chrome has stuck and the values are finalized, +// restore them. +static const uint16_t kSignSignatureAlgorithms[] = { + // List our preferred algorithms first. + SSL_SIGN_ED25519, + SSL_SIGN_ECDSA_SECP256R1_SHA256, + SSL_SIGN_RSA_PSS_SHA256, + SSL_SIGN_RSA_PKCS1_SHA256, + + // If needed, sign larger hashes. + // + // TODO(davidben): Determine which of these may be pruned. + SSL_SIGN_ECDSA_SECP384R1_SHA384, + SSL_SIGN_RSA_PSS_SHA384, + SSL_SIGN_RSA_PKCS1_SHA384, + + SSL_SIGN_ECDSA_SECP521R1_SHA512, + SSL_SIGN_RSA_PSS_SHA512, + SSL_SIGN_RSA_PKCS1_SHA512, + + // If the peer supports nothing else, sign with SHA-1. + SSL_SIGN_ECDSA_SHA1, + SSL_SIGN_RSA_PKCS1_SHA1, +}; + +bool tls12_add_verify_sigalgs(const SSL *ssl, CBB *out) { + bool use_default = ssl->ctx->num_verify_sigalgs == 0; + Span sigalgs = kVerifySignatureAlgorithms; + if (!use_default) { + sigalgs = MakeConstSpan(ssl->ctx->verify_sigalgs, + ssl->ctx->num_verify_sigalgs); + } + + for (uint16_t sigalg : sigalgs) { + if (use_default && + sigalg == SSL_SIGN_ED25519 && + !ssl->ctx->ed25519_enabled) { + continue; + } + if (!CBB_add_u16(out, sigalg)) { + return false; + } + } + + return true; +} + +bool tls12_check_peer_sigalg(const SSL *ssl, uint8_t *out_alert, + uint16_t sigalg) { + const uint16_t *sigalgs = kVerifySignatureAlgorithms; + size_t num_sigalgs = OPENSSL_ARRAY_SIZE(kVerifySignatureAlgorithms); + if (ssl->ctx->num_verify_sigalgs != 0) { + sigalgs = ssl->ctx->verify_sigalgs; + num_sigalgs = ssl->ctx->num_verify_sigalgs; + } + + for (size_t i = 0; i < num_sigalgs; i++) { + if (sigalgs == kVerifySignatureAlgorithms && + sigalgs[i] == SSL_SIGN_ED25519 && + !ssl->ctx->ed25519_enabled) { + continue; + } + if (sigalg == sigalgs[i]) { + return true; + } + } + + OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_SIGNATURE_TYPE); + *out_alert = SSL_AD_ILLEGAL_PARAMETER; + return false; +} + +// tls_extension represents a TLS extension that is handled internally. The +// |init| function is called for each handshake, before any other functions of +// the extension. Then the add and parse callbacks are called as needed. +// +// The parse callbacks receive a |CBS| that contains the contents of the +// extension (i.e. not including the type and length bytes). If an extension is +// not received then the parse callbacks will be called with a NULL CBS so that +// they can do any processing needed to handle the absence of an extension. +// +// The add callbacks receive a |CBB| to which the extension can be appended but +// the function is responsible for appending the type and length bytes too. +// +// All callbacks return true for success and false for error. If a parse +// function returns zero then a fatal alert with value |*out_alert| will be +// sent. If |*out_alert| isn't set, then a |decode_error| alert will be sent. +struct tls_extension { + uint16_t value; + void (*init)(SSL_HANDSHAKE *hs); + + bool (*add_clienthello)(SSL_HANDSHAKE *hs, CBB *out); + bool (*parse_serverhello)(SSL_HANDSHAKE *hs, uint8_t *out_alert, + CBS *contents); + + bool (*parse_clienthello)(SSL_HANDSHAKE *hs, uint8_t *out_alert, + CBS *contents); + bool (*add_serverhello)(SSL_HANDSHAKE *hs, CBB *out); +}; + +static bool forbid_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert, + CBS *contents) { + if (contents != NULL) { + // Servers MUST NOT send this extension. + *out_alert = SSL_AD_UNSUPPORTED_EXTENSION; + OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION); + return false; + } + + return true; +} + +static bool ignore_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert, + CBS *contents) { + // This extension from the client is handled elsewhere. + return true; +} + +static bool dont_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) { + return true; +} + +// Server name indication (SNI). +// +// https://tools.ietf.org/html/rfc6066#section-3. + +static bool ext_sni_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) { + SSL *const ssl = hs->ssl; + if (ssl->tlsext_hostname == NULL) { + return true; + } + + CBB contents, server_name_list, name; + if (!CBB_add_u16(out, TLSEXT_TYPE_server_name) || + !CBB_add_u16_length_prefixed(out, &contents) || + !CBB_add_u16_length_prefixed(&contents, &server_name_list) || + !CBB_add_u8(&server_name_list, TLSEXT_NAMETYPE_host_name) || + !CBB_add_u16_length_prefixed(&server_name_list, &name) || + !CBB_add_bytes(&name, (const uint8_t *)ssl->tlsext_hostname, + strlen(ssl->tlsext_hostname)) || + !CBB_flush(out)) { + return false; + } + + return true; +} + +static bool ext_sni_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert, + CBS *contents) { + // The server may acknowledge SNI with an empty extension. We check the syntax + // but otherwise ignore this signal. + return contents == NULL || CBS_len(contents) == 0; +} + +static bool ext_sni_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert, + CBS *contents) { + SSL *const ssl = hs->ssl; + if (contents == NULL) { + return true; + } + + CBS server_name_list, host_name; + uint8_t name_type; + if (!CBS_get_u16_length_prefixed(contents, &server_name_list) || + !CBS_get_u8(&server_name_list, &name_type) || + // Although the server_name extension was intended to be extensible to + // new name types and multiple names, OpenSSL 1.0.x had a bug which meant + // different name types will cause an error. Further, RFC 4366 originally + // defined syntax inextensibly. RFC 6066 corrected this mistake, but + // adding new name types is no longer feasible. + // + // Act as if the extensibility does not exist to simplify parsing. + !CBS_get_u16_length_prefixed(&server_name_list, &host_name) || + CBS_len(&server_name_list) != 0 || + CBS_len(contents) != 0) { + return false; + } + + if (name_type != TLSEXT_NAMETYPE_host_name || + CBS_len(&host_name) == 0 || + CBS_len(&host_name) > TLSEXT_MAXLEN_host_name || + CBS_contains_zero_byte(&host_name)) { + *out_alert = SSL_AD_UNRECOGNIZED_NAME; + return false; + } + + // Copy the hostname as a string. + char *raw = nullptr; + if (!CBS_strdup(&host_name, &raw)) { + *out_alert = SSL_AD_INTERNAL_ERROR; + return false; + } + ssl->s3->hostname.reset(raw); + + hs->should_ack_sni = true; + return true; +} + +static bool ext_sni_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) { + if (hs->ssl->s3->session_reused || + !hs->should_ack_sni) { + return true; + } + + if (!CBB_add_u16(out, TLSEXT_TYPE_server_name) || + !CBB_add_u16(out, 0 /* length */)) { + return false; + } + + return true; +} + + +// Renegotiation indication. +// +// https://tools.ietf.org/html/rfc5746 + +static bool ext_ri_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) { + SSL *const ssl = hs->ssl; + // Renegotiation indication is not necessary in TLS 1.3. + if (hs->min_version >= TLS1_3_VERSION) { + return true; + } + + assert(ssl->s3->initial_handshake_complete == + (ssl->s3->previous_client_finished_len != 0)); + + CBB contents, prev_finished; + if (!CBB_add_u16(out, TLSEXT_TYPE_renegotiate) || + !CBB_add_u16_length_prefixed(out, &contents) || + !CBB_add_u8_length_prefixed(&contents, &prev_finished) || + !CBB_add_bytes(&prev_finished, ssl->s3->previous_client_finished, + ssl->s3->previous_client_finished_len) || + !CBB_flush(out)) { + return false; + } + + return true; +} + +static bool ext_ri_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert, + CBS *contents) { + SSL *const ssl = hs->ssl; + if (contents != NULL && ssl_protocol_version(ssl) >= TLS1_3_VERSION) { + *out_alert = SSL_AD_ILLEGAL_PARAMETER; + return false; + } + + // Servers may not switch between omitting the extension and supporting it. + // See RFC 5746, sections 3.5 and 4.2. + if (ssl->s3->initial_handshake_complete && + (contents != NULL) != ssl->s3->send_connection_binding) { + *out_alert = SSL_AD_HANDSHAKE_FAILURE; + OPENSSL_PUT_ERROR(SSL, SSL_R_RENEGOTIATION_MISMATCH); + return false; + } + + if (contents == NULL) { + // Strictly speaking, if we want to avoid an attack we should *always* see + // RI even on initial ServerHello 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. + // + // OpenSSL has |SSL_OP_LEGACY_SERVER_CONNECT| to control this, but in + // practical terms every client sets it so it's just assumed here. + return true; + } + + const size_t expected_len = ssl->s3->previous_client_finished_len + + ssl->s3->previous_server_finished_len; + + // Check for logic errors + assert(!expected_len || ssl->s3->previous_client_finished_len); + assert(!expected_len || ssl->s3->previous_server_finished_len); + assert(ssl->s3->initial_handshake_complete == + (ssl->s3->previous_client_finished_len != 0)); + assert(ssl->s3->initial_handshake_complete == + (ssl->s3->previous_server_finished_len != 0)); + + // Parse out the extension contents. + CBS renegotiated_connection; + if (!CBS_get_u8_length_prefixed(contents, &renegotiated_connection) || + CBS_len(contents) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_RENEGOTIATION_ENCODING_ERR); + *out_alert = SSL_AD_ILLEGAL_PARAMETER; + return false; + } + + // Check that the extension matches. + if (CBS_len(&renegotiated_connection) != expected_len) { + OPENSSL_PUT_ERROR(SSL, SSL_R_RENEGOTIATION_MISMATCH); + *out_alert = SSL_AD_HANDSHAKE_FAILURE; + return false; + } + + const uint8_t *d = CBS_data(&renegotiated_connection); + bool ok = CRYPTO_memcmp(d, ssl->s3->previous_client_finished, + ssl->s3->previous_client_finished_len) == 0; +#if defined(BORINGSSL_UNSAFE_FUZZER_MODE) + ok = true; +#endif + if (!ok) { + OPENSSL_PUT_ERROR(SSL, SSL_R_RENEGOTIATION_MISMATCH); + *out_alert = SSL_AD_HANDSHAKE_FAILURE; + return false; + } + d += ssl->s3->previous_client_finished_len; + + ok = CRYPTO_memcmp(d, ssl->s3->previous_server_finished, + ssl->s3->previous_server_finished_len) == 0; +#if defined(BORINGSSL_UNSAFE_FUZZER_MODE) + ok = true; +#endif + if (!ok) { + OPENSSL_PUT_ERROR(SSL, SSL_R_RENEGOTIATION_MISMATCH); + *out_alert = SSL_AD_HANDSHAKE_FAILURE; + return false; + } + ssl->s3->send_connection_binding = true; + + return true; +} + +static bool ext_ri_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert, + CBS *contents) { + SSL *const ssl = hs->ssl; + // Renegotiation isn't supported as a server so this function should never be + // called after the initial handshake. + assert(!ssl->s3->initial_handshake_complete); + + if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) { + return true; + } + + if (contents == NULL) { + return true; + } + + CBS renegotiated_connection; + if (!CBS_get_u8_length_prefixed(contents, &renegotiated_connection) || + CBS_len(contents) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_RENEGOTIATION_ENCODING_ERR); + return false; + } + + // Check that the extension matches. We do not support renegotiation as a + // server, so this must be empty. + if (CBS_len(&renegotiated_connection) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_RENEGOTIATION_MISMATCH); + *out_alert = SSL_AD_HANDSHAKE_FAILURE; + return false; + } + + ssl->s3->send_connection_binding = true; + + return true; +} + +static bool ext_ri_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) { + SSL *const ssl = hs->ssl; + // Renegotiation isn't supported as a server so this function should never be + // called after the initial handshake. + assert(!ssl->s3->initial_handshake_complete); + + if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) { + return true; + } + + if (!CBB_add_u16(out, TLSEXT_TYPE_renegotiate) || + !CBB_add_u16(out, 1 /* length */) || + !CBB_add_u8(out, 0 /* empty renegotiation info */)) { + return false; + } + + return true; +} + + +// Extended Master Secret. +// +// https://tools.ietf.org/html/rfc7627 + +static bool ext_ems_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) { + // Extended master secret is not necessary in TLS 1.3. + if (hs->min_version >= TLS1_3_VERSION || hs->max_version <= SSL3_VERSION) { + return true; + } + + if (!CBB_add_u16(out, TLSEXT_TYPE_extended_master_secret) || + !CBB_add_u16(out, 0 /* length */)) { + return false; + } + + return true; +} + +static bool ext_ems_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert, + CBS *contents) { + SSL *const ssl = hs->ssl; + + if (contents != NULL) { + if (ssl_protocol_version(ssl) >= TLS1_3_VERSION || + ssl->version == SSL3_VERSION || + CBS_len(contents) != 0) { + return false; + } + + hs->extended_master_secret = true; + } + + // Whether EMS is negotiated may not change on renegotiation. + if (ssl->s3->established_session != nullptr && + hs->extended_master_secret != + !!ssl->s3->established_session->extended_master_secret) { + OPENSSL_PUT_ERROR(SSL, SSL_R_RENEGOTIATION_EMS_MISMATCH); + *out_alert = SSL_AD_ILLEGAL_PARAMETER; + return false; + } + + return true; +} + +static bool ext_ems_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert, + CBS *contents) { + uint16_t version = ssl_protocol_version(hs->ssl); + if (version >= TLS1_3_VERSION || + version == SSL3_VERSION) { + return true; + } + + if (contents == NULL) { + return true; + } + + if (CBS_len(contents) != 0) { + return false; + } + + hs->extended_master_secret = true; + return true; +} + +static bool ext_ems_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) { + if (!hs->extended_master_secret) { + return true; + } + + if (!CBB_add_u16(out, TLSEXT_TYPE_extended_master_secret) || + !CBB_add_u16(out, 0 /* length */)) { + return false; + } + + return true; +} + + +// Session tickets. +// +// https://tools.ietf.org/html/rfc5077 + +static bool ext_ticket_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) { + SSL *const ssl = hs->ssl; + // TLS 1.3 uses a different ticket extension. + if (hs->min_version >= TLS1_3_VERSION || + SSL_get_options(ssl) & SSL_OP_NO_TICKET) { + return true; + } + + const uint8_t *ticket_data = NULL; + int ticket_len = 0; + + // Renegotiation does not participate in session resumption. However, still + // advertise the extension to avoid potentially breaking servers which carry + // over the state from the previous handshake, such as OpenSSL servers + // without upstream's 3c3f0259238594d77264a78944d409f2127642c4. + if (!ssl->s3->initial_handshake_complete && + ssl->session != NULL && + ssl->session->tlsext_tick != NULL && + // Don't send TLS 1.3 session tickets in the ticket extension. + ssl_session_protocol_version(ssl->session) < TLS1_3_VERSION) { + ticket_data = ssl->session->tlsext_tick; + ticket_len = ssl->session->tlsext_ticklen; + } + + CBB ticket; + if (!CBB_add_u16(out, TLSEXT_TYPE_session_ticket) || + !CBB_add_u16_length_prefixed(out, &ticket) || + !CBB_add_bytes(&ticket, ticket_data, ticket_len) || + !CBB_flush(out)) { + return false; + } + + return true; +} + +static bool ext_ticket_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert, + CBS *contents) { + SSL *const ssl = hs->ssl; + if (contents == NULL) { + return true; + } + + if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) { + return false; + } + + // If |SSL_OP_NO_TICKET| is set then no extension will have been sent and + // this function should never be called, even if the server tries to send the + // extension. + assert((SSL_get_options(ssl) & SSL_OP_NO_TICKET) == 0); + + if (CBS_len(contents) != 0) { + return false; + } + + hs->ticket_expected = true; + return true; +} + +static bool ext_ticket_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) { + if (!hs->ticket_expected) { + return true; + } + + // If |SSL_OP_NO_TICKET| is set, |ticket_expected| should never be true. + assert((SSL_get_options(hs->ssl) & SSL_OP_NO_TICKET) == 0); + + if (!CBB_add_u16(out, TLSEXT_TYPE_session_ticket) || + !CBB_add_u16(out, 0 /* length */)) { + return false; + } + + return true; +} + + +// Signature Algorithms. +// +// https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 + +static bool ext_sigalgs_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) { + SSL *const ssl = hs->ssl; + if (hs->max_version < TLS1_2_VERSION) { + return true; + } + + CBB contents, sigalgs_cbb; + if (!CBB_add_u16(out, TLSEXT_TYPE_signature_algorithms) || + !CBB_add_u16_length_prefixed(out, &contents) || + !CBB_add_u16_length_prefixed(&contents, &sigalgs_cbb) || + !tls12_add_verify_sigalgs(ssl, &sigalgs_cbb) || + !CBB_flush(out)) { + return false; + } + + return true; +} + +static bool ext_sigalgs_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert, + CBS *contents) { + hs->peer_sigalgs.Reset(); + if (contents == NULL) { + return true; + } + + CBS supported_signature_algorithms; + if (!CBS_get_u16_length_prefixed(contents, &supported_signature_algorithms) || + CBS_len(contents) != 0 || + CBS_len(&supported_signature_algorithms) == 0 || + !tls1_parse_peer_sigalgs(hs, &supported_signature_algorithms)) { + return false; + } + + return true; +} + + +// OCSP Stapling. +// +// https://tools.ietf.org/html/rfc6066#section-8 + +static bool ext_ocsp_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) { + SSL *const ssl = hs->ssl; + if (!ssl->ocsp_stapling_enabled) { + return true; + } + + CBB contents; + if (!CBB_add_u16(out, TLSEXT_TYPE_status_request) || + !CBB_add_u16_length_prefixed(out, &contents) || + !CBB_add_u8(&contents, TLSEXT_STATUSTYPE_ocsp) || + !CBB_add_u16(&contents, 0 /* empty responder ID list */) || + !CBB_add_u16(&contents, 0 /* empty request extensions */) || + !CBB_flush(out)) { + return false; + } + + return true; +} + +static bool ext_ocsp_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert, + CBS *contents) { + SSL *const ssl = hs->ssl; + if (contents == NULL) { + return true; + } + + // TLS 1.3 OCSP responses are included in the Certificate extensions. + if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) { + return false; + } + + // OCSP stapling is forbidden on non-certificate ciphers. + if (CBS_len(contents) != 0 || + !ssl_cipher_uses_certificate_auth(hs->new_cipher)) { + return false; + } + + // Note this does not check for resumption in TLS 1.2. Sending + // status_request here does not make sense, but OpenSSL does so and the + // specification does not say anything. Tolerate it but ignore it. + + hs->certificate_status_expected = true; + return true; +} + +static bool ext_ocsp_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert, + CBS *contents) { + if (contents == NULL) { + return true; + } + + uint8_t status_type; + if (!CBS_get_u8(contents, &status_type)) { + return false; + } + + // We cannot decide whether OCSP stapling will occur yet because the correct + // SSL_CTX might not have been selected. + hs->ocsp_stapling_requested = status_type == TLSEXT_STATUSTYPE_ocsp; + + return true; +} + +static bool ext_ocsp_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) { + SSL *const ssl = hs->ssl; + if (ssl_protocol_version(ssl) >= TLS1_3_VERSION || + !hs->ocsp_stapling_requested || + ssl->cert->ocsp_response == NULL || + ssl->s3->session_reused || + !ssl_cipher_uses_certificate_auth(hs->new_cipher)) { + return true; + } + + hs->certificate_status_expected = true; + + return CBB_add_u16(out, TLSEXT_TYPE_status_request) && + CBB_add_u16(out, 0 /* length */); +} + + +// Next protocol negotiation. +// +// https://htmlpreview.github.io/?https://github.com/agl/technotes/blob/master/nextprotoneg.html + +static bool ext_npn_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) { + SSL *const ssl = hs->ssl; + if (ssl->s3->initial_handshake_complete || + ssl->ctx->next_proto_select_cb == NULL || + SSL_is_dtls(ssl)) { + return true; + } + + if (!CBB_add_u16(out, TLSEXT_TYPE_next_proto_neg) || + !CBB_add_u16(out, 0 /* length */)) { + return false; + } + + return true; +} + +static bool ext_npn_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert, + CBS *contents) { + SSL *const ssl = hs->ssl; + if (contents == NULL) { + return true; + } + + if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) { + return false; + } + + // If any of these are false then we should never have sent the NPN + // extension in the ClientHello and thus this function should never have been + // called. + assert(!ssl->s3->initial_handshake_complete); + assert(!SSL_is_dtls(ssl)); + assert(ssl->ctx->next_proto_select_cb != NULL); + + if (!ssl->s3->alpn_selected.empty()) { + // NPN and ALPN may not be negotiated in the same connection. + *out_alert = SSL_AD_ILLEGAL_PARAMETER; + OPENSSL_PUT_ERROR(SSL, SSL_R_NEGOTIATED_BOTH_NPN_AND_ALPN); + return false; + } + + const uint8_t *const orig_contents = CBS_data(contents); + const size_t orig_len = CBS_len(contents); + + while (CBS_len(contents) != 0) { + CBS proto; + if (!CBS_get_u8_length_prefixed(contents, &proto) || + CBS_len(&proto) == 0) { + return false; + } + } + + uint8_t *selected; + uint8_t selected_len; + if (ssl->ctx->next_proto_select_cb( + ssl, &selected, &selected_len, orig_contents, orig_len, + ssl->ctx->next_proto_select_cb_arg) != SSL_TLSEXT_ERR_OK || + !ssl->s3->next_proto_negotiated.CopyFrom( + MakeConstSpan(selected, selected_len))) { + *out_alert = SSL_AD_INTERNAL_ERROR; + return false; + } + + hs->next_proto_neg_seen = true; + return true; +} + +static bool ext_npn_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert, + CBS *contents) { + SSL *const ssl = hs->ssl; + if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) { + return true; + } + + if (contents != NULL && CBS_len(contents) != 0) { + return false; + } + + if (contents == NULL || + ssl->s3->initial_handshake_complete || + ssl->ctx->next_protos_advertised_cb == NULL || + SSL_is_dtls(ssl)) { + return true; + } + + hs->next_proto_neg_seen = true; + return true; +} + +static bool ext_npn_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) { + SSL *const ssl = hs->ssl; + // |next_proto_neg_seen| might have been cleared when an ALPN extension was + // parsed. + if (!hs->next_proto_neg_seen) { + return true; + } + + const uint8_t *npa; + unsigned npa_len; + + if (ssl->ctx->next_protos_advertised_cb( + ssl, &npa, &npa_len, ssl->ctx->next_protos_advertised_cb_arg) != + SSL_TLSEXT_ERR_OK) { + hs->next_proto_neg_seen = false; + return true; + } + + CBB contents; + if (!CBB_add_u16(out, TLSEXT_TYPE_next_proto_neg) || + !CBB_add_u16_length_prefixed(out, &contents) || + !CBB_add_bytes(&contents, npa, npa_len) || + !CBB_flush(out)) { + return false; + } + + return true; +} + + +// Signed certificate timestamps. +// +// https://tools.ietf.org/html/rfc6962#section-3.3.1 + +static bool ext_sct_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) { + SSL *const ssl = hs->ssl; + if (!ssl->signed_cert_timestamps_enabled) { + return true; + } + + if (!CBB_add_u16(out, TLSEXT_TYPE_certificate_timestamp) || + !CBB_add_u16(out, 0 /* length */)) { + return false; + } + + return true; +} + +static bool ext_sct_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert, + CBS *contents) { + SSL *const ssl = hs->ssl; + if (contents == NULL) { + return true; + } + + // TLS 1.3 SCTs are included in the Certificate extensions. + if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) { + *out_alert = SSL_AD_DECODE_ERROR; + return false; + } + + // If this is false then we should never have sent the SCT extension in the + // ClientHello and thus this function should never have been called. + assert(ssl->signed_cert_timestamps_enabled); + + if (!ssl_is_sct_list_valid(contents)) { + *out_alert = SSL_AD_DECODE_ERROR; + return false; + } + + // Session resumption uses the original session information. The extension + // should not be sent on resumption, but RFC 6962 did not make it a + // requirement, so tolerate this. + // + // TODO(davidben): Enforce this anyway. + if (!ssl->s3->session_reused) { + CRYPTO_BUFFER_free(hs->new_session->signed_cert_timestamp_list); + hs->new_session->signed_cert_timestamp_list = + CRYPTO_BUFFER_new_from_CBS(contents, ssl->ctx->pool); + if (hs->new_session->signed_cert_timestamp_list == nullptr) { + *out_alert = SSL_AD_INTERNAL_ERROR; + return false; + } + } + + return true; +} + +static bool ext_sct_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert, + CBS *contents) { + if (contents == NULL) { + return true; + } + + if (CBS_len(contents) != 0) { + return false; + } + + hs->scts_requested = true; + return true; +} + +static bool ext_sct_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) { + SSL *const ssl = hs->ssl; + // The extension shouldn't be sent when resuming sessions. + if (ssl_protocol_version(ssl) >= TLS1_3_VERSION || + ssl->s3->session_reused || + ssl->cert->signed_cert_timestamp_list == NULL) { + return true; + } + + CBB contents; + return CBB_add_u16(out, TLSEXT_TYPE_certificate_timestamp) && + CBB_add_u16_length_prefixed(out, &contents) && + CBB_add_bytes( + &contents, + CRYPTO_BUFFER_data(ssl->cert->signed_cert_timestamp_list), + CRYPTO_BUFFER_len(ssl->cert->signed_cert_timestamp_list)) && + CBB_flush(out); +} + + +// Application-level Protocol Negotiation. +// +// https://tools.ietf.org/html/rfc7301 + +static bool ext_alpn_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) { + SSL *const ssl = hs->ssl; + if (ssl->alpn_client_proto_list == NULL || + ssl->s3->initial_handshake_complete) { + return true; + } + + CBB contents, proto_list; + if (!CBB_add_u16(out, TLSEXT_TYPE_application_layer_protocol_negotiation) || + !CBB_add_u16_length_prefixed(out, &contents) || + !CBB_add_u16_length_prefixed(&contents, &proto_list) || + !CBB_add_bytes(&proto_list, ssl->alpn_client_proto_list, + ssl->alpn_client_proto_list_len) || + !CBB_flush(out)) { + return false; + } + + return true; +} + +static bool ext_alpn_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert, + CBS *contents) { + SSL *const ssl = hs->ssl; + if (contents == NULL) { + return true; + } + + assert(!ssl->s3->initial_handshake_complete); + assert(ssl->alpn_client_proto_list != NULL); + + if (hs->next_proto_neg_seen) { + // NPN and ALPN may not be negotiated in the same connection. + *out_alert = SSL_AD_ILLEGAL_PARAMETER; + OPENSSL_PUT_ERROR(SSL, SSL_R_NEGOTIATED_BOTH_NPN_AND_ALPN); + return false; + } + + // The extension data consists of a ProtocolNameList which must have + // exactly one ProtocolName. Each of these is length-prefixed. + CBS protocol_name_list, protocol_name; + if (!CBS_get_u16_length_prefixed(contents, &protocol_name_list) || + CBS_len(contents) != 0 || + !CBS_get_u8_length_prefixed(&protocol_name_list, &protocol_name) || + // Empty protocol names are forbidden. + CBS_len(&protocol_name) == 0 || + CBS_len(&protocol_name_list) != 0) { + return false; + } + + if (!ssl_is_alpn_protocol_allowed(ssl, protocol_name)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_ALPN_PROTOCOL); + *out_alert = SSL_AD_ILLEGAL_PARAMETER; + return false; + } + + if (!ssl->s3->alpn_selected.CopyFrom(protocol_name)) { + *out_alert = SSL_AD_INTERNAL_ERROR; + return false; + } + + return true; +} + +bool ssl_is_alpn_protocol_allowed(const SSL *ssl, + Span protocol) { + if (ssl->alpn_client_proto_list == nullptr) { + return false; + } + + if (ssl->ctx->allow_unknown_alpn_protos) { + return true; + } + + // Check that the protocol name is one of the ones we advertised. + CBS client_protocol_name_list, client_protocol_name; + CBS_init(&client_protocol_name_list, ssl->alpn_client_proto_list, + ssl->alpn_client_proto_list_len); + while (CBS_len(&client_protocol_name_list) > 0) { + if (!CBS_get_u8_length_prefixed(&client_protocol_name_list, + &client_protocol_name)) { + return false; + } + + if (client_protocol_name == protocol) { + return true; + } + } + + return false; +} + +bool ssl_negotiate_alpn(SSL_HANDSHAKE *hs, uint8_t *out_alert, + const SSL_CLIENT_HELLO *client_hello) { + SSL *const ssl = hs->ssl; + CBS contents; + if (ssl->ctx->alpn_select_cb == NULL || + !ssl_client_hello_get_extension( + client_hello, &contents, + TLSEXT_TYPE_application_layer_protocol_negotiation)) { + // Ignore ALPN if not configured or no extension was supplied. + return true; + } + + // ALPN takes precedence over NPN. + hs->next_proto_neg_seen = false; + + CBS protocol_name_list; + if (!CBS_get_u16_length_prefixed(&contents, &protocol_name_list) || + CBS_len(&contents) != 0 || + CBS_len(&protocol_name_list) < 2) { + OPENSSL_PUT_ERROR(SSL, SSL_R_PARSE_TLSEXT); + *out_alert = SSL_AD_DECODE_ERROR; + return false; + } + + // Validate the protocol list. + CBS protocol_name_list_copy = protocol_name_list; + while (CBS_len(&protocol_name_list_copy) > 0) { + CBS protocol_name; + + if (!CBS_get_u8_length_prefixed(&protocol_name_list_copy, &protocol_name) || + // Empty protocol names are forbidden. + CBS_len(&protocol_name) == 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_PARSE_TLSEXT); + *out_alert = SSL_AD_DECODE_ERROR; + return false; + } + } + + const uint8_t *selected; + uint8_t selected_len; + if (ssl->ctx->alpn_select_cb( + ssl, &selected, &selected_len, CBS_data(&protocol_name_list), + CBS_len(&protocol_name_list), + ssl->ctx->alpn_select_cb_arg) == SSL_TLSEXT_ERR_OK) { + if (!ssl->s3->alpn_selected.CopyFrom( + MakeConstSpan(selected, selected_len))) { + *out_alert = SSL_AD_INTERNAL_ERROR; + return false; + } + } + + return true; +} + +static bool ext_alpn_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) { + SSL *const ssl = hs->ssl; + if (ssl->s3->alpn_selected.empty()) { + return true; + } + + CBB contents, proto_list, proto; + if (!CBB_add_u16(out, TLSEXT_TYPE_application_layer_protocol_negotiation) || + !CBB_add_u16_length_prefixed(out, &contents) || + !CBB_add_u16_length_prefixed(&contents, &proto_list) || + !CBB_add_u8_length_prefixed(&proto_list, &proto) || + !CBB_add_bytes(&proto, ssl->s3->alpn_selected.data(), + ssl->s3->alpn_selected.size()) || + !CBB_flush(out)) { + return false; + } + + return true; +} + + +// Channel ID. +// +// https://tools.ietf.org/html/draft-balfanz-tls-channelid-01 + +static void ext_channel_id_init(SSL_HANDSHAKE *hs) { + hs->ssl->s3->tlsext_channel_id_valid = false; +} + +static bool ext_channel_id_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) { + SSL *const ssl = hs->ssl; + if (!ssl->tlsext_channel_id_enabled || + SSL_is_dtls(ssl)) { + return true; + } + + if (!CBB_add_u16(out, TLSEXT_TYPE_channel_id) || + !CBB_add_u16(out, 0 /* length */)) { + return false; + } + + return true; +} + +static bool ext_channel_id_parse_serverhello(SSL_HANDSHAKE *hs, + uint8_t *out_alert, + CBS *contents) { + SSL *const ssl = hs->ssl; + if (contents == NULL) { + return true; + } + + assert(!SSL_is_dtls(ssl)); + assert(ssl->tlsext_channel_id_enabled); + + if (CBS_len(contents) != 0) { + return false; + } + + ssl->s3->tlsext_channel_id_valid = true; + return true; +} + +static bool ext_channel_id_parse_clienthello(SSL_HANDSHAKE *hs, + uint8_t *out_alert, + CBS *contents) { + SSL *const ssl = hs->ssl; + if (contents == NULL || + !ssl->tlsext_channel_id_enabled || + SSL_is_dtls(ssl)) { + return true; + } + + if (CBS_len(contents) != 0) { + return false; + } + + ssl->s3->tlsext_channel_id_valid = true; + return true; +} + +static bool ext_channel_id_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) { + SSL *const ssl = hs->ssl; + if (!ssl->s3->tlsext_channel_id_valid) { + return true; + } + + if (!CBB_add_u16(out, TLSEXT_TYPE_channel_id) || + !CBB_add_u16(out, 0 /* length */)) { + return false; + } + + return true; +} + + +// Secure Real-time Transport Protocol (SRTP) extension. +// +// https://tools.ietf.org/html/rfc5764 + + +static void ext_srtp_init(SSL_HANDSHAKE *hs) { + hs->ssl->srtp_profile = NULL; +} + +static bool ext_srtp_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) { + SSL *const ssl = hs->ssl; + STACK_OF(SRTP_PROTECTION_PROFILE) *profiles = SSL_get_srtp_profiles(ssl); + if (profiles == NULL || + sk_SRTP_PROTECTION_PROFILE_num(profiles) == 0) { + return true; + } + + CBB contents, profile_ids; + if (!CBB_add_u16(out, TLSEXT_TYPE_srtp) || + !CBB_add_u16_length_prefixed(out, &contents) || + !CBB_add_u16_length_prefixed(&contents, &profile_ids)) { + return false; + } + + for (const SRTP_PROTECTION_PROFILE *profile : profiles) { + if (!CBB_add_u16(&profile_ids, profile->id)) { + return false; + } + } + + if (!CBB_add_u8(&contents, 0 /* empty use_mki value */) || + !CBB_flush(out)) { + return false; + } + + return true; +} + +static bool ext_srtp_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert, + CBS *contents) { + SSL *const ssl = hs->ssl; + if (contents == NULL) { + return true; + } + + // The extension consists of a u16-prefixed profile ID list containing a + // single uint16_t profile ID, then followed by a u8-prefixed srtp_mki field. + // + // See https://tools.ietf.org/html/rfc5764#section-4.1.1 + CBS profile_ids, srtp_mki; + uint16_t profile_id; + if (!CBS_get_u16_length_prefixed(contents, &profile_ids) || + !CBS_get_u16(&profile_ids, &profile_id) || + CBS_len(&profile_ids) != 0 || + !CBS_get_u8_length_prefixed(contents, &srtp_mki) || + CBS_len(contents) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST); + return false; + } + + if (CBS_len(&srtp_mki) != 0) { + // Must be no MKI, since we never offer one. + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SRTP_MKI_VALUE); + *out_alert = SSL_AD_ILLEGAL_PARAMETER; + return false; + } + + STACK_OF(SRTP_PROTECTION_PROFILE) *profiles = SSL_get_srtp_profiles(ssl); + + // Check to see if the server gave us something we support (and presumably + // offered). + for (const SRTP_PROTECTION_PROFILE *profile : profiles) { + if (profile->id == profile_id) { + ssl->srtp_profile = profile; + return true; + } + } + + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST); + *out_alert = SSL_AD_ILLEGAL_PARAMETER; + return false; +} + +static bool ext_srtp_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert, + CBS *contents) { + SSL *const ssl = hs->ssl; + if (contents == NULL) { + return true; + } + + CBS profile_ids, srtp_mki; + if (!CBS_get_u16_length_prefixed(contents, &profile_ids) || + CBS_len(&profile_ids) < 2 || + !CBS_get_u8_length_prefixed(contents, &srtp_mki) || + CBS_len(contents) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST); + return false; + } + // Discard the MKI value for now. + + const STACK_OF(SRTP_PROTECTION_PROFILE) *server_profiles = + SSL_get_srtp_profiles(ssl); + + // Pick the server's most preferred profile. + for (const SRTP_PROTECTION_PROFILE *server_profile : server_profiles) { + CBS profile_ids_tmp; + CBS_init(&profile_ids_tmp, CBS_data(&profile_ids), CBS_len(&profile_ids)); + + while (CBS_len(&profile_ids_tmp) > 0) { + uint16_t profile_id; + if (!CBS_get_u16(&profile_ids_tmp, &profile_id)) { + return false; + } + + if (server_profile->id == profile_id) { + ssl->srtp_profile = server_profile; + return true; + } + } + } + + return true; +} + +static bool ext_srtp_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) { + SSL *const ssl = hs->ssl; + if (ssl->srtp_profile == NULL) { + return true; + } + + CBB contents, profile_ids; + if (!CBB_add_u16(out, TLSEXT_TYPE_srtp) || + !CBB_add_u16_length_prefixed(out, &contents) || + !CBB_add_u16_length_prefixed(&contents, &profile_ids) || + !CBB_add_u16(&profile_ids, ssl->srtp_profile->id) || + !CBB_add_u8(&contents, 0 /* empty MKI */) || + !CBB_flush(out)) { + return false; + } + + return true; +} + + +// EC point formats. +// +// https://tools.ietf.org/html/rfc4492#section-5.1.2 + +static bool ext_ec_point_add_extension(SSL_HANDSHAKE *hs, CBB *out) { + CBB contents, formats; + if (!CBB_add_u16(out, TLSEXT_TYPE_ec_point_formats) || + !CBB_add_u16_length_prefixed(out, &contents) || + !CBB_add_u8_length_prefixed(&contents, &formats) || + !CBB_add_u8(&formats, TLSEXT_ECPOINTFORMAT_uncompressed) || + !CBB_flush(out)) { + return false; + } + + return true; +} + +static bool ext_ec_point_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) { + // The point format extension is unneccessary in TLS 1.3. + if (hs->min_version >= TLS1_3_VERSION) { + return true; + } + + return ext_ec_point_add_extension(hs, out); +} + +static bool ext_ec_point_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert, + CBS *contents) { + if (contents == NULL) { + return true; + } + + if (ssl_protocol_version(hs->ssl) >= TLS1_3_VERSION) { + return false; + } + + CBS ec_point_format_list; + if (!CBS_get_u8_length_prefixed(contents, &ec_point_format_list) || + CBS_len(contents) != 0) { + return false; + } + + // Per RFC 4492, section 5.1.2, implementations MUST support the uncompressed + // point format. + if (OPENSSL_memchr(CBS_data(&ec_point_format_list), + TLSEXT_ECPOINTFORMAT_uncompressed, + CBS_len(&ec_point_format_list)) == NULL) { + *out_alert = SSL_AD_ILLEGAL_PARAMETER; + return false; + } + + return true; +} + +static bool ext_ec_point_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert, + CBS *contents) { + if (ssl_protocol_version(hs->ssl) >= TLS1_3_VERSION) { + return true; + } + + return ext_ec_point_parse_serverhello(hs, out_alert, contents); +} + +static bool ext_ec_point_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) { + SSL *const ssl = hs->ssl; + if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) { + return true; + } + + const uint32_t alg_k = hs->new_cipher->algorithm_mkey; + const uint32_t alg_a = hs->new_cipher->algorithm_auth; + const bool using_ecc = (alg_k & SSL_kECDHE) || (alg_a & SSL_aECDSA); + + if (!using_ecc) { + return true; + } + + return ext_ec_point_add_extension(hs, out); +} + + +// Pre Shared Key +// +// https://tools.ietf.org/html/draft-ietf-tls-tls13-18#section-4.2.6 + +static size_t ext_pre_shared_key_clienthello_length(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + if (hs->max_version < TLS1_3_VERSION || ssl->session == NULL || + ssl_session_protocol_version(ssl->session) < TLS1_3_VERSION) { + return 0; + } + + size_t binder_len = EVP_MD_size(ssl_session_get_digest(ssl->session)); + return 15 + ssl->session->tlsext_ticklen + binder_len; +} + +static bool ext_pre_shared_key_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) { + SSL *const ssl = hs->ssl; + hs->needs_psk_binder = false; + if (hs->max_version < TLS1_3_VERSION || ssl->session == NULL || + ssl_session_protocol_version(ssl->session) < TLS1_3_VERSION) { + return true; + } + + // Per draft-ietf-tls-tls13-21 section 4.1.4, skip offering the session if the + // selected cipher in HelloRetryRequest does not match. This avoids performing + // the transcript hash transformation for multiple hashes. + if (hs->received_hello_retry_request && + ssl->session->cipher->algorithm_prf != hs->new_cipher->algorithm_prf) { + return true; + } + + struct OPENSSL_timeval now; + ssl_get_current_time(ssl, &now); + uint32_t ticket_age = 1000 * (now.tv_sec - ssl->session->time); + uint32_t obfuscated_ticket_age = ticket_age + ssl->session->ticket_age_add; + + // Fill in a placeholder zero binder of the appropriate length. It will be + // computed and filled in later after length prefixes are computed. + uint8_t zero_binder[EVP_MAX_MD_SIZE] = {0}; + size_t binder_len = EVP_MD_size(ssl_session_get_digest(ssl->session)); + + CBB contents, identity, ticket, binders, binder; + if (!CBB_add_u16(out, TLSEXT_TYPE_pre_shared_key) || + !CBB_add_u16_length_prefixed(out, &contents) || + !CBB_add_u16_length_prefixed(&contents, &identity) || + !CBB_add_u16_length_prefixed(&identity, &ticket) || + !CBB_add_bytes(&ticket, ssl->session->tlsext_tick, + ssl->session->tlsext_ticklen) || + !CBB_add_u32(&identity, obfuscated_ticket_age) || + !CBB_add_u16_length_prefixed(&contents, &binders) || + !CBB_add_u8_length_prefixed(&binders, &binder) || + !CBB_add_bytes(&binder, zero_binder, binder_len)) { + return false; + } + + hs->needs_psk_binder = true; + return CBB_flush(out); +} + +bool ssl_ext_pre_shared_key_parse_serverhello(SSL_HANDSHAKE *hs, + uint8_t *out_alert, + CBS *contents) { + uint16_t psk_id; + if (!CBS_get_u16(contents, &psk_id) || + CBS_len(contents) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + *out_alert = SSL_AD_DECODE_ERROR; + return false; + } + + // We only advertise one PSK identity, so the only legal index is zero. + if (psk_id != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_PSK_IDENTITY_NOT_FOUND); + *out_alert = SSL_AD_UNKNOWN_PSK_IDENTITY; + return false; + } + + return true; +} + +bool ssl_ext_pre_shared_key_parse_clienthello( + SSL_HANDSHAKE *hs, CBS *out_ticket, CBS *out_binders, + uint32_t *out_obfuscated_ticket_age, uint8_t *out_alert, CBS *contents) { + // We only process the first PSK identity since we don't support pure PSK. + CBS identities, binders; + if (!CBS_get_u16_length_prefixed(contents, &identities) || + !CBS_get_u16_length_prefixed(&identities, out_ticket) || + !CBS_get_u32(&identities, out_obfuscated_ticket_age) || + !CBS_get_u16_length_prefixed(contents, &binders) || + CBS_len(&binders) == 0 || + CBS_len(contents) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + *out_alert = SSL_AD_DECODE_ERROR; + return false; + } + + *out_binders = binders; + + // Check the syntax of the remaining identities, but do not process them. + size_t num_identities = 1; + while (CBS_len(&identities) != 0) { + CBS unused_ticket; + uint32_t unused_obfuscated_ticket_age; + if (!CBS_get_u16_length_prefixed(&identities, &unused_ticket) || + !CBS_get_u32(&identities, &unused_obfuscated_ticket_age)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + *out_alert = SSL_AD_DECODE_ERROR; + return false; + } + + num_identities++; + } + + // Check the syntax of the binders. The value will be checked later if + // resuming. + size_t num_binders = 0; + while (CBS_len(&binders) != 0) { + CBS binder; + if (!CBS_get_u8_length_prefixed(&binders, &binder)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + *out_alert = SSL_AD_DECODE_ERROR; + return false; + } + + num_binders++; + } + + if (num_identities != num_binders) { + OPENSSL_PUT_ERROR(SSL, SSL_R_PSK_IDENTITY_BINDER_COUNT_MISMATCH); + *out_alert = SSL_AD_ILLEGAL_PARAMETER; + return false; + } + + return true; +} + +bool ssl_ext_pre_shared_key_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) { + if (!hs->ssl->s3->session_reused) { + return true; + } + + CBB contents; + if (!CBB_add_u16(out, TLSEXT_TYPE_pre_shared_key) || + !CBB_add_u16_length_prefixed(out, &contents) || + // We only consider the first identity for resumption + !CBB_add_u16(&contents, 0) || + !CBB_flush(out)) { + return false; + } + + return true; +} + + +// Pre-Shared Key Exchange Modes +// +// https://tools.ietf.org/html/draft-ietf-tls-tls13-18#section-4.2.7 + +static bool ext_psk_key_exchange_modes_add_clienthello(SSL_HANDSHAKE *hs, + CBB *out) { + if (hs->max_version < TLS1_3_VERSION) { + return true; + } + + CBB contents, ke_modes; + if (!CBB_add_u16(out, TLSEXT_TYPE_psk_key_exchange_modes) || + !CBB_add_u16_length_prefixed(out, &contents) || + !CBB_add_u8_length_prefixed(&contents, &ke_modes) || + !CBB_add_u8(&ke_modes, SSL_PSK_DHE_KE)) { + return false; + } + + return CBB_flush(out); +} + +static bool ext_psk_key_exchange_modes_parse_clienthello(SSL_HANDSHAKE *hs, + uint8_t *out_alert, + CBS *contents) { + if (contents == NULL) { + return true; + } + + CBS ke_modes; + if (!CBS_get_u8_length_prefixed(contents, &ke_modes) || + CBS_len(&ke_modes) == 0 || + CBS_len(contents) != 0) { + *out_alert = SSL_AD_DECODE_ERROR; + return false; + } + + // We only support tickets with PSK_DHE_KE. + hs->accept_psk_mode = OPENSSL_memchr(CBS_data(&ke_modes), SSL_PSK_DHE_KE, + CBS_len(&ke_modes)) != NULL; + + return true; +} + + +// Early Data Indication +// +// https://tools.ietf.org/html/draft-ietf-tls-tls13-18#section-4.2.8 + +static bool ext_early_data_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) { + SSL *const ssl = hs->ssl; + if (!ssl->cert->enable_early_data || + // Session must be 0-RTT capable. + ssl->session == NULL || + ssl_session_protocol_version(ssl->session) < TLS1_3_VERSION || + ssl->session->ticket_max_early_data == 0 || + // The second ClientHello never offers early data. + hs->received_hello_retry_request || + // In case ALPN preferences changed since this session was established, + // avoid reporting a confusing value in |SSL_get0_alpn_selected|. + (ssl->session->early_alpn_len != 0 && + !ssl_is_alpn_protocol_allowed( + ssl, MakeConstSpan(ssl->session->early_alpn, + ssl->session->early_alpn_len)))) { + return true; + } + + hs->early_data_offered = true; + + if (!CBB_add_u16(out, TLSEXT_TYPE_early_data) || + !CBB_add_u16(out, 0) || + !CBB_flush(out)) { + return false; + } + + return true; +} + +static bool ext_early_data_parse_serverhello(SSL_HANDSHAKE *hs, + uint8_t *out_alert, CBS *contents) { + SSL *const ssl = hs->ssl; + if (contents == NULL) { + return true; + } + + if (CBS_len(contents) != 0) { + *out_alert = SSL_AD_DECODE_ERROR; + return false; + } + + if (!ssl->s3->session_reused) { + *out_alert = SSL_AD_UNSUPPORTED_EXTENSION; + OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION); + return false; + } + + ssl->s3->early_data_accepted = true; + return true; +} + +static bool ext_early_data_parse_clienthello(SSL_HANDSHAKE *hs, + uint8_t *out_alert, CBS *contents) { + SSL *const ssl = hs->ssl; + if (contents == NULL || + ssl_protocol_version(ssl) < TLS1_3_VERSION) { + return true; + } + + if (CBS_len(contents) != 0) { + *out_alert = SSL_AD_DECODE_ERROR; + return false; + } + + hs->early_data_offered = true; + return true; +} + +static bool ext_early_data_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) { + if (!hs->ssl->s3->early_data_accepted) { + return true; + } + + if (!CBB_add_u16(out, TLSEXT_TYPE_early_data) || + !CBB_add_u16(out, 0) || + !CBB_flush(out)) { + return false; + } + + return true; +} + + +// Key Share +// +// https://tools.ietf.org/html/draft-ietf-tls-tls13-16#section-4.2.5 + +static bool ext_key_share_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) { + SSL *const ssl = hs->ssl; + if (hs->max_version < TLS1_3_VERSION) { + return true; + } + + CBB contents, kse_bytes; + if (!CBB_add_u16(out, TLSEXT_TYPE_key_share) || + !CBB_add_u16_length_prefixed(out, &contents) || + !CBB_add_u16_length_prefixed(&contents, &kse_bytes)) { + return false; + } + + uint16_t group_id = hs->retry_group; + if (hs->received_hello_retry_request) { + // We received a HelloRetryRequest without a new curve, so there is no new + // share to append. Leave |hs->key_share| as-is. + if (group_id == 0 && + !CBB_add_bytes(&kse_bytes, hs->key_share_bytes.data(), + hs->key_share_bytes.size())) { + return false; + } + hs->key_share_bytes.Reset(); + if (group_id == 0) { + return CBB_flush(out); + } + } else { + // Add a fake group. See draft-davidben-tls-grease-01. + if (ssl->ctx->grease_enabled && + (!CBB_add_u16(&kse_bytes, + ssl_get_grease_value(hs, ssl_grease_group)) || + !CBB_add_u16(&kse_bytes, 1 /* length */) || + !CBB_add_u8(&kse_bytes, 0 /* one byte key share */))) { + return false; + } + + // Predict the most preferred group. + Span groups = tls1_get_grouplist(ssl); + if (groups.empty()) { + OPENSSL_PUT_ERROR(SSL, SSL_R_NO_GROUPS_SPECIFIED); + return false; + } + + group_id = groups[0]; + } + + hs->key_share = SSLKeyShare::Create(group_id); + CBB key_exchange; + if (!hs->key_share || + !CBB_add_u16(&kse_bytes, group_id) || + !CBB_add_u16_length_prefixed(&kse_bytes, &key_exchange) || + !hs->key_share->Offer(&key_exchange) || + !CBB_flush(&kse_bytes)) { + return false; + } + + // Save the contents of the extension to repeat it in the second ClientHello. + if (!hs->received_hello_retry_request && + !hs->key_share_bytes.CopyFrom( + MakeConstSpan(CBB_data(&kse_bytes), CBB_len(&kse_bytes)))) { + return false; + } + + return CBB_flush(out); +} + +bool ssl_ext_key_share_parse_serverhello(SSL_HANDSHAKE *hs, + Array *out_secret, + uint8_t *out_alert, CBS *contents) { + CBS peer_key; + uint16_t group_id; + if (!CBS_get_u16(contents, &group_id) || + !CBS_get_u16_length_prefixed(contents, &peer_key) || + CBS_len(contents) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + *out_alert = SSL_AD_DECODE_ERROR; + return false; + } + + if (hs->key_share->GroupID() != group_id) { + *out_alert = SSL_AD_ILLEGAL_PARAMETER; + OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CURVE); + return false; + } + + if (!hs->key_share->Finish(out_secret, out_alert, peer_key)) { + *out_alert = SSL_AD_INTERNAL_ERROR; + return false; + } + + hs->new_session->group_id = group_id; + hs->key_share.reset(); + return true; +} + +bool ssl_ext_key_share_parse_clienthello(SSL_HANDSHAKE *hs, bool *out_found, + Array *out_secret, + uint8_t *out_alert, CBS *contents) { + uint16_t group_id; + CBS key_shares; + if (!tls1_get_shared_group(hs, &group_id)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_NO_SHARED_GROUP); + *out_alert = SSL_AD_HANDSHAKE_FAILURE; + return false; + } + + if (!CBS_get_u16_length_prefixed(contents, &key_shares) || + CBS_len(contents) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + return false; + } + + // Find the corresponding key share. + CBS peer_key; + CBS_init(&peer_key, NULL, 0); + while (CBS_len(&key_shares) > 0) { + uint16_t id; + CBS peer_key_tmp; + if (!CBS_get_u16(&key_shares, &id) || + !CBS_get_u16_length_prefixed(&key_shares, &peer_key_tmp) || + CBS_len(&peer_key_tmp) == 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + return false; + } + + if (id == group_id) { + if (CBS_len(&peer_key) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DUPLICATE_KEY_SHARE); + *out_alert = SSL_AD_ILLEGAL_PARAMETER; + return false; + } + + peer_key = peer_key_tmp; + // Continue parsing the structure to keep peers honest. + } + } + + if (CBS_len(&peer_key) == 0) { + *out_found = false; + out_secret->Reset(); + return true; + } + + // Compute the DH secret. + Array secret; + ScopedCBB public_key; + UniquePtr key_share = SSLKeyShare::Create(group_id); + if (!key_share || + !CBB_init(public_key.get(), 32) || + !key_share->Accept(public_key.get(), &secret, out_alert, peer_key) || + !CBBFinishArray(public_key.get(), &hs->ecdh_public_key)) { + *out_alert = SSL_AD_ILLEGAL_PARAMETER; + return false; + } + + *out_secret = std::move(secret); + *out_found = true; + return true; +} + +bool ssl_ext_key_share_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) { + uint16_t group_id; + CBB kse_bytes, public_key; + if (!tls1_get_shared_group(hs, &group_id) || + !CBB_add_u16(out, TLSEXT_TYPE_key_share) || + !CBB_add_u16_length_prefixed(out, &kse_bytes) || + !CBB_add_u16(&kse_bytes, group_id) || + !CBB_add_u16_length_prefixed(&kse_bytes, &public_key) || + !CBB_add_bytes(&public_key, hs->ecdh_public_key.data(), + hs->ecdh_public_key.size()) || + !CBB_flush(out)) { + return false; + } + + hs->ecdh_public_key.Reset(); + + hs->new_session->group_id = group_id; + return true; +} + + +// Supported Versions +// +// https://tools.ietf.org/html/draft-ietf-tls-tls13-16#section-4.2.1 + +static bool ext_supported_versions_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) { + SSL *const ssl = hs->ssl; + if (hs->max_version <= TLS1_2_VERSION) { + return true; + } + + CBB contents, versions; + if (!CBB_add_u16(out, TLSEXT_TYPE_supported_versions) || + !CBB_add_u16_length_prefixed(out, &contents) || + !CBB_add_u8_length_prefixed(&contents, &versions)) { + return false; + } + + // Add a fake version. See draft-davidben-tls-grease-01. + if (ssl->ctx->grease_enabled && + !CBB_add_u16(&versions, ssl_get_grease_value(hs, ssl_grease_version))) { + return false; + } + + if (!ssl_add_supported_versions(hs, &versions) || + !CBB_flush(out)) { + return false; + } + + return true; +} + + +// Cookie +// +// https://tools.ietf.org/html/draft-ietf-tls-tls13-16#section-4.2.2 + +static bool ext_cookie_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) { + if (hs->cookie.empty()) { + return true; + } + + CBB contents, cookie; + if (!CBB_add_u16(out, TLSEXT_TYPE_cookie) || + !CBB_add_u16_length_prefixed(out, &contents) || + !CBB_add_u16_length_prefixed(&contents, &cookie) || + !CBB_add_bytes(&cookie, hs->cookie.data(), hs->cookie.size()) || + !CBB_flush(out)) { + return false; + } + + // The cookie is no longer needed in memory. + hs->cookie.Reset(); + return true; +} + + +// Dummy PQ Padding extension +// +// Dummy post-quantum padding invovles the client (and later server) sending +// useless, random-looking bytes in an extension in their ClientHello or +// ServerHello. These extensions are sized to simulate a post-quantum +// key-exchange and so enable measurement of the latency impact of the +// additional bandwidth. + +static bool ext_dummy_pq_padding_add(CBB *out, size_t len) { + CBB contents; + uint8_t *buffer; + if (!CBB_add_u16(out, TLSEXT_TYPE_dummy_pq_padding) || + !CBB_add_u16_length_prefixed(out, &contents) || + !CBB_add_space(&contents, &buffer, len)) { + return false; + } + + // The length is used as the nonce so that different length extensions have + // different contents. There's no reason this has to be the case, it just + // makes things a little more obvious in a packet dump. + uint8_t nonce[12] = {0}; + memcpy(nonce, &len, sizeof(len)); + + memset(buffer, 0, len); + static const uint8_t kZeroKey[32] = {0}; + CRYPTO_chacha_20(buffer, buffer, len, kZeroKey, nonce, 0); + + return CBB_flush(out); +} + +static bool ext_dummy_pq_padding_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) { + const size_t len = hs->ssl->dummy_pq_padding_len; + if (len == 0) { + return true; + } + + return ext_dummy_pq_padding_add(out, len); +} + +static bool ext_dummy_pq_padding_parse_serverhello(SSL_HANDSHAKE *hs, + uint8_t *out_alert, + CBS *contents) { + if (contents == nullptr) { + return true; + } + + if (CBS_len(contents) != hs->ssl->dummy_pq_padding_len) { + return false; + } + + hs->ssl->did_dummy_pq_padding = true; + return true; +} + +static bool ext_dummy_pq_padding_parse_clienthello(SSL_HANDSHAKE *hs, + uint8_t *out_alert, + CBS *contents) { + if (contents != nullptr && + 0 < CBS_len(contents) && CBS_len(contents) < (1 << 12)) { + hs->dummy_pq_padding_len = CBS_len(contents); + } + + return true; +} + +static bool ext_dummy_pq_padding_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) { + if (!hs->dummy_pq_padding_len) { + return true; + } + + return ext_dummy_pq_padding_add(out, hs->dummy_pq_padding_len); +} + +// Negotiated Groups +// +// https://tools.ietf.org/html/rfc4492#section-5.1.2 +// https://tools.ietf.org/html/draft-ietf-tls-tls13-16#section-4.2.4 + +static bool ext_supported_groups_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) { + SSL *const ssl = hs->ssl; + CBB contents, groups_bytes; + if (!CBB_add_u16(out, TLSEXT_TYPE_supported_groups) || + !CBB_add_u16_length_prefixed(out, &contents) || + !CBB_add_u16_length_prefixed(&contents, &groups_bytes)) { + return false; + } + + // Add a fake group. See draft-davidben-tls-grease-01. + if (ssl->ctx->grease_enabled && + !CBB_add_u16(&groups_bytes, + ssl_get_grease_value(hs, ssl_grease_group))) { + return false; + } + + for (uint16_t group : tls1_get_grouplist(ssl)) { + if (!CBB_add_u16(&groups_bytes, group)) { + return false; + } + } + + return CBB_flush(out); +} + +static bool ext_supported_groups_parse_serverhello(SSL_HANDSHAKE *hs, + uint8_t *out_alert, + CBS *contents) { + // This extension is not expected to be echoed by servers in TLS 1.2, but some + // BigIP servers send it nonetheless, so do not enforce this. + return true; +} + +static bool parse_u16_array(const CBS *cbs, Array *out) { + CBS copy = *cbs; + if ((CBS_len(©) & 1) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + return false; + } + + Array ret; + if (!ret.Init(CBS_len(©) / 2)) { + return false; + } + for (size_t i = 0; i < ret.size(); i++) { + if (!CBS_get_u16(©, &ret[i])) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return false; + } + } + + assert(CBS_len(©) == 0); + *out = std::move(ret); + return 1; +} + +static bool ext_supported_groups_parse_clienthello(SSL_HANDSHAKE *hs, + uint8_t *out_alert, + CBS *contents) { + if (contents == NULL) { + return true; + } + + CBS supported_group_list; + if (!CBS_get_u16_length_prefixed(contents, &supported_group_list) || + CBS_len(&supported_group_list) == 0 || + CBS_len(contents) != 0 || + !parse_u16_array(&supported_group_list, &hs->peer_supported_group_list)) { + return false; + } + + return true; +} + +// Token Binding +// +// https://tools.ietf.org/html/draft-ietf-tokbind-negotiation-10 + +// The Token Binding version number currently matches the draft number of +// draft-ietf-tokbind-protocol, and when published as an RFC it will be 0x0100. +// Since there are no wire changes to the protocol from draft 13 through the +// current draft (16), this implementation supports all versions in that range. +static uint16_t kTokenBindingMaxVersion = 16; +static uint16_t kTokenBindingMinVersion = 13; + +static bool ext_token_binding_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) { + SSL *const ssl = hs->ssl; + if (ssl->token_binding_params == nullptr || SSL_is_dtls(ssl)) { + return true; + } + + CBB contents, params; + if (!CBB_add_u16(out, TLSEXT_TYPE_token_binding) || + !CBB_add_u16_length_prefixed(out, &contents) || + !CBB_add_u16(&contents, kTokenBindingMaxVersion) || + !CBB_add_u8_length_prefixed(&contents, ¶ms) || + !CBB_add_bytes(¶ms, ssl->token_binding_params, + ssl->token_binding_params_len) || + !CBB_flush(out)) { + return false; + } + + return true; +} + +static bool ext_token_binding_parse_serverhello(SSL_HANDSHAKE *hs, + uint8_t *out_alert, + CBS *contents) { + SSL *const ssl = hs->ssl; + if (contents == nullptr) { + return true; + } + + CBS params_list; + uint16_t version; + uint8_t param; + if (!CBS_get_u16(contents, &version) || + !CBS_get_u8_length_prefixed(contents, ¶ms_list) || + !CBS_get_u8(¶ms_list, ¶m) || + CBS_len(¶ms_list) > 0 || + CBS_len(contents) > 0) { + *out_alert = SSL_AD_DECODE_ERROR; + return false; + } + + // The server-negotiated version must be less than or equal to our version. + if (version > kTokenBindingMaxVersion) { + *out_alert = SSL_AD_ILLEGAL_PARAMETER; + return false; + } + + // If the server-selected version is less than what we support, then Token + // Binding wasn't negotiated (but the extension was parsed successfully). + if (version < kTokenBindingMinVersion) { + return true; + } + + for (size_t i = 0; i < ssl->token_binding_params_len; ++i) { + if (param == ssl->token_binding_params[i]) { + ssl->negotiated_token_binding_param = param; + ssl->token_binding_negotiated = true; + return true; + } + } + + *out_alert = SSL_AD_ILLEGAL_PARAMETER; + return false; +} + +// select_tb_param looks for the first token binding param in +// |ssl->token_binding_params| that is also in |params| and puts it in +// |ssl->negotiated_token_binding_param|. It returns true if a token binding +// param is found, and false otherwise. +static bool select_tb_param(SSL *ssl, Span peer_params) { + for (size_t i = 0; i < ssl->token_binding_params_len; ++i) { + uint8_t tb_param = ssl->token_binding_params[i]; + for (uint8_t peer_param : peer_params) { + if (tb_param == peer_param) { + ssl->negotiated_token_binding_param = tb_param; + return true; + } + } + } + return false; +} + +static bool ext_token_binding_parse_clienthello(SSL_HANDSHAKE *hs, + uint8_t *out_alert, + CBS *contents) { + SSL *const ssl = hs->ssl; + if (contents == nullptr || ssl->token_binding_params == nullptr) { + return true; + } + + CBS params; + uint16_t version; + if (!CBS_get_u16(contents, &version) || + !CBS_get_u8_length_prefixed(contents, ¶ms) || + CBS_len(¶ms) == 0 || + CBS_len(contents) > 0) { + *out_alert = SSL_AD_DECODE_ERROR; + return false; + } + + // If the client-selected version is less than what we support, then Token + // Binding wasn't negotiated (but the extension was parsed successfully). + if (version < kTokenBindingMinVersion) { + return true; + } + + // If the client-selected version is higher than we support, use our max + // version. Otherwise, use the client's version. + hs->negotiated_token_binding_version = + std::min(version, kTokenBindingMaxVersion); + if (!select_tb_param(ssl, params)) { + return true; + } + + ssl->token_binding_negotiated = true; + return true; +} + +static bool ext_token_binding_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) { + SSL *const ssl = hs->ssl; + + if (!ssl->token_binding_negotiated) { + return true; + } + + CBB contents, params; + if (!CBB_add_u16(out, TLSEXT_TYPE_token_binding) || + !CBB_add_u16_length_prefixed(out, &contents) || + !CBB_add_u16(&contents, hs->negotiated_token_binding_version) || + !CBB_add_u8_length_prefixed(&contents, ¶ms) || + !CBB_add_u8(¶ms, ssl->negotiated_token_binding_param) || + !CBB_flush(out)) { + return false; + } + + return true; +} + +// QUIC Transport Parameters + +static bool ext_quic_transport_params_add_clienthello(SSL_HANDSHAKE *hs, + CBB *out) { + SSL *const ssl = hs->ssl; + if (!ssl->quic_transport_params || hs->max_version <= TLS1_2_VERSION) { + return true; + } + + CBB contents; + if (!CBB_add_u16(out, TLSEXT_TYPE_quic_transport_parameters) || + !CBB_add_u16_length_prefixed(out, &contents) || + !CBB_add_bytes(&contents, ssl->quic_transport_params, + ssl->quic_transport_params_len) || + !CBB_flush(out)) { + return false; + } + return true; +} + +static bool ext_quic_transport_params_parse_serverhello(SSL_HANDSHAKE *hs, + uint8_t *out_alert, + CBS *contents) { + SSL *const ssl = hs->ssl; + if (contents == nullptr) { + return true; + } + // QUIC requires TLS 1.3. + if (ssl_protocol_version(ssl) < TLS1_3_VERSION) { + *out_alert = SSL_AD_UNSUPPORTED_EXTENSION; + return false; + } + + return ssl->s3->peer_quic_transport_params.CopyFrom(*contents); +} + +static bool ext_quic_transport_params_parse_clienthello(SSL_HANDSHAKE *hs, + uint8_t *out_alert, + CBS *contents) { + SSL *const ssl = hs->ssl; + if (!contents || !ssl->quic_transport_params) { + return true; + } + // Ignore the extension before TLS 1.3. + if (ssl_protocol_version(ssl) < TLS1_3_VERSION) { + return true; + } + + return ssl->s3->peer_quic_transport_params.CopyFrom(*contents); +} + +static bool ext_quic_transport_params_add_serverhello(SSL_HANDSHAKE *hs, + CBB *out) { + SSL *const ssl = hs->ssl; + if (!ssl->quic_transport_params) { + return true; + } + + CBB contents; + if (!CBB_add_u16(out, TLSEXT_TYPE_quic_transport_parameters) || + !CBB_add_u16_length_prefixed(out, &contents) || + !CBB_add_bytes(&contents, ssl->quic_transport_params, + ssl->quic_transport_params_len) || + !CBB_flush(out)) { + return false; + } + + return true; +} + + +// kExtensions contains all the supported extensions. +static const struct tls_extension kExtensions[] = { + { + TLSEXT_TYPE_renegotiate, + NULL, + ext_ri_add_clienthello, + ext_ri_parse_serverhello, + ext_ri_parse_clienthello, + ext_ri_add_serverhello, + }, + { + TLSEXT_TYPE_server_name, + NULL, + ext_sni_add_clienthello, + ext_sni_parse_serverhello, + ext_sni_parse_clienthello, + ext_sni_add_serverhello, + }, + { + TLSEXT_TYPE_extended_master_secret, + NULL, + ext_ems_add_clienthello, + ext_ems_parse_serverhello, + ext_ems_parse_clienthello, + ext_ems_add_serverhello, + }, + { + TLSEXT_TYPE_session_ticket, + NULL, + ext_ticket_add_clienthello, + ext_ticket_parse_serverhello, + // Ticket extension client parsing is handled in ssl_session.c + ignore_parse_clienthello, + ext_ticket_add_serverhello, + }, + { + TLSEXT_TYPE_signature_algorithms, + NULL, + ext_sigalgs_add_clienthello, + forbid_parse_serverhello, + ext_sigalgs_parse_clienthello, + dont_add_serverhello, + }, + { + TLSEXT_TYPE_status_request, + NULL, + ext_ocsp_add_clienthello, + ext_ocsp_parse_serverhello, + ext_ocsp_parse_clienthello, + ext_ocsp_add_serverhello, + }, + { + TLSEXT_TYPE_next_proto_neg, + NULL, + ext_npn_add_clienthello, + ext_npn_parse_serverhello, + ext_npn_parse_clienthello, + ext_npn_add_serverhello, + }, + { + TLSEXT_TYPE_certificate_timestamp, + NULL, + ext_sct_add_clienthello, + ext_sct_parse_serverhello, + ext_sct_parse_clienthello, + ext_sct_add_serverhello, + }, + { + TLSEXT_TYPE_application_layer_protocol_negotiation, + NULL, + ext_alpn_add_clienthello, + ext_alpn_parse_serverhello, + // ALPN is negotiated late in |ssl_negotiate_alpn|. + ignore_parse_clienthello, + ext_alpn_add_serverhello, + }, + { + TLSEXT_TYPE_channel_id, + ext_channel_id_init, + ext_channel_id_add_clienthello, + ext_channel_id_parse_serverhello, + ext_channel_id_parse_clienthello, + ext_channel_id_add_serverhello, + }, + { + TLSEXT_TYPE_srtp, + ext_srtp_init, + ext_srtp_add_clienthello, + ext_srtp_parse_serverhello, + ext_srtp_parse_clienthello, + ext_srtp_add_serverhello, + }, + { + TLSEXT_TYPE_ec_point_formats, + NULL, + ext_ec_point_add_clienthello, + ext_ec_point_parse_serverhello, + ext_ec_point_parse_clienthello, + ext_ec_point_add_serverhello, + }, + { + TLSEXT_TYPE_key_share, + NULL, + ext_key_share_add_clienthello, + forbid_parse_serverhello, + ignore_parse_clienthello, + dont_add_serverhello, + }, + { + TLSEXT_TYPE_psk_key_exchange_modes, + NULL, + ext_psk_key_exchange_modes_add_clienthello, + forbid_parse_serverhello, + ext_psk_key_exchange_modes_parse_clienthello, + dont_add_serverhello, + }, + { + TLSEXT_TYPE_early_data, + NULL, + ext_early_data_add_clienthello, + ext_early_data_parse_serverhello, + ext_early_data_parse_clienthello, + ext_early_data_add_serverhello, + }, + { + TLSEXT_TYPE_supported_versions, + NULL, + ext_supported_versions_add_clienthello, + forbid_parse_serverhello, + ignore_parse_clienthello, + dont_add_serverhello, + }, + { + TLSEXT_TYPE_cookie, + NULL, + ext_cookie_add_clienthello, + forbid_parse_serverhello, + ignore_parse_clienthello, + dont_add_serverhello, + }, + { + TLSEXT_TYPE_dummy_pq_padding, + NULL, + ext_dummy_pq_padding_add_clienthello, + ext_dummy_pq_padding_parse_serverhello, + ext_dummy_pq_padding_parse_clienthello, + ext_dummy_pq_padding_add_serverhello, + }, + { + TLSEXT_TYPE_quic_transport_parameters, + NULL, + ext_quic_transport_params_add_clienthello, + ext_quic_transport_params_parse_serverhello, + ext_quic_transport_params_parse_clienthello, + ext_quic_transport_params_add_serverhello, + }, + // The final extension must be non-empty. WebSphere Application Server 7.0 is + // intolerant to the last extension being zero-length. See + // https://crbug.com/363583. + { + TLSEXT_TYPE_supported_groups, + NULL, + ext_supported_groups_add_clienthello, + ext_supported_groups_parse_serverhello, + ext_supported_groups_parse_clienthello, + dont_add_serverhello, + }, + { + TLSEXT_TYPE_token_binding, + NULL, + ext_token_binding_add_clienthello, + ext_token_binding_parse_serverhello, + ext_token_binding_parse_clienthello, + ext_token_binding_add_serverhello, + }, +}; + +#define kNumExtensions (sizeof(kExtensions) / sizeof(struct tls_extension)) + +static_assert(kNumExtensions <= + sizeof(((SSL_HANDSHAKE *)NULL)->extensions.sent) * 8, + "too many extensions for sent bitset"); +static_assert(kNumExtensions <= + sizeof(((SSL_HANDSHAKE *)NULL)->extensions.received) * 8, + "too many extensions for received bitset"); + +static const struct tls_extension *tls_extension_find(uint32_t *out_index, + uint16_t value) { + unsigned i; + for (i = 0; i < kNumExtensions; i++) { + if (kExtensions[i].value == value) { + *out_index = i; + return &kExtensions[i]; + } + } + + return NULL; +} + +int ssl_add_clienthello_tlsext(SSL_HANDSHAKE *hs, CBB *out, size_t header_len) { + SSL *const ssl = hs->ssl; + // Don't add extensions for SSLv3 unless doing secure renegotiation. + if (hs->client_version == SSL3_VERSION && + !ssl->s3->send_connection_binding) { + return 1; + } + + CBB extensions; + if (!CBB_add_u16_length_prefixed(out, &extensions)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return 0; + } + + hs->extensions.sent = 0; + hs->custom_extensions.sent = 0; + + for (size_t i = 0; i < kNumExtensions; i++) { + if (kExtensions[i].init != NULL) { + kExtensions[i].init(hs); + } + } + + uint16_t grease_ext1 = 0; + if (ssl->ctx->grease_enabled) { + // Add a fake empty extension. See draft-davidben-tls-grease-01. + grease_ext1 = ssl_get_grease_value(hs, ssl_grease_extension1); + if (!CBB_add_u16(&extensions, grease_ext1) || + !CBB_add_u16(&extensions, 0 /* zero length */)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return 0; + } + } + + for (size_t i = 0; i < kNumExtensions; i++) { + const size_t len_before = CBB_len(&extensions); + if (!kExtensions[i].add_clienthello(hs, &extensions)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_ERROR_ADDING_EXTENSION); + ERR_add_error_dataf("extension %u", (unsigned)kExtensions[i].value); + return 0; + } + + if (CBB_len(&extensions) != len_before) { + hs->extensions.sent |= (1u << i); + } + } + + if (!custom_ext_add_clienthello(hs, &extensions)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return 0; + } + + if (ssl->ctx->grease_enabled) { + // Add a fake non-empty extension. See draft-davidben-tls-grease-01. + uint16_t grease_ext2 = ssl_get_grease_value(hs, ssl_grease_extension2); + + // The two fake extensions must not have the same value. GREASE values are + // of the form 0x1a1a, 0x2a2a, 0x3a3a, etc., so XOR to generate a different + // one. + if (grease_ext1 == grease_ext2) { + grease_ext2 ^= 0x1010; + } + + if (!CBB_add_u16(&extensions, grease_ext2) || + !CBB_add_u16(&extensions, 1 /* one byte length */) || + !CBB_add_u8(&extensions, 0 /* single zero byte as contents */)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return 0; + } + } + + if (!SSL_is_dtls(ssl)) { + size_t psk_extension_len = ext_pre_shared_key_clienthello_length(hs); + header_len += 2 + CBB_len(&extensions) + psk_extension_len; + if (header_len > 0xff && header_len < 0x200) { + // Add padding to workaround bugs in F5 terminators. See RFC 7685. + // + // NB: because this code works out the length of all existing extensions + // it MUST always appear last. + size_t padding_len = 0x200 - header_len; + // Extensions take at least four bytes to encode. Always include at least + // one byte of data if including the extension. WebSphere Application + // Server 7.0 is intolerant to the last extension being zero-length. See + // https://crbug.com/363583. + if (padding_len >= 4 + 1) { + padding_len -= 4; + } else { + padding_len = 1; + } + + uint8_t *padding_bytes; + if (!CBB_add_u16(&extensions, TLSEXT_TYPE_padding) || + !CBB_add_u16(&extensions, padding_len) || + !CBB_add_space(&extensions, &padding_bytes, padding_len)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return 0; + } + + OPENSSL_memset(padding_bytes, 0, padding_len); + } + } + + // The PSK extension must be last, including after the padding. + if (!ext_pre_shared_key_add_clienthello(hs, &extensions)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return 0; + } + + // Discard empty extensions blocks. + if (CBB_len(&extensions) == 0) { + CBB_discard_child(out); + } + + return CBB_flush(out); +} + +int ssl_add_serverhello_tlsext(SSL_HANDSHAKE *hs, CBB *out) { + SSL *const ssl = hs->ssl; + CBB extensions; + if (!CBB_add_u16_length_prefixed(out, &extensions)) { + goto err; + } + + for (unsigned i = 0; i < kNumExtensions; i++) { + if (!(hs->extensions.received & (1u << i))) { + // Don't send extensions that were not received. + continue; + } + + if (!kExtensions[i].add_serverhello(hs, &extensions)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_ERROR_ADDING_EXTENSION); + ERR_add_error_dataf("extension %u", (unsigned)kExtensions[i].value); + goto err; + } + } + + if (!custom_ext_add_serverhello(hs, &extensions)) { + goto err; + } + + // Discard empty extensions blocks before TLS 1.3. + if (ssl_protocol_version(ssl) < TLS1_3_VERSION && + CBB_len(&extensions) == 0) { + CBB_discard_child(out); + } + + return CBB_flush(out); + +err: + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return 0; +} + +static int ssl_scan_clienthello_tlsext(SSL_HANDSHAKE *hs, + const SSL_CLIENT_HELLO *client_hello, + int *out_alert) { + SSL *const ssl = hs->ssl; + for (size_t i = 0; i < kNumExtensions; i++) { + if (kExtensions[i].init != NULL) { + kExtensions[i].init(hs); + } + } + + hs->extensions.received = 0; + hs->custom_extensions.received = 0; + CBS extensions; + CBS_init(&extensions, client_hello->extensions, client_hello->extensions_len); + while (CBS_len(&extensions) != 0) { + uint16_t type; + CBS extension; + + // Decode the next extension. + if (!CBS_get_u16(&extensions, &type) || + !CBS_get_u16_length_prefixed(&extensions, &extension)) { + *out_alert = SSL_AD_DECODE_ERROR; + return 0; + } + + // RFC 5746 made the existence of extensions in SSL 3.0 somewhat + // ambiguous. Ignore all but the renegotiation_info extension. + if (ssl->version == SSL3_VERSION && type != TLSEXT_TYPE_renegotiate) { + continue; + } + + unsigned ext_index; + const struct tls_extension *const ext = + tls_extension_find(&ext_index, type); + + if (ext == NULL) { + if (!custom_ext_parse_clienthello(hs, out_alert, type, &extension)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_ERROR_PARSING_EXTENSION); + return 0; + } + continue; + } + + hs->extensions.received |= (1u << ext_index); + uint8_t alert = SSL_AD_DECODE_ERROR; + if (!ext->parse_clienthello(hs, &alert, &extension)) { + *out_alert = alert; + OPENSSL_PUT_ERROR(SSL, SSL_R_ERROR_PARSING_EXTENSION); + ERR_add_error_dataf("extension %u", (unsigned)type); + return 0; + } + } + + for (size_t i = 0; i < kNumExtensions; i++) { + if (hs->extensions.received & (1u << i)) { + continue; + } + + CBS *contents = NULL, fake_contents; + static const uint8_t kFakeRenegotiateExtension[] = {0}; + if (kExtensions[i].value == TLSEXT_TYPE_renegotiate && + ssl_client_cipher_list_contains_cipher(client_hello, + SSL3_CK_SCSV & 0xffff)) { + // The renegotiation SCSV was received so pretend that we received a + // renegotiation extension. + CBS_init(&fake_contents, kFakeRenegotiateExtension, + sizeof(kFakeRenegotiateExtension)); + contents = &fake_contents; + hs->extensions.received |= (1u << i); + } + + // Extension wasn't observed so call the callback with a NULL + // parameter. + uint8_t alert = SSL_AD_DECODE_ERROR; + if (!kExtensions[i].parse_clienthello(hs, &alert, contents)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_MISSING_EXTENSION); + ERR_add_error_dataf("extension %u", (unsigned)kExtensions[i].value); + *out_alert = alert; + return 0; + } + } + + return 1; +} + +int ssl_parse_clienthello_tlsext(SSL_HANDSHAKE *hs, + const SSL_CLIENT_HELLO *client_hello) { + SSL *const ssl = hs->ssl; + int alert = SSL_AD_DECODE_ERROR; + if (ssl_scan_clienthello_tlsext(hs, client_hello, &alert) <= 0) { + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + return 0; + } + + if (ssl_check_clienthello_tlsext(hs) <= 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_CLIENTHELLO_TLSEXT); + return 0; + } + + return 1; +} + +static int ssl_scan_serverhello_tlsext(SSL_HANDSHAKE *hs, CBS *cbs, + int *out_alert) { + SSL *const ssl = hs->ssl; + // Before TLS 1.3, ServerHello extensions blocks may be omitted if empty. + if (CBS_len(cbs) == 0 && ssl_protocol_version(ssl) < TLS1_3_VERSION) { + return 1; + } + + // Decode the extensions block and check it is valid. + CBS extensions; + if (!CBS_get_u16_length_prefixed(cbs, &extensions) || + !tls1_check_duplicate_extensions(&extensions)) { + *out_alert = SSL_AD_DECODE_ERROR; + return 0; + } + + uint32_t received = 0; + while (CBS_len(&extensions) != 0) { + uint16_t type; + CBS extension; + + // Decode the next extension. + if (!CBS_get_u16(&extensions, &type) || + !CBS_get_u16_length_prefixed(&extensions, &extension)) { + *out_alert = SSL_AD_DECODE_ERROR; + return 0; + } + + unsigned ext_index; + const struct tls_extension *const ext = + tls_extension_find(&ext_index, type); + + if (ext == NULL) { + hs->received_custom_extension = true; + if (!custom_ext_parse_serverhello(hs, out_alert, type, &extension)) { + return 0; + } + continue; + } + + static_assert(kNumExtensions <= sizeof(hs->extensions.sent) * 8, + "too many bits"); + + if (!(hs->extensions.sent & (1u << ext_index)) && + type != TLSEXT_TYPE_renegotiate) { + // If the extension was never sent then it is illegal, except for the + // renegotiation extension which, in SSL 3.0, is signaled via SCSV. + OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION); + ERR_add_error_dataf("extension :%u", (unsigned)type); + *out_alert = SSL_AD_UNSUPPORTED_EXTENSION; + return 0; + } + + received |= (1u << ext_index); + + uint8_t alert = SSL_AD_DECODE_ERROR; + if (!ext->parse_serverhello(hs, &alert, &extension)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_ERROR_PARSING_EXTENSION); + ERR_add_error_dataf("extension %u", (unsigned)type); + *out_alert = alert; + return 0; + } + } + + for (size_t i = 0; i < kNumExtensions; i++) { + if (!(received & (1u << i))) { + // Extension wasn't observed so call the callback with a NULL + // parameter. + uint8_t alert = SSL_AD_DECODE_ERROR; + if (!kExtensions[i].parse_serverhello(hs, &alert, NULL)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_MISSING_EXTENSION); + ERR_add_error_dataf("extension %u", (unsigned)kExtensions[i].value); + *out_alert = alert; + return 0; + } + } + } + + return 1; +} + +static int ssl_check_clienthello_tlsext(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + + if (ssl->token_binding_negotiated && + !(SSL_get_secure_renegotiation_support(ssl) && + SSL_get_extms_support(ssl))) { + OPENSSL_PUT_ERROR(SSL, SSL_R_NEGOTIATED_TB_WITHOUT_EMS_OR_RI); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNSUPPORTED_EXTENSION); + return -1; + } + + int ret = SSL_TLSEXT_ERR_NOACK; + int al = SSL_AD_UNRECOGNIZED_NAME; + + if (ssl->ctx->tlsext_servername_callback != 0) { + ret = ssl->ctx->tlsext_servername_callback(ssl, &al, + ssl->ctx->tlsext_servername_arg); + } else if (ssl->session_ctx->tlsext_servername_callback != 0) { + ret = ssl->session_ctx->tlsext_servername_callback( + ssl, &al, ssl->session_ctx->tlsext_servername_arg); + } + + switch (ret) { + case SSL_TLSEXT_ERR_ALERT_FATAL: + ssl_send_alert(ssl, SSL3_AL_FATAL, al); + return -1; + + case SSL_TLSEXT_ERR_NOACK: + hs->should_ack_sni = false; + return 1; + + default: + return 1; + } +} + +int ssl_parse_serverhello_tlsext(SSL_HANDSHAKE *hs, CBS *cbs) { + SSL *const ssl = hs->ssl; + int alert = SSL_AD_DECODE_ERROR; + if (ssl_scan_serverhello_tlsext(hs, cbs, &alert) <= 0) { + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + return 0; + } + + return 1; +} + +static enum ssl_ticket_aead_result_t decrypt_ticket_with_cipher_ctx( + uint8_t **out, size_t *out_len, EVP_CIPHER_CTX *cipher_ctx, + HMAC_CTX *hmac_ctx, const uint8_t *ticket, size_t ticket_len) { + size_t iv_len = EVP_CIPHER_CTX_iv_length(cipher_ctx); + + // Check the MAC at the end of the ticket. + uint8_t mac[EVP_MAX_MD_SIZE]; + size_t mac_len = HMAC_size(hmac_ctx); + if (ticket_len < SSL_TICKET_KEY_NAME_LEN + iv_len + 1 + mac_len) { + // The ticket must be large enough for key name, IV, data, and MAC. + return ssl_ticket_aead_ignore_ticket; + } + HMAC_Update(hmac_ctx, ticket, ticket_len - mac_len); + HMAC_Final(hmac_ctx, mac, NULL); + int mac_ok = + CRYPTO_memcmp(mac, ticket + (ticket_len - mac_len), mac_len) == 0; +#if defined(BORINGSSL_UNSAFE_FUZZER_MODE) + mac_ok = 1; +#endif + if (!mac_ok) { + return ssl_ticket_aead_ignore_ticket; + } + + // Decrypt the session data. + const uint8_t *ciphertext = ticket + SSL_TICKET_KEY_NAME_LEN + iv_len; + size_t ciphertext_len = ticket_len - SSL_TICKET_KEY_NAME_LEN - iv_len - + mac_len; + UniquePtr plaintext((uint8_t *)OPENSSL_malloc(ciphertext_len)); + if (!plaintext) { + return ssl_ticket_aead_error; + } + size_t plaintext_len; +#if defined(BORINGSSL_UNSAFE_FUZZER_MODE) + OPENSSL_memcpy(plaintext.get(), ciphertext, ciphertext_len); + plaintext_len = ciphertext_len; +#else + if (ciphertext_len >= INT_MAX) { + return ssl_ticket_aead_ignore_ticket; + } + int len1, len2; + if (!EVP_DecryptUpdate(cipher_ctx, plaintext.get(), &len1, ciphertext, + (int)ciphertext_len) || + !EVP_DecryptFinal_ex(cipher_ctx, plaintext.get() + len1, &len2)) { + ERR_clear_error(); + return ssl_ticket_aead_ignore_ticket; + } + plaintext_len = (size_t)(len1) + len2; +#endif + + *out = plaintext.release(); + *out_len = plaintext_len; + return ssl_ticket_aead_success; +} + +static enum ssl_ticket_aead_result_t ssl_decrypt_ticket_with_cb( + SSL *ssl, uint8_t **out, size_t *out_len, bool *out_renew_ticket, + const uint8_t *ticket, size_t ticket_len) { + assert(ticket_len >= SSL_TICKET_KEY_NAME_LEN + EVP_MAX_IV_LENGTH); + ScopedEVP_CIPHER_CTX cipher_ctx; + ScopedHMAC_CTX hmac_ctx; + const uint8_t *iv = ticket + SSL_TICKET_KEY_NAME_LEN; + int cb_ret = ssl->session_ctx->tlsext_ticket_key_cb( + ssl, (uint8_t *)ticket /* name */, (uint8_t *)iv, cipher_ctx.get(), + hmac_ctx.get(), 0 /* decrypt */); + if (cb_ret < 0) { + return ssl_ticket_aead_error; + } else if (cb_ret == 0) { + return ssl_ticket_aead_ignore_ticket; + } else if (cb_ret == 2) { + *out_renew_ticket = true; + } else { + assert(cb_ret == 1); + } + return decrypt_ticket_with_cipher_ctx(out, out_len, cipher_ctx.get(), + hmac_ctx.get(), ticket, ticket_len); +} + +static enum ssl_ticket_aead_result_t ssl_decrypt_ticket_with_ticket_keys( + SSL *ssl, uint8_t **out, size_t *out_len, const uint8_t *ticket, + size_t ticket_len) { + assert(ticket_len >= SSL_TICKET_KEY_NAME_LEN + EVP_MAX_IV_LENGTH); + SSL_CTX *ctx = ssl->session_ctx; + + // Rotate the ticket key if necessary. + if (!ssl_ctx_rotate_ticket_encryption_key(ctx)) { + return ssl_ticket_aead_error; + } + + // Pick the matching ticket key and decrypt. + ScopedEVP_CIPHER_CTX cipher_ctx; + ScopedHMAC_CTX hmac_ctx; + { + MutexReadLock lock(&ctx->lock); + const tlsext_ticket_key *key; + if (ctx->tlsext_ticket_key_current && + !OPENSSL_memcmp(ctx->tlsext_ticket_key_current->name, ticket, + SSL_TICKET_KEY_NAME_LEN)) { + key = ctx->tlsext_ticket_key_current; + } else if (ctx->tlsext_ticket_key_prev && + !OPENSSL_memcmp(ctx->tlsext_ticket_key_prev->name, ticket, + SSL_TICKET_KEY_NAME_LEN)) { + key = ctx->tlsext_ticket_key_prev; + } else { + return ssl_ticket_aead_ignore_ticket; + } + const uint8_t *iv = ticket + SSL_TICKET_KEY_NAME_LEN; + if (!HMAC_Init_ex(hmac_ctx.get(), key->hmac_key, sizeof(key->hmac_key), + tlsext_tick_md(), NULL) || + !EVP_DecryptInit_ex(cipher_ctx.get(), EVP_aes_128_cbc(), NULL, + key->aes_key, iv)) { + return ssl_ticket_aead_error; + } + } + return decrypt_ticket_with_cipher_ctx(out, out_len, cipher_ctx.get(), + hmac_ctx.get(), ticket, ticket_len); +} + +static enum ssl_ticket_aead_result_t ssl_decrypt_ticket_with_method( + SSL *ssl, uint8_t **out, size_t *out_len, bool *out_renew_ticket, + const uint8_t *ticket, size_t ticket_len) { + uint8_t *plaintext = (uint8_t *)OPENSSL_malloc(ticket_len); + if (plaintext == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return ssl_ticket_aead_error; + } + + size_t plaintext_len; + const enum ssl_ticket_aead_result_t result = + ssl->session_ctx->ticket_aead_method->open( + ssl, plaintext, &plaintext_len, ticket_len, ticket, ticket_len); + + if (result == ssl_ticket_aead_success) { + *out = plaintext; + plaintext = NULL; + *out_len = plaintext_len; + } + + OPENSSL_free(plaintext); + return result; +} + +enum ssl_ticket_aead_result_t ssl_process_ticket( + SSL *ssl, UniquePtr *out_session, bool *out_renew_ticket, + const uint8_t *ticket, size_t ticket_len, const uint8_t *session_id, + size_t session_id_len) { + *out_renew_ticket = false; + out_session->reset(); + + if ((SSL_get_options(ssl) & SSL_OP_NO_TICKET) || + session_id_len > SSL_MAX_SSL_SESSION_ID_LENGTH) { + return ssl_ticket_aead_ignore_ticket; + } + + uint8_t *plaintext = NULL; + size_t plaintext_len; + enum ssl_ticket_aead_result_t result; + if (ssl->session_ctx->ticket_aead_method != NULL) { + result = ssl_decrypt_ticket_with_method( + ssl, &plaintext, &plaintext_len, out_renew_ticket, ticket, ticket_len); + } else { + // Ensure there is room for the key name and the largest IV + // |tlsext_ticket_key_cb| may try to consume. The real limit may be lower, + // but the maximum IV length should be well under the minimum size for the + // session material and HMAC. + if (ticket_len < SSL_TICKET_KEY_NAME_LEN + EVP_MAX_IV_LENGTH) { + return ssl_ticket_aead_ignore_ticket; + } + if (ssl->session_ctx->tlsext_ticket_key_cb != NULL) { + result = ssl_decrypt_ticket_with_cb(ssl, &plaintext, &plaintext_len, + out_renew_ticket, ticket, ticket_len); + } else { + result = ssl_decrypt_ticket_with_ticket_keys( + ssl, &plaintext, &plaintext_len, ticket, ticket_len); + } + } + + if (result != ssl_ticket_aead_success) { + return result; + } + + // Decode the session. + UniquePtr session( + SSL_SESSION_from_bytes(plaintext, plaintext_len, ssl->ctx)); + OPENSSL_free(plaintext); + + if (!session) { + ERR_clear_error(); // Don't leave an error on the queue. + return ssl_ticket_aead_ignore_ticket; + } + + // Copy the client's session ID into the new session, to denote the ticket has + // been accepted. + OPENSSL_memcpy(session->session_id, session_id, session_id_len); + session->session_id_length = session_id_len; + + *out_session = std::move(session); + return ssl_ticket_aead_success; +} + +bool tls1_parse_peer_sigalgs(SSL_HANDSHAKE *hs, const CBS *in_sigalgs) { + // Extension ignored for inappropriate versions + if (ssl_protocol_version(hs->ssl) < TLS1_2_VERSION) { + return true; + } + + return parse_u16_array(in_sigalgs, &hs->peer_sigalgs); +} + +bool tls1_get_legacy_signature_algorithm(uint16_t *out, const EVP_PKEY *pkey) { + switch (EVP_PKEY_id(pkey)) { + case EVP_PKEY_RSA: + *out = SSL_SIGN_RSA_PKCS1_MD5_SHA1; + return true; + case EVP_PKEY_EC: + *out = SSL_SIGN_ECDSA_SHA1; + return true; + default: + return false; + } +} + +bool tls1_choose_signature_algorithm(SSL_HANDSHAKE *hs, uint16_t *out) { + SSL *const ssl = hs->ssl; + CERT *cert = ssl->cert; + + // Before TLS 1.2, the signature algorithm isn't negotiated as part of the + // handshake. + if (ssl_protocol_version(ssl) < TLS1_2_VERSION) { + if (!tls1_get_legacy_signature_algorithm(out, hs->local_pubkey.get())) { + OPENSSL_PUT_ERROR(SSL, SSL_R_NO_COMMON_SIGNATURE_ALGORITHMS); + return false; + } + return true; + } + + Span sigalgs = kSignSignatureAlgorithms; + if (cert->sigalgs != nullptr) { + sigalgs = MakeConstSpan(cert->sigalgs, cert->num_sigalgs); + } + + Span peer_sigalgs = hs->peer_sigalgs; + if (peer_sigalgs.empty() && ssl_protocol_version(ssl) < TLS1_3_VERSION) { + // If the client didn't specify any signature_algorithms extension then + // we can assume that it supports SHA1. See + // http://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 + static const uint16_t kDefaultPeerAlgorithms[] = {SSL_SIGN_RSA_PKCS1_SHA1, + SSL_SIGN_ECDSA_SHA1}; + peer_sigalgs = kDefaultPeerAlgorithms; + } + + for (uint16_t sigalg : sigalgs) { + // SSL_SIGN_RSA_PKCS1_MD5_SHA1 is an internal value and should never be + // negotiated. + if (sigalg == SSL_SIGN_RSA_PKCS1_MD5_SHA1 || + !ssl_private_key_supports_signature_algorithm(hs, sigalg)) { + continue; + } + + for (uint16_t peer_sigalg : peer_sigalgs) { + if (sigalg == peer_sigalg) { + *out = sigalg; + return true; + } + } + } + + OPENSSL_PUT_ERROR(SSL, SSL_R_NO_COMMON_SIGNATURE_ALGORITHMS); + return false; +} + +int tls1_verify_channel_id(SSL_HANDSHAKE *hs, const SSLMessage &msg) { + SSL *const ssl = hs->ssl; + // A Channel ID handshake message is structured to contain multiple + // extensions, but the only one that can be present is Channel ID. + uint16_t extension_type; + CBS channel_id = msg.body, extension; + if (!CBS_get_u16(&channel_id, &extension_type) || + !CBS_get_u16_length_prefixed(&channel_id, &extension) || + CBS_len(&channel_id) != 0 || + extension_type != TLSEXT_TYPE_channel_id || + CBS_len(&extension) != TLSEXT_CHANNEL_ID_SIZE) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return 0; + } + + UniquePtr p256(EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1)); + if (!p256) { + OPENSSL_PUT_ERROR(SSL, SSL_R_NO_P256_SUPPORT); + return 0; + } + + UniquePtr sig(ECDSA_SIG_new()); + UniquePtr x(BN_new()), y(BN_new()); + if (!sig || !x || !y) { + return 0; + } + + const uint8_t *p = CBS_data(&extension); + if (BN_bin2bn(p + 0, 32, x.get()) == NULL || + BN_bin2bn(p + 32, 32, y.get()) == NULL || + BN_bin2bn(p + 64, 32, sig->r) == NULL || + BN_bin2bn(p + 96, 32, sig->s) == NULL) { + return 0; + } + + UniquePtr key(EC_KEY_new()); + UniquePtr point(EC_POINT_new(p256.get())); + if (!key || !point || + !EC_POINT_set_affine_coordinates_GFp(p256.get(), point.get(), x.get(), + y.get(), nullptr) || + !EC_KEY_set_group(key.get(), p256.get()) || + !EC_KEY_set_public_key(key.get(), point.get())) { + return 0; + } + + uint8_t digest[EVP_MAX_MD_SIZE]; + size_t digest_len; + if (!tls1_channel_id_hash(hs, digest, &digest_len)) { + return 0; + } + + int sig_ok = ECDSA_do_verify(digest, digest_len, sig.get(), key.get()); +#if defined(BORINGSSL_UNSAFE_FUZZER_MODE) + sig_ok = 1; + ERR_clear_error(); +#endif + if (!sig_ok) { + OPENSSL_PUT_ERROR(SSL, SSL_R_CHANNEL_ID_SIGNATURE_INVALID); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECRYPT_ERROR); + ssl->s3->tlsext_channel_id_valid = false; + return 0; + } + + OPENSSL_memcpy(ssl->s3->tlsext_channel_id, p, 64); + return 1; +} + +bool tls1_write_channel_id(SSL_HANDSHAKE *hs, CBB *cbb) { + SSL *const ssl = hs->ssl; + uint8_t digest[EVP_MAX_MD_SIZE]; + size_t digest_len; + if (!tls1_channel_id_hash(hs, digest, &digest_len)) { + return false; + } + + EC_KEY *ec_key = EVP_PKEY_get0_EC_KEY(ssl->tlsext_channel_id_private); + if (ec_key == nullptr) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return false; + } + + UniquePtr x(BN_new()), y(BN_new()); + if (!x || !y || + !EC_POINT_get_affine_coordinates_GFp(EC_KEY_get0_group(ec_key), + EC_KEY_get0_public_key(ec_key), + x.get(), y.get(), nullptr)) { + return false; + } + + UniquePtr sig(ECDSA_do_sign(digest, digest_len, ec_key)); + if (!sig) { + return false; + } + + CBB child; + if (!CBB_add_u16(cbb, TLSEXT_TYPE_channel_id) || + !CBB_add_u16_length_prefixed(cbb, &child) || + !BN_bn2cbb_padded(&child, 32, x.get()) || + !BN_bn2cbb_padded(&child, 32, y.get()) || + !BN_bn2cbb_padded(&child, 32, sig->r) || + !BN_bn2cbb_padded(&child, 32, sig->s) || + !CBB_flush(cbb)) { + return false; + } + + return true; +} + +int tls1_channel_id_hash(SSL_HANDSHAKE *hs, uint8_t *out, size_t *out_len) { + SSL *const ssl = hs->ssl; + if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) { + Array msg; + if (!tls13_get_cert_verify_signature_input(hs, &msg, + ssl_cert_verify_channel_id)) { + return 0; + } + SHA256(msg.data(), msg.size(), out); + *out_len = SHA256_DIGEST_LENGTH; + return 1; + } + + SHA256_CTX ctx; + + SHA256_Init(&ctx); + static const char kClientIDMagic[] = "TLS Channel ID signature"; + SHA256_Update(&ctx, kClientIDMagic, sizeof(kClientIDMagic)); + + if (ssl->session != NULL) { + static const char kResumptionMagic[] = "Resumption"; + SHA256_Update(&ctx, kResumptionMagic, sizeof(kResumptionMagic)); + if (ssl->session->original_handshake_hash_len == 0) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return 0; + } + SHA256_Update(&ctx, ssl->session->original_handshake_hash, + ssl->session->original_handshake_hash_len); + } + + uint8_t hs_hash[EVP_MAX_MD_SIZE]; + size_t hs_hash_len; + if (!hs->transcript.GetHash(hs_hash, &hs_hash_len)) { + return 0; + } + SHA256_Update(&ctx, hs_hash, (size_t)hs_hash_len); + SHA256_Final(out, &ctx); + *out_len = SHA256_DIGEST_LENGTH; + return 1; +} + +// tls1_record_handshake_hashes_for_channel_id records the current handshake +// hashes in |hs->new_session| so that Channel ID resumptions can sign that +// data. +int tls1_record_handshake_hashes_for_channel_id(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + // This function should never be called for a resumed session because the + // handshake hashes that we wish to record are for the original, full + // handshake. + if (ssl->session != NULL) { + return 0; + } + + static_assert( + sizeof(hs->new_session->original_handshake_hash) == EVP_MAX_MD_SIZE, + "original_handshake_hash is too small"); + + size_t digest_len; + if (!hs->transcript.GetHash(hs->new_session->original_handshake_hash, + &digest_len)) { + return 0; + } + + static_assert(EVP_MAX_MD_SIZE <= 0xff, + "EVP_MAX_MD_SIZE does not fit in uint8_t"); + hs->new_session->original_handshake_hash_len = (uint8_t)digest_len; + + return 1; +} + +int ssl_do_channel_id_callback(SSL *ssl) { + if (ssl->tlsext_channel_id_private != NULL || + ssl->ctx->channel_id_cb == NULL) { + return 1; + } + + EVP_PKEY *key = NULL; + ssl->ctx->channel_id_cb(ssl, &key); + if (key == NULL) { + // The caller should try again later. + return 1; + } + + int ret = SSL_set1_tls_channel_id(ssl, key); + EVP_PKEY_free(key); + return ret; +} + +int ssl_is_sct_list_valid(const CBS *contents) { + // Shallow parse the SCT list for sanity. By the RFC + // (https://tools.ietf.org/html/rfc6962#section-3.3) neither the list nor any + // of the SCTs may be empty. + CBS copy = *contents; + CBS sct_list; + if (!CBS_get_u16_length_prefixed(©, &sct_list) || + CBS_len(©) != 0 || + CBS_len(&sct_list) == 0) { + return 0; + } + + while (CBS_len(&sct_list) > 0) { + CBS sct; + if (!CBS_get_u16_length_prefixed(&sct_list, &sct) || + CBS_len(&sct) == 0) { + return 0; + } + } + + return 1; +} + +} // namespace bssl + +using namespace bssl; + +int SSL_early_callback_ctx_extension_get(const SSL_CLIENT_HELLO *client_hello, + uint16_t extension_type, + const uint8_t **out_data, + size_t *out_len) { + CBS cbs; + if (!ssl_client_hello_get_extension(client_hello, &cbs, extension_type)) { + return 0; + } + + *out_data = CBS_data(&cbs); + *out_len = CBS_len(&cbs); + return 1; +} + +void SSL_CTX_set_ed25519_enabled(SSL_CTX *ctx, int enabled) { + ctx->ed25519_enabled = !!enabled; +} + +int SSL_extension_supported(unsigned extension_value) { + uint32_t index; + return extension_value == TLSEXT_TYPE_padding || + tls_extension_find(&index, extension_value) != NULL; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/ssl/t1_lib.cc.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/ssl/t1_lib.cc.grpc_back new file mode 100644 index 0000000..97c0c4b --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/ssl/t1_lib.cc.grpc_back @@ -0,0 +1,3783 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 + +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "internal.h" +#include "../crypto/internal.h" + + +namespace bssl { + +static int ssl_check_clienthello_tlsext(SSL_HANDSHAKE *hs); + +static int compare_uint16_t(const void *p1, const void *p2) { + uint16_t u1 = *((const uint16_t *)p1); + uint16_t u2 = *((const uint16_t *)p2); + if (u1 < u2) { + return -1; + } else if (u1 > u2) { + return 1; + } else { + return 0; + } +} + +// Per http://tools.ietf.org/html/rfc5246#section-7.4.1.4, there may not be +// more than one extension of the same type in a ClientHello or ServerHello. +// This function does an initial scan over the extensions block to filter those +// out. +static int tls1_check_duplicate_extensions(const CBS *cbs) { + // First pass: count the extensions. + size_t num_extensions = 0; + CBS extensions = *cbs; + while (CBS_len(&extensions) > 0) { + uint16_t type; + CBS extension; + + if (!CBS_get_u16(&extensions, &type) || + !CBS_get_u16_length_prefixed(&extensions, &extension)) { + return 0; + } + + num_extensions++; + } + + if (num_extensions == 0) { + return 1; + } + + Array extension_types; + if (!extension_types.Init(num_extensions)) { + return 0; + } + + // Second pass: gather the extension types. + extensions = *cbs; + for (size_t i = 0; i < extension_types.size(); i++) { + CBS extension; + + if (!CBS_get_u16(&extensions, &extension_types[i]) || + !CBS_get_u16_length_prefixed(&extensions, &extension)) { + // This should not happen. + return 0; + } + } + assert(CBS_len(&extensions) == 0); + + // Sort the extensions and make sure there are no duplicates. + qsort(extension_types.data(), extension_types.size(), sizeof(uint16_t), + compare_uint16_t); + for (size_t i = 1; i < num_extensions; i++) { + if (extension_types[i - 1] == extension_types[i]) { + return 0; + } + } + + return 1; +} + +int ssl_client_hello_init(SSL *ssl, SSL_CLIENT_HELLO *out, + const SSLMessage &msg) { + OPENSSL_memset(out, 0, sizeof(*out)); + out->ssl = ssl; + out->client_hello = CBS_data(&msg.body); + out->client_hello_len = CBS_len(&msg.body); + + CBS client_hello, random, session_id; + CBS_init(&client_hello, out->client_hello, out->client_hello_len); + if (!CBS_get_u16(&client_hello, &out->version) || + !CBS_get_bytes(&client_hello, &random, SSL3_RANDOM_SIZE) || + !CBS_get_u8_length_prefixed(&client_hello, &session_id) || + CBS_len(&session_id) > SSL_MAX_SSL_SESSION_ID_LENGTH) { + return 0; + } + + out->random = CBS_data(&random); + out->random_len = CBS_len(&random); + out->session_id = CBS_data(&session_id); + out->session_id_len = CBS_len(&session_id); + + // Skip past DTLS cookie + if (SSL_is_dtls(out->ssl)) { + CBS cookie; + if (!CBS_get_u8_length_prefixed(&client_hello, &cookie) || + CBS_len(&cookie) > DTLS1_COOKIE_LENGTH) { + return 0; + } + } + + CBS cipher_suites, compression_methods; + if (!CBS_get_u16_length_prefixed(&client_hello, &cipher_suites) || + CBS_len(&cipher_suites) < 2 || (CBS_len(&cipher_suites) & 1) != 0 || + !CBS_get_u8_length_prefixed(&client_hello, &compression_methods) || + CBS_len(&compression_methods) < 1) { + return 0; + } + + out->cipher_suites = CBS_data(&cipher_suites); + out->cipher_suites_len = CBS_len(&cipher_suites); + out->compression_methods = CBS_data(&compression_methods); + out->compression_methods_len = CBS_len(&compression_methods); + + // If the ClientHello ends here then it's valid, but doesn't have any + // extensions. (E.g. SSLv3.) + if (CBS_len(&client_hello) == 0) { + out->extensions = NULL; + out->extensions_len = 0; + return 1; + } + + // Extract extensions and check it is valid. + CBS extensions; + if (!CBS_get_u16_length_prefixed(&client_hello, &extensions) || + !tls1_check_duplicate_extensions(&extensions) || + CBS_len(&client_hello) != 0) { + return 0; + } + + out->extensions = CBS_data(&extensions); + out->extensions_len = CBS_len(&extensions); + + return 1; +} + +int ssl_client_hello_get_extension(const SSL_CLIENT_HELLO *client_hello, + CBS *out, uint16_t extension_type) { + CBS extensions; + CBS_init(&extensions, client_hello->extensions, client_hello->extensions_len); + while (CBS_len(&extensions) != 0) { + // Decode the next extension. + uint16_t type; + CBS extension; + if (!CBS_get_u16(&extensions, &type) || + !CBS_get_u16_length_prefixed(&extensions, &extension)) { + return 0; + } + + if (type == extension_type) { + *out = extension; + return 1; + } + } + + return 0; +} + +static const uint16_t kDefaultGroups[] = { + SSL_CURVE_X25519, + SSL_CURVE_SECP256R1, + SSL_CURVE_SECP384R1, +}; + +Span tls1_get_grouplist(const SSL *ssl) { + if (ssl->supported_group_list != nullptr) { + return MakeConstSpan(ssl->supported_group_list, + ssl->supported_group_list_len); + } + return Span(kDefaultGroups); +} + +int tls1_get_shared_group(SSL_HANDSHAKE *hs, uint16_t *out_group_id) { + SSL *const ssl = hs->ssl; + assert(ssl->server); + + // Clients are not required to send a supported_groups extension. In this + // case, the server is free to pick any group it likes. See RFC 4492, + // section 4, paragraph 3. + // + // However, in the interests of compatibility, we will skip ECDH if the + // client didn't send an extension because we can't be sure that they'll + // support our favoured group. Thus we do not special-case an emtpy + // |peer_supported_group_list|. + + Span groups = tls1_get_grouplist(ssl); + Span pref, supp; + if (ssl->options & SSL_OP_CIPHER_SERVER_PREFERENCE) { + pref = groups; + supp = hs->peer_supported_group_list; + } else { + pref = hs->peer_supported_group_list; + supp = groups; + } + + for (uint16_t pref_group : pref) { + for (uint16_t supp_group : supp) { + if (pref_group == supp_group) { + *out_group_id = pref_group; + return 1; + } + } + } + + return 0; +} + +int tls1_set_curves(uint16_t **out_group_ids, size_t *out_group_ids_len, + const int *curves, size_t ncurves) { + uint16_t *group_ids = (uint16_t *)OPENSSL_malloc(ncurves * sizeof(uint16_t)); + if (group_ids == NULL) { + return 0; + } + + for (size_t i = 0; i < ncurves; i++) { + if (!ssl_nid_to_group_id(&group_ids[i], curves[i])) { + OPENSSL_free(group_ids); + return 0; + } + } + + OPENSSL_free(*out_group_ids); + *out_group_ids = group_ids; + *out_group_ids_len = ncurves; + + return 1; +} + +int tls1_set_curves_list(uint16_t **out_group_ids, size_t *out_group_ids_len, + const char *curves) { + uint16_t *group_ids = NULL; + size_t ncurves = 0; + + const char *col; + const char *ptr = curves; + + do { + col = strchr(ptr, ':'); + + uint16_t group_id; + if (!ssl_name_to_group_id(&group_id, ptr, + col ? (size_t)(col - ptr) : strlen(ptr))) { + goto err; + } + + uint16_t *new_group_ids = (uint16_t *)OPENSSL_realloc( + group_ids, (ncurves + 1) * sizeof(uint16_t)); + if (new_group_ids == NULL) { + goto err; + } + group_ids = new_group_ids; + + group_ids[ncurves] = group_id; + ncurves++; + + if (col) { + ptr = col + 1; + } + } while (col); + + OPENSSL_free(*out_group_ids); + *out_group_ids = group_ids; + *out_group_ids_len = ncurves; + + return 1; + +err: + OPENSSL_free(group_ids); + return 0; +} + +int tls1_check_group_id(const SSL *ssl, uint16_t group_id) { + for (uint16_t supported : tls1_get_grouplist(ssl)) { + if (supported == group_id) { + return 1; + } + } + + return 0; +} + +// kVerifySignatureAlgorithms is the default list of accepted signature +// algorithms for verifying. +// +// For now, RSA-PSS signature algorithms are not enabled on Android's system +// BoringSSL. Once the change in Chrome has stuck and the values are finalized, +// restore them. +static const uint16_t kVerifySignatureAlgorithms[] = { + // List our preferred algorithms first. + SSL_SIGN_ED25519, + SSL_SIGN_ECDSA_SECP256R1_SHA256, + SSL_SIGN_RSA_PSS_SHA256, + SSL_SIGN_RSA_PKCS1_SHA256, + + // Larger hashes are acceptable. + SSL_SIGN_ECDSA_SECP384R1_SHA384, + SSL_SIGN_RSA_PSS_SHA384, + SSL_SIGN_RSA_PKCS1_SHA384, + + SSL_SIGN_RSA_PSS_SHA512, + SSL_SIGN_RSA_PKCS1_SHA512, + + // For now, SHA-1 is still accepted but least preferable. + SSL_SIGN_RSA_PKCS1_SHA1, + +}; + +// kSignSignatureAlgorithms is the default list of supported signature +// algorithms for signing. +// +// For now, RSA-PSS signature algorithms are not enabled on Android's system +// BoringSSL. Once the change in Chrome has stuck and the values are finalized, +// restore them. +static const uint16_t kSignSignatureAlgorithms[] = { + // List our preferred algorithms first. + SSL_SIGN_ED25519, + SSL_SIGN_ECDSA_SECP256R1_SHA256, + SSL_SIGN_RSA_PSS_SHA256, + SSL_SIGN_RSA_PKCS1_SHA256, + + // If needed, sign larger hashes. + // + // TODO(davidben): Determine which of these may be pruned. + SSL_SIGN_ECDSA_SECP384R1_SHA384, + SSL_SIGN_RSA_PSS_SHA384, + SSL_SIGN_RSA_PKCS1_SHA384, + + SSL_SIGN_ECDSA_SECP521R1_SHA512, + SSL_SIGN_RSA_PSS_SHA512, + SSL_SIGN_RSA_PKCS1_SHA512, + + // If the peer supports nothing else, sign with SHA-1. + SSL_SIGN_ECDSA_SHA1, + SSL_SIGN_RSA_PKCS1_SHA1, +}; + +bool tls12_add_verify_sigalgs(const SSL *ssl, CBB *out) { + bool use_default = ssl->ctx->num_verify_sigalgs == 0; + Span sigalgs = kVerifySignatureAlgorithms; + if (!use_default) { + sigalgs = MakeConstSpan(ssl->ctx->verify_sigalgs, + ssl->ctx->num_verify_sigalgs); + } + + for (uint16_t sigalg : sigalgs) { + if (use_default && + sigalg == SSL_SIGN_ED25519 && + !ssl->ctx->ed25519_enabled) { + continue; + } + if (!CBB_add_u16(out, sigalg)) { + return false; + } + } + + return true; +} + +bool tls12_check_peer_sigalg(const SSL *ssl, uint8_t *out_alert, + uint16_t sigalg) { + const uint16_t *sigalgs = kVerifySignatureAlgorithms; + size_t num_sigalgs = OPENSSL_ARRAY_SIZE(kVerifySignatureAlgorithms); + if (ssl->ctx->num_verify_sigalgs != 0) { + sigalgs = ssl->ctx->verify_sigalgs; + num_sigalgs = ssl->ctx->num_verify_sigalgs; + } + + for (size_t i = 0; i < num_sigalgs; i++) { + if (sigalgs == kVerifySignatureAlgorithms && + sigalgs[i] == SSL_SIGN_ED25519 && + !ssl->ctx->ed25519_enabled) { + continue; + } + if (sigalg == sigalgs[i]) { + return true; + } + } + + OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_SIGNATURE_TYPE); + *out_alert = SSL_AD_ILLEGAL_PARAMETER; + return false; +} + +// tls_extension represents a TLS extension that is handled internally. The +// |init| function is called for each handshake, before any other functions of +// the extension. Then the add and parse callbacks are called as needed. +// +// The parse callbacks receive a |CBS| that contains the contents of the +// extension (i.e. not including the type and length bytes). If an extension is +// not received then the parse callbacks will be called with a NULL CBS so that +// they can do any processing needed to handle the absence of an extension. +// +// The add callbacks receive a |CBB| to which the extension can be appended but +// the function is responsible for appending the type and length bytes too. +// +// All callbacks return true for success and false for error. If a parse +// function returns zero then a fatal alert with value |*out_alert| will be +// sent. If |*out_alert| isn't set, then a |decode_error| alert will be sent. +struct tls_extension { + uint16_t value; + void (*init)(SSL_HANDSHAKE *hs); + + bool (*add_clienthello)(SSL_HANDSHAKE *hs, CBB *out); + bool (*parse_serverhello)(SSL_HANDSHAKE *hs, uint8_t *out_alert, + CBS *contents); + + bool (*parse_clienthello)(SSL_HANDSHAKE *hs, uint8_t *out_alert, + CBS *contents); + bool (*add_serverhello)(SSL_HANDSHAKE *hs, CBB *out); +}; + +static bool forbid_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert, + CBS *contents) { + if (contents != NULL) { + // Servers MUST NOT send this extension. + *out_alert = SSL_AD_UNSUPPORTED_EXTENSION; + OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION); + return false; + } + + return true; +} + +static bool ignore_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert, + CBS *contents) { + // This extension from the client is handled elsewhere. + return true; +} + +static bool dont_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) { + return true; +} + +// Server name indication (SNI). +// +// https://tools.ietf.org/html/rfc6066#section-3. + +static bool ext_sni_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) { + SSL *const ssl = hs->ssl; + if (ssl->tlsext_hostname == NULL) { + return true; + } + + CBB contents, server_name_list, name; + if (!CBB_add_u16(out, TLSEXT_TYPE_server_name) || + !CBB_add_u16_length_prefixed(out, &contents) || + !CBB_add_u16_length_prefixed(&contents, &server_name_list) || + !CBB_add_u8(&server_name_list, TLSEXT_NAMETYPE_host_name) || + !CBB_add_u16_length_prefixed(&server_name_list, &name) || + !CBB_add_bytes(&name, (const uint8_t *)ssl->tlsext_hostname, + strlen(ssl->tlsext_hostname)) || + !CBB_flush(out)) { + return false; + } + + return true; +} + +static bool ext_sni_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert, + CBS *contents) { + // The server may acknowledge SNI with an empty extension. We check the syntax + // but otherwise ignore this signal. + return contents == NULL || CBS_len(contents) == 0; +} + +static bool ext_sni_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert, + CBS *contents) { + SSL *const ssl = hs->ssl; + if (contents == NULL) { + return true; + } + + CBS server_name_list, host_name; + uint8_t name_type; + if (!CBS_get_u16_length_prefixed(contents, &server_name_list) || + !CBS_get_u8(&server_name_list, &name_type) || + // Although the server_name extension was intended to be extensible to + // new name types and multiple names, OpenSSL 1.0.x had a bug which meant + // different name types will cause an error. Further, RFC 4366 originally + // defined syntax inextensibly. RFC 6066 corrected this mistake, but + // adding new name types is no longer feasible. + // + // Act as if the extensibility does not exist to simplify parsing. + !CBS_get_u16_length_prefixed(&server_name_list, &host_name) || + CBS_len(&server_name_list) != 0 || + CBS_len(contents) != 0) { + return false; + } + + if (name_type != TLSEXT_NAMETYPE_host_name || + CBS_len(&host_name) == 0 || + CBS_len(&host_name) > TLSEXT_MAXLEN_host_name || + CBS_contains_zero_byte(&host_name)) { + *out_alert = SSL_AD_UNRECOGNIZED_NAME; + return false; + } + + // Copy the hostname as a string. + char *raw = nullptr; + if (!CBS_strdup(&host_name, &raw)) { + *out_alert = SSL_AD_INTERNAL_ERROR; + return false; + } + ssl->s3->hostname.reset(raw); + + hs->should_ack_sni = true; + return true; +} + +static bool ext_sni_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) { + if (hs->ssl->s3->session_reused || + !hs->should_ack_sni) { + return true; + } + + if (!CBB_add_u16(out, TLSEXT_TYPE_server_name) || + !CBB_add_u16(out, 0 /* length */)) { + return false; + } + + return true; +} + + +// Renegotiation indication. +// +// https://tools.ietf.org/html/rfc5746 + +static bool ext_ri_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) { + SSL *const ssl = hs->ssl; + // Renegotiation indication is not necessary in TLS 1.3. + if (hs->min_version >= TLS1_3_VERSION) { + return true; + } + + assert(ssl->s3->initial_handshake_complete == + (ssl->s3->previous_client_finished_len != 0)); + + CBB contents, prev_finished; + if (!CBB_add_u16(out, TLSEXT_TYPE_renegotiate) || + !CBB_add_u16_length_prefixed(out, &contents) || + !CBB_add_u8_length_prefixed(&contents, &prev_finished) || + !CBB_add_bytes(&prev_finished, ssl->s3->previous_client_finished, + ssl->s3->previous_client_finished_len) || + !CBB_flush(out)) { + return false; + } + + return true; +} + +static bool ext_ri_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert, + CBS *contents) { + SSL *const ssl = hs->ssl; + if (contents != NULL && ssl_protocol_version(ssl) >= TLS1_3_VERSION) { + *out_alert = SSL_AD_ILLEGAL_PARAMETER; + return false; + } + + // Servers may not switch between omitting the extension and supporting it. + // See RFC 5746, sections 3.5 and 4.2. + if (ssl->s3->initial_handshake_complete && + (contents != NULL) != ssl->s3->send_connection_binding) { + *out_alert = SSL_AD_HANDSHAKE_FAILURE; + OPENSSL_PUT_ERROR(SSL, SSL_R_RENEGOTIATION_MISMATCH); + return false; + } + + if (contents == NULL) { + // Strictly speaking, if we want to avoid an attack we should *always* see + // RI even on initial ServerHello 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. + // + // OpenSSL has |SSL_OP_LEGACY_SERVER_CONNECT| to control this, but in + // practical terms every client sets it so it's just assumed here. + return true; + } + + const size_t expected_len = ssl->s3->previous_client_finished_len + + ssl->s3->previous_server_finished_len; + + // Check for logic errors + assert(!expected_len || ssl->s3->previous_client_finished_len); + assert(!expected_len || ssl->s3->previous_server_finished_len); + assert(ssl->s3->initial_handshake_complete == + (ssl->s3->previous_client_finished_len != 0)); + assert(ssl->s3->initial_handshake_complete == + (ssl->s3->previous_server_finished_len != 0)); + + // Parse out the extension contents. + CBS renegotiated_connection; + if (!CBS_get_u8_length_prefixed(contents, &renegotiated_connection) || + CBS_len(contents) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_RENEGOTIATION_ENCODING_ERR); + *out_alert = SSL_AD_ILLEGAL_PARAMETER; + return false; + } + + // Check that the extension matches. + if (CBS_len(&renegotiated_connection) != expected_len) { + OPENSSL_PUT_ERROR(SSL, SSL_R_RENEGOTIATION_MISMATCH); + *out_alert = SSL_AD_HANDSHAKE_FAILURE; + return false; + } + + const uint8_t *d = CBS_data(&renegotiated_connection); + bool ok = CRYPTO_memcmp(d, ssl->s3->previous_client_finished, + ssl->s3->previous_client_finished_len) == 0; +#if defined(BORINGSSL_UNSAFE_FUZZER_MODE) + ok = true; +#endif + if (!ok) { + OPENSSL_PUT_ERROR(SSL, SSL_R_RENEGOTIATION_MISMATCH); + *out_alert = SSL_AD_HANDSHAKE_FAILURE; + return false; + } + d += ssl->s3->previous_client_finished_len; + + ok = CRYPTO_memcmp(d, ssl->s3->previous_server_finished, + ssl->s3->previous_server_finished_len) == 0; +#if defined(BORINGSSL_UNSAFE_FUZZER_MODE) + ok = true; +#endif + if (!ok) { + OPENSSL_PUT_ERROR(SSL, SSL_R_RENEGOTIATION_MISMATCH); + *out_alert = SSL_AD_HANDSHAKE_FAILURE; + return false; + } + ssl->s3->send_connection_binding = true; + + return true; +} + +static bool ext_ri_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert, + CBS *contents) { + SSL *const ssl = hs->ssl; + // Renegotiation isn't supported as a server so this function should never be + // called after the initial handshake. + assert(!ssl->s3->initial_handshake_complete); + + if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) { + return true; + } + + if (contents == NULL) { + return true; + } + + CBS renegotiated_connection; + if (!CBS_get_u8_length_prefixed(contents, &renegotiated_connection) || + CBS_len(contents) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_RENEGOTIATION_ENCODING_ERR); + return false; + } + + // Check that the extension matches. We do not support renegotiation as a + // server, so this must be empty. + if (CBS_len(&renegotiated_connection) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_RENEGOTIATION_MISMATCH); + *out_alert = SSL_AD_HANDSHAKE_FAILURE; + return false; + } + + ssl->s3->send_connection_binding = true; + + return true; +} + +static bool ext_ri_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) { + SSL *const ssl = hs->ssl; + // Renegotiation isn't supported as a server so this function should never be + // called after the initial handshake. + assert(!ssl->s3->initial_handshake_complete); + + if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) { + return true; + } + + if (!CBB_add_u16(out, TLSEXT_TYPE_renegotiate) || + !CBB_add_u16(out, 1 /* length */) || + !CBB_add_u8(out, 0 /* empty renegotiation info */)) { + return false; + } + + return true; +} + + +// Extended Master Secret. +// +// https://tools.ietf.org/html/rfc7627 + +static bool ext_ems_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) { + // Extended master secret is not necessary in TLS 1.3. + if (hs->min_version >= TLS1_3_VERSION || hs->max_version <= SSL3_VERSION) { + return true; + } + + if (!CBB_add_u16(out, TLSEXT_TYPE_extended_master_secret) || + !CBB_add_u16(out, 0 /* length */)) { + return false; + } + + return true; +} + +static bool ext_ems_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert, + CBS *contents) { + SSL *const ssl = hs->ssl; + + if (contents != NULL) { + if (ssl_protocol_version(ssl) >= TLS1_3_VERSION || + ssl->version == SSL3_VERSION || + CBS_len(contents) != 0) { + return false; + } + + hs->extended_master_secret = true; + } + + // Whether EMS is negotiated may not change on renegotiation. + if (ssl->s3->established_session != nullptr && + hs->extended_master_secret != + !!ssl->s3->established_session->extended_master_secret) { + OPENSSL_PUT_ERROR(SSL, SSL_R_RENEGOTIATION_EMS_MISMATCH); + *out_alert = SSL_AD_ILLEGAL_PARAMETER; + return false; + } + + return true; +} + +static bool ext_ems_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert, + CBS *contents) { + uint16_t version = ssl_protocol_version(hs->ssl); + if (version >= TLS1_3_VERSION || + version == SSL3_VERSION) { + return true; + } + + if (contents == NULL) { + return true; + } + + if (CBS_len(contents) != 0) { + return false; + } + + hs->extended_master_secret = true; + return true; +} + +static bool ext_ems_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) { + if (!hs->extended_master_secret) { + return true; + } + + if (!CBB_add_u16(out, TLSEXT_TYPE_extended_master_secret) || + !CBB_add_u16(out, 0 /* length */)) { + return false; + } + + return true; +} + + +// Session tickets. +// +// https://tools.ietf.org/html/rfc5077 + +static bool ext_ticket_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) { + SSL *const ssl = hs->ssl; + // TLS 1.3 uses a different ticket extension. + if (hs->min_version >= TLS1_3_VERSION || + SSL_get_options(ssl) & SSL_OP_NO_TICKET) { + return true; + } + + const uint8_t *ticket_data = NULL; + int ticket_len = 0; + + // Renegotiation does not participate in session resumption. However, still + // advertise the extension to avoid potentially breaking servers which carry + // over the state from the previous handshake, such as OpenSSL servers + // without upstream's 3c3f0259238594d77264a78944d409f2127642c4. + if (!ssl->s3->initial_handshake_complete && + ssl->session != NULL && + ssl->session->tlsext_tick != NULL && + // Don't send TLS 1.3 session tickets in the ticket extension. + ssl_session_protocol_version(ssl->session) < TLS1_3_VERSION) { + ticket_data = ssl->session->tlsext_tick; + ticket_len = ssl->session->tlsext_ticklen; + } + + CBB ticket; + if (!CBB_add_u16(out, TLSEXT_TYPE_session_ticket) || + !CBB_add_u16_length_prefixed(out, &ticket) || + !CBB_add_bytes(&ticket, ticket_data, ticket_len) || + !CBB_flush(out)) { + return false; + } + + return true; +} + +static bool ext_ticket_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert, + CBS *contents) { + SSL *const ssl = hs->ssl; + if (contents == NULL) { + return true; + } + + if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) { + return false; + } + + // If |SSL_OP_NO_TICKET| is set then no extension will have been sent and + // this function should never be called, even if the server tries to send the + // extension. + assert((SSL_get_options(ssl) & SSL_OP_NO_TICKET) == 0); + + if (CBS_len(contents) != 0) { + return false; + } + + hs->ticket_expected = true; + return true; +} + +static bool ext_ticket_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) { + if (!hs->ticket_expected) { + return true; + } + + // If |SSL_OP_NO_TICKET| is set, |ticket_expected| should never be true. + assert((SSL_get_options(hs->ssl) & SSL_OP_NO_TICKET) == 0); + + if (!CBB_add_u16(out, TLSEXT_TYPE_session_ticket) || + !CBB_add_u16(out, 0 /* length */)) { + return false; + } + + return true; +} + + +// Signature Algorithms. +// +// https://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 + +static bool ext_sigalgs_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) { + SSL *const ssl = hs->ssl; + if (hs->max_version < TLS1_2_VERSION) { + return true; + } + + CBB contents, sigalgs_cbb; + if (!CBB_add_u16(out, TLSEXT_TYPE_signature_algorithms) || + !CBB_add_u16_length_prefixed(out, &contents) || + !CBB_add_u16_length_prefixed(&contents, &sigalgs_cbb) || + !tls12_add_verify_sigalgs(ssl, &sigalgs_cbb) || + !CBB_flush(out)) { + return false; + } + + return true; +} + +static bool ext_sigalgs_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert, + CBS *contents) { + hs->peer_sigalgs.Reset(); + if (contents == NULL) { + return true; + } + + CBS supported_signature_algorithms; + if (!CBS_get_u16_length_prefixed(contents, &supported_signature_algorithms) || + CBS_len(contents) != 0 || + CBS_len(&supported_signature_algorithms) == 0 || + !tls1_parse_peer_sigalgs(hs, &supported_signature_algorithms)) { + return false; + } + + return true; +} + + +// OCSP Stapling. +// +// https://tools.ietf.org/html/rfc6066#section-8 + +static bool ext_ocsp_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) { + SSL *const ssl = hs->ssl; + if (!ssl->ocsp_stapling_enabled) { + return true; + } + + CBB contents; + if (!CBB_add_u16(out, TLSEXT_TYPE_status_request) || + !CBB_add_u16_length_prefixed(out, &contents) || + !CBB_add_u8(&contents, TLSEXT_STATUSTYPE_ocsp) || + !CBB_add_u16(&contents, 0 /* empty responder ID list */) || + !CBB_add_u16(&contents, 0 /* empty request extensions */) || + !CBB_flush(out)) { + return false; + } + + return true; +} + +static bool ext_ocsp_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert, + CBS *contents) { + SSL *const ssl = hs->ssl; + if (contents == NULL) { + return true; + } + + // TLS 1.3 OCSP responses are included in the Certificate extensions. + if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) { + return false; + } + + // OCSP stapling is forbidden on non-certificate ciphers. + if (CBS_len(contents) != 0 || + !ssl_cipher_uses_certificate_auth(hs->new_cipher)) { + return false; + } + + // Note this does not check for resumption in TLS 1.2. Sending + // status_request here does not make sense, but OpenSSL does so and the + // specification does not say anything. Tolerate it but ignore it. + + hs->certificate_status_expected = true; + return true; +} + +static bool ext_ocsp_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert, + CBS *contents) { + if (contents == NULL) { + return true; + } + + uint8_t status_type; + if (!CBS_get_u8(contents, &status_type)) { + return false; + } + + // We cannot decide whether OCSP stapling will occur yet because the correct + // SSL_CTX might not have been selected. + hs->ocsp_stapling_requested = status_type == TLSEXT_STATUSTYPE_ocsp; + + return true; +} + +static bool ext_ocsp_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) { + SSL *const ssl = hs->ssl; + if (ssl_protocol_version(ssl) >= TLS1_3_VERSION || + !hs->ocsp_stapling_requested || + ssl->cert->ocsp_response == NULL || + ssl->s3->session_reused || + !ssl_cipher_uses_certificate_auth(hs->new_cipher)) { + return true; + } + + hs->certificate_status_expected = true; + + return CBB_add_u16(out, TLSEXT_TYPE_status_request) && + CBB_add_u16(out, 0 /* length */); +} + + +// Next protocol negotiation. +// +// https://htmlpreview.github.io/?https://github.com/agl/technotes/blob/master/nextprotoneg.html + +static bool ext_npn_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) { + SSL *const ssl = hs->ssl; + if (ssl->s3->initial_handshake_complete || + ssl->ctx->next_proto_select_cb == NULL || + SSL_is_dtls(ssl)) { + return true; + } + + if (!CBB_add_u16(out, TLSEXT_TYPE_next_proto_neg) || + !CBB_add_u16(out, 0 /* length */)) { + return false; + } + + return true; +} + +static bool ext_npn_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert, + CBS *contents) { + SSL *const ssl = hs->ssl; + if (contents == NULL) { + return true; + } + + if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) { + return false; + } + + // If any of these are false then we should never have sent the NPN + // extension in the ClientHello and thus this function should never have been + // called. + assert(!ssl->s3->initial_handshake_complete); + assert(!SSL_is_dtls(ssl)); + assert(ssl->ctx->next_proto_select_cb != NULL); + + if (!ssl->s3->alpn_selected.empty()) { + // NPN and ALPN may not be negotiated in the same connection. + *out_alert = SSL_AD_ILLEGAL_PARAMETER; + OPENSSL_PUT_ERROR(SSL, SSL_R_NEGOTIATED_BOTH_NPN_AND_ALPN); + return false; + } + + const uint8_t *const orig_contents = CBS_data(contents); + const size_t orig_len = CBS_len(contents); + + while (CBS_len(contents) != 0) { + CBS proto; + if (!CBS_get_u8_length_prefixed(contents, &proto) || + CBS_len(&proto) == 0) { + return false; + } + } + + uint8_t *selected; + uint8_t selected_len; + if (ssl->ctx->next_proto_select_cb( + ssl, &selected, &selected_len, orig_contents, orig_len, + ssl->ctx->next_proto_select_cb_arg) != SSL_TLSEXT_ERR_OK || + !ssl->s3->next_proto_negotiated.CopyFrom( + MakeConstSpan(selected, selected_len))) { + *out_alert = SSL_AD_INTERNAL_ERROR; + return false; + } + + hs->next_proto_neg_seen = true; + return true; +} + +static bool ext_npn_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert, + CBS *contents) { + SSL *const ssl = hs->ssl; + if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) { + return true; + } + + if (contents != NULL && CBS_len(contents) != 0) { + return false; + } + + if (contents == NULL || + ssl->s3->initial_handshake_complete || + ssl->ctx->next_protos_advertised_cb == NULL || + SSL_is_dtls(ssl)) { + return true; + } + + hs->next_proto_neg_seen = true; + return true; +} + +static bool ext_npn_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) { + SSL *const ssl = hs->ssl; + // |next_proto_neg_seen| might have been cleared when an ALPN extension was + // parsed. + if (!hs->next_proto_neg_seen) { + return true; + } + + const uint8_t *npa; + unsigned npa_len; + + if (ssl->ctx->next_protos_advertised_cb( + ssl, &npa, &npa_len, ssl->ctx->next_protos_advertised_cb_arg) != + SSL_TLSEXT_ERR_OK) { + hs->next_proto_neg_seen = false; + return true; + } + + CBB contents; + if (!CBB_add_u16(out, TLSEXT_TYPE_next_proto_neg) || + !CBB_add_u16_length_prefixed(out, &contents) || + !CBB_add_bytes(&contents, npa, npa_len) || + !CBB_flush(out)) { + return false; + } + + return true; +} + + +// Signed certificate timestamps. +// +// https://tools.ietf.org/html/rfc6962#section-3.3.1 + +static bool ext_sct_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) { + SSL *const ssl = hs->ssl; + if (!ssl->signed_cert_timestamps_enabled) { + return true; + } + + if (!CBB_add_u16(out, TLSEXT_TYPE_certificate_timestamp) || + !CBB_add_u16(out, 0 /* length */)) { + return false; + } + + return true; +} + +static bool ext_sct_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert, + CBS *contents) { + SSL *const ssl = hs->ssl; + if (contents == NULL) { + return true; + } + + // TLS 1.3 SCTs are included in the Certificate extensions. + if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) { + *out_alert = SSL_AD_DECODE_ERROR; + return false; + } + + // If this is false then we should never have sent the SCT extension in the + // ClientHello and thus this function should never have been called. + assert(ssl->signed_cert_timestamps_enabled); + + if (!ssl_is_sct_list_valid(contents)) { + *out_alert = SSL_AD_DECODE_ERROR; + return false; + } + + // Session resumption uses the original session information. The extension + // should not be sent on resumption, but RFC 6962 did not make it a + // requirement, so tolerate this. + // + // TODO(davidben): Enforce this anyway. + if (!ssl->s3->session_reused) { + CRYPTO_BUFFER_free(hs->new_session->signed_cert_timestamp_list); + hs->new_session->signed_cert_timestamp_list = + CRYPTO_BUFFER_new_from_CBS(contents, ssl->ctx->pool); + if (hs->new_session->signed_cert_timestamp_list == nullptr) { + *out_alert = SSL_AD_INTERNAL_ERROR; + return false; + } + } + + return true; +} + +static bool ext_sct_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert, + CBS *contents) { + if (contents == NULL) { + return true; + } + + if (CBS_len(contents) != 0) { + return false; + } + + hs->scts_requested = true; + return true; +} + +static bool ext_sct_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) { + SSL *const ssl = hs->ssl; + // The extension shouldn't be sent when resuming sessions. + if (ssl_protocol_version(ssl) >= TLS1_3_VERSION || + ssl->s3->session_reused || + ssl->cert->signed_cert_timestamp_list == NULL) { + return true; + } + + CBB contents; + return CBB_add_u16(out, TLSEXT_TYPE_certificate_timestamp) && + CBB_add_u16_length_prefixed(out, &contents) && + CBB_add_bytes( + &contents, + CRYPTO_BUFFER_data(ssl->cert->signed_cert_timestamp_list), + CRYPTO_BUFFER_len(ssl->cert->signed_cert_timestamp_list)) && + CBB_flush(out); +} + + +// Application-level Protocol Negotiation. +// +// https://tools.ietf.org/html/rfc7301 + +static bool ext_alpn_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) { + SSL *const ssl = hs->ssl; + if (ssl->alpn_client_proto_list == NULL || + ssl->s3->initial_handshake_complete) { + return true; + } + + CBB contents, proto_list; + if (!CBB_add_u16(out, TLSEXT_TYPE_application_layer_protocol_negotiation) || + !CBB_add_u16_length_prefixed(out, &contents) || + !CBB_add_u16_length_prefixed(&contents, &proto_list) || + !CBB_add_bytes(&proto_list, ssl->alpn_client_proto_list, + ssl->alpn_client_proto_list_len) || + !CBB_flush(out)) { + return false; + } + + return true; +} + +static bool ext_alpn_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert, + CBS *contents) { + SSL *const ssl = hs->ssl; + if (contents == NULL) { + return true; + } + + assert(!ssl->s3->initial_handshake_complete); + assert(ssl->alpn_client_proto_list != NULL); + + if (hs->next_proto_neg_seen) { + // NPN and ALPN may not be negotiated in the same connection. + *out_alert = SSL_AD_ILLEGAL_PARAMETER; + OPENSSL_PUT_ERROR(SSL, SSL_R_NEGOTIATED_BOTH_NPN_AND_ALPN); + return false; + } + + // The extension data consists of a ProtocolNameList which must have + // exactly one ProtocolName. Each of these is length-prefixed. + CBS protocol_name_list, protocol_name; + if (!CBS_get_u16_length_prefixed(contents, &protocol_name_list) || + CBS_len(contents) != 0 || + !CBS_get_u8_length_prefixed(&protocol_name_list, &protocol_name) || + // Empty protocol names are forbidden. + CBS_len(&protocol_name) == 0 || + CBS_len(&protocol_name_list) != 0) { + return false; + } + + if (!ssl_is_alpn_protocol_allowed(ssl, protocol_name)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_ALPN_PROTOCOL); + *out_alert = SSL_AD_ILLEGAL_PARAMETER; + return false; + } + + if (!ssl->s3->alpn_selected.CopyFrom(protocol_name)) { + *out_alert = SSL_AD_INTERNAL_ERROR; + return false; + } + + return true; +} + +bool ssl_is_alpn_protocol_allowed(const SSL *ssl, + Span protocol) { + if (ssl->alpn_client_proto_list == nullptr) { + return false; + } + + if (ssl->ctx->allow_unknown_alpn_protos) { + return true; + } + + // Check that the protocol name is one of the ones we advertised. + CBS client_protocol_name_list, client_protocol_name; + CBS_init(&client_protocol_name_list, ssl->alpn_client_proto_list, + ssl->alpn_client_proto_list_len); + while (CBS_len(&client_protocol_name_list) > 0) { + if (!CBS_get_u8_length_prefixed(&client_protocol_name_list, + &client_protocol_name)) { + return false; + } + + if (client_protocol_name == protocol) { + return true; + } + } + + return false; +} + +bool ssl_negotiate_alpn(SSL_HANDSHAKE *hs, uint8_t *out_alert, + const SSL_CLIENT_HELLO *client_hello) { + SSL *const ssl = hs->ssl; + CBS contents; + if (ssl->ctx->alpn_select_cb == NULL || + !ssl_client_hello_get_extension( + client_hello, &contents, + TLSEXT_TYPE_application_layer_protocol_negotiation)) { + // Ignore ALPN if not configured or no extension was supplied. + return true; + } + + // ALPN takes precedence over NPN. + hs->next_proto_neg_seen = false; + + CBS protocol_name_list; + if (!CBS_get_u16_length_prefixed(&contents, &protocol_name_list) || + CBS_len(&contents) != 0 || + CBS_len(&protocol_name_list) < 2) { + OPENSSL_PUT_ERROR(SSL, SSL_R_PARSE_TLSEXT); + *out_alert = SSL_AD_DECODE_ERROR; + return false; + } + + // Validate the protocol list. + CBS protocol_name_list_copy = protocol_name_list; + while (CBS_len(&protocol_name_list_copy) > 0) { + CBS protocol_name; + + if (!CBS_get_u8_length_prefixed(&protocol_name_list_copy, &protocol_name) || + // Empty protocol names are forbidden. + CBS_len(&protocol_name) == 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_PARSE_TLSEXT); + *out_alert = SSL_AD_DECODE_ERROR; + return false; + } + } + + const uint8_t *selected; + uint8_t selected_len; + if (ssl->ctx->alpn_select_cb( + ssl, &selected, &selected_len, CBS_data(&protocol_name_list), + CBS_len(&protocol_name_list), + ssl->ctx->alpn_select_cb_arg) == SSL_TLSEXT_ERR_OK) { + if (!ssl->s3->alpn_selected.CopyFrom( + MakeConstSpan(selected, selected_len))) { + *out_alert = SSL_AD_INTERNAL_ERROR; + return false; + } + } + + return true; +} + +static bool ext_alpn_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) { + SSL *const ssl = hs->ssl; + if (ssl->s3->alpn_selected.empty()) { + return true; + } + + CBB contents, proto_list, proto; + if (!CBB_add_u16(out, TLSEXT_TYPE_application_layer_protocol_negotiation) || + !CBB_add_u16_length_prefixed(out, &contents) || + !CBB_add_u16_length_prefixed(&contents, &proto_list) || + !CBB_add_u8_length_prefixed(&proto_list, &proto) || + !CBB_add_bytes(&proto, ssl->s3->alpn_selected.data(), + ssl->s3->alpn_selected.size()) || + !CBB_flush(out)) { + return false; + } + + return true; +} + + +// Channel ID. +// +// https://tools.ietf.org/html/draft-balfanz-tls-channelid-01 + +static void ext_channel_id_init(SSL_HANDSHAKE *hs) { + hs->ssl->s3->tlsext_channel_id_valid = false; +} + +static bool ext_channel_id_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) { + SSL *const ssl = hs->ssl; + if (!ssl->tlsext_channel_id_enabled || + SSL_is_dtls(ssl)) { + return true; + } + + if (!CBB_add_u16(out, TLSEXT_TYPE_channel_id) || + !CBB_add_u16(out, 0 /* length */)) { + return false; + } + + return true; +} + +static bool ext_channel_id_parse_serverhello(SSL_HANDSHAKE *hs, + uint8_t *out_alert, + CBS *contents) { + SSL *const ssl = hs->ssl; + if (contents == NULL) { + return true; + } + + assert(!SSL_is_dtls(ssl)); + assert(ssl->tlsext_channel_id_enabled); + + if (CBS_len(contents) != 0) { + return false; + } + + ssl->s3->tlsext_channel_id_valid = true; + return true; +} + +static bool ext_channel_id_parse_clienthello(SSL_HANDSHAKE *hs, + uint8_t *out_alert, + CBS *contents) { + SSL *const ssl = hs->ssl; + if (contents == NULL || + !ssl->tlsext_channel_id_enabled || + SSL_is_dtls(ssl)) { + return true; + } + + if (CBS_len(contents) != 0) { + return false; + } + + ssl->s3->tlsext_channel_id_valid = true; + return true; +} + +static bool ext_channel_id_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) { + SSL *const ssl = hs->ssl; + if (!ssl->s3->tlsext_channel_id_valid) { + return true; + } + + if (!CBB_add_u16(out, TLSEXT_TYPE_channel_id) || + !CBB_add_u16(out, 0 /* length */)) { + return false; + } + + return true; +} + + +// Secure Real-time Transport Protocol (SRTP) extension. +// +// https://tools.ietf.org/html/rfc5764 + + +static void ext_srtp_init(SSL_HANDSHAKE *hs) { + hs->ssl->srtp_profile = NULL; +} + +static bool ext_srtp_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) { + SSL *const ssl = hs->ssl; + STACK_OF(SRTP_PROTECTION_PROFILE) *profiles = SSL_get_srtp_profiles(ssl); + if (profiles == NULL || + sk_SRTP_PROTECTION_PROFILE_num(profiles) == 0) { + return true; + } + + CBB contents, profile_ids; + if (!CBB_add_u16(out, TLSEXT_TYPE_srtp) || + !CBB_add_u16_length_prefixed(out, &contents) || + !CBB_add_u16_length_prefixed(&contents, &profile_ids)) { + return false; + } + + for (const SRTP_PROTECTION_PROFILE *profile : profiles) { + if (!CBB_add_u16(&profile_ids, profile->id)) { + return false; + } + } + + if (!CBB_add_u8(&contents, 0 /* empty use_mki value */) || + !CBB_flush(out)) { + return false; + } + + return true; +} + +static bool ext_srtp_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert, + CBS *contents) { + SSL *const ssl = hs->ssl; + if (contents == NULL) { + return true; + } + + // The extension consists of a u16-prefixed profile ID list containing a + // single uint16_t profile ID, then followed by a u8-prefixed srtp_mki field. + // + // See https://tools.ietf.org/html/rfc5764#section-4.1.1 + CBS profile_ids, srtp_mki; + uint16_t profile_id; + if (!CBS_get_u16_length_prefixed(contents, &profile_ids) || + !CBS_get_u16(&profile_ids, &profile_id) || + CBS_len(&profile_ids) != 0 || + !CBS_get_u8_length_prefixed(contents, &srtp_mki) || + CBS_len(contents) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST); + return false; + } + + if (CBS_len(&srtp_mki) != 0) { + // Must be no MKI, since we never offer one. + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SRTP_MKI_VALUE); + *out_alert = SSL_AD_ILLEGAL_PARAMETER; + return false; + } + + STACK_OF(SRTP_PROTECTION_PROFILE) *profiles = SSL_get_srtp_profiles(ssl); + + // Check to see if the server gave us something we support (and presumably + // offered). + for (const SRTP_PROTECTION_PROFILE *profile : profiles) { + if (profile->id == profile_id) { + ssl->srtp_profile = profile; + return true; + } + } + + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST); + *out_alert = SSL_AD_ILLEGAL_PARAMETER; + return false; +} + +static bool ext_srtp_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert, + CBS *contents) { + SSL *const ssl = hs->ssl; + if (contents == NULL) { + return true; + } + + CBS profile_ids, srtp_mki; + if (!CBS_get_u16_length_prefixed(contents, &profile_ids) || + CBS_len(&profile_ids) < 2 || + !CBS_get_u8_length_prefixed(contents, &srtp_mki) || + CBS_len(contents) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SRTP_PROTECTION_PROFILE_LIST); + return false; + } + // Discard the MKI value for now. + + const STACK_OF(SRTP_PROTECTION_PROFILE) *server_profiles = + SSL_get_srtp_profiles(ssl); + + // Pick the server's most preferred profile. + for (const SRTP_PROTECTION_PROFILE *server_profile : server_profiles) { + CBS profile_ids_tmp; + CBS_init(&profile_ids_tmp, CBS_data(&profile_ids), CBS_len(&profile_ids)); + + while (CBS_len(&profile_ids_tmp) > 0) { + uint16_t profile_id; + if (!CBS_get_u16(&profile_ids_tmp, &profile_id)) { + return false; + } + + if (server_profile->id == profile_id) { + ssl->srtp_profile = server_profile; + return true; + } + } + } + + return true; +} + +static bool ext_srtp_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) { + SSL *const ssl = hs->ssl; + if (ssl->srtp_profile == NULL) { + return true; + } + + CBB contents, profile_ids; + if (!CBB_add_u16(out, TLSEXT_TYPE_srtp) || + !CBB_add_u16_length_prefixed(out, &contents) || + !CBB_add_u16_length_prefixed(&contents, &profile_ids) || + !CBB_add_u16(&profile_ids, ssl->srtp_profile->id) || + !CBB_add_u8(&contents, 0 /* empty MKI */) || + !CBB_flush(out)) { + return false; + } + + return true; +} + + +// EC point formats. +// +// https://tools.ietf.org/html/rfc4492#section-5.1.2 + +static bool ext_ec_point_add_extension(SSL_HANDSHAKE *hs, CBB *out) { + CBB contents, formats; + if (!CBB_add_u16(out, TLSEXT_TYPE_ec_point_formats) || + !CBB_add_u16_length_prefixed(out, &contents) || + !CBB_add_u8_length_prefixed(&contents, &formats) || + !CBB_add_u8(&formats, TLSEXT_ECPOINTFORMAT_uncompressed) || + !CBB_flush(out)) { + return false; + } + + return true; +} + +static bool ext_ec_point_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) { + // The point format extension is unneccessary in TLS 1.3. + if (hs->min_version >= TLS1_3_VERSION) { + return true; + } + + return ext_ec_point_add_extension(hs, out); +} + +static bool ext_ec_point_parse_serverhello(SSL_HANDSHAKE *hs, uint8_t *out_alert, + CBS *contents) { + if (contents == NULL) { + return true; + } + + if (ssl_protocol_version(hs->ssl) >= TLS1_3_VERSION) { + return false; + } + + CBS ec_point_format_list; + if (!CBS_get_u8_length_prefixed(contents, &ec_point_format_list) || + CBS_len(contents) != 0) { + return false; + } + + // Per RFC 4492, section 5.1.2, implementations MUST support the uncompressed + // point format. + if (OPENSSL_memchr(CBS_data(&ec_point_format_list), + TLSEXT_ECPOINTFORMAT_uncompressed, + CBS_len(&ec_point_format_list)) == NULL) { + *out_alert = SSL_AD_ILLEGAL_PARAMETER; + return false; + } + + return true; +} + +static bool ext_ec_point_parse_clienthello(SSL_HANDSHAKE *hs, uint8_t *out_alert, + CBS *contents) { + if (ssl_protocol_version(hs->ssl) >= TLS1_3_VERSION) { + return true; + } + + return ext_ec_point_parse_serverhello(hs, out_alert, contents); +} + +static bool ext_ec_point_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) { + SSL *const ssl = hs->ssl; + if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) { + return true; + } + + const uint32_t alg_k = hs->new_cipher->algorithm_mkey; + const uint32_t alg_a = hs->new_cipher->algorithm_auth; + const bool using_ecc = (alg_k & SSL_kECDHE) || (alg_a & SSL_aECDSA); + + if (!using_ecc) { + return true; + } + + return ext_ec_point_add_extension(hs, out); +} + + +// Pre Shared Key +// +// https://tools.ietf.org/html/draft-ietf-tls-tls13-18#section-4.2.6 + +static size_t ext_pre_shared_key_clienthello_length(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + if (hs->max_version < TLS1_3_VERSION || ssl->session == NULL || + ssl_session_protocol_version(ssl->session) < TLS1_3_VERSION) { + return 0; + } + + size_t binder_len = EVP_MD_size(ssl_session_get_digest(ssl->session)); + return 15 + ssl->session->tlsext_ticklen + binder_len; +} + +static bool ext_pre_shared_key_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) { + SSL *const ssl = hs->ssl; + hs->needs_psk_binder = false; + if (hs->max_version < TLS1_3_VERSION || ssl->session == NULL || + ssl_session_protocol_version(ssl->session) < TLS1_3_VERSION) { + return true; + } + + // Per draft-ietf-tls-tls13-21 section 4.1.4, skip offering the session if the + // selected cipher in HelloRetryRequest does not match. This avoids performing + // the transcript hash transformation for multiple hashes. + if (hs->received_hello_retry_request && + ssl->session->cipher->algorithm_prf != hs->new_cipher->algorithm_prf) { + return true; + } + + struct OPENSSL_timeval now; + ssl_get_current_time(ssl, &now); + uint32_t ticket_age = 1000 * (now.tv_sec - ssl->session->time); + uint32_t obfuscated_ticket_age = ticket_age + ssl->session->ticket_age_add; + + // Fill in a placeholder zero binder of the appropriate length. It will be + // computed and filled in later after length prefixes are computed. + uint8_t zero_binder[EVP_MAX_MD_SIZE] = {0}; + size_t binder_len = EVP_MD_size(ssl_session_get_digest(ssl->session)); + + CBB contents, identity, ticket, binders, binder; + if (!CBB_add_u16(out, TLSEXT_TYPE_pre_shared_key) || + !CBB_add_u16_length_prefixed(out, &contents) || + !CBB_add_u16_length_prefixed(&contents, &identity) || + !CBB_add_u16_length_prefixed(&identity, &ticket) || + !CBB_add_bytes(&ticket, ssl->session->tlsext_tick, + ssl->session->tlsext_ticklen) || + !CBB_add_u32(&identity, obfuscated_ticket_age) || + !CBB_add_u16_length_prefixed(&contents, &binders) || + !CBB_add_u8_length_prefixed(&binders, &binder) || + !CBB_add_bytes(&binder, zero_binder, binder_len)) { + return false; + } + + hs->needs_psk_binder = true; + return CBB_flush(out); +} + +bool ssl_ext_pre_shared_key_parse_serverhello(SSL_HANDSHAKE *hs, + uint8_t *out_alert, + CBS *contents) { + uint16_t psk_id; + if (!CBS_get_u16(contents, &psk_id) || + CBS_len(contents) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + *out_alert = SSL_AD_DECODE_ERROR; + return false; + } + + // We only advertise one PSK identity, so the only legal index is zero. + if (psk_id != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_PSK_IDENTITY_NOT_FOUND); + *out_alert = SSL_AD_UNKNOWN_PSK_IDENTITY; + return false; + } + + return true; +} + +bool ssl_ext_pre_shared_key_parse_clienthello( + SSL_HANDSHAKE *hs, CBS *out_ticket, CBS *out_binders, + uint32_t *out_obfuscated_ticket_age, uint8_t *out_alert, CBS *contents) { + // We only process the first PSK identity since we don't support pure PSK. + CBS identities, binders; + if (!CBS_get_u16_length_prefixed(contents, &identities) || + !CBS_get_u16_length_prefixed(&identities, out_ticket) || + !CBS_get_u32(&identities, out_obfuscated_ticket_age) || + !CBS_get_u16_length_prefixed(contents, &binders) || + CBS_len(&binders) == 0 || + CBS_len(contents) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + *out_alert = SSL_AD_DECODE_ERROR; + return false; + } + + *out_binders = binders; + + // Check the syntax of the remaining identities, but do not process them. + size_t num_identities = 1; + while (CBS_len(&identities) != 0) { + CBS unused_ticket; + uint32_t unused_obfuscated_ticket_age; + if (!CBS_get_u16_length_prefixed(&identities, &unused_ticket) || + !CBS_get_u32(&identities, &unused_obfuscated_ticket_age)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + *out_alert = SSL_AD_DECODE_ERROR; + return false; + } + + num_identities++; + } + + // Check the syntax of the binders. The value will be checked later if + // resuming. + size_t num_binders = 0; + while (CBS_len(&binders) != 0) { + CBS binder; + if (!CBS_get_u8_length_prefixed(&binders, &binder)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + *out_alert = SSL_AD_DECODE_ERROR; + return false; + } + + num_binders++; + } + + if (num_identities != num_binders) { + OPENSSL_PUT_ERROR(SSL, SSL_R_PSK_IDENTITY_BINDER_COUNT_MISMATCH); + *out_alert = SSL_AD_ILLEGAL_PARAMETER; + return false; + } + + return true; +} + +bool ssl_ext_pre_shared_key_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) { + if (!hs->ssl->s3->session_reused) { + return true; + } + + CBB contents; + if (!CBB_add_u16(out, TLSEXT_TYPE_pre_shared_key) || + !CBB_add_u16_length_prefixed(out, &contents) || + // We only consider the first identity for resumption + !CBB_add_u16(&contents, 0) || + !CBB_flush(out)) { + return false; + } + + return true; +} + + +// Pre-Shared Key Exchange Modes +// +// https://tools.ietf.org/html/draft-ietf-tls-tls13-18#section-4.2.7 + +static bool ext_psk_key_exchange_modes_add_clienthello(SSL_HANDSHAKE *hs, + CBB *out) { + if (hs->max_version < TLS1_3_VERSION) { + return true; + } + + CBB contents, ke_modes; + if (!CBB_add_u16(out, TLSEXT_TYPE_psk_key_exchange_modes) || + !CBB_add_u16_length_prefixed(out, &contents) || + !CBB_add_u8_length_prefixed(&contents, &ke_modes) || + !CBB_add_u8(&ke_modes, SSL_PSK_DHE_KE)) { + return false; + } + + return CBB_flush(out); +} + +static bool ext_psk_key_exchange_modes_parse_clienthello(SSL_HANDSHAKE *hs, + uint8_t *out_alert, + CBS *contents) { + if (contents == NULL) { + return true; + } + + CBS ke_modes; + if (!CBS_get_u8_length_prefixed(contents, &ke_modes) || + CBS_len(&ke_modes) == 0 || + CBS_len(contents) != 0) { + *out_alert = SSL_AD_DECODE_ERROR; + return false; + } + + // We only support tickets with PSK_DHE_KE. + hs->accept_psk_mode = OPENSSL_memchr(CBS_data(&ke_modes), SSL_PSK_DHE_KE, + CBS_len(&ke_modes)) != NULL; + + return true; +} + + +// Early Data Indication +// +// https://tools.ietf.org/html/draft-ietf-tls-tls13-18#section-4.2.8 + +static bool ext_early_data_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) { + SSL *const ssl = hs->ssl; + if (!ssl->cert->enable_early_data || + // Session must be 0-RTT capable. + ssl->session == NULL || + ssl_session_protocol_version(ssl->session) < TLS1_3_VERSION || + ssl->session->ticket_max_early_data == 0 || + // The second ClientHello never offers early data. + hs->received_hello_retry_request || + // In case ALPN preferences changed since this session was established, + // avoid reporting a confusing value in |SSL_get0_alpn_selected|. + (ssl->session->early_alpn_len != 0 && + !ssl_is_alpn_protocol_allowed( + ssl, MakeConstSpan(ssl->session->early_alpn, + ssl->session->early_alpn_len)))) { + return true; + } + + hs->early_data_offered = true; + + if (!CBB_add_u16(out, TLSEXT_TYPE_early_data) || + !CBB_add_u16(out, 0) || + !CBB_flush(out)) { + return false; + } + + return true; +} + +static bool ext_early_data_parse_serverhello(SSL_HANDSHAKE *hs, + uint8_t *out_alert, CBS *contents) { + SSL *const ssl = hs->ssl; + if (contents == NULL) { + return true; + } + + if (CBS_len(contents) != 0) { + *out_alert = SSL_AD_DECODE_ERROR; + return false; + } + + if (!ssl->s3->session_reused) { + *out_alert = SSL_AD_UNSUPPORTED_EXTENSION; + OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION); + return false; + } + + ssl->s3->early_data_accepted = true; + return true; +} + +static bool ext_early_data_parse_clienthello(SSL_HANDSHAKE *hs, + uint8_t *out_alert, CBS *contents) { + SSL *const ssl = hs->ssl; + if (contents == NULL || + ssl_protocol_version(ssl) < TLS1_3_VERSION) { + return true; + } + + if (CBS_len(contents) != 0) { + *out_alert = SSL_AD_DECODE_ERROR; + return false; + } + + hs->early_data_offered = true; + return true; +} + +static bool ext_early_data_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) { + if (!hs->ssl->s3->early_data_accepted) { + return true; + } + + if (!CBB_add_u16(out, TLSEXT_TYPE_early_data) || + !CBB_add_u16(out, 0) || + !CBB_flush(out)) { + return false; + } + + return true; +} + + +// Key Share +// +// https://tools.ietf.org/html/draft-ietf-tls-tls13-16#section-4.2.5 + +static bool ext_key_share_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) { + SSL *const ssl = hs->ssl; + if (hs->max_version < TLS1_3_VERSION) { + return true; + } + + CBB contents, kse_bytes; + if (!CBB_add_u16(out, TLSEXT_TYPE_key_share) || + !CBB_add_u16_length_prefixed(out, &contents) || + !CBB_add_u16_length_prefixed(&contents, &kse_bytes)) { + return false; + } + + uint16_t group_id = hs->retry_group; + if (hs->received_hello_retry_request) { + // We received a HelloRetryRequest without a new curve, so there is no new + // share to append. Leave |hs->key_share| as-is. + if (group_id == 0 && + !CBB_add_bytes(&kse_bytes, hs->key_share_bytes.data(), + hs->key_share_bytes.size())) { + return false; + } + hs->key_share_bytes.Reset(); + if (group_id == 0) { + return CBB_flush(out); + } + } else { + // Add a fake group. See draft-davidben-tls-grease-01. + if (ssl->ctx->grease_enabled && + (!CBB_add_u16(&kse_bytes, + ssl_get_grease_value(hs, ssl_grease_group)) || + !CBB_add_u16(&kse_bytes, 1 /* length */) || + !CBB_add_u8(&kse_bytes, 0 /* one byte key share */))) { + return false; + } + + // Predict the most preferred group. + Span groups = tls1_get_grouplist(ssl); + if (groups.empty()) { + OPENSSL_PUT_ERROR(SSL, SSL_R_NO_GROUPS_SPECIFIED); + return false; + } + + group_id = groups[0]; + } + + hs->key_share = SSLKeyShare::Create(group_id); + CBB key_exchange; + if (!hs->key_share || + !CBB_add_u16(&kse_bytes, group_id) || + !CBB_add_u16_length_prefixed(&kse_bytes, &key_exchange) || + !hs->key_share->Offer(&key_exchange) || + !CBB_flush(&kse_bytes)) { + return false; + } + + // Save the contents of the extension to repeat it in the second ClientHello. + if (!hs->received_hello_retry_request && + !hs->key_share_bytes.CopyFrom( + MakeConstSpan(CBB_data(&kse_bytes), CBB_len(&kse_bytes)))) { + return false; + } + + return CBB_flush(out); +} + +bool ssl_ext_key_share_parse_serverhello(SSL_HANDSHAKE *hs, + Array *out_secret, + uint8_t *out_alert, CBS *contents) { + CBS peer_key; + uint16_t group_id; + if (!CBS_get_u16(contents, &group_id) || + !CBS_get_u16_length_prefixed(contents, &peer_key) || + CBS_len(contents) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + *out_alert = SSL_AD_DECODE_ERROR; + return false; + } + + if (hs->key_share->GroupID() != group_id) { + *out_alert = SSL_AD_ILLEGAL_PARAMETER; + OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CURVE); + return false; + } + + if (!hs->key_share->Finish(out_secret, out_alert, peer_key)) { + *out_alert = SSL_AD_INTERNAL_ERROR; + return false; + } + + hs->new_session->group_id = group_id; + hs->key_share.reset(); + return true; +} + +bool ssl_ext_key_share_parse_clienthello(SSL_HANDSHAKE *hs, bool *out_found, + Array *out_secret, + uint8_t *out_alert, CBS *contents) { + uint16_t group_id; + CBS key_shares; + if (!tls1_get_shared_group(hs, &group_id)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_NO_SHARED_GROUP); + *out_alert = SSL_AD_HANDSHAKE_FAILURE; + return false; + } + + if (!CBS_get_u16_length_prefixed(contents, &key_shares) || + CBS_len(contents) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + return false; + } + + // Find the corresponding key share. + CBS peer_key; + CBS_init(&peer_key, NULL, 0); + while (CBS_len(&key_shares) > 0) { + uint16_t id; + CBS peer_key_tmp; + if (!CBS_get_u16(&key_shares, &id) || + !CBS_get_u16_length_prefixed(&key_shares, &peer_key_tmp) || + CBS_len(&peer_key_tmp) == 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + return false; + } + + if (id == group_id) { + if (CBS_len(&peer_key) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DUPLICATE_KEY_SHARE); + *out_alert = SSL_AD_ILLEGAL_PARAMETER; + return false; + } + + peer_key = peer_key_tmp; + // Continue parsing the structure to keep peers honest. + } + } + + if (CBS_len(&peer_key) == 0) { + *out_found = false; + out_secret->Reset(); + return true; + } + + // Compute the DH secret. + Array secret; + ScopedCBB public_key; + UniquePtr key_share = SSLKeyShare::Create(group_id); + if (!key_share || + !CBB_init(public_key.get(), 32) || + !key_share->Accept(public_key.get(), &secret, out_alert, peer_key) || + !CBBFinishArray(public_key.get(), &hs->ecdh_public_key)) { + *out_alert = SSL_AD_ILLEGAL_PARAMETER; + return false; + } + + *out_secret = std::move(secret); + *out_found = true; + return true; +} + +bool ssl_ext_key_share_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) { + uint16_t group_id; + CBB kse_bytes, public_key; + if (!tls1_get_shared_group(hs, &group_id) || + !CBB_add_u16(out, TLSEXT_TYPE_key_share) || + !CBB_add_u16_length_prefixed(out, &kse_bytes) || + !CBB_add_u16(&kse_bytes, group_id) || + !CBB_add_u16_length_prefixed(&kse_bytes, &public_key) || + !CBB_add_bytes(&public_key, hs->ecdh_public_key.data(), + hs->ecdh_public_key.size()) || + !CBB_flush(out)) { + return false; + } + + hs->ecdh_public_key.Reset(); + + hs->new_session->group_id = group_id; + return true; +} + + +// Supported Versions +// +// https://tools.ietf.org/html/draft-ietf-tls-tls13-16#section-4.2.1 + +static bool ext_supported_versions_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) { + SSL *const ssl = hs->ssl; + if (hs->max_version <= TLS1_2_VERSION) { + return true; + } + + CBB contents, versions; + if (!CBB_add_u16(out, TLSEXT_TYPE_supported_versions) || + !CBB_add_u16_length_prefixed(out, &contents) || + !CBB_add_u8_length_prefixed(&contents, &versions)) { + return false; + } + + // Add a fake version. See draft-davidben-tls-grease-01. + if (ssl->ctx->grease_enabled && + !CBB_add_u16(&versions, ssl_get_grease_value(hs, ssl_grease_version))) { + return false; + } + + if (!ssl_add_supported_versions(hs, &versions) || + !CBB_flush(out)) { + return false; + } + + return true; +} + + +// Cookie +// +// https://tools.ietf.org/html/draft-ietf-tls-tls13-16#section-4.2.2 + +static bool ext_cookie_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) { + if (hs->cookie.empty()) { + return true; + } + + CBB contents, cookie; + if (!CBB_add_u16(out, TLSEXT_TYPE_cookie) || + !CBB_add_u16_length_prefixed(out, &contents) || + !CBB_add_u16_length_prefixed(&contents, &cookie) || + !CBB_add_bytes(&cookie, hs->cookie.data(), hs->cookie.size()) || + !CBB_flush(out)) { + return false; + } + + // The cookie is no longer needed in memory. + hs->cookie.Reset(); + return true; +} + + +// Dummy PQ Padding extension +// +// Dummy post-quantum padding invovles the client (and later server) sending +// useless, random-looking bytes in an extension in their ClientHello or +// ServerHello. These extensions are sized to simulate a post-quantum +// key-exchange and so enable measurement of the latency impact of the +// additional bandwidth. + +static bool ext_dummy_pq_padding_add(CBB *out, size_t len) { + CBB contents; + uint8_t *buffer; + if (!CBB_add_u16(out, TLSEXT_TYPE_dummy_pq_padding) || + !CBB_add_u16_length_prefixed(out, &contents) || + !CBB_add_space(&contents, &buffer, len)) { + return false; + } + + // The length is used as the nonce so that different length extensions have + // different contents. There's no reason this has to be the case, it just + // makes things a little more obvious in a packet dump. + uint8_t nonce[12] = {0}; + memcpy(nonce, &len, sizeof(len)); + + memset(buffer, 0, len); + static const uint8_t kZeroKey[32] = {0}; + CRYPTO_chacha_20(buffer, buffer, len, kZeroKey, nonce, 0); + + return CBB_flush(out); +} + +static bool ext_dummy_pq_padding_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) { + const size_t len = hs->ssl->dummy_pq_padding_len; + if (len == 0) { + return true; + } + + return ext_dummy_pq_padding_add(out, len); +} + +static bool ext_dummy_pq_padding_parse_serverhello(SSL_HANDSHAKE *hs, + uint8_t *out_alert, + CBS *contents) { + if (contents == nullptr) { + return true; + } + + if (CBS_len(contents) != hs->ssl->dummy_pq_padding_len) { + return false; + } + + hs->ssl->did_dummy_pq_padding = true; + return true; +} + +static bool ext_dummy_pq_padding_parse_clienthello(SSL_HANDSHAKE *hs, + uint8_t *out_alert, + CBS *contents) { + if (contents != nullptr && + 0 < CBS_len(contents) && CBS_len(contents) < (1 << 12)) { + hs->dummy_pq_padding_len = CBS_len(contents); + } + + return true; +} + +static bool ext_dummy_pq_padding_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) { + if (!hs->dummy_pq_padding_len) { + return true; + } + + return ext_dummy_pq_padding_add(out, hs->dummy_pq_padding_len); +} + +// Negotiated Groups +// +// https://tools.ietf.org/html/rfc4492#section-5.1.2 +// https://tools.ietf.org/html/draft-ietf-tls-tls13-16#section-4.2.4 + +static bool ext_supported_groups_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) { + SSL *const ssl = hs->ssl; + CBB contents, groups_bytes; + if (!CBB_add_u16(out, TLSEXT_TYPE_supported_groups) || + !CBB_add_u16_length_prefixed(out, &contents) || + !CBB_add_u16_length_prefixed(&contents, &groups_bytes)) { + return false; + } + + // Add a fake group. See draft-davidben-tls-grease-01. + if (ssl->ctx->grease_enabled && + !CBB_add_u16(&groups_bytes, + ssl_get_grease_value(hs, ssl_grease_group))) { + return false; + } + + for (uint16_t group : tls1_get_grouplist(ssl)) { + if (!CBB_add_u16(&groups_bytes, group)) { + return false; + } + } + + return CBB_flush(out); +} + +static bool ext_supported_groups_parse_serverhello(SSL_HANDSHAKE *hs, + uint8_t *out_alert, + CBS *contents) { + // This extension is not expected to be echoed by servers in TLS 1.2, but some + // BigIP servers send it nonetheless, so do not enforce this. + return true; +} + +static bool parse_u16_array(const CBS *cbs, Array *out) { + CBS copy = *cbs; + if ((CBS_len(©) & 1) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + return false; + } + + Array ret; + if (!ret.Init(CBS_len(©) / 2)) { + return false; + } + for (size_t i = 0; i < ret.size(); i++) { + if (!CBS_get_u16(©, &ret[i])) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return false; + } + } + + assert(CBS_len(©) == 0); + *out = std::move(ret); + return 1; +} + +static bool ext_supported_groups_parse_clienthello(SSL_HANDSHAKE *hs, + uint8_t *out_alert, + CBS *contents) { + if (contents == NULL) { + return true; + } + + CBS supported_group_list; + if (!CBS_get_u16_length_prefixed(contents, &supported_group_list) || + CBS_len(&supported_group_list) == 0 || + CBS_len(contents) != 0 || + !parse_u16_array(&supported_group_list, &hs->peer_supported_group_list)) { + return false; + } + + return true; +} + +// Token Binding +// +// https://tools.ietf.org/html/draft-ietf-tokbind-negotiation-10 + +// The Token Binding version number currently matches the draft number of +// draft-ietf-tokbind-protocol, and when published as an RFC it will be 0x0100. +// Since there are no wire changes to the protocol from draft 13 through the +// current draft (16), this implementation supports all versions in that range. +static uint16_t kTokenBindingMaxVersion = 16; +static uint16_t kTokenBindingMinVersion = 13; + +static bool ext_token_binding_add_clienthello(SSL_HANDSHAKE *hs, CBB *out) { + SSL *const ssl = hs->ssl; + if (ssl->token_binding_params == nullptr || SSL_is_dtls(ssl)) { + return true; + } + + CBB contents, params; + if (!CBB_add_u16(out, TLSEXT_TYPE_token_binding) || + !CBB_add_u16_length_prefixed(out, &contents) || + !CBB_add_u16(&contents, kTokenBindingMaxVersion) || + !CBB_add_u8_length_prefixed(&contents, ¶ms) || + !CBB_add_bytes(¶ms, ssl->token_binding_params, + ssl->token_binding_params_len) || + !CBB_flush(out)) { + return false; + } + + return true; +} + +static bool ext_token_binding_parse_serverhello(SSL_HANDSHAKE *hs, + uint8_t *out_alert, + CBS *contents) { + SSL *const ssl = hs->ssl; + if (contents == nullptr) { + return true; + } + + CBS params_list; + uint16_t version; + uint8_t param; + if (!CBS_get_u16(contents, &version) || + !CBS_get_u8_length_prefixed(contents, ¶ms_list) || + !CBS_get_u8(¶ms_list, ¶m) || + CBS_len(¶ms_list) > 0 || + CBS_len(contents) > 0) { + *out_alert = SSL_AD_DECODE_ERROR; + return false; + } + + // The server-negotiated version must be less than or equal to our version. + if (version > kTokenBindingMaxVersion) { + *out_alert = SSL_AD_ILLEGAL_PARAMETER; + return false; + } + + // If the server-selected version is less than what we support, then Token + // Binding wasn't negotiated (but the extension was parsed successfully). + if (version < kTokenBindingMinVersion) { + return true; + } + + for (size_t i = 0; i < ssl->token_binding_params_len; ++i) { + if (param == ssl->token_binding_params[i]) { + ssl->negotiated_token_binding_param = param; + ssl->token_binding_negotiated = true; + return true; + } + } + + *out_alert = SSL_AD_ILLEGAL_PARAMETER; + return false; +} + +// select_tb_param looks for the first token binding param in +// |ssl->token_binding_params| that is also in |params| and puts it in +// |ssl->negotiated_token_binding_param|. It returns true if a token binding +// param is found, and false otherwise. +static bool select_tb_param(SSL *ssl, Span peer_params) { + for (size_t i = 0; i < ssl->token_binding_params_len; ++i) { + uint8_t tb_param = ssl->token_binding_params[i]; + for (uint8_t peer_param : peer_params) { + if (tb_param == peer_param) { + ssl->negotiated_token_binding_param = tb_param; + return true; + } + } + } + return false; +} + +static bool ext_token_binding_parse_clienthello(SSL_HANDSHAKE *hs, + uint8_t *out_alert, + CBS *contents) { + SSL *const ssl = hs->ssl; + if (contents == nullptr || ssl->token_binding_params == nullptr) { + return true; + } + + CBS params; + uint16_t version; + if (!CBS_get_u16(contents, &version) || + !CBS_get_u8_length_prefixed(contents, ¶ms) || + CBS_len(¶ms) == 0 || + CBS_len(contents) > 0) { + *out_alert = SSL_AD_DECODE_ERROR; + return false; + } + + // If the client-selected version is less than what we support, then Token + // Binding wasn't negotiated (but the extension was parsed successfully). + if (version < kTokenBindingMinVersion) { + return true; + } + + // If the client-selected version is higher than we support, use our max + // version. Otherwise, use the client's version. + hs->negotiated_token_binding_version = + std::min(version, kTokenBindingMaxVersion); + if (!select_tb_param(ssl, params)) { + return true; + } + + ssl->token_binding_negotiated = true; + return true; +} + +static bool ext_token_binding_add_serverhello(SSL_HANDSHAKE *hs, CBB *out) { + SSL *const ssl = hs->ssl; + + if (!ssl->token_binding_negotiated) { + return true; + } + + CBB contents, params; + if (!CBB_add_u16(out, TLSEXT_TYPE_token_binding) || + !CBB_add_u16_length_prefixed(out, &contents) || + !CBB_add_u16(&contents, hs->negotiated_token_binding_version) || + !CBB_add_u8_length_prefixed(&contents, ¶ms) || + !CBB_add_u8(¶ms, ssl->negotiated_token_binding_param) || + !CBB_flush(out)) { + return false; + } + + return true; +} + +// QUIC Transport Parameters + +static bool ext_quic_transport_params_add_clienthello(SSL_HANDSHAKE *hs, + CBB *out) { + SSL *const ssl = hs->ssl; + if (!ssl->quic_transport_params || hs->max_version <= TLS1_2_VERSION) { + return true; + } + + CBB contents; + if (!CBB_add_u16(out, TLSEXT_TYPE_quic_transport_parameters) || + !CBB_add_u16_length_prefixed(out, &contents) || + !CBB_add_bytes(&contents, ssl->quic_transport_params, + ssl->quic_transport_params_len) || + !CBB_flush(out)) { + return false; + } + return true; +} + +static bool ext_quic_transport_params_parse_serverhello(SSL_HANDSHAKE *hs, + uint8_t *out_alert, + CBS *contents) { + SSL *const ssl = hs->ssl; + if (contents == nullptr) { + return true; + } + // QUIC requires TLS 1.3. + if (ssl_protocol_version(ssl) < TLS1_3_VERSION) { + *out_alert = SSL_AD_UNSUPPORTED_EXTENSION; + return false; + } + + return ssl->s3->peer_quic_transport_params.CopyFrom(*contents); +} + +static bool ext_quic_transport_params_parse_clienthello(SSL_HANDSHAKE *hs, + uint8_t *out_alert, + CBS *contents) { + SSL *const ssl = hs->ssl; + if (!contents || !ssl->quic_transport_params) { + return true; + } + // Ignore the extension before TLS 1.3. + if (ssl_protocol_version(ssl) < TLS1_3_VERSION) { + return true; + } + + return ssl->s3->peer_quic_transport_params.CopyFrom(*contents); +} + +static bool ext_quic_transport_params_add_serverhello(SSL_HANDSHAKE *hs, + CBB *out) { + SSL *const ssl = hs->ssl; + if (!ssl->quic_transport_params) { + return true; + } + + CBB contents; + if (!CBB_add_u16(out, TLSEXT_TYPE_quic_transport_parameters) || + !CBB_add_u16_length_prefixed(out, &contents) || + !CBB_add_bytes(&contents, ssl->quic_transport_params, + ssl->quic_transport_params_len) || + !CBB_flush(out)) { + return false; + } + + return true; +} + + +// kExtensions contains all the supported extensions. +static const struct tls_extension kExtensions[] = { + { + TLSEXT_TYPE_renegotiate, + NULL, + ext_ri_add_clienthello, + ext_ri_parse_serverhello, + ext_ri_parse_clienthello, + ext_ri_add_serverhello, + }, + { + TLSEXT_TYPE_server_name, + NULL, + ext_sni_add_clienthello, + ext_sni_parse_serverhello, + ext_sni_parse_clienthello, + ext_sni_add_serverhello, + }, + { + TLSEXT_TYPE_extended_master_secret, + NULL, + ext_ems_add_clienthello, + ext_ems_parse_serverhello, + ext_ems_parse_clienthello, + ext_ems_add_serverhello, + }, + { + TLSEXT_TYPE_session_ticket, + NULL, + ext_ticket_add_clienthello, + ext_ticket_parse_serverhello, + // Ticket extension client parsing is handled in ssl_session.c + ignore_parse_clienthello, + ext_ticket_add_serverhello, + }, + { + TLSEXT_TYPE_signature_algorithms, + NULL, + ext_sigalgs_add_clienthello, + forbid_parse_serverhello, + ext_sigalgs_parse_clienthello, + dont_add_serverhello, + }, + { + TLSEXT_TYPE_status_request, + NULL, + ext_ocsp_add_clienthello, + ext_ocsp_parse_serverhello, + ext_ocsp_parse_clienthello, + ext_ocsp_add_serverhello, + }, + { + TLSEXT_TYPE_next_proto_neg, + NULL, + ext_npn_add_clienthello, + ext_npn_parse_serverhello, + ext_npn_parse_clienthello, + ext_npn_add_serverhello, + }, + { + TLSEXT_TYPE_certificate_timestamp, + NULL, + ext_sct_add_clienthello, + ext_sct_parse_serverhello, + ext_sct_parse_clienthello, + ext_sct_add_serverhello, + }, + { + TLSEXT_TYPE_application_layer_protocol_negotiation, + NULL, + ext_alpn_add_clienthello, + ext_alpn_parse_serverhello, + // ALPN is negotiated late in |ssl_negotiate_alpn|. + ignore_parse_clienthello, + ext_alpn_add_serverhello, + }, + { + TLSEXT_TYPE_channel_id, + ext_channel_id_init, + ext_channel_id_add_clienthello, + ext_channel_id_parse_serverhello, + ext_channel_id_parse_clienthello, + ext_channel_id_add_serverhello, + }, + { + TLSEXT_TYPE_srtp, + ext_srtp_init, + ext_srtp_add_clienthello, + ext_srtp_parse_serverhello, + ext_srtp_parse_clienthello, + ext_srtp_add_serverhello, + }, + { + TLSEXT_TYPE_ec_point_formats, + NULL, + ext_ec_point_add_clienthello, + ext_ec_point_parse_serverhello, + ext_ec_point_parse_clienthello, + ext_ec_point_add_serverhello, + }, + { + TLSEXT_TYPE_key_share, + NULL, + ext_key_share_add_clienthello, + forbid_parse_serverhello, + ignore_parse_clienthello, + dont_add_serverhello, + }, + { + TLSEXT_TYPE_psk_key_exchange_modes, + NULL, + ext_psk_key_exchange_modes_add_clienthello, + forbid_parse_serverhello, + ext_psk_key_exchange_modes_parse_clienthello, + dont_add_serverhello, + }, + { + TLSEXT_TYPE_early_data, + NULL, + ext_early_data_add_clienthello, + ext_early_data_parse_serverhello, + ext_early_data_parse_clienthello, + ext_early_data_add_serverhello, + }, + { + TLSEXT_TYPE_supported_versions, + NULL, + ext_supported_versions_add_clienthello, + forbid_parse_serverhello, + ignore_parse_clienthello, + dont_add_serverhello, + }, + { + TLSEXT_TYPE_cookie, + NULL, + ext_cookie_add_clienthello, + forbid_parse_serverhello, + ignore_parse_clienthello, + dont_add_serverhello, + }, + { + TLSEXT_TYPE_dummy_pq_padding, + NULL, + ext_dummy_pq_padding_add_clienthello, + ext_dummy_pq_padding_parse_serverhello, + ext_dummy_pq_padding_parse_clienthello, + ext_dummy_pq_padding_add_serverhello, + }, + { + TLSEXT_TYPE_quic_transport_parameters, + NULL, + ext_quic_transport_params_add_clienthello, + ext_quic_transport_params_parse_serverhello, + ext_quic_transport_params_parse_clienthello, + ext_quic_transport_params_add_serverhello, + }, + // The final extension must be non-empty. WebSphere Application Server 7.0 is + // intolerant to the last extension being zero-length. See + // https://crbug.com/363583. + { + TLSEXT_TYPE_supported_groups, + NULL, + ext_supported_groups_add_clienthello, + ext_supported_groups_parse_serverhello, + ext_supported_groups_parse_clienthello, + dont_add_serverhello, + }, + { + TLSEXT_TYPE_token_binding, + NULL, + ext_token_binding_add_clienthello, + ext_token_binding_parse_serverhello, + ext_token_binding_parse_clienthello, + ext_token_binding_add_serverhello, + }, +}; + +#define kNumExtensions (sizeof(kExtensions) / sizeof(struct tls_extension)) + +static_assert(kNumExtensions <= + sizeof(((SSL_HANDSHAKE *)NULL)->extensions.sent) * 8, + "too many extensions for sent bitset"); +static_assert(kNumExtensions <= + sizeof(((SSL_HANDSHAKE *)NULL)->extensions.received) * 8, + "too many extensions for received bitset"); + +static const struct tls_extension *tls_extension_find(uint32_t *out_index, + uint16_t value) { + unsigned i; + for (i = 0; i < kNumExtensions; i++) { + if (kExtensions[i].value == value) { + *out_index = i; + return &kExtensions[i]; + } + } + + return NULL; +} + +int ssl_add_clienthello_tlsext(SSL_HANDSHAKE *hs, CBB *out, size_t header_len) { + SSL *const ssl = hs->ssl; + // Don't add extensions for SSLv3 unless doing secure renegotiation. + if (hs->client_version == SSL3_VERSION && + !ssl->s3->send_connection_binding) { + return 1; + } + + CBB extensions; + if (!CBB_add_u16_length_prefixed(out, &extensions)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return 0; + } + + hs->extensions.sent = 0; + hs->custom_extensions.sent = 0; + + for (size_t i = 0; i < kNumExtensions; i++) { + if (kExtensions[i].init != NULL) { + kExtensions[i].init(hs); + } + } + + uint16_t grease_ext1 = 0; + if (ssl->ctx->grease_enabled) { + // Add a fake empty extension. See draft-davidben-tls-grease-01. + grease_ext1 = ssl_get_grease_value(hs, ssl_grease_extension1); + if (!CBB_add_u16(&extensions, grease_ext1) || + !CBB_add_u16(&extensions, 0 /* zero length */)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return 0; + } + } + + for (size_t i = 0; i < kNumExtensions; i++) { + const size_t len_before = CBB_len(&extensions); + if (!kExtensions[i].add_clienthello(hs, &extensions)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_ERROR_ADDING_EXTENSION); + ERR_add_error_dataf("extension %u", (unsigned)kExtensions[i].value); + return 0; + } + + if (CBB_len(&extensions) != len_before) { + hs->extensions.sent |= (1u << i); + } + } + + if (!custom_ext_add_clienthello(hs, &extensions)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return 0; + } + + if (ssl->ctx->grease_enabled) { + // Add a fake non-empty extension. See draft-davidben-tls-grease-01. + uint16_t grease_ext2 = ssl_get_grease_value(hs, ssl_grease_extension2); + + // The two fake extensions must not have the same value. GREASE values are + // of the form 0x1a1a, 0x2a2a, 0x3a3a, etc., so XOR to generate a different + // one. + if (grease_ext1 == grease_ext2) { + grease_ext2 ^= 0x1010; + } + + if (!CBB_add_u16(&extensions, grease_ext2) || + !CBB_add_u16(&extensions, 1 /* one byte length */) || + !CBB_add_u8(&extensions, 0 /* single zero byte as contents */)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return 0; + } + } + + if (!SSL_is_dtls(ssl)) { + size_t psk_extension_len = ext_pre_shared_key_clienthello_length(hs); + header_len += 2 + CBB_len(&extensions) + psk_extension_len; + if (header_len > 0xff && header_len < 0x200) { + // Add padding to workaround bugs in F5 terminators. See RFC 7685. + // + // NB: because this code works out the length of all existing extensions + // it MUST always appear last. + size_t padding_len = 0x200 - header_len; + // Extensions take at least four bytes to encode. Always include at least + // one byte of data if including the extension. WebSphere Application + // Server 7.0 is intolerant to the last extension being zero-length. See + // https://crbug.com/363583. + if (padding_len >= 4 + 1) { + padding_len -= 4; + } else { + padding_len = 1; + } + + uint8_t *padding_bytes; + if (!CBB_add_u16(&extensions, TLSEXT_TYPE_padding) || + !CBB_add_u16(&extensions, padding_len) || + !CBB_add_space(&extensions, &padding_bytes, padding_len)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return 0; + } + + OPENSSL_memset(padding_bytes, 0, padding_len); + } + } + + // The PSK extension must be last, including after the padding. + if (!ext_pre_shared_key_add_clienthello(hs, &extensions)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return 0; + } + + // Discard empty extensions blocks. + if (CBB_len(&extensions) == 0) { + CBB_discard_child(out); + } + + return CBB_flush(out); +} + +int ssl_add_serverhello_tlsext(SSL_HANDSHAKE *hs, CBB *out) { + SSL *const ssl = hs->ssl; + CBB extensions; + if (!CBB_add_u16_length_prefixed(out, &extensions)) { + goto err; + } + + for (unsigned i = 0; i < kNumExtensions; i++) { + if (!(hs->extensions.received & (1u << i))) { + // Don't send extensions that were not received. + continue; + } + + if (!kExtensions[i].add_serverhello(hs, &extensions)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_ERROR_ADDING_EXTENSION); + ERR_add_error_dataf("extension %u", (unsigned)kExtensions[i].value); + goto err; + } + } + + if (!custom_ext_add_serverhello(hs, &extensions)) { + goto err; + } + + // Discard empty extensions blocks before TLS 1.3. + if (ssl_protocol_version(ssl) < TLS1_3_VERSION && + CBB_len(&extensions) == 0) { + CBB_discard_child(out); + } + + return CBB_flush(out); + +err: + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return 0; +} + +static int ssl_scan_clienthello_tlsext(SSL_HANDSHAKE *hs, + const SSL_CLIENT_HELLO *client_hello, + int *out_alert) { + SSL *const ssl = hs->ssl; + for (size_t i = 0; i < kNumExtensions; i++) { + if (kExtensions[i].init != NULL) { + kExtensions[i].init(hs); + } + } + + hs->extensions.received = 0; + hs->custom_extensions.received = 0; + CBS extensions; + CBS_init(&extensions, client_hello->extensions, client_hello->extensions_len); + while (CBS_len(&extensions) != 0) { + uint16_t type; + CBS extension; + + // Decode the next extension. + if (!CBS_get_u16(&extensions, &type) || + !CBS_get_u16_length_prefixed(&extensions, &extension)) { + *out_alert = SSL_AD_DECODE_ERROR; + return 0; + } + + // RFC 5746 made the existence of extensions in SSL 3.0 somewhat + // ambiguous. Ignore all but the renegotiation_info extension. + if (ssl->version == SSL3_VERSION && type != TLSEXT_TYPE_renegotiate) { + continue; + } + + unsigned ext_index; + const struct tls_extension *const ext = + tls_extension_find(&ext_index, type); + + if (ext == NULL) { + if (!custom_ext_parse_clienthello(hs, out_alert, type, &extension)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_ERROR_PARSING_EXTENSION); + return 0; + } + continue; + } + + hs->extensions.received |= (1u << ext_index); + uint8_t alert = SSL_AD_DECODE_ERROR; + if (!ext->parse_clienthello(hs, &alert, &extension)) { + *out_alert = alert; + OPENSSL_PUT_ERROR(SSL, SSL_R_ERROR_PARSING_EXTENSION); + ERR_add_error_dataf("extension %u", (unsigned)type); + return 0; + } + } + + for (size_t i = 0; i < kNumExtensions; i++) { + if (hs->extensions.received & (1u << i)) { + continue; + } + + CBS *contents = NULL, fake_contents; + static const uint8_t kFakeRenegotiateExtension[] = {0}; + if (kExtensions[i].value == TLSEXT_TYPE_renegotiate && + ssl_client_cipher_list_contains_cipher(client_hello, + SSL3_CK_SCSV & 0xffff)) { + // The renegotiation SCSV was received so pretend that we received a + // renegotiation extension. + CBS_init(&fake_contents, kFakeRenegotiateExtension, + sizeof(kFakeRenegotiateExtension)); + contents = &fake_contents; + hs->extensions.received |= (1u << i); + } + + // Extension wasn't observed so call the callback with a NULL + // parameter. + uint8_t alert = SSL_AD_DECODE_ERROR; + if (!kExtensions[i].parse_clienthello(hs, &alert, contents)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_MISSING_EXTENSION); + ERR_add_error_dataf("extension %u", (unsigned)kExtensions[i].value); + *out_alert = alert; + return 0; + } + } + + return 1; +} + +int ssl_parse_clienthello_tlsext(SSL_HANDSHAKE *hs, + const SSL_CLIENT_HELLO *client_hello) { + SSL *const ssl = hs->ssl; + int alert = SSL_AD_DECODE_ERROR; + if (ssl_scan_clienthello_tlsext(hs, client_hello, &alert) <= 0) { + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + return 0; + } + + if (ssl_check_clienthello_tlsext(hs) <= 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_CLIENTHELLO_TLSEXT); + return 0; + } + + return 1; +} + +static int ssl_scan_serverhello_tlsext(SSL_HANDSHAKE *hs, CBS *cbs, + int *out_alert) { + SSL *const ssl = hs->ssl; + // Before TLS 1.3, ServerHello extensions blocks may be omitted if empty. + if (CBS_len(cbs) == 0 && ssl_protocol_version(ssl) < TLS1_3_VERSION) { + return 1; + } + + // Decode the extensions block and check it is valid. + CBS extensions; + if (!CBS_get_u16_length_prefixed(cbs, &extensions) || + !tls1_check_duplicate_extensions(&extensions)) { + *out_alert = SSL_AD_DECODE_ERROR; + return 0; + } + + uint32_t received = 0; + while (CBS_len(&extensions) != 0) { + uint16_t type; + CBS extension; + + // Decode the next extension. + if (!CBS_get_u16(&extensions, &type) || + !CBS_get_u16_length_prefixed(&extensions, &extension)) { + *out_alert = SSL_AD_DECODE_ERROR; + return 0; + } + + unsigned ext_index; + const struct tls_extension *const ext = + tls_extension_find(&ext_index, type); + + if (ext == NULL) { + hs->received_custom_extension = true; + if (!custom_ext_parse_serverhello(hs, out_alert, type, &extension)) { + return 0; + } + continue; + } + + static_assert(kNumExtensions <= sizeof(hs->extensions.sent) * 8, + "too many bits"); + + if (!(hs->extensions.sent & (1u << ext_index)) && + type != TLSEXT_TYPE_renegotiate) { + // If the extension was never sent then it is illegal, except for the + // renegotiation extension which, in SSL 3.0, is signaled via SCSV. + OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION); + ERR_add_error_dataf("extension :%u", (unsigned)type); + *out_alert = SSL_AD_UNSUPPORTED_EXTENSION; + return 0; + } + + received |= (1u << ext_index); + + uint8_t alert = SSL_AD_DECODE_ERROR; + if (!ext->parse_serverhello(hs, &alert, &extension)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_ERROR_PARSING_EXTENSION); + ERR_add_error_dataf("extension %u", (unsigned)type); + *out_alert = alert; + return 0; + } + } + + for (size_t i = 0; i < kNumExtensions; i++) { + if (!(received & (1u << i))) { + // Extension wasn't observed so call the callback with a NULL + // parameter. + uint8_t alert = SSL_AD_DECODE_ERROR; + if (!kExtensions[i].parse_serverhello(hs, &alert, NULL)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_MISSING_EXTENSION); + ERR_add_error_dataf("extension %u", (unsigned)kExtensions[i].value); + *out_alert = alert; + return 0; + } + } + } + + return 1; +} + +static int ssl_check_clienthello_tlsext(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + + if (ssl->token_binding_negotiated && + !(SSL_get_secure_renegotiation_support(ssl) && + SSL_get_extms_support(ssl))) { + OPENSSL_PUT_ERROR(SSL, SSL_R_NEGOTIATED_TB_WITHOUT_EMS_OR_RI); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNSUPPORTED_EXTENSION); + return -1; + } + + int ret = SSL_TLSEXT_ERR_NOACK; + int al = SSL_AD_UNRECOGNIZED_NAME; + + if (ssl->ctx->tlsext_servername_callback != 0) { + ret = ssl->ctx->tlsext_servername_callback(ssl, &al, + ssl->ctx->tlsext_servername_arg); + } else if (ssl->session_ctx->tlsext_servername_callback != 0) { + ret = ssl->session_ctx->tlsext_servername_callback( + ssl, &al, ssl->session_ctx->tlsext_servername_arg); + } + + switch (ret) { + case SSL_TLSEXT_ERR_ALERT_FATAL: + ssl_send_alert(ssl, SSL3_AL_FATAL, al); + return -1; + + case SSL_TLSEXT_ERR_NOACK: + hs->should_ack_sni = false; + return 1; + + default: + return 1; + } +} + +int ssl_parse_serverhello_tlsext(SSL_HANDSHAKE *hs, CBS *cbs) { + SSL *const ssl = hs->ssl; + int alert = SSL_AD_DECODE_ERROR; + if (ssl_scan_serverhello_tlsext(hs, cbs, &alert) <= 0) { + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + return 0; + } + + return 1; +} + +static enum ssl_ticket_aead_result_t decrypt_ticket_with_cipher_ctx( + uint8_t **out, size_t *out_len, EVP_CIPHER_CTX *cipher_ctx, + HMAC_CTX *hmac_ctx, const uint8_t *ticket, size_t ticket_len) { + size_t iv_len = EVP_CIPHER_CTX_iv_length(cipher_ctx); + + // Check the MAC at the end of the ticket. + uint8_t mac[EVP_MAX_MD_SIZE]; + size_t mac_len = HMAC_size(hmac_ctx); + if (ticket_len < SSL_TICKET_KEY_NAME_LEN + iv_len + 1 + mac_len) { + // The ticket must be large enough for key name, IV, data, and MAC. + return ssl_ticket_aead_ignore_ticket; + } + HMAC_Update(hmac_ctx, ticket, ticket_len - mac_len); + HMAC_Final(hmac_ctx, mac, NULL); + int mac_ok = + CRYPTO_memcmp(mac, ticket + (ticket_len - mac_len), mac_len) == 0; +#if defined(BORINGSSL_UNSAFE_FUZZER_MODE) + mac_ok = 1; +#endif + if (!mac_ok) { + return ssl_ticket_aead_ignore_ticket; + } + + // Decrypt the session data. + const uint8_t *ciphertext = ticket + SSL_TICKET_KEY_NAME_LEN + iv_len; + size_t ciphertext_len = ticket_len - SSL_TICKET_KEY_NAME_LEN - iv_len - + mac_len; + UniquePtr plaintext((uint8_t *)OPENSSL_malloc(ciphertext_len)); + if (!plaintext) { + return ssl_ticket_aead_error; + } + size_t plaintext_len; +#if defined(BORINGSSL_UNSAFE_FUZZER_MODE) + OPENSSL_memcpy(plaintext.get(), ciphertext, ciphertext_len); + plaintext_len = ciphertext_len; +#else + if (ciphertext_len >= INT_MAX) { + return ssl_ticket_aead_ignore_ticket; + } + int len1, len2; + if (!EVP_DecryptUpdate(cipher_ctx, plaintext.get(), &len1, ciphertext, + (int)ciphertext_len) || + !EVP_DecryptFinal_ex(cipher_ctx, plaintext.get() + len1, &len2)) { + ERR_clear_error(); + return ssl_ticket_aead_ignore_ticket; + } + plaintext_len = (size_t)(len1) + len2; +#endif + + *out = plaintext.release(); + *out_len = plaintext_len; + return ssl_ticket_aead_success; +} + +static enum ssl_ticket_aead_result_t ssl_decrypt_ticket_with_cb( + SSL *ssl, uint8_t **out, size_t *out_len, bool *out_renew_ticket, + const uint8_t *ticket, size_t ticket_len) { + assert(ticket_len >= SSL_TICKET_KEY_NAME_LEN + EVP_MAX_IV_LENGTH); + ScopedEVP_CIPHER_CTX cipher_ctx; + ScopedHMAC_CTX hmac_ctx; + const uint8_t *iv = ticket + SSL_TICKET_KEY_NAME_LEN; + int cb_ret = ssl->session_ctx->tlsext_ticket_key_cb( + ssl, (uint8_t *)ticket /* name */, (uint8_t *)iv, cipher_ctx.get(), + hmac_ctx.get(), 0 /* decrypt */); + if (cb_ret < 0) { + return ssl_ticket_aead_error; + } else if (cb_ret == 0) { + return ssl_ticket_aead_ignore_ticket; + } else if (cb_ret == 2) { + *out_renew_ticket = true; + } else { + assert(cb_ret == 1); + } + return decrypt_ticket_with_cipher_ctx(out, out_len, cipher_ctx.get(), + hmac_ctx.get(), ticket, ticket_len); +} + +static enum ssl_ticket_aead_result_t ssl_decrypt_ticket_with_ticket_keys( + SSL *ssl, uint8_t **out, size_t *out_len, const uint8_t *ticket, + size_t ticket_len) { + assert(ticket_len >= SSL_TICKET_KEY_NAME_LEN + EVP_MAX_IV_LENGTH); + SSL_CTX *ctx = ssl->session_ctx; + + // Rotate the ticket key if necessary. + if (!ssl_ctx_rotate_ticket_encryption_key(ctx)) { + return ssl_ticket_aead_error; + } + + // Pick the matching ticket key and decrypt. + ScopedEVP_CIPHER_CTX cipher_ctx; + ScopedHMAC_CTX hmac_ctx; + { + MutexReadLock lock(&ctx->lock); + const tlsext_ticket_key *key; + if (ctx->tlsext_ticket_key_current && + !OPENSSL_memcmp(ctx->tlsext_ticket_key_current->name, ticket, + SSL_TICKET_KEY_NAME_LEN)) { + key = ctx->tlsext_ticket_key_current; + } else if (ctx->tlsext_ticket_key_prev && + !OPENSSL_memcmp(ctx->tlsext_ticket_key_prev->name, ticket, + SSL_TICKET_KEY_NAME_LEN)) { + key = ctx->tlsext_ticket_key_prev; + } else { + return ssl_ticket_aead_ignore_ticket; + } + const uint8_t *iv = ticket + SSL_TICKET_KEY_NAME_LEN; + if (!HMAC_Init_ex(hmac_ctx.get(), key->hmac_key, sizeof(key->hmac_key), + tlsext_tick_md(), NULL) || + !EVP_DecryptInit_ex(cipher_ctx.get(), EVP_aes_128_cbc(), NULL, + key->aes_key, iv)) { + return ssl_ticket_aead_error; + } + } + return decrypt_ticket_with_cipher_ctx(out, out_len, cipher_ctx.get(), + hmac_ctx.get(), ticket, ticket_len); +} + +static enum ssl_ticket_aead_result_t ssl_decrypt_ticket_with_method( + SSL *ssl, uint8_t **out, size_t *out_len, bool *out_renew_ticket, + const uint8_t *ticket, size_t ticket_len) { + uint8_t *plaintext = (uint8_t *)OPENSSL_malloc(ticket_len); + if (plaintext == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return ssl_ticket_aead_error; + } + + size_t plaintext_len; + const enum ssl_ticket_aead_result_t result = + ssl->session_ctx->ticket_aead_method->open( + ssl, plaintext, &plaintext_len, ticket_len, ticket, ticket_len); + + if (result == ssl_ticket_aead_success) { + *out = plaintext; + plaintext = NULL; + *out_len = plaintext_len; + } + + OPENSSL_free(plaintext); + return result; +} + +enum ssl_ticket_aead_result_t ssl_process_ticket( + SSL *ssl, UniquePtr *out_session, bool *out_renew_ticket, + const uint8_t *ticket, size_t ticket_len, const uint8_t *session_id, + size_t session_id_len) { + *out_renew_ticket = false; + out_session->reset(); + + if ((SSL_get_options(ssl) & SSL_OP_NO_TICKET) || + session_id_len > SSL_MAX_SSL_SESSION_ID_LENGTH) { + return ssl_ticket_aead_ignore_ticket; + } + + uint8_t *plaintext = NULL; + size_t plaintext_len; + enum ssl_ticket_aead_result_t result; + if (ssl->session_ctx->ticket_aead_method != NULL) { + result = ssl_decrypt_ticket_with_method( + ssl, &plaintext, &plaintext_len, out_renew_ticket, ticket, ticket_len); + } else { + // Ensure there is room for the key name and the largest IV + // |tlsext_ticket_key_cb| may try to consume. The real limit may be lower, + // but the maximum IV length should be well under the minimum size for the + // session material and HMAC. + if (ticket_len < SSL_TICKET_KEY_NAME_LEN + EVP_MAX_IV_LENGTH) { + return ssl_ticket_aead_ignore_ticket; + } + if (ssl->session_ctx->tlsext_ticket_key_cb != NULL) { + result = ssl_decrypt_ticket_with_cb(ssl, &plaintext, &plaintext_len, + out_renew_ticket, ticket, ticket_len); + } else { + result = ssl_decrypt_ticket_with_ticket_keys( + ssl, &plaintext, &plaintext_len, ticket, ticket_len); + } + } + + if (result != ssl_ticket_aead_success) { + return result; + } + + // Decode the session. + UniquePtr session( + SSL_SESSION_from_bytes(plaintext, plaintext_len, ssl->ctx)); + OPENSSL_free(plaintext); + + if (!session) { + ERR_clear_error(); // Don't leave an error on the queue. + return ssl_ticket_aead_ignore_ticket; + } + + // Copy the client's session ID into the new session, to denote the ticket has + // been accepted. + OPENSSL_memcpy(session->session_id, session_id, session_id_len); + session->session_id_length = session_id_len; + + *out_session = std::move(session); + return ssl_ticket_aead_success; +} + +bool tls1_parse_peer_sigalgs(SSL_HANDSHAKE *hs, const CBS *in_sigalgs) { + // Extension ignored for inappropriate versions + if (ssl_protocol_version(hs->ssl) < TLS1_2_VERSION) { + return true; + } + + return parse_u16_array(in_sigalgs, &hs->peer_sigalgs); +} + +bool tls1_get_legacy_signature_algorithm(uint16_t *out, const EVP_PKEY *pkey) { + switch (EVP_PKEY_id(pkey)) { + case EVP_PKEY_RSA: + *out = SSL_SIGN_RSA_PKCS1_MD5_SHA1; + return true; + case EVP_PKEY_EC: + *out = SSL_SIGN_ECDSA_SHA1; + return true; + default: + return false; + } +} + +bool tls1_choose_signature_algorithm(SSL_HANDSHAKE *hs, uint16_t *out) { + SSL *const ssl = hs->ssl; + CERT *cert = ssl->cert; + + // Before TLS 1.2, the signature algorithm isn't negotiated as part of the + // handshake. + if (ssl_protocol_version(ssl) < TLS1_2_VERSION) { + if (!tls1_get_legacy_signature_algorithm(out, hs->local_pubkey.get())) { + OPENSSL_PUT_ERROR(SSL, SSL_R_NO_COMMON_SIGNATURE_ALGORITHMS); + return false; + } + return true; + } + + Span sigalgs = kSignSignatureAlgorithms; + if (cert->sigalgs != nullptr) { + sigalgs = MakeConstSpan(cert->sigalgs, cert->num_sigalgs); + } + + Span peer_sigalgs = hs->peer_sigalgs; + if (peer_sigalgs.empty() && ssl_protocol_version(ssl) < TLS1_3_VERSION) { + // If the client didn't specify any signature_algorithms extension then + // we can assume that it supports SHA1. See + // http://tools.ietf.org/html/rfc5246#section-7.4.1.4.1 + static const uint16_t kDefaultPeerAlgorithms[] = {SSL_SIGN_RSA_PKCS1_SHA1, + SSL_SIGN_ECDSA_SHA1}; + peer_sigalgs = kDefaultPeerAlgorithms; + } + + for (uint16_t sigalg : sigalgs) { + // SSL_SIGN_RSA_PKCS1_MD5_SHA1 is an internal value and should never be + // negotiated. + if (sigalg == SSL_SIGN_RSA_PKCS1_MD5_SHA1 || + !ssl_private_key_supports_signature_algorithm(hs, sigalg)) { + continue; + } + + for (uint16_t peer_sigalg : peer_sigalgs) { + if (sigalg == peer_sigalg) { + *out = sigalg; + return true; + } + } + } + + OPENSSL_PUT_ERROR(SSL, SSL_R_NO_COMMON_SIGNATURE_ALGORITHMS); + return false; +} + +int tls1_verify_channel_id(SSL_HANDSHAKE *hs, const SSLMessage &msg) { + SSL *const ssl = hs->ssl; + // A Channel ID handshake message is structured to contain multiple + // extensions, but the only one that can be present is Channel ID. + uint16_t extension_type; + CBS channel_id = msg.body, extension; + if (!CBS_get_u16(&channel_id, &extension_type) || + !CBS_get_u16_length_prefixed(&channel_id, &extension) || + CBS_len(&channel_id) != 0 || + extension_type != TLSEXT_TYPE_channel_id || + CBS_len(&extension) != TLSEXT_CHANNEL_ID_SIZE) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return 0; + } + + UniquePtr p256(EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1)); + if (!p256) { + OPENSSL_PUT_ERROR(SSL, SSL_R_NO_P256_SUPPORT); + return 0; + } + + UniquePtr sig(ECDSA_SIG_new()); + UniquePtr x(BN_new()), y(BN_new()); + if (!sig || !x || !y) { + return 0; + } + + const uint8_t *p = CBS_data(&extension); + if (BN_bin2bn(p + 0, 32, x.get()) == NULL || + BN_bin2bn(p + 32, 32, y.get()) == NULL || + BN_bin2bn(p + 64, 32, sig->r) == NULL || + BN_bin2bn(p + 96, 32, sig->s) == NULL) { + return 0; + } + + UniquePtr key(EC_KEY_new()); + UniquePtr point(EC_POINT_new(p256.get())); + if (!key || !point || + !EC_POINT_set_affine_coordinates_GFp(p256.get(), point.get(), x.get(), + y.get(), nullptr) || + !EC_KEY_set_group(key.get(), p256.get()) || + !EC_KEY_set_public_key(key.get(), point.get())) { + return 0; + } + + uint8_t digest[EVP_MAX_MD_SIZE]; + size_t digest_len; + if (!tls1_channel_id_hash(hs, digest, &digest_len)) { + return 0; + } + + int sig_ok = ECDSA_do_verify(digest, digest_len, sig.get(), key.get()); +#if defined(BORINGSSL_UNSAFE_FUZZER_MODE) + sig_ok = 1; + ERR_clear_error(); +#endif + if (!sig_ok) { + OPENSSL_PUT_ERROR(SSL, SSL_R_CHANNEL_ID_SIGNATURE_INVALID); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECRYPT_ERROR); + ssl->s3->tlsext_channel_id_valid = false; + return 0; + } + + OPENSSL_memcpy(ssl->s3->tlsext_channel_id, p, 64); + return 1; +} + +bool tls1_write_channel_id(SSL_HANDSHAKE *hs, CBB *cbb) { + SSL *const ssl = hs->ssl; + uint8_t digest[EVP_MAX_MD_SIZE]; + size_t digest_len; + if (!tls1_channel_id_hash(hs, digest, &digest_len)) { + return false; + } + + EC_KEY *ec_key = EVP_PKEY_get0_EC_KEY(ssl->tlsext_channel_id_private); + if (ec_key == nullptr) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return false; + } + + UniquePtr x(BN_new()), y(BN_new()); + if (!x || !y || + !EC_POINT_get_affine_coordinates_GFp(EC_KEY_get0_group(ec_key), + EC_KEY_get0_public_key(ec_key), + x.get(), y.get(), nullptr)) { + return false; + } + + UniquePtr sig(ECDSA_do_sign(digest, digest_len, ec_key)); + if (!sig) { + return false; + } + + CBB child; + if (!CBB_add_u16(cbb, TLSEXT_TYPE_channel_id) || + !CBB_add_u16_length_prefixed(cbb, &child) || + !BN_bn2cbb_padded(&child, 32, x.get()) || + !BN_bn2cbb_padded(&child, 32, y.get()) || + !BN_bn2cbb_padded(&child, 32, sig->r) || + !BN_bn2cbb_padded(&child, 32, sig->s) || + !CBB_flush(cbb)) { + return false; + } + + return true; +} + +int tls1_channel_id_hash(SSL_HANDSHAKE *hs, uint8_t *out, size_t *out_len) { + SSL *const ssl = hs->ssl; + if (ssl_protocol_version(ssl) >= TLS1_3_VERSION) { + Array msg; + if (!tls13_get_cert_verify_signature_input(hs, &msg, + ssl_cert_verify_channel_id)) { + return 0; + } + SHA256(msg.data(), msg.size(), out); + *out_len = SHA256_DIGEST_LENGTH; + return 1; + } + + SHA256_CTX ctx; + + SHA256_Init(&ctx); + static const char kClientIDMagic[] = "TLS Channel ID signature"; + SHA256_Update(&ctx, kClientIDMagic, sizeof(kClientIDMagic)); + + if (ssl->session != NULL) { + static const char kResumptionMagic[] = "Resumption"; + SHA256_Update(&ctx, kResumptionMagic, sizeof(kResumptionMagic)); + if (ssl->session->original_handshake_hash_len == 0) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return 0; + } + SHA256_Update(&ctx, ssl->session->original_handshake_hash, + ssl->session->original_handshake_hash_len); + } + + uint8_t hs_hash[EVP_MAX_MD_SIZE]; + size_t hs_hash_len; + if (!hs->transcript.GetHash(hs_hash, &hs_hash_len)) { + return 0; + } + SHA256_Update(&ctx, hs_hash, (size_t)hs_hash_len); + SHA256_Final(out, &ctx); + *out_len = SHA256_DIGEST_LENGTH; + return 1; +} + +// tls1_record_handshake_hashes_for_channel_id records the current handshake +// hashes in |hs->new_session| so that Channel ID resumptions can sign that +// data. +int tls1_record_handshake_hashes_for_channel_id(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + // This function should never be called for a resumed session because the + // handshake hashes that we wish to record are for the original, full + // handshake. + if (ssl->session != NULL) { + return 0; + } + + static_assert( + sizeof(hs->new_session->original_handshake_hash) == EVP_MAX_MD_SIZE, + "original_handshake_hash is too small"); + + size_t digest_len; + if (!hs->transcript.GetHash(hs->new_session->original_handshake_hash, + &digest_len)) { + return 0; + } + + static_assert(EVP_MAX_MD_SIZE <= 0xff, + "EVP_MAX_MD_SIZE does not fit in uint8_t"); + hs->new_session->original_handshake_hash_len = (uint8_t)digest_len; + + return 1; +} + +int ssl_do_channel_id_callback(SSL *ssl) { + if (ssl->tlsext_channel_id_private != NULL || + ssl->ctx->channel_id_cb == NULL) { + return 1; + } + + EVP_PKEY *key = NULL; + ssl->ctx->channel_id_cb(ssl, &key); + if (key == NULL) { + // The caller should try again later. + return 1; + } + + int ret = SSL_set1_tls_channel_id(ssl, key); + EVP_PKEY_free(key); + return ret; +} + +int ssl_is_sct_list_valid(const CBS *contents) { + // Shallow parse the SCT list for sanity. By the RFC + // (https://tools.ietf.org/html/rfc6962#section-3.3) neither the list nor any + // of the SCTs may be empty. + CBS copy = *contents; + CBS sct_list; + if (!CBS_get_u16_length_prefixed(©, &sct_list) || + CBS_len(©) != 0 || + CBS_len(&sct_list) == 0) { + return 0; + } + + while (CBS_len(&sct_list) > 0) { + CBS sct; + if (!CBS_get_u16_length_prefixed(&sct_list, &sct) || + CBS_len(&sct) == 0) { + return 0; + } + } + + return 1; +} + +} // namespace bssl + +using namespace bssl; + +int SSL_early_callback_ctx_extension_get(const SSL_CLIENT_HELLO *client_hello, + uint16_t extension_type, + const uint8_t **out_data, + size_t *out_len) { + CBS cbs; + if (!ssl_client_hello_get_extension(client_hello, &cbs, extension_type)) { + return 0; + } + + *out_data = CBS_data(&cbs); + *out_len = CBS_len(&cbs); + return 1; +} + +void SSL_CTX_set_ed25519_enabled(SSL_CTX *ctx, int enabled) { + ctx->ed25519_enabled = !!enabled; +} + +int SSL_extension_supported(unsigned extension_value) { + uint32_t index; + return extension_value == TLSEXT_TYPE_padding || + tls_extension_find(&index, extension_value) != NULL; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/ssl/test/runner/curve25519/const_amd64.h b/FoodApp/Pods/BoringSSL-GRPC/ssl/test/runner/curve25519/const_amd64.h new file mode 100644 index 0000000..80ad222 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/ssl/test/runner/curve25519/const_amd64.h @@ -0,0 +1,8 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This code was translated into a form compatible with 6a from the public +// domain sources in SUPERCOP: http://bench.cr.yp.to/supercop.html + +#define REDMASK51 0x0007FFFFFFFFFFFF diff --git a/FoodApp/Pods/BoringSSL-GRPC/ssl/test/runner/curve25519/const_amd64.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/ssl/test/runner/curve25519/const_amd64.h.grpc_back new file mode 100644 index 0000000..80ad222 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/ssl/test/runner/curve25519/const_amd64.h.grpc_back @@ -0,0 +1,8 @@ +// Copyright 2012 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// This code was translated into a form compatible with 6a from the public +// domain sources in SUPERCOP: http://bench.cr.yp.to/supercop.html + +#define REDMASK51 0x0007FFFFFFFFFFFF diff --git a/FoodApp/Pods/BoringSSL-GRPC/ssl/tls13_both.cc b/FoodApp/Pods/BoringSSL-GRPC/ssl/tls13_both.cc new file mode 100644 index 0000000..0a36477 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/ssl/tls13_both.cc @@ -0,0 +1,559 @@ +/* Copyright (c) 2016, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include "../crypto/internal.h" +#include "internal.h" + + +namespace bssl { + +// kMaxKeyUpdates is the number of consecutive KeyUpdates that will be +// processed. Without this limit an attacker could force unbounded processing +// without being able to return application data. +static const uint8_t kMaxKeyUpdates = 32; + +const uint8_t kHelloRetryRequest[SSL3_RANDOM_SIZE] = { + 0xcf, 0x21, 0xad, 0x74, 0xe5, 0x9a, 0x61, 0x11, 0xbe, 0x1d, 0x8c, + 0x02, 0x1e, 0x65, 0xb8, 0x91, 0xc2, 0xa2, 0x11, 0x16, 0x7a, 0xbb, + 0x8c, 0x5e, 0x07, 0x9e, 0x09, 0xe2, 0xc8, 0xa8, 0x33, 0x9c, +}; + +// This value was selected by truncating the SHA-256 hash of "Draft TLS 1.3 +// Downgrade" to 8 bytes: +// +// echo -n 'Draft TLS 1.3 Downgrade' | sha256sum | head -c 16 +const uint8_t kDraftDowngradeRandom[8] = {0x95, 0xb9, 0x9f, 0x87, + 0x22, 0xfe, 0x9b, 0x64}; + + +bool tls13_get_cert_verify_signature_input( + SSL_HANDSHAKE *hs, Array *out, + enum ssl_cert_verify_context_t cert_verify_context) { + ScopedCBB cbb; + if (!CBB_init(cbb.get(), 64 + 33 + 1 + 2 * EVP_MAX_MD_SIZE)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return false; + } + + for (size_t i = 0; i < 64; i++) { + if (!CBB_add_u8(cbb.get(), 0x20)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return false; + } + } + + Span context; + if (cert_verify_context == ssl_cert_verify_server) { + static const char kContext[] = "TLS 1.3, server CertificateVerify"; + context = kContext; + } else if (cert_verify_context == ssl_cert_verify_client) { + static const char kContext[] = "TLS 1.3, client CertificateVerify"; + context = kContext; + } else if (cert_verify_context == ssl_cert_verify_channel_id) { + static const char kContext[] = "TLS 1.3, Channel ID"; + context = kContext; + } else { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return false; + } + + // Note |context| includes the NUL byte separator. + if (!CBB_add_bytes(cbb.get(), + reinterpret_cast(context.data()), + context.size())) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return false; + } + + uint8_t context_hash[EVP_MAX_MD_SIZE]; + size_t context_hash_len; + if (!hs->transcript.GetHash(context_hash, &context_hash_len) || + !CBB_add_bytes(cbb.get(), context_hash, context_hash_len) || + !CBBFinishArray(cbb.get(), out)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return false; + } + + return true; +} + +int tls13_process_certificate(SSL_HANDSHAKE *hs, const SSLMessage &msg, + int allow_anonymous) { + SSL *const ssl = hs->ssl; + CBS body = msg.body, context, certificate_list; + if (!CBS_get_u8_length_prefixed(&body, &context) || + CBS_len(&context) != 0 || + !CBS_get_u24_length_prefixed(&body, &certificate_list) || + CBS_len(&body) != 0) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + return 0; + } + + UniquePtr certs(sk_CRYPTO_BUFFER_new_null()); + if (!certs) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + + const bool retain_sha256 = + ssl->server && ssl->retain_only_sha256_of_client_certs; + UniquePtr pkey; + while (CBS_len(&certificate_list) > 0) { + CBS certificate, extensions; + if (!CBS_get_u24_length_prefixed(&certificate_list, &certificate) || + !CBS_get_u16_length_prefixed(&certificate_list, &extensions) || + CBS_len(&certificate) == 0) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + OPENSSL_PUT_ERROR(SSL, SSL_R_CERT_LENGTH_MISMATCH); + return 0; + } + + if (sk_CRYPTO_BUFFER_num(certs.get()) == 0) { + pkey = ssl_cert_parse_pubkey(&certificate); + if (!pkey) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + return 0; + } + // TLS 1.3 always uses certificate keys for signing thus the correct + // keyUsage is enforced. + if (!ssl_cert_check_digital_signature_key_usage(&certificate)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + return 0; + } + + if (retain_sha256) { + // Retain the hash of the leaf certificate if requested. + SHA256(CBS_data(&certificate), CBS_len(&certificate), + hs->new_session->peer_sha256); + } + } + + UniquePtr buf( + CRYPTO_BUFFER_new_from_CBS(&certificate, ssl->ctx->pool)); + if (!buf || + !PushToStack(certs.get(), std::move(buf))) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + + // Parse out the extensions. + bool have_status_request = false, have_sct = false; + CBS status_request, sct; + const SSL_EXTENSION_TYPE ext_types[] = { + {TLSEXT_TYPE_status_request, &have_status_request, &status_request}, + {TLSEXT_TYPE_certificate_timestamp, &have_sct, &sct}, + }; + + uint8_t alert = SSL_AD_DECODE_ERROR; + if (!ssl_parse_extensions(&extensions, &alert, ext_types, + OPENSSL_ARRAY_SIZE(ext_types), + 0 /* reject unknown */)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + return 0; + } + + // All Certificate extensions are parsed, but only the leaf extensions are + // stored. + if (have_status_request) { + if (ssl->server || !ssl->ocsp_stapling_enabled) { + OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNSUPPORTED_EXTENSION); + return 0; + } + + uint8_t status_type; + CBS ocsp_response; + if (!CBS_get_u8(&status_request, &status_type) || + status_type != TLSEXT_STATUSTYPE_ocsp || + !CBS_get_u24_length_prefixed(&status_request, &ocsp_response) || + CBS_len(&ocsp_response) == 0 || + CBS_len(&status_request) != 0) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return 0; + } + + if (sk_CRYPTO_BUFFER_num(certs.get()) == 1) { + CRYPTO_BUFFER_free(hs->new_session->ocsp_response); + hs->new_session->ocsp_response = + CRYPTO_BUFFER_new_from_CBS(&ocsp_response, ssl->ctx->pool); + if (hs->new_session->ocsp_response == nullptr) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return 0; + } + } + } + + if (have_sct) { + if (ssl->server || !ssl->signed_cert_timestamps_enabled) { + OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNSUPPORTED_EXTENSION); + return 0; + } + + if (!ssl_is_sct_list_valid(&sct)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_ERROR_PARSING_EXTENSION); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return 0; + } + + if (sk_CRYPTO_BUFFER_num(certs.get()) == 1) { + CRYPTO_BUFFER_free(hs->new_session->signed_cert_timestamp_list); + hs->new_session->signed_cert_timestamp_list = + CRYPTO_BUFFER_new_from_CBS(&sct, ssl->ctx->pool); + if (hs->new_session->signed_cert_timestamp_list == nullptr) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return 0; + } + } + } + } + + // Store a null certificate list rather than an empty one if the peer didn't + // send certificates. + if (sk_CRYPTO_BUFFER_num(certs.get()) == 0) { + certs.reset(); + } + + hs->peer_pubkey = std::move(pkey); + + sk_CRYPTO_BUFFER_pop_free(hs->new_session->certs, CRYPTO_BUFFER_free); + hs->new_session->certs = certs.release(); + + if (!ssl->ctx->x509_method->session_cache_objects(hs->new_session.get())) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return 0; + } + + if (sk_CRYPTO_BUFFER_num(hs->new_session->certs) == 0) { + if (!allow_anonymous) { + OPENSSL_PUT_ERROR(SSL, SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_CERTIFICATE_REQUIRED); + return 0; + } + + // OpenSSL returns X509_V_OK when no certificates are requested. This is + // classed by them as a bug, but it's assumed by at least NGINX. + hs->new_session->verify_result = X509_V_OK; + + // No certificate, so nothing more to do. + return 1; + } + + hs->new_session->peer_sha256_valid = retain_sha256; + return 1; +} + +int tls13_process_certificate_verify(SSL_HANDSHAKE *hs, const SSLMessage &msg) { + SSL *const ssl = hs->ssl; + if (hs->peer_pubkey == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return 0; + } + + CBS body = msg.body, signature; + uint16_t signature_algorithm; + if (!CBS_get_u16(&body, &signature_algorithm) || + !CBS_get_u16_length_prefixed(&body, &signature) || + CBS_len(&body) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return 0; + } + + uint8_t alert = SSL_AD_DECODE_ERROR; + if (!tls12_check_peer_sigalg(ssl, &alert, signature_algorithm)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + return 0; + } + hs->new_session->peer_signature_algorithm = signature_algorithm; + + Array input; + if (!tls13_get_cert_verify_signature_input( + hs, &input, + ssl->server ? ssl_cert_verify_client : ssl_cert_verify_server)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return 0; + } + + bool sig_ok = ssl_public_key_verify(ssl, signature, signature_algorithm, + hs->peer_pubkey.get(), input); +#if defined(BORINGSSL_UNSAFE_FUZZER_MODE) + sig_ok = true; + ERR_clear_error(); +#endif + if (!sig_ok) { + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SIGNATURE); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECRYPT_ERROR); + return 0; + } + + return 1; +} + +int tls13_process_finished(SSL_HANDSHAKE *hs, const SSLMessage &msg, + int use_saved_value) { + SSL *const ssl = hs->ssl; + uint8_t verify_data_buf[EVP_MAX_MD_SIZE]; + const uint8_t *verify_data; + size_t verify_data_len; + if (use_saved_value) { + assert(ssl->server); + verify_data = hs->expected_client_finished; + verify_data_len = hs->hash_len; + } else { + if (!tls13_finished_mac(hs, verify_data_buf, &verify_data_len, + !ssl->server)) { + return 0; + } + verify_data = verify_data_buf; + } + + int finished_ok = CBS_mem_equal(&msg.body, verify_data, verify_data_len); +#if defined(BORINGSSL_UNSAFE_FUZZER_MODE) + finished_ok = 1; +#endif + if (!finished_ok) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECRYPT_ERROR); + OPENSSL_PUT_ERROR(SSL, SSL_R_DIGEST_CHECK_FAILED); + return 0; + } + + return 1; +} + +int tls13_add_certificate(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + ScopedCBB cbb; + CBB body, certificate_list; + if (!ssl->method->init_message(ssl, cbb.get(), &body, SSL3_MT_CERTIFICATE) || + // The request context is always empty in the handshake. + !CBB_add_u8(&body, 0) || + !CBB_add_u24_length_prefixed(&body, &certificate_list)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return 0; + } + + if (!ssl_has_certificate(ssl)) { + return ssl_add_message_cbb(ssl, cbb.get()); + } + + CERT *cert = ssl->cert; + CRYPTO_BUFFER *leaf_buf = sk_CRYPTO_BUFFER_value(cert->chain, 0); + CBB leaf, extensions; + if (!CBB_add_u24_length_prefixed(&certificate_list, &leaf) || + !CBB_add_bytes(&leaf, CRYPTO_BUFFER_data(leaf_buf), + CRYPTO_BUFFER_len(leaf_buf)) || + !CBB_add_u16_length_prefixed(&certificate_list, &extensions)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return 0; + } + + if (hs->scts_requested && ssl->cert->signed_cert_timestamp_list != NULL) { + CBB contents; + if (!CBB_add_u16(&extensions, TLSEXT_TYPE_certificate_timestamp) || + !CBB_add_u16_length_prefixed(&extensions, &contents) || + !CBB_add_bytes( + &contents, + CRYPTO_BUFFER_data(ssl->cert->signed_cert_timestamp_list), + CRYPTO_BUFFER_len(ssl->cert->signed_cert_timestamp_list)) || + !CBB_flush(&extensions)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return 0; + } + } + + if (hs->ocsp_stapling_requested && + ssl->cert->ocsp_response != NULL) { + CBB contents, ocsp_response; + if (!CBB_add_u16(&extensions, TLSEXT_TYPE_status_request) || + !CBB_add_u16_length_prefixed(&extensions, &contents) || + !CBB_add_u8(&contents, TLSEXT_STATUSTYPE_ocsp) || + !CBB_add_u24_length_prefixed(&contents, &ocsp_response) || + !CBB_add_bytes(&ocsp_response, + CRYPTO_BUFFER_data(ssl->cert->ocsp_response), + CRYPTO_BUFFER_len(ssl->cert->ocsp_response)) || + !CBB_flush(&extensions)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return 0; + } + } + + for (size_t i = 1; i < sk_CRYPTO_BUFFER_num(cert->chain); i++) { + CRYPTO_BUFFER *cert_buf = sk_CRYPTO_BUFFER_value(cert->chain, i); + CBB child; + if (!CBB_add_u24_length_prefixed(&certificate_list, &child) || + !CBB_add_bytes(&child, CRYPTO_BUFFER_data(cert_buf), + CRYPTO_BUFFER_len(cert_buf)) || + !CBB_add_u16(&certificate_list, 0 /* no extensions */)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return 0; + } + } + + return ssl_add_message_cbb(ssl, cbb.get()); +} + +enum ssl_private_key_result_t tls13_add_certificate_verify(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + uint16_t signature_algorithm; + if (!tls1_choose_signature_algorithm(hs, &signature_algorithm)) { + return ssl_private_key_failure; + } + + ScopedCBB cbb; + CBB body; + if (!ssl->method->init_message(ssl, cbb.get(), &body, + SSL3_MT_CERTIFICATE_VERIFY) || + !CBB_add_u16(&body, signature_algorithm)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return ssl_private_key_failure; + } + + // Sign the digest. + CBB child; + const size_t max_sig_len = EVP_PKEY_size(hs->local_pubkey.get()); + uint8_t *sig; + size_t sig_len; + if (!CBB_add_u16_length_prefixed(&body, &child) || + !CBB_reserve(&child, &sig, max_sig_len)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return ssl_private_key_failure; + } + + Array msg; + if (!tls13_get_cert_verify_signature_input( + hs, &msg, + ssl->server ? ssl_cert_verify_server : ssl_cert_verify_client)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return ssl_private_key_failure; + } + + enum ssl_private_key_result_t sign_result = ssl_private_key_sign( + hs, sig, &sig_len, max_sig_len, signature_algorithm, msg); + if (sign_result != ssl_private_key_success) { + return sign_result; + } + + if (!CBB_did_write(&child, sig_len) || + !ssl_add_message_cbb(ssl, cbb.get())) { + return ssl_private_key_failure; + } + + return ssl_private_key_success; +} + +int tls13_add_finished(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + size_t verify_data_len; + uint8_t verify_data[EVP_MAX_MD_SIZE]; + + if (!tls13_finished_mac(hs, verify_data, &verify_data_len, ssl->server)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + OPENSSL_PUT_ERROR(SSL, SSL_R_DIGEST_CHECK_FAILED); + return 0; + } + + ScopedCBB cbb; + CBB body; + if (!ssl->method->init_message(ssl, cbb.get(), &body, SSL3_MT_FINISHED) || + !CBB_add_bytes(&body, verify_data, verify_data_len) || + !ssl_add_message_cbb(ssl, cbb.get())) { + return 0; + } + + return 1; +} + +static int tls13_receive_key_update(SSL *ssl, const SSLMessage &msg) { + CBS body = msg.body; + uint8_t key_update_request; + if (!CBS_get_u8(&body, &key_update_request) || + CBS_len(&body) != 0 || + (key_update_request != SSL_KEY_UPDATE_NOT_REQUESTED && + key_update_request != SSL_KEY_UPDATE_REQUESTED)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return 0; + } + + if (!tls13_rotate_traffic_key(ssl, evp_aead_open)) { + return 0; + } + + // Acknowledge the KeyUpdate + if (key_update_request == SSL_KEY_UPDATE_REQUESTED && + !ssl->s3->key_update_pending) { + ScopedCBB cbb; + CBB body_cbb; + if (!ssl->method->init_message(ssl, cbb.get(), &body_cbb, + SSL3_MT_KEY_UPDATE) || + !CBB_add_u8(&body_cbb, SSL_KEY_UPDATE_NOT_REQUESTED) || + !ssl_add_message_cbb(ssl, cbb.get()) || + !tls13_rotate_traffic_key(ssl, evp_aead_seal)) { + return 0; + } + + // Suppress KeyUpdate acknowledgments until this change is written to the + // wire. This prevents us from accumulating write obligations when read and + // write progress at different rates. See draft-ietf-tls-tls13-18, section + // 4.5.3. + ssl->s3->key_update_pending = true; + } + + return 1; +} + +int tls13_post_handshake(SSL *ssl, const SSLMessage &msg) { + if (msg.type == SSL3_MT_KEY_UPDATE) { + ssl->s3->key_update_count++; + if (ssl->s3->key_update_count > kMaxKeyUpdates) { + OPENSSL_PUT_ERROR(SSL, SSL_R_TOO_MANY_KEY_UPDATES); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE); + return 0; + } + + return tls13_receive_key_update(ssl, msg); + } + + ssl->s3->key_update_count = 0; + + if (msg.type == SSL3_MT_NEW_SESSION_TICKET && !ssl->server) { + return tls13_process_new_session_ticket(ssl, msg); + } + + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE); + OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_MESSAGE); + return 0; +} + +} // namespace bssl diff --git a/FoodApp/Pods/BoringSSL-GRPC/ssl/tls13_both.cc.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/ssl/tls13_both.cc.grpc_back new file mode 100644 index 0000000..2a5a935 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/ssl/tls13_both.cc.grpc_back @@ -0,0 +1,559 @@ +/* Copyright (c) 2016, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include "../crypto/internal.h" +#include "internal.h" + + +namespace bssl { + +// kMaxKeyUpdates is the number of consecutive KeyUpdates that will be +// processed. Without this limit an attacker could force unbounded processing +// without being able to return application data. +static const uint8_t kMaxKeyUpdates = 32; + +const uint8_t kHelloRetryRequest[SSL3_RANDOM_SIZE] = { + 0xcf, 0x21, 0xad, 0x74, 0xe5, 0x9a, 0x61, 0x11, 0xbe, 0x1d, 0x8c, + 0x02, 0x1e, 0x65, 0xb8, 0x91, 0xc2, 0xa2, 0x11, 0x16, 0x7a, 0xbb, + 0x8c, 0x5e, 0x07, 0x9e, 0x09, 0xe2, 0xc8, 0xa8, 0x33, 0x9c, +}; + +// This value was selected by truncating the SHA-256 hash of "Draft TLS 1.3 +// Downgrade" to 8 bytes: +// +// echo -n 'Draft TLS 1.3 Downgrade' | sha256sum | head -c 16 +const uint8_t kDraftDowngradeRandom[8] = {0x95, 0xb9, 0x9f, 0x87, + 0x22, 0xfe, 0x9b, 0x64}; + + +bool tls13_get_cert_verify_signature_input( + SSL_HANDSHAKE *hs, Array *out, + enum ssl_cert_verify_context_t cert_verify_context) { + ScopedCBB cbb; + if (!CBB_init(cbb.get(), 64 + 33 + 1 + 2 * EVP_MAX_MD_SIZE)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return false; + } + + for (size_t i = 0; i < 64; i++) { + if (!CBB_add_u8(cbb.get(), 0x20)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return false; + } + } + + Span context; + if (cert_verify_context == ssl_cert_verify_server) { + static const char kContext[] = "TLS 1.3, server CertificateVerify"; + context = kContext; + } else if (cert_verify_context == ssl_cert_verify_client) { + static const char kContext[] = "TLS 1.3, client CertificateVerify"; + context = kContext; + } else if (cert_verify_context == ssl_cert_verify_channel_id) { + static const char kContext[] = "TLS 1.3, Channel ID"; + context = kContext; + } else { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return false; + } + + // Note |context| includes the NUL byte separator. + if (!CBB_add_bytes(cbb.get(), + reinterpret_cast(context.data()), + context.size())) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return false; + } + + uint8_t context_hash[EVP_MAX_MD_SIZE]; + size_t context_hash_len; + if (!hs->transcript.GetHash(context_hash, &context_hash_len) || + !CBB_add_bytes(cbb.get(), context_hash, context_hash_len) || + !CBBFinishArray(cbb.get(), out)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return false; + } + + return true; +} + +int tls13_process_certificate(SSL_HANDSHAKE *hs, const SSLMessage &msg, + int allow_anonymous) { + SSL *const ssl = hs->ssl; + CBS body = msg.body, context, certificate_list; + if (!CBS_get_u8_length_prefixed(&body, &context) || + CBS_len(&context) != 0 || + !CBS_get_u24_length_prefixed(&body, &certificate_list) || + CBS_len(&body) != 0) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + return 0; + } + + UniquePtr certs(sk_CRYPTO_BUFFER_new_null()); + if (!certs) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + + const bool retain_sha256 = + ssl->server && ssl->retain_only_sha256_of_client_certs; + UniquePtr pkey; + while (CBS_len(&certificate_list) > 0) { + CBS certificate, extensions; + if (!CBS_get_u24_length_prefixed(&certificate_list, &certificate) || + !CBS_get_u16_length_prefixed(&certificate_list, &extensions) || + CBS_len(&certificate) == 0) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + OPENSSL_PUT_ERROR(SSL, SSL_R_CERT_LENGTH_MISMATCH); + return 0; + } + + if (sk_CRYPTO_BUFFER_num(certs.get()) == 0) { + pkey = ssl_cert_parse_pubkey(&certificate); + if (!pkey) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + return 0; + } + // TLS 1.3 always uses certificate keys for signing thus the correct + // keyUsage is enforced. + if (!ssl_cert_check_digital_signature_key_usage(&certificate)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + return 0; + } + + if (retain_sha256) { + // Retain the hash of the leaf certificate if requested. + SHA256(CBS_data(&certificate), CBS_len(&certificate), + hs->new_session->peer_sha256); + } + } + + UniquePtr buf( + CRYPTO_BUFFER_new_from_CBS(&certificate, ssl->ctx->pool)); + if (!buf || + !PushToStack(certs.get(), std::move(buf))) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + return 0; + } + + // Parse out the extensions. + bool have_status_request = false, have_sct = false; + CBS status_request, sct; + const SSL_EXTENSION_TYPE ext_types[] = { + {TLSEXT_TYPE_status_request, &have_status_request, &status_request}, + {TLSEXT_TYPE_certificate_timestamp, &have_sct, &sct}, + }; + + uint8_t alert = SSL_AD_DECODE_ERROR; + if (!ssl_parse_extensions(&extensions, &alert, ext_types, + OPENSSL_ARRAY_SIZE(ext_types), + 0 /* reject unknown */)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + return 0; + } + + // All Certificate extensions are parsed, but only the leaf extensions are + // stored. + if (have_status_request) { + if (ssl->server || !ssl->ocsp_stapling_enabled) { + OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNSUPPORTED_EXTENSION); + return 0; + } + + uint8_t status_type; + CBS ocsp_response; + if (!CBS_get_u8(&status_request, &status_type) || + status_type != TLSEXT_STATUSTYPE_ocsp || + !CBS_get_u24_length_prefixed(&status_request, &ocsp_response) || + CBS_len(&ocsp_response) == 0 || + CBS_len(&status_request) != 0) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return 0; + } + + if (sk_CRYPTO_BUFFER_num(certs.get()) == 1) { + CRYPTO_BUFFER_free(hs->new_session->ocsp_response); + hs->new_session->ocsp_response = + CRYPTO_BUFFER_new_from_CBS(&ocsp_response, ssl->ctx->pool); + if (hs->new_session->ocsp_response == nullptr) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return 0; + } + } + } + + if (have_sct) { + if (ssl->server || !ssl->signed_cert_timestamps_enabled) { + OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNSUPPORTED_EXTENSION); + return 0; + } + + if (!ssl_is_sct_list_valid(&sct)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_ERROR_PARSING_EXTENSION); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return 0; + } + + if (sk_CRYPTO_BUFFER_num(certs.get()) == 1) { + CRYPTO_BUFFER_free(hs->new_session->signed_cert_timestamp_list); + hs->new_session->signed_cert_timestamp_list = + CRYPTO_BUFFER_new_from_CBS(&sct, ssl->ctx->pool); + if (hs->new_session->signed_cert_timestamp_list == nullptr) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return 0; + } + } + } + } + + // Store a null certificate list rather than an empty one if the peer didn't + // send certificates. + if (sk_CRYPTO_BUFFER_num(certs.get()) == 0) { + certs.reset(); + } + + hs->peer_pubkey = std::move(pkey); + + sk_CRYPTO_BUFFER_pop_free(hs->new_session->certs, CRYPTO_BUFFER_free); + hs->new_session->certs = certs.release(); + + if (!ssl->ctx->x509_method->session_cache_objects(hs->new_session.get())) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return 0; + } + + if (sk_CRYPTO_BUFFER_num(hs->new_session->certs) == 0) { + if (!allow_anonymous) { + OPENSSL_PUT_ERROR(SSL, SSL_R_PEER_DID_NOT_RETURN_A_CERTIFICATE); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_CERTIFICATE_REQUIRED); + return 0; + } + + // OpenSSL returns X509_V_OK when no certificates are requested. This is + // classed by them as a bug, but it's assumed by at least NGINX. + hs->new_session->verify_result = X509_V_OK; + + // No certificate, so nothing more to do. + return 1; + } + + hs->new_session->peer_sha256_valid = retain_sha256; + return 1; +} + +int tls13_process_certificate_verify(SSL_HANDSHAKE *hs, const SSLMessage &msg) { + SSL *const ssl = hs->ssl; + if (hs->peer_pubkey == NULL) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return 0; + } + + CBS body = msg.body, signature; + uint16_t signature_algorithm; + if (!CBS_get_u16(&body, &signature_algorithm) || + !CBS_get_u16_length_prefixed(&body, &signature) || + CBS_len(&body) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return 0; + } + + uint8_t alert = SSL_AD_DECODE_ERROR; + if (!tls12_check_peer_sigalg(ssl, &alert, signature_algorithm)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + return 0; + } + hs->new_session->peer_signature_algorithm = signature_algorithm; + + Array input; + if (!tls13_get_cert_verify_signature_input( + hs, &input, + ssl->server ? ssl_cert_verify_client : ssl_cert_verify_server)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return 0; + } + + bool sig_ok = ssl_public_key_verify(ssl, signature, signature_algorithm, + hs->peer_pubkey.get(), input); +#if defined(BORINGSSL_UNSAFE_FUZZER_MODE) + sig_ok = true; + ERR_clear_error(); +#endif + if (!sig_ok) { + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_SIGNATURE); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECRYPT_ERROR); + return 0; + } + + return 1; +} + +int tls13_process_finished(SSL_HANDSHAKE *hs, const SSLMessage &msg, + int use_saved_value) { + SSL *const ssl = hs->ssl; + uint8_t verify_data_buf[EVP_MAX_MD_SIZE]; + const uint8_t *verify_data; + size_t verify_data_len; + if (use_saved_value) { + assert(ssl->server); + verify_data = hs->expected_client_finished; + verify_data_len = hs->hash_len; + } else { + if (!tls13_finished_mac(hs, verify_data_buf, &verify_data_len, + !ssl->server)) { + return 0; + } + verify_data = verify_data_buf; + } + + int finished_ok = CBS_mem_equal(&msg.body, verify_data, verify_data_len); +#if defined(BORINGSSL_UNSAFE_FUZZER_MODE) + finished_ok = 1; +#endif + if (!finished_ok) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECRYPT_ERROR); + OPENSSL_PUT_ERROR(SSL, SSL_R_DIGEST_CHECK_FAILED); + return 0; + } + + return 1; +} + +int tls13_add_certificate(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + ScopedCBB cbb; + CBB body, certificate_list; + if (!ssl->method->init_message(ssl, cbb.get(), &body, SSL3_MT_CERTIFICATE) || + // The request context is always empty in the handshake. + !CBB_add_u8(&body, 0) || + !CBB_add_u24_length_prefixed(&body, &certificate_list)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return 0; + } + + if (!ssl_has_certificate(ssl)) { + return ssl_add_message_cbb(ssl, cbb.get()); + } + + CERT *cert = ssl->cert; + CRYPTO_BUFFER *leaf_buf = sk_CRYPTO_BUFFER_value(cert->chain, 0); + CBB leaf, extensions; + if (!CBB_add_u24_length_prefixed(&certificate_list, &leaf) || + !CBB_add_bytes(&leaf, CRYPTO_BUFFER_data(leaf_buf), + CRYPTO_BUFFER_len(leaf_buf)) || + !CBB_add_u16_length_prefixed(&certificate_list, &extensions)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return 0; + } + + if (hs->scts_requested && ssl->cert->signed_cert_timestamp_list != NULL) { + CBB contents; + if (!CBB_add_u16(&extensions, TLSEXT_TYPE_certificate_timestamp) || + !CBB_add_u16_length_prefixed(&extensions, &contents) || + !CBB_add_bytes( + &contents, + CRYPTO_BUFFER_data(ssl->cert->signed_cert_timestamp_list), + CRYPTO_BUFFER_len(ssl->cert->signed_cert_timestamp_list)) || + !CBB_flush(&extensions)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return 0; + } + } + + if (hs->ocsp_stapling_requested && + ssl->cert->ocsp_response != NULL) { + CBB contents, ocsp_response; + if (!CBB_add_u16(&extensions, TLSEXT_TYPE_status_request) || + !CBB_add_u16_length_prefixed(&extensions, &contents) || + !CBB_add_u8(&contents, TLSEXT_STATUSTYPE_ocsp) || + !CBB_add_u24_length_prefixed(&contents, &ocsp_response) || + !CBB_add_bytes(&ocsp_response, + CRYPTO_BUFFER_data(ssl->cert->ocsp_response), + CRYPTO_BUFFER_len(ssl->cert->ocsp_response)) || + !CBB_flush(&extensions)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return 0; + } + } + + for (size_t i = 1; i < sk_CRYPTO_BUFFER_num(cert->chain); i++) { + CRYPTO_BUFFER *cert_buf = sk_CRYPTO_BUFFER_value(cert->chain, i); + CBB child; + if (!CBB_add_u24_length_prefixed(&certificate_list, &child) || + !CBB_add_bytes(&child, CRYPTO_BUFFER_data(cert_buf), + CRYPTO_BUFFER_len(cert_buf)) || + !CBB_add_u16(&certificate_list, 0 /* no extensions */)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return 0; + } + } + + return ssl_add_message_cbb(ssl, cbb.get()); +} + +enum ssl_private_key_result_t tls13_add_certificate_verify(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + uint16_t signature_algorithm; + if (!tls1_choose_signature_algorithm(hs, &signature_algorithm)) { + return ssl_private_key_failure; + } + + ScopedCBB cbb; + CBB body; + if (!ssl->method->init_message(ssl, cbb.get(), &body, + SSL3_MT_CERTIFICATE_VERIFY) || + !CBB_add_u16(&body, signature_algorithm)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return ssl_private_key_failure; + } + + // Sign the digest. + CBB child; + const size_t max_sig_len = EVP_PKEY_size(hs->local_pubkey.get()); + uint8_t *sig; + size_t sig_len; + if (!CBB_add_u16_length_prefixed(&body, &child) || + !CBB_reserve(&child, &sig, max_sig_len)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return ssl_private_key_failure; + } + + Array msg; + if (!tls13_get_cert_verify_signature_input( + hs, &msg, + ssl->server ? ssl_cert_verify_server : ssl_cert_verify_client)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return ssl_private_key_failure; + } + + enum ssl_private_key_result_t sign_result = ssl_private_key_sign( + hs, sig, &sig_len, max_sig_len, signature_algorithm, msg); + if (sign_result != ssl_private_key_success) { + return sign_result; + } + + if (!CBB_did_write(&child, sig_len) || + !ssl_add_message_cbb(ssl, cbb.get())) { + return ssl_private_key_failure; + } + + return ssl_private_key_success; +} + +int tls13_add_finished(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + size_t verify_data_len; + uint8_t verify_data[EVP_MAX_MD_SIZE]; + + if (!tls13_finished_mac(hs, verify_data, &verify_data_len, ssl->server)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + OPENSSL_PUT_ERROR(SSL, SSL_R_DIGEST_CHECK_FAILED); + return 0; + } + + ScopedCBB cbb; + CBB body; + if (!ssl->method->init_message(ssl, cbb.get(), &body, SSL3_MT_FINISHED) || + !CBB_add_bytes(&body, verify_data, verify_data_len) || + !ssl_add_message_cbb(ssl, cbb.get())) { + return 0; + } + + return 1; +} + +static int tls13_receive_key_update(SSL *ssl, const SSLMessage &msg) { + CBS body = msg.body; + uint8_t key_update_request; + if (!CBS_get_u8(&body, &key_update_request) || + CBS_len(&body) != 0 || + (key_update_request != SSL_KEY_UPDATE_NOT_REQUESTED && + key_update_request != SSL_KEY_UPDATE_REQUESTED)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return 0; + } + + if (!tls13_rotate_traffic_key(ssl, evp_aead_open)) { + return 0; + } + + // Acknowledge the KeyUpdate + if (key_update_request == SSL_KEY_UPDATE_REQUESTED && + !ssl->s3->key_update_pending) { + ScopedCBB cbb; + CBB body_cbb; + if (!ssl->method->init_message(ssl, cbb.get(), &body_cbb, + SSL3_MT_KEY_UPDATE) || + !CBB_add_u8(&body_cbb, SSL_KEY_UPDATE_NOT_REQUESTED) || + !ssl_add_message_cbb(ssl, cbb.get()) || + !tls13_rotate_traffic_key(ssl, evp_aead_seal)) { + return 0; + } + + // Suppress KeyUpdate acknowledgments until this change is written to the + // wire. This prevents us from accumulating write obligations when read and + // write progress at different rates. See draft-ietf-tls-tls13-18, section + // 4.5.3. + ssl->s3->key_update_pending = true; + } + + return 1; +} + +int tls13_post_handshake(SSL *ssl, const SSLMessage &msg) { + if (msg.type == SSL3_MT_KEY_UPDATE) { + ssl->s3->key_update_count++; + if (ssl->s3->key_update_count > kMaxKeyUpdates) { + OPENSSL_PUT_ERROR(SSL, SSL_R_TOO_MANY_KEY_UPDATES); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE); + return 0; + } + + return tls13_receive_key_update(ssl, msg); + } + + ssl->s3->key_update_count = 0; + + if (msg.type == SSL3_MT_NEW_SESSION_TICKET && !ssl->server) { + return tls13_process_new_session_ticket(ssl, msg); + } + + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE); + OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_MESSAGE); + return 0; +} + +} // namespace bssl diff --git a/FoodApp/Pods/BoringSSL-GRPC/ssl/tls13_client.cc b/FoodApp/Pods/BoringSSL-GRPC/ssl/tls13_client.cc new file mode 100644 index 0000000..12bb78a --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/ssl/tls13_client.cc @@ -0,0 +1,891 @@ +/* Copyright (c) 2016, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include "../crypto/internal.h" +#include "internal.h" + + +namespace bssl { + +enum client_hs_state_t { + state_read_hello_retry_request = 0, + state_send_second_client_hello, + state_read_server_hello, + state_read_encrypted_extensions, + state_read_certificate_request, + state_read_server_certificate, + state_read_server_certificate_verify, + state_read_server_finished, + state_send_end_of_early_data, + state_send_client_certificate, + state_send_client_certificate_verify, + state_complete_second_flight, + state_done, +}; + +static const uint8_t kZeroes[EVP_MAX_MD_SIZE] = {0}; + +static enum ssl_hs_wait_t do_read_hello_retry_request(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + assert(ssl->s3->have_version); + SSLMessage msg; + if (!ssl->method->get_message(ssl, &msg)) { + return ssl_hs_read_message; + } + + // Queue up a ChangeCipherSpec for whenever we next send something. This + // will be before the second ClientHello. If we offered early data, this was + // already done. + if (!hs->early_data_offered && + !ssl->method->add_change_cipher_spec(ssl)) { + return ssl_hs_error; + } + + if (!ssl_check_message_type(ssl, msg, SSL3_MT_SERVER_HELLO)) { + return ssl_hs_error; + } + + CBS body = msg.body, extensions, server_random, session_id; + uint16_t server_version, cipher_suite; + uint8_t compression_method; + if (!CBS_get_u16(&body, &server_version) || + !CBS_get_bytes(&body, &server_random, SSL3_RANDOM_SIZE) || + !CBS_get_u8_length_prefixed(&body, &session_id) || + !CBS_mem_equal(&session_id, hs->session_id, hs->session_id_len) || + !CBS_get_u16(&body, &cipher_suite) || + !CBS_get_u8(&body, &compression_method) || + compression_method != 0 || + !CBS_get_u16_length_prefixed(&body, &extensions) || + CBS_len(&extensions) == 0 || + CBS_len(&body) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return ssl_hs_error; + } + + if (!CBS_mem_equal(&server_random, kHelloRetryRequest, SSL3_RANDOM_SIZE)) { + hs->tls13_state = state_read_server_hello; + return ssl_hs_ok; + } + + const SSL_CIPHER *cipher = SSL_get_cipher_by_value(cipher_suite); + // Check if the cipher is a TLS 1.3 cipher. + if (cipher == NULL || + SSL_CIPHER_get_min_version(cipher) > ssl_protocol_version(ssl) || + SSL_CIPHER_get_max_version(cipher) < ssl_protocol_version(ssl)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CIPHER_RETURNED); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + return ssl_hs_error; + } + + hs->new_cipher = cipher; + + if (!hs->transcript.InitHash(ssl_protocol_version(ssl), hs->new_cipher) || + !hs->transcript.UpdateForHelloRetryRequest()) { + return ssl_hs_error; + } + + + bool have_cookie, have_key_share, have_supported_versions; + CBS cookie, key_share, supported_versions; + SSL_EXTENSION_TYPE ext_types[] = { + {TLSEXT_TYPE_key_share, &have_key_share, &key_share}, + {TLSEXT_TYPE_cookie, &have_cookie, &cookie}, + {TLSEXT_TYPE_supported_versions, &have_supported_versions, + &supported_versions}, + }; + + uint8_t alert = SSL_AD_DECODE_ERROR; + if (!ssl_parse_extensions(&extensions, &alert, ext_types, + OPENSSL_ARRAY_SIZE(ext_types), + 0 /* reject unknown */)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + return ssl_hs_error; + } + + if (!have_cookie && !have_key_share) { + OPENSSL_PUT_ERROR(SSL, SSL_R_EMPTY_HELLO_RETRY_REQUEST); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + return ssl_hs_error; + } + if (have_cookie) { + CBS cookie_value; + if (!CBS_get_u16_length_prefixed(&cookie, &cookie_value) || + CBS_len(&cookie_value) == 0 || + CBS_len(&cookie) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return ssl_hs_error; + } + + if (!hs->cookie.CopyFrom(cookie_value)) { + return ssl_hs_error; + } + } + + if (have_key_share) { + uint16_t group_id; + if (!CBS_get_u16(&key_share, &group_id) || CBS_len(&key_share) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return ssl_hs_error; + } + + // The group must be supported. + if (!tls1_check_group_id(ssl, group_id)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CURVE); + return ssl_hs_error; + } + + // Check that the HelloRetryRequest does not request the key share that + // was provided in the initial ClientHello. + if (hs->key_share->GroupID() == group_id) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CURVE); + return ssl_hs_error; + } + + hs->key_share.reset(); + hs->retry_group = group_id; + } + + if (!ssl_hash_message(hs, msg)) { + return ssl_hs_error; + } + + ssl->method->next_message(ssl); + hs->received_hello_retry_request = true; + hs->tls13_state = state_send_second_client_hello; + // 0-RTT is rejected if we receive a HelloRetryRequest. + if (hs->in_early_data) { + return ssl_hs_early_data_rejected; + } + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_send_second_client_hello(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + // Restore the null cipher. We may have switched due to 0-RTT. + bssl::UniquePtr null_ctx = + SSLAEADContext::CreateNullCipher(SSL_is_dtls(ssl)); + if (!null_ctx || + !ssl->method->set_write_state(ssl, std::move(null_ctx))) { + return ssl_hs_error; + } + + ssl->s3->aead_write_ctx->SetVersionIfNullCipher(ssl->version); + + if (!ssl_write_client_hello(hs)) { + return ssl_hs_error; + } + + hs->tls13_state = state_read_server_hello; + return ssl_hs_flush; +} + +static enum ssl_hs_wait_t do_read_server_hello(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + SSLMessage msg; + if (!ssl->method->get_message(ssl, &msg)) { + return ssl_hs_read_message; + } + if (!ssl_check_message_type(ssl, msg, SSL3_MT_SERVER_HELLO)) { + return ssl_hs_error; + } + + CBS body = msg.body, server_random, session_id, extensions; + uint16_t server_version; + uint16_t cipher_suite; + uint8_t compression_method; + if (!CBS_get_u16(&body, &server_version) || + !CBS_get_bytes(&body, &server_random, SSL3_RANDOM_SIZE) || + !CBS_get_u8_length_prefixed(&body, &session_id) || + !CBS_mem_equal(&session_id, hs->session_id, hs->session_id_len) || + !CBS_get_u16(&body, &cipher_suite) || + !CBS_get_u8(&body, &compression_method) || + compression_method != 0 || + !CBS_get_u16_length_prefixed(&body, &extensions) || + CBS_len(&body) != 0) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + return ssl_hs_error; + } + + if (server_version != TLS1_2_VERSION) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_VERSION_NUMBER); + return ssl_hs_error; + } + + // Forbid a second HelloRetryRequest. + if (CBS_mem_equal(&server_random, kHelloRetryRequest, SSL3_RANDOM_SIZE)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE); + OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_MESSAGE); + return ssl_hs_error; + } + + OPENSSL_memcpy(ssl->s3->server_random, CBS_data(&server_random), + SSL3_RANDOM_SIZE); + + // Check if the cipher is a TLS 1.3 cipher. + const SSL_CIPHER *cipher = SSL_get_cipher_by_value(cipher_suite); + if (cipher == nullptr || + SSL_CIPHER_get_min_version(cipher) > ssl_protocol_version(ssl) || + SSL_CIPHER_get_max_version(cipher) < ssl_protocol_version(ssl)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CIPHER_RETURNED); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + return ssl_hs_error; + } + + // Check that the cipher matches the one in the HelloRetryRequest. + if (hs->received_hello_retry_request && + hs->new_cipher != cipher) { + OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CIPHER_RETURNED); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + return ssl_hs_error; + } + + // Parse out the extensions. + bool have_key_share = false, have_pre_shared_key = false, + have_supported_versions = false; + CBS key_share, pre_shared_key, supported_versions; + SSL_EXTENSION_TYPE ext_types[] = { + {TLSEXT_TYPE_key_share, &have_key_share, &key_share}, + {TLSEXT_TYPE_pre_shared_key, &have_pre_shared_key, &pre_shared_key}, + {TLSEXT_TYPE_supported_versions, &have_supported_versions, + &supported_versions}, + }; + + uint8_t alert = SSL_AD_DECODE_ERROR; + if (!ssl_parse_extensions(&extensions, &alert, ext_types, + OPENSSL_ARRAY_SIZE(ext_types), + 0 /* reject unknown */)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + return ssl_hs_error; + } + + alert = SSL_AD_DECODE_ERROR; + if (have_pre_shared_key) { + if (ssl->session == NULL) { + OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNSUPPORTED_EXTENSION); + return ssl_hs_error; + } + + if (!ssl_ext_pre_shared_key_parse_serverhello(hs, &alert, + &pre_shared_key)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + return ssl_hs_error; + } + + if (ssl->session->ssl_version != ssl->version) { + OPENSSL_PUT_ERROR(SSL, SSL_R_OLD_SESSION_VERSION_NOT_RETURNED); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + return ssl_hs_error; + } + + if (ssl->session->cipher->algorithm_prf != cipher->algorithm_prf) { + OPENSSL_PUT_ERROR(SSL, SSL_R_OLD_SESSION_PRF_HASH_MISMATCH); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + return ssl_hs_error; + } + + if (!ssl_session_is_context_valid(ssl, ssl->session)) { + // This is actually a client application bug. + OPENSSL_PUT_ERROR(SSL, + SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + return ssl_hs_error; + } + + ssl->s3->session_reused = true; + // Only authentication information carries over in TLS 1.3. + hs->new_session = SSL_SESSION_dup(ssl->session, SSL_SESSION_DUP_AUTH_ONLY); + if (!hs->new_session) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return ssl_hs_error; + } + ssl_set_session(ssl, NULL); + + // Resumption incorporates fresh key material, so refresh the timeout. + ssl_session_renew_timeout(ssl, hs->new_session.get(), + ssl->session_ctx->session_psk_dhe_timeout); + } else if (!ssl_get_new_session(hs, 0)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return ssl_hs_error; + } + + hs->new_session->cipher = cipher; + hs->new_cipher = cipher; + + size_t hash_len = + EVP_MD_size(ssl_get_handshake_digest(ssl_protocol_version(ssl), cipher)); + + // Set up the key schedule and incorporate the PSK into the running secret. + if (ssl->s3->session_reused) { + if (!tls13_init_key_schedule(hs, hs->new_session->master_key, + hs->new_session->master_key_length)) { + return ssl_hs_error; + } + } else if (!tls13_init_key_schedule(hs, kZeroes, hash_len)) { + return ssl_hs_error; + } + + if (!have_key_share) { + // We do not support psk_ke and thus always require a key share. + OPENSSL_PUT_ERROR(SSL, SSL_R_MISSING_KEY_SHARE); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_MISSING_EXTENSION); + return ssl_hs_error; + } + + // Resolve ECDHE and incorporate it into the secret. + Array dhe_secret; + alert = SSL_AD_DECODE_ERROR; + if (!ssl_ext_key_share_parse_serverhello(hs, &dhe_secret, &alert, + &key_share)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + return ssl_hs_error; + } + + if (!tls13_advance_key_schedule(hs, dhe_secret.data(), dhe_secret.size()) || + !ssl_hash_message(hs, msg) || + !tls13_derive_handshake_secrets(hs) || + !tls13_set_traffic_key(ssl, evp_aead_open, hs->server_handshake_secret, + hs->hash_len)) { + return ssl_hs_error; + } + + if (!hs->early_data_offered) { + // If not sending early data, set client traffic keys now so that alerts are + // encrypted. + if (!tls13_set_traffic_key(ssl, evp_aead_seal, hs->client_handshake_secret, + hs->hash_len)) { + return ssl_hs_error; + } + } + + ssl->method->next_message(ssl); + hs->tls13_state = state_read_encrypted_extensions; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_read_encrypted_extensions(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + SSLMessage msg; + if (!ssl->method->get_message(ssl, &msg)) { + return ssl_hs_read_message; + } + if (!ssl_check_message_type(ssl, msg, SSL3_MT_ENCRYPTED_EXTENSIONS)) { + return ssl_hs_error; + } + + CBS body = msg.body; + if (!ssl_parse_serverhello_tlsext(hs, &body)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_PARSE_TLSEXT); + return ssl_hs_error; + } + if (CBS_len(&body) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return ssl_hs_error; + } + + // Store the negotiated ALPN in the session. + if (!ssl->s3->alpn_selected.empty()) { + hs->new_session->early_alpn = (uint8_t *)BUF_memdup( + ssl->s3->alpn_selected.data(), ssl->s3->alpn_selected.size()); + if (hs->new_session->early_alpn == NULL) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return ssl_hs_error; + } + hs->new_session->early_alpn_len = ssl->s3->alpn_selected.size(); + } + + if (ssl->s3->early_data_accepted) { + if (hs->early_session->cipher != hs->new_session->cipher || + MakeConstSpan(hs->early_session->early_alpn, + hs->early_session->early_alpn_len) != + ssl->s3->alpn_selected) { + OPENSSL_PUT_ERROR(SSL, SSL_R_ALPN_MISMATCH_ON_EARLY_DATA); + return ssl_hs_error; + } + if (ssl->s3->tlsext_channel_id_valid || hs->received_custom_extension || + ssl->token_binding_negotiated) { + OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION_ON_EARLY_DATA); + return ssl_hs_error; + } + } + + if (!ssl_hash_message(hs, msg)) { + return ssl_hs_error; + } + + ssl->method->next_message(ssl); + hs->tls13_state = state_read_certificate_request; + if (hs->in_early_data && !ssl->s3->early_data_accepted) { + return ssl_hs_early_data_rejected; + } + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_read_certificate_request(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + // CertificateRequest may only be sent in non-resumption handshakes. + if (ssl->s3->session_reused) { + hs->tls13_state = state_read_server_finished; + return ssl_hs_ok; + } + + SSLMessage msg; + if (!ssl->method->get_message(ssl, &msg)) { + return ssl_hs_read_message; + } + + // CertificateRequest is optional. + if (msg.type != SSL3_MT_CERTIFICATE_REQUEST) { + hs->tls13_state = state_read_server_certificate; + return ssl_hs_ok; + } + + + bool have_sigalgs = false, have_ca = false; + CBS sigalgs, ca; + const SSL_EXTENSION_TYPE ext_types[] = { + {TLSEXT_TYPE_signature_algorithms, &have_sigalgs, &sigalgs}, + {TLSEXT_TYPE_certificate_authorities, &have_ca, &ca}, + }; + + CBS body = msg.body, context, extensions, supported_signature_algorithms; + uint8_t alert = SSL_AD_DECODE_ERROR; + if (!CBS_get_u8_length_prefixed(&body, &context) || + // The request context is always empty during the handshake. + CBS_len(&context) != 0 || + !CBS_get_u16_length_prefixed(&body, &extensions) || + CBS_len(&body) != 0 || + !ssl_parse_extensions(&extensions, &alert, ext_types, + OPENSSL_ARRAY_SIZE(ext_types), + 1 /* accept unknown */) || + (have_ca && CBS_len(&ca) == 0) || + !have_sigalgs || + !CBS_get_u16_length_prefixed(&sigalgs, + &supported_signature_algorithms) || + CBS_len(&supported_signature_algorithms) == 0 || + !tls1_parse_peer_sigalgs(hs, &supported_signature_algorithms)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + return ssl_hs_error; + } + + if (have_ca) { + hs->ca_names = ssl_parse_client_CA_list(ssl, &alert, &ca); + if (!hs->ca_names) { + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + return ssl_hs_error; + } + } else { + hs->ca_names.reset(sk_CRYPTO_BUFFER_new_null()); + if (!hs->ca_names) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return ssl_hs_error; + } + } + + hs->cert_request = true; + ssl->ctx->x509_method->hs_flush_cached_ca_names(hs); + + if (!ssl_hash_message(hs, msg)) { + return ssl_hs_error; + } + + ssl->method->next_message(ssl); + hs->tls13_state = state_read_server_certificate; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_read_server_certificate(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + SSLMessage msg; + if (!ssl->method->get_message(ssl, &msg)) { + return ssl_hs_read_message; + } + if (!ssl_check_message_type(ssl, msg, SSL3_MT_CERTIFICATE) || + !tls13_process_certificate(hs, msg, 0 /* certificate required */) || + !ssl_hash_message(hs, msg)) { + return ssl_hs_error; + } + + ssl->method->next_message(ssl); + hs->tls13_state = state_read_server_certificate_verify; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_read_server_certificate_verify( + SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + SSLMessage msg; + if (!ssl->method->get_message(ssl, &msg)) { + return ssl_hs_read_message; + } + switch (ssl_verify_peer_cert(hs)) { + case ssl_verify_ok: + break; + case ssl_verify_invalid: + return ssl_hs_error; + case ssl_verify_retry: + hs->tls13_state = state_read_server_certificate_verify; + return ssl_hs_certificate_verify; + } + + if (!ssl_check_message_type(ssl, msg, SSL3_MT_CERTIFICATE_VERIFY) || + !tls13_process_certificate_verify(hs, msg) || + !ssl_hash_message(hs, msg)) { + return ssl_hs_error; + } + + ssl->method->next_message(ssl); + hs->tls13_state = state_read_server_finished; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_read_server_finished(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + SSLMessage msg; + if (!ssl->method->get_message(ssl, &msg)) { + return ssl_hs_read_message; + } + if (!ssl_check_message_type(ssl, msg, SSL3_MT_FINISHED) || + !tls13_process_finished(hs, msg, 0 /* don't use saved value */) || + !ssl_hash_message(hs, msg) || + // Update the secret to the master secret and derive traffic keys. + !tls13_advance_key_schedule(hs, kZeroes, hs->hash_len) || + !tls13_derive_application_secrets(hs)) { + return ssl_hs_error; + } + + ssl->method->next_message(ssl); + hs->tls13_state = state_send_end_of_early_data; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_send_end_of_early_data(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + + if (ssl->s3->early_data_accepted) { + hs->can_early_write = false; + ScopedCBB cbb; + CBB body; + if (!ssl->method->init_message(ssl, cbb.get(), &body, + SSL3_MT_END_OF_EARLY_DATA) || + !ssl_add_message_cbb(ssl, cbb.get())) { + return ssl_hs_error; + } + } + + if (hs->early_data_offered) { + if (!tls13_set_traffic_key(ssl, evp_aead_seal, hs->client_handshake_secret, + hs->hash_len)) { + return ssl_hs_error; + } + } + + hs->tls13_state = state_send_client_certificate; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_send_client_certificate(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + + // The peer didn't request a certificate. + if (!hs->cert_request) { + hs->tls13_state = state_complete_second_flight; + return ssl_hs_ok; + } + + // Call cert_cb to update the certificate. + if (ssl->cert->cert_cb != NULL) { + int rv = ssl->cert->cert_cb(ssl, ssl->cert->cert_cb_arg); + if (rv == 0) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + OPENSSL_PUT_ERROR(SSL, SSL_R_CERT_CB_ERROR); + return ssl_hs_error; + } + if (rv < 0) { + hs->tls13_state = state_send_client_certificate; + return ssl_hs_x509_lookup; + } + } + + if (!ssl_on_certificate_selected(hs) || + !tls13_add_certificate(hs)) { + return ssl_hs_error; + } + + hs->tls13_state = state_send_client_certificate_verify; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_send_client_certificate_verify(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + // Don't send CertificateVerify if there is no certificate. + if (!ssl_has_certificate(ssl)) { + hs->tls13_state = state_complete_second_flight; + return ssl_hs_ok; + } + + switch (tls13_add_certificate_verify(hs)) { + case ssl_private_key_success: + hs->tls13_state = state_complete_second_flight; + return ssl_hs_ok; + + case ssl_private_key_retry: + hs->tls13_state = state_send_client_certificate_verify; + return ssl_hs_private_key_operation; + + case ssl_private_key_failure: + return ssl_hs_error; + } + + assert(0); + return ssl_hs_error; +} + +static enum ssl_hs_wait_t do_complete_second_flight(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + + // Send a Channel ID assertion if necessary. + if (ssl->s3->tlsext_channel_id_valid) { + if (!ssl_do_channel_id_callback(ssl)) { + hs->tls13_state = state_complete_second_flight; + return ssl_hs_error; + } + + if (ssl->tlsext_channel_id_private == NULL) { + return ssl_hs_channel_id_lookup; + } + + ScopedCBB cbb; + CBB body; + if (!ssl->method->init_message(ssl, cbb.get(), &body, SSL3_MT_CHANNEL_ID) || + !tls1_write_channel_id(hs, &body) || + !ssl_add_message_cbb(ssl, cbb.get())) { + return ssl_hs_error; + } + } + + // Send a Finished message. + if (!tls13_add_finished(hs)) { + return ssl_hs_error; + } + + // Derive the final keys and enable them. + if (!tls13_set_traffic_key(ssl, evp_aead_open, hs->server_traffic_secret_0, + hs->hash_len) || + !tls13_set_traffic_key(ssl, evp_aead_seal, hs->client_traffic_secret_0, + hs->hash_len) || + !tls13_derive_resumption_secret(hs)) { + return ssl_hs_error; + } + + hs->tls13_state = state_done; + return ssl_hs_flush; +} + +enum ssl_hs_wait_t tls13_client_handshake(SSL_HANDSHAKE *hs) { + while (hs->tls13_state != state_done) { + enum ssl_hs_wait_t ret = ssl_hs_error; + enum client_hs_state_t state = + static_cast(hs->tls13_state); + switch (state) { + case state_read_hello_retry_request: + ret = do_read_hello_retry_request(hs); + break; + case state_send_second_client_hello: + ret = do_send_second_client_hello(hs); + break; + case state_read_server_hello: + ret = do_read_server_hello(hs); + break; + case state_read_encrypted_extensions: + ret = do_read_encrypted_extensions(hs); + break; + case state_read_certificate_request: + ret = do_read_certificate_request(hs); + break; + case state_read_server_certificate: + ret = do_read_server_certificate(hs); + break; + case state_read_server_certificate_verify: + ret = do_read_server_certificate_verify(hs); + break; + case state_read_server_finished: + ret = do_read_server_finished(hs); + break; + case state_send_end_of_early_data: + ret = do_send_end_of_early_data(hs); + break; + case state_send_client_certificate: + ret = do_send_client_certificate(hs); + break; + case state_send_client_certificate_verify: + ret = do_send_client_certificate_verify(hs); + break; + case state_complete_second_flight: + ret = do_complete_second_flight(hs); + break; + case state_done: + ret = ssl_hs_ok; + break; + } + + if (hs->tls13_state != state) { + ssl_do_info_callback(hs->ssl, SSL_CB_CONNECT_LOOP, 1); + } + + if (ret != ssl_hs_ok) { + return ret; + } + } + + return ssl_hs_ok; +} + +const char *tls13_client_handshake_state(SSL_HANDSHAKE *hs) { + enum client_hs_state_t state = + static_cast(hs->tls13_state); + switch (state) { + case state_read_hello_retry_request: + return "TLS 1.3 client read_hello_retry_request"; + case state_send_second_client_hello: + return "TLS 1.3 client send_second_client_hello"; + case state_read_server_hello: + return "TLS 1.3 client read_server_hello"; + case state_read_encrypted_extensions: + return "TLS 1.3 client read_encrypted_extensions"; + case state_read_certificate_request: + return "TLS 1.3 client read_certificate_request"; + case state_read_server_certificate: + return "TLS 1.3 client read_server_certificate"; + case state_read_server_certificate_verify: + return "TLS 1.3 client read_server_certificate_verify"; + case state_read_server_finished: + return "TLS 1.3 client read_server_finished"; + case state_send_end_of_early_data: + return "TLS 1.3 client send_end_of_early_data"; + case state_send_client_certificate: + return "TLS 1.3 client send_client_certificate"; + case state_send_client_certificate_verify: + return "TLS 1.3 client send_client_certificate_verify"; + case state_complete_second_flight: + return "TLS 1.3 client complete_second_flight"; + case state_done: + return "TLS 1.3 client done"; + } + + return "TLS 1.3 client unknown"; +} + +int tls13_process_new_session_ticket(SSL *ssl, const SSLMessage &msg) { + if (ssl->s3->write_shutdown != ssl_shutdown_none) { + // Ignore tickets on shutdown. Callers tend to indiscriminately call + // |SSL_shutdown| before destroying an |SSL|, at which point calling the new + // session callback may be confusing. + return 1; + } + + UniquePtr session = SSL_SESSION_dup( + ssl->s3->established_session.get(), SSL_SESSION_INCLUDE_NONAUTH); + if (!session) { + return 0; + } + + ssl_session_rebase_time(ssl, session.get()); + + uint32_t server_timeout; + CBS body = msg.body, ticket_nonce, ticket, extensions; + if (!CBS_get_u32(&body, &server_timeout) || + !CBS_get_u32(&body, &session->ticket_age_add) || + !CBS_get_u8_length_prefixed(&body, &ticket_nonce) || + !CBS_get_u16_length_prefixed(&body, &ticket) || + !CBS_stow(&ticket, &session->tlsext_tick, &session->tlsext_ticklen) || + !CBS_get_u16_length_prefixed(&body, &extensions) || + CBS_len(&body) != 0) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + return 0; + } + + // Cap the renewable lifetime by the server advertised value. This avoids + // wasting bandwidth on 0-RTT when we know the server will reject it. + if (session->timeout > server_timeout) { + session->timeout = server_timeout; + } + + if (!tls13_derive_session_psk(session.get(), ticket_nonce)) { + return 0; + } + + // Parse out the extensions. + bool have_early_data_info = false; + CBS early_data_info; + const SSL_EXTENSION_TYPE ext_types[] = { + {TLSEXT_TYPE_early_data, &have_early_data_info, &early_data_info}, + }; + + uint8_t alert = SSL_AD_DECODE_ERROR; + if (!ssl_parse_extensions(&extensions, &alert, ext_types, + OPENSSL_ARRAY_SIZE(ext_types), + 1 /* ignore unknown */)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + return 0; + } + + if (have_early_data_info && ssl->cert->enable_early_data) { + if (!CBS_get_u32(&early_data_info, &session->ticket_max_early_data) || + CBS_len(&early_data_info) != 0) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + return 0; + } + } + + session->ticket_age_add_valid = 1; + session->not_resumable = 0; + + if ((ssl->ctx->session_cache_mode & SSL_SESS_CACHE_CLIENT) && + ssl->ctx->new_session_cb != NULL && + ssl->ctx->new_session_cb(ssl, session.get())) { + // |new_session_cb|'s return value signals that it took ownership. + session.release(); + } + + return 1; +} + +} // namespace bssl diff --git a/FoodApp/Pods/BoringSSL-GRPC/ssl/tls13_client.cc.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/ssl/tls13_client.cc.grpc_back new file mode 100644 index 0000000..aa05456 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/ssl/tls13_client.cc.grpc_back @@ -0,0 +1,891 @@ +/* Copyright (c) 2016, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include "../crypto/internal.h" +#include "internal.h" + + +namespace bssl { + +enum client_hs_state_t { + state_read_hello_retry_request = 0, + state_send_second_client_hello, + state_read_server_hello, + state_read_encrypted_extensions, + state_read_certificate_request, + state_read_server_certificate, + state_read_server_certificate_verify, + state_read_server_finished, + state_send_end_of_early_data, + state_send_client_certificate, + state_send_client_certificate_verify, + state_complete_second_flight, + state_done, +}; + +static const uint8_t kZeroes[EVP_MAX_MD_SIZE] = {0}; + +static enum ssl_hs_wait_t do_read_hello_retry_request(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + assert(ssl->s3->have_version); + SSLMessage msg; + if (!ssl->method->get_message(ssl, &msg)) { + return ssl_hs_read_message; + } + + // Queue up a ChangeCipherSpec for whenever we next send something. This + // will be before the second ClientHello. If we offered early data, this was + // already done. + if (!hs->early_data_offered && + !ssl->method->add_change_cipher_spec(ssl)) { + return ssl_hs_error; + } + + if (!ssl_check_message_type(ssl, msg, SSL3_MT_SERVER_HELLO)) { + return ssl_hs_error; + } + + CBS body = msg.body, extensions, server_random, session_id; + uint16_t server_version, cipher_suite; + uint8_t compression_method; + if (!CBS_get_u16(&body, &server_version) || + !CBS_get_bytes(&body, &server_random, SSL3_RANDOM_SIZE) || + !CBS_get_u8_length_prefixed(&body, &session_id) || + !CBS_mem_equal(&session_id, hs->session_id, hs->session_id_len) || + !CBS_get_u16(&body, &cipher_suite) || + !CBS_get_u8(&body, &compression_method) || + compression_method != 0 || + !CBS_get_u16_length_prefixed(&body, &extensions) || + CBS_len(&extensions) == 0 || + CBS_len(&body) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return ssl_hs_error; + } + + if (!CBS_mem_equal(&server_random, kHelloRetryRequest, SSL3_RANDOM_SIZE)) { + hs->tls13_state = state_read_server_hello; + return ssl_hs_ok; + } + + const SSL_CIPHER *cipher = SSL_get_cipher_by_value(cipher_suite); + // Check if the cipher is a TLS 1.3 cipher. + if (cipher == NULL || + SSL_CIPHER_get_min_version(cipher) > ssl_protocol_version(ssl) || + SSL_CIPHER_get_max_version(cipher) < ssl_protocol_version(ssl)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CIPHER_RETURNED); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + return ssl_hs_error; + } + + hs->new_cipher = cipher; + + if (!hs->transcript.InitHash(ssl_protocol_version(ssl), hs->new_cipher) || + !hs->transcript.UpdateForHelloRetryRequest()) { + return ssl_hs_error; + } + + + bool have_cookie, have_key_share, have_supported_versions; + CBS cookie, key_share, supported_versions; + SSL_EXTENSION_TYPE ext_types[] = { + {TLSEXT_TYPE_key_share, &have_key_share, &key_share}, + {TLSEXT_TYPE_cookie, &have_cookie, &cookie}, + {TLSEXT_TYPE_supported_versions, &have_supported_versions, + &supported_versions}, + }; + + uint8_t alert = SSL_AD_DECODE_ERROR; + if (!ssl_parse_extensions(&extensions, &alert, ext_types, + OPENSSL_ARRAY_SIZE(ext_types), + 0 /* reject unknown */)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + return ssl_hs_error; + } + + if (!have_cookie && !have_key_share) { + OPENSSL_PUT_ERROR(SSL, SSL_R_EMPTY_HELLO_RETRY_REQUEST); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + return ssl_hs_error; + } + if (have_cookie) { + CBS cookie_value; + if (!CBS_get_u16_length_prefixed(&cookie, &cookie_value) || + CBS_len(&cookie_value) == 0 || + CBS_len(&cookie) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return ssl_hs_error; + } + + if (!hs->cookie.CopyFrom(cookie_value)) { + return ssl_hs_error; + } + } + + if (have_key_share) { + uint16_t group_id; + if (!CBS_get_u16(&key_share, &group_id) || CBS_len(&key_share) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return ssl_hs_error; + } + + // The group must be supported. + if (!tls1_check_group_id(ssl, group_id)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CURVE); + return ssl_hs_error; + } + + // Check that the HelloRetryRequest does not request the key share that + // was provided in the initial ClientHello. + if (hs->key_share->GroupID() == group_id) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CURVE); + return ssl_hs_error; + } + + hs->key_share.reset(); + hs->retry_group = group_id; + } + + if (!ssl_hash_message(hs, msg)) { + return ssl_hs_error; + } + + ssl->method->next_message(ssl); + hs->received_hello_retry_request = true; + hs->tls13_state = state_send_second_client_hello; + // 0-RTT is rejected if we receive a HelloRetryRequest. + if (hs->in_early_data) { + return ssl_hs_early_data_rejected; + } + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_send_second_client_hello(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + // Restore the null cipher. We may have switched due to 0-RTT. + bssl::UniquePtr null_ctx = + SSLAEADContext::CreateNullCipher(SSL_is_dtls(ssl)); + if (!null_ctx || + !ssl->method->set_write_state(ssl, std::move(null_ctx))) { + return ssl_hs_error; + } + + ssl->s3->aead_write_ctx->SetVersionIfNullCipher(ssl->version); + + if (!ssl_write_client_hello(hs)) { + return ssl_hs_error; + } + + hs->tls13_state = state_read_server_hello; + return ssl_hs_flush; +} + +static enum ssl_hs_wait_t do_read_server_hello(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + SSLMessage msg; + if (!ssl->method->get_message(ssl, &msg)) { + return ssl_hs_read_message; + } + if (!ssl_check_message_type(ssl, msg, SSL3_MT_SERVER_HELLO)) { + return ssl_hs_error; + } + + CBS body = msg.body, server_random, session_id, extensions; + uint16_t server_version; + uint16_t cipher_suite; + uint8_t compression_method; + if (!CBS_get_u16(&body, &server_version) || + !CBS_get_bytes(&body, &server_random, SSL3_RANDOM_SIZE) || + !CBS_get_u8_length_prefixed(&body, &session_id) || + !CBS_mem_equal(&session_id, hs->session_id, hs->session_id_len) || + !CBS_get_u16(&body, &cipher_suite) || + !CBS_get_u8(&body, &compression_method) || + compression_method != 0 || + !CBS_get_u16_length_prefixed(&body, &extensions) || + CBS_len(&body) != 0) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + return ssl_hs_error; + } + + if (server_version != TLS1_2_VERSION) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_VERSION_NUMBER); + return ssl_hs_error; + } + + // Forbid a second HelloRetryRequest. + if (CBS_mem_equal(&server_random, kHelloRetryRequest, SSL3_RANDOM_SIZE)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE); + OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_MESSAGE); + return ssl_hs_error; + } + + OPENSSL_memcpy(ssl->s3->server_random, CBS_data(&server_random), + SSL3_RANDOM_SIZE); + + // Check if the cipher is a TLS 1.3 cipher. + const SSL_CIPHER *cipher = SSL_get_cipher_by_value(cipher_suite); + if (cipher == nullptr || + SSL_CIPHER_get_min_version(cipher) > ssl_protocol_version(ssl) || + SSL_CIPHER_get_max_version(cipher) < ssl_protocol_version(ssl)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CIPHER_RETURNED); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + return ssl_hs_error; + } + + // Check that the cipher matches the one in the HelloRetryRequest. + if (hs->received_hello_retry_request && + hs->new_cipher != cipher) { + OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CIPHER_RETURNED); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + return ssl_hs_error; + } + + // Parse out the extensions. + bool have_key_share = false, have_pre_shared_key = false, + have_supported_versions = false; + CBS key_share, pre_shared_key, supported_versions; + SSL_EXTENSION_TYPE ext_types[] = { + {TLSEXT_TYPE_key_share, &have_key_share, &key_share}, + {TLSEXT_TYPE_pre_shared_key, &have_pre_shared_key, &pre_shared_key}, + {TLSEXT_TYPE_supported_versions, &have_supported_versions, + &supported_versions}, + }; + + uint8_t alert = SSL_AD_DECODE_ERROR; + if (!ssl_parse_extensions(&extensions, &alert, ext_types, + OPENSSL_ARRAY_SIZE(ext_types), + 0 /* reject unknown */)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + return ssl_hs_error; + } + + alert = SSL_AD_DECODE_ERROR; + if (have_pre_shared_key) { + if (ssl->session == NULL) { + OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNSUPPORTED_EXTENSION); + return ssl_hs_error; + } + + if (!ssl_ext_pre_shared_key_parse_serverhello(hs, &alert, + &pre_shared_key)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + return ssl_hs_error; + } + + if (ssl->session->ssl_version != ssl->version) { + OPENSSL_PUT_ERROR(SSL, SSL_R_OLD_SESSION_VERSION_NOT_RETURNED); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + return ssl_hs_error; + } + + if (ssl->session->cipher->algorithm_prf != cipher->algorithm_prf) { + OPENSSL_PUT_ERROR(SSL, SSL_R_OLD_SESSION_PRF_HASH_MISMATCH); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + return ssl_hs_error; + } + + if (!ssl_session_is_context_valid(ssl, ssl->session)) { + // This is actually a client application bug. + OPENSSL_PUT_ERROR(SSL, + SSL_R_ATTEMPT_TO_REUSE_SESSION_IN_DIFFERENT_CONTEXT); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + return ssl_hs_error; + } + + ssl->s3->session_reused = true; + // Only authentication information carries over in TLS 1.3. + hs->new_session = SSL_SESSION_dup(ssl->session, SSL_SESSION_DUP_AUTH_ONLY); + if (!hs->new_session) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return ssl_hs_error; + } + ssl_set_session(ssl, NULL); + + // Resumption incorporates fresh key material, so refresh the timeout. + ssl_session_renew_timeout(ssl, hs->new_session.get(), + ssl->session_ctx->session_psk_dhe_timeout); + } else if (!ssl_get_new_session(hs, 0)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return ssl_hs_error; + } + + hs->new_session->cipher = cipher; + hs->new_cipher = cipher; + + size_t hash_len = + EVP_MD_size(ssl_get_handshake_digest(ssl_protocol_version(ssl), cipher)); + + // Set up the key schedule and incorporate the PSK into the running secret. + if (ssl->s3->session_reused) { + if (!tls13_init_key_schedule(hs, hs->new_session->master_key, + hs->new_session->master_key_length)) { + return ssl_hs_error; + } + } else if (!tls13_init_key_schedule(hs, kZeroes, hash_len)) { + return ssl_hs_error; + } + + if (!have_key_share) { + // We do not support psk_ke and thus always require a key share. + OPENSSL_PUT_ERROR(SSL, SSL_R_MISSING_KEY_SHARE); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_MISSING_EXTENSION); + return ssl_hs_error; + } + + // Resolve ECDHE and incorporate it into the secret. + Array dhe_secret; + alert = SSL_AD_DECODE_ERROR; + if (!ssl_ext_key_share_parse_serverhello(hs, &dhe_secret, &alert, + &key_share)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + return ssl_hs_error; + } + + if (!tls13_advance_key_schedule(hs, dhe_secret.data(), dhe_secret.size()) || + !ssl_hash_message(hs, msg) || + !tls13_derive_handshake_secrets(hs) || + !tls13_set_traffic_key(ssl, evp_aead_open, hs->server_handshake_secret, + hs->hash_len)) { + return ssl_hs_error; + } + + if (!hs->early_data_offered) { + // If not sending early data, set client traffic keys now so that alerts are + // encrypted. + if (!tls13_set_traffic_key(ssl, evp_aead_seal, hs->client_handshake_secret, + hs->hash_len)) { + return ssl_hs_error; + } + } + + ssl->method->next_message(ssl); + hs->tls13_state = state_read_encrypted_extensions; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_read_encrypted_extensions(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + SSLMessage msg; + if (!ssl->method->get_message(ssl, &msg)) { + return ssl_hs_read_message; + } + if (!ssl_check_message_type(ssl, msg, SSL3_MT_ENCRYPTED_EXTENSIONS)) { + return ssl_hs_error; + } + + CBS body = msg.body; + if (!ssl_parse_serverhello_tlsext(hs, &body)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_PARSE_TLSEXT); + return ssl_hs_error; + } + if (CBS_len(&body) != 0) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return ssl_hs_error; + } + + // Store the negotiated ALPN in the session. + if (!ssl->s3->alpn_selected.empty()) { + hs->new_session->early_alpn = (uint8_t *)BUF_memdup( + ssl->s3->alpn_selected.data(), ssl->s3->alpn_selected.size()); + if (hs->new_session->early_alpn == NULL) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return ssl_hs_error; + } + hs->new_session->early_alpn_len = ssl->s3->alpn_selected.size(); + } + + if (ssl->s3->early_data_accepted) { + if (hs->early_session->cipher != hs->new_session->cipher || + MakeConstSpan(hs->early_session->early_alpn, + hs->early_session->early_alpn_len) != + ssl->s3->alpn_selected) { + OPENSSL_PUT_ERROR(SSL, SSL_R_ALPN_MISMATCH_ON_EARLY_DATA); + return ssl_hs_error; + } + if (ssl->s3->tlsext_channel_id_valid || hs->received_custom_extension || + ssl->token_binding_negotiated) { + OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_EXTENSION_ON_EARLY_DATA); + return ssl_hs_error; + } + } + + if (!ssl_hash_message(hs, msg)) { + return ssl_hs_error; + } + + ssl->method->next_message(ssl); + hs->tls13_state = state_read_certificate_request; + if (hs->in_early_data && !ssl->s3->early_data_accepted) { + return ssl_hs_early_data_rejected; + } + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_read_certificate_request(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + // CertificateRequest may only be sent in non-resumption handshakes. + if (ssl->s3->session_reused) { + hs->tls13_state = state_read_server_finished; + return ssl_hs_ok; + } + + SSLMessage msg; + if (!ssl->method->get_message(ssl, &msg)) { + return ssl_hs_read_message; + } + + // CertificateRequest is optional. + if (msg.type != SSL3_MT_CERTIFICATE_REQUEST) { + hs->tls13_state = state_read_server_certificate; + return ssl_hs_ok; + } + + + bool have_sigalgs = false, have_ca = false; + CBS sigalgs, ca; + const SSL_EXTENSION_TYPE ext_types[] = { + {TLSEXT_TYPE_signature_algorithms, &have_sigalgs, &sigalgs}, + {TLSEXT_TYPE_certificate_authorities, &have_ca, &ca}, + }; + + CBS body = msg.body, context, extensions, supported_signature_algorithms; + uint8_t alert = SSL_AD_DECODE_ERROR; + if (!CBS_get_u8_length_prefixed(&body, &context) || + // The request context is always empty during the handshake. + CBS_len(&context) != 0 || + !CBS_get_u16_length_prefixed(&body, &extensions) || + CBS_len(&body) != 0 || + !ssl_parse_extensions(&extensions, &alert, ext_types, + OPENSSL_ARRAY_SIZE(ext_types), + 1 /* accept unknown */) || + (have_ca && CBS_len(&ca) == 0) || + !have_sigalgs || + !CBS_get_u16_length_prefixed(&sigalgs, + &supported_signature_algorithms) || + CBS_len(&supported_signature_algorithms) == 0 || + !tls1_parse_peer_sigalgs(hs, &supported_signature_algorithms)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + return ssl_hs_error; + } + + if (have_ca) { + hs->ca_names = ssl_parse_client_CA_list(ssl, &alert, &ca); + if (!hs->ca_names) { + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + return ssl_hs_error; + } + } else { + hs->ca_names.reset(sk_CRYPTO_BUFFER_new_null()); + if (!hs->ca_names) { + OPENSSL_PUT_ERROR(SSL, ERR_R_MALLOC_FAILURE); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return ssl_hs_error; + } + } + + hs->cert_request = true; + ssl->ctx->x509_method->hs_flush_cached_ca_names(hs); + + if (!ssl_hash_message(hs, msg)) { + return ssl_hs_error; + } + + ssl->method->next_message(ssl); + hs->tls13_state = state_read_server_certificate; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_read_server_certificate(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + SSLMessage msg; + if (!ssl->method->get_message(ssl, &msg)) { + return ssl_hs_read_message; + } + if (!ssl_check_message_type(ssl, msg, SSL3_MT_CERTIFICATE) || + !tls13_process_certificate(hs, msg, 0 /* certificate required */) || + !ssl_hash_message(hs, msg)) { + return ssl_hs_error; + } + + ssl->method->next_message(ssl); + hs->tls13_state = state_read_server_certificate_verify; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_read_server_certificate_verify( + SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + SSLMessage msg; + if (!ssl->method->get_message(ssl, &msg)) { + return ssl_hs_read_message; + } + switch (ssl_verify_peer_cert(hs)) { + case ssl_verify_ok: + break; + case ssl_verify_invalid: + return ssl_hs_error; + case ssl_verify_retry: + hs->tls13_state = state_read_server_certificate_verify; + return ssl_hs_certificate_verify; + } + + if (!ssl_check_message_type(ssl, msg, SSL3_MT_CERTIFICATE_VERIFY) || + !tls13_process_certificate_verify(hs, msg) || + !ssl_hash_message(hs, msg)) { + return ssl_hs_error; + } + + ssl->method->next_message(ssl); + hs->tls13_state = state_read_server_finished; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_read_server_finished(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + SSLMessage msg; + if (!ssl->method->get_message(ssl, &msg)) { + return ssl_hs_read_message; + } + if (!ssl_check_message_type(ssl, msg, SSL3_MT_FINISHED) || + !tls13_process_finished(hs, msg, 0 /* don't use saved value */) || + !ssl_hash_message(hs, msg) || + // Update the secret to the master secret and derive traffic keys. + !tls13_advance_key_schedule(hs, kZeroes, hs->hash_len) || + !tls13_derive_application_secrets(hs)) { + return ssl_hs_error; + } + + ssl->method->next_message(ssl); + hs->tls13_state = state_send_end_of_early_data; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_send_end_of_early_data(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + + if (ssl->s3->early_data_accepted) { + hs->can_early_write = false; + ScopedCBB cbb; + CBB body; + if (!ssl->method->init_message(ssl, cbb.get(), &body, + SSL3_MT_END_OF_EARLY_DATA) || + !ssl_add_message_cbb(ssl, cbb.get())) { + return ssl_hs_error; + } + } + + if (hs->early_data_offered) { + if (!tls13_set_traffic_key(ssl, evp_aead_seal, hs->client_handshake_secret, + hs->hash_len)) { + return ssl_hs_error; + } + } + + hs->tls13_state = state_send_client_certificate; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_send_client_certificate(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + + // The peer didn't request a certificate. + if (!hs->cert_request) { + hs->tls13_state = state_complete_second_flight; + return ssl_hs_ok; + } + + // Call cert_cb to update the certificate. + if (ssl->cert->cert_cb != NULL) { + int rv = ssl->cert->cert_cb(ssl, ssl->cert->cert_cb_arg); + if (rv == 0) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + OPENSSL_PUT_ERROR(SSL, SSL_R_CERT_CB_ERROR); + return ssl_hs_error; + } + if (rv < 0) { + hs->tls13_state = state_send_client_certificate; + return ssl_hs_x509_lookup; + } + } + + if (!ssl_on_certificate_selected(hs) || + !tls13_add_certificate(hs)) { + return ssl_hs_error; + } + + hs->tls13_state = state_send_client_certificate_verify; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_send_client_certificate_verify(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + // Don't send CertificateVerify if there is no certificate. + if (!ssl_has_certificate(ssl)) { + hs->tls13_state = state_complete_second_flight; + return ssl_hs_ok; + } + + switch (tls13_add_certificate_verify(hs)) { + case ssl_private_key_success: + hs->tls13_state = state_complete_second_flight; + return ssl_hs_ok; + + case ssl_private_key_retry: + hs->tls13_state = state_send_client_certificate_verify; + return ssl_hs_private_key_operation; + + case ssl_private_key_failure: + return ssl_hs_error; + } + + assert(0); + return ssl_hs_error; +} + +static enum ssl_hs_wait_t do_complete_second_flight(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + + // Send a Channel ID assertion if necessary. + if (ssl->s3->tlsext_channel_id_valid) { + if (!ssl_do_channel_id_callback(ssl)) { + hs->tls13_state = state_complete_second_flight; + return ssl_hs_error; + } + + if (ssl->tlsext_channel_id_private == NULL) { + return ssl_hs_channel_id_lookup; + } + + ScopedCBB cbb; + CBB body; + if (!ssl->method->init_message(ssl, cbb.get(), &body, SSL3_MT_CHANNEL_ID) || + !tls1_write_channel_id(hs, &body) || + !ssl_add_message_cbb(ssl, cbb.get())) { + return ssl_hs_error; + } + } + + // Send a Finished message. + if (!tls13_add_finished(hs)) { + return ssl_hs_error; + } + + // Derive the final keys and enable them. + if (!tls13_set_traffic_key(ssl, evp_aead_open, hs->server_traffic_secret_0, + hs->hash_len) || + !tls13_set_traffic_key(ssl, evp_aead_seal, hs->client_traffic_secret_0, + hs->hash_len) || + !tls13_derive_resumption_secret(hs)) { + return ssl_hs_error; + } + + hs->tls13_state = state_done; + return ssl_hs_flush; +} + +enum ssl_hs_wait_t tls13_client_handshake(SSL_HANDSHAKE *hs) { + while (hs->tls13_state != state_done) { + enum ssl_hs_wait_t ret = ssl_hs_error; + enum client_hs_state_t state = + static_cast(hs->tls13_state); + switch (state) { + case state_read_hello_retry_request: + ret = do_read_hello_retry_request(hs); + break; + case state_send_second_client_hello: + ret = do_send_second_client_hello(hs); + break; + case state_read_server_hello: + ret = do_read_server_hello(hs); + break; + case state_read_encrypted_extensions: + ret = do_read_encrypted_extensions(hs); + break; + case state_read_certificate_request: + ret = do_read_certificate_request(hs); + break; + case state_read_server_certificate: + ret = do_read_server_certificate(hs); + break; + case state_read_server_certificate_verify: + ret = do_read_server_certificate_verify(hs); + break; + case state_read_server_finished: + ret = do_read_server_finished(hs); + break; + case state_send_end_of_early_data: + ret = do_send_end_of_early_data(hs); + break; + case state_send_client_certificate: + ret = do_send_client_certificate(hs); + break; + case state_send_client_certificate_verify: + ret = do_send_client_certificate_verify(hs); + break; + case state_complete_second_flight: + ret = do_complete_second_flight(hs); + break; + case state_done: + ret = ssl_hs_ok; + break; + } + + if (hs->tls13_state != state) { + ssl_do_info_callback(hs->ssl, SSL_CB_CONNECT_LOOP, 1); + } + + if (ret != ssl_hs_ok) { + return ret; + } + } + + return ssl_hs_ok; +} + +const char *tls13_client_handshake_state(SSL_HANDSHAKE *hs) { + enum client_hs_state_t state = + static_cast(hs->tls13_state); + switch (state) { + case state_read_hello_retry_request: + return "TLS 1.3 client read_hello_retry_request"; + case state_send_second_client_hello: + return "TLS 1.3 client send_second_client_hello"; + case state_read_server_hello: + return "TLS 1.3 client read_server_hello"; + case state_read_encrypted_extensions: + return "TLS 1.3 client read_encrypted_extensions"; + case state_read_certificate_request: + return "TLS 1.3 client read_certificate_request"; + case state_read_server_certificate: + return "TLS 1.3 client read_server_certificate"; + case state_read_server_certificate_verify: + return "TLS 1.3 client read_server_certificate_verify"; + case state_read_server_finished: + return "TLS 1.3 client read_server_finished"; + case state_send_end_of_early_data: + return "TLS 1.3 client send_end_of_early_data"; + case state_send_client_certificate: + return "TLS 1.3 client send_client_certificate"; + case state_send_client_certificate_verify: + return "TLS 1.3 client send_client_certificate_verify"; + case state_complete_second_flight: + return "TLS 1.3 client complete_second_flight"; + case state_done: + return "TLS 1.3 client done"; + } + + return "TLS 1.3 client unknown"; +} + +int tls13_process_new_session_ticket(SSL *ssl, const SSLMessage &msg) { + if (ssl->s3->write_shutdown != ssl_shutdown_none) { + // Ignore tickets on shutdown. Callers tend to indiscriminately call + // |SSL_shutdown| before destroying an |SSL|, at which point calling the new + // session callback may be confusing. + return 1; + } + + UniquePtr session = SSL_SESSION_dup( + ssl->s3->established_session.get(), SSL_SESSION_INCLUDE_NONAUTH); + if (!session) { + return 0; + } + + ssl_session_rebase_time(ssl, session.get()); + + uint32_t server_timeout; + CBS body = msg.body, ticket_nonce, ticket, extensions; + if (!CBS_get_u32(&body, &server_timeout) || + !CBS_get_u32(&body, &session->ticket_age_add) || + !CBS_get_u8_length_prefixed(&body, &ticket_nonce) || + !CBS_get_u16_length_prefixed(&body, &ticket) || + !CBS_stow(&ticket, &session->tlsext_tick, &session->tlsext_ticklen) || + !CBS_get_u16_length_prefixed(&body, &extensions) || + CBS_len(&body) != 0) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + return 0; + } + + // Cap the renewable lifetime by the server advertised value. This avoids + // wasting bandwidth on 0-RTT when we know the server will reject it. + if (session->timeout > server_timeout) { + session->timeout = server_timeout; + } + + if (!tls13_derive_session_psk(session.get(), ticket_nonce)) { + return 0; + } + + // Parse out the extensions. + bool have_early_data_info = false; + CBS early_data_info; + const SSL_EXTENSION_TYPE ext_types[] = { + {TLSEXT_TYPE_early_data, &have_early_data_info, &early_data_info}, + }; + + uint8_t alert = SSL_AD_DECODE_ERROR; + if (!ssl_parse_extensions(&extensions, &alert, ext_types, + OPENSSL_ARRAY_SIZE(ext_types), + 1 /* ignore unknown */)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + return 0; + } + + if (have_early_data_info && ssl->cert->enable_early_data) { + if (!CBS_get_u32(&early_data_info, &session->ticket_max_early_data) || + CBS_len(&early_data_info) != 0) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + return 0; + } + } + + session->ticket_age_add_valid = 1; + session->not_resumable = 0; + + if ((ssl->ctx->session_cache_mode & SSL_SESS_CACHE_CLIENT) && + ssl->ctx->new_session_cb != NULL && + ssl->ctx->new_session_cb(ssl, session.get())) { + // |new_session_cb|'s return value signals that it took ownership. + session.release(); + } + + return 1; +} + +} // namespace bssl diff --git a/FoodApp/Pods/BoringSSL-GRPC/ssl/tls13_enc.cc b/FoodApp/Pods/BoringSSL-GRPC/ssl/tls13_enc.cc new file mode 100644 index 0000000..65bc4f6 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/ssl/tls13_enc.cc @@ -0,0 +1,493 @@ +/* Copyright (c) 2016, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include "../crypto/internal.h" +#include "internal.h" + + +namespace bssl { + +static int init_key_schedule(SSL_HANDSHAKE *hs, uint16_t version, + const SSL_CIPHER *cipher) { + if (!hs->transcript.InitHash(version, cipher)) { + return 0; + } + + hs->hash_len = hs->transcript.DigestLen(); + + // Initialize the secret to the zero key. + OPENSSL_memset(hs->secret, 0, hs->hash_len); + + return 1; +} + +int tls13_init_key_schedule(SSL_HANDSHAKE *hs, const uint8_t *psk, + size_t psk_len) { + if (!init_key_schedule(hs, ssl_protocol_version(hs->ssl), hs->new_cipher)) { + return 0; + } + + hs->transcript.FreeBuffer(); + return HKDF_extract(hs->secret, &hs->hash_len, hs->transcript.Digest(), psk, + psk_len, hs->secret, hs->hash_len); +} + +int tls13_init_early_key_schedule(SSL_HANDSHAKE *hs, const uint8_t *psk, + size_t psk_len) { + SSL *const ssl = hs->ssl; + return init_key_schedule(hs, ssl_session_protocol_version(ssl->session), + ssl->session->cipher) && + HKDF_extract(hs->secret, &hs->hash_len, hs->transcript.Digest(), psk, + psk_len, hs->secret, hs->hash_len); +} + +static int hkdf_expand_label(uint8_t *out, const EVP_MD *digest, + const uint8_t *secret, size_t secret_len, + const char *label, size_t label_len, + const uint8_t *hash, size_t hash_len, size_t len) { + static const char kTLS13LabelVersion[] = "tls13 "; + + ScopedCBB cbb; + CBB child; + uint8_t *hkdf_label; + size_t hkdf_label_len; + if (!CBB_init(cbb.get(), 2 + 1 + strlen(kTLS13LabelVersion) + label_len + 1 + + hash_len) || + !CBB_add_u16(cbb.get(), len) || + !CBB_add_u8_length_prefixed(cbb.get(), &child) || + !CBB_add_bytes(&child, (const uint8_t *)kTLS13LabelVersion, + strlen(kTLS13LabelVersion)) || + !CBB_add_bytes(&child, (const uint8_t *)label, label_len) || + !CBB_add_u8_length_prefixed(cbb.get(), &child) || + !CBB_add_bytes(&child, hash, hash_len) || + !CBB_finish(cbb.get(), &hkdf_label, &hkdf_label_len)) { + return 0; + } + + int ret = HKDF_expand(out, len, digest, secret, secret_len, hkdf_label, + hkdf_label_len); + OPENSSL_free(hkdf_label); + return ret; +} + +static const char kTLS13LabelDerived[] = "derived"; + +int tls13_advance_key_schedule(SSL_HANDSHAKE *hs, const uint8_t *in, + size_t len) { + uint8_t derive_context[EVP_MAX_MD_SIZE]; + unsigned derive_context_len; + if (!EVP_Digest(nullptr, 0, derive_context, &derive_context_len, + hs->transcript.Digest(), nullptr)) { + return 0; + } + + if (!hkdf_expand_label(hs->secret, hs->transcript.Digest(), hs->secret, + hs->hash_len, kTLS13LabelDerived, + strlen(kTLS13LabelDerived), derive_context, + derive_context_len, hs->hash_len)) { + return 0; + } + + return HKDF_extract(hs->secret, &hs->hash_len, hs->transcript.Digest(), in, + len, hs->secret, hs->hash_len); +} + +// derive_secret derives a secret of length |len| and writes the result in |out| +// with the given label and the current base secret and most recently-saved +// handshake context. It returns one on success and zero on error. +static int derive_secret(SSL_HANDSHAKE *hs, uint8_t *out, size_t len, + const char *label, size_t label_len) { + uint8_t context_hash[EVP_MAX_MD_SIZE]; + size_t context_hash_len; + if (!hs->transcript.GetHash(context_hash, &context_hash_len)) { + return 0; + } + + return hkdf_expand_label(out, hs->transcript.Digest(), hs->secret, + hs->hash_len, label, label_len, context_hash, + context_hash_len, len); +} + +int tls13_set_traffic_key(SSL *ssl, enum evp_aead_direction_t direction, + const uint8_t *traffic_secret, + size_t traffic_secret_len) { + const SSL_SESSION *session = SSL_get_session(ssl); + uint16_t version = ssl_session_protocol_version(session); + + if (traffic_secret_len > 0xff) { + OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW); + return 0; + } + + // Look up cipher suite properties. + const EVP_AEAD *aead; + size_t discard; + if (!ssl_cipher_get_evp_aead(&aead, &discard, &discard, session->cipher, + version, SSL_is_dtls(ssl))) { + return 0; + } + + const EVP_MD *digest = ssl_session_get_digest(session); + + // Derive the key. + size_t key_len = EVP_AEAD_key_length(aead); + uint8_t key[EVP_AEAD_MAX_KEY_LENGTH]; + if (!hkdf_expand_label(key, digest, traffic_secret, traffic_secret_len, "key", + 3, NULL, 0, key_len)) { + return 0; + } + + // Derive the IV. + size_t iv_len = EVP_AEAD_nonce_length(aead); + uint8_t iv[EVP_AEAD_MAX_NONCE_LENGTH]; + if (!hkdf_expand_label(iv, digest, traffic_secret, traffic_secret_len, "iv", + 2, NULL, 0, iv_len)) { + return 0; + } + + UniquePtr traffic_aead = + SSLAEADContext::Create(direction, session->ssl_version, SSL_is_dtls(ssl), + session->cipher, MakeConstSpan(key, key_len), + Span(), MakeConstSpan(iv, iv_len)); + if (!traffic_aead) { + return 0; + } + + if (direction == evp_aead_open) { + if (!ssl->method->set_read_state(ssl, std::move(traffic_aead))) { + return 0; + } + } else { + if (!ssl->method->set_write_state(ssl, std::move(traffic_aead))) { + return 0; + } + } + + // Save the traffic secret. + if (direction == evp_aead_open) { + OPENSSL_memmove(ssl->s3->read_traffic_secret, traffic_secret, + traffic_secret_len); + ssl->s3->read_traffic_secret_len = traffic_secret_len; + } else { + OPENSSL_memmove(ssl->s3->write_traffic_secret, traffic_secret, + traffic_secret_len); + ssl->s3->write_traffic_secret_len = traffic_secret_len; + } + + return 1; +} + + +static const char kTLS13LabelExporter[] = "exp master"; +static const char kTLS13LabelEarlyExporter[] = "e exp master"; + +static const char kTLS13LabelClientEarlyTraffic[] = "c e traffic"; +static const char kTLS13LabelClientHandshakeTraffic[] = "c hs traffic"; +static const char kTLS13LabelServerHandshakeTraffic[] = "s hs traffic"; +static const char kTLS13LabelClientApplicationTraffic[] = "c ap traffic"; +static const char kTLS13LabelServerApplicationTraffic[] = "s ap traffic"; + +int tls13_derive_early_secrets(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + if (!derive_secret(hs, hs->early_traffic_secret, hs->hash_len, + kTLS13LabelClientEarlyTraffic, + strlen(kTLS13LabelClientEarlyTraffic)) || + !ssl_log_secret(ssl, "CLIENT_EARLY_TRAFFIC_SECRET", + hs->early_traffic_secret, hs->hash_len) || + !derive_secret(hs, ssl->s3->early_exporter_secret, hs->hash_len, + kTLS13LabelEarlyExporter, + strlen(kTLS13LabelEarlyExporter))) { + return 0; + } + ssl->s3->early_exporter_secret_len = hs->hash_len; + return 1; +} + +int tls13_derive_handshake_secrets(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + return derive_secret(hs, hs->client_handshake_secret, hs->hash_len, + kTLS13LabelClientHandshakeTraffic, + strlen(kTLS13LabelClientHandshakeTraffic)) && + ssl_log_secret(ssl, "CLIENT_HANDSHAKE_TRAFFIC_SECRET", + hs->client_handshake_secret, hs->hash_len) && + derive_secret(hs, hs->server_handshake_secret, hs->hash_len, + kTLS13LabelServerHandshakeTraffic, + strlen(kTLS13LabelServerHandshakeTraffic)) && + ssl_log_secret(ssl, "SERVER_HANDSHAKE_TRAFFIC_SECRET", + hs->server_handshake_secret, hs->hash_len); +} + +int tls13_derive_application_secrets(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + ssl->s3->exporter_secret_len = hs->hash_len; + return derive_secret(hs, hs->client_traffic_secret_0, hs->hash_len, + kTLS13LabelClientApplicationTraffic, + strlen(kTLS13LabelClientApplicationTraffic)) && + ssl_log_secret(ssl, "CLIENT_TRAFFIC_SECRET_0", + hs->client_traffic_secret_0, hs->hash_len) && + derive_secret(hs, hs->server_traffic_secret_0, hs->hash_len, + kTLS13LabelServerApplicationTraffic, + strlen(kTLS13LabelServerApplicationTraffic)) && + ssl_log_secret(ssl, "SERVER_TRAFFIC_SECRET_0", + hs->server_traffic_secret_0, hs->hash_len) && + derive_secret(hs, ssl->s3->exporter_secret, hs->hash_len, + kTLS13LabelExporter, strlen(kTLS13LabelExporter)) && + ssl_log_secret(ssl, "EXPORTER_SECRET", ssl->s3->exporter_secret, + hs->hash_len); +} + +static const char kTLS13LabelApplicationTraffic[] = "traffic upd"; + +int tls13_rotate_traffic_key(SSL *ssl, enum evp_aead_direction_t direction) { + uint8_t *secret; + size_t secret_len; + if (direction == evp_aead_open) { + secret = ssl->s3->read_traffic_secret; + secret_len = ssl->s3->read_traffic_secret_len; + } else { + secret = ssl->s3->write_traffic_secret; + secret_len = ssl->s3->write_traffic_secret_len; + } + + const EVP_MD *digest = ssl_session_get_digest(SSL_get_session(ssl)); + if (!hkdf_expand_label( + secret, digest, secret, secret_len, kTLS13LabelApplicationTraffic, + strlen(kTLS13LabelApplicationTraffic), NULL, 0, secret_len)) { + return 0; + } + + return tls13_set_traffic_key(ssl, direction, secret, secret_len); +} + +static const char kTLS13LabelResumption[] = "res master"; + +int tls13_derive_resumption_secret(SSL_HANDSHAKE *hs) { + if (hs->hash_len > SSL_MAX_MASTER_KEY_LENGTH) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return 0; + } + hs->new_session->master_key_length = hs->hash_len; + return derive_secret(hs, hs->new_session->master_key, + hs->new_session->master_key_length, + kTLS13LabelResumption, strlen(kTLS13LabelResumption)); +} + +static const char kTLS13LabelFinished[] = "finished"; + +// tls13_verify_data sets |out| to be the HMAC of |context| using a derived +// Finished key for both Finished messages and the PSK binder. +static int tls13_verify_data(const EVP_MD *digest, uint16_t version, + uint8_t *out, size_t *out_len, + const uint8_t *secret, size_t hash_len, + uint8_t *context, size_t context_len) { + uint8_t key[EVP_MAX_MD_SIZE]; + unsigned len; + if (!hkdf_expand_label(key, digest, secret, hash_len, kTLS13LabelFinished, + strlen(kTLS13LabelFinished), NULL, 0, hash_len) || + HMAC(digest, key, hash_len, context, context_len, out, &len) == NULL) { + return 0; + } + *out_len = len; + return 1; +} + +int tls13_finished_mac(SSL_HANDSHAKE *hs, uint8_t *out, size_t *out_len, + int is_server) { + const uint8_t *traffic_secret; + if (is_server) { + traffic_secret = hs->server_handshake_secret; + } else { + traffic_secret = hs->client_handshake_secret; + } + + uint8_t context_hash[EVP_MAX_MD_SIZE]; + size_t context_hash_len; + if (!hs->transcript.GetHash(context_hash, &context_hash_len) || + !tls13_verify_data(hs->transcript.Digest(), hs->ssl->version, out, + out_len, traffic_secret, hs->hash_len, context_hash, + context_hash_len)) { + return 0; + } + return 1; +} + +static const char kTLS13LabelResumptionPSK[] = "resumption"; + +bool tls13_derive_session_psk(SSL_SESSION *session, Span nonce) { + const EVP_MD *digest = ssl_session_get_digest(session); + return hkdf_expand_label(session->master_key, digest, session->master_key, + session->master_key_length, kTLS13LabelResumptionPSK, + strlen(kTLS13LabelResumptionPSK), nonce.data(), + nonce.size(), session->master_key_length); +} + +static const char kTLS13LabelExportKeying[] = "exporter"; + +int tls13_export_keying_material(SSL *ssl, Span out, + Span secret, + Span label, + Span context) { + if (secret.empty()) { + assert(0); + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return 0; + } + + const EVP_MD *digest = ssl_session_get_digest(SSL_get_session(ssl)); + + uint8_t hash[EVP_MAX_MD_SIZE]; + uint8_t export_context[EVP_MAX_MD_SIZE]; + uint8_t derived_secret[EVP_MAX_MD_SIZE]; + unsigned hash_len; + unsigned export_context_len; + unsigned derived_secret_len = EVP_MD_size(digest); + return EVP_Digest(context.data(), context.size(), hash, &hash_len, digest, + nullptr) && + EVP_Digest(nullptr, 0, export_context, &export_context_len, digest, + nullptr) && + hkdf_expand_label(derived_secret, digest, secret.data(), secret.size(), + label.data(), label.size(), export_context, + export_context_len, derived_secret_len) && + hkdf_expand_label(out.data(), digest, derived_secret, + derived_secret_len, kTLS13LabelExportKeying, + strlen(kTLS13LabelExportKeying), hash, hash_len, + out.size()); +} + +static const char kTLS13LabelPSKBinder[] = "res binder"; + +static int tls13_psk_binder(uint8_t *out, uint16_t version, + const EVP_MD *digest, uint8_t *psk, size_t psk_len, + uint8_t *context, size_t context_len, + size_t hash_len) { + uint8_t binder_context[EVP_MAX_MD_SIZE]; + unsigned binder_context_len; + if (!EVP_Digest(NULL, 0, binder_context, &binder_context_len, digest, NULL)) { + return 0; + } + + uint8_t early_secret[EVP_MAX_MD_SIZE] = {0}; + size_t early_secret_len; + if (!HKDF_extract(early_secret, &early_secret_len, digest, psk, hash_len, + NULL, 0)) { + return 0; + } + + uint8_t binder_key[EVP_MAX_MD_SIZE] = {0}; + size_t len; + if (!hkdf_expand_label(binder_key, digest, early_secret, hash_len, + kTLS13LabelPSKBinder, strlen(kTLS13LabelPSKBinder), + binder_context, binder_context_len, hash_len) || + !tls13_verify_data(digest, version, out, &len, binder_key, hash_len, + context, context_len)) { + return 0; + } + + return 1; +} + +int tls13_write_psk_binder(SSL_HANDSHAKE *hs, uint8_t *msg, size_t len) { + SSL *const ssl = hs->ssl; + const EVP_MD *digest = ssl_session_get_digest(ssl->session); + size_t hash_len = EVP_MD_size(digest); + + if (len < hash_len + 3) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return 0; + } + + ScopedEVP_MD_CTX ctx; + uint8_t context[EVP_MAX_MD_SIZE]; + unsigned context_len; + + if (!EVP_DigestInit_ex(ctx.get(), digest, NULL) || + !EVP_DigestUpdate(ctx.get(), hs->transcript.buffer().data(), + hs->transcript.buffer().size()) || + !EVP_DigestUpdate(ctx.get(), msg, len - hash_len - 3) || + !EVP_DigestFinal_ex(ctx.get(), context, &context_len)) { + return 0; + } + + uint8_t verify_data[EVP_MAX_MD_SIZE] = {0}; + if (!tls13_psk_binder(verify_data, ssl->session->ssl_version, digest, + ssl->session->master_key, + ssl->session->master_key_length, context, context_len, + hash_len)) { + return 0; + } + + OPENSSL_memcpy(msg + len - hash_len, verify_data, hash_len); + return 1; +} + +int tls13_verify_psk_binder(SSL_HANDSHAKE *hs, SSL_SESSION *session, + const SSLMessage &msg, CBS *binders) { + size_t hash_len = hs->transcript.DigestLen(); + + // The message must be large enough to exclude the binders. + if (CBS_len(&msg.raw) < CBS_len(binders) + 2) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return 0; + } + + // Hash a ClientHello prefix up to the binders. This includes the header. For + // now, this assumes we only ever verify PSK binders on initial + // ClientHellos. + uint8_t context[EVP_MAX_MD_SIZE]; + unsigned context_len; + if (!EVP_Digest(CBS_data(&msg.raw), CBS_len(&msg.raw) - CBS_len(binders) - 2, + context, &context_len, hs->transcript.Digest(), NULL)) { + return 0; + } + + uint8_t verify_data[EVP_MAX_MD_SIZE] = {0}; + CBS binder; + if (!tls13_psk_binder(verify_data, hs->ssl->version, hs->transcript.Digest(), + session->master_key, session->master_key_length, + context, context_len, hash_len) || + // We only consider the first PSK, so compare against the first binder. + !CBS_get_u8_length_prefixed(binders, &binder)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return 0; + } + + int binder_ok = + CBS_len(&binder) == hash_len && + CRYPTO_memcmp(CBS_data(&binder), verify_data, hash_len) == 0; +#if defined(BORINGSSL_UNSAFE_FUZZER_MODE) + binder_ok = 1; +#endif + if (!binder_ok) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DIGEST_CHECK_FAILED); + return 0; + } + + return 1; +} + +} // namespace bssl diff --git a/FoodApp/Pods/BoringSSL-GRPC/ssl/tls13_enc.cc.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/ssl/tls13_enc.cc.grpc_back new file mode 100644 index 0000000..cc7afb8 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/ssl/tls13_enc.cc.grpc_back @@ -0,0 +1,493 @@ +/* Copyright (c) 2016, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +#include + +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include "../crypto/internal.h" +#include "internal.h" + + +namespace bssl { + +static int init_key_schedule(SSL_HANDSHAKE *hs, uint16_t version, + const SSL_CIPHER *cipher) { + if (!hs->transcript.InitHash(version, cipher)) { + return 0; + } + + hs->hash_len = hs->transcript.DigestLen(); + + // Initialize the secret to the zero key. + OPENSSL_memset(hs->secret, 0, hs->hash_len); + + return 1; +} + +int tls13_init_key_schedule(SSL_HANDSHAKE *hs, const uint8_t *psk, + size_t psk_len) { + if (!init_key_schedule(hs, ssl_protocol_version(hs->ssl), hs->new_cipher)) { + return 0; + } + + hs->transcript.FreeBuffer(); + return HKDF_extract(hs->secret, &hs->hash_len, hs->transcript.Digest(), psk, + psk_len, hs->secret, hs->hash_len); +} + +int tls13_init_early_key_schedule(SSL_HANDSHAKE *hs, const uint8_t *psk, + size_t psk_len) { + SSL *const ssl = hs->ssl; + return init_key_schedule(hs, ssl_session_protocol_version(ssl->session), + ssl->session->cipher) && + HKDF_extract(hs->secret, &hs->hash_len, hs->transcript.Digest(), psk, + psk_len, hs->secret, hs->hash_len); +} + +static int hkdf_expand_label(uint8_t *out, const EVP_MD *digest, + const uint8_t *secret, size_t secret_len, + const char *label, size_t label_len, + const uint8_t *hash, size_t hash_len, size_t len) { + static const char kTLS13LabelVersion[] = "tls13 "; + + ScopedCBB cbb; + CBB child; + uint8_t *hkdf_label; + size_t hkdf_label_len; + if (!CBB_init(cbb.get(), 2 + 1 + strlen(kTLS13LabelVersion) + label_len + 1 + + hash_len) || + !CBB_add_u16(cbb.get(), len) || + !CBB_add_u8_length_prefixed(cbb.get(), &child) || + !CBB_add_bytes(&child, (const uint8_t *)kTLS13LabelVersion, + strlen(kTLS13LabelVersion)) || + !CBB_add_bytes(&child, (const uint8_t *)label, label_len) || + !CBB_add_u8_length_prefixed(cbb.get(), &child) || + !CBB_add_bytes(&child, hash, hash_len) || + !CBB_finish(cbb.get(), &hkdf_label, &hkdf_label_len)) { + return 0; + } + + int ret = HKDF_expand(out, len, digest, secret, secret_len, hkdf_label, + hkdf_label_len); + OPENSSL_free(hkdf_label); + return ret; +} + +static const char kTLS13LabelDerived[] = "derived"; + +int tls13_advance_key_schedule(SSL_HANDSHAKE *hs, const uint8_t *in, + size_t len) { + uint8_t derive_context[EVP_MAX_MD_SIZE]; + unsigned derive_context_len; + if (!EVP_Digest(nullptr, 0, derive_context, &derive_context_len, + hs->transcript.Digest(), nullptr)) { + return 0; + } + + if (!hkdf_expand_label(hs->secret, hs->transcript.Digest(), hs->secret, + hs->hash_len, kTLS13LabelDerived, + strlen(kTLS13LabelDerived), derive_context, + derive_context_len, hs->hash_len)) { + return 0; + } + + return HKDF_extract(hs->secret, &hs->hash_len, hs->transcript.Digest(), in, + len, hs->secret, hs->hash_len); +} + +// derive_secret derives a secret of length |len| and writes the result in |out| +// with the given label and the current base secret and most recently-saved +// handshake context. It returns one on success and zero on error. +static int derive_secret(SSL_HANDSHAKE *hs, uint8_t *out, size_t len, + const char *label, size_t label_len) { + uint8_t context_hash[EVP_MAX_MD_SIZE]; + size_t context_hash_len; + if (!hs->transcript.GetHash(context_hash, &context_hash_len)) { + return 0; + } + + return hkdf_expand_label(out, hs->transcript.Digest(), hs->secret, + hs->hash_len, label, label_len, context_hash, + context_hash_len, len); +} + +int tls13_set_traffic_key(SSL *ssl, enum evp_aead_direction_t direction, + const uint8_t *traffic_secret, + size_t traffic_secret_len) { + const SSL_SESSION *session = SSL_get_session(ssl); + uint16_t version = ssl_session_protocol_version(session); + + if (traffic_secret_len > 0xff) { + OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW); + return 0; + } + + // Look up cipher suite properties. + const EVP_AEAD *aead; + size_t discard; + if (!ssl_cipher_get_evp_aead(&aead, &discard, &discard, session->cipher, + version, SSL_is_dtls(ssl))) { + return 0; + } + + const EVP_MD *digest = ssl_session_get_digest(session); + + // Derive the key. + size_t key_len = EVP_AEAD_key_length(aead); + uint8_t key[EVP_AEAD_MAX_KEY_LENGTH]; + if (!hkdf_expand_label(key, digest, traffic_secret, traffic_secret_len, "key", + 3, NULL, 0, key_len)) { + return 0; + } + + // Derive the IV. + size_t iv_len = EVP_AEAD_nonce_length(aead); + uint8_t iv[EVP_AEAD_MAX_NONCE_LENGTH]; + if (!hkdf_expand_label(iv, digest, traffic_secret, traffic_secret_len, "iv", + 2, NULL, 0, iv_len)) { + return 0; + } + + UniquePtr traffic_aead = + SSLAEADContext::Create(direction, session->ssl_version, SSL_is_dtls(ssl), + session->cipher, MakeConstSpan(key, key_len), + Span(), MakeConstSpan(iv, iv_len)); + if (!traffic_aead) { + return 0; + } + + if (direction == evp_aead_open) { + if (!ssl->method->set_read_state(ssl, std::move(traffic_aead))) { + return 0; + } + } else { + if (!ssl->method->set_write_state(ssl, std::move(traffic_aead))) { + return 0; + } + } + + // Save the traffic secret. + if (direction == evp_aead_open) { + OPENSSL_memmove(ssl->s3->read_traffic_secret, traffic_secret, + traffic_secret_len); + ssl->s3->read_traffic_secret_len = traffic_secret_len; + } else { + OPENSSL_memmove(ssl->s3->write_traffic_secret, traffic_secret, + traffic_secret_len); + ssl->s3->write_traffic_secret_len = traffic_secret_len; + } + + return 1; +} + + +static const char kTLS13LabelExporter[] = "exp master"; +static const char kTLS13LabelEarlyExporter[] = "e exp master"; + +static const char kTLS13LabelClientEarlyTraffic[] = "c e traffic"; +static const char kTLS13LabelClientHandshakeTraffic[] = "c hs traffic"; +static const char kTLS13LabelServerHandshakeTraffic[] = "s hs traffic"; +static const char kTLS13LabelClientApplicationTraffic[] = "c ap traffic"; +static const char kTLS13LabelServerApplicationTraffic[] = "s ap traffic"; + +int tls13_derive_early_secrets(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + if (!derive_secret(hs, hs->early_traffic_secret, hs->hash_len, + kTLS13LabelClientEarlyTraffic, + strlen(kTLS13LabelClientEarlyTraffic)) || + !ssl_log_secret(ssl, "CLIENT_EARLY_TRAFFIC_SECRET", + hs->early_traffic_secret, hs->hash_len) || + !derive_secret(hs, ssl->s3->early_exporter_secret, hs->hash_len, + kTLS13LabelEarlyExporter, + strlen(kTLS13LabelEarlyExporter))) { + return 0; + } + ssl->s3->early_exporter_secret_len = hs->hash_len; + return 1; +} + +int tls13_derive_handshake_secrets(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + return derive_secret(hs, hs->client_handshake_secret, hs->hash_len, + kTLS13LabelClientHandshakeTraffic, + strlen(kTLS13LabelClientHandshakeTraffic)) && + ssl_log_secret(ssl, "CLIENT_HANDSHAKE_TRAFFIC_SECRET", + hs->client_handshake_secret, hs->hash_len) && + derive_secret(hs, hs->server_handshake_secret, hs->hash_len, + kTLS13LabelServerHandshakeTraffic, + strlen(kTLS13LabelServerHandshakeTraffic)) && + ssl_log_secret(ssl, "SERVER_HANDSHAKE_TRAFFIC_SECRET", + hs->server_handshake_secret, hs->hash_len); +} + +int tls13_derive_application_secrets(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + ssl->s3->exporter_secret_len = hs->hash_len; + return derive_secret(hs, hs->client_traffic_secret_0, hs->hash_len, + kTLS13LabelClientApplicationTraffic, + strlen(kTLS13LabelClientApplicationTraffic)) && + ssl_log_secret(ssl, "CLIENT_TRAFFIC_SECRET_0", + hs->client_traffic_secret_0, hs->hash_len) && + derive_secret(hs, hs->server_traffic_secret_0, hs->hash_len, + kTLS13LabelServerApplicationTraffic, + strlen(kTLS13LabelServerApplicationTraffic)) && + ssl_log_secret(ssl, "SERVER_TRAFFIC_SECRET_0", + hs->server_traffic_secret_0, hs->hash_len) && + derive_secret(hs, ssl->s3->exporter_secret, hs->hash_len, + kTLS13LabelExporter, strlen(kTLS13LabelExporter)) && + ssl_log_secret(ssl, "EXPORTER_SECRET", ssl->s3->exporter_secret, + hs->hash_len); +} + +static const char kTLS13LabelApplicationTraffic[] = "traffic upd"; + +int tls13_rotate_traffic_key(SSL *ssl, enum evp_aead_direction_t direction) { + uint8_t *secret; + size_t secret_len; + if (direction == evp_aead_open) { + secret = ssl->s3->read_traffic_secret; + secret_len = ssl->s3->read_traffic_secret_len; + } else { + secret = ssl->s3->write_traffic_secret; + secret_len = ssl->s3->write_traffic_secret_len; + } + + const EVP_MD *digest = ssl_session_get_digest(SSL_get_session(ssl)); + if (!hkdf_expand_label( + secret, digest, secret, secret_len, kTLS13LabelApplicationTraffic, + strlen(kTLS13LabelApplicationTraffic), NULL, 0, secret_len)) { + return 0; + } + + return tls13_set_traffic_key(ssl, direction, secret, secret_len); +} + +static const char kTLS13LabelResumption[] = "res master"; + +int tls13_derive_resumption_secret(SSL_HANDSHAKE *hs) { + if (hs->hash_len > SSL_MAX_MASTER_KEY_LENGTH) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return 0; + } + hs->new_session->master_key_length = hs->hash_len; + return derive_secret(hs, hs->new_session->master_key, + hs->new_session->master_key_length, + kTLS13LabelResumption, strlen(kTLS13LabelResumption)); +} + +static const char kTLS13LabelFinished[] = "finished"; + +// tls13_verify_data sets |out| to be the HMAC of |context| using a derived +// Finished key for both Finished messages and the PSK binder. +static int tls13_verify_data(const EVP_MD *digest, uint16_t version, + uint8_t *out, size_t *out_len, + const uint8_t *secret, size_t hash_len, + uint8_t *context, size_t context_len) { + uint8_t key[EVP_MAX_MD_SIZE]; + unsigned len; + if (!hkdf_expand_label(key, digest, secret, hash_len, kTLS13LabelFinished, + strlen(kTLS13LabelFinished), NULL, 0, hash_len) || + HMAC(digest, key, hash_len, context, context_len, out, &len) == NULL) { + return 0; + } + *out_len = len; + return 1; +} + +int tls13_finished_mac(SSL_HANDSHAKE *hs, uint8_t *out, size_t *out_len, + int is_server) { + const uint8_t *traffic_secret; + if (is_server) { + traffic_secret = hs->server_handshake_secret; + } else { + traffic_secret = hs->client_handshake_secret; + } + + uint8_t context_hash[EVP_MAX_MD_SIZE]; + size_t context_hash_len; + if (!hs->transcript.GetHash(context_hash, &context_hash_len) || + !tls13_verify_data(hs->transcript.Digest(), hs->ssl->version, out, + out_len, traffic_secret, hs->hash_len, context_hash, + context_hash_len)) { + return 0; + } + return 1; +} + +static const char kTLS13LabelResumptionPSK[] = "resumption"; + +bool tls13_derive_session_psk(SSL_SESSION *session, Span nonce) { + const EVP_MD *digest = ssl_session_get_digest(session); + return hkdf_expand_label(session->master_key, digest, session->master_key, + session->master_key_length, kTLS13LabelResumptionPSK, + strlen(kTLS13LabelResumptionPSK), nonce.data(), + nonce.size(), session->master_key_length); +} + +static const char kTLS13LabelExportKeying[] = "exporter"; + +int tls13_export_keying_material(SSL *ssl, Span out, + Span secret, + Span label, + Span context) { + if (secret.empty()) { + assert(0); + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return 0; + } + + const EVP_MD *digest = ssl_session_get_digest(SSL_get_session(ssl)); + + uint8_t hash[EVP_MAX_MD_SIZE]; + uint8_t export_context[EVP_MAX_MD_SIZE]; + uint8_t derived_secret[EVP_MAX_MD_SIZE]; + unsigned hash_len; + unsigned export_context_len; + unsigned derived_secret_len = EVP_MD_size(digest); + return EVP_Digest(context.data(), context.size(), hash, &hash_len, digest, + nullptr) && + EVP_Digest(nullptr, 0, export_context, &export_context_len, digest, + nullptr) && + hkdf_expand_label(derived_secret, digest, secret.data(), secret.size(), + label.data(), label.size(), export_context, + export_context_len, derived_secret_len) && + hkdf_expand_label(out.data(), digest, derived_secret, + derived_secret_len, kTLS13LabelExportKeying, + strlen(kTLS13LabelExportKeying), hash, hash_len, + out.size()); +} + +static const char kTLS13LabelPSKBinder[] = "res binder"; + +static int tls13_psk_binder(uint8_t *out, uint16_t version, + const EVP_MD *digest, uint8_t *psk, size_t psk_len, + uint8_t *context, size_t context_len, + size_t hash_len) { + uint8_t binder_context[EVP_MAX_MD_SIZE]; + unsigned binder_context_len; + if (!EVP_Digest(NULL, 0, binder_context, &binder_context_len, digest, NULL)) { + return 0; + } + + uint8_t early_secret[EVP_MAX_MD_SIZE] = {0}; + size_t early_secret_len; + if (!HKDF_extract(early_secret, &early_secret_len, digest, psk, hash_len, + NULL, 0)) { + return 0; + } + + uint8_t binder_key[EVP_MAX_MD_SIZE] = {0}; + size_t len; + if (!hkdf_expand_label(binder_key, digest, early_secret, hash_len, + kTLS13LabelPSKBinder, strlen(kTLS13LabelPSKBinder), + binder_context, binder_context_len, hash_len) || + !tls13_verify_data(digest, version, out, &len, binder_key, hash_len, + context, context_len)) { + return 0; + } + + return 1; +} + +int tls13_write_psk_binder(SSL_HANDSHAKE *hs, uint8_t *msg, size_t len) { + SSL *const ssl = hs->ssl; + const EVP_MD *digest = ssl_session_get_digest(ssl->session); + size_t hash_len = EVP_MD_size(digest); + + if (len < hash_len + 3) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return 0; + } + + ScopedEVP_MD_CTX ctx; + uint8_t context[EVP_MAX_MD_SIZE]; + unsigned context_len; + + if (!EVP_DigestInit_ex(ctx.get(), digest, NULL) || + !EVP_DigestUpdate(ctx.get(), hs->transcript.buffer().data(), + hs->transcript.buffer().size()) || + !EVP_DigestUpdate(ctx.get(), msg, len - hash_len - 3) || + !EVP_DigestFinal_ex(ctx.get(), context, &context_len)) { + return 0; + } + + uint8_t verify_data[EVP_MAX_MD_SIZE] = {0}; + if (!tls13_psk_binder(verify_data, ssl->session->ssl_version, digest, + ssl->session->master_key, + ssl->session->master_key_length, context, context_len, + hash_len)) { + return 0; + } + + OPENSSL_memcpy(msg + len - hash_len, verify_data, hash_len); + return 1; +} + +int tls13_verify_psk_binder(SSL_HANDSHAKE *hs, SSL_SESSION *session, + const SSLMessage &msg, CBS *binders) { + size_t hash_len = hs->transcript.DigestLen(); + + // The message must be large enough to exclude the binders. + if (CBS_len(&msg.raw) < CBS_len(binders) + 2) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return 0; + } + + // Hash a ClientHello prefix up to the binders. This includes the header. For + // now, this assumes we only ever verify PSK binders on initial + // ClientHellos. + uint8_t context[EVP_MAX_MD_SIZE]; + unsigned context_len; + if (!EVP_Digest(CBS_data(&msg.raw), CBS_len(&msg.raw) - CBS_len(binders) - 2, + context, &context_len, hs->transcript.Digest(), NULL)) { + return 0; + } + + uint8_t verify_data[EVP_MAX_MD_SIZE] = {0}; + CBS binder; + if (!tls13_psk_binder(verify_data, hs->ssl->version, hs->transcript.Digest(), + session->master_key, session->master_key_length, + context, context_len, hash_len) || + // We only consider the first PSK, so compare against the first binder. + !CBS_get_u8_length_prefixed(binders, &binder)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return 0; + } + + int binder_ok = + CBS_len(&binder) == hash_len && + CRYPTO_memcmp(CBS_data(&binder), verify_data, hash_len) == 0; +#if defined(BORINGSSL_UNSAFE_FUZZER_MODE) + binder_ok = 1; +#endif + if (!binder_ok) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DIGEST_CHECK_FAILED); + return 0; + } + + return 1; +} + +} // namespace bssl diff --git a/FoodApp/Pods/BoringSSL-GRPC/ssl/tls13_server.cc b/FoodApp/Pods/BoringSSL-GRPC/ssl/tls13_server.cc new file mode 100644 index 0000000..889ea61 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/ssl/tls13_server.cc @@ -0,0 +1,1022 @@ +/* Copyright (c) 2016, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +// Per C99, various stdint.h macros are unavailable in C++ unless some macros +// are defined. C++11 overruled this decision, but older Android NDKs still +// require it. +#if !defined(__STDC_LIMIT_MACROS) +#define __STDC_LIMIT_MACROS +#endif + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "../crypto/internal.h" +#include "internal.h" + + +namespace bssl { + +enum server_hs_state_t { + state_select_parameters = 0, + state_select_session, + state_send_hello_retry_request, + state_read_second_client_hello, + state_send_server_hello, + state_send_server_certificate_verify, + state_send_server_finished, + state_read_second_client_flight, + state_process_end_of_early_data, + state_read_client_certificate, + state_read_client_certificate_verify, + state_read_channel_id, + state_read_client_finished, + state_send_new_session_ticket, + state_done, +}; + +static const uint8_t kZeroes[EVP_MAX_MD_SIZE] = {0}; + +static int resolve_ecdhe_secret(SSL_HANDSHAKE *hs, bool *out_need_retry, + SSL_CLIENT_HELLO *client_hello) { + SSL *const ssl = hs->ssl; + *out_need_retry = false; + + // We only support connections that include an ECDHE key exchange. + CBS key_share; + if (!ssl_client_hello_get_extension(client_hello, &key_share, + TLSEXT_TYPE_key_share)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_MISSING_KEY_SHARE); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_MISSING_EXTENSION); + return 0; + } + + bool found_key_share; + Array dhe_secret; + uint8_t alert = SSL_AD_DECODE_ERROR; + if (!ssl_ext_key_share_parse_clienthello(hs, &found_key_share, &dhe_secret, + &alert, &key_share)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + return 0; + } + + if (!found_key_share) { + *out_need_retry = true; + return 0; + } + + return tls13_advance_key_schedule(hs, dhe_secret.data(), dhe_secret.size()); +} + +static int ssl_ext_supported_versions_add_serverhello(SSL_HANDSHAKE *hs, + CBB *out) { + CBB contents; + if (!CBB_add_u16(out, TLSEXT_TYPE_supported_versions) || + !CBB_add_u16_length_prefixed(out, &contents) || + !CBB_add_u16(&contents, hs->ssl->version) || + !CBB_flush(out)) { + return 0; + } + + return 1; +} + +static const SSL_CIPHER *choose_tls13_cipher( + const SSL *ssl, const SSL_CLIENT_HELLO *client_hello) { + if (client_hello->cipher_suites_len % 2 != 0) { + return NULL; + } + + CBS cipher_suites; + CBS_init(&cipher_suites, client_hello->cipher_suites, + client_hello->cipher_suites_len); + + const int aes_is_fine = EVP_has_aes_hardware(); + const uint16_t version = ssl_protocol_version(ssl); + + const SSL_CIPHER *best = NULL; + while (CBS_len(&cipher_suites) > 0) { + uint16_t cipher_suite; + if (!CBS_get_u16(&cipher_suites, &cipher_suite)) { + return NULL; + } + + // Limit to TLS 1.3 ciphers we know about. + const SSL_CIPHER *candidate = SSL_get_cipher_by_value(cipher_suite); + if (candidate == NULL || + SSL_CIPHER_get_min_version(candidate) > version || + SSL_CIPHER_get_max_version(candidate) < version) { + continue; + } + + // TLS 1.3 removes legacy ciphers, so honor the client order, but prefer + // ChaCha20 if we do not have AES hardware. + if (aes_is_fine) { + return candidate; + } + + if (candidate->algorithm_enc == SSL_CHACHA20POLY1305) { + return candidate; + } + + if (best == NULL) { + best = candidate; + } + } + + return best; +} + +static int add_new_session_tickets(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + // TLS 1.3 recommends single-use tickets, so issue multiple tickets in case + // the client makes several connections before getting a renewal. + static const int kNumTickets = 2; + + // Rebase the session timestamp so that it is measured from ticket + // issuance. + ssl_session_rebase_time(ssl, hs->new_session.get()); + + for (int i = 0; i < kNumTickets; i++) { + UniquePtr session( + SSL_SESSION_dup(hs->new_session.get(), SSL_SESSION_INCLUDE_NONAUTH)); + if (!session) { + return 0; + } + + if (!RAND_bytes((uint8_t *)&session->ticket_age_add, 4)) { + return 0; + } + session->ticket_age_add_valid = 1; + if (ssl->cert->enable_early_data) { + session->ticket_max_early_data = kMaxEarlyDataAccepted; + } + + static_assert(kNumTickets < 256, "Too many tickets"); + uint8_t nonce[] = {static_cast(i)}; + + ScopedCBB cbb; + CBB body, nonce_cbb, ticket, extensions; + if (!ssl->method->init_message(ssl, cbb.get(), &body, + SSL3_MT_NEW_SESSION_TICKET) || + !CBB_add_u32(&body, session->timeout) || + !CBB_add_u32(&body, session->ticket_age_add) || + !CBB_add_u8_length_prefixed(&body, &nonce_cbb) || + !CBB_add_bytes(&nonce_cbb, nonce, sizeof(nonce)) || + !CBB_add_u16_length_prefixed(&body, &ticket) || + !tls13_derive_session_psk(session.get(), nonce) || + !ssl_encrypt_ticket(ssl, &ticket, session.get()) || + !CBB_add_u16_length_prefixed(&body, &extensions)) { + return 0; + } + + if (ssl->cert->enable_early_data) { + CBB early_data_info; + if (!CBB_add_u16(&extensions, TLSEXT_TYPE_early_data) || + !CBB_add_u16_length_prefixed(&extensions, &early_data_info) || + !CBB_add_u32(&early_data_info, session->ticket_max_early_data) || + !CBB_flush(&extensions)) { + return 0; + } + } + + // Add a fake extension. See draft-davidben-tls-grease-01. + if (!CBB_add_u16(&extensions, + ssl_get_grease_value(hs, ssl_grease_ticket_extension)) || + !CBB_add_u16(&extensions, 0 /* empty */)) { + return 0; + } + + if (!ssl_add_message_cbb(ssl, cbb.get())) { + return 0; + } + } + + return 1; +} + +static enum ssl_hs_wait_t do_select_parameters(SSL_HANDSHAKE *hs) { + // At this point, most ClientHello extensions have already been processed by + // the common handshake logic. Resolve the remaining non-PSK parameters. + SSL *const ssl = hs->ssl; + SSLMessage msg; + if (!ssl->method->get_message(ssl, &msg)) { + return ssl_hs_read_message; + } + SSL_CLIENT_HELLO client_hello; + if (!ssl_client_hello_init(ssl, &client_hello, msg)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_CLIENTHELLO_PARSE_FAILED); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return ssl_hs_error; + } + + OPENSSL_memcpy(hs->session_id, client_hello.session_id, + client_hello.session_id_len); + hs->session_id_len = client_hello.session_id_len; + + // Negotiate the cipher suite. + hs->new_cipher = choose_tls13_cipher(ssl, &client_hello); + if (hs->new_cipher == NULL) { + OPENSSL_PUT_ERROR(SSL, SSL_R_NO_SHARED_CIPHER); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); + return ssl_hs_error; + } + + // HTTP/2 negotiation depends on the cipher suite, so ALPN negotiation was + // deferred. Complete it now. + uint8_t alert = SSL_AD_DECODE_ERROR; + if (!ssl_negotiate_alpn(hs, &alert, &client_hello)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + return ssl_hs_error; + } + + // The PRF hash is now known. Set up the key schedule and hash the + // ClientHello. + if (!hs->transcript.InitHash(ssl_protocol_version(ssl), hs->new_cipher)) { + return ssl_hs_error; + } + + if (!ssl_hash_message(hs, msg)) { + return ssl_hs_error; + } + + hs->tls13_state = state_select_session; + return ssl_hs_ok; +} + +static enum ssl_ticket_aead_result_t select_session( + SSL_HANDSHAKE *hs, uint8_t *out_alert, UniquePtr *out_session, + int32_t *out_ticket_age_skew, const SSLMessage &msg, + const SSL_CLIENT_HELLO *client_hello) { + SSL *const ssl = hs->ssl; + *out_session = NULL; + + // Decode the ticket if we agreed on a PSK key exchange mode. + CBS pre_shared_key; + if (!hs->accept_psk_mode || + !ssl_client_hello_get_extension(client_hello, &pre_shared_key, + TLSEXT_TYPE_pre_shared_key)) { + return ssl_ticket_aead_ignore_ticket; + } + + // Verify that the pre_shared_key extension is the last extension in + // ClientHello. + if (CBS_data(&pre_shared_key) + CBS_len(&pre_shared_key) != + client_hello->extensions + client_hello->extensions_len) { + OPENSSL_PUT_ERROR(SSL, SSL_R_PRE_SHARED_KEY_MUST_BE_LAST); + *out_alert = SSL_AD_ILLEGAL_PARAMETER; + return ssl_ticket_aead_error; + } + + CBS ticket, binders; + uint32_t client_ticket_age; + if (!ssl_ext_pre_shared_key_parse_clienthello(hs, &ticket, &binders, + &client_ticket_age, out_alert, + &pre_shared_key)) { + return ssl_ticket_aead_error; + } + + // TLS 1.3 session tickets are renewed separately as part of the + // NewSessionTicket. + bool unused_renew; + UniquePtr session; + enum ssl_ticket_aead_result_t ret = + ssl_process_ticket(ssl, &session, &unused_renew, CBS_data(&ticket), + CBS_len(&ticket), NULL, 0); + switch (ret) { + case ssl_ticket_aead_success: + break; + case ssl_ticket_aead_error: + *out_alert = SSL_AD_INTERNAL_ERROR; + return ret; + default: + return ret; + } + + if (!ssl_session_is_resumable(hs, session.get()) || + // Historically, some TLS 1.3 tickets were missing ticket_age_add. + !session->ticket_age_add_valid) { + return ssl_ticket_aead_ignore_ticket; + } + + // Recover the client ticket age and convert to seconds. + client_ticket_age -= session->ticket_age_add; + client_ticket_age /= 1000; + + struct OPENSSL_timeval now; + ssl_get_current_time(ssl, &now); + + // Compute the server ticket age in seconds. + assert(now.tv_sec >= session->time); + uint64_t server_ticket_age = now.tv_sec - session->time; + + // To avoid overflowing |hs->ticket_age_skew|, we will not resume + // 68-year-old sessions. + if (server_ticket_age > INT32_MAX) { + return ssl_ticket_aead_ignore_ticket; + } + + // TODO(davidben,svaldez): Measure this value to decide on tolerance. For + // now, accept all values. https://crbug.com/boringssl/113. + *out_ticket_age_skew = + (int32_t)client_ticket_age - (int32_t)server_ticket_age; + + // Check the PSK binder. + if (!tls13_verify_psk_binder(hs, session.get(), msg, &binders)) { + *out_alert = SSL_AD_DECRYPT_ERROR; + return ssl_ticket_aead_error; + } + + *out_session = std::move(session); + return ssl_ticket_aead_success; +} + +static enum ssl_hs_wait_t do_select_session(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + SSLMessage msg; + if (!ssl->method->get_message(ssl, &msg)) { + return ssl_hs_read_message; + } + SSL_CLIENT_HELLO client_hello; + if (!ssl_client_hello_init(ssl, &client_hello, msg)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_CLIENTHELLO_PARSE_FAILED); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return ssl_hs_error; + } + + uint8_t alert = SSL_AD_DECODE_ERROR; + UniquePtr session; + switch (select_session(hs, &alert, &session, &ssl->s3->ticket_age_skew, msg, + &client_hello)) { + case ssl_ticket_aead_ignore_ticket: + assert(!session); + if (!ssl_get_new_session(hs, 1 /* server */)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return ssl_hs_error; + } + break; + + case ssl_ticket_aead_success: + // Carry over authentication information from the previous handshake into + // a fresh session. + hs->new_session = + SSL_SESSION_dup(session.get(), SSL_SESSION_DUP_AUTH_ONLY); + + if (ssl->cert->enable_early_data && + // Early data must be acceptable for this ticket. + session->ticket_max_early_data != 0 && + // The client must have offered early data. + hs->early_data_offered && + // Channel ID is incompatible with 0-RTT. + !ssl->s3->tlsext_channel_id_valid && + // If Token Binding is negotiated, reject 0-RTT. + !ssl->token_binding_negotiated && + // Custom extensions is incompatible with 0-RTT. + hs->custom_extensions.received == 0 && + // The negotiated ALPN must match the one in the ticket. + ssl->s3->alpn_selected == + MakeConstSpan(session->early_alpn, session->early_alpn_len)) { + ssl->s3->early_data_accepted = true; + } + + if (hs->new_session == NULL) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return ssl_hs_error; + } + + ssl->s3->session_reused = true; + + // Resumption incorporates fresh key material, so refresh the timeout. + ssl_session_renew_timeout(ssl, hs->new_session.get(), + ssl->session_ctx->session_psk_dhe_timeout); + break; + + case ssl_ticket_aead_error: + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + return ssl_hs_error; + + case ssl_ticket_aead_retry: + hs->tls13_state = state_select_session; + return ssl_hs_pending_ticket; + } + + // Record connection properties in the new session. + hs->new_session->cipher = hs->new_cipher; + + // Store the initial negotiated ALPN in the session. + if (!ssl->s3->alpn_selected.empty()) { + hs->new_session->early_alpn = (uint8_t *)BUF_memdup( + ssl->s3->alpn_selected.data(), ssl->s3->alpn_selected.size()); + if (hs->new_session->early_alpn == NULL) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return ssl_hs_error; + } + hs->new_session->early_alpn_len = ssl->s3->alpn_selected.size(); + } + + if (ssl->ctx->dos_protection_cb != NULL && + ssl->ctx->dos_protection_cb(&client_hello) == 0) { + // Connection rejected for DOS reasons. + OPENSSL_PUT_ERROR(SSL, SSL_R_CONNECTION_REJECTED); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return ssl_hs_error; + } + + size_t hash_len = EVP_MD_size( + ssl_get_handshake_digest(ssl_protocol_version(ssl), hs->new_cipher)); + + // Set up the key schedule and incorporate the PSK into the running secret. + if (ssl->s3->session_reused) { + if (!tls13_init_key_schedule(hs, hs->new_session->master_key, + hs->new_session->master_key_length)) { + return ssl_hs_error; + } + } else if (!tls13_init_key_schedule(hs, kZeroes, hash_len)) { + return ssl_hs_error; + } + + if (ssl->s3->early_data_accepted) { + if (!tls13_derive_early_secrets(hs)) { + return ssl_hs_error; + } + } else if (hs->early_data_offered) { + ssl->s3->skip_early_data = true; + } + + // Resolve ECDHE and incorporate it into the secret. + bool need_retry; + if (!resolve_ecdhe_secret(hs, &need_retry, &client_hello)) { + if (need_retry) { + ssl->s3->early_data_accepted = false; + ssl->s3->skip_early_data = true; + ssl->method->next_message(ssl); + if (!hs->transcript.UpdateForHelloRetryRequest()) { + return ssl_hs_error; + } + hs->tls13_state = state_send_hello_retry_request; + return ssl_hs_ok; + } + return ssl_hs_error; + } + + ssl->method->next_message(ssl); + hs->tls13_state = state_send_server_hello; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_send_hello_retry_request(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + + + ScopedCBB cbb; + CBB body, session_id, extensions; + uint16_t group_id; + if (!ssl->method->init_message(ssl, cbb.get(), &body, SSL3_MT_SERVER_HELLO) || + !CBB_add_u16(&body, TLS1_2_VERSION) || + !CBB_add_bytes(&body, kHelloRetryRequest, SSL3_RANDOM_SIZE) || + !CBB_add_u8_length_prefixed(&body, &session_id) || + !CBB_add_bytes(&session_id, hs->session_id, hs->session_id_len) || + !CBB_add_u16(&body, ssl_cipher_get_value(hs->new_cipher)) || + !CBB_add_u8(&body, 0 /* no compression */) || + !tls1_get_shared_group(hs, &group_id) || + !CBB_add_u16_length_prefixed(&body, &extensions) || + !CBB_add_u16(&extensions, TLSEXT_TYPE_supported_versions) || + !CBB_add_u16(&extensions, 2 /* length */) || + !CBB_add_u16(&extensions, ssl->version) || + !CBB_add_u16(&extensions, TLSEXT_TYPE_key_share) || + !CBB_add_u16(&extensions, 2 /* length */) || + !CBB_add_u16(&extensions, group_id) || + !ssl_add_message_cbb(ssl, cbb.get())) { + return ssl_hs_error; + } + + if (!ssl->method->add_change_cipher_spec(ssl)) { + return ssl_hs_error; + } + + hs->sent_hello_retry_request = true; + hs->tls13_state = state_read_second_client_hello; + return ssl_hs_flush; +} + +static enum ssl_hs_wait_t do_read_second_client_hello(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + SSLMessage msg; + if (!ssl->method->get_message(ssl, &msg)) { + return ssl_hs_read_message; + } + if (!ssl_check_message_type(ssl, msg, SSL3_MT_CLIENT_HELLO)) { + return ssl_hs_error; + } + SSL_CLIENT_HELLO client_hello; + if (!ssl_client_hello_init(ssl, &client_hello, msg)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_CLIENTHELLO_PARSE_FAILED); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return ssl_hs_error; + } + + bool need_retry; + if (!resolve_ecdhe_secret(hs, &need_retry, &client_hello)) { + if (need_retry) { + // Only send one HelloRetryRequest. + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CURVE); + } + return ssl_hs_error; + } + + if (!ssl_hash_message(hs, msg)) { + return ssl_hs_error; + } + + ssl->method->next_message(ssl); + hs->tls13_state = state_send_server_hello; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_send_server_hello(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + + // Send a ServerHello. + ScopedCBB cbb; + CBB body, extensions, session_id; + if (!ssl->method->init_message(ssl, cbb.get(), &body, SSL3_MT_SERVER_HELLO) || + !CBB_add_u16(&body, TLS1_2_VERSION) || + !RAND_bytes(ssl->s3->server_random, sizeof(ssl->s3->server_random)) || + !CBB_add_bytes(&body, ssl->s3->server_random, SSL3_RANDOM_SIZE) || + !CBB_add_u8_length_prefixed(&body, &session_id) || + !CBB_add_bytes(&session_id, hs->session_id, hs->session_id_len) || + !CBB_add_u16(&body, ssl_cipher_get_value(hs->new_cipher)) || + !CBB_add_u8(&body, 0) || + !CBB_add_u16_length_prefixed(&body, &extensions) || + !ssl_ext_pre_shared_key_add_serverhello(hs, &extensions) || + !ssl_ext_key_share_add_serverhello(hs, &extensions) || + !ssl_ext_supported_versions_add_serverhello(hs, &extensions) || + !ssl_add_message_cbb(ssl, cbb.get())) { + return ssl_hs_error; + } + + if (!hs->sent_hello_retry_request && + !ssl->method->add_change_cipher_spec(ssl)) { + return ssl_hs_error; + } + + // Derive and enable the handshake traffic secrets. + if (!tls13_derive_handshake_secrets(hs) || + !tls13_set_traffic_key(ssl, evp_aead_seal, hs->server_handshake_secret, + hs->hash_len)) { + return ssl_hs_error; + } + + // Send EncryptedExtensions. + if (!ssl->method->init_message(ssl, cbb.get(), &body, + SSL3_MT_ENCRYPTED_EXTENSIONS) || + !ssl_add_serverhello_tlsext(hs, &body) || + !ssl_add_message_cbb(ssl, cbb.get())) { + return ssl_hs_error; + } + + if (!ssl->s3->session_reused) { + // Determine whether to request a client certificate. + hs->cert_request = !!(ssl->verify_mode & SSL_VERIFY_PEER); + // Only request a certificate if Channel ID isn't negotiated. + if ((ssl->verify_mode & SSL_VERIFY_PEER_IF_NO_OBC) && + ssl->s3->tlsext_channel_id_valid) { + hs->cert_request = false; + } + } + + // Send a CertificateRequest, if necessary. + if (hs->cert_request) { + CBB cert_request_extensions, sigalg_contents, sigalgs_cbb; + if (!ssl->method->init_message(ssl, cbb.get(), &body, + SSL3_MT_CERTIFICATE_REQUEST) || + !CBB_add_u8(&body, 0 /* no certificate_request_context. */) || + !CBB_add_u16_length_prefixed(&body, &cert_request_extensions) || + !CBB_add_u16(&cert_request_extensions, + TLSEXT_TYPE_signature_algorithms) || + !CBB_add_u16_length_prefixed(&cert_request_extensions, + &sigalg_contents) || + !CBB_add_u16_length_prefixed(&sigalg_contents, &sigalgs_cbb) || + !tls12_add_verify_sigalgs(ssl, &sigalgs_cbb)) { + return ssl_hs_error; + } + + if (ssl_has_client_CAs(ssl)) { + CBB ca_contents; + if (!CBB_add_u16(&cert_request_extensions, + TLSEXT_TYPE_certificate_authorities) || + !CBB_add_u16_length_prefixed(&cert_request_extensions, + &ca_contents) || + !ssl_add_client_CA_list(ssl, &ca_contents) || + !CBB_flush(&cert_request_extensions)) { + return ssl_hs_error; + } + } + + if (!ssl_add_message_cbb(ssl, cbb.get())) { + return ssl_hs_error; + } + } + + // Send the server Certificate message, if necessary. + if (!ssl->s3->session_reused) { + if (!ssl_has_certificate(ssl)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CERTIFICATE_SET); + return ssl_hs_error; + } + + if (!tls13_add_certificate(hs)) { + return ssl_hs_error; + } + + hs->tls13_state = state_send_server_certificate_verify; + return ssl_hs_ok; + } + + hs->tls13_state = state_send_server_finished; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_send_server_certificate_verify(SSL_HANDSHAKE *hs) { + switch (tls13_add_certificate_verify(hs)) { + case ssl_private_key_success: + hs->tls13_state = state_send_server_finished; + return ssl_hs_ok; + + case ssl_private_key_retry: + hs->tls13_state = state_send_server_certificate_verify; + return ssl_hs_private_key_operation; + + case ssl_private_key_failure: + return ssl_hs_error; + } + + assert(0); + return ssl_hs_error; +} + +static enum ssl_hs_wait_t do_send_server_finished(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + if (!tls13_add_finished(hs) || + // Update the secret to the master secret and derive traffic keys. + !tls13_advance_key_schedule(hs, kZeroes, hs->hash_len) || + !tls13_derive_application_secrets(hs) || + !tls13_set_traffic_key(ssl, evp_aead_seal, hs->server_traffic_secret_0, + hs->hash_len)) { + return ssl_hs_error; + } + + if (ssl->s3->early_data_accepted) { + // If accepting 0-RTT, we send tickets half-RTT. This gets the tickets on + // the wire sooner and also avoids triggering a write on |SSL_read| when + // processing the client Finished. This requires computing the client + // Finished early. See draft-ietf-tls-tls13-18, section 4.5.1. + static const uint8_t kEndOfEarlyData[4] = {SSL3_MT_END_OF_EARLY_DATA, 0, + 0, 0}; + if (!hs->transcript.Update(kEndOfEarlyData)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return ssl_hs_error; + } + + size_t finished_len; + if (!tls13_finished_mac(hs, hs->expected_client_finished, &finished_len, + 0 /* client */)) { + return ssl_hs_error; + } + + if (finished_len != hs->hash_len) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return ssl_hs_error; + } + + // Feed the predicted Finished into the transcript. This allows us to derive + // the resumption secret early and send half-RTT tickets. + // + // TODO(davidben): This will need to be updated for DTLS 1.3. + assert(!SSL_is_dtls(hs->ssl)); + assert(hs->hash_len <= 0xff); + uint8_t header[4] = {SSL3_MT_FINISHED, 0, 0, + static_cast(hs->hash_len)}; + if (!hs->transcript.Update(header) || + !hs->transcript.Update( + MakeConstSpan(hs->expected_client_finished, hs->hash_len)) || + !tls13_derive_resumption_secret(hs) || + !add_new_session_tickets(hs)) { + return ssl_hs_error; + } + } + + hs->tls13_state = state_read_second_client_flight; + return ssl_hs_flush; +} + +static enum ssl_hs_wait_t do_read_second_client_flight(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + if (ssl->s3->early_data_accepted) { + if (!tls13_set_traffic_key(ssl, evp_aead_open, hs->early_traffic_secret, + hs->hash_len)) { + return ssl_hs_error; + } + hs->can_early_write = true; + hs->can_early_read = true; + hs->in_early_data = true; + } + hs->tls13_state = state_process_end_of_early_data; + return ssl->s3->early_data_accepted ? ssl_hs_read_end_of_early_data + : ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_process_end_of_early_data(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + if (hs->early_data_offered) { + // If early data was not accepted, the EndOfEarlyData and ChangeCipherSpec + // message will be in the discarded early data. + if (hs->ssl->s3->early_data_accepted) { + SSLMessage msg; + if (!ssl->method->get_message(ssl, &msg)) { + return ssl_hs_read_message; + } + + if (!ssl_check_message_type(ssl, msg, SSL3_MT_END_OF_EARLY_DATA)) { + return ssl_hs_error; + } + if (CBS_len(&msg.body) != 0) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + return ssl_hs_error; + } + ssl->method->next_message(ssl); + } + } + if (!tls13_set_traffic_key(ssl, evp_aead_open, hs->client_handshake_secret, + hs->hash_len)) { + return ssl_hs_error; + } + hs->tls13_state = ssl->s3->early_data_accepted + ? state_read_client_finished + : state_read_client_certificate; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_read_client_certificate(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + if (!hs->cert_request) { + // OpenSSL returns X509_V_OK when no certificates are requested. This is + // classed by them as a bug, but it's assumed by at least NGINX. + hs->new_session->verify_result = X509_V_OK; + + // Skip this state. + hs->tls13_state = state_read_channel_id; + return ssl_hs_ok; + } + + const int allow_anonymous = + (ssl->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) == 0; + SSLMessage msg; + if (!ssl->method->get_message(ssl, &msg)) { + return ssl_hs_read_message; + } + if (!ssl_check_message_type(ssl, msg, SSL3_MT_CERTIFICATE) || + !tls13_process_certificate(hs, msg, allow_anonymous) || + !ssl_hash_message(hs, msg)) { + return ssl_hs_error; + } + + ssl->method->next_message(ssl); + hs->tls13_state = state_read_client_certificate_verify; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_read_client_certificate_verify( + SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + if (sk_CRYPTO_BUFFER_num(hs->new_session->certs) == 0) { + // Skip this state. + hs->tls13_state = state_read_channel_id; + return ssl_hs_ok; + } + + SSLMessage msg; + if (!ssl->method->get_message(ssl, &msg)) { + return ssl_hs_read_message; + } + + switch (ssl_verify_peer_cert(hs)) { + case ssl_verify_ok: + break; + case ssl_verify_invalid: + return ssl_hs_error; + case ssl_verify_retry: + hs->tls13_state = state_read_client_certificate_verify; + return ssl_hs_certificate_verify; + } + + if (!ssl_check_message_type(ssl, msg, SSL3_MT_CERTIFICATE_VERIFY) || + !tls13_process_certificate_verify(hs, msg) || + !ssl_hash_message(hs, msg)) { + return ssl_hs_error; + } + + ssl->method->next_message(ssl); + hs->tls13_state = state_read_channel_id; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_read_channel_id(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + if (!ssl->s3->tlsext_channel_id_valid) { + hs->tls13_state = state_read_client_finished; + return ssl_hs_ok; + } + + SSLMessage msg; + if (!ssl->method->get_message(ssl, &msg)) { + return ssl_hs_read_message; + } + if (!ssl_check_message_type(ssl, msg, SSL3_MT_CHANNEL_ID) || + !tls1_verify_channel_id(hs, msg) || + !ssl_hash_message(hs, msg)) { + return ssl_hs_error; + } + + ssl->method->next_message(ssl); + hs->tls13_state = state_read_client_finished; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_read_client_finished(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + SSLMessage msg; + if (!ssl->method->get_message(ssl, &msg)) { + return ssl_hs_read_message; + } + if (!ssl_check_message_type(ssl, msg, SSL3_MT_FINISHED) || + // If early data was accepted, we've already computed the client Finished + // and derived the resumption secret. + !tls13_process_finished(hs, msg, ssl->s3->early_data_accepted) || + // evp_aead_seal keys have already been switched. + !tls13_set_traffic_key(ssl, evp_aead_open, hs->client_traffic_secret_0, + hs->hash_len)) { + return ssl_hs_error; + } + + if (!ssl->s3->early_data_accepted) { + if (!ssl_hash_message(hs, msg) || + !tls13_derive_resumption_secret(hs)) { + return ssl_hs_error; + } + + // We send post-handshake tickets as part of the handshake in 1-RTT. + hs->tls13_state = state_send_new_session_ticket; + } else { + // We already sent half-RTT tickets. + hs->tls13_state = state_done; + } + + ssl->method->next_message(ssl); + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_send_new_session_ticket(SSL_HANDSHAKE *hs) { + // If the client doesn't accept resumption with PSK_DHE_KE, don't send a + // session ticket. + if (!hs->accept_psk_mode) { + hs->tls13_state = state_done; + return ssl_hs_ok; + } + + if (!add_new_session_tickets(hs)) { + return ssl_hs_error; + } + + hs->tls13_state = state_done; + return ssl_hs_flush; +} + +enum ssl_hs_wait_t tls13_server_handshake(SSL_HANDSHAKE *hs) { + while (hs->tls13_state != state_done) { + enum ssl_hs_wait_t ret = ssl_hs_error; + enum server_hs_state_t state = + static_cast(hs->tls13_state); + switch (state) { + case state_select_parameters: + ret = do_select_parameters(hs); + break; + case state_select_session: + ret = do_select_session(hs); + break; + case state_send_hello_retry_request: + ret = do_send_hello_retry_request(hs); + break; + case state_read_second_client_hello: + ret = do_read_second_client_hello(hs); + break; + case state_send_server_hello: + ret = do_send_server_hello(hs); + break; + case state_send_server_certificate_verify: + ret = do_send_server_certificate_verify(hs); + break; + case state_send_server_finished: + ret = do_send_server_finished(hs); + break; + case state_read_second_client_flight: + ret = do_read_second_client_flight(hs); + break; + case state_process_end_of_early_data: + ret = do_process_end_of_early_data(hs); + break; + case state_read_client_certificate: + ret = do_read_client_certificate(hs); + break; + case state_read_client_certificate_verify: + ret = do_read_client_certificate_verify(hs); + break; + case state_read_channel_id: + ret = do_read_channel_id(hs); + break; + case state_read_client_finished: + ret = do_read_client_finished(hs); + break; + case state_send_new_session_ticket: + ret = do_send_new_session_ticket(hs); + break; + case state_done: + ret = ssl_hs_ok; + break; + } + + if (hs->tls13_state != state) { + ssl_do_info_callback(hs->ssl, SSL_CB_ACCEPT_LOOP, 1); + } + + if (ret != ssl_hs_ok) { + return ret; + } + } + + return ssl_hs_ok; +} + +const char *tls13_server_handshake_state(SSL_HANDSHAKE *hs) { + enum server_hs_state_t state = + static_cast(hs->tls13_state); + switch (state) { + case state_select_parameters: + return "TLS 1.3 server select_parameters"; + case state_select_session: + return "TLS 1.3 server select_session"; + case state_send_hello_retry_request: + return "TLS 1.3 server send_hello_retry_request"; + case state_read_second_client_hello: + return "TLS 1.3 server read_second_client_hello"; + case state_send_server_hello: + return "TLS 1.3 server send_server_hello"; + case state_send_server_certificate_verify: + return "TLS 1.3 server send_server_certificate_verify"; + case state_send_server_finished: + return "TLS 1.3 server send_server_finished"; + case state_read_second_client_flight: + return "TLS 1.3 server read_second_client_flight"; + case state_process_end_of_early_data: + return "TLS 1.3 server process_end_of_early_data"; + case state_read_client_certificate: + return "TLS 1.3 server read_client_certificate"; + case state_read_client_certificate_verify: + return "TLS 1.3 server read_client_certificate_verify"; + case state_read_channel_id: + return "TLS 1.3 server read_channel_id"; + case state_read_client_finished: + return "TLS 1.3 server read_client_finished"; + case state_send_new_session_ticket: + return "TLS 1.3 server send_new_session_ticket"; + case state_done: + return "TLS 1.3 server done"; + } + + return "TLS 1.3 server unknown"; +} + +} // namespace bssl diff --git a/FoodApp/Pods/BoringSSL-GRPC/ssl/tls13_server.cc.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/ssl/tls13_server.cc.grpc_back new file mode 100644 index 0000000..3bd6786 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/ssl/tls13_server.cc.grpc_back @@ -0,0 +1,1022 @@ +/* Copyright (c) 2016, Google Inc. + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ + +// Per C99, various stdint.h macros are unavailable in C++ unless some macros +// are defined. C++11 overruled this decision, but older Android NDKs still +// require it. +#if !defined(__STDC_LIMIT_MACROS) +#define __STDC_LIMIT_MACROS +#endif + +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "../crypto/internal.h" +#include "internal.h" + + +namespace bssl { + +enum server_hs_state_t { + state_select_parameters = 0, + state_select_session, + state_send_hello_retry_request, + state_read_second_client_hello, + state_send_server_hello, + state_send_server_certificate_verify, + state_send_server_finished, + state_read_second_client_flight, + state_process_end_of_early_data, + state_read_client_certificate, + state_read_client_certificate_verify, + state_read_channel_id, + state_read_client_finished, + state_send_new_session_ticket, + state_done, +}; + +static const uint8_t kZeroes[EVP_MAX_MD_SIZE] = {0}; + +static int resolve_ecdhe_secret(SSL_HANDSHAKE *hs, bool *out_need_retry, + SSL_CLIENT_HELLO *client_hello) { + SSL *const ssl = hs->ssl; + *out_need_retry = false; + + // We only support connections that include an ECDHE key exchange. + CBS key_share; + if (!ssl_client_hello_get_extension(client_hello, &key_share, + TLSEXT_TYPE_key_share)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_MISSING_KEY_SHARE); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_MISSING_EXTENSION); + return 0; + } + + bool found_key_share; + Array dhe_secret; + uint8_t alert = SSL_AD_DECODE_ERROR; + if (!ssl_ext_key_share_parse_clienthello(hs, &found_key_share, &dhe_secret, + &alert, &key_share)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + return 0; + } + + if (!found_key_share) { + *out_need_retry = true; + return 0; + } + + return tls13_advance_key_schedule(hs, dhe_secret.data(), dhe_secret.size()); +} + +static int ssl_ext_supported_versions_add_serverhello(SSL_HANDSHAKE *hs, + CBB *out) { + CBB contents; + if (!CBB_add_u16(out, TLSEXT_TYPE_supported_versions) || + !CBB_add_u16_length_prefixed(out, &contents) || + !CBB_add_u16(&contents, hs->ssl->version) || + !CBB_flush(out)) { + return 0; + } + + return 1; +} + +static const SSL_CIPHER *choose_tls13_cipher( + const SSL *ssl, const SSL_CLIENT_HELLO *client_hello) { + if (client_hello->cipher_suites_len % 2 != 0) { + return NULL; + } + + CBS cipher_suites; + CBS_init(&cipher_suites, client_hello->cipher_suites, + client_hello->cipher_suites_len); + + const int aes_is_fine = EVP_has_aes_hardware(); + const uint16_t version = ssl_protocol_version(ssl); + + const SSL_CIPHER *best = NULL; + while (CBS_len(&cipher_suites) > 0) { + uint16_t cipher_suite; + if (!CBS_get_u16(&cipher_suites, &cipher_suite)) { + return NULL; + } + + // Limit to TLS 1.3 ciphers we know about. + const SSL_CIPHER *candidate = SSL_get_cipher_by_value(cipher_suite); + if (candidate == NULL || + SSL_CIPHER_get_min_version(candidate) > version || + SSL_CIPHER_get_max_version(candidate) < version) { + continue; + } + + // TLS 1.3 removes legacy ciphers, so honor the client order, but prefer + // ChaCha20 if we do not have AES hardware. + if (aes_is_fine) { + return candidate; + } + + if (candidate->algorithm_enc == SSL_CHACHA20POLY1305) { + return candidate; + } + + if (best == NULL) { + best = candidate; + } + } + + return best; +} + +static int add_new_session_tickets(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + // TLS 1.3 recommends single-use tickets, so issue multiple tickets in case + // the client makes several connections before getting a renewal. + static const int kNumTickets = 2; + + // Rebase the session timestamp so that it is measured from ticket + // issuance. + ssl_session_rebase_time(ssl, hs->new_session.get()); + + for (int i = 0; i < kNumTickets; i++) { + UniquePtr session( + SSL_SESSION_dup(hs->new_session.get(), SSL_SESSION_INCLUDE_NONAUTH)); + if (!session) { + return 0; + } + + if (!RAND_bytes((uint8_t *)&session->ticket_age_add, 4)) { + return 0; + } + session->ticket_age_add_valid = 1; + if (ssl->cert->enable_early_data) { + session->ticket_max_early_data = kMaxEarlyDataAccepted; + } + + static_assert(kNumTickets < 256, "Too many tickets"); + uint8_t nonce[] = {static_cast(i)}; + + ScopedCBB cbb; + CBB body, nonce_cbb, ticket, extensions; + if (!ssl->method->init_message(ssl, cbb.get(), &body, + SSL3_MT_NEW_SESSION_TICKET) || + !CBB_add_u32(&body, session->timeout) || + !CBB_add_u32(&body, session->ticket_age_add) || + !CBB_add_u8_length_prefixed(&body, &nonce_cbb) || + !CBB_add_bytes(&nonce_cbb, nonce, sizeof(nonce)) || + !CBB_add_u16_length_prefixed(&body, &ticket) || + !tls13_derive_session_psk(session.get(), nonce) || + !ssl_encrypt_ticket(ssl, &ticket, session.get()) || + !CBB_add_u16_length_prefixed(&body, &extensions)) { + return 0; + } + + if (ssl->cert->enable_early_data) { + CBB early_data_info; + if (!CBB_add_u16(&extensions, TLSEXT_TYPE_early_data) || + !CBB_add_u16_length_prefixed(&extensions, &early_data_info) || + !CBB_add_u32(&early_data_info, session->ticket_max_early_data) || + !CBB_flush(&extensions)) { + return 0; + } + } + + // Add a fake extension. See draft-davidben-tls-grease-01. + if (!CBB_add_u16(&extensions, + ssl_get_grease_value(hs, ssl_grease_ticket_extension)) || + !CBB_add_u16(&extensions, 0 /* empty */)) { + return 0; + } + + if (!ssl_add_message_cbb(ssl, cbb.get())) { + return 0; + } + } + + return 1; +} + +static enum ssl_hs_wait_t do_select_parameters(SSL_HANDSHAKE *hs) { + // At this point, most ClientHello extensions have already been processed by + // the common handshake logic. Resolve the remaining non-PSK parameters. + SSL *const ssl = hs->ssl; + SSLMessage msg; + if (!ssl->method->get_message(ssl, &msg)) { + return ssl_hs_read_message; + } + SSL_CLIENT_HELLO client_hello; + if (!ssl_client_hello_init(ssl, &client_hello, msg)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_CLIENTHELLO_PARSE_FAILED); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return ssl_hs_error; + } + + OPENSSL_memcpy(hs->session_id, client_hello.session_id, + client_hello.session_id_len); + hs->session_id_len = client_hello.session_id_len; + + // Negotiate the cipher suite. + hs->new_cipher = choose_tls13_cipher(ssl, &client_hello); + if (hs->new_cipher == NULL) { + OPENSSL_PUT_ERROR(SSL, SSL_R_NO_SHARED_CIPHER); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_HANDSHAKE_FAILURE); + return ssl_hs_error; + } + + // HTTP/2 negotiation depends on the cipher suite, so ALPN negotiation was + // deferred. Complete it now. + uint8_t alert = SSL_AD_DECODE_ERROR; + if (!ssl_negotiate_alpn(hs, &alert, &client_hello)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + return ssl_hs_error; + } + + // The PRF hash is now known. Set up the key schedule and hash the + // ClientHello. + if (!hs->transcript.InitHash(ssl_protocol_version(ssl), hs->new_cipher)) { + return ssl_hs_error; + } + + if (!ssl_hash_message(hs, msg)) { + return ssl_hs_error; + } + + hs->tls13_state = state_select_session; + return ssl_hs_ok; +} + +static enum ssl_ticket_aead_result_t select_session( + SSL_HANDSHAKE *hs, uint8_t *out_alert, UniquePtr *out_session, + int32_t *out_ticket_age_skew, const SSLMessage &msg, + const SSL_CLIENT_HELLO *client_hello) { + SSL *const ssl = hs->ssl; + *out_session = NULL; + + // Decode the ticket if we agreed on a PSK key exchange mode. + CBS pre_shared_key; + if (!hs->accept_psk_mode || + !ssl_client_hello_get_extension(client_hello, &pre_shared_key, + TLSEXT_TYPE_pre_shared_key)) { + return ssl_ticket_aead_ignore_ticket; + } + + // Verify that the pre_shared_key extension is the last extension in + // ClientHello. + if (CBS_data(&pre_shared_key) + CBS_len(&pre_shared_key) != + client_hello->extensions + client_hello->extensions_len) { + OPENSSL_PUT_ERROR(SSL, SSL_R_PRE_SHARED_KEY_MUST_BE_LAST); + *out_alert = SSL_AD_ILLEGAL_PARAMETER; + return ssl_ticket_aead_error; + } + + CBS ticket, binders; + uint32_t client_ticket_age; + if (!ssl_ext_pre_shared_key_parse_clienthello(hs, &ticket, &binders, + &client_ticket_age, out_alert, + &pre_shared_key)) { + return ssl_ticket_aead_error; + } + + // TLS 1.3 session tickets are renewed separately as part of the + // NewSessionTicket. + bool unused_renew; + UniquePtr session; + enum ssl_ticket_aead_result_t ret = + ssl_process_ticket(ssl, &session, &unused_renew, CBS_data(&ticket), + CBS_len(&ticket), NULL, 0); + switch (ret) { + case ssl_ticket_aead_success: + break; + case ssl_ticket_aead_error: + *out_alert = SSL_AD_INTERNAL_ERROR; + return ret; + default: + return ret; + } + + if (!ssl_session_is_resumable(hs, session.get()) || + // Historically, some TLS 1.3 tickets were missing ticket_age_add. + !session->ticket_age_add_valid) { + return ssl_ticket_aead_ignore_ticket; + } + + // Recover the client ticket age and convert to seconds. + client_ticket_age -= session->ticket_age_add; + client_ticket_age /= 1000; + + struct OPENSSL_timeval now; + ssl_get_current_time(ssl, &now); + + // Compute the server ticket age in seconds. + assert(now.tv_sec >= session->time); + uint64_t server_ticket_age = now.tv_sec - session->time; + + // To avoid overflowing |hs->ticket_age_skew|, we will not resume + // 68-year-old sessions. + if (server_ticket_age > INT32_MAX) { + return ssl_ticket_aead_ignore_ticket; + } + + // TODO(davidben,svaldez): Measure this value to decide on tolerance. For + // now, accept all values. https://crbug.com/boringssl/113. + *out_ticket_age_skew = + (int32_t)client_ticket_age - (int32_t)server_ticket_age; + + // Check the PSK binder. + if (!tls13_verify_psk_binder(hs, session.get(), msg, &binders)) { + *out_alert = SSL_AD_DECRYPT_ERROR; + return ssl_ticket_aead_error; + } + + *out_session = std::move(session); + return ssl_ticket_aead_success; +} + +static enum ssl_hs_wait_t do_select_session(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + SSLMessage msg; + if (!ssl->method->get_message(ssl, &msg)) { + return ssl_hs_read_message; + } + SSL_CLIENT_HELLO client_hello; + if (!ssl_client_hello_init(ssl, &client_hello, msg)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_CLIENTHELLO_PARSE_FAILED); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return ssl_hs_error; + } + + uint8_t alert = SSL_AD_DECODE_ERROR; + UniquePtr session; + switch (select_session(hs, &alert, &session, &ssl->s3->ticket_age_skew, msg, + &client_hello)) { + case ssl_ticket_aead_ignore_ticket: + assert(!session); + if (!ssl_get_new_session(hs, 1 /* server */)) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return ssl_hs_error; + } + break; + + case ssl_ticket_aead_success: + // Carry over authentication information from the previous handshake into + // a fresh session. + hs->new_session = + SSL_SESSION_dup(session.get(), SSL_SESSION_DUP_AUTH_ONLY); + + if (ssl->cert->enable_early_data && + // Early data must be acceptable for this ticket. + session->ticket_max_early_data != 0 && + // The client must have offered early data. + hs->early_data_offered && + // Channel ID is incompatible with 0-RTT. + !ssl->s3->tlsext_channel_id_valid && + // If Token Binding is negotiated, reject 0-RTT. + !ssl->token_binding_negotiated && + // Custom extensions is incompatible with 0-RTT. + hs->custom_extensions.received == 0 && + // The negotiated ALPN must match the one in the ticket. + ssl->s3->alpn_selected == + MakeConstSpan(session->early_alpn, session->early_alpn_len)) { + ssl->s3->early_data_accepted = true; + } + + if (hs->new_session == NULL) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return ssl_hs_error; + } + + ssl->s3->session_reused = true; + + // Resumption incorporates fresh key material, so refresh the timeout. + ssl_session_renew_timeout(ssl, hs->new_session.get(), + ssl->session_ctx->session_psk_dhe_timeout); + break; + + case ssl_ticket_aead_error: + ssl_send_alert(ssl, SSL3_AL_FATAL, alert); + return ssl_hs_error; + + case ssl_ticket_aead_retry: + hs->tls13_state = state_select_session; + return ssl_hs_pending_ticket; + } + + // Record connection properties in the new session. + hs->new_session->cipher = hs->new_cipher; + + // Store the initial negotiated ALPN in the session. + if (!ssl->s3->alpn_selected.empty()) { + hs->new_session->early_alpn = (uint8_t *)BUF_memdup( + ssl->s3->alpn_selected.data(), ssl->s3->alpn_selected.size()); + if (hs->new_session->early_alpn == NULL) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return ssl_hs_error; + } + hs->new_session->early_alpn_len = ssl->s3->alpn_selected.size(); + } + + if (ssl->ctx->dos_protection_cb != NULL && + ssl->ctx->dos_protection_cb(&client_hello) == 0) { + // Connection rejected for DOS reasons. + OPENSSL_PUT_ERROR(SSL, SSL_R_CONNECTION_REJECTED); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_INTERNAL_ERROR); + return ssl_hs_error; + } + + size_t hash_len = EVP_MD_size( + ssl_get_handshake_digest(ssl_protocol_version(ssl), hs->new_cipher)); + + // Set up the key schedule and incorporate the PSK into the running secret. + if (ssl->s3->session_reused) { + if (!tls13_init_key_schedule(hs, hs->new_session->master_key, + hs->new_session->master_key_length)) { + return ssl_hs_error; + } + } else if (!tls13_init_key_schedule(hs, kZeroes, hash_len)) { + return ssl_hs_error; + } + + if (ssl->s3->early_data_accepted) { + if (!tls13_derive_early_secrets(hs)) { + return ssl_hs_error; + } + } else if (hs->early_data_offered) { + ssl->s3->skip_early_data = true; + } + + // Resolve ECDHE and incorporate it into the secret. + bool need_retry; + if (!resolve_ecdhe_secret(hs, &need_retry, &client_hello)) { + if (need_retry) { + ssl->s3->early_data_accepted = false; + ssl->s3->skip_early_data = true; + ssl->method->next_message(ssl); + if (!hs->transcript.UpdateForHelloRetryRequest()) { + return ssl_hs_error; + } + hs->tls13_state = state_send_hello_retry_request; + return ssl_hs_ok; + } + return ssl_hs_error; + } + + ssl->method->next_message(ssl); + hs->tls13_state = state_send_server_hello; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_send_hello_retry_request(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + + + ScopedCBB cbb; + CBB body, session_id, extensions; + uint16_t group_id; + if (!ssl->method->init_message(ssl, cbb.get(), &body, SSL3_MT_SERVER_HELLO) || + !CBB_add_u16(&body, TLS1_2_VERSION) || + !CBB_add_bytes(&body, kHelloRetryRequest, SSL3_RANDOM_SIZE) || + !CBB_add_u8_length_prefixed(&body, &session_id) || + !CBB_add_bytes(&session_id, hs->session_id, hs->session_id_len) || + !CBB_add_u16(&body, ssl_cipher_get_value(hs->new_cipher)) || + !CBB_add_u8(&body, 0 /* no compression */) || + !tls1_get_shared_group(hs, &group_id) || + !CBB_add_u16_length_prefixed(&body, &extensions) || + !CBB_add_u16(&extensions, TLSEXT_TYPE_supported_versions) || + !CBB_add_u16(&extensions, 2 /* length */) || + !CBB_add_u16(&extensions, ssl->version) || + !CBB_add_u16(&extensions, TLSEXT_TYPE_key_share) || + !CBB_add_u16(&extensions, 2 /* length */) || + !CBB_add_u16(&extensions, group_id) || + !ssl_add_message_cbb(ssl, cbb.get())) { + return ssl_hs_error; + } + + if (!ssl->method->add_change_cipher_spec(ssl)) { + return ssl_hs_error; + } + + hs->sent_hello_retry_request = true; + hs->tls13_state = state_read_second_client_hello; + return ssl_hs_flush; +} + +static enum ssl_hs_wait_t do_read_second_client_hello(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + SSLMessage msg; + if (!ssl->method->get_message(ssl, &msg)) { + return ssl_hs_read_message; + } + if (!ssl_check_message_type(ssl, msg, SSL3_MT_CLIENT_HELLO)) { + return ssl_hs_error; + } + SSL_CLIENT_HELLO client_hello; + if (!ssl_client_hello_init(ssl, &client_hello, msg)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_CLIENTHELLO_PARSE_FAILED); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + return ssl_hs_error; + } + + bool need_retry; + if (!resolve_ecdhe_secret(hs, &need_retry, &client_hello)) { + if (need_retry) { + // Only send one HelloRetryRequest. + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_ILLEGAL_PARAMETER); + OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_CURVE); + } + return ssl_hs_error; + } + + if (!ssl_hash_message(hs, msg)) { + return ssl_hs_error; + } + + ssl->method->next_message(ssl); + hs->tls13_state = state_send_server_hello; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_send_server_hello(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + + // Send a ServerHello. + ScopedCBB cbb; + CBB body, extensions, session_id; + if (!ssl->method->init_message(ssl, cbb.get(), &body, SSL3_MT_SERVER_HELLO) || + !CBB_add_u16(&body, TLS1_2_VERSION) || + !RAND_bytes(ssl->s3->server_random, sizeof(ssl->s3->server_random)) || + !CBB_add_bytes(&body, ssl->s3->server_random, SSL3_RANDOM_SIZE) || + !CBB_add_u8_length_prefixed(&body, &session_id) || + !CBB_add_bytes(&session_id, hs->session_id, hs->session_id_len) || + !CBB_add_u16(&body, ssl_cipher_get_value(hs->new_cipher)) || + !CBB_add_u8(&body, 0) || + !CBB_add_u16_length_prefixed(&body, &extensions) || + !ssl_ext_pre_shared_key_add_serverhello(hs, &extensions) || + !ssl_ext_key_share_add_serverhello(hs, &extensions) || + !ssl_ext_supported_versions_add_serverhello(hs, &extensions) || + !ssl_add_message_cbb(ssl, cbb.get())) { + return ssl_hs_error; + } + + if (!hs->sent_hello_retry_request && + !ssl->method->add_change_cipher_spec(ssl)) { + return ssl_hs_error; + } + + // Derive and enable the handshake traffic secrets. + if (!tls13_derive_handshake_secrets(hs) || + !tls13_set_traffic_key(ssl, evp_aead_seal, hs->server_handshake_secret, + hs->hash_len)) { + return ssl_hs_error; + } + + // Send EncryptedExtensions. + if (!ssl->method->init_message(ssl, cbb.get(), &body, + SSL3_MT_ENCRYPTED_EXTENSIONS) || + !ssl_add_serverhello_tlsext(hs, &body) || + !ssl_add_message_cbb(ssl, cbb.get())) { + return ssl_hs_error; + } + + if (!ssl->s3->session_reused) { + // Determine whether to request a client certificate. + hs->cert_request = !!(ssl->verify_mode & SSL_VERIFY_PEER); + // Only request a certificate if Channel ID isn't negotiated. + if ((ssl->verify_mode & SSL_VERIFY_PEER_IF_NO_OBC) && + ssl->s3->tlsext_channel_id_valid) { + hs->cert_request = false; + } + } + + // Send a CertificateRequest, if necessary. + if (hs->cert_request) { + CBB cert_request_extensions, sigalg_contents, sigalgs_cbb; + if (!ssl->method->init_message(ssl, cbb.get(), &body, + SSL3_MT_CERTIFICATE_REQUEST) || + !CBB_add_u8(&body, 0 /* no certificate_request_context. */) || + !CBB_add_u16_length_prefixed(&body, &cert_request_extensions) || + !CBB_add_u16(&cert_request_extensions, + TLSEXT_TYPE_signature_algorithms) || + !CBB_add_u16_length_prefixed(&cert_request_extensions, + &sigalg_contents) || + !CBB_add_u16_length_prefixed(&sigalg_contents, &sigalgs_cbb) || + !tls12_add_verify_sigalgs(ssl, &sigalgs_cbb)) { + return ssl_hs_error; + } + + if (ssl_has_client_CAs(ssl)) { + CBB ca_contents; + if (!CBB_add_u16(&cert_request_extensions, + TLSEXT_TYPE_certificate_authorities) || + !CBB_add_u16_length_prefixed(&cert_request_extensions, + &ca_contents) || + !ssl_add_client_CA_list(ssl, &ca_contents) || + !CBB_flush(&cert_request_extensions)) { + return ssl_hs_error; + } + } + + if (!ssl_add_message_cbb(ssl, cbb.get())) { + return ssl_hs_error; + } + } + + // Send the server Certificate message, if necessary. + if (!ssl->s3->session_reused) { + if (!ssl_has_certificate(ssl)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_NO_CERTIFICATE_SET); + return ssl_hs_error; + } + + if (!tls13_add_certificate(hs)) { + return ssl_hs_error; + } + + hs->tls13_state = state_send_server_certificate_verify; + return ssl_hs_ok; + } + + hs->tls13_state = state_send_server_finished; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_send_server_certificate_verify(SSL_HANDSHAKE *hs) { + switch (tls13_add_certificate_verify(hs)) { + case ssl_private_key_success: + hs->tls13_state = state_send_server_finished; + return ssl_hs_ok; + + case ssl_private_key_retry: + hs->tls13_state = state_send_server_certificate_verify; + return ssl_hs_private_key_operation; + + case ssl_private_key_failure: + return ssl_hs_error; + } + + assert(0); + return ssl_hs_error; +} + +static enum ssl_hs_wait_t do_send_server_finished(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + if (!tls13_add_finished(hs) || + // Update the secret to the master secret and derive traffic keys. + !tls13_advance_key_schedule(hs, kZeroes, hs->hash_len) || + !tls13_derive_application_secrets(hs) || + !tls13_set_traffic_key(ssl, evp_aead_seal, hs->server_traffic_secret_0, + hs->hash_len)) { + return ssl_hs_error; + } + + if (ssl->s3->early_data_accepted) { + // If accepting 0-RTT, we send tickets half-RTT. This gets the tickets on + // the wire sooner and also avoids triggering a write on |SSL_read| when + // processing the client Finished. This requires computing the client + // Finished early. See draft-ietf-tls-tls13-18, section 4.5.1. + static const uint8_t kEndOfEarlyData[4] = {SSL3_MT_END_OF_EARLY_DATA, 0, + 0, 0}; + if (!hs->transcript.Update(kEndOfEarlyData)) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return ssl_hs_error; + } + + size_t finished_len; + if (!tls13_finished_mac(hs, hs->expected_client_finished, &finished_len, + 0 /* client */)) { + return ssl_hs_error; + } + + if (finished_len != hs->hash_len) { + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return ssl_hs_error; + } + + // Feed the predicted Finished into the transcript. This allows us to derive + // the resumption secret early and send half-RTT tickets. + // + // TODO(davidben): This will need to be updated for DTLS 1.3. + assert(!SSL_is_dtls(hs->ssl)); + assert(hs->hash_len <= 0xff); + uint8_t header[4] = {SSL3_MT_FINISHED, 0, 0, + static_cast(hs->hash_len)}; + if (!hs->transcript.Update(header) || + !hs->transcript.Update( + MakeConstSpan(hs->expected_client_finished, hs->hash_len)) || + !tls13_derive_resumption_secret(hs) || + !add_new_session_tickets(hs)) { + return ssl_hs_error; + } + } + + hs->tls13_state = state_read_second_client_flight; + return ssl_hs_flush; +} + +static enum ssl_hs_wait_t do_read_second_client_flight(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + if (ssl->s3->early_data_accepted) { + if (!tls13_set_traffic_key(ssl, evp_aead_open, hs->early_traffic_secret, + hs->hash_len)) { + return ssl_hs_error; + } + hs->can_early_write = true; + hs->can_early_read = true; + hs->in_early_data = true; + } + hs->tls13_state = state_process_end_of_early_data; + return ssl->s3->early_data_accepted ? ssl_hs_read_end_of_early_data + : ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_process_end_of_early_data(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + if (hs->early_data_offered) { + // If early data was not accepted, the EndOfEarlyData and ChangeCipherSpec + // message will be in the discarded early data. + if (hs->ssl->s3->early_data_accepted) { + SSLMessage msg; + if (!ssl->method->get_message(ssl, &msg)) { + return ssl_hs_read_message; + } + + if (!ssl_check_message_type(ssl, msg, SSL3_MT_END_OF_EARLY_DATA)) { + return ssl_hs_error; + } + if (CBS_len(&msg.body) != 0) { + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_DECODE_ERROR); + OPENSSL_PUT_ERROR(SSL, SSL_R_DECODE_ERROR); + return ssl_hs_error; + } + ssl->method->next_message(ssl); + } + } + if (!tls13_set_traffic_key(ssl, evp_aead_open, hs->client_handshake_secret, + hs->hash_len)) { + return ssl_hs_error; + } + hs->tls13_state = ssl->s3->early_data_accepted + ? state_read_client_finished + : state_read_client_certificate; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_read_client_certificate(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + if (!hs->cert_request) { + // OpenSSL returns X509_V_OK when no certificates are requested. This is + // classed by them as a bug, but it's assumed by at least NGINX. + hs->new_session->verify_result = X509_V_OK; + + // Skip this state. + hs->tls13_state = state_read_channel_id; + return ssl_hs_ok; + } + + const int allow_anonymous = + (ssl->verify_mode & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) == 0; + SSLMessage msg; + if (!ssl->method->get_message(ssl, &msg)) { + return ssl_hs_read_message; + } + if (!ssl_check_message_type(ssl, msg, SSL3_MT_CERTIFICATE) || + !tls13_process_certificate(hs, msg, allow_anonymous) || + !ssl_hash_message(hs, msg)) { + return ssl_hs_error; + } + + ssl->method->next_message(ssl); + hs->tls13_state = state_read_client_certificate_verify; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_read_client_certificate_verify( + SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + if (sk_CRYPTO_BUFFER_num(hs->new_session->certs) == 0) { + // Skip this state. + hs->tls13_state = state_read_channel_id; + return ssl_hs_ok; + } + + SSLMessage msg; + if (!ssl->method->get_message(ssl, &msg)) { + return ssl_hs_read_message; + } + + switch (ssl_verify_peer_cert(hs)) { + case ssl_verify_ok: + break; + case ssl_verify_invalid: + return ssl_hs_error; + case ssl_verify_retry: + hs->tls13_state = state_read_client_certificate_verify; + return ssl_hs_certificate_verify; + } + + if (!ssl_check_message_type(ssl, msg, SSL3_MT_CERTIFICATE_VERIFY) || + !tls13_process_certificate_verify(hs, msg) || + !ssl_hash_message(hs, msg)) { + return ssl_hs_error; + } + + ssl->method->next_message(ssl); + hs->tls13_state = state_read_channel_id; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_read_channel_id(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + if (!ssl->s3->tlsext_channel_id_valid) { + hs->tls13_state = state_read_client_finished; + return ssl_hs_ok; + } + + SSLMessage msg; + if (!ssl->method->get_message(ssl, &msg)) { + return ssl_hs_read_message; + } + if (!ssl_check_message_type(ssl, msg, SSL3_MT_CHANNEL_ID) || + !tls1_verify_channel_id(hs, msg) || + !ssl_hash_message(hs, msg)) { + return ssl_hs_error; + } + + ssl->method->next_message(ssl); + hs->tls13_state = state_read_client_finished; + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_read_client_finished(SSL_HANDSHAKE *hs) { + SSL *const ssl = hs->ssl; + SSLMessage msg; + if (!ssl->method->get_message(ssl, &msg)) { + return ssl_hs_read_message; + } + if (!ssl_check_message_type(ssl, msg, SSL3_MT_FINISHED) || + // If early data was accepted, we've already computed the client Finished + // and derived the resumption secret. + !tls13_process_finished(hs, msg, ssl->s3->early_data_accepted) || + // evp_aead_seal keys have already been switched. + !tls13_set_traffic_key(ssl, evp_aead_open, hs->client_traffic_secret_0, + hs->hash_len)) { + return ssl_hs_error; + } + + if (!ssl->s3->early_data_accepted) { + if (!ssl_hash_message(hs, msg) || + !tls13_derive_resumption_secret(hs)) { + return ssl_hs_error; + } + + // We send post-handshake tickets as part of the handshake in 1-RTT. + hs->tls13_state = state_send_new_session_ticket; + } else { + // We already sent half-RTT tickets. + hs->tls13_state = state_done; + } + + ssl->method->next_message(ssl); + return ssl_hs_ok; +} + +static enum ssl_hs_wait_t do_send_new_session_ticket(SSL_HANDSHAKE *hs) { + // If the client doesn't accept resumption with PSK_DHE_KE, don't send a + // session ticket. + if (!hs->accept_psk_mode) { + hs->tls13_state = state_done; + return ssl_hs_ok; + } + + if (!add_new_session_tickets(hs)) { + return ssl_hs_error; + } + + hs->tls13_state = state_done; + return ssl_hs_flush; +} + +enum ssl_hs_wait_t tls13_server_handshake(SSL_HANDSHAKE *hs) { + while (hs->tls13_state != state_done) { + enum ssl_hs_wait_t ret = ssl_hs_error; + enum server_hs_state_t state = + static_cast(hs->tls13_state); + switch (state) { + case state_select_parameters: + ret = do_select_parameters(hs); + break; + case state_select_session: + ret = do_select_session(hs); + break; + case state_send_hello_retry_request: + ret = do_send_hello_retry_request(hs); + break; + case state_read_second_client_hello: + ret = do_read_second_client_hello(hs); + break; + case state_send_server_hello: + ret = do_send_server_hello(hs); + break; + case state_send_server_certificate_verify: + ret = do_send_server_certificate_verify(hs); + break; + case state_send_server_finished: + ret = do_send_server_finished(hs); + break; + case state_read_second_client_flight: + ret = do_read_second_client_flight(hs); + break; + case state_process_end_of_early_data: + ret = do_process_end_of_early_data(hs); + break; + case state_read_client_certificate: + ret = do_read_client_certificate(hs); + break; + case state_read_client_certificate_verify: + ret = do_read_client_certificate_verify(hs); + break; + case state_read_channel_id: + ret = do_read_channel_id(hs); + break; + case state_read_client_finished: + ret = do_read_client_finished(hs); + break; + case state_send_new_session_ticket: + ret = do_send_new_session_ticket(hs); + break; + case state_done: + ret = ssl_hs_ok; + break; + } + + if (hs->tls13_state != state) { + ssl_do_info_callback(hs->ssl, SSL_CB_ACCEPT_LOOP, 1); + } + + if (ret != ssl_hs_ok) { + return ret; + } + } + + return ssl_hs_ok; +} + +const char *tls13_server_handshake_state(SSL_HANDSHAKE *hs) { + enum server_hs_state_t state = + static_cast(hs->tls13_state); + switch (state) { + case state_select_parameters: + return "TLS 1.3 server select_parameters"; + case state_select_session: + return "TLS 1.3 server select_session"; + case state_send_hello_retry_request: + return "TLS 1.3 server send_hello_retry_request"; + case state_read_second_client_hello: + return "TLS 1.3 server read_second_client_hello"; + case state_send_server_hello: + return "TLS 1.3 server send_server_hello"; + case state_send_server_certificate_verify: + return "TLS 1.3 server send_server_certificate_verify"; + case state_send_server_finished: + return "TLS 1.3 server send_server_finished"; + case state_read_second_client_flight: + return "TLS 1.3 server read_second_client_flight"; + case state_process_end_of_early_data: + return "TLS 1.3 server process_end_of_early_data"; + case state_read_client_certificate: + return "TLS 1.3 server read_client_certificate"; + case state_read_client_certificate_verify: + return "TLS 1.3 server read_client_certificate_verify"; + case state_read_channel_id: + return "TLS 1.3 server read_channel_id"; + case state_read_client_finished: + return "TLS 1.3 server read_client_finished"; + case state_send_new_session_ticket: + return "TLS 1.3 server send_new_session_ticket"; + case state_done: + return "TLS 1.3 server done"; + } + + return "TLS 1.3 server unknown"; +} + +} // namespace bssl diff --git a/FoodApp/Pods/BoringSSL-GRPC/ssl/tls_method.cc b/FoodApp/Pods/BoringSSL-GRPC/ssl/tls_method.cc new file mode 100644 index 0000000..fde8b8d --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/ssl/tls_method.cc @@ -0,0 +1,274 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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/internal.h" +#include "internal.h" + + +namespace bssl { + +static void ssl3_on_handshake_complete(SSL *ssl) { + // The handshake should have released its final message. + assert(!ssl->s3->has_message); + + // During the handshake, |hs_buf| is retained. Release if it there is no + // excess in it. There may be excess left if there server sent Finished and + // HelloRequest in the same record. + // + // TODO(davidben): SChannel does not support this. Reject this case. + if (ssl->s3->hs_buf && ssl->s3->hs_buf->length == 0) { + ssl->s3->hs_buf.reset(); + } +} + +static bool ssl3_set_read_state(SSL *ssl, UniquePtr aead_ctx) { + // Cipher changes are forbidden if the current epoch has leftover data. + if (tls_has_unprocessed_handshake_data(ssl)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_BUFFERED_MESSAGES_ON_CIPHER_CHANGE); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE); + return false; + } + + OPENSSL_memset(ssl->s3->read_sequence, 0, sizeof(ssl->s3->read_sequence)); + ssl->s3->aead_read_ctx = std::move(aead_ctx); + return true; +} + +static bool ssl3_set_write_state(SSL *ssl, UniquePtr aead_ctx) { + OPENSSL_memset(ssl->s3->write_sequence, 0, sizeof(ssl->s3->write_sequence)); + ssl->s3->aead_write_ctx = std::move(aead_ctx); + return true; +} + +static const SSL_PROTOCOL_METHOD kTLSProtocolMethod = { + false /* is_dtls */, + ssl3_new, + ssl3_free, + ssl3_get_message, + ssl3_next_message, + ssl3_open_handshake, + ssl3_open_change_cipher_spec, + ssl3_open_app_data, + ssl3_write_app_data, + ssl3_dispatch_alert, + ssl3_init_message, + ssl3_finish_message, + ssl3_add_message, + ssl3_add_change_cipher_spec, + ssl3_add_alert, + ssl3_flush_flight, + ssl3_on_handshake_complete, + ssl3_set_read_state, + ssl3_set_write_state, +}; + +static int ssl_noop_x509_check_client_CA_names( + STACK_OF(CRYPTO_BUFFER) *names) { + return 1; +} + +static void ssl_noop_x509_clear(CERT *cert) {} +static void ssl_noop_x509_free(CERT *cert) {} +static void ssl_noop_x509_dup(CERT *new_cert, const CERT *cert) {} +static void ssl_noop_x509_flush_cached_leaf(CERT *cert) {} +static void ssl_noop_x509_flush_cached_chain(CERT *cert) {} +static int ssl_noop_x509_session_cache_objects(SSL_SESSION *sess) { + return 1; +} +static int ssl_noop_x509_session_dup(SSL_SESSION *new_session, + const SSL_SESSION *session) { + return 1; +} +static void ssl_noop_x509_session_clear(SSL_SESSION *session) {} +static int ssl_noop_x509_session_verify_cert_chain(SSL_SESSION *session, + SSL *ssl, + uint8_t *out_alert) { + return 0; +} + +static void ssl_noop_x509_hs_flush_cached_ca_names(SSL_HANDSHAKE *hs) {} +static int ssl_noop_x509_ssl_new(SSL *ctx) { return 1; } +static void ssl_noop_x509_ssl_free(SSL *ctx) { } +static void ssl_noop_x509_ssl_flush_cached_client_CA(SSL *ssl) {} +static int ssl_noop_x509_ssl_auto_chain_if_needed(SSL *ssl) { return 1; } +static int ssl_noop_x509_ssl_ctx_new(SSL_CTX *ctx) { return 1; } +static void ssl_noop_x509_ssl_ctx_free(SSL_CTX *ctx) { } +static void ssl_noop_x509_ssl_ctx_flush_cached_client_CA(SSL_CTX *ctx) {} + +const SSL_X509_METHOD ssl_noop_x509_method = { + ssl_noop_x509_check_client_CA_names, + ssl_noop_x509_clear, + ssl_noop_x509_free, + ssl_noop_x509_dup, + ssl_noop_x509_flush_cached_chain, + ssl_noop_x509_flush_cached_leaf, + ssl_noop_x509_session_cache_objects, + ssl_noop_x509_session_dup, + ssl_noop_x509_session_clear, + ssl_noop_x509_session_verify_cert_chain, + ssl_noop_x509_hs_flush_cached_ca_names, + ssl_noop_x509_ssl_new, + ssl_noop_x509_ssl_free, + ssl_noop_x509_ssl_flush_cached_client_CA, + ssl_noop_x509_ssl_auto_chain_if_needed, + ssl_noop_x509_ssl_ctx_new, + ssl_noop_x509_ssl_ctx_free, + ssl_noop_x509_ssl_ctx_flush_cached_client_CA, +}; + +} // namespace bssl + +using namespace bssl; + +const SSL_METHOD *TLS_method(void) { + static const SSL_METHOD kMethod = { + 0, + &kTLSProtocolMethod, + &ssl_crypto_x509_method, + }; + return &kMethod; +} + +const SSL_METHOD *SSLv23_method(void) { + return TLS_method(); +} + +const SSL_METHOD *TLS_with_buffers_method(void) { + static const SSL_METHOD kMethod = { + 0, + &kTLSProtocolMethod, + &ssl_noop_x509_method, + }; + return &kMethod; +} + +// Legacy version-locked methods. + +const SSL_METHOD *TLSv1_2_method(void) { + static const SSL_METHOD kMethod = { + TLS1_2_VERSION, + &kTLSProtocolMethod, + &ssl_crypto_x509_method, + }; + return &kMethod; +} + +const SSL_METHOD *TLSv1_1_method(void) { + static const SSL_METHOD kMethod = { + TLS1_1_VERSION, + &kTLSProtocolMethod, + &ssl_crypto_x509_method, + }; + return &kMethod; +} + +const SSL_METHOD *TLSv1_method(void) { + static const SSL_METHOD kMethod = { + TLS1_VERSION, + &kTLSProtocolMethod, + &ssl_crypto_x509_method, + }; + return &kMethod; +} + +// Legacy side-specific methods. + +const SSL_METHOD *TLSv1_2_server_method(void) { + return TLSv1_2_method(); +} + +const SSL_METHOD *TLSv1_1_server_method(void) { + return TLSv1_1_method(); +} + +const SSL_METHOD *TLSv1_server_method(void) { + return TLSv1_method(); +} + +const SSL_METHOD *TLSv1_2_client_method(void) { + return TLSv1_2_method(); +} + +const SSL_METHOD *TLSv1_1_client_method(void) { + return TLSv1_1_method(); +} + +const SSL_METHOD *TLSv1_client_method(void) { + return TLSv1_method(); +} + +const SSL_METHOD *SSLv23_server_method(void) { + return SSLv23_method(); +} + +const SSL_METHOD *SSLv23_client_method(void) { + return SSLv23_method(); +} + +const SSL_METHOD *TLS_server_method(void) { + return TLS_method(); +} + +const SSL_METHOD *TLS_client_method(void) { + return TLS_method(); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/ssl/tls_method.cc.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/ssl/tls_method.cc.grpc_back new file mode 100644 index 0000000..2ad2817 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/ssl/tls_method.cc.grpc_back @@ -0,0 +1,274 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of this code 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/internal.h" +#include "internal.h" + + +namespace bssl { + +static void ssl3_on_handshake_complete(SSL *ssl) { + // The handshake should have released its final message. + assert(!ssl->s3->has_message); + + // During the handshake, |hs_buf| is retained. Release if it there is no + // excess in it. There may be excess left if there server sent Finished and + // HelloRequest in the same record. + // + // TODO(davidben): SChannel does not support this. Reject this case. + if (ssl->s3->hs_buf && ssl->s3->hs_buf->length == 0) { + ssl->s3->hs_buf.reset(); + } +} + +static bool ssl3_set_read_state(SSL *ssl, UniquePtr aead_ctx) { + // Cipher changes are forbidden if the current epoch has leftover data. + if (tls_has_unprocessed_handshake_data(ssl)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_BUFFERED_MESSAGES_ON_CIPHER_CHANGE); + ssl_send_alert(ssl, SSL3_AL_FATAL, SSL_AD_UNEXPECTED_MESSAGE); + return false; + } + + OPENSSL_memset(ssl->s3->read_sequence, 0, sizeof(ssl->s3->read_sequence)); + ssl->s3->aead_read_ctx = std::move(aead_ctx); + return true; +} + +static bool ssl3_set_write_state(SSL *ssl, UniquePtr aead_ctx) { + OPENSSL_memset(ssl->s3->write_sequence, 0, sizeof(ssl->s3->write_sequence)); + ssl->s3->aead_write_ctx = std::move(aead_ctx); + return true; +} + +static const SSL_PROTOCOL_METHOD kTLSProtocolMethod = { + false /* is_dtls */, + ssl3_new, + ssl3_free, + ssl3_get_message, + ssl3_next_message, + ssl3_open_handshake, + ssl3_open_change_cipher_spec, + ssl3_open_app_data, + ssl3_write_app_data, + ssl3_dispatch_alert, + ssl3_init_message, + ssl3_finish_message, + ssl3_add_message, + ssl3_add_change_cipher_spec, + ssl3_add_alert, + ssl3_flush_flight, + ssl3_on_handshake_complete, + ssl3_set_read_state, + ssl3_set_write_state, +}; + +static int ssl_noop_x509_check_client_CA_names( + STACK_OF(CRYPTO_BUFFER) *names) { + return 1; +} + +static void ssl_noop_x509_clear(CERT *cert) {} +static void ssl_noop_x509_free(CERT *cert) {} +static void ssl_noop_x509_dup(CERT *new_cert, const CERT *cert) {} +static void ssl_noop_x509_flush_cached_leaf(CERT *cert) {} +static void ssl_noop_x509_flush_cached_chain(CERT *cert) {} +static int ssl_noop_x509_session_cache_objects(SSL_SESSION *sess) { + return 1; +} +static int ssl_noop_x509_session_dup(SSL_SESSION *new_session, + const SSL_SESSION *session) { + return 1; +} +static void ssl_noop_x509_session_clear(SSL_SESSION *session) {} +static int ssl_noop_x509_session_verify_cert_chain(SSL_SESSION *session, + SSL *ssl, + uint8_t *out_alert) { + return 0; +} + +static void ssl_noop_x509_hs_flush_cached_ca_names(SSL_HANDSHAKE *hs) {} +static int ssl_noop_x509_ssl_new(SSL *ctx) { return 1; } +static void ssl_noop_x509_ssl_free(SSL *ctx) { } +static void ssl_noop_x509_ssl_flush_cached_client_CA(SSL *ssl) {} +static int ssl_noop_x509_ssl_auto_chain_if_needed(SSL *ssl) { return 1; } +static int ssl_noop_x509_ssl_ctx_new(SSL_CTX *ctx) { return 1; } +static void ssl_noop_x509_ssl_ctx_free(SSL_CTX *ctx) { } +static void ssl_noop_x509_ssl_ctx_flush_cached_client_CA(SSL_CTX *ctx) {} + +const SSL_X509_METHOD ssl_noop_x509_method = { + ssl_noop_x509_check_client_CA_names, + ssl_noop_x509_clear, + ssl_noop_x509_free, + ssl_noop_x509_dup, + ssl_noop_x509_flush_cached_chain, + ssl_noop_x509_flush_cached_leaf, + ssl_noop_x509_session_cache_objects, + ssl_noop_x509_session_dup, + ssl_noop_x509_session_clear, + ssl_noop_x509_session_verify_cert_chain, + ssl_noop_x509_hs_flush_cached_ca_names, + ssl_noop_x509_ssl_new, + ssl_noop_x509_ssl_free, + ssl_noop_x509_ssl_flush_cached_client_CA, + ssl_noop_x509_ssl_auto_chain_if_needed, + ssl_noop_x509_ssl_ctx_new, + ssl_noop_x509_ssl_ctx_free, + ssl_noop_x509_ssl_ctx_flush_cached_client_CA, +}; + +} // namespace bssl + +using namespace bssl; + +const SSL_METHOD *TLS_method(void) { + static const SSL_METHOD kMethod = { + 0, + &kTLSProtocolMethod, + &ssl_crypto_x509_method, + }; + return &kMethod; +} + +const SSL_METHOD *SSLv23_method(void) { + return TLS_method(); +} + +const SSL_METHOD *TLS_with_buffers_method(void) { + static const SSL_METHOD kMethod = { + 0, + &kTLSProtocolMethod, + &ssl_noop_x509_method, + }; + return &kMethod; +} + +// Legacy version-locked methods. + +const SSL_METHOD *TLSv1_2_method(void) { + static const SSL_METHOD kMethod = { + TLS1_2_VERSION, + &kTLSProtocolMethod, + &ssl_crypto_x509_method, + }; + return &kMethod; +} + +const SSL_METHOD *TLSv1_1_method(void) { + static const SSL_METHOD kMethod = { + TLS1_1_VERSION, + &kTLSProtocolMethod, + &ssl_crypto_x509_method, + }; + return &kMethod; +} + +const SSL_METHOD *TLSv1_method(void) { + static const SSL_METHOD kMethod = { + TLS1_VERSION, + &kTLSProtocolMethod, + &ssl_crypto_x509_method, + }; + return &kMethod; +} + +// Legacy side-specific methods. + +const SSL_METHOD *TLSv1_2_server_method(void) { + return TLSv1_2_method(); +} + +const SSL_METHOD *TLSv1_1_server_method(void) { + return TLSv1_1_method(); +} + +const SSL_METHOD *TLSv1_server_method(void) { + return TLSv1_method(); +} + +const SSL_METHOD *TLSv1_2_client_method(void) { + return TLSv1_2_method(); +} + +const SSL_METHOD *TLSv1_1_client_method(void) { + return TLSv1_1_method(); +} + +const SSL_METHOD *TLSv1_client_method(void) { + return TLSv1_method(); +} + +const SSL_METHOD *SSLv23_server_method(void) { + return SSLv23_method(); +} + +const SSL_METHOD *SSLv23_client_method(void) { + return SSLv23_method(); +} + +const SSL_METHOD *TLS_server_method(void) { + return TLS_method(); +} + +const SSL_METHOD *TLS_client_method(void) { + return TLS_method(); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/ssl/tls_record.cc b/FoodApp/Pods/BoringSSL-GRPC/ssl/tls_record.cc new file mode 100644 index 0000000..e6f6e39 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/ssl/tls_record.cc @@ -0,0 +1,703 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 +#include + +#include +#include +#include + +#include "internal.h" +#include "../crypto/internal.h" + + +namespace bssl { + +// kMaxEmptyRecords is the number of consecutive, empty records that will be +// processed. Without this limit an attacker could send empty records at a +// faster rate than we can process and cause record processing to loop +// forever. +static const uint8_t kMaxEmptyRecords = 32; + +// kMaxEarlyDataSkipped is the maximum number of rejected early data bytes that +// will be skipped. Without this limit an attacker could send records at a +// faster rate than we can process and cause trial decryption to loop forever. +// This value should be slightly above kMaxEarlyDataAccepted, which is measured +// in plaintext. +static const size_t kMaxEarlyDataSkipped = 16384; + +// kMaxWarningAlerts is the number of consecutive warning alerts that will be +// processed. +static const uint8_t kMaxWarningAlerts = 4; + +// ssl_needs_record_splitting returns one if |ssl|'s current outgoing cipher +// state needs record-splitting and zero otherwise. +static int ssl_needs_record_splitting(const SSL *ssl) { +#if !defined(BORINGSSL_UNSAFE_FUZZER_MODE) + return !ssl->s3->aead_write_ctx->is_null_cipher() && + ssl->s3->aead_write_ctx->ProtocolVersion() < TLS1_1_VERSION && + (ssl->mode & SSL_MODE_CBC_RECORD_SPLITTING) != 0 && + SSL_CIPHER_is_block_cipher(ssl->s3->aead_write_ctx->cipher()); +#else + return 0; +#endif +} + +int ssl_record_sequence_update(uint8_t *seq, size_t seq_len) { + for (size_t i = seq_len - 1; i < seq_len; i--) { + ++seq[i]; + if (seq[i] != 0) { + return 1; + } + } + OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW); + return 0; +} + +size_t ssl_record_prefix_len(const SSL *ssl) { + size_t header_len; + if (SSL_is_dtls(ssl)) { + header_len = DTLS1_RT_HEADER_LENGTH; + } else { + header_len = SSL3_RT_HEADER_LENGTH; + } + + return header_len + ssl->s3->aead_read_ctx->ExplicitNonceLen(); +} + +size_t ssl_seal_align_prefix_len(const SSL *ssl) { + if (SSL_is_dtls(ssl)) { + return DTLS1_RT_HEADER_LENGTH + ssl->s3->aead_write_ctx->ExplicitNonceLen(); + } + + size_t ret = + SSL3_RT_HEADER_LENGTH + ssl->s3->aead_write_ctx->ExplicitNonceLen(); + if (ssl_needs_record_splitting(ssl)) { + ret += SSL3_RT_HEADER_LENGTH; + ret += ssl_cipher_get_record_split_len(ssl->s3->aead_write_ctx->cipher()); + } + return ret; +} + +static ssl_open_record_t skip_early_data(SSL *ssl, uint8_t *out_alert, + size_t consumed) { + ssl->s3->early_data_skipped += consumed; + if (ssl->s3->early_data_skipped < consumed) { + ssl->s3->early_data_skipped = kMaxEarlyDataSkipped + 1; + } + + if (ssl->s3->early_data_skipped > kMaxEarlyDataSkipped) { + OPENSSL_PUT_ERROR(SSL, SSL_R_TOO_MUCH_SKIPPED_EARLY_DATA); + *out_alert = SSL_AD_UNEXPECTED_MESSAGE; + return ssl_open_record_error; + } + + return ssl_open_record_discard; +} + +ssl_open_record_t tls_open_record(SSL *ssl, uint8_t *out_type, + Span *out, size_t *out_consumed, + uint8_t *out_alert, Span in) { + *out_consumed = 0; + if (ssl->s3->read_shutdown == ssl_shutdown_close_notify) { + return ssl_open_record_close_notify; + } + + // If there is an unprocessed handshake message or we are already buffering + // too much, stop before decrypting another handshake record. + if (!tls_can_accept_handshake_data(ssl, out_alert)) { + return ssl_open_record_error; + } + + CBS cbs = CBS(in); + + // Decode the record header. + uint8_t type; + uint16_t version, ciphertext_len; + if (!CBS_get_u8(&cbs, &type) || + !CBS_get_u16(&cbs, &version) || + !CBS_get_u16(&cbs, &ciphertext_len)) { + *out_consumed = SSL3_RT_HEADER_LENGTH; + return ssl_open_record_partial; + } + + bool version_ok; + if (ssl->s3->aead_read_ctx->is_null_cipher()) { + // Only check the first byte. Enforcing beyond that can prevent decoding + // version negotiation failure alerts. + version_ok = (version >> 8) == SSL3_VERSION_MAJOR; + } else { + version_ok = version == ssl->s3->aead_read_ctx->RecordVersion(); + } + + if (!version_ok) { + OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_VERSION_NUMBER); + *out_alert = SSL_AD_PROTOCOL_VERSION; + return ssl_open_record_error; + } + + // Check the ciphertext length. + if (ciphertext_len > SSL3_RT_MAX_ENCRYPTED_LENGTH) { + OPENSSL_PUT_ERROR(SSL, SSL_R_ENCRYPTED_LENGTH_TOO_LONG); + *out_alert = SSL_AD_RECORD_OVERFLOW; + return ssl_open_record_error; + } + + // Extract the body. + CBS body; + if (!CBS_get_bytes(&cbs, &body, ciphertext_len)) { + *out_consumed = SSL3_RT_HEADER_LENGTH + (size_t)ciphertext_len; + return ssl_open_record_partial; + } + + ssl_do_msg_callback(ssl, 0 /* read */, SSL3_RT_HEADER, + in.subspan(0, SSL3_RT_HEADER_LENGTH)); + + *out_consumed = in.size() - CBS_len(&cbs); + + if (ssl->s3->have_version && + ssl_protocol_version(ssl) >= TLS1_3_VERSION && + SSL_in_init(ssl) && + type == SSL3_RT_CHANGE_CIPHER_SPEC && + ciphertext_len == 1 && + CBS_data(&body)[0] == 1) { + ssl->s3->empty_record_count++; + if (ssl->s3->empty_record_count > kMaxEmptyRecords) { + OPENSSL_PUT_ERROR(SSL, SSL_R_TOO_MANY_EMPTY_FRAGMENTS); + *out_alert = SSL_AD_UNEXPECTED_MESSAGE; + return ssl_open_record_error; + } + return ssl_open_record_discard; + } + + // Skip early data received when expecting a second ClientHello if we rejected + // 0RTT. + if (ssl->s3->skip_early_data && + ssl->s3->aead_read_ctx->is_null_cipher() && + type == SSL3_RT_APPLICATION_DATA) { + return skip_early_data(ssl, out_alert, *out_consumed); + } + + // Decrypt the body in-place. + if (!ssl->s3->aead_read_ctx->Open( + out, type, version, ssl->s3->read_sequence, + MakeSpan(const_cast(CBS_data(&body)), CBS_len(&body)))) { + if (ssl->s3->skip_early_data && !ssl->s3->aead_read_ctx->is_null_cipher()) { + ERR_clear_error(); + return skip_early_data(ssl, out_alert, *out_consumed); + } + + OPENSSL_PUT_ERROR(SSL, SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC); + *out_alert = SSL_AD_BAD_RECORD_MAC; + return ssl_open_record_error; + } + + ssl->s3->skip_early_data = false; + + if (!ssl_record_sequence_update(ssl->s3->read_sequence, 8)) { + *out_alert = SSL_AD_INTERNAL_ERROR; + return ssl_open_record_error; + } + + // TLS 1.3 hides the record type inside the encrypted data. + bool has_padding = + !ssl->s3->aead_read_ctx->is_null_cipher() && + ssl->s3->aead_read_ctx->ProtocolVersion() >= TLS1_3_VERSION; + + // If there is padding, the plaintext limit includes the padding, but includes + // extra room for the inner content type. + size_t plaintext_limit = + has_padding ? SSL3_RT_MAX_PLAIN_LENGTH + 1 : SSL3_RT_MAX_PLAIN_LENGTH; + if (out->size() > plaintext_limit) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DATA_LENGTH_TOO_LONG); + *out_alert = SSL_AD_RECORD_OVERFLOW; + return ssl_open_record_error; + } + + if (has_padding) { + // The outer record type is always application_data. + if (type != SSL3_RT_APPLICATION_DATA) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_OUTER_RECORD_TYPE); + *out_alert = SSL_AD_DECODE_ERROR; + return ssl_open_record_error; + } + + do { + if (out->empty()) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC); + *out_alert = SSL_AD_DECRYPT_ERROR; + return ssl_open_record_error; + } + type = out->back(); + *out = out->subspan(0, out->size() - 1); + } while (type == 0); + } + + // Limit the number of consecutive empty records. + if (out->empty()) { + ssl->s3->empty_record_count++; + if (ssl->s3->empty_record_count > kMaxEmptyRecords) { + OPENSSL_PUT_ERROR(SSL, SSL_R_TOO_MANY_EMPTY_FRAGMENTS); + *out_alert = SSL_AD_UNEXPECTED_MESSAGE; + return ssl_open_record_error; + } + // Apart from the limit, empty records are returned up to the caller. This + // allows the caller to reject records of the wrong type. + } else { + ssl->s3->empty_record_count = 0; + } + + if (type == SSL3_RT_ALERT) { + return ssl_process_alert(ssl, out_alert, *out); + } + + // Handshake messages may not interleave with any other record type. + if (type != SSL3_RT_HANDSHAKE && + tls_has_unprocessed_handshake_data(ssl)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_RECORD); + *out_alert = SSL_AD_UNEXPECTED_MESSAGE; + return ssl_open_record_error; + } + + ssl->s3->warning_alert_count = 0; + + *out_type = type; + return ssl_open_record_success; +} + +static int do_seal_record(SSL *ssl, uint8_t *out_prefix, uint8_t *out, + uint8_t *out_suffix, uint8_t type, const uint8_t *in, + const size_t in_len) { + uint8_t *extra_in = NULL; + size_t extra_in_len = 0; + if (!ssl->s3->aead_write_ctx->is_null_cipher() && + ssl->s3->aead_write_ctx->ProtocolVersion() >= TLS1_3_VERSION) { + // TLS 1.3 hides the actual record type inside the encrypted data. + extra_in = &type; + extra_in_len = 1; + } + + size_t suffix_len; + if (!ssl->s3->aead_write_ctx->SuffixLen(&suffix_len, in_len, extra_in_len)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_RECORD_TOO_LARGE); + return 0; + } + size_t ciphertext_len = + ssl->s3->aead_write_ctx->ExplicitNonceLen() + suffix_len; + if (ciphertext_len + in_len < ciphertext_len) { + OPENSSL_PUT_ERROR(SSL, SSL_R_RECORD_TOO_LARGE); + return 0; + } + ciphertext_len += in_len; + + assert(in == out || !buffers_alias(in, in_len, out, in_len)); + assert(!buffers_alias(in, in_len, out_prefix, ssl_record_prefix_len(ssl))); + assert(!buffers_alias(in, in_len, out_suffix, suffix_len)); + + if (extra_in_len) { + out_prefix[0] = SSL3_RT_APPLICATION_DATA; + } else { + out_prefix[0] = type; + } + + uint16_t record_version = ssl->s3->aead_write_ctx->RecordVersion(); + + out_prefix[1] = record_version >> 8; + out_prefix[2] = record_version & 0xff; + out_prefix[3] = ciphertext_len >> 8; + out_prefix[4] = ciphertext_len & 0xff; + + if (!ssl->s3->aead_write_ctx->SealScatter( + out_prefix + SSL3_RT_HEADER_LENGTH, out, out_suffix, type, + record_version, ssl->s3->write_sequence, in, in_len, extra_in, + extra_in_len) || + !ssl_record_sequence_update(ssl->s3->write_sequence, 8)) { + return 0; + } + + ssl_do_msg_callback(ssl, 1 /* write */, SSL3_RT_HEADER, + MakeSpan(out_prefix, SSL3_RT_HEADER_LENGTH)); + return 1; +} + +static size_t tls_seal_scatter_prefix_len(const SSL *ssl, uint8_t type, + size_t in_len) { + size_t ret = SSL3_RT_HEADER_LENGTH; + if (type == SSL3_RT_APPLICATION_DATA && in_len > 1 && + ssl_needs_record_splitting(ssl)) { + // In the case of record splitting, the 1-byte record (of the 1/n-1 split) + // will be placed in the prefix, as will four of the five bytes of the + // record header for the main record. The final byte will replace the first + // byte of the plaintext that was used in the small record. + ret += ssl_cipher_get_record_split_len(ssl->s3->aead_write_ctx->cipher()); + ret += SSL3_RT_HEADER_LENGTH - 1; + } else { + ret += ssl->s3->aead_write_ctx->ExplicitNonceLen(); + } + return ret; +} + +static bool tls_seal_scatter_suffix_len(const SSL *ssl, size_t *out_suffix_len, + uint8_t type, size_t in_len) { + size_t extra_in_len = 0; + if (!ssl->s3->aead_write_ctx->is_null_cipher() && + ssl->s3->aead_write_ctx->ProtocolVersion() >= TLS1_3_VERSION) { + // TLS 1.3 adds an extra byte for encrypted record type. + extra_in_len = 1; + } + if (type == SSL3_RT_APPLICATION_DATA && // clang-format off + in_len > 1 && + ssl_needs_record_splitting(ssl)) { + // With record splitting enabled, the first byte gets sealed into a separate + // record which is written into the prefix. + in_len -= 1; + } + return ssl->s3->aead_write_ctx->SuffixLen(out_suffix_len, in_len, extra_in_len); +} + +// tls_seal_scatter_record seals a new record of type |type| and body |in| and +// splits it between |out_prefix|, |out|, and |out_suffix|. Exactly +// |tls_seal_scatter_prefix_len| bytes are written to |out_prefix|, |in_len| +// bytes to |out|, and |tls_seal_scatter_suffix_len| bytes to |out_suffix|. It +// returns one on success and zero on error. If enabled, +// |tls_seal_scatter_record| implements TLS 1.0 CBC 1/n-1 record splitting and +// may write two records concatenated. +static int tls_seal_scatter_record(SSL *ssl, uint8_t *out_prefix, uint8_t *out, + uint8_t *out_suffix, uint8_t type, + const uint8_t *in, size_t in_len) { + if (type == SSL3_RT_APPLICATION_DATA && in_len > 1 && + ssl_needs_record_splitting(ssl)) { + assert(ssl->s3->aead_write_ctx->ExplicitNonceLen() == 0); + const size_t prefix_len = SSL3_RT_HEADER_LENGTH; + + // Write the 1-byte fragment into |out_prefix|. + uint8_t *split_body = out_prefix + prefix_len; + uint8_t *split_suffix = split_body + 1; + + if (!do_seal_record(ssl, out_prefix, split_body, split_suffix, type, in, + 1)) { + return 0; + } + + size_t split_record_suffix_len; + if (!ssl->s3->aead_write_ctx->SuffixLen(&split_record_suffix_len, 1, 0)) { + assert(false); + return 0; + } + const size_t split_record_len = prefix_len + 1 + split_record_suffix_len; + assert(SSL3_RT_HEADER_LENGTH + ssl_cipher_get_record_split_len( + ssl->s3->aead_write_ctx->cipher()) == + split_record_len); + + // Write the n-1-byte fragment. The header gets split between |out_prefix| + // (header[:-1]) and |out| (header[-1:]). + uint8_t tmp_prefix[SSL3_RT_HEADER_LENGTH]; + if (!do_seal_record(ssl, tmp_prefix, out + 1, out_suffix, type, in + 1, + in_len - 1)) { + return 0; + } + assert(tls_seal_scatter_prefix_len(ssl, type, in_len) == + split_record_len + SSL3_RT_HEADER_LENGTH - 1); + OPENSSL_memcpy(out_prefix + split_record_len, tmp_prefix, + SSL3_RT_HEADER_LENGTH - 1); + OPENSSL_memcpy(out, tmp_prefix + SSL3_RT_HEADER_LENGTH - 1, 1); + return 1; + } + + return do_seal_record(ssl, out_prefix, out, out_suffix, type, in, in_len); +} + +int tls_seal_record(SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out_len, + uint8_t type, const uint8_t *in, size_t in_len) { + if (buffers_alias(in, in_len, out, max_out_len)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_OUTPUT_ALIASES_INPUT); + return 0; + } + + const size_t prefix_len = tls_seal_scatter_prefix_len(ssl, type, in_len); + size_t suffix_len; + if (!tls_seal_scatter_suffix_len(ssl, &suffix_len, type, in_len)) { + return false; + } + if (in_len + prefix_len < in_len || + prefix_len + in_len + suffix_len < prefix_len + in_len) { + OPENSSL_PUT_ERROR(SSL, SSL_R_RECORD_TOO_LARGE); + return 0; + } + if (max_out_len < in_len + prefix_len + suffix_len) { + OPENSSL_PUT_ERROR(SSL, SSL_R_BUFFER_TOO_SMALL); + return 0; + } + + uint8_t *prefix = out; + uint8_t *body = out + prefix_len; + uint8_t *suffix = body + in_len; + if (!tls_seal_scatter_record(ssl, prefix, body, suffix, type, in, in_len)) { + return 0; + } + + *out_len = prefix_len + in_len + suffix_len; + return 1; +} + +enum ssl_open_record_t ssl_process_alert(SSL *ssl, uint8_t *out_alert, + Span in) { + // Alerts records may not contain fragmented or multiple alerts. + if (in.size() != 2) { + *out_alert = SSL_AD_DECODE_ERROR; + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_ALERT); + return ssl_open_record_error; + } + + ssl_do_msg_callback(ssl, 0 /* read */, SSL3_RT_ALERT, in); + + const uint8_t alert_level = in[0]; + const uint8_t alert_descr = in[1]; + + uint16_t alert = (alert_level << 8) | alert_descr; + ssl_do_info_callback(ssl, SSL_CB_READ_ALERT, alert); + + if (alert_level == SSL3_AL_WARNING) { + if (alert_descr == SSL_AD_CLOSE_NOTIFY) { + ssl->s3->read_shutdown = ssl_shutdown_close_notify; + return ssl_open_record_close_notify; + } + + // Warning alerts do not exist in TLS 1.3. + if (ssl->s3->have_version && + ssl_protocol_version(ssl) >= TLS1_3_VERSION) { + *out_alert = SSL_AD_DECODE_ERROR; + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_ALERT); + return ssl_open_record_error; + } + + ssl->s3->warning_alert_count++; + if (ssl->s3->warning_alert_count > kMaxWarningAlerts) { + *out_alert = SSL_AD_UNEXPECTED_MESSAGE; + OPENSSL_PUT_ERROR(SSL, SSL_R_TOO_MANY_WARNING_ALERTS); + return ssl_open_record_error; + } + return ssl_open_record_discard; + } + + if (alert_level == SSL3_AL_FATAL) { + OPENSSL_PUT_ERROR(SSL, SSL_AD_REASON_OFFSET + alert_descr); + ERR_add_error_dataf("SSL alert number %d", alert_descr); + *out_alert = 0; // No alert to send back to the peer. + return ssl_open_record_error; + } + + *out_alert = SSL_AD_ILLEGAL_PARAMETER; + OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_ALERT_TYPE); + return ssl_open_record_error; +} + +OpenRecordResult OpenRecord(SSL *ssl, Span *out, + size_t *out_record_len, uint8_t *out_alert, + const Span in) { + // This API is a work in progress and currently only works for TLS 1.2 servers + // and below. + if (SSL_in_init(ssl) || + SSL_is_dtls(ssl) || + ssl_protocol_version(ssl) > TLS1_2_VERSION) { + assert(false); + *out_alert = SSL_AD_INTERNAL_ERROR; + return OpenRecordResult::kError; + } + + Span plaintext; + uint8_t type = 0; + const ssl_open_record_t result = tls_open_record( + ssl, &type, &plaintext, out_record_len, out_alert, in); + + switch (result) { + case ssl_open_record_success: + if (type != SSL3_RT_APPLICATION_DATA && type != SSL3_RT_ALERT) { + *out_alert = SSL_AD_UNEXPECTED_MESSAGE; + return OpenRecordResult::kError; + } + *out = plaintext; + return OpenRecordResult::kOK; + case ssl_open_record_discard: + return OpenRecordResult::kDiscard; + case ssl_open_record_partial: + return OpenRecordResult::kIncompleteRecord; + case ssl_open_record_close_notify: + return OpenRecordResult::kAlertCloseNotify; + case ssl_open_record_error: + return OpenRecordResult::kError; + } + assert(false); + return OpenRecordResult::kError; +} + +size_t SealRecordPrefixLen(const SSL *ssl, const size_t record_len) { + return tls_seal_scatter_prefix_len(ssl, SSL3_RT_APPLICATION_DATA, record_len); +} + +size_t SealRecordSuffixLen(const SSL *ssl, const size_t plaintext_len) { + assert(plaintext_len <= SSL3_RT_MAX_PLAIN_LENGTH); + size_t suffix_len; + if (!tls_seal_scatter_suffix_len(ssl, &suffix_len, SSL3_RT_APPLICATION_DATA, + plaintext_len)) { + assert(false); + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return 0; + } + assert(suffix_len <= SSL3_RT_MAX_ENCRYPTED_OVERHEAD); + return suffix_len; +} + +bool SealRecord(SSL *ssl, const Span out_prefix, + const Span out, Span out_suffix, + const Span in) { + // This API is a work in progress and currently only works for TLS 1.2 servers + // and below. + if (SSL_in_init(ssl) || + SSL_is_dtls(ssl) || + ssl_protocol_version(ssl) > TLS1_2_VERSION) { + assert(false); + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return false; + } + + if (out_prefix.size() != SealRecordPrefixLen(ssl, in.size()) || + out.size() != in.size() || + out_suffix.size() != SealRecordSuffixLen(ssl, in.size())) { + OPENSSL_PUT_ERROR(SSL, SSL_R_BUFFER_TOO_SMALL); + return false; + } + return tls_seal_scatter_record(ssl, out_prefix.data(), out.data(), + out_suffix.data(), SSL3_RT_APPLICATION_DATA, + in.data(), in.size()); +} + +} // namespace bssl + +using namespace bssl; + +size_t SSL_max_seal_overhead(const SSL *ssl) { + if (SSL_is_dtls(ssl)) { + return dtls_max_seal_overhead(ssl, dtls1_use_current_epoch); + } + + size_t ret = SSL3_RT_HEADER_LENGTH; + ret += ssl->s3->aead_write_ctx->MaxOverhead(); + // TLS 1.3 needs an extra byte for the encrypted record type. + if (!ssl->s3->aead_write_ctx->is_null_cipher() && + ssl->s3->aead_write_ctx->ProtocolVersion() >= TLS1_3_VERSION) { + ret += 1; + } + if (ssl_needs_record_splitting(ssl)) { + ret *= 2; + } + return ret; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/ssl/tls_record.cc.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/ssl/tls_record.cc.grpc_back new file mode 100644 index 0000000..05a3d56 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/ssl/tls_record.cc.grpc_back @@ -0,0 +1,703 @@ +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) + * All rights reserved. + * + * This package is an SSL implementation written + * by Eric Young (eay@cryptsoft.com). + * The implementation was written so as to conform with Netscapes SSL. + * + * This library is free for commercial and non-commercial use as long as + * the following conditions are aheared to. The following conditions + * apply to all code found in this distribution, be it the RC4, RSA, + * lhash, DES, etc., code; not just the SSL code. The SSL documentation + * included with this distribution is covered by the same copyright terms + * except that the holder is Tim Hudson (tjh@cryptsoft.com). + * + * Copyright remains Eric Young's, and as such any Copyright notices in + * the code are not to be removed. + * If this package is used in a product, Eric Young should be given attribution + * as the author of the parts of the library used. + * This can be in the form of a textual message at program startup or + * in documentation (online or textual) provided with the package. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * "This product includes cryptographic software written by + * Eric Young (eay@cryptsoft.com)" + * The word 'cryptographic' can be left out if the rouines from the library + * being used are not cryptographic related :-). + * 4. If you include any Windows specific code (or a derivative thereof) from + * the apps directory (application code) you must include an acknowledgement: + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" + * + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * The licence and distribution terms for any publically available version or + * derivative of 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 +#include + +#include +#include +#include + +#include "internal.h" +#include "../crypto/internal.h" + + +namespace bssl { + +// kMaxEmptyRecords is the number of consecutive, empty records that will be +// processed. Without this limit an attacker could send empty records at a +// faster rate than we can process and cause record processing to loop +// forever. +static const uint8_t kMaxEmptyRecords = 32; + +// kMaxEarlyDataSkipped is the maximum number of rejected early data bytes that +// will be skipped. Without this limit an attacker could send records at a +// faster rate than we can process and cause trial decryption to loop forever. +// This value should be slightly above kMaxEarlyDataAccepted, which is measured +// in plaintext. +static const size_t kMaxEarlyDataSkipped = 16384; + +// kMaxWarningAlerts is the number of consecutive warning alerts that will be +// processed. +static const uint8_t kMaxWarningAlerts = 4; + +// ssl_needs_record_splitting returns one if |ssl|'s current outgoing cipher +// state needs record-splitting and zero otherwise. +static int ssl_needs_record_splitting(const SSL *ssl) { +#if !defined(BORINGSSL_UNSAFE_FUZZER_MODE) + return !ssl->s3->aead_write_ctx->is_null_cipher() && + ssl->s3->aead_write_ctx->ProtocolVersion() < TLS1_1_VERSION && + (ssl->mode & SSL_MODE_CBC_RECORD_SPLITTING) != 0 && + SSL_CIPHER_is_block_cipher(ssl->s3->aead_write_ctx->cipher()); +#else + return 0; +#endif +} + +int ssl_record_sequence_update(uint8_t *seq, size_t seq_len) { + for (size_t i = seq_len - 1; i < seq_len; i--) { + ++seq[i]; + if (seq[i] != 0) { + return 1; + } + } + OPENSSL_PUT_ERROR(SSL, ERR_R_OVERFLOW); + return 0; +} + +size_t ssl_record_prefix_len(const SSL *ssl) { + size_t header_len; + if (SSL_is_dtls(ssl)) { + header_len = DTLS1_RT_HEADER_LENGTH; + } else { + header_len = SSL3_RT_HEADER_LENGTH; + } + + return header_len + ssl->s3->aead_read_ctx->ExplicitNonceLen(); +} + +size_t ssl_seal_align_prefix_len(const SSL *ssl) { + if (SSL_is_dtls(ssl)) { + return DTLS1_RT_HEADER_LENGTH + ssl->s3->aead_write_ctx->ExplicitNonceLen(); + } + + size_t ret = + SSL3_RT_HEADER_LENGTH + ssl->s3->aead_write_ctx->ExplicitNonceLen(); + if (ssl_needs_record_splitting(ssl)) { + ret += SSL3_RT_HEADER_LENGTH; + ret += ssl_cipher_get_record_split_len(ssl->s3->aead_write_ctx->cipher()); + } + return ret; +} + +static ssl_open_record_t skip_early_data(SSL *ssl, uint8_t *out_alert, + size_t consumed) { + ssl->s3->early_data_skipped += consumed; + if (ssl->s3->early_data_skipped < consumed) { + ssl->s3->early_data_skipped = kMaxEarlyDataSkipped + 1; + } + + if (ssl->s3->early_data_skipped > kMaxEarlyDataSkipped) { + OPENSSL_PUT_ERROR(SSL, SSL_R_TOO_MUCH_SKIPPED_EARLY_DATA); + *out_alert = SSL_AD_UNEXPECTED_MESSAGE; + return ssl_open_record_error; + } + + return ssl_open_record_discard; +} + +ssl_open_record_t tls_open_record(SSL *ssl, uint8_t *out_type, + Span *out, size_t *out_consumed, + uint8_t *out_alert, Span in) { + *out_consumed = 0; + if (ssl->s3->read_shutdown == ssl_shutdown_close_notify) { + return ssl_open_record_close_notify; + } + + // If there is an unprocessed handshake message or we are already buffering + // too much, stop before decrypting another handshake record. + if (!tls_can_accept_handshake_data(ssl, out_alert)) { + return ssl_open_record_error; + } + + CBS cbs = CBS(in); + + // Decode the record header. + uint8_t type; + uint16_t version, ciphertext_len; + if (!CBS_get_u8(&cbs, &type) || + !CBS_get_u16(&cbs, &version) || + !CBS_get_u16(&cbs, &ciphertext_len)) { + *out_consumed = SSL3_RT_HEADER_LENGTH; + return ssl_open_record_partial; + } + + bool version_ok; + if (ssl->s3->aead_read_ctx->is_null_cipher()) { + // Only check the first byte. Enforcing beyond that can prevent decoding + // version negotiation failure alerts. + version_ok = (version >> 8) == SSL3_VERSION_MAJOR; + } else { + version_ok = version == ssl->s3->aead_read_ctx->RecordVersion(); + } + + if (!version_ok) { + OPENSSL_PUT_ERROR(SSL, SSL_R_WRONG_VERSION_NUMBER); + *out_alert = SSL_AD_PROTOCOL_VERSION; + return ssl_open_record_error; + } + + // Check the ciphertext length. + if (ciphertext_len > SSL3_RT_MAX_ENCRYPTED_LENGTH) { + OPENSSL_PUT_ERROR(SSL, SSL_R_ENCRYPTED_LENGTH_TOO_LONG); + *out_alert = SSL_AD_RECORD_OVERFLOW; + return ssl_open_record_error; + } + + // Extract the body. + CBS body; + if (!CBS_get_bytes(&cbs, &body, ciphertext_len)) { + *out_consumed = SSL3_RT_HEADER_LENGTH + (size_t)ciphertext_len; + return ssl_open_record_partial; + } + + ssl_do_msg_callback(ssl, 0 /* read */, SSL3_RT_HEADER, + in.subspan(0, SSL3_RT_HEADER_LENGTH)); + + *out_consumed = in.size() - CBS_len(&cbs); + + if (ssl->s3->have_version && + ssl_protocol_version(ssl) >= TLS1_3_VERSION && + SSL_in_init(ssl) && + type == SSL3_RT_CHANGE_CIPHER_SPEC && + ciphertext_len == 1 && + CBS_data(&body)[0] == 1) { + ssl->s3->empty_record_count++; + if (ssl->s3->empty_record_count > kMaxEmptyRecords) { + OPENSSL_PUT_ERROR(SSL, SSL_R_TOO_MANY_EMPTY_FRAGMENTS); + *out_alert = SSL_AD_UNEXPECTED_MESSAGE; + return ssl_open_record_error; + } + return ssl_open_record_discard; + } + + // Skip early data received when expecting a second ClientHello if we rejected + // 0RTT. + if (ssl->s3->skip_early_data && + ssl->s3->aead_read_ctx->is_null_cipher() && + type == SSL3_RT_APPLICATION_DATA) { + return skip_early_data(ssl, out_alert, *out_consumed); + } + + // Decrypt the body in-place. + if (!ssl->s3->aead_read_ctx->Open( + out, type, version, ssl->s3->read_sequence, + MakeSpan(const_cast(CBS_data(&body)), CBS_len(&body)))) { + if (ssl->s3->skip_early_data && !ssl->s3->aead_read_ctx->is_null_cipher()) { + ERR_clear_error(); + return skip_early_data(ssl, out_alert, *out_consumed); + } + + OPENSSL_PUT_ERROR(SSL, SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC); + *out_alert = SSL_AD_BAD_RECORD_MAC; + return ssl_open_record_error; + } + + ssl->s3->skip_early_data = false; + + if (!ssl_record_sequence_update(ssl->s3->read_sequence, 8)) { + *out_alert = SSL_AD_INTERNAL_ERROR; + return ssl_open_record_error; + } + + // TLS 1.3 hides the record type inside the encrypted data. + bool has_padding = + !ssl->s3->aead_read_ctx->is_null_cipher() && + ssl->s3->aead_read_ctx->ProtocolVersion() >= TLS1_3_VERSION; + + // If there is padding, the plaintext limit includes the padding, but includes + // extra room for the inner content type. + size_t plaintext_limit = + has_padding ? SSL3_RT_MAX_PLAIN_LENGTH + 1 : SSL3_RT_MAX_PLAIN_LENGTH; + if (out->size() > plaintext_limit) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DATA_LENGTH_TOO_LONG); + *out_alert = SSL_AD_RECORD_OVERFLOW; + return ssl_open_record_error; + } + + if (has_padding) { + // The outer record type is always application_data. + if (type != SSL3_RT_APPLICATION_DATA) { + OPENSSL_PUT_ERROR(SSL, SSL_R_INVALID_OUTER_RECORD_TYPE); + *out_alert = SSL_AD_DECODE_ERROR; + return ssl_open_record_error; + } + + do { + if (out->empty()) { + OPENSSL_PUT_ERROR(SSL, SSL_R_DECRYPTION_FAILED_OR_BAD_RECORD_MAC); + *out_alert = SSL_AD_DECRYPT_ERROR; + return ssl_open_record_error; + } + type = out->back(); + *out = out->subspan(0, out->size() - 1); + } while (type == 0); + } + + // Limit the number of consecutive empty records. + if (out->empty()) { + ssl->s3->empty_record_count++; + if (ssl->s3->empty_record_count > kMaxEmptyRecords) { + OPENSSL_PUT_ERROR(SSL, SSL_R_TOO_MANY_EMPTY_FRAGMENTS); + *out_alert = SSL_AD_UNEXPECTED_MESSAGE; + return ssl_open_record_error; + } + // Apart from the limit, empty records are returned up to the caller. This + // allows the caller to reject records of the wrong type. + } else { + ssl->s3->empty_record_count = 0; + } + + if (type == SSL3_RT_ALERT) { + return ssl_process_alert(ssl, out_alert, *out); + } + + // Handshake messages may not interleave with any other record type. + if (type != SSL3_RT_HANDSHAKE && + tls_has_unprocessed_handshake_data(ssl)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_UNEXPECTED_RECORD); + *out_alert = SSL_AD_UNEXPECTED_MESSAGE; + return ssl_open_record_error; + } + + ssl->s3->warning_alert_count = 0; + + *out_type = type; + return ssl_open_record_success; +} + +static int do_seal_record(SSL *ssl, uint8_t *out_prefix, uint8_t *out, + uint8_t *out_suffix, uint8_t type, const uint8_t *in, + const size_t in_len) { + uint8_t *extra_in = NULL; + size_t extra_in_len = 0; + if (!ssl->s3->aead_write_ctx->is_null_cipher() && + ssl->s3->aead_write_ctx->ProtocolVersion() >= TLS1_3_VERSION) { + // TLS 1.3 hides the actual record type inside the encrypted data. + extra_in = &type; + extra_in_len = 1; + } + + size_t suffix_len; + if (!ssl->s3->aead_write_ctx->SuffixLen(&suffix_len, in_len, extra_in_len)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_RECORD_TOO_LARGE); + return 0; + } + size_t ciphertext_len = + ssl->s3->aead_write_ctx->ExplicitNonceLen() + suffix_len; + if (ciphertext_len + in_len < ciphertext_len) { + OPENSSL_PUT_ERROR(SSL, SSL_R_RECORD_TOO_LARGE); + return 0; + } + ciphertext_len += in_len; + + assert(in == out || !buffers_alias(in, in_len, out, in_len)); + assert(!buffers_alias(in, in_len, out_prefix, ssl_record_prefix_len(ssl))); + assert(!buffers_alias(in, in_len, out_suffix, suffix_len)); + + if (extra_in_len) { + out_prefix[0] = SSL3_RT_APPLICATION_DATA; + } else { + out_prefix[0] = type; + } + + uint16_t record_version = ssl->s3->aead_write_ctx->RecordVersion(); + + out_prefix[1] = record_version >> 8; + out_prefix[2] = record_version & 0xff; + out_prefix[3] = ciphertext_len >> 8; + out_prefix[4] = ciphertext_len & 0xff; + + if (!ssl->s3->aead_write_ctx->SealScatter( + out_prefix + SSL3_RT_HEADER_LENGTH, out, out_suffix, type, + record_version, ssl->s3->write_sequence, in, in_len, extra_in, + extra_in_len) || + !ssl_record_sequence_update(ssl->s3->write_sequence, 8)) { + return 0; + } + + ssl_do_msg_callback(ssl, 1 /* write */, SSL3_RT_HEADER, + MakeSpan(out_prefix, SSL3_RT_HEADER_LENGTH)); + return 1; +} + +static size_t tls_seal_scatter_prefix_len(const SSL *ssl, uint8_t type, + size_t in_len) { + size_t ret = SSL3_RT_HEADER_LENGTH; + if (type == SSL3_RT_APPLICATION_DATA && in_len > 1 && + ssl_needs_record_splitting(ssl)) { + // In the case of record splitting, the 1-byte record (of the 1/n-1 split) + // will be placed in the prefix, as will four of the five bytes of the + // record header for the main record. The final byte will replace the first + // byte of the plaintext that was used in the small record. + ret += ssl_cipher_get_record_split_len(ssl->s3->aead_write_ctx->cipher()); + ret += SSL3_RT_HEADER_LENGTH - 1; + } else { + ret += ssl->s3->aead_write_ctx->ExplicitNonceLen(); + } + return ret; +} + +static bool tls_seal_scatter_suffix_len(const SSL *ssl, size_t *out_suffix_len, + uint8_t type, size_t in_len) { + size_t extra_in_len = 0; + if (!ssl->s3->aead_write_ctx->is_null_cipher() && + ssl->s3->aead_write_ctx->ProtocolVersion() >= TLS1_3_VERSION) { + // TLS 1.3 adds an extra byte for encrypted record type. + extra_in_len = 1; + } + if (type == SSL3_RT_APPLICATION_DATA && // clang-format off + in_len > 1 && + ssl_needs_record_splitting(ssl)) { + // With record splitting enabled, the first byte gets sealed into a separate + // record which is written into the prefix. + in_len -= 1; + } + return ssl->s3->aead_write_ctx->SuffixLen(out_suffix_len, in_len, extra_in_len); +} + +// tls_seal_scatter_record seals a new record of type |type| and body |in| and +// splits it between |out_prefix|, |out|, and |out_suffix|. Exactly +// |tls_seal_scatter_prefix_len| bytes are written to |out_prefix|, |in_len| +// bytes to |out|, and |tls_seal_scatter_suffix_len| bytes to |out_suffix|. It +// returns one on success and zero on error. If enabled, +// |tls_seal_scatter_record| implements TLS 1.0 CBC 1/n-1 record splitting and +// may write two records concatenated. +static int tls_seal_scatter_record(SSL *ssl, uint8_t *out_prefix, uint8_t *out, + uint8_t *out_suffix, uint8_t type, + const uint8_t *in, size_t in_len) { + if (type == SSL3_RT_APPLICATION_DATA && in_len > 1 && + ssl_needs_record_splitting(ssl)) { + assert(ssl->s3->aead_write_ctx->ExplicitNonceLen() == 0); + const size_t prefix_len = SSL3_RT_HEADER_LENGTH; + + // Write the 1-byte fragment into |out_prefix|. + uint8_t *split_body = out_prefix + prefix_len; + uint8_t *split_suffix = split_body + 1; + + if (!do_seal_record(ssl, out_prefix, split_body, split_suffix, type, in, + 1)) { + return 0; + } + + size_t split_record_suffix_len; + if (!ssl->s3->aead_write_ctx->SuffixLen(&split_record_suffix_len, 1, 0)) { + assert(false); + return 0; + } + const size_t split_record_len = prefix_len + 1 + split_record_suffix_len; + assert(SSL3_RT_HEADER_LENGTH + ssl_cipher_get_record_split_len( + ssl->s3->aead_write_ctx->cipher()) == + split_record_len); + + // Write the n-1-byte fragment. The header gets split between |out_prefix| + // (header[:-1]) and |out| (header[-1:]). + uint8_t tmp_prefix[SSL3_RT_HEADER_LENGTH]; + if (!do_seal_record(ssl, tmp_prefix, out + 1, out_suffix, type, in + 1, + in_len - 1)) { + return 0; + } + assert(tls_seal_scatter_prefix_len(ssl, type, in_len) == + split_record_len + SSL3_RT_HEADER_LENGTH - 1); + OPENSSL_memcpy(out_prefix + split_record_len, tmp_prefix, + SSL3_RT_HEADER_LENGTH - 1); + OPENSSL_memcpy(out, tmp_prefix + SSL3_RT_HEADER_LENGTH - 1, 1); + return 1; + } + + return do_seal_record(ssl, out_prefix, out, out_suffix, type, in, in_len); +} + +int tls_seal_record(SSL *ssl, uint8_t *out, size_t *out_len, size_t max_out_len, + uint8_t type, const uint8_t *in, size_t in_len) { + if (buffers_alias(in, in_len, out, max_out_len)) { + OPENSSL_PUT_ERROR(SSL, SSL_R_OUTPUT_ALIASES_INPUT); + return 0; + } + + const size_t prefix_len = tls_seal_scatter_prefix_len(ssl, type, in_len); + size_t suffix_len; + if (!tls_seal_scatter_suffix_len(ssl, &suffix_len, type, in_len)) { + return false; + } + if (in_len + prefix_len < in_len || + prefix_len + in_len + suffix_len < prefix_len + in_len) { + OPENSSL_PUT_ERROR(SSL, SSL_R_RECORD_TOO_LARGE); + return 0; + } + if (max_out_len < in_len + prefix_len + suffix_len) { + OPENSSL_PUT_ERROR(SSL, SSL_R_BUFFER_TOO_SMALL); + return 0; + } + + uint8_t *prefix = out; + uint8_t *body = out + prefix_len; + uint8_t *suffix = body + in_len; + if (!tls_seal_scatter_record(ssl, prefix, body, suffix, type, in, in_len)) { + return 0; + } + + *out_len = prefix_len + in_len + suffix_len; + return 1; +} + +enum ssl_open_record_t ssl_process_alert(SSL *ssl, uint8_t *out_alert, + Span in) { + // Alerts records may not contain fragmented or multiple alerts. + if (in.size() != 2) { + *out_alert = SSL_AD_DECODE_ERROR; + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_ALERT); + return ssl_open_record_error; + } + + ssl_do_msg_callback(ssl, 0 /* read */, SSL3_RT_ALERT, in); + + const uint8_t alert_level = in[0]; + const uint8_t alert_descr = in[1]; + + uint16_t alert = (alert_level << 8) | alert_descr; + ssl_do_info_callback(ssl, SSL_CB_READ_ALERT, alert); + + if (alert_level == SSL3_AL_WARNING) { + if (alert_descr == SSL_AD_CLOSE_NOTIFY) { + ssl->s3->read_shutdown = ssl_shutdown_close_notify; + return ssl_open_record_close_notify; + } + + // Warning alerts do not exist in TLS 1.3. + if (ssl->s3->have_version && + ssl_protocol_version(ssl) >= TLS1_3_VERSION) { + *out_alert = SSL_AD_DECODE_ERROR; + OPENSSL_PUT_ERROR(SSL, SSL_R_BAD_ALERT); + return ssl_open_record_error; + } + + ssl->s3->warning_alert_count++; + if (ssl->s3->warning_alert_count > kMaxWarningAlerts) { + *out_alert = SSL_AD_UNEXPECTED_MESSAGE; + OPENSSL_PUT_ERROR(SSL, SSL_R_TOO_MANY_WARNING_ALERTS); + return ssl_open_record_error; + } + return ssl_open_record_discard; + } + + if (alert_level == SSL3_AL_FATAL) { + OPENSSL_PUT_ERROR(SSL, SSL_AD_REASON_OFFSET + alert_descr); + ERR_add_error_dataf("SSL alert number %d", alert_descr); + *out_alert = 0; // No alert to send back to the peer. + return ssl_open_record_error; + } + + *out_alert = SSL_AD_ILLEGAL_PARAMETER; + OPENSSL_PUT_ERROR(SSL, SSL_R_UNKNOWN_ALERT_TYPE); + return ssl_open_record_error; +} + +OpenRecordResult OpenRecord(SSL *ssl, Span *out, + size_t *out_record_len, uint8_t *out_alert, + const Span in) { + // This API is a work in progress and currently only works for TLS 1.2 servers + // and below. + if (SSL_in_init(ssl) || + SSL_is_dtls(ssl) || + ssl_protocol_version(ssl) > TLS1_2_VERSION) { + assert(false); + *out_alert = SSL_AD_INTERNAL_ERROR; + return OpenRecordResult::kError; + } + + Span plaintext; + uint8_t type = 0; + const ssl_open_record_t result = tls_open_record( + ssl, &type, &plaintext, out_record_len, out_alert, in); + + switch (result) { + case ssl_open_record_success: + if (type != SSL3_RT_APPLICATION_DATA && type != SSL3_RT_ALERT) { + *out_alert = SSL_AD_UNEXPECTED_MESSAGE; + return OpenRecordResult::kError; + } + *out = plaintext; + return OpenRecordResult::kOK; + case ssl_open_record_discard: + return OpenRecordResult::kDiscard; + case ssl_open_record_partial: + return OpenRecordResult::kIncompleteRecord; + case ssl_open_record_close_notify: + return OpenRecordResult::kAlertCloseNotify; + case ssl_open_record_error: + return OpenRecordResult::kError; + } + assert(false); + return OpenRecordResult::kError; +} + +size_t SealRecordPrefixLen(const SSL *ssl, const size_t record_len) { + return tls_seal_scatter_prefix_len(ssl, SSL3_RT_APPLICATION_DATA, record_len); +} + +size_t SealRecordSuffixLen(const SSL *ssl, const size_t plaintext_len) { + assert(plaintext_len <= SSL3_RT_MAX_PLAIN_LENGTH); + size_t suffix_len; + if (!tls_seal_scatter_suffix_len(ssl, &suffix_len, SSL3_RT_APPLICATION_DATA, + plaintext_len)) { + assert(false); + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return 0; + } + assert(suffix_len <= SSL3_RT_MAX_ENCRYPTED_OVERHEAD); + return suffix_len; +} + +bool SealRecord(SSL *ssl, const Span out_prefix, + const Span out, Span out_suffix, + const Span in) { + // This API is a work in progress and currently only works for TLS 1.2 servers + // and below. + if (SSL_in_init(ssl) || + SSL_is_dtls(ssl) || + ssl_protocol_version(ssl) > TLS1_2_VERSION) { + assert(false); + OPENSSL_PUT_ERROR(SSL, ERR_R_INTERNAL_ERROR); + return false; + } + + if (out_prefix.size() != SealRecordPrefixLen(ssl, in.size()) || + out.size() != in.size() || + out_suffix.size() != SealRecordSuffixLen(ssl, in.size())) { + OPENSSL_PUT_ERROR(SSL, SSL_R_BUFFER_TOO_SMALL); + return false; + } + return tls_seal_scatter_record(ssl, out_prefix.data(), out.data(), + out_suffix.data(), SSL3_RT_APPLICATION_DATA, + in.data(), in.size()); +} + +} // namespace bssl + +using namespace bssl; + +size_t SSL_max_seal_overhead(const SSL *ssl) { + if (SSL_is_dtls(ssl)) { + return dtls_max_seal_overhead(ssl, dtls1_use_current_epoch); + } + + size_t ret = SSL3_RT_HEADER_LENGTH; + ret += ssl->s3->aead_write_ctx->MaxOverhead(); + // TLS 1.3 needs an extra byte for the encrypted record type. + if (!ssl->s3->aead_write_ctx->is_null_cipher() && + ssl->s3->aead_write_ctx->ProtocolVersion() >= TLS1_3_VERSION) { + ret += 1; + } + if (ssl_needs_record_splitting(ssl)) { + ret *= 2; + } + return ret; +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/third_party/fiat/curve25519.c b/FoodApp/Pods/BoringSSL-GRPC/third_party/fiat/curve25519.c new file mode 100644 index 0000000..bf7819b --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/third_party/fiat/curve25519.c @@ -0,0 +1,3230 @@ +// The MIT License (MIT) +// +// Copyright (c) 2015-2016 the fiat-crypto authors (see the AUTHORS file). +// +// 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. + +// Some of this code is taken from the ref10 version of Ed25519 in SUPERCOP +// 20141124 (http://bench.cr.yp.to/supercop.html). That code is released as +// public domain but parts have been replaced with code generated by Fiat +// (https://github.com/mit-plv/fiat-crypto), which is MIT licensed. +// +// The field functions are shared by Ed25519 and X25519 where possible. + +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include "internal.h" +#include "../../crypto/internal.h" + + +// Various pre-computed constants. +#include "./curve25519_tables.h" + + +// Low-level intrinsic operations (hand-written). + +static uint64_t load_3(const uint8_t *in) { + uint64_t result; + result = (uint64_t)in[0]; + result |= ((uint64_t)in[1]) << 8; + result |= ((uint64_t)in[2]) << 16; + return result; +} + +static uint64_t load_4(const uint8_t *in) { + uint64_t result; + result = (uint64_t)in[0]; + result |= ((uint64_t)in[1]) << 8; + result |= ((uint64_t)in[2]) << 16; + result |= ((uint64_t)in[3]) << 24; + return result; +} + +#if defined(BORINGSSL_CURVE25519_64BIT) +static uint64_t load_8(const uint8_t *in) { + uint64_t result; + result = (uint64_t)in[0]; + result |= ((uint64_t)in[1]) << 8; + result |= ((uint64_t)in[2]) << 16; + result |= ((uint64_t)in[3]) << 24; + result |= ((uint64_t)in[4]) << 32; + result |= ((uint64_t)in[5]) << 40; + result |= ((uint64_t)in[6]) << 48; + result |= ((uint64_t)in[7]) << 56; + return result; +} + +static uint8_t /*bool*/ addcarryx_u51(uint8_t /*bool*/ c, uint64_t a, + uint64_t b, uint64_t *low) { + // This function extracts 51 bits of result and 1 bit of carry (52 total), so + // a 64-bit intermediate is sufficient. + uint64_t x = a + b + c; + *low = x & ((UINT64_C(1) << 51) - 1); + return (x >> 51) & 1; +} + +static uint8_t /*bool*/ subborrow_u51(uint8_t /*bool*/ c, uint64_t a, + uint64_t b, uint64_t *low) { + // This function extracts 51 bits of result and 1 bit of borrow (52 total), so + // a 64-bit intermediate is sufficient. + uint64_t x = a - b - c; + *low = x & ((UINT64_C(1) << 51) - 1); + return x >> 63; +} + +static uint64_t cmovznz64(uint64_t t, uint64_t z, uint64_t nz) { + t = -!!t; // all set if nonzero, 0 if 0 + return (t&nz) | ((~t)&z); +} + +#else + +static uint8_t /*bool*/ addcarryx_u25(uint8_t /*bool*/ c, uint32_t a, + uint32_t b, uint32_t *low) { + // This function extracts 25 bits of result and 1 bit of carry (26 total), so + // a 32-bit intermediate is sufficient. + uint32_t x = a + b + c; + *low = x & ((1 << 25) - 1); + return (x >> 25) & 1; +} + +static uint8_t /*bool*/ addcarryx_u26(uint8_t /*bool*/ c, uint32_t a, + uint32_t b, uint32_t *low) { + // This function extracts 26 bits of result and 1 bit of carry (27 total), so + // a 32-bit intermediate is sufficient. + uint32_t x = a + b + c; + *low = x & ((1 << 26) - 1); + return (x >> 26) & 1; +} + +static uint8_t /*bool*/ subborrow_u25(uint8_t /*bool*/ c, uint32_t a, + uint32_t b, uint32_t *low) { + // This function extracts 25 bits of result and 1 bit of borrow (26 total), so + // a 32-bit intermediate is sufficient. + uint32_t x = a - b - c; + *low = x & ((1 << 25) - 1); + return x >> 31; +} + +static uint8_t /*bool*/ subborrow_u26(uint8_t /*bool*/ c, uint32_t a, + uint32_t b, uint32_t *low) { + // This function extracts 26 bits of result and 1 bit of borrow (27 total), so + // a 32-bit intermediate is sufficient. + uint32_t x = a - b - c; + *low = x & ((1 << 26) - 1); + return x >> 31; +} + +static uint32_t cmovznz32(uint32_t t, uint32_t z, uint32_t nz) { + t = -!!t; // all set if nonzero, 0 if 0 + return (t&nz) | ((~t)&z); +} + +#endif + + +// Field operations. + +#if defined(BORINGSSL_CURVE25519_64BIT) + +#define assert_fe(f) do { \ + for (unsigned _assert_fe_i = 0; _assert_fe_i< 5; _assert_fe_i++) { \ + assert(f[_assert_fe_i] < 1.125*(UINT64_C(1)<<51)); \ + } \ +} while (0) + +#define assert_fe_loose(f) do { \ + for (unsigned _assert_fe_i = 0; _assert_fe_i< 5; _assert_fe_i++) { \ + assert(f[_assert_fe_i] < 3.375*(UINT64_C(1)<<51)); \ + } \ +} while (0) + +#define assert_fe_frozen(f) do { \ + for (unsigned _assert_fe_i = 0; _assert_fe_i< 5; _assert_fe_i++) { \ + assert(f[_assert_fe_i] < (UINT64_C(1)<<51)); \ + } \ +} while (0) + +static void fe_frombytes_impl(uint64_t h[5], const uint8_t *s) { + // Ignores top bit of s. + uint64_t a0 = load_8(s); + uint64_t a1 = load_8(s+8); + uint64_t a2 = load_8(s+16); + uint64_t a3 = load_8(s+24); + // Use 51 bits, 64-51 = 13 left. + h[0] = a0 & ((UINT64_C(1) << 51) - 1); + // (64-51) + 38 = 13 + 38 = 51 + h[1] = (a0 >> 51) | ((a1 & ((UINT64_C(1) << 38) - 1)) << 13); + // (64-38) + 25 = 26 + 25 = 51 + h[2] = (a1 >> 38) | ((a2 & ((UINT64_C(1) << 25) - 1)) << 26); + // (64-25) + 12 = 39 + 12 = 51 + h[3] = (a2 >> 25) | ((a3 & ((UINT64_C(1) << 12) - 1)) << 39); + // (64-12) = 52, ignore top bit + h[4] = (a3 >> 12) & ((UINT64_C(1) << 51) - 1); + assert_fe(h); +} + +static void fe_frombytes(fe *h, const uint8_t *s) { + fe_frombytes_impl(h->v, s); +} + +static void fe_freeze(uint64_t out[5], const uint64_t in1[5]) { + { const uint64_t x7 = in1[4]; + { const uint64_t x8 = in1[3]; + { const uint64_t x6 = in1[2]; + { const uint64_t x4 = in1[1]; + { const uint64_t x2 = in1[0]; + { uint64_t x10; uint8_t/*bool*/ x11 = subborrow_u51(0x0, x2, 0x7ffffffffffed, &x10); + { uint64_t x13; uint8_t/*bool*/ x14 = subborrow_u51(x11, x4, 0x7ffffffffffff, &x13); + { uint64_t x16; uint8_t/*bool*/ x17 = subborrow_u51(x14, x6, 0x7ffffffffffff, &x16); + { uint64_t x19; uint8_t/*bool*/ x20 = subborrow_u51(x17, x8, 0x7ffffffffffff, &x19); + { uint64_t x22; uint8_t/*bool*/ x23 = subborrow_u51(x20, x7, 0x7ffffffffffff, &x22); + { uint64_t x24 = cmovznz64(x23, 0x0, 0xffffffffffffffffL); + { uint64_t x25 = (x24 & 0x7ffffffffffed); + { uint64_t x27; uint8_t/*bool*/ x28 = addcarryx_u51(0x0, x10, x25, &x27); + { uint64_t x29 = (x24 & 0x7ffffffffffff); + { uint64_t x31; uint8_t/*bool*/ x32 = addcarryx_u51(x28, x13, x29, &x31); + { uint64_t x33 = (x24 & 0x7ffffffffffff); + { uint64_t x35; uint8_t/*bool*/ x36 = addcarryx_u51(x32, x16, x33, &x35); + { uint64_t x37 = (x24 & 0x7ffffffffffff); + { uint64_t x39; uint8_t/*bool*/ x40 = addcarryx_u51(x36, x19, x37, &x39); + { uint64_t x41 = (x24 & 0x7ffffffffffff); + { uint64_t x43; addcarryx_u51(x40, x22, x41, &x43); + out[0] = x27; + out[1] = x31; + out[2] = x35; + out[3] = x39; + out[4] = x43; + }}}}}}}}}}}}}}}}}}}}} +} + +static void fe_tobytes(uint8_t s[32], const fe *f) { + assert_fe(f->v); + uint64_t h[5]; + fe_freeze(h, f->v); + assert_fe_frozen(h); + + s[0] = h[0] >> 0; + s[1] = h[0] >> 8; + s[2] = h[0] >> 16; + s[3] = h[0] >> 24; + s[4] = h[0] >> 32; + s[5] = h[0] >> 40; + s[6] = (h[0] >> 48) | (h[1] << 3); + s[7] = h[1] >> 5; + s[8] = h[1] >> 13; + s[9] = h[1] >> 21; + s[10] = h[1] >> 29; + s[11] = h[1] >> 37; + s[12] = (h[1] >> 45) | (h[2] << 6); + s[13] = h[2] >> 2; + s[14] = h[2] >> 10; + s[15] = h[2] >> 18; + s[16] = h[2] >> 26; + s[17] = h[2] >> 34; + s[18] = h[2] >> 42; + s[19] = (h[2] >> 50) | (h[3] << 1); + s[20] = h[3] >> 7; + s[21] = h[3] >> 15; + s[22] = h[3] >> 23; + s[23] = h[3] >> 31; + s[24] = h[3] >> 39; + s[25] = (h[3] >> 47) | (h[4] << 4); + s[26] = h[4] >> 4; + s[27] = h[4] >> 12; + s[28] = h[4] >> 20; + s[29] = h[4] >> 28; + s[30] = h[4] >> 36; + s[31] = h[4] >> 44; +} + +// h = 0 +static void fe_0(fe *h) { + OPENSSL_memset(h, 0, sizeof(fe)); +} + +static void fe_loose_0(fe_loose *h) { + OPENSSL_memset(h, 0, sizeof(fe_loose)); +} + +// h = 1 +static void fe_1(fe *h) { + OPENSSL_memset(h, 0, sizeof(fe)); + h->v[0] = 1; +} + +static void fe_loose_1(fe_loose *h) { + OPENSSL_memset(h, 0, sizeof(fe_loose)); + h->v[0] = 1; +} + +static void fe_add_impl(uint64_t out[5], const uint64_t in1[5], const uint64_t in2[5]) { + { const uint64_t x10 = in1[4]; + { const uint64_t x11 = in1[3]; + { const uint64_t x9 = in1[2]; + { const uint64_t x7 = in1[1]; + { const uint64_t x5 = in1[0]; + { const uint64_t x18 = in2[4]; + { const uint64_t x19 = in2[3]; + { const uint64_t x17 = in2[2]; + { const uint64_t x15 = in2[1]; + { const uint64_t x13 = in2[0]; + out[0] = (x5 + x13); + out[1] = (x7 + x15); + out[2] = (x9 + x17); + out[3] = (x11 + x19); + out[4] = (x10 + x18); + }}}}}}}}}} +} + +// h = f + g +// Can overlap h with f or g. +static void fe_add(fe_loose *h, const fe *f, const fe *g) { + assert_fe(f->v); + assert_fe(g->v); + fe_add_impl(h->v, f->v, g->v); + assert_fe_loose(h->v); +} + +static void fe_sub_impl(uint64_t out[5], const uint64_t in1[5], const uint64_t in2[5]) { + { const uint64_t x10 = in1[4]; + { const uint64_t x11 = in1[3]; + { const uint64_t x9 = in1[2]; + { const uint64_t x7 = in1[1]; + { const uint64_t x5 = in1[0]; + { const uint64_t x18 = in2[4]; + { const uint64_t x19 = in2[3]; + { const uint64_t x17 = in2[2]; + { const uint64_t x15 = in2[1]; + { const uint64_t x13 = in2[0]; + out[0] = ((0xfffffffffffda + x5) - x13); + out[1] = ((0xffffffffffffe + x7) - x15); + out[2] = ((0xffffffffffffe + x9) - x17); + out[3] = ((0xffffffffffffe + x11) - x19); + out[4] = ((0xffffffffffffe + x10) - x18); + }}}}}}}}}} +} + +// h = f - g +// Can overlap h with f or g. +static void fe_sub(fe_loose *h, const fe *f, const fe *g) { + assert_fe(f->v); + assert_fe(g->v); + fe_sub_impl(h->v, f->v, g->v); + assert_fe_loose(h->v); +} + +static void fe_carry_impl(uint64_t out[5], const uint64_t in1[5]) { + { const uint64_t x7 = in1[4]; + { const uint64_t x8 = in1[3]; + { const uint64_t x6 = in1[2]; + { const uint64_t x4 = in1[1]; + { const uint64_t x2 = in1[0]; + { uint64_t x9 = (x2 >> 0x33); + { uint64_t x10 = (x2 & 0x7ffffffffffff); + { uint64_t x11 = (x9 + x4); + { uint64_t x12 = (x11 >> 0x33); + { uint64_t x13 = (x11 & 0x7ffffffffffff); + { uint64_t x14 = (x12 + x6); + { uint64_t x15 = (x14 >> 0x33); + { uint64_t x16 = (x14 & 0x7ffffffffffff); + { uint64_t x17 = (x15 + x8); + { uint64_t x18 = (x17 >> 0x33); + { uint64_t x19 = (x17 & 0x7ffffffffffff); + { uint64_t x20 = (x18 + x7); + { uint64_t x21 = (x20 >> 0x33); + { uint64_t x22 = (x20 & 0x7ffffffffffff); + { uint64_t x23 = (x10 + (0x13 * x21)); + { uint64_t x24 = (x23 >> 0x33); + { uint64_t x25 = (x23 & 0x7ffffffffffff); + { uint64_t x26 = (x24 + x13); + { uint64_t x27 = (x26 >> 0x33); + { uint64_t x28 = (x26 & 0x7ffffffffffff); + out[0] = x25; + out[1] = x28; + out[2] = (x27 + x16); + out[3] = x19; + out[4] = x22; + }}}}}}}}}}}}}}}}}}}}}}}}} +} + +static void fe_carry(fe *h, const fe_loose* f) { + assert_fe_loose(f->v); + fe_carry_impl(h->v, f->v); + assert_fe(h->v); +} + +static void fe_mul_impl(uint64_t out[5], const uint64_t in1[5], const uint64_t in2[5]) { + assert_fe_loose(in1); + assert_fe_loose(in2); + { const uint64_t x10 = in1[4]; + { const uint64_t x11 = in1[3]; + { const uint64_t x9 = in1[2]; + { const uint64_t x7 = in1[1]; + { const uint64_t x5 = in1[0]; + { const uint64_t x18 = in2[4]; + { const uint64_t x19 = in2[3]; + { const uint64_t x17 = in2[2]; + { const uint64_t x15 = in2[1]; + { const uint64_t x13 = in2[0]; + { uint128_t x20 = ((uint128_t)x5 * x13); + { uint128_t x21 = (((uint128_t)x5 * x15) + ((uint128_t)x7 * x13)); + { uint128_t x22 = ((((uint128_t)x5 * x17) + ((uint128_t)x9 * x13)) + ((uint128_t)x7 * x15)); + { uint128_t x23 = (((((uint128_t)x5 * x19) + ((uint128_t)x11 * x13)) + ((uint128_t)x7 * x17)) + ((uint128_t)x9 * x15)); + { uint128_t x24 = ((((((uint128_t)x5 * x18) + ((uint128_t)x10 * x13)) + ((uint128_t)x11 * x15)) + ((uint128_t)x7 * x19)) + ((uint128_t)x9 * x17)); + { uint64_t x25 = (x10 * 0x13); + { uint64_t x26 = (x7 * 0x13); + { uint64_t x27 = (x9 * 0x13); + { uint64_t x28 = (x11 * 0x13); + { uint128_t x29 = ((((x20 + ((uint128_t)x25 * x15)) + ((uint128_t)x26 * x18)) + ((uint128_t)x27 * x19)) + ((uint128_t)x28 * x17)); + { uint128_t x30 = (((x21 + ((uint128_t)x25 * x17)) + ((uint128_t)x27 * x18)) + ((uint128_t)x28 * x19)); + { uint128_t x31 = ((x22 + ((uint128_t)x25 * x19)) + ((uint128_t)x28 * x18)); + { uint128_t x32 = (x23 + ((uint128_t)x25 * x18)); + { uint64_t x33 = (uint64_t) (x29 >> 0x33); + { uint64_t x34 = ((uint64_t)x29 & 0x7ffffffffffff); + { uint128_t x35 = (x33 + x30); + { uint64_t x36 = (uint64_t) (x35 >> 0x33); + { uint64_t x37 = ((uint64_t)x35 & 0x7ffffffffffff); + { uint128_t x38 = (x36 + x31); + { uint64_t x39 = (uint64_t) (x38 >> 0x33); + { uint64_t x40 = ((uint64_t)x38 & 0x7ffffffffffff); + { uint128_t x41 = (x39 + x32); + { uint64_t x42 = (uint64_t) (x41 >> 0x33); + { uint64_t x43 = ((uint64_t)x41 & 0x7ffffffffffff); + { uint128_t x44 = (x42 + x24); + { uint64_t x45 = (uint64_t) (x44 >> 0x33); + { uint64_t x46 = ((uint64_t)x44 & 0x7ffffffffffff); + { uint64_t x47 = (x34 + (0x13 * x45)); + { uint64_t x48 = (x47 >> 0x33); + { uint64_t x49 = (x47 & 0x7ffffffffffff); + { uint64_t x50 = (x48 + x37); + { uint64_t x51 = (x50 >> 0x33); + { uint64_t x52 = (x50 & 0x7ffffffffffff); + out[0] = x49; + out[1] = x52; + out[2] = (x51 + x40); + out[3] = x43; + out[4] = x46; + }}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} + assert_fe(out); +} + +static void fe_mul_ltt(fe_loose *h, const fe *f, const fe *g) { + fe_mul_impl(h->v, f->v, g->v); +} + +static void fe_mul_llt(fe_loose *h, const fe_loose *f, const fe *g) { + fe_mul_impl(h->v, f->v, g->v); +} + +static void fe_mul_ttt(fe *h, const fe *f, const fe *g) { + fe_mul_impl(h->v, f->v, g->v); +} + +static void fe_mul_tlt(fe *h, const fe_loose *f, const fe *g) { + fe_mul_impl(h->v, f->v, g->v); +} + +static void fe_mul_ttl(fe *h, const fe *f, const fe_loose *g) { + fe_mul_impl(h->v, f->v, g->v); +} + +static void fe_mul_tll(fe *h, const fe_loose *f, const fe_loose *g) { + fe_mul_impl(h->v, f->v, g->v); +} + +static void fe_sqr_impl(uint64_t out[5], const uint64_t in1[5]) { + assert_fe_loose(in1); + { const uint64_t x7 = in1[4]; + { const uint64_t x8 = in1[3]; + { const uint64_t x6 = in1[2]; + { const uint64_t x4 = in1[1]; + { const uint64_t x2 = in1[0]; + { uint64_t x9 = (x2 * 0x2); + { uint64_t x10 = (x4 * 0x2); + { uint64_t x11 = ((x6 * 0x2) * 0x13); + { uint64_t x12 = (x7 * 0x13); + { uint64_t x13 = (x12 * 0x2); + { uint128_t x14 = ((((uint128_t)x2 * x2) + ((uint128_t)x13 * x4)) + ((uint128_t)x11 * x8)); + { uint128_t x15 = ((((uint128_t)x9 * x4) + ((uint128_t)x13 * x6)) + ((uint128_t)x8 * (x8 * 0x13))); + { uint128_t x16 = ((((uint128_t)x9 * x6) + ((uint128_t)x4 * x4)) + ((uint128_t)x13 * x8)); + { uint128_t x17 = ((((uint128_t)x9 * x8) + ((uint128_t)x10 * x6)) + ((uint128_t)x7 * x12)); + { uint128_t x18 = ((((uint128_t)x9 * x7) + ((uint128_t)x10 * x8)) + ((uint128_t)x6 * x6)); + { uint64_t x19 = (uint64_t) (x14 >> 0x33); + { uint64_t x20 = ((uint64_t)x14 & 0x7ffffffffffff); + { uint128_t x21 = (x19 + x15); + { uint64_t x22 = (uint64_t) (x21 >> 0x33); + { uint64_t x23 = ((uint64_t)x21 & 0x7ffffffffffff); + { uint128_t x24 = (x22 + x16); + { uint64_t x25 = (uint64_t) (x24 >> 0x33); + { uint64_t x26 = ((uint64_t)x24 & 0x7ffffffffffff); + { uint128_t x27 = (x25 + x17); + { uint64_t x28 = (uint64_t) (x27 >> 0x33); + { uint64_t x29 = ((uint64_t)x27 & 0x7ffffffffffff); + { uint128_t x30 = (x28 + x18); + { uint64_t x31 = (uint64_t) (x30 >> 0x33); + { uint64_t x32 = ((uint64_t)x30 & 0x7ffffffffffff); + { uint64_t x33 = (x20 + (0x13 * x31)); + { uint64_t x34 = (x33 >> 0x33); + { uint64_t x35 = (x33 & 0x7ffffffffffff); + { uint64_t x36 = (x34 + x23); + { uint64_t x37 = (x36 >> 0x33); + { uint64_t x38 = (x36 & 0x7ffffffffffff); + out[0] = x35; + out[1] = x38; + out[2] = (x37 + x26); + out[3] = x29; + out[4] = x32; + }}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} + assert_fe(out); +} + +static void fe_sq_tl(fe *h, const fe_loose *f) { + fe_sqr_impl(h->v, f->v); +} + +static void fe_sq_tt(fe *h, const fe *f) { + fe_sqr_impl(h->v, f->v); +} + +// Replace (f,g) with (g,f) if b == 1; +// replace (f,g) with (f,g) if b == 0. +// +// Preconditions: b in {0,1}. +static void fe_cswap(fe *f, fe *g, uint64_t b) { + b = 0-b; + for (unsigned i = 0; i < 5; i++) { + uint64_t x = f->v[i] ^ g->v[i]; + x &= b; + f->v[i] ^= x; + g->v[i] ^= x; + } +} + +// NOTE: based on fiat-crypto fe_mul, edited for in2=121666, 0, 0.. +static void fe_mul_121666_impl(uint64_t out[5], const uint64_t in1[5]) { + { const uint64_t x10 = in1[4]; + { const uint64_t x11 = in1[3]; + { const uint64_t x9 = in1[2]; + { const uint64_t x7 = in1[1]; + { const uint64_t x5 = in1[0]; + { const uint64_t x18 = 0; + { const uint64_t x19 = 0; + { const uint64_t x17 = 0; + { const uint64_t x15 = 0; + { const uint64_t x13 = 121666; + { uint128_t x20 = ((uint128_t)x5 * x13); + { uint128_t x21 = (((uint128_t)x5 * x15) + ((uint128_t)x7 * x13)); + { uint128_t x22 = ((((uint128_t)x5 * x17) + ((uint128_t)x9 * x13)) + ((uint128_t)x7 * x15)); + { uint128_t x23 = (((((uint128_t)x5 * x19) + ((uint128_t)x11 * x13)) + ((uint128_t)x7 * x17)) + ((uint128_t)x9 * x15)); + { uint128_t x24 = ((((((uint128_t)x5 * x18) + ((uint128_t)x10 * x13)) + ((uint128_t)x11 * x15)) + ((uint128_t)x7 * x19)) + ((uint128_t)x9 * x17)); + { uint64_t x25 = (x10 * 0x13); + { uint64_t x26 = (x7 * 0x13); + { uint64_t x27 = (x9 * 0x13); + { uint64_t x28 = (x11 * 0x13); + { uint128_t x29 = ((((x20 + ((uint128_t)x25 * x15)) + ((uint128_t)x26 * x18)) + ((uint128_t)x27 * x19)) + ((uint128_t)x28 * x17)); + { uint128_t x30 = (((x21 + ((uint128_t)x25 * x17)) + ((uint128_t)x27 * x18)) + ((uint128_t)x28 * x19)); + { uint128_t x31 = ((x22 + ((uint128_t)x25 * x19)) + ((uint128_t)x28 * x18)); + { uint128_t x32 = (x23 + ((uint128_t)x25 * x18)); + { uint64_t x33 = (uint64_t) (x29 >> 0x33); + { uint64_t x34 = ((uint64_t)x29 & 0x7ffffffffffff); + { uint128_t x35 = (x33 + x30); + { uint64_t x36 = (uint64_t) (x35 >> 0x33); + { uint64_t x37 = ((uint64_t)x35 & 0x7ffffffffffff); + { uint128_t x38 = (x36 + x31); + { uint64_t x39 = (uint64_t) (x38 >> 0x33); + { uint64_t x40 = ((uint64_t)x38 & 0x7ffffffffffff); + { uint128_t x41 = (x39 + x32); + { uint64_t x42 = (uint64_t) (x41 >> 0x33); + { uint64_t x43 = ((uint64_t)x41 & 0x7ffffffffffff); + { uint128_t x44 = (x42 + x24); + { uint64_t x45 = (uint64_t) (x44 >> 0x33); + { uint64_t x46 = ((uint64_t)x44 & 0x7ffffffffffff); + { uint64_t x47 = (x34 + (0x13 * x45)); + { uint64_t x48 = (x47 >> 0x33); + { uint64_t x49 = (x47 & 0x7ffffffffffff); + { uint64_t x50 = (x48 + x37); + { uint64_t x51 = (x50 >> 0x33); + { uint64_t x52 = (x50 & 0x7ffffffffffff); + out[0] = x49; + out[1] = x52; + out[2] = (x51 + x40); + out[3] = x43; + out[4] = x46; + }}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} +} + +static void fe_mul121666(fe *h, const fe_loose *f) { + assert_fe_loose(f->v); + fe_mul_121666_impl(h->v, f->v); + assert_fe(h->v); +} + +// Adapted from Fiat-synthesized |fe_sub_impl| with |out| = 0. +static void fe_neg_impl(uint64_t out[5], const uint64_t in2[5]) { + { const uint64_t x10 = 0; + { const uint64_t x11 = 0; + { const uint64_t x9 = 0; + { const uint64_t x7 = 0; + { const uint64_t x5 = 0; + { const uint64_t x18 = in2[4]; + { const uint64_t x19 = in2[3]; + { const uint64_t x17 = in2[2]; + { const uint64_t x15 = in2[1]; + { const uint64_t x13 = in2[0]; + out[0] = ((0xfffffffffffda + x5) - x13); + out[1] = ((0xffffffffffffe + x7) - x15); + out[2] = ((0xffffffffffffe + x9) - x17); + out[3] = ((0xffffffffffffe + x11) - x19); + out[4] = ((0xffffffffffffe + x10) - x18); + }}}}}}}}}} +} + +// h = -f +static void fe_neg(fe_loose *h, const fe *f) { + assert_fe(f->v); + fe_neg_impl(h->v, f->v); + assert_fe_loose(h->v); +} + +// Replace (f,g) with (g,g) if b == 1; +// replace (f,g) with (f,g) if b == 0. +// +// Preconditions: b in {0,1}. +static void fe_cmov(fe_loose *f, const fe_loose *g, uint64_t b) { + b = 0-b; + for (unsigned i = 0; i < 5; i++) { + uint64_t x = f->v[i] ^ g->v[i]; + x &= b; + f->v[i] ^= x; + } +} + +#else + +#define assert_fe(f) do { \ + for (unsigned _assert_fe_i = 0; _assert_fe_i< 10; _assert_fe_i++) { \ + assert(f[_assert_fe_i] < 1.125*(1<<(26-(_assert_fe_i&1)))); \ + } \ +} while (0) + +#define assert_fe_loose(f) do { \ + for (unsigned _assert_fe_i = 0; _assert_fe_i< 10; _assert_fe_i++) { \ + assert(f[_assert_fe_i] < 3.375*(1<<(26-(_assert_fe_i&1)))); \ + } \ +} while (0) + +#define assert_fe_frozen(f) do { \ + for (unsigned _assert_fe_i = 0; _assert_fe_i< 10; _assert_fe_i++) { \ + assert(f[_assert_fe_i] < (1u<<(26-(_assert_fe_i&1)))); \ + } \ +} while (0) + +static void fe_frombytes_impl(uint32_t h[10], const uint8_t *s) { + // Ignores top bit of s. + uint32_t a0 = load_4(s); + uint32_t a1 = load_4(s+4); + uint32_t a2 = load_4(s+8); + uint32_t a3 = load_4(s+12); + uint32_t a4 = load_4(s+16); + uint32_t a5 = load_4(s+20); + uint32_t a6 = load_4(s+24); + uint32_t a7 = load_4(s+28); + h[0] = a0&((1<<26)-1); // 26 used, 32-26 left. 26 + h[1] = (a0>>26) | ((a1&((1<<19)-1))<< 6); // (32-26) + 19 = 6+19 = 25 + h[2] = (a1>>19) | ((a2&((1<<13)-1))<<13); // (32-19) + 13 = 13+13 = 26 + h[3] = (a2>>13) | ((a3&((1<< 6)-1))<<19); // (32-13) + 6 = 19+ 6 = 25 + h[4] = (a3>> 6); // (32- 6) = 26 + h[5] = a4&((1<<25)-1); // 25 + h[6] = (a4>>25) | ((a5&((1<<19)-1))<< 7); // (32-25) + 19 = 7+19 = 26 + h[7] = (a5>>19) | ((a6&((1<<12)-1))<<13); // (32-19) + 12 = 13+12 = 25 + h[8] = (a6>>12) | ((a7&((1<< 6)-1))<<20); // (32-12) + 6 = 20+ 6 = 26 + h[9] = (a7>> 6)&((1<<25)-1); // 25 + assert_fe(h); +} + +static void fe_frombytes(fe *h, const uint8_t *s) { + fe_frombytes_impl(h->v, s); +} + +static void fe_freeze(uint32_t out[10], const uint32_t in1[10]) { + { const uint32_t x17 = in1[9]; + { const uint32_t x18 = in1[8]; + { const uint32_t x16 = in1[7]; + { const uint32_t x14 = in1[6]; + { const uint32_t x12 = in1[5]; + { const uint32_t x10 = in1[4]; + { const uint32_t x8 = in1[3]; + { const uint32_t x6 = in1[2]; + { const uint32_t x4 = in1[1]; + { const uint32_t x2 = in1[0]; + { uint32_t x20; uint8_t/*bool*/ x21 = subborrow_u26(0x0, x2, 0x3ffffed, &x20); + { uint32_t x23; uint8_t/*bool*/ x24 = subborrow_u25(x21, x4, 0x1ffffff, &x23); + { uint32_t x26; uint8_t/*bool*/ x27 = subborrow_u26(x24, x6, 0x3ffffff, &x26); + { uint32_t x29; uint8_t/*bool*/ x30 = subborrow_u25(x27, x8, 0x1ffffff, &x29); + { uint32_t x32; uint8_t/*bool*/ x33 = subborrow_u26(x30, x10, 0x3ffffff, &x32); + { uint32_t x35; uint8_t/*bool*/ x36 = subborrow_u25(x33, x12, 0x1ffffff, &x35); + { uint32_t x38; uint8_t/*bool*/ x39 = subborrow_u26(x36, x14, 0x3ffffff, &x38); + { uint32_t x41; uint8_t/*bool*/ x42 = subborrow_u25(x39, x16, 0x1ffffff, &x41); + { uint32_t x44; uint8_t/*bool*/ x45 = subborrow_u26(x42, x18, 0x3ffffff, &x44); + { uint32_t x47; uint8_t/*bool*/ x48 = subborrow_u25(x45, x17, 0x1ffffff, &x47); + { uint32_t x49 = cmovznz32(x48, 0x0, 0xffffffff); + { uint32_t x50 = (x49 & 0x3ffffed); + { uint32_t x52; uint8_t/*bool*/ x53 = addcarryx_u26(0x0, x20, x50, &x52); + { uint32_t x54 = (x49 & 0x1ffffff); + { uint32_t x56; uint8_t/*bool*/ x57 = addcarryx_u25(x53, x23, x54, &x56); + { uint32_t x58 = (x49 & 0x3ffffff); + { uint32_t x60; uint8_t/*bool*/ x61 = addcarryx_u26(x57, x26, x58, &x60); + { uint32_t x62 = (x49 & 0x1ffffff); + { uint32_t x64; uint8_t/*bool*/ x65 = addcarryx_u25(x61, x29, x62, &x64); + { uint32_t x66 = (x49 & 0x3ffffff); + { uint32_t x68; uint8_t/*bool*/ x69 = addcarryx_u26(x65, x32, x66, &x68); + { uint32_t x70 = (x49 & 0x1ffffff); + { uint32_t x72; uint8_t/*bool*/ x73 = addcarryx_u25(x69, x35, x70, &x72); + { uint32_t x74 = (x49 & 0x3ffffff); + { uint32_t x76; uint8_t/*bool*/ x77 = addcarryx_u26(x73, x38, x74, &x76); + { uint32_t x78 = (x49 & 0x1ffffff); + { uint32_t x80; uint8_t/*bool*/ x81 = addcarryx_u25(x77, x41, x78, &x80); + { uint32_t x82 = (x49 & 0x3ffffff); + { uint32_t x84; uint8_t/*bool*/ x85 = addcarryx_u26(x81, x44, x82, &x84); + { uint32_t x86 = (x49 & 0x1ffffff); + { uint32_t x88; addcarryx_u25(x85, x47, x86, &x88); + out[0] = x52; + out[1] = x56; + out[2] = x60; + out[3] = x64; + out[4] = x68; + out[5] = x72; + out[6] = x76; + out[7] = x80; + out[8] = x84; + out[9] = x88; + }}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} +} + +static void fe_tobytes(uint8_t s[32], const fe *f) { + assert_fe(f->v); + uint32_t h[10]; + fe_freeze(h, f->v); + assert_fe_frozen(h); + + s[0] = h[0] >> 0; + s[1] = h[0] >> 8; + s[2] = h[0] >> 16; + s[3] = (h[0] >> 24) | (h[1] << 2); + s[4] = h[1] >> 6; + s[5] = h[1] >> 14; + s[6] = (h[1] >> 22) | (h[2] << 3); + s[7] = h[2] >> 5; + s[8] = h[2] >> 13; + s[9] = (h[2] >> 21) | (h[3] << 5); + s[10] = h[3] >> 3; + s[11] = h[3] >> 11; + s[12] = (h[3] >> 19) | (h[4] << 6); + s[13] = h[4] >> 2; + s[14] = h[4] >> 10; + s[15] = h[4] >> 18; + s[16] = h[5] >> 0; + s[17] = h[5] >> 8; + s[18] = h[5] >> 16; + s[19] = (h[5] >> 24) | (h[6] << 1); + s[20] = h[6] >> 7; + s[21] = h[6] >> 15; + s[22] = (h[6] >> 23) | (h[7] << 3); + s[23] = h[7] >> 5; + s[24] = h[7] >> 13; + s[25] = (h[7] >> 21) | (h[8] << 4); + s[26] = h[8] >> 4; + s[27] = h[8] >> 12; + s[28] = (h[8] >> 20) | (h[9] << 6); + s[29] = h[9] >> 2; + s[30] = h[9] >> 10; + s[31] = h[9] >> 18; +} + +// h = 0 +static void fe_0(fe *h) { + OPENSSL_memset(h, 0, sizeof(fe)); +} + +static void fe_loose_0(fe_loose *h) { + OPENSSL_memset(h, 0, sizeof(fe_loose)); +} + +// h = 1 +static void fe_1(fe *h) { + OPENSSL_memset(h, 0, sizeof(fe)); + h->v[0] = 1; +} + +static void fe_loose_1(fe_loose *h) { + OPENSSL_memset(h, 0, sizeof(fe_loose)); + h->v[0] = 1; +} + +static void fe_add_impl(uint32_t out[10], const uint32_t in1[10], const uint32_t in2[10]) { + { const uint32_t x20 = in1[9]; + { const uint32_t x21 = in1[8]; + { const uint32_t x19 = in1[7]; + { const uint32_t x17 = in1[6]; + { const uint32_t x15 = in1[5]; + { const uint32_t x13 = in1[4]; + { const uint32_t x11 = in1[3]; + { const uint32_t x9 = in1[2]; + { const uint32_t x7 = in1[1]; + { const uint32_t x5 = in1[0]; + { const uint32_t x38 = in2[9]; + { const uint32_t x39 = in2[8]; + { const uint32_t x37 = in2[7]; + { const uint32_t x35 = in2[6]; + { const uint32_t x33 = in2[5]; + { const uint32_t x31 = in2[4]; + { const uint32_t x29 = in2[3]; + { const uint32_t x27 = in2[2]; + { const uint32_t x25 = in2[1]; + { const uint32_t x23 = in2[0]; + out[0] = (x5 + x23); + out[1] = (x7 + x25); + out[2] = (x9 + x27); + out[3] = (x11 + x29); + out[4] = (x13 + x31); + out[5] = (x15 + x33); + out[6] = (x17 + x35); + out[7] = (x19 + x37); + out[8] = (x21 + x39); + out[9] = (x20 + x38); + }}}}}}}}}}}}}}}}}}}} +} + +// h = f + g +// Can overlap h with f or g. +static void fe_add(fe_loose *h, const fe *f, const fe *g) { + assert_fe(f->v); + assert_fe(g->v); + fe_add_impl(h->v, f->v, g->v); + assert_fe_loose(h->v); +} + +static void fe_sub_impl(uint32_t out[10], const uint32_t in1[10], const uint32_t in2[10]) { + { const uint32_t x20 = in1[9]; + { const uint32_t x21 = in1[8]; + { const uint32_t x19 = in1[7]; + { const uint32_t x17 = in1[6]; + { const uint32_t x15 = in1[5]; + { const uint32_t x13 = in1[4]; + { const uint32_t x11 = in1[3]; + { const uint32_t x9 = in1[2]; + { const uint32_t x7 = in1[1]; + { const uint32_t x5 = in1[0]; + { const uint32_t x38 = in2[9]; + { const uint32_t x39 = in2[8]; + { const uint32_t x37 = in2[7]; + { const uint32_t x35 = in2[6]; + { const uint32_t x33 = in2[5]; + { const uint32_t x31 = in2[4]; + { const uint32_t x29 = in2[3]; + { const uint32_t x27 = in2[2]; + { const uint32_t x25 = in2[1]; + { const uint32_t x23 = in2[0]; + out[0] = ((0x7ffffda + x5) - x23); + out[1] = ((0x3fffffe + x7) - x25); + out[2] = ((0x7fffffe + x9) - x27); + out[3] = ((0x3fffffe + x11) - x29); + out[4] = ((0x7fffffe + x13) - x31); + out[5] = ((0x3fffffe + x15) - x33); + out[6] = ((0x7fffffe + x17) - x35); + out[7] = ((0x3fffffe + x19) - x37); + out[8] = ((0x7fffffe + x21) - x39); + out[9] = ((0x3fffffe + x20) - x38); + }}}}}}}}}}}}}}}}}}}} +} + +// h = f - g +// Can overlap h with f or g. +static void fe_sub(fe_loose *h, const fe *f, const fe *g) { + assert_fe(f->v); + assert_fe(g->v); + fe_sub_impl(h->v, f->v, g->v); + assert_fe_loose(h->v); +} + +static void fe_carry_impl(uint32_t out[10], const uint32_t in1[10]) { + { const uint32_t x17 = in1[9]; + { const uint32_t x18 = in1[8]; + { const uint32_t x16 = in1[7]; + { const uint32_t x14 = in1[6]; + { const uint32_t x12 = in1[5]; + { const uint32_t x10 = in1[4]; + { const uint32_t x8 = in1[3]; + { const uint32_t x6 = in1[2]; + { const uint32_t x4 = in1[1]; + { const uint32_t x2 = in1[0]; + { uint32_t x19 = (x2 >> 0x1a); + { uint32_t x20 = (x2 & 0x3ffffff); + { uint32_t x21 = (x19 + x4); + { uint32_t x22 = (x21 >> 0x19); + { uint32_t x23 = (x21 & 0x1ffffff); + { uint32_t x24 = (x22 + x6); + { uint32_t x25 = (x24 >> 0x1a); + { uint32_t x26 = (x24 & 0x3ffffff); + { uint32_t x27 = (x25 + x8); + { uint32_t x28 = (x27 >> 0x19); + { uint32_t x29 = (x27 & 0x1ffffff); + { uint32_t x30 = (x28 + x10); + { uint32_t x31 = (x30 >> 0x1a); + { uint32_t x32 = (x30 & 0x3ffffff); + { uint32_t x33 = (x31 + x12); + { uint32_t x34 = (x33 >> 0x19); + { uint32_t x35 = (x33 & 0x1ffffff); + { uint32_t x36 = (x34 + x14); + { uint32_t x37 = (x36 >> 0x1a); + { uint32_t x38 = (x36 & 0x3ffffff); + { uint32_t x39 = (x37 + x16); + { uint32_t x40 = (x39 >> 0x19); + { uint32_t x41 = (x39 & 0x1ffffff); + { uint32_t x42 = (x40 + x18); + { uint32_t x43 = (x42 >> 0x1a); + { uint32_t x44 = (x42 & 0x3ffffff); + { uint32_t x45 = (x43 + x17); + { uint32_t x46 = (x45 >> 0x19); + { uint32_t x47 = (x45 & 0x1ffffff); + { uint32_t x48 = (x20 + (0x13 * x46)); + { uint32_t x49 = (x48 >> 0x1a); + { uint32_t x50 = (x48 & 0x3ffffff); + { uint32_t x51 = (x49 + x23); + { uint32_t x52 = (x51 >> 0x19); + { uint32_t x53 = (x51 & 0x1ffffff); + out[0] = x50; + out[1] = x53; + out[2] = (x52 + x26); + out[3] = x29; + out[4] = x32; + out[5] = x35; + out[6] = x38; + out[7] = x41; + out[8] = x44; + out[9] = x47; + }}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} +} + +static void fe_carry(fe *h, const fe_loose* f) { + assert_fe_loose(f->v); + fe_carry_impl(h->v, f->v); + assert_fe(h->v); +} + +static void fe_mul_impl(uint32_t out[10], const uint32_t in1[10], const uint32_t in2[10]) { + assert_fe_loose(in1); + assert_fe_loose(in2); + { const uint32_t x20 = in1[9]; + { const uint32_t x21 = in1[8]; + { const uint32_t x19 = in1[7]; + { const uint32_t x17 = in1[6]; + { const uint32_t x15 = in1[5]; + { const uint32_t x13 = in1[4]; + { const uint32_t x11 = in1[3]; + { const uint32_t x9 = in1[2]; + { const uint32_t x7 = in1[1]; + { const uint32_t x5 = in1[0]; + { const uint32_t x38 = in2[9]; + { const uint32_t x39 = in2[8]; + { const uint32_t x37 = in2[7]; + { const uint32_t x35 = in2[6]; + { const uint32_t x33 = in2[5]; + { const uint32_t x31 = in2[4]; + { const uint32_t x29 = in2[3]; + { const uint32_t x27 = in2[2]; + { const uint32_t x25 = in2[1]; + { const uint32_t x23 = in2[0]; + { uint64_t x40 = ((uint64_t)x23 * x5); + { uint64_t x41 = (((uint64_t)x23 * x7) + ((uint64_t)x25 * x5)); + { uint64_t x42 = ((((uint64_t)(0x2 * x25) * x7) + ((uint64_t)x23 * x9)) + ((uint64_t)x27 * x5)); + { uint64_t x43 = (((((uint64_t)x25 * x9) + ((uint64_t)x27 * x7)) + ((uint64_t)x23 * x11)) + ((uint64_t)x29 * x5)); + { uint64_t x44 = (((((uint64_t)x27 * x9) + (0x2 * (((uint64_t)x25 * x11) + ((uint64_t)x29 * x7)))) + ((uint64_t)x23 * x13)) + ((uint64_t)x31 * x5)); + { uint64_t x45 = (((((((uint64_t)x27 * x11) + ((uint64_t)x29 * x9)) + ((uint64_t)x25 * x13)) + ((uint64_t)x31 * x7)) + ((uint64_t)x23 * x15)) + ((uint64_t)x33 * x5)); + { uint64_t x46 = (((((0x2 * ((((uint64_t)x29 * x11) + ((uint64_t)x25 * x15)) + ((uint64_t)x33 * x7))) + ((uint64_t)x27 * x13)) + ((uint64_t)x31 * x9)) + ((uint64_t)x23 * x17)) + ((uint64_t)x35 * x5)); + { uint64_t x47 = (((((((((uint64_t)x29 * x13) + ((uint64_t)x31 * x11)) + ((uint64_t)x27 * x15)) + ((uint64_t)x33 * x9)) + ((uint64_t)x25 * x17)) + ((uint64_t)x35 * x7)) + ((uint64_t)x23 * x19)) + ((uint64_t)x37 * x5)); + { uint64_t x48 = (((((((uint64_t)x31 * x13) + (0x2 * (((((uint64_t)x29 * x15) + ((uint64_t)x33 * x11)) + ((uint64_t)x25 * x19)) + ((uint64_t)x37 * x7)))) + ((uint64_t)x27 * x17)) + ((uint64_t)x35 * x9)) + ((uint64_t)x23 * x21)) + ((uint64_t)x39 * x5)); + { uint64_t x49 = (((((((((((uint64_t)x31 * x15) + ((uint64_t)x33 * x13)) + ((uint64_t)x29 * x17)) + ((uint64_t)x35 * x11)) + ((uint64_t)x27 * x19)) + ((uint64_t)x37 * x9)) + ((uint64_t)x25 * x21)) + ((uint64_t)x39 * x7)) + ((uint64_t)x23 * x20)) + ((uint64_t)x38 * x5)); + { uint64_t x50 = (((((0x2 * ((((((uint64_t)x33 * x15) + ((uint64_t)x29 * x19)) + ((uint64_t)x37 * x11)) + ((uint64_t)x25 * x20)) + ((uint64_t)x38 * x7))) + ((uint64_t)x31 * x17)) + ((uint64_t)x35 * x13)) + ((uint64_t)x27 * x21)) + ((uint64_t)x39 * x9)); + { uint64_t x51 = (((((((((uint64_t)x33 * x17) + ((uint64_t)x35 * x15)) + ((uint64_t)x31 * x19)) + ((uint64_t)x37 * x13)) + ((uint64_t)x29 * x21)) + ((uint64_t)x39 * x11)) + ((uint64_t)x27 * x20)) + ((uint64_t)x38 * x9)); + { uint64_t x52 = (((((uint64_t)x35 * x17) + (0x2 * (((((uint64_t)x33 * x19) + ((uint64_t)x37 * x15)) + ((uint64_t)x29 * x20)) + ((uint64_t)x38 * x11)))) + ((uint64_t)x31 * x21)) + ((uint64_t)x39 * x13)); + { uint64_t x53 = (((((((uint64_t)x35 * x19) + ((uint64_t)x37 * x17)) + ((uint64_t)x33 * x21)) + ((uint64_t)x39 * x15)) + ((uint64_t)x31 * x20)) + ((uint64_t)x38 * x13)); + { uint64_t x54 = (((0x2 * ((((uint64_t)x37 * x19) + ((uint64_t)x33 * x20)) + ((uint64_t)x38 * x15))) + ((uint64_t)x35 * x21)) + ((uint64_t)x39 * x17)); + { uint64_t x55 = (((((uint64_t)x37 * x21) + ((uint64_t)x39 * x19)) + ((uint64_t)x35 * x20)) + ((uint64_t)x38 * x17)); + { uint64_t x56 = (((uint64_t)x39 * x21) + (0x2 * (((uint64_t)x37 * x20) + ((uint64_t)x38 * x19)))); + { uint64_t x57 = (((uint64_t)x39 * x20) + ((uint64_t)x38 * x21)); + { uint64_t x58 = ((uint64_t)(0x2 * x38) * x20); + { uint64_t x59 = (x48 + (x58 << 0x4)); + { uint64_t x60 = (x59 + (x58 << 0x1)); + { uint64_t x61 = (x60 + x58); + { uint64_t x62 = (x47 + (x57 << 0x4)); + { uint64_t x63 = (x62 + (x57 << 0x1)); + { uint64_t x64 = (x63 + x57); + { uint64_t x65 = (x46 + (x56 << 0x4)); + { uint64_t x66 = (x65 + (x56 << 0x1)); + { uint64_t x67 = (x66 + x56); + { uint64_t x68 = (x45 + (x55 << 0x4)); + { uint64_t x69 = (x68 + (x55 << 0x1)); + { uint64_t x70 = (x69 + x55); + { uint64_t x71 = (x44 + (x54 << 0x4)); + { uint64_t x72 = (x71 + (x54 << 0x1)); + { uint64_t x73 = (x72 + x54); + { uint64_t x74 = (x43 + (x53 << 0x4)); + { uint64_t x75 = (x74 + (x53 << 0x1)); + { uint64_t x76 = (x75 + x53); + { uint64_t x77 = (x42 + (x52 << 0x4)); + { uint64_t x78 = (x77 + (x52 << 0x1)); + { uint64_t x79 = (x78 + x52); + { uint64_t x80 = (x41 + (x51 << 0x4)); + { uint64_t x81 = (x80 + (x51 << 0x1)); + { uint64_t x82 = (x81 + x51); + { uint64_t x83 = (x40 + (x50 << 0x4)); + { uint64_t x84 = (x83 + (x50 << 0x1)); + { uint64_t x85 = (x84 + x50); + { uint64_t x86 = (x85 >> 0x1a); + { uint32_t x87 = ((uint32_t)x85 & 0x3ffffff); + { uint64_t x88 = (x86 + x82); + { uint64_t x89 = (x88 >> 0x19); + { uint32_t x90 = ((uint32_t)x88 & 0x1ffffff); + { uint64_t x91 = (x89 + x79); + { uint64_t x92 = (x91 >> 0x1a); + { uint32_t x93 = ((uint32_t)x91 & 0x3ffffff); + { uint64_t x94 = (x92 + x76); + { uint64_t x95 = (x94 >> 0x19); + { uint32_t x96 = ((uint32_t)x94 & 0x1ffffff); + { uint64_t x97 = (x95 + x73); + { uint64_t x98 = (x97 >> 0x1a); + { uint32_t x99 = ((uint32_t)x97 & 0x3ffffff); + { uint64_t x100 = (x98 + x70); + { uint64_t x101 = (x100 >> 0x19); + { uint32_t x102 = ((uint32_t)x100 & 0x1ffffff); + { uint64_t x103 = (x101 + x67); + { uint64_t x104 = (x103 >> 0x1a); + { uint32_t x105 = ((uint32_t)x103 & 0x3ffffff); + { uint64_t x106 = (x104 + x64); + { uint64_t x107 = (x106 >> 0x19); + { uint32_t x108 = ((uint32_t)x106 & 0x1ffffff); + { uint64_t x109 = (x107 + x61); + { uint64_t x110 = (x109 >> 0x1a); + { uint32_t x111 = ((uint32_t)x109 & 0x3ffffff); + { uint64_t x112 = (x110 + x49); + { uint64_t x113 = (x112 >> 0x19); + { uint32_t x114 = ((uint32_t)x112 & 0x1ffffff); + { uint64_t x115 = (x87 + (0x13 * x113)); + { uint32_t x116 = (uint32_t) (x115 >> 0x1a); + { uint32_t x117 = ((uint32_t)x115 & 0x3ffffff); + { uint32_t x118 = (x116 + x90); + { uint32_t x119 = (x118 >> 0x19); + { uint32_t x120 = (x118 & 0x1ffffff); + out[0] = x117; + out[1] = x120; + out[2] = (x119 + x93); + out[3] = x96; + out[4] = x99; + out[5] = x102; + out[6] = x105; + out[7] = x108; + out[8] = x111; + out[9] = x114; + }}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} + assert_fe(out); +} + +static void fe_mul_ltt(fe_loose *h, const fe *f, const fe *g) { + fe_mul_impl(h->v, f->v, g->v); +} + +static void fe_mul_llt(fe_loose *h, const fe_loose *f, const fe *g) { + fe_mul_impl(h->v, f->v, g->v); +} + +static void fe_mul_ttt(fe *h, const fe *f, const fe *g) { + fe_mul_impl(h->v, f->v, g->v); +} + +static void fe_mul_tlt(fe *h, const fe_loose *f, const fe *g) { + fe_mul_impl(h->v, f->v, g->v); +} + +static void fe_mul_ttl(fe *h, const fe *f, const fe_loose *g) { + fe_mul_impl(h->v, f->v, g->v); +} + +static void fe_mul_tll(fe *h, const fe_loose *f, const fe_loose *g) { + fe_mul_impl(h->v, f->v, g->v); +} + +static void fe_sqr_impl(uint32_t out[10], const uint32_t in1[10]) { + assert_fe_loose(in1); + { const uint32_t x17 = in1[9]; + { const uint32_t x18 = in1[8]; + { const uint32_t x16 = in1[7]; + { const uint32_t x14 = in1[6]; + { const uint32_t x12 = in1[5]; + { const uint32_t x10 = in1[4]; + { const uint32_t x8 = in1[3]; + { const uint32_t x6 = in1[2]; + { const uint32_t x4 = in1[1]; + { const uint32_t x2 = in1[0]; + { uint64_t x19 = ((uint64_t)x2 * x2); + { uint64_t x20 = ((uint64_t)(0x2 * x2) * x4); + { uint64_t x21 = (0x2 * (((uint64_t)x4 * x4) + ((uint64_t)x2 * x6))); + { uint64_t x22 = (0x2 * (((uint64_t)x4 * x6) + ((uint64_t)x2 * x8))); + { uint64_t x23 = ((((uint64_t)x6 * x6) + ((uint64_t)(0x4 * x4) * x8)) + ((uint64_t)(0x2 * x2) * x10)); + { uint64_t x24 = (0x2 * ((((uint64_t)x6 * x8) + ((uint64_t)x4 * x10)) + ((uint64_t)x2 * x12))); + { uint64_t x25 = (0x2 * (((((uint64_t)x8 * x8) + ((uint64_t)x6 * x10)) + ((uint64_t)x2 * x14)) + ((uint64_t)(0x2 * x4) * x12))); + { uint64_t x26 = (0x2 * (((((uint64_t)x8 * x10) + ((uint64_t)x6 * x12)) + ((uint64_t)x4 * x14)) + ((uint64_t)x2 * x16))); + { uint64_t x27 = (((uint64_t)x10 * x10) + (0x2 * ((((uint64_t)x6 * x14) + ((uint64_t)x2 * x18)) + (0x2 * (((uint64_t)x4 * x16) + ((uint64_t)x8 * x12)))))); + { uint64_t x28 = (0x2 * ((((((uint64_t)x10 * x12) + ((uint64_t)x8 * x14)) + ((uint64_t)x6 * x16)) + ((uint64_t)x4 * x18)) + ((uint64_t)x2 * x17))); + { uint64_t x29 = (0x2 * (((((uint64_t)x12 * x12) + ((uint64_t)x10 * x14)) + ((uint64_t)x6 * x18)) + (0x2 * (((uint64_t)x8 * x16) + ((uint64_t)x4 * x17))))); + { uint64_t x30 = (0x2 * (((((uint64_t)x12 * x14) + ((uint64_t)x10 * x16)) + ((uint64_t)x8 * x18)) + ((uint64_t)x6 * x17))); + { uint64_t x31 = (((uint64_t)x14 * x14) + (0x2 * (((uint64_t)x10 * x18) + (0x2 * (((uint64_t)x12 * x16) + ((uint64_t)x8 * x17)))))); + { uint64_t x32 = (0x2 * ((((uint64_t)x14 * x16) + ((uint64_t)x12 * x18)) + ((uint64_t)x10 * x17))); + { uint64_t x33 = (0x2 * ((((uint64_t)x16 * x16) + ((uint64_t)x14 * x18)) + ((uint64_t)(0x2 * x12) * x17))); + { uint64_t x34 = (0x2 * (((uint64_t)x16 * x18) + ((uint64_t)x14 * x17))); + { uint64_t x35 = (((uint64_t)x18 * x18) + ((uint64_t)(0x4 * x16) * x17)); + { uint64_t x36 = ((uint64_t)(0x2 * x18) * x17); + { uint64_t x37 = ((uint64_t)(0x2 * x17) * x17); + { uint64_t x38 = (x27 + (x37 << 0x4)); + { uint64_t x39 = (x38 + (x37 << 0x1)); + { uint64_t x40 = (x39 + x37); + { uint64_t x41 = (x26 + (x36 << 0x4)); + { uint64_t x42 = (x41 + (x36 << 0x1)); + { uint64_t x43 = (x42 + x36); + { uint64_t x44 = (x25 + (x35 << 0x4)); + { uint64_t x45 = (x44 + (x35 << 0x1)); + { uint64_t x46 = (x45 + x35); + { uint64_t x47 = (x24 + (x34 << 0x4)); + { uint64_t x48 = (x47 + (x34 << 0x1)); + { uint64_t x49 = (x48 + x34); + { uint64_t x50 = (x23 + (x33 << 0x4)); + { uint64_t x51 = (x50 + (x33 << 0x1)); + { uint64_t x52 = (x51 + x33); + { uint64_t x53 = (x22 + (x32 << 0x4)); + { uint64_t x54 = (x53 + (x32 << 0x1)); + { uint64_t x55 = (x54 + x32); + { uint64_t x56 = (x21 + (x31 << 0x4)); + { uint64_t x57 = (x56 + (x31 << 0x1)); + { uint64_t x58 = (x57 + x31); + { uint64_t x59 = (x20 + (x30 << 0x4)); + { uint64_t x60 = (x59 + (x30 << 0x1)); + { uint64_t x61 = (x60 + x30); + { uint64_t x62 = (x19 + (x29 << 0x4)); + { uint64_t x63 = (x62 + (x29 << 0x1)); + { uint64_t x64 = (x63 + x29); + { uint64_t x65 = (x64 >> 0x1a); + { uint32_t x66 = ((uint32_t)x64 & 0x3ffffff); + { uint64_t x67 = (x65 + x61); + { uint64_t x68 = (x67 >> 0x19); + { uint32_t x69 = ((uint32_t)x67 & 0x1ffffff); + { uint64_t x70 = (x68 + x58); + { uint64_t x71 = (x70 >> 0x1a); + { uint32_t x72 = ((uint32_t)x70 & 0x3ffffff); + { uint64_t x73 = (x71 + x55); + { uint64_t x74 = (x73 >> 0x19); + { uint32_t x75 = ((uint32_t)x73 & 0x1ffffff); + { uint64_t x76 = (x74 + x52); + { uint64_t x77 = (x76 >> 0x1a); + { uint32_t x78 = ((uint32_t)x76 & 0x3ffffff); + { uint64_t x79 = (x77 + x49); + { uint64_t x80 = (x79 >> 0x19); + { uint32_t x81 = ((uint32_t)x79 & 0x1ffffff); + { uint64_t x82 = (x80 + x46); + { uint64_t x83 = (x82 >> 0x1a); + { uint32_t x84 = ((uint32_t)x82 & 0x3ffffff); + { uint64_t x85 = (x83 + x43); + { uint64_t x86 = (x85 >> 0x19); + { uint32_t x87 = ((uint32_t)x85 & 0x1ffffff); + { uint64_t x88 = (x86 + x40); + { uint64_t x89 = (x88 >> 0x1a); + { uint32_t x90 = ((uint32_t)x88 & 0x3ffffff); + { uint64_t x91 = (x89 + x28); + { uint64_t x92 = (x91 >> 0x19); + { uint32_t x93 = ((uint32_t)x91 & 0x1ffffff); + { uint64_t x94 = (x66 + (0x13 * x92)); + { uint32_t x95 = (uint32_t) (x94 >> 0x1a); + { uint32_t x96 = ((uint32_t)x94 & 0x3ffffff); + { uint32_t x97 = (x95 + x69); + { uint32_t x98 = (x97 >> 0x19); + { uint32_t x99 = (x97 & 0x1ffffff); + out[0] = x96; + out[1] = x99; + out[2] = (x98 + x72); + out[3] = x75; + out[4] = x78; + out[5] = x81; + out[6] = x84; + out[7] = x87; + out[8] = x90; + out[9] = x93; + }}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} + assert_fe(out); +} + +static void fe_sq_tl(fe *h, const fe_loose *f) { + fe_sqr_impl(h->v, f->v); +} + +static void fe_sq_tt(fe *h, const fe *f) { + fe_sqr_impl(h->v, f->v); +} + +// Replace (f,g) with (g,f) if b == 1; +// replace (f,g) with (f,g) if b == 0. +// +// Preconditions: b in {0,1}. +static void fe_cswap(fe *f, fe *g, unsigned int b) { + b = 0-b; + unsigned i; + for (i = 0; i < 10; i++) { + uint32_t x = f->v[i] ^ g->v[i]; + x &= b; + f->v[i] ^= x; + g->v[i] ^= x; + } +} + +// NOTE: based on fiat-crypto fe_mul, edited for in2=121666, 0, 0.. +static void fe_mul_121666_impl(uint32_t out[10], const uint32_t in1[10]) { + { const uint32_t x20 = in1[9]; + { const uint32_t x21 = in1[8]; + { const uint32_t x19 = in1[7]; + { const uint32_t x17 = in1[6]; + { const uint32_t x15 = in1[5]; + { const uint32_t x13 = in1[4]; + { const uint32_t x11 = in1[3]; + { const uint32_t x9 = in1[2]; + { const uint32_t x7 = in1[1]; + { const uint32_t x5 = in1[0]; + { const uint32_t x38 = 0; + { const uint32_t x39 = 0; + { const uint32_t x37 = 0; + { const uint32_t x35 = 0; + { const uint32_t x33 = 0; + { const uint32_t x31 = 0; + { const uint32_t x29 = 0; + { const uint32_t x27 = 0; + { const uint32_t x25 = 0; + { const uint32_t x23 = 121666; + { uint64_t x40 = ((uint64_t)x23 * x5); + { uint64_t x41 = (((uint64_t)x23 * x7) + ((uint64_t)x25 * x5)); + { uint64_t x42 = ((((uint64_t)(0x2 * x25) * x7) + ((uint64_t)x23 * x9)) + ((uint64_t)x27 * x5)); + { uint64_t x43 = (((((uint64_t)x25 * x9) + ((uint64_t)x27 * x7)) + ((uint64_t)x23 * x11)) + ((uint64_t)x29 * x5)); + { uint64_t x44 = (((((uint64_t)x27 * x9) + (0x2 * (((uint64_t)x25 * x11) + ((uint64_t)x29 * x7)))) + ((uint64_t)x23 * x13)) + ((uint64_t)x31 * x5)); + { uint64_t x45 = (((((((uint64_t)x27 * x11) + ((uint64_t)x29 * x9)) + ((uint64_t)x25 * x13)) + ((uint64_t)x31 * x7)) + ((uint64_t)x23 * x15)) + ((uint64_t)x33 * x5)); + { uint64_t x46 = (((((0x2 * ((((uint64_t)x29 * x11) + ((uint64_t)x25 * x15)) + ((uint64_t)x33 * x7))) + ((uint64_t)x27 * x13)) + ((uint64_t)x31 * x9)) + ((uint64_t)x23 * x17)) + ((uint64_t)x35 * x5)); + { uint64_t x47 = (((((((((uint64_t)x29 * x13) + ((uint64_t)x31 * x11)) + ((uint64_t)x27 * x15)) + ((uint64_t)x33 * x9)) + ((uint64_t)x25 * x17)) + ((uint64_t)x35 * x7)) + ((uint64_t)x23 * x19)) + ((uint64_t)x37 * x5)); + { uint64_t x48 = (((((((uint64_t)x31 * x13) + (0x2 * (((((uint64_t)x29 * x15) + ((uint64_t)x33 * x11)) + ((uint64_t)x25 * x19)) + ((uint64_t)x37 * x7)))) + ((uint64_t)x27 * x17)) + ((uint64_t)x35 * x9)) + ((uint64_t)x23 * x21)) + ((uint64_t)x39 * x5)); + { uint64_t x49 = (((((((((((uint64_t)x31 * x15) + ((uint64_t)x33 * x13)) + ((uint64_t)x29 * x17)) + ((uint64_t)x35 * x11)) + ((uint64_t)x27 * x19)) + ((uint64_t)x37 * x9)) + ((uint64_t)x25 * x21)) + ((uint64_t)x39 * x7)) + ((uint64_t)x23 * x20)) + ((uint64_t)x38 * x5)); + { uint64_t x50 = (((((0x2 * ((((((uint64_t)x33 * x15) + ((uint64_t)x29 * x19)) + ((uint64_t)x37 * x11)) + ((uint64_t)x25 * x20)) + ((uint64_t)x38 * x7))) + ((uint64_t)x31 * x17)) + ((uint64_t)x35 * x13)) + ((uint64_t)x27 * x21)) + ((uint64_t)x39 * x9)); + { uint64_t x51 = (((((((((uint64_t)x33 * x17) + ((uint64_t)x35 * x15)) + ((uint64_t)x31 * x19)) + ((uint64_t)x37 * x13)) + ((uint64_t)x29 * x21)) + ((uint64_t)x39 * x11)) + ((uint64_t)x27 * x20)) + ((uint64_t)x38 * x9)); + { uint64_t x52 = (((((uint64_t)x35 * x17) + (0x2 * (((((uint64_t)x33 * x19) + ((uint64_t)x37 * x15)) + ((uint64_t)x29 * x20)) + ((uint64_t)x38 * x11)))) + ((uint64_t)x31 * x21)) + ((uint64_t)x39 * x13)); + { uint64_t x53 = (((((((uint64_t)x35 * x19) + ((uint64_t)x37 * x17)) + ((uint64_t)x33 * x21)) + ((uint64_t)x39 * x15)) + ((uint64_t)x31 * x20)) + ((uint64_t)x38 * x13)); + { uint64_t x54 = (((0x2 * ((((uint64_t)x37 * x19) + ((uint64_t)x33 * x20)) + ((uint64_t)x38 * x15))) + ((uint64_t)x35 * x21)) + ((uint64_t)x39 * x17)); + { uint64_t x55 = (((((uint64_t)x37 * x21) + ((uint64_t)x39 * x19)) + ((uint64_t)x35 * x20)) + ((uint64_t)x38 * x17)); + { uint64_t x56 = (((uint64_t)x39 * x21) + (0x2 * (((uint64_t)x37 * x20) + ((uint64_t)x38 * x19)))); + { uint64_t x57 = (((uint64_t)x39 * x20) + ((uint64_t)x38 * x21)); + { uint64_t x58 = ((uint64_t)(0x2 * x38) * x20); + { uint64_t x59 = (x48 + (x58 << 0x4)); + { uint64_t x60 = (x59 + (x58 << 0x1)); + { uint64_t x61 = (x60 + x58); + { uint64_t x62 = (x47 + (x57 << 0x4)); + { uint64_t x63 = (x62 + (x57 << 0x1)); + { uint64_t x64 = (x63 + x57); + { uint64_t x65 = (x46 + (x56 << 0x4)); + { uint64_t x66 = (x65 + (x56 << 0x1)); + { uint64_t x67 = (x66 + x56); + { uint64_t x68 = (x45 + (x55 << 0x4)); + { uint64_t x69 = (x68 + (x55 << 0x1)); + { uint64_t x70 = (x69 + x55); + { uint64_t x71 = (x44 + (x54 << 0x4)); + { uint64_t x72 = (x71 + (x54 << 0x1)); + { uint64_t x73 = (x72 + x54); + { uint64_t x74 = (x43 + (x53 << 0x4)); + { uint64_t x75 = (x74 + (x53 << 0x1)); + { uint64_t x76 = (x75 + x53); + { uint64_t x77 = (x42 + (x52 << 0x4)); + { uint64_t x78 = (x77 + (x52 << 0x1)); + { uint64_t x79 = (x78 + x52); + { uint64_t x80 = (x41 + (x51 << 0x4)); + { uint64_t x81 = (x80 + (x51 << 0x1)); + { uint64_t x82 = (x81 + x51); + { uint64_t x83 = (x40 + (x50 << 0x4)); + { uint64_t x84 = (x83 + (x50 << 0x1)); + { uint64_t x85 = (x84 + x50); + { uint64_t x86 = (x85 >> 0x1a); + { uint32_t x87 = ((uint32_t)x85 & 0x3ffffff); + { uint64_t x88 = (x86 + x82); + { uint64_t x89 = (x88 >> 0x19); + { uint32_t x90 = ((uint32_t)x88 & 0x1ffffff); + { uint64_t x91 = (x89 + x79); + { uint64_t x92 = (x91 >> 0x1a); + { uint32_t x93 = ((uint32_t)x91 & 0x3ffffff); + { uint64_t x94 = (x92 + x76); + { uint64_t x95 = (x94 >> 0x19); + { uint32_t x96 = ((uint32_t)x94 & 0x1ffffff); + { uint64_t x97 = (x95 + x73); + { uint64_t x98 = (x97 >> 0x1a); + { uint32_t x99 = ((uint32_t)x97 & 0x3ffffff); + { uint64_t x100 = (x98 + x70); + { uint64_t x101 = (x100 >> 0x19); + { uint32_t x102 = ((uint32_t)x100 & 0x1ffffff); + { uint64_t x103 = (x101 + x67); + { uint64_t x104 = (x103 >> 0x1a); + { uint32_t x105 = ((uint32_t)x103 & 0x3ffffff); + { uint64_t x106 = (x104 + x64); + { uint64_t x107 = (x106 >> 0x19); + { uint32_t x108 = ((uint32_t)x106 & 0x1ffffff); + { uint64_t x109 = (x107 + x61); + { uint64_t x110 = (x109 >> 0x1a); + { uint32_t x111 = ((uint32_t)x109 & 0x3ffffff); + { uint64_t x112 = (x110 + x49); + { uint64_t x113 = (x112 >> 0x19); + { uint32_t x114 = ((uint32_t)x112 & 0x1ffffff); + { uint64_t x115 = (x87 + (0x13 * x113)); + { uint32_t x116 = (uint32_t) (x115 >> 0x1a); + { uint32_t x117 = ((uint32_t)x115 & 0x3ffffff); + { uint32_t x118 = (x116 + x90); + { uint32_t x119 = (x118 >> 0x19); + { uint32_t x120 = (x118 & 0x1ffffff); + out[0] = x117; + out[1] = x120; + out[2] = (x119 + x93); + out[3] = x96; + out[4] = x99; + out[5] = x102; + out[6] = x105; + out[7] = x108; + out[8] = x111; + out[9] = x114; + }}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} +} + +static void fe_mul121666(fe *h, const fe_loose *f) { + assert_fe_loose(f->v); + fe_mul_121666_impl(h->v, f->v); + assert_fe(h->v); +} + +// Adapted from Fiat-synthesized |fe_sub_impl| with |out| = 0. +static void fe_neg_impl(uint32_t out[10], const uint32_t in2[10]) { + { const uint32_t x20 = 0; + { const uint32_t x21 = 0; + { const uint32_t x19 = 0; + { const uint32_t x17 = 0; + { const uint32_t x15 = 0; + { const uint32_t x13 = 0; + { const uint32_t x11 = 0; + { const uint32_t x9 = 0; + { const uint32_t x7 = 0; + { const uint32_t x5 = 0; + { const uint32_t x38 = in2[9]; + { const uint32_t x39 = in2[8]; + { const uint32_t x37 = in2[7]; + { const uint32_t x35 = in2[6]; + { const uint32_t x33 = in2[5]; + { const uint32_t x31 = in2[4]; + { const uint32_t x29 = in2[3]; + { const uint32_t x27 = in2[2]; + { const uint32_t x25 = in2[1]; + { const uint32_t x23 = in2[0]; + out[0] = ((0x7ffffda + x5) - x23); + out[1] = ((0x3fffffe + x7) - x25); + out[2] = ((0x7fffffe + x9) - x27); + out[3] = ((0x3fffffe + x11) - x29); + out[4] = ((0x7fffffe + x13) - x31); + out[5] = ((0x3fffffe + x15) - x33); + out[6] = ((0x7fffffe + x17) - x35); + out[7] = ((0x3fffffe + x19) - x37); + out[8] = ((0x7fffffe + x21) - x39); + out[9] = ((0x3fffffe + x20) - x38); + }}}}}}}}}}}}}}}}}}}} +} + +// h = -f +static void fe_neg(fe_loose *h, const fe *f) { + assert_fe(f->v); + fe_neg_impl(h->v, f->v); + assert_fe_loose(h->v); +} + +// Replace (f,g) with (g,g) if b == 1; +// replace (f,g) with (f,g) if b == 0. +// +// Preconditions: b in {0,1}. +static void fe_cmov(fe_loose *f, const fe_loose *g, unsigned b) { + b = 0-b; + unsigned i; + for (i = 0; i < 10; i++) { + uint32_t x = f->v[i] ^ g->v[i]; + x &= b; + f->v[i] ^= x; + } +} + +#endif // BORINGSSL_CURVE25519_64BIT + +// h = f +static void fe_copy(fe *h, const fe *f) { + OPENSSL_memmove(h, f, sizeof(fe)); +} + +static void fe_copy_lt(fe_loose *h, const fe *f) { + OPENSSL_COMPILE_ASSERT(sizeof(fe_loose) == sizeof(fe), + fe_and_fe_loose_mismatch); + OPENSSL_memmove(h, f, sizeof(fe)); +} +#if !defined(OPENSSL_SMALL) +static void fe_copy_ll(fe_loose *h, const fe_loose *f) { + OPENSSL_memmove(h, f, sizeof(fe_loose)); +} +#endif // !defined(OPENSSL_SMALL) + +static void fe_loose_invert(fe *out, const fe_loose *z) { + fe t0; + fe t1; + fe t2; + fe t3; + int i; + + fe_sq_tl(&t0, z); + fe_sq_tt(&t1, &t0); + for (i = 1; i < 2; ++i) { + fe_sq_tt(&t1, &t1); + } + fe_mul_tlt(&t1, z, &t1); + fe_mul_ttt(&t0, &t0, &t1); + fe_sq_tt(&t2, &t0); + fe_mul_ttt(&t1, &t1, &t2); + fe_sq_tt(&t2, &t1); + for (i = 1; i < 5; ++i) { + fe_sq_tt(&t2, &t2); + } + fe_mul_ttt(&t1, &t2, &t1); + fe_sq_tt(&t2, &t1); + for (i = 1; i < 10; ++i) { + fe_sq_tt(&t2, &t2); + } + fe_mul_ttt(&t2, &t2, &t1); + fe_sq_tt(&t3, &t2); + for (i = 1; i < 20; ++i) { + fe_sq_tt(&t3, &t3); + } + fe_mul_ttt(&t2, &t3, &t2); + fe_sq_tt(&t2, &t2); + for (i = 1; i < 10; ++i) { + fe_sq_tt(&t2, &t2); + } + fe_mul_ttt(&t1, &t2, &t1); + fe_sq_tt(&t2, &t1); + for (i = 1; i < 50; ++i) { + fe_sq_tt(&t2, &t2); + } + fe_mul_ttt(&t2, &t2, &t1); + fe_sq_tt(&t3, &t2); + for (i = 1; i < 100; ++i) { + fe_sq_tt(&t3, &t3); + } + fe_mul_ttt(&t2, &t3, &t2); + fe_sq_tt(&t2, &t2); + for (i = 1; i < 50; ++i) { + fe_sq_tt(&t2, &t2); + } + fe_mul_ttt(&t1, &t2, &t1); + fe_sq_tt(&t1, &t1); + for (i = 1; i < 5; ++i) { + fe_sq_tt(&t1, &t1); + } + fe_mul_ttt(out, &t1, &t0); +} + +static void fe_invert(fe *out, const fe *z) { + fe_loose l; + fe_copy_lt(&l, z); + fe_loose_invert(out, &l); +} + +// return 0 if f == 0 +// return 1 if f != 0 +static int fe_isnonzero(const fe_loose *f) { + fe tight; + fe_carry(&tight, f); + uint8_t s[32]; + fe_tobytes(s, &tight); + + static const uint8_t zero[32] = {0}; + return CRYPTO_memcmp(s, zero, sizeof(zero)) != 0; +} + +// return 1 if f is in {1,3,5,...,q-2} +// return 0 if f is in {0,2,4,...,q-1} +static int fe_isnegative(const fe *f) { + uint8_t s[32]; + fe_tobytes(s, f); + return s[0] & 1; +} + +static void fe_sq2_tt(fe *h, const fe *f) { + // h = f^2 + fe_sq_tt(h, f); + + // h = h + h + fe_loose tmp; + fe_add(&tmp, h, h); + fe_carry(h, &tmp); +} + +static void fe_pow22523(fe *out, const fe *z) { + fe t0; + fe t1; + fe t2; + int i; + + fe_sq_tt(&t0, z); + fe_sq_tt(&t1, &t0); + for (i = 1; i < 2; ++i) { + fe_sq_tt(&t1, &t1); + } + fe_mul_ttt(&t1, z, &t1); + fe_mul_ttt(&t0, &t0, &t1); + fe_sq_tt(&t0, &t0); + fe_mul_ttt(&t0, &t1, &t0); + fe_sq_tt(&t1, &t0); + for (i = 1; i < 5; ++i) { + fe_sq_tt(&t1, &t1); + } + fe_mul_ttt(&t0, &t1, &t0); + fe_sq_tt(&t1, &t0); + for (i = 1; i < 10; ++i) { + fe_sq_tt(&t1, &t1); + } + fe_mul_ttt(&t1, &t1, &t0); + fe_sq_tt(&t2, &t1); + for (i = 1; i < 20; ++i) { + fe_sq_tt(&t2, &t2); + } + fe_mul_ttt(&t1, &t2, &t1); + fe_sq_tt(&t1, &t1); + for (i = 1; i < 10; ++i) { + fe_sq_tt(&t1, &t1); + } + fe_mul_ttt(&t0, &t1, &t0); + fe_sq_tt(&t1, &t0); + for (i = 1; i < 50; ++i) { + fe_sq_tt(&t1, &t1); + } + fe_mul_ttt(&t1, &t1, &t0); + fe_sq_tt(&t2, &t1); + for (i = 1; i < 100; ++i) { + fe_sq_tt(&t2, &t2); + } + fe_mul_ttt(&t1, &t2, &t1); + fe_sq_tt(&t1, &t1); + for (i = 1; i < 50; ++i) { + fe_sq_tt(&t1, &t1); + } + fe_mul_ttt(&t0, &t1, &t0); + fe_sq_tt(&t0, &t0); + for (i = 1; i < 2; ++i) { + fe_sq_tt(&t0, &t0); + } + fe_mul_ttt(out, &t0, z); +} + + +// Group operations. + +void x25519_ge_tobytes(uint8_t s[32], const ge_p2 *h) { + fe recip; + fe x; + fe y; + + fe_invert(&recip, &h->Z); + fe_mul_ttt(&x, &h->X, &recip); + fe_mul_ttt(&y, &h->Y, &recip); + fe_tobytes(s, &y); + s[31] ^= fe_isnegative(&x) << 7; +} + +static void ge_p3_tobytes(uint8_t s[32], const ge_p3 *h) { + fe recip; + fe x; + fe y; + + fe_invert(&recip, &h->Z); + fe_mul_ttt(&x, &h->X, &recip); + fe_mul_ttt(&y, &h->Y, &recip); + fe_tobytes(s, &y); + s[31] ^= fe_isnegative(&x) << 7; +} + +int x25519_ge_frombytes_vartime(ge_p3 *h, const uint8_t *s) { + fe u; + fe_loose v; + fe v3; + fe vxx; + fe_loose check; + + fe_frombytes(&h->Y, s); + fe_1(&h->Z); + fe_sq_tt(&v3, &h->Y); + fe_mul_ttt(&vxx, &v3, &d); + fe_sub(&v, &v3, &h->Z); // u = y^2-1 + fe_carry(&u, &v); + fe_add(&v, &vxx, &h->Z); // v = dy^2+1 + + fe_sq_tl(&v3, &v); + fe_mul_ttl(&v3, &v3, &v); // v3 = v^3 + fe_sq_tt(&h->X, &v3); + fe_mul_ttl(&h->X, &h->X, &v); + fe_mul_ttt(&h->X, &h->X, &u); // x = uv^7 + + fe_pow22523(&h->X, &h->X); // x = (uv^7)^((q-5)/8) + fe_mul_ttt(&h->X, &h->X, &v3); + fe_mul_ttt(&h->X, &h->X, &u); // x = uv^3(uv^7)^((q-5)/8) + + fe_sq_tt(&vxx, &h->X); + fe_mul_ttl(&vxx, &vxx, &v); + fe_sub(&check, &vxx, &u); + if (fe_isnonzero(&check)) { + fe_add(&check, &vxx, &u); + if (fe_isnonzero(&check)) { + return -1; + } + fe_mul_ttt(&h->X, &h->X, &sqrtm1); + } + + if (fe_isnegative(&h->X) != (s[31] >> 7)) { + fe_loose t; + fe_neg(&t, &h->X); + fe_carry(&h->X, &t); + } + + fe_mul_ttt(&h->T, &h->X, &h->Y); + return 0; +} + +static void ge_p2_0(ge_p2 *h) { + fe_0(&h->X); + fe_1(&h->Y); + fe_1(&h->Z); +} + +static void ge_p3_0(ge_p3 *h) { + fe_0(&h->X); + fe_1(&h->Y); + fe_1(&h->Z); + fe_0(&h->T); +} + +static void ge_cached_0(ge_cached *h) { + fe_loose_1(&h->YplusX); + fe_loose_1(&h->YminusX); + fe_loose_1(&h->Z); + fe_loose_0(&h->T2d); +} + +static void ge_precomp_0(ge_precomp *h) { + fe_loose_1(&h->yplusx); + fe_loose_1(&h->yminusx); + fe_loose_0(&h->xy2d); +} + +// r = p +static void ge_p3_to_p2(ge_p2 *r, const ge_p3 *p) { + fe_copy(&r->X, &p->X); + fe_copy(&r->Y, &p->Y); + fe_copy(&r->Z, &p->Z); +} + +// r = p +void x25519_ge_p3_to_cached(ge_cached *r, const ge_p3 *p) { + fe_add(&r->YplusX, &p->Y, &p->X); + fe_sub(&r->YminusX, &p->Y, &p->X); + fe_copy_lt(&r->Z, &p->Z); + fe_mul_ltt(&r->T2d, &p->T, &d2); +} + +// r = p +void x25519_ge_p1p1_to_p2(ge_p2 *r, const ge_p1p1 *p) { + fe_mul_tll(&r->X, &p->X, &p->T); + fe_mul_tll(&r->Y, &p->Y, &p->Z); + fe_mul_tll(&r->Z, &p->Z, &p->T); +} + +// r = p +void x25519_ge_p1p1_to_p3(ge_p3 *r, const ge_p1p1 *p) { + fe_mul_tll(&r->X, &p->X, &p->T); + fe_mul_tll(&r->Y, &p->Y, &p->Z); + fe_mul_tll(&r->Z, &p->Z, &p->T); + fe_mul_tll(&r->T, &p->X, &p->Y); +} + +// r = p +static void ge_p1p1_to_cached(ge_cached *r, const ge_p1p1 *p) { + ge_p3 t; + x25519_ge_p1p1_to_p3(&t, p); + x25519_ge_p3_to_cached(r, &t); +} + +// r = 2 * p +static void ge_p2_dbl(ge_p1p1 *r, const ge_p2 *p) { + fe trX, trZ, trT; + fe t0; + + fe_sq_tt(&trX, &p->X); + fe_sq_tt(&trZ, &p->Y); + fe_sq2_tt(&trT, &p->Z); + fe_add(&r->Y, &p->X, &p->Y); + fe_sq_tl(&t0, &r->Y); + + fe_add(&r->Y, &trZ, &trX); + fe_sub(&r->Z, &trZ, &trX); + fe_carry(&trZ, &r->Y); + fe_sub(&r->X, &t0, &trZ); + fe_carry(&trZ, &r->Z); + fe_sub(&r->T, &trT, &trZ); +} + +// r = 2 * p +static void ge_p3_dbl(ge_p1p1 *r, const ge_p3 *p) { + ge_p2 q; + ge_p3_to_p2(&q, p); + ge_p2_dbl(r, &q); +} + +// r = p + q +static void ge_madd(ge_p1p1 *r, const ge_p3 *p, const ge_precomp *q) { + fe trY, trZ, trT; + + fe_add(&r->X, &p->Y, &p->X); + fe_sub(&r->Y, &p->Y, &p->X); + fe_mul_tll(&trZ, &r->X, &q->yplusx); + fe_mul_tll(&trY, &r->Y, &q->yminusx); + fe_mul_tlt(&trT, &q->xy2d, &p->T); + fe_add(&r->T, &p->Z, &p->Z); + fe_sub(&r->X, &trZ, &trY); + fe_add(&r->Y, &trZ, &trY); + fe_carry(&trZ, &r->T); + fe_add(&r->Z, &trZ, &trT); + fe_sub(&r->T, &trZ, &trT); +} + +// r = p - q +static void ge_msub(ge_p1p1 *r, const ge_p3 *p, const ge_precomp *q) { + fe trY, trZ, trT; + + fe_add(&r->X, &p->Y, &p->X); + fe_sub(&r->Y, &p->Y, &p->X); + fe_mul_tll(&trZ, &r->X, &q->yminusx); + fe_mul_tll(&trY, &r->Y, &q->yplusx); + fe_mul_tlt(&trT, &q->xy2d, &p->T); + fe_add(&r->T, &p->Z, &p->Z); + fe_sub(&r->X, &trZ, &trY); + fe_add(&r->Y, &trZ, &trY); + fe_carry(&trZ, &r->T); + fe_sub(&r->Z, &trZ, &trT); + fe_add(&r->T, &trZ, &trT); +} + +// r = p + q +void x25519_ge_add(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q) { + fe trX, trY, trZ, trT; + + fe_add(&r->X, &p->Y, &p->X); + fe_sub(&r->Y, &p->Y, &p->X); + fe_mul_tll(&trZ, &r->X, &q->YplusX); + fe_mul_tll(&trY, &r->Y, &q->YminusX); + fe_mul_tlt(&trT, &q->T2d, &p->T); + fe_mul_ttl(&trX, &p->Z, &q->Z); + fe_add(&r->T, &trX, &trX); + fe_sub(&r->X, &trZ, &trY); + fe_add(&r->Y, &trZ, &trY); + fe_carry(&trZ, &r->T); + fe_add(&r->Z, &trZ, &trT); + fe_sub(&r->T, &trZ, &trT); +} + +// r = p - q +void x25519_ge_sub(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q) { + fe trX, trY, trZ, trT; + + fe_add(&r->X, &p->Y, &p->X); + fe_sub(&r->Y, &p->Y, &p->X); + fe_mul_tll(&trZ, &r->X, &q->YminusX); + fe_mul_tll(&trY, &r->Y, &q->YplusX); + fe_mul_tlt(&trT, &q->T2d, &p->T); + fe_mul_ttl(&trX, &p->Z, &q->Z); + fe_add(&r->T, &trX, &trX); + fe_sub(&r->X, &trZ, &trY); + fe_add(&r->Y, &trZ, &trY); + fe_carry(&trZ, &r->T); + fe_sub(&r->Z, &trZ, &trT); + fe_add(&r->T, &trZ, &trT); +} + +static uint8_t equal(signed char b, signed char c) { + uint8_t ub = b; + uint8_t uc = c; + uint8_t x = ub ^ uc; // 0: yes; 1..255: no + uint32_t y = x; // 0: yes; 1..255: no + y -= 1; // 4294967295: yes; 0..254: no + y >>= 31; // 1: yes; 0: no + return y; +} + +static void cmov(ge_precomp *t, const ge_precomp *u, uint8_t b) { + fe_cmov(&t->yplusx, &u->yplusx, b); + fe_cmov(&t->yminusx, &u->yminusx, b); + fe_cmov(&t->xy2d, &u->xy2d, b); +} + +void x25519_ge_scalarmult_small_precomp( + ge_p3 *h, const uint8_t a[32], const uint8_t precomp_table[15 * 2 * 32]) { + // precomp_table is first expanded into matching |ge_precomp| + // elements. + ge_precomp multiples[15]; + + unsigned i; + for (i = 0; i < 15; i++) { + const uint8_t *bytes = &precomp_table[i*(2 * 32)]; + fe x, y; + fe_frombytes(&x, bytes); + fe_frombytes(&y, bytes + 32); + + ge_precomp *out = &multiples[i]; + fe_add(&out->yplusx, &y, &x); + fe_sub(&out->yminusx, &y, &x); + fe_mul_ltt(&out->xy2d, &x, &y); + fe_mul_llt(&out->xy2d, &out->xy2d, &d2); + } + + // See the comment above |k25519SmallPrecomp| about the structure of the + // precomputed elements. This loop does 64 additions and 64 doublings to + // calculate the result. + ge_p3_0(h); + + for (i = 63; i < 64; i--) { + unsigned j; + signed char index = 0; + + for (j = 0; j < 4; j++) { + const uint8_t bit = 1 & (a[(8 * j) + (i / 8)] >> (i & 7)); + index |= (bit << j); + } + + ge_precomp e; + ge_precomp_0(&e); + + for (j = 1; j < 16; j++) { + cmov(&e, &multiples[j-1], equal(index, j)); + } + + ge_cached cached; + ge_p1p1 r; + x25519_ge_p3_to_cached(&cached, h); + x25519_ge_add(&r, h, &cached); + x25519_ge_p1p1_to_p3(h, &r); + + ge_madd(&r, h, &e); + x25519_ge_p1p1_to_p3(h, &r); + } +} + +#if defined(OPENSSL_SMALL) + +void x25519_ge_scalarmult_base(ge_p3 *h, const uint8_t a[32]) { + x25519_ge_scalarmult_small_precomp(h, a, k25519SmallPrecomp); +} + +#else + +static uint8_t negative(signed char b) { + uint32_t x = b; + x >>= 31; // 1: yes; 0: no + return x; +} + +static void table_select(ge_precomp *t, int pos, signed char b) { + ge_precomp minust; + uint8_t bnegative = negative(b); + uint8_t babs = b - ((uint8_t)((-bnegative) & b) << 1); + + ge_precomp_0(t); + cmov(t, &k25519Precomp[pos][0], equal(babs, 1)); + cmov(t, &k25519Precomp[pos][1], equal(babs, 2)); + cmov(t, &k25519Precomp[pos][2], equal(babs, 3)); + cmov(t, &k25519Precomp[pos][3], equal(babs, 4)); + cmov(t, &k25519Precomp[pos][4], equal(babs, 5)); + cmov(t, &k25519Precomp[pos][5], equal(babs, 6)); + cmov(t, &k25519Precomp[pos][6], equal(babs, 7)); + cmov(t, &k25519Precomp[pos][7], equal(babs, 8)); + fe_copy_ll(&minust.yplusx, &t->yminusx); + fe_copy_ll(&minust.yminusx, &t->yplusx); + + // NOTE: the input table is canonical, but types don't encode it + fe tmp; + fe_carry(&tmp, &t->xy2d); + fe_neg(&minust.xy2d, &tmp); + + cmov(t, &minust, bnegative); +} + +// h = a * B +// where a = a[0]+256*a[1]+...+256^31 a[31] +// B is the Ed25519 base point (x,4/5) with x positive. +// +// Preconditions: +// a[31] <= 127 +void x25519_ge_scalarmult_base(ge_p3 *h, const uint8_t *a) { + signed char e[64]; + signed char carry; + ge_p1p1 r; + ge_p2 s; + ge_precomp t; + int i; + + for (i = 0; i < 32; ++i) { + e[2 * i + 0] = (a[i] >> 0) & 15; + e[2 * i + 1] = (a[i] >> 4) & 15; + } + // each e[i] is between 0 and 15 + // e[63] is between 0 and 7 + + carry = 0; + for (i = 0; i < 63; ++i) { + e[i] += carry; + carry = e[i] + 8; + carry >>= 4; + e[i] -= carry << 4; + } + e[63] += carry; + // each e[i] is between -8 and 8 + + ge_p3_0(h); + for (i = 1; i < 64; i += 2) { + table_select(&t, i / 2, e[i]); + ge_madd(&r, h, &t); + x25519_ge_p1p1_to_p3(h, &r); + } + + ge_p3_dbl(&r, h); + x25519_ge_p1p1_to_p2(&s, &r); + ge_p2_dbl(&r, &s); + x25519_ge_p1p1_to_p2(&s, &r); + ge_p2_dbl(&r, &s); + x25519_ge_p1p1_to_p2(&s, &r); + ge_p2_dbl(&r, &s); + x25519_ge_p1p1_to_p3(h, &r); + + for (i = 0; i < 64; i += 2) { + table_select(&t, i / 2, e[i]); + ge_madd(&r, h, &t); + x25519_ge_p1p1_to_p3(h, &r); + } +} + +#endif + +static void cmov_cached(ge_cached *t, ge_cached *u, uint8_t b) { + fe_cmov(&t->YplusX, &u->YplusX, b); + fe_cmov(&t->YminusX, &u->YminusX, b); + fe_cmov(&t->Z, &u->Z, b); + fe_cmov(&t->T2d, &u->T2d, b); +} + +// r = scalar * A. +// where a = a[0]+256*a[1]+...+256^31 a[31]. +void x25519_ge_scalarmult(ge_p2 *r, const uint8_t *scalar, const ge_p3 *A) { + ge_p2 Ai_p2[8]; + ge_cached Ai[16]; + ge_p1p1 t; + + ge_cached_0(&Ai[0]); + x25519_ge_p3_to_cached(&Ai[1], A); + ge_p3_to_p2(&Ai_p2[1], A); + + unsigned i; + for (i = 2; i < 16; i += 2) { + ge_p2_dbl(&t, &Ai_p2[i / 2]); + ge_p1p1_to_cached(&Ai[i], &t); + if (i < 8) { + x25519_ge_p1p1_to_p2(&Ai_p2[i], &t); + } + x25519_ge_add(&t, A, &Ai[i]); + ge_p1p1_to_cached(&Ai[i + 1], &t); + if (i < 7) { + x25519_ge_p1p1_to_p2(&Ai_p2[i + 1], &t); + } + } + + ge_p2_0(r); + ge_p3 u; + + for (i = 0; i < 256; i += 4) { + ge_p2_dbl(&t, r); + x25519_ge_p1p1_to_p2(r, &t); + ge_p2_dbl(&t, r); + x25519_ge_p1p1_to_p2(r, &t); + ge_p2_dbl(&t, r); + x25519_ge_p1p1_to_p2(r, &t); + ge_p2_dbl(&t, r); + x25519_ge_p1p1_to_p3(&u, &t); + + uint8_t index = scalar[31 - i/8]; + index >>= 4 - (i & 4); + index &= 0xf; + + unsigned j; + ge_cached selected; + ge_cached_0(&selected); + for (j = 0; j < 16; j++) { + cmov_cached(&selected, &Ai[j], equal(j, index)); + } + + x25519_ge_add(&t, &u, &selected); + x25519_ge_p1p1_to_p2(r, &t); + } +} + +static void slide(signed char *r, const uint8_t *a) { + int i; + int b; + int k; + + for (i = 0; i < 256; ++i) { + r[i] = 1 & (a[i >> 3] >> (i & 7)); + } + + for (i = 0; i < 256; ++i) { + if (r[i]) { + for (b = 1; b <= 6 && i + b < 256; ++b) { + if (r[i + b]) { + if (r[i] + (r[i + b] << b) <= 15) { + r[i] += r[i + b] << b; + r[i + b] = 0; + } else if (r[i] - (r[i + b] << b) >= -15) { + r[i] -= r[i + b] << b; + for (k = i + b; k < 256; ++k) { + if (!r[k]) { + r[k] = 1; + break; + } + r[k] = 0; + } + } else { + break; + } + } + } + } + } +} + +// r = a * A + b * B +// where a = a[0]+256*a[1]+...+256^31 a[31]. +// and b = b[0]+256*b[1]+...+256^31 b[31]. +// B is the Ed25519 base point (x,4/5) with x positive. +static void ge_double_scalarmult_vartime(ge_p2 *r, const uint8_t *a, + const ge_p3 *A, const uint8_t *b) { + signed char aslide[256]; + signed char bslide[256]; + ge_cached Ai[8]; // A,3A,5A,7A,9A,11A,13A,15A + ge_p1p1 t; + ge_p3 u; + ge_p3 A2; + int i; + + slide(aslide, a); + slide(bslide, b); + + x25519_ge_p3_to_cached(&Ai[0], A); + ge_p3_dbl(&t, A); + x25519_ge_p1p1_to_p3(&A2, &t); + x25519_ge_add(&t, &A2, &Ai[0]); + x25519_ge_p1p1_to_p3(&u, &t); + x25519_ge_p3_to_cached(&Ai[1], &u); + x25519_ge_add(&t, &A2, &Ai[1]); + x25519_ge_p1p1_to_p3(&u, &t); + x25519_ge_p3_to_cached(&Ai[2], &u); + x25519_ge_add(&t, &A2, &Ai[2]); + x25519_ge_p1p1_to_p3(&u, &t); + x25519_ge_p3_to_cached(&Ai[3], &u); + x25519_ge_add(&t, &A2, &Ai[3]); + x25519_ge_p1p1_to_p3(&u, &t); + x25519_ge_p3_to_cached(&Ai[4], &u); + x25519_ge_add(&t, &A2, &Ai[4]); + x25519_ge_p1p1_to_p3(&u, &t); + x25519_ge_p3_to_cached(&Ai[5], &u); + x25519_ge_add(&t, &A2, &Ai[5]); + x25519_ge_p1p1_to_p3(&u, &t); + x25519_ge_p3_to_cached(&Ai[6], &u); + x25519_ge_add(&t, &A2, &Ai[6]); + x25519_ge_p1p1_to_p3(&u, &t); + x25519_ge_p3_to_cached(&Ai[7], &u); + + ge_p2_0(r); + + for (i = 255; i >= 0; --i) { + if (aslide[i] || bslide[i]) { + break; + } + } + + for (; i >= 0; --i) { + ge_p2_dbl(&t, r); + + if (aslide[i] > 0) { + x25519_ge_p1p1_to_p3(&u, &t); + x25519_ge_add(&t, &u, &Ai[aslide[i] / 2]); + } else if (aslide[i] < 0) { + x25519_ge_p1p1_to_p3(&u, &t); + x25519_ge_sub(&t, &u, &Ai[(-aslide[i]) / 2]); + } + + if (bslide[i] > 0) { + x25519_ge_p1p1_to_p3(&u, &t); + ge_madd(&t, &u, &Bi[bslide[i] / 2]); + } else if (bslide[i] < 0) { + x25519_ge_p1p1_to_p3(&u, &t); + ge_msub(&t, &u, &Bi[(-bslide[i]) / 2]); + } + + x25519_ge_p1p1_to_p2(r, &t); + } +} + +// The set of scalars is \Z/l +// where l = 2^252 + 27742317777372353535851937790883648493. + +// Input: +// s[0]+256*s[1]+...+256^63*s[63] = s +// +// Output: +// s[0]+256*s[1]+...+256^31*s[31] = s mod l +// where l = 2^252 + 27742317777372353535851937790883648493. +// Overwrites s in place. +void x25519_sc_reduce(uint8_t s[64]) { + int64_t s0 = 2097151 & load_3(s); + int64_t s1 = 2097151 & (load_4(s + 2) >> 5); + int64_t s2 = 2097151 & (load_3(s + 5) >> 2); + int64_t s3 = 2097151 & (load_4(s + 7) >> 7); + int64_t s4 = 2097151 & (load_4(s + 10) >> 4); + int64_t s5 = 2097151 & (load_3(s + 13) >> 1); + int64_t s6 = 2097151 & (load_4(s + 15) >> 6); + int64_t s7 = 2097151 & (load_3(s + 18) >> 3); + int64_t s8 = 2097151 & load_3(s + 21); + int64_t s9 = 2097151 & (load_4(s + 23) >> 5); + int64_t s10 = 2097151 & (load_3(s + 26) >> 2); + int64_t s11 = 2097151 & (load_4(s + 28) >> 7); + int64_t s12 = 2097151 & (load_4(s + 31) >> 4); + int64_t s13 = 2097151 & (load_3(s + 34) >> 1); + int64_t s14 = 2097151 & (load_4(s + 36) >> 6); + int64_t s15 = 2097151 & (load_3(s + 39) >> 3); + int64_t s16 = 2097151 & load_3(s + 42); + int64_t s17 = 2097151 & (load_4(s + 44) >> 5); + int64_t s18 = 2097151 & (load_3(s + 47) >> 2); + int64_t s19 = 2097151 & (load_4(s + 49) >> 7); + int64_t s20 = 2097151 & (load_4(s + 52) >> 4); + int64_t s21 = 2097151 & (load_3(s + 55) >> 1); + int64_t s22 = 2097151 & (load_4(s + 57) >> 6); + int64_t s23 = (load_4(s + 60) >> 3); + int64_t carry0; + int64_t carry1; + int64_t carry2; + int64_t carry3; + int64_t carry4; + int64_t carry5; + int64_t carry6; + int64_t carry7; + int64_t carry8; + int64_t carry9; + int64_t carry10; + int64_t carry11; + int64_t carry12; + int64_t carry13; + int64_t carry14; + int64_t carry15; + int64_t carry16; + + s11 += s23 * 666643; + s12 += s23 * 470296; + s13 += s23 * 654183; + s14 -= s23 * 997805; + s15 += s23 * 136657; + s16 -= s23 * 683901; + s23 = 0; + + s10 += s22 * 666643; + s11 += s22 * 470296; + s12 += s22 * 654183; + s13 -= s22 * 997805; + s14 += s22 * 136657; + s15 -= s22 * 683901; + s22 = 0; + + s9 += s21 * 666643; + s10 += s21 * 470296; + s11 += s21 * 654183; + s12 -= s21 * 997805; + s13 += s21 * 136657; + s14 -= s21 * 683901; + s21 = 0; + + s8 += s20 * 666643; + s9 += s20 * 470296; + s10 += s20 * 654183; + s11 -= s20 * 997805; + s12 += s20 * 136657; + s13 -= s20 * 683901; + s20 = 0; + + s7 += s19 * 666643; + s8 += s19 * 470296; + s9 += s19 * 654183; + s10 -= s19 * 997805; + s11 += s19 * 136657; + s12 -= s19 * 683901; + s19 = 0; + + s6 += s18 * 666643; + s7 += s18 * 470296; + s8 += s18 * 654183; + s9 -= s18 * 997805; + s10 += s18 * 136657; + s11 -= s18 * 683901; + s18 = 0; + + carry6 = (s6 + (1 << 20)) >> 21; + s7 += carry6; + s6 -= carry6 << 21; + carry8 = (s8 + (1 << 20)) >> 21; + s9 += carry8; + s8 -= carry8 << 21; + carry10 = (s10 + (1 << 20)) >> 21; + s11 += carry10; + s10 -= carry10 << 21; + carry12 = (s12 + (1 << 20)) >> 21; + s13 += carry12; + s12 -= carry12 << 21; + carry14 = (s14 + (1 << 20)) >> 21; + s15 += carry14; + s14 -= carry14 << 21; + carry16 = (s16 + (1 << 20)) >> 21; + s17 += carry16; + s16 -= carry16 << 21; + + carry7 = (s7 + (1 << 20)) >> 21; + s8 += carry7; + s7 -= carry7 << 21; + carry9 = (s9 + (1 << 20)) >> 21; + s10 += carry9; + s9 -= carry9 << 21; + carry11 = (s11 + (1 << 20)) >> 21; + s12 += carry11; + s11 -= carry11 << 21; + carry13 = (s13 + (1 << 20)) >> 21; + s14 += carry13; + s13 -= carry13 << 21; + carry15 = (s15 + (1 << 20)) >> 21; + s16 += carry15; + s15 -= carry15 << 21; + + s5 += s17 * 666643; + s6 += s17 * 470296; + s7 += s17 * 654183; + s8 -= s17 * 997805; + s9 += s17 * 136657; + s10 -= s17 * 683901; + s17 = 0; + + s4 += s16 * 666643; + s5 += s16 * 470296; + s6 += s16 * 654183; + s7 -= s16 * 997805; + s8 += s16 * 136657; + s9 -= s16 * 683901; + s16 = 0; + + s3 += s15 * 666643; + s4 += s15 * 470296; + s5 += s15 * 654183; + s6 -= s15 * 997805; + s7 += s15 * 136657; + s8 -= s15 * 683901; + s15 = 0; + + s2 += s14 * 666643; + s3 += s14 * 470296; + s4 += s14 * 654183; + s5 -= s14 * 997805; + s6 += s14 * 136657; + s7 -= s14 * 683901; + s14 = 0; + + s1 += s13 * 666643; + s2 += s13 * 470296; + s3 += s13 * 654183; + s4 -= s13 * 997805; + s5 += s13 * 136657; + s6 -= s13 * 683901; + s13 = 0; + + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + s12 = 0; + + carry0 = (s0 + (1 << 20)) >> 21; + s1 += carry0; + s0 -= carry0 << 21; + carry2 = (s2 + (1 << 20)) >> 21; + s3 += carry2; + s2 -= carry2 << 21; + carry4 = (s4 + (1 << 20)) >> 21; + s5 += carry4; + s4 -= carry4 << 21; + carry6 = (s6 + (1 << 20)) >> 21; + s7 += carry6; + s6 -= carry6 << 21; + carry8 = (s8 + (1 << 20)) >> 21; + s9 += carry8; + s8 -= carry8 << 21; + carry10 = (s10 + (1 << 20)) >> 21; + s11 += carry10; + s10 -= carry10 << 21; + + carry1 = (s1 + (1 << 20)) >> 21; + s2 += carry1; + s1 -= carry1 << 21; + carry3 = (s3 + (1 << 20)) >> 21; + s4 += carry3; + s3 -= carry3 << 21; + carry5 = (s5 + (1 << 20)) >> 21; + s6 += carry5; + s5 -= carry5 << 21; + carry7 = (s7 + (1 << 20)) >> 21; + s8 += carry7; + s7 -= carry7 << 21; + carry9 = (s9 + (1 << 20)) >> 21; + s10 += carry9; + s9 -= carry9 << 21; + carry11 = (s11 + (1 << 20)) >> 21; + s12 += carry11; + s11 -= carry11 << 21; + + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + s12 = 0; + + carry0 = s0 >> 21; + s1 += carry0; + s0 -= carry0 << 21; + carry1 = s1 >> 21; + s2 += carry1; + s1 -= carry1 << 21; + carry2 = s2 >> 21; + s3 += carry2; + s2 -= carry2 << 21; + carry3 = s3 >> 21; + s4 += carry3; + s3 -= carry3 << 21; + carry4 = s4 >> 21; + s5 += carry4; + s4 -= carry4 << 21; + carry5 = s5 >> 21; + s6 += carry5; + s5 -= carry5 << 21; + carry6 = s6 >> 21; + s7 += carry6; + s6 -= carry6 << 21; + carry7 = s7 >> 21; + s8 += carry7; + s7 -= carry7 << 21; + carry8 = s8 >> 21; + s9 += carry8; + s8 -= carry8 << 21; + carry9 = s9 >> 21; + s10 += carry9; + s9 -= carry9 << 21; + carry10 = s10 >> 21; + s11 += carry10; + s10 -= carry10 << 21; + carry11 = s11 >> 21; + s12 += carry11; + s11 -= carry11 << 21; + + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + s12 = 0; + + carry0 = s0 >> 21; + s1 += carry0; + s0 -= carry0 << 21; + carry1 = s1 >> 21; + s2 += carry1; + s1 -= carry1 << 21; + carry2 = s2 >> 21; + s3 += carry2; + s2 -= carry2 << 21; + carry3 = s3 >> 21; + s4 += carry3; + s3 -= carry3 << 21; + carry4 = s4 >> 21; + s5 += carry4; + s4 -= carry4 << 21; + carry5 = s5 >> 21; + s6 += carry5; + s5 -= carry5 << 21; + carry6 = s6 >> 21; + s7 += carry6; + s6 -= carry6 << 21; + carry7 = s7 >> 21; + s8 += carry7; + s7 -= carry7 << 21; + carry8 = s8 >> 21; + s9 += carry8; + s8 -= carry8 << 21; + carry9 = s9 >> 21; + s10 += carry9; + s9 -= carry9 << 21; + carry10 = s10 >> 21; + s11 += carry10; + s10 -= carry10 << 21; + + s[0] = s0 >> 0; + s[1] = s0 >> 8; + s[2] = (s0 >> 16) | (s1 << 5); + s[3] = s1 >> 3; + s[4] = s1 >> 11; + s[5] = (s1 >> 19) | (s2 << 2); + s[6] = s2 >> 6; + s[7] = (s2 >> 14) | (s3 << 7); + s[8] = s3 >> 1; + s[9] = s3 >> 9; + s[10] = (s3 >> 17) | (s4 << 4); + s[11] = s4 >> 4; + s[12] = s4 >> 12; + s[13] = (s4 >> 20) | (s5 << 1); + s[14] = s5 >> 7; + s[15] = (s5 >> 15) | (s6 << 6); + s[16] = s6 >> 2; + s[17] = s6 >> 10; + s[18] = (s6 >> 18) | (s7 << 3); + s[19] = s7 >> 5; + s[20] = s7 >> 13; + s[21] = s8 >> 0; + s[22] = s8 >> 8; + s[23] = (s8 >> 16) | (s9 << 5); + s[24] = s9 >> 3; + s[25] = s9 >> 11; + s[26] = (s9 >> 19) | (s10 << 2); + s[27] = s10 >> 6; + s[28] = (s10 >> 14) | (s11 << 7); + s[29] = s11 >> 1; + s[30] = s11 >> 9; + s[31] = s11 >> 17; +} + +// Input: +// a[0]+256*a[1]+...+256^31*a[31] = a +// b[0]+256*b[1]+...+256^31*b[31] = b +// c[0]+256*c[1]+...+256^31*c[31] = c +// +// Output: +// s[0]+256*s[1]+...+256^31*s[31] = (ab+c) mod l +// where l = 2^252 + 27742317777372353535851937790883648493. +static void sc_muladd(uint8_t *s, const uint8_t *a, const uint8_t *b, + const uint8_t *c) { + int64_t a0 = 2097151 & load_3(a); + int64_t a1 = 2097151 & (load_4(a + 2) >> 5); + int64_t a2 = 2097151 & (load_3(a + 5) >> 2); + int64_t a3 = 2097151 & (load_4(a + 7) >> 7); + int64_t a4 = 2097151 & (load_4(a + 10) >> 4); + int64_t a5 = 2097151 & (load_3(a + 13) >> 1); + int64_t a6 = 2097151 & (load_4(a + 15) >> 6); + int64_t a7 = 2097151 & (load_3(a + 18) >> 3); + int64_t a8 = 2097151 & load_3(a + 21); + int64_t a9 = 2097151 & (load_4(a + 23) >> 5); + int64_t a10 = 2097151 & (load_3(a + 26) >> 2); + int64_t a11 = (load_4(a + 28) >> 7); + int64_t b0 = 2097151 & load_3(b); + int64_t b1 = 2097151 & (load_4(b + 2) >> 5); + int64_t b2 = 2097151 & (load_3(b + 5) >> 2); + int64_t b3 = 2097151 & (load_4(b + 7) >> 7); + int64_t b4 = 2097151 & (load_4(b + 10) >> 4); + int64_t b5 = 2097151 & (load_3(b + 13) >> 1); + int64_t b6 = 2097151 & (load_4(b + 15) >> 6); + int64_t b7 = 2097151 & (load_3(b + 18) >> 3); + int64_t b8 = 2097151 & load_3(b + 21); + int64_t b9 = 2097151 & (load_4(b + 23) >> 5); + int64_t b10 = 2097151 & (load_3(b + 26) >> 2); + int64_t b11 = (load_4(b + 28) >> 7); + int64_t c0 = 2097151 & load_3(c); + int64_t c1 = 2097151 & (load_4(c + 2) >> 5); + int64_t c2 = 2097151 & (load_3(c + 5) >> 2); + int64_t c3 = 2097151 & (load_4(c + 7) >> 7); + int64_t c4 = 2097151 & (load_4(c + 10) >> 4); + int64_t c5 = 2097151 & (load_3(c + 13) >> 1); + int64_t c6 = 2097151 & (load_4(c + 15) >> 6); + int64_t c7 = 2097151 & (load_3(c + 18) >> 3); + int64_t c8 = 2097151 & load_3(c + 21); + int64_t c9 = 2097151 & (load_4(c + 23) >> 5); + int64_t c10 = 2097151 & (load_3(c + 26) >> 2); + int64_t c11 = (load_4(c + 28) >> 7); + int64_t s0; + int64_t s1; + int64_t s2; + int64_t s3; + int64_t s4; + int64_t s5; + int64_t s6; + int64_t s7; + int64_t s8; + int64_t s9; + int64_t s10; + int64_t s11; + int64_t s12; + int64_t s13; + int64_t s14; + int64_t s15; + int64_t s16; + int64_t s17; + int64_t s18; + int64_t s19; + int64_t s20; + int64_t s21; + int64_t s22; + int64_t s23; + int64_t carry0; + int64_t carry1; + int64_t carry2; + int64_t carry3; + int64_t carry4; + int64_t carry5; + int64_t carry6; + int64_t carry7; + int64_t carry8; + int64_t carry9; + int64_t carry10; + int64_t carry11; + int64_t carry12; + int64_t carry13; + int64_t carry14; + int64_t carry15; + int64_t carry16; + int64_t carry17; + int64_t carry18; + int64_t carry19; + int64_t carry20; + int64_t carry21; + int64_t carry22; + + s0 = c0 + a0 * b0; + s1 = c1 + a0 * b1 + a1 * b0; + s2 = c2 + a0 * b2 + a1 * b1 + a2 * b0; + s3 = c3 + a0 * b3 + a1 * b2 + a2 * b1 + a3 * b0; + s4 = c4 + a0 * b4 + a1 * b3 + a2 * b2 + a3 * b1 + a4 * b0; + s5 = c5 + a0 * b5 + a1 * b4 + a2 * b3 + a3 * b2 + a4 * b1 + a5 * b0; + s6 = c6 + a0 * b6 + a1 * b5 + a2 * b4 + a3 * b3 + a4 * b2 + a5 * b1 + a6 * b0; + s7 = c7 + a0 * b7 + a1 * b6 + a2 * b5 + a3 * b4 + a4 * b3 + a5 * b2 + + a6 * b1 + a7 * b0; + s8 = c8 + a0 * b8 + a1 * b7 + a2 * b6 + a3 * b5 + a4 * b4 + a5 * b3 + + a6 * b2 + a7 * b1 + a8 * b0; + s9 = c9 + a0 * b9 + a1 * b8 + a2 * b7 + a3 * b6 + a4 * b5 + a5 * b4 + + a6 * b3 + a7 * b2 + a8 * b1 + a9 * b0; + s10 = c10 + a0 * b10 + a1 * b9 + a2 * b8 + a3 * b7 + a4 * b6 + a5 * b5 + + a6 * b4 + a7 * b3 + a8 * b2 + a9 * b1 + a10 * b0; + s11 = c11 + a0 * b11 + a1 * b10 + a2 * b9 + a3 * b8 + a4 * b7 + a5 * b6 + + a6 * b5 + a7 * b4 + a8 * b3 + a9 * b2 + a10 * b1 + a11 * b0; + s12 = a1 * b11 + a2 * b10 + a3 * b9 + a4 * b8 + a5 * b7 + a6 * b6 + a7 * b5 + + a8 * b4 + a9 * b3 + a10 * b2 + a11 * b1; + s13 = a2 * b11 + a3 * b10 + a4 * b9 + a5 * b8 + a6 * b7 + a7 * b6 + a8 * b5 + + a9 * b4 + a10 * b3 + a11 * b2; + s14 = a3 * b11 + a4 * b10 + a5 * b9 + a6 * b8 + a7 * b7 + a8 * b6 + a9 * b5 + + a10 * b4 + a11 * b3; + s15 = a4 * b11 + a5 * b10 + a6 * b9 + a7 * b8 + a8 * b7 + a9 * b6 + a10 * b5 + + a11 * b4; + s16 = a5 * b11 + a6 * b10 + a7 * b9 + a8 * b8 + a9 * b7 + a10 * b6 + a11 * b5; + s17 = a6 * b11 + a7 * b10 + a8 * b9 + a9 * b8 + a10 * b7 + a11 * b6; + s18 = a7 * b11 + a8 * b10 + a9 * b9 + a10 * b8 + a11 * b7; + s19 = a8 * b11 + a9 * b10 + a10 * b9 + a11 * b8; + s20 = a9 * b11 + a10 * b10 + a11 * b9; + s21 = a10 * b11 + a11 * b10; + s22 = a11 * b11; + s23 = 0; + + carry0 = (s0 + (1 << 20)) >> 21; + s1 += carry0; + s0 -= carry0 << 21; + carry2 = (s2 + (1 << 20)) >> 21; + s3 += carry2; + s2 -= carry2 << 21; + carry4 = (s4 + (1 << 20)) >> 21; + s5 += carry4; + s4 -= carry4 << 21; + carry6 = (s6 + (1 << 20)) >> 21; + s7 += carry6; + s6 -= carry6 << 21; + carry8 = (s8 + (1 << 20)) >> 21; + s9 += carry8; + s8 -= carry8 << 21; + carry10 = (s10 + (1 << 20)) >> 21; + s11 += carry10; + s10 -= carry10 << 21; + carry12 = (s12 + (1 << 20)) >> 21; + s13 += carry12; + s12 -= carry12 << 21; + carry14 = (s14 + (1 << 20)) >> 21; + s15 += carry14; + s14 -= carry14 << 21; + carry16 = (s16 + (1 << 20)) >> 21; + s17 += carry16; + s16 -= carry16 << 21; + carry18 = (s18 + (1 << 20)) >> 21; + s19 += carry18; + s18 -= carry18 << 21; + carry20 = (s20 + (1 << 20)) >> 21; + s21 += carry20; + s20 -= carry20 << 21; + carry22 = (s22 + (1 << 20)) >> 21; + s23 += carry22; + s22 -= carry22 << 21; + + carry1 = (s1 + (1 << 20)) >> 21; + s2 += carry1; + s1 -= carry1 << 21; + carry3 = (s3 + (1 << 20)) >> 21; + s4 += carry3; + s3 -= carry3 << 21; + carry5 = (s5 + (1 << 20)) >> 21; + s6 += carry5; + s5 -= carry5 << 21; + carry7 = (s7 + (1 << 20)) >> 21; + s8 += carry7; + s7 -= carry7 << 21; + carry9 = (s9 + (1 << 20)) >> 21; + s10 += carry9; + s9 -= carry9 << 21; + carry11 = (s11 + (1 << 20)) >> 21; + s12 += carry11; + s11 -= carry11 << 21; + carry13 = (s13 + (1 << 20)) >> 21; + s14 += carry13; + s13 -= carry13 << 21; + carry15 = (s15 + (1 << 20)) >> 21; + s16 += carry15; + s15 -= carry15 << 21; + carry17 = (s17 + (1 << 20)) >> 21; + s18 += carry17; + s17 -= carry17 << 21; + carry19 = (s19 + (1 << 20)) >> 21; + s20 += carry19; + s19 -= carry19 << 21; + carry21 = (s21 + (1 << 20)) >> 21; + s22 += carry21; + s21 -= carry21 << 21; + + s11 += s23 * 666643; + s12 += s23 * 470296; + s13 += s23 * 654183; + s14 -= s23 * 997805; + s15 += s23 * 136657; + s16 -= s23 * 683901; + s23 = 0; + + s10 += s22 * 666643; + s11 += s22 * 470296; + s12 += s22 * 654183; + s13 -= s22 * 997805; + s14 += s22 * 136657; + s15 -= s22 * 683901; + s22 = 0; + + s9 += s21 * 666643; + s10 += s21 * 470296; + s11 += s21 * 654183; + s12 -= s21 * 997805; + s13 += s21 * 136657; + s14 -= s21 * 683901; + s21 = 0; + + s8 += s20 * 666643; + s9 += s20 * 470296; + s10 += s20 * 654183; + s11 -= s20 * 997805; + s12 += s20 * 136657; + s13 -= s20 * 683901; + s20 = 0; + + s7 += s19 * 666643; + s8 += s19 * 470296; + s9 += s19 * 654183; + s10 -= s19 * 997805; + s11 += s19 * 136657; + s12 -= s19 * 683901; + s19 = 0; + + s6 += s18 * 666643; + s7 += s18 * 470296; + s8 += s18 * 654183; + s9 -= s18 * 997805; + s10 += s18 * 136657; + s11 -= s18 * 683901; + s18 = 0; + + carry6 = (s6 + (1 << 20)) >> 21; + s7 += carry6; + s6 -= carry6 << 21; + carry8 = (s8 + (1 << 20)) >> 21; + s9 += carry8; + s8 -= carry8 << 21; + carry10 = (s10 + (1 << 20)) >> 21; + s11 += carry10; + s10 -= carry10 << 21; + carry12 = (s12 + (1 << 20)) >> 21; + s13 += carry12; + s12 -= carry12 << 21; + carry14 = (s14 + (1 << 20)) >> 21; + s15 += carry14; + s14 -= carry14 << 21; + carry16 = (s16 + (1 << 20)) >> 21; + s17 += carry16; + s16 -= carry16 << 21; + + carry7 = (s7 + (1 << 20)) >> 21; + s8 += carry7; + s7 -= carry7 << 21; + carry9 = (s9 + (1 << 20)) >> 21; + s10 += carry9; + s9 -= carry9 << 21; + carry11 = (s11 + (1 << 20)) >> 21; + s12 += carry11; + s11 -= carry11 << 21; + carry13 = (s13 + (1 << 20)) >> 21; + s14 += carry13; + s13 -= carry13 << 21; + carry15 = (s15 + (1 << 20)) >> 21; + s16 += carry15; + s15 -= carry15 << 21; + + s5 += s17 * 666643; + s6 += s17 * 470296; + s7 += s17 * 654183; + s8 -= s17 * 997805; + s9 += s17 * 136657; + s10 -= s17 * 683901; + s17 = 0; + + s4 += s16 * 666643; + s5 += s16 * 470296; + s6 += s16 * 654183; + s7 -= s16 * 997805; + s8 += s16 * 136657; + s9 -= s16 * 683901; + s16 = 0; + + s3 += s15 * 666643; + s4 += s15 * 470296; + s5 += s15 * 654183; + s6 -= s15 * 997805; + s7 += s15 * 136657; + s8 -= s15 * 683901; + s15 = 0; + + s2 += s14 * 666643; + s3 += s14 * 470296; + s4 += s14 * 654183; + s5 -= s14 * 997805; + s6 += s14 * 136657; + s7 -= s14 * 683901; + s14 = 0; + + s1 += s13 * 666643; + s2 += s13 * 470296; + s3 += s13 * 654183; + s4 -= s13 * 997805; + s5 += s13 * 136657; + s6 -= s13 * 683901; + s13 = 0; + + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + s12 = 0; + + carry0 = (s0 + (1 << 20)) >> 21; + s1 += carry0; + s0 -= carry0 << 21; + carry2 = (s2 + (1 << 20)) >> 21; + s3 += carry2; + s2 -= carry2 << 21; + carry4 = (s4 + (1 << 20)) >> 21; + s5 += carry4; + s4 -= carry4 << 21; + carry6 = (s6 + (1 << 20)) >> 21; + s7 += carry6; + s6 -= carry6 << 21; + carry8 = (s8 + (1 << 20)) >> 21; + s9 += carry8; + s8 -= carry8 << 21; + carry10 = (s10 + (1 << 20)) >> 21; + s11 += carry10; + s10 -= carry10 << 21; + + carry1 = (s1 + (1 << 20)) >> 21; + s2 += carry1; + s1 -= carry1 << 21; + carry3 = (s3 + (1 << 20)) >> 21; + s4 += carry3; + s3 -= carry3 << 21; + carry5 = (s5 + (1 << 20)) >> 21; + s6 += carry5; + s5 -= carry5 << 21; + carry7 = (s7 + (1 << 20)) >> 21; + s8 += carry7; + s7 -= carry7 << 21; + carry9 = (s9 + (1 << 20)) >> 21; + s10 += carry9; + s9 -= carry9 << 21; + carry11 = (s11 + (1 << 20)) >> 21; + s12 += carry11; + s11 -= carry11 << 21; + + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + s12 = 0; + + carry0 = s0 >> 21; + s1 += carry0; + s0 -= carry0 << 21; + carry1 = s1 >> 21; + s2 += carry1; + s1 -= carry1 << 21; + carry2 = s2 >> 21; + s3 += carry2; + s2 -= carry2 << 21; + carry3 = s3 >> 21; + s4 += carry3; + s3 -= carry3 << 21; + carry4 = s4 >> 21; + s5 += carry4; + s4 -= carry4 << 21; + carry5 = s5 >> 21; + s6 += carry5; + s5 -= carry5 << 21; + carry6 = s6 >> 21; + s7 += carry6; + s6 -= carry6 << 21; + carry7 = s7 >> 21; + s8 += carry7; + s7 -= carry7 << 21; + carry8 = s8 >> 21; + s9 += carry8; + s8 -= carry8 << 21; + carry9 = s9 >> 21; + s10 += carry9; + s9 -= carry9 << 21; + carry10 = s10 >> 21; + s11 += carry10; + s10 -= carry10 << 21; + carry11 = s11 >> 21; + s12 += carry11; + s11 -= carry11 << 21; + + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + s12 = 0; + + carry0 = s0 >> 21; + s1 += carry0; + s0 -= carry0 << 21; + carry1 = s1 >> 21; + s2 += carry1; + s1 -= carry1 << 21; + carry2 = s2 >> 21; + s3 += carry2; + s2 -= carry2 << 21; + carry3 = s3 >> 21; + s4 += carry3; + s3 -= carry3 << 21; + carry4 = s4 >> 21; + s5 += carry4; + s4 -= carry4 << 21; + carry5 = s5 >> 21; + s6 += carry5; + s5 -= carry5 << 21; + carry6 = s6 >> 21; + s7 += carry6; + s6 -= carry6 << 21; + carry7 = s7 >> 21; + s8 += carry7; + s7 -= carry7 << 21; + carry8 = s8 >> 21; + s9 += carry8; + s8 -= carry8 << 21; + carry9 = s9 >> 21; + s10 += carry9; + s9 -= carry9 << 21; + carry10 = s10 >> 21; + s11 += carry10; + s10 -= carry10 << 21; + + s[0] = s0 >> 0; + s[1] = s0 >> 8; + s[2] = (s0 >> 16) | (s1 << 5); + s[3] = s1 >> 3; + s[4] = s1 >> 11; + s[5] = (s1 >> 19) | (s2 << 2); + s[6] = s2 >> 6; + s[7] = (s2 >> 14) | (s3 << 7); + s[8] = s3 >> 1; + s[9] = s3 >> 9; + s[10] = (s3 >> 17) | (s4 << 4); + s[11] = s4 >> 4; + s[12] = s4 >> 12; + s[13] = (s4 >> 20) | (s5 << 1); + s[14] = s5 >> 7; + s[15] = (s5 >> 15) | (s6 << 6); + s[16] = s6 >> 2; + s[17] = s6 >> 10; + s[18] = (s6 >> 18) | (s7 << 3); + s[19] = s7 >> 5; + s[20] = s7 >> 13; + s[21] = s8 >> 0; + s[22] = s8 >> 8; + s[23] = (s8 >> 16) | (s9 << 5); + s[24] = s9 >> 3; + s[25] = s9 >> 11; + s[26] = (s9 >> 19) | (s10 << 2); + s[27] = s10 >> 6; + s[28] = (s10 >> 14) | (s11 << 7); + s[29] = s11 >> 1; + s[30] = s11 >> 9; + s[31] = s11 >> 17; +} + +void ED25519_keypair(uint8_t out_public_key[32], uint8_t out_private_key[64]) { + uint8_t seed[32]; + RAND_bytes(seed, 32); + ED25519_keypair_from_seed(out_public_key, out_private_key, seed); +} + +int ED25519_sign(uint8_t out_sig[64], const uint8_t *message, + size_t message_len, const uint8_t private_key[64]) { + uint8_t az[SHA512_DIGEST_LENGTH]; + SHA512(private_key, 32, az); + + az[0] &= 248; + az[31] &= 63; + az[31] |= 64; + + SHA512_CTX hash_ctx; + SHA512_Init(&hash_ctx); + SHA512_Update(&hash_ctx, az + 32, 32); + SHA512_Update(&hash_ctx, message, message_len); + uint8_t nonce[SHA512_DIGEST_LENGTH]; + SHA512_Final(nonce, &hash_ctx); + + x25519_sc_reduce(nonce); + ge_p3 R; + x25519_ge_scalarmult_base(&R, nonce); + ge_p3_tobytes(out_sig, &R); + + SHA512_Init(&hash_ctx); + SHA512_Update(&hash_ctx, out_sig, 32); + SHA512_Update(&hash_ctx, private_key + 32, 32); + SHA512_Update(&hash_ctx, message, message_len); + uint8_t hram[SHA512_DIGEST_LENGTH]; + SHA512_Final(hram, &hash_ctx); + + x25519_sc_reduce(hram); + sc_muladd(out_sig + 32, hram, az, nonce); + + return 1; +} + +int ED25519_verify(const uint8_t *message, size_t message_len, + const uint8_t signature[64], const uint8_t public_key[32]) { + ge_p3 A; + if ((signature[63] & 224) != 0 || + x25519_ge_frombytes_vartime(&A, public_key) != 0) { + return 0; + } + + fe_loose t; + fe_neg(&t, &A.X); + fe_carry(&A.X, &t); + fe_neg(&t, &A.T); + fe_carry(&A.T, &t); + + uint8_t pkcopy[32]; + OPENSSL_memcpy(pkcopy, public_key, 32); + uint8_t rcopy[32]; + OPENSSL_memcpy(rcopy, signature, 32); + union { + uint64_t u64[4]; + uint8_t u8[32]; + } scopy; + OPENSSL_memcpy(&scopy.u8[0], signature + 32, 32); + + // https://tools.ietf.org/html/rfc8032#section-5.1.7 requires that s be in + // the range [0, order) in order to prevent signature malleability. + + // kOrder is the order of Curve25519 in little-endian form. + static const uint64_t kOrder[4] = { + UINT64_C(0x5812631a5cf5d3ed), + UINT64_C(0x14def9dea2f79cd6), + 0, + UINT64_C(0x1000000000000000), + }; + for (size_t i = 3;; i--) { + if (scopy.u64[i] > kOrder[i]) { + return 0; + } else if (scopy.u64[i] < kOrder[i]) { + break; + } else if (i == 0) { + return 0; + } + } + + SHA512_CTX hash_ctx; + SHA512_Init(&hash_ctx); + SHA512_Update(&hash_ctx, signature, 32); + SHA512_Update(&hash_ctx, public_key, 32); + SHA512_Update(&hash_ctx, message, message_len); + uint8_t h[SHA512_DIGEST_LENGTH]; + SHA512_Final(h, &hash_ctx); + + x25519_sc_reduce(h); + + ge_p2 R; + ge_double_scalarmult_vartime(&R, h, &A, scopy.u8); + + uint8_t rcheck[32]; + x25519_ge_tobytes(rcheck, &R); + + return CRYPTO_memcmp(rcheck, rcopy, sizeof(rcheck)) == 0; +} + +void ED25519_keypair_from_seed(uint8_t out_public_key[32], + uint8_t out_private_key[64], + const uint8_t seed[32]) { + uint8_t az[SHA512_DIGEST_LENGTH]; + SHA512(seed, 32, az); + + az[0] &= 248; + az[31] &= 63; + az[31] |= 64; + + ge_p3 A; + x25519_ge_scalarmult_base(&A, az); + ge_p3_tobytes(out_public_key, &A); + + OPENSSL_memcpy(out_private_key, seed, 32); + OPENSSL_memcpy(out_private_key + 32, out_public_key, 32); +} + + +static void x25519_scalar_mult_generic(uint8_t out[32], + const uint8_t scalar[32], + const uint8_t point[32]) { + fe x1, x2, z2, x3, z3, tmp0, tmp1; + fe_loose x2l, z2l, x3l, tmp0l, tmp1l; + + uint8_t e[32]; + OPENSSL_memcpy(e, scalar, 32); + e[0] &= 248; + e[31] &= 127; + e[31] |= 64; + + // The following implementation was transcribed to Coq and proven to + // correspond to unary scalar multiplication in affine coordinates given that + // x1 != 0 is the x coordinate of some point on the curve. It was also checked + // in Coq that doing a ladderstep with x1 = x3 = 0 gives z2' = z3' = 0, and z2 + // = z3 = 0 gives z2' = z3' = 0. The statement was quantified over the + // underlying field, so it applies to Curve25519 itself and the quadratic + // twist of Curve25519. It was not proven in Coq that prime-field arithmetic + // correctly simulates extension-field arithmetic on prime-field values. + // The decoding of the byte array representation of e was not considered. + // Specification of Montgomery curves in affine coordinates: + // + // Proof that these form a group that is isomorphic to a Weierstrass curve: + // + // Coq transcription and correctness proof of the loop (where scalarbits=255): + // + // + // preconditions: 0 <= e < 2^255 (not necessarily e < order), fe_invert(0) = 0 + fe_frombytes(&x1, point); + fe_1(&x2); + fe_0(&z2); + fe_copy(&x3, &x1); + fe_1(&z3); + + unsigned swap = 0; + int pos; + for (pos = 254; pos >= 0; --pos) { + // loop invariant as of right before the test, for the case where x1 != 0: + // pos >= -1; if z2 = 0 then x2 is nonzero; if z3 = 0 then x3 is nonzero + // let r := e >> (pos+1) in the following equalities of projective points: + // to_xz (r*P) === if swap then (x3, z3) else (x2, z2) + // to_xz ((r+1)*P) === if swap then (x2, z2) else (x3, z3) + // x1 is the nonzero x coordinate of the nonzero point (r*P-(r+1)*P) + unsigned b = 1 & (e[pos / 8] >> (pos & 7)); + swap ^= b; + fe_cswap(&x2, &x3, swap); + fe_cswap(&z2, &z3, swap); + swap = b; + // Coq transcription of ladderstep formula (called from transcribed loop): + // + // + // x1 != 0 + // x1 = 0 + fe_sub(&tmp0l, &x3, &z3); + fe_sub(&tmp1l, &x2, &z2); + fe_add(&x2l, &x2, &z2); + fe_add(&z2l, &x3, &z3); + fe_mul_tll(&z3, &tmp0l, &x2l); + fe_mul_tll(&z2, &z2l, &tmp1l); + fe_sq_tl(&tmp0, &tmp1l); + fe_sq_tl(&tmp1, &x2l); + fe_add(&x3l, &z3, &z2); + fe_sub(&z2l, &z3, &z2); + fe_mul_ttt(&x2, &tmp1, &tmp0); + fe_sub(&tmp1l, &tmp1, &tmp0); + fe_sq_tl(&z2, &z2l); + fe_mul121666(&z3, &tmp1l); + fe_sq_tl(&x3, &x3l); + fe_add(&tmp0l, &tmp0, &z3); + fe_mul_ttt(&z3, &x1, &z2); + fe_mul_tll(&z2, &tmp1l, &tmp0l); + } + // here pos=-1, so r=e, so to_xz (e*P) === if swap then (x3, z3) else (x2, z2) + fe_cswap(&x2, &x3, swap); + fe_cswap(&z2, &z3, swap); + + fe_invert(&z2, &z2); + fe_mul_ttt(&x2, &x2, &z2); + fe_tobytes(out, &x2); +} + +static void x25519_scalar_mult(uint8_t out[32], const uint8_t scalar[32], + const uint8_t point[32]) { +#if defined(BORINGSSL_X25519_NEON) + if (CRYPTO_is_NEON_capable()) { + x25519_NEON(out, scalar, point); + return; + } +#endif + + x25519_scalar_mult_generic(out, scalar, point); +} + +void X25519_keypair(uint8_t out_public_value[32], uint8_t out_private_key[32]) { + RAND_bytes(out_private_key, 32); + + // All X25519 implementations should decode scalars correctly (see + // https://tools.ietf.org/html/rfc7748#section-5). However, if an + // implementation doesn't then it might interoperate with random keys a + // fraction of the time because they'll, randomly, happen to be correctly + // formed. + // + // Thus we do the opposite of the masking here to make sure that our private + // keys are never correctly masked and so, hopefully, any incorrect + // implementations are deterministically broken. + // + // This does not affect security because, although we're throwing away + // entropy, a valid implementation of scalarmult should throw away the exact + // same bits anyway. + out_private_key[0] |= 7; + out_private_key[31] &= 63; + out_private_key[31] |= 128; + + X25519_public_from_private(out_public_value, out_private_key); +} + +int X25519(uint8_t out_shared_key[32], const uint8_t private_key[32], + const uint8_t peer_public_value[32]) { + static const uint8_t kZeros[32] = {0}; + x25519_scalar_mult(out_shared_key, private_key, peer_public_value); + // The all-zero output results when the input is a point of small order. + return CRYPTO_memcmp(kZeros, out_shared_key, 32) != 0; +} + +void X25519_public_from_private(uint8_t out_public_value[32], + const uint8_t private_key[32]) { +#if defined(BORINGSSL_X25519_NEON) + if (CRYPTO_is_NEON_capable()) { + static const uint8_t kMongomeryBasePoint[32] = {9}; + x25519_NEON(out_public_value, private_key, kMongomeryBasePoint); + return; + } +#endif + + uint8_t e[32]; + OPENSSL_memcpy(e, private_key, 32); + e[0] &= 248; + e[31] &= 127; + e[31] |= 64; + + ge_p3 A; + x25519_ge_scalarmult_base(&A, e); + + // We only need the u-coordinate of the curve25519 point. The map is + // u=(y+1)/(1-y). Since y=Y/Z, this gives u=(Z+Y)/(Z-Y). + fe_loose zplusy, zminusy; + fe zminusy_inv; + fe_add(&zplusy, &A.Z, &A.Y); + fe_sub(&zminusy, &A.Z, &A.Y); + fe_loose_invert(&zminusy_inv, &zminusy); + fe_mul_tlt(&zminusy_inv, &zplusy, &zminusy_inv); + fe_tobytes(out_public_value, &zminusy_inv); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/third_party/fiat/curve25519.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/third_party/fiat/curve25519.c.grpc_back new file mode 100644 index 0000000..0fdf1d9 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/third_party/fiat/curve25519.c.grpc_back @@ -0,0 +1,3230 @@ +// The MIT License (MIT) +// +// Copyright (c) 2015-2016 the fiat-crypto authors (see the AUTHORS file). +// +// 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. + +// Some of this code is taken from the ref10 version of Ed25519 in SUPERCOP +// 20141124 (http://bench.cr.yp.to/supercop.html). That code is released as +// public domain but parts have been replaced with code generated by Fiat +// (https://github.com/mit-plv/fiat-crypto), which is MIT licensed. +// +// The field functions are shared by Ed25519 and X25519 where possible. + +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include "internal.h" +#include "../../crypto/internal.h" + + +// Various pre-computed constants. +#include "./curve25519_tables.h" + + +// Low-level intrinsic operations (hand-written). + +static uint64_t load_3(const uint8_t *in) { + uint64_t result; + result = (uint64_t)in[0]; + result |= ((uint64_t)in[1]) << 8; + result |= ((uint64_t)in[2]) << 16; + return result; +} + +static uint64_t load_4(const uint8_t *in) { + uint64_t result; + result = (uint64_t)in[0]; + result |= ((uint64_t)in[1]) << 8; + result |= ((uint64_t)in[2]) << 16; + result |= ((uint64_t)in[3]) << 24; + return result; +} + +#if defined(BORINGSSL_CURVE25519_64BIT) +static uint64_t load_8(const uint8_t *in) { + uint64_t result; + result = (uint64_t)in[0]; + result |= ((uint64_t)in[1]) << 8; + result |= ((uint64_t)in[2]) << 16; + result |= ((uint64_t)in[3]) << 24; + result |= ((uint64_t)in[4]) << 32; + result |= ((uint64_t)in[5]) << 40; + result |= ((uint64_t)in[6]) << 48; + result |= ((uint64_t)in[7]) << 56; + return result; +} + +static uint8_t /*bool*/ addcarryx_u51(uint8_t /*bool*/ c, uint64_t a, + uint64_t b, uint64_t *low) { + // This function extracts 51 bits of result and 1 bit of carry (52 total), so + // a 64-bit intermediate is sufficient. + uint64_t x = a + b + c; + *low = x & ((UINT64_C(1) << 51) - 1); + return (x >> 51) & 1; +} + +static uint8_t /*bool*/ subborrow_u51(uint8_t /*bool*/ c, uint64_t a, + uint64_t b, uint64_t *low) { + // This function extracts 51 bits of result and 1 bit of borrow (52 total), so + // a 64-bit intermediate is sufficient. + uint64_t x = a - b - c; + *low = x & ((UINT64_C(1) << 51) - 1); + return x >> 63; +} + +static uint64_t cmovznz64(uint64_t t, uint64_t z, uint64_t nz) { + t = -!!t; // all set if nonzero, 0 if 0 + return (t&nz) | ((~t)&z); +} + +#else + +static uint8_t /*bool*/ addcarryx_u25(uint8_t /*bool*/ c, uint32_t a, + uint32_t b, uint32_t *low) { + // This function extracts 25 bits of result and 1 bit of carry (26 total), so + // a 32-bit intermediate is sufficient. + uint32_t x = a + b + c; + *low = x & ((1 << 25) - 1); + return (x >> 25) & 1; +} + +static uint8_t /*bool*/ addcarryx_u26(uint8_t /*bool*/ c, uint32_t a, + uint32_t b, uint32_t *low) { + // This function extracts 26 bits of result and 1 bit of carry (27 total), so + // a 32-bit intermediate is sufficient. + uint32_t x = a + b + c; + *low = x & ((1 << 26) - 1); + return (x >> 26) & 1; +} + +static uint8_t /*bool*/ subborrow_u25(uint8_t /*bool*/ c, uint32_t a, + uint32_t b, uint32_t *low) { + // This function extracts 25 bits of result and 1 bit of borrow (26 total), so + // a 32-bit intermediate is sufficient. + uint32_t x = a - b - c; + *low = x & ((1 << 25) - 1); + return x >> 31; +} + +static uint8_t /*bool*/ subborrow_u26(uint8_t /*bool*/ c, uint32_t a, + uint32_t b, uint32_t *low) { + // This function extracts 26 bits of result and 1 bit of borrow (27 total), so + // a 32-bit intermediate is sufficient. + uint32_t x = a - b - c; + *low = x & ((1 << 26) - 1); + return x >> 31; +} + +static uint32_t cmovznz32(uint32_t t, uint32_t z, uint32_t nz) { + t = -!!t; // all set if nonzero, 0 if 0 + return (t&nz) | ((~t)&z); +} + +#endif + + +// Field operations. + +#if defined(BORINGSSL_CURVE25519_64BIT) + +#define assert_fe(f) do { \ + for (unsigned _assert_fe_i = 0; _assert_fe_i< 5; _assert_fe_i++) { \ + assert(f[_assert_fe_i] < 1.125*(UINT64_C(1)<<51)); \ + } \ +} while (0) + +#define assert_fe_loose(f) do { \ + for (unsigned _assert_fe_i = 0; _assert_fe_i< 5; _assert_fe_i++) { \ + assert(f[_assert_fe_i] < 3.375*(UINT64_C(1)<<51)); \ + } \ +} while (0) + +#define assert_fe_frozen(f) do { \ + for (unsigned _assert_fe_i = 0; _assert_fe_i< 5; _assert_fe_i++) { \ + assert(f[_assert_fe_i] < (UINT64_C(1)<<51)); \ + } \ +} while (0) + +static void fe_frombytes_impl(uint64_t h[5], const uint8_t *s) { + // Ignores top bit of s. + uint64_t a0 = load_8(s); + uint64_t a1 = load_8(s+8); + uint64_t a2 = load_8(s+16); + uint64_t a3 = load_8(s+24); + // Use 51 bits, 64-51 = 13 left. + h[0] = a0 & ((UINT64_C(1) << 51) - 1); + // (64-51) + 38 = 13 + 38 = 51 + h[1] = (a0 >> 51) | ((a1 & ((UINT64_C(1) << 38) - 1)) << 13); + // (64-38) + 25 = 26 + 25 = 51 + h[2] = (a1 >> 38) | ((a2 & ((UINT64_C(1) << 25) - 1)) << 26); + // (64-25) + 12 = 39 + 12 = 51 + h[3] = (a2 >> 25) | ((a3 & ((UINT64_C(1) << 12) - 1)) << 39); + // (64-12) = 52, ignore top bit + h[4] = (a3 >> 12) & ((UINT64_C(1) << 51) - 1); + assert_fe(h); +} + +static void fe_frombytes(fe *h, const uint8_t *s) { + fe_frombytes_impl(h->v, s); +} + +static void fe_freeze(uint64_t out[5], const uint64_t in1[5]) { + { const uint64_t x7 = in1[4]; + { const uint64_t x8 = in1[3]; + { const uint64_t x6 = in1[2]; + { const uint64_t x4 = in1[1]; + { const uint64_t x2 = in1[0]; + { uint64_t x10; uint8_t/*bool*/ x11 = subborrow_u51(0x0, x2, 0x7ffffffffffed, &x10); + { uint64_t x13; uint8_t/*bool*/ x14 = subborrow_u51(x11, x4, 0x7ffffffffffff, &x13); + { uint64_t x16; uint8_t/*bool*/ x17 = subborrow_u51(x14, x6, 0x7ffffffffffff, &x16); + { uint64_t x19; uint8_t/*bool*/ x20 = subborrow_u51(x17, x8, 0x7ffffffffffff, &x19); + { uint64_t x22; uint8_t/*bool*/ x23 = subborrow_u51(x20, x7, 0x7ffffffffffff, &x22); + { uint64_t x24 = cmovznz64(x23, 0x0, 0xffffffffffffffffL); + { uint64_t x25 = (x24 & 0x7ffffffffffed); + { uint64_t x27; uint8_t/*bool*/ x28 = addcarryx_u51(0x0, x10, x25, &x27); + { uint64_t x29 = (x24 & 0x7ffffffffffff); + { uint64_t x31; uint8_t/*bool*/ x32 = addcarryx_u51(x28, x13, x29, &x31); + { uint64_t x33 = (x24 & 0x7ffffffffffff); + { uint64_t x35; uint8_t/*bool*/ x36 = addcarryx_u51(x32, x16, x33, &x35); + { uint64_t x37 = (x24 & 0x7ffffffffffff); + { uint64_t x39; uint8_t/*bool*/ x40 = addcarryx_u51(x36, x19, x37, &x39); + { uint64_t x41 = (x24 & 0x7ffffffffffff); + { uint64_t x43; addcarryx_u51(x40, x22, x41, &x43); + out[0] = x27; + out[1] = x31; + out[2] = x35; + out[3] = x39; + out[4] = x43; + }}}}}}}}}}}}}}}}}}}}} +} + +static void fe_tobytes(uint8_t s[32], const fe *f) { + assert_fe(f->v); + uint64_t h[5]; + fe_freeze(h, f->v); + assert_fe_frozen(h); + + s[0] = h[0] >> 0; + s[1] = h[0] >> 8; + s[2] = h[0] >> 16; + s[3] = h[0] >> 24; + s[4] = h[0] >> 32; + s[5] = h[0] >> 40; + s[6] = (h[0] >> 48) | (h[1] << 3); + s[7] = h[1] >> 5; + s[8] = h[1] >> 13; + s[9] = h[1] >> 21; + s[10] = h[1] >> 29; + s[11] = h[1] >> 37; + s[12] = (h[1] >> 45) | (h[2] << 6); + s[13] = h[2] >> 2; + s[14] = h[2] >> 10; + s[15] = h[2] >> 18; + s[16] = h[2] >> 26; + s[17] = h[2] >> 34; + s[18] = h[2] >> 42; + s[19] = (h[2] >> 50) | (h[3] << 1); + s[20] = h[3] >> 7; + s[21] = h[3] >> 15; + s[22] = h[3] >> 23; + s[23] = h[3] >> 31; + s[24] = h[3] >> 39; + s[25] = (h[3] >> 47) | (h[4] << 4); + s[26] = h[4] >> 4; + s[27] = h[4] >> 12; + s[28] = h[4] >> 20; + s[29] = h[4] >> 28; + s[30] = h[4] >> 36; + s[31] = h[4] >> 44; +} + +// h = 0 +static void fe_0(fe *h) { + OPENSSL_memset(h, 0, sizeof(fe)); +} + +static void fe_loose_0(fe_loose *h) { + OPENSSL_memset(h, 0, sizeof(fe_loose)); +} + +// h = 1 +static void fe_1(fe *h) { + OPENSSL_memset(h, 0, sizeof(fe)); + h->v[0] = 1; +} + +static void fe_loose_1(fe_loose *h) { + OPENSSL_memset(h, 0, sizeof(fe_loose)); + h->v[0] = 1; +} + +static void fe_add_impl(uint64_t out[5], const uint64_t in1[5], const uint64_t in2[5]) { + { const uint64_t x10 = in1[4]; + { const uint64_t x11 = in1[3]; + { const uint64_t x9 = in1[2]; + { const uint64_t x7 = in1[1]; + { const uint64_t x5 = in1[0]; + { const uint64_t x18 = in2[4]; + { const uint64_t x19 = in2[3]; + { const uint64_t x17 = in2[2]; + { const uint64_t x15 = in2[1]; + { const uint64_t x13 = in2[0]; + out[0] = (x5 + x13); + out[1] = (x7 + x15); + out[2] = (x9 + x17); + out[3] = (x11 + x19); + out[4] = (x10 + x18); + }}}}}}}}}} +} + +// h = f + g +// Can overlap h with f or g. +static void fe_add(fe_loose *h, const fe *f, const fe *g) { + assert_fe(f->v); + assert_fe(g->v); + fe_add_impl(h->v, f->v, g->v); + assert_fe_loose(h->v); +} + +static void fe_sub_impl(uint64_t out[5], const uint64_t in1[5], const uint64_t in2[5]) { + { const uint64_t x10 = in1[4]; + { const uint64_t x11 = in1[3]; + { const uint64_t x9 = in1[2]; + { const uint64_t x7 = in1[1]; + { const uint64_t x5 = in1[0]; + { const uint64_t x18 = in2[4]; + { const uint64_t x19 = in2[3]; + { const uint64_t x17 = in2[2]; + { const uint64_t x15 = in2[1]; + { const uint64_t x13 = in2[0]; + out[0] = ((0xfffffffffffda + x5) - x13); + out[1] = ((0xffffffffffffe + x7) - x15); + out[2] = ((0xffffffffffffe + x9) - x17); + out[3] = ((0xffffffffffffe + x11) - x19); + out[4] = ((0xffffffffffffe + x10) - x18); + }}}}}}}}}} +} + +// h = f - g +// Can overlap h with f or g. +static void fe_sub(fe_loose *h, const fe *f, const fe *g) { + assert_fe(f->v); + assert_fe(g->v); + fe_sub_impl(h->v, f->v, g->v); + assert_fe_loose(h->v); +} + +static void fe_carry_impl(uint64_t out[5], const uint64_t in1[5]) { + { const uint64_t x7 = in1[4]; + { const uint64_t x8 = in1[3]; + { const uint64_t x6 = in1[2]; + { const uint64_t x4 = in1[1]; + { const uint64_t x2 = in1[0]; + { uint64_t x9 = (x2 >> 0x33); + { uint64_t x10 = (x2 & 0x7ffffffffffff); + { uint64_t x11 = (x9 + x4); + { uint64_t x12 = (x11 >> 0x33); + { uint64_t x13 = (x11 & 0x7ffffffffffff); + { uint64_t x14 = (x12 + x6); + { uint64_t x15 = (x14 >> 0x33); + { uint64_t x16 = (x14 & 0x7ffffffffffff); + { uint64_t x17 = (x15 + x8); + { uint64_t x18 = (x17 >> 0x33); + { uint64_t x19 = (x17 & 0x7ffffffffffff); + { uint64_t x20 = (x18 + x7); + { uint64_t x21 = (x20 >> 0x33); + { uint64_t x22 = (x20 & 0x7ffffffffffff); + { uint64_t x23 = (x10 + (0x13 * x21)); + { uint64_t x24 = (x23 >> 0x33); + { uint64_t x25 = (x23 & 0x7ffffffffffff); + { uint64_t x26 = (x24 + x13); + { uint64_t x27 = (x26 >> 0x33); + { uint64_t x28 = (x26 & 0x7ffffffffffff); + out[0] = x25; + out[1] = x28; + out[2] = (x27 + x16); + out[3] = x19; + out[4] = x22; + }}}}}}}}}}}}}}}}}}}}}}}}} +} + +static void fe_carry(fe *h, const fe_loose* f) { + assert_fe_loose(f->v); + fe_carry_impl(h->v, f->v); + assert_fe(h->v); +} + +static void fe_mul_impl(uint64_t out[5], const uint64_t in1[5], const uint64_t in2[5]) { + assert_fe_loose(in1); + assert_fe_loose(in2); + { const uint64_t x10 = in1[4]; + { const uint64_t x11 = in1[3]; + { const uint64_t x9 = in1[2]; + { const uint64_t x7 = in1[1]; + { const uint64_t x5 = in1[0]; + { const uint64_t x18 = in2[4]; + { const uint64_t x19 = in2[3]; + { const uint64_t x17 = in2[2]; + { const uint64_t x15 = in2[1]; + { const uint64_t x13 = in2[0]; + { uint128_t x20 = ((uint128_t)x5 * x13); + { uint128_t x21 = (((uint128_t)x5 * x15) + ((uint128_t)x7 * x13)); + { uint128_t x22 = ((((uint128_t)x5 * x17) + ((uint128_t)x9 * x13)) + ((uint128_t)x7 * x15)); + { uint128_t x23 = (((((uint128_t)x5 * x19) + ((uint128_t)x11 * x13)) + ((uint128_t)x7 * x17)) + ((uint128_t)x9 * x15)); + { uint128_t x24 = ((((((uint128_t)x5 * x18) + ((uint128_t)x10 * x13)) + ((uint128_t)x11 * x15)) + ((uint128_t)x7 * x19)) + ((uint128_t)x9 * x17)); + { uint64_t x25 = (x10 * 0x13); + { uint64_t x26 = (x7 * 0x13); + { uint64_t x27 = (x9 * 0x13); + { uint64_t x28 = (x11 * 0x13); + { uint128_t x29 = ((((x20 + ((uint128_t)x25 * x15)) + ((uint128_t)x26 * x18)) + ((uint128_t)x27 * x19)) + ((uint128_t)x28 * x17)); + { uint128_t x30 = (((x21 + ((uint128_t)x25 * x17)) + ((uint128_t)x27 * x18)) + ((uint128_t)x28 * x19)); + { uint128_t x31 = ((x22 + ((uint128_t)x25 * x19)) + ((uint128_t)x28 * x18)); + { uint128_t x32 = (x23 + ((uint128_t)x25 * x18)); + { uint64_t x33 = (uint64_t) (x29 >> 0x33); + { uint64_t x34 = ((uint64_t)x29 & 0x7ffffffffffff); + { uint128_t x35 = (x33 + x30); + { uint64_t x36 = (uint64_t) (x35 >> 0x33); + { uint64_t x37 = ((uint64_t)x35 & 0x7ffffffffffff); + { uint128_t x38 = (x36 + x31); + { uint64_t x39 = (uint64_t) (x38 >> 0x33); + { uint64_t x40 = ((uint64_t)x38 & 0x7ffffffffffff); + { uint128_t x41 = (x39 + x32); + { uint64_t x42 = (uint64_t) (x41 >> 0x33); + { uint64_t x43 = ((uint64_t)x41 & 0x7ffffffffffff); + { uint128_t x44 = (x42 + x24); + { uint64_t x45 = (uint64_t) (x44 >> 0x33); + { uint64_t x46 = ((uint64_t)x44 & 0x7ffffffffffff); + { uint64_t x47 = (x34 + (0x13 * x45)); + { uint64_t x48 = (x47 >> 0x33); + { uint64_t x49 = (x47 & 0x7ffffffffffff); + { uint64_t x50 = (x48 + x37); + { uint64_t x51 = (x50 >> 0x33); + { uint64_t x52 = (x50 & 0x7ffffffffffff); + out[0] = x49; + out[1] = x52; + out[2] = (x51 + x40); + out[3] = x43; + out[4] = x46; + }}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} + assert_fe(out); +} + +static void fe_mul_ltt(fe_loose *h, const fe *f, const fe *g) { + fe_mul_impl(h->v, f->v, g->v); +} + +static void fe_mul_llt(fe_loose *h, const fe_loose *f, const fe *g) { + fe_mul_impl(h->v, f->v, g->v); +} + +static void fe_mul_ttt(fe *h, const fe *f, const fe *g) { + fe_mul_impl(h->v, f->v, g->v); +} + +static void fe_mul_tlt(fe *h, const fe_loose *f, const fe *g) { + fe_mul_impl(h->v, f->v, g->v); +} + +static void fe_mul_ttl(fe *h, const fe *f, const fe_loose *g) { + fe_mul_impl(h->v, f->v, g->v); +} + +static void fe_mul_tll(fe *h, const fe_loose *f, const fe_loose *g) { + fe_mul_impl(h->v, f->v, g->v); +} + +static void fe_sqr_impl(uint64_t out[5], const uint64_t in1[5]) { + assert_fe_loose(in1); + { const uint64_t x7 = in1[4]; + { const uint64_t x8 = in1[3]; + { const uint64_t x6 = in1[2]; + { const uint64_t x4 = in1[1]; + { const uint64_t x2 = in1[0]; + { uint64_t x9 = (x2 * 0x2); + { uint64_t x10 = (x4 * 0x2); + { uint64_t x11 = ((x6 * 0x2) * 0x13); + { uint64_t x12 = (x7 * 0x13); + { uint64_t x13 = (x12 * 0x2); + { uint128_t x14 = ((((uint128_t)x2 * x2) + ((uint128_t)x13 * x4)) + ((uint128_t)x11 * x8)); + { uint128_t x15 = ((((uint128_t)x9 * x4) + ((uint128_t)x13 * x6)) + ((uint128_t)x8 * (x8 * 0x13))); + { uint128_t x16 = ((((uint128_t)x9 * x6) + ((uint128_t)x4 * x4)) + ((uint128_t)x13 * x8)); + { uint128_t x17 = ((((uint128_t)x9 * x8) + ((uint128_t)x10 * x6)) + ((uint128_t)x7 * x12)); + { uint128_t x18 = ((((uint128_t)x9 * x7) + ((uint128_t)x10 * x8)) + ((uint128_t)x6 * x6)); + { uint64_t x19 = (uint64_t) (x14 >> 0x33); + { uint64_t x20 = ((uint64_t)x14 & 0x7ffffffffffff); + { uint128_t x21 = (x19 + x15); + { uint64_t x22 = (uint64_t) (x21 >> 0x33); + { uint64_t x23 = ((uint64_t)x21 & 0x7ffffffffffff); + { uint128_t x24 = (x22 + x16); + { uint64_t x25 = (uint64_t) (x24 >> 0x33); + { uint64_t x26 = ((uint64_t)x24 & 0x7ffffffffffff); + { uint128_t x27 = (x25 + x17); + { uint64_t x28 = (uint64_t) (x27 >> 0x33); + { uint64_t x29 = ((uint64_t)x27 & 0x7ffffffffffff); + { uint128_t x30 = (x28 + x18); + { uint64_t x31 = (uint64_t) (x30 >> 0x33); + { uint64_t x32 = ((uint64_t)x30 & 0x7ffffffffffff); + { uint64_t x33 = (x20 + (0x13 * x31)); + { uint64_t x34 = (x33 >> 0x33); + { uint64_t x35 = (x33 & 0x7ffffffffffff); + { uint64_t x36 = (x34 + x23); + { uint64_t x37 = (x36 >> 0x33); + { uint64_t x38 = (x36 & 0x7ffffffffffff); + out[0] = x35; + out[1] = x38; + out[2] = (x37 + x26); + out[3] = x29; + out[4] = x32; + }}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} + assert_fe(out); +} + +static void fe_sq_tl(fe *h, const fe_loose *f) { + fe_sqr_impl(h->v, f->v); +} + +static void fe_sq_tt(fe *h, const fe *f) { + fe_sqr_impl(h->v, f->v); +} + +// Replace (f,g) with (g,f) if b == 1; +// replace (f,g) with (f,g) if b == 0. +// +// Preconditions: b in {0,1}. +static void fe_cswap(fe *f, fe *g, uint64_t b) { + b = 0-b; + for (unsigned i = 0; i < 5; i++) { + uint64_t x = f->v[i] ^ g->v[i]; + x &= b; + f->v[i] ^= x; + g->v[i] ^= x; + } +} + +// NOTE: based on fiat-crypto fe_mul, edited for in2=121666, 0, 0.. +static void fe_mul_121666_impl(uint64_t out[5], const uint64_t in1[5]) { + { const uint64_t x10 = in1[4]; + { const uint64_t x11 = in1[3]; + { const uint64_t x9 = in1[2]; + { const uint64_t x7 = in1[1]; + { const uint64_t x5 = in1[0]; + { const uint64_t x18 = 0; + { const uint64_t x19 = 0; + { const uint64_t x17 = 0; + { const uint64_t x15 = 0; + { const uint64_t x13 = 121666; + { uint128_t x20 = ((uint128_t)x5 * x13); + { uint128_t x21 = (((uint128_t)x5 * x15) + ((uint128_t)x7 * x13)); + { uint128_t x22 = ((((uint128_t)x5 * x17) + ((uint128_t)x9 * x13)) + ((uint128_t)x7 * x15)); + { uint128_t x23 = (((((uint128_t)x5 * x19) + ((uint128_t)x11 * x13)) + ((uint128_t)x7 * x17)) + ((uint128_t)x9 * x15)); + { uint128_t x24 = ((((((uint128_t)x5 * x18) + ((uint128_t)x10 * x13)) + ((uint128_t)x11 * x15)) + ((uint128_t)x7 * x19)) + ((uint128_t)x9 * x17)); + { uint64_t x25 = (x10 * 0x13); + { uint64_t x26 = (x7 * 0x13); + { uint64_t x27 = (x9 * 0x13); + { uint64_t x28 = (x11 * 0x13); + { uint128_t x29 = ((((x20 + ((uint128_t)x25 * x15)) + ((uint128_t)x26 * x18)) + ((uint128_t)x27 * x19)) + ((uint128_t)x28 * x17)); + { uint128_t x30 = (((x21 + ((uint128_t)x25 * x17)) + ((uint128_t)x27 * x18)) + ((uint128_t)x28 * x19)); + { uint128_t x31 = ((x22 + ((uint128_t)x25 * x19)) + ((uint128_t)x28 * x18)); + { uint128_t x32 = (x23 + ((uint128_t)x25 * x18)); + { uint64_t x33 = (uint64_t) (x29 >> 0x33); + { uint64_t x34 = ((uint64_t)x29 & 0x7ffffffffffff); + { uint128_t x35 = (x33 + x30); + { uint64_t x36 = (uint64_t) (x35 >> 0x33); + { uint64_t x37 = ((uint64_t)x35 & 0x7ffffffffffff); + { uint128_t x38 = (x36 + x31); + { uint64_t x39 = (uint64_t) (x38 >> 0x33); + { uint64_t x40 = ((uint64_t)x38 & 0x7ffffffffffff); + { uint128_t x41 = (x39 + x32); + { uint64_t x42 = (uint64_t) (x41 >> 0x33); + { uint64_t x43 = ((uint64_t)x41 & 0x7ffffffffffff); + { uint128_t x44 = (x42 + x24); + { uint64_t x45 = (uint64_t) (x44 >> 0x33); + { uint64_t x46 = ((uint64_t)x44 & 0x7ffffffffffff); + { uint64_t x47 = (x34 + (0x13 * x45)); + { uint64_t x48 = (x47 >> 0x33); + { uint64_t x49 = (x47 & 0x7ffffffffffff); + { uint64_t x50 = (x48 + x37); + { uint64_t x51 = (x50 >> 0x33); + { uint64_t x52 = (x50 & 0x7ffffffffffff); + out[0] = x49; + out[1] = x52; + out[2] = (x51 + x40); + out[3] = x43; + out[4] = x46; + }}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} +} + +static void fe_mul121666(fe *h, const fe_loose *f) { + assert_fe_loose(f->v); + fe_mul_121666_impl(h->v, f->v); + assert_fe(h->v); +} + +// Adapted from Fiat-synthesized |fe_sub_impl| with |out| = 0. +static void fe_neg_impl(uint64_t out[5], const uint64_t in2[5]) { + { const uint64_t x10 = 0; + { const uint64_t x11 = 0; + { const uint64_t x9 = 0; + { const uint64_t x7 = 0; + { const uint64_t x5 = 0; + { const uint64_t x18 = in2[4]; + { const uint64_t x19 = in2[3]; + { const uint64_t x17 = in2[2]; + { const uint64_t x15 = in2[1]; + { const uint64_t x13 = in2[0]; + out[0] = ((0xfffffffffffda + x5) - x13); + out[1] = ((0xffffffffffffe + x7) - x15); + out[2] = ((0xffffffffffffe + x9) - x17); + out[3] = ((0xffffffffffffe + x11) - x19); + out[4] = ((0xffffffffffffe + x10) - x18); + }}}}}}}}}} +} + +// h = -f +static void fe_neg(fe_loose *h, const fe *f) { + assert_fe(f->v); + fe_neg_impl(h->v, f->v); + assert_fe_loose(h->v); +} + +// Replace (f,g) with (g,g) if b == 1; +// replace (f,g) with (f,g) if b == 0. +// +// Preconditions: b in {0,1}. +static void fe_cmov(fe_loose *f, const fe_loose *g, uint64_t b) { + b = 0-b; + for (unsigned i = 0; i < 5; i++) { + uint64_t x = f->v[i] ^ g->v[i]; + x &= b; + f->v[i] ^= x; + } +} + +#else + +#define assert_fe(f) do { \ + for (unsigned _assert_fe_i = 0; _assert_fe_i< 10; _assert_fe_i++) { \ + assert(f[_assert_fe_i] < 1.125*(1<<(26-(_assert_fe_i&1)))); \ + } \ +} while (0) + +#define assert_fe_loose(f) do { \ + for (unsigned _assert_fe_i = 0; _assert_fe_i< 10; _assert_fe_i++) { \ + assert(f[_assert_fe_i] < 3.375*(1<<(26-(_assert_fe_i&1)))); \ + } \ +} while (0) + +#define assert_fe_frozen(f) do { \ + for (unsigned _assert_fe_i = 0; _assert_fe_i< 10; _assert_fe_i++) { \ + assert(f[_assert_fe_i] < (1u<<(26-(_assert_fe_i&1)))); \ + } \ +} while (0) + +static void fe_frombytes_impl(uint32_t h[10], const uint8_t *s) { + // Ignores top bit of s. + uint32_t a0 = load_4(s); + uint32_t a1 = load_4(s+4); + uint32_t a2 = load_4(s+8); + uint32_t a3 = load_4(s+12); + uint32_t a4 = load_4(s+16); + uint32_t a5 = load_4(s+20); + uint32_t a6 = load_4(s+24); + uint32_t a7 = load_4(s+28); + h[0] = a0&((1<<26)-1); // 26 used, 32-26 left. 26 + h[1] = (a0>>26) | ((a1&((1<<19)-1))<< 6); // (32-26) + 19 = 6+19 = 25 + h[2] = (a1>>19) | ((a2&((1<<13)-1))<<13); // (32-19) + 13 = 13+13 = 26 + h[3] = (a2>>13) | ((a3&((1<< 6)-1))<<19); // (32-13) + 6 = 19+ 6 = 25 + h[4] = (a3>> 6); // (32- 6) = 26 + h[5] = a4&((1<<25)-1); // 25 + h[6] = (a4>>25) | ((a5&((1<<19)-1))<< 7); // (32-25) + 19 = 7+19 = 26 + h[7] = (a5>>19) | ((a6&((1<<12)-1))<<13); // (32-19) + 12 = 13+12 = 25 + h[8] = (a6>>12) | ((a7&((1<< 6)-1))<<20); // (32-12) + 6 = 20+ 6 = 26 + h[9] = (a7>> 6)&((1<<25)-1); // 25 + assert_fe(h); +} + +static void fe_frombytes(fe *h, const uint8_t *s) { + fe_frombytes_impl(h->v, s); +} + +static void fe_freeze(uint32_t out[10], const uint32_t in1[10]) { + { const uint32_t x17 = in1[9]; + { const uint32_t x18 = in1[8]; + { const uint32_t x16 = in1[7]; + { const uint32_t x14 = in1[6]; + { const uint32_t x12 = in1[5]; + { const uint32_t x10 = in1[4]; + { const uint32_t x8 = in1[3]; + { const uint32_t x6 = in1[2]; + { const uint32_t x4 = in1[1]; + { const uint32_t x2 = in1[0]; + { uint32_t x20; uint8_t/*bool*/ x21 = subborrow_u26(0x0, x2, 0x3ffffed, &x20); + { uint32_t x23; uint8_t/*bool*/ x24 = subborrow_u25(x21, x4, 0x1ffffff, &x23); + { uint32_t x26; uint8_t/*bool*/ x27 = subborrow_u26(x24, x6, 0x3ffffff, &x26); + { uint32_t x29; uint8_t/*bool*/ x30 = subborrow_u25(x27, x8, 0x1ffffff, &x29); + { uint32_t x32; uint8_t/*bool*/ x33 = subborrow_u26(x30, x10, 0x3ffffff, &x32); + { uint32_t x35; uint8_t/*bool*/ x36 = subborrow_u25(x33, x12, 0x1ffffff, &x35); + { uint32_t x38; uint8_t/*bool*/ x39 = subborrow_u26(x36, x14, 0x3ffffff, &x38); + { uint32_t x41; uint8_t/*bool*/ x42 = subborrow_u25(x39, x16, 0x1ffffff, &x41); + { uint32_t x44; uint8_t/*bool*/ x45 = subborrow_u26(x42, x18, 0x3ffffff, &x44); + { uint32_t x47; uint8_t/*bool*/ x48 = subborrow_u25(x45, x17, 0x1ffffff, &x47); + { uint32_t x49 = cmovznz32(x48, 0x0, 0xffffffff); + { uint32_t x50 = (x49 & 0x3ffffed); + { uint32_t x52; uint8_t/*bool*/ x53 = addcarryx_u26(0x0, x20, x50, &x52); + { uint32_t x54 = (x49 & 0x1ffffff); + { uint32_t x56; uint8_t/*bool*/ x57 = addcarryx_u25(x53, x23, x54, &x56); + { uint32_t x58 = (x49 & 0x3ffffff); + { uint32_t x60; uint8_t/*bool*/ x61 = addcarryx_u26(x57, x26, x58, &x60); + { uint32_t x62 = (x49 & 0x1ffffff); + { uint32_t x64; uint8_t/*bool*/ x65 = addcarryx_u25(x61, x29, x62, &x64); + { uint32_t x66 = (x49 & 0x3ffffff); + { uint32_t x68; uint8_t/*bool*/ x69 = addcarryx_u26(x65, x32, x66, &x68); + { uint32_t x70 = (x49 & 0x1ffffff); + { uint32_t x72; uint8_t/*bool*/ x73 = addcarryx_u25(x69, x35, x70, &x72); + { uint32_t x74 = (x49 & 0x3ffffff); + { uint32_t x76; uint8_t/*bool*/ x77 = addcarryx_u26(x73, x38, x74, &x76); + { uint32_t x78 = (x49 & 0x1ffffff); + { uint32_t x80; uint8_t/*bool*/ x81 = addcarryx_u25(x77, x41, x78, &x80); + { uint32_t x82 = (x49 & 0x3ffffff); + { uint32_t x84; uint8_t/*bool*/ x85 = addcarryx_u26(x81, x44, x82, &x84); + { uint32_t x86 = (x49 & 0x1ffffff); + { uint32_t x88; addcarryx_u25(x85, x47, x86, &x88); + out[0] = x52; + out[1] = x56; + out[2] = x60; + out[3] = x64; + out[4] = x68; + out[5] = x72; + out[6] = x76; + out[7] = x80; + out[8] = x84; + out[9] = x88; + }}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} +} + +static void fe_tobytes(uint8_t s[32], const fe *f) { + assert_fe(f->v); + uint32_t h[10]; + fe_freeze(h, f->v); + assert_fe_frozen(h); + + s[0] = h[0] >> 0; + s[1] = h[0] >> 8; + s[2] = h[0] >> 16; + s[3] = (h[0] >> 24) | (h[1] << 2); + s[4] = h[1] >> 6; + s[5] = h[1] >> 14; + s[6] = (h[1] >> 22) | (h[2] << 3); + s[7] = h[2] >> 5; + s[8] = h[2] >> 13; + s[9] = (h[2] >> 21) | (h[3] << 5); + s[10] = h[3] >> 3; + s[11] = h[3] >> 11; + s[12] = (h[3] >> 19) | (h[4] << 6); + s[13] = h[4] >> 2; + s[14] = h[4] >> 10; + s[15] = h[4] >> 18; + s[16] = h[5] >> 0; + s[17] = h[5] >> 8; + s[18] = h[5] >> 16; + s[19] = (h[5] >> 24) | (h[6] << 1); + s[20] = h[6] >> 7; + s[21] = h[6] >> 15; + s[22] = (h[6] >> 23) | (h[7] << 3); + s[23] = h[7] >> 5; + s[24] = h[7] >> 13; + s[25] = (h[7] >> 21) | (h[8] << 4); + s[26] = h[8] >> 4; + s[27] = h[8] >> 12; + s[28] = (h[8] >> 20) | (h[9] << 6); + s[29] = h[9] >> 2; + s[30] = h[9] >> 10; + s[31] = h[9] >> 18; +} + +// h = 0 +static void fe_0(fe *h) { + OPENSSL_memset(h, 0, sizeof(fe)); +} + +static void fe_loose_0(fe_loose *h) { + OPENSSL_memset(h, 0, sizeof(fe_loose)); +} + +// h = 1 +static void fe_1(fe *h) { + OPENSSL_memset(h, 0, sizeof(fe)); + h->v[0] = 1; +} + +static void fe_loose_1(fe_loose *h) { + OPENSSL_memset(h, 0, sizeof(fe_loose)); + h->v[0] = 1; +} + +static void fe_add_impl(uint32_t out[10], const uint32_t in1[10], const uint32_t in2[10]) { + { const uint32_t x20 = in1[9]; + { const uint32_t x21 = in1[8]; + { const uint32_t x19 = in1[7]; + { const uint32_t x17 = in1[6]; + { const uint32_t x15 = in1[5]; + { const uint32_t x13 = in1[4]; + { const uint32_t x11 = in1[3]; + { const uint32_t x9 = in1[2]; + { const uint32_t x7 = in1[1]; + { const uint32_t x5 = in1[0]; + { const uint32_t x38 = in2[9]; + { const uint32_t x39 = in2[8]; + { const uint32_t x37 = in2[7]; + { const uint32_t x35 = in2[6]; + { const uint32_t x33 = in2[5]; + { const uint32_t x31 = in2[4]; + { const uint32_t x29 = in2[3]; + { const uint32_t x27 = in2[2]; + { const uint32_t x25 = in2[1]; + { const uint32_t x23 = in2[0]; + out[0] = (x5 + x23); + out[1] = (x7 + x25); + out[2] = (x9 + x27); + out[3] = (x11 + x29); + out[4] = (x13 + x31); + out[5] = (x15 + x33); + out[6] = (x17 + x35); + out[7] = (x19 + x37); + out[8] = (x21 + x39); + out[9] = (x20 + x38); + }}}}}}}}}}}}}}}}}}}} +} + +// h = f + g +// Can overlap h with f or g. +static void fe_add(fe_loose *h, const fe *f, const fe *g) { + assert_fe(f->v); + assert_fe(g->v); + fe_add_impl(h->v, f->v, g->v); + assert_fe_loose(h->v); +} + +static void fe_sub_impl(uint32_t out[10], const uint32_t in1[10], const uint32_t in2[10]) { + { const uint32_t x20 = in1[9]; + { const uint32_t x21 = in1[8]; + { const uint32_t x19 = in1[7]; + { const uint32_t x17 = in1[6]; + { const uint32_t x15 = in1[5]; + { const uint32_t x13 = in1[4]; + { const uint32_t x11 = in1[3]; + { const uint32_t x9 = in1[2]; + { const uint32_t x7 = in1[1]; + { const uint32_t x5 = in1[0]; + { const uint32_t x38 = in2[9]; + { const uint32_t x39 = in2[8]; + { const uint32_t x37 = in2[7]; + { const uint32_t x35 = in2[6]; + { const uint32_t x33 = in2[5]; + { const uint32_t x31 = in2[4]; + { const uint32_t x29 = in2[3]; + { const uint32_t x27 = in2[2]; + { const uint32_t x25 = in2[1]; + { const uint32_t x23 = in2[0]; + out[0] = ((0x7ffffda + x5) - x23); + out[1] = ((0x3fffffe + x7) - x25); + out[2] = ((0x7fffffe + x9) - x27); + out[3] = ((0x3fffffe + x11) - x29); + out[4] = ((0x7fffffe + x13) - x31); + out[5] = ((0x3fffffe + x15) - x33); + out[6] = ((0x7fffffe + x17) - x35); + out[7] = ((0x3fffffe + x19) - x37); + out[8] = ((0x7fffffe + x21) - x39); + out[9] = ((0x3fffffe + x20) - x38); + }}}}}}}}}}}}}}}}}}}} +} + +// h = f - g +// Can overlap h with f or g. +static void fe_sub(fe_loose *h, const fe *f, const fe *g) { + assert_fe(f->v); + assert_fe(g->v); + fe_sub_impl(h->v, f->v, g->v); + assert_fe_loose(h->v); +} + +static void fe_carry_impl(uint32_t out[10], const uint32_t in1[10]) { + { const uint32_t x17 = in1[9]; + { const uint32_t x18 = in1[8]; + { const uint32_t x16 = in1[7]; + { const uint32_t x14 = in1[6]; + { const uint32_t x12 = in1[5]; + { const uint32_t x10 = in1[4]; + { const uint32_t x8 = in1[3]; + { const uint32_t x6 = in1[2]; + { const uint32_t x4 = in1[1]; + { const uint32_t x2 = in1[0]; + { uint32_t x19 = (x2 >> 0x1a); + { uint32_t x20 = (x2 & 0x3ffffff); + { uint32_t x21 = (x19 + x4); + { uint32_t x22 = (x21 >> 0x19); + { uint32_t x23 = (x21 & 0x1ffffff); + { uint32_t x24 = (x22 + x6); + { uint32_t x25 = (x24 >> 0x1a); + { uint32_t x26 = (x24 & 0x3ffffff); + { uint32_t x27 = (x25 + x8); + { uint32_t x28 = (x27 >> 0x19); + { uint32_t x29 = (x27 & 0x1ffffff); + { uint32_t x30 = (x28 + x10); + { uint32_t x31 = (x30 >> 0x1a); + { uint32_t x32 = (x30 & 0x3ffffff); + { uint32_t x33 = (x31 + x12); + { uint32_t x34 = (x33 >> 0x19); + { uint32_t x35 = (x33 & 0x1ffffff); + { uint32_t x36 = (x34 + x14); + { uint32_t x37 = (x36 >> 0x1a); + { uint32_t x38 = (x36 & 0x3ffffff); + { uint32_t x39 = (x37 + x16); + { uint32_t x40 = (x39 >> 0x19); + { uint32_t x41 = (x39 & 0x1ffffff); + { uint32_t x42 = (x40 + x18); + { uint32_t x43 = (x42 >> 0x1a); + { uint32_t x44 = (x42 & 0x3ffffff); + { uint32_t x45 = (x43 + x17); + { uint32_t x46 = (x45 >> 0x19); + { uint32_t x47 = (x45 & 0x1ffffff); + { uint32_t x48 = (x20 + (0x13 * x46)); + { uint32_t x49 = (x48 >> 0x1a); + { uint32_t x50 = (x48 & 0x3ffffff); + { uint32_t x51 = (x49 + x23); + { uint32_t x52 = (x51 >> 0x19); + { uint32_t x53 = (x51 & 0x1ffffff); + out[0] = x50; + out[1] = x53; + out[2] = (x52 + x26); + out[3] = x29; + out[4] = x32; + out[5] = x35; + out[6] = x38; + out[7] = x41; + out[8] = x44; + out[9] = x47; + }}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} +} + +static void fe_carry(fe *h, const fe_loose* f) { + assert_fe_loose(f->v); + fe_carry_impl(h->v, f->v); + assert_fe(h->v); +} + +static void fe_mul_impl(uint32_t out[10], const uint32_t in1[10], const uint32_t in2[10]) { + assert_fe_loose(in1); + assert_fe_loose(in2); + { const uint32_t x20 = in1[9]; + { const uint32_t x21 = in1[8]; + { const uint32_t x19 = in1[7]; + { const uint32_t x17 = in1[6]; + { const uint32_t x15 = in1[5]; + { const uint32_t x13 = in1[4]; + { const uint32_t x11 = in1[3]; + { const uint32_t x9 = in1[2]; + { const uint32_t x7 = in1[1]; + { const uint32_t x5 = in1[0]; + { const uint32_t x38 = in2[9]; + { const uint32_t x39 = in2[8]; + { const uint32_t x37 = in2[7]; + { const uint32_t x35 = in2[6]; + { const uint32_t x33 = in2[5]; + { const uint32_t x31 = in2[4]; + { const uint32_t x29 = in2[3]; + { const uint32_t x27 = in2[2]; + { const uint32_t x25 = in2[1]; + { const uint32_t x23 = in2[0]; + { uint64_t x40 = ((uint64_t)x23 * x5); + { uint64_t x41 = (((uint64_t)x23 * x7) + ((uint64_t)x25 * x5)); + { uint64_t x42 = ((((uint64_t)(0x2 * x25) * x7) + ((uint64_t)x23 * x9)) + ((uint64_t)x27 * x5)); + { uint64_t x43 = (((((uint64_t)x25 * x9) + ((uint64_t)x27 * x7)) + ((uint64_t)x23 * x11)) + ((uint64_t)x29 * x5)); + { uint64_t x44 = (((((uint64_t)x27 * x9) + (0x2 * (((uint64_t)x25 * x11) + ((uint64_t)x29 * x7)))) + ((uint64_t)x23 * x13)) + ((uint64_t)x31 * x5)); + { uint64_t x45 = (((((((uint64_t)x27 * x11) + ((uint64_t)x29 * x9)) + ((uint64_t)x25 * x13)) + ((uint64_t)x31 * x7)) + ((uint64_t)x23 * x15)) + ((uint64_t)x33 * x5)); + { uint64_t x46 = (((((0x2 * ((((uint64_t)x29 * x11) + ((uint64_t)x25 * x15)) + ((uint64_t)x33 * x7))) + ((uint64_t)x27 * x13)) + ((uint64_t)x31 * x9)) + ((uint64_t)x23 * x17)) + ((uint64_t)x35 * x5)); + { uint64_t x47 = (((((((((uint64_t)x29 * x13) + ((uint64_t)x31 * x11)) + ((uint64_t)x27 * x15)) + ((uint64_t)x33 * x9)) + ((uint64_t)x25 * x17)) + ((uint64_t)x35 * x7)) + ((uint64_t)x23 * x19)) + ((uint64_t)x37 * x5)); + { uint64_t x48 = (((((((uint64_t)x31 * x13) + (0x2 * (((((uint64_t)x29 * x15) + ((uint64_t)x33 * x11)) + ((uint64_t)x25 * x19)) + ((uint64_t)x37 * x7)))) + ((uint64_t)x27 * x17)) + ((uint64_t)x35 * x9)) + ((uint64_t)x23 * x21)) + ((uint64_t)x39 * x5)); + { uint64_t x49 = (((((((((((uint64_t)x31 * x15) + ((uint64_t)x33 * x13)) + ((uint64_t)x29 * x17)) + ((uint64_t)x35 * x11)) + ((uint64_t)x27 * x19)) + ((uint64_t)x37 * x9)) + ((uint64_t)x25 * x21)) + ((uint64_t)x39 * x7)) + ((uint64_t)x23 * x20)) + ((uint64_t)x38 * x5)); + { uint64_t x50 = (((((0x2 * ((((((uint64_t)x33 * x15) + ((uint64_t)x29 * x19)) + ((uint64_t)x37 * x11)) + ((uint64_t)x25 * x20)) + ((uint64_t)x38 * x7))) + ((uint64_t)x31 * x17)) + ((uint64_t)x35 * x13)) + ((uint64_t)x27 * x21)) + ((uint64_t)x39 * x9)); + { uint64_t x51 = (((((((((uint64_t)x33 * x17) + ((uint64_t)x35 * x15)) + ((uint64_t)x31 * x19)) + ((uint64_t)x37 * x13)) + ((uint64_t)x29 * x21)) + ((uint64_t)x39 * x11)) + ((uint64_t)x27 * x20)) + ((uint64_t)x38 * x9)); + { uint64_t x52 = (((((uint64_t)x35 * x17) + (0x2 * (((((uint64_t)x33 * x19) + ((uint64_t)x37 * x15)) + ((uint64_t)x29 * x20)) + ((uint64_t)x38 * x11)))) + ((uint64_t)x31 * x21)) + ((uint64_t)x39 * x13)); + { uint64_t x53 = (((((((uint64_t)x35 * x19) + ((uint64_t)x37 * x17)) + ((uint64_t)x33 * x21)) + ((uint64_t)x39 * x15)) + ((uint64_t)x31 * x20)) + ((uint64_t)x38 * x13)); + { uint64_t x54 = (((0x2 * ((((uint64_t)x37 * x19) + ((uint64_t)x33 * x20)) + ((uint64_t)x38 * x15))) + ((uint64_t)x35 * x21)) + ((uint64_t)x39 * x17)); + { uint64_t x55 = (((((uint64_t)x37 * x21) + ((uint64_t)x39 * x19)) + ((uint64_t)x35 * x20)) + ((uint64_t)x38 * x17)); + { uint64_t x56 = (((uint64_t)x39 * x21) + (0x2 * (((uint64_t)x37 * x20) + ((uint64_t)x38 * x19)))); + { uint64_t x57 = (((uint64_t)x39 * x20) + ((uint64_t)x38 * x21)); + { uint64_t x58 = ((uint64_t)(0x2 * x38) * x20); + { uint64_t x59 = (x48 + (x58 << 0x4)); + { uint64_t x60 = (x59 + (x58 << 0x1)); + { uint64_t x61 = (x60 + x58); + { uint64_t x62 = (x47 + (x57 << 0x4)); + { uint64_t x63 = (x62 + (x57 << 0x1)); + { uint64_t x64 = (x63 + x57); + { uint64_t x65 = (x46 + (x56 << 0x4)); + { uint64_t x66 = (x65 + (x56 << 0x1)); + { uint64_t x67 = (x66 + x56); + { uint64_t x68 = (x45 + (x55 << 0x4)); + { uint64_t x69 = (x68 + (x55 << 0x1)); + { uint64_t x70 = (x69 + x55); + { uint64_t x71 = (x44 + (x54 << 0x4)); + { uint64_t x72 = (x71 + (x54 << 0x1)); + { uint64_t x73 = (x72 + x54); + { uint64_t x74 = (x43 + (x53 << 0x4)); + { uint64_t x75 = (x74 + (x53 << 0x1)); + { uint64_t x76 = (x75 + x53); + { uint64_t x77 = (x42 + (x52 << 0x4)); + { uint64_t x78 = (x77 + (x52 << 0x1)); + { uint64_t x79 = (x78 + x52); + { uint64_t x80 = (x41 + (x51 << 0x4)); + { uint64_t x81 = (x80 + (x51 << 0x1)); + { uint64_t x82 = (x81 + x51); + { uint64_t x83 = (x40 + (x50 << 0x4)); + { uint64_t x84 = (x83 + (x50 << 0x1)); + { uint64_t x85 = (x84 + x50); + { uint64_t x86 = (x85 >> 0x1a); + { uint32_t x87 = ((uint32_t)x85 & 0x3ffffff); + { uint64_t x88 = (x86 + x82); + { uint64_t x89 = (x88 >> 0x19); + { uint32_t x90 = ((uint32_t)x88 & 0x1ffffff); + { uint64_t x91 = (x89 + x79); + { uint64_t x92 = (x91 >> 0x1a); + { uint32_t x93 = ((uint32_t)x91 & 0x3ffffff); + { uint64_t x94 = (x92 + x76); + { uint64_t x95 = (x94 >> 0x19); + { uint32_t x96 = ((uint32_t)x94 & 0x1ffffff); + { uint64_t x97 = (x95 + x73); + { uint64_t x98 = (x97 >> 0x1a); + { uint32_t x99 = ((uint32_t)x97 & 0x3ffffff); + { uint64_t x100 = (x98 + x70); + { uint64_t x101 = (x100 >> 0x19); + { uint32_t x102 = ((uint32_t)x100 & 0x1ffffff); + { uint64_t x103 = (x101 + x67); + { uint64_t x104 = (x103 >> 0x1a); + { uint32_t x105 = ((uint32_t)x103 & 0x3ffffff); + { uint64_t x106 = (x104 + x64); + { uint64_t x107 = (x106 >> 0x19); + { uint32_t x108 = ((uint32_t)x106 & 0x1ffffff); + { uint64_t x109 = (x107 + x61); + { uint64_t x110 = (x109 >> 0x1a); + { uint32_t x111 = ((uint32_t)x109 & 0x3ffffff); + { uint64_t x112 = (x110 + x49); + { uint64_t x113 = (x112 >> 0x19); + { uint32_t x114 = ((uint32_t)x112 & 0x1ffffff); + { uint64_t x115 = (x87 + (0x13 * x113)); + { uint32_t x116 = (uint32_t) (x115 >> 0x1a); + { uint32_t x117 = ((uint32_t)x115 & 0x3ffffff); + { uint32_t x118 = (x116 + x90); + { uint32_t x119 = (x118 >> 0x19); + { uint32_t x120 = (x118 & 0x1ffffff); + out[0] = x117; + out[1] = x120; + out[2] = (x119 + x93); + out[3] = x96; + out[4] = x99; + out[5] = x102; + out[6] = x105; + out[7] = x108; + out[8] = x111; + out[9] = x114; + }}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} + assert_fe(out); +} + +static void fe_mul_ltt(fe_loose *h, const fe *f, const fe *g) { + fe_mul_impl(h->v, f->v, g->v); +} + +static void fe_mul_llt(fe_loose *h, const fe_loose *f, const fe *g) { + fe_mul_impl(h->v, f->v, g->v); +} + +static void fe_mul_ttt(fe *h, const fe *f, const fe *g) { + fe_mul_impl(h->v, f->v, g->v); +} + +static void fe_mul_tlt(fe *h, const fe_loose *f, const fe *g) { + fe_mul_impl(h->v, f->v, g->v); +} + +static void fe_mul_ttl(fe *h, const fe *f, const fe_loose *g) { + fe_mul_impl(h->v, f->v, g->v); +} + +static void fe_mul_tll(fe *h, const fe_loose *f, const fe_loose *g) { + fe_mul_impl(h->v, f->v, g->v); +} + +static void fe_sqr_impl(uint32_t out[10], const uint32_t in1[10]) { + assert_fe_loose(in1); + { const uint32_t x17 = in1[9]; + { const uint32_t x18 = in1[8]; + { const uint32_t x16 = in1[7]; + { const uint32_t x14 = in1[6]; + { const uint32_t x12 = in1[5]; + { const uint32_t x10 = in1[4]; + { const uint32_t x8 = in1[3]; + { const uint32_t x6 = in1[2]; + { const uint32_t x4 = in1[1]; + { const uint32_t x2 = in1[0]; + { uint64_t x19 = ((uint64_t)x2 * x2); + { uint64_t x20 = ((uint64_t)(0x2 * x2) * x4); + { uint64_t x21 = (0x2 * (((uint64_t)x4 * x4) + ((uint64_t)x2 * x6))); + { uint64_t x22 = (0x2 * (((uint64_t)x4 * x6) + ((uint64_t)x2 * x8))); + { uint64_t x23 = ((((uint64_t)x6 * x6) + ((uint64_t)(0x4 * x4) * x8)) + ((uint64_t)(0x2 * x2) * x10)); + { uint64_t x24 = (0x2 * ((((uint64_t)x6 * x8) + ((uint64_t)x4 * x10)) + ((uint64_t)x2 * x12))); + { uint64_t x25 = (0x2 * (((((uint64_t)x8 * x8) + ((uint64_t)x6 * x10)) + ((uint64_t)x2 * x14)) + ((uint64_t)(0x2 * x4) * x12))); + { uint64_t x26 = (0x2 * (((((uint64_t)x8 * x10) + ((uint64_t)x6 * x12)) + ((uint64_t)x4 * x14)) + ((uint64_t)x2 * x16))); + { uint64_t x27 = (((uint64_t)x10 * x10) + (0x2 * ((((uint64_t)x6 * x14) + ((uint64_t)x2 * x18)) + (0x2 * (((uint64_t)x4 * x16) + ((uint64_t)x8 * x12)))))); + { uint64_t x28 = (0x2 * ((((((uint64_t)x10 * x12) + ((uint64_t)x8 * x14)) + ((uint64_t)x6 * x16)) + ((uint64_t)x4 * x18)) + ((uint64_t)x2 * x17))); + { uint64_t x29 = (0x2 * (((((uint64_t)x12 * x12) + ((uint64_t)x10 * x14)) + ((uint64_t)x6 * x18)) + (0x2 * (((uint64_t)x8 * x16) + ((uint64_t)x4 * x17))))); + { uint64_t x30 = (0x2 * (((((uint64_t)x12 * x14) + ((uint64_t)x10 * x16)) + ((uint64_t)x8 * x18)) + ((uint64_t)x6 * x17))); + { uint64_t x31 = (((uint64_t)x14 * x14) + (0x2 * (((uint64_t)x10 * x18) + (0x2 * (((uint64_t)x12 * x16) + ((uint64_t)x8 * x17)))))); + { uint64_t x32 = (0x2 * ((((uint64_t)x14 * x16) + ((uint64_t)x12 * x18)) + ((uint64_t)x10 * x17))); + { uint64_t x33 = (0x2 * ((((uint64_t)x16 * x16) + ((uint64_t)x14 * x18)) + ((uint64_t)(0x2 * x12) * x17))); + { uint64_t x34 = (0x2 * (((uint64_t)x16 * x18) + ((uint64_t)x14 * x17))); + { uint64_t x35 = (((uint64_t)x18 * x18) + ((uint64_t)(0x4 * x16) * x17)); + { uint64_t x36 = ((uint64_t)(0x2 * x18) * x17); + { uint64_t x37 = ((uint64_t)(0x2 * x17) * x17); + { uint64_t x38 = (x27 + (x37 << 0x4)); + { uint64_t x39 = (x38 + (x37 << 0x1)); + { uint64_t x40 = (x39 + x37); + { uint64_t x41 = (x26 + (x36 << 0x4)); + { uint64_t x42 = (x41 + (x36 << 0x1)); + { uint64_t x43 = (x42 + x36); + { uint64_t x44 = (x25 + (x35 << 0x4)); + { uint64_t x45 = (x44 + (x35 << 0x1)); + { uint64_t x46 = (x45 + x35); + { uint64_t x47 = (x24 + (x34 << 0x4)); + { uint64_t x48 = (x47 + (x34 << 0x1)); + { uint64_t x49 = (x48 + x34); + { uint64_t x50 = (x23 + (x33 << 0x4)); + { uint64_t x51 = (x50 + (x33 << 0x1)); + { uint64_t x52 = (x51 + x33); + { uint64_t x53 = (x22 + (x32 << 0x4)); + { uint64_t x54 = (x53 + (x32 << 0x1)); + { uint64_t x55 = (x54 + x32); + { uint64_t x56 = (x21 + (x31 << 0x4)); + { uint64_t x57 = (x56 + (x31 << 0x1)); + { uint64_t x58 = (x57 + x31); + { uint64_t x59 = (x20 + (x30 << 0x4)); + { uint64_t x60 = (x59 + (x30 << 0x1)); + { uint64_t x61 = (x60 + x30); + { uint64_t x62 = (x19 + (x29 << 0x4)); + { uint64_t x63 = (x62 + (x29 << 0x1)); + { uint64_t x64 = (x63 + x29); + { uint64_t x65 = (x64 >> 0x1a); + { uint32_t x66 = ((uint32_t)x64 & 0x3ffffff); + { uint64_t x67 = (x65 + x61); + { uint64_t x68 = (x67 >> 0x19); + { uint32_t x69 = ((uint32_t)x67 & 0x1ffffff); + { uint64_t x70 = (x68 + x58); + { uint64_t x71 = (x70 >> 0x1a); + { uint32_t x72 = ((uint32_t)x70 & 0x3ffffff); + { uint64_t x73 = (x71 + x55); + { uint64_t x74 = (x73 >> 0x19); + { uint32_t x75 = ((uint32_t)x73 & 0x1ffffff); + { uint64_t x76 = (x74 + x52); + { uint64_t x77 = (x76 >> 0x1a); + { uint32_t x78 = ((uint32_t)x76 & 0x3ffffff); + { uint64_t x79 = (x77 + x49); + { uint64_t x80 = (x79 >> 0x19); + { uint32_t x81 = ((uint32_t)x79 & 0x1ffffff); + { uint64_t x82 = (x80 + x46); + { uint64_t x83 = (x82 >> 0x1a); + { uint32_t x84 = ((uint32_t)x82 & 0x3ffffff); + { uint64_t x85 = (x83 + x43); + { uint64_t x86 = (x85 >> 0x19); + { uint32_t x87 = ((uint32_t)x85 & 0x1ffffff); + { uint64_t x88 = (x86 + x40); + { uint64_t x89 = (x88 >> 0x1a); + { uint32_t x90 = ((uint32_t)x88 & 0x3ffffff); + { uint64_t x91 = (x89 + x28); + { uint64_t x92 = (x91 >> 0x19); + { uint32_t x93 = ((uint32_t)x91 & 0x1ffffff); + { uint64_t x94 = (x66 + (0x13 * x92)); + { uint32_t x95 = (uint32_t) (x94 >> 0x1a); + { uint32_t x96 = ((uint32_t)x94 & 0x3ffffff); + { uint32_t x97 = (x95 + x69); + { uint32_t x98 = (x97 >> 0x19); + { uint32_t x99 = (x97 & 0x1ffffff); + out[0] = x96; + out[1] = x99; + out[2] = (x98 + x72); + out[3] = x75; + out[4] = x78; + out[5] = x81; + out[6] = x84; + out[7] = x87; + out[8] = x90; + out[9] = x93; + }}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} + assert_fe(out); +} + +static void fe_sq_tl(fe *h, const fe_loose *f) { + fe_sqr_impl(h->v, f->v); +} + +static void fe_sq_tt(fe *h, const fe *f) { + fe_sqr_impl(h->v, f->v); +} + +// Replace (f,g) with (g,f) if b == 1; +// replace (f,g) with (f,g) if b == 0. +// +// Preconditions: b in {0,1}. +static void fe_cswap(fe *f, fe *g, unsigned int b) { + b = 0-b; + unsigned i; + for (i = 0; i < 10; i++) { + uint32_t x = f->v[i] ^ g->v[i]; + x &= b; + f->v[i] ^= x; + g->v[i] ^= x; + } +} + +// NOTE: based on fiat-crypto fe_mul, edited for in2=121666, 0, 0.. +static void fe_mul_121666_impl(uint32_t out[10], const uint32_t in1[10]) { + { const uint32_t x20 = in1[9]; + { const uint32_t x21 = in1[8]; + { const uint32_t x19 = in1[7]; + { const uint32_t x17 = in1[6]; + { const uint32_t x15 = in1[5]; + { const uint32_t x13 = in1[4]; + { const uint32_t x11 = in1[3]; + { const uint32_t x9 = in1[2]; + { const uint32_t x7 = in1[1]; + { const uint32_t x5 = in1[0]; + { const uint32_t x38 = 0; + { const uint32_t x39 = 0; + { const uint32_t x37 = 0; + { const uint32_t x35 = 0; + { const uint32_t x33 = 0; + { const uint32_t x31 = 0; + { const uint32_t x29 = 0; + { const uint32_t x27 = 0; + { const uint32_t x25 = 0; + { const uint32_t x23 = 121666; + { uint64_t x40 = ((uint64_t)x23 * x5); + { uint64_t x41 = (((uint64_t)x23 * x7) + ((uint64_t)x25 * x5)); + { uint64_t x42 = ((((uint64_t)(0x2 * x25) * x7) + ((uint64_t)x23 * x9)) + ((uint64_t)x27 * x5)); + { uint64_t x43 = (((((uint64_t)x25 * x9) + ((uint64_t)x27 * x7)) + ((uint64_t)x23 * x11)) + ((uint64_t)x29 * x5)); + { uint64_t x44 = (((((uint64_t)x27 * x9) + (0x2 * (((uint64_t)x25 * x11) + ((uint64_t)x29 * x7)))) + ((uint64_t)x23 * x13)) + ((uint64_t)x31 * x5)); + { uint64_t x45 = (((((((uint64_t)x27 * x11) + ((uint64_t)x29 * x9)) + ((uint64_t)x25 * x13)) + ((uint64_t)x31 * x7)) + ((uint64_t)x23 * x15)) + ((uint64_t)x33 * x5)); + { uint64_t x46 = (((((0x2 * ((((uint64_t)x29 * x11) + ((uint64_t)x25 * x15)) + ((uint64_t)x33 * x7))) + ((uint64_t)x27 * x13)) + ((uint64_t)x31 * x9)) + ((uint64_t)x23 * x17)) + ((uint64_t)x35 * x5)); + { uint64_t x47 = (((((((((uint64_t)x29 * x13) + ((uint64_t)x31 * x11)) + ((uint64_t)x27 * x15)) + ((uint64_t)x33 * x9)) + ((uint64_t)x25 * x17)) + ((uint64_t)x35 * x7)) + ((uint64_t)x23 * x19)) + ((uint64_t)x37 * x5)); + { uint64_t x48 = (((((((uint64_t)x31 * x13) + (0x2 * (((((uint64_t)x29 * x15) + ((uint64_t)x33 * x11)) + ((uint64_t)x25 * x19)) + ((uint64_t)x37 * x7)))) + ((uint64_t)x27 * x17)) + ((uint64_t)x35 * x9)) + ((uint64_t)x23 * x21)) + ((uint64_t)x39 * x5)); + { uint64_t x49 = (((((((((((uint64_t)x31 * x15) + ((uint64_t)x33 * x13)) + ((uint64_t)x29 * x17)) + ((uint64_t)x35 * x11)) + ((uint64_t)x27 * x19)) + ((uint64_t)x37 * x9)) + ((uint64_t)x25 * x21)) + ((uint64_t)x39 * x7)) + ((uint64_t)x23 * x20)) + ((uint64_t)x38 * x5)); + { uint64_t x50 = (((((0x2 * ((((((uint64_t)x33 * x15) + ((uint64_t)x29 * x19)) + ((uint64_t)x37 * x11)) + ((uint64_t)x25 * x20)) + ((uint64_t)x38 * x7))) + ((uint64_t)x31 * x17)) + ((uint64_t)x35 * x13)) + ((uint64_t)x27 * x21)) + ((uint64_t)x39 * x9)); + { uint64_t x51 = (((((((((uint64_t)x33 * x17) + ((uint64_t)x35 * x15)) + ((uint64_t)x31 * x19)) + ((uint64_t)x37 * x13)) + ((uint64_t)x29 * x21)) + ((uint64_t)x39 * x11)) + ((uint64_t)x27 * x20)) + ((uint64_t)x38 * x9)); + { uint64_t x52 = (((((uint64_t)x35 * x17) + (0x2 * (((((uint64_t)x33 * x19) + ((uint64_t)x37 * x15)) + ((uint64_t)x29 * x20)) + ((uint64_t)x38 * x11)))) + ((uint64_t)x31 * x21)) + ((uint64_t)x39 * x13)); + { uint64_t x53 = (((((((uint64_t)x35 * x19) + ((uint64_t)x37 * x17)) + ((uint64_t)x33 * x21)) + ((uint64_t)x39 * x15)) + ((uint64_t)x31 * x20)) + ((uint64_t)x38 * x13)); + { uint64_t x54 = (((0x2 * ((((uint64_t)x37 * x19) + ((uint64_t)x33 * x20)) + ((uint64_t)x38 * x15))) + ((uint64_t)x35 * x21)) + ((uint64_t)x39 * x17)); + { uint64_t x55 = (((((uint64_t)x37 * x21) + ((uint64_t)x39 * x19)) + ((uint64_t)x35 * x20)) + ((uint64_t)x38 * x17)); + { uint64_t x56 = (((uint64_t)x39 * x21) + (0x2 * (((uint64_t)x37 * x20) + ((uint64_t)x38 * x19)))); + { uint64_t x57 = (((uint64_t)x39 * x20) + ((uint64_t)x38 * x21)); + { uint64_t x58 = ((uint64_t)(0x2 * x38) * x20); + { uint64_t x59 = (x48 + (x58 << 0x4)); + { uint64_t x60 = (x59 + (x58 << 0x1)); + { uint64_t x61 = (x60 + x58); + { uint64_t x62 = (x47 + (x57 << 0x4)); + { uint64_t x63 = (x62 + (x57 << 0x1)); + { uint64_t x64 = (x63 + x57); + { uint64_t x65 = (x46 + (x56 << 0x4)); + { uint64_t x66 = (x65 + (x56 << 0x1)); + { uint64_t x67 = (x66 + x56); + { uint64_t x68 = (x45 + (x55 << 0x4)); + { uint64_t x69 = (x68 + (x55 << 0x1)); + { uint64_t x70 = (x69 + x55); + { uint64_t x71 = (x44 + (x54 << 0x4)); + { uint64_t x72 = (x71 + (x54 << 0x1)); + { uint64_t x73 = (x72 + x54); + { uint64_t x74 = (x43 + (x53 << 0x4)); + { uint64_t x75 = (x74 + (x53 << 0x1)); + { uint64_t x76 = (x75 + x53); + { uint64_t x77 = (x42 + (x52 << 0x4)); + { uint64_t x78 = (x77 + (x52 << 0x1)); + { uint64_t x79 = (x78 + x52); + { uint64_t x80 = (x41 + (x51 << 0x4)); + { uint64_t x81 = (x80 + (x51 << 0x1)); + { uint64_t x82 = (x81 + x51); + { uint64_t x83 = (x40 + (x50 << 0x4)); + { uint64_t x84 = (x83 + (x50 << 0x1)); + { uint64_t x85 = (x84 + x50); + { uint64_t x86 = (x85 >> 0x1a); + { uint32_t x87 = ((uint32_t)x85 & 0x3ffffff); + { uint64_t x88 = (x86 + x82); + { uint64_t x89 = (x88 >> 0x19); + { uint32_t x90 = ((uint32_t)x88 & 0x1ffffff); + { uint64_t x91 = (x89 + x79); + { uint64_t x92 = (x91 >> 0x1a); + { uint32_t x93 = ((uint32_t)x91 & 0x3ffffff); + { uint64_t x94 = (x92 + x76); + { uint64_t x95 = (x94 >> 0x19); + { uint32_t x96 = ((uint32_t)x94 & 0x1ffffff); + { uint64_t x97 = (x95 + x73); + { uint64_t x98 = (x97 >> 0x1a); + { uint32_t x99 = ((uint32_t)x97 & 0x3ffffff); + { uint64_t x100 = (x98 + x70); + { uint64_t x101 = (x100 >> 0x19); + { uint32_t x102 = ((uint32_t)x100 & 0x1ffffff); + { uint64_t x103 = (x101 + x67); + { uint64_t x104 = (x103 >> 0x1a); + { uint32_t x105 = ((uint32_t)x103 & 0x3ffffff); + { uint64_t x106 = (x104 + x64); + { uint64_t x107 = (x106 >> 0x19); + { uint32_t x108 = ((uint32_t)x106 & 0x1ffffff); + { uint64_t x109 = (x107 + x61); + { uint64_t x110 = (x109 >> 0x1a); + { uint32_t x111 = ((uint32_t)x109 & 0x3ffffff); + { uint64_t x112 = (x110 + x49); + { uint64_t x113 = (x112 >> 0x19); + { uint32_t x114 = ((uint32_t)x112 & 0x1ffffff); + { uint64_t x115 = (x87 + (0x13 * x113)); + { uint32_t x116 = (uint32_t) (x115 >> 0x1a); + { uint32_t x117 = ((uint32_t)x115 & 0x3ffffff); + { uint32_t x118 = (x116 + x90); + { uint32_t x119 = (x118 >> 0x19); + { uint32_t x120 = (x118 & 0x1ffffff); + out[0] = x117; + out[1] = x120; + out[2] = (x119 + x93); + out[3] = x96; + out[4] = x99; + out[5] = x102; + out[6] = x105; + out[7] = x108; + out[8] = x111; + out[9] = x114; + }}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}} +} + +static void fe_mul121666(fe *h, const fe_loose *f) { + assert_fe_loose(f->v); + fe_mul_121666_impl(h->v, f->v); + assert_fe(h->v); +} + +// Adapted from Fiat-synthesized |fe_sub_impl| with |out| = 0. +static void fe_neg_impl(uint32_t out[10], const uint32_t in2[10]) { + { const uint32_t x20 = 0; + { const uint32_t x21 = 0; + { const uint32_t x19 = 0; + { const uint32_t x17 = 0; + { const uint32_t x15 = 0; + { const uint32_t x13 = 0; + { const uint32_t x11 = 0; + { const uint32_t x9 = 0; + { const uint32_t x7 = 0; + { const uint32_t x5 = 0; + { const uint32_t x38 = in2[9]; + { const uint32_t x39 = in2[8]; + { const uint32_t x37 = in2[7]; + { const uint32_t x35 = in2[6]; + { const uint32_t x33 = in2[5]; + { const uint32_t x31 = in2[4]; + { const uint32_t x29 = in2[3]; + { const uint32_t x27 = in2[2]; + { const uint32_t x25 = in2[1]; + { const uint32_t x23 = in2[0]; + out[0] = ((0x7ffffda + x5) - x23); + out[1] = ((0x3fffffe + x7) - x25); + out[2] = ((0x7fffffe + x9) - x27); + out[3] = ((0x3fffffe + x11) - x29); + out[4] = ((0x7fffffe + x13) - x31); + out[5] = ((0x3fffffe + x15) - x33); + out[6] = ((0x7fffffe + x17) - x35); + out[7] = ((0x3fffffe + x19) - x37); + out[8] = ((0x7fffffe + x21) - x39); + out[9] = ((0x3fffffe + x20) - x38); + }}}}}}}}}}}}}}}}}}}} +} + +// h = -f +static void fe_neg(fe_loose *h, const fe *f) { + assert_fe(f->v); + fe_neg_impl(h->v, f->v); + assert_fe_loose(h->v); +} + +// Replace (f,g) with (g,g) if b == 1; +// replace (f,g) with (f,g) if b == 0. +// +// Preconditions: b in {0,1}. +static void fe_cmov(fe_loose *f, const fe_loose *g, unsigned b) { + b = 0-b; + unsigned i; + for (i = 0; i < 10; i++) { + uint32_t x = f->v[i] ^ g->v[i]; + x &= b; + f->v[i] ^= x; + } +} + +#endif // BORINGSSL_CURVE25519_64BIT + +// h = f +static void fe_copy(fe *h, const fe *f) { + OPENSSL_memmove(h, f, sizeof(fe)); +} + +static void fe_copy_lt(fe_loose *h, const fe *f) { + OPENSSL_COMPILE_ASSERT(sizeof(fe_loose) == sizeof(fe), + fe_and_fe_loose_mismatch); + OPENSSL_memmove(h, f, sizeof(fe)); +} +#if !defined(OPENSSL_SMALL) +static void fe_copy_ll(fe_loose *h, const fe_loose *f) { + OPENSSL_memmove(h, f, sizeof(fe_loose)); +} +#endif // !defined(OPENSSL_SMALL) + +static void fe_loose_invert(fe *out, const fe_loose *z) { + fe t0; + fe t1; + fe t2; + fe t3; + int i; + + fe_sq_tl(&t0, z); + fe_sq_tt(&t1, &t0); + for (i = 1; i < 2; ++i) { + fe_sq_tt(&t1, &t1); + } + fe_mul_tlt(&t1, z, &t1); + fe_mul_ttt(&t0, &t0, &t1); + fe_sq_tt(&t2, &t0); + fe_mul_ttt(&t1, &t1, &t2); + fe_sq_tt(&t2, &t1); + for (i = 1; i < 5; ++i) { + fe_sq_tt(&t2, &t2); + } + fe_mul_ttt(&t1, &t2, &t1); + fe_sq_tt(&t2, &t1); + for (i = 1; i < 10; ++i) { + fe_sq_tt(&t2, &t2); + } + fe_mul_ttt(&t2, &t2, &t1); + fe_sq_tt(&t3, &t2); + for (i = 1; i < 20; ++i) { + fe_sq_tt(&t3, &t3); + } + fe_mul_ttt(&t2, &t3, &t2); + fe_sq_tt(&t2, &t2); + for (i = 1; i < 10; ++i) { + fe_sq_tt(&t2, &t2); + } + fe_mul_ttt(&t1, &t2, &t1); + fe_sq_tt(&t2, &t1); + for (i = 1; i < 50; ++i) { + fe_sq_tt(&t2, &t2); + } + fe_mul_ttt(&t2, &t2, &t1); + fe_sq_tt(&t3, &t2); + for (i = 1; i < 100; ++i) { + fe_sq_tt(&t3, &t3); + } + fe_mul_ttt(&t2, &t3, &t2); + fe_sq_tt(&t2, &t2); + for (i = 1; i < 50; ++i) { + fe_sq_tt(&t2, &t2); + } + fe_mul_ttt(&t1, &t2, &t1); + fe_sq_tt(&t1, &t1); + for (i = 1; i < 5; ++i) { + fe_sq_tt(&t1, &t1); + } + fe_mul_ttt(out, &t1, &t0); +} + +static void fe_invert(fe *out, const fe *z) { + fe_loose l; + fe_copy_lt(&l, z); + fe_loose_invert(out, &l); +} + +// return 0 if f == 0 +// return 1 if f != 0 +static int fe_isnonzero(const fe_loose *f) { + fe tight; + fe_carry(&tight, f); + uint8_t s[32]; + fe_tobytes(s, &tight); + + static const uint8_t zero[32] = {0}; + return CRYPTO_memcmp(s, zero, sizeof(zero)) != 0; +} + +// return 1 if f is in {1,3,5,...,q-2} +// return 0 if f is in {0,2,4,...,q-1} +static int fe_isnegative(const fe *f) { + uint8_t s[32]; + fe_tobytes(s, f); + return s[0] & 1; +} + +static void fe_sq2_tt(fe *h, const fe *f) { + // h = f^2 + fe_sq_tt(h, f); + + // h = h + h + fe_loose tmp; + fe_add(&tmp, h, h); + fe_carry(h, &tmp); +} + +static void fe_pow22523(fe *out, const fe *z) { + fe t0; + fe t1; + fe t2; + int i; + + fe_sq_tt(&t0, z); + fe_sq_tt(&t1, &t0); + for (i = 1; i < 2; ++i) { + fe_sq_tt(&t1, &t1); + } + fe_mul_ttt(&t1, z, &t1); + fe_mul_ttt(&t0, &t0, &t1); + fe_sq_tt(&t0, &t0); + fe_mul_ttt(&t0, &t1, &t0); + fe_sq_tt(&t1, &t0); + for (i = 1; i < 5; ++i) { + fe_sq_tt(&t1, &t1); + } + fe_mul_ttt(&t0, &t1, &t0); + fe_sq_tt(&t1, &t0); + for (i = 1; i < 10; ++i) { + fe_sq_tt(&t1, &t1); + } + fe_mul_ttt(&t1, &t1, &t0); + fe_sq_tt(&t2, &t1); + for (i = 1; i < 20; ++i) { + fe_sq_tt(&t2, &t2); + } + fe_mul_ttt(&t1, &t2, &t1); + fe_sq_tt(&t1, &t1); + for (i = 1; i < 10; ++i) { + fe_sq_tt(&t1, &t1); + } + fe_mul_ttt(&t0, &t1, &t0); + fe_sq_tt(&t1, &t0); + for (i = 1; i < 50; ++i) { + fe_sq_tt(&t1, &t1); + } + fe_mul_ttt(&t1, &t1, &t0); + fe_sq_tt(&t2, &t1); + for (i = 1; i < 100; ++i) { + fe_sq_tt(&t2, &t2); + } + fe_mul_ttt(&t1, &t2, &t1); + fe_sq_tt(&t1, &t1); + for (i = 1; i < 50; ++i) { + fe_sq_tt(&t1, &t1); + } + fe_mul_ttt(&t0, &t1, &t0); + fe_sq_tt(&t0, &t0); + for (i = 1; i < 2; ++i) { + fe_sq_tt(&t0, &t0); + } + fe_mul_ttt(out, &t0, z); +} + + +// Group operations. + +void x25519_ge_tobytes(uint8_t s[32], const ge_p2 *h) { + fe recip; + fe x; + fe y; + + fe_invert(&recip, &h->Z); + fe_mul_ttt(&x, &h->X, &recip); + fe_mul_ttt(&y, &h->Y, &recip); + fe_tobytes(s, &y); + s[31] ^= fe_isnegative(&x) << 7; +} + +static void ge_p3_tobytes(uint8_t s[32], const ge_p3 *h) { + fe recip; + fe x; + fe y; + + fe_invert(&recip, &h->Z); + fe_mul_ttt(&x, &h->X, &recip); + fe_mul_ttt(&y, &h->Y, &recip); + fe_tobytes(s, &y); + s[31] ^= fe_isnegative(&x) << 7; +} + +int x25519_ge_frombytes_vartime(ge_p3 *h, const uint8_t *s) { + fe u; + fe_loose v; + fe v3; + fe vxx; + fe_loose check; + + fe_frombytes(&h->Y, s); + fe_1(&h->Z); + fe_sq_tt(&v3, &h->Y); + fe_mul_ttt(&vxx, &v3, &d); + fe_sub(&v, &v3, &h->Z); // u = y^2-1 + fe_carry(&u, &v); + fe_add(&v, &vxx, &h->Z); // v = dy^2+1 + + fe_sq_tl(&v3, &v); + fe_mul_ttl(&v3, &v3, &v); // v3 = v^3 + fe_sq_tt(&h->X, &v3); + fe_mul_ttl(&h->X, &h->X, &v); + fe_mul_ttt(&h->X, &h->X, &u); // x = uv^7 + + fe_pow22523(&h->X, &h->X); // x = (uv^7)^((q-5)/8) + fe_mul_ttt(&h->X, &h->X, &v3); + fe_mul_ttt(&h->X, &h->X, &u); // x = uv^3(uv^7)^((q-5)/8) + + fe_sq_tt(&vxx, &h->X); + fe_mul_ttl(&vxx, &vxx, &v); + fe_sub(&check, &vxx, &u); + if (fe_isnonzero(&check)) { + fe_add(&check, &vxx, &u); + if (fe_isnonzero(&check)) { + return -1; + } + fe_mul_ttt(&h->X, &h->X, &sqrtm1); + } + + if (fe_isnegative(&h->X) != (s[31] >> 7)) { + fe_loose t; + fe_neg(&t, &h->X); + fe_carry(&h->X, &t); + } + + fe_mul_ttt(&h->T, &h->X, &h->Y); + return 0; +} + +static void ge_p2_0(ge_p2 *h) { + fe_0(&h->X); + fe_1(&h->Y); + fe_1(&h->Z); +} + +static void ge_p3_0(ge_p3 *h) { + fe_0(&h->X); + fe_1(&h->Y); + fe_1(&h->Z); + fe_0(&h->T); +} + +static void ge_cached_0(ge_cached *h) { + fe_loose_1(&h->YplusX); + fe_loose_1(&h->YminusX); + fe_loose_1(&h->Z); + fe_loose_0(&h->T2d); +} + +static void ge_precomp_0(ge_precomp *h) { + fe_loose_1(&h->yplusx); + fe_loose_1(&h->yminusx); + fe_loose_0(&h->xy2d); +} + +// r = p +static void ge_p3_to_p2(ge_p2 *r, const ge_p3 *p) { + fe_copy(&r->X, &p->X); + fe_copy(&r->Y, &p->Y); + fe_copy(&r->Z, &p->Z); +} + +// r = p +void x25519_ge_p3_to_cached(ge_cached *r, const ge_p3 *p) { + fe_add(&r->YplusX, &p->Y, &p->X); + fe_sub(&r->YminusX, &p->Y, &p->X); + fe_copy_lt(&r->Z, &p->Z); + fe_mul_ltt(&r->T2d, &p->T, &d2); +} + +// r = p +void x25519_ge_p1p1_to_p2(ge_p2 *r, const ge_p1p1 *p) { + fe_mul_tll(&r->X, &p->X, &p->T); + fe_mul_tll(&r->Y, &p->Y, &p->Z); + fe_mul_tll(&r->Z, &p->Z, &p->T); +} + +// r = p +void x25519_ge_p1p1_to_p3(ge_p3 *r, const ge_p1p1 *p) { + fe_mul_tll(&r->X, &p->X, &p->T); + fe_mul_tll(&r->Y, &p->Y, &p->Z); + fe_mul_tll(&r->Z, &p->Z, &p->T); + fe_mul_tll(&r->T, &p->X, &p->Y); +} + +// r = p +static void ge_p1p1_to_cached(ge_cached *r, const ge_p1p1 *p) { + ge_p3 t; + x25519_ge_p1p1_to_p3(&t, p); + x25519_ge_p3_to_cached(r, &t); +} + +// r = 2 * p +static void ge_p2_dbl(ge_p1p1 *r, const ge_p2 *p) { + fe trX, trZ, trT; + fe t0; + + fe_sq_tt(&trX, &p->X); + fe_sq_tt(&trZ, &p->Y); + fe_sq2_tt(&trT, &p->Z); + fe_add(&r->Y, &p->X, &p->Y); + fe_sq_tl(&t0, &r->Y); + + fe_add(&r->Y, &trZ, &trX); + fe_sub(&r->Z, &trZ, &trX); + fe_carry(&trZ, &r->Y); + fe_sub(&r->X, &t0, &trZ); + fe_carry(&trZ, &r->Z); + fe_sub(&r->T, &trT, &trZ); +} + +// r = 2 * p +static void ge_p3_dbl(ge_p1p1 *r, const ge_p3 *p) { + ge_p2 q; + ge_p3_to_p2(&q, p); + ge_p2_dbl(r, &q); +} + +// r = p + q +static void ge_madd(ge_p1p1 *r, const ge_p3 *p, const ge_precomp *q) { + fe trY, trZ, trT; + + fe_add(&r->X, &p->Y, &p->X); + fe_sub(&r->Y, &p->Y, &p->X); + fe_mul_tll(&trZ, &r->X, &q->yplusx); + fe_mul_tll(&trY, &r->Y, &q->yminusx); + fe_mul_tlt(&trT, &q->xy2d, &p->T); + fe_add(&r->T, &p->Z, &p->Z); + fe_sub(&r->X, &trZ, &trY); + fe_add(&r->Y, &trZ, &trY); + fe_carry(&trZ, &r->T); + fe_add(&r->Z, &trZ, &trT); + fe_sub(&r->T, &trZ, &trT); +} + +// r = p - q +static void ge_msub(ge_p1p1 *r, const ge_p3 *p, const ge_precomp *q) { + fe trY, trZ, trT; + + fe_add(&r->X, &p->Y, &p->X); + fe_sub(&r->Y, &p->Y, &p->X); + fe_mul_tll(&trZ, &r->X, &q->yminusx); + fe_mul_tll(&trY, &r->Y, &q->yplusx); + fe_mul_tlt(&trT, &q->xy2d, &p->T); + fe_add(&r->T, &p->Z, &p->Z); + fe_sub(&r->X, &trZ, &trY); + fe_add(&r->Y, &trZ, &trY); + fe_carry(&trZ, &r->T); + fe_sub(&r->Z, &trZ, &trT); + fe_add(&r->T, &trZ, &trT); +} + +// r = p + q +void x25519_ge_add(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q) { + fe trX, trY, trZ, trT; + + fe_add(&r->X, &p->Y, &p->X); + fe_sub(&r->Y, &p->Y, &p->X); + fe_mul_tll(&trZ, &r->X, &q->YplusX); + fe_mul_tll(&trY, &r->Y, &q->YminusX); + fe_mul_tlt(&trT, &q->T2d, &p->T); + fe_mul_ttl(&trX, &p->Z, &q->Z); + fe_add(&r->T, &trX, &trX); + fe_sub(&r->X, &trZ, &trY); + fe_add(&r->Y, &trZ, &trY); + fe_carry(&trZ, &r->T); + fe_add(&r->Z, &trZ, &trT); + fe_sub(&r->T, &trZ, &trT); +} + +// r = p - q +void x25519_ge_sub(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q) { + fe trX, trY, trZ, trT; + + fe_add(&r->X, &p->Y, &p->X); + fe_sub(&r->Y, &p->Y, &p->X); + fe_mul_tll(&trZ, &r->X, &q->YminusX); + fe_mul_tll(&trY, &r->Y, &q->YplusX); + fe_mul_tlt(&trT, &q->T2d, &p->T); + fe_mul_ttl(&trX, &p->Z, &q->Z); + fe_add(&r->T, &trX, &trX); + fe_sub(&r->X, &trZ, &trY); + fe_add(&r->Y, &trZ, &trY); + fe_carry(&trZ, &r->T); + fe_sub(&r->Z, &trZ, &trT); + fe_add(&r->T, &trZ, &trT); +} + +static uint8_t equal(signed char b, signed char c) { + uint8_t ub = b; + uint8_t uc = c; + uint8_t x = ub ^ uc; // 0: yes; 1..255: no + uint32_t y = x; // 0: yes; 1..255: no + y -= 1; // 4294967295: yes; 0..254: no + y >>= 31; // 1: yes; 0: no + return y; +} + +static void cmov(ge_precomp *t, const ge_precomp *u, uint8_t b) { + fe_cmov(&t->yplusx, &u->yplusx, b); + fe_cmov(&t->yminusx, &u->yminusx, b); + fe_cmov(&t->xy2d, &u->xy2d, b); +} + +void x25519_ge_scalarmult_small_precomp( + ge_p3 *h, const uint8_t a[32], const uint8_t precomp_table[15 * 2 * 32]) { + // precomp_table is first expanded into matching |ge_precomp| + // elements. + ge_precomp multiples[15]; + + unsigned i; + for (i = 0; i < 15; i++) { + const uint8_t *bytes = &precomp_table[i*(2 * 32)]; + fe x, y; + fe_frombytes(&x, bytes); + fe_frombytes(&y, bytes + 32); + + ge_precomp *out = &multiples[i]; + fe_add(&out->yplusx, &y, &x); + fe_sub(&out->yminusx, &y, &x); + fe_mul_ltt(&out->xy2d, &x, &y); + fe_mul_llt(&out->xy2d, &out->xy2d, &d2); + } + + // See the comment above |k25519SmallPrecomp| about the structure of the + // precomputed elements. This loop does 64 additions and 64 doublings to + // calculate the result. + ge_p3_0(h); + + for (i = 63; i < 64; i--) { + unsigned j; + signed char index = 0; + + for (j = 0; j < 4; j++) { + const uint8_t bit = 1 & (a[(8 * j) + (i / 8)] >> (i & 7)); + index |= (bit << j); + } + + ge_precomp e; + ge_precomp_0(&e); + + for (j = 1; j < 16; j++) { + cmov(&e, &multiples[j-1], equal(index, j)); + } + + ge_cached cached; + ge_p1p1 r; + x25519_ge_p3_to_cached(&cached, h); + x25519_ge_add(&r, h, &cached); + x25519_ge_p1p1_to_p3(h, &r); + + ge_madd(&r, h, &e); + x25519_ge_p1p1_to_p3(h, &r); + } +} + +#if defined(OPENSSL_SMALL) + +void x25519_ge_scalarmult_base(ge_p3 *h, const uint8_t a[32]) { + x25519_ge_scalarmult_small_precomp(h, a, k25519SmallPrecomp); +} + +#else + +static uint8_t negative(signed char b) { + uint32_t x = b; + x >>= 31; // 1: yes; 0: no + return x; +} + +static void table_select(ge_precomp *t, int pos, signed char b) { + ge_precomp minust; + uint8_t bnegative = negative(b); + uint8_t babs = b - ((uint8_t)((-bnegative) & b) << 1); + + ge_precomp_0(t); + cmov(t, &k25519Precomp[pos][0], equal(babs, 1)); + cmov(t, &k25519Precomp[pos][1], equal(babs, 2)); + cmov(t, &k25519Precomp[pos][2], equal(babs, 3)); + cmov(t, &k25519Precomp[pos][3], equal(babs, 4)); + cmov(t, &k25519Precomp[pos][4], equal(babs, 5)); + cmov(t, &k25519Precomp[pos][5], equal(babs, 6)); + cmov(t, &k25519Precomp[pos][6], equal(babs, 7)); + cmov(t, &k25519Precomp[pos][7], equal(babs, 8)); + fe_copy_ll(&minust.yplusx, &t->yminusx); + fe_copy_ll(&minust.yminusx, &t->yplusx); + + // NOTE: the input table is canonical, but types don't encode it + fe tmp; + fe_carry(&tmp, &t->xy2d); + fe_neg(&minust.xy2d, &tmp); + + cmov(t, &minust, bnegative); +} + +// h = a * B +// where a = a[0]+256*a[1]+...+256^31 a[31] +// B is the Ed25519 base point (x,4/5) with x positive. +// +// Preconditions: +// a[31] <= 127 +void x25519_ge_scalarmult_base(ge_p3 *h, const uint8_t *a) { + signed char e[64]; + signed char carry; + ge_p1p1 r; + ge_p2 s; + ge_precomp t; + int i; + + for (i = 0; i < 32; ++i) { + e[2 * i + 0] = (a[i] >> 0) & 15; + e[2 * i + 1] = (a[i] >> 4) & 15; + } + // each e[i] is between 0 and 15 + // e[63] is between 0 and 7 + + carry = 0; + for (i = 0; i < 63; ++i) { + e[i] += carry; + carry = e[i] + 8; + carry >>= 4; + e[i] -= carry << 4; + } + e[63] += carry; + // each e[i] is between -8 and 8 + + ge_p3_0(h); + for (i = 1; i < 64; i += 2) { + table_select(&t, i / 2, e[i]); + ge_madd(&r, h, &t); + x25519_ge_p1p1_to_p3(h, &r); + } + + ge_p3_dbl(&r, h); + x25519_ge_p1p1_to_p2(&s, &r); + ge_p2_dbl(&r, &s); + x25519_ge_p1p1_to_p2(&s, &r); + ge_p2_dbl(&r, &s); + x25519_ge_p1p1_to_p2(&s, &r); + ge_p2_dbl(&r, &s); + x25519_ge_p1p1_to_p3(h, &r); + + for (i = 0; i < 64; i += 2) { + table_select(&t, i / 2, e[i]); + ge_madd(&r, h, &t); + x25519_ge_p1p1_to_p3(h, &r); + } +} + +#endif + +static void cmov_cached(ge_cached *t, ge_cached *u, uint8_t b) { + fe_cmov(&t->YplusX, &u->YplusX, b); + fe_cmov(&t->YminusX, &u->YminusX, b); + fe_cmov(&t->Z, &u->Z, b); + fe_cmov(&t->T2d, &u->T2d, b); +} + +// r = scalar * A. +// where a = a[0]+256*a[1]+...+256^31 a[31]. +void x25519_ge_scalarmult(ge_p2 *r, const uint8_t *scalar, const ge_p3 *A) { + ge_p2 Ai_p2[8]; + ge_cached Ai[16]; + ge_p1p1 t; + + ge_cached_0(&Ai[0]); + x25519_ge_p3_to_cached(&Ai[1], A); + ge_p3_to_p2(&Ai_p2[1], A); + + unsigned i; + for (i = 2; i < 16; i += 2) { + ge_p2_dbl(&t, &Ai_p2[i / 2]); + ge_p1p1_to_cached(&Ai[i], &t); + if (i < 8) { + x25519_ge_p1p1_to_p2(&Ai_p2[i], &t); + } + x25519_ge_add(&t, A, &Ai[i]); + ge_p1p1_to_cached(&Ai[i + 1], &t); + if (i < 7) { + x25519_ge_p1p1_to_p2(&Ai_p2[i + 1], &t); + } + } + + ge_p2_0(r); + ge_p3 u; + + for (i = 0; i < 256; i += 4) { + ge_p2_dbl(&t, r); + x25519_ge_p1p1_to_p2(r, &t); + ge_p2_dbl(&t, r); + x25519_ge_p1p1_to_p2(r, &t); + ge_p2_dbl(&t, r); + x25519_ge_p1p1_to_p2(r, &t); + ge_p2_dbl(&t, r); + x25519_ge_p1p1_to_p3(&u, &t); + + uint8_t index = scalar[31 - i/8]; + index >>= 4 - (i & 4); + index &= 0xf; + + unsigned j; + ge_cached selected; + ge_cached_0(&selected); + for (j = 0; j < 16; j++) { + cmov_cached(&selected, &Ai[j], equal(j, index)); + } + + x25519_ge_add(&t, &u, &selected); + x25519_ge_p1p1_to_p2(r, &t); + } +} + +static void slide(signed char *r, const uint8_t *a) { + int i; + int b; + int k; + + for (i = 0; i < 256; ++i) { + r[i] = 1 & (a[i >> 3] >> (i & 7)); + } + + for (i = 0; i < 256; ++i) { + if (r[i]) { + for (b = 1; b <= 6 && i + b < 256; ++b) { + if (r[i + b]) { + if (r[i] + (r[i + b] << b) <= 15) { + r[i] += r[i + b] << b; + r[i + b] = 0; + } else if (r[i] - (r[i + b] << b) >= -15) { + r[i] -= r[i + b] << b; + for (k = i + b; k < 256; ++k) { + if (!r[k]) { + r[k] = 1; + break; + } + r[k] = 0; + } + } else { + break; + } + } + } + } + } +} + +// r = a * A + b * B +// where a = a[0]+256*a[1]+...+256^31 a[31]. +// and b = b[0]+256*b[1]+...+256^31 b[31]. +// B is the Ed25519 base point (x,4/5) with x positive. +static void ge_double_scalarmult_vartime(ge_p2 *r, const uint8_t *a, + const ge_p3 *A, const uint8_t *b) { + signed char aslide[256]; + signed char bslide[256]; + ge_cached Ai[8]; // A,3A,5A,7A,9A,11A,13A,15A + ge_p1p1 t; + ge_p3 u; + ge_p3 A2; + int i; + + slide(aslide, a); + slide(bslide, b); + + x25519_ge_p3_to_cached(&Ai[0], A); + ge_p3_dbl(&t, A); + x25519_ge_p1p1_to_p3(&A2, &t); + x25519_ge_add(&t, &A2, &Ai[0]); + x25519_ge_p1p1_to_p3(&u, &t); + x25519_ge_p3_to_cached(&Ai[1], &u); + x25519_ge_add(&t, &A2, &Ai[1]); + x25519_ge_p1p1_to_p3(&u, &t); + x25519_ge_p3_to_cached(&Ai[2], &u); + x25519_ge_add(&t, &A2, &Ai[2]); + x25519_ge_p1p1_to_p3(&u, &t); + x25519_ge_p3_to_cached(&Ai[3], &u); + x25519_ge_add(&t, &A2, &Ai[3]); + x25519_ge_p1p1_to_p3(&u, &t); + x25519_ge_p3_to_cached(&Ai[4], &u); + x25519_ge_add(&t, &A2, &Ai[4]); + x25519_ge_p1p1_to_p3(&u, &t); + x25519_ge_p3_to_cached(&Ai[5], &u); + x25519_ge_add(&t, &A2, &Ai[5]); + x25519_ge_p1p1_to_p3(&u, &t); + x25519_ge_p3_to_cached(&Ai[6], &u); + x25519_ge_add(&t, &A2, &Ai[6]); + x25519_ge_p1p1_to_p3(&u, &t); + x25519_ge_p3_to_cached(&Ai[7], &u); + + ge_p2_0(r); + + for (i = 255; i >= 0; --i) { + if (aslide[i] || bslide[i]) { + break; + } + } + + for (; i >= 0; --i) { + ge_p2_dbl(&t, r); + + if (aslide[i] > 0) { + x25519_ge_p1p1_to_p3(&u, &t); + x25519_ge_add(&t, &u, &Ai[aslide[i] / 2]); + } else if (aslide[i] < 0) { + x25519_ge_p1p1_to_p3(&u, &t); + x25519_ge_sub(&t, &u, &Ai[(-aslide[i]) / 2]); + } + + if (bslide[i] > 0) { + x25519_ge_p1p1_to_p3(&u, &t); + ge_madd(&t, &u, &Bi[bslide[i] / 2]); + } else if (bslide[i] < 0) { + x25519_ge_p1p1_to_p3(&u, &t); + ge_msub(&t, &u, &Bi[(-bslide[i]) / 2]); + } + + x25519_ge_p1p1_to_p2(r, &t); + } +} + +// The set of scalars is \Z/l +// where l = 2^252 + 27742317777372353535851937790883648493. + +// Input: +// s[0]+256*s[1]+...+256^63*s[63] = s +// +// Output: +// s[0]+256*s[1]+...+256^31*s[31] = s mod l +// where l = 2^252 + 27742317777372353535851937790883648493. +// Overwrites s in place. +void x25519_sc_reduce(uint8_t s[64]) { + int64_t s0 = 2097151 & load_3(s); + int64_t s1 = 2097151 & (load_4(s + 2) >> 5); + int64_t s2 = 2097151 & (load_3(s + 5) >> 2); + int64_t s3 = 2097151 & (load_4(s + 7) >> 7); + int64_t s4 = 2097151 & (load_4(s + 10) >> 4); + int64_t s5 = 2097151 & (load_3(s + 13) >> 1); + int64_t s6 = 2097151 & (load_4(s + 15) >> 6); + int64_t s7 = 2097151 & (load_3(s + 18) >> 3); + int64_t s8 = 2097151 & load_3(s + 21); + int64_t s9 = 2097151 & (load_4(s + 23) >> 5); + int64_t s10 = 2097151 & (load_3(s + 26) >> 2); + int64_t s11 = 2097151 & (load_4(s + 28) >> 7); + int64_t s12 = 2097151 & (load_4(s + 31) >> 4); + int64_t s13 = 2097151 & (load_3(s + 34) >> 1); + int64_t s14 = 2097151 & (load_4(s + 36) >> 6); + int64_t s15 = 2097151 & (load_3(s + 39) >> 3); + int64_t s16 = 2097151 & load_3(s + 42); + int64_t s17 = 2097151 & (load_4(s + 44) >> 5); + int64_t s18 = 2097151 & (load_3(s + 47) >> 2); + int64_t s19 = 2097151 & (load_4(s + 49) >> 7); + int64_t s20 = 2097151 & (load_4(s + 52) >> 4); + int64_t s21 = 2097151 & (load_3(s + 55) >> 1); + int64_t s22 = 2097151 & (load_4(s + 57) >> 6); + int64_t s23 = (load_4(s + 60) >> 3); + int64_t carry0; + int64_t carry1; + int64_t carry2; + int64_t carry3; + int64_t carry4; + int64_t carry5; + int64_t carry6; + int64_t carry7; + int64_t carry8; + int64_t carry9; + int64_t carry10; + int64_t carry11; + int64_t carry12; + int64_t carry13; + int64_t carry14; + int64_t carry15; + int64_t carry16; + + s11 += s23 * 666643; + s12 += s23 * 470296; + s13 += s23 * 654183; + s14 -= s23 * 997805; + s15 += s23 * 136657; + s16 -= s23 * 683901; + s23 = 0; + + s10 += s22 * 666643; + s11 += s22 * 470296; + s12 += s22 * 654183; + s13 -= s22 * 997805; + s14 += s22 * 136657; + s15 -= s22 * 683901; + s22 = 0; + + s9 += s21 * 666643; + s10 += s21 * 470296; + s11 += s21 * 654183; + s12 -= s21 * 997805; + s13 += s21 * 136657; + s14 -= s21 * 683901; + s21 = 0; + + s8 += s20 * 666643; + s9 += s20 * 470296; + s10 += s20 * 654183; + s11 -= s20 * 997805; + s12 += s20 * 136657; + s13 -= s20 * 683901; + s20 = 0; + + s7 += s19 * 666643; + s8 += s19 * 470296; + s9 += s19 * 654183; + s10 -= s19 * 997805; + s11 += s19 * 136657; + s12 -= s19 * 683901; + s19 = 0; + + s6 += s18 * 666643; + s7 += s18 * 470296; + s8 += s18 * 654183; + s9 -= s18 * 997805; + s10 += s18 * 136657; + s11 -= s18 * 683901; + s18 = 0; + + carry6 = (s6 + (1 << 20)) >> 21; + s7 += carry6; + s6 -= carry6 << 21; + carry8 = (s8 + (1 << 20)) >> 21; + s9 += carry8; + s8 -= carry8 << 21; + carry10 = (s10 + (1 << 20)) >> 21; + s11 += carry10; + s10 -= carry10 << 21; + carry12 = (s12 + (1 << 20)) >> 21; + s13 += carry12; + s12 -= carry12 << 21; + carry14 = (s14 + (1 << 20)) >> 21; + s15 += carry14; + s14 -= carry14 << 21; + carry16 = (s16 + (1 << 20)) >> 21; + s17 += carry16; + s16 -= carry16 << 21; + + carry7 = (s7 + (1 << 20)) >> 21; + s8 += carry7; + s7 -= carry7 << 21; + carry9 = (s9 + (1 << 20)) >> 21; + s10 += carry9; + s9 -= carry9 << 21; + carry11 = (s11 + (1 << 20)) >> 21; + s12 += carry11; + s11 -= carry11 << 21; + carry13 = (s13 + (1 << 20)) >> 21; + s14 += carry13; + s13 -= carry13 << 21; + carry15 = (s15 + (1 << 20)) >> 21; + s16 += carry15; + s15 -= carry15 << 21; + + s5 += s17 * 666643; + s6 += s17 * 470296; + s7 += s17 * 654183; + s8 -= s17 * 997805; + s9 += s17 * 136657; + s10 -= s17 * 683901; + s17 = 0; + + s4 += s16 * 666643; + s5 += s16 * 470296; + s6 += s16 * 654183; + s7 -= s16 * 997805; + s8 += s16 * 136657; + s9 -= s16 * 683901; + s16 = 0; + + s3 += s15 * 666643; + s4 += s15 * 470296; + s5 += s15 * 654183; + s6 -= s15 * 997805; + s7 += s15 * 136657; + s8 -= s15 * 683901; + s15 = 0; + + s2 += s14 * 666643; + s3 += s14 * 470296; + s4 += s14 * 654183; + s5 -= s14 * 997805; + s6 += s14 * 136657; + s7 -= s14 * 683901; + s14 = 0; + + s1 += s13 * 666643; + s2 += s13 * 470296; + s3 += s13 * 654183; + s4 -= s13 * 997805; + s5 += s13 * 136657; + s6 -= s13 * 683901; + s13 = 0; + + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + s12 = 0; + + carry0 = (s0 + (1 << 20)) >> 21; + s1 += carry0; + s0 -= carry0 << 21; + carry2 = (s2 + (1 << 20)) >> 21; + s3 += carry2; + s2 -= carry2 << 21; + carry4 = (s4 + (1 << 20)) >> 21; + s5 += carry4; + s4 -= carry4 << 21; + carry6 = (s6 + (1 << 20)) >> 21; + s7 += carry6; + s6 -= carry6 << 21; + carry8 = (s8 + (1 << 20)) >> 21; + s9 += carry8; + s8 -= carry8 << 21; + carry10 = (s10 + (1 << 20)) >> 21; + s11 += carry10; + s10 -= carry10 << 21; + + carry1 = (s1 + (1 << 20)) >> 21; + s2 += carry1; + s1 -= carry1 << 21; + carry3 = (s3 + (1 << 20)) >> 21; + s4 += carry3; + s3 -= carry3 << 21; + carry5 = (s5 + (1 << 20)) >> 21; + s6 += carry5; + s5 -= carry5 << 21; + carry7 = (s7 + (1 << 20)) >> 21; + s8 += carry7; + s7 -= carry7 << 21; + carry9 = (s9 + (1 << 20)) >> 21; + s10 += carry9; + s9 -= carry9 << 21; + carry11 = (s11 + (1 << 20)) >> 21; + s12 += carry11; + s11 -= carry11 << 21; + + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + s12 = 0; + + carry0 = s0 >> 21; + s1 += carry0; + s0 -= carry0 << 21; + carry1 = s1 >> 21; + s2 += carry1; + s1 -= carry1 << 21; + carry2 = s2 >> 21; + s3 += carry2; + s2 -= carry2 << 21; + carry3 = s3 >> 21; + s4 += carry3; + s3 -= carry3 << 21; + carry4 = s4 >> 21; + s5 += carry4; + s4 -= carry4 << 21; + carry5 = s5 >> 21; + s6 += carry5; + s5 -= carry5 << 21; + carry6 = s6 >> 21; + s7 += carry6; + s6 -= carry6 << 21; + carry7 = s7 >> 21; + s8 += carry7; + s7 -= carry7 << 21; + carry8 = s8 >> 21; + s9 += carry8; + s8 -= carry8 << 21; + carry9 = s9 >> 21; + s10 += carry9; + s9 -= carry9 << 21; + carry10 = s10 >> 21; + s11 += carry10; + s10 -= carry10 << 21; + carry11 = s11 >> 21; + s12 += carry11; + s11 -= carry11 << 21; + + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + s12 = 0; + + carry0 = s0 >> 21; + s1 += carry0; + s0 -= carry0 << 21; + carry1 = s1 >> 21; + s2 += carry1; + s1 -= carry1 << 21; + carry2 = s2 >> 21; + s3 += carry2; + s2 -= carry2 << 21; + carry3 = s3 >> 21; + s4 += carry3; + s3 -= carry3 << 21; + carry4 = s4 >> 21; + s5 += carry4; + s4 -= carry4 << 21; + carry5 = s5 >> 21; + s6 += carry5; + s5 -= carry5 << 21; + carry6 = s6 >> 21; + s7 += carry6; + s6 -= carry6 << 21; + carry7 = s7 >> 21; + s8 += carry7; + s7 -= carry7 << 21; + carry8 = s8 >> 21; + s9 += carry8; + s8 -= carry8 << 21; + carry9 = s9 >> 21; + s10 += carry9; + s9 -= carry9 << 21; + carry10 = s10 >> 21; + s11 += carry10; + s10 -= carry10 << 21; + + s[0] = s0 >> 0; + s[1] = s0 >> 8; + s[2] = (s0 >> 16) | (s1 << 5); + s[3] = s1 >> 3; + s[4] = s1 >> 11; + s[5] = (s1 >> 19) | (s2 << 2); + s[6] = s2 >> 6; + s[7] = (s2 >> 14) | (s3 << 7); + s[8] = s3 >> 1; + s[9] = s3 >> 9; + s[10] = (s3 >> 17) | (s4 << 4); + s[11] = s4 >> 4; + s[12] = s4 >> 12; + s[13] = (s4 >> 20) | (s5 << 1); + s[14] = s5 >> 7; + s[15] = (s5 >> 15) | (s6 << 6); + s[16] = s6 >> 2; + s[17] = s6 >> 10; + s[18] = (s6 >> 18) | (s7 << 3); + s[19] = s7 >> 5; + s[20] = s7 >> 13; + s[21] = s8 >> 0; + s[22] = s8 >> 8; + s[23] = (s8 >> 16) | (s9 << 5); + s[24] = s9 >> 3; + s[25] = s9 >> 11; + s[26] = (s9 >> 19) | (s10 << 2); + s[27] = s10 >> 6; + s[28] = (s10 >> 14) | (s11 << 7); + s[29] = s11 >> 1; + s[30] = s11 >> 9; + s[31] = s11 >> 17; +} + +// Input: +// a[0]+256*a[1]+...+256^31*a[31] = a +// b[0]+256*b[1]+...+256^31*b[31] = b +// c[0]+256*c[1]+...+256^31*c[31] = c +// +// Output: +// s[0]+256*s[1]+...+256^31*s[31] = (ab+c) mod l +// where l = 2^252 + 27742317777372353535851937790883648493. +static void sc_muladd(uint8_t *s, const uint8_t *a, const uint8_t *b, + const uint8_t *c) { + int64_t a0 = 2097151 & load_3(a); + int64_t a1 = 2097151 & (load_4(a + 2) >> 5); + int64_t a2 = 2097151 & (load_3(a + 5) >> 2); + int64_t a3 = 2097151 & (load_4(a + 7) >> 7); + int64_t a4 = 2097151 & (load_4(a + 10) >> 4); + int64_t a5 = 2097151 & (load_3(a + 13) >> 1); + int64_t a6 = 2097151 & (load_4(a + 15) >> 6); + int64_t a7 = 2097151 & (load_3(a + 18) >> 3); + int64_t a8 = 2097151 & load_3(a + 21); + int64_t a9 = 2097151 & (load_4(a + 23) >> 5); + int64_t a10 = 2097151 & (load_3(a + 26) >> 2); + int64_t a11 = (load_4(a + 28) >> 7); + int64_t b0 = 2097151 & load_3(b); + int64_t b1 = 2097151 & (load_4(b + 2) >> 5); + int64_t b2 = 2097151 & (load_3(b + 5) >> 2); + int64_t b3 = 2097151 & (load_4(b + 7) >> 7); + int64_t b4 = 2097151 & (load_4(b + 10) >> 4); + int64_t b5 = 2097151 & (load_3(b + 13) >> 1); + int64_t b6 = 2097151 & (load_4(b + 15) >> 6); + int64_t b7 = 2097151 & (load_3(b + 18) >> 3); + int64_t b8 = 2097151 & load_3(b + 21); + int64_t b9 = 2097151 & (load_4(b + 23) >> 5); + int64_t b10 = 2097151 & (load_3(b + 26) >> 2); + int64_t b11 = (load_4(b + 28) >> 7); + int64_t c0 = 2097151 & load_3(c); + int64_t c1 = 2097151 & (load_4(c + 2) >> 5); + int64_t c2 = 2097151 & (load_3(c + 5) >> 2); + int64_t c3 = 2097151 & (load_4(c + 7) >> 7); + int64_t c4 = 2097151 & (load_4(c + 10) >> 4); + int64_t c5 = 2097151 & (load_3(c + 13) >> 1); + int64_t c6 = 2097151 & (load_4(c + 15) >> 6); + int64_t c7 = 2097151 & (load_3(c + 18) >> 3); + int64_t c8 = 2097151 & load_3(c + 21); + int64_t c9 = 2097151 & (load_4(c + 23) >> 5); + int64_t c10 = 2097151 & (load_3(c + 26) >> 2); + int64_t c11 = (load_4(c + 28) >> 7); + int64_t s0; + int64_t s1; + int64_t s2; + int64_t s3; + int64_t s4; + int64_t s5; + int64_t s6; + int64_t s7; + int64_t s8; + int64_t s9; + int64_t s10; + int64_t s11; + int64_t s12; + int64_t s13; + int64_t s14; + int64_t s15; + int64_t s16; + int64_t s17; + int64_t s18; + int64_t s19; + int64_t s20; + int64_t s21; + int64_t s22; + int64_t s23; + int64_t carry0; + int64_t carry1; + int64_t carry2; + int64_t carry3; + int64_t carry4; + int64_t carry5; + int64_t carry6; + int64_t carry7; + int64_t carry8; + int64_t carry9; + int64_t carry10; + int64_t carry11; + int64_t carry12; + int64_t carry13; + int64_t carry14; + int64_t carry15; + int64_t carry16; + int64_t carry17; + int64_t carry18; + int64_t carry19; + int64_t carry20; + int64_t carry21; + int64_t carry22; + + s0 = c0 + a0 * b0; + s1 = c1 + a0 * b1 + a1 * b0; + s2 = c2 + a0 * b2 + a1 * b1 + a2 * b0; + s3 = c3 + a0 * b3 + a1 * b2 + a2 * b1 + a3 * b0; + s4 = c4 + a0 * b4 + a1 * b3 + a2 * b2 + a3 * b1 + a4 * b0; + s5 = c5 + a0 * b5 + a1 * b4 + a2 * b3 + a3 * b2 + a4 * b1 + a5 * b0; + s6 = c6 + a0 * b6 + a1 * b5 + a2 * b4 + a3 * b3 + a4 * b2 + a5 * b1 + a6 * b0; + s7 = c7 + a0 * b7 + a1 * b6 + a2 * b5 + a3 * b4 + a4 * b3 + a5 * b2 + + a6 * b1 + a7 * b0; + s8 = c8 + a0 * b8 + a1 * b7 + a2 * b6 + a3 * b5 + a4 * b4 + a5 * b3 + + a6 * b2 + a7 * b1 + a8 * b0; + s9 = c9 + a0 * b9 + a1 * b8 + a2 * b7 + a3 * b6 + a4 * b5 + a5 * b4 + + a6 * b3 + a7 * b2 + a8 * b1 + a9 * b0; + s10 = c10 + a0 * b10 + a1 * b9 + a2 * b8 + a3 * b7 + a4 * b6 + a5 * b5 + + a6 * b4 + a7 * b3 + a8 * b2 + a9 * b1 + a10 * b0; + s11 = c11 + a0 * b11 + a1 * b10 + a2 * b9 + a3 * b8 + a4 * b7 + a5 * b6 + + a6 * b5 + a7 * b4 + a8 * b3 + a9 * b2 + a10 * b1 + a11 * b0; + s12 = a1 * b11 + a2 * b10 + a3 * b9 + a4 * b8 + a5 * b7 + a6 * b6 + a7 * b5 + + a8 * b4 + a9 * b3 + a10 * b2 + a11 * b1; + s13 = a2 * b11 + a3 * b10 + a4 * b9 + a5 * b8 + a6 * b7 + a7 * b6 + a8 * b5 + + a9 * b4 + a10 * b3 + a11 * b2; + s14 = a3 * b11 + a4 * b10 + a5 * b9 + a6 * b8 + a7 * b7 + a8 * b6 + a9 * b5 + + a10 * b4 + a11 * b3; + s15 = a4 * b11 + a5 * b10 + a6 * b9 + a7 * b8 + a8 * b7 + a9 * b6 + a10 * b5 + + a11 * b4; + s16 = a5 * b11 + a6 * b10 + a7 * b9 + a8 * b8 + a9 * b7 + a10 * b6 + a11 * b5; + s17 = a6 * b11 + a7 * b10 + a8 * b9 + a9 * b8 + a10 * b7 + a11 * b6; + s18 = a7 * b11 + a8 * b10 + a9 * b9 + a10 * b8 + a11 * b7; + s19 = a8 * b11 + a9 * b10 + a10 * b9 + a11 * b8; + s20 = a9 * b11 + a10 * b10 + a11 * b9; + s21 = a10 * b11 + a11 * b10; + s22 = a11 * b11; + s23 = 0; + + carry0 = (s0 + (1 << 20)) >> 21; + s1 += carry0; + s0 -= carry0 << 21; + carry2 = (s2 + (1 << 20)) >> 21; + s3 += carry2; + s2 -= carry2 << 21; + carry4 = (s4 + (1 << 20)) >> 21; + s5 += carry4; + s4 -= carry4 << 21; + carry6 = (s6 + (1 << 20)) >> 21; + s7 += carry6; + s6 -= carry6 << 21; + carry8 = (s8 + (1 << 20)) >> 21; + s9 += carry8; + s8 -= carry8 << 21; + carry10 = (s10 + (1 << 20)) >> 21; + s11 += carry10; + s10 -= carry10 << 21; + carry12 = (s12 + (1 << 20)) >> 21; + s13 += carry12; + s12 -= carry12 << 21; + carry14 = (s14 + (1 << 20)) >> 21; + s15 += carry14; + s14 -= carry14 << 21; + carry16 = (s16 + (1 << 20)) >> 21; + s17 += carry16; + s16 -= carry16 << 21; + carry18 = (s18 + (1 << 20)) >> 21; + s19 += carry18; + s18 -= carry18 << 21; + carry20 = (s20 + (1 << 20)) >> 21; + s21 += carry20; + s20 -= carry20 << 21; + carry22 = (s22 + (1 << 20)) >> 21; + s23 += carry22; + s22 -= carry22 << 21; + + carry1 = (s1 + (1 << 20)) >> 21; + s2 += carry1; + s1 -= carry1 << 21; + carry3 = (s3 + (1 << 20)) >> 21; + s4 += carry3; + s3 -= carry3 << 21; + carry5 = (s5 + (1 << 20)) >> 21; + s6 += carry5; + s5 -= carry5 << 21; + carry7 = (s7 + (1 << 20)) >> 21; + s8 += carry7; + s7 -= carry7 << 21; + carry9 = (s9 + (1 << 20)) >> 21; + s10 += carry9; + s9 -= carry9 << 21; + carry11 = (s11 + (1 << 20)) >> 21; + s12 += carry11; + s11 -= carry11 << 21; + carry13 = (s13 + (1 << 20)) >> 21; + s14 += carry13; + s13 -= carry13 << 21; + carry15 = (s15 + (1 << 20)) >> 21; + s16 += carry15; + s15 -= carry15 << 21; + carry17 = (s17 + (1 << 20)) >> 21; + s18 += carry17; + s17 -= carry17 << 21; + carry19 = (s19 + (1 << 20)) >> 21; + s20 += carry19; + s19 -= carry19 << 21; + carry21 = (s21 + (1 << 20)) >> 21; + s22 += carry21; + s21 -= carry21 << 21; + + s11 += s23 * 666643; + s12 += s23 * 470296; + s13 += s23 * 654183; + s14 -= s23 * 997805; + s15 += s23 * 136657; + s16 -= s23 * 683901; + s23 = 0; + + s10 += s22 * 666643; + s11 += s22 * 470296; + s12 += s22 * 654183; + s13 -= s22 * 997805; + s14 += s22 * 136657; + s15 -= s22 * 683901; + s22 = 0; + + s9 += s21 * 666643; + s10 += s21 * 470296; + s11 += s21 * 654183; + s12 -= s21 * 997805; + s13 += s21 * 136657; + s14 -= s21 * 683901; + s21 = 0; + + s8 += s20 * 666643; + s9 += s20 * 470296; + s10 += s20 * 654183; + s11 -= s20 * 997805; + s12 += s20 * 136657; + s13 -= s20 * 683901; + s20 = 0; + + s7 += s19 * 666643; + s8 += s19 * 470296; + s9 += s19 * 654183; + s10 -= s19 * 997805; + s11 += s19 * 136657; + s12 -= s19 * 683901; + s19 = 0; + + s6 += s18 * 666643; + s7 += s18 * 470296; + s8 += s18 * 654183; + s9 -= s18 * 997805; + s10 += s18 * 136657; + s11 -= s18 * 683901; + s18 = 0; + + carry6 = (s6 + (1 << 20)) >> 21; + s7 += carry6; + s6 -= carry6 << 21; + carry8 = (s8 + (1 << 20)) >> 21; + s9 += carry8; + s8 -= carry8 << 21; + carry10 = (s10 + (1 << 20)) >> 21; + s11 += carry10; + s10 -= carry10 << 21; + carry12 = (s12 + (1 << 20)) >> 21; + s13 += carry12; + s12 -= carry12 << 21; + carry14 = (s14 + (1 << 20)) >> 21; + s15 += carry14; + s14 -= carry14 << 21; + carry16 = (s16 + (1 << 20)) >> 21; + s17 += carry16; + s16 -= carry16 << 21; + + carry7 = (s7 + (1 << 20)) >> 21; + s8 += carry7; + s7 -= carry7 << 21; + carry9 = (s9 + (1 << 20)) >> 21; + s10 += carry9; + s9 -= carry9 << 21; + carry11 = (s11 + (1 << 20)) >> 21; + s12 += carry11; + s11 -= carry11 << 21; + carry13 = (s13 + (1 << 20)) >> 21; + s14 += carry13; + s13 -= carry13 << 21; + carry15 = (s15 + (1 << 20)) >> 21; + s16 += carry15; + s15 -= carry15 << 21; + + s5 += s17 * 666643; + s6 += s17 * 470296; + s7 += s17 * 654183; + s8 -= s17 * 997805; + s9 += s17 * 136657; + s10 -= s17 * 683901; + s17 = 0; + + s4 += s16 * 666643; + s5 += s16 * 470296; + s6 += s16 * 654183; + s7 -= s16 * 997805; + s8 += s16 * 136657; + s9 -= s16 * 683901; + s16 = 0; + + s3 += s15 * 666643; + s4 += s15 * 470296; + s5 += s15 * 654183; + s6 -= s15 * 997805; + s7 += s15 * 136657; + s8 -= s15 * 683901; + s15 = 0; + + s2 += s14 * 666643; + s3 += s14 * 470296; + s4 += s14 * 654183; + s5 -= s14 * 997805; + s6 += s14 * 136657; + s7 -= s14 * 683901; + s14 = 0; + + s1 += s13 * 666643; + s2 += s13 * 470296; + s3 += s13 * 654183; + s4 -= s13 * 997805; + s5 += s13 * 136657; + s6 -= s13 * 683901; + s13 = 0; + + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + s12 = 0; + + carry0 = (s0 + (1 << 20)) >> 21; + s1 += carry0; + s0 -= carry0 << 21; + carry2 = (s2 + (1 << 20)) >> 21; + s3 += carry2; + s2 -= carry2 << 21; + carry4 = (s4 + (1 << 20)) >> 21; + s5 += carry4; + s4 -= carry4 << 21; + carry6 = (s6 + (1 << 20)) >> 21; + s7 += carry6; + s6 -= carry6 << 21; + carry8 = (s8 + (1 << 20)) >> 21; + s9 += carry8; + s8 -= carry8 << 21; + carry10 = (s10 + (1 << 20)) >> 21; + s11 += carry10; + s10 -= carry10 << 21; + + carry1 = (s1 + (1 << 20)) >> 21; + s2 += carry1; + s1 -= carry1 << 21; + carry3 = (s3 + (1 << 20)) >> 21; + s4 += carry3; + s3 -= carry3 << 21; + carry5 = (s5 + (1 << 20)) >> 21; + s6 += carry5; + s5 -= carry5 << 21; + carry7 = (s7 + (1 << 20)) >> 21; + s8 += carry7; + s7 -= carry7 << 21; + carry9 = (s9 + (1 << 20)) >> 21; + s10 += carry9; + s9 -= carry9 << 21; + carry11 = (s11 + (1 << 20)) >> 21; + s12 += carry11; + s11 -= carry11 << 21; + + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + s12 = 0; + + carry0 = s0 >> 21; + s1 += carry0; + s0 -= carry0 << 21; + carry1 = s1 >> 21; + s2 += carry1; + s1 -= carry1 << 21; + carry2 = s2 >> 21; + s3 += carry2; + s2 -= carry2 << 21; + carry3 = s3 >> 21; + s4 += carry3; + s3 -= carry3 << 21; + carry4 = s4 >> 21; + s5 += carry4; + s4 -= carry4 << 21; + carry5 = s5 >> 21; + s6 += carry5; + s5 -= carry5 << 21; + carry6 = s6 >> 21; + s7 += carry6; + s6 -= carry6 << 21; + carry7 = s7 >> 21; + s8 += carry7; + s7 -= carry7 << 21; + carry8 = s8 >> 21; + s9 += carry8; + s8 -= carry8 << 21; + carry9 = s9 >> 21; + s10 += carry9; + s9 -= carry9 << 21; + carry10 = s10 >> 21; + s11 += carry10; + s10 -= carry10 << 21; + carry11 = s11 >> 21; + s12 += carry11; + s11 -= carry11 << 21; + + s0 += s12 * 666643; + s1 += s12 * 470296; + s2 += s12 * 654183; + s3 -= s12 * 997805; + s4 += s12 * 136657; + s5 -= s12 * 683901; + s12 = 0; + + carry0 = s0 >> 21; + s1 += carry0; + s0 -= carry0 << 21; + carry1 = s1 >> 21; + s2 += carry1; + s1 -= carry1 << 21; + carry2 = s2 >> 21; + s3 += carry2; + s2 -= carry2 << 21; + carry3 = s3 >> 21; + s4 += carry3; + s3 -= carry3 << 21; + carry4 = s4 >> 21; + s5 += carry4; + s4 -= carry4 << 21; + carry5 = s5 >> 21; + s6 += carry5; + s5 -= carry5 << 21; + carry6 = s6 >> 21; + s7 += carry6; + s6 -= carry6 << 21; + carry7 = s7 >> 21; + s8 += carry7; + s7 -= carry7 << 21; + carry8 = s8 >> 21; + s9 += carry8; + s8 -= carry8 << 21; + carry9 = s9 >> 21; + s10 += carry9; + s9 -= carry9 << 21; + carry10 = s10 >> 21; + s11 += carry10; + s10 -= carry10 << 21; + + s[0] = s0 >> 0; + s[1] = s0 >> 8; + s[2] = (s0 >> 16) | (s1 << 5); + s[3] = s1 >> 3; + s[4] = s1 >> 11; + s[5] = (s1 >> 19) | (s2 << 2); + s[6] = s2 >> 6; + s[7] = (s2 >> 14) | (s3 << 7); + s[8] = s3 >> 1; + s[9] = s3 >> 9; + s[10] = (s3 >> 17) | (s4 << 4); + s[11] = s4 >> 4; + s[12] = s4 >> 12; + s[13] = (s4 >> 20) | (s5 << 1); + s[14] = s5 >> 7; + s[15] = (s5 >> 15) | (s6 << 6); + s[16] = s6 >> 2; + s[17] = s6 >> 10; + s[18] = (s6 >> 18) | (s7 << 3); + s[19] = s7 >> 5; + s[20] = s7 >> 13; + s[21] = s8 >> 0; + s[22] = s8 >> 8; + s[23] = (s8 >> 16) | (s9 << 5); + s[24] = s9 >> 3; + s[25] = s9 >> 11; + s[26] = (s9 >> 19) | (s10 << 2); + s[27] = s10 >> 6; + s[28] = (s10 >> 14) | (s11 << 7); + s[29] = s11 >> 1; + s[30] = s11 >> 9; + s[31] = s11 >> 17; +} + +void ED25519_keypair(uint8_t out_public_key[32], uint8_t out_private_key[64]) { + uint8_t seed[32]; + RAND_bytes(seed, 32); + ED25519_keypair_from_seed(out_public_key, out_private_key, seed); +} + +int ED25519_sign(uint8_t out_sig[64], const uint8_t *message, + size_t message_len, const uint8_t private_key[64]) { + uint8_t az[SHA512_DIGEST_LENGTH]; + SHA512(private_key, 32, az); + + az[0] &= 248; + az[31] &= 63; + az[31] |= 64; + + SHA512_CTX hash_ctx; + SHA512_Init(&hash_ctx); + SHA512_Update(&hash_ctx, az + 32, 32); + SHA512_Update(&hash_ctx, message, message_len); + uint8_t nonce[SHA512_DIGEST_LENGTH]; + SHA512_Final(nonce, &hash_ctx); + + x25519_sc_reduce(nonce); + ge_p3 R; + x25519_ge_scalarmult_base(&R, nonce); + ge_p3_tobytes(out_sig, &R); + + SHA512_Init(&hash_ctx); + SHA512_Update(&hash_ctx, out_sig, 32); + SHA512_Update(&hash_ctx, private_key + 32, 32); + SHA512_Update(&hash_ctx, message, message_len); + uint8_t hram[SHA512_DIGEST_LENGTH]; + SHA512_Final(hram, &hash_ctx); + + x25519_sc_reduce(hram); + sc_muladd(out_sig + 32, hram, az, nonce); + + return 1; +} + +int ED25519_verify(const uint8_t *message, size_t message_len, + const uint8_t signature[64], const uint8_t public_key[32]) { + ge_p3 A; + if ((signature[63] & 224) != 0 || + x25519_ge_frombytes_vartime(&A, public_key) != 0) { + return 0; + } + + fe_loose t; + fe_neg(&t, &A.X); + fe_carry(&A.X, &t); + fe_neg(&t, &A.T); + fe_carry(&A.T, &t); + + uint8_t pkcopy[32]; + OPENSSL_memcpy(pkcopy, public_key, 32); + uint8_t rcopy[32]; + OPENSSL_memcpy(rcopy, signature, 32); + union { + uint64_t u64[4]; + uint8_t u8[32]; + } scopy; + OPENSSL_memcpy(&scopy.u8[0], signature + 32, 32); + + // https://tools.ietf.org/html/rfc8032#section-5.1.7 requires that s be in + // the range [0, order) in order to prevent signature malleability. + + // kOrder is the order of Curve25519 in little-endian form. + static const uint64_t kOrder[4] = { + UINT64_C(0x5812631a5cf5d3ed), + UINT64_C(0x14def9dea2f79cd6), + 0, + UINT64_C(0x1000000000000000), + }; + for (size_t i = 3;; i--) { + if (scopy.u64[i] > kOrder[i]) { + return 0; + } else if (scopy.u64[i] < kOrder[i]) { + break; + } else if (i == 0) { + return 0; + } + } + + SHA512_CTX hash_ctx; + SHA512_Init(&hash_ctx); + SHA512_Update(&hash_ctx, signature, 32); + SHA512_Update(&hash_ctx, public_key, 32); + SHA512_Update(&hash_ctx, message, message_len); + uint8_t h[SHA512_DIGEST_LENGTH]; + SHA512_Final(h, &hash_ctx); + + x25519_sc_reduce(h); + + ge_p2 R; + ge_double_scalarmult_vartime(&R, h, &A, scopy.u8); + + uint8_t rcheck[32]; + x25519_ge_tobytes(rcheck, &R); + + return CRYPTO_memcmp(rcheck, rcopy, sizeof(rcheck)) == 0; +} + +void ED25519_keypair_from_seed(uint8_t out_public_key[32], + uint8_t out_private_key[64], + const uint8_t seed[32]) { + uint8_t az[SHA512_DIGEST_LENGTH]; + SHA512(seed, 32, az); + + az[0] &= 248; + az[31] &= 63; + az[31] |= 64; + + ge_p3 A; + x25519_ge_scalarmult_base(&A, az); + ge_p3_tobytes(out_public_key, &A); + + OPENSSL_memcpy(out_private_key, seed, 32); + OPENSSL_memcpy(out_private_key + 32, out_public_key, 32); +} + + +static void x25519_scalar_mult_generic(uint8_t out[32], + const uint8_t scalar[32], + const uint8_t point[32]) { + fe x1, x2, z2, x3, z3, tmp0, tmp1; + fe_loose x2l, z2l, x3l, tmp0l, tmp1l; + + uint8_t e[32]; + OPENSSL_memcpy(e, scalar, 32); + e[0] &= 248; + e[31] &= 127; + e[31] |= 64; + + // The following implementation was transcribed to Coq and proven to + // correspond to unary scalar multiplication in affine coordinates given that + // x1 != 0 is the x coordinate of some point on the curve. It was also checked + // in Coq that doing a ladderstep with x1 = x3 = 0 gives z2' = z3' = 0, and z2 + // = z3 = 0 gives z2' = z3' = 0. The statement was quantified over the + // underlying field, so it applies to Curve25519 itself and the quadratic + // twist of Curve25519. It was not proven in Coq that prime-field arithmetic + // correctly simulates extension-field arithmetic on prime-field values. + // The decoding of the byte array representation of e was not considered. + // Specification of Montgomery curves in affine coordinates: + // + // Proof that these form a group that is isomorphic to a Weierstrass curve: + // + // Coq transcription and correctness proof of the loop (where scalarbits=255): + // + // + // preconditions: 0 <= e < 2^255 (not necessarily e < order), fe_invert(0) = 0 + fe_frombytes(&x1, point); + fe_1(&x2); + fe_0(&z2); + fe_copy(&x3, &x1); + fe_1(&z3); + + unsigned swap = 0; + int pos; + for (pos = 254; pos >= 0; --pos) { + // loop invariant as of right before the test, for the case where x1 != 0: + // pos >= -1; if z2 = 0 then x2 is nonzero; if z3 = 0 then x3 is nonzero + // let r := e >> (pos+1) in the following equalities of projective points: + // to_xz (r*P) === if swap then (x3, z3) else (x2, z2) + // to_xz ((r+1)*P) === if swap then (x2, z2) else (x3, z3) + // x1 is the nonzero x coordinate of the nonzero point (r*P-(r+1)*P) + unsigned b = 1 & (e[pos / 8] >> (pos & 7)); + swap ^= b; + fe_cswap(&x2, &x3, swap); + fe_cswap(&z2, &z3, swap); + swap = b; + // Coq transcription of ladderstep formula (called from transcribed loop): + // + // + // x1 != 0 + // x1 = 0 + fe_sub(&tmp0l, &x3, &z3); + fe_sub(&tmp1l, &x2, &z2); + fe_add(&x2l, &x2, &z2); + fe_add(&z2l, &x3, &z3); + fe_mul_tll(&z3, &tmp0l, &x2l); + fe_mul_tll(&z2, &z2l, &tmp1l); + fe_sq_tl(&tmp0, &tmp1l); + fe_sq_tl(&tmp1, &x2l); + fe_add(&x3l, &z3, &z2); + fe_sub(&z2l, &z3, &z2); + fe_mul_ttt(&x2, &tmp1, &tmp0); + fe_sub(&tmp1l, &tmp1, &tmp0); + fe_sq_tl(&z2, &z2l); + fe_mul121666(&z3, &tmp1l); + fe_sq_tl(&x3, &x3l); + fe_add(&tmp0l, &tmp0, &z3); + fe_mul_ttt(&z3, &x1, &z2); + fe_mul_tll(&z2, &tmp1l, &tmp0l); + } + // here pos=-1, so r=e, so to_xz (e*P) === if swap then (x3, z3) else (x2, z2) + fe_cswap(&x2, &x3, swap); + fe_cswap(&z2, &z3, swap); + + fe_invert(&z2, &z2); + fe_mul_ttt(&x2, &x2, &z2); + fe_tobytes(out, &x2); +} + +static void x25519_scalar_mult(uint8_t out[32], const uint8_t scalar[32], + const uint8_t point[32]) { +#if defined(BORINGSSL_X25519_NEON) + if (CRYPTO_is_NEON_capable()) { + x25519_NEON(out, scalar, point); + return; + } +#endif + + x25519_scalar_mult_generic(out, scalar, point); +} + +void X25519_keypair(uint8_t out_public_value[32], uint8_t out_private_key[32]) { + RAND_bytes(out_private_key, 32); + + // All X25519 implementations should decode scalars correctly (see + // https://tools.ietf.org/html/rfc7748#section-5). However, if an + // implementation doesn't then it might interoperate with random keys a + // fraction of the time because they'll, randomly, happen to be correctly + // formed. + // + // Thus we do the opposite of the masking here to make sure that our private + // keys are never correctly masked and so, hopefully, any incorrect + // implementations are deterministically broken. + // + // This does not affect security because, although we're throwing away + // entropy, a valid implementation of scalarmult should throw away the exact + // same bits anyway. + out_private_key[0] |= 7; + out_private_key[31] &= 63; + out_private_key[31] |= 128; + + X25519_public_from_private(out_public_value, out_private_key); +} + +int X25519(uint8_t out_shared_key[32], const uint8_t private_key[32], + const uint8_t peer_public_value[32]) { + static const uint8_t kZeros[32] = {0}; + x25519_scalar_mult(out_shared_key, private_key, peer_public_value); + // The all-zero output results when the input is a point of small order. + return CRYPTO_memcmp(kZeros, out_shared_key, 32) != 0; +} + +void X25519_public_from_private(uint8_t out_public_value[32], + const uint8_t private_key[32]) { +#if defined(BORINGSSL_X25519_NEON) + if (CRYPTO_is_NEON_capable()) { + static const uint8_t kMongomeryBasePoint[32] = {9}; + x25519_NEON(out_public_value, private_key, kMongomeryBasePoint); + return; + } +#endif + + uint8_t e[32]; + OPENSSL_memcpy(e, private_key, 32); + e[0] &= 248; + e[31] &= 127; + e[31] |= 64; + + ge_p3 A; + x25519_ge_scalarmult_base(&A, e); + + // We only need the u-coordinate of the curve25519 point. The map is + // u=(y+1)/(1-y). Since y=Y/Z, this gives u=(Z+Y)/(Z-Y). + fe_loose zplusy, zminusy; + fe zminusy_inv; + fe_add(&zplusy, &A.Z, &A.Y); + fe_sub(&zminusy, &A.Z, &A.Y); + fe_loose_invert(&zminusy_inv, &zminusy); + fe_mul_tlt(&zminusy_inv, &zplusy, &zminusy_inv); + fe_tobytes(out_public_value, &zminusy_inv); +} diff --git a/FoodApp/Pods/BoringSSL-GRPC/third_party/fiat/curve25519_tables.h b/FoodApp/Pods/BoringSSL-GRPC/third_party/fiat/curve25519_tables.h new file mode 100644 index 0000000..c293e95 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/third_party/fiat/curve25519_tables.h @@ -0,0 +1,7880 @@ +// The MIT License (MIT) +// +// Copyright (c) 2015-2016 the fiat-crypto authors (see the AUTHORS file). +// +// 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. + +// This file is generated from +// ./make_curve25519_tables.py > curve25519_tables.h + + +static const fe d = {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 929955233495203, 466365720129213, 1662059464998953, 2033849074728123, + 1442794654840575 +#else + 56195235, 13857412, 51736253, 6949390, 114729, 24766616, 60832955, 30306712, + 48412415, 21499315 +#endif +}}; + +static const fe sqrtm1 = {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1718705420411056, 234908883556509, 2233514472574048, 2117202627021982, + 765476049583133 +#else + 34513072, 25610706, 9377949, 3500415, 12389472, 33281959, 41962654, + 31548777, 326685, 11406482 +#endif +}}; + +static const fe d2 = {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1859910466990425, 932731440258426, 1072319116312658, 1815898335770999, + 633789495995903 +#else + 45281625, 27714825, 36363642, 13898781, 229458, 15978800, 54557047, + 27058993, 29715967, 9444199 +#endif +}}; + +#if defined(OPENSSL_SMALL) + +// This block of code replaces the standard base-point table with a much smaller +// one. The standard table is 30,720 bytes while this one is just 960. +// +// This table contains 15 pairs of group elements, (x, y), where each field +// element is serialised with |fe_tobytes|. If |i| is the index of the group +// element then consider i+1 as a four-bit number: (i₀, i₁, i₂, i₃) (where i₀ +// is the most significant bit). The value of the group element is then: +// (i₀×2^192 + i₁×2^128 + i₂×2^64 + i₃)G, where G is the generator. +static const uint8_t k25519SmallPrecomp[15 * 2 * 32] = { + 0x1a, 0xd5, 0x25, 0x8f, 0x60, 0x2d, 0x56, 0xc9, 0xb2, 0xa7, 0x25, 0x95, + 0x60, 0xc7, 0x2c, 0x69, 0x5c, 0xdc, 0xd6, 0xfd, 0x31, 0xe2, 0xa4, 0xc0, + 0xfe, 0x53, 0x6e, 0xcd, 0xd3, 0x36, 0x69, 0x21, 0x58, 0x66, 0x66, 0x66, + 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, + 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, + 0x66, 0x66, 0x66, 0x66, 0x02, 0xa2, 0xed, 0xf4, 0x8f, 0x6b, 0x0b, 0x3e, + 0xeb, 0x35, 0x1a, 0xd5, 0x7e, 0xdb, 0x78, 0x00, 0x96, 0x8a, 0xa0, 0xb4, + 0xcf, 0x60, 0x4b, 0xd4, 0xd5, 0xf9, 0x2d, 0xbf, 0x88, 0xbd, 0x22, 0x62, + 0x13, 0x53, 0xe4, 0x82, 0x57, 0xfa, 0x1e, 0x8f, 0x06, 0x2b, 0x90, 0xba, + 0x08, 0xb6, 0x10, 0x54, 0x4f, 0x7c, 0x1b, 0x26, 0xed, 0xda, 0x6b, 0xdd, + 0x25, 0xd0, 0x4e, 0xea, 0x42, 0xbb, 0x25, 0x03, 0xa2, 0xfb, 0xcc, 0x61, + 0x67, 0x06, 0x70, 0x1a, 0xc4, 0x78, 0x3a, 0xff, 0x32, 0x62, 0xdd, 0x2c, + 0xab, 0x50, 0x19, 0x3b, 0xf2, 0x9b, 0x7d, 0xb8, 0xfd, 0x4f, 0x29, 0x9c, + 0xa7, 0x91, 0xba, 0x0e, 0x46, 0x5e, 0x51, 0xfe, 0x1d, 0xbf, 0xe5, 0xe5, + 0x9b, 0x95, 0x0d, 0x67, 0xf8, 0xd1, 0xb5, 0x5a, 0xa1, 0x93, 0x2c, 0xc3, + 0xde, 0x0e, 0x97, 0x85, 0x2d, 0x7f, 0xea, 0xab, 0x3e, 0x47, 0x30, 0x18, + 0x24, 0xe8, 0xb7, 0x60, 0xae, 0x47, 0x80, 0xfc, 0xe5, 0x23, 0xe7, 0xc2, + 0xc9, 0x85, 0xe6, 0x98, 0xa0, 0x29, 0x4e, 0xe1, 0x84, 0x39, 0x2d, 0x95, + 0x2c, 0xf3, 0x45, 0x3c, 0xff, 0xaf, 0x27, 0x4c, 0x6b, 0xa6, 0xf5, 0x4b, + 0x11, 0xbd, 0xba, 0x5b, 0x9e, 0xc4, 0xa4, 0x51, 0x1e, 0xbe, 0xd0, 0x90, + 0x3a, 0x9c, 0xc2, 0x26, 0xb6, 0x1e, 0xf1, 0x95, 0x7d, 0xc8, 0x6d, 0x52, + 0xe6, 0x99, 0x2c, 0x5f, 0x9a, 0x96, 0x0c, 0x68, 0x29, 0xfd, 0xe2, 0xfb, + 0xe6, 0xbc, 0xec, 0x31, 0x08, 0xec, 0xe6, 0xb0, 0x53, 0x60, 0xc3, 0x8c, + 0xbe, 0xc1, 0xb3, 0x8a, 0x8f, 0xe4, 0x88, 0x2b, 0x55, 0xe5, 0x64, 0x6e, + 0x9b, 0xd0, 0xaf, 0x7b, 0x64, 0x2a, 0x35, 0x25, 0x10, 0x52, 0xc5, 0x9e, + 0x58, 0x11, 0x39, 0x36, 0x45, 0x51, 0xb8, 0x39, 0x93, 0xfc, 0x9d, 0x6a, + 0xbe, 0x58, 0xcb, 0xa4, 0x0f, 0x51, 0x3c, 0x38, 0x05, 0xca, 0xab, 0x43, + 0x63, 0x0e, 0xf3, 0x8b, 0x41, 0xa6, 0xf8, 0x9b, 0x53, 0x70, 0x80, 0x53, + 0x86, 0x5e, 0x8f, 0xe3, 0xc3, 0x0d, 0x18, 0xc8, 0x4b, 0x34, 0x1f, 0xd8, + 0x1d, 0xbc, 0xf2, 0x6d, 0x34, 0x3a, 0xbe, 0xdf, 0xd9, 0xf6, 0xf3, 0x89, + 0xa1, 0xe1, 0x94, 0x9f, 0x5d, 0x4c, 0x5d, 0xe9, 0xa1, 0x49, 0x92, 0xef, + 0x0e, 0x53, 0x81, 0x89, 0x58, 0x87, 0xa6, 0x37, 0xf1, 0xdd, 0x62, 0x60, + 0x63, 0x5a, 0x9d, 0x1b, 0x8c, 0xc6, 0x7d, 0x52, 0xea, 0x70, 0x09, 0x6a, + 0xe1, 0x32, 0xf3, 0x73, 0x21, 0x1f, 0x07, 0x7b, 0x7c, 0x9b, 0x49, 0xd8, + 0xc0, 0xf3, 0x25, 0x72, 0x6f, 0x9d, 0xed, 0x31, 0x67, 0x36, 0x36, 0x54, + 0x40, 0x92, 0x71, 0xe6, 0x11, 0x28, 0x11, 0xad, 0x93, 0x32, 0x85, 0x7b, + 0x3e, 0xb7, 0x3b, 0x49, 0x13, 0x1c, 0x07, 0xb0, 0x2e, 0x93, 0xaa, 0xfd, + 0xfd, 0x28, 0x47, 0x3d, 0x8d, 0xd2, 0xda, 0xc7, 0x44, 0xd6, 0x7a, 0xdb, + 0x26, 0x7d, 0x1d, 0xb8, 0xe1, 0xde, 0x9d, 0x7a, 0x7d, 0x17, 0x7e, 0x1c, + 0x37, 0x04, 0x8d, 0x2d, 0x7c, 0x5e, 0x18, 0x38, 0x1e, 0xaf, 0xc7, 0x1b, + 0x33, 0x48, 0x31, 0x00, 0x59, 0xf6, 0xf2, 0xca, 0x0f, 0x27, 0x1b, 0x63, + 0x12, 0x7e, 0x02, 0x1d, 0x49, 0xc0, 0x5d, 0x79, 0x87, 0xef, 0x5e, 0x7a, + 0x2f, 0x1f, 0x66, 0x55, 0xd8, 0x09, 0xd9, 0x61, 0x38, 0x68, 0xb0, 0x07, + 0xa3, 0xfc, 0xcc, 0x85, 0x10, 0x7f, 0x4c, 0x65, 0x65, 0xb3, 0xfa, 0xfa, + 0xa5, 0x53, 0x6f, 0xdb, 0x74, 0x4c, 0x56, 0x46, 0x03, 0xe2, 0xd5, 0x7a, + 0x29, 0x1c, 0xc6, 0x02, 0xbc, 0x59, 0xf2, 0x04, 0x75, 0x63, 0xc0, 0x84, + 0x2f, 0x60, 0x1c, 0x67, 0x76, 0xfd, 0x63, 0x86, 0xf3, 0xfa, 0xbf, 0xdc, + 0xd2, 0x2d, 0x90, 0x91, 0xbd, 0x33, 0xa9, 0xe5, 0x66, 0x0c, 0xda, 0x42, + 0x27, 0xca, 0xf4, 0x66, 0xc2, 0xec, 0x92, 0x14, 0x57, 0x06, 0x63, 0xd0, + 0x4d, 0x15, 0x06, 0xeb, 0x69, 0x58, 0x4f, 0x77, 0xc5, 0x8b, 0xc7, 0xf0, + 0x8e, 0xed, 0x64, 0xa0, 0xb3, 0x3c, 0x66, 0x71, 0xc6, 0x2d, 0xda, 0x0a, + 0x0d, 0xfe, 0x70, 0x27, 0x64, 0xf8, 0x27, 0xfa, 0xf6, 0x5f, 0x30, 0xa5, + 0x0d, 0x6c, 0xda, 0xf2, 0x62, 0x5e, 0x78, 0x47, 0xd3, 0x66, 0x00, 0x1c, + 0xfd, 0x56, 0x1f, 0x5d, 0x3f, 0x6f, 0xf4, 0x4c, 0xd8, 0xfd, 0x0e, 0x27, + 0xc9, 0x5c, 0x2b, 0xbc, 0xc0, 0xa4, 0xe7, 0x23, 0x29, 0x02, 0x9f, 0x31, + 0xd6, 0xe9, 0xd7, 0x96, 0xf4, 0xe0, 0x5e, 0x0b, 0x0e, 0x13, 0xee, 0x3c, + 0x09, 0xed, 0xf2, 0x3d, 0x76, 0x91, 0xc3, 0xa4, 0x97, 0xae, 0xd4, 0x87, + 0xd0, 0x5d, 0xf6, 0x18, 0x47, 0x1f, 0x1d, 0x67, 0xf2, 0xcf, 0x63, 0xa0, + 0x91, 0x27, 0xf8, 0x93, 0x45, 0x75, 0x23, 0x3f, 0xd1, 0xf1, 0xad, 0x23, + 0xdd, 0x64, 0x93, 0x96, 0x41, 0x70, 0x7f, 0xf7, 0xf5, 0xa9, 0x89, 0xa2, + 0x34, 0xb0, 0x8d, 0x1b, 0xae, 0x19, 0x15, 0x49, 0x58, 0x23, 0x6d, 0x87, + 0x15, 0x4f, 0x81, 0x76, 0xfb, 0x23, 0xb5, 0xea, 0xcf, 0xac, 0x54, 0x8d, + 0x4e, 0x42, 0x2f, 0xeb, 0x0f, 0x63, 0xdb, 0x68, 0x37, 0xa8, 0xcf, 0x8b, + 0xab, 0xf5, 0xa4, 0x6e, 0x96, 0x2a, 0xb2, 0xd6, 0xbe, 0x9e, 0xbd, 0x0d, + 0xb4, 0x42, 0xa9, 0xcf, 0x01, 0x83, 0x8a, 0x17, 0x47, 0x76, 0xc4, 0xc6, + 0x83, 0x04, 0x95, 0x0b, 0xfc, 0x11, 0xc9, 0x62, 0xb8, 0x0c, 0x76, 0x84, + 0xd9, 0xb9, 0x37, 0xfa, 0xfc, 0x7c, 0xc2, 0x6d, 0x58, 0x3e, 0xb3, 0x04, + 0xbb, 0x8c, 0x8f, 0x48, 0xbc, 0x91, 0x27, 0xcc, 0xf9, 0xb7, 0x22, 0x19, + 0x83, 0x2e, 0x09, 0xb5, 0x72, 0xd9, 0x54, 0x1c, 0x4d, 0xa1, 0xea, 0x0b, + 0xf1, 0xc6, 0x08, 0x72, 0x46, 0x87, 0x7a, 0x6e, 0x80, 0x56, 0x0a, 0x8a, + 0xc0, 0xdd, 0x11, 0x6b, 0xd6, 0xdd, 0x47, 0xdf, 0x10, 0xd9, 0xd8, 0xea, + 0x7c, 0xb0, 0x8f, 0x03, 0x00, 0x2e, 0xc1, 0x8f, 0x44, 0xa8, 0xd3, 0x30, + 0x06, 0x89, 0xa2, 0xf9, 0x34, 0xad, 0xdc, 0x03, 0x85, 0xed, 0x51, 0xa7, + 0x82, 0x9c, 0xe7, 0x5d, 0x52, 0x93, 0x0c, 0x32, 0x9a, 0x5b, 0xe1, 0xaa, + 0xca, 0xb8, 0x02, 0x6d, 0x3a, 0xd4, 0xb1, 0x3a, 0xf0, 0x5f, 0xbe, 0xb5, + 0x0d, 0x10, 0x6b, 0x38, 0x32, 0xac, 0x76, 0x80, 0xbd, 0xca, 0x94, 0x71, + 0x7a, 0xf2, 0xc9, 0x35, 0x2a, 0xde, 0x9f, 0x42, 0x49, 0x18, 0x01, 0xab, + 0xbc, 0xef, 0x7c, 0x64, 0x3f, 0x58, 0x3d, 0x92, 0x59, 0xdb, 0x13, 0xdb, + 0x58, 0x6e, 0x0a, 0xe0, 0xb7, 0x91, 0x4a, 0x08, 0x20, 0xd6, 0x2e, 0x3c, + 0x45, 0xc9, 0x8b, 0x17, 0x79, 0xe7, 0xc7, 0x90, 0x99, 0x3a, 0x18, 0x25, +}; + +#else + +// k25519Precomp[i][j] = (j+1)*256^i*B +static const ge_precomp k25519Precomp[32][8] = { + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1288382639258501, 245678601348599, 269427782077623, + 1462984067271730, 137412439391563 +#else + 25967493, 19198397, 29566455, 3660896, 54414519, 4014786, + 27544626, 21800161, 61029707, 2047604 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 62697248952638, 204681361388450, 631292143396476, + 338455783676468, 1213667448819585 +#else + 54563134, 934261, 64385954, 3049989, 66381436, 9406985, + 12720692, 5043384, 19500929, 18085054 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 301289933810280, 1259582250014073, 1422107436869536, + 796239922652654, 1953934009299142 +#else + 58370664, 4489569, 9688441, 18769238, 10184608, 21191052, + 29287918, 11864899, 42594502, 29115885 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1380971894829527, 790832306631236, 2067202295274102, + 1995808275510000, 1566530869037010 +#else + 54292951, 20578084, 45527620, 11784319, 41753206, 30803714, + 55390960, 29739860, 66750418, 23343128 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 463307831301544, 432984605774163, 1610641361907204, + 750899048855000, 1894842303421586 +#else + 45405608, 6903824, 27185491, 6451973, 37531140, 24000426, + 51492312, 11189267, 40279186, 28235350 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 748439484463711, 1033211726465151, 1396005112841647, + 1611506220286469, 1972177495910992 +#else + 26966623, 11152617, 32442495, 15396054, 14353839, 20802097, + 63980037, 24013313, 51636816, 29387734 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1601611775252272, 1720807796594148, 1132070835939856, + 1260455018889551, 2147779492816911 +#else + 15636272, 23865875, 24204772, 25642034, 616976, 16869170, + 27787599, 18782243, 28944399, 32004408 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 316559037616741, 2177824224946892, 1459442586438991, + 1461528397712656, 751590696113597 +#else + 16568933, 4717097, 55552716, 32452109, 15682895, 21747389, + 16354576, 21778470, 7689661, 11199574 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1850748884277385, 1200145853858453, 1068094770532492, + 672251375690438, 1586055907191707 +#else + 30464137, 27578307, 55329429, 17883566, 23220364, 15915852, + 7512774, 10017326, 49359771, 23634074 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 934282339813791, 1846903124198670, 1172395437954843, + 1007037127761661, 1830588347719256 +#else + 50071967, 13921891, 10945806, 27521001, 27105051, 17470053, + 38182653, 15006022, 3284568, 27277892 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1694390458783935, 1735906047636159, 705069562067493, + 648033061693059, 696214010414170 +#else + 23599295, 25248385, 55915199, 25867015, 13236773, 10506355, + 7464579, 9656445, 13059162, 10374397 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1121406372216585, 192876649532226, 190294192191717, + 1994165897297032, 2245000007398739 +#else + 7798537, 16710257, 3033922, 2874086, 28997861, 2835604, + 32406664, 29715387, 66467155, 33453106 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 769950342298419, 132954430919746, 844085933195555, + 974092374476333, 726076285546016 +#else + 10861363, 11473154, 27284546, 1981175, 37044515, 12577860, + 32867885, 14515107, 51670560, 10819379 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 425251763115706, 608463272472562, 442562545713235, + 837766094556764, 374555092627893 +#else + 4708026, 6336745, 20377586, 9066809, 55836755, 6594695, + 41455196, 12483687, 54440373, 5581305 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1086255230780037, 274979815921559, 1960002765731872, + 929474102396301, 1190409889297339 +#else + 19563141, 16186464, 37722007, 4097518, 10237984, 29206317, + 28542349, 13850243, 43430843, 17738489 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1388594989461809, 316767091099457, 394298842192982, + 1230079486801005, 1440737038838979 +#else + 51736881, 20691677, 32573249, 4720197, 40672342, 5875510, + 47920237, 18329612, 57289923, 21468654 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 7380825640100, 146210432690483, 304903576448906, + 1198869323871120, 997689833219095 +#else + 58559652, 109982, 15149363, 2178705, 22900618, 4543417, 3044240, + 17864545, 1762327, 14866737 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1181317918772081, 114573476638901, 262805072233344, + 265712217171332, 294181933805782 +#else + 48909169, 17603008, 56635573, 1707277, 49922944, 3916100, + 38872452, 3959420, 27914454, 4383652 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 665000864555967, 2065379846933859, 370231110385876, + 350988370788628, 1233371373142985 +#else + 5153727, 9909285, 1723747, 30776558, 30523604, 5516873, + 19480852, 5230134, 43156425, 18378665 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2019367628972465, 676711900706637, 110710997811333, + 1108646842542025, 517791959672113 +#else + 36839857, 30090922, 7665485, 10083793, 28475525, 1649722, + 20654025, 16520125, 30598449, 7715701 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 965130719900578, 247011430587952, 526356006571389, + 91986625355052, 2157223321444601 +#else + 28881826, 14381568, 9657904, 3680757, 46927229, 7843315, + 35708204, 1370707, 29794553, 32145132 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2068619540119183, 1966274918058806, 957728544705549, + 729906502578991, 159834893065166 +#else + 14499471, 30824833, 33917750, 29299779, 28494861, 14271267, + 30290735, 10876454, 33954766, 2381725 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2073601412052185, 31021124762708, 264500969797082, + 248034690651703, 1030252227928288 +#else + 59913433, 30899068, 52378708, 462250, 39384538, 3941371, + 60872247, 3696004, 34808032, 15351954 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 551790716293402, 1989538725166328, 801169423371717, + 2052451893578887, 678432056995012 +#else + 27431194, 8222322, 16448760, 29646437, 48401861, 11938354, + 34147463, 30583916, 29551812, 10109425 +#endif + }}, + }, + }, + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1368953770187805, 790347636712921, 437508475667162, + 2142576377050580, 1932081720066286 +#else + 53451805, 20399000, 35825113, 11777097, 21447386, 6519384, + 64730580, 31926875, 10092782, 28790261 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 953638594433374, 1092333936795051, 1419774766716690, + 805677984380077, 859228993502513 +#else + 27939166, 14210322, 4677035, 16277044, 44144402, 21156292, + 34600109, 12005537, 49298737, 12803509 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1200766035879111, 20142053207432, 1465634435977050, + 1645256912097844, 295121984874596 +#else + 17228999, 17892808, 65875336, 300139, 65883994, 21839654, + 30364212, 24516238, 18016356, 4397660 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1735718747031557, 1248237894295956, 1204753118328107, + 976066523550493, 65943769534592 +#else + 56150021, 25864224, 4776340, 18600194, 27850027, 17952220, + 40489757, 14544524, 49631360, 982638 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1060098822528990, 1586825862073490, 212301317240126, + 1975302711403555, 666724059764335 +#else + 29253598, 15796703, 64244882, 23645547, 10057022, 3163536, + 7332899, 29434304, 46061167, 9934962 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1091990273418756, 1572899409348578, 80968014455247, + 306009358661350, 1520450739132526 +#else + 5793284, 16271923, 42977250, 23438027, 29188559, 1206517, + 52360934, 4559894, 36984942, 22656481 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1480517209436112, 1511153322193952, 1244343858991172, + 304788150493241, 369136856496443 +#else + 39464912, 22061425, 16282656, 22517939, 28414020, 18542168, + 24191033, 4541697, 53770555, 5500567 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2151330273626164, 762045184746182, 1688074332551515, + 823046109005759, 907602769079491 +#else + 12650548, 32057319, 9052870, 11355358, 49428827, 25154267, + 49678271, 12264342, 10874051, 13524335 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2047386910586836, 168470092900250, 1552838872594810, + 340951180073789, 360819374702533 +#else + 25556948, 30508442, 714650, 2510400, 23394682, 23139102, + 33119037, 5080568, 44580805, 5376627 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1982622644432056, 2014393600336956, 128909208804214, + 1617792623929191, 105294281913815 +#else + 41020600, 29543379, 50095164, 30016803, 60382070, 1920896, + 44787559, 24106988, 4535767, 1569007 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 980234343912898, 1712256739246056, 588935272190264, + 204298813091998, 841798321043288 +#else + 64853442, 14606629, 45416424, 25514613, 28430648, 8775819, + 36614302, 3044289, 31848280, 12543772 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 197561292938973, 454817274782871, 1963754960082318, + 2113372252160468, 971377527342673 +#else + 45080285, 2943892, 35251351, 6777305, 13784462, 29262229, + 39731668, 31491700, 7718481, 14474653 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 164699448829328, 3127451757672, 1199504971548753, + 1766155447043652, 1899238924683527 +#else + 2385296, 2454213, 44477544, 46602, 62670929, 17874016, 656964, + 26317767, 24316167, 28300865 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 732262946680281, 1674412764227063, 2182456405662809, + 1350894754474250, 558458873295247 +#else + 13741529, 10911568, 33875447, 24950694, 46931033, 32521134, + 33040650, 20129900, 46379407, 8321685 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2103305098582922, 1960809151316468, 715134605001343, + 1454892949167181, 40827143824949 +#else + 21060490, 31341688, 15712756, 29218333, 1639039, 10656336, + 23845965, 21679594, 57124405, 608371 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1239289043050212, 1744654158124578, 758702410031698, + 1796762995074688, 1603056663766 +#else + 53436132, 18466845, 56219170, 25997372, 61071954, 11305546, + 1123968, 26773855, 27229398, 23887 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2232056027107988, 987343914584615, 2115594492994461, + 1819598072792159, 1119305654014850 +#else + 43864724, 33260226, 55364135, 14712570, 37643165, 31524814, + 12797023, 27114124, 65475458, 16678953 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 320153677847348, 939613871605645, 641883205761567, + 1930009789398224, 329165806634126 +#else + 37608244, 4770661, 51054477, 14001337, 7830047, 9564805, + 65600720, 28759386, 49939598, 4904952 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 980930490474130, 1242488692177893, 1251446316964684, + 1086618677993530, 1961430968465772 +#else + 24059538, 14617003, 19037157, 18514524, 19766092, 18648003, + 5169210, 16191880, 2128236, 29227599 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 276821765317453, 1536835591188030, 1305212741412361, + 61473904210175, 2051377036983058 +#else + 50127693, 4124965, 58568254, 22900634, 30336521, 19449185, + 37302527, 916032, 60226322, 30567899 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 833449923882501, 1750270368490475, 1123347002068295, + 185477424765687, 278090826653186 +#else + 44477957, 12419371, 59974635, 26081060, 50629959, 16739174, + 285431, 2763829, 15736322, 4143876 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 794524995833413, 1849907304548286, 53348672473145, + 1272368559505217, 1147304168324779 +#else + 2379333, 11839345, 62998462, 27565766, 11274297, 794957, 212801, + 18959769, 23527083, 17096164 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1504846112759364, 1203096289004681, 562139421471418, + 274333017451844, 1284344053775441 +#else + 33431108, 22423954, 49269897, 17927531, 8909498, 8376530, + 34483524, 4087880, 51919953, 19138217 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 483048732424432, 2116063063343382, 30120189902313, + 292451576741007, 1156379271702225 +#else + 1767664, 7197987, 53903638, 31531796, 54017513, 448825, 5799055, + 4357868, 62334673, 17231393 +#endif + }}, + }, + }, + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 928372153029038, 2147692869914564, 1455665844462196, + 1986737809425946, 185207050258089 +#else + 6721966, 13833823, 43585476, 32003117, 26354292, 21691111, + 23365146, 29604700, 7390889, 2759800 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 137732961814206, 706670923917341, 1387038086865771, + 1965643813686352, 1384777115696347 +#else + 4409022, 2052381, 23373853, 10530217, 7676779, 20668478, + 21302352, 29290375, 1244379, 20634787 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 481144981981577, 2053319313589856, 2065402289827512, + 617954271490316, 1106602634668125 +#else + 62687625, 7169618, 4982368, 30596842, 30256824, 30776892, + 14086412, 9208236, 15886429, 16489664 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 696298019648792, 893299659040895, 1148636718636009, + 26734077349617, 2203955659340681 +#else + 1996056, 10375649, 14346367, 13311202, 60234729, 17116020, + 53415665, 398368, 36502409, 32841498 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 657390353372855, 998499966885562, 991893336905797, + 810470207106761, 343139804608786 +#else + 41801399, 9795879, 64331450, 14878808, 33577029, 14780362, + 13348553, 12076947, 36272402, 5113181 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 791736669492960, 934767652997115, 824656780392914, + 1759463253018643, 361530362383518 +#else + 49338080, 11797795, 31950843, 13929123, 41220562, 12288343, + 36767763, 26218045, 13847710, 5387222 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2022541353055597, 2094700262587466, 1551008075025686, + 242785517418164, 695985404963562 +#else + 48526701, 30138214, 17824842, 31213466, 22744342, 23111821, + 8763060, 3617786, 47508202, 10370990 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1287487199965223, 2215311941380308, 1552928390931986, + 1664859529680196, 1125004975265243 +#else + 20246567, 19185054, 22358228, 33010720, 18507282, 23140436, + 14554436, 24808340, 32232923, 16763880 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 677434665154918, 989582503122485, 1817429540898386, + 1052904935475344, 1143826298169798 +#else + 9648486, 10094563, 26416693, 14745928, 36734546, 27081810, + 11094160, 15689506, 3140038, 17044340 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 367266328308408, 318431188922404, 695629353755355, + 634085657580832, 24581612564426 +#else + 50948792, 5472694, 31895588, 4744994, 8823515, 10365685, + 39884064, 9448612, 38334410, 366294 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 773360688841258, 1815381330538070, 363773437667376, + 539629987070205, 783280434248437 +#else + 19153450, 11523972, 56012374, 27051289, 42461232, 5420646, + 28344573, 8041113, 719605, 11671788 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 180820816194166, 168937968377394, 748416242794470, + 1227281252254508, 1567587861004268 +#else + 8678006, 2694440, 60300850, 2517371, 4964326, 11152271, + 51675948, 18287915, 27000812, 23358879 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 478775558583645, 2062896624554807, 699391259285399, + 358099408427873, 1277310261461761 +#else + 51950941, 7134311, 8639287, 30739555, 59873175, 10421741, + 564065, 5336097, 6750977, 19033406 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1984740906540026, 1079164179400229, 1056021349262661, + 1659958556483663, 1088529069025527 +#else + 11836410, 29574944, 26297893, 16080799, 23455045, 15735944, + 1695823, 24735310, 8169719, 16220347 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 580736401511151, 1842931091388998, 1177201471228238, + 2075460256527244, 1301133425678027 +#else + 48993007, 8653646, 17578566, 27461813, 59083086, 17541668, + 55964556, 30926767, 61118155, 19388398 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1515728832059182, 1575261009617579, 1510246567196186, + 191078022609704, 116661716289141 +#else + 43800366, 22586119, 15213227, 23473218, 36255258, 22504427, + 27884328, 2847284, 2655861, 1738395 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1295295738269652, 1714742313707026, 545583042462581, + 2034411676262552, 1513248090013606 +#else + 39571412, 19301410, 41772562, 25551651, 57738101, 8129820, + 21651608, 30315096, 48021414, 22549153 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 230710545179830, 30821514358353, 760704303452229, + 390668103790604, 573437871383156 +#else + 1533110, 3437855, 23735889, 459276, 29970501, 11335377, + 26030092, 5821408, 10478196, 8544890 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1169380107545646, 263167233745614, 2022901299054448, + 819900753251120, 2023898464874585 +#else + 32173102, 17425121, 24896206, 3921497, 22579056, 30143578, + 19270448, 12217473, 17789017, 30158437 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2102254323485823, 1570832666216754, 34696906544624, + 1993213739807337, 70638552271463 +#else + 36555903, 31326030, 51530034, 23407230, 13243888, 517024, + 15479401, 29701199, 30460519, 1052596 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 894132856735058, 548675863558441, 845349339503395, + 1942269668326667, 1615682209874691 +#else + 55493970, 13323617, 32618793, 8175907, 51878691, 12596686, + 27491595, 28942073, 3179267, 24075541 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1287670217537834, 1222355136884920, 1846481788678694, + 1150426571265110, 1613523400722047 +#else + 31947050, 19187781, 62468280, 18214510, 51982886, 27514722, + 52352086, 17142691, 19072639, 24043372 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 793388516527298, 1315457083650035, 1972286999342417, + 1901825953052455, 338269477222410 +#else + 11685058, 11822410, 3158003, 19601838, 33402193, 29389366, + 5977895, 28339415, 473098, 5040608 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 550201530671806, 778605267108140, 2063911101902983, + 115500557286349, 2041641272971022 +#else + 46817982, 8198641, 39698732, 11602122, 1290375, 30754672, + 28326861, 1721092, 47550222, 30422825 +#endif + }}, + }, + }, + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 717255318455100, 519313764361315, 2080406977303708, + 541981206705521, 774328150311600 +#else + 7881532, 10687937, 7578723, 7738378, 48157852, 31000479, + 21820785, 8076149, 39240368, 11538388 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 261715221532238, 1795354330069993, 1496878026850283, + 499739720521052, 389031152673770 +#else + 47173198, 3899860, 18283497, 26752864, 51380203, 22305220, + 8754524, 7446702, 61432810, 5797015 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1997217696294013, 1717306351628065, 1684313917746180, + 1644426076011410, 1857378133465451 +#else + 55813245, 29760862, 51326753, 25589858, 12708868, 25098233, + 2014098, 24503858, 64739691, 27677090 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1475434724792648, 76931896285979, 1116729029771667, + 2002544139318042, 725547833803938 +#else + 44636488, 21985690, 39426843, 1146374, 18956691, 16640559, + 1192730, 29840233, 15123618, 10811505 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2022306639183567, 726296063571875, 315345054448644, + 1058733329149221, 1448201136060677 +#else + 14352079, 30134717, 48166819, 10822654, 32750596, 4699007, + 67038501, 15776355, 38222085, 21579878 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1710065158525665, 1895094923036397, 123988286168546, + 1145519900776355, 1607510767693874 +#else + 38867681, 25481956, 62129901, 28239114, 29416930, 1847569, + 46454691, 17069576, 4714546, 23953777 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 561605375422540, 1071733543815037, 131496498800990, + 1946868434569999, 828138133964203 +#else + 15200332, 8368572, 19679101, 15970074, 35236190, 1959450, + 24611599, 29010600, 55362987, 12340219 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1548495173745801, 442310529226540, 998072547000384, + 553054358385281, 644824326376171 +#else + 12876937, 23074376, 33134380, 6590940, 60801088, 14872439, + 9613953, 8241152, 15370987, 9608631 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1445526537029440, 2225519789662536, 914628859347385, + 1064754194555068, 1660295614401091 +#else + 62965568, 21540023, 8446280, 33162829, 4407737, 13629032, + 59383996, 15866073, 38898243, 24740332 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1199690223111956, 24028135822341, 66638289244341, + 57626156285975, 565093967979607 +#else + 26660628, 17876777, 8393733, 358047, 59707573, 992987, 43204631, + 858696, 20571223, 8420556 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 876926774220824, 554618976488214, 1012056309841565, + 839961821554611, 1414499340307677 +#else + 14620696, 13067227, 51661590, 8264466, 14106269, 15080814, + 33531827, 12516406, 45534429, 21077682 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 703047626104145, 1266841406201770, 165556500219173, + 486991595001879, 1011325891650656 +#else + 236881, 10476226, 57258, 18877408, 6472997, 2466984, 17258519, + 7256740, 8791136, 15069930 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1622861044480487, 1156394801573634, 1869132565415504, + 327103985777730, 2095342781472284 +#else + 1276391, 24182514, 22949634, 17231625, 43615824, 27852245, + 14711874, 4874229, 36445724, 31223040 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 334886927423922, 489511099221528, 129160865966726, + 1720809113143481, 619700195649254 +#else + 5855666, 4990204, 53397016, 7294283, 59304582, 1924646, + 65685689, 25642053, 34039526, 9234252 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1646545795166119, 1758370782583567, 714746174550637, + 1472693650165135, 898994790308209 +#else + 20590503, 24535444, 31529743, 26201766, 64402029, 10650547, + 31559055, 21944845, 18979185, 13396066 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 333403773039279, 295772542452938, 1693106465353610, + 912330357530760, 471235657950362 +#else + 24474287, 4968103, 22267082, 4407354, 24063882, 25229252, + 48291976, 13594781, 33514650, 7021958 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1811196219982022, 1068969825533602, 289602974833439, + 1988956043611592, 863562343398367 +#else + 55541958, 26988926, 45743778, 15928891, 40950559, 4315420, + 41160136, 29637754, 45628383, 12868081 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 906282429780072, 2108672665779781, 432396390473936, + 150625823801893, 1708930497638539 +#else + 38473832, 13504660, 19988037, 31421671, 21078224, 6443208, + 45662757, 2244499, 54653067, 25465048 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 925664675702328, 21416848568684, 1831436641861340, + 601157008940113, 371818055044496 +#else + 36513336, 13793478, 61256044, 319135, 41385692, 27290532, + 33086545, 8957937, 51875216, 5540520 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1479786007267725, 1738881859066675, 68646196476567, + 2146507056100328, 1247662817535471 +#else + 55478669, 22050529, 58989363, 25911358, 2620055, 1022908, + 43398120, 31985447, 50980335, 18591624 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 52035296774456, 939969390708103, 312023458773250, + 59873523517659, 1231345905848899 +#else + 23152952, 775386, 27395463, 14006635, 57407746, 4649511, + 1689819, 892185, 55595587, 18348483 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 643355106415761, 290186807495774, 2013561737429023, + 319648069511546, 393736678496162 +#else + 9770129, 9586738, 26496094, 4324120, 1556511, 30004408, + 27453818, 4763127, 47929250, 5867133 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 129358342392716, 1932811617704777, 1176749390799681, + 398040349861790, 1170779668090425 +#else + 34343820, 1927589, 31726409, 28801137, 23962433, 17534932, + 27846558, 5931263, 37359161, 17445976 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2051980782668029, 121859921510665, 2048329875753063, + 1235229850149665, 519062146124755 +#else + 27461885, 30576896, 22380809, 1815854, 44075111, 30522493, + 7283489, 18406359, 47582163, 7734628 +#endif + }}, + }, + }, + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1608170971973096, 415809060360428, 1350468408164766, + 2038620059057678, 1026904485989112 +#else + 59098600, 23963614, 55988460, 6196037, 29344158, 20123547, + 7585294, 30377806, 18549496, 15302069 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1837656083115103, 1510134048812070, 906263674192061, + 1821064197805734, 565375124676301 +#else + 34450527, 27383209, 59436070, 22502750, 6258877, 13504381, + 10458790, 27135971, 58236621, 8424745 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 578027192365650, 2034800251375322, 2128954087207123, + 478816193810521, 2196171989962750 +#else + 24687186, 8613276, 36441818, 30320886, 1863891, 31723888, + 19206233, 7134917, 55824382, 32725512 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1633188840273139, 852787172373708, 1548762607215796, + 1266275218902681, 1107218203325133 +#else + 11334899, 24336410, 8025292, 12707519, 17523892, 23078361, + 10243737, 18868971, 62042829, 16498836 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 462189358480054, 1784816734159228, 1611334301651368, + 1303938263943540, 707589560319424 +#else + 8911542, 6887158, 57524604, 26595841, 11145640, 24010752, + 17303924, 19430194, 6536640, 10543906 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1038829280972848, 38176604650029, 753193246598573, + 1136076426528122, 595709990562434 +#else + 38162480, 15479762, 49642029, 568875, 65611181, 11223453, + 64439674, 16928857, 39873154, 8876770 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1408451820859834, 2194984964010833, 2198361797561729, + 1061962440055713, 1645147963442934 +#else + 41365946, 20987567, 51458897, 32707824, 34082177, 32758143, + 33627041, 15824473, 66504438, 24514614 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 4701053362120, 1647641066302348, 1047553002242085, + 1923635013395977, 206970314902065 +#else + 10330056, 70051, 7957388, 24551765, 9764901, 15609756, 27698697, + 28664395, 1657393, 3084098 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1750479161778571, 1362553355169293, 1891721260220598, + 966109370862782, 1024913988299801 +#else + 10477963, 26084172, 12119565, 20303627, 29016246, 28188843, + 31280318, 14396151, 36875289, 15272408 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 212699049131723, 1117950018299775, 1873945661751056, + 1403802921984058, 130896082652698 +#else + 54820555, 3169462, 28813183, 16658753, 25116432, 27923966, + 41934906, 20918293, 42094106, 1950503 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 636808533673210, 1262201711667560, 390951380330599, + 1663420692697294, 561951321757406 +#else + 40928506, 9489186, 11053416, 18808271, 36055143, 5825629, + 58724558, 24786899, 15341278, 8373727 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 520731594438141, 1446301499955692, 273753264629267, + 1565101517999256, 1019411827004672 +#else + 28685821, 7759505, 52730348, 21551571, 35137043, 4079241, + 298136, 23321830, 64230656, 15190419 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 926527492029409, 1191853477411379, 734233225181171, + 184038887541270, 1790426146325343 +#else + 34175969, 13806335, 52771379, 17760000, 43104243, 10940927, + 8669718, 2742393, 41075551, 26679428 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1464651961852572, 1483737295721717, 1519450561335517, + 1161429831763785, 405914998179977 +#else + 65528476, 21825014, 41129205, 22109408, 49696989, 22641577, + 9291593, 17306653, 54954121, 6048604 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 996126634382301, 796204125879525, 127517800546509, + 344155944689303, 615279846169038 +#else + 36803549, 14843443, 1539301, 11864366, 20201677, 1900163, + 13934231, 5128323, 11213262, 9168384 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 738724080975276, 2188666632415296, 1961313708559162, + 1506545807547587, 1151301638969740 +#else + 40828332, 11007846, 19408960, 32613674, 48515898, 29225851, + 62020803, 22449281, 20470156, 17155731 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 622917337413835, 1218989177089035, 1284857712846592, + 970502061709359, 351025208117090 +#else + 43972811, 9282191, 14855179, 18164354, 59746048, 19145871, + 44324911, 14461607, 14042978, 5230683 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2067814584765580, 1677855129927492, 2086109782475197, + 235286517313238, 1416314046739645 +#else + 29969548, 30812838, 50396996, 25001989, 9175485, 31085458, + 21556950, 3506042, 61174973, 21104723 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 586844262630358, 307444381952195, 458399356043426, + 602068024507062, 1028548203415243 +#else + 63964118, 8744660, 19704003, 4581278, 46678178, 6830682, + 45824694, 8971512, 38569675, 15326562 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 678489922928203, 2016657584724032, 90977383049628, + 1026831907234582, 615271492942522 +#else + 47644235, 10110287, 49846336, 30050539, 43608476, 1355668, + 51585814, 15300987, 46594746, 9168259 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 301225714012278, 1094837270268560, 1202288391010439, + 644352775178361, 1647055902137983 +#else + 61755510, 4488612, 43305616, 16314346, 7780487, 17915493, + 38160505, 9601604, 33087103, 24543045 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1210746697896478, 1416608304244708, 686487477217856, + 1245131191434135, 1051238336855737 +#else + 47665694, 18041531, 46311396, 21109108, 37284416, 10229460, + 39664535, 18553900, 61111993, 15664671 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1135604073198207, 1683322080485474, 769147804376683, + 2086688130589414, 900445683120379 +#else + 23294591, 16921819, 44458082, 25083453, 27844203, 11461195, + 13099750, 31094076, 18151675, 13417686 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1971518477615628, 401909519527336, 448627091057375, + 1409486868273821, 1214789035034363 +#else + 42385932, 29377914, 35958184, 5988918, 40250079, 6685064, + 1661597, 21002991, 15271675, 18101767 +#endif + }}, + }, + }, + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1364039144731711, 1897497433586190, 2203097701135459, + 145461396811251, 1349844460790699 +#else + 11433023, 20325767, 8239630, 28274915, 65123427, 32828713, + 48410099, 2167543, 60187563, 20114249 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1045230323257973, 818206601145807, 630513189076103, + 1672046528998132, 807204017562437 +#else + 35672693, 15575145, 30436815, 12192228, 44645511, 9395378, + 57191156, 24915434, 12215109, 12028277 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 439961968385997, 386362664488986, 1382706320807688, + 309894000125359, 2207801346498567 +#else + 14098381, 6555944, 23007258, 5757252, 51681032, 20603929, + 30123439, 4617780, 50208775, 32898803 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1229004686397588, 920643968530863, 123975893911178, + 681423993215777, 1400559197080973 +#else + 63082644, 18313596, 11893167, 13718664, 52299402, 1847384, + 51288865, 10154008, 23973261, 20869958 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2003766096898049, 170074059235165, 1141124258967971, + 1485419893480973, 1573762821028725 +#else + 40577025, 29858441, 65199965, 2534300, 35238307, 17004076, + 18341389, 22134481, 32013173, 23450893 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 729905708611432, 1270323270673202, 123353058984288, + 426460209632942, 2195574535456672 +#else + 41629544, 10876442, 55337778, 18929291, 54739296, 1838103, + 21911214, 6354752, 4425632, 32716610 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1271140255321235, 2044363183174497, 52125387634689, + 1445120246694705, 942541986339084 +#else + 56675475, 18941465, 22229857, 30463385, 53917697, 776728, + 49693489, 21533969, 4725004, 14044970 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1761608437466135, 583360847526804, 1586706389685493, + 2157056599579261, 1170692369685772 +#else + 19268631, 26250011, 1555348, 8692754, 45634805, 23643767, + 6347389, 32142648, 47586572, 17444675 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 871476219910823, 1878769545097794, 2241832391238412, + 548957640601001, 690047440233174 +#else + 42244775, 12986007, 56209986, 27995847, 55796492, 33405905, + 19541417, 8180106, 9282262, 10282508 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 297194732135507, 1366347803776820, 1301185512245601, + 561849853336294, 1533554921345731 +#else + 40903763, 4428546, 58447668, 20360168, 4098401, 19389175, + 15522534, 8372215, 5542595, 22851749 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 999628998628371, 1132836708493400, 2084741674517453, + 469343353015612, 678782988708035 +#else + 56546323, 14895632, 26814552, 16880582, 49628109, 31065071, + 64326972, 6993760, 49014979, 10114654 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2189427607417022, 699801937082607, 412764402319267, + 1478091893643349, 2244675696854460 +#else + 47001790, 32625013, 31422703, 10427861, 59998115, 6150668, + 38017109, 22025285, 25953724, 33448274 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1712292055966563, 204413590624874, 1405738637332841, + 408981300829763, 861082219276721 +#else + 62874467, 25515139, 57989738, 3045999, 2101609, 20947138, + 19390019, 6094296, 63793585, 12831124 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 508561155940631, 966928475686665, 2236717801150132, + 424543858577297, 2089272956986143 +#else + 51110167, 7578151, 5310217, 14408357, 33560244, 33329692, + 31575953, 6326196, 7381791, 31132593 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 221245220129925, 1156020201681217, 491145634799213, + 542422431960839, 828100817819207 +#else + 46206085, 3296810, 24736065, 17226043, 18374253, 7318640, + 6295303, 8082724, 51746375, 12339663 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 153756971240384, 1299874139923977, 393099165260502, + 1058234455773022, 996989038681183 +#else + 27724736, 2291157, 6088201, 19369634, 1792726, 5857634, + 13848414, 15768922, 25091167, 14856294 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 559086812798481, 573177704212711, 1629737083816402, + 1399819713462595, 1646954378266038 +#else + 48242193, 8331042, 24373479, 8541013, 66406866, 24284974, + 12927299, 20858939, 44926390, 24541532 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1887963056288059, 228507035730124, 1468368348640282, + 930557653420194, 613513962454686 +#else + 55685435, 28132841, 11632844, 3405020, 30536730, 21880393, + 39848098, 13866389, 30146206, 9142070 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1224529808187553, 1577022856702685, 2206946542980843, + 625883007765001, 279930793512158 +#else + 3924129, 18246916, 53291741, 23499471, 12291819, 32886066, + 39406089, 9326383, 58871006, 4171293 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1076287717051609, 1114455570543035, 187297059715481, + 250446884292121, 1885187512550540 +#else + 51186905, 16037936, 6713787, 16606682, 45496729, 2790943, + 26396185, 3731949, 345228, 28091483 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 902497362940219, 76749815795675, 1657927525633846, + 1420238379745202, 1340321636548352 +#else + 45781307, 13448258, 25284571, 1143661, 20614966, 24705045, + 2031538, 21163201, 50855680, 19972348 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1129576631190784, 1281994010027327, 996844254743018, + 257876363489249, 1150850742055018 +#else + 31016192, 16832003, 26371391, 19103199, 62081514, 14854136, + 17477601, 3842657, 28012650, 17149012 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 628740660038789, 1943038498527841, 467786347793886, + 1093341428303375, 235413859513003 +#else + 62033029, 9368965, 58546785, 28953529, 51858910, 6970559, + 57918991, 16292056, 58241707, 3507939 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 237425418909360, 469614029179605, 1512389769174935, + 1241726368345357, 441602891065214 +#else + 29439664, 3537914, 23333589, 6997794, 49553303, 22536363, + 51899661, 18503164, 57943934, 6580395 +#endif + }}, + }, + }, + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1736417953058555, 726531315520508, 1833335034432527, + 1629442561574747, 624418919286085 +#else + 54923003, 25874643, 16438268, 10826160, 58412047, 27318820, + 17860443, 24280586, 65013061, 9304566 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1960754663920689, 497040957888962, 1909832851283095, + 1271432136996826, 2219780368020940 +#else + 20714545, 29217521, 29088194, 7406487, 11426967, 28458727, + 14792666, 18945815, 5289420, 33077305 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1537037379417136, 1358865369268262, 2130838645654099, + 828733687040705, 1999987652890901 +#else + 50443312, 22903641, 60948518, 20248671, 9192019, 31751970, + 17271489, 12349094, 26939669, 29802138 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 629042105241814, 1098854999137608, 887281544569320, + 1423102019874777, 7911258951561 +#else + 54218966, 9373457, 31595848, 16374215, 21471720, 13221525, + 39825369, 21205872, 63410057, 117886 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1811562332665373, 1501882019007673, 2213763501088999, + 359573079719636, 36370565049116 +#else + 22263325, 26994382, 3984569, 22379786, 51994855, 32987646, + 28311252, 5358056, 43789084, 541963 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 218907117361280, 1209298913016966, 1944312619096112, + 1130690631451061, 1342327389191701 +#else + 16259200, 3261970, 2309254, 18019958, 50223152, 28972515, + 24134069, 16848603, 53771797, 20002236 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1369976867854704, 1396479602419169, 1765656654398856, + 2203659200586299, 998327836117241 +#else + 9378160, 20414246, 44262881, 20809167, 28198280, 26310334, + 64709179, 32837080, 690425, 14876244 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2230701885562825, 1348173180338974, 2172856128624598, + 1426538746123771, 444193481326151 +#else + 24977353, 33240048, 58884894, 20089345, 28432342, 32378079, + 54040059, 21257083, 44727879, 6618998 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 784210426627951, 918204562375674, 1284546780452985, + 1324534636134684, 1872449409642708 +#else + 65570671, 11685645, 12944378, 13682314, 42719353, 19141238, + 8044828, 19737104, 32239828, 27901670 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 319638829540294, 596282656808406, 2037902696412608, + 1557219121643918, 341938082688094 +#else + 48505798, 4762989, 66182614, 8885303, 38696384, 30367116, + 9781646, 23204373, 32779358, 5095274 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1901860206695915, 2004489122065736, 1625847061568236, + 973529743399879, 2075287685312905 +#else + 34100715, 28339925, 34843976, 29869215, 9460460, 24227009, + 42507207, 14506723, 21639561, 30924196 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1371853944110545, 1042332820512553, 1949855697918254, + 1791195775521505, 37487364849293 +#else + 50707921, 20442216, 25239337, 15531969, 3987758, 29055114, + 65819361, 26690896, 17874573, 558605 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 687200189577855, 1082536651125675, 644224940871546, + 340923196057951, 343581346747396 +#else + 53508735, 10240080, 9171883, 16131053, 46239610, 9599699, + 33499487, 5080151, 2085892, 5119761 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2082717129583892, 27829425539422, 145655066671970, + 1690527209845512, 1865260509673478 +#else + 44903700, 31034903, 50727262, 414690, 42089314, 2170429, + 30634760, 25190818, 35108870, 27794547 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1059729620568824, 2163709103470266, 1440302280256872, + 1769143160546397, 869830310425069 +#else + 60263160, 15791201, 8550074, 32241778, 29928808, 21462176, + 27534429, 26362287, 44757485, 12961481 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1609516219779025, 777277757338817, 2101121130363987, + 550762194946473, 1905542338659364 +#else + 42616785, 23983660, 10368193, 11582341, 43711571, 31309144, + 16533929, 8206996, 36914212, 28394793 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2024821921041576, 426948675450149, 595133284085473, + 471860860885970, 600321679413000 +#else + 55987368, 30172197, 2307365, 6362031, 66973409, 8868176, + 50273234, 7031274, 7589640, 8945490 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 598474602406721, 1468128276358244, 1191923149557635, + 1501376424093216, 1281662691293476 +#else + 34956097, 8917966, 6661220, 21876816, 65916803, 17761038, + 7251488, 22372252, 24099108, 19098262 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1721138489890707, 1264336102277790, 433064545421287, + 1359988423149466, 1561871293409447 +#else + 5019539, 25646962, 4244126, 18840076, 40175591, 6453164, + 47990682, 20265406, 60876967, 23273695 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 719520245587143, 393380711632345, 132350400863381, + 1543271270810729, 1819543295798660 +#else + 10853575, 10721687, 26480089, 5861829, 44113045, 1972174, + 65242217, 22996533, 63745412, 27113307 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 396397949784152, 1811354474471839, 1362679985304303, + 2117033964846756, 498041172552279 +#else + 50106456, 5906789, 221599, 26991285, 7828207, 20305514, + 24362660, 31546264, 53242455, 7421391 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1812471844975748, 1856491995543149, 126579494584102, + 1036244859282620, 1975108050082550 +#else + 8139908, 27007935, 32257645, 27663886, 30375718, 1886181, + 45933756, 15441251, 28826358, 29431403 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 650623932407995, 1137551288410575, 2125223403615539, + 1725658013221271, 2134892965117796 +#else + 6267067, 9695052, 7709135, 16950835, 34239795, 31668296, + 14795159, 25714308, 13746020, 31812384 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 522584000310195, 1241762481390450, 1743702789495384, + 2227404127826575, 1686746002148897 +#else + 28584883, 7787108, 60375922, 18503702, 22846040, 25983196, + 63926927, 33190907, 4771361, 25134474 +#endif + }}, + }, + }, + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 427904865186312, 1703211129693455, 1585368107547509, + 1436984488744336, 761188534613978 +#else + 24949256, 6376279, 39642383, 25379823, 48462709, 23623825, + 33543568, 21412737, 3569626, 11342593 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 318101947455002, 248138407995851, 1481904195303927, + 309278454311197, 1258516760217879 +#else + 26514970, 4740088, 27912651, 3697550, 19331575, 22082093, + 6809885, 4608608, 7325975, 18753361 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1275068538599310, 513726919533379, 349926553492294, + 688428871968420, 1702400196000666 +#else + 55490446, 19000001, 42787651, 7655127, 65739590, 5214311, + 39708324, 10258389, 49462170, 25367739 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1061864036265233, 961611260325381, 321859632700838, + 1045600629959517, 1985130202504038 +#else + 11431185, 15823007, 26570245, 14329124, 18029990, 4796082, + 35662685, 15580663, 9280358, 29580745 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1558816436882417, 1962896332636523, 1337709822062152, + 1501413830776938, 294436165831932 +#else + 66948081, 23228174, 44253547, 29249434, 46247496, 19933429, + 34297962, 22372809, 51563772, 4387440 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 818359826554971, 1862173000996177, 626821592884859, + 573655738872376, 1749691246745455 +#else + 46309467, 12194511, 3937617, 27748540, 39954043, 9340369, + 42594872, 8548136, 20617071, 26072431 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1988022651432119, 1082111498586040, 1834020786104821, + 1454826876423687, 692929915223122 +#else + 66170039, 29623845, 58394552, 16124717, 24603125, 27329039, + 53333511, 21678609, 24345682, 10325460 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2146513703733331, 584788900394667, 464965657279958, + 2183973639356127, 238371159456790 +#else + 47253587, 31985546, 44906155, 8714033, 14007766, 6928528, + 16318175, 32543743, 4766742, 3552007 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1129007025494441, 2197883144413266, 265142755578169, + 971864464758890, 1983715884903702 +#else + 45357481, 16823515, 1351762, 32751011, 63099193, 3950934, + 3217514, 14481909, 10988822, 29559670 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1291366624493075, 381456718189114, 1711482489312444, + 1815233647702022, 892279782992467 +#else + 15564307, 19242862, 3101242, 5684148, 30446780, 25503076, + 12677126, 27049089, 58813011, 13296004 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 444548969917454, 1452286453853356, 2113731441506810, + 645188273895859, 810317625309512 +#else + 57666574, 6624295, 36809900, 21640754, 62437882, 31497052, + 31521203, 9614054, 37108040, 12074673 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2242724082797924, 1373354730327868, 1006520110883049, + 2147330369940688, 1151816104883620 +#else + 4771172, 33419193, 14290748, 20464580, 27992297, 14998318, + 65694928, 31997715, 29832612, 17163397 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1745720200383796, 1911723143175317, 2056329390702074, + 355227174309849, 879232794371100 +#else + 7064884, 26013258, 47946901, 28486894, 48217594, 30641695, + 25825241, 5293297, 39986204, 13101589 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 163723479936298, 115424889803150, 1156016391581227, + 1894942220753364, 1970549419986329 +#else + 64810282, 2439669, 59642254, 1719964, 39841323, 17225986, + 32512468, 28236839, 36752793, 29363474 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 681981452362484, 267208874112496, 1374683991933094, + 638600984916117, 646178654558546 +#else + 37102324, 10162315, 33928688, 3981722, 50626726, 20484387, + 14413973, 9515896, 19568978, 9628812 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 13378654854251, 106237307029567, 1944412051589651, + 1841976767925457, 230702819835573 +#else + 33053803, 199357, 15894591, 1583059, 27380243, 28973997, + 49269969, 27447592, 60817077, 3437739 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 260683893467075, 854060306077237, 913639551980112, + 4704576840123, 280254810808712 +#else + 48129987, 3884492, 19469877, 12726490, 15913552, 13614290, + 44147131, 70103, 7463304, 4176122 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 715374893080287, 1173334812210491, 1806524662079626, + 1894596008000979, 398905715033393 +#else + 39984863, 10659916, 11482427, 17484051, 12771466, 26919315, + 34389459, 28231680, 24216881, 5944158 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 500026409727661, 1596431288195371, 1420380351989370, + 985211561521489, 392444930785633 +#else + 8894125, 7450974, 64444715, 23788679, 39028346, 21165316, + 19345745, 14680796, 11632993, 5847885 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2096421546958141, 1922523000950363, 789831022876840, + 427295144688779, 320923973161730 +#else + 26942781, 31239115, 9129563, 28647825, 26024104, 11769399, + 55590027, 6367193, 57381634, 4782139 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1927770723575450, 1485792977512719, 1850996108474547, + 551696031508956, 2126047405475647 +#else + 19916442, 28726022, 44198159, 22140040, 25606323, 27581991, + 33253852, 8220911, 6358847, 31680575 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2112099158080148, 742570803909715, 6484558077432, + 1951119898618916, 93090382703416 +#else + 801428, 31472730, 16569427, 11065167, 29875704, 96627, 7908388, + 29073952, 53570360, 1387154 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 383905201636970, 859946997631870, 855623867637644, + 1017125780577795, 794250831877809 +#else + 19646058, 5720633, 55692158, 12814208, 11607948, 12749789, + 14147075, 15156355, 45242033, 11835259 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 77571826285752, 999304298101753, 487841111777762, + 1038031143212339, 339066367948762 +#else + 19299512, 1155910, 28703737, 14890794, 2925026, 7269399, + 26121523, 15467869, 40548314, 5052482 +#endif + }}, + }, + }, + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 674994775520533, 266035846330789, 826951213393478, + 1405007746162285, 1781791018620876 +#else + 64091413, 10058205, 1980837, 3964243, 22160966, 12322533, + 60677741, 20936246, 12228556, 26550755 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1001412661522686, 348196197067298, 1666614366723946, + 888424995032760, 580747687801357 +#else + 32944382, 14922211, 44263970, 5188527, 21913450, 24834489, + 4001464, 13238564, 60994061, 8653814 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1939560076207777, 1409892634407635, 552574736069277, + 383854338280405, 190706709864139 +#else + 22865569, 28901697, 27603667, 21009037, 14348957, 8234005, + 24808405, 5719875, 28483275, 2841751 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2177087163428741, 1439255351721944, 1208070840382793, + 2230616362004769, 1396886392021913 +#else + 50687877, 32441126, 66781144, 21446575, 21886281, 18001658, + 65220897, 33238773, 19932057, 20815229 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 676962063230039, 1880275537148808, 2046721011602706, + 888463247083003, 1318301552024067 +#else + 55452759, 10087520, 58243976, 28018288, 47830290, 30498519, + 3999227, 13239134, 62331395, 19644223 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1466980508178206, 617045217998949, 652303580573628, + 757303753529064, 207583137376902 +#else + 1382174, 21859713, 17266789, 9194690, 53784508, 9720080, + 20403944, 11284705, 53095046, 3093229 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1511056752906902, 105403126891277, 493434892772846, + 1091943425335976, 1802717338077427 +#else + 16650902, 22516500, 66044685, 1570628, 58779118, 7352752, + 66806440, 16271224, 43059443, 26862581 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1853982405405128, 1878664056251147, 1528011020803992, + 1019626468153565, 1128438412189035 +#else + 45197768, 27626490, 62497547, 27994275, 35364760, 22769138, + 24123613, 15193618, 45456747, 16815042 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1963939888391106, 293456433791664, 697897559513649, + 985882796904380, 796244541237972 +#else + 57172930, 29264984, 41829040, 4372841, 2087473, 10399484, + 31870908, 14690798, 17361620, 11864968 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 416770998629779, 389655552427054, 1314476859406756, + 1749382513022778, 1161905598739491 +#else + 55801235, 6210371, 13206574, 5806320, 38091172, 19587231, + 54777658, 26067830, 41530403, 17313742 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1428358296490651, 1027115282420478, 304840698058337, + 441410174026628, 1819358356278573 +#else + 14668443, 21284197, 26039038, 15305210, 25515617, 4542480, + 10453892, 6577524, 9145645, 27110552 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 204943430200135, 1554861433819175, 216426658514651, + 264149070665950, 2047097371738319 +#else + 5974855, 3053895, 57675815, 23169240, 35243739, 3225008, + 59136222, 3936127, 61456591, 30504127 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1934415182909034, 1393285083565062, 516409331772960, + 1157690734993892, 121039666594268 +#else + 30625386, 28825032, 41552902, 20761565, 46624288, 7695098, + 17097188, 17250936, 39109084, 1803631 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 662035583584445, 286736105093098, 1131773000510616, + 818494214211439, 472943792054479 +#else + 63555773, 9865098, 61880298, 4272700, 61435032, 16864731, + 14911343, 12196514, 45703375, 7047411 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 665784778135882, 1893179629898606, 808313193813106, + 276797254706413, 1563426179676396 +#else + 20093258, 9920966, 55970670, 28210574, 13161586, 12044805, + 34252013, 4124600, 34765036, 23296865 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 945205108984232, 526277562959295, 1324180513733566, + 1666970227868664, 153547609289173 +#else + 46320040, 14084653, 53577151, 7842146, 19119038, 19731827, + 4752376, 24839792, 45429205, 2288037 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2031433403516252, 203996615228162, 170487168837083, + 981513604791390, 843573964916831 +#else + 40289628, 30270716, 29965058, 3039786, 52635099, 2540456, + 29457502, 14625692, 42289247, 12570231 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1476570093962618, 838514669399805, 1857930577281364, + 2017007352225784, 317085545220047 +#else + 66045306, 22002608, 16920317, 12494842, 1278292, 27685323, + 45948920, 30055751, 55134159, 4724942 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1461557121912842, 1600674043318359, 2157134900399597, + 1670641601940616, 127765583803283 +#else + 17960970, 21778898, 62967895, 23851901, 58232301, 32143814, + 54201480, 24894499, 37532563, 1903855 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1293543509393474, 2143624609202546, 1058361566797508, + 214097127393994, 946888515472729 +#else + 23134274, 19275300, 56426866, 31942495, 20684484, 15770816, + 54119114, 3190295, 26955097, 14109738 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 357067959932916, 1290876214345711, 521245575443703, + 1494975468601005, 800942377643885 +#else + 15308788, 5320727, 36995055, 19235554, 22902007, 7767164, + 29425325, 22276870, 31960941, 11934971 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 566116659100033, 820247422481740, 994464017954148, + 327157611686365, 92591318111744 +#else + 39713153, 8435795, 4109644, 12222639, 42480996, 14818668, + 20638173, 4875028, 10491392, 1379718 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 617256647603209, 1652107761099439, 1857213046645471, + 1085597175214970, 817432759830522 +#else + 53949449, 9197840, 3875503, 24618324, 65725151, 27674630, + 33518458, 16176658, 21432314, 12180697 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 771808161440705, 1323510426395069, 680497615846440, + 851580615547985, 1320806384849017 +#else + 55321537, 11500837, 13787581, 19721842, 44678184, 10140204, + 1465425, 12689540, 56807545, 19681548 +#endif + }}, + }, + }, + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1219260086131915, 647169006596815, 79601124759706, + 2161724213426748, 404861897060198 +#else + 5414091, 18168391, 46101199, 9643569, 12834970, 1186149, + 64485948, 32212200, 26128230, 6032912 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1327968293887866, 1335500852943256, 1401587164534264, + 558137311952440, 1551360549268902 +#else + 40771450, 19788269, 32496024, 19900513, 17847800, 20885276, + 3604024, 8316894, 41233830, 23117073 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 417621685193956, 1429953819744454, 396157358457099, + 1940470778873255, 214000046234152 +#else + 3296484, 6223048, 24680646, 21307972, 44056843, 5903204, + 58246567, 28915267, 12376616, 3188849 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1268047918491973, 2172375426948536, 1533916099229249, + 1761293575457130, 1590622667026765 +#else + 29190469, 18895386, 27549112, 32370916, 3520065, 22857131, + 32049514, 26245319, 50999629, 23702124 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1627072914981959, 2211603081280073, 1912369601616504, + 1191770436221309, 2187309757525860 +#else + 52364359, 24245275, 735817, 32955454, 46701176, 28496527, + 25246077, 17758763, 18640740, 32593455 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1149147819689533, 378692712667677, 828475842424202, + 2218619146419342, 70688125792186 +#else + 60180029, 17123636, 10361373, 5642961, 4910474, 12345252, + 35470478, 33060001, 10530746, 1053335 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1299739417079761, 1438616663452759, 1536729078504412, + 2053896748919838, 1008421032591246 +#else + 37842897, 19367626, 53570647, 21437058, 47651804, 22899047, + 35646494, 30605446, 24018830, 15026644 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2040723824657366, 399555637875075, 632543375452995, + 872649937008051, 1235394727030233 +#else + 44516310, 30409154, 64819587, 5953842, 53668675, 9425630, + 25310643, 13003497, 64794073, 18408815 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2211311599327900, 2139787259888175, 938706616835350, + 12609661139114, 2081897930719789 +#else + 39688860, 32951110, 59064879, 31885314, 41016598, 13987818, + 39811242, 187898, 43942445, 31022696 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1324994503390450, 336982330582631, 1183998925654177, + 1091654665913274, 48727673971319 +#else + 45364466, 19743956, 1844839, 5021428, 56674465, 17642958, + 9716666, 16266922, 62038647, 726098 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1845522914617879, 1222198248335542, 150841072760134, + 1927029069940982, 1189913404498011 +#else + 29370903, 27500434, 7334070, 18212173, 9385286, 2247707, + 53446902, 28714970, 30007387, 17731091 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1079559557592645, 2215338383666441, 1903569501302605, + 49033973033940, 305703433934152 +#else + 66172485, 16086690, 23751945, 33011114, 65941325, 28365395, + 9137108, 730663, 9835848, 4555336 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 94653405416909, 1386121349852999, 1062130477891762, + 36553947479274, 833669648948846 +#else + 43732429, 1410445, 44855111, 20654817, 30867634, 15826977, + 17693930, 544696, 55123566, 12422645 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1432015813136298, 440364795295369, 1395647062821501, + 1976874522764578, 934452372723352 +#else + 31117226, 21338698, 53606025, 6561946, 57231997, 20796761, + 61990178, 29457725, 29120152, 13924425 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1296625309219774, 2068273464883862, 1858621048097805, + 1492281814208508, 2235868981918946 +#else + 49707966, 19321222, 19675798, 30819676, 56101901, 27695611, + 57724924, 22236731, 7240930, 33317044 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1490330266465570, 1858795661361448, 1436241134969763, + 294573218899647, 1208140011028933 +#else + 35747106, 22207651, 52101416, 27698213, 44655523, 21401660, + 1222335, 4389483, 3293637, 18002689 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1282462923712748, 741885683986255, 2027754642827561, + 518989529541027, 1826610009555945 +#else + 50424044, 19110186, 11038543, 11054958, 53307689, 30215898, + 42789283, 7733546, 12796905, 27218610 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1525827120027511, 723686461809551, 1597702369236987, + 244802101764964, 1502833890372311 +#else + 58349431, 22736595, 41689999, 10783768, 36493307, 23807620, + 38855524, 3647835, 3222231, 22393970 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 113622036244513, 1233740067745854, 674109952278496, + 2114345180342965, 166764512856263 +#else + 18606113, 1693100, 41660478, 18384159, 4112352, 10045021, + 23603893, 31506198, 59558087, 2484984 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2041668749310338, 2184405322203901, 1633400637611036, + 2110682505536899, 2048144390084644 +#else + 9255298, 30423235, 54952701, 32550175, 13098012, 24339566, + 16377219, 31451620, 47306788, 30519729 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 503058759232932, 760293024620937, 2027152777219493, + 666858468148475, 1539184379870952 +#else + 44379556, 7496159, 61366665, 11329248, 19991973, 30206930, + 35390715, 9936965, 37011176, 22935634 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1916168475367211, 915626432541343, 883217071712575, + 363427871374304, 1976029821251593 +#else + 21878571, 28553135, 4338335, 13643897, 64071999, 13160959, + 19708896, 5415497, 59748361, 29445138 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 678039535434506, 570587290189340, 1605302676614120, + 2147762562875701, 1706063797091704 +#else + 27736842, 10103576, 12500508, 8502413, 63695848, 23920873, + 10436917, 32004156, 43449720, 25422331 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1439489648586438, 2194580753290951, 832380563557396, + 561521973970522, 584497280718389 +#else + 19492550, 21450067, 37426887, 32701801, 63900692, 12403436, + 30066266, 8367329, 13243957, 8709688 +#endif + }}, + }, + }, + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 187989455492609, 681223515948275, 1933493571072456, + 1872921007304880, 488162364135671 +#else + 12015105, 2801261, 28198131, 10151021, 24818120, 28811299, + 55914672, 27908697, 5150967, 7274186 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1413466089534451, 410844090765630, 1397263346404072, + 408227143123410, 1594561803147811 +#else + 2831347, 21062286, 1478974, 6122054, 23825128, 20820846, + 31097298, 6083058, 31021603, 23760822 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2102170800973153, 719462588665004, 1479649438510153, + 1097529543970028, 1302363283777685 +#else + 64578913, 31324785, 445612, 10720828, 53259337, 22048494, + 43601132, 16354464, 15067285, 19406725 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 942065717847195, 1069313679352961, 2007341951411051, + 70973416446291, 1419433790163706 +#else + 7840923, 14037873, 33744001, 15934015, 66380651, 29911725, + 21403987, 1057586, 47729402, 21151211 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1146565545556377, 1661971299445212, 406681704748893, + 564452436406089, 1109109865829139 +#else + 915865, 17085158, 15608284, 24765302, 42751837, 6060029, + 49737545, 8410996, 59888403, 16527024 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2214421081775077, 1165671861210569, 1890453018796184, + 3556249878661, 442116172656317 +#else + 32922597, 32997445, 20336073, 17369864, 10903704, 28169945, + 16957573, 52992, 23834301, 6588044 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 753830546620811, 1666955059895019, 1530775289309243, + 1119987029104146, 2164156153857580 +#else + 32752011, 11232950, 3381995, 24839566, 22652987, 22810329, + 17159698, 16689107, 46794284, 32248439 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 615171919212796, 1523849404854568, 854560460547503, + 2067097370290715, 1765325848586042 +#else + 62419196, 9166775, 41398568, 22707125, 11576751, 12733943, + 7924251, 30802151, 1976122, 26305405 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1094538949313667, 1796592198908825, 870221004284388, + 2025558921863561, 1699010892802384 +#else + 21251203, 16309901, 64125849, 26771309, 30810596, 12967303, + 156041, 30183180, 12331344, 25317235 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1951351290725195, 1916457206844795, 198025184438026, + 1909076887557595, 1938542290318919 +#else + 8651595, 29077400, 51023227, 28557437, 13002506, 2950805, + 29054427, 28447462, 10008135, 28886531 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1014323197538413, 869150639940606, 1756009942696599, + 1334952557375672, 1544945379082874 +#else + 31486061, 15114593, 52847614, 12951353, 14369431, 26166587, + 16347320, 19892343, 8684154, 23021480 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 764055910920305, 1603590757375439, 146805246592357, + 1843313433854297, 954279890114939 +#else + 19443825, 11385320, 24468943, 23895364, 43189605, 2187568, + 40845657, 27467510, 31316347, 14219878 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 80113526615750, 764536758732259, 1055139345100233, + 469252651759390, 617897512431515 +#else + 38514374, 1193784, 32245219, 11392485, 31092169, 15722801, + 27146014, 6992409, 29126555, 9207390 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 74497112547268, 740094153192149, 1745254631717581, + 727713886503130, 1283034364416928 +#else + 32382916, 1110093, 18477781, 11028262, 39697101, 26006320, + 62128346, 10843781, 59151264, 19118701 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 525892105991110, 1723776830270342, 1476444848991936, + 573789489857760, 133864092632978 +#else + 2814918, 7836403, 27519878, 25686276, 46214848, 22000742, + 45614304, 8550129, 28346258, 1994730 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 542611720192581, 1986812262899321, 1162535242465837, + 481498966143464, 544600533583622 +#else + 47530565, 8085544, 53108345, 29605809, 2785837, 17323125, + 47591912, 7174893, 22628102, 8115180 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 64123227344372, 1239927720647794, 1360722983445904, + 222610813654661, 62429487187991 +#else + 36703732, 955510, 55975026, 18476362, 34661776, 20276352, + 41457285, 3317159, 57165847, 930271 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1793193323953132, 91096687857833, 70945970938921, + 2158587638946380, 1537042406482111 +#else + 51805164, 26720662, 28856489, 1357446, 23421993, 1057177, + 24091212, 32165462, 44343487, 22903716 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1895854577604609, 1394895708949416, 1728548428495944, + 1140864900240149, 563645333603061 +#else + 44357633, 28250434, 54201256, 20785565, 51297352, 25757378, + 52269845, 17000211, 65241845, 8398969 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 141358280486863, 91435889572504, 1087208572552643, + 1829599652522921, 1193307020643647 +#else + 35139535, 2106402, 62372504, 1362500, 12813763, 16200670, + 22981545, 27263159, 18009407, 17781660 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1611230858525381, 950720175540785, 499589887488610, + 2001656988495019, 88977313255908 +#else + 49887941, 24009210, 39324209, 14166834, 29815394, 7444469, + 29551787, 29827013, 19288548, 1325865 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1189080501479658, 2184348804772597, 1040818725742319, + 2018318290311834, 1712060030915354 +#else + 15100138, 17718680, 43184885, 32549333, 40658671, 15509407, + 12376730, 30075286, 33166106, 25511682 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 873966876953756, 1090638350350440, 1708559325189137, + 672344594801910, 1320437969700239 +#else + 20909212, 13023121, 57899112, 16251777, 61330449, 25459517, + 12412150, 10018715, 2213263, 19676059 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1508590048271766, 1131769479776094, 101550868699323, + 428297785557897, 561791648661744 +#else + 32529814, 22479743, 30361438, 16864679, 57972923, 1513225, + 22922121, 6382134, 61341936, 8371347 +#endif + }}, + }, + }, + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 756417570499462, 237882279232602, 2136263418594016, + 1701968045454886, 703713185137472 +#else + 9923462, 11271500, 12616794, 3544722, 37110496, 31832805, + 12891686, 25361300, 40665920, 10486143 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1781187809325462, 1697624151492346, 1381393690939988, + 175194132284669, 1483054666415238 +#else + 44511638, 26541766, 8587002, 25296571, 4084308, 20584370, + 361725, 2610596, 43187334, 22099236 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2175517777364616, 708781536456029, 955668231122942, + 1967557500069555, 2021208005604118 +#else + 5408392, 32417741, 62139741, 10561667, 24145918, 14240566, + 31319731, 29318891, 19985174, 30118346 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1115135966606887, 224217372950782, 915967306279222, + 593866251291540, 561747094208006 +#else + 53114407, 16616820, 14549246, 3341099, 32155958, 13648976, + 49531796, 8849296, 65030, 8370684 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1443163092879439, 391875531646162, 2180847134654632, + 464538543018753, 1594098196837178 +#else + 58787919, 21504805, 31204562, 5839400, 46481576, 32497154, + 47665921, 6922163, 12743482, 23753914 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 850858855888869, 319436476624586, 327807784938441, + 740785849558761, 17128415486016 +#else + 64747493, 12678784, 28815050, 4759974, 43215817, 4884716, + 23783145, 11038569, 18800704, 255233 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2132756334090067, 536247820155645, 48907151276867, + 608473197600695, 1261689545022784 +#else + 61839187, 31780545, 13957885, 7990715, 23132995, 728773, + 13393847, 9066957, 19258688, 18800639 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1525176236978354, 974205476721062, 293436255662638, + 148269621098039, 137961998433963 +#else + 64172210, 22726896, 56676774, 14516792, 63468078, 4372540, + 35173943, 2209389, 65584811, 2055793 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1121075518299410, 2071745529082111, 1265567917414828, + 1648196578317805, 496232102750820 +#else + 580882, 16705327, 5468415, 30871414, 36182444, 18858431, + 59905517, 24560042, 37087844, 7394434 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 122321229299801, 1022922077493685, 2001275453369484, + 2017441881607947, 993205880778002 +#else + 23838809, 1822728, 51370421, 15242726, 8318092, 29821328, + 45436683, 30062226, 62287122, 14799920 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 654925550560074, 1168810995576858, 575655959430926, + 905758704861388, 496774564663534 +#else + 13345610, 9759151, 3371034, 17416641, 16353038, 8577942, + 31129804, 13496856, 58052846, 7402517 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1954109525779738, 2117022646152485, 338102630417180, + 1194140505732026, 107881734943492 +#else + 2286874, 29118501, 47066405, 31546095, 53412636, 5038121, + 11006906, 17794080, 8205060, 1607563 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1714785840001267, 2036500018681589, 1876380234251966, + 2056717182974196, 1645855254384642 +#else + 14414067, 25552300, 3331829, 30346215, 22249150, 27960244, + 18364660, 30647474, 30019586, 24525154 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 106431476499341, 62482972120563, 1513446655109411, + 807258751769522, 538491469114 +#else + 39420813, 1585952, 56333811, 931068, 37988643, 22552112, + 52698034, 12029092, 9944378, 8024 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2002850762893643, 1243624520538135, 1486040410574605, + 2184752338181213, 378495998083531 +#else + 4368715, 29844802, 29874199, 18531449, 46878477, 22143727, + 50994269, 32555346, 58966475, 5640029 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 922510868424903, 1089502620807680, 402544072617374, + 1131446598479839, 1290278588136533 +#else + 10299591, 13746483, 11661824, 16234854, 7630238, 5998374, + 9809887, 16859868, 15219797, 19226649 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1867998812076769, 715425053580701, 39968586461416, + 2173068014586163, 653822651801304 +#else + 27425505, 27835351, 3055005, 10660664, 23458024, 595578, + 51710259, 32381236, 48766680, 9742716 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 162892278589453, 182585796682149, 75093073137630, + 497037941226502, 133871727117371 +#else + 6744077, 2427284, 26042789, 2720740, 66260958, 1118973, + 32324614, 7406442, 12420155, 1994844 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1914596576579670, 1608999621851578, 1987629837704609, + 1519655314857977, 1819193753409464 +#else + 14012502, 28529712, 48724410, 23975962, 40623521, 29617992, + 54075385, 22644628, 24319928, 27108099 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1949315551096831, 1069003344994464, 1939165033499916, + 1548227205730856, 1933767655861407 +#else + 16412671, 29047065, 10772640, 15929391, 50040076, 28895810, + 10555944, 23070383, 37006495, 28815383 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1730519386931635, 1393284965610134, 1597143735726030, + 416032382447158, 1429665248828629 +#else + 22397363, 25786748, 57815702, 20761563, 17166286, 23799296, + 39775798, 6199365, 21880021, 21303672 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 360275475604565, 547835731063078, 215360904187529, + 596646739879007, 332709650425085 +#else + 62825557, 5368522, 35991846, 8163388, 36785801, 3209127, + 16557151, 8890729, 8840445, 4957760 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 47602113726801, 1522314509708010, 437706261372925, + 814035330438027, 335930650933545 +#else + 51661137, 709326, 60189418, 22684253, 37330941, 6522331, + 45388683, 12130071, 52312361, 5005756 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1291597595523886, 1058020588994081, 402837842324045, + 1363323695882781, 2105763393033193 +#else + 64994094, 19246303, 23019041, 15765735, 41839181, 6002751, + 10183197, 20315106, 50713577, 31378319 +#endif + }}, + }, + }, + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 109521982566564, 1715257748585139, 1112231216891516, + 2046641005101484, 134249157157013 +#else + 48083108, 1632004, 13466291, 25559332, 43468412, 16573536, + 35094956, 30497327, 22208661, 2000468 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2156991030936798, 2227544497153325, 1869050094431622, + 754875860479115, 1754242344267058 +#else + 3065054, 32141671, 41510189, 33192999, 49425798, 27851016, + 58944651, 11248526, 63417650, 26140247 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1846089562873800, 98894784984326, 1412430299204844, + 171351226625762, 1100604760929008 +#else + 10379208, 27508878, 8877318, 1473647, 37817580, 21046851, + 16690914, 2553332, 63976176, 16400288 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 84172382130492, 499710970700046, 425749630620778, + 1762872794206857, 612842602127960 +#else + 15716668, 1254266, 48636174, 7446273, 58659946, 6344163, + 45011593, 26268851, 26894936, 9132066 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 868309334532756, 1703010512741873, 1952690008738057, + 4325269926064, 2071083554962116 +#else + 24158868, 12938817, 11085297, 25376834, 39045385, 29097348, + 36532400, 64451, 60291780, 30861549 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 523094549451158, 401938899487815, 1407690589076010, + 2022387426254453, 158660516411257 +#else + 13488534, 7794716, 22236231, 5989356, 25426474, 20976224, + 2350709, 30135921, 62420857, 2364225 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 612867287630009, 448212612103814, 571629077419196, + 1466796750919376, 1728478129663858 +#else + 16335033, 9132434, 25640582, 6678888, 1725628, 8517937, + 55301840, 21856974, 15445874, 25756331 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1723848973783452, 2208822520534681, 1718748322776940, + 1974268454121942, 1194212502258141 +#else + 29004188, 25687351, 28661401, 32914020, 54314860, 25611345, + 31863254, 29418892, 66830813, 17795152 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1254114807944608, 977770684047110, 2010756238954993, + 1783628927194099, 1525962994408256 +#else + 60986784, 18687766, 38493958, 14569918, 56250865, 29962602, + 10343411, 26578142, 37280576, 22738620 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 232464058235826, 1948628555342434, 1835348780427694, + 1031609499437291, 64472106918373 +#else + 27081650, 3463984, 14099042, 29036828, 1616302, 27348828, + 29542635, 15372179, 17293797, 960709 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 767338676040683, 754089548318405, 1523192045639075, + 435746025122062, 512692508440385 +#else + 20263915, 11434237, 61343429, 11236809, 13505955, 22697330, + 50997518, 6493121, 47724353, 7639713 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1255955808701983, 1700487367990941, 1166401238800299, + 1175121994891534, 1190934801395380 +#else + 64278047, 18715199, 25403037, 25339236, 58791851, 17380732, + 18006286, 17510682, 29994676, 17746311 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 349144008168292, 1337012557669162, 1475912332999108, + 1321618454900458, 47611291904320 +#else + 9769828, 5202651, 42951466, 19923039, 39057860, 21992807, + 42495722, 19693649, 35924288, 709463 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 877519947135419, 2172838026132651, 272304391224129, + 1655143327559984, 886229406429814 +#else + 12286395, 13076066, 45333675, 32377809, 42105665, 4057651, + 35090736, 24663557, 16102006, 13205847 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 375806028254706, 214463229793940, 572906353144089, + 572168269875638, 697556386112979 +#else + 13733362, 5599946, 10557076, 3195751, 61550873, 8536969, + 41568694, 8525971, 10151379, 10394400 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1168827102357844, 823864273033637, 2071538752104697, + 788062026895924, 599578340743362 +#else + 4024660, 17416881, 22436261, 12276534, 58009849, 30868332, + 19698228, 11743039, 33806530, 8934413 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1948116082078088, 2054898304487796, 2204939184983900, + 210526805152138, 786593586607626 +#else + 51229064, 29029191, 58528116, 30620370, 14634844, 32856154, + 57659786, 3137093, 55571978, 11721157 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1915320147894736, 156481169009469, 655050471180417, + 592917090415421, 2165897438660879 +#else + 17555920, 28540494, 8268605, 2331751, 44370049, 9761012, + 9319229, 8835153, 57903375, 32274386 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1726336468579724, 1119932070398949, 1929199510967666, + 33918788322959, 1836837863503150 +#else + 66647436, 25724417, 20614117, 16688288, 59594098, 28747312, + 22300303, 505429, 6108462, 27371017 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 829996854845988, 217061778005138, 1686565909803640, + 1346948817219846, 1723823550730181 +#else + 62038564, 12367916, 36445330, 3234472, 32617080, 25131790, + 29880582, 20071101, 40210373, 25686972 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 384301494966394, 687038900403062, 2211195391021739, + 254684538421383, 1245698430589680 +#else + 35133562, 5726538, 26934134, 10237677, 63935147, 32949378, + 24199303, 3795095, 7592688, 18562353 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1247567493562688, 1978182094455847, 183871474792955, + 806570235643435, 288461518067916 +#else + 21594432, 18590204, 17466407, 29477210, 32537083, 2739898, + 6407723, 12018833, 38852812, 4298411 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1449077384734201, 38285445457996, 2136537659177832, + 2146493000841573, 725161151123125 +#else + 46458361, 21592935, 39872588, 570497, 3767144, 31836892, + 13891941, 31985238, 13717173, 10805743 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1201928866368855, 800415690605445, 1703146756828343, + 997278587541744, 1858284414104014 +#else + 52432215, 17910135, 15287173, 11927123, 24177847, 25378864, + 66312432, 14860608, 40169934, 27690595 +#endif + }}, + }, + }, + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 356468809648877, 782373916933152, 1718002439402870, + 1392222252219254, 663171266061951 +#else + 12962541, 5311799, 57048096, 11658279, 18855286, 25600231, + 13286262, 20745728, 62727807, 9882021 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 759628738230460, 1012693474275852, 353780233086498, + 246080061387552, 2030378857679162 +#else + 18512060, 11319350, 46985740, 15090308, 18818594, 5271736, + 44380960, 3666878, 43141434, 30255002 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2040672435071076, 888593182036908, 1298443657189359, + 1804780278521327, 354070726137060 +#else + 60319844, 30408388, 16192428, 13241070, 15898607, 19348318, + 57023983, 26893321, 64705764, 5276064 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1894938527423184, 1463213041477277, 474410505497651, + 247294963033299, 877975941029128 +#else + 30169808, 28236784, 26306205, 21803573, 27814963, 7069267, + 7152851, 3684982, 1449224, 13082861 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 207937160991127, 12966911039119, 820997788283092, + 1010440472205286, 1701372890140810 +#else + 10342807, 3098505, 2119311, 193222, 25702612, 12233820, + 23697382, 15056736, 46092426, 25352431 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 218882774543183, 533427444716285, 1233243976733245, + 435054256891319, 1509568989549904 +#else + 33958735, 3261607, 22745853, 7948688, 19370557, 18376767, + 40936887, 6482813, 56808784, 22494330 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1888838535711826, 1052177758340622, 1213553803324135, + 169182009127332, 463374268115872 +#else + 32869458, 28145887, 25609742, 15678670, 56421095, 18083360, + 26112420, 2521008, 44444576, 6904814 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 299137589460312, 1594371588983567, 868058494039073, + 257771590636681, 1805012993142921 +#else + 29506904, 4457497, 3377935, 23757988, 36598817, 12935079, + 1561737, 3841096, 38105225, 26896789 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1806842755664364, 2098896946025095, 1356630998422878, + 1458279806348064, 347755825962072 +#else + 10340844, 26924055, 48452231, 31276001, 12621150, 20215377, + 30878496, 21730062, 41524312, 5181965 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1402334161391744, 1560083671046299, 1008585416617747, + 1147797150908892, 1420416683642459 +#else + 25940096, 20896407, 17324187, 23247058, 58437395, 15029093, + 24396252, 17103510, 64786011, 21165857 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 665506704253369, 273770475169863, 799236974202630, + 848328990077558, 1811448782807931 +#else + 45343161, 9916822, 65808455, 4079497, 66080518, 11909558, + 1782390, 12641087, 20603771, 26992690 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1468412523962641, 771866649897997, 1931766110147832, + 799561180078482, 524837559150077 +#else + 48226577, 21881051, 24849421, 11501709, 13161720, 28785558, + 1925522, 11914390, 4662781, 7820689 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2223212657821850, 630416247363666, 2144451165500328, + 816911130947791, 1024351058410032 +#else + 12241050, 33128450, 8132690, 9393934, 32846760, 31954812, + 29749455, 12172924, 16136752, 15264020 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1266603897524861, 156378408858100, 1275649024228779, + 447738405888420, 253186462063095 +#else + 56758909, 18873868, 58896884, 2330219, 49446315, 19008651, + 10658212, 6671822, 19012087, 3772772 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2022215964509735, 136144366993649, 1800716593296582, + 1193970603800203, 871675847064218 +#else + 3753511, 30133366, 10617073, 2028709, 14841030, 26832768, + 28718731, 17791548, 20527770, 12988982 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1862751661970328, 851596246739884, 1519315554814041, + 1542798466547449, 1417975335901520 +#else + 52286360, 27757162, 63400876, 12689772, 66209881, 22639565, + 42925817, 22989488, 3299664, 21129479 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1228168094547481, 334133883362894, 587567568420081, + 433612590281181, 603390400373205 +#else + 50331161, 18301130, 57466446, 4978982, 3308785, 8755439, + 6943197, 6461331, 41525717, 8991217 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 121893973206505, 1843345804916664, 1703118377384911, + 497810164760654, 101150811654673 +#else + 49882601, 1816361, 65435576, 27467992, 31783887, 25378441, + 34160718, 7417949, 36866577, 1507264 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 458346255946468, 290909935619344, 1452768413850679, + 550922875254215, 1537286854336538 +#else + 29692644, 6829891, 56610064, 4334895, 20945975, 21647936, + 38221255, 8209390, 14606362, 22907359 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 584322311184395, 380661238802118, 114839394528060, + 655082270500073, 2111856026034852 +#else + 63627275, 8707080, 32188102, 5672294, 22096700, 1711240, + 34088169, 9761486, 4170404, 31469107 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 996965581008991, 2148998626477022, 1012273164934654, + 1073876063914522, 1688031788934939 +#else + 55521375, 14855944, 62981086, 32022574, 40459774, 15084045, + 22186522, 16002000, 52832027, 25153633 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 923487018849600, 2085106799623355, 528082801620136, + 1606206360876188, 735907091712524 +#else + 62297408, 13761028, 35404987, 31070512, 63796392, 7869046, + 59995292, 23934339, 13240844, 10965870 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1697697887804317, 1335343703828273, 831288615207040, + 949416685250051, 288760277392022 +#else + 59366301, 25297669, 52340529, 19898171, 43876480, 12387165, + 4498947, 14147411, 29514390, 4302863 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1419122478109648, 1325574567803701, 602393874111094, + 2107893372601700, 1314159682671307 +#else + 53695440, 21146572, 20757301, 19752600, 14785142, 8976368, + 62047588, 31410058, 17846987, 19582505 +#endif + }}, + }, + }, + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2201150872731804, 2180241023425241, 97663456423163, + 1633405770247824, 848945042443986 +#else + 64864412, 32799703, 62511833, 32488122, 60861691, 1455298, + 45461136, 24339642, 61886162, 12650266 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1173339555550611, 818605084277583, 47521504364289, + 924108720564965, 735423405754506 +#else + 57202067, 17484121, 21134159, 12198166, 40044289, 708125, + 387813, 13770293, 47974538, 10958662 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 830104860549448, 1886653193241086, 1600929509383773, + 1475051275443631, 286679780900937 +#else + 22470984, 12369526, 23446014, 28113323, 45588061, 23855708, + 55336367, 21979976, 42025033, 4271861 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1577111294832995, 1030899169768747, 144900916293530, + 1964672592979567, 568390100955250 +#else + 41939299, 23500789, 47199531, 15361594, 61124506, 2159191, + 75375, 29275903, 34582642, 8469672 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 278388655910247, 487143369099838, 927762205508727, + 181017540174210, 1616886700741287 +#else + 15854951, 4148314, 58214974, 7259001, 11666551, 13824734, + 36577666, 2697371, 24154791, 24093489 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1191033906638969, 940823957346562, 1606870843663445, + 861684761499847, 658674867251089 +#else + 15446137, 17747788, 29759746, 14019369, 30811221, 23944241, + 35526855, 12840103, 24913809, 9815020 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1875032594195546, 1427106132796197, 724736390962158, + 901860512044740, 635268497268760 +#else + 62399578, 27940162, 35267365, 21265538, 52665326, 10799413, + 58005188, 13438768, 18735128, 9466238 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 622869792298357, 1903919278950367, 1922588621661629, + 1520574711600434, 1087100760174640 +#else + 11933045, 9281483, 5081055, 28370608, 64480701, 28648802, + 59381042, 22658328, 44380208, 16199063 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 25465949416618, 1693639527318811, 1526153382657203, + 125943137857169, 145276964043999 +#else + 14576810, 379472, 40322331, 25237195, 37682355, 22741457, + 67006097, 1876698, 30801119, 2164795 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 214739857969358, 920212862967915, 1939901550972269, + 1211862791775221, 85097515720120 +#else + 15995086, 3199873, 13672555, 13712240, 47730029, 28906785, + 54027253, 18058162, 53616056, 1268051 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2006245852772938, 734762734836159, 254642929763427, + 1406213292755966, 239303749517686 +#else + 56818250, 29895392, 63822271, 10948817, 23037027, 3794475, + 63638526, 20954210, 50053494, 3565903 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1619678837192149, 1919424032779215, 1357391272956794, + 1525634040073113, 1310226789796241 +#else + 29210069, 24135095, 61189071, 28601646, 10834810, 20226706, + 50596761, 22733718, 39946641, 19523900 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1040763709762123, 1704449869235352, 605263070456329, + 1998838089036355, 1312142911487502 +#else + 53946955, 15508587, 16663704, 25398282, 38758921, 9019122, + 37925443, 29785008, 2244110, 19552453 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1996723311435669, 1844342766567060, 985455700466044, + 1165924681400960, 311508689870129 +#else + 61955989, 29753495, 57802388, 27482848, 16243068, 14684434, + 41435776, 17373631, 13491505, 4641841 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 43173156290518, 2202883069785309, 1137787467085917, + 1733636061944606, 1394992037553852 +#else + 10813398, 643330, 47920349, 32825515, 30292061, 16954354, + 27548446, 25833190, 14476988, 20787001 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 670078326344559, 555655025059356, 471959386282438, + 2141455487356409, 849015953823125 +#else + 10292079, 9984945, 6481436, 8279905, 59857350, 7032742, + 27282937, 31910173, 39196053, 12651323 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2197214573372804, 794254097241315, 1030190060513737, + 267632515541902, 2040478049202624 +#else + 35923332, 32741048, 22271203, 11835308, 10201545, 15351028, + 17099662, 3988035, 21721536, 30405492 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1812516004670529, 1609256702920783, 1706897079364493, + 258549904773295, 996051247540686 +#else + 10202177, 27008593, 35735631, 23979793, 34958221, 25434748, + 54202543, 3852693, 13216206, 14842320 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1540374301420584, 1764656898914615, 1810104162020396, + 923808779163088, 664390074196579 +#else + 51293224, 22953365, 60569911, 26295436, 60124204, 26972653, + 35608016, 13765823, 39674467, 9900183 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1323460699404750, 1262690757880991, 871777133477900, + 1060078894988977, 1712236889662886 +#else + 14465486, 19721101, 34974879, 18815558, 39665676, 12990491, + 33046193, 15796406, 60056998, 25514317 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1696163952057966, 1391710137550823, 608793846867416, + 1034391509472039, 1780770894075012 +#else + 30924398, 25274812, 6359015, 20738097, 16508376, 9071735, + 41620263, 15413634, 9524356, 26535554 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1367603834210841, 2131988646583224, 890353773628144, + 1908908219165595, 270836895252891 +#else + 12274201, 20378885, 32627640, 31769106, 6736624, 13267305, + 5237659, 28444949, 15663515, 4035784 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 597536315471731, 40375058742586, 1942256403956049, + 1185484645495932, 312666282024145 +#else + 64157555, 8903984, 17349946, 601635, 50676049, 28941875, + 53376124, 17665097, 44850385, 4659090 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1919411405316294, 1234508526402192, 1066863051997083, + 1008444703737597, 1348810787701552 +#else + 50192582, 28601458, 36715152, 18395610, 20774811, 15897498, + 5736189, 15026997, 64930608, 20098846 +#endif + }}, + }, + }, + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2102881477513865, 1570274565945361, 1573617900503708, + 18662635732583, 2232324307922098 +#else + 58249865, 31335375, 28571665, 23398914, 66634396, 23448733, + 63307367, 278094, 23440562, 33264224 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1853931367696942, 8107973870707, 350214504129299, + 775206934582587, 1752317649166792 +#else + 10226222, 27625730, 15139955, 120818, 52241171, 5218602, + 32937275, 11551483, 50536904, 26111567 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1417148368003523, 721357181628282, 505725498207811, + 373232277872983, 261634707184480 +#else + 17932739, 21117156, 43069306, 10749059, 11316803, 7535897, + 22503767, 5561594, 63462240, 3898660 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2186733281493267, 2250694917008620, 1014829812957440, + 479998161452389, 83566193876474 +#else + 7749907, 32584865, 50769132, 33537967, 42090752, 15122142, + 65535333, 7152529, 21831162, 1245233 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1268116367301224, 560157088142809, 802626839600444, + 2210189936605713, 1129993785579988 +#else + 26958440, 18896406, 4314585, 8346991, 61431100, 11960071, + 34519569, 32934396, 36706772, 16838219 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 615183387352312, 917611676109240, 878893615973325, + 978940963313282, 938686890583575 +#else + 54942968, 9166946, 33491384, 13673479, 29787085, 13096535, + 6280834, 14587357, 44770839, 13987524 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 522024729211672, 1045059315315808, 1892245413707790, + 1907891107684253, 2059998109500714 +#else + 42758936, 7778774, 21116000, 15572597, 62275598, 28196653, + 62807965, 28429792, 59639082, 30696363 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1799679152208884, 912132775900387, 25967768040979, + 432130448590461, 274568990261996 +#else + 9681908, 26817309, 35157219, 13591837, 60225043, 386949, + 31622781, 6439245, 52527852, 4091396 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 98698809797682, 2144627600856209, 1907959298569602, + 811491302610148, 1262481774981493 +#else + 58682418, 1470726, 38999185, 31957441, 3978626, 28430809, + 47486180, 12092162, 29077877, 18812444 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1791451399743152, 1713538728337276, 118349997257490, + 1882306388849954, 158235232210248 +#else + 5269168, 26694706, 53878652, 25533716, 25932562, 1763552, + 61502754, 28048550, 47091016, 2357888 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1217809823321928, 2173947284933160, 1986927836272325, + 1388114931125539, 12686131160169 +#else + 32264008, 18146780, 61721128, 32394338, 65017541, 29607531, + 23104803, 20684524, 5727337, 189038 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1650875518872272, 1136263858253897, 1732115601395988, + 734312880662190, 1252904681142109 +#else + 14609104, 24599962, 61108297, 16931650, 52531476, 25810533, + 40363694, 10942114, 41219933, 18669734 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 372986456113865, 525430915458171, 2116279931702135, + 501422713587815, 1907002872974925 +#else + 20513481, 5557931, 51504251, 7829530, 26413943, 31535028, + 45729895, 7471780, 13913677, 28416557 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 803147181835288, 868941437997146, 316299302989663, + 943495589630550, 571224287904572 +#else + 41534488, 11967825, 29233242, 12948236, 60354399, 4713226, + 58167894, 14059179, 12878652, 8511905 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 227742695588364, 1776969298667369, 628602552821802, + 457210915378118, 2041906378111140 +#else + 41452044, 3393630, 64153449, 26478905, 64858154, 9366907, + 36885446, 6812973, 5568676, 30426776 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 815000523470260, 913085688728307, 1052060118271173, + 1345536665214223, 541623413135555 +#else + 11630004, 12144454, 2116339, 13606037, 27378885, 15676917, + 49700111, 20050058, 52713667, 8070817 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1580216071604333, 1877997504342444, 857147161260913, + 703522726778478, 2182763974211603 +#else + 27117677, 23547054, 35826092, 27984343, 1127281, 12772488, + 37262958, 10483305, 55556115, 32525717 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1870080310923419, 71988220958492, 1783225432016732, + 615915287105016, 1035570475990230 +#else + 10637467, 27866368, 5674780, 1072708, 40765276, 26572129, + 65424888, 9177852, 39615702, 15431202 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 730987750830150, 857613889540280, 1083813157271766, + 1002817255970169, 1719228484436074 +#else + 20525126, 10892566, 54366392, 12779442, 37615830, 16150074, + 38868345, 14943141, 52052074, 25618500 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 377616581647602, 1581980403078513, 804044118130621, + 2034382823044191, 643844048472185 +#else + 37084402, 5626925, 66557297, 23573344, 753597, 11981191, + 25244767, 30314666, 63752313, 9594023 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 176957326463017, 1573744060478586, 528642225008045, + 1816109618372371, 1515140189765006 +#else + 43356201, 2636869, 61944954, 23450613, 585133, 7877383, + 11345683, 27062142, 13352334, 22577348 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1888911448245718, 1387110895611080, 1924503794066429, + 1731539523700949, 2230378382645454 +#else + 65177046, 28146973, 3304648, 20669563, 17015805, 28677341, + 37325013, 25801949, 53893326, 33235227 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 443392177002051, 233793396845137, 2199506622312416, + 1011858706515937, 974676837063129 +#else + 20239939, 6607058, 6203985, 3483793, 48721888, 32775202, + 46385121, 15077869, 44358105, 14523816 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1846351103143623, 1949984838808427, 671247021915253, + 1946756846184401, 1929296930380217 +#else + 27406023, 27512775, 27423595, 29057038, 4996213, 10002360, + 38266833, 29008937, 36936121, 28748764 +#endif + }}, + }, + }, + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 849646212452002, 1410198775302919, 73767886183695, + 1641663456615812, 762256272452411 +#else + 11374242, 12660715, 17861383, 21013599, 10935567, 1099227, + 53222788, 24462691, 39381819, 11358503 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 692017667358279, 723305578826727, 1638042139863265, + 748219305990306, 334589200523901 +#else + 54378055, 10311866, 1510375, 10778093, 64989409, 24408729, + 32676002, 11149336, 40985213, 4985767 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 22893968530686, 2235758574399251, 1661465835630252, + 925707319443452, 1203475116966621 +#else + 48012542, 341146, 60911379, 33315398, 15756972, 24757770, + 66125820, 13794113, 47694557, 17933176 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 801299035785166, 1733292596726131, 1664508947088596, + 467749120991922, 1647498584535623 +#else + 6490062, 11940286, 25495923, 25828072, 8668372, 24803116, + 3367602, 6970005, 65417799, 24549641 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 903105258014366, 427141894933047, 561187017169777, + 1884330244401954, 1914145708422219 +#else + 1656478, 13457317, 15370807, 6364910, 13605745, 8362338, + 47934242, 28078708, 50312267, 28522993 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1344191060517578, 1960935031767890, 1518838929955259, + 1781502350597190, 1564784025565682 +#else + 44835530, 20030007, 67044178, 29220208, 48503227, 22632463, + 46537798, 26546453, 67009010, 23317098 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 673723351748086, 1979969272514923, 1175287312495508, + 1187589090978666, 1881897672213940 +#else + 17747446, 10039260, 19368299, 29503841, 46478228, 17513145, + 31992682, 17696456, 37848500, 28042460 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1917185587363432, 1098342571752737, 5935801044414, + 2000527662351839, 1538640296181569 +#else + 31932008, 28568291, 47496481, 16366579, 22023614, 88450, + 11371999, 29810185, 4882241, 22927527 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2495540013192, 678856913479236, 224998292422872, + 219635787698590, 1972465269000940 +#else + 29796488, 37186, 19818052, 10115756, 55279832, 3352735, + 18551198, 3272828, 61917932, 29392022 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 271413961212179, 1353052061471651, 344711291283483, + 2014925838520662, 2006221033113941 +#else + 12501267, 4044383, 58495907, 20162046, 34678811, 5136598, + 47878486, 30024734, 330069, 29895023 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 194583029968109, 514316781467765, 829677956235672, + 1676415686873082, 810104584395840 +#else + 6384877, 2899513, 17807477, 7663917, 64749976, 12363164, + 25366522, 24980540, 66837568, 12071498 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1980510813313589, 1948645276483975, 152063780665900, + 129968026417582, 256984195613935 +#else + 58743349, 29511910, 25133447, 29037077, 60897836, 2265926, + 34339246, 1936674, 61949167, 3829362 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1860190562533102, 1936576191345085, 461100292705964, + 1811043097042830, 957486749306835 +#else + 28425966, 27718999, 66531773, 28857233, 52891308, 6870929, + 7921550, 26986645, 26333139, 14267664 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 796664815624365, 1543160838872951, 1500897791837765, + 1667315977988401, 599303877030711 +#else + 56041645, 11871230, 27385719, 22994888, 62522949, 22365119, + 10004785, 24844944, 45347639, 8930323 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1151480509533204, 2136010406720455, 738796060240027, + 319298003765044, 1150614464349587 +#else + 45911060, 17158396, 25654215, 31829035, 12282011, 11008919, + 1541940, 4757911, 40617363, 17145491 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1731069268103150, 735642447616087, 1364750481334268, + 417232839982871, 927108269127661 +#else + 13537262, 25794942, 46504023, 10961926, 61186044, 20336366, + 53952279, 6217253, 51165165, 13814989 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1017222050227968, 1987716148359, 2234319589635701, + 621282683093392, 2132553131763026 +#else + 49686272, 15157789, 18705543, 29619, 24409717, 33293956, + 27361680, 9257833, 65152338, 31777517 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1567828528453324, 1017807205202360, 565295260895298, + 829541698429100, 307243822276582 +#else + 42063564, 23362465, 15366584, 15166509, 54003778, 8423555, + 37937324, 12361134, 48422886, 4578289 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 249079270936248, 1501514259790706, 947909724204848, + 944551802437487, 552658763982480 +#else + 24579768, 3711570, 1342322, 22374306, 40103728, 14124955, + 44564335, 14074918, 21964432, 8235257 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2089966982947227, 1854140343916181, 2151980759220007, + 2139781292261749, 158070445864917 +#else + 60580251, 31142934, 9442965, 27628844, 12025639, 32067012, + 64127349, 31885225, 13006805, 2355433 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1338766321464554, 1906702607371284, 1519569445519894, + 115384726262267, 1393058953390992 +#else + 50803946, 19949172, 60476436, 28412082, 16974358, 22643349, + 27202043, 1719366, 1141648, 20758196 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1364621558265400, 1512388234908357, 1926731583198686, + 2041482526432505, 920401122333774 +#else + 54244920, 20334445, 58790597, 22536340, 60298718, 28710537, + 13475065, 30420460, 32674894, 13715045 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1884844597333588, 601480070269079, 620203503079537, + 1079527400117915, 1202076693132015 +#else + 11423316, 28086373, 32344215, 8962751, 24989809, 9241752, + 53843611, 16086211, 38367983, 17912338 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 840922919763324, 727955812569642, 1303406629750194, + 522898432152867, 294161410441865 +#else + 65699196, 12530727, 60740138, 10847386, 19531186, 19422272, + 55399715, 7791793, 39862921, 4383346 +#endif + }}, + }, + }, + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 353760790835310, 1598361541848743, 1122905698202299, + 1922533590158905, 419107700666580 +#else + 38137966, 5271446, 65842855, 23817442, 54653627, 16732598, + 62246457, 28647982, 27193556, 6245191 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 359856369838236, 180914355488683, 861726472646627, + 218807937262986, 575626773232501 +#else + 51914908, 5362277, 65324971, 2695833, 4960227, 12840725, + 23061898, 3260492, 22510453, 8577507 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 755467689082474, 909202735047934, 730078068932500, + 936309075711518, 2007798262842972 +#else + 54476394, 11257345, 34415870, 13548176, 66387860, 10879010, + 31168030, 13952092, 37537372, 29918525 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1609384177904073, 362745185608627, 1335318541768201, + 800965770436248, 547877979267412 +#else + 3877321, 23981693, 32416691, 5405324, 56104457, 19897796, + 3759768, 11935320, 5611860, 8164018 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 984339177776787, 815727786505884, 1645154585713747, + 1659074964378553, 1686601651984156 +#else + 50833043, 14667796, 15906460, 12155291, 44997715, 24514713, + 32003001, 24722143, 5773084, 25132323 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1697863093781930, 599794399429786, 1104556219769607, + 830560774794755, 12812858601017 +#else + 43320746, 25300131, 1950874, 8937633, 18686727, 16459170, + 66203139, 12376319, 31632953, 190926 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1168737550514982, 897832437380552, 463140296333799, + 302564600022547, 2008360505135501 +#else + 42515238, 17415546, 58684872, 13378745, 14162407, 6901328, + 58820115, 4508563, 41767309, 29926903 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1856930662813910, 678090852002597, 1920179140755167, + 1259527833759868, 55540971895511 +#else + 8884438, 27670423, 6023973, 10104341, 60227295, 28612898, + 18722940, 18768427, 65436375, 827624 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1158643631044921, 476554103621892, 178447851439725, + 1305025542653569, 103433927680625 +#else + 34388281, 17265135, 34605316, 7101209, 13354605, 2659080, + 65308289, 19446395, 42230385, 1541285 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2176793111709008, 1576725716350391, 2009350167273523, + 2012390194631546, 2125297410909580 +#else + 2901328, 32436745, 3880375, 23495044, 49487923, 29941650, + 45306746, 29986950, 20456844, 31669399 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 825403285195098, 2144208587560784, 1925552004644643, + 1915177840006985, 1015952128947864 +#else + 27019610, 12299467, 53450576, 31951197, 54247203, 28692960, + 47568713, 28538373, 29439640, 15138866 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1807108316634472, 1534392066433717, 347342975407218, + 1153820745616376, 7375003497471 +#else + 21536104, 26928012, 34661045, 22864223, 44700786, 5175813, + 61688824, 17193268, 7779327, 109896 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 983061001799725, 431211889901241, 2201903782961093, + 817393911064341, 2214616493042167 +#else + 30279725, 14648750, 59063993, 6425557, 13639621, 32810923, + 28698389, 12180118, 23177719, 33000357 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 228567918409756, 865093958780220, 358083886450556, + 159617889659320, 1360637926292598 +#else + 26572828, 3405927, 35407164, 12890904, 47843196, 5335865, + 60615096, 2378491, 4439158, 20275085 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 234147501399755, 2229469128637390, 2175289352258889, + 1397401514549353, 1885288963089922 +#else + 44392139, 3489069, 57883598, 33221678, 18875721, 32414337, + 14819433, 20822905, 49391106, 28092994 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1111762412951562, 252849572507389, 1048714233823341, + 146111095601446, 1237505378776770 +#else + 62052362, 16566550, 15953661, 3767752, 56672365, 15627059, + 66287910, 2177224, 8550082, 18440267 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1113790697840279, 1051167139966244, 1045930658550944, + 2011366241542643, 1686166824620755 +#else + 48635543, 16596774, 66727204, 15663610, 22860960, 15585581, + 39264755, 29971692, 43848403, 25125843 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1054097349305049, 1872495070333352, 182121071220717, + 1064378906787311, 100273572924182 +#else + 34628313, 15707274, 58902952, 27902350, 29464557, 2713815, + 44383727, 15860481, 45206294, 1494192 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1306410853171605, 1627717417672447, 50983221088417, + 1109249951172250, 870201789081392 +#else + 47546773, 19467038, 41524991, 24254879, 13127841, 759709, + 21923482, 16529112, 8742704, 12967017 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 104233794644221, 1548919791188248, 2224541913267306, + 2054909377116478, 1043803389015153 +#else + 38643965, 1553204, 32536856, 23080703, 42417258, 33148257, + 58194238, 30620535, 37205105, 15553882 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 216762189468802, 707284285441622, 190678557969733, + 973969342604308, 1403009538434867 +#else + 21877890, 3230008, 9881174, 10539357, 62311749, 2841331, + 11543572, 14513274, 19375923, 20906471 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1279024291038477, 344776835218310, 273722096017199, + 1834200436811442, 634517197663804 +#else + 8832269, 19058947, 13253510, 5137575, 5037871, 4078777, + 24880818, 27331716, 2862652, 9455043 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 343805853118335, 1302216857414201, 566872543223541, + 2051138939539004, 321428858384280 +#else + 29306751, 5123106, 20245049, 19404543, 9592565, 8447059, + 65031740, 30564351, 15511448, 4789663 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 470067171324852, 1618629234173951, 2000092177515639, + 7307679772789, 1117521120249968 +#else + 46429108, 7004546, 8824831, 24119455, 63063159, 29803695, + 61354101, 108892, 23513200, 16652362 +#endif + }}, + }, + }, + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 278151578291475, 1810282338562947, 1771599529530998, + 1383659409671631, 685373414471841 +#else + 33852691, 4144781, 62632835, 26975308, 10770038, 26398890, + 60458447, 20618131, 48789665, 10212859 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 577009397403102, 1791440261786291, 2177643735971638, + 174546149911960, 1412505077782326 +#else + 2756062, 8598110, 7383731, 26694540, 22312758, 32449420, + 21179800, 2600940, 57120566, 21047965 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 893719721537457, 1201282458018197, 1522349501711173, + 58011597740583, 1130406465887139 +#else + 42463153, 13317461, 36659605, 17900503, 21365573, 22684775, + 11344423, 864440, 64609187, 16844368 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 412607348255453, 1280455764199780, 2233277987330768, + 14180080401665, 331584698417165 +#else + 40676061, 6148328, 49924452, 19080277, 18782928, 33278435, + 44547329, 211299, 2719757, 4940997 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 262483770854550, 990511055108216, 526885552771698, + 571664396646158, 354086190278723 +#else + 65784982, 3911312, 60160120, 14759764, 37081714, 7851206, + 21690126, 8518463, 26699843, 5276295 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1820352417585487, 24495617171480, 1547899057533253, + 10041836186225, 480457105094042 +#else + 53958991, 27125364, 9396248, 365013, 24703301, 23065493, + 1321585, 149635, 51656090, 7159368 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2023310314989233, 637905337525881, 2106474638900687, + 557820711084072, 1687858215057826 +#else + 9987761, 30149673, 17507961, 9505530, 9731535, 31388918, + 22356008, 8312176, 22477218, 25151047 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1144168702609745, 604444390410187, 1544541121756138, + 1925315550126027, 626401428894002 +#else + 18155857, 17049442, 19744715, 9006923, 15154154, 23015456, + 24256459, 28689437, 44560690, 9334108 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1922168257351784, 2018674099908659, 1776454117494445, + 956539191509034, 36031129147635 +#else + 2986088, 28642539, 10776627, 30080588, 10620589, 26471229, + 45695018, 14253544, 44521715, 536905 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 544644538748041, 1039872944430374, 876750409130610, + 710657711326551, 1216952687484972 +#else + 4377737, 8115836, 24567078, 15495314, 11625074, 13064599, + 7390551, 10589625, 10838060, 18134008 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 58242421545916, 2035812695641843, 2118491866122923, + 1191684463816273, 46921517454099 +#else + 47766460, 867879, 9277171, 30335973, 52677291, 31567988, + 19295825, 17757482, 6378259, 699185 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 272268252444639, 1374166457774292, 2230115177009552, + 1053149803909880, 1354288411641016 +#else + 7895007, 4057113, 60027092, 20476675, 49222032, 33231305, + 66392824, 15693154, 62063800, 20180469 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1857910905368338, 1754729879288912, 885945464109877, + 1516096106802166, 1602902393369811 +#else + 59371282, 27685029, 52542544, 26147512, 11385653, 13201616, + 31730678, 22591592, 63190227, 23885106 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1193437069800958, 901107149704790, 999672920611411, + 477584824802207, 364239578697845 +#else + 10188286, 17783598, 59772502, 13427542, 22223443, 14896287, + 30743455, 7116568, 45322357, 5427592 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 886299989548838, 1538292895758047, 1590564179491896, + 1944527126709657, 837344427345298 +#else + 696102, 13206899, 27047647, 22922350, 15285304, 23701253, + 10798489, 28975712, 19236242, 12477404 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 754558365378305, 1712186480903618, 1703656826337531, + 750310918489786, 518996040250900 +#else + 55879425, 11243795, 50054594, 25513566, 66320635, 25386464, + 63211194, 11180503, 43939348, 7733643 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1309847803895382, 1462151862813074, 211370866671570, + 1544595152703681, 1027691798954090 +#else + 17800790, 19518253, 40108434, 21787760, 23887826, 3149671, + 23466177, 23016261, 10322026, 15313801 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 803217563745370, 1884799722343599, 1357706345069218, + 2244955901722095, 730869460037413 +#else + 26246234, 11968874, 32263343, 28085704, 6830754, 20231401, + 51314159, 33452449, 42659621, 10890803 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 689299471295966, 1831210565161071, 1375187341585438, + 1106284977546171, 1893781834054269 +#else + 35743198, 10271362, 54448239, 27287163, 16690206, 20491888, + 52126651, 16484930, 25180797, 28219548 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 696351368613042, 1494385251239250, 738037133616932, + 636385507851544, 927483222611406 +#else + 66522290, 10376443, 34522450, 22268075, 19801892, 10997610, + 2276632, 9482883, 316878, 13820577 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1949114198209333, 1104419699537997, 783495707664463, + 1747473107602770, 2002634765788641 +#else + 57226037, 29044064, 64993357, 16457135, 56008783, 11674995, + 30756178, 26039378, 30696929, 29841583 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1607325776830197, 530883941415333, 1451089452727895, + 1581691157083423, 496100432831154 +#else + 32988917, 23951020, 12499365, 7910787, 56491607, 21622917, + 59766047, 23569034, 34759346, 7392472 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1068900648804224, 2006891997072550, 1134049269345549, + 1638760646180091, 2055396084625778 +#else + 58253184, 15927860, 9866406, 29905021, 64711949, 16898650, + 36699387, 24419436, 25112946, 30627788 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2222475519314561, 1870703901472013, 1884051508440561, + 1344072275216753, 1318025677799069 +#else + 64604801, 33117465, 25621773, 27875660, 15085041, 28074555, + 42223985, 20028237, 5537437, 19640113 +#endif + }}, + }, + }, + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 155711679280656, 681100400509288, 389811735211209, + 2135723811340709, 408733211204125 +#else + 55883280, 2320284, 57524584, 10149186, 33664201, 5808647, + 52232613, 31824764, 31234589, 6090599 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 7813206966729, 194444201427550, 2071405409526507, + 1065605076176312, 1645486789731291 +#else + 57475529, 116425, 26083934, 2897444, 60744427, 30866345, 609720, + 15878753, 60138459, 24519663 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 16625790644959, 1647648827778410, 1579910185572704, + 436452271048548, 121070048451050 +#else + 39351007, 247743, 51914090, 24551880, 23288160, 23542496, + 43239268, 6503645, 20650474, 1804084 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1037263028552531, 568385780377829, 297953104144430, + 1558584511931211, 2238221839292471 +#else + 39519059, 15456423, 8972517, 8469608, 15640622, 4439847, + 3121995, 23224719, 27842615, 33352104 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 190565267697443, 672855706028058, 338796554369226, + 337687268493904, 853246848691734 +#else + 51801891, 2839643, 22530074, 10026331, 4602058, 5048462, + 28248656, 5031932, 55733782, 12714368 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1763863028400139, 766498079432444, 1321118624818005, + 69494294452268, 858786744165651 +#else + 20807691, 26283607, 29286140, 11421711, 39232341, 19686201, + 45881388, 1035545, 47375635, 12796919 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1292056768563024, 1456632109855638, 1100631247050184, + 1386133165675321, 1232898350193752 +#else + 12076880, 19253146, 58323862, 21705509, 42096072, 16400683, + 49517369, 20654993, 3480664, 18371617 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 366253102478259, 525676242508811, 1449610995265438, + 1183300845322183, 185960306491545 +#else + 34747315, 5457596, 28548107, 7833186, 7303070, 21600887, + 42745799, 17632556, 33734809, 2771024 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 28315355815982, 460422265558930, 1799675876678724, + 1969256312504498, 1051823843138725 +#else + 45719598, 421931, 26597266, 6860826, 22486084, 26817260, + 49971378, 29344205, 42556581, 15673396 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 156914999361983, 1606148405719949, 1665208410108430, + 317643278692271, 1383783705665320 +#else + 46924223, 2338215, 19788685, 23933476, 63107598, 24813538, + 46837679, 4733253, 3727144, 20619984 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 54684536365732, 2210010038536222, 1194984798155308, + 535239027773705, 1516355079301361 +#else + 6120100, 814863, 55314462, 32931715, 6812204, 17806661, 2019593, + 7975683, 31123697, 22595451 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1484387703771650, 198537510937949, 2186282186359116, + 617687444857508, 647477376402122 +#else + 30069250, 22119100, 30434653, 2958439, 18399564, 32578143, + 12296868, 9204260, 50676426, 9648164 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2147715541830533, 500032538445817, 646380016884826, + 352227855331122, 1488268620408052 +#else + 32705413, 32003455, 30705657, 7451065, 55303258, 9631812, + 3305266, 5248604, 41100532, 22176930 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 159386186465542, 1877626593362941, 618737197060512, + 1026674284330807, 1158121760792685 +#else + 17219846, 2375039, 35537917, 27978816, 47649184, 9219902, + 294711, 15298639, 2662509, 17257359 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1744544377739822, 1964054180355661, 1685781755873170, + 2169740670377448, 1286112621104591 +#else + 65935918, 25995736, 62742093, 29266687, 45762450, 25120105, + 32087528, 32331655, 32247247, 19164571 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 81977249784993, 1667943117713086, 1668983819634866, + 1605016835177615, 1353960708075544 +#else + 14312609, 1221556, 17395390, 24854289, 62163122, 24869796, + 38911119, 23916614, 51081240, 20175586 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1602253788689063, 439542044889886, 2220348297664483, + 657877410752869, 157451572512238 +#else + 65680039, 23875441, 57873182, 6549686, 59725795, 33085767, + 23046501, 9803137, 17597934, 2346211 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1029287186166717, 65860128430192, 525298368814832, + 1491902500801986, 1461064796385400 +#else + 18510781, 15337574, 26171504, 981392, 44867312, 7827555, + 43617730, 22231079, 3059832, 21771562 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 408216988729246, 2121095722306989, 913562102267595, + 1879708920318308, 241061448436731 +#else + 10141598, 6082907, 17829293, 31606789, 9830091, 13613136, + 41552228, 28009845, 33606651, 3592095 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1185483484383269, 1356339572588553, 584932367316448, + 102132779946470, 1792922621116791 +#else + 33114149, 17665080, 40583177, 20211034, 33076704, 8716171, + 1151462, 1521897, 66126199, 26716628 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1966196870701923, 2230044620318636, 1425982460745905, + 261167817826569, 46517743394330 +#else + 34169699, 29298616, 23947180, 33230254, 34035889, 21248794, + 50471177, 3891703, 26353178, 693168 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 107077591595359, 884959942172345, 27306869797400, + 2224911448949390, 964352058245223 +#else + 30374239, 1595580, 50224825, 13186930, 4600344, 406904, 9585294, + 33153764, 31375463, 14369965 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1730194207717538, 431790042319772, 1831515233279467, + 1372080552768581, 1074513929381760 +#else + 52738210, 25781902, 1510300, 6434173, 48324075, 27291703, + 32732229, 20445593, 17901440, 16011505 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1450880638731607, 1019861580989005, 1229729455116861, + 1174945729836143, 826083146840706 +#else + 18171223, 21619806, 54608461, 15197121, 56070717, 18324396, + 47936623, 17508055, 8764034, 12309598 +#endif + }}, + }, + }, + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1899935429242705, 1602068751520477, 940583196550370, + 82431069053859, 1540863155745696 +#else + 5975889, 28311244, 47649501, 23872684, 55567586, 14015781, + 43443107, 1228318, 17544096, 22960650 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2136688454840028, 2099509000964294, 1690800495246475, + 1217643678575476, 828720645084218 +#else + 5811932, 31839139, 3442886, 31285122, 48741515, 25194890, + 49064820, 18144304, 61543482, 12348899 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 765548025667841, 462473984016099, 998061409979798, + 546353034089527, 2212508972466858 +#else + 35709185, 11407554, 25755363, 6891399, 63851926, 14872273, + 42259511, 8141294, 56476330, 32968952 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 46575283771160, 892570971573071, 1281983193144090, + 1491520128287375, 75847005908304 +#else + 54433560, 694025, 62032719, 13300343, 14015258, 19103038, + 57410191, 22225381, 30944592, 1130208 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1801436127943107, 1734436817907890, 1268728090345068, + 167003097070711, 2233597765834956 +#else + 8247747, 26843490, 40546482, 25845122, 52706924, 18905521, + 4652151, 2488540, 23550156, 33283200 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1997562060465113, 1048700225534011, 7615603985628, + 1855310849546841, 2242557647635213 +#else + 17294297, 29765994, 7026747, 15626851, 22990044, 113481, + 2267737, 27646286, 66700045, 33416712 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1161017320376250, 492624580169043, 2169815802355237, + 976496781732542, 1770879511019629 +#else + 16091066, 17300506, 18599251, 7340678, 2137637, 32332775, + 63744702, 14550935, 3260525, 26388161 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1357044908364776, 729130645262438, 1762469072918979, + 1365633616878458, 181282906404941 +#else + 62198760, 20221544, 18550886, 10864893, 50649539, 26262835, + 44079994, 20349526, 54360141, 2701325 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1080413443139865, 1155205815510486, 1848782073549786, + 622566975152580, 124965574467971 +#else + 58534169, 16099414, 4629974, 17213908, 46322650, 27548999, + 57090500, 9276970, 11329923, 1862132 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1184526762066993, 247622751762817, 692129017206356, + 820018689412496, 2188697339828085 +#else + 14763057, 17650824, 36190593, 3689866, 3511892, 10313526, + 45157776, 12219230, 58070901, 32614131 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2020536369003019, 202261491735136, 1053169669150884, + 2056531979272544, 778165514694311 +#else + 8894987, 30108338, 6150752, 3013931, 301220, 15693451, 35127648, + 30644714, 51670695, 11595569 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 237404399610207, 1308324858405118, 1229680749538400, + 720131409105291, 1958958863624906 +#else + 15214943, 3537601, 40870142, 19495559, 4418656, 18323671, + 13947275, 10730794, 53619402, 29190761 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 515583508038846, 17656978857189, 1717918437373989, + 1568052070792483, 46975803123923 +#else + 64570558, 7682792, 32759013, 263109, 37124133, 25598979, + 44776739, 23365796, 977107, 699994 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 281527309158085, 36970532401524, 866906920877543, + 2222282602952734, 1289598729589882 +#else + 54642373, 4195083, 57897332, 550903, 51543527, 12917919, + 19118110, 33114591, 36574330, 19216518 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1278207464902042, 494742455008756, 1262082121427081, + 1577236621659884, 1888786707293291 +#else + 31788442, 19046775, 4799988, 7372237, 8808585, 18806489, + 9408236, 23502657, 12493931, 28145115 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 353042527954210, 1830056151907359, 1111731275799225, + 174960955838824, 404312815582675 +#else + 41428258, 5260743, 47873055, 27269961, 63412921, 16566086, + 27218280, 2607121, 29375955, 6024730 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2064251142068628, 1666421603389706, 1419271365315441, + 468767774902855, 191535130366583 +#else + 842132, 30759739, 62345482, 24831616, 26332017, 21148791, + 11831879, 6985184, 57168503, 2854095 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1716987058588002, 1859366439773457, 1767194234188234, + 64476199777924, 1117233614485261 +#else + 62261602, 25585100, 2516241, 27706719, 9695690, 26333246, + 16512644, 960770, 12121869, 16648078 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 984292135520292, 135138246951259, 2220652137473167, + 1722843421165029, 190482558012909 +#else + 51890212, 14667095, 53772635, 2013716, 30598287, 33090295, + 35603941, 25672367, 20237805, 2838411 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 298845952651262, 1166086588952562, 1179896526238434, + 1347812759398693, 1412945390096208 +#else + 47820798, 4453151, 15298546, 17376044, 22115042, 17581828, + 12544293, 20083975, 1068880, 21054527 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1143239552672925, 906436640714209, 2177000572812152, + 2075299936108548, 325186347798433 +#else + 57549981, 17035596, 33238497, 13506958, 30505848, 32439836, + 58621956, 30924378, 12521377, 4845654 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 721024854374772, 684487861263316, 1373438744094159, + 2193186935276995, 1387043709851261 +#else + 38910324, 10744107, 64150484, 10199663, 7759311, 20465832, + 3409347, 32681032, 60626557, 20668561 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 418098668140962, 715065997721283, 1471916138376055, + 2168570337288357, 937812682637044 +#else + 43547042, 6230155, 46726851, 10655313, 43068279, 21933259, + 10477733, 32314216, 63995636, 13974497 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1043584187226485, 2143395746619356, 2209558562919611, + 482427979307092, 847556718384018 +#else + 12966261, 15550616, 35069916, 31939085, 21025979, 32924988, + 5642324, 7188737, 18895762, 12629579 +#endif + }}, + }, + }, + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1248731221520759, 1465200936117687, 540803492710140, + 52978634680892, 261434490176109 +#else + 14741879, 18607545, 22177207, 21833195, 1279740, 8058600, + 11758140, 789443, 32195181, 3895677 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1057329623869501, 620334067429122, 461700859268034, + 2012481616501857, 297268569108938 +#else + 10758205, 15755439, 62598914, 9243697, 62229442, 6879878, + 64904289, 29988312, 58126794, 4429646 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1055352180870759, 1553151421852298, 1510903185371259, + 1470458349428097, 1226259419062731 +#else + 64654951, 15725972, 46672522, 23143759, 61304955, 22514211, + 59972993, 21911536, 18047435, 18272689 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1492988790301668, 790326625573331, 1190107028409745, + 1389394752159193, 1620408196604194 +#else + 41935844, 22247266, 29759955, 11776784, 44846481, 17733976, + 10993113, 20703595, 49488162, 24145963 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 47000654413729, 1004754424173864, 1868044813557703, + 173236934059409, 588771199737015 +#else + 21987233, 700364, 42603816, 14972007, 59334599, 27836036, + 32155025, 2581431, 37149879, 8773374 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 30498470091663, 1082245510489825, 576771653181956, + 806509986132686, 1317634017056939 +#else + 41540495, 454462, 53896929, 16126714, 25240068, 8594567, + 20656846, 12017935, 59234475, 19634276 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 420308055751555, 1493354863316002, 165206721528088, + 1884845694919786, 2065456951573059 +#else + 6028163, 6263078, 36097058, 22252721, 66289944, 2461771, + 35267690, 28086389, 65387075, 30777706 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1115636332012334, 1854340990964155, 83792697369514, + 1972177451994021, 457455116057587 +#else + 54829870, 16624276, 987579, 27631834, 32908202, 1248608, + 7719845, 29387734, 28408819, 6816612 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1698968457310898, 1435137169051090, 1083661677032510, + 938363267483709, 340103887207182 +#else + 56750770, 25316602, 19549650, 21385210, 22082622, 16147817, + 20613181, 13982702, 56769294, 5067942 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1995325341336574, 911500251774648, 164010755403692, + 855378419194762, 1573601397528842 +#else + 36602878, 29732664, 12074680, 13582412, 47230892, 2443950, + 47389578, 12746131, 5331210, 23448488 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 241719380661528, 310028521317150, 1215881323380194, + 1408214976493624, 2141142156467363 +#else + 30528792, 3601899, 65151774, 4619784, 39747042, 18118043, + 24180792, 20984038, 27679907, 31905504 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1315157046163473, 727368447885818, 1363466668108618, + 1668921439990361, 1398483384337907 +#else + 9402385, 19597367, 32834042, 10838634, 40528714, 20317236, + 26653273, 24868867, 22611443, 20839026 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 75029678299646, 1015388206460473, 1849729037055212, + 1939814616452984, 444404230394954 +#else + 22190590, 1118029, 22736441, 15130463, 36648172, 27563110, + 19189624, 28905490, 4854858, 6622139 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2053597130993710, 2024431685856332, 2233550957004860, + 2012407275509545, 872546993104440 +#else + 58798126, 30600981, 58846284, 30166382, 56707132, 33282502, + 13424425, 29987205, 26404408, 13001963 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1217269667678610, 599909351968693, 1390077048548598, + 1471879360694802, 739586172317596 +#else + 35867026, 18138731, 64114613, 8939345, 11562230, 20713762, + 41044498, 21932711, 51703708, 11020692 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1718318639380794, 1560510726633958, 904462881159922, + 1418028351780052, 94404349451937 +#else + 1866042, 25604943, 59210214, 23253421, 12483314, 13477547, + 3175636, 21130269, 28761761, 1406734 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2132502667405250, 214379346175414, 1502748313768060, + 1960071701057800, 1353971822643138 +#else + 66660290, 31776765, 13018550, 3194501, 57528444, 22392694, + 24760584, 29207344, 25577410, 20175752 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 319394212043702, 2127459436033571, 717646691535162, + 663366796076914, 318459064945314 +#else + 42818486, 4759344, 66418211, 31701615, 2066746, 10693769, + 37513074, 9884935, 57739938, 4745409 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 405989424923593, 1960452633787083, 667349034401665, + 1492674260767112, 1451061489880787 +#else + 57967561, 6049713, 47577803, 29213020, 35848065, 9944275, + 51646856, 22242579, 10931923, 21622501 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 947085906234007, 323284730494107, 1485778563977200, + 728576821512394, 901584347702286 +#else + 50547351, 14112679, 59096219, 4817317, 59068400, 22139825, + 44255434, 10856640, 46638094, 13434653 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1575783124125742, 2126210792434375, 1569430791264065, + 1402582372904727, 1891780248341114 +#else + 22759470, 23480998, 50342599, 31683009, 13637441, 23386341, + 1765143, 20900106, 28445306, 28189722 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 838432205560695, 1997703511451664, 1018791879907867, + 1662001808174331, 78328132957753 +#else + 29875063, 12493613, 2795536, 29768102, 1710619, 15181182, + 56913147, 24765756, 9074233, 1167180 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 739152638255629, 2074935399403557, 505483666745895, + 1611883356514088, 628654635394878 +#else + 40903181, 11014232, 57266213, 30918946, 40200743, 7532293, + 48391976, 24018933, 3843902, 9367684 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1822054032121349, 643057948186973, 7306757352712, + 577249257962099, 284735863382083 +#else + 56139269, 27150720, 9591133, 9582310, 11349256, 108879, + 16235123, 8601684, 66969667, 4242894 +#endif + }}, + }, + }, + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1366558556363930, 1448606567552086, 1478881020944768, + 165803179355898, 1115718458123498 +#else + 22092954, 20363309, 65066070, 21585919, 32186752, 22037044, + 60534522, 2470659, 39691498, 16625500 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 204146226972102, 1630511199034723, 2215235214174763, + 174665910283542, 956127674017216 +#else + 56051142, 3042015, 13770083, 24296510, 584235, 33009577, + 59338006, 2602724, 39757248, 14247412 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1562934578796716, 1070893489712745, 11324610642270, + 958989751581897, 2172552325473805 +#else + 6314156, 23289540, 34336361, 15957556, 56951134, 168749, + 58490057, 14290060, 27108877, 32373552 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1770564423056027, 735523631664565, 1326060113795289, + 1509650369341127, 65892421582684 +#else + 58522267, 26383465, 13241781, 10960156, 34117849, 19759835, + 33547975, 22495543, 39960412, 981873 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 623682558650637, 1337866509471512, 990313350206649, + 1314236615762469, 1164772974270275 +#else + 22833421, 9293594, 34459416, 19935764, 57971897, 14756818, + 44180005, 19583651, 56629059, 17356469 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 223256821462517, 723690150104139, 1000261663630601, + 933280913953265, 254872671543046 +#else + 59340277, 3326785, 38997067, 10783823, 19178761, 14905060, + 22680049, 13906969, 51175174, 3797898 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1969087237026041, 624795725447124, 1335555107635969, + 2069986355593023, 1712100149341902 +#else + 21721337, 29341686, 54902740, 9310181, 63226625, 19901321, + 23740223, 30845200, 20491982, 25512280 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1236103475266979, 1837885883267218, 1026072585230455, + 1025865513954973, 1801964901432134 +#else + 9209251, 18419377, 53852306, 27386633, 66377847, 15289672, + 25947805, 15286587, 30997318, 26851369 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1115241013365517, 1712251818829143, 2148864332502771, + 2096001471438138, 2235017246626125 +#else + 7392013, 16618386, 23946583, 25514540, 53843699, 32020573, + 52911418, 31232855, 17649997, 33304352 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1299268198601632, 2047148477845621, 2165648650132450, + 1612539282026145, 514197911628890 +#else + 57807776, 19360604, 30609525, 30504889, 41933794, 32270679, + 51867297, 24028707, 64875610, 7662145 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 118352772338543, 1067608711804704, 1434796676193498, + 1683240170548391, 230866769907437 +#else + 49550191, 1763593, 33994528, 15908609, 37067994, 21380136, + 7335079, 25082233, 63934189, 3440182 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1850689576796636, 1601590730430274, 1139674615958142, + 1954384401440257, 76039205311 +#else + 47219164, 27577423, 42997570, 23865561, 10799742, 16982475, + 40449, 29122597, 4862399, 1133 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1723387471374172, 997301467038410, 533927635123657, + 20928644693965, 1756575222802513 +#else + 34252636, 25680474, 61686474, 14860949, 50789833, 7956141, + 7258061, 311861, 36513873, 26175010 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2146711623855116, 503278928021499, 625853062251406, + 1109121378393107, 1033853809911861 +#else + 63335436, 31988495, 28985339, 7499440, 24445838, 9325937, + 29727763, 16527196, 18278453, 15405622 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 571005965509422, 2005213373292546, 1016697270349626, + 56607856974274, 914438579435146 +#else + 62726958, 8508651, 47210498, 29880007, 61124410, 15149969, + 53795266, 843522, 45233802, 13626196 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1346698876211176, 2076651707527589, 1084761571110205, + 265334478828406, 1068954492309671 +#else + 2281448, 20067377, 56193445, 30944521, 1879357, 16164207, + 56324982, 3953791, 13340839, 15928663 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1769967932677654, 1695893319756416, 1151863389675920, + 1781042784397689, 400287774418285 +#else + 31727126, 26374577, 48671360, 25270779, 2875792, 17164102, + 41838969, 26539605, 43656557, 5964752 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1851867764003121, 403841933237558, 820549523771987, + 761292590207581, 1743735048551143 +#else + 4100401, 27594980, 49929526, 6017713, 48403027, 12227140, + 40424029, 11344143, 2538215, 25983677 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 410915148140008, 2107072311871739, 1004367461876503, + 99684895396761, 1180818713503224 +#else + 57675240, 6123112, 11159803, 31397824, 30016279, 14966241, + 46633881, 1485420, 66479608, 17595569 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 285945406881439, 648174397347453, 1098403762631981, + 1366547441102991, 1505876883139217 +#else + 40304287, 4260918, 11851389, 9658551, 35091757, 16367491, + 46903439, 20363143, 11659921, 22439314 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 672095903120153, 1675918957959872, 636236529315028, + 1569297300327696, 2164144194785875 +#else + 26180377, 10015009, 36264640, 24973138, 5418196, 9480663, + 2231568, 23384352, 33100371, 32248261 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1902708175321798, 1035343530915438, 1178560808893263, + 301095684058146, 1280977479761118 +#else + 15121094, 28352561, 56718958, 15427820, 39598927, 17561924, + 21670946, 4486675, 61177054, 19088051 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1615357281742403, 404257611616381, 2160201349780978, + 1160947379188955, 1578038619549541 +#else + 16166467, 24070699, 56004733, 6023907, 35182066, 32189508, + 2340059, 17299464, 56373093, 23514607 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2013087639791217, 822734930507457, 1785668418619014, + 1668650702946164, 389450875221715 +#else + 28042865, 29997343, 54982337, 12259705, 63391366, 26608532, + 6766452, 24864833, 18036435, 5803270 +#endif + }}, + }, + }, + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 453918449698368, 106406819929001, 2072540975937135, + 308588860670238, 1304394580755385 +#else + 66291264, 6763911, 11803561, 1585585, 10958447, 30883267, + 23855390, 4598332, 60949433, 19436993 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1295082798350326, 2091844511495996, 1851348972587817, + 3375039684596, 789440738712837 +#else + 36077558, 19298237, 17332028, 31170912, 31312681, 27587249, + 696308, 50292, 47013125, 11763583 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2083069137186154, 848523102004566, 993982213589257, + 1405313299916317, 1532824818698468 +#else + 66514282, 31040148, 34874710, 12643979, 12650761, 14811489, + 665117, 20940800, 47335652, 22840869 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1495961298852430, 1397203457344779, 1774950217066942, + 139302743555696, 66603584342787 +#else + 30464590, 22291560, 62981387, 20819953, 19835326, 26448819, + 42712688, 2075772, 50088707, 992470 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1782411379088302, 1096724939964781, 27593390721418, + 542241850291353, 1540337798439873 +#else + 18357166, 26559999, 7766381, 16342475, 37783946, 411173, + 14578841, 8080033, 55534529, 22952821 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 693543956581437, 171507720360750, 1557908942697227, + 1074697073443438, 1104093109037196 +#else + 19598397, 10334610, 12555054, 2555664, 18821899, 23214652, + 21873262, 16014234, 26224780, 16452269 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 345288228393419, 1099643569747172, 134881908403743, + 1740551994106740, 248212179299770 +#else + 36884939, 5145195, 5944548, 16385966, 3976735, 2009897, + 55731060, 25936245, 46575034, 3698649 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 231429562203065, 1526290236421172, 2021375064026423, + 1520954495658041, 806337791525116 +#else + 14187449, 3448569, 56472628, 22743496, 44444983, 30120835, + 7268409, 22663988, 27394300, 12015369 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1079623667189886, 872403650198613, 766894200588288, + 2163700860774109, 2023464507911816 +#else + 19695742, 16087646, 28032085, 12999827, 6817792, 11427614, + 20244189, 32241655, 53849736, 30151970 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 854645372543796, 1936406001954827, 151460662541253, + 825325739271555, 1554306377287556 +#else + 30860084, 12735208, 65220619, 28854697, 50133957, 2256939, + 58942851, 12298311, 58558340, 23160969 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1497138821904622, 1044820250515590, 1742593886423484, + 1237204112746837, 849047450816987 +#else + 61389038, 22309106, 65198214, 15569034, 26642876, 25966672, + 61319509, 18435777, 62132699, 12651792 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 667962773375330, 1897271816877105, 1399712621683474, + 1143302161683099, 2081798441209593 +#else + 64260450, 9953420, 11531313, 28271553, 26895122, 20857343, + 53990043, 17036529, 9768697, 31021214 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 127147851567005, 1936114012888110, 1704424366552046, + 856674880716312, 716603621335359 +#else + 42389405, 1894650, 66821166, 28850346, 15348718, 25397902, + 32767512, 12765450, 4940095, 10678226 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1072409664800960, 2146937497077528, 1508780108920651, + 935767602384853, 1112800433544068 +#else + 18860224, 15980149, 48121624, 31991861, 40875851, 22482575, + 59264981, 13944023, 42736516, 16582018 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 333549023751292, 280219272863308, 2104176666454852, + 1036466864875785, 536135186520207 +#else + 51604604, 4970267, 37215820, 4175592, 46115652, 31354675, + 55404809, 15444559, 56105103, 7989036 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 373666279883137, 146457241530109, 304116267127857, + 416088749147715, 1258577131183391 +#else + 31490433, 5568061, 64696061, 2182382, 34772017, 4531685, + 35030595, 6200205, 47422751, 18754260 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1186115062588401, 2251609796968486, 1098944457878953, + 1153112761201374, 1791625503417267 +#else + 49800177, 17674491, 35586086, 33551600, 34221481, 16375548, + 8680158, 17182719, 28550067, 26697300 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1870078460219737, 2129630962183380, 852283639691142, + 292865602592851, 401904317342226 +#else + 38981977, 27866340, 16837844, 31733974, 60258182, 12700015, + 37068883, 4364037, 1155602, 5988841 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1361070124828035, 815664541425524, 1026798897364671, + 1951790935390647, 555874891834790 +#else + 21890435, 20281525, 54484852, 12154348, 59276991, 15300495, + 23148983, 29083951, 24618406, 8283181 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1546301003424277, 459094500062839, 1097668518375311, + 1780297770129643, 720763293687608 +#else + 33972757, 23041680, 9975415, 6841041, 35549071, 16356535, + 3070187, 26528504, 1466168, 10740210 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1212405311403990, 1536693382542438, 61028431067459, + 1863929423417129, 1223219538638038 +#else + 65599446, 18066246, 53605478, 22898515, 32799043, 909394, + 53169961, 27774712, 34944214, 18227391 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1294303766540260, 1183557465955093, 882271357233093, + 63854569425375, 2213283684565087 +#else + 3960804, 19286629, 39082773, 17636380, 47704005, 13146867, + 15567327, 951507, 63848543, 32980496 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 339050984211414, 601386726509773, 413735232134068, + 966191255137228, 1839475899458159 +#else + 24740822, 5052253, 37014733, 8961360, 25877428, 6165135, + 42740684, 14397371, 59728495, 27410326 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 235605972169408, 2174055643032978, 1538335001838863, + 1281866796917192, 1815940222628465 +#else + 38220480, 3510802, 39005586, 32395953, 55870735, 22922977, + 51667400, 19101303, 65483377, 27059617 +#endif + }}, + }, + }, + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1632352921721536, 1833328609514701, 2092779091951987, + 1923956201873226, 2210068022482919 +#else + 793280, 24323954, 8836301, 27318725, 39747955, 31184838, + 33152842, 28669181, 57202663, 32932579 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 35271216625062, 1712350667021807, 983664255668860, + 98571260373038, 1232645608559836 +#else + 5666214, 525582, 20782575, 25516013, 42570364, 14657739, + 16099374, 1468826, 60937436, 18367850 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1998172393429622, 1798947921427073, 784387737563581, + 1589352214827263, 1589861734168180 +#else + 62249590, 29775088, 64191105, 26806412, 7778749, 11688288, + 36704511, 23683193, 65549940, 23690785 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1733739258725305, 31715717059538, 201969945218860, + 992093044556990, 1194308773174556 +#else + 10896313, 25834728, 824274, 472601, 47648556, 3009586, 25248958, + 14783338, 36527388, 17796587 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 846415389605137, 746163495539180, 829658752826080, + 592067705956946, 957242537821393 +#else + 10566929, 12612572, 35164652, 11118702, 54475488, 12362878, + 21752402, 8822496, 24003793, 14264025 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1758148849754419, 619249044817679, 168089007997045, + 1371497636330523, 1867101418880350 +#else + 27713843, 26198459, 56100623, 9227529, 27050101, 2504721, + 23886875, 20436907, 13958494, 27821979 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 326633984209635, 261759506071016, 1700682323676193, + 1577907266349064, 1217647663383016 +#else + 43627235, 4867225, 39861736, 3900520, 29838369, 25342141, + 35219464, 23512650, 7340520, 18144364 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1714182387328607, 1477856482074168, 574895689942184, + 2159118410227270, 1555532449716575 +#else + 4646495, 25543308, 44342840, 22021777, 23184552, 8566613, + 31366726, 32173371, 52042079, 23179239 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 853828206885131, 998498946036955, 1835887550391235, + 207627336608048, 258363815956050 +#else + 49838347, 12723031, 50115803, 14878793, 21619651, 27356856, + 27584816, 3093888, 58265170, 3849920 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 141141474651677, 1236728744905256, 643101419899887, + 1646615130509173, 1208239602291765 +#else + 58043933, 2103171, 25561640, 18428694, 61869039, 9582957, + 32477045, 24536477, 5002293, 18004173 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1501663228068911, 1354879465566912, 1444432675498247, + 897812463852601, 855062598754348 +#else + 55051311, 22376525, 21115584, 20189277, 8808711, 21523724, + 16489529, 13378448, 41263148, 12741425 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 714380763546606, 1032824444965790, 1774073483745338, + 1063840874947367, 1738680636537158 +#else + 61162478, 10645102, 36197278, 15390283, 63821882, 26435754, + 24306471, 15852464, 28834118, 25908360 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1640635546696252, 633168953192112, 2212651044092396, + 30590958583852, 368515260889378 +#else + 49773116, 24447374, 42577584, 9434952, 58636780, 32971069, + 54018092, 455840, 20461858, 5491305 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1171650314802029, 1567085444565577, 1453660792008405, + 757914533009261, 1619511342778196 +#else + 13669229, 17458950, 54626889, 23351392, 52539093, 21661233, + 42112877, 11293806, 38520660, 24132599 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 420958967093237, 971103481109486, 2169549185607107, + 1301191633558497, 1661514101014240 +#else + 28497909, 6272777, 34085870, 14470569, 8906179, 32328802, + 18504673, 19389266, 29867744, 24758489 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 907123651818302, 1332556122804146, 1824055253424487, + 1367614217442959, 1982558335973172 +#else + 50901822, 13517195, 39309234, 19856633, 24009063, 27180541, + 60741263, 20379039, 22853428, 29542421 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1121533090144639, 1021251337022187, 110469995947421, + 1511059774758394, 2110035908131662 +#else + 24191359, 16712145, 53177067, 15217830, 14542237, 1646131, + 18603514, 22516545, 12876622, 31441985 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 303213233384524, 2061932261128138, 352862124777736, + 40828818670255, 249879468482660 +#else + 17902668, 4518229, 66697162, 30725184, 26878216, 5258055, + 54248111, 608396, 16031844, 3723494 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 856559257852200, 508517664949010, 1378193767894916, + 1723459126947129, 1962275756614521 +#else + 38476072, 12763727, 46662418, 7577503, 33001348, 20536687, + 17558841, 25681542, 23896953, 29240187 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1445691340537320, 40614383122127, 402104303144865, + 485134269878232, 1659439323587426 +#else + 47103464, 21542479, 31520463, 605201, 2543521, 5991821, + 64163800, 7229063, 57189218, 24727572 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 20057458979482, 1183363722525800, 2140003847237215, + 2053873950687614, 2112017736174909 +#else + 28816026, 298879, 38943848, 17633493, 19000927, 31888542, + 54428030, 30605106, 49057085, 31471516 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2228654250927986, 1483591363415267, 1368661293910956, + 1076511285177291, 526650682059608 +#else + 16000882, 33209536, 3493091, 22107234, 37604268, 20394642, + 12577739, 16041268, 47393624, 7847706 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 709481497028540, 531682216165724, 316963769431931, + 1814315888453765, 258560242424104 +#else + 10151868, 10572098, 27312476, 7922682, 14825339, 4723128, + 34252933, 27035413, 57088296, 3852847 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1053447823660455, 1955135194248683, 1010900954918985, + 1182614026976701, 1240051576966610 +#else + 55678375, 15697595, 45987307, 29133784, 5386313, 15063598, + 16514493, 17622322, 29330898, 18478208 +#endif + }}, + }, + }, + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1957943897155497, 1788667368028035, 137692910029106, + 1039519607062, 826404763313028 +#else + 41609129, 29175637, 51885955, 26653220, 16615730, 2051784, + 3303702, 15490, 39560068, 12314390 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1848942433095597, 1582009882530495, 1849292741020143, + 1068498323302788, 2001402229799484 +#else + 15683501, 27551389, 18109119, 23573784, 15337967, 27556609, + 50391428, 15921865, 16103996, 29823217 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1528282417624269, 2142492439828191, 2179662545816034, + 362568973150328, 1591374675250271 +#else + 43939021, 22773182, 13588191, 31925625, 63310306, 32479502, + 47835256, 5402698, 37293151, 23713330 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 160026679434388, 232341189218716, 2149181472355545, + 598041771119831, 183859001910173 +#else + 23190676, 2384583, 34394524, 3462153, 37205209, 32025299, + 55842007, 8911516, 41903005, 2739712 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2013278155187349, 662660471354454, 793981225706267, + 411706605985744, 804490933124791 +#else + 21374101, 30000182, 33584214, 9874410, 15377179, 11831242, + 33578960, 6134906, 4931255, 11987849 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2051892037280204, 488391251096321, 2230187337030708, + 930221970662692, 679002758255210 +#else + 67101132, 30575573, 50885377, 7277596, 105524, 33232381, + 35628324, 13861387, 37032554, 10117929 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1530723630438670, 875873929577927, 341560134269988, + 449903119530753, 1055551308214179 +#else + 37607694, 22809559, 40945095, 13051538, 41483300, 5089642, + 60783361, 6704078, 12890019, 15728940 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1461835919309432, 1955256480136428, 180866187813063, + 1551979252664528, 557743861963950 +#else + 45136504, 21783052, 66157804, 29135591, 14704839, 2695116, + 903376, 23126293, 12885166, 8311031 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 359179641731115, 1324915145732949, 902828372691474, + 294254275669987, 1887036027752957 +#else + 49592363, 5352193, 10384213, 19742774, 7506450, 13453191, + 26423267, 4384730, 1888765, 28119028 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2043271609454323, 2038225437857464, 1317528426475850, + 1398989128982787, 2027639881006861 +#else + 41291507, 30447119, 53614264, 30371925, 30896458, 19632703, + 34857219, 20846562, 47644429, 30214188 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2072902725256516, 312132452743412, 309930885642209, + 996244312618453, 1590501300352303 +#else + 43500868, 30888657, 66582772, 4651135, 5765089, 4618330, + 6092245, 14845197, 17151279, 23700316 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1397254305160710, 695734355138021, 2233992044438756, + 1776180593969996, 1085588199351115 +#else + 42278406, 20820711, 51942885, 10367249, 37577956, 33289075, + 22825804, 26467153, 50242379, 16176524 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 440567051331029, 254894786356681, 493869224930222, + 1556322069683366, 1567456540319218 +#else + 43525589, 6564960, 20063689, 3798228, 62368686, 7359224, + 2006182, 23191006, 38362610, 23356922 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1950722461391320, 1907845598854797, 1822757481635527, + 2121567704750244, 73811931471221 +#else + 56482264, 29068029, 53788301, 28429114, 3432135, 27161203, + 23632036, 31613822, 32808309, 1099883 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 387139307395758, 2058036430315676, 1220915649965325, + 1794832055328951, 1230009312169328 +#else + 15030958, 5768825, 39657628, 30667132, 60681485, 18193060, + 51830967, 26745081, 2051440, 18328567 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1765973779329517, 659344059446977, 19821901606666, + 1301928341311214, 1116266004075885 +#else + 63746541, 26315059, 7517889, 9824992, 23555850, 295369, 5148398, + 19400244, 44422509, 16633659 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1127572801181483, 1224743760571696, 1276219889847274, + 1529738721702581, 1589819666871853 +#else + 4577067, 16802144, 13249840, 18250104, 19958762, 19017158, + 18559669, 22794883, 8402477, 23690159 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2181229378964934, 2190885205260020, 1511536077659137, + 1246504208580490, 668883326494241 +#else + 38702534, 32502850, 40318708, 32646733, 49896449, 22523642, + 9453450, 18574360, 17983009, 9967138 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 437866655573314, 669026411194768, 81896997980338, + 523874406393178, 245052060935236 +#else + 41346370, 6524721, 26585488, 9969270, 24709298, 1220360, + 65430874, 7806336, 17507396, 3651560 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1975438052228868, 1071801519999806, 594652299224319, + 1877697652668809, 1489635366987285 +#else + 56688388, 29436320, 14584638, 15971087, 51340543, 8861009, + 26556809, 27979875, 48555541, 22197296 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 958592545673770, 233048016518599, 851568750216589, + 567703851596087, 1740300006094761 +#else + 2839082, 14284142, 4029895, 3472686, 14402957, 12689363, + 40466743, 8459446, 61503401, 25932490 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2014540178270324, 192672779514432, 213877182641530, + 2194819933853411, 1716422829364835 +#else + 62269556, 30018987, 9744960, 2871048, 25113978, 3187018, + 41998051, 32705365, 17258083, 25576693 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1540769606609725, 2148289943846077, 1597804156127445, + 1230603716683868, 815423458809453 +#else + 18164541, 22959256, 49953981, 32012014, 19237077, 23809137, + 23357532, 18337424, 26908269, 12150756 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1738560251245018, 1779576754536888, 1783765347671392, + 1880170990446751, 1088225159617541 +#else + 36843994, 25906566, 5112248, 26517760, 65609056, 26580174, + 43167, 28016731, 34806789, 16215818 +#endif + }}, + }, + }, + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 659303913929492, 1956447718227573, 1830568515922666, + 841069049744408, 1669607124206368 +#else + 60209940, 9824393, 54804085, 29153342, 35711722, 27277596, + 32574488, 12532905, 59605792, 24879084 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1143465490433355, 1532194726196059, 1093276745494697, + 481041706116088, 2121405433561163 +#else + 39765323, 17038963, 39957339, 22831480, 946345, 16291093, + 254968, 7168080, 21676107, 31611404 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1686424298744462, 1451806974487153, 266296068846582, + 1834686947542675, 1720762336132256 +#else + 21260942, 25129680, 50276977, 21633609, 43430902, 3968120, + 63456915, 27338965, 63552672, 25641356 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 889217026388959, 1043290623284660, 856125087551909, + 1669272323124636, 1603340330827879 +#else + 16544735, 13250366, 50304436, 15546241, 62525861, 12757257, + 64646556, 24874095, 48201831, 23891632 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1206396181488998, 333158148435054, 1402633492821422, + 1120091191722026, 1945474114550509 +#else + 64693606, 17976703, 18312302, 4964443, 51836334, 20900867, + 26820650, 16690659, 25459437, 28989823 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 766720088232571, 1512222781191002, 1189719893490790, + 2091302129467914, 2141418006894941 +#else + 41964155, 11425019, 28423002, 22533875, 60963942, 17728207, + 9142794, 31162830, 60676445, 31909614 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 419663647306612, 1998875112167987, 1426599870253707, + 1154928355379510, 486538532138187 +#else + 44004212, 6253475, 16964147, 29785560, 41994891, 21257994, + 39651638, 17209773, 6335691, 7249989 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 938160078005954, 1421776319053174, 1941643234741774, + 180002183320818, 1414380336750546 +#else + 36775618, 13979674, 7503222, 21186118, 55152142, 28932738, + 36836594, 2682241, 25993170, 21075909 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 398001940109652, 1577721237663248, 1012748649830402, + 1540516006905144, 1011684812884559 +#else + 4364628, 5930691, 32304656, 23509878, 59054082, 15091130, + 22857016, 22955477, 31820367, 15075278 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1653276489969630, 6081825167624, 1921777941170836, + 1604139841794531, 861211053640641 +#else + 31879134, 24635739, 17258760, 90626, 59067028, 28636722, + 24162787, 23903546, 49138625, 12833044 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 996661541407379, 1455877387952927, 744312806857277, + 139213896196746, 1000282908547789 +#else + 19073683, 14851414, 42705695, 21694263, 7625277, 11091125, + 47489674, 2074448, 57694925, 14905376 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1450817495603008, 1476865707053229, 1030490562252053, + 620966950353376, 1744760161539058 +#else + 24483648, 21618865, 64589997, 22007013, 65555733, 15355505, + 41826784, 9253128, 27628530, 25998952 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 559728410002599, 37056661641185, 2038622963352006, + 1637244893271723, 1026565352238948 +#else + 17597607, 8340603, 19355617, 552187, 26198470, 30377849, + 4593323, 24396850, 52997988, 15297015 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 962165956135846, 1116599660248791, 182090178006815, + 1455605467021751, 196053588803284 +#else + 510886, 14337390, 35323607, 16638631, 6328095, 2713355, + 46891447, 21690211, 8683220, 2921426 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 796863823080135, 1897365583584155, 420466939481601, + 2165972651724672, 932177357788289 +#else + 18606791, 11874196, 27155355, 28272950, 43077121, 6265445, + 41930624, 32275507, 4674689, 13890525 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 877047233620632, 1375632631944375, 643773611882121, + 660022738847877, 19353932331831 +#else + 13609624, 13069022, 39736503, 20498523, 24360585, 9592974, + 14977157, 9835105, 4389687, 288396 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2216943882299338, 394841323190322, 2222656898319671, + 558186553950529, 1077236877025190 +#else + 9922506, 33035038, 13613106, 5883594, 48350519, 33120168, + 54804801, 8317627, 23388070, 16052080 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 801118384953213, 1914330175515892, 574541023311511, + 1471123787903705, 1526158900256288 +#else + 12719997, 11937594, 35138804, 28525742, 26900119, 8561328, + 46953177, 21921452, 52354592, 22741539 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 949617889087234, 2207116611267331, 912920039141287, + 501158539198789, 62362560771472 +#else + 15961858, 14150409, 26716931, 32888600, 44314535, 13603568, + 11829573, 7467844, 38286736, 929274 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1474518386765335, 1760793622169197, 1157399790472736, + 1622864308058898, 165428294422792 +#else + 11038231, 21972036, 39798381, 26237869, 56610336, 17246600, + 43629330, 24182562, 45715720, 2465073 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1961673048027128, 102619413083113, 1051982726768458, + 1603657989805485, 1941613251499678 +#else + 20017144, 29231206, 27915241, 1529148, 12396362, 15675764, + 13817261, 23896366, 2463390, 28932292 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1401939116319266, 335306339903072, 72046196085786, + 862423201496006, 850518754531384 +#else + 50749986, 20890520, 55043680, 4996453, 65852442, 1073571, + 9583558, 12851107, 4003896, 12673717 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1234706593321979, 1083343891215917, 898273974314935, + 1640859118399498, 157578398571149 +#else + 65377275, 18398561, 63845933, 16143081, 19294135, 13385325, + 14741514, 24450706, 7903885, 2348101 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1143483057726416, 1992614991758919, 674268662140796, + 1773370048077526, 674318359920189 +#else + 24536016, 17039225, 12715591, 29692277, 1511292, 10047386, + 63266518, 26425272, 38731325, 10048126 +#endif + }}, + }, + }, + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1835401379538542, 173900035308392, 818247630716732, + 1762100412152786, 1021506399448291 +#else + 54486638, 27349611, 30718824, 2591312, 56491836, 12192839, + 18873298, 26257342, 34811107, 15221631 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1506632088156630, 2127481795522179, 513812919490255, + 140643715928370, 442476620300318 +#else + 40630742, 22450567, 11546243, 31701949, 9180879, 7656409, + 45764914, 2095754, 29769758, 6593415 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2056683376856736, 219094741662735, 2193541883188309, + 1841182310235800, 556477468664293 +#else + 35114656, 30646970, 4176911, 3264766, 12538965, 32686321, + 26312344, 27435754, 30958053, 8292160 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1315019427910827, 1049075855992603, 2066573052986543, + 266904467185534, 2040482348591520 +#else + 31429803, 19595316, 29173531, 15632448, 12174511, 30794338, + 32808830, 3977186, 26143136, 30405556 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 94096246544434, 922482381166992, 24517828745563, + 2139430508542503, 2097139044231004 +#else + 22648882, 1402143, 44308880, 13746058, 7936347, 365344, + 58440231, 31879998, 63350620, 31249806 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 537697207950515, 1399352016347350, 1563663552106345, + 2148749520888918, 549922092988516 +#else + 51616947, 8012312, 64594134, 20851969, 43143017, 23300402, + 65496150, 32018862, 50444388, 8194477 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1747985413252434, 680511052635695, 1809559829982725, + 594274250930054, 201673170745982 +#else + 27338066, 26047012, 59694639, 10140404, 48082437, 26964542, + 27277190, 8855376, 28572286, 3005164 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 323583936109569, 1973572998577657, 1192219029966558, + 79354804385273, 1374043025560347 +#else + 26287105, 4821776, 25476601, 29408529, 63344350, 17765447, + 49100281, 1182478, 41014043, 20474836 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 213277331329947, 416202017849623, 1950535221091783, + 1313441578103244, 2171386783823658 +#else + 59937691, 3178079, 23970071, 6201893, 49913287, 29065239, + 45232588, 19571804, 32208682, 32356184 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 189088804229831, 993969372859110, 895870121536987, + 1547301535298256, 1477373024911350 +#else + 50451143, 2817642, 56822502, 14811297, 6024667, 13349505, + 39793360, 23056589, 39436278, 22014573 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1620578418245010, 541035331188469, 2235785724453865, + 2154865809088198, 1974627268751826 +#else + 15941010, 24148500, 45741813, 8062054, 31876073, 33315803, + 51830470, 32110002, 15397330, 29424239 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1346805451740245, 1350981335690626, 942744349501813, + 2155094562545502, 1012483751693409 +#else + 8934485, 20068965, 43822466, 20131190, 34662773, 14047985, + 31170398, 32113411, 39603297, 15087183 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2107080134091762, 1132567062788208, 1824935377687210, + 769194804343737, 1857941799971888 +#else + 48751602, 31397940, 24524912, 16876564, 15520426, 27193656, + 51606457, 11461895, 16788528, 27685490 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1074666112436467, 249279386739593, 1174337926625354, + 1559013532006480, 1472287775519121 +#else + 65161459, 16013772, 21750665, 3714552, 49707082, 17498998, + 63338576, 23231111, 31322513, 21938797 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1872620123779532, 1892932666768992, 1921559078394978, + 1270573311796160, 1438913646755037 +#else + 21426636, 27904214, 53460576, 28206894, 38296674, 28633461, + 48833472, 18933017, 13040861, 21441484 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 837390187648199, 1012253300223599, 989780015893987, + 1351393287739814, 328627746545550 +#else + 11293895, 12478086, 39972463, 15083749, 37801443, 14748871, + 14555558, 20137329, 1613710, 4896935 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1028328827183114, 1711043289969857, 1350832470374933, + 1923164689604327, 1495656368846911 +#else + 41213962, 15323293, 58619073, 25496531, 25967125, 20128972, + 2825959, 28657387, 43137087, 22287016 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1900828492104143, 430212361082163, 687437570852799, + 832514536673512, 1685641495940794 +#else + 51184079, 28324551, 49665331, 6410663, 3622847, 10243618, + 20615400, 12405433, 43355834, 25118015 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 842632847936398, 605670026766216, 290836444839585, + 163210774892356, 2213815011799645 +#else + 60017550, 12556207, 46917512, 9025186, 50036385, 4333800, + 4378436, 2432030, 23097949, 32988414 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1176336383453996, 1725477294339771, 12700622672454, + 678015708818208, 162724078519879 +#else + 4565804, 17528778, 20084411, 25711615, 1724998, 189254, + 24767264, 10103221, 48596551, 2424777 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1448049969043497, 1789411762943521, 385587766217753, + 90201620913498, 832999441066823 +#else + 366633, 21577626, 8173089, 26664313, 30788633, 5745705, + 59940186, 1344108, 63466311, 12412658 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 516086333293313, 2240508292484616, 1351669528166508, + 1223255565316488, 750235824427138 +#else + 43107073, 7690285, 14929416, 33386175, 34898028, 20141445, + 24162696, 18227928, 63967362, 11179384 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1263624896582495, 1102602401673328, 526302183714372, + 2152015839128799, 1483839308490010 +#else + 18289503, 18829478, 8056944, 16430056, 45379140, 7842513, + 61107423, 32067534, 48424218, 22110928 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 442991718646863, 1599275157036458, 1925389027579192, + 899514691371390, 350263251085160 +#else + 476239, 6601091, 60956074, 23831056, 17503544, 28690532, + 27672958, 13403813, 11052904, 5219329 +#endif + }}, + }, + }, + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1689713572022143, 593854559254373, 978095044791970, + 1985127338729499, 1676069120347625 +#else + 20678527, 25178694, 34436965, 8849122, 62099106, 14574751, + 31186971, 29580702, 9014761, 24975376 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1557207018622683, 340631692799603, 1477725909476187, + 614735951619419, 2033237123746766 +#else + 53464795, 23204192, 51146355, 5075807, 65594203, 22019831, + 34006363, 9160279, 8473550, 30297594 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 968764929340557, 1225534776710944, 662967304013036, + 1155521416178595, 791142883466590 +#else + 24900749, 14435722, 17209120, 18261891, 44516588, 9878982, + 59419555, 17218610, 42540382, 11788947 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1487081286167458, 993039441814934, 1792378982844640, + 698652444999874, 2153908693179754 +#else + 63990690, 22159237, 53306774, 14797440, 9652448, 26708528, + 47071426, 10410732, 42540394, 32095740 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1123181311102823, 685575944875442, 507605465509927, + 1412590462117473, 568017325228626 +#else + 51449703, 16736705, 44641714, 10215877, 58011687, 7563910, + 11871841, 21049238, 48595538, 8464117 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 560258797465417, 2193971151466401, 1824086900849026, + 579056363542056, 1690063960036441 +#else + 43708233, 8348506, 52522913, 32692717, 63158658, 27181012, + 14325288, 8628612, 33313881, 25183915 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1918407319222416, 353767553059963, 1930426334528099, + 1564816146005724, 1861342381708096 +#else + 46921872, 28586496, 22367355, 5271547, 66011747, 28765593, + 42303196, 23317577, 58168128, 27736162 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2131325168777276, 1176636658428908, 1756922641512981, + 1390243617176012, 1966325177038383 +#else + 60160060, 31759219, 34483180, 17533252, 32635413, 26180187, + 15989196, 20716244, 28358191, 29300528 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2063958120364491, 2140267332393533, 699896251574968, + 273268351312140, 375580724713232 +#else + 43547083, 30755372, 34757181, 31892468, 57961144, 10429266, + 50471180, 4072015, 61757200, 5596588 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2024297515263178, 416959329722687, 1079014235017302, + 171612225573183, 1031677520051053 +#else + 38872266, 30164383, 12312895, 6213178, 3117142, 16078565, + 29266239, 2557221, 1768301, 15373193 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2033900009388450, 1744902869870788, 2190580087917640, + 1949474984254121, 231049754293748 +#else + 59865506, 30307471, 62515396, 26001078, 66980936, 32642186, + 66017961, 29049440, 42448372, 3442909 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 343868674606581, 550155864008088, 1450580864229630, + 481603765195050, 896972360018042 +#else + 36898293, 5124042, 14181784, 8197961, 18964734, 21615339, + 22597930, 7176455, 48523386, 13365929 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2151139328380127, 314745882084928, 59756825775204, + 1676664391494651, 2048348075599360 +#else + 59231455, 32054473, 8324672, 4690079, 6261860, 890446, 24538107, + 24984246, 57419264, 30522764 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1528930066340597, 1605003907059576, 1055061081337675, + 1458319101947665, 1234195845213142 +#else + 25008885, 22782833, 62803832, 23916421, 16265035, 15721635, + 683793, 21730648, 15723478, 18390951 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 830430507734812, 1780282976102377, 1425386760709037, + 362399353095425, 2168861579799910 +#else + 57448220, 12374378, 40101865, 26528283, 59384749, 21239917, + 11879681, 5400171, 519526, 32318556 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1155762232730333, 980662895504006, 2053766700883521, + 490966214077606, 510405877041357 +#else + 22258397, 17222199, 59239046, 14613015, 44588609, 30603508, + 46754982, 7315966, 16648397, 7605640 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1683750316716132, 652278688286128, 1221798761193539, + 1897360681476669, 319658166027343 +#else + 59027556, 25089834, 58885552, 9719709, 19259459, 18206220, + 23994941, 28272877, 57640015, 4763277 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 618808732869972, 72755186759744, 2060379135624181, + 1730731526741822, 48862757828238 +#else + 45409620, 9220968, 51378240, 1084136, 41632757, 30702041, + 31088446, 25789909, 55752334, 728111 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1463171970593505, 1143040711767452, 614590986558883, + 1409210575145591, 1882816996436803 +#else + 26047201, 21802961, 60208540, 17032633, 24092067, 9158119, + 62835319, 20998873, 37743427, 28056159 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2230133264691131, 563950955091024, 2042915975426398, + 827314356293472, 672028980152815 +#else + 17510331, 33231575, 5854288, 8403524, 17133918, 30441820, + 38997856, 12327944, 10750447, 10014012 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 264204366029760, 1654686424479449, 2185050199932931, + 2207056159091748, 506015669043634 +#else + 56796096, 3936951, 9156313, 24656749, 16498691, 32559785, + 39627812, 32887699, 3424690, 7540221 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1784446333136569, 1973746527984364, 334856327359575, + 1156769775884610, 1023950124675478 +#else + 30322361, 26590322, 11361004, 29411115, 7433303, 4989748, + 60037442, 17237212, 57864598, 15258045 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2065270940578383, 31477096270353, 306421879113491, + 181958643936686, 1907105536686083 +#else + 13054543, 30774935, 19155473, 469045, 54626067, 4566041, + 5631406, 2711395, 1062915, 28418087 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1496516440779464, 1748485652986458, 872778352227340, + 818358834654919, 97932669284220 +#else + 47868616, 22299832, 37599834, 26054466, 61273100, 13005410, + 61042375, 12194496, 32960380, 1459310 +#endif + }}, + }, + }, + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 471636015770351, 672455402793577, 1804995246884103, + 1842309243470804, 1501862504981682 +#else + 19852015, 7027924, 23669353, 10020366, 8586503, 26896525, + 394196, 27452547, 18638002, 22379495 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1013216974933691, 538921919682598, 1915776722521558, + 1742822441583877, 1886550687916656 +#else + 31395515, 15098109, 26581030, 8030562, 50580950, 28547297, + 9012485, 25970078, 60465776, 28111795 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2094270000643336, 303971879192276, 40801275554748, + 649448917027930, 1818544418535447 +#else + 57916680, 31207054, 65111764, 4529533, 25766844, 607986, + 67095642, 9677542, 34813975, 27098423 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2241737709499165, 549397817447461, 838180519319392, + 1725686958520781, 1705639080897747 +#else + 64664349, 33404494, 29348901, 8186665, 1873760, 12489863, + 36174285, 25714739, 59256019, 25416002 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1216074541925116, 50120933933509, 1565829004133810, + 721728156134580, 349206064666188 +#else + 51872508, 18120922, 7766469, 746860, 26346930, 23332670, + 39775412, 10754587, 57677388, 5203575 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 948617110470858, 346222547451945, 1126511960599975, + 1759386906004538, 493053284802266 +#else + 31834314, 14135496, 66338857, 5159117, 20917671, 16786336, + 59640890, 26216907, 31809242, 7347066 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1454933046815146, 874696014266362, 1467170975468588, + 1432316382418897, 2111710746366763 +#else + 57502122, 21680191, 20414458, 13033986, 13716524, 21862551, + 19797969, 21343177, 15192875, 31466942 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2105387117364450, 1996463405126433, 1303008614294500, + 851908115948209, 1353742049788635 +#else + 54445282, 31372712, 1168161, 29749623, 26747876, 19416341, + 10609329, 12694420, 33473243, 20172328 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 750300956351719, 1487736556065813, 15158817002104, + 1511998221598392, 971739901354129 +#else + 33184999, 11180355, 15832085, 22169002, 65475192, 225883, + 15089336, 22530529, 60973201, 14480052 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1874648163531693, 2124487685930551, 1810030029384882, + 918400043048335, 586348627300650 +#else + 31308717, 27934434, 31030839, 31657333, 15674546, 26971549, + 5496207, 13685227, 27595050, 8737275 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1235084464747900, 1166111146432082, 1745394857881591, + 1405516473883040, 4463504151617 +#else + 46790012, 18404192, 10933842, 17376410, 8335351, 26008410, + 36100512, 20943827, 26498113, 66511 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1663810156463827, 327797390285791, 1341846161759410, + 1964121122800605, 1747470312055380 +#else + 22644435, 24792703, 50437087, 4884561, 64003250, 19995065, + 30540765, 29267685, 53781076, 26039336 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 660005247548233, 2071860029952887, 1358748199950107, + 911703252219107, 1014379923023831 +#else + 39091017, 9834844, 18617207, 30873120, 63706907, 20246925, + 8205539, 13585437, 49981399, 15115438 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2206641276178231, 1690587809721504, 1600173622825126, + 2156096097634421, 1106822408548216 +#else + 23711543, 32881517, 31206560, 25191721, 6164646, 23844445, + 33572981, 32128335, 8236920, 16492939 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1344788193552206, 1949552134239140, 1735915881729557, + 675891104100469, 1834220014427292 +#else + 43198286, 20038905, 40809380, 29050590, 25005589, 25867162, + 19574901, 10071562, 6708380, 27332008 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1920949492387964, 158885288387530, 70308263664033, + 626038464897817, 1468081726101009 +#else + 2101372, 28624378, 19702730, 2367575, 51681697, 1047674, + 5301017, 9328700, 29955601, 21876122 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 622221042073383, 1210146474039168, 1742246422343683, + 1403839361379025, 417189490895736 +#else + 3096359, 9271816, 45488000, 18032587, 52260867, 25961494, + 41216721, 20918836, 57191288, 6216607 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 22727256592983, 168471543384997, 1324340989803650, + 1839310709638189, 504999476432775 +#else + 34493015, 338662, 41913253, 2510421, 37895298, 19734218, + 24822829, 27407865, 40341383, 7525078 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1313240518756327, 1721896294296942, 52263574587266, + 2065069734239232, 804910473424630 +#else + 44042215, 19568808, 16133486, 25658254, 63719298, 778787, + 66198528, 30771936, 47722230, 11994100 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1337466662091884, 1287645354669772, 2018019646776184, + 652181229374245, 898011753211715 +#else + 21691500, 19929806, 66467532, 19187410, 3285880, 30070836, + 42044197, 9718257, 59631427, 13381417 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1969792547910734, 779969968247557, 2011350094423418, + 1823964252907487, 1058949448296945 +#else + 18445390, 29352196, 14979845, 11622458, 65381754, 29971451, + 23111647, 27179185, 28535281, 15779576 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 207343737062002, 1118176942430253, 758894594548164, + 806764629546266, 1157700123092949 +#else + 30098034, 3089662, 57874477, 16662134, 45801924, 11308410, + 53040410, 12021729, 9955285, 17251076 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1273565321399022, 1638509681964574, 759235866488935, + 666015124346707, 897983460943405 +#else + 9734894, 18977602, 59635230, 24415696, 2060391, 11313496, + 48682835, 9924398, 20194861, 13380996 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1717263794012298, 1059601762860786, 1837819172257618, + 1054130665797229, 680893204263559 +#else + 40730762, 25589224, 44941042, 15789296, 49053522, 27385639, + 65123949, 15707770, 26342023, 10146099 +#endif + }}, + }, + }, + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2237039662793603, 2249022333361206, 2058613546633703, + 149454094845279, 2215176649164582 +#else + 41091971, 33334488, 21339190, 33513044, 19745255, 30675732, + 37471583, 2227039, 21612326, 33008704 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 79472182719605, 1851130257050174, 1825744808933107, + 821667333481068, 781795293511946 +#else + 54031477, 1184227, 23562814, 27583990, 46757619, 27205717, + 25764460, 12243797, 46252298, 11649657 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 755822026485370, 152464789723500, 1178207602290608, + 410307889503239, 156581253571278 +#else + 57077370, 11262625, 27384172, 2271902, 26947504, 17556661, + 39943, 6114064, 33514190, 2333242 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1418185496130297, 484520167728613, 1646737281442950, + 1401487684670265, 1349185550126961 +#else + 45675257, 21132610, 8119781, 7219913, 45278342, 24538297, + 60429113, 20883793, 24350577, 20104431 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1495380034400429, 325049476417173, 46346894893933, + 1553408840354856, 828980101835683 +#else + 62992557, 22282898, 43222677, 4843614, 37020525, 690622, + 35572776, 23147595, 8317859, 12352766 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1280337889310282, 2070832742866672, 1640940617225222, + 2098284908289951, 450929509534434 +#else + 18200138, 19078521, 34021104, 30857812, 43406342, 24451920, + 43556767, 31266881, 20712162, 6719373 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 407703353998781, 126572141483652, 286039827513621, + 1999255076709338, 2030511179441770 +#else + 26656189, 6075253, 59250308, 1886071, 38764821, 4262325, + 11117530, 29791222, 26224234, 30256974 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1254958221100483, 1153235960999843, 942907704968834, + 637105404087392, 1149293270147267 +#else + 49939907, 18700334, 63713187, 17184554, 47154818, 14050419, + 21728352, 9493610, 18620611, 17125804 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 894249020470196, 400291701616810, 406878712230981, + 1599128793487393, 1145868722604026 +#else + 53785524, 13325348, 11432106, 5964811, 18609221, 6062965, + 61839393, 23828875, 36407290, 17074774 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1497955250203334, 110116344653260, 1128535642171976, + 1900106496009660, 129792717460909 +#else + 43248326, 22321272, 26961356, 1640861, 34695752, 16816491, + 12248508, 28313793, 13735341, 1934062 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 452487513298665, 1352120549024569, 1173495883910956, + 1999111705922009, 367328130454226 +#else + 25089769, 6742589, 17081145, 20148166, 21909292, 17486451, + 51972569, 29789085, 45830866, 5473615 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1717539401269642, 1475188995688487, 891921989653942, + 836824441505699, 1885988485608364 +#else + 31883658, 25593331, 1083431, 21982029, 22828470, 13290673, + 59983779, 12469655, 29111212, 28103418 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1241784121422547, 187337051947583, 1118481812236193, + 428747751936362, 30358898927325 +#else + 24244947, 18504025, 40845887, 2791539, 52111265, 16666677, + 24367466, 6388839, 56813277, 452382 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2022432361201842, 1088816090685051, 1977843398539868, + 1854834215890724, 564238862029357 +#else + 41468082, 30136590, 5217915, 16224624, 19987036, 29472163, + 42872612, 27639183, 15766061, 8407814 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 938868489100585, 1100285072929025, 1017806255688848, + 1957262154788833, 152787950560442 +#else + 46701865, 13990230, 15495425, 16395525, 5377168, 15166495, + 58191841, 29165478, 59040954, 2276717 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 867319417678923, 620471962942542, 226032203305716, + 342001443957629, 1761675818237336 +#else + 30157899, 12924066, 49396814, 9245752, 19895028, 3368142, + 43281277, 5096218, 22740376, 26251015 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1295072362439987, 931227904689414, 1355731432641687, + 922235735834035, 892227229410209 +#else + 2041139, 19298082, 7783686, 13876377, 41161879, 20201972, + 24051123, 13742383, 51471265, 13295221 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1680989767906154, 535362787031440, 2136691276706570, + 1942228485381244, 1267350086882274 +#else + 33338218, 25048699, 12532112, 7977527, 9106186, 31839181, + 49388668, 28941459, 62657506, 18884987 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 366018233770527, 432660629755596, 126409707644535, + 1973842949591662, 645627343442376 +#else + 47063583, 5454096, 52762316, 6447145, 28862071, 1883651, + 64639598, 29412551, 7770568, 9620597 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 535509430575217, 546885533737322, 1524675609547799, + 2138095752851703, 1260738089896827 +#else + 23208049, 7979712, 33071466, 8149229, 1758231, 22719437, + 30945527, 31860109, 33606523, 18786461 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1159906385590467, 2198530004321610, 714559485023225, + 81880727882151, 1484020820037082 +#else + 1439939, 17283952, 66028874, 32760649, 4625401, 10647766, + 62065063, 1220117, 30494170, 22113633 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1377485731340769, 2046328105512000, 1802058637158797, + 62146136768173, 1356993908853901 +#else + 62071265, 20526136, 64138304, 30492664, 15640973, 26852766, + 40369837, 926049, 65424525, 20220784 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2013612215646735, 1830770575920375, 536135310219832, + 609272325580394, 270684344495013 +#else + 13908495, 30005160, 30919927, 27280607, 45587000, 7989038, + 9021034, 9078865, 3353509, 4033511 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1237542585982777, 2228682050256790, 1385281931622824, + 593183794882890, 493654978552689 +#else + 37445433, 18440821, 32259990, 33209950, 24295848, 20642309, + 23161162, 8839127, 27485041, 7356032 +#endif + }}, + }, + }, + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 47341488007760, 1891414891220257, 983894663308928, + 176161768286818, 1126261115179708 +#else + 9661008, 705443, 11980065, 28184278, 65480320, 14661172, + 60762722, 2625014, 28431036, 16782598 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1694030170963455, 502038567066200, 1691160065225467, + 949628319562187, 275110186693066 +#else + 43269631, 25243016, 41163352, 7480957, 49427195, 25200248, + 44562891, 14150564, 15970762, 4099461 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1124515748676336, 1661673816593408, 1499640319059718, + 1584929449166988, 558148594103306 +#else + 29262576, 16756590, 26350592, 24760869, 8529670, 22346382, + 13617292, 23617289, 11465738, 8317062 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1784525599998356, 1619698033617383, 2097300287550715, + 258265458103756, 1905684794832758 +#else + 41615764, 26591503, 32500199, 24135381, 44070139, 31252209, + 14898636, 3848455, 20969334, 28396916 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1288941072872766, 931787902039402, 190731008859042, + 2006859954667190, 1005931482221702 +#else + 46724414, 19206718, 48772458, 13884721, 34069410, 2842113, + 45498038, 29904543, 11177094, 14989547 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1465551264822703, 152905080555927, 680334307368453, + 173227184634745, 666407097159852 +#else + 42612143, 21838415, 16959895, 2278463, 12066309, 10137771, + 13515641, 2581286, 38621356, 9930239 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2111017076203943, 1378760485794347, 1248583954016456, + 1352289194864422, 1895180776543896 +#else + 49357223, 31456605, 16544299, 20545132, 51194056, 18605350, + 18345766, 20150679, 16291480, 28240394 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 171348223915638, 662766099800389, 462338943760497, + 466917763340314, 656911292869115 +#else + 33879670, 2553287, 32678213, 9875984, 8534129, 6889387, + 57432090, 6957616, 4368891, 9788741 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 488623681976577, 866497561541722, 1708105560937768, + 1673781214218839, 1506146329818807 +#else + 16660737, 7281060, 56278106, 12911819, 20108584, 25452756, + 45386327, 24941283, 16250551, 22443329 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 160425464456957, 950394373239689, 430497123340934, + 711676555398832, 320964687779005 +#else + 47343357, 2390525, 50557833, 14161979, 1905286, 6414907, + 4689584, 10604807, 36918461, 4782746 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 988979367990485, 1359729327576302, 1301834257246029, + 294141160829308, 29348272277475 +#else + 65754325, 14736940, 59741422, 20261545, 7710541, 19398842, + 57127292, 4383044, 22546403, 437323 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1434382743317910, 100082049942065, 221102347892623, + 186982837860588, 1305765053501834 +#else + 31665558, 21373968, 50922033, 1491338, 48740239, 3294681, + 27343084, 2786261, 36475274, 19457415 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2205916462268190, 499863829790820, 961960554686616, + 158062762756985, 1841471168298305 +#else + 52641566, 32870716, 33734756, 7448551, 19294360, 14334329, + 47418233, 2355318, 47824193, 27440058 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1191737341426592, 1847042034978363, 1382213545049056, + 1039952395710448, 788812858896859 +#else + 15121312, 17758270, 6377019, 27523071, 56310752, 20596586, + 18952176, 15496498, 37728731, 11754227 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1346965964571152, 1291881610839830, 2142916164336056, + 786821641205979, 1571709146321039 +#else + 64471568, 20071356, 8488726, 19250536, 12728760, 31931939, + 7141595, 11724556, 22761615, 23420291 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 787164375951248, 202869205373189, 1356590421032140, + 1431233331032510, 786341368775957 +#else + 16918416, 11729663, 49025285, 3022986, 36093132, 20214772, + 38367678, 21327038, 32851221, 11717399 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 492448143532951, 304105152670757, 1761767168301056, + 233782684697790, 1981295323106089 +#else + 11166615, 7338049, 60386341, 4531519, 37640192, 26252376, + 31474878, 3483633, 65915689, 29523600 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 665807507761866, 1343384868355425, 895831046139653, + 439338948736892, 1986828765695105 +#else + 66923210, 9921304, 31456609, 20017994, 55095045, 13348922, + 33142652, 6546660, 47123585, 29606055 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 756096210874553, 1721699973539149, 258765301727885, + 1390588532210645, 1212530909934781 +#else + 34648249, 11266711, 55911757, 25655328, 31703693, 3855903, + 58571733, 20721383, 36336829, 18068118 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 852891097972275, 1816988871354562, 1543772755726524, + 1174710635522444, 202129090724628 +#else + 49102387, 12709067, 3991746, 27075244, 45617340, 23004006, + 35973516, 17504552, 10928916, 3011958 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1205281565824323, 22430498399418, 992947814485516, + 1392458699738672, 688441466734558 +#else + 60151107, 17960094, 31696058, 334240, 29576716, 14796075, + 36277808, 20749251, 18008030, 10258577 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1050627428414972, 1955849529137135, 2171162376368357, + 91745868298214, 447733118757826 +#else + 44660220, 15655568, 7018479, 29144429, 36794597, 32352840, + 65255398, 1367119, 25127874, 6671743 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1287181461435438, 622722465530711, 880952150571872, + 741035693459198, 311565274989772 +#else + 29701166, 19180498, 56230743, 9279287, 67091296, 13127209, + 21382910, 11042292, 25838796, 4642684 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1003649078149734, 545233927396469, 1849786171789880, + 1318943684880434, 280345687170552 +#else + 46678630, 14955536, 42982517, 8124618, 61739576, 27563961, + 30468146, 19653792, 18423288, 4177476 +#endif + }}, + }, + }, +}; + +#endif // OPENSSL_SMALL + +// Bi[i] = (2*i+1)*B +static const ge_precomp Bi[8] = { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1288382639258501, 245678601348599, 269427782077623, + 1462984067271730, 137412439391563 +#else + 25967493, 19198397, 29566455, 3660896, 54414519, 4014786, 27544626, + 21800161, 61029707, 2047604 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 62697248952638, 204681361388450, 631292143396476, 338455783676468, + 1213667448819585 +#else + 54563134, 934261, 64385954, 3049989, 66381436, 9406985, 12720692, + 5043384, 19500929, 18085054 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 301289933810280, 1259582250014073, 1422107436869536, + 796239922652654, 1953934009299142 +#else + 58370664, 4489569, 9688441, 18769238, 10184608, 21191052, 29287918, + 11864899, 42594502, 29115885 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1601611775252272, 1720807796594148, 1132070835939856, + 1260455018889551, 2147779492816911 +#else + 15636272, 23865875, 24204772, 25642034, 616976, 16869170, 27787599, + 18782243, 28944399, 32004408 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 316559037616741, 2177824224946892, 1459442586438991, + 1461528397712656, 751590696113597 +#else + 16568933, 4717097, 55552716, 32452109, 15682895, 21747389, 16354576, + 21778470, 7689661, 11199574 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1850748884277385, 1200145853858453, 1068094770532492, + 672251375690438, 1586055907191707 +#else + 30464137, 27578307, 55329429, 17883566, 23220364, 15915852, 7512774, + 10017326, 49359771, 23634074 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 769950342298419, 132954430919746, 844085933195555, 974092374476333, + 726076285546016 +#else + 10861363, 11473154, 27284546, 1981175, 37044515, 12577860, 32867885, + 14515107, 51670560, 10819379 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 425251763115706, 608463272472562, 442562545713235, 837766094556764, + 374555092627893 +#else + 4708026, 6336745, 20377586, 9066809, 55836755, 6594695, 41455196, + 12483687, 54440373, 5581305 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1086255230780037, 274979815921559, 1960002765731872, + 929474102396301, 1190409889297339 +#else + 19563141, 16186464, 37722007, 4097518, 10237984, 29206317, 28542349, + 13850243, 43430843, 17738489 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 665000864555967, 2065379846933859, 370231110385876, 350988370788628, + 1233371373142985 +#else + 5153727, 9909285, 1723747, 30776558, 30523604, 5516873, 19480852, + 5230134, 43156425, 18378665 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2019367628972465, 676711900706637, 110710997811333, + 1108646842542025, 517791959672113 +#else + 36839857, 30090922, 7665485, 10083793, 28475525, 1649722, 20654025, + 16520125, 30598449, 7715701 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 965130719900578, 247011430587952, 526356006571389, 91986625355052, + 2157223321444601 +#else + 28881826, 14381568, 9657904, 3680757, 46927229, 7843315, 35708204, + 1370707, 29794553, 32145132 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1802695059465007, 1664899123557221, 593559490740857, + 2160434469266659, 927570450755031 +#else + 44589871, 26862249, 14201701, 24808930, 43598457, 8844725, 18474211, + 32192982, 54046167, 13821876 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1725674970513508, 1933645953859181, 1542344539275782, + 1767788773573747, 1297447965928905 +#else + 60653668, 25714560, 3374701, 28813570, 40010246, 22982724, 31655027, + 26342105, 18853321, 19333481 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1381809363726107, 1430341051343062, 2061843536018959, + 1551778050872521, 2036394857967624 +#else + 4566811, 20590564, 38133974, 21313742, 59506191, 30723862, 58594505, + 23123294, 2207752, 30344648 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1970894096313054, 528066325833207, 1619374932191227, + 2207306624415883, 1169170329061080 +#else + 41954014, 29368610, 29681143, 7868801, 60254203, 24130566, 54671499, + 32891431, 35997400, 17421995 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2070390218572616, 1458919061857835, 624171843017421, + 1055332792707765, 433987520732508 +#else + 25576264, 30851218, 7349803, 21739588, 16472781, 9300885, 3844789, + 15725684, 171356, 6466918 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 893653801273833, 1168026499324677, 1242553501121234, + 1306366254304474, 1086752658510815 +#else + 23103977, 13316479, 9739013, 17404951, 817874, 18515490, 8965338, + 19466374, 36393951, 16193876 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 213454002618221, 939771523987438, 1159882208056014, 317388369627517, + 621213314200687 +#else + 33587053, 3180712, 64714734, 14003686, 50205390, 17283591, 17238397, + 4729455, 49034351, 9256799 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1971678598905747, 338026507889165, 762398079972271, 655096486107477, + 42299032696322 +#else + 41926547, 29380300, 32336397, 5036987, 45872047, 11360616, 22616405, + 9761698, 47281666, 630304 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 177130678690680, 1754759263300204, 1864311296286618, + 1180675631479880, 1292726903152791 +#else + 53388152, 2639452, 42871404, 26147950, 9494426, 27780403, 60554312, + 17593437, 64659607, 19263131 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1913163449625248, 460779200291993, 2193883288642314, + 1008900146920800, 1721983679009502 +#else + 63957664, 28508356, 9282713, 6866145, 35201802, 32691408, 48168288, + 15033783, 25105118, 25659556 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1070401523076875, 1272492007800961, 1910153608563310, + 2075579521696771, 1191169788841221 +#else + 42782475, 15950225, 35307649, 18961608, 55446126, 28463506, 1573891, + 30928545, 2198789, 17749813 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 692896803108118, 500174642072499, 2068223309439677, + 1162190621851337, 1426986007309901 +#else + 64009494, 10324966, 64867251, 7453182, 61661885, 30818928, 53296841, + 17317989, 34647629, 21263748 +#endif + }}, + }, +}; diff --git a/FoodApp/Pods/BoringSSL-GRPC/third_party/fiat/curve25519_tables.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/third_party/fiat/curve25519_tables.h.grpc_back new file mode 100644 index 0000000..c293e95 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/third_party/fiat/curve25519_tables.h.grpc_back @@ -0,0 +1,7880 @@ +// The MIT License (MIT) +// +// Copyright (c) 2015-2016 the fiat-crypto authors (see the AUTHORS file). +// +// 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. + +// This file is generated from +// ./make_curve25519_tables.py > curve25519_tables.h + + +static const fe d = {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 929955233495203, 466365720129213, 1662059464998953, 2033849074728123, + 1442794654840575 +#else + 56195235, 13857412, 51736253, 6949390, 114729, 24766616, 60832955, 30306712, + 48412415, 21499315 +#endif +}}; + +static const fe sqrtm1 = {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1718705420411056, 234908883556509, 2233514472574048, 2117202627021982, + 765476049583133 +#else + 34513072, 25610706, 9377949, 3500415, 12389472, 33281959, 41962654, + 31548777, 326685, 11406482 +#endif +}}; + +static const fe d2 = {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1859910466990425, 932731440258426, 1072319116312658, 1815898335770999, + 633789495995903 +#else + 45281625, 27714825, 36363642, 13898781, 229458, 15978800, 54557047, + 27058993, 29715967, 9444199 +#endif +}}; + +#if defined(OPENSSL_SMALL) + +// This block of code replaces the standard base-point table with a much smaller +// one. The standard table is 30,720 bytes while this one is just 960. +// +// This table contains 15 pairs of group elements, (x, y), where each field +// element is serialised with |fe_tobytes|. If |i| is the index of the group +// element then consider i+1 as a four-bit number: (i₀, i₁, i₂, i₃) (where i₀ +// is the most significant bit). The value of the group element is then: +// (i₀×2^192 + i₁×2^128 + i₂×2^64 + i₃)G, where G is the generator. +static const uint8_t k25519SmallPrecomp[15 * 2 * 32] = { + 0x1a, 0xd5, 0x25, 0x8f, 0x60, 0x2d, 0x56, 0xc9, 0xb2, 0xa7, 0x25, 0x95, + 0x60, 0xc7, 0x2c, 0x69, 0x5c, 0xdc, 0xd6, 0xfd, 0x31, 0xe2, 0xa4, 0xc0, + 0xfe, 0x53, 0x6e, 0xcd, 0xd3, 0x36, 0x69, 0x21, 0x58, 0x66, 0x66, 0x66, + 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, + 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, + 0x66, 0x66, 0x66, 0x66, 0x02, 0xa2, 0xed, 0xf4, 0x8f, 0x6b, 0x0b, 0x3e, + 0xeb, 0x35, 0x1a, 0xd5, 0x7e, 0xdb, 0x78, 0x00, 0x96, 0x8a, 0xa0, 0xb4, + 0xcf, 0x60, 0x4b, 0xd4, 0xd5, 0xf9, 0x2d, 0xbf, 0x88, 0xbd, 0x22, 0x62, + 0x13, 0x53, 0xe4, 0x82, 0x57, 0xfa, 0x1e, 0x8f, 0x06, 0x2b, 0x90, 0xba, + 0x08, 0xb6, 0x10, 0x54, 0x4f, 0x7c, 0x1b, 0x26, 0xed, 0xda, 0x6b, 0xdd, + 0x25, 0xd0, 0x4e, 0xea, 0x42, 0xbb, 0x25, 0x03, 0xa2, 0xfb, 0xcc, 0x61, + 0x67, 0x06, 0x70, 0x1a, 0xc4, 0x78, 0x3a, 0xff, 0x32, 0x62, 0xdd, 0x2c, + 0xab, 0x50, 0x19, 0x3b, 0xf2, 0x9b, 0x7d, 0xb8, 0xfd, 0x4f, 0x29, 0x9c, + 0xa7, 0x91, 0xba, 0x0e, 0x46, 0x5e, 0x51, 0xfe, 0x1d, 0xbf, 0xe5, 0xe5, + 0x9b, 0x95, 0x0d, 0x67, 0xf8, 0xd1, 0xb5, 0x5a, 0xa1, 0x93, 0x2c, 0xc3, + 0xde, 0x0e, 0x97, 0x85, 0x2d, 0x7f, 0xea, 0xab, 0x3e, 0x47, 0x30, 0x18, + 0x24, 0xe8, 0xb7, 0x60, 0xae, 0x47, 0x80, 0xfc, 0xe5, 0x23, 0xe7, 0xc2, + 0xc9, 0x85, 0xe6, 0x98, 0xa0, 0x29, 0x4e, 0xe1, 0x84, 0x39, 0x2d, 0x95, + 0x2c, 0xf3, 0x45, 0x3c, 0xff, 0xaf, 0x27, 0x4c, 0x6b, 0xa6, 0xf5, 0x4b, + 0x11, 0xbd, 0xba, 0x5b, 0x9e, 0xc4, 0xa4, 0x51, 0x1e, 0xbe, 0xd0, 0x90, + 0x3a, 0x9c, 0xc2, 0x26, 0xb6, 0x1e, 0xf1, 0x95, 0x7d, 0xc8, 0x6d, 0x52, + 0xe6, 0x99, 0x2c, 0x5f, 0x9a, 0x96, 0x0c, 0x68, 0x29, 0xfd, 0xe2, 0xfb, + 0xe6, 0xbc, 0xec, 0x31, 0x08, 0xec, 0xe6, 0xb0, 0x53, 0x60, 0xc3, 0x8c, + 0xbe, 0xc1, 0xb3, 0x8a, 0x8f, 0xe4, 0x88, 0x2b, 0x55, 0xe5, 0x64, 0x6e, + 0x9b, 0xd0, 0xaf, 0x7b, 0x64, 0x2a, 0x35, 0x25, 0x10, 0x52, 0xc5, 0x9e, + 0x58, 0x11, 0x39, 0x36, 0x45, 0x51, 0xb8, 0x39, 0x93, 0xfc, 0x9d, 0x6a, + 0xbe, 0x58, 0xcb, 0xa4, 0x0f, 0x51, 0x3c, 0x38, 0x05, 0xca, 0xab, 0x43, + 0x63, 0x0e, 0xf3, 0x8b, 0x41, 0xa6, 0xf8, 0x9b, 0x53, 0x70, 0x80, 0x53, + 0x86, 0x5e, 0x8f, 0xe3, 0xc3, 0x0d, 0x18, 0xc8, 0x4b, 0x34, 0x1f, 0xd8, + 0x1d, 0xbc, 0xf2, 0x6d, 0x34, 0x3a, 0xbe, 0xdf, 0xd9, 0xf6, 0xf3, 0x89, + 0xa1, 0xe1, 0x94, 0x9f, 0x5d, 0x4c, 0x5d, 0xe9, 0xa1, 0x49, 0x92, 0xef, + 0x0e, 0x53, 0x81, 0x89, 0x58, 0x87, 0xa6, 0x37, 0xf1, 0xdd, 0x62, 0x60, + 0x63, 0x5a, 0x9d, 0x1b, 0x8c, 0xc6, 0x7d, 0x52, 0xea, 0x70, 0x09, 0x6a, + 0xe1, 0x32, 0xf3, 0x73, 0x21, 0x1f, 0x07, 0x7b, 0x7c, 0x9b, 0x49, 0xd8, + 0xc0, 0xf3, 0x25, 0x72, 0x6f, 0x9d, 0xed, 0x31, 0x67, 0x36, 0x36, 0x54, + 0x40, 0x92, 0x71, 0xe6, 0x11, 0x28, 0x11, 0xad, 0x93, 0x32, 0x85, 0x7b, + 0x3e, 0xb7, 0x3b, 0x49, 0x13, 0x1c, 0x07, 0xb0, 0x2e, 0x93, 0xaa, 0xfd, + 0xfd, 0x28, 0x47, 0x3d, 0x8d, 0xd2, 0xda, 0xc7, 0x44, 0xd6, 0x7a, 0xdb, + 0x26, 0x7d, 0x1d, 0xb8, 0xe1, 0xde, 0x9d, 0x7a, 0x7d, 0x17, 0x7e, 0x1c, + 0x37, 0x04, 0x8d, 0x2d, 0x7c, 0x5e, 0x18, 0x38, 0x1e, 0xaf, 0xc7, 0x1b, + 0x33, 0x48, 0x31, 0x00, 0x59, 0xf6, 0xf2, 0xca, 0x0f, 0x27, 0x1b, 0x63, + 0x12, 0x7e, 0x02, 0x1d, 0x49, 0xc0, 0x5d, 0x79, 0x87, 0xef, 0x5e, 0x7a, + 0x2f, 0x1f, 0x66, 0x55, 0xd8, 0x09, 0xd9, 0x61, 0x38, 0x68, 0xb0, 0x07, + 0xa3, 0xfc, 0xcc, 0x85, 0x10, 0x7f, 0x4c, 0x65, 0x65, 0xb3, 0xfa, 0xfa, + 0xa5, 0x53, 0x6f, 0xdb, 0x74, 0x4c, 0x56, 0x46, 0x03, 0xe2, 0xd5, 0x7a, + 0x29, 0x1c, 0xc6, 0x02, 0xbc, 0x59, 0xf2, 0x04, 0x75, 0x63, 0xc0, 0x84, + 0x2f, 0x60, 0x1c, 0x67, 0x76, 0xfd, 0x63, 0x86, 0xf3, 0xfa, 0xbf, 0xdc, + 0xd2, 0x2d, 0x90, 0x91, 0xbd, 0x33, 0xa9, 0xe5, 0x66, 0x0c, 0xda, 0x42, + 0x27, 0xca, 0xf4, 0x66, 0xc2, 0xec, 0x92, 0x14, 0x57, 0x06, 0x63, 0xd0, + 0x4d, 0x15, 0x06, 0xeb, 0x69, 0x58, 0x4f, 0x77, 0xc5, 0x8b, 0xc7, 0xf0, + 0x8e, 0xed, 0x64, 0xa0, 0xb3, 0x3c, 0x66, 0x71, 0xc6, 0x2d, 0xda, 0x0a, + 0x0d, 0xfe, 0x70, 0x27, 0x64, 0xf8, 0x27, 0xfa, 0xf6, 0x5f, 0x30, 0xa5, + 0x0d, 0x6c, 0xda, 0xf2, 0x62, 0x5e, 0x78, 0x47, 0xd3, 0x66, 0x00, 0x1c, + 0xfd, 0x56, 0x1f, 0x5d, 0x3f, 0x6f, 0xf4, 0x4c, 0xd8, 0xfd, 0x0e, 0x27, + 0xc9, 0x5c, 0x2b, 0xbc, 0xc0, 0xa4, 0xe7, 0x23, 0x29, 0x02, 0x9f, 0x31, + 0xd6, 0xe9, 0xd7, 0x96, 0xf4, 0xe0, 0x5e, 0x0b, 0x0e, 0x13, 0xee, 0x3c, + 0x09, 0xed, 0xf2, 0x3d, 0x76, 0x91, 0xc3, 0xa4, 0x97, 0xae, 0xd4, 0x87, + 0xd0, 0x5d, 0xf6, 0x18, 0x47, 0x1f, 0x1d, 0x67, 0xf2, 0xcf, 0x63, 0xa0, + 0x91, 0x27, 0xf8, 0x93, 0x45, 0x75, 0x23, 0x3f, 0xd1, 0xf1, 0xad, 0x23, + 0xdd, 0x64, 0x93, 0x96, 0x41, 0x70, 0x7f, 0xf7, 0xf5, 0xa9, 0x89, 0xa2, + 0x34, 0xb0, 0x8d, 0x1b, 0xae, 0x19, 0x15, 0x49, 0x58, 0x23, 0x6d, 0x87, + 0x15, 0x4f, 0x81, 0x76, 0xfb, 0x23, 0xb5, 0xea, 0xcf, 0xac, 0x54, 0x8d, + 0x4e, 0x42, 0x2f, 0xeb, 0x0f, 0x63, 0xdb, 0x68, 0x37, 0xa8, 0xcf, 0x8b, + 0xab, 0xf5, 0xa4, 0x6e, 0x96, 0x2a, 0xb2, 0xd6, 0xbe, 0x9e, 0xbd, 0x0d, + 0xb4, 0x42, 0xa9, 0xcf, 0x01, 0x83, 0x8a, 0x17, 0x47, 0x76, 0xc4, 0xc6, + 0x83, 0x04, 0x95, 0x0b, 0xfc, 0x11, 0xc9, 0x62, 0xb8, 0x0c, 0x76, 0x84, + 0xd9, 0xb9, 0x37, 0xfa, 0xfc, 0x7c, 0xc2, 0x6d, 0x58, 0x3e, 0xb3, 0x04, + 0xbb, 0x8c, 0x8f, 0x48, 0xbc, 0x91, 0x27, 0xcc, 0xf9, 0xb7, 0x22, 0x19, + 0x83, 0x2e, 0x09, 0xb5, 0x72, 0xd9, 0x54, 0x1c, 0x4d, 0xa1, 0xea, 0x0b, + 0xf1, 0xc6, 0x08, 0x72, 0x46, 0x87, 0x7a, 0x6e, 0x80, 0x56, 0x0a, 0x8a, + 0xc0, 0xdd, 0x11, 0x6b, 0xd6, 0xdd, 0x47, 0xdf, 0x10, 0xd9, 0xd8, 0xea, + 0x7c, 0xb0, 0x8f, 0x03, 0x00, 0x2e, 0xc1, 0x8f, 0x44, 0xa8, 0xd3, 0x30, + 0x06, 0x89, 0xa2, 0xf9, 0x34, 0xad, 0xdc, 0x03, 0x85, 0xed, 0x51, 0xa7, + 0x82, 0x9c, 0xe7, 0x5d, 0x52, 0x93, 0x0c, 0x32, 0x9a, 0x5b, 0xe1, 0xaa, + 0xca, 0xb8, 0x02, 0x6d, 0x3a, 0xd4, 0xb1, 0x3a, 0xf0, 0x5f, 0xbe, 0xb5, + 0x0d, 0x10, 0x6b, 0x38, 0x32, 0xac, 0x76, 0x80, 0xbd, 0xca, 0x94, 0x71, + 0x7a, 0xf2, 0xc9, 0x35, 0x2a, 0xde, 0x9f, 0x42, 0x49, 0x18, 0x01, 0xab, + 0xbc, 0xef, 0x7c, 0x64, 0x3f, 0x58, 0x3d, 0x92, 0x59, 0xdb, 0x13, 0xdb, + 0x58, 0x6e, 0x0a, 0xe0, 0xb7, 0x91, 0x4a, 0x08, 0x20, 0xd6, 0x2e, 0x3c, + 0x45, 0xc9, 0x8b, 0x17, 0x79, 0xe7, 0xc7, 0x90, 0x99, 0x3a, 0x18, 0x25, +}; + +#else + +// k25519Precomp[i][j] = (j+1)*256^i*B +static const ge_precomp k25519Precomp[32][8] = { + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1288382639258501, 245678601348599, 269427782077623, + 1462984067271730, 137412439391563 +#else + 25967493, 19198397, 29566455, 3660896, 54414519, 4014786, + 27544626, 21800161, 61029707, 2047604 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 62697248952638, 204681361388450, 631292143396476, + 338455783676468, 1213667448819585 +#else + 54563134, 934261, 64385954, 3049989, 66381436, 9406985, + 12720692, 5043384, 19500929, 18085054 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 301289933810280, 1259582250014073, 1422107436869536, + 796239922652654, 1953934009299142 +#else + 58370664, 4489569, 9688441, 18769238, 10184608, 21191052, + 29287918, 11864899, 42594502, 29115885 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1380971894829527, 790832306631236, 2067202295274102, + 1995808275510000, 1566530869037010 +#else + 54292951, 20578084, 45527620, 11784319, 41753206, 30803714, + 55390960, 29739860, 66750418, 23343128 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 463307831301544, 432984605774163, 1610641361907204, + 750899048855000, 1894842303421586 +#else + 45405608, 6903824, 27185491, 6451973, 37531140, 24000426, + 51492312, 11189267, 40279186, 28235350 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 748439484463711, 1033211726465151, 1396005112841647, + 1611506220286469, 1972177495910992 +#else + 26966623, 11152617, 32442495, 15396054, 14353839, 20802097, + 63980037, 24013313, 51636816, 29387734 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1601611775252272, 1720807796594148, 1132070835939856, + 1260455018889551, 2147779492816911 +#else + 15636272, 23865875, 24204772, 25642034, 616976, 16869170, + 27787599, 18782243, 28944399, 32004408 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 316559037616741, 2177824224946892, 1459442586438991, + 1461528397712656, 751590696113597 +#else + 16568933, 4717097, 55552716, 32452109, 15682895, 21747389, + 16354576, 21778470, 7689661, 11199574 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1850748884277385, 1200145853858453, 1068094770532492, + 672251375690438, 1586055907191707 +#else + 30464137, 27578307, 55329429, 17883566, 23220364, 15915852, + 7512774, 10017326, 49359771, 23634074 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 934282339813791, 1846903124198670, 1172395437954843, + 1007037127761661, 1830588347719256 +#else + 50071967, 13921891, 10945806, 27521001, 27105051, 17470053, + 38182653, 15006022, 3284568, 27277892 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1694390458783935, 1735906047636159, 705069562067493, + 648033061693059, 696214010414170 +#else + 23599295, 25248385, 55915199, 25867015, 13236773, 10506355, + 7464579, 9656445, 13059162, 10374397 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1121406372216585, 192876649532226, 190294192191717, + 1994165897297032, 2245000007398739 +#else + 7798537, 16710257, 3033922, 2874086, 28997861, 2835604, + 32406664, 29715387, 66467155, 33453106 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 769950342298419, 132954430919746, 844085933195555, + 974092374476333, 726076285546016 +#else + 10861363, 11473154, 27284546, 1981175, 37044515, 12577860, + 32867885, 14515107, 51670560, 10819379 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 425251763115706, 608463272472562, 442562545713235, + 837766094556764, 374555092627893 +#else + 4708026, 6336745, 20377586, 9066809, 55836755, 6594695, + 41455196, 12483687, 54440373, 5581305 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1086255230780037, 274979815921559, 1960002765731872, + 929474102396301, 1190409889297339 +#else + 19563141, 16186464, 37722007, 4097518, 10237984, 29206317, + 28542349, 13850243, 43430843, 17738489 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1388594989461809, 316767091099457, 394298842192982, + 1230079486801005, 1440737038838979 +#else + 51736881, 20691677, 32573249, 4720197, 40672342, 5875510, + 47920237, 18329612, 57289923, 21468654 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 7380825640100, 146210432690483, 304903576448906, + 1198869323871120, 997689833219095 +#else + 58559652, 109982, 15149363, 2178705, 22900618, 4543417, 3044240, + 17864545, 1762327, 14866737 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1181317918772081, 114573476638901, 262805072233344, + 265712217171332, 294181933805782 +#else + 48909169, 17603008, 56635573, 1707277, 49922944, 3916100, + 38872452, 3959420, 27914454, 4383652 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 665000864555967, 2065379846933859, 370231110385876, + 350988370788628, 1233371373142985 +#else + 5153727, 9909285, 1723747, 30776558, 30523604, 5516873, + 19480852, 5230134, 43156425, 18378665 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2019367628972465, 676711900706637, 110710997811333, + 1108646842542025, 517791959672113 +#else + 36839857, 30090922, 7665485, 10083793, 28475525, 1649722, + 20654025, 16520125, 30598449, 7715701 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 965130719900578, 247011430587952, 526356006571389, + 91986625355052, 2157223321444601 +#else + 28881826, 14381568, 9657904, 3680757, 46927229, 7843315, + 35708204, 1370707, 29794553, 32145132 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2068619540119183, 1966274918058806, 957728544705549, + 729906502578991, 159834893065166 +#else + 14499471, 30824833, 33917750, 29299779, 28494861, 14271267, + 30290735, 10876454, 33954766, 2381725 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2073601412052185, 31021124762708, 264500969797082, + 248034690651703, 1030252227928288 +#else + 59913433, 30899068, 52378708, 462250, 39384538, 3941371, + 60872247, 3696004, 34808032, 15351954 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 551790716293402, 1989538725166328, 801169423371717, + 2052451893578887, 678432056995012 +#else + 27431194, 8222322, 16448760, 29646437, 48401861, 11938354, + 34147463, 30583916, 29551812, 10109425 +#endif + }}, + }, + }, + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1368953770187805, 790347636712921, 437508475667162, + 2142576377050580, 1932081720066286 +#else + 53451805, 20399000, 35825113, 11777097, 21447386, 6519384, + 64730580, 31926875, 10092782, 28790261 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 953638594433374, 1092333936795051, 1419774766716690, + 805677984380077, 859228993502513 +#else + 27939166, 14210322, 4677035, 16277044, 44144402, 21156292, + 34600109, 12005537, 49298737, 12803509 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1200766035879111, 20142053207432, 1465634435977050, + 1645256912097844, 295121984874596 +#else + 17228999, 17892808, 65875336, 300139, 65883994, 21839654, + 30364212, 24516238, 18016356, 4397660 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1735718747031557, 1248237894295956, 1204753118328107, + 976066523550493, 65943769534592 +#else + 56150021, 25864224, 4776340, 18600194, 27850027, 17952220, + 40489757, 14544524, 49631360, 982638 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1060098822528990, 1586825862073490, 212301317240126, + 1975302711403555, 666724059764335 +#else + 29253598, 15796703, 64244882, 23645547, 10057022, 3163536, + 7332899, 29434304, 46061167, 9934962 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1091990273418756, 1572899409348578, 80968014455247, + 306009358661350, 1520450739132526 +#else + 5793284, 16271923, 42977250, 23438027, 29188559, 1206517, + 52360934, 4559894, 36984942, 22656481 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1480517209436112, 1511153322193952, 1244343858991172, + 304788150493241, 369136856496443 +#else + 39464912, 22061425, 16282656, 22517939, 28414020, 18542168, + 24191033, 4541697, 53770555, 5500567 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2151330273626164, 762045184746182, 1688074332551515, + 823046109005759, 907602769079491 +#else + 12650548, 32057319, 9052870, 11355358, 49428827, 25154267, + 49678271, 12264342, 10874051, 13524335 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2047386910586836, 168470092900250, 1552838872594810, + 340951180073789, 360819374702533 +#else + 25556948, 30508442, 714650, 2510400, 23394682, 23139102, + 33119037, 5080568, 44580805, 5376627 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1982622644432056, 2014393600336956, 128909208804214, + 1617792623929191, 105294281913815 +#else + 41020600, 29543379, 50095164, 30016803, 60382070, 1920896, + 44787559, 24106988, 4535767, 1569007 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 980234343912898, 1712256739246056, 588935272190264, + 204298813091998, 841798321043288 +#else + 64853442, 14606629, 45416424, 25514613, 28430648, 8775819, + 36614302, 3044289, 31848280, 12543772 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 197561292938973, 454817274782871, 1963754960082318, + 2113372252160468, 971377527342673 +#else + 45080285, 2943892, 35251351, 6777305, 13784462, 29262229, + 39731668, 31491700, 7718481, 14474653 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 164699448829328, 3127451757672, 1199504971548753, + 1766155447043652, 1899238924683527 +#else + 2385296, 2454213, 44477544, 46602, 62670929, 17874016, 656964, + 26317767, 24316167, 28300865 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 732262946680281, 1674412764227063, 2182456405662809, + 1350894754474250, 558458873295247 +#else + 13741529, 10911568, 33875447, 24950694, 46931033, 32521134, + 33040650, 20129900, 46379407, 8321685 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2103305098582922, 1960809151316468, 715134605001343, + 1454892949167181, 40827143824949 +#else + 21060490, 31341688, 15712756, 29218333, 1639039, 10656336, + 23845965, 21679594, 57124405, 608371 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1239289043050212, 1744654158124578, 758702410031698, + 1796762995074688, 1603056663766 +#else + 53436132, 18466845, 56219170, 25997372, 61071954, 11305546, + 1123968, 26773855, 27229398, 23887 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2232056027107988, 987343914584615, 2115594492994461, + 1819598072792159, 1119305654014850 +#else + 43864724, 33260226, 55364135, 14712570, 37643165, 31524814, + 12797023, 27114124, 65475458, 16678953 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 320153677847348, 939613871605645, 641883205761567, + 1930009789398224, 329165806634126 +#else + 37608244, 4770661, 51054477, 14001337, 7830047, 9564805, + 65600720, 28759386, 49939598, 4904952 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 980930490474130, 1242488692177893, 1251446316964684, + 1086618677993530, 1961430968465772 +#else + 24059538, 14617003, 19037157, 18514524, 19766092, 18648003, + 5169210, 16191880, 2128236, 29227599 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 276821765317453, 1536835591188030, 1305212741412361, + 61473904210175, 2051377036983058 +#else + 50127693, 4124965, 58568254, 22900634, 30336521, 19449185, + 37302527, 916032, 60226322, 30567899 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 833449923882501, 1750270368490475, 1123347002068295, + 185477424765687, 278090826653186 +#else + 44477957, 12419371, 59974635, 26081060, 50629959, 16739174, + 285431, 2763829, 15736322, 4143876 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 794524995833413, 1849907304548286, 53348672473145, + 1272368559505217, 1147304168324779 +#else + 2379333, 11839345, 62998462, 27565766, 11274297, 794957, 212801, + 18959769, 23527083, 17096164 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1504846112759364, 1203096289004681, 562139421471418, + 274333017451844, 1284344053775441 +#else + 33431108, 22423954, 49269897, 17927531, 8909498, 8376530, + 34483524, 4087880, 51919953, 19138217 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 483048732424432, 2116063063343382, 30120189902313, + 292451576741007, 1156379271702225 +#else + 1767664, 7197987, 53903638, 31531796, 54017513, 448825, 5799055, + 4357868, 62334673, 17231393 +#endif + }}, + }, + }, + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 928372153029038, 2147692869914564, 1455665844462196, + 1986737809425946, 185207050258089 +#else + 6721966, 13833823, 43585476, 32003117, 26354292, 21691111, + 23365146, 29604700, 7390889, 2759800 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 137732961814206, 706670923917341, 1387038086865771, + 1965643813686352, 1384777115696347 +#else + 4409022, 2052381, 23373853, 10530217, 7676779, 20668478, + 21302352, 29290375, 1244379, 20634787 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 481144981981577, 2053319313589856, 2065402289827512, + 617954271490316, 1106602634668125 +#else + 62687625, 7169618, 4982368, 30596842, 30256824, 30776892, + 14086412, 9208236, 15886429, 16489664 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 696298019648792, 893299659040895, 1148636718636009, + 26734077349617, 2203955659340681 +#else + 1996056, 10375649, 14346367, 13311202, 60234729, 17116020, + 53415665, 398368, 36502409, 32841498 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 657390353372855, 998499966885562, 991893336905797, + 810470207106761, 343139804608786 +#else + 41801399, 9795879, 64331450, 14878808, 33577029, 14780362, + 13348553, 12076947, 36272402, 5113181 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 791736669492960, 934767652997115, 824656780392914, + 1759463253018643, 361530362383518 +#else + 49338080, 11797795, 31950843, 13929123, 41220562, 12288343, + 36767763, 26218045, 13847710, 5387222 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2022541353055597, 2094700262587466, 1551008075025686, + 242785517418164, 695985404963562 +#else + 48526701, 30138214, 17824842, 31213466, 22744342, 23111821, + 8763060, 3617786, 47508202, 10370990 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1287487199965223, 2215311941380308, 1552928390931986, + 1664859529680196, 1125004975265243 +#else + 20246567, 19185054, 22358228, 33010720, 18507282, 23140436, + 14554436, 24808340, 32232923, 16763880 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 677434665154918, 989582503122485, 1817429540898386, + 1052904935475344, 1143826298169798 +#else + 9648486, 10094563, 26416693, 14745928, 36734546, 27081810, + 11094160, 15689506, 3140038, 17044340 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 367266328308408, 318431188922404, 695629353755355, + 634085657580832, 24581612564426 +#else + 50948792, 5472694, 31895588, 4744994, 8823515, 10365685, + 39884064, 9448612, 38334410, 366294 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 773360688841258, 1815381330538070, 363773437667376, + 539629987070205, 783280434248437 +#else + 19153450, 11523972, 56012374, 27051289, 42461232, 5420646, + 28344573, 8041113, 719605, 11671788 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 180820816194166, 168937968377394, 748416242794470, + 1227281252254508, 1567587861004268 +#else + 8678006, 2694440, 60300850, 2517371, 4964326, 11152271, + 51675948, 18287915, 27000812, 23358879 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 478775558583645, 2062896624554807, 699391259285399, + 358099408427873, 1277310261461761 +#else + 51950941, 7134311, 8639287, 30739555, 59873175, 10421741, + 564065, 5336097, 6750977, 19033406 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1984740906540026, 1079164179400229, 1056021349262661, + 1659958556483663, 1088529069025527 +#else + 11836410, 29574944, 26297893, 16080799, 23455045, 15735944, + 1695823, 24735310, 8169719, 16220347 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 580736401511151, 1842931091388998, 1177201471228238, + 2075460256527244, 1301133425678027 +#else + 48993007, 8653646, 17578566, 27461813, 59083086, 17541668, + 55964556, 30926767, 61118155, 19388398 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1515728832059182, 1575261009617579, 1510246567196186, + 191078022609704, 116661716289141 +#else + 43800366, 22586119, 15213227, 23473218, 36255258, 22504427, + 27884328, 2847284, 2655861, 1738395 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1295295738269652, 1714742313707026, 545583042462581, + 2034411676262552, 1513248090013606 +#else + 39571412, 19301410, 41772562, 25551651, 57738101, 8129820, + 21651608, 30315096, 48021414, 22549153 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 230710545179830, 30821514358353, 760704303452229, + 390668103790604, 573437871383156 +#else + 1533110, 3437855, 23735889, 459276, 29970501, 11335377, + 26030092, 5821408, 10478196, 8544890 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1169380107545646, 263167233745614, 2022901299054448, + 819900753251120, 2023898464874585 +#else + 32173102, 17425121, 24896206, 3921497, 22579056, 30143578, + 19270448, 12217473, 17789017, 30158437 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2102254323485823, 1570832666216754, 34696906544624, + 1993213739807337, 70638552271463 +#else + 36555903, 31326030, 51530034, 23407230, 13243888, 517024, + 15479401, 29701199, 30460519, 1052596 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 894132856735058, 548675863558441, 845349339503395, + 1942269668326667, 1615682209874691 +#else + 55493970, 13323617, 32618793, 8175907, 51878691, 12596686, + 27491595, 28942073, 3179267, 24075541 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1287670217537834, 1222355136884920, 1846481788678694, + 1150426571265110, 1613523400722047 +#else + 31947050, 19187781, 62468280, 18214510, 51982886, 27514722, + 52352086, 17142691, 19072639, 24043372 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 793388516527298, 1315457083650035, 1972286999342417, + 1901825953052455, 338269477222410 +#else + 11685058, 11822410, 3158003, 19601838, 33402193, 29389366, + 5977895, 28339415, 473098, 5040608 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 550201530671806, 778605267108140, 2063911101902983, + 115500557286349, 2041641272971022 +#else + 46817982, 8198641, 39698732, 11602122, 1290375, 30754672, + 28326861, 1721092, 47550222, 30422825 +#endif + }}, + }, + }, + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 717255318455100, 519313764361315, 2080406977303708, + 541981206705521, 774328150311600 +#else + 7881532, 10687937, 7578723, 7738378, 48157852, 31000479, + 21820785, 8076149, 39240368, 11538388 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 261715221532238, 1795354330069993, 1496878026850283, + 499739720521052, 389031152673770 +#else + 47173198, 3899860, 18283497, 26752864, 51380203, 22305220, + 8754524, 7446702, 61432810, 5797015 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1997217696294013, 1717306351628065, 1684313917746180, + 1644426076011410, 1857378133465451 +#else + 55813245, 29760862, 51326753, 25589858, 12708868, 25098233, + 2014098, 24503858, 64739691, 27677090 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1475434724792648, 76931896285979, 1116729029771667, + 2002544139318042, 725547833803938 +#else + 44636488, 21985690, 39426843, 1146374, 18956691, 16640559, + 1192730, 29840233, 15123618, 10811505 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2022306639183567, 726296063571875, 315345054448644, + 1058733329149221, 1448201136060677 +#else + 14352079, 30134717, 48166819, 10822654, 32750596, 4699007, + 67038501, 15776355, 38222085, 21579878 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1710065158525665, 1895094923036397, 123988286168546, + 1145519900776355, 1607510767693874 +#else + 38867681, 25481956, 62129901, 28239114, 29416930, 1847569, + 46454691, 17069576, 4714546, 23953777 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 561605375422540, 1071733543815037, 131496498800990, + 1946868434569999, 828138133964203 +#else + 15200332, 8368572, 19679101, 15970074, 35236190, 1959450, + 24611599, 29010600, 55362987, 12340219 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1548495173745801, 442310529226540, 998072547000384, + 553054358385281, 644824326376171 +#else + 12876937, 23074376, 33134380, 6590940, 60801088, 14872439, + 9613953, 8241152, 15370987, 9608631 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1445526537029440, 2225519789662536, 914628859347385, + 1064754194555068, 1660295614401091 +#else + 62965568, 21540023, 8446280, 33162829, 4407737, 13629032, + 59383996, 15866073, 38898243, 24740332 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1199690223111956, 24028135822341, 66638289244341, + 57626156285975, 565093967979607 +#else + 26660628, 17876777, 8393733, 358047, 59707573, 992987, 43204631, + 858696, 20571223, 8420556 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 876926774220824, 554618976488214, 1012056309841565, + 839961821554611, 1414499340307677 +#else + 14620696, 13067227, 51661590, 8264466, 14106269, 15080814, + 33531827, 12516406, 45534429, 21077682 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 703047626104145, 1266841406201770, 165556500219173, + 486991595001879, 1011325891650656 +#else + 236881, 10476226, 57258, 18877408, 6472997, 2466984, 17258519, + 7256740, 8791136, 15069930 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1622861044480487, 1156394801573634, 1869132565415504, + 327103985777730, 2095342781472284 +#else + 1276391, 24182514, 22949634, 17231625, 43615824, 27852245, + 14711874, 4874229, 36445724, 31223040 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 334886927423922, 489511099221528, 129160865966726, + 1720809113143481, 619700195649254 +#else + 5855666, 4990204, 53397016, 7294283, 59304582, 1924646, + 65685689, 25642053, 34039526, 9234252 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1646545795166119, 1758370782583567, 714746174550637, + 1472693650165135, 898994790308209 +#else + 20590503, 24535444, 31529743, 26201766, 64402029, 10650547, + 31559055, 21944845, 18979185, 13396066 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 333403773039279, 295772542452938, 1693106465353610, + 912330357530760, 471235657950362 +#else + 24474287, 4968103, 22267082, 4407354, 24063882, 25229252, + 48291976, 13594781, 33514650, 7021958 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1811196219982022, 1068969825533602, 289602974833439, + 1988956043611592, 863562343398367 +#else + 55541958, 26988926, 45743778, 15928891, 40950559, 4315420, + 41160136, 29637754, 45628383, 12868081 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 906282429780072, 2108672665779781, 432396390473936, + 150625823801893, 1708930497638539 +#else + 38473832, 13504660, 19988037, 31421671, 21078224, 6443208, + 45662757, 2244499, 54653067, 25465048 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 925664675702328, 21416848568684, 1831436641861340, + 601157008940113, 371818055044496 +#else + 36513336, 13793478, 61256044, 319135, 41385692, 27290532, + 33086545, 8957937, 51875216, 5540520 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1479786007267725, 1738881859066675, 68646196476567, + 2146507056100328, 1247662817535471 +#else + 55478669, 22050529, 58989363, 25911358, 2620055, 1022908, + 43398120, 31985447, 50980335, 18591624 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 52035296774456, 939969390708103, 312023458773250, + 59873523517659, 1231345905848899 +#else + 23152952, 775386, 27395463, 14006635, 57407746, 4649511, + 1689819, 892185, 55595587, 18348483 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 643355106415761, 290186807495774, 2013561737429023, + 319648069511546, 393736678496162 +#else + 9770129, 9586738, 26496094, 4324120, 1556511, 30004408, + 27453818, 4763127, 47929250, 5867133 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 129358342392716, 1932811617704777, 1176749390799681, + 398040349861790, 1170779668090425 +#else + 34343820, 1927589, 31726409, 28801137, 23962433, 17534932, + 27846558, 5931263, 37359161, 17445976 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2051980782668029, 121859921510665, 2048329875753063, + 1235229850149665, 519062146124755 +#else + 27461885, 30576896, 22380809, 1815854, 44075111, 30522493, + 7283489, 18406359, 47582163, 7734628 +#endif + }}, + }, + }, + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1608170971973096, 415809060360428, 1350468408164766, + 2038620059057678, 1026904485989112 +#else + 59098600, 23963614, 55988460, 6196037, 29344158, 20123547, + 7585294, 30377806, 18549496, 15302069 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1837656083115103, 1510134048812070, 906263674192061, + 1821064197805734, 565375124676301 +#else + 34450527, 27383209, 59436070, 22502750, 6258877, 13504381, + 10458790, 27135971, 58236621, 8424745 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 578027192365650, 2034800251375322, 2128954087207123, + 478816193810521, 2196171989962750 +#else + 24687186, 8613276, 36441818, 30320886, 1863891, 31723888, + 19206233, 7134917, 55824382, 32725512 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1633188840273139, 852787172373708, 1548762607215796, + 1266275218902681, 1107218203325133 +#else + 11334899, 24336410, 8025292, 12707519, 17523892, 23078361, + 10243737, 18868971, 62042829, 16498836 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 462189358480054, 1784816734159228, 1611334301651368, + 1303938263943540, 707589560319424 +#else + 8911542, 6887158, 57524604, 26595841, 11145640, 24010752, + 17303924, 19430194, 6536640, 10543906 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1038829280972848, 38176604650029, 753193246598573, + 1136076426528122, 595709990562434 +#else + 38162480, 15479762, 49642029, 568875, 65611181, 11223453, + 64439674, 16928857, 39873154, 8876770 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1408451820859834, 2194984964010833, 2198361797561729, + 1061962440055713, 1645147963442934 +#else + 41365946, 20987567, 51458897, 32707824, 34082177, 32758143, + 33627041, 15824473, 66504438, 24514614 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 4701053362120, 1647641066302348, 1047553002242085, + 1923635013395977, 206970314902065 +#else + 10330056, 70051, 7957388, 24551765, 9764901, 15609756, 27698697, + 28664395, 1657393, 3084098 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1750479161778571, 1362553355169293, 1891721260220598, + 966109370862782, 1024913988299801 +#else + 10477963, 26084172, 12119565, 20303627, 29016246, 28188843, + 31280318, 14396151, 36875289, 15272408 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 212699049131723, 1117950018299775, 1873945661751056, + 1403802921984058, 130896082652698 +#else + 54820555, 3169462, 28813183, 16658753, 25116432, 27923966, + 41934906, 20918293, 42094106, 1950503 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 636808533673210, 1262201711667560, 390951380330599, + 1663420692697294, 561951321757406 +#else + 40928506, 9489186, 11053416, 18808271, 36055143, 5825629, + 58724558, 24786899, 15341278, 8373727 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 520731594438141, 1446301499955692, 273753264629267, + 1565101517999256, 1019411827004672 +#else + 28685821, 7759505, 52730348, 21551571, 35137043, 4079241, + 298136, 23321830, 64230656, 15190419 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 926527492029409, 1191853477411379, 734233225181171, + 184038887541270, 1790426146325343 +#else + 34175969, 13806335, 52771379, 17760000, 43104243, 10940927, + 8669718, 2742393, 41075551, 26679428 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1464651961852572, 1483737295721717, 1519450561335517, + 1161429831763785, 405914998179977 +#else + 65528476, 21825014, 41129205, 22109408, 49696989, 22641577, + 9291593, 17306653, 54954121, 6048604 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 996126634382301, 796204125879525, 127517800546509, + 344155944689303, 615279846169038 +#else + 36803549, 14843443, 1539301, 11864366, 20201677, 1900163, + 13934231, 5128323, 11213262, 9168384 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 738724080975276, 2188666632415296, 1961313708559162, + 1506545807547587, 1151301638969740 +#else + 40828332, 11007846, 19408960, 32613674, 48515898, 29225851, + 62020803, 22449281, 20470156, 17155731 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 622917337413835, 1218989177089035, 1284857712846592, + 970502061709359, 351025208117090 +#else + 43972811, 9282191, 14855179, 18164354, 59746048, 19145871, + 44324911, 14461607, 14042978, 5230683 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2067814584765580, 1677855129927492, 2086109782475197, + 235286517313238, 1416314046739645 +#else + 29969548, 30812838, 50396996, 25001989, 9175485, 31085458, + 21556950, 3506042, 61174973, 21104723 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 586844262630358, 307444381952195, 458399356043426, + 602068024507062, 1028548203415243 +#else + 63964118, 8744660, 19704003, 4581278, 46678178, 6830682, + 45824694, 8971512, 38569675, 15326562 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 678489922928203, 2016657584724032, 90977383049628, + 1026831907234582, 615271492942522 +#else + 47644235, 10110287, 49846336, 30050539, 43608476, 1355668, + 51585814, 15300987, 46594746, 9168259 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 301225714012278, 1094837270268560, 1202288391010439, + 644352775178361, 1647055902137983 +#else + 61755510, 4488612, 43305616, 16314346, 7780487, 17915493, + 38160505, 9601604, 33087103, 24543045 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1210746697896478, 1416608304244708, 686487477217856, + 1245131191434135, 1051238336855737 +#else + 47665694, 18041531, 46311396, 21109108, 37284416, 10229460, + 39664535, 18553900, 61111993, 15664671 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1135604073198207, 1683322080485474, 769147804376683, + 2086688130589414, 900445683120379 +#else + 23294591, 16921819, 44458082, 25083453, 27844203, 11461195, + 13099750, 31094076, 18151675, 13417686 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1971518477615628, 401909519527336, 448627091057375, + 1409486868273821, 1214789035034363 +#else + 42385932, 29377914, 35958184, 5988918, 40250079, 6685064, + 1661597, 21002991, 15271675, 18101767 +#endif + }}, + }, + }, + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1364039144731711, 1897497433586190, 2203097701135459, + 145461396811251, 1349844460790699 +#else + 11433023, 20325767, 8239630, 28274915, 65123427, 32828713, + 48410099, 2167543, 60187563, 20114249 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1045230323257973, 818206601145807, 630513189076103, + 1672046528998132, 807204017562437 +#else + 35672693, 15575145, 30436815, 12192228, 44645511, 9395378, + 57191156, 24915434, 12215109, 12028277 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 439961968385997, 386362664488986, 1382706320807688, + 309894000125359, 2207801346498567 +#else + 14098381, 6555944, 23007258, 5757252, 51681032, 20603929, + 30123439, 4617780, 50208775, 32898803 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1229004686397588, 920643968530863, 123975893911178, + 681423993215777, 1400559197080973 +#else + 63082644, 18313596, 11893167, 13718664, 52299402, 1847384, + 51288865, 10154008, 23973261, 20869958 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2003766096898049, 170074059235165, 1141124258967971, + 1485419893480973, 1573762821028725 +#else + 40577025, 29858441, 65199965, 2534300, 35238307, 17004076, + 18341389, 22134481, 32013173, 23450893 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 729905708611432, 1270323270673202, 123353058984288, + 426460209632942, 2195574535456672 +#else + 41629544, 10876442, 55337778, 18929291, 54739296, 1838103, + 21911214, 6354752, 4425632, 32716610 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1271140255321235, 2044363183174497, 52125387634689, + 1445120246694705, 942541986339084 +#else + 56675475, 18941465, 22229857, 30463385, 53917697, 776728, + 49693489, 21533969, 4725004, 14044970 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1761608437466135, 583360847526804, 1586706389685493, + 2157056599579261, 1170692369685772 +#else + 19268631, 26250011, 1555348, 8692754, 45634805, 23643767, + 6347389, 32142648, 47586572, 17444675 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 871476219910823, 1878769545097794, 2241832391238412, + 548957640601001, 690047440233174 +#else + 42244775, 12986007, 56209986, 27995847, 55796492, 33405905, + 19541417, 8180106, 9282262, 10282508 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 297194732135507, 1366347803776820, 1301185512245601, + 561849853336294, 1533554921345731 +#else + 40903763, 4428546, 58447668, 20360168, 4098401, 19389175, + 15522534, 8372215, 5542595, 22851749 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 999628998628371, 1132836708493400, 2084741674517453, + 469343353015612, 678782988708035 +#else + 56546323, 14895632, 26814552, 16880582, 49628109, 31065071, + 64326972, 6993760, 49014979, 10114654 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2189427607417022, 699801937082607, 412764402319267, + 1478091893643349, 2244675696854460 +#else + 47001790, 32625013, 31422703, 10427861, 59998115, 6150668, + 38017109, 22025285, 25953724, 33448274 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1712292055966563, 204413590624874, 1405738637332841, + 408981300829763, 861082219276721 +#else + 62874467, 25515139, 57989738, 3045999, 2101609, 20947138, + 19390019, 6094296, 63793585, 12831124 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 508561155940631, 966928475686665, 2236717801150132, + 424543858577297, 2089272956986143 +#else + 51110167, 7578151, 5310217, 14408357, 33560244, 33329692, + 31575953, 6326196, 7381791, 31132593 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 221245220129925, 1156020201681217, 491145634799213, + 542422431960839, 828100817819207 +#else + 46206085, 3296810, 24736065, 17226043, 18374253, 7318640, + 6295303, 8082724, 51746375, 12339663 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 153756971240384, 1299874139923977, 393099165260502, + 1058234455773022, 996989038681183 +#else + 27724736, 2291157, 6088201, 19369634, 1792726, 5857634, + 13848414, 15768922, 25091167, 14856294 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 559086812798481, 573177704212711, 1629737083816402, + 1399819713462595, 1646954378266038 +#else + 48242193, 8331042, 24373479, 8541013, 66406866, 24284974, + 12927299, 20858939, 44926390, 24541532 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1887963056288059, 228507035730124, 1468368348640282, + 930557653420194, 613513962454686 +#else + 55685435, 28132841, 11632844, 3405020, 30536730, 21880393, + 39848098, 13866389, 30146206, 9142070 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1224529808187553, 1577022856702685, 2206946542980843, + 625883007765001, 279930793512158 +#else + 3924129, 18246916, 53291741, 23499471, 12291819, 32886066, + 39406089, 9326383, 58871006, 4171293 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1076287717051609, 1114455570543035, 187297059715481, + 250446884292121, 1885187512550540 +#else + 51186905, 16037936, 6713787, 16606682, 45496729, 2790943, + 26396185, 3731949, 345228, 28091483 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 902497362940219, 76749815795675, 1657927525633846, + 1420238379745202, 1340321636548352 +#else + 45781307, 13448258, 25284571, 1143661, 20614966, 24705045, + 2031538, 21163201, 50855680, 19972348 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1129576631190784, 1281994010027327, 996844254743018, + 257876363489249, 1150850742055018 +#else + 31016192, 16832003, 26371391, 19103199, 62081514, 14854136, + 17477601, 3842657, 28012650, 17149012 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 628740660038789, 1943038498527841, 467786347793886, + 1093341428303375, 235413859513003 +#else + 62033029, 9368965, 58546785, 28953529, 51858910, 6970559, + 57918991, 16292056, 58241707, 3507939 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 237425418909360, 469614029179605, 1512389769174935, + 1241726368345357, 441602891065214 +#else + 29439664, 3537914, 23333589, 6997794, 49553303, 22536363, + 51899661, 18503164, 57943934, 6580395 +#endif + }}, + }, + }, + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1736417953058555, 726531315520508, 1833335034432527, + 1629442561574747, 624418919286085 +#else + 54923003, 25874643, 16438268, 10826160, 58412047, 27318820, + 17860443, 24280586, 65013061, 9304566 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1960754663920689, 497040957888962, 1909832851283095, + 1271432136996826, 2219780368020940 +#else + 20714545, 29217521, 29088194, 7406487, 11426967, 28458727, + 14792666, 18945815, 5289420, 33077305 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1537037379417136, 1358865369268262, 2130838645654099, + 828733687040705, 1999987652890901 +#else + 50443312, 22903641, 60948518, 20248671, 9192019, 31751970, + 17271489, 12349094, 26939669, 29802138 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 629042105241814, 1098854999137608, 887281544569320, + 1423102019874777, 7911258951561 +#else + 54218966, 9373457, 31595848, 16374215, 21471720, 13221525, + 39825369, 21205872, 63410057, 117886 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1811562332665373, 1501882019007673, 2213763501088999, + 359573079719636, 36370565049116 +#else + 22263325, 26994382, 3984569, 22379786, 51994855, 32987646, + 28311252, 5358056, 43789084, 541963 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 218907117361280, 1209298913016966, 1944312619096112, + 1130690631451061, 1342327389191701 +#else + 16259200, 3261970, 2309254, 18019958, 50223152, 28972515, + 24134069, 16848603, 53771797, 20002236 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1369976867854704, 1396479602419169, 1765656654398856, + 2203659200586299, 998327836117241 +#else + 9378160, 20414246, 44262881, 20809167, 28198280, 26310334, + 64709179, 32837080, 690425, 14876244 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2230701885562825, 1348173180338974, 2172856128624598, + 1426538746123771, 444193481326151 +#else + 24977353, 33240048, 58884894, 20089345, 28432342, 32378079, + 54040059, 21257083, 44727879, 6618998 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 784210426627951, 918204562375674, 1284546780452985, + 1324534636134684, 1872449409642708 +#else + 65570671, 11685645, 12944378, 13682314, 42719353, 19141238, + 8044828, 19737104, 32239828, 27901670 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 319638829540294, 596282656808406, 2037902696412608, + 1557219121643918, 341938082688094 +#else + 48505798, 4762989, 66182614, 8885303, 38696384, 30367116, + 9781646, 23204373, 32779358, 5095274 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1901860206695915, 2004489122065736, 1625847061568236, + 973529743399879, 2075287685312905 +#else + 34100715, 28339925, 34843976, 29869215, 9460460, 24227009, + 42507207, 14506723, 21639561, 30924196 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1371853944110545, 1042332820512553, 1949855697918254, + 1791195775521505, 37487364849293 +#else + 50707921, 20442216, 25239337, 15531969, 3987758, 29055114, + 65819361, 26690896, 17874573, 558605 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 687200189577855, 1082536651125675, 644224940871546, + 340923196057951, 343581346747396 +#else + 53508735, 10240080, 9171883, 16131053, 46239610, 9599699, + 33499487, 5080151, 2085892, 5119761 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2082717129583892, 27829425539422, 145655066671970, + 1690527209845512, 1865260509673478 +#else + 44903700, 31034903, 50727262, 414690, 42089314, 2170429, + 30634760, 25190818, 35108870, 27794547 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1059729620568824, 2163709103470266, 1440302280256872, + 1769143160546397, 869830310425069 +#else + 60263160, 15791201, 8550074, 32241778, 29928808, 21462176, + 27534429, 26362287, 44757485, 12961481 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1609516219779025, 777277757338817, 2101121130363987, + 550762194946473, 1905542338659364 +#else + 42616785, 23983660, 10368193, 11582341, 43711571, 31309144, + 16533929, 8206996, 36914212, 28394793 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2024821921041576, 426948675450149, 595133284085473, + 471860860885970, 600321679413000 +#else + 55987368, 30172197, 2307365, 6362031, 66973409, 8868176, + 50273234, 7031274, 7589640, 8945490 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 598474602406721, 1468128276358244, 1191923149557635, + 1501376424093216, 1281662691293476 +#else + 34956097, 8917966, 6661220, 21876816, 65916803, 17761038, + 7251488, 22372252, 24099108, 19098262 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1721138489890707, 1264336102277790, 433064545421287, + 1359988423149466, 1561871293409447 +#else + 5019539, 25646962, 4244126, 18840076, 40175591, 6453164, + 47990682, 20265406, 60876967, 23273695 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 719520245587143, 393380711632345, 132350400863381, + 1543271270810729, 1819543295798660 +#else + 10853575, 10721687, 26480089, 5861829, 44113045, 1972174, + 65242217, 22996533, 63745412, 27113307 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 396397949784152, 1811354474471839, 1362679985304303, + 2117033964846756, 498041172552279 +#else + 50106456, 5906789, 221599, 26991285, 7828207, 20305514, + 24362660, 31546264, 53242455, 7421391 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1812471844975748, 1856491995543149, 126579494584102, + 1036244859282620, 1975108050082550 +#else + 8139908, 27007935, 32257645, 27663886, 30375718, 1886181, + 45933756, 15441251, 28826358, 29431403 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 650623932407995, 1137551288410575, 2125223403615539, + 1725658013221271, 2134892965117796 +#else + 6267067, 9695052, 7709135, 16950835, 34239795, 31668296, + 14795159, 25714308, 13746020, 31812384 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 522584000310195, 1241762481390450, 1743702789495384, + 2227404127826575, 1686746002148897 +#else + 28584883, 7787108, 60375922, 18503702, 22846040, 25983196, + 63926927, 33190907, 4771361, 25134474 +#endif + }}, + }, + }, + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 427904865186312, 1703211129693455, 1585368107547509, + 1436984488744336, 761188534613978 +#else + 24949256, 6376279, 39642383, 25379823, 48462709, 23623825, + 33543568, 21412737, 3569626, 11342593 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 318101947455002, 248138407995851, 1481904195303927, + 309278454311197, 1258516760217879 +#else + 26514970, 4740088, 27912651, 3697550, 19331575, 22082093, + 6809885, 4608608, 7325975, 18753361 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1275068538599310, 513726919533379, 349926553492294, + 688428871968420, 1702400196000666 +#else + 55490446, 19000001, 42787651, 7655127, 65739590, 5214311, + 39708324, 10258389, 49462170, 25367739 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1061864036265233, 961611260325381, 321859632700838, + 1045600629959517, 1985130202504038 +#else + 11431185, 15823007, 26570245, 14329124, 18029990, 4796082, + 35662685, 15580663, 9280358, 29580745 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1558816436882417, 1962896332636523, 1337709822062152, + 1501413830776938, 294436165831932 +#else + 66948081, 23228174, 44253547, 29249434, 46247496, 19933429, + 34297962, 22372809, 51563772, 4387440 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 818359826554971, 1862173000996177, 626821592884859, + 573655738872376, 1749691246745455 +#else + 46309467, 12194511, 3937617, 27748540, 39954043, 9340369, + 42594872, 8548136, 20617071, 26072431 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1988022651432119, 1082111498586040, 1834020786104821, + 1454826876423687, 692929915223122 +#else + 66170039, 29623845, 58394552, 16124717, 24603125, 27329039, + 53333511, 21678609, 24345682, 10325460 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2146513703733331, 584788900394667, 464965657279958, + 2183973639356127, 238371159456790 +#else + 47253587, 31985546, 44906155, 8714033, 14007766, 6928528, + 16318175, 32543743, 4766742, 3552007 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1129007025494441, 2197883144413266, 265142755578169, + 971864464758890, 1983715884903702 +#else + 45357481, 16823515, 1351762, 32751011, 63099193, 3950934, + 3217514, 14481909, 10988822, 29559670 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1291366624493075, 381456718189114, 1711482489312444, + 1815233647702022, 892279782992467 +#else + 15564307, 19242862, 3101242, 5684148, 30446780, 25503076, + 12677126, 27049089, 58813011, 13296004 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 444548969917454, 1452286453853356, 2113731441506810, + 645188273895859, 810317625309512 +#else + 57666574, 6624295, 36809900, 21640754, 62437882, 31497052, + 31521203, 9614054, 37108040, 12074673 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2242724082797924, 1373354730327868, 1006520110883049, + 2147330369940688, 1151816104883620 +#else + 4771172, 33419193, 14290748, 20464580, 27992297, 14998318, + 65694928, 31997715, 29832612, 17163397 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1745720200383796, 1911723143175317, 2056329390702074, + 355227174309849, 879232794371100 +#else + 7064884, 26013258, 47946901, 28486894, 48217594, 30641695, + 25825241, 5293297, 39986204, 13101589 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 163723479936298, 115424889803150, 1156016391581227, + 1894942220753364, 1970549419986329 +#else + 64810282, 2439669, 59642254, 1719964, 39841323, 17225986, + 32512468, 28236839, 36752793, 29363474 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 681981452362484, 267208874112496, 1374683991933094, + 638600984916117, 646178654558546 +#else + 37102324, 10162315, 33928688, 3981722, 50626726, 20484387, + 14413973, 9515896, 19568978, 9628812 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 13378654854251, 106237307029567, 1944412051589651, + 1841976767925457, 230702819835573 +#else + 33053803, 199357, 15894591, 1583059, 27380243, 28973997, + 49269969, 27447592, 60817077, 3437739 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 260683893467075, 854060306077237, 913639551980112, + 4704576840123, 280254810808712 +#else + 48129987, 3884492, 19469877, 12726490, 15913552, 13614290, + 44147131, 70103, 7463304, 4176122 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 715374893080287, 1173334812210491, 1806524662079626, + 1894596008000979, 398905715033393 +#else + 39984863, 10659916, 11482427, 17484051, 12771466, 26919315, + 34389459, 28231680, 24216881, 5944158 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 500026409727661, 1596431288195371, 1420380351989370, + 985211561521489, 392444930785633 +#else + 8894125, 7450974, 64444715, 23788679, 39028346, 21165316, + 19345745, 14680796, 11632993, 5847885 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2096421546958141, 1922523000950363, 789831022876840, + 427295144688779, 320923973161730 +#else + 26942781, 31239115, 9129563, 28647825, 26024104, 11769399, + 55590027, 6367193, 57381634, 4782139 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1927770723575450, 1485792977512719, 1850996108474547, + 551696031508956, 2126047405475647 +#else + 19916442, 28726022, 44198159, 22140040, 25606323, 27581991, + 33253852, 8220911, 6358847, 31680575 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2112099158080148, 742570803909715, 6484558077432, + 1951119898618916, 93090382703416 +#else + 801428, 31472730, 16569427, 11065167, 29875704, 96627, 7908388, + 29073952, 53570360, 1387154 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 383905201636970, 859946997631870, 855623867637644, + 1017125780577795, 794250831877809 +#else + 19646058, 5720633, 55692158, 12814208, 11607948, 12749789, + 14147075, 15156355, 45242033, 11835259 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 77571826285752, 999304298101753, 487841111777762, + 1038031143212339, 339066367948762 +#else + 19299512, 1155910, 28703737, 14890794, 2925026, 7269399, + 26121523, 15467869, 40548314, 5052482 +#endif + }}, + }, + }, + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 674994775520533, 266035846330789, 826951213393478, + 1405007746162285, 1781791018620876 +#else + 64091413, 10058205, 1980837, 3964243, 22160966, 12322533, + 60677741, 20936246, 12228556, 26550755 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1001412661522686, 348196197067298, 1666614366723946, + 888424995032760, 580747687801357 +#else + 32944382, 14922211, 44263970, 5188527, 21913450, 24834489, + 4001464, 13238564, 60994061, 8653814 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1939560076207777, 1409892634407635, 552574736069277, + 383854338280405, 190706709864139 +#else + 22865569, 28901697, 27603667, 21009037, 14348957, 8234005, + 24808405, 5719875, 28483275, 2841751 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2177087163428741, 1439255351721944, 1208070840382793, + 2230616362004769, 1396886392021913 +#else + 50687877, 32441126, 66781144, 21446575, 21886281, 18001658, + 65220897, 33238773, 19932057, 20815229 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 676962063230039, 1880275537148808, 2046721011602706, + 888463247083003, 1318301552024067 +#else + 55452759, 10087520, 58243976, 28018288, 47830290, 30498519, + 3999227, 13239134, 62331395, 19644223 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1466980508178206, 617045217998949, 652303580573628, + 757303753529064, 207583137376902 +#else + 1382174, 21859713, 17266789, 9194690, 53784508, 9720080, + 20403944, 11284705, 53095046, 3093229 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1511056752906902, 105403126891277, 493434892772846, + 1091943425335976, 1802717338077427 +#else + 16650902, 22516500, 66044685, 1570628, 58779118, 7352752, + 66806440, 16271224, 43059443, 26862581 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1853982405405128, 1878664056251147, 1528011020803992, + 1019626468153565, 1128438412189035 +#else + 45197768, 27626490, 62497547, 27994275, 35364760, 22769138, + 24123613, 15193618, 45456747, 16815042 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1963939888391106, 293456433791664, 697897559513649, + 985882796904380, 796244541237972 +#else + 57172930, 29264984, 41829040, 4372841, 2087473, 10399484, + 31870908, 14690798, 17361620, 11864968 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 416770998629779, 389655552427054, 1314476859406756, + 1749382513022778, 1161905598739491 +#else + 55801235, 6210371, 13206574, 5806320, 38091172, 19587231, + 54777658, 26067830, 41530403, 17313742 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1428358296490651, 1027115282420478, 304840698058337, + 441410174026628, 1819358356278573 +#else + 14668443, 21284197, 26039038, 15305210, 25515617, 4542480, + 10453892, 6577524, 9145645, 27110552 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 204943430200135, 1554861433819175, 216426658514651, + 264149070665950, 2047097371738319 +#else + 5974855, 3053895, 57675815, 23169240, 35243739, 3225008, + 59136222, 3936127, 61456591, 30504127 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1934415182909034, 1393285083565062, 516409331772960, + 1157690734993892, 121039666594268 +#else + 30625386, 28825032, 41552902, 20761565, 46624288, 7695098, + 17097188, 17250936, 39109084, 1803631 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 662035583584445, 286736105093098, 1131773000510616, + 818494214211439, 472943792054479 +#else + 63555773, 9865098, 61880298, 4272700, 61435032, 16864731, + 14911343, 12196514, 45703375, 7047411 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 665784778135882, 1893179629898606, 808313193813106, + 276797254706413, 1563426179676396 +#else + 20093258, 9920966, 55970670, 28210574, 13161586, 12044805, + 34252013, 4124600, 34765036, 23296865 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 945205108984232, 526277562959295, 1324180513733566, + 1666970227868664, 153547609289173 +#else + 46320040, 14084653, 53577151, 7842146, 19119038, 19731827, + 4752376, 24839792, 45429205, 2288037 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2031433403516252, 203996615228162, 170487168837083, + 981513604791390, 843573964916831 +#else + 40289628, 30270716, 29965058, 3039786, 52635099, 2540456, + 29457502, 14625692, 42289247, 12570231 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1476570093962618, 838514669399805, 1857930577281364, + 2017007352225784, 317085545220047 +#else + 66045306, 22002608, 16920317, 12494842, 1278292, 27685323, + 45948920, 30055751, 55134159, 4724942 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1461557121912842, 1600674043318359, 2157134900399597, + 1670641601940616, 127765583803283 +#else + 17960970, 21778898, 62967895, 23851901, 58232301, 32143814, + 54201480, 24894499, 37532563, 1903855 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1293543509393474, 2143624609202546, 1058361566797508, + 214097127393994, 946888515472729 +#else + 23134274, 19275300, 56426866, 31942495, 20684484, 15770816, + 54119114, 3190295, 26955097, 14109738 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 357067959932916, 1290876214345711, 521245575443703, + 1494975468601005, 800942377643885 +#else + 15308788, 5320727, 36995055, 19235554, 22902007, 7767164, + 29425325, 22276870, 31960941, 11934971 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 566116659100033, 820247422481740, 994464017954148, + 327157611686365, 92591318111744 +#else + 39713153, 8435795, 4109644, 12222639, 42480996, 14818668, + 20638173, 4875028, 10491392, 1379718 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 617256647603209, 1652107761099439, 1857213046645471, + 1085597175214970, 817432759830522 +#else + 53949449, 9197840, 3875503, 24618324, 65725151, 27674630, + 33518458, 16176658, 21432314, 12180697 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 771808161440705, 1323510426395069, 680497615846440, + 851580615547985, 1320806384849017 +#else + 55321537, 11500837, 13787581, 19721842, 44678184, 10140204, + 1465425, 12689540, 56807545, 19681548 +#endif + }}, + }, + }, + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1219260086131915, 647169006596815, 79601124759706, + 2161724213426748, 404861897060198 +#else + 5414091, 18168391, 46101199, 9643569, 12834970, 1186149, + 64485948, 32212200, 26128230, 6032912 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1327968293887866, 1335500852943256, 1401587164534264, + 558137311952440, 1551360549268902 +#else + 40771450, 19788269, 32496024, 19900513, 17847800, 20885276, + 3604024, 8316894, 41233830, 23117073 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 417621685193956, 1429953819744454, 396157358457099, + 1940470778873255, 214000046234152 +#else + 3296484, 6223048, 24680646, 21307972, 44056843, 5903204, + 58246567, 28915267, 12376616, 3188849 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1268047918491973, 2172375426948536, 1533916099229249, + 1761293575457130, 1590622667026765 +#else + 29190469, 18895386, 27549112, 32370916, 3520065, 22857131, + 32049514, 26245319, 50999629, 23702124 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1627072914981959, 2211603081280073, 1912369601616504, + 1191770436221309, 2187309757525860 +#else + 52364359, 24245275, 735817, 32955454, 46701176, 28496527, + 25246077, 17758763, 18640740, 32593455 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1149147819689533, 378692712667677, 828475842424202, + 2218619146419342, 70688125792186 +#else + 60180029, 17123636, 10361373, 5642961, 4910474, 12345252, + 35470478, 33060001, 10530746, 1053335 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1299739417079761, 1438616663452759, 1536729078504412, + 2053896748919838, 1008421032591246 +#else + 37842897, 19367626, 53570647, 21437058, 47651804, 22899047, + 35646494, 30605446, 24018830, 15026644 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2040723824657366, 399555637875075, 632543375452995, + 872649937008051, 1235394727030233 +#else + 44516310, 30409154, 64819587, 5953842, 53668675, 9425630, + 25310643, 13003497, 64794073, 18408815 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2211311599327900, 2139787259888175, 938706616835350, + 12609661139114, 2081897930719789 +#else + 39688860, 32951110, 59064879, 31885314, 41016598, 13987818, + 39811242, 187898, 43942445, 31022696 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1324994503390450, 336982330582631, 1183998925654177, + 1091654665913274, 48727673971319 +#else + 45364466, 19743956, 1844839, 5021428, 56674465, 17642958, + 9716666, 16266922, 62038647, 726098 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1845522914617879, 1222198248335542, 150841072760134, + 1927029069940982, 1189913404498011 +#else + 29370903, 27500434, 7334070, 18212173, 9385286, 2247707, + 53446902, 28714970, 30007387, 17731091 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1079559557592645, 2215338383666441, 1903569501302605, + 49033973033940, 305703433934152 +#else + 66172485, 16086690, 23751945, 33011114, 65941325, 28365395, + 9137108, 730663, 9835848, 4555336 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 94653405416909, 1386121349852999, 1062130477891762, + 36553947479274, 833669648948846 +#else + 43732429, 1410445, 44855111, 20654817, 30867634, 15826977, + 17693930, 544696, 55123566, 12422645 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1432015813136298, 440364795295369, 1395647062821501, + 1976874522764578, 934452372723352 +#else + 31117226, 21338698, 53606025, 6561946, 57231997, 20796761, + 61990178, 29457725, 29120152, 13924425 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1296625309219774, 2068273464883862, 1858621048097805, + 1492281814208508, 2235868981918946 +#else + 49707966, 19321222, 19675798, 30819676, 56101901, 27695611, + 57724924, 22236731, 7240930, 33317044 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1490330266465570, 1858795661361448, 1436241134969763, + 294573218899647, 1208140011028933 +#else + 35747106, 22207651, 52101416, 27698213, 44655523, 21401660, + 1222335, 4389483, 3293637, 18002689 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1282462923712748, 741885683986255, 2027754642827561, + 518989529541027, 1826610009555945 +#else + 50424044, 19110186, 11038543, 11054958, 53307689, 30215898, + 42789283, 7733546, 12796905, 27218610 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1525827120027511, 723686461809551, 1597702369236987, + 244802101764964, 1502833890372311 +#else + 58349431, 22736595, 41689999, 10783768, 36493307, 23807620, + 38855524, 3647835, 3222231, 22393970 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 113622036244513, 1233740067745854, 674109952278496, + 2114345180342965, 166764512856263 +#else + 18606113, 1693100, 41660478, 18384159, 4112352, 10045021, + 23603893, 31506198, 59558087, 2484984 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2041668749310338, 2184405322203901, 1633400637611036, + 2110682505536899, 2048144390084644 +#else + 9255298, 30423235, 54952701, 32550175, 13098012, 24339566, + 16377219, 31451620, 47306788, 30519729 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 503058759232932, 760293024620937, 2027152777219493, + 666858468148475, 1539184379870952 +#else + 44379556, 7496159, 61366665, 11329248, 19991973, 30206930, + 35390715, 9936965, 37011176, 22935634 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1916168475367211, 915626432541343, 883217071712575, + 363427871374304, 1976029821251593 +#else + 21878571, 28553135, 4338335, 13643897, 64071999, 13160959, + 19708896, 5415497, 59748361, 29445138 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 678039535434506, 570587290189340, 1605302676614120, + 2147762562875701, 1706063797091704 +#else + 27736842, 10103576, 12500508, 8502413, 63695848, 23920873, + 10436917, 32004156, 43449720, 25422331 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1439489648586438, 2194580753290951, 832380563557396, + 561521973970522, 584497280718389 +#else + 19492550, 21450067, 37426887, 32701801, 63900692, 12403436, + 30066266, 8367329, 13243957, 8709688 +#endif + }}, + }, + }, + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 187989455492609, 681223515948275, 1933493571072456, + 1872921007304880, 488162364135671 +#else + 12015105, 2801261, 28198131, 10151021, 24818120, 28811299, + 55914672, 27908697, 5150967, 7274186 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1413466089534451, 410844090765630, 1397263346404072, + 408227143123410, 1594561803147811 +#else + 2831347, 21062286, 1478974, 6122054, 23825128, 20820846, + 31097298, 6083058, 31021603, 23760822 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2102170800973153, 719462588665004, 1479649438510153, + 1097529543970028, 1302363283777685 +#else + 64578913, 31324785, 445612, 10720828, 53259337, 22048494, + 43601132, 16354464, 15067285, 19406725 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 942065717847195, 1069313679352961, 2007341951411051, + 70973416446291, 1419433790163706 +#else + 7840923, 14037873, 33744001, 15934015, 66380651, 29911725, + 21403987, 1057586, 47729402, 21151211 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1146565545556377, 1661971299445212, 406681704748893, + 564452436406089, 1109109865829139 +#else + 915865, 17085158, 15608284, 24765302, 42751837, 6060029, + 49737545, 8410996, 59888403, 16527024 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2214421081775077, 1165671861210569, 1890453018796184, + 3556249878661, 442116172656317 +#else + 32922597, 32997445, 20336073, 17369864, 10903704, 28169945, + 16957573, 52992, 23834301, 6588044 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 753830546620811, 1666955059895019, 1530775289309243, + 1119987029104146, 2164156153857580 +#else + 32752011, 11232950, 3381995, 24839566, 22652987, 22810329, + 17159698, 16689107, 46794284, 32248439 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 615171919212796, 1523849404854568, 854560460547503, + 2067097370290715, 1765325848586042 +#else + 62419196, 9166775, 41398568, 22707125, 11576751, 12733943, + 7924251, 30802151, 1976122, 26305405 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1094538949313667, 1796592198908825, 870221004284388, + 2025558921863561, 1699010892802384 +#else + 21251203, 16309901, 64125849, 26771309, 30810596, 12967303, + 156041, 30183180, 12331344, 25317235 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1951351290725195, 1916457206844795, 198025184438026, + 1909076887557595, 1938542290318919 +#else + 8651595, 29077400, 51023227, 28557437, 13002506, 2950805, + 29054427, 28447462, 10008135, 28886531 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1014323197538413, 869150639940606, 1756009942696599, + 1334952557375672, 1544945379082874 +#else + 31486061, 15114593, 52847614, 12951353, 14369431, 26166587, + 16347320, 19892343, 8684154, 23021480 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 764055910920305, 1603590757375439, 146805246592357, + 1843313433854297, 954279890114939 +#else + 19443825, 11385320, 24468943, 23895364, 43189605, 2187568, + 40845657, 27467510, 31316347, 14219878 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 80113526615750, 764536758732259, 1055139345100233, + 469252651759390, 617897512431515 +#else + 38514374, 1193784, 32245219, 11392485, 31092169, 15722801, + 27146014, 6992409, 29126555, 9207390 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 74497112547268, 740094153192149, 1745254631717581, + 727713886503130, 1283034364416928 +#else + 32382916, 1110093, 18477781, 11028262, 39697101, 26006320, + 62128346, 10843781, 59151264, 19118701 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 525892105991110, 1723776830270342, 1476444848991936, + 573789489857760, 133864092632978 +#else + 2814918, 7836403, 27519878, 25686276, 46214848, 22000742, + 45614304, 8550129, 28346258, 1994730 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 542611720192581, 1986812262899321, 1162535242465837, + 481498966143464, 544600533583622 +#else + 47530565, 8085544, 53108345, 29605809, 2785837, 17323125, + 47591912, 7174893, 22628102, 8115180 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 64123227344372, 1239927720647794, 1360722983445904, + 222610813654661, 62429487187991 +#else + 36703732, 955510, 55975026, 18476362, 34661776, 20276352, + 41457285, 3317159, 57165847, 930271 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1793193323953132, 91096687857833, 70945970938921, + 2158587638946380, 1537042406482111 +#else + 51805164, 26720662, 28856489, 1357446, 23421993, 1057177, + 24091212, 32165462, 44343487, 22903716 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1895854577604609, 1394895708949416, 1728548428495944, + 1140864900240149, 563645333603061 +#else + 44357633, 28250434, 54201256, 20785565, 51297352, 25757378, + 52269845, 17000211, 65241845, 8398969 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 141358280486863, 91435889572504, 1087208572552643, + 1829599652522921, 1193307020643647 +#else + 35139535, 2106402, 62372504, 1362500, 12813763, 16200670, + 22981545, 27263159, 18009407, 17781660 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1611230858525381, 950720175540785, 499589887488610, + 2001656988495019, 88977313255908 +#else + 49887941, 24009210, 39324209, 14166834, 29815394, 7444469, + 29551787, 29827013, 19288548, 1325865 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1189080501479658, 2184348804772597, 1040818725742319, + 2018318290311834, 1712060030915354 +#else + 15100138, 17718680, 43184885, 32549333, 40658671, 15509407, + 12376730, 30075286, 33166106, 25511682 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 873966876953756, 1090638350350440, 1708559325189137, + 672344594801910, 1320437969700239 +#else + 20909212, 13023121, 57899112, 16251777, 61330449, 25459517, + 12412150, 10018715, 2213263, 19676059 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1508590048271766, 1131769479776094, 101550868699323, + 428297785557897, 561791648661744 +#else + 32529814, 22479743, 30361438, 16864679, 57972923, 1513225, + 22922121, 6382134, 61341936, 8371347 +#endif + }}, + }, + }, + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 756417570499462, 237882279232602, 2136263418594016, + 1701968045454886, 703713185137472 +#else + 9923462, 11271500, 12616794, 3544722, 37110496, 31832805, + 12891686, 25361300, 40665920, 10486143 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1781187809325462, 1697624151492346, 1381393690939988, + 175194132284669, 1483054666415238 +#else + 44511638, 26541766, 8587002, 25296571, 4084308, 20584370, + 361725, 2610596, 43187334, 22099236 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2175517777364616, 708781536456029, 955668231122942, + 1967557500069555, 2021208005604118 +#else + 5408392, 32417741, 62139741, 10561667, 24145918, 14240566, + 31319731, 29318891, 19985174, 30118346 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1115135966606887, 224217372950782, 915967306279222, + 593866251291540, 561747094208006 +#else + 53114407, 16616820, 14549246, 3341099, 32155958, 13648976, + 49531796, 8849296, 65030, 8370684 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1443163092879439, 391875531646162, 2180847134654632, + 464538543018753, 1594098196837178 +#else + 58787919, 21504805, 31204562, 5839400, 46481576, 32497154, + 47665921, 6922163, 12743482, 23753914 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 850858855888869, 319436476624586, 327807784938441, + 740785849558761, 17128415486016 +#else + 64747493, 12678784, 28815050, 4759974, 43215817, 4884716, + 23783145, 11038569, 18800704, 255233 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2132756334090067, 536247820155645, 48907151276867, + 608473197600695, 1261689545022784 +#else + 61839187, 31780545, 13957885, 7990715, 23132995, 728773, + 13393847, 9066957, 19258688, 18800639 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1525176236978354, 974205476721062, 293436255662638, + 148269621098039, 137961998433963 +#else + 64172210, 22726896, 56676774, 14516792, 63468078, 4372540, + 35173943, 2209389, 65584811, 2055793 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1121075518299410, 2071745529082111, 1265567917414828, + 1648196578317805, 496232102750820 +#else + 580882, 16705327, 5468415, 30871414, 36182444, 18858431, + 59905517, 24560042, 37087844, 7394434 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 122321229299801, 1022922077493685, 2001275453369484, + 2017441881607947, 993205880778002 +#else + 23838809, 1822728, 51370421, 15242726, 8318092, 29821328, + 45436683, 30062226, 62287122, 14799920 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 654925550560074, 1168810995576858, 575655959430926, + 905758704861388, 496774564663534 +#else + 13345610, 9759151, 3371034, 17416641, 16353038, 8577942, + 31129804, 13496856, 58052846, 7402517 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1954109525779738, 2117022646152485, 338102630417180, + 1194140505732026, 107881734943492 +#else + 2286874, 29118501, 47066405, 31546095, 53412636, 5038121, + 11006906, 17794080, 8205060, 1607563 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1714785840001267, 2036500018681589, 1876380234251966, + 2056717182974196, 1645855254384642 +#else + 14414067, 25552300, 3331829, 30346215, 22249150, 27960244, + 18364660, 30647474, 30019586, 24525154 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 106431476499341, 62482972120563, 1513446655109411, + 807258751769522, 538491469114 +#else + 39420813, 1585952, 56333811, 931068, 37988643, 22552112, + 52698034, 12029092, 9944378, 8024 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2002850762893643, 1243624520538135, 1486040410574605, + 2184752338181213, 378495998083531 +#else + 4368715, 29844802, 29874199, 18531449, 46878477, 22143727, + 50994269, 32555346, 58966475, 5640029 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 922510868424903, 1089502620807680, 402544072617374, + 1131446598479839, 1290278588136533 +#else + 10299591, 13746483, 11661824, 16234854, 7630238, 5998374, + 9809887, 16859868, 15219797, 19226649 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1867998812076769, 715425053580701, 39968586461416, + 2173068014586163, 653822651801304 +#else + 27425505, 27835351, 3055005, 10660664, 23458024, 595578, + 51710259, 32381236, 48766680, 9742716 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 162892278589453, 182585796682149, 75093073137630, + 497037941226502, 133871727117371 +#else + 6744077, 2427284, 26042789, 2720740, 66260958, 1118973, + 32324614, 7406442, 12420155, 1994844 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1914596576579670, 1608999621851578, 1987629837704609, + 1519655314857977, 1819193753409464 +#else + 14012502, 28529712, 48724410, 23975962, 40623521, 29617992, + 54075385, 22644628, 24319928, 27108099 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1949315551096831, 1069003344994464, 1939165033499916, + 1548227205730856, 1933767655861407 +#else + 16412671, 29047065, 10772640, 15929391, 50040076, 28895810, + 10555944, 23070383, 37006495, 28815383 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1730519386931635, 1393284965610134, 1597143735726030, + 416032382447158, 1429665248828629 +#else + 22397363, 25786748, 57815702, 20761563, 17166286, 23799296, + 39775798, 6199365, 21880021, 21303672 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 360275475604565, 547835731063078, 215360904187529, + 596646739879007, 332709650425085 +#else + 62825557, 5368522, 35991846, 8163388, 36785801, 3209127, + 16557151, 8890729, 8840445, 4957760 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 47602113726801, 1522314509708010, 437706261372925, + 814035330438027, 335930650933545 +#else + 51661137, 709326, 60189418, 22684253, 37330941, 6522331, + 45388683, 12130071, 52312361, 5005756 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1291597595523886, 1058020588994081, 402837842324045, + 1363323695882781, 2105763393033193 +#else + 64994094, 19246303, 23019041, 15765735, 41839181, 6002751, + 10183197, 20315106, 50713577, 31378319 +#endif + }}, + }, + }, + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 109521982566564, 1715257748585139, 1112231216891516, + 2046641005101484, 134249157157013 +#else + 48083108, 1632004, 13466291, 25559332, 43468412, 16573536, + 35094956, 30497327, 22208661, 2000468 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2156991030936798, 2227544497153325, 1869050094431622, + 754875860479115, 1754242344267058 +#else + 3065054, 32141671, 41510189, 33192999, 49425798, 27851016, + 58944651, 11248526, 63417650, 26140247 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1846089562873800, 98894784984326, 1412430299204844, + 171351226625762, 1100604760929008 +#else + 10379208, 27508878, 8877318, 1473647, 37817580, 21046851, + 16690914, 2553332, 63976176, 16400288 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 84172382130492, 499710970700046, 425749630620778, + 1762872794206857, 612842602127960 +#else + 15716668, 1254266, 48636174, 7446273, 58659946, 6344163, + 45011593, 26268851, 26894936, 9132066 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 868309334532756, 1703010512741873, 1952690008738057, + 4325269926064, 2071083554962116 +#else + 24158868, 12938817, 11085297, 25376834, 39045385, 29097348, + 36532400, 64451, 60291780, 30861549 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 523094549451158, 401938899487815, 1407690589076010, + 2022387426254453, 158660516411257 +#else + 13488534, 7794716, 22236231, 5989356, 25426474, 20976224, + 2350709, 30135921, 62420857, 2364225 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 612867287630009, 448212612103814, 571629077419196, + 1466796750919376, 1728478129663858 +#else + 16335033, 9132434, 25640582, 6678888, 1725628, 8517937, + 55301840, 21856974, 15445874, 25756331 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1723848973783452, 2208822520534681, 1718748322776940, + 1974268454121942, 1194212502258141 +#else + 29004188, 25687351, 28661401, 32914020, 54314860, 25611345, + 31863254, 29418892, 66830813, 17795152 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1254114807944608, 977770684047110, 2010756238954993, + 1783628927194099, 1525962994408256 +#else + 60986784, 18687766, 38493958, 14569918, 56250865, 29962602, + 10343411, 26578142, 37280576, 22738620 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 232464058235826, 1948628555342434, 1835348780427694, + 1031609499437291, 64472106918373 +#else + 27081650, 3463984, 14099042, 29036828, 1616302, 27348828, + 29542635, 15372179, 17293797, 960709 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 767338676040683, 754089548318405, 1523192045639075, + 435746025122062, 512692508440385 +#else + 20263915, 11434237, 61343429, 11236809, 13505955, 22697330, + 50997518, 6493121, 47724353, 7639713 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1255955808701983, 1700487367990941, 1166401238800299, + 1175121994891534, 1190934801395380 +#else + 64278047, 18715199, 25403037, 25339236, 58791851, 17380732, + 18006286, 17510682, 29994676, 17746311 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 349144008168292, 1337012557669162, 1475912332999108, + 1321618454900458, 47611291904320 +#else + 9769828, 5202651, 42951466, 19923039, 39057860, 21992807, + 42495722, 19693649, 35924288, 709463 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 877519947135419, 2172838026132651, 272304391224129, + 1655143327559984, 886229406429814 +#else + 12286395, 13076066, 45333675, 32377809, 42105665, 4057651, + 35090736, 24663557, 16102006, 13205847 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 375806028254706, 214463229793940, 572906353144089, + 572168269875638, 697556386112979 +#else + 13733362, 5599946, 10557076, 3195751, 61550873, 8536969, + 41568694, 8525971, 10151379, 10394400 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1168827102357844, 823864273033637, 2071538752104697, + 788062026895924, 599578340743362 +#else + 4024660, 17416881, 22436261, 12276534, 58009849, 30868332, + 19698228, 11743039, 33806530, 8934413 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1948116082078088, 2054898304487796, 2204939184983900, + 210526805152138, 786593586607626 +#else + 51229064, 29029191, 58528116, 30620370, 14634844, 32856154, + 57659786, 3137093, 55571978, 11721157 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1915320147894736, 156481169009469, 655050471180417, + 592917090415421, 2165897438660879 +#else + 17555920, 28540494, 8268605, 2331751, 44370049, 9761012, + 9319229, 8835153, 57903375, 32274386 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1726336468579724, 1119932070398949, 1929199510967666, + 33918788322959, 1836837863503150 +#else + 66647436, 25724417, 20614117, 16688288, 59594098, 28747312, + 22300303, 505429, 6108462, 27371017 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 829996854845988, 217061778005138, 1686565909803640, + 1346948817219846, 1723823550730181 +#else + 62038564, 12367916, 36445330, 3234472, 32617080, 25131790, + 29880582, 20071101, 40210373, 25686972 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 384301494966394, 687038900403062, 2211195391021739, + 254684538421383, 1245698430589680 +#else + 35133562, 5726538, 26934134, 10237677, 63935147, 32949378, + 24199303, 3795095, 7592688, 18562353 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1247567493562688, 1978182094455847, 183871474792955, + 806570235643435, 288461518067916 +#else + 21594432, 18590204, 17466407, 29477210, 32537083, 2739898, + 6407723, 12018833, 38852812, 4298411 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1449077384734201, 38285445457996, 2136537659177832, + 2146493000841573, 725161151123125 +#else + 46458361, 21592935, 39872588, 570497, 3767144, 31836892, + 13891941, 31985238, 13717173, 10805743 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1201928866368855, 800415690605445, 1703146756828343, + 997278587541744, 1858284414104014 +#else + 52432215, 17910135, 15287173, 11927123, 24177847, 25378864, + 66312432, 14860608, 40169934, 27690595 +#endif + }}, + }, + }, + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 356468809648877, 782373916933152, 1718002439402870, + 1392222252219254, 663171266061951 +#else + 12962541, 5311799, 57048096, 11658279, 18855286, 25600231, + 13286262, 20745728, 62727807, 9882021 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 759628738230460, 1012693474275852, 353780233086498, + 246080061387552, 2030378857679162 +#else + 18512060, 11319350, 46985740, 15090308, 18818594, 5271736, + 44380960, 3666878, 43141434, 30255002 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2040672435071076, 888593182036908, 1298443657189359, + 1804780278521327, 354070726137060 +#else + 60319844, 30408388, 16192428, 13241070, 15898607, 19348318, + 57023983, 26893321, 64705764, 5276064 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1894938527423184, 1463213041477277, 474410505497651, + 247294963033299, 877975941029128 +#else + 30169808, 28236784, 26306205, 21803573, 27814963, 7069267, + 7152851, 3684982, 1449224, 13082861 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 207937160991127, 12966911039119, 820997788283092, + 1010440472205286, 1701372890140810 +#else + 10342807, 3098505, 2119311, 193222, 25702612, 12233820, + 23697382, 15056736, 46092426, 25352431 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 218882774543183, 533427444716285, 1233243976733245, + 435054256891319, 1509568989549904 +#else + 33958735, 3261607, 22745853, 7948688, 19370557, 18376767, + 40936887, 6482813, 56808784, 22494330 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1888838535711826, 1052177758340622, 1213553803324135, + 169182009127332, 463374268115872 +#else + 32869458, 28145887, 25609742, 15678670, 56421095, 18083360, + 26112420, 2521008, 44444576, 6904814 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 299137589460312, 1594371588983567, 868058494039073, + 257771590636681, 1805012993142921 +#else + 29506904, 4457497, 3377935, 23757988, 36598817, 12935079, + 1561737, 3841096, 38105225, 26896789 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1806842755664364, 2098896946025095, 1356630998422878, + 1458279806348064, 347755825962072 +#else + 10340844, 26924055, 48452231, 31276001, 12621150, 20215377, + 30878496, 21730062, 41524312, 5181965 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1402334161391744, 1560083671046299, 1008585416617747, + 1147797150908892, 1420416683642459 +#else + 25940096, 20896407, 17324187, 23247058, 58437395, 15029093, + 24396252, 17103510, 64786011, 21165857 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 665506704253369, 273770475169863, 799236974202630, + 848328990077558, 1811448782807931 +#else + 45343161, 9916822, 65808455, 4079497, 66080518, 11909558, + 1782390, 12641087, 20603771, 26992690 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1468412523962641, 771866649897997, 1931766110147832, + 799561180078482, 524837559150077 +#else + 48226577, 21881051, 24849421, 11501709, 13161720, 28785558, + 1925522, 11914390, 4662781, 7820689 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2223212657821850, 630416247363666, 2144451165500328, + 816911130947791, 1024351058410032 +#else + 12241050, 33128450, 8132690, 9393934, 32846760, 31954812, + 29749455, 12172924, 16136752, 15264020 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1266603897524861, 156378408858100, 1275649024228779, + 447738405888420, 253186462063095 +#else + 56758909, 18873868, 58896884, 2330219, 49446315, 19008651, + 10658212, 6671822, 19012087, 3772772 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2022215964509735, 136144366993649, 1800716593296582, + 1193970603800203, 871675847064218 +#else + 3753511, 30133366, 10617073, 2028709, 14841030, 26832768, + 28718731, 17791548, 20527770, 12988982 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1862751661970328, 851596246739884, 1519315554814041, + 1542798466547449, 1417975335901520 +#else + 52286360, 27757162, 63400876, 12689772, 66209881, 22639565, + 42925817, 22989488, 3299664, 21129479 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1228168094547481, 334133883362894, 587567568420081, + 433612590281181, 603390400373205 +#else + 50331161, 18301130, 57466446, 4978982, 3308785, 8755439, + 6943197, 6461331, 41525717, 8991217 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 121893973206505, 1843345804916664, 1703118377384911, + 497810164760654, 101150811654673 +#else + 49882601, 1816361, 65435576, 27467992, 31783887, 25378441, + 34160718, 7417949, 36866577, 1507264 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 458346255946468, 290909935619344, 1452768413850679, + 550922875254215, 1537286854336538 +#else + 29692644, 6829891, 56610064, 4334895, 20945975, 21647936, + 38221255, 8209390, 14606362, 22907359 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 584322311184395, 380661238802118, 114839394528060, + 655082270500073, 2111856026034852 +#else + 63627275, 8707080, 32188102, 5672294, 22096700, 1711240, + 34088169, 9761486, 4170404, 31469107 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 996965581008991, 2148998626477022, 1012273164934654, + 1073876063914522, 1688031788934939 +#else + 55521375, 14855944, 62981086, 32022574, 40459774, 15084045, + 22186522, 16002000, 52832027, 25153633 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 923487018849600, 2085106799623355, 528082801620136, + 1606206360876188, 735907091712524 +#else + 62297408, 13761028, 35404987, 31070512, 63796392, 7869046, + 59995292, 23934339, 13240844, 10965870 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1697697887804317, 1335343703828273, 831288615207040, + 949416685250051, 288760277392022 +#else + 59366301, 25297669, 52340529, 19898171, 43876480, 12387165, + 4498947, 14147411, 29514390, 4302863 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1419122478109648, 1325574567803701, 602393874111094, + 2107893372601700, 1314159682671307 +#else + 53695440, 21146572, 20757301, 19752600, 14785142, 8976368, + 62047588, 31410058, 17846987, 19582505 +#endif + }}, + }, + }, + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2201150872731804, 2180241023425241, 97663456423163, + 1633405770247824, 848945042443986 +#else + 64864412, 32799703, 62511833, 32488122, 60861691, 1455298, + 45461136, 24339642, 61886162, 12650266 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1173339555550611, 818605084277583, 47521504364289, + 924108720564965, 735423405754506 +#else + 57202067, 17484121, 21134159, 12198166, 40044289, 708125, + 387813, 13770293, 47974538, 10958662 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 830104860549448, 1886653193241086, 1600929509383773, + 1475051275443631, 286679780900937 +#else + 22470984, 12369526, 23446014, 28113323, 45588061, 23855708, + 55336367, 21979976, 42025033, 4271861 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1577111294832995, 1030899169768747, 144900916293530, + 1964672592979567, 568390100955250 +#else + 41939299, 23500789, 47199531, 15361594, 61124506, 2159191, + 75375, 29275903, 34582642, 8469672 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 278388655910247, 487143369099838, 927762205508727, + 181017540174210, 1616886700741287 +#else + 15854951, 4148314, 58214974, 7259001, 11666551, 13824734, + 36577666, 2697371, 24154791, 24093489 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1191033906638969, 940823957346562, 1606870843663445, + 861684761499847, 658674867251089 +#else + 15446137, 17747788, 29759746, 14019369, 30811221, 23944241, + 35526855, 12840103, 24913809, 9815020 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1875032594195546, 1427106132796197, 724736390962158, + 901860512044740, 635268497268760 +#else + 62399578, 27940162, 35267365, 21265538, 52665326, 10799413, + 58005188, 13438768, 18735128, 9466238 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 622869792298357, 1903919278950367, 1922588621661629, + 1520574711600434, 1087100760174640 +#else + 11933045, 9281483, 5081055, 28370608, 64480701, 28648802, + 59381042, 22658328, 44380208, 16199063 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 25465949416618, 1693639527318811, 1526153382657203, + 125943137857169, 145276964043999 +#else + 14576810, 379472, 40322331, 25237195, 37682355, 22741457, + 67006097, 1876698, 30801119, 2164795 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 214739857969358, 920212862967915, 1939901550972269, + 1211862791775221, 85097515720120 +#else + 15995086, 3199873, 13672555, 13712240, 47730029, 28906785, + 54027253, 18058162, 53616056, 1268051 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2006245852772938, 734762734836159, 254642929763427, + 1406213292755966, 239303749517686 +#else + 56818250, 29895392, 63822271, 10948817, 23037027, 3794475, + 63638526, 20954210, 50053494, 3565903 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1619678837192149, 1919424032779215, 1357391272956794, + 1525634040073113, 1310226789796241 +#else + 29210069, 24135095, 61189071, 28601646, 10834810, 20226706, + 50596761, 22733718, 39946641, 19523900 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1040763709762123, 1704449869235352, 605263070456329, + 1998838089036355, 1312142911487502 +#else + 53946955, 15508587, 16663704, 25398282, 38758921, 9019122, + 37925443, 29785008, 2244110, 19552453 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1996723311435669, 1844342766567060, 985455700466044, + 1165924681400960, 311508689870129 +#else + 61955989, 29753495, 57802388, 27482848, 16243068, 14684434, + 41435776, 17373631, 13491505, 4641841 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 43173156290518, 2202883069785309, 1137787467085917, + 1733636061944606, 1394992037553852 +#else + 10813398, 643330, 47920349, 32825515, 30292061, 16954354, + 27548446, 25833190, 14476988, 20787001 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 670078326344559, 555655025059356, 471959386282438, + 2141455487356409, 849015953823125 +#else + 10292079, 9984945, 6481436, 8279905, 59857350, 7032742, + 27282937, 31910173, 39196053, 12651323 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2197214573372804, 794254097241315, 1030190060513737, + 267632515541902, 2040478049202624 +#else + 35923332, 32741048, 22271203, 11835308, 10201545, 15351028, + 17099662, 3988035, 21721536, 30405492 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1812516004670529, 1609256702920783, 1706897079364493, + 258549904773295, 996051247540686 +#else + 10202177, 27008593, 35735631, 23979793, 34958221, 25434748, + 54202543, 3852693, 13216206, 14842320 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1540374301420584, 1764656898914615, 1810104162020396, + 923808779163088, 664390074196579 +#else + 51293224, 22953365, 60569911, 26295436, 60124204, 26972653, + 35608016, 13765823, 39674467, 9900183 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1323460699404750, 1262690757880991, 871777133477900, + 1060078894988977, 1712236889662886 +#else + 14465486, 19721101, 34974879, 18815558, 39665676, 12990491, + 33046193, 15796406, 60056998, 25514317 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1696163952057966, 1391710137550823, 608793846867416, + 1034391509472039, 1780770894075012 +#else + 30924398, 25274812, 6359015, 20738097, 16508376, 9071735, + 41620263, 15413634, 9524356, 26535554 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1367603834210841, 2131988646583224, 890353773628144, + 1908908219165595, 270836895252891 +#else + 12274201, 20378885, 32627640, 31769106, 6736624, 13267305, + 5237659, 28444949, 15663515, 4035784 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 597536315471731, 40375058742586, 1942256403956049, + 1185484645495932, 312666282024145 +#else + 64157555, 8903984, 17349946, 601635, 50676049, 28941875, + 53376124, 17665097, 44850385, 4659090 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1919411405316294, 1234508526402192, 1066863051997083, + 1008444703737597, 1348810787701552 +#else + 50192582, 28601458, 36715152, 18395610, 20774811, 15897498, + 5736189, 15026997, 64930608, 20098846 +#endif + }}, + }, + }, + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2102881477513865, 1570274565945361, 1573617900503708, + 18662635732583, 2232324307922098 +#else + 58249865, 31335375, 28571665, 23398914, 66634396, 23448733, + 63307367, 278094, 23440562, 33264224 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1853931367696942, 8107973870707, 350214504129299, + 775206934582587, 1752317649166792 +#else + 10226222, 27625730, 15139955, 120818, 52241171, 5218602, + 32937275, 11551483, 50536904, 26111567 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1417148368003523, 721357181628282, 505725498207811, + 373232277872983, 261634707184480 +#else + 17932739, 21117156, 43069306, 10749059, 11316803, 7535897, + 22503767, 5561594, 63462240, 3898660 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2186733281493267, 2250694917008620, 1014829812957440, + 479998161452389, 83566193876474 +#else + 7749907, 32584865, 50769132, 33537967, 42090752, 15122142, + 65535333, 7152529, 21831162, 1245233 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1268116367301224, 560157088142809, 802626839600444, + 2210189936605713, 1129993785579988 +#else + 26958440, 18896406, 4314585, 8346991, 61431100, 11960071, + 34519569, 32934396, 36706772, 16838219 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 615183387352312, 917611676109240, 878893615973325, + 978940963313282, 938686890583575 +#else + 54942968, 9166946, 33491384, 13673479, 29787085, 13096535, + 6280834, 14587357, 44770839, 13987524 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 522024729211672, 1045059315315808, 1892245413707790, + 1907891107684253, 2059998109500714 +#else + 42758936, 7778774, 21116000, 15572597, 62275598, 28196653, + 62807965, 28429792, 59639082, 30696363 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1799679152208884, 912132775900387, 25967768040979, + 432130448590461, 274568990261996 +#else + 9681908, 26817309, 35157219, 13591837, 60225043, 386949, + 31622781, 6439245, 52527852, 4091396 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 98698809797682, 2144627600856209, 1907959298569602, + 811491302610148, 1262481774981493 +#else + 58682418, 1470726, 38999185, 31957441, 3978626, 28430809, + 47486180, 12092162, 29077877, 18812444 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1791451399743152, 1713538728337276, 118349997257490, + 1882306388849954, 158235232210248 +#else + 5269168, 26694706, 53878652, 25533716, 25932562, 1763552, + 61502754, 28048550, 47091016, 2357888 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1217809823321928, 2173947284933160, 1986927836272325, + 1388114931125539, 12686131160169 +#else + 32264008, 18146780, 61721128, 32394338, 65017541, 29607531, + 23104803, 20684524, 5727337, 189038 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1650875518872272, 1136263858253897, 1732115601395988, + 734312880662190, 1252904681142109 +#else + 14609104, 24599962, 61108297, 16931650, 52531476, 25810533, + 40363694, 10942114, 41219933, 18669734 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 372986456113865, 525430915458171, 2116279931702135, + 501422713587815, 1907002872974925 +#else + 20513481, 5557931, 51504251, 7829530, 26413943, 31535028, + 45729895, 7471780, 13913677, 28416557 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 803147181835288, 868941437997146, 316299302989663, + 943495589630550, 571224287904572 +#else + 41534488, 11967825, 29233242, 12948236, 60354399, 4713226, + 58167894, 14059179, 12878652, 8511905 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 227742695588364, 1776969298667369, 628602552821802, + 457210915378118, 2041906378111140 +#else + 41452044, 3393630, 64153449, 26478905, 64858154, 9366907, + 36885446, 6812973, 5568676, 30426776 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 815000523470260, 913085688728307, 1052060118271173, + 1345536665214223, 541623413135555 +#else + 11630004, 12144454, 2116339, 13606037, 27378885, 15676917, + 49700111, 20050058, 52713667, 8070817 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1580216071604333, 1877997504342444, 857147161260913, + 703522726778478, 2182763974211603 +#else + 27117677, 23547054, 35826092, 27984343, 1127281, 12772488, + 37262958, 10483305, 55556115, 32525717 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1870080310923419, 71988220958492, 1783225432016732, + 615915287105016, 1035570475990230 +#else + 10637467, 27866368, 5674780, 1072708, 40765276, 26572129, + 65424888, 9177852, 39615702, 15431202 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 730987750830150, 857613889540280, 1083813157271766, + 1002817255970169, 1719228484436074 +#else + 20525126, 10892566, 54366392, 12779442, 37615830, 16150074, + 38868345, 14943141, 52052074, 25618500 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 377616581647602, 1581980403078513, 804044118130621, + 2034382823044191, 643844048472185 +#else + 37084402, 5626925, 66557297, 23573344, 753597, 11981191, + 25244767, 30314666, 63752313, 9594023 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 176957326463017, 1573744060478586, 528642225008045, + 1816109618372371, 1515140189765006 +#else + 43356201, 2636869, 61944954, 23450613, 585133, 7877383, + 11345683, 27062142, 13352334, 22577348 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1888911448245718, 1387110895611080, 1924503794066429, + 1731539523700949, 2230378382645454 +#else + 65177046, 28146973, 3304648, 20669563, 17015805, 28677341, + 37325013, 25801949, 53893326, 33235227 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 443392177002051, 233793396845137, 2199506622312416, + 1011858706515937, 974676837063129 +#else + 20239939, 6607058, 6203985, 3483793, 48721888, 32775202, + 46385121, 15077869, 44358105, 14523816 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1846351103143623, 1949984838808427, 671247021915253, + 1946756846184401, 1929296930380217 +#else + 27406023, 27512775, 27423595, 29057038, 4996213, 10002360, + 38266833, 29008937, 36936121, 28748764 +#endif + }}, + }, + }, + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 849646212452002, 1410198775302919, 73767886183695, + 1641663456615812, 762256272452411 +#else + 11374242, 12660715, 17861383, 21013599, 10935567, 1099227, + 53222788, 24462691, 39381819, 11358503 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 692017667358279, 723305578826727, 1638042139863265, + 748219305990306, 334589200523901 +#else + 54378055, 10311866, 1510375, 10778093, 64989409, 24408729, + 32676002, 11149336, 40985213, 4985767 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 22893968530686, 2235758574399251, 1661465835630252, + 925707319443452, 1203475116966621 +#else + 48012542, 341146, 60911379, 33315398, 15756972, 24757770, + 66125820, 13794113, 47694557, 17933176 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 801299035785166, 1733292596726131, 1664508947088596, + 467749120991922, 1647498584535623 +#else + 6490062, 11940286, 25495923, 25828072, 8668372, 24803116, + 3367602, 6970005, 65417799, 24549641 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 903105258014366, 427141894933047, 561187017169777, + 1884330244401954, 1914145708422219 +#else + 1656478, 13457317, 15370807, 6364910, 13605745, 8362338, + 47934242, 28078708, 50312267, 28522993 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1344191060517578, 1960935031767890, 1518838929955259, + 1781502350597190, 1564784025565682 +#else + 44835530, 20030007, 67044178, 29220208, 48503227, 22632463, + 46537798, 26546453, 67009010, 23317098 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 673723351748086, 1979969272514923, 1175287312495508, + 1187589090978666, 1881897672213940 +#else + 17747446, 10039260, 19368299, 29503841, 46478228, 17513145, + 31992682, 17696456, 37848500, 28042460 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1917185587363432, 1098342571752737, 5935801044414, + 2000527662351839, 1538640296181569 +#else + 31932008, 28568291, 47496481, 16366579, 22023614, 88450, + 11371999, 29810185, 4882241, 22927527 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2495540013192, 678856913479236, 224998292422872, + 219635787698590, 1972465269000940 +#else + 29796488, 37186, 19818052, 10115756, 55279832, 3352735, + 18551198, 3272828, 61917932, 29392022 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 271413961212179, 1353052061471651, 344711291283483, + 2014925838520662, 2006221033113941 +#else + 12501267, 4044383, 58495907, 20162046, 34678811, 5136598, + 47878486, 30024734, 330069, 29895023 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 194583029968109, 514316781467765, 829677956235672, + 1676415686873082, 810104584395840 +#else + 6384877, 2899513, 17807477, 7663917, 64749976, 12363164, + 25366522, 24980540, 66837568, 12071498 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1980510813313589, 1948645276483975, 152063780665900, + 129968026417582, 256984195613935 +#else + 58743349, 29511910, 25133447, 29037077, 60897836, 2265926, + 34339246, 1936674, 61949167, 3829362 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1860190562533102, 1936576191345085, 461100292705964, + 1811043097042830, 957486749306835 +#else + 28425966, 27718999, 66531773, 28857233, 52891308, 6870929, + 7921550, 26986645, 26333139, 14267664 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 796664815624365, 1543160838872951, 1500897791837765, + 1667315977988401, 599303877030711 +#else + 56041645, 11871230, 27385719, 22994888, 62522949, 22365119, + 10004785, 24844944, 45347639, 8930323 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1151480509533204, 2136010406720455, 738796060240027, + 319298003765044, 1150614464349587 +#else + 45911060, 17158396, 25654215, 31829035, 12282011, 11008919, + 1541940, 4757911, 40617363, 17145491 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1731069268103150, 735642447616087, 1364750481334268, + 417232839982871, 927108269127661 +#else + 13537262, 25794942, 46504023, 10961926, 61186044, 20336366, + 53952279, 6217253, 51165165, 13814989 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1017222050227968, 1987716148359, 2234319589635701, + 621282683093392, 2132553131763026 +#else + 49686272, 15157789, 18705543, 29619, 24409717, 33293956, + 27361680, 9257833, 65152338, 31777517 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1567828528453324, 1017807205202360, 565295260895298, + 829541698429100, 307243822276582 +#else + 42063564, 23362465, 15366584, 15166509, 54003778, 8423555, + 37937324, 12361134, 48422886, 4578289 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 249079270936248, 1501514259790706, 947909724204848, + 944551802437487, 552658763982480 +#else + 24579768, 3711570, 1342322, 22374306, 40103728, 14124955, + 44564335, 14074918, 21964432, 8235257 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2089966982947227, 1854140343916181, 2151980759220007, + 2139781292261749, 158070445864917 +#else + 60580251, 31142934, 9442965, 27628844, 12025639, 32067012, + 64127349, 31885225, 13006805, 2355433 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1338766321464554, 1906702607371284, 1519569445519894, + 115384726262267, 1393058953390992 +#else + 50803946, 19949172, 60476436, 28412082, 16974358, 22643349, + 27202043, 1719366, 1141648, 20758196 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1364621558265400, 1512388234908357, 1926731583198686, + 2041482526432505, 920401122333774 +#else + 54244920, 20334445, 58790597, 22536340, 60298718, 28710537, + 13475065, 30420460, 32674894, 13715045 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1884844597333588, 601480070269079, 620203503079537, + 1079527400117915, 1202076693132015 +#else + 11423316, 28086373, 32344215, 8962751, 24989809, 9241752, + 53843611, 16086211, 38367983, 17912338 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 840922919763324, 727955812569642, 1303406629750194, + 522898432152867, 294161410441865 +#else + 65699196, 12530727, 60740138, 10847386, 19531186, 19422272, + 55399715, 7791793, 39862921, 4383346 +#endif + }}, + }, + }, + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 353760790835310, 1598361541848743, 1122905698202299, + 1922533590158905, 419107700666580 +#else + 38137966, 5271446, 65842855, 23817442, 54653627, 16732598, + 62246457, 28647982, 27193556, 6245191 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 359856369838236, 180914355488683, 861726472646627, + 218807937262986, 575626773232501 +#else + 51914908, 5362277, 65324971, 2695833, 4960227, 12840725, + 23061898, 3260492, 22510453, 8577507 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 755467689082474, 909202735047934, 730078068932500, + 936309075711518, 2007798262842972 +#else + 54476394, 11257345, 34415870, 13548176, 66387860, 10879010, + 31168030, 13952092, 37537372, 29918525 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1609384177904073, 362745185608627, 1335318541768201, + 800965770436248, 547877979267412 +#else + 3877321, 23981693, 32416691, 5405324, 56104457, 19897796, + 3759768, 11935320, 5611860, 8164018 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 984339177776787, 815727786505884, 1645154585713747, + 1659074964378553, 1686601651984156 +#else + 50833043, 14667796, 15906460, 12155291, 44997715, 24514713, + 32003001, 24722143, 5773084, 25132323 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1697863093781930, 599794399429786, 1104556219769607, + 830560774794755, 12812858601017 +#else + 43320746, 25300131, 1950874, 8937633, 18686727, 16459170, + 66203139, 12376319, 31632953, 190926 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1168737550514982, 897832437380552, 463140296333799, + 302564600022547, 2008360505135501 +#else + 42515238, 17415546, 58684872, 13378745, 14162407, 6901328, + 58820115, 4508563, 41767309, 29926903 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1856930662813910, 678090852002597, 1920179140755167, + 1259527833759868, 55540971895511 +#else + 8884438, 27670423, 6023973, 10104341, 60227295, 28612898, + 18722940, 18768427, 65436375, 827624 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1158643631044921, 476554103621892, 178447851439725, + 1305025542653569, 103433927680625 +#else + 34388281, 17265135, 34605316, 7101209, 13354605, 2659080, + 65308289, 19446395, 42230385, 1541285 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2176793111709008, 1576725716350391, 2009350167273523, + 2012390194631546, 2125297410909580 +#else + 2901328, 32436745, 3880375, 23495044, 49487923, 29941650, + 45306746, 29986950, 20456844, 31669399 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 825403285195098, 2144208587560784, 1925552004644643, + 1915177840006985, 1015952128947864 +#else + 27019610, 12299467, 53450576, 31951197, 54247203, 28692960, + 47568713, 28538373, 29439640, 15138866 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1807108316634472, 1534392066433717, 347342975407218, + 1153820745616376, 7375003497471 +#else + 21536104, 26928012, 34661045, 22864223, 44700786, 5175813, + 61688824, 17193268, 7779327, 109896 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 983061001799725, 431211889901241, 2201903782961093, + 817393911064341, 2214616493042167 +#else + 30279725, 14648750, 59063993, 6425557, 13639621, 32810923, + 28698389, 12180118, 23177719, 33000357 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 228567918409756, 865093958780220, 358083886450556, + 159617889659320, 1360637926292598 +#else + 26572828, 3405927, 35407164, 12890904, 47843196, 5335865, + 60615096, 2378491, 4439158, 20275085 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 234147501399755, 2229469128637390, 2175289352258889, + 1397401514549353, 1885288963089922 +#else + 44392139, 3489069, 57883598, 33221678, 18875721, 32414337, + 14819433, 20822905, 49391106, 28092994 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1111762412951562, 252849572507389, 1048714233823341, + 146111095601446, 1237505378776770 +#else + 62052362, 16566550, 15953661, 3767752, 56672365, 15627059, + 66287910, 2177224, 8550082, 18440267 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1113790697840279, 1051167139966244, 1045930658550944, + 2011366241542643, 1686166824620755 +#else + 48635543, 16596774, 66727204, 15663610, 22860960, 15585581, + 39264755, 29971692, 43848403, 25125843 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1054097349305049, 1872495070333352, 182121071220717, + 1064378906787311, 100273572924182 +#else + 34628313, 15707274, 58902952, 27902350, 29464557, 2713815, + 44383727, 15860481, 45206294, 1494192 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1306410853171605, 1627717417672447, 50983221088417, + 1109249951172250, 870201789081392 +#else + 47546773, 19467038, 41524991, 24254879, 13127841, 759709, + 21923482, 16529112, 8742704, 12967017 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 104233794644221, 1548919791188248, 2224541913267306, + 2054909377116478, 1043803389015153 +#else + 38643965, 1553204, 32536856, 23080703, 42417258, 33148257, + 58194238, 30620535, 37205105, 15553882 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 216762189468802, 707284285441622, 190678557969733, + 973969342604308, 1403009538434867 +#else + 21877890, 3230008, 9881174, 10539357, 62311749, 2841331, + 11543572, 14513274, 19375923, 20906471 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1279024291038477, 344776835218310, 273722096017199, + 1834200436811442, 634517197663804 +#else + 8832269, 19058947, 13253510, 5137575, 5037871, 4078777, + 24880818, 27331716, 2862652, 9455043 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 343805853118335, 1302216857414201, 566872543223541, + 2051138939539004, 321428858384280 +#else + 29306751, 5123106, 20245049, 19404543, 9592565, 8447059, + 65031740, 30564351, 15511448, 4789663 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 470067171324852, 1618629234173951, 2000092177515639, + 7307679772789, 1117521120249968 +#else + 46429108, 7004546, 8824831, 24119455, 63063159, 29803695, + 61354101, 108892, 23513200, 16652362 +#endif + }}, + }, + }, + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 278151578291475, 1810282338562947, 1771599529530998, + 1383659409671631, 685373414471841 +#else + 33852691, 4144781, 62632835, 26975308, 10770038, 26398890, + 60458447, 20618131, 48789665, 10212859 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 577009397403102, 1791440261786291, 2177643735971638, + 174546149911960, 1412505077782326 +#else + 2756062, 8598110, 7383731, 26694540, 22312758, 32449420, + 21179800, 2600940, 57120566, 21047965 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 893719721537457, 1201282458018197, 1522349501711173, + 58011597740583, 1130406465887139 +#else + 42463153, 13317461, 36659605, 17900503, 21365573, 22684775, + 11344423, 864440, 64609187, 16844368 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 412607348255453, 1280455764199780, 2233277987330768, + 14180080401665, 331584698417165 +#else + 40676061, 6148328, 49924452, 19080277, 18782928, 33278435, + 44547329, 211299, 2719757, 4940997 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 262483770854550, 990511055108216, 526885552771698, + 571664396646158, 354086190278723 +#else + 65784982, 3911312, 60160120, 14759764, 37081714, 7851206, + 21690126, 8518463, 26699843, 5276295 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1820352417585487, 24495617171480, 1547899057533253, + 10041836186225, 480457105094042 +#else + 53958991, 27125364, 9396248, 365013, 24703301, 23065493, + 1321585, 149635, 51656090, 7159368 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2023310314989233, 637905337525881, 2106474638900687, + 557820711084072, 1687858215057826 +#else + 9987761, 30149673, 17507961, 9505530, 9731535, 31388918, + 22356008, 8312176, 22477218, 25151047 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1144168702609745, 604444390410187, 1544541121756138, + 1925315550126027, 626401428894002 +#else + 18155857, 17049442, 19744715, 9006923, 15154154, 23015456, + 24256459, 28689437, 44560690, 9334108 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1922168257351784, 2018674099908659, 1776454117494445, + 956539191509034, 36031129147635 +#else + 2986088, 28642539, 10776627, 30080588, 10620589, 26471229, + 45695018, 14253544, 44521715, 536905 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 544644538748041, 1039872944430374, 876750409130610, + 710657711326551, 1216952687484972 +#else + 4377737, 8115836, 24567078, 15495314, 11625074, 13064599, + 7390551, 10589625, 10838060, 18134008 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 58242421545916, 2035812695641843, 2118491866122923, + 1191684463816273, 46921517454099 +#else + 47766460, 867879, 9277171, 30335973, 52677291, 31567988, + 19295825, 17757482, 6378259, 699185 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 272268252444639, 1374166457774292, 2230115177009552, + 1053149803909880, 1354288411641016 +#else + 7895007, 4057113, 60027092, 20476675, 49222032, 33231305, + 66392824, 15693154, 62063800, 20180469 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1857910905368338, 1754729879288912, 885945464109877, + 1516096106802166, 1602902393369811 +#else + 59371282, 27685029, 52542544, 26147512, 11385653, 13201616, + 31730678, 22591592, 63190227, 23885106 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1193437069800958, 901107149704790, 999672920611411, + 477584824802207, 364239578697845 +#else + 10188286, 17783598, 59772502, 13427542, 22223443, 14896287, + 30743455, 7116568, 45322357, 5427592 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 886299989548838, 1538292895758047, 1590564179491896, + 1944527126709657, 837344427345298 +#else + 696102, 13206899, 27047647, 22922350, 15285304, 23701253, + 10798489, 28975712, 19236242, 12477404 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 754558365378305, 1712186480903618, 1703656826337531, + 750310918489786, 518996040250900 +#else + 55879425, 11243795, 50054594, 25513566, 66320635, 25386464, + 63211194, 11180503, 43939348, 7733643 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1309847803895382, 1462151862813074, 211370866671570, + 1544595152703681, 1027691798954090 +#else + 17800790, 19518253, 40108434, 21787760, 23887826, 3149671, + 23466177, 23016261, 10322026, 15313801 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 803217563745370, 1884799722343599, 1357706345069218, + 2244955901722095, 730869460037413 +#else + 26246234, 11968874, 32263343, 28085704, 6830754, 20231401, + 51314159, 33452449, 42659621, 10890803 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 689299471295966, 1831210565161071, 1375187341585438, + 1106284977546171, 1893781834054269 +#else + 35743198, 10271362, 54448239, 27287163, 16690206, 20491888, + 52126651, 16484930, 25180797, 28219548 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 696351368613042, 1494385251239250, 738037133616932, + 636385507851544, 927483222611406 +#else + 66522290, 10376443, 34522450, 22268075, 19801892, 10997610, + 2276632, 9482883, 316878, 13820577 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1949114198209333, 1104419699537997, 783495707664463, + 1747473107602770, 2002634765788641 +#else + 57226037, 29044064, 64993357, 16457135, 56008783, 11674995, + 30756178, 26039378, 30696929, 29841583 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1607325776830197, 530883941415333, 1451089452727895, + 1581691157083423, 496100432831154 +#else + 32988917, 23951020, 12499365, 7910787, 56491607, 21622917, + 59766047, 23569034, 34759346, 7392472 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1068900648804224, 2006891997072550, 1134049269345549, + 1638760646180091, 2055396084625778 +#else + 58253184, 15927860, 9866406, 29905021, 64711949, 16898650, + 36699387, 24419436, 25112946, 30627788 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2222475519314561, 1870703901472013, 1884051508440561, + 1344072275216753, 1318025677799069 +#else + 64604801, 33117465, 25621773, 27875660, 15085041, 28074555, + 42223985, 20028237, 5537437, 19640113 +#endif + }}, + }, + }, + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 155711679280656, 681100400509288, 389811735211209, + 2135723811340709, 408733211204125 +#else + 55883280, 2320284, 57524584, 10149186, 33664201, 5808647, + 52232613, 31824764, 31234589, 6090599 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 7813206966729, 194444201427550, 2071405409526507, + 1065605076176312, 1645486789731291 +#else + 57475529, 116425, 26083934, 2897444, 60744427, 30866345, 609720, + 15878753, 60138459, 24519663 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 16625790644959, 1647648827778410, 1579910185572704, + 436452271048548, 121070048451050 +#else + 39351007, 247743, 51914090, 24551880, 23288160, 23542496, + 43239268, 6503645, 20650474, 1804084 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1037263028552531, 568385780377829, 297953104144430, + 1558584511931211, 2238221839292471 +#else + 39519059, 15456423, 8972517, 8469608, 15640622, 4439847, + 3121995, 23224719, 27842615, 33352104 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 190565267697443, 672855706028058, 338796554369226, + 337687268493904, 853246848691734 +#else + 51801891, 2839643, 22530074, 10026331, 4602058, 5048462, + 28248656, 5031932, 55733782, 12714368 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1763863028400139, 766498079432444, 1321118624818005, + 69494294452268, 858786744165651 +#else + 20807691, 26283607, 29286140, 11421711, 39232341, 19686201, + 45881388, 1035545, 47375635, 12796919 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1292056768563024, 1456632109855638, 1100631247050184, + 1386133165675321, 1232898350193752 +#else + 12076880, 19253146, 58323862, 21705509, 42096072, 16400683, + 49517369, 20654993, 3480664, 18371617 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 366253102478259, 525676242508811, 1449610995265438, + 1183300845322183, 185960306491545 +#else + 34747315, 5457596, 28548107, 7833186, 7303070, 21600887, + 42745799, 17632556, 33734809, 2771024 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 28315355815982, 460422265558930, 1799675876678724, + 1969256312504498, 1051823843138725 +#else + 45719598, 421931, 26597266, 6860826, 22486084, 26817260, + 49971378, 29344205, 42556581, 15673396 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 156914999361983, 1606148405719949, 1665208410108430, + 317643278692271, 1383783705665320 +#else + 46924223, 2338215, 19788685, 23933476, 63107598, 24813538, + 46837679, 4733253, 3727144, 20619984 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 54684536365732, 2210010038536222, 1194984798155308, + 535239027773705, 1516355079301361 +#else + 6120100, 814863, 55314462, 32931715, 6812204, 17806661, 2019593, + 7975683, 31123697, 22595451 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1484387703771650, 198537510937949, 2186282186359116, + 617687444857508, 647477376402122 +#else + 30069250, 22119100, 30434653, 2958439, 18399564, 32578143, + 12296868, 9204260, 50676426, 9648164 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2147715541830533, 500032538445817, 646380016884826, + 352227855331122, 1488268620408052 +#else + 32705413, 32003455, 30705657, 7451065, 55303258, 9631812, + 3305266, 5248604, 41100532, 22176930 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 159386186465542, 1877626593362941, 618737197060512, + 1026674284330807, 1158121760792685 +#else + 17219846, 2375039, 35537917, 27978816, 47649184, 9219902, + 294711, 15298639, 2662509, 17257359 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1744544377739822, 1964054180355661, 1685781755873170, + 2169740670377448, 1286112621104591 +#else + 65935918, 25995736, 62742093, 29266687, 45762450, 25120105, + 32087528, 32331655, 32247247, 19164571 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 81977249784993, 1667943117713086, 1668983819634866, + 1605016835177615, 1353960708075544 +#else + 14312609, 1221556, 17395390, 24854289, 62163122, 24869796, + 38911119, 23916614, 51081240, 20175586 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1602253788689063, 439542044889886, 2220348297664483, + 657877410752869, 157451572512238 +#else + 65680039, 23875441, 57873182, 6549686, 59725795, 33085767, + 23046501, 9803137, 17597934, 2346211 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1029287186166717, 65860128430192, 525298368814832, + 1491902500801986, 1461064796385400 +#else + 18510781, 15337574, 26171504, 981392, 44867312, 7827555, + 43617730, 22231079, 3059832, 21771562 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 408216988729246, 2121095722306989, 913562102267595, + 1879708920318308, 241061448436731 +#else + 10141598, 6082907, 17829293, 31606789, 9830091, 13613136, + 41552228, 28009845, 33606651, 3592095 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1185483484383269, 1356339572588553, 584932367316448, + 102132779946470, 1792922621116791 +#else + 33114149, 17665080, 40583177, 20211034, 33076704, 8716171, + 1151462, 1521897, 66126199, 26716628 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1966196870701923, 2230044620318636, 1425982460745905, + 261167817826569, 46517743394330 +#else + 34169699, 29298616, 23947180, 33230254, 34035889, 21248794, + 50471177, 3891703, 26353178, 693168 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 107077591595359, 884959942172345, 27306869797400, + 2224911448949390, 964352058245223 +#else + 30374239, 1595580, 50224825, 13186930, 4600344, 406904, 9585294, + 33153764, 31375463, 14369965 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1730194207717538, 431790042319772, 1831515233279467, + 1372080552768581, 1074513929381760 +#else + 52738210, 25781902, 1510300, 6434173, 48324075, 27291703, + 32732229, 20445593, 17901440, 16011505 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1450880638731607, 1019861580989005, 1229729455116861, + 1174945729836143, 826083146840706 +#else + 18171223, 21619806, 54608461, 15197121, 56070717, 18324396, + 47936623, 17508055, 8764034, 12309598 +#endif + }}, + }, + }, + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1899935429242705, 1602068751520477, 940583196550370, + 82431069053859, 1540863155745696 +#else + 5975889, 28311244, 47649501, 23872684, 55567586, 14015781, + 43443107, 1228318, 17544096, 22960650 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2136688454840028, 2099509000964294, 1690800495246475, + 1217643678575476, 828720645084218 +#else + 5811932, 31839139, 3442886, 31285122, 48741515, 25194890, + 49064820, 18144304, 61543482, 12348899 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 765548025667841, 462473984016099, 998061409979798, + 546353034089527, 2212508972466858 +#else + 35709185, 11407554, 25755363, 6891399, 63851926, 14872273, + 42259511, 8141294, 56476330, 32968952 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 46575283771160, 892570971573071, 1281983193144090, + 1491520128287375, 75847005908304 +#else + 54433560, 694025, 62032719, 13300343, 14015258, 19103038, + 57410191, 22225381, 30944592, 1130208 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1801436127943107, 1734436817907890, 1268728090345068, + 167003097070711, 2233597765834956 +#else + 8247747, 26843490, 40546482, 25845122, 52706924, 18905521, + 4652151, 2488540, 23550156, 33283200 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1997562060465113, 1048700225534011, 7615603985628, + 1855310849546841, 2242557647635213 +#else + 17294297, 29765994, 7026747, 15626851, 22990044, 113481, + 2267737, 27646286, 66700045, 33416712 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1161017320376250, 492624580169043, 2169815802355237, + 976496781732542, 1770879511019629 +#else + 16091066, 17300506, 18599251, 7340678, 2137637, 32332775, + 63744702, 14550935, 3260525, 26388161 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1357044908364776, 729130645262438, 1762469072918979, + 1365633616878458, 181282906404941 +#else + 62198760, 20221544, 18550886, 10864893, 50649539, 26262835, + 44079994, 20349526, 54360141, 2701325 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1080413443139865, 1155205815510486, 1848782073549786, + 622566975152580, 124965574467971 +#else + 58534169, 16099414, 4629974, 17213908, 46322650, 27548999, + 57090500, 9276970, 11329923, 1862132 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1184526762066993, 247622751762817, 692129017206356, + 820018689412496, 2188697339828085 +#else + 14763057, 17650824, 36190593, 3689866, 3511892, 10313526, + 45157776, 12219230, 58070901, 32614131 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2020536369003019, 202261491735136, 1053169669150884, + 2056531979272544, 778165514694311 +#else + 8894987, 30108338, 6150752, 3013931, 301220, 15693451, 35127648, + 30644714, 51670695, 11595569 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 237404399610207, 1308324858405118, 1229680749538400, + 720131409105291, 1958958863624906 +#else + 15214943, 3537601, 40870142, 19495559, 4418656, 18323671, + 13947275, 10730794, 53619402, 29190761 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 515583508038846, 17656978857189, 1717918437373989, + 1568052070792483, 46975803123923 +#else + 64570558, 7682792, 32759013, 263109, 37124133, 25598979, + 44776739, 23365796, 977107, 699994 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 281527309158085, 36970532401524, 866906920877543, + 2222282602952734, 1289598729589882 +#else + 54642373, 4195083, 57897332, 550903, 51543527, 12917919, + 19118110, 33114591, 36574330, 19216518 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1278207464902042, 494742455008756, 1262082121427081, + 1577236621659884, 1888786707293291 +#else + 31788442, 19046775, 4799988, 7372237, 8808585, 18806489, + 9408236, 23502657, 12493931, 28145115 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 353042527954210, 1830056151907359, 1111731275799225, + 174960955838824, 404312815582675 +#else + 41428258, 5260743, 47873055, 27269961, 63412921, 16566086, + 27218280, 2607121, 29375955, 6024730 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2064251142068628, 1666421603389706, 1419271365315441, + 468767774902855, 191535130366583 +#else + 842132, 30759739, 62345482, 24831616, 26332017, 21148791, + 11831879, 6985184, 57168503, 2854095 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1716987058588002, 1859366439773457, 1767194234188234, + 64476199777924, 1117233614485261 +#else + 62261602, 25585100, 2516241, 27706719, 9695690, 26333246, + 16512644, 960770, 12121869, 16648078 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 984292135520292, 135138246951259, 2220652137473167, + 1722843421165029, 190482558012909 +#else + 51890212, 14667095, 53772635, 2013716, 30598287, 33090295, + 35603941, 25672367, 20237805, 2838411 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 298845952651262, 1166086588952562, 1179896526238434, + 1347812759398693, 1412945390096208 +#else + 47820798, 4453151, 15298546, 17376044, 22115042, 17581828, + 12544293, 20083975, 1068880, 21054527 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1143239552672925, 906436640714209, 2177000572812152, + 2075299936108548, 325186347798433 +#else + 57549981, 17035596, 33238497, 13506958, 30505848, 32439836, + 58621956, 30924378, 12521377, 4845654 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 721024854374772, 684487861263316, 1373438744094159, + 2193186935276995, 1387043709851261 +#else + 38910324, 10744107, 64150484, 10199663, 7759311, 20465832, + 3409347, 32681032, 60626557, 20668561 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 418098668140962, 715065997721283, 1471916138376055, + 2168570337288357, 937812682637044 +#else + 43547042, 6230155, 46726851, 10655313, 43068279, 21933259, + 10477733, 32314216, 63995636, 13974497 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1043584187226485, 2143395746619356, 2209558562919611, + 482427979307092, 847556718384018 +#else + 12966261, 15550616, 35069916, 31939085, 21025979, 32924988, + 5642324, 7188737, 18895762, 12629579 +#endif + }}, + }, + }, + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1248731221520759, 1465200936117687, 540803492710140, + 52978634680892, 261434490176109 +#else + 14741879, 18607545, 22177207, 21833195, 1279740, 8058600, + 11758140, 789443, 32195181, 3895677 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1057329623869501, 620334067429122, 461700859268034, + 2012481616501857, 297268569108938 +#else + 10758205, 15755439, 62598914, 9243697, 62229442, 6879878, + 64904289, 29988312, 58126794, 4429646 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1055352180870759, 1553151421852298, 1510903185371259, + 1470458349428097, 1226259419062731 +#else + 64654951, 15725972, 46672522, 23143759, 61304955, 22514211, + 59972993, 21911536, 18047435, 18272689 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1492988790301668, 790326625573331, 1190107028409745, + 1389394752159193, 1620408196604194 +#else + 41935844, 22247266, 29759955, 11776784, 44846481, 17733976, + 10993113, 20703595, 49488162, 24145963 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 47000654413729, 1004754424173864, 1868044813557703, + 173236934059409, 588771199737015 +#else + 21987233, 700364, 42603816, 14972007, 59334599, 27836036, + 32155025, 2581431, 37149879, 8773374 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 30498470091663, 1082245510489825, 576771653181956, + 806509986132686, 1317634017056939 +#else + 41540495, 454462, 53896929, 16126714, 25240068, 8594567, + 20656846, 12017935, 59234475, 19634276 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 420308055751555, 1493354863316002, 165206721528088, + 1884845694919786, 2065456951573059 +#else + 6028163, 6263078, 36097058, 22252721, 66289944, 2461771, + 35267690, 28086389, 65387075, 30777706 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1115636332012334, 1854340990964155, 83792697369514, + 1972177451994021, 457455116057587 +#else + 54829870, 16624276, 987579, 27631834, 32908202, 1248608, + 7719845, 29387734, 28408819, 6816612 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1698968457310898, 1435137169051090, 1083661677032510, + 938363267483709, 340103887207182 +#else + 56750770, 25316602, 19549650, 21385210, 22082622, 16147817, + 20613181, 13982702, 56769294, 5067942 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1995325341336574, 911500251774648, 164010755403692, + 855378419194762, 1573601397528842 +#else + 36602878, 29732664, 12074680, 13582412, 47230892, 2443950, + 47389578, 12746131, 5331210, 23448488 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 241719380661528, 310028521317150, 1215881323380194, + 1408214976493624, 2141142156467363 +#else + 30528792, 3601899, 65151774, 4619784, 39747042, 18118043, + 24180792, 20984038, 27679907, 31905504 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1315157046163473, 727368447885818, 1363466668108618, + 1668921439990361, 1398483384337907 +#else + 9402385, 19597367, 32834042, 10838634, 40528714, 20317236, + 26653273, 24868867, 22611443, 20839026 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 75029678299646, 1015388206460473, 1849729037055212, + 1939814616452984, 444404230394954 +#else + 22190590, 1118029, 22736441, 15130463, 36648172, 27563110, + 19189624, 28905490, 4854858, 6622139 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2053597130993710, 2024431685856332, 2233550957004860, + 2012407275509545, 872546993104440 +#else + 58798126, 30600981, 58846284, 30166382, 56707132, 33282502, + 13424425, 29987205, 26404408, 13001963 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1217269667678610, 599909351968693, 1390077048548598, + 1471879360694802, 739586172317596 +#else + 35867026, 18138731, 64114613, 8939345, 11562230, 20713762, + 41044498, 21932711, 51703708, 11020692 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1718318639380794, 1560510726633958, 904462881159922, + 1418028351780052, 94404349451937 +#else + 1866042, 25604943, 59210214, 23253421, 12483314, 13477547, + 3175636, 21130269, 28761761, 1406734 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2132502667405250, 214379346175414, 1502748313768060, + 1960071701057800, 1353971822643138 +#else + 66660290, 31776765, 13018550, 3194501, 57528444, 22392694, + 24760584, 29207344, 25577410, 20175752 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 319394212043702, 2127459436033571, 717646691535162, + 663366796076914, 318459064945314 +#else + 42818486, 4759344, 66418211, 31701615, 2066746, 10693769, + 37513074, 9884935, 57739938, 4745409 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 405989424923593, 1960452633787083, 667349034401665, + 1492674260767112, 1451061489880787 +#else + 57967561, 6049713, 47577803, 29213020, 35848065, 9944275, + 51646856, 22242579, 10931923, 21622501 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 947085906234007, 323284730494107, 1485778563977200, + 728576821512394, 901584347702286 +#else + 50547351, 14112679, 59096219, 4817317, 59068400, 22139825, + 44255434, 10856640, 46638094, 13434653 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1575783124125742, 2126210792434375, 1569430791264065, + 1402582372904727, 1891780248341114 +#else + 22759470, 23480998, 50342599, 31683009, 13637441, 23386341, + 1765143, 20900106, 28445306, 28189722 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 838432205560695, 1997703511451664, 1018791879907867, + 1662001808174331, 78328132957753 +#else + 29875063, 12493613, 2795536, 29768102, 1710619, 15181182, + 56913147, 24765756, 9074233, 1167180 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 739152638255629, 2074935399403557, 505483666745895, + 1611883356514088, 628654635394878 +#else + 40903181, 11014232, 57266213, 30918946, 40200743, 7532293, + 48391976, 24018933, 3843902, 9367684 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1822054032121349, 643057948186973, 7306757352712, + 577249257962099, 284735863382083 +#else + 56139269, 27150720, 9591133, 9582310, 11349256, 108879, + 16235123, 8601684, 66969667, 4242894 +#endif + }}, + }, + }, + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1366558556363930, 1448606567552086, 1478881020944768, + 165803179355898, 1115718458123498 +#else + 22092954, 20363309, 65066070, 21585919, 32186752, 22037044, + 60534522, 2470659, 39691498, 16625500 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 204146226972102, 1630511199034723, 2215235214174763, + 174665910283542, 956127674017216 +#else + 56051142, 3042015, 13770083, 24296510, 584235, 33009577, + 59338006, 2602724, 39757248, 14247412 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1562934578796716, 1070893489712745, 11324610642270, + 958989751581897, 2172552325473805 +#else + 6314156, 23289540, 34336361, 15957556, 56951134, 168749, + 58490057, 14290060, 27108877, 32373552 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1770564423056027, 735523631664565, 1326060113795289, + 1509650369341127, 65892421582684 +#else + 58522267, 26383465, 13241781, 10960156, 34117849, 19759835, + 33547975, 22495543, 39960412, 981873 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 623682558650637, 1337866509471512, 990313350206649, + 1314236615762469, 1164772974270275 +#else + 22833421, 9293594, 34459416, 19935764, 57971897, 14756818, + 44180005, 19583651, 56629059, 17356469 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 223256821462517, 723690150104139, 1000261663630601, + 933280913953265, 254872671543046 +#else + 59340277, 3326785, 38997067, 10783823, 19178761, 14905060, + 22680049, 13906969, 51175174, 3797898 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1969087237026041, 624795725447124, 1335555107635969, + 2069986355593023, 1712100149341902 +#else + 21721337, 29341686, 54902740, 9310181, 63226625, 19901321, + 23740223, 30845200, 20491982, 25512280 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1236103475266979, 1837885883267218, 1026072585230455, + 1025865513954973, 1801964901432134 +#else + 9209251, 18419377, 53852306, 27386633, 66377847, 15289672, + 25947805, 15286587, 30997318, 26851369 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1115241013365517, 1712251818829143, 2148864332502771, + 2096001471438138, 2235017246626125 +#else + 7392013, 16618386, 23946583, 25514540, 53843699, 32020573, + 52911418, 31232855, 17649997, 33304352 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1299268198601632, 2047148477845621, 2165648650132450, + 1612539282026145, 514197911628890 +#else + 57807776, 19360604, 30609525, 30504889, 41933794, 32270679, + 51867297, 24028707, 64875610, 7662145 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 118352772338543, 1067608711804704, 1434796676193498, + 1683240170548391, 230866769907437 +#else + 49550191, 1763593, 33994528, 15908609, 37067994, 21380136, + 7335079, 25082233, 63934189, 3440182 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1850689576796636, 1601590730430274, 1139674615958142, + 1954384401440257, 76039205311 +#else + 47219164, 27577423, 42997570, 23865561, 10799742, 16982475, + 40449, 29122597, 4862399, 1133 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1723387471374172, 997301467038410, 533927635123657, + 20928644693965, 1756575222802513 +#else + 34252636, 25680474, 61686474, 14860949, 50789833, 7956141, + 7258061, 311861, 36513873, 26175010 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2146711623855116, 503278928021499, 625853062251406, + 1109121378393107, 1033853809911861 +#else + 63335436, 31988495, 28985339, 7499440, 24445838, 9325937, + 29727763, 16527196, 18278453, 15405622 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 571005965509422, 2005213373292546, 1016697270349626, + 56607856974274, 914438579435146 +#else + 62726958, 8508651, 47210498, 29880007, 61124410, 15149969, + 53795266, 843522, 45233802, 13626196 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1346698876211176, 2076651707527589, 1084761571110205, + 265334478828406, 1068954492309671 +#else + 2281448, 20067377, 56193445, 30944521, 1879357, 16164207, + 56324982, 3953791, 13340839, 15928663 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1769967932677654, 1695893319756416, 1151863389675920, + 1781042784397689, 400287774418285 +#else + 31727126, 26374577, 48671360, 25270779, 2875792, 17164102, + 41838969, 26539605, 43656557, 5964752 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1851867764003121, 403841933237558, 820549523771987, + 761292590207581, 1743735048551143 +#else + 4100401, 27594980, 49929526, 6017713, 48403027, 12227140, + 40424029, 11344143, 2538215, 25983677 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 410915148140008, 2107072311871739, 1004367461876503, + 99684895396761, 1180818713503224 +#else + 57675240, 6123112, 11159803, 31397824, 30016279, 14966241, + 46633881, 1485420, 66479608, 17595569 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 285945406881439, 648174397347453, 1098403762631981, + 1366547441102991, 1505876883139217 +#else + 40304287, 4260918, 11851389, 9658551, 35091757, 16367491, + 46903439, 20363143, 11659921, 22439314 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 672095903120153, 1675918957959872, 636236529315028, + 1569297300327696, 2164144194785875 +#else + 26180377, 10015009, 36264640, 24973138, 5418196, 9480663, + 2231568, 23384352, 33100371, 32248261 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1902708175321798, 1035343530915438, 1178560808893263, + 301095684058146, 1280977479761118 +#else + 15121094, 28352561, 56718958, 15427820, 39598927, 17561924, + 21670946, 4486675, 61177054, 19088051 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1615357281742403, 404257611616381, 2160201349780978, + 1160947379188955, 1578038619549541 +#else + 16166467, 24070699, 56004733, 6023907, 35182066, 32189508, + 2340059, 17299464, 56373093, 23514607 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2013087639791217, 822734930507457, 1785668418619014, + 1668650702946164, 389450875221715 +#else + 28042865, 29997343, 54982337, 12259705, 63391366, 26608532, + 6766452, 24864833, 18036435, 5803270 +#endif + }}, + }, + }, + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 453918449698368, 106406819929001, 2072540975937135, + 308588860670238, 1304394580755385 +#else + 66291264, 6763911, 11803561, 1585585, 10958447, 30883267, + 23855390, 4598332, 60949433, 19436993 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1295082798350326, 2091844511495996, 1851348972587817, + 3375039684596, 789440738712837 +#else + 36077558, 19298237, 17332028, 31170912, 31312681, 27587249, + 696308, 50292, 47013125, 11763583 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2083069137186154, 848523102004566, 993982213589257, + 1405313299916317, 1532824818698468 +#else + 66514282, 31040148, 34874710, 12643979, 12650761, 14811489, + 665117, 20940800, 47335652, 22840869 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1495961298852430, 1397203457344779, 1774950217066942, + 139302743555696, 66603584342787 +#else + 30464590, 22291560, 62981387, 20819953, 19835326, 26448819, + 42712688, 2075772, 50088707, 992470 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1782411379088302, 1096724939964781, 27593390721418, + 542241850291353, 1540337798439873 +#else + 18357166, 26559999, 7766381, 16342475, 37783946, 411173, + 14578841, 8080033, 55534529, 22952821 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 693543956581437, 171507720360750, 1557908942697227, + 1074697073443438, 1104093109037196 +#else + 19598397, 10334610, 12555054, 2555664, 18821899, 23214652, + 21873262, 16014234, 26224780, 16452269 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 345288228393419, 1099643569747172, 134881908403743, + 1740551994106740, 248212179299770 +#else + 36884939, 5145195, 5944548, 16385966, 3976735, 2009897, + 55731060, 25936245, 46575034, 3698649 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 231429562203065, 1526290236421172, 2021375064026423, + 1520954495658041, 806337791525116 +#else + 14187449, 3448569, 56472628, 22743496, 44444983, 30120835, + 7268409, 22663988, 27394300, 12015369 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1079623667189886, 872403650198613, 766894200588288, + 2163700860774109, 2023464507911816 +#else + 19695742, 16087646, 28032085, 12999827, 6817792, 11427614, + 20244189, 32241655, 53849736, 30151970 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 854645372543796, 1936406001954827, 151460662541253, + 825325739271555, 1554306377287556 +#else + 30860084, 12735208, 65220619, 28854697, 50133957, 2256939, + 58942851, 12298311, 58558340, 23160969 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1497138821904622, 1044820250515590, 1742593886423484, + 1237204112746837, 849047450816987 +#else + 61389038, 22309106, 65198214, 15569034, 26642876, 25966672, + 61319509, 18435777, 62132699, 12651792 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 667962773375330, 1897271816877105, 1399712621683474, + 1143302161683099, 2081798441209593 +#else + 64260450, 9953420, 11531313, 28271553, 26895122, 20857343, + 53990043, 17036529, 9768697, 31021214 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 127147851567005, 1936114012888110, 1704424366552046, + 856674880716312, 716603621335359 +#else + 42389405, 1894650, 66821166, 28850346, 15348718, 25397902, + 32767512, 12765450, 4940095, 10678226 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1072409664800960, 2146937497077528, 1508780108920651, + 935767602384853, 1112800433544068 +#else + 18860224, 15980149, 48121624, 31991861, 40875851, 22482575, + 59264981, 13944023, 42736516, 16582018 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 333549023751292, 280219272863308, 2104176666454852, + 1036466864875785, 536135186520207 +#else + 51604604, 4970267, 37215820, 4175592, 46115652, 31354675, + 55404809, 15444559, 56105103, 7989036 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 373666279883137, 146457241530109, 304116267127857, + 416088749147715, 1258577131183391 +#else + 31490433, 5568061, 64696061, 2182382, 34772017, 4531685, + 35030595, 6200205, 47422751, 18754260 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1186115062588401, 2251609796968486, 1098944457878953, + 1153112761201374, 1791625503417267 +#else + 49800177, 17674491, 35586086, 33551600, 34221481, 16375548, + 8680158, 17182719, 28550067, 26697300 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1870078460219737, 2129630962183380, 852283639691142, + 292865602592851, 401904317342226 +#else + 38981977, 27866340, 16837844, 31733974, 60258182, 12700015, + 37068883, 4364037, 1155602, 5988841 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1361070124828035, 815664541425524, 1026798897364671, + 1951790935390647, 555874891834790 +#else + 21890435, 20281525, 54484852, 12154348, 59276991, 15300495, + 23148983, 29083951, 24618406, 8283181 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1546301003424277, 459094500062839, 1097668518375311, + 1780297770129643, 720763293687608 +#else + 33972757, 23041680, 9975415, 6841041, 35549071, 16356535, + 3070187, 26528504, 1466168, 10740210 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1212405311403990, 1536693382542438, 61028431067459, + 1863929423417129, 1223219538638038 +#else + 65599446, 18066246, 53605478, 22898515, 32799043, 909394, + 53169961, 27774712, 34944214, 18227391 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1294303766540260, 1183557465955093, 882271357233093, + 63854569425375, 2213283684565087 +#else + 3960804, 19286629, 39082773, 17636380, 47704005, 13146867, + 15567327, 951507, 63848543, 32980496 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 339050984211414, 601386726509773, 413735232134068, + 966191255137228, 1839475899458159 +#else + 24740822, 5052253, 37014733, 8961360, 25877428, 6165135, + 42740684, 14397371, 59728495, 27410326 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 235605972169408, 2174055643032978, 1538335001838863, + 1281866796917192, 1815940222628465 +#else + 38220480, 3510802, 39005586, 32395953, 55870735, 22922977, + 51667400, 19101303, 65483377, 27059617 +#endif + }}, + }, + }, + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1632352921721536, 1833328609514701, 2092779091951987, + 1923956201873226, 2210068022482919 +#else + 793280, 24323954, 8836301, 27318725, 39747955, 31184838, + 33152842, 28669181, 57202663, 32932579 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 35271216625062, 1712350667021807, 983664255668860, + 98571260373038, 1232645608559836 +#else + 5666214, 525582, 20782575, 25516013, 42570364, 14657739, + 16099374, 1468826, 60937436, 18367850 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1998172393429622, 1798947921427073, 784387737563581, + 1589352214827263, 1589861734168180 +#else + 62249590, 29775088, 64191105, 26806412, 7778749, 11688288, + 36704511, 23683193, 65549940, 23690785 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1733739258725305, 31715717059538, 201969945218860, + 992093044556990, 1194308773174556 +#else + 10896313, 25834728, 824274, 472601, 47648556, 3009586, 25248958, + 14783338, 36527388, 17796587 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 846415389605137, 746163495539180, 829658752826080, + 592067705956946, 957242537821393 +#else + 10566929, 12612572, 35164652, 11118702, 54475488, 12362878, + 21752402, 8822496, 24003793, 14264025 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1758148849754419, 619249044817679, 168089007997045, + 1371497636330523, 1867101418880350 +#else + 27713843, 26198459, 56100623, 9227529, 27050101, 2504721, + 23886875, 20436907, 13958494, 27821979 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 326633984209635, 261759506071016, 1700682323676193, + 1577907266349064, 1217647663383016 +#else + 43627235, 4867225, 39861736, 3900520, 29838369, 25342141, + 35219464, 23512650, 7340520, 18144364 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1714182387328607, 1477856482074168, 574895689942184, + 2159118410227270, 1555532449716575 +#else + 4646495, 25543308, 44342840, 22021777, 23184552, 8566613, + 31366726, 32173371, 52042079, 23179239 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 853828206885131, 998498946036955, 1835887550391235, + 207627336608048, 258363815956050 +#else + 49838347, 12723031, 50115803, 14878793, 21619651, 27356856, + 27584816, 3093888, 58265170, 3849920 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 141141474651677, 1236728744905256, 643101419899887, + 1646615130509173, 1208239602291765 +#else + 58043933, 2103171, 25561640, 18428694, 61869039, 9582957, + 32477045, 24536477, 5002293, 18004173 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1501663228068911, 1354879465566912, 1444432675498247, + 897812463852601, 855062598754348 +#else + 55051311, 22376525, 21115584, 20189277, 8808711, 21523724, + 16489529, 13378448, 41263148, 12741425 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 714380763546606, 1032824444965790, 1774073483745338, + 1063840874947367, 1738680636537158 +#else + 61162478, 10645102, 36197278, 15390283, 63821882, 26435754, + 24306471, 15852464, 28834118, 25908360 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1640635546696252, 633168953192112, 2212651044092396, + 30590958583852, 368515260889378 +#else + 49773116, 24447374, 42577584, 9434952, 58636780, 32971069, + 54018092, 455840, 20461858, 5491305 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1171650314802029, 1567085444565577, 1453660792008405, + 757914533009261, 1619511342778196 +#else + 13669229, 17458950, 54626889, 23351392, 52539093, 21661233, + 42112877, 11293806, 38520660, 24132599 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 420958967093237, 971103481109486, 2169549185607107, + 1301191633558497, 1661514101014240 +#else + 28497909, 6272777, 34085870, 14470569, 8906179, 32328802, + 18504673, 19389266, 29867744, 24758489 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 907123651818302, 1332556122804146, 1824055253424487, + 1367614217442959, 1982558335973172 +#else + 50901822, 13517195, 39309234, 19856633, 24009063, 27180541, + 60741263, 20379039, 22853428, 29542421 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1121533090144639, 1021251337022187, 110469995947421, + 1511059774758394, 2110035908131662 +#else + 24191359, 16712145, 53177067, 15217830, 14542237, 1646131, + 18603514, 22516545, 12876622, 31441985 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 303213233384524, 2061932261128138, 352862124777736, + 40828818670255, 249879468482660 +#else + 17902668, 4518229, 66697162, 30725184, 26878216, 5258055, + 54248111, 608396, 16031844, 3723494 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 856559257852200, 508517664949010, 1378193767894916, + 1723459126947129, 1962275756614521 +#else + 38476072, 12763727, 46662418, 7577503, 33001348, 20536687, + 17558841, 25681542, 23896953, 29240187 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1445691340537320, 40614383122127, 402104303144865, + 485134269878232, 1659439323587426 +#else + 47103464, 21542479, 31520463, 605201, 2543521, 5991821, + 64163800, 7229063, 57189218, 24727572 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 20057458979482, 1183363722525800, 2140003847237215, + 2053873950687614, 2112017736174909 +#else + 28816026, 298879, 38943848, 17633493, 19000927, 31888542, + 54428030, 30605106, 49057085, 31471516 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2228654250927986, 1483591363415267, 1368661293910956, + 1076511285177291, 526650682059608 +#else + 16000882, 33209536, 3493091, 22107234, 37604268, 20394642, + 12577739, 16041268, 47393624, 7847706 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 709481497028540, 531682216165724, 316963769431931, + 1814315888453765, 258560242424104 +#else + 10151868, 10572098, 27312476, 7922682, 14825339, 4723128, + 34252933, 27035413, 57088296, 3852847 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1053447823660455, 1955135194248683, 1010900954918985, + 1182614026976701, 1240051576966610 +#else + 55678375, 15697595, 45987307, 29133784, 5386313, 15063598, + 16514493, 17622322, 29330898, 18478208 +#endif + }}, + }, + }, + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1957943897155497, 1788667368028035, 137692910029106, + 1039519607062, 826404763313028 +#else + 41609129, 29175637, 51885955, 26653220, 16615730, 2051784, + 3303702, 15490, 39560068, 12314390 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1848942433095597, 1582009882530495, 1849292741020143, + 1068498323302788, 2001402229799484 +#else + 15683501, 27551389, 18109119, 23573784, 15337967, 27556609, + 50391428, 15921865, 16103996, 29823217 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1528282417624269, 2142492439828191, 2179662545816034, + 362568973150328, 1591374675250271 +#else + 43939021, 22773182, 13588191, 31925625, 63310306, 32479502, + 47835256, 5402698, 37293151, 23713330 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 160026679434388, 232341189218716, 2149181472355545, + 598041771119831, 183859001910173 +#else + 23190676, 2384583, 34394524, 3462153, 37205209, 32025299, + 55842007, 8911516, 41903005, 2739712 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2013278155187349, 662660471354454, 793981225706267, + 411706605985744, 804490933124791 +#else + 21374101, 30000182, 33584214, 9874410, 15377179, 11831242, + 33578960, 6134906, 4931255, 11987849 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2051892037280204, 488391251096321, 2230187337030708, + 930221970662692, 679002758255210 +#else + 67101132, 30575573, 50885377, 7277596, 105524, 33232381, + 35628324, 13861387, 37032554, 10117929 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1530723630438670, 875873929577927, 341560134269988, + 449903119530753, 1055551308214179 +#else + 37607694, 22809559, 40945095, 13051538, 41483300, 5089642, + 60783361, 6704078, 12890019, 15728940 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1461835919309432, 1955256480136428, 180866187813063, + 1551979252664528, 557743861963950 +#else + 45136504, 21783052, 66157804, 29135591, 14704839, 2695116, + 903376, 23126293, 12885166, 8311031 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 359179641731115, 1324915145732949, 902828372691474, + 294254275669987, 1887036027752957 +#else + 49592363, 5352193, 10384213, 19742774, 7506450, 13453191, + 26423267, 4384730, 1888765, 28119028 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2043271609454323, 2038225437857464, 1317528426475850, + 1398989128982787, 2027639881006861 +#else + 41291507, 30447119, 53614264, 30371925, 30896458, 19632703, + 34857219, 20846562, 47644429, 30214188 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2072902725256516, 312132452743412, 309930885642209, + 996244312618453, 1590501300352303 +#else + 43500868, 30888657, 66582772, 4651135, 5765089, 4618330, + 6092245, 14845197, 17151279, 23700316 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1397254305160710, 695734355138021, 2233992044438756, + 1776180593969996, 1085588199351115 +#else + 42278406, 20820711, 51942885, 10367249, 37577956, 33289075, + 22825804, 26467153, 50242379, 16176524 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 440567051331029, 254894786356681, 493869224930222, + 1556322069683366, 1567456540319218 +#else + 43525589, 6564960, 20063689, 3798228, 62368686, 7359224, + 2006182, 23191006, 38362610, 23356922 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1950722461391320, 1907845598854797, 1822757481635527, + 2121567704750244, 73811931471221 +#else + 56482264, 29068029, 53788301, 28429114, 3432135, 27161203, + 23632036, 31613822, 32808309, 1099883 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 387139307395758, 2058036430315676, 1220915649965325, + 1794832055328951, 1230009312169328 +#else + 15030958, 5768825, 39657628, 30667132, 60681485, 18193060, + 51830967, 26745081, 2051440, 18328567 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1765973779329517, 659344059446977, 19821901606666, + 1301928341311214, 1116266004075885 +#else + 63746541, 26315059, 7517889, 9824992, 23555850, 295369, 5148398, + 19400244, 44422509, 16633659 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1127572801181483, 1224743760571696, 1276219889847274, + 1529738721702581, 1589819666871853 +#else + 4577067, 16802144, 13249840, 18250104, 19958762, 19017158, + 18559669, 22794883, 8402477, 23690159 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2181229378964934, 2190885205260020, 1511536077659137, + 1246504208580490, 668883326494241 +#else + 38702534, 32502850, 40318708, 32646733, 49896449, 22523642, + 9453450, 18574360, 17983009, 9967138 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 437866655573314, 669026411194768, 81896997980338, + 523874406393178, 245052060935236 +#else + 41346370, 6524721, 26585488, 9969270, 24709298, 1220360, + 65430874, 7806336, 17507396, 3651560 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1975438052228868, 1071801519999806, 594652299224319, + 1877697652668809, 1489635366987285 +#else + 56688388, 29436320, 14584638, 15971087, 51340543, 8861009, + 26556809, 27979875, 48555541, 22197296 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 958592545673770, 233048016518599, 851568750216589, + 567703851596087, 1740300006094761 +#else + 2839082, 14284142, 4029895, 3472686, 14402957, 12689363, + 40466743, 8459446, 61503401, 25932490 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2014540178270324, 192672779514432, 213877182641530, + 2194819933853411, 1716422829364835 +#else + 62269556, 30018987, 9744960, 2871048, 25113978, 3187018, + 41998051, 32705365, 17258083, 25576693 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1540769606609725, 2148289943846077, 1597804156127445, + 1230603716683868, 815423458809453 +#else + 18164541, 22959256, 49953981, 32012014, 19237077, 23809137, + 23357532, 18337424, 26908269, 12150756 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1738560251245018, 1779576754536888, 1783765347671392, + 1880170990446751, 1088225159617541 +#else + 36843994, 25906566, 5112248, 26517760, 65609056, 26580174, + 43167, 28016731, 34806789, 16215818 +#endif + }}, + }, + }, + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 659303913929492, 1956447718227573, 1830568515922666, + 841069049744408, 1669607124206368 +#else + 60209940, 9824393, 54804085, 29153342, 35711722, 27277596, + 32574488, 12532905, 59605792, 24879084 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1143465490433355, 1532194726196059, 1093276745494697, + 481041706116088, 2121405433561163 +#else + 39765323, 17038963, 39957339, 22831480, 946345, 16291093, + 254968, 7168080, 21676107, 31611404 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1686424298744462, 1451806974487153, 266296068846582, + 1834686947542675, 1720762336132256 +#else + 21260942, 25129680, 50276977, 21633609, 43430902, 3968120, + 63456915, 27338965, 63552672, 25641356 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 889217026388959, 1043290623284660, 856125087551909, + 1669272323124636, 1603340330827879 +#else + 16544735, 13250366, 50304436, 15546241, 62525861, 12757257, + 64646556, 24874095, 48201831, 23891632 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1206396181488998, 333158148435054, 1402633492821422, + 1120091191722026, 1945474114550509 +#else + 64693606, 17976703, 18312302, 4964443, 51836334, 20900867, + 26820650, 16690659, 25459437, 28989823 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 766720088232571, 1512222781191002, 1189719893490790, + 2091302129467914, 2141418006894941 +#else + 41964155, 11425019, 28423002, 22533875, 60963942, 17728207, + 9142794, 31162830, 60676445, 31909614 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 419663647306612, 1998875112167987, 1426599870253707, + 1154928355379510, 486538532138187 +#else + 44004212, 6253475, 16964147, 29785560, 41994891, 21257994, + 39651638, 17209773, 6335691, 7249989 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 938160078005954, 1421776319053174, 1941643234741774, + 180002183320818, 1414380336750546 +#else + 36775618, 13979674, 7503222, 21186118, 55152142, 28932738, + 36836594, 2682241, 25993170, 21075909 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 398001940109652, 1577721237663248, 1012748649830402, + 1540516006905144, 1011684812884559 +#else + 4364628, 5930691, 32304656, 23509878, 59054082, 15091130, + 22857016, 22955477, 31820367, 15075278 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1653276489969630, 6081825167624, 1921777941170836, + 1604139841794531, 861211053640641 +#else + 31879134, 24635739, 17258760, 90626, 59067028, 28636722, + 24162787, 23903546, 49138625, 12833044 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 996661541407379, 1455877387952927, 744312806857277, + 139213896196746, 1000282908547789 +#else + 19073683, 14851414, 42705695, 21694263, 7625277, 11091125, + 47489674, 2074448, 57694925, 14905376 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1450817495603008, 1476865707053229, 1030490562252053, + 620966950353376, 1744760161539058 +#else + 24483648, 21618865, 64589997, 22007013, 65555733, 15355505, + 41826784, 9253128, 27628530, 25998952 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 559728410002599, 37056661641185, 2038622963352006, + 1637244893271723, 1026565352238948 +#else + 17597607, 8340603, 19355617, 552187, 26198470, 30377849, + 4593323, 24396850, 52997988, 15297015 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 962165956135846, 1116599660248791, 182090178006815, + 1455605467021751, 196053588803284 +#else + 510886, 14337390, 35323607, 16638631, 6328095, 2713355, + 46891447, 21690211, 8683220, 2921426 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 796863823080135, 1897365583584155, 420466939481601, + 2165972651724672, 932177357788289 +#else + 18606791, 11874196, 27155355, 28272950, 43077121, 6265445, + 41930624, 32275507, 4674689, 13890525 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 877047233620632, 1375632631944375, 643773611882121, + 660022738847877, 19353932331831 +#else + 13609624, 13069022, 39736503, 20498523, 24360585, 9592974, + 14977157, 9835105, 4389687, 288396 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2216943882299338, 394841323190322, 2222656898319671, + 558186553950529, 1077236877025190 +#else + 9922506, 33035038, 13613106, 5883594, 48350519, 33120168, + 54804801, 8317627, 23388070, 16052080 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 801118384953213, 1914330175515892, 574541023311511, + 1471123787903705, 1526158900256288 +#else + 12719997, 11937594, 35138804, 28525742, 26900119, 8561328, + 46953177, 21921452, 52354592, 22741539 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 949617889087234, 2207116611267331, 912920039141287, + 501158539198789, 62362560771472 +#else + 15961858, 14150409, 26716931, 32888600, 44314535, 13603568, + 11829573, 7467844, 38286736, 929274 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1474518386765335, 1760793622169197, 1157399790472736, + 1622864308058898, 165428294422792 +#else + 11038231, 21972036, 39798381, 26237869, 56610336, 17246600, + 43629330, 24182562, 45715720, 2465073 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1961673048027128, 102619413083113, 1051982726768458, + 1603657989805485, 1941613251499678 +#else + 20017144, 29231206, 27915241, 1529148, 12396362, 15675764, + 13817261, 23896366, 2463390, 28932292 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1401939116319266, 335306339903072, 72046196085786, + 862423201496006, 850518754531384 +#else + 50749986, 20890520, 55043680, 4996453, 65852442, 1073571, + 9583558, 12851107, 4003896, 12673717 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1234706593321979, 1083343891215917, 898273974314935, + 1640859118399498, 157578398571149 +#else + 65377275, 18398561, 63845933, 16143081, 19294135, 13385325, + 14741514, 24450706, 7903885, 2348101 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1143483057726416, 1992614991758919, 674268662140796, + 1773370048077526, 674318359920189 +#else + 24536016, 17039225, 12715591, 29692277, 1511292, 10047386, + 63266518, 26425272, 38731325, 10048126 +#endif + }}, + }, + }, + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1835401379538542, 173900035308392, 818247630716732, + 1762100412152786, 1021506399448291 +#else + 54486638, 27349611, 30718824, 2591312, 56491836, 12192839, + 18873298, 26257342, 34811107, 15221631 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1506632088156630, 2127481795522179, 513812919490255, + 140643715928370, 442476620300318 +#else + 40630742, 22450567, 11546243, 31701949, 9180879, 7656409, + 45764914, 2095754, 29769758, 6593415 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2056683376856736, 219094741662735, 2193541883188309, + 1841182310235800, 556477468664293 +#else + 35114656, 30646970, 4176911, 3264766, 12538965, 32686321, + 26312344, 27435754, 30958053, 8292160 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1315019427910827, 1049075855992603, 2066573052986543, + 266904467185534, 2040482348591520 +#else + 31429803, 19595316, 29173531, 15632448, 12174511, 30794338, + 32808830, 3977186, 26143136, 30405556 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 94096246544434, 922482381166992, 24517828745563, + 2139430508542503, 2097139044231004 +#else + 22648882, 1402143, 44308880, 13746058, 7936347, 365344, + 58440231, 31879998, 63350620, 31249806 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 537697207950515, 1399352016347350, 1563663552106345, + 2148749520888918, 549922092988516 +#else + 51616947, 8012312, 64594134, 20851969, 43143017, 23300402, + 65496150, 32018862, 50444388, 8194477 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1747985413252434, 680511052635695, 1809559829982725, + 594274250930054, 201673170745982 +#else + 27338066, 26047012, 59694639, 10140404, 48082437, 26964542, + 27277190, 8855376, 28572286, 3005164 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 323583936109569, 1973572998577657, 1192219029966558, + 79354804385273, 1374043025560347 +#else + 26287105, 4821776, 25476601, 29408529, 63344350, 17765447, + 49100281, 1182478, 41014043, 20474836 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 213277331329947, 416202017849623, 1950535221091783, + 1313441578103244, 2171386783823658 +#else + 59937691, 3178079, 23970071, 6201893, 49913287, 29065239, + 45232588, 19571804, 32208682, 32356184 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 189088804229831, 993969372859110, 895870121536987, + 1547301535298256, 1477373024911350 +#else + 50451143, 2817642, 56822502, 14811297, 6024667, 13349505, + 39793360, 23056589, 39436278, 22014573 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1620578418245010, 541035331188469, 2235785724453865, + 2154865809088198, 1974627268751826 +#else + 15941010, 24148500, 45741813, 8062054, 31876073, 33315803, + 51830470, 32110002, 15397330, 29424239 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1346805451740245, 1350981335690626, 942744349501813, + 2155094562545502, 1012483751693409 +#else + 8934485, 20068965, 43822466, 20131190, 34662773, 14047985, + 31170398, 32113411, 39603297, 15087183 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2107080134091762, 1132567062788208, 1824935377687210, + 769194804343737, 1857941799971888 +#else + 48751602, 31397940, 24524912, 16876564, 15520426, 27193656, + 51606457, 11461895, 16788528, 27685490 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1074666112436467, 249279386739593, 1174337926625354, + 1559013532006480, 1472287775519121 +#else + 65161459, 16013772, 21750665, 3714552, 49707082, 17498998, + 63338576, 23231111, 31322513, 21938797 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1872620123779532, 1892932666768992, 1921559078394978, + 1270573311796160, 1438913646755037 +#else + 21426636, 27904214, 53460576, 28206894, 38296674, 28633461, + 48833472, 18933017, 13040861, 21441484 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 837390187648199, 1012253300223599, 989780015893987, + 1351393287739814, 328627746545550 +#else + 11293895, 12478086, 39972463, 15083749, 37801443, 14748871, + 14555558, 20137329, 1613710, 4896935 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1028328827183114, 1711043289969857, 1350832470374933, + 1923164689604327, 1495656368846911 +#else + 41213962, 15323293, 58619073, 25496531, 25967125, 20128972, + 2825959, 28657387, 43137087, 22287016 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1900828492104143, 430212361082163, 687437570852799, + 832514536673512, 1685641495940794 +#else + 51184079, 28324551, 49665331, 6410663, 3622847, 10243618, + 20615400, 12405433, 43355834, 25118015 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 842632847936398, 605670026766216, 290836444839585, + 163210774892356, 2213815011799645 +#else + 60017550, 12556207, 46917512, 9025186, 50036385, 4333800, + 4378436, 2432030, 23097949, 32988414 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1176336383453996, 1725477294339771, 12700622672454, + 678015708818208, 162724078519879 +#else + 4565804, 17528778, 20084411, 25711615, 1724998, 189254, + 24767264, 10103221, 48596551, 2424777 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1448049969043497, 1789411762943521, 385587766217753, + 90201620913498, 832999441066823 +#else + 366633, 21577626, 8173089, 26664313, 30788633, 5745705, + 59940186, 1344108, 63466311, 12412658 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 516086333293313, 2240508292484616, 1351669528166508, + 1223255565316488, 750235824427138 +#else + 43107073, 7690285, 14929416, 33386175, 34898028, 20141445, + 24162696, 18227928, 63967362, 11179384 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1263624896582495, 1102602401673328, 526302183714372, + 2152015839128799, 1483839308490010 +#else + 18289503, 18829478, 8056944, 16430056, 45379140, 7842513, + 61107423, 32067534, 48424218, 22110928 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 442991718646863, 1599275157036458, 1925389027579192, + 899514691371390, 350263251085160 +#else + 476239, 6601091, 60956074, 23831056, 17503544, 28690532, + 27672958, 13403813, 11052904, 5219329 +#endif + }}, + }, + }, + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1689713572022143, 593854559254373, 978095044791970, + 1985127338729499, 1676069120347625 +#else + 20678527, 25178694, 34436965, 8849122, 62099106, 14574751, + 31186971, 29580702, 9014761, 24975376 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1557207018622683, 340631692799603, 1477725909476187, + 614735951619419, 2033237123746766 +#else + 53464795, 23204192, 51146355, 5075807, 65594203, 22019831, + 34006363, 9160279, 8473550, 30297594 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 968764929340557, 1225534776710944, 662967304013036, + 1155521416178595, 791142883466590 +#else + 24900749, 14435722, 17209120, 18261891, 44516588, 9878982, + 59419555, 17218610, 42540382, 11788947 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1487081286167458, 993039441814934, 1792378982844640, + 698652444999874, 2153908693179754 +#else + 63990690, 22159237, 53306774, 14797440, 9652448, 26708528, + 47071426, 10410732, 42540394, 32095740 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1123181311102823, 685575944875442, 507605465509927, + 1412590462117473, 568017325228626 +#else + 51449703, 16736705, 44641714, 10215877, 58011687, 7563910, + 11871841, 21049238, 48595538, 8464117 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 560258797465417, 2193971151466401, 1824086900849026, + 579056363542056, 1690063960036441 +#else + 43708233, 8348506, 52522913, 32692717, 63158658, 27181012, + 14325288, 8628612, 33313881, 25183915 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1918407319222416, 353767553059963, 1930426334528099, + 1564816146005724, 1861342381708096 +#else + 46921872, 28586496, 22367355, 5271547, 66011747, 28765593, + 42303196, 23317577, 58168128, 27736162 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2131325168777276, 1176636658428908, 1756922641512981, + 1390243617176012, 1966325177038383 +#else + 60160060, 31759219, 34483180, 17533252, 32635413, 26180187, + 15989196, 20716244, 28358191, 29300528 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2063958120364491, 2140267332393533, 699896251574968, + 273268351312140, 375580724713232 +#else + 43547083, 30755372, 34757181, 31892468, 57961144, 10429266, + 50471180, 4072015, 61757200, 5596588 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2024297515263178, 416959329722687, 1079014235017302, + 171612225573183, 1031677520051053 +#else + 38872266, 30164383, 12312895, 6213178, 3117142, 16078565, + 29266239, 2557221, 1768301, 15373193 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2033900009388450, 1744902869870788, 2190580087917640, + 1949474984254121, 231049754293748 +#else + 59865506, 30307471, 62515396, 26001078, 66980936, 32642186, + 66017961, 29049440, 42448372, 3442909 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 343868674606581, 550155864008088, 1450580864229630, + 481603765195050, 896972360018042 +#else + 36898293, 5124042, 14181784, 8197961, 18964734, 21615339, + 22597930, 7176455, 48523386, 13365929 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2151139328380127, 314745882084928, 59756825775204, + 1676664391494651, 2048348075599360 +#else + 59231455, 32054473, 8324672, 4690079, 6261860, 890446, 24538107, + 24984246, 57419264, 30522764 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1528930066340597, 1605003907059576, 1055061081337675, + 1458319101947665, 1234195845213142 +#else + 25008885, 22782833, 62803832, 23916421, 16265035, 15721635, + 683793, 21730648, 15723478, 18390951 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 830430507734812, 1780282976102377, 1425386760709037, + 362399353095425, 2168861579799910 +#else + 57448220, 12374378, 40101865, 26528283, 59384749, 21239917, + 11879681, 5400171, 519526, 32318556 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1155762232730333, 980662895504006, 2053766700883521, + 490966214077606, 510405877041357 +#else + 22258397, 17222199, 59239046, 14613015, 44588609, 30603508, + 46754982, 7315966, 16648397, 7605640 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1683750316716132, 652278688286128, 1221798761193539, + 1897360681476669, 319658166027343 +#else + 59027556, 25089834, 58885552, 9719709, 19259459, 18206220, + 23994941, 28272877, 57640015, 4763277 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 618808732869972, 72755186759744, 2060379135624181, + 1730731526741822, 48862757828238 +#else + 45409620, 9220968, 51378240, 1084136, 41632757, 30702041, + 31088446, 25789909, 55752334, 728111 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1463171970593505, 1143040711767452, 614590986558883, + 1409210575145591, 1882816996436803 +#else + 26047201, 21802961, 60208540, 17032633, 24092067, 9158119, + 62835319, 20998873, 37743427, 28056159 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2230133264691131, 563950955091024, 2042915975426398, + 827314356293472, 672028980152815 +#else + 17510331, 33231575, 5854288, 8403524, 17133918, 30441820, + 38997856, 12327944, 10750447, 10014012 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 264204366029760, 1654686424479449, 2185050199932931, + 2207056159091748, 506015669043634 +#else + 56796096, 3936951, 9156313, 24656749, 16498691, 32559785, + 39627812, 32887699, 3424690, 7540221 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1784446333136569, 1973746527984364, 334856327359575, + 1156769775884610, 1023950124675478 +#else + 30322361, 26590322, 11361004, 29411115, 7433303, 4989748, + 60037442, 17237212, 57864598, 15258045 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2065270940578383, 31477096270353, 306421879113491, + 181958643936686, 1907105536686083 +#else + 13054543, 30774935, 19155473, 469045, 54626067, 4566041, + 5631406, 2711395, 1062915, 28418087 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1496516440779464, 1748485652986458, 872778352227340, + 818358834654919, 97932669284220 +#else + 47868616, 22299832, 37599834, 26054466, 61273100, 13005410, + 61042375, 12194496, 32960380, 1459310 +#endif + }}, + }, + }, + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 471636015770351, 672455402793577, 1804995246884103, + 1842309243470804, 1501862504981682 +#else + 19852015, 7027924, 23669353, 10020366, 8586503, 26896525, + 394196, 27452547, 18638002, 22379495 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1013216974933691, 538921919682598, 1915776722521558, + 1742822441583877, 1886550687916656 +#else + 31395515, 15098109, 26581030, 8030562, 50580950, 28547297, + 9012485, 25970078, 60465776, 28111795 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2094270000643336, 303971879192276, 40801275554748, + 649448917027930, 1818544418535447 +#else + 57916680, 31207054, 65111764, 4529533, 25766844, 607986, + 67095642, 9677542, 34813975, 27098423 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2241737709499165, 549397817447461, 838180519319392, + 1725686958520781, 1705639080897747 +#else + 64664349, 33404494, 29348901, 8186665, 1873760, 12489863, + 36174285, 25714739, 59256019, 25416002 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1216074541925116, 50120933933509, 1565829004133810, + 721728156134580, 349206064666188 +#else + 51872508, 18120922, 7766469, 746860, 26346930, 23332670, + 39775412, 10754587, 57677388, 5203575 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 948617110470858, 346222547451945, 1126511960599975, + 1759386906004538, 493053284802266 +#else + 31834314, 14135496, 66338857, 5159117, 20917671, 16786336, + 59640890, 26216907, 31809242, 7347066 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1454933046815146, 874696014266362, 1467170975468588, + 1432316382418897, 2111710746366763 +#else + 57502122, 21680191, 20414458, 13033986, 13716524, 21862551, + 19797969, 21343177, 15192875, 31466942 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2105387117364450, 1996463405126433, 1303008614294500, + 851908115948209, 1353742049788635 +#else + 54445282, 31372712, 1168161, 29749623, 26747876, 19416341, + 10609329, 12694420, 33473243, 20172328 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 750300956351719, 1487736556065813, 15158817002104, + 1511998221598392, 971739901354129 +#else + 33184999, 11180355, 15832085, 22169002, 65475192, 225883, + 15089336, 22530529, 60973201, 14480052 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1874648163531693, 2124487685930551, 1810030029384882, + 918400043048335, 586348627300650 +#else + 31308717, 27934434, 31030839, 31657333, 15674546, 26971549, + 5496207, 13685227, 27595050, 8737275 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1235084464747900, 1166111146432082, 1745394857881591, + 1405516473883040, 4463504151617 +#else + 46790012, 18404192, 10933842, 17376410, 8335351, 26008410, + 36100512, 20943827, 26498113, 66511 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1663810156463827, 327797390285791, 1341846161759410, + 1964121122800605, 1747470312055380 +#else + 22644435, 24792703, 50437087, 4884561, 64003250, 19995065, + 30540765, 29267685, 53781076, 26039336 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 660005247548233, 2071860029952887, 1358748199950107, + 911703252219107, 1014379923023831 +#else + 39091017, 9834844, 18617207, 30873120, 63706907, 20246925, + 8205539, 13585437, 49981399, 15115438 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2206641276178231, 1690587809721504, 1600173622825126, + 2156096097634421, 1106822408548216 +#else + 23711543, 32881517, 31206560, 25191721, 6164646, 23844445, + 33572981, 32128335, 8236920, 16492939 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1344788193552206, 1949552134239140, 1735915881729557, + 675891104100469, 1834220014427292 +#else + 43198286, 20038905, 40809380, 29050590, 25005589, 25867162, + 19574901, 10071562, 6708380, 27332008 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1920949492387964, 158885288387530, 70308263664033, + 626038464897817, 1468081726101009 +#else + 2101372, 28624378, 19702730, 2367575, 51681697, 1047674, + 5301017, 9328700, 29955601, 21876122 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 622221042073383, 1210146474039168, 1742246422343683, + 1403839361379025, 417189490895736 +#else + 3096359, 9271816, 45488000, 18032587, 52260867, 25961494, + 41216721, 20918836, 57191288, 6216607 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 22727256592983, 168471543384997, 1324340989803650, + 1839310709638189, 504999476432775 +#else + 34493015, 338662, 41913253, 2510421, 37895298, 19734218, + 24822829, 27407865, 40341383, 7525078 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1313240518756327, 1721896294296942, 52263574587266, + 2065069734239232, 804910473424630 +#else + 44042215, 19568808, 16133486, 25658254, 63719298, 778787, + 66198528, 30771936, 47722230, 11994100 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1337466662091884, 1287645354669772, 2018019646776184, + 652181229374245, 898011753211715 +#else + 21691500, 19929806, 66467532, 19187410, 3285880, 30070836, + 42044197, 9718257, 59631427, 13381417 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1969792547910734, 779969968247557, 2011350094423418, + 1823964252907487, 1058949448296945 +#else + 18445390, 29352196, 14979845, 11622458, 65381754, 29971451, + 23111647, 27179185, 28535281, 15779576 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 207343737062002, 1118176942430253, 758894594548164, + 806764629546266, 1157700123092949 +#else + 30098034, 3089662, 57874477, 16662134, 45801924, 11308410, + 53040410, 12021729, 9955285, 17251076 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1273565321399022, 1638509681964574, 759235866488935, + 666015124346707, 897983460943405 +#else + 9734894, 18977602, 59635230, 24415696, 2060391, 11313496, + 48682835, 9924398, 20194861, 13380996 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1717263794012298, 1059601762860786, 1837819172257618, + 1054130665797229, 680893204263559 +#else + 40730762, 25589224, 44941042, 15789296, 49053522, 27385639, + 65123949, 15707770, 26342023, 10146099 +#endif + }}, + }, + }, + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2237039662793603, 2249022333361206, 2058613546633703, + 149454094845279, 2215176649164582 +#else + 41091971, 33334488, 21339190, 33513044, 19745255, 30675732, + 37471583, 2227039, 21612326, 33008704 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 79472182719605, 1851130257050174, 1825744808933107, + 821667333481068, 781795293511946 +#else + 54031477, 1184227, 23562814, 27583990, 46757619, 27205717, + 25764460, 12243797, 46252298, 11649657 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 755822026485370, 152464789723500, 1178207602290608, + 410307889503239, 156581253571278 +#else + 57077370, 11262625, 27384172, 2271902, 26947504, 17556661, + 39943, 6114064, 33514190, 2333242 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1418185496130297, 484520167728613, 1646737281442950, + 1401487684670265, 1349185550126961 +#else + 45675257, 21132610, 8119781, 7219913, 45278342, 24538297, + 60429113, 20883793, 24350577, 20104431 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1495380034400429, 325049476417173, 46346894893933, + 1553408840354856, 828980101835683 +#else + 62992557, 22282898, 43222677, 4843614, 37020525, 690622, + 35572776, 23147595, 8317859, 12352766 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1280337889310282, 2070832742866672, 1640940617225222, + 2098284908289951, 450929509534434 +#else + 18200138, 19078521, 34021104, 30857812, 43406342, 24451920, + 43556767, 31266881, 20712162, 6719373 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 407703353998781, 126572141483652, 286039827513621, + 1999255076709338, 2030511179441770 +#else + 26656189, 6075253, 59250308, 1886071, 38764821, 4262325, + 11117530, 29791222, 26224234, 30256974 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1254958221100483, 1153235960999843, 942907704968834, + 637105404087392, 1149293270147267 +#else + 49939907, 18700334, 63713187, 17184554, 47154818, 14050419, + 21728352, 9493610, 18620611, 17125804 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 894249020470196, 400291701616810, 406878712230981, + 1599128793487393, 1145868722604026 +#else + 53785524, 13325348, 11432106, 5964811, 18609221, 6062965, + 61839393, 23828875, 36407290, 17074774 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1497955250203334, 110116344653260, 1128535642171976, + 1900106496009660, 129792717460909 +#else + 43248326, 22321272, 26961356, 1640861, 34695752, 16816491, + 12248508, 28313793, 13735341, 1934062 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 452487513298665, 1352120549024569, 1173495883910956, + 1999111705922009, 367328130454226 +#else + 25089769, 6742589, 17081145, 20148166, 21909292, 17486451, + 51972569, 29789085, 45830866, 5473615 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1717539401269642, 1475188995688487, 891921989653942, + 836824441505699, 1885988485608364 +#else + 31883658, 25593331, 1083431, 21982029, 22828470, 13290673, + 59983779, 12469655, 29111212, 28103418 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1241784121422547, 187337051947583, 1118481812236193, + 428747751936362, 30358898927325 +#else + 24244947, 18504025, 40845887, 2791539, 52111265, 16666677, + 24367466, 6388839, 56813277, 452382 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2022432361201842, 1088816090685051, 1977843398539868, + 1854834215890724, 564238862029357 +#else + 41468082, 30136590, 5217915, 16224624, 19987036, 29472163, + 42872612, 27639183, 15766061, 8407814 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 938868489100585, 1100285072929025, 1017806255688848, + 1957262154788833, 152787950560442 +#else + 46701865, 13990230, 15495425, 16395525, 5377168, 15166495, + 58191841, 29165478, 59040954, 2276717 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 867319417678923, 620471962942542, 226032203305716, + 342001443957629, 1761675818237336 +#else + 30157899, 12924066, 49396814, 9245752, 19895028, 3368142, + 43281277, 5096218, 22740376, 26251015 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1295072362439987, 931227904689414, 1355731432641687, + 922235735834035, 892227229410209 +#else + 2041139, 19298082, 7783686, 13876377, 41161879, 20201972, + 24051123, 13742383, 51471265, 13295221 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1680989767906154, 535362787031440, 2136691276706570, + 1942228485381244, 1267350086882274 +#else + 33338218, 25048699, 12532112, 7977527, 9106186, 31839181, + 49388668, 28941459, 62657506, 18884987 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 366018233770527, 432660629755596, 126409707644535, + 1973842949591662, 645627343442376 +#else + 47063583, 5454096, 52762316, 6447145, 28862071, 1883651, + 64639598, 29412551, 7770568, 9620597 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 535509430575217, 546885533737322, 1524675609547799, + 2138095752851703, 1260738089896827 +#else + 23208049, 7979712, 33071466, 8149229, 1758231, 22719437, + 30945527, 31860109, 33606523, 18786461 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1159906385590467, 2198530004321610, 714559485023225, + 81880727882151, 1484020820037082 +#else + 1439939, 17283952, 66028874, 32760649, 4625401, 10647766, + 62065063, 1220117, 30494170, 22113633 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1377485731340769, 2046328105512000, 1802058637158797, + 62146136768173, 1356993908853901 +#else + 62071265, 20526136, 64138304, 30492664, 15640973, 26852766, + 40369837, 926049, 65424525, 20220784 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2013612215646735, 1830770575920375, 536135310219832, + 609272325580394, 270684344495013 +#else + 13908495, 30005160, 30919927, 27280607, 45587000, 7989038, + 9021034, 9078865, 3353509, 4033511 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1237542585982777, 2228682050256790, 1385281931622824, + 593183794882890, 493654978552689 +#else + 37445433, 18440821, 32259990, 33209950, 24295848, 20642309, + 23161162, 8839127, 27485041, 7356032 +#endif + }}, + }, + }, + { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 47341488007760, 1891414891220257, 983894663308928, + 176161768286818, 1126261115179708 +#else + 9661008, 705443, 11980065, 28184278, 65480320, 14661172, + 60762722, 2625014, 28431036, 16782598 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1694030170963455, 502038567066200, 1691160065225467, + 949628319562187, 275110186693066 +#else + 43269631, 25243016, 41163352, 7480957, 49427195, 25200248, + 44562891, 14150564, 15970762, 4099461 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1124515748676336, 1661673816593408, 1499640319059718, + 1584929449166988, 558148594103306 +#else + 29262576, 16756590, 26350592, 24760869, 8529670, 22346382, + 13617292, 23617289, 11465738, 8317062 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1784525599998356, 1619698033617383, 2097300287550715, + 258265458103756, 1905684794832758 +#else + 41615764, 26591503, 32500199, 24135381, 44070139, 31252209, + 14898636, 3848455, 20969334, 28396916 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1288941072872766, 931787902039402, 190731008859042, + 2006859954667190, 1005931482221702 +#else + 46724414, 19206718, 48772458, 13884721, 34069410, 2842113, + 45498038, 29904543, 11177094, 14989547 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1465551264822703, 152905080555927, 680334307368453, + 173227184634745, 666407097159852 +#else + 42612143, 21838415, 16959895, 2278463, 12066309, 10137771, + 13515641, 2581286, 38621356, 9930239 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2111017076203943, 1378760485794347, 1248583954016456, + 1352289194864422, 1895180776543896 +#else + 49357223, 31456605, 16544299, 20545132, 51194056, 18605350, + 18345766, 20150679, 16291480, 28240394 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 171348223915638, 662766099800389, 462338943760497, + 466917763340314, 656911292869115 +#else + 33879670, 2553287, 32678213, 9875984, 8534129, 6889387, + 57432090, 6957616, 4368891, 9788741 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 488623681976577, 866497561541722, 1708105560937768, + 1673781214218839, 1506146329818807 +#else + 16660737, 7281060, 56278106, 12911819, 20108584, 25452756, + 45386327, 24941283, 16250551, 22443329 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 160425464456957, 950394373239689, 430497123340934, + 711676555398832, 320964687779005 +#else + 47343357, 2390525, 50557833, 14161979, 1905286, 6414907, + 4689584, 10604807, 36918461, 4782746 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 988979367990485, 1359729327576302, 1301834257246029, + 294141160829308, 29348272277475 +#else + 65754325, 14736940, 59741422, 20261545, 7710541, 19398842, + 57127292, 4383044, 22546403, 437323 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1434382743317910, 100082049942065, 221102347892623, + 186982837860588, 1305765053501834 +#else + 31665558, 21373968, 50922033, 1491338, 48740239, 3294681, + 27343084, 2786261, 36475274, 19457415 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2205916462268190, 499863829790820, 961960554686616, + 158062762756985, 1841471168298305 +#else + 52641566, 32870716, 33734756, 7448551, 19294360, 14334329, + 47418233, 2355318, 47824193, 27440058 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1191737341426592, 1847042034978363, 1382213545049056, + 1039952395710448, 788812858896859 +#else + 15121312, 17758270, 6377019, 27523071, 56310752, 20596586, + 18952176, 15496498, 37728731, 11754227 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1346965964571152, 1291881610839830, 2142916164336056, + 786821641205979, 1571709146321039 +#else + 64471568, 20071356, 8488726, 19250536, 12728760, 31931939, + 7141595, 11724556, 22761615, 23420291 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 787164375951248, 202869205373189, 1356590421032140, + 1431233331032510, 786341368775957 +#else + 16918416, 11729663, 49025285, 3022986, 36093132, 20214772, + 38367678, 21327038, 32851221, 11717399 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 492448143532951, 304105152670757, 1761767168301056, + 233782684697790, 1981295323106089 +#else + 11166615, 7338049, 60386341, 4531519, 37640192, 26252376, + 31474878, 3483633, 65915689, 29523600 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 665807507761866, 1343384868355425, 895831046139653, + 439338948736892, 1986828765695105 +#else + 66923210, 9921304, 31456609, 20017994, 55095045, 13348922, + 33142652, 6546660, 47123585, 29606055 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 756096210874553, 1721699973539149, 258765301727885, + 1390588532210645, 1212530909934781 +#else + 34648249, 11266711, 55911757, 25655328, 31703693, 3855903, + 58571733, 20721383, 36336829, 18068118 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 852891097972275, 1816988871354562, 1543772755726524, + 1174710635522444, 202129090724628 +#else + 49102387, 12709067, 3991746, 27075244, 45617340, 23004006, + 35973516, 17504552, 10928916, 3011958 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1205281565824323, 22430498399418, 992947814485516, + 1392458699738672, 688441466734558 +#else + 60151107, 17960094, 31696058, 334240, 29576716, 14796075, + 36277808, 20749251, 18008030, 10258577 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1050627428414972, 1955849529137135, 2171162376368357, + 91745868298214, 447733118757826 +#else + 44660220, 15655568, 7018479, 29144429, 36794597, 32352840, + 65255398, 1367119, 25127874, 6671743 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1287181461435438, 622722465530711, 880952150571872, + 741035693459198, 311565274989772 +#else + 29701166, 19180498, 56230743, 9279287, 67091296, 13127209, + 21382910, 11042292, 25838796, 4642684 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1003649078149734, 545233927396469, 1849786171789880, + 1318943684880434, 280345687170552 +#else + 46678630, 14955536, 42982517, 8124618, 61739576, 27563961, + 30468146, 19653792, 18423288, 4177476 +#endif + }}, + }, + }, +}; + +#endif // OPENSSL_SMALL + +// Bi[i] = (2*i+1)*B +static const ge_precomp Bi[8] = { + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1288382639258501, 245678601348599, 269427782077623, + 1462984067271730, 137412439391563 +#else + 25967493, 19198397, 29566455, 3660896, 54414519, 4014786, 27544626, + 21800161, 61029707, 2047604 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 62697248952638, 204681361388450, 631292143396476, 338455783676468, + 1213667448819585 +#else + 54563134, 934261, 64385954, 3049989, 66381436, 9406985, 12720692, + 5043384, 19500929, 18085054 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 301289933810280, 1259582250014073, 1422107436869536, + 796239922652654, 1953934009299142 +#else + 58370664, 4489569, 9688441, 18769238, 10184608, 21191052, 29287918, + 11864899, 42594502, 29115885 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1601611775252272, 1720807796594148, 1132070835939856, + 1260455018889551, 2147779492816911 +#else + 15636272, 23865875, 24204772, 25642034, 616976, 16869170, 27787599, + 18782243, 28944399, 32004408 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 316559037616741, 2177824224946892, 1459442586438991, + 1461528397712656, 751590696113597 +#else + 16568933, 4717097, 55552716, 32452109, 15682895, 21747389, 16354576, + 21778470, 7689661, 11199574 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1850748884277385, 1200145853858453, 1068094770532492, + 672251375690438, 1586055907191707 +#else + 30464137, 27578307, 55329429, 17883566, 23220364, 15915852, 7512774, + 10017326, 49359771, 23634074 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 769950342298419, 132954430919746, 844085933195555, 974092374476333, + 726076285546016 +#else + 10861363, 11473154, 27284546, 1981175, 37044515, 12577860, 32867885, + 14515107, 51670560, 10819379 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 425251763115706, 608463272472562, 442562545713235, 837766094556764, + 374555092627893 +#else + 4708026, 6336745, 20377586, 9066809, 55836755, 6594695, 41455196, + 12483687, 54440373, 5581305 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1086255230780037, 274979815921559, 1960002765731872, + 929474102396301, 1190409889297339 +#else + 19563141, 16186464, 37722007, 4097518, 10237984, 29206317, 28542349, + 13850243, 43430843, 17738489 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 665000864555967, 2065379846933859, 370231110385876, 350988370788628, + 1233371373142985 +#else + 5153727, 9909285, 1723747, 30776558, 30523604, 5516873, 19480852, + 5230134, 43156425, 18378665 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2019367628972465, 676711900706637, 110710997811333, + 1108646842542025, 517791959672113 +#else + 36839857, 30090922, 7665485, 10083793, 28475525, 1649722, 20654025, + 16520125, 30598449, 7715701 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 965130719900578, 247011430587952, 526356006571389, 91986625355052, + 2157223321444601 +#else + 28881826, 14381568, 9657904, 3680757, 46927229, 7843315, 35708204, + 1370707, 29794553, 32145132 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1802695059465007, 1664899123557221, 593559490740857, + 2160434469266659, 927570450755031 +#else + 44589871, 26862249, 14201701, 24808930, 43598457, 8844725, 18474211, + 32192982, 54046167, 13821876 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1725674970513508, 1933645953859181, 1542344539275782, + 1767788773573747, 1297447965928905 +#else + 60653668, 25714560, 3374701, 28813570, 40010246, 22982724, 31655027, + 26342105, 18853321, 19333481 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1381809363726107, 1430341051343062, 2061843536018959, + 1551778050872521, 2036394857967624 +#else + 4566811, 20590564, 38133974, 21313742, 59506191, 30723862, 58594505, + 23123294, 2207752, 30344648 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1970894096313054, 528066325833207, 1619374932191227, + 2207306624415883, 1169170329061080 +#else + 41954014, 29368610, 29681143, 7868801, 60254203, 24130566, 54671499, + 32891431, 35997400, 17421995 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 2070390218572616, 1458919061857835, 624171843017421, + 1055332792707765, 433987520732508 +#else + 25576264, 30851218, 7349803, 21739588, 16472781, 9300885, 3844789, + 15725684, 171356, 6466918 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 893653801273833, 1168026499324677, 1242553501121234, + 1306366254304474, 1086752658510815 +#else + 23103977, 13316479, 9739013, 17404951, 817874, 18515490, 8965338, + 19466374, 36393951, 16193876 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 213454002618221, 939771523987438, 1159882208056014, 317388369627517, + 621213314200687 +#else + 33587053, 3180712, 64714734, 14003686, 50205390, 17283591, 17238397, + 4729455, 49034351, 9256799 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1971678598905747, 338026507889165, 762398079972271, 655096486107477, + 42299032696322 +#else + 41926547, 29380300, 32336397, 5036987, 45872047, 11360616, 22616405, + 9761698, 47281666, 630304 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 177130678690680, 1754759263300204, 1864311296286618, + 1180675631479880, 1292726903152791 +#else + 53388152, 2639452, 42871404, 26147950, 9494426, 27780403, 60554312, + 17593437, 64659607, 19263131 +#endif + }}, + }, + { + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1913163449625248, 460779200291993, 2193883288642314, + 1008900146920800, 1721983679009502 +#else + 63957664, 28508356, 9282713, 6866145, 35201802, 32691408, 48168288, + 15033783, 25105118, 25659556 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 1070401523076875, 1272492007800961, 1910153608563310, + 2075579521696771, 1191169788841221 +#else + 42782475, 15950225, 35307649, 18961608, 55446126, 28463506, 1573891, + 30928545, 2198789, 17749813 +#endif + }}, + {{ +#if defined(BORINGSSL_CURVE25519_64BIT) + 692896803108118, 500174642072499, 2068223309439677, + 1162190621851337, 1426986007309901 +#else + 64009494, 10324966, 64867251, 7453182, 61661885, 30818928, 53296841, + 17317989, 34647629, 21263748 +#endif + }}, + }, +}; diff --git a/FoodApp/Pods/BoringSSL-GRPC/third_party/fiat/internal.h b/FoodApp/Pods/BoringSSL-GRPC/third_party/fiat/internal.h new file mode 100644 index 0000000..6160dd3 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/third_party/fiat/internal.h @@ -0,0 +1,154 @@ +// The MIT License (MIT) +// +// Copyright (c) 2015-2016 the fiat-crypto authors (see the AUTHORS file). +// +// 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 OPENSSL_HEADER_CURVE25519_INTERNAL_H +#define OPENSSL_HEADER_CURVE25519_INTERNAL_H + +#if defined(__cplusplus) +extern "C" { +#endif + +#include + +#include "../../crypto/internal.h" + + +#if defined(OPENSSL_ARM) && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_APPLE) +#define BORINGSSL_X25519_NEON + +// x25519_NEON is defined in asm/x25519-arm.S. +void x25519_NEON(uint8_t out[32], const uint8_t scalar[32], + const uint8_t point[32]); +#endif + +#if defined(BORINGSSL_HAS_UINT128) +#define BORINGSSL_CURVE25519_64BIT +#endif + +#if defined(BORINGSSL_CURVE25519_64BIT) +// fe means field element. Here the field is \Z/(2^255-19). An element t, +// entries t[0]...t[4], represents the integer t[0]+2^51 t[1]+2^102 t[2]+2^153 +// t[3]+2^204 t[4]. +// fe limbs are bounded by 1.125*2^51. +// Multiplication and carrying produce fe from fe_loose. +typedef struct fe { uint64_t v[5]; } fe; + +// fe_loose limbs are bounded by 3.375*2^51. +// Addition and subtraction produce fe_loose from (fe, fe). +typedef struct fe_loose { uint64_t v[5]; } fe_loose; +#else +// fe means field element. Here the field is \Z/(2^255-19). An element t, +// entries t[0]...t[9], represents the integer t[0]+2^26 t[1]+2^51 t[2]+2^77 +// t[3]+2^102 t[4]+...+2^230 t[9]. +// fe limbs are bounded by 1.125*2^26,1.125*2^25,1.125*2^26,1.125*2^25,etc. +// Multiplication and carrying produce fe from fe_loose. +typedef struct fe { uint32_t v[10]; } fe; + +// fe_loose limbs are bounded by 3.375*2^26,3.375*2^25,3.375*2^26,3.375*2^25,etc. +// Addition and subtraction produce fe_loose from (fe, fe). +typedef struct fe_loose { uint32_t v[10]; } fe_loose; +#endif + +// ge means group element. +// +// Here the group is the set of pairs (x,y) of field elements (see fe.h) +// satisfying -x^2 + y^2 = 1 + d x^2y^2 +// where d = -121665/121666. +// +// Representations: +// ge_p2 (projective): (X:Y:Z) satisfying x=X/Z, y=Y/Z +// ge_p3 (extended): (X:Y:Z:T) satisfying x=X/Z, y=Y/Z, XY=ZT +// ge_p1p1 (completed): ((X:Z),(Y:T)) satisfying x=X/Z, y=Y/T +// ge_precomp (Duif): (y+x,y-x,2dxy) + +typedef struct { + fe X; + fe Y; + fe Z; +} ge_p2; + +typedef struct { + fe X; + fe Y; + fe Z; + fe T; +} ge_p3; + +typedef struct { + fe_loose X; + fe_loose Y; + fe_loose Z; + fe_loose T; +} ge_p1p1; + +typedef struct { + fe_loose yplusx; + fe_loose yminusx; + fe_loose xy2d; +} ge_precomp; + +typedef struct { + fe_loose YplusX; + fe_loose YminusX; + fe_loose Z; + fe_loose T2d; +} ge_cached; + +void x25519_ge_tobytes(uint8_t s[32], const ge_p2 *h); +int x25519_ge_frombytes_vartime(ge_p3 *h, const uint8_t *s); +void x25519_ge_p3_to_cached(ge_cached *r, const ge_p3 *p); +void x25519_ge_p1p1_to_p2(ge_p2 *r, const ge_p1p1 *p); +void x25519_ge_p1p1_to_p3(ge_p3 *r, const ge_p1p1 *p); +void x25519_ge_add(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q); +void x25519_ge_sub(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q); +void x25519_ge_scalarmult_small_precomp( + ge_p3 *h, const uint8_t a[32], const uint8_t precomp_table[15 * 2 * 32]); +void x25519_ge_scalarmult_base(ge_p3 *h, const uint8_t a[32]); +void x25519_ge_scalarmult(ge_p2 *r, const uint8_t *scalar, const ge_p3 *A); +void x25519_sc_reduce(uint8_t s[64]); + +enum spake2_state_t { + spake2_state_init = 0, + spake2_state_msg_generated, + spake2_state_key_generated, +}; + +struct spake2_ctx_st { + uint8_t private_key[32]; + uint8_t my_msg[32]; + uint8_t password_scalar[32]; + uint8_t password_hash[64]; + uint8_t *my_name; + size_t my_name_len; + uint8_t *their_name; + size_t their_name_len; + enum spake2_role_t my_role; + enum spake2_state_t state; + char disable_password_scalar_hack; +}; + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_CURVE25519_INTERNAL_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/third_party/fiat/internal.h.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/third_party/fiat/internal.h.grpc_back new file mode 100644 index 0000000..be3e265 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/third_party/fiat/internal.h.grpc_back @@ -0,0 +1,154 @@ +// The MIT License (MIT) +// +// Copyright (c) 2015-2016 the fiat-crypto authors (see the AUTHORS file). +// +// 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 OPENSSL_HEADER_CURVE25519_INTERNAL_H +#define OPENSSL_HEADER_CURVE25519_INTERNAL_H + +#if defined(__cplusplus) +extern "C" { +#endif + +#include + +#include "../../crypto/internal.h" + + +#if defined(OPENSSL_ARM) && !defined(OPENSSL_NO_ASM) && !defined(OPENSSL_APPLE) +#define BORINGSSL_X25519_NEON + +// x25519_NEON is defined in asm/x25519-arm.S. +void x25519_NEON(uint8_t out[32], const uint8_t scalar[32], + const uint8_t point[32]); +#endif + +#if defined(BORINGSSL_HAS_UINT128) +#define BORINGSSL_CURVE25519_64BIT +#endif + +#if defined(BORINGSSL_CURVE25519_64BIT) +// fe means field element. Here the field is \Z/(2^255-19). An element t, +// entries t[0]...t[4], represents the integer t[0]+2^51 t[1]+2^102 t[2]+2^153 +// t[3]+2^204 t[4]. +// fe limbs are bounded by 1.125*2^51. +// Multiplication and carrying produce fe from fe_loose. +typedef struct fe { uint64_t v[5]; } fe; + +// fe_loose limbs are bounded by 3.375*2^51. +// Addition and subtraction produce fe_loose from (fe, fe). +typedef struct fe_loose { uint64_t v[5]; } fe_loose; +#else +// fe means field element. Here the field is \Z/(2^255-19). An element t, +// entries t[0]...t[9], represents the integer t[0]+2^26 t[1]+2^51 t[2]+2^77 +// t[3]+2^102 t[4]+...+2^230 t[9]. +// fe limbs are bounded by 1.125*2^26,1.125*2^25,1.125*2^26,1.125*2^25,etc. +// Multiplication and carrying produce fe from fe_loose. +typedef struct fe { uint32_t v[10]; } fe; + +// fe_loose limbs are bounded by 3.375*2^26,3.375*2^25,3.375*2^26,3.375*2^25,etc. +// Addition and subtraction produce fe_loose from (fe, fe). +typedef struct fe_loose { uint32_t v[10]; } fe_loose; +#endif + +// ge means group element. +// +// Here the group is the set of pairs (x,y) of field elements (see fe.h) +// satisfying -x^2 + y^2 = 1 + d x^2y^2 +// where d = -121665/121666. +// +// Representations: +// ge_p2 (projective): (X:Y:Z) satisfying x=X/Z, y=Y/Z +// ge_p3 (extended): (X:Y:Z:T) satisfying x=X/Z, y=Y/Z, XY=ZT +// ge_p1p1 (completed): ((X:Z),(Y:T)) satisfying x=X/Z, y=Y/T +// ge_precomp (Duif): (y+x,y-x,2dxy) + +typedef struct { + fe X; + fe Y; + fe Z; +} ge_p2; + +typedef struct { + fe X; + fe Y; + fe Z; + fe T; +} ge_p3; + +typedef struct { + fe_loose X; + fe_loose Y; + fe_loose Z; + fe_loose T; +} ge_p1p1; + +typedef struct { + fe_loose yplusx; + fe_loose yminusx; + fe_loose xy2d; +} ge_precomp; + +typedef struct { + fe_loose YplusX; + fe_loose YminusX; + fe_loose Z; + fe_loose T2d; +} ge_cached; + +void x25519_ge_tobytes(uint8_t s[32], const ge_p2 *h); +int x25519_ge_frombytes_vartime(ge_p3 *h, const uint8_t *s); +void x25519_ge_p3_to_cached(ge_cached *r, const ge_p3 *p); +void x25519_ge_p1p1_to_p2(ge_p2 *r, const ge_p1p1 *p); +void x25519_ge_p1p1_to_p3(ge_p3 *r, const ge_p1p1 *p); +void x25519_ge_add(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q); +void x25519_ge_sub(ge_p1p1 *r, const ge_p3 *p, const ge_cached *q); +void x25519_ge_scalarmult_small_precomp( + ge_p3 *h, const uint8_t a[32], const uint8_t precomp_table[15 * 2 * 32]); +void x25519_ge_scalarmult_base(ge_p3 *h, const uint8_t a[32]); +void x25519_ge_scalarmult(ge_p2 *r, const uint8_t *scalar, const ge_p3 *A); +void x25519_sc_reduce(uint8_t s[64]); + +enum spake2_state_t { + spake2_state_init = 0, + spake2_state_msg_generated, + spake2_state_key_generated, +}; + +struct spake2_ctx_st { + uint8_t private_key[32]; + uint8_t my_msg[32]; + uint8_t password_scalar[32]; + uint8_t password_hash[64]; + uint8_t *my_name; + size_t my_name_len; + uint8_t *their_name; + size_t their_name_len; + enum spake2_role_t my_role; + enum spake2_state_t state; + char disable_password_scalar_hack; +}; + + +#if defined(__cplusplus) +} // extern C +#endif + +#endif // OPENSSL_HEADER_CURVE25519_INTERNAL_H diff --git a/FoodApp/Pods/BoringSSL-GRPC/third_party/fiat/p256.c b/FoodApp/Pods/BoringSSL-GRPC/third_party/fiat/p256.c new file mode 100644 index 0000000..c501a33 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/third_party/fiat/p256.c @@ -0,0 +1,1824 @@ +// The MIT License (MIT) +// +// Copyright (c) 2015-2016 the fiat-crypto authors (see the AUTHORS file). +// +// 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. + +// The field arithmetic code is generated by Fiat +// (https://github.com/mit-plv/fiat-crypto), which is MIT licensed. +// +// An implementation of the NIST P-256 elliptic curve point multiplication. +// 256-bit Montgomery form, generated using fiat-crypto, for 64 and 32-bit. +// Field operations with inputs in [0,p) return outputs in [0,p). + +#include + +#include +#include +#include +#include + +#include + +#include "../../crypto/fipsmodule/delocate.h" +#include "../../crypto/fipsmodule/ec/internal.h" +#include "../../crypto/internal.h" + + +// MSVC does not implement uint128_t, and crashes with intrinsics +#if defined(BORINGSSL_HAS_UINT128) +#define BORINGSSL_NISTP256_64BIT 1 +#endif + +// "intrinsics" + +#if defined(BORINGSSL_NISTP256_64BIT) + +static uint64_t mulx_u64(uint64_t a, uint64_t b, uint64_t *high) { + uint128_t x = (uint128_t)a * b; + *high = (uint64_t) (x >> 64); + return (uint64_t) x; +} + +static uint64_t addcarryx_u64(uint8_t c, uint64_t a, uint64_t b, uint64_t *low) { + uint128_t x = (uint128_t)a + b + c; + *low = (uint64_t) x; + return (uint64_t) (x>>64); +} + +static uint64_t subborrow_u64(uint8_t c, uint64_t a, uint64_t b, uint64_t *low) { + uint128_t t = ((uint128_t) b + c); + uint128_t x = a-t; + *low = (uint64_t) x; + return (uint8_t) (x>>127); +} + +static uint64_t cmovznz_u64(uint64_t t, uint64_t z, uint64_t nz) { + t = -!!t; // all set if nonzero, 0 if 0 + return (t&nz) | ((~t)&z); +} + +#else + +static uint32_t mulx_u32(uint32_t a, uint32_t b, uint32_t *high) { + uint64_t x = (uint64_t)a * b; + *high = (uint32_t) (x >> 32); + return (uint32_t) x; +} + +static uint32_t addcarryx_u32(uint8_t c, uint32_t a, uint32_t b, uint32_t *low) { + uint64_t x = (uint64_t)a + b + c; + *low = (uint32_t) x; + return (uint32_t) (x>>32); +} + +static uint32_t subborrow_u32(uint8_t c, uint32_t a, uint32_t b, uint32_t *low) { + uint64_t t = ((uint64_t) b + c); + uint64_t x = a-t; + *low = (uint32_t) x; + return (uint8_t) (x>>63); +} + +static uint32_t cmovznz_u32(uint32_t t, uint32_t z, uint32_t nz) { + t = -!!t; // all set if nonzero, 0 if 0 + return (t&nz) | ((~t)&z); +} + +#endif + +// fiat-crypto generated code + +#if defined(BORINGSSL_NISTP256_64BIT) + +static void fe_add(uint64_t out[4], const uint64_t in1[4], const uint64_t in2[4]) { + { const uint64_t x8 = in1[3]; + { const uint64_t x9 = in1[2]; + { const uint64_t x7 = in1[1]; + { const uint64_t x5 = in1[0]; + { const uint64_t x14 = in2[3]; + { const uint64_t x15 = in2[2]; + { const uint64_t x13 = in2[1]; + { const uint64_t x11 = in2[0]; + { uint64_t x17; uint8_t x18 = addcarryx_u64(0x0, x5, x11, &x17); + { uint64_t x20; uint8_t x21 = addcarryx_u64(x18, x7, x13, &x20); + { uint64_t x23; uint8_t x24 = addcarryx_u64(x21, x9, x15, &x23); + { uint64_t x26; uint8_t x27 = addcarryx_u64(x24, x8, x14, &x26); + { uint64_t x29; uint8_t x30 = subborrow_u64(0x0, x17, 0xffffffffffffffffL, &x29); + { uint64_t x32; uint8_t x33 = subborrow_u64(x30, x20, 0xffffffff, &x32); + { uint64_t x35; uint8_t x36 = subborrow_u64(x33, x23, 0x0, &x35); + { uint64_t x38; uint8_t x39 = subborrow_u64(x36, x26, 0xffffffff00000001L, &x38); + { uint64_t _1; uint8_t x42 = subborrow_u64(x39, x27, 0x0, &_1); + { uint64_t x43 = cmovznz_u64(x42, x38, x26); + { uint64_t x44 = cmovznz_u64(x42, x35, x23); + { uint64_t x45 = cmovznz_u64(x42, x32, x20); + { uint64_t x46 = cmovznz_u64(x42, x29, x17); + out[0] = x46; + out[1] = x45; + out[2] = x44; + out[3] = x43; + }}}}}}}}}}}}}}}}}}}}} +} + +// fe_op sets out = -in +static void fe_opp(uint64_t out[4], const uint64_t in1[4]) { + const uint64_t x5 = in1[3]; + const uint64_t x6 = in1[2]; + const uint64_t x4 = in1[1]; + const uint64_t x2 = in1[0]; + uint64_t x8; uint8_t x9 = subborrow_u64(0x0, 0x0, x2, &x8); + uint64_t x11; uint8_t x12 = subborrow_u64(x9, 0x0, x4, &x11); + uint64_t x14; uint8_t x15 = subborrow_u64(x12, 0x0, x6, &x14); + uint64_t x17; uint8_t x18 = subborrow_u64(x15, 0x0, x5, &x17); + uint64_t x19 = (uint64_t)cmovznz_u64(x18, 0x0, 0xffffffffffffffffL); + uint64_t x20 = (x19 & 0xffffffffffffffffL); + uint64_t x22; uint8_t x23 = addcarryx_u64(0x0, x8, x20, &x22); + uint64_t x24 = (x19 & 0xffffffff); + uint64_t x26; uint8_t x27 = addcarryx_u64(x23, x11, x24, &x26); + uint64_t x29; uint8_t x30 = addcarryx_u64(x27, x14, 0x0, &x29); + uint64_t x31 = (x19 & 0xffffffff00000001L); + uint64_t x33; addcarryx_u64(x30, x17, x31, &x33); + out[0] = x22; + out[1] = x26; + out[2] = x29; + out[3] = x33; +} + +static void fe_mul(uint64_t out[4], const uint64_t in1[4], const uint64_t in2[4]) { + const uint64_t x8 = in1[3]; + const uint64_t x9 = in1[2]; + const uint64_t x7 = in1[1]; + const uint64_t x5 = in1[0]; + const uint64_t x14 = in2[3]; + const uint64_t x15 = in2[2]; + const uint64_t x13 = in2[1]; + const uint64_t x11 = in2[0]; + uint64_t x18; uint64_t x17 = mulx_u64(x5, x11, &x18); + uint64_t x21; uint64_t x20 = mulx_u64(x5, x13, &x21); + uint64_t x24; uint64_t x23 = mulx_u64(x5, x15, &x24); + uint64_t x27; uint64_t x26 = mulx_u64(x5, x14, &x27); + uint64_t x29; uint8_t x30 = addcarryx_u64(0x0, x18, x20, &x29); + uint64_t x32; uint8_t x33 = addcarryx_u64(x30, x21, x23, &x32); + uint64_t x35; uint8_t x36 = addcarryx_u64(x33, x24, x26, &x35); + uint64_t x38; addcarryx_u64(0x0, x36, x27, &x38); + uint64_t x42; uint64_t x41 = mulx_u64(x17, 0xffffffffffffffffL, &x42); + uint64_t x45; uint64_t x44 = mulx_u64(x17, 0xffffffff, &x45); + uint64_t x48; uint64_t x47 = mulx_u64(x17, 0xffffffff00000001L, &x48); + uint64_t x50; uint8_t x51 = addcarryx_u64(0x0, x42, x44, &x50); + uint64_t x53; uint8_t x54 = addcarryx_u64(x51, x45, 0x0, &x53); + uint64_t x56; uint8_t x57 = addcarryx_u64(x54, 0x0, x47, &x56); + uint64_t x59; addcarryx_u64(0x0, x57, x48, &x59); + uint64_t _2; uint8_t x63 = addcarryx_u64(0x0, x17, x41, &_2); + uint64_t x65; uint8_t x66 = addcarryx_u64(x63, x29, x50, &x65); + uint64_t x68; uint8_t x69 = addcarryx_u64(x66, x32, x53, &x68); + uint64_t x71; uint8_t x72 = addcarryx_u64(x69, x35, x56, &x71); + uint64_t x74; uint8_t x75 = addcarryx_u64(x72, x38, x59, &x74); + uint64_t x78; uint64_t x77 = mulx_u64(x7, x11, &x78); + uint64_t x81; uint64_t x80 = mulx_u64(x7, x13, &x81); + uint64_t x84; uint64_t x83 = mulx_u64(x7, x15, &x84); + uint64_t x87; uint64_t x86 = mulx_u64(x7, x14, &x87); + uint64_t x89; uint8_t x90 = addcarryx_u64(0x0, x78, x80, &x89); + uint64_t x92; uint8_t x93 = addcarryx_u64(x90, x81, x83, &x92); + uint64_t x95; uint8_t x96 = addcarryx_u64(x93, x84, x86, &x95); + uint64_t x98; addcarryx_u64(0x0, x96, x87, &x98); + uint64_t x101; uint8_t x102 = addcarryx_u64(0x0, x65, x77, &x101); + uint64_t x104; uint8_t x105 = addcarryx_u64(x102, x68, x89, &x104); + uint64_t x107; uint8_t x108 = addcarryx_u64(x105, x71, x92, &x107); + uint64_t x110; uint8_t x111 = addcarryx_u64(x108, x74, x95, &x110); + uint64_t x113; uint8_t x114 = addcarryx_u64(x111, x75, x98, &x113); + uint64_t x117; uint64_t x116 = mulx_u64(x101, 0xffffffffffffffffL, &x117); + uint64_t x120; uint64_t x119 = mulx_u64(x101, 0xffffffff, &x120); + uint64_t x123; uint64_t x122 = mulx_u64(x101, 0xffffffff00000001L, &x123); + uint64_t x125; uint8_t x126 = addcarryx_u64(0x0, x117, x119, &x125); + uint64_t x128; uint8_t x129 = addcarryx_u64(x126, x120, 0x0, &x128); + uint64_t x131; uint8_t x132 = addcarryx_u64(x129, 0x0, x122, &x131); + uint64_t x134; addcarryx_u64(0x0, x132, x123, &x134); + uint64_t _3; uint8_t x138 = addcarryx_u64(0x0, x101, x116, &_3); + uint64_t x140; uint8_t x141 = addcarryx_u64(x138, x104, x125, &x140); + uint64_t x143; uint8_t x144 = addcarryx_u64(x141, x107, x128, &x143); + uint64_t x146; uint8_t x147 = addcarryx_u64(x144, x110, x131, &x146); + uint64_t x149; uint8_t x150 = addcarryx_u64(x147, x113, x134, &x149); + uint8_t x151 = (x150 + x114); + uint64_t x154; uint64_t x153 = mulx_u64(x9, x11, &x154); + uint64_t x157; uint64_t x156 = mulx_u64(x9, x13, &x157); + uint64_t x160; uint64_t x159 = mulx_u64(x9, x15, &x160); + uint64_t x163; uint64_t x162 = mulx_u64(x9, x14, &x163); + uint64_t x165; uint8_t x166 = addcarryx_u64(0x0, x154, x156, &x165); + uint64_t x168; uint8_t x169 = addcarryx_u64(x166, x157, x159, &x168); + uint64_t x171; uint8_t x172 = addcarryx_u64(x169, x160, x162, &x171); + uint64_t x174; addcarryx_u64(0x0, x172, x163, &x174); + uint64_t x177; uint8_t x178 = addcarryx_u64(0x0, x140, x153, &x177); + uint64_t x180; uint8_t x181 = addcarryx_u64(x178, x143, x165, &x180); + uint64_t x183; uint8_t x184 = addcarryx_u64(x181, x146, x168, &x183); + uint64_t x186; uint8_t x187 = addcarryx_u64(x184, x149, x171, &x186); + uint64_t x189; uint8_t x190 = addcarryx_u64(x187, x151, x174, &x189); + uint64_t x193; uint64_t x192 = mulx_u64(x177, 0xffffffffffffffffL, &x193); + uint64_t x196; uint64_t x195 = mulx_u64(x177, 0xffffffff, &x196); + uint64_t x199; uint64_t x198 = mulx_u64(x177, 0xffffffff00000001L, &x199); + uint64_t x201; uint8_t x202 = addcarryx_u64(0x0, x193, x195, &x201); + uint64_t x204; uint8_t x205 = addcarryx_u64(x202, x196, 0x0, &x204); + uint64_t x207; uint8_t x208 = addcarryx_u64(x205, 0x0, x198, &x207); + uint64_t x210; addcarryx_u64(0x0, x208, x199, &x210); + uint64_t _4; uint8_t x214 = addcarryx_u64(0x0, x177, x192, &_4); + uint64_t x216; uint8_t x217 = addcarryx_u64(x214, x180, x201, &x216); + uint64_t x219; uint8_t x220 = addcarryx_u64(x217, x183, x204, &x219); + uint64_t x222; uint8_t x223 = addcarryx_u64(x220, x186, x207, &x222); + uint64_t x225; uint8_t x226 = addcarryx_u64(x223, x189, x210, &x225); + uint8_t x227 = (x226 + x190); + uint64_t x230; uint64_t x229 = mulx_u64(x8, x11, &x230); + uint64_t x233; uint64_t x232 = mulx_u64(x8, x13, &x233); + uint64_t x236; uint64_t x235 = mulx_u64(x8, x15, &x236); + uint64_t x239; uint64_t x238 = mulx_u64(x8, x14, &x239); + uint64_t x241; uint8_t x242 = addcarryx_u64(0x0, x230, x232, &x241); + uint64_t x244; uint8_t x245 = addcarryx_u64(x242, x233, x235, &x244); + uint64_t x247; uint8_t x248 = addcarryx_u64(x245, x236, x238, &x247); + uint64_t x250; addcarryx_u64(0x0, x248, x239, &x250); + uint64_t x253; uint8_t x254 = addcarryx_u64(0x0, x216, x229, &x253); + uint64_t x256; uint8_t x257 = addcarryx_u64(x254, x219, x241, &x256); + uint64_t x259; uint8_t x260 = addcarryx_u64(x257, x222, x244, &x259); + uint64_t x262; uint8_t x263 = addcarryx_u64(x260, x225, x247, &x262); + uint64_t x265; uint8_t x266 = addcarryx_u64(x263, x227, x250, &x265); + uint64_t x269; uint64_t x268 = mulx_u64(x253, 0xffffffffffffffffL, &x269); + uint64_t x272; uint64_t x271 = mulx_u64(x253, 0xffffffff, &x272); + uint64_t x275; uint64_t x274 = mulx_u64(x253, 0xffffffff00000001L, &x275); + uint64_t x277; uint8_t x278 = addcarryx_u64(0x0, x269, x271, &x277); + uint64_t x280; uint8_t x281 = addcarryx_u64(x278, x272, 0x0, &x280); + uint64_t x283; uint8_t x284 = addcarryx_u64(x281, 0x0, x274, &x283); + uint64_t x286; addcarryx_u64(0x0, x284, x275, &x286); + uint64_t _5; uint8_t x290 = addcarryx_u64(0x0, x253, x268, &_5); + uint64_t x292; uint8_t x293 = addcarryx_u64(x290, x256, x277, &x292); + uint64_t x295; uint8_t x296 = addcarryx_u64(x293, x259, x280, &x295); + uint64_t x298; uint8_t x299 = addcarryx_u64(x296, x262, x283, &x298); + uint64_t x301; uint8_t x302 = addcarryx_u64(x299, x265, x286, &x301); + uint8_t x303 = (x302 + x266); + uint64_t x305; uint8_t x306 = subborrow_u64(0x0, x292, 0xffffffffffffffffL, &x305); + uint64_t x308; uint8_t x309 = subborrow_u64(x306, x295, 0xffffffff, &x308); + uint64_t x311; uint8_t x312 = subborrow_u64(x309, x298, 0x0, &x311); + uint64_t x314; uint8_t x315 = subborrow_u64(x312, x301, 0xffffffff00000001L, &x314); + uint64_t _6; uint8_t x318 = subborrow_u64(x315, x303, 0x0, &_6); + uint64_t x319 = cmovznz_u64(x318, x314, x301); + uint64_t x320 = cmovznz_u64(x318, x311, x298); + uint64_t x321 = cmovznz_u64(x318, x308, x295); + uint64_t x322 = cmovznz_u64(x318, x305, x292); + out[0] = x322; + out[1] = x321; + out[2] = x320; + out[3] = x319; +} + +static void fe_sub(uint64_t out[4], const uint64_t in1[4], const uint64_t in2[4]) { + const uint64_t x8 = in1[3]; + const uint64_t x9 = in1[2]; + const uint64_t x7 = in1[1]; + const uint64_t x5 = in1[0]; + const uint64_t x14 = in2[3]; + const uint64_t x15 = in2[2]; + const uint64_t x13 = in2[1]; + const uint64_t x11 = in2[0]; + uint64_t x17; uint8_t x18 = subborrow_u64(0x0, x5, x11, &x17); + uint64_t x20; uint8_t x21 = subborrow_u64(x18, x7, x13, &x20); + uint64_t x23; uint8_t x24 = subborrow_u64(x21, x9, x15, &x23); + uint64_t x26; uint8_t x27 = subborrow_u64(x24, x8, x14, &x26); + uint64_t x28 = (uint64_t)cmovznz_u64(x27, 0x0, 0xffffffffffffffffL); + uint64_t x29 = (x28 & 0xffffffffffffffffL); + uint64_t x31; uint8_t x32 = addcarryx_u64(0x0, x17, x29, &x31); + uint64_t x33 = (x28 & 0xffffffff); + uint64_t x35; uint8_t x36 = addcarryx_u64(x32, x20, x33, &x35); + uint64_t x38; uint8_t x39 = addcarryx_u64(x36, x23, 0x0, &x38); + uint64_t x40 = (x28 & 0xffffffff00000001L); + uint64_t x42; addcarryx_u64(x39, x26, x40, &x42); + out[0] = x31; + out[1] = x35; + out[2] = x38; + out[3] = x42; +} + +#else // 64BIT, else 32BIT + +static void fe_add(uint32_t out[8], const uint32_t in1[8], const uint32_t in2[8]) { + const uint32_t x16 = in1[7]; + const uint32_t x17 = in1[6]; + const uint32_t x15 = in1[5]; + const uint32_t x13 = in1[4]; + const uint32_t x11 = in1[3]; + const uint32_t x9 = in1[2]; + const uint32_t x7 = in1[1]; + const uint32_t x5 = in1[0]; + const uint32_t x30 = in2[7]; + const uint32_t x31 = in2[6]; + const uint32_t x29 = in2[5]; + const uint32_t x27 = in2[4]; + const uint32_t x25 = in2[3]; + const uint32_t x23 = in2[2]; + const uint32_t x21 = in2[1]; + const uint32_t x19 = in2[0]; + uint32_t x33; uint8_t x34 = addcarryx_u32(0x0, x5, x19, &x33); + uint32_t x36; uint8_t x37 = addcarryx_u32(x34, x7, x21, &x36); + uint32_t x39; uint8_t x40 = addcarryx_u32(x37, x9, x23, &x39); + uint32_t x42; uint8_t x43 = addcarryx_u32(x40, x11, x25, &x42); + uint32_t x45; uint8_t x46 = addcarryx_u32(x43, x13, x27, &x45); + uint32_t x48; uint8_t x49 = addcarryx_u32(x46, x15, x29, &x48); + uint32_t x51; uint8_t x52 = addcarryx_u32(x49, x17, x31, &x51); + uint32_t x54; uint8_t x55 = addcarryx_u32(x52, x16, x30, &x54); + uint32_t x57; uint8_t x58 = subborrow_u32(0x0, x33, 0xffffffff, &x57); + uint32_t x60; uint8_t x61 = subborrow_u32(x58, x36, 0xffffffff, &x60); + uint32_t x63; uint8_t x64 = subborrow_u32(x61, x39, 0xffffffff, &x63); + uint32_t x66; uint8_t x67 = subborrow_u32(x64, x42, 0x0, &x66); + uint32_t x69; uint8_t x70 = subborrow_u32(x67, x45, 0x0, &x69); + uint32_t x72; uint8_t x73 = subborrow_u32(x70, x48, 0x0, &x72); + uint32_t x75; uint8_t x76 = subborrow_u32(x73, x51, 0x1, &x75); + uint32_t x78; uint8_t x79 = subborrow_u32(x76, x54, 0xffffffff, &x78); + uint32_t _; uint8_t x82 = subborrow_u32(x79, x55, 0x0, &_); + uint32_t x83 = cmovznz_u32(x82, x78, x54); + uint32_t x84 = cmovznz_u32(x82, x75, x51); + uint32_t x85 = cmovznz_u32(x82, x72, x48); + uint32_t x86 = cmovznz_u32(x82, x69, x45); + uint32_t x87 = cmovznz_u32(x82, x66, x42); + uint32_t x88 = cmovznz_u32(x82, x63, x39); + uint32_t x89 = cmovznz_u32(x82, x60, x36); + uint32_t x90 = cmovznz_u32(x82, x57, x33); + out[0] = x90; + out[1] = x89; + out[2] = x88; + out[3] = x87; + out[4] = x86; + out[5] = x85; + out[6] = x84; + out[7] = x83; +} + +static void fe_mul(uint32_t out[8], const uint32_t in1[8], const uint32_t in2[8]) { + const uint32_t x16 = in1[7]; + const uint32_t x17 = in1[6]; + const uint32_t x15 = in1[5]; + const uint32_t x13 = in1[4]; + const uint32_t x11 = in1[3]; + const uint32_t x9 = in1[2]; + const uint32_t x7 = in1[1]; + const uint32_t x5 = in1[0]; + const uint32_t x30 = in2[7]; + const uint32_t x31 = in2[6]; + const uint32_t x29 = in2[5]; + const uint32_t x27 = in2[4]; + const uint32_t x25 = in2[3]; + const uint32_t x23 = in2[2]; + const uint32_t x21 = in2[1]; + const uint32_t x19 = in2[0]; + uint32_t x34; uint32_t x33 = mulx_u32(x5, x19, &x34); + uint32_t x37; uint32_t x36 = mulx_u32(x5, x21, &x37); + uint32_t x40; uint32_t x39 = mulx_u32(x5, x23, &x40); + uint32_t x43; uint32_t x42 = mulx_u32(x5, x25, &x43); + uint32_t x46; uint32_t x45 = mulx_u32(x5, x27, &x46); + uint32_t x49; uint32_t x48 = mulx_u32(x5, x29, &x49); + uint32_t x52; uint32_t x51 = mulx_u32(x5, x31, &x52); + uint32_t x55; uint32_t x54 = mulx_u32(x5, x30, &x55); + uint32_t x57; uint8_t x58 = addcarryx_u32(0x0, x34, x36, &x57); + uint32_t x60; uint8_t x61 = addcarryx_u32(x58, x37, x39, &x60); + uint32_t x63; uint8_t x64 = addcarryx_u32(x61, x40, x42, &x63); + uint32_t x66; uint8_t x67 = addcarryx_u32(x64, x43, x45, &x66); + uint32_t x69; uint8_t x70 = addcarryx_u32(x67, x46, x48, &x69); + uint32_t x72; uint8_t x73 = addcarryx_u32(x70, x49, x51, &x72); + uint32_t x75; uint8_t x76 = addcarryx_u32(x73, x52, x54, &x75); + uint32_t x78; addcarryx_u32(0x0, x76, x55, &x78); + uint32_t x82; uint32_t x81 = mulx_u32(x33, 0xffffffff, &x82); + uint32_t x85; uint32_t x84 = mulx_u32(x33, 0xffffffff, &x85); + uint32_t x88; uint32_t x87 = mulx_u32(x33, 0xffffffff, &x88); + uint32_t x91; uint32_t x90 = mulx_u32(x33, 0xffffffff, &x91); + uint32_t x93; uint8_t x94 = addcarryx_u32(0x0, x82, x84, &x93); + uint32_t x96; uint8_t x97 = addcarryx_u32(x94, x85, x87, &x96); + uint32_t x99; uint8_t x100 = addcarryx_u32(x97, x88, 0x0, &x99); + uint8_t x101 = (0x0 + 0x0); + uint32_t _1; uint8_t x104 = addcarryx_u32(0x0, x33, x81, &_1); + uint32_t x106; uint8_t x107 = addcarryx_u32(x104, x57, x93, &x106); + uint32_t x109; uint8_t x110 = addcarryx_u32(x107, x60, x96, &x109); + uint32_t x112; uint8_t x113 = addcarryx_u32(x110, x63, x99, &x112); + uint32_t x115; uint8_t x116 = addcarryx_u32(x113, x66, x100, &x115); + uint32_t x118; uint8_t x119 = addcarryx_u32(x116, x69, x101, &x118); + uint32_t x121; uint8_t x122 = addcarryx_u32(x119, x72, x33, &x121); + uint32_t x124; uint8_t x125 = addcarryx_u32(x122, x75, x90, &x124); + uint32_t x127; uint8_t x128 = addcarryx_u32(x125, x78, x91, &x127); + uint8_t x129 = (x128 + 0x0); + uint32_t x132; uint32_t x131 = mulx_u32(x7, x19, &x132); + uint32_t x135; uint32_t x134 = mulx_u32(x7, x21, &x135); + uint32_t x138; uint32_t x137 = mulx_u32(x7, x23, &x138); + uint32_t x141; uint32_t x140 = mulx_u32(x7, x25, &x141); + uint32_t x144; uint32_t x143 = mulx_u32(x7, x27, &x144); + uint32_t x147; uint32_t x146 = mulx_u32(x7, x29, &x147); + uint32_t x150; uint32_t x149 = mulx_u32(x7, x31, &x150); + uint32_t x153; uint32_t x152 = mulx_u32(x7, x30, &x153); + uint32_t x155; uint8_t x156 = addcarryx_u32(0x0, x132, x134, &x155); + uint32_t x158; uint8_t x159 = addcarryx_u32(x156, x135, x137, &x158); + uint32_t x161; uint8_t x162 = addcarryx_u32(x159, x138, x140, &x161); + uint32_t x164; uint8_t x165 = addcarryx_u32(x162, x141, x143, &x164); + uint32_t x167; uint8_t x168 = addcarryx_u32(x165, x144, x146, &x167); + uint32_t x170; uint8_t x171 = addcarryx_u32(x168, x147, x149, &x170); + uint32_t x173; uint8_t x174 = addcarryx_u32(x171, x150, x152, &x173); + uint32_t x176; addcarryx_u32(0x0, x174, x153, &x176); + uint32_t x179; uint8_t x180 = addcarryx_u32(0x0, x106, x131, &x179); + uint32_t x182; uint8_t x183 = addcarryx_u32(x180, x109, x155, &x182); + uint32_t x185; uint8_t x186 = addcarryx_u32(x183, x112, x158, &x185); + uint32_t x188; uint8_t x189 = addcarryx_u32(x186, x115, x161, &x188); + uint32_t x191; uint8_t x192 = addcarryx_u32(x189, x118, x164, &x191); + uint32_t x194; uint8_t x195 = addcarryx_u32(x192, x121, x167, &x194); + uint32_t x197; uint8_t x198 = addcarryx_u32(x195, x124, x170, &x197); + uint32_t x200; uint8_t x201 = addcarryx_u32(x198, x127, x173, &x200); + uint32_t x203; uint8_t x204 = addcarryx_u32(x201, x129, x176, &x203); + uint32_t x207; uint32_t x206 = mulx_u32(x179, 0xffffffff, &x207); + uint32_t x210; uint32_t x209 = mulx_u32(x179, 0xffffffff, &x210); + uint32_t x213; uint32_t x212 = mulx_u32(x179, 0xffffffff, &x213); + uint32_t x216; uint32_t x215 = mulx_u32(x179, 0xffffffff, &x216); + uint32_t x218; uint8_t x219 = addcarryx_u32(0x0, x207, x209, &x218); + uint32_t x221; uint8_t x222 = addcarryx_u32(x219, x210, x212, &x221); + uint32_t x224; uint8_t x225 = addcarryx_u32(x222, x213, 0x0, &x224); + uint8_t x226 = (0x0 + 0x0); + uint32_t _2; uint8_t x229 = addcarryx_u32(0x0, x179, x206, &_2); + uint32_t x231; uint8_t x232 = addcarryx_u32(x229, x182, x218, &x231); + uint32_t x234; uint8_t x235 = addcarryx_u32(x232, x185, x221, &x234); + uint32_t x237; uint8_t x238 = addcarryx_u32(x235, x188, x224, &x237); + uint32_t x240; uint8_t x241 = addcarryx_u32(x238, x191, x225, &x240); + uint32_t x243; uint8_t x244 = addcarryx_u32(x241, x194, x226, &x243); + uint32_t x246; uint8_t x247 = addcarryx_u32(x244, x197, x179, &x246); + uint32_t x249; uint8_t x250 = addcarryx_u32(x247, x200, x215, &x249); + uint32_t x252; uint8_t x253 = addcarryx_u32(x250, x203, x216, &x252); + uint8_t x254 = (x253 + x204); + uint32_t x257; uint32_t x256 = mulx_u32(x9, x19, &x257); + uint32_t x260; uint32_t x259 = mulx_u32(x9, x21, &x260); + uint32_t x263; uint32_t x262 = mulx_u32(x9, x23, &x263); + uint32_t x266; uint32_t x265 = mulx_u32(x9, x25, &x266); + uint32_t x269; uint32_t x268 = mulx_u32(x9, x27, &x269); + uint32_t x272; uint32_t x271 = mulx_u32(x9, x29, &x272); + uint32_t x275; uint32_t x274 = mulx_u32(x9, x31, &x275); + uint32_t x278; uint32_t x277 = mulx_u32(x9, x30, &x278); + uint32_t x280; uint8_t x281 = addcarryx_u32(0x0, x257, x259, &x280); + uint32_t x283; uint8_t x284 = addcarryx_u32(x281, x260, x262, &x283); + uint32_t x286; uint8_t x287 = addcarryx_u32(x284, x263, x265, &x286); + uint32_t x289; uint8_t x290 = addcarryx_u32(x287, x266, x268, &x289); + uint32_t x292; uint8_t x293 = addcarryx_u32(x290, x269, x271, &x292); + uint32_t x295; uint8_t x296 = addcarryx_u32(x293, x272, x274, &x295); + uint32_t x298; uint8_t x299 = addcarryx_u32(x296, x275, x277, &x298); + uint32_t x301; addcarryx_u32(0x0, x299, x278, &x301); + uint32_t x304; uint8_t x305 = addcarryx_u32(0x0, x231, x256, &x304); + uint32_t x307; uint8_t x308 = addcarryx_u32(x305, x234, x280, &x307); + uint32_t x310; uint8_t x311 = addcarryx_u32(x308, x237, x283, &x310); + uint32_t x313; uint8_t x314 = addcarryx_u32(x311, x240, x286, &x313); + uint32_t x316; uint8_t x317 = addcarryx_u32(x314, x243, x289, &x316); + uint32_t x319; uint8_t x320 = addcarryx_u32(x317, x246, x292, &x319); + uint32_t x322; uint8_t x323 = addcarryx_u32(x320, x249, x295, &x322); + uint32_t x325; uint8_t x326 = addcarryx_u32(x323, x252, x298, &x325); + uint32_t x328; uint8_t x329 = addcarryx_u32(x326, x254, x301, &x328); + uint32_t x332; uint32_t x331 = mulx_u32(x304, 0xffffffff, &x332); + uint32_t x335; uint32_t x334 = mulx_u32(x304, 0xffffffff, &x335); + uint32_t x338; uint32_t x337 = mulx_u32(x304, 0xffffffff, &x338); + uint32_t x341; uint32_t x340 = mulx_u32(x304, 0xffffffff, &x341); + uint32_t x343; uint8_t x344 = addcarryx_u32(0x0, x332, x334, &x343); + uint32_t x346; uint8_t x347 = addcarryx_u32(x344, x335, x337, &x346); + uint32_t x349; uint8_t x350 = addcarryx_u32(x347, x338, 0x0, &x349); + uint8_t x351 = (0x0 + 0x0); + uint32_t _3; uint8_t x354 = addcarryx_u32(0x0, x304, x331, &_3); + uint32_t x356; uint8_t x357 = addcarryx_u32(x354, x307, x343, &x356); + uint32_t x359; uint8_t x360 = addcarryx_u32(x357, x310, x346, &x359); + uint32_t x362; uint8_t x363 = addcarryx_u32(x360, x313, x349, &x362); + uint32_t x365; uint8_t x366 = addcarryx_u32(x363, x316, x350, &x365); + uint32_t x368; uint8_t x369 = addcarryx_u32(x366, x319, x351, &x368); + uint32_t x371; uint8_t x372 = addcarryx_u32(x369, x322, x304, &x371); + uint32_t x374; uint8_t x375 = addcarryx_u32(x372, x325, x340, &x374); + uint32_t x377; uint8_t x378 = addcarryx_u32(x375, x328, x341, &x377); + uint8_t x379 = (x378 + x329); + uint32_t x382; uint32_t x381 = mulx_u32(x11, x19, &x382); + uint32_t x385; uint32_t x384 = mulx_u32(x11, x21, &x385); + uint32_t x388; uint32_t x387 = mulx_u32(x11, x23, &x388); + uint32_t x391; uint32_t x390 = mulx_u32(x11, x25, &x391); + uint32_t x394; uint32_t x393 = mulx_u32(x11, x27, &x394); + uint32_t x397; uint32_t x396 = mulx_u32(x11, x29, &x397); + uint32_t x400; uint32_t x399 = mulx_u32(x11, x31, &x400); + uint32_t x403; uint32_t x402 = mulx_u32(x11, x30, &x403); + uint32_t x405; uint8_t x406 = addcarryx_u32(0x0, x382, x384, &x405); + uint32_t x408; uint8_t x409 = addcarryx_u32(x406, x385, x387, &x408); + uint32_t x411; uint8_t x412 = addcarryx_u32(x409, x388, x390, &x411); + uint32_t x414; uint8_t x415 = addcarryx_u32(x412, x391, x393, &x414); + uint32_t x417; uint8_t x418 = addcarryx_u32(x415, x394, x396, &x417); + uint32_t x420; uint8_t x421 = addcarryx_u32(x418, x397, x399, &x420); + uint32_t x423; uint8_t x424 = addcarryx_u32(x421, x400, x402, &x423); + uint32_t x426; addcarryx_u32(0x0, x424, x403, &x426); + uint32_t x429; uint8_t x430 = addcarryx_u32(0x0, x356, x381, &x429); + uint32_t x432; uint8_t x433 = addcarryx_u32(x430, x359, x405, &x432); + uint32_t x435; uint8_t x436 = addcarryx_u32(x433, x362, x408, &x435); + uint32_t x438; uint8_t x439 = addcarryx_u32(x436, x365, x411, &x438); + uint32_t x441; uint8_t x442 = addcarryx_u32(x439, x368, x414, &x441); + uint32_t x444; uint8_t x445 = addcarryx_u32(x442, x371, x417, &x444); + uint32_t x447; uint8_t x448 = addcarryx_u32(x445, x374, x420, &x447); + uint32_t x450; uint8_t x451 = addcarryx_u32(x448, x377, x423, &x450); + uint32_t x453; uint8_t x454 = addcarryx_u32(x451, x379, x426, &x453); + uint32_t x457; uint32_t x456 = mulx_u32(x429, 0xffffffff, &x457); + uint32_t x460; uint32_t x459 = mulx_u32(x429, 0xffffffff, &x460); + uint32_t x463; uint32_t x462 = mulx_u32(x429, 0xffffffff, &x463); + uint32_t x466; uint32_t x465 = mulx_u32(x429, 0xffffffff, &x466); + uint32_t x468; uint8_t x469 = addcarryx_u32(0x0, x457, x459, &x468); + uint32_t x471; uint8_t x472 = addcarryx_u32(x469, x460, x462, &x471); + uint32_t x474; uint8_t x475 = addcarryx_u32(x472, x463, 0x0, &x474); + uint8_t x476 = (0x0 + 0x0); + uint32_t _4; uint8_t x479 = addcarryx_u32(0x0, x429, x456, &_4); + uint32_t x481; uint8_t x482 = addcarryx_u32(x479, x432, x468, &x481); + uint32_t x484; uint8_t x485 = addcarryx_u32(x482, x435, x471, &x484); + uint32_t x487; uint8_t x488 = addcarryx_u32(x485, x438, x474, &x487); + uint32_t x490; uint8_t x491 = addcarryx_u32(x488, x441, x475, &x490); + uint32_t x493; uint8_t x494 = addcarryx_u32(x491, x444, x476, &x493); + uint32_t x496; uint8_t x497 = addcarryx_u32(x494, x447, x429, &x496); + uint32_t x499; uint8_t x500 = addcarryx_u32(x497, x450, x465, &x499); + uint32_t x502; uint8_t x503 = addcarryx_u32(x500, x453, x466, &x502); + uint8_t x504 = (x503 + x454); + uint32_t x507; uint32_t x506 = mulx_u32(x13, x19, &x507); + uint32_t x510; uint32_t x509 = mulx_u32(x13, x21, &x510); + uint32_t x513; uint32_t x512 = mulx_u32(x13, x23, &x513); + uint32_t x516; uint32_t x515 = mulx_u32(x13, x25, &x516); + uint32_t x519; uint32_t x518 = mulx_u32(x13, x27, &x519); + uint32_t x522; uint32_t x521 = mulx_u32(x13, x29, &x522); + uint32_t x525; uint32_t x524 = mulx_u32(x13, x31, &x525); + uint32_t x528; uint32_t x527 = mulx_u32(x13, x30, &x528); + uint32_t x530; uint8_t x531 = addcarryx_u32(0x0, x507, x509, &x530); + uint32_t x533; uint8_t x534 = addcarryx_u32(x531, x510, x512, &x533); + uint32_t x536; uint8_t x537 = addcarryx_u32(x534, x513, x515, &x536); + uint32_t x539; uint8_t x540 = addcarryx_u32(x537, x516, x518, &x539); + uint32_t x542; uint8_t x543 = addcarryx_u32(x540, x519, x521, &x542); + uint32_t x545; uint8_t x546 = addcarryx_u32(x543, x522, x524, &x545); + uint32_t x548; uint8_t x549 = addcarryx_u32(x546, x525, x527, &x548); + uint32_t x551; addcarryx_u32(0x0, x549, x528, &x551); + uint32_t x554; uint8_t x555 = addcarryx_u32(0x0, x481, x506, &x554); + uint32_t x557; uint8_t x558 = addcarryx_u32(x555, x484, x530, &x557); + uint32_t x560; uint8_t x561 = addcarryx_u32(x558, x487, x533, &x560); + uint32_t x563; uint8_t x564 = addcarryx_u32(x561, x490, x536, &x563); + uint32_t x566; uint8_t x567 = addcarryx_u32(x564, x493, x539, &x566); + uint32_t x569; uint8_t x570 = addcarryx_u32(x567, x496, x542, &x569); + uint32_t x572; uint8_t x573 = addcarryx_u32(x570, x499, x545, &x572); + uint32_t x575; uint8_t x576 = addcarryx_u32(x573, x502, x548, &x575); + uint32_t x578; uint8_t x579 = addcarryx_u32(x576, x504, x551, &x578); + uint32_t x582; uint32_t x581 = mulx_u32(x554, 0xffffffff, &x582); + uint32_t x585; uint32_t x584 = mulx_u32(x554, 0xffffffff, &x585); + uint32_t x588; uint32_t x587 = mulx_u32(x554, 0xffffffff, &x588); + uint32_t x591; uint32_t x590 = mulx_u32(x554, 0xffffffff, &x591); + uint32_t x593; uint8_t x594 = addcarryx_u32(0x0, x582, x584, &x593); + uint32_t x596; uint8_t x597 = addcarryx_u32(x594, x585, x587, &x596); + uint32_t x599; uint8_t x600 = addcarryx_u32(x597, x588, 0x0, &x599); + uint8_t x601 = (0x0 + 0x0); + uint32_t _5; uint8_t x604 = addcarryx_u32(0x0, x554, x581, &_5); + uint32_t x606; uint8_t x607 = addcarryx_u32(x604, x557, x593, &x606); + uint32_t x609; uint8_t x610 = addcarryx_u32(x607, x560, x596, &x609); + uint32_t x612; uint8_t x613 = addcarryx_u32(x610, x563, x599, &x612); + uint32_t x615; uint8_t x616 = addcarryx_u32(x613, x566, x600, &x615); + uint32_t x618; uint8_t x619 = addcarryx_u32(x616, x569, x601, &x618); + uint32_t x621; uint8_t x622 = addcarryx_u32(x619, x572, x554, &x621); + uint32_t x624; uint8_t x625 = addcarryx_u32(x622, x575, x590, &x624); + uint32_t x627; uint8_t x628 = addcarryx_u32(x625, x578, x591, &x627); + uint8_t x629 = (x628 + x579); + uint32_t x632; uint32_t x631 = mulx_u32(x15, x19, &x632); + uint32_t x635; uint32_t x634 = mulx_u32(x15, x21, &x635); + uint32_t x638; uint32_t x637 = mulx_u32(x15, x23, &x638); + uint32_t x641; uint32_t x640 = mulx_u32(x15, x25, &x641); + uint32_t x644; uint32_t x643 = mulx_u32(x15, x27, &x644); + uint32_t x647; uint32_t x646 = mulx_u32(x15, x29, &x647); + uint32_t x650; uint32_t x649 = mulx_u32(x15, x31, &x650); + uint32_t x653; uint32_t x652 = mulx_u32(x15, x30, &x653); + uint32_t x655; uint8_t x656 = addcarryx_u32(0x0, x632, x634, &x655); + uint32_t x658; uint8_t x659 = addcarryx_u32(x656, x635, x637, &x658); + uint32_t x661; uint8_t x662 = addcarryx_u32(x659, x638, x640, &x661); + uint32_t x664; uint8_t x665 = addcarryx_u32(x662, x641, x643, &x664); + uint32_t x667; uint8_t x668 = addcarryx_u32(x665, x644, x646, &x667); + uint32_t x670; uint8_t x671 = addcarryx_u32(x668, x647, x649, &x670); + uint32_t x673; uint8_t x674 = addcarryx_u32(x671, x650, x652, &x673); + uint32_t x676; addcarryx_u32(0x0, x674, x653, &x676); + uint32_t x679; uint8_t x680 = addcarryx_u32(0x0, x606, x631, &x679); + uint32_t x682; uint8_t x683 = addcarryx_u32(x680, x609, x655, &x682); + uint32_t x685; uint8_t x686 = addcarryx_u32(x683, x612, x658, &x685); + uint32_t x688; uint8_t x689 = addcarryx_u32(x686, x615, x661, &x688); + uint32_t x691; uint8_t x692 = addcarryx_u32(x689, x618, x664, &x691); + uint32_t x694; uint8_t x695 = addcarryx_u32(x692, x621, x667, &x694); + uint32_t x697; uint8_t x698 = addcarryx_u32(x695, x624, x670, &x697); + uint32_t x700; uint8_t x701 = addcarryx_u32(x698, x627, x673, &x700); + uint32_t x703; uint8_t x704 = addcarryx_u32(x701, x629, x676, &x703); + uint32_t x707; uint32_t x706 = mulx_u32(x679, 0xffffffff, &x707); + uint32_t x710; uint32_t x709 = mulx_u32(x679, 0xffffffff, &x710); + uint32_t x713; uint32_t x712 = mulx_u32(x679, 0xffffffff, &x713); + uint32_t x716; uint32_t x715 = mulx_u32(x679, 0xffffffff, &x716); + uint32_t x718; uint8_t x719 = addcarryx_u32(0x0, x707, x709, &x718); + uint32_t x721; uint8_t x722 = addcarryx_u32(x719, x710, x712, &x721); + uint32_t x724; uint8_t x725 = addcarryx_u32(x722, x713, 0x0, &x724); + uint8_t x726 = (0x0 + 0x0); + uint32_t _6; uint8_t x729 = addcarryx_u32(0x0, x679, x706, &_6); + uint32_t x731; uint8_t x732 = addcarryx_u32(x729, x682, x718, &x731); + uint32_t x734; uint8_t x735 = addcarryx_u32(x732, x685, x721, &x734); + uint32_t x737; uint8_t x738 = addcarryx_u32(x735, x688, x724, &x737); + uint32_t x740; uint8_t x741 = addcarryx_u32(x738, x691, x725, &x740); + uint32_t x743; uint8_t x744 = addcarryx_u32(x741, x694, x726, &x743); + uint32_t x746; uint8_t x747 = addcarryx_u32(x744, x697, x679, &x746); + uint32_t x749; uint8_t x750 = addcarryx_u32(x747, x700, x715, &x749); + uint32_t x752; uint8_t x753 = addcarryx_u32(x750, x703, x716, &x752); + uint8_t x754 = (x753 + x704); + uint32_t x757; uint32_t x756 = mulx_u32(x17, x19, &x757); + uint32_t x760; uint32_t x759 = mulx_u32(x17, x21, &x760); + uint32_t x763; uint32_t x762 = mulx_u32(x17, x23, &x763); + uint32_t x766; uint32_t x765 = mulx_u32(x17, x25, &x766); + uint32_t x769; uint32_t x768 = mulx_u32(x17, x27, &x769); + uint32_t x772; uint32_t x771 = mulx_u32(x17, x29, &x772); + uint32_t x775; uint32_t x774 = mulx_u32(x17, x31, &x775); + uint32_t x778; uint32_t x777 = mulx_u32(x17, x30, &x778); + uint32_t x780; uint8_t x781 = addcarryx_u32(0x0, x757, x759, &x780); + uint32_t x783; uint8_t x784 = addcarryx_u32(x781, x760, x762, &x783); + uint32_t x786; uint8_t x787 = addcarryx_u32(x784, x763, x765, &x786); + uint32_t x789; uint8_t x790 = addcarryx_u32(x787, x766, x768, &x789); + uint32_t x792; uint8_t x793 = addcarryx_u32(x790, x769, x771, &x792); + uint32_t x795; uint8_t x796 = addcarryx_u32(x793, x772, x774, &x795); + uint32_t x798; uint8_t x799 = addcarryx_u32(x796, x775, x777, &x798); + uint32_t x801; addcarryx_u32(0x0, x799, x778, &x801); + uint32_t x804; uint8_t x805 = addcarryx_u32(0x0, x731, x756, &x804); + uint32_t x807; uint8_t x808 = addcarryx_u32(x805, x734, x780, &x807); + uint32_t x810; uint8_t x811 = addcarryx_u32(x808, x737, x783, &x810); + uint32_t x813; uint8_t x814 = addcarryx_u32(x811, x740, x786, &x813); + uint32_t x816; uint8_t x817 = addcarryx_u32(x814, x743, x789, &x816); + uint32_t x819; uint8_t x820 = addcarryx_u32(x817, x746, x792, &x819); + uint32_t x822; uint8_t x823 = addcarryx_u32(x820, x749, x795, &x822); + uint32_t x825; uint8_t x826 = addcarryx_u32(x823, x752, x798, &x825); + uint32_t x828; uint8_t x829 = addcarryx_u32(x826, x754, x801, &x828); + uint32_t x832; uint32_t x831 = mulx_u32(x804, 0xffffffff, &x832); + uint32_t x835; uint32_t x834 = mulx_u32(x804, 0xffffffff, &x835); + uint32_t x838; uint32_t x837 = mulx_u32(x804, 0xffffffff, &x838); + uint32_t x841; uint32_t x840 = mulx_u32(x804, 0xffffffff, &x841); + uint32_t x843; uint8_t x844 = addcarryx_u32(0x0, x832, x834, &x843); + uint32_t x846; uint8_t x847 = addcarryx_u32(x844, x835, x837, &x846); + uint32_t x849; uint8_t x850 = addcarryx_u32(x847, x838, 0x0, &x849); + uint8_t x851 = (0x0 + 0x0); + uint32_t _7; uint8_t x854 = addcarryx_u32(0x0, x804, x831, &_7); + uint32_t x856; uint8_t x857 = addcarryx_u32(x854, x807, x843, &x856); + uint32_t x859; uint8_t x860 = addcarryx_u32(x857, x810, x846, &x859); + uint32_t x862; uint8_t x863 = addcarryx_u32(x860, x813, x849, &x862); + uint32_t x865; uint8_t x866 = addcarryx_u32(x863, x816, x850, &x865); + uint32_t x868; uint8_t x869 = addcarryx_u32(x866, x819, x851, &x868); + uint32_t x871; uint8_t x872 = addcarryx_u32(x869, x822, x804, &x871); + uint32_t x874; uint8_t x875 = addcarryx_u32(x872, x825, x840, &x874); + uint32_t x877; uint8_t x878 = addcarryx_u32(x875, x828, x841, &x877); + uint8_t x879 = (x878 + x829); + uint32_t x882; uint32_t x881 = mulx_u32(x16, x19, &x882); + uint32_t x885; uint32_t x884 = mulx_u32(x16, x21, &x885); + uint32_t x888; uint32_t x887 = mulx_u32(x16, x23, &x888); + uint32_t x891; uint32_t x890 = mulx_u32(x16, x25, &x891); + uint32_t x894; uint32_t x893 = mulx_u32(x16, x27, &x894); + uint32_t x897; uint32_t x896 = mulx_u32(x16, x29, &x897); + uint32_t x900; uint32_t x899 = mulx_u32(x16, x31, &x900); + uint32_t x903; uint32_t x902 = mulx_u32(x16, x30, &x903); + uint32_t x905; uint8_t x906 = addcarryx_u32(0x0, x882, x884, &x905); + uint32_t x908; uint8_t x909 = addcarryx_u32(x906, x885, x887, &x908); + uint32_t x911; uint8_t x912 = addcarryx_u32(x909, x888, x890, &x911); + uint32_t x914; uint8_t x915 = addcarryx_u32(x912, x891, x893, &x914); + uint32_t x917; uint8_t x918 = addcarryx_u32(x915, x894, x896, &x917); + uint32_t x920; uint8_t x921 = addcarryx_u32(x918, x897, x899, &x920); + uint32_t x923; uint8_t x924 = addcarryx_u32(x921, x900, x902, &x923); + uint32_t x926; addcarryx_u32(0x0, x924, x903, &x926); + uint32_t x929; uint8_t x930 = addcarryx_u32(0x0, x856, x881, &x929); + uint32_t x932; uint8_t x933 = addcarryx_u32(x930, x859, x905, &x932); + uint32_t x935; uint8_t x936 = addcarryx_u32(x933, x862, x908, &x935); + uint32_t x938; uint8_t x939 = addcarryx_u32(x936, x865, x911, &x938); + uint32_t x941; uint8_t x942 = addcarryx_u32(x939, x868, x914, &x941); + uint32_t x944; uint8_t x945 = addcarryx_u32(x942, x871, x917, &x944); + uint32_t x947; uint8_t x948 = addcarryx_u32(x945, x874, x920, &x947); + uint32_t x950; uint8_t x951 = addcarryx_u32(x948, x877, x923, &x950); + uint32_t x953; uint8_t x954 = addcarryx_u32(x951, x879, x926, &x953); + uint32_t x957; uint32_t x956 = mulx_u32(x929, 0xffffffff, &x957); + uint32_t x960; uint32_t x959 = mulx_u32(x929, 0xffffffff, &x960); + uint32_t x963; uint32_t x962 = mulx_u32(x929, 0xffffffff, &x963); + uint32_t x966; uint32_t x965 = mulx_u32(x929, 0xffffffff, &x966); + uint32_t x968; uint8_t x969 = addcarryx_u32(0x0, x957, x959, &x968); + uint32_t x971; uint8_t x972 = addcarryx_u32(x969, x960, x962, &x971); + uint32_t x974; uint8_t x975 = addcarryx_u32(x972, x963, 0x0, &x974); + uint8_t x976 = (0x0 + 0x0); + uint32_t _8; uint8_t x979 = addcarryx_u32(0x0, x929, x956, &_8); + uint32_t x981; uint8_t x982 = addcarryx_u32(x979, x932, x968, &x981); + uint32_t x984; uint8_t x985 = addcarryx_u32(x982, x935, x971, &x984); + uint32_t x987; uint8_t x988 = addcarryx_u32(x985, x938, x974, &x987); + uint32_t x990; uint8_t x991 = addcarryx_u32(x988, x941, x975, &x990); + uint32_t x993; uint8_t x994 = addcarryx_u32(x991, x944, x976, &x993); + uint32_t x996; uint8_t x997 = addcarryx_u32(x994, x947, x929, &x996); + uint32_t x999; uint8_t x1000 = addcarryx_u32(x997, x950, x965, &x999); + uint32_t x1002; uint8_t x1003 = addcarryx_u32(x1000, x953, x966, &x1002); + uint8_t x1004 = (x1003 + x954); + uint32_t x1006; uint8_t x1007 = subborrow_u32(0x0, x981, 0xffffffff, &x1006); + uint32_t x1009; uint8_t x1010 = subborrow_u32(x1007, x984, 0xffffffff, &x1009); + uint32_t x1012; uint8_t x1013 = subborrow_u32(x1010, x987, 0xffffffff, &x1012); + uint32_t x1015; uint8_t x1016 = subborrow_u32(x1013, x990, 0x0, &x1015); + uint32_t x1018; uint8_t x1019 = subborrow_u32(x1016, x993, 0x0, &x1018); + uint32_t x1021; uint8_t x1022 = subborrow_u32(x1019, x996, 0x0, &x1021); + uint32_t x1024; uint8_t x1025 = subborrow_u32(x1022, x999, 0x1, &x1024); + uint32_t x1027; uint8_t x1028 = subborrow_u32(x1025, x1002, 0xffffffff, &x1027); + uint32_t _9; uint8_t x1031 = subborrow_u32(x1028, x1004, 0x0, &_9); + uint32_t x1032 = cmovznz_u32(x1031, x1027, x1002); + uint32_t x1033 = cmovznz_u32(x1031, x1024, x999); + uint32_t x1034 = cmovznz_u32(x1031, x1021, x996); + uint32_t x1035 = cmovznz_u32(x1031, x1018, x993); + uint32_t x1036 = cmovznz_u32(x1031, x1015, x990); + uint32_t x1037 = cmovznz_u32(x1031, x1012, x987); + uint32_t x1038 = cmovznz_u32(x1031, x1009, x984); + uint32_t x1039 = cmovznz_u32(x1031, x1006, x981); + out[0] = x1039; + out[1] = x1038; + out[2] = x1037; + out[3] = x1036; + out[4] = x1035; + out[5] = x1034; + out[6] = x1033; + out[7] = x1032; +} + +// NOTE: the following functions are generated from fiat-crypto, from the same +// template as their 64-bit counterparts above, but the correctness proof of +// the template was not composed with the correctness proof of the +// specialization pipeline. This is because Coq unexplainedly loops on trying +// to synthesize opp and sub using the normal pipeline. + +static void fe_sub(uint32_t out[8], const uint32_t in1[8], const uint32_t in2[8]) { + const uint32_t x14 = in1[7]; + const uint32_t x15 = in1[6]; + const uint32_t x13 = in1[5]; + const uint32_t x11 = in1[4]; + const uint32_t x9 = in1[3]; + const uint32_t x7 = in1[2]; + const uint32_t x5 = in1[1]; + const uint32_t x3 = in1[0]; + const uint32_t x28 = in2[7]; + const uint32_t x29 = in2[6]; + const uint32_t x27 = in2[5]; + const uint32_t x25 = in2[4]; + const uint32_t x23 = in2[3]; + const uint32_t x21 = in2[2]; + const uint32_t x19 = in2[1]; + const uint32_t x17 = in2[0]; + uint32_t x31; uint8_t x32 = subborrow_u32(0x0, x3, x17, &x31); + uint32_t x34; uint8_t x35 = subborrow_u32(x32, x5, x19, &x34); + uint32_t x37; uint8_t x38 = subborrow_u32(x35, x7, x21, &x37); + uint32_t x40; uint8_t x41 = subborrow_u32(x38, x9, x23, &x40); + uint32_t x43; uint8_t x44 = subborrow_u32(x41, x11, x25, &x43); + uint32_t x46; uint8_t x47 = subborrow_u32(x44, x13, x27, &x46); + uint32_t x49; uint8_t x50 = subborrow_u32(x47, x15, x29, &x49); + uint32_t x52; uint8_t x53 = subborrow_u32(x50, x14, x28, &x52); + uint32_t x54 = cmovznz_u32(x53, 0x0, 0xffffffff); + uint32_t x56; uint8_t x57 = addcarryx_u32(0x0, x31, (x54 & 0xffffffff), &x56); + uint32_t x59; uint8_t x60 = addcarryx_u32(x57, x34, (x54 & 0xffffffff), &x59); + uint32_t x62; uint8_t x63 = addcarryx_u32(x60, x37, (x54 & 0xffffffff), &x62); + uint32_t x65; uint8_t x66 = addcarryx_u32(x63, x40, 0x0, &x65); + uint32_t x68; uint8_t x69 = addcarryx_u32(x66, x43, 0x0, &x68); + uint32_t x71; uint8_t x72 = addcarryx_u32(x69, x46, 0x0, &x71); + uint32_t x74; uint8_t x75 = addcarryx_u32(x72, x49, ((uint8_t)x54 & 0x1), &x74); + uint32_t x77; addcarryx_u32(x75, x52, (x54 & 0xffffffff), &x77); + out[0] = x56; + out[1] = x59; + out[2] = x62; + out[3] = x65; + out[4] = x68; + out[5] = x71; + out[6] = x74; + out[7] = x77; +} + +// fe_op sets out = -in +static void fe_opp(uint32_t out[8], const uint32_t in1[8]) { + const uint32_t x12 = in1[7]; + const uint32_t x13 = in1[6]; + const uint32_t x11 = in1[5]; + const uint32_t x9 = in1[4]; + const uint32_t x7 = in1[3]; + const uint32_t x5 = in1[2]; + const uint32_t x3 = in1[1]; + const uint32_t x1 = in1[0]; + uint32_t x15; uint8_t x16 = subborrow_u32(0x0, 0x0, x1, &x15); + uint32_t x18; uint8_t x19 = subborrow_u32(x16, 0x0, x3, &x18); + uint32_t x21; uint8_t x22 = subborrow_u32(x19, 0x0, x5, &x21); + uint32_t x24; uint8_t x25 = subborrow_u32(x22, 0x0, x7, &x24); + uint32_t x27; uint8_t x28 = subborrow_u32(x25, 0x0, x9, &x27); + uint32_t x30; uint8_t x31 = subborrow_u32(x28, 0x0, x11, &x30); + uint32_t x33; uint8_t x34 = subborrow_u32(x31, 0x0, x13, &x33); + uint32_t x36; uint8_t x37 = subborrow_u32(x34, 0x0, x12, &x36); + uint32_t x38 = cmovznz_u32(x37, 0x0, 0xffffffff); + uint32_t x40; uint8_t x41 = addcarryx_u32(0x0, x15, (x38 & 0xffffffff), &x40); + uint32_t x43; uint8_t x44 = addcarryx_u32(x41, x18, (x38 & 0xffffffff), &x43); + uint32_t x46; uint8_t x47 = addcarryx_u32(x44, x21, (x38 & 0xffffffff), &x46); + uint32_t x49; uint8_t x50 = addcarryx_u32(x47, x24, 0x0, &x49); + uint32_t x52; uint8_t x53 = addcarryx_u32(x50, x27, 0x0, &x52); + uint32_t x55; uint8_t x56 = addcarryx_u32(x53, x30, 0x0, &x55); + uint32_t x58; uint8_t x59 = addcarryx_u32(x56, x33, ((uint8_t)x38 & 0x1), &x58); + uint32_t x61; addcarryx_u32(x59, x36, (x38 & 0xffffffff), &x61); + out[0] = x40; + out[1] = x43; + out[2] = x46; + out[3] = x49; + out[4] = x52; + out[5] = x55; + out[6] = x58; + out[7] = x61; +} + +#endif + +// utility functions, handwritten + +#define NBYTES 32 + +#if defined(BORINGSSL_NISTP256_64BIT) + +#define NLIMBS 4 +typedef uint64_t limb_t; +#define cmovznz_limb cmovznz_u64 +typedef uint64_t fe[NLIMBS]; +#else // 64BIT; else 32BIT + +#define NLIMBS 8 +typedef uint32_t limb_t; +#define cmovznz_limb cmovznz_u32 +typedef uint32_t fe[NLIMBS]; + +#endif // 64BIT + +static limb_t fe_nz(const limb_t in1[NLIMBS]) { + limb_t ret = 0; + for (int i = 0; i < NLIMBS; i++) { + ret |= in1[i]; + } + return ret; +} + +static void fe_copy(limb_t out[NLIMBS], const limb_t in1[NLIMBS]) { + for (int i = 0; i < NLIMBS; i++) { + out[i] = in1[i]; + } +} + +static void fe_cmovznz(limb_t out[NLIMBS], limb_t t, const limb_t z[NLIMBS], + const limb_t nz[NLIMBS]) { + for (int i = 0; i < NLIMBS; i++) { + out[i] = cmovznz_limb(t, z[i], nz[i]); + } +} + +static void fe_sqr(fe out, const fe in) { + fe_mul(out, in, in); +} + +static void fe_tobytes(uint8_t out[NBYTES], const fe in) { + for (int i = 0; i> (8*(i%sizeof(in[0])))); + } +} + +static void fe_frombytes(fe out, const uint8_t in[NBYTES]) { + for (int i = 0; i +// As a sanity check, a proof that these points form a commutative group: +// + +// 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 +// +// Coq transcription and correctness proof: +// +// +// +// 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(fe x_out, fe y_out, fe z_out, + const fe x_in, const fe y_in, const fe z_in) { + fe delta, gamma, beta, ftmp, ftmp2, tmptmp, alpha, fourbeta; + // delta = z^2 + fe_sqr(delta, z_in); + // gamma = y^2 + fe_sqr(gamma, y_in); + // beta = x*gamma + fe_mul(beta, x_in, gamma); + + // alpha = 3*(x-delta)*(x+delta) + fe_sub(ftmp, x_in, delta); + fe_add(ftmp2, x_in, delta); + + fe_add(tmptmp, ftmp2, ftmp2); + fe_add(ftmp2, ftmp2, tmptmp); + fe_mul(alpha, ftmp, ftmp2); + + // x' = alpha^2 - 8*beta + fe_sqr(x_out, alpha); + fe_add(fourbeta, beta, beta); + fe_add(fourbeta, fourbeta, fourbeta); + fe_add(tmptmp, fourbeta, fourbeta); + fe_sub(x_out, x_out, tmptmp); + + // z' = (y + z)^2 - gamma - delta + fe_add(delta, gamma, delta); + fe_add(ftmp, y_in, z_in); + fe_sqr(z_out, ftmp); + fe_sub(z_out, z_out, delta); + + // y' = alpha*(4*beta - x') - 8*gamma^2 + fe_sub(y_out, fourbeta, x_out); + fe_add(gamma, gamma, gamma); + fe_sqr(gamma, gamma); + fe_mul(y_out, alpha, y_out); + fe_add(gamma, gamma, gamma); + fe_sub(y_out, y_out, gamma); +} + +// 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). +// +// Coq transcription and correctness proof: +// +// +// +// 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(fe x3, fe y3, fe z3, const fe x1, + const fe y1, const fe z1, const int mixed, + const fe x2, const fe y2, const fe z2) { + fe x_out, y_out, z_out; + limb_t z1nz = fe_nz(z1); + limb_t z2nz = fe_nz(z2); + + // z1z1 = z1z1 = z1**2 + fe z1z1; fe_sqr(z1z1, z1); + + fe u1, s1, two_z1z2; + if (!mixed) { + // z2z2 = z2**2 + fe z2z2; fe_sqr(z2z2, z2); + + // u1 = x1*z2z2 + fe_mul(u1, x1, z2z2); + + // two_z1z2 = (z1 + z2)**2 - (z1z1 + z2z2) = 2z1z2 + fe_add(two_z1z2, z1, z2); + fe_sqr(two_z1z2, two_z1z2); + fe_sub(two_z1z2, two_z1z2, z1z1); + fe_sub(two_z1z2, two_z1z2, z2z2); + + // s1 = y1 * z2**3 + fe_mul(s1, z2, z2z2); + fe_mul(s1, s1, y1); + } else { + // We'll assume z2 = 1 (special case z2 = 0 is handled later). + + // u1 = x1*z2z2 + fe_copy(u1, x1); + // two_z1z2 = 2z1z2 + fe_add(two_z1z2, z1, z1); + // s1 = y1 * z2**3 + fe_copy(s1, y1); + } + + // u2 = x2*z1z1 + fe u2; fe_mul(u2, x2, z1z1); + + // h = u2 - u1 + fe h; fe_sub(h, u2, u1); + + limb_t xneq = fe_nz(h); + + // z_out = two_z1z2 * h + fe_mul(z_out, h, two_z1z2); + + // z1z1z1 = z1 * z1z1 + fe z1z1z1; fe_mul(z1z1z1, z1, z1z1); + + // s2 = y2 * z1**3 + fe s2; fe_mul(s2, y2, z1z1z1); + + // r = (s2 - s1)*2 + fe r; + fe_sub(r, s2, s1); + fe_add(r, r, r); + + limb_t yneq = fe_nz(r); + + if (!xneq && !yneq && z1nz && z2nz) { + point_double(x3, y3, z3, x1, y1, z1); + return; + } + + // I = (2h)**2 + fe i; + fe_add(i, h, h); + fe_sqr(i, i); + + // J = h * I + fe j; fe_mul(j, h, i); + + // V = U1 * I + fe v; fe_mul(v, u1, i); + + // x_out = r**2 - J - 2V + fe_sqr(x_out, r); + fe_sub(x_out, x_out, j); + fe_sub(x_out, x_out, v); + fe_sub(x_out, x_out, v); + + // y_out = r(V-x_out) - 2 * s1 * J + fe_sub(y_out, v, x_out); + fe_mul(y_out, y_out, r); + fe s1j; + fe_mul(s1j, s1, j); + fe_sub(y_out, y_out, s1j); + fe_sub(y_out, y_out, s1j); + + fe_cmovznz(x_out, z1nz, x2, x_out); + fe_cmovznz(x3, z2nz, x1, x_out); + fe_cmovznz(y_out, z1nz, y2, y_out); + fe_cmovznz(y3, z2nz, y1, y_out); + fe_cmovznz(z_out, z1nz, z2, z_out); + fe_cmovznz(z3, z2nz, z1, 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 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. + +// g_pre_comp is the table of precomputed base points +#if defined(BORINGSSL_NISTP256_64BIT) +static const fe g_pre_comp[2][16][3] = { + {{{0x0, 0x0, 0x0, 0x0}, {0x0, 0x0, 0x0, 0x0}, {0x0, 0x0, 0x0, 0x0}}, + {{0x79e730d418a9143c, 0x75ba95fc5fedb601, 0x79fb732b77622510, + 0x18905f76a53755c6}, + {0xddf25357ce95560a, 0x8b4ab8e4ba19e45c, 0xd2e88688dd21f325, + 0x8571ff1825885d85}, + {0x1, 0xffffffff00000000, 0xffffffffffffffff, 0xfffffffe}}, + {{0x4f922fc516a0d2bb, 0xd5cc16c1a623499, 0x9241cf3a57c62c8b, + 0x2f5e6961fd1b667f}, + {0x5c15c70bf5a01797, 0x3d20b44d60956192, 0x4911b37071fdb52, + 0xf648f9168d6f0f7b}, + {0x1, 0xffffffff00000000, 0xffffffffffffffff, 0xfffffffe}}, + {{0x9e566847e137bbbc, 0xe434469e8a6a0bec, 0xb1c4276179d73463, + 0x5abe0285133d0015}, + {0x92aa837cc04c7dab, 0x573d9f4c43260c07, 0xc93156278e6cc37, + 0x94bb725b6b6f7383}, + {0x1, 0xffffffff00000000, 0xffffffffffffffff, 0xfffffffe}}, + {{0x62a8c244bfe20925, 0x91c19ac38fdce867, 0x5a96a5d5dd387063, + 0x61d587d421d324f6}, + {0xe87673a2a37173ea, 0x2384800853778b65, 0x10f8441e05bab43e, + 0xfa11fe124621efbe}, + {0x1, 0xffffffff00000000, 0xffffffffffffffff, 0xfffffffe}}, + {{0x1c891f2b2cb19ffd, 0x1ba8d5bb1923c23, 0xb6d03d678ac5ca8e, + 0x586eb04c1f13bedc}, + {0xc35c6e527e8ed09, 0x1e81a33c1819ede2, 0x278fd6c056c652fa, + 0x19d5ac0870864f11}, + {0x1, 0xffffffff00000000, 0xffffffffffffffff, 0xfffffffe}}, + {{0x62577734d2b533d5, 0x673b8af6a1bdddc0, 0x577e7c9aa79ec293, + 0xbb6de651c3b266b1}, + {0xe7e9303ab65259b3, 0xd6a0afd3d03a7480, 0xc5ac83d19b3cfc27, + 0x60b4619a5d18b99b}, + {0x1, 0xffffffff00000000, 0xffffffffffffffff, 0xfffffffe}}, + {{0xbd6a38e11ae5aa1c, 0xb8b7652b49e73658, 0xb130014ee5f87ed, + 0x9d0f27b2aeebffcd}, + {0xca9246317a730a55, 0x9c955b2fddbbc83a, 0x7c1dfe0ac019a71, + 0x244a566d356ec48d}, + {0x1, 0xffffffff00000000, 0xffffffffffffffff, 0xfffffffe}}, + {{0x56f8410ef4f8b16a, 0x97241afec47b266a, 0xa406b8e6d9c87c1, + 0x803f3e02cd42ab1b}, + {0x7f0309a804dbec69, 0xa83b85f73bbad05f, 0xc6097273ad8e197f, + 0xc097440e5067adc1}, + {0x1, 0xffffffff00000000, 0xffffffffffffffff, 0xfffffffe}}, + {{0x846a56f2c379ab34, 0xa8ee068b841df8d1, 0x20314459176c68ef, + 0xf1af32d5915f1f30}, + {0x99c375315d75bd50, 0x837cffbaf72f67bc, 0x613a41848d7723f, + 0x23d0f130e2d41c8b}, + {0x1, 0xffffffff00000000, 0xffffffffffffffff, 0xfffffffe}}, + {{0xed93e225d5be5a2b, 0x6fe799835934f3c6, 0x4314092622626ffc, + 0x50bbb4d97990216a}, + {0x378191c6e57ec63e, 0x65422c40181dcdb2, 0x41a8099b0236e0f6, + 0x2b10011801fe49c3}, + {0x1, 0xffffffff00000000, 0xffffffffffffffff, 0xfffffffe}}, + {{0xfc68b5c59b391593, 0xc385f5a2598270fc, 0x7144f3aad19adcbb, + 0xdd55899983fbae0c}, + {0x93b88b8e74b82ff4, 0xd2e03c4071e734c9, 0x9a7a9eaf43c0322a, + 0xe6e4c551149d6041}, + {0x1, 0xffffffff00000000, 0xffffffffffffffff, 0xfffffffe}}, + {{0x5fe14bfe80ec21fe, 0xf6ce116ac255be82, 0x98bc5a072f4a5d67, + 0xfad27148db7e63af}, + {0x90c0b6ac29ab05b3, 0x37a9a83c4e251ae6, 0xa7dc875c2aade7d, + 0x77387de39f0e1a84}, + {0x1, 0xffffffff00000000, 0xffffffffffffffff, 0xfffffffe}}, + {{0x1e9ecc49a56c0dd7, 0xa5cffcd846086c74, 0x8f7a1408f505aece, + 0xb37b85c0bef0c47e}, + {0x3596b6e4cc0e6a8f, 0xfd6d4bbf6b388f23, 0xaba453fac39cef4e, + 0x9c135ac8f9f628d5}, + {0x1, 0xffffffff00000000, 0xffffffffffffffff, 0xfffffffe}}, + {{0xa1c729495c8f8be, 0x2961c4803bf362bf, 0x9e418403df63d4ac, + 0xc109f9cb91ece900}, + {0xc2d095d058945705, 0xb9083d96ddeb85c0, 0x84692b8d7a40449b, + 0x9bc3344f2eee1ee1}, + {0x1, 0xffffffff00000000, 0xffffffffffffffff, 0xfffffffe}}, + {{0xd5ae35642913074, 0x55491b2748a542b1, 0x469ca665b310732a, + 0x29591d525f1a4cc1}, + {0xe76f5b6bb84f983f, 0xbe7eef419f5f84e1, 0x1200d49680baa189, + 0x6376551f18ef332c}, + {0x1, 0xffffffff00000000, 0xffffffffffffffff, 0xfffffffe}}}, + {{{0x0, 0x0, 0x0, 0x0}, {0x0, 0x0, 0x0, 0x0}, {0x0, 0x0, 0x0, 0x0}}, + {{0x202886024147519a, 0xd0981eac26b372f0, 0xa9d4a7caa785ebc8, + 0xd953c50ddbdf58e9}, + {0x9d6361ccfd590f8f, 0x72e9626b44e6c917, 0x7fd9611022eb64cf, + 0x863ebb7e9eb288f3}, + {0x1, 0xffffffff00000000, 0xffffffffffffffff, 0xfffffffe}}, + {{0x4fe7ee31b0e63d34, 0xf4600572a9e54fab, 0xc0493334d5e7b5a4, + 0x8589fb9206d54831}, + {0xaa70f5cc6583553a, 0x879094ae25649e5, 0xcc90450710044652, + 0xebb0696d02541c4f}, + {0x1, 0xffffffff00000000, 0xffffffffffffffff, 0xfffffffe}}, + {{0xabbaa0c03b89da99, 0xa6f2d79eb8284022, 0x27847862b81c05e8, + 0x337a4b5905e54d63}, + {0x3c67500d21f7794a, 0x207005b77d6d7f61, 0xa5a378104cfd6e8, + 0xd65e0d5f4c2fbd6}, + {0x1, 0xffffffff00000000, 0xffffffffffffffff, 0xfffffffe}}, + {{0xd433e50f6d3549cf, 0x6f33696ffacd665e, 0x695bfdacce11fcb4, + 0x810ee252af7c9860}, + {0x65450fe17159bb2c, 0xf7dfbebe758b357b, 0x2b057e74d69fea72, + 0xd485717a92731745}, + {0x1, 0xffffffff00000000, 0xffffffffffffffff, 0xfffffffe}}, + {{0xce1f69bbe83f7669, 0x9f8ae8272877d6b, 0x9548ae543244278d, + 0x207755dee3c2c19c}, + {0x87bd61d96fef1945, 0x18813cefb12d28c3, 0x9fbcd1d672df64aa, + 0x48dc5ee57154b00d}, + {0x1, 0xffffffff00000000, 0xffffffffffffffff, 0xfffffffe}}, + {{0xef0f469ef49a3154, 0x3e85a5956e2b2e9a, 0x45aaec1eaa924a9c, + 0xaa12dfc8a09e4719}, + {0x26f272274df69f1d, 0xe0e4c82ca2ff5e73, 0xb9d8ce73b7a9dd44, + 0x6c036e73e48ca901}, + {0x1, 0xffffffff00000000, 0xffffffffffffffff, 0xfffffffe}}, + {{0xe1e421e1a47153f0, 0xb86c3b79920418c9, 0x93bdce87705d7672, + 0xf25ae793cab79a77}, + {0x1f3194a36d869d0c, 0x9d55c8824986c264, 0x49fb5ea3096e945e, + 0x39b8e65313db0a3e}, + {0x1, 0xffffffff00000000, 0xffffffffffffffff, 0xfffffffe}}, + {{0xe3417bc035d0b34a, 0x440b386b8327c0a7, 0x8fb7262dac0362d1, + 0x2c41114ce0cdf943}, + {0x2ba5cef1ad95a0b1, 0xc09b37a867d54362, 0x26d6cdd201e486c9, + 0x20477abf42ff9297}, + {0x1, 0xffffffff00000000, 0xffffffffffffffff, 0xfffffffe}}, + {{0xf121b41bc0a67d2, 0x62d4760a444d248a, 0xe044f1d659b4737, + 0x8fde365250bb4a8}, + {0xaceec3da848bf287, 0xc2a62182d3369d6e, 0x3582dfdc92449482, + 0x2f7e2fd2565d6cd7}, + {0x1, 0xffffffff00000000, 0xffffffffffffffff, 0xfffffffe}}, + {{0xa0122b5178a876b, 0x51ff96ff085104b4, 0x50b31ab14f29f76, + 0x84abb28b5f87d4e6}, + {0xd5ed439f8270790a, 0x2d6cb59d85e3f46b, 0x75f55c1b6c1e2212, + 0xe5436f6717655640}, + {0x1, 0xffffffff00000000, 0xffffffffffffffff, 0xfffffffe}}, + {{0xc2965ecc9aeb596d, 0x1ea03e7023c92b4, 0x4704b4b62e013961, + 0xca8fd3f905ea367}, + {0x92523a42551b2b61, 0x1eb7a89c390fcd06, 0xe7f1d2be0392a63e, + 0x96dca2644ddb0c33}, + {0x1, 0xffffffff00000000, 0xffffffffffffffff, 0xfffffffe}}, + {{0x231c210e15339848, 0xe87a28e870778c8d, 0x9d1de6616956e170, + 0x4ac3c9382bb09c0b}, + {0x19be05516998987d, 0x8b2376c4ae09f4d6, 0x1de0b7651a3f933d, + 0x380d94c7e39705f4}, + {0x1, 0xffffffff00000000, 0xffffffffffffffff, 0xfffffffe}}, + {{0x3685954b8c31c31d, 0x68533d005bf21a0c, 0xbd7626e75c79ec9, + 0xca17754742c69d54}, + {0xcc6edafff6d2dbb2, 0xfd0d8cbd174a9d18, 0x875e8793aa4578e8, + 0xa976a7139cab2ce6}, + {0x1, 0xffffffff00000000, 0xffffffffffffffff, 0xfffffffe}}, + {{0xce37ab11b43ea1db, 0xa7ff1a95259d292, 0x851b02218f84f186, + 0xa7222beadefaad13}, + {0xa2ac78ec2b0a9144, 0x5a024051f2fa59c5, 0x91d1eca56147ce38, + 0xbe94d523bc2ac690}, + {0x1, 0xffffffff00000000, 0xffffffffffffffff, 0xfffffffe}}, + {{0x2d8daefd79ec1a0f, 0x3bbcd6fdceb39c97, 0xf5575ffc58f61a95, + 0xdbd986c4adf7b420}, + {0x81aa881415f39eb7, 0x6ee2fcf5b98d976c, 0x5465475dcf2f717d, + 0x8e24d3c46860bbd0}, + {0x1, 0xffffffff00000000, 0xffffffffffffffff, 0xfffffffe}}}}; +#else +static const fe g_pre_comp[2][16][3] = { + {{{0x0,0x0, 0x0,0x0, 0x0,0x0, 0x0,0x0}, + {0x0,0x0, 0x0,0x0, 0x0,0x0, 0x0,0x0}, + {0x0,0x0, 0x0,0x0, 0x0,0x0, 0x0,0x0}}, + {{0x18a9143c,0x79e730d4, 0x5fedb601,0x75ba95fc, 0x77622510,0x79fb732b, + 0xa53755c6,0x18905f76}, + {0xce95560a,0xddf25357, 0xba19e45c,0x8b4ab8e4, 0xdd21f325,0xd2e88688, + 0x25885d85,0x8571ff18}, + {0x1,0x0, 0x0,0xffffffff, 0xffffffff,0xffffffff, 0xfffffffe,0x0}}, + {{0x16a0d2bb,0x4f922fc5, 0x1a623499,0xd5cc16c, 0x57c62c8b,0x9241cf3a, + 0xfd1b667f,0x2f5e6961}, + {0xf5a01797,0x5c15c70b, 0x60956192,0x3d20b44d, 0x71fdb52,0x4911b37, + 0x8d6f0f7b,0xf648f916}, + {0x1,0x0, 0x0,0xffffffff, 0xffffffff,0xffffffff, 0xfffffffe,0x0}}, + {{0xe137bbbc,0x9e566847, 0x8a6a0bec,0xe434469e, 0x79d73463,0xb1c42761, + 0x133d0015,0x5abe0285}, + {0xc04c7dab,0x92aa837c, 0x43260c07,0x573d9f4c, 0x78e6cc37,0xc931562, + 0x6b6f7383,0x94bb725b}, + {0x1,0x0, 0x0,0xffffffff, 0xffffffff,0xffffffff, 0xfffffffe,0x0}}, + {{0xbfe20925,0x62a8c244, 0x8fdce867,0x91c19ac3, 0xdd387063,0x5a96a5d5, + 0x21d324f6,0x61d587d4}, + {0xa37173ea,0xe87673a2, 0x53778b65,0x23848008, 0x5bab43e,0x10f8441e, + 0x4621efbe,0xfa11fe12}, + {0x1,0x0, 0x0,0xffffffff, 0xffffffff,0xffffffff, 0xfffffffe,0x0}}, + {{0x2cb19ffd,0x1c891f2b, 0xb1923c23,0x1ba8d5b, 0x8ac5ca8e,0xb6d03d67, + 0x1f13bedc,0x586eb04c}, + {0x27e8ed09,0xc35c6e5, 0x1819ede2,0x1e81a33c, 0x56c652fa,0x278fd6c0, + 0x70864f11,0x19d5ac08}, + {0x1,0x0, 0x0,0xffffffff, 0xffffffff,0xffffffff, 0xfffffffe,0x0}}, + {{0xd2b533d5,0x62577734, 0xa1bdddc0,0x673b8af6, 0xa79ec293,0x577e7c9a, + 0xc3b266b1,0xbb6de651}, + {0xb65259b3,0xe7e9303a, 0xd03a7480,0xd6a0afd3, 0x9b3cfc27,0xc5ac83d1, + 0x5d18b99b,0x60b4619a}, + {0x1,0x0, 0x0,0xffffffff, 0xffffffff,0xffffffff, 0xfffffffe,0x0}}, + {{0x1ae5aa1c,0xbd6a38e1, 0x49e73658,0xb8b7652b, 0xee5f87ed,0xb130014, + 0xaeebffcd,0x9d0f27b2}, + {0x7a730a55,0xca924631, 0xddbbc83a,0x9c955b2f, 0xac019a71,0x7c1dfe0, + 0x356ec48d,0x244a566d}, + {0x1,0x0, 0x0,0xffffffff, 0xffffffff,0xffffffff, 0xfffffffe,0x0}}, + {{0xf4f8b16a,0x56f8410e, 0xc47b266a,0x97241afe, 0x6d9c87c1,0xa406b8e, + 0xcd42ab1b,0x803f3e02}, + {0x4dbec69,0x7f0309a8, 0x3bbad05f,0xa83b85f7, 0xad8e197f,0xc6097273, + 0x5067adc1,0xc097440e}, + {0x1,0x0, 0x0,0xffffffff, 0xffffffff,0xffffffff, 0xfffffffe,0x0}}, + {{0xc379ab34,0x846a56f2, 0x841df8d1,0xa8ee068b, 0x176c68ef,0x20314459, + 0x915f1f30,0xf1af32d5}, + {0x5d75bd50,0x99c37531, 0xf72f67bc,0x837cffba, 0x48d7723f,0x613a418, + 0xe2d41c8b,0x23d0f130}, + {0x1,0x0, 0x0,0xffffffff, 0xffffffff,0xffffffff, 0xfffffffe,0x0}}, + {{0xd5be5a2b,0xed93e225, 0x5934f3c6,0x6fe79983, 0x22626ffc,0x43140926, + 0x7990216a,0x50bbb4d9}, + {0xe57ec63e,0x378191c6, 0x181dcdb2,0x65422c40, 0x236e0f6,0x41a8099b, + 0x1fe49c3,0x2b100118}, + {0x1,0x0, 0x0,0xffffffff, 0xffffffff,0xffffffff, 0xfffffffe,0x0}}, + {{0x9b391593,0xfc68b5c5, 0x598270fc,0xc385f5a2, 0xd19adcbb,0x7144f3aa, + 0x83fbae0c,0xdd558999}, + {0x74b82ff4,0x93b88b8e, 0x71e734c9,0xd2e03c40, 0x43c0322a,0x9a7a9eaf, + 0x149d6041,0xe6e4c551}, + {0x1,0x0, 0x0,0xffffffff, 0xffffffff,0xffffffff, 0xfffffffe,0x0}}, + {{0x80ec21fe,0x5fe14bfe, 0xc255be82,0xf6ce116a, 0x2f4a5d67,0x98bc5a07, + 0xdb7e63af,0xfad27148}, + {0x29ab05b3,0x90c0b6ac, 0x4e251ae6,0x37a9a83c, 0xc2aade7d,0xa7dc875, + 0x9f0e1a84,0x77387de3}, + {0x1,0x0, 0x0,0xffffffff, 0xffffffff,0xffffffff, 0xfffffffe,0x0}}, + {{0xa56c0dd7,0x1e9ecc49, 0x46086c74,0xa5cffcd8, 0xf505aece,0x8f7a1408, + 0xbef0c47e,0xb37b85c0}, + {0xcc0e6a8f,0x3596b6e4, 0x6b388f23,0xfd6d4bbf, 0xc39cef4e,0xaba453fa, + 0xf9f628d5,0x9c135ac8}, + {0x1,0x0, 0x0,0xffffffff, 0xffffffff,0xffffffff, 0xfffffffe,0x0}}, + {{0x95c8f8be,0xa1c7294, 0x3bf362bf,0x2961c480, 0xdf63d4ac,0x9e418403, + 0x91ece900,0xc109f9cb}, + {0x58945705,0xc2d095d0, 0xddeb85c0,0xb9083d96, 0x7a40449b,0x84692b8d, + 0x2eee1ee1,0x9bc3344f}, + {0x1,0x0, 0x0,0xffffffff, 0xffffffff,0xffffffff, 0xfffffffe,0x0}}, + {{0x42913074,0xd5ae356, 0x48a542b1,0x55491b27, 0xb310732a,0x469ca665, + 0x5f1a4cc1,0x29591d52}, + {0xb84f983f,0xe76f5b6b, 0x9f5f84e1,0xbe7eef41, 0x80baa189,0x1200d496, + 0x18ef332c,0x6376551f}, + {0x1,0x0, 0x0,0xffffffff, 0xffffffff,0xffffffff, 0xfffffffe,0x0}}}, + {{{0x0,0x0, 0x0,0x0, 0x0,0x0, 0x0,0x0}, + {0x0,0x0, 0x0,0x0, 0x0,0x0, 0x0,0x0}, + {0x0,0x0, 0x0,0x0, 0x0,0x0, 0x0,0x0}}, + {{0x4147519a,0x20288602, 0x26b372f0,0xd0981eac, 0xa785ebc8,0xa9d4a7ca, + 0xdbdf58e9,0xd953c50d}, + {0xfd590f8f,0x9d6361cc, 0x44e6c917,0x72e9626b, 0x22eb64cf,0x7fd96110, + 0x9eb288f3,0x863ebb7e}, + {0x1,0x0, 0x0,0xffffffff, 0xffffffff,0xffffffff, 0xfffffffe,0x0}}, + {{0xb0e63d34,0x4fe7ee31, 0xa9e54fab,0xf4600572, 0xd5e7b5a4,0xc0493334, + 0x6d54831,0x8589fb92}, + {0x6583553a,0xaa70f5cc, 0xe25649e5,0x879094a, 0x10044652,0xcc904507, + 0x2541c4f,0xebb0696d}, + {0x1,0x0, 0x0,0xffffffff, 0xffffffff,0xffffffff, 0xfffffffe,0x0}}, + {{0x3b89da99,0xabbaa0c0, 0xb8284022,0xa6f2d79e, 0xb81c05e8,0x27847862, + 0x5e54d63,0x337a4b59}, + {0x21f7794a,0x3c67500d, 0x7d6d7f61,0x207005b7, 0x4cfd6e8,0xa5a3781, + 0xf4c2fbd6,0xd65e0d5}, + {0x1,0x0, 0x0,0xffffffff, 0xffffffff,0xffffffff, 0xfffffffe,0x0}}, + {{0x6d3549cf,0xd433e50f, 0xfacd665e,0x6f33696f, 0xce11fcb4,0x695bfdac, + 0xaf7c9860,0x810ee252}, + {0x7159bb2c,0x65450fe1, 0x758b357b,0xf7dfbebe, 0xd69fea72,0x2b057e74, + 0x92731745,0xd485717a}, + {0x1,0x0, 0x0,0xffffffff, 0xffffffff,0xffffffff, 0xfffffffe,0x0}}, + {{0xe83f7669,0xce1f69bb, 0x72877d6b,0x9f8ae82, 0x3244278d,0x9548ae54, + 0xe3c2c19c,0x207755de}, + {0x6fef1945,0x87bd61d9, 0xb12d28c3,0x18813cef, 0x72df64aa,0x9fbcd1d6, + 0x7154b00d,0x48dc5ee5}, + {0x1,0x0, 0x0,0xffffffff, 0xffffffff,0xffffffff, 0xfffffffe,0x0}}, + {{0xf49a3154,0xef0f469e, 0x6e2b2e9a,0x3e85a595, 0xaa924a9c,0x45aaec1e, + 0xa09e4719,0xaa12dfc8}, + {0x4df69f1d,0x26f27227, 0xa2ff5e73,0xe0e4c82c, 0xb7a9dd44,0xb9d8ce73, + 0xe48ca901,0x6c036e73}, + {0x1,0x0, 0x0,0xffffffff, 0xffffffff,0xffffffff, 0xfffffffe,0x0}}, + {{0xa47153f0,0xe1e421e1, 0x920418c9,0xb86c3b79, 0x705d7672,0x93bdce87, + 0xcab79a77,0xf25ae793}, + {0x6d869d0c,0x1f3194a3, 0x4986c264,0x9d55c882, 0x96e945e,0x49fb5ea3, + 0x13db0a3e,0x39b8e653}, + {0x1,0x0, 0x0,0xffffffff, 0xffffffff,0xffffffff, 0xfffffffe,0x0}}, + {{0x35d0b34a,0xe3417bc0, 0x8327c0a7,0x440b386b, 0xac0362d1,0x8fb7262d, + 0xe0cdf943,0x2c41114c}, + {0xad95a0b1,0x2ba5cef1, 0x67d54362,0xc09b37a8, 0x1e486c9,0x26d6cdd2, + 0x42ff9297,0x20477abf}, + {0x1,0x0, 0x0,0xffffffff, 0xffffffff,0xffffffff, 0xfffffffe,0x0}}, + {{0xbc0a67d2,0xf121b41, 0x444d248a,0x62d4760a, 0x659b4737,0xe044f1d, + 0x250bb4a8,0x8fde365}, + {0x848bf287,0xaceec3da, 0xd3369d6e,0xc2a62182, 0x92449482,0x3582dfdc, + 0x565d6cd7,0x2f7e2fd2}, + {0x1,0x0, 0x0,0xffffffff, 0xffffffff,0xffffffff, 0xfffffffe,0x0}}, + {{0x178a876b,0xa0122b5, 0x85104b4,0x51ff96ff, 0x14f29f76,0x50b31ab, + 0x5f87d4e6,0x84abb28b}, + {0x8270790a,0xd5ed439f, 0x85e3f46b,0x2d6cb59d, 0x6c1e2212,0x75f55c1b, + 0x17655640,0xe5436f67}, + {0x1,0x0, 0x0,0xffffffff, 0xffffffff,0xffffffff, 0xfffffffe,0x0}}, + {{0x9aeb596d,0xc2965ecc, 0x23c92b4,0x1ea03e7, 0x2e013961,0x4704b4b6, + 0x905ea367,0xca8fd3f}, + {0x551b2b61,0x92523a42, 0x390fcd06,0x1eb7a89c, 0x392a63e,0xe7f1d2be, + 0x4ddb0c33,0x96dca264}, + {0x1,0x0, 0x0,0xffffffff, 0xffffffff,0xffffffff, 0xfffffffe,0x0}}, + {{0x15339848,0x231c210e, 0x70778c8d,0xe87a28e8, 0x6956e170,0x9d1de661, + 0x2bb09c0b,0x4ac3c938}, + {0x6998987d,0x19be0551, 0xae09f4d6,0x8b2376c4, 0x1a3f933d,0x1de0b765, + 0xe39705f4,0x380d94c7}, + {0x1,0x0, 0x0,0xffffffff, 0xffffffff,0xffffffff, 0xfffffffe,0x0}}, + {{0x8c31c31d,0x3685954b, 0x5bf21a0c,0x68533d00, 0x75c79ec9,0xbd7626e, + 0x42c69d54,0xca177547}, + {0xf6d2dbb2,0xcc6edaff, 0x174a9d18,0xfd0d8cbd, 0xaa4578e8,0x875e8793, + 0x9cab2ce6,0xa976a713}, + {0x1,0x0, 0x0,0xffffffff, 0xffffffff,0xffffffff, 0xfffffffe,0x0}}, + {{0xb43ea1db,0xce37ab11, 0x5259d292,0xa7ff1a9, 0x8f84f186,0x851b0221, + 0xdefaad13,0xa7222bea}, + {0x2b0a9144,0xa2ac78ec, 0xf2fa59c5,0x5a024051, 0x6147ce38,0x91d1eca5, + 0xbc2ac690,0xbe94d523}, + {0x1,0x0, 0x0,0xffffffff, 0xffffffff,0xffffffff, 0xfffffffe,0x0}}, + {{0x79ec1a0f,0x2d8daefd, 0xceb39c97,0x3bbcd6fd, 0x58f61a95,0xf5575ffc, + 0xadf7b420,0xdbd986c4}, + {0x15f39eb7,0x81aa8814, 0xb98d976c,0x6ee2fcf5, 0xcf2f717d,0x5465475d, + 0x6860bbd0,0x8e24d3c4}, + {0x1,0x0, 0x0,0xffffffff, 0xffffffff,0xffffffff, 0xfffffffe,0x0}}}}; +#endif + +// select_point selects the |idx|th point from a precomputation table and +// copies it to out. +static void select_point(const limb_t idx, size_t size, + const fe pre_comp[/*size*/][3], + fe out[3]) { + OPENSSL_memset(out, 0, sizeof(fe) * 3); + for (size_t i = 0; i < size; i++) { + limb_t mismatch = i ^ idx; + fe_cmovznz(out[0], mismatch, pre_comp[i][0], out[0]); + fe_cmovznz(out[1], mismatch, pre_comp[i][1], out[1]); + fe_cmovznz(out[2], mismatch, pre_comp[i][2], out[2]); + } +} + +// get_bit returns the |i|th bit in |in| +static char get_bit(const uint8_t *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 p_pre_comp, the scalar +// in p_scalar, if non-NULL. 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(fe x_out, fe y_out, fe z_out, + const uint8_t *p_scalar, const uint8_t *g_scalar, + const fe p_pre_comp[17][3]) { + // set nq to the point at infinity + fe nq[3] = {{0},{0},{0}}, ftmp, tmp[3]; + uint64_t bits; + uint8_t sign, digit; + + // Loop over both scalars msb-to-lsb, interleaving additions of multiples + // of the generator (two in each of the last 32 rounds) and additions of p + // (every 5th round). + + int skip = 1; // save two point operations in the first round + size_t i = p_scalar != NULL ? 255 : 31; + for (;;) { + // double + if (!skip) { + point_double(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2]); + } + + // add multiples of the generator + if (g_scalar != NULL && 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) { + point_add(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2], 1 /* mixed */, + tmp[0], tmp[1], tmp[2]); + } else { + fe_copy(nq[0], tmp[0]); + fe_copy(nq[1], tmp[1]); + fe_copy(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); + 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 (p_scalar != NULL && i % 5 == 0) { + bits = get_bit(p_scalar, i + 4) << 5; + bits |= get_bit(p_scalar, i + 3) << 4; + bits |= get_bit(p_scalar, i + 2) << 3; + bits |= get_bit(p_scalar, i + 1) << 2; + bits |= get_bit(p_scalar, i) << 1; + bits |= get_bit(p_scalar, 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, p_pre_comp, tmp); + fe_opp(ftmp, tmp[1]); // (X, -Y, Z) is the negative point. + fe_cmovznz(tmp[1], sign, tmp[1], ftmp); + + if (!skip) { + point_add(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2], 0 /* mixed */, + tmp[0], tmp[1], tmp[2]); + } else { + fe_copy(nq[0], tmp[0]); + fe_copy(nq[1], tmp[1]); + fe_copy(nq[2], tmp[2]); + skip = 0; + } + } + + if (i == 0) { + break; + } + --i; + } + fe_copy(x_out, nq[0]); + fe_copy(y_out, nq[1]); + fe_copy(z_out, nq[2]); +} + +// OPENSSL EC_METHOD FUNCTIONS + +// Takes the Jacobian coordinates (X, Y, Z) of a point and returns (X', Y') = +// (X/Z^2, Y/Z^3). +static int ec_GFp_nistp256_point_get_affine_coordinates(const EC_GROUP *group, + const EC_POINT *point, + BIGNUM *x_out, + BIGNUM *y_out, + BN_CTX *ctx) { + fe x, y, z1, z2; + + if (EC_POINT_is_at_infinity(group, point)) { + OPENSSL_PUT_ERROR(EC, EC_R_POINT_AT_INFINITY); + return 0; + } + if (!BN_to_fe(x, &point->X) || + !BN_to_fe(y, &point->Y) || + !BN_to_fe(z1, &point->Z)) { + return 0; + } + + fe_inv(z2, z1); + fe_sqr(z1, z2); + + // Instead of using |fe_from_montgomery| to convert the |x| coordinate and + // then calling |fe_from_montgomery| again to convert the |y| coordinate + // below, convert the common factor |z1| once now, saving one reduction. + fe_from_montgomery(z1); + + if (x_out != NULL) { + fe_mul(x, x, z1); + if (!fe_to_BN(x_out, x)) { + OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB); + return 0; + } + } + + if (y_out != NULL) { + fe_mul(z1, z1, z2); + fe_mul(y, y, z1); + if (!fe_to_BN(y_out, y)) { + OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB); + return 0; + } + } + + return 1; +} + +static int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r, + const EC_SCALAR *g_scalar, + const EC_POINT *p, + const EC_SCALAR *p_scalar, + BN_CTX *unused_ctx) { + fe p_pre_comp[17][3]; + fe x_out, y_out, z_out; + + if (p != NULL && p_scalar != NULL) { + // We treat NULL scalars as 0, and NULL points as points at infinity, i.e., + // they contribute nothing to the linear combination. + OPENSSL_memset(&p_pre_comp, 0, sizeof(p_pre_comp)); + // Precompute multiples. + if (!BN_to_fe(p_pre_comp[1][0], &p->X) || + !BN_to_fe(p_pre_comp[1][1], &p->Y) || + !BN_to_fe(p_pre_comp[1][2], &p->Z)) { + return 0; + } + for (size_t j = 2; j <= 16; ++j) { + if (j & 1) { + point_add(p_pre_comp[j][0], p_pre_comp[j][1], + p_pre_comp[j][2], p_pre_comp[1][0], + p_pre_comp[1][1], p_pre_comp[1][2], + 0, + p_pre_comp[j - 1][0], p_pre_comp[j - 1][1], + p_pre_comp[j - 1][2]); + } else { + point_double(p_pre_comp[j][0], p_pre_comp[j][1], + p_pre_comp[j][2], p_pre_comp[j / 2][0], + p_pre_comp[j / 2][1], p_pre_comp[j / 2][2]); + } + } + } + + batch_mul(x_out, y_out, z_out, + (p != NULL && p_scalar != NULL) ? p_scalar->bytes : NULL, + g_scalar != NULL ? g_scalar->bytes : NULL, + (const fe (*) [3])p_pre_comp); + + if (!fe_to_BN(&r->X, x_out) || + !fe_to_BN(&r->Y, y_out) || + !fe_to_BN(&r->Z, z_out)) { + OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB); + return 0; + } + return 1; +} + +static int ec_GFp_nistp256_point_mul_public(const EC_GROUP *group, EC_POINT *r, + const EC_SCALAR *g_scalar, + const EC_POINT *p, + const EC_SCALAR *p_scalar, + BN_CTX *unused_ctx) { +#define P256_WSIZE_PUBLIC 4 + // Precompute multiples of |p|. p_pre_comp[i] is (2*i+1) * |p|. + fe p_pre_comp[1 << (P256_WSIZE_PUBLIC-1)][3]; + if (!BN_to_fe(p_pre_comp[0][0], &p->X) || + !BN_to_fe(p_pre_comp[0][1], &p->Y) || + !BN_to_fe(p_pre_comp[0][2], &p->Z)) { + return 0; + } + fe p2[3]; + point_double(p2[0], p2[1], p2[2], p_pre_comp[0][0], p_pre_comp[0][1], + p_pre_comp[0][2]); + for (size_t i = 1; i < OPENSSL_ARRAY_SIZE(p_pre_comp); i++) { + point_add(p_pre_comp[i][0], p_pre_comp[i][1], p_pre_comp[i][2], + p_pre_comp[i - 1][0], p_pre_comp[i - 1][1], p_pre_comp[i - 1][2], + 0 /* not mixed */, p2[0], p2[1], p2[2]); + } + + // Set up the coefficients for |p_scalar|. + int8_t p_wNAF[257]; + if (!ec_compute_wNAF(group, p_wNAF, p_scalar, 256, P256_WSIZE_PUBLIC)) { + return 0; + } + + // Set |ret| to the point at infinity. + int skip = 1; // Save some point operations. + fe ret[3] = {{0},{0},{0}}; + for (int i = 256; i >= 0; i--) { + if (!skip) { + point_double(ret[0], ret[1], ret[2], ret[0], ret[1], ret[2]); + } + + // For the |g_scalar|, we use the precomputed table without the + // constant-time lookup. + if (i <= 31) { + // First, look 32 bits upwards. + uint64_t bits = get_bit(g_scalar->bytes, i + 224) << 3; + bits |= get_bit(g_scalar->bytes, i + 160) << 2; + bits |= get_bit(g_scalar->bytes, i + 96) << 1; + bits |= get_bit(g_scalar->bytes, i + 32); + point_add(ret[0], ret[1], ret[2], ret[0], ret[1], ret[2], 1 /* mixed */, + g_pre_comp[1][bits][0], g_pre_comp[1][bits][1], + g_pre_comp[1][bits][2]); + skip = 0; + + // Second, look at the current position. + bits = get_bit(g_scalar->bytes, i + 192) << 3; + bits |= get_bit(g_scalar->bytes, i + 128) << 2; + bits |= get_bit(g_scalar->bytes, i + 64) << 1; + bits |= get_bit(g_scalar->bytes, i); + point_add(ret[0], ret[1], ret[2], ret[0], ret[1], ret[2], 1 /* mixed */, + g_pre_comp[0][bits][0], g_pre_comp[0][bits][1], + g_pre_comp[0][bits][2]); + } + + int digit = p_wNAF[i]; + if (digit != 0) { + assert(digit & 1); + int idx = digit < 0 ? (-digit) >> 1 : digit >> 1; + fe *y = &p_pre_comp[idx][1], tmp; + if (digit < 0) { + fe_opp(tmp, p_pre_comp[idx][1]); + y = &tmp; + } + if (!skip) { + point_add(ret[0], ret[1], ret[2], ret[0], ret[1], ret[2], + 0 /* not mixed */, p_pre_comp[idx][0], *y, p_pre_comp[idx][2]); + } else { + fe_copy(ret[0], p_pre_comp[idx][0]); + fe_copy(ret[1], *y); + fe_copy(ret[2], p_pre_comp[idx][2]); + skip = 0; + } + } + } + + if (!fe_to_BN(&r->X, ret[0]) || + !fe_to_BN(&r->Y, ret[1]) || + !fe_to_BN(&r->Z, ret[2])) { + OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB); + return 0; + } + return 1; +} + +DEFINE_METHOD_FUNCTION(EC_METHOD, EC_GFp_nistp256_method) { + out->group_init = ec_GFp_mont_group_init; + out->group_finish = ec_GFp_mont_group_finish; + out->group_set_curve = ec_GFp_mont_group_set_curve; + out->point_get_affine_coordinates = + ec_GFp_nistp256_point_get_affine_coordinates; + out->mul = ec_GFp_nistp256_points_mul; + out->mul_public = ec_GFp_nistp256_point_mul_public; + out->field_mul = ec_GFp_mont_field_mul; + out->field_sqr = ec_GFp_mont_field_sqr; + out->field_encode = ec_GFp_mont_field_encode; + out->field_decode = ec_GFp_mont_field_decode; +}; + +#undef BORINGSSL_NISTP256_64BIT diff --git a/FoodApp/Pods/BoringSSL-GRPC/third_party/fiat/p256.c.grpc_back b/FoodApp/Pods/BoringSSL-GRPC/third_party/fiat/p256.c.grpc_back new file mode 100644 index 0000000..82f3608 --- /dev/null +++ b/FoodApp/Pods/BoringSSL-GRPC/third_party/fiat/p256.c.grpc_back @@ -0,0 +1,1824 @@ +// The MIT License (MIT) +// +// Copyright (c) 2015-2016 the fiat-crypto authors (see the AUTHORS file). +// +// 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. + +// The field arithmetic code is generated by Fiat +// (https://github.com/mit-plv/fiat-crypto), which is MIT licensed. +// +// An implementation of the NIST P-256 elliptic curve point multiplication. +// 256-bit Montgomery form, generated using fiat-crypto, for 64 and 32-bit. +// Field operations with inputs in [0,p) return outputs in [0,p). + +#include + +#include +#include +#include +#include + +#include + +#include "../../crypto/fipsmodule/delocate.h" +#include "../../crypto/fipsmodule/ec/internal.h" +#include "../../crypto/internal.h" + + +// MSVC does not implement uint128_t, and crashes with intrinsics +#if defined(BORINGSSL_HAS_UINT128) +#define BORINGSSL_NISTP256_64BIT 1 +#endif + +// "intrinsics" + +#if defined(BORINGSSL_NISTP256_64BIT) + +static uint64_t mulx_u64(uint64_t a, uint64_t b, uint64_t *high) { + uint128_t x = (uint128_t)a * b; + *high = (uint64_t) (x >> 64); + return (uint64_t) x; +} + +static uint64_t addcarryx_u64(uint8_t c, uint64_t a, uint64_t b, uint64_t *low) { + uint128_t x = (uint128_t)a + b + c; + *low = (uint64_t) x; + return (uint64_t) (x>>64); +} + +static uint64_t subborrow_u64(uint8_t c, uint64_t a, uint64_t b, uint64_t *low) { + uint128_t t = ((uint128_t) b + c); + uint128_t x = a-t; + *low = (uint64_t) x; + return (uint8_t) (x>>127); +} + +static uint64_t cmovznz_u64(uint64_t t, uint64_t z, uint64_t nz) { + t = -!!t; // all set if nonzero, 0 if 0 + return (t&nz) | ((~t)&z); +} + +#else + +static uint32_t mulx_u32(uint32_t a, uint32_t b, uint32_t *high) { + uint64_t x = (uint64_t)a * b; + *high = (uint32_t) (x >> 32); + return (uint32_t) x; +} + +static uint32_t addcarryx_u32(uint8_t c, uint32_t a, uint32_t b, uint32_t *low) { + uint64_t x = (uint64_t)a + b + c; + *low = (uint32_t) x; + return (uint32_t) (x>>32); +} + +static uint32_t subborrow_u32(uint8_t c, uint32_t a, uint32_t b, uint32_t *low) { + uint64_t t = ((uint64_t) b + c); + uint64_t x = a-t; + *low = (uint32_t) x; + return (uint8_t) (x>>63); +} + +static uint32_t cmovznz_u32(uint32_t t, uint32_t z, uint32_t nz) { + t = -!!t; // all set if nonzero, 0 if 0 + return (t&nz) | ((~t)&z); +} + +#endif + +// fiat-crypto generated code + +#if defined(BORINGSSL_NISTP256_64BIT) + +static void fe_add(uint64_t out[4], const uint64_t in1[4], const uint64_t in2[4]) { + { const uint64_t x8 = in1[3]; + { const uint64_t x9 = in1[2]; + { const uint64_t x7 = in1[1]; + { const uint64_t x5 = in1[0]; + { const uint64_t x14 = in2[3]; + { const uint64_t x15 = in2[2]; + { const uint64_t x13 = in2[1]; + { const uint64_t x11 = in2[0]; + { uint64_t x17; uint8_t x18 = addcarryx_u64(0x0, x5, x11, &x17); + { uint64_t x20; uint8_t x21 = addcarryx_u64(x18, x7, x13, &x20); + { uint64_t x23; uint8_t x24 = addcarryx_u64(x21, x9, x15, &x23); + { uint64_t x26; uint8_t x27 = addcarryx_u64(x24, x8, x14, &x26); + { uint64_t x29; uint8_t x30 = subborrow_u64(0x0, x17, 0xffffffffffffffffL, &x29); + { uint64_t x32; uint8_t x33 = subborrow_u64(x30, x20, 0xffffffff, &x32); + { uint64_t x35; uint8_t x36 = subborrow_u64(x33, x23, 0x0, &x35); + { uint64_t x38; uint8_t x39 = subborrow_u64(x36, x26, 0xffffffff00000001L, &x38); + { uint64_t _1; uint8_t x42 = subborrow_u64(x39, x27, 0x0, &_1); + { uint64_t x43 = cmovznz_u64(x42, x38, x26); + { uint64_t x44 = cmovznz_u64(x42, x35, x23); + { uint64_t x45 = cmovznz_u64(x42, x32, x20); + { uint64_t x46 = cmovznz_u64(x42, x29, x17); + out[0] = x46; + out[1] = x45; + out[2] = x44; + out[3] = x43; + }}}}}}}}}}}}}}}}}}}}} +} + +// fe_op sets out = -in +static void fe_opp(uint64_t out[4], const uint64_t in1[4]) { + const uint64_t x5 = in1[3]; + const uint64_t x6 = in1[2]; + const uint64_t x4 = in1[1]; + const uint64_t x2 = in1[0]; + uint64_t x8; uint8_t x9 = subborrow_u64(0x0, 0x0, x2, &x8); + uint64_t x11; uint8_t x12 = subborrow_u64(x9, 0x0, x4, &x11); + uint64_t x14; uint8_t x15 = subborrow_u64(x12, 0x0, x6, &x14); + uint64_t x17; uint8_t x18 = subborrow_u64(x15, 0x0, x5, &x17); + uint64_t x19 = (uint64_t)cmovznz_u64(x18, 0x0, 0xffffffffffffffffL); + uint64_t x20 = (x19 & 0xffffffffffffffffL); + uint64_t x22; uint8_t x23 = addcarryx_u64(0x0, x8, x20, &x22); + uint64_t x24 = (x19 & 0xffffffff); + uint64_t x26; uint8_t x27 = addcarryx_u64(x23, x11, x24, &x26); + uint64_t x29; uint8_t x30 = addcarryx_u64(x27, x14, 0x0, &x29); + uint64_t x31 = (x19 & 0xffffffff00000001L); + uint64_t x33; addcarryx_u64(x30, x17, x31, &x33); + out[0] = x22; + out[1] = x26; + out[2] = x29; + out[3] = x33; +} + +static void fe_mul(uint64_t out[4], const uint64_t in1[4], const uint64_t in2[4]) { + const uint64_t x8 = in1[3]; + const uint64_t x9 = in1[2]; + const uint64_t x7 = in1[1]; + const uint64_t x5 = in1[0]; + const uint64_t x14 = in2[3]; + const uint64_t x15 = in2[2]; + const uint64_t x13 = in2[1]; + const uint64_t x11 = in2[0]; + uint64_t x18; uint64_t x17 = mulx_u64(x5, x11, &x18); + uint64_t x21; uint64_t x20 = mulx_u64(x5, x13, &x21); + uint64_t x24; uint64_t x23 = mulx_u64(x5, x15, &x24); + uint64_t x27; uint64_t x26 = mulx_u64(x5, x14, &x27); + uint64_t x29; uint8_t x30 = addcarryx_u64(0x0, x18, x20, &x29); + uint64_t x32; uint8_t x33 = addcarryx_u64(x30, x21, x23, &x32); + uint64_t x35; uint8_t x36 = addcarryx_u64(x33, x24, x26, &x35); + uint64_t x38; addcarryx_u64(0x0, x36, x27, &x38); + uint64_t x42; uint64_t x41 = mulx_u64(x17, 0xffffffffffffffffL, &x42); + uint64_t x45; uint64_t x44 = mulx_u64(x17, 0xffffffff, &x45); + uint64_t x48; uint64_t x47 = mulx_u64(x17, 0xffffffff00000001L, &x48); + uint64_t x50; uint8_t x51 = addcarryx_u64(0x0, x42, x44, &x50); + uint64_t x53; uint8_t x54 = addcarryx_u64(x51, x45, 0x0, &x53); + uint64_t x56; uint8_t x57 = addcarryx_u64(x54, 0x0, x47, &x56); + uint64_t x59; addcarryx_u64(0x0, x57, x48, &x59); + uint64_t _2; uint8_t x63 = addcarryx_u64(0x0, x17, x41, &_2); + uint64_t x65; uint8_t x66 = addcarryx_u64(x63, x29, x50, &x65); + uint64_t x68; uint8_t x69 = addcarryx_u64(x66, x32, x53, &x68); + uint64_t x71; uint8_t x72 = addcarryx_u64(x69, x35, x56, &x71); + uint64_t x74; uint8_t x75 = addcarryx_u64(x72, x38, x59, &x74); + uint64_t x78; uint64_t x77 = mulx_u64(x7, x11, &x78); + uint64_t x81; uint64_t x80 = mulx_u64(x7, x13, &x81); + uint64_t x84; uint64_t x83 = mulx_u64(x7, x15, &x84); + uint64_t x87; uint64_t x86 = mulx_u64(x7, x14, &x87); + uint64_t x89; uint8_t x90 = addcarryx_u64(0x0, x78, x80, &x89); + uint64_t x92; uint8_t x93 = addcarryx_u64(x90, x81, x83, &x92); + uint64_t x95; uint8_t x96 = addcarryx_u64(x93, x84, x86, &x95); + uint64_t x98; addcarryx_u64(0x0, x96, x87, &x98); + uint64_t x101; uint8_t x102 = addcarryx_u64(0x0, x65, x77, &x101); + uint64_t x104; uint8_t x105 = addcarryx_u64(x102, x68, x89, &x104); + uint64_t x107; uint8_t x108 = addcarryx_u64(x105, x71, x92, &x107); + uint64_t x110; uint8_t x111 = addcarryx_u64(x108, x74, x95, &x110); + uint64_t x113; uint8_t x114 = addcarryx_u64(x111, x75, x98, &x113); + uint64_t x117; uint64_t x116 = mulx_u64(x101, 0xffffffffffffffffL, &x117); + uint64_t x120; uint64_t x119 = mulx_u64(x101, 0xffffffff, &x120); + uint64_t x123; uint64_t x122 = mulx_u64(x101, 0xffffffff00000001L, &x123); + uint64_t x125; uint8_t x126 = addcarryx_u64(0x0, x117, x119, &x125); + uint64_t x128; uint8_t x129 = addcarryx_u64(x126, x120, 0x0, &x128); + uint64_t x131; uint8_t x132 = addcarryx_u64(x129, 0x0, x122, &x131); + uint64_t x134; addcarryx_u64(0x0, x132, x123, &x134); + uint64_t _3; uint8_t x138 = addcarryx_u64(0x0, x101, x116, &_3); + uint64_t x140; uint8_t x141 = addcarryx_u64(x138, x104, x125, &x140); + uint64_t x143; uint8_t x144 = addcarryx_u64(x141, x107, x128, &x143); + uint64_t x146; uint8_t x147 = addcarryx_u64(x144, x110, x131, &x146); + uint64_t x149; uint8_t x150 = addcarryx_u64(x147, x113, x134, &x149); + uint8_t x151 = (x150 + x114); + uint64_t x154; uint64_t x153 = mulx_u64(x9, x11, &x154); + uint64_t x157; uint64_t x156 = mulx_u64(x9, x13, &x157); + uint64_t x160; uint64_t x159 = mulx_u64(x9, x15, &x160); + uint64_t x163; uint64_t x162 = mulx_u64(x9, x14, &x163); + uint64_t x165; uint8_t x166 = addcarryx_u64(0x0, x154, x156, &x165); + uint64_t x168; uint8_t x169 = addcarryx_u64(x166, x157, x159, &x168); + uint64_t x171; uint8_t x172 = addcarryx_u64(x169, x160, x162, &x171); + uint64_t x174; addcarryx_u64(0x0, x172, x163, &x174); + uint64_t x177; uint8_t x178 = addcarryx_u64(0x0, x140, x153, &x177); + uint64_t x180; uint8_t x181 = addcarryx_u64(x178, x143, x165, &x180); + uint64_t x183; uint8_t x184 = addcarryx_u64(x181, x146, x168, &x183); + uint64_t x186; uint8_t x187 = addcarryx_u64(x184, x149, x171, &x186); + uint64_t x189; uint8_t x190 = addcarryx_u64(x187, x151, x174, &x189); + uint64_t x193; uint64_t x192 = mulx_u64(x177, 0xffffffffffffffffL, &x193); + uint64_t x196; uint64_t x195 = mulx_u64(x177, 0xffffffff, &x196); + uint64_t x199; uint64_t x198 = mulx_u64(x177, 0xffffffff00000001L, &x199); + uint64_t x201; uint8_t x202 = addcarryx_u64(0x0, x193, x195, &x201); + uint64_t x204; uint8_t x205 = addcarryx_u64(x202, x196, 0x0, &x204); + uint64_t x207; uint8_t x208 = addcarryx_u64(x205, 0x0, x198, &x207); + uint64_t x210; addcarryx_u64(0x0, x208, x199, &x210); + uint64_t _4; uint8_t x214 = addcarryx_u64(0x0, x177, x192, &_4); + uint64_t x216; uint8_t x217 = addcarryx_u64(x214, x180, x201, &x216); + uint64_t x219; uint8_t x220 = addcarryx_u64(x217, x183, x204, &x219); + uint64_t x222; uint8_t x223 = addcarryx_u64(x220, x186, x207, &x222); + uint64_t x225; uint8_t x226 = addcarryx_u64(x223, x189, x210, &x225); + uint8_t x227 = (x226 + x190); + uint64_t x230; uint64_t x229 = mulx_u64(x8, x11, &x230); + uint64_t x233; uint64_t x232 = mulx_u64(x8, x13, &x233); + uint64_t x236; uint64_t x235 = mulx_u64(x8, x15, &x236); + uint64_t x239; uint64_t x238 = mulx_u64(x8, x14, &x239); + uint64_t x241; uint8_t x242 = addcarryx_u64(0x0, x230, x232, &x241); + uint64_t x244; uint8_t x245 = addcarryx_u64(x242, x233, x235, &x244); + uint64_t x247; uint8_t x248 = addcarryx_u64(x245, x236, x238, &x247); + uint64_t x250; addcarryx_u64(0x0, x248, x239, &x250); + uint64_t x253; uint8_t x254 = addcarryx_u64(0x0, x216, x229, &x253); + uint64_t x256; uint8_t x257 = addcarryx_u64(x254, x219, x241, &x256); + uint64_t x259; uint8_t x260 = addcarryx_u64(x257, x222, x244, &x259); + uint64_t x262; uint8_t x263 = addcarryx_u64(x260, x225, x247, &x262); + uint64_t x265; uint8_t x266 = addcarryx_u64(x263, x227, x250, &x265); + uint64_t x269; uint64_t x268 = mulx_u64(x253, 0xffffffffffffffffL, &x269); + uint64_t x272; uint64_t x271 = mulx_u64(x253, 0xffffffff, &x272); + uint64_t x275; uint64_t x274 = mulx_u64(x253, 0xffffffff00000001L, &x275); + uint64_t x277; uint8_t x278 = addcarryx_u64(0x0, x269, x271, &x277); + uint64_t x280; uint8_t x281 = addcarryx_u64(x278, x272, 0x0, &x280); + uint64_t x283; uint8_t x284 = addcarryx_u64(x281, 0x0, x274, &x283); + uint64_t x286; addcarryx_u64(0x0, x284, x275, &x286); + uint64_t _5; uint8_t x290 = addcarryx_u64(0x0, x253, x268, &_5); + uint64_t x292; uint8_t x293 = addcarryx_u64(x290, x256, x277, &x292); + uint64_t x295; uint8_t x296 = addcarryx_u64(x293, x259, x280, &x295); + uint64_t x298; uint8_t x299 = addcarryx_u64(x296, x262, x283, &x298); + uint64_t x301; uint8_t x302 = addcarryx_u64(x299, x265, x286, &x301); + uint8_t x303 = (x302 + x266); + uint64_t x305; uint8_t x306 = subborrow_u64(0x0, x292, 0xffffffffffffffffL, &x305); + uint64_t x308; uint8_t x309 = subborrow_u64(x306, x295, 0xffffffff, &x308); + uint64_t x311; uint8_t x312 = subborrow_u64(x309, x298, 0x0, &x311); + uint64_t x314; uint8_t x315 = subborrow_u64(x312, x301, 0xffffffff00000001L, &x314); + uint64_t _6; uint8_t x318 = subborrow_u64(x315, x303, 0x0, &_6); + uint64_t x319 = cmovznz_u64(x318, x314, x301); + uint64_t x320 = cmovznz_u64(x318, x311, x298); + uint64_t x321 = cmovznz_u64(x318, x308, x295); + uint64_t x322 = cmovznz_u64(x318, x305, x292); + out[0] = x322; + out[1] = x321; + out[2] = x320; + out[3] = x319; +} + +static void fe_sub(uint64_t out[4], const uint64_t in1[4], const uint64_t in2[4]) { + const uint64_t x8 = in1[3]; + const uint64_t x9 = in1[2]; + const uint64_t x7 = in1[1]; + const uint64_t x5 = in1[0]; + const uint64_t x14 = in2[3]; + const uint64_t x15 = in2[2]; + const uint64_t x13 = in2[1]; + const uint64_t x11 = in2[0]; + uint64_t x17; uint8_t x18 = subborrow_u64(0x0, x5, x11, &x17); + uint64_t x20; uint8_t x21 = subborrow_u64(x18, x7, x13, &x20); + uint64_t x23; uint8_t x24 = subborrow_u64(x21, x9, x15, &x23); + uint64_t x26; uint8_t x27 = subborrow_u64(x24, x8, x14, &x26); + uint64_t x28 = (uint64_t)cmovznz_u64(x27, 0x0, 0xffffffffffffffffL); + uint64_t x29 = (x28 & 0xffffffffffffffffL); + uint64_t x31; uint8_t x32 = addcarryx_u64(0x0, x17, x29, &x31); + uint64_t x33 = (x28 & 0xffffffff); + uint64_t x35; uint8_t x36 = addcarryx_u64(x32, x20, x33, &x35); + uint64_t x38; uint8_t x39 = addcarryx_u64(x36, x23, 0x0, &x38); + uint64_t x40 = (x28 & 0xffffffff00000001L); + uint64_t x42; addcarryx_u64(x39, x26, x40, &x42); + out[0] = x31; + out[1] = x35; + out[2] = x38; + out[3] = x42; +} + +#else // 64BIT, else 32BIT + +static void fe_add(uint32_t out[8], const uint32_t in1[8], const uint32_t in2[8]) { + const uint32_t x16 = in1[7]; + const uint32_t x17 = in1[6]; + const uint32_t x15 = in1[5]; + const uint32_t x13 = in1[4]; + const uint32_t x11 = in1[3]; + const uint32_t x9 = in1[2]; + const uint32_t x7 = in1[1]; + const uint32_t x5 = in1[0]; + const uint32_t x30 = in2[7]; + const uint32_t x31 = in2[6]; + const uint32_t x29 = in2[5]; + const uint32_t x27 = in2[4]; + const uint32_t x25 = in2[3]; + const uint32_t x23 = in2[2]; + const uint32_t x21 = in2[1]; + const uint32_t x19 = in2[0]; + uint32_t x33; uint8_t x34 = addcarryx_u32(0x0, x5, x19, &x33); + uint32_t x36; uint8_t x37 = addcarryx_u32(x34, x7, x21, &x36); + uint32_t x39; uint8_t x40 = addcarryx_u32(x37, x9, x23, &x39); + uint32_t x42; uint8_t x43 = addcarryx_u32(x40, x11, x25, &x42); + uint32_t x45; uint8_t x46 = addcarryx_u32(x43, x13, x27, &x45); + uint32_t x48; uint8_t x49 = addcarryx_u32(x46, x15, x29, &x48); + uint32_t x51; uint8_t x52 = addcarryx_u32(x49, x17, x31, &x51); + uint32_t x54; uint8_t x55 = addcarryx_u32(x52, x16, x30, &x54); + uint32_t x57; uint8_t x58 = subborrow_u32(0x0, x33, 0xffffffff, &x57); + uint32_t x60; uint8_t x61 = subborrow_u32(x58, x36, 0xffffffff, &x60); + uint32_t x63; uint8_t x64 = subborrow_u32(x61, x39, 0xffffffff, &x63); + uint32_t x66; uint8_t x67 = subborrow_u32(x64, x42, 0x0, &x66); + uint32_t x69; uint8_t x70 = subborrow_u32(x67, x45, 0x0, &x69); + uint32_t x72; uint8_t x73 = subborrow_u32(x70, x48, 0x0, &x72); + uint32_t x75; uint8_t x76 = subborrow_u32(x73, x51, 0x1, &x75); + uint32_t x78; uint8_t x79 = subborrow_u32(x76, x54, 0xffffffff, &x78); + uint32_t _; uint8_t x82 = subborrow_u32(x79, x55, 0x0, &_); + uint32_t x83 = cmovznz_u32(x82, x78, x54); + uint32_t x84 = cmovznz_u32(x82, x75, x51); + uint32_t x85 = cmovznz_u32(x82, x72, x48); + uint32_t x86 = cmovznz_u32(x82, x69, x45); + uint32_t x87 = cmovznz_u32(x82, x66, x42); + uint32_t x88 = cmovznz_u32(x82, x63, x39); + uint32_t x89 = cmovznz_u32(x82, x60, x36); + uint32_t x90 = cmovznz_u32(x82, x57, x33); + out[0] = x90; + out[1] = x89; + out[2] = x88; + out[3] = x87; + out[4] = x86; + out[5] = x85; + out[6] = x84; + out[7] = x83; +} + +static void fe_mul(uint32_t out[8], const uint32_t in1[8], const uint32_t in2[8]) { + const uint32_t x16 = in1[7]; + const uint32_t x17 = in1[6]; + const uint32_t x15 = in1[5]; + const uint32_t x13 = in1[4]; + const uint32_t x11 = in1[3]; + const uint32_t x9 = in1[2]; + const uint32_t x7 = in1[1]; + const uint32_t x5 = in1[0]; + const uint32_t x30 = in2[7]; + const uint32_t x31 = in2[6]; + const uint32_t x29 = in2[5]; + const uint32_t x27 = in2[4]; + const uint32_t x25 = in2[3]; + const uint32_t x23 = in2[2]; + const uint32_t x21 = in2[1]; + const uint32_t x19 = in2[0]; + uint32_t x34; uint32_t x33 = mulx_u32(x5, x19, &x34); + uint32_t x37; uint32_t x36 = mulx_u32(x5, x21, &x37); + uint32_t x40; uint32_t x39 = mulx_u32(x5, x23, &x40); + uint32_t x43; uint32_t x42 = mulx_u32(x5, x25, &x43); + uint32_t x46; uint32_t x45 = mulx_u32(x5, x27, &x46); + uint32_t x49; uint32_t x48 = mulx_u32(x5, x29, &x49); + uint32_t x52; uint32_t x51 = mulx_u32(x5, x31, &x52); + uint32_t x55; uint32_t x54 = mulx_u32(x5, x30, &x55); + uint32_t x57; uint8_t x58 = addcarryx_u32(0x0, x34, x36, &x57); + uint32_t x60; uint8_t x61 = addcarryx_u32(x58, x37, x39, &x60); + uint32_t x63; uint8_t x64 = addcarryx_u32(x61, x40, x42, &x63); + uint32_t x66; uint8_t x67 = addcarryx_u32(x64, x43, x45, &x66); + uint32_t x69; uint8_t x70 = addcarryx_u32(x67, x46, x48, &x69); + uint32_t x72; uint8_t x73 = addcarryx_u32(x70, x49, x51, &x72); + uint32_t x75; uint8_t x76 = addcarryx_u32(x73, x52, x54, &x75); + uint32_t x78; addcarryx_u32(0x0, x76, x55, &x78); + uint32_t x82; uint32_t x81 = mulx_u32(x33, 0xffffffff, &x82); + uint32_t x85; uint32_t x84 = mulx_u32(x33, 0xffffffff, &x85); + uint32_t x88; uint32_t x87 = mulx_u32(x33, 0xffffffff, &x88); + uint32_t x91; uint32_t x90 = mulx_u32(x33, 0xffffffff, &x91); + uint32_t x93; uint8_t x94 = addcarryx_u32(0x0, x82, x84, &x93); + uint32_t x96; uint8_t x97 = addcarryx_u32(x94, x85, x87, &x96); + uint32_t x99; uint8_t x100 = addcarryx_u32(x97, x88, 0x0, &x99); + uint8_t x101 = (0x0 + 0x0); + uint32_t _1; uint8_t x104 = addcarryx_u32(0x0, x33, x81, &_1); + uint32_t x106; uint8_t x107 = addcarryx_u32(x104, x57, x93, &x106); + uint32_t x109; uint8_t x110 = addcarryx_u32(x107, x60, x96, &x109); + uint32_t x112; uint8_t x113 = addcarryx_u32(x110, x63, x99, &x112); + uint32_t x115; uint8_t x116 = addcarryx_u32(x113, x66, x100, &x115); + uint32_t x118; uint8_t x119 = addcarryx_u32(x116, x69, x101, &x118); + uint32_t x121; uint8_t x122 = addcarryx_u32(x119, x72, x33, &x121); + uint32_t x124; uint8_t x125 = addcarryx_u32(x122, x75, x90, &x124); + uint32_t x127; uint8_t x128 = addcarryx_u32(x125, x78, x91, &x127); + uint8_t x129 = (x128 + 0x0); + uint32_t x132; uint32_t x131 = mulx_u32(x7, x19, &x132); + uint32_t x135; uint32_t x134 = mulx_u32(x7, x21, &x135); + uint32_t x138; uint32_t x137 = mulx_u32(x7, x23, &x138); + uint32_t x141; uint32_t x140 = mulx_u32(x7, x25, &x141); + uint32_t x144; uint32_t x143 = mulx_u32(x7, x27, &x144); + uint32_t x147; uint32_t x146 = mulx_u32(x7, x29, &x147); + uint32_t x150; uint32_t x149 = mulx_u32(x7, x31, &x150); + uint32_t x153; uint32_t x152 = mulx_u32(x7, x30, &x153); + uint32_t x155; uint8_t x156 = addcarryx_u32(0x0, x132, x134, &x155); + uint32_t x158; uint8_t x159 = addcarryx_u32(x156, x135, x137, &x158); + uint32_t x161; uint8_t x162 = addcarryx_u32(x159, x138, x140, &x161); + uint32_t x164; uint8_t x165 = addcarryx_u32(x162, x141, x143, &x164); + uint32_t x167; uint8_t x168 = addcarryx_u32(x165, x144, x146, &x167); + uint32_t x170; uint8_t x171 = addcarryx_u32(x168, x147, x149, &x170); + uint32_t x173; uint8_t x174 = addcarryx_u32(x171, x150, x152, &x173); + uint32_t x176; addcarryx_u32(0x0, x174, x153, &x176); + uint32_t x179; uint8_t x180 = addcarryx_u32(0x0, x106, x131, &x179); + uint32_t x182; uint8_t x183 = addcarryx_u32(x180, x109, x155, &x182); + uint32_t x185; uint8_t x186 = addcarryx_u32(x183, x112, x158, &x185); + uint32_t x188; uint8_t x189 = addcarryx_u32(x186, x115, x161, &x188); + uint32_t x191; uint8_t x192 = addcarryx_u32(x189, x118, x164, &x191); + uint32_t x194; uint8_t x195 = addcarryx_u32(x192, x121, x167, &x194); + uint32_t x197; uint8_t x198 = addcarryx_u32(x195, x124, x170, &x197); + uint32_t x200; uint8_t x201 = addcarryx_u32(x198, x127, x173, &x200); + uint32_t x203; uint8_t x204 = addcarryx_u32(x201, x129, x176, &x203); + uint32_t x207; uint32_t x206 = mulx_u32(x179, 0xffffffff, &x207); + uint32_t x210; uint32_t x209 = mulx_u32(x179, 0xffffffff, &x210); + uint32_t x213; uint32_t x212 = mulx_u32(x179, 0xffffffff, &x213); + uint32_t x216; uint32_t x215 = mulx_u32(x179, 0xffffffff, &x216); + uint32_t x218; uint8_t x219 = addcarryx_u32(0x0, x207, x209, &x218); + uint32_t x221; uint8_t x222 = addcarryx_u32(x219, x210, x212, &x221); + uint32_t x224; uint8_t x225 = addcarryx_u32(x222, x213, 0x0, &x224); + uint8_t x226 = (0x0 + 0x0); + uint32_t _2; uint8_t x229 = addcarryx_u32(0x0, x179, x206, &_2); + uint32_t x231; uint8_t x232 = addcarryx_u32(x229, x182, x218, &x231); + uint32_t x234; uint8_t x235 = addcarryx_u32(x232, x185, x221, &x234); + uint32_t x237; uint8_t x238 = addcarryx_u32(x235, x188, x224, &x237); + uint32_t x240; uint8_t x241 = addcarryx_u32(x238, x191, x225, &x240); + uint32_t x243; uint8_t x244 = addcarryx_u32(x241, x194, x226, &x243); + uint32_t x246; uint8_t x247 = addcarryx_u32(x244, x197, x179, &x246); + uint32_t x249; uint8_t x250 = addcarryx_u32(x247, x200, x215, &x249); + uint32_t x252; uint8_t x253 = addcarryx_u32(x250, x203, x216, &x252); + uint8_t x254 = (x253 + x204); + uint32_t x257; uint32_t x256 = mulx_u32(x9, x19, &x257); + uint32_t x260; uint32_t x259 = mulx_u32(x9, x21, &x260); + uint32_t x263; uint32_t x262 = mulx_u32(x9, x23, &x263); + uint32_t x266; uint32_t x265 = mulx_u32(x9, x25, &x266); + uint32_t x269; uint32_t x268 = mulx_u32(x9, x27, &x269); + uint32_t x272; uint32_t x271 = mulx_u32(x9, x29, &x272); + uint32_t x275; uint32_t x274 = mulx_u32(x9, x31, &x275); + uint32_t x278; uint32_t x277 = mulx_u32(x9, x30, &x278); + uint32_t x280; uint8_t x281 = addcarryx_u32(0x0, x257, x259, &x280); + uint32_t x283; uint8_t x284 = addcarryx_u32(x281, x260, x262, &x283); + uint32_t x286; uint8_t x287 = addcarryx_u32(x284, x263, x265, &x286); + uint32_t x289; uint8_t x290 = addcarryx_u32(x287, x266, x268, &x289); + uint32_t x292; uint8_t x293 = addcarryx_u32(x290, x269, x271, &x292); + uint32_t x295; uint8_t x296 = addcarryx_u32(x293, x272, x274, &x295); + uint32_t x298; uint8_t x299 = addcarryx_u32(x296, x275, x277, &x298); + uint32_t x301; addcarryx_u32(0x0, x299, x278, &x301); + uint32_t x304; uint8_t x305 = addcarryx_u32(0x0, x231, x256, &x304); + uint32_t x307; uint8_t x308 = addcarryx_u32(x305, x234, x280, &x307); + uint32_t x310; uint8_t x311 = addcarryx_u32(x308, x237, x283, &x310); + uint32_t x313; uint8_t x314 = addcarryx_u32(x311, x240, x286, &x313); + uint32_t x316; uint8_t x317 = addcarryx_u32(x314, x243, x289, &x316); + uint32_t x319; uint8_t x320 = addcarryx_u32(x317, x246, x292, &x319); + uint32_t x322; uint8_t x323 = addcarryx_u32(x320, x249, x295, &x322); + uint32_t x325; uint8_t x326 = addcarryx_u32(x323, x252, x298, &x325); + uint32_t x328; uint8_t x329 = addcarryx_u32(x326, x254, x301, &x328); + uint32_t x332; uint32_t x331 = mulx_u32(x304, 0xffffffff, &x332); + uint32_t x335; uint32_t x334 = mulx_u32(x304, 0xffffffff, &x335); + uint32_t x338; uint32_t x337 = mulx_u32(x304, 0xffffffff, &x338); + uint32_t x341; uint32_t x340 = mulx_u32(x304, 0xffffffff, &x341); + uint32_t x343; uint8_t x344 = addcarryx_u32(0x0, x332, x334, &x343); + uint32_t x346; uint8_t x347 = addcarryx_u32(x344, x335, x337, &x346); + uint32_t x349; uint8_t x350 = addcarryx_u32(x347, x338, 0x0, &x349); + uint8_t x351 = (0x0 + 0x0); + uint32_t _3; uint8_t x354 = addcarryx_u32(0x0, x304, x331, &_3); + uint32_t x356; uint8_t x357 = addcarryx_u32(x354, x307, x343, &x356); + uint32_t x359; uint8_t x360 = addcarryx_u32(x357, x310, x346, &x359); + uint32_t x362; uint8_t x363 = addcarryx_u32(x360, x313, x349, &x362); + uint32_t x365; uint8_t x366 = addcarryx_u32(x363, x316, x350, &x365); + uint32_t x368; uint8_t x369 = addcarryx_u32(x366, x319, x351, &x368); + uint32_t x371; uint8_t x372 = addcarryx_u32(x369, x322, x304, &x371); + uint32_t x374; uint8_t x375 = addcarryx_u32(x372, x325, x340, &x374); + uint32_t x377; uint8_t x378 = addcarryx_u32(x375, x328, x341, &x377); + uint8_t x379 = (x378 + x329); + uint32_t x382; uint32_t x381 = mulx_u32(x11, x19, &x382); + uint32_t x385; uint32_t x384 = mulx_u32(x11, x21, &x385); + uint32_t x388; uint32_t x387 = mulx_u32(x11, x23, &x388); + uint32_t x391; uint32_t x390 = mulx_u32(x11, x25, &x391); + uint32_t x394; uint32_t x393 = mulx_u32(x11, x27, &x394); + uint32_t x397; uint32_t x396 = mulx_u32(x11, x29, &x397); + uint32_t x400; uint32_t x399 = mulx_u32(x11, x31, &x400); + uint32_t x403; uint32_t x402 = mulx_u32(x11, x30, &x403); + uint32_t x405; uint8_t x406 = addcarryx_u32(0x0, x382, x384, &x405); + uint32_t x408; uint8_t x409 = addcarryx_u32(x406, x385, x387, &x408); + uint32_t x411; uint8_t x412 = addcarryx_u32(x409, x388, x390, &x411); + uint32_t x414; uint8_t x415 = addcarryx_u32(x412, x391, x393, &x414); + uint32_t x417; uint8_t x418 = addcarryx_u32(x415, x394, x396, &x417); + uint32_t x420; uint8_t x421 = addcarryx_u32(x418, x397, x399, &x420); + uint32_t x423; uint8_t x424 = addcarryx_u32(x421, x400, x402, &x423); + uint32_t x426; addcarryx_u32(0x0, x424, x403, &x426); + uint32_t x429; uint8_t x430 = addcarryx_u32(0x0, x356, x381, &x429); + uint32_t x432; uint8_t x433 = addcarryx_u32(x430, x359, x405, &x432); + uint32_t x435; uint8_t x436 = addcarryx_u32(x433, x362, x408, &x435); + uint32_t x438; uint8_t x439 = addcarryx_u32(x436, x365, x411, &x438); + uint32_t x441; uint8_t x442 = addcarryx_u32(x439, x368, x414, &x441); + uint32_t x444; uint8_t x445 = addcarryx_u32(x442, x371, x417, &x444); + uint32_t x447; uint8_t x448 = addcarryx_u32(x445, x374, x420, &x447); + uint32_t x450; uint8_t x451 = addcarryx_u32(x448, x377, x423, &x450); + uint32_t x453; uint8_t x454 = addcarryx_u32(x451, x379, x426, &x453); + uint32_t x457; uint32_t x456 = mulx_u32(x429, 0xffffffff, &x457); + uint32_t x460; uint32_t x459 = mulx_u32(x429, 0xffffffff, &x460); + uint32_t x463; uint32_t x462 = mulx_u32(x429, 0xffffffff, &x463); + uint32_t x466; uint32_t x465 = mulx_u32(x429, 0xffffffff, &x466); + uint32_t x468; uint8_t x469 = addcarryx_u32(0x0, x457, x459, &x468); + uint32_t x471; uint8_t x472 = addcarryx_u32(x469, x460, x462, &x471); + uint32_t x474; uint8_t x475 = addcarryx_u32(x472, x463, 0x0, &x474); + uint8_t x476 = (0x0 + 0x0); + uint32_t _4; uint8_t x479 = addcarryx_u32(0x0, x429, x456, &_4); + uint32_t x481; uint8_t x482 = addcarryx_u32(x479, x432, x468, &x481); + uint32_t x484; uint8_t x485 = addcarryx_u32(x482, x435, x471, &x484); + uint32_t x487; uint8_t x488 = addcarryx_u32(x485, x438, x474, &x487); + uint32_t x490; uint8_t x491 = addcarryx_u32(x488, x441, x475, &x490); + uint32_t x493; uint8_t x494 = addcarryx_u32(x491, x444, x476, &x493); + uint32_t x496; uint8_t x497 = addcarryx_u32(x494, x447, x429, &x496); + uint32_t x499; uint8_t x500 = addcarryx_u32(x497, x450, x465, &x499); + uint32_t x502; uint8_t x503 = addcarryx_u32(x500, x453, x466, &x502); + uint8_t x504 = (x503 + x454); + uint32_t x507; uint32_t x506 = mulx_u32(x13, x19, &x507); + uint32_t x510; uint32_t x509 = mulx_u32(x13, x21, &x510); + uint32_t x513; uint32_t x512 = mulx_u32(x13, x23, &x513); + uint32_t x516; uint32_t x515 = mulx_u32(x13, x25, &x516); + uint32_t x519; uint32_t x518 = mulx_u32(x13, x27, &x519); + uint32_t x522; uint32_t x521 = mulx_u32(x13, x29, &x522); + uint32_t x525; uint32_t x524 = mulx_u32(x13, x31, &x525); + uint32_t x528; uint32_t x527 = mulx_u32(x13, x30, &x528); + uint32_t x530; uint8_t x531 = addcarryx_u32(0x0, x507, x509, &x530); + uint32_t x533; uint8_t x534 = addcarryx_u32(x531, x510, x512, &x533); + uint32_t x536; uint8_t x537 = addcarryx_u32(x534, x513, x515, &x536); + uint32_t x539; uint8_t x540 = addcarryx_u32(x537, x516, x518, &x539); + uint32_t x542; uint8_t x543 = addcarryx_u32(x540, x519, x521, &x542); + uint32_t x545; uint8_t x546 = addcarryx_u32(x543, x522, x524, &x545); + uint32_t x548; uint8_t x549 = addcarryx_u32(x546, x525, x527, &x548); + uint32_t x551; addcarryx_u32(0x0, x549, x528, &x551); + uint32_t x554; uint8_t x555 = addcarryx_u32(0x0, x481, x506, &x554); + uint32_t x557; uint8_t x558 = addcarryx_u32(x555, x484, x530, &x557); + uint32_t x560; uint8_t x561 = addcarryx_u32(x558, x487, x533, &x560); + uint32_t x563; uint8_t x564 = addcarryx_u32(x561, x490, x536, &x563); + uint32_t x566; uint8_t x567 = addcarryx_u32(x564, x493, x539, &x566); + uint32_t x569; uint8_t x570 = addcarryx_u32(x567, x496, x542, &x569); + uint32_t x572; uint8_t x573 = addcarryx_u32(x570, x499, x545, &x572); + uint32_t x575; uint8_t x576 = addcarryx_u32(x573, x502, x548, &x575); + uint32_t x578; uint8_t x579 = addcarryx_u32(x576, x504, x551, &x578); + uint32_t x582; uint32_t x581 = mulx_u32(x554, 0xffffffff, &x582); + uint32_t x585; uint32_t x584 = mulx_u32(x554, 0xffffffff, &x585); + uint32_t x588; uint32_t x587 = mulx_u32(x554, 0xffffffff, &x588); + uint32_t x591; uint32_t x590 = mulx_u32(x554, 0xffffffff, &x591); + uint32_t x593; uint8_t x594 = addcarryx_u32(0x0, x582, x584, &x593); + uint32_t x596; uint8_t x597 = addcarryx_u32(x594, x585, x587, &x596); + uint32_t x599; uint8_t x600 = addcarryx_u32(x597, x588, 0x0, &x599); + uint8_t x601 = (0x0 + 0x0); + uint32_t _5; uint8_t x604 = addcarryx_u32(0x0, x554, x581, &_5); + uint32_t x606; uint8_t x607 = addcarryx_u32(x604, x557, x593, &x606); + uint32_t x609; uint8_t x610 = addcarryx_u32(x607, x560, x596, &x609); + uint32_t x612; uint8_t x613 = addcarryx_u32(x610, x563, x599, &x612); + uint32_t x615; uint8_t x616 = addcarryx_u32(x613, x566, x600, &x615); + uint32_t x618; uint8_t x619 = addcarryx_u32(x616, x569, x601, &x618); + uint32_t x621; uint8_t x622 = addcarryx_u32(x619, x572, x554, &x621); + uint32_t x624; uint8_t x625 = addcarryx_u32(x622, x575, x590, &x624); + uint32_t x627; uint8_t x628 = addcarryx_u32(x625, x578, x591, &x627); + uint8_t x629 = (x628 + x579); + uint32_t x632; uint32_t x631 = mulx_u32(x15, x19, &x632); + uint32_t x635; uint32_t x634 = mulx_u32(x15, x21, &x635); + uint32_t x638; uint32_t x637 = mulx_u32(x15, x23, &x638); + uint32_t x641; uint32_t x640 = mulx_u32(x15, x25, &x641); + uint32_t x644; uint32_t x643 = mulx_u32(x15, x27, &x644); + uint32_t x647; uint32_t x646 = mulx_u32(x15, x29, &x647); + uint32_t x650; uint32_t x649 = mulx_u32(x15, x31, &x650); + uint32_t x653; uint32_t x652 = mulx_u32(x15, x30, &x653); + uint32_t x655; uint8_t x656 = addcarryx_u32(0x0, x632, x634, &x655); + uint32_t x658; uint8_t x659 = addcarryx_u32(x656, x635, x637, &x658); + uint32_t x661; uint8_t x662 = addcarryx_u32(x659, x638, x640, &x661); + uint32_t x664; uint8_t x665 = addcarryx_u32(x662, x641, x643, &x664); + uint32_t x667; uint8_t x668 = addcarryx_u32(x665, x644, x646, &x667); + uint32_t x670; uint8_t x671 = addcarryx_u32(x668, x647, x649, &x670); + uint32_t x673; uint8_t x674 = addcarryx_u32(x671, x650, x652, &x673); + uint32_t x676; addcarryx_u32(0x0, x674, x653, &x676); + uint32_t x679; uint8_t x680 = addcarryx_u32(0x0, x606, x631, &x679); + uint32_t x682; uint8_t x683 = addcarryx_u32(x680, x609, x655, &x682); + uint32_t x685; uint8_t x686 = addcarryx_u32(x683, x612, x658, &x685); + uint32_t x688; uint8_t x689 = addcarryx_u32(x686, x615, x661, &x688); + uint32_t x691; uint8_t x692 = addcarryx_u32(x689, x618, x664, &x691); + uint32_t x694; uint8_t x695 = addcarryx_u32(x692, x621, x667, &x694); + uint32_t x697; uint8_t x698 = addcarryx_u32(x695, x624, x670, &x697); + uint32_t x700; uint8_t x701 = addcarryx_u32(x698, x627, x673, &x700); + uint32_t x703; uint8_t x704 = addcarryx_u32(x701, x629, x676, &x703); + uint32_t x707; uint32_t x706 = mulx_u32(x679, 0xffffffff, &x707); + uint32_t x710; uint32_t x709 = mulx_u32(x679, 0xffffffff, &x710); + uint32_t x713; uint32_t x712 = mulx_u32(x679, 0xffffffff, &x713); + uint32_t x716; uint32_t x715 = mulx_u32(x679, 0xffffffff, &x716); + uint32_t x718; uint8_t x719 = addcarryx_u32(0x0, x707, x709, &x718); + uint32_t x721; uint8_t x722 = addcarryx_u32(x719, x710, x712, &x721); + uint32_t x724; uint8_t x725 = addcarryx_u32(x722, x713, 0x0, &x724); + uint8_t x726 = (0x0 + 0x0); + uint32_t _6; uint8_t x729 = addcarryx_u32(0x0, x679, x706, &_6); + uint32_t x731; uint8_t x732 = addcarryx_u32(x729, x682, x718, &x731); + uint32_t x734; uint8_t x735 = addcarryx_u32(x732, x685, x721, &x734); + uint32_t x737; uint8_t x738 = addcarryx_u32(x735, x688, x724, &x737); + uint32_t x740; uint8_t x741 = addcarryx_u32(x738, x691, x725, &x740); + uint32_t x743; uint8_t x744 = addcarryx_u32(x741, x694, x726, &x743); + uint32_t x746; uint8_t x747 = addcarryx_u32(x744, x697, x679, &x746); + uint32_t x749; uint8_t x750 = addcarryx_u32(x747, x700, x715, &x749); + uint32_t x752; uint8_t x753 = addcarryx_u32(x750, x703, x716, &x752); + uint8_t x754 = (x753 + x704); + uint32_t x757; uint32_t x756 = mulx_u32(x17, x19, &x757); + uint32_t x760; uint32_t x759 = mulx_u32(x17, x21, &x760); + uint32_t x763; uint32_t x762 = mulx_u32(x17, x23, &x763); + uint32_t x766; uint32_t x765 = mulx_u32(x17, x25, &x766); + uint32_t x769; uint32_t x768 = mulx_u32(x17, x27, &x769); + uint32_t x772; uint32_t x771 = mulx_u32(x17, x29, &x772); + uint32_t x775; uint32_t x774 = mulx_u32(x17, x31, &x775); + uint32_t x778; uint32_t x777 = mulx_u32(x17, x30, &x778); + uint32_t x780; uint8_t x781 = addcarryx_u32(0x0, x757, x759, &x780); + uint32_t x783; uint8_t x784 = addcarryx_u32(x781, x760, x762, &x783); + uint32_t x786; uint8_t x787 = addcarryx_u32(x784, x763, x765, &x786); + uint32_t x789; uint8_t x790 = addcarryx_u32(x787, x766, x768, &x789); + uint32_t x792; uint8_t x793 = addcarryx_u32(x790, x769, x771, &x792); + uint32_t x795; uint8_t x796 = addcarryx_u32(x793, x772, x774, &x795); + uint32_t x798; uint8_t x799 = addcarryx_u32(x796, x775, x777, &x798); + uint32_t x801; addcarryx_u32(0x0, x799, x778, &x801); + uint32_t x804; uint8_t x805 = addcarryx_u32(0x0, x731, x756, &x804); + uint32_t x807; uint8_t x808 = addcarryx_u32(x805, x734, x780, &x807); + uint32_t x810; uint8_t x811 = addcarryx_u32(x808, x737, x783, &x810); + uint32_t x813; uint8_t x814 = addcarryx_u32(x811, x740, x786, &x813); + uint32_t x816; uint8_t x817 = addcarryx_u32(x814, x743, x789, &x816); + uint32_t x819; uint8_t x820 = addcarryx_u32(x817, x746, x792, &x819); + uint32_t x822; uint8_t x823 = addcarryx_u32(x820, x749, x795, &x822); + uint32_t x825; uint8_t x826 = addcarryx_u32(x823, x752, x798, &x825); + uint32_t x828; uint8_t x829 = addcarryx_u32(x826, x754, x801, &x828); + uint32_t x832; uint32_t x831 = mulx_u32(x804, 0xffffffff, &x832); + uint32_t x835; uint32_t x834 = mulx_u32(x804, 0xffffffff, &x835); + uint32_t x838; uint32_t x837 = mulx_u32(x804, 0xffffffff, &x838); + uint32_t x841; uint32_t x840 = mulx_u32(x804, 0xffffffff, &x841); + uint32_t x843; uint8_t x844 = addcarryx_u32(0x0, x832, x834, &x843); + uint32_t x846; uint8_t x847 = addcarryx_u32(x844, x835, x837, &x846); + uint32_t x849; uint8_t x850 = addcarryx_u32(x847, x838, 0x0, &x849); + uint8_t x851 = (0x0 + 0x0); + uint32_t _7; uint8_t x854 = addcarryx_u32(0x0, x804, x831, &_7); + uint32_t x856; uint8_t x857 = addcarryx_u32(x854, x807, x843, &x856); + uint32_t x859; uint8_t x860 = addcarryx_u32(x857, x810, x846, &x859); + uint32_t x862; uint8_t x863 = addcarryx_u32(x860, x813, x849, &x862); + uint32_t x865; uint8_t x866 = addcarryx_u32(x863, x816, x850, &x865); + uint32_t x868; uint8_t x869 = addcarryx_u32(x866, x819, x851, &x868); + uint32_t x871; uint8_t x872 = addcarryx_u32(x869, x822, x804, &x871); + uint32_t x874; uint8_t x875 = addcarryx_u32(x872, x825, x840, &x874); + uint32_t x877; uint8_t x878 = addcarryx_u32(x875, x828, x841, &x877); + uint8_t x879 = (x878 + x829); + uint32_t x882; uint32_t x881 = mulx_u32(x16, x19, &x882); + uint32_t x885; uint32_t x884 = mulx_u32(x16, x21, &x885); + uint32_t x888; uint32_t x887 = mulx_u32(x16, x23, &x888); + uint32_t x891; uint32_t x890 = mulx_u32(x16, x25, &x891); + uint32_t x894; uint32_t x893 = mulx_u32(x16, x27, &x894); + uint32_t x897; uint32_t x896 = mulx_u32(x16, x29, &x897); + uint32_t x900; uint32_t x899 = mulx_u32(x16, x31, &x900); + uint32_t x903; uint32_t x902 = mulx_u32(x16, x30, &x903); + uint32_t x905; uint8_t x906 = addcarryx_u32(0x0, x882, x884, &x905); + uint32_t x908; uint8_t x909 = addcarryx_u32(x906, x885, x887, &x908); + uint32_t x911; uint8_t x912 = addcarryx_u32(x909, x888, x890, &x911); + uint32_t x914; uint8_t x915 = addcarryx_u32(x912, x891, x893, &x914); + uint32_t x917; uint8_t x918 = addcarryx_u32(x915, x894, x896, &x917); + uint32_t x920; uint8_t x921 = addcarryx_u32(x918, x897, x899, &x920); + uint32_t x923; uint8_t x924 = addcarryx_u32(x921, x900, x902, &x923); + uint32_t x926; addcarryx_u32(0x0, x924, x903, &x926); + uint32_t x929; uint8_t x930 = addcarryx_u32(0x0, x856, x881, &x929); + uint32_t x932; uint8_t x933 = addcarryx_u32(x930, x859, x905, &x932); + uint32_t x935; uint8_t x936 = addcarryx_u32(x933, x862, x908, &x935); + uint32_t x938; uint8_t x939 = addcarryx_u32(x936, x865, x911, &x938); + uint32_t x941; uint8_t x942 = addcarryx_u32(x939, x868, x914, &x941); + uint32_t x944; uint8_t x945 = addcarryx_u32(x942, x871, x917, &x944); + uint32_t x947; uint8_t x948 = addcarryx_u32(x945, x874, x920, &x947); + uint32_t x950; uint8_t x951 = addcarryx_u32(x948, x877, x923, &x950); + uint32_t x953; uint8_t x954 = addcarryx_u32(x951, x879, x926, &x953); + uint32_t x957; uint32_t x956 = mulx_u32(x929, 0xffffffff, &x957); + uint32_t x960; uint32_t x959 = mulx_u32(x929, 0xffffffff, &x960); + uint32_t x963; uint32_t x962 = mulx_u32(x929, 0xffffffff, &x963); + uint32_t x966; uint32_t x965 = mulx_u32(x929, 0xffffffff, &x966); + uint32_t x968; uint8_t x969 = addcarryx_u32(0x0, x957, x959, &x968); + uint32_t x971; uint8_t x972 = addcarryx_u32(x969, x960, x962, &x971); + uint32_t x974; uint8_t x975 = addcarryx_u32(x972, x963, 0x0, &x974); + uint8_t x976 = (0x0 + 0x0); + uint32_t _8; uint8_t x979 = addcarryx_u32(0x0, x929, x956, &_8); + uint32_t x981; uint8_t x982 = addcarryx_u32(x979, x932, x968, &x981); + uint32_t x984; uint8_t x985 = addcarryx_u32(x982, x935, x971, &x984); + uint32_t x987; uint8_t x988 = addcarryx_u32(x985, x938, x974, &x987); + uint32_t x990; uint8_t x991 = addcarryx_u32(x988, x941, x975, &x990); + uint32_t x993; uint8_t x994 = addcarryx_u32(x991, x944, x976, &x993); + uint32_t x996; uint8_t x997 = addcarryx_u32(x994, x947, x929, &x996); + uint32_t x999; uint8_t x1000 = addcarryx_u32(x997, x950, x965, &x999); + uint32_t x1002; uint8_t x1003 = addcarryx_u32(x1000, x953, x966, &x1002); + uint8_t x1004 = (x1003 + x954); + uint32_t x1006; uint8_t x1007 = subborrow_u32(0x0, x981, 0xffffffff, &x1006); + uint32_t x1009; uint8_t x1010 = subborrow_u32(x1007, x984, 0xffffffff, &x1009); + uint32_t x1012; uint8_t x1013 = subborrow_u32(x1010, x987, 0xffffffff, &x1012); + uint32_t x1015; uint8_t x1016 = subborrow_u32(x1013, x990, 0x0, &x1015); + uint32_t x1018; uint8_t x1019 = subborrow_u32(x1016, x993, 0x0, &x1018); + uint32_t x1021; uint8_t x1022 = subborrow_u32(x1019, x996, 0x0, &x1021); + uint32_t x1024; uint8_t x1025 = subborrow_u32(x1022, x999, 0x1, &x1024); + uint32_t x1027; uint8_t x1028 = subborrow_u32(x1025, x1002, 0xffffffff, &x1027); + uint32_t _9; uint8_t x1031 = subborrow_u32(x1028, x1004, 0x0, &_9); + uint32_t x1032 = cmovznz_u32(x1031, x1027, x1002); + uint32_t x1033 = cmovznz_u32(x1031, x1024, x999); + uint32_t x1034 = cmovznz_u32(x1031, x1021, x996); + uint32_t x1035 = cmovznz_u32(x1031, x1018, x993); + uint32_t x1036 = cmovznz_u32(x1031, x1015, x990); + uint32_t x1037 = cmovznz_u32(x1031, x1012, x987); + uint32_t x1038 = cmovznz_u32(x1031, x1009, x984); + uint32_t x1039 = cmovznz_u32(x1031, x1006, x981); + out[0] = x1039; + out[1] = x1038; + out[2] = x1037; + out[3] = x1036; + out[4] = x1035; + out[5] = x1034; + out[6] = x1033; + out[7] = x1032; +} + +// NOTE: the following functions are generated from fiat-crypto, from the same +// template as their 64-bit counterparts above, but the correctness proof of +// the template was not composed with the correctness proof of the +// specialization pipeline. This is because Coq unexplainedly loops on trying +// to synthesize opp and sub using the normal pipeline. + +static void fe_sub(uint32_t out[8], const uint32_t in1[8], const uint32_t in2[8]) { + const uint32_t x14 = in1[7]; + const uint32_t x15 = in1[6]; + const uint32_t x13 = in1[5]; + const uint32_t x11 = in1[4]; + const uint32_t x9 = in1[3]; + const uint32_t x7 = in1[2]; + const uint32_t x5 = in1[1]; + const uint32_t x3 = in1[0]; + const uint32_t x28 = in2[7]; + const uint32_t x29 = in2[6]; + const uint32_t x27 = in2[5]; + const uint32_t x25 = in2[4]; + const uint32_t x23 = in2[3]; + const uint32_t x21 = in2[2]; + const uint32_t x19 = in2[1]; + const uint32_t x17 = in2[0]; + uint32_t x31; uint8_t x32 = subborrow_u32(0x0, x3, x17, &x31); + uint32_t x34; uint8_t x35 = subborrow_u32(x32, x5, x19, &x34); + uint32_t x37; uint8_t x38 = subborrow_u32(x35, x7, x21, &x37); + uint32_t x40; uint8_t x41 = subborrow_u32(x38, x9, x23, &x40); + uint32_t x43; uint8_t x44 = subborrow_u32(x41, x11, x25, &x43); + uint32_t x46; uint8_t x47 = subborrow_u32(x44, x13, x27, &x46); + uint32_t x49; uint8_t x50 = subborrow_u32(x47, x15, x29, &x49); + uint32_t x52; uint8_t x53 = subborrow_u32(x50, x14, x28, &x52); + uint32_t x54 = cmovznz_u32(x53, 0x0, 0xffffffff); + uint32_t x56; uint8_t x57 = addcarryx_u32(0x0, x31, (x54 & 0xffffffff), &x56); + uint32_t x59; uint8_t x60 = addcarryx_u32(x57, x34, (x54 & 0xffffffff), &x59); + uint32_t x62; uint8_t x63 = addcarryx_u32(x60, x37, (x54 & 0xffffffff), &x62); + uint32_t x65; uint8_t x66 = addcarryx_u32(x63, x40, 0x0, &x65); + uint32_t x68; uint8_t x69 = addcarryx_u32(x66, x43, 0x0, &x68); + uint32_t x71; uint8_t x72 = addcarryx_u32(x69, x46, 0x0, &x71); + uint32_t x74; uint8_t x75 = addcarryx_u32(x72, x49, ((uint8_t)x54 & 0x1), &x74); + uint32_t x77; addcarryx_u32(x75, x52, (x54 & 0xffffffff), &x77); + out[0] = x56; + out[1] = x59; + out[2] = x62; + out[3] = x65; + out[4] = x68; + out[5] = x71; + out[6] = x74; + out[7] = x77; +} + +// fe_op sets out = -in +static void fe_opp(uint32_t out[8], const uint32_t in1[8]) { + const uint32_t x12 = in1[7]; + const uint32_t x13 = in1[6]; + const uint32_t x11 = in1[5]; + const uint32_t x9 = in1[4]; + const uint32_t x7 = in1[3]; + const uint32_t x5 = in1[2]; + const uint32_t x3 = in1[1]; + const uint32_t x1 = in1[0]; + uint32_t x15; uint8_t x16 = subborrow_u32(0x0, 0x0, x1, &x15); + uint32_t x18; uint8_t x19 = subborrow_u32(x16, 0x0, x3, &x18); + uint32_t x21; uint8_t x22 = subborrow_u32(x19, 0x0, x5, &x21); + uint32_t x24; uint8_t x25 = subborrow_u32(x22, 0x0, x7, &x24); + uint32_t x27; uint8_t x28 = subborrow_u32(x25, 0x0, x9, &x27); + uint32_t x30; uint8_t x31 = subborrow_u32(x28, 0x0, x11, &x30); + uint32_t x33; uint8_t x34 = subborrow_u32(x31, 0x0, x13, &x33); + uint32_t x36; uint8_t x37 = subborrow_u32(x34, 0x0, x12, &x36); + uint32_t x38 = cmovznz_u32(x37, 0x0, 0xffffffff); + uint32_t x40; uint8_t x41 = addcarryx_u32(0x0, x15, (x38 & 0xffffffff), &x40); + uint32_t x43; uint8_t x44 = addcarryx_u32(x41, x18, (x38 & 0xffffffff), &x43); + uint32_t x46; uint8_t x47 = addcarryx_u32(x44, x21, (x38 & 0xffffffff), &x46); + uint32_t x49; uint8_t x50 = addcarryx_u32(x47, x24, 0x0, &x49); + uint32_t x52; uint8_t x53 = addcarryx_u32(x50, x27, 0x0, &x52); + uint32_t x55; uint8_t x56 = addcarryx_u32(x53, x30, 0x0, &x55); + uint32_t x58; uint8_t x59 = addcarryx_u32(x56, x33, ((uint8_t)x38 & 0x1), &x58); + uint32_t x61; addcarryx_u32(x59, x36, (x38 & 0xffffffff), &x61); + out[0] = x40; + out[1] = x43; + out[2] = x46; + out[3] = x49; + out[4] = x52; + out[5] = x55; + out[6] = x58; + out[7] = x61; +} + +#endif + +// utility functions, handwritten + +#define NBYTES 32 + +#if defined(BORINGSSL_NISTP256_64BIT) + +#define NLIMBS 4 +typedef uint64_t limb_t; +#define cmovznz_limb cmovznz_u64 +typedef uint64_t fe[NLIMBS]; +#else // 64BIT; else 32BIT + +#define NLIMBS 8 +typedef uint32_t limb_t; +#define cmovznz_limb cmovznz_u32 +typedef uint32_t fe[NLIMBS]; + +#endif // 64BIT + +static limb_t fe_nz(const limb_t in1[NLIMBS]) { + limb_t ret = 0; + for (int i = 0; i < NLIMBS; i++) { + ret |= in1[i]; + } + return ret; +} + +static void fe_copy(limb_t out[NLIMBS], const limb_t in1[NLIMBS]) { + for (int i = 0; i < NLIMBS; i++) { + out[i] = in1[i]; + } +} + +static void fe_cmovznz(limb_t out[NLIMBS], limb_t t, const limb_t z[NLIMBS], + const limb_t nz[NLIMBS]) { + for (int i = 0; i < NLIMBS; i++) { + out[i] = cmovznz_limb(t, z[i], nz[i]); + } +} + +static void fe_sqr(fe out, const fe in) { + fe_mul(out, in, in); +} + +static void fe_tobytes(uint8_t out[NBYTES], const fe in) { + for (int i = 0; i> (8*(i%sizeof(in[0])))); + } +} + +static void fe_frombytes(fe out, const uint8_t in[NBYTES]) { + for (int i = 0; i +// As a sanity check, a proof that these points form a commutative group: +// + +// 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 +// +// Coq transcription and correctness proof: +// +// +// +// 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(fe x_out, fe y_out, fe z_out, + const fe x_in, const fe y_in, const fe z_in) { + fe delta, gamma, beta, ftmp, ftmp2, tmptmp, alpha, fourbeta; + // delta = z^2 + fe_sqr(delta, z_in); + // gamma = y^2 + fe_sqr(gamma, y_in); + // beta = x*gamma + fe_mul(beta, x_in, gamma); + + // alpha = 3*(x-delta)*(x+delta) + fe_sub(ftmp, x_in, delta); + fe_add(ftmp2, x_in, delta); + + fe_add(tmptmp, ftmp2, ftmp2); + fe_add(ftmp2, ftmp2, tmptmp); + fe_mul(alpha, ftmp, ftmp2); + + // x' = alpha^2 - 8*beta + fe_sqr(x_out, alpha); + fe_add(fourbeta, beta, beta); + fe_add(fourbeta, fourbeta, fourbeta); + fe_add(tmptmp, fourbeta, fourbeta); + fe_sub(x_out, x_out, tmptmp); + + // z' = (y + z)^2 - gamma - delta + fe_add(delta, gamma, delta); + fe_add(ftmp, y_in, z_in); + fe_sqr(z_out, ftmp); + fe_sub(z_out, z_out, delta); + + // y' = alpha*(4*beta - x') - 8*gamma^2 + fe_sub(y_out, fourbeta, x_out); + fe_add(gamma, gamma, gamma); + fe_sqr(gamma, gamma); + fe_mul(y_out, alpha, y_out); + fe_add(gamma, gamma, gamma); + fe_sub(y_out, y_out, gamma); +} + +// 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). +// +// Coq transcription and correctness proof: +// +// +// +// 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(fe x3, fe y3, fe z3, const fe x1, + const fe y1, const fe z1, const int mixed, + const fe x2, const fe y2, const fe z2) { + fe x_out, y_out, z_out; + limb_t z1nz = fe_nz(z1); + limb_t z2nz = fe_nz(z2); + + // z1z1 = z1z1 = z1**2 + fe z1z1; fe_sqr(z1z1, z1); + + fe u1, s1, two_z1z2; + if (!mixed) { + // z2z2 = z2**2 + fe z2z2; fe_sqr(z2z2, z2); + + // u1 = x1*z2z2 + fe_mul(u1, x1, z2z2); + + // two_z1z2 = (z1 + z2)**2 - (z1z1 + z2z2) = 2z1z2 + fe_add(two_z1z2, z1, z2); + fe_sqr(two_z1z2, two_z1z2); + fe_sub(two_z1z2, two_z1z2, z1z1); + fe_sub(two_z1z2, two_z1z2, z2z2); + + // s1 = y1 * z2**3 + fe_mul(s1, z2, z2z2); + fe_mul(s1, s1, y1); + } else { + // We'll assume z2 = 1 (special case z2 = 0 is handled later). + + // u1 = x1*z2z2 + fe_copy(u1, x1); + // two_z1z2 = 2z1z2 + fe_add(two_z1z2, z1, z1); + // s1 = y1 * z2**3 + fe_copy(s1, y1); + } + + // u2 = x2*z1z1 + fe u2; fe_mul(u2, x2, z1z1); + + // h = u2 - u1 + fe h; fe_sub(h, u2, u1); + + limb_t xneq = fe_nz(h); + + // z_out = two_z1z2 * h + fe_mul(z_out, h, two_z1z2); + + // z1z1z1 = z1 * z1z1 + fe z1z1z1; fe_mul(z1z1z1, z1, z1z1); + + // s2 = y2 * z1**3 + fe s2; fe_mul(s2, y2, z1z1z1); + + // r = (s2 - s1)*2 + fe r; + fe_sub(r, s2, s1); + fe_add(r, r, r); + + limb_t yneq = fe_nz(r); + + if (!xneq && !yneq && z1nz && z2nz) { + point_double(x3, y3, z3, x1, y1, z1); + return; + } + + // I = (2h)**2 + fe i; + fe_add(i, h, h); + fe_sqr(i, i); + + // J = h * I + fe j; fe_mul(j, h, i); + + // V = U1 * I + fe v; fe_mul(v, u1, i); + + // x_out = r**2 - J - 2V + fe_sqr(x_out, r); + fe_sub(x_out, x_out, j); + fe_sub(x_out, x_out, v); + fe_sub(x_out, x_out, v); + + // y_out = r(V-x_out) - 2 * s1 * J + fe_sub(y_out, v, x_out); + fe_mul(y_out, y_out, r); + fe s1j; + fe_mul(s1j, s1, j); + fe_sub(y_out, y_out, s1j); + fe_sub(y_out, y_out, s1j); + + fe_cmovznz(x_out, z1nz, x2, x_out); + fe_cmovznz(x3, z2nz, x1, x_out); + fe_cmovznz(y_out, z1nz, y2, y_out); + fe_cmovznz(y3, z2nz, y1, y_out); + fe_cmovznz(z_out, z1nz, z2, z_out); + fe_cmovznz(z3, z2nz, z1, 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 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. + +// g_pre_comp is the table of precomputed base points +#if defined(BORINGSSL_NISTP256_64BIT) +static const fe g_pre_comp[2][16][3] = { + {{{0x0, 0x0, 0x0, 0x0}, {0x0, 0x0, 0x0, 0x0}, {0x0, 0x0, 0x0, 0x0}}, + {{0x79e730d418a9143c, 0x75ba95fc5fedb601, 0x79fb732b77622510, + 0x18905f76a53755c6}, + {0xddf25357ce95560a, 0x8b4ab8e4ba19e45c, 0xd2e88688dd21f325, + 0x8571ff1825885d85}, + {0x1, 0xffffffff00000000, 0xffffffffffffffff, 0xfffffffe}}, + {{0x4f922fc516a0d2bb, 0xd5cc16c1a623499, 0x9241cf3a57c62c8b, + 0x2f5e6961fd1b667f}, + {0x5c15c70bf5a01797, 0x3d20b44d60956192, 0x4911b37071fdb52, + 0xf648f9168d6f0f7b}, + {0x1, 0xffffffff00000000, 0xffffffffffffffff, 0xfffffffe}}, + {{0x9e566847e137bbbc, 0xe434469e8a6a0bec, 0xb1c4276179d73463, + 0x5abe0285133d0015}, + {0x92aa837cc04c7dab, 0x573d9f4c43260c07, 0xc93156278e6cc37, + 0x94bb725b6b6f7383}, + {0x1, 0xffffffff00000000, 0xffffffffffffffff, 0xfffffffe}}, + {{0x62a8c244bfe20925, 0x91c19ac38fdce867, 0x5a96a5d5dd387063, + 0x61d587d421d324f6}, + {0xe87673a2a37173ea, 0x2384800853778b65, 0x10f8441e05bab43e, + 0xfa11fe124621efbe}, + {0x1, 0xffffffff00000000, 0xffffffffffffffff, 0xfffffffe}}, + {{0x1c891f2b2cb19ffd, 0x1ba8d5bb1923c23, 0xb6d03d678ac5ca8e, + 0x586eb04c1f13bedc}, + {0xc35c6e527e8ed09, 0x1e81a33c1819ede2, 0x278fd6c056c652fa, + 0x19d5ac0870864f11}, + {0x1, 0xffffffff00000000, 0xffffffffffffffff, 0xfffffffe}}, + {{0x62577734d2b533d5, 0x673b8af6a1bdddc0, 0x577e7c9aa79ec293, + 0xbb6de651c3b266b1}, + {0xe7e9303ab65259b3, 0xd6a0afd3d03a7480, 0xc5ac83d19b3cfc27, + 0x60b4619a5d18b99b}, + {0x1, 0xffffffff00000000, 0xffffffffffffffff, 0xfffffffe}}, + {{0xbd6a38e11ae5aa1c, 0xb8b7652b49e73658, 0xb130014ee5f87ed, + 0x9d0f27b2aeebffcd}, + {0xca9246317a730a55, 0x9c955b2fddbbc83a, 0x7c1dfe0ac019a71, + 0x244a566d356ec48d}, + {0x1, 0xffffffff00000000, 0xffffffffffffffff, 0xfffffffe}}, + {{0x56f8410ef4f8b16a, 0x97241afec47b266a, 0xa406b8e6d9c87c1, + 0x803f3e02cd42ab1b}, + {0x7f0309a804dbec69, 0xa83b85f73bbad05f, 0xc6097273ad8e197f, + 0xc097440e5067adc1}, + {0x1, 0xffffffff00000000, 0xffffffffffffffff, 0xfffffffe}}, + {{0x846a56f2c379ab34, 0xa8ee068b841df8d1, 0x20314459176c68ef, + 0xf1af32d5915f1f30}, + {0x99c375315d75bd50, 0x837cffbaf72f67bc, 0x613a41848d7723f, + 0x23d0f130e2d41c8b}, + {0x1, 0xffffffff00000000, 0xffffffffffffffff, 0xfffffffe}}, + {{0xed93e225d5be5a2b, 0x6fe799835934f3c6, 0x4314092622626ffc, + 0x50bbb4d97990216a}, + {0x378191c6e57ec63e, 0x65422c40181dcdb2, 0x41a8099b0236e0f6, + 0x2b10011801fe49c3}, + {0x1, 0xffffffff00000000, 0xffffffffffffffff, 0xfffffffe}}, + {{0xfc68b5c59b391593, 0xc385f5a2598270fc, 0x7144f3aad19adcbb, + 0xdd55899983fbae0c}, + {0x93b88b8e74b82ff4, 0xd2e03c4071e734c9, 0x9a7a9eaf43c0322a, + 0xe6e4c551149d6041}, + {0x1, 0xffffffff00000000, 0xffffffffffffffff, 0xfffffffe}}, + {{0x5fe14bfe80ec21fe, 0xf6ce116ac255be82, 0x98bc5a072f4a5d67, + 0xfad27148db7e63af}, + {0x90c0b6ac29ab05b3, 0x37a9a83c4e251ae6, 0xa7dc875c2aade7d, + 0x77387de39f0e1a84}, + {0x1, 0xffffffff00000000, 0xffffffffffffffff, 0xfffffffe}}, + {{0x1e9ecc49a56c0dd7, 0xa5cffcd846086c74, 0x8f7a1408f505aece, + 0xb37b85c0bef0c47e}, + {0x3596b6e4cc0e6a8f, 0xfd6d4bbf6b388f23, 0xaba453fac39cef4e, + 0x9c135ac8f9f628d5}, + {0x1, 0xffffffff00000000, 0xffffffffffffffff, 0xfffffffe}}, + {{0xa1c729495c8f8be, 0x2961c4803bf362bf, 0x9e418403df63d4ac, + 0xc109f9cb91ece900}, + {0xc2d095d058945705, 0xb9083d96ddeb85c0, 0x84692b8d7a40449b, + 0x9bc3344f2eee1ee1}, + {0x1, 0xffffffff00000000, 0xffffffffffffffff, 0xfffffffe}}, + {{0xd5ae35642913074, 0x55491b2748a542b1, 0x469ca665b310732a, + 0x29591d525f1a4cc1}, + {0xe76f5b6bb84f983f, 0xbe7eef419f5f84e1, 0x1200d49680baa189, + 0x6376551f18ef332c}, + {0x1, 0xffffffff00000000, 0xffffffffffffffff, 0xfffffffe}}}, + {{{0x0, 0x0, 0x0, 0x0}, {0x0, 0x0, 0x0, 0x0}, {0x0, 0x0, 0x0, 0x0}}, + {{0x202886024147519a, 0xd0981eac26b372f0, 0xa9d4a7caa785ebc8, + 0xd953c50ddbdf58e9}, + {0x9d6361ccfd590f8f, 0x72e9626b44e6c917, 0x7fd9611022eb64cf, + 0x863ebb7e9eb288f3}, + {0x1, 0xffffffff00000000, 0xffffffffffffffff, 0xfffffffe}}, + {{0x4fe7ee31b0e63d34, 0xf4600572a9e54fab, 0xc0493334d5e7b5a4, + 0x8589fb9206d54831}, + {0xaa70f5cc6583553a, 0x879094ae25649e5, 0xcc90450710044652, + 0xebb0696d02541c4f}, + {0x1, 0xffffffff00000000, 0xffffffffffffffff, 0xfffffffe}}, + {{0xabbaa0c03b89da99, 0xa6f2d79eb8284022, 0x27847862b81c05e8, + 0x337a4b5905e54d63}, + {0x3c67500d21f7794a, 0x207005b77d6d7f61, 0xa5a378104cfd6e8, + 0xd65e0d5f4c2fbd6}, + {0x1, 0xffffffff00000000, 0xffffffffffffffff, 0xfffffffe}}, + {{0xd433e50f6d3549cf, 0x6f33696ffacd665e, 0x695bfdacce11fcb4, + 0x810ee252af7c9860}, + {0x65450fe17159bb2c, 0xf7dfbebe758b357b, 0x2b057e74d69fea72, + 0xd485717a92731745}, + {0x1, 0xffffffff00000000, 0xffffffffffffffff, 0xfffffffe}}, + {{0xce1f69bbe83f7669, 0x9f8ae8272877d6b, 0x9548ae543244278d, + 0x207755dee3c2c19c}, + {0x87bd61d96fef1945, 0x18813cefb12d28c3, 0x9fbcd1d672df64aa, + 0x48dc5ee57154b00d}, + {0x1, 0xffffffff00000000, 0xffffffffffffffff, 0xfffffffe}}, + {{0xef0f469ef49a3154, 0x3e85a5956e2b2e9a, 0x45aaec1eaa924a9c, + 0xaa12dfc8a09e4719}, + {0x26f272274df69f1d, 0xe0e4c82ca2ff5e73, 0xb9d8ce73b7a9dd44, + 0x6c036e73e48ca901}, + {0x1, 0xffffffff00000000, 0xffffffffffffffff, 0xfffffffe}}, + {{0xe1e421e1a47153f0, 0xb86c3b79920418c9, 0x93bdce87705d7672, + 0xf25ae793cab79a77}, + {0x1f3194a36d869d0c, 0x9d55c8824986c264, 0x49fb5ea3096e945e, + 0x39b8e65313db0a3e}, + {0x1, 0xffffffff00000000, 0xffffffffffffffff, 0xfffffffe}}, + {{0xe3417bc035d0b34a, 0x440b386b8327c0a7, 0x8fb7262dac0362d1, + 0x2c41114ce0cdf943}, + {0x2ba5cef1ad95a0b1, 0xc09b37a867d54362, 0x26d6cdd201e486c9, + 0x20477abf42ff9297}, + {0x1, 0xffffffff00000000, 0xffffffffffffffff, 0xfffffffe}}, + {{0xf121b41bc0a67d2, 0x62d4760a444d248a, 0xe044f1d659b4737, + 0x8fde365250bb4a8}, + {0xaceec3da848bf287, 0xc2a62182d3369d6e, 0x3582dfdc92449482, + 0x2f7e2fd2565d6cd7}, + {0x1, 0xffffffff00000000, 0xffffffffffffffff, 0xfffffffe}}, + {{0xa0122b5178a876b, 0x51ff96ff085104b4, 0x50b31ab14f29f76, + 0x84abb28b5f87d4e6}, + {0xd5ed439f8270790a, 0x2d6cb59d85e3f46b, 0x75f55c1b6c1e2212, + 0xe5436f6717655640}, + {0x1, 0xffffffff00000000, 0xffffffffffffffff, 0xfffffffe}}, + {{0xc2965ecc9aeb596d, 0x1ea03e7023c92b4, 0x4704b4b62e013961, + 0xca8fd3f905ea367}, + {0x92523a42551b2b61, 0x1eb7a89c390fcd06, 0xe7f1d2be0392a63e, + 0x96dca2644ddb0c33}, + {0x1, 0xffffffff00000000, 0xffffffffffffffff, 0xfffffffe}}, + {{0x231c210e15339848, 0xe87a28e870778c8d, 0x9d1de6616956e170, + 0x4ac3c9382bb09c0b}, + {0x19be05516998987d, 0x8b2376c4ae09f4d6, 0x1de0b7651a3f933d, + 0x380d94c7e39705f4}, + {0x1, 0xffffffff00000000, 0xffffffffffffffff, 0xfffffffe}}, + {{0x3685954b8c31c31d, 0x68533d005bf21a0c, 0xbd7626e75c79ec9, + 0xca17754742c69d54}, + {0xcc6edafff6d2dbb2, 0xfd0d8cbd174a9d18, 0x875e8793aa4578e8, + 0xa976a7139cab2ce6}, + {0x1, 0xffffffff00000000, 0xffffffffffffffff, 0xfffffffe}}, + {{0xce37ab11b43ea1db, 0xa7ff1a95259d292, 0x851b02218f84f186, + 0xa7222beadefaad13}, + {0xa2ac78ec2b0a9144, 0x5a024051f2fa59c5, 0x91d1eca56147ce38, + 0xbe94d523bc2ac690}, + {0x1, 0xffffffff00000000, 0xffffffffffffffff, 0xfffffffe}}, + {{0x2d8daefd79ec1a0f, 0x3bbcd6fdceb39c97, 0xf5575ffc58f61a95, + 0xdbd986c4adf7b420}, + {0x81aa881415f39eb7, 0x6ee2fcf5b98d976c, 0x5465475dcf2f717d, + 0x8e24d3c46860bbd0}, + {0x1, 0xffffffff00000000, 0xffffffffffffffff, 0xfffffffe}}}}; +#else +static const fe g_pre_comp[2][16][3] = { + {{{0x0,0x0, 0x0,0x0, 0x0,0x0, 0x0,0x0}, + {0x0,0x0, 0x0,0x0, 0x0,0x0, 0x0,0x0}, + {0x0,0x0, 0x0,0x0, 0x0,0x0, 0x0,0x0}}, + {{0x18a9143c,0x79e730d4, 0x5fedb601,0x75ba95fc, 0x77622510,0x79fb732b, + 0xa53755c6,0x18905f76}, + {0xce95560a,0xddf25357, 0xba19e45c,0x8b4ab8e4, 0xdd21f325,0xd2e88688, + 0x25885d85,0x8571ff18}, + {0x1,0x0, 0x0,0xffffffff, 0xffffffff,0xffffffff, 0xfffffffe,0x0}}, + {{0x16a0d2bb,0x4f922fc5, 0x1a623499,0xd5cc16c, 0x57c62c8b,0x9241cf3a, + 0xfd1b667f,0x2f5e6961}, + {0xf5a01797,0x5c15c70b, 0x60956192,0x3d20b44d, 0x71fdb52,0x4911b37, + 0x8d6f0f7b,0xf648f916}, + {0x1,0x0, 0x0,0xffffffff, 0xffffffff,0xffffffff, 0xfffffffe,0x0}}, + {{0xe137bbbc,0x9e566847, 0x8a6a0bec,0xe434469e, 0x79d73463,0xb1c42761, + 0x133d0015,0x5abe0285}, + {0xc04c7dab,0x92aa837c, 0x43260c07,0x573d9f4c, 0x78e6cc37,0xc931562, + 0x6b6f7383,0x94bb725b}, + {0x1,0x0, 0x0,0xffffffff, 0xffffffff,0xffffffff, 0xfffffffe,0x0}}, + {{0xbfe20925,0x62a8c244, 0x8fdce867,0x91c19ac3, 0xdd387063,0x5a96a5d5, + 0x21d324f6,0x61d587d4}, + {0xa37173ea,0xe87673a2, 0x53778b65,0x23848008, 0x5bab43e,0x10f8441e, + 0x4621efbe,0xfa11fe12}, + {0x1,0x0, 0x0,0xffffffff, 0xffffffff,0xffffffff, 0xfffffffe,0x0}}, + {{0x2cb19ffd,0x1c891f2b, 0xb1923c23,0x1ba8d5b, 0x8ac5ca8e,0xb6d03d67, + 0x1f13bedc,0x586eb04c}, + {0x27e8ed09,0xc35c6e5, 0x1819ede2,0x1e81a33c, 0x56c652fa,0x278fd6c0, + 0x70864f11,0x19d5ac08}, + {0x1,0x0, 0x0,0xffffffff, 0xffffffff,0xffffffff, 0xfffffffe,0x0}}, + {{0xd2b533d5,0x62577734, 0xa1bdddc0,0x673b8af6, 0xa79ec293,0x577e7c9a, + 0xc3b266b1,0xbb6de651}, + {0xb65259b3,0xe7e9303a, 0xd03a7480,0xd6a0afd3, 0x9b3cfc27,0xc5ac83d1, + 0x5d18b99b,0x60b4619a}, + {0x1,0x0, 0x0,0xffffffff, 0xffffffff,0xffffffff, 0xfffffffe,0x0}}, + {{0x1ae5aa1c,0xbd6a38e1, 0x49e73658,0xb8b7652b, 0xee5f87ed,0xb130014, + 0xaeebffcd,0x9d0f27b2}, + {0x7a730a55,0xca924631, 0xddbbc83a,0x9c955b2f, 0xac019a71,0x7c1dfe0, + 0x356ec48d,0x244a566d}, + {0x1,0x0, 0x0,0xffffffff, 0xffffffff,0xffffffff, 0xfffffffe,0x0}}, + {{0xf4f8b16a,0x56f8410e, 0xc47b266a,0x97241afe, 0x6d9c87c1,0xa406b8e, + 0xcd42ab1b,0x803f3e02}, + {0x4dbec69,0x7f0309a8, 0x3bbad05f,0xa83b85f7, 0xad8e197f,0xc6097273, + 0x5067adc1,0xc097440e}, + {0x1,0x0, 0x0,0xffffffff, 0xffffffff,0xffffffff, 0xfffffffe,0x0}}, + {{0xc379ab34,0x846a56f2, 0x841df8d1,0xa8ee068b, 0x176c68ef,0x20314459, + 0x915f1f30,0xf1af32d5}, + {0x5d75bd50,0x99c37531, 0xf72f67bc,0x837cffba, 0x48d7723f,0x613a418, + 0xe2d41c8b,0x23d0f130}, + {0x1,0x0, 0x0,0xffffffff, 0xffffffff,0xffffffff, 0xfffffffe,0x0}}, + {{0xd5be5a2b,0xed93e225, 0x5934f3c6,0x6fe79983, 0x22626ffc,0x43140926, + 0x7990216a,0x50bbb4d9}, + {0xe57ec63e,0x378191c6, 0x181dcdb2,0x65422c40, 0x236e0f6,0x41a8099b, + 0x1fe49c3,0x2b100118}, + {0x1,0x0, 0x0,0xffffffff, 0xffffffff,0xffffffff, 0xfffffffe,0x0}}, + {{0x9b391593,0xfc68b5c5, 0x598270fc,0xc385f5a2, 0xd19adcbb,0x7144f3aa, + 0x83fbae0c,0xdd558999}, + {0x74b82ff4,0x93b88b8e, 0x71e734c9,0xd2e03c40, 0x43c0322a,0x9a7a9eaf, + 0x149d6041,0xe6e4c551}, + {0x1,0x0, 0x0,0xffffffff, 0xffffffff,0xffffffff, 0xfffffffe,0x0}}, + {{0x80ec21fe,0x5fe14bfe, 0xc255be82,0xf6ce116a, 0x2f4a5d67,0x98bc5a07, + 0xdb7e63af,0xfad27148}, + {0x29ab05b3,0x90c0b6ac, 0x4e251ae6,0x37a9a83c, 0xc2aade7d,0xa7dc875, + 0x9f0e1a84,0x77387de3}, + {0x1,0x0, 0x0,0xffffffff, 0xffffffff,0xffffffff, 0xfffffffe,0x0}}, + {{0xa56c0dd7,0x1e9ecc49, 0x46086c74,0xa5cffcd8, 0xf505aece,0x8f7a1408, + 0xbef0c47e,0xb37b85c0}, + {0xcc0e6a8f,0x3596b6e4, 0x6b388f23,0xfd6d4bbf, 0xc39cef4e,0xaba453fa, + 0xf9f628d5,0x9c135ac8}, + {0x1,0x0, 0x0,0xffffffff, 0xffffffff,0xffffffff, 0xfffffffe,0x0}}, + {{0x95c8f8be,0xa1c7294, 0x3bf362bf,0x2961c480, 0xdf63d4ac,0x9e418403, + 0x91ece900,0xc109f9cb}, + {0x58945705,0xc2d095d0, 0xddeb85c0,0xb9083d96, 0x7a40449b,0x84692b8d, + 0x2eee1ee1,0x9bc3344f}, + {0x1,0x0, 0x0,0xffffffff, 0xffffffff,0xffffffff, 0xfffffffe,0x0}}, + {{0x42913074,0xd5ae356, 0x48a542b1,0x55491b27, 0xb310732a,0x469ca665, + 0x5f1a4cc1,0x29591d52}, + {0xb84f983f,0xe76f5b6b, 0x9f5f84e1,0xbe7eef41, 0x80baa189,0x1200d496, + 0x18ef332c,0x6376551f}, + {0x1,0x0, 0x0,0xffffffff, 0xffffffff,0xffffffff, 0xfffffffe,0x0}}}, + {{{0x0,0x0, 0x0,0x0, 0x0,0x0, 0x0,0x0}, + {0x0,0x0, 0x0,0x0, 0x0,0x0, 0x0,0x0}, + {0x0,0x0, 0x0,0x0, 0x0,0x0, 0x0,0x0}}, + {{0x4147519a,0x20288602, 0x26b372f0,0xd0981eac, 0xa785ebc8,0xa9d4a7ca, + 0xdbdf58e9,0xd953c50d}, + {0xfd590f8f,0x9d6361cc, 0x44e6c917,0x72e9626b, 0x22eb64cf,0x7fd96110, + 0x9eb288f3,0x863ebb7e}, + {0x1,0x0, 0x0,0xffffffff, 0xffffffff,0xffffffff, 0xfffffffe,0x0}}, + {{0xb0e63d34,0x4fe7ee31, 0xa9e54fab,0xf4600572, 0xd5e7b5a4,0xc0493334, + 0x6d54831,0x8589fb92}, + {0x6583553a,0xaa70f5cc, 0xe25649e5,0x879094a, 0x10044652,0xcc904507, + 0x2541c4f,0xebb0696d}, + {0x1,0x0, 0x0,0xffffffff, 0xffffffff,0xffffffff, 0xfffffffe,0x0}}, + {{0x3b89da99,0xabbaa0c0, 0xb8284022,0xa6f2d79e, 0xb81c05e8,0x27847862, + 0x5e54d63,0x337a4b59}, + {0x21f7794a,0x3c67500d, 0x7d6d7f61,0x207005b7, 0x4cfd6e8,0xa5a3781, + 0xf4c2fbd6,0xd65e0d5}, + {0x1,0x0, 0x0,0xffffffff, 0xffffffff,0xffffffff, 0xfffffffe,0x0}}, + {{0x6d3549cf,0xd433e50f, 0xfacd665e,0x6f33696f, 0xce11fcb4,0x695bfdac, + 0xaf7c9860,0x810ee252}, + {0x7159bb2c,0x65450fe1, 0x758b357b,0xf7dfbebe, 0xd69fea72,0x2b057e74, + 0x92731745,0xd485717a}, + {0x1,0x0, 0x0,0xffffffff, 0xffffffff,0xffffffff, 0xfffffffe,0x0}}, + {{0xe83f7669,0xce1f69bb, 0x72877d6b,0x9f8ae82, 0x3244278d,0x9548ae54, + 0xe3c2c19c,0x207755de}, + {0x6fef1945,0x87bd61d9, 0xb12d28c3,0x18813cef, 0x72df64aa,0x9fbcd1d6, + 0x7154b00d,0x48dc5ee5}, + {0x1,0x0, 0x0,0xffffffff, 0xffffffff,0xffffffff, 0xfffffffe,0x0}}, + {{0xf49a3154,0xef0f469e, 0x6e2b2e9a,0x3e85a595, 0xaa924a9c,0x45aaec1e, + 0xa09e4719,0xaa12dfc8}, + {0x4df69f1d,0x26f27227, 0xa2ff5e73,0xe0e4c82c, 0xb7a9dd44,0xb9d8ce73, + 0xe48ca901,0x6c036e73}, + {0x1,0x0, 0x0,0xffffffff, 0xffffffff,0xffffffff, 0xfffffffe,0x0}}, + {{0xa47153f0,0xe1e421e1, 0x920418c9,0xb86c3b79, 0x705d7672,0x93bdce87, + 0xcab79a77,0xf25ae793}, + {0x6d869d0c,0x1f3194a3, 0x4986c264,0x9d55c882, 0x96e945e,0x49fb5ea3, + 0x13db0a3e,0x39b8e653}, + {0x1,0x0, 0x0,0xffffffff, 0xffffffff,0xffffffff, 0xfffffffe,0x0}}, + {{0x35d0b34a,0xe3417bc0, 0x8327c0a7,0x440b386b, 0xac0362d1,0x8fb7262d, + 0xe0cdf943,0x2c41114c}, + {0xad95a0b1,0x2ba5cef1, 0x67d54362,0xc09b37a8, 0x1e486c9,0x26d6cdd2, + 0x42ff9297,0x20477abf}, + {0x1,0x0, 0x0,0xffffffff, 0xffffffff,0xffffffff, 0xfffffffe,0x0}}, + {{0xbc0a67d2,0xf121b41, 0x444d248a,0x62d4760a, 0x659b4737,0xe044f1d, + 0x250bb4a8,0x8fde365}, + {0x848bf287,0xaceec3da, 0xd3369d6e,0xc2a62182, 0x92449482,0x3582dfdc, + 0x565d6cd7,0x2f7e2fd2}, + {0x1,0x0, 0x0,0xffffffff, 0xffffffff,0xffffffff, 0xfffffffe,0x0}}, + {{0x178a876b,0xa0122b5, 0x85104b4,0x51ff96ff, 0x14f29f76,0x50b31ab, + 0x5f87d4e6,0x84abb28b}, + {0x8270790a,0xd5ed439f, 0x85e3f46b,0x2d6cb59d, 0x6c1e2212,0x75f55c1b, + 0x17655640,0xe5436f67}, + {0x1,0x0, 0x0,0xffffffff, 0xffffffff,0xffffffff, 0xfffffffe,0x0}}, + {{0x9aeb596d,0xc2965ecc, 0x23c92b4,0x1ea03e7, 0x2e013961,0x4704b4b6, + 0x905ea367,0xca8fd3f}, + {0x551b2b61,0x92523a42, 0x390fcd06,0x1eb7a89c, 0x392a63e,0xe7f1d2be, + 0x4ddb0c33,0x96dca264}, + {0x1,0x0, 0x0,0xffffffff, 0xffffffff,0xffffffff, 0xfffffffe,0x0}}, + {{0x15339848,0x231c210e, 0x70778c8d,0xe87a28e8, 0x6956e170,0x9d1de661, + 0x2bb09c0b,0x4ac3c938}, + {0x6998987d,0x19be0551, 0xae09f4d6,0x8b2376c4, 0x1a3f933d,0x1de0b765, + 0xe39705f4,0x380d94c7}, + {0x1,0x0, 0x0,0xffffffff, 0xffffffff,0xffffffff, 0xfffffffe,0x0}}, + {{0x8c31c31d,0x3685954b, 0x5bf21a0c,0x68533d00, 0x75c79ec9,0xbd7626e, + 0x42c69d54,0xca177547}, + {0xf6d2dbb2,0xcc6edaff, 0x174a9d18,0xfd0d8cbd, 0xaa4578e8,0x875e8793, + 0x9cab2ce6,0xa976a713}, + {0x1,0x0, 0x0,0xffffffff, 0xffffffff,0xffffffff, 0xfffffffe,0x0}}, + {{0xb43ea1db,0xce37ab11, 0x5259d292,0xa7ff1a9, 0x8f84f186,0x851b0221, + 0xdefaad13,0xa7222bea}, + {0x2b0a9144,0xa2ac78ec, 0xf2fa59c5,0x5a024051, 0x6147ce38,0x91d1eca5, + 0xbc2ac690,0xbe94d523}, + {0x1,0x0, 0x0,0xffffffff, 0xffffffff,0xffffffff, 0xfffffffe,0x0}}, + {{0x79ec1a0f,0x2d8daefd, 0xceb39c97,0x3bbcd6fd, 0x58f61a95,0xf5575ffc, + 0xadf7b420,0xdbd986c4}, + {0x15f39eb7,0x81aa8814, 0xb98d976c,0x6ee2fcf5, 0xcf2f717d,0x5465475d, + 0x6860bbd0,0x8e24d3c4}, + {0x1,0x0, 0x0,0xffffffff, 0xffffffff,0xffffffff, 0xfffffffe,0x0}}}}; +#endif + +// select_point selects the |idx|th point from a precomputation table and +// copies it to out. +static void select_point(const limb_t idx, size_t size, + const fe pre_comp[/*size*/][3], + fe out[3]) { + OPENSSL_memset(out, 0, sizeof(fe) * 3); + for (size_t i = 0; i < size; i++) { + limb_t mismatch = i ^ idx; + fe_cmovznz(out[0], mismatch, pre_comp[i][0], out[0]); + fe_cmovznz(out[1], mismatch, pre_comp[i][1], out[1]); + fe_cmovznz(out[2], mismatch, pre_comp[i][2], out[2]); + } +} + +// get_bit returns the |i|th bit in |in| +static char get_bit(const uint8_t *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 p_pre_comp, the scalar +// in p_scalar, if non-NULL. 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(fe x_out, fe y_out, fe z_out, + const uint8_t *p_scalar, const uint8_t *g_scalar, + const fe p_pre_comp[17][3]) { + // set nq to the point at infinity + fe nq[3] = {{0},{0},{0}}, ftmp, tmp[3]; + uint64_t bits; + uint8_t sign, digit; + + // Loop over both scalars msb-to-lsb, interleaving additions of multiples + // of the generator (two in each of the last 32 rounds) and additions of p + // (every 5th round). + + int skip = 1; // save two point operations in the first round + size_t i = p_scalar != NULL ? 255 : 31; + for (;;) { + // double + if (!skip) { + point_double(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2]); + } + + // add multiples of the generator + if (g_scalar != NULL && 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) { + point_add(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2], 1 /* mixed */, + tmp[0], tmp[1], tmp[2]); + } else { + fe_copy(nq[0], tmp[0]); + fe_copy(nq[1], tmp[1]); + fe_copy(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); + 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 (p_scalar != NULL && i % 5 == 0) { + bits = get_bit(p_scalar, i + 4) << 5; + bits |= get_bit(p_scalar, i + 3) << 4; + bits |= get_bit(p_scalar, i + 2) << 3; + bits |= get_bit(p_scalar, i + 1) << 2; + bits |= get_bit(p_scalar, i) << 1; + bits |= get_bit(p_scalar, 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, p_pre_comp, tmp); + fe_opp(ftmp, tmp[1]); // (X, -Y, Z) is the negative point. + fe_cmovznz(tmp[1], sign, tmp[1], ftmp); + + if (!skip) { + point_add(nq[0], nq[1], nq[2], nq[0], nq[1], nq[2], 0 /* mixed */, + tmp[0], tmp[1], tmp[2]); + } else { + fe_copy(nq[0], tmp[0]); + fe_copy(nq[1], tmp[1]); + fe_copy(nq[2], tmp[2]); + skip = 0; + } + } + + if (i == 0) { + break; + } + --i; + } + fe_copy(x_out, nq[0]); + fe_copy(y_out, nq[1]); + fe_copy(z_out, nq[2]); +} + +// OPENSSL EC_METHOD FUNCTIONS + +// Takes the Jacobian coordinates (X, Y, Z) of a point and returns (X', Y') = +// (X/Z^2, Y/Z^3). +static int ec_GFp_nistp256_point_get_affine_coordinates(const EC_GROUP *group, + const EC_POINT *point, + BIGNUM *x_out, + BIGNUM *y_out, + BN_CTX *ctx) { + fe x, y, z1, z2; + + if (EC_POINT_is_at_infinity(group, point)) { + OPENSSL_PUT_ERROR(EC, EC_R_POINT_AT_INFINITY); + return 0; + } + if (!BN_to_fe(x, &point->X) || + !BN_to_fe(y, &point->Y) || + !BN_to_fe(z1, &point->Z)) { + return 0; + } + + fe_inv(z2, z1); + fe_sqr(z1, z2); + + // Instead of using |fe_from_montgomery| to convert the |x| coordinate and + // then calling |fe_from_montgomery| again to convert the |y| coordinate + // below, convert the common factor |z1| once now, saving one reduction. + fe_from_montgomery(z1); + + if (x_out != NULL) { + fe_mul(x, x, z1); + if (!fe_to_BN(x_out, x)) { + OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB); + return 0; + } + } + + if (y_out != NULL) { + fe_mul(z1, z1, z2); + fe_mul(y, y, z1); + if (!fe_to_BN(y_out, y)) { + OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB); + return 0; + } + } + + return 1; +} + +static int ec_GFp_nistp256_points_mul(const EC_GROUP *group, EC_POINT *r, + const EC_SCALAR *g_scalar, + const EC_POINT *p, + const EC_SCALAR *p_scalar, + BN_CTX *unused_ctx) { + fe p_pre_comp[17][3]; + fe x_out, y_out, z_out; + + if (p != NULL && p_scalar != NULL) { + // We treat NULL scalars as 0, and NULL points as points at infinity, i.e., + // they contribute nothing to the linear combination. + OPENSSL_memset(&p_pre_comp, 0, sizeof(p_pre_comp)); + // Precompute multiples. + if (!BN_to_fe(p_pre_comp[1][0], &p->X) || + !BN_to_fe(p_pre_comp[1][1], &p->Y) || + !BN_to_fe(p_pre_comp[1][2], &p->Z)) { + return 0; + } + for (size_t j = 2; j <= 16; ++j) { + if (j & 1) { + point_add(p_pre_comp[j][0], p_pre_comp[j][1], + p_pre_comp[j][2], p_pre_comp[1][0], + p_pre_comp[1][1], p_pre_comp[1][2], + 0, + p_pre_comp[j - 1][0], p_pre_comp[j - 1][1], + p_pre_comp[j - 1][2]); + } else { + point_double(p_pre_comp[j][0], p_pre_comp[j][1], + p_pre_comp[j][2], p_pre_comp[j / 2][0], + p_pre_comp[j / 2][1], p_pre_comp[j / 2][2]); + } + } + } + + batch_mul(x_out, y_out, z_out, + (p != NULL && p_scalar != NULL) ? p_scalar->bytes : NULL, + g_scalar != NULL ? g_scalar->bytes : NULL, + (const fe (*) [3])p_pre_comp); + + if (!fe_to_BN(&r->X, x_out) || + !fe_to_BN(&r->Y, y_out) || + !fe_to_BN(&r->Z, z_out)) { + OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB); + return 0; + } + return 1; +} + +static int ec_GFp_nistp256_point_mul_public(const EC_GROUP *group, EC_POINT *r, + const EC_SCALAR *g_scalar, + const EC_POINT *p, + const EC_SCALAR *p_scalar, + BN_CTX *unused_ctx) { +#define P256_WSIZE_PUBLIC 4 + // Precompute multiples of |p|. p_pre_comp[i] is (2*i+1) * |p|. + fe p_pre_comp[1 << (P256_WSIZE_PUBLIC-1)][3]; + if (!BN_to_fe(p_pre_comp[0][0], &p->X) || + !BN_to_fe(p_pre_comp[0][1], &p->Y) || + !BN_to_fe(p_pre_comp[0][2], &p->Z)) { + return 0; + } + fe p2[3]; + point_double(p2[0], p2[1], p2[2], p_pre_comp[0][0], p_pre_comp[0][1], + p_pre_comp[0][2]); + for (size_t i = 1; i < OPENSSL_ARRAY_SIZE(p_pre_comp); i++) { + point_add(p_pre_comp[i][0], p_pre_comp[i][1], p_pre_comp[i][2], + p_pre_comp[i - 1][0], p_pre_comp[i - 1][1], p_pre_comp[i - 1][2], + 0 /* not mixed */, p2[0], p2[1], p2[2]); + } + + // Set up the coefficients for |p_scalar|. + int8_t p_wNAF[257]; + if (!ec_compute_wNAF(group, p_wNAF, p_scalar, 256, P256_WSIZE_PUBLIC)) { + return 0; + } + + // Set |ret| to the point at infinity. + int skip = 1; // Save some point operations. + fe ret[3] = {{0},{0},{0}}; + for (int i = 256; i >= 0; i--) { + if (!skip) { + point_double(ret[0], ret[1], ret[2], ret[0], ret[1], ret[2]); + } + + // For the |g_scalar|, we use the precomputed table without the + // constant-time lookup. + if (i <= 31) { + // First, look 32 bits upwards. + uint64_t bits = get_bit(g_scalar->bytes, i + 224) << 3; + bits |= get_bit(g_scalar->bytes, i + 160) << 2; + bits |= get_bit(g_scalar->bytes, i + 96) << 1; + bits |= get_bit(g_scalar->bytes, i + 32); + point_add(ret[0], ret[1], ret[2], ret[0], ret[1], ret[2], 1 /* mixed */, + g_pre_comp[1][bits][0], g_pre_comp[1][bits][1], + g_pre_comp[1][bits][2]); + skip = 0; + + // Second, look at the current position. + bits = get_bit(g_scalar->bytes, i + 192) << 3; + bits |= get_bit(g_scalar->bytes, i + 128) << 2; + bits |= get_bit(g_scalar->bytes, i + 64) << 1; + bits |= get_bit(g_scalar->bytes, i); + point_add(ret[0], ret[1], ret[2], ret[0], ret[1], ret[2], 1 /* mixed */, + g_pre_comp[0][bits][0], g_pre_comp[0][bits][1], + g_pre_comp[0][bits][2]); + } + + int digit = p_wNAF[i]; + if (digit != 0) { + assert(digit & 1); + int idx = digit < 0 ? (-digit) >> 1 : digit >> 1; + fe *y = &p_pre_comp[idx][1], tmp; + if (digit < 0) { + fe_opp(tmp, p_pre_comp[idx][1]); + y = &tmp; + } + if (!skip) { + point_add(ret[0], ret[1], ret[2], ret[0], ret[1], ret[2], + 0 /* not mixed */, p_pre_comp[idx][0], *y, p_pre_comp[idx][2]); + } else { + fe_copy(ret[0], p_pre_comp[idx][0]); + fe_copy(ret[1], *y); + fe_copy(ret[2], p_pre_comp[idx][2]); + skip = 0; + } + } + } + + if (!fe_to_BN(&r->X, ret[0]) || + !fe_to_BN(&r->Y, ret[1]) || + !fe_to_BN(&r->Z, ret[2])) { + OPENSSL_PUT_ERROR(EC, ERR_R_BN_LIB); + return 0; + } + return 1; +} + +DEFINE_METHOD_FUNCTION(EC_METHOD, EC_GFp_nistp256_method) { + out->group_init = ec_GFp_mont_group_init; + out->group_finish = ec_GFp_mont_group_finish; + out->group_set_curve = ec_GFp_mont_group_set_curve; + out->point_get_affine_coordinates = + ec_GFp_nistp256_point_get_affine_coordinates; + out->mul = ec_GFp_nistp256_points_mul; + out->mul_public = ec_GFp_nistp256_point_mul_public; + out->field_mul = ec_GFp_mont_field_mul; + out->field_sqr = ec_GFp_mont_field_sqr; + out->field_encode = ec_GFp_mont_field_encode; + out->field_decode = ec_GFp_mont_field_decode; +}; + +#undef BORINGSSL_NISTP256_64BIT diff --git a/FoodApp/Pods/CodableFirebase/CodableFirebase/Decoder.swift b/FoodApp/Pods/CodableFirebase/CodableFirebase/Decoder.swift new file mode 100644 index 0000000..df4ca1f --- /dev/null +++ b/FoodApp/Pods/CodableFirebase/CodableFirebase/Decoder.swift @@ -0,0 +1,1250 @@ +// +// Decoder.swift +// CodableFirebase +// +// Created by Oleksii on 27/12/2017. +// Copyright © 2017 ViolentOctopus. All rights reserved. +// + +import Foundation + +class _FirebaseDecoder : Decoder { + /// Options set on the top-level encoder to pass down the decoding hierarchy. + struct _Options { + let dateDecodingStrategy: FirebaseDecoder.DateDecodingStrategy? + let dataDecodingStrategy: FirebaseDecoder.DataDecodingStrategy? + let skipFirestoreTypes: Bool + let userInfo: [CodingUserInfoKey : Any] + } + + // MARK: Properties + /// The decoder's storage. + fileprivate var storage: _FirebaseDecodingStorage + + fileprivate let options: _Options + + /// The path to the current point in encoding. + fileprivate(set) public var codingPath: [CodingKey] + + /// Contextual user-provided information for use during encoding. + public var userInfo: [CodingUserInfoKey : Any] { + return options.userInfo + } + + // MARK: - Initialization + /// Initializes `self` with the given top-level container and options. + init(referencing container: Any, at codingPath: [CodingKey] = [], options: _Options) { + self.storage = _FirebaseDecodingStorage() + self.storage.push(container: container) + self.codingPath = codingPath + self.options = options + } + + // MARK: - Decoder Methods + public func container(keyedBy type: Key.Type) throws -> KeyedDecodingContainer { + guard !(self.storage.topContainer is NSNull) else { + throw DecodingError.valueNotFound(KeyedDecodingContainer.self, + DecodingError.Context(codingPath: self.codingPath, + debugDescription: "Cannot get keyed decoding container -- found null value instead.")) + } + + guard let topContainer = self.storage.topContainer as? [String : Any] else { + let context = DecodingError.Context(codingPath: codingPath, debugDescription: "Not a dictionary") + throw DecodingError.typeMismatch([String: Any].self, context) + } + + let container = _FirebaseKeyedDecodingContainer(referencing: self, wrapping: topContainer) + return KeyedDecodingContainer(container) + } + + public func unkeyedContainer() throws -> UnkeyedDecodingContainer { + guard !(self.storage.topContainer is NSNull) else { + throw DecodingError.valueNotFound(UnkeyedDecodingContainer.self, + DecodingError.Context(codingPath: self.codingPath, + debugDescription: "Cannot get unkeyed decoding container -- found null value instead.")) + } + + guard let topContainer = self.storage.topContainer as? [Any] else { + let context = DecodingError.Context(codingPath: codingPath, debugDescription: "Not an array") + throw DecodingError.typeMismatch([Any].self, context) + } + + return _FirebaseUnkeyedDecodingContainer(referencing: self, wrapping: topContainer) + } + + public func singleValueContainer() throws -> SingleValueDecodingContainer { + return self + } +} + +fileprivate struct _FirebaseDecodingStorage { + // MARK: Properties + /// The container stack. + /// Elements may be any one of the plist types (NSNumber, Date, String, Array, [String : Any]). + private(set) fileprivate var containers: [Any] = [] + + // MARK: - Initialization + /// Initializes `self` with no containers. + fileprivate init() {} + + // MARK: - Modifying the Stack + fileprivate var count: Int { + return containers.count + } + + fileprivate var topContainer: Any { + precondition(containers.count > 0, "Empty container stack.") + return containers.last! + } + + fileprivate mutating func push(container: Any) { + containers.append(container) + } + + fileprivate mutating func popContainer() { + precondition(containers.count > 0, "Empty container stack.") + containers.removeLast() + } +} + +fileprivate struct _FirebaseKeyedDecodingContainer : KeyedDecodingContainerProtocol { + typealias Key = K + + // MARK: Properties + /// A reference to the decoder we're reading from. + private let decoder: _FirebaseDecoder + + /// A reference to the container we're reading from. + private let container: [String : Any] + + /// The path of coding keys taken to get to this point in decoding. + private(set) public var codingPath: [CodingKey] + + // MARK: - Initialization + /// Initializes `self` by referencing the given decoder and container. + fileprivate init(referencing decoder: _FirebaseDecoder, wrapping container: [String : Any]) { + self.decoder = decoder + self.container = container + self.codingPath = decoder.codingPath + } + + // MARK: - KeyedDecodingContainerProtocol Methods + public var allKeys: [Key] { + return container.keys.compactMap { Key(stringValue: $0) } + } + + public func contains(_ key: Key) -> Bool { + return container[key.stringValue] != nil + } + + public func decodeNil(forKey key: Key) throws -> Bool { + guard let entry = self.container[key.stringValue] else { + throw DecodingError.keyNotFound(key, DecodingError.Context(codingPath: self.decoder.codingPath, debugDescription: "No value associated with key \(key) (\"\(key.stringValue)\").")) + } + + return entry is NSNull + } + + public func decode(_ type: Bool.Type, forKey key: Key) throws -> Bool { + guard let entry = self.container[key.stringValue] else { + throw DecodingError.keyNotFound(key, DecodingError.Context(codingPath: self.decoder.codingPath, debugDescription: "No value associated with key \(key) (\"\(key.stringValue)\").")) + } + + self.decoder.codingPath.append(key) + defer { self.decoder.codingPath.removeLast() } + + guard let value = try self.decoder.unbox(entry, as: Bool.self) else { + throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath, debugDescription: "Expected \(type) value but found null instead.")) + } + + return value + } + + public func decode(_ type: Int.Type, forKey key: Key) throws -> Int { + guard let entry = self.container[key.stringValue] else { + throw DecodingError.keyNotFound(key, DecodingError.Context(codingPath: self.decoder.codingPath, debugDescription: "No value associated with key \(key) (\"\(key.stringValue)\").")) + } + + self.decoder.codingPath.append(key) + defer { self.decoder.codingPath.removeLast() } + + guard let value = try self.decoder.unbox(entry, as: Int.self) else { + throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath, debugDescription: "Expected \(type) value but found null instead.")) + } + + return value + } + + public func decode(_ type: Int8.Type, forKey key: Key) throws -> Int8 { + guard let entry = self.container[key.stringValue] else { + throw DecodingError.keyNotFound(key, DecodingError.Context(codingPath: self.decoder.codingPath, debugDescription: "No value associated with key \(key) (\"\(key.stringValue)\").")) + } + + self.decoder.codingPath.append(key) + defer { self.decoder.codingPath.removeLast() } + + guard let value = try self.decoder.unbox(entry, as: Int8.self) else { + throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath, debugDescription: "Expected \(type) value but found null instead.")) + } + + return value + } + + public func decode(_ type: Int16.Type, forKey key: Key) throws -> Int16 { + guard let entry = self.container[key.stringValue] else { + throw DecodingError.keyNotFound(key, DecodingError.Context(codingPath: self.decoder.codingPath, debugDescription: "No value associated with key \(key) (\"\(key.stringValue)\").")) + } + + self.decoder.codingPath.append(key) + defer { self.decoder.codingPath.removeLast() } + + guard let value = try self.decoder.unbox(entry, as: Int16.self) else { + throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath, debugDescription: "Expected \(type) value but found null instead.")) + } + + return value + } + + public func decode(_ type: Int32.Type, forKey key: Key) throws -> Int32 { + guard let entry = self.container[key.stringValue] else { + throw DecodingError.keyNotFound(key, DecodingError.Context(codingPath: self.decoder.codingPath, debugDescription: "No value associated with key \(key) (\"\(key.stringValue)\").")) + } + + self.decoder.codingPath.append(key) + defer { self.decoder.codingPath.removeLast() } + + guard let value = try self.decoder.unbox(entry, as: Int32.self) else { + throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath, debugDescription: "Expected \(type) value but found null instead.")) + } + + return value + } + + public func decode(_ type: Int64.Type, forKey key: Key) throws -> Int64 { + guard let entry = self.container[key.stringValue] else { + throw DecodingError.keyNotFound(key, DecodingError.Context(codingPath: self.decoder.codingPath, debugDescription: "No value associated with key \(key) (\"\(key.stringValue)\").")) + } + + self.decoder.codingPath.append(key) + defer { self.decoder.codingPath.removeLast() } + + guard let value = try self.decoder.unbox(entry, as: Int64.self) else { + throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath, debugDescription: "Expected \(type) value but found null instead.")) + } + + return value + } + + public func decode(_ type: UInt.Type, forKey key: Key) throws -> UInt { + guard let entry = self.container[key.stringValue] else { + throw DecodingError.keyNotFound(key, DecodingError.Context(codingPath: self.decoder.codingPath, debugDescription: "No value associated with key \(key) (\"\(key.stringValue)\").")) + } + + self.decoder.codingPath.append(key) + defer { self.decoder.codingPath.removeLast() } + + guard let value = try self.decoder.unbox(entry, as: UInt.self) else { + throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath, debugDescription: "Expected \(type) value but found null instead.")) + } + + return value + } + + public func decode(_ type: UInt8.Type, forKey key: Key) throws -> UInt8 { + guard let entry = container[key.stringValue] else { + throw DecodingError.keyNotFound(key, DecodingError.Context(codingPath: self.decoder.codingPath, debugDescription: "No value associated with key \(key) (\"\(key.stringValue)\").")) + } + + self.decoder.codingPath.append(key) + defer { self.decoder.codingPath.removeLast() } + + guard let value = try self.decoder.unbox(entry, as: UInt8.self) else { + throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath, debugDescription: "Expected \(type) value but found null instead.")) + } + + return value + } + + public func decode(_ type: UInt16.Type, forKey key: Key) throws -> UInt16 { + guard let entry = container[key.stringValue] else { + throw DecodingError.keyNotFound(key, DecodingError.Context(codingPath: self.decoder.codingPath, debugDescription: "No value associated with key \(key) (\"\(key.stringValue)\").")) + } + + self.decoder.codingPath.append(key) + defer { self.decoder.codingPath.removeLast() } + + guard let value = try self.decoder.unbox(entry, as: UInt16.self) else { + throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath, debugDescription: "Expected \(type) value but found null instead.")) + } + + return value + } + + public func decode(_ type: UInt32.Type, forKey key: Key) throws -> UInt32 { + guard let entry = self.container[key.stringValue] else { + throw DecodingError.keyNotFound(key, DecodingError.Context(codingPath: self.decoder.codingPath, debugDescription: "No value associated with key \(key) (\"\(key.stringValue)\").")) + } + + self.decoder.codingPath.append(key) + defer { self.decoder.codingPath.removeLast() } + + guard let value = try self.decoder.unbox(entry, as: UInt32.self) else { + throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath, debugDescription: "Expected \(type) value but found null instead.")) + } + + return value + } + + public func decode(_ type: UInt64.Type, forKey key: Key) throws -> UInt64 { + guard let entry = self.container[key.stringValue] else { + throw DecodingError.keyNotFound(key, DecodingError.Context(codingPath: self.decoder.codingPath, debugDescription: "No value associated with key \(key) (\"\(key.stringValue)\").")) + } + + self.decoder.codingPath.append(key) + defer { self.decoder.codingPath.removeLast() } + + guard let value = try self.decoder.unbox(entry, as: UInt64.self) else { + throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath, debugDescription: "Expected \(type) value but found null instead.")) + } + + return value + } + + public func decode(_ type: Float.Type, forKey key: Key) throws -> Float { + guard let entry = self.container[key.stringValue] else { + throw DecodingError.keyNotFound(key, DecodingError.Context(codingPath: self.decoder.codingPath, debugDescription: "No value associated with key \(key) (\"\(key.stringValue)\").")) + } + + self.decoder.codingPath.append(key) + defer { self.decoder.codingPath.removeLast() } + guard let value = try self.decoder.unbox(entry, as: Float.self) else { + throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath, debugDescription: "Expected \(type) value but found null instead.")) + } + + return value + } + + public func decode(_ type: Double.Type, forKey key: Key) throws -> Double { + guard let entry = self.container[key.stringValue] else { + throw DecodingError.keyNotFound(key, DecodingError.Context(codingPath: self.decoder.codingPath, debugDescription: "No value associated with key \(key) (\"\(key.stringValue)\").")) + } + + self.decoder.codingPath.append(key) + defer { self.decoder.codingPath.removeLast() } + + guard let value = try self.decoder.unbox(entry, as: Double.self) else { + throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath, debugDescription: "Expected \(type) value but found null instead.")) + } + + return value + } + + public func decode(_ type: String.Type, forKey key: Key) throws -> String { + guard let entry = self.container[key.stringValue] else { + throw DecodingError.keyNotFound(key, DecodingError.Context(codingPath: self.decoder.codingPath, debugDescription: "No value associated with key \(key) (\"\(key.stringValue)\").")) + } + + self.decoder.codingPath.append(key) + defer { self.decoder.codingPath.removeLast() } + + guard let value = try self.decoder.unbox(entry, as: String.self) else { + throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath, debugDescription: "Expected \(type) value but found null instead.")) + } + + return value + } + + public func decode(_ type: T.Type, forKey key: Key) throws -> T { + guard let entry = container[key.stringValue] else { + throw DecodingError.keyNotFound(key, DecodingError.Context(codingPath: self.decoder.codingPath, debugDescription: "No value associated with key \(key) (\"\(key.stringValue)\").")) + } + + self.decoder.codingPath.append(key) + defer { self.decoder.codingPath.removeLast() } + + guard let value = try decoder.unbox(entry, as: T.self) else { + throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath, debugDescription: "Expected \(type) value but found null instead.")) + } + + return value + } + + public func nestedContainer(keyedBy type: NestedKey.Type, forKey key: Key) throws -> KeyedDecodingContainer { + self.decoder.codingPath.append(key) + defer { self.decoder.codingPath.removeLast() } + + guard let value = self.container[key.stringValue] else { + throw DecodingError.valueNotFound(KeyedDecodingContainer.self, + DecodingError.Context(codingPath: self.codingPath, + debugDescription: "Cannot get nested keyed container -- no value found for key \"\(key.stringValue)\"")) + } + + guard let dictionary = value as? [String : Any] else { + throw DecodingError._typeMismatch(at: self.codingPath, expectation: [String : Any].self, reality: value) + } + + let container = _FirebaseKeyedDecodingContainer(referencing: self.decoder, wrapping: dictionary) + return KeyedDecodingContainer(container) + } + + public func nestedUnkeyedContainer(forKey key: Key) throws -> UnkeyedDecodingContainer { + self.decoder.codingPath.append(key) + defer { self.decoder.codingPath.removeLast() } + + guard let value = self.container[key.stringValue] else { + throw DecodingError.valueNotFound(UnkeyedDecodingContainer.self, + DecodingError.Context(codingPath: self.codingPath, + debugDescription: "Cannot get nested unkeyed container -- no value found for key \"\(key.stringValue)\"")) + } + + guard let array = value as? [Any] else { + let context = DecodingError.Context(codingPath: codingPath, debugDescription: "Not an array") + throw DecodingError.typeMismatch([Any].self, context) + } + + return _FirebaseUnkeyedDecodingContainer(referencing: self.decoder, wrapping: array) + } + + private func _superDecoder(forKey key: CodingKey) throws -> Decoder { + self.decoder.codingPath.append(key) + defer { self.decoder.codingPath.removeLast() } + + let value: Any = container[key.stringValue] ?? NSNull() + return _FirebaseDecoder(referencing: value, at: self.decoder.codingPath, options: decoder.options) + } + + public func superDecoder() throws -> Decoder { + return try _superDecoder(forKey: _FirebaseKey.super) + } + + public func superDecoder(forKey key: Key) throws -> Decoder { + return try _superDecoder(forKey: key) + } +} + +fileprivate struct _FirebaseUnkeyedDecodingContainer : UnkeyedDecodingContainer { + // MARK: Properties + /// A reference to the decoder we're reading from. + private let decoder: _FirebaseDecoder + + /// A reference to the container we're reading from. + private let container: [Any] + + /// The path of coding keys taken to get to this point in decoding. + private(set) public var codingPath: [CodingKey] + + /// The index of the element we're about to decode. + private(set) public var currentIndex: Int + + // MARK: - Initialization + /// Initializes `self` by referencing the given decoder and container. + fileprivate init(referencing decoder: _FirebaseDecoder, wrapping container: [Any]) { + self.decoder = decoder + self.container = container + self.codingPath = decoder.codingPath + self.currentIndex = 0 + } + + // MARK: - UnkeyedDecodingContainer Methods + public var count: Int? { + return container.count + } + + public var isAtEnd: Bool { + return currentIndex >= count! + } + + public mutating func decodeNil() throws -> Bool { + guard !isAtEnd else { + throw DecodingError.valueNotFound(Any?.self, DecodingError.Context(codingPath: self.decoder.codingPath + [_FirebaseKey(index: self.currentIndex)], debugDescription: "Unkeyed container is at end.")) + } + + if container[currentIndex] is NSNull { + currentIndex += 1 + return true + } else { + return false + } + } + + public mutating func decode(_ type: Bool.Type) throws -> Bool { + guard !isAtEnd else { + throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: decoder.codingPath + [_FirebaseKey(index: currentIndex)], debugDescription: "Unkeyed container is at end.")) + } + + decoder.codingPath.append(_FirebaseKey(index: currentIndex)) + defer { decoder.codingPath.removeLast() } + + guard let decoded = try decoder.unbox(container[currentIndex], as: Bool.self) else { + throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: decoder.codingPath + [_FirebaseKey(index: currentIndex)], debugDescription: "Expected \(type) but found null instead.")) + } + + currentIndex += 1 + return decoded + } + + public mutating func decode(_ type: Int.Type) throws -> Int { + guard !isAtEnd else { + throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: decoder.codingPath + [_FirebaseKey(index: currentIndex)], debugDescription: "Unkeyed container is at end.")) + } + + decoder.codingPath.append(_FirebaseKey(index: currentIndex)) + defer { decoder.codingPath.removeLast() } + + guard let decoded = try decoder.unbox(container[currentIndex], as: Int.self) else { + throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: decoder.codingPath + [_FirebaseKey(index: currentIndex)], debugDescription: "Expected \(type) but found null instead.")) + } + + currentIndex += 1 + return decoded + } + + public mutating func decode(_ type: Int8.Type) throws -> Int8 { + guard !isAtEnd else { + throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: decoder.codingPath + [_FirebaseKey(index: currentIndex)], debugDescription: "Unkeyed container is at end.")) + } + + decoder.codingPath.append(_FirebaseKey(index: currentIndex)) + defer { decoder.codingPath.removeLast() } + + guard let decoded = try decoder.unbox(container[currentIndex], as: Int8.self) else { + throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: decoder.codingPath + [_FirebaseKey(index: currentIndex)], debugDescription: "Expected \(type) but found null instead.")) + } + + currentIndex += 1 + return decoded + } + + public mutating func decode(_ type: Int16.Type) throws -> Int16 { + guard !isAtEnd else { + throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: decoder.codingPath + [_FirebaseKey(index: currentIndex)], debugDescription: "Unkeyed container is at end.")) + } + + decoder.codingPath.append(_FirebaseKey(index: currentIndex)) + defer { decoder.codingPath.removeLast() } + + guard let decoded = try decoder.unbox(container[currentIndex], as: Int16.self) else { + throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: decoder.codingPath + [_FirebaseKey(index: currentIndex)], debugDescription: "Expected \(type) but found null instead.")) + } + + currentIndex += 1 + return decoded + } + + public mutating func decode(_ type: Int32.Type) throws -> Int32 { + guard !isAtEnd else { + throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: decoder.codingPath + [_FirebaseKey(index: currentIndex)], debugDescription: "Unkeyed container is at end.")) + } + + decoder.codingPath.append(_FirebaseKey(index: currentIndex)) + defer { decoder.codingPath.removeLast() } + + guard let decoded = try decoder.unbox(container[currentIndex], as: Int32.self) else { + throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: decoder.codingPath + [_FirebaseKey(index: currentIndex)], debugDescription: "Expected \(type) but found null instead.")) + } + + currentIndex += 1 + return decoded + } + + public mutating func decode(_ type: Int64.Type) throws -> Int64 { + guard !isAtEnd else { + throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: decoder.codingPath + [_FirebaseKey(index: currentIndex)], debugDescription: "Unkeyed container is at end.")) + } + + decoder.codingPath.append(_FirebaseKey(index: currentIndex)) + defer { decoder.codingPath.removeLast() } + + guard let decoded = try decoder.unbox(container[currentIndex], as: Int64.self) else { + throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: decoder.codingPath + [_FirebaseKey(index: currentIndex)], debugDescription: "Expected \(type) but found null instead.")) + } + + currentIndex += 1 + return decoded + } + + public mutating func decode(_ type: UInt.Type) throws -> UInt { + guard !isAtEnd else { + throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: decoder.codingPath + [_FirebaseKey(index: currentIndex)], debugDescription: "Unkeyed container is at end.")) + } + + decoder.codingPath.append(_FirebaseKey(index: currentIndex)) + defer { decoder.codingPath.removeLast() } + + guard let decoded = try decoder.unbox(container[currentIndex], as: UInt.self) else { + throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: decoder.codingPath + [_FirebaseKey(index: currentIndex)], debugDescription: "Expected \(type) but found null instead.")) + } + + currentIndex += 1 + return decoded + } + + public mutating func decode(_ type: UInt8.Type) throws -> UInt8 { + guard !isAtEnd else { + throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: decoder.codingPath + [_FirebaseKey(index: currentIndex)], debugDescription: "Unkeyed container is at end.")) + } + + decoder.codingPath.append(_FirebaseKey(index: currentIndex)) + defer { decoder.codingPath.removeLast() } + + guard let decoded = try decoder.unbox(container[currentIndex], as: UInt8.self) else { + throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: decoder.codingPath + [_FirebaseKey(index: currentIndex)], debugDescription: "Expected \(type) but found null instead.")) + } + + currentIndex += 1 + return decoded + } + + public mutating func decode(_ type: UInt16.Type) throws -> UInt16 { + guard !self.isAtEnd else { + throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: decoder.codingPath + [_FirebaseKey(index: currentIndex)], debugDescription: "Unkeyed container is at end.")) + } + + self.decoder.codingPath.append(_FirebaseKey(index: currentIndex)) + defer { self.decoder.codingPath.removeLast() } + + guard let decoded = try decoder.unbox(container[currentIndex], as: UInt16.self) else { + throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: decoder.codingPath + [_FirebaseKey(index: currentIndex)], debugDescription: "Expected \(type) but found null instead.")) + } + + currentIndex += 1 + return decoded + } + + public mutating func decode(_ type: UInt32.Type) throws -> UInt32 { + guard !self.isAtEnd else { + throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: decoder.codingPath + [_FirebaseKey(index: currentIndex)], debugDescription: "Unkeyed container is at end.")) + } + + decoder.codingPath.append(_FirebaseKey(index: currentIndex)) + defer { decoder.codingPath.removeLast() } + + guard let decoded = try decoder.unbox(container[currentIndex], as: UInt32.self) else { + throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: decoder.codingPath + [_FirebaseKey(index: currentIndex)], debugDescription: "Expected \(type) but found null instead.")) + } + + currentIndex += 1 + return decoded + } + + public mutating func decode(_ type: UInt64.Type) throws -> UInt64 { + guard !isAtEnd else { + throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: decoder.codingPath + [_FirebaseKey(index: currentIndex)], debugDescription: "Unkeyed container is at end.")) + } + + decoder.codingPath.append(_FirebaseKey(index: currentIndex)) + defer { decoder.codingPath.removeLast() } + + guard let decoded = try decoder.unbox(container[currentIndex], as: UInt64.self) else { + throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: decoder.codingPath + [_FirebaseKey(index: currentIndex)], debugDescription: "Expected \(type) but found null instead.")) + } + + currentIndex += 1 + return decoded + } + + public mutating func decode(_ type: Float.Type) throws -> Float { + guard !self.isAtEnd else { + throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_FirebaseKey(index: self.currentIndex)], debugDescription: "Unkeyed container is at end.")) + } + + self.decoder.codingPath.append(_FirebaseKey(index: self.currentIndex)) + defer { self.decoder.codingPath.removeLast() } + + guard let decoded = try self.decoder.unbox(self.container[self.currentIndex], as: Float.self) else { + throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_FirebaseKey(index: self.currentIndex)], debugDescription: "Expected \(type) but found null instead.")) + } + + self.currentIndex += 1 + return decoded + } + + public mutating func decode(_ type: Double.Type) throws -> Double { + guard !self.isAtEnd else { + throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_FirebaseKey(index: self.currentIndex)], debugDescription: "Unkeyed container is at end.")) + } + + self.decoder.codingPath.append(_FirebaseKey(index: self.currentIndex)) + defer { self.decoder.codingPath.removeLast() } + + guard let decoded = try self.decoder.unbox(self.container[self.currentIndex], as: Double.self) else { + throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_FirebaseKey(index: self.currentIndex)], debugDescription: "Expected \(type) but found null instead.")) + } + + self.currentIndex += 1 + return decoded + } + + public mutating func decode(_ type: String.Type) throws -> String { + guard !self.isAtEnd else { + throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_FirebaseKey(index: self.currentIndex)], debugDescription: "Unkeyed container is at end.")) + } + + self.decoder.codingPath.append(_FirebaseKey(index: self.currentIndex)) + defer { self.decoder.codingPath.removeLast() } + + guard let decoded = try self.decoder.unbox(self.container[self.currentIndex], as: String.self) else { + throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_FirebaseKey(index: self.currentIndex)], debugDescription: "Expected \(type) but found null instead.")) + } + + self.currentIndex += 1 + return decoded + } + + public mutating func decode(_ type: T.Type) throws -> T { + guard !self.isAtEnd else { + throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_FirebaseKey(index: self.currentIndex)], debugDescription: "Unkeyed container is at end.")) + } + + self.decoder.codingPath.append(_FirebaseKey(index: self.currentIndex)) + defer { self.decoder.codingPath.removeLast() } + + guard let decoded = try self.decoder.unbox(self.container[self.currentIndex], as: T.self) else { + throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: self.decoder.codingPath + [_FirebaseKey(index: self.currentIndex)], debugDescription: "Expected \(type) but found null instead.")) + } + + self.currentIndex += 1 + return decoded + } + + public mutating func nestedContainer(keyedBy type: NestedKey.Type) throws -> KeyedDecodingContainer { + self.decoder.codingPath.append(_FirebaseKey(index: self.currentIndex)) + defer { self.decoder.codingPath.removeLast() } + + guard !self.isAtEnd else { + throw DecodingError.valueNotFound(KeyedDecodingContainer.self, + DecodingError.Context(codingPath: self.codingPath, + debugDescription: "Cannot get nested keyed container -- unkeyed container is at end.")) + } + + let value = self.container[self.currentIndex] + guard !(value is NSNull) else { + throw DecodingError.valueNotFound(KeyedDecodingContainer.self, + DecodingError.Context(codingPath: self.codingPath, + debugDescription: "Cannot get keyed decoding container -- found null value instead.")) + } + + guard let dictionary = value as? [String : Any] else { + let context = DecodingError.Context(codingPath: codingPath, debugDescription: "Not a dictionary") + throw DecodingError.typeMismatch([String : Any].self, context) + } + + self.currentIndex += 1 + let container = _FirebaseKeyedDecodingContainer(referencing: self.decoder, wrapping: dictionary) + return KeyedDecodingContainer(container) + } + + public mutating func nestedUnkeyedContainer() throws -> UnkeyedDecodingContainer { + self.decoder.codingPath.append(_FirebaseKey(index: self.currentIndex)) + defer { self.decoder.codingPath.removeLast() } + + guard !self.isAtEnd else { + throw DecodingError.valueNotFound(UnkeyedDecodingContainer.self, + DecodingError.Context(codingPath: self.codingPath, + debugDescription: "Cannot get nested unkeyed container -- unkeyed container is at end.")) + } + + let value = self.container[self.currentIndex] + guard !(value is NSNull) else { + throw DecodingError.valueNotFound(UnkeyedDecodingContainer.self, + DecodingError.Context(codingPath: self.codingPath, + debugDescription: "Cannot get keyed decoding container -- found null value instead.")) + } + + guard let array = value as? [Any] else { + let context = DecodingError.Context(codingPath: codingPath, debugDescription: "Not an array") + throw DecodingError.typeMismatch([String : Any].self, context) + } + + self.currentIndex += 1 + return _FirebaseUnkeyedDecodingContainer(referencing: self.decoder, wrapping: array) + } + + public mutating func superDecoder() throws -> Decoder { + self.decoder.codingPath.append(_FirebaseKey(index: self.currentIndex)) + defer { self.decoder.codingPath.removeLast() } + + guard !self.isAtEnd else { + throw DecodingError.valueNotFound(Decoder.self, DecodingError.Context(codingPath: self.codingPath, + debugDescription: "Cannot get superDecoder() -- unkeyed container is at end.")) + } + + let value = self.container[self.currentIndex] + self.currentIndex += 1 + return _FirebaseDecoder(referencing: value, at: decoder.codingPath, options: decoder.options) + } +} + +extension _FirebaseDecoder : SingleValueDecodingContainer { + // MARK: SingleValueDecodingContainer Methods + private func expectNonNull(_ type: T.Type) throws { + guard !decodeNil() else { + throw DecodingError.valueNotFound(type, DecodingError.Context(codingPath: codingPath, debugDescription: "Expected \(type) but found null value instead.")) + } + } + + public func decodeNil() -> Bool { + return storage.topContainer is NSNull + } + + public func decode(_ type: Bool.Type) throws -> Bool { + try expectNonNull(Bool.self) + return try self.unbox(self.storage.topContainer, as: Bool.self)! + } + + public func decode(_ type: Int.Type) throws -> Int { + try expectNonNull(Int.self) + return try self.unbox(self.storage.topContainer, as: Int.self)! + } + + public func decode(_ type: Int8.Type) throws -> Int8 { + try expectNonNull(Int8.self) + return try self.unbox(self.storage.topContainer, as: Int8.self)! + } + + public func decode(_ type: Int16.Type) throws -> Int16 { + try expectNonNull(Int16.self) + return try self.unbox(self.storage.topContainer, as: Int16.self)! + } + + public func decode(_ type: Int32.Type) throws -> Int32 { + try expectNonNull(Int32.self) + return try self.unbox(self.storage.topContainer, as: Int32.self)! + } + + public func decode(_ type: Int64.Type) throws -> Int64 { + try expectNonNull(Int64.self) + return try self.unbox(self.storage.topContainer, as: Int64.self)! + } + + public func decode(_ type: UInt.Type) throws -> UInt { + try expectNonNull(UInt.self) + return try self.unbox(self.storage.topContainer, as: UInt.self)! + } + + public func decode(_ type: UInt8.Type) throws -> UInt8 { + try expectNonNull(UInt8.self) + return try self.unbox(self.storage.topContainer, as: UInt8.self)! + } + + public func decode(_ type: UInt16.Type) throws -> UInt16 { + try expectNonNull(UInt16.self) + return try self.unbox(self.storage.topContainer, as: UInt16.self)! + } + + public func decode(_ type: UInt32.Type) throws -> UInt32 { + try expectNonNull(UInt32.self) + return try self.unbox(self.storage.topContainer, as: UInt32.self)! + } + + public func decode(_ type: UInt64.Type) throws -> UInt64 { + try expectNonNull(UInt64.self) + return try self.unbox(self.storage.topContainer, as: UInt64.self)! + } + + public func decode(_ type: Float.Type) throws -> Float { + try expectNonNull(Float.self) + return try self.unbox(self.storage.topContainer, as: Float.self)! + } + + public func decode(_ type: Double.Type) throws -> Double { + try expectNonNull(Double.self) + return try self.unbox(self.storage.topContainer, as: Double.self)! + } + + public func decode(_ type: String.Type) throws -> String { + try expectNonNull(String.self) + return try self.unbox(self.storage.topContainer, as: String.self)! + } + + public func decode(_ type: T.Type) throws -> T { + try expectNonNull(T.self) + return try self.unbox(self.storage.topContainer, as: T.self)! + } +} + +extension _FirebaseDecoder { + /// Returns the given value unboxed from a container. + func unbox(_ value: Any, as type: Bool.Type) throws -> Bool? { + guard !(value is NSNull) else { return nil } + + if let number = value as? NSNumber { + // TODO: Add a flag to coerce non-boolean numbers into Bools? + if number === kCFBooleanTrue as NSNumber { + return true + } else if number === kCFBooleanFalse as NSNumber { + return false + } + + /* FIXME: If swift-corelibs-foundation doesn't change to use NSNumber, this code path will need to be included and tested: + } else if let bool = value as? Bool { + return bool + */ + + } + + throw DecodingError._typeMismatch(at: self.codingPath, expectation: type, reality: value) + } + + func unbox(_ value: Any, as type: Int.Type) throws -> Int? { + guard !(value is NSNull) else { return nil } + + guard let number = value as? NSNumber, number !== kCFBooleanTrue, number !== kCFBooleanFalse else { + throw DecodingError._typeMismatch(at: self.codingPath, expectation: type, reality: value) + } + + let int = number.intValue + guard NSNumber(value: int) == number else { + throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: self.codingPath, debugDescription: "Parsed JSON number <\(number)> does not fit in \(type).")) + } + + return int + } + + func unbox(_ value: Any, as type: Int8.Type) throws -> Int8? { + guard !(value is NSNull) else { return nil } + + guard let number = value as? NSNumber, number !== kCFBooleanTrue, number !== kCFBooleanFalse else { + throw DecodingError._typeMismatch(at: self.codingPath, expectation: type, reality: value) + } + + let int8 = number.int8Value + guard NSNumber(value: int8) == number else { + throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: self.codingPath, debugDescription: "Parsed JSON number <\(number)> does not fit in \(type).")) + } + + return int8 + } + + func unbox(_ value: Any, as type: Int16.Type) throws -> Int16? { + guard !(value is NSNull) else { return nil } + + guard let number = value as? NSNumber, number !== kCFBooleanTrue, number !== kCFBooleanFalse else { + throw DecodingError._typeMismatch(at: self.codingPath, expectation: type, reality: value) + } + + let int16 = number.int16Value + guard NSNumber(value: int16) == number else { + throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: self.codingPath, debugDescription: "Parsed JSON number <\(number)> does not fit in \(type).")) + } + + return int16 + } + + func unbox(_ value: Any, as type: Int32.Type) throws -> Int32? { + guard !(value is NSNull) else { return nil } + + guard let number = value as? NSNumber, number !== kCFBooleanTrue, number !== kCFBooleanFalse else { + throw DecodingError._typeMismatch(at: self.codingPath, expectation: type, reality: value) + } + + let int32 = number.int32Value + guard NSNumber(value: int32) == number else { + throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: self.codingPath, debugDescription: "Parsed JSON number <\(number)> does not fit in \(type).")) + } + + return int32 + } + + func unbox(_ value: Any, as type: Int64.Type) throws -> Int64? { + guard !(value is NSNull) else { return nil } + + guard let number = value as? NSNumber, number !== kCFBooleanTrue, number !== kCFBooleanFalse else { + throw DecodingError._typeMismatch(at: self.codingPath, expectation: type, reality: value) + } + + let int64 = number.int64Value + guard NSNumber(value: int64) == number else { + throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: self.codingPath, debugDescription: "Parsed JSON number <\(number)> does not fit in \(type).")) + } + + return int64 + } + + func unbox(_ value: Any, as type: UInt.Type) throws -> UInt? { + guard !(value is NSNull) else { return nil } + + guard let number = value as? NSNumber, number !== kCFBooleanTrue, number !== kCFBooleanFalse else { + throw DecodingError._typeMismatch(at: self.codingPath, expectation: type, reality: value) + } + + let uint = number.uintValue + guard NSNumber(value: uint) == number else { + throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: self.codingPath, debugDescription: "Parsed JSON number <\(number)> does not fit in \(type).")) + } + + return uint + } + + func unbox(_ value: Any, as type: UInt8.Type) throws -> UInt8? { + guard !(value is NSNull) else { return nil } + + guard let number = value as? NSNumber, number !== kCFBooleanTrue, number !== kCFBooleanFalse else { + throw DecodingError._typeMismatch(at: self.codingPath, expectation: type, reality: value) + } + + let uint8 = number.uint8Value + guard NSNumber(value: uint8) == number else { + throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: self.codingPath, debugDescription: "Parsed JSON number <\(number)> does not fit in \(type).")) + } + + return uint8 + } + + func unbox(_ value: Any, as type: UInt16.Type) throws -> UInt16? { + guard !(value is NSNull) else { return nil } + + guard let number = value as? NSNumber, number !== kCFBooleanTrue, number !== kCFBooleanFalse else { + throw DecodingError._typeMismatch(at: self.codingPath, expectation: type, reality: value) + } + + let uint16 = number.uint16Value + guard NSNumber(value: uint16) == number else { + throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: self.codingPath, debugDescription: "Parsed JSON number <\(number)> does not fit in \(type).")) + } + + return uint16 + } + + func unbox(_ value: Any, as type: UInt32.Type) throws -> UInt32? { + guard !(value is NSNull) else { return nil } + + guard let number = value as? NSNumber, number !== kCFBooleanTrue, number !== kCFBooleanFalse else { + throw DecodingError._typeMismatch(at: self.codingPath, expectation: type, reality: value) + } + + let uint32 = number.uint32Value + guard NSNumber(value: uint32) == number else { + throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: self.codingPath, debugDescription: "Parsed JSON number <\(number)> does not fit in \(type).")) + } + + return uint32 + } + + func unbox(_ value: Any, as type: UInt64.Type) throws -> UInt64? { + guard !(value is NSNull) else { return nil } + + guard let number = value as? NSNumber, number !== kCFBooleanTrue, number !== kCFBooleanFalse else { + throw DecodingError._typeMismatch(at: self.codingPath, expectation: type, reality: value) + } + + let uint64 = number.uint64Value + guard NSNumber(value: uint64) == number else { + throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: self.codingPath, debugDescription: "Parsed JSON number <\(number)> does not fit in \(type).")) + } + + return uint64 + } + + func unbox(_ value: Any, as type: Float.Type) throws -> Float? { + guard !(value is NSNull) else { return nil } + + if let number = value as? NSNumber, number !== kCFBooleanTrue, number !== kCFBooleanFalse { + // We are willing to return a Float by losing precision: + // * If the original value was integral, + // * and the integral value was > Float.greatestFiniteMagnitude, we will fail + // * and the integral value was <= Float.greatestFiniteMagnitude, we are willing to lose precision past 2^24 + // * If it was a Float, you will get back the precise value + // * If it was a Double or Decimal, you will get back the nearest approximation if it will fit + let double = number.doubleValue + guard abs(double) <= Double(Float.greatestFiniteMagnitude) else { + throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: self.codingPath, debugDescription: "Parsed JSON number \(number) does not fit in \(type).")) + } + + return Float(double) + + /* FIXME: If swift-corelibs-foundation doesn't change to use NSNumber, this code path will need to be included and tested: + } else if let double = value as? Double { + if abs(double) <= Double(Float.max) { + return Float(double) + } + overflow = true + } else if let int = value as? Int { + if let float = Float(exactly: int) { + return float + } + overflow = true + */ + + } + + throw DecodingError._typeMismatch(at: self.codingPath, expectation: type, reality: value) + } + + func unbox(_ value: Any, as type: Double.Type) throws -> Double? { + guard !(value is NSNull) else { return nil } + + if let number = value as? NSNumber, number !== kCFBooleanTrue, number !== kCFBooleanFalse { + // We are always willing to return the number as a Double: + // * If the original value was integral, it is guaranteed to fit in a Double; we are willing to lose precision past 2^53 if you encoded a UInt64 but requested a Double + // * If it was a Float or Double, you will get back the precise value + // * If it was Decimal, you will get back the nearest approximation + return number.doubleValue + + /* FIXME: If swift-corelibs-foundation doesn't change to use NSNumber, this code path will need to be included and tested: + } else if let double = value as? Double { + return double + } else if let int = value as? Int { + if let double = Double(exactly: int) { + return double + } + overflow = true + */ + + } + + throw DecodingError._typeMismatch(at: self.codingPath, expectation: type, reality: value) + } + + func unbox(_ value: Any, as type: String.Type) throws -> String? { + guard !(value is NSNull) else { return nil } + + guard let string = value as? String else { + throw DecodingError._typeMismatch(at: self.codingPath, expectation: type, reality: value) + } + + return string + } + + func unbox(_ value: Any, as type: Date.Type) throws -> Date? { + guard !(value is NSNull) else { return nil } + + guard let options = options.dateDecodingStrategy else { + guard let date = value as? Date else { + throw DecodingError._typeMismatch(at: codingPath, expectation: type, reality: value) + } + return date + } + + switch options { + case .deferredToDate: + self.storage.push(container: value) + let date = try Date(from: self) + self.storage.popContainer() + return date + + case .secondsSince1970: + let double = try self.unbox(value, as: Double.self)! + return Date(timeIntervalSince1970: double) + + case .millisecondsSince1970: + let double = try self.unbox(value, as: Double.self)! + return Date(timeIntervalSince1970: double / 1000.0) + + case .iso8601: + if #available(OSX 10.12, iOS 10.0, watchOS 3.0, tvOS 10.0, *) { + let string = try self.unbox(value, as: String.self)! + guard let date = _iso8601Formatter.date(from: string) else { + throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: self.codingPath, debugDescription: "Expected date string to be ISO8601-formatted.")) + } + + return date + } else { + fatalError("ISO8601DateFormatter is unavailable on this platform.") + } + + case .formatted(let formatter): + let string = try self.unbox(value, as: String.self)! + guard let date = formatter.date(from: string) else { + throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: self.codingPath, debugDescription: "Date string does not match format expected by formatter.")) + } + + return date + + case .custom(let closure): + self.storage.push(container: value) + let date = try closure(self) + self.storage.popContainer() + return date + } + } + + func unbox(_ value: Any, as type: Data.Type) throws -> Data? { + guard !(value is NSNull) else { return nil } + + guard let options = options.dataDecodingStrategy else { + guard let data = value as? Data else { + throw DecodingError._typeMismatch(at: codingPath, expectation: type, reality: value) + } + + return data + } + + switch options { + case .deferredToData: + self.storage.push(container: value) + let data = try Data(from: self) + self.storage.popContainer() + return data + + case .base64: + guard let string = value as? String else { + throw DecodingError._typeMismatch(at: self.codingPath, expectation: type, reality: value) + } + + guard let data = Data(base64Encoded: string) else { + throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: self.codingPath, debugDescription: "Encountered Data is not valid Base64.")) + } + + return data + + case .custom(let closure): + self.storage.push(container: value) + let data = try closure(self) + self.storage.popContainer() + return data + } + } + + func unbox(_ value: Any, as type: Decimal.Type) throws -> Decimal? { + guard !(value is NSNull) else { return nil } + + // Attempt to bridge from NSDecimalNumber. + if let decimal = value as? Decimal { + return decimal + } else { + let doubleValue = try self.unbox(value, as: Double.self)! + return Decimal(doubleValue) + } + } + + func unbox(_ value: Any, as type: T.Type) throws -> T? { + let decoded: T + if T.self == Date.self || T.self == NSDate.self { + guard let date = try self.unbox(value, as: Date.self) else { return nil } + decoded = date as! T + } else if T.self == Data.self || T.self == NSData.self { + guard let data = try self.unbox(value, as: Data.self) else { return nil } + decoded = data as! T + } else if T.self == URL.self || T.self == NSURL.self { + guard let urlString = try self.unbox(value, as: String.self) else { + return nil + } + + guard let url = URL(string: urlString) else { + throw DecodingError.dataCorrupted(DecodingError.Context(codingPath: self.codingPath, + debugDescription: "Invalid URL string.")) + } + + decoded = (url as! T) + } else if T.self == Decimal.self || T.self == NSDecimalNumber.self { + guard let decimal = try self.unbox(value, as: Decimal.self) else { return nil } + decoded = decimal as! T + } else if options.skipFirestoreTypes && (T.self is FirestoreDecodable.Type) { + decoded = value as! T + } else { + self.storage.push(container: value) + decoded = try T(from: self) + self.storage.popContainer() + } + + return decoded + } +} + +@available(OSX 10.12, iOS 10.0, watchOS 3.0, tvOS 10.0, *) +internal var _iso8601Formatter: ISO8601DateFormatter = { + let formatter = ISO8601DateFormatter() + formatter.formatOptions = .withInternetDateTime + return formatter +}() diff --git a/FoodApp/Pods/CodableFirebase/CodableFirebase/Encoder.swift b/FoodApp/Pods/CodableFirebase/CodableFirebase/Encoder.swift new file mode 100644 index 0000000..69fe0ef --- /dev/null +++ b/FoodApp/Pods/CodableFirebase/CodableFirebase/Encoder.swift @@ -0,0 +1,589 @@ +// +// Encoder.swift +// CodableFirebase +// +// Created by Oleksii on 27/12/2017. +// Copyright © 2017 ViolentOctopus. All rights reserved. +// + +import Foundation + +class _FirebaseEncoder : Encoder { + /// Options set on the top-level encoder to pass down the encoding hierarchy. + struct _Options { + let dateEncodingStrategy: FirebaseEncoder.DateEncodingStrategy? + let dataEncodingStrategy: FirebaseEncoder.DataEncodingStrategy? + let skipFirestoreTypes: Bool + let userInfo: [CodingUserInfoKey : Any] + } + + fileprivate var storage: _FirebaseEncodingStorage + fileprivate let options: _Options + fileprivate(set) public var codingPath: [CodingKey] + + public var userInfo: [CodingUserInfoKey : Any] { + return options.userInfo + } + + init(options: _Options, codingPath: [CodingKey] = []) { + self.storage = _FirebaseEncodingStorage() + self.codingPath = codingPath + self.options = options + } + + /// Returns whether a new element can be encoded at this coding path. + /// + /// `true` if an element has not yet been encoded at this coding path; `false` otherwise. + fileprivate var canEncodeNewValue: Bool { + // Every time a new value gets encoded, the key it's encoded for is pushed onto the coding path (even if it's a nil key from an unkeyed container). + // At the same time, every time a container is requested, a new value gets pushed onto the storage stack. + // If there are more values on the storage stack than on the coding path, it means the value is requesting more than one container, which violates the precondition. + // + // This means that anytime something that can request a new container goes onto the stack, we MUST push a key onto the coding path. + // Things which will not request containers do not need to have the coding path extended for them (but it doesn't matter if it is, because they will not reach here). + return self.storage.count == self.codingPath.count + } + + // MARK: - Encoder Methods + public func container(keyedBy: Key.Type) -> KeyedEncodingContainer { + // If an existing keyed container was already requested, return that one. + let topContainer: NSMutableDictionary + if canEncodeNewValue { + // We haven't yet pushed a container at this level; do so here. + topContainer = storage.pushKeyedContainer() + } else { + guard let container = self.storage.containers.last as? NSMutableDictionary else { + preconditionFailure("Attempt to push new keyed encoding container when already previously encoded at this path.") + } + + topContainer = container + } + + let container = _FirebaseKeyedEncodingContainer(referencing: self, codingPath: self.codingPath, wrapping: topContainer) + return KeyedEncodingContainer(container) + } + + public func unkeyedContainer() -> UnkeyedEncodingContainer { + // If an existing unkeyed container was already requested, return that one. + let topContainer: NSMutableArray + if canEncodeNewValue { + // We haven't yet pushed a container at this level; do so here. + topContainer = self.storage.pushUnkeyedContainer() + } else { + guard let container = self.storage.containers.last as? NSMutableArray else { + preconditionFailure("Attempt to push new unkeyed encoding container when already previously encoded at this path.") + } + + topContainer = container + } + + return _FirebaseUnkeyedEncodingContainer(referencing: self, codingPath: self.codingPath, wrapping: topContainer) + } + + public func singleValueContainer() -> SingleValueEncodingContainer { + return self + } +} + +fileprivate struct _FirebaseEncodingStorage { + // MARK: Properties + /// The container stack. + /// Elements may be any one of the plist types (NSNumber, NSString, NSDate, NSArray, NSDictionary). + private(set) fileprivate var containers: [NSObject] = [] + + // MARK: - Initialization + /// Initializes `self` with no containers. + fileprivate init() {} + + // MARK: - Modifying the Stack + fileprivate var count: Int { + return containers.count + } + + fileprivate mutating func pushKeyedContainer() -> NSMutableDictionary { + let dictionary = NSMutableDictionary() + containers.append(dictionary) + return dictionary + } + + fileprivate mutating func pushUnkeyedContainer() -> NSMutableArray { + let array = NSMutableArray() + containers.append(array) + return array + } + + fileprivate mutating func push(container: NSObject) { + containers.append(container) + } + + fileprivate mutating func popContainer() -> NSObject { + precondition(containers.count > 0, "Empty container stack.") + return containers.popLast()! + } +} + +fileprivate struct _FirebaseKeyedEncodingContainer : KeyedEncodingContainerProtocol { + typealias Key = K + + // MARK: Properties + /// A reference to the encoder we're writing to. + private let encoder: _FirebaseEncoder + + /// A reference to the container we're writing to. + private let container: NSMutableDictionary + + /// The path of coding keys taken to get to this point in encoding. + private(set) public var codingPath: [CodingKey] + + // MARK: - Initialization + /// Initializes `self` with the given references. + fileprivate init(referencing encoder: _FirebaseEncoder, codingPath: [CodingKey], wrapping container: NSMutableDictionary) { + self.encoder = encoder + self.codingPath = codingPath + self.container = container + } + + // MARK: - KeyedEncodingContainerProtocol Methods + public mutating func encodeNil(forKey key: Key) throws { container[key.stringValue] = NSNull() } + public mutating func encode(_ value: Bool, forKey key: Key) throws { container[key.stringValue] = encoder.box(value) } + public mutating func encode(_ value: Int, forKey key: Key) throws { container[key.stringValue] = encoder.box(value) } + public mutating func encode(_ value: Int8, forKey key: Key) throws { container[key.stringValue] = encoder.box(value) } + public mutating func encode(_ value: Int16, forKey key: Key) throws { container[key.stringValue] = encoder.box(value) } + public mutating func encode(_ value: Int32, forKey key: Key) throws { container[key.stringValue] = encoder.box(value) } + public mutating func encode(_ value: Int64, forKey key: Key) throws { container[key.stringValue] = encoder.box(value) } + public mutating func encode(_ value: UInt, forKey key: Key) throws { container[key.stringValue] = encoder.box(value) } + public mutating func encode(_ value: UInt8, forKey key: Key) throws { container[key.stringValue] = encoder.box(value) } + public mutating func encode(_ value: UInt16, forKey key: Key) throws { container[key.stringValue] = encoder.box(value) } + public mutating func encode(_ value: UInt32, forKey key: Key) throws { container[key.stringValue] = encoder.box(value) } + public mutating func encode(_ value: UInt64, forKey key: Key) throws { container[key.stringValue] = encoder.box(value) } + public mutating func encode(_ value: String, forKey key: Key) throws { container[key.stringValue] = encoder.box(value) } + public mutating func encode(_ value: Float, forKey key: Key) throws { container[key.stringValue] = encoder.box(value) } + public mutating func encode(_ value: Double, forKey key: Key) throws { container[key.stringValue] = encoder.box(value) } + + public mutating func encode(_ value: T, forKey key: Key) throws { + encoder.codingPath.append(key) + defer { encoder.codingPath.removeLast() } + container[key.stringValue] = try encoder.box(value) + } + + public mutating func nestedContainer(keyedBy keyType: NestedKey.Type, forKey key: Key) -> KeyedEncodingContainer { + let dictionary = NSMutableDictionary() + self.container[key.stringValue] = dictionary + + codingPath.append(key) + defer { codingPath.removeLast() } + + let container = _FirebaseKeyedEncodingContainer(referencing: encoder, codingPath: codingPath, wrapping: dictionary) + return KeyedEncodingContainer(container) + } + + public mutating func nestedUnkeyedContainer(forKey key: Key) -> UnkeyedEncodingContainer { + let array = NSMutableArray() + container[key.stringValue] = array + + codingPath.append(key) + defer { codingPath.removeLast() } + return _FirebaseUnkeyedEncodingContainer(referencing: encoder, codingPath: codingPath, wrapping: array) + } + + public mutating func superEncoder() -> Encoder { + return _FirebaseReferencingEncoder(referencing: encoder, at: _FirebaseKey.super, wrapping: container) + } + + public mutating func superEncoder(forKey key: Key) -> Encoder { + return _FirebaseReferencingEncoder(referencing: encoder, at: key, wrapping: container) + } +} + +fileprivate struct _FirebaseUnkeyedEncodingContainer : UnkeyedEncodingContainer { + // MARK: Properties + /// A reference to the encoder we're writing to. + private let encoder: _FirebaseEncoder + + /// A reference to the container we're writing to. + private let container: NSMutableArray + + /// The path of coding keys taken to get to this point in encoding. + private(set) public var codingPath: [CodingKey] + + /// The number of elements encoded into the container. + public var count: Int { + return container.count + } + + // MARK: - Initialization + /// Initializes `self` with the given references. + fileprivate init(referencing encoder: _FirebaseEncoder, codingPath: [CodingKey], wrapping container: NSMutableArray) { + self.encoder = encoder + self.codingPath = codingPath + self.container = container + } + + // MARK: - UnkeyedEncodingContainer Methods + public mutating func encodeNil() throws { container.add(NSNull()) } + public mutating func encode(_ value: Bool) throws { container.add(self.encoder.box(value)) } + public mutating func encode(_ value: Int) throws { container.add(self.encoder.box(value)) } + public mutating func encode(_ value: Int8) throws { container.add(self.encoder.box(value)) } + public mutating func encode(_ value: Int16) throws { container.add(self.encoder.box(value)) } + public mutating func encode(_ value: Int32) throws { container.add(self.encoder.box(value)) } + public mutating func encode(_ value: Int64) throws { container.add(self.encoder.box(value)) } + public mutating func encode(_ value: UInt) throws { container.add(self.encoder.box(value)) } + public mutating func encode(_ value: UInt8) throws { container.add(self.encoder.box(value)) } + public mutating func encode(_ value: UInt16) throws { container.add(self.encoder.box(value)) } + public mutating func encode(_ value: UInt32) throws { container.add(self.encoder.box(value)) } + public mutating func encode(_ value: UInt64) throws { container.add(self.encoder.box(value)) } + public mutating func encode(_ value: Float) throws { container.add(self.encoder.box(value)) } + public mutating func encode(_ value: Double) throws { container.add(self.encoder.box(value)) } + public mutating func encode(_ value: String) throws { container.add(self.encoder.box(value)) } + + public mutating func encode(_ value: T) throws { + encoder.codingPath.append(_FirebaseKey(index: count)) + defer { encoder.codingPath.removeLast() } + container.add(try encoder.box(value)) + } + + public mutating func nestedContainer(keyedBy keyType: NestedKey.Type) -> KeyedEncodingContainer { + self.codingPath.append(_FirebaseKey(index: self.count)) + defer { self.codingPath.removeLast() } + + let dictionary = NSMutableDictionary() + self.container.add(dictionary) + + let container = _FirebaseKeyedEncodingContainer(referencing: self.encoder, codingPath: self.codingPath, wrapping: dictionary) + return KeyedEncodingContainer(container) + } + + public mutating func nestedUnkeyedContainer() -> UnkeyedEncodingContainer { + self.codingPath.append(_FirebaseKey(index: self.count)) + defer { self.codingPath.removeLast() } + + let array = NSMutableArray() + self.container.add(array) + return _FirebaseUnkeyedEncodingContainer(referencing: self.encoder, codingPath: self.codingPath, wrapping: array) + } + + public mutating func superEncoder() -> Encoder { + return _FirebaseReferencingEncoder(referencing: encoder, at: container.count, wrapping: container) + } +} + +struct _FirebaseKey : CodingKey { + public var stringValue: String + public var intValue: Int? + + public init?(stringValue: String) { + self.stringValue = stringValue + self.intValue = nil + } + + public init?(intValue: Int) { + self.stringValue = "\(intValue)" + self.intValue = intValue + } + + init(index: Int) { + self.stringValue = "Index \(index)" + self.intValue = index + } + + static let `super` = _FirebaseKey(stringValue: "super")! +} + +extension _FirebaseEncoder { + + /// Returns the given value boxed in a container appropriate for pushing onto the container stack. + fileprivate func box(_ value: Bool) -> NSObject { return NSNumber(value: value) } + fileprivate func box(_ value: Int) -> NSObject { return NSNumber(value: value) } + fileprivate func box(_ value: Int8) -> NSObject { return NSNumber(value: value) } + fileprivate func box(_ value: Int16) -> NSObject { return NSNumber(value: value) } + fileprivate func box(_ value: Int32) -> NSObject { return NSNumber(value: value) } + fileprivate func box(_ value: Int64) -> NSObject { return NSNumber(value: value) } + fileprivate func box(_ value: UInt) -> NSObject { return NSNumber(value: value) } + fileprivate func box(_ value: UInt8) -> NSObject { return NSNumber(value: value) } + fileprivate func box(_ value: UInt16) -> NSObject { return NSNumber(value: value) } + fileprivate func box(_ value: UInt32) -> NSObject { return NSNumber(value: value) } + fileprivate func box(_ value: UInt64) -> NSObject { return NSNumber(value: value) } + fileprivate func box(_ value: Float) -> NSObject { return NSNumber(value: value) } + fileprivate func box(_ value: Double) -> NSObject { return NSNumber(value: value) } + fileprivate func box(_ value: String) -> NSObject { return NSString(string: value) } + + fileprivate func box(_ value: T) throws -> NSObject { + return try self.box_(value) ?? NSDictionary() + } + + fileprivate func box(_ date: Date) throws -> NSObject { + guard let options = options.dateEncodingStrategy else { return date as NSDate } + + switch options { + case .deferredToDate: + // Must be called with a surrounding with(pushedKey:) call. + try date.encode(to: self) + return self.storage.popContainer() + + case .secondsSince1970: + return NSNumber(value: date.timeIntervalSince1970) + + case .millisecondsSince1970: + return NSNumber(value: 1000.0 * date.timeIntervalSince1970) + + case .iso8601: + if #available(OSX 10.12, iOS 10.0, watchOS 3.0, tvOS 10.0, *) { + return NSString(string: _iso8601Formatter.string(from: date)) + } else { + fatalError("ISO8601DateFormatter is unavailable on this platform.") + } + + case .formatted(let formatter): + return NSString(string: formatter.string(from: date)) + + case .custom(let closure): + let depth = self.storage.count + try closure(date, self) + + guard self.storage.count > depth else { + // The closure didn't encode anything. Return the default keyed container. + return NSDictionary() + } + + // We can pop because the closure encoded something. + return self.storage.popContainer() + } + } + + fileprivate func box(_ data: Data) throws -> NSObject { + guard let options = options.dataEncodingStrategy else { return data as NSData } + + switch options { + case .deferredToData: + // Must be called with a surrounding with(pushedKey:) call. + try data.encode(to: self) + return self.storage.popContainer() + + case .base64: + return NSString(string: data.base64EncodedString()) + + case .custom(let closure): + let depth = self.storage.count + try closure(data, self) + + guard self.storage.count > depth else { + // The closure didn't encode anything. Return the default keyed container. + return NSDictionary() + } + + // We can pop because the closure encoded something. + return self.storage.popContainer() + } + } + + func box_(_ value: T) throws -> NSObject? { + if T.self == Date.self || T.self == NSDate.self { + return try self.box((value as! Date)) + } else if T.self == Data.self || T.self == NSData.self { + return try self.box((value as! Data)) + } else if T.self == URL.self || T.self == NSURL.self { + return self.box((value as! URL).absoluteString) + } else if T.self == Decimal.self || T.self == NSDecimalNumber.self { + return (value as! NSDecimalNumber) + } else if options.skipFirestoreTypes && (value is FirestoreEncodable) { + guard let value = value as? NSObject else { + throw DocumentReferenceError.typeIsNotNSObject + } + return value + } + + // The value should request a container from the _FirebaseEncoder. + let depth = self.storage.count + do { + try value.encode(to: self) + } catch { + // If the value pushed a container before throwing, pop it back off to restore state. + if self.storage.count > depth { + let _ = self.storage.popContainer() + } + + throw error + } + + // The top container should be a new container. + guard self.storage.count > depth else { + return nil + } + + return storage.popContainer() + } +} + +extension _FirebaseEncoder : SingleValueEncodingContainer { + // MARK: - SingleValueEncodingContainer Methods + private func assertCanEncodeNewValue() { + precondition(canEncodeNewValue, "Attempt to encode value through single value container when previously value already encoded.") + } + + public func encodeNil() throws { + assertCanEncodeNewValue() + storage.push(container: NSNull()) + } + + public func encode(_ value: Bool) throws { + assertCanEncodeNewValue() + storage.push(container: box(value)) + } + + public func encode(_ value: Int) throws { + assertCanEncodeNewValue() + storage.push(container: box(value)) + } + + public func encode(_ value: Int8) throws { + assertCanEncodeNewValue() + storage.push(container: box(value)) + } + + public func encode(_ value: Int16) throws { + assertCanEncodeNewValue() + storage.push(container: box(value)) + } + + public func encode(_ value: Int32) throws { + assertCanEncodeNewValue() + storage.push(container: box(value)) + } + + public func encode(_ value: Int64) throws { + assertCanEncodeNewValue() + storage.push(container: box(value)) + } + + public func encode(_ value: UInt) throws { + assertCanEncodeNewValue() + storage.push(container: box(value)) + } + + public func encode(_ value: UInt8) throws { + assertCanEncodeNewValue() + storage.push(container: box(value)) + } + + public func encode(_ value: UInt16) throws { + assertCanEncodeNewValue() + storage.push(container: box(value)) + } + + public func encode(_ value: UInt32) throws { + assertCanEncodeNewValue() + storage.push(container: box(value)) + } + + public func encode(_ value: UInt64) throws { + assertCanEncodeNewValue() + storage.push(container: box(value)) + } + + public func encode(_ value: String) throws { + assertCanEncodeNewValue() + storage.push(container: box(value)) + } + + public func encode(_ value: Float) throws { + assertCanEncodeNewValue() + storage.push(container: box(value)) + } + + public func encode(_ value: Double) throws { + assertCanEncodeNewValue() + storage.push(container: box(value)) + } + + public func encode(_ value: T) throws { + assertCanEncodeNewValue() + try storage.push(container: box(value)) + } +} + +fileprivate class _FirebaseReferencingEncoder : _FirebaseEncoder { + // MARK: Reference types. + /// The type of container we're referencing. + private enum Reference { + /// Referencing a specific index in an array container. + case array(NSMutableArray, Int) + + /// Referencing a specific key in a dictionary container. + case dictionary(NSMutableDictionary, String) + } + + // MARK: - Properties + /// The encoder we're referencing. + private let encoder: _FirebaseEncoder + + /// The container reference itself. + private let reference: Reference + + // MARK: - Initialization + /// Initializes `self` by referencing the given array container in the given encoder. + fileprivate init(referencing encoder: _FirebaseEncoder, at index: Int, wrapping array: NSMutableArray) { + self.encoder = encoder + self.reference = .array(array, index) + super.init(options: encoder.options, codingPath: encoder.codingPath) + + self.codingPath.append(_FirebaseKey(index: index)) + } + + /// Initializes `self` by referencing the given dictionary container in the given encoder. + fileprivate init(referencing encoder: _FirebaseEncoder, at key: CodingKey, wrapping dictionary: NSMutableDictionary) { + self.encoder = encoder + reference = .dictionary(dictionary, key.stringValue) + super.init(options: encoder.options, codingPath: encoder.codingPath) + codingPath.append(key) + } + + // MARK: - Coding Path Operations + fileprivate override var canEncodeNewValue: Bool { + // With a regular encoder, the storage and coding path grow together. + // A referencing encoder, however, inherits its parents coding path, as well as the key it was created for. + // We have to take this into account. + return storage.count == codingPath.count - encoder.codingPath.count - 1 + } + + // MARK: - Deinitialization + // Finalizes `self` by writing the contents of our storage to the referenced encoder's storage. + deinit { + let value: Any + switch storage.count { + case 0: value = NSDictionary() + case 1: value = self.storage.popContainer() + default: fatalError("Referencing encoder deallocated with multiple containers on stack.") + } + + switch self.reference { + case .array(let array, let index): + array.insert(value, at: index) + + case .dictionary(let dictionary, let key): + dictionary[NSString(string: key)] = value + } + } +} + +internal extension DecodingError { + internal static func _typeMismatch(at path: [CodingKey], expectation: Any.Type, reality: Any) -> DecodingError { + let description = "Expected to decode \(expectation) but found \(_typeDescription(of: reality)) instead." + return .typeMismatch(expectation, Context(codingPath: path, debugDescription: description)) + } + + fileprivate static func _typeDescription(of value: Any) -> String { + if value is NSNull { + return "a null value" + } else if value is NSNumber /* FIXME: If swift-corelibs-foundation isn't updated to use NSNumber, this check will be necessary: || value is Int || value is Double */ { + return "a number" + } else if value is String { + return "a string/data" + } else if value is [Any] { + return "an array" + } else if value is [String : Any] { + return "a dictionary" + } else { + return "\(type(of: value))" + } + } +} diff --git a/FoodApp/Pods/CodableFirebase/CodableFirebase/FirebaseDecoder.swift b/FoodApp/Pods/CodableFirebase/CodableFirebase/FirebaseDecoder.swift new file mode 100644 index 0000000..a6a20f0 --- /dev/null +++ b/FoodApp/Pods/CodableFirebase/CodableFirebase/FirebaseDecoder.swift @@ -0,0 +1,66 @@ +// +// FirebaseDecoder.swift +// CodableFirebase +// +// Created by Oleksii on 27/12/2017. +// Copyright © 2017 ViolentOctopus. All rights reserved. +// + +import Foundation + +open class FirebaseDecoder { + /// The strategy to use for decoding `Date` values. + public enum DateDecodingStrategy { + /// Defer to `Date` for decoding. This is the default strategy. + case deferredToDate + + /// Decode the `Date` as a UNIX timestamp from a JSON number. + case secondsSince1970 + + /// Decode the `Date` as UNIX millisecond timestamp from a JSON number. + case millisecondsSince1970 + + /// Decode the `Date` as an ISO-8601-formatted string (in RFC 3339 format). + @available(OSX 10.12, iOS 10.0, watchOS 3.0, tvOS 10.0, *) + case iso8601 + + /// Decode the `Date` as a string parsed by the given formatter. + case formatted(DateFormatter) + + /// Decode the `Date` as a custom value decoded by the given closure. + case custom((_ decoder: Decoder) throws -> Date) + } + + /// The strategy to use for decoding `Data` values. + public enum DataDecodingStrategy { + /// Defer to `Data` for decoding. + case deferredToData + + /// Decode the `Data` from a Base64-encoded string. This is the default strategy. + case base64 + + /// Decode the `Data` as a custom value decoded by the given closure. + case custom((_ decoder: Decoder) throws -> Data) + } + + public init() {} + + open var userInfo: [CodingUserInfoKey : Any] = [:] + open var dateDecodingStrategy: DateDecodingStrategy = .deferredToDate + open var dataDecodingStrategy: DataDecodingStrategy = .deferredToData + + open func decode(_ type: T.Type, from container: Any) throws -> T { + let options = _FirebaseDecoder._Options( + dateDecodingStrategy: dateDecodingStrategy, + dataDecodingStrategy: dataDecodingStrategy, + skipFirestoreTypes: false, + userInfo: userInfo + ) + let decoder = _FirebaseDecoder(referencing: container, options: options) + guard let value = try decoder.unbox(container, as: T.self) else { + throw DecodingError.valueNotFound(T.self, DecodingError.Context(codingPath: [], debugDescription: "The given dictionary was invalid")) + } + + return value + } +} diff --git a/FoodApp/Pods/CodableFirebase/CodableFirebase/FirebaseEncoder.swift b/FoodApp/Pods/CodableFirebase/CodableFirebase/FirebaseEncoder.swift new file mode 100644 index 0000000..49f79fc --- /dev/null +++ b/FoodApp/Pods/CodableFirebase/CodableFirebase/FirebaseEncoder.swift @@ -0,0 +1,72 @@ +// +// FirebaseEncoder.swift +// CodableFirebase +// +// Created by Oleksii on 27/12/2017. +// Copyright © 2017 ViolentOctopus. All rights reserved. +// + +import Foundation + +open class FirebaseEncoder { + /// The strategy to use for encoding `Date` values. + public enum DateEncodingStrategy { + /// Defer to `Date` for choosing an encoding. This is the default strategy. + case deferredToDate + + /// Encode the `Date` as a UNIX timestamp (as a JSON number). + case secondsSince1970 + + /// Encode the `Date` as UNIX millisecond timestamp (as a JSON number). + case millisecondsSince1970 + + /// Encode the `Date` as an ISO-8601-formatted string (in RFC 3339 format). + @available(OSX 10.12, iOS 10.0, watchOS 3.0, tvOS 10.0, *) + case iso8601 + + /// Encode the `Date` as a string formatted by the given formatter. + case formatted(DateFormatter) + + /// Encode the `Date` as a custom value encoded by the given closure. + /// + /// If the closure fails to encode a value into the given encoder, the encoder will encode an empty automatic container in its place. + case custom((Date, Encoder) throws -> Void) + } + + /// The strategy to use for encoding `Data` values. + public enum DataEncodingStrategy { + /// Defer to `Data` for choosing an encoding. + case deferredToData + + /// Encoded the `Data` as a Base64-encoded string. This is the default strategy. + case base64 + + /// Encode the `Data` as a custom value encoded by the given closure. + /// + /// If the closure fails to encode a value into the given encoder, the encoder will encode an empty automatic container in its place. + case custom((Data, Encoder) throws -> Void) + } + + public init() {} + + open var userInfo: [CodingUserInfoKey : Any] = [:] + open var dateEncodingStrategy: DateEncodingStrategy = .deferredToDate + open var dataEncodingStrategy: DataEncodingStrategy = .deferredToData + + open func encode(_ value: Value) throws -> Any { + let options = _FirebaseEncoder._Options( + dateEncodingStrategy: dateEncodingStrategy, + dataEncodingStrategy: dataEncodingStrategy, + skipFirestoreTypes: false, + userInfo: userInfo + ) + let encoder = _FirebaseEncoder(options: options) + guard let topLevel = try encoder.box_(value) else { + throw EncodingError.invalidValue(value, + EncodingError.Context(codingPath: [], + debugDescription: "Top-level \(Value.self) did not encode any values.")) + } + + return topLevel + } +} diff --git a/FoodApp/Pods/CodableFirebase/CodableFirebase/FirestoreDecoder.swift b/FoodApp/Pods/CodableFirebase/CodableFirebase/FirestoreDecoder.swift new file mode 100644 index 0000000..bf841de --- /dev/null +++ b/FoodApp/Pods/CodableFirebase/CodableFirebase/FirestoreDecoder.swift @@ -0,0 +1,95 @@ +// +// FirestoreDecoder.swift +// Slap +// +// Created by Oleksii on 21/10/2017. +// Copyright © 2017 Slap. All rights reserved. +// + +import Foundation + +public protocol FirestoreDecodable: Decodable {} +public protocol FirestoreEncodable: Encodable {} + +public typealias DocumentReferenceType = FirestoreDecodable & FirestoreEncodable +public typealias FieldValueType = FirestoreEncodable + +public protocol GeoPointType: FirestoreDecodable, FirestoreEncodable { + var latitude: Double { get } + var longitude: Double { get } + init(latitude: Double, longitude: Double) +} + +public protocol TimestampType: FirestoreDecodable, FirestoreEncodable { + init(date: Date) + func dateValue() -> Date +} + +open class FirestoreDecoder { + public init() {} + + open var userInfo: [CodingUserInfoKey : Any] = [:] + + open func decode(_ type: T.Type, from container: [String: Any]) throws -> T { + let options = _FirebaseDecoder._Options( + dateDecodingStrategy: nil, + dataDecodingStrategy: nil, + skipFirestoreTypes: true, + userInfo: userInfo + ) + let decoder = _FirebaseDecoder(referencing: container, options: options) + guard let value = try decoder.unbox(container, as: T.self) else { + throw DecodingError.valueNotFound(T.self, DecodingError.Context(codingPath: [], debugDescription: "The given dictionary was invalid")) + } + + return value + } +} + +enum GeoPointKeys: CodingKey { + case latitude, longitude +} + +extension GeoPointType { + public init(from decoder: Decoder) throws { + let container = try decoder.container(keyedBy: GeoPointKeys.self) + let latitude = try container.decode(Double.self, forKey: .latitude) + let longitude = try container.decode(Double.self, forKey: .longitude) + self.init(latitude: latitude, longitude: longitude) + } + + public func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: GeoPointKeys.self) + try container.encode(latitude, forKey: .latitude) + try container.encode(longitude, forKey: .longitude) + } +} + +enum DocumentReferenceError: Error { + case typeIsNotSupported + case typeIsNotNSObject +} + +extension FirestoreDecodable { + public init(from decoder: Decoder) throws { + throw DocumentReferenceError.typeIsNotSupported + } +} + +extension FirestoreEncodable { + public func encode(to encoder: Encoder) throws { + throw DocumentReferenceError.typeIsNotSupported + } +} + +extension TimestampType { + public init(from decoder: Decoder) throws { + let container = try decoder.singleValueContainer() + self.init(date: try container.decode(Date.self)) + } + + public func encode(to encoder: Encoder) throws { + var container = encoder.singleValueContainer() + try container.encode(self.dateValue()) + } +} diff --git a/FoodApp/Pods/CodableFirebase/CodableFirebase/FirestoreEncoder.swift b/FoodApp/Pods/CodableFirebase/CodableFirebase/FirestoreEncoder.swift new file mode 100644 index 0000000..d88e5cb --- /dev/null +++ b/FoodApp/Pods/CodableFirebase/CodableFirebase/FirestoreEncoder.swift @@ -0,0 +1,44 @@ +// +// CodableFirestore.swift +// Slap +// +// Created by Oleksii on 20/10/2017. +// Copyright © 2017 Slap. All rights reserved. +// + +import Foundation + +open class FirestoreEncoder { + public init() {} + + open var userInfo: [CodingUserInfoKey : Any] = [:] + + open func encode(_ value: Value) throws -> [String: Any] { + let topLevel = try encodeToTopLevelContainer(value) + switch topLevel { + case let top as [String: Any]: + return top + default: + throw EncodingError.invalidValue(value, + EncodingError.Context(codingPath: [], + debugDescription: "Top-level \(Value.self) encoded not as dictionary.")) + } + } + + internal func encodeToTopLevelContainer(_ value: Value) throws -> Any { + let options = _FirebaseEncoder._Options( + dateEncodingStrategy: nil, + dataEncodingStrategy: nil, + skipFirestoreTypes: true, + userInfo: userInfo + ) + let encoder = _FirebaseEncoder(options: options) + guard let topLevel = try encoder.box_(value) else { + throw EncodingError.invalidValue(value, + EncodingError.Context(codingPath: [], + debugDescription: "Top-level \(Value.self) did not encode any values.")) + } + + return topLevel + } +} diff --git a/FoodApp/Pods/CodableFirebase/LICENSE b/FoodApp/Pods/CodableFirebase/LICENSE new file mode 100644 index 0000000..b280522 --- /dev/null +++ b/FoodApp/Pods/CodableFirebase/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2017 Oleksii Dykan + +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. diff --git a/FoodApp/Pods/CodableFirebase/README.md b/FoodApp/Pods/CodableFirebase/README.md new file mode 100644 index 0000000..ccfac86 --- /dev/null +++ b/FoodApp/Pods/CodableFirebase/README.md @@ -0,0 +1,127 @@ +# CodableFirebase +Use [Codable](https://developer.apple.com/documentation/swift/codable) with [Firebase](https://firebase.google.com) + +[![CocoaPods](https://img.shields.io/cocoapods/p/CodableFirebase.svg)](https://github.com/alickbass/CodableFirebase) +[![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) +[![Build Status](https://travis-ci.org/alickbass/CodableFirebase.svg?branch=master)](https://travis-ci.org/alickbass/CodableFirebase) + +## Overview + +This library helps you to use your custom types that conform to `Codable` protocol with Firebase. Here's an example of a custom model: + +```swift +struct Model: Codable { + enum MyEnum: Int, Codable { + case one, two, three + } + + let stringExample: String + let booleanExample: Bool + let numberExample: Double + let dateExample: Date + let arrayExample: [String] + let optionalExample: Int? + let objectExample: [String: String] + let myEnumExample: MyEnum +} +``` + +### Firebase Realtime Database usage + +This is how you would use the library with [Firebase Realtime Database](https://firebase.google.com/products/realtime-database/): + +```swift +import Firebase +import CodableFirebase + +let model: Model // here you will create an instance of Model +let data = try! FirebaseEncoder().encode(model) + +Database.database().reference().child("model").setValue(data) +``` + +And here is how you would read the same value from [Firebase Realtime Database](https://firebase.google.com/products/realtime-database/): + +```swift +Database.database().reference().child("model").observeSingleEvent(of: .value, with: { snapshot in + guard let value = snapshot.value else { return } + do { + let model = try FirebaseDecoder().decode(Model.self, from: value) + print(model) + } catch let error { + print(error) + } +}) +``` + +### Firebase Cloud Firestore usage + +This is how you would encode a model with [Firebase Cloud Firestore](https://firebase.google.com/products/firestore/): + +```swift +import Firebase +import CodableFirebase + +let model: Model // here you will create an instance of Model +let docData = try! FirestoreEncoder().encode(model) +Firestore.firestore().collection("data").document("one").setData(docData) { error in + if let error = error { + print("Error writing document: \(error)") + } else { + print("Document successfully written!") + } +} +``` + +And this is how you would decode the same model with [Firebase Cloud Firestore](https://firebase.google.com/products/firestore/): + +```swift +Firestore.firestore().collection("data").document("one").getDocument { document, error in + if let document = document { + let model = try! FirestoreDecoder().decode(Model.self, from: document.data()) + print("Model: \(model)") + } else { + print("Document does not exist") + } +} +``` + +#### How to use `GeoPoint`, `DocumentRefence`, `FieldValue`, `Timestamp` in Cloud Firestore + +In order to use these types with Cloud Firestore, you need to add the following code somewhere in your app: + +```swift +extension DocumentReference: DocumentReferenceType {} +extension GeoPoint: GeoPointType {} +extension FieldValue: FieldValueType {} +extension Timestamp: TimestampType {} +``` + +and now they become `Codable` and can be used properly with `FirestoreEncoder` and `FirestoreDecoder`. + +***PLEASE NOTE*** that as `FieldValue` is only used to [`setData()` and `updateData()`](https://firebase.google.com/docs/reference/swift/firebasefirestore/api/reference/Classes/FieldValue), it only adopts the `Encodable` protocol. + +## Integration + +### CocoaPods (iOS 9+) + +You can use CocoaPods to install CodableFirebase by adding it to your Podfile: + +```swift +platform :ios, '9.0' +use_frameworks! + +target 'MyApp' do + pod 'CodableFirebase' +end +``` + +Note that this requires CocoaPods version 36, and your iOS deployment target to be at least 9.0: + +### Carthage (iOS 9+) + +You can use Carthage to install CodableFirebase by adding it to your Cartfile: + +```swift +github "alickbass/CodableFirebase" +``` diff --git a/FoodApp/Pods/Firebase/CoreOnly/Sources/Firebase.h b/FoodApp/Pods/Firebase/CoreOnly/Sources/Firebase.h new file mode 100755 index 0000000..aa0af40 --- /dev/null +++ b/FoodApp/Pods/Firebase/CoreOnly/Sources/Firebase.h @@ -0,0 +1,117 @@ +#import + +#if !defined(__has_include) + #error "Firebase.h won't import anything if your compiler doesn't support __has_include. Please \ + import the headers individually." +#else + #if __has_include() + #import + #else + #ifndef FIREBASE_ANALYTICS_SUPPRESS_WARNING + #warning "FirebaseAnalytics.framework is not included in your target. Please add \ +`Firebase/Core` to your Podfile or add FirebaseAnalytics.framework to your project to ensure \ +Firebase services work as intended." + #endif // #ifndef FIREBASE_ANALYTICS_SUPPRESS_WARNING + #endif + + #if __has_include() + #import + #endif + + #if __has_include() + #import + #endif + + #if __has_include() + #import + #endif + + #if __has_include() + #import + #endif + + #if __has_include() + #import + #endif + + #if __has_include() + #import + #endif + + #if __has_include() + #import + #endif + + #if __has_include() + #import + #endif + + #if __has_include() + #import + #endif + + #if __has_include() + #import + #endif + + #if __has_include() + #import + #endif + + #if __has_include() + #import + #endif + + #if __has_include() + #import + #endif + + #if __has_include() + #import + #endif + + #if __has_include() + #import + #endif + + #if __has_include() + #import + #endif + + #if __has_include() + #import + #endif + + #if __has_include() + #import + #endif + + #if __has_include() + #import + #endif + + #if __has_include() + #import + #endif + + #if __has_include() + #import + #endif + + #if __has_include() + #import + #endif + + #if __has_include() + #import + #endif + + #if __has_include() + #import + #endif + + #if __has_include() + #import + #endif + +#endif // defined(__has_include) diff --git a/FoodApp/Pods/Firebase/CoreOnly/Sources/module.modulemap b/FoodApp/Pods/Firebase/CoreOnly/Sources/module.modulemap new file mode 100755 index 0000000..3685b54 --- /dev/null +++ b/FoodApp/Pods/Firebase/CoreOnly/Sources/module.modulemap @@ -0,0 +1,4 @@ +module Firebase { + export * + header "Firebase.h" +} \ No newline at end of file diff --git a/FoodApp/Pods/Firebase/README.md b/FoodApp/Pods/Firebase/README.md new file mode 100755 index 0000000..a7ebe74 --- /dev/null +++ b/FoodApp/Pods/Firebase/README.md @@ -0,0 +1,90 @@ +# Firebase APIs for iOS + +Simplify your iOS development, grow your user base, and monetize more +effectively with Firebase services. + +Much more information can be found at [https://firebase.google.com](https://firebase.google.com). + +## Install a Firebase SDK using CocoaPods + +Firebase distributes several iOS specific APIs and SDKs via CocoaPods. +You can install the CocoaPods tool on OS X by running the following command from +the terminal. Detailed information is available in the [Getting Started +guide](https://guides.cocoapods.org/using/getting-started.html#getting-started). + +``` +$ sudo gem install cocoapods +``` + +## Try out an SDK + +You can try any of the SDKs with `pod try`. Run the following command and select +the SDK you are interested in when prompted: + +``` +$ pod try Firebase +``` + +Note that some SDKs may require credentials. More information is available in +the SDK-specific documentation at [https://firebase.google.com/docs/](https://firebase.google.com/docs/). + +## Add a Firebase SDK to your iOS app + +CocoaPods is used to install and manage dependencies in existing Xcode projects. + +1. Create an Xcode project, and save it to your local machine. +2. Create a file named `Podfile` in your project directory. This file defines + your project's dependencies, and is commonly referred to as a Podspec. +3. Open `Podfile`, and add your dependencies. A simple Podspec is shown here: + + ``` + platform :ios, '8.0' + pod 'Firebase' + ``` + +4. Save the file. + +5. Open a terminal and `cd` to the directory containing the Podfile. + + ``` + $ cd /project/ + ``` + +6. Run the `pod install` command. This will install the SDKs specified in the + Podspec, along with any dependencies they may have. + + ``` + $ pod install + ``` + +7. Open your app's `.xcworkspace` file to launch Xcode. Use this file for all + development on your app. + +8. You can also install other Firebase SDKs by adding the subspecs in the + Podfile. + + ``` + pod 'Firebase/AdMob' + pod 'Firebase/Analytics' + pod 'Firebase/Auth' + pod 'Firebase/Database' + pod 'Firebase/DynamicLinks' + pod 'Firebase/Firestore' + pod 'Firebase/Functions' + pod 'Firebase/InAppMessaging' + pod 'Firebase/InAppMessagingDisplay' + pod 'Firebase/Messaging' + pod 'Firebase/MLCommon' + pod 'Firebase/MLModelInterpreter' + pod 'Firebase/MLNLLanguageID' + pod 'Firebase/MLNLSmartReply' + pod 'Firebase/MLNaturalLanguage' + pod 'Firebase/MLVision' + pod 'Firebase/MLVisionBarcodeModel' + pod 'Firebase/MLVisionFaceModel' + pod 'Firebase/MLVisionLabelModel' + pod 'Firebase/MLVisionTextModel' + pod 'Firebase/Performance' + pod 'Firebase/RemoteConfig' + pod 'Firebase/Storage' + ``` diff --git a/FoodApp/Pods/FirebaseAnalytics/Frameworks/FIRAnalyticsConnector.framework/FIRAnalyticsConnector b/FoodApp/Pods/FirebaseAnalytics/Frameworks/FIRAnalyticsConnector.framework/FIRAnalyticsConnector new file mode 100755 index 0000000..1898de6 Binary files /dev/null and b/FoodApp/Pods/FirebaseAnalytics/Frameworks/FIRAnalyticsConnector.framework/FIRAnalyticsConnector differ diff --git a/FoodApp/Pods/FirebaseAnalytics/Frameworks/FIRAnalyticsConnector.framework/Modules/module.modulemap b/FoodApp/Pods/FirebaseAnalytics/Frameworks/FIRAnalyticsConnector.framework/Modules/module.modulemap new file mode 100755 index 0000000..270ad21 --- /dev/null +++ b/FoodApp/Pods/FirebaseAnalytics/Frameworks/FIRAnalyticsConnector.framework/Modules/module.modulemap @@ -0,0 +1,10 @@ +framework module FIRAnalyticsConnector { + export * + module * { export * } + link "sqlite3" + link "z" + link framework "Security" + link framework "StoreKit" + link framework "SystemConfiguration" + link framework "UIKit" +} diff --git a/FoodApp/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/FirebaseAnalytics b/FoodApp/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/FirebaseAnalytics new file mode 100755 index 0000000..b5d8a4a Binary files /dev/null and b/FoodApp/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/FirebaseAnalytics differ diff --git a/FoodApp/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/Headers/FIRAnalytics+AppDelegate.h b/FoodApp/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/Headers/FIRAnalytics+AppDelegate.h new file mode 100755 index 0000000..d499af6 --- /dev/null +++ b/FoodApp/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/Headers/FIRAnalytics+AppDelegate.h @@ -0,0 +1,62 @@ +#import + +#import "FIRAnalytics.h" + +NS_ASSUME_NONNULL_BEGIN + +/** + * Provides App Delegate handlers to be used in your App Delegate. + * + * To save time integrating Firebase Analytics in an application, Firebase Analytics does not + * require delegation implementation from the AppDelegate. Instead this is automatically done by + * Firebase Analytics. Should you choose instead to delegate manually, you can turn off the App + * Delegate Proxy by adding FirebaseAppDelegateProxyEnabled into your app's Info.plist and setting + * it to NO, and adding the methods in this category to corresponding delegation handlers. + * + * To handle Universal Links, you must return YES in + * [UIApplicationDelegate application:didFinishLaunchingWithOptions:]. + */ +@interface FIRAnalytics (AppDelegate) + +/** + * Handles events related to a URL session that are waiting to be processed. + * + * For optimal use of Firebase Analytics, call this method from the + * [UIApplicationDelegate application:handleEventsForBackgroundURLSession:completionHandler] + * method of the app delegate in your app. + * + * @param identifier The identifier of the URL session requiring attention. + * @param completionHandler The completion handler to call when you finish processing the events. + * Calling this completion handler lets the system know that your app's user interface is + * updated and a new snapshot can be taken. + */ ++ (void)handleEventsForBackgroundURLSession:(NSString *)identifier + completionHandler:(nullable void (^)(void))completionHandler; + +/** + * Handles the event when the app is launched by a URL. + * + * Call this method from [UIApplicationDelegate application:openURL:options:] (on iOS 9.0 and + * above), or [UIApplicationDelegate application:openURL:sourceApplication:annotation:] (on + * iOS 8.x and below) in your app. + * + * @param url The URL resource to open. This resource can be a network resource or a file. + */ ++ (void)handleOpenURL:(NSURL *)url; + +/** + * Handles the event when the app receives data associated with user activity that includes a + * Universal Link (on iOS 9.0 and above). + * + * Call this method from [UIApplication continueUserActivity:restorationHandler:] in your app + * delegate (on iOS 9.0 and above). + * + * @param userActivity The activity object containing the data associated with the task the user + * was performing. + */ ++ (void)handleUserActivity:(id)userActivity; + +@end + +NS_ASSUME_NONNULL_END + diff --git a/FoodApp/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/Headers/FIRAnalytics.h b/FoodApp/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/Headers/FIRAnalytics.h new file mode 100755 index 0000000..afb9f82 --- /dev/null +++ b/FoodApp/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/Headers/FIRAnalytics.h @@ -0,0 +1,132 @@ +#import + +#import "FIREventNames.h" +#import "FIRParameterNames.h" +#import "FIRUserPropertyNames.h" + +NS_ASSUME_NONNULL_BEGIN + +/// The top level Firebase Analytics singleton that provides methods for logging events and setting +/// user properties. See the developer guides for general +/// information on using Firebase Analytics in your apps. +NS_SWIFT_NAME(Analytics) +@interface FIRAnalytics : NSObject + +/// Logs an app event. The event can have up to 25 parameters. Events with the same name must have +/// the same parameters. Up to 500 event names are supported. Using predefined events and/or +/// parameters is recommended for optimal reporting. +/// +/// The following event names are reserved and cannot be used: +///
    +///
  • ad_activeview
  • +///
  • ad_click
  • +///
  • ad_exposure
  • +///
  • ad_impression
  • +///
  • ad_query
  • +///
  • adunit_exposure
  • +///
  • app_clear_data
  • +///
  • app_remove
  • +///
  • app_update
  • +///
  • error
  • +///
  • first_open
  • +///
  • in_app_purchase
  • +///
  • notification_dismiss
  • +///
  • notification_foreground
  • +///
  • notification_open
  • +///
  • notification_receive
  • +///
  • os_update
  • +///
  • screen_view
  • +///
  • session_start
  • +///
  • user_engagement
  • +///
+/// +/// @param name The name of the event. Should contain 1 to 40 alphanumeric characters or +/// underscores. The name must start with an alphabetic character. Some event names are +/// reserved. See FIREventNames.h for the list of reserved event names. The "firebase_", +/// "google_", and "ga_" prefixes are reserved and should not be used. Note that event names are +/// case-sensitive and that logging two events whose names differ only in case will result in +/// two distinct events. +/// @param parameters The dictionary of event parameters. Passing nil indicates that the event has +/// no parameters. Parameter names can be up to 40 characters long and must start with an +/// alphabetic character and contain only alphanumeric characters and underscores. Only NSString +/// and NSNumber (signed 64-bit integer and 64-bit floating-point number) parameter types are +/// supported. NSString parameter values can be up to 100 characters long. The "firebase_", +/// "google_", and "ga_" prefixes are reserved and should not be used for parameter names. ++ (void)logEventWithName:(NSString *)name + parameters:(nullable NSDictionary *)parameters + NS_SWIFT_NAME(logEvent(_:parameters:)); + +/// Sets a user property to a given value. Up to 25 user property names are supported. Once set, +/// user property values persist throughout the app lifecycle and across sessions. +/// +/// The following user property names are reserved and cannot be used: +///
    +///
  • first_open_time
  • +///
  • last_deep_link_referrer
  • +///
  • user_id
  • +///
+/// +/// @param value The value of the user property. Values can be up to 36 characters long. Setting the +/// value to nil removes the user property. +/// @param name The name of the user property to set. Should contain 1 to 24 alphanumeric characters +/// or underscores and must start with an alphabetic character. The "firebase_", "google_", and +/// "ga_" prefixes are reserved and should not be used for user property names. ++ (void)setUserPropertyString:(nullable NSString *)value forName:(NSString *)name + NS_SWIFT_NAME(setUserProperty(_:forName:)); + +/// Sets the user ID property. This feature must be used in accordance with +/// Google's Privacy Policy +/// +/// @param userID The user ID to ascribe to the user of this app on this device, which must be +/// non-empty and no more than 256 characters long. Setting userID to nil removes the user ID. ++ (void)setUserID:(nullable NSString *)userID; + +/// Sets the current screen name, which specifies the current visual context in your app. This helps +/// identify the areas in your app where users spend their time and how they interact with your app. +/// Must be called on the main thread. +/// +/// Note that screen reporting is enabled automatically and records the class name of the current +/// UIViewController for you without requiring you to call this method. If you implement +/// viewDidAppear in your UIViewController but do not call [super viewDidAppear:], that screen class +/// will not be automatically tracked. The class name can optionally be overridden by calling this +/// method in the viewDidAppear callback of your UIViewController and specifying the +/// screenClassOverride parameter. setScreenName:screenClass: must be called after +/// [super viewDidAppear:]. +/// +/// If your app does not use a distinct UIViewController for each screen, you should call this +/// method and specify a distinct screenName each time a new screen is presented to the user. +/// +/// The screen name and screen class remain in effect until the current UIViewController changes or +/// a new call to setScreenName:screenClass: is made. +/// +/// @param screenName The name of the current screen. Should contain 1 to 100 characters. Set to nil +/// to clear the current screen name. +/// @param screenClassOverride The name of the screen class. Should contain 1 to 100 characters. By +/// default this is the class name of the current UIViewController. Set to nil to revert to the +/// default class name. ++ (void)setScreenName:(nullable NSString *)screenName + screenClass:(nullable NSString *)screenClassOverride; + +/// Sets whether analytics collection is enabled for this app on this device. This setting is +/// persisted across app sessions. By default it is enabled. +/// +/// @param analyticsCollectionEnabled A flag that enables or disables Analytics collection. ++ (void)setAnalyticsCollectionEnabled:(BOOL)analyticsCollectionEnabled; + +/// Sets the interval of inactivity in seconds that terminates the current session. The default +/// value is 1800 seconds (30 minutes). +/// +/// @param sessionTimeoutInterval The custom time of inactivity in seconds before the current +/// session terminates. ++ (void)setSessionTimeoutInterval:(NSTimeInterval)sessionTimeoutInterval; + +/// The unique ID for this instance of the application. ++ (NSString *)appInstanceID; + +/// Clears all analytics data for this instance from the device and resets the app instance ID. +/// FIRAnalyticsConfiguration values will be reset to the default values. ++ (void)resetAnalyticsData; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/Headers/FIREventNames.h b/FoodApp/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/Headers/FIREventNames.h new file mode 100755 index 0000000..c70c53e --- /dev/null +++ b/FoodApp/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/Headers/FIREventNames.h @@ -0,0 +1,407 @@ +/// @file FIREventNames.h +/// +/// Predefined event names. +/// +/// An Event is an important occurrence in your app that you want to measure. You can report up to +/// 500 different types of Events per app and you can associate up to 25 unique parameters with each +/// Event type. Some common events are suggested below, but you may also choose to specify custom +/// Event types that are associated with your specific app. Each event type is identified by a +/// unique name. Event names can be up to 40 characters long, may only contain alphanumeric +/// characters and underscores ("_"), and must start with an alphabetic character. The "firebase_", +/// "google_", and "ga_" prefixes are reserved and should not be used. + +#import + +/// Add Payment Info event. This event signifies that a user has submitted their payment information +/// to your app. +static NSString *const kFIREventAddPaymentInfo NS_SWIFT_NAME(AnalyticsEventAddPaymentInfo) = + @"add_payment_info"; + +/// E-Commerce Add To Cart event. This event signifies that an item was added to a cart for +/// purchase. Add this event to a funnel with kFIREventEcommercePurchase to gauge the effectiveness +/// of your checkout process. Note: If you supply the @c kFIRParameterValue parameter, you must +/// also supply the @c kFIRParameterCurrency parameter so that revenue metrics can be computed +/// accurately. Params: +/// +///
    +///
  • @c kFIRParameterQuantity (signed 64-bit integer as NSNumber)
  • +///
  • @c kFIRParameterItemID (NSString)
  • +///
  • @c kFIRParameterItemName (NSString)
  • +///
  • @c kFIRParameterItemCategory (NSString)
  • +///
  • @c kFIRParameterItemLocationID (NSString) (optional)
  • +///
  • @c kFIRParameterPrice (double as NSNumber) (optional)
  • +///
  • @c kFIRParameterCurrency (NSString) (optional)
  • +///
  • @c kFIRParameterValue (double as NSNumber) (optional)
  • +///
  • @c kFIRParameterOrigin (NSString) (optional)
  • +///
  • @c kFIRParameterDestination (NSString) (optional)
  • +///
  • @c kFIRParameterStartDate (NSString) (optional)
  • +///
  • @c kFIRParameterEndDate (NSString) (optional)
  • +///
+static NSString *const kFIREventAddToCart NS_SWIFT_NAME(AnalyticsEventAddToCart) = @"add_to_cart"; + +/// E-Commerce Add To Wishlist event. This event signifies that an item was added to a wishlist. +/// Use this event to identify popular gift items in your app. Note: If you supply the +/// @c kFIRParameterValue parameter, you must also supply the @c kFIRParameterCurrency +/// parameter so that revenue metrics can be computed accurately. Params: +/// +///
    +///
  • @c kFIRParameterQuantity (signed 64-bit integer as NSNumber)
  • +///
  • @c kFIRParameterItemID (NSString)
  • +///
  • @c kFIRParameterItemName (NSString)
  • +///
  • @c kFIRParameterItemCategory (NSString)
  • +///
  • @c kFIRParameterItemLocationID (NSString) (optional)
  • +///
  • @c kFIRParameterPrice (double as NSNumber) (optional)
  • +///
  • @c kFIRParameterCurrency (NSString) (optional)
  • +///
  • @c kFIRParameterValue (double as NSNumber) (optional)
  • +///
+static NSString *const kFIREventAddToWishlist NS_SWIFT_NAME(AnalyticsEventAddToWishlist) = + @"add_to_wishlist"; + +/// App Open event. By logging this event when an App becomes active, developers can understand how +/// often users leave and return during the course of a Session. Although Sessions are automatically +/// reported, this event can provide further clarification around the continuous engagement of +/// app-users. +static NSString *const kFIREventAppOpen NS_SWIFT_NAME(AnalyticsEventAppOpen) = @"app_open"; + +/// E-Commerce Begin Checkout event. This event signifies that a user has begun the process of +/// checking out. Add this event to a funnel with your kFIREventEcommercePurchase event to gauge the +/// effectiveness of your checkout process. Note: If you supply the @c kFIRParameterValue +/// parameter, you must also supply the @c kFIRParameterCurrency parameter so that revenue +/// metrics can be computed accurately. Params: +/// +///
    +///
  • @c kFIRParameterValue (double as NSNumber) (optional)
  • +///
  • @c kFIRParameterCurrency (NSString) (optional)
  • +///
  • @c kFIRParameterTransactionID (NSString) (optional)
  • +///
  • @c kFIRParameterStartDate (NSString) (optional)
  • +///
  • @c kFIRParameterEndDate (NSString) (optional)
  • +///
  • @c kFIRParameterNumberOfNights (signed 64-bit integer as NSNumber) (optional) for +/// hotel bookings
  • +///
  • @c kFIRParameterNumberOfRooms (signed 64-bit integer as NSNumber) (optional) for +/// hotel bookings
  • +///
  • @c kFIRParameterNumberOfPassengers (signed 64-bit integer as NSNumber) (optional) +/// for travel bookings
  • +///
  • @c kFIRParameterOrigin (NSString) (optional)
  • +///
  • @c kFIRParameterDestination (NSString) (optional)
  • +///
  • @c kFIRParameterTravelClass (NSString) (optional) for travel bookings
  • +///
+static NSString *const kFIREventBeginCheckout NS_SWIFT_NAME(AnalyticsEventBeginCheckout) = + @"begin_checkout"; + +/// Campaign Detail event. Log this event to supply the referral details of a re-engagement +/// campaign. Note: you must supply at least one of the required parameters kFIRParameterSource, +/// kFIRParameterMedium or kFIRParameterCampaign. Params: +/// +///
    +///
  • @c kFIRParameterSource (NSString)
  • +///
  • @c kFIRParameterMedium (NSString)
  • +///
  • @c kFIRParameterCampaign (NSString)
  • +///
  • @c kFIRParameterTerm (NSString) (optional)
  • +///
  • @c kFIRParameterContent (NSString) (optional)
  • +///
  • @c kFIRParameterAdNetworkClickID (NSString) (optional)
  • +///
  • @c kFIRParameterCP1 (NSString) (optional)
  • +///
+static NSString *const kFIREventCampaignDetails NS_SWIFT_NAME(AnalyticsEventCampaignDetails) = + @"campaign_details"; + +/// Checkout progress. Params: +/// +///
    +///
  • @c kFIRParameterCheckoutStep (unsigned 64-bit integer as NSNumber)
  • +///
  • @c kFIRParameterCheckoutOption (NSString) (optional)
  • +///
+static NSString *const kFIREventCheckoutProgress NS_SWIFT_NAME(AnalyticsEventCheckoutProgress) = + @"checkout_progress"; + +/// Earn Virtual Currency event. This event tracks the awarding of virtual currency in your app. Log +/// this along with @c kFIREventSpendVirtualCurrency to better understand your virtual economy. +/// Params: +/// +///
    +///
  • @c kFIRParameterVirtualCurrencyName (NSString)
  • +///
  • @c kFIRParameterValue (signed 64-bit integer or double as NSNumber)
  • +///
+static NSString *const kFIREventEarnVirtualCurrency + NS_SWIFT_NAME(AnalyticsEventEarnVirtualCurrency) = @"earn_virtual_currency"; + +/// E-Commerce Purchase event. This event signifies that an item was purchased by a user. Note: +/// This is different from the in-app purchase event, which is reported automatically for App +/// Store-based apps. Note: If you supply the @c kFIRParameterValue parameter, you must also +/// supply the @c kFIRParameterCurrency parameter so that revenue metrics can be computed +/// accurately. Params: +/// +///
    +///
  • @c kFIRParameterCurrency (NSString) (optional)
  • +///
  • @c kFIRParameterValue (double as NSNumber) (optional)
  • +///
  • @c kFIRParameterTransactionID (NSString) (optional)
  • +///
  • @c kFIRParameterTax (double as NSNumber) (optional)
  • +///
  • @c kFIRParameterShipping (double as NSNumber) (optional)
  • +///
  • @c kFIRParameterCoupon (NSString) (optional)
  • +///
  • @c kFIRParameterLocation (NSString) (optional)
  • +///
  • @c kFIRParameterStartDate (NSString) (optional)
  • +///
  • @c kFIRParameterEndDate (NSString) (optional)
  • +///
  • @c kFIRParameterNumberOfNights (signed 64-bit integer as NSNumber) (optional) for +/// hotel bookings
  • +///
  • @c kFIRParameterNumberOfRooms (signed 64-bit integer as NSNumber) (optional) for +/// hotel bookings
  • +///
  • @c kFIRParameterNumberOfPassengers (signed 64-bit integer as NSNumber) (optional) +/// for travel bookings
  • +///
  • @c kFIRParameterOrigin (NSString) (optional)
  • +///
  • @c kFIRParameterDestination (NSString) (optional)
  • +///
  • @c kFIRParameterTravelClass (NSString) (optional) for travel bookings
  • +///
+static NSString *const kFIREventEcommercePurchase NS_SWIFT_NAME(AnalyticsEventEcommercePurchase) = + @"ecommerce_purchase"; + +/// Generate Lead event. Log this event when a lead has been generated in the app to understand the +/// efficacy of your install and re-engagement campaigns. Note: If you supply the +/// @c kFIRParameterValue parameter, you must also supply the @c kFIRParameterCurrency +/// parameter so that revenue metrics can be computed accurately. Params: +/// +///
    +///
  • @c kFIRParameterCurrency (NSString) (optional)
  • +///
  • @c kFIRParameterValue (double as NSNumber) (optional)
  • +///
+static NSString *const kFIREventGenerateLead NS_SWIFT_NAME(AnalyticsEventGenerateLead) = + @"generate_lead"; + +/// Join Group event. Log this event when a user joins a group such as a guild, team or family. Use +/// this event to analyze how popular certain groups or social features are in your app. Params: +/// +///
    +///
  • @c kFIRParameterGroupID (NSString)
  • +///
+static NSString *const kFIREventJoinGroup NS_SWIFT_NAME(AnalyticsEventJoinGroup) = @"join_group"; + +/// Level Up event. This event signifies that a player has leveled up in your gaming app. It can +/// help you gauge the level distribution of your userbase and help you identify certain levels that +/// are difficult to pass. Params: +/// +///
    +///
  • @c kFIRParameterLevel (signed 64-bit integer as NSNumber)
  • +///
  • @c kFIRParameterCharacter (NSString) (optional)
  • +///
+static NSString *const kFIREventLevelUp NS_SWIFT_NAME(AnalyticsEventLevelUp) = @"level_up"; + +/// Login event. Apps with a login feature can report this event to signify that a user has logged +/// in. +static NSString *const kFIREventLogin NS_SWIFT_NAME(AnalyticsEventLogin) = @"login"; + +/// Post Score event. Log this event when the user posts a score in your gaming app. This event can +/// help you understand how users are actually performing in your game and it can help you correlate +/// high scores with certain audiences or behaviors. Params: +/// +///
    +///
  • @c kFIRParameterScore (signed 64-bit integer as NSNumber)
  • +///
  • @c kFIRParameterLevel (signed 64-bit integer as NSNumber) (optional)
  • +///
  • @c kFIRParameterCharacter (NSString) (optional)
  • +///
+static NSString *const kFIREventPostScore NS_SWIFT_NAME(AnalyticsEventPostScore) = @"post_score"; + +/// Present Offer event. This event signifies that the app has presented a purchase offer to a user. +/// Add this event to a funnel with the kFIREventAddToCart and kFIREventEcommercePurchase to gauge +/// your conversion process. Note: If you supply the @c kFIRParameterValue parameter, you must +/// also supply the @c kFIRParameterCurrency parameter so that revenue metrics can be computed +/// accurately. Params: +/// +///
    +///
  • @c kFIRParameterQuantity (signed 64-bit integer as NSNumber)
  • +///
  • @c kFIRParameterItemID (NSString)
  • +///
  • @c kFIRParameterItemName (NSString)
  • +///
  • @c kFIRParameterItemCategory (NSString)
  • +///
  • @c kFIRParameterItemLocationID (NSString) (optional)
  • +///
  • @c kFIRParameterPrice (double as NSNumber) (optional)
  • +///
  • @c kFIRParameterCurrency (NSString) (optional)
  • +///
  • @c kFIRParameterValue (double as NSNumber) (optional)
  • +///
+static NSString *const kFIREventPresentOffer NS_SWIFT_NAME(AnalyticsEventPresentOffer) = + @"present_offer"; + +/// E-Commerce Purchase Refund event. This event signifies that an item purchase was refunded. +/// Note: If you supply the @c kFIRParameterValue parameter, you must also supply the +/// @c kFIRParameterCurrency parameter so that revenue metrics can be computed accurately. +/// Params: +/// +///
    +///
  • @c kFIRParameterCurrency (NSString) (optional)
  • +///
  • @c kFIRParameterValue (double as NSNumber) (optional)
  • +///
  • @c kFIRParameterTransactionID (NSString) (optional)
  • +///
+static NSString *const kFIREventPurchaseRefund NS_SWIFT_NAME(AnalyticsEventPurchaseRefund) = + @"purchase_refund"; + +/// Remove from cart event. Params: +/// +///
    +///
  • @c kFIRParameterQuantity (signed 64-bit integer as NSNumber)
  • +///
  • @c kFIRParameterItemID (NSString)
  • +///
  • @c kFIRParameterItemName (NSString)
  • +///
  • @c kFIRParameterItemCategory (NSString)
  • +///
  • @c kFIRParameterItemLocationID (NSString) (optional)
  • +///
  • @c kFIRParameterPrice (double as NSNumber) (optional)
  • +///
  • @c kFIRParameterCurrency (NSString) (optional)
  • +///
  • @c kFIRParameterValue (double as NSNumber) (optional)
  • +///
  • @c kFIRParameterOrigin (NSString) (optional)
  • +///
  • @c kFIRParameterDestination (NSString) (optional)
  • +///
  • @c kFIRParameterStartDate (NSString) (optional)
  • +///
  • @c kFIRParameterEndDate (NSString) (optional)
  • +///
+static NSString *const kFIREventRemoveFromCart NS_SWIFT_NAME(AnalyticsEventRemoveFromCart) = + @"remove_from_cart"; + +/// Search event. Apps that support search features can use this event to contextualize search +/// operations by supplying the appropriate, corresponding parameters. This event can help you +/// identify the most popular content in your app. Params: +/// +///
    +///
  • @c kFIRParameterSearchTerm (NSString)
  • +///
  • @c kFIRParameterStartDate (NSString) (optional)
  • +///
  • @c kFIRParameterEndDate (NSString) (optional)
  • +///
  • @c kFIRParameterNumberOfNights (signed 64-bit integer as NSNumber) (optional) for +/// hotel bookings
  • +///
  • @c kFIRParameterNumberOfRooms (signed 64-bit integer as NSNumber) (optional) for +/// hotel bookings
  • +///
  • @c kFIRParameterNumberOfPassengers (signed 64-bit integer as NSNumber) (optional) +/// for travel bookings
  • +///
  • @c kFIRParameterOrigin (NSString) (optional)
  • +///
  • @c kFIRParameterDestination (NSString) (optional)
  • +///
  • @c kFIRParameterTravelClass (NSString) (optional) for travel bookings
  • +///
+static NSString *const kFIREventSearch NS_SWIFT_NAME(AnalyticsEventSearch) = @"search"; + +/// Select Content event. This general purpose event signifies that a user has selected some content +/// of a certain type in an app. The content can be any object in your app. This event can help you +/// identify popular content and categories of content in your app. Params: +/// +///
    +///
  • @c kFIRParameterContentType (NSString)
  • +///
  • @c kFIRParameterItemID (NSString)
  • +///
+static NSString *const kFIREventSelectContent NS_SWIFT_NAME(AnalyticsEventSelectContent) = + @"select_content"; + +/// Set checkout option. Params: +/// +///
    +///
  • @c kFIRParameterCheckoutStep (unsigned 64-bit integer as NSNumber)
  • +///
  • @c kFIRParameterCheckoutOption (NSString)
  • +///
+static NSString *const kFIREventSetCheckoutOption NS_SWIFT_NAME(AnalyticsEventSetCheckoutOption) = + @"set_checkout_option"; + +/// Share event. Apps with social features can log the Share event to identify the most viral +/// content. Params: +/// +///
    +///
  • @c kFIRParameterContentType (NSString)
  • +///
  • @c kFIRParameterItemID (NSString)
  • +///
+static NSString *const kFIREventShare NS_SWIFT_NAME(AnalyticsEventShare) = @"share"; + +/// Sign Up event. This event indicates that a user has signed up for an account in your app. The +/// parameter signifies the method by which the user signed up. Use this event to understand the +/// different behaviors between logged in and logged out users. Params: +/// +///
    +///
  • @c kFIRParameterSignUpMethod (NSString)
  • +///
+static NSString *const kFIREventSignUp NS_SWIFT_NAME(AnalyticsEventSignUp) = @"sign_up"; + +/// Spend Virtual Currency event. This event tracks the sale of virtual goods in your app and can +/// help you identify which virtual goods are the most popular objects of purchase. Params: +/// +///
    +///
  • @c kFIRParameterItemName (NSString)
  • +///
  • @c kFIRParameterVirtualCurrencyName (NSString)
  • +///
  • @c kFIRParameterValue (signed 64-bit integer or double as NSNumber)
  • +///
+static NSString *const kFIREventSpendVirtualCurrency + NS_SWIFT_NAME(AnalyticsEventSpendVirtualCurrency) = @"spend_virtual_currency"; + +/// Tutorial Begin event. This event signifies the start of the on-boarding process in your app. Use +/// this in a funnel with kFIREventTutorialComplete to understand how many users complete this +/// process and move on to the full app experience. +static NSString *const kFIREventTutorialBegin NS_SWIFT_NAME(AnalyticsEventTutorialBegin) = + @"tutorial_begin"; + +/// Tutorial End event. Use this event to signify the user's completion of your app's on-boarding +/// process. Add this to a funnel with kFIREventTutorialBegin to gauge the completion rate of your +/// on-boarding process. +static NSString *const kFIREventTutorialComplete NS_SWIFT_NAME(AnalyticsEventTutorialComplete) = + @"tutorial_complete"; + +/// Unlock Achievement event. Log this event when the user has unlocked an achievement in your +/// game. Since achievements generally represent the breadth of a gaming experience, this event can +/// help you understand how many users are experiencing all that your game has to offer. Params: +/// +///
    +///
  • @c kFIRParameterAchievementID (NSString)
  • +///
+static NSString *const kFIREventUnlockAchievement NS_SWIFT_NAME(AnalyticsEventUnlockAchievement) = + @"unlock_achievement"; + +/// View Item event. This event signifies that some content was shown to the user. This content may +/// be a product, a webpage or just a simple image or text. Use the appropriate parameters to +/// contextualize the event. Use this event to discover the most popular items viewed in your app. +/// Note: If you supply the @c kFIRParameterValue parameter, you must also supply the +/// @c kFIRParameterCurrency parameter so that revenue metrics can be computed accurately. +/// Params: +/// +///
    +///
  • @c kFIRParameterItemID (NSString)
  • +///
  • @c kFIRParameterItemName (NSString)
  • +///
  • @c kFIRParameterItemCategory (NSString)
  • +///
  • @c kFIRParameterItemLocationID (NSString) (optional)
  • +///
  • @c kFIRParameterPrice (double as NSNumber) (optional)
  • +///
  • @c kFIRParameterQuantity (signed 64-bit integer as NSNumber) (optional)
  • +///
  • @c kFIRParameterCurrency (NSString) (optional)
  • +///
  • @c kFIRParameterValue (double as NSNumber) (optional)
  • +///
  • @c kFIRParameterStartDate (NSString) (optional)
  • +///
  • @c kFIRParameterEndDate (NSString) (optional)
  • +///
  • @c kFIRParameterFlightNumber (NSString) (optional) for travel bookings
  • +///
  • @c kFIRParameterNumberOfPassengers (signed 64-bit integer as NSNumber) (optional) +/// for travel bookings
  • +///
  • @c kFIRParameterNumberOfNights (signed 64-bit integer as NSNumber) (optional) for +/// travel bookings
  • +///
  • @c kFIRParameterNumberOfRooms (signed 64-bit integer as NSNumber) (optional) for +/// travel bookings
  • +///
  • @c kFIRParameterOrigin (NSString) (optional)
  • +///
  • @c kFIRParameterDestination (NSString) (optional)
  • +///
  • @c kFIRParameterSearchTerm (NSString) (optional) for travel bookings
  • +///
  • @c kFIRParameterTravelClass (NSString) (optional) for travel bookings
  • +///
+static NSString *const kFIREventViewItem NS_SWIFT_NAME(AnalyticsEventViewItem) = @"view_item"; + +/// View Item List event. Log this event when the user has been presented with a list of items of a +/// certain category. Params: +/// +///
    +///
  • @c kFIRParameterItemCategory (NSString)
  • +///
+static NSString *const kFIREventViewItemList NS_SWIFT_NAME(AnalyticsEventViewItemList) = + @"view_item_list"; + +/// View Search Results event. Log this event when the user has been presented with the results of a +/// search. Params: +/// +///
    +///
  • @c kFIRParameterSearchTerm (NSString)
  • +///
+static NSString *const kFIREventViewSearchResults NS_SWIFT_NAME(AnalyticsEventViewSearchResults) = + @"view_search_results"; + +/// Level Start event. Log this event when the user starts a new level. Params: +/// +///
    +///
  • @c kFIRParameterLevelName (NSString)
  • +///
+static NSString *const kFIREventLevelStart NS_SWIFT_NAME(AnalyticsEventLevelStart) = + @"level_start"; + +/// Level End event. Log this event when the user finishes a level. Params: +/// +///
    +///
  • @c kFIRParameterLevelName (NSString)
  • +///
  • @c kFIRParameterSuccess (NSString)
  • +///
+static NSString *const kFIREventLevelEnd NS_SWIFT_NAME(AnalyticsEventLevelEnd) = @"level_end"; diff --git a/FoodApp/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/Headers/FIRParameterNames.h b/FoodApp/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/Headers/FIRParameterNames.h new file mode 100755 index 0000000..ad9fff7 --- /dev/null +++ b/FoodApp/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/Headers/FIRParameterNames.h @@ -0,0 +1,532 @@ +/// @file FIRParameterNames.h +/// +/// Predefined event parameter names. +/// +/// Params supply information that contextualize Events. You can associate up to 25 unique Params +/// with each Event type. Some Params are suggested below for certain common Events, but you are +/// not limited to these. You may supply extra Params for suggested Events or custom Params for +/// Custom events. Param names can be up to 40 characters long, may only contain alphanumeric +/// characters and underscores ("_"), and must start with an alphabetic character. Param values can +/// be up to 100 characters long. The "firebase_", "google_", and "ga_" prefixes are reserved and +/// should not be used. + +#import + +/// Game achievement ID (NSString). +///
+///     NSDictionary *params = @{
+///       kFIRParameterAchievementID : @"10_matches_won",
+///       // ...
+///     };
+/// 
+static NSString *const kFIRParameterAchievementID NS_SWIFT_NAME(AnalyticsParameterAchievementID) = + @"achievement_id"; + +/// Ad Network Click ID (NSString). Used for network-specific click IDs which vary in format. +///
+///     NSDictionary *params = @{
+///       kFIRParameterAdNetworkClickID : @"1234567",
+///       // ...
+///     };
+/// 
+static NSString *const kFIRParameterAdNetworkClickID + NS_SWIFT_NAME(AnalyticsParameterAdNetworkClickID) = @"aclid"; + +/// The store or affiliation from which this transaction occurred (NSString). +///
+///     NSDictionary *params = @{
+///       kFIRParameterAffiliation : @"Google Store",
+///       // ...
+///     };
+/// 
+static NSString *const kFIRParameterAffiliation NS_SWIFT_NAME(AnalyticsParameterAffiliation) = + @"affiliation"; + +/// The individual campaign name, slogan, promo code, etc. Some networks have pre-defined macro to +/// capture campaign information, otherwise can be populated by developer. Highly Recommended +/// (NSString). +///
+///     NSDictionary *params = @{
+///       kFIRParameterCampaign : @"winter_promotion",
+///       // ...
+///     };
+/// 
+static NSString *const kFIRParameterCampaign NS_SWIFT_NAME(AnalyticsParameterCampaign) = + @"campaign"; + +/// Character used in game (NSString). +///
+///     NSDictionary *params = @{
+///       kFIRParameterCharacter : @"beat_boss",
+///       // ...
+///     };
+/// 
+static NSString *const kFIRParameterCharacter NS_SWIFT_NAME(AnalyticsParameterCharacter) = + @"character"; + +/// The checkout step (1..N) (unsigned 64-bit integer as NSNumber). +///
+///     NSDictionary *params = @{
+///       kFIRParameterCheckoutStep : @"1",
+///       // ...
+///     };
+/// 
+static NSString *const kFIRParameterCheckoutStep NS_SWIFT_NAME(AnalyticsParameterCheckoutStep) = + @"checkout_step"; + +/// Some option on a step in an ecommerce flow (NSString). +///
+///     NSDictionary *params = @{
+///       kFIRParameterCheckoutOption : @"Visa",
+///       // ...
+///     };
+/// 
+static NSString *const kFIRParameterCheckoutOption + NS_SWIFT_NAME(AnalyticsParameterCheckoutOption) = @"checkout_option"; + +/// Campaign content (NSString). +static NSString *const kFIRParameterContent NS_SWIFT_NAME(AnalyticsParameterContent) = @"content"; + +/// Type of content selected (NSString). +///
+///     NSDictionary *params = @{
+///       kFIRParameterContentType : @"news article",
+///       // ...
+///     };
+/// 
+static NSString *const kFIRParameterContentType NS_SWIFT_NAME(AnalyticsParameterContentType) = + @"content_type"; + +/// Coupon code for a purchasable item (NSString). +///
+///     NSDictionary *params = @{
+///       kFIRParameterCoupon : @"zz123",
+///       // ...
+///     };
+/// 
+static NSString *const kFIRParameterCoupon NS_SWIFT_NAME(AnalyticsParameterCoupon) = @"coupon"; + +/// Campaign custom parameter (NSString). Used as a method of capturing custom data in a campaign. +/// Use varies by network. +///
+///     NSDictionary *params = @{
+///       kFIRParameterCP1 : @"custom_data",
+///       // ...
+///     };
+/// 
+static NSString *const kFIRParameterCP1 NS_SWIFT_NAME(AnalyticsParameterCP1) = @"cp1"; + +/// The name of a creative used in a promotional spot (NSString). +///
+///     NSDictionary *params = @{
+///       kFIRParameterCreativeName : @"Summer Sale",
+///       // ...
+///     };
+/// 
+static NSString *const kFIRParameterCreativeName NS_SWIFT_NAME(AnalyticsParameterCreativeName) = + @"creative_name"; + +/// The name of a creative slot (NSString). +///
+///     NSDictionary *params = @{
+///       kFIRParameterCreativeSlot : @"summer_banner2",
+///       // ...
+///     };
+/// 
+static NSString *const kFIRParameterCreativeSlot NS_SWIFT_NAME(AnalyticsParameterCreativeSlot) = + @"creative_slot"; + +/// Purchase currency in 3-letter +/// ISO_4217 format (NSString). +///
+///     NSDictionary *params = @{
+///       kFIRParameterCurrency : @"USD",
+///       // ...
+///     };
+/// 
+static NSString *const kFIRParameterCurrency NS_SWIFT_NAME(AnalyticsParameterCurrency) = + @"currency"; + +/// Flight or Travel destination (NSString). +///
+///     NSDictionary *params = @{
+///       kFIRParameterDestination : @"Mountain View, CA",
+///       // ...
+///     };
+/// 
+static NSString *const kFIRParameterDestination NS_SWIFT_NAME(AnalyticsParameterDestination) = + @"destination"; + +/// The arrival date, check-out date or rental end date for the item. This should be in +/// YYYY-MM-DD format (NSString). +///
+///     NSDictionary *params = @{
+///       kFIRParameterEndDate : @"2015-09-14",
+///       // ...
+///     };
+/// 
+static NSString *const kFIRParameterEndDate NS_SWIFT_NAME(AnalyticsParameterEndDate) = @"end_date"; + +/// Flight number for travel events (NSString). +///
+///     NSDictionary *params = @{
+///       kFIRParameterFlightNumber : @"ZZ800",
+///       // ...
+///     };
+/// 
+static NSString *const kFIRParameterFlightNumber NS_SWIFT_NAME(AnalyticsParameterFlightNumber) = + @"flight_number"; + +/// Group/clan/guild ID (NSString). +///
+///     NSDictionary *params = @{
+///       kFIRParameterGroupID : @"g1",
+///       // ...
+///     };
+/// 
+static NSString *const kFIRParameterGroupID NS_SWIFT_NAME(AnalyticsParameterGroupID) = @"group_id"; + +/// Index of an item in a list (signed 64-bit integer as NSNumber). +///
+///     NSDictionary *params = @{
+///       kFIRParameterIndex : @(1),
+///       // ...
+///     };
+/// 
+static NSString *const kFIRParameterIndex NS_SWIFT_NAME(AnalyticsParameterIndex) = @"index"; + +/// Item brand (NSString). +///
+///     NSDictionary *params = @{
+///       kFIRParameterItemBrand : @"Google",
+///       // ...
+///     };
+/// 
+static NSString *const kFIRParameterItemBrand NS_SWIFT_NAME(AnalyticsParameterItemBrand) = + @"item_brand"; + +/// Item category (NSString). +///
+///     NSDictionary *params = @{
+///       kFIRParameterItemCategory : @"t-shirts",
+///       // ...
+///     };
+/// 
+static NSString *const kFIRParameterItemCategory NS_SWIFT_NAME(AnalyticsParameterItemCategory) = + @"item_category"; + +/// Item ID (NSString). +///
+///     NSDictionary *params = @{
+///       kFIRParameterItemID : @"p7654",
+///       // ...
+///     };
+/// 
+static NSString *const kFIRParameterItemID NS_SWIFT_NAME(AnalyticsParameterItemID) = @"item_id"; + +/// The Google Place ID (NSString) that +/// corresponds to the associated item. Alternatively, you can supply your own custom Location ID. +///
+///     NSDictionary *params = @{
+///       kFIRParameterItemLocationID : @"ChIJiyj437sx3YAR9kUWC8QkLzQ",
+///       // ...
+///     };
+/// 
+static NSString *const kFIRParameterItemLocationID + NS_SWIFT_NAME(AnalyticsParameterItemLocationID) = @"item_location_id"; + +/// Item name (NSString). +///
+///     NSDictionary *params = @{
+///       kFIRParameterItemName : @"abc",
+///       // ...
+///     };
+/// 
+static NSString *const kFIRParameterItemName NS_SWIFT_NAME(AnalyticsParameterItemName) = + @"item_name"; + +/// The list in which the item was presented to the user (NSString). +///
+///     NSDictionary *params = @{
+///       kFIRParameterItemList : @"Search Results",
+///       // ...
+///     };
+/// 
+static NSString *const kFIRParameterItemList NS_SWIFT_NAME(AnalyticsParameterItemList) = + @"item_list"; + +/// Item variant (NSString). +///
+///     NSDictionary *params = @{
+///       kFIRParameterItemVariant : @"Red",
+///       // ...
+///     };
+/// 
+static NSString *const kFIRParameterItemVariant NS_SWIFT_NAME(AnalyticsParameterItemVariant) = + @"item_variant"; + +/// Level in game (signed 64-bit integer as NSNumber). +///
+///     NSDictionary *params = @{
+///       kFIRParameterLevel : @(42),
+///       // ...
+///     };
+/// 
+static NSString *const kFIRParameterLevel NS_SWIFT_NAME(AnalyticsParameterLevel) = @"level"; + +/// Location (NSString). The Google Place ID +/// that corresponds to the associated event. Alternatively, you can supply your own custom +/// Location ID. +///
+///     NSDictionary *params = @{
+///       kFIRParameterLocation : @"ChIJiyj437sx3YAR9kUWC8QkLzQ",
+///       // ...
+///     };
+/// 
+static NSString *const kFIRParameterLocation NS_SWIFT_NAME(AnalyticsParameterLocation) = + @"location"; + +/// The advertising or marketing medium, for example: cpc, banner, email, push. Highly recommended +/// (NSString). +///
+///     NSDictionary *params = @{
+///       kFIRParameterMedium : @"email",
+///       // ...
+///     };
+/// 
+static NSString *const kFIRParameterMedium NS_SWIFT_NAME(AnalyticsParameterMedium) = @"medium"; + +/// Number of nights staying at hotel (signed 64-bit integer as NSNumber). +///
+///     NSDictionary *params = @{
+///       kFIRParameterNumberOfNights : @(3),
+///       // ...
+///     };
+/// 
+static NSString *const kFIRParameterNumberOfNights + NS_SWIFT_NAME(AnalyticsParameterNumberOfNights) = @"number_of_nights"; + +/// Number of passengers traveling (signed 64-bit integer as NSNumber). +///
+///     NSDictionary *params = @{
+///       kFIRParameterNumberOfPassengers : @(11),
+///       // ...
+///     };
+/// 
+static NSString *const kFIRParameterNumberOfPassengers + NS_SWIFT_NAME(AnalyticsParameterNumberOfPassengers) = @"number_of_passengers"; + +/// Number of rooms for travel events (signed 64-bit integer as NSNumber). +///
+///     NSDictionary *params = @{
+///       kFIRParameterNumberOfRooms : @(2),
+///       // ...
+///     };
+/// 
+static NSString *const kFIRParameterNumberOfRooms NS_SWIFT_NAME(AnalyticsParameterNumberOfRooms) = + @"number_of_rooms"; + +/// Flight or Travel origin (NSString). +///
+///     NSDictionary *params = @{
+///       kFIRParameterOrigin : @"Mountain View, CA",
+///       // ...
+///     };
+/// 
+static NSString *const kFIRParameterOrigin NS_SWIFT_NAME(AnalyticsParameterOrigin) = @"origin"; + +/// Purchase price (double as NSNumber). +///
+///     NSDictionary *params = @{
+///       kFIRParameterPrice : @(1.0),
+///       kFIRParameterCurrency : @"USD",  // e.g. $1.00 USD
+///       // ...
+///     };
+/// 
+static NSString *const kFIRParameterPrice NS_SWIFT_NAME(AnalyticsParameterPrice) = @"price"; + +/// Purchase quantity (signed 64-bit integer as NSNumber). +///
+///     NSDictionary *params = @{
+///       kFIRParameterQuantity : @(1),
+///       // ...
+///     };
+/// 
+static NSString *const kFIRParameterQuantity NS_SWIFT_NAME(AnalyticsParameterQuantity) = + @"quantity"; + +/// Score in game (signed 64-bit integer as NSNumber). +///
+///     NSDictionary *params = @{
+///       kFIRParameterScore : @(4200),
+///       // ...
+///     };
+/// 
+static NSString *const kFIRParameterScore NS_SWIFT_NAME(AnalyticsParameterScore) = @"score"; + +/// The search string/keywords used (NSString). +///
+///     NSDictionary *params = @{
+///       kFIRParameterSearchTerm : @"periodic table",
+///       // ...
+///     };
+/// 
+static NSString *const kFIRParameterSearchTerm NS_SWIFT_NAME(AnalyticsParameterSearchTerm) = + @"search_term"; + +/// Shipping cost (double as NSNumber). +///
+///     NSDictionary *params = @{
+///       kFIRParameterShipping : @(9.50),
+///       kFIRParameterCurrency : @"USD",  // e.g. $9.50 USD
+///       // ...
+///     };
+/// 
+static NSString *const kFIRParameterShipping NS_SWIFT_NAME(AnalyticsParameterShipping) = + @"shipping"; + +/// Sign up method (NSString). +///
+///     NSDictionary *params = @{
+///       kFIRParameterSignUpMethod : @"google",
+///       // ...
+///     };
+/// 
+/// +/// This constant has been deprecated. Use Method constant instead. +static NSString *const kFIRParameterSignUpMethod NS_SWIFT_NAME(AnalyticsParameterSignUpMethod) = + @"sign_up_method"; + +/// A particular approach used in an operation; for example, "facebook" or "email" in the context +/// of a sign_up or login event. (NSString). +///
+///     NSDictionary *params = @{
+///       kFIRParameterMethod : @"google",
+///       // ...
+///     };
+/// 
+static NSString *const kFIRParameterMethod NS_SWIFT_NAME(AnalyticsParameterMethod) = @"method"; + +/// The origin of your traffic, such as an Ad network (for example, google) or partner (urban +/// airship). Identify the advertiser, site, publication, etc. that is sending traffic to your +/// property. Highly recommended (NSString). +///
+///     NSDictionary *params = @{
+///       kFIRParameterSource : @"InMobi",
+///       // ...
+///     };
+/// 
+static NSString *const kFIRParameterSource NS_SWIFT_NAME(AnalyticsParameterSource) = @"source"; + +/// The departure date, check-in date or rental start date for the item. This should be in +/// YYYY-MM-DD format (NSString). +///
+///     NSDictionary *params = @{
+///       kFIRParameterStartDate : @"2015-09-14",
+///       // ...
+///     };
+/// 
+static NSString *const kFIRParameterStartDate NS_SWIFT_NAME(AnalyticsParameterStartDate) = + @"start_date"; + +/// Tax amount (double as NSNumber). +///
+///     NSDictionary *params = @{
+///       kFIRParameterTax : @(1.0),
+///       kFIRParameterCurrency : @"USD",  // e.g. $1.00 USD
+///       // ...
+///     };
+/// 
+static NSString *const kFIRParameterTax NS_SWIFT_NAME(AnalyticsParameterTax) = @"tax"; + +/// If you're manually tagging keyword campaigns, you should use utm_term to specify the keyword +/// (NSString). +///
+///     NSDictionary *params = @{
+///       kFIRParameterTerm : @"game",
+///       // ...
+///     };
+/// 
+static NSString *const kFIRParameterTerm NS_SWIFT_NAME(AnalyticsParameterTerm) = @"term"; + +/// A single ID for a ecommerce group transaction (NSString). +///
+///     NSDictionary *params = @{
+///       kFIRParameterTransactionID : @"ab7236dd9823",
+///       // ...
+///     };
+/// 
+static NSString *const kFIRParameterTransactionID NS_SWIFT_NAME(AnalyticsParameterTransactionID) = + @"transaction_id"; + +/// Travel class (NSString). +///
+///     NSDictionary *params = @{
+///       kFIRParameterTravelClass : @"business",
+///       // ...
+///     };
+/// 
+static NSString *const kFIRParameterTravelClass NS_SWIFT_NAME(AnalyticsParameterTravelClass) = + @"travel_class"; + +/// A context-specific numeric value which is accumulated automatically for each event type. This is +/// a general purpose parameter that is useful for accumulating a key metric that pertains to an +/// event. Examples include revenue, distance, time and points. Value should be specified as signed +/// 64-bit integer or double as NSNumber. Notes: Values for pre-defined currency-related events +/// (such as @c kFIREventAddToCart) should be supplied using double as NSNumber and must be +/// accompanied by a @c kFIRParameterCurrency parameter. The valid range of accumulated values is +/// [-9,223,372,036,854.77, 9,223,372,036,854.77]. Supplying a non-numeric value, omitting the +/// corresponding @c kFIRParameterCurrency parameter, or supplying an invalid +/// currency code for conversion events will cause that +/// conversion to be omitted from reporting. +///
+///     NSDictionary *params = @{
+///       kFIRParameterValue : @(3.99),
+///       kFIRParameterCurrency : @"USD",  // e.g. $3.99 USD
+///       // ...
+///     };
+/// 
+static NSString *const kFIRParameterValue NS_SWIFT_NAME(AnalyticsParameterValue) = @"value"; + +/// Name of virtual currency type (NSString). +///
+///     NSDictionary *params = @{
+///       kFIRParameterVirtualCurrencyName : @"virtual_currency_name",
+///       // ...
+///     };
+/// 
+static NSString *const kFIRParameterVirtualCurrencyName + NS_SWIFT_NAME(AnalyticsParameterVirtualCurrencyName) = @"virtual_currency_name"; + +/// The name of a level in a game (NSString). +///
+///     NSDictionary *params = @{
+///       kFIRParameterLevelName : @"room_1",
+///       // ...
+///     };
+/// 
+static NSString *const kFIRParameterLevelName NS_SWIFT_NAME(AnalyticsParameterLevelName) = + @"level_name"; + +/// The result of an operation. Specify 1 to indicate success and 0 to indicate failure (unsigned +/// integer as NSNumber). +///
+///     NSDictionary *params = @{
+///       kFIRParameterSuccess : @(1),
+///       // ...
+///     };
+/// 
+static NSString *const kFIRParameterSuccess NS_SWIFT_NAME(AnalyticsParameterSuccess) = @"success"; + +/// Indicates that the associated event should either extend the current session +/// or start a new session if no session was active when the event was logged. +/// Specify YES to extend the current session or to start a new session; any +/// other value will not extend or start a session. +///
+///     NSDictionary *params = @{
+///       kFIRParameterExtendSession : @YES,
+///       // ...
+///     };
+/// 
+static NSString *const kFIRParameterExtendSession NS_SWIFT_NAME(AnalyticsParameterExtendSession) = + @"extend_session"; diff --git a/FoodApp/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/Headers/FIRUserPropertyNames.h b/FoodApp/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/Headers/FIRUserPropertyNames.h new file mode 100755 index 0000000..f50707f --- /dev/null +++ b/FoodApp/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/Headers/FIRUserPropertyNames.h @@ -0,0 +1,17 @@ +/// @file FIRUserPropertyNames.h +/// +/// Predefined user property names. +/// +/// A UserProperty is an attribute that describes the app-user. By supplying UserProperties, you can +/// later analyze different behaviors of various segments of your userbase. You may supply up to 25 +/// unique UserProperties per app, and you can use the name and value of your choosing for each one. +/// UserProperty names can be up to 24 characters long, may only contain alphanumeric characters and +/// underscores ("_"), and must start with an alphabetic character. UserProperty values can be up to +/// 36 characters long. The "firebase_", "google_", and "ga_" prefixes are reserved and should not +/// be used. + +#import + +/// The method used to sign in. For example, "google", "facebook" or "twitter". +static NSString *const kFIRUserPropertySignUpMethod + NS_SWIFT_NAME(AnalyticsUserPropertySignUpMethod) = @"sign_up_method"; diff --git a/FoodApp/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/Headers/FirebaseAnalytics.h b/FoodApp/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/Headers/FirebaseAnalytics.h new file mode 100755 index 0000000..ed7588a --- /dev/null +++ b/FoodApp/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/Headers/FirebaseAnalytics.h @@ -0,0 +1,5 @@ +#import "FIRAnalytics+AppDelegate.h" +#import "FIRAnalytics.h" +#import "FIREventNames.h" +#import "FIRParameterNames.h" +#import "FIRUserPropertyNames.h" diff --git a/FoodApp/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/Modules/module.modulemap b/FoodApp/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/Modules/module.modulemap new file mode 100755 index 0000000..6118e37 --- /dev/null +++ b/FoodApp/Pods/FirebaseAnalytics/Frameworks/FirebaseAnalytics.framework/Modules/module.modulemap @@ -0,0 +1,11 @@ +framework module FirebaseAnalytics { + umbrella header "FirebaseAnalytics.h" + export * + module * { export * } + link "sqlite3" + link "z" + link framework "Security" + link framework "StoreKit" + link framework "SystemConfiguration" + link framework "UIKit" +} diff --git a/FoodApp/Pods/FirebaseAnalytics/Frameworks/FirebaseCoreDiagnostics.framework/FirebaseCoreDiagnostics b/FoodApp/Pods/FirebaseAnalytics/Frameworks/FirebaseCoreDiagnostics.framework/FirebaseCoreDiagnostics new file mode 100755 index 0000000..4d6ec2c Binary files /dev/null and b/FoodApp/Pods/FirebaseAnalytics/Frameworks/FirebaseCoreDiagnostics.framework/FirebaseCoreDiagnostics differ diff --git a/FoodApp/Pods/FirebaseAnalytics/Frameworks/FirebaseCoreDiagnostics.framework/Modules/module.modulemap b/FoodApp/Pods/FirebaseAnalytics/Frameworks/FirebaseCoreDiagnostics.framework/Modules/module.modulemap new file mode 100755 index 0000000..ce076e0 --- /dev/null +++ b/FoodApp/Pods/FirebaseAnalytics/Frameworks/FirebaseCoreDiagnostics.framework/Modules/module.modulemap @@ -0,0 +1,7 @@ +framework module FirebaseCoreDiagnostics { + export * + module * { export * } + link "z" + link framework "Security" + link framework "SystemConfiguration" +} diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/CHANGELOG.md b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/CHANGELOG.md new file mode 100644 index 0000000..a4e3c96 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/CHANGELOG.md @@ -0,0 +1,193 @@ +# v5.4.2 +- Support new error code ERROR_INVALID_PROVIDER_ID. (#2629) + +# v5.4.1 +- Deprecate Microsoft and Yahoo OAuth Provider ID (#2517) +- Fix an issue where an exception was thrown when linking OAuth credentials. (#2521) +- Fix an issue where a wrong error was thrown when handling error with + FEDERATED_USER_ID_ALREADY_LINKED. (#2522) + +# v5.4.0 +- Add support of Generic IDP (#2405). + +# v5.3.0 +- Use the new registerInternalLibrary API to register with FirebaseCore. (#2137) + +# v5.2.0 +- Add support of Game Center sign in (#2127). + +# v5.1.0 +- Add support of custom FDL domain link (#2121). + +# v5.0.5 +- Restore SafariServices framework dependency (#2002). + +# v5.0.4 +- Fix analyzer issues (#1740). + +# v5.0.3 +- Add `FIRAuthErrorCodeMalformedJWT`, which is raised on JWT token parsing. + failures during auth operations (#1436). +- Migrate to use FirebaseAuthInterop interfaces to access FirebaseAuth (#1501). + +# v5.0.2 +- Fix an issue where JWT date timestamps weren't parsed correctly. (#1319) +- Fix an issue where anonymous accounts weren't correctly promoted to + non-anonymous when linked with passwordless email auth accounts. (#1383) +- Fix an exception from using an invalidated NSURLSession. (#1261) +- Fix a data race issue caught by the sanitizer. (#1446) + +# v5.0.1 +- Restore 4.x level of support for extensions (#1357). + +# v5.0.0 +- Adds APIs for phone Auth testing to bypass the verification flow (#1192). +- Changes the callback block signature for sign in and create user methods + to provide an AuthDataResult that includes the user and user info (#1123, #1186). +- Removes GoogleToolboxForMac dependency (#1175). +- Removes miscellaneous deprecated APIs (#1188, #1200). + +# v4.6.1 +- Fixes crash which occurred when certain Firebase IDTokens were being parsed (#1076). + +# v4.6.0 +- Adds `getIDTokenResultWithCompletion:` and `getIDTokenResultForcingRefresh:completion:` APIs which + call back with an AuthTokenResult object. The Auth token result object contains the ID token JWT string and other properties associated with the token including the decoded available payload claims (#1004). + +- Adds the `updateCurrentUser:completion:` API which sets the currentUser on the calling Auth instance to the provided user object (#1018). + +- Adds client-side validation to prevent setting `handleCodeInApp` to false when performing + email-link authentication. If `handleCodeInApp` is set to false an invalid argument exception + is thrown (#931). + +- Adds support for passing the deep link (which is embedded in the sign-in link sent via email) to the + `signInWithEmail:link:completion:` and `isSignInWithEmailLink:` methods during an + email/link sign-in flow (#1023). + +# v4.5.0 +- Adds new API which provides a way to determine the sign-in methods associated with an + email address. +- Adds new API which allows authentication using only an email link (Passwordless Authentication + with email link). + +# v4.4.4 +- Addresses CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF warnings that surface in newer versions of + Xcode and CocoaPods. +- Improves FIRUser documentation with clear message explaining when Firebase Auth attempts to validate + users and what happens when an invalidated user is detected (#694) . + +# v4.4.3 +- Adds an explicit dependency on CoreGraphics from Firebase Auth. + +# v4.4.2 +- Fixes bug where the FIRAuthResult object returned following a Phone Number authentication + always contained a nil FIRAdditionalUserInfo object. Now the FIRAdditionalUserInfo object is + never nil and its newUser field is populated correctly. + +# v4.4.0 +- Adds new APIs which return an AuthDataResult object after successfully creating an + Email/Password user, signing in anonymously, signing in with Email/Password and signing + in with Custom Token. The AuthDataResult object contains the new user and additional + information pertaining to the new user. + +# v4.3.2 +- Improves error handling for the phone number sign-in reCAPTCHA flow. +- Improves error handling for phone number linking flow. +- Fixes issue where after linking an anonymous user to a phone number the user remained + anonymous. + +# v4.3.1 +- Internal clean up. + +# v4.3.0 +- Provides account creation and last sign-in dates as metadata to the user + object. +- Returns more descriptive errors for some error cases of the phone number + sign-in reCAPTCHA flow. +- Fixes an issue that invalid users were not automatically signed out earlier. +- Fixes an issue that ID token listeners were not fired in some cases. + +# v4.2.1 +- Fixes a threading issue in phone number auth that completion block was not + executed on the main thread in some error cases. + +# v4.2.0 +- Adds new phone number verification API which makes use of an intelligent reCAPTCHA to verify the application. + +# v4.1.1 +- Improves some method documentation in headers. + +# v4.1.0 +- Allows the app to handle continue URL natively, e.g., from password reset + email. +- Allows the app to set language code, e.g., for sending password reset email. +- Fixes an issue that user's phone number did not persist on client. +- Fixes an issue that recover email action code type was reported as unknown. +- Improves app start-up time by moving initialization off from the main + thread. +- Better reports missing email error when creating a new password user. +- Changes console message logging levels to be more consistent with other + Firebase products on the iOS platform. + +# 2017-05-17 -- v4.0.0 +- Adds Phone Number Authentication. +- Adds support for generic OAuth2 identity providers. +- Adds methods that return additional user data from identity providers if + available when authenticating users. +- Improves session management by automatically refreshing tokens if possible + and signing out users if the session is detected invalidated, for example, + after the user changed password or deleted account from another device. +- Fixes an issue that reauthentication creates new user account if the user + credential is valid but does not match the currently signed in user. +- Fixes an issue that the "password" provider is not immediately listed on the + client side after adding a password to an account. +- Changes factory methods to return non-null FIRAuth instances or raises an + exception, instead of returning nullable instances. +- Changes auth state change listener to only be triggered when the user changes. +- Adds a new listener which is triggered whenever the ID token is changed. +- Switches ERROR_EMAIL_ALREADY_IN_USE to + ERROR_ACCOUNT_EXISTS_WITH_DIFFERENT_CREDENTIAL when the email used in the + signInWithCredential: call is already in use by another account. +- Deprecates FIREmailPasswordAuthProvider in favor of FIREmailAuthProvider. +- Deprecates getTokenWithCompletion in favor of getIDTokenWithCompletion on + FIRUser. +- Changes Swift API names to better align with Swift convention. + +# 2017-02-06 -- v3.1.1 +- Allows handling of additional errors when sending OOB action emails. The + server can respond with the following new error messages: + INVALID_MESSAGE_PAYLOAD,INVALID_SENDER and INVALID_RECIPIENT_EMAIL. +- Removes incorrect reference to FIRAuthErrorCodeCredentialTooOld in FIRUser.h. +- Provides additional error information from server if available. + +# 2016-12-13 -- v3.1.0 +- Adds FIRAuth methods that enable the app to follow up with user actions + delivered by email, such as verifying email address or reset password. +- No longer applies the keychain workaround introduced in v3.0.5 on iOS 10.2 + simulator or above since the issue has been fixed. +- Fixes nullability compilation warnings when used in Swift. +- Better reports missing password error. + +# 2016-10-24 -- v3.0.6 +- Switches to depend on open sourced GoogleToolboxForMac and GTMSessionFetcher. +- Improves logging of keychain error when initializing. + +# 2016-09-14 -- v3.0.5 +- Works around a keychain issue in iOS 10 simulator. +- Reports the correct error for invalid email when signing in with email and + password. + +# 2016-07-18 -- v3.0.4 +- Fixes a race condition bug that could crash the app with an exception from + NSURLSession on iOS 9. + +# 2016-06-20 -- v3.0.3 +- Adds documentation for all possible errors returned by each method. +- Improves error handling and messages for a variety of error conditions. +- Whether or not an user is considered anonymous is now consistent with other + platforms. +- A saved signed in user is now siloed between different Firebase projects + within the same app. + +# 2016-05-18 -- v3.0.2 +- Initial public release. diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/README.md b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/README.md new file mode 100644 index 0000000..f6e123e --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/README.md @@ -0,0 +1,17 @@ +# Firebase Auth for iOS + +Firebase Auth enables apps to easily support multiple authentication options +for their end users. + +Please visit [our developer site](https://firebase.google.com/docs/auth/) for +integration instructions, documentation, support information, and terms of +service. + +# Firebase Auth Development + +Example/Auth contains a set of samples and tests that integrate with +FirebaseAuth. + +The unit tests run without any additional configuration along with the rest of +Firebase. See [Example/Auth/README.md](../../Example/Auth/README.md) for +information about setting up, running, and testing the samples. diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/AuthProviders/EmailPassword/FIREmailAuthProvider.m b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/AuthProviders/EmailPassword/FIREmailAuthProvider.m new file mode 100644 index 0000000..ff7e004 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/AuthProviders/EmailPassword/FIREmailAuthProvider.m @@ -0,0 +1,43 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIREmailAuthProvider.h" + +#import "FIREmailPasswordAuthCredential.h" + +// FIREmailPasswordAuthProviderID is defined in FIRAuthProvider.m. + +NS_ASSUME_NONNULL_BEGIN + +@implementation FIREmailAuthProvider + +- (instancetype)init { + @throw [NSException exceptionWithName:@"Attempt to call unavailable initializer." + reason:@"This class is not meant to be initialized." + userInfo:nil]; +} + ++ (FIRAuthCredential *)credentialWithEmail:(NSString *)email password:(NSString *)password { + return [[FIREmailPasswordAuthCredential alloc] initWithEmail:email password:password]; +} + ++ (FIRAuthCredential *)credentialWithEmail:(NSString *)email link:(NSString *)link { + return [[FIREmailPasswordAuthCredential alloc] initWithEmail:email link:link]; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/AuthProviders/EmailPassword/FIREmailPasswordAuthCredential.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/AuthProviders/EmailPassword/FIREmailPasswordAuthCredential.h new file mode 100644 index 0000000..dc719ac --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/AuthProviders/EmailPassword/FIREmailPasswordAuthCredential.h @@ -0,0 +1,61 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +#import "FIRAuthCredential_Internal.h" + +NS_ASSUME_NONNULL_BEGIN + +/** @class FIREmailPasswordAuthCredential + @brief Internal implementation of FIRAuthCredential for Email/Password credentials. + */ +@interface FIREmailPasswordAuthCredential : FIRAuthCredential + +/** @property email + @brief The user's email address. + */ +@property(nonatomic, readonly) NSString *email; + +/** @property password + @brief The user's password. + */ +@property(nonatomic, readonly) NSString *password; + +/** @property link + @brief The email sign-in link. + */ +@property(nonatomic, readonly) NSString *link; + +/** @fn initWithEmail:password: + @brief Designated initializer. + @param email The user's email address. + @param password The user's password. + */ +- (nullable instancetype)initWithEmail:(NSString *)email password:(NSString *)password + NS_DESIGNATED_INITIALIZER; + +/** @fn initWithEmail:link: + @brief Designated initializer. + @param email The user's email address. + @param link The email sign-in link. + */ +- (nullable instancetype)initWithEmail:(NSString *)email link:(NSString *)link + NS_DESIGNATED_INITIALIZER; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/AuthProviders/EmailPassword/FIREmailPasswordAuthCredential.m b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/AuthProviders/EmailPassword/FIREmailPasswordAuthCredential.m new file mode 100644 index 0000000..84c1461 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/AuthProviders/EmailPassword/FIREmailPasswordAuthCredential.m @@ -0,0 +1,90 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIREmailPasswordAuthCredential.h" + +#import "FIREmailAuthProvider.h" +#import "FIRAuthExceptionUtils.h" +#import "FIRVerifyAssertionRequest.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface FIREmailPasswordAuthCredential () + +- (nullable instancetype)initWithProvider:(NSString *)provider NS_UNAVAILABLE; + +@end + +@implementation FIREmailPasswordAuthCredential + +- (nullable instancetype)initWithProvider:(NSString *)provider { + [FIRAuthExceptionUtils raiseMethodNotImplementedExceptionWithReason: + @"Please call the designated initializer."]; + return nil; +} + +- (nullable instancetype)initWithEmail:(NSString *)email password:(NSString *)password { + self = [super initWithProvider:FIREmailAuthProviderID]; + if (self) { + _email = [email copy]; + _password = [password copy]; + } + return self; +} + +- (nullable instancetype)initWithEmail:(NSString *)email link:(NSString *)link { + self = [super initWithProvider:FIREmailAuthProviderID]; + if (self) { + _email = [email copy]; + _link = [link copy]; + } + return self; +} + +- (void)prepareVerifyAssertionRequest:(FIRVerifyAssertionRequest *)request { + [FIRAuthExceptionUtils raiseMethodNotImplementedExceptionWithReason: + @"Attempt to call prepareVerifyAssertionRequest: on a FIREmailPasswordAuthCredential."]; +} + +#pragma mark - NSSecureCoding + ++ (BOOL)supportsSecureCoding { + return YES; +} + +- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder { + NSString *email = [aDecoder decodeObjectOfClass:[NSString class] forKey:@"email"]; + NSString *password = [aDecoder decodeObjectOfClass:[NSString class] forKey:@"password"]; + NSString *link = [aDecoder decodeObjectOfClass:[NSString class] forKey:@"link"]; + if (email.length && password.length) { + self = [self initWithEmail:email password:password]; + } else if (email.length && link.length) { + self = [self initWithEmail:email link:link]; + } else { + self = nil; + } + return self; +} + +- (void)encodeWithCoder:(NSCoder *)aCoder { + [aCoder encodeObject:self.email forKey:@"email"]; + [aCoder encodeObject:self.password forKey:@"password"]; + [aCoder encodeObject:self.link forKey:@"link"]; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/AuthProviders/Facebook/FIRFacebookAuthCredential.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/AuthProviders/Facebook/FIRFacebookAuthCredential.h new file mode 100644 index 0000000..29849a1 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/AuthProviders/Facebook/FIRFacebookAuthCredential.h @@ -0,0 +1,36 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +#import "FIRAuthCredential_Internal.h" + +NS_ASSUME_NONNULL_BEGIN + +/** @class FIRFacebookAuthCredential + @brief Internal implementation of FIRAuthCredential for the Facebook IdP. + */ +@interface FIRFacebookAuthCredential : FIRAuthCredential + +/** @fn initWithAccessToken: + @brief Designated initializer. + @param accessToken The Access Token obtained from Facebook. + */ +- (nullable instancetype)initWithAccessToken:(NSString *)accessToken NS_DESIGNATED_INITIALIZER; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/AuthProviders/Facebook/FIRFacebookAuthCredential.m b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/AuthProviders/Facebook/FIRFacebookAuthCredential.m new file mode 100644 index 0000000..4f10860 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/AuthProviders/Facebook/FIRFacebookAuthCredential.m @@ -0,0 +1,71 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRFacebookAuthCredential.h" + +#import "FIRFacebookAuthProvider.h" +#import "FIRAuthExceptionUtils.h" +#import "FIRVerifyAssertionRequest.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface FIRFacebookAuthCredential () + +- (nullable instancetype)initWithProvider:(NSString *)provider NS_UNAVAILABLE; + +@end + +@implementation FIRFacebookAuthCredential { + NSString *_accessToken; +} + +- (nullable instancetype)initWithProvider:(NSString *)provider { + [FIRAuthExceptionUtils raiseMethodNotImplementedExceptionWithReason: + @"Please call the designated initializer."]; + return nil; +} + +- (nullable instancetype)initWithAccessToken:(NSString *)accessToken { + self = [super initWithProvider:FIRFacebookAuthProviderID]; + if (self) { + _accessToken = [accessToken copy]; + } + return self; +} + +- (void)prepareVerifyAssertionRequest:(FIRVerifyAssertionRequest *)request { + request.providerAccessToken = _accessToken; +} + +#pragma mark - NSSecureCoding + ++ (BOOL)supportsSecureCoding { + return YES; +} + +- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder { + NSString *accessToken = [aDecoder decodeObjectOfClass:[NSString class] forKey:@"accessToken"]; + self = [self initWithAccessToken:accessToken]; + return self; +} + +- (void)encodeWithCoder:(NSCoder *)aCoder { + [aCoder encodeObject:_accessToken forKey:@"accessToken"]; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/AuthProviders/Facebook/FIRFacebookAuthProvider.m b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/AuthProviders/Facebook/FIRFacebookAuthProvider.m new file mode 100644 index 0000000..d850830 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/AuthProviders/Facebook/FIRFacebookAuthProvider.m @@ -0,0 +1,40 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRFacebookAuthProvider.h" + +#import "FIRFacebookAuthCredential.h" +#import "FIRAuthExceptionUtils.h" + +// FIRFacebookAuthProviderID is defined in FIRAuthProvider.m. + +NS_ASSUME_NONNULL_BEGIN + +@implementation FIRFacebookAuthProvider + +- (instancetype)init { + [FIRAuthExceptionUtils raiseMethodNotImplementedExceptionWithReason: + @"This class is not meant to be initialized."]; + return nil; +} + ++ (FIRAuthCredential *)credentialWithAccessToken:(NSString *)accessToken { + return [[FIRFacebookAuthCredential alloc] initWithAccessToken:accessToken]; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/AuthProviders/GameCenter/FIRGameCenterAuthCredential.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/AuthProviders/GameCenter/FIRGameCenterAuthCredential.h new file mode 100644 index 0000000..ee1d21b --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/AuthProviders/GameCenter/FIRGameCenterAuthCredential.h @@ -0,0 +1,80 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#import + +#import "FIRAuthCredential.h" + +NS_ASSUME_NONNULL_BEGIN + +/** @class FIRGameCenterAuthCredential + @brief Internal implementation of FIRAuthCredential for Game Center credentials. + */ +@interface FIRGameCenterAuthCredential : FIRAuthCredential + +/** @property playerID + @brief The ID of the Game Center local player. + */ +@property(nonatomic, readonly) NSString *playerID; + +/** @property publicKeyURL + @brief The URL for the public encryption key. + */ +@property(nonatomic, readonly) NSURL *publicKeyURL; + +/** @property signature + @brief The verification signature data generated. + */ +@property(nonatomic, readonly) NSData *signature; + +/** @property salt + @brief A random string used to compute the hash and keep it randomized. + */ +@property(nonatomic, readonly) NSData *salt; + +/** @property timestamp + @brief The date and time that the signature was created. + */ +@property(nonatomic, readonly) uint64_t timestamp; + +/** @property displayName + @brief The date and time that the signature was created. + */ +@property(nonatomic, readonly) NSString *displayName; + +/** @fn initWithPlayerID:publicKeyURL:signature:salt:timestamp:displayName: + @brief Designated initializer. + @param publicKeyURL The URL for the public encryption key. + @param signature The verification signature generated. + @param salt A random string used to compute the hash and keep it randomized. + @param timestamp The date and time that the signature was created. + */ +- (nullable instancetype)initWithPlayerID:(NSString *)playerID + publicKeyURL:(NSURL *)publicKeyURL + signature:(NSData *)signature + salt:(NSData *)salt + timestamp:(uint64_t)timestamp + displayName:(NSString *)displayName NS_DESIGNATED_INITIALIZER; + +/** @fn initWithProvider: + @brief Initializer with a provider name. + @param provider The provider name. + */ +- (nullable instancetype)initWithProvider:(NSString *)provider NS_UNAVAILABLE; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/AuthProviders/GameCenter/FIRGameCenterAuthCredential.m b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/AuthProviders/GameCenter/FIRGameCenterAuthCredential.m new file mode 100644 index 0000000..91a4b68 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/AuthProviders/GameCenter/FIRGameCenterAuthCredential.m @@ -0,0 +1,90 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#import "FIRGameCenterAuthCredential.h" + +#import "FIRAuthExceptionUtils.h" +#import "FIRAuthCredential_Internal.h" +#import "FIRGameCenterAuthProvider.h" +#import "FIRVerifyAssertionRequest.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation FIRGameCenterAuthCredential + +- (nullable instancetype)initWithProvider:(NSString *)provider { + [FIRAuthExceptionUtils raiseMethodNotImplementedExceptionWithReason: + @"Please call the designated initializer."]; + return nil; +} + +- (nullable instancetype)initWithPlayerID:(NSString *)playerID + publicKeyURL:(NSURL *)publicKeyURL + signature:(NSData *)signature + salt:(NSData *)salt + timestamp:(uint64_t)timestamp + displayName:(NSString *)displayName { + self = [super initWithProvider:FIRGameCenterAuthProviderID]; + if (self) { + _playerID = [playerID copy]; + _publicKeyURL = [publicKeyURL copy]; + _signature = [signature copy]; + _salt = [salt copy]; + _timestamp = timestamp; + _displayName = [displayName copy]; + } + return self; +} + +- (void)prepareVerifyAssertionRequest:(FIRVerifyAssertionRequest *)request { + [FIRAuthExceptionUtils raiseMethodNotImplementedExceptionWithReason: + @"Attempt to call prepareVerifyAssertionRequest: on a FIRGameCenterAuthCredential."]; +} + +#pragma mark - NSSecureCoding + ++ (BOOL)supportsSecureCoding { + return YES; +} + +- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder { + NSString *playerID = [aDecoder decodeObjectOfClass:[NSString class] forKey:@"playerID"]; + NSURL *publicKeyURL = [aDecoder decodeObjectOfClass:[NSURL class] forKey:@"publicKeyURL"]; + NSData *signature = [aDecoder decodeObjectOfClass:[NSData class] forKey:@"signature"]; + NSData *salt = [aDecoder decodeObjectOfClass:[NSData class] forKey:@"salt"]; + NSNumber *timestamp = [aDecoder decodeObjectOfClass:[NSNumber class] forKey:@"timestamp"]; + NSString *displayName = [aDecoder decodeObjectOfClass:[NSString class] forKey:@"displayName"]; + self = [self initWithPlayerID:playerID + publicKeyURL:publicKeyURL + signature:signature + salt:salt + timestamp:timestamp.unsignedLongLongValue + displayName:displayName]; + return self; +} + +- (void)encodeWithCoder:(NSCoder *)aCoder { + [aCoder encodeObject:self.playerID forKey:@"playerID"]; + [aCoder encodeObject:self.publicKeyURL forKey:@"publicKeyURL"]; + [aCoder encodeObject:self.signature forKey:@"signature"]; + [aCoder encodeObject:self.salt forKey:@"salt"]; + [aCoder encodeObject:[NSNumber numberWithUnsignedLongLong:self.timestamp] forKey:@"timestamp"]; + [aCoder encodeObject:self.displayName forKey:@"displayName"]; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/AuthProviders/GameCenter/FIRGameCenterAuthProvider.m b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/AuthProviders/GameCenter/FIRGameCenterAuthProvider.m new file mode 100644 index 0000000..af8e7e6 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/AuthProviders/GameCenter/FIRGameCenterAuthProvider.m @@ -0,0 +1,88 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#import "FIRGameCenterAuthProvider.h" + +#import + +#import "FIRAuthErrorUtils.h" +#import "FIRAuthExceptionUtils.h" +#import "FIRGameCenterAuthCredential.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation FIRGameCenterAuthProvider + +- (instancetype)init { + [FIRAuthExceptionUtils raiseMethodNotImplementedExceptionWithReason: + @"This class is not meant to be initialized."]; + return nil; +} + ++ (void)getCredentialWithCompletion:(FIRGameCenterCredentialCallback)completion { + /** + Linking GameKit.framework without using it on macOS results in App Store rejection. + Thus we don't link GameKit.framework to our SDK directly. `optionalLocalPlayer` is used for + checking whether the APP that consuming our SDK has linked GameKit.framework. If not, a + `GameKitNotLinkedError` will be raised. + **/ + GKLocalPlayer * _Nullable optionalLocalPlayer = [[NSClassFromString(@"GKLocalPlayer") alloc] init]; + + if (!optionalLocalPlayer) { + if (completion) { + completion(nil, [FIRAuthErrorUtils gameKitNotLinkedError]); + } + return; + } + + __weak GKLocalPlayer *localPlayer = [[optionalLocalPlayer class] localPlayer]; + if (!localPlayer.isAuthenticated) { + if (completion) { + completion(nil, [FIRAuthErrorUtils localPlayerNotAuthenticatedError]); + } + return; + } + + [localPlayer generateIdentityVerificationSignatureWithCompletionHandler: + ^(NSURL *publicKeyURL, NSData *signature, NSData *salt, uint64_t timestamp, NSError *error) { + if (error) { + if (completion) { + completion(nil, error); + } + } else { + if (completion) { + /** + @c `localPlayer.alias` is actually the displayname needed, instead of + `localPlayer.displayname`. For more information, check + https://developer.apple.com/documentation/gamekit/gkplayer + **/ + NSString *displayName = localPlayer.alias; + FIRGameCenterAuthCredential *credential = + [[FIRGameCenterAuthCredential alloc] initWithPlayerID:localPlayer.playerID + publicKeyURL:publicKeyURL + signature:signature + salt:salt + timestamp:timestamp + displayName:displayName]; + completion(credential, nil); + } + } + }]; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/AuthProviders/GitHub/FIRGitHubAuthCredential.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/AuthProviders/GitHub/FIRGitHubAuthCredential.h new file mode 100644 index 0000000..ba406f7 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/AuthProviders/GitHub/FIRGitHubAuthCredential.h @@ -0,0 +1,41 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +#import "FIRAuthCredential_Internal.h" + +NS_ASSUME_NONNULL_BEGIN + +/** @class FIRGitHubAuthCredential + @brief Internal implementation of FIRAuthCredential for GitHub credentials. + */ +@interface FIRGitHubAuthCredential : FIRAuthCredential + +/** @property token + @brief The GitHub OAuth access token. + */ +@property(nonatomic, readonly) NSString *token; + +/** @fn initWithToken: + @brief Designated initializer. + @param token The GitHub OAuth access token. + */ +- (nullable instancetype)initWithToken:(NSString *)token NS_DESIGNATED_INITIALIZER; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/AuthProviders/GitHub/FIRGitHubAuthCredential.m b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/AuthProviders/GitHub/FIRGitHubAuthCredential.m new file mode 100644 index 0000000..f6b536d --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/AuthProviders/GitHub/FIRGitHubAuthCredential.m @@ -0,0 +1,69 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRGitHubAuthCredential.h" + +#import "FIRGitHubAuthProvider.h" +#import "FIRAuthExceptionUtils.h" +#import "FIRVerifyAssertionRequest.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface FIRGitHubAuthCredential () + +- (nullable instancetype)initWithProvider:(NSString *)provider NS_UNAVAILABLE; + +@end + +@implementation FIRGitHubAuthCredential + +- (nullable instancetype)initWithProvider:(NSString *)provider { + [FIRAuthExceptionUtils raiseMethodNotImplementedExceptionWithReason: + @"Please call the designated initializer."]; + return nil; +} + +- (nullable instancetype)initWithToken:(NSString *)token { + self = [super initWithProvider:FIRGitHubAuthProviderID]; + if (self) { + _token = [token copy]; + } + return self; +} + +- (void)prepareVerifyAssertionRequest:(FIRVerifyAssertionRequest *)request { + request.providerAccessToken = _token; +} + +#pragma mark - NSSecureCoding + ++ (BOOL)supportsSecureCoding { + return YES; +} + +- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder { + NSString *token = [aDecoder decodeObjectOfClass:[NSString class] forKey:@"token"]; + self = [self initWithToken:token]; + return self; +} + +- (void)encodeWithCoder:(NSCoder *)aCoder { + [aCoder encodeObject:self.token forKey:@"token"]; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/AuthProviders/GitHub/FIRGitHubAuthProvider.m b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/AuthProviders/GitHub/FIRGitHubAuthProvider.m new file mode 100644 index 0000000..fa6be66 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/AuthProviders/GitHub/FIRGitHubAuthProvider.m @@ -0,0 +1,40 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRGitHubAuthProvider.h" + +#import "FIRGitHubAuthCredential.h" +#import "FIRAuthExceptionUtils.h" + +// FIRGitHubAuthProviderID is defined in FIRAuthProvider.m. + +NS_ASSUME_NONNULL_BEGIN + +@implementation FIRGitHubAuthProvider + +- (instancetype)init { + [FIRAuthExceptionUtils raiseMethodNotImplementedExceptionWithReason: + @"This class is not meant to be initialized."]; + return nil; +} + ++ (FIRAuthCredential *)credentialWithToken:(NSString *)token { + return [[FIRGitHubAuthCredential alloc] initWithToken:token]; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/AuthProviders/Google/FIRGoogleAuthCredential.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/AuthProviders/Google/FIRGoogleAuthCredential.h new file mode 100644 index 0000000..23e2d68 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/AuthProviders/Google/FIRGoogleAuthCredential.h @@ -0,0 +1,38 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +#import "FIRAuthCredential_Internal.h" + +NS_ASSUME_NONNULL_BEGIN + +/** @class FIRGoogleAuthCredential + @brief Internal implementation of FIRAuthCredential for the Google IdP. + */ +@interface FIRGoogleAuthCredential : FIRAuthCredential + +/** @fn initWithIDToken:accessToken: + @brief Designated initializer. + @param IDToken The ID Token obtained from Google. + @param accessToken The Access Token obtained from Google. + */ +- (nullable instancetype)initWithIDToken:(NSString *)IDToken accessToken:(NSString *)accessToken + NS_DESIGNATED_INITIALIZER; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/AuthProviders/Google/FIRGoogleAuthCredential.m b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/AuthProviders/Google/FIRGoogleAuthCredential.m new file mode 100644 index 0000000..a4676d9 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/AuthProviders/Google/FIRGoogleAuthCredential.m @@ -0,0 +1,76 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRGoogleAuthCredential.h" + +#import "FIRGoogleAuthProvider.h" +#import "FIRAuthExceptionUtils.h" +#import "FIRVerifyAssertionRequest.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface FIRGoogleAuthCredential () + +- (nullable instancetype)initWithProvider:(NSString *)provider NS_UNAVAILABLE; + +@end + +@implementation FIRGoogleAuthCredential { + NSString *_IDToken; + NSString *_accessToken; +} + +- (nullable instancetype)initWithProvider:(NSString *)provider { + [FIRAuthExceptionUtils raiseMethodNotImplementedExceptionWithReason: + @"Please call the designated initializer."]; + return nil; +} + +- (nullable instancetype)initWithIDToken:(NSString *)IDToken accessToken:(NSString *)accessToken { + self = [super initWithProvider:FIRGoogleAuthProviderID]; + if (self) { + _IDToken = [IDToken copy]; + _accessToken = [accessToken copy]; + } + return self; +} + +- (void)prepareVerifyAssertionRequest:(FIRVerifyAssertionRequest *)request { + request.providerIDToken = _IDToken; + request.providerAccessToken = _accessToken; +} + +#pragma mark - NSSecureCoding + ++ (BOOL)supportsSecureCoding { + return YES; +} + +- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder { + NSString *IDToken = [aDecoder decodeObjectOfClass:[NSString class] forKey:@"IDToken"]; + NSString *accessToken = [aDecoder decodeObjectOfClass:[NSString class] forKey:@"accessToken"]; + self = [self initWithIDToken:IDToken accessToken:accessToken]; + return self; +} + +- (void)encodeWithCoder:(NSCoder *)aCoder { + [aCoder encodeObject:_IDToken forKey:@"IDToken"]; + [aCoder encodeObject:_accessToken forKey:@"accessToken"]; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/AuthProviders/Google/FIRGoogleAuthProvider.m b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/AuthProviders/Google/FIRGoogleAuthProvider.m new file mode 100644 index 0000000..93a33d8 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/AuthProviders/Google/FIRGoogleAuthProvider.m @@ -0,0 +1,41 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRGoogleAuthProvider.h" + +#import "FIRGoogleAuthCredential.h" +#import "FIRAuthExceptionUtils.h" + +// FIRGoogleAuthProviderID is defined in FIRAuthProvider.m. + +NS_ASSUME_NONNULL_BEGIN + +@implementation FIRGoogleAuthProvider + +- (instancetype)init { + [FIRAuthExceptionUtils raiseMethodNotImplementedExceptionWithReason: + @"This class is not meant to be initialized."]; + return nil; +} + ++ (FIRAuthCredential *)credentialWithIDToken:(NSString *)IDToken + accessToken:(NSString *)accessToken { + return [[FIRGoogleAuthCredential alloc] initWithIDToken:IDToken accessToken:accessToken]; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/AuthProviders/OAuth/FIROAuthCredential.m b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/AuthProviders/OAuth/FIROAuthCredential.m new file mode 100644 index 0000000..ebea7be --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/AuthProviders/OAuth/FIROAuthCredential.m @@ -0,0 +1,94 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIROAuthCredential.h" + +#import "FIRAuthCredential_Internal.h" +#import "FIRAuthExceptionUtils.h" +#import "FIROAuthCredential_Internal.h" +#import "FIRVerifyAssertionRequest.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface FIROAuthCredential () + +- (nullable instancetype)initWithProvider:(NSString *)provider NS_UNAVAILABLE; + +@end + +@implementation FIROAuthCredential + +- (nullable instancetype)initWithProvider:(NSString *)provider { + [FIRAuthExceptionUtils raiseMethodNotImplementedExceptionWithReason: + @"Please call the designated initializer."]; + return nil; +} + +- (instancetype)initWithProviderID:(NSString *)providerID + IDToken:(nullable NSString *)IDToken + accessToken:(nullable NSString *)accessToken + pendingToken:(nullable NSString *)pendingToken { + self = [super initWithProvider:providerID]; + if (self) { + _IDToken = IDToken; + _accessToken = accessToken; + _pendingToken = pendingToken; + } + return self; +} + +- (instancetype)initWithProviderID:(NSString *)providerID + sessionID:(NSString *)sessionID + OAuthResponseURLString:(NSString *)OAuthResponseURLString { + self = [self initWithProviderID:providerID IDToken:nil accessToken:nil pendingToken:nil]; + if (self) { + _OAuthResponseURLString = OAuthResponseURLString; + _sessionID = sessionID; + } + return self; +} + +- (void)prepareVerifyAssertionRequest:(FIRVerifyAssertionRequest *)request { + request.providerIDToken = _IDToken; + request.providerAccessToken = _accessToken; +} + +#pragma mark - NSSecureCoding + ++ (BOOL)supportsSecureCoding { + return YES; +} + +- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder { + NSString *IDToken = [aDecoder decodeObjectOfClass:[NSString class] forKey:@"IDToken"]; + NSString *accessToken = [aDecoder decodeObjectOfClass:[NSString class] forKey:@"accessToken"]; + NSString *pendingToken = [aDecoder decodeObjectOfClass:[NSString class] forKey:@"pendingToken"]; + self = [self initWithProviderID:self.provider + IDToken:IDToken + accessToken:accessToken + pendingToken:pendingToken]; + return self; +} + +- (void)encodeWithCoder:(NSCoder *)aCoder { + [aCoder encodeObject:self.IDToken forKey:@"IDToken"]; + [aCoder encodeObject:self.accessToken forKey:@"accessToken"]; + [aCoder encodeObject:self.pendingToken forKey:@"pendingToken"]; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/AuthProviders/OAuth/FIROAuthCredential_Internal.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/AuthProviders/OAuth/FIROAuthCredential_Internal.h new file mode 100644 index 0000000..bcc3248 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/AuthProviders/OAuth/FIROAuthCredential_Internal.h @@ -0,0 +1,62 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +#import "FIROAuthCredential.h" + +NS_ASSUME_NONNULL_BEGIN + +/** @extension FIROAuthCredential + @brief Internal implementation of FIRAuthCredential for generic credentials. + */ +@interface FIROAuthCredential() + +/** @property OAuthResponseURLString + @brief A string representation of the response URL corresponding to this OAuthCredential. + */ +@property(nonatomic, readonly, nullable) NSString *OAuthResponseURLString; + +/** @property sessionID + @brief The session ID used when completing the headful-lite flow. + */ +@property(nonatomic, readonly, nullable) NSString *sessionID; + +/** @fn initWithProviderId:IDToken:accessToken:pendingToken + @brief Designated initializer. + @param providerID The provider ID associated with the credential being created. + @param IDToken The ID Token associated with the credential being created. + @param accessToken The access token associated with the credential being created. + @param pendingToken The pending token associated with the credential being created. + */ +- (instancetype)initWithProviderID:(NSString *)providerID + IDToken:(nullable NSString *)IDToken + accessToken:(nullable NSString *)accessToken + pendingToken:(nullable NSString *)pendingToken NS_DESIGNATED_INITIALIZER; + +/** @fn initWithProviderId:sessionID:OAuthResponseURLString: + @brief Intitializer which takes a sessionID and an OAuthResponseURLString. + @param providerID The provider ID associated with the credential being created. + @param sessionID The session ID used when completing the headful-lite flow. + @param OAuthResponseURLString The error that occurred if any. + */ +- (instancetype)initWithProviderID:(NSString *)providerID + sessionID:(NSString *)sessionID + OAuthResponseURLString:(NSString *)OAuthResponseURLString; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/AuthProviders/OAuth/FIROAuthProvider.m b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/AuthProviders/OAuth/FIROAuthProvider.m new file mode 100644 index 0000000..5557c16 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/AuthProviders/OAuth/FIROAuthProvider.m @@ -0,0 +1,359 @@ +/* + * Copyright 2017 Google + * + * 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 +#import "FIROAuthProvider.h" + +#import "FIRApp.h" +#import "FIRAuthBackend.h" +#import "FIRAuth_Internal.h" +#import "FIRAuthErrorUtils.h" +#import "FIRAuthGlobalWorkQueue.h" +#import "FIRAuthRequestConfiguration.h" +#import "FIRAuthWebUtils.h" +#import "FIROAuthCredential_Internal.h" +#import "FIROAuthCredential.h" +#import "FIROptions.h" + +#if TARGET_OS_IOS +#import "FIRAuthURLPresenter.h" +#endif + +NS_ASSUME_NONNULL_BEGIN + +/** @typedef FIRHeadfulLiteURLCallBack + @brief The callback invoked at the end of the flow to fetch a headful-lite URL. + @param headfulLiteURL The headful lite URL. + @param error The error that occurred while fetching the headful-lite, if any. + */ +typedef void (^FIRHeadfulLiteURLCallBack)(NSURL *_Nullable headfulLiteURL, + NSError *_Nullable error); + +/** @var kHeadfulLiteURLStringFormat + @brief The format of the URL used to open the headful lite page during sign-in. + */ +NSString *const kHeadfulLiteURLStringFormat = @"https://%@/__/auth/handler?%@"; + +/** @var kauthTypeSignInWithRedirect + @brief The auth type to be specified in the sign-in request with redirect request and response. + */ +static NSString *const kAuthTypeSignInWithRedirect = @"signInWithRedirect"; + +@implementation FIROAuthProvider { + /** @var _auth + @brief The auth instance used for launching the URL presenter. + */ + FIRAuth *_auth; + + /** @var _callbackScheme + @brief The callback URL scheme used for headful-lite sign-in. + */ + NSString *_callbackScheme; +} + ++ (FIROAuthCredential *)credentialWithProviderID:(NSString *)providerID + IDToken:(NSString *)IDToken + accessToken:(nullable NSString *)accessToken + pendingToken:(nullable NSString *)pendingToken { + return [[FIROAuthCredential alloc] initWithProviderID:providerID + IDToken:IDToken + accessToken:accessToken + pendingToken:pendingToken]; +} + ++ (FIROAuthCredential *)credentialWithProviderID:(NSString *)providerID + IDToken:(NSString *)IDToken + accessToken:(nullable NSString *)accessToken { + return [[FIROAuthCredential alloc] initWithProviderID:providerID + IDToken:IDToken + accessToken:accessToken + pendingToken:nil]; +} + ++ (FIROAuthCredential *)credentialWithProviderID:(NSString *)providerID + accessToken:(NSString *)accessToken { + return [[FIROAuthCredential alloc] initWithProviderID:providerID + IDToken:nil + accessToken:accessToken + pendingToken:nil]; +} + ++ (instancetype)providerWithProviderID:(NSString *)providerID { + return [[self alloc]initWithProviderID:providerID auth:[FIRAuth auth]]; +} + ++ (instancetype)providerWithProviderID:(NSString *)providerID auth:(FIRAuth *)auth { + return [[self alloc] initWithProviderID:providerID auth:auth]; +} + +#if TARGET_OS_IOS +- (void)getCredentialWithUIDelegate:(nullable id)UIDelegate + completion:(nullable FIRAuthCredentialCallback)completion { + if (![FIRAuthWebUtils isCallbackSchemeRegisteredForCustomURLScheme:self->_callbackScheme]) { + [NSException raise:NSInternalInconsistencyException + format:@"Please register custom URL scheme '%@' in the app's Info.plist file.", + self->_callbackScheme]; + } + __weak __typeof__(self) weakSelf = self; + __weak FIRAuth *weakAuth = _auth; + __weak NSString *weakProviderID = _providerID; + dispatch_async(FIRAuthGlobalWorkQueue(), ^{ + FIRAuthCredentialCallback callbackOnMainThread = ^(FIRAuthCredential *_Nullable credential, + NSError *_Nullable error) { + if (completion) { + dispatch_async(dispatch_get_main_queue(), ^{ + completion(credential, error); + }); + } + }; + NSString *eventID = [FIRAuthWebUtils randomStringWithLength:10]; + NSString *sessionID = [FIRAuthWebUtils randomStringWithLength:10]; + __strong __typeof__(self) strongSelf = weakSelf; + [strongSelf getHeadFulLiteURLWithEventID:eventID + sessionID:sessionID + completion:^(NSURL *_Nullable headfulLiteURL, + NSError *_Nullable error) { + if (error) { + callbackOnMainThread(nil, error); + return; + } + FIRAuthURLCallbackMatcher callbackMatcher = ^BOOL(NSURL *_Nullable callbackURL) { + return [FIRAuthWebUtils isExpectedCallbackURL:callbackURL + eventID:eventID + authType:kAuthTypeSignInWithRedirect + callbackScheme:strongSelf->_callbackScheme]; + }; + __strong FIRAuth *strongAuth = weakAuth; + [strongAuth.authURLPresenter presentURL:headfulLiteURL + UIDelegate:UIDelegate + callbackMatcher:callbackMatcher + completion:^(NSURL *_Nullable callbackURL, + NSError *_Nullable error) { + if (error) { + callbackOnMainThread(nil, error); + return; + } + NSString *OAuthResponseURLString = + [strongSelf OAuthResponseForURL:callbackURL error:&error]; + if (error) { + callbackOnMainThread(nil, error); + return; + } + __strong NSString *strongProviderID = weakProviderID; + FIROAuthCredential *credential = + [[FIROAuthCredential alloc] initWithProviderID:strongProviderID + sessionID:sessionID + OAuthResponseURLString:OAuthResponseURLString]; + callbackOnMainThread(credential, nil); + }]; + }]; + }); +} +#endif // TARGET_OS_IOS + +#pragma mark - Internal Methods + +/** @fn initWithProviderID:auth: + @brief returns an instance of @c FIROAuthProvider associated with the provided auth instance. + @param auth The Auth instance to be associated with the OAuthProvider instance. + @return An Instance of @c FIROAuthProvider. + */ +- (nullable instancetype)initWithProviderID:(NSString *)providerID auth:(FIRAuth *)auth { + self = [super init]; + if (self) { + _auth = auth; + _providerID = providerID; + _callbackScheme = [[[_auth.app.options.clientID componentsSeparatedByString:@"."] + reverseObjectEnumerator].allObjects componentsJoinedByString:@"."]; + } + return self; +} + +/** @fn OAuthResponseForURL:error: + @brief Parses the redirected URL and returns a string representation of the OAuth response URL. + @param URL The url to be parsed for an OAuth response URL. + @param error The error that occurred if any. + @return The OAuth response if successful. + */ +- (nullable NSString *)OAuthResponseForURL:(NSURL *)URL error:(NSError *_Nullable *_Nullable)error { + NSDictionary *URLQueryItems = + [FIRAuthWebUtils dictionaryWithHttpArgumentsString:URL.query]; + NSURL *deepLinkURL = [NSURL URLWithString:URLQueryItems[@"deep_link_id"]]; + URLQueryItems = + [FIRAuthWebUtils dictionaryWithHttpArgumentsString:deepLinkURL.query]; + NSString *queryItemLink = URLQueryItems[@"link"]; + if (queryItemLink) { + return queryItemLink; + } + if (!error) { + return nil; + } + NSData *errorData = [URLQueryItems[@"firebaseError"] dataUsingEncoding:NSUTF8StringEncoding]; + NSError *jsonError; + NSDictionary *errorDict = [NSJSONSerialization JSONObjectWithData:errorData + options:0 + error:&jsonError]; + if (jsonError) { + *error = [FIRAuthErrorUtils JSONSerializationErrorWithUnderlyingError:jsonError]; + return nil; + } + *error = [FIRAuthErrorUtils URLResponseErrorWithCode:errorDict[@"code"] + message:errorDict[@"message"]]; + if (!*error) { + NSString *reason; + if(errorDict[@"code"] && errorDict[@"message"]) { + reason = [NSString stringWithFormat:@"[%@] - %@",errorDict[@"code"], errorDict[@"message"]]; + } + *error = [FIRAuthErrorUtils webSignInUserInteractionFailureWithReason:reason]; + } + return nil; +} + +/** @fn getHeadFulLiteURLWithEventID:completion: + @brief Constructs a URL used for opening a headful-lite flow using a given event + ID and session ID. + @param eventID The event ID used for this purpose. + @param sessionID The session ID used when completing the headful lite flow. + @param completion The callback invoked after the URL has been constructed or an error + has been encountered. + */ +- (void)getHeadFulLiteURLWithEventID:(NSString *)eventID + sessionID:(NSString *)sessionID + completion:(FIRHeadfulLiteURLCallBack)completion { + __weak __typeof__(self) weakSelf = self; + [FIRAuthWebUtils fetchAuthDomainWithRequestConfiguration:_auth.requestConfiguration + completion:^(NSString *_Nullable authDomain, + NSError *_Nullable error) { + if (error) { + if (completion) { + completion(nil, error); + } + return; + } + __strong __typeof__(self) strongSelf = weakSelf; + NSString *bundleID = [NSBundle mainBundle].bundleIdentifier; + NSString *clienID = strongSelf->_auth.app.options.clientID; + NSString *apiKey = strongSelf->_auth.requestConfiguration.APIKey; + NSMutableDictionary *urlArguments = [@{ + @"apiKey" : apiKey, + @"authType" : @"signInWithRedirect", + @"ibi" : bundleID ?: @"", + @"clientId" : clienID, + @"sessionId" : [strongSelf hashforString:sessionID], + @"v" : [FIRAuthBackend authUserAgent], + @"eventId" : eventID, + @"providerId" : strongSelf->_providerID, + } mutableCopy]; + if (strongSelf.scopes.count) { + urlArguments[@"scopes"] = [strongSelf.scopes componentsJoinedByString:@","]; + } + if (strongSelf.customParameters.count) { + NSString *customParameters = [strongSelf customParametersStringWithError:&error]; + if (error) { + completion(nil, error); + return; + } + if (customParameters) { + urlArguments[@"customParameters"] = customParameters; + } + } + if (strongSelf->_auth.requestConfiguration.languageCode) { + urlArguments[@"hl"] = strongSelf->_auth.requestConfiguration.languageCode; + } + NSString *argumentsString = [strongSelf httpArgumentsStringForArgsDictionary:urlArguments]; + NSString *URLString = + [NSString stringWithFormat:kHeadfulLiteURLStringFormat, authDomain, argumentsString]; + if (completion) { + NSCharacterSet *set = [NSCharacterSet URLFragmentAllowedCharacterSet]; + completion([NSURL URLWithString: + [URLString stringByAddingPercentEncodingWithAllowedCharacters:set]], nil); + } + }]; +} + +/** @fn customParametersString + @brief Returns a JSON string representation of the custom parameters dictionary corresponding + to the OAuthProvider. + @return The JSON string representation of the custom parameters dictionary corresponding + to the OAuthProvider. + */ +- (nullable NSString *)customParametersStringWithError:(NSError *_Nullable *_Nullable)error { + if (!_customParameters.count) { + return nil; + } + + if (!error) { + return nil; + } + NSError *jsonError; + NSData *customParametersJSONData = + [NSJSONSerialization dataWithJSONObject:_customParameters + options:0 + error:&jsonError]; + if (jsonError) { + *error = [FIRAuthErrorUtils JSONSerializationErrorWithUnderlyingError:jsonError]; + return nil; + } + + NSString *customParamsRawJSON = + [[NSString alloc] initWithData:customParametersJSONData encoding:NSUTF8StringEncoding]; + return customParamsRawJSON; +} + +/** @fn hashforString: + @brief Returns the SHA256 hash representation of a given string object. + @param string The string for which a SHA256 hash is desired. + @return An hexadecimal string representation of the SHA256 hash. + */ +- (NSString *)hashforString:(NSString *)string { + NSData *sessionIDData = [string dataUsingEncoding:NSUTF8StringEncoding]; + NSMutableData *hashOutputData = [NSMutableData dataWithLength:CC_SHA256_DIGEST_LENGTH]; + if (CC_SHA256(sessionIDData.bytes, + (CC_LONG)[sessionIDData length], + hashOutputData.mutableBytes)) { + } + return [self hexStringFromData:hashOutputData];; +} + +/** @fn hexStringFromData: + @brief Returns the hexadecimal string representation of an NSData object. + @param data The NSData object for which a hexadecical string is desired. + @return The hexadecimal string representation of the supplied NSData object. + */ +- (NSString *)hexStringFromData:(NSData *)data { + const unsigned char *dataBuffer = (const unsigned char *)[data bytes]; + NSMutableString *string = [[NSMutableString alloc] init]; + for (unsigned int i = 0; i < data.length; i++){ + [string appendFormat:@"%02lx", (unsigned long)dataBuffer[i]]; + } + return [string copy]; +} + +- (NSString *)httpArgumentsStringForArgsDictionary:(NSDictionary *)argsDictionary { + NSMutableArray* arguments = [NSMutableArray arrayWithCapacity:argsDictionary.count]; + NSString* key; + for (key in argsDictionary) { + NSString *description = [argsDictionary[key] description]; + [arguments addObject:[NSString stringWithFormat:@"%@=%@", + [FIRAuthWebUtils stringByUnescapingFromURLArgument:key], + [FIRAuthWebUtils stringByUnescapingFromURLArgument:description]]] ; + } + return [arguments componentsJoinedByString:@"&"]; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/AuthProviders/Phone/FIRPhoneAuthCredential.m b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/AuthProviders/Phone/FIRPhoneAuthCredential.m new file mode 100644 index 0000000..64f79b8 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/AuthProviders/Phone/FIRPhoneAuthCredential.m @@ -0,0 +1,92 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRPhoneAuthCredential.h" + +#import "FIRPhoneAuthCredential_Internal.h" +#import "FIRAuthCredential_Internal.h" +#import "FIRAuthExceptionUtils.h" +#import "FIRVerifyAssertionRequest.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface FIRPhoneAuthCredential () + +- (nullable instancetype)initWithProvider:(NSString *)provider NS_UNAVAILABLE; + +@end + +@implementation FIRPhoneAuthCredential + +- (instancetype)initWithTemporaryProof:(NSString *)temporaryProof + phoneNumber:(NSString *)phoneNumber + providerID:(NSString *)providerID { + self = [super initWithProvider:providerID]; + if (self) { + _temporaryProof = [temporaryProof copy]; + _phoneNumber = [phoneNumber copy]; + } + return self; +} + +- (nullable instancetype)initWithProvider:(NSString *)provider { + [FIRAuthExceptionUtils raiseMethodNotImplementedExceptionWithReason: + @"Please call the designated initializer."]; + return nil; +} + +- (instancetype)initWithProviderID:(NSString *)providerID + verificationID:(NSString *)verificationID + verificationCode:(NSString *)verificationCode { + self = [super initWithProvider:providerID]; + if (self) { + _verificationID = [verificationID copy]; + _verificationCode = [verificationCode copy]; + } + return self; +} + +#pragma mark - NSSecureCoding + ++ (BOOL)supportsSecureCoding { + return YES; +} + +- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder { + NSString *verificationID = [aDecoder decodeObjectOfClass:[NSString class] forKey:@"verificationID"]; + NSString *verificationCode = [aDecoder decodeObjectOfClass:[NSString class] forKey:@"verificationCode"]; + NSString *temporaryProof = [aDecoder decodeObjectOfClass:[NSString class] forKey:@"temporaryProof"]; + NSString *phoneNumber = [aDecoder decodeObjectOfClass:[NSString class] forKey:@"phoneNumber"]; + if (temporaryProof.length && phoneNumber.length) { + self = [self initWithTemporaryProof:temporaryProof phoneNumber:phoneNumber providerID:self.provider]; + } else if (verificationID.length && verificationCode.length) { + self = [self initWithProviderID:self.provider verificationID:verificationID verificationCode:verificationCode]; + } else { + self = nil; + } + return self; +} + +- (void)encodeWithCoder:(NSCoder *)aCoder { + [aCoder encodeObject:self.verificationID forKey:@"verificationID"]; + [aCoder encodeObject:self.verificationCode forKey:@"verificationCode"]; + [aCoder encodeObject:self.temporaryProof forKey:@"temporaryProof"]; + [aCoder encodeObject:self.phoneNumber forKey:@"phoneNumber"]; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/AuthProviders/Phone/FIRPhoneAuthCredential_Internal.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/AuthProviders/Phone/FIRPhoneAuthCredential_Internal.h new file mode 100644 index 0000000..f260b89 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/AuthProviders/Phone/FIRPhoneAuthCredential_Internal.h @@ -0,0 +1,70 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + + +#import + +#import "FIRPhoneAuthCredential.h" + +NS_ASSUME_NONNULL_BEGIN + +/** @extension FIRPhoneAuthCredential + @brief Internal implementation of FIRAuthCredential for Phone Auth credentials. + */ +@interface FIRPhoneAuthCredential () + +/** @var verificationID + @brief The verification ID obtained from invoking @c verifyPhoneNumber:completion: + */ +@property(nonatomic, readonly, nonnull) NSString *verificationID; + +/** @var verificationCode + @brief The verification code provided by the user. + */ +@property(nonatomic, readonly, nonnull) NSString *verificationCode; + +/** @var temporaryProof + @brief The a temporary proof code perftaining to this credential, returned from the backend. + */ +@property(nonatomic, readonly, nonnull) NSString *temporaryProof; + +/** @var phoneNumber + @brief The a phone number pertaining to this credential, returned from the backend. + */ +@property(nonatomic, readonly, nonnull) NSString *phoneNumber; + +/** @var initWithTemporaryProof:phoneNumber: + @brief Designated Initializer. + @param providerID The provider ID associated with the phone auth credential being created. + */ +- (instancetype)initWithTemporaryProof:(NSString *)temporaryProof + phoneNumber:(NSString *)phoneNumber + providerID:(NSString *)providerID NS_DESIGNATED_INITIALIZER; + +/** @var initWithProviderID:verificationID:verificationCode: + @brief Designated Initializer. + @param providerID The provider ID associated with the phone auth credential being created. + @param verificationID The verification ID associated witht Phone Auth credential being created. + @param verificationCode The verification code associated witht Phone Auth credential being + created. + */ +- (instancetype)initWithProviderID:(NSString *)providerID + verificationID:(NSString *)verificationID + verificationCode:(NSString *)verificationCode NS_DESIGNATED_INITIALIZER; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/AuthProviders/Phone/FIRPhoneAuthProvider.m b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/AuthProviders/Phone/FIRPhoneAuthProvider.m new file mode 100644 index 0000000..c8f1909 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/AuthProviders/Phone/FIRPhoneAuthProvider.m @@ -0,0 +1,429 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRPhoneAuthProvider.h" + +#import +#import "FIRPhoneAuthCredential_Internal.h" +#import +#import "FIRAuthAPNSToken.h" +#import "FIRAuthAPNSTokenManager.h" +#import "FIRAuthAppCredential.h" +#import "FIRAuthAppCredentialManager.h" +#import "FIRAuthGlobalWorkQueue.h" +#import "FIRAuth_Internal.h" +#import "FIRAuthURLPresenter.h" +#import "FIRAuthNotificationManager.h" +#import "FIRAuthErrorUtils.h" +#import "FIRAuthBackend.h" +#import "FIRAuthSettings.h" +#import "FIRAuthWebUtils.h" +#import "FirebaseAuthVersion.h" +#import +#import "FIRGetProjectConfigRequest.h" +#import "FIRGetProjectConfigResponse.h" +#import "FIRSendVerificationCodeRequest.h" +#import "FIRSendVerificationCodeResponse.h" +#import "FIRVerifyClientRequest.h" +#import "FIRVerifyClientResponse.h" + +NS_ASSUME_NONNULL_BEGIN + +/** @typedef FIRReCAPTCHAURLCallBack + @brief The callback invoked at the end of the flow to fetch a reCAPTCHA URL. + @param reCAPTCHAURL The reCAPTCHA URL. + @param error The error that occurred while fetching the reCAPTCHAURL, if any. + */ +typedef void (^FIRReCAPTCHAURLCallBack)(NSURL *_Nullable reCAPTCHAURL, NSError *_Nullable error); + +/** @typedef FIRVerifyClientCallback + @brief The callback invoked at the end of a client verification flow. + @param appCredential credential that proves the identity of the app during a phone + authentication flow. + @param error The error that occurred while verifying the app, if any. + */ +typedef void (^FIRVerifyClientCallback)(FIRAuthAppCredential *_Nullable appCredential, + NSError *_Nullable error); + +/** @typedef FIRFetchAuthDomainCallback + @brief The callback invoked at the end of the flow to fetch the Auth domain. + @param authDomain The Auth domain. + @param error The error that occurred while fetching the auth domain, if any. + */ +typedef void (^FIRFetchAuthDomainCallback)(NSString *_Nullable authDomain, + NSError *_Nullable error); +/** @var kAuthDomainSuffix + @brief The suffix of the auth domain pertiaining to a given Firebase project. + */ +static NSString *const kAuthDomainSuffix = @"firebaseapp.com"; + +/** @var kauthTypeVerifyApp + @brief The auth type to be specified in the app verification request. + */ +static NSString *const kAuthTypeVerifyApp = @"verifyApp"; + +/** @var kReCAPTCHAURLStringFormat + @brief The format of the URL used to open the reCAPTCHA page during app verification. + */ +NSString *const kReCAPTCHAURLStringFormat = @"https://%@/__/auth/handler?"; + +@implementation FIRPhoneAuthProvider { + + /** @var _auth + @brief The auth instance used for verifying the phone number. + */ + FIRAuth *_auth; + + /** @var _callbackScheme + @brief The callback URL scheme used for reCAPTCHA fallback. + */ + NSString *_callbackScheme; +} + +/** @fn initWithAuth: + @brief returns an instance of @c FIRPhoneAuthProvider associated with the provided auth + instance. + @return An Instance of @c FIRPhoneAuthProvider. + */ +- (nullable instancetype)initWithAuth:(FIRAuth *)auth { + self = [super init]; + if (self) { + _auth = auth; + _callbackScheme = [[[_auth.app.options.clientID componentsSeparatedByString:@"."] + reverseObjectEnumerator].allObjects componentsJoinedByString:@"."]; + } + return self; +} + +- (void)verifyPhoneNumber:(NSString *)phoneNumber + UIDelegate:(nullable id)UIDelegate + completion:(nullable FIRVerificationResultCallback)completion { + if (![FIRAuthWebUtils isCallbackSchemeRegisteredForCustomURLScheme:_callbackScheme]) { + [NSException raise:NSInternalInconsistencyException + format:@"Please register custom URL scheme '%@' in the app's Info.plist file.", + _callbackScheme]; + } + dispatch_async(FIRAuthGlobalWorkQueue(), ^{ + FIRVerificationResultCallback callBackOnMainThread = ^(NSString *_Nullable verificationID, + NSError *_Nullable error) { + if (completion) { + dispatch_async(dispatch_get_main_queue(), ^{ + completion(verificationID, error); + }); + } + }; + [self internalVerifyPhoneNumber:phoneNumber completion:^(NSString *_Nullable verificationID, + NSError *_Nullable error) { + if (!error) { + callBackOnMainThread(verificationID, nil); + return; + } + NSError *underlyingError = error.userInfo[NSUnderlyingErrorKey]; + BOOL isInvalidAppCredential = error.code == FIRAuthErrorCodeInternalError && + underlyingError.code == FIRAuthErrorCodeInvalidAppCredential; + if (error.code != FIRAuthErrorCodeMissingAppToken && !isInvalidAppCredential) { + callBackOnMainThread(nil, error); + return; + } + NSString *eventID = [FIRAuthWebUtils randomStringWithLength:10]; + [self reCAPTCHAURLWithEventID:eventID completion:^(NSURL *_Nullable reCAPTCHAURL, + NSError *_Nullable error) { + if (error) { + callBackOnMainThread(nil, error); + return; + } + FIRAuthURLCallbackMatcher callbackMatcher = ^BOOL(NSURL *_Nullable callbackURL) { + return [FIRAuthWebUtils isExpectedCallbackURL:callbackURL + eventID:eventID + authType:kAuthTypeVerifyApp + callbackScheme:self->_callbackScheme]; + }; + [self->_auth.authURLPresenter presentURL:reCAPTCHAURL + UIDelegate:UIDelegate + callbackMatcher:callbackMatcher + completion:^(NSURL *_Nullable callbackURL, + NSError *_Nullable error) { + if (error) { + callBackOnMainThread(nil, error); + return; + } + NSError *reCAPTCHAError; + NSString *reCAPTCHAToken = [self reCAPTCHATokenForURL:callbackURL error:&reCAPTCHAError]; + if (!reCAPTCHAToken) { + callBackOnMainThread(nil, reCAPTCHAError); + return; + } + FIRSendVerificationCodeRequest *request = + [[FIRSendVerificationCodeRequest alloc] initWithPhoneNumber:phoneNumber + appCredential:nil + reCAPTCHAToken:reCAPTCHAToken + requestConfiguration: + self->_auth.requestConfiguration]; + [FIRAuthBackend sendVerificationCode:request + callback:^(FIRSendVerificationCodeResponse + *_Nullable response, NSError *_Nullable error) { + if (error) { + callBackOnMainThread(nil, error); + return; + } + callBackOnMainThread(response.verificationID, nil); + }]; + }]; + }]; + }]; + }); +} + +- (FIRPhoneAuthCredential *)credentialWithVerificationID:(NSString *)verificationID + verificationCode:(NSString *)verificationCode { + return [[FIRPhoneAuthCredential alloc] initWithProviderID:FIRPhoneAuthProviderID + verificationID:verificationID + verificationCode:verificationCode]; +} + ++ (instancetype)provider { + return [[self alloc]initWithAuth:[FIRAuth auth]]; +} + ++ (instancetype)providerWithAuth:(FIRAuth *)auth { + return [[self alloc]initWithAuth:auth]; +} + +#pragma mark - Internal Methods + +/** @fn reCAPTCHATokenForURL:error: + @brief Parses the reCAPTCHA URL and returns the reCAPTCHA token. + @param URL The url to be parsed for a reCAPTCHA token. + @param error The error that occurred if any. + @return The reCAPTCHA token if successful. + */ +- (NSString *)reCAPTCHATokenForURL:(NSURL *)URL error:(NSError **)error { + NSURLComponents *actualURLComponents = [NSURLComponents componentsWithURL:URL resolvingAgainstBaseURL:NO]; + NSArray *queryItems = [actualURLComponents queryItems]; + NSString *deepLinkURL = [FIRAuthWebUtils queryItemValue:@"deep_link_id" from:queryItems]; + NSData *errorData; + if (deepLinkURL) { + actualURLComponents = [NSURLComponents componentsWithString:deepLinkURL]; + queryItems = [actualURLComponents queryItems]; + NSString *recaptchaToken = [FIRAuthWebUtils queryItemValue:@"recaptchaToken" from:queryItems]; + if (recaptchaToken) { + return recaptchaToken; + } + NSString *firebaseError = [FIRAuthWebUtils queryItemValue:@"firebaseError" from:queryItems]; + errorData = [firebaseError dataUsingEncoding:NSUTF8StringEncoding]; + } else { + errorData = nil; + } + NSError *jsonError; + NSDictionary *errorDict = [NSJSONSerialization JSONObjectWithData:errorData + options:0 + error:&jsonError]; + if (jsonError) { + *error = [FIRAuthErrorUtils JSONSerializationErrorWithUnderlyingError:jsonError]; + return nil; + } + *error = [FIRAuthErrorUtils URLResponseErrorWithCode:errorDict[@"code"] + message:errorDict[@"message"]]; + if (!*error) { + NSString *reason; + if(errorDict[@"code"] && errorDict[@"message"]) { + reason = [NSString stringWithFormat:@"[%@] - %@",errorDict[@"code"], errorDict[@"message"]]; + } else { + reason = [NSString stringWithFormat:@"An unknown error occurred with the following " + "response: %@", deepLinkURL]; + } + *error = [FIRAuthErrorUtils appVerificationUserInteractionFailureWithReason:reason]; + } + return nil; +} + +/** @fn internalVerifyPhoneNumber:completion: + @brief Starts the phone number authentication flow by sending a verifcation code to the + specified phone number. + @param phoneNumber The phone number to be verified. + @param completion The callback to be invoked when the verification flow is finished. + */ + +- (void)internalVerifyPhoneNumber:(NSString *)phoneNumber + completion:(nullable FIRVerificationResultCallback)completion { + if (!phoneNumber.length) { + completion(nil, [FIRAuthErrorUtils missingPhoneNumberErrorWithMessage:nil]); + return; + } + [_auth.notificationManager checkNotificationForwardingWithCallback: + ^(BOOL isNotificationBeingForwarded) { + if (!isNotificationBeingForwarded) { + completion(nil, [FIRAuthErrorUtils notificationNotForwardedError]); + return; + } + FIRVerificationResultCallback callback = ^(NSString *_Nullable verificationID, + NSError *_Nullable error) { + if (completion) { + completion(verificationID, error); + } + }; + [self verifyClientAndSendVerificationCodeToPhoneNumber:phoneNumber + retryOnInvalidAppCredential:YES + callback:callback]; + }]; +} + +/** @fn verifyClientAndSendVerificationCodeToPhoneNumber:retryOnInvalidAppCredential:callback: + @brief Starts the flow to verify the client via silent push notification. + @param retryOnInvalidAppCredential Whether of not the flow should be retried if an + FIRAuthErrorCodeInvalidAppCredential error is returned from the backend. + @param phoneNumber The phone number to be verified. + @param callback The callback to be invoked on the global work queue when the flow is + finished. + */ +- (void)verifyClientAndSendVerificationCodeToPhoneNumber:(NSString *)phoneNumber + retryOnInvalidAppCredential:(BOOL)retryOnInvalidAppCredential + callback:(FIRVerificationResultCallback)callback { + if (_auth.settings.isAppVerificationDisabledForTesting) { + FIRSendVerificationCodeRequest *request = + [[FIRSendVerificationCodeRequest alloc] initWithPhoneNumber:phoneNumber + appCredential:nil + reCAPTCHAToken:nil + requestConfiguration: + _auth.requestConfiguration]; + [FIRAuthBackend sendVerificationCode:request + callback:^(FIRSendVerificationCodeResponse *_Nullable response, + NSError *_Nullable error) { + callback(response.verificationID, error); + }]; + return; + } + [self verifyClientWithCompletion:^(FIRAuthAppCredential *_Nullable appCredential, + NSError *_Nullable error) { + if (error) { + callback(nil, error); + return; + } + FIRSendVerificationCodeRequest *request = + [[FIRSendVerificationCodeRequest alloc] initWithPhoneNumber:phoneNumber + appCredential:appCredential + reCAPTCHAToken:nil + requestConfiguration: + self->_auth.requestConfiguration]; + [FIRAuthBackend sendVerificationCode:request + callback:^(FIRSendVerificationCodeResponse *_Nullable response, + NSError *_Nullable error) { + if (error) { + if (error.code == FIRAuthErrorCodeInvalidAppCredential) { + if (retryOnInvalidAppCredential) { + [self->_auth.appCredentialManager clearCredential]; + [self verifyClientAndSendVerificationCodeToPhoneNumber:phoneNumber + retryOnInvalidAppCredential:NO + callback:callback]; + return; + } + callback(nil, [FIRAuthErrorUtils unexpectedResponseWithDeserializedResponse:nil + underlyingError:error]); + return; + } + callback(nil, error); + return; + } + callback(response.verificationID, nil); + }]; + }]; +} + +/** @fn verifyClientWithCompletion:completion: + @brief Continues the flow to verify the client via silent push notification. + @param completion The callback to be invoked when the client verification flow is finished. + */ +- (void)verifyClientWithCompletion:(FIRVerifyClientCallback)completion { + if (_auth.appCredentialManager.credential) { + completion(_auth.appCredentialManager.credential, nil); + return; + } + [_auth.tokenManager getTokenWithCallback:^(FIRAuthAPNSToken *_Nullable token, + NSError *_Nullable error) { + if (!token) { + completion(nil, [FIRAuthErrorUtils missingAppTokenErrorWithUnderlyingError:error]); + return; + } + FIRVerifyClientRequest *request = + [[FIRVerifyClientRequest alloc] initWithAppToken:token.string + isSandbox:token.type == FIRAuthAPNSTokenTypeSandbox + requestConfiguration:self->_auth.requestConfiguration]; + [FIRAuthBackend verifyClient:request callback:^(FIRVerifyClientResponse *_Nullable response, + NSError *_Nullable error) { + if (error) { + completion(nil, error); + return; + } + NSTimeInterval timeout = [response.suggestedTimeOutDate timeIntervalSinceNow]; + [self->_auth.appCredentialManager + didStartVerificationWithReceipt:response.receipt + timeout:timeout + callback:^(FIRAuthAppCredential *credential) { + if (!credential.secret) { + FIRLogWarning(kFIRLoggerAuth, @"I-AUT000014", + @"Failed to receive remote notification to verify app identity within " + @"%.0f second(s)", timeout); + } + completion(credential, nil); + }]; + }]; + }]; +} + +/** @fn reCAPTCHAURLWithEventID:completion: + @brief Constructs a URL used for opening a reCAPTCHA app verification flow using a given event + ID. + @param eventID The event ID used for this purpose. + @param completion The callback invoked after the URL has been constructed or an error + has been encountered. + */ +- (void)reCAPTCHAURLWithEventID:(NSString *)eventID completion:(FIRReCAPTCHAURLCallBack)completion { + [FIRAuthWebUtils fetchAuthDomainWithRequestConfiguration:_auth.requestConfiguration + completion:^(NSString *_Nullable authDomain, + NSError *_Nullable error) { + if (error) { + if (completion) { + completion(nil, error); + return; + } + } + NSString *bundleID = [NSBundle mainBundle].bundleIdentifier; + NSString *clientID = self->_auth.app.options.clientID; + NSString *apiKey = self->_auth.requestConfiguration.APIKey; + NSMutableArray *queryItems = [@[ + [NSURLQueryItem queryItemWithName:@"apiKey" value:apiKey], + [NSURLQueryItem queryItemWithName:@"authType" value:kAuthTypeVerifyApp], + [NSURLQueryItem queryItemWithName:@"ibi" value:bundleID ?: @""], + [NSURLQueryItem queryItemWithName:@"clientId" value:clientID], + [NSURLQueryItem queryItemWithName:@"v" value:[FIRAuthBackend authUserAgent]], + [NSURLQueryItem queryItemWithName:@"eventId" value:eventID] + ] mutableCopy + ]; + + if (self->_auth.requestConfiguration.languageCode) { + [queryItems addObject:[NSURLQueryItem queryItemWithName:@"hl"value: + self->_auth.requestConfiguration.languageCode]]; + } + NSURLComponents *components = [[NSURLComponents alloc] initWithString: + [NSString stringWithFormat:kReCAPTCHAURLStringFormat, authDomain]]; + [components setQueryItems:queryItems]; + completion([components URL], nil); + }]; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/AuthProviders/Twitter/FIRTwitterAuthCredential.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/AuthProviders/Twitter/FIRTwitterAuthCredential.h new file mode 100644 index 0000000..423d595 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/AuthProviders/Twitter/FIRTwitterAuthCredential.h @@ -0,0 +1,48 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +#import "FIRAuthCredential_Internal.h" + +NS_ASSUME_NONNULL_BEGIN + +/** @class FIRTwitterAuthCredential + @brief Internal implementation of FIRAuthCredential for Twitter credentials. + */ +@interface FIRTwitterAuthCredential : FIRAuthCredential + +/** @property token + @brief The Twitter OAuth token. + */ +@property(nonatomic, readonly) NSString *token; + +/** @property secret + @brief The Twitter OAuth secret. + */ +@property(nonatomic, readonly) NSString *secret; + +/** @fn initWithToken:secret: + @brief Designated initializer. + @param token The Twitter OAuth token. + @param secret The Twitter OAuth secret. + */ +- (nullable instancetype)initWithToken:(NSString *)token secret:(NSString *)secret + NS_DESIGNATED_INITIALIZER; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/AuthProviders/Twitter/FIRTwitterAuthCredential.m b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/AuthProviders/Twitter/FIRTwitterAuthCredential.m new file mode 100644 index 0000000..cb46615 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/AuthProviders/Twitter/FIRTwitterAuthCredential.m @@ -0,0 +1,73 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRTwitterAuthCredential.h" + +#import "FIRTwitterAuthProvider.h" +#import "FIRAuthExceptionUtils.h" +#import "FIRVerifyAssertionRequest.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface FIRTwitterAuthCredential () + +- (nullable instancetype)initWithProvider:(NSString *)provider NS_UNAVAILABLE; + +@end + +@implementation FIRTwitterAuthCredential + +- (nullable instancetype)initWithProvider:(NSString *)provider { + [FIRAuthExceptionUtils raiseMethodNotImplementedExceptionWithReason: + @"Please call the designated initializer."]; + return nil; +} + +- (nullable instancetype)initWithToken:(NSString *)token secret:(NSString *)secret { + self = [super initWithProvider:FIRTwitterAuthProviderID]; + if (self) { + _token = [token copy]; + _secret = [secret copy]; + } + return self; +} + +- (void)prepareVerifyAssertionRequest:(FIRVerifyAssertionRequest *)request { + request.providerAccessToken = _token; + request.providerOAuthTokenSecret = _secret; +} + +#pragma mark - NSSecureCoding + ++ (BOOL)supportsSecureCoding { + return YES; +} + +- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder { + NSString *token = [aDecoder decodeObjectOfClass:[NSString class] forKey:@"token"]; + NSString *secret = [aDecoder decodeObjectOfClass:[NSString class] forKey:@"secret"]; + self = [self initWithToken:token secret:secret]; + return self; +} + +- (void)encodeWithCoder:(NSCoder *)aCoder { + [aCoder encodeObject:self.token forKey:@"token"]; + [aCoder encodeObject:self.secret forKey:@"secret"]; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/AuthProviders/Twitter/FIRTwitterAuthProvider.m b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/AuthProviders/Twitter/FIRTwitterAuthProvider.m new file mode 100644 index 0000000..33771b7 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/AuthProviders/Twitter/FIRTwitterAuthProvider.m @@ -0,0 +1,40 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRTwitterAuthProvider.h" + +#import "FIRTwitterAuthCredential.h" +#import "FIRAuthExceptionUtils.h" + +// FIRTwitterAuthProviderID is defined in FIRAuthProvider.m. + +NS_ASSUME_NONNULL_BEGIN + +@implementation FIRTwitterAuthProvider + +- (instancetype)init { + [FIRAuthExceptionUtils raiseMethodNotImplementedExceptionWithReason: + @"This class is not meant to be initialized."]; + return nil; +} + ++ (FIRAuthCredential *)credentialWithToken:(NSString *)token secret:(NSString *)secret { + return [[FIRTwitterAuthCredential alloc] initWithToken:token secret:secret]; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRActionCodeSettings.m b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRActionCodeSettings.m new file mode 100644 index 0000000..02807ff --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRActionCodeSettings.m @@ -0,0 +1,45 @@ +/* + * Copyright 2017 Google + * + * 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/LICENSE2.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. + */ + +#import "FIRActionCodeSettings.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation FIRActionCodeSettings + +- (instancetype)init { + self = [super init]; + if (self) { + _iOSBundleID = [NSBundle mainBundle].bundleIdentifier; + } + return self; +} + +- (void)setIOSBundleID:(NSString *)iOSBundleID { + _iOSBundleID = [iOSBundleID copy]; + } + +- (void)setAndroidPackageName:(NSString *)androidPackageName + installIfNotAvailable:(BOOL)installIfNotAvailable + minimumVersion:(nullable NSString *)minimumVersion { + _androidPackageName = [androidPackageName copy]; + _androidInstallIfNotAvailable = installIfNotAvailable; + _androidMinimumVersion = [minimumVersion copy]; + } + + @end + + NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAdditionalUserInfo.m b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAdditionalUserInfo.m new file mode 100644 index 0000000..c6ba37c --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAdditionalUserInfo.m @@ -0,0 +1,98 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRAdditionalUserInfo_Internal.h" + +#import "FIRVerifyAssertionResponse.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation FIRAdditionalUserInfo + +/** @var kProviderIDCodingKey + @brief The key used to encode the providerID property for NSSecureCoding. + */ +static NSString *const kProviderIDCodingKey = @"providerID"; + +/** @var kProfileCodingKey + @brief The key used to encode the profile property for NSSecureCoding. + */ +static NSString *const kProfileCodingKey = @"profile"; + +/** @var kUsernameCodingKey + @brief The key used to encode the username property for NSSecureCoding. + */ +static NSString *const kUsernameCodingKey = @"username"; + +/** @var kNewUserKey + @brief The key used to encode the newUser property for NSSecureCoding. + */ +static NSString *const kNewUserKey = @"newUser"; + ++ (nullable instancetype)userInfoWithVerifyAssertionResponse: + (FIRVerifyAssertionResponse *)verifyAssertionResponse { + return [[self alloc] initWithProviderID:verifyAssertionResponse.providerID + profile:verifyAssertionResponse.profile + username:verifyAssertionResponse.username + isNewUser:verifyAssertionResponse.isNewUser]; +} + +- (nullable instancetype)initWithProviderID:(nullable NSString *)providerID + profile:(nullable NSDictionary *)profile + username:(nullable NSString *)username + isNewUser:(BOOL)isNewUser { + self = [super init]; + if (self) { + _providerID = [providerID copy]; + if (profile) { + _profile = [[NSDictionary alloc] initWithDictionary:profile copyItems:YES]; + } + _username = [username copy]; + _newUser = isNewUser; + } + return self; +} + +#pragma mark - NSSecureCoding + ++ (BOOL)supportsSecureCoding { + return YES; +} + +- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder { + NSString *providerID = + [aDecoder decodeObjectOfClass:[NSString class] forKey:kProviderIDCodingKey]; + NSDictionary *profile = + [aDecoder decodeObjectOfClass:[NSDictionary class] forKey:kProfileCodingKey]; + NSString *username = [aDecoder decodeObjectOfClass:[NSString class] forKey:kUsernameCodingKey]; + NSNumber *isNewUser = [aDecoder decodeObjectOfClass:[NSNumber class] forKey:kNewUserKey]; + + return [self initWithProviderID:providerID + profile:profile + username:username + isNewUser:isNewUser.boolValue]; +} + +- (void)encodeWithCoder:(NSCoder *)aCoder { + [aCoder encodeObject:_providerID forKey:kProviderIDCodingKey]; + [aCoder encodeObject:_profile forKey:kProfileCodingKey]; + [aCoder encodeObject:_username forKey:kUsernameCodingKey]; + [aCoder encodeObject:[NSNumber numberWithBool:_newUser] forKey:kNewUserKey]; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAdditionalUserInfo_Internal.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAdditionalUserInfo_Internal.h new file mode 100644 index 0000000..c8e345d --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAdditionalUserInfo_Internal.h @@ -0,0 +1,46 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRAdditionalUserInfo.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface FIRAdditionalUserInfo () + +/** @fn userInfoWithVerifyAssertionResponse: + @brief A convenience factory method for constructing a @c FIRAdditionalUserInfo instance from + data returned by the verifyAssertion endpoint. + @param verifyAssertionResponse Data returned by the verifyAssertion endpoint. + @return A new instance of @c FIRAdditionalUserInfo using data from the verifyAssertion endpoint. + */ ++ (nullable instancetype)userInfoWithVerifyAssertionResponse: + (FIRVerifyAssertionResponse *)verifyAssertionResponse; + +/** @fn initWithProviderID:profile:username: + @brief Designated initializer. + @param providerID The provider identifier. + @param profile Dictionary containing the additional IdP specific information. + @param username The name of the user. + @param isNewUser Indicates whether or not the current user was signed in for the first time. + */ +- (nullable instancetype)initWithProviderID:(nullable NSString *)providerID + profile:(nullable NSDictionary *)profile + username:(nullable NSString *)username + isNewUser:(BOOL)isNewUser NS_DESIGNATED_INITIALIZER; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuth.m b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuth.m new file mode 100644 index 0000000..efb3a48 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuth.m @@ -0,0 +1,2016 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +#import "FIRAuth_Internal.h" + +#if __has_include() +#import +#endif + +#import +#import +#import +#import +#import +#import +#import +#import + +#import "AuthProviders/EmailPassword/FIREmailPasswordAuthCredential.h" +#import "FIRAdditionalUserInfo_Internal.h" +#import "FIRAuthCredential_Internal.h" +#import "FIRAuthDataResult_Internal.h" +#import "FIRAuthDispatcher.h" +#import "FIRAuthErrorUtils.h" +#import "FIRAuthExceptionUtils.h" +#import "FIRAuthGlobalWorkQueue.h" +#import "FIRAuthKeychain.h" +#import "FIRAuthOperationType.h" +#import "FIRAuthSettings.h" +#import "FIRUser_Internal.h" +#import "FirebaseAuth.h" +#import "FIRAuthBackend.h" +#import "FIRAuthRequestConfiguration.h" +#import "FIRCreateAuthURIRequest.h" +#import "FIRCreateAuthURIResponse.h" +#import "FIREmailLinkSignInRequest.h" +#import "FIREmailLinkSignInResponse.h" +#import "FIRGameCenterAuthCredential.h" +#import "FIRGetOOBConfirmationCodeRequest.h" +#import "FIRGetOOBConfirmationCodeResponse.h" +#import "FIROAuthCredential_Internal.h" +#import "FIRResetPasswordRequest.h" +#import "FIRResetPasswordResponse.h" +#import "FIRSendVerificationCodeRequest.h" +#import "FIRSendVerificationCodeResponse.h" +#import "FIRSetAccountInfoRequest.h" +#import "FIRSetAccountInfoResponse.h" +#import "FIRSignInWithGameCenterRequest.h" +#import "FIRSignInWithGameCenterResponse.h" +#import "FIRSignUpNewUserRequest.h" +#import "FIRSignUpNewUserResponse.h" +#import "FIRVerifyAssertionRequest.h" +#import "FIRVerifyAssertionResponse.h" +#import "FIRVerifyCustomTokenRequest.h" +#import "FIRVerifyCustomTokenResponse.h" +#import "FIRVerifyPasswordRequest.h" +#import "FIRVerifyPasswordResponse.h" +#import "FIRVerifyPhoneNumberRequest.h" +#import "FIRVerifyPhoneNumberResponse.h" + +#if TARGET_OS_IOS +#import "FIRAuthAPNSToken.h" +#import "FIRAuthAPNSTokenManager.h" +#import "FIRAuthAppCredentialManager.h" +#import "FIRAuthAppDelegateProxy.h" +#import "AuthProviders/Phone/FIRPhoneAuthCredential_Internal.h" +#import "FIRAuthNotificationManager.h" +#import "FIRAuthURLPresenter.h" +#endif + +NS_ASSUME_NONNULL_BEGIN + +#pragma mark - Constants + +#if defined(__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0 +const NSNotificationName FIRAuthStateDidChangeNotification = @"FIRAuthStateDidChangeNotification"; +#else +NSString *const FIRAuthStateDidChangeNotification = @"FIRAuthStateDidChangeNotification"; +#endif // defined(__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0 + +/** @var kMaxWaitTimeForBackoff + @brief The maximum wait time before attempting to retry auto refreshing tokens after a failed + attempt. + @remarks This is the upper limit (in seconds) of the exponential backoff used for retrying + token refresh. + */ +static NSTimeInterval kMaxWaitTimeForBackoff = 16 * 60; + +/** @var kTokenRefreshHeadStart + @brief The amount of time before the token expires that proactive refresh should be attempted. + */ +NSTimeInterval kTokenRefreshHeadStart = 5 * 60; + +/** @var kUserKey + @brief Key of user stored in the keychain. Prefixed with a Firebase app name. + */ +static NSString *const kUserKey = @"%@_firebase_user"; + +/** @var kMissingEmailInvalidParameterExceptionReason + @brief The reason for @c invalidParameterException when the email used to initiate password + reset is nil. + */ +static NSString *const kMissingEmailInvalidParameterExceptionReason = + @"The email used to initiate password reset cannot be nil."; + +/** @var kHandleCodeInAppFalseExceptionReason + @brief The reason for @c invalidParameterException when the handleCodeInApp parameter is false + on the ActionCodeSettings object used to send the link for Email-link Authentication. + */ +static NSString *const kHandleCodeInAppFalseExceptionReason = + @"You must set handleCodeInApp in your ActionCodeSettings to true for Email-link " + "Authentication."; + +static NSString *const kInvalidEmailSignInLinkExceptionMessage = + @"The link provided is not valid for email/link sign-in. Please check the link by calling " + "isSignInWithEmailLink:link: on Auth before attempting to use it for email/link sign-in."; + +/** @var kPasswordResetRequestType + @brief The action code type value for resetting password in the check action code response. + */ +static NSString *const kPasswordResetRequestType = @"PASSWORD_RESET"; + +/** @var kVerifyEmailRequestType + @brief The action code type value for verifying email in the check action code response. + */ +static NSString *const kVerifyEmailRequestType = @"VERIFY_EMAIL"; + +/** @var kRecoverEmailRequestType + @brief The action code type value for recovering email in the check action code response. + */ +static NSString *const kRecoverEmailRequestType = @"RECOVER_EMAIL"; + +/** @var kEmailLinkSignInRequestType + @brief The action code type value for an email sign-in link in the check action code response. +*/ +static NSString *const kEmailLinkSignInRequestType = @"EMAIL_SIGNIN"; + +/** @var kMissingPasswordReason + @brief The reason why the @c FIRAuthErrorCodeWeakPassword error is thrown. + @remarks This error message will be localized in the future. + */ +static NSString *const kMissingPasswordReason = @"Missing Password"; + +/** @var gKeychainServiceNameForAppName + @brief A map from Firebase app name to keychain service names. + @remarks This map is needed for looking up the keychain service name after the FIRApp instance + is deleted, to remove the associated keychain item. Accessing should occur within a + @syncronized([FIRAuth class]) context. + */ +static NSMutableDictionary *gKeychainServiceNameForAppName; + +#pragma mark - FIRActionCodeInfo + +@implementation FIRActionCodeInfo { + /** @var _email + @brief The email address to which the code was sent. The new email address in the case of + FIRActionCodeOperationRecoverEmail. + */ + NSString *_email; + + /** @var _fromEmail + @brief The current email address in the case of FIRActionCodeOperationRecoverEmail. + */ + NSString *_fromEmail; +} + +- (NSString *)dataForKey:(FIRActionDataKey)key{ + switch (key) { + case FIRActionCodeEmailKey: + return _email; + case FIRActionCodeFromEmailKey: + return _fromEmail; + } +} + +- (instancetype)initWithOperation:(FIRActionCodeOperation)operation + email:(NSString *)email + newEmail:(nullable NSString *)newEmail { + self = [super init]; + if (self) { + _operation = operation; + if (newEmail) { + _email = [newEmail copy]; + _fromEmail = [email copy]; + } else { + _email = [email copy]; + } + } + return self; +} + +/** @fn actionCodeOperationForRequestType: + @brief Returns the corresponding operation type per provided request type string. + @param requestType Request type returned in in the server response. + @return The corresponding FIRActionCodeOperation for the supplied request type. + */ ++ (FIRActionCodeOperation)actionCodeOperationForRequestType:(NSString *)requestType { + if ([requestType isEqualToString:kPasswordResetRequestType]) { + return FIRActionCodeOperationPasswordReset; + } + if ([requestType isEqualToString:kVerifyEmailRequestType]) { + return FIRActionCodeOperationVerifyEmail; + } + if ([requestType isEqualToString:kRecoverEmailRequestType]) { + return FIRActionCodeOperationRecoverEmail; + } + if ([requestType isEqualToString:kEmailLinkSignInRequestType]) { + return FIRActionCodeOperationEmailLink; + } + return FIRActionCodeOperationUnknown; +} + +@end + +#pragma mark - FIRAuth + +#if TARGET_OS_IOS +@interface FIRAuth () +#else +@interface FIRAuth () +#endif + +/** @property firebaseAppId + @brief The Firebase app ID. + */ +@property(nonatomic, copy, readonly) NSString *firebaseAppId; + +/** @property additionalFrameworkMarker + @brief Additional framework marker that will be added as part of the header of every request. + */ +@property(nonatomic, copy, nullable) NSString *additionalFrameworkMarker; + +/** @fn initWithApp: + @brief Creates a @c FIRAuth instance associated with the provided @c FIRApp instance. + @param app The application to associate the auth instance with. + */ +- (instancetype)initWithApp:(FIRApp *)app; + +@end + +@implementation FIRAuth { + /** @var _currentUser + @brief The current user. + */ + FIRUser *_currentUser; + + /** @var _firebaseAppName + @brief The Firebase app name. + */ + NSString *_firebaseAppName; + + /** @var _listenerHandles + @brief Handles returned from @c NSNotificationCenter for blocks which are "auth state did + change" notification listeners. + @remarks Mutations should occur within a @syncronized(self) context. + */ + NSMutableArray *_listenerHandles; + + /** @var _keychain + @brief The keychain service. + */ + FIRAuthKeychain *_keychain; + + /** @var _lastNotifiedUserToken + @brief The user access (ID) token used last time for posting auth state changed notification. + */ + NSString *_lastNotifiedUserToken; + + /** @var _autoRefreshTokens + @brief This flag denotes whether or not tokens should be automatically refreshed. + @remarks Will only be set to @YES if the another Firebase service is included (additionally to + Firebase Auth). + */ + BOOL _autoRefreshTokens; + + /** @var _autoRefreshScheduled + @brief Whether or not token auto-refresh is currently scheduled. + */ + BOOL _autoRefreshScheduled; + + /** @var _isAppInBackground + @brief A flag that is set to YES if the app is put in the background and no when the app is + returned to the foreground. + */ + BOOL _isAppInBackground; + + /** @var _applicationDidBecomeActiveObserver + @brief An opaque object to act as the observer for UIApplicationDidBecomeActiveNotification. + */ + id _applicationDidBecomeActiveObserver; + + /** @var _applicationDidBecomeActiveObserver + @brief An opaque object to act as the observer for + UIApplicationDidEnterBackgroundNotification. + */ + id _applicationDidEnterBackgroundObserver; +} + ++ (void)load { + [FIRApp registerInternalLibrary:(Class)self + withName:@"fire-auth" + withVersion:[NSString stringWithUTF8String:FirebaseAuthVersionStr]]; +} + ++ (void)initialize { + gKeychainServiceNameForAppName = [[NSMutableDictionary alloc] init]; +} + ++ (FIRAuth *)auth { + FIRApp *defaultApp = [FIRApp defaultApp]; + if (!defaultApp) { + [NSException raise:NSInternalInconsistencyException + format:@"The default FIRApp instance must be configured before the default FIRAuth" + @"instance can be initialized. One way to ensure that is to call " + @"`[FIRApp configure];` (`FirebaseApp.configure()` in Swift) in the App " + @"Delegate's `application:didFinishLaunchingWithOptions:` " + @"(`application(_:didFinishLaunchingWithOptions:)` in Swift)."]; + } + return [self authWithApp:defaultApp]; +} + ++ (FIRAuth *)authWithApp:(FIRApp *)app { + // Get the instance of Auth from the container, which will create or return the cached instance + // associated with this app. + id auth = FIR_COMPONENT(FIRAuthInterop, app.container); + return (FIRAuth *)auth; +} + +- (instancetype)initWithApp:(FIRApp *)app { + [FIRAuth setKeychainServiceNameForApp:app]; + self = [self initWithAPIKey:app.options.APIKey appName:app.name]; + if (self) { + _app = app; + #if TARGET_OS_IOS + _authURLPresenter = [[FIRAuthURLPresenter alloc] init]; + #endif + } + return self; +} + +- (nullable instancetype)initWithAPIKey:(NSString *)APIKey appName:(NSString *)appName { + self = [super init]; + if (self) { + _listenerHandles = [NSMutableArray array]; + _requestConfiguration = [[FIRAuthRequestConfiguration alloc] initWithAPIKey:APIKey]; + _settings = [[FIRAuthSettings alloc] init]; + _firebaseAppName = [appName copy]; + #if TARGET_OS_IOS + + static Class applicationClass = nil; + // iOS App extensions should not call [UIApplication sharedApplication], even if UIApplication + // responds to it. + if (![GULAppEnvironmentUtil isAppExtension]) { + Class cls = NSClassFromString(@"UIApplication"); + if (cls && [cls respondsToSelector:NSSelectorFromString(@"sharedApplication")]) { + applicationClass = cls; + } + } + UIApplication *application = [applicationClass sharedApplication]; + + // Initialize the shared FIRAuthAppDelegateProxy instance in the main thread if not already. + [FIRAuthAppDelegateProxy sharedInstance]; + #endif + + // Continue with the rest of initialization in the work thread. + __weak FIRAuth *weakSelf = self; + dispatch_async(FIRAuthGlobalWorkQueue(), ^{ + // Load current user from Keychain. + FIRAuth *strongSelf = weakSelf; + if (!strongSelf) { + return; + } + NSString *keychainServiceName = + [FIRAuth keychainServiceNameForAppName:strongSelf->_firebaseAppName]; + if (keychainServiceName) { + strongSelf->_keychain = [[FIRAuthKeychain alloc] initWithService:keychainServiceName]; + } + FIRUser *user; + NSError *error; + if ([strongSelf getUser:&user error:&error]) { + [strongSelf updateCurrentUser:user byForce:NO savingToDisk:NO error:&error]; + self->_lastNotifiedUserToken = user.rawAccessToken; + } else { + FIRLogError(kFIRLoggerAuth, @"I-AUT000001", + @"Error loading saved user when starting up: %@", error); + } + + #if TARGET_OS_IOS + // Initialize for phone number auth. + strongSelf->_tokenManager = + [[FIRAuthAPNSTokenManager alloc] initWithApplication:application]; + + strongSelf->_appCredentialManager = + [[FIRAuthAppCredentialManager alloc] initWithKeychain:strongSelf->_keychain]; + + strongSelf->_notificationManager = [[FIRAuthNotificationManager alloc] + initWithApplication:application + appCredentialManager:strongSelf->_appCredentialManager]; + + [[FIRAuthAppDelegateProxy sharedInstance] addHandler:strongSelf]; + #endif + }); + } + return self; +} + +- (void)dealloc { + @synchronized (self) { + NSNotificationCenter *defaultCenter = [NSNotificationCenter defaultCenter]; + while (_listenerHandles.count != 0) { + FIRAuthStateDidChangeListenerHandle handleToRemove = _listenerHandles.lastObject; + [defaultCenter removeObserver:handleToRemove]; + [_listenerHandles removeLastObject]; + } + + #if TARGET_OS_IOS + [defaultCenter removeObserver:_applicationDidBecomeActiveObserver + name:UIApplicationDidBecomeActiveNotification + object:nil]; + [defaultCenter removeObserver:_applicationDidEnterBackgroundObserver + name:UIApplicationDidEnterBackgroundNotification + object:nil]; + #endif + } +} + +#pragma mark - Public API + +- (nullable FIRUser *)currentUser { + __block FIRUser *result; + dispatch_sync(FIRAuthGlobalWorkQueue(), ^{ + result = self->_currentUser; + }); + return result; +} + +- (void)fetchProvidersForEmail:(NSString *)email + completion:(nullable FIRProviderQueryCallback)completion { + dispatch_async(FIRAuthGlobalWorkQueue(), ^{ + FIRCreateAuthURIRequest *request = + [[FIRCreateAuthURIRequest alloc] initWithIdentifier:email + continueURI:@"http://www.google.com/" + requestConfiguration:self->_requestConfiguration]; + [FIRAuthBackend createAuthURI:request callback:^(FIRCreateAuthURIResponse *_Nullable response, + NSError *_Nullable error) { + if (completion) { + dispatch_async(dispatch_get_main_queue(), ^{ + completion(response.allProviders, error); + }); + } + }]; + }); +} + + +- (void)signInWithProvider:(id)provider + UIDelegate:(nullable id)UIDelegate + completion:(nullable FIRAuthDataResultCallback)completion { +#if TARGET_OS_IOS + dispatch_async(FIRAuthGlobalWorkQueue(), ^{ + FIRAuthDataResultCallback decoratedCallback = + [self signInFlowAuthDataResultCallbackByDecoratingCallback:completion]; + [provider getCredentialWithUIDelegate:UIDelegate + completion:^(FIRAuthCredential *_Nullable credential, + NSError *_Nullable error) { + if (error) { + decoratedCallback(nil, error); + return; + } + [self internalSignInAndRetrieveDataWithCredential:credential + isReauthentication:NO + callback:decoratedCallback]; + }]; + }); +#endif // TARGET_OS_IOS +} + +- (void)fetchSignInMethodsForEmail:(nonnull NSString *)email + completion:(nullable FIRSignInMethodQueryCallback)completion { + dispatch_async(FIRAuthGlobalWorkQueue(), ^{ + FIRCreateAuthURIRequest *request = + [[FIRCreateAuthURIRequest alloc] initWithIdentifier:email + continueURI:@"http://www.google.com/" + requestConfiguration:self->_requestConfiguration]; + [FIRAuthBackend createAuthURI:request callback:^(FIRCreateAuthURIResponse *_Nullable response, + NSError *_Nullable error) { + if (completion) { + dispatch_async(dispatch_get_main_queue(), ^{ + completion(response.signinMethods, error); + }); + } + }]; + }); +} + +- (void)signInWithEmail:(NSString *)email + password:(NSString *)password + completion:(nullable FIRAuthDataResultCallback)completion { + dispatch_async(FIRAuthGlobalWorkQueue(), ^{ + FIRAuthDataResultCallback decoratedCallback = + [self signInFlowAuthDataResultCallbackByDecoratingCallback:completion]; + [self internalSignInAndRetrieveDataWithEmail:email + password:password + completion:^(FIRAuthDataResult *_Nullable authResult, + NSError *_Nullable error) { + decoratedCallback(authResult, error); + }]; + }); +} + +- (void)signInWithEmail:(NSString *)email + link:(NSString *)link + completion:(nullable FIRAuthDataResultCallback)completion { + dispatch_async(FIRAuthGlobalWorkQueue(), ^{ + FIRAuthDataResultCallback decoratedCallback = + [self signInFlowAuthDataResultCallbackByDecoratingCallback:completion]; + FIREmailPasswordAuthCredential *credential = + [[FIREmailPasswordAuthCredential alloc] initWithEmail:email link:link]; + [self internalSignInAndRetrieveDataWithCredential:credential + isReauthentication:NO + callback:^(FIRAuthDataResult *_Nullable authResult, + NSError *_Nullable error) { + decoratedCallback(authResult, error); + }]; + }); +} + +/** @fn signInWithEmail:password:callback: + @brief Signs in using an email address and password. + @param email The user's email address. + @param password The user's password. + @param callback A block which is invoked when the sign in finishes (or is cancelled.) Invoked + asynchronously on the global auth work queue in the future. + @remarks This is the internal counterpart of this method, which uses a callback that does not + update the current user. + */ +- (void)signInWithEmail:(NSString *)email + password:(NSString *)password + callback:(FIRAuthResultCallback)callback { + + FIRVerifyPasswordRequest *request = + [[FIRVerifyPasswordRequest alloc] initWithEmail:email + password:password + requestConfiguration:_requestConfiguration]; + + if (![request.password length]) { + callback(nil, [FIRAuthErrorUtils wrongPasswordErrorWithMessage:nil]); + return; + } + [FIRAuthBackend verifyPassword:request + callback:^(FIRVerifyPasswordResponse *_Nullable response, + NSError *_Nullable error) { + if (error) { + callback(nil, error); + return; + } + [self completeSignInWithAccessToken:response.IDToken + accessTokenExpirationDate:response.approximateExpirationDate + refreshToken:response.refreshToken + anonymous:NO + callback:callback]; + }]; +} + +- (void)signInAndRetrieveDataWithEmail:(NSString *)email + password:(NSString *)password + completion:(nullable FIRAuthDataResultCallback)completion { + dispatch_async(FIRAuthGlobalWorkQueue(), ^{ + FIRAuthDataResultCallback decoratedCallback = + [self signInFlowAuthDataResultCallbackByDecoratingCallback:completion]; + [self internalSignInAndRetrieveDataWithEmail:email + password:password + completion:decoratedCallback]; + }); +} + +/** @fn internalSignInAndRetrieveDataWithEmail:password:callback: + @brief Signs in using an email address and password. + @param email The user's email address. + @param password The user's password. + @param completion A block which is invoked when the sign in finishes (or is cancelled.) Invoked + asynchronously on the global auth work queue in the future. + @remarks This is the internal counterpart of this method, which uses a callback that does not + update the current user. + */ +- (void)internalSignInAndRetrieveDataWithEmail:(NSString *)email + password:(NSString *)password + completion:(FIRAuthDataResultCallback)completion { + FIREmailPasswordAuthCredential *credentail = + [[FIREmailPasswordAuthCredential alloc] initWithEmail:email password:password]; + [self internalSignInAndRetrieveDataWithCredential:credentail + isReauthentication:NO + callback:completion]; +} + +/** @fn signInAndRetrieveDataWithGameCenterCredential:callback: + @brief Signs in using a game center credential. + @param credential The Game Center Auth Credential used to sign in. + @param callback A block which is invoked when the sign in finished (or is cancelled). Invoked + asynchronously on the global auth work queue in the future. + */ +- (void)signInAndRetrieveDataWithGameCenterCredential:(FIRGameCenterAuthCredential *)credential + callback:(FIRAuthDataResultCallback)callback { + FIRSignInWithGameCenterRequest *request = + [[FIRSignInWithGameCenterRequest alloc] initWithPlayerID:credential.playerID + publicKeyURL:credential.publicKeyURL + signature:credential.signature + salt:credential.salt + timestamp:credential.timestamp + displayName:credential.displayName + requestConfiguration:_requestConfiguration]; + [FIRAuthBackend signInWithGameCenter:request + callback:^(FIRSignInWithGameCenterResponse *_Nullable response, + NSError *_Nullable error) { + if (error) { + if (callback) { + callback(nil, error); + } + return; + } + + [self completeSignInWithAccessToken:response.IDToken + accessTokenExpirationDate:response.approximateExpirationDate + refreshToken:response.refreshToken + anonymous:NO + callback:^(FIRUser *_Nullable user, NSError *_Nullable error) { + FIRAdditionalUserInfo *additionalUserInfo = + [[FIRAdditionalUserInfo alloc] initWithProviderID:FIRGameCenterAuthProviderID + profile:nil + username:nil + isNewUser:response.isNewUser]; + FIRAuthDataResult *result = user ? + [[FIRAuthDataResult alloc] initWithUser:user + additionalUserInfo:additionalUserInfo] : nil; + if (callback) { + callback(result, error); + } + }]; + }]; +} + +/** @fn internalSignInAndRetrieveDataWithEmail:link:completion: + @brief Signs in using an email and email sign-in link. + @param email The user's email address. + @param link The email sign-in link. + @param callback A block which is invoked when the sign in finishes (or is cancelled.) Invoked + asynchronously on the global auth work queue in the future. + */ +- (void)internalSignInAndRetrieveDataWithEmail:(nonnull NSString *)email + link:(nonnull NSString *)link + callback:(nullable FIRAuthDataResultCallback)callback { + if (![self isSignInWithEmailLink:link]) { + [FIRAuthExceptionUtils raiseInvalidParameterExceptionWithReason: + kInvalidEmailSignInLinkExceptionMessage]; + return; + } + NSDictionary *queryItems = FIRAuthParseURL(link); + if (![queryItems count]) { + NSURLComponents *urlComponents = [NSURLComponents componentsWithString:link]; + queryItems = FIRAuthParseURL(urlComponents.query); + } + NSString *actionCode = queryItems[@"oobCode"]; + + FIREmailLinkSignInRequest *request = + [[FIREmailLinkSignInRequest alloc] initWithEmail:email + oobCode:actionCode + requestConfiguration:_requestConfiguration]; + + [FIRAuthBackend emailLinkSignin:request + callback:^(FIREmailLinkSignInResponse *_Nullable response, + NSError *_Nullable error) { + if (error) { + if (callback) { + callback(nil, error); + } + return; + } + [self completeSignInWithAccessToken:response.IDToken + accessTokenExpirationDate:response.approximateExpirationDate + refreshToken:response.refreshToken + anonymous:NO + callback:^(FIRUser *_Nullable user, NSError *_Nullable error) { + if (error) { + if (callback) { + callback(nil, error); + } + return; + } + FIRAdditionalUserInfo *additionalUserInfo = + [[FIRAdditionalUserInfo alloc] initWithProviderID:FIREmailAuthProviderID + profile:nil + username:nil + isNewUser:response.isNewUser]; + FIRAuthDataResult *result = user ? + [[FIRAuthDataResult alloc] initWithUser:user + additionalUserInfo:additionalUserInfo] : nil; + if (callback) { + callback(result, error); + } + }]; + }]; +} + +- (void)signInWithCredential:(FIRAuthCredential *)credential + completion:(nullable FIRAuthResultCallback)completion { + dispatch_async(FIRAuthGlobalWorkQueue(), ^{ + FIRAuthResultCallback callback = + [self signInFlowAuthResultCallbackByDecoratingCallback:completion]; + [self internalSignInWithCredential:credential callback:callback]; + }); +} + +- (void)signInAndRetrieveDataWithCredential:(FIRAuthCredential *)credential + completion:(nullable FIRAuthDataResultCallback)completion { + dispatch_async(FIRAuthGlobalWorkQueue(), ^{ + FIRAuthDataResultCallback callback = + [self signInFlowAuthDataResultCallbackByDecoratingCallback:completion]; + [self internalSignInAndRetrieveDataWithCredential:credential + isReauthentication:NO + callback:callback]; + }); +} + +- (void)internalSignInWithCredential:(FIRAuthCredential *)credential + callback:(FIRAuthResultCallback)callback { + [self internalSignInAndRetrieveDataWithCredential:credential + isReauthentication:NO + callback:^(FIRAuthDataResult *_Nullable authResult, + NSError *_Nullable error) { + callback(authResult.user, error); + }]; +} + +- (void)internalSignInAndRetrieveDataWithCredential:(FIRAuthCredential *)credential + isReauthentication:(BOOL)isReauthentication + callback:(nullable FIRAuthDataResultCallback)callback { + if ([credential isKindOfClass:[FIREmailPasswordAuthCredential class]]) { + // Special case for email/password credentials + FIREmailPasswordAuthCredential *emailPasswordCredential = + (FIREmailPasswordAuthCredential *)credential; + + if (emailPasswordCredential.link) { + // Email link sign in + [self internalSignInAndRetrieveDataWithEmail:emailPasswordCredential.email + link:emailPasswordCredential.link + callback:callback]; + } else { + // Email password sign in + FIRAuthResultCallback completeEmailSignIn = ^(FIRUser *user, NSError *error) { + if (callback) { + if (error) { + callback(nil, error); + return; + } + FIRAdditionalUserInfo *additionalUserInfo = + [[FIRAdditionalUserInfo alloc] initWithProviderID:FIREmailAuthProviderID + profile:nil + username:nil + isNewUser:NO]; + FIRAuthDataResult *result = [[FIRAuthDataResult alloc] initWithUser:user + additionalUserInfo:additionalUserInfo]; + callback(result, error); + } + }; + + [self signInWithEmail:emailPasswordCredential.email + password:emailPasswordCredential.password + callback:completeEmailSignIn]; + } + return; + } + + if ([credential isKindOfClass:[FIRGameCenterAuthCredential class]]) { + // Special case for Game Center credentials. + [self signInAndRetrieveDataWithGameCenterCredential:(FIRGameCenterAuthCredential *)credential + callback:callback]; + return; + } + + #if TARGET_OS_IOS + if ([credential isKindOfClass:[FIRPhoneAuthCredential class]]) { + // Special case for phone auth credentials + FIRPhoneAuthCredential *phoneCredential = (FIRPhoneAuthCredential *)credential; + FIRAuthOperationType operation = + isReauthentication ? FIRAuthOperationTypeReauth : FIRAuthOperationTypeSignUpOrSignIn; + [self signInWithPhoneCredential:phoneCredential + operation:operation + callback:^(FIRVerifyPhoneNumberResponse *_Nullable response, + NSError *_Nullable error) { + if (callback) { + if (error) { + callback(nil, error); + return; + } + + [self completeSignInWithAccessToken:response.IDToken + accessTokenExpirationDate:response.approximateExpirationDate + refreshToken:response.refreshToken + anonymous:NO + callback:^(FIRUser *_Nullable user, NSError *_Nullable error) { + FIRAdditionalUserInfo *additionalUserInfo = + [[FIRAdditionalUserInfo alloc] initWithProviderID:FIRPhoneAuthProviderID + profile:nil + username:nil + isNewUser:response.isNewUser]; + FIRAuthDataResult *result = user ? + [[FIRAuthDataResult alloc] initWithUser:user + additionalUserInfo:additionalUserInfo] : nil; + callback(result, error); + }]; + } + }]; + return; + } + #endif + FIRVerifyAssertionRequest *request = + [[FIRVerifyAssertionRequest alloc] initWithProviderID:credential.provider + requestConfiguration:_requestConfiguration]; + request.autoCreate = !isReauthentication; + [credential prepareVerifyAssertionRequest:request]; + if ([credential isKindOfClass:[FIROAuthCredential class]]) { + FIROAuthCredential *OAuthCredential = (FIROAuthCredential *)credential; + request.requestURI = OAuthCredential.OAuthResponseURLString; + request.sessionID = OAuthCredential.sessionID; + request.pendingToken = OAuthCredential.pendingToken; + } + [FIRAuthBackend verifyAssertion:request + callback:^(FIRVerifyAssertionResponse *response, NSError *error) { + if (error) { + if (callback) { + callback(nil, error); + } + return; + } + + if (response.needConfirmation) { + if (callback) { + NSString *email = response.email; + callback(nil, [FIRAuthErrorUtils accountExistsWithDifferentCredentialErrorWithEmail:email]); + } + return; + } + + if (!response.providerID.length) { + if (callback) { + callback(nil, [FIRAuthErrorUtils unexpectedResponseWithDeserializedResponse:response]); + } + return; + } + [self completeSignInWithAccessToken:response.IDToken + accessTokenExpirationDate:response.approximateExpirationDate + refreshToken:response.refreshToken + anonymous:NO + callback:^(FIRUser *_Nullable user, NSError *_Nullable error) { + if (callback) { + FIRAdditionalUserInfo *additionalUserInfo = + [FIRAdditionalUserInfo userInfoWithVerifyAssertionResponse:response]; + FIRAuthDataResult *result = user ? + [[FIRAuthDataResult alloc] initWithUser:user + additionalUserInfo:additionalUserInfo] : nil; + callback(result, error); + } + }]; + }]; +} + +- (void)signInWithCredential:(FIRAuthCredential *)credential + callback:(FIRAuthResultCallback)callback { + [self signInAndRetrieveDataWithCredential:credential + completion:^(FIRAuthDataResult *_Nullable authResult, + NSError *_Nullable error) { + callback(authResult.user, error); + }]; +} + +- (void)signInAnonymouslyAndRetrieveDataWithCompletion: + (nullable FIRAuthDataResultCallback)completion { + dispatch_async(FIRAuthGlobalWorkQueue(), ^{ + FIRAuthDataResultCallback decoratedCallback = + [self signInFlowAuthDataResultCallbackByDecoratingCallback:completion]; + if (self->_currentUser.anonymous) { + FIRAdditionalUserInfo *additionalUserInfo = + [[FIRAdditionalUserInfo alloc] initWithProviderID:nil + profile:nil + username:nil + isNewUser:NO]; + FIRAuthDataResult *authDataResult = + [[FIRAuthDataResult alloc] initWithUser:self->_currentUser + additionalUserInfo:additionalUserInfo]; + decoratedCallback(authDataResult, nil); + return; + } + [self internalSignInAnonymouslyWithCompletion:^(FIRSignUpNewUserResponse *_Nullable response, + NSError *_Nullable error) { + if (error) { + decoratedCallback(nil, error); + return; + } + [self completeSignInWithAccessToken:response.IDToken + accessTokenExpirationDate:response.approximateExpirationDate + refreshToken:response.refreshToken + anonymous:YES + callback:^(FIRUser *_Nullable user, NSError *_Nullable error) { + FIRAdditionalUserInfo *additionalUserInfo = + [[FIRAdditionalUserInfo alloc] initWithProviderID:nil + profile:nil + username:nil + isNewUser:YES]; + FIRAuthDataResult *authDataResult = + [[FIRAuthDataResult alloc] initWithUser:user + additionalUserInfo:additionalUserInfo]; + decoratedCallback(authDataResult, nil); + }]; + }]; + }); +} + +- (void)signInAnonymouslyWithCompletion:(nullable FIRAuthDataResultCallback)completion { + dispatch_async(FIRAuthGlobalWorkQueue(), ^{ + FIRAuthDataResultCallback decoratedCallback = + [self signInFlowAuthDataResultCallbackByDecoratingCallback:completion]; + if (self->_currentUser.anonymous) { + FIRAuthDataResult *result = + [[FIRAuthDataResult alloc] initWithUser:self->_currentUser additionalUserInfo:nil]; + decoratedCallback(result, nil); + return; + } + [self internalSignInAnonymouslyWithCompletion:^(FIRSignUpNewUserResponse *_Nullable response, + NSError *_Nullable error) { + if (error) { + decoratedCallback(nil, error); + return; + } + [self completeSignInWithAccessToken:response.IDToken + accessTokenExpirationDate:response.approximateExpirationDate + refreshToken:response.refreshToken + anonymous:YES + callback:^(FIRUser * _Nullable user, NSError * _Nullable error) { + FIRAdditionalUserInfo *additionalUserInfo = + [[FIRAdditionalUserInfo alloc] initWithProviderID:FIREmailAuthProviderID + profile:nil + username:nil + isNewUser:YES]; + FIRAuthDataResult *authDataResult = + [[FIRAuthDataResult alloc] initWithUser:user + additionalUserInfo:additionalUserInfo]; + decoratedCallback(authDataResult, nil); + }]; + }]; + }); +} + +- (void)signInWithCustomToken:(NSString *)token + completion:(nullable FIRAuthDataResultCallback)completion { + dispatch_async(FIRAuthGlobalWorkQueue(), ^{ + FIRAuthDataResultCallback decoratedCallback = + [self signInFlowAuthDataResultCallbackByDecoratingCallback:completion]; + [self internalSignInAndRetrieveDataWithCustomToken:token + completion:^(FIRAuthDataResult *_Nullable authResult, + NSError *_Nullable error) { + decoratedCallback(authResult, error); + }]; + }); +} + +- (void)signInAndRetrieveDataWithCustomToken:(NSString *)token + completion:(nullable FIRAuthDataResultCallback)completion { + dispatch_async(FIRAuthGlobalWorkQueue(), ^{ + FIRAuthDataResultCallback decoratedCallback = + [self signInFlowAuthDataResultCallbackByDecoratingCallback:completion]; + [self internalSignInAndRetrieveDataWithCustomToken:token completion:decoratedCallback]; + }); +} + +- (void)createUserWithEmail:(NSString *)email + password:(NSString *)password + completion:(nullable FIRAuthDataResultCallback)completion { + dispatch_async(FIRAuthGlobalWorkQueue(), ^{ + FIRAuthDataResultCallback decoratedCallback = + [self signInFlowAuthDataResultCallbackByDecoratingCallback:completion]; + [self internalCreateUserWithEmail:email + password:password + completion:^(FIRSignUpNewUserResponse *_Nullable response, + NSError *_Nullable error) { + if (error) { + decoratedCallback(nil, error); + return; + } + [self completeSignInWithAccessToken:response.IDToken + accessTokenExpirationDate:response.approximateExpirationDate + refreshToken:response.refreshToken + anonymous:NO + callback:^(FIRUser *_Nullable user, NSError *_Nullable error) { + FIRAdditionalUserInfo *additionalUserInfo = + [[FIRAdditionalUserInfo alloc] initWithProviderID:FIREmailAuthProviderID + profile:nil + username:nil + isNewUser:YES]; + FIRAuthDataResult *authDataResult = + [[FIRAuthDataResult alloc] initWithUser:user + additionalUserInfo:additionalUserInfo]; + decoratedCallback(authDataResult, nil); + }]; + }]; + }); +} + +- (void)createUserAndRetrieveDataWithEmail:(NSString *)email + password:(NSString *)password + completion:(nullable FIRAuthDataResultCallback)completion { + dispatch_async(FIRAuthGlobalWorkQueue(), ^{ + FIRAuthDataResultCallback decoratedCallback = + [self signInFlowAuthDataResultCallbackByDecoratingCallback:completion]; + [self internalCreateUserWithEmail:email + password:password + completion:^(FIRSignUpNewUserResponse *_Nullable response, + NSError *_Nullable error) { + if (error) { + decoratedCallback(nil, error); + return; + } + + [self completeSignInWithAccessToken:response.IDToken + accessTokenExpirationDate:response.approximateExpirationDate + refreshToken:response.refreshToken + anonymous:NO + callback:^(FIRUser *_Nullable user, NSError *_Nullable error) { + FIRAdditionalUserInfo *additionalUserInfo = + [[FIRAdditionalUserInfo alloc] initWithProviderID:FIREmailAuthProviderID + profile:nil + username:nil + isNewUser:YES]; + FIRAuthDataResult *authDataResult = + [[FIRAuthDataResult alloc] initWithUser:user + additionalUserInfo:additionalUserInfo]; + decoratedCallback(authDataResult, nil); + }]; + }]; + }); +} + +- (void)confirmPasswordResetWithCode:(NSString *)code + newPassword:(NSString *)newPassword + completion:(FIRConfirmPasswordResetCallback)completion { + dispatch_async(FIRAuthGlobalWorkQueue(), ^{ + FIRResetPasswordRequest *request = + [[FIRResetPasswordRequest alloc] initWithOobCode:code + newPassword:newPassword + requestConfiguration:self->_requestConfiguration]; + [FIRAuthBackend resetPassword:request callback:^(FIRResetPasswordResponse *_Nullable response, + NSError *_Nullable error) { + if (completion) { + dispatch_async(dispatch_get_main_queue(), ^{ + if (error) { + completion(error); + return; + } + completion(nil); + }); + } + }]; + }); +} + +- (void)checkActionCode:(NSString *)code completion:(FIRCheckActionCodeCallBack)completion { + dispatch_async(FIRAuthGlobalWorkQueue(), ^ { + FIRResetPasswordRequest *request = + [[FIRResetPasswordRequest alloc] initWithOobCode:code + newPassword:nil + requestConfiguration:self->_requestConfiguration]; + [FIRAuthBackend resetPassword:request callback:^(FIRResetPasswordResponse *_Nullable response, + NSError *_Nullable error) { + if (completion) { + if (error) { + dispatch_async(dispatch_get_main_queue(), ^{ + completion(nil, error); + }); + return; + } + FIRActionCodeOperation operation = + [FIRActionCodeInfo actionCodeOperationForRequestType:response.requestType]; + FIRActionCodeInfo *actionCodeInfo = + [[FIRActionCodeInfo alloc] initWithOperation:operation + email:response.email + newEmail:response.verifiedEmail]; + dispatch_async(dispatch_get_main_queue(), ^{ + completion(actionCodeInfo, nil); + }); + } + }]; + }); +} + +- (void)verifyPasswordResetCode:(NSString *)code + completion:(FIRVerifyPasswordResetCodeCallback)completion { + [self checkActionCode:code completion:^(FIRActionCodeInfo *_Nullable info, + NSError *_Nullable error) { + if (completion) { + if (error) { + completion(nil, error); + return; + } + completion([info dataForKey:FIRActionCodeEmailKey], nil); + } + }]; +} + +- (void)applyActionCode:(NSString *)code completion:(FIRApplyActionCodeCallback)completion { + dispatch_async(FIRAuthGlobalWorkQueue(), ^ { + FIRSetAccountInfoRequest *request = + [[FIRSetAccountInfoRequest alloc] initWithRequestConfiguration:self->_requestConfiguration]; + request.OOBCode = code; + [FIRAuthBackend setAccountInfo:request callback:^(FIRSetAccountInfoResponse *_Nullable response, + NSError *_Nullable error) { + if (completion) { + dispatch_async(dispatch_get_main_queue(), ^{ + completion(error); + }); + } + }]; + }); +} + +- (void)sendPasswordResetWithEmail:(NSString *)email + completion:(nullable FIRSendPasswordResetCallback)completion { + [self sendPasswordResetWithNullableActionCodeSettings:nil email:email completion:completion]; +} + +- (void)sendPasswordResetWithEmail:(NSString *)email + actionCodeSettings:(FIRActionCodeSettings *)actionCodeSettings + completion:(nullable FIRSendPasswordResetCallback)completion { + [self sendPasswordResetWithNullableActionCodeSettings:actionCodeSettings + email:email + completion:completion]; +} + +/** @fn sendPasswordResetWithNullableActionCodeSettings:actionCodeSetting:email:completion: + @brief Initiates a password reset for the given email address and @FIRActionCodeSettings object. + + @param actionCodeSettings Optionally, An @c FIRActionCodeSettings object containing settings + related to the handling action codes. + @param email The email address of the user. + @param completion Optionally; a block which is invoked when the request finishes. Invoked + asynchronously on the main thread in the future. + */ +- (void)sendPasswordResetWithNullableActionCodeSettings:(nullable FIRActionCodeSettings *) + actionCodeSettings + email:(NSString *)email + completion:(nullable FIRSendPasswordResetCallback) + completion { + dispatch_async(FIRAuthGlobalWorkQueue(), ^{ + if (!email) { + [FIRAuthExceptionUtils raiseInvalidParameterExceptionWithReason: + kMissingEmailInvalidParameterExceptionReason]; + return; + } + FIRGetOOBConfirmationCodeRequest *request = + [FIRGetOOBConfirmationCodeRequest passwordResetRequestWithEmail:email + actionCodeSettings:actionCodeSettings + requestConfiguration:self->_requestConfiguration + ]; + [FIRAuthBackend getOOBConfirmationCode:request + callback:^(FIRGetOOBConfirmationCodeResponse *_Nullable response, + NSError *_Nullable error) { + if (completion) { + dispatch_async(dispatch_get_main_queue(), ^{ + completion(error); + }); + } + }]; + }); +} + +- (void)sendSignInLinkToEmail:(nonnull NSString *)email + actionCodeSettings:(nonnull FIRActionCodeSettings *)actionCodeSettings + completion:(nullable FIRSendSignInLinkToEmailCallback)completion { + dispatch_async(FIRAuthGlobalWorkQueue(), ^{ + if (!email) { + [FIRAuthExceptionUtils raiseInvalidParameterExceptionWithReason: + kMissingEmailInvalidParameterExceptionReason]; + } + + if (!actionCodeSettings.handleCodeInApp) { + [FIRAuthExceptionUtils raiseInvalidParameterExceptionWithReason: + kHandleCodeInAppFalseExceptionReason]; + } + FIRGetOOBConfirmationCodeRequest *request = + [FIRGetOOBConfirmationCodeRequest signInWithEmailLinkRequest:email + actionCodeSettings:actionCodeSettings + requestConfiguration:self->_requestConfiguration]; + [FIRAuthBackend getOOBConfirmationCode:request + callback:^(FIRGetOOBConfirmationCodeResponse *_Nullable response, + NSError *_Nullable error) { + if (completion) { + dispatch_async(dispatch_get_main_queue(), ^{ + completion(error); + }); + } + }]; + }); +} + +- (void)updateCurrentUser:(FIRUser *)user completion:(nullable FIRUserUpdateCallback)completion { + dispatch_async(FIRAuthGlobalWorkQueue(), ^{ + if (!user) { + if (completion) { + dispatch_async(dispatch_get_main_queue(), ^{ + completion([FIRAuthErrorUtils nullUserErrorWithMessage:nil]); + }); + } + return; + } + void (^updateUserBlock)(FIRUser *user) = ^(FIRUser *user) { + NSError *error; + [self updateCurrentUser:user byForce:YES savingToDisk:YES error:(&error)]; + if (error) { + if (completion) { + dispatch_async(dispatch_get_main_queue(), ^{ + completion(error); + }); + } + return; + } if (completion) { + dispatch_async(dispatch_get_main_queue(), ^{ + completion(nil); + }); + } + }; + if (![user.requestConfiguration.APIKey isEqualToString:self->_requestConfiguration.APIKey]) { + // If the API keys are different, then we need to confirm that the user belongs to the same + // project before proceeding. + user.requestConfiguration = self->_requestConfiguration; + [user reloadWithCompletion:^(NSError *_Nullable error) { + if (error) { + if (completion) { + dispatch_async(dispatch_get_main_queue(), ^{ + completion(error); + }); + } + return; + } + updateUserBlock(user); + }]; + } else { + updateUserBlock(user); + } + }); +} + +- (BOOL)signOut:(NSError *_Nullable __autoreleasing *_Nullable)error { + __block BOOL result = YES; + dispatch_sync(FIRAuthGlobalWorkQueue(), ^{ + if (!self->_currentUser) { + return; + } + result = [self updateCurrentUser:nil byForce:NO savingToDisk:YES error:error]; + }); + return result; +} + +- (BOOL)signOutByForceWithUserID:(NSString *)userID error:(NSError *_Nullable *_Nullable)error { + if (_currentUser.uid != userID) { + return YES; + } + return [self updateCurrentUser:nil byForce:YES savingToDisk:YES error:error]; +} + +- (BOOL)isSignInWithEmailLink:(NSString *)link { + if (link.length == 0) { + return NO; + } + NSDictionary *queryItems = FIRAuthParseURL(link); + if (![queryItems count]) { + NSURLComponents *urlComponents = [NSURLComponents componentsWithString:link]; + if (!urlComponents.query) { + return NO; + } + queryItems = FIRAuthParseURL(urlComponents.query); + } + + if (![queryItems count]) { + return NO; + } + + NSString *actionCode = queryItems[@"oobCode"]; + NSString *mode = queryItems[@"mode"]; + + if (actionCode && [mode isEqualToString:@"signIn"]) { + return YES; + } + return NO; +} + +/** @fn FIRAuthParseURL:NSString + @brief Parses an incoming URL into all available query items. + @param urlString The url to be parsed. + @return A dictionary of available query items in the target URL. + */ +static NSDictionary *FIRAuthParseURL(NSString *urlString) { + NSString *linkURL = [NSURLComponents componentsWithString:urlString].query; + if (!linkURL) { + return @{}; + } + NSArray *URLComponents = [linkURL componentsSeparatedByString:@"&"]; + NSMutableDictionary *queryItems = + [[NSMutableDictionary alloc] initWithCapacity:URLComponents.count]; + for (NSString *component in URLComponents) { + NSRange equalRange = [component rangeOfString:@"="]; + if (equalRange.location != NSNotFound) { + NSString *queryItemKey = + [[component substringToIndex:equalRange.location] stringByRemovingPercentEncoding]; + NSString *queryItemValue = + [[component substringFromIndex:equalRange.location + 1] stringByRemovingPercentEncoding]; + if (queryItemKey && queryItemValue) { + queryItems[queryItemKey] = queryItemValue; + } + } + } + return queryItems; +} + +- (FIRAuthStateDidChangeListenerHandle)addAuthStateDidChangeListener: + (FIRAuthStateDidChangeListenerBlock)listener { + __block BOOL firstInvocation = YES; + __block NSString *previousUserID; + return [self addIDTokenDidChangeListener:^(FIRAuth *_Nonnull auth, FIRUser *_Nullable user) { + BOOL shouldCallListener = firstInvocation || + !(previousUserID == user.uid || [previousUserID isEqualToString:user.uid]); + firstInvocation = NO; + previousUserID = [user.uid copy]; + if (shouldCallListener) { + listener(auth, user); + } + }]; +} + +- (void)removeAuthStateDidChangeListener:(FIRAuthStateDidChangeListenerHandle)listenerHandle { + [self removeIDTokenDidChangeListener:listenerHandle]; +} + +- (FIRIDTokenDidChangeListenerHandle)addIDTokenDidChangeListener: + (FIRIDTokenDidChangeListenerBlock)listener { + if (!listener) { + [NSException raise:NSInvalidArgumentException format:@"listener must not be nil."]; + return nil; + } + FIRAuthStateDidChangeListenerHandle handle; + NSNotificationCenter *notifications = [NSNotificationCenter defaultCenter]; + handle = [notifications addObserverForName:FIRAuthStateDidChangeNotification + object:self + queue:[NSOperationQueue mainQueue] + usingBlock:^(NSNotification *_Nonnull notification) { + FIRAuth *auth = notification.object; + listener(auth, auth.currentUser); + }]; + @synchronized (self) { + [_listenerHandles addObject:handle]; + } + dispatch_async(dispatch_get_main_queue(), ^{ + listener(self, self->_currentUser); + }); + return handle; +} + +- (void)removeIDTokenDidChangeListener:(FIRIDTokenDidChangeListenerHandle)listenerHandle { + [[NSNotificationCenter defaultCenter] removeObserver:listenerHandle]; + @synchronized (self) { + [_listenerHandles removeObject:listenerHandle]; + } +} + +- (void)useAppLanguage { + dispatch_sync(FIRAuthGlobalWorkQueue(), ^{ + self->_requestConfiguration.languageCode = + [NSBundle mainBundle].preferredLocalizations.firstObject; + }); +} + +- (nullable NSString *)languageCode { + return _requestConfiguration.languageCode; +} + +- (void)setLanguageCode:(nullable NSString *)languageCode { + dispatch_sync(FIRAuthGlobalWorkQueue(), ^{ + self->_requestConfiguration.languageCode = [languageCode copy]; + }); +} + +- (nullable NSString *)additionalFrameworkMarker { + return self->_requestConfiguration.additionalFrameworkMarker; +} + +- (void)setAdditionalFrameworkMarker:(nullable NSString *)additionalFrameworkMarker { + dispatch_sync(FIRAuthGlobalWorkQueue(), ^{ + self->_requestConfiguration.additionalFrameworkMarker = [additionalFrameworkMarker copy]; + }); +} + +#if TARGET_OS_IOS +- (nullable NSData *)APNSToken { + __block NSData *result = nil; + dispatch_sync(FIRAuthGlobalWorkQueue(), ^{ + result = self->_tokenManager.token.data; + }); + return result; +} + +- (void)setAPNSToken:(nullable NSData *)APNSToken { + [self setAPNSToken:APNSToken type:FIRAuthAPNSTokenTypeUnknown]; +} + +- (void)setAPNSToken:(NSData *)token type:(FIRAuthAPNSTokenType)type { + dispatch_sync(FIRAuthGlobalWorkQueue(), ^{ + self->_tokenManager.token = [[FIRAuthAPNSToken alloc] initWithData:token type:type]; + }); +} + +- (void)handleAPNSTokenError:(NSError *)error { + dispatch_sync(FIRAuthGlobalWorkQueue(), ^{ + [self->_tokenManager cancelWithError:error]; + }); +} + +- (BOOL)canHandleNotification:(NSDictionary *)userInfo { + __block BOOL result = NO; + dispatch_sync(FIRAuthGlobalWorkQueue(), ^{ + result = [self->_notificationManager canHandleNotification:userInfo]; + }); + return result; +} + +- (BOOL)canHandleURL:(NSURL *)URL { + __block BOOL result = NO; + dispatch_sync(FIRAuthGlobalWorkQueue(), ^{ + result = [self->_authURLPresenter canHandleURL:URL]; + }); + return result; +} +#endif + +#pragma mark - Internal Methods + +#if TARGET_OS_IOS +/** @fn signInWithPhoneCredential:callback: + @brief Signs in using a phone credential. + @param credential The Phone Auth credential used to sign in. + @param operation The type of operation for which this sign-in attempt is initiated. + @param callback A block which is invoked when the sign in finishes (or is cancelled.) Invoked + asynchronously on the global auth work queue in the future. + */ +- (void)signInWithPhoneCredential:(FIRPhoneAuthCredential *)credential + operation:(FIRAuthOperationType)operation + callback:(FIRVerifyPhoneNumberResponseCallback)callback { + if (credential.temporaryProof.length && credential.phoneNumber.length) { + FIRVerifyPhoneNumberRequest *request = + [[FIRVerifyPhoneNumberRequest alloc] initWithTemporaryProof:credential.temporaryProof + phoneNumber:credential.phoneNumber + operation:operation + requestConfiguration:_requestConfiguration]; + [FIRAuthBackend verifyPhoneNumber:request callback:callback]; + return; + } + + if (!credential.verificationID.length) { + callback(nil, [FIRAuthErrorUtils missingVerificationIDErrorWithMessage:nil]); + return; + } + if (!credential.verificationCode.length) { + callback(nil, [FIRAuthErrorUtils missingVerificationCodeErrorWithMessage:nil]); + return; + } + FIRVerifyPhoneNumberRequest *request = + [[FIRVerifyPhoneNumberRequest alloc]initWithVerificationID:credential.verificationID + verificationCode:credential.verificationCode + operation:operation + requestConfiguration:_requestConfiguration]; + [FIRAuthBackend verifyPhoneNumber:request callback:callback]; +} + +#endif + +/** @fn internalSignInAndRetrieveDataWithCustomToken:completion: + @brief Signs in a Firebase user given a custom token. + @param token A self-signed custom auth token. + @param completion A block which is invoked when the custom token sign in request completes. + */ +- (void)internalSignInAndRetrieveDataWithCustomToken:(NSString *)token + completion:(nullable FIRAuthDataResultCallback) + completion { + FIRVerifyCustomTokenRequest *request = + [[FIRVerifyCustomTokenRequest alloc] initWithToken:token + requestConfiguration:_requestConfiguration]; + [FIRAuthBackend verifyCustomToken:request + callback:^(FIRVerifyCustomTokenResponse *_Nullable response, + NSError *_Nullable error) { + if (error) { + if (completion) { + completion(nil, error); + return; + } + } + [self completeSignInWithAccessToken:response.IDToken + accessTokenExpirationDate:response.approximateExpirationDate + refreshToken:response.refreshToken + anonymous:NO + callback:^(FIRUser *_Nullable user, + NSError *_Nullable error) { + if (error) { + if (completion) { + completion(nil, error); + } + return; + } + FIRAdditionalUserInfo *additonalUserInfo = + [[FIRAdditionalUserInfo alloc] initWithProviderID:nil + profile:nil + username:nil + isNewUser:response.isNewUser]; + FIRAuthDataResult *result = + [[FIRAuthDataResult alloc] initWithUser:user additionalUserInfo:additonalUserInfo]; + if (completion) { + completion(result, nil); + } + }]; + }]; +} + +/** @fn internalCreateUserWithEmail:password:completion: + @brief Makes a backend request attempting to create a new Firebase user given an email address + and password. + @param email The email address used to create the new Firebase user. + @param password The password used to create the new Firebase user. + @param completion Optionally; a block which is invoked when the request finishes. + */ +- (void)internalCreateUserWithEmail:(NSString *)email + password:(NSString *)password + completion:(nullable FIRSignupNewUserCallback)completion { + FIRSignUpNewUserRequest *request = + [[FIRSignUpNewUserRequest alloc] initWithEmail:email + password:password + displayName:nil + requestConfiguration:_requestConfiguration]; + if (![request.password length]) { + completion(nil, [FIRAuthErrorUtils + weakPasswordErrorWithServerResponseReason:kMissingPasswordReason]); + return; + } + if (![request.email length]) { + completion(nil, [FIRAuthErrorUtils missingEmailErrorWithMessage:nil]); + return; + } + [FIRAuthBackend signUpNewUser:request callback:completion]; +} + +/** @fn internalSignInAnonymouslyWithCompletion: + @param completion A block which is invoked when the anonymous sign in request completes. + */ +- (void)internalSignInAnonymouslyWithCompletion:(FIRSignupNewUserCallback)completion { + FIRSignUpNewUserRequest *request = + [[FIRSignUpNewUserRequest alloc]initWithRequestConfiguration:_requestConfiguration]; + [FIRAuthBackend signUpNewUser:request + callback:completion]; +} + +/** @fn possiblyPostAuthStateChangeNotification + @brief Posts the auth state change notificaton if current user's token has been changed. + */ +- (void)possiblyPostAuthStateChangeNotification { + NSString *token = _currentUser.rawAccessToken; + if (_lastNotifiedUserToken == token || + (token != nil && [_lastNotifiedUserToken isEqualToString:token])) { + return; + } + _lastNotifiedUserToken = token; + if (_autoRefreshTokens) { + // Shedule new refresh task after successful attempt. + [self scheduleAutoTokenRefresh]; + } + NSMutableDictionary *internalNotificationParameters = [NSMutableDictionary dictionary]; + if (self.app) { + internalNotificationParameters[FIRAuthStateDidChangeInternalNotificationAppKey] = self.app; + } + if (token.length) { + internalNotificationParameters[FIRAuthStateDidChangeInternalNotificationTokenKey] = token; + } + internalNotificationParameters[FIRAuthStateDidChangeInternalNotificationUIDKey] = _currentUser.uid; + NSNotificationCenter *notifications = [NSNotificationCenter defaultCenter]; + dispatch_async(dispatch_get_main_queue(), ^{ + [notifications postNotificationName:FIRAuthStateDidChangeInternalNotification + object:self + userInfo:internalNotificationParameters]; + [notifications postNotificationName:FIRAuthStateDidChangeNotification + object:self]; + }); +} + +- (BOOL)updateKeychainWithUser:(FIRUser *)user error:(NSError *_Nullable *_Nullable)error { + if (user != _currentUser) { + // No-op if the user is no longer signed in. This is not considered an error as we don't check + // whether the user is still current on other callbacks of user operations either. + return YES; + } + if ([self saveUser:user error:error]) { + [self possiblyPostAuthStateChangeNotification]; + return YES; + } + return NO; +} + +/** @fn setKeychainServiceNameForApp + @brief Sets the keychain service name global data for the particular app. + @param app The Firebase app to set keychain service name for. + */ ++ (void)setKeychainServiceNameForApp:(FIRApp *)app { + @synchronized (self) { + gKeychainServiceNameForAppName[app.name] = + [@"firebase_auth_" stringByAppendingString:app.options.googleAppID]; + } +} + +/** @fn keychainServiceNameForAppName: + @brief Gets the keychain service name global data for the particular app by name. + @param appName The name of the Firebase app to get keychain service name for. + */ ++ (NSString *)keychainServiceNameForAppName:(NSString *)appName { + @synchronized (self) { + return gKeychainServiceNameForAppName[appName]; + } +} + +/** @fn deleteKeychainServiceNameForAppName: + @brief Deletes the keychain service name global data for the particular app by name. + @param appName The name of the Firebase app to delete keychain service name for. + */ ++ (void)deleteKeychainServiceNameForAppName:(NSString *)appName { + @synchronized (self) { + [gKeychainServiceNameForAppName removeObjectForKey:appName]; + } +} + +/** @fn scheduleAutoTokenRefreshWithDelay: + @brief Schedules a task to automatically refresh tokens on the current user. The token refresh + is scheduled 5 minutes before the scheduled expiration time. + @remarks If the token expires in less than 5 minutes, schedule the token refresh immediately. + */ +- (void)scheduleAutoTokenRefresh { + NSTimeInterval tokenExpirationInterval = + [_currentUser.accessTokenExpirationDate timeIntervalSinceNow] - kTokenRefreshHeadStart; + [self scheduleAutoTokenRefreshWithDelay:MAX(tokenExpirationInterval, 0) retry:NO]; +} + +/** @fn scheduleAutoTokenRefreshWithDelay: + @brief Schedules a task to automatically refresh tokens on the current user. + @param delay The delay in seconds after which the token refresh task should be scheduled to be + executed. + @param retry Flag to determine whether the invocation is a retry attempt or not. + */ +- (void)scheduleAutoTokenRefreshWithDelay:(NSTimeInterval)delay retry:(BOOL)retry { + NSString *accessToken = _currentUser.rawAccessToken; + if (!accessToken) { + return; + } + if (retry) { + FIRLogInfo(kFIRLoggerAuth, @"I-AUT000003", + @"Token auto-refresh re-scheduled in %02d:%02d " + @"because of error on previous refresh attempt.", + (int)ceil(delay) / 60, (int)ceil(delay) % 60); + } else { + FIRLogInfo(kFIRLoggerAuth, @"I-AUT000004", + @"Token auto-refresh scheduled in %02d:%02d for the new token.", + (int)ceil(delay) / 60, (int)ceil(delay) % 60); + } + _autoRefreshScheduled = YES; + __weak FIRAuth *weakSelf = self; + [[FIRAuthDispatcher sharedInstance] dispatchAfterDelay:delay + queue:FIRAuthGlobalWorkQueue() + task:^(void) { + FIRAuth *strongSelf = weakSelf; + if (!strongSelf) { + return; + } + if (![strongSelf->_currentUser.rawAccessToken isEqualToString:accessToken]) { + // Another auto refresh must have been scheduled, so keep _autoRefreshScheduled unchanged. + return; + } + strongSelf->_autoRefreshScheduled = NO; + if (strongSelf->_isAppInBackground) { + return; + } + NSString *uid = strongSelf->_currentUser.uid; + [strongSelf->_currentUser internalGetTokenForcingRefresh:YES + callback:^(NSString *_Nullable token, + NSError *_Nullable error) { + if (![strongSelf->_currentUser.uid isEqualToString:uid]) { + return; + } + if (error) { + // Kicks off exponential back off logic to retry failed attempt. Starts with one minute + // delay (60 seconds) if this is the first failed attempt. + NSTimeInterval rescheduleDelay; + if (retry) { + rescheduleDelay = MIN(delay * 2, kMaxWaitTimeForBackoff); + } else { + rescheduleDelay = 60; + } + [strongSelf scheduleAutoTokenRefreshWithDelay:rescheduleDelay retry:YES]; + } + }]; + }]; +} + +#pragma mark - + +/** @fn completeSignInWithTokenService:callback: + @brief Completes a sign-in flow once we have access and refresh tokens for the user. + @param accessToken The STS access token. + @param accessTokenExpirationDate The approximate expiration date of the access token. + @param refreshToken The STS refresh token. + @param anonymous Whether or not the user is anonymous. + @param callback Called when the user has been signed in or when an error occurred. Invoked + asynchronously on the global auth work queue in the future. + */ +- (void)completeSignInWithAccessToken:(NSString *)accessToken + accessTokenExpirationDate:(NSDate *)accessTokenExpirationDate + refreshToken:(NSString *)refreshToken + anonymous:(BOOL)anonymous + callback:(FIRAuthResultCallback)callback { + [FIRUser retrieveUserWithAuth:self + accessToken:accessToken + accessTokenExpirationDate:accessTokenExpirationDate + refreshToken:refreshToken + anonymous:anonymous + callback:callback]; +} + +/** @fn signInFlowAuthResultCallbackByDecoratingCallback: + @brief Creates a FIRAuthResultCallback block which wraps another FIRAuthResultCallback; trying + to update the current user before forwarding it's invocations along to a subject block + @param callback Called when the user has been updated or when an error has occurred. Invoked + asynchronously on the main thread in the future. + @return Returns a block that updates the current user. + @remarks Typically invoked as part of the complete sign-in flow. For any other uses please + consider alternative ways of updating the current user. +*/ +- (FIRAuthResultCallback)signInFlowAuthResultCallbackByDecoratingCallback: + (nullable FIRAuthResultCallback)callback { + return ^(FIRUser *_Nullable user, NSError *_Nullable error) { + if (error) { + if (callback) { + dispatch_async(dispatch_get_main_queue(), ^{ + callback(nil, error); + }); + } + return; + } + if (![self updateCurrentUser:user byForce:NO savingToDisk:YES error:&error]) { + if (callback) { + dispatch_async(dispatch_get_main_queue(), ^{ + callback(nil, error); + }); + } + return; + } + if (callback) { + dispatch_async(dispatch_get_main_queue(), ^{ + callback(user, nil); + }); + } + }; +} + +/** @fn signInFlowAuthDataResultCallbackByDecoratingCallback: + @brief Creates a FIRAuthDataResultCallback block which wraps another FIRAuthDataResultCallback; + trying to update the current user before forwarding it's invocations along to a subject + block. + @param callback Called when the user has been updated or when an error has occurred. Invoked + asynchronously on the main thread in the future. + @return Returns a block that updates the current user. + @remarks Typically invoked as part of the complete sign-in flow. For any other uses please + consider alternative ways of updating the current user. +*/ +- (FIRAuthDataResultCallback)signInFlowAuthDataResultCallbackByDecoratingCallback: + (nullable FIRAuthDataResultCallback)callback { + return ^(FIRAuthDataResult *_Nullable authResult, NSError *_Nullable error) { + if (error) { + if (callback) { + dispatch_async(dispatch_get_main_queue(), ^{ + callback(nil, error); + }); + } + return; + } + if (![self updateCurrentUser:authResult.user byForce:NO savingToDisk:YES error:&error]) { + if (callback) { + dispatch_async(dispatch_get_main_queue(), ^{ + callback(nil, error); + }); + } + return; + } + if (callback) { + dispatch_async(dispatch_get_main_queue(), ^{ + callback(authResult, nil); + }); + } + }; +} + +#pragma mark - User-Related Methods + +/** @fn updateCurrentUser:byForce:savingToDisk:error: + @brief Update the current user; initializing the user's internal properties correctly, and + optionally saving the user to disk. + @remarks This method is called during: sign in and sign out events, as well as during class + initialization time. The only time the saveToDisk parameter should be set to NO is during + class initialization time because the user was just read from disk. + @param user The user to use as the current user (including nil, which is passed at sign out + time.) + @param saveToDisk Indicates the method should persist the user data to disk. + */ +- (BOOL)updateCurrentUser:(nullable FIRUser *)user + byForce:(BOOL)force + savingToDisk:(BOOL)saveToDisk + error:(NSError *_Nullable *_Nullable)error { + if (user == _currentUser) { + [self possiblyPostAuthStateChangeNotification]; + return YES; + } + BOOL success = YES; + if (saveToDisk) { + success = [self saveUser:user error:error]; + } + if (success || force) { + _currentUser = user; + [self possiblyPostAuthStateChangeNotification]; + } + return success; +} + +/** @fn saveUser:error: + @brief Persists user. + @param user The user to save. + @param error Return value for any error which occurs. + @return @YES on success, @NO otherwise. + */ +- (BOOL)saveUser:(FIRUser *)user + error:(NSError *_Nullable *_Nullable)error { + BOOL success; + NSString *userKey = [NSString stringWithFormat:kUserKey, _firebaseAppName]; + + if (!user) { + success = [_keychain removeDataForKey:userKey error:error]; + } else { + // Encode the user object. + NSMutableData *archiveData = [NSMutableData data]; + NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:archiveData]; + [archiver encodeObject:user forKey:userKey]; + [archiver finishEncoding]; + + // Save the user object's encoded value. + success = [_keychain setData:archiveData forKey:userKey error:error]; + } + return success; +} + +/** @fn getUser:error: + @brief Retrieves the saved user associated, if one exists, from the keychain. + @param outUser An out parameter which is populated with the saved user, if one exists. + @param error Return value for any error which occurs. + @return YES if the operation was a success (irrespective of whether or not a saved user existed + for the given @c firebaseAppId,) NO if an error occurred. + */ +- (BOOL)getUser:(FIRUser *_Nullable *)outUser + error:(NSError *_Nullable *_Nullable)error { + NSString *userKey = [NSString stringWithFormat:kUserKey, _firebaseAppName]; + + NSError *keychainError; + NSData *encodedUserData = [_keychain dataForKey:userKey error:&keychainError]; + if (keychainError) { + if (error) { + *error = keychainError; + } + return NO; + } + if (!encodedUserData) { + *outUser = nil; + return YES; + } + NSKeyedUnarchiver *unarchiver = + [[NSKeyedUnarchiver alloc] initForReadingWithData:encodedUserData]; + FIRUser *user = [unarchiver decodeObjectOfClass:[FIRUser class] forKey:userKey]; + user.auth = self; + *outUser = user; + return YES; +} + +#pragma mark - Interoperability + ++ (nonnull NSArray *)componentsToRegister { + FIRComponentCreationBlock authCreationBlock = + ^id _Nullable(FIRComponentContainer *_Nonnull container, BOOL *_Nonnull isCacheable) { + *isCacheable = YES; + return [[FIRAuth alloc] initWithApp:container.app]; + }; + FIRComponent *authInterop = [FIRComponent componentWithProtocol:@protocol(FIRAuthInterop) + creationBlock:authCreationBlock]; + return @[authInterop]; +} + +#pragma mark - FIRCoreConfigurable + ++ (void)configureWithApp:(nonnull FIRApp *)app { + // TODO: Evaluate what actually needs to be configured here instead of initializing a full + // instance. + // Ensures the @c FIRAuth instance for a given app gets loaded as soon as the app is ready. + [FIRAuth authWithApp:app]; +} + +#pragma mark - FIRComponentLifecycleMaintainer + +- (void)appWillBeDeleted:(nonnull FIRApp *)app { + dispatch_async(FIRAuthGlobalWorkQueue(), ^{ + // This doesn't stop any request already issued, see b/27704535 . + NSString *keychainServiceName = [FIRAuth keychainServiceNameForAppName:app.name]; + if (keychainServiceName) { + [[self class] deleteKeychainServiceNameForAppName:app.name]; + FIRAuthKeychain *keychain = [[FIRAuthKeychain alloc] initWithService:keychainServiceName]; + NSString *userKey = [NSString stringWithFormat:kUserKey, app.name]; + [keychain removeDataForKey:userKey error:NULL]; + } + dispatch_async(dispatch_get_main_queue(), ^{ + // TODO: Move over to fire an event instead, once ready. + [[NSNotificationCenter defaultCenter] postNotificationName:FIRAuthStateDidChangeNotification + object:nil]; + }); + }); +} + +#pragma mark - FIRAuthInterop + +- (void)getTokenForcingRefresh:(BOOL)forceRefresh withCallback:(FIRTokenCallback)callback { + __weak FIRAuth *weakSelf = self; + dispatch_async(FIRAuthGlobalWorkQueue(), ^{ + FIRAuth *strongSelf = weakSelf; + // Enable token auto-refresh if not aleady enabled. + if (strongSelf && !strongSelf->_autoRefreshTokens) { + FIRLogInfo(kFIRLoggerAuth, @"I-AUT000002", @"Token auto-refresh enabled."); + strongSelf->_autoRefreshTokens = YES; + [strongSelf scheduleAutoTokenRefresh]; + +#if TARGET_OS_IOS || TARGET_OS_TV // TODO: Is a similar mechanism needed on macOS? + strongSelf->_applicationDidBecomeActiveObserver = [[NSNotificationCenter defaultCenter] + addObserverForName:UIApplicationDidBecomeActiveNotification + object:nil + queue:nil + usingBlock:^(NSNotification *notification) { + FIRAuth *strongSelf = weakSelf; + if (strongSelf) { + strongSelf->_isAppInBackground = NO; + if (!strongSelf->_autoRefreshScheduled) { + [weakSelf scheduleAutoTokenRefresh]; + } + } + }]; + strongSelf->_applicationDidEnterBackgroundObserver = [[NSNotificationCenter defaultCenter] + addObserverForName:UIApplicationDidEnterBackgroundNotification + object:nil + queue:nil + usingBlock:^(NSNotification *notification) { + FIRAuth *strongSelf = weakSelf; + if (strongSelf) { + strongSelf->_isAppInBackground = YES; + } + }]; +#endif + } + // Call back with 'nil' if there is no current user. + if (!strongSelf || !strongSelf->_currentUser) { + dispatch_async(dispatch_get_main_queue(), ^{ + callback(nil, nil); + }); + return; + } + // Call back with current user token. + [strongSelf->_currentUser internalGetTokenForcingRefresh:forceRefresh + callback:^(NSString *_Nullable token, + NSError *_Nullable error) { + dispatch_async(dispatch_get_main_queue(), ^{ + callback(token, error); + }); + }]; + }); +} + +- (nullable NSString *)getUserID { + return _currentUser.uid; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthAPNSToken.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthAPNSToken.h new file mode 100644 index 0000000..dc07442 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthAPNSToken.h @@ -0,0 +1,59 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +#import "FIRAuthAPNSTokenType.h" + +NS_ASSUME_NONNULL_BEGIN + +/** @class FIRAuthAPNSToken + @brief A data structure for an APNs token. + */ +@interface FIRAuthAPNSToken : NSObject + +/** @property data + @brief The APNs token data. + */ +@property(nonatomic, strong, readonly) NSData *data; + +/** @property string + @brief The uppercase hexadecimal string form of the APNs token data. + */ +@property(nonatomic, strong, readonly) NSString *string; + +/** @property type + @brief The APNs token type. + */ +@property(nonatomic, assign, readonly) FIRAuthAPNSTokenType type; + +/** @fn initWithData:type: + @brief Initializes the instance. + @param data The APNs token data. + @param type The APNs token type. + @return The initialized instance. + */ +- (instancetype)initWithData:(NSData *)data type:(FIRAuthAPNSTokenType)type + NS_DESIGNATED_INITIALIZER; + +/** @fn init + @brief Call @c initWithData:type: to get an instance of this class. + */ +- (instancetype)init NS_UNAVAILABLE; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthAPNSToken.m b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthAPNSToken.m new file mode 100644 index 0000000..db3f96d --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthAPNSToken.m @@ -0,0 +1,52 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRAuthAPNSToken.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation FIRAuthAPNSToken { + /** @var _string + @brief The lazy-initialized string form of the token data. + */ + NSString *_string; +} + +- (instancetype)initWithData:(NSData *)data type:(FIRAuthAPNSTokenType)type { + self = [super init]; + if (self) { + _data = [data copy]; + _type = type; + } + return self; +} + +- (NSString *)string { + if (!_string) { + NSUInteger capacity = _data.length * 2; + NSMutableString *tokenString = [NSMutableString stringWithCapacity:capacity]; + const unsigned char *tokenData = _data.bytes; + for (int idx = 0; idx < _data.length; ++idx) { + [tokenString appendFormat:@"%02X", (int)tokenData[idx]]; + } + _string = tokenString; + } + return _string; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthAPNSTokenManager.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthAPNSTokenManager.h new file mode 100644 index 0000000..566780f --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthAPNSTokenManager.h @@ -0,0 +1,78 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import +#import + +@class FIRAuthAPNSToken; + +NS_ASSUME_NONNULL_BEGIN + +/** @typedef FIRAuthAPNSTokenCallback + @brief The type of block to receive an APNs token. + @param token The APNs token if one is available. + @param error The error happened if any. + @remarks Both `token` and `error` being `nil` means the request timed-out. + */ +typedef void (^FIRAuthAPNSTokenCallback)(FIRAuthAPNSToken *_Nullable token, + NSError *_Nullable error); + +/** @class FIRAuthAPNSTokenManager + @brief A class to manage APNs token in memory. + */ +@interface FIRAuthAPNSTokenManager : NSObject + +/** @property token + @brief The APNs token, if one is available. + @remarks Setting a token with FIRAuthAPNSTokenTypeUnknown will automatically converts it to + a token with the automatically detected type. + */ +@property(nonatomic, strong, nullable) FIRAuthAPNSToken *token; + +/** @property timeout + @brief The timeout for registering for remote notification. + @remarks Only tests should access this property. + */ +@property(nonatomic, assign) NSTimeInterval timeout; + +/** @fn init + @brief Call @c initWithApplication: to initialize an instance of this class. + */ +- (instancetype)init NS_UNAVAILABLE; + +/** @fn initWithApplication:bundle + @brief Initializes the instance. + @param application The @c UIApplication to request the token from. + @return The initialized instance. + */ +- (instancetype)initWithApplication:(UIApplication *)application NS_DESIGNATED_INITIALIZER; + +/** @fn getTokenWithCallback: + @brief Attempts to get the APNs token. + @param callback The block to be called either immediately or in future, either when a token + becomes available, or when timeout occurs, whichever happens earlier. + */ +- (void)getTokenWithCallback:(FIRAuthAPNSTokenCallback)callback; + +/** @fn cancelWithError: + @brief Cancels any pending `getTokenWithCallback:` request. + @param error The error to return. + */ +- (void)cancelWithError:(NSError *)error; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthAPNSTokenManager.m b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthAPNSTokenManager.m new file mode 100644 index 0000000..3e8dd90 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthAPNSTokenManager.m @@ -0,0 +1,247 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRAuthAPNSTokenManager.h" + +#import +#import + +#import "FIRAuthAPNSToken.h" +#import "FIRAuthGlobalWorkQueue.h" + +NS_ASSUME_NONNULL_BEGIN + +/** @var kRegistrationTimeout + @brief Timeout for registration for remote notification. + @remarks Once we start to handle `application:didFailToRegisterForRemoteNotificationsWithError:` + we probably don't have to use timeout at all. + */ +static const NSTimeInterval kRegistrationTimeout = 5; + +/** @var kLegacyRegistrationTimeout + @brief Timeout for registration for remote notification on iOS 7. + */ +static const NSTimeInterval kLegacyRegistrationTimeout = 30; + +@implementation FIRAuthAPNSTokenManager { + /** @var _application + @brief The @c UIApplication to request the token from. + */ + UIApplication *_application; + + /** @var _pendingCallbacks + @brief The list of all pending callbacks for the APNs token. + */ + NSMutableArray *_pendingCallbacks; +} + +- (instancetype)initWithApplication:(UIApplication *)application { + self = [super init]; + if (self) { + _application = application; + _timeout = [_application respondsToSelector:@selector(registerForRemoteNotifications)] ? + kRegistrationTimeout : kLegacyRegistrationTimeout; + } + return self; +} + +- (void)getTokenWithCallback:(FIRAuthAPNSTokenCallback)callback { + if (_token) { + callback(_token, nil); + return; + } + if (_pendingCallbacks) { + [_pendingCallbacks addObject:callback]; + return; + } + _pendingCallbacks = + [[NSMutableArray alloc] initWithObjects:callback, nil]; + dispatch_async(dispatch_get_main_queue(), ^{ + if ([self->_application respondsToSelector:@selector(registerForRemoteNotifications)]) { + [self->_application registerForRemoteNotifications]; + } else { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" +#if TARGET_OS_IOS + [self->_application registerForRemoteNotificationTypes:UIRemoteNotificationTypeAlert]; +#endif // TARGET_OS_IOS +#pragma clang diagnostic pop + } + }); + NSArray *applicableCallbacks = _pendingCallbacks; + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(_timeout * NSEC_PER_SEC)), + FIRAuthGlobalWorkQueue(), ^{ + // Only cancel if the pending callbacks remain the same, i.e., not triggered yet. + if (applicableCallbacks == self->_pendingCallbacks) { + [self callBackWithToken:nil error:nil]; + } + }); +} + +- (void)setToken:(nullable FIRAuthAPNSToken *)token { + if (!token) { + _token = nil; + return; + } + if (token.type == FIRAuthAPNSTokenTypeUnknown) { + static FIRAuthAPNSTokenType detectedTokenType = FIRAuthAPNSTokenTypeUnknown; + if (detectedTokenType == FIRAuthAPNSTokenTypeUnknown) { + detectedTokenType = + [[self class] isProductionApp] ? FIRAuthAPNSTokenTypeProd : FIRAuthAPNSTokenTypeSandbox; + } + token = [[FIRAuthAPNSToken alloc] initWithData:token.data type:detectedTokenType]; + } + _token = token; + [self callBackWithToken:token error:nil]; +} + +- (void)cancelWithError:(NSError *)error { + [self callBackWithToken:nil error:error]; +} + +#pragma mark - Internal methods + +/** @fn callBack + @brief Calls back all pending callbacks with APNs token or error. + @param token The APNs token if one is available. + @param error The error occurred, if any. + */ +- (void)callBackWithToken:(nullable FIRAuthAPNSToken *)token error:(nullable NSError *)error { + if (!_pendingCallbacks) { + return; + } + NSArray *allCallbacks = _pendingCallbacks; + _pendingCallbacks = nil; + for (FIRAuthAPNSTokenCallback callback in allCallbacks) { + callback(token, error); + } +}; + +/** @fn isProductionApp + @brief Whether or not the app has production (versus sandbox) provisioning profile. + @remarks This method is adapted from @c FIRInstanceID . + */ ++ (BOOL)isProductionApp { + const BOOL defaultAppTypeProd = YES; + + NSError *error = nil; + + if ([GULAppEnvironmentUtil isSimulator]) { + FIRLogInfo(kFIRLoggerAuth, @"I-AUT000006", @"Assuming prod APNs token type on simulator."); + return defaultAppTypeProd; + } + + // Apps distributed via AppStore or TestFlight use the Production APNS certificates. + if ([GULAppEnvironmentUtil isFromAppStore]) { + return defaultAppTypeProd; + } + NSString *path = [[[NSBundle mainBundle] bundlePath] + stringByAppendingPathComponent:@"embedded.mobileprovision"]; + if ([GULAppEnvironmentUtil isAppStoreReceiptSandbox] && !path.length) { + // Distributed via TestFlight + return defaultAppTypeProd; + } + + NSMutableData *profileData = [NSMutableData dataWithContentsOfFile:path options:0 error:&error]; + + if (!profileData.length || error) { + FIRLogInfo(kFIRLoggerAuth, @"I-AUT000007", + @"Error while reading embedded mobileprovision %@", error); + return defaultAppTypeProd; + } + + // The "embedded.mobileprovision" sometimes contains characters with value 0, which signals the + // end of a c-string and halts the ASCII parser, or with value > 127, which violates strict 7-bit + // ASCII. Replace any 0s or invalid characters in the input. + uint8_t *profileBytes = (uint8_t *)profileData.bytes; + for (int i = 0; i < profileData.length; i++) { + uint8_t currentByte = profileBytes[i]; + if (!currentByte || currentByte > 127) { + profileBytes[i] = '.'; + } + } + + NSString *embeddedProfile = [[NSString alloc] initWithBytesNoCopy:profileBytes + length:profileData.length + encoding:NSASCIIStringEncoding + freeWhenDone:NO]; + + if (error || !embeddedProfile.length) { + FIRLogInfo(kFIRLoggerAuth, @"I-AUT000008", + @"Error while reading embedded mobileprovision %@", error); + return defaultAppTypeProd; + } + + NSScanner *scanner = [NSScanner scannerWithString:embeddedProfile]; + NSString *plistContents; + if ([scanner scanUpToString:@"" intoString:&plistContents]) { + plistContents = [plistContents stringByAppendingString:@""]; + } + } + + if (!plistContents.length) { + return defaultAppTypeProd; + } + + NSData *data = [plistContents dataUsingEncoding:NSUTF8StringEncoding]; + if (!data.length) { + FIRLogInfo(kFIRLoggerAuth, @"I-AUT000009", + @"Couldn't read plist fetched from embedded mobileprovision"); + return defaultAppTypeProd; + } + + NSError *plistMapError; + id plistData = [NSPropertyListSerialization propertyListWithData:data + options:NSPropertyListImmutable + format:nil + error:&plistMapError]; + if (plistMapError || ![plistData isKindOfClass:[NSDictionary class]]) { + FIRLogInfo(kFIRLoggerAuth, @"I-AUT000010", + @"Error while converting assumed plist to dict %@", + plistMapError.localizedDescription); + return defaultAppTypeProd; + } + NSDictionary *plistMap = (NSDictionary *)plistData; + + if ([plistMap valueForKeyPath:@"ProvisionedDevices"]) { + FIRLogInfo(kFIRLoggerAuth, @"I-AUT000011", + @"Provisioning profile has specifically provisioned devices, " + @"most likely a Dev profile."); + } + + NSString *apsEnvironment = [plistMap valueForKeyPath:@"Entitlements.aps-environment"]; + FIRLogDebug(kFIRLoggerAuth, @"I-AUT000012", + @"APNS Environment in profile: %@", apsEnvironment); + + // No aps-environment in the profile. + if (!apsEnvironment.length) { + FIRLogInfo(kFIRLoggerAuth, @"I-AUT000013", + @"No aps-environment set. If testing on a device APNS is not " + @"correctly configured. Please recheck your provisioning profiles."); + return defaultAppTypeProd; + } + + if ([apsEnvironment isEqualToString:@"development"]) { + return NO; + } + + return defaultAppTypeProd; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthAppCredential.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthAppCredential.h new file mode 100644 index 0000000..57fa83a --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthAppCredential.h @@ -0,0 +1,53 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** @class FIRAuthAppCredential + @brief A class represents a credential that proves the identity of the app. + */ +@interface FIRAuthAppCredential : NSObject + +/** @property receipt + @brief The server acknowledgement of receiving client's claim of identity. + */ +@property(nonatomic, strong, readonly) NSString *receipt; + +/** @property secret + @brief The secret that the client received from server via a trusted channel, if ever. + */ +@property(nonatomic, strong, readonly, nullable) NSString *secret; + +/** @fn initWithReceipt:secret: + @brief Initializes the instance. + @param receipt The server acknowledgement of receiving client's claim of identity. + @param secret The secret that the client received from server via a trusted channel, if ever. + @return The initialized instance. + */ +- (instancetype)initWithReceipt:(NSString *)receipt secret:(nullable NSString *)secret + NS_DESIGNATED_INITIALIZER; + +/** @fn init + @brief Call @c initWithReceipt:secret: to get an instance of this class. + */ +- (instancetype)init NS_UNAVAILABLE; + + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthAppCredential.m b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthAppCredential.m new file mode 100644 index 0000000..27d4ad2 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthAppCredential.m @@ -0,0 +1,64 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRAuthAppCredential.h" + +NS_ASSUME_NONNULL_BEGIN + +/** @var kReceiptKey + @brief The key used to encode the receipt property for NSSecureCoding. + */ +static NSString *const kReceiptKey = @"receipt"; + +/** @var kSecretKey + @brief The key used to encode the secret property for NSSecureCoding. + */ +static NSString *const kSecretKey = @"secret"; + +@implementation FIRAuthAppCredential + +- (instancetype)initWithReceipt:(NSString *)receipt secret:(nullable NSString *)secret { + self = [super init]; + if (self) { + _receipt = [receipt copy]; + _secret = [secret copy]; + } + return self; +} + +#pragma mark - NSSecureCoding + ++ (BOOL)supportsSecureCoding { + return YES; +} + +- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder { + NSString *receipt = [aDecoder decodeObjectOfClass:[NSString class] forKey:kReceiptKey]; + if (!receipt) { + return nil; + } + NSString *secret = [aDecoder decodeObjectOfClass:[NSString class] forKey:kSecretKey]; + return [self initWithReceipt:receipt secret:secret]; +} + +- (void)encodeWithCoder:(NSCoder *)aCoder { + [aCoder encodeObject:_receipt forKey:kReceiptKey]; + [aCoder encodeObject:_secret forKey:kSecretKey]; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthAppCredentialManager.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthAppCredentialManager.h new file mode 100644 index 0000000..21c1545 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthAppCredentialManager.h @@ -0,0 +1,85 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +@class FIRAuthAppCredential; +@class FIRAuthKeychain; + +NS_ASSUME_NONNULL_BEGIN + +/** @typedef FIRAuthAppCredentialCallback + @brief The type of block to receive an app crdential. + @param credential The best available app credential at the time. + */ +typedef void (^FIRAuthAppCredentialCallback)(FIRAuthAppCredential *credential); + +/** @class FIRAuthAppCredentialManager + @brief A class to manage app credentials backed by iOS Keychain. + */ +@interface FIRAuthAppCredentialManager : NSObject + +/** @property credential + @brief The full credential (which has a secret) to be used by the app, if one is available. + */ +@property(nonatomic, strong, readonly, nullable) FIRAuthAppCredential *credential; + +/** @property maximumNumberOfPendingReceipts + @brief The maximum (but not necessarily the minimum) number of pending receipts to be kept. + @remarks Only tests should access this property. + */ +@property(nonatomic, assign, readonly) NSUInteger maximumNumberOfPendingReceipts; + +/** @fn init + @brief Call @c initWithKeychain: to initialize an instance of this class. + */ +- (instancetype)init NS_UNAVAILABLE; + +/** @fn initWithKeychain: + @brief Initializes the instance. + @param keychain The iOS Keychain storage to back up the app credential with. + @return The initialized instance. + */ +- (instancetype)initWithKeychain:(FIRAuthKeychain *)keychain NS_DESIGNATED_INITIALIZER; + +/** @fn didStartVerificationWithReceipt:timeout:callback: + @brief Notifies that the app verification process has started. + @param receipt The receipt for verification. + @param timeout The timeout value for how long the callback is waited to be called. + @param callback The block to be called in future either when the verification finishes, or + when timeout occurs, whichever happens earlier. + */ +- (void)didStartVerificationWithReceipt:(NSString *)receipt + timeout:(NSTimeInterval)timeout + callback:(FIRAuthAppCredentialCallback)callback; + +/** @fn canFinishVerificationWithReceipt: + @brief Attempts to finish verification. + @param receipt The receipt to match the original receipt obtained when verification started. + @param secret The secret to complete the verification. + @return Whether or not the receipt matches a pending verification, and finishes verification + if it does. + */ +- (BOOL)canFinishVerificationWithReceipt:(NSString *)receipt secret:(NSString *)secret; + +/** @fn clearCredential + @brief Clears the saved credential, to be used in the case that it is rejected by the server. + */ +- (void)clearCredential; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthAppCredentialManager.m b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthAppCredentialManager.m new file mode 100644 index 0000000..0e251a7 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthAppCredentialManager.m @@ -0,0 +1,164 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRAuthAppCredentialManager.h" + +#import "FIRAuthAppCredential.h" +#import "FIRAuthGlobalWorkQueue.h" +#import "FIRAuthKeychain.h" + +NS_ASSUME_NONNULL_BEGIN + +/** @var kKeychainDataKey + @brief The keychain key for the data. + */ +static NSString *const kKeychainDataKey = @"app_credentials"; + +/** @var kFullCredentialKey + @brief The data key for the full app credential. + */ +static NSString *const kFullCredentialKey = @"full_credential"; + +/** @var kPendingReceiptsKey + @brief The data key for the array of pending receipts. + */ +static NSString *const kPendingReceiptsKey = @"pending_receipts"; + +/** @var kMaximumNumberOfPendingReceipts + @brief The maximum number of partial credentials kept by this class. + */ +static const NSUInteger kMaximumNumberOfPendingReceipts = 32; + +@implementation FIRAuthAppCredentialManager { + /** @var _keychain + @brief The keychain for app credentials to load from and to save to. + */ + FIRAuthKeychain *_keychain; + + /** @var _pendingReceipts + @brief A list of pending receipts sorted in the order they were recorded. + */ + NSMutableArray *_pendingReceipts; + + /** @var _callbacksByReceipt + @brief A map from pending receipts to callbacks. + */ + NSMutableDictionary *_callbacksByReceipt; +} + +- (instancetype)initWithKeychain:(FIRAuthKeychain *)keychain { + self = [super init]; + if (self) { + _keychain = keychain; + // Load the credentials from keychain if possible. + NSError *error; + NSData *encodedData = [_keychain dataForKey:kKeychainDataKey error:&error]; + if (!error && encodedData) { + NSKeyedUnarchiver *unarchiver = + [[NSKeyedUnarchiver alloc] initForReadingWithData:encodedData]; + FIRAuthAppCredential *credential = + [unarchiver decodeObjectOfClass:[FIRAuthAppCredential class] + forKey:kFullCredentialKey]; + if ([credential isKindOfClass:[FIRAuthAppCredential class]]) { + _credential = credential; + } + NSSet *allowedClasses = + [NSSet setWithObjects:[NSArray class], [NSString class], nil]; + NSArray *pendingReceipts = + [unarchiver decodeObjectOfClasses:allowedClasses forKey:kPendingReceiptsKey]; + if ([pendingReceipts isKindOfClass:[NSArray class]]) { + _pendingReceipts = [pendingReceipts mutableCopy]; + } + } + if (!_pendingReceipts) { + _pendingReceipts = [[NSMutableArray alloc] init]; + } + _callbacksByReceipt = + [[NSMutableDictionary alloc] init]; + } + return self; +} + +- (NSUInteger)maximumNumberOfPendingReceipts { + return kMaximumNumberOfPendingReceipts; +} + +- (void)didStartVerificationWithReceipt:(NSString *)receipt + timeout:(NSTimeInterval)timeout + callback:(FIRAuthAppCredentialCallback)callback { + [_pendingReceipts removeObject:receipt]; + if (_pendingReceipts.count >= kMaximumNumberOfPendingReceipts) { + [_pendingReceipts removeObjectAtIndex:0]; + } + [_pendingReceipts addObject:receipt]; + _callbacksByReceipt[receipt] = callback; + [self saveData]; + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(timeout * NSEC_PER_SEC)), + FIRAuthGlobalWorkQueue(), ^{ + [self callBackWithReceipt:receipt]; + }); +} + +- (BOOL)canFinishVerificationWithReceipt:(NSString *)receipt secret:(NSString *)secret { + if (![_pendingReceipts containsObject:receipt]) { + return NO; + } + [_pendingReceipts removeObject:receipt]; + _credential = [[FIRAuthAppCredential alloc] initWithReceipt:receipt secret:secret]; + [self saveData]; + [self callBackWithReceipt:receipt]; + return YES; +} + +- (void)clearCredential { + _credential = nil; + [self saveData]; +} + +#pragma mark - Internal methods + +/** @fn saveData + @brief Save the data in memory to the keychain ignoring any errors. + */ +- (void)saveData { + NSMutableData *archiveData = [NSMutableData data]; + NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:archiveData]; + [archiver encodeObject:_credential forKey:kFullCredentialKey]; + [archiver encodeObject:_pendingReceipts forKey:kPendingReceiptsKey]; + [archiver finishEncoding]; + [_keychain setData:archiveData forKey:kKeychainDataKey error:NULL]; +} + +/** @fn callBackWithReceipt: + @brief Calls the saved callback for the specifc receipt. + @param receipt The receipt associated with the callback. + */ +- (void)callBackWithReceipt:(NSString *)receipt { + FIRAuthAppCredentialCallback callback = _callbacksByReceipt[receipt]; + if (!callback) { + return; + } + [_callbacksByReceipt removeObjectForKey:receipt]; + if (_credential) { + callback(_credential); + } else { + callback([[FIRAuthAppCredential alloc] initWithReceipt:receipt secret:nil]); + } +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthAppDelegateProxy.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthAppDelegateProxy.h new file mode 100644 index 0000000..ccae93a --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthAppDelegateProxy.h @@ -0,0 +1,87 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import +#import + +NS_ASSUME_NONNULL_BEGIN + +/** @protocol FIRAuthAppDelegateHandler + @brief The protocol to handle app delegate methods. + */ +@protocol FIRAuthAppDelegateHandler + +/** @fn setAPNSToken: + @brief Sets the APNs device token. + @param token The APNs device token. + */ +- (void)setAPNSToken:(NSData *)token; + +/** @fn handleAPNSTokenError: + @brief Handles APNs device token error. + @param error The APNs device token error. + */ +- (void)handleAPNSTokenError:(NSError *)error; + +/** @fn canHandleNotification: + @brief Checks whether the notification can be handled by the receiver, and handles it if so. + @param notification The notification in question, which will be consumed if returns @c YES. + @return Whether the notification can be (and already has been) handled by the receiver. + */ +- (BOOL)canHandleNotification:(nonnull NSDictionary *)notification; + +/** @fn canHandleURL: + @brief Checks whether the URL can be handled by the receiver, and handles it if so. + @param url The URL in question, which will be consumed if returns @c YES. + @return Whether the URL can be (and already has been) handled by the receiver. + */ +- (BOOL)canHandleURL:(nonnull NSURL *)url; + +@end + +/** @class FIRAuthAppDelegateProxy + @brief A manager for swizzling @c UIApplicationDelegate methods. + */ +@interface FIRAuthAppDelegateProxy : NSObject + +/** @fn initWithApplication + @brief Initialize the instance with the given @c UIApplication. + @returns An initialized instance, or @c nil if a proxy cannot be established. + @remarks This method should only be called from tests if called outside of this class. + */ +- (nullable instancetype)initWithApplication:(nullable UIApplication *)application + NS_DESIGNATED_INITIALIZER; + +/** @fn init + @brief Call @c sharedInstance to get an instance of this class. + */ +- (instancetype)init NS_UNAVAILABLE; + +/** @fn addHandler: + @brief Adds a handler for UIApplicationDelegate methods. + @param handler The handler to be added. + */ +- (void)addHandler:(__weak id)handler; + +/** @fn sharedInstance + @brief Gets the shared instance of this class. + @returns The shared instance of this class. + */ ++ (nullable instancetype)sharedInstance; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthAppDelegateProxy.m b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthAppDelegateProxy.m new file mode 100644 index 0000000..d97fedc --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthAppDelegateProxy.m @@ -0,0 +1,412 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRAuthAppDelegateProxy.h" + +#import + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** @var kProxyEnabledBundleKey + @brief The key in application's bundle plist for whether or not proxy should be enabled. + @remarks This key is a shared constant with Analytics and FCM. + */ +static NSString *const kProxyEnabledBundleKey = @"FirebaseAppDelegateProxyEnabled"; + +/** @fn noop + @brief A function that does nothing. + @remarks This is used as the placeholder for unimplemented UApplicationDelegate methods, + because once we added a method there is no way to remove it from the class. + */ +#if !OBJC_OLD_DISPATCH_PROTOTYPES +static void noop(void) { +} +#else +static id noop(id object, SEL cmd, ...) { + return nil; +} +#endif + +/** @fn isIOS9orLater + @brief Checks whether the iOS version is 9 or later. + @returns Whether the iOS version is 9 or later. + */ +static BOOL isIOS9orLater() { +#if defined(__IPHONE_11_0) && (__IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_11_0) + if (@available(iOS 9.0, *)) { + return YES; + } + return NO; +#else + // UIApplicationOpenURLOptionsAnnotationKey is only available on iOS 9+. + return &UIApplicationOpenURLOptionsAnnotationKey != NULL; +#endif +} + +@implementation FIRAuthAppDelegateProxy { + /** @var _appDelegate + @brief The application delegate whose method is being swizzled. + */ + id _appDelegate; + + /** @var _orginalImplementationsBySelector + @brief A map from selectors to original implementations that have been swizzled. + */ + NSMutableDictionary *_originalImplementationsBySelector; + + /** @var _handlers + @brief The array of weak pointers of `id`. + */ + NSPointerArray *_handlers; +} + +- (nullable instancetype)initWithApplication:(nullable UIApplication *)application { + self = [super init]; + if (self) { + id proxyEnabled = [[NSBundle mainBundle] objectForInfoDictionaryKey:kProxyEnabledBundleKey]; + if ([proxyEnabled isKindOfClass:[NSNumber class]] && !((NSNumber *)proxyEnabled).boolValue) { + return nil; + } + _appDelegate = application.delegate; + if (![_appDelegate conformsToProtocol:@protocol(UIApplicationDelegate)]) { + return nil; + } + _originalImplementationsBySelector = [[NSMutableDictionary alloc] init]; + _handlers = [[NSPointerArray alloc] initWithOptions:NSPointerFunctionsWeakMemory]; + + // Swizzle the methods. + __weak FIRAuthAppDelegateProxy *weakSelf = self; + SEL registerDeviceTokenSelector = + @selector(application:didRegisterForRemoteNotificationsWithDeviceToken:); + [self replaceSelector:registerDeviceTokenSelector + withBlock:^(id object, UIApplication* application, NSData *deviceToken) { + [weakSelf object:object + selector:registerDeviceTokenSelector + application:application + didRegisterForRemoteNotificationsWithDeviceToken:deviceToken]; + }]; + SEL failToRegisterRemoteNotificationSelector = + @selector(application:didFailToRegisterForRemoteNotificationsWithError:); + [self replaceSelector:failToRegisterRemoteNotificationSelector + withBlock:^(id object, UIApplication* application, NSError *error) { + [weakSelf object:object + selector:failToRegisterRemoteNotificationSelector + application:application + didFailToRegisterForRemoteNotificationsWithError:error]; + }]; + SEL receiveNotificationSelector = @selector(application:didReceiveRemoteNotification:); + SEL receiveNotificationWithHandlerSelector = + @selector(application:didReceiveRemoteNotification:fetchCompletionHandler:); + if ([_appDelegate respondsToSelector:receiveNotificationWithHandlerSelector] || + ![_appDelegate respondsToSelector:receiveNotificationSelector]) { + // Replace the modern selector which is available on iOS 7 and above. + [self replaceSelector:receiveNotificationWithHandlerSelector + withBlock:^(id object, UIApplication *application, NSDictionary *notification, + void (^completionHandler)(UIBackgroundFetchResult)) { + [weakSelf object:object + selector:receiveNotificationWithHandlerSelector + application:application + didReceiveRemoteNotification:notification + fetchCompletionHandler:completionHandler]; + }]; + } else { + // Replace the deprecated selector because this is the only one that the client app uses. + [self replaceSelector:receiveNotificationSelector + withBlock:^(id object, UIApplication *application, NSDictionary *notification) { + [weakSelf object:object + selector:receiveNotificationSelector + application:application + didReceiveRemoteNotification:notification]; + }]; + } + SEL openURLOptionsSelector = @selector(application:openURL:options:); + SEL openURLAnnotationSelector = @selector(application:openURL:sourceApplication:annotation:); + SEL handleOpenURLSelector = @selector(application:handleOpenURL:); + if (isIOS9orLater() && + ([_appDelegate respondsToSelector:openURLOptionsSelector] || + (![_appDelegate respondsToSelector:openURLAnnotationSelector] && + ![_appDelegate respondsToSelector:handleOpenURLSelector]))) { + // Replace the modern selector which is avaliable on iOS 9 and above because this is the one + // that the client app uses or the client app doesn't use any of them. + [self replaceSelector:openURLOptionsSelector + withBlock:^BOOL(id object, UIApplication *application, NSURL *url, + NSDictionary *options) { + return [weakSelf object:object + selector:openURLOptionsSelector + application:application + openURL:url + options:options]; + }]; + } else if ([_appDelegate respondsToSelector:openURLAnnotationSelector] || + ![_appDelegate respondsToSelector:handleOpenURLSelector]) { + // Replace the longer form of the deprecated selectors on iOS 8 and below because this is the + // one that the client app uses or the client app doesn't use either of the applicable ones. + [self replaceSelector:openURLAnnotationSelector + withBlock:^(id object, UIApplication *application, NSURL *url, + NSString *sourceApplication, id annotation) { + return [weakSelf object:object + selector:openURLAnnotationSelector + application:application + openURL:url + sourceApplication:sourceApplication + annotation:annotation]; + }]; + } else { + // Replace the shorter form of the deprecated selectors on iOS 8 and below because this is + // the only one that the client app uses. + [self replaceSelector:handleOpenURLSelector + withBlock:^(id object, UIApplication *application, NSURL *url) { + return [weakSelf object:object + selector:handleOpenURLSelector + application:application + handleOpenURL:url]; + }]; + } + // Reset the application delegate to clear the system cache that indicates whether each of the + // openURL: methods is implemented on the application delegate. + application.delegate = nil; + application.delegate = _appDelegate; + } + return self; +} + +- (void)dealloc { + for (NSValue *selector in _originalImplementationsBySelector) { + IMP implementation = _originalImplementationsBySelector[selector].pointerValue; + Method method = class_getInstanceMethod([_appDelegate class], selector.pointerValue); + imp_removeBlock(method_setImplementation(method, implementation)); + } +} + +- (void)addHandler:(__weak id)handler { + @synchronized (_handlers) { + [_handlers addPointer:(__bridge void *)handler]; + } +} + ++ (nullable instancetype)sharedInstance { + static dispatch_once_t onceToken; + static FIRAuthAppDelegateProxy *_Nullable sharedInstance; + // iOS App extensions should not call [UIApplication sharedApplication], even if UIApplication + // responds to it. + static Class applicationClass = nil; + dispatch_once(&onceToken, ^{ + if (![GULAppEnvironmentUtil isAppExtension]) { + Class cls = NSClassFromString(@"UIApplication"); + if (cls && [cls respondsToSelector:NSSelectorFromString(@"sharedApplication")]) { + applicationClass = cls; + } + } + UIApplication *application = [applicationClass sharedApplication]; + sharedInstance = [[self alloc] initWithApplication:application]; + }); + return sharedInstance; +} + +#pragma mark - UIApplicationDelegate proxy methods. + +- (void)object:(id)object + selector:(SEL)selector + application:(UIApplication *)application + didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { + if (object == _appDelegate) { + for (id handler in [self handlers]) { + [handler setAPNSToken:deviceToken]; + } + } + IMP originalImplementation = [self originalImplementationForSelector:selector]; + if (originalImplementation && originalImplementation != &noop) { + typedef void (*Implmentation)(id, SEL, UIApplication*, NSData *); + ((Implmentation)originalImplementation)(object, selector, application, deviceToken); + } +} + +- (void)object:(id)object + selector:(SEL)selector + application:(UIApplication *)application + didFailToRegisterForRemoteNotificationsWithError:(NSError *)error { + if (object == _appDelegate) { + for (id handler in [self handlers]) { + [handler handleAPNSTokenError:error]; + } + } + IMP originalImplementation = [self originalImplementationForSelector:selector]; + if (originalImplementation && originalImplementation != &noop) { + typedef void (*Implmentation)(id, SEL, UIApplication *, NSError *); + ((Implmentation)originalImplementation)(object, selector, application, error); + } +} + +- (void)object:(id)object + selector:(SEL)selector + application:(UIApplication *)application + didReceiveRemoteNotification:(NSDictionary *)notification + fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler { + if (object == _appDelegate) { + for (id handler in [self handlers]) { + if ([handler canHandleNotification:notification]) { + completionHandler(UIBackgroundFetchResultNoData); + return; + }; + } + } + IMP originalImplementation = [self originalImplementationForSelector:selector]; + if (originalImplementation && originalImplementation != &noop) { + typedef void (*Implmentation)(id, SEL, UIApplication*, NSDictionary *, + void (^)(UIBackgroundFetchResult)); + ((Implmentation)originalImplementation)(object, selector, application, notification, + completionHandler); + } +} + +- (void)object:(id)object + selector:(SEL)selector + application:(UIApplication *)application + didReceiveRemoteNotification:(NSDictionary *)notification { + if (object == _appDelegate) { + for (id handler in [self handlers]) { + if ([handler canHandleNotification:notification]) { + return; + }; + } + } + IMP originalImplementation = [self originalImplementationForSelector:selector]; + if (originalImplementation && originalImplementation != &noop) { + typedef void (*Implmentation)(id, SEL, UIApplication*, NSDictionary *); + ((Implmentation)originalImplementation)(object, selector, application, notification); + } +} + +- (BOOL)object:(id)object + selector:(SEL)selector + application:(UIApplication *)application + openURL:(NSURL *)url + options:(NSDictionary *)options { + if (object == _appDelegate && [self delegateCanHandleURL:url]) { + return YES; + } + IMP originalImplementation = [self originalImplementationForSelector:selector]; + if (originalImplementation && originalImplementation != &noop) { + typedef BOOL (*Implmentation)(id, SEL, UIApplication*, NSURL *, NSDictionary *); + return ((Implmentation)originalImplementation)(object, selector, application, url, options); + } + return NO; +} + +- (BOOL)object:(id)object + selector:(SEL)selector + application:(UIApplication *)application + openURL:(NSURL *)url + sourceApplication:(NSString *)sourceApplication + annotation:(id)annotation { + if (object == _appDelegate && [self delegateCanHandleURL:url]) { + return YES; + } + IMP originalImplementation = [self originalImplementationForSelector:selector]; + if (originalImplementation && originalImplementation != &noop) { + typedef BOOL (*Implmentation)(id, SEL, UIApplication*, NSURL *, NSString *, id); + return ((Implmentation)originalImplementation)(object, selector, application, url, + sourceApplication, annotation); + } + return NO; +} + +- (BOOL)object:(id)object + selector:(SEL)selector + application:(UIApplication *)application + handleOpenURL:(NSURL *)url { + if (object == _appDelegate && [self delegateCanHandleURL:url]) { + return YES; + } + IMP originalImplementation = [self originalImplementationForSelector:selector]; + if (originalImplementation && originalImplementation != &noop) { + typedef BOOL (*Implmentation)(id, SEL, UIApplication*, NSURL *); + return ((Implmentation)originalImplementation)(object, selector, application, url); + } + return NO; +} + +#pragma mark - Internal Methods + +/** @fn delegateCanHandleURL: + @brief Checks for whether any of the delegates can handle the URL. + @param url The URL in question. + @return Whether any of the delegate can handle the URL. + */ +- (BOOL)delegateCanHandleURL:(NSURL *)url { + for (id handler in [self handlers]) { + if ([handler canHandleURL:url]) { + return YES; + }; + } + return NO; +} + +/** @fn handlers + @brief Gets the list of handlers from `_handlers` safely. + */ +- (NSArray> *)handlers { + @synchronized (_handlers) { + NSMutableArray> *liveHandlers = + [[NSMutableArray> alloc] initWithCapacity:_handlers.count]; + for (__weak id handler in _handlers) { + if (handler) { + [liveHandlers addObject:handler]; + } + } + if (liveHandlers.count < _handlers.count) { + [_handlers compact]; + } + return liveHandlers; + } +} + +/** @fn replaceSelector:withBlock: + @brief replaces the implementation for a method of `_appDelegate` specified by a selector. + @param selector The selector for the method. + @param block The block as the new implementation of the method. + */ +- (void)replaceSelector:(SEL)selector withBlock:(id)block { + Method originalMethod = class_getInstanceMethod([_appDelegate class], selector); + IMP newImplementation = imp_implementationWithBlock(block); + IMP originalImplementation; + if (originalMethod) { + originalImplementation = method_setImplementation(originalMethod, newImplementation) ?: &noop; + } else { + // The original method was not implemented in the class, add it with the new implementation. + struct objc_method_description methodDescription = + protocol_getMethodDescription(@protocol(UIApplicationDelegate), selector, NO, YES); + class_addMethod([_appDelegate class], selector, newImplementation, methodDescription.types); + originalImplementation = &noop; + } + _originalImplementationsBySelector[[NSValue valueWithPointer:selector]] = + [NSValue valueWithPointer:originalImplementation]; +} + +/** @fn originalImplementationForSelector: + @brief Gets the original implementation for the given selector. + @param selector The selector for the method that has been replaced. + @return The original implementation if there was one. + */ +- (IMP)originalImplementationForSelector:(SEL)selector { + return _originalImplementationsBySelector[[NSValue valueWithPointer:selector]].pointerValue; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthCredential.m b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthCredential.m new file mode 100644 index 0000000..510d5f9 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthCredential.m @@ -0,0 +1,46 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRAuthCredential_Internal.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation FIRAuthCredential + +- (instancetype)init { + @throw [NSException exceptionWithName:@"Attempt to call unavailable initializer." + reason:@"This class is an abstract base class. It's init method " + "should not be called directly." + userInfo:nil]; +} + +- (nullable instancetype)initWithProvider:(NSString *)provider { + self = [super init]; + if (self) { + _provider = [provider copy]; + } + return self; +} + +- (void)prepareVerifyAssertionRequest:(FIRVerifyAssertionRequest *)request { + @throw [NSException exceptionWithName:@"Attempt to call virtual method." + reason:@"This method must be overridden by a subclass." + userInfo:nil]; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthCredential_Internal.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthCredential_Internal.h new file mode 100644 index 0000000..e060cda --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthCredential_Internal.h @@ -0,0 +1,41 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRAuthCredential.h" + +@class FIRVerifyAssertionRequest; + +NS_ASSUME_NONNULL_BEGIN + +@interface FIRAuthCredential () + +/** @fn initWithProvider: + @brief Designated initializer. + @remarks This is the designated initializer for internal/friend subclasses. + @param provider The provider name. + */ +- (nullable instancetype)initWithProvider:(NSString *)provider NS_DESIGNATED_INITIALIZER; + +/** @fn prepareVerifyAssertionRequest: + @brief Called immediately before a request to the verifyAssertion endpoint is made. Implementers + should update the passed request instance with their credentials. + @param request The request to be updated with credentials. + */ +- (void)prepareVerifyAssertionRequest:(FIRVerifyAssertionRequest *)request; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthDataResult.m b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthDataResult.m new file mode 100644 index 0000000..9d8e598 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthDataResult.m @@ -0,0 +1,69 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRAuthDataResult_Internal.h" + +#import "FIRAdditionalUserInfo.h" +#import "FIRUser.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation FIRAuthDataResult + +/** @var kAdditionalUserInfoCodingKey + @brief The key used to encode the additionalUserInfo property for NSSecureCoding. + */ +static NSString *const kAdditionalUserInfoCodingKey = @"additionalUserInfo"; + +/** @var kUserCodingKey + @brief The key used to encode the user property for NSSecureCoding. + */ +static NSString *const kUserCodingKey = @"user"; + +- (nullable instancetype)initWithUser:(nullable FIRUser *)user + additionalUserInfo:(nullable FIRAdditionalUserInfo *)additionalUserInfo { + self = [super init]; + if (self) { + _additionalUserInfo = additionalUserInfo; + _user = user; + } + return self; +} + +#pragma mark - NSSecureCoding + ++ (BOOL)supportsSecureCoding { + return YES; +} + +- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder { + FIRUser *user = + [aDecoder decodeObjectOfClass:[FIRUser class] forKey:kUserCodingKey]; + FIRAdditionalUserInfo *additionalUserInfo = + [aDecoder decodeObjectOfClass:[FIRAdditionalUserInfo class] + forKey:kAdditionalUserInfoCodingKey]; + + return [self initWithUser:user additionalUserInfo:additionalUserInfo]; +} + +- (void)encodeWithCoder:(NSCoder *)aCoder { + [aCoder encodeObject:_user forKey:kUserCodingKey]; + [aCoder encodeObject:_additionalUserInfo forKey:kAdditionalUserInfoCodingKey]; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthDataResult_Internal.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthDataResult_Internal.h new file mode 100644 index 0000000..b02bf59 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthDataResult_Internal.h @@ -0,0 +1,34 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRAuthDataResult.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface FIRAuthDataResult () + +/** @fn initWithUser:additionalUserInfo: + @brief Designated initializer. + @param user The signed in user reference. + @param additionalUserInfo The additional user info if available. + */ +- (nullable instancetype)initWithUser:(nullable FIRUser *)user + additionalUserInfo:(nullable FIRAdditionalUserInfo *)additionalUserInfo + NS_DESIGNATED_INITIALIZER; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthDefaultUIDelegate.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthDefaultUIDelegate.h new file mode 100644 index 0000000..03cadf7 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthDefaultUIDelegate.h @@ -0,0 +1,43 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +#import "FIRAuthUIDelegate.h" + +NS_ASSUME_NONNULL_BEGIN + +/** @class FIRAuthDefaultUIDelegate + @brief Class responsible for providing a default FIRAuthUIDelegte. + @remarks This class should be used in the case that a UIDelegate was expected and necessary to + continue a given flow, but none was provided. + */ +@interface FIRAuthDefaultUIDelegate : NSObject + +/** @fn defaultUIDelegate + @brief Unavailable. Please use @c +defaultUIDelegate: + */ +- (instancetype)init NS_UNAVAILABLE; + +/** @fn defaultUIDelegate + @brief Returns a default FIRAuthUIDelegate object. + @return The default FIRAuthUIDelegate object. + */ ++ (id)defaultUIDelegate; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthDefaultUIDelegate.m b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthDefaultUIDelegate.m new file mode 100644 index 0000000..f37dbe4 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthDefaultUIDelegate.m @@ -0,0 +1,93 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRAuthDefaultUIDelegate.h" + +#import +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface FIRAuthDefaultUIDelegate () + +/** @fn initWithViewController: + @brief Initializes the instance with a view controller. + @param viewController The view controller as the presenting view controller in @c + FIRAuthUIDelegate. + @return The initialized instance. + */ +- (instancetype)initWithViewController:(nullable UIViewController *)viewController NS_DESIGNATED_INITIALIZER; + +@end + +@implementation FIRAuthDefaultUIDelegate { + /** @var _viewController + @brief The presenting view controller. + */ + UIViewController *_viewController; +} + +- (instancetype)initWithViewController:(nullable UIViewController *)viewController { + self = [super init]; + if (self) { + _viewController = viewController; + } + return self; +} + +- (void)presentViewController:(UIViewController *)viewControllerToPresent + animated:(BOOL)flag + completion:(nullable void (^)(void))completion { + [_viewController presentViewController:viewControllerToPresent + animated:flag + completion:completion]; +} + +- (void)dismissViewControllerAnimated:(BOOL)flag completion:(nullable void (^)(void))completion { + [_viewController dismissViewControllerAnimated:flag completion:completion]; +} + ++ (id)defaultUIDelegate { + // iOS App extensions should not call [UIApplication sharedApplication], even if UIApplication + // responds to it. + static Class applicationClass = nil; + if (![GULAppEnvironmentUtil isAppExtension]) { + Class cls = NSClassFromString(@"UIApplication"); + if (cls && [cls respondsToSelector:NSSelectorFromString(@"sharedApplication")]) { + applicationClass = cls; + } + } + UIApplication *application = [applicationClass sharedApplication]; + UIViewController *topViewController = application.keyWindow.rootViewController; + while (true){ + if (topViewController.presentedViewController) { + topViewController = topViewController.presentedViewController; + } else if ([topViewController isKindOfClass:[UINavigationController class]]) { + UINavigationController *nav = (UINavigationController *)topViewController; + topViewController = nav.topViewController; + } else if ([topViewController isKindOfClass:[UITabBarController class]]) { + UITabBarController *tab = (UITabBarController *)topViewController; + topViewController = tab.selectedViewController; + } else { + break; + } + } + return [[FIRAuthDefaultUIDelegate alloc] initWithViewController:topViewController]; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthDispatcher.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthDispatcher.h new file mode 100644 index 0000000..f8ddca5 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthDispatcher.h @@ -0,0 +1,63 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** @typedef FIRAuthDispatcherImplBlock + @brief The type of block which can be set as the implementation for @c + dispatchAfterDelay:queue:callback: . + + @param delay The delay in seconds after which the task will be scheduled to execute. + @param queue The dispatch queue on which the task will be submitted. + @param task The task (block) to be scheduled for future execution. + */ +typedef void(^FIRAuthDispatcherImplBlock)(NSTimeInterval delay, + dispatch_queue_t queue, + void (^task)(void)); + +/** @class FIRAuthDispatchAfter + @brief A utility class used to facilitate scheduling tasks to be executed in the future. + */ +@interface FIRAuthDispatcher : NSObject + +/** @property dispatchAfterImplementation + @brief Allows custom implementation of dispatchAfterDelay:queue:callback:. + @remarks Set to nil to restore default implementation. + */ +@property(nonatomic, nullable, copy) FIRAuthDispatcherImplBlock dispatchAfterImplementation; + +/** @fn dispatchAfterDelay:queue:callback: + @brief Schedules task in the future after a specified delay. + + @param delay The delay in seconds after which the task will be scheduled to execute. + @param queue The dispatch queue on which the task will be submitted. + @param task The task (block) to be scheduled for future execution. + */ + - (void)dispatchAfterDelay:(NSTimeInterval)delay + queue:(dispatch_queue_t)queue + task:(void (^)(void))task; + +/** @fn sharedInstance + @brief Gets the shared instance of this class. + @returns The shared instance of this clss + */ ++ (instancetype)sharedInstance; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthDispatcher.m b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthDispatcher.m new file mode 100644 index 0000000..78ed2e3 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthDispatcher.m @@ -0,0 +1,46 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRAuthDispatcher.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation FIRAuthDispatcher + +@synthesize dispatchAfterImplementation = _dispatchAfterImplementation; + ++ (instancetype)sharedInstance { + static dispatch_once_t onceToken; + static FIRAuthDispatcher *sharedInstance; + dispatch_once(&onceToken, ^{ + sharedInstance = [[self alloc] init]; + }); + return sharedInstance; +} + +- (void)dispatchAfterDelay:(NSTimeInterval)delay + queue:(dispatch_queue_t)queue + task:(void (^)(void))task { + if (_dispatchAfterImplementation) { + _dispatchAfterImplementation(delay, queue, task); + return; + } + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, delay * NSEC_PER_SEC), queue, task); +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthErrorUtils.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthErrorUtils.h new file mode 100644 index 0000000..bbf726f --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthErrorUtils.h @@ -0,0 +1,552 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +@class FIRAuthCredential; + +NS_ASSUME_NONNULL_BEGIN + +/** @class FIRAuthErrorUtils + @brief Utility class used to construct @c NSError instances. + */ +@interface FIRAuthErrorUtils : NSObject + +/** @fn RPCRequestEncodingErrorWithUnderlyingError + @brief Constructs an @c NSError with the @c FIRAuthInternalErrorCodeRPCRequestEncodingError + code and a populated @c NSUnderlyingErrorKey in the @c NSError.userInfo dictionary. + @param underlyingError The value of the @c NSUnderlyingErrorKey key. + @remarks This error is used when an @c FIRAuthRPCRequest.unencodedHTTPRequestBodyWithError: + invocation returns an error. The error returned is wrapped in this internal error code. + */ ++ (NSError *)RPCRequestEncodingErrorWithUnderlyingError:(NSError *)underlyingError; + +/** @fn JSONSerializationErrorForUnencodableType + @brief Constructs an @c NSError with the @c FIRAuthErrorCodeJSONSerializationError code. + @remarks This error is used when an @c NSJSONSerialization.isValidJSONObject: check fails, not + for when an error is returned from @c NSJSONSerialization.dataWithJSONObject:options:error:. + */ ++ (NSError *)JSONSerializationErrorForUnencodableType; + +/** @fn JSONSerializationErrorWithUnderlyingError: + @brief Constructs an @c NSError with the @c FIRAuthErrorCodeJSONSerializationError code, and the + @c underlyingError as the @c NSUnderlyingErrorKey value in the @c NSError.userInfo + dictionary. + @param underlyingError The value of the @c NSUnderlyingErrorKey key. + @remarks This error is used when an invocation of + @c NSJSONSerialization.dataWithJSONObject:options:error: returns an error. + */ ++ (NSError *)JSONSerializationErrorWithUnderlyingError:(NSError *)underlyingError; + +/** @fn networkErrorWithUnderlyingError: + @brief Constructs an @c NSError with the @c FIRAuthErrorCodeNetworkError code, and the + @c underlyingError as the @c NSUnderlyingErrorKey value in the @c NSError.userInfo + dictionary. + @param underlyingError The value of the @c NSUnderlyingErrorKey key. Should be the error from + GTM. + @remarks This error is used when a network request results in an error, and no body data was + returned. + */ ++ (NSError *)networkErrorWithUnderlyingError:(NSError *)underlyingError; + +/** @fn unexpectedErrorResponseWithUnderlyingError: + @brief Constructs an @c NSError with the @c FIRAuthErrorCodeNetworkError code, and the + @c underlyingError as the @c NSUnderlyingErrorKey value. + @param data The value of the @c FIRAuthErrorUserInfoDataKey key in the @c NSError.userInfo + dictionary. + @param underlyingError The value of the @c NSUnderlyingErrorKey key in the @c NSError.userInfo + dictionary. + @remarks This error is used when a network request results in an error, and unserializable body + data was returned. + */ ++ (NSError *)unexpectedErrorResponseWithData:(NSData *)data + underlyingError:(NSError *)underlyingError; + +/** @fn unexpectedErrorResponseWithDeserializedResponse: + @brief Constructs an @c NSError with the @c FIRAuthInternalErrorCodeUnexpectedErrorResponse + code, and a populated @c FIRAuthErrorUserInfoDeserializedResponseKey key in the + @c NSError.userInfo dictionary. + @param deserializedResponse The value of the @c FIRAuthErrorUserInfoDeserializedResponseKey key. + @remarks This error is used when a network request results in an error, and the body data was + deserializable as JSON, but couldn't be decoded as an error. + */ ++ (NSError *)unexpectedErrorResponseWithDeserializedResponse:(id)deserializedResponse; + +/** @fn malformedJWTErrorWithToken:underlyingError: + @brief Constructs an @c NSError with the code set to @c FIRAuthErrorCodeMalformedJWT and + populates the userInfo dictionary with an error message, the bad token, and an underlying + error that may have occurred when parsing. + @param token The token that failed to parse. + @param underlyingError The error that caused this error. If this parameter is nil, the + NSUnderlyingErrorKey value will not be set. + @remarks This error is returned when JWT parsing fails. + @returns An @c FIRAuthErrorCodeMalformedJWT error wrapping an underlying error, if available. + */ ++ (NSError *)malformedJWTErrorWithToken:(NSString *)token + underlyingError:(NSError *_Nullable)underlyingError; + +/** @fn unexpectedResponseWithData:underlyingError: + @brief Constructs an @c NSError with the @c FIRAuthInternalErrorCodeUnexpectedResponse + code, and a populated @c FIRAuthErrorUserInfoDataKey key in the @c NSError.userInfo + dictionary. + @param data The value of the @c FIRAuthErrorUserInfoDataKey key in the @c NSError.userInfo + dictionary. + @param underlyingError The value of the @c NSUnderlyingErrorKey key in the @c NSError.userInfo + dictionary. + @remarks This error is used when a network request is apparently successful, but the body data + couldn't be deserialized as JSON. + */ ++ (NSError *)unexpectedResponseWithData:(NSData *)data + underlyingError:(NSError *)underlyingError;; + +/** @fn unexpectedResponseWithDeserializedResponse: + @brief Constructs an @c NSError with the @c FIRAuthInternalErrorCodeUnexpectedResponse + code, and a populated @c FIRAuthErrorUserInfoDeserializedResponseKey key in the + @c NSError.userInfo dictionary. + @param deserializedResponse The value of the @c FIRAuthErrorUserInfoDeserializedResponseKey key. + @remarks This error is used when a network request is apparently successful, the body data was + successfully deserialized as JSON, but the JSON wasn't a dictionary. + */ ++ (NSError *)unexpectedResponseWithDeserializedResponse:(id)deserializedResponse; + +/** @fn unexpectedResponseWithDeserializedResponse:underlyingError: + @brief Constructs an @c NSError with the @c FIRAuthInternalErrorCodeUnexpectedResponse + code, and populated @c FIRAuthErrorUserInfoDeserializedResponseKey and + @c NSUnderlyingErrorKey keys in the @c NSError.userInfo dictionary. + @param deserializedResponse The value of the @c FIRAuthErrorUserInfoDeserializedResponseKey key. + @param underlyingError The value of the @c NSUnderlyingErrorKey key. + @remarks This error is used when a network request was apparently successful, the body data was + successfully deserialized as JSON, but the data type of the response was unexpected. + */ ++ (NSError *)unexpectedResponseWithDeserializedResponse:(nullable id)deserializedResponse + underlyingError:(NSError *)underlyingError; + +/** @fn RPCResponseDecodingErrorWithDeserializedResponse:underlyingError: + @brief Constructs an @c NSError with the @c FIRAuthInternalErrorCodeRPCResponseDecodingError + code, and populated @c FIRAuthErrorUserInfoDeserializedResponseKey and + @c NSUnderlyingErrorKey keys in the @c NSError.userInfo dictionary. + @param deserializedResponse The value of the @c FIRAuthErrorUserInfoDeserializedResponseKey key. + @param underlyingError The value of the @c NSUnderlyingErrorKey key. + @remarks This error is used when an invocation of @c FIRAuthRPCResponse.setWithDictionary:error: + resulted in an error. + */ ++ (NSError *)RPCResponseDecodingErrorWithDeserializedResponse:(id)deserializedResponse + underlyingError:(NSError *)underlyingError; + +/** @fn emailAlreadyInUseErrorWithEmail: + @brief Constructs an @c NSError with the @c FIRAuthErrorCodeEmailExists code. + @param email The email address that is already in use. + @return The NSError instance associated with the given FIRAuthError. + */ ++ (NSError *)emailAlreadyInUseErrorWithEmail:(nullable NSString *)email; + +/** @fn userDisabledErrorWithMessageWithMessage: + @brief Constructs an @c NSError with the @c FIRAuthErrorCodeUserDisabled code. + @param message Error message from the backend, if any. + @return The NSError instance associated with the given FIRAuthError. + */ ++ (NSError *)userDisabledErrorWithMessage:(nullable NSString *)message; + +/** @fn wrongPasswordErrorWithMessage: + @brief Constructs an @c NSError with the @c FIRAuthErrorCodeWrongPassword code. + @param message Error message from the backend, if any. + @return The NSError instance associated with the given FIRAuthError. + */ ++ (NSError *)wrongPasswordErrorWithMessage:(nullable NSString *)message; + +/** @fn tooManyRequestsErrorWithMessage: + @brief Constructs an @c NSError with the @c FIRAuthErrorCodeTooManyRequests Code. + @param message Error message from the backend, if any. + @return The NSError instance associated with the given FIRAuthError. + */ ++ (NSError *)tooManyRequestsErrorWithMessage:(nullable NSString *)message; + +/** @fn invalidCustomTokenErrorWithMessage: + @brief Constructs an @c NSError with the @c FIRAuthErrorCodeInvalidCustomToken code. + @param message Error message from the backend, if any. + @return The NSError instance associated with the given FIRAuthError. + */ ++ (NSError *)invalidCustomTokenErrorWithMessage:(nullable NSString *)message; + +/** @fn customTokenMistmatchErrorWithMessage: + @brief Constructs an @c NSError with the @c FIRAuthErrorCodeCustomTokenMismatch code. + @param message Error message from the backend, if any. + @return The NSError instance associated with the given FIRAuthError. + */ ++ (NSError *)customTokenMistmatchErrorWithMessage:(nullable NSString *)message; + +/** @fn invalidCredentialErrorWithMessage: + @brief Constructs an @c NSError with the @c FIRAuthErrorCodeInvalidCredential code. + @param message Error message from the backend, if any. + @return The NSError instance associated with the given FIRAuthError. + */ ++ (NSError *)invalidCredentialErrorWithMessage:(nullable NSString *)message; + +/** @fn requiresRecentLoginError + @brief Constructs an @c NSError with the @c FIRAuthErrorCodeRequiresRecentLogin code. + @param message Error message from the backend, if any. + @return The NSError instance associated with the given FIRAuthError. + */ ++ (NSError *)requiresRecentLoginErrorWithMessage:(nullable NSString *)message; + +/** @fn invalidUserTokenErrorWithMessage: + @brief Constructs an @c NSError with the @c FIRAuthErrorCodeInvalidUserToken code. + @param message Error message from the backend, if any. + @return The NSError instance associated with the given FIRAuthError. + */ ++ (NSError *)invalidUserTokenErrorWithMessage:(nullable NSString *)message; + +/** @fn invalidEmailErrorWithMessage: + @brief Constructs an @c NSError with the @c FIRAuthErrorCodeInvalidEmail code. + @param message Error message from the backend, if any. + @return The NSError instance associated with the given FIRAuthError. + */ ++ (NSError *)invalidEmailErrorWithMessage:(nullable NSString *)message; + +/** @fn accountExistsWithDifferentCredentialErrorWithEmail: + @brief Constructs an @c NSError with the @c FIRAuthErrorAccountExistsWithDifferentCredential + code. + @param Email The email address that is already associated with an existing account + @return The NSError instance associated with the given FIRAuthError. + */ ++ (NSError *)accountExistsWithDifferentCredentialErrorWithEmail:(nullable NSString *)Email; + +/** @fn providerAlreadyLinkedErrorWithMessage: + @brief Constructs an @c NSError with the @c FIRAuthErrorCodeProviderAlreadyLinked code. + @return The NSError instance associated with the given FIRAuthError. + */ ++ (NSError *)providerAlreadyLinkedError; + +/** @fn noSuchProviderError + @brief Constructs an @c NSError with the @c FIRAuthErrorCodeNoSuchProvider code. + @return The NSError instance associated with the given FIRAuthError. + */ ++ (NSError *)noSuchProviderError; + +/** @fn userTokenExpiredErrorWithMessage: + @brief Constructs an @c NSError with the @c FIRAuthErrorCodeUserTokenExpired code. + @param message Error message from the backend, if any. + @return The NSError instance associated with the given FIRAuthError. + */ ++ (NSError *)userTokenExpiredErrorWithMessage:(nullable NSString *)message; + +/** @fn userNotFoundErrorWithMessage: + @brief Constructs an @c NSError with the @c FIRAuthErrorCodeUserNotFound code. + @param message Error message from the backend, if any. + @return The NSError instance associated with the given FIRAuthError. + */ ++ (NSError *)userNotFoundErrorWithMessage:(nullable NSString *)message; + +/** @fn invalidLocalAPIKeyErrorWithMessage: + @brief Constructs an @c NSError with the @c FIRAuthErrorCodeInvalidAPIKey code. + @return The NSError instance associated with the given FIRAuthError. + */ ++ (NSError *)invalidAPIKeyError; + +/** @fn userMismatchError + @brief Constructs an @c NSError with the @c FIRAuthErrorCodeUserMismatch code. + @return The NSError instance associated with the given FIRAuthError. + */ ++ (NSError *)userMismatchError; + +/** @fn credentialAlreadyInUseErrorWithMessage:email: + @brief Constructs an @c NSError with the @c FIRAuthErrorCodeCredentialAlreadyInUse code. + @param message Error message from the backend, if any. + @param credential Auth credential to be added to the Error User Info dictionary. + @param email Email to be added to the Error User Info dictionary. + @return The NSError instance associated with the given FIRAuthError. + */ ++ (NSError *)credentialAlreadyInUseErrorWithMessage:(nullable NSString *)message + credential:(nullable FIRAuthCredential *)credential + email:(nullable NSString *)email; +/** @fn operationNotAllowedErrorWithMessage: + @brief Constructs an @c NSError with the @c FIRAuthErrorCodeOperationNotAllowed code. + @param message Error message from the backend, if any. + @return The NSError instance associated with the given FIRAuthError. + */ ++ (NSError *)operationNotAllowedErrorWithMessage:(nullable NSString *)message; + +/** @fn weakPasswordErrorWithServerResponseReason: + @brief Constructs an @c NSError with the @c FIRAuthErrorCodeWeakPassword code. + @param serverResponseReason A more detailed explanation string from server response. + @return The NSError instance associated with the given FIRAuthError. + */ ++ (NSError *)weakPasswordErrorWithServerResponseReason:(nullable NSString *)serverResponseReason; + +/** @fn appNotAuthorizedError + @brief Constructs an @c NSError with the @c FIRAuthErrorCodeAppNotAuthorized code. + @return The NSError instance associated with the given FIRAuthError. + */ ++ (NSError *)appNotAuthorizedError; + +/** @fn expiredActionCodeErrorWithMessage: + @brief Constructs an @c NSError with the @c FIRAuthErrorCodeExpiredActionCode code. + @param message Error message from the backend, if any. + @return The NSError instance associated with the given FIRAuthError. + */ ++ (NSError *)expiredActionCodeErrorWithMessage:(nullable NSString *)message; + +/** @fn invalidActionCodeErrorWithMessage: + @brief Constructs an @c NSError with the @c FIRAuthErrorCodeInvalidActionCode code. + @param message Error message from the backend, if any. + @return The NSError instance associated with the given FIRAuthError. + */ ++ (NSError *)invalidActionCodeErrorWithMessage:(nullable NSString *)message; + +/** @fn invalidMessagePayloadError: + @brief Constructs an @c NSError with the @c FIRAuthErrorCodeInvalidMessagePayload code. + @param message Error message from the backend, if any. + @return The NSError instance associated with the given FIRAuthError. + */ ++ (NSError *)invalidMessagePayloadErrorWithMessage:(nullable NSString *)message; + +/** @fn invalidSenderErrorWithMessage: + @brief Constructs an @c NSError with the @c FIRAuthErrorCodeInvalidSender code. + @param message Error message from the backend, if any. + @return The NSError instance associated with the given FIRAuthError. + */ ++ (NSError *)invalidSenderErrorWithMessage:(nullable NSString *)message; + +/** @fn invalidRecipientEmailError: + @brief Constructs an @c NSError with the @c FIRAuthErrorCodeInvalidRecipientEmail code. + @param message Error message from the backend, if any. + @return The NSError instance associated with the given FIRAuthError. + */ ++ (NSError *)invalidRecipientEmailErrorWithMessage:(nullable NSString *)message; + +/** @fn missingIosBundleIDErrorWithMessage: + @brief Constructs an @c NSError with the @c FIRAuthErrorCodeMissingIosBundleID code. + @param message Error message from the backend, if any. + @return The NSError instance associated with the given FIRAuthError. + */ ++ (NSError *)missingIosBundleIDErrorWithMessage:(nullable NSString *)message; + +/** @fn missingAndroidPackageNameErrorWithMessage: + @brief Constructs an @c NSError with the @c FIRAuthErrorCodeMissingAndroidPackageName code. + @param message Error message from the backend, if any. + @return The NSError instance associated with the given FIRAuthError. + */ ++ (NSError *)missingAndroidPackageNameErrorWithMessage:(nullable NSString *)message; + +/** @fn unauthorizedDomainErrorWithMessage: + @brief Constructs an @c NSError with the @c FIRAuthErrorCodeUnauthorizedDomain code. + @param message Error message from the backend, if any. + @return The NSError instance associated with the given FIRAuthError. + */ ++ (NSError *)unauthorizedDomainErrorWithMessage:(nullable NSString *)message; + +/** @fn invalidContinueURIErrorWithMessage: + @brief Constructs an @c NSError with the @c FIRAuthErrorCodeInvalidContinueURI code. + @param message Error message from the backend, if any. + @return The NSError instance associated with the given FIRAuthError. + */ ++ (NSError *)invalidContinueURIErrorWithMessage:(nullable NSString *)message; + +/** @fn missingContinueURIErrorWithMessage: + @brief Constructs an @c NSError with the @c FIRAuthErrorCodeMissingContinueURI code. + @param message Error message from the backend, if any. + @return The NSError instance associated with the given FIRAuthError. + */ ++ (NSError *)missingContinueURIErrorWithMessage:(nullable NSString *)message; + +/** @fn missingEmailErrorWithMessage + @brief Constructs an @c NSError with the @c FIRAuthErrorCodeMissingEmail code. + @param message Error message from the backend, if any. + @return The NSError instance associated with the given FIRAuthError. + */ ++ (NSError *)missingEmailErrorWithMessage:(nullable NSString *)message; + +/** @fn missingPhoneNumberErrorWithMessage: + @brief Constructs an @c NSError with the @c FIRAuthErrorCodeMissingPhoneNumber code. + @param message Error message from the backend, if any. + @return The NSError instance associated with the given FIRAuthError. + */ ++ (NSError *)missingPhoneNumberErrorWithMessage:(nullable NSString *)message; + +/** @fn invalidPhoneNumberErrorWithMessage: + @brief Constructs an @c NSError with the @c FIRAuthErrorCodeInvalidPhoneNumber code. + @param message Error message from the backend, if any. + @return The NSError instance associated with the given FIRAuthError. + */ ++ (NSError *)invalidPhoneNumberErrorWithMessage:(nullable NSString *)message; + +/** @fn missingVerificationCodeErrorWithMessage: + @brief Constructs an @c NSError with the @c FIRAuthErrorCodeMissingVerificationCode code. + @param message Error message from the backend, if any. + @return The NSError instance associated with the given FIRAuthError. + */ ++ (NSError *)missingVerificationCodeErrorWithMessage:(nullable NSString *)message; + +/** @fn invalidVerificationCodeErrorWithMessage: + @brief Constructs an @c NSError with the @c FIRAuthErrorCodeInvalidVerificationCode code. + @param message Error message from the backend, if any. + @return The NSError instance associated with the given FIRAuthError. + */ ++ (NSError *)invalidVerificationCodeErrorWithMessage:(nullable NSString *)message; + +/** @fn missingVerificationIDErrorWithMessage: + @brief Constructs an @c NSError with the @c FIRAuthErrorCodeMissingVerificationID code. + @param message Error message from the backend, if any. + @return The NSError instance associated with the given FIRAuthError. + */ ++ (NSError *)missingVerificationIDErrorWithMessage:(nullable NSString *)message; + +/** @fn invalidVerificationIDErrorWithMessage: + @brief Constructs an @c NSError with the @c FIRAuthErrorCodeInvalidVerificationID code. + @param message Error message from the backend, if any. + @return The NSError instance associated with the given FIRAuthError. + */ ++ (NSError *)invalidVerificationIDErrorWithMessage:(nullable NSString *)message; + +/** @fn sessionExpiredErrorWithMessage: + @brief Constructs an @c NSError with the @c FIRAuthErrorCodeSessionExpired code. + @param message Error message from the backend, if any. + @return The NSError instance associated with the given FIRAuthError. + */ ++ (NSError *)sessionExpiredErrorWithMessage:(nullable NSString *)message; + +/** @fn missingAppCredentialWithMessage: + @brief Constructs an @c NSError with the @c FIRAuthErrorMissingCredential code. + @param message Error message from the backend, if any. + @return The NSError instance associated with the given FIRAuthError. + */ ++ (NSError *)missingAppCredentialWithMessage:(nullable NSString *)message; + +/** @fn invalidAppCredentialWithMessage: + @brief Constructs an @c NSError with the @c FIRAuthErrorInvalidCredential code. + @param message Error message from the backend, if any. + @return The NSError instance associated with the given FIRAuthError. + */ ++ (NSError *)invalidAppCredentialWithMessage:(nullable NSString *)message; + +/** @fn quotaExceededErrorWithMessage: + @brief Constructs an @c NSError with the @c FIRAuthErrorCodeQuotaExceeded code. + @param message Error message from the backend, if any. + @return The NSError instance associated with the given FIRAuthError. + */ ++ (NSError *)quotaExceededErrorWithMessage:(nullable NSString *)message; + +/** @fn missingAppTokenErrorWithUnderlyingError + @brief Constructs an @c NSError with the @c FIRAuthErrorCodeMissingAppToken code. + @param underlyingError The underlying error, if any. + @return The NSError instance associated with the given FIRAuthError. + */ ++ (NSError *)missingAppTokenErrorWithUnderlyingError:(nullable NSError *)underlyingError; + +/** @fn localPlayerNotAuthenticatedError + @brief Constructs an @c NSError with the @c FIRAuthErrorCodeLocalPlayerNotAuthenticated code. + @return The NSError instance associated with the given FIRAuthError. + */ ++ (NSError *)localPlayerNotAuthenticatedError; + +/** @fn gameKitNotLinkedError + @brief Constructs an @c NSError with the @c FIRAuthErrorCodeGameKitNotLinked code. + @return The NSError instance associated with the given FIRAuthError. + */ ++ (NSError *)gameKitNotLinkedError; + +/** @fn notificationNotForwardedError + @brief Constructs an @c NSError with the @c FIRAuthErrorCodeNotificationNotForwarded code. + @return The NSError instance associated with the given FIRAuthError. + */ ++ (NSError *)notificationNotForwardedError; + +/** @fn appNotVerifiedErrorWithMessage: + @brief Constructs an @c NSError with the @c FIRAuthErrorCodeAppNotVerified code. + @param message Error message from the backend, if any. + @return The NSError instance associated with the given FIRAuthError. + */ ++ (NSError *)appNotVerifiedErrorWithMessage:(nullable NSString *)message; + +/** @fn captchaCheckFailedErrorWithMessage: + @brief Constructs an @c NSError with the @c FIRAuthErrorCaptchaCheckFailed code. + @param message Error message from the backend, if any. + @return The NSError instance associated with the given FIRAuthError. + */ ++ (NSError *)captchaCheckFailedErrorWithMessage:(nullable NSString *)message; + +/** @fn webContextAlreadyPresentedErrorWithMessage: + @brief Constructs an @c NSError with the @c FIRAuthErrorCodeWebContextAlreadyPresented code. + @param message Error message from the backend, if any. + @return The NSError instance associated with the given FIRAuthError. + */ ++ (NSError *)webContextAlreadyPresentedErrorWithMessage:(nullable NSString *)message; + +/** @fn webContextCancelledErrorWithMessage: + @brief Constructs an @c NSError with the @c FIRAuthErrorCodeWebContextCancelled code. + @param message Error message from the backend, if any. + @return The NSError instance associated with the given FIRAuthError. + */ ++ (NSError *)webContextCancelledErrorWithMessage:(nullable NSString *)message; + +/** @fn appVerificationUserInteractionFailureWithReason: + @brief Constructs an @c NSError with the @c + FIRAuthErrorCodeAppVerificationUserInteractionFailure code. + @param reason Reason for error, returned via URL response. + @return The NSError instance associated with the given FIRAuthError. + */ ++ (NSError *)appVerificationUserInteractionFailureWithReason:(NSString *)reason; + +/** @fn webSignInUserInteractionFailureWithReason: + @brief Constructs an @c NSError with the @c + FIRAuthErrorCodeWebSignInUserInteractionFailure code. + @param reason Reason for error, returned via URL response. + @return The NSError instance associated with the given FIRAuthError. + */ ++ (NSError *)webSignInUserInteractionFailureWithReason:(nullable NSString *)reason; + +/** @fn URLResponseErrorWithCode:message: + @brief Constructs an @c NSError with the code and message provided. + @param message Error message from the backend, if any. + @return The nullable NSError instance associated with the given error message, if one is found. + */ ++ (nullable NSError *)URLResponseErrorWithCode:(NSString *)code message:(nullable NSString *)message; + +/** @fn nullUserErrorWithMessage: + @brief Constructs an @c NSError with the code and message provided. + @param message Error message from the backend, if any. + @return The nullable NSError instance associated with the given error message, if one is found. + */ ++ (NSError *)nullUserErrorWithMessage:(nullable NSString *)message; + +/** @fn invalidProviderIDErrorWithMessage: + @brief Constructs an @c NSError with the @c FIRAuthErrorCodeInvalidProviderID code. + @param message Error message from the backend, if any. + @remarks This error indicates that the provider id given for the web operation is invalid. + */ ++ (NSError *)invalidProviderIDErrorWithMessage:(nullable NSString *)message; + +/** @fn invalidDynamicLinkDomainErrorWithMessage: + @brief Constructs an @c NSError with the code and message provided. + @param message Error message from the backend, if any. + @return The nullable NSError instance associated with the given error message, if one is found. + */ ++ (NSError *)invalidDynamicLinkDomainErrorWithMessage:(nullable NSString *)message; + +/** @fn keychainErrorWithFunction:status: + @brief Constructs an @c NSError with the @c FIRAuthErrorCodeKeychainError code. + @param keychainFunction The keychain function which was invoked and yielded an unexpected + response. The @c NSLocalizedFailureReasonErrorKey field in the @c NSError.userInfo + dictionary will contain a string partially comprised of this value. + @param status The response status from the invoked keychain function. The + @c NSLocalizedFailureReasonErrorKey field in the @c NSError.userInfo dictionary will contain + a string partially comprised of this value. + */ ++ (NSError *)keychainErrorWithFunction:(NSString *)keychainFunction status:(OSStatus)status; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthErrorUtils.m b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthErrorUtils.m new file mode 100644 index 0000000..0300e4a --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthErrorUtils.m @@ -0,0 +1,1166 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRAuthErrorUtils.h" + +#import "FIRAuthCredential.h" +#import "FIRAuthInternalErrors.h" + +NS_ASSUME_NONNULL_BEGIN + +NSString *const FIRAuthErrorDomain = @"FIRAuthErrorDomain"; + +NSString *const FIRAuthInternalErrorDomain = @"FIRAuthInternalErrorDomain"; + +NSString *const FIRAuthErrorUserInfoDeserializedResponseKey = + @"FIRAuthErrorUserInfoDeserializedResponseKey"; + +NSString *const FIRAuthErrorUserInfoDataKey = @"FIRAuthErrorUserInfoDataKey"; + +NSString *const FIRAuthErrorUserInfoEmailKey = @"FIRAuthErrorUserInfoEmailKey"; + +NSString *const FIRAuthErrorUserInfoUpdatedCredentialKey = + @"FIRAuthErrorUserInfoUpdatedCredentialKey"; + +NSString *const FIRAuthErrorUserInfoNameKey = @"FIRAuthErrorUserInfoNameKey"; + +NSString *const FIRAuthErrorNameKey = @"error_name"; + +NSString *const FIRAuthUpdatedCredentialKey = @"FIRAuthUpdatedCredentialKey"; + +/** @var kServerErrorDetailMarker + @brief This marker indicates that the server error message contains a detail error message which + should be used instead of the hardcoded client error message. + */ +static NSString *const kServerErrorDetailMarker = @" : "; + +#pragma mark - URL response error codes + +/** @var kURLResponseErrorCodeInvalidClientID + @brief Error code that indicates that the client ID provided was invalid. + */ +static NSString *const kURLResponseErrorCodeInvalidClientID = @"auth/invalid-oauth-client-id"; + +/** @var kURLResponseErrorCodeNetworkRequestFailed + @brief Error code that indicates that a network request within the SFSafariViewController or + UIWebView failed. + */ +static NSString *const kURLResponseErrorCodeNetworkRequestFailed = @"auth/network-request-failed"; + +/** @var kURLResponseErrorCodeInternalError + @brief Error code that indicates that an internal error occurred within the + SFSafariViewController or UIWebView failed. + */ +static NSString *const kURLResponseErrorCodeInternalError = @"auth/internal-error"; + +#pragma mark - Standard Error Messages + +/** @var kFIRAuthErrorMessageInvalidCustomToken + @brief Message for @c FIRAuthErrorCodeInvalidCustomToken error code. + */ +static NSString *const kFIRAuthErrorMessageInvalidCustomToken = @"The custom token format is " + "incorrect. Please check the documentation."; + +/** @var kFIRAuthErrorMessageCustomTokenMismatch + @brief Message for @c FIRAuthErrorCodeCustomTokenMismatch error code. + */ +static NSString *const kFIRAuthErrorMessageCustomTokenMismatch = @"The custom token corresponds to " + "a different audience."; + +/** @var kFIRAuthErrorMessageInvalidEmail + @brief Message for @c FIRAuthErrorCodeInvalidEmail error code. + */ +static NSString *const kFIRAuthErrorMessageInvalidEmail = @"The email address is badly formatted."; + +/** @var kFIRAuthErrorMessageInvalidCredential + @brief Message for @c FIRAuthErrorCodeInvalidCredential error code. + */ +static NSString *const kFIRAuthErrorMessageInvalidCredential = @"The supplied auth credential is " + "malformed or has expired."; + +/** @var kFIRAuthErrorMessageUserDisabled + @brief Message for @c FIRAuthErrorCodeUserDisabled error code. + */ +static NSString *const kFIRAuthErrorMessageUserDisabled = @"The user account has been disabled by " + "an administrator."; + +/** @var kFIRAuthErrorMessageEmailAlreadyInUse + @brief Message for @c FIRAuthErrorCodeEmailAlreadyInUse error code. + */ +static NSString *const kFIRAuthErrorMessageEmailAlreadyInUse = @"The email address is already in " + "use by another account."; + +/** @var kFIRAuthErrorMessageWrongPassword + @brief Message for @c FIRAuthErrorCodeWrongPassword error code. + */ +static NSString *const kFIRAuthErrorMessageWrongPassword = @"The password is invalid or the user " + "does not have a password."; + +/** @var kFIRAuthErrorMessageTooManyRequests + @brief Message for @c FIRAuthErrorCodeTooManyRequests error code. + */ +static NSString *const kFIRAuthErrorMessageTooManyRequests = @"We have blocked all requests from " + "this device due to unusual activity. Try again later."; + +/** @var kFIRAuthErrorMessageAccountExistsWithDifferentCredential + @brief Message for @c FIRAuthErrorCodeAccountExistsWithDifferentCredential error code. + */ +static NSString *const kFIRAuthErrorMessageAccountExistsWithDifferentCredential = @"An account " + "already exists with the same email address but different sign-in credentials. Sign in using a " + "provider associated with this email address."; + +/** @var kFIRAuthErrorMessageRequiresRecentLogin + @brief Message for @c FIRAuthErrorCodeRequiresRecentLogin error code. + */ +static NSString *const kFIRAuthErrorMessageRequiresRecentLogin= @"This operation is sensitive and " + "requires recent authentication. Log in again before retrying this request."; + +/** @var kFIRAuthErrorMessageProviderAlreadyLinked + @brief Message for @c FIRAuthErrorCodeProviderAlreadyExists error code. + */ +static NSString *const kFIRAuthErrorMessageProviderAlreadyLinked = + @"[ERROR_PROVIDER_ALREADY_LINKED] - User can only be linked to one identity for the given " + "provider."; + +/** @var kFIRAuthErrorMessageNoSuchProvider + @brief Message for @c FIRAuthErrorCodeNoSuchProvider error code. + */ +static NSString *const kFIRAuthErrorMessageNoSuchProvider = @"User was not linked to an account " + "with the given provider."; + +/** @var kFIRAuthErrorMessageInvalidUserToken + @brief Message for @c FIRAuthErrorCodeInvalidUserToken error code. + */ +static NSString *const kFIRAuthErrorMessageInvalidUserToken = @"This user's credential isn't valid " + "for this project. This can happen if the user's token has been tampered with, or if the user " + "doesn’t belong to the project associated with the API key used in your request."; + +/** @var kFIRAuthErrorMessageNetworkError + @brief Message for @c FIRAuthErrorCodeNetworkError error code. + */ +static NSString *const kFIRAuthErrorMessageNetworkError = @"Network error (such as timeout, " + "interrupted connection or unreachable host) has occurred."; + +/** @var kFIRAuthErrorMessageKeychainError + @brief Message for @c FIRAuthErrorCodeKeychainError error code. + */ +static NSString *const kFIRAuthErrorMessageKeychainError = @"An error occurred when accessing the " + "keychain. The @c NSLocalizedFailureReasonErrorKey field in the @c NSError.userInfo dictionary " + "will contain more information about the error encountered"; + +/** @var kFIRAuthErrorMessageUserTokenExpired + @brief Message for @c FIRAuthErrorCodeTokenExpired error code. + */ +static NSString *const kFIRAuthErrorMessageUserTokenExpired = @"The user's credential is no longer " + "valid. The user must sign in again."; + +/** @var kFIRAuthErrorMessageUserNotFound + @brief Message for @c FIRAuthErrorCodeUserNotFound error code. + */ +static NSString *const kFIRAuthErrorMessageUserNotFound = @"There is no user record corresponding " + "to this identifier. The user may have been deleted."; + +/** @var kFIRAuthErrorMessageInvalidAPIKey + @brief Message for @c FIRAuthErrorCodeInvalidAPIKey error code. + @remarks This error is not thrown by the server. + */ +static NSString *const kFIRAuthErrorMessageInvalidAPIKey = @"An invalid API Key was supplied in " + "the request."; + +/** @var kFIRAuthErrorMessageUserMismatch. + @brief Message for @c FIRAuthErrorCodeInvalidAPIKey error code. + */ +static NSString *const FIRAuthErrorMessageUserMismatch = @"The supplied credentials do not " + "correspond to the previously signed in user."; + +/** @var kFIRAuthErrorMessageCredentialAlreadyInUse + @brief Message for @c FIRAuthErrorCodeCredentialAlreadyInUse error code. + */ +static NSString *const kFIRAuthErrorMessageCredentialAlreadyInUse = @"This credential is already " + "associated with a different user account."; + +/** @var kFIRAuthErrorMessageOperationNotAllowed + @brief Message for @c FIRAuthErrorCodeOperationNotAllowed error code. + */ +static NSString *const kFIRAuthErrorMessageOperationNotAllowed = @"The given sign-in provider is " + "disabled for this Firebase project. Enable it in the Firebase console, under the sign-in " + "method tab of the Auth section."; + +/** @var kFIRAuthErrorMessageWeakPassword + @brief Message for @c FIRAuthErrorCodeWeakPassword error code. + */ +static NSString *const kFIRAuthErrorMessageWeakPassword = @"The password must be 6 characters long " + "or more."; + +/** @var kFIRAuthErrorMessageAppNotAuthorized + @brief Message for @c FIRAuthErrorCodeAppNotAuthorized error code. + */ +static NSString *const kFIRAuthErrorMessageAppNotAuthorized = @"This app is not authorized to use " + "Firebase Authentication with the provided API key. Review your key configuration in the " + "Google API console and ensure that it accepts requests from your app's bundle ID."; + +/** @var kFIRAuthErrorMessageExpiredActionCode + @brief Message for @c FIRAuthErrorCodeExpiredActionCode error code. + */ +static NSString *const kFIRAuthErrorMessageExpiredActionCode = @"The action code has expired."; + +/** @var kFIRAuthErrorMessageInvalidActionCode + @brief Message for @c FIRAuthErrorCodeInvalidActionCode error code. + */ +static NSString *const kFIRAuthErrorMessageInvalidActionCode = @"The action code is invalid. This " + "can happen if the code is malformed, expired, or has already been used."; + +/** @var kFIRAuthErrorMessageInvalidMessagePayload + @brief Message for @c FIRAuthErrorCodeInvalidMessagePayload error code. + */ +static NSString *const kFIRAuthErrorMessageInvalidMessagePayload = @"The action code is invalid. " + "This can happen if the code is malformed, expired, or has already been used."; + +/** @var kFIRAuthErrorMessageInvalidSender + @brief Message for @c FIRAuthErrorCodeInvalidSender error code. + */ +static NSString *const kFIRAuthErrorMessageInvalidSender = @"The email template corresponding to " + "this action contains invalid characters in its message. Please fix by going to the Auth email " + "templates section in the Firebase Console."; + +/** @var kFIRAuthErrorMessageInvalidRecipientEmail + @brief Message for @c FIRAuthErrorCodeInvalidRecipient error code. + */ +static NSString *const kFIRAuthErrorMessageInvalidRecipientEmail = @"The action code is invalid. " + "This can happen if the code is malformed, expired, or has already been used."; + +/** @var kFIRAuthErrorMessageMissingIosBundleID + @brief Message for @c FIRAuthErrorCodeMissingIosbundleID error code. + */ +static NSString *const kFIRAuthErrorMessageMissingIosBundleID = + @"An iOS Bundle ID must be provided if an App Store ID is provided."; + +/** @var kFIRAuthErrorMessageMissingAndroidPackageName + @brief Message for @c FIRAuthErrorCodeMissingAndroidPackageName error code. + */ +static NSString *const kFIRAuthErrorMessageMissingAndroidPackageName = + @"An Android Package Name must be provided if the Android App is required to be installed."; + +/** @var kFIRAuthErrorMessageUnauthorizedDomain + @brief Message for @c FIRAuthErrorCodeUnauthorizedDomain error code. + */ +static NSString *const kFIRAuthErrorMessageUnauthorizedDomain = @"The domain of the continue URL " + "is not whitelisted. Please whitelist the domain in the Firebase console."; + +/** @var kFIRAuthErrorMessageInvalidContinueURI + @brief Message for @c FIRAuthErrorCodeInvalidContinueURI error code. + */ +static NSString *const kFIRAuthErrorMessageInvalidContinueURI = + @"The continue URL provided in the request is invalid."; + +/** @var kFIRAuthErrorMessageMissingEmail + @brief Message for @c FIRAuthErrorCodeMissingEmail error code. + */ +static NSString *const kFIRAuthErrorMessageMissingEmail = @"An email address must be provided."; + +/** @var kFIRAuthErrorMessageMissingContinueURI + @brief Message for @c FIRAuthErrorCodeMissingContinueURI error code. + */ +static NSString *const kFIRAuthErrorMessageMissingContinueURI = + @"A continue URL must be provided in the request."; + +/** @var kFIRAuthErrorMessageMissingPhoneNumber + @brief Message for @c FIRAuthErrorCodeMissingPhoneNumber error code. + */ +static NSString *const kFIRAuthErrorMessageMissingPhoneNumber = + @"To send verification codes, provide a phone number for the recipient."; + +/** @var kFIRAuthErrorMessageInvalidPhoneNumber + @brief Message for @c FIRAuthErrorCodeInvalidPhoneNumber error code. + */ +static NSString *const kFIRAuthErrorMessageInvalidPhoneNumber = + @"The format of the phone number provided is incorrect. Please enter the phone number in a " + "format that can be parsed into E.164 format. E.164 phone numbers are written in the format " + "[+][country code][subscriber number including area code]."; + +/** @var kFIRAuthErrorMessageMissingVerificationCode + @brief Message for @c FIRAuthErrorCodeMissingVerificationCode error code. + */ +static NSString *const kFIRAuthErrorMessageMissingVerificationCode = + @"The phone auth credential was created with an empty SMS verification Code."; + +/** @var kFIRAuthErrorMessageInvalidVerificationCode + @brief Message for @c FIRAuthErrorCodeInvalidVerificationCode error code. + */ +static NSString *const kFIRAuthErrorMessageInvalidVerificationCode = + @"The SMS verification code used to create the phone auth credential is invalid. Please resend " + "the verification code SMS and be sure to use the verification code provided by the user."; + +/** @var kFIRAuthErrorMessageMissingVerificationID + @brief Message for @c FIRAuthErrorCodeInvalidVerificationID error code. + */ +static NSString *const kFIRAuthErrorMessageMissingVerificationID = + @"The phone auth credential was created with an empty verification ID."; + +/** @var kFIRAuthErrorMessageInvalidVerificationID + @brief Message for @c FIRAuthErrorCodeInvalidVerificationID error code. + */ +static NSString *const kFIRAuthErrorMessageInvalidVerificationID = + @"The verification ID used to create the phone auth credential is invalid."; + +/** @var kFIRAuthErrorMessageLocalPlayerNotAuthenticated + @brief Message for @c FIRAuthErrorCodeLocalPlayerNotAuthenticated error code. + */ +static NSString *const kFIRAuthErrorMessageLocalPlayerNotAuthenticated = + @"The local player is not authenticated. Please log the local player in to Game Center."; + +/** @var kFIRAuthErrorMessageGameKitNotLinked + @brief Message for @c kFIRAuthErrorMessageGameKitNotLinked error code. + */ +static NSString *const kFIRAuthErrorMessageGameKitNotLinked = + @"The GameKit framework is not linked. Please turn on the Game Center capability."; + +/** @var kFIRAuthErrorMessageSessionExpired + @brief Message for @c FIRAuthErrorCodeSessionExpired error code. + */ +static NSString *const kFIRAuthErrorMessageSessionExpired = @"The SMS code has expired. Please " + @"re-send the verification code to try again."; + +/** @var kFIRAuthErrorMessageMissingAppCredential + @brief Message for @c FIRAuthErrorCodeMissingAppCredential error code. + */ +static NSString *const kFIRAuthErrorMessageMissingAppCredential = @"The phone verification request " + "is missing an APNs Device token. Firebase Auth automatically detects APNs Device Tokens, " + "however, if method swizzling is disabled, the APNs token must be set via the APNSToken " + "property on FIRAuth or by calling setAPNSToken:type on FIRAuth."; + +/** @var kFIRAuthErrorMessageInvalidAppCredential + @brief Message for @c FIRAuthErrorCodeInvalidAppCredential error code. + */ +static NSString *const kFIRAuthErrorMessageInvalidAppCredential = @"The APNs device token provided " + "is either incorrect or does not match the private certificate uploaded to the Firebase " + "Console."; + +/** @var kFIRAuthErrorMessageQuotaExceeded + @brief Message for @c FIRAuthErrorCodeQuotaExceeded error code. + */ +static NSString *const kFIRAuthErrorMessageQuotaExceeded = @"The phone verification quota for this " + "project has been exceeded."; + +/** @var kFIRAuthErrorMessageMissingAppToken + @brief Message for @c FIRAuthErrorCodeMissingAppToken error code. + */ +static NSString *const kFIRAuthErrorMessageMissingAppToken = @"There seems to be a problem with " + "your project's Firebase phone number authentication set-up, please make sure to follow the " + "instructions found at https://firebase.google.com/docs/auth/ios/phone-auth"; + +/** @var kFIRAuthErrorMessageMissingAppToken + @brief Message for @c FIRAuthErrorCodeMissingAppToken error code. + */ +static NSString *const kFIRAuthErrorMessageNotificationNotForwarded = @"If app delegate swizzling " + "is disabled, remote notifications received by UIApplicationDelegate need to be forwarded to " + "FIRAuth's canHandleNotificaton: method."; + +/** @var kFIRAuthErrorMessageAppNotVerified + @brief Message for @c FIRAuthErrorCodeMissingAppToken error code. + */ +static NSString *const kFIRAuthErrorMessageAppNotVerified = @"Firebase could not retrieve the " + "silent push notification and therefore could not verify your app. Ensure that you configured " + "your app correctly to receive push notifications."; + +/** @var kFIRAuthErrorMessageCaptchaCheckFailed + @brief Message for @c FIRAuthErrorCodeCaptchaCheckFailed error code. + */ +static NSString *const kFIRAuthErrorMessageCaptchaCheckFailed = @"The reCAPTCHA response token " + "provided is either invalid, expired or already"; + +/** @var kFIRAuthErrorMessageWebContextAlreadyPresented + @brief Message for @c FIRAuthErrorCodeWebContextAlreadyPresented error code. + */ +static NSString *const kFIRAuthErrorMessageWebContextAlreadyPresented = @"User interaction is " + "still ongoing, another view cannot be presented."; + +/** @var kFIRAuthErrorMessageWebContextCancelled + @brief Message for @c FIRAuthErrorCodeWebContextCancelled error code. + */ +static NSString *const kFIRAuthErrorMessageWebContextCancelled = @"The interaction was cancelled " + "by the user."; + +/** @var kFIRAuthErrorMessageInvalidClientID + @brief Message for @c FIRAuthErrorCodeInvalidClientID error code. + */ +static NSString *const kFIRAuthErrorMessageInvalidClientID = @"The OAuth client ID provided is " + "either invalid or does not match the specified API key."; + +/** @var kFIRAuthErrorMessageWebRequestFailed + @brief Message for @c FIRAuthErrorCodeWebRequestFailed error code. + */ +static NSString *const kFIRAuthErrorMessageWebRequestFailed = @"A network error (such as timeout, " + "interrupted connection, or unreachable host) has occurred within the web context."; + +/** @var kFIRAuthErrorMessageWebInternalError + @brief Message for @c FIRAuthErrorCodeWebInternalError error code. + */ +static NSString *const kFIRAuthErrorMessageWebInternalError = @"An internal error has occurred " + "within the SFSafariViewController or UIWebView."; + +/** @var kFIRAuthErrorMessageAppVerificationUserInteractionFailure + @brief Message for @c FIRAuthErrorCodeInvalidClientID error code. + */ +static NSString *const kFIRAuthErrorMessageAppVerificationUserInteractionFailure = @"The app " + "verification process has failed, print and inspect the error details for more information"; + +/** @var kFIRAuthErrorMessageNullUser + @brief Message for @c FIRAuthErrorCodeNullUser error code. + */ +static NSString *const kFIRAuthErrorMessageNullUser = @"A null user object was provided as the " + "argument for an operation which requires a non-null user object."; + +/** @var kFIRAuthErrorMessageInvalidProviderID + @brief Message for @c FIRAuthErrorCodeInvalidProviderID error code. + */ +static NSString *const kFIRAuthErrorMessageInvalidProviderID = @"The provider ID provided for the " + "attempted web operation is invalid."; + +/** @var kFIRAuthErrorMessageInvalidDynamicLinkDomain + @brief Message for @c kFIRAuthErrorMessageInvalidDynamicLinkDomain error code. + */ +static NSString *const kFIRAuthErrorMessageInvalidDynamicLinkDomain = @"The " + "Firebase Dynamic Link domain used is either not configured or is unauthorized " + "for the current project."; + +/** @var kFIRAuthErrorMessageInternalError + @brief Message for @c FIRAuthErrorCodeInternalError error code. + */ +static NSString *const kFIRAuthErrorMessageInternalError = @"An internal error has occurred, " + "print and inspect the error details for more information."; + +/** @var kFIRAuthErrorMessageMalformedJWT + @brief Error message constant describing @c FIRAuthErrorCodeMalformedJWT errors. + */ +static NSString *const kFIRAuthErrorMessageMalformedJWT = + @"Failed to parse JWT. Check the userInfo dictionary for the full token."; + +/** @var FIRAuthErrorDescription + @brief The error descrioption, based on the error code. + @remarks No default case so that we get a compiler warning if a new value was added to the enum. + */ +static NSString *FIRAuthErrorDescription(FIRAuthErrorCode code) { + switch (code) { + case FIRAuthErrorCodeInvalidCustomToken: + return kFIRAuthErrorMessageInvalidCustomToken; + case FIRAuthErrorCodeCustomTokenMismatch: + return kFIRAuthErrorMessageCustomTokenMismatch; + case FIRAuthErrorCodeInvalidEmail: + return kFIRAuthErrorMessageInvalidEmail; + case FIRAuthErrorCodeInvalidCredential: + return kFIRAuthErrorMessageInvalidCredential; + case FIRAuthErrorCodeUserDisabled: + return kFIRAuthErrorMessageUserDisabled; + case FIRAuthErrorCodeEmailAlreadyInUse: + return kFIRAuthErrorMessageEmailAlreadyInUse; + case FIRAuthErrorCodeWrongPassword: + return kFIRAuthErrorMessageWrongPassword; + case FIRAuthErrorCodeTooManyRequests: + return kFIRAuthErrorMessageTooManyRequests; + case FIRAuthErrorCodeAccountExistsWithDifferentCredential: + return kFIRAuthErrorMessageAccountExistsWithDifferentCredential; + case FIRAuthErrorCodeRequiresRecentLogin: + return kFIRAuthErrorMessageRequiresRecentLogin; + case FIRAuthErrorCodeProviderAlreadyLinked: + return kFIRAuthErrorMessageProviderAlreadyLinked; + case FIRAuthErrorCodeNoSuchProvider: + return kFIRAuthErrorMessageNoSuchProvider; + case FIRAuthErrorCodeInvalidUserToken: + return kFIRAuthErrorMessageInvalidUserToken; + case FIRAuthErrorCodeNetworkError: + return kFIRAuthErrorMessageNetworkError; + case FIRAuthErrorCodeKeychainError: + return kFIRAuthErrorMessageKeychainError; + case FIRAuthErrorCodeUserTokenExpired: + return kFIRAuthErrorMessageUserTokenExpired; + case FIRAuthErrorCodeUserNotFound: + return kFIRAuthErrorMessageUserNotFound; + case FIRAuthErrorCodeInvalidAPIKey: + return kFIRAuthErrorMessageInvalidAPIKey; + case FIRAuthErrorCodeCredentialAlreadyInUse: + return kFIRAuthErrorMessageCredentialAlreadyInUse; + case FIRAuthErrorCodeInternalError: + return kFIRAuthErrorMessageInternalError; + case FIRAuthErrorCodeUserMismatch: + return FIRAuthErrorMessageUserMismatch; + case FIRAuthErrorCodeOperationNotAllowed: + return kFIRAuthErrorMessageOperationNotAllowed; + case FIRAuthErrorCodeWeakPassword: + return kFIRAuthErrorMessageWeakPassword; + case FIRAuthErrorCodeAppNotAuthorized: + return kFIRAuthErrorMessageAppNotAuthorized; + case FIRAuthErrorCodeExpiredActionCode: + return kFIRAuthErrorMessageExpiredActionCode; + case FIRAuthErrorCodeInvalidActionCode: + return kFIRAuthErrorMessageInvalidActionCode; + case FIRAuthErrorCodeInvalidSender: + return kFIRAuthErrorMessageInvalidSender; + case FIRAuthErrorCodeInvalidMessagePayload: + return kFIRAuthErrorMessageInvalidMessagePayload; + case FIRAuthErrorCodeInvalidRecipientEmail: + return kFIRAuthErrorMessageInvalidRecipientEmail; + case FIRAuthErrorCodeMissingIosBundleID: + return kFIRAuthErrorMessageMissingIosBundleID; + case FIRAuthErrorCodeMissingAndroidPackageName: + return kFIRAuthErrorMessageMissingAndroidPackageName; + case FIRAuthErrorCodeUnauthorizedDomain: + return kFIRAuthErrorMessageUnauthorizedDomain; + case FIRAuthErrorCodeInvalidContinueURI: + return kFIRAuthErrorMessageInvalidContinueURI; + case FIRAuthErrorCodeMissingContinueURI: + return kFIRAuthErrorMessageMissingContinueURI; + case FIRAuthErrorCodeMissingEmail: + return kFIRAuthErrorMessageMissingEmail; + case FIRAuthErrorCodeMissingPhoneNumber: + return kFIRAuthErrorMessageMissingPhoneNumber; + case FIRAuthErrorCodeInvalidPhoneNumber: + return kFIRAuthErrorMessageInvalidPhoneNumber; + case FIRAuthErrorCodeMissingVerificationCode: + return kFIRAuthErrorMessageMissingVerificationCode; + case FIRAuthErrorCodeInvalidVerificationCode: + return kFIRAuthErrorMessageInvalidVerificationCode; + case FIRAuthErrorCodeMissingVerificationID: + return kFIRAuthErrorMessageMissingVerificationID; + case FIRAuthErrorCodeInvalidVerificationID: + return kFIRAuthErrorMessageInvalidVerificationID; + case FIRAuthErrorCodeSessionExpired: + return kFIRAuthErrorMessageSessionExpired; + case FIRAuthErrorCodeMissingAppCredential: + return kFIRAuthErrorMessageMissingAppCredential; + case FIRAuthErrorCodeInvalidAppCredential: + return kFIRAuthErrorMessageInvalidAppCredential; + case FIRAuthErrorCodeQuotaExceeded: + return kFIRAuthErrorMessageQuotaExceeded; + case FIRAuthErrorCodeMissingAppToken: + return kFIRAuthErrorMessageMissingAppToken; + case FIRAuthErrorCodeNotificationNotForwarded: + return kFIRAuthErrorMessageNotificationNotForwarded; + case FIRAuthErrorCodeAppNotVerified: + return kFIRAuthErrorMessageAppNotVerified; + case FIRAuthErrorCodeCaptchaCheckFailed: + return kFIRAuthErrorMessageCaptchaCheckFailed; + case FIRAuthErrorCodeWebContextAlreadyPresented: + return kFIRAuthErrorMessageWebContextAlreadyPresented; + case FIRAuthErrorCodeWebContextCancelled: + return kFIRAuthErrorMessageWebContextCancelled; + case FIRAuthErrorCodeInvalidClientID: + return kFIRAuthErrorMessageInvalidClientID; + case FIRAuthErrorCodeAppVerificationUserInteractionFailure: + return kFIRAuthErrorMessageAppVerificationUserInteractionFailure; + case FIRAuthErrorCodeWebNetworkRequestFailed: + return kFIRAuthErrorMessageWebRequestFailed; + case FIRAuthErrorCodeNullUser: + return kFIRAuthErrorMessageNullUser; + case FIRAuthErrorCodeInvalidProviderID: + return kFIRAuthErrorMessageInvalidProviderID; + case FIRAuthErrorCodeInvalidDynamicLinkDomain: + return kFIRAuthErrorMessageInvalidDynamicLinkDomain; + case FIRAuthErrorCodeWebInternalError: + return kFIRAuthErrorMessageWebInternalError; + case FIRAuthErrorCodeWebSignInUserInteractionFailure: + return kFIRAuthErrorMessageAppVerificationUserInteractionFailure; + case FIRAuthErrorCodeMalformedJWT: + return kFIRAuthErrorMessageMalformedJWT; + case FIRAuthErrorCodeLocalPlayerNotAuthenticated: + return kFIRAuthErrorMessageLocalPlayerNotAuthenticated; + case FIRAuthErrorCodeGameKitNotLinked: + return kFIRAuthErrorMessageGameKitNotLinked; + } +} + +/** @var FIRAuthErrorCodeString + @brief The the error short string, based on the error code. + @remarks No default case so that we get a compiler warning if a new value was added to the enum. + */ +static NSString *const FIRAuthErrorCodeString(FIRAuthErrorCode code) { + switch (code) { + case FIRAuthErrorCodeInvalidCustomToken: + return @"ERROR_INVALID_CUSTOM_TOKEN"; + case FIRAuthErrorCodeCustomTokenMismatch: + return @"ERROR_CUSTOM_TOKEN_MISMATCH"; + case FIRAuthErrorCodeInvalidEmail: + return @"ERROR_INVALID_EMAIL"; + case FIRAuthErrorCodeInvalidCredential: + return @"ERROR_INVALID_CREDENTIAL"; + case FIRAuthErrorCodeUserDisabled: + return @"ERROR_USER_DISABLED"; + case FIRAuthErrorCodeEmailAlreadyInUse: + return @"ERROR_EMAIL_ALREADY_IN_USE"; + case FIRAuthErrorCodeWrongPassword: + return @"ERROR_WRONG_PASSWORD"; + case FIRAuthErrorCodeTooManyRequests: + return @"ERROR_TOO_MANY_REQUESTS"; + case FIRAuthErrorCodeAccountExistsWithDifferentCredential: + return @"ERROR_ACCOUNT_EXISTS_WITH_DIFFERENT_CREDENTIAL"; + case FIRAuthErrorCodeRequiresRecentLogin: + return @"ERROR_REQUIRES_RECENT_LOGIN"; + case FIRAuthErrorCodeProviderAlreadyLinked: + return @"ERROR_PROVIDER_ALREADY_LINKED"; + case FIRAuthErrorCodeNoSuchProvider: + return @"ERROR_NO_SUCH_PROVIDER"; + case FIRAuthErrorCodeInvalidUserToken: + return @"ERROR_INVALID_USER_TOKEN"; + case FIRAuthErrorCodeNetworkError: + return @"ERROR_NETWORK_REQUEST_FAILED"; + case FIRAuthErrorCodeKeychainError: + return @"ERROR_KEYCHAIN_ERROR"; + case FIRAuthErrorCodeUserTokenExpired: + return @"ERROR_USER_TOKEN_EXPIRED"; + case FIRAuthErrorCodeUserNotFound: + return @"ERROR_USER_NOT_FOUND"; + case FIRAuthErrorCodeInvalidAPIKey: + return @"ERROR_INVALID_API_KEY"; + case FIRAuthErrorCodeCredentialAlreadyInUse: + return @"ERROR_CREDENTIAL_ALREADY_IN_USE"; + case FIRAuthErrorCodeInternalError: + return @"ERROR_INTERNAL_ERROR"; + case FIRAuthErrorCodeUserMismatch: + return @"ERROR_USER_MISMATCH"; + case FIRAuthErrorCodeOperationNotAllowed: + return @"ERROR_OPERATION_NOT_ALLOWED"; + case FIRAuthErrorCodeWeakPassword: + return @"ERROR_WEAK_PASSWORD"; + case FIRAuthErrorCodeAppNotAuthorized: + return @"ERROR_APP_NOT_AUTHORIZED"; + case FIRAuthErrorCodeExpiredActionCode: + return @"ERROR_EXPIRED_ACTION_CODE"; + case FIRAuthErrorCodeInvalidActionCode: + return @"ERROR_INVALID_ACTION_CODE"; + case FIRAuthErrorCodeInvalidMessagePayload: + return @"ERROR_INVALID_MESSAGE_PAYLOAD"; + case FIRAuthErrorCodeInvalidSender: + return @"ERROR_INVALID_SENDER"; + case FIRAuthErrorCodeInvalidRecipientEmail: + return @"ERROR_INVALID_RECIPIENT_EMAIL"; + case FIRAuthErrorCodeMissingIosBundleID: + return @"ERROR_MISSING_IOS_BUNDLE_ID"; + case FIRAuthErrorCodeMissingAndroidPackageName: + return @"ERROR_MISSING_ANDROID_PKG_NAME"; + case FIRAuthErrorCodeUnauthorizedDomain: + return @"ERROR_UNAUTHORIZED_DOMAIN"; + case FIRAuthErrorCodeInvalidContinueURI: + return @"ERROR_INVALID_CONTINUE_URI"; + case FIRAuthErrorCodeMissingContinueURI: + return @"ERROR_MISSING_CONTINUE_URI"; + case FIRAuthErrorCodeMissingEmail: + return @"ERROR_MISSING_EMAIL"; + case FIRAuthErrorCodeMissingPhoneNumber: + return @"ERROR_MISSING_PHONE_NUMBER"; + case FIRAuthErrorCodeInvalidPhoneNumber: + return @"ERROR_INVALID_PHONE_NUMBER"; + case FIRAuthErrorCodeMissingVerificationCode: + return @"ERROR_MISSING_VERIFICATION_CODE"; + case FIRAuthErrorCodeInvalidVerificationCode: + return @"ERROR_INVALID_VERIFICATION_CODE"; + case FIRAuthErrorCodeMissingVerificationID: + return @"ERROR_MISSING_VERIFICATION_ID"; + case FIRAuthErrorCodeInvalidVerificationID: + return @"ERROR_INVALID_VERIFICATION_ID"; + case FIRAuthErrorCodeSessionExpired: + return @"ERROR_SESSION_EXPIRED"; + case FIRAuthErrorCodeMissingAppCredential: + return @"MISSING_APP_CREDENTIAL"; + case FIRAuthErrorCodeInvalidAppCredential: + return @"INVALID_APP_CREDENTIAL"; + case FIRAuthErrorCodeQuotaExceeded: + return @"ERROR_QUOTA_EXCEEDED"; + case FIRAuthErrorCodeMissingAppToken: + return @"ERROR_MISSING_APP_TOKEN"; + case FIRAuthErrorCodeNotificationNotForwarded: + return @"ERROR_NOTIFICATION_NOT_FORWARDED"; + case FIRAuthErrorCodeAppNotVerified: + return @"ERROR_APP_NOT_VERIFIED"; + case FIRAuthErrorCodeCaptchaCheckFailed: + return @"ERROR_CAPTCHA_CHECK_FAILED"; + case FIRAuthErrorCodeWebContextAlreadyPresented: + return @"ERROR_WEB_CONTEXT_ALREADY_PRESENTED"; + case FIRAuthErrorCodeWebContextCancelled: + return @"ERROR_WEB_CONTEXT_CANCELLED"; + case FIRAuthErrorCodeInvalidClientID: + return @"ERROR_INVALID_CLIENT_ID"; + case FIRAuthErrorCodeAppVerificationUserInteractionFailure: + return @"ERROR_APP_VERIFICATION_FAILED"; + case FIRAuthErrorCodeWebNetworkRequestFailed: + return @"ERROR_WEB_NETWORK_REQUEST_FAILED"; + case FIRAuthErrorCodeNullUser: + return @"ERROR_NULL_USER"; + case FIRAuthErrorCodeInvalidProviderID: + return @"ERROR_INVALID_PROVIDER_ID"; + case FIRAuthErrorCodeInvalidDynamicLinkDomain: + return @"ERROR_INVALID_DYNAMIC_LINK_DOMAIN"; + case FIRAuthErrorCodeWebInternalError: + return @"ERROR_WEB_INTERNAL_ERROR"; + case FIRAuthErrorCodeWebSignInUserInteractionFailure: + return @"ERROR_WEB_USER_INTERACTION_FAILURE"; + case FIRAuthErrorCodeMalformedJWT: + return @"ERROR_MALFORMED_JWT"; + case FIRAuthErrorCodeLocalPlayerNotAuthenticated: + return @"ERROR_LOCAL_PLAYER_NOT_AUTHENTICATED"; + case FIRAuthErrorCodeGameKitNotLinked: + return @"ERROR_GAME_KIT_NOT_LINKED"; + } +} + +@implementation FIRAuthErrorUtils + ++ (NSError *)errorWithCode:(FIRAuthInternalErrorCode)code { + return [self errorWithCode:code message:nil]; +} + ++ (NSError *)errorWithCode:(FIRAuthInternalErrorCode)code + message:(nullable NSString *)message { + NSDictionary *userInfo = nil; + if (message.length) { + userInfo = @{ + NSLocalizedDescriptionKey : message + }; + } + return [self errorWithCode:code userInfo:userInfo]; +} + ++ (NSError *)errorWithCode:(FIRAuthInternalErrorCode)code + underlyingError:(nullable NSError *)underlyingError { + NSDictionary *errorUserInfo; + if (underlyingError) { + errorUserInfo = @{ + NSUnderlyingErrorKey : underlyingError + }; + } + return [self errorWithCode:code userInfo:errorUserInfo]; +} + ++ (NSError *)errorWithCode:(FIRAuthInternalErrorCode)code + userInfo:(nullable NSDictionary *)userInfo { + BOOL isPublic = (code & FIRAuthPublicErrorCodeFlag) == FIRAuthPublicErrorCodeFlag; + if (isPublic) { + // This is a public error. Return it as a public error and add a description. + NSInteger errorCode = code & ~FIRAuthPublicErrorCodeFlag; + NSMutableDictionary *errorUserInfo = [NSMutableDictionary dictionaryWithDictionary:userInfo]; + if (!errorUserInfo[NSLocalizedDescriptionKey]) { + errorUserInfo[NSLocalizedDescriptionKey] = FIRAuthErrorDescription(errorCode); + } +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + // TODO(wangyue): Remove the deprecated code on next breaking change. + errorUserInfo[FIRAuthErrorNameKey] = FIRAuthErrorCodeString(errorCode); +#pragma clang diagnostic pop + errorUserInfo[FIRAuthErrorUserInfoNameKey] = FIRAuthErrorCodeString(errorCode); + return [NSError errorWithDomain:FIRAuthErrorDomain code:errorCode userInfo:errorUserInfo]; + } else { + // This is an internal error. Wrap it in an internal error. + NSError *error = + [NSError errorWithDomain:FIRAuthInternalErrorDomain code:code userInfo:userInfo]; + return [self errorWithCode:FIRAuthInternalErrorCodeInternalError underlyingError:error]; + } +} + ++ (NSError *)RPCRequestEncodingErrorWithUnderlyingError:(NSError *)underlyingError { + return [self errorWithCode:FIRAuthInternalErrorCodeRPCRequestEncodingError + underlyingError:underlyingError]; +} + ++ (NSError *)JSONSerializationErrorForUnencodableType { + return [self errorWithCode:FIRAuthInternalErrorCodeJSONSerializationError]; +} + ++ (NSError *)JSONSerializationErrorWithUnderlyingError:(NSError *)underlyingError { + return [self errorWithCode:FIRAuthInternalErrorCodeJSONSerializationError + underlyingError:underlyingError]; +} + ++ (NSError *)networkErrorWithUnderlyingError:(NSError *)underlyingError { + return [self errorWithCode:FIRAuthInternalErrorCodeNetworkError + underlyingError:underlyingError]; +} + ++ (NSError *)unexpectedErrorResponseWithData:(NSData *)data + underlyingError:(NSError *)underlyingError { + NSMutableDictionary *userInfo = [NSMutableDictionary dictionary]; + if (data) { + userInfo[FIRAuthErrorUserInfoDataKey] = data; + } + if (underlyingError) { + userInfo[NSUnderlyingErrorKey] = underlyingError; + } + return [self errorWithCode:FIRAuthInternalErrorCodeUnexpectedErrorResponse + userInfo:[userInfo copy]]; +} + ++ (NSError *)unexpectedErrorResponseWithDeserializedResponse:(id)deserializedResponse { + NSDictionary *userInfo; + if (deserializedResponse) { + userInfo = @{ + FIRAuthErrorUserInfoDeserializedResponseKey : deserializedResponse, + }; + } + return [self errorWithCode:FIRAuthInternalErrorCodeUnexpectedErrorResponse userInfo:userInfo]; +} + ++ (NSError *)malformedJWTErrorWithToken:(NSString *)token + underlyingError:(NSError *_Nullable)underlyingError { + NSMutableDictionary *userInfo = + [NSMutableDictionary dictionaryWithObject:kFIRAuthErrorMessageMalformedJWT + forKey:NSLocalizedDescriptionKey]; + [userInfo setObject:token forKey:FIRAuthErrorUserInfoDataKey]; + if (underlyingError != nil) { + [userInfo setObject:underlyingError forKey:NSUnderlyingErrorKey]; + } + return [self errorWithCode:FIRAuthInternalErrorCodeMalformedJWT userInfo:[userInfo copy]]; +} + ++ (NSError *)unexpectedResponseWithData:(NSData *)data + underlyingError:(NSError *)underlyingError { + NSMutableDictionary *userInfo = [NSMutableDictionary dictionary]; + if (data) { + userInfo[FIRAuthErrorUserInfoDataKey] = data; + } + if (underlyingError) { + userInfo[NSUnderlyingErrorKey] = underlyingError; + } + return [self errorWithCode:FIRAuthInternalErrorCodeUnexpectedResponse userInfo:[userInfo copy]]; +} + ++ (NSError *)unexpectedResponseWithDeserializedResponse:(id)deserializedResponse { + NSDictionary *userInfo; + if (deserializedResponse) { + userInfo = @{ + FIRAuthErrorUserInfoDeserializedResponseKey : deserializedResponse, + }; + } + return [self errorWithCode:FIRAuthInternalErrorCodeUnexpectedResponse userInfo:userInfo]; +} + ++ (NSError *)unexpectedResponseWithDeserializedResponse:(nullable id)deserializedResponse + underlyingError:(NSError *)underlyingError { + NSMutableDictionary *userInfo = [NSMutableDictionary dictionary]; + if (deserializedResponse) { + userInfo[FIRAuthErrorUserInfoDeserializedResponseKey] = deserializedResponse; + } + if (underlyingError) { + userInfo[NSUnderlyingErrorKey] = underlyingError; + } + return [self errorWithCode:FIRAuthInternalErrorCodeUnexpectedResponse userInfo:[userInfo copy]]; +} + ++ (NSError *)RPCResponseDecodingErrorWithDeserializedResponse:(id)deserializedResponse + underlyingError:(NSError *)underlyingError { + NSMutableDictionary *userInfo = [NSMutableDictionary dictionary]; + if (deserializedResponse) { + userInfo[FIRAuthErrorUserInfoDeserializedResponseKey] = deserializedResponse; + } + if (underlyingError) { + userInfo[NSUnderlyingErrorKey] = underlyingError; + } + return [self errorWithCode:FIRAuthInternalErrorCodeRPCResponseDecodingError + userInfo:[userInfo copy]]; +} + ++ (NSError *)emailAlreadyInUseErrorWithEmail:(nullable NSString *)email { + NSDictionary *userInfo; + if (email.length) { + userInfo = @{ + FIRAuthErrorUserInfoEmailKey : email, + }; + } + return [self errorWithCode:FIRAuthInternalErrorCodeEmailAlreadyInUse userInfo:userInfo]; +} + ++ (NSError *)userDisabledErrorWithMessage:(nullable NSString *)message { + return [self errorWithCode:FIRAuthInternalErrorCodeUserDisabled message:message]; +} + ++ (NSError *)wrongPasswordErrorWithMessage:(nullable NSString *)message { + return [self errorWithCode:FIRAuthInternalErrorCodeWrongPassword message:message]; +} + ++ (NSError *)tooManyRequestsErrorWithMessage:(nullable NSString *)message { + return [self errorWithCode:FIRAuthInternalErrorCodeTooManyRequests message:message]; +} + ++ (NSError *)invalidCustomTokenErrorWithMessage:(nullable NSString *)message { + return [self errorWithCode:FIRAuthInternalErrorCodeInvalidCustomToken message:message]; +} + ++ (NSError *)customTokenMistmatchErrorWithMessage:(nullable NSString *)message { + return [self errorWithCode:FIRAuthInternalErrorCodeCustomTokenMismatch message:message]; +} + ++ (NSError *)invalidCredentialErrorWithMessage:(nullable NSString *)message { + return [self errorWithCode:FIRAuthInternalErrorCodeInvalidCredential message:message]; +} + ++ (NSError *)requiresRecentLoginErrorWithMessage:(nullable NSString *)message { + return [self errorWithCode:FIRAuthInternalErrorCodeRequiresRecentLogin message:message]; +} + ++ (NSError *)invalidUserTokenErrorWithMessage:(nullable NSString *)message { + return [self errorWithCode:FIRAuthInternalErrorCodeInvalidUserToken message:message]; +} + ++ (NSError *)invalidEmailErrorWithMessage:(nullable NSString *)message { + return [self errorWithCode:FIRAuthInternalErrorCodeInvalidEmail message:message]; +} + ++ (NSError *)accountExistsWithDifferentCredentialErrorWithEmail:(nullable NSString *)email { + NSDictionary *userInfo; + if (email.length) { + userInfo = @{ + FIRAuthErrorUserInfoEmailKey : email, + }; + } + return [self errorWithCode:FIRAuthInternalErrorCodeAccountExistsWithDifferentCredential + userInfo:userInfo]; +} + ++ (NSError *)providerAlreadyLinkedError { + return [self errorWithCode:FIRAuthInternalErrorCodeProviderAlreadyLinked]; +} + ++ (NSError *)noSuchProviderError { + return [self errorWithCode:FIRAuthInternalErrorCodeNoSuchProvider]; +} + ++ (NSError *)userTokenExpiredErrorWithMessage:(nullable NSString *)message { + return [self errorWithCode:FIRAuthInternalErrorCodeUserTokenExpired message:message]; +} + ++ (NSError *)userNotFoundErrorWithMessage:(nullable NSString *)message { + return [self errorWithCode:FIRAuthInternalErrorCodeUserNotFound message:message]; +} + ++ (NSError *)invalidAPIKeyError { + return [self errorWithCode:FIRAuthInternalErrorCodeInvalidAPIKey]; +} + ++ (NSError *)userMismatchError { + return [self errorWithCode:FIRAuthInternalErrorCodeUserMismatch]; +} + ++ (NSError *)credentialAlreadyInUseErrorWithMessage:(nullable NSString *)message + credential:(nullable FIRAuthCredential *)credential + email:(nullable NSString *)email { + NSMutableDictionary *userInfo = [NSMutableDictionary dictionary]; + if (credential) { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + // TODO(wangyue): Remove the deprecated code on next breaking change. + userInfo[FIRAuthUpdatedCredentialKey] = credential; +#pragma clang diagnostic pop + userInfo[FIRAuthErrorUserInfoUpdatedCredentialKey] = credential; + } + if (email.length) { + userInfo[FIRAuthErrorUserInfoEmailKey] = email; + } + if (userInfo.count) { + return [self errorWithCode:FIRAuthInternalErrorCodeCredentialAlreadyInUse + userInfo:userInfo]; + } + return [self errorWithCode:FIRAuthInternalErrorCodeCredentialAlreadyInUse message:message]; +} + ++ (NSError *)operationNotAllowedErrorWithMessage:(nullable NSString *)message { + return [self errorWithCode:FIRAuthInternalErrorCodeOperationNotAllowed message:message]; +} + ++ (NSError *)weakPasswordErrorWithServerResponseReason:(nullable NSString *)reason { + NSDictionary *userInfo; + if (reason.length) { + userInfo = @{ + NSLocalizedFailureReasonErrorKey : reason, + }; + } + return [self errorWithCode:FIRAuthInternalErrorCodeWeakPassword userInfo:userInfo]; +} + ++ (NSError *)appNotAuthorizedError { + return [self errorWithCode:FIRAuthInternalErrorCodeAppNotAuthorized]; +} + ++ (NSError *)expiredActionCodeErrorWithMessage:(nullable NSString *)message { + return [self errorWithCode:FIRAuthInternalErrorCodeExpiredActionCode message:message]; +} + ++ (NSError *)invalidActionCodeErrorWithMessage:(nullable NSString *)message { + return [self errorWithCode:FIRAuthInternalErrorCodeInvalidActionCode message:message]; +} + ++ (NSError *)invalidMessagePayloadErrorWithMessage:(nullable NSString *)message { + return [self errorWithCode:FIRAuthInternalErrorCodeInvalidMessagePayload message:message]; +} + ++ (NSError *)invalidSenderErrorWithMessage:(nullable NSString *)message { + return [self errorWithCode:FIRAuthInternalErrorCodeInvalidSender message:message]; +} + ++ (NSError *)invalidRecipientEmailErrorWithMessage:(nullable NSString *)message { + return [self errorWithCode:FIRAuthInternalErrorCodeInvalidRecipientEmail message:message]; +} + ++ (NSError *)missingIosBundleIDErrorWithMessage:(nullable NSString *)message { + return [self errorWithCode:FIRAuthinternalErrorCodeMissingIosBundleID message:message]; +} + ++ (NSError *)missingAndroidPackageNameErrorWithMessage:(nullable NSString *)message { + return [self errorWithCode:FIRAuthInternalErrorCodeMissingAndroidPackageName message:message]; +} + ++ (NSError *)unauthorizedDomainErrorWithMessage:(nullable NSString *)message { + return [self errorWithCode:FIRAuthInternalErrorCodeUnauthorizedDomain message:message]; +} + ++ (NSError *)invalidContinueURIErrorWithMessage:(nullable NSString *)message { + return [self errorWithCode:FIRAuthInternalErrorCodeInvalidContinueURI message:message]; +} + ++ (NSError *)missingContinueURIErrorWithMessage:(nullable NSString *)message { + return[self errorWithCode:FIRAuthInternalErrorCodeMissingContinueURI message:message]; +} + ++ (NSError *)missingEmailErrorWithMessage:(nullable NSString *)message { + return [self errorWithCode:FIRAuthInternalErrorCodeMissingEmail message:message]; +} + ++ (NSError *)missingPhoneNumberErrorWithMessage:(nullable NSString *)message { + return [self errorWithCode:FIRAuthInternalErrorCodeMissingPhoneNumber message:message]; +} + ++ (NSError *)invalidPhoneNumberErrorWithMessage:(nullable NSString *)message { + return [self errorWithCode:FIRAuthInternalErrorCodeInvalidPhoneNumber message:message]; +} + ++ (NSError *)missingVerificationCodeErrorWithMessage:(nullable NSString *)message { + return [self errorWithCode:FIRAuthInternalErrorCodeMissingVerificationCode message:message]; +} + ++ (NSError *)invalidVerificationCodeErrorWithMessage:(nullable NSString *)message { + return [self errorWithCode:FIRAuthInternalErrorCodeInvalidVerificationCode message:message]; +} + ++ (NSError *)missingVerificationIDErrorWithMessage:(nullable NSString *)message { + return [self errorWithCode:FIRAuthInternalErrorCodeMissingVerificationID message:message]; +} + ++ (NSError *)invalidVerificationIDErrorWithMessage:(nullable NSString *)message { + return [self errorWithCode:FIRAuthInternalErrorCodeInvalidVerificationID message:message]; +} + ++ (NSError *)sessionExpiredErrorWithMessage:(nullable NSString *)message { + return [self errorWithCode:FIRAuthInternalErrorCodeSessionExpired message:message]; +} + ++ (NSError *)missingAppCredentialWithMessage:(nullable NSString *)message { + return [self errorWithCode:FIRAuthInternalErrorCodeMissingAppCredential message:message]; +} + ++ (NSError *)invalidAppCredentialWithMessage:(nullable NSString *)message { + return [self errorWithCode:FIRAuthInternalErrorCodeInvalidAppCredential message:message]; +} + ++ (NSError *)quotaExceededErrorWithMessage:(nullable NSString *)message { + return [self errorWithCode:FIRAuthInternalErrorCodeQuotaExceeded message:message]; +} + ++ (NSError *)missingAppTokenErrorWithUnderlyingError:(nullable NSError *)underlyingError { + return [self errorWithCode:FIRAuthInternalErrorCodeMissingAppToken + underlyingError:underlyingError]; +} + ++ (NSError *)localPlayerNotAuthenticatedError { + return [self errorWithCode:FIRAuthInternalErrorCodeLocalPlayerNotAuthenticated]; +} + ++ (NSError *)gameKitNotLinkedError { + return [self errorWithCode:FIRAuthInternalErrorCodeGameKitNotLinked]; +} + ++ (NSError *)notificationNotForwardedError { + return [self errorWithCode:FIRAuthInternalErrorCodeNotificationNotForwarded]; +} + ++ (NSError *)appNotVerifiedErrorWithMessage:(nullable NSString *)message { + return [self errorWithCode:FIRAuthInternalErrorCodeAppNotVerified message:message]; +} + ++ (NSError *)captchaCheckFailedErrorWithMessage:(nullable NSString *)message { + return [self errorWithCode:FIRAuthInternalErrorCodeCaptchaCheckFailed message:message]; +} + ++ (NSError *)webContextAlreadyPresentedErrorWithMessage:(nullable NSString *)message { + return [self errorWithCode:FIRAuthInternalErrorCodeWebContextAlreadyPresented message:message]; +} + ++ (NSError *)webContextCancelledErrorWithMessage:(nullable NSString *)message { + return [self errorWithCode:FIRAuthInternalErrorCodeWebContextCancelled message:message]; +} + ++ (NSError *)appVerificationUserInteractionFailureWithReason:(NSString *)reason { + NSDictionary *userInfo; + if (reason.length) { + userInfo = @{ + NSLocalizedFailureReasonErrorKey : reason, + }; + } + return [self errorWithCode:FIRAuthInternalErrorCodeAppVerificationUserInteractionFailure + userInfo:userInfo]; +} + ++ (NSError *)webSignInUserInteractionFailureWithReason:(nullable NSString *)reason { + NSDictionary *userInfo; + if (reason.length) { + userInfo = @{ + NSLocalizedFailureReasonErrorKey : reason, + }; + } + return [self errorWithCode:FIRAuthInternalErrorCodeWebSignInUserInteractionFailure + userInfo:userInfo]; +} + ++ (nullable NSError *)URLResponseErrorWithCode:(NSString *)code message:(nullable NSString *)message { + if ([code isEqualToString:kURLResponseErrorCodeInvalidClientID]) { + return [self errorWithCode:FIRAuthInternalErrorCodeInvalidClientID message:message]; + } + if ([code isEqualToString:kURLResponseErrorCodeNetworkRequestFailed]) { + return [self errorWithCode:FIRAuthInternalErrorCodeWebNetworkRequestFailed message:message]; + } + if ([code isEqualToString:kURLResponseErrorCodeInternalError]) { + return [self errorWithCode:FIRAuthInternalErrorCodeWebInternalError message:message]; + } + return nil; +} + ++ (NSError *)nullUserErrorWithMessage:(nullable NSString *)message { + return [self errorWithCode:FIRAuthInternalErrorCodeNullUser message:message]; +} + ++ (NSError *)invalidProviderIDErrorWithMessage:(nullable NSString *)message { + return [self errorWithCode:FIRAuthInternalErrorCodeInvalidProviderID message:message]; +} + ++ (NSError *)invalidDynamicLinkDomainErrorWithMessage:(nullable NSString *)message { + return [self errorWithCode:FIRAuthInternalErrorCodeInvalidDynamicLinkDomain message:message]; +} + ++ (NSError *)keychainErrorWithFunction:(NSString *)keychainFunction status:(OSStatus)status { + NSString *failureReason = [NSString stringWithFormat:@"%@ (%li)", keychainFunction, (long)status]; + return [self errorWithCode:FIRAuthInternalErrorCodeKeychainError userInfo:@{ + NSLocalizedFailureReasonErrorKey : failureReason, + }]; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthExceptionUtils.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthExceptionUtils.h new file mode 100644 index 0000000..3ae9159 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthExceptionUtils.h @@ -0,0 +1,41 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** @class FIRAuthExceptionUtils + @brief Utility class used to raise standardized Auth related exceptions. +*/ +@interface FIRAuthExceptionUtils : NSObject + +/** @fn raiseInvalidParameterExceptionWithReason: + @brief raises the "invalid parameter" exception + @param reason string will contain a description of the error. + */ ++ (void)raiseInvalidParameterExceptionWithReason:(nullable NSString *)reason; + +/** @fn raiseMethodNotImplementedExceptionWithReason: + @brief raises the "method not implemented" exception + @param reason string will contain a description of the error. + @see FIRMethodNotImplementedException + */ ++ (void)raiseMethodNotImplementedExceptionWithReason:(nullable NSString *)reason; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthExceptionUtils.m b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthExceptionUtils.m new file mode 100644 index 0000000..3da858f --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthExceptionUtils.m @@ -0,0 +1,40 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRAuthExceptionUtils.h" + +NS_ASSUME_NONNULL_BEGIN + +/** @var FIRMethodNotImplementedException + @brief The name of the "Method Not Implemented" exception. + */ +static NSString *const FIRMethodNotImplementedException = @"FIRMethodNotImplementedException"; + +@implementation FIRAuthExceptionUtils + ++ (void)raiseInvalidParameterExceptionWithReason:(nullable NSString *)reason { + [NSException raise:NSInvalidArgumentException format:@"%@", reason]; +} + ++ (void)raiseMethodNotImplementedExceptionWithReason:(nullable NSString *)reason { + NSException *exception = + [NSException exceptionWithName:FIRMethodNotImplementedException reason:reason userInfo:nil]; + [exception raise]; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthGlobalWorkQueue.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthGlobalWorkQueue.h new file mode 100644 index 0000000..55bb1a7 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthGlobalWorkQueue.h @@ -0,0 +1,31 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** @fn FIRAuthGlobalWorkQueue + @brief Retrieves the global serial work queue for Firebase Auth. + @return The global serial dispatch queue. + @remarks To ensure thread safety, all auth code must be executed in either this global work + queue, or a serial queue that has its target queue set to this work queue. All public method + implementations that may involve contested code shall dispatch to this work queue as the + first thing they do. + */ +extern dispatch_queue_t FIRAuthGlobalWorkQueue(void); + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthGlobalWorkQueue.m b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthGlobalWorkQueue.m new file mode 100644 index 0000000..6295b8b --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthGlobalWorkQueue.m @@ -0,0 +1,30 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRAuthGlobalWorkQueue.h" + +NS_ASSUME_NONNULL_BEGIN + +dispatch_queue_t FIRAuthGlobalWorkQueue() { + static dispatch_once_t once; + static dispatch_queue_t queue; + dispatch_once(&once, ^{ + queue = dispatch_queue_create("com.google.firebase.auth.globalWorkQueue", NULL); + }); + return queue; +} + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthInternalErrors.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthInternalErrors.h new file mode 100644 index 0000000..205dc0f --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthInternalErrors.h @@ -0,0 +1,473 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +#import "FIRAuthErrors.h" + +NS_ASSUME_NONNULL_BEGIN + +/** @var FIRAuthPublicErrorCodeFlag + @brief Bitmask value indicating the error represents a public error code when this bit is + zeroed. Error codes which don't contain this flag will be wrapped in an @c NSError whose + code is @c FIRAuthErrorCodeInternalError. + */ +static const NSInteger FIRAuthPublicErrorCodeFlag = 1 << 20; + +/** @var FIRAuthInternalErrorDomain + @brief The Firebase Auth error domain for internal errors. + */ +extern NSString *const FIRAuthInternalErrorDomain; + +/** @var FIRAuthErrorUserInfoDeserializedResponseKey + @brief Errors with the code @c FIRAuthErrorCodeUnexpectedResponseError, + @c FIRAuthErrorCodeUnexpectedErrorResponseError, and + @c FIRAuthInternalErrorCodeRPCResponseDecodingError may contain an @c NSError.userInfo + dictionary which contains this key. The value associated with this key is an object of + unspecified contents containing the deserialized server response. + */ +extern NSString *const FIRAuthErrorUserInfoDeserializedResponseKey; + +/** @var FIRAuthErrorUserInfoDataKey + @brief Errors with the code @c FIRAuthErrorCodeUnexpectedResponseError or + @c FIRAuthErrorCodeUnexpectedErrorResponseError may contain an @c NSError.userInfo + dictionary which contains this key. The value associated with this key is an @c NSString + which represents the response from a server to an RPC which could not be deserialized. + */ +extern NSString *const FIRAuthErrorUserInfoDataKey; + + +/** @var FIRAuthInternalErrorCode + @brief Error codes used internally by Firebase Auth. + @remarks All errors are generated using an internal error code. These errors are automatically + converted to the appropriate public version of the @c NSError by the methods in + @c FIRAuthErrorUtils + */ +typedef NS_ENUM(NSInteger, FIRAuthInternalErrorCode) { + /** @var FIRAuthInternalErrorCodeNetworkError + @brief Indicates a network error occurred (such as a timeout, interrupted connection, or + unreachable host.) + @remarks These types of errors are often recoverable with a retry. + + See the @c NSUnderlyingError value in the @c NSError.userInfo dictionary for details about + the network error which occurred. + */ + FIRAuthInternalErrorCodeNetworkError = FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeNetworkError, + + /** @var FIRAuthInternalErrorCodeEmailAlreadyInUse + @brief The email used to attempt a sign-up already exists. + */ + FIRAuthInternalErrorCodeEmailAlreadyInUse = + FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeEmailAlreadyInUse, + + /** @var FIRAuthInternalErrorCodeUserDisabled + @brief Indicates the user's account is disabled on the server side. + */ + FIRAuthInternalErrorCodeUserDisabled = FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeUserDisabled, + + /** @var FIRAuthInternalErrorCodeWrongPassword + @brief Indicates the user attempted sign in with a wrong password + */ + FIRAuthInternalErrorCodeWrongPassword = + FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeWrongPassword, + + /** @var FIRAuthInternalErrorCodeKeychainError + @brief Indicates an error occurred accessing the keychain. + @remarks The @c NSLocalizedFailureReasonErrorKey field in the @c NSError.userInfo dictionary + will contain more information about the error encountered. + */ + FIRAuthInternalErrorCodeKeychainError = + FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeKeychainError, + + /** @var FIRAuthInternalErrorCodeInternalError + @brief An internal error occurred. + @remarks This value is here for consistency. It's also used to make the implementation of + wrapping internal errors simpler. + */ + FIRAuthInternalErrorCodeInternalError = + FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeInternalError, + + /** @var FIRAuthInternalErrorCodeTooManyRequests + @brief Indicates that too many requests were made to a server method. + */ + FIRAuthInternalErrorCodeTooManyRequests = + FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeTooManyRequests, + + /** @var FIRAuthInternalErrorCodeInvalidCustomToken + @brief Indicates a validation error with the custom token. + */ + FIRAuthInternalErrorCodeInvalidCustomToken = + FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeInvalidCustomToken, + + /** @var FIRAuthInternalErrorCodeCredentialMismatch + @brief Indicates the service account and the API key belong to different projects. + */ + FIRAuthInternalErrorCodeCustomTokenMismatch = + FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeCustomTokenMismatch, + + /** @var FIRAuthInternalErrorCodeInvalidCredential + @brief Indicates the IDP token or requestUri is invalid. + */ + FIRAuthInternalErrorCodeInvalidCredential = + FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeInvalidCredential, + + /** @var FIRAuthInternalErrorCodeRequiresRecentLogin + @brief Indicates the user has attemped to change email or password more than 5 minutes after + signing in. + */ + FIRAuthInternalErrorCodeRequiresRecentLogin = + FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeRequiresRecentLogin, + + /** @var FIRAuthInternalErrorCodeInvalidUserToken + @brief Indicates user's saved auth credential is invalid, the user needs to sign in again. + */ + FIRAuthInternalErrorCodeInvalidUserToken = + FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeInvalidUserToken, + + /** @var FIRAuthInternalErrorCodeInvalidEmail + @brief Indicates the email identifier is invalid. + */ + FIRAuthInternalErrorCodeInvalidEmail = + FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeInvalidEmail, + + /** @var FIRAuthInternalErrorCodeAccountExistsWithDifferentCredential + @brief Indicates account linking is needed. + */ + FIRAuthInternalErrorCodeAccountExistsWithDifferentCredential = + FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeAccountExistsWithDifferentCredential, + + /** @var FIRAuthInternalErrorCodeProviderAlreadyLinked + @brief Indicates an attempt to link a provider to which we are already linked. + */ + FIRAuthInternalErrorCodeProviderAlreadyLinked = + FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeProviderAlreadyLinked, + + /** @var FIRAuthInternalErrorCodeNoSuchProvider + @brief Indicates an attempt to unlink a provider that is not is not linked. + */ + FIRAuthInternalErrorCodeNoSuchProvider = + FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeNoSuchProvider, + + /** @var FIRAuthInternalErrorCodeUserTokenExpired + @brief Indicates the token issue time is older than account's valid_since time. + */ + FIRAuthInternalErrorCodeUserTokenExpired = + FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeUserTokenExpired, + + /** @var FIRAuthInternalErrorCodeUserNotFound + @brief Indicates the user account was been found. + */ + FIRAuthInternalErrorCodeUserNotFound = + FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeUserNotFound, + + /** @var FIRAuthInternalErrorCodeInvalidAPIKey + @brief Indicates an invalid API Key was supplied in the request. + */ + FIRAuthInternalErrorCodeInvalidAPIKey = + FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeInvalidAPIKey, + + /** @var FIRAuthInternalErrorCodeOperationNotAllowed + @brief Indicates that admin disabled sign-in with the specified IDP. + */ + FIRAuthInternalErrorCodeOperationNotAllowed = + FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeOperationNotAllowed, + + /** @var FIRAuthInternalErrorCodeUserMismatch + @brief Indicates that user attempted to reauthenticate with a user other than the current + user. + */ + FIRAuthInternalErrorCodeUserMismatch = + FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeUserMismatch, + + /** @var FIRAuthInternalErrorCodeCredentialAlreadyInUse + @brief Indicates an attempt to link with a credential that has already been linked with a + different Firebase account. + */ + FIRAuthInternalErrorCodeCredentialAlreadyInUse = + FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeCredentialAlreadyInUse, + + /** @var FIRAuthInternalErrorCodeWeakPassword + @brief Indicates an attempt to set a password that is considered too weak. + */ + FIRAuthInternalErrorCodeWeakPassword = + FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeWeakPassword, + + /** @var FIRAuthInternalErrorCodeAppNotAuthorized + @brief Indicates the App is not authorized to use Firebase Authentication with the + provided API Key. + */ + FIRAuthInternalErrorCodeAppNotAuthorized = + FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeAppNotAuthorized, + + /** @var FIRAuthInternalErrorCodeExpiredActionCode + @brief Indicates the OOB code is expired. + */ + FIRAuthInternalErrorCodeExpiredActionCode = + FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeExpiredActionCode, + + /** @var FIRAuthInternalErrorCodeInvalidActionCode + @brief Indicates the OOB code is invalid. + */ + FIRAuthInternalErrorCodeInvalidActionCode = + FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeInvalidActionCode, + + /** Indicates that there are invalid parameters in the payload during a "send password reset email + * " attempt. + */ + FIRAuthInternalErrorCodeInvalidMessagePayload = + FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeInvalidMessagePayload, + + /** Indicates that the sender email is invalid during a "send password reset email" attempt. + */ + FIRAuthInternalErrorCodeInvalidSender = + FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeInvalidSender, + + /** Indicates that the recipient email is invalid. + */ + FIRAuthInternalErrorCodeInvalidRecipientEmail = + FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeInvalidRecipientEmail, + + /** Indicates that the iOS bundle ID is missing when a iOS App Store ID is provided. + */ + FIRAuthinternalErrorCodeMissingIosBundleID = + FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeMissingIosBundleID, + + /** Indicates that the android package name is missing when the @c androidInstallApp flag is set + to true. + */ + FIRAuthInternalErrorCodeMissingAndroidPackageName = + FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeMissingAndroidPackageName, + + /** Indicates that the domain specified in the continue URL is not whitelisted in the Firebase + console. + */ + FIRAuthInternalErrorCodeUnauthorizedDomain = + FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeUnauthorizedDomain, + + /** Indicates that the domain specified in the continue URI is not valid. + */ + FIRAuthInternalErrorCodeInvalidContinueURI = + FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeInvalidContinueURI, + + /** Indicates that a continue URI was not provided in a request to the backend which requires + one. + */ + FIRAuthInternalErrorCodeMissingContinueURI = + FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeMissingContinueURI, + + /** Indicates that an email address was expected but one was not provided. + */ + FIRAuthInternalErrorCodeMissingEmail = + FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeMissingEmail, + + /** Indicates that a phone number was not provided in a call to @c verifyPhoneNumber:completion:. + */ + FIRAuthInternalErrorCodeMissingPhoneNumber = + FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeMissingPhoneNumber, + + /** Indicates that an invalid phone number was provided in a call to @c + verifyPhoneNumber:completion:. + */ + FIRAuthInternalErrorCodeInvalidPhoneNumber = + FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeInvalidPhoneNumber, + + /** Indicates that the phone auth credential was created with an empty verification code. + */ + FIRAuthInternalErrorCodeMissingVerificationCode = + FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeMissingVerificationCode, + + /** Indicates that an invalid verification code was used in the verifyPhoneNumber request. + */ + FIRAuthInternalErrorCodeInvalidVerificationCode = + FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeInvalidVerificationCode, + + /** Indicates that the phone auth credential was created with an empty verification ID. + */ + FIRAuthInternalErrorCodeMissingVerificationID = + FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeMissingVerificationID, + + /** Indicates that the APNS device token is missing in the verifyClient request. + */ + FIRAuthInternalErrorCodeMissingAppCredential = + FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeMissingAppCredential, + + /** Indicates that an invalid APNS device token was used in the verifyClient request. + */ + FIRAuthInternalErrorCodeInvalidAppCredential = + FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeInvalidAppCredential, + + /** Indicates that the reCAPTCHA token is not valid. + */ + FIRAuthInternalErrorCodeCaptchaCheckFailed = + FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeCaptchaCheckFailed, + + /** Indicates that an invalid verification ID was used in the verifyPhoneNumber request. + */ + FIRAuthInternalErrorCodeInvalidVerificationID = + FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeInvalidVerificationID, + + /** Indicates that the quota of SMS messages for a given project has been exceeded. + */ + FIRAuthInternalErrorCodeQuotaExceeded = + FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeQuotaExceeded, + + /** Indicates that an attempt was made to present a new web context while one was already being + presented. + */ + FIRAuthInternalErrorCodeWebContextAlreadyPresented = + FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeWebContextAlreadyPresented, + + /** Indicates that the URL presentation was cancelled prematurely by the user. + */ + FIRAuthInternalErrorCodeWebContextCancelled = + FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeWebContextCancelled, + + /** Indicates a general failure during the app verification flow. + */ + FIRAuthInternalErrorCodeAppVerificationUserInteractionFailure = + FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeAppVerificationUserInteractionFailure, + + /** Indicates that the clientID used to invoke a web flow is invalid. + */ + FIRAuthInternalErrorCodeInvalidClientID = + FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeInvalidClientID, + + /** Indicates that a network request within a SFSafariViewController or UIWebview failed. + */ + FIRAuthInternalErrorCodeWebNetworkRequestFailed = + FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeWebNetworkRequestFailed, + + /** Indicates that an internal error occurred within a SFSafariViewController or UIWebview. + */ + FIRAuthInternalErrorCodeWebInternalError = + FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeWebInternalError, + + /** Indicates that an internal error occurred within a SFSafariViewController or UIWebview. + */ + FIRAuthInternalErrorCodeWebSignInUserInteractionFailure = + FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeWebSignInUserInteractionFailure, + + // The enum values between 17046 and 17051 are reserved and should NOT be used for new error + // codes. + + /** Indicates that the SMS code has expired + */ + FIRAuthInternalErrorCodeSessionExpired = + FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeSessionExpired, + + FIRAuthInternalErrorCodeMissingAppToken = + FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeMissingAppToken, + + FIRAuthInternalErrorCodeNotificationNotForwarded = + FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeNotificationNotForwarded, + + FIRAuthInternalErrorCodeAppNotVerified = + FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeAppNotVerified, + + /** Indicates that the Game Center local player was not authenticated. + */ + FIRAuthInternalErrorCodeLocalPlayerNotAuthenticated = + FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeLocalPlayerNotAuthenticated, + + /** Indicates that the Game Center local player was not authenticated. + */ + FIRAuthInternalErrorCodeGameKitNotLinked = + FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeGameKitNotLinked, + + /** Indicates that a non-null user was expected as an argmument to the operation but a null + user was provided. + */ + FIRAuthInternalErrorCodeNullUser = + FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeNullUser, + + /** Indicates that the provider id given for the web operation is invalid. + */ + FIRAuthInternalErrorCodeInvalidProviderID = + FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeInvalidProviderID, + + /** Indicates that the Firebase Dynamic Link domain used is either not configured or is unauthorized + for the current project. + */ + FIRAuthInternalErrorCodeInvalidDynamicLinkDomain = + FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeInvalidDynamicLinkDomain, + + FIRAuthInternalErrorCodeMalformedJWT = + FIRAuthPublicErrorCodeFlag | FIRAuthErrorCodeMalformedJWT, + + /** @var FIRAuthInternalErrorCodeRPCRequestEncodingError + @brief Indicates an error encoding the RPC request. + @remarks This is typically due to some sort of unexpected input value. + + See the @c NSUnderlyingError value in the @c NSError.userInfo dictionary for details. + */ + FIRAuthInternalErrorCodeRPCRequestEncodingError = 1, + + /** @var FIRAuthInternalErrorCodeJSONSerializationError + @brief Indicates an error serializing an RPC request. + @remarks This is typically due to some sort of unexpected input value. + + If an @c NSJSONSerialization.isValidJSONObject: check fails, the error will contain no + @c NSUnderlyingError key in the @c NSError.userInfo dictionary. If an error was + encountered calling @c NSJSONSerialization.dataWithJSONObject:options:error:, the + resulting error will be associated with the @c NSUnderlyingError key in the + @c NSError.userInfo dictionary. + */ + FIRAuthInternalErrorCodeJSONSerializationError = 2, + + /** @var FIRAuthInternalErrorCodeUnexpectedErrorResponse + @brief Indicates an HTTP error occurred and the data returned either couldn't be deserialized + or couldn't be decoded. + @remarks See the @c NSUnderlyingError value in the @c NSError.userInfo dictionary for details + about the HTTP error which occurred. + + If the response could be deserialized as JSON then the @c NSError.userInfo dictionary will + contain a value for the key @c FIRAuthErrorUserInfoDeserializedResponseKey which is the + deserialized response value. + + If the response could not be deserialized as JSON then the @c NSError.userInfo dictionary + will contain values for the @c NSUnderlyingErrorKey and @c FIRAuthErrorUserInfoDataKey + keys. + */ + FIRAuthInternalErrorCodeUnexpectedErrorResponse = 3, + + /** @var FIRAuthInternalErrorCodeUnexpectedResponse + @brief Indicates the HTTP response indicated the request was a successes, but the response + contains something other than a JSON-encoded dictionary, or the data type of the response + indicated it is different from the type of response we expected. + @remarks See the @c NSUnderlyingError value in the @c NSError.userInfo dictionary. + If this key is present in the dictionary, it may contain an error from + @c NSJSONSerialization error (indicating the response received was of the wrong data + type). + + See the @c FIRAuthErrorUserInfoDeserializedResponseKey value in the @c NSError.userInfo + dictionary. If the response could be deserialized, it's deserialized representation will + be associated with this key. If the @c NSUnderlyingError value in the @c NSError.userInfo + dictionary is @c nil, this indicates the JSON didn't represent a dictionary. + */ + FIRAuthInternalErrorCodeUnexpectedResponse = 4, + + /** @var FIRAuthInternalErrorCodeRPCResponseDecodingError + @brief Indicates an error decoding the RPC response. + This is typically due to some sort of unexpected response value from the server. + @remarks See the @c NSUnderlyingError value in the @c NSError.userInfo dictionary for details. + + See the @c FIRErrorUserInfoDecodedResponseKey value in the @c NSError.userInfo dictionary. + The deserialized representation of the response will be associated with this key. + */ + FIRAuthInternalErrorCodeRPCResponseDecodingError = 5, +}; + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthKeychain.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthKeychain.h new file mode 100644 index 0000000..c52e26a --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthKeychain.h @@ -0,0 +1,70 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + @brief The protocol for permanant data storage. + */ +@protocol FIRAuthStorage + +/** @fn initWithService: + @brief Initialize a @c FIRAuthStorage instance. + @param service The name of the storage service to use. + @return An initialized @c FIRAuthStorage instance for the specified service. + */ +- (id)initWithService:(NSString *)service; + +/** @fn dataForKey:error: + @brief Gets the data for @c key in the storage. The key is set for the attribute + @c kSecAttrAccount of a generic password query. + @param key The key to use. + @param error The address to store any error that occurs during the process, if not NULL. + If the operation was successful, its content is set to @c nil . + @return The data stored in the storage for @c key, if any. + */ +- (nullable NSData *)dataForKey:(NSString *)key error:(NSError **_Nullable)error; + +/** @fn setData:forKey:error: + @brief Sets the data for @c key in the storage. The key is set for the attribute + @c kSecAttrAccount of a generic password query. + @param data The data to store. + @param key The key to use. + @param error The address to store any error that occurs during the process, if not NULL. + @return Whether the operation succeeded or not. + */ +- (BOOL)setData:(NSData *)data forKey:(NSString *)key error:(NSError **_Nullable)error; + +/** @fn removeDataForKey:error: + @brief Removes the data for @c key in the storage. The key is set for the attribute + @c kSecAttrAccount of a generic password query. + @param key The key to use. + @param error The address to store any error that occurs during the process, if not NULL. + @return Whether the operation succeeded or not. + */ +- (BOOL)removeDataForKey:(NSString *)key error:(NSError **_Nullable)error; + +@end + +/** @class FIRAuthKeychain + @brief The utility class to manipulate data in iOS Keychain. + */ +@interface FIRAuthKeychain : NSObject +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthKeychain.m b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthKeychain.m new file mode 100644 index 0000000..d196244 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthKeychain.m @@ -0,0 +1,260 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRAuthKeychain.h" + +#import + +#import "FIRAuthErrorUtils.h" +#import "FIRAuthUserDefaultsStorage.h" + +#if FIRAUTH_USER_DEFAULTS_STORAGE_AVAILABLE +#import + +/** @var kOSVersionMatcherForUsingUserDefaults + @brief The regular expression to match all OS versions that @c FIRAuthUserDefaultsStorage is + used instead if available. + */ +static NSString *const kOSVersionMatcherForUsingUserDefaults = @"^10\\.[01](\\..*)?$"; + +#endif // FIRAUTH_USER_DEFAULTS_STORAGE_AVAILABLE + +/** @var kAccountPrefix + @brief The prefix string for keychain item account attribute before the key. + @remarks A number "1" is encoded in the prefix in case we need to upgrade the scheme in future. + */ +static NSString *const kAccountPrefix = @"firebase_auth_1_"; + +NS_ASSUME_NONNULL_BEGIN + +@implementation FIRAuthKeychain { + /** @var _service + @brief The name of the keychain service. + */ + NSString *_service; + + /** @var _legacyItemDeletedForKey + @brief Indicates whether or not this class knows that the legacy item for a particular key has + been deleted. + @remarks This dictionary is to avoid unecessary keychain operations against legacy items. + */ + NSMutableDictionary *_legacyEntryDeletedForKey; +} + +- (id)initWithService:(NSString *)service { + +#if FIRAUTH_USER_DEFAULTS_STORAGE_AVAILABLE + + NSString *OSVersion = [UIDevice currentDevice].systemVersion; + NSRegularExpression *regex = + [NSRegularExpression regularExpressionWithPattern:kOSVersionMatcherForUsingUserDefaults + options:0 + error:NULL]; + if ([regex numberOfMatchesInString:OSVersion options:0 range:NSMakeRange(0, OSVersion.length)]) { + return (id)[[FIRAuthUserDefaultsStorage alloc] initWithService:service]; + } + +#endif // FIRAUTH_USER_DEFAULTS_STORAGE_AVAILABLE + + self = [super init]; + if (self) { + _service = [service copy]; + _legacyEntryDeletedForKey = [[NSMutableDictionary alloc] init]; + } + return self; +} + +- (nullable NSData *)dataForKey:(NSString *)key error:(NSError **_Nullable)error { + if (!key.length) { + [NSException raise:NSInvalidArgumentException + format:@"%@", @"The key cannot be nil or empty."]; + return nil; + } + NSData *data = [self itemWithQuery:[self genericPasswordQueryWithKey:key] error:error]; + if (error && *error) { + return nil; + } + if (data) { + return data; + } + // Check for legacy form. + if (_legacyEntryDeletedForKey[key]) { + return nil; + } + data = [self itemWithQuery:[self legacyGenericPasswordQueryWithKey:key] error:error]; + if (error && *error) { + return nil; + } + if (!data) { + // Mark legacy data as non-existing so we don't have to query it again. + _legacyEntryDeletedForKey[key] = @YES; + return nil; + } + // Move the data to current form. + if (![self setData:data forKey:key error:error]) { + return nil; + } + [self deleteLegacyItemWithKey:key]; + return data; +} + +- (BOOL)setData:(NSData *)data forKey:(NSString *)key error:(NSError **_Nullable)error { + if (!key.length) { + [NSException raise:NSInvalidArgumentException + format:@"%@", @"The key cannot be nil or empty."]; + return NO; + } + NSDictionary *attributes = @{ + (__bridge id)kSecValueData : data, + (__bridge id)kSecAttrAccessible : (__bridge id)kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly, + }; + return [self setItemWithQuery:[self genericPasswordQueryWithKey:key] + attributes:attributes + error:error]; +} + +- (BOOL)removeDataForKey:(NSString *)key error:(NSError **_Nullable)error { + if (!key.length) { + [NSException raise:NSInvalidArgumentException + format:@"%@", @"The key cannot be nil or empty."]; + return NO; + } + if (![self deleteItemWithQuery:[self genericPasswordQueryWithKey:key] error:error]) { + return NO; + } + // Legacy form item, if exists, also needs to be removed, otherwise it will be exposed when + // current form item is removed, leading to incorrect semantics. + [self deleteLegacyItemWithKey:key]; + return YES; +} + +#pragma mark - Private + +- (NSData *)itemWithQuery:(NSDictionary *)query error:(NSError **_Nullable)error { + NSMutableDictionary *returningQuery = [query mutableCopy]; + returningQuery[(__bridge id)kSecReturnData] = @YES; + returningQuery[(__bridge id)kSecReturnAttributes] = @YES; + // Using a match limit of 2 means that we can check whether there is more than one item. + // If we used a match limit of 1 we would never find out. + returningQuery[(__bridge id)kSecMatchLimit] = @2; + + CFArrayRef result = NULL; + OSStatus status = SecItemCopyMatching((__bridge CFDictionaryRef)returningQuery, + (CFTypeRef *)&result); + + if (status == noErr && result != NULL) { + NSArray *items = (__bridge_transfer NSArray *)result; + if (items.count != 1) { + if (error) { + *error = [FIRAuthErrorUtils keychainErrorWithFunction:@"SecItemCopyMatching" + status:status]; + } + return nil; + } + + if (error) { + *error = nil; + } + NSDictionary *item = items[0]; + return item[(__bridge id)kSecValueData]; + } + + if (status == errSecItemNotFound) { + if (error) { + *error = nil; + } + } else { + if (error) { + *error = [FIRAuthErrorUtils keychainErrorWithFunction:@"SecItemCopyMatching" status:status]; + } + } + return nil; +} + +- (BOOL)setItemWithQuery:(NSDictionary *)query + attributes:(NSDictionary *)attributes + error:(NSError **_Nullable)error { + NSMutableDictionary *combined = [attributes mutableCopy]; + [combined addEntriesFromDictionary:query]; + BOOL hasItem = NO; + OSStatus status = SecItemAdd((__bridge CFDictionaryRef)combined, NULL); + + if (status == errSecDuplicateItem) { + hasItem = YES; + status = SecItemUpdate((__bridge CFDictionaryRef)query, (__bridge CFDictionaryRef)attributes); + } + + if (status == noErr) { + return YES; + } + if (error) { + NSString *function = hasItem ? @"SecItemUpdate" : @"SecItemAdd"; + *error = [FIRAuthErrorUtils keychainErrorWithFunction:function status:status]; + } + return NO; +} + +- (BOOL)deleteItemWithQuery:(NSDictionary *)query error:(NSError **_Nullable)error { + OSStatus status = SecItemDelete((__bridge CFDictionaryRef)query); + if (status == noErr || status == errSecItemNotFound) { + return YES; + } + if (error) { + *error = [FIRAuthErrorUtils keychainErrorWithFunction:@"SecItemDelete" status:status]; + } + return NO; +} + +/** @fn deleteLegacyItemsWithKey: + @brief Deletes legacy item from the keychain if it is not already known to be deleted. + @param key The key for the item. + */ +- (void)deleteLegacyItemWithKey:(NSString *)key { + if (_legacyEntryDeletedForKey[key]) { + return; + } + NSDictionary *query = [self legacyGenericPasswordQueryWithKey:key]; + SecItemDelete((__bridge CFDictionaryRef)query); + _legacyEntryDeletedForKey[key] = @YES; +} + +/** @fn genericPasswordQueryWithKey: + @brief Returns a keychain query of generic password to be used to manipulate key'ed value. + @param key The key for the value being manipulated, used as the account field in the query. + */ +- (NSDictionary *)genericPasswordQueryWithKey:(NSString *)key { + return @{ + (__bridge id)kSecClass : (__bridge id)kSecClassGenericPassword, + (__bridge id)kSecAttrAccount : [kAccountPrefix stringByAppendingString:key], + (__bridge id)kSecAttrService : _service, + }; +} + +/** @fn legacyGenericPasswordQueryWithKey: + @brief Returns a keychain query of generic password without service field, which is used by + previous version of this class. + @param key The key for the value being manipulated, used as the account field in the query. + */ +- (NSDictionary *)legacyGenericPasswordQueryWithKey:(NSString *)key { + return @{ + (__bridge id)kSecClass : (__bridge id)kSecClassGenericPassword, + (__bridge id)kSecAttrAccount : key, + }; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthNotificationManager.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthNotificationManager.h new file mode 100644 index 0000000..42e5db8 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthNotificationManager.h @@ -0,0 +1,71 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import +#import + +@class FIRAuthAppCredentialManager; + +NS_ASSUME_NONNULL_BEGIN + +/** @typedef FIRAuthNotificationForwardingCallback + @brief The type of block to receive whether or not remote notifications are being forwarded. + @param isNotificationBeingForwarded Whether or not remote notifications are being forwarded. + */ +typedef void (^FIRAuthNotificationForwardingCallback)(BOOL isNotificationBeingForwarded); + +/** @class FIRAuthNotificationManager + */ +@interface FIRAuthNotificationManager : NSObject + +/** @property timeout + @brief The timeout for checking for notification forwarding. + @remarks Only tests should access this property. + */ +@property(nonatomic, assign) NSTimeInterval timeout; + +/** @fn initWithApplication:appCredentialManager: + @brief Initializes the instance. + @param application The application. + @param appCredentialManager The object to handle app credentials delivered via notification. + @return The initialized instance. + */ +- (instancetype)initWithApplication:(UIApplication *)application + appCredentialManager:(FIRAuthAppCredentialManager *)appCredentialManager + NS_DESIGNATED_INITIALIZER; + +/** @fn init + @brief please use initWithAppCredentialManager: instead. + */ +- (instancetype)init NS_UNAVAILABLE; + +/** @fn checkNotificationForwardingWithCallback: + @brief Checks whether or not remote notifications are being forwarded to this class. + @param callback The block to be called either immediately or in future once a result + is available. + */ +- (void)checkNotificationForwardingWithCallback:(FIRAuthNotificationForwardingCallback)callback; + +/** @fn canHandleNotification: + @brief Attempts to handle the remote notification. + @param notification The notification in question. + @return Whether or the notification has been handled. + */ +- (BOOL)canHandleNotification:(NSDictionary *)notification; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthNotificationManager.m b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthNotificationManager.m new file mode 100644 index 0000000..682ffcb --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthNotificationManager.m @@ -0,0 +1,177 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRAuthNotificationManager.h" + +#import +#import "FIRAuthAppCredential.h" +#import "FIRAuthAppCredentialManager.h" +#import "FIRAuthGlobalWorkQueue.h" + +NS_ASSUME_NONNULL_BEGIN + +/** @var kNotificationKey + @brief The key to locate payload data in the remote notification. + */ +static NSString *const kNotificationDataKey = @"com.google.firebase.auth"; + +/** @var kNotificationReceiptKey + @brief The key for the receipt in the remote notification payload data. + */ +static NSString *const kNotificationReceiptKey = @"receipt"; + +/** @var kNotificationSecretKey + @brief The key for the secret in the remote notification payload data. + */ +static NSString *const kNotificationSecretKey = @"secret"; + +/** @var kNotificationProberKey + @brief The key for marking the prober in the remote notification payload data. + */ +static NSString *const kNotificationProberKey = @"warning"; + +/** @var kProbingTimeout + @brief Timeout for probing whether the app delegate forwards the remote notification to us. + */ +static const NSTimeInterval kProbingTimeout = 1; + +@implementation FIRAuthNotificationManager { + /** @var _application + @brief The application. + */ + UIApplication *_application; + + /** @var _appCredentialManager + @brief The object to handle app credentials delivered via notification. + */ + FIRAuthAppCredentialManager *_appCredentialManager; + + /** @var _hasCheckedNotificationForwarding + @brief Whether notification forwarding has been checked or not. + */ + BOOL _hasCheckedNotificationForwarding; + + /** @var _isNotificationBeingForwarded + @brief Whether or not notification is being forwarded + */ + BOOL _isNotificationBeingForwarded; + + /** @var _pendingCallbacks + @brief All pending callbacks while a check is being performed. + */ + NSMutableArray *_pendingCallbacks; +} + +- (instancetype)initWithApplication:(UIApplication *)application + appCredentialManager:(FIRAuthAppCredentialManager *)appCredentialManager { + self = [super init]; + if (self) { + _application = application; + _appCredentialManager = appCredentialManager; + _timeout = kProbingTimeout; + } + return self; +} + +- (void)checkNotificationForwardingWithCallback:(FIRAuthNotificationForwardingCallback)callback { + if (_pendingCallbacks) { + [_pendingCallbacks addObject:callback]; + return; + } + if (_hasCheckedNotificationForwarding) { + callback(_isNotificationBeingForwarded); + return; + } + _hasCheckedNotificationForwarding = YES; + _pendingCallbacks = + [[NSMutableArray alloc] initWithObjects:callback, nil]; + dispatch_async(dispatch_get_main_queue(), ^{ + NSDictionary *proberNotification = @{ + kNotificationDataKey : @{ + kNotificationProberKey : @"This fake notification should be forwarded to Firebase Auth." + } + }; + if ([self->_application.delegate respondsToSelector: + @selector(application:didReceiveRemoteNotification:fetchCompletionHandler:)]) { + [self->_application.delegate application:self->_application + didReceiveRemoteNotification:proberNotification + fetchCompletionHandler:^(UIBackgroundFetchResult result) {}]; +#if !TARGET_OS_TV + } else if ([self->_application.delegate respondsToSelector: + @selector(application:didReceiveRemoteNotification:)]) { + [self->_application.delegate application:self->_application + didReceiveRemoteNotification:proberNotification]; +#endif + } else { + FIRLogWarning(kFIRLoggerAuth, @"I-AUT000015", + @"The UIApplicationDelegate must handle remote notification for phone number " + @"authentication to work."); + } + }); + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(_timeout * NSEC_PER_SEC)), + FIRAuthGlobalWorkQueue(), ^{ + [self callBack]; + }); +} + +- (BOOL)canHandleNotification:(NSDictionary *)notification { + NSDictionary *data = notification[kNotificationDataKey]; + if ([data isKindOfClass:[NSString class]]) { + // Deserialize in case the data is a JSON string. + NSData *JSONData = [((NSString *)data) dataUsingEncoding:NSUTF8StringEncoding]; + data = [NSJSONSerialization JSONObjectWithData:JSONData options:0 error:NULL]; + } + if (![data isKindOfClass:[NSDictionary class]]) { + return NO; + } + if (data[kNotificationProberKey]) { + if (!_pendingCallbacks) { + // The prober notification probably comes from another instance, so pass it along. + return NO; + } + _isNotificationBeingForwarded = YES; + [self callBack]; + return YES; + } + NSString *receipt = data[kNotificationReceiptKey]; + if (![receipt isKindOfClass:[NSString class]]) { + return NO; + } + NSString *secret = data[kNotificationSecretKey]; + if (![receipt isKindOfClass:[NSString class]]) { + return NO; + } + return [_appCredentialManager canFinishVerificationWithReceipt:receipt secret:secret]; +} + +#pragma mark - Internal methods + +/** @fn callBack + @brief Calls back all pending callbacks with the result of notification forwarding check. + */ +- (void)callBack { + if (!_pendingCallbacks) { + return; + } + NSArray *allCallbacks = _pendingCallbacks; + _pendingCallbacks = nil; + for (FIRAuthNotificationForwardingCallback callback in allCallbacks) { + callback(_isNotificationBeingForwarded); + } +}; + +@end +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthOperationType.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthOperationType.h new file mode 100644 index 0000000..15d3dd7 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthOperationType.h @@ -0,0 +1,47 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + @brief Indicates the type of operation performed for RPCs that support the operation + parameter. + */ +typedef NS_ENUM(NSInteger, FIRAuthOperationType) { + /** Indicates that the operation type is uspecified. + */ + FIRAuthOperationTypeUnspecified = 0, + + /** Indicates that the operation type is sign in or sign up. + */ + FIRAuthOperationTypeSignUpOrSignIn = 1, + + /** Indicates that the operation type is reauthentication. + */ + FIRAuthOperationTypeReauth = 2, + + /** Indicates that the operation type is update. + */ + FIRAuthOperationTypeUpdate = 3, + + /** Indicates that the operation type is link. + */ + FIRAuthOperationTypeLink = 4, +}; + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthProvider.m b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthProvider.m new file mode 100644 index 0000000..e382d4e --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthProvider.m @@ -0,0 +1,75 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +#pragma mark - Provider ID constants + +// Declared 'extern' in FIRGoogleAuthProvider.h +NSString *const FIRGoogleAuthProviderID = @"google.com"; + +// Declared 'extern' in FIRFacebookAuthProvider.h +NSString *const FIRFacebookAuthProviderID = @"facebook.com"; + +// Declared 'extern' in FIREmailAuthProvider.h +NSString *const FIREmailAuthProviderID = @"password"; + +// Declared 'extern' in FIREmailAuthProvider.h +NSString *const FIREmailPasswordAuthProviderID = @"password"; + +// Declared 'extern' in FIRTwitterAuthProvider.h +NSString *const FIRTwitterAuthProviderID = @"twitter.com"; + +// Declared 'extern' in FIRGitHubAuthProvider.h +NSString *const FIRGitHubAuthProviderID = @"github.com"; + +// Declared 'extern' in FIRPhoneAuthProvider.h +NSString *const FIRPhoneAuthProviderID = @"phone"; + +// Declared 'extern' in FIRGameCenterAuthProvider.h +NSString *const FIRGameCenterAuthProviderID = @"gc.apple.com"; + +// Declared 'extern' in FIROAuthProvider.h +NSString *const FIRYahooAuthProviderID = @"yahoo.com"; + +// Declared 'extern' in FIROAuthProvider.h +NSString *const FIRMicrosoftAuthProviderID = @"hotmail.com"; + +#pragma mark - sign-in methods constants + +// Declared 'extern' in FIRGoogleAuthProvider.h +NSString *const FIRGoogleAuthSignInMethod = @"google.com"; + +// Declared 'extern' in FIREmailAuthProvider.h +NSString *const FIREmailPasswordAuthSignInMethod = @"password"; + +// Declared 'extern' in FIREmailAuthProvider.h +NSString *const FIREmailLinkAuthSignInMethod = @"emailLink"; + +// Declared 'extern' in FIRTwitterAuthProvider.h +NSString *const FIRTwitterAuthSignInMethod = @"twitter.com"; + +// Declared 'extern' in FIRFacebookAuthProvider.h +NSString *const FIRFacebookAuthSignInMethod = @"facebook.com"; + +// Declared 'extern' in FIRGitHubAuthProvider.h +NSString *const FIRGitHubAuthSignInMethod = @"github.com"; + +// Declared 'extern' in FIRPhoneAuthProvider.h +NSString *const FIRPhoneAuthSignInMethod = @"phone"; + +// Declared 'extern' in FIRGameCenterAuthProvider.h +NSString *const FIRGameCenterAuthSignInMethod = @"gc.apple.com"; diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthSerialTaskQueue.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthSerialTaskQueue.h new file mode 100644 index 0000000..cdae046 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthSerialTaskQueue.h @@ -0,0 +1,50 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** @typedef FIRAuthSerialTaskCompletionBlock + @brief The type of method a @c FIRAuthSerialTask must call when it is complete. + */ +typedef void (^FIRAuthSerialTaskCompletionBlock)(void); + +/** @typedef FIRAuthSerialTask + @brief Represents a unit of work submitted to a task queue. + @param complete The task MUST call the complete method when done. + */ +typedef void (^FIRAuthSerialTask)(FIRAuthSerialTaskCompletionBlock complete); + +/** @class FIRAuthSerialTaskQueue + @brief An easy to use serial task queue which supports a callback-based completion notification + system for easy asyncronous call chaining. + */ +@interface FIRAuthSerialTaskQueue : NSObject + +/** @fn enqueueTask: + @brief Enqueues a task for serial execution in the queue. + @remarks The task MUST call the complete method when done. This method is thread-safe. + The task block won't be executed concurrently with any other blocks in other task queues or + the global work queue as returned by @c FIRAuthGlobalWorkQueue , but an uncompleted task + (e.g. task block finished executation before complete method is called at a later time) + does not affect other task queues or the global work queue. + */ +- (void)enqueueTask:(FIRAuthSerialTask)task; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthSerialTaskQueue.m b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthSerialTaskQueue.m new file mode 100644 index 0000000..78005e0 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthSerialTaskQueue.m @@ -0,0 +1,56 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRAuthSerialTaskQueue.h" + +#import "FIRAuthGlobalWorkQueue.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation FIRAuthSerialTaskQueue { + /** @var _dispatchQueue + @brief The asyncronous dispatch queue into which tasks are enqueued and processed + serially. + */ + dispatch_queue_t _dispatchQueue; +} + +- (instancetype)init { + self = [super init]; + if (self) { + _dispatchQueue = dispatch_queue_create("com.google.firebase.auth.serialTaskQueue", NULL); + dispatch_set_target_queue(_dispatchQueue, FIRAuthGlobalWorkQueue()); + } + return self; +} + +- (void)enqueueTask:(FIRAuthSerialTask)task { + // This dispatch queue will run tasks serially in FIFO order, as long as it's not suspended. + dispatch_async(self->_dispatchQueue, ^{ + // But as soon as a task is started, stop other tasks from running until the task calls it's + // completion handler, which allows the queue to resume processing of tasks. This allows the + // task to perform other asyncronous actions on other dispatch queues and "get back to us" when + // all of their sub-tasks are complete. + dispatch_suspend(self->_dispatchQueue); + task(^{ + dispatch_resume(self->_dispatchQueue); + }); + }); +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthSettings.m b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthSettings.m new file mode 100644 index 0000000..8ed5bb6 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthSettings.m @@ -0,0 +1,33 @@ +/* + * Copyright 2018 Google + * + * 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/LICENSE2.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. + */ + +#import "FIRAuthSettings.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation FIRAuthSettings + +- (instancetype)init { + self = [super init]; + if (self) { + _appVerificationDisabledForTesting = NO; + } + return self; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthTokenResult.m b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthTokenResult.m new file mode 100644 index 0000000..3a06ac6 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthTokenResult.m @@ -0,0 +1,110 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#import "FIRAuthTokenResult_Internal.h" + +NS_ASSUME_NONNULL_BEGIN + +/** @var kExpirationDateKey + @brief The key used to encode the expirationDate property for NSSecureCoding. + */ +static NSString *const kExpirationDateKey = @"expiratinDate"; + +/** @var kTokenKey + @brief The key used to encode the token property for NSSecureCoding. + */ +static NSString *const kTokenKey = @"token"; + +/** @var kAuthDateKey + @brief The key used to encode the authDate property for NSSecureCoding. + */ +static NSString *const kAuthDateKey = @"authDate"; + +/** @var kIssuedDateKey + @brief The key used to encode the issuedDate property for NSSecureCoding. + */ +static NSString *const kIssuedDateKey = @"issuedDate"; + +/** @var kSignInProviderKey + @brief The key used to encode the signInProvider property for NSSecureCoding. + */ +static NSString *const kSignInProviderKey = @"signInProvider"; + +/** @var kClaimsKey + @brief The key used to encode the claims property for NSSecureCoding. + */ +static NSString *const kClaimsKey = @"claims"; + +@implementation FIRAuthTokenResult + +- (instancetype)initWithToken:(NSString *)token + expirationDate:(NSDate *)expirationDate + authDate:(NSDate *)authDate + issuedAtDate:(NSDate *)issuedAtDate + signInProvider:(NSString *)signInProvider + claims:(NSDictionary *)claims { + self = [super init]; + if (self) { + _token = token; + _expirationDate = expirationDate; + _authDate = authDate; + _issuedAtDate = issuedAtDate; + _signInProvider = signInProvider; + _claims = claims; + } + return self; +} + +#pragma mark - NSSecureCoding + ++ (BOOL)supportsSecureCoding { + return YES; +} + +- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder { + NSString *token = + [aDecoder decodeObjectOfClass:[NSDate class] forKey:kTokenKey]; + NSDate *expirationDate = + [aDecoder decodeObjectOfClass:[NSDate class] forKey:kExpirationDateKey]; + NSDate *authDate = + [aDecoder decodeObjectOfClass:[NSDate class] forKey:kAuthDateKey]; + NSDate *issuedAtDate = + [aDecoder decodeObjectOfClass:[NSDate class] forKey:kAuthDateKey]; + NSString *signInProvider = + [aDecoder decodeObjectOfClass:[NSString class] forKey:kSignInProviderKey]; + NSDictionary *claims = + [aDecoder decodeObjectOfClass:[NSDictionary class] forKey:kClaimsKey]; + + return [self initWithToken:token + expirationDate:expirationDate + authDate:authDate + issuedAtDate:issuedAtDate + signInProvider:signInProvider + claims:claims]; +} + +- (void)encodeWithCoder:(NSCoder *)aCoder { + [aCoder encodeObject:_token forKey:kTokenKey]; + [aCoder encodeObject:_expirationDate forKey:kExpirationDateKey]; + [aCoder encodeObject:_authDate forKey:kAuthDateKey]; + [aCoder encodeObject:_issuedAtDate forKey:kIssuedDateKey]; + [aCoder encodeObject:_signInProvider forKey:kSignInProviderKey]; + [aCoder encodeObject:_claims forKey:kClaimsKey]; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthTokenResult_Internal.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthTokenResult_Internal.h new file mode 100644 index 0000000..2914f2a --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthTokenResult_Internal.h @@ -0,0 +1,37 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + + #import + + #import "FIRAuthTokenResult.h" + + NS_ASSUME_NONNULL_BEGIN + +/** @extension FIRAuthAPNSTokenResult + @brief An internal class used to expose internal methods of FIRAuthAPNSTokenResult. + */ +@interface FIRAuthTokenResult () + +- (instancetype)initWithToken:(NSString *)token + expirationDate:(NSDate *)expirationDate + authDate:(NSDate *)authDate + issuedAtDate:(NSDate *)issuedAtDate + signInProvider:(NSString *)signInProvider + claims:(NSDictionary *)claims; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthURLPresenter.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthURLPresenter.h new file mode 100644 index 0000000..a886a3e --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthURLPresenter.h @@ -0,0 +1,64 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +NS_ASSUME_NONNULL_BEGIN + +@protocol FIRAuthUIDelegate; + +/** @typedef FIRAuthURLPresentationCompletion + @brief The type of block invoked when the URLPresentation completes. + @param callbackURL The callback URL if the presentation ends with a matching callback. + @param error The error if the presentation fails to start or ends with an error. + */ +typedef void (^FIRAuthURLPresentationCompletion)(NSURL *_Nullable callbackURL, + NSError *_Nullable error); + +/** @typedef FIRAuthCallbackMatcher + @brief The type of block invoked for checking whether a callback URL matches. + @param callbackURL The callback URL to check for match. + @return Whether or not the specific callback URL matches or not. + */ +typedef BOOL (^FIRAuthURLCallbackMatcher)(NSURL * _Nullable callbackURL); + +/** @class FIRAuthURLPresenter + @brief A Class responsible for presenting URL via SFSafariViewController or UIWebView. + */ +@interface FIRAuthURLPresenter : NSObject + +/** @fn presentURL:UIDelegate:callbackMatcher:completion: + @brief Presents an URL to interact with user. + @param URL The URL to present. + @param UIDelegate The UI delegate to present view controller. + @param completion A block to be called either synchronously if the presentation fails to start, + or asynchronously in future on an unspecified thread once the presentation finishes. + */ +- (void)presentURL:(NSURL *)URL + UIDelegate:(nullable id)UIDelegate + callbackMatcher:(FIRAuthURLCallbackMatcher)callbackMatcher + completion:(FIRAuthURLPresentationCompletion)completion; + +/** @fn canHandleURL: + @brief Determines if a URL was produced by the currently presented URL. + @param URL The URL to handle. + @return Whether the URL could be handled or not. + */ +- (BOOL)canHandleURL:(NSURL *)URL; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthURLPresenter.m b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthURLPresenter.m new file mode 100644 index 0000000..d8e3593 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthURLPresenter.m @@ -0,0 +1,190 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRAuthURLPresenter.h" + +#import + +#import "FIRAuthDefaultUIDelegate.h" +#import "FIRAuthErrorUtils.h" +#import "FIRAuthGlobalWorkQueue.h" +#import "FIRAuthUIDelegate.h" +#import "FIRAuthWebViewController.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface FIRAuthURLPresenter () +@end + +// Disable unguarded availability warnings because SFSafariViewController is been used throughout +// the code, including as an iVar, which cannot be simply excluded by @available check. +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunguarded-availability" + +@implementation FIRAuthURLPresenter { + /** @var _isPresenting + @brief Whether or not some web-based content is being presented. + */ + BOOL _isPresenting; + + /** @var _callbackMatcher + @brief The callback URL matcher for the current presentation, if one is active. + */ + FIRAuthURLCallbackMatcher _Nullable _callbackMatcher; + + /** @var _safariViewController + @brief The SFSafariViewController used for the current presentation, if any. + */ + SFSafariViewController *_Nullable _safariViewController; + + /** @var _webViewController + @brief The FIRAuthWebViewController used for the current presentation, if any. + */ + FIRAuthWebViewController *_Nullable _webViewController; + + /** @var _UIDelegate + @brief The UIDelegate used to present the SFSafariViewController. + */ + id _UIDelegate; + + /** @var _completion + @brief The completion handler for the current presentaion, if one is active. + @remarks This variable is also used as a flag to indicate a presentation is active. + */ + FIRAuthURLPresentationCompletion _Nullable _completion; +} + +- (void)presentURL:(NSURL *)URL + UIDelegate:(nullable id)UIDelegate + callbackMatcher:(FIRAuthURLCallbackMatcher)callbackMatcher + completion:(FIRAuthURLPresentationCompletion)completion { + if (_isPresenting) { + // Unable to start a new presentation on top of another. + _completion(nil, [FIRAuthErrorUtils webContextAlreadyPresentedErrorWithMessage:nil]); + return; + } + _isPresenting = YES; + _callbackMatcher = callbackMatcher; + _completion = completion; + dispatch_async(dispatch_get_main_queue(), ^() { + self->_UIDelegate = UIDelegate ?: [FIRAuthDefaultUIDelegate defaultUIDelegate]; + if ([SFSafariViewController class]) { + self->_safariViewController = [[SFSafariViewController alloc] initWithURL:URL]; + self->_safariViewController.delegate = self; + [self->_UIDelegate presentViewController:self->_safariViewController + animated:YES + completion:nil]; + return; + } else { + self->_webViewController = [[FIRAuthWebViewController alloc] initWithURL:URL delegate:self]; + UINavigationController *navController = + [[UINavigationController alloc] initWithRootViewController:self->_webViewController]; + [self->_UIDelegate presentViewController:navController animated:YES completion:nil]; + } + }); +} + +- (BOOL)canHandleURL:(NSURL *)URL { + if (_isPresenting && _callbackMatcher && _callbackMatcher(URL)) { + [self finishPresentationWithURL:URL error:nil]; + return YES; + } + return NO; +} + +#pragma mark - SFSafariViewControllerDelegate + +- (void)safariViewControllerDidFinish:(SFSafariViewController *)controller { + dispatch_async(FIRAuthGlobalWorkQueue(), ^() { + if (controller == self->_safariViewController) { + self->_safariViewController = nil; + //TODO:Ensure that the SFSafariViewController is actually removed from the screen before + //invoking finishPresentationWithURL:error: + [self finishPresentationWithURL:nil + error:[FIRAuthErrorUtils webContextCancelledErrorWithMessage:nil]]; + } + }); +} + +#pragma mark - FIRAuthwebViewControllerDelegate + +- (BOOL)webViewController:(FIRAuthWebViewController *)webViewController canHandleURL:(NSURL *)URL { + __block BOOL result = NO; + dispatch_sync(FIRAuthGlobalWorkQueue(), ^() { + if (webViewController == self->_webViewController) { + result = [self canHandleURL:URL]; + } + }); + return result; +} + +- (void)webViewControllerDidCancel:(FIRAuthWebViewController *)webViewController { + dispatch_async(FIRAuthGlobalWorkQueue(), ^() { + if (webViewController == self->_webViewController) { + [self finishPresentationWithURL:nil + error:[FIRAuthErrorUtils webContextCancelledErrorWithMessage:nil]]; + } + }); +} + +- (void)webViewController:(FIRAuthWebViewController *)webViewController + didFailWithError:(NSError *)error { + dispatch_async(FIRAuthGlobalWorkQueue(), ^() { + if (webViewController == self->_webViewController) { + [self finishPresentationWithURL:nil error:error]; + } + }); +} + +#pragma mark - Private methods + +/** @fn finishPresentationWithURL:error: + @brief Finishes the presentation for a given URL, if any. + @param URL The URL to finish presenting. + @param error The error with which to finish presenting, if any. + */ +- (void)finishPresentationWithURL:(nullable NSURL *)URL + error:(nullable NSError *)error { + _callbackMatcher = nil; + id UIDelegate = _UIDelegate; + _UIDelegate = nil; + FIRAuthURLPresentationCompletion completion = _completion; + _completion = nil; + void (^finishBlock)(void) = ^() { + self->_isPresenting = NO; + completion(URL, error); + }; + SFSafariViewController *safariViewController = _safariViewController; + _safariViewController = nil; + FIRAuthWebViewController *webViewController = _webViewController; + _webViewController = nil; + if (safariViewController || webViewController) { + dispatch_async(dispatch_get_main_queue(), ^() { + [UIDelegate dismissViewControllerAnimated:YES completion:^() { + dispatch_async(FIRAuthGlobalWorkQueue(), finishBlock); + }]; + }); + } else { + finishBlock(); + } +} + +#pragma clang diagnostic pop // ignored "-Wunguarded-availability" + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthUserDefaultsStorage.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthUserDefaultsStorage.h new file mode 100644 index 0000000..13774ab --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthUserDefaultsStorage.h @@ -0,0 +1,47 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +// This class is only available in the simulator. +#if TARGET_OS_SIMULATOR +#ifndef FIRAUTH_USER_DEFAULTS_STORAGE_AVAILABLE +#define FIRAUTH_USER_DEFAULTS_STORAGE_AVAILABLE 1 +#endif +#endif + +#if FIRAUTH_USER_DEFAULTS_STORAGE_AVAILABLE + +#import "FIRAuthKeychain.h" + +NS_ASSUME_NONNULL_BEGIN + +/** @class FIRAuthUserDefaultsStorage + @brief The utility class to storage data in NSUserDefaults. + */ +@interface FIRAuthUserDefaultsStorage : NSObject + +/** @fn clear + @brief Clears all data from the storage. + @remarks This method is only supposed to be called from tests. + */ +- (void)clear; + +@end + +NS_ASSUME_NONNULL_END + +#endif // FIRAUTH_USER_DEFAULTS_STORAGE_AVAILABLE diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthUserDefaultsStorage.m b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthUserDefaultsStorage.m new file mode 100644 index 0000000..d9f012a --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthUserDefaultsStorage.m @@ -0,0 +1,78 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRAuthUserDefaultsStorage.h" + +#if FIRAUTH_USER_DEFAULTS_STORAGE_AVAILABLE + +NS_ASSUME_NONNULL_BEGIN + +static NSString *const kPersistentDomainNamePrefix = @"com.google.Firebase.Auth."; + +@implementation FIRAuthUserDefaultsStorage { + /** @var _persistentDomainName + @brief The name of the persistent domain in user defaults. + */ + NSString *_persistentDomainName; + + /** @var _storage + @brief The backing NSUserDefaults storage for this instance. + */ + NSUserDefaults *_storage; +} + +- (id)initWithService:(NSString *)service { + self = [super init]; + if (self) { + _persistentDomainName = [kPersistentDomainNamePrefix stringByAppendingString:service]; + _storage = [[NSUserDefaults alloc] init]; + } + return self; +} + +- (nullable NSData *)dataForKey:(NSString *)key error:(NSError **_Nullable)error { + if (error) { + *error = nil; + } + NSDictionary *allData = [_storage persistentDomainForName:_persistentDomainName]; + return allData[key]; +} + +- (BOOL)setData:(NSData *)data forKey:(NSString *)key error:(NSError **_Nullable)error { + NSMutableDictionary *allData = + [([_storage persistentDomainForName:_persistentDomainName] ?: @{}) mutableCopy]; + allData[key] = data; + [_storage setPersistentDomain:allData forName:_persistentDomainName]; + return YES; +} + +- (BOOL)removeDataForKey:(NSString *)key error:(NSError **_Nullable)error { + NSMutableDictionary *allData = + [[_storage persistentDomainForName:_persistentDomainName] mutableCopy]; + [allData removeObjectForKey:key]; + [_storage setPersistentDomain:allData forName:_persistentDomainName]; + return YES; +} + +- (void)clear { + [_storage setPersistentDomain:@{} forName:_persistentDomainName]; +} + +@end + +NS_ASSUME_NONNULL_END + +#endif // FIRAUTH_USER_DEFAULTS_STORAGE_AVAILABLE diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthWebUtils.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthWebUtils.h new file mode 100644 index 0000000..52bf7f4 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthWebUtils.h @@ -0,0 +1,94 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#import + +@class FIRAuthRequestConfiguration; + +NS_ASSUME_NONNULL_BEGIN + +/** @typedef FIRFetchAuthDomainCallback + @brief The callback invoked at the end of the flow to fetch the Auth domain. + @param authDomain The Auth domain. + @param error The error that occurred while fetching the auth domain, if any. + */ +typedef void (^FIRFetchAuthDomainCallback)(NSString *_Nullable authDomain, + NSError *_Nullable error); + +/** @class FIRAuthURLUtils + @brief A utility class used to facilitate the creation of auth related URLs. + */ +@interface FIRAuthWebUtils : NSObject + +/** @fn randomStringWithLength: + @brief Generates a random string of a specified length. + */ ++ (NSString *)randomStringWithLength:(NSUInteger)length; + +/** @fn isCallbackSchemeRegisteredForCustomURLScheme: + @brief Checks whether or not the provided custom URL scheme has been registered by the app. + @param URLScheme The custom URL scheme to be checked against all custom URL schemes registered by the app. + @return whether or not the provided custom URL scheme has been registered by the app. + */ ++ (BOOL)isCallbackSchemeRegisteredForCustomURLScheme:(NSString *)URLScheme; + +/** @fn isExpectedCallbackURL:eventID:authType + @brief Parses a URL into all available query items. + @param URL The actual callback URL. + @param eventID The expected event ID. + @param authType The expected auth type. + @param callbackScheme The expected callback custom scheme. + @return Whether or not the actual callback URL matches the expected callback URL. + */ ++ (BOOL)isExpectedCallbackURL:(nullable NSURL *)URL + eventID:(NSString *)eventID + authType:(NSString *)authType + callbackScheme:(NSString *)callbackScheme; + +/** @fn fetchAuthDomainWithCompletion:completion: + @brief Fetches the auth domain associated with the Firebase Project. + @param completion The callback invoked after the auth domain has been constructed or an error + has been encountered. + */ ++ (void)fetchAuthDomainWithRequestConfiguration:(FIRAuthRequestConfiguration *)requestConfiguration + completion:(FIRFetchAuthDomainCallback)completion; + +/** @fn queryItemValue:from: + @brief Utility function to get a value from a NSURLQueryItem array. + @param name The key. + @param queryList The NSURLQueryItem array. + @return The value for the key. + */ + ++ (nullable NSString *)queryItemValue:(NSString *)name from:(NSArray *)queryList; + +/** @fn dictionaryWithHttpArgumentsString: + @brief Utility function to get a dictionary from a http argument string. + @param argString The http argument string. + @return The resulting dictionary of query arguments. + */ ++ (NSDictionary *)dictionaryWithHttpArgumentsString:(NSString *)argString; + +/** @fn stringByUnescapingFromURLArgument:from: + @brief Utility function to get a string by unescapting URL arguments. + @param argument The argument string. + @return The resulting string after unescaping URL argument. + */ ++ (NSString *)stringByUnescapingFromURLArgument:(NSString *)argument; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthWebUtils.m b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthWebUtils.m new file mode 100644 index 0000000..423d87e --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthWebUtils.m @@ -0,0 +1,173 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#import "FIRAuthWebUtils.h" + +#import "FIRAuthBackend.h" +#import "FIRAuthErrorUtils.h" +#import "FIRGetProjectConfigRequest.h" +#import "FIRGetProjectConfigResponse.h" + +NS_ASSUME_NONNULL_BEGIN + +/** @var kAuthDomainSuffix + @brief The suffix of the auth domain pertiaining to a given Firebase project. + */ +static NSString *const kAuthDomainSuffix = @"firebaseapp.com"; + +@implementation FIRAuthWebUtils + ++ (NSString *)randomStringWithLength:(NSUInteger)length { + NSMutableString *randomString = [[NSMutableString alloc] init]; + for (int i=0; i < length; i++) { + [randomString appendString: + [NSString stringWithFormat:@"%c", 'a' + arc4random_uniform('z' - 'a' + 1)]]; + } + return randomString; +} + ++ (BOOL)isCallbackSchemeRegisteredForCustomURLScheme:(NSString *)URLScheme { + NSString *expectedCustomScheme = [URLScheme lowercaseString]; + NSArray *urlTypes = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleURLTypes"]; + for (NSDictionary *urlType in urlTypes) { + NSArray *urlTypeSchemes = urlType[@"CFBundleURLSchemes"]; + for (NSString *urlTypeScheme in urlTypeSchemes) { + if ([urlTypeScheme.lowercaseString isEqualToString:expectedCustomScheme]) { + return YES; + } + } + } + return NO; +} + ++ (BOOL)isExpectedCallbackURL:(nullable NSURL *)URL + eventID:(NSString *)eventID + authType:(NSString *)authType + callbackScheme:(NSString *)callbackScheme { + if (!URL) { + return NO; + } + NSURLComponents *actualURLComponents = + [NSURLComponents componentsWithURL:URL resolvingAgainstBaseURL:NO]; + actualURLComponents.query = nil; + actualURLComponents.fragment = nil; + + NSURLComponents *expectedURLComponents = [[NSURLComponents alloc] init]; + expectedURLComponents.scheme = callbackScheme; + expectedURLComponents.host = @"firebaseauth"; + expectedURLComponents.path = @"/link"; + + if (![expectedURLComponents.URL isEqual:actualURLComponents.URL]) { + return NO; + } + NSDictionary *URLQueryItems = + [self dictionaryWithHttpArgumentsString:URL.query]; + NSURL *deeplinkURL = [NSURL URLWithString:URLQueryItems[@"deep_link_id"]]; + NSDictionary *deeplinkQueryItems = + [self dictionaryWithHttpArgumentsString:deeplinkURL.query]; + if ([deeplinkQueryItems[@"authType"] isEqualToString:authType] && + [deeplinkQueryItems[@"eventId"] isEqualToString:eventID]) { + return YES; + } + return NO; +} + ++ (void)fetchAuthDomainWithRequestConfiguration:(FIRAuthRequestConfiguration *)requestConfiguration + completion:(FIRFetchAuthDomainCallback)completion { + FIRGetProjectConfigRequest *request = + [[FIRGetProjectConfigRequest alloc] initWithRequestConfiguration:requestConfiguration]; + + [FIRAuthBackend getProjectConfig:request + callback:^(FIRGetProjectConfigResponse *_Nullable response, + NSError *_Nullable error) { + if (error) { + completion(nil, error); + return; + } + NSString *authDomain; + for (NSString *domain in response.authorizedDomains) { + NSInteger index = domain.length - kAuthDomainSuffix.length; + if (index >= 2) { + if ([domain hasSuffix:kAuthDomainSuffix] && domain.length >= kAuthDomainSuffix.length + 2) { + authDomain = domain; + break; + } + } + } + if (!authDomain.length) { + completion(nil, [FIRAuthErrorUtils unexpectedErrorResponseWithDeserializedResponse:response]); + return; + } + completion(authDomain, nil); + }]; +} + +/** @fn queryItemValue:from: + @brief Utility function to get a value from a NSURLQueryItem array. + @param name The key. + @param queryList The NSURLQueryItem array. + @return The value for the key. + */ ++ (nullable NSString *)queryItemValue:(NSString *)name from:(NSArray *)queryList { + for (NSURLQueryItem *item in queryList) { + if ([item.name isEqualToString:name]) { + return item.value; + } + } + return nil; +} + ++ (NSDictionary *)dictionaryWithHttpArgumentsString:(NSString *)argString { + NSMutableDictionary* ret = [NSMutableDictionary dictionary]; + NSArray* components = [argString componentsSeparatedByString:@"&"]; + NSString* component; + // Use reverse order so that the first occurrence of a key replaces + // those subsequent. + for (component in [components reverseObjectEnumerator]) { + if (component.length == 0) + continue; + NSRange pos = [component rangeOfString:@"="]; + NSString *key; + NSString *val; + if (pos.location == NSNotFound) { + key = [self stringByUnescapingFromURLArgument:component]; + val = @""; + } else { + key = [self stringByUnescapingFromURLArgument:[component substringToIndex:pos.location]]; + val = [self stringByUnescapingFromURLArgument: + [component substringFromIndex:pos.location + pos.length]]; + } + // returns nil on invalid UTF8 and NSMutableDictionary raises an exception when passed nil + // values. + if (!key) key = @""; + if (!val) val = @""; + [ret setObject:val forKey:key]; + } + return ret; +} + ++ (NSString *)stringByUnescapingFromURLArgument:(NSString *)argument { + NSMutableString *resultString = [NSMutableString stringWithString:argument]; + [resultString replaceOccurrencesOfString:@"+" + withString:@" " + options:NSLiteralSearch + range:NSMakeRange(0, [resultString length])]; + return [resultString stringByRemovingPercentEncoding]; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthWebView.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthWebView.h new file mode 100644 index 0000000..28af833 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthWebView.h @@ -0,0 +1,38 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** @class FIRAuthWebView + @brief A class reponsible for creating a UIWebview for use within Firebase Auth. + */ +@interface FIRAuthWebView : UIView + +/** @property webView + * @brief The web view. + */ +@property(nonatomic, weak) UIWebView *webView; + +/** @property spinner + * @brief The spinner that indicates web view loading. + */ +@property(nonatomic, weak) UIActivityIndicatorView *spinner; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthWebView.m b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthWebView.m new file mode 100644 index 0000000..80b90f0 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthWebView.m @@ -0,0 +1,86 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRAuthWebView.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation FIRAuthWebView + +- (instancetype)initWithFrame:(CGRect)frame { + self = [super initWithFrame:frame]; + if (self) { + self.backgroundColor = [UIColor whiteColor]; + [self initializeSubviews]; + } + return self; +} + +/** @fn initializeSubviews + @brief Initializes the subviews of this view. + */ +- (void)initializeSubviews { + UIWebView *webView = [self createWebView]; + UIActivityIndicatorView *spinner = [self createSpinner]; + + // The order of the following controls z-order. + [self addSubview:webView]; + [self addSubview:spinner]; + + [self layoutSubviews]; + _webView = webView; + _spinner = spinner; +} + +- (void)layoutSubviews { + CGFloat height = self.bounds.size.height; + CGFloat width = self.bounds.size.width; + _webView.frame = CGRectMake(0, 0, width, height); + _spinner.center = _webView.center; +} + +/** @fn createWebView + @brief Creates a web view to be used by this view. + @return The newly created web view. + */ +- (UIWebView *)createWebView { + UIWebView *webView = [[UIWebView alloc] initWithFrame:CGRectZero]; + // Trickery to make the web view not do weird things (like showing a black background when + // the prompt in the navigation bar animates changes.) + webView.opaque = NO; + webView.backgroundColor = [UIColor clearColor]; + webView.scrollView.opaque = NO; + webView.scrollView.backgroundColor = [UIColor clearColor]; + webView.scrollView.bounces = NO; + webView.scrollView.alwaysBounceVertical = NO; + webView.scrollView.alwaysBounceHorizontal = NO; + return webView; +} + +/** @fn createSpinner + @brief Creates a spinner to be used by this view. + @return The newly created spinner. + */ +- (UIActivityIndicatorView *)createSpinner { + UIActivityIndicatorViewStyle spinnerStyle = UIActivityIndicatorViewStyleGray; + UIActivityIndicatorView *spinner = + [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:spinnerStyle]; + return spinner; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthWebViewController.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthWebViewController.h new file mode 100644 index 0000000..4bf9678 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthWebViewController.h @@ -0,0 +1,73 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +@class FIRAuthWebViewController; + +NS_ASSUME_NONNULL_BEGIN + +/** @protocol FIRAuthWebViewControllerDelegate + @brief Defines a delegate for FIRAuthWebViewController + */ +@protocol FIRAuthWebViewControllerDelegate + +/** @fn webViewController:canHandleURL: + @brief Determines if a URL should be handled by the delegate. + @param URL The URL to handle. + @return Whether the URL could be handled or not. + */ +- (BOOL)webViewController:(FIRAuthWebViewController *)webViewController canHandleURL:(NSURL *)URL; + +/** @fn webViewControllerDidCancel: + @brief Notifies the delegate that the web view controller is being cancelled by the user. + @param webViewController The web view controller in question. + */ +- (void)webViewControllerDidCancel:(FIRAuthWebViewController *)webViewController; + +/** @fn webViewController:didFailWithError: + @brief Notifies the delegate that the web view controller failed to load a page. + @param webViewController The web view controller in question. + @param error The error that has occurred. + */ +- (void)webViewController:(FIRAuthWebViewController *)webViewController + didFailWithError:(NSError *)error; + +@end + +/** @class FIRAuthWebViewController + @brief Reponsible for creating a UIViewController for presenting a FIRAutWebView. + */ +@interface FIRAuthWebViewController : UIViewController + +/** @fn initWithNibName:bundle: + * @brief Please call initWithURL:delegate: + */ +- (instancetype)initWithNibName:(nullable NSString *)nibNameOrNil + bundle:(nullable NSBundle *)nibBundleOrNil NS_UNAVAILABLE; + +/** @fn initWithCoder: + * @brief Please call initWithURL:delegate: + */ +- (instancetype)initWithCoder:(NSCoder *)aDecoder NS_UNAVAILABLE; + +- (instancetype)initWithURL:(NSURL *)URL + delegate:(__weak id)delegate + NS_DESIGNATED_INITIALIZER; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthWebViewController.m b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthWebViewController.m new file mode 100644 index 0000000..a3ab06a --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuthWebViewController.m @@ -0,0 +1,111 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRAuthWebViewController.h" + +#import "FIRAuthWebView.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface FIRAuthWebViewController () +@end + +@implementation FIRAuthWebViewController { + /** @var _URL + @brief The initial URL to display. + */ + NSURL *_URL; + + /** @var _delegate + @brief The delegate to call. + */ + __weak id _delegate; + + /** @var _webView; + @brief The web view instance for easier access. + */ + __weak FIRAuthWebView *_webView; +} + +- (instancetype)initWithURL:(NSURL *)URL + delegate:(__weak id)delegate { + self = [super initWithNibName:nil bundle:nil]; + if (self) { + _URL = URL; + _delegate = delegate; + } + return self; +} + +#pragma mark - Lifecycle + +- (void)loadView { + FIRAuthWebView *webView = [[FIRAuthWebView alloc] initWithFrame:[UIScreen mainScreen].bounds]; + webView.webView.delegate = self; + self.view = webView; + _webView = webView; + self.navigationItem.leftBarButtonItem = + [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel + target:self + action:@selector(cancel)]; +} + +- (void)viewDidAppear:(BOOL)animated { + [super viewDidAppear:animated]; + + // Loads the requested URL in the web view. + [_webView.webView loadRequest:[NSURLRequest requestWithURL:_URL]]; +} + +#pragma mark - UI Targets + +- (void)cancel { + [_delegate webViewControllerDidCancel:self]; +} + +#pragma mark - UIWebViewDelegate + +- (BOOL)webView:(UIWebView *)webView + shouldStartLoadWithRequest:(NSURLRequest *)request + navigationType:(UIWebViewNavigationType)navigationType { + return ![_delegate webViewController:self canHandleURL:request.URL]; +} + +- (void)webViewDidStartLoad:(UIWebView *)webView { + // Show & animate the activity indicator. + _webView.spinner.hidden = NO; + [_webView.spinner startAnimating]; +} + +- (void)webViewDidFinishLoad:(UIWebView *)webView { + // Hide & stop the activity indicator. + _webView.spinner.hidden = YES; + [_webView.spinner stopAnimating]; +} + +- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error { + if ([error.domain isEqualToString:NSURLErrorDomain] && error.code == NSURLErrorCancelled) { + // It's okay for the page to be redirected before it is completely loaded. See b/32028062 . + return; + } + // Forward notification to our delegate. + [self webViewDidFinishLoad:webView]; + [_delegate webViewController:self didFailWithError:error]; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuth_Internal.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuth_Internal.h new file mode 100644 index 0000000..ce01224 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRAuth_Internal.h @@ -0,0 +1,122 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +#import "FIRAuth.h" + +#import + +@class FIRAuthRequestConfiguration; +@class FIRAuthURLPresenter; + +#if TARGET_OS_IOS +@class FIRAuthAPNSTokenManager; +@class FIRAuthAppCredentialManager; +@class FIRAuthNotificationManager; +#endif + +NS_ASSUME_NONNULL_BEGIN + +@interface FIRAuth () + +/** @property requestConfiguration + @brief The configuration object comprising of paramters needed to make a request to Firebase + Auth's backend. + */ +@property(nonatomic, copy, readonly) FIRAuthRequestConfiguration *requestConfiguration; + +#if TARGET_OS_IOS + +/** @property tokenManager + @brief The manager for APNs tokens used by phone number auth. + */ +@property(nonatomic, strong, readonly) FIRAuthAPNSTokenManager *tokenManager; + +/** @property appCredentailManager + @brief The manager for app credentials used by phone number auth. + */ +@property(nonatomic, strong, readonly) FIRAuthAppCredentialManager *appCredentialManager; + +/** @property notificationManager + @brief The manager for remote notifications used by phone number auth. + */ +@property(nonatomic, strong, readonly) FIRAuthNotificationManager *notificationManager; + +#endif // TARGET_OS_IOS + +/** @property authURLPresenter + @brief An object that takes care of presenting URLs via the auth instance. + */ +@property(nonatomic, strong, readonly) FIRAuthURLPresenter *authURLPresenter; + +/** @fn initWithAPIKey:appName: + @brief Designated initializer. + @param APIKey The Google Developers Console API key for making requests from your app. + @param appName The name property of the previously created @c FIRApp instance. + */ +- (nullable instancetype)initWithAPIKey:(NSString *)APIKey + appName:(NSString *)appName NS_DESIGNATED_INITIALIZER; + +/** @fn getUserID + @brief Gets the identifier of the current user, if any. + @return The identifier of the current user, or nil if there is no current user. + */ +- (nullable NSString *)getUserID; + +/** @fn updateKeychainWithUser:error: + @brief Updates the keychain for the given user. + @param user The user to be updated. + @param error The error caused the method to fail if the method returns NO. + @return Whether updating keychain has succeeded or not. + @remarks Called by @c FIRUser when user info or token changes occur. + */ +- (BOOL)updateKeychainWithUser:(FIRUser *)user error:(NSError *_Nullable *_Nullable)error; + +/** @fn internalSignInWithCredential:callback: + @brief Convenience method for @c internalSignInAndRetrieveDataWithCredential:callback: + This method doesn't return additional identity provider data. +*/ +- (void)internalSignInWithCredential:(FIRAuthCredential *)credential + callback:(FIRAuthResultCallback)callback; + +/** @fn internalSignInAndRetrieveDataWithCredential:callback: + @brief Asynchronously signs in Firebase with the given 3rd party credentials (e.g. a Facebook + login Access Token, a Google ID Token/Access Token pair, etc.) and returns additional + identity provider data. + @param credential The credential supplied by the IdP. + @param isReauthentication Indicates whether or not the current invocation originated from an + attempt to reauthenticate. + @param callback A block which is invoked when the sign in finishes (or is cancelled.) Invoked + asynchronously on the auth global work queue in the future. + @remarks This is the internal counterpart of this method, which uses a callback that does not + update the current user. + */ +- (void)internalSignInAndRetrieveDataWithCredential:(FIRAuthCredential *)credential + isReauthentication:(BOOL)isReauthentication + callback:(nullable FIRAuthDataResultCallback)callback; + +/** @fn signOutByForceWithUserID:error: + @brief Signs out the current user. + @param userID The ID of the user to force sign out. + @param error An optional out parameter for error results. + @return @YES when the sign out request was successful. @NO otherwise. + */ +- (BOOL)signOutByForceWithUserID:(NSString *)userID error:(NSError *_Nullable *_Nullable)error; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRSecureTokenService.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRSecureTokenService.h new file mode 100644 index 0000000..989e786 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRSecureTokenService.h @@ -0,0 +1,99 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +@class FIRAuthRequestConfiguration; + +NS_ASSUME_NONNULL_BEGIN + +/** @typedef FIRFetchAccessTokenCallback + @brief The callback used to return the value of attempting to fetch an access token. + + In the event the operation was successful @c token will be set and @c error will be @c nil. + In the event of failure @c token will be @c nil and @c error will be set. + @c tokenUpdated indicates whether either the access or the refresh token has been updated. + + The token returned should be considered ephemeral and not cached. It should be used immediately + and discarded. All operations that need this token should call fetchAccessToken and do their + work from the callback. + */ +typedef void(^FIRFetchAccessTokenCallback)(NSString *_Nullable token, + NSError *_Nullable error, + BOOL tokenUpdated); + +/** @class FIRSecureTokenService + @brief Provides services for token exchanges and refreshes. + */ +@interface FIRSecureTokenService : NSObject + +/** @property requestConfiguration + @brief The configuration for making requests to server. + */ +@property(nonatomic, strong) FIRAuthRequestConfiguration *requestConfiguration; + +/** @property rawAccessToken + @brief The cached access token. + @remarks This method is specifically for providing the access token to internal clients during + deserialization and sign-in events, and should not be used to retrieve the access token by + anyone else. + */ +@property(nonatomic, copy, readonly) NSString *rawAccessToken; + +/** @property refreshToken + @brief The refresh token for the user, or @c nil if the user has yet completed sign-in flow. + @remarks This property needs to be set manually after the instance is decoded from archive. + */ +@property(nonatomic, copy, readonly, nullable) NSString *refreshToken; + +/** @property accessTokenExpirationDate + @brief The expiration date of the cached access token. + */ +@property(nonatomic, copy, readonly, nullable) NSDate *accessTokenExpirationDate; + +/** @fn initWithRequestConfiguration:authorizationCode: + @brief Creates a @c FIRSecureTokenService with an authroization code. + @param requestConfiguration The configuration for making requests to server. + @param authorizationCode An authorization code which needs to be exchanged for STS tokens. + */ +- (instancetype)initWithRequestConfiguration:(FIRAuthRequestConfiguration *)requestConfiguration + authorizationCode:(NSString *)authorizationCode; + +/** @fn initWithRequestConfiguration:accessToken:accessTokenExpirationDate:refreshToken + @brief Creates a @c FIRSecureTokenService with access and refresh tokens. + @param requestConfiguration The configuration for making requests to server. + @param accessToken The STS access token. + @param accessTokenExpirationDate The approximate expiration date of the access token. + @param refreshToken The STS refresh token. + */ +- (instancetype)initWithRequestConfiguration:(FIRAuthRequestConfiguration *)requestConfiguration + accessToken:(nullable NSString *)accessToken + accessTokenExpirationDate:(nullable NSDate *)accessTokenExpirationDate + refreshToken:(NSString *)refreshToken; + +/** @fn fetchAccessTokenForcingRefresh:callback: + @brief Fetch a fresh ephemeral access token for the ID associated with this instance. The token + received in the callback should be considered short lived and not cached. + @param forceRefresh Forces the token to be refreshed. + @param callback Callback block that will be called to return either the token or an error. + Invoked asyncronously on the auth global work queue in the future. + */ +- (void)fetchAccessTokenForcingRefresh:(BOOL)forceRefresh + callback:(FIRFetchAccessTokenCallback)callback; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRSecureTokenService.m b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRSecureTokenService.m new file mode 100644 index 0000000..cf625b4 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRSecureTokenService.m @@ -0,0 +1,210 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRSecureTokenService.h" + +#import "FIRAuth.h" +#import "FIRAuthKeychain.h" +#import "FIRAuthSerialTaskQueue.h" +#import "FIRAuthBackend.h" +#import "FIRAuthRequestConfiguration.h" +#import "FIRSecureTokenRequest.h" +#import "FIRSecureTokenResponse.h" + +NS_ASSUME_NONNULL_BEGIN + +/** @var kAPIKeyCodingKey + @brief The key used to encode the APIKey for NSSecureCoding. + */ +static NSString *const kAPIKeyCodingKey = @"APIKey"; + +/** @var kRefreshTokenKey + @brief The key used to encode the refresh token for NSSecureCoding. + */ +static NSString *const kRefreshTokenKey = @"refreshToken"; + +/** @var kAccessTokenKey + @brief The key used to encode the access token for NSSecureCoding. + */ +static NSString *const kAccessTokenKey = @"accessToken"; + +/** @var kAccessTokenExpirationDateKey + @brief The key used to encode the access token expiration date for NSSecureCoding. + */ +static NSString *const kAccessTokenExpirationDateKey = @"accessTokenExpirationDate"; + +/** @var kFiveMinutes + @brief Five minutes (in seconds.) + */ +static const NSTimeInterval kFiveMinutes = 5 * 60; + +@interface FIRSecureTokenService () +- (instancetype)init NS_DESIGNATED_INITIALIZER; +@end + +@implementation FIRSecureTokenService { + /** @var _taskQueue + @brief Used to serialize all requests for access tokens. + */ + FIRAuthSerialTaskQueue *_taskQueue; + + /** @var _authorizationCode + @brief An authorization code which needs to be exchanged for Secure Token Service tokens. + */ + NSString *_Nullable _authorizationCode; + + /** @var _accessToken + @brief The currently cached access token. Or |nil| if no token is currently cached. + */ + NSString *_Nullable _accessToken; +} + +- (instancetype)init { + self = [super init]; + if (self) { + _taskQueue = [[FIRAuthSerialTaskQueue alloc] init]; + } + return self; +} + +- (instancetype)initWithRequestConfiguration:(FIRAuthRequestConfiguration *)requestConfiguration + authorizationCode:(NSString *)authorizationCode { + self = [self init]; + if (self) { + _requestConfiguration = requestConfiguration; + _authorizationCode = [authorizationCode copy]; + } + return self; +} + +- (instancetype)initWithRequestConfiguration:(FIRAuthRequestConfiguration *)requestConfiguration + accessToken:(nullable NSString *)accessToken + accessTokenExpirationDate:(nullable NSDate *)accessTokenExpirationDate + refreshToken:(NSString *)refreshToken { + self = [self init]; + if (self) { + _requestConfiguration = requestConfiguration; + _accessToken = [accessToken copy]; + _accessTokenExpirationDate = [accessTokenExpirationDate copy]; + _refreshToken = [refreshToken copy]; + } + return self; +} + +- (void)fetchAccessTokenForcingRefresh:(BOOL)forceRefresh + callback:(FIRFetchAccessTokenCallback)callback { + [_taskQueue enqueueTask:^(FIRAuthSerialTaskCompletionBlock complete) { + if (!forceRefresh && [self hasValidAccessToken]) { + complete(); + callback(self->_accessToken, nil, NO); + } else { + [self requestAccessToken:^(NSString *_Nullable token, + NSError *_Nullable error, + BOOL tokenUpdated) { + complete(); + callback(token, error, tokenUpdated); + }]; + } + }]; +} + +- (NSString *)rawAccessToken { + return _accessToken; +} + +#pragma mark - NSSecureCoding + ++ (BOOL)supportsSecureCoding { + return YES; +} + +- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder { + NSString *refreshToken = [aDecoder decodeObjectOfClass:[NSString class] forKey:kRefreshTokenKey]; + NSString *accessToken = [aDecoder decodeObjectOfClass:[NSString class] forKey:kAccessTokenKey]; + NSDate *accessTokenExpirationDate = + [aDecoder decodeObjectOfClass:[NSDate class] forKey:kAccessTokenExpirationDateKey]; + if (!refreshToken) { + return nil; + } + self = [self init]; + if (self) { + _refreshToken = refreshToken; + _accessToken = accessToken; + _accessTokenExpirationDate = accessTokenExpirationDate; + } + return self; +} + +- (void)encodeWithCoder:(NSCoder *)aCoder { + // The API key is encoded even it is not used in decoding to be compatible with previous versions + // of the library. + [aCoder encodeObject:_requestConfiguration.APIKey forKey:kAPIKeyCodingKey]; + // Authorization code is not encoded because it is not long-lived. + [aCoder encodeObject:_refreshToken forKey:kRefreshTokenKey]; + [aCoder encodeObject:_accessToken forKey:kAccessTokenKey]; + [aCoder encodeObject:_accessTokenExpirationDate forKey:kAccessTokenExpirationDateKey]; +} + +#pragma mark - Private methods + +/** @fn requestAccessToken: + @brief Makes a request to STS for an access token. + @details This handles both the case that the token has not been granted yet and that it just + needs to be refreshed. The caller is responsible for making sure that this is occurring in + a @c _taskQueue task. + @param callback Called when the fetch is complete. Invoked asynchronously on the main thread in + the future. + @remarks Because this method is guaranteed to only be called from tasks enqueued in + @c _taskQueue, we do not need any @synchronized guards around access to _accessToken/etc. + since only one of those tasks is ever running at a time, and those tasks are the only + access to and mutation of these instance variables. + */ +- (void)requestAccessToken:(FIRFetchAccessTokenCallback)callback { + FIRSecureTokenRequest *request; + if (_refreshToken.length) { + request = [FIRSecureTokenRequest refreshRequestWithRefreshToken:_refreshToken + requestConfiguration:_requestConfiguration]; + } else { + request = [FIRSecureTokenRequest authCodeRequestWithCode:_authorizationCode + requestConfiguration:_requestConfiguration]; + } + [FIRAuthBackend secureToken:request + callback:^(FIRSecureTokenResponse *_Nullable response, + NSError *_Nullable error) { + BOOL tokenUpdated = NO; + NSString *newAccessToken = response.accessToken; + if (newAccessToken.length && ![newAccessToken isEqualToString:self->_accessToken]) { + self->_accessToken = [newAccessToken copy]; + self->_accessTokenExpirationDate = response.approximateExpirationDate; + tokenUpdated = YES; + } + NSString *newRefreshToken = response.refreshToken; + if (newRefreshToken.length && + ![newRefreshToken isEqualToString:self->_refreshToken]) { + self->_refreshToken = [newRefreshToken copy]; + tokenUpdated = YES; + } + callback(newAccessToken, error, tokenUpdated); + }]; +} + +- (BOOL)hasValidAccessToken { + return _accessToken && [_accessTokenExpirationDate timeIntervalSinceNow] > kFiveMinutes; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRUser.m b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRUser.m new file mode 100644 index 0000000..9989614 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRUser.m @@ -0,0 +1,1452 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRUser_Internal.h" + +#import + +#import "FIRAdditionalUserInfo_Internal.h" +#import "FIRAuth.h" +#import "FIRAuthCredential_Internal.h" +#import "FIRAuthDataResult_Internal.h" +#import "FIRAuthErrorUtils.h" +#import "FIRAuthGlobalWorkQueue.h" +#import "FIRAuthSerialTaskQueue.h" +#import "FIRAuthOperationType.h" +#import "FIRAuth_Internal.h" +#import "FIRAuthBackend.h" +#import "FIRAuthRequestConfiguration.h" +#import "FIRAuthTokenResult_Internal.h" +#import "FIRDeleteAccountRequest.h" +#import "FIRDeleteAccountResponse.h" +#import "FIREmailAuthProvider.h" +#import "FIREmailPasswordAuthCredential.h" +#import "FIRGameCenterAuthCredential.h" +#import "FIRGetAccountInfoRequest.h" +#import "FIRGetAccountInfoResponse.h" +#import "FIRGetOOBConfirmationCodeRequest.h" +#import "FIRGetOOBConfirmationCodeResponse.h" +#import "FIRSecureTokenService.h" +#import "FIRSetAccountInfoRequest.h" +#import "FIRSetAccountInfoResponse.h" +#import "FIRSignInWithGameCenterRequest.h" +#import "FIRSignInWithGameCenterResponse.h" +#import "FIRUserInfoImpl.h" +#import "FIRUserMetadata_Internal.h" +#import "FIRVerifyAssertionRequest.h" +#import "FIRVerifyAssertionResponse.h" +#import "FIRVerifyCustomTokenRequest.h" +#import "FIRVerifyCustomTokenResponse.h" +#import "FIRVerifyPasswordRequest.h" +#import "FIRVerifyPasswordResponse.h" +#import "FIRVerifyPhoneNumberRequest.h" +#import "FIRVerifyPhoneNumberResponse.h" + +#if TARGET_OS_IOS +#import "FIRPhoneAuthProvider.h" +#import "AuthProviders/Phone/FIRPhoneAuthCredential_Internal.h" +#endif + +NS_ASSUME_NONNULL_BEGIN + +/** @var kUserIDCodingKey + @brief The key used to encode the user ID for NSSecureCoding. + */ +static NSString *const kUserIDCodingKey = @"userID"; + +/** @var kHasEmailPasswordCredentialCodingKey + @brief The key used to encode the hasEmailPasswordCredential property for NSSecureCoding. + */ +static NSString *const kHasEmailPasswordCredentialCodingKey = @"hasEmailPassword"; + +/** @var kAnonymousCodingKey + @brief The key used to encode the anonymous property for NSSecureCoding. + */ +static NSString *const kAnonymousCodingKey = @"anonymous"; + +/** @var kEmailCodingKey + @brief The key used to encode the email property for NSSecureCoding. + */ +static NSString *const kEmailCodingKey = @"email"; + +/** @var kPhoneNumberCodingKey + @brief The key used to encode the phoneNumber property for NSSecureCoding. + */ +static NSString *const kPhoneNumberCodingKey = @"phoneNumber"; + +/** @var kEmailVerifiedCodingKey + @brief The key used to encode the isEmailVerified property for NSSecureCoding. + */ +static NSString *const kEmailVerifiedCodingKey = @"emailVerified"; + +/** @var kDisplayNameCodingKey + @brief The key used to encode the displayName property for NSSecureCoding. + */ +static NSString *const kDisplayNameCodingKey = @"displayName"; + +/** @var kPhotoURLCodingKey + @brief The key used to encode the photoURL property for NSSecureCoding. + */ +static NSString *const kPhotoURLCodingKey = @"photoURL"; + +/** @var kProviderDataKey + @brief The key used to encode the providerData instance variable for NSSecureCoding. + */ +static NSString *const kProviderDataKey = @"providerData"; + +/** @var kAPIKeyCodingKey + @brief The key used to encode the APIKey instance variable for NSSecureCoding. + */ +static NSString *const kAPIKeyCodingKey = @"APIKey"; + +/** @var kTokenServiceCodingKey + @brief The key used to encode the tokenService instance variable for NSSecureCoding. + */ +static NSString *const kTokenServiceCodingKey = @"tokenService"; + +/** @var kMetadataCodingKey + @brief The key used to encode the metadata instance variable for NSSecureCoding. + */ +static NSString *const kMetadataCodingKey = @"metadata"; + +/** @var kMissingUsersErrorMessage + @brief The error message when there is no users array in the getAccountInfo response. + */ +static NSString *const kMissingUsersErrorMessage = @"users"; + +/** @typedef CallbackWithError + @brief The type for a callback block that only takes an error parameter. + */ +typedef void (^CallbackWithError)(NSError *_Nullable); + +/** @typedef CallbackWithUserAndError + @brief The type for a callback block that takes a user parameter and an error parameter. + */ +typedef void (^CallbackWithUserAndError)(FIRUser *_Nullable, NSError *_Nullable); + +/** @typedef CallbackWithUserAndError + @brief The type for a callback block that takes a user parameter and an error parameter. + */ +typedef void (^CallbackWithAuthDataResultAndError)(FIRAuthDataResult *_Nullable, + NSError *_Nullable); + +/** @var kMissingPasswordReason + @brief The reason why the @c FIRAuthErrorCodeWeakPassword error is thrown. + @remarks This error message will be localized in the future. + */ +static NSString *const kMissingPasswordReason = @"Missing Password"; + +/** @fn callInMainThreadWithError + @brief Calls a callback in main thread with error. + @param callback The callback to be called in main thread. + @param error The error to pass to callback. + */ +static void callInMainThreadWithError(_Nullable CallbackWithError callback, + NSError *_Nullable error) { + if (callback) { + dispatch_async(dispatch_get_main_queue(), ^{ + callback(error); + }); + } +} + +/** @fn callInMainThreadWithUserAndError + @brief Calls a callback in main thread with user and error. + @param callback The callback to be called in main thread. + @param user The user to pass to callback if there is no error. + @param error The error to pass to callback. + */ +static void callInMainThreadWithUserAndError(_Nullable CallbackWithUserAndError callback, + FIRUser *_Nonnull user, + NSError *_Nullable error) { + if (callback) { + dispatch_async(dispatch_get_main_queue(), ^{ + callback(error ? nil : user, error); + }); + } +} + +/** @fn callInMainThreadWithUserAndError + @brief Calls a callback in main thread with user and error. + @param callback The callback to be called in main thread. + @param result The result to pass to callback if there is no error. + @param error The error to pass to callback. + */ +static void callInMainThreadWithAuthDataResultAndError( + _Nullable CallbackWithAuthDataResultAndError callback, + FIRAuthDataResult *_Nullable result, + NSError *_Nullable error) { + if (callback) { + dispatch_async(dispatch_get_main_queue(), ^{ + callback(result, error); + }); + } +} + +@interface FIRUserProfileChangeRequest () + +/** @fn initWithUser: + @brief Designated initializer. + @param user The user for which we are updating profile information. + */ +- (nullable instancetype)initWithUser:(FIRUser *)user NS_DESIGNATED_INITIALIZER; + +@end + +@interface FIRUser () + +/** @property anonymous + @brief Whether the current user is anonymous. + */ +@property(nonatomic, readwrite) BOOL anonymous; + +@end + +@implementation FIRUser { + /** @var _hasEmailPasswordCredential + @brief Whether or not the user can be authenticated by using Firebase email and password. + */ + BOOL _hasEmailPasswordCredential; + + /** @var _providerData + @brief Provider specific user data. + */ + NSDictionary *_providerData; + + /** @var _taskQueue + @brief Used to serialize the update profile calls. + */ + FIRAuthSerialTaskQueue *_taskQueue; + + /** @var _tokenService + @brief A secure token service associated with this user. For performing token exchanges and + refreshing access tokens. + */ + FIRSecureTokenService *_tokenService; +} + +#pragma mark - Properties + +// Explicitly @synthesize because these properties are defined in FIRUserInfo protocol. +@synthesize uid = _userID; +@synthesize displayName = _displayName; +@synthesize photoURL = _photoURL; +@synthesize email = _email; +@synthesize phoneNumber = _phoneNumber; + +#pragma mark - + ++ (void)retrieveUserWithAuth:(FIRAuth *)auth + accessToken:(nullable NSString *)accessToken + accessTokenExpirationDate:(nullable NSDate *)accessTokenExpirationDate + refreshToken:(nullable NSString *)refreshToken + anonymous:(BOOL)anonymous + callback:(FIRRetrieveUserCallback)callback { + FIRSecureTokenService *tokenService = + [[FIRSecureTokenService alloc] initWithRequestConfiguration:auth.requestConfiguration + accessToken:accessToken + accessTokenExpirationDate:accessTokenExpirationDate + refreshToken:refreshToken]; + FIRUser *user = [[self alloc] initWithTokenService:tokenService]; + user.auth = auth; + user.requestConfiguration = auth.requestConfiguration; + [user internalGetTokenWithCallback:^(NSString *_Nullable accessToken, NSError *_Nullable error) { + if (error) { + callback(nil, error); + return; + } + FIRGetAccountInfoRequest *getAccountInfoRequest = + [[FIRGetAccountInfoRequest alloc] initWithAccessToken:accessToken + requestConfiguration:auth.requestConfiguration]; + [FIRAuthBackend getAccountInfo:getAccountInfoRequest + callback:^(FIRGetAccountInfoResponse *_Nullable response, + NSError *_Nullable error) { + if (error) { + // No need to sign out user here for errors because the user hasn't been signed in yet. + callback(nil, error); + return; + } + user.anonymous = anonymous; + [user updateWithGetAccountInfoResponse:response]; + callback(user, nil); + }]; + }]; +} + +- (instancetype)initWithTokenService:(FIRSecureTokenService *)tokenService { + self = [super init]; + if (self) { + _providerData = @{ }; + _taskQueue = [[FIRAuthSerialTaskQueue alloc] init]; + _tokenService = tokenService; + } + return self; +} + +#pragma mark - NSSecureCoding + ++ (BOOL)supportsSecureCoding { + return YES; +} + +- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder { + NSString *userID = [aDecoder decodeObjectOfClass:[NSString class] forKey:kUserIDCodingKey]; + BOOL hasAnonymousKey = [aDecoder containsValueForKey:kAnonymousCodingKey]; + BOOL anonymous = [aDecoder decodeBoolForKey:kAnonymousCodingKey]; + BOOL hasEmailPasswordCredential = + [aDecoder decodeBoolForKey:kHasEmailPasswordCredentialCodingKey]; + NSString *displayName = + [aDecoder decodeObjectOfClass:[NSString class] forKey:kDisplayNameCodingKey]; + NSURL *photoURL = + [aDecoder decodeObjectOfClass:[NSURL class] forKey:kPhotoURLCodingKey]; + NSString *email = + [aDecoder decodeObjectOfClass:[NSString class] forKey:kEmailCodingKey]; + NSString *phoneNumber = + [aDecoder decodeObjectOfClass:[NSString class] forKey:kPhoneNumberCodingKey]; + BOOL emailVerified = [aDecoder decodeBoolForKey:kEmailVerifiedCodingKey]; + NSSet *providerDataClasses = [NSSet setWithArray:@[ + [NSDictionary class], + [NSString class], + [FIRUserInfoImpl class] + ]]; + NSDictionary *providerData = + [aDecoder decodeObjectOfClasses:providerDataClasses forKey:kProviderDataKey]; + FIRSecureTokenService *tokenService = + [aDecoder decodeObjectOfClass:[FIRSecureTokenService class] forKey:kTokenServiceCodingKey]; + FIRUserMetadata *metadata = + [aDecoder decodeObjectOfClass:[FIRUserMetadata class] forKey:kMetadataCodingKey]; + NSString *APIKey = + [aDecoder decodeObjectOfClass:[FIRUserMetadata class] forKey:kAPIKeyCodingKey]; + if (!userID || !tokenService) { + return nil; + } + self = [self initWithTokenService:tokenService]; + if (self) { + _userID = userID; + // Previous version of this code didn't save 'anonymous' bit directly but deduced it from + // 'hasEmailPasswordCredential' and 'providerData' instead, so here backward compatibility is + // provided to read old format data. + _anonymous = hasAnonymousKey ? anonymous : (!hasEmailPasswordCredential && !providerData.count); + _hasEmailPasswordCredential = hasEmailPasswordCredential; + _email = email; + _emailVerified = emailVerified; + _displayName = displayName; + _photoURL = photoURL; + _providerData = providerData; + _phoneNumber = phoneNumber; + _metadata = metadata ?: [[FIRUserMetadata alloc] initWithCreationDate:nil lastSignInDate:nil]; + _requestConfiguration = [[FIRAuthRequestConfiguration alloc] initWithAPIKey:APIKey]; + } + return self; +} + +- (void)encodeWithCoder:(NSCoder *)aCoder { + [aCoder encodeObject:_userID forKey:kUserIDCodingKey]; + [aCoder encodeBool:self.anonymous forKey:kAnonymousCodingKey]; + [aCoder encodeBool:_hasEmailPasswordCredential forKey:kHasEmailPasswordCredentialCodingKey]; + [aCoder encodeObject:_providerData forKey:kProviderDataKey]; + [aCoder encodeObject:_email forKey:kEmailCodingKey]; + [aCoder encodeObject:_phoneNumber forKey:kPhoneNumberCodingKey]; + [aCoder encodeBool:_emailVerified forKey:kEmailVerifiedCodingKey]; + [aCoder encodeObject:_photoURL forKey:kPhotoURLCodingKey]; + [aCoder encodeObject:_displayName forKey:kDisplayNameCodingKey]; + [aCoder encodeObject:_metadata forKey:kMetadataCodingKey]; + [aCoder encodeObject:_auth.requestConfiguration.APIKey forKey:kAPIKeyCodingKey]; + [aCoder encodeObject:_tokenService forKey:kTokenServiceCodingKey]; +} + +#pragma mark - + +- (void)setAuth:(nullable FIRAuth *)auth { + _auth = auth; + _tokenService.requestConfiguration = auth.requestConfiguration; +} + +- (NSString *)providerID { + return @"Firebase"; +} + +- (NSArray> *)providerData { + return _providerData.allValues; +} + +/** @fn getAccountInfoRefreshingCache: + @brief Gets the users's account data from the server, updating our local values. + @param callback Invoked when the request to getAccountInfo has completed, or when an error has + been detected. Invoked asynchronously on the auth global work queue in the future. + */ +- (void)getAccountInfoRefreshingCache:(void(^)(FIRGetAccountInfoResponseUser *_Nullable user, + NSError *_Nullable error))callback { + [self internalGetTokenWithCallback:^(NSString *_Nullable accessToken, NSError *_Nullable error) { + if (error) { + callback(nil, error); + return; + } + FIRGetAccountInfoRequest *getAccountInfoRequest = + [[FIRGetAccountInfoRequest alloc] initWithAccessToken:accessToken + requestConfiguration:self->_auth.requestConfiguration]; + [FIRAuthBackend getAccountInfo:getAccountInfoRequest + callback:^(FIRGetAccountInfoResponse *_Nullable response, + NSError *_Nullable error) { + if (error) { + [self signOutIfTokenIsInvalidWithError:error]; + callback(nil, error); + return; + } + [self updateWithGetAccountInfoResponse:response]; + if (![self updateKeychain:&error]) { + callback(nil, error); + return; + } + callback(response.users.firstObject, nil); + }]; + }]; +} + +- (void)updateWithGetAccountInfoResponse:(FIRGetAccountInfoResponse *)response { + FIRGetAccountInfoResponseUser *user = response.users.firstObject; + _userID = user.localID; + _email = user.email; + _emailVerified = user.emailVerified; + _displayName = user.displayName; + _photoURL = user.photoURL; + _phoneNumber = user.phoneNumber; + _hasEmailPasswordCredential = user.passwordHash.length > 0; + _metadata = + [[FIRUserMetadata alloc]initWithCreationDate:user.creationDate + lastSignInDate:user.lastLoginDate]; + NSMutableDictionary *providerData = + [NSMutableDictionary dictionary]; + for (FIRGetAccountInfoResponseProviderUserInfo *providerUserInfo in user.providerUserInfo) { + FIRUserInfoImpl *userInfo = + [FIRUserInfoImpl userInfoWithGetAccountInfoResponseProviderUserInfo:providerUserInfo]; + if (userInfo) { + providerData[providerUserInfo.providerID] = userInfo; + } + } + _providerData = [providerData copy]; +} + +/** @fn executeUserUpdateWithChanges:callback: + @brief Performs a setAccountInfo request by mutating the results of a getAccountInfo response, + atomically in regards to other calls to this method. + @param changeBlock A block responsible for mutating a template @c FIRSetAccountInfoRequest + @param callback A block to invoke when the change is complete. Invoked asynchronously on the + auth global work queue in the future. + */ +- (void)executeUserUpdateWithChanges:(void(^)(FIRGetAccountInfoResponseUser *, + FIRSetAccountInfoRequest *))changeBlock + callback:(nonnull FIRUserProfileChangeCallback)callback { + [_taskQueue enqueueTask:^(FIRAuthSerialTaskCompletionBlock _Nonnull complete) { + [self getAccountInfoRefreshingCache:^(FIRGetAccountInfoResponseUser *_Nullable user, + NSError *_Nullable error) { + if (error) { + complete(); + callback(error); + return; + } + [self internalGetTokenWithCallback:^(NSString *_Nullable accessToken, + NSError *_Nullable error) { + if (error) { + complete(); + callback(error); + return; + } + FIRAuthRequestConfiguration *configuration = self->_auth.requestConfiguration; + // Mutate setAccountInfoRequest in block: + FIRSetAccountInfoRequest *setAccountInfoRequest = + [[FIRSetAccountInfoRequest alloc] initWithRequestConfiguration:configuration]; + setAccountInfoRequest.accessToken = accessToken; + changeBlock(user, setAccountInfoRequest); + // Execute request: + [FIRAuthBackend setAccountInfo:setAccountInfoRequest + callback:^(FIRSetAccountInfoResponse *_Nullable response, + NSError *_Nullable error) { + if (error) { + [self signOutIfTokenIsInvalidWithError:error]; + complete(); + callback(error); + return; + } + if (response.IDToken && response.refreshToken) { + FIRSecureTokenService *tokenService = [[FIRSecureTokenService alloc] + initWithRequestConfiguration:configuration + accessToken:response.IDToken + accessTokenExpirationDate:response.approximateExpirationDate + refreshToken:response.refreshToken]; + [self setTokenService:tokenService callback:^(NSError *_Nullable error) { + complete(); + callback(error); + }]; + return; + } + complete(); + callback(nil); + }]; + }]; + }]; + }]; +} + +/** @fn updateKeychain: + @brief Updates the keychain for user token or info changes. + @param error The error if NO is returned. + @return Whether the operation is successful. + */ +- (BOOL)updateKeychain:(NSError *_Nullable *_Nullable)error { + return [_auth updateKeychainWithUser:self error:error]; +} + +/** @fn setTokenService:callback: + @brief Sets a new token service for the @c FIRUser instance. + @param tokenService The new token service object. + @param callback The block to be called in the global auth working queue once finished. + @remarks The method makes sure the token service has access and refresh token and the new tokens + are saved in the keychain before calling back. + */ +- (void)setTokenService:(FIRSecureTokenService *)tokenService + callback:(nonnull CallbackWithError)callback { + [tokenService fetchAccessTokenForcingRefresh:NO + callback:^(NSString *_Nullable token, + NSError *_Nullable error, + BOOL tokenUpdated) { + if (error) { + callback(error); + return; + } + self->_tokenService = tokenService; + if (![self updateKeychain:&error]) { + callback(error); + return; + } + callback(nil); + }]; +} + +#pragma mark - + +/** @fn updateEmail:password:callback: + @brief Updates email address and/or password for the current user. + @remarks May fail if there is already an email/password-based account for the same email + address. + @param email The email address for the user, if to be updated. + @param password The new password for the user, if to be updated. + @param callback The block called when the user profile change has finished. Invoked + asynchronously on the auth global work queue in the future. + @remarks May fail with a @c FIRAuthErrorCodeRequiresRecentLogin error code. + Call @c reauthentateWithCredential:completion: beforehand to avoid this error case. + */ +- (void)updateEmail:(nullable NSString *)email + password:(nullable NSString *)password + callback:(nonnull FIRUserProfileChangeCallback)callback { + if (password && ![password length]) { + callback([FIRAuthErrorUtils weakPasswordErrorWithServerResponseReason:kMissingPasswordReason]); + return; + } + BOOL hadEmailPasswordCredential = _hasEmailPasswordCredential; + [self executeUserUpdateWithChanges:^(FIRGetAccountInfoResponseUser *user, + FIRSetAccountInfoRequest *request) { + if (email) { + request.email = email; + } + if (password) { + request.password = password; + } + } + callback:^(NSError *error) { + if (error) { + callback(error); + return; + } + if (email) { + self->_email = [email copy]; + } + if (self->_email) { + if (!hadEmailPasswordCredential) { + // The list of providers need to be updated for the newly added email-password provider. + [self internalGetTokenWithCallback:^(NSString *_Nullable accessToken, + NSError *_Nullable error) { + if (error) { + callback(error); + return; + } + FIRAuthRequestConfiguration *requestConfiguration = self->_auth.requestConfiguration; + FIRGetAccountInfoRequest *getAccountInfoRequest = + [[FIRGetAccountInfoRequest alloc] initWithAccessToken:accessToken + requestConfiguration:requestConfiguration]; + [FIRAuthBackend getAccountInfo:getAccountInfoRequest + callback:^(FIRGetAccountInfoResponse *_Nullable response, + NSError *_Nullable error) { + if (error) { + [self signOutIfTokenIsInvalidWithError:error]; + callback(error); + return; + } + for (FIRGetAccountInfoResponseUser *userAccountInfo in response.users) { + // Set the account to non-anonymous if there are any providers, even if + // they're not email/password ones. + if (userAccountInfo.providerUserInfo.count > 0) { + self.anonymous = NO; + } + for (FIRGetAccountInfoResponseProviderUserInfo *providerUserInfo in + userAccountInfo.providerUserInfo) { + if ([providerUserInfo.providerID isEqualToString:FIREmailAuthProviderID]) { + self->_hasEmailPasswordCredential = YES; + break; + } + } + } + [self updateWithGetAccountInfoResponse:response]; + if (![self updateKeychain:&error]) { + callback(error); + return; + } + callback(nil); + }]; + }]; + return; + } + } + if (![self updateKeychain:&error]) { + callback(error); + return; + } + callback(nil); + }]; +} + +- (void)updateEmail:(NSString *)email completion:(nullable FIRUserProfileChangeCallback)completion { + dispatch_async(FIRAuthGlobalWorkQueue(), ^{ + [self updateEmail:email password:nil callback:^(NSError *_Nullable error) { + callInMainThreadWithError(completion, error); + }]; + }); +} + +- (void)updatePassword:(NSString *)password + completion:(nullable FIRUserProfileChangeCallback)completion { + dispatch_async(FIRAuthGlobalWorkQueue(), ^{ + [self updateEmail:nil password:password callback:^(NSError *_Nullable error){ + callInMainThreadWithError(completion, error); + }]; + }); +} + +#if TARGET_OS_IOS +/** @fn internalUpdateOrLinkPhoneNumberCredential:completion: + @brief Updates the phone number for the user. On success, the cached user profile data is + updated. + + @param phoneAuthCredential The new phone number credential corresponding to the phone number + to be added to the Firebase account, if a phone number is already linked to the account this + new phone number will replace it. + @param isLinkOperation Boolean value indicating whether or not this is a link operation. + @param completion Optionally; the block invoked when the user profile change has finished. + Invoked asynchronously on the global work queue in the future. + */ +- (void)internalUpdateOrLinkPhoneNumberCredential:(FIRPhoneAuthCredential *)phoneAuthCredential + isLinkOperation:(BOOL)isLinkOperation + completion:(FIRUserProfileChangeCallback)completion { + [self internalGetTokenWithCallback:^(NSString *_Nullable accessToken, + NSError *_Nullable error) { + if (error) { + completion(error); + return; + } + FIRAuthOperationType operation = + isLinkOperation ? FIRAuthOperationTypeLink : FIRAuthOperationTypeUpdate; + FIRVerifyPhoneNumberRequest *request = [[FIRVerifyPhoneNumberRequest alloc] + initWithVerificationID:phoneAuthCredential.verificationID + verificationCode:phoneAuthCredential.verificationCode + operation:operation + requestConfiguration:self->_auth.requestConfiguration]; + request.accessToken = accessToken; + [FIRAuthBackend verifyPhoneNumber:request + callback:^(FIRVerifyPhoneNumberResponse *_Nullable response, + NSError *_Nullable error) { + if (error) { + [self signOutIfTokenIsInvalidWithError:error]; + completion(error); + return; + } + // Get account info to update cached user info. + [self getAccountInfoRefreshingCache:^(FIRGetAccountInfoResponseUser *_Nullable user, + NSError *_Nullable error) { + if (error) { + [self signOutIfTokenIsInvalidWithError:error]; + completion(error); + return; + } + self.anonymous = NO; + if (![self updateKeychain:&error]) { + completion(error); + return; + } + completion(nil); + }]; + }]; + }]; +} + +- (void)updatePhoneNumberCredential:(FIRPhoneAuthCredential *)phoneAuthCredential + completion:(nullable FIRUserProfileChangeCallback)completion { + dispatch_async(FIRAuthGlobalWorkQueue(), ^{ + [self internalUpdateOrLinkPhoneNumberCredential:phoneAuthCredential + isLinkOperation:NO + completion:^(NSError *_Nullable error) { + callInMainThreadWithError(completion, error); + }]; + }); +} +#endif + +- (FIRUserProfileChangeRequest *)profileChangeRequest { + __block FIRUserProfileChangeRequest *result; + dispatch_sync(FIRAuthGlobalWorkQueue(), ^{ + result = [[FIRUserProfileChangeRequest alloc] initWithUser:self]; + }); + return result; +} + +- (void)setDisplayName:(NSString *)displayName { + _displayName = [displayName copy]; +} + +- (void)setPhotoURL:(NSURL *)photoURL { + _photoURL = [photoURL copy]; +} + +- (NSString *)rawAccessToken { + return _tokenService.rawAccessToken; +} + +- (NSDate *)accessTokenExpirationDate { + return _tokenService.accessTokenExpirationDate; +} + +#pragma mark - + +- (void)reloadWithCompletion:(nullable FIRUserProfileChangeCallback)completion { + dispatch_async(FIRAuthGlobalWorkQueue(), ^{ + [self getAccountInfoRefreshingCache:^(FIRGetAccountInfoResponseUser *_Nullable user, + NSError *_Nullable error) { + callInMainThreadWithError(completion, error); + }]; + }); +} + +#pragma mark - + +- (void)reauthenticateWithCredential:(FIRAuthCredential *)credential + completion:(nullable FIRUserProfileChangeCallback)completion { + FIRAuthDataResultCallback callback = ^(FIRAuthDataResult *_Nullable authResult, + NSError *_Nullable error) { + completion(error); + }; + [self reauthenticateAndRetrieveDataWithCredential:credential completion:callback]; +} + +- (void) + reauthenticateAndRetrieveDataWithCredential:(FIRAuthCredential *) credential + completion:(nullable FIRAuthDataResultCallback) completion { + dispatch_async(FIRAuthGlobalWorkQueue(), ^{ + [self->_auth internalSignInAndRetrieveDataWithCredential:credential + isReauthentication:YES + callback:^(FIRAuthDataResult *_Nullable + authResult, + NSError *_Nullable error) { + if (error) { + // If "user not found" error returned by backend, translate to user mismatch error which is + // more accurate. + if (error.code == FIRAuthErrorCodeUserNotFound) { + error = [FIRAuthErrorUtils userMismatchError]; + } + callInMainThreadWithAuthDataResultAndError(completion, authResult, error); + return; + } + if (![authResult.user.uid isEqual:[self->_auth getUserID]]) { + callInMainThreadWithAuthDataResultAndError(completion, authResult, + [FIRAuthErrorUtils userMismatchError]); + return; + } + // Successful reauthenticate + [self setTokenService:authResult.user->_tokenService callback:^(NSError *_Nullable error) { + callInMainThreadWithAuthDataResultAndError(completion, authResult, error); + }]; + }]; + }); +} + +- (nullable NSString *)refreshToken { + __block NSString *result; + dispatch_sync(FIRAuthGlobalWorkQueue(), ^{ + result = self->_tokenService.refreshToken; + }); + return result; +} + +- (void)getIDTokenWithCompletion:(nullable FIRAuthTokenCallback)completion { + // |getIDTokenForcingRefresh:completion:| is also a public API so there is no need to dispatch to + // global work queue here. + [self getIDTokenForcingRefresh:NO completion:completion]; +} + +- (void)getIDTokenForcingRefresh:(BOOL)forceRefresh + completion:(nullable FIRAuthTokenCallback)completion { + [self getIDTokenResultForcingRefresh:forceRefresh + completion:^(FIRAuthTokenResult *_Nullable tokenResult, + NSError *_Nullable error) { + + if (completion) { + dispatch_async(dispatch_get_main_queue(), ^{ + completion(tokenResult.token, error); + }); + } + }]; +} + +- (void)getIDTokenResultWithCompletion:(nullable FIRAuthTokenResultCallback)completion { + [self getIDTokenResultForcingRefresh:NO + completion:^(FIRAuthTokenResult *_Nullable tokenResult, + NSError *_Nullable error) { + if (completion) { + dispatch_async(dispatch_get_main_queue(), ^{ + completion(tokenResult, error); + }); + } + }]; +} + +- (void)getIDTokenResultForcingRefresh:(BOOL)forceRefresh + completion:(nullable FIRAuthTokenResultCallback)completion { + dispatch_async(FIRAuthGlobalWorkQueue(), ^{ + [self internalGetTokenForcingRefresh:forceRefresh + callback:^(NSString *_Nullable token, NSError *_Nullable error) { + FIRAuthTokenResult *tokenResult; + if (token) { + tokenResult = [self parseIDToken:token error:&error]; + } + if (completion) { + dispatch_async(dispatch_get_main_queue(), ^{ + completion(tokenResult, error); + }); + } + }]; + }); +} + +/** @fn parseIDToken:error: + @brief Parses the provided IDToken and returns an instance of FIRAuthTokenResult containing + claims obtained from the IDToken. + + @param token The raw text of the Firebase IDToken encoded in base64. + @param error An out parameter which would contain any error that occurs during parsing. + @return An instance of FIRAuthTokenResult containing claims obtained from the IDToken. + + @remarks IDToken returned from the backend in some cases is of a length that is not a multiple + of 4. In these cases this function pads the token with as many "=" characters as needed and + then attempts to parse the token. If the token cannot be parsed an error is returned via the + "error" out parameter. + */ +- (nullable FIRAuthTokenResult *)parseIDToken:(NSString *)token error:(NSError **)error { + // Though this is an internal method, errors returned here are surfaced in user-visible + // callbacks. + if (error) { + *error = nil; + } + NSArray *tokenStringArray = [token componentsSeparatedByString:@"."]; + + // The JWT should have three parts, though we only use the second in this method. + if (tokenStringArray.count != 3) { + if (error) { + *error = [FIRAuthErrorUtils malformedJWTErrorWithToken:token underlyingError:nil]; + } + return nil; + } + + // The token payload is always the second index of the array. + NSString *idToken = tokenStringArray[1]; + + // Convert the base64URL encoded string to a base64 encoded string. + // Replace "_" with "/" + NSMutableString *tokenPayload = + [[idToken stringByReplacingOccurrencesOfString:@"_" withString:@"/"] mutableCopy]; + + // Replace "-" with "+" + [tokenPayload replaceOccurrencesOfString:@"-" + withString:@"+" + options:kNilOptions + range:NSMakeRange(0, tokenPayload.length)]; + + // Pad the token payload with "=" signs if the payload's length is not a multiple of 4. + while ((tokenPayload.length % 4) != 0) { + [tokenPayload appendFormat:@"="]; + } + NSData *decodedTokenPayloadData = + [[NSData alloc] initWithBase64EncodedString:tokenPayload + options:NSDataBase64DecodingIgnoreUnknownCharacters]; + if (!decodedTokenPayloadData) { + if (error) { + *error = [FIRAuthErrorUtils malformedJWTErrorWithToken:token underlyingError:nil]; + } + return nil; + } + NSError *jsonError = nil; + NSJSONReadingOptions options = NSJSONReadingMutableContainers|NSJSONReadingAllowFragments; + NSDictionary *tokenPayloadDictionary = + [NSJSONSerialization JSONObjectWithData:decodedTokenPayloadData + options:options + error:&jsonError]; + if (jsonError != nil) { + if (error) { + *error = [FIRAuthErrorUtils malformedJWTErrorWithToken:token underlyingError:jsonError]; + } + return nil; + } + + if (!tokenPayloadDictionary) { + if (error) { + *error = [FIRAuthErrorUtils malformedJWTErrorWithToken:token underlyingError:nil]; + } + return nil; + } + + // These are dates since 00:00:00 January 1 1970, as described by the Terminology section in + // the JWT spec. https://tools.ietf.org/html/rfc7519 + NSDate *expDate = + [NSDate dateWithTimeIntervalSince1970:[tokenPayloadDictionary[@"exp"] doubleValue]]; + NSDate *authDate = + [NSDate dateWithTimeIntervalSince1970:[tokenPayloadDictionary[@"auth_time"] doubleValue]]; + NSDate *issuedDate = + [NSDate dateWithTimeIntervalSince1970:[tokenPayloadDictionary[@"iat"] doubleValue]]; + FIRAuthTokenResult *result = + [[FIRAuthTokenResult alloc] initWithToken:token + expirationDate:expDate + authDate:authDate + issuedAtDate:issuedDate + signInProvider:tokenPayloadDictionary[@"sign_in_provider"] + claims:tokenPayloadDictionary]; + return result; +} + +/** @fn internalGetTokenForcingRefresh:callback: + @brief Retrieves the Firebase authentication token, possibly refreshing it if it has expired. + @param callback The block to invoke when the token is available. Invoked asynchronously on the + global work thread in the future. + */ +- (void)internalGetTokenWithCallback:(nonnull FIRAuthTokenCallback)callback { + [self internalGetTokenForcingRefresh:NO callback:callback]; +} + +- (void)internalGetTokenForcingRefresh:(BOOL)forceRefresh + callback:(nonnull FIRAuthTokenCallback)callback { + [_tokenService fetchAccessTokenForcingRefresh:forceRefresh + callback:^(NSString *_Nullable token, + NSError *_Nullable error, + BOOL tokenUpdated) { + if (error) { + [self signOutIfTokenIsInvalidWithError:error]; + callback(nil, error); + return; + } + if (tokenUpdated) { + if (![self updateKeychain:&error]) { + callback(nil, error); + return; + } + } + callback(token, nil); + }]; +} + +- (void)linkWithCredential:(FIRAuthCredential *)credential + completion:(nullable FIRAuthResultCallback)completion { + FIRAuthDataResultCallback callback = ^(FIRAuthDataResult *_Nullable authResult, + NSError *_Nullable error) { + completion(authResult.user, error); + }; + [self linkAndRetrieveDataWithCredential:credential completion:callback]; +} + +- (void)linkAndRetrieveDataWithCredential:(FIRAuthCredential *)credential + completion:(nullable FIRAuthDataResultCallback)completion { + dispatch_async(FIRAuthGlobalWorkQueue(), ^{ + if (self->_providerData[credential.provider]) { + callInMainThreadWithAuthDataResultAndError(completion, + nil, + [FIRAuthErrorUtils providerAlreadyLinkedError]); + return; + } + FIRAuthDataResult *result = + [[FIRAuthDataResult alloc] initWithUser:self additionalUserInfo:nil]; + if ([credential isKindOfClass:[FIREmailPasswordAuthCredential class]]) { + if (self->_hasEmailPasswordCredential) { + callInMainThreadWithAuthDataResultAndError(completion, + nil, + [FIRAuthErrorUtils providerAlreadyLinkedError]); + return; + } + FIREmailPasswordAuthCredential *emailPasswordCredential = + (FIREmailPasswordAuthCredential *)credential; + [self updateEmail:emailPasswordCredential.email + password:emailPasswordCredential.password + callback:^(NSError *error) { + if (error) { + callInMainThreadWithAuthDataResultAndError(completion, nil, error); + } else { + callInMainThreadWithAuthDataResultAndError(completion, result, nil); + } + }]; + return; + } + + if ([credential isKindOfClass:[FIRGameCenterAuthCredential class]]) { + FIRGameCenterAuthCredential *gameCenterCredential = (FIRGameCenterAuthCredential *)credential; + [self internalGetTokenWithCallback:^(NSString *_Nullable accessToken, + NSError *_Nullable error) { + FIRAuthRequestConfiguration *requestConfiguration = self.auth.requestConfiguration; + FIRSignInWithGameCenterRequest *gameCenterRequest = + [[FIRSignInWithGameCenterRequest alloc] initWithPlayerID:gameCenterCredential.playerID + publicKeyURL:gameCenterCredential.publicKeyURL + signature:gameCenterCredential.signature + salt:gameCenterCredential.salt + timestamp:gameCenterCredential.timestamp + displayName:gameCenterCredential.displayName + requestConfiguration:requestConfiguration]; + gameCenterRequest.accessToken = accessToken; + + [FIRAuthBackend signInWithGameCenter:gameCenterRequest + callback:^(FIRSignInWithGameCenterResponse *_Nullable response, + NSError *_Nullable error) { + if (error){ + callInMainThreadWithAuthDataResultAndError(completion, nil, error); + } else { + [self internalGetTokenWithCallback:^(NSString *_Nullable accessToken, + NSError *_Nullable error) { + if (error) { + callInMainThreadWithAuthDataResultAndError(completion, nil, error); + return; + } + + FIRGetAccountInfoRequest *getAccountInfoRequest = + [[FIRGetAccountInfoRequest alloc] initWithAccessToken:accessToken + requestConfiguration:requestConfiguration]; + [FIRAuthBackend getAccountInfo:getAccountInfoRequest + callback:^(FIRGetAccountInfoResponse *_Nullable response, + NSError *_Nullable error) { + if (error) { + [self signOutIfTokenIsInvalidWithError:error]; + callInMainThreadWithAuthDataResultAndError(completion, nil, error); + return; + } + self.anonymous = NO; + [self updateWithGetAccountInfoResponse:response]; + if (![self updateKeychain:&error]) { + callInMainThreadWithAuthDataResultAndError(completion, nil, error); + return; + } + callInMainThreadWithAuthDataResultAndError(completion, result, nil); + }]; + }]; + } + }]; + }]; + return; + } + + #if TARGET_OS_IOS + if ([credential isKindOfClass:[FIRPhoneAuthCredential class]]) { + FIRPhoneAuthCredential *phoneAuthCredential = (FIRPhoneAuthCredential *)credential; + [self internalUpdateOrLinkPhoneNumberCredential:phoneAuthCredential + isLinkOperation:YES + completion:^(NSError *_Nullable error) { + if (error){ + callInMainThreadWithAuthDataResultAndError(completion, nil, error); + } else { + callInMainThreadWithAuthDataResultAndError(completion, result, nil); + } + }]; + return; + } + #endif + + [self->_taskQueue enqueueTask:^(FIRAuthSerialTaskCompletionBlock _Nonnull complete) { + CallbackWithAuthDataResultAndError completeWithError = + ^(FIRAuthDataResult *result, NSError *error) { + complete(); + callInMainThreadWithAuthDataResultAndError(completion, result, error); + }; + [self internalGetTokenWithCallback:^(NSString *_Nullable accessToken, + NSError *_Nullable error) { + if (error) { + completeWithError(nil, error); + return; + } + FIRAuthRequestConfiguration *requestConfiguration = self->_auth.requestConfiguration; + FIRVerifyAssertionRequest *request = + [[FIRVerifyAssertionRequest alloc] initWithProviderID:credential.provider + requestConfiguration:requestConfiguration]; + [credential prepareVerifyAssertionRequest:request]; + request.accessToken = accessToken; + [FIRAuthBackend verifyAssertion:request + callback:^(FIRVerifyAssertionResponse *response, NSError *error) { + if (error) { + [self signOutIfTokenIsInvalidWithError:error]; + completeWithError(nil, error); + return; + } + FIRAdditionalUserInfo *additionalUserInfo = + [FIRAdditionalUserInfo userInfoWithVerifyAssertionResponse:response]; + FIRAuthDataResult *result = + [[FIRAuthDataResult alloc] initWithUser:self additionalUserInfo:additionalUserInfo]; + // Update the new token and refresh user info again. + self->_tokenService = [[FIRSecureTokenService alloc] + initWithRequestConfiguration:requestConfiguration + accessToken:response.IDToken + accessTokenExpirationDate:response.approximateExpirationDate + refreshToken:response.refreshToken]; + [self internalGetTokenWithCallback:^(NSString *_Nullable accessToken, + NSError *_Nullable error) { + if (error) { + completeWithError(nil, error); + return; + } + FIRGetAccountInfoRequest *getAccountInfoRequest = + [[FIRGetAccountInfoRequest alloc] initWithAccessToken:accessToken + requestConfiguration:requestConfiguration]; + [FIRAuthBackend getAccountInfo:getAccountInfoRequest + callback:^(FIRGetAccountInfoResponse *_Nullable response, + NSError *_Nullable error) { + if (error) { + [self signOutIfTokenIsInvalidWithError:error]; + completeWithError(nil, error); + return; + } + self.anonymous = NO; + [self updateWithGetAccountInfoResponse:response]; + if (![self updateKeychain:&error]) { + completeWithError(nil, error); + return; + } + completeWithError(result, nil); + }]; + }]; + }]; + }]; + }]; + }); +} + +- (void)unlinkFromProvider:(NSString *)provider + completion:(nullable FIRAuthResultCallback)completion { + [_taskQueue enqueueTask:^(FIRAuthSerialTaskCompletionBlock _Nonnull complete) { + CallbackWithError completeAndCallbackWithError = ^(NSError *error) { + complete(); + callInMainThreadWithUserAndError(completion, self, error); + }; + [self internalGetTokenWithCallback:^(NSString *_Nullable accessToken, + NSError *_Nullable error) { + if (error) { + completeAndCallbackWithError(error); + return; + } + FIRAuthRequestConfiguration *requestConfiguration = self->_auth.requestConfiguration; + FIRSetAccountInfoRequest *setAccountInfoRequest = + [[FIRSetAccountInfoRequest alloc] initWithRequestConfiguration:requestConfiguration]; + setAccountInfoRequest.accessToken = accessToken; + + if ([provider isEqualToString:FIREmailAuthProviderID]) { + if (!self->_hasEmailPasswordCredential) { + completeAndCallbackWithError([FIRAuthErrorUtils noSuchProviderError]); + return; + } + setAccountInfoRequest.deleteAttributes = @[ FIRSetAccountInfoUserAttributePassword ]; + } else { + if (!self->_providerData[provider]) { + completeAndCallbackWithError([FIRAuthErrorUtils noSuchProviderError]); + return; + } + setAccountInfoRequest.deleteProviders = @[ provider ]; + } + + [FIRAuthBackend setAccountInfo:setAccountInfoRequest + callback:^(FIRSetAccountInfoResponse *_Nullable response, + NSError *_Nullable error) { + if (error) { + [self signOutIfTokenIsInvalidWithError:error]; + completeAndCallbackWithError(error); + return; + } + + // We can't just use the provider info objects in FIRSetAccountInfoResponse because they + // don't have localID and email fields. Remove the specific provider manually. + NSMutableDictionary *mutableProviderData = [self->_providerData mutableCopy]; + [mutableProviderData removeObjectForKey:provider]; + self->_providerData = [mutableProviderData copy]; + + if ([provider isEqualToString:FIREmailAuthProviderID]) { + self->_hasEmailPasswordCredential = NO; + } + #if TARGET_OS_IOS + // After successfully unlinking a phone auth provider, remove the phone number from the + // cached user info. + if ([provider isEqualToString:FIRPhoneAuthProviderID]) { + self->_phoneNumber = nil; + } + #endif + + if (response.IDToken && response.refreshToken) { + FIRSecureTokenService *tokenService = [[FIRSecureTokenService alloc] + initWithRequestConfiguration:requestConfiguration + accessToken:response.IDToken + accessTokenExpirationDate:response.approximateExpirationDate + refreshToken:response.refreshToken]; + [self setTokenService:tokenService callback:^(NSError *_Nullable error) { + completeAndCallbackWithError(error); + }]; + return; + } + if (![self updateKeychain:&error]) { + completeAndCallbackWithError(error); + return; + } + completeAndCallbackWithError(nil); + }]; + }]; + }]; +} + +- (void)sendEmailVerificationWithCompletion:(nullable FIRSendEmailVerificationCallback)completion { + [self sendEmailVerificationWithNullableActionCodeSettings:nil completion:completion]; +} + +- (void)sendEmailVerificationWithActionCodeSettings:(FIRActionCodeSettings *)actionCodeSettings + completion:(nullable FIRSendEmailVerificationCallback) + completion { + [self sendEmailVerificationWithNullableActionCodeSettings:actionCodeSettings + completion:completion]; +} + +/** @fn sendEmailVerificationWithNullableActionCodeSettings:completion: + @brief Initiates email verification for the user. + + @param actionCodeSettings Optionally, a @c FIRActionCodeSettings object containing settings + related to the handling action codes. + */ +- (void)sendEmailVerificationWithNullableActionCodeSettings:(nullable FIRActionCodeSettings *) + actionCodeSettings + completion: + (nullable FIRSendEmailVerificationCallback) + completion { + dispatch_async(FIRAuthGlobalWorkQueue(), ^{ + [self internalGetTokenWithCallback:^(NSString *_Nullable accessToken, + NSError *_Nullable error) { + if (error) { + callInMainThreadWithError(completion, error); + return; + } + FIRAuthRequestConfiguration *configuration = self->_auth.requestConfiguration; + FIRGetOOBConfirmationCodeRequest *request = + [FIRGetOOBConfirmationCodeRequest verifyEmailRequestWithAccessToken:accessToken + actionCodeSettings:actionCodeSettings + requestConfiguration:configuration]; + [FIRAuthBackend getOOBConfirmationCode:request + callback:^(FIRGetOOBConfirmationCodeResponse *_Nullable + response, + NSError *_Nullable error) { + [self signOutIfTokenIsInvalidWithError:error]; + callInMainThreadWithError(completion, error); + }]; + }]; + }); +} + +- (void)deleteWithCompletion:(nullable FIRUserProfileChangeCallback)completion { + dispatch_async(FIRAuthGlobalWorkQueue(), ^{ + [self internalGetTokenWithCallback:^(NSString *_Nullable accessToken, + NSError *_Nullable error) { + if (error) { + callInMainThreadWithError(completion, error); + return; + } + FIRDeleteAccountRequest *deleteUserRequest = + [[FIRDeleteAccountRequest alloc] initWitLocalID:self->_userID + accessToken:accessToken + requestConfiguration:self->_auth.requestConfiguration]; + [FIRAuthBackend deleteAccount:deleteUserRequest callback:^(NSError *_Nullable error) { + if (error) { + callInMainThreadWithError(completion, error); + return; + } + if (![self->_auth signOutByForceWithUserID:self->_userID error:&error]) { + callInMainThreadWithError(completion, error); + return; + } + callInMainThreadWithError(completion, error); + }]; + }]; + }); +} + +/** @fn signOutIfTokenIsInvalidWithError: + @brief Signs out this user if the user or the token is invalid. + @param error The error from the server. + */ +- (void)signOutIfTokenIsInvalidWithError:(nullable NSError *)error { + NSInteger errorCode = error.code; + if (errorCode == FIRAuthErrorCodeUserNotFound || + errorCode == FIRAuthErrorCodeUserDisabled || + errorCode == FIRAuthErrorCodeInvalidUserToken || + errorCode == FIRAuthErrorCodeUserTokenExpired) { + FIRLogNotice(kFIRLoggerAuth, @"I-AUT000016", + @"Invalid user token detected, user is automatically signed out."); + [_auth signOutByForceWithUserID:_userID error:NULL]; + } +} + +@end + +@implementation FIRUserProfileChangeRequest { + /** @var _user + @brief The user associated with the change request. + */ + FIRUser *_user; + + /** @var _displayName + @brief The display name value to set if @c _displayNameSet is YES. + */ + NSString *_displayName; + + /** @var _displayNameSet + @brief Indicates the display name should be part of the change request. + */ + BOOL _displayNameSet; + + /** @var _photoURL + @brief The photo URL value to set if @c _displayNameSet is YES. + */ + NSURL *_photoURL; + + /** @var _photoURLSet + @brief Indicates the photo URL should be part of the change request. + */ + BOOL _photoURLSet; + + /** @var _consumed + @brief Indicates the @c commitChangesWithCallback: method has already been invoked. + */ + BOOL _consumed; +} + +- (nullable instancetype)initWithUser:(FIRUser *)user { + self = [super init]; + if (self) { + _user = user; + } + return self; +} + +- (nullable NSString *)displayName { + return _displayName; +} + +- (void)setDisplayName:(nullable NSString *)displayName { + dispatch_sync(FIRAuthGlobalWorkQueue(), ^{ + if (self->_consumed) { + [NSException raise:NSInternalInconsistencyException + format:@"%@", + @"Invalid call to setDisplayName: after commitChangesWithCallback:."]; + return; + } + self->_displayNameSet = YES; + self->_displayName = [displayName copy]; + }); +} + +- (nullable NSURL *)photoURL { + return _photoURL; +} + +- (void)setPhotoURL:(nullable NSURL *)photoURL { + dispatch_sync(FIRAuthGlobalWorkQueue(), ^{ + if (self->_consumed) { + [NSException raise:NSInternalInconsistencyException + format:@"%@", + @"Invalid call to setPhotoURL: after commitChangesWithCallback:."]; + return; + } + self->_photoURLSet = YES; + self->_photoURL = [photoURL copy]; + }); +} + +/** @fn hasUpdates + @brief Indicates at least one field has a value which needs to be committed. + */ +- (BOOL)hasUpdates { + return _displayNameSet || _photoURLSet; +} + +- (void)commitChangesWithCompletion:(nullable FIRUserProfileChangeCallback)completion { + dispatch_sync(FIRAuthGlobalWorkQueue(), ^{ + if (self->_consumed) { + [NSException raise:NSInternalInconsistencyException + format:@"%@", + @"commitChangesWithCallback: should only be called once."]; + return; + } + self->_consumed = YES; + // Return fast if there is nothing to update: + if (![self hasUpdates]) { + callInMainThreadWithError(completion, nil); + return; + } + NSString *displayName = [self->_displayName copy]; + BOOL displayNameWasSet = self->_displayNameSet; + NSURL *photoURL = [self->_photoURL copy]; + BOOL photoURLWasSet = self->_photoURLSet; + [self->_user executeUserUpdateWithChanges:^(FIRGetAccountInfoResponseUser *user, + FIRSetAccountInfoRequest *request) { + if (photoURLWasSet) { + request.photoURL = photoURL; + } + if (displayNameWasSet) { + request.displayName = displayName; + } + } + callback:^(NSError *_Nullable error) { + if (error) { + callInMainThreadWithError(completion, error); + return; + } + if (displayNameWasSet) { + [self->_user setDisplayName:displayName]; + } + if (photoURLWasSet) { + [self->_user setPhotoURL:photoURL]; + } + if (![self->_user updateKeychain:&error]) { + callInMainThreadWithError(completion, error); + return; + } + callInMainThreadWithError(completion, nil); + }]; + }); +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRUserInfoImpl.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRUserInfoImpl.h new file mode 100644 index 0000000..0022a68 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRUserInfoImpl.h @@ -0,0 +1,61 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +#import "FIRUserInfo.h" + +@class FIRGetAccountInfoResponseProviderUserInfo; + +NS_ASSUME_NONNULL_BEGIN + +@interface FIRUserInfoImpl : NSObject + +/** @fn userInfoWithGetAccountInfoResponseProviderUserInfo: + @brief A convenience factory method for constructing a @c FIRUserInfo instance from data + returned by the getAccountInfo endpoint. + @param providerUserInfo Data returned by the getAccountInfo endpoint. + @return A new instance of @c FIRUserInfo using data from the getAccountInfo endpoint. + */ ++ (nullable instancetype)userInfoWithGetAccountInfoResponseProviderUserInfo: + (FIRGetAccountInfoResponseProviderUserInfo *)providerUserInfo; + +/** @fn init + @brief This class should not be initialized manually. + @see FIRUser.providerData + */ +- (instancetype)init NS_UNAVAILABLE; + +/** @fn initWithProviderID:userID:displayName:photoURL:email: + @brief Designated initializer. + @param providerID The provider identifier. + @param userID The unique user ID for the user (the value of the @c uid field in the token.) + @param displayName The name of the user. + @param photoURL The URL of the user's profile photo. + @param email The user's email address. + @param phoneNumber The user's phone number. + */ +- (nullable instancetype)initWithProviderID:(NSString *)providerID + userID:(NSString *)userID + displayName:(nullable NSString *)displayName + photoURL:(nullable NSURL *)photoURL + email:(nullable NSString *)email + phoneNumber:(nullable NSString *)phoneNumber + NS_DESIGNATED_INITIALIZER; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRUserInfoImpl.m b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRUserInfoImpl.m new file mode 100644 index 0000000..2e804ab --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRUserInfoImpl.m @@ -0,0 +1,131 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRUserInfoImpl.h" + +#import "FIRGetAccountInfoResponse.h" + +NS_ASSUME_NONNULL_BEGIN + +/** @var kProviderIDCodingKey + @brief The key used to encode the providerID property for NSSecureCoding. + */ +static NSString *const kProviderIDCodingKey = @"providerID"; + +/** @var kUserIDCodingKey + @brief The key used to encode the userID property for NSSecureCoding. + */ +static NSString *const kUserIDCodingKey = @"userID"; + +/** @var kDisplayNameCodingKey + @brief The key used to encode the displayName property for NSSecureCoding. + */ +static NSString *const kDisplayNameCodingKey = @"displayName"; + +/** @var kProfileURLCodingKey + @brief The key used to encode the profileURL property for NSSecureCoding. + */ +static NSString *const kProfileURLCodingKey = @"profileURL"; + +/** @var kPhotoURLCodingKey + @brief The key used to encode the photoURL property for NSSecureCoding. + */ +static NSString *const kPhotoURLCodingKey = @"photoURL"; + +/** @var kEmailCodingKey + @brief The key used to encode the email property for NSSecureCoding. + */ +static NSString *const kEmailCodingKey = @"email"; + +/** @var kPhoneNumberCodingKey + @brief The key used to encode the phoneNumber property for NSSecureCoding. + */ +static NSString *const kPhoneNumberCodingKey = @"phoneNumber"; + +@implementation FIRUserInfoImpl + +@synthesize providerID = _providerID; +@synthesize uid = _userID; +@synthesize displayName = _displayName; +@synthesize photoURL = _photoURL; +@synthesize email = _email; +@synthesize phoneNumber = _phoneNumber; + ++ (nullable instancetype)userInfoWithGetAccountInfoResponseProviderUserInfo: + (FIRGetAccountInfoResponseProviderUserInfo *)providerUserInfo { + return [[self alloc] initWithProviderID:providerUserInfo.providerID + userID:providerUserInfo.federatedID + displayName:providerUserInfo.displayName + photoURL:providerUserInfo.photoURL + email:providerUserInfo.email + phoneNumber:providerUserInfo.phoneNumber]; +} + +- (nullable instancetype)initWithProviderID:(NSString *)providerID + userID:(NSString *)userID + displayName:(nullable NSString *)displayName + photoURL:(nullable NSURL *)photoURL + email:(nullable NSString *)email + phoneNumber:(nullable NSString *)phoneNumber { + self = [super init]; + if (self) { + _providerID = [providerID copy]; + _userID = [userID copy]; + _displayName = [displayName copy]; + _photoURL = [photoURL copy]; + _email = [email copy]; + _phoneNumber = [phoneNumber copy]; + } + return self; +} + +#pragma mark - NSSecureCoding + ++ (BOOL)supportsSecureCoding { + return YES; +} + +- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder { + NSString *providerID = + [aDecoder decodeObjectOfClass:[NSString class] forKey:kProviderIDCodingKey]; + NSString *userID = [aDecoder decodeObjectOfClass:[NSString class] forKey:kUserIDCodingKey]; + NSString *displayName = + [aDecoder decodeObjectOfClass:[NSString class] forKey:kDisplayNameCodingKey]; + NSURL *photoURL = [aDecoder decodeObjectOfClass:[NSURL class] forKey:kPhotoURLCodingKey]; + NSString *email = [aDecoder decodeObjectOfClass:[NSString class] forKey:kEmailCodingKey]; + NSString *phoneNumber = + [aDecoder decodeObjectOfClass:[NSString class] forKey:kPhoneNumberCodingKey]; + + return [self initWithProviderID:providerID + userID:userID + displayName:displayName + photoURL:photoURL + email:email + phoneNumber:phoneNumber]; +} + +- (void)encodeWithCoder:(NSCoder *)aCoder { + [aCoder encodeObject:_providerID forKey:kProviderIDCodingKey]; + [aCoder encodeObject:_userID forKey:kUserIDCodingKey]; + [aCoder encodeObject:_displayName forKey:kDisplayNameCodingKey]; + [aCoder encodeObject:_photoURL forKey:kPhotoURLCodingKey]; + [aCoder encodeObject:_email forKey:kEmailCodingKey]; + [aCoder encodeObject:_phoneNumber forKey:kPhoneNumberCodingKey]; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRUserMetadata.m b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRUserMetadata.m new file mode 100644 index 0000000..8fe6509 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRUserMetadata.m @@ -0,0 +1,64 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRUserMetadata_Internal.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation FIRUserMetadata + +/** @var kCreationDateCodingKey + @brief The key used to encode the creationDate property for NSSecureCoding. + */ +static NSString *const kCreationDateCodingKey = @"creationDate"; + +/** @var kLastSignInDateCodingKey + @brief The key used to encode the lastSignInDate property for NSSecureCoding. + */ +static NSString *const kLastSignInDateCodingKey = @"lastSignInDate"; + +- (instancetype)initWithCreationDate:(nullable NSDate *)creationDate + lastSignInDate:(nullable NSDate *)lastSignInDate { + self = [super init]; + if (self) { + _creationDate = [creationDate copy]; + _lastSignInDate = [lastSignInDate copy]; + } + return self; +} + +#pragma mark - NSSecureCoding + ++ (BOOL)supportsSecureCoding { + return YES; +} + +- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder { + NSDate *creationDate = + [aDecoder decodeObjectOfClass:[NSDate class] forKey:kCreationDateCodingKey]; + NSDate *lastSignInDate = + [aDecoder decodeObjectOfClass:[NSDate class] forKey:kLastSignInDateCodingKey]; + return [self initWithCreationDate:creationDate lastSignInDate:lastSignInDate]; +} + +- (void)encodeWithCoder:(NSCoder *)aCoder { + [aCoder encodeObject:_creationDate forKey:kCreationDateCodingKey]; + [aCoder encodeObject:_lastSignInDate forKey:kLastSignInDateCodingKey]; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRUserMetadata_Internal.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRUserMetadata_Internal.h new file mode 100644 index 0000000..0b01a03 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRUserMetadata_Internal.h @@ -0,0 +1,38 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +#import "FIRUserMetadata.h" + +NS_ASSUME_NONNULL_BEGIN + +/** @extension FIRUserMetadata + @brief An internal class used to expose internal methods of FIRUserMetadata. + */ +@interface FIRUserMetadata () + +/** @fn initWithCreationDate:lastSignInDate: + @brief Designated initializer. + @param creationDate The creation date of the corresponding user. + @param lastSignInDate The date of the last recorded sign-in of the corresponding user. + */ +- (instancetype)initWithCreationDate:(nullable NSDate *)creationDate + lastSignInDate:(nullable NSDate *)lastSignInDate NS_DESIGNATED_INITIALIZER; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRUser_Internal.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRUser_Internal.h new file mode 100644 index 0000000..cf225b1 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FIRUser_Internal.h @@ -0,0 +1,86 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRUser.h" + +@class FIRAuth; +@class FIRAuthRequestConfiguration; + +NS_ASSUME_NONNULL_BEGIN + +/** @typedef FIRRetrieveUserCallback + @brief The type of block that is invoked when the construction of a user succeeds or fails. + @param user The user that was constructed, or nil if user construction failed. + @param error The error which occurred, or nil if the request was successful. + */ +typedef void(^FIRRetrieveUserCallback)(FIRUser *_Nullable user, NSError *_Nullable error); + +@interface FIRUser () + +/** @property rawAccessToken + @brief The cached access token. + @remarks This method is specifically for providing the access token to internal clients during + deserialization and sign-in events, and should not be used to retrieve the access token by + anyone else. + */ +@property(nonatomic, copy, readonly) NSString *rawAccessToken; + +/** @property auth + @brief A weak reference to a FIRAuth instance associated with this instance. + */ +@property(nonatomic, weak) FIRAuth *auth; + +/** @property auth + @brief A strong reference to a requestConfiguration instance associated with this user instance. + */ +@property(nonatomic, strong) FIRAuthRequestConfiguration *requestConfiguration; + +/** @var accessTokenExpirationDate + @brief The expiration date of the cached access token. + */ +@property(nonatomic, copy, readonly) NSDate *accessTokenExpirationDate; + +/** @fn retrieveUserWithAuth:accessToken:accessTokenExpirationDate:refreshToken:callback: + @brief Constructs a user with Secure Token Service tokens, and obtains user details from the + getAccountInfo endpoint. + @param auth The associated FIRAuth instance. + @param accessToken The Secure Token Service access token. + @param accessTokenExpirationDate The approximate expiration date of the access token. + @param refreshToken The Secure Token Service refresh token. + @param anonymous Whether or not the user is anonymous. + @param callback A block which is invoked when the construction succeeds or fails. Invoked + asynchronously on the auth global work queue in the future. + */ ++ (void)retrieveUserWithAuth:(FIRAuth *)auth + accessToken:(nullable NSString *)accessToken + accessTokenExpirationDate:(nullable NSDate *)accessTokenExpirationDate + refreshToken:(nullable NSString *)refreshToken + anonymous:(BOOL)anonymous + callback:(FIRRetrieveUserCallback)callback; + +/** @fn internalGetTokenForcingRefresh:callback: + @brief Retrieves the Firebase authentication token, possibly refreshing it if it has expired. + @param forceRefresh Forces a token refresh. Useful if the token becomes invalid for some reason + other than an expiration. + @param callback The block to invoke when the token is available. Invoked asynchronously on the + global work thread in the future. + */ +- (void)internalGetTokenForcingRefresh:(BOOL)forceRefresh + callback:(nonnull FIRAuthTokenCallback)callback; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FirebaseAuthVersion.m b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FirebaseAuthVersion.m new file mode 100644 index 0000000..4893018 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/FirebaseAuthVersion.m @@ -0,0 +1,25 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FirebaseAuthVersion.h" + +// Convert the macro to a string +#define STR(x) STR_EXPAND(x) +#define STR_EXPAND(x) #x + +const double FirebaseAuthVersionNum = FIRAuth_MINOR_VERSION; + +const char *const FirebaseAuthVersionStr = (const char *const)STR(FIRAuth_VERSION); diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/NSData+FIRBase64.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/NSData+FIRBase64.h new file mode 100644 index 0000000..114cbfd --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/NSData+FIRBase64.h @@ -0,0 +1,31 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface NSData (FIRBase64) + +/** @fn fir_base64URLEncodedStringWithOptions: + @brief Get a web safe base64 encoded string + @param options The base64 encoding options + */ +- (NSString *)fir_base64URLEncodedStringWithOptions:(NSDataBase64EncodingOptions)options; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/NSData+FIRBase64.m b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/NSData+FIRBase64.m new file mode 100644 index 0000000..b53f053 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/NSData+FIRBase64.m @@ -0,0 +1,33 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#import "NSData+FIRBase64.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation NSData (FIRBase64) + +- (NSString *)fir_base64URLEncodedStringWithOptions:(NSDataBase64EncodingOptions)options { + NSString *string = [self base64EncodedStringWithOptions:options]; + string = [string stringByReplacingOccurrencesOfString:@"/" withString:@"_"]; + string = [string stringByReplacingOccurrencesOfString:@"+" withString:@"-"]; + string = [string stringByReplacingOccurrencesOfString:@"=" withString:@""]; + return string; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/Public/FIRActionCodeSettings.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/Public/FIRActionCodeSettings.h new file mode 100644 index 0000000..788e060 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/Public/FIRActionCodeSettings.h @@ -0,0 +1,89 @@ +/* + * Copyright 2017 Google + * + * 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/LICENSE2.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. + */ + + #import + + NS_ASSUME_NONNULL_BEGIN + + /** @class FIRActionCodeSettings + @brief Used to set and retrieve settings related to handling action codes. + */ + NS_SWIFT_NAME(ActionCodeSettings) + @interface FIRActionCodeSettings : NSObject + + /** @property URL + @brief This URL represents the state/Continue URL in the form of a universal link. + @remarks This URL can should be contructed as a universal link that would either directly open + the app where the action code would be handled or continue to the app after the action code + is handled by Firebase. + */ + @property(nonatomic, copy, nullable) NSURL *URL; + + /** @property handleCodeInApp + @brief Indicates whether the action code link will open the app directly or after being + redirected from a Firebase owned web widget. + */ + @property(assign, nonatomic) BOOL handleCodeInApp; + + /** @property iOSBundleID + @brief The iOS bundle ID, if available. The default value is the current app's bundle ID. + */ + @property(copy, nonatomic, readonly, nullable) NSString *iOSBundleID; + + /** @property androidPackageName + @brief The Android package name, if available. + */ + @property(nonatomic, copy, readonly, nullable) NSString *androidPackageName; + + /** @property androidMinimumVersion + @brief The minimum Android version supported, if available. + */ + @property(nonatomic, copy, readonly, nullable) NSString *androidMinimumVersion; + + /** @property androidInstallIfNotAvailable + @brief Indicates whether the Android app should be installed on a device where it is not + available. + */ + @property(nonatomic, assign, readonly) BOOL androidInstallIfNotAvailable; + + /** @property dynamicLinkDomain + @brief The Firebase Dynamic Link domain used for out of band code flow. + */ + @property (copy, nonatomic, nullable) NSString *dynamicLinkDomain; + + /** @fn setIOSBundleID + @brief Sets the iOS bundle Id. + @param iOSBundleID The iOS bundle ID. + */ + - (void)setIOSBundleID:(NSString *)iOSBundleID; + + /** @fn setAndroidPackageName:installIfNotAvailable:minimumVersion: + @brief Sets the Android package name, the flag to indicate whether or not to install the app and + the minimum Android version supported. + @param androidPackageName The Android package name. + @param installIfNotAvailable Indicates whether or not the app should be installed if not + available. + @param minimumVersion The minimum version of Android supported. + @remarks If installIfNotAvailable is set to YES and the link is opened on an android device, it + will try to install the app if not already available. Otherwise the web URL is used. + */ + - (void)setAndroidPackageName:(NSString *)androidPackageName + installIfNotAvailable:(BOOL)installIfNotAvailable + minimumVersion:(nullable NSString *)minimumVersion; + + @end + + NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/Public/FIRAdditionalUserInfo.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/Public/FIRAdditionalUserInfo.h new file mode 100644 index 0000000..4f6947a --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/Public/FIRAdditionalUserInfo.h @@ -0,0 +1,57 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +@class FIRVerifyAssertionResponse; + +NS_ASSUME_NONNULL_BEGIN + +/** @class FIRAdditionalUserInfo + @brief Represents additional user data returned from an identity provider. + */ +NS_SWIFT_NAME(AdditionalUserInfo) +@interface FIRAdditionalUserInfo : NSObject + +/** @fn init + @brief This class should not be initialized manually. `FIRAdditionalUserInfo` can be retrieved + from from an instance of `FIRAuthDataResult`. + */ +- (instancetype)init NS_UNAVAILABLE; + +/** @property providerID + @brief The provider identifier. + */ +@property(nonatomic, readonly) NSString *providerID; + +/** @property profile + @brief Dictionary containing the additional IdP specific information. + */ +@property(nonatomic, readonly, nullable) NSDictionary *profile; + +/** @property username + @brief username The name of the user. + */ +@property(nonatomic, readonly, nullable) NSString *username; + +/** @property newUser + @brief Indicates whether or not the current user was signed in for the first time. + */ +@property(nonatomic, readonly, getter=isNewUser) BOOL newUser; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/Public/FIRAuth.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/Public/FIRAuth.h new file mode 100644 index 0000000..25ee65d --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/Public/FIRAuth.h @@ -0,0 +1,914 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import +#import + +#import "FIRAuthErrors.h" + +#if TARGET_OS_IOS +#import "FIRAuthAPNSTokenType.h" +#endif + +@class FIRActionCodeSettings; +@class FIRApp; +@class FIRAuth; +@class FIRAuthCredential; +@class FIRAuthDataResult; +@class FIRAuthSettings; +@class FIRUser; +@protocol FIRAuthStateListener; +@protocol FIRAuthUIDelegate; +@protocol FIRFederatedAuthProvider; + +NS_ASSUME_NONNULL_BEGIN + +/** @typedef FIRUserUpdateCallback + @brief The type of block invoked when a request to update the current user is completed. + */ +typedef void (^FIRUserUpdateCallback)(NSError *_Nullable error) NS_SWIFT_NAME(UserUpdateCallback); + +/** @typedef FIRAuthStateDidChangeListenerHandle + @brief The type of handle returned by `FIRAuth.addAuthStateDidChangeListener:`. + */ +typedef id FIRAuthStateDidChangeListenerHandle + NS_SWIFT_NAME(AuthStateDidChangeListenerHandle); + +/** @typedef FIRAuthStateDidChangeListenerBlock + @brief The type of block which can be registered as a listener for auth state did change events. + + @param auth The FIRAuth object on which state changes occurred. + @param user Optionally; the current signed in user, if any. + */ +typedef void(^FIRAuthStateDidChangeListenerBlock)(FIRAuth *auth, FIRUser *_Nullable user) + NS_SWIFT_NAME(AuthStateDidChangeListenerBlock); + +/** @typedef FIRIDTokenDidChangeListenerHandle + @brief The type of handle returned by `FIRAuth.addIDTokenDidChangeListener:`. + */ +typedef id FIRIDTokenDidChangeListenerHandle + NS_SWIFT_NAME(IDTokenDidChangeListenerHandle); + +/** @typedef FIRIDTokenDidChangeListenerBlock + @brief The type of block which can be registered as a listener for ID token did change events. + + @param auth The FIRAuth object on which ID token changes occurred. + @param user Optionally; the current signed in user, if any. + */ +typedef void(^FIRIDTokenDidChangeListenerBlock)(FIRAuth *auth, FIRUser *_Nullable user) + NS_SWIFT_NAME(IDTokenDidChangeListenerBlock); + +/** @typedef FIRAuthDataResultCallback + @brief The type of block invoked when sign-in related events complete. + + @param authResult Optionally; Result of sign-in request containing both the user and + the additional user info associated with the user. + @param error Optionally; the error which occurred - or nil if the request was successful. + */ +typedef void (^FIRAuthDataResultCallback)(FIRAuthDataResult *_Nullable authResult, + NSError *_Nullable error) + NS_SWIFT_NAME(AuthDataResultCallback); + +#if defined(__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0 +/** + @brief The name of the `NSNotificationCenter` notification which is posted when the auth state + changes (for example, a new token has been produced, a user signs in or signs out). The + object parameter of the notification is the sender `FIRAuth` instance. + */ +extern const NSNotificationName FIRAuthStateDidChangeNotification + NS_SWIFT_NAME(AuthStateDidChange); +#else +/** + @brief The name of the `NSNotificationCenter` notification which is posted when the auth state + changes (for example, a new token has been produced, a user signs in or signs out). The + object parameter of the notification is the sender `FIRAuth` instance. + */ +extern NSString *const FIRAuthStateDidChangeNotification + NS_SWIFT_NAME(AuthStateDidChangeNotification); +#endif // defined(__IPHONE_10_0) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0 + +/** @typedef FIRAuthResultCallback + @brief The type of block invoked when sign-in related events complete. + + @param user Optionally; the signed in user, if any. + @param error Optionally; if an error occurs, this is the NSError object that describes the + problem. Set to nil otherwise. + */ +typedef void (^FIRAuthResultCallback)(FIRUser *_Nullable user, NSError *_Nullable error) + NS_SWIFT_NAME(AuthResultCallback); + +/** @typedef FIRProviderQueryCallback + @brief The type of block invoked when a list of identity providers for a given email address is + requested. + + @param providers Optionally; a list of provider identifiers, if any. + @see FIRGoogleAuthProviderID etc. + @param error Optionally; if an error occurs, this is the NSError object that describes the + problem. Set to nil otherwise. + */ +typedef void (^FIRProviderQueryCallback)(NSArray *_Nullable providers, + NSError *_Nullable error) + NS_SWIFT_NAME(ProviderQueryCallback); + +/** @typedef FIRSignInMethodQueryCallback + @brief The type of block invoked when a list of sign-in methods for a given email address is + requested. + */ +typedef void (^FIRSignInMethodQueryCallback)(NSArray *_Nullable, + NSError *_Nullable) + NS_SWIFT_NAME(SignInMethodQueryCallback); + +/** @typedef FIRSendPasswordResetCallback + @brief The type of block invoked when sending a password reset email. + + @param error Optionally; if an error occurs, this is the NSError object that describes the + problem. Set to nil otherwise. + */ +typedef void (^FIRSendPasswordResetCallback)(NSError *_Nullable error) + NS_SWIFT_NAME(SendPasswordResetCallback); + +/** @typedef FIRSendSignInLinkToEmailCallback + @brief The type of block invoked when sending an email sign-in link email. + */ +typedef void (^FIRSendSignInLinkToEmailCallback)(NSError *_Nullable error) + NS_SWIFT_NAME(SendSignInLinkToEmailCallback); + +/** @typedef FIRConfirmPasswordResetCallback + @brief The type of block invoked when performing a password reset. + + @param error Optionally; if an error occurs, this is the NSError object that describes the + problem. Set to nil otherwise. + */ +typedef void (^FIRConfirmPasswordResetCallback)(NSError *_Nullable error) + NS_SWIFT_NAME(ConfirmPasswordResetCallback); + +/** @typedef FIRVerifyPasswordResetCodeCallback + @brief The type of block invoked when verifying that an out of band code should be used to + perform password reset. + + @param email Optionally; the email address of the user for which the out of band code applies. + @param error Optionally; if an error occurs, this is the NSError object that describes the + problem. Set to nil otherwise. + */ +typedef void (^FIRVerifyPasswordResetCodeCallback)(NSString *_Nullable email, + NSError *_Nullable error) + NS_SWIFT_NAME(VerifyPasswordResetCodeCallback); + +/** @typedef FIRApplyActionCodeCallback + @brief The type of block invoked when applying an action code. + + @param error Optionally; if an error occurs, this is the NSError object that describes the + problem. Set to nil otherwise. + */ +typedef void (^FIRApplyActionCodeCallback)(NSError *_Nullable error) + NS_SWIFT_NAME(ApplyActionCodeCallback); + +/** + @brief Keys used to retrieve operation data from a `FIRActionCodeInfo` object by the + `dataForKey` method. + */ +typedef NS_ENUM(NSInteger, FIRActionDataKey) { + /** + * The email address to which the code was sent. + * For FIRActionCodeOperationRecoverEmail, the new email address for the account. + */ + FIRActionCodeEmailKey = 0, + + /** For FIRActionCodeOperationRecoverEmail, the current email address for the account. */ + FIRActionCodeFromEmailKey = 1 +} NS_SWIFT_NAME(ActionDataKey); + +/** @class FIRActionCodeInfo + @brief Manages information regarding action codes. + */ +NS_SWIFT_NAME(ActionCodeInfo) +@interface FIRActionCodeInfo : NSObject + +/** + @brief Operations which can be performed with action codes. + */ +typedef NS_ENUM(NSInteger, FIRActionCodeOperation) { + /** Action code for unknown operation. */ + FIRActionCodeOperationUnknown = 0, + + /** Action code for password reset operation. */ + FIRActionCodeOperationPasswordReset = 1, + + /** Action code for verify email operation. */ + FIRActionCodeOperationVerifyEmail = 2, + + /** Action code for recover email operation. */ + FIRActionCodeOperationRecoverEmail = 3, + + /** Action code for email link operation. */ + FIRActionCodeOperationEmailLink = 4, + + +} NS_SWIFT_NAME(ActionCodeOperation); + +/** + @brief The operation being performed. + */ +@property(nonatomic, readonly) FIRActionCodeOperation operation; + +/** @fn dataForKey: + @brief The operation being performed. + + @param key The FIRActionDataKey value used to retrieve the operation data. + + @return The operation data pertaining to the provided action code key. + */ +- (NSString *)dataForKey:(FIRActionDataKey)key; + +/** @fn init + @brief please use initWithOperation: instead. + */ +- (instancetype)init NS_UNAVAILABLE; + +@end + +/** @typedef FIRCheckActionCodeCallBack + @brief The type of block invoked when performing a check action code operation. + + @param info Metadata corresponding to the action code. + @param error Optionally; if an error occurs, this is the NSError object that describes the + problem. Set to nil otherwise. + */ +typedef void (^FIRCheckActionCodeCallBack)(FIRActionCodeInfo *_Nullable info, + NSError *_Nullable error) + NS_SWIFT_NAME(CheckActionCodeCallback); + +/** @class FIRAuth + @brief Manages authentication for Firebase apps. + @remarks This class is thread-safe. + */ +NS_SWIFT_NAME(Auth) +@interface FIRAuth : NSObject + +/** @fn auth + @brief Gets the auth object for the default Firebase app. + @remarks The default Firebase app must have already been configured or an exception will be + raised. + */ ++ (FIRAuth *)auth NS_SWIFT_NAME(auth()); + +/** @fn authWithApp: + @brief Gets the auth object for a `FIRApp`. + + @param app The FIRApp for which to retrieve the associated FIRAuth instance. + @return The FIRAuth instance associated with the given FIRApp. + */ ++ (FIRAuth *)authWithApp:(FIRApp *)app NS_SWIFT_NAME(auth(app:)); + +/** @property app + @brief Gets the `FIRApp` object that this auth object is connected to. + */ +@property(nonatomic, weak, readonly, nullable) FIRApp *app; + +/** @property currentUser + @brief Synchronously gets the cached current user, or null if there is none. + */ +@property(nonatomic, strong, readonly, nullable) FIRUser *currentUser; + +/** @property languageCode + @brief The current user language code. This property can be set to the app's current language by + calling `useAppLanguage`. + + @remarks The string used to set this property must be a language code that follows BCP 47. + */ +@property (nonatomic, copy, nullable) NSString *languageCode; + +/** @property settings + @brief Contains settings related to the auth object. + */ +@property (nonatomic, copy, nullable) FIRAuthSettings *settings; + +#if TARGET_OS_IOS +/** @property APNSToken + @brief The APNs token used for phone number authentication. The type of the token (production + or sandbox) will be attempted to be automatcially detected. + @remarks If swizzling is disabled, the APNs Token must be set for phone number auth to work, + by either setting this property or by calling `setAPNSToken:type:` + */ +@property(nonatomic, strong, nullable) NSData *APNSToken; +#endif + +/** @fn init + @brief Please access auth instances using `FIRAuth.auth` and `FIRAuth.authForApp:`. + */ +- (instancetype)init NS_UNAVAILABLE; + +/** @fn updateCurrentUser:completion: + @brief Sets the currentUser on the calling Auth instance to the provided user object. + @param user The user object to be set as the current user of the calling Auth instance. + @param completion Optionally; a block invoked after the user of the calling Auth instance has + been updated or an error was encountered. + */ +- (void)updateCurrentUser:(FIRUser *)user completion:(nullable FIRUserUpdateCallback)completion; + +/** @fn fetchProvidersForEmail:completion: + @brief Fetches the list of IdPs that can be used for signing in with the provided email address. + Useful for an "identifier-first" sign-in flow. + + @param email The email address for which to obtain a list of identity providers. + @param completion Optionally; a block which is invoked when the list of providers for the + specified email address is ready or an error was encountered. Invoked asynchronously on the + main thread in the future. + + @remarks Possible error codes: + + + `FIRAuthErrorCodeInvalidEmail` - Indicates the email address is malformed. + + @remarks See `FIRAuthErrors` for a list of error codes that are common to all API methods. + */ +- (void)fetchProvidersForEmail:(NSString *)email + completion:(nullable FIRProviderQueryCallback)completion; + +/** @fn fetchSignInMethodsForEmail:completion: + @brief Fetches the list of all sign-in methods previously used for the provided email address. + + @param email The email address for which to obtain a list of sign-in methods. + @param completion Optionally; a block which is invoked when the list of sign in methods for the + specified email address is ready or an error was encountered. Invoked asynchronously on the + main thread in the future. + + @remarks Possible error codes: + + + `FIRAuthErrorCodeInvalidEmail` - Indicates the email address is malformed. + + @remarks See @c FIRAuthErrors for a list of error codes that are common to all API methods. + */ + +- (void)fetchSignInMethodsForEmail:(NSString *)email + completion:(nullable FIRSignInMethodQueryCallback)completion; + +/** @fn signInWithEmail:password:completion: + @brief Signs in using an email address and password. + + @param email The user's email address. + @param password The user's password. + @param completion Optionally; a block which is invoked when the sign in flow finishes, or is + canceled. Invoked asynchronously on the main thread in the future. + + @remarks Possible error codes: + + + `FIRAuthErrorCodeOperationNotAllowed` - Indicates that email and password + accounts are not enabled. Enable them in the Auth section of the + Firebase console. + + `FIRAuthErrorCodeUserDisabled` - Indicates the user's account is disabled. + + `FIRAuthErrorCodeWrongPassword` - Indicates the user attempted + sign in with an incorrect password. + + `FIRAuthErrorCodeInvalidEmail` - Indicates the email address is malformed. + + + @remarks See `FIRAuthErrors` for a list of error codes that are common to all API methods. + */ +- (void)signInWithEmail:(NSString *)email + password:(NSString *)password + completion:(nullable FIRAuthDataResultCallback)completion; + +/** @fn signInWithEmail:link:completion: + @brief Signs in using an email address and email sign-in link. + + @param email The user's email address. + @param link The email sign-in link. + @param completion Optionally; a block which is invoked when the sign in flow finishes, or is + canceled. Invoked asynchronously on the main thread in the future. + + @remarks Possible error codes: + + + `FIRAuthErrorCodeOperationNotAllowed` - Indicates that email and email sign-in link + accounts are not enabled. Enable them in the Auth section of the + Firebase console. + + `FIRAuthErrorCodeUserDisabled` - Indicates the user's account is disabled. + + `FIRAuthErrorCodeInvalidEmail` - Indicates the email address is invalid. + + + @remarks See `FIRAuthErrors` for a list of error codes that are common to all API methods. + */ + +- (void)signInWithEmail:(NSString *)email + link:(NSString *)link + completion:(nullable FIRAuthDataResultCallback)completion; + +/** @fn signInAndRetrieveDataWithEmail:password:completion: + @brief Please use `signInWithEmail:password:completion:` for Objective-C or + `signIn(withEmail:password:completion:)` for Swift instead. + + @param email The user's email address. + @param password The user's password. + @param completion Optionally; a block which is invoked when the sign in flow finishes, or is + canceled. Invoked asynchronously on the main thread in the future. + */ +- (void)signInAndRetrieveDataWithEmail:(NSString *)email + password:(NSString *)password + completion:(nullable FIRAuthDataResultCallback)completion + DEPRECATED_MSG_ATTRIBUTE( + "Please use signInWithEmail:password:completion: for" + " Objective-C or signIn(withEmail:password:completion:) for" + " Swift instead."); + +/** @fn signInWithCredential:completion: + @brief Please use `signInAndRetrieveDataWithCredential:completion:` for Objective-C or + `signInAndRetrieveData(with:completion:)` for swift instead + + @param credential The credential supplied by the IdP. + @param completion Optionally; a block which is invoked when the sign in flow finishes, or is + canceled. Invoked asynchronously on the main thread in the future. + + @remarks Possible error codes: + + + `FIRAuthErrorCodeInvalidCredential` - Indicates the supplied credential is invalid. + This could happen if it has expired or it is malformed. + + `FIRAuthErrorCodeOperationNotAllowed` - Indicates that accounts + with the identity provider represented by the credential are not enabled. + Enable them in the Auth section of the Firebase console. + + `FIRAuthErrorCodeAccountExistsWithDifferentCredential` - Indicates the email asserted + by the credential (e.g. the email in a Facebook access token) is already in use by an + existing account, that cannot be authenticated with this sign-in method. Call + fetchProvidersForEmail for this user’s email and then prompt them to sign in with any of + the sign-in providers returned. This error will only be thrown if the "One account per + email address" setting is enabled in the Firebase console, under Auth settings. + + `FIRAuthErrorCodeUserDisabled` - Indicates the user's account is disabled. + + `FIRAuthErrorCodeWrongPassword` - Indicates the user attempted sign in with an + incorrect password, if credential is of the type EmailPasswordAuthCredential. + + `FIRAuthErrorCodeInvalidEmail` - Indicates the email address is malformed. + + `FIRAuthErrorCodeMissingVerificationID` - Indicates that the phone auth credential was + created with an empty verification ID. + + `FIRAuthErrorCodeMissingVerificationCode` - Indicates that the phone auth credential + was created with an empty verification code. + + `FIRAuthErrorCodeInvalidVerificationCode` - Indicates that the phone auth credential + was created with an invalid verification Code. + + `FIRAuthErrorCodeInvalidVerificationID` - Indicates that the phone auth credential was + created with an invalid verification ID. + + `FIRAuthErrorCodeSessionExpired` - Indicates that the SMS code has expired. + + + + @remarks See `FIRAuthErrors` for a list of error codes that are common to all API methods + */ +- (void)signInWithCredential:(FIRAuthCredential *)credential + completion:(nullable FIRAuthResultCallback)completion DEPRECATED_MSG_ATTRIBUTE( + "Please use signInAndRetrieveDataWithCredential:completion:" + " for Objective-C or signInAndRetrieveData(with:completion:)" + " for Swift instead."); + +/** @fn signInWithProvider:UIDelegate:completion: + @brief Signs in using the provided auth provider instance. + + @param provider An isntance of an auth provider used to initiate the sign-in flow. + @param UIDelegate Optionally an instance of a class conforming to the FIRAuthUIDelegate + protocol, this is used for presenting the web context. If nil, a default FIRAuthUIDelegate + will be used. + @param completion Optionally; a block which is invoked when the sign in flow finishes, or is + canceled. Invoked asynchronously on the main thread in the future. + + @remarks Possible error codes: +
    +
  • @c FIRAuthErrorCodeOperationNotAllowed - Indicates that email and password + accounts are not enabled. Enable them in the Auth section of the + Firebase console. +
  • +
  • @c FIRAuthErrorCodeUserDisabled - Indicates the user's account is disabled. +
  • +
  • @c FIRAuthErrorCodeWebNetworkRequestFailed - Indicates that a network request within a + SFSafariViewController or UIWebview failed. +
  • +
  • @c FIRAuthErrorCodeWebInternalError - Indicates that an internal error occurred within a + SFSafariViewController or UIWebview. +
  • +
  • @c FIRAuthErrorCodeWebSignInUserInteractionFailure - Indicates a general failure during + a web sign-in flow. +
  • +
  • @c FIRAuthErrorCodeWebContextAlreadyPresented - Indicates that an attempt was made to + present a new web context while one was already being presented. +
  • +
  • @c FIRAuthErrorCodeWebContextCancelled - Indicates that the URL presentation was cancelled prematurely + by the user. +
  • +
  • @c FIRAuthErrorCodeAccountExistsWithDifferentCredential - Indicates the email asserted + by the credential (e.g. the email in a Facebook access token) is already in use by an + existing account, that cannot be authenticated with this sign-in method. Call + fetchProvidersForEmail for this user’s email and then prompt them to sign in with any of + the sign-in providers returned. This error will only be thrown if the "One account per + email address" setting is enabled in the Firebase console, under Auth settings. +
  • +
+ + @remarks See @c FIRAuthErrors for a list of error codes that are common to all API methods. + */ +- (void)signInWithProvider:(id)provider + UIDelegate:(nullable id)UIDelegate + completion:(nullable FIRAuthDataResultCallback)completion; + +/** @fn signInAndRetrieveDataWithCredential:completion: + @brief Asynchronously signs in to Firebase with the given 3rd-party credentials (e.g. a Facebook + login Access Token, a Google ID Token/Access Token pair, etc.) and returns additional + identity provider data. + + @param credential The credential supplied by the IdP. + @param completion Optionally; a block which is invoked when the sign in flow finishes, or is + canceled. Invoked asynchronously on the main thread in the future. + + @remarks Possible error codes: + + + `FIRAuthErrorCodeInvalidCredential` - Indicates the supplied credential is invalid. + This could happen if it has expired or it is malformed. + + `FIRAuthErrorCodeOperationNotAllowed` - Indicates that accounts + with the identity provider represented by the credential are not enabled. + Enable them in the Auth section of the Firebase console. + + `FIRAuthErrorCodeAccountExistsWithDifferentCredential` - Indicates the email asserted + by the credential (e.g. the email in a Facebook access token) is already in use by an + existing account, that cannot be authenticated with this sign-in method. Call + fetchProvidersForEmail for this user’s email and then prompt them to sign in with any of + the sign-in providers returned. This error will only be thrown if the "One account per + email address" setting is enabled in the Firebase console, under Auth settings. + + `FIRAuthErrorCodeUserDisabled` - Indicates the user's account is disabled. + + `FIRAuthErrorCodeWrongPassword` - Indicates the user attempted sign in with an + incorrect password, if credential is of the type EmailPasswordAuthCredential. + + `FIRAuthErrorCodeInvalidEmail` - Indicates the email address is malformed. + + `FIRAuthErrorCodeMissingVerificationID` - Indicates that the phone auth credential was + created with an empty verification ID. + + `FIRAuthErrorCodeMissingVerificationCode` - Indicates that the phone auth credential + was created with an empty verification code. + + `FIRAuthErrorCodeInvalidVerificationCode` - Indicates that the phone auth credential + was created with an invalid verification Code. + + `FIRAuthErrorCodeInvalidVerificationID` - Indicates that the phone auth credential was + created with an invalid verification ID. + + `FIRAuthErrorCodeSessionExpired` - Indicates that the SMS code has expired. + + + + @remarks See `FIRAuthErrors` for a list of error codes that are common to all API methods + */ +- (void)signInAndRetrieveDataWithCredential:(FIRAuthCredential *)credential + completion:(nullable FIRAuthDataResultCallback)completion; + +/** @fn signInAnonymouslyWithCompletion: + @brief Asynchronously creates and becomes an anonymous user. + @param completion Optionally; a block which is invoked when the sign in finishes, or is + canceled. Invoked asynchronously on the main thread in the future. + + @remarks If there is already an anonymous user signed in, that user will be returned instead. + If there is any other existing user signed in, that user will be signed out. + + @remarks Possible error codes: + + + `FIRAuthErrorCodeOperationNotAllowed` - Indicates that anonymous accounts are + not enabled. Enable them in the Auth section of the Firebase console. + + @remarks See `FIRAuthErrors` for a list of error codes that are common to all API methods. + */ +- (void)signInAnonymouslyWithCompletion:(nullable FIRAuthDataResultCallback)completion; + +/** @fn signInAnonymouslyAndRetrieveDataWithCompletion: + @brief `Please use sign `signInAnonymouslyWithCompletion:` for Objective-C or + `signInAnonymously(Completion:)` for Swift instead. + @param completion Optionally; a block which is invoked when the sign in finishes, or is + canceled. Invoked asynchronously on the main thread in the future. + */ +- (void)signInAnonymouslyAndRetrieveDataWithCompletion: + (nullable FIRAuthDataResultCallback)completion + DEPRECATED_MSG_ATTRIBUTE("Please use signInAnonymouslyWithCompletion: for Objective-C or" + " signInAnonymously(Completion:) for swift instead."); + +/** @fn signInWithCustomToken:completion: + @brief Asynchronously signs in to Firebase with the given Auth token. + + @param token A self-signed custom auth token. + @param completion Optionally; a block which is invoked when the sign in finishes, or is + canceled. Invoked asynchronously on the main thread in the future. + + @remarks Possible error codes: + + + `FIRAuthErrorCodeInvalidCustomToken` - Indicates a validation error with + the custom token. + + `FIRAuthErrorCodeCustomTokenMismatch` - Indicates the service account and the API key + belong to different projects. + + + + @remarks See `FIRAuthErrors` for a list of error codes that are common to all API methods. + */ +- (void)signInWithCustomToken:(NSString *)token + completion:(nullable FIRAuthDataResultCallback)completion; + +/** @fn signInAndRetrieveDataWithCustomToken:completion: + @brief Please use `signInWithCustomToken:completion:` or `signIn(withCustomToken:completion:)` + for Swift instead. + + @param token A self-signed custom auth token. + @param completion Optionally; a block which is invoked when the sign in finishes, or is + canceled. Invoked asynchronously on the main thread in the future. + */ +- (void)signInAndRetrieveDataWithCustomToken:(NSString *)token + completion:(nullable FIRAuthDataResultCallback)completion + DEPRECATED_MSG_ATTRIBUTE( + "Please use signInWithCustomToken:completion:" + "for Objective-C or signIn(withCustomToken:completion:) for" + " Swift instead."); + +/** @fn createUserWithEmail:password:completion: + @brief Creates and, on success, signs in a user with the given email address and password. + + @param email The user's email address. + @param password The user's desired password. + @param completion Optionally; a block which is invoked when the sign up flow finishes, or is + canceled. Invoked asynchronously on the main thread in the future. + + @remarks Possible error codes: + + + `FIRAuthErrorCodeInvalidEmail` - Indicates the email address is malformed. + + `FIRAuthErrorCodeEmailAlreadyInUse` - Indicates the email used to attempt sign up + already exists. Call fetchProvidersForEmail to check which sign-in mechanisms the user + used, and prompt the user to sign in with one of those. + + `FIRAuthErrorCodeOperationNotAllowed` - Indicates that email and password accounts + are not enabled. Enable them in the Auth section of the Firebase console. + + `FIRAuthErrorCodeWeakPassword` - Indicates an attempt to set a password that is + considered too weak. The NSLocalizedFailureReasonErrorKey field in the NSError.userInfo + dictionary object will contain more detailed explanation that can be shown to the user. + + @remarks See `FIRAuthErrors` for a list of error codes that are common to all API methods. + */ +- (void)createUserWithEmail:(NSString *)email + password:(NSString *)password + completion:(nullable FIRAuthDataResultCallback)completion; + +/** @fn createUserAndRetrieveDataWithEmail:password:completion: + @brief Please use `createUserAndRetrieveDataWithEmail:password:completion:` or + `createUser(withEmail:password:completion:)` for Swift instead. + + @param email The user's email address. + @param password The user's desired password. + @param completion Optionally; a block which is invoked when the sign up flow finishes, or is + canceled. Invoked asynchronously on the main thread in the future. + */ +- (void)createUserAndRetrieveDataWithEmail:(NSString *)email + password:(NSString *)password + completion:(nullable FIRAuthDataResultCallback)completion + DEPRECATED_MSG_ATTRIBUTE( + "Please use createUserWithEmail:password:completion: for" + " Objective-C or createUser(withEmail:password:completion:)" + " for Swift instead."); + +/** @fn confirmPasswordResetWithCode:newPassword:completion: + @brief Resets the password given a code sent to the user outside of the app and a new password + for the user. + + @param newPassword The new password. + @param completion Optionally; a block which is invoked when the request finishes. Invoked + asynchronously on the main thread in the future. + + @remarks Possible error codes: + + + `FIRAuthErrorCodeWeakPassword` - Indicates an attempt to set a password that is + considered too weak. + + `FIRAuthErrorCodeOperationNotAllowed` - Indicates the administrator disabled sign + in with the specified identity provider. + + `FIRAuthErrorCodeExpiredActionCode` - Indicates the OOB code is expired. + + `FIRAuthErrorCodeInvalidActionCode` - Indicates the OOB code is invalid. + + @remarks See `FIRAuthErrors` for a list of error codes that are common to all API methods. + */ +- (void)confirmPasswordResetWithCode:(NSString *)code + newPassword:(NSString *)newPassword + completion:(FIRConfirmPasswordResetCallback)completion; + +/** @fn checkActionCode:completion: + @brief Checks the validity of an out of band code. + + @param code The out of band code to check validity. + @param completion Optionally; a block which is invoked when the request finishes. Invoked + asynchronously on the main thread in the future. + */ +- (void)checkActionCode:(NSString *)code completion:(FIRCheckActionCodeCallBack)completion; + +/** @fn verifyPasswordResetCode:completion: + @brief Checks the validity of a verify password reset code. + + @param code The password reset code to be verified. + @param completion Optionally; a block which is invoked when the request finishes. Invoked + asynchronously on the main thread in the future. + */ +- (void)verifyPasswordResetCode:(NSString *)code + completion:(FIRVerifyPasswordResetCodeCallback)completion; + +/** @fn applyActionCode:completion: + @brief Applies out of band code. + + @param code The out of band code to be applied. + @param completion Optionally; a block which is invoked when the request finishes. Invoked + asynchronously on the main thread in the future. + + @remarks This method will not work for out of band codes which require an additional parameter, + such as password reset code. + */ +- (void)applyActionCode:(NSString *)code + completion:(FIRApplyActionCodeCallback)completion; + +/** @fn sendPasswordResetWithEmail:completion: + @brief Initiates a password reset for the given email address. + + @param email The email address of the user. + @param completion Optionally; a block which is invoked when the request finishes. Invoked + asynchronously on the main thread in the future. + + @remarks Possible error codes: + + + `FIRAuthErrorCodeInvalidRecipientEmail` - Indicates an invalid recipient email was + sent in the request. + + `FIRAuthErrorCodeInvalidSender` - Indicates an invalid sender email is set in + the console for this action. + + `FIRAuthErrorCodeInvalidMessagePayload` - Indicates an invalid email template for + sending update email. + + + */ +- (void)sendPasswordResetWithEmail:(NSString *)email + completion:(nullable FIRSendPasswordResetCallback)completion; + +/** @fn sendPasswordResetWithEmail:actionCodeSetting:completion: + @brief Initiates a password reset for the given email address and @FIRActionCodeSettings object. + + @param email The email address of the user. + @param actionCodeSettings An `FIRActionCodeSettings` object containing settings related to + handling action codes. + @param completion Optionally; a block which is invoked when the request finishes. Invoked + asynchronously on the main thread in the future. + + @remarks Possible error codes: + + + `FIRAuthErrorCodeInvalidRecipientEmail` - Indicates an invalid recipient email was + sent in the request. + + `FIRAuthErrorCodeInvalidSender` - Indicates an invalid sender email is set in + the console for this action. + + `FIRAuthErrorCodeInvalidMessagePayload` - Indicates an invalid email template for + sending update email. + + `FIRAuthErrorCodeMissingIosBundleID` - Indicates that the iOS bundle ID is missing when + `handleCodeInApp` is set to YES. + + `FIRAuthErrorCodeMissingAndroidPackageName` - Indicates that the android package name + is missing when the `androidInstallApp` flag is set to true. + + `FIRAuthErrorCodeUnauthorizedDomain` - Indicates that the domain specified in the + continue URL is not whitelisted in the Firebase console. + + `FIRAuthErrorCodeInvalidContinueURI` - Indicates that the domain specified in the + continue URI is not valid. + + + */ + - (void)sendPasswordResetWithEmail:(NSString *)email + actionCodeSettings:(FIRActionCodeSettings *)actionCodeSettings + completion:(nullable FIRSendPasswordResetCallback)completion; + +/** @fn sendSignInLinkToEmail:actionCodeSettings:completion: + @brief Sends a sign in with email link to provided email address. + + @param email The email address of the user. + @param actionCodeSettings An `FIRActionCodeSettings` object containing settings related to + handling action codes. + @param completion Optionally; a block which is invoked when the request finishes. Invoked + asynchronously on the main thread in the future. + */ +- (void)sendSignInLinkToEmail:(NSString *)email + actionCodeSettings:(FIRActionCodeSettings *)actionCodeSettings + completion:(nullable FIRSendSignInLinkToEmailCallback)completion; + +/** @fn signOut: + @brief Signs out the current user. + + @param error Optionally; if an error occurs, upon return contains an NSError object that + describes the problem; is nil otherwise. + @return @YES when the sign out request was successful. @NO otherwise. + + @remarks Possible error codes: + + + `FIRAuthErrorCodeKeychainError` - Indicates an error occurred when accessing the + keychain. The `NSLocalizedFailureReasonErrorKey` field in the `NSError.userInfo` + dictionary will contain more information about the error encountered. + + + + */ +- (BOOL)signOut:(NSError *_Nullable *_Nullable)error; + +/** @fn isSignInWithEmailLink + @brief Checks if link is an email sign-in link. + + @param link The email sign-in link. + @return @YES when the link passed matches the expected format of an email sign-in link. + */ +- (BOOL)isSignInWithEmailLink:(NSString *)link; + +/** @fn addAuthStateDidChangeListener: + @brief Registers a block as an "auth state did change" listener. To be invoked when: + + + The block is registered as a listener, + + A user with a different UID from the current user has signed in, or + + The current user has signed out. + + @param listener The block to be invoked. The block is always invoked asynchronously on the main + thread, even for it's initial invocation after having been added as a listener. + + @remarks The block is invoked immediately after adding it according to it's standard invocation + semantics, asynchronously on the main thread. Users should pay special attention to + making sure the block does not inadvertently retain objects which should not be retained by + the long-lived block. The block itself will be retained by `FIRAuth` until it is + unregistered or until the `FIRAuth` instance is otherwise deallocated. + + @return A handle useful for manually unregistering the block as a listener. + */ +- (FIRAuthStateDidChangeListenerHandle)addAuthStateDidChangeListener: + (FIRAuthStateDidChangeListenerBlock)listener; + +/** @fn removeAuthStateDidChangeListener: + @brief Unregisters a block as an "auth state did change" listener. + + @param listenerHandle The handle for the listener. + */ +- (void)removeAuthStateDidChangeListener:(FIRAuthStateDidChangeListenerHandle)listenerHandle; + +/** @fn addIDTokenDidChangeListener: + @brief Registers a block as an "ID token did change" listener. To be invoked when: + + + The block is registered as a listener, + + A user with a different UID from the current user has signed in, + + The ID token of the current user has been refreshed, or + + The current user has signed out. + + @param listener The block to be invoked. The block is always invoked asynchronously on the main + thread, even for it's initial invocation after having been added as a listener. + + @remarks The block is invoked immediately after adding it according to it's standard invocation + semantics, asynchronously on the main thread. Users should pay special attention to + making sure the block does not inadvertently retain objects which should not be retained by + the long-lived block. The block itself will be retained by `FIRAuth` until it is + unregistered or until the `FIRAuth` instance is otherwise deallocated. + + @return A handle useful for manually unregistering the block as a listener. + */ +- (FIRIDTokenDidChangeListenerHandle)addIDTokenDidChangeListener: + (FIRIDTokenDidChangeListenerBlock)listener; + +/** @fn removeIDTokenDidChangeListener: + @brief Unregisters a block as an "ID token did change" listener. + + @param listenerHandle The handle for the listener. + */ +- (void)removeIDTokenDidChangeListener:(FIRIDTokenDidChangeListenerHandle)listenerHandle; + +/** @fn useAppLanguage + @brief Sets `languageCode` to the app's current language. + */ +- (void)useAppLanguage; + +#if TARGET_OS_IOS + +/** @fn canHandleURL: + @brief Whether the specific URL is handled by `FIRAuth` . + @param URL The URL received by the application delegate from any of the openURL method. + @return Whether or the URL is handled. YES means the URL is for Firebase Auth + so the caller should ignore the URL from further processing, and NO means the + the URL is for the app (or another libaray) so the caller should continue handling + this URL as usual. + @remarks If swizzling is disabled, URLs received by the application delegate must be forwarded + to this method for phone number auth to work. + */ +- (BOOL)canHandleURL:(nonnull NSURL *)URL; + +/** @fn setAPNSToken:type: + @brief Sets the APNs token along with its type. + @remarks If swizzling is disabled, the APNs Token must be set for phone number auth to work, + by either setting calling this method or by setting the `APNSToken` property. + */ +- (void)setAPNSToken:(NSData *)token type:(FIRAuthAPNSTokenType)type; + +/** @fn canHandleNotification: + @brief Whether the specific remote notification is handled by `FIRAuth` . + @param userInfo A dictionary that contains information related to the + notification in question. + @return Whether or the notification is handled. YES means the notification is for Firebase Auth + so the caller should ignore the notification from further processing, and NO means the + the notification is for the app (or another libaray) so the caller should continue handling + this notification as usual. + @remarks If swizzling is disabled, related remote notifications must be forwarded to this method + for phone number auth to work. + */ +- (BOOL)canHandleNotification:(NSDictionary *)userInfo; + +#endif // TARGET_OS_IOS + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/Public/FIRAuthAPNSTokenType.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/Public/FIRAuthAPNSTokenType.h new file mode 100644 index 0000000..4f3c9f6 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/Public/FIRAuthAPNSTokenType.h @@ -0,0 +1,40 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * @brief The APNs token type for the app. + */ +typedef NS_ENUM(NSInteger, FIRAuthAPNSTokenType) { + + /** Unknown token type. + The actual token type will be detected from the provisioning profile in the app's bundle. + */ + FIRAuthAPNSTokenTypeUnknown, + + /** Sandbox token type. + */ + FIRAuthAPNSTokenTypeSandbox, + + /** Production token type. + */ + FIRAuthAPNSTokenTypeProd, +} NS_SWIFT_NAME(AuthAPNSTokenType); + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/Public/FIRAuthCredential.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/Public/FIRAuthCredential.h new file mode 100644 index 0000000..106d844 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/Public/FIRAuthCredential.h @@ -0,0 +1,41 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** @class FIRAuthCredential + @brief Represents a credential. + */ +NS_SWIFT_NAME(AuthCredential) +@interface FIRAuthCredential : NSObject + +/** @property provider + @brief Gets the name of the identity provider for the credential. + */ +@property(nonatomic, copy, readonly) NSString *provider; + +/** @fn init + @brief This is an abstract base class. Concrete instances should be created via factory + methods available in the various authentication provider libraries (like the Facebook + provider or the Google provider libraries.) + */ +- (instancetype)init NS_UNAVAILABLE; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/Public/FIRAuthDataResult.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/Public/FIRAuthDataResult.h new file mode 100644 index 0000000..bc4fa4a --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/Public/FIRAuthDataResult.h @@ -0,0 +1,49 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +@class FIRAdditionalUserInfo; +@class FIRUser; + +NS_ASSUME_NONNULL_BEGIN + +/** @class FIRAuthDataResult + @brief Helper object that contains the result of a successful sign-in, link and reauthenticate + action. It contains references to a FIRUser instance and a FIRAdditionalUserInfo instance. + */ +NS_SWIFT_NAME(AuthDataResult) +@interface FIRAuthDataResult : NSObject + +/** @fn init + @brief This class should not be initialized manually. `FIRAuthDataResult` instance is + returned as part of `FIRAuthDataResultCallback`. + */ +- (instancetype)init NS_UNAVAILABLE; + +/** @property user + @brief The signed in user. + */ +@property(nonatomic, readonly) FIRUser *user; + +/** @property additionalUserInfo + @brief If available contains the additional IdP specific information about signed in user. + */ +@property(nonatomic, readonly, nullable) FIRAdditionalUserInfo *additionalUserInfo; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/Public/FIRAuthErrors.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/Public/FIRAuthErrors.h new file mode 100644 index 0000000..2c90274 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/Public/FIRAuthErrors.h @@ -0,0 +1,367 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** @class FIRAuthErrors + @remarks Error Codes common to all API Methods: + + + `FIRAuthErrorCodeNetworkError` + + `FIRAuthErrorCodeUserNotFound` + + `FIRAuthErrorCodeUserTokenExpired` + + `FIRAuthErrorCodeTooManyRequests` + + `FIRAuthErrorCodeInvalidAPIKey` + + `FIRAuthErrorCodeAppNotAuthorized` + + `FIRAuthErrorCodeKeychainError` + + `FIRAuthErrorCodeInternalError` + + @remarks Common error codes for `FIRUser` operations: + + + `FIRAuthErrorCodeInvalidUserToken` + + `FIRAuthErrorCodeUserDisabled` + + */ +NS_SWIFT_NAME(AuthErrors) +@interface FIRAuthErrors + +/** + @brief The Firebase Auth error domain. + */ +extern NSString *const FIRAuthErrorDomain NS_SWIFT_NAME(AuthErrorDomain); + +/** + @brief Please use `FIRAuthErrorUserInfoUpdatedCredentialKey` for Objective C or + `AuthErrorUserInfoUpdatedCredentialKey` for Swift instead. + */ +extern NSString *const FIRAuthUpdatedCredentialKey + NS_SWIFT_NAME(AuthUpdatedCredentialKey) __attribute__((deprecated)); + +/** + @brief Please use `FIRAuthErrorUserInfoNameKey` for Objective C or + `AuthErrorUserInfoNameKey` for Swift instead. + */ +extern NSString *const FIRAuthErrorNameKey + NS_SWIFT_NAME(AuthErrorNameKey) __attribute__((deprecated)); + +/** + @brief The name of the key for the error short string of an error code. + */ +extern NSString *const FIRAuthErrorUserInfoNameKey NS_SWIFT_NAME(AuthErrorUserInfoNameKey); + +/** + @brief Errors with one of the following three codes: + - `FIRAuthErrorCodeAccountExistsWithDifferentCredential` + - `FIRAuthErrorCodeCredentialAlreadyInUse` + - `FIRAuthErrorCodeEmailAlreadyInUse` + may contain an `NSError.userInfo` dictinary object which contains this key. The value + associated with this key is an NSString of the email address of the account that already + exists. + */ +extern NSString *const FIRAuthErrorUserInfoEmailKey NS_SWIFT_NAME(AuthErrorUserInfoEmailKey); + +/** + @brief The key used to read the updated Auth credential from the userInfo dictionary of the + NSError object returned. This is the updated auth credential the developer should use for + recovery if applicable. + */ +extern NSString *const FIRAuthErrorUserInfoUpdatedCredentialKey + NS_SWIFT_NAME(AuthErrorUserInfoUpdatedCredentialKey); + +/** + @brief Error codes used by Firebase Auth. + */ +typedef NS_ENUM(NSInteger, FIRAuthErrorCode) { + /** Indicates a validation error with the custom token. + */ + FIRAuthErrorCodeInvalidCustomToken = 17000, + + /** Indicates the service account and the API key belong to different projects. + */ + FIRAuthErrorCodeCustomTokenMismatch = 17002, + + /** Indicates the IDP token or requestUri is invalid. + */ + FIRAuthErrorCodeInvalidCredential = 17004, + + /** Indicates the user's account is disabled on the server. + */ + FIRAuthErrorCodeUserDisabled = 17005, + + /** Indicates the administrator disabled sign in with the specified identity provider. + */ + FIRAuthErrorCodeOperationNotAllowed = 17006, + + /** Indicates the email used to attempt a sign up is already in use. + */ + FIRAuthErrorCodeEmailAlreadyInUse = 17007, + + /** Indicates the email is invalid. + */ + FIRAuthErrorCodeInvalidEmail = 17008, + + /** Indicates the user attempted sign in with a wrong password. + */ + FIRAuthErrorCodeWrongPassword = 17009, + + /** Indicates that too many requests were made to a server method. + */ + FIRAuthErrorCodeTooManyRequests = 17010, + + /** Indicates the user account was not found. + */ + FIRAuthErrorCodeUserNotFound = 17011, + + /** Indicates account linking is required. + */ + FIRAuthErrorCodeAccountExistsWithDifferentCredential = 17012, + + /** Indicates the user has attemped to change email or password more than 5 minutes after + signing in. + */ + FIRAuthErrorCodeRequiresRecentLogin = 17014, + + /** Indicates an attempt to link a provider to which the account is already linked. + */ + FIRAuthErrorCodeProviderAlreadyLinked = 17015, + + /** Indicates an attempt to unlink a provider that is not linked. + */ + FIRAuthErrorCodeNoSuchProvider = 17016, + + /** Indicates user's saved auth credential is invalid, the user needs to sign in again. + */ + FIRAuthErrorCodeInvalidUserToken = 17017, + + /** Indicates a network error occurred (such as a timeout, interrupted connection, or + unreachable host). These types of errors are often recoverable with a retry. The + `NSUnderlyingError` field in the `NSError.userInfo` dictionary will contain the error + encountered. + */ + FIRAuthErrorCodeNetworkError = 17020, + + /** Indicates the saved token has expired, for example, the user may have changed account + password on another device. The user needs to sign in again on the device that made this + request. + */ + FIRAuthErrorCodeUserTokenExpired = 17021, + + /** Indicates an invalid API key was supplied in the request. + */ + FIRAuthErrorCodeInvalidAPIKey = 17023, + + /** Indicates that an attempt was made to reauthenticate with a user which is not the current + user. + */ + FIRAuthErrorCodeUserMismatch = 17024, + + /** Indicates an attempt to link with a credential that has already been linked with a + different Firebase account + */ + FIRAuthErrorCodeCredentialAlreadyInUse = 17025, + + /** Indicates an attempt to set a password that is considered too weak. + */ + FIRAuthErrorCodeWeakPassword = 17026, + + /** Indicates the App is not authorized to use Firebase Authentication with the + provided API Key. + */ + FIRAuthErrorCodeAppNotAuthorized = 17028, + + /** Indicates the OOB code is expired. + */ + FIRAuthErrorCodeExpiredActionCode = 17029, + + /** Indicates the OOB code is invalid. + */ + FIRAuthErrorCodeInvalidActionCode = 17030, + + /** Indicates that there are invalid parameters in the payload during a "send password reset + * email" attempt. + */ + FIRAuthErrorCodeInvalidMessagePayload = 17031, + + /** Indicates that the sender email is invalid during a "send password reset email" attempt. + */ + FIRAuthErrorCodeInvalidSender = 17032, + + /** Indicates that the recipient email is invalid. + */ + FIRAuthErrorCodeInvalidRecipientEmail = 17033, + + /** Indicates that an email address was expected but one was not provided. + */ + FIRAuthErrorCodeMissingEmail = 17034, + + // The enum values 17035 is reserved and should NOT be used for new error codes. + + /** Indicates that the iOS bundle ID is missing when a iOS App Store ID is provided. + */ + FIRAuthErrorCodeMissingIosBundleID = 17036, + + /** Indicates that the android package name is missing when the `androidInstallApp` flag is set + to true. + */ + FIRAuthErrorCodeMissingAndroidPackageName = 17037, + + /** Indicates that the domain specified in the continue URL is not whitelisted in the Firebase + console. + */ + FIRAuthErrorCodeUnauthorizedDomain = 17038, + + /** Indicates that the domain specified in the continue URI is not valid. + */ + FIRAuthErrorCodeInvalidContinueURI = 17039, + + /** Indicates that a continue URI was not provided in a request to the backend which requires + one. + */ + FIRAuthErrorCodeMissingContinueURI = 17040, + + /** Indicates that a phone number was not provided in a call to + `verifyPhoneNumber:completion:`. + */ + FIRAuthErrorCodeMissingPhoneNumber = 17041, + + /** Indicates that an invalid phone number was provided in a call to + `verifyPhoneNumber:completion:`. + */ + FIRAuthErrorCodeInvalidPhoneNumber = 17042, + + /** Indicates that the phone auth credential was created with an empty verification code. + */ + FIRAuthErrorCodeMissingVerificationCode = 17043, + + /** Indicates that an invalid verification code was used in the verifyPhoneNumber request. + */ + FIRAuthErrorCodeInvalidVerificationCode = 17044, + + /** Indicates that the phone auth credential was created with an empty verification ID. + */ + FIRAuthErrorCodeMissingVerificationID = 17045, + + /** Indicates that an invalid verification ID was used in the verifyPhoneNumber request. + */ + FIRAuthErrorCodeInvalidVerificationID = 17046, + + /** Indicates that the APNS device token is missing in the verifyClient request. + */ + FIRAuthErrorCodeMissingAppCredential = 17047, + + /** Indicates that an invalid APNS device token was used in the verifyClient request. + */ + FIRAuthErrorCodeInvalidAppCredential = 17048, + + // The enum values between 17048 and 17051 are reserved and should NOT be used for new error + // codes. + + /** Indicates that the SMS code has expired. + */ + FIRAuthErrorCodeSessionExpired = 17051, + + /** Indicates that the quota of SMS messages for a given project has been exceeded. + */ + FIRAuthErrorCodeQuotaExceeded = 17052, + + /** Indicates that the APNs device token could not be obtained. The app may not have set up + remote notification correctly, or may fail to forward the APNs device token to FIRAuth + if app delegate swizzling is disabled. + */ + FIRAuthErrorCodeMissingAppToken = 17053, + + /** Indicates that the app fails to forward remote notification to FIRAuth. + */ + FIRAuthErrorCodeNotificationNotForwarded = 17054, + + /** Indicates that the app could not be verified by Firebase during phone number authentication. + */ + FIRAuthErrorCodeAppNotVerified = 17055, + + /** Indicates that the reCAPTCHA token is not valid. + */ + FIRAuthErrorCodeCaptchaCheckFailed = 17056, + + /** Indicates that an attempt was made to present a new web context while one was already being + presented. + */ + FIRAuthErrorCodeWebContextAlreadyPresented = 17057, + + /** Indicates that the URL presentation was cancelled prematurely by the user. + */ + FIRAuthErrorCodeWebContextCancelled = 17058, + + /** Indicates a general failure during the app verification flow. + */ + FIRAuthErrorCodeAppVerificationUserInteractionFailure = 17059, + + /** Indicates that the clientID used to invoke a web flow is invalid. + */ + FIRAuthErrorCodeInvalidClientID = 17060, + + /** Indicates that a network request within a SFSafariViewController or UIWebview failed. + */ + FIRAuthErrorCodeWebNetworkRequestFailed = 17061, + + /** Indicates that an internal error occurred within a SFSafariViewController or UIWebview. + */ + FIRAuthErrorCodeWebInternalError = 17062, + + /** Indicates a general failure during a web sign-in flow. + */ + FIRAuthErrorCodeWebSignInUserInteractionFailure = 17063, + + /** Indicates that the local player was not authenticated prior to attempting Game Center signin. + */ + FIRAuthErrorCodeLocalPlayerNotAuthenticated = 17066, + + /** Indicates that a non-null user was expected as an argmument to the operation but a null + user was provided. + */ + FIRAuthErrorCodeNullUser = 17067, + + /** + * Represents the error code for when the given provider id for a web operation is invalid. + */ + FIRAuthErrorCodeInvalidProviderID = 17071, + + /** Indicates that the Firebase Dynamic Link domain used is either not configured or is unauthorized + for the current project. + */ + FIRAuthErrorCodeInvalidDynamicLinkDomain = 17074, + + /** Indicates that the GameKit framework is not linked prior to attempting Game Center signin. + */ + FIRAuthErrorCodeGameKitNotLinked = 17076, + + /** Indicates an error occurred while attempting to access the keychain. + */ + FIRAuthErrorCodeKeychainError = 17995, + + /** Indicates an internal error occurred. + */ + FIRAuthErrorCodeInternalError = 17999, + + /** Raised when a JWT fails to parse correctly. May be accompanied by an underlying error + describing which step of the JWT parsing process failed. + */ + FIRAuthErrorCodeMalformedJWT = 18000, +} NS_SWIFT_NAME(AuthErrorCode); + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/Public/FIRAuthSettings.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/Public/FIRAuthSettings.h new file mode 100644 index 0000000..05fc601 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/Public/FIRAuthSettings.h @@ -0,0 +1,34 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** @class FIRAuthSettings + @brief Determines settings related to an auth object. + */ +@interface FIRAuthSettings : NSObject + +/** @property appVerificationDisabledForTesting + @brief Flag to determine whether app verification should be disabled for testing or not. + */ +@property (nonatomic, assign, getter=isAppVerificationDisabledForTesting) BOOL + appVerificationDisabledForTesting; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/Public/FIRAuthTokenResult.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/Public/FIRAuthTokenResult.h new file mode 100644 index 0000000..9e0028d --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/Public/FIRAuthTokenResult.h @@ -0,0 +1,66 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** @class FIRAuthTokenResult + @brief A data class containing the ID token JWT string and other properties associated with the + token including the decoded payload claims. + */ +NS_SWIFT_NAME(AuthTokenResult) +@interface FIRAuthTokenResult : NSObject + +/** @property token + @brief Stores the JWT string of the ID token. + */ +@property (nonatomic, readonly) NSString *token; + +/** @property expirationDate + @brief Stores the ID token's expiration date. + */ +@property (nonatomic, readonly) NSDate *expirationDate; + +/** @property authDate + @brief Stores the ID token's authentication date. + @remarks This is the date the user was signed in and NOT the date the token was refreshed. + */ +@property (nonatomic, readonly) NSDate *authDate; + +/** @property issuedAtDate + @brief Stores the date that the ID token was issued. + @remarks This is the date last refreshed and NOT the last authentication date. + */ +@property (nonatomic, readonly) NSDate *issuedAtDate; + +/** @property signInProvider + @brief Stores sign-in provider through which the token was obtained. + @remarks This does not necessarily map to provider IDs. + */ +@property (nonatomic, readonly) NSString *signInProvider; + +/** @property claims + @brief Stores the entire payload of claims found on the ID token. This includes the standard + reserved claims as well as custom claims set by the developer via the Admin SDK. + */ +@property (nonatomic, readonly) NSDictionary *claims; + + + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/Public/FIRAuthUIDelegate.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/Public/FIRAuthUIDelegate.h new file mode 100644 index 0000000..9df4f6e --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/Public/FIRAuthUIDelegate.h @@ -0,0 +1,53 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +@class UIViewController; + +NS_ASSUME_NONNULL_BEGIN + +/** @protocol FIRAuthUIDelegate + @brief A protocol to handle user interface interactions for Firebase Auth. + */ +NS_SWIFT_NAME(AuthUIDelegate) +@protocol FIRAuthUIDelegate + +/** @fn presentViewController:animated:completion: + @brief If implemented, this method will be invoked when Firebase Auth needs to display a view + controller. + @param viewControllerToPresent The view controller to be presented. + @param flag Decides whether the view controller presentation should be animated or not. + @param completion The block to execute after the presentation finishes. This block has no return + value and takes no parameters. +*/ +- (void)presentViewController:(UIViewController *)viewControllerToPresent + animated:(BOOL)flag + completion:(void (^ _Nullable)(void))completion; + +/** @fn dismissViewControllerAnimated:completion: + @brief If implemented, this method will be invoked when Firebase Auth needs to display a view + controller. + @param flag Decides whether removing the view controller should be animated or not. + @param completion The block to execute after the presentation finishes. This block has no return + value and takes no parameters. +*/ +- (void)dismissViewControllerAnimated:(BOOL)flag completion:(void (^ _Nullable)(void))completion + NS_SWIFT_NAME(dismiss(animated:completion:)); + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/Public/FIREmailAuthProvider.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/Public/FIREmailAuthProvider.h new file mode 100644 index 0000000..b6375bd --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/Public/FIREmailAuthProvider.h @@ -0,0 +1,81 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +@class FIRAuthCredential; + +NS_ASSUME_NONNULL_BEGIN + +/** + @brief A string constant identifying the email & password identity provider. + */ +extern NSString *const FIREmailAuthProviderID NS_SWIFT_NAME(EmailAuthProviderID); + +/** + @brief A string constant identifying the email-link sign-in method. + */ +extern NSString *const FIREmailLinkAuthSignInMethod NS_SWIFT_NAME(EmailLinkAuthSignInMethod); + +/** + @brief A string constant identifying the email & password sign-in method. + */ +extern NSString *const FIREmailPasswordAuthSignInMethod + NS_SWIFT_NAME(EmailPasswordAuthSignInMethod); + +/** + @brief Please use `FIREmailAuthProviderID` for Objective-C or `EmailAuthProviderID` for Swift instead. + */ +extern NSString *const FIREmailPasswordAuthProviderID __attribute__((deprecated)); + +/** @class FIREmailAuthProvider + @brief A concrete implementation of `FIRAuthProvider` for Email & Password Sign In. + */ +NS_SWIFT_NAME(EmailAuthProvider) +@interface FIREmailAuthProvider : NSObject + +/** @typedef FIREmailPasswordAuthProvider + @brief Please use `FIREmailAuthProvider` instead. + */ +typedef FIREmailAuthProvider FIREmailPasswordAuthProvider __attribute__((deprecated)); + + +/** @fn credentialWithEmail:password: + @brief Creates an `FIRAuthCredential` for an email & password sign in. + + @param email The user's email address. + @param password The user's password. + @return A FIRAuthCredential containing the email & password credential. + */ ++ (FIRAuthCredential *)credentialWithEmail:(NSString *)email password:(NSString *)password; + +/** @fn credentialWithEmail:Link: + @brief Creates an `FIRAuthCredential` for an email & link sign in. + + @param email The user's email address. + @param link The email sign-in link. + @return A FIRAuthCredential containing the email & link credential. + */ ++ (FIRAuthCredential *)credentialWithEmail:(NSString *)email link:(NSString *)link; + +/** @fn init + @brief This class is not meant to be initialized. + */ +- (instancetype)init NS_UNAVAILABLE; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/Public/FIRFacebookAuthProvider.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/Public/FIRFacebookAuthProvider.h new file mode 100644 index 0000000..75efe13 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/Public/FIRFacebookAuthProvider.h @@ -0,0 +1,54 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +@class FIRAuthCredential; + +NS_ASSUME_NONNULL_BEGIN + +/** + @brief A string constant identifying the Facebook identity provider. + */ +extern NSString *const FIRFacebookAuthProviderID NS_SWIFT_NAME(FacebookAuthProviderID); + +/** + @brief A string constant identifying the Facebook sign-in method. + */ +extern NSString *const _Nonnull FIRFacebookAuthSignInMethod NS_SWIFT_NAME(FacebookAuthSignInMethod); + +/** @class FIRFacebookAuthProvider + @brief Utility class for constructing Facebook credentials. + */ +NS_SWIFT_NAME(FacebookAuthProvider) +@interface FIRFacebookAuthProvider : NSObject + +/** @fn credentialWithAccessToken: + @brief Creates an `FIRAuthCredential` for a Facebook sign in. + + @param accessToken The Access Token from Facebook. + @return A FIRAuthCredential containing the Facebook credentials. + */ ++ (FIRAuthCredential *)credentialWithAccessToken:(NSString *)accessToken; + +/** @fn init + @brief This class should not be initialized. + */ +- (instancetype)init NS_UNAVAILABLE; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/Public/FIRFederatedAuthProvider.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/Public/FIRFederatedAuthProvider.h new file mode 100644 index 0000000..51190e2 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/Public/FIRFederatedAuthProvider.h @@ -0,0 +1,52 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +#if TARGET_OS_IOS +#import "FIRAuthUIDelegate.h" +#endif // TARGET_OS_IOS + +@class FIRAuthCredential; + +NS_ASSUME_NONNULL_BEGIN + +NS_SWIFT_NAME(FederatedAuthProvider) +@protocol FIRFederatedAuthProvider + +/** @typedef FIRAuthCredentialCallback + @brief The type of block invoked when obtaining an auth credential. + @param credential The credential obtained. + @param error The error that occurred if any. + */ +typedef void(^FIRAuthCredentialCallback)(FIRAuthCredential *_Nullable credential, + NSError *_Nullable error) + NS_SWIFT_NAME(AuthCredentialCallback); + +#if TARGET_OS_IOS +/** @fn getCredentialWithUIDelegate:completion: + @brief Used to obtain an auth credential via a mobile web flow. + @param UIDelegate An optional UI delegate used to presenet the mobile web flow. + @param completion Optionally; a block which is invoked asynchronously on the main thread when + the mobile web flow is completed. + */ +- (void)getCredentialWithUIDelegate:(nullable id)UIDelegate + completion:(nullable FIRAuthCredentialCallback)completion; +#endif // TARGET_OS_IOS + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/Public/FIRGameCenterAuthProvider.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/Public/FIRGameCenterAuthProvider.h new file mode 100644 index 0000000..5e59404 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/Public/FIRGameCenterAuthProvider.h @@ -0,0 +1,62 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#import + +@class FIRAuthCredential; + +NS_ASSUME_NONNULL_BEGIN + +/** + @brief A string constant identifying the Game Center identity provider. + */ +extern NSString *const FIRGameCenterAuthProviderID NS_SWIFT_NAME(GameCenterAuthProviderID); + +/** + @brief A string constant identifying the Game Center sign-in method. + */ +extern NSString *const _Nonnull FIRGameCenterAuthSignInMethod +NS_SWIFT_NAME(GameCenterAuthSignInMethod); + +/** @typedef FIRGameCenterCredentialCallback + @brief The type of block invoked when the Game Center credential code has finished. + @param credential On success, the credential will be provided, nil otherwise. + @param error On error, the error that occurred, nil otherwise. + */ +typedef void (^FIRGameCenterCredentialCallback)(FIRAuthCredential *_Nullable credential, + NSError *_Nullable error) +NS_SWIFT_NAME(GameCenterCredentialCallback); + +/** @class FIRGameCenterAuthProvider + @brief A concrete implementation of @c FIRAuthProvider for Game Center Sign In. + */ +NS_SWIFT_NAME(GameCenterAuthProvider) +@interface FIRGameCenterAuthProvider : NSObject + +/** @fn getCredentialWithCompletion: + @brief Creates a @c FIRAuthCredential for a Game Center sign in. + */ ++ (void)getCredentialWithCompletion:(FIRGameCenterCredentialCallback)completion +NS_SWIFT_NAME(getCredential(completion:)); + +/** @fn init + @brief This class is not meant to be initialized. + */ +- (instancetype)init NS_UNAVAILABLE; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/Public/FIRGitHubAuthProvider.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/Public/FIRGitHubAuthProvider.h new file mode 100644 index 0000000..0610427 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/Public/FIRGitHubAuthProvider.h @@ -0,0 +1,55 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +@class FIRAuthCredential; + +NS_ASSUME_NONNULL_BEGIN + +/** + @brief A string constant identifying the GitHub identity provider. + */ +extern NSString *const FIRGitHubAuthProviderID NS_SWIFT_NAME(GitHubAuthProviderID); + +/** + @brief A string constant identifying the GitHub sign-in method. + */ +extern NSString *const _Nonnull FIRGitHubAuthSignInMethod NS_SWIFT_NAME(GitHubAuthSignInMethod); + + +/** @class FIRGitHubAuthProvider + @brief Utility class for constructing GitHub credentials. + */ +NS_SWIFT_NAME(GitHubAuthProvider) +@interface FIRGitHubAuthProvider : NSObject + +/** @fn credentialWithToken: + @brief Creates an `FIRAuthCredential` for a GitHub sign in. + + @param token The GitHub OAuth access token. + @return A FIRAuthCredential containing the GitHub credential. + */ ++ (FIRAuthCredential *)credentialWithToken:(NSString *)token; + +/** @fn init + @brief This class is not meant to be initialized. + */ +- (instancetype)init NS_UNAVAILABLE; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/Public/FIRGoogleAuthProvider.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/Public/FIRGoogleAuthProvider.h new file mode 100644 index 0000000..7d6fa22 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/Public/FIRGoogleAuthProvider.h @@ -0,0 +1,56 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +@class FIRAuthCredential; + +NS_ASSUME_NONNULL_BEGIN + +/** + @brief A string constant identifying the Google identity provider. + */ +extern NSString *const FIRGoogleAuthProviderID NS_SWIFT_NAME(GoogleAuthProviderID); + +/** + @brief A string constant identifying the Google sign-in method. + */ +extern NSString *const _Nonnull FIRGoogleAuthSignInMethod NS_SWIFT_NAME(GoogleAuthSignInMethod); + +/** @class FIRGoogleAuthProvider + @brief Utility class for constructing Google Sign In credentials. + */ +NS_SWIFT_NAME(GoogleAuthProvider) +@interface FIRGoogleAuthProvider : NSObject + +/** @fn credentialWithIDToken:accessToken: + @brief Creates an `FIRAuthCredential` for a Google sign in. + + @param IDToken The ID Token from Google. + @param accessToken The Access Token from Google. + @return A FIRAuthCredential containing the Google credentials. + */ ++ (FIRAuthCredential *)credentialWithIDToken:(NSString *)IDToken + accessToken:(NSString *)accessToken; + +/** @fn init + @brief This class should not be initialized. + */ +- (instancetype)init NS_UNAVAILABLE; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/Public/FIROAuthCredential.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/Public/FIROAuthCredential.h new file mode 100644 index 0000000..43b1d81 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/Public/FIROAuthCredential.h @@ -0,0 +1,51 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +#import "FIRAuthCredential.h" + +NS_ASSUME_NONNULL_BEGIN + +/** @class FIROAuthCredential + @brief Internal implementation of FIRAuthCredential for generic credentials. + */ +NS_SWIFT_NAME(OAuthCredential) +@interface FIROAuthCredential : FIRAuthCredential + +/** @property IDToken + @brief The ID Token associated with this credential. + */ +@property(nonatomic, readonly, nullable) NSString *IDToken; + +/** @property accessToken + @brief The access token associated with this credential. + */ +@property(nonatomic, readonly, nullable) NSString *accessToken; + +/** @property pendingToken + @brief The pending token used when completing the headful-lite flow. + */ +@property(nonatomic, readonly, nullable) NSString *pendingToken; + +/** @fn init + @brief This class is not supposed to be instantiated directly. + */ +- (instancetype)init NS_UNAVAILABLE; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/Public/FIROAuthProvider.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/Public/FIROAuthProvider.h new file mode 100644 index 0000000..1ddf1f8 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/Public/FIROAuthProvider.h @@ -0,0 +1,123 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +#import "FIRFederatedAuthProvider.h" + +@class FIRAuth; +@class FIROAuthCredential; + +NS_ASSUME_NONNULL_BEGIN + +/** + @brief A string constant identifying the Microsoft identity provider. + */ +extern NSString *const FIRMicrosoftAuthProviderID NS_SWIFT_NAME(MicrosoftAuthProviderID) + DEPRECATED_MSG_ATTRIBUTE("Please use \"microsoft.com\" instead."); + +/** + @brief A string constant identifying the Yahoo identity provider. + */ +extern NSString *const FIRYahooAuthProviderID NS_SWIFT_NAME(YahooAuthProviderID) + DEPRECATED_MSG_ATTRIBUTE("Please use \"yahoo.com\" instead."); + +/** @class FIROAuthProvider + @brief A concrete implementation of `FIRAuthProvider` for generic OAuth Providers. + */ +NS_SWIFT_NAME(OAuthProvider) +@interface FIROAuthProvider : NSObject + +/** @property scopes + @brief Array used to configure the OAuth scopes. + */ +@property(nonatomic, copy, nullable) NSArray *scopes; + +/** @property customParameters + @brief Dictionary used to configure the OAuth custom parameters. + */ +@property(nonatomic, copy, nullable) NSDictionary *customParameters; + +/** @property providerID + @brief The provider ID indicating the specific OAuth provider this OAuthProvider instance + represents. + */ +@property(nonatomic, copy, readonly) NSString *providerID; + +/** @fn providerWithProviderID: + @param providerID The provider ID of the IDP for which this auth provider instance will be + configured. + @return An instance of FIROAuthProvider corresponding to the specified provider ID. + */ ++ (FIROAuthProvider *)providerWithProviderID:(NSString *)providerID; + +/** @fn providerWithProviderID:auth: + @param providerID The provider ID of the IDP for which this auth provider instance will be + configured. + @param auth The auth instance to be associated with the FIROAuthProvider instance. + @return An instance of FIROAuthProvider corresponding to the specified provider ID. + */ ++ (FIROAuthProvider *)providerWithProviderID:(NSString *)providerID auth:(FIRAuth *)auth; + +/** @fn credentialWithProviderID:IDToken:accessToken: + @brief Creates an `FIRAuthCredential` for that OAuth 2 provider identified by providerID, ID + token and access token. + + @param providerID The provider ID associated with the Auth credential being created. + @param IDToken The IDToken associated with the Auth credential being created. + @param accessToken The accessstoken associated with the Auth credential be created, if + available. + @param pendingToken The pending token used when completing the headful-lite flow. + @return A FIRAuthCredential for the specified provider ID, ID token and access token. + */ ++ (FIROAuthCredential *)credentialWithProviderID:(NSString *)providerID + IDToken:(NSString *)IDToken + accessToken:(nullable NSString *)accessToken + pendingToken:(nullable NSString *)pendingToken; + +/** @fn credentialWithProviderID:IDToken:accessToken: + @brief Creates an `FIRAuthCredential` for that OAuth 2 provider identified by providerID, ID + token and access token. + + @param providerID The provider ID associated with the Auth credential being created. + @param IDToken The IDToken associated with the Auth credential being created. + @param accessToken The accessstoken associated with the Auth credential be created, if + available. + @return A FIRAuthCredential for the specified provider ID, ID token and access token. + */ ++ (FIROAuthCredential *)credentialWithProviderID:(NSString *)providerID + IDToken:(NSString *)IDToken + accessToken:(nullable NSString *)accessToken; + +/** @fn credentialWithProviderID:accessToken: + @brief Creates an `FIRAuthCredential` for that OAuth 2 provider identified by providerID using + an ID token. + + @param providerID The provider ID associated with the Auth credential being created. + @param accessToken The accessstoken associated with the Auth credential be created + @return A FIRAuthCredential. + */ ++ (FIROAuthCredential *)credentialWithProviderID:(NSString *)providerID + accessToken:(NSString *)accessToken; + +/** @fn init + @brief This class is not meant to be initialized. + */ +- (instancetype)init NS_UNAVAILABLE; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/Public/FIRPhoneAuthCredential.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/Public/FIRPhoneAuthCredential.h new file mode 100644 index 0000000..9f5f596 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/Public/FIRPhoneAuthCredential.h @@ -0,0 +1,36 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +#import "FIRAuthCredential.h" + +NS_ASSUME_NONNULL_BEGIN + +/** @class FIRPhoneAuthCredential + @brief Implementation of FIRAuthCredential for Phone Auth credentials. + */ +NS_SWIFT_NAME(PhoneAuthCredential) +@interface FIRPhoneAuthCredential : FIRAuthCredential + +/** @fn init + @brief This class is not supposed to be instantiated directly. + */ +- (instancetype)init NS_UNAVAILABLE; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/Public/FIRPhoneAuthProvider.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/Public/FIRPhoneAuthProvider.h new file mode 100644 index 0000000..a4301c1 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/Public/FIRPhoneAuthProvider.h @@ -0,0 +1,105 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +@class FIRAuth; +@class FIRPhoneAuthCredential; +@protocol FIRAuthUIDelegate; + +NS_ASSUME_NONNULL_BEGIN + +/** @var FIRPhoneAuthProviderID + @brief A string constant identifying the phone identity provider. + */ +extern NSString *const FIRPhoneAuthProviderID NS_SWIFT_NAME(PhoneAuthProviderID); + +/** @var FIRPhoneAuthProviderID + @brief A string constant identifying the phone sign-in method. + */ +extern NSString *const _Nonnull FIRPhoneAuthSignInMethod NS_SWIFT_NAME(PhoneAuthSignInMethod); + +/** @typedef FIRVerificationResultCallback + @brief The type of block invoked when a request to send a verification code has finished. + + @param verificationID On success, the verification ID provided, nil otherwise. + @param error On error, the error that occurred, nil otherwise. + */ +typedef void (^FIRVerificationResultCallback) + (NSString *_Nullable verificationID, NSError *_Nullable error) + NS_SWIFT_NAME(VerificationResultCallback); + +/** @class FIRPhoneAuthProvider + @brief A concrete implementation of `FIRAuthProvider` for phone auth providers. + */ +NS_SWIFT_NAME(PhoneAuthProvider) +@interface FIRPhoneAuthProvider : NSObject + +/** @fn provider + @brief Returns an instance of `FIRPhoneAuthProvider` for the default `FIRAuth` object. + */ ++ (instancetype)provider NS_SWIFT_NAME(provider()); + +/** @fn providerWithAuth: + @brief Returns an instance of `FIRPhoneAuthProvider` for the provided `FIRAuth` object. + + @param auth The auth object to associate with the phone auth provider instance. + */ ++ (instancetype)providerWithAuth:(FIRAuth *)auth NS_SWIFT_NAME(provider(auth:)); + +/** @fn verifyPhoneNumber:UIDelegate:completion: + @brief Starts the phone number authentication flow by sending a verification code to the + specified phone number. + @param phoneNumber The phone number to be verified. + @param UIDelegate An object used to present the SFSafariViewController. The object is retained + by this method until the completion block is executed. + @param completion The callback to be invoked when the verification flow is finished. + @remarks Possible error codes: + + + `FIRAuthErrorCodeCaptchaCheckFailed` - Indicates that the reCAPTCHA token obtained by + the Firebase Auth is invalid or has expired. + + `FIRAuthErrorCodeQuotaExceeded` - Indicates that the phone verification quota for this + project has been exceeded. + + `FIRAuthErrorCodeInvalidPhoneNumber` - Indicates that the phone number provided is + invalid. + + `FIRAuthErrorCodeMissingPhoneNumber` - Indicates that a phone number was not provided. + */ +- (void)verifyPhoneNumber:(NSString *)phoneNumber + UIDelegate:(nullable id)UIDelegate + completion:(nullable FIRVerificationResultCallback)completion; + +/** @fn credentialWithVerificationID:verificationCode: + @brief Creates an `FIRAuthCredential` for the phone number provider identified by the + verification ID and verification code. + + @param verificationID The verification ID obtained from invoking + verifyPhoneNumber:completion: + @param verificationCode The verification code obtained from the user. + @return The corresponding phone auth credential for the verification ID and verification code + provided. + */ +- (FIRPhoneAuthCredential *)credentialWithVerificationID:(NSString *)verificationID + verificationCode:(NSString *)verificationCode; + +/** @fn init + @brief Please use the `provider` or `providerWithAuth:` methods to obtain an instance of + `FIRPhoneAuthProvider`. + */ +- (instancetype)init NS_UNAVAILABLE; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/Public/FIRTwitterAuthProvider.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/Public/FIRTwitterAuthProvider.h new file mode 100644 index 0000000..a0d1166 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/Public/FIRTwitterAuthProvider.h @@ -0,0 +1,56 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +@class FIRAuthCredential; + +NS_ASSUME_NONNULL_BEGIN + +/** + @brief A string constant identifying the Twitter identity provider. + */ +extern NSString *const FIRTwitterAuthProviderID NS_SWIFT_NAME(TwitterAuthProviderID); + +/** + @brief A string constant identifying the Twitter sign-in method. + */ +extern NSString *const _Nonnull FIRTwitterAuthSignInMethod NS_SWIFT_NAME(TwitterAuthSignInMethod); + + +/** @class FIRTwitterAuthProvider + @brief Utility class for constructing Twitter credentials. + */ +NS_SWIFT_NAME(TwitterAuthProvider) +@interface FIRTwitterAuthProvider : NSObject + +/** @fn credentialWithToken:secret: + @brief Creates an `FIRAuthCredential` for a Twitter sign in. + + @param token The Twitter OAuth token. + @param secret The Twitter OAuth secret. + @return A FIRAuthCredential containing the Twitter credential. + */ ++ (FIRAuthCredential *)credentialWithToken:(NSString *)token secret:(NSString *)secret; + +/** @fn init + @brief This class is not meant to be initialized. + */ +- (instancetype)init NS_UNAVAILABLE; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/Public/FIRUser.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/Public/FIRUser.h new file mode 100644 index 0000000..cc5d0a0 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/Public/FIRUser.h @@ -0,0 +1,495 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +#import "FIRAuth.h" +#import "FIRAuthDataResult.h" +#import "FIRUserInfo.h" + +@class FIRAuthTokenResult; +@class FIRPhoneAuthCredential; +@class FIRUserProfileChangeRequest; +@class FIRUserMetadata; + +NS_ASSUME_NONNULL_BEGIN + +/** @typedef FIRAuthTokenCallback + @brief The type of block called when a token is ready for use. + @see FIRUser.getIDTokenWithCompletion: + @see FIRUser.getIDTokenForcingRefresh:withCompletion: + + @param token Optionally; an access token if the request was successful. + @param error Optionally; the error which occurred - or nil if the request was successful. + + @remarks One of: `token` or `error` will always be non-nil. + */ +typedef void (^FIRAuthTokenCallback)(NSString *_Nullable token, NSError *_Nullable error) + NS_SWIFT_NAME(AuthTokenCallback); + +/** @typedef FIRAuthTokenResultCallback + @brief The type of block called when a token is ready for use. + @see FIRUser.getIDTokenResultWithCompletion: + @see FIRUser.getIDTokenResultForcingRefresh:withCompletion: + + @param tokenResult Optionally; an object containing the raw access token string as well as other + useful data pertaining to the token. + @param error Optionally; the error which occurred - or nil if the request was successful. + + @remarks One of: `token` or `error` will always be non-nil. + */ +typedef void (^FIRAuthTokenResultCallback)(FIRAuthTokenResult *_Nullable tokenResult, + NSError *_Nullable error) + NS_SWIFT_NAME(AuthTokenResultCallback); + +/** @typedef FIRUserProfileChangeCallback + @brief The type of block called when a user profile change has finished. + + @param error Optionally; the error which occurred - or nil if the request was successful. + */ +typedef void (^FIRUserProfileChangeCallback)(NSError *_Nullable error) + NS_SWIFT_NAME(UserProfileChangeCallback); + +/** @typedef FIRSendEmailVerificationCallback + @brief The type of block called when a request to send an email verification has finished. + + @param error Optionally; the error which occurred - or nil if the request was successful. + */ +typedef void (^FIRSendEmailVerificationCallback)(NSError *_Nullable error) + NS_SWIFT_NAME(SendEmailVerificationCallback); + +/** @class FIRUser + @brief Represents a user. Firebase Auth does not attempt to validate users + when loading them from the keychain. Invalidated users (such as those + whose passwords have been changed on another client) are automatically + logged out when an auth-dependent operation is attempted or when the + ID token is automatically refreshed. + @remarks This class is thread-safe. + */ +NS_SWIFT_NAME(User) +@interface FIRUser : NSObject + +/** @property anonymous + @brief Indicates the user represents an anonymous user. + */ +@property(nonatomic, readonly, getter=isAnonymous) BOOL anonymous; + +/** @property emailVerified + @brief Indicates the email address associated with this user has been verified. + */ +@property(nonatomic, readonly, getter=isEmailVerified) BOOL emailVerified; + +/** @property refreshToken + @brief A refresh token; useful for obtaining new access tokens independently. + @remarks This property should only be used for advanced scenarios, and is not typically needed. + */ +@property(nonatomic, readonly, nullable) NSString *refreshToken; + +/** @property providerData + @brief Profile data for each identity provider, if any. + @remarks This data is cached on sign-in and updated when linking or unlinking. + */ +@property(nonatomic, readonly, nonnull) NSArray> *providerData; + +/** @property metadata + @brief Metadata associated with the Firebase user in question. + */ +@property(nonatomic, readonly, nonnull) FIRUserMetadata *metadata; + +/** @fn init + @brief This class should not be instantiated. + @remarks To retrieve the current user, use `FIRAuth.currentUser`. To sign a user + in or out, use the methods on `FIRAuth`. + */ +- (instancetype)init NS_UNAVAILABLE; + +/** @fn updateEmail:completion: + @brief Updates the email address for the user. On success, the cached user profile data is + updated. + @remarks May fail if there is already an account with this email address that was created using + email and password authentication. + + @param email The email address for the user. + @param completion Optionally; the block invoked when the user profile change has finished. + Invoked asynchronously on the main thread in the future. + + @remarks Possible error codes: + + + `FIRAuthErrorCodeInvalidRecipientEmail` - Indicates an invalid recipient email was + sent in the request. + + `FIRAuthErrorCodeInvalidSender` - Indicates an invalid sender email is set in + the console for this action. + + `FIRAuthErrorCodeInvalidMessagePayload` - Indicates an invalid email template for + sending update email. + + `FIRAuthErrorCodeEmailAlreadyInUse` - Indicates the email is already in use by another + account. + + `FIRAuthErrorCodeInvalidEmail` - Indicates the email address is malformed. + + `FIRAuthErrorCodeRequiresRecentLogin` - Updating a user’s email is a security + sensitive operation that requires a recent login from the user. This error indicates + the user has not signed in recently enough. To resolve, reauthenticate the user by + invoking reauthenticateWithCredential:completion: on FIRUser. + + @remarks See `FIRAuthErrors` for a list of error codes that are common to all FIRUser methods. + */ +- (void)updateEmail:(NSString *)email completion:(nullable FIRUserProfileChangeCallback)completion + NS_SWIFT_NAME(updateEmail(to:completion:)); + +/** @fn updatePassword:completion: + @brief Updates the password for the user. On success, the cached user profile data is updated. + + @param password The new password for the user. + @param completion Optionally; the block invoked when the user profile change has finished. + Invoked asynchronously on the main thread in the future. + + @remarks Possible error codes: + + + `FIRAuthErrorCodeOperationNotAllowed` - Indicates the administrator disabled + sign in with the specified identity provider. + + `FIRAuthErrorCodeRequiresRecentLogin` - Updating a user’s password is a security + sensitive operation that requires a recent login from the user. This error indicates + the user has not signed in recently enough. To resolve, reauthenticate the user by + invoking reauthenticateWithCredential:completion: on FIRUser. + + `FIRAuthErrorCodeWeakPassword` - Indicates an attempt to set a password that is + considered too weak. The NSLocalizedFailureReasonErrorKey field in the NSError.userInfo + dictionary object will contain more detailed explanation that can be shown to the user. + + @remarks See `FIRAuthErrors` for a list of error codes that are common to all FIRUser methods. + */ +- (void)updatePassword:(NSString *)password + completion:(nullable FIRUserProfileChangeCallback)completion + NS_SWIFT_NAME(updatePassword(to:completion:)); + +#if TARGET_OS_IOS +/** @fn updatePhoneNumberCredential:completion: + @brief Updates the phone number for the user. On success, the cached user profile data is + updated. + + @param phoneNumberCredential The new phone number credential corresponding to the phone number + to be added to the Firebase account, if a phone number is already linked to the account this + new phone number will replace it. + @param completion Optionally; the block invoked when the user profile change has finished. + Invoked asynchronously on the main thread in the future. + + @remarks Possible error codes: + + + `FIRAuthErrorCodeRequiresRecentLogin` - Updating a user’s phone number is a security + sensitive operation that requires a recent login from the user. This error indicates + the user has not signed in recently enough. To resolve, reauthenticate the user by + invoking reauthenticateWithCredential:completion: on FIRUser. + + @remarks See `FIRAuthErrors` for a list of error codes that are common to all FIRUser methods. + */ +- (void)updatePhoneNumberCredential:(FIRPhoneAuthCredential *)phoneNumberCredential + completion:(nullable FIRUserProfileChangeCallback)completion; +#endif + +/** @fn profileChangeRequest + @brief Creates an object which may be used to change the user's profile data. + + @remarks Set the properties of the returned object, then call + `FIRUserProfileChangeRequest.commitChangesWithCallback:` to perform the updates atomically. + + @return An object which may be used to change the user's profile data atomically. + */ +- (FIRUserProfileChangeRequest *)profileChangeRequest NS_SWIFT_NAME(createProfileChangeRequest()); + +/** @fn reloadWithCompletion: + @brief Reloads the user's profile data from the server. + + @param completion Optionally; the block invoked when the reload has finished. Invoked + asynchronously on the main thread in the future. + + @remarks May fail with a `FIRAuthErrorCodeRequiresRecentLogin` error code. In this case + you should call `FIRUser.reauthenticateWithCredential:completion:` before re-invoking + `FIRUser.updateEmail:completion:`. + + @remarks See `FIRAuthErrors` for a list of error codes that are common to all API methods. + */ +- (void)reloadWithCompletion:(nullable FIRUserProfileChangeCallback)completion; + +/** @fn reauthenticateWithCredential:completion: + @brief Please use reauthenticateAndRetrieveDataWithCredential:completion: for Objective-C or + reauthenticateAndRetrieveData(WithCredential:completion:) for Swift instead. + */ +- (void)reauthenticateWithCredential:(FIRAuthCredential *)credential + completion:(nullable FIRUserProfileChangeCallback)completion + DEPRECATED_MSG_ATTRIBUTE( "Please use" + " reauthenticateAndRetrieveDataWithCredential:completion: for" + " Objective-C or" + " reauthenticateAndRetrieveData(WithCredential:completion:)" + " for Swift instead."); + +/** @fn reauthenticateAndRetrieveDataWithCredential:completion: + @brief Renews the user's authentication tokens by validating a fresh set of credentials supplied + by the user and returns additional identity provider data. + + @param credential A user-supplied credential, which will be validated by the server. This can be + a successful third-party identity provider sign-in, or an email address and password. + @param completion Optionally; the block invoked when the re-authentication operation has + finished. Invoked asynchronously on the main thread in the future. + + @remarks If the user associated with the supplied credential is different from the current user, + or if the validation of the supplied credentials fails; an error is returned and the current + user remains signed in. + + @remarks Possible error codes: + + + `FIRAuthErrorCodeInvalidCredential` - Indicates the supplied credential is invalid. + This could happen if it has expired or it is malformed. + + `FIRAuthErrorCodeOperationNotAllowed` - Indicates that accounts with the + identity provider represented by the credential are not enabled. Enable them in the + Auth section of the Firebase console. + + `FIRAuthErrorCodeEmailAlreadyInUse` - Indicates the email asserted by the credential + (e.g. the email in a Facebook access token) is already in use by an existing account, + that cannot be authenticated with this method. Call fetchProvidersForEmail for + this user’s email and then prompt them to sign in with any of the sign-in providers + returned. This error will only be thrown if the "One account per email address" + setting is enabled in the Firebase console, under Auth settings. Please note that the + error code raised in this specific situation may not be the same on Web and Android. + + `FIRAuthErrorCodeUserDisabled` - Indicates the user's account is disabled. + + `FIRAuthErrorCodeWrongPassword` - Indicates the user attempted reauthentication with + an incorrect password, if credential is of the type EmailPasswordAuthCredential. + + `FIRAuthErrorCodeUserMismatch` - Indicates that an attempt was made to + reauthenticate with a user which is not the current user. + + `FIRAuthErrorCodeInvalidEmail` - Indicates the email address is malformed. + + @remarks See `FIRAuthErrors` for a list of error codes that are common to all API methods. + */ +- (void)reauthenticateAndRetrieveDataWithCredential:(FIRAuthCredential *) credential + completion:(nullable FIRAuthDataResultCallback) completion; + +/** @fn getIDTokenResultWithCompletion: + @brief Retrieves the Firebase authentication token, possibly refreshing it if it has expired. + + @param completion Optionally; the block invoked when the token is available. Invoked + asynchronously on the main thread in the future. + + @remarks See `FIRAuthErrors` for a list of error codes that are common to all API methods. + */ +- (void)getIDTokenResultWithCompletion:(nullable FIRAuthTokenResultCallback)completion + NS_SWIFT_NAME(getIDTokenResult(completion:)); + +/** @fn getIDTokenResultForcingRefresh:completion: + @brief Retrieves the Firebase authentication token, possibly refreshing it if it has expired. + + @param forceRefresh Forces a token refresh. Useful if the token becomes invalid for some reason + other than an expiration. + @param completion Optionally; the block invoked when the token is available. Invoked + asynchronously on the main thread in the future. + + @remarks The authentication token will be refreshed (by making a network request) if it has + expired, or if `forceRefresh` is YES. + + @remarks See `FIRAuthErrors` for a list of error codes that are common to all API methods. + */ +- (void)getIDTokenResultForcingRefresh:(BOOL)forceRefresh + completion:(nullable FIRAuthTokenResultCallback)completion + NS_SWIFT_NAME(getIDTokenResult(forcingRefresh:completion:)); + +/** @fn getIDTokenWithCompletion: + @brief Retrieves the Firebase authentication token, possibly refreshing it if it has expired. + + @param completion Optionally; the block invoked when the token is available. Invoked + asynchronously on the main thread in the future. + + @remarks See `FIRAuthErrors` for a list of error codes that are common to all API methods. + */ +- (void)getIDTokenWithCompletion:(nullable FIRAuthTokenCallback)completion + NS_SWIFT_NAME(getIDToken(completion:)); + +/** @fn getIDTokenForcingRefresh:completion: + @brief Retrieves the Firebase authentication token, possibly refreshing it if it has expired. + + @param forceRefresh Forces a token refresh. Useful if the token becomes invalid for some reason + other than an expiration. + @param completion Optionally; the block invoked when the token is available. Invoked + asynchronously on the main thread in the future. + + @remarks The authentication token will be refreshed (by making a network request) if it has + expired, or if `forceRefresh` is YES. + + @remarks See `FIRAuthErrors` for a list of error codes that are common to all API methods. + */ +- (void)getIDTokenForcingRefresh:(BOOL)forceRefresh + completion:(nullable FIRAuthTokenCallback)completion; + +/** @fn linkWithCredential:completion: + @brief Please use linkAndRetrieveDataWithCredential:completion: for Objective-C or + linkAndRetrieveData(WithCredential:completion:) for Swift instead. + */ +- (void)linkWithCredential:(FIRAuthCredential *)credential + completion:(nullable FIRAuthResultCallback)completion DEPRECATED_MSG_ATTRIBUTE( + "Please use linkAndRetrieveDataWithCredential:completion: for" + " Objective-C or" + " linkAndRetrieveData(WithCredential:completion:) for" + " Swift instead."); + +/** @fn linkAndRetrieveDataWithCredential:completion: + @brief Associates a user account from a third-party identity provider with this user and + returns additional identity provider data. + + @param credential The credential for the identity provider. + @param completion Optionally; the block invoked when the unlinking is complete, or fails. + Invoked asynchronously on the main thread in the future. + + @remarks Possible error codes: + + + `FIRAuthErrorCodeProviderAlreadyLinked` - Indicates an attempt to link a provider of a + type already linked to this account. + + `FIRAuthErrorCodeCredentialAlreadyInUse` - Indicates an attempt to link with a + credential + that has already been linked with a different Firebase account. + + `FIRAuthErrorCodeOperationNotAllowed` - Indicates that accounts with the identity + provider represented by the credential are not enabled. Enable them in the Auth section + of the Firebase console. + + @remarks This method may also return error codes associated with updateEmail:completion: and + updatePassword:completion: on FIRUser. + + @remarks See `FIRAuthErrors` for a list of error codes that are common to all FIRUser methods. + */ +- (void)linkAndRetrieveDataWithCredential:(FIRAuthCredential *) credential + completion:(nullable FIRAuthDataResultCallback) completion; + +/** @fn unlinkFromProvider:completion: + @brief Disassociates a user account from a third-party identity provider with this user. + + @param provider The provider ID of the provider to unlink. + @param completion Optionally; the block invoked when the unlinking is complete, or fails. + Invoked asynchronously on the main thread in the future. + + @remarks Possible error codes: + + + `FIRAuthErrorCodeNoSuchProvider` - Indicates an attempt to unlink a provider + that is not linked to the account. + + `FIRAuthErrorCodeRequiresRecentLogin` - Updating email is a security sensitive + operation that requires a recent login from the user. This error indicates the user + has not signed in recently enough. To resolve, reauthenticate the user by invoking + reauthenticateWithCredential:completion: on FIRUser. + + @remarks See `FIRAuthErrors` for a list of error codes that are common to all FIRUser methods. + */ +- (void)unlinkFromProvider:(NSString *)provider + completion:(nullable FIRAuthResultCallback)completion; + +/** @fn sendEmailVerificationWithCompletion: + @brief Initiates email verification for the user. + + @param completion Optionally; the block invoked when the request to send an email verification + is complete, or fails. Invoked asynchronously on the main thread in the future. + + @remarks Possible error codes: + + + `FIRAuthErrorCodeInvalidRecipientEmail` - Indicates an invalid recipient email was + sent in the request. + + `FIRAuthErrorCodeInvalidSender` - Indicates an invalid sender email is set in + the console for this action. + + `FIRAuthErrorCodeInvalidMessagePayload` - Indicates an invalid email template for + sending update email. + + `FIRAuthErrorCodeUserNotFound` - Indicates the user account was not found. + + @remarks See `FIRAuthErrors` for a list of error codes that are common to all FIRUser methods. + */ +- (void)sendEmailVerificationWithCompletion:(nullable FIRSendEmailVerificationCallback)completion; + +/** @fn sendEmailVerificationWithActionCodeSettings:completion: + @brief Initiates email verification for the user. + + @param actionCodeSettings An `FIRActionCodeSettings` object containing settings related to + handling action codes. + + @remarks Possible error codes: + + + `FIRAuthErrorCodeInvalidRecipientEmail` - Indicates an invalid recipient email was + sent in the request. + + `FIRAuthErrorCodeInvalidSender` - Indicates an invalid sender email is set in + the console for this action. + + `FIRAuthErrorCodeInvalidMessagePayload` - Indicates an invalid email template for + sending update email. + + `FIRAuthErrorCodeUserNotFound` - Indicates the user account was not found. + + `FIRAuthErrorCodeMissingIosBundleID` - Indicates that the iOS bundle ID is missing when + a iOS App Store ID is provided. + + `FIRAuthErrorCodeMissingAndroidPackageName` - Indicates that the android package name + is missing when the `androidInstallApp` flag is set to true. + + `FIRAuthErrorCodeUnauthorizedDomain` - Indicates that the domain specified in the + continue URL is not whitelisted in the Firebase console. + + `FIRAuthErrorCodeInvalidContinueURI` - Indicates that the domain specified in the + continue URI is not valid. + */ +- (void)sendEmailVerificationWithActionCodeSettings:(FIRActionCodeSettings *)actionCodeSettings + completion:(nullable FIRSendEmailVerificationCallback) + completion; + +/** @fn deleteWithCompletion: + @brief Deletes the user account (also signs out the user, if this was the current user). + + @param completion Optionally; the block invoked when the request to delete the account is + complete, or fails. Invoked asynchronously on the main thread in the future. + + @remarks Possible error codes: + + + `FIRAuthErrorCodeRequiresRecentLogin` - Updating email is a security sensitive + operation that requires a recent login from the user. This error indicates the user + has not signed in recently enough. To resolve, reauthenticate the user by invoking + reauthenticateWithCredential:completion: on FIRUser. + + @remarks See `FIRAuthErrors` for a list of error codes that are common to all FIRUser methods. + + */ +- (void)deleteWithCompletion:(nullable FIRUserProfileChangeCallback)completion; + +@end + +/** @class FIRUserProfileChangeRequest + @brief Represents an object capable of updating a user's profile data. + @remarks Properties are marked as being part of a profile update when they are set. Setting a + property value to nil is not the same as leaving the property unassigned. + */ +NS_SWIFT_NAME(UserProfileChangeRequest) +@interface FIRUserProfileChangeRequest : NSObject + +/** @fn init + @brief Please use `FIRUser.profileChangeRequest` + */ +- (instancetype)init NS_UNAVAILABLE; + +/** @property displayName + @brief The user's display name. + @remarks It is an error to set this property after calling + `FIRUserProfileChangeRequest.commitChangesWithCallback:` + */ +@property(nonatomic, copy, nullable) NSString *displayName; + +/** @property photoURL + @brief The user's photo URL. + @remarks It is an error to set this property after calling + `FIRUserProfileChangeRequest.commitChangesWithCallback:` + */ +@property(nonatomic, copy, nullable) NSURL *photoURL; + +/** @fn commitChangesWithCompletion: + @brief Commits any pending changes. + @remarks This method should only be called once. Once called, property values should not be + changed. + + @param completion Optionally; the block invoked when the user profile change has been applied. + Invoked asynchronously on the main thread in the future. + */ +- (void)commitChangesWithCompletion:(nullable FIRUserProfileChangeCallback)completion; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/Public/FIRUserInfo.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/Public/FIRUserInfo.h new file mode 100644 index 0000000..04eca49 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/Public/FIRUserInfo.h @@ -0,0 +1,60 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + @brief Represents user data returned from an identity provider. + */ +NS_SWIFT_NAME(UserInfo) +@protocol FIRUserInfo + +/** @property providerID + @brief The provider identifier. + */ +@property(nonatomic, copy, readonly) NSString *providerID; + +/** @property uid + @brief The provider's user ID for the user. + */ +@property(nonatomic, copy, readonly) NSString *uid; + +/** @property displayName + @brief The name of the user. + */ +@property(nonatomic, copy, readonly, nullable) NSString *displayName; + +/** @property photoURL + @brief The URL of the user's profile photo. + */ +@property(nonatomic, copy, readonly, nullable) NSURL *photoURL; + +/** @property email + @brief The user's email address. + */ +@property(nonatomic, copy, readonly, nullable) NSString *email; + +/** @property phoneNumber + @brief A phone number associated with the user. + @remarks This property is only available for users authenticated via phone number auth. + */ +@property(nonatomic, readonly, nullable) NSString *phoneNumber; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/Public/FIRUserMetadata.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/Public/FIRUserMetadata.h new file mode 100644 index 0000000..2533171 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/Public/FIRUserMetadata.h @@ -0,0 +1,45 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** @class FIRUserMetdata + @brief A data class representing the metadata corresponding to a Firebase user. + */ +NS_SWIFT_NAME(UserMetadata) +@interface FIRUserMetadata : NSObject + +/** @property lastSignInDate + @brief Stores the last sign in date for the corresponding Firebase user. + */ +@property (copy, nonatomic, readonly, nullable) NSDate *lastSignInDate; + +/** @property creationDate + @brief Stores the creation date for the corresponding Firebase user. + */ +@property (copy, nonatomic, readonly, nullable) NSDate *creationDate; + +/** @fn init + @brief This class should not be initialized manually, an instance of this class can be obtained + from a Firebase user object. + */ +- (instancetype)init NS_UNAVAILABLE; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/Public/FirebaseAuth.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/Public/FirebaseAuth.h new file mode 100644 index 0000000..462d2ec --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/Public/FirebaseAuth.h @@ -0,0 +1,46 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +#import "FIRActionCodeSettings.h" +#import "FIRAdditionalUserInfo.h" +#import "FIRAuth.h" +#import "FIRAuthCredential.h" +#import "FIRAuthDataResult.h" +#import "FIRAuthErrors.h" +#import "FIRAuthTokenResult.h" +#import "FirebaseAuthVersion.h" +#import "FIREmailAuthProvider.h" +#import "FIRFacebookAuthProvider.h" +#import "FIRFederatedAuthProvider.h" +#import "FIRGameCenterAuthProvider.h" +#import "FIRGitHubAuthProvider.h" +#import "FIRGoogleAuthProvider.h" +#import "FIROAuthCredential.h" +#import "FIROAuthProvider.h" +#import "FIRTwitterAuthProvider.h" +#import "FIRUser.h" +#import "FIRUserInfo.h" +#import "FIRUserMetadata.h" + +#if TARGET_OS_IOS +#import "FIRAuthUIDelegate.h" +#import "FIRPhoneAuthCredential.h" +#import "FIRPhoneAuthProvider.h" +#import "FIRAuthAPNSTokenType.h" +#import "FIRAuthSettings.h" +#endif diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/Public/FirebaseAuthVersion.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/Public/FirebaseAuthVersion.h new file mode 100644 index 0000000..7b4b94e --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/Public/FirebaseAuthVersion.h @@ -0,0 +1,27 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +/** + Version number for FirebaseAuth. + */ +extern const double FirebaseAuthVersionNum; + +/** + Version string for FirebaseAuth. + */ +extern const char *const FirebaseAuthVersionStr; diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRAuthBackend.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRAuthBackend.h new file mode 100644 index 0000000..9ced6a3 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRAuthBackend.h @@ -0,0 +1,599 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +@class FIRAuthRequestConfiguration; +@class FIRCreateAuthURIRequest; +@class FIRCreateAuthURIResponse; +@class FIRDeleteAccountRequest; +@class FIRDeleteAccountResponse; +@class FIREmailLinkSignInRequest; +@class FIREmailLinkSignInResponse; +@class FIRGetAccountInfoRequest; +@class FIRGetAccountInfoResponse; +@class FIRGetProjectConfigRequest; +@class FIRGetProjectConfigResponse; +@class FIRGetOOBConfirmationCodeRequest; +@class FIRGetOOBConfirmationCodeResponse; +@class FIRResetPasswordRequest; +@class FIRResetPasswordResponse; +@class FIRSecureTokenRequest; +@class FIRSecureTokenResponse; +@class FIRSetAccountInfoRequest; +@class FIRSetAccountInfoResponse; +@class FIRVerifyAssertionRequest; +@class FIRVerifyAssertionResponse; +@class FIRVerifyClientRequest; +@class FIRVerifyClientResponse; +@class FIRVerifyCustomTokenRequest; +@class FIRVerifyCustomTokenResponse; +@class FIRVerifyPasswordRequest; +@class FIRVerifyPasswordResponse; +@class FIRVerifyPhoneNumberRequest; +@class FIRVerifyPhoneNumberResponse; +@class FIRSendVerificationCodeRequest; +@class FIRSendVerificationCodeResponse; +@class FIRSignInWithGameCenterRequest; +@class FIRSignInWithGameCenterResponse; +@class FIRSignUpNewUserRequest; +@class FIRSignUpNewUserResponse; + +@protocol FIRAuthBackendImplementation; +@protocol FIRAuthBackendRPCIssuer; + +NS_ASSUME_NONNULL_BEGIN + +/** @typedef FIRAuthBackendRPCIssuerCompletionHandler + @brief The type of block used to return the result of a call to an endpoint. + @param data The HTTP response body. + @param error The error which occurred, if any. + @remarks One of response or error will be non-nil. + */ +typedef void (^FIRAuthBackendRPCIssuerCompletionHandler)(NSData *_Nullable data, + NSError *_Nullable error); + +/** @typedef FIRCreateAuthURIResponseCallback + @brief The type of block used to return the result of a call to the createAuthURI + endpoint. + @param response The received response, if any. + @param error The error which occurred, if any. + @remarks One of response or error will be non-nil. + */ +typedef void (^FIRCreateAuthURIResponseCallback) + (FIRCreateAuthURIResponse *_Nullable response, NSError *_Nullable error); + +/** @typedef FIRGetAccountInfoResponseCallback + @brief The type of block used to return the result of a call to the getAccountInfo + endpoint. + @param response The received response, if any. + @param error The error which occurred, if any. + @remarks One of response or error will be non-nil. + */ +typedef void (^FIRGetAccountInfoResponseCallback) + (FIRGetAccountInfoResponse *_Nullable response, NSError *_Nullable error); + +/** @typedef FIRGetProjectConfigResponseCallback + @brief The type of block used to return the result of a call to the getProjectInfo + endpoint. + @param response The received response, if any. + @param error The error which occurred, if any. + @remarks One of response or error will be non-nil. + */ +typedef void (^FIRGetProjectConfigResponseCallback) + (FIRGetProjectConfigResponse *_Nullable response, NSError *_Nullable error); + +/** @typedef FIRSetAccountInfoResponseCallback + @brief The type of block used to return the result of a call to the setAccountInfo + endpoint. + @param response The received response, if any. + @param error The error which occurred, if any. + @remarks One of response or error will be non-nil. + */ +typedef void (^FIRSetAccountInfoResponseCallback) + (FIRSetAccountInfoResponse *_Nullable response, NSError *_Nullable error); + +/** @typedef FIRSecureTokenResponseCallback + @brief The type of block used to return the result of a call to the token endpoint. + @param response The received response, if any. + @param error The error which occurred, if any. + @remarks One of response or error will be non-nil. + */ +typedef void (^FIRSecureTokenResponseCallback) + (FIRSecureTokenResponse *_Nullable response, NSError *_Nullable error); + +/** @typedef FIRVerifyAssertionResponseCallback + @brief The type of block used to return the result of a call to the verifyAssertion + endpoint. + @param response The received response, if any. + @param error The error which occurred, if any. + @remarks One of response or error will be non-nil. + */ +typedef void (^FIRVerifyAssertionResponseCallback) + (FIRVerifyAssertionResponse *_Nullable response, NSError *_Nullable error); + +/** @typedef FIRVerifyPasswordResponseCallback + @brief The type of block used to return the result of a call to the verifyPassword + endpoint. + @param response The received response, if any. + @param error The error which occurred, if any. + @remarks One of response or error will be non-nil. + */ +typedef void (^FIRVerifyPasswordResponseCallback) + (FIRVerifyPasswordResponse *_Nullable response, NSError *_Nullable error); + +/** @typedef FIREmailLinkSigninResponseCallback + @brief The type of block used to return the result of a call to the emailLinkSignin + endpoint. + @param response The received response, if any. + @param error The error which occurred, if any. + @remarks One of response or error will be non-nil. + */ +typedef void (^FIREmailLinkSigninResponseCallback) + (FIREmailLinkSignInResponse *_Nullable response, NSError *_Nullable error); + +/** @typedef FIRVerifyCustomTokenResponseCallback + @brief The type of block used to return the result of a call to the verifyCustomToken + endpoint. + @param response The received response, if any. + @param error The error which occurred, if any. + @remarks One of response or error will be non-nil. + */ +typedef void (^FIRVerifyCustomTokenResponseCallback) + (FIRVerifyCustomTokenResponse *_Nullable response, NSError *_Nullable error); + +/** @typedef FIRDeleteCallBack + @brief The type of block called when a request delete account has finished. + @param error The error which occurred, or nil if the request was successful. + */ +typedef void (^FIRDeleteCallBack)(NSError *_Nullable error); + +/** @typedef FIRGetOOBConfirmationCodeResponseCallback + @brief The type of block used to return the result of a call to the getOOBConfirmationCode + endpoint. + @param response The received response, if any. + @param error The error which occurred, if any. + @remarks One of response or error will be non-nil. + */ +typedef void (^FIRGetOOBConfirmationCodeResponseCallback) + (FIRGetOOBConfirmationCodeResponse *_Nullable response, NSError *_Nullable error); + +/** @typedef FIRSignupNewUserCallback + @brief The type of block used to return the result of a call to the signupNewUser endpoint. + @param response The received response, if any. + @param error The error which occurred, if any. + @remarks One of response or error will be non-nil. + */ +typedef void (^FIRSignupNewUserCallback) + (FIRSignUpNewUserResponse *_Nullable response, NSError *_Nullable error); + +/** @typedef FIRResetPasswordCallback + @brief The type of block used to return the result of a call to the resetPassword endpoint. + @param response The received response, if any. + @param error The error which occurred, if any. + @remarks One of response or error will be non-nil. + */ +typedef void (^FIRResetPasswordCallback) + (FIRResetPasswordResponse *_Nullable response, NSError *_Nullable error); + +/** @typedef FIRSendVerificationCodeResponseCallback + @brief The type of block used to return the result of a call to the sendVerificationCode + endpoint. + @param response The received response, if any. + @param error The error which occurred, if any. + @remarks One of response or error will be non-nil. + */ +typedef void (^FIRSendVerificationCodeResponseCallback) + (FIRSendVerificationCodeResponse *_Nullable response, NSError *_Nullable error); + +/** @typedef FIRVerifyPhoneNumberResponseCallback + @brief The type of block used to return the result of a call to the verifyPhoneNumber endpoint. + @param response The received response, if any. + @param error The error which occurred, if any. + @remarks One of response or error will be non-nil. + */ +typedef void (^FIRVerifyPhoneNumberResponseCallback) + (FIRVerifyPhoneNumberResponse *_Nullable response, NSError *_Nullable error); + +/** @typedef FIRVerifyClientResponseCallback + @brief The type of block used to return the result of a call to the verifyClient endpoint. + @param response The received response, if any. + @param error The error which occurred, if any. + @remarks One of response or error will be non-nil. + */ +typedef void (^FIRVerifyClientResponseCallback) + (FIRVerifyClientResponse *_Nullable response, NSError *_Nullable error); + +/** @typedef FIRSignInWithGameCenterResponseCallback + @brief The type of block used to return the result of a call to the SignInWithGameCenter endpoint. + @param response The received response, if any. + @param error The error which occurred, if any. + @remarks One of response or error will be non-nil. + */ +typedef void (^FIRSignInWithGameCenterResponseCallback) + (FIRSignInWithGameCenterResponse *_Nullable response, NSError *_Nullable error); + +/** @class FIRAuthBackend + @brief Simple static class with methods representing the backend RPCs. + @remarks All callback blocks passed as method parameters are invoked asynchronously on the + global work queue in the future. See + https://github.com/firebase/firebase-ios-sdk/tree/master/Firebase/Auth/Docs/threading.ml + */ +@interface FIRAuthBackend : NSObject + +/** @fn authUserAgent + @brief Retrieves the Firebase Auth user agent. + @return The Firebase Auth user agent. + */ ++ (NSString *)authUserAgent; + +/** @fn setBackendImplementation: + @brief Changes the default backend implementation to something else. + @param backendImplementation The backend implementation to use. + @remarks This is not, generally, safe to call in a scenario where other backend requests may + be occuring. This is specifically to help mock the backend for testing purposes. + */ ++ (void)setBackendImplementation:(id)backendImplementation; + +/** @fn setDefaultBackendImplementationWithRPCIssuer: + @brief Uses the default backend implementation, but with a custom RPC issuer. + @param RPCIssuer The RPC issuer to use. If @c nil, will use the default implementation. + @remarks This is not, generally, safe to call in a scenario where other backend requests may + be occuring. This is specifically to help test the backend interfaces (requests, responses, + and shared FIRAuthBackend logic.) + */ ++ (void)setDefaultBackendImplementationWithRPCIssuer: + (nullable id)RPCIssuer; + +/** @fn createAuthURI:callback: + @brief Calls the createAuthURI endpoint, which is responsible for creating the URI used by the + IdP to authenticate the user. + @param request The request parameters. + @param callback The callback. + */ ++ (void)createAuthURI:(FIRCreateAuthURIRequest *)request + callback:(FIRCreateAuthURIResponseCallback)callback; + +/** @fn getAccountInfo:callback: + @brief Calls the getAccountInfo endpoint, which returns account info for a given account. + @param request The request parameters. + @param callback The callback. + */ ++ (void)getAccountInfo:(FIRGetAccountInfoRequest *)request + callback:(FIRGetAccountInfoResponseCallback)callback; + +/** @fn getProjectConfig:callback: + @brief Calls the getProjectConfig endpoint, which returns configuration information for a given + project. + @param request An object wrapping the backend get request. + @param callback The callback. + */ ++ (void)getProjectConfig:(FIRGetProjectConfigRequest *)request + callback:(FIRGetProjectConfigResponseCallback)callback; + +/** @fn setAccountInfo:callback: + @brief Calls the setAccountInfo endpoint, which is responsible for setting account info for a + user, for example, to sign up a new user with email and password. + @param request The request parameters. + @param callback The callback. + */ ++ (void)setAccountInfo:(FIRSetAccountInfoRequest *)request + callback:(FIRSetAccountInfoResponseCallback)callback; + +/** @fn verifyAssertion:callback: + @brief Calls the verifyAssertion endpoint, which is responsible for authenticating a + user who has IDP-related credentials (an ID Token, an Access Token, etc.) + @param request The request parameters. + @param callback The callback. + */ ++ (void)verifyAssertion:(FIRVerifyAssertionRequest *)request + callback:(FIRVerifyAssertionResponseCallback)callback; + +/** @fn verifyCustomToken:callback: + @brief Calls the verifyCustomToken endpoint, which is responsible for authenticating a + user who has BYOAuth credentials (a self-signed token using their BYOAuth private key.) + @param request The request parameters. + @param callback The callback. + */ ++ (void)verifyCustomToken:(FIRVerifyCustomTokenRequest *)request + callback:(FIRVerifyCustomTokenResponseCallback)callback; + +/** @fn verifyPassword:callback: + @brief Calls the verifyPassword endpoint, which is responsible for authenticating a + user who has email and password credentials. + @param request The request parameters. + @param callback The callback. + */ ++ (void)verifyPassword:(FIRVerifyPasswordRequest *)request + callback:(FIRVerifyPasswordResponseCallback)callback; + +/** @fn emailLinkSignin:callback: + @brief Calls the emailLinkSignin endpoint, which is responsible for authenticating a + user through passwordless sign-in. + @param request The request parameters. + @param callback The callback. + */ ++ (void)emailLinkSignin:(FIREmailLinkSignInRequest *)request + callback:(FIREmailLinkSigninResponseCallback)callback; + +/** @fn secureToken:callback: + @brief Calls the token endpoint, which is responsible for performing STS token exchanges and + token refreshes. + @param request The request parameters. + @param callback The callback. + */ ++ (void)secureToken:(FIRSecureTokenRequest *)request + callback:(FIRSecureTokenResponseCallback)callback; + +/** @fn getOOBConfirmationCode:callback: + @brief Calls the getOOBConfirmationCode endpoint, which is responsible for sending email change + request emails, and password reset emails. + @param request The request parameters. + @param callback The callback. + */ ++ (void)getOOBConfirmationCode:(FIRGetOOBConfirmationCodeRequest *)request + callback:(FIRGetOOBConfirmationCodeResponseCallback)callback; + +/** @fn signUpNewUser: + @brief Calls the signUpNewUser endpoint, which is responsible anonymously signing up a user + or signing in a user anonymously. + @param request The request parameters. + @param callback The callback. + */ ++ (void)signUpNewUser:(FIRSignUpNewUserRequest *)request + callback:(FIRSignupNewUserCallback)callback; + +/** @fn resetPassword:callback + @brief Calls the resetPassword endpoint, which is responsible for resetting a user's password + given an OOB code and new password. + @param request The request parameters. + @param callback The callback. + */ ++ (void)resetPassword:(FIRResetPasswordRequest *)request + callback:(FIRResetPasswordCallback)callback; + +/** @fn deleteAccount: + @brief Calls the DeleteAccount endpoint, which is responsible for deleting a user. + @param request The request parameters. + @param callback The callback. + */ ++ (void)deleteAccount:(FIRDeleteAccountRequest *)request + callback:(FIRDeleteCallBack)callback; + +/** @fn SignInWithGameCenter:callback: + @brief Calls the SignInWithGameCenter endpoint, which is responsible for authenticating a user + who has Game Center credentials. + @param request The request parameters. + @param callback The callback. + */ ++ (void)signInWithGameCenter:(FIRSignInWithGameCenterRequest *)request + callback:(FIRSignInWithGameCenterResponseCallback)callback; + +#if TARGET_OS_IOS +/** @fn sendVerificationCode:callback: + @brief Calls the sendVerificationCode endpoint, which is responsible for sending the + verification code to a phone number specified in the request parameters. + @param request The request parameters. + @param callback The callback. + */ ++ (void)sendVerificationCode:(FIRSendVerificationCodeRequest *)request + callback:(FIRSendVerificationCodeResponseCallback)callback; + +/** @fn verifyPhoneNumber:callback: + @brief Calls the verifyPhoneNumber endpoint, which is responsible for sending the verification + code to a phone number specified in the request parameters. + @param request The request parameters. + @param callback The callback. + */ ++ (void)verifyPhoneNumber:(FIRVerifyPhoneNumberRequest *)request + callback:(FIRVerifyPhoneNumberResponseCallback)callback; + +/** @fn verifyClient:callback: + @brief Calls the verifyClient endpoint, which is responsible for sending the silent push + notification used for app validation to the device provided in the request parameters. + @param request The request parameters. + @param callback The callback. + */ ++ (void)verifyClient:(FIRVerifyClientRequest *)request + callback:(FIRVerifyClientResponseCallback)callback; +#endif + +@end + +/** @protocol FIRAuthBackendRPCIssuer + @brief Used to make FIRAuthBackend + */ +@protocol FIRAuthBackendRPCIssuer + +/** @fn asyncPostToURLWithRequestConfiguration:URL:body:contentType:completionHandler: + @brief Asynchronously seXnds a POST request. + @param requestConfiguration The request to be made. + @param URL The request URL. + @param body Request body. + @param contentType Content type of the body. + @param handler provided that handles POST response. Invoked asynchronously on the auth global + work queue in the future. + */ +- (void)asyncPostToURLWithRequestConfiguration:(FIRAuthRequestConfiguration *)requestConfiguration + URL:(NSURL *)URL + body:(nullable NSData *)body + contentType:(NSString *)contentType + completionHandler:(FIRAuthBackendRPCIssuerCompletionHandler)handler; + +@end + +/** @protocol FIRAuthBackendImplementation + @brief Used to make FIRAuthBackend provide a layer of indirection to an actual RPC-based backend + or a mock backend. + */ +@protocol FIRAuthBackendImplementation + +/** @fn createAuthURI:callback: + @brief Calls the createAuthURI endpoint, which is responsible for creating the URI used by the + IdP to authenticate the user. + @param request The request parameters. + @param callback The callback. + */ +- (void)createAuthURI:(FIRCreateAuthURIRequest *)request + callback:(FIRCreateAuthURIResponseCallback)callback; + +/** @fn getAccountInfo:callback: + @brief Calls the getAccountInfo endpoint, which returns account info for a given account. + @param request The request parameters. + @param callback The callback. + */ +- (void)getAccountInfo:(FIRGetAccountInfoRequest *)request + callback:(FIRGetAccountInfoResponseCallback)callback; + +/** @fn getProjectConfig:callback: + @brief Calls the getProjectInfo endpoint, which returns configuration information for a given + project. + @param request The request parameters. + @param callback The callback. + */ +- (void)getProjectConfig:(FIRGetProjectConfigRequest *)request + callback:(FIRGetProjectConfigResponseCallback)callback; + +/** @fn setAccountInfo:callback: + @brief Calls the setAccountInfo endpoint, which is responsible for setting account info for a + user, for example, to sign up a new user with email and password. + @param request The request parameters. + @param callback The callback. + */ +- (void)setAccountInfo:(FIRSetAccountInfoRequest *)request + callback:(FIRSetAccountInfoResponseCallback)callback; + +/** @fn verifyAssertion:callback: + @brief Calls the verifyAssertion endpoint, which is responsible for authenticating a + user who has IDP-related credentials (an ID Token, an Access Token, etc.) + @param request The request parameters. + @param callback The callback. + */ +- (void)verifyAssertion:(FIRVerifyAssertionRequest *)request + callback:(FIRVerifyAssertionResponseCallback)callback; + +/** @fn verifyCustomToken:callback: + @brief Calls the verifyCustomToken endpoint, which is responsible for authenticating a + user who has BYOAuth credentials (a self-signed token using their BYOAuth private key.) + @param request The request parameters. + @param callback The callback. + */ +- (void)verifyCustomToken:(FIRVerifyCustomTokenRequest *)request + callback:(FIRVerifyCustomTokenResponseCallback)callback; + +/** @fn verifyPassword:callback: + @brief Calls the verifyPassword endpoint, which is responsible for authenticating a + user who has email and password credentials. + @param request The request parameters. + @param callback The callback. + */ +- (void)verifyPassword:(FIRVerifyPasswordRequest *)request + callback:(FIRVerifyPasswordResponseCallback)callback; + +/** @fn emailLinkSignin:callback: + @brief Calls the emailLinkSignin endpoint, which is responsible for authenticating a + user through passwordless sign-in. + @param request The request parameters. + @param callback The callback. + */ +- (void)emailLinkSignin:(FIREmailLinkSignInRequest *)request + callback:(FIREmailLinkSigninResponseCallback)callback; + +/** @fn secureToken:callback: + @brief Calls the token endpoint, which is responsible for performing STS token exchanges and + token refreshes. + @param request The request parameters. + @param callback The callback. + */ +- (void)secureToken:(FIRSecureTokenRequest *)request + callback:(FIRSecureTokenResponseCallback)callback; + +/** @fn getOOBConfirmationCode:callback: + @brief Calls the getOOBConfirmationCode endpoint, which is responsible for sending email change + request emails, email sign-in link emails, and password reset emails. + @param request The request parameters. + @param callback The callback. + */ +- (void)getOOBConfirmationCode:(FIRGetOOBConfirmationCodeRequest *)request + callback:(FIRGetOOBConfirmationCodeResponseCallback)callback; + +/** @fn signUpNewUser: + @brief Calls the signUpNewUser endpoint, which is responsible anonymously signing up a user + or signing in a user anonymously. + @param request The request parameters. + @param callback The callback. + */ +- (void)signUpNewUser:(FIRSignUpNewUserRequest *)request + callback:(FIRSignupNewUserCallback)callback; + +/** @fn deleteAccount: + @brief Calls the DeleteAccount endpoint, which is responsible for deleting a user. + @param request The request parameters. + @param callback The callback. + */ +- (void)deleteAccount:(FIRDeleteAccountRequest *)request + callback:(FIRDeleteCallBack)callback; + +#if TARGET_OS_IOS +/** @fn sendVerificationCode:callback: + @brief Calls the sendVerificationCode endpoint, which is responsible for sending the + verification code to a phone number specified in the request parameters. + @param request The request parameters. + @param callback The callback. + */ +- (void)sendVerificationCode:(FIRSendVerificationCodeRequest *)request + callback:(FIRSendVerificationCodeResponseCallback)callback; + +/** @fn verifyPhoneNumber:callback: + @brief Calls the verifyPhoneNumber endpoint, which is responsible for sending the verification + code to a phone number specified in the request parameters. + @param request The request parameters. + @param callback The callback. + */ +- (void)verifyPhoneNumber:(FIRVerifyPhoneNumberRequest *)request + callback:(FIRVerifyPhoneNumberResponseCallback)callback; + +/** @fn verifyClient:callback: + @brief Calls the verifyClient endpoint, which is responsible for sending the silent push + notification used for app validation to the device provided in the request parameters. + @param request The request parameters. + @param callback The callback. + */ +- (void)verifyClient:(FIRVerifyClientRequest *)request + callback:(FIRVerifyClientResponseCallback)callback; +#endif + +/** @fn SignInWithGameCenter:callback: + @brief Calls the SignInWithGameCenter endpoint, which is responsible for authenticating a user + who has Game Center credentials. + @param request The request parameters. + @param callback The callback. + */ +- (void)signInWithGameCenter:(FIRSignInWithGameCenterRequest *)request + callback:(FIRSignInWithGameCenterResponseCallback)callback; + +/** @fn resetPassword:callback + @brief Calls the resetPassword endpoint, which is responsible for resetting a user's password + given an OOB code and new password. + @param request The request parameters. + @param callback The callback. + */ +- (void)resetPassword:(FIRResetPasswordRequest *)request + callback:(FIRResetPasswordCallback)callback; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRAuthBackend.m b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRAuthBackend.m new file mode 100644 index 0000000..e862b5c --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRAuthBackend.m @@ -0,0 +1,1213 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRAuthBackend.h" + +#import +#import + +#import "FIRAuthErrorUtils.h" +#import "FIRAuthGlobalWorkQueue.h" +#import "FirebaseAuth.h" +#import "FIRAuthRPCRequest.h" +#import "FIRAuthRPCResponse.h" +#import "FIRCreateAuthURIRequest.h" +#import "FIRCreateAuthURIResponse.h" +#import "FIRDeleteAccountRequest.h" +#import "FIRDeleteAccountResponse.h" +#import "FIRGetAccountInfoRequest.h" +#import "FIRGetAccountInfoResponse.h" +#import "FIRSignInWithGameCenterRequest.h" +#import "FIRSignInWithGameCenterResponse.h" +#import "FIRGetOOBConfirmationCodeRequest.h" +#import "FIRGetOOBConfirmationCodeResponse.h" +#import "FIRGetProjectConfigRequest.h" +#import "FIRGetProjectConfigResponse.h" +#import "FIRResetPasswordRequest.h" +#import "FIRResetPasswordResponse.h" +#import "FIRSendVerificationCodeRequest.h" +#import "FIRSendVerificationCodeResponse.h" +#import "FIRSecureTokenRequest.h" +#import "FIRSecureTokenResponse.h" +#import "FIRSetAccountInfoRequest.h" +#import "FIRSetAccountInfoResponse.h" +#import "FIRSignUpNewUserRequest.h" +#import "FIRSignUpNewUserResponse.h" +#import "FIRVerifyAssertionRequest.h" +#import "FIRVerifyAssertionResponse.h" +#import "FIRVerifyClientRequest.h" +#import "FIRVerifyClientResponse.h" +#import "FIRVerifyCustomTokenRequest.h" +#import "FIRVerifyCustomTokenResponse.h" +#import "FIRVerifyPasswordRequest.h" +#import "FIRVerifyPasswordResponse.h" +#import "FIREmailLinkSignInRequest.h" +#import "FIREmailLinkSignInResponse.h" +#import "FIRVerifyPhoneNumberRequest.h" +#import "FIRVerifyPhoneNumberResponse.h" + +#import "../AuthProviders/OAuth/FIROAuthCredential_Internal.h" +#if TARGET_OS_IOS +#import "../AuthProviders/Phone/FIRPhoneAuthCredential_Internal.h" +#import "FIRPhoneAuthProvider.h" +#endif + +NS_ASSUME_NONNULL_BEGIN + +/** @var kClientVersionHeader + @brief HTTP header name for the client version. + */ +static NSString *const kClientVersionHeader = @"X-Client-Version"; + +/** @var kIosBundleIdentifierHeader + @brief HTTP header name for iOS bundle ID. + */ +static NSString *const kIosBundleIdentifierHeader = @"X-Ios-Bundle-Identifier"; + +/** @var kFirebaseLocalHeader + @brief HTTP header name for the firebase locale. + */ +static NSString *const kFirebaseLocalHeader = @"X-Firebase-Locale"; + +/** @var kFirebaseAuthCoreFrameworkMarker + @brief The marker in the HTTP header that indicates the request comes from Firebase Auth Core. + */ +static NSString *const kFirebaseAuthCoreFrameworkMarker = @"FirebaseCore-iOS"; + +/** @var kJSONContentType + @brief The value of the HTTP content-type header for JSON payloads. + */ +static NSString *const kJSONContentType = @"application/json"; + +/** @var kErrorDataKey + @brief Key for error data in NSError returned by @c GTMSessionFetcher. + */ +static NSString * const kErrorDataKey = @"data"; + +/** @var kErrorKey + @brief The key for the "error" value in JSON responses from the server. + */ +static NSString *const kErrorKey = @"error"; + +/** @var kErrorsKey + @brief The key for the "errors" value in JSON responses from the server. + */ +static NSString *const kErrorsKey = @"errors"; + +/** @var kReasonKey + @brief The key for the "reason" value in JSON responses from the server. + */ +static NSString *const kReasonKey = @"reason"; + +/** @var kInvalidKeyReasonValue + @brief The value for the "reason" key indicating an invalid API Key was received by the server. + */ +static NSString *const kInvalidKeyReasonValue = @"keyInvalid"; + +/** @var kAppNotAuthorizedReasonValue + @brief The value for the "reason" key indicating the App is not authorized to use Firebase + Authentication. + */ +static NSString *const kAppNotAuthorizedReasonValue = @"ipRefererBlocked"; + +/** @var kErrorMessageKey + @brief The key for an error's "message" value in JSON responses from the server. + */ +static NSString *const kErrorMessageKey = @"message"; + +/** @var kReturnIDPCredentialErrorMessageKey + @brief The key for "errorMessage" value in JSON responses from the server, In case + returnIDPCredential of a verifyAssertion request is set to @YES. + */ +static NSString *const kReturnIDPCredentialErrorMessageKey = @"errorMessage"; + +/** @var kUserNotFoundErrorMessage + @brief This is the error message returned when the user is not found, which means the user + account has been deleted given the token was once valid. + */ +static NSString *const kUserNotFoundErrorMessage = @"USER_NOT_FOUND"; + +/** @var kUserDeletedErrorMessage + @brief This is the error message the server will respond with if the user entered an invalid + email address. + */ +static NSString *const kUserDeletedErrorMessage = @"EMAIL_NOT_FOUND"; + +/** @var kInvalidLocalIDErrorMessage + @brief This is the error message the server responds with if the user local id in the id token + does not exit. + */ +static NSString *const kInvalidLocalIDErrorMessage = @"INVALID_LOCAL_ID"; + +/** @var kUserTokenExpiredErrorMessage + @brief The error returned by the server if the token issue time is older than the account's + valid_since time. + */ +static NSString *const kUserTokenExpiredErrorMessage = @"TOKEN_EXPIRED"; + +/** @var kTooManyRequestsErrorMessage + @brief This is the error message the server will respond with if too many requests were made to + a server method. + */ +static NSString *const kTooManyRequestsErrorMessage = @"TOO_MANY_ATTEMPTS_TRY_LATER"; + +/** @var kInvalidTokenCustomErrorMessage + @brief This is the error message the server will respond with if there is a validation error + with the custom token. + */ +static NSString *const kInvalidCustomTokenErrorMessage = @"INVALID_CUSTOM_TOKEN"; + +/** @var kCustomTokenMismatch + @brief This is the error message the server will respond with if the service account and API key + belong to different projects. + */ +static NSString *const kCustomTokenMismatch = @"CREDENTIAL_MISMATCH"; + +/** @var kInvalidCredentialErrorMessage + @brief This is the error message the server responds with if the IDP token or requestUri is + invalid. + */ +static NSString *const kInvalidCredentialErrorMessage = @"INVALID_IDP_RESPONSE"; + +/** @var kUserDisabledErrorMessage + @brief The error returned by the server if the user account is diabled. + */ +static NSString *const kUserDisabledErrorMessage = @"USER_DISABLED"; + +/** @var kOperationNotAllowedErrorMessage + @brief This is the error message the server will respond with if Admin disables IDP specified by + provider. + */ +static NSString *const kOperationNotAllowedErrorMessage = @"OPERATION_NOT_ALLOWED"; + +/** @var kPasswordLoginDisabledErrorMessage + @brief This is the error message the server responds with if password login is disabled. + */ +static NSString *const kPasswordLoginDisabledErrorMessage = @"PASSWORD_LOGIN_DISABLED"; + +/** @var kEmailAlreadyInUseErrorMessage + @brief This is the error message the server responds with if the email address already exists. + */ +static NSString *const kEmailAlreadyInUseErrorMessage = @"EMAIL_EXISTS"; + +/** @var kInvalidEmailErrorMessage + @brief The error returned by the server if the email is invalid. + */ +static NSString *const kInvalidEmailErrorMessage = @"INVALID_EMAIL"; + +/** @var kInvalidIdentifierErrorMessage + @brief The error returned by the server if the identifier is invalid. + */ +static NSString *const kInvalidIdentifierErrorMessage = @"INVALID_IDENTIFIER"; + +/** @var kWrongPasswordErrorMessage + @brief This is the error message the server will respond with if the user entered a wrong + password. + */ +static NSString *const kWrongPasswordErrorMessage = @"INVALID_PASSWORD"; + +/** @var kCredentialTooOldErrorMessage + @brief This is the error message the server responds with if account change is attempted 5 + minutes after signing in. + */ +static NSString *const kCredentialTooOldErrorMessage = @"CREDENTIAL_TOO_OLD_LOGIN_AGAIN"; + +/** @var kFederatedUserIDAlreadyLinkedMessage + @brief This is the error message the server will respond with if the federated user ID has been + already linked with another account. + */ +static NSString *const kFederatedUserIDAlreadyLinkedMessage = @"FEDERATED_USER_ID_ALREADY_LINKED"; + +/** @var kInvalidUserTokenErrorMessage + @brief This is the error message the server responds with if user's saved auth credential is + invalid, and the user needs to sign in again. + */ +static NSString *const kInvalidUserTokenErrorMessage = @"INVALID_ID_TOKEN"; + +/** @var kWeakPasswordErrorMessagePrefix + @brief This is the prefix for the error message the server responds with if user's new password + to be set is too weak. + */ +static NSString *const kWeakPasswordErrorMessagePrefix = @"WEAK_PASSWORD"; + +/** @var kExpiredActionCodeErrorMessage + @brief This is the error message the server will respond with if the action code is expired. + */ +static NSString *const kExpiredActionCodeErrorMessage = @"EXPIRED_OOB_CODE"; + +/** @var kInvalidActionCodeErrorMessage + @brief This is the error message the server will respond with if the action code is invalid. + */ +static NSString *const kInvalidActionCodeErrorMessage = @"INVALID_OOB_CODE"; + +/** @var kMissingEmailErrorMessage + @brief This is the error message the server will respond with if the email address is missing + during a "send password reset email" attempt. + */ +static NSString *const kMissingEmailErrorMessage = @"MISSING_EMAIL"; + +/** @var kInvalidSenderEmailErrorMessage + @brief This is the error message the server will respond with if the sender email is invalid + during a "send password reset email" attempt. + */ +static NSString *const kInvalidSenderEmailErrorMessage = @"INVALID_SENDER"; + +/** @var kInvalidMessagePayloadErrorMessage + @brief This is the error message the server will respond with if there are invalid parameters in + the payload during a "send password reset email" attempt. + */ +static NSString *const kInvalidMessagePayloadErrorMessage = @"INVALID_MESSAGE_PAYLOAD"; + +/** @var kInvalidRecipientEmailErrorMessage + @brief This is the error message the server will respond with if the recipient email is invalid. + */ +static NSString *const kInvalidRecipientEmailErrorMessage = @"INVALID_RECIPIENT_EMAIL"; + +/** @var kMissingIosBundleIDErrorMessage + @brief This is the error message the server will respond with if iOS bundle ID is missing but + the iOS App store ID is provided. + */ +static NSString *const kMissingIosBundleIDErrorMessage = @"MISSING_IOS_BUNDLE_ID"; + +/** @var kMissingAndroidPackageNameErrorMessage + @brief This is the error message the server will respond with if Android Package Name is missing + but the flag indicating the app should be installed is set to true. + */ +static NSString *const kMissingAndroidPackageNameErrorMessage = @"MISSING_ANDROID_PACKAGE_NAME"; + +/** @var kUnauthorizedDomainErrorMessage + @brief This is the error message the server will respond with if the domain of the continue URL + specified is not whitelisted in the firebase console. + */ +static NSString *const kUnauthorizedDomainErrorMessage = @"UNAUTHORIZED_DOMAIN"; + +/** @var kInvalidProviderIDErrorMessage + @brief This is the error message the server will respond with if the provider id given for the + web operation is invalid. + */ +static NSString *const kInvalidProviderIDErrorMessage = @"INVALID_PROVIDER_ID"; + +/** @var kInvalidDynamicLinkDomainErrorMessage + @brief This is the error message the server will respond with if the dynamic link domain + provided in the request is invalid. + */ +static NSString *const kInvalidDynamicLinkDomainErrorMessage = @"INVALID_DYNAMIC_LINK_DOMAIN"; + +/** @var kInvalidContinueURIErrorMessage + @brief This is the error message the server will respond with if the continue URL provided in + the request is invalid. + */ +static NSString *const kInvalidContinueURIErrorMessage = @"INVALID_CONTINUE_URI"; + +/** @var kMissingContinueURIErrorMessage + @brief This is the error message the server will respond with if there was no continue URI + present in a request that required one. + */ +static NSString *const kMissingContinueURIErrorMessage = @"MISSING_CONTINUE_URI"; + +/** @var kInvalidPhoneNumberErrorMessage + @brief This is the error message the server will respond with if an incorrectly formatted phone + number is provided. + */ +static NSString *const kInvalidPhoneNumberErrorMessage = @"INVALID_PHONE_NUMBER"; + +/** @var kInvalidVerificationCodeErrorMessage + @brief This is the error message the server will respond with if an invalid verification code is + provided. + */ +static NSString *const kInvalidVerificationCodeErrorMessage = @"INVALID_CODE"; + +/** @var kInvalidSessionInfoErrorMessage + @brief This is the error message the server will respond with if an invalid session info + (verification ID) is provided. + */ +static NSString *const kInvalidSessionInfoErrorMessage = @"INVALID_SESSION_INFO"; + +/** @var kSessionExpiredErrorMessage + @brief This is the error message the server will respond with if the SMS code has expired before + it is used. + */ +static NSString *const kSessionExpiredErrorMessage = @"SESSION_EXPIRED"; + +/** @var kMissingAppTokenErrorMessage + @brief This is the error message the server will respond with if the APNS token is missing in a + verifyClient request. + */ +static NSString *const kMissingAppTokenErrorMessage = @"MISSING_IOS_APP_TOKEN"; + +/** @var kMissingAppCredentialErrorMessage + @brief This is the error message the server will respond with if the app token is missing in a + sendVerificationCode request. + */ +static NSString *const kMissingAppCredentialErrorMessage = @"MISSING_APP_CREDENTIAL"; + +/** @var kInvalidAppCredentialErrorMessage + @brief This is the error message the server will respond with if the app credential in a + sendVerificationCode request is invalid. + */ +static NSString *const kInvalidAppCredentialErrorMessage = @"INVALID_APP_CREDENTIAL"; + +/** @var kQuoutaExceededErrorMessage + @brief This is the error message the server will respond with if the quota for SMS text messages + has been exceeded for the project. + */ +static NSString *const kQuoutaExceededErrorMessage = @"QUOTA_EXCEEDED"; + +/** @var kAppNotVerifiedErrorMessage + @brief This is the error message the server will respond with if Firebase could not verify the + app during a phone authentication flow. + */ +static NSString *const kAppNotVerifiedErrorMessage = @"APP_NOT_VERIFIED"; + +/** @var kMissingClientIdentifier + @brief This is the error message the server will respond with if Firebase could not verify the + app during a phone authentication flow when a real phone number is used and app verification + is disabled for testing. + */ +static NSString *const kMissingClientIdentifier = @"MISSING_CLIENT_IDENTIFIER"; + +/** @var kCaptchaCheckFailedErrorMessage + @brief This is the error message the server will respond with if the reCAPTCHA token provided is + invalid. + */ +static NSString *const kCaptchaCheckFailedErrorMessage = @"CAPTCHA_CHECK_FAILED"; + +/** @var kInvalidPendingToken + @brief Generic IDP error codes. + */ +static NSString *const kInvalidPendingToken = @"INVALID_PENDING_TOKEN"; + +/** @var gBackendImplementation + @brief The singleton FIRAuthBackendImplementation instance to use. + */ +static id gBackendImplementation; + +/** @class FIRAuthBackendRPCImplementation + @brief The default RPC-based backend implementation. + */ +@interface FIRAuthBackendRPCImplementation : NSObject + +/** @property RPCIssuer + @brief An instance of FIRAuthBackendRPCIssuer for making RPC requests. Allows the RPC + requests/responses to be easily faked. + */ +@property(nonatomic, strong) id RPCIssuer; + +@end + +@implementation FIRAuthBackend + ++ (id)implementation { + if (!gBackendImplementation) { + gBackendImplementation = [[FIRAuthBackendRPCImplementation alloc] init]; + } + return gBackendImplementation; +} + ++ (void)setBackendImplementation:(id)backendImplementation { + gBackendImplementation = backendImplementation; +} + ++ (void)setDefaultBackendImplementationWithRPCIssuer: + (nullable id)RPCIssuer { + FIRAuthBackendRPCImplementation *defaultImplementation = + [[FIRAuthBackendRPCImplementation alloc] init]; + if (RPCIssuer) { + defaultImplementation.RPCIssuer = RPCIssuer; + } + gBackendImplementation = defaultImplementation; +} + ++ (void)createAuthURI:(FIRCreateAuthURIRequest *)request + callback:(FIRCreateAuthURIResponseCallback)callback { + [[self implementation] createAuthURI:request callback:callback]; +} + ++ (void)getAccountInfo:(FIRGetAccountInfoRequest *)request + callback:(FIRGetAccountInfoResponseCallback)callback { + [[self implementation] getAccountInfo:request callback:callback]; +} + ++ (void)getProjectConfig:(FIRGetProjectConfigRequest *)request + callback:(FIRGetProjectConfigResponseCallback)callback { + [[self implementation] getProjectConfig:request callback:callback]; +} + ++ (void)setAccountInfo:(FIRSetAccountInfoRequest *)request + callback:(FIRSetAccountInfoResponseCallback)callback { + [[self implementation] setAccountInfo:request callback:callback]; +} + ++ (void)verifyAssertion:(FIRVerifyAssertionRequest *)request + callback:(FIRVerifyAssertionResponseCallback)callback { + [[self implementation] verifyAssertion:request callback:callback]; +} + ++ (void)verifyCustomToken:(FIRVerifyCustomTokenRequest *)request + callback:(FIRVerifyCustomTokenResponseCallback)callback { + [[self implementation] verifyCustomToken:request callback:callback]; +} + ++ (void)verifyPassword:(FIRVerifyPasswordRequest *)request + callback:(FIRVerifyPasswordResponseCallback)callback { + [[self implementation] verifyPassword:request callback:callback]; +} + ++ (void)emailLinkSignin:(FIREmailLinkSignInRequest *)request + callback:(FIREmailLinkSigninResponseCallback)callback { + [[self implementation] emailLinkSignin:request callback:callback]; +} + ++ (void)secureToken:(FIRSecureTokenRequest *)request + callback:(FIRSecureTokenResponseCallback)callback { + [[self implementation] secureToken:request callback:callback]; +} + ++ (void)getOOBConfirmationCode:(FIRGetOOBConfirmationCodeRequest *)request + callback:(FIRGetOOBConfirmationCodeResponseCallback)callback { + [[self implementation] getOOBConfirmationCode:request callback:callback]; +} + ++ (void)signUpNewUser:(FIRSignUpNewUserRequest *)request + callback:(FIRSignupNewUserCallback)callback { + [[self implementation] signUpNewUser:request callback:callback]; +} + ++ (void)deleteAccount:(FIRDeleteAccountRequest *)request callback:(FIRDeleteCallBack)callback { + [[self implementation] deleteAccount:request callback:callback]; +} + ++ (void)signInWithGameCenter:(FIRSignInWithGameCenterRequest *)request + callback:(FIRSignInWithGameCenterResponseCallback)callback { + [[self implementation] signInWithGameCenter:request callback:callback]; +} + +#if TARGET_OS_IOS ++ (void)sendVerificationCode:(FIRSendVerificationCodeRequest *)request + callback:(FIRSendVerificationCodeResponseCallback)callback { + [[self implementation] sendVerificationCode:request callback:callback]; +} + ++ (void)verifyPhoneNumber:(FIRVerifyPhoneNumberRequest *)request + callback:(FIRVerifyPhoneNumberResponseCallback)callback { + [[self implementation] verifyPhoneNumber:request callback:callback]; +} + ++ (void)verifyClient:(id)request callback:(FIRVerifyClientResponseCallback)callback { + [[self implementation] verifyClient:request callback:callback]; +} +#endif + ++ (void)resetPassword:(FIRResetPasswordRequest *)request + callback:(FIRResetPasswordCallback)callback { + [[self implementation] resetPassword:request callback:callback]; +} + ++ (NSString *)authUserAgent { + return [NSString stringWithFormat:@"FirebaseAuth.iOS/%s %@", + FirebaseAuthVersionStr, GTMFetcherStandardUserAgentString(nil)]; +} + +@end + +@interface FIRAuthBackendRPCIssuerImplementation : NSObject +@end + +@implementation FIRAuthBackendRPCIssuerImplementation { + /** @var The session fetcher service. + */ + GTMSessionFetcherService *_fetcherService; +} + +- (instancetype)init { + self = [super init]; + if (self) { + _fetcherService = [[GTMSessionFetcherService alloc] init]; + _fetcherService.userAgent = [FIRAuthBackend authUserAgent]; + _fetcherService.callbackQueue = FIRAuthGlobalWorkQueue(); + + // Avoid reusing the session to prevent + // https://github.com/firebase/firebase-ios-sdk/issues/1261 + _fetcherService.reuseSession = NO; + } + return self; +} + +- (void)asyncPostToURLWithRequestConfiguration:(FIRAuthRequestConfiguration *)requestConfiguration + URL:(NSURL *)URL + body:(nullable NSData *)body + contentType:(NSString *)contentType + completionHandler:(void (^)(NSData *_Nullable, + NSError *_Nullable))handler { + NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:URL]; + [request setValue:contentType forHTTPHeaderField:@"Content-Type"]; + NSString *additionalFrameworkMarker = requestConfiguration.additionalFrameworkMarker ?: + kFirebaseAuthCoreFrameworkMarker; + NSString *clientVersion = [NSString stringWithFormat:@"iOS/FirebaseSDK/%s/%@", + FirebaseAuthVersionStr, + additionalFrameworkMarker]; + [request setValue:clientVersion forHTTPHeaderField:kClientVersionHeader]; + NSString *bundleID = [[NSBundle mainBundle] bundleIdentifier]; + [request setValue:bundleID forHTTPHeaderField:kIosBundleIdentifierHeader]; + + NSArray *preferredLocalizations = [NSBundle mainBundle].preferredLocalizations; + if (preferredLocalizations.count) { + NSString *acceptLanguage = preferredLocalizations.firstObject; + [request setValue:acceptLanguage forHTTPHeaderField:@"Accept-Language"]; + } + NSString *languageCode = requestConfiguration.languageCode; + if (languageCode.length) { + [request setValue:languageCode forHTTPHeaderField:kFirebaseLocalHeader]; + } + GTMSessionFetcher *fetcher = [_fetcherService fetcherWithRequest:request]; + fetcher.bodyData = body; + [fetcher beginFetchWithCompletionHandler:handler]; +} + +@end + +@implementation FIRAuthBackendRPCImplementation + +- (instancetype)init { + self = [super init]; + if (self) { + _RPCIssuer = [[FIRAuthBackendRPCIssuerImplementation alloc] init]; + } + return self; +} + +- (void)createAuthURI:(FIRCreateAuthURIRequest *)request + callback:(FIRCreateAuthURIResponseCallback)callback { + FIRCreateAuthURIResponse *response = [[FIRCreateAuthURIResponse alloc] init]; + [self postWithRequest:request response:response callback:^(NSError *error) { + if (error) { + callback(nil, error); + } else { + callback(response, nil); + } + }]; +} + +- (void)getAccountInfo:(FIRGetAccountInfoRequest *)request + callback:(FIRGetAccountInfoResponseCallback)callback { + FIRGetAccountInfoResponse *response = [[FIRGetAccountInfoResponse alloc] init]; + [self postWithRequest:request response:response callback:^(NSError *error) { + if (error) { + callback(nil, error); + } else { + callback(response, nil); + } + }]; +} + +- (void)getProjectConfig:(FIRGetProjectConfigRequest *)request + callback:(FIRGetProjectConfigResponseCallback)callback { + FIRGetProjectConfigResponse *response = [[FIRGetProjectConfigResponse alloc] init]; + [self postWithRequest:request response:response callback:^(NSError *error) { + if (error) { + callback(nil, error); + } else { + callback(response, nil); + } + }]; +} + +- (void)setAccountInfo:(FIRSetAccountInfoRequest *)request + callback:(FIRSetAccountInfoResponseCallback)callback { + FIRSetAccountInfoResponse *response = [[FIRSetAccountInfoResponse alloc] init]; + [self postWithRequest:request response:response callback:^(NSError *error) { + if (error) { + callback(nil, error); + } else { + callback(response, nil); + } + }]; +} + +- (void)verifyAssertion:(FIRVerifyAssertionRequest *)request + callback:(FIRVerifyAssertionResponseCallback)callback { + FIRVerifyAssertionResponse *response = [[FIRVerifyAssertionResponse alloc] init]; + [self postWithRequest:request response:response callback:^(NSError *error) { + if (error) { + callback(nil, error); + return; + } + callback(response, nil); + }]; +} + +- (void)verifyCustomToken:(FIRVerifyCustomTokenRequest *)request + callback:(FIRVerifyCustomTokenResponseCallback)callback { + FIRVerifyCustomTokenResponse *response = [[FIRVerifyCustomTokenResponse alloc] init]; + [self postWithRequest:request response:response callback:^(NSError *error) { + if (error) { + callback(nil, error); + } else { + callback(response, nil); + } + }]; +} + +- (void)verifyPassword:(FIRVerifyPasswordRequest *)request + callback:(FIRVerifyPasswordResponseCallback)callback { + FIRVerifyPasswordResponse *response = [[FIRVerifyPasswordResponse alloc] init]; + [self postWithRequest:request response:response callback:^(NSError *error) { + if (error) { + callback(nil, error); + } else { + callback(response, nil); + } + }]; +} + +- (void)emailLinkSignin:(FIREmailLinkSignInRequest *)request + callback:(FIREmailLinkSigninResponseCallback)callback { + FIREmailLinkSignInResponse *response = [[FIREmailLinkSignInResponse alloc] init]; + [self postWithRequest:request response:response callback:^(NSError *error) { + if (error) { + callback(nil, error); + } else { + callback(response, nil); + } + }]; +} + +- (void)secureToken:(FIRSecureTokenRequest *)request + callback:(FIRSecureTokenResponseCallback)callback { + FIRSecureTokenResponse *response = [[FIRSecureTokenResponse alloc] init]; + [self postWithRequest:request response:response callback:^(NSError *error) { + if (error) { + callback(nil, error); + } else { + callback(response, nil); + } + }]; +} + +- (void)getOOBConfirmationCode:(FIRGetOOBConfirmationCodeRequest *)request + callback:(FIRGetOOBConfirmationCodeResponseCallback)callback { + FIRGetOOBConfirmationCodeResponse *response = [[FIRGetOOBConfirmationCodeResponse alloc] init]; + [self postWithRequest:request response:response callback:^(NSError *error) { + if (error) { + callback(nil, error); + } else { + callback(response, nil); + } + }]; +} + +- (void)signUpNewUser:(FIRSignUpNewUserRequest *)request + callback:(FIRSignupNewUserCallback)callback{ + FIRSignUpNewUserResponse *response = [[FIRSignUpNewUserResponse alloc] init]; + [self postWithRequest:request response:response callback:^(NSError *error) { + if (error) { + callback(nil, error); + } else { + callback(response, nil); + } + }]; +} + +- (void)deleteAccount:(FIRDeleteAccountRequest *)request callback:(FIRDeleteCallBack)callback { + FIRDeleteAccountResponse *response = [[FIRDeleteAccountResponse alloc] init]; + [self postWithRequest:request response:response callback:callback]; +} + +#if TARGET_OS_IOS +- (void)sendVerificationCode:(FIRSendVerificationCodeRequest *)request + callback:(FIRSendVerificationCodeResponseCallback)callback { + FIRSendVerificationCodeResponse *response = [[FIRSendVerificationCodeResponse alloc] init]; + [self postWithRequest:request response:response callback:^(NSError *error) { + if (error) { + callback(nil, error); + } else { + callback(response, error); + } + }]; +} + +- (void)verifyPhoneNumber:(FIRVerifyPhoneNumberRequest *)request + callback:(FIRVerifyPhoneNumberResponseCallback)callback { + FIRVerifyPhoneNumberResponse *response = [[FIRVerifyPhoneNumberResponse alloc] init]; + [self postWithRequest:request response:response callback:^(NSError *error) { + if (error) { + callback(nil, error); + return; + } + // Check whether or not the successful response is actually the special case phone auth flow + // that returns a temporary proof and phone number. + if (response.phoneNumber.length && response.temporaryProof.length) { + FIRPhoneAuthCredential *credential = + [[FIRPhoneAuthCredential alloc] initWithTemporaryProof:response.temporaryProof + phoneNumber:response.phoneNumber + providerID:FIRPhoneAuthProviderID]; + callback(nil, + [FIRAuthErrorUtils credentialAlreadyInUseErrorWithMessage:nil + credential:credential + email:nil]); + return; + } + callback(response, nil); + }]; +} + +- (void)verifyClient:(id)request callback:(FIRVerifyClientResponseCallback)callback { + FIRVerifyClientResponse *response = [[FIRVerifyClientResponse alloc] init]; + [self postWithRequest:request response:response callback:^(NSError *error) { + if (error) { + callback(nil, error); + return; + } + callback(response, nil); + }]; +} +#endif + +- (void)resetPassword:(FIRResetPasswordRequest *)request + callback:(FIRResetPasswordCallback)callback { + FIRResetPasswordResponse *response = [[FIRResetPasswordResponse alloc] init]; + [self postWithRequest:request response:response callback:^(NSError *error) { + if (error) { + callback(nil, error); + return; + } + callback(response, nil); + }]; +} + +- (void)signInWithGameCenter:(FIRSignInWithGameCenterRequest *)request + callback:(FIRSignInWithGameCenterResponseCallback)callback { + FIRSignInWithGameCenterResponse *response = [[FIRSignInWithGameCenterResponse alloc] init]; + [self postWithRequest:request response:response callback:^(NSError *error) { + if (error) { + if (callback) { + callback(nil, error); + } + } else { + if (callback) { + callback(response, nil); + } + } + }]; +} + +#pragma mark - Generic RPC handling methods + +/** @fn postWithRequest:response:callback: + @brief Calls the RPC using HTTP POST. + @remarks Possible error responses: + @see FIRAuthInternalErrorCodeRPCRequestEncodingError + @see FIRAuthInternalErrorCodeJSONSerializationError + @see FIRAuthInternalErrorCodeNetworkError + @see FIRAuthInternalErrorCodeUnexpectedErrorResponse + @see FIRAuthInternalErrorCodeUnexpectedResponse + @see FIRAuthInternalErrorCodeRPCResponseDecodingError + @param request The request. + @param response The empty response to be filled. + @param callback The callback for both success and failure. + */ +- (void)postWithRequest:(id)request + response:(id)response + callback:(void (^)(NSError * _Nullable error))callback { + NSError *error; + NSData *bodyData; + if ([request containsPostBody]) { + id postBody = [request unencodedHTTPRequestBodyWithError:&error]; + if (!postBody) { + callback([FIRAuthErrorUtils RPCRequestEncodingErrorWithUnderlyingError:error]); + return; + } + + NSJSONWritingOptions JSONWritingOptions = 0; + #if DEBUG + JSONWritingOptions |= NSJSONWritingPrettyPrinted; + #endif + + if ([NSJSONSerialization isValidJSONObject:postBody]) { + bodyData = [NSJSONSerialization dataWithJSONObject:postBody + options:JSONWritingOptions + error:&error]; + if (!bodyData) { + // This is an untested case. This happens exclusively when there is an error in the framework + // implementation of dataWithJSONObject:options:error:. This shouldn't normally occur as + // isValidJSONObject: should return NO in any case we should encounter an error. + error = [FIRAuthErrorUtils JSONSerializationErrorWithUnderlyingError:error]; + } + } else { + error = [FIRAuthErrorUtils JSONSerializationErrorForUnencodableType]; + } + if (!bodyData) { + callback(error); + return; + } + } + + [_RPCIssuer asyncPostToURLWithRequestConfiguration:[request requestConfiguration] + URL:[request requestURL] + body:bodyData + contentType:kJSONContentType + completionHandler:^(NSData *data, NSError *error) { + // If there is an error with no body data at all, then this must be a network error. + if (error && !data) { + callback([FIRAuthErrorUtils networkErrorWithUnderlyingError:error]); + return; + } + + // Try to decode the HTTP response data which may contain either a successful response or error + // message. + NSError *jsonError; + NSDictionary * dictionary = + [NSJSONSerialization JSONObjectWithData:data + options:NSJSONReadingMutableLeaves + error:&jsonError]; + if (!dictionary) { + if (error) { + // We have an error, but we couldn't decode the body, so we have no additional information + // other than the raw response and the original NSError (the jsonError is infered by the + // error code (FIRAuthErrorCodeUnexpectedHTTPResponse, and is irrelevant.) + callback([FIRAuthErrorUtils unexpectedErrorResponseWithData:data underlyingError:error]); + } else { + // This is supposed to be a "successful" response, but we couldn't deserialize the body. + callback([FIRAuthErrorUtils unexpectedResponseWithData:data underlyingError:jsonError]); + } + return; + } + if (![dictionary isKindOfClass:[NSDictionary class]]) { + if (error) { + callback([FIRAuthErrorUtils unexpectedErrorResponseWithDeserializedResponse:dictionary]); + } else { + callback([FIRAuthErrorUtils unexpectedResponseWithDeserializedResponse:dictionary]); + } + return; + } + + // At this point we either have an error with successfully decoded details in the body, or we + // have a response which must pass further validation before we know it's truly successful. + // We deal with the case where we have an error with successfully decoded error details first: + if (error) { + NSDictionary *errorDictionary = dictionary[kErrorKey]; + if ([errorDictionary isKindOfClass:[NSDictionary class]]) { + id errorMessage = errorDictionary[kErrorMessageKey]; + if ([errorMessage isKindOfClass:[NSString class]]) { + NSString *errorMessageString = (NSString *)errorMessage; + + // Contruct client error. + NSError *clientError = [[self class] clientErrorWithServerErrorMessage:errorMessageString + errorDictionary:errorDictionary + response:response]; + if (clientError) { + callback(clientError); + return; + } + } + // Not a message we know, return the message directly. + if (errorMessage) { + NSError *unexpecterErrorResponse = + [FIRAuthErrorUtils unexpectedErrorResponseWithDeserializedResponse:errorDictionary]; + callback(unexpecterErrorResponse); + return; + } + } + // No error message at all, return the decoded response. + callback([FIRAuthErrorUtils unexpectedErrorResponseWithDeserializedResponse:dictionary]); + return; + } + + // Finally, we try to populate the response object with the JSON values. + if (![response setWithDictionary:dictionary error:&error]) { + callback([FIRAuthErrorUtils RPCResponseDecodingErrorWithDeserializedResponse:dictionary + underlyingError:error]); + return; + } + // In case returnIDPCredential of a verifyAssertion request is set to @YES, the server may + // return a 200 with a response that may contain a server error. + if ([request isKindOfClass:[FIRVerifyAssertionRequest class]]) { + FIRVerifyAssertionRequest *verifyAssertionRequest = (FIRVerifyAssertionRequest *)request; + if (verifyAssertionRequest.returnIDPCredential) { + NSString *errorMessage = dictionary[kReturnIDPCredentialErrorMessageKey]; + if ([errorMessage isKindOfClass:[NSString class]]) { + NSString *errorString = (NSString *)errorMessage; + NSError *clientError = [[self class] clientErrorWithServerErrorMessage:errorString + errorDictionary:@{} + response:response]; + if (clientError) { + callback(clientError); + return; + } + } + } + } + // Success! The response object originally passed in can be used by the caller. + callback(nil); + }]; +} + +/** @fn clientErrorWithServerErrorMessage:errorDictionary: + @brief Translates known server errors to client errors. + @param serverErrorMessage The error message from the server. + @param errorDictionary The error part of the response from the server. + @param response The response from the server RPC. + @return A client error, if any. + */ ++ (nullable NSError *)clientErrorWithServerErrorMessage:(NSString *)serverErrorMessage + errorDictionary:(NSDictionary *)errorDictionary + response:(id)response { + NSString *shortErrorMessage = serverErrorMessage; + NSString *serverDetailErrorMessage; + NSRange colonRange = [serverErrorMessage rangeOfString:@":"]; + if (colonRange.location != NSNotFound) { + shortErrorMessage = [serverErrorMessage substringToIndex:colonRange.location]; + shortErrorMessage = + [shortErrorMessage stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; + serverDetailErrorMessage = [serverErrorMessage substringFromIndex:colonRange.location + 1]; + serverDetailErrorMessage = [serverDetailErrorMessage stringByTrimmingCharactersInSet: + [NSCharacterSet whitespaceCharacterSet]]; + } + + // Delegate the responsibility for constructing the client error to the response object, + // if possible. + SEL clientErrorWithServerErrorMessageSelector = + @selector(clientErrorWithShortErrorMessage:detailErrorMessage:); + if ([response respondsToSelector:clientErrorWithServerErrorMessageSelector]) { + NSError *error = [response clientErrorWithShortErrorMessage:shortErrorMessage + detailErrorMessage:serverDetailErrorMessage]; + if (error) { + return error; + } + } + + if ([shortErrorMessage isEqualToString:kUserNotFoundErrorMessage]) { + return [FIRAuthErrorUtils userNotFoundErrorWithMessage:serverDetailErrorMessage]; + } + + if ([shortErrorMessage isEqualToString:kUserDeletedErrorMessage]) { + return [FIRAuthErrorUtils userNotFoundErrorWithMessage:serverDetailErrorMessage]; + } + + if ([shortErrorMessage isEqualToString:kInvalidLocalIDErrorMessage]) { + // This case shouldn't be necessary but it is for now: b/27908364 . + return [FIRAuthErrorUtils userNotFoundErrorWithMessage:serverDetailErrorMessage]; + } + + if ([shortErrorMessage isEqualToString:kUserTokenExpiredErrorMessage]) { + return [FIRAuthErrorUtils userTokenExpiredErrorWithMessage:serverDetailErrorMessage]; + } + + if ([shortErrorMessage isEqualToString:kTooManyRequestsErrorMessage]) { + return [FIRAuthErrorUtils tooManyRequestsErrorWithMessage:serverDetailErrorMessage]; + } + + if ([shortErrorMessage isEqualToString:kInvalidCustomTokenErrorMessage]) { + return [FIRAuthErrorUtils invalidCustomTokenErrorWithMessage:serverDetailErrorMessage]; + } + + if ([shortErrorMessage isEqualToString:kCustomTokenMismatch]) { + return [FIRAuthErrorUtils customTokenMistmatchErrorWithMessage:serverDetailErrorMessage]; + } + + if ([shortErrorMessage isEqualToString:kInvalidCredentialErrorMessage] || + [shortErrorMessage isEqualToString:kInvalidPendingToken]) { + return [FIRAuthErrorUtils invalidCredentialErrorWithMessage:serverDetailErrorMessage]; + } + + if ([shortErrorMessage isEqualToString:kUserDisabledErrorMessage]) { + return [FIRAuthErrorUtils userDisabledErrorWithMessage:serverDetailErrorMessage]; + } + + if ([shortErrorMessage isEqualToString:kOperationNotAllowedErrorMessage]) { + return [FIRAuthErrorUtils operationNotAllowedErrorWithMessage:serverDetailErrorMessage]; + } + + if ([shortErrorMessage isEqualToString:kPasswordLoginDisabledErrorMessage]) { + return [FIRAuthErrorUtils operationNotAllowedErrorWithMessage:serverDetailErrorMessage]; + } + + if ([shortErrorMessage isEqualToString:kEmailAlreadyInUseErrorMessage]) { + return [FIRAuthErrorUtils emailAlreadyInUseErrorWithEmail:nil]; + } + + if ([shortErrorMessage isEqualToString:kInvalidEmailErrorMessage]) { + return [FIRAuthErrorUtils invalidEmailErrorWithMessage:serverDetailErrorMessage]; + } + + // "INVALID_IDENTIFIER" can be returned by createAuthURI RPC. Considering email addresses are + // currently the only identifiers, we surface the FIRAuthErrorCodeInvalidEmail error code in this + // case. + if ([shortErrorMessage isEqualToString:kInvalidIdentifierErrorMessage]) { + return [FIRAuthErrorUtils invalidEmailErrorWithMessage:serverDetailErrorMessage]; + } + + if ([shortErrorMessage isEqualToString:kWrongPasswordErrorMessage]) { + return [FIRAuthErrorUtils wrongPasswordErrorWithMessage:serverDetailErrorMessage]; + } + + if ([shortErrorMessage isEqualToString:kCredentialTooOldErrorMessage]) { + return [FIRAuthErrorUtils requiresRecentLoginErrorWithMessage:serverDetailErrorMessage]; + } + + if ([shortErrorMessage isEqualToString:kInvalidUserTokenErrorMessage]) { + return [FIRAuthErrorUtils invalidUserTokenErrorWithMessage:serverDetailErrorMessage]; + } + + if ([shortErrorMessage isEqualToString:kFederatedUserIDAlreadyLinkedMessage]) { + FIROAuthCredential *credential; + NSString *email; + if ([response isKindOfClass:[FIRVerifyAssertionResponse class]]) { + FIRVerifyAssertionResponse *verifyAssertion = (FIRVerifyAssertionResponse *)response; + if (verifyAssertion.oauthIDToken.length || verifyAssertion.oauthAccessToken.length) { + credential = + [[FIROAuthCredential alloc] initWithProviderID:verifyAssertion.providerID + IDToken:verifyAssertion.oauthIDToken + accessToken:verifyAssertion.oauthAccessToken + pendingToken:verifyAssertion.pendingToken]; + } + email = verifyAssertion.email; + } + return [FIRAuthErrorUtils credentialAlreadyInUseErrorWithMessage:serverDetailErrorMessage + credential:credential + email:email]; + } + + if ([shortErrorMessage isEqualToString:kWeakPasswordErrorMessagePrefix]) { + return [FIRAuthErrorUtils weakPasswordErrorWithServerResponseReason:serverDetailErrorMessage]; + } + + if ([shortErrorMessage isEqualToString:kExpiredActionCodeErrorMessage]) { + return [FIRAuthErrorUtils expiredActionCodeErrorWithMessage:serverDetailErrorMessage]; + } + + if ([shortErrorMessage isEqualToString:kInvalidActionCodeErrorMessage]) { + return [FIRAuthErrorUtils invalidActionCodeErrorWithMessage:serverDetailErrorMessage]; + } + + if ([shortErrorMessage isEqualToString:kMissingEmailErrorMessage]) { + return [FIRAuthErrorUtils missingEmailErrorWithMessage:serverDetailErrorMessage]; + } + + if ([shortErrorMessage isEqualToString:kInvalidSenderEmailErrorMessage]) { + return [FIRAuthErrorUtils invalidSenderErrorWithMessage:serverDetailErrorMessage]; + } + + if ([shortErrorMessage isEqualToString:kInvalidMessagePayloadErrorMessage]) { + return [FIRAuthErrorUtils invalidMessagePayloadErrorWithMessage:serverDetailErrorMessage]; + } + + if ([shortErrorMessage isEqualToString:kInvalidRecipientEmailErrorMessage]) { + return [FIRAuthErrorUtils invalidRecipientEmailErrorWithMessage:serverDetailErrorMessage]; + } + + if ([shortErrorMessage isEqualToString:kMissingIosBundleIDErrorMessage]) { + return [FIRAuthErrorUtils missingIosBundleIDErrorWithMessage:serverDetailErrorMessage]; + } + + if ([shortErrorMessage isEqualToString:kMissingAndroidPackageNameErrorMessage]) { + return [FIRAuthErrorUtils missingAndroidPackageNameErrorWithMessage:serverDetailErrorMessage]; + } + + if ([shortErrorMessage isEqualToString:kUnauthorizedDomainErrorMessage]) { + return [FIRAuthErrorUtils unauthorizedDomainErrorWithMessage:serverDetailErrorMessage]; + } + + if ([shortErrorMessage isEqualToString:kInvalidContinueURIErrorMessage]) { + return [FIRAuthErrorUtils invalidContinueURIErrorWithMessage:serverDetailErrorMessage]; + } + + if ([shortErrorMessage isEqualToString:kInvalidProviderIDErrorMessage]) { + return [FIRAuthErrorUtils invalidProviderIDErrorWithMessage:serverDetailErrorMessage]; + } + + if ([shortErrorMessage isEqualToString:kInvalidDynamicLinkDomainErrorMessage]) { + return [FIRAuthErrorUtils invalidDynamicLinkDomainErrorWithMessage:serverDetailErrorMessage]; + } + + if ([shortErrorMessage isEqualToString:kMissingContinueURIErrorMessage]) { + return [FIRAuthErrorUtils missingContinueURIErrorWithMessage:serverDetailErrorMessage]; + } + + if ([shortErrorMessage isEqualToString:kInvalidPhoneNumberErrorMessage]) { + return [FIRAuthErrorUtils invalidPhoneNumberErrorWithMessage:serverDetailErrorMessage]; + } + + if ([shortErrorMessage isEqualToString:kInvalidSessionInfoErrorMessage]) { + return [FIRAuthErrorUtils invalidVerificationIDErrorWithMessage:serverDetailErrorMessage]; + } + + if ([shortErrorMessage isEqualToString:kInvalidVerificationCodeErrorMessage]) { + return [FIRAuthErrorUtils invalidVerificationCodeErrorWithMessage:serverDetailErrorMessage]; + } + + if ([shortErrorMessage isEqualToString:kSessionExpiredErrorMessage]) { + return [FIRAuthErrorUtils sessionExpiredErrorWithMessage:serverDetailErrorMessage]; + } + + if ([shortErrorMessage isEqualToString:kMissingAppTokenErrorMessage]) { + return [FIRAuthErrorUtils missingAppTokenErrorWithUnderlyingError:nil]; + } + + if ([shortErrorMessage isEqualToString:kMissingAppCredentialErrorMessage]) { + return [FIRAuthErrorUtils missingAppCredentialWithMessage:serverDetailErrorMessage]; + } + + if ([shortErrorMessage isEqualToString:kInvalidAppCredentialErrorMessage]) { + return [FIRAuthErrorUtils invalidAppCredentialWithMessage:serverDetailErrorMessage]; + } + + if ([shortErrorMessage isEqualToString:kQuoutaExceededErrorMessage]) { + return [FIRAuthErrorUtils quotaExceededErrorWithMessage:serverErrorMessage]; + } + + if ([shortErrorMessage isEqualToString:kAppNotVerifiedErrorMessage]) { + return [FIRAuthErrorUtils appNotVerifiedErrorWithMessage:serverErrorMessage]; + } + + if ([shortErrorMessage isEqualToString:kMissingClientIdentifier]) { + return [FIRAuthErrorUtils appNotVerifiedErrorWithMessage:@"Missing app verification via" + " reCAPTCHA or APNS token. Please verify that appVerificationDisabledForTesting is not" + " enabled when testing with a phone number that is not marked as a test Phone number in the" + " app console."]; + } + + if ([shortErrorMessage isEqualToString:kCaptchaCheckFailedErrorMessage]) { + return [FIRAuthErrorUtils captchaCheckFailedErrorWithMessage:serverErrorMessage]; + } + + // In this case we handle an error that might be specified in the underlying errors dictionary, + // the error message in determined based on the @c reason key in the dictionary. + if (errorDictionary[kErrorsKey]) { + // Check for underlying error with reason = keyInvalid; + id underlyingErrors = errorDictionary[kErrorsKey]; + if ([underlyingErrors isKindOfClass:[NSArray class]]) { + NSArray *underlyingErrorsArray = (NSArray *)underlyingErrors; + for (id underlyingError in underlyingErrorsArray) { + if ([underlyingError isKindOfClass:[NSDictionary class]]) { + NSDictionary *underlyingErrorDictionary = (NSDictionary *)underlyingError; + NSString *reason = underlyingErrorDictionary[kReasonKey]; + if ([reason hasPrefix:kInvalidKeyReasonValue]) { + return [FIRAuthErrorUtils invalidAPIKeyError]; + } + if ([reason isEqualToString:kAppNotAuthorizedReasonValue]) { + return [FIRAuthErrorUtils appNotAuthorizedError]; + } + } + } + } + } + return nil; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRAuthRPCRequest.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRAuthRPCRequest.h new file mode 100644 index 0000000..9ca4f44 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRAuthRPCRequest.h @@ -0,0 +1,57 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +@class FIRAuthRequestConfiguration; + +NS_ASSUME_NONNULL_BEGIN + +/** @protocol FIRAuthRPCRequest + @brief The generic interface for an RPC request needed by @c FIRAuthBackend. + */ +@protocol FIRAuthRPCRequest + +/** @fn requestURL + @brief Gets the request's full URL. + */ +- (NSURL *)requestURL; + +@optional + +/** @fn containsPostBody + @brief Returns whether the request contains a post body or not. Requests without a post body + are get requests. + @remarks The default implementation returns YES. + */ +- (BOOL)containsPostBody; + +/** @fn UnencodedHTTPRequestBodyWithError: + @brief Creates unencoded HTTP body representing the request. + @param error An out field for an error which occurred constructing the request. + @return The HTTP body data representing the request before any encoding, or nil for error. + */ +- (nullable id)unencodedHTTPRequestBodyWithError:(NSError *_Nullable *_Nullable)error; + +/** @fn requestConfiguration + @brief Obtains the request configurations if available. + @return Returns the request configurations. + */ +- (FIRAuthRequestConfiguration *)requestConfiguration; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRAuthRPCResponse.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRAuthRPCResponse.h new file mode 100644 index 0000000..2b26161 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRAuthRPCResponse.h @@ -0,0 +1,49 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** @protocol FIRAuthRPCResponse + @brief The generic interface for an RPC response needed by @c FIRAuthBackend. + */ +@protocol FIRAuthRPCResponse + +/** @fn setFieldsWithDictionary:error: + @brief Sets the response instance from the decoded JSON response. + @param dictionary The dictionary decoded from HTTP JSON response. + @param error An out field for an error which occurred constructing the request. + @return Whether the operation was successful or not. + */ +- (BOOL)setWithDictionary:(NSDictionary *)dictionary + error:(NSError *_Nullable *_Nullable)error; + +@optional + +/** @fn clientErrorWithshortErrorMessage:detailErrorMessage + @brief This optional method allows response classes to create client errors given a short error + message and a detail error message from the server. + @param shortErrorMessage The short error message from the server. + @param detailErrorMessage The detailed error message from the server. + @return A client error, if any. + */ +- (nullable NSError *)clientErrorWithShortErrorMessage:(NSString *)shortErrorMessage + detailErrorMessage:(nullable NSString *)detailErrorMessage; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRAuthRequestConfiguration.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRAuthRequestConfiguration.h new file mode 100644 index 0000000..f24f23a --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRAuthRequestConfiguration.h @@ -0,0 +1,52 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +#import "FIRAuthRPCRequest.h" + +NS_ASSUME_NONNULL_BEGIN + +/** @class FIRAuthRequestConfiguration + @brief Defines configurations to be added to a request to Firebase Auth's backend. + */ +@interface FIRAuthRequestConfiguration : NSObject + +/** @property APIKey + @brief The Firebase Auth API key used in the request. + */ +@property(nonatomic, copy, readonly) NSString *APIKey; + +/** @property LanguageCode + @brief The language code used in the request. + */ +@property(nonatomic, copy, nullable) NSString *languageCode; + +/** @property additionalFrameworkMarker + @brief Additional framework marker that will be added as part of the header of every request. + */ +@property(nonatomic, copy, nullable) NSString *additionalFrameworkMarker; + +- (nullable instancetype)init NS_UNAVAILABLE; + +/** @fn initWithRequestClass:APIKey:authLanguage: + @brief Designated initializer. + @param APIKey The API key to be used in the request. + */ +- (nullable instancetype)initWithAPIKey:(NSString *)APIKey NS_DESIGNATED_INITIALIZER; +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRAuthRequestConfiguration.m b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRAuthRequestConfiguration.m new file mode 100644 index 0000000..a4ee5dd --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRAuthRequestConfiguration.m @@ -0,0 +1,34 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRAuthRequestConfiguration.h" +#import "FIRAuthExceptionUtils.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation FIRAuthRequestConfiguration + +- (nullable instancetype)initWithAPIKey:(NSString *)APIKey { + self = [super init]; + if (self) { + _APIKey = [APIKey copy]; + } + return self; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRCreateAuthURIRequest.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRCreateAuthURIRequest.h new file mode 100644 index 0000000..a4fb6f5 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRCreateAuthURIRequest.h @@ -0,0 +1,88 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +#import "FIRAuthRPCRequest.h" +#import "FIRIdentityToolkitRequest.h" + +NS_ASSUME_NONNULL_BEGIN + +/** @class FIRCreateAuthURIRequest + @brief Represents the parameters for the createAuthUri endpoint. + @see https://developers.google.com/identity/toolkit/web/reference/relyingparty/createAuthUri + */ +@interface FIRCreateAuthURIRequest : FIRIdentityToolkitRequest + +/** @property identifier + @brief The email or federated ID of the user. + */ +@property(nonatomic, copy) NSString *identifier; + +/** @property continueURI + @brief The URI to which the IDP redirects the user after the federated login flow. + */ +@property(nonatomic, copy) NSString *continueURI; + +/** @property openIDRealm + @brief Optional realm for OpenID protocol. The sub string "scheme://domain:port" of the param + "continueUri" is used if this is not set. + */ +@property(nonatomic, copy, nullable) NSString *openIDRealm; + +/** @property providerID + @brief The IdP ID. For white listed IdPs it's a short domain name e.g. google.com, aol.com, + live.net and yahoo.com. For other OpenID IdPs it's the OP identifier. + */ +@property(nonatomic, copy, nullable) NSString *providerID; + +/** @property clientID + @brief The relying party OAuth client ID. + */ +@property(nonatomic, copy, nullable) NSString *clientID; + +/** @property context + @brief The opaque value used by the client to maintain context info between the authentication + request and the IDP callback. + */ +@property(nonatomic, copy, nullable) NSString *context; + +/** @property appID + @brief The iOS client application's bundle identifier. + */ +@property(nonatomic, copy, nullable) NSString *appID; + +/** @fn initWithEndpoint:requestConfiguration:requestConfiguration. + @brief Please use initWithIdentifier:continueURI:requestConfiguration: instead. + */ +- (nullable instancetype)initWithEndpoint:(NSString *)endpoint + requestConfiguration:(FIRAuthRequestConfiguration *)requestConfiguration + NS_UNAVAILABLE; + +/** @fn initWithIdentifier:continueURI:requestConfiguration: + @brief Designated initializer. + @param identifier The email or federated ID of the user. + @param continueURI The URI to which the IDP redirects the user after the federated login flow. + @param requestConfiguration An object containing configurations to be added to the request. + */ +- (nullable instancetype)initWithIdentifier:(NSString *)identifier + continueURI:(NSString *)continueURI + requestConfiguration:(FIRAuthRequestConfiguration *)requestConfiguration + NS_DESIGNATED_INITIALIZER; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRCreateAuthURIRequest.m b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRCreateAuthURIRequest.m new file mode 100644 index 0000000..de97d4d --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRCreateAuthURIRequest.m @@ -0,0 +1,99 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRCreateAuthURIRequest.h" + +NS_ASSUME_NONNULL_BEGIN + +/** @var kCreateAuthURIEndpoint + @brief The "createAuthUri" endpoint. + */ +static NSString *const kCreateAuthURIEndpoint = @"createAuthUri"; + +/** @var kProviderIDKey + @brief The key for the "providerId" value in the request. + */ +static NSString *const kProviderIDKey = @"providerId"; + +/** @var kIdentifierKey + @brief The key for the "identifier" value in the request. + */ +static NSString *const kIdentifierKey = @"identifier"; + +/** @var kContinueURIKey + @brief The key for the "continueUri" value in the request. + */ +static NSString *const kContinueURIKey = @"continueUri"; + +/** @var kOpenIDRealmKey + @brief The key for the "openidRealm" value in the request. + */ +static NSString *const kOpenIDRealmKey = @"openidRealm"; + +/** @var kClientIDKey + @brief The key for the "clientId" value in the request. + */ +static NSString *const kClientIDKey = @"clientId"; + +/** @var kContextKey + @brief The key for the "context" value in the request. + */ +static NSString *const kContextKey = @"context"; + +/** @var kAppIDKey + @brief The key for the "appId" value in the request. + */ +static NSString *const kAppIDKey = @"appId"; + +@implementation FIRCreateAuthURIRequest + +- (nullable instancetype)initWithIdentifier:(NSString *)identifier + continueURI:(NSString *)continueURI + requestConfiguration:(FIRAuthRequestConfiguration *)requestConfiguration { + self = [super initWithEndpoint:kCreateAuthURIEndpoint requestConfiguration:requestConfiguration]; + if (self) { + _identifier = [identifier copy]; + _continueURI = [continueURI copy]; + } + return self; +} + +- (nullable id)unencodedHTTPRequestBodyWithError:(NSError *_Nullable *_Nullable)error { + NSMutableDictionary *postBody = [@{ + kIdentifierKey : _identifier, + kContinueURIKey : _continueURI + } mutableCopy]; + if (_providerID) { + postBody[kProviderIDKey] = _providerID; + } + if (_openIDRealm) { + postBody[kOpenIDRealmKey] = _openIDRealm; + } + if (_clientID) { + postBody[kClientIDKey] = _clientID; + } + if (_context) { + postBody[kContextKey] = _context; + } + if (_appID) { + postBody[kAppIDKey] = _appID; + } + return postBody; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRCreateAuthURIResponse.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRCreateAuthURIResponse.h new file mode 100644 index 0000000..8e8f7b0 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRCreateAuthURIResponse.h @@ -0,0 +1,61 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +#import "FIRAuthRPCResponse.h" + +NS_ASSUME_NONNULL_BEGIN + +/** @class FIRCreateAuthURIResponse + @brief Represents the parameters for the createAuthUri endpoint. + @see https://developers.google.com/identity/toolkit/web/reference/relyingparty/createAuthUri + */ +@interface FIRCreateAuthURIResponse : NSObject + +/** @property authUri + @brief The URI used by the IDP to authenticate the user. + */ +@property(nonatomic, strong, readonly, nullable) NSString *authURI; + +/** @property registered + @brief Whether the user is registered if the identifier is an email. + */ +@property(nonatomic, assign, readonly) BOOL registered; + +/** @property providerId + @brief The provider ID of the auth URI. + */ +@property(nonatomic, strong, readonly, nullable) NSString *providerID; + +/** @property forExistingProvider + @brief True if the authUri is for user's existing provider. + */ +@property(nonatomic, assign, readonly) BOOL forExistingProvider; + +/** @property allProviders + @brief A list of provider IDs the passed @c identifier could use to sign in with. + */ +@property(nonatomic, copy, readonly, nullable) NSArray *allProviders; + +/** @property signinMethods + @brief A list of sign-in methods available for the passed @c identifier. + */ +@property(nonatomic, copy, readonly, nullable) NSArray *signinMethods; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRCreateAuthURIResponse.m b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRCreateAuthURIResponse.m new file mode 100644 index 0000000..474582e --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRCreateAuthURIResponse.m @@ -0,0 +1,36 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRCreateAuthURIResponse.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation FIRCreateAuthURIResponse + +- (BOOL)setWithDictionary:(NSDictionary *)dictionary + error:(NSError *_Nullable *_Nullable)error { + _providerID = [dictionary[@"providerId"] copy]; + _authURI = [dictionary[@"authUri"] copy]; + _registered = [dictionary[@"registered"] boolValue]; + _forExistingProvider = [dictionary[@"forExistingProvider"] boolValue]; + _allProviders = [dictionary[@"allProviders"] copy]; + _signinMethods = [dictionary[@"signinMethods"] copy]; + return YES; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRDeleteAccountRequest.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRDeleteAccountRequest.h new file mode 100644 index 0000000..89a7d26 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRDeleteAccountRequest.h @@ -0,0 +1,50 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +#import "FIRAuthRPCRequest.h" +#import "FIRIdentityToolkitRequest.h" + +NS_ASSUME_NONNULL_BEGIN + +/** @class FIRDeleteAccountRequest + @brief Represents the parameters for the deleteAccount endpoint. + @see https://developers.google.com/identity/toolkit/web/reference/relyingparty/deleteAccount + */ +@interface FIRDeleteAccountRequest : FIRIdentityToolkitRequest + +/** @fn initWithEndpoint:requestConfiguration:requestConfiguration. + @brief Please use initWitLocalID:accessToken:requestConfiguration instead. + */ +- (nullable instancetype)initWithEndpoint:(NSString *)endpoint + requestConfiguration:(FIRAuthRequestConfiguration *)requestConfiguration + NS_UNAVAILABLE; + +/** @fn initWitLocalID:accessToken:requestConfiguration. + @brief Designated initializer. + @param localID The local ID. + @param accessToken The access token. + @param requestConfiguration An object containing configurations to be added to the request. + */ +- (nullable instancetype)initWitLocalID:(NSString *)localID + accessToken:(NSString *)accessToken + requestConfiguration:(FIRAuthRequestConfiguration *)requestConfiguration + NS_DESIGNATED_INITIALIZER; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRDeleteAccountRequest.m b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRDeleteAccountRequest.m new file mode 100644 index 0000000..701d446 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRDeleteAccountRequest.m @@ -0,0 +1,69 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRDeleteAccountRequest.h" + +NS_ASSUME_NONNULL_BEGIN + +/** @var kCreateAuthURIEndpoint + @brief The "deleteAccount" endpoint. + */ +static NSString *const kDeleteAccountEndpoint = @"deleteAccount"; + +/** @var kIDTokenKey + @brief The key for the "idToken" value in the request. This is actually the STS Access Token, + despite it's confusing (backwards compatiable) parameter name. + */ +static NSString *const kIDTokenKey = @"idToken"; + +/** @var kLocalIDKey + @brief The key for the "localID" value in the request. + */ +static NSString *const kLocalIDKey = @"localId"; + +@implementation FIRDeleteAccountRequest { + /** @var _accessToken + @brief The STS Access Token of the authenticated user. + */ + NSString *_accessToken; + + /** @var _localID + @brief The localID of the user. + */ + NSString *_localID; +} + +- (nullable instancetype)initWitLocalID:(NSString *)localID + accessToken:(NSString *)accessToken + requestConfiguration:(FIRAuthRequestConfiguration *)requestConfiguration { + self = [super initWithEndpoint:kDeleteAccountEndpoint requestConfiguration:requestConfiguration]; + if (self) { + _localID = [localID copy]; + _accessToken = [accessToken copy]; + } + return self; +} + +- (nullable id)unencodedHTTPRequestBodyWithError:(NSError *_Nullable *_Nullable)error { + NSMutableDictionary *postBody = [NSMutableDictionary dictionary]; + postBody[kIDTokenKey] = _accessToken; + postBody[kLocalIDKey] = _localID; + return postBody; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRDeleteAccountResponse.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRDeleteAccountResponse.h new file mode 100644 index 0000000..cf09f94 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRDeleteAccountResponse.h @@ -0,0 +1,30 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +#import "FIRAuthRPCResponse.h" + +NS_ASSUME_NONNULL_BEGIN + +/** @class FIRDeleteAccountResponse + @brief Represents the response from the deleteAccount endpoint. + @see https://developers.google.com/identity/toolkit/web/reference/relyingparty/deleteAccount + */ +@interface FIRDeleteAccountResponse : NSObject +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRDeleteAccountResponse.m b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRDeleteAccountResponse.m new file mode 100644 index 0000000..d75d2eb --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRDeleteAccountResponse.m @@ -0,0 +1,30 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRDeleteAccountResponse.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation FIRDeleteAccountResponse + +- (BOOL)setWithDictionary:(NSDictionary *)dictionary + error:(NSError *_Nullable *_Nullable)error { + return YES; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIREmailLinkSignInRequest.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIREmailLinkSignInRequest.h new file mode 100644 index 0000000..e1b10d8 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIREmailLinkSignInRequest.h @@ -0,0 +1,66 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +#import "FIRAuthRPCRequest.h" +#import "FIRIdentityToolkitRequest.h" + +NS_ASSUME_NONNULL_BEGIN + +/** @class FIREmailLinkSignInRequest + @brief Represents the parameters for the emailLinkSignin endpoint. + */ +@interface FIREmailLinkSignInRequest : FIRIdentityToolkitRequest + +#pragma mark - Components of "postBody" + +/** @property email + @brief The email identifier used to complete the email link sign-in. + */ +@property(nonatomic, copy, readonly) NSString *email; + +/** @property oobCode + @brief The OOB code used to complete the email link sign-in flow. + */ +@property(nonatomic, copy, readonly) NSString *oobCode; + +/** @property idToken + @brief The ID Token code potentially used to complete the email link sign-in flow. + */ +@property(nonatomic, copy) NSString *IDToken; + +/** @fn initWithEndpoint:requestConfiguration: + @brief Please use initWithProviderID:requestConfifuration instead. + */ +- (instancetype)initWithEndpoint:(NSString *)endpoint + requestConfiguration:(FIRAuthRequestConfiguration *)requestConfiguration NS_UNAVAILABLE; + +/** @fn initWithProviderID:requestConfifuration + @brief Designated initializer. + @param email The email identifier used to complete hte email link sign-in flow. + @param oobCode The OOB code used to complete the email link sign-in flow. + @param requestConfiguration An object containing configurations to be added to the request. + + */ +- (instancetype)initWithEmail:(NSString *)email + oobCode:(NSString *)oobCode + requestConfiguration:(FIRAuthRequestConfiguration *)requestConfiguration + NS_DESIGNATED_INITIALIZER; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIREmailLinkSignInRequest.m b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIREmailLinkSignInRequest.m new file mode 100644 index 0000000..2750f9f --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIREmailLinkSignInRequest.m @@ -0,0 +1,74 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIREmailLinkSignInRequest.h" + +NS_ASSUME_NONNULL_BEGIN + +/** @var kEmailLinkSigninEndpoint + @brief The "EmailLinkSignin" endpoint. + */ +static NSString *const kEmailLinkSigninEndpoint = @"emailLinkSignin"; + +/** @var kEmailKey + @brief The key for the "identifier" value in the request. + */ +static NSString *const kEmailKey = @"email"; + +/** @var kEmailLinkKey + @brief The key for the "emailLink" value in the request. + */ +static NSString *const kOOBCodeKey = @"oobCode"; + +/** @var kIDTokenKey + @brief The key for the "IDToken" value in the request. + */ +static NSString *const kIDTokenKey = @"idToken"; + +/** @var kPostBodyKey + @brief The key for the "postBody" value in the request. + */ +static NSString *const kPostBodyKey = @"postBody"; + +@implementation FIREmailLinkSignInRequest + +- (instancetype)initWithEmail:(NSString *)email + oobCode:(NSString *)oobCode + requestConfiguration:(FIRAuthRequestConfiguration *)requestConfiguration { + self = [super initWithEndpoint:kEmailLinkSigninEndpoint + requestConfiguration:requestConfiguration]; + if (self) { + _email = email; + _oobCode = oobCode; + } + return self; +} + +- (nullable id)unencodedHTTPRequestBodyWithError:(NSError *_Nullable *_Nullable)error { + NSMutableDictionary *postBody = [@{ + kEmailKey : _email, + kOOBCodeKey : _oobCode, + } mutableCopy]; + + if (_IDToken) { + postBody[kIDTokenKey] = _IDToken; + } + return postBody; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIREmailLinkSignInResponse.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIREmailLinkSignInResponse.h new file mode 100644 index 0000000..df0a127 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIREmailLinkSignInResponse.h @@ -0,0 +1,54 @@ +/* + * Copyright 2017 Google + * + * 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. + */ +#import + +#import "FIRAuthRPCResponse.h" + +NS_ASSUME_NONNULL_BEGIN + +/** @class FIRVerifyAssertionResponse + @brief Represents the response from the emailLinkSignin endpoint. + */ +@interface FIREmailLinkSignInResponse : NSObject + +/** @property IDToken + @brief The ID token in the email link sign-in response. + */ +@property(nonatomic, copy, readonly) NSString *IDToken; + +/** @property email + @brief The email returned by the IdP. + */ +@property(nonatomic, strong, readonly, nullable) NSString *email; + +/** @property refreshToken + @brief The refreshToken returned by the server. + */ +@property(nonatomic, strong, readonly, nullable) NSString *refreshToken; + +/** @property approximateExpirationDate + @brief The approximate expiration date of the access token. + */ +@property(nonatomic, copy, readonly, nullable) NSDate *approximateExpirationDate; + +/** @property isNewUser + @brief Flag indicating that the user signing in is a new user and not a returning user. + */ +@property(nonatomic, assign) BOOL isNewUser; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIREmailLinkSignInResponse.m b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIREmailLinkSignInResponse.m new file mode 100644 index 0000000..f58cab5 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIREmailLinkSignInResponse.m @@ -0,0 +1,36 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIREmailLinkSignInResponse.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation FIREmailLinkSignInResponse + +- (BOOL)setWithDictionary:(NSDictionary *)dictionary + error:(NSError *_Nullable *_Nullable)error { + _email = [dictionary[@"email"] copy]; + _IDToken = [dictionary[@"idToken"] copy]; + _isNewUser = [dictionary[@"isNewUser"] boolValue]; + _refreshToken = [dictionary[@"refreshToken"] copy]; + _approximateExpirationDate = [dictionary[@"expiresIn"] isKindOfClass:[NSString class]] ? + [NSDate dateWithTimeIntervalSinceNow:[dictionary[@"expiresIn"] doubleValue]] : nil; + return YES; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRGetAccountInfoRequest.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRGetAccountInfoRequest.h new file mode 100644 index 0000000..a5a8a20 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRGetAccountInfoRequest.h @@ -0,0 +1,53 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +#import "FIRAuthRPCRequest.h" +#import "FIRIdentityToolkitRequest.h" + +NS_ASSUME_NONNULL_BEGIN + +/** @class FIRGetAccountInfoRequest + @brief Represents the parameters for the getAccountInfo endpoint. + @see https://developers.google.com/identity/toolkit/web/reference/relyingparty/getAccountInfo + */ +@interface FIRGetAccountInfoRequest : FIRIdentityToolkitRequest + +/** @property accessToken + @brief The STS Access Token for the authenticated user. + */ +@property(nonatomic, copy) NSString *accessToken; + +/** @fn initWithEndpoint:requestConfiguration:requestConfiguration + @brief Please use initWithAccessToken:requestConfiguration: instead. + */ +- (nullable instancetype)initWithEndpoint:(NSString *)endpoint + requestConfiguration:(FIRAuthRequestConfiguration *)requestConfiguration + NS_UNAVAILABLE; + +/** @fn initWithAccessToken:requestConfiguration + @brief Designated initializer. + @param accessToken The Access Token of the authenticated user. + @param requestConfiguration An object containing configurations to be added to the request. + */ +- (nullable instancetype)initWithAccessToken:(NSString *)accessToken + requestConfiguration:(FIRAuthRequestConfiguration *)requestConfiguration + NS_DESIGNATED_INITIALIZER; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRGetAccountInfoRequest.m b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRGetAccountInfoRequest.m new file mode 100644 index 0000000..e707937 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRGetAccountInfoRequest.m @@ -0,0 +1,52 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRGetAccountInfoRequest.h" + +NS_ASSUME_NONNULL_BEGIN + +/** @var kGetAccountInfoEndpoint + @brief The "getAccountInfo" endpoint. + */ +static NSString *const kGetAccountInfoEndpoint = @"getAccountInfo"; + +/** @var kIDTokenKey + @brief The key for the "idToken" value in the request. This is actually the STS Access Token, + despite it's confusing (backwards compatiable) parameter name. + */ +static NSString *const kIDTokenKey = @"idToken"; + +@implementation FIRGetAccountInfoRequest + +- (nullable instancetype)initWithAccessToken:(NSString *)accessToken + requestConfiguration:(FIRAuthRequestConfiguration *)requestConfiguration { + self = [super initWithEndpoint:kGetAccountInfoEndpoint + requestConfiguration:requestConfiguration]; + if (self) { + _accessToken = [accessToken copy]; + } + return self; +} + +- (nullable id)unencodedHTTPRequestBodyWithError:(NSError *_Nullable *_Nullable)error { + return @{ + kIDTokenKey : _accessToken + }; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRGetAccountInfoResponse.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRGetAccountInfoResponse.h new file mode 100644 index 0000000..6c30dbe --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRGetAccountInfoResponse.h @@ -0,0 +1,156 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +#import "FIRAuthRPCResponse.h" + +NS_ASSUME_NONNULL_BEGIN + +/** @class FIRGetAccountInfoResponseProviderUserInfo + @brief Represents the provider user info part of the response from the getAccountInfo endpoint. + @see https://developers.google.com/identity/toolkit/web/reference/relyingparty/getAccountInfo + */ +@interface FIRGetAccountInfoResponseProviderUserInfo : NSObject + +/** @property providerID + @brief The ID of the identity provider. + */ +@property(nonatomic, strong, readonly, nullable) NSString *providerID; + +/** @property displayName + @brief The user's display name at the identity provider. + */ +@property(nonatomic, strong, readonly, nullable) NSString *displayName; + +/** @property photoURL + @brief The user's photo URL at the identity provider. + */ +@property(nonatomic, strong, readonly, nullable) NSURL *photoURL; + +/** @property federatedID + @brief The user's identifier at the identity provider. + */ +@property(nonatomic, strong, readonly, nullable) NSString *federatedID; + +/** @property email + @brief The user's email at the identity provider. + */ +@property(nonatomic, strong, readonly, nullable) NSString *email; + +/** @property phoneNumber + @brief A phone number associated with the user. + */ +@property(nonatomic, readonly, nullable) NSString *phoneNumber; + +/** @fn init + @brief Please use initWithDictionary: + */ +- (instancetype)init NS_UNAVAILABLE; + +/** @fn initWithAPIKey: + @brief Designated initializer. + @param dictionary The provider user info data from endpoint. + */ +- (instancetype)initWithDictionary:(NSDictionary *)dictionary NS_DESIGNATED_INITIALIZER; + +@end + +/** @class FIRGetAccountInfoResponseUser + @brief Represents the firebase user info part of the response from the getAccountInfo endpoint. + @see https://developers.google.com/identity/toolkit/web/reference/relyingparty/getAccountInfo + */ +@interface FIRGetAccountInfoResponseUser : NSObject + +/** @property localID + @brief The ID of the user. + */ +@property(nonatomic, strong, readonly, nullable) NSString *localID; + +/** @property email + @brief The email or the user. + */ +@property(nonatomic, strong, readonly, nullable) NSString *email; + +/** @property emailVerified + @brief Whether the email has been verified. + */ +@property(nonatomic, assign, readonly) BOOL emailVerified; + +/** @property displayName + @brief The display name of the user. + */ +@property(nonatomic, strong, readonly, nullable) NSString *displayName; + +/** @property photoURL + @brief The user's photo URL. + */ +@property(nonatomic, strong, readonly, nullable) NSURL *photoURL; + +/** @property creationDate + @brief The user's creation date. + */ +@property(nonatomic, strong, readonly, nullable) NSDate *creationDate; + +/** @property lastSignInDate + @brief The user's last login date. + */ +@property(nonatomic, strong, readonly, nullable) NSDate *lastLoginDate; + +/** @property providerUserInfo + @brief The user's profiles at the associated identity providers. + */ +@property(nonatomic, strong, readonly, nullable) + NSArray *providerUserInfo; + +/** @property passwordHash + @brief Information about user's password. + @remarks This is not necessarily the hash of user's actual password. + */ +@property(nonatomic, strong, readonly, nullable) NSString *passwordHash; + +/** @property phoneNumber + @brief A phone number associated with the user. + */ +@property(nonatomic, readonly, nullable) NSString *phoneNumber; + +/** @fn init + @brief Please use initWithDictionary: + */ +- (instancetype)init NS_UNAVAILABLE; + +/** @fn initWithAPIKey: + @brief Designated initializer. + @param dictionary The provider user info data from endpoint. + */ +- (instancetype)initWithDictionary:(NSDictionary *)dictionary NS_DESIGNATED_INITIALIZER; + +@end + +/** @class FIRGetAccountInfoResponse + @brief Represents the response from the setAccountInfo endpoint. + @see https://developers.google.com/identity/toolkit/web/reference/relyingparty/getAccountInfo + */ +@interface FIRGetAccountInfoResponse : NSObject + +/** @property providerUserInfo + @brief The requested users' profiles. + */ +@property(nonatomic, strong, readonly, nullable) NSArray *users; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRGetAccountInfoResponse.m b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRGetAccountInfoResponse.m new file mode 100644 index 0000000..cb78b78 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRGetAccountInfoResponse.m @@ -0,0 +1,108 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRGetAccountInfoResponse.h" + +#import "FIRAuthErrorUtils.h" + +NS_ASSUME_NONNULL_BEGIN + +/** @var kErrorKey + @brief The key for the "error" value in JSON responses from the server. + */ +static NSString *const kErrorKey = @"error"; + +@implementation FIRGetAccountInfoResponseProviderUserInfo + +- (instancetype)initWithDictionary:(NSDictionary *)dictionary { + self = [super init]; + if (self) { + _providerID = [dictionary[@"providerId"] copy]; + _displayName = [dictionary[@"displayName"] copy]; + NSString *photoURL = dictionary[@"photoUrl"]; + if (photoURL) { + _photoURL = [NSURL URLWithString:photoURL]; + } + _federatedID = [dictionary[@"federatedId"] copy]; + _email = [dictionary[@"email"] copy]; + _phoneNumber = [dictionary[@"phoneNumber"] copy]; + } + return self; +} + +@end + +@implementation FIRGetAccountInfoResponseUser + +- (instancetype)initWithDictionary:(NSDictionary *)dictionary { + self = [super init]; + if (self) { + NSArray *providerUserInfoData = dictionary[@"providerUserInfo"]; + if (providerUserInfoData) { + NSMutableArray *providerUserInfoArray = + [NSMutableArray arrayWithCapacity:providerUserInfoData.count]; + for (NSDictionary *dictionary in providerUserInfoData) { + [providerUserInfoArray addObject: + [[FIRGetAccountInfoResponseProviderUserInfo alloc] initWithDictionary:dictionary]]; + } + _providerUserInfo = [providerUserInfoArray copy]; + } + _localID = [dictionary[@"localId"] copy]; + _displayName = [dictionary[@"displayName"] copy]; + _email = [dictionary[@"email"] copy]; + NSString *photoURL = dictionary[@"photoUrl"]; + if (photoURL) { + _photoURL = [NSURL URLWithString:photoURL]; + } + if ([dictionary[@"createdAt"] isKindOfClass:[NSString class]]) { + // Divide by 1000 in order to convert miliseconds to seconds. + NSTimeInterval creationDateTimeInterval = [dictionary[@"createdAt"] doubleValue] / 1000; + _creationDate = [NSDate dateWithTimeIntervalSince1970:creationDateTimeInterval]; + } + if ([dictionary[@"lastLoginAt"] isKindOfClass:[NSString class]]) { + // Divide by 1000 in order to convert miliseconds to seconds + NSTimeInterval creationDateTimeInterval = [dictionary[@"lastLoginAt"] doubleValue] / 1000; + _lastLoginDate = [NSDate dateWithTimeIntervalSince1970:creationDateTimeInterval]; + } + _emailVerified = [dictionary[@"emailVerified"] boolValue]; + _passwordHash = [dictionary[@"passwordHash"] copy]; + _phoneNumber = [dictionary[@"phoneNumber"] copy]; + } + return self; +} + +@end + +@implementation FIRGetAccountInfoResponse + +- (BOOL)setWithDictionary:(NSDictionary *)dictionary + error:(NSError *_Nullable *_Nullable)error { + NSArray *usersData = dictionary[@"users"]; + // The client side never sends a getAccountInfo request with multiple localID, so only one user + // data is expected in the response. + if (![usersData isKindOfClass:[NSArray class]] || usersData.count != 1) { + if (error) { + *error = [FIRAuthErrorUtils unexpectedResponseWithDeserializedResponse:dictionary]; + } + return NO; + } + _users = @[ [[FIRGetAccountInfoResponseUser alloc] initWithDictionary:usersData.firstObject] ]; + return YES; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRGetOOBConfirmationCodeRequest.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRGetOOBConfirmationCodeRequest.h new file mode 100644 index 0000000..3130c78 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRGetOOBConfirmationCodeRequest.h @@ -0,0 +1,153 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +#import "FIRAuthRPCRequest.h" +#import "FIRIdentityToolkitRequest.h" + +@class FIRActionCodeSettings; + +NS_ASSUME_NONNULL_BEGIN + +/** @enum FIRGetOOBConfirmationCodeRequestType + @brief Types of OOB Confirmation Code requests. + */ +typedef NS_ENUM(NSInteger, FIRGetOOBConfirmationCodeRequestType) { + /** @var FIRGetOOBConfirmationCodeRequestTypePasswordReset + @brief Requests a password reset code. + */ + FIRGetOOBConfirmationCodeRequestTypePasswordReset, + + /** @var FIRGetOOBConfirmationCodeRequestTypeVerifyEmail + @brief Requests an email verification code. + */ + FIRGetOOBConfirmationCodeRequestTypeVerifyEmail, + + /** @var FIRGetOOBConfirmationCodeRequestTypeEmailLink + @brief Requests an email sign-in link. + */ + FIRGetOOBConfirmationCodeRequestTypeEmailLink, +}; + +/** @enum FIRGetOOBConfirmationCodeRequest + @brief Represents the parameters for the getOOBConfirmationCode endpoint. + */ +@interface FIRGetOOBConfirmationCodeRequest : FIRIdentityToolkitRequest + +/** @property requestType + @brief The types of OOB Confirmation Code to request. + */ +@property(nonatomic, assign, readonly) FIRGetOOBConfirmationCodeRequestType requestType; + +/** @property email + @brief The email of the user. + @remarks For password reset. + */ +@property(nonatomic, copy, nullable, readonly) NSString *email; + +/** @property accessToken + @brief The STS Access Token of the authenticated user. + @remarks For email change. + */ +@property(nonatomic, copy, nullable, readonly) NSString *accessToken; + +/** @property continueURL + @brief This URL represents the state/Continue URL in the form of a universal link. + */ +@property(nonatomic, copy, nullable, readonly) NSString *continueURL; + +/** @property iOSBundleID + @brief The iOS bundle Identifier, if available. + */ +@property(nonatomic, copy, nullable, readonly) NSString *iOSBundleID; + +/** @property androidPackageName + @brief The Android package name, if available. + */ +@property(nonatomic, copy, nullable, readonly) NSString *androidPackageName; + +/** @property androidMinimumVersion + @brief The minimum Android version supported, if available. + */ +@property(nonatomic, copy, nullable, readonly) NSString *androidMinimumVersion; + +/** @property androidInstallIfNotAvailable + @brief Indicates whether or not the Android app should be installed if not already available. + */ +@property(nonatomic, assign, readonly) BOOL androidInstallApp; + +/** @property handleCodeInApp + @brief Indicates whether the action code link will open the app directly or after being + redirected from a Firebase owned web widget. + */ +@property(assign, nonatomic) BOOL handleCodeInApp; + +/** @property dynamicLinkDomain + @brief The Firebase Dynamic Link domain used for out of band code flow. + */ +@property (copy, nonatomic, nullable) NSString *dynamicLinkDomain; + + +/** @fn passwordResetRequestWithEmail:actionCodeSettings:requestConfiguration: + @brief Creates a password reset request. + @param email The user's email address. + @param actionCodeSettings An object of FIRActionCodeSettings which specifies action code + settings to be applied to the password reset request. + @param requestConfiguration An object containing configurations to be added to the request. + @return A password reset request. + */ ++ (nullable FIRGetOOBConfirmationCodeRequest *) + passwordResetRequestWithEmail:(NSString *)email + actionCodeSettings:(nullable FIRActionCodeSettings *)actionCodeSettings + requestConfiguration:(FIRAuthRequestConfiguration *)requestConfiguration; + +/** @fn verifyEmailRequestWithAccessToken:actionCodeSettings:requestConfiguration: + @brief Creates a password reset request. + @param accessToken The user's STS Access Token. + @param actionCodeSettings An object of FIRActionCodeSettings which specifies action code + settings to be applied to the email verification request. + @param requestConfiguration An object containing configurations to be added to the request. + @return A password reset request. + */ ++ (nullable FIRGetOOBConfirmationCodeRequest *) + verifyEmailRequestWithAccessToken:(NSString *)accessToken + actionCodeSettings:(nullable FIRActionCodeSettings *)actionCodeSettings + requestConfiguration:(FIRAuthRequestConfiguration *)requestConfiguration; + +/** @fn signInWithEmailLinkRequest:actionCodeSettings:requestConfiguration: + @brief Creates a sign-in with email link. + @param email The user's email address. + @param actionCodeSettings An object of FIRActionCodeSettings which specifies action code + settings to be applied to the email sign-in link. + @param requestConfiguration An object containing configurations to be added to the request. + @return An email sign-in link request. + */ ++ (nullable FIRGetOOBConfirmationCodeRequest *) + signInWithEmailLinkRequest:(NSString *)email + actionCodeSettings:(nullable FIRActionCodeSettings *)actionCodeSettings + requestConfiguration:(FIRAuthRequestConfiguration *)requestConfiguration; + +/** @fn init + @brief Please use a factory method. + */ +- (nullable instancetype)initWithEndpoint:(NSString *)endpoint + requestConfiguration:(FIRAuthRequestConfiguration *)requestConfiguration + NS_UNAVAILABLE; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRGetOOBConfirmationCodeRequest.m b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRGetOOBConfirmationCodeRequest.m new file mode 100644 index 0000000..4fa953f --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRGetOOBConfirmationCodeRequest.m @@ -0,0 +1,248 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRGetOOBConfirmationCodeRequest.h" + +#import "FIRActionCodeSettings.h" + +#import "FIRAuthErrorUtils.h" +#import "FIRAuth_Internal.h" + +NS_ASSUME_NONNULL_BEGIN + +/** @var kEndpoint + @brief The getOobConfirmationCode endpoint name. + */ +static NSString *const kGetOobConfirmationCodeEndpoint = @"getOobConfirmationCode"; + +/** @var kRequestTypeKey + @brief The name of the required "requestType" property in the request. + */ +static NSString *const kRequestTypeKey = @"requestType"; + +/** @var kEmailKey + @brief The name of the "email" property in the request. + */ +static NSString *const kEmailKey = @"email"; + +/** @var kIDTokenKey + @brief The key for the "idToken" value in the request. This is actually the STS Access Token, + despite it's confusing (backwards compatiable) parameter name. + */ +static NSString *const kIDTokenKey = @"idToken"; + +/** @var kContinueURLKey + @brief The key for the "continue URL" value in the request. + */ +static NSString *const kContinueURLKey = @"continueUrl"; + +/** @var kIosBundeIDKey + @brief The key for the "iOS Bundle Identifier" value in the request. + */ +static NSString *const kIosBundleIDKey = @"iOSBundleId"; + +/** @var kAndroidPackageNameKey + @brief The key for the "Android Package Name" value in the request. + */ +static NSString *const kAndroidPackageNameKey = @"androidPackageName"; + +/** @var kAndroidInstallAppKey + @brief The key for the request parameter indicating whether the android app should be installed + or not. + */ +static NSString *const kAndroidInstallAppKey = @"androidInstallApp"; + +/** @var kAndroidMinimumVersionKey + @brief The key for the "minimum Android version supported" value in the request. + */ +static NSString *const kAndroidMinimumVersionKey = @"androidMinimumVersion"; + +/** @var kCanHandleCodeInAppKey + @brief The key for the request parameter indicating whether the action code can be handled in + the app or not. + */ +static NSString *const kCanHandleCodeInAppKey = @"canHandleCodeInApp"; + +/** @var kDynamicLinkDomainKey + @brief The key for the "dynamic link domain" value in the request. + */ +static NSString *const kDynamicLinkDomainKey = @"dynamicLinkDomain"; + +/** @var kPasswordResetRequestTypeValue + @brief The value for the "PASSWORD_RESET" request type. + */ +static NSString *const kPasswordResetRequestTypeValue = @"PASSWORD_RESET"; + +/** @var kEmailLinkSignInTypeValue + @brief The value for the "EMAIL_SIGNIN" request type. + */ +static NSString *const kEmailLinkSignInTypeValue= @"EMAIL_SIGNIN"; + +/** @var kVerifyEmailRequestTypeValue + @brief The value for the "VERIFY_EMAIL" request type. + */ +static NSString *const kVerifyEmailRequestTypeValue = @"VERIFY_EMAIL"; + +@interface FIRGetOOBConfirmationCodeRequest () + +/** @fn initWithRequestType:email:APIKey: + @brief Designated initializer. + @param requestType The types of OOB Confirmation Code to request. + @param email The email of the user. + @param accessToken The STS Access Token of the currently signed in user. + @param actionCodeSettings An object of FIRActionCodeSettings which specifies action code + settings to be applied to the OOB code request. + @param requestConfiguration An object containing configurations to be added to the request. + */ +- (nullable instancetype)initWithRequestType:(FIRGetOOBConfirmationCodeRequestType)requestType + email:(nullable NSString *)email + accessToken:(nullable NSString *)accessToken + actionCodeSettings:(nullable FIRActionCodeSettings *)actionCodeSettings + requestConfiguration:(FIRAuthRequestConfiguration *)requestConfiguration + NS_DESIGNATED_INITIALIZER; + +@end + +@implementation FIRGetOOBConfirmationCodeRequest + +/** @var requestTypeStringValueForRequestType: + @brief Returns the string equivilent for an @c FIRGetOOBConfirmationCodeRequestType value. + */ ++ (NSString *)requestTypeStringValueForRequestType: + (FIRGetOOBConfirmationCodeRequestType)requestType { + switch (requestType) { + case FIRGetOOBConfirmationCodeRequestTypePasswordReset: + return kPasswordResetRequestTypeValue; + case FIRGetOOBConfirmationCodeRequestTypeVerifyEmail: + return kVerifyEmailRequestTypeValue; + case FIRGetOOBConfirmationCodeRequestTypeEmailLink: + return kEmailLinkSignInTypeValue; + // No default case so that we get a compiler warning if a new value was added to the enum. + } +} + ++ (nullable FIRGetOOBConfirmationCodeRequest *) + passwordResetRequestWithEmail:(NSString *)email + actionCodeSettings:(nullable FIRActionCodeSettings *)actionCodeSettings + requestConfiguration:(FIRAuthRequestConfiguration *)requestConfiguration { + return [[self alloc] initWithRequestType:FIRGetOOBConfirmationCodeRequestTypePasswordReset + email:email + accessToken:nil + actionCodeSettings:actionCodeSettings + requestConfiguration:requestConfiguration]; +} + ++ (nullable FIRGetOOBConfirmationCodeRequest *) + verifyEmailRequestWithAccessToken:(NSString *)accessToken + actionCodeSettings:(nullable FIRActionCodeSettings *)actionCodeSettings + requestConfiguration:(FIRAuthRequestConfiguration *)requestConfiguration { + return [[self alloc] initWithRequestType:FIRGetOOBConfirmationCodeRequestTypeVerifyEmail + email:nil + accessToken:accessToken + actionCodeSettings:actionCodeSettings + requestConfiguration:requestConfiguration]; +} + ++ (nullable FIRGetOOBConfirmationCodeRequest *) + signInWithEmailLinkRequest:(NSString *)email + actionCodeSettings:(nullable FIRActionCodeSettings *)actionCodeSettings + requestConfiguration:(FIRAuthRequestConfiguration *)requestConfiguration { + return [[self alloc] initWithRequestType:FIRGetOOBConfirmationCodeRequestTypeEmailLink + email:email + accessToken:nil + actionCodeSettings:actionCodeSettings + requestConfiguration:requestConfiguration]; +} + +- (nullable instancetype)initWithRequestType:(FIRGetOOBConfirmationCodeRequestType)requestType + email:(nullable NSString *)email + accessToken:(nullable NSString *)accessToken + actionCodeSettings:(nullable FIRActionCodeSettings *)actionCodeSettings + requestConfiguration:(FIRAuthRequestConfiguration *)requestConfiguration { + self = [super initWithEndpoint:kGetOobConfirmationCodeEndpoint + requestConfiguration:requestConfiguration]; + if (self) { + _requestType = requestType; + _email = email; + _accessToken = accessToken; + _continueURL = actionCodeSettings.URL.absoluteString; + _iOSBundleID = actionCodeSettings.iOSBundleID; + _androidPackageName = actionCodeSettings.androidPackageName; + _androidMinimumVersion = actionCodeSettings.androidMinimumVersion; + _androidInstallApp = actionCodeSettings.androidInstallIfNotAvailable; + _handleCodeInApp = actionCodeSettings.handleCodeInApp; + _dynamicLinkDomain = actionCodeSettings.dynamicLinkDomain; + } + return self; +} + +- (nullable id)unencodedHTTPRequestBodyWithError:(NSError *_Nullable *_Nullable)error { + NSMutableDictionary *body = [@{ + kRequestTypeKey : [[self class] requestTypeStringValueForRequestType:_requestType] + } mutableCopy]; + + // For password reset requests, we only need an email address in addition to the already required + // fields. + if (_requestType == FIRGetOOBConfirmationCodeRequestTypePasswordReset) { + body[kEmailKey] = _email; + } + + // For verify email requests, we only need an STS Access Token in addition to the already required + // fields. + if (_requestType == FIRGetOOBConfirmationCodeRequestTypeVerifyEmail) { + body[kIDTokenKey] = _accessToken; + } + + // For email sign-in link requests, we only need an email address in addition to the already + // required fields. + if (_requestType == FIRGetOOBConfirmationCodeRequestTypeEmailLink) { + body[kEmailKey] = _email; + } + + if (_continueURL) { + body[kContinueURLKey] = _continueURL; + } + + if (_iOSBundleID) { + body[kIosBundleIDKey] = _iOSBundleID; + } + + if (_androidPackageName) { + body[kAndroidPackageNameKey] = _androidPackageName; + } + + if (_androidMinimumVersion) { + body[kAndroidMinimumVersionKey] = _androidMinimumVersion; + } + + if (_androidInstallApp) { + body[kAndroidInstallAppKey] = @YES; + } + + if (_handleCodeInApp) { + body[kCanHandleCodeInAppKey] = @YES; + } + + if (_dynamicLinkDomain) { + body[kDynamicLinkDomainKey] = _dynamicLinkDomain; + } + + return body; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRGetOOBConfirmationCodeResponse.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRGetOOBConfirmationCodeResponse.h new file mode 100644 index 0000000..69aa458 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRGetOOBConfirmationCodeResponse.h @@ -0,0 +1,35 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +#import "FIRAuthRPCResponse.h" + +NS_ASSUME_NONNULL_BEGIN + +/** @class FIRGetOOBConfirmationCodeResponse + @brief Represents the response from the getOobConfirmationCode endpoint. + */ +@interface FIRGetOOBConfirmationCodeResponse : NSObject + +/** @property OOBCode + @brief The OOB code returned by the server in some cases. + */ +@property(nonatomic, copy, readonly, nullable) NSString *OOBCode; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRGetOOBConfirmationCodeResponse.m b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRGetOOBConfirmationCodeResponse.m new file mode 100644 index 0000000..0b6c416 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRGetOOBConfirmationCodeResponse.m @@ -0,0 +1,36 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRGetOOBConfirmationCodeResponse.h" + +NS_ASSUME_NONNULL_BEGIN + +/** @var kOOBCodeKey + @brief The name of the field in the response JSON for the OOB code. + */ +static NSString *const kOOBCodeKey = @"oobCode"; + +@implementation FIRGetOOBConfirmationCodeResponse + +- (BOOL)setWithDictionary:(NSDictionary *)dictionary + error:(NSError *_Nullable *_Nullable)error { + _OOBCode = [dictionary[kOOBCodeKey] copy]; + return YES; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRGetProjectConfigRequest.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRGetProjectConfigRequest.h new file mode 100644 index 0000000..7c37e8d --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRGetProjectConfigRequest.h @@ -0,0 +1,41 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRIdentityToolkitRequest.h" + +#import "FIRAuthRPCRequest.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface FIRGetProjectConfigRequest : FIRIdentityToolkitRequest + +/** @fn initWithEndpoint:requestConfiguration: + @brief Please use initWithRequestConfiguration: + */ +- (nullable instancetype)initWithEndpoint:(NSString *)endpoint + requestConfiguration:(FIRAuthRequestConfiguration *)requestConfiguration + NS_UNAVAILABLE; + +/** @fn initWithTemporaryProof:phoneNumberAPIKey + @brief Designated initializer. + @param requestConfiguration An object containing configurations to be added to the request. + */ +- (nullable instancetype)initWithRequestConfiguration: + (FIRAuthRequestConfiguration *)requestConfiguration NS_DESIGNATED_INITIALIZER; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRGetProjectConfigRequest.m b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRGetProjectConfigRequest.m new file mode 100644 index 0000000..acfcc02 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRGetProjectConfigRequest.m @@ -0,0 +1,40 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRGetProjectConfigRequest.h" + +NS_ASSUME_NONNULL_BEGIN + +/** @var kGetProjectConfigEndPoint + @brief The "getProjectConfig" endpoint. + */ +static NSString *const kGetProjectConfigEndPoint = @"getProjectConfig"; + +@implementation FIRGetProjectConfigRequest + +- (nullable instancetype)initWithRequestConfiguration: + (FIRAuthRequestConfiguration *)requestConfiguration { + return [super initWithEndpoint:kGetProjectConfigEndPoint + requestConfiguration:requestConfiguration]; +} + +- (BOOL)containsPostBody { + return NO; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRGetProjectConfigResponse.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRGetProjectConfigResponse.h new file mode 100644 index 0000000..bd27cd2 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRGetProjectConfigResponse.h @@ -0,0 +1,40 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +#import "FIRAuthRPCResponse.h" + +NS_ASSUME_NONNULL_BEGIN + +/** @class FIRGetProjectConfigResponse + @brief Represents the response from the getProjectConfig endpoint. + */ +@interface FIRGetProjectConfigResponse : NSObject + +/** @property projectID + @brief The unique ID pertaining to the current project. + */ +@property(nonatomic, strong, readonly, nullable) NSString *projectID; + +/** @property authorizedDomains + @brief A list of domains whitelisted for the current project. + */ +@property(nonatomic, strong, readonly, nullable) NSArray *authorizedDomains; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRGetProjectConfigResponse.m b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRGetProjectConfigResponse.m new file mode 100644 index 0000000..030edd1 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRGetProjectConfigResponse.m @@ -0,0 +1,42 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRGetProjectConfigResponse.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation FIRGetProjectConfigResponse + +- (BOOL)setWithDictionary:(NSDictionary *)dictionary + error:(NSError *_Nullable *_Nullable)error { + _projectID = [dictionary[@"projectId"] copy]; + id authorizedDomains = dictionary[@"authorizedDomains"]; + if ([authorizedDomains isKindOfClass:[NSString class]]) { + NSData *data = [authorizedDomains dataUsingEncoding:NSUTF8StringEncoding]; + authorizedDomains = [NSJSONSerialization JSONObjectWithData:data + options:NSJSONReadingMutableLeaves + error:nil]; + } + if ([authorizedDomains isKindOfClass:[NSArray class]]) { + _authorizedDomains = [[NSArray alloc] initWithArray:authorizedDomains + copyItems:YES]; + } + return YES; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRIdentityToolkitRequest.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRIdentityToolkitRequest.h new file mode 100644 index 0000000..b5ca726 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRIdentityToolkitRequest.h @@ -0,0 +1,66 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +#import "FIRAuthRequestConfiguration.h" + +@class FIRAuthRequestConfiguration; + +NS_ASSUME_NONNULL_BEGIN + +/** @class FIRIdentityToolkitRequest + @brief Represents a request to an identity toolkit endpoint. + */ +@interface FIRIdentityToolkitRequest : NSObject + +/** @property endpoint + @brief Gets the RPC's endpoint. + */ +@property(nonatomic, copy, readonly) NSString *endpoint; + +/** @property APIKey + @brief Gets the client's API key used for the request. + */ +@property(nonatomic, copy, readonly) NSString *APIKey; + +/** @fn init + @brief Please use initWithEndpoint:APIKey: + */ +- (instancetype)init NS_UNAVAILABLE; + +/** @fn initWithEndpoint:APIKey: + @brief Designated initializer. + @param endpoint The endpoint name. + @param requestConfiguration An object containing configurations to be added to the request. + */ +- (nullable instancetype)initWithEndpoint:(NSString *)endpoint + requestConfiguration:(FIRAuthRequestConfiguration *)requestConfiguration + NS_DESIGNATED_INITIALIZER; + +/** @fn requestURL + @brief Gets the request's full URL. + */ +- (NSURL *)requestURL; + +/** @fn requestConfiguration + @brief Gets the request's configuration. + */ +- (FIRAuthRequestConfiguration *)requestConfiguration; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRIdentityToolkitRequest.m b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRIdentityToolkitRequest.m new file mode 100644 index 0000000..a1ab482 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRIdentityToolkitRequest.m @@ -0,0 +1,72 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRIdentityToolkitRequest.h" + +NS_ASSUME_NONNULL_BEGIN + +/** @var kAPIURLFormat + @brief URL format for server API calls. + */ +static NSString *const kAPIURLFormat = @"https://%@/identitytoolkit/v3/relyingparty/%@?key=%@"; + +/** @var gAPIHost + @brief Host for server API calls. + */ +static NSString *gAPIHost = @"www.googleapis.com"; + +@implementation FIRIdentityToolkitRequest { + FIRAuthRequestConfiguration *_requestConfiguration; +} + +- (nullable instancetype)initWithEndpoint:(NSString *)endpoint + requestConfiguration:(FIRAuthRequestConfiguration *)requestConfiguration { + self = [super init]; + if (self) { + _endpoint = [endpoint copy]; + _APIKey = [requestConfiguration.APIKey copy]; + _requestConfiguration = requestConfiguration; + } + return self; +} + +- (BOOL)containsPostBody { + return YES; +} + +- (NSURL *)requestURL { + NSString *URLString = [NSString stringWithFormat:kAPIURLFormat, gAPIHost, _endpoint, _APIKey]; + NSURL *URL = [NSURL URLWithString:URLString]; + return URL; +} + +- (FIRAuthRequestConfiguration *)requestConfiguration { + return _requestConfiguration; +} + +#pragma mark - Internal API for development + ++ (NSString *)host { + return gAPIHost; +} + ++ (void)setHost:(NSString *)host { + gAPIHost = host; +} + +NS_ASSUME_NONNULL_END + +@end diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRResetPasswordRequest.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRResetPasswordRequest.h new file mode 100644 index 0000000..701e305 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRResetPasswordRequest.h @@ -0,0 +1,55 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +#import "FIRAuthRPCRequest.h" +#import "FIRIdentityToolkitRequest.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface FIRResetPasswordRequest : FIRIdentityToolkitRequest + +/** @property oobCode + @brief The oobCode sent in the request. + */ +@property(nonatomic, copy, readonly) NSString *oobCode; + +/** @property updatedPassword + @brief The new password sent in the request. + */ +@property(nonatomic, copy, readonly) NSString *updatedPassword; + +/** @fn initWithEndpoint:requestConfiguration: + @brief Please use initWithOobCode:newPassword:requestConfiguration: instead. + */ +- (nullable instancetype)initWithEndpoint:(NSString *)endpoint + requestConfiguration:(FIRAuthRequestConfiguration *)requestConfiguration + NS_UNAVAILABLE; + +/** @fn initWithOobCode:newPassword:requestConfiguration: + @brief Designated initializer. + @param oobCode The OOB Code. + @param newPassword The new password. + @param requestConfiguration An object containing configurations to be added to the request. + */ +- (nullable instancetype)initWithOobCode:(NSString *)oobCode + newPassword:(nullable NSString *)newPassword + requestConfiguration:(FIRAuthRequestConfiguration *)requestConfiguration; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRResetPasswordRequest.m b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRResetPasswordRequest.m new file mode 100644 index 0000000..1295037 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRResetPasswordRequest.m @@ -0,0 +1,60 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRResetPasswordRequest.h" + +NS_ASSUME_NONNULL_BEGIN + +/** @var kResetPasswordEndpoint + @brief The "resetPassword" endpoint. + */ +static NSString *const kResetPasswordEndpoint = @"resetPassword"; + +/** @var kOOBCodeKey + @brief The "resetPassword" key. + */ +static NSString *const kOOBCodeKey = @"oobCode"; + +/** @var kCurrentPasswordKey + @brief The "newPassword" key. + */ +static NSString *const kCurrentPasswordKey = @"newPassword"; + +@implementation FIRResetPasswordRequest + +- (nullable instancetype)initWithOobCode:(NSString *)oobCode + newPassword:(nullable NSString *)newPassword + requestConfiguration:(FIRAuthRequestConfiguration *)requestConfiguration { + self = [super initWithEndpoint:kResetPasswordEndpoint requestConfiguration:requestConfiguration]; + if (self) { + _oobCode = oobCode; + _updatedPassword = newPassword; + } + return self; +} + +- (nullable id)unencodedHTTPRequestBodyWithError:(NSError *_Nullable *_Nullable)error { + NSMutableDictionary *postBody = [NSMutableDictionary dictionary]; + postBody[kOOBCodeKey] = _oobCode; + if (_updatedPassword) { + postBody[kCurrentPasswordKey] = _updatedPassword; + } + return postBody; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRResetPasswordResponse.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRResetPasswordResponse.h new file mode 100644 index 0000000..28eb5f4 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRResetPasswordResponse.h @@ -0,0 +1,52 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +#import "FIRAuthRPCResponse.h" + +NS_ASSUME_NONNULL_BEGIN + +/** @class FIRAuthResetPasswordResponse + @brief Represents the response from the resetPassword endpoint. + @remarks Possible error codes: + - FIRAuthErrorCodeWeakPassword + - FIRAuthErrorCodeUserDisabled + - FIRAuthErrorCodeOperationNotAllowed + - FIRAuthErrorCodeExpiredActionCode + - FIRAuthErrorCodeInvalidActionCode + @see https://developers.google.com/identity/toolkit/web/reference/relyingparty/resetPassword + */ +@interface FIRResetPasswordResponse : NSObject + +/** @property email + @brief The email address corresponding to the reset password request. + */ +@property(nonatomic, strong, readonly) NSString *email; + +/** @property verifiedEmail + @brief The verified email returned from the backend. + */ +@property(nonatomic, strong, readonly) NSString *verifiedEmail; + +/** @property requestType + @brief The tpye of request as returned by the backend. + */ +@property(nonatomic, strong, readonly) NSString *requestType; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRResetPasswordResponse.m b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRResetPasswordResponse.m new file mode 100644 index 0000000..4f43cc9 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRResetPasswordResponse.m @@ -0,0 +1,33 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRResetPasswordResponse.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation FIRResetPasswordResponse + +- (BOOL)setWithDictionary:(NSDictionary *)dictionary + error:(NSError *_Nullable *_Nullable)error { + _email = [dictionary[@"email"] copy]; + _requestType = [dictionary[@"requestType"] copy]; + _verifiedEmail = [dictionary[@"newEmail"] copy]; + return YES; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRSecureTokenRequest.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRSecureTokenRequest.h new file mode 100644 index 0000000..14722fa --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRSecureTokenRequest.h @@ -0,0 +1,113 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +#import "FIRAuthRPCRequest.h" + +NS_ASSUME_NONNULL_BEGIN + +/** @enum FIRSecureTokenRequestGrantType + @brief Represents the possible grant types for a token request. + */ +typedef NS_ENUM(NSUInteger, FIRSecureTokenRequestGrantType) { + /** @var FIRSecureTokenRequestGrantTypeAuthorizationCode + @brief Indicates an authorization code request. + @remarks Exchanges a Gitkit "ID Token" for an STS Access Token and Refresh Token. + */ + FIRSecureTokenRequestGrantTypeAuthorizationCode, + + /** @var FIRSecureTokenRequestGrantTypeRefreshToken + @brief Indicates an refresh token request. + @remarks Uses an existing Refresh Token to create a new Access Token. + */ + FIRSecureTokenRequestGrantTypeRefreshToken, +}; + +/** @class FIRSecureTokenRequest + @brief Represents the parameters for the token endpoint. + */ +@interface FIRSecureTokenRequest : NSObject + +/** @property grantType + @brief The type of grant requested. + @see FIRSecureTokenRequestGrantType + */ +@property(nonatomic, assign, readonly) FIRSecureTokenRequestGrantType grantType; + +/** @property scope + @brief The scopes requested (a comma-delimited list of scope strings.) + */ +@property(nonatomic, copy, readonly, nullable) NSString *scope; + +/** @property refreshToken + @brief The client's refresh token. + */ +@property(nonatomic, copy, readonly, nullable) NSString *refreshToken; + +/** @property code + @brief The client's authorization code (legacy Gitkit "ID Token"). + */ +@property(nonatomic, copy, readonly, nullable) NSString *code; + +/** @property APIKey + @brief The client's API Key. + */ +@property(nonatomic, copy, readonly) NSString *APIKey; + +/** @fn authCodeRequestWithCode: + @brief Creates an authorization code request with the given code (legacy Gitkit "ID Token"). + @param code The authorization code (legacy Gitkit "ID Token"). + @param requestConfiguration An object containing configurations to be added to the request. + @return An authorization request. + */ ++ (FIRSecureTokenRequest *)authCodeRequestWithCode:(NSString *)code + requestConfiguration:(FIRAuthRequestConfiguration *) + requestConfiguration; + +/** @fn refreshRequestWithCode: + @brief Creates a refresh request with the given refresh token. + @param refreshToken The refresh token. + @param requestConfiguration An object containing configurations to be added to the request. + @return A refresh request. + */ ++ (FIRSecureTokenRequest *)refreshRequestWithRefreshToken:(NSString *)refreshToken + requestConfiguration:(FIRAuthRequestConfiguration *) + requestConfiguration; + +/** @fn init + @brief Please use initWithGrantType:scope:refreshToken:code: + */ +- (instancetype)init NS_UNAVAILABLE; + +/** @fn initWithGrantType:scope:refreshToken:code:APIKey: + @brief Designated initializer. + @param grantType The type of request. + @param scope The scopes requested. + @param refreshToken The client's refresh token (for refresh requests.) + @param code The client's authorization code (Gitkit ID Token) (for authorization code requests.) + @param requestConfiguration An object containing configurations to be added to the request. + */ +- (nullable instancetype)initWithGrantType:(FIRSecureTokenRequestGrantType)grantType + scope:(nullable NSString *)scope + refreshToken:(nullable NSString *)refreshToken + code:(nullable NSString *)code + requestConfiguration:(FIRAuthRequestConfiguration *)requestConfiguration + NS_DESIGNATED_INITIALIZER; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRSecureTokenRequest.m b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRSecureTokenRequest.m new file mode 100644 index 0000000..b733a94 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRSecureTokenRequest.m @@ -0,0 +1,163 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRSecureTokenRequest.h" +#import "FIRAuthRequestConfiguration.h" + +NS_ASSUME_NONNULL_BEGIN + +/** @var kFIRSecureTokenServiceGetTokenURLFormat + @brief The format of the secure token service URLs. Requires string format substitution with + the client's API Key. + */ +static NSString *const kFIRSecureTokenServiceGetTokenURLFormat = @"https://%@/v1/token?key=%@"; + +/** @var kFIRSecureTokenServiceGrantTypeRefreshToken + @brief The string value of the @c FIRSecureTokenRequestGrantTypeRefreshToken request type. + */ +static NSString *const kFIRSecureTokenServiceGrantTypeRefreshToken = @"refresh_token"; + +/** @var kFIRSecureTokenServiceGrantTypeAuthorizationCode + @brief The string value of the @c FIRSecureTokenRequestGrantTypeAuthorizationCode request type. + */ +static NSString *const kFIRSecureTokenServiceGrantTypeAuthorizationCode = @"authorization_code"; + +/** @var kGrantTypeKey + @brief The key for the "grantType" parameter in the request. + */ +static NSString *const kGrantTypeKey = @"grantType"; + +/** @var kScopeKey + @brief The key for the "scope" parameter in the request. + */ +static NSString *const kScopeKey = @"scope"; + +/** @var kRefreshTokenKey + @brief The key for the "refreshToken" parameter in the request. + */ +static NSString *const kRefreshTokenKey = @"refreshToken"; + +/** @var kCodeKey + @brief The key for the "code" parameter in the request. + */ +static NSString *const kCodeKey = @"code"; + +/** @var gAPIHost + @brief Host for server API calls. + */ +static NSString *gAPIHost = @"securetoken.googleapis.com"; + +@implementation FIRSecureTokenRequest { + /** @var _requestConfiguration + @brief Contains configuration relevant to the request. + */ + FIRAuthRequestConfiguration *_requestConfiguration; +} + ++ (FIRSecureTokenRequest *)authCodeRequestWithCode:(NSString *)code + requestConfiguration:(FIRAuthRequestConfiguration *) + requestConfiguration { + return [[self alloc] initWithGrantType:FIRSecureTokenRequestGrantTypeAuthorizationCode + scope:nil + refreshToken:nil + code:code + requestConfiguration:requestConfiguration]; +} + ++ (FIRSecureTokenRequest *)refreshRequestWithRefreshToken:(NSString *)refreshToken + requestConfiguration:(FIRAuthRequestConfiguration *) + requestConfiguration { + return [[self alloc] initWithGrantType:FIRSecureTokenRequestGrantTypeRefreshToken + scope:nil + refreshToken:refreshToken + code:nil + requestConfiguration:requestConfiguration]; +} + +/** @fn grantTypeStringWithGrantType: + @brief Converts a @c FIRSecureTokenRequestGrantType to it's @c NSString equivilent. + */ ++ (NSString *)grantTypeStringWithGrantType:(FIRSecureTokenRequestGrantType)grantType { + switch (grantType) { + case FIRSecureTokenRequestGrantTypeAuthorizationCode: + return kFIRSecureTokenServiceGrantTypeAuthorizationCode; + case FIRSecureTokenRequestGrantTypeRefreshToken: + return kFIRSecureTokenServiceGrantTypeRefreshToken; + // No Default case so we will notice if new grant types are added to the enum. + } +} + +- (nullable instancetype)initWithGrantType:(FIRSecureTokenRequestGrantType)grantType + scope:(nullable NSString *)scope + refreshToken:(nullable NSString *)refreshToken + code:(nullable NSString *)code + requestConfiguration:(FIRAuthRequestConfiguration *)requestConfiguration { + self = [super init]; + if (self) { + _grantType = grantType; + _scope = [scope copy]; + _refreshToken = [refreshToken copy]; + _code = [code copy]; + _APIKey = [requestConfiguration.APIKey copy]; + _requestConfiguration = requestConfiguration; + } + return self; +} + +- (FIRAuthRequestConfiguration *)requestConfiguration { + return _requestConfiguration; +} + +- (NSURL *)requestURL { + NSString *URLString = + [NSString stringWithFormat:kFIRSecureTokenServiceGetTokenURLFormat, gAPIHost, _APIKey]; + NSURL *URL = [NSURL URLWithString:URLString]; + return URL; +} + +- (BOOL)containsPostBody { + return YES; +} + +- (nullable id)unencodedHTTPRequestBodyWithError:(NSError *_Nullable *_Nullable)error { + NSMutableDictionary *postBody = [@{ + kGrantTypeKey : [[self class] grantTypeStringWithGrantType:_grantType] + } mutableCopy]; + if (_scope) { + postBody[kScopeKey] = _scope; + } + if (_refreshToken) { + postBody[kRefreshTokenKey] = _refreshToken; + } + if (_code) { + postBody[kCodeKey] = _code; + } + return postBody; +} + +#pragma mark - Internal API for development + ++ (NSString *)host { + return gAPIHost; +} + ++ (void)setHost:(NSString *)host { + gAPIHost = host; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRSecureTokenResponse.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRSecureTokenResponse.h new file mode 100644 index 0000000..0dd4a20 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRSecureTokenResponse.h @@ -0,0 +1,50 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +#import "FIRAuthRPCResponse.h" + +NS_ASSUME_NONNULL_BEGIN + +/** @class FIRSecureTokenResponse + @brief Represents the response from the token endpoint. + */ +@interface FIRSecureTokenResponse : NSObject + +/** @property approximateExpirationDate + @brief The approximate expiration date of the access token. + */ +@property(nonatomic, copy, readonly, nullable) NSDate *approximateExpirationDate; + +/** @property refreshToken + @brief The refresh token. (Possibly an updated one for refresh requests.) + */ +@property(nonatomic, copy, readonly, nullable) NSString *refreshToken; + +/** @property accessToken + @brief The new access token. + */ +@property(nonatomic, copy, readonly, nullable) NSString *accessToken; + +/** @property IDToken + @brief The new ID Token. + */ +@property(nonatomic, copy, readonly, nullable) NSString *IDToken; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRSecureTokenResponse.m b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRSecureTokenResponse.m new file mode 100644 index 0000000..1b1797b --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRSecureTokenResponse.m @@ -0,0 +1,74 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRSecureTokenResponse.h" + +#import "FIRAuthErrorUtils.h" + +NS_ASSUME_NONNULL_BEGIN + +/** @var kExpiresInKey + @brief The key for the number of seconds till the access token expires. + */ +static NSString *const kExpiresInKey = @"expires_in"; + +/** @var kRefreshTokenKey + @brief The key for the refresh token. + */ +static NSString *const kRefreshTokenKey = @"refresh_token"; + +/** @var kAccessTokenKey + @brief The key for the access token. + */ +static NSString *const kAccessTokenKey = @"access_token"; + +/** @var kIDTokenKey + @brief The key for the "id_token" value in the response. + */ +static NSString *const kIDTokenKey = @"id_token"; + +@implementation FIRSecureTokenResponse + +- (nullable NSString *)expectedKind { + return nil; +} + +- (BOOL)setWithDictionary:(NSDictionary *)dictionary + error:(NSError *_Nullable *_Nullable)error { + _refreshToken = dictionary[kRefreshTokenKey]; + _accessToken = dictionary[kAccessTokenKey]; + _IDToken = dictionary[kIDTokenKey]; + if (!_accessToken.length) { + if (error) { + *error = [FIRAuthErrorUtils unexpectedResponseWithDeserializedResponse:dictionary]; + } + return NO; + } + id expiresIn = dictionary[kExpiresInKey]; + if (![expiresIn isKindOfClass:[NSString class]]) { + if (error) { + *error = [FIRAuthErrorUtils unexpectedResponseWithDeserializedResponse:dictionary]; + } + return NO; + } + + _approximateExpirationDate = [NSDate dateWithTimeIntervalSinceNow:[expiresIn doubleValue]]; + return YES; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRSendVerificationCodeRequest.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRSendVerificationCodeRequest.h new file mode 100644 index 0000000..af6cc93 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRSendVerificationCodeRequest.h @@ -0,0 +1,67 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRIdentityToolkitRequest.h" + +#import "FIRAuthRPCRequest.h" +#import "FIRIdentityToolkitRequest.h" + +@class FIRAuthAppCredential; + +NS_ASSUME_NONNULL_BEGIN + +@interface FIRSendVerificationCodeRequest : FIRIdentityToolkitRequest + +/** @property phoneNumber + @brief The phone number to which the verification code should be sent. + */ +@property(nonatomic, strong, readonly) NSString *phoneNumber; + +/** @property appCredential + @brief The credential to prove the identity of the app in order to send the verification code. + */ +@property(nonatomic, strong, readonly, nullable) FIRAuthAppCredential *appCredential; + +/** @property reCAPTCHAToken + @brief The reCAPTCHA token to prove the identity of the app in order to send the verification + code. + */ +@property(nonatomic, strong, readonly, nullable) NSString *reCAPTCHAToken; + +/** @fn initWithEndpoint:requestConfiguration: + @brief Please use initWithPhoneNumber:appCredentials:requestConfiguration: instead. + */ +- (nullable instancetype)initWithEndpoint:(NSString *)endpoint + requestConfiguration:(FIRAuthRequestConfiguration *)requestConfiguration + NS_UNAVAILABLE; + +/** @fn initWithPhoneNumber:appCredentials:requestConfiguration: + @brief Designated initializer. + @param phoneNumber The phone number to which the verification code is to be sent. + @param appCredential The credential that proves the identity of the app. + @param reCAPTCHAToken The reCAPTCHA token that proves the identity of the app. + @param requestConfiguration An object containing configurations to be added to the request. + */ +- (nullable instancetype)initWithPhoneNumber:(NSString *)phoneNumber + appCredential:(nullable FIRAuthAppCredential *)appCredential + reCAPTCHAToken:(nullable NSString *)reCAPTCHAToken + requestConfiguration:(FIRAuthRequestConfiguration *)requestConfiguration + NS_DESIGNATED_INITIALIZER; + + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRSendVerificationCodeRequest.m b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRSendVerificationCodeRequest.m new file mode 100644 index 0000000..38ad8cf --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRSendVerificationCodeRequest.m @@ -0,0 +1,84 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRSendVerificationCodeRequest.h" + +#import "FIRAuthAppCredential.h" + +NS_ASSUME_NONNULL_BEGIN + +/** @var kSendVerificationCodeEndPoint + @brief The "sendVerificationCodeEnd" endpoint. + */ +static NSString *const kSendVerificationCodeEndPoint = @"sendVerificationCode"; + +/** @var kPhoneNumberKey + @brief The key for the Phone Number parameter in the request. + */ +static NSString *const kPhoneNumberKey = @"phoneNumber"; + +/** @var kReceiptKey + @brief The key for the receipt parameter in the request. + */ +static NSString *const kReceiptKey = @"iosReceipt"; + +/** @var kSecretKey + @brief The key for the Secret parameter in the request. + */ +static NSString *const kSecretKey = @"iosSecret"; + +/** @var kreCAPTCHATokenKey + @brief The key for the reCAPTCHAToken parameter in the request. + */ +static NSString *const kreCAPTCHATokenKey = @"recaptchaToken"; + +@implementation FIRSendVerificationCodeRequest { +} + +- (nullable instancetype)initWithPhoneNumber:(NSString *)phoneNumber + appCredential:(nullable FIRAuthAppCredential *)appCredential + reCAPTCHAToken:(nullable NSString *)reCAPTCHAToken + requestConfiguration:(FIRAuthRequestConfiguration *)requestConfiguration { + self = [super initWithEndpoint:kSendVerificationCodeEndPoint + requestConfiguration:requestConfiguration]; + if (self) { + _phoneNumber = [phoneNumber copy]; + _appCredential = appCredential; + _reCAPTCHAToken = [reCAPTCHAToken copy]; + } + return self; +} + +- (nullable id)unencodedHTTPRequestBodyWithError:(NSError *_Nullable *_Nullable)error { + NSMutableDictionary *postBody = [NSMutableDictionary dictionary]; + if (_phoneNumber) { + postBody[kPhoneNumberKey] = _phoneNumber; + } + if (_appCredential.receipt) { + postBody[kReceiptKey] = _appCredential.receipt; + } + if (_appCredential.secret) { + postBody[kSecretKey] = _appCredential.secret; + } + if (_reCAPTCHAToken) { + postBody[kreCAPTCHATokenKey] = _reCAPTCHAToken; + } + return postBody; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRSendVerificationCodeResponse.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRSendVerificationCodeResponse.h new file mode 100644 index 0000000..1a49ec2 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRSendVerificationCodeResponse.h @@ -0,0 +1,32 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +#import "FIRAuthRPCResponse.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface FIRSendVerificationCodeResponse : NSObject + +/** @property verificationID + @brief Encrypted session information returned by the backend. + */ +@property(nonatomic, readonly) NSString *verificationID; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRSendVerificationCodeResponse.m b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRSendVerificationCodeResponse.m new file mode 100644 index 0000000..9e47b6e --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRSendVerificationCodeResponse.m @@ -0,0 +1,36 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRSendVerificationCodeResponse.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation FIRSendVerificationCodeResponse + +// TODO: remove when resolving b/37169084 . +- (nullable NSString *)expectedKind { + return nil; +} + +- (BOOL)setWithDictionary:(NSDictionary *)dictionary + error:(NSError *_Nullable *_Nullable)error { + _verificationID = [dictionary[@"sessionInfo"] copy]; + return YES; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRSetAccountInfoRequest.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRSetAccountInfoRequest.h new file mode 100644 index 0000000..0e0e18f --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRSetAccountInfoRequest.h @@ -0,0 +1,151 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +#import "FIRAuthRPCRequest.h" +#import "FIRIdentityToolkitRequest.h" + +@class FIRGetAccountInfoResponse; + +NS_ASSUME_NONNULL_BEGIN + +/** @var FIRSetAccountInfoUserAttributeEmail + @brief Constant for email attribute used in "deleteAttributes". + */ +extern NSString *const FIRSetAccountInfoUserAttributeEmail; + +/** @var FIRSetAccountInfoUserAttributeDisplayName + @brief Constant for displayName attribute used in "deleteAttributes". + */ +extern NSString *const FIRSetAccountInfoUserAttributeDisplayName; + +/** @var FIRSetAccountInfoUserAttributeProvider + @brief Constant for provider attribute used in "deleteAttributes". + */ +extern NSString *const FIRSetAccountInfoUserAttributeProvider; + +/** @var FIRSetAccountInfoUserAttributePhotoURL + @brief Constant for photoURL attribute used in "deleteAttributes". + */ +extern NSString *const FIRSetAccountInfoUserAttributePhotoURL; + +/** @var FIRSetAccountInfoUserAttributePassword + @brief Constant for password attribute used in "deleteAttributes". + */ +extern NSString *const FIRSetAccountInfoUserAttributePassword; + +/** @class FIRSetAccountInfoRequest + @brief Represents the parameters for the setAccountInfo endpoint. + @see https://developers.google.com/identity/toolkit/web/reference/relyingparty/setAccountInfo + */ +@interface FIRSetAccountInfoRequest : FIRIdentityToolkitRequest + +/** @property accessToken + @brief The STS Access Token of the authenticated user. + */ +@property(nonatomic, copy, nullable) NSString *accessToken; + +/** @property displayName + @brief The name of the user. + */ +@property(nonatomic, copy, nullable) NSString *displayName; + +/** @property localID + @brief The local ID of the user. + */ +@property(nonatomic, copy, nullable) NSString *localID; + +/** @property email + @brief The email of the user. + */ +@property(nonatomic, copy, nullable) NSString *email; + +/** @property photoURL + @brief The photoURL of the user. + */ +@property(nonatomic, copy, nullable) NSURL *photoURL; + +/** @property password + @brief The new password of the user. + */ +@property(nonatomic, copy, nullable) NSString *password; + +/** @property providers + @brief The associated identity providers of the user. + */ +@property(nonatomic, copy, nullable) NSArray *providers; + +/** @property OOBCode + @brief The out-of-band code of the change email request. + */ +@property(nonatomic, copy, nullable) NSString *OOBCode; + +/** @property emailVerified + @brief Whether to mark the email as verified or not. + */ +@property(nonatomic, assign) BOOL emailVerified; + +/** @property upgradeToFederatedLogin + @brief Whether to mark the user to upgrade to federated login. + */ +@property(nonatomic, assign) BOOL upgradeToFederatedLogin; + +/** @property captchaChallenge + @brief The captcha challenge. + */ +@property(nonatomic, copy, nullable) NSString *captchaChallenge; + +/** @property captchaResponse + @brief Response to the captcha. + */ +@property(nonatomic, copy, nullable) NSString *captchaResponse; + +/** @property deleteAttributes + @brief The list of user attributes to delete. + @remarks Every element of the list must be one of the predefined constant starts with + "FIRSetAccountInfoUserAttribute". + */ +@property(nonatomic, copy, nullable) NSArray *deleteAttributes; + +/** @property deleteProviders + @brief The list of identity providers to delete. + */ +@property(nonatomic, copy, nullable) NSArray *deleteProviders; + +/** @property returnSecureToken + @brief Whether the response should return access token and refresh token directly. + @remarks The default value is @c YES . + */ +@property(nonatomic, assign) BOOL returnSecureToken; + +/** @fn initWithEndpoint:requestConfiguration: + @brief Please use initWithAPIKey:email:password:displayName:requestConfiguration instead. + */ +- (nullable instancetype)initWithEndpoint:(NSString *)endpoint + requestConfiguration:(FIRAuthRequestConfiguration *)requestConfiguration + NS_UNAVAILABLE; + +/** @fn initWithRequestConfiguration: + @brief Designated initializer. + @param requestConfiguration An object containing configurations to be added to the request. + */ +- (nullable instancetype)initWithRequestConfiguration: + (FIRAuthRequestConfiguration *)requestConfiguration NS_DESIGNATED_INITIALIZER; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRSetAccountInfoRequest.m b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRSetAccountInfoRequest.m new file mode 100644 index 0000000..ef06d2b --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRSetAccountInfoRequest.m @@ -0,0 +1,180 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRSetAccountInfoRequest.h" + +#import "FIRAuthErrorUtils.h" +#import "FIRAuth_Internal.h" +#import "FIRGetAccountInfoResponse.h" + +NS_ASSUME_NONNULL_BEGIN + +NSString *const FIRSetAccountInfoUserAttributeEmail = @"EMAIL"; + +NSString *const FIRSetAccountInfoUserAttributeDisplayName = @"DISPLAY_NAME"; + +NSString *const FIRSetAccountInfoUserAttributeProvider = @"PROVIDER"; + +NSString *const FIRSetAccountInfoUserAttributePhotoURL = @"PHOTO_URL"; + +NSString *const FIRSetAccountInfoUserAttributePassword = @"PASSWORD"; + +/** @var kCreateAuthURIEndpoint + @brief The "setAccountInfo" endpoint. + */ +static NSString *const kSetAccountInfoEndpoint = @"setAccountInfo"; + +/** @var kIDTokenKey + @brief The key for the "idToken" value in the request. This is actually the STS Access Token, + despite it's confusing (backwards compatiable) parameter name. + */ +static NSString *const kIDTokenKey = @"idToken"; + +/** @var kDisplayNameKey + @brief The key for the "displayName" value in the request. + */ +static NSString *const kDisplayNameKey = @"displayName"; + +/** @var kLocalIDKey + @brief The key for the "localID" value in the request. + */ +static NSString *const kLocalIDKey = @"localId"; + +/** @var kEmailKey + @brief The key for the "email" value in the request. + */ +static NSString *const kEmailKey = @"email"; + +/** @var kPasswordKey + @brief The key for the "password" value in the request. + */ +static NSString *const kPasswordKey = @"password"; + +/** @var kPhotoURLKey + @brief The key for the "photoURL" value in the request. + */ +static NSString *const kPhotoURLKey = @"photoUrl"; + +/** @var kProvidersKey + @brief The key for the "providers" value in the request. + */ +static NSString *const kProvidersKey = @"provider"; + +/** @var kOOBCodeKey + @brief The key for the "OOBCode" value in the request. + */ +static NSString *const kOOBCodeKey = @"oobCode"; + +/** @var kEmailVerifiedKey + @brief The key for the "emailVerified" value in the request. + */ +static NSString *const kEmailVerifiedKey = @"emailVerified"; + +/** @var kUpgradeToFederatedLoginKey + @brief The key for the "upgradeToFederatedLogin" value in the request. + */ +static NSString *const kUpgradeToFederatedLoginKey = @"upgradeToFederatedLogin"; + +/** @var kCaptchaChallengeKey + @brief The key for the "captchaChallenge" value in the request. + */ +static NSString *const kCaptchaChallengeKey = @"captchaChallenge"; + +/** @var kCaptchaResponseKey + @brief The key for the "captchaResponse" value in the request. + */ +static NSString *const kCaptchaResponseKey = @"captchaResponse"; + +/** @var kDeleteAttributesKey + @brief The key for the "deleteAttribute" value in the request. + */ +static NSString *const kDeleteAttributesKey = @"deleteAttribute"; + +/** @var kDeleteProvidersKey + @brief The key for the "deleteProvider" value in the request. + */ +static NSString *const kDeleteProvidersKey = @"deleteProvider"; + +/** @var kReturnSecureTokenKey + @brief The key for the "returnSecureToken" value in the request. + */ +static NSString *const kReturnSecureTokenKey = @"returnSecureToken"; + +@implementation FIRSetAccountInfoRequest + +- (nullable instancetype)initWithRequestConfiguration: + (FIRAuthRequestConfiguration *)requestConfiguration { + self = [super initWithEndpoint:kSetAccountInfoEndpoint requestConfiguration:requestConfiguration]; + if (self) { + _returnSecureToken = YES; + } + return self; +} + +- (nullable id)unencodedHTTPRequestBodyWithError:(NSError *_Nullable *_Nullable)error { + NSMutableDictionary *postBody = [NSMutableDictionary dictionary]; + if (_accessToken) { + postBody[kIDTokenKey] = _accessToken; + } + if (_displayName) { + postBody[kDisplayNameKey] = _displayName; + } + if (_localID) { + postBody[kLocalIDKey] = _localID; + } + if (_email) { + postBody[kEmailKey] = _email; + } + if (_password) { + postBody[kPasswordKey] = _password; + } + if (_photoURL) { + postBody[kPhotoURLKey] = _photoURL.absoluteString; + } + if (_providers) { + postBody[kProvidersKey] = _providers; + } + if (_OOBCode) { + postBody[kOOBCodeKey] = _OOBCode; + } + if (_emailVerified) { + postBody[kEmailVerifiedKey] = @YES; + } + if (_upgradeToFederatedLogin) { + postBody[kUpgradeToFederatedLoginKey] = @YES; + } + if (_captchaChallenge) { + postBody[kCaptchaChallengeKey] = _captchaChallenge; + } + if (_captchaResponse) { + postBody[kCaptchaResponseKey] = _captchaResponse; + } + if (_deleteAttributes) { + postBody[kDeleteAttributesKey] = _deleteAttributes; + } + if (_deleteProviders) { + postBody[kDeleteProvidersKey] = _deleteProviders; + } + if (_returnSecureToken) { + postBody[kReturnSecureTokenKey] = @YES; + } + return postBody; +} + +@end + +NS_ASSUME_NONNULL_END + diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRSetAccountInfoResponse.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRSetAccountInfoResponse.h new file mode 100644 index 0000000..92895c0 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRSetAccountInfoResponse.h @@ -0,0 +1,98 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +#import "FIRAuthRPCResponse.h" + +NS_ASSUME_NONNULL_BEGIN + +/** @class FIRSetAccountInfoResponseProviderUserInfo + @brief Represents the provider user info part of the response from the setAccountInfo endpoint. + @see https://developers.google.com/identity/toolkit/web/reference/relyingparty/setAccountInfo + */ +@interface FIRSetAccountInfoResponseProviderUserInfo : NSObject + +/** @property providerID + @brief The ID of the identity provider. + */ +@property(nonatomic, strong, readonly, nullable) NSString *providerID; + +/** @property displayName + @brief The user's display name at the identity provider. + */ +@property(nonatomic, strong, readonly, nullable) NSString *displayName; + +/** @property photoURL + @brief The user's photo URL at the identity provider. + */ +@property(nonatomic, strong, readonly, nullable) NSURL *photoURL; + +/** @fn init + @brief Please use initWithDictionary: + */ +- (instancetype)init NS_UNAVAILABLE; + +/** @fn initWithAPIKey: + @brief Designated initializer. + @param dictionary The provider user info data from endpoint. + */ +- (instancetype)initWithDictionary:(NSDictionary *)dictionary NS_DESIGNATED_INITIALIZER; + +@end + +/** @class FIRSetAccountInfoResponse + @brief Represents the response from the setAccountInfo endpoint. + @see https://developers.google.com/identity/toolkit/web/reference/relyingparty/setAccountInfo + */ +@interface FIRSetAccountInfoResponse : NSObject + +/** @property email + @brief The email or the user. + */ +@property(nonatomic, strong, readonly, nullable) NSString *email; + +/** @property displayName + @brief The display name of the user. + */ +@property(nonatomic, strong, readonly, nullable) NSString *displayName; + +/** @property providerUserInfo + @brief The user's profiles at the associated identity providers. + */ +@property(nonatomic, strong, readonly, nullable) + NSArray *providerUserInfo; + +/** @property IDToken + @brief Either an authorization code suitable for performing an STS token exchange, or the + access token from Secure Token Service, depending on whether @c returnSecureToken is set + on the request. + */ +@property(nonatomic, strong, readonly, nullable) NSString *IDToken; + +/** @property approximateExpirationDate + @brief The approximate expiration date of the access token. + */ +@property(nonatomic, copy, readonly, nullable) NSDate *approximateExpirationDate; + +/** @property refreshToken + @brief The refresh token from Secure Token Service. + */ +@property(nonatomic, strong, readonly, nullable) NSString *refreshToken; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRSetAccountInfoResponse.m b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRSetAccountInfoResponse.m new file mode 100644 index 0000000..7054a44 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRSetAccountInfoResponse.m @@ -0,0 +1,63 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRSetAccountInfoResponse.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation FIRSetAccountInfoResponseProviderUserInfo + +- (instancetype)initWithDictionary:(NSDictionary *)dictionary { + self = [super init]; + if (self) { + _providerID = [dictionary[@"providerId"] copy]; + _displayName = [dictionary[@"displayName"] copy]; + NSString *photoURL = dictionary[@"photoUrl"]; + if (photoURL) { + _photoURL = [NSURL URLWithString:photoURL]; + } + } + return self; +} + +@end + +@implementation FIRSetAccountInfoResponse + +- (BOOL)setWithDictionary:(NSDictionary *)dictionary + error:(NSError *_Nullable *_Nullable)error { + _email = [dictionary[@"email"] copy]; + _displayName = [dictionary[@"displayName"] copy]; + _IDToken = [dictionary[@"idToken"] copy]; + _approximateExpirationDate = [dictionary[@"expiresIn"] isKindOfClass:[NSString class]] ? + [NSDate dateWithTimeIntervalSinceNow:[dictionary[@"expiresIn"] doubleValue]] : nil; + _refreshToken = [dictionary[@"refreshToken"] copy]; + NSArray *providerUserInfoData = dictionary[@"providerUserInfo"]; + if (providerUserInfoData) { + NSMutableArray *providerUserInfoArray = + [NSMutableArray arrayWithCapacity:providerUserInfoData.count]; + for (NSDictionary *dictionary in providerUserInfoData) { + [providerUserInfoArray addObject: + [[FIRSetAccountInfoResponseProviderUserInfo alloc] initWithDictionary:dictionary]]; + } + _providerUserInfo = [providerUserInfoArray copy]; + } + return YES; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRSignInWithGameCenterRequest.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRSignInWithGameCenterRequest.h new file mode 100644 index 0000000..52720cb --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRSignInWithGameCenterRequest.h @@ -0,0 +1,91 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#import + +#import "FIRAuthRPCRequest.h" +#import "FIRIdentityToolkitRequest.h" + +NS_ASSUME_NONNULL_BEGIN + +/** @class FIRSignInWithGameCenterRequest + @brief The request to sign in with Game Center account + */ +@interface FIRSignInWithGameCenterRequest : FIRIdentityToolkitRequest + +/** @property playerID + @brief The playerID to verify. + */ +@property(nonatomic, copy) NSString *playerID; + +/** @property publicKeyURL + @brief The URL for the public encryption key. + */ +@property(nonatomic, copy) NSURL *publicKeyURL; + +/** @property signature + @brief The verification signature data generated by Game Center. + */ +@property(nonatomic, copy) NSData *signature; + +/** @property salt + @brief A random strong used to compute the hash and keep it randomized. + */ +@property(nonatomic, copy) NSData *salt; + +/** @property timestamp + @brief The date and time that the signature was created. + */ +@property(nonatomic, assign) uint64_t timestamp; + +/** @property accessToken + @brief The STS Access Token for the authenticated user, only needed for linking the user. + */ +@property(nonatomic, copy, nullable) NSString *accessToken; + +/** @property displayName + @brief The display name of the local Game Center player. + */ +@property(nonatomic, copy, nullable) NSString *displayName; + +/** @fn initWithEndpoint:requestConfiguration: + @brief Please use initWithPlayerID:publicKeyURL:signature:salt:timestamp:requestConfiguration:. + */ +- (nullable instancetype)initWithEndpoint:(NSString *)endpoint + requestConfiguration:(FIRAuthRequestConfiguration *)requestConfiguration + NS_UNAVAILABLE; + +/** @fn initWithPlayerID:publicKeyURL:signature:salt:timestamp:displayName:requestConfiguration: + @brief Designated initializer. + @param playerID The ID of the Game Center player. + @param publicKeyURL The URL for the public encryption key. + @param signature The verification signature generated. + @param salt A random string used to compute the hash and keep it randomized. + @param timestamp The date and time that the signature was created. + @param displayName The display name of the Game Center player. + */ +- (nullable instancetype)initWithPlayerID:(NSString *)playerID + publicKeyURL:(NSURL *)publicKeyURL + signature:(NSData *)signature + salt:(NSData *)salt + timestamp:(uint64_t)timestamp + displayName:(NSString *)displayName + requestConfiguration:(FIRAuthRequestConfiguration *)requestConfiguration + NS_DESIGNATED_INITIALIZER; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRSignInWithGameCenterRequest.m b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRSignInWithGameCenterRequest.m new file mode 100644 index 0000000..35fb754 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRSignInWithGameCenterRequest.m @@ -0,0 +1,80 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#import "FIRSignInWithGameCenterRequest.h" + +#import "NSData+FIRBase64.h" + +NS_ASSUME_NONNULL_BEGIN + +/** @var kSignInWithGameCenterEndPoint + @brief The "SignInWithGameCenter" endpoint. + */ +static NSString *const kSignInWithGameCenterEndPoint = @"signInWithGameCenter"; + +@implementation FIRSignInWithGameCenterRequest + +- (nullable instancetype)initWithPlayerID:(NSString *)playerID + publicKeyURL:(NSURL *)publicKeyURL + signature:(NSData *)signature + salt:(NSData *)salt + timestamp:(uint64_t)timestamp + displayName:(NSString *)displayName + requestConfiguration:(FIRAuthRequestConfiguration *)requestConfiguration { + self = [super initWithEndpoint:kSignInWithGameCenterEndPoint + requestConfiguration:requestConfiguration]; + if (self) { + _playerID = playerID; + _publicKeyURL = [publicKeyURL copy]; + _signature = [signature copy]; + _salt = [salt copy]; + _timestamp = timestamp; + _displayName = displayName; + } + return self; +} + +#pragma mark - FIRAuthRPCRequest + +- (nullable id)unencodedHTTPRequestBodyWithError:(NSError *__autoreleasing _Nullable *)error { + NSMutableDictionary *postBody = [NSMutableDictionary dictionary]; + if (_playerID) { + postBody[@"playerId"] = _playerID; + } + if (_publicKeyURL) { + postBody[@"publicKeyUrl"] = _publicKeyURL.absoluteString; + } + if (_signature) { + postBody[@"signature"] = [_signature fir_base64URLEncodedStringWithOptions:0]; + } + if (_salt) { + postBody[@"salt"] = [_salt fir_base64URLEncodedStringWithOptions:0]; + } + if (_timestamp != 0) { + postBody[@"timestamp"] = [NSNumber numberWithUnsignedLongLong:_timestamp]; + } + if (_accessToken) { + postBody[@"idToken"] = _accessToken; + } + if (_displayName) { + postBody[@"displayName"] = _displayName; + } + return postBody; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRSignInWithGameCenterResponse.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRSignInWithGameCenterResponse.h new file mode 100644 index 0000000..75dbd75 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRSignInWithGameCenterResponse.h @@ -0,0 +1,64 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#import + +#import "FIRAuthRPCResponse.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface FIRSignInWithGameCenterResponse : NSObject + +/** @property IDToken + @breif Either an authorization code suitable for performing an STS token exchange, or the access + token from Secure Token Service, depending on whether @c returnSecureToken is set on the + request. + */ +@property(nonatomic, copy, readonly, nullable) NSString *IDToken; + +/** @property refreshToken + @breif @breif The refresh token from Secure Token Service. + */ +@property(nonatomic, copy, readonly, nullable) NSString *refreshToken; + +/** @property localID + @breif @breif The Firebase Auth user ID. + */ +@property(nonatomic, copy, readonly, nullable) NSString *localID; + +/** @property playerID + @breif @breif The verified player ID. + */ +@property(nonatomic, copy, readonly, nullable) NSString *playerID; + +/** @property approximateExpirationDate + @breif The approximate expiration date of the access token. + */ +@property(nonatomic, copy, readonly, nullable) NSDate *approximateExpirationDate; + +/** @property isNewUser + @breif Flag indicating that the user signing in is a new user and not a returning user. + */ +@property(nonatomic, assign) BOOL isNewUser; + +/** @property displayName + @breif The user's Game Center display name. + */ +@property(nonatomic, copy, readonly, nullable) NSString *displayName; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRSignInWithGameCenterResponse.m b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRSignInWithGameCenterResponse.m new file mode 100644 index 0000000..7cd1b9a --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRSignInWithGameCenterResponse.m @@ -0,0 +1,40 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#import "FIRSignInWithGameCenterResponse.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation FIRSignInWithGameCenterResponse + +- (BOOL)setWithDictionary:(NSDictionary *)dictionary + error:(NSError *_Nullable *_Nullable)error { + _IDToken = [dictionary[@"idToken"] copy]; + _refreshToken = [dictionary[@"refreshToken"] copy]; + _localID = [dictionary[@"localId"] copy]; + _approximateExpirationDate = nil; + if ([dictionary[@"expiresIn"] isKindOfClass:[NSString class]]) { + _approximateExpirationDate = [NSDate dateWithTimeIntervalSinceNow:[dictionary[@"expiresIn"] integerValue]]; + } + _playerID = [dictionary[@"playerId"] copy]; + _isNewUser = [dictionary[@"isNewUser"] boolValue]; + _displayName = [dictionary[@"displayName"] copy]; + return YES; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRSignUpNewUserRequest.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRSignUpNewUserRequest.h new file mode 100644 index 0000000..06d2cfe --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRSignUpNewUserRequest.h @@ -0,0 +1,72 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +#import "FIRAuthRPCRequest.h" +#import "FIRIdentityToolkitRequest.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface FIRSignUpNewUserRequest : FIRIdentityToolkitRequest + +/** @property email + @brief The email of the user. + */ +@property(nonatomic, copy, nullable) NSString *email; + +/** @property password + @brief The password inputed by the user. + */ +@property(nonatomic, copy, nullable) NSString *password; + +/** @property displayName + @brief The password inputed by the user. + */ +@property(nonatomic, copy, nullable) NSString *displayName; + +/** @property returnSecureToken + @brief Whether the response should return access token and refresh token directly. + @remarks The default value is @c YES . + */ +@property(nonatomic, assign) BOOL returnSecureToken; + +/** @fn initWithEndpoint:requestConfiguration: + @brief Please use initWithAPIKey:email:password:displayName:requestConfiguration instead. + */ +- (nullable instancetype)initWithEndpoint:(NSString *)endpoint + requestConfiguration:(FIRAuthRequestConfiguration *)requestConfiguration + NS_UNAVAILABLE; + +/** @fn initWithEndpoint:requestConfiguration: + @brief initializer for anonymous sign-in. + */ +- (nullable instancetype)initWithRequestConfiguration: + (FIRAuthRequestConfiguration *)requestConfiguration; + +/** @fn initWithAPIKey:email:password:displayName:requestConfiguration + @brief Designated initializer. + @param requestConfiguration An object containing configurations to be added to the request. + */ +- (nullable instancetype)initWithEmail:(nullable NSString *)email + password:(nullable NSString *)password + displayName:(nullable NSString *)displayName + requestConfiguration:(FIRAuthRequestConfiguration *)requestConfiguration + NS_DESIGNATED_INITIALIZER; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRSignUpNewUserRequest.m b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRSignUpNewUserRequest.m new file mode 100644 index 0000000..5d50e0a --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRSignUpNewUserRequest.m @@ -0,0 +1,90 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRSignUpNewUserRequest.h" + +NS_ASSUME_NONNULL_BEGIN + +/** @var kSignupNewUserEndpoint + @brief The "SingupNewUserEndpoint" endpoint. + */ +static NSString *const kSignupNewUserEndpoint = @"signupNewUser"; + +/** @var kEmailKey + @brief The key for the "email" value in the request. + */ +static NSString *const kEmailKey = @"email"; + +/** @var kPasswordKey + @brief The key for the "password" value in the request. + */ +static NSString *const kPasswordKey = @"password"; + +/** @var kDisplayNameKey + @brief The key for the "kDisplayName" value in the request. + */ +static NSString *const kDisplayNameKey = @"displayName"; + +/** @var kReturnSecureTokenKey + @brief The key for the "returnSecureToken" value in the request. + */ +static NSString *const kReturnSecureTokenKey = @"returnSecureToken"; + +@implementation FIRSignUpNewUserRequest + +- (nullable instancetype)initWithEmail:(nullable NSString *)email + password:(nullable NSString *)password + displayName:(nullable NSString *)displayName + requestConfiguration:(FIRAuthRequestConfiguration *)requestConfiguration { + self = [super initWithEndpoint:kSignupNewUserEndpoint requestConfiguration:requestConfiguration]; + if (self) { + _email = [email copy]; + _password = [password copy]; + _displayName = [displayName copy]; + _returnSecureToken = YES; + } + return self; +} + +- (nullable instancetype)initWithRequestConfiguration: + (FIRAuthRequestConfiguration *)requestConfiguration { + self = [self initWithEmail:nil + password:nil + displayName:nil + requestConfiguration:requestConfiguration]; + return self; +} + +- (nullable id)unencodedHTTPRequestBodyWithError:(NSError *_Nullable *_Nullable)error { + NSMutableDictionary *postBody = [NSMutableDictionary dictionary]; + if (_email) { + postBody[kEmailKey] = _email; + } + if (_password) { + postBody[kPasswordKey] = _password; + } + if (_displayName) { + postBody[kDisplayNameKey] = _displayName; + } + if (_returnSecureToken) { + postBody[kReturnSecureTokenKey] = @YES; + } + return postBody; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRSignUpNewUserResponse.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRSignUpNewUserResponse.h new file mode 100644 index 0000000..0d55939 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRSignUpNewUserResponse.h @@ -0,0 +1,44 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +#import "FIRAuthRPCResponse.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface FIRSignUpNewUserResponse : NSObject + +/** @property IDToken + @brief Either an authorization code suitable for performing an STS token exchange, or the + access token from Secure Token Service, depending on whether @c returnSecureToken is set + on the request. + */ +@property(nonatomic, strong, readonly, nullable) NSString *IDToken; + +/** @property approximateExpirationDate + @brief The approximate expiration date of the access token. + */ +@property(nonatomic, copy, readonly, nullable) NSDate *approximateExpirationDate; + +/** @property refreshToken + @brief The refresh token from Secure Token Service. + */ +@property(nonatomic, strong, readonly, nullable) NSString *refreshToken; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRSignUpNewUserResponse.m b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRSignUpNewUserResponse.m new file mode 100644 index 0000000..03d0616 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRSignUpNewUserResponse.m @@ -0,0 +1,34 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRSignUpNewUserResponse.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation FIRSignUpNewUserResponse + +- (BOOL)setWithDictionary:(NSDictionary *)dictionary + error:(NSError *_Nullable *_Nullable)error { + _IDToken = [dictionary[@"idToken"] copy]; + _approximateExpirationDate = [dictionary[@"expiresIn"] isKindOfClass:[NSString class]] ? + [NSDate dateWithTimeIntervalSinceNow:[dictionary[@"expiresIn"] doubleValue]] : nil; + _refreshToken = [dictionary[@"refreshToken"] copy]; + return YES; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRVerifyAssertionRequest.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRVerifyAssertionRequest.h new file mode 100644 index 0000000..595ee9b --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRVerifyAssertionRequest.h @@ -0,0 +1,113 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +#import "FIRAuthRPCRequest.h" +#import "FIRIdentityToolkitRequest.h" + +NS_ASSUME_NONNULL_BEGIN + +/** @class FIRVerifyAssertionRequest + @brief Represents the parameters for the verifyAssertion endpoint. + @see https://developers.google.com/identity/toolkit/web/reference/relyingparty/verifyAssertion + */ +@interface FIRVerifyAssertionRequest : FIRIdentityToolkitRequest + +/** @property requestURI + @brief The URI to which the IDP redirects the user back. It may contain federated login result + params added by the IDP. + */ +@property(nonatomic, copy, nullable) NSString *requestURI; + +/** @property pendingToken + @brief The Firebase ID Token for the IDP pending to be confirmed by the user. + */ +@property(nonatomic, copy, nullable) NSString *pendingToken; + +/** @property accessToken + @brief The STS Access Token for the authenticated user, only needed for linking the user. + */ +@property(nonatomic, copy, nullable) NSString *accessToken; + +/** @property returnSecureToken + @brief Whether the response should return access token and refresh token directly. + @remarks The default value is @c YES . + */ +@property(nonatomic, assign) BOOL returnSecureToken; + +#pragma mark - Components of "postBody" + +/** @property providerID + @brief The ID of the IDP whose credentials are being presented to the endpoint. + */ +@property(nonatomic, copy, readonly) NSString *providerID; + +/** @property providerAccessToken + @brief An access token from the IDP. + */ +@property(nonatomic, copy, nullable) NSString *providerAccessToken; + +/** @property providerIDToken + @brief An ID Token from the IDP. + */ +@property(nonatomic, copy, nullable) NSString *providerIDToken; + +/** @property returnIDPCredential + @brief Whether the response should return the IDP credential directly. + */ +@property(nonatomic, assign) BOOL returnIDPCredential; + +/** @property providerOAuthTokenSecret + @brief A session ID used to map this request to a headful-lite flow. + */ +@property(nonatomic, copy, nullable) NSString *sessionID; + +/** @property providerOAuthTokenSecret + @brief An OAuth client secret from the IDP. + */ +@property(nonatomic, copy, nullable) NSString *providerOAuthTokenSecret; + +/** @property inputEmail + @brief The originally entered email in the UI. + */ +@property(nonatomic, copy, nullable) NSString *inputEmail; + +/** @property autoCreate + @brief A flag that indicates whether or not the user should be automatically created. + */ +@property(nonatomic, assign) BOOL autoCreate; + +/** @fn initWithEndpoint:requestConfiguration: + @brief Please use initWithProviderID:requestConfifuration instead. + */ +- (nullable instancetype)initWithEndpoint:(NSString *)endpoint + requestConfiguration:(FIRAuthRequestConfiguration *)requestConfiguration + NS_UNAVAILABLE; + +/** @fn initWithProviderID:requestConfifuration + @brief Designated initializer. + @param providerID The auth provider's ID. + @param requestConfiguration An object containing configurations to be added to the request. + + */ +- (nullable instancetype)initWithProviderID:(NSString *)providerID + requestConfiguration:(FIRAuthRequestConfiguration *)requestConfiguration + NS_DESIGNATED_INITIALIZER; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRVerifyAssertionRequest.m b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRVerifyAssertionRequest.m new file mode 100644 index 0000000..3a819d7 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRVerifyAssertionRequest.m @@ -0,0 +1,168 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRVerifyAssertionRequest.h" + +NS_ASSUME_NONNULL_BEGIN + +/** @var kVerifyAssertionEndpoint + @brief The "verifyAssertion" endpoint. + */ +static NSString *const kVerifyAssertionEndpoint = @"verifyAssertion"; + +/** @var kProviderIDKey + @brief The key for the "providerId" value in the request. + */ +static NSString *const kProviderIDKey = @"providerId"; + +/** @var kProviderIDTokenKey + @brief The key for the "id_token" value in the request. + */ +static NSString *const kProviderIDTokenKey = @"id_token"; + +/** @var kProviderAccessTokenKey + @brief The key for the "access_token" value in the request. + */ +static NSString *const kProviderAccessTokenKey = @"access_token"; + +/** @var kProviderOAuthTokenSecretKey + @brief The key for the "oauth_token_secret" value in the request. + */ +static NSString *const kProviderOAuthTokenSecretKey = @"oauth_token_secret"; + +/** @var kIdentifierKey + @brief The key for the "identifier" value in the request. + */ +static NSString *const kIdentifierKey = @"identifier"; + +/** @var kRequestURIKey + @brief The key for the "requestUri" value in the request. + */ +static NSString *const kRequestURIKey = @"requestUri"; + +/** @var kPostBodyKey + @brief The key for the "postBody" value in the request. + */ +static NSString *const kPostBodyKey = @"postBody"; + +/** @var kPendingTokenKey + @brief The key for the "pendingToken" value in the request. + */ +static NSString *const kPendingTokenKey = @"pendingToken"; + +/** @var kAutoCreateKey + @brief The key for the "autoCreate" value in the request. + */ +static NSString *const kAutoCreateKey = @"autoCreate"; + +/** @var kIDTokenKey + @brief The key for the "idToken" value in the request. This is actually the STS Access Token, + despite it's confusing (backwards compatiable) parameter name. + */ +static NSString *const kIDTokenKey = @"idToken"; + +/** @var kReturnSecureTokenKey + @brief The key for the "returnSecureToken" value in the request. + */ +static NSString *const kReturnSecureTokenKey = @"returnSecureToken"; + +/** @var kReturnIDPCredentialKey + @brief The key for the "returnIdpCredential" value in the request. + */ +static NSString *const kReturnIDPCredentialKey = @"returnIdpCredential"; + +/** @var kSessionIDKey + @brief The key for the "sessionID" value in the request. + */ +static NSString *const kSessionIDKey = @"sessionId"; + +@implementation FIRVerifyAssertionRequest + +- (nullable instancetype)initWithProviderID:(NSString *)providerID + requestConfiguration:(FIRAuthRequestConfiguration *)requestConfiguration { + self = [super initWithEndpoint:kVerifyAssertionEndpoint + requestConfiguration:requestConfiguration]; + if (self) { + _providerID = providerID; + _returnSecureToken = YES; + _autoCreate = YES; + _returnIDPCredential = YES; + } + return self; +} + +- (nullable id)unencodedHTTPRequestBodyWithError:(NSError *_Nullable *_Nullable)error { + NSURLComponents *components = [[NSURLComponents alloc] init]; + NSMutableArray *queryItems = [@[[NSURLQueryItem queryItemWithName:kProviderIDKey + value:_providerID]] + mutableCopy]; + + if (_providerIDToken) { + [queryItems addObject:[NSURLQueryItem queryItemWithName:kProviderIDTokenKey + value:_providerIDToken]]; + } + + if (_providerAccessToken) { + [queryItems addObject:[NSURLQueryItem queryItemWithName:kProviderAccessTokenKey + value:_providerAccessToken]]; + } + + if (!_providerIDToken && !_providerAccessToken && !_pendingToken && !_requestURI) { + [NSException raise:NSInvalidArgumentException + format:@"One of IDToken, accessToken, pendingToken, or requestURI must be supplied."]; + } + + if (_providerOAuthTokenSecret) { + [queryItems addObject:[NSURLQueryItem queryItemWithName:kProviderOAuthTokenSecretKey + value:_providerOAuthTokenSecret]]; + } + + if (_inputEmail) { + [queryItems addObject:[NSURLQueryItem queryItemWithName:kIdentifierKey + value:_inputEmail]]; + } + [components setQueryItems:queryItems]; + NSMutableDictionary *body = [@{ + kRequestURIKey : _requestURI ?: @"http://localhost", // Unused by server, but required + kPostBodyKey : [components query] + } mutableCopy]; + + if (_pendingToken) { + body[kPendingTokenKey] = _pendingToken; + } + if (_accessToken) { + body[kIDTokenKey] = _accessToken; + } + if (_returnSecureToken) { + body[kReturnSecureTokenKey] = @YES; + } + + if (_returnIDPCredential) { + body[kReturnIDPCredentialKey] = @YES; + } + + if (_sessionID) { + body[kSessionIDKey] = _sessionID; + } + + body[kAutoCreateKey] = @(_autoCreate); + + return body; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRVerifyAssertionResponse.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRVerifyAssertionResponse.h new file mode 100644 index 0000000..a75d0a2 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRVerifyAssertionResponse.h @@ -0,0 +1,206 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +#import "FIRAuthRPCResponse.h" + +NS_ASSUME_NONNULL_BEGIN + +/** @class FIRVerifyAssertionResponse + @brief Represents the response from the verifyAssertion endpoint. + @see https://developers.google.com/identity/toolkit/web/reference/relyingparty/verifyAssertion + */ +@interface FIRVerifyAssertionResponse : NSObject + +/** @property federatedID + @brief The unique ID identifies the IdP account. + */ +@property(nonatomic, strong, readonly, nullable) NSString *federatedID; + +/** @property providerID + @brief The IdP ID. For white listed IdPs it's a short domain name e.g. google.com, aol.com, + live.net and yahoo.com. If the "providerId" param is set to OpenID OP identifer other than + the whilte listed IdPs the OP identifier is returned. If the "identifier" param is federated + ID in the createAuthUri request. The domain part of the federated ID is returned. + */ +@property(nonatomic, strong, readonly, nullable) NSString *providerID; + +/** @property localID + @brief The RP local ID if it's already been mapped to the IdP account identified by the + federated ID. + */ +@property(nonatomic, strong, readonly, nullable) NSString *localID; + +/** @property email + @brief The email returned by the IdP. NOTE: The federated login user may not own the email. + */ +@property(nonatomic, strong, readonly, nullable) NSString *email; + +/** @property inputEmail + @brief It's the identifier param in the createAuthUri request if the identifier is an email. It + can be used to check whether the user input email is different from the asserted email. + */ +@property(nonatomic, strong, readonly, nullable) NSString *inputEmail; + +/** @property originalEmail + @brief The original email stored in the mapping storage. It's returned when the federated ID is + associated to a different email. + */ +@property(nonatomic, strong, readonly, nullable) NSString *originalEmail; + +/** @property oauthRequestToken + @brief The user approved request token for the OpenID OAuth extension. + */ +@property(nonatomic, strong, readonly, nullable) NSString *oauthRequestToken; + +/** @property oauthScope + @brief The scope for the OpenID OAuth extension. + */ +@property(nonatomic, strong, readonly, nullable) NSString *oauthScope; + +/** @property firstName + @brief The first name of the user. + */ +@property(nonatomic, strong, readonly, nullable) NSString *firstName; + +/** @property lastName + @brief The last name of the user. + */ +@property(nonatomic, strong, readonly, nullable) NSString *lastName; + +/** @property fullName + @brief The full name of the user. + */ +@property(nonatomic, strong, readonly, nullable) NSString *fullName; + +/** @property nickName + @brief The nick name of the user. + */ +@property(nonatomic, strong, readonly, nullable) NSString *nickName; + +/** @property displayName + @brief The display name of the user. + */ +@property(nonatomic, strong, readonly, nullable) NSString *displayName; + +/** @property IDToken + @brief Either an authorization code suitable for performing an STS token exchange, or the + access token from Secure Token Service, depending on whether @c returnSecureToken is set + on the request. + */ +@property(nonatomic, strong, readonly, nullable) NSString *IDToken; + +/** @property approximateExpirationDate + @brief The approximate expiration date of the access token. + */ +@property(nonatomic, copy, readonly, nullable) NSDate *approximateExpirationDate; + +/** @property refreshToken + @brief The refresh token from Secure Token Service. + */ +@property(nonatomic, strong, readonly, nullable) NSString *refreshToken; + +/** @property action + @brief The action code. + */ +@property(nonatomic, strong, readonly, nullable) NSString *action; + +/** @property language + @brief The language preference of the user. + */ +@property(nonatomic, strong, readonly, nullable) NSString *language; + +/** @property timeZone + @brief The timezone of the user. + */ +@property(nonatomic, strong, readonly, nullable) NSString *timeZone; + +/** @property photoURL + @brief The URI of the public accessible profile picture. + */ +@property(nonatomic, strong, readonly, nullable) NSURL *photoURL; + +/** @property dateOfBirth + @brief The birth date of the IdP account. + */ +@property(nonatomic, strong, readonly, nullable) NSString *dateOfBirth; + +/** @property context + @brief The opaque value used by the client to maintain context info between the authentication + request and the IDP callback. + */ +@property(nonatomic, strong, readonly, nullable) NSString *context; + +/** @property verifiedProvider + @brief When action is 'map', contains the idps which can be used for confirmation. + */ +@property(nonatomic, strong, readonly, nullable) NSArray *verifiedProvider; + +/** @property needConfirmation + @brief Whether the assertion is from a non-trusted IDP and need account linking confirmation. + */ +@property(nonatomic, assign) BOOL needConfirmation; + +/** @property emailRecycled + @brief It's true if the email is recycled. + */ +@property(nonatomic, assign) BOOL emailRecycled; + +/** @property emailVerified + @brief The value is true if the IDP is also the email provider. It means the user owns the + email. + */ +@property(nonatomic, assign) BOOL emailVerified; + +/** @property isNewUser + @brief Flag indicating that the user signing in is a new user and not a returning user. + */ +@property(nonatomic, assign) BOOL isNewUser; + +/** @property profile + @brief Dictionary containing the additional IdP specific information. + */ +@property(nonatomic, readonly, nullable) NSDictionary *profile; + +/** @property username + @brief The name of the user. + */ +@property(nonatomic, strong, readonly, nullable) NSString *username; + +/** @property oauthIDToken + @brief The ID token for the OpenID OAuth extension. + */ +@property(nonatomic, strong, readonly, nullable) NSString *oauthIDToken; + +/** @property oauthExpirationDate + @brief The approximate expiration date of the oauth access token. + */ +@property(nonatomic, copy, readonly, nullable) NSDate *oauthExpirationDate; + +/** @property oauthAccessToken + @brief The access token for the OpenID OAuth extension. + */ +@property(nonatomic, strong, readonly, nullable) NSString *oauthAccessToken; + +/** @property pendingToken + @brief The pending ID Token string. + */ +@property(nonatomic, copy, nullable) NSString *pendingToken; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRVerifyAssertionResponse.m b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRVerifyAssertionResponse.m new file mode 100644 index 0000000..e479241 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRVerifyAssertionResponse.m @@ -0,0 +1,85 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRVerifyAssertionResponse.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation FIRVerifyAssertionResponse + +- (BOOL)setWithDictionary:(NSDictionary *)dictionary + error:(NSError *_Nullable *_Nullable)error { + _federatedID = [dictionary[@"federatedId"] copy]; + _providerID = [dictionary[@"providerId"] copy]; + _localID = [dictionary[@"localId"] copy]; + _emailRecycled = [dictionary[@"emailRecycled"] boolValue]; + _emailVerified = [dictionary[@"emailVerified"] boolValue]; + _email = [dictionary[@"email"] copy]; + _inputEmail = [dictionary[@"inputEmail"] copy]; + _originalEmail = [dictionary[@"originalEmail"] copy]; + _oauthRequestToken = [dictionary[@"oauthRequestToken"] copy]; + _oauthScope = [dictionary[@"oauthScope"] copy]; + _firstName = [dictionary[@"firstName"] copy]; + _lastName = [dictionary[@"lastName"] copy]; + _fullName = [dictionary[@"fullName"] copy]; + _nickName = [dictionary[@"nickName"] copy]; + _displayName = [dictionary[@"displayName"] copy]; + _IDToken = [dictionary[@"idToken"] copy]; + _approximateExpirationDate = [dictionary[@"expiresIn"] isKindOfClass:[NSString class]] ? + [NSDate dateWithTimeIntervalSinceNow:[dictionary[@"expiresIn"] doubleValue]] : nil; + _refreshToken = [dictionary[@"refreshToken"] copy]; + _isNewUser = [dictionary[@"isNewUser"] boolValue]; + id rawUserInfo = dictionary[@"rawUserInfo"]; + if ([rawUserInfo isKindOfClass:[NSString class]]) { + NSData *data = [rawUserInfo dataUsingEncoding:NSUTF8StringEncoding]; + rawUserInfo = [NSJSONSerialization JSONObjectWithData:data + options:NSJSONReadingMutableLeaves + error:nil]; + } + if ([rawUserInfo isKindOfClass:[NSDictionary class]]) { + _profile = [[NSDictionary alloc] initWithDictionary:rawUserInfo + copyItems:YES]; + } + _username = [dictionary[@"username"] copy]; + _action = [dictionary[@"action"] copy]; + _language = [dictionary[@"language"] copy]; + _timeZone = [dictionary[@"timeZone"] copy]; + _photoURL = dictionary[@"photoUrl"] ? [NSURL URLWithString:dictionary[@"photoUrl"]] : nil; + _dateOfBirth = [dictionary[@"dateOfBirth"] copy]; + _context = [dictionary[@"context"] copy]; + _needConfirmation = [dictionary[@"needConfirmation"] boolValue]; + id verifiedProvider = dictionary[@"verifiedProvider"]; + if ([verifiedProvider isKindOfClass:[NSString class]]) { + NSData *data = [verifiedProvider dataUsingEncoding:NSUTF8StringEncoding]; + verifiedProvider = [NSJSONSerialization JSONObjectWithData:data + options:NSJSONReadingMutableLeaves + error:nil]; + } + if ([verifiedProvider isKindOfClass:[NSArray class]]) { + _verifiedProvider = [[NSArray alloc] initWithArray:verifiedProvider + copyItems:YES]; + } + _oauthIDToken = [dictionary[@"oauthIdToken"] copy]; + _oauthExpirationDate = [dictionary[@"oauthExpireIn"] isKindOfClass:[NSString class]] ? + [NSDate dateWithTimeIntervalSinceNow:[dictionary[@"oauthExpireIn"] doubleValue]] : nil; + _oauthAccessToken = [dictionary[@"oauthAccessToken"] copy]; + _pendingToken = [dictionary[@"pendingToken"] copy]; + return YES; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRVerifyClientRequest.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRVerifyClientRequest.h new file mode 100644 index 0000000..a235788 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRVerifyClientRequest.h @@ -0,0 +1,56 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRIdentityToolkitRequest.h" + +#import "FIRAuthRPCRequest.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface FIRVerifyClientRequest : FIRIdentityToolkitRequest + +/** @property appToken + @brief The APNS device token. + */ +@property(nonatomic, readonly, nullable) NSString *appToken; + +/** @property isSandbox + @brief The flag that denotes if the appToken pertains to Sandbox or Production. + */ +@property(nonatomic, assign, readonly) BOOL isSandbox; + +/** @fn initWithEndpoint:requestConfiguration: + @brief Please use initWithToken:requestConfiguration: instead. + */ +- (nullable instancetype)initWithEndpoint:(NSString *)endpoint + requestConfiguration:(FIRAuthRequestConfiguration *)requestConfiguration + NS_UNAVAILABLE; + +/** @fn initWithAppToken:isSandbox:requestConfiguration: + @brief Designated initializer. + @param appToken The APNS device token. + @param isSandbox The flag indicating whether or not the app token provided is for Sandbox or + Production. + @param requestConfiguration An object containing configurations to be added to the request. + */ +- (nullable instancetype)initWithAppToken:(nullable NSString *)appToken + isSandbox:(BOOL)isSandbox + requestConfiguration:(FIRAuthRequestConfiguration *)requestConfiguration + NS_DESIGNATED_INITIALIZER; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRVerifyClientRequest.m b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRVerifyClientRequest.m new file mode 100644 index 0000000..101f4ef --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRVerifyClientRequest.m @@ -0,0 +1,63 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRVerifyClientRequest.h" + + +NS_ASSUME_NONNULL_BEGIN + +/** @var kVerifyClientEndpoint + @brief The endpoint for the verifyClient request. + */ +static NSString *const kVerifyClientEndpoint = @"verifyClient"; + +/** @var kAppTokenKey + @brief The key for the appToken request paramenter. + */ +static NSString *const kAPPTokenKey = @"appToken"; + +/** @var kIsSandboxKey + @brief The key for the isSandbox request parameter + */ +static NSString *const kIsSandboxKey = @"isSandbox"; + +@implementation FIRVerifyClientRequest + +- (nullable instancetype)initWithAppToken:(nullable NSString *)appToken + isSandbox:(BOOL)isSandbox + requestConfiguration:(FIRAuthRequestConfiguration *)requestConfiguration { + self = [super initWithEndpoint:kVerifyClientEndpoint requestConfiguration:requestConfiguration]; + if (self) { + _appToken = appToken; + _isSandbox = isSandbox; + } + return self; +} + +- (nullable id)unencodedHTTPRequestBodyWithError:(NSError *__autoreleasing _Nullable *)error { + NSMutableDictionary *postBody = [NSMutableDictionary dictionary]; + if (_appToken) { + postBody[kAPPTokenKey] = _appToken; + } + if (_isSandbox) { + postBody[kIsSandboxKey] = @YES; + } + return postBody; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRVerifyClientResponse.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRVerifyClientResponse.h new file mode 100644 index 0000000..794256a --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRVerifyClientResponse.h @@ -0,0 +1,38 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +#import "FIRAuthRPCResponse.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface FIRVerifyClientResponse : NSObject + +/** @property receipt + @brief Receipt that the APNS token was successfully validated with APNS. + */ +@property(nonatomic, copy, readonly, nullable) NSString *receipt; + +/** @property suggestedTimeOut + @brief The date after which delivery of the silent push notification is considered to have + failed. + */ +@property(nonatomic, copy, readonly, nullable) NSDate *suggestedTimeOutDate; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRVerifyClientResponse.m b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRVerifyClientResponse.m new file mode 100644 index 0000000..c2477d2 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRVerifyClientResponse.m @@ -0,0 +1,33 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRVerifyClientResponse.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation FIRVerifyClientResponse + +- (BOOL)setWithDictionary:(NSDictionary *)dictionary + error:(NSError *_Nullable *_Nullable)error { + _receipt = dictionary[@"receipt"]; + _suggestedTimeOutDate = [dictionary[@"suggestedTimeout"] isKindOfClass:[NSString class]] ? + [NSDate dateWithTimeIntervalSinceNow:[dictionary[@"suggestedTimeout"] doubleValue]] : nil; + return YES; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRVerifyCustomTokenRequest.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRVerifyCustomTokenRequest.h new file mode 100644 index 0000000..84bad05 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRVerifyCustomTokenRequest.h @@ -0,0 +1,57 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +#import "FIRAuthRPCRequest.h" +#import "FIRIdentityToolkitRequest.h" + +NS_ASSUME_NONNULL_BEGIN + +/** @class FIRVerifyCustomTokenRequest + @brief Represents the parameters for the verifyCustomToken endpoint. + */ +@interface FIRVerifyCustomTokenRequest : FIRIdentityToolkitRequest + +/** @property token + @brief The self-signed token from the client's BYOAuth server. + */ +@property(nonatomic, copy, readonly) NSString *token; + +/** @property returnSecureToken + @brief Whether the response should return access token and refresh token directly. + @remarks The default value is @c YES . + */ +@property(nonatomic, assign) BOOL returnSecureToken; + +/** @fn initWithEndpoint:requestConfiguration: + @brief Please use initWithToken:requestConfiguration: instead. + */ +- (nullable instancetype)initWithEndpoint:(NSString *)endpoint requestConfiguration: + (FIRAuthRequestConfiguration *)requestConfiguration NS_UNAVAILABLE; + +/** @fn initWithToken:requestConfiguration: + @brief Designated initializer. + @param token The self-signed token from the client's BYOAuth server. + @param requestConfiguration An object containing configurations to be added to the request. + */ +- (nullable instancetype)initWithToken:(NSString *)token + requestConfiguration:(FIRAuthRequestConfiguration *)requestConfiguration + NS_DESIGNATED_INITIALIZER; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRVerifyCustomTokenRequest.m b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRVerifyCustomTokenRequest.m new file mode 100644 index 0000000..9ad46a0 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRVerifyCustomTokenRequest.m @@ -0,0 +1,61 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRVerifyCustomTokenRequest.h" + +NS_ASSUME_NONNULL_BEGIN + +/** @var kVerifyCustomTokenEndpoint + @brief The "verifyPassword" endpoint. + */ +static NSString *const kVerifyCustomTokenEndpoint = @"verifyCustomToken"; + +/** @var kTokenKey + @brief The key for the "token" value in the request. + */ +static NSString *const kTokenKey = @"token"; + +/** @var kReturnSecureTokenKey + @brief The key for the "returnSecureToken" value in the request. + */ +static NSString *const kReturnSecureTokenKey = @"returnSecureToken"; + +@implementation FIRVerifyCustomTokenRequest + +- (nullable instancetype)initWithToken:(NSString *)token + requestConfiguration:(FIRAuthRequestConfiguration *)requestConfiguration { + self = [super initWithEndpoint:kVerifyCustomTokenEndpoint + requestConfiguration:requestConfiguration]; + if (self) { + _token = [token copy]; + _returnSecureToken = YES; + } + return self; +} + +- (nullable id)unencodedHTTPRequestBodyWithError:(NSError *_Nullable *_Nullable)error { + NSMutableDictionary *body = [@{ + kTokenKey : _token + } mutableCopy]; + if (_returnSecureToken) { + body[kReturnSecureTokenKey] = @YES; + } + return body; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRVerifyCustomTokenResponse.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRVerifyCustomTokenResponse.h new file mode 100644 index 0000000..6957bf3 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRVerifyCustomTokenResponse.h @@ -0,0 +1,52 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +#import "FIRAuthRPCResponse.h" + +NS_ASSUME_NONNULL_BEGIN + +/** @class FIRVerifyCustomTokenResponse + @brief Represents the response from the verifyCustomToken endpoint. + */ +@interface FIRVerifyCustomTokenResponse : NSObject + +/** @property IDToken + @brief Either an authorization code suitable for performing an STS token exchange, or the + access token from Secure Token Service, depending on whether @c returnSecureToken is set + on the request. + */ +@property(nonatomic, strong, readonly, nullable) NSString *IDToken; + +/** @property approximateExpirationDate + @brief The approximate expiration date of the access token. + */ +@property(nonatomic, copy, readonly, nullable) NSDate *approximateExpirationDate; + +/** @property refreshToken + @brief The refresh token from Secure Token Service. + */ +@property(nonatomic, strong, readonly, nullable) NSString *refreshToken; + +/** @property isNewUser + @brief Flag indicating that the user signing in is a new user and not a returning user. + */ +@property(nonatomic, assign) BOOL isNewUser; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRVerifyCustomTokenResponse.m b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRVerifyCustomTokenResponse.m new file mode 100644 index 0000000..8b67360 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRVerifyCustomTokenResponse.m @@ -0,0 +1,35 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRVerifyCustomTokenResponse.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation FIRVerifyCustomTokenResponse + +- (BOOL)setWithDictionary:(NSDictionary *)dictionary + error:(NSError *_Nullable *_Nullable)error { + _IDToken = [dictionary[@"idToken"] copy]; + _approximateExpirationDate = [dictionary[@"expiresIn"] isKindOfClass:[NSString class]] ? + [NSDate dateWithTimeIntervalSinceNow:[dictionary[@"expiresIn"] doubleValue]] : nil; + _refreshToken = [dictionary[@"refreshToken"] copy]; + _isNewUser = [dictionary[@"isNewUser"] boolValue]; + return YES; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRVerifyPasswordRequest.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRVerifyPasswordRequest.h new file mode 100644 index 0000000..39eb388 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRVerifyPasswordRequest.h @@ -0,0 +1,81 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +#import "FIRAuthRPCRequest.h" +#import "FIRIdentityToolkitRequest.h" + +NS_ASSUME_NONNULL_BEGIN + +/** @class FIRVerifyPasswordRequest + @brief Represents the parameters for the verifyPassword endpoint. + @see https://developers.google.com/identity/toolkit/web/reference/relyingparty/verifyPassword + */ +@interface FIRVerifyPasswordRequest : FIRIdentityToolkitRequest + +/** @property email + @brief The email of the user. + */ +@property(nonatomic, copy) NSString *email; + +/** @property password + @brief The password inputed by the user. + */ +@property(nonatomic, copy) NSString *password; + +/** @property pendingIDToken + @brief The GITKit token for the non-trusted IDP, which is to be confirmed by the user. + */ +@property(nonatomic, copy, nullable) NSString *pendingIDToken; + +/** @property captchaChallenge + @brief The captcha challenge. + */ +@property(nonatomic, copy, nullable) NSString *captchaChallenge; + +/** @property captchaResponse + @brief Response to the captcha. + */ +@property(nonatomic, copy, nullable) NSString *captchaResponse; + +/** @property returnSecureToken + @brief Whether the response should return access token and refresh token directly. + @remarks The default value is @c YES . + */ +@property(nonatomic, assign) BOOL returnSecureToken; + +/** @fn initWithEndpoint:requestConfiguration: + @brief Please use initWithEmail:password:requestConfiguration: + */ +- (nullable instancetype)initWithEndpoint:(NSString *)endpoint + requestConfiguration:(FIRAuthRequestConfiguration *)requestConfiguration + NS_UNAVAILABLE; + +/** @fn initWithEmail:password:requestConfiguration: + @brief Designated initializer. + @param email The email of the user. + @param password The password inputed by the user. + @param requestConfiguration The configu + */ +- (nullable instancetype)initWithEmail:(NSString *)email + password:(NSString *)password + requestConfiguration:(FIRAuthRequestConfiguration *)requestConfiguration + NS_DESIGNATED_INITIALIZER; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRVerifyPasswordRequest.m b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRVerifyPasswordRequest.m new file mode 100644 index 0000000..5849da6 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRVerifyPasswordRequest.m @@ -0,0 +1,96 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRVerifyPasswordRequest.h" + +NS_ASSUME_NONNULL_BEGIN + +/** @var kVerifyPasswordEndpoint + @brief The "verifyPassword" endpoint. + */ +static NSString *const kVerifyPasswordEndpoint = @"verifyPassword"; + +/** @var kEmailKey + @brief The key for the "email" value in the request. + */ +static NSString *const kEmailKey = @"email"; + +/** @var kPasswordKey + @brief The key for the "password" value in the request. + */ +static NSString *const kPasswordKey = @"password"; + +/** @var kPendingIDTokenKey + @brief The key for the "pendingIdToken" value in the request. + */ +static NSString *const kPendingIDTokenKey = @"pendingIdToken"; + +/** @var kCaptchaChallengeKey + @brief The key for the "captchaChallenge" value in the request. + */ +static NSString *const kCaptchaChallengeKey = @"captchaChallenge"; + +/** @var kCaptchaResponseKey + @brief The key for the "captchaResponse" value in the request. + */ +static NSString *const kCaptchaResponseKey = @"captchaResponse"; + +/** @var kReturnSecureTokenKey + @brief The key for the "returnSecureToken" value in the request. + */ +static NSString *const kReturnSecureTokenKey = @"returnSecureToken"; + +@implementation FIRVerifyPasswordRequest + +- (nullable instancetype)initWithEmail:(NSString *)email + password:(NSString *)password + requestConfiguration:(nonnull FIRAuthRequestConfiguration *)requestConfiguration { + self = [super initWithEndpoint:kVerifyPasswordEndpoint + requestConfiguration:requestConfiguration]; + if (self) { + _email = [email copy]; + _password = [password copy]; + _returnSecureToken = YES; + } + return self; +} + +- (nullable id)unencodedHTTPRequestBodyWithError:(NSError *_Nullable *_Nullable)error { + NSMutableDictionary *postBody = [NSMutableDictionary dictionary]; + if (_email) { + postBody[kEmailKey] = _email; + } + if (_password) { + postBody[kPasswordKey] = _password; + } + if (_pendingIDToken) { + postBody[kPendingIDTokenKey] = _pendingIDToken; + } + if (_captchaChallenge) { + postBody[kCaptchaChallengeKey] = _captchaChallenge; + } + if (_captchaResponse) { + postBody[kCaptchaResponseKey] = _captchaResponse; + } + if (_returnSecureToken) { + postBody[kReturnSecureTokenKey] = @YES; + } + return postBody; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRVerifyPasswordResponse.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRVerifyPasswordResponse.h new file mode 100644 index 0000000..bed13be --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRVerifyPasswordResponse.h @@ -0,0 +1,72 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +#import "FIRAuthRPCResponse.h" + +NS_ASSUME_NONNULL_BEGIN + +/** @class FIRVerifyPasswordResponse + @brief Represents the response from the verifyPassword endpoint. + @remarks Possible error codes: + - FIRAuthInternalErrorCodeUserDisabled + - FIRAuthInternalErrorCodeEmailNotFound + @see https://developers.google.com/identity/toolkit/web/reference/relyingparty/verifyPassword + */ +@interface FIRVerifyPasswordResponse : NSObject + +/** @property localID + @brief The RP local ID if it's already been mapped to the IdP account identified by the + federated ID. + */ +@property(nonatomic, strong, readonly, nullable) NSString *localID; + +/** @property email + @brief The email returned by the IdP. NOTE: The federated login user may not own the email. + */ +@property(nonatomic, strong, readonly, nullable) NSString *email; + +/** @property displayName + @brief The display name of the user. + */ +@property(nonatomic, strong, readonly, nullable) NSString *displayName; + +/** @property IDToken + @brief Either an authorization code suitable for performing an STS token exchange, or the + access token from Secure Token Service, depending on whether @c returnSecureToken is set + on the request. + */ +@property(nonatomic, strong, readonly, nullable) NSString *IDToken; + +/** @property approximateExpirationDate + @brief The approximate expiration date of the access token. + */ +@property(nonatomic, copy, readonly, nullable) NSDate *approximateExpirationDate; + +/** @property refreshToken + @brief The refresh token from Secure Token Service. + */ +@property(nonatomic, strong, readonly, nullable) NSString *refreshToken; + +/** @property photoURL + @brief The URI of the public accessible profile picture. + */ +@property(nonatomic, strong, readonly, nullable) NSURL *photoURL; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRVerifyPasswordResponse.m b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRVerifyPasswordResponse.m new file mode 100644 index 0000000..b42a371 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRVerifyPasswordResponse.m @@ -0,0 +1,38 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRVerifyPasswordResponse.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation FIRVerifyPasswordResponse + +- (BOOL)setWithDictionary:(NSDictionary *)dictionary + error:(NSError *_Nullable *_Nullable)error { + _localID = [dictionary[@"localId"] copy]; + _email = [dictionary[@"email"] copy]; + _displayName = [dictionary[@"displayName"] copy]; + _IDToken = [dictionary[@"idToken"] copy]; + _approximateExpirationDate = [dictionary[@"expiresIn"] isKindOfClass:[NSString class]] ? + [NSDate dateWithTimeIntervalSinceNow:[dictionary[@"expiresIn"] doubleValue]] : nil; + _refreshToken = [dictionary[@"refreshToken"] copy]; + _photoURL = dictionary[@"photoUrl"] ? [NSURL URLWithString:dictionary[@"photoUrl"]] : nil; + return YES; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRVerifyPhoneNumberRequest.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRVerifyPhoneNumberRequest.h new file mode 100644 index 0000000..07988f1 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRVerifyPhoneNumberRequest.h @@ -0,0 +1,91 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRIdentityToolkitRequest.h" + +#import "FIRAuthOperationType.h" +#import "FIRAuthRPCRequest.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface FIRVerifyPhoneNumberRequest : FIRIdentityToolkitRequest + +/** @property verificationID + @brief The verification ID obtained from the response of @c sendVerificationCode. +*/ +@property(nonatomic, readonly, nullable) NSString *verificationID; + +/** @property verificationCode + @brief The verification code provided by the user. +*/ +@property(nonatomic, readonly, nullable) NSString *verificationCode; + +/** @property accessToken + @brief The STS Access Token for the authenticated user. + */ +@property(nonatomic, copy, nullable) NSString *accessToken; + +/** @var temporaryProof + @brief The temporary proof code, previously returned from the backend. + */ +@property(nonatomic, readonly, nonnull) NSString *temporaryProof; + +/** @var phoneNumber + @brief The phone number to be verified in the request. + */ +@property(nonatomic, readonly, nonnull) NSString *phoneNumber; + +/** @var operation + @brief The type of operation triggering this verify phone number request. + */ +@property(nonatomic, assign, readonly) FIRAuthOperationType operation; + +/** @fn initWithEndpoint:requestConfiguration: + @brief Please use initWithVerificationID:verificationCode:requestConfiguration + */ +- (nullable instancetype)initWithEndpoint:(NSString *)endpoint + requestConfiguration:(FIRAuthRequestConfiguration *)requestConfiguration + NS_UNAVAILABLE; + +/** @fn initWithTemporaryProof:phoneNumberAPIKey + @brief Designated initializer. + @param temporaryProof The temporary proof sent by the backed. + @param phoneNumber The phone number associated with the credential to be signed in. + @param operation Indicates what operation triggered the verify phone number request. + @param requestConfiguration An object containing configurations to be added to the request. + */ +- (nullable instancetype)initWithTemporaryProof:(NSString *)temporaryProof + phoneNumber:(NSString *)phoneNumber + operation:(FIRAuthOperationType)operation + requestConfiguration:(FIRAuthRequestConfiguration *)requestConfiguration + NS_DESIGNATED_INITIALIZER; + +/** @fn initWithVerificationID:verificationCode:requestConfiguration + @brief Designated initializer. + @param verificationID The verification ID obtained from the response of @c sendVerificationCode. + @param verificationCode The verification code provided by the user. + @param operation Indicates what operation triggered the verify phone number request. + @param requestConfiguration An object containing configurations to be added to the request. + */ +- (nullable instancetype)initWithVerificationID:(NSString *)verificationID + verificationCode:(NSString *)verificationCode + operation:(FIRAuthOperationType)operation + requestConfiguration:(FIRAuthRequestConfiguration *)requestConfiguration + NS_DESIGNATED_INITIALIZER; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRVerifyPhoneNumberRequest.m b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRVerifyPhoneNumberRequest.m new file mode 100644 index 0000000..022ab9e --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRVerifyPhoneNumberRequest.m @@ -0,0 +1,133 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRVerifyPhoneNumberRequest.h" + +NS_ASSUME_NONNULL_BEGIN + +/** @var kVerifyPhoneNumberEndPoint + @brief The "verifyPhoneNumber" endpoint. + */ +static NSString *const kVerifyPhoneNumberEndPoint = @"verifyPhoneNumber"; + +/** @var kVerificationIDKey + @brief The key for the verification ID parameter in the request. + */ +static NSString *const kVerificationIDKey = @"sessionInfo"; + +/** @var kVerificationCodeKey + @brief The key for the verification code parameter in the request. + */ +static NSString *const kVerificationCodeKey = @"code"; + +/** @var kIDTokenKey + @brief The key for the "ID Token" value in the request. + */ +static NSString *const kIDTokenKey = @"idToken"; + +/** @var kTemporaryProofKey + @brief The key for the temporary proof value in the request. + */ +static NSString *const kTemporaryProofKey = @"temporaryProof"; + +/** @var kPhoneNumberKey + @brief The key for the phone number value in the request. + */ +static NSString *const kPhoneNumberKey = @"phoneNumber"; + +/** @var kOperationKey + @brief The key for the operation value in the request. + */ +static NSString *const kOperationKey = @"operation"; + +@implementation FIRVerifyPhoneNumberRequest + +- (nullable instancetype)initWithTemporaryProof:(NSString *)temporaryProof + phoneNumber:(NSString *)phoneNumber + operation:(FIRAuthOperationType)operation + requestConfiguration: + (FIRAuthRequestConfiguration *)requestConfiguration { + self = [super initWithEndpoint:kVerifyPhoneNumberEndPoint + requestConfiguration:requestConfiguration]; + if (self) { + _temporaryProof = [temporaryProof copy]; + _phoneNumber = [phoneNumber copy]; + _operation = operation; + } + return self; +} + +- (nullable instancetype)initWithVerificationID:(NSString *)verificationID + verificationCode:(NSString *)verificationCode + operation:(FIRAuthOperationType)operation + requestConfiguration: + (FIRAuthRequestConfiguration *)requestConfiguration { + self = [super initWithEndpoint:kVerifyPhoneNumberEndPoint + requestConfiguration:requestConfiguration]; + if (self) { + _verificationID = verificationID; + _verificationCode = verificationCode; + _operation = operation; + } + return self; +} + +/** @fn FIRAuthOperationString + @brief Returns a string object corresponding to the provided FIRAuthOperationType value. + @param operationType The value of the FIRAuthOperationType enum which will be translated to its + corresponding string value. + @return The string value corresponding to the FIRAuthOperationType argument. + */ +NSString *const FIRAuthOperationString(FIRAuthOperationType operationType) { + switch(operationType){ + case FIRAuthOperationTypeUnspecified: + return @"VERIFY_OP_UNSPECIFIED"; + case FIRAuthOperationTypeSignUpOrSignIn: + return @"SIGN_UP_OR_IN"; + case FIRAuthOperationTypeReauth: + return @"REAUTH"; + case FIRAuthOperationTypeLink: + return @"LINK"; + case FIRAuthOperationTypeUpdate: + return @"UPDATE"; + } +} + +- (nullable id)unencodedHTTPRequestBodyWithError:(NSError *__autoreleasing _Nullable *)error { + NSMutableDictionary *postBody = [NSMutableDictionary dictionary]; + if (_verificationID) { + postBody[kVerificationIDKey] = _verificationID; + } + if (_verificationCode) { + postBody[kVerificationCodeKey] = _verificationCode; + } + if (_accessToken) { + postBody[kIDTokenKey] = _accessToken; + } + if (_temporaryProof) { + postBody[kTemporaryProofKey] = _temporaryProof; + } + if (_phoneNumber) { + postBody[kPhoneNumberKey] = _phoneNumber; + } + NSString *operation = FIRAuthOperationString(_operation); + postBody[kOperationKey] = operation; + return postBody; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRVerifyPhoneNumberResponse.h b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRVerifyPhoneNumberResponse.h new file mode 100644 index 0000000..b0ba5dd --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRVerifyPhoneNumberResponse.h @@ -0,0 +1,64 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +#import "FIRAuthRPCResponse.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface FIRVerifyPhoneNumberResponse : NSObject + +/** @property IDToken + @brief Either an authorization code suitable for performing an STS token exchange, or the + access token from Secure Token Service, depending on whether @c returnSecureToken is set + on the request. + */ +@property(nonatomic, strong, readonly, nullable) NSString *IDToken; + +/** @property refreshToken + @brief The refresh token from Secure Token Service. + */ +@property(nonatomic, strong, readonly, nullable) NSString *refreshToken; + +/** @property localID + @brief The Firebase Auth user ID. + */ +@property(nonatomic, strong, readonly, nullable) NSString *localID; + +/** @property phoneNumber + @brief The verified phone number. + */ +@property(nonatomic, strong, readonly, nullable) NSString *phoneNumber; + +/** @property temporaryProof + @brief The temporary proof code returned by the backend. + */ +@property(nonatomic, strong, readonly, nullable) NSString *temporaryProof; + +/** @property isNewUser + @brief Flag indicating that the user signing in is a new user and not a returning user. + */ +@property(nonatomic, assign) BOOL isNewUser; + +/** @property approximateExpirationDate + @brief The approximate expiration date of the access token. + */ +@property(nonatomic, copy, readonly, nullable) NSDate *approximateExpirationDate; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRVerifyPhoneNumberResponse.m b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRVerifyPhoneNumberResponse.m new file mode 100644 index 0000000..acba2c2 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/Firebase/Auth/Source/RPCs/FIRVerifyPhoneNumberResponse.m @@ -0,0 +1,42 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRVerifyPhoneNumberResponse.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation FIRVerifyPhoneNumberResponse + +- (nullable NSString *)expectedKind { + return nil; +} + +- (BOOL)setWithDictionary:(NSDictionary *)dictionary + error:(NSError *_Nullable *_Nullable)error { + _IDToken = [dictionary[@"idToken"] copy]; + _refreshToken = [dictionary[@"refreshToken"] copy]; + _isNewUser = [dictionary[@"isNewUser"] boolValue]; + _localID = [dictionary[@"localId"] copy]; + _phoneNumber = [dictionary[@"phoneNumber"] copy]; + _temporaryProof = [dictionary[@"temporaryProof"] copy]; + _approximateExpirationDate = [dictionary[@"expiresIn"] isKindOfClass:[NSString class]] ? + [NSDate dateWithTimeIntervalSinceNow:[dictionary[@"expiresIn"] doubleValue]] : nil; + return YES; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseAuth/LICENSE b/FoodApp/Pods/FirebaseAuth/LICENSE new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/FoodApp/Pods/FirebaseAuth/README.md b/FoodApp/Pods/FirebaseAuth/README.md new file mode 100644 index 0000000..ad8de0f --- /dev/null +++ b/FoodApp/Pods/FirebaseAuth/README.md @@ -0,0 +1,213 @@ +# Firebase iOS Open Source Development [![Build Status](https://travis-ci.org/firebase/firebase-ios-sdk.svg?branch=master)](https://travis-ci.org/firebase/firebase-ios-sdk) + +This repository contains a subset of the Firebase iOS SDK source. It currently +includes FirebaseCore, FirebaseAuth, FirebaseDatabase, FirebaseFirestore, +FirebaseFunctions, FirebaseInstanceID, FirebaseInAppMessaging, +FirebaseInAppMessagingDisplay, FirebaseMessaging and FirebaseStorage. + +The repository also includes GoogleUtilities source. The +[GoogleUtilities](GoogleUtilities/README.md) pod is +a set of utilities used by Firebase and other Google products. + +Firebase is an app development platform with tools to help you build, grow and +monetize your app. More information about Firebase can be found at +[https://firebase.google.com](https://firebase.google.com). + +## Installation + +See the three subsections for details about three different installation methods. +1. [Standard pod install](README.md#standard-pod-install) +1. [Installing from the GitHub repo](README.md#installing-from-github) +1. [Experimental Carthage](README.md#carthage-ios-only) + +### Standard pod install + +Go to +[https://firebase.google.com/docs/ios/setup](https://firebase.google.com/docs/ios/setup). + +### Installing from GitHub + +For releases starting with 5.0.0, the source for each release is also deployed +to CocoaPods master and available via standard +[CocoaPods Podfile syntax](https://guides.cocoapods.org/syntax/podfile.html#pod). + +These instructions can be used to access the Firebase repo at other branches, +tags, or commits. + +#### Background + +See +[the Podfile Syntax Reference](https://guides.cocoapods.org/syntax/podfile.html#pod) +for instructions and options about overriding pod source locations. + +#### Accessing Firebase Source Snapshots + +All of the official releases are tagged in this repo and available via CocoaPods. To access a local +source snapshot or unreleased branch, use Podfile directives like the following: + +To access FirebaseFirestore via a branch: +``` +pod 'FirebaseCore', :git => 'https://github.com/firebase/firebase-ios-sdk.git', :branch => 'master' +pod 'FirebaseFirestore', :git => 'https://github.com/firebase/firebase-ios-sdk.git', :branch => 'master' +``` + +To access FirebaseMessaging via a checked out version of the firebase-ios-sdk repo do: + +``` +pod 'FirebaseCore', :path => '/path/to/firebase-ios-sdk' +pod 'FirebaseMessaging', :path => '/path/to/firebase-ios-sdk' +``` + +### Carthage (iOS only) + +Instructions for the experimental Carthage distribution are at +[Carthage](Carthage.md). + +### Rome + +Instructions for installing binary frameworks via +[Rome](https://github.com/CocoaPods/Rome) are at [Rome](Rome.md). + +## Development + +Follow the subsequent instructions to develop, debug, unit test, run integration +tests, and try out reference samples: + +``` +$ git clone git@github.com:firebase/firebase-ios-sdk.git +$ cd firebase-ios-sdk/Example +$ pod update +$ open Firebase.xcworkspace +``` + +Firestore and Functions have self contained Xcode projects. See +[Firestore/README.md](Firestore/README.md) and +[Functions/README.md](Functions/README.md). + +### Code Formatting + +To ensure that the code is formatted consistently, run the script +[./scripts/style.sh](https://github.com/firebase/firebase-ios-sdk/blob/master/scripts/style.sh) +before creating a PR. + +Travis will verify that any code changes are done in a style compliant way. Install +`clang-format` and `swiftformat`. +This command will get the right `clang-format` version: + +`brew install https://raw.githubusercontent.com/Homebrew/homebrew-core/773cb75d360b58f32048f5964038d09825a507c8/Formula/clang-format.rb` + +### Running Unit Tests + +Select a scheme and press Command-u to build a component and run its unit tests. + +#### Viewing Code Coverage + +First, make sure that [xcov](https://github.com/nakiostudio/xcov) is installed with `gem install xcov`. + +After running the `AllUnitTests_iOS` scheme in Xcode, execute +`xcov --workspace Firebase.xcworkspace --scheme AllUnitTests_iOS --output_directory xcov_output` +at Example/ in the terminal. This will aggregate the coverage, and you can run `open xcov_output/index.html` to see the results. + +### Running Sample Apps +In order to run the sample apps and integration tests, you'll need valid +`GoogleService-Info.plist` files for those samples. The Firebase Xcode project contains dummy plist +files without real values, but can be replaced with real plist files. To get your own +`GoogleService-Info.plist` files: + +1. Go to the [Firebase Console](https://console.firebase.google.com/) +2. Create a new Firebase project, if you don't already have one +3. For each sample app you want to test, create a new Firebase app with the sample app's bundle +identifier (e.g. `com.google.Database-Example`) +4. Download the resulting `GoogleService-Info.plist` and replace the appropriate dummy plist file +(e.g. in [Example/Database/App/](Example/Database/App/)); + +Some sample apps like Firebase Messaging ([Example/Messaging/App](Example/Messaging/App)) require +special Apple capabilities, and you will have to change the sample app to use a unique bundle +identifier that you can control in your own Apple Developer account. + +## Specific Component Instructions +See the sections below for any special instructions for those components. + +### Firebase Auth + +If you're doing specific Firebase Auth development, see +[the Auth Sample README](Example/Auth/README.md) for instructions about +building and running the FirebaseAuth pod along with various samples and tests. + +### Firebase Database + +To run the Database Integration tests, make your database authentication rules +[public](https://firebase.google.com/docs/database/security/quickstart). + +### Firebase Storage + +To run the Storage Integration tests, follow the instructions in +[FIRStorageIntegrationTests.m](Example/Storage/Tests/Integration/FIRStorageIntegrationTests.m). + +#### Push Notifications + +Push notifications can only be delivered to specially provisioned App IDs in the developer portal. +In order to actually test receiving push notifications, you will need to: + +1. Change the bundle identifier of the sample app to something you own in your Apple Developer +account, and enable that App ID for push notifications. +2. You'll also need to +[upload your APNs Provider Authentication Key or certificate to the Firebase Console](https://firebase.google.com/docs/cloud-messaging/ios/certs) +at **Project Settings > Cloud Messaging > [Your Firebase App]**. +3. Ensure your iOS device is added to your Apple Developer portal as a test device. + +#### iOS Simulator + +The iOS Simulator cannot register for remote notifications, and will not receive push notifications. +In order to receive push notifications, you'll have to follow the steps above and run the app on a +physical device. + +## Community Supported Efforts + +We've seen an amazing amount of interest and contributions to improve the Firebase SDKs, and we are +very grateful! We'd like to empower as many developers as we can to be able to use Firebase and +participate in the Firebase community. + +### macOS and tvOS +Thanks to contributions from the community, FirebaseAuth, FirebaseCore, FirebaseDatabase, +FirebaseFunctions and FirebaseStorage now compile, run unit tests, and work on macOS and tvOS. +FirebaseFirestore is availiable for macOS and FirebaseMessaging for tvOS. + +For tvOS, checkout the [Sample](Example/tvOSSample). + +Keep in mind that macOS and tvOS are not officially supported by Firebase, and this repository is +actively developed primarily for iOS. While we can catch basic unit test issues with Travis, there +may be some changes where the SDK no longer works as expected on macOS or tvOS. If you encounter +this, please [file an issue](https://github.com/firebase/firebase-ios-sdk/issues). + +Note that the Firebase pod is not available for macOS and tvOS. + +To install, add a subset of the following to the Podfile: + +``` +pod 'FirebaseAuth' +pod 'FirebaseCore' +pod 'FirebaseDatabase' +pod 'FirebaseFirestore' # Only iOS and macOS +pod 'FirebaseFunctions' +pod 'FirebaseMessaging' # Only iOS and tvOS +pod 'FirebaseStorage' +``` + +## Roadmap + +See [Roadmap](ROADMAP.md) for more about the Firebase iOS SDK Open Source +plans and directions. + +## Contributing + +See [Contributing](CONTRIBUTING.md) for more information on contributing to the Firebase +iOS SDK. + +## License + +The contents of this repository is licensed under the +[Apache License, version 2.0](http://www.apache.org/licenses/LICENSE-2.0). + +Your use of Firebase is governed by the +[Terms of Service for Firebase Services](https://firebase.google.com/terms/). diff --git a/FoodApp/Pods/FirebaseAuthInterop/Interop/Auth/Public/FIRAuthInterop.h b/FoodApp/Pods/FirebaseAuthInterop/Interop/Auth/Public/FIRAuthInterop.h new file mode 100644 index 0000000..5c365a3 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuthInterop/Interop/Auth/Public/FIRAuthInterop.h @@ -0,0 +1,42 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRAuthInterop_h +#define FIRAuthInterop_h + +NS_ASSUME_NONNULL_BEGIN + +/** @typedef FIRTokenCallback + @brief The type of block which gets called when a token is ready. + */ +typedef void (^FIRTokenCallback)(NSString *_Nullable token, NSError *_Nullable error) + NS_SWIFT_NAME(TokenCallback); + +/// Common methods for Auth interoperability. +NS_SWIFT_NAME(AuthInterop) +@protocol FIRAuthInterop + +/// Retrieves the Firebase authentication token, possibly refreshing it if it has expired. +- (void)getTokenForcingRefresh:(BOOL)forceRefresh withCallback:(FIRTokenCallback)callback; + +/// Get the current Auth user's UID. Returns nil if there is no user signed in. +- (nullable NSString *)getUserID; + +@end + +NS_ASSUME_NONNULL_END + +#endif /* FIRAuthInterop_h */ diff --git a/FoodApp/Pods/FirebaseAuthInterop/LICENSE b/FoodApp/Pods/FirebaseAuthInterop/LICENSE new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/FoodApp/Pods/FirebaseAuthInterop/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/FoodApp/Pods/FirebaseAuthInterop/README.md b/FoodApp/Pods/FirebaseAuthInterop/README.md new file mode 100644 index 0000000..4414b3e --- /dev/null +++ b/FoodApp/Pods/FirebaseAuthInterop/README.md @@ -0,0 +1,179 @@ +# Firebase iOS Open Source Development [![Build Status](https://travis-ci.org/firebase/firebase-ios-sdk.svg?branch=master)](https://travis-ci.org/firebase/firebase-ios-sdk) + +This repository contains a subset of the Firebase iOS SDK source. It currently +includes FirebaseCore, FirebaseAuth, FirebaseDatabase, FirebaseFirestore, +FirebaseFunctions, FirebaseMessaging and FirebaseStorage. + +The repository also includes GoogleUtilities source. The +[GoogleUtilities](GoogleUtilities/README.md) pod is +a set of utilities used by Firebase and other Google products. + +Firebase is an app development platform with tools to help you build, grow and +monetize your app. More information about Firebase can be found at +[https://firebase.google.com](https://firebase.google.com). + +## Installation + +See the three subsections for details about three different installation methods. +1. [Standard pod install](README.md#standard-pod-install) +1. [Installing from the GitHub repo](README.md#installing-from-github) +1. [Experimental Carthage](README.md#carthage-ios-only) + +### Standard pod install + +Go to +[https://firebase.google.com/docs/ios/setup](https://firebase.google.com/docs/ios/setup). + +### Installing from GitHub + +For releases starting with 5.0.0, the source for each release is also deployed +to CocoaPods master and available via standard +[CocoaPods Podfile syntax](https://guides.cocoapods.org/syntax/podfile.html#pod). + +These instructions can be used to access the Firebase repo at other branches, +tags, or commits. + +#### Background + +See +[the Podfile Syntax Reference](https://guides.cocoapods.org/syntax/podfile.html#pod) +for instructions and options about overriding pod source locations. + +#### Accessing Firebase Source Snapshots + +All of the official releases are tagged in this repo and available via CocoaPods. To access a local +source snapshot or unreleased branch, use Podfile directives like the following: + +To access FirebaseFirestore via a branch: +``` +pod 'FirebaseCore', :git => 'https://github.com/firebase/firebase-ios-sdk.git', :branch => 'master' +pod 'FirebaseFirestore', :git => 'https://github.com/firebase/firebase-ios-sdk.git', :branch => 'master' +``` + +To access FirebaseMessaging via a checked out version of the firebase-ios-sdk repo do: + +``` +pod 'FirebaseCore', :path => '/path/to/firebase-ios-sdk' +pod 'FirebaseMessaging', :path => '/path/to/firebase-ios-sdk' +``` + +### Carthage (iOS only) + +An experimental Carthage distribution is now available. See +[Carthage](Carthage.md). + +## Development + +Follow the subsequent instructions to develop, debug, unit test, run integration +tests, and try out reference samples: + +``` +$ git clone git@github.com:firebase/firebase-ios-sdk.git +$ cd firebase-ios-sdk/Example +$ pod update +$ open Firebase.xcworkspace +``` + +Firestore and Functions have self contained Xcode projects. See +[Firestore/README.md](Firestore/README.md) and +[Functions/README.md](Functions/README.md). + +### Running Unit Tests + +Select a scheme and press Command-u to build a component and run its unit tests. + +### Running Sample Apps +In order to run the sample apps and integration tests, you'll need valid +`GoogleService-Info.plist` files for those samples. The Firebase Xcode project contains dummy plist +files without real values, but can be replaced with real plist files. To get your own +`GoogleService-Info.plist` files: + +1. Go to the [Firebase Console](https://console.firebase.google.com/) +2. Create a new Firebase project, if you don't already have one +3. For each sample app you want to test, create a new Firebase app with the sample app's bundle +identifier (e.g. `com.google.Database-Example`) +4. Download the resulting `GoogleService-Info.plist` and replace the appropriate dummy plist file +(e.g. in [Example/Database/App/](Example/Database/App/)); + +Some sample apps like Firebase Messaging ([Example/Messaging/App](Example/Messaging/App)) require +special Apple capabilities, and you will have to change the sample app to use a unique bundle +identifier that you can control in your own Apple Developer account. + +## Specific Component Instructions +See the sections below for any special instructions for those components. + +### Firebase Auth + +If you're doing specific Firebase Auth development, see +[AuthSamples/README.md](AuthSamples/README.md) for instructions about +building and running the FirebaseAuth pod along with various samples and tests. + +### Firebase Database + +To run the Database Integration tests, make your database authentication rules +[public](https://firebase.google.com/docs/database/security/quickstart). + +### Firebase Storage + +To run the Storage Integration tests, follow the instructions in +[FIRStorageIntegrationTests.m](Example/Storage/Tests/Integration/FIRStorageIntegrationTests.m). + +#### Push Notifications + +Push notifications can only be delivered to specially provisioned App IDs in the developer portal. +In order to actually test receiving push notifications, you will need to: + +1. Change the bundle identifier of the sample app to something you own in your Apple Developer +account, and enable that App ID for push notifications. +2. You'll also need to +[upload your APNs Provider Authentication Key or certificate to the Firebase Console](https://firebase.google.com/docs/cloud-messaging/ios/certs) +at **Project Settings > Cloud Messaging > [Your Firebase App]**. +3. Ensure your iOS device is added to your Apple Developer portal as a test device. + +#### iOS Simulator + +The iOS Simulator cannot register for remote notifications, and will not receive push notifications. +In order to receive push notifications, you'll have to follow the steps above and run the app on a +physical device. + +## Community Supported Efforts + +We've seen an amazing amount of interest and contributions to improve the Firebase SDKs, and we are +very grateful! We'd like to empower as many developers as we can to be able to use Firebase and +participate in the Firebase community. + +### macOS and tvOS +FirebaseAuth, FirebaseCore, FirebaseDatabase and FirebaseStorage now compile, run unit tests, and +work on macOS and tvOS, thanks to contributions from the community. There are a few tweaks needed, +like ensuring iOS-only, macOS-only, or tvOS-only code is correctly guarded with checks for +`TARGET_OS_IOS`, `TARGET_OS_OSX` and `TARGET_OS_TV`. + +For tvOS, checkout the [Sample](Example/tvOSSample). + +Keep in mind that macOS and tvOS are not officially supported by Firebase, and this repository is +actively developed primarily for iOS. While we can catch basic unit test issues with Travis, there +may be some changes where the SDK no longer works as expected on macOS or tvOS. If you encounter +this, please [file an issue](https://github.com/firebase/firebase-ios-sdk/issues). + +For installation instructions, see [above](README.md#accessing-firebase-source-snapshots). + +Note that the Firebase pod is not available for macOS and tvOS. Install a selection of the +`FirebaseAuth`, `FirebaseCore`, `FirebaseDatabase` and `FirebaseStorage` CocoaPods. + +## Roadmap + +See [Roadmap](ROADMAP.md) for more about the Firebase iOS SDK Open Source +plans and directions. + +## Contributing + +See [Contributing](CONTRIBUTING.md) for more information on contributing to the Firebase +iOS SDK. + +## License + +The contents of this repository is licensed under the +[Apache License, version 2.0](http://www.apache.org/licenses/LICENSE-2.0). + +Your use of Firebase is governed by the +[Terms of Service for Firebase Services](https://firebase.google.com/terms/). diff --git a/FoodApp/Pods/FirebaseCore/Firebase/Core/FIRAnalyticsConfiguration.m b/FoodApp/Pods/FirebaseCore/Firebase/Core/FIRAnalyticsConfiguration.m new file mode 100644 index 0000000..e584839 --- /dev/null +++ b/FoodApp/Pods/FirebaseCore/Firebase/Core/FIRAnalyticsConfiguration.m @@ -0,0 +1,72 @@ +// Copyright 2017 Google +// +// 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. + +#import "FIRAnalyticsConfiguration.h" + +#import "Private/FIRAnalyticsConfiguration+Internal.h" + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-implementations" +@implementation FIRAnalyticsConfiguration +#pragma clang diagnostic pop + ++ (FIRAnalyticsConfiguration *)sharedInstance { + static FIRAnalyticsConfiguration *sharedInstance = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + sharedInstance = [[FIRAnalyticsConfiguration alloc] init]; + }); + return sharedInstance; +} + +- (void)postNotificationName:(NSString *)name value:(id)value { + if (!name.length || !value) { + return; + } + [[NSNotificationCenter defaultCenter] postNotificationName:name + object:self + userInfo:@{name : value}]; +} + +- (void)setMinimumSessionInterval:(NSTimeInterval)minimumSessionInterval { + [self postNotificationName:kFIRAnalyticsConfigurationSetMinimumSessionIntervalNotification + value:@(minimumSessionInterval)]; +} + +- (void)setSessionTimeoutInterval:(NSTimeInterval)sessionTimeoutInterval { + [self postNotificationName:kFIRAnalyticsConfigurationSetSessionTimeoutIntervalNotification + value:@(sessionTimeoutInterval)]; +} + +- (void)setAnalyticsCollectionEnabled:(BOOL)analyticsCollectionEnabled { + [self setAnalyticsCollectionEnabled:analyticsCollectionEnabled persistSetting:YES]; +} + +- (void)setAnalyticsCollectionEnabled:(BOOL)analyticsCollectionEnabled + persistSetting:(BOOL)shouldPersist { + // Persist the measurementEnabledState. Use FIRAnalyticsEnabledState values instead of YES/NO. + FIRAnalyticsEnabledState analyticsEnabledState = + analyticsCollectionEnabled ? kFIRAnalyticsEnabledStateSetYes : kFIRAnalyticsEnabledStateSetNo; + if (shouldPersist) { + NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; + [userDefaults setObject:@(analyticsEnabledState) + forKey:kFIRAPersistedConfigMeasurementEnabledStateKey]; + [userDefaults synchronize]; + } + + [self postNotificationName:kFIRAnalyticsConfigurationSetEnabledNotification + value:@(analyticsCollectionEnabled)]; +} + +@end diff --git a/FoodApp/Pods/FirebaseCore/Firebase/Core/FIRApp.m b/FoodApp/Pods/FirebaseCore/Firebase/Core/FIRApp.m new file mode 100644 index 0000000..a38e8f3 --- /dev/null +++ b/FoodApp/Pods/FirebaseCore/Firebase/Core/FIRApp.m @@ -0,0 +1,829 @@ +// Copyright 2017 Google +// +// 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 + +#import "FIRApp.h" +#import "FIRConfiguration.h" +#import "Private/FIRAnalyticsConfiguration+Internal.h" +#import "Private/FIRAppInternal.h" +#import "Private/FIRBundleUtil.h" +#import "Private/FIRComponentContainerInternal.h" +#import "Private/FIRLibrary.h" +#import "Private/FIRLogger.h" +#import "Private/FIROptionsInternal.h" + +NSString *const kFIRServiceAdMob = @"AdMob"; +NSString *const kFIRServiceAuth = @"Auth"; +NSString *const kFIRServiceAuthUI = @"AuthUI"; +NSString *const kFIRServiceCrash = @"Crash"; +NSString *const kFIRServiceDatabase = @"Database"; +NSString *const kFIRServiceDynamicLinks = @"DynamicLinks"; +NSString *const kFIRServiceFirestore = @"Firestore"; +NSString *const kFIRServiceFunctions = @"Functions"; +NSString *const kFIRServiceInstanceID = @"InstanceID"; +NSString *const kFIRServiceInvites = @"Invites"; +NSString *const kFIRServiceMessaging = @"Messaging"; +NSString *const kFIRServiceMeasurement = @"Measurement"; +NSString *const kFIRServicePerformance = @"Performance"; +NSString *const kFIRServiceRemoteConfig = @"RemoteConfig"; +NSString *const kFIRServiceStorage = @"Storage"; +NSString *const kGGLServiceAnalytics = @"Analytics"; +NSString *const kGGLServiceSignIn = @"SignIn"; + +NSString *const kFIRDefaultAppName = @"__FIRAPP_DEFAULT"; +NSString *const kFIRAppReadyToConfigureSDKNotification = @"FIRAppReadyToConfigureSDKNotification"; +NSString *const kFIRAppDeleteNotification = @"FIRAppDeleteNotification"; +NSString *const kFIRAppIsDefaultAppKey = @"FIRAppIsDefaultAppKey"; +NSString *const kFIRAppNameKey = @"FIRAppNameKey"; +NSString *const kFIRGoogleAppIDKey = @"FIRGoogleAppIDKey"; + +NSString *const kFIRGlobalAppDataCollectionEnabledDefaultsKeyFormat = + @"/google/firebase/global_data_collection_enabled:%@"; +NSString *const kFIRGlobalAppDataCollectionEnabledPlistKey = + @"FirebaseDataCollectionDefaultEnabled"; + +NSString *const kFIRAppDiagnosticsNotification = @"FIRAppDiagnosticsNotification"; + +NSString *const kFIRAppDiagnosticsConfigurationTypeKey = @"ConfigType"; +NSString *const kFIRAppDiagnosticsErrorKey = @"Error"; +NSString *const kFIRAppDiagnosticsFIRAppKey = @"FIRApp"; +NSString *const kFIRAppDiagnosticsSDKNameKey = @"SDKName"; +NSString *const kFIRAppDiagnosticsSDKVersionKey = @"SDKVersion"; + +// Auth internal notification notification and key. +NSString *const FIRAuthStateDidChangeInternalNotification = + @"FIRAuthStateDidChangeInternalNotification"; +NSString *const FIRAuthStateDidChangeInternalNotificationAppKey = + @"FIRAuthStateDidChangeInternalNotificationAppKey"; +NSString *const FIRAuthStateDidChangeInternalNotificationTokenKey = + @"FIRAuthStateDidChangeInternalNotificationTokenKey"; +NSString *const FIRAuthStateDidChangeInternalNotificationUIDKey = + @"FIRAuthStateDidChangeInternalNotificationUIDKey"; + +/** + * The URL to download plist files. + */ +static NSString *const kPlistURL = @"https://console.firebase.google.com/"; + +/** + * An array of all classes that registered as `FIRCoreConfigurable` in order to receive lifecycle + * events from Core. + */ +static NSMutableArray> *sRegisteredAsConfigurable; + +@interface FIRApp () + +#ifdef DEBUG +@property(nonatomic) BOOL alreadyOutputDataCollectionFlag; +#endif // DEBUG + +@end + +@implementation FIRApp + +// This is necessary since our custom getter prevents `_options` from being created. +@synthesize options = _options; + +static NSMutableDictionary *sAllApps; +static FIRApp *sDefaultApp; +static NSMutableDictionary *sLibraryVersions; + ++ (void)configure { + FIROptions *options = [FIROptions defaultOptions]; + if (!options) { + // Read the Info.plist to see if the flag is set. At this point we can't check any user defaults + // since the app isn't configured at all, so only rely on the Info.plist value. + NSNumber *collectionEnabledPlistValue = [[self class] readDataCollectionSwitchFromPlist]; + if (collectionEnabledPlistValue == nil || [collectionEnabledPlistValue boolValue]) { + [[NSNotificationCenter defaultCenter] + postNotificationName:kFIRAppDiagnosticsNotification + object:nil + userInfo:@{ + kFIRAppDiagnosticsConfigurationTypeKey : @(FIRConfigTypeCore), + kFIRAppDiagnosticsErrorKey : [FIRApp errorForMissingOptions] + }]; + } + + [NSException raise:kFirebaseCoreErrorDomain + format:@"`[FIRApp configure];` (`FirebaseApp.configure()` in Swift) could not find " + @"a valid GoogleService-Info.plist in your project. Please download one " + @"from %@.", + kPlistURL]; + } + [FIRApp configureWithOptions:options]; +#if TARGET_OS_OSX || TARGET_OS_TV + FIRLogNotice(kFIRLoggerCore, @"I-COR000028", + @"tvOS and macOS SDK support is not part of the official Firebase product. " + @"Instead they are community supported. Details at " + @"https://github.com/firebase/firebase-ios-sdk/blob/master/README.md."); +#endif +} + ++ (void)configureWithOptions:(FIROptions *)options { + if (!options) { + [NSException raise:kFirebaseCoreErrorDomain + format:@"Options is nil. Please pass a valid options."]; + } + [FIRApp configureWithName:kFIRDefaultAppName options:options]; +} + ++ (void)configureWithName:(NSString *)name options:(FIROptions *)options { + if (!name || !options) { + [NSException raise:kFirebaseCoreErrorDomain format:@"Neither name nor options can be nil."]; + } + if (name.length == 0) { + [NSException raise:kFirebaseCoreErrorDomain format:@"Name cannot be empty."]; + } + + if ([name isEqualToString:kFIRDefaultAppName]) { + if (sDefaultApp) { + [NSException raise:kFirebaseCoreErrorDomain + format:@"Default app has already been configured."]; + } + + FIRLogDebug(kFIRLoggerCore, @"I-COR000001", @"Configuring the default app."); + } else { + // Validate the app name and ensure it hasn't been configured already. + for (NSUInteger charIndex = 0; charIndex < name.length; charIndex++) { + char character = [name characterAtIndex:charIndex]; + if (!((character >= 'a' && character <= 'z') || (character >= 'A' && character <= 'Z') || + (character >= '0' && character <= '9') || character == '_' || character == '-')) { + [NSException raise:kFirebaseCoreErrorDomain + format:@"App name can only contain alphanumeric (A-Z,a-z,0-9), " + @"hyphen (-), and underscore (_) characters"]; + } + } + + @synchronized(self) { + if (sAllApps && sAllApps[name]) { + [NSException raise:kFirebaseCoreErrorDomain + format:@"App named %@ has already been configured.", name]; + } + } + + FIRLogDebug(kFIRLoggerCore, @"I-COR000002", @"Configuring app named %@", name); + } + + @synchronized(self) { + FIRApp *app = [[FIRApp alloc] initInstanceWithName:name options:options]; + if (app.isDefaultApp) { + sDefaultApp = app; + } + + [FIRApp addAppToAppDictionary:app]; + [FIRApp sendNotificationsToSDKs:app]; + } +} + ++ (FIRApp *)defaultApp { + if (sDefaultApp) { + return sDefaultApp; + } + FIRLogError(kFIRLoggerCore, @"I-COR000003", + @"The default Firebase app has not yet been " + @"configured. Add `[FIRApp configure];` (`FirebaseApp.configure()` in Swift) to your " + @"application initialization. Read more: https://goo.gl/ctyzm8."); + return nil; +} + ++ (FIRApp *)appNamed:(NSString *)name { + @synchronized(self) { + if (sAllApps) { + FIRApp *app = sAllApps[name]; + if (app) { + return app; + } + } + FIRLogError(kFIRLoggerCore, @"I-COR000004", @"App with name %@ does not exist.", name); + return nil; + } +} + ++ (NSDictionary *)allApps { + @synchronized(self) { + if (!sAllApps) { + FIRLogError(kFIRLoggerCore, @"I-COR000005", @"No app has been configured yet."); + } + return [sAllApps copy]; + } +} + +// Public only for tests ++ (void)resetApps { + @synchronized(self) { + sDefaultApp = nil; + [sAllApps removeAllObjects]; + sAllApps = nil; + [sLibraryVersions removeAllObjects]; + sLibraryVersions = nil; + } +} + +- (void)deleteApp:(FIRAppVoidBoolCallback)completion { + @synchronized([self class]) { + if (sAllApps && sAllApps[self.name]) { + FIRLogDebug(kFIRLoggerCore, @"I-COR000006", @"Deleting app named %@", self.name); + + // Remove all cached instances from the container before deleting the app. + [self.container removeAllCachedInstances]; + + [sAllApps removeObjectForKey:self.name]; + [self clearDataCollectionSwitchFromUserDefaults]; + if ([self.name isEqualToString:kFIRDefaultAppName]) { + sDefaultApp = nil; + } + NSDictionary *appInfoDict = @{kFIRAppNameKey : self.name}; + [[NSNotificationCenter defaultCenter] postNotificationName:kFIRAppDeleteNotification + object:[self class] + userInfo:appInfoDict]; + completion(YES); + } else { + FIRLogError(kFIRLoggerCore, @"I-COR000007", @"App does not exist."); + completion(NO); + } + } +} + ++ (void)addAppToAppDictionary:(FIRApp *)app { + if (!sAllApps) { + sAllApps = [NSMutableDictionary dictionary]; + } + if ([app configureCore]) { + sAllApps[app.name] = app; + } else { + [NSException raise:kFirebaseCoreErrorDomain + format:@"Configuration fails. It may be caused by an invalid GOOGLE_APP_ID in " + @"GoogleService-Info.plist or set in the customized options."]; + } +} + +- (instancetype)initInstanceWithName:(NSString *)name options:(FIROptions *)options { + self = [super init]; + if (self) { + _name = [name copy]; + _options = [options copy]; + _options.editingLocked = YES; + _isDefaultApp = [name isEqualToString:kFIRDefaultAppName]; + _container = [[FIRComponentContainer alloc] initWithApp:self]; + } + return self; +} + +- (BOOL)configureCore { + [self checkExpectedBundleID]; + if (![self isAppIDValid]) { + if (_options.usingOptionsFromDefaultPlist && [self isDataCollectionDefaultEnabled]) { + [[NSNotificationCenter defaultCenter] + postNotificationName:kFIRAppDiagnosticsNotification + object:nil + userInfo:@{ + kFIRAppDiagnosticsConfigurationTypeKey : @(FIRConfigTypeCore), + kFIRAppDiagnosticsErrorKey : [FIRApp errorForInvalidAppID], + }]; + } + return NO; + } + + if ([self isDataCollectionDefaultEnabled]) { + [[NSNotificationCenter defaultCenter] + postNotificationName:kFIRAppDiagnosticsNotification + object:nil + userInfo:@{ + kFIRAppDiagnosticsConfigurationTypeKey : @(FIRConfigTypeCore), + kFIRAppDiagnosticsFIRAppKey : self + }]; + } + +#if TARGET_OS_IOS + // Initialize the Analytics once there is a valid options under default app. Analytics should + // always initialize first by itself before the other SDKs. + if ([self.name isEqualToString:kFIRDefaultAppName]) { + Class firAnalyticsClass = NSClassFromString(@"FIRAnalytics"); + if (!firAnalyticsClass) { + FIRLogWarning(kFIRLoggerCore, @"I-COR000022", + @"Firebase Analytics is not available. To add it, include Firebase/Core in the " + @"Podfile or add FirebaseAnalytics.framework to the Link Build Phase"); + } else { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wundeclared-selector" + SEL startWithConfigurationSelector = @selector(startWithConfiguration:options:); +#pragma clang diagnostic pop + if ([firAnalyticsClass respondsToSelector:startWithConfigurationSelector]) { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Warc-performSelector-leaks" +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + [firAnalyticsClass performSelector:startWithConfigurationSelector + withObject:[FIRConfiguration sharedInstance].analyticsConfiguration + withObject:_options]; +#pragma clang diagnostic pop + } + } + } +#endif + + return YES; +} + +- (FIROptions *)options { + return [_options copy]; +} + +- (void)setDataCollectionDefaultEnabled:(BOOL)dataCollectionDefaultEnabled { +#ifdef DEBUG + FIRLogDebug(kFIRLoggerCore, @"I-COR000034", @"Explicitly %@ data collection flag.", + dataCollectionDefaultEnabled ? @"enabled" : @"disabled"); + self.alreadyOutputDataCollectionFlag = YES; +#endif // DEBUG + + NSString *key = + [NSString stringWithFormat:kFIRGlobalAppDataCollectionEnabledDefaultsKeyFormat, self.name]; + [[NSUserDefaults standardUserDefaults] setBool:dataCollectionDefaultEnabled forKey:key]; + + // Core also controls the FirebaseAnalytics flag, so check if the Analytics flags are set + // within FIROptions and change the Analytics value if necessary. Analytics only works with the + // default app, so return if this isn't the default app. + if (!self.isDefaultApp) { + return; + } + + // Check if the Analytics flag is explicitly set. If so, no further actions are necessary. + if ([self.options isAnalyticsCollectionExpicitlySet]) { + return; + } + + // The Analytics flag has not been explicitly set, so update with the value being set. +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + [[FIRAnalyticsConfiguration sharedInstance] + setAnalyticsCollectionEnabled:dataCollectionDefaultEnabled + persistSetting:NO]; +#pragma clang diagnostic pop +} + +- (BOOL)isDataCollectionDefaultEnabled { + // Check if it's been manually set before in code, and use that as the higher priority value. + NSNumber *defaultsObject = [[self class] readDataCollectionSwitchFromUserDefaultsForApp:self]; + if (defaultsObject != nil) { +#ifdef DEBUG + if (!self.alreadyOutputDataCollectionFlag) { + FIRLogDebug(kFIRLoggerCore, @"I-COR000031", @"Data Collection flag is %@ in user defaults.", + [defaultsObject boolValue] ? @"enabled" : @"disabled"); + self.alreadyOutputDataCollectionFlag = YES; + } +#endif // DEBUG + return [defaultsObject boolValue]; + } + + // Read the Info.plist to see if the flag is set. If it's not set, it should default to `YES`. + // As per the implementation of `readDataCollectionSwitchFromPlist`, it's a cached value and has + // no performance impact calling multiple times. + NSNumber *collectionEnabledPlistValue = [[self class] readDataCollectionSwitchFromPlist]; + if (collectionEnabledPlistValue != nil) { +#ifdef DEBUG + if (!self.alreadyOutputDataCollectionFlag) { + FIRLogDebug(kFIRLoggerCore, @"I-COR000032", @"Data Collection flag is %@ in plist.", + [collectionEnabledPlistValue boolValue] ? @"enabled" : @"disabled"); + self.alreadyOutputDataCollectionFlag = YES; + } +#endif // DEBUG + return [collectionEnabledPlistValue boolValue]; + } + +#ifdef DEBUG + if (!self.alreadyOutputDataCollectionFlag) { + FIRLogDebug(kFIRLoggerCore, @"I-COR000033", @"Data Collection flag is not set."); + self.alreadyOutputDataCollectionFlag = YES; + } +#endif // DEBUG + return YES; +} + +#pragma mark - private + ++ (void)sendNotificationsToSDKs:(FIRApp *)app { + // TODO: Remove this notification once all SDKs are registered with `FIRCoreConfigurable`. + NSNumber *isDefaultApp = [NSNumber numberWithBool:app.isDefaultApp]; + NSDictionary *appInfoDict = @{ + kFIRAppNameKey : app.name, + kFIRAppIsDefaultAppKey : isDefaultApp, + kFIRGoogleAppIDKey : app.options.googleAppID + }; + [[NSNotificationCenter defaultCenter] postNotificationName:kFIRAppReadyToConfigureSDKNotification + object:self + userInfo:appInfoDict]; + + // This is the new way of sending information to SDKs. + // TODO: Do we want this on a background thread, maybe? + @synchronized(self) { + for (Class library in sRegisteredAsConfigurable) { + [library configureWithApp:app]; + } + } +} + ++ (NSError *)errorForMissingOptions { + NSDictionary *errorDict = @{ + NSLocalizedDescriptionKey : + @"Unable to parse GoogleService-Info.plist in order to configure services.", + NSLocalizedRecoverySuggestionErrorKey : + @"Check formatting and location of GoogleService-Info.plist." + }; + return [NSError errorWithDomain:kFirebaseCoreErrorDomain + code:FIRErrorCodeInvalidPlistFile + userInfo:errorDict]; +} + ++ (NSError *)errorForSubspecConfigurationFailureWithDomain:(NSString *)domain + errorCode:(FIRErrorCode)code + service:(NSString *)service + reason:(NSString *)reason { + NSString *description = + [NSString stringWithFormat:@"Configuration failed for service %@.", service]; + NSDictionary *errorDict = + @{NSLocalizedDescriptionKey : description, NSLocalizedFailureReasonErrorKey : reason}; + return [NSError errorWithDomain:domain code:code userInfo:errorDict]; +} + ++ (NSError *)errorForInvalidAppID { + NSDictionary *errorDict = @{ + NSLocalizedDescriptionKey : @"Unable to validate Google App ID", + NSLocalizedRecoverySuggestionErrorKey : + @"Check formatting and location of GoogleService-Info.plist or GoogleAppID set in the " + @"customized options." + }; + return [NSError errorWithDomain:kFirebaseCoreErrorDomain + code:FIRErrorCodeInvalidAppID + userInfo:errorDict]; +} + ++ (BOOL)isDefaultAppConfigured { + return (sDefaultApp != nil); +} + ++ (void)registerLibrary:(nonnull NSString *)name withVersion:(nonnull NSString *)version { + // Create the set of characters which aren't allowed, only if this feature is used. + NSMutableCharacterSet *allowedSet = [NSMutableCharacterSet alphanumericCharacterSet]; + [allowedSet addCharactersInString:@"-_."]; + NSCharacterSet *disallowedSet = [allowedSet invertedSet]; + // Make sure the library name and version strings do not contain unexpected characters, and + // add the name/version pair to the dictionary. + if ([name rangeOfCharacterFromSet:disallowedSet].location == NSNotFound && + [version rangeOfCharacterFromSet:disallowedSet].location == NSNotFound) { + @synchronized(self) { + if (!sLibraryVersions) { + sLibraryVersions = [[NSMutableDictionary alloc] init]; + } + sLibraryVersions[name] = version; + } + } else { + FIRLogError(kFIRLoggerCore, @"I-COR000027", + @"The library name (%@) or version number (%@) contain invalid characters. " + @"Only alphanumeric, dash, underscore and period characters are allowed.", + name, version); + } +} + ++ (void)registerInternalLibrary:(nonnull Class)library + withName:(nonnull NSString *)name + withVersion:(nonnull NSString *)version { + // This is called at +load time, keep the work to a minimum. + + // Ensure the class given conforms to the proper protocol. + if (![(Class)library conformsToProtocol:@protocol(FIRLibrary)] || + ![(Class)library respondsToSelector:@selector(componentsToRegister)]) { + [NSException raise:NSInvalidArgumentException + format:@"Class %@ attempted to register components, but it does not conform to " + @"`FIRLibrary or provide a `componentsToRegister:` method.", + library]; + } + + [FIRComponentContainer registerAsComponentRegistrant:library]; + if ([(Class)library respondsToSelector:@selector(configureWithApp:)]) { + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + sRegisteredAsConfigurable = [[NSMutableArray alloc] init]; + }); + @synchronized(self) { + [sRegisteredAsConfigurable addObject:library]; + } + } + [self registerLibrary:name withVersion:version]; +} + ++ (NSString *)firebaseUserAgent { + @synchronized(self) { + NSMutableArray *libraries = + [[NSMutableArray alloc] initWithCapacity:sLibraryVersions.count]; + for (NSString *libraryName in sLibraryVersions) { + [libraries addObject:[NSString stringWithFormat:@"%@/%@", libraryName, + sLibraryVersions[libraryName]]]; + } + [libraries sortUsingSelector:@selector(localizedCaseInsensitiveCompare:)]; + return [libraries componentsJoinedByString:@" "]; + } +} + +- (void)checkExpectedBundleID { + NSArray *bundles = [FIRBundleUtil relevantBundles]; + NSString *expectedBundleID = [self expectedBundleID]; + // The checking is only done when the bundle ID is provided in the serviceInfo dictionary for + // backward compatibility. + if (expectedBundleID != nil && ![FIRBundleUtil hasBundleIdentifierPrefix:expectedBundleID + inBundles:bundles]) { + FIRLogError(kFIRLoggerCore, @"I-COR000008", + @"The project's Bundle ID is inconsistent with " + @"either the Bundle ID in '%@.%@', or the Bundle ID in the options if you are " + @"using a customized options. To ensure that everything can be configured " + @"correctly, you may need to make the Bundle IDs consistent. To continue with this " + @"plist file, you may change your app's bundle identifier to '%@'. Or you can " + @"download a new configuration file that matches your bundle identifier from %@ " + @"and replace the current one.", + kServiceInfoFileName, kServiceInfoFileType, expectedBundleID, kPlistURL); + } +} + +#pragma mark - private - App ID Validation + +/** + * Validates the format and fingerprint of the app ID contained in GOOGLE_APP_ID in the plist file. + * This is the main method for validating app ID. + * + * @return YES if the app ID fulfills the expected format and fingerprint, NO otherwise. + */ +- (BOOL)isAppIDValid { + NSString *appID = _options.googleAppID; + BOOL isValid = [FIRApp validateAppID:appID]; + if (!isValid) { + NSString *expectedBundleID = [self expectedBundleID]; + FIRLogError(kFIRLoggerCore, @"I-COR000009", + @"The GOOGLE_APP_ID either in the plist file " + @"'%@.%@' or the one set in the customized options is invalid. If you are using " + @"the plist file, use the iOS version of bundle identifier to download the file, " + @"and do not manually edit the GOOGLE_APP_ID. You may change your app's bundle " + @"identifier to '%@'. Or you can download a new configuration file that matches " + @"your bundle identifier from %@ and replace the current one.", + kServiceInfoFileName, kServiceInfoFileType, expectedBundleID, kPlistURL); + }; + return isValid; +} + ++ (BOOL)validateAppID:(NSString *)appID { + // Failing validation only occurs when we are sure we are looking at a V2 app ID and it does not + // have a valid fingerprint, otherwise we just warn about the potential issue. + if (!appID.length) { + return NO; + } + + NSScanner *stringScanner = [NSScanner scannerWithString:appID]; + stringScanner.charactersToBeSkipped = nil; + + NSString *appIDVersion; + if (![stringScanner scanCharactersFromSet:[NSCharacterSet decimalDigitCharacterSet] + intoString:&appIDVersion]) { + return NO; + } + + if (![stringScanner scanString:@":" intoString:NULL]) { + // appIDVersion must be separated by ":" + return NO; + } + + NSArray *knownVersions = @[ @"1" ]; + if (![knownVersions containsObject:appIDVersion]) { + // Permit unknown yet properly formatted app ID versions. + FIRLogInfo(kFIRLoggerCore, @"I-COR000010", @"Unknown GOOGLE_APP_ID version: %@", appIDVersion); + return YES; + } + + if (![self validateAppIDFormat:appID withVersion:appIDVersion]) { + return NO; + } + + if (![self validateAppIDFingerprint:appID withVersion:appIDVersion]) { + return NO; + } + + return YES; +} + ++ (NSString *)actualBundleID { + return [[NSBundle mainBundle] bundleIdentifier]; +} + +/** + * Validates that the format of the app ID string is what is expected based on the supplied version. + * The version must end in ":". + * + * For v1 app ids the format is expected to be + * '::ios:'. + * + * This method does not verify that the contents of the app id are correct, just that they fulfill + * the expected format. + * + * @param appID Contents of GOOGLE_APP_ID from the plist file. + * @param version Indicates what version of the app id format this string should be. + * @return YES if provided string fufills the expected format, NO otherwise. + */ ++ (BOOL)validateAppIDFormat:(NSString *)appID withVersion:(NSString *)version { + if (!appID.length || !version.length) { + return NO; + } + + NSScanner *stringScanner = [NSScanner scannerWithString:appID]; + stringScanner.charactersToBeSkipped = nil; + + // Skip version part + // '**::ios:' + if (![stringScanner scanString:version intoString:NULL]) { + // The version part is missing or mismatched + return NO; + } + + // Validate version part (see part between '*' symbols below) + // '*:*:ios:' + if (![stringScanner scanString:@":" intoString:NULL]) { + // appIDVersion must be separated by ":" + return NO; + } + + // Validate version part (see part between '*' symbols below) + // ':**:ios:'. + NSInteger projectNumber = NSNotFound; + if (![stringScanner scanInteger:&projectNumber]) { + // NO project number found. + return NO; + } + + // Validate version part (see part between '*' symbols below) + // ':*:*ios:'. + if (![stringScanner scanString:@":" intoString:NULL]) { + // The project number must be separated by ":" + return NO; + } + + // Validate version part (see part between '*' symbols below) + // '::*ios*:'. + NSString *platform; + if (![stringScanner scanUpToString:@":" intoString:&platform]) { + return NO; + } + + if (![platform isEqualToString:@"ios"]) { + // The platform must be @"ios" + return NO; + } + + // Validate version part (see part between '*' symbols below) + // '::ios*:*'. + if (![stringScanner scanString:@":" intoString:NULL]) { + // The platform must be separated by ":" + return NO; + } + + // Validate version part (see part between '*' symbols below) + // '::ios:**'. + unsigned long long fingerprint = NSNotFound; + if (![stringScanner scanHexLongLong:&fingerprint]) { + // Fingerprint part is missing + return NO; + } + + if (!stringScanner.isAtEnd) { + // There are not allowed characters in the fingerprint part + return NO; + } + + return YES; +} + +/** + * Validates that the fingerprint of the app ID string is what is expected based on the supplied + * version. + * + * Note that the v1 hash algorithm is not permitted on the client and cannot be fully validated. + * + * @param appID Contents of GOOGLE_APP_ID from the plist file. + * @param version Indicates what version of the app id format this string should be. + * @return YES if provided string fufills the expected fingerprint and the version is known, NO + * otherwise. + */ ++ (BOOL)validateAppIDFingerprint:(NSString *)appID withVersion:(NSString *)version { + // Extract the supplied fingerprint from the supplied app ID. + // This assumes the app ID format is the same for all known versions below. If the app ID format + // changes in future versions, the tokenizing of the app ID format will need to take into account + // the version of the app ID. + NSArray *components = [appID componentsSeparatedByString:@":"]; + if (components.count != 4) { + return NO; + } + + NSString *suppliedFingerprintString = components[3]; + if (!suppliedFingerprintString.length) { + return NO; + } + + uint64_t suppliedFingerprint; + NSScanner *scanner = [NSScanner scannerWithString:suppliedFingerprintString]; + if (![scanner scanHexLongLong:&suppliedFingerprint]) { + return NO; + } + + if ([version isEqual:@"1"]) { + // The v1 hash algorithm is not permitted on the client so the actual hash cannot be validated. + return YES; + } + + // Unknown version. + return NO; +} + +- (NSString *)expectedBundleID { + return _options.bundleID; +} + +// end App ID validation + +#pragma mark - Reading From Plist & User Defaults + +/** + * Clears the data collection switch from the standard NSUserDefaults for easier testing and + * readability. + */ +- (void)clearDataCollectionSwitchFromUserDefaults { + NSString *key = + [NSString stringWithFormat:kFIRGlobalAppDataCollectionEnabledDefaultsKeyFormat, self.name]; + [[NSUserDefaults standardUserDefaults] removeObjectForKey:key]; +} + +/** + * Reads the data collection switch from the standard NSUserDefaults for easier testing and + * readability. + */ ++ (nullable NSNumber *)readDataCollectionSwitchFromUserDefaultsForApp:(FIRApp *)app { + // Read the object in user defaults, and only return if it's an NSNumber. + NSString *key = + [NSString stringWithFormat:kFIRGlobalAppDataCollectionEnabledDefaultsKeyFormat, app.name]; + id collectionEnabledDefaultsObject = [[NSUserDefaults standardUserDefaults] objectForKey:key]; + if ([collectionEnabledDefaultsObject isKindOfClass:[NSNumber class]]) { + return collectionEnabledDefaultsObject; + } + + return nil; +} + +/** + * Reads the data collection switch from the Info.plist for easier testing and readability. Will + * only read once from the plist and return the cached value. + */ ++ (nullable NSNumber *)readDataCollectionSwitchFromPlist { + static NSNumber *collectionEnabledPlistObject; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + // Read the data from the `Info.plist`, only assign it if it's there and an NSNumber. + id plistValue = [[NSBundle mainBundle] + objectForInfoDictionaryKey:kFIRGlobalAppDataCollectionEnabledPlistKey]; + if (plistValue && [plistValue isKindOfClass:[NSNumber class]]) { + collectionEnabledPlistObject = (NSNumber *)plistValue; + } + }); + + return collectionEnabledPlistObject; +} + +#pragma mark - Sending Logs + +- (void)sendLogsWithServiceName:(NSString *)serviceName + version:(NSString *)version + error:(NSError *)error { + // If the user has manually turned off data collection, return and don't send logs. + if (![self isDataCollectionDefaultEnabled]) { + return; + } + + NSMutableDictionary *userInfo = [[NSMutableDictionary alloc] initWithDictionary:@{ + kFIRAppDiagnosticsConfigurationTypeKey : @(FIRConfigTypeSDK), + kFIRAppDiagnosticsSDKNameKey : serviceName, + kFIRAppDiagnosticsSDKVersionKey : version, + kFIRAppDiagnosticsFIRAppKey : self + }]; + if (error) { + userInfo[kFIRAppDiagnosticsErrorKey] = error; + } + [[NSNotificationCenter defaultCenter] postNotificationName:kFIRAppDiagnosticsNotification + object:nil + userInfo:userInfo]; +} + +@end diff --git a/FoodApp/Pods/FirebaseCore/Firebase/Core/FIRAppAssociationRegistration.m b/FoodApp/Pods/FirebaseCore/Firebase/Core/FIRAppAssociationRegistration.m new file mode 100644 index 0000000..2aecdab --- /dev/null +++ b/FoodApp/Pods/FirebaseCore/Firebase/Core/FIRAppAssociationRegistration.m @@ -0,0 +1,47 @@ +// Copyright 2017 Google +// +// 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. + +#import "Private/FIRAppAssociationRegistration.h" + +#import + +@implementation FIRAppAssociationRegistration + ++ (nullable id)registeredObjectWithHost:(id)host + key:(NSString *)key + creationBlock:(id _Nullable (^)(void))creationBlock { + @synchronized(self) { + SEL dictKey = @selector(registeredObjectWithHost:key:creationBlock:); + NSMutableDictionary *objectsByKey = objc_getAssociatedObject(host, dictKey); + if (!objectsByKey) { + objectsByKey = [[NSMutableDictionary alloc] init]; + objc_setAssociatedObject(host, dictKey, objectsByKey, OBJC_ASSOCIATION_RETAIN_NONATOMIC); + } + id obj = objectsByKey[key]; + NSValue *creationBlockBeingCalled = [NSValue valueWithPointer:dictKey]; + if (obj) { + if ([creationBlockBeingCalled isEqual:obj]) { + [NSException raise:@"Reentering registeredObjectWithHost:key:creationBlock: not allowed" + format:@"host: %@ key: %@", host, key]; + } + return obj; + } + objectsByKey[key] = creationBlockBeingCalled; + obj = creationBlock(); + objectsByKey[key] = obj; + return obj; + } +} + +@end diff --git a/FoodApp/Pods/FirebaseCore/Firebase/Core/FIRBundleUtil.m b/FoodApp/Pods/FirebaseCore/Firebase/Core/FIRBundleUtil.m new file mode 100644 index 0000000..841833a --- /dev/null +++ b/FoodApp/Pods/FirebaseCore/Firebase/Core/FIRBundleUtil.m @@ -0,0 +1,75 @@ +// Copyright 2017 Google +// +// 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. + +#import "Private/FIRBundleUtil.h" + +#import + +@implementation FIRBundleUtil + ++ (NSArray *)relevantBundles { + return @[ [NSBundle mainBundle], [NSBundle bundleForClass:[self class]] ]; +} + ++ (NSString *)optionsDictionaryPathWithResourceName:(NSString *)resourceName + andFileType:(NSString *)fileType + inBundles:(NSArray *)bundles { + // Loop through all bundles to find the config dict. + for (NSBundle *bundle in bundles) { + NSString *path = [bundle pathForResource:resourceName ofType:fileType]; + // Use the first one we find. + if (path) { + return path; + } + } + return nil; +} + ++ (NSArray *)relevantURLSchemes { + NSMutableArray *result = [[NSMutableArray alloc] init]; + for (NSBundle *bundle in [[self class] relevantBundles]) { + NSArray *urlTypes = [bundle objectForInfoDictionaryKey:@"CFBundleURLTypes"]; + for (NSDictionary *urlType in urlTypes) { + [result addObjectsFromArray:urlType[@"CFBundleURLSchemes"]]; + } + } + return result; +} + ++ (BOOL)hasBundleIdentifierPrefix:(NSString *)bundleIdentifier inBundles:(NSArray *)bundles { + for (NSBundle *bundle in bundles) { + // This allows app extensions that have the app's bundle as their prefix to pass this test. + NSString *applicationBundleIdentifier = + [GULAppEnvironmentUtil isAppExtension] + ? [self bundleIdentifierByRemovingLastPartFrom:bundleIdentifier] + : bundleIdentifier; + + if ([applicationBundleIdentifier isEqualToString:bundle.bundleIdentifier]) { + return YES; + } + } + return NO; +} + ++ (NSString *)bundleIdentifierByRemovingLastPartFrom:(NSString *)bundleIdentifier { + NSString *bundleIDComponentsSeparator = @"."; + + NSMutableArray *bundleIDComponents = + [[bundleIdentifier componentsSeparatedByString:bundleIDComponentsSeparator] mutableCopy]; + [bundleIDComponents removeLastObject]; + + return [bundleIDComponents componentsJoinedByString:bundleIDComponentsSeparator]; +} + +@end diff --git a/FoodApp/Pods/FirebaseCore/Firebase/Core/FIRComponent.m b/FoodApp/Pods/FirebaseCore/Firebase/Core/FIRComponent.m new file mode 100644 index 0000000..2474d1a --- /dev/null +++ b/FoodApp/Pods/FirebaseCore/Firebase/Core/FIRComponent.m @@ -0,0 +1,65 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#import "Private/FIRComponent.h" + +#import "Private/FIRComponentContainer.h" +#import "Private/FIRDependency.h" + +@interface FIRComponent () + +- (instancetype)initWithProtocol:(Protocol *)protocol + instantiationTiming:(FIRInstantiationTiming)instantiationTiming + dependencies:(NSArray *)dependencies + creationBlock:(FIRComponentCreationBlock)creationBlock; + +@end + +@implementation FIRComponent + ++ (instancetype)componentWithProtocol:(Protocol *)protocol + creationBlock:(FIRComponentCreationBlock)creationBlock { + return [[FIRComponent alloc] initWithProtocol:protocol + instantiationTiming:FIRInstantiationTimingLazy + dependencies:@[] + creationBlock:creationBlock]; +} + ++ (instancetype)componentWithProtocol:(Protocol *)protocol + instantiationTiming:(FIRInstantiationTiming)instantiationTiming + dependencies:(NSArray *)dependencies + creationBlock:(FIRComponentCreationBlock)creationBlock { + return [[FIRComponent alloc] initWithProtocol:protocol + instantiationTiming:instantiationTiming + dependencies:dependencies + creationBlock:creationBlock]; +} + +- (instancetype)initWithProtocol:(Protocol *)protocol + instantiationTiming:(FIRInstantiationTiming)instantiationTiming + dependencies:(NSArray *)dependencies + creationBlock:(FIRComponentCreationBlock)creationBlock { + self = [super init]; + if (self) { + _protocol = protocol; + _instantiationTiming = instantiationTiming; + _dependencies = [dependencies copy]; + _creationBlock = creationBlock; + } + return self; +} + +@end diff --git a/FoodApp/Pods/FirebaseCore/Firebase/Core/FIRComponentContainer.m b/FoodApp/Pods/FirebaseCore/Firebase/Core/FIRComponentContainer.m new file mode 100644 index 0000000..1977d0e --- /dev/null +++ b/FoodApp/Pods/FirebaseCore/Firebase/Core/FIRComponentContainer.m @@ -0,0 +1,176 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#import "Private/FIRComponentContainer.h" + +#import "Private/FIRAppInternal.h" +#import "Private/FIRComponent.h" +#import "Private/FIRLibrary.h" +#import "Private/FIRLogger.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface FIRComponentContainer () + +/// The dictionary of components that are registered for a particular app. The key is an NSString +/// of the protocol. +@property(nonatomic, strong) NSMutableDictionary *components; + +/// Cached instances of components that requested to be cached. +@property(nonatomic, strong) NSMutableDictionary *cachedInstances; + +@end + +@implementation FIRComponentContainer + +// Collection of all classes that register to provide components. +static NSMutableSet *sFIRComponentRegistrants; + +#pragma mark - Public Registration + ++ (void)registerAsComponentRegistrant:(Class)klass { + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + sFIRComponentRegistrants = [[NSMutableSet alloc] init]; + }); + + [self registerAsComponentRegistrant:klass inSet:sFIRComponentRegistrants]; +} + ++ (void)registerAsComponentRegistrant:(Class)klass + inSet:(NSMutableSet *)allRegistrants { + [allRegistrants addObject:klass]; +} + +#pragma mark - Internal Initialization + +- (instancetype)initWithApp:(FIRApp *)app { + return [self initWithApp:app registrants:sFIRComponentRegistrants]; +} + +- (instancetype)initWithApp:(FIRApp *)app registrants:(NSMutableSet *)allRegistrants { + self = [super init]; + if (self) { + _app = app; + _cachedInstances = [NSMutableDictionary dictionary]; + _components = [NSMutableDictionary dictionary]; + + [self populateComponentsFromRegisteredClasses:allRegistrants forApp:app]; + } + return self; +} + +- (void)populateComponentsFromRegisteredClasses:(NSSet *)classes forApp:(FIRApp *)app { + // Loop through the verified component registrants and populate the components array. + for (Class klass in classes) { + // Loop through all the components being registered and store them as appropriate. + // Classes which do not provide functionality should use a dummy FIRComponentRegistrant + // protocol. + for (FIRComponent *component in [klass componentsToRegister]) { + // Check if the component has been registered before, and error out if so. + NSString *protocolName = NSStringFromProtocol(component.protocol); + if (self.components[protocolName]) { + FIRLogError(kFIRLoggerCore, @"I-COR000029", + @"Attempted to register protocol %@, but it already has an implementation.", + protocolName); + continue; + } + + // Store the creation block for later usage. + self.components[protocolName] = component.creationBlock; + + // Instantiate the + BOOL shouldInstantiateEager = + (component.instantiationTiming == FIRInstantiationTimingAlwaysEager); + BOOL shouldInstantiateDefaultEager = + (component.instantiationTiming == FIRInstantiationTimingEagerInDefaultApp && + [app isDefaultApp]); + if (shouldInstantiateEager || shouldInstantiateDefaultEager) { + [self instantiateInstanceForProtocol:component.protocol withBlock:component.creationBlock]; + } + } + } +} + +#pragma mark - Instance Creation + +/// Instantiate an instance of a class that conforms to the specified protocol. +/// This will: +/// - Call the block to create an instance if possible, +/// - Validate that the instance returned conforms to the protocol it claims to, +/// - Cache the instance if the block requests it +- (nullable id)instantiateInstanceForProtocol:(Protocol *)protocol + withBlock:(FIRComponentCreationBlock)creationBlock { + if (!creationBlock) { + return nil; + } + + // Create an instance using the creation block. + BOOL shouldCache = NO; + id instance = creationBlock(self, &shouldCache); + if (!instance) { + return nil; + } + + // An instance was created, validate that it conforms to the protocol it claims to. + NSString *protocolName = NSStringFromProtocol(protocol); + if (![instance conformsToProtocol:protocol]) { + FIRLogError(kFIRLoggerCore, @"I-COR000030", + @"An instance conforming to %@ was requested, but the instance provided does not " + @"conform to the protocol", + protocolName); + } + + // The instance is ready to be returned, but check if it should be cached first before returning. + if (shouldCache) { + self.cachedInstances[protocolName] = instance; + } + + return instance; +} + +#pragma mark - Internal Retrieval + +- (nullable id)instanceForProtocol:(Protocol *)protocol { + // Check if there is a cached instance, and return it if so. + NSString *protocolName = NSStringFromProtocol(protocol); + id cachedInstance = self.cachedInstances[protocolName]; + if (cachedInstance) { + return cachedInstance; + } + + // Use the creation block to instantiate an instance and return it. + FIRComponentCreationBlock creationBlock = self.components[protocolName]; + return [self instantiateInstanceForProtocol:protocol withBlock:creationBlock]; +} + +#pragma mark - Lifecycle + +- (void)removeAllCachedInstances { + // Loop through the cache and notify each instance that is a maintainer to clean up after itself. + for (id instance in self.cachedInstances.allValues) { + if ([instance conformsToProtocol:@protocol(FIRComponentLifecycleMaintainer)] && + [instance respondsToSelector:@selector(appWillBeDeleted:)]) { + [instance appWillBeDeleted:self.app]; + } + } + + [self.cachedInstances removeAllObjects]; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseCore/Firebase/Core/FIRComponentType.m b/FoodApp/Pods/FirebaseCore/Firebase/Core/FIRComponentType.m new file mode 100644 index 0000000..bdc004f --- /dev/null +++ b/FoodApp/Pods/FirebaseCore/Firebase/Core/FIRComponentType.m @@ -0,0 +1,28 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#import "Private/FIRComponentType.h" + +#import "Private/FIRComponentContainerInternal.h" + +@implementation FIRComponentType + ++ (id)instanceForProtocol:(Protocol *)protocol inContainer:(FIRComponentContainer *)container { + // Forward the call to the container. + return [container instanceForProtocol:protocol]; +} + +@end diff --git a/FoodApp/Pods/FirebaseCore/Firebase/Core/FIRConfiguration.m b/FoodApp/Pods/FirebaseCore/Firebase/Core/FIRConfiguration.m new file mode 100644 index 0000000..f8378d7 --- /dev/null +++ b/FoodApp/Pods/FirebaseCore/Firebase/Core/FIRConfiguration.m @@ -0,0 +1,47 @@ +// Copyright 2017 Google +// +// 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. + +#import "FIRConfiguration.h" + +extern void FIRSetLoggerLevel(FIRLoggerLevel loggerLevel); + +@implementation FIRConfiguration + ++ (instancetype)sharedInstance { + static FIRConfiguration *sharedInstance = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + sharedInstance = [[FIRConfiguration alloc] init]; + }); + return sharedInstance; +} + +- (instancetype)init { + self = [super init]; + if (self) { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + _analyticsConfiguration = [FIRAnalyticsConfiguration sharedInstance]; +#pragma clang diagnostic pop + } + return self; +} + +- (void)setLoggerLevel:(FIRLoggerLevel)loggerLevel { + NSAssert(loggerLevel <= FIRLoggerLevelMax && loggerLevel >= FIRLoggerLevelMin, + @"Invalid logger level, %ld", (long)loggerLevel); + FIRSetLoggerLevel(loggerLevel); +} + +@end diff --git a/FoodApp/Pods/FirebaseCore/Firebase/Core/FIRDependency.m b/FoodApp/Pods/FirebaseCore/Firebase/Core/FIRDependency.m new file mode 100644 index 0000000..f979984 --- /dev/null +++ b/FoodApp/Pods/FirebaseCore/Firebase/Core/FIRDependency.m @@ -0,0 +1,44 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#import "Private/FIRDependency.h" + +@interface FIRDependency () + +- (instancetype)initWithProtocol:(Protocol *)protocol isRequired:(BOOL)required; + +@end + +@implementation FIRDependency + ++ (instancetype)dependencyWithProtocol:(Protocol *)protocol { + return [[self alloc] initWithProtocol:protocol isRequired:YES]; +} + ++ (instancetype)dependencyWithProtocol:(Protocol *)protocol isRequired:(BOOL)required { + return [[self alloc] initWithProtocol:protocol isRequired:required]; +} + +- (instancetype)initWithProtocol:(Protocol *)protocol isRequired:(BOOL)required { + self = [super init]; + if (self) { + _protocol = protocol; + _isRequired = required; + } + return self; +} + +@end diff --git a/FoodApp/Pods/FirebaseCore/Firebase/Core/FIRErrors.m b/FoodApp/Pods/FirebaseCore/Firebase/Core/FIRErrors.m new file mode 100644 index 0000000..6d6d52d --- /dev/null +++ b/FoodApp/Pods/FirebaseCore/Firebase/Core/FIRErrors.m @@ -0,0 +1,29 @@ +// Copyright 2017 Google +// +// 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. + +#import "Private/FIRErrors.h" + +NSString *const kFirebaseErrorDomain = @"com.firebase"; +NSString *const kFirebaseAdMobErrorDomain = @"com.firebase.admob"; +NSString *const kFirebaseAppInviteErrorDomain = @"com.firebase.appinvite"; +NSString *const kFirebaseAuthErrorDomain = @"com.firebase.auth"; +NSString *const kFirebaseCloudMessagingErrorDomain = @"com.firebase.cloudmessaging"; +NSString *const kFirebaseConfigErrorDomain = @"com.firebase.config"; +NSString *const kFirebaseCoreErrorDomain = @"com.firebase.core"; +NSString *const kFirebaseCrashReportingErrorDomain = @"com.firebase.crashreporting"; +NSString *const kFirebaseDatabaseErrorDomain = @"com.firebase.database"; +NSString *const kFirebaseDurableDeepLinkErrorDomain = @"com.firebase.durabledeeplink"; +NSString *const kFirebaseInstanceIDErrorDomain = @"com.firebase.instanceid"; +NSString *const kFirebasePerfErrorDomain = @"com.firebase.perf"; +NSString *const kFirebaseStorageErrorDomain = @"com.firebase.storage"; diff --git a/FoodApp/Pods/FirebaseCore/Firebase/Core/FIRLogger.m b/FoodApp/Pods/FirebaseCore/Firebase/Core/FIRLogger.m new file mode 100644 index 0000000..d1e3b37 --- /dev/null +++ b/FoodApp/Pods/FirebaseCore/Firebase/Core/FIRLogger.m @@ -0,0 +1,185 @@ +// Copyright 2017 Google +// +// 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. + +#import "Private/FIRLogger.h" + +#import +#import +#import + +#import "Private/FIRVersion.h" + +FIRLoggerService kFIRLoggerABTesting = @"[Firebase/ABTesting]"; +FIRLoggerService kFIRLoggerAdMob = @"[Firebase/AdMob]"; +FIRLoggerService kFIRLoggerAnalytics = @"[Firebase/Analytics]"; +FIRLoggerService kFIRLoggerAuth = @"[Firebase/Auth]"; +FIRLoggerService kFIRLoggerCore = @"[Firebase/Core]"; +FIRLoggerService kFIRLoggerCrash = @"[Firebase/Crash]"; +FIRLoggerService kFIRLoggerDatabase = @"[Firebase/Database]"; +FIRLoggerService kFIRLoggerDynamicLinks = @"[Firebase/DynamicLinks]"; +FIRLoggerService kFIRLoggerFirestore = @"[Firebase/Firestore]"; +FIRLoggerService kFIRLoggerInstanceID = @"[Firebase/InstanceID]"; +FIRLoggerService kFIRLoggerInvites = @"[Firebase/Invites]"; +FIRLoggerService kFIRLoggerMLKit = @"[Firebase/MLKit]"; +FIRLoggerService kFIRLoggerMessaging = @"[Firebase/Messaging]"; +FIRLoggerService kFIRLoggerPerf = @"[Firebase/Performance]"; +FIRLoggerService kFIRLoggerRemoteConfig = @"[Firebase/RemoteConfig]"; +FIRLoggerService kFIRLoggerStorage = @"[Firebase/Storage]"; +FIRLoggerService kFIRLoggerSwizzler = @"[FirebaseSwizzlingUtilities]"; + +/// Arguments passed on launch. +NSString *const kFIRDisableDebugModeApplicationArgument = @"-FIRDebugDisabled"; +NSString *const kFIREnableDebugModeApplicationArgument = @"-FIRDebugEnabled"; +NSString *const kFIRLoggerForceSDTERRApplicationArgument = @"-FIRLoggerForceSTDERR"; + +/// Key for the debug mode bit in NSUserDefaults. +NSString *const kFIRPersistedDebugModeKey = @"/google/firebase/debug_mode"; + +/// NSUserDefaults that should be used to store and read variables. If nil, `standardUserDefaults` +/// will be used. +static NSUserDefaults *sFIRLoggerUserDefaults; + +static dispatch_once_t sFIRLoggerOnceToken; + +// The sFIRAnalyticsDebugMode flag is here to support the -FIRDebugEnabled/-FIRDebugDisabled +// flags used by Analytics. Users who use those flags expect Analytics to log verbosely, +// while the rest of Firebase logs at the default level. This flag is introduced to support +// that behavior. +static BOOL sFIRAnalyticsDebugMode; + +#ifdef DEBUG +/// The regex pattern for the message code. +static NSString *const kMessageCodePattern = @"^I-[A-Z]{3}[0-9]{6}$"; +static NSRegularExpression *sMessageCodeRegex; +#endif + +void FIRLoggerInitializeASL() { + dispatch_once(&sFIRLoggerOnceToken, ^{ + // Register Firebase Version with GULLogger. + GULLoggerRegisterVersion(FIRVersionString); + + // Override the aslOptions to ASL_OPT_STDERR if the override argument is passed in. + NSArray *arguments = [NSProcessInfo processInfo].arguments; + BOOL overrideSTDERR = [arguments containsObject:kFIRLoggerForceSDTERRApplicationArgument]; + + // Use the standard NSUserDefaults if it hasn't been explicitly set. + if (sFIRLoggerUserDefaults == nil) { + sFIRLoggerUserDefaults = [NSUserDefaults standardUserDefaults]; + } + + BOOL forceDebugMode = NO; + BOOL debugMode = [sFIRLoggerUserDefaults boolForKey:kFIRPersistedDebugModeKey]; + if ([arguments containsObject:kFIRDisableDebugModeApplicationArgument]) { // Default mode + [sFIRLoggerUserDefaults removeObjectForKey:kFIRPersistedDebugModeKey]; + } else if ([arguments containsObject:kFIREnableDebugModeApplicationArgument] || + debugMode) { // Debug mode + [sFIRLoggerUserDefaults setBool:YES forKey:kFIRPersistedDebugModeKey]; + forceDebugMode = YES; + } + GULLoggerInitializeASL(); + if (overrideSTDERR) { + GULLoggerEnableSTDERR(); + } + if (forceDebugMode) { + GULLoggerForceDebug(); + } + }); +} + +__attribute__((no_sanitize("thread"))) void FIRSetAnalyticsDebugMode(BOOL analyticsDebugMode) { + sFIRAnalyticsDebugMode = analyticsDebugMode; +} + +void FIRSetLoggerLevel(FIRLoggerLevel loggerLevel) { + FIRLoggerInitializeASL(); + GULSetLoggerLevel((GULLoggerLevel)loggerLevel); +} + +#ifdef DEBUG +void FIRResetLogger() { + extern void GULResetLogger(void); + sFIRLoggerOnceToken = 0; + [sFIRLoggerUserDefaults removeObjectForKey:kFIRPersistedDebugModeKey]; + sFIRLoggerUserDefaults = nil; + GULResetLogger(); +} + +void FIRSetLoggerUserDefaults(NSUserDefaults *defaults) { + sFIRLoggerUserDefaults = defaults; +} +#endif + +/** + * Check if the level is high enough to be loggable. + * + * Analytics can override the log level with an intentional race condition. + * Add the attribute to get a clean thread sanitizer run. + */ +__attribute__((no_sanitize("thread"))) BOOL FIRIsLoggableLevel(FIRLoggerLevel loggerLevel, + BOOL analyticsComponent) { + FIRLoggerInitializeASL(); + if (sFIRAnalyticsDebugMode && analyticsComponent) { + return YES; + } + return GULIsLoggableLevel((GULLoggerLevel)loggerLevel); +} + +void FIRLogBasic(FIRLoggerLevel level, + FIRLoggerService service, + NSString *messageCode, + NSString *message, + va_list args_ptr) { + FIRLoggerInitializeASL(); + GULLogBasic((GULLoggerLevel)level, service, + sFIRAnalyticsDebugMode && [kFIRLoggerAnalytics isEqualToString:service], messageCode, + message, args_ptr); +} + +/** + * Generates the logging functions using macros. + * + * Calling FIRLogError(kFIRLoggerCore, @"I-COR000001", @"Configure %@ failed.", @"blah") shows: + * yyyy-mm-dd hh:mm:ss.SSS sender[PID] [Firebase/Core][I-COR000001] Configure blah failed. + * Calling FIRLogDebug(kFIRLoggerCore, @"I-COR000001", @"Configure succeed.") shows: + * yyyy-mm-dd hh:mm:ss.SSS sender[PID] [Firebase/Core][I-COR000001] Configure succeed. + */ +#define FIR_LOGGING_FUNCTION(level) \ + void FIRLog##level(FIRLoggerService service, NSString *messageCode, NSString *message, ...) { \ + va_list args_ptr; \ + va_start(args_ptr, message); \ + FIRLogBasic(FIRLoggerLevel##level, service, messageCode, message, args_ptr); \ + va_end(args_ptr); \ + } + +FIR_LOGGING_FUNCTION(Error) +FIR_LOGGING_FUNCTION(Warning) +FIR_LOGGING_FUNCTION(Notice) +FIR_LOGGING_FUNCTION(Info) +FIR_LOGGING_FUNCTION(Debug) + +#undef FIR_MAKE_LOGGER + +#pragma mark - FIRLoggerWrapper + +@implementation FIRLoggerWrapper + ++ (void)logWithLevel:(FIRLoggerLevel)level + withService:(FIRLoggerService)service + withCode:(NSString *)messageCode + withMessage:(NSString *)message + withArgs:(va_list)args { + FIRLogBasic(level, service, messageCode, message, args); +} + +@end diff --git a/FoodApp/Pods/FirebaseCore/Firebase/Core/FIROptions.m b/FoodApp/Pods/FirebaseCore/Firebase/Core/FIROptions.m new file mode 100644 index 0000000..72901f5 --- /dev/null +++ b/FoodApp/Pods/FirebaseCore/Firebase/Core/FIROptions.m @@ -0,0 +1,443 @@ +// Copyright 2017 Google +// +// 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. + +#import "Private/FIRAppInternal.h" +#import "Private/FIRBundleUtil.h" +#import "Private/FIRErrors.h" +#import "Private/FIRLogger.h" +#import "Private/FIROptionsInternal.h" + +// Keys for the strings in the plist file. +NSString *const kFIRAPIKey = @"API_KEY"; +NSString *const kFIRTrackingID = @"TRACKING_ID"; +NSString *const kFIRGoogleAppID = @"GOOGLE_APP_ID"; +NSString *const kFIRClientID = @"CLIENT_ID"; +NSString *const kFIRGCMSenderID = @"GCM_SENDER_ID"; +NSString *const kFIRAndroidClientID = @"ANDROID_CLIENT_ID"; +NSString *const kFIRDatabaseURL = @"DATABASE_URL"; +NSString *const kFIRStorageBucket = @"STORAGE_BUCKET"; +// The key to locate the expected bundle identifier in the plist file. +NSString *const kFIRBundleID = @"BUNDLE_ID"; +// The key to locate the project identifier in the plist file. +NSString *const kFIRProjectID = @"PROJECT_ID"; + +NSString *const kFIRIsMeasurementEnabled = @"IS_MEASUREMENT_ENABLED"; +NSString *const kFIRIsAnalyticsCollectionEnabled = @"FIREBASE_ANALYTICS_COLLECTION_ENABLED"; +NSString *const kFIRIsAnalyticsCollectionDeactivated = @"FIREBASE_ANALYTICS_COLLECTION_DEACTIVATED"; + +NSString *const kFIRIsAnalyticsEnabled = @"IS_ANALYTICS_ENABLED"; +NSString *const kFIRIsSignInEnabled = @"IS_SIGNIN_ENABLED"; + +// Library version ID. +NSString *const kFIRLibraryVersionID = @"5" // Major version (one or more digits) + @"04" // Minor version (exactly 2 digits) + @"01" // Build number (exactly 2 digits) + @"000"; // Fixed "000" +// Plist file name. +NSString *const kServiceInfoFileName = @"GoogleService-Info"; +// Plist file type. +NSString *const kServiceInfoFileType = @"plist"; + +// Exception raised from attempting to modify a FIROptions after it's been copied to a FIRApp. +NSString *const kFIRExceptionBadModification = + @"Attempted to modify options after it's set on FIRApp. Please modify all properties before " + @"initializing FIRApp."; + +@interface FIROptions () + +/** + * This property maintains the actual configuration key-value pairs. + */ +@property(nonatomic, readwrite) NSMutableDictionary *optionsDictionary; + +/** + * Calls `analyticsOptionsDictionaryWithInfoDictionary:` using [NSBundle mainBundle].infoDictionary. + * It combines analytics options from both the infoDictionary and the GoogleService-Info.plist. + * Values which are present in the main plist override values from the GoogleService-Info.plist. + */ +@property(nonatomic, readonly) NSDictionary *analyticsOptionsDictionary; + +/** + * Combination of analytics options from both the infoDictionary and the GoogleService-Info.plist. + * Values which are present in the infoDictionary override values from the GoogleService-Info.plist. + */ +- (NSDictionary *)analyticsOptionsDictionaryWithInfoDictionary:(NSDictionary *)infoDictionary; + +/** + * Throw exception if editing is locked when attempting to modify an option. + */ +- (void)checkEditingLocked; + +@end + +@implementation FIROptions { + /// Backing variable for self.analyticsOptionsDictionary. + NSDictionary *_analyticsOptionsDictionary; +} + +static FIROptions *sDefaultOptions = nil; +static NSDictionary *sDefaultOptionsDictionary = nil; + +#pragma mark - Public only for internal class methods + ++ (FIROptions *)defaultOptions { + if (sDefaultOptions != nil) { + return sDefaultOptions; + } + + NSDictionary *defaultOptionsDictionary = [self defaultOptionsDictionary]; + if (defaultOptionsDictionary == nil) { + return nil; + } + + sDefaultOptions = [[FIROptions alloc] initInternalWithOptionsDictionary:defaultOptionsDictionary]; + return sDefaultOptions; +} + +#pragma mark - Private class methods + ++ (void)initialize { + // Report FirebaseCore version for useragent string + NSRange major = NSMakeRange(0, 1); + NSRange minor = NSMakeRange(1, 2); + NSRange patch = NSMakeRange(3, 2); + [FIRApp + registerLibrary:@"fire-ios" + withVersion:[NSString stringWithFormat:@"%@.%d.%d", + [kFIRLibraryVersionID substringWithRange:major], + [[kFIRLibraryVersionID substringWithRange:minor] + intValue], + [[kFIRLibraryVersionID substringWithRange:patch] + intValue]]]; + NSDictionary *info = [[NSBundle mainBundle] infoDictionary]; + NSString *xcodeVersion = info[@"DTXcodeBuild"]; + NSString *sdkVersion = info[@"DTSDKBuild"]; + if (xcodeVersion) { + [FIRApp registerLibrary:@"xcode" withVersion:xcodeVersion]; + } + if (sdkVersion) { + [FIRApp registerLibrary:@"apple-sdk" withVersion:sdkVersion]; + } +} + ++ (NSDictionary *)defaultOptionsDictionary { + if (sDefaultOptionsDictionary != nil) { + return sDefaultOptionsDictionary; + } + NSString *plistFilePath = [FIROptions plistFilePathWithName:kServiceInfoFileName]; + if (plistFilePath == nil) { + return nil; + } + sDefaultOptionsDictionary = [NSDictionary dictionaryWithContentsOfFile:plistFilePath]; + if (sDefaultOptionsDictionary == nil) { + FIRLogError(kFIRLoggerCore, @"I-COR000011", + @"The configuration file is not a dictionary: " + @"'%@.%@'.", + kServiceInfoFileName, kServiceInfoFileType); + } + return sDefaultOptionsDictionary; +} + +// Returns the path of the plist file with a given file name. ++ (NSString *)plistFilePathWithName:(NSString *)fileName { + NSArray *bundles = [FIRBundleUtil relevantBundles]; + NSString *plistFilePath = + [FIRBundleUtil optionsDictionaryPathWithResourceName:fileName + andFileType:kServiceInfoFileType + inBundles:bundles]; + if (plistFilePath == nil) { + FIRLogError(kFIRLoggerCore, @"I-COR000012", @"Could not locate configuration file: '%@.%@'.", + fileName, kServiceInfoFileType); + } + return plistFilePath; +} + ++ (void)resetDefaultOptions { + sDefaultOptions = nil; + sDefaultOptionsDictionary = nil; +} + +#pragma mark - Private instance methods + +- (instancetype)initInternalWithOptionsDictionary:(NSDictionary *)optionsDictionary { + self = [super init]; + if (self) { + _optionsDictionary = [optionsDictionary mutableCopy]; + _usingOptionsFromDefaultPlist = YES; + } + return self; +} + +- (id)copyWithZone:(NSZone *)zone { + FIROptions *newOptions = [[[self class] allocWithZone:zone] init]; + if (newOptions) { + newOptions.optionsDictionary = self.optionsDictionary; + newOptions.deepLinkURLScheme = self.deepLinkURLScheme; + newOptions.editingLocked = self.isEditingLocked; + newOptions.usingOptionsFromDefaultPlist = self.usingOptionsFromDefaultPlist; + } + return newOptions; +} + +#pragma mark - Public instance methods + +- (instancetype)initWithContentsOfFile:(NSString *)plistPath { + self = [super init]; + if (self) { + if (plistPath == nil) { + FIRLogError(kFIRLoggerCore, @"I-COR000013", @"The plist file path is nil."); + return nil; + } + _optionsDictionary = [[NSDictionary dictionaryWithContentsOfFile:plistPath] mutableCopy]; + if (_optionsDictionary == nil) { + FIRLogError(kFIRLoggerCore, @"I-COR000014", + @"The configuration file at %@ does not exist or " + @"is not a well-formed plist file.", + plistPath); + return nil; + } + // TODO: Do we want to validate the dictionary here? It says we do that already in + // the public header. + } + return self; +} + +- (instancetype)initWithGoogleAppID:(NSString *)googleAppID GCMSenderID:(NSString *)GCMSenderID { + self = [super init]; + if (self) { + NSMutableDictionary *mutableOptionsDict = [NSMutableDictionary dictionary]; + [mutableOptionsDict setValue:googleAppID forKey:kFIRGoogleAppID]; + [mutableOptionsDict setValue:GCMSenderID forKey:kFIRGCMSenderID]; + [mutableOptionsDict setValue:[[NSBundle mainBundle] bundleIdentifier] forKey:kFIRBundleID]; + self.optionsDictionary = mutableOptionsDict; + } + return self; +} + +- (NSString *)APIKey { + return self.optionsDictionary[kFIRAPIKey]; +} + +- (void)checkEditingLocked { + if (self.isEditingLocked) { + [NSException raise:kFirebaseCoreErrorDomain format:kFIRExceptionBadModification]; + } +} + +- (void)setAPIKey:(NSString *)APIKey { + [self checkEditingLocked]; + _optionsDictionary[kFIRAPIKey] = [APIKey copy]; +} + +- (NSString *)clientID { + return self.optionsDictionary[kFIRClientID]; +} + +- (void)setClientID:(NSString *)clientID { + [self checkEditingLocked]; + _optionsDictionary[kFIRClientID] = [clientID copy]; +} + +- (NSString *)trackingID { + return self.optionsDictionary[kFIRTrackingID]; +} + +- (void)setTrackingID:(NSString *)trackingID { + [self checkEditingLocked]; + _optionsDictionary[kFIRTrackingID] = [trackingID copy]; +} + +- (NSString *)GCMSenderID { + return self.optionsDictionary[kFIRGCMSenderID]; +} + +- (void)setGCMSenderID:(NSString *)GCMSenderID { + [self checkEditingLocked]; + _optionsDictionary[kFIRGCMSenderID] = [GCMSenderID copy]; +} + +- (NSString *)projectID { + return self.optionsDictionary[kFIRProjectID]; +} + +- (void)setProjectID:(NSString *)projectID { + [self checkEditingLocked]; + _optionsDictionary[kFIRProjectID] = [projectID copy]; +} + +- (NSString *)androidClientID { + return self.optionsDictionary[kFIRAndroidClientID]; +} + +- (void)setAndroidClientID:(NSString *)androidClientID { + [self checkEditingLocked]; + _optionsDictionary[kFIRAndroidClientID] = [androidClientID copy]; +} + +- (NSString *)googleAppID { + return self.optionsDictionary[kFIRGoogleAppID]; +} + +- (void)setGoogleAppID:(NSString *)googleAppID { + [self checkEditingLocked]; + _optionsDictionary[kFIRGoogleAppID] = [googleAppID copy]; +} + +- (NSString *)libraryVersionID { + return kFIRLibraryVersionID; +} + +- (void)setLibraryVersionID:(NSString *)libraryVersionID { + _optionsDictionary[kFIRLibraryVersionID] = [libraryVersionID copy]; +} + +- (NSString *)databaseURL { + return self.optionsDictionary[kFIRDatabaseURL]; +} + +- (void)setDatabaseURL:(NSString *)databaseURL { + [self checkEditingLocked]; + + _optionsDictionary[kFIRDatabaseURL] = [databaseURL copy]; +} + +- (NSString *)storageBucket { + return self.optionsDictionary[kFIRStorageBucket]; +} + +- (void)setStorageBucket:(NSString *)storageBucket { + [self checkEditingLocked]; + _optionsDictionary[kFIRStorageBucket] = [storageBucket copy]; +} + +- (void)setDeepLinkURLScheme:(NSString *)deepLinkURLScheme { + [self checkEditingLocked]; + _deepLinkURLScheme = [deepLinkURLScheme copy]; +} + +- (NSString *)bundleID { + return self.optionsDictionary[kFIRBundleID]; +} + +- (void)setBundleID:(NSString *)bundleID { + [self checkEditingLocked]; + _optionsDictionary[kFIRBundleID] = [bundleID copy]; +} + +#pragma mark - Internal instance methods + +- (NSDictionary *)analyticsOptionsDictionaryWithInfoDictionary:(NSDictionary *)infoDictionary { + if (_analyticsOptionsDictionary == nil) { + NSMutableDictionary *tempAnalyticsOptions = [[NSMutableDictionary alloc] init]; + NSArray *measurementKeys = @[ + kFIRIsMeasurementEnabled, kFIRIsAnalyticsCollectionEnabled, + kFIRIsAnalyticsCollectionDeactivated + ]; + for (NSString *key in measurementKeys) { + id value = infoDictionary[key] ?: self.optionsDictionary[key] ?: nil; + if (!value) { + continue; + } + tempAnalyticsOptions[key] = value; + } + _analyticsOptionsDictionary = tempAnalyticsOptions; + } + return _analyticsOptionsDictionary; +} + +- (NSDictionary *)analyticsOptionsDictionary { + return [self analyticsOptionsDictionaryWithInfoDictionary:[NSBundle mainBundle].infoDictionary]; +} + +/** + * Whether or not Measurement was enabled. Measurement is enabled unless explicitly disabled in + * GoogleService-Info.plist. This uses the old plist flag IS_MEASUREMENT_ENABLED, which should still + * be supported. + */ +- (BOOL)isMeasurementEnabled { + if (self.isAnalyticsCollectionDeactivated) { + return NO; + } + NSNumber *value = self.analyticsOptionsDictionary[kFIRIsMeasurementEnabled]; + if (value == nil) { + // TODO: This could probably be cleaned up since FIROptions shouldn't know about FIRApp or have + // to check if it's the default app. The FIROptions instance can't be modified after + // `+configure` is called, so it's not a good place to copy it either in case the flag is + // changed at runtime. + + // If no values are set for Analytics, fall back to the global collection switch in FIRApp. + // Analytics only supports the default FIRApp, so check that first. + if (![FIRApp isDefaultAppConfigured]) { + return NO; + } + + // Fall back to the default app's collection switch when the key is not in the dictionary. + return [FIRApp defaultApp].isDataCollectionDefaultEnabled; + } + return [value boolValue]; +} + +- (BOOL)isAnalyticsCollectionExpicitlySet { + // If it's de-activated, it classifies as explicity set. If not, it's not a good enough indication + // that the developer wants FirebaseAnalytics enabled so continue checking. + if (self.isAnalyticsCollectionDeactivated) { + return YES; + } + + // Check if the current Analytics flag is set. + id collectionEnabledObject = self.analyticsOptionsDictionary[kFIRIsAnalyticsCollectionEnabled]; + if (collectionEnabledObject && [collectionEnabledObject isKindOfClass:[NSNumber class]]) { + // It doesn't matter what the value is, it's explicitly set. + return YES; + } + + // Check if the old measurement flag is set. + id measurementEnabledObject = self.analyticsOptionsDictionary[kFIRIsMeasurementEnabled]; + if (measurementEnabledObject && [measurementEnabledObject isKindOfClass:[NSNumber class]]) { + // It doesn't matter what the value is, it's explicitly set. + return YES; + } + + // No flags are set to explicitly enable or disable FirebaseAnalytics. + return NO; +} + +- (BOOL)isAnalyticsCollectionEnabled { + if (self.isAnalyticsCollectionDeactivated) { + return NO; + } + NSNumber *value = self.analyticsOptionsDictionary[kFIRIsAnalyticsCollectionEnabled]; + if (value == nil) { + return self.isMeasurementEnabled; // Fall back to older plist flag. + } + return [value boolValue]; +} + +- (BOOL)isAnalyticsCollectionDeactivated { + NSNumber *value = self.analyticsOptionsDictionary[kFIRIsAnalyticsCollectionDeactivated]; + if (value == nil) { + return NO; // Analytics Collection is not deactivated when the key is not in the dictionary. + } + return [value boolValue]; +} + +- (BOOL)isAnalyticsEnabled { + return [self.optionsDictionary[kFIRIsAnalyticsEnabled] boolValue]; +} + +- (BOOL)isSignInEnabled { + return [self.optionsDictionary[kFIRIsSignInEnabled] boolValue]; +} + +@end diff --git a/FoodApp/Pods/FirebaseCore/Firebase/Core/FIRVersion.m b/FoodApp/Pods/FirebaseCore/Firebase/Core/FIRVersion.m new file mode 100644 index 0000000..ec0f6ba --- /dev/null +++ b/FoodApp/Pods/FirebaseCore/Firebase/Core/FIRVersion.m @@ -0,0 +1,33 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#ifndef Firebase_VERSION +#error "Firebase_VERSION is not defined: add -DFirebase_VERSION=... to the build invocation" +#endif + +#ifndef FIRCore_VERSION +#error "FIRCore_VERSION is not defined: add -DFIRCore_VERSION=... to the build invocation" +#endif + +// The following two macros supply the incantation so that the C +// preprocessor does not try to parse the version as a floating +// point number. See +// https://www.guyrutenberg.com/2008/12/20/expanding-macros-into-string-constants-in-c/ +#define STR(x) STR_EXPAND(x) +#define STR_EXPAND(x) #x + +const char *const FIRVersionString = (const char *const)STR(Firebase_VERSION); +const char *const FIRCoreVersionString = (const char *const)STR(FIRCore_VERSION); diff --git a/FoodApp/Pods/FirebaseCore/Firebase/Core/Private/FIRAnalyticsConfiguration+Internal.h b/FoodApp/Pods/FirebaseCore/Firebase/Core/Private/FIRAnalyticsConfiguration+Internal.h new file mode 100644 index 0000000..be624b4 --- /dev/null +++ b/FoodApp/Pods/FirebaseCore/Firebase/Core/Private/FIRAnalyticsConfiguration+Internal.h @@ -0,0 +1,49 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRAnalyticsConfiguration.h" + +/// Values stored in analyticsEnabledState. Never alter these constants since they must match with +/// values persisted to disk. +typedef NS_ENUM(int64_t, FIRAnalyticsEnabledState) { + // 0 is the default value for keys not found stored in persisted config, so it cannot represent + // kFIRAnalyticsEnabledStateSetNo. It must represent kFIRAnalyticsEnabledStateNotSet. + kFIRAnalyticsEnabledStateNotSet = 0, + kFIRAnalyticsEnabledStateSetYes = 1, + kFIRAnalyticsEnabledStateSetNo = 2, +}; + +/// The user defaults key for the persisted measurementEnabledState value. FIRAPersistedConfig reads +/// measurementEnabledState using this same key. +static NSString *const kFIRAPersistedConfigMeasurementEnabledStateKey = + @"/google/measurement/measurement_enabled_state"; + +static NSString *const kFIRAnalyticsConfigurationSetEnabledNotification = + @"FIRAnalyticsConfigurationSetEnabledNotification"; +static NSString *const kFIRAnalyticsConfigurationSetMinimumSessionIntervalNotification = + @"FIRAnalyticsConfigurationSetMinimumSessionIntervalNotification"; +static NSString *const kFIRAnalyticsConfigurationSetSessionTimeoutIntervalNotification = + @"FIRAnalyticsConfigurationSetSessionTimeoutIntervalNotification"; + +@interface FIRAnalyticsConfiguration (Internal) + +/// Sets whether analytics collection is enabled for this app on this device, and a flag to persist +/// the value or not. The setting should not be persisted if being set by the global data collection +/// flag. +- (void)setAnalyticsCollectionEnabled:(BOOL)analyticsCollectionEnabled + persistSetting:(BOOL)shouldPersist; + +@end diff --git a/FoodApp/Pods/FirebaseCore/Firebase/Core/Private/FIRAppAssociationRegistration.h b/FoodApp/Pods/FirebaseCore/Firebase/Core/Private/FIRAppAssociationRegistration.h new file mode 100644 index 0000000..3fc69c6 --- /dev/null +++ b/FoodApp/Pods/FirebaseCore/Firebase/Core/Private/FIRAppAssociationRegistration.h @@ -0,0 +1,49 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +NS_ASSUME_NONNULL_BEGIN + +// TODO: Remove this once Auth moves over to Core's instance registration system. +/** @class FIRAppAssociationRegistration + @brief Manages object associations as a singleton-dependent: At most one object is + registered for any given host/key pair, and the object shall be created on-the-fly when + asked for. + */ +@interface FIRAppAssociationRegistration : NSObject + +/** @fn registeredObjectWithHost:key:creationBlock: + @brief Retrieves the registered object with a particular host and key. + @param host The host object. + @param key The key to specify the registered object on the host. + @param creationBlock The block to return the object to be registered if not already. + The block is executed immediately before this method returns if it is executed at all. + It can also be executed multiple times across different method invocations if previous + execution of the block returns @c nil. + @return The registered object for the host/key pair, or @c nil if no object is registered + and @c creationBlock returns @c nil. + @remarks The method is thread-safe but non-reentrant in the sense that attempting to call this + method again within the @c creationBlock with the same host/key pair raises an exception. + The registered object is retained by the host. + */ ++ (nullable ObjectType)registeredObjectWithHost:(id)host + key:(NSString *)key + creationBlock:(ObjectType _Nullable (^)(void))creationBlock; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseCore/Firebase/Core/Private/FIRAppInternal.h b/FoodApp/Pods/FirebaseCore/Firebase/Core/Private/FIRAppInternal.h new file mode 100644 index 0000000..d663d3e --- /dev/null +++ b/FoodApp/Pods/FirebaseCore/Firebase/Core/Private/FIRAppInternal.h @@ -0,0 +1,182 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRApp.h" +#import "FIRErrors.h" + +@class FIRComponentContainer; +@protocol FIRLibrary; + +/** + * The internal interface to FIRApp. This is meant for first-party integrators, who need to receive + * FIRApp notifications, log info about the success or failure of their configuration, and access + * other internal functionality of FIRApp. + * + * TODO(b/28296561): Restructure this header. + */ +NS_ASSUME_NONNULL_BEGIN + +typedef NS_ENUM(NSInteger, FIRConfigType) { + FIRConfigTypeCore = 1, + FIRConfigTypeSDK = 2, +}; + +/** + * Names of services provided by Firebase. + */ +extern NSString *const kFIRServiceAdMob; +extern NSString *const kFIRServiceAuth; +extern NSString *const kFIRServiceAuthUI; +extern NSString *const kFIRServiceCrash; +extern NSString *const kFIRServiceDatabase; +extern NSString *const kFIRServiceDynamicLinks; +extern NSString *const kFIRServiceInstanceID; +extern NSString *const kFIRServiceInvites; +extern NSString *const kFIRServiceMessaging; +extern NSString *const kFIRServiceMeasurement; +extern NSString *const kFIRServiceRemoteConfig; +extern NSString *const kFIRServiceStorage; + +/** + * Names of services provided by the Google pod, but logged by the Firebase pod. + */ +extern NSString *const kGGLServiceAnalytics; +extern NSString *const kGGLServiceSignIn; + +extern NSString *const kFIRDefaultAppName; +extern NSString *const kFIRAppReadyToConfigureSDKNotification; +extern NSString *const kFIRAppDeleteNotification; +extern NSString *const kFIRAppIsDefaultAppKey; +extern NSString *const kFIRAppNameKey; +extern NSString *const kFIRGoogleAppIDKey; + +/** + * The format string for the User Defaults key used for storing the data collection enabled flag. + * This includes formatting to append the Firebase App's name. + */ +extern NSString *const kFIRGlobalAppDataCollectionEnabledDefaultsKeyFormat; + +/** + * The plist key used for storing the data collection enabled flag. + */ +extern NSString *const kFIRGlobalAppDataCollectionEnabledPlistKey; + +/** + * A notification fired containing diagnostic information when SDK errors occur. + */ +extern NSString *const kFIRAppDiagnosticsNotification; + +/** @var FIRAuthStateDidChangeInternalNotification + @brief The name of the @c NSNotificationCenter notification which is posted when the auth state + changes (e.g. a new token has been produced, a user logs in or out). The object parameter of + the notification is a dictionary possibly containing the key: + @c FIRAuthStateDidChangeInternalNotificationTokenKey (the new access token.) If it does not + contain this key it indicates a sign-out event took place. + */ +extern NSString *const FIRAuthStateDidChangeInternalNotification; + +/** @var FIRAuthStateDidChangeInternalNotificationTokenKey + @brief A key present in the dictionary object parameter of the + @c FIRAuthStateDidChangeInternalNotification notification. The value associated with this + key will contain the new access token. + */ +extern NSString *const FIRAuthStateDidChangeInternalNotificationTokenKey; + +/** @var FIRAuthStateDidChangeInternalNotificationAppKey + @brief A key present in the dictionary object parameter of the + @c FIRAuthStateDidChangeInternalNotification notification. The value associated with this + key will contain the FIRApp associated with the auth instance. + */ +extern NSString *const FIRAuthStateDidChangeInternalNotificationAppKey; + +/** @var FIRAuthStateDidChangeInternalNotificationUIDKey + @brief A key present in the dictionary object parameter of the + @c FIRAuthStateDidChangeInternalNotification notification. The value associated with this + key will contain the new user's UID (or nil if there is no longer a user signed in). + */ +extern NSString *const FIRAuthStateDidChangeInternalNotificationUIDKey; + +@interface FIRApp () + +/** + * A flag indicating if this is the default app (has the default app name). + */ +@property(nonatomic, readonly) BOOL isDefaultApp; + +/* + * The container of interop SDKs for this app. + */ +@property(nonatomic) FIRComponentContainer *container; + +/** + * Creates an error for failing to configure a subspec service. This method is called by each + * FIRApp notification listener. + */ ++ (NSError *)errorForSubspecConfigurationFailureWithDomain:(NSString *)domain + errorCode:(FIRErrorCode)code + service:(NSString *)service + reason:(NSString *)reason; +/** + * Checks if the default app is configured without trying to configure it. + */ ++ (BOOL)isDefaultAppConfigured; + +/** + * Registers a given third-party library with the given version number to be reported for + * analytics. + * + * @param name Name of the library. + * @param version Version of the library. + */ ++ (void)registerLibrary:(nonnull NSString *)name withVersion:(nonnull NSString *)version; + +/** + * Registers a given internal library with the given version number to be reported for + * analytics. + * + * @param library Optional parameter for component registration. + * @param name Name of the library. + * @param version Version of the library. + */ ++ (void)registerInternalLibrary:(nonnull Class)library + withName:(nonnull NSString *)name + withVersion:(nonnull NSString *)version; + +/** + * A concatenated string representing all the third-party libraries and version numbers. + */ ++ (NSString *)firebaseUserAgent; + +/** + * Used by each SDK to send logs about SDK configuration status to Clearcut. + */ +- (void)sendLogsWithServiceName:(NSString *)serviceName + version:(NSString *)version + error:(NSError *)error; + +/** + * Can be used by the unit tests in eack SDK to reset FIRApp. This method is thread unsafe. + */ ++ (void)resetApps; + +/** + * Can be used by the unit tests in each SDK to set customized options. + */ +- (instancetype)initInstanceWithName:(NSString *)name options:(FIROptions *)options; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseCore/Firebase/Core/Private/FIRBundleUtil.h b/FoodApp/Pods/FirebaseCore/Firebase/Core/Private/FIRBundleUtil.h new file mode 100644 index 0000000..d9475dd --- /dev/null +++ b/FoodApp/Pods/FirebaseCore/Firebase/Core/Private/FIRBundleUtil.h @@ -0,0 +1,53 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +/** + * This class provides utilities for accessing resources in bundles. + */ +@interface FIRBundleUtil : NSObject + +/** + * Finds all relevant bundles, starting with [NSBundle mainBundle]. + */ ++ (NSArray *)relevantBundles; + +/** + * Reads the options dictionary from one of the provided bundles. + * + * @param resourceName The resource name, e.g. @"GoogleService-Info". + * @param fileType The file type (extension), e.g. @"plist". + * @param bundles The bundles to expect, in priority order. See also + * +[FIRBundleUtil relevantBundles]. + */ ++ (NSString *)optionsDictionaryPathWithResourceName:(NSString *)resourceName + andFileType:(NSString *)fileType + inBundles:(NSArray *)bundles; + +/** + * Finds URL schemes defined in all relevant bundles, starting with those from + * [NSBundle mainBundle]. + */ ++ (NSArray *)relevantURLSchemes; + +/** + * Checks if any of the given bundles have a matching bundle identifier prefix (removing extension + * suffixes). + */ ++ (BOOL)hasBundleIdentifierPrefix:(NSString *)bundleIdentifier inBundles:(NSArray *)bundles; + +@end diff --git a/FoodApp/Pods/FirebaseCore/Firebase/Core/Private/FIRComponent.h b/FoodApp/Pods/FirebaseCore/Firebase/Core/Private/FIRComponent.h new file mode 100644 index 0000000..cb51ee7 --- /dev/null +++ b/FoodApp/Pods/FirebaseCore/Firebase/Core/Private/FIRComponent.h @@ -0,0 +1,91 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#import + +@class FIRApp; +@class FIRComponentContainer; + +NS_ASSUME_NONNULL_BEGIN + +/// Provides a system to clean up cached instances returned from the component system. +NS_SWIFT_NAME(ComponentLifecycleMaintainer) +@protocol FIRComponentLifecycleMaintainer +/// The associated app will be deleted, clean up any resources as they are about to be deallocated. +- (void)appWillBeDeleted:(FIRApp *)app; +@end + +typedef _Nullable id (^FIRComponentCreationBlock)(FIRComponentContainer *container, + BOOL *isCacheable) + NS_SWIFT_NAME(ComponentCreationBlock); + +@class FIRDependency; + +/// Describes the timing of instantiation. Note: new components should default to lazy unless there +/// is a strong reason to be eager. +typedef NS_ENUM(NSInteger, FIRInstantiationTiming) { + FIRInstantiationTimingLazy, + FIRInstantiationTimingAlwaysEager, + FIRInstantiationTimingEagerInDefaultApp +} NS_SWIFT_NAME(InstantiationTiming); + +/// A component that can be used from other Firebase SDKs. +NS_SWIFT_NAME(Component) +@interface FIRComponent : NSObject + +/// The protocol describing functionality provided from the Component. +@property(nonatomic, strong, readonly) Protocol *protocol; + +/// The timing of instantiation. +@property(nonatomic, readonly) FIRInstantiationTiming instantiationTiming; + +/// An array of dependencies for the component. +@property(nonatomic, copy, readonly) NSArray *dependencies; + +/// A block to instantiate an instance of the component with the appropriate dependencies. +@property(nonatomic, copy, readonly) FIRComponentCreationBlock creationBlock; + +// There's an issue with long NS_SWIFT_NAMES that causes compilation to fail, disable clang-format +// for the next two methods. +// clang-format off + +/// Creates a component with no dependencies that will be lazily initialized. ++ (instancetype)componentWithProtocol:(Protocol *)protocol + creationBlock:(FIRComponentCreationBlock)creationBlock +NS_SWIFT_NAME(init(_:creationBlock:)); + +/// Creates a component to be registered with the component container. +/// +/// @param protocol - The protocol describing functionality provided by the component. +/// @param instantiationTiming - When the component should be initialized. Use .lazy unless there's +/// a good reason to be instantiated earlier. +/// @param dependencies - Any dependencies the `implementingClass` has, optional or required. +/// @param creationBlock - A block to instantiate the component with a container, and if +/// @return A component that can be registered with the component container. ++ (instancetype)componentWithProtocol:(Protocol *)protocol + instantiationTiming:(FIRInstantiationTiming)instantiationTiming + dependencies:(NSArray *)dependencies + creationBlock:(FIRComponentCreationBlock)creationBlock +NS_SWIFT_NAME(init(_:instantiationTiming:dependencies:creationBlock:)); + +// clang-format on + +/// Unavailable. +- (instancetype)init NS_UNAVAILABLE; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseCore/Firebase/Core/Private/FIRComponentContainer.h b/FoodApp/Pods/FirebaseCore/Firebase/Core/Private/FIRComponentContainer.h new file mode 100644 index 0000000..f3dc356 --- /dev/null +++ b/FoodApp/Pods/FirebaseCore/Firebase/Core/Private/FIRComponentContainer.h @@ -0,0 +1,44 @@ +/* + * Copyright 2018 Google + * + * 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. + */ +#import + +#import "FIRComponentType.h" +#import "FIRLibrary.h" + +NS_ASSUME_NONNULL_BEGIN + +/// A type-safe macro to retrieve a component from a container. This should be used to retrieve +/// components instead of using the container directly. +#define FIR_COMPONENT(type, container) \ + [FIRComponentType> instanceForProtocol:@protocol(type) inContainer:container] + +@class FIRApp; + +/// A container that holds different components that are registered via the +/// `registerAsComponentRegistrant:` call. These classes should conform to `FIRComponentRegistrant` +/// in order to properly register components for Core. +NS_SWIFT_NAME(FirebaseComponentContainer) +@interface FIRComponentContainer : NSObject + +/// A weak reference to the app that an instance of the container belongs to. +@property(nonatomic, weak, readonly) FIRApp *app; + +/// Unavailable. Use the `container` property on `FIRApp`. +- (instancetype)init NS_UNAVAILABLE; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseCore/Firebase/Core/Private/FIRComponentContainerInternal.h b/FoodApp/Pods/FirebaseCore/Firebase/Core/Private/FIRComponentContainerInternal.h new file mode 100644 index 0000000..e8552fa --- /dev/null +++ b/FoodApp/Pods/FirebaseCore/Firebase/Core/Private/FIRComponentContainerInternal.h @@ -0,0 +1,43 @@ +/* + * Copyright 2018 Google + * + * 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. + */ +#import + +#import "FIRComponent.h" +#import "FIRComponentContainer.h" + +@class FIRApp; + +NS_ASSUME_NONNULL_BEGIN + +@interface FIRComponentContainer (Private) + +/// Initializes a contain for a given app. This should only be called by the app itself. +- (instancetype)initWithApp:(FIRApp *)app; + +/// Retrieves an instance that conforms to the specified protocol. This will return `nil` if the +/// protocol wasn't registered, or if the instance couldn't instantiate for the provided app. +- (nullable id)instanceForProtocol:(Protocol *)protocol NS_SWIFT_NAME(instance(for:)); + +/// Remove all of the cached instances stored and allow them to clean up after themselves. +- (void)removeAllCachedInstances; + +/// Register a class to provide components for the interoperability system. The class should conform +/// to `FIRComponentRegistrant` and provide an array of `FIRComponent` objects. ++ (void)registerAsComponentRegistrant:(Class)klass; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseCore/Firebase/Core/Private/FIRComponentType.h b/FoodApp/Pods/FirebaseCore/Firebase/Core/Private/FIRComponentType.h new file mode 100644 index 0000000..6f2aca7 --- /dev/null +++ b/FoodApp/Pods/FirebaseCore/Firebase/Core/Private/FIRComponentType.h @@ -0,0 +1,34 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#import + +@class FIRComponentContainer; + +NS_ASSUME_NONNULL_BEGIN + +/// Do not use directly. A placeholder type in order to provide a macro that will warn users of +/// mis-matched protocols. +NS_SWIFT_NAME(ComponentType) +@interface FIRComponentType<__covariant T> : NSObject + +/// Do not use directly. A factory method to retrieve an instance that provides a specific +/// functionality. ++ (T)instanceForProtocol:(Protocol *)protocol inContainer:(FIRComponentContainer *)container; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseCore/Firebase/Core/Private/FIRDependency.h b/FoodApp/Pods/FirebaseCore/Firebase/Core/Private/FIRDependency.h new file mode 100644 index 0000000..46e9b7e --- /dev/null +++ b/FoodApp/Pods/FirebaseCore/Firebase/Core/Private/FIRDependency.h @@ -0,0 +1,45 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#import + +NS_ASSUME_NONNULL_BEGIN + +/// A dependency on a specific protocol's functionality. +NS_SWIFT_NAME(Dependency) +@interface FIRDependency : NSObject + +/// The protocol describing functionality being depended on. +@property(nonatomic, strong, readonly) Protocol *protocol; + +/// A flag to specify if the dependency is required or not. +@property(nonatomic, readonly) BOOL isRequired; + +/// Initializes a dependency that is required. Calls `initWithProtocol:isRequired` with `YES` for +/// the required parameter. +/// Creates a required dependency on the specified protocol's functionality. ++ (instancetype)dependencyWithProtocol:(Protocol *)protocol; + +/// Creates a dependency on the specified protocol's functionality and specify if it's required for +/// the class's functionality. ++ (instancetype)dependencyWithProtocol:(Protocol *)protocol isRequired:(BOOL)required; + +/// Use `dependencyWithProtocol:isRequired:` instead. +- (instancetype)init NS_UNAVAILABLE; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseCore/Firebase/Core/Private/FIRErrorCode.h b/FoodApp/Pods/FirebaseCore/Firebase/Core/Private/FIRErrorCode.h new file mode 100644 index 0000000..01d3c56 --- /dev/null +++ b/FoodApp/Pods/FirebaseCore/Firebase/Core/Private/FIRErrorCode.h @@ -0,0 +1,55 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +/** Error codes in Firebase error domain. */ +typedef NS_ENUM(NSInteger, FIRErrorCode) { + /** + * Unknown error. + */ + FIRErrorCodeUnknown = 0, + /** + * Loading data from the GoogleService-Info.plist file failed. This is a fatal error and should + * not be ignored. Further calls to the API will fail and/or possibly cause crashes. + */ + FIRErrorCodeInvalidPlistFile = -100, + + /** + * Validating the Google App ID format failed. + */ + FIRErrorCodeInvalidAppID = -101, + + /** + * Error code for failing to configure a specific service. + */ + FIRErrorCodeAdMobFailed = -110, + FIRErrorCodeAppInviteFailed = -112, + FIRErrorCodeCloudMessagingFailed = -113, + FIRErrorCodeConfigFailed = -114, + FIRErrorCodeDatabaseFailed = -115, + FIRErrorCodeCrashReportingFailed = -118, + FIRErrorCodeDurableDeepLinkFailed = -119, + FIRErrorCodeAuthFailed = -120, + FIRErrorCodeInstanceIDFailed = -121, + FIRErrorCodeStorageFailed = -123, + + /** + * Error codes returned by Dynamic Links + */ + FIRErrorCodeDynamicLinksStrongMatchNotAvailable = -124, + FIRErrorCodeDynamicLinksManualRetrievalNotEnabled = -125, + FIRErrorCodeDynamicLinksPendingLinkOnlyAvailableAtFirstLaunch = -126, + FIRErrorCodeDynamicLinksPendingLinkRetrievalAlreadyRunning = -127, +}; diff --git a/FoodApp/Pods/FirebaseCore/Firebase/Core/Private/FIRErrors.h b/FoodApp/Pods/FirebaseCore/Firebase/Core/Private/FIRErrors.h new file mode 100644 index 0000000..cf69252 --- /dev/null +++ b/FoodApp/Pods/FirebaseCore/Firebase/Core/Private/FIRErrors.h @@ -0,0 +1,33 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +#include "FIRErrorCode.h" + +extern NSString *const kFirebaseErrorDomain; +extern NSString *const kFirebaseAdMobErrorDomain; +extern NSString *const kFirebaseAppInviteErrorDomain; +extern NSString *const kFirebaseAuthErrorDomain; +extern NSString *const kFirebaseCloudMessagingErrorDomain; +extern NSString *const kFirebaseConfigErrorDomain; +extern NSString *const kFirebaseCoreErrorDomain; +extern NSString *const kFirebaseCrashReportingErrorDomain; +extern NSString *const kFirebaseDatabaseErrorDomain; +extern NSString *const kFirebaseDurableDeepLinkErrorDomain; +extern NSString *const kFirebaseInstanceIDErrorDomain; +extern NSString *const kFirebasePerfErrorDomain; +extern NSString *const kFirebaseStorageErrorDomain; diff --git a/FoodApp/Pods/FirebaseCore/Firebase/Core/Private/FIRLibrary.h b/FoodApp/Pods/FirebaseCore/Firebase/Core/Private/FIRLibrary.h new file mode 100644 index 0000000..728c062 --- /dev/null +++ b/FoodApp/Pods/FirebaseCore/Firebase/Core/Private/FIRLibrary.h @@ -0,0 +1,44 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRLibrary_h +#define FIRLibrary_h + +#import +#import "FIRComponent.h" + +@class FIRApp; + +NS_ASSUME_NONNULL_BEGIN + +/// Provide an interface to register a library for userAgent logging and availability to others. +NS_SWIFT_NAME(Library) +@protocol FIRLibrary + +/// Returns one or more FIRComponents that will be registered in +/// FIRApp and participate in dependency resolution and injection. ++ (NSArray *)componentsToRegister; + +@optional +/// Implement this method if the library needs notifications for lifecycle events. This method is +/// called when the developer calls `FirebaseApp.configure()`. ++ (void)configureWithApp:(FIRApp *)app; + +@end + +NS_ASSUME_NONNULL_END + +#endif /* FIRLibrary_h */ diff --git a/FoodApp/Pods/FirebaseCore/Firebase/Core/Private/FIRLogger.h b/FoodApp/Pods/FirebaseCore/Firebase/Core/Private/FIRLogger.h new file mode 100644 index 0000000..a538199 --- /dev/null +++ b/FoodApp/Pods/FirebaseCore/Firebase/Core/Private/FIRLogger.h @@ -0,0 +1,159 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +#import "FIRLoggerLevel.h" + +NS_ASSUME_NONNULL_BEGIN + +/** + * The Firebase services used in Firebase logger. + */ +typedef NSString *const FIRLoggerService; + +extern FIRLoggerService kFIRLoggerABTesting; +extern FIRLoggerService kFIRLoggerAdMob; +extern FIRLoggerService kFIRLoggerAnalytics; +extern FIRLoggerService kFIRLoggerAuth; +extern FIRLoggerService kFIRLoggerCore; +extern FIRLoggerService kFIRLoggerCrash; +extern FIRLoggerService kFIRLoggerDatabase; +extern FIRLoggerService kFIRLoggerDynamicLinks; +extern FIRLoggerService kFIRLoggerFirestore; +extern FIRLoggerService kFIRLoggerInstanceID; +extern FIRLoggerService kFIRLoggerInvites; +extern FIRLoggerService kFIRLoggerMLKit; +extern FIRLoggerService kFIRLoggerMessaging; +extern FIRLoggerService kFIRLoggerPerf; +extern FIRLoggerService kFIRLoggerRemoteConfig; +extern FIRLoggerService kFIRLoggerStorage; +extern FIRLoggerService kFIRLoggerSwizzler; + +/** + * The key used to store the logger's error count. + */ +extern NSString *const kFIRLoggerErrorCountKey; + +/** + * The key used to store the logger's warning count. + */ +extern NSString *const kFIRLoggerWarningCountKey; + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +/** + * Enables or disables Analytics debug mode. + * If set to YES, the logging level for Analytics will be set to FIRLoggerLevelDebug. + * Enabling the debug mode has no effect if the app is running from App Store. + * (required) analytics debug mode flag. + */ +void FIRSetAnalyticsDebugMode(BOOL analyticsDebugMode); + +/** + * Changes the default logging level of FIRLoggerLevelNotice to a user-specified level. + * The default level cannot be set above FIRLoggerLevelNotice if the app is running from App Store. + * (required) log level (one of the FIRLoggerLevel enum values). + */ +void FIRSetLoggerLevel(FIRLoggerLevel loggerLevel); + +/** + * Checks if the specified logger level is loggable given the current settings. + * (required) log level (one of the FIRLoggerLevel enum values). + * (required) whether or not this function is called from the Analytics component. + */ +BOOL FIRIsLoggableLevel(FIRLoggerLevel loggerLevel, BOOL analyticsComponent); + +/** + * Logs a message to the Xcode console and the device log. If running from AppStore, will + * not log any messages with a level higher than FIRLoggerLevelNotice to avoid log spamming. + * (required) log level (one of the FIRLoggerLevel enum values). + * (required) service name of type FIRLoggerService. + * (required) message code starting with "I-" which means iOS, followed by a capitalized + * three-character service identifier and a six digit integer message ID that is unique + * within the service. + * An example of the message code is @"I-COR000001". + * (required) message string which can be a format string. + * (optional) variable arguments list obtained from calling va_start, used when message is a format + * string. + */ +extern void FIRLogBasic(FIRLoggerLevel level, + FIRLoggerService service, + NSString *messageCode, + NSString *message, +// On 64-bit simulators, va_list is not a pointer, so cannot be marked nullable +// See: http://stackoverflow.com/q/29095469 +#if __LP64__ && TARGET_OS_SIMULATOR || TARGET_OS_OSX + va_list args_ptr +#else + va_list _Nullable args_ptr +#endif +); + +/** + * The following functions accept the following parameters in order: + * (required) service name of type FIRLoggerService. + * (required) message code starting from "I-" which means iOS, followed by a capitalized + * three-character service identifier and a six digit integer message ID that is unique + * within the service. + * An example of the message code is @"I-COR000001". + * See go/firebase-log-proposal for details. + * (required) message string which can be a format string. + * (optional) the list of arguments to substitute into the format string. + * Example usage: + * FIRLogError(kFIRLoggerCore, @"I-COR000001", @"Configuration of %@ failed.", app.name); + */ +extern void FIRLogError(FIRLoggerService service, NSString *messageCode, NSString *message, ...) + NS_FORMAT_FUNCTION(3, 4); +extern void FIRLogWarning(FIRLoggerService service, NSString *messageCode, NSString *message, ...) + NS_FORMAT_FUNCTION(3, 4); +extern void FIRLogNotice(FIRLoggerService service, NSString *messageCode, NSString *message, ...) + NS_FORMAT_FUNCTION(3, 4); +extern void FIRLogInfo(FIRLoggerService service, NSString *messageCode, NSString *message, ...) + NS_FORMAT_FUNCTION(3, 4); +extern void FIRLogDebug(FIRLoggerService service, NSString *messageCode, NSString *message, ...) + NS_FORMAT_FUNCTION(3, 4); + +#ifdef __cplusplus +} // extern "C" +#endif // __cplusplus + +@interface FIRLoggerWrapper : NSObject + +/** + * Objective-C wrapper for FIRLogBasic to allow weak linking to FIRLogger + * (required) log level (one of the FIRLoggerLevel enum values). + * (required) service name of type FIRLoggerService. + * (required) message code starting with "I-" which means iOS, followed by a capitalized + * three-character service identifier and a six digit integer message ID that is unique + * within the service. + * An example of the message code is @"I-COR000001". + * (required) message string which can be a format string. + * (optional) variable arguments list obtained from calling va_start, used when message is a format + * string. + */ + ++ (void)logWithLevel:(FIRLoggerLevel)level + withService:(FIRLoggerService)service + withCode:(NSString *)messageCode + withMessage:(NSString *)message + withArgs:(va_list)args; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseCore/Firebase/Core/Private/FIROptionsInternal.h b/FoodApp/Pods/FirebaseCore/Firebase/Core/Private/FIROptionsInternal.h new file mode 100644 index 0000000..7bb40fc --- /dev/null +++ b/FoodApp/Pods/FirebaseCore/Firebase/Core/Private/FIROptionsInternal.h @@ -0,0 +1,114 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIROptions.h" + +/** + * Keys for the strings in the plist file. + */ +extern NSString *const kFIRAPIKey; +extern NSString *const kFIRTrackingID; +extern NSString *const kFIRGoogleAppID; +extern NSString *const kFIRClientID; +extern NSString *const kFIRGCMSenderID; +extern NSString *const kFIRAndroidClientID; +extern NSString *const kFIRDatabaseURL; +extern NSString *const kFIRStorageBucket; +extern NSString *const kFIRBundleID; +extern NSString *const kFIRProjectID; + +/** + * Keys for the plist file name + */ +extern NSString *const kServiceInfoFileName; + +extern NSString *const kServiceInfoFileType; + +/** + * This header file exposes the initialization of FIROptions to internal use. + */ +@interface FIROptions () + +/** + * resetDefaultOptions and initInternalWithOptionsDictionary: are exposed only for unit tests. + */ ++ (void)resetDefaultOptions; + +/** + * Initializes the options with dictionary. The above strings are the keys of the dictionary. + * This is the designated initializer. + */ +- (instancetype)initInternalWithOptionsDictionary:(NSDictionary *)serviceInfoDictionary; + +/** + * defaultOptions and defaultOptionsDictionary are exposed in order to be used in FIRApp and + * other first party services. + */ ++ (FIROptions *)defaultOptions; + ++ (NSDictionary *)defaultOptionsDictionary; + +/** + * Indicates whether or not Analytics collection was explicitly enabled via a plist flag or at + * runtime. + */ +@property(nonatomic, readonly) BOOL isAnalyticsCollectionExpicitlySet; + +/** + * Whether or not Analytics Collection was enabled. Analytics Collection is enabled unless + * explicitly disabled in GoogleService-Info.plist. + */ +@property(nonatomic, readonly) BOOL isAnalyticsCollectionEnabled; + +/** + * Whether or not Analytics Collection was completely disabled. If YES, then + * isAnalyticsCollectionEnabled will be NO. + */ +@property(nonatomic, readonly) BOOL isAnalyticsCollectionDeactivated; + +/** + * The version ID of the client library, e.g. @"1100000". + */ +@property(nonatomic, readonly, copy) NSString *libraryVersionID; + +/** + * The flag indicating whether this object was constructed with the values in the default plist + * file. + */ +@property(nonatomic) BOOL usingOptionsFromDefaultPlist; + +/** + * Whether or not Measurement was enabled. Measurement is enabled unless explicitly disabled in + * GoogleService-Info.plist. + */ +@property(nonatomic, readonly) BOOL isMeasurementEnabled; + +/** + * Whether or not Analytics was enabled in the developer console. + */ +@property(nonatomic, readonly) BOOL isAnalyticsEnabled; + +/** + * Whether or not SignIn was enabled in the developer console. + */ +@property(nonatomic, readonly) BOOL isSignInEnabled; + +/** + * Whether or not editing is locked. This should occur after FIROptions has been set on a FIRApp. + */ +@property(nonatomic, getter=isEditingLocked) BOOL editingLocked; + +@end diff --git a/FoodApp/Pods/FirebaseCore/Firebase/Core/Private/FIRVersion.h b/FoodApp/Pods/FirebaseCore/Firebase/Core/Private/FIRVersion.h new file mode 100644 index 0000000..226efb1 --- /dev/null +++ b/FoodApp/Pods/FirebaseCore/Firebase/Core/Private/FIRVersion.h @@ -0,0 +1,23 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +/** The version of the Firebase SDK. */ +FOUNDATION_EXPORT const char *const FIRVersionString; + +/** The version of the FirebaseCore Component. */ +FOUNDATION_EXPORT const char *const FIRCoreVersionString; diff --git a/FoodApp/Pods/FirebaseCore/Firebase/Core/Public/FIRAnalyticsConfiguration.h b/FoodApp/Pods/FirebaseCore/Firebase/Core/Public/FIRAnalyticsConfiguration.h new file mode 100644 index 0000000..add4a38 --- /dev/null +++ b/FoodApp/Pods/FirebaseCore/Firebase/Core/Public/FIRAnalyticsConfiguration.h @@ -0,0 +1,56 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * This class provides configuration fields for Firebase Analytics. + */ +NS_SWIFT_NAME(AnalyticsConfiguration) +DEPRECATED_MSG_ATTRIBUTE("Use these methods directly on the `Analytics` class.") +@interface FIRAnalyticsConfiguration : NSObject + +/** + * Returns the shared instance of FIRAnalyticsConfiguration. + */ ++ (FIRAnalyticsConfiguration *)sharedInstance NS_SWIFT_NAME(shared()); + +/** + * Deprecated. + * Sets the minimum engagement time in seconds required to start a new session. The default value + * is 10 seconds. + */ +- (void)setMinimumSessionInterval:(NSTimeInterval)minimumSessionInterval + DEPRECATED_MSG_ATTRIBUTE( + "Sessions are started immediately. More information at https://bit.ly/2FU46av"); + +/** + * Sets the interval of inactivity in seconds that terminates the current session. The default + * value is 1800 seconds (30 minutes). + */ +- (void)setSessionTimeoutInterval:(NSTimeInterval)sessionTimeoutInterval; + +/** + * Sets whether analytics collection is enabled for this app on this device. This setting is + * persisted across app sessions. By default it is enabled. + */ +- (void)setAnalyticsCollectionEnabled:(BOOL)analyticsCollectionEnabled; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseCore/Firebase/Core/Public/FIRApp.h b/FoodApp/Pods/FirebaseCore/Firebase/Core/Public/FIRApp.h new file mode 100644 index 0000000..e0dd6d6 --- /dev/null +++ b/FoodApp/Pods/FirebaseCore/Firebase/Core/Public/FIRApp.h @@ -0,0 +1,127 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +@class FIROptions; + +NS_ASSUME_NONNULL_BEGIN + +/** A block that takes a BOOL and has no return value. */ +typedef void (^FIRAppVoidBoolCallback)(BOOL success) NS_SWIFT_NAME(FirebaseAppVoidBoolCallback); + +/** + * The entry point of Firebase SDKs. + * + * Initialize and configure FIRApp using +[FIRApp configure] + * or other customized ways as shown below. + * + * The logging system has two modes: default mode and debug mode. In default mode, only logs with + * log level Notice, Warning and Error will be sent to device. In debug mode, all logs will be sent + * to device. The log levels that Firebase uses are consistent with the ASL log levels. + * + * Enable debug mode by passing the -FIRDebugEnabled argument to the application. You can add this + * argument in the application's Xcode scheme. When debug mode is enabled via -FIRDebugEnabled, + * further executions of the application will also be in debug mode. In order to return to default + * mode, you must explicitly disable the debug mode with the application argument -FIRDebugDisabled. + * + * It is also possible to change the default logging level in code by calling setLoggerLevel: on + * the FIRConfiguration interface. + */ +NS_SWIFT_NAME(FirebaseApp) +@interface FIRApp : NSObject + +/** + * Configures a default Firebase app. Raises an exception if any configuration step fails. The + * default app is named "__FIRAPP_DEFAULT". This method should be called after the app is launched + * and before using Firebase services. This method is thread safe and contains synchronous file I/O + * (reading GoogleService-Info.plist from disk). + */ ++ (void)configure; + +/** + * Configures the default Firebase app with the provided options. The default app is named + * "__FIRAPP_DEFAULT". Raises an exception if any configuration step fails. This method is thread + * safe. + * + * @param options The Firebase application options used to configure the service. + */ ++ (void)configureWithOptions:(FIROptions *)options NS_SWIFT_NAME(configure(options:)); + +/** + * Configures a Firebase app with the given name and options. Raises an exception if any + * configuration step fails. This method is thread safe. + * + * @param name The application's name given by the developer. The name should should only contain + Letters, Numbers and Underscore. + * @param options The Firebase application options used to configure the services. + */ +// clang-format off ++ (void)configureWithName:(NSString *)name + options:(FIROptions *)options NS_SWIFT_NAME(configure(name:options:)); +// clang-format on + +/** + * Returns the default app, or nil if the default app does not exist. + */ ++ (nullable FIRApp *)defaultApp NS_SWIFT_NAME(app()); + +/** + * Returns a previously created FIRApp instance with the given name, or nil if no such app exists. + * This method is thread safe. + */ ++ (nullable FIRApp *)appNamed:(NSString *)name NS_SWIFT_NAME(app(name:)); + +/** + * Returns the set of all extant FIRApp instances, or nil if there are no FIRApp instances. This + * method is thread safe. + */ +@property(class, readonly, nullable) NSDictionary *allApps; + +/** + * Cleans up the current FIRApp, freeing associated data and returning its name to the pool for + * future use. This method is thread safe. + */ +- (void)deleteApp:(FIRAppVoidBoolCallback)completion; + +/** + * FIRApp instances should not be initialized directly. Call +[FIRApp configure], + * +[FIRApp configureWithOptions:], or +[FIRApp configureWithNames:options:] directly. + */ +- (instancetype)init NS_UNAVAILABLE; + +/** + * Gets the name of this app. + */ +@property(nonatomic, copy, readonly) NSString *name; + +/** + * Gets a copy of the options for this app. These are non-modifiable. + */ +@property(nonatomic, copy, readonly) FIROptions *options; + +/** + * Gets or sets whether automatic data collection is enabled for all products. Defaults to `YES` + * unless `FirebaseDataCollectionDefaultEnabled` is set to `NO` in your app's Info.plist. This value + * is persisted across runs of the app so that it can be set once when users have consented to + * collection. + */ +@property(nonatomic, readwrite, getter=isDataCollectionDefaultEnabled) + BOOL dataCollectionDefaultEnabled; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseCore/Firebase/Core/Public/FIRConfiguration.h b/FoodApp/Pods/FirebaseCore/Firebase/Core/Public/FIRConfiguration.h new file mode 100644 index 0000000..b88fcaf --- /dev/null +++ b/FoodApp/Pods/FirebaseCore/Firebase/Core/Public/FIRConfiguration.h @@ -0,0 +1,52 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +#import "FIRAnalyticsConfiguration.h" +#import "FIRLoggerLevel.h" + +NS_ASSUME_NONNULL_BEGIN + +/** + * This interface provides global level properties that the developer can tweak, and the singleton + * of the Firebase Analytics configuration class. + */ +NS_SWIFT_NAME(FirebaseConfiguration) +@interface FIRConfiguration : NSObject + +/** Returns the shared configuration object. */ +@property(class, nonatomic, readonly) FIRConfiguration *sharedInstance NS_SWIFT_NAME(shared); + +/** The configuration class for Firebase Analytics. */ +@property(nonatomic, readwrite) + FIRAnalyticsConfiguration *analyticsConfiguration DEPRECATED_MSG_ATTRIBUTE( + "Use the methods available here directly on the `Analytics` class."); + +/** + * Sets the logging level for internal Firebase logging. Firebase will only log messages + * that are logged at or below loggerLevel. The messages are logged both to the Xcode + * console and to the device's log. Note that if an app is running from AppStore, it will + * never log above FIRLoggerLevelNotice even if loggerLevel is set to a higher (more verbose) + * setting. + * + * @param loggerLevel The maximum logging level. The default level is set to FIRLoggerLevelNotice. + */ +- (void)setLoggerLevel:(FIRLoggerLevel)loggerLevel; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseCore/Firebase/Core/Public/FIRLoggerLevel.h b/FoodApp/Pods/FirebaseCore/Firebase/Core/Public/FIRLoggerLevel.h new file mode 100644 index 0000000..dca3aa0 --- /dev/null +++ b/FoodApp/Pods/FirebaseCore/Firebase/Core/Public/FIRLoggerLevel.h @@ -0,0 +1,38 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +// Note that importing GULLoggerLevel.h will lead to a non-modular header +// import error. + +/** + * The log levels used by internal logging. + */ +typedef NS_ENUM(NSInteger, FIRLoggerLevel) { + /** Error level, matches ASL_LEVEL_ERR. */ + FIRLoggerLevelError = 3, + /** Warning level, matches ASL_LEVEL_WARNING. */ + FIRLoggerLevelWarning = 4, + /** Notice level, matches ASL_LEVEL_NOTICE. */ + FIRLoggerLevelNotice = 5, + /** Info level, matches ASL_LEVEL_INFO. */ + FIRLoggerLevelInfo = 6, + /** Debug level, matches ASL_LEVEL_DEBUG. */ + FIRLoggerLevelDebug = 7, + /** Minimum log level. */ + FIRLoggerLevelMin = FIRLoggerLevelError, + /** Maximum log level. */ + FIRLoggerLevelMax = FIRLoggerLevelDebug +} NS_SWIFT_NAME(FirebaseLoggerLevel); diff --git a/FoodApp/Pods/FirebaseCore/Firebase/Core/Public/FIROptions.h b/FoodApp/Pods/FirebaseCore/Firebase/Core/Public/FIROptions.h new file mode 100644 index 0000000..87a01dd --- /dev/null +++ b/FoodApp/Pods/FirebaseCore/Firebase/Core/Public/FIROptions.h @@ -0,0 +1,116 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * This class provides constant fields of Google APIs. + */ +NS_SWIFT_NAME(FirebaseOptions) +@interface FIROptions : NSObject + +/** + * Returns the default options. The first time this is called it synchronously reads + * GoogleService-Info.plist from disk. + */ ++ (nullable FIROptions *)defaultOptions NS_SWIFT_NAME(defaultOptions()); + +/** + * An iOS API key used for authenticating requests from your app, e.g. + * @"AIzaSyDdVgKwhZl0sTTTLZ7iTmt1r3N2cJLnaDk", used to identify your app to Google servers. + */ +@property(nonatomic, copy, nullable) NSString *APIKey NS_SWIFT_NAME(apiKey); + +/** + * The bundle ID for the application. Defaults to `[[NSBundle mainBundle] bundleID]` when not set + * manually or in a plist. + */ +@property(nonatomic, copy) NSString *bundleID; + +/** + * The OAuth2 client ID for iOS application used to authenticate Google users, for example + * @"12345.apps.googleusercontent.com", used for signing in with Google. + */ +@property(nonatomic, copy, nullable) NSString *clientID; + +/** + * The tracking ID for Google Analytics, e.g. @"UA-12345678-1", used to configure Google Analytics. + */ +@property(nonatomic, copy, nullable) NSString *trackingID; + +/** + * The Project Number from the Google Developer's console, for example @"012345678901", used to + * configure Google Cloud Messaging. + */ +@property(nonatomic, copy) NSString *GCMSenderID NS_SWIFT_NAME(gcmSenderID); + +/** + * The Project ID from the Firebase console, for example @"abc-xyz-123". + */ +@property(nonatomic, copy, nullable) NSString *projectID; + +/** + * The Android client ID used in Google AppInvite when an iOS app has its Android version, for + * example @"12345.apps.googleusercontent.com". + */ +@property(nonatomic, copy, nullable) NSString *androidClientID; + +/** + * The Google App ID that is used to uniquely identify an instance of an app. + */ +@property(nonatomic, copy) NSString *googleAppID; + +/** + * The database root URL, e.g. @"http://abc-xyz-123.firebaseio.com". + */ +@property(nonatomic, copy, nullable) NSString *databaseURL; + +/** + * The URL scheme used to set up Durable Deep Link service. + */ +@property(nonatomic, copy, nullable) NSString *deepLinkURLScheme; + +/** + * The Google Cloud Storage bucket name, e.g. @"abc-xyz-123.storage.firebase.com". + */ +@property(nonatomic, copy, nullable) NSString *storageBucket; + +/** + * Initializes a customized instance of FIROptions from the file at the given plist file path. This + * will read the file synchronously from disk. + * For example, + * NSString *filePath = + * [[NSBundle mainBundle] pathForResource:@"GoogleService-Info" ofType:@"plist"]; + * FIROptions *options = [[FIROptions alloc] initWithContentsOfFile:filePath]; + * Returns nil if the plist file does not exist or is invalid. + */ +- (nullable instancetype)initWithContentsOfFile:(NSString *)plistPath; + +/** + * Initializes a customized instance of FIROptions with required fields. Use the mutable properties + * to modify fields for configuring specific services. + */ +// clang-format off +- (instancetype)initWithGoogleAppID:(NSString *)googleAppID + GCMSenderID:(NSString *)GCMSenderID + NS_SWIFT_NAME(init(googleAppID:gcmSenderID:)); +// clang-format on + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseCore/Firebase/Core/Public/FirebaseCore.h b/FoodApp/Pods/FirebaseCore/Firebase/Core/Public/FirebaseCore.h new file mode 100644 index 0000000..fa26f69 --- /dev/null +++ b/FoodApp/Pods/FirebaseCore/Firebase/Core/Public/FirebaseCore.h @@ -0,0 +1,21 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRAnalyticsConfiguration.h" +#import "FIRApp.h" +#import "FIRConfiguration.h" +#import "FIRLoggerLevel.h" +#import "FIROptions.h" diff --git a/FoodApp/Pods/FirebaseCore/LICENSE b/FoodApp/Pods/FirebaseCore/LICENSE new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/FoodApp/Pods/FirebaseCore/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + 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. diff --git a/FoodApp/Pods/FirebaseCore/README.md b/FoodApp/Pods/FirebaseCore/README.md new file mode 100644 index 0000000..ad8de0f --- /dev/null +++ b/FoodApp/Pods/FirebaseCore/README.md @@ -0,0 +1,213 @@ +# Firebase iOS Open Source Development [![Build Status](https://travis-ci.org/firebase/firebase-ios-sdk.svg?branch=master)](https://travis-ci.org/firebase/firebase-ios-sdk) + +This repository contains a subset of the Firebase iOS SDK source. It currently +includes FirebaseCore, FirebaseAuth, FirebaseDatabase, FirebaseFirestore, +FirebaseFunctions, FirebaseInstanceID, FirebaseInAppMessaging, +FirebaseInAppMessagingDisplay, FirebaseMessaging and FirebaseStorage. + +The repository also includes GoogleUtilities source. The +[GoogleUtilities](GoogleUtilities/README.md) pod is +a set of utilities used by Firebase and other Google products. + +Firebase is an app development platform with tools to help you build, grow and +monetize your app. More information about Firebase can be found at +[https://firebase.google.com](https://firebase.google.com). + +## Installation + +See the three subsections for details about three different installation methods. +1. [Standard pod install](README.md#standard-pod-install) +1. [Installing from the GitHub repo](README.md#installing-from-github) +1. [Experimental Carthage](README.md#carthage-ios-only) + +### Standard pod install + +Go to +[https://firebase.google.com/docs/ios/setup](https://firebase.google.com/docs/ios/setup). + +### Installing from GitHub + +For releases starting with 5.0.0, the source for each release is also deployed +to CocoaPods master and available via standard +[CocoaPods Podfile syntax](https://guides.cocoapods.org/syntax/podfile.html#pod). + +These instructions can be used to access the Firebase repo at other branches, +tags, or commits. + +#### Background + +See +[the Podfile Syntax Reference](https://guides.cocoapods.org/syntax/podfile.html#pod) +for instructions and options about overriding pod source locations. + +#### Accessing Firebase Source Snapshots + +All of the official releases are tagged in this repo and available via CocoaPods. To access a local +source snapshot or unreleased branch, use Podfile directives like the following: + +To access FirebaseFirestore via a branch: +``` +pod 'FirebaseCore', :git => 'https://github.com/firebase/firebase-ios-sdk.git', :branch => 'master' +pod 'FirebaseFirestore', :git => 'https://github.com/firebase/firebase-ios-sdk.git', :branch => 'master' +``` + +To access FirebaseMessaging via a checked out version of the firebase-ios-sdk repo do: + +``` +pod 'FirebaseCore', :path => '/path/to/firebase-ios-sdk' +pod 'FirebaseMessaging', :path => '/path/to/firebase-ios-sdk' +``` + +### Carthage (iOS only) + +Instructions for the experimental Carthage distribution are at +[Carthage](Carthage.md). + +### Rome + +Instructions for installing binary frameworks via +[Rome](https://github.com/CocoaPods/Rome) are at [Rome](Rome.md). + +## Development + +Follow the subsequent instructions to develop, debug, unit test, run integration +tests, and try out reference samples: + +``` +$ git clone git@github.com:firebase/firebase-ios-sdk.git +$ cd firebase-ios-sdk/Example +$ pod update +$ open Firebase.xcworkspace +``` + +Firestore and Functions have self contained Xcode projects. See +[Firestore/README.md](Firestore/README.md) and +[Functions/README.md](Functions/README.md). + +### Code Formatting + +To ensure that the code is formatted consistently, run the script +[./scripts/style.sh](https://github.com/firebase/firebase-ios-sdk/blob/master/scripts/style.sh) +before creating a PR. + +Travis will verify that any code changes are done in a style compliant way. Install +`clang-format` and `swiftformat`. +This command will get the right `clang-format` version: + +`brew install https://raw.githubusercontent.com/Homebrew/homebrew-core/773cb75d360b58f32048f5964038d09825a507c8/Formula/clang-format.rb` + +### Running Unit Tests + +Select a scheme and press Command-u to build a component and run its unit tests. + +#### Viewing Code Coverage + +First, make sure that [xcov](https://github.com/nakiostudio/xcov) is installed with `gem install xcov`. + +After running the `AllUnitTests_iOS` scheme in Xcode, execute +`xcov --workspace Firebase.xcworkspace --scheme AllUnitTests_iOS --output_directory xcov_output` +at Example/ in the terminal. This will aggregate the coverage, and you can run `open xcov_output/index.html` to see the results. + +### Running Sample Apps +In order to run the sample apps and integration tests, you'll need valid +`GoogleService-Info.plist` files for those samples. The Firebase Xcode project contains dummy plist +files without real values, but can be replaced with real plist files. To get your own +`GoogleService-Info.plist` files: + +1. Go to the [Firebase Console](https://console.firebase.google.com/) +2. Create a new Firebase project, if you don't already have one +3. For each sample app you want to test, create a new Firebase app with the sample app's bundle +identifier (e.g. `com.google.Database-Example`) +4. Download the resulting `GoogleService-Info.plist` and replace the appropriate dummy plist file +(e.g. in [Example/Database/App/](Example/Database/App/)); + +Some sample apps like Firebase Messaging ([Example/Messaging/App](Example/Messaging/App)) require +special Apple capabilities, and you will have to change the sample app to use a unique bundle +identifier that you can control in your own Apple Developer account. + +## Specific Component Instructions +See the sections below for any special instructions for those components. + +### Firebase Auth + +If you're doing specific Firebase Auth development, see +[the Auth Sample README](Example/Auth/README.md) for instructions about +building and running the FirebaseAuth pod along with various samples and tests. + +### Firebase Database + +To run the Database Integration tests, make your database authentication rules +[public](https://firebase.google.com/docs/database/security/quickstart). + +### Firebase Storage + +To run the Storage Integration tests, follow the instructions in +[FIRStorageIntegrationTests.m](Example/Storage/Tests/Integration/FIRStorageIntegrationTests.m). + +#### Push Notifications + +Push notifications can only be delivered to specially provisioned App IDs in the developer portal. +In order to actually test receiving push notifications, you will need to: + +1. Change the bundle identifier of the sample app to something you own in your Apple Developer +account, and enable that App ID for push notifications. +2. You'll also need to +[upload your APNs Provider Authentication Key or certificate to the Firebase Console](https://firebase.google.com/docs/cloud-messaging/ios/certs) +at **Project Settings > Cloud Messaging > [Your Firebase App]**. +3. Ensure your iOS device is added to your Apple Developer portal as a test device. + +#### iOS Simulator + +The iOS Simulator cannot register for remote notifications, and will not receive push notifications. +In order to receive push notifications, you'll have to follow the steps above and run the app on a +physical device. + +## Community Supported Efforts + +We've seen an amazing amount of interest and contributions to improve the Firebase SDKs, and we are +very grateful! We'd like to empower as many developers as we can to be able to use Firebase and +participate in the Firebase community. + +### macOS and tvOS +Thanks to contributions from the community, FirebaseAuth, FirebaseCore, FirebaseDatabase, +FirebaseFunctions and FirebaseStorage now compile, run unit tests, and work on macOS and tvOS. +FirebaseFirestore is availiable for macOS and FirebaseMessaging for tvOS. + +For tvOS, checkout the [Sample](Example/tvOSSample). + +Keep in mind that macOS and tvOS are not officially supported by Firebase, and this repository is +actively developed primarily for iOS. While we can catch basic unit test issues with Travis, there +may be some changes where the SDK no longer works as expected on macOS or tvOS. If you encounter +this, please [file an issue](https://github.com/firebase/firebase-ios-sdk/issues). + +Note that the Firebase pod is not available for macOS and tvOS. + +To install, add a subset of the following to the Podfile: + +``` +pod 'FirebaseAuth' +pod 'FirebaseCore' +pod 'FirebaseDatabase' +pod 'FirebaseFirestore' # Only iOS and macOS +pod 'FirebaseFunctions' +pod 'FirebaseMessaging' # Only iOS and tvOS +pod 'FirebaseStorage' +``` + +## Roadmap + +See [Roadmap](ROADMAP.md) for more about the Firebase iOS SDK Open Source +plans and directions. + +## Contributing + +See [Contributing](CONTRIBUTING.md) for more information on contributing to the Firebase +iOS SDK. + +## License + +The contents of this repository is licensed under the +[Apache License, version 2.0](http://www.apache.org/licenses/LICENSE-2.0). + +Your use of Firebase is governed by the +[Terms of Service for Firebase Services](https://firebase.google.com/terms/). diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/firestore/local/maybe_document.nanopb.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/firestore/local/maybe_document.nanopb.cc new file mode 100644 index 0000000..0295f6e --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/firestore/local/maybe_document.nanopb.cc @@ -0,0 +1,80 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +/* Automatically generated nanopb constant definitions */ +/* Generated by nanopb-0.3.9.1 */ + +#include "maybe_document.nanopb.h" + +namespace firebase { +namespace firestore { + +/* @@protoc_insertion_point(includes) */ +#if PB_PROTO_HEADER_VERSION != 30 +#error Regenerate this file with the current version of nanopb generator. +#endif + + + +const pb_field_t firestore_client_NoDocument_fields[3] = { + PB_FIELD( 1, BYTES , SINGULAR, POINTER , FIRST, firestore_client_NoDocument, name, name, 0), + PB_FIELD( 2, MESSAGE , SINGULAR, STATIC , OTHER, firestore_client_NoDocument, read_time, name, &google_protobuf_Timestamp_fields), + PB_LAST_FIELD +}; + +const pb_field_t firestore_client_UnknownDocument_fields[3] = { + PB_FIELD( 1, BYTES , SINGULAR, POINTER , FIRST, firestore_client_UnknownDocument, name, name, 0), + PB_FIELD( 2, MESSAGE , SINGULAR, STATIC , OTHER, firestore_client_UnknownDocument, version, name, &google_protobuf_Timestamp_fields), + PB_LAST_FIELD +}; + +const pb_field_t firestore_client_MaybeDocument_fields[5] = { + PB_ANONYMOUS_ONEOF_FIELD(document_type, 1, MESSAGE , ONEOF, STATIC , FIRST, firestore_client_MaybeDocument, no_document, no_document, &firestore_client_NoDocument_fields), + PB_ANONYMOUS_ONEOF_FIELD(document_type, 2, MESSAGE , ONEOF, STATIC , UNION, firestore_client_MaybeDocument, document, document, &google_firestore_v1_Document_fields), + PB_ANONYMOUS_ONEOF_FIELD(document_type, 3, MESSAGE , ONEOF, STATIC , UNION, firestore_client_MaybeDocument, unknown_document, unknown_document, &firestore_client_UnknownDocument_fields), + PB_FIELD( 4, BOOL , SINGULAR, STATIC , OTHER, firestore_client_MaybeDocument, has_committed_mutations, unknown_document, 0), + PB_LAST_FIELD +}; + + +/* Check that field information fits in pb_field_t */ +#if !defined(PB_FIELD_32BIT) +/* If you get an error here, it means that you need to define PB_FIELD_32BIT + * compile-time option. You can do that in pb.h or on compiler command line. + * + * The reason you need to do this is that some of your messages contain tag + * numbers or field sizes that are larger than what can fit in 8 or 16 bit + * field descriptors. + */ +PB_STATIC_ASSERT((pb_membersize(firestore_client_NoDocument, read_time) < 65536 && pb_membersize(firestore_client_UnknownDocument, version) < 65536 && pb_membersize(firestore_client_MaybeDocument, no_document) < 65536 && pb_membersize(firestore_client_MaybeDocument, document) < 65536 && pb_membersize(firestore_client_MaybeDocument, unknown_document) < 65536), YOU_MUST_DEFINE_PB_FIELD_32BIT_FOR_MESSAGES_firestore_client_NoDocument_firestore_client_UnknownDocument_firestore_client_MaybeDocument) +#endif + +#if !defined(PB_FIELD_16BIT) && !defined(PB_FIELD_32BIT) +/* If you get an error here, it means that you need to define PB_FIELD_16BIT + * compile-time option. You can do that in pb.h or on compiler command line. + * + * The reason you need to do this is that some of your messages contain tag + * numbers or field sizes that are larger than what can fit in the default + * 8 bit descriptors. + */ +PB_STATIC_ASSERT((pb_membersize(firestore_client_NoDocument, read_time) < 256 && pb_membersize(firestore_client_UnknownDocument, version) < 256 && pb_membersize(firestore_client_MaybeDocument, no_document) < 256 && pb_membersize(firestore_client_MaybeDocument, document) < 256 && pb_membersize(firestore_client_MaybeDocument, unknown_document) < 256), YOU_MUST_DEFINE_PB_FIELD_16BIT_FOR_MESSAGES_firestore_client_NoDocument_firestore_client_UnknownDocument_firestore_client_MaybeDocument) +#endif + + +} // namespace firestore +} // namespace firebase + +/* @@protoc_insertion_point(eof) */ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/firestore/local/maybe_document.nanopb.h b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/firestore/local/maybe_document.nanopb.h new file mode 100644 index 0000000..5422e41 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/firestore/local/maybe_document.nanopb.h @@ -0,0 +1,104 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +/* Automatically generated nanopb header */ +/* Generated by nanopb-0.3.9.1 */ + +#ifndef PB_FIRESTORE_CLIENT_MAYBE_DOCUMENT_NANOPB_H_INCLUDED +#define PB_FIRESTORE_CLIENT_MAYBE_DOCUMENT_NANOPB_H_INCLUDED +#include + +#include "google/firestore/v1/document.nanopb.h" + +#include "google/protobuf/timestamp.nanopb.h" + +namespace firebase { +namespace firestore { + +/* @@protoc_insertion_point(includes) */ +#if PB_PROTO_HEADER_VERSION != 30 +#error Regenerate this file with the current version of nanopb generator. +#endif + + +/* Struct definitions */ +typedef struct _firestore_client_NoDocument { + pb_bytes_array_t *name; + google_protobuf_Timestamp read_time; +/* @@protoc_insertion_point(struct:firestore_client_NoDocument) */ +} firestore_client_NoDocument; + +typedef struct _firestore_client_UnknownDocument { + pb_bytes_array_t *name; + google_protobuf_Timestamp version; +/* @@protoc_insertion_point(struct:firestore_client_UnknownDocument) */ +} firestore_client_UnknownDocument; + +typedef struct _firestore_client_MaybeDocument { + pb_size_t which_document_type; + union { + firestore_client_NoDocument no_document; + google_firestore_v1_Document document; + firestore_client_UnknownDocument unknown_document; + }; + bool has_committed_mutations; +/* @@protoc_insertion_point(struct:firestore_client_MaybeDocument) */ +} firestore_client_MaybeDocument; + +/* Default values for struct fields */ + +/* Initializer values for message structs */ +#define firestore_client_NoDocument_init_default {NULL, google_protobuf_Timestamp_init_default} +#define firestore_client_UnknownDocument_init_default {NULL, google_protobuf_Timestamp_init_default} +#define firestore_client_MaybeDocument_init_default {0, {firestore_client_NoDocument_init_default}, 0} +#define firestore_client_NoDocument_init_zero {NULL, google_protobuf_Timestamp_init_zero} +#define firestore_client_UnknownDocument_init_zero {NULL, google_protobuf_Timestamp_init_zero} +#define firestore_client_MaybeDocument_init_zero {0, {firestore_client_NoDocument_init_zero}, 0} + +/* Field tags (for use in manual encoding/decoding) */ +#define firestore_client_NoDocument_name_tag 1 +#define firestore_client_NoDocument_read_time_tag 2 +#define firestore_client_UnknownDocument_name_tag 1 +#define firestore_client_UnknownDocument_version_tag 2 +#define firestore_client_MaybeDocument_no_document_tag 1 +#define firestore_client_MaybeDocument_document_tag 2 +#define firestore_client_MaybeDocument_unknown_document_tag 3 +#define firestore_client_MaybeDocument_has_committed_mutations_tag 4 + +/* Struct field encoding specification for nanopb */ +extern const pb_field_t firestore_client_NoDocument_fields[3]; +extern const pb_field_t firestore_client_UnknownDocument_fields[3]; +extern const pb_field_t firestore_client_MaybeDocument_fields[5]; + +/* Maximum encoded size of messages (where known) */ +/* firestore_client_NoDocument_size depends on runtime parameters */ +/* firestore_client_UnknownDocument_size depends on runtime parameters */ +#define firestore_client_MaybeDocument_size (2 + (((firestore_client_NoDocument_size > firestore_client_UnknownDocument_size ? firestore_client_NoDocument_size : firestore_client_UnknownDocument_size) > google_firestore_v1_Document_size ? (firestore_client_NoDocument_size > firestore_client_UnknownDocument_size ? firestore_client_NoDocument_size : firestore_client_UnknownDocument_size) : google_firestore_v1_Document_size) > 0 ? ((firestore_client_NoDocument_size > firestore_client_UnknownDocument_size ? firestore_client_NoDocument_size : firestore_client_UnknownDocument_size) > google_firestore_v1_Document_size ? (firestore_client_NoDocument_size > firestore_client_UnknownDocument_size ? firestore_client_NoDocument_size : firestore_client_UnknownDocument_size) : google_firestore_v1_Document_size) : 0)) + +/* Message IDs (where set with "msgid" option) */ +#ifdef PB_MSGID + +#define MAYBE_DOCUMENT_MESSAGES \ + + +#endif + +} // namespace firestore +} // namespace firebase + +/* @@protoc_insertion_point(eof) */ + +#endif diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/firestore/local/mutation.nanopb.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/firestore/local/mutation.nanopb.cc new file mode 100644 index 0000000..c9e68d8 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/firestore/local/mutation.nanopb.cc @@ -0,0 +1,74 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +/* Automatically generated nanopb constant definitions */ +/* Generated by nanopb-0.3.9.1 */ + +#include "mutation.nanopb.h" + +namespace firebase { +namespace firestore { + +/* @@protoc_insertion_point(includes) */ +#if PB_PROTO_HEADER_VERSION != 30 +#error Regenerate this file with the current version of nanopb generator. +#endif + + + +const pb_field_t firestore_client_MutationQueue_fields[3] = { + PB_FIELD( 1, INT32 , SINGULAR, STATIC , FIRST, firestore_client_MutationQueue, last_acknowledged_batch_id, last_acknowledged_batch_id, 0), + PB_FIELD( 2, BYTES , SINGULAR, POINTER , OTHER, firestore_client_MutationQueue, last_stream_token, last_acknowledged_batch_id, 0), + PB_LAST_FIELD +}; + +const pb_field_t firestore_client_WriteBatch_fields[5] = { + PB_FIELD( 1, INT32 , SINGULAR, STATIC , FIRST, firestore_client_WriteBatch, batch_id, batch_id, 0), + PB_FIELD( 2, MESSAGE , REPEATED, POINTER , OTHER, firestore_client_WriteBatch, writes, batch_id, &google_firestore_v1_Write_fields), + PB_FIELD( 3, MESSAGE , SINGULAR, STATIC , OTHER, firestore_client_WriteBatch, local_write_time, writes, &google_protobuf_Timestamp_fields), + PB_FIELD( 4, MESSAGE , REPEATED, POINTER , OTHER, firestore_client_WriteBatch, base_writes, local_write_time, &google_firestore_v1_Write_fields), + PB_LAST_FIELD +}; + + +/* Check that field information fits in pb_field_t */ +#if !defined(PB_FIELD_32BIT) +/* If you get an error here, it means that you need to define PB_FIELD_32BIT + * compile-time option. You can do that in pb.h or on compiler command line. + * + * The reason you need to do this is that some of your messages contain tag + * numbers or field sizes that are larger than what can fit in 8 or 16 bit + * field descriptors. + */ +PB_STATIC_ASSERT((pb_membersize(firestore_client_WriteBatch, local_write_time) < 65536), YOU_MUST_DEFINE_PB_FIELD_32BIT_FOR_MESSAGES_firestore_client_MutationQueue_firestore_client_WriteBatch) +#endif + +#if !defined(PB_FIELD_16BIT) && !defined(PB_FIELD_32BIT) +/* If you get an error here, it means that you need to define PB_FIELD_16BIT + * compile-time option. You can do that in pb.h or on compiler command line. + * + * The reason you need to do this is that some of your messages contain tag + * numbers or field sizes that are larger than what can fit in the default + * 8 bit descriptors. + */ +PB_STATIC_ASSERT((pb_membersize(firestore_client_WriteBatch, local_write_time) < 256), YOU_MUST_DEFINE_PB_FIELD_16BIT_FOR_MESSAGES_firestore_client_MutationQueue_firestore_client_WriteBatch) +#endif + + +} // namespace firestore +} // namespace firebase + +/* @@protoc_insertion_point(eof) */ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/firestore/local/mutation.nanopb.h b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/firestore/local/mutation.nanopb.h new file mode 100644 index 0000000..59efa45 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/firestore/local/mutation.nanopb.h @@ -0,0 +1,91 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +/* Automatically generated nanopb header */ +/* Generated by nanopb-0.3.9.1 */ + +#ifndef PB_FIRESTORE_CLIENT_MUTATION_NANOPB_H_INCLUDED +#define PB_FIRESTORE_CLIENT_MUTATION_NANOPB_H_INCLUDED +#include + +#include "google/firestore/v1/write.nanopb.h" + +#include "google/protobuf/timestamp.nanopb.h" + +namespace firebase { +namespace firestore { + +/* @@protoc_insertion_point(includes) */ +#if PB_PROTO_HEADER_VERSION != 30 +#error Regenerate this file with the current version of nanopb generator. +#endif + + +/* Struct definitions */ +typedef struct _firestore_client_MutationQueue { + int32_t last_acknowledged_batch_id; + pb_bytes_array_t *last_stream_token; +/* @@protoc_insertion_point(struct:firestore_client_MutationQueue) */ +} firestore_client_MutationQueue; + +typedef struct _firestore_client_WriteBatch { + int32_t batch_id; + pb_size_t writes_count; + struct _google_firestore_v1_Write *writes; + google_protobuf_Timestamp local_write_time; + pb_size_t base_writes_count; + struct _google_firestore_v1_Write *base_writes; +/* @@protoc_insertion_point(struct:firestore_client_WriteBatch) */ +} firestore_client_WriteBatch; + +/* Default values for struct fields */ + +/* Initializer values for message structs */ +#define firestore_client_MutationQueue_init_default {0, NULL} +#define firestore_client_WriteBatch_init_default {0, 0, NULL, google_protobuf_Timestamp_init_default, 0, NULL} +#define firestore_client_MutationQueue_init_zero {0, NULL} +#define firestore_client_WriteBatch_init_zero {0, 0, NULL, google_protobuf_Timestamp_init_zero, 0, NULL} + +/* Field tags (for use in manual encoding/decoding) */ +#define firestore_client_MutationQueue_last_acknowledged_batch_id_tag 1 +#define firestore_client_MutationQueue_last_stream_token_tag 2 +#define firestore_client_WriteBatch_batch_id_tag 1 +#define firestore_client_WriteBatch_writes_tag 2 +#define firestore_client_WriteBatch_local_write_time_tag 3 +#define firestore_client_WriteBatch_base_writes_tag 4 + +/* Struct field encoding specification for nanopb */ +extern const pb_field_t firestore_client_MutationQueue_fields[3]; +extern const pb_field_t firestore_client_WriteBatch_fields[5]; + +/* Maximum encoded size of messages (where known) */ +/* firestore_client_MutationQueue_size depends on runtime parameters */ +/* firestore_client_WriteBatch_size depends on runtime parameters */ + +/* Message IDs (where set with "msgid" option) */ +#ifdef PB_MSGID + +#define MUTATION_MESSAGES \ + + +#endif + +} // namespace firestore +} // namespace firebase + +/* @@protoc_insertion_point(eof) */ + +#endif diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/firestore/local/target.nanopb.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/firestore/local/target.nanopb.cc new file mode 100644 index 0000000..74223ca --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/firestore/local/target.nanopb.cc @@ -0,0 +1,78 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +/* Automatically generated nanopb constant definitions */ +/* Generated by nanopb-0.3.9.1 */ + +#include "target.nanopb.h" + +namespace firebase { +namespace firestore { + +/* @@protoc_insertion_point(includes) */ +#if PB_PROTO_HEADER_VERSION != 30 +#error Regenerate this file with the current version of nanopb generator. +#endif + + + +const pb_field_t firestore_client_Target_fields[7] = { + PB_FIELD( 1, INT32 , SINGULAR, STATIC , FIRST, firestore_client_Target, target_id, target_id, 0), + PB_FIELD( 2, MESSAGE , SINGULAR, STATIC , OTHER, firestore_client_Target, snapshot_version, target_id, &google_protobuf_Timestamp_fields), + PB_FIELD( 3, BYTES , SINGULAR, POINTER , OTHER, firestore_client_Target, resume_token, snapshot_version, 0), + PB_FIELD( 4, INT64 , SINGULAR, STATIC , OTHER, firestore_client_Target, last_listen_sequence_number, resume_token, 0), + PB_ANONYMOUS_ONEOF_FIELD(target_type, 5, MESSAGE , ONEOF, STATIC , OTHER, firestore_client_Target, query, last_listen_sequence_number, &google_firestore_v1_Target_QueryTarget_fields), + PB_ANONYMOUS_ONEOF_FIELD(target_type, 6, MESSAGE , ONEOF, STATIC , UNION, firestore_client_Target, documents, last_listen_sequence_number, &google_firestore_v1_Target_DocumentsTarget_fields), + PB_LAST_FIELD +}; + +const pb_field_t firestore_client_TargetGlobal_fields[5] = { + PB_FIELD( 1, INT32 , SINGULAR, STATIC , FIRST, firestore_client_TargetGlobal, highest_target_id, highest_target_id, 0), + PB_FIELD( 2, INT64 , SINGULAR, STATIC , OTHER, firestore_client_TargetGlobal, highest_listen_sequence_number, highest_target_id, 0), + PB_FIELD( 3, MESSAGE , SINGULAR, STATIC , OTHER, firestore_client_TargetGlobal, last_remote_snapshot_version, highest_listen_sequence_number, &google_protobuf_Timestamp_fields), + PB_FIELD( 4, INT32 , SINGULAR, STATIC , OTHER, firestore_client_TargetGlobal, target_count, last_remote_snapshot_version, 0), + PB_LAST_FIELD +}; + + +/* Check that field information fits in pb_field_t */ +#if !defined(PB_FIELD_32BIT) +/* If you get an error here, it means that you need to define PB_FIELD_32BIT + * compile-time option. You can do that in pb.h or on compiler command line. + * + * The reason you need to do this is that some of your messages contain tag + * numbers or field sizes that are larger than what can fit in 8 or 16 bit + * field descriptors. + */ +PB_STATIC_ASSERT((pb_membersize(firestore_client_Target, query) < 65536 && pb_membersize(firestore_client_Target, documents) < 65536 && pb_membersize(firestore_client_Target, snapshot_version) < 65536 && pb_membersize(firestore_client_TargetGlobal, last_remote_snapshot_version) < 65536), YOU_MUST_DEFINE_PB_FIELD_32BIT_FOR_MESSAGES_firestore_client_Target_firestore_client_TargetGlobal) +#endif + +#if !defined(PB_FIELD_16BIT) && !defined(PB_FIELD_32BIT) +/* If you get an error here, it means that you need to define PB_FIELD_16BIT + * compile-time option. You can do that in pb.h or on compiler command line. + * + * The reason you need to do this is that some of your messages contain tag + * numbers or field sizes that are larger than what can fit in the default + * 8 bit descriptors. + */ +PB_STATIC_ASSERT((pb_membersize(firestore_client_Target, query) < 256 && pb_membersize(firestore_client_Target, documents) < 256 && pb_membersize(firestore_client_Target, snapshot_version) < 256 && pb_membersize(firestore_client_TargetGlobal, last_remote_snapshot_version) < 256), YOU_MUST_DEFINE_PB_FIELD_16BIT_FOR_MESSAGES_firestore_client_Target_firestore_client_TargetGlobal) +#endif + + +} // namespace firestore +} // namespace firebase + +/* @@protoc_insertion_point(eof) */ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/firestore/local/target.nanopb.h b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/firestore/local/target.nanopb.h new file mode 100644 index 0000000..5feacc3 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/firestore/local/target.nanopb.h @@ -0,0 +1,100 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +/* Automatically generated nanopb header */ +/* Generated by nanopb-0.3.9.1 */ + +#ifndef PB_FIRESTORE_CLIENT_TARGET_NANOPB_H_INCLUDED +#define PB_FIRESTORE_CLIENT_TARGET_NANOPB_H_INCLUDED +#include + +#include "google/firestore/v1/firestore.nanopb.h" + +#include "google/protobuf/timestamp.nanopb.h" + +namespace firebase { +namespace firestore { + +/* @@protoc_insertion_point(includes) */ +#if PB_PROTO_HEADER_VERSION != 30 +#error Regenerate this file with the current version of nanopb generator. +#endif + + +/* Struct definitions */ +typedef struct _firestore_client_Target { + int32_t target_id; + google_protobuf_Timestamp snapshot_version; + pb_bytes_array_t *resume_token; + int64_t last_listen_sequence_number; + pb_size_t which_target_type; + union { + google_firestore_v1_Target_QueryTarget query; + google_firestore_v1_Target_DocumentsTarget documents; + }; +/* @@protoc_insertion_point(struct:firestore_client_Target) */ +} firestore_client_Target; + +typedef struct _firestore_client_TargetGlobal { + int32_t highest_target_id; + int64_t highest_listen_sequence_number; + google_protobuf_Timestamp last_remote_snapshot_version; + int32_t target_count; +/* @@protoc_insertion_point(struct:firestore_client_TargetGlobal) */ +} firestore_client_TargetGlobal; + +/* Default values for struct fields */ + +/* Initializer values for message structs */ +#define firestore_client_Target_init_default {0, google_protobuf_Timestamp_init_default, NULL, 0, 0, {google_firestore_v1_Target_QueryTarget_init_default}} +#define firestore_client_TargetGlobal_init_default {0, 0, google_protobuf_Timestamp_init_default, 0} +#define firestore_client_Target_init_zero {0, google_protobuf_Timestamp_init_zero, NULL, 0, 0, {google_firestore_v1_Target_QueryTarget_init_zero}} +#define firestore_client_TargetGlobal_init_zero {0, 0, google_protobuf_Timestamp_init_zero, 0} + +/* Field tags (for use in manual encoding/decoding) */ +#define firestore_client_Target_query_tag 5 +#define firestore_client_Target_documents_tag 6 +#define firestore_client_Target_target_id_tag 1 +#define firestore_client_Target_snapshot_version_tag 2 +#define firestore_client_Target_resume_token_tag 3 +#define firestore_client_Target_last_listen_sequence_number_tag 4 +#define firestore_client_TargetGlobal_highest_target_id_tag 1 +#define firestore_client_TargetGlobal_highest_listen_sequence_number_tag 2 +#define firestore_client_TargetGlobal_last_remote_snapshot_version_tag 3 +#define firestore_client_TargetGlobal_target_count_tag 4 + +/* Struct field encoding specification for nanopb */ +extern const pb_field_t firestore_client_Target_fields[7]; +extern const pb_field_t firestore_client_TargetGlobal_fields[5]; + +/* Maximum encoded size of messages (where known) */ +/* firestore_client_Target_size depends on runtime parameters */ +#define firestore_client_TargetGlobal_size 57 + +/* Message IDs (where set with "msgid" option) */ +#ifdef PB_MSGID + +#define TARGET_MESSAGES \ + + +#endif + +} // namespace firestore +} // namespace firebase + +/* @@protoc_insertion_point(eof) */ + +#endif diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/google/api/annotations.nanopb.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/google/api/annotations.nanopb.cc new file mode 100644 index 0000000..613bcf6 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/google/api/annotations.nanopb.cc @@ -0,0 +1,43 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +/* Automatically generated nanopb constant definitions */ +/* Generated by nanopb-0.3.9.1 */ + +#include "annotations.nanopb.h" + +namespace firebase { +namespace firestore { + +/* @@protoc_insertion_point(includes) */ +#if PB_PROTO_HEADER_VERSION != 30 +#error Regenerate this file with the current version of nanopb generator. +#endif + + + + + +/* Check that field information fits in pb_field_t */ +#if !defined(PB_FIELD_32BIT) +#error Field descriptor for google_api_http_struct.http is too large. Define PB_FIELD_32BIT to fix this. +#endif + + +} // namespace firestore +} // namespace firebase + +/* @@protoc_insertion_point(eof) */ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/google/api/annotations.nanopb.h b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/google/api/annotations.nanopb.h new file mode 100644 index 0000000..2ef2a03 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/google/api/annotations.nanopb.h @@ -0,0 +1,44 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +/* Automatically generated nanopb header */ +/* Generated by nanopb-0.3.9.1 */ + +#ifndef PB_GOOGLE_API_ANNOTATIONS_NANOPB_H_INCLUDED +#define PB_GOOGLE_API_ANNOTATIONS_NANOPB_H_INCLUDED +#include + +#include "google/api/http.nanopb.h" + +namespace firebase { +namespace firestore { + +/* @@protoc_insertion_point(includes) */ +#if PB_PROTO_HEADER_VERSION != 30 +#error Regenerate this file with the current version of nanopb generator. +#endif + + +/* Extensions */ +/* Extension field google_api_http was skipped because only "optional" + type of extension fields is currently supported. */ + +} // namespace firestore +} // namespace firebase + +/* @@protoc_insertion_point(eof) */ + +#endif diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/google/api/http.nanopb.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/google/api/http.nanopb.cc new file mode 100644 index 0000000..151b1fc --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/google/api/http.nanopb.cc @@ -0,0 +1,85 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +/* Automatically generated nanopb constant definitions */ +/* Generated by nanopb-0.3.9.1 */ + +#include "http.nanopb.h" + +namespace firebase { +namespace firestore { + +/* @@protoc_insertion_point(includes) */ +#if PB_PROTO_HEADER_VERSION != 30 +#error Regenerate this file with the current version of nanopb generator. +#endif + + + +const pb_field_t google_api_Http_fields[3] = { + PB_FIELD( 1, MESSAGE , REPEATED, POINTER , FIRST, google_api_Http, rules, rules, &google_api_HttpRule_fields), + PB_FIELD( 2, BOOL , SINGULAR, STATIC , OTHER, google_api_Http, fully_decode_reserved_expansion, rules, 0), + PB_LAST_FIELD +}; + +const pb_field_t google_api_HttpRule_fields[10] = { + PB_FIELD( 1, BYTES , SINGULAR, POINTER , FIRST, google_api_HttpRule, selector, selector, 0), + PB_ANONYMOUS_ONEOF_FIELD(pattern, 2, BYTES , ONEOF, POINTER , OTHER, google_api_HttpRule, get, selector, 0), + PB_ANONYMOUS_ONEOF_FIELD(pattern, 3, BYTES , ONEOF, POINTER , UNION, google_api_HttpRule, put, selector, 0), + PB_ANONYMOUS_ONEOF_FIELD(pattern, 4, BYTES , ONEOF, POINTER , UNION, google_api_HttpRule, post, selector, 0), + PB_ANONYMOUS_ONEOF_FIELD(pattern, 5, BYTES , ONEOF, POINTER , UNION, google_api_HttpRule, delete_, selector, 0), + PB_ANONYMOUS_ONEOF_FIELD(pattern, 6, BYTES , ONEOF, POINTER , UNION, google_api_HttpRule, patch, selector, 0), + PB_ANONYMOUS_ONEOF_FIELD(pattern, 8, MESSAGE , ONEOF, STATIC , UNION, google_api_HttpRule, custom, selector, &google_api_CustomHttpPattern_fields), + PB_FIELD( 7, BYTES , SINGULAR, POINTER , OTHER, google_api_HttpRule, body, custom, 0), + PB_FIELD( 11, MESSAGE , REPEATED, POINTER , OTHER, google_api_HttpRule, additional_bindings, body, &google_api_HttpRule_fields), + PB_LAST_FIELD +}; + +const pb_field_t google_api_CustomHttpPattern_fields[3] = { + PB_FIELD( 1, BYTES , SINGULAR, POINTER , FIRST, google_api_CustomHttpPattern, kind, kind, 0), + PB_FIELD( 2, BYTES , SINGULAR, POINTER , OTHER, google_api_CustomHttpPattern, path, kind, 0), + PB_LAST_FIELD +}; + + +/* Check that field information fits in pb_field_t */ +#if !defined(PB_FIELD_32BIT) +/* If you get an error here, it means that you need to define PB_FIELD_32BIT + * compile-time option. You can do that in pb.h or on compiler command line. + * + * The reason you need to do this is that some of your messages contain tag + * numbers or field sizes that are larger than what can fit in 8 or 16 bit + * field descriptors. + */ +PB_STATIC_ASSERT((pb_membersize(google_api_HttpRule, custom) < 65536), YOU_MUST_DEFINE_PB_FIELD_32BIT_FOR_MESSAGES_google_api_Http_google_api_HttpRule_google_api_CustomHttpPattern) +#endif + +#if !defined(PB_FIELD_16BIT) && !defined(PB_FIELD_32BIT) +/* If you get an error here, it means that you need to define PB_FIELD_16BIT + * compile-time option. You can do that in pb.h or on compiler command line. + * + * The reason you need to do this is that some of your messages contain tag + * numbers or field sizes that are larger than what can fit in the default + * 8 bit descriptors. + */ +PB_STATIC_ASSERT((pb_membersize(google_api_HttpRule, custom) < 256), YOU_MUST_DEFINE_PB_FIELD_16BIT_FOR_MESSAGES_google_api_Http_google_api_HttpRule_google_api_CustomHttpPattern) +#endif + + +} // namespace firestore +} // namespace firebase + +/* @@protoc_insertion_point(eof) */ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/google/api/http.nanopb.h b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/google/api/http.nanopb.h new file mode 100644 index 0000000..9e8ea1e --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/google/api/http.nanopb.h @@ -0,0 +1,112 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +/* Automatically generated nanopb header */ +/* Generated by nanopb-0.3.9.1 */ + +#ifndef PB_GOOGLE_API_HTTP_NANOPB_H_INCLUDED +#define PB_GOOGLE_API_HTTP_NANOPB_H_INCLUDED +#include + +namespace firebase { +namespace firestore { + +/* @@protoc_insertion_point(includes) */ +#if PB_PROTO_HEADER_VERSION != 30 +#error Regenerate this file with the current version of nanopb generator. +#endif + + +/* Struct definitions */ +typedef struct _google_api_CustomHttpPattern { + pb_bytes_array_t *kind; + pb_bytes_array_t *path; +/* @@protoc_insertion_point(struct:google_api_CustomHttpPattern) */ +} google_api_CustomHttpPattern; + +typedef struct _google_api_Http { + pb_size_t rules_count; + struct _google_api_HttpRule *rules; + bool fully_decode_reserved_expansion; +/* @@protoc_insertion_point(struct:google_api_Http) */ +} google_api_Http; + +typedef struct _google_api_HttpRule { + pb_bytes_array_t *selector; + pb_size_t which_pattern; + union { + pb_bytes_array_t *get; + pb_bytes_array_t *put; + pb_bytes_array_t *post; + pb_bytes_array_t *delete_; + pb_bytes_array_t *patch; + google_api_CustomHttpPattern custom; + }; + pb_bytes_array_t *body; + pb_size_t additional_bindings_count; + struct _google_api_HttpRule *additional_bindings; +/* @@protoc_insertion_point(struct:google_api_HttpRule) */ +} google_api_HttpRule; + +/* Default values for struct fields */ + +/* Initializer values for message structs */ +#define google_api_Http_init_default {0, NULL, 0} +#define google_api_HttpRule_init_default {NULL, 0, {NULL}, NULL, 0, NULL} +#define google_api_CustomHttpPattern_init_default {NULL, NULL} +#define google_api_Http_init_zero {0, NULL, 0} +#define google_api_HttpRule_init_zero {NULL, 0, {NULL}, NULL, 0, NULL} +#define google_api_CustomHttpPattern_init_zero {NULL, NULL} + +/* Field tags (for use in manual encoding/decoding) */ +#define google_api_CustomHttpPattern_kind_tag 1 +#define google_api_CustomHttpPattern_path_tag 2 +#define google_api_Http_rules_tag 1 +#define google_api_Http_fully_decode_reserved_expansion_tag 2 +#define google_api_HttpRule_get_tag 2 +#define google_api_HttpRule_put_tag 3 +#define google_api_HttpRule_post_tag 4 +#define google_api_HttpRule_delete_tag 5 +#define google_api_HttpRule_patch_tag 6 +#define google_api_HttpRule_custom_tag 8 +#define google_api_HttpRule_selector_tag 1 +#define google_api_HttpRule_body_tag 7 +#define google_api_HttpRule_additional_bindings_tag 11 + +/* Struct field encoding specification for nanopb */ +extern const pb_field_t google_api_Http_fields[3]; +extern const pb_field_t google_api_HttpRule_fields[10]; +extern const pb_field_t google_api_CustomHttpPattern_fields[3]; + +/* Maximum encoded size of messages (where known) */ +/* google_api_Http_size depends on runtime parameters */ +/* google_api_HttpRule_size depends on runtime parameters */ +/* google_api_CustomHttpPattern_size depends on runtime parameters */ + +/* Message IDs (where set with "msgid" option) */ +#ifdef PB_MSGID + +#define HTTP_MESSAGES \ + + +#endif + +} // namespace firestore +} // namespace firebase + +/* @@protoc_insertion_point(eof) */ + +#endif diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/google/firestore/v1/common.nanopb.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/google/firestore/v1/common.nanopb.cc new file mode 100644 index 0000000..08db6cc --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/google/firestore/v1/common.nanopb.cc @@ -0,0 +1,87 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +/* Automatically generated nanopb constant definitions */ +/* Generated by nanopb-0.3.9.1 */ + +#include "common.nanopb.h" + +namespace firebase { +namespace firestore { + +/* @@protoc_insertion_point(includes) */ +#if PB_PROTO_HEADER_VERSION != 30 +#error Regenerate this file with the current version of nanopb generator. +#endif + + + +const pb_field_t google_firestore_v1_DocumentMask_fields[2] = { + PB_FIELD( 1, BYTES , REPEATED, POINTER , FIRST, google_firestore_v1_DocumentMask, field_paths, field_paths, 0), + PB_LAST_FIELD +}; + +const pb_field_t google_firestore_v1_Precondition_fields[3] = { + PB_ANONYMOUS_ONEOF_FIELD(condition_type, 1, BOOL , ONEOF, STATIC , FIRST, google_firestore_v1_Precondition, exists, exists, 0), + PB_ANONYMOUS_ONEOF_FIELD(condition_type, 2, MESSAGE , ONEOF, STATIC , UNION, google_firestore_v1_Precondition, update_time, update_time, &google_protobuf_Timestamp_fields), + PB_LAST_FIELD +}; + +const pb_field_t google_firestore_v1_TransactionOptions_fields[3] = { + PB_ANONYMOUS_ONEOF_FIELD(mode, 2, MESSAGE , ONEOF, STATIC , FIRST, google_firestore_v1_TransactionOptions, read_only, read_only, &google_firestore_v1_TransactionOptions_ReadOnly_fields), + PB_ANONYMOUS_ONEOF_FIELD(mode, 3, MESSAGE , ONEOF, STATIC , UNION, google_firestore_v1_TransactionOptions, read_write, read_write, &google_firestore_v1_TransactionOptions_ReadWrite_fields), + PB_LAST_FIELD +}; + +const pb_field_t google_firestore_v1_TransactionOptions_ReadWrite_fields[2] = { + PB_FIELD( 1, BYTES , SINGULAR, POINTER , FIRST, google_firestore_v1_TransactionOptions_ReadWrite, retry_transaction, retry_transaction, 0), + PB_LAST_FIELD +}; + +const pb_field_t google_firestore_v1_TransactionOptions_ReadOnly_fields[2] = { + PB_ANONYMOUS_ONEOF_FIELD(consistency_selector, 2, MESSAGE , ONEOF, STATIC , FIRST, google_firestore_v1_TransactionOptions_ReadOnly, read_time, read_time, &google_protobuf_Timestamp_fields), + PB_LAST_FIELD +}; + + +/* Check that field information fits in pb_field_t */ +#if !defined(PB_FIELD_32BIT) +/* If you get an error here, it means that you need to define PB_FIELD_32BIT + * compile-time option. You can do that in pb.h or on compiler command line. + * + * The reason you need to do this is that some of your messages contain tag + * numbers or field sizes that are larger than what can fit in 8 or 16 bit + * field descriptors. + */ +PB_STATIC_ASSERT((pb_membersize(google_firestore_v1_Precondition, update_time) < 65536 && pb_membersize(google_firestore_v1_TransactionOptions, read_only) < 65536 && pb_membersize(google_firestore_v1_TransactionOptions, read_write) < 65536 && pb_membersize(google_firestore_v1_TransactionOptions_ReadOnly, read_time) < 65536), YOU_MUST_DEFINE_PB_FIELD_32BIT_FOR_MESSAGES_google_firestore_v1_DocumentMask_google_firestore_v1_Precondition_google_firestore_v1_TransactionOptions_google_firestore_v1_TransactionOptions_ReadWrite_google_firestore_v1_TransactionOptions_ReadOnly) +#endif + +#if !defined(PB_FIELD_16BIT) && !defined(PB_FIELD_32BIT) +/* If you get an error here, it means that you need to define PB_FIELD_16BIT + * compile-time option. You can do that in pb.h or on compiler command line. + * + * The reason you need to do this is that some of your messages contain tag + * numbers or field sizes that are larger than what can fit in the default + * 8 bit descriptors. + */ +PB_STATIC_ASSERT((pb_membersize(google_firestore_v1_Precondition, update_time) < 256 && pb_membersize(google_firestore_v1_TransactionOptions, read_only) < 256 && pb_membersize(google_firestore_v1_TransactionOptions, read_write) < 256 && pb_membersize(google_firestore_v1_TransactionOptions_ReadOnly, read_time) < 256), YOU_MUST_DEFINE_PB_FIELD_16BIT_FOR_MESSAGES_google_firestore_v1_DocumentMask_google_firestore_v1_Precondition_google_firestore_v1_TransactionOptions_google_firestore_v1_TransactionOptions_ReadWrite_google_firestore_v1_TransactionOptions_ReadOnly) +#endif + + +} // namespace firestore +} // namespace firebase + +/* @@protoc_insertion_point(eof) */ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/google/firestore/v1/common.nanopb.h b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/google/firestore/v1/common.nanopb.h new file mode 100644 index 0000000..c650f80 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/google/firestore/v1/common.nanopb.h @@ -0,0 +1,125 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +/* Automatically generated nanopb header */ +/* Generated by nanopb-0.3.9.1 */ + +#ifndef PB_GOOGLE_FIRESTORE_V1_COMMON_NANOPB_H_INCLUDED +#define PB_GOOGLE_FIRESTORE_V1_COMMON_NANOPB_H_INCLUDED +#include + +#include "google/api/annotations.nanopb.h" + +#include "google/protobuf/timestamp.nanopb.h" + +namespace firebase { +namespace firestore { + +/* @@protoc_insertion_point(includes) */ +#if PB_PROTO_HEADER_VERSION != 30 +#error Regenerate this file with the current version of nanopb generator. +#endif + + +/* Struct definitions */ +typedef struct _google_firestore_v1_DocumentMask { + pb_size_t field_paths_count; + pb_bytes_array_t **field_paths; +/* @@protoc_insertion_point(struct:google_firestore_v1_DocumentMask) */ +} google_firestore_v1_DocumentMask; + +typedef struct _google_firestore_v1_TransactionOptions_ReadWrite { + pb_bytes_array_t *retry_transaction; +/* @@protoc_insertion_point(struct:google_firestore_v1_TransactionOptions_ReadWrite) */ +} google_firestore_v1_TransactionOptions_ReadWrite; + +typedef struct _google_firestore_v1_Precondition { + pb_size_t which_condition_type; + union { + bool exists; + google_protobuf_Timestamp update_time; + }; +/* @@protoc_insertion_point(struct:google_firestore_v1_Precondition) */ +} google_firestore_v1_Precondition; + +typedef struct _google_firestore_v1_TransactionOptions_ReadOnly { + pb_size_t which_consistency_selector; + union { + google_protobuf_Timestamp read_time; + }; +/* @@protoc_insertion_point(struct:google_firestore_v1_TransactionOptions_ReadOnly) */ +} google_firestore_v1_TransactionOptions_ReadOnly; + +typedef struct _google_firestore_v1_TransactionOptions { + pb_size_t which_mode; + union { + google_firestore_v1_TransactionOptions_ReadOnly read_only; + google_firestore_v1_TransactionOptions_ReadWrite read_write; + }; +/* @@protoc_insertion_point(struct:google_firestore_v1_TransactionOptions) */ +} google_firestore_v1_TransactionOptions; + +/* Default values for struct fields */ + +/* Initializer values for message structs */ +#define google_firestore_v1_DocumentMask_init_default {0, NULL} +#define google_firestore_v1_Precondition_init_default {0, {0}} +#define google_firestore_v1_TransactionOptions_init_default {0, {google_firestore_v1_TransactionOptions_ReadOnly_init_default}} +#define google_firestore_v1_TransactionOptions_ReadWrite_init_default {NULL} +#define google_firestore_v1_TransactionOptions_ReadOnly_init_default {0, {google_protobuf_Timestamp_init_default}} +#define google_firestore_v1_DocumentMask_init_zero {0, NULL} +#define google_firestore_v1_Precondition_init_zero {0, {0}} +#define google_firestore_v1_TransactionOptions_init_zero {0, {google_firestore_v1_TransactionOptions_ReadOnly_init_zero}} +#define google_firestore_v1_TransactionOptions_ReadWrite_init_zero {NULL} +#define google_firestore_v1_TransactionOptions_ReadOnly_init_zero {0, {google_protobuf_Timestamp_init_zero}} + +/* Field tags (for use in manual encoding/decoding) */ +#define google_firestore_v1_DocumentMask_field_paths_tag 1 +#define google_firestore_v1_TransactionOptions_ReadWrite_retry_transaction_tag 1 +#define google_firestore_v1_Precondition_exists_tag 1 +#define google_firestore_v1_Precondition_update_time_tag 2 +#define google_firestore_v1_TransactionOptions_ReadOnly_read_time_tag 2 +#define google_firestore_v1_TransactionOptions_read_only_tag 2 +#define google_firestore_v1_TransactionOptions_read_write_tag 3 + +/* Struct field encoding specification for nanopb */ +extern const pb_field_t google_firestore_v1_DocumentMask_fields[2]; +extern const pb_field_t google_firestore_v1_Precondition_fields[3]; +extern const pb_field_t google_firestore_v1_TransactionOptions_fields[3]; +extern const pb_field_t google_firestore_v1_TransactionOptions_ReadWrite_fields[2]; +extern const pb_field_t google_firestore_v1_TransactionOptions_ReadOnly_fields[2]; + +/* Maximum encoded size of messages (where known) */ +/* google_firestore_v1_DocumentMask_size depends on runtime parameters */ +#define google_firestore_v1_Precondition_size 24 +#define google_firestore_v1_TransactionOptions_size (0 + (google_firestore_v1_TransactionOptions_ReadWrite_size > 26 ? google_firestore_v1_TransactionOptions_ReadWrite_size : 26)) +/* google_firestore_v1_TransactionOptions_ReadWrite_size depends on runtime parameters */ +#define google_firestore_v1_TransactionOptions_ReadOnly_size 24 + +/* Message IDs (where set with "msgid" option) */ +#ifdef PB_MSGID + +#define COMMON_MESSAGES \ + + +#endif + +} // namespace firestore +} // namespace firebase + +/* @@protoc_insertion_point(eof) */ + +#endif diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/google/firestore/v1/document.nanopb.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/google/firestore/v1/document.nanopb.cc new file mode 100644 index 0000000..00e15d5 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/google/firestore/v1/document.nanopb.cc @@ -0,0 +1,105 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +/* Automatically generated nanopb constant definitions */ +/* Generated by nanopb-0.3.9.1 */ + +#include "document.nanopb.h" + +namespace firebase { +namespace firestore { + +/* @@protoc_insertion_point(includes) */ +#if PB_PROTO_HEADER_VERSION != 30 +#error Regenerate this file with the current version of nanopb generator. +#endif + + + +const pb_field_t google_firestore_v1_Document_fields[5] = { + PB_FIELD( 1, BYTES , SINGULAR, POINTER , FIRST, google_firestore_v1_Document, name, name, 0), + PB_FIELD( 2, MESSAGE , REPEATED, POINTER , OTHER, google_firestore_v1_Document, fields, name, &google_firestore_v1_Document_FieldsEntry_fields), + PB_FIELD( 3, MESSAGE , SINGULAR, STATIC , OTHER, google_firestore_v1_Document, create_time, fields, &google_protobuf_Timestamp_fields), + PB_FIELD( 4, MESSAGE , SINGULAR, STATIC , OTHER, google_firestore_v1_Document, update_time, create_time, &google_protobuf_Timestamp_fields), + PB_LAST_FIELD +}; + +const pb_field_t google_firestore_v1_Document_FieldsEntry_fields[3] = { + PB_FIELD( 1, BYTES , SINGULAR, POINTER , FIRST, google_firestore_v1_Document_FieldsEntry, key, key, 0), + PB_FIELD( 2, MESSAGE , SINGULAR, STATIC , OTHER, google_firestore_v1_Document_FieldsEntry, value, key, &google_firestore_v1_Value_fields), + PB_LAST_FIELD +}; + +const pb_field_t google_firestore_v1_Value_fields[12] = { + PB_ANONYMOUS_ONEOF_FIELD(value_type, 1, BOOL , ONEOF, STATIC , FIRST, google_firestore_v1_Value, boolean_value, boolean_value, 0), + PB_ANONYMOUS_ONEOF_FIELD(value_type, 2, INT64 , ONEOF, STATIC , UNION, google_firestore_v1_Value, integer_value, integer_value, 0), + PB_ANONYMOUS_ONEOF_FIELD(value_type, 3, DOUBLE , ONEOF, STATIC , UNION, google_firestore_v1_Value, double_value, double_value, 0), + PB_ANONYMOUS_ONEOF_FIELD(value_type, 5, BYTES , ONEOF, POINTER , UNION, google_firestore_v1_Value, reference_value, reference_value, 0), + PB_ANONYMOUS_ONEOF_FIELD(value_type, 6, MESSAGE , ONEOF, STATIC , UNION, google_firestore_v1_Value, map_value, map_value, &google_firestore_v1_MapValue_fields), + PB_ANONYMOUS_ONEOF_FIELD(value_type, 8, MESSAGE , ONEOF, STATIC , UNION, google_firestore_v1_Value, geo_point_value, geo_point_value, &google_type_LatLng_fields), + PB_ANONYMOUS_ONEOF_FIELD(value_type, 9, MESSAGE , ONEOF, STATIC , UNION, google_firestore_v1_Value, array_value, array_value, &google_firestore_v1_ArrayValue_fields), + PB_ANONYMOUS_ONEOF_FIELD(value_type, 10, MESSAGE , ONEOF, STATIC , UNION, google_firestore_v1_Value, timestamp_value, timestamp_value, &google_protobuf_Timestamp_fields), + PB_ANONYMOUS_ONEOF_FIELD(value_type, 11, ENUM , ONEOF, STATIC , UNION, google_firestore_v1_Value, null_value, null_value, 0), + PB_ANONYMOUS_ONEOF_FIELD(value_type, 17, BYTES , ONEOF, POINTER , UNION, google_firestore_v1_Value, string_value, string_value, 0), + PB_ANONYMOUS_ONEOF_FIELD(value_type, 18, BYTES , ONEOF, POINTER , UNION, google_firestore_v1_Value, bytes_value, bytes_value, 0), + PB_LAST_FIELD +}; + +const pb_field_t google_firestore_v1_ArrayValue_fields[2] = { + PB_FIELD( 1, MESSAGE , REPEATED, POINTER , FIRST, google_firestore_v1_ArrayValue, values, values, &google_firestore_v1_Value_fields), + PB_LAST_FIELD +}; + +const pb_field_t google_firestore_v1_MapValue_fields[2] = { + PB_FIELD( 1, MESSAGE , REPEATED, POINTER , FIRST, google_firestore_v1_MapValue, fields, fields, &google_firestore_v1_MapValue_FieldsEntry_fields), + PB_LAST_FIELD +}; + +const pb_field_t google_firestore_v1_MapValue_FieldsEntry_fields[3] = { + PB_FIELD( 1, BYTES , SINGULAR, POINTER , FIRST, google_firestore_v1_MapValue_FieldsEntry, key, key, 0), + PB_FIELD( 2, MESSAGE , SINGULAR, STATIC , OTHER, google_firestore_v1_MapValue_FieldsEntry, value, key, &google_firestore_v1_Value_fields), + PB_LAST_FIELD +}; + + +/* Check that field information fits in pb_field_t */ +#if !defined(PB_FIELD_32BIT) +/* If you get an error here, it means that you need to define PB_FIELD_32BIT + * compile-time option. You can do that in pb.h or on compiler command line. + * + * The reason you need to do this is that some of your messages contain tag + * numbers or field sizes that are larger than what can fit in 8 or 16 bit + * field descriptors. + */ +PB_STATIC_ASSERT((pb_membersize(google_firestore_v1_Document, create_time) < 65536 && pb_membersize(google_firestore_v1_Document, update_time) < 65536 && pb_membersize(google_firestore_v1_Document_FieldsEntry, value) < 65536 && pb_membersize(google_firestore_v1_Value, map_value) < 65536 && pb_membersize(google_firestore_v1_Value, geo_point_value) < 65536 && pb_membersize(google_firestore_v1_Value, array_value) < 65536 && pb_membersize(google_firestore_v1_Value, timestamp_value) < 65536 && pb_membersize(google_firestore_v1_MapValue_FieldsEntry, value) < 65536), YOU_MUST_DEFINE_PB_FIELD_32BIT_FOR_MESSAGES_google_firestore_v1_Document_google_firestore_v1_Document_FieldsEntry_google_firestore_v1_Value_google_firestore_v1_ArrayValue_google_firestore_v1_MapValue_google_firestore_v1_MapValue_FieldsEntry) +#endif + +#if !defined(PB_FIELD_16BIT) && !defined(PB_FIELD_32BIT) +/* If you get an error here, it means that you need to define PB_FIELD_16BIT + * compile-time option. You can do that in pb.h or on compiler command line. + * + * The reason you need to do this is that some of your messages contain tag + * numbers or field sizes that are larger than what can fit in the default + * 8 bit descriptors. + */ +PB_STATIC_ASSERT((pb_membersize(google_firestore_v1_Document, create_time) < 256 && pb_membersize(google_firestore_v1_Document, update_time) < 256 && pb_membersize(google_firestore_v1_Document_FieldsEntry, value) < 256 && pb_membersize(google_firestore_v1_Value, map_value) < 256 && pb_membersize(google_firestore_v1_Value, geo_point_value) < 256 && pb_membersize(google_firestore_v1_Value, array_value) < 256 && pb_membersize(google_firestore_v1_Value, timestamp_value) < 256 && pb_membersize(google_firestore_v1_MapValue_FieldsEntry, value) < 256), YOU_MUST_DEFINE_PB_FIELD_16BIT_FOR_MESSAGES_google_firestore_v1_Document_google_firestore_v1_Document_FieldsEntry_google_firestore_v1_Value_google_firestore_v1_ArrayValue_google_firestore_v1_MapValue_google_firestore_v1_MapValue_FieldsEntry) +#endif + + +} // namespace firestore +} // namespace firebase + +/* @@protoc_insertion_point(eof) */ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/google/firestore/v1/document.nanopb.h b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/google/firestore/v1/document.nanopb.h new file mode 100644 index 0000000..c07959d --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/google/firestore/v1/document.nanopb.h @@ -0,0 +1,161 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +/* Automatically generated nanopb header */ +/* Generated by nanopb-0.3.9.1 */ + +#ifndef PB_GOOGLE_FIRESTORE_V1_DOCUMENT_NANOPB_H_INCLUDED +#define PB_GOOGLE_FIRESTORE_V1_DOCUMENT_NANOPB_H_INCLUDED +#include + +#include "google/api/annotations.nanopb.h" + +#include "google/protobuf/struct.nanopb.h" + +#include "google/protobuf/timestamp.nanopb.h" + +#include "google/type/latlng.nanopb.h" + +namespace firebase { +namespace firestore { + +/* @@protoc_insertion_point(includes) */ +#if PB_PROTO_HEADER_VERSION != 30 +#error Regenerate this file with the current version of nanopb generator. +#endif + + +/* Struct definitions */ +typedef struct _google_firestore_v1_ArrayValue { + pb_size_t values_count; + struct _google_firestore_v1_Value *values; +/* @@protoc_insertion_point(struct:google_firestore_v1_ArrayValue) */ +} google_firestore_v1_ArrayValue; + +typedef struct _google_firestore_v1_MapValue { + pb_size_t fields_count; + struct _google_firestore_v1_MapValue_FieldsEntry *fields; +/* @@protoc_insertion_point(struct:google_firestore_v1_MapValue) */ +} google_firestore_v1_MapValue; + +typedef struct _google_firestore_v1_Document { + pb_bytes_array_t *name; + pb_size_t fields_count; + struct _google_firestore_v1_Document_FieldsEntry *fields; + google_protobuf_Timestamp create_time; + google_protobuf_Timestamp update_time; +/* @@protoc_insertion_point(struct:google_firestore_v1_Document) */ +} google_firestore_v1_Document; + +typedef struct _google_firestore_v1_Value { + pb_size_t which_value_type; + union { + bool boolean_value; + int64_t integer_value; + double double_value; + pb_bytes_array_t *reference_value; + google_firestore_v1_MapValue map_value; + google_type_LatLng geo_point_value; + google_firestore_v1_ArrayValue array_value; + google_protobuf_Timestamp timestamp_value; + google_protobuf_NullValue null_value; + pb_bytes_array_t *string_value; + pb_bytes_array_t *bytes_value; + }; +/* @@protoc_insertion_point(struct:google_firestore_v1_Value) */ +} google_firestore_v1_Value; + +typedef struct _google_firestore_v1_Document_FieldsEntry { + pb_bytes_array_t *key; + google_firestore_v1_Value value; +/* @@protoc_insertion_point(struct:google_firestore_v1_Document_FieldsEntry) */ +} google_firestore_v1_Document_FieldsEntry; + +typedef struct _google_firestore_v1_MapValue_FieldsEntry { + pb_bytes_array_t *key; + google_firestore_v1_Value value; +/* @@protoc_insertion_point(struct:google_firestore_v1_MapValue_FieldsEntry) */ +} google_firestore_v1_MapValue_FieldsEntry; + +/* Default values for struct fields */ + +/* Initializer values for message structs */ +#define google_firestore_v1_Document_init_default {NULL, 0, NULL, google_protobuf_Timestamp_init_default, google_protobuf_Timestamp_init_default} +#define google_firestore_v1_Document_FieldsEntry_init_default {NULL, google_firestore_v1_Value_init_default} +#define google_firestore_v1_Value_init_default {0, {0}} +#define google_firestore_v1_ArrayValue_init_default {0, NULL} +#define google_firestore_v1_MapValue_init_default {0, NULL} +#define google_firestore_v1_MapValue_FieldsEntry_init_default {NULL, google_firestore_v1_Value_init_default} +#define google_firestore_v1_Document_init_zero {NULL, 0, NULL, google_protobuf_Timestamp_init_zero, google_protobuf_Timestamp_init_zero} +#define google_firestore_v1_Document_FieldsEntry_init_zero {NULL, google_firestore_v1_Value_init_zero} +#define google_firestore_v1_Value_init_zero {0, {0}} +#define google_firestore_v1_ArrayValue_init_zero {0, NULL} +#define google_firestore_v1_MapValue_init_zero {0, NULL} +#define google_firestore_v1_MapValue_FieldsEntry_init_zero {NULL, google_firestore_v1_Value_init_zero} + +/* Field tags (for use in manual encoding/decoding) */ +#define google_firestore_v1_ArrayValue_values_tag 1 +#define google_firestore_v1_MapValue_fields_tag 1 +#define google_firestore_v1_Document_name_tag 1 +#define google_firestore_v1_Document_fields_tag 2 +#define google_firestore_v1_Document_create_time_tag 3 +#define google_firestore_v1_Document_update_time_tag 4 +#define google_firestore_v1_Value_boolean_value_tag 1 +#define google_firestore_v1_Value_integer_value_tag 2 +#define google_firestore_v1_Value_double_value_tag 3 +#define google_firestore_v1_Value_reference_value_tag 5 +#define google_firestore_v1_Value_map_value_tag 6 +#define google_firestore_v1_Value_geo_point_value_tag 8 +#define google_firestore_v1_Value_array_value_tag 9 +#define google_firestore_v1_Value_timestamp_value_tag 10 +#define google_firestore_v1_Value_null_value_tag 11 +#define google_firestore_v1_Value_string_value_tag 17 +#define google_firestore_v1_Value_bytes_value_tag 18 +#define google_firestore_v1_Document_FieldsEntry_key_tag 1 +#define google_firestore_v1_Document_FieldsEntry_value_tag 2 +#define google_firestore_v1_MapValue_FieldsEntry_key_tag 1 +#define google_firestore_v1_MapValue_FieldsEntry_value_tag 2 + +/* Struct field encoding specification for nanopb */ +extern const pb_field_t google_firestore_v1_Document_fields[5]; +extern const pb_field_t google_firestore_v1_Document_FieldsEntry_fields[3]; +extern const pb_field_t google_firestore_v1_Value_fields[12]; +extern const pb_field_t google_firestore_v1_ArrayValue_fields[2]; +extern const pb_field_t google_firestore_v1_MapValue_fields[2]; +extern const pb_field_t google_firestore_v1_MapValue_FieldsEntry_fields[3]; + +/* Maximum encoded size of messages (where known) */ +/* google_firestore_v1_Document_size depends on runtime parameters */ +/* google_firestore_v1_Document_FieldsEntry_size depends on runtime parameters */ +/* google_firestore_v1_Value_size depends on runtime parameters */ +/* google_firestore_v1_ArrayValue_size depends on runtime parameters */ +/* google_firestore_v1_MapValue_size depends on runtime parameters */ +/* google_firestore_v1_MapValue_FieldsEntry_size depends on runtime parameters */ + +/* Message IDs (where set with "msgid" option) */ +#ifdef PB_MSGID + +#define DOCUMENT_MESSAGES \ + + +#endif + +} // namespace firestore +} // namespace firebase + +/* @@protoc_insertion_point(eof) */ + +#endif diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/google/firestore/v1/firestore.nanopb.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/google/firestore/v1/firestore.nanopb.cc new file mode 100644 index 0000000..50508a9 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/google/firestore/v1/firestore.nanopb.cc @@ -0,0 +1,265 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +/* Automatically generated nanopb constant definitions */ +/* Generated by nanopb-0.3.9.1 */ + +#include "firestore.nanopb.h" + +namespace firebase { +namespace firestore { + +/* @@protoc_insertion_point(includes) */ +#if PB_PROTO_HEADER_VERSION != 30 +#error Regenerate this file with the current version of nanopb generator. +#endif + + + +const pb_field_t google_firestore_v1_GetDocumentRequest_fields[5] = { + PB_FIELD( 1, BYTES , SINGULAR, POINTER , FIRST, google_firestore_v1_GetDocumentRequest, name, name, 0), + PB_FIELD( 2, MESSAGE , SINGULAR, STATIC , OTHER, google_firestore_v1_GetDocumentRequest, mask, name, &google_firestore_v1_DocumentMask_fields), + PB_ANONYMOUS_ONEOF_FIELD(consistency_selector, 3, BYTES , ONEOF, POINTER , OTHER, google_firestore_v1_GetDocumentRequest, transaction, mask, 0), + PB_ANONYMOUS_ONEOF_FIELD(consistency_selector, 5, MESSAGE , ONEOF, STATIC , UNION, google_firestore_v1_GetDocumentRequest, read_time, mask, &google_protobuf_Timestamp_fields), + PB_LAST_FIELD +}; + +const pb_field_t google_firestore_v1_ListDocumentsRequest_fields[10] = { + PB_FIELD( 1, BYTES , SINGULAR, POINTER , FIRST, google_firestore_v1_ListDocumentsRequest, parent, parent, 0), + PB_FIELD( 2, BYTES , SINGULAR, POINTER , OTHER, google_firestore_v1_ListDocumentsRequest, collection_id, parent, 0), + PB_FIELD( 3, INT32 , SINGULAR, STATIC , OTHER, google_firestore_v1_ListDocumentsRequest, page_size, collection_id, 0), + PB_FIELD( 4, BYTES , SINGULAR, POINTER , OTHER, google_firestore_v1_ListDocumentsRequest, page_token, page_size, 0), + PB_FIELD( 6, BYTES , SINGULAR, POINTER , OTHER, google_firestore_v1_ListDocumentsRequest, order_by, page_token, 0), + PB_FIELD( 7, MESSAGE , SINGULAR, STATIC , OTHER, google_firestore_v1_ListDocumentsRequest, mask, order_by, &google_firestore_v1_DocumentMask_fields), + PB_ANONYMOUS_ONEOF_FIELD(consistency_selector, 8, BYTES , ONEOF, POINTER , OTHER, google_firestore_v1_ListDocumentsRequest, transaction, mask, 0), + PB_ANONYMOUS_ONEOF_FIELD(consistency_selector, 10, MESSAGE , ONEOF, STATIC , UNION, google_firestore_v1_ListDocumentsRequest, read_time, mask, &google_protobuf_Timestamp_fields), + PB_FIELD( 12, BOOL , SINGULAR, STATIC , OTHER, google_firestore_v1_ListDocumentsRequest, show_missing, read_time, 0), + PB_LAST_FIELD +}; + +const pb_field_t google_firestore_v1_ListDocumentsResponse_fields[3] = { + PB_FIELD( 1, MESSAGE , REPEATED, POINTER , FIRST, google_firestore_v1_ListDocumentsResponse, documents, documents, &google_firestore_v1_Document_fields), + PB_FIELD( 2, BYTES , SINGULAR, POINTER , OTHER, google_firestore_v1_ListDocumentsResponse, next_page_token, documents, 0), + PB_LAST_FIELD +}; + +const pb_field_t google_firestore_v1_CreateDocumentRequest_fields[6] = { + PB_FIELD( 1, BYTES , SINGULAR, POINTER , FIRST, google_firestore_v1_CreateDocumentRequest, parent, parent, 0), + PB_FIELD( 2, BYTES , SINGULAR, POINTER , OTHER, google_firestore_v1_CreateDocumentRequest, collection_id, parent, 0), + PB_FIELD( 3, BYTES , SINGULAR, POINTER , OTHER, google_firestore_v1_CreateDocumentRequest, document_id, collection_id, 0), + PB_FIELD( 4, MESSAGE , SINGULAR, STATIC , OTHER, google_firestore_v1_CreateDocumentRequest, document, document_id, &google_firestore_v1_Document_fields), + PB_FIELD( 5, MESSAGE , SINGULAR, STATIC , OTHER, google_firestore_v1_CreateDocumentRequest, mask, document, &google_firestore_v1_DocumentMask_fields), + PB_LAST_FIELD +}; + +const pb_field_t google_firestore_v1_UpdateDocumentRequest_fields[5] = { + PB_FIELD( 1, MESSAGE , SINGULAR, STATIC , FIRST, google_firestore_v1_UpdateDocumentRequest, document, document, &google_firestore_v1_Document_fields), + PB_FIELD( 2, MESSAGE , SINGULAR, STATIC , OTHER, google_firestore_v1_UpdateDocumentRequest, update_mask, document, &google_firestore_v1_DocumentMask_fields), + PB_FIELD( 3, MESSAGE , SINGULAR, STATIC , OTHER, google_firestore_v1_UpdateDocumentRequest, mask, update_mask, &google_firestore_v1_DocumentMask_fields), + PB_FIELD( 4, MESSAGE , SINGULAR, STATIC , OTHER, google_firestore_v1_UpdateDocumentRequest, current_document, mask, &google_firestore_v1_Precondition_fields), + PB_LAST_FIELD +}; + +const pb_field_t google_firestore_v1_DeleteDocumentRequest_fields[3] = { + PB_FIELD( 1, BYTES , SINGULAR, POINTER , FIRST, google_firestore_v1_DeleteDocumentRequest, name, name, 0), + PB_FIELD( 2, MESSAGE , SINGULAR, STATIC , OTHER, google_firestore_v1_DeleteDocumentRequest, current_document, name, &google_firestore_v1_Precondition_fields), + PB_LAST_FIELD +}; + +const pb_field_t google_firestore_v1_BatchGetDocumentsRequest_fields[7] = { + PB_FIELD( 1, BYTES , SINGULAR, POINTER , FIRST, google_firestore_v1_BatchGetDocumentsRequest, database, database, 0), + PB_FIELD( 2, BYTES , REPEATED, POINTER , OTHER, google_firestore_v1_BatchGetDocumentsRequest, documents, database, 0), + PB_FIELD( 3, MESSAGE , SINGULAR, STATIC , OTHER, google_firestore_v1_BatchGetDocumentsRequest, mask, documents, &google_firestore_v1_DocumentMask_fields), + PB_ANONYMOUS_ONEOF_FIELD(consistency_selector, 4, BYTES , ONEOF, POINTER , OTHER, google_firestore_v1_BatchGetDocumentsRequest, transaction, mask, 0), + PB_ANONYMOUS_ONEOF_FIELD(consistency_selector, 5, MESSAGE , ONEOF, STATIC , UNION, google_firestore_v1_BatchGetDocumentsRequest, new_transaction, mask, &google_firestore_v1_TransactionOptions_fields), + PB_ANONYMOUS_ONEOF_FIELD(consistency_selector, 7, MESSAGE , ONEOF, STATIC , UNION, google_firestore_v1_BatchGetDocumentsRequest, read_time, mask, &google_protobuf_Timestamp_fields), + PB_LAST_FIELD +}; + +const pb_field_t google_firestore_v1_BatchGetDocumentsResponse_fields[5] = { + PB_ANONYMOUS_ONEOF_FIELD(result, 1, MESSAGE , ONEOF, STATIC , FIRST, google_firestore_v1_BatchGetDocumentsResponse, found, found, &google_firestore_v1_Document_fields), + PB_ANONYMOUS_ONEOF_FIELD(result, 2, BYTES , ONEOF, POINTER , UNION, google_firestore_v1_BatchGetDocumentsResponse, missing, missing, 0), + PB_FIELD( 3, BYTES , SINGULAR, POINTER , OTHER, google_firestore_v1_BatchGetDocumentsResponse, transaction, missing, 0), + PB_FIELD( 4, MESSAGE , SINGULAR, STATIC , OTHER, google_firestore_v1_BatchGetDocumentsResponse, read_time, transaction, &google_protobuf_Timestamp_fields), + PB_LAST_FIELD +}; + +const pb_field_t google_firestore_v1_BeginTransactionRequest_fields[3] = { + PB_FIELD( 1, BYTES , SINGULAR, POINTER , FIRST, google_firestore_v1_BeginTransactionRequest, database, database, 0), + PB_FIELD( 2, MESSAGE , SINGULAR, STATIC , OTHER, google_firestore_v1_BeginTransactionRequest, options, database, &google_firestore_v1_TransactionOptions_fields), + PB_LAST_FIELD +}; + +const pb_field_t google_firestore_v1_BeginTransactionResponse_fields[2] = { + PB_FIELD( 1, BYTES , SINGULAR, POINTER , FIRST, google_firestore_v1_BeginTransactionResponse, transaction, transaction, 0), + PB_LAST_FIELD +}; + +const pb_field_t google_firestore_v1_CommitRequest_fields[4] = { + PB_FIELD( 1, BYTES , SINGULAR, POINTER , FIRST, google_firestore_v1_CommitRequest, database, database, 0), + PB_FIELD( 2, MESSAGE , REPEATED, POINTER , OTHER, google_firestore_v1_CommitRequest, writes, database, &google_firestore_v1_Write_fields), + PB_FIELD( 3, BYTES , SINGULAR, POINTER , OTHER, google_firestore_v1_CommitRequest, transaction, writes, 0), + PB_LAST_FIELD +}; + +const pb_field_t google_firestore_v1_CommitResponse_fields[3] = { + PB_FIELD( 1, MESSAGE , REPEATED, POINTER , FIRST, google_firestore_v1_CommitResponse, write_results, write_results, &google_firestore_v1_WriteResult_fields), + PB_FIELD( 2, MESSAGE , SINGULAR, STATIC , OTHER, google_firestore_v1_CommitResponse, commit_time, write_results, &google_protobuf_Timestamp_fields), + PB_LAST_FIELD +}; + +const pb_field_t google_firestore_v1_RollbackRequest_fields[3] = { + PB_FIELD( 1, BYTES , SINGULAR, POINTER , FIRST, google_firestore_v1_RollbackRequest, database, database, 0), + PB_FIELD( 2, BYTES , SINGULAR, POINTER , OTHER, google_firestore_v1_RollbackRequest, transaction, database, 0), + PB_LAST_FIELD +}; + +const pb_field_t google_firestore_v1_RunQueryRequest_fields[6] = { + PB_FIELD( 1, BYTES , SINGULAR, POINTER , FIRST, google_firestore_v1_RunQueryRequest, parent, parent, 0), + PB_ONEOF_FIELD(query_type, 2, MESSAGE , ONEOF, STATIC , OTHER, google_firestore_v1_RunQueryRequest, structured_query, parent, &google_firestore_v1_StructuredQuery_fields), + PB_ONEOF_FIELD(consistency_selector, 5, BYTES , ONEOF, POINTER , OTHER, google_firestore_v1_RunQueryRequest, transaction, query_type.structured_query, 0), + PB_ONEOF_FIELD(consistency_selector, 6, MESSAGE , ONEOF, STATIC , UNION, google_firestore_v1_RunQueryRequest, new_transaction, query_type.structured_query, &google_firestore_v1_TransactionOptions_fields), + PB_ONEOF_FIELD(consistency_selector, 7, MESSAGE , ONEOF, STATIC , UNION, google_firestore_v1_RunQueryRequest, read_time, query_type.structured_query, &google_protobuf_Timestamp_fields), + PB_LAST_FIELD +}; + +const pb_field_t google_firestore_v1_RunQueryResponse_fields[5] = { + PB_FIELD( 1, MESSAGE , SINGULAR, STATIC , FIRST, google_firestore_v1_RunQueryResponse, document, document, &google_firestore_v1_Document_fields), + PB_FIELD( 2, BYTES , SINGULAR, POINTER , OTHER, google_firestore_v1_RunQueryResponse, transaction, document, 0), + PB_FIELD( 3, MESSAGE , SINGULAR, STATIC , OTHER, google_firestore_v1_RunQueryResponse, read_time, transaction, &google_protobuf_Timestamp_fields), + PB_FIELD( 4, INT32 , SINGULAR, STATIC , OTHER, google_firestore_v1_RunQueryResponse, skipped_results, read_time, 0), + PB_LAST_FIELD +}; + +const pb_field_t google_firestore_v1_WriteRequest_fields[6] = { + PB_FIELD( 1, BYTES , SINGULAR, POINTER , FIRST, google_firestore_v1_WriteRequest, database, database, 0), + PB_FIELD( 2, BYTES , SINGULAR, POINTER , OTHER, google_firestore_v1_WriteRequest, stream_id, database, 0), + PB_FIELD( 3, MESSAGE , REPEATED, POINTER , OTHER, google_firestore_v1_WriteRequest, writes, stream_id, &google_firestore_v1_Write_fields), + PB_FIELD( 4, BYTES , SINGULAR, POINTER , OTHER, google_firestore_v1_WriteRequest, stream_token, writes, 0), + PB_FIELD( 5, MESSAGE , REPEATED, POINTER , OTHER, google_firestore_v1_WriteRequest, labels, stream_token, &google_firestore_v1_WriteRequest_LabelsEntry_fields), + PB_LAST_FIELD +}; + +const pb_field_t google_firestore_v1_WriteRequest_LabelsEntry_fields[3] = { + PB_FIELD( 1, BYTES , SINGULAR, POINTER , FIRST, google_firestore_v1_WriteRequest_LabelsEntry, key, key, 0), + PB_FIELD( 2, BYTES , SINGULAR, POINTER , OTHER, google_firestore_v1_WriteRequest_LabelsEntry, value, key, 0), + PB_LAST_FIELD +}; + +const pb_field_t google_firestore_v1_WriteResponse_fields[5] = { + PB_FIELD( 1, BYTES , SINGULAR, POINTER , FIRST, google_firestore_v1_WriteResponse, stream_id, stream_id, 0), + PB_FIELD( 2, BYTES , SINGULAR, POINTER , OTHER, google_firestore_v1_WriteResponse, stream_token, stream_id, 0), + PB_FIELD( 3, MESSAGE , REPEATED, POINTER , OTHER, google_firestore_v1_WriteResponse, write_results, stream_token, &google_firestore_v1_WriteResult_fields), + PB_FIELD( 4, MESSAGE , SINGULAR, STATIC , OTHER, google_firestore_v1_WriteResponse, commit_time, write_results, &google_protobuf_Timestamp_fields), + PB_LAST_FIELD +}; + +const pb_field_t google_firestore_v1_ListenRequest_fields[5] = { + PB_FIELD( 1, BYTES , SINGULAR, POINTER , FIRST, google_firestore_v1_ListenRequest, database, database, 0), + PB_ANONYMOUS_ONEOF_FIELD(target_change, 2, MESSAGE , ONEOF, STATIC , OTHER, google_firestore_v1_ListenRequest, add_target, database, &google_firestore_v1_Target_fields), + PB_ANONYMOUS_ONEOF_FIELD(target_change, 3, INT32 , ONEOF, STATIC , UNION, google_firestore_v1_ListenRequest, remove_target, database, 0), + PB_FIELD( 4, MESSAGE , REPEATED, POINTER , OTHER, google_firestore_v1_ListenRequest, labels, remove_target, &google_firestore_v1_ListenRequest_LabelsEntry_fields), + PB_LAST_FIELD +}; + +const pb_field_t google_firestore_v1_ListenRequest_LabelsEntry_fields[3] = { + PB_FIELD( 1, BYTES , SINGULAR, POINTER , FIRST, google_firestore_v1_ListenRequest_LabelsEntry, key, key, 0), + PB_FIELD( 2, BYTES , SINGULAR, POINTER , OTHER, google_firestore_v1_ListenRequest_LabelsEntry, value, key, 0), + PB_LAST_FIELD +}; + +const pb_field_t google_firestore_v1_ListenResponse_fields[6] = { + PB_ANONYMOUS_ONEOF_FIELD(response_type, 2, MESSAGE , ONEOF, STATIC , FIRST, google_firestore_v1_ListenResponse, target_change, target_change, &google_firestore_v1_TargetChange_fields), + PB_ANONYMOUS_ONEOF_FIELD(response_type, 3, MESSAGE , ONEOF, STATIC , UNION, google_firestore_v1_ListenResponse, document_change, document_change, &google_firestore_v1_DocumentChange_fields), + PB_ANONYMOUS_ONEOF_FIELD(response_type, 4, MESSAGE , ONEOF, STATIC , UNION, google_firestore_v1_ListenResponse, document_delete, document_delete, &google_firestore_v1_DocumentDelete_fields), + PB_ANONYMOUS_ONEOF_FIELD(response_type, 5, MESSAGE , ONEOF, STATIC , UNION, google_firestore_v1_ListenResponse, filter, filter, &google_firestore_v1_ExistenceFilter_fields), + PB_ANONYMOUS_ONEOF_FIELD(response_type, 6, MESSAGE , ONEOF, STATIC , UNION, google_firestore_v1_ListenResponse, document_remove, document_remove, &google_firestore_v1_DocumentRemove_fields), + PB_LAST_FIELD +}; + +const pb_field_t google_firestore_v1_Target_fields[7] = { + PB_ONEOF_FIELD(target_type, 2, MESSAGE , ONEOF, STATIC , FIRST, google_firestore_v1_Target, query, query, &google_firestore_v1_Target_QueryTarget_fields), + PB_ONEOF_FIELD(target_type, 3, MESSAGE , ONEOF, STATIC , UNION, google_firestore_v1_Target, documents, documents, &google_firestore_v1_Target_DocumentsTarget_fields), + PB_ONEOF_FIELD(resume_type, 4, BYTES , ONEOF, POINTER , OTHER, google_firestore_v1_Target, resume_token, target_type.documents, 0), + PB_ONEOF_FIELD(resume_type, 11, MESSAGE , ONEOF, STATIC , UNION, google_firestore_v1_Target, read_time, target_type.documents, &google_protobuf_Timestamp_fields), + PB_FIELD( 5, INT32 , SINGULAR, STATIC , OTHER, google_firestore_v1_Target, target_id, resume_type.read_time, 0), + PB_FIELD( 6, BOOL , SINGULAR, STATIC , OTHER, google_firestore_v1_Target, once, target_id, 0), + PB_LAST_FIELD +}; + +const pb_field_t google_firestore_v1_Target_DocumentsTarget_fields[2] = { + PB_FIELD( 2, BYTES , REPEATED, POINTER , FIRST, google_firestore_v1_Target_DocumentsTarget, documents, documents, 0), + PB_LAST_FIELD +}; + +const pb_field_t google_firestore_v1_Target_QueryTarget_fields[3] = { + PB_FIELD( 1, BYTES , SINGULAR, POINTER , FIRST, google_firestore_v1_Target_QueryTarget, parent, parent, 0), + PB_ANONYMOUS_ONEOF_FIELD(query_type, 2, MESSAGE , ONEOF, STATIC , OTHER, google_firestore_v1_Target_QueryTarget, structured_query, parent, &google_firestore_v1_StructuredQuery_fields), + PB_LAST_FIELD +}; + +const pb_field_t google_firestore_v1_TargetChange_fields[6] = { + PB_FIELD( 1, UENUM , SINGULAR, STATIC , FIRST, google_firestore_v1_TargetChange, target_change_type, target_change_type, 0), + PB_FIELD( 2, INT32 , REPEATED, POINTER , OTHER, google_firestore_v1_TargetChange, target_ids, target_change_type, 0), + PB_FIELD( 3, MESSAGE , SINGULAR, STATIC , OTHER, google_firestore_v1_TargetChange, cause, target_ids, &google_rpc_Status_fields), + PB_FIELD( 4, BYTES , SINGULAR, POINTER , OTHER, google_firestore_v1_TargetChange, resume_token, cause, 0), + PB_FIELD( 6, MESSAGE , SINGULAR, STATIC , OTHER, google_firestore_v1_TargetChange, read_time, resume_token, &google_protobuf_Timestamp_fields), + PB_LAST_FIELD +}; + +const pb_field_t google_firestore_v1_ListCollectionIdsRequest_fields[4] = { + PB_FIELD( 1, BYTES , SINGULAR, POINTER , FIRST, google_firestore_v1_ListCollectionIdsRequest, parent, parent, 0), + PB_FIELD( 2, INT32 , SINGULAR, STATIC , OTHER, google_firestore_v1_ListCollectionIdsRequest, page_size, parent, 0), + PB_FIELD( 3, BYTES , SINGULAR, POINTER , OTHER, google_firestore_v1_ListCollectionIdsRequest, page_token, page_size, 0), + PB_LAST_FIELD +}; + +const pb_field_t google_firestore_v1_ListCollectionIdsResponse_fields[3] = { + PB_FIELD( 1, BYTES , REPEATED, POINTER , FIRST, google_firestore_v1_ListCollectionIdsResponse, collection_ids, collection_ids, 0), + PB_FIELD( 2, BYTES , SINGULAR, POINTER , OTHER, google_firestore_v1_ListCollectionIdsResponse, next_page_token, collection_ids, 0), + PB_LAST_FIELD +}; + + + +/* Check that field information fits in pb_field_t */ +#if !defined(PB_FIELD_32BIT) +/* If you get an error here, it means that you need to define PB_FIELD_32BIT + * compile-time option. You can do that in pb.h or on compiler command line. + * + * The reason you need to do this is that some of your messages contain tag + * numbers or field sizes that are larger than what can fit in 8 or 16 bit + * field descriptors. + */ +PB_STATIC_ASSERT((pb_membersize(google_firestore_v1_GetDocumentRequest, read_time) < 65536 && pb_membersize(google_firestore_v1_GetDocumentRequest, mask) < 65536 && pb_membersize(google_firestore_v1_ListDocumentsRequest, read_time) < 65536 && pb_membersize(google_firestore_v1_ListDocumentsRequest, mask) < 65536 && pb_membersize(google_firestore_v1_CreateDocumentRequest, document) < 65536 && pb_membersize(google_firestore_v1_CreateDocumentRequest, mask) < 65536 && pb_membersize(google_firestore_v1_UpdateDocumentRequest, document) < 65536 && pb_membersize(google_firestore_v1_UpdateDocumentRequest, update_mask) < 65536 && pb_membersize(google_firestore_v1_UpdateDocumentRequest, mask) < 65536 && pb_membersize(google_firestore_v1_UpdateDocumentRequest, current_document) < 65536 && pb_membersize(google_firestore_v1_DeleteDocumentRequest, current_document) < 65536 && pb_membersize(google_firestore_v1_BatchGetDocumentsRequest, new_transaction) < 65536 && pb_membersize(google_firestore_v1_BatchGetDocumentsRequest, read_time) < 65536 && pb_membersize(google_firestore_v1_BatchGetDocumentsRequest, mask) < 65536 && pb_membersize(google_firestore_v1_BatchGetDocumentsResponse, found) < 65536 && pb_membersize(google_firestore_v1_BatchGetDocumentsResponse, read_time) < 65536 && pb_membersize(google_firestore_v1_BeginTransactionRequest, options) < 65536 && pb_membersize(google_firestore_v1_CommitResponse, commit_time) < 65536 && pb_membersize(google_firestore_v1_RunQueryRequest, query_type.structured_query) < 65536 && pb_membersize(google_firestore_v1_RunQueryRequest, consistency_selector.new_transaction) < 65536 && pb_membersize(google_firestore_v1_RunQueryRequest, consistency_selector.read_time) < 65536 && pb_membersize(google_firestore_v1_RunQueryResponse, document) < 65536 && pb_membersize(google_firestore_v1_RunQueryResponse, read_time) < 65536 && pb_membersize(google_firestore_v1_WriteResponse, commit_time) < 65536 && pb_membersize(google_firestore_v1_ListenRequest, add_target) < 65536 && pb_membersize(google_firestore_v1_ListenResponse, target_change) < 65536 && pb_membersize(google_firestore_v1_ListenResponse, document_change) < 65536 && pb_membersize(google_firestore_v1_ListenResponse, document_delete) < 65536 && pb_membersize(google_firestore_v1_ListenResponse, filter) < 65536 && pb_membersize(google_firestore_v1_ListenResponse, document_remove) < 65536 && pb_membersize(google_firestore_v1_Target, target_type.query) < 65536 && pb_membersize(google_firestore_v1_Target, target_type.documents) < 65536 && pb_membersize(google_firestore_v1_Target, resume_type.read_time) < 65536 && pb_membersize(google_firestore_v1_Target_QueryTarget, structured_query) < 65536 && pb_membersize(google_firestore_v1_TargetChange, cause) < 65536 && pb_membersize(google_firestore_v1_TargetChange, read_time) < 65536), YOU_MUST_DEFINE_PB_FIELD_32BIT_FOR_MESSAGES_google_firestore_v1_GetDocumentRequest_google_firestore_v1_ListDocumentsRequest_google_firestore_v1_ListDocumentsResponse_google_firestore_v1_CreateDocumentRequest_google_firestore_v1_UpdateDocumentRequest_google_firestore_v1_DeleteDocumentRequest_google_firestore_v1_BatchGetDocumentsRequest_google_firestore_v1_BatchGetDocumentsResponse_google_firestore_v1_BeginTransactionRequest_google_firestore_v1_BeginTransactionResponse_google_firestore_v1_CommitRequest_google_firestore_v1_CommitResponse_google_firestore_v1_RollbackRequest_google_firestore_v1_RunQueryRequest_google_firestore_v1_RunQueryResponse_google_firestore_v1_WriteRequest_google_firestore_v1_WriteRequest_LabelsEntry_google_firestore_v1_WriteResponse_google_firestore_v1_ListenRequest_google_firestore_v1_ListenRequest_LabelsEntry_google_firestore_v1_ListenResponse_google_firestore_v1_Target_google_firestore_v1_Target_DocumentsTarget_google_firestore_v1_Target_QueryTarget_google_firestore_v1_TargetChange_google_firestore_v1_ListCollectionIdsRequest_google_firestore_v1_ListCollectionIdsResponse) +#endif + +#if !defined(PB_FIELD_16BIT) && !defined(PB_FIELD_32BIT) +/* If you get an error here, it means that you need to define PB_FIELD_16BIT + * compile-time option. You can do that in pb.h or on compiler command line. + * + * The reason you need to do this is that some of your messages contain tag + * numbers or field sizes that are larger than what can fit in the default + * 8 bit descriptors. + */ +PB_STATIC_ASSERT((pb_membersize(google_firestore_v1_GetDocumentRequest, read_time) < 256 && pb_membersize(google_firestore_v1_GetDocumentRequest, mask) < 256 && pb_membersize(google_firestore_v1_ListDocumentsRequest, read_time) < 256 && pb_membersize(google_firestore_v1_ListDocumentsRequest, mask) < 256 && pb_membersize(google_firestore_v1_CreateDocumentRequest, document) < 256 && pb_membersize(google_firestore_v1_CreateDocumentRequest, mask) < 256 && pb_membersize(google_firestore_v1_UpdateDocumentRequest, document) < 256 && pb_membersize(google_firestore_v1_UpdateDocumentRequest, update_mask) < 256 && pb_membersize(google_firestore_v1_UpdateDocumentRequest, mask) < 256 && pb_membersize(google_firestore_v1_UpdateDocumentRequest, current_document) < 256 && pb_membersize(google_firestore_v1_DeleteDocumentRequest, current_document) < 256 && pb_membersize(google_firestore_v1_BatchGetDocumentsRequest, new_transaction) < 256 && pb_membersize(google_firestore_v1_BatchGetDocumentsRequest, read_time) < 256 && pb_membersize(google_firestore_v1_BatchGetDocumentsRequest, mask) < 256 && pb_membersize(google_firestore_v1_BatchGetDocumentsResponse, found) < 256 && pb_membersize(google_firestore_v1_BatchGetDocumentsResponse, read_time) < 256 && pb_membersize(google_firestore_v1_BeginTransactionRequest, options) < 256 && pb_membersize(google_firestore_v1_CommitResponse, commit_time) < 256 && pb_membersize(google_firestore_v1_RunQueryRequest, query_type.structured_query) < 256 && pb_membersize(google_firestore_v1_RunQueryRequest, consistency_selector.new_transaction) < 256 && pb_membersize(google_firestore_v1_RunQueryRequest, consistency_selector.read_time) < 256 && pb_membersize(google_firestore_v1_RunQueryResponse, document) < 256 && pb_membersize(google_firestore_v1_RunQueryResponse, read_time) < 256 && pb_membersize(google_firestore_v1_WriteResponse, commit_time) < 256 && pb_membersize(google_firestore_v1_ListenRequest, add_target) < 256 && pb_membersize(google_firestore_v1_ListenResponse, target_change) < 256 && pb_membersize(google_firestore_v1_ListenResponse, document_change) < 256 && pb_membersize(google_firestore_v1_ListenResponse, document_delete) < 256 && pb_membersize(google_firestore_v1_ListenResponse, filter) < 256 && pb_membersize(google_firestore_v1_ListenResponse, document_remove) < 256 && pb_membersize(google_firestore_v1_Target, target_type.query) < 256 && pb_membersize(google_firestore_v1_Target, target_type.documents) < 256 && pb_membersize(google_firestore_v1_Target, resume_type.read_time) < 256 && pb_membersize(google_firestore_v1_Target_QueryTarget, structured_query) < 256 && pb_membersize(google_firestore_v1_TargetChange, cause) < 256 && pb_membersize(google_firestore_v1_TargetChange, read_time) < 256), YOU_MUST_DEFINE_PB_FIELD_16BIT_FOR_MESSAGES_google_firestore_v1_GetDocumentRequest_google_firestore_v1_ListDocumentsRequest_google_firestore_v1_ListDocumentsResponse_google_firestore_v1_CreateDocumentRequest_google_firestore_v1_UpdateDocumentRequest_google_firestore_v1_DeleteDocumentRequest_google_firestore_v1_BatchGetDocumentsRequest_google_firestore_v1_BatchGetDocumentsResponse_google_firestore_v1_BeginTransactionRequest_google_firestore_v1_BeginTransactionResponse_google_firestore_v1_CommitRequest_google_firestore_v1_CommitResponse_google_firestore_v1_RollbackRequest_google_firestore_v1_RunQueryRequest_google_firestore_v1_RunQueryResponse_google_firestore_v1_WriteRequest_google_firestore_v1_WriteRequest_LabelsEntry_google_firestore_v1_WriteResponse_google_firestore_v1_ListenRequest_google_firestore_v1_ListenRequest_LabelsEntry_google_firestore_v1_ListenResponse_google_firestore_v1_Target_google_firestore_v1_Target_DocumentsTarget_google_firestore_v1_Target_QueryTarget_google_firestore_v1_TargetChange_google_firestore_v1_ListCollectionIdsRequest_google_firestore_v1_ListCollectionIdsResponse) +#endif + + +} // namespace firestore +} // namespace firebase + +/* @@protoc_insertion_point(eof) */ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/google/firestore/v1/firestore.nanopb.h b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/google/firestore/v1/firestore.nanopb.h new file mode 100644 index 0000000..3b949de --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/google/firestore/v1/firestore.nanopb.h @@ -0,0 +1,537 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +/* Automatically generated nanopb header */ +/* Generated by nanopb-0.3.9.1 */ + +#ifndef PB_GOOGLE_FIRESTORE_V1_FIRESTORE_NANOPB_H_INCLUDED +#define PB_GOOGLE_FIRESTORE_V1_FIRESTORE_NANOPB_H_INCLUDED +#include + +#include "google/api/annotations.nanopb.h" + +#include "google/firestore/v1/common.nanopb.h" + +#include "google/firestore/v1/document.nanopb.h" + +#include "google/firestore/v1/query.nanopb.h" + +#include "google/firestore/v1/write.nanopb.h" + +#include "google/protobuf/empty.nanopb.h" + +#include "google/protobuf/timestamp.nanopb.h" + +#include "google/rpc/status.nanopb.h" + +namespace firebase { +namespace firestore { + +/* @@protoc_insertion_point(includes) */ +#if PB_PROTO_HEADER_VERSION != 30 +#error Regenerate this file with the current version of nanopb generator. +#endif + + +/* Enum definitions */ +typedef enum _google_firestore_v1_TargetChange_TargetChangeType { + google_firestore_v1_TargetChange_TargetChangeType_NO_CHANGE = 0, + google_firestore_v1_TargetChange_TargetChangeType_ADD = 1, + google_firestore_v1_TargetChange_TargetChangeType_REMOVE = 2, + google_firestore_v1_TargetChange_TargetChangeType_CURRENT = 3, + google_firestore_v1_TargetChange_TargetChangeType_RESET = 4 +} google_firestore_v1_TargetChange_TargetChangeType; +#define _google_firestore_v1_TargetChange_TargetChangeType_MIN google_firestore_v1_TargetChange_TargetChangeType_NO_CHANGE +#define _google_firestore_v1_TargetChange_TargetChangeType_MAX google_firestore_v1_TargetChange_TargetChangeType_RESET +#define _google_firestore_v1_TargetChange_TargetChangeType_ARRAYSIZE ((google_firestore_v1_TargetChange_TargetChangeType)(google_firestore_v1_TargetChange_TargetChangeType_RESET+1)) + +/* Struct definitions */ +typedef struct _google_firestore_v1_BeginTransactionResponse { + pb_bytes_array_t *transaction; +/* @@protoc_insertion_point(struct:google_firestore_v1_BeginTransactionResponse) */ +} google_firestore_v1_BeginTransactionResponse; + +typedef struct _google_firestore_v1_CommitRequest { + pb_bytes_array_t *database; + pb_size_t writes_count; + struct _google_firestore_v1_Write *writes; + pb_bytes_array_t *transaction; +/* @@protoc_insertion_point(struct:google_firestore_v1_CommitRequest) */ +} google_firestore_v1_CommitRequest; + +typedef struct _google_firestore_v1_ListCollectionIdsResponse { + pb_size_t collection_ids_count; + pb_bytes_array_t **collection_ids; + pb_bytes_array_t *next_page_token; +/* @@protoc_insertion_point(struct:google_firestore_v1_ListCollectionIdsResponse) */ +} google_firestore_v1_ListCollectionIdsResponse; + +typedef struct _google_firestore_v1_ListDocumentsResponse { + pb_size_t documents_count; + struct _google_firestore_v1_Document *documents; + pb_bytes_array_t *next_page_token; +/* @@protoc_insertion_point(struct:google_firestore_v1_ListDocumentsResponse) */ +} google_firestore_v1_ListDocumentsResponse; + +typedef struct _google_firestore_v1_ListenRequest_LabelsEntry { + pb_bytes_array_t *key; + pb_bytes_array_t *value; +/* @@protoc_insertion_point(struct:google_firestore_v1_ListenRequest_LabelsEntry) */ +} google_firestore_v1_ListenRequest_LabelsEntry; + +typedef struct _google_firestore_v1_RollbackRequest { + pb_bytes_array_t *database; + pb_bytes_array_t *transaction; +/* @@protoc_insertion_point(struct:google_firestore_v1_RollbackRequest) */ +} google_firestore_v1_RollbackRequest; + +typedef struct _google_firestore_v1_Target_DocumentsTarget { + pb_size_t documents_count; + pb_bytes_array_t **documents; +/* @@protoc_insertion_point(struct:google_firestore_v1_Target_DocumentsTarget) */ +} google_firestore_v1_Target_DocumentsTarget; + +typedef struct _google_firestore_v1_WriteRequest { + pb_bytes_array_t *database; + pb_bytes_array_t *stream_id; + pb_size_t writes_count; + struct _google_firestore_v1_Write *writes; + pb_bytes_array_t *stream_token; + pb_size_t labels_count; + struct _google_firestore_v1_WriteRequest_LabelsEntry *labels; +/* @@protoc_insertion_point(struct:google_firestore_v1_WriteRequest) */ +} google_firestore_v1_WriteRequest; + +typedef struct _google_firestore_v1_WriteRequest_LabelsEntry { + pb_bytes_array_t *key; + pb_bytes_array_t *value; +/* @@protoc_insertion_point(struct:google_firestore_v1_WriteRequest_LabelsEntry) */ +} google_firestore_v1_WriteRequest_LabelsEntry; + +typedef struct _google_firestore_v1_BatchGetDocumentsRequest { + pb_bytes_array_t *database; + pb_size_t documents_count; + pb_bytes_array_t **documents; + google_firestore_v1_DocumentMask mask; + pb_size_t which_consistency_selector; + union { + pb_bytes_array_t *transaction; + google_firestore_v1_TransactionOptions new_transaction; + google_protobuf_Timestamp read_time; + }; +/* @@protoc_insertion_point(struct:google_firestore_v1_BatchGetDocumentsRequest) */ +} google_firestore_v1_BatchGetDocumentsRequest; + +typedef struct _google_firestore_v1_BatchGetDocumentsResponse { + pb_size_t which_result; + union { + google_firestore_v1_Document found; + pb_bytes_array_t *missing; + }; + pb_bytes_array_t *transaction; + google_protobuf_Timestamp read_time; +/* @@protoc_insertion_point(struct:google_firestore_v1_BatchGetDocumentsResponse) */ +} google_firestore_v1_BatchGetDocumentsResponse; + +typedef struct _google_firestore_v1_BeginTransactionRequest { + pb_bytes_array_t *database; + google_firestore_v1_TransactionOptions options; +/* @@protoc_insertion_point(struct:google_firestore_v1_BeginTransactionRequest) */ +} google_firestore_v1_BeginTransactionRequest; + +typedef struct _google_firestore_v1_CommitResponse { + pb_size_t write_results_count; + struct _google_firestore_v1_WriteResult *write_results; + google_protobuf_Timestamp commit_time; +/* @@protoc_insertion_point(struct:google_firestore_v1_CommitResponse) */ +} google_firestore_v1_CommitResponse; + +typedef struct _google_firestore_v1_CreateDocumentRequest { + pb_bytes_array_t *parent; + pb_bytes_array_t *collection_id; + pb_bytes_array_t *document_id; + google_firestore_v1_Document document; + google_firestore_v1_DocumentMask mask; +/* @@protoc_insertion_point(struct:google_firestore_v1_CreateDocumentRequest) */ +} google_firestore_v1_CreateDocumentRequest; + +typedef struct _google_firestore_v1_DeleteDocumentRequest { + pb_bytes_array_t *name; + google_firestore_v1_Precondition current_document; +/* @@protoc_insertion_point(struct:google_firestore_v1_DeleteDocumentRequest) */ +} google_firestore_v1_DeleteDocumentRequest; + +typedef struct _google_firestore_v1_GetDocumentRequest { + pb_bytes_array_t *name; + google_firestore_v1_DocumentMask mask; + pb_size_t which_consistency_selector; + union { + pb_bytes_array_t *transaction; + google_protobuf_Timestamp read_time; + }; +/* @@protoc_insertion_point(struct:google_firestore_v1_GetDocumentRequest) */ +} google_firestore_v1_GetDocumentRequest; + +typedef struct _google_firestore_v1_ListCollectionIdsRequest { + pb_bytes_array_t *parent; + int32_t page_size; + pb_bytes_array_t *page_token; +/* @@protoc_insertion_point(struct:google_firestore_v1_ListCollectionIdsRequest) */ +} google_firestore_v1_ListCollectionIdsRequest; + +typedef struct _google_firestore_v1_ListDocumentsRequest { + pb_bytes_array_t *parent; + pb_bytes_array_t *collection_id; + int32_t page_size; + pb_bytes_array_t *page_token; + pb_bytes_array_t *order_by; + google_firestore_v1_DocumentMask mask; + pb_size_t which_consistency_selector; + union { + pb_bytes_array_t *transaction; + google_protobuf_Timestamp read_time; + }; + bool show_missing; +/* @@protoc_insertion_point(struct:google_firestore_v1_ListDocumentsRequest) */ +} google_firestore_v1_ListDocumentsRequest; + +typedef struct _google_firestore_v1_RunQueryRequest { + pb_bytes_array_t *parent; + pb_size_t which_query_type; + union { + google_firestore_v1_StructuredQuery structured_query; + } query_type; + pb_size_t which_consistency_selector; + union { + pb_bytes_array_t *transaction; + google_firestore_v1_TransactionOptions new_transaction; + google_protobuf_Timestamp read_time; + } consistency_selector; +/* @@protoc_insertion_point(struct:google_firestore_v1_RunQueryRequest) */ +} google_firestore_v1_RunQueryRequest; + +typedef struct _google_firestore_v1_RunQueryResponse { + google_firestore_v1_Document document; + pb_bytes_array_t *transaction; + google_protobuf_Timestamp read_time; + int32_t skipped_results; +/* @@protoc_insertion_point(struct:google_firestore_v1_RunQueryResponse) */ +} google_firestore_v1_RunQueryResponse; + +typedef struct _google_firestore_v1_TargetChange { + google_firestore_v1_TargetChange_TargetChangeType target_change_type; + pb_size_t target_ids_count; + int32_t *target_ids; + google_rpc_Status cause; + pb_bytes_array_t *resume_token; + google_protobuf_Timestamp read_time; +/* @@protoc_insertion_point(struct:google_firestore_v1_TargetChange) */ +} google_firestore_v1_TargetChange; + +typedef struct _google_firestore_v1_Target_QueryTarget { + pb_bytes_array_t *parent; + pb_size_t which_query_type; + union { + google_firestore_v1_StructuredQuery structured_query; + }; +/* @@protoc_insertion_point(struct:google_firestore_v1_Target_QueryTarget) */ +} google_firestore_v1_Target_QueryTarget; + +typedef struct _google_firestore_v1_UpdateDocumentRequest { + google_firestore_v1_Document document; + google_firestore_v1_DocumentMask update_mask; + google_firestore_v1_DocumentMask mask; + google_firestore_v1_Precondition current_document; +/* @@protoc_insertion_point(struct:google_firestore_v1_UpdateDocumentRequest) */ +} google_firestore_v1_UpdateDocumentRequest; + +typedef struct _google_firestore_v1_WriteResponse { + pb_bytes_array_t *stream_id; + pb_bytes_array_t *stream_token; + pb_size_t write_results_count; + struct _google_firestore_v1_WriteResult *write_results; + google_protobuf_Timestamp commit_time; +/* @@protoc_insertion_point(struct:google_firestore_v1_WriteResponse) */ +} google_firestore_v1_WriteResponse; + +typedef struct _google_firestore_v1_ListenResponse { + pb_size_t which_response_type; + union { + google_firestore_v1_TargetChange target_change; + google_firestore_v1_DocumentChange document_change; + google_firestore_v1_DocumentDelete document_delete; + google_firestore_v1_ExistenceFilter filter; + google_firestore_v1_DocumentRemove document_remove; + }; +/* @@protoc_insertion_point(struct:google_firestore_v1_ListenResponse) */ +} google_firestore_v1_ListenResponse; + +typedef struct _google_firestore_v1_Target { + pb_size_t which_target_type; + union { + google_firestore_v1_Target_QueryTarget query; + google_firestore_v1_Target_DocumentsTarget documents; + } target_type; + pb_size_t which_resume_type; + union { + pb_bytes_array_t *resume_token; + google_protobuf_Timestamp read_time; + } resume_type; + int32_t target_id; + bool once; +/* @@protoc_insertion_point(struct:google_firestore_v1_Target) */ +} google_firestore_v1_Target; + +typedef struct _google_firestore_v1_ListenRequest { + pb_bytes_array_t *database; + pb_size_t which_target_change; + union { + google_firestore_v1_Target add_target; + int32_t remove_target; + }; + pb_size_t labels_count; + struct _google_firestore_v1_ListenRequest_LabelsEntry *labels; +/* @@protoc_insertion_point(struct:google_firestore_v1_ListenRequest) */ +} google_firestore_v1_ListenRequest; + +/* Default values for struct fields */ + +/* Initializer values for message structs */ +#define google_firestore_v1_GetDocumentRequest_init_default {NULL, google_firestore_v1_DocumentMask_init_default, 0, {NULL}} +#define google_firestore_v1_ListDocumentsRequest_init_default {NULL, NULL, 0, NULL, NULL, google_firestore_v1_DocumentMask_init_default, 0, {NULL}, 0} +#define google_firestore_v1_ListDocumentsResponse_init_default {0, NULL, NULL} +#define google_firestore_v1_CreateDocumentRequest_init_default {NULL, NULL, NULL, google_firestore_v1_Document_init_default, google_firestore_v1_DocumentMask_init_default} +#define google_firestore_v1_UpdateDocumentRequest_init_default {google_firestore_v1_Document_init_default, google_firestore_v1_DocumentMask_init_default, google_firestore_v1_DocumentMask_init_default, google_firestore_v1_Precondition_init_default} +#define google_firestore_v1_DeleteDocumentRequest_init_default {NULL, google_firestore_v1_Precondition_init_default} +#define google_firestore_v1_BatchGetDocumentsRequest_init_default {NULL, 0, NULL, google_firestore_v1_DocumentMask_init_default, 0, {NULL}} +#define google_firestore_v1_BatchGetDocumentsResponse_init_default {0, {google_firestore_v1_Document_init_default}, NULL, google_protobuf_Timestamp_init_default} +#define google_firestore_v1_BeginTransactionRequest_init_default {NULL, google_firestore_v1_TransactionOptions_init_default} +#define google_firestore_v1_BeginTransactionResponse_init_default {NULL} +#define google_firestore_v1_CommitRequest_init_default {NULL, 0, NULL, NULL} +#define google_firestore_v1_CommitResponse_init_default {0, NULL, google_protobuf_Timestamp_init_default} +#define google_firestore_v1_RollbackRequest_init_default {NULL, NULL} +#define google_firestore_v1_RunQueryRequest_init_default {NULL, 0, {google_firestore_v1_StructuredQuery_init_default}, 0, {NULL}} +#define google_firestore_v1_RunQueryResponse_init_default {google_firestore_v1_Document_init_default, NULL, google_protobuf_Timestamp_init_default, 0} +#define google_firestore_v1_WriteRequest_init_default {NULL, NULL, 0, NULL, NULL, 0, NULL} +#define google_firestore_v1_WriteRequest_LabelsEntry_init_default {NULL, NULL} +#define google_firestore_v1_WriteResponse_init_default {NULL, NULL, 0, NULL, google_protobuf_Timestamp_init_default} +#define google_firestore_v1_ListenRequest_init_default {NULL, 0, {google_firestore_v1_Target_init_default}, 0, NULL} +#define google_firestore_v1_ListenRequest_LabelsEntry_init_default {NULL, NULL} +#define google_firestore_v1_ListenResponse_init_default {0, {google_firestore_v1_TargetChange_init_default}} +#define google_firestore_v1_Target_init_default {0, {google_firestore_v1_Target_QueryTarget_init_default}, 0, {NULL}, 0, 0} +#define google_firestore_v1_Target_DocumentsTarget_init_default {0, NULL} +#define google_firestore_v1_Target_QueryTarget_init_default {NULL, 0, {google_firestore_v1_StructuredQuery_init_default}} +#define google_firestore_v1_TargetChange_init_default {_google_firestore_v1_TargetChange_TargetChangeType_MIN, 0, NULL, google_rpc_Status_init_default, NULL, google_protobuf_Timestamp_init_default} +#define google_firestore_v1_ListCollectionIdsRequest_init_default {NULL, 0, NULL} +#define google_firestore_v1_ListCollectionIdsResponse_init_default {0, NULL, NULL} +#define google_firestore_v1_GetDocumentRequest_init_zero {NULL, google_firestore_v1_DocumentMask_init_zero, 0, {NULL}} +#define google_firestore_v1_ListDocumentsRequest_init_zero {NULL, NULL, 0, NULL, NULL, google_firestore_v1_DocumentMask_init_zero, 0, {NULL}, 0} +#define google_firestore_v1_ListDocumentsResponse_init_zero {0, NULL, NULL} +#define google_firestore_v1_CreateDocumentRequest_init_zero {NULL, NULL, NULL, google_firestore_v1_Document_init_zero, google_firestore_v1_DocumentMask_init_zero} +#define google_firestore_v1_UpdateDocumentRequest_init_zero {google_firestore_v1_Document_init_zero, google_firestore_v1_DocumentMask_init_zero, google_firestore_v1_DocumentMask_init_zero, google_firestore_v1_Precondition_init_zero} +#define google_firestore_v1_DeleteDocumentRequest_init_zero {NULL, google_firestore_v1_Precondition_init_zero} +#define google_firestore_v1_BatchGetDocumentsRequest_init_zero {NULL, 0, NULL, google_firestore_v1_DocumentMask_init_zero, 0, {NULL}} +#define google_firestore_v1_BatchGetDocumentsResponse_init_zero {0, {google_firestore_v1_Document_init_zero}, NULL, google_protobuf_Timestamp_init_zero} +#define google_firestore_v1_BeginTransactionRequest_init_zero {NULL, google_firestore_v1_TransactionOptions_init_zero} +#define google_firestore_v1_BeginTransactionResponse_init_zero {NULL} +#define google_firestore_v1_CommitRequest_init_zero {NULL, 0, NULL, NULL} +#define google_firestore_v1_CommitResponse_init_zero {0, NULL, google_protobuf_Timestamp_init_zero} +#define google_firestore_v1_RollbackRequest_init_zero {NULL, NULL} +#define google_firestore_v1_RunQueryRequest_init_zero {NULL, 0, {google_firestore_v1_StructuredQuery_init_zero}, 0, {NULL}} +#define google_firestore_v1_RunQueryResponse_init_zero {google_firestore_v1_Document_init_zero, NULL, google_protobuf_Timestamp_init_zero, 0} +#define google_firestore_v1_WriteRequest_init_zero {NULL, NULL, 0, NULL, NULL, 0, NULL} +#define google_firestore_v1_WriteRequest_LabelsEntry_init_zero {NULL, NULL} +#define google_firestore_v1_WriteResponse_init_zero {NULL, NULL, 0, NULL, google_protobuf_Timestamp_init_zero} +#define google_firestore_v1_ListenRequest_init_zero {NULL, 0, {google_firestore_v1_Target_init_zero}, 0, NULL} +#define google_firestore_v1_ListenRequest_LabelsEntry_init_zero {NULL, NULL} +#define google_firestore_v1_ListenResponse_init_zero {0, {google_firestore_v1_TargetChange_init_zero}} +#define google_firestore_v1_Target_init_zero {0, {google_firestore_v1_Target_QueryTarget_init_zero}, 0, {NULL}, 0, 0} +#define google_firestore_v1_Target_DocumentsTarget_init_zero {0, NULL} +#define google_firestore_v1_Target_QueryTarget_init_zero {NULL, 0, {google_firestore_v1_StructuredQuery_init_zero}} +#define google_firestore_v1_TargetChange_init_zero {_google_firestore_v1_TargetChange_TargetChangeType_MIN, 0, NULL, google_rpc_Status_init_zero, NULL, google_protobuf_Timestamp_init_zero} +#define google_firestore_v1_ListCollectionIdsRequest_init_zero {NULL, 0, NULL} +#define google_firestore_v1_ListCollectionIdsResponse_init_zero {0, NULL, NULL} + +/* Field tags (for use in manual encoding/decoding) */ +#define google_firestore_v1_BeginTransactionResponse_transaction_tag 1 +#define google_firestore_v1_CommitRequest_database_tag 1 +#define google_firestore_v1_CommitRequest_writes_tag 2 +#define google_firestore_v1_CommitRequest_transaction_tag 3 +#define google_firestore_v1_ListCollectionIdsResponse_collection_ids_tag 1 +#define google_firestore_v1_ListCollectionIdsResponse_next_page_token_tag 2 +#define google_firestore_v1_ListDocumentsResponse_documents_tag 1 +#define google_firestore_v1_ListDocumentsResponse_next_page_token_tag 2 +#define google_firestore_v1_ListenRequest_LabelsEntry_key_tag 1 +#define google_firestore_v1_ListenRequest_LabelsEntry_value_tag 2 +#define google_firestore_v1_RollbackRequest_database_tag 1 +#define google_firestore_v1_RollbackRequest_transaction_tag 2 +#define google_firestore_v1_Target_DocumentsTarget_documents_tag 2 +#define google_firestore_v1_WriteRequest_database_tag 1 +#define google_firestore_v1_WriteRequest_stream_id_tag 2 +#define google_firestore_v1_WriteRequest_writes_tag 3 +#define google_firestore_v1_WriteRequest_stream_token_tag 4 +#define google_firestore_v1_WriteRequest_labels_tag 5 +#define google_firestore_v1_WriteRequest_LabelsEntry_key_tag 1 +#define google_firestore_v1_WriteRequest_LabelsEntry_value_tag 2 +#define google_firestore_v1_BatchGetDocumentsRequest_transaction_tag 4 +#define google_firestore_v1_BatchGetDocumentsRequest_new_transaction_tag 5 +#define google_firestore_v1_BatchGetDocumentsRequest_read_time_tag 7 +#define google_firestore_v1_BatchGetDocumentsRequest_database_tag 1 +#define google_firestore_v1_BatchGetDocumentsRequest_documents_tag 2 +#define google_firestore_v1_BatchGetDocumentsRequest_mask_tag 3 +#define google_firestore_v1_BatchGetDocumentsResponse_found_tag 1 +#define google_firestore_v1_BatchGetDocumentsResponse_missing_tag 2 +#define google_firestore_v1_BatchGetDocumentsResponse_transaction_tag 3 +#define google_firestore_v1_BatchGetDocumentsResponse_read_time_tag 4 +#define google_firestore_v1_BeginTransactionRequest_database_tag 1 +#define google_firestore_v1_BeginTransactionRequest_options_tag 2 +#define google_firestore_v1_CommitResponse_write_results_tag 1 +#define google_firestore_v1_CommitResponse_commit_time_tag 2 +#define google_firestore_v1_CreateDocumentRequest_parent_tag 1 +#define google_firestore_v1_CreateDocumentRequest_collection_id_tag 2 +#define google_firestore_v1_CreateDocumentRequest_document_id_tag 3 +#define google_firestore_v1_CreateDocumentRequest_document_tag 4 +#define google_firestore_v1_CreateDocumentRequest_mask_tag 5 +#define google_firestore_v1_DeleteDocumentRequest_name_tag 1 +#define google_firestore_v1_DeleteDocumentRequest_current_document_tag 2 +#define google_firestore_v1_GetDocumentRequest_transaction_tag 3 +#define google_firestore_v1_GetDocumentRequest_read_time_tag 5 +#define google_firestore_v1_GetDocumentRequest_name_tag 1 +#define google_firestore_v1_GetDocumentRequest_mask_tag 2 +#define google_firestore_v1_ListCollectionIdsRequest_parent_tag 1 +#define google_firestore_v1_ListCollectionIdsRequest_page_size_tag 2 +#define google_firestore_v1_ListCollectionIdsRequest_page_token_tag 3 +#define google_firestore_v1_ListDocumentsRequest_transaction_tag 8 +#define google_firestore_v1_ListDocumentsRequest_read_time_tag 10 +#define google_firestore_v1_ListDocumentsRequest_parent_tag 1 +#define google_firestore_v1_ListDocumentsRequest_collection_id_tag 2 +#define google_firestore_v1_ListDocumentsRequest_page_size_tag 3 +#define google_firestore_v1_ListDocumentsRequest_page_token_tag 4 +#define google_firestore_v1_ListDocumentsRequest_order_by_tag 6 +#define google_firestore_v1_ListDocumentsRequest_mask_tag 7 +#define google_firestore_v1_ListDocumentsRequest_show_missing_tag 12 +#define google_firestore_v1_RunQueryRequest_structured_query_tag 2 +#define google_firestore_v1_RunQueryRequest_transaction_tag 5 +#define google_firestore_v1_RunQueryRequest_new_transaction_tag 6 +#define google_firestore_v1_RunQueryRequest_read_time_tag 7 +#define google_firestore_v1_RunQueryRequest_parent_tag 1 +#define google_firestore_v1_RunQueryResponse_transaction_tag 2 +#define google_firestore_v1_RunQueryResponse_document_tag 1 +#define google_firestore_v1_RunQueryResponse_read_time_tag 3 +#define google_firestore_v1_RunQueryResponse_skipped_results_tag 4 +#define google_firestore_v1_TargetChange_target_change_type_tag 1 +#define google_firestore_v1_TargetChange_target_ids_tag 2 +#define google_firestore_v1_TargetChange_cause_tag 3 +#define google_firestore_v1_TargetChange_resume_token_tag 4 +#define google_firestore_v1_TargetChange_read_time_tag 6 +#define google_firestore_v1_Target_QueryTarget_structured_query_tag 2 +#define google_firestore_v1_Target_QueryTarget_parent_tag 1 +#define google_firestore_v1_UpdateDocumentRequest_document_tag 1 +#define google_firestore_v1_UpdateDocumentRequest_update_mask_tag 2 +#define google_firestore_v1_UpdateDocumentRequest_mask_tag 3 +#define google_firestore_v1_UpdateDocumentRequest_current_document_tag 4 +#define google_firestore_v1_WriteResponse_stream_id_tag 1 +#define google_firestore_v1_WriteResponse_stream_token_tag 2 +#define google_firestore_v1_WriteResponse_write_results_tag 3 +#define google_firestore_v1_WriteResponse_commit_time_tag 4 +#define google_firestore_v1_ListenResponse_target_change_tag 2 +#define google_firestore_v1_ListenResponse_document_change_tag 3 +#define google_firestore_v1_ListenResponse_document_delete_tag 4 +#define google_firestore_v1_ListenResponse_filter_tag 5 +#define google_firestore_v1_ListenResponse_document_remove_tag 6 +#define google_firestore_v1_Target_query_tag 2 +#define google_firestore_v1_Target_documents_tag 3 +#define google_firestore_v1_Target_resume_token_tag 4 +#define google_firestore_v1_Target_read_time_tag 11 +#define google_firestore_v1_Target_target_id_tag 5 +#define google_firestore_v1_Target_once_tag 6 +#define google_firestore_v1_ListenRequest_add_target_tag 2 +#define google_firestore_v1_ListenRequest_remove_target_tag 3 +#define google_firestore_v1_ListenRequest_database_tag 1 +#define google_firestore_v1_ListenRequest_labels_tag 4 + +/* Struct field encoding specification for nanopb */ +extern const pb_field_t google_firestore_v1_GetDocumentRequest_fields[5]; +extern const pb_field_t google_firestore_v1_ListDocumentsRequest_fields[10]; +extern const pb_field_t google_firestore_v1_ListDocumentsResponse_fields[3]; +extern const pb_field_t google_firestore_v1_CreateDocumentRequest_fields[6]; +extern const pb_field_t google_firestore_v1_UpdateDocumentRequest_fields[5]; +extern const pb_field_t google_firestore_v1_DeleteDocumentRequest_fields[3]; +extern const pb_field_t google_firestore_v1_BatchGetDocumentsRequest_fields[7]; +extern const pb_field_t google_firestore_v1_BatchGetDocumentsResponse_fields[5]; +extern const pb_field_t google_firestore_v1_BeginTransactionRequest_fields[3]; +extern const pb_field_t google_firestore_v1_BeginTransactionResponse_fields[2]; +extern const pb_field_t google_firestore_v1_CommitRequest_fields[4]; +extern const pb_field_t google_firestore_v1_CommitResponse_fields[3]; +extern const pb_field_t google_firestore_v1_RollbackRequest_fields[3]; +extern const pb_field_t google_firestore_v1_RunQueryRequest_fields[6]; +extern const pb_field_t google_firestore_v1_RunQueryResponse_fields[5]; +extern const pb_field_t google_firestore_v1_WriteRequest_fields[6]; +extern const pb_field_t google_firestore_v1_WriteRequest_LabelsEntry_fields[3]; +extern const pb_field_t google_firestore_v1_WriteResponse_fields[5]; +extern const pb_field_t google_firestore_v1_ListenRequest_fields[5]; +extern const pb_field_t google_firestore_v1_ListenRequest_LabelsEntry_fields[3]; +extern const pb_field_t google_firestore_v1_ListenResponse_fields[6]; +extern const pb_field_t google_firestore_v1_Target_fields[7]; +extern const pb_field_t google_firestore_v1_Target_DocumentsTarget_fields[2]; +extern const pb_field_t google_firestore_v1_Target_QueryTarget_fields[3]; +extern const pb_field_t google_firestore_v1_TargetChange_fields[6]; +extern const pb_field_t google_firestore_v1_ListCollectionIdsRequest_fields[4]; +extern const pb_field_t google_firestore_v1_ListCollectionIdsResponse_fields[3]; + +/* Maximum encoded size of messages (where known) */ +/* google_firestore_v1_GetDocumentRequest_size depends on runtime parameters */ +/* google_firestore_v1_ListDocumentsRequest_size depends on runtime parameters */ +/* google_firestore_v1_ListDocumentsResponse_size depends on runtime parameters */ +/* google_firestore_v1_CreateDocumentRequest_size depends on runtime parameters */ +#define google_firestore_v1_UpdateDocumentRequest_size (44 + google_firestore_v1_Document_size + google_firestore_v1_DocumentMask_size + google_firestore_v1_DocumentMask_size) +/* google_firestore_v1_DeleteDocumentRequest_size depends on runtime parameters */ +/* google_firestore_v1_BatchGetDocumentsRequest_size depends on runtime parameters */ +/* google_firestore_v1_BatchGetDocumentsResponse_size depends on runtime parameters */ +/* google_firestore_v1_BeginTransactionRequest_size depends on runtime parameters */ +/* google_firestore_v1_BeginTransactionResponse_size depends on runtime parameters */ +/* google_firestore_v1_CommitRequest_size depends on runtime parameters */ +/* google_firestore_v1_CommitResponse_size depends on runtime parameters */ +/* google_firestore_v1_RollbackRequest_size depends on runtime parameters */ +/* google_firestore_v1_RunQueryRequest_size depends on runtime parameters */ +/* google_firestore_v1_RunQueryResponse_size depends on runtime parameters */ +/* google_firestore_v1_WriteRequest_size depends on runtime parameters */ +/* google_firestore_v1_WriteRequest_LabelsEntry_size depends on runtime parameters */ +/* google_firestore_v1_WriteResponse_size depends on runtime parameters */ +/* google_firestore_v1_ListenRequest_size depends on runtime parameters */ +/* google_firestore_v1_ListenRequest_LabelsEntry_size depends on runtime parameters */ +#define google_firestore_v1_ListenResponse_size (0 + ((((google_firestore_v1_TargetChange_size > google_firestore_v1_DocumentChange_size ? google_firestore_v1_TargetChange_size : google_firestore_v1_DocumentChange_size) > google_firestore_v1_DocumentRemove_size ? (google_firestore_v1_TargetChange_size > google_firestore_v1_DocumentChange_size ? google_firestore_v1_TargetChange_size : google_firestore_v1_DocumentChange_size) : google_firestore_v1_DocumentRemove_size) > google_firestore_v1_DocumentDelete_size ? ((google_firestore_v1_TargetChange_size > google_firestore_v1_DocumentChange_size ? google_firestore_v1_TargetChange_size : google_firestore_v1_DocumentChange_size) > google_firestore_v1_DocumentRemove_size ? (google_firestore_v1_TargetChange_size > google_firestore_v1_DocumentChange_size ? google_firestore_v1_TargetChange_size : google_firestore_v1_DocumentChange_size) : google_firestore_v1_DocumentRemove_size) : google_firestore_v1_DocumentDelete_size) > 24 ? (((google_firestore_v1_TargetChange_size > google_firestore_v1_DocumentChange_size ? google_firestore_v1_TargetChange_size : google_firestore_v1_DocumentChange_size) > google_firestore_v1_DocumentRemove_size ? (google_firestore_v1_TargetChange_size > google_firestore_v1_DocumentChange_size ? google_firestore_v1_TargetChange_size : google_firestore_v1_DocumentChange_size) : google_firestore_v1_DocumentRemove_size) > google_firestore_v1_DocumentDelete_size ? ((google_firestore_v1_TargetChange_size > google_firestore_v1_DocumentChange_size ? google_firestore_v1_TargetChange_size : google_firestore_v1_DocumentChange_size) > google_firestore_v1_DocumentRemove_size ? (google_firestore_v1_TargetChange_size > google_firestore_v1_DocumentChange_size ? google_firestore_v1_TargetChange_size : google_firestore_v1_DocumentChange_size) : google_firestore_v1_DocumentRemove_size) : google_firestore_v1_DocumentDelete_size) : 24)) +/* google_firestore_v1_Target_size depends on runtime parameters */ +/* google_firestore_v1_Target_DocumentsTarget_size depends on runtime parameters */ +/* google_firestore_v1_Target_QueryTarget_size depends on runtime parameters */ +/* google_firestore_v1_TargetChange_size depends on runtime parameters */ +/* google_firestore_v1_ListCollectionIdsRequest_size depends on runtime parameters */ +/* google_firestore_v1_ListCollectionIdsResponse_size depends on runtime parameters */ + +/* Message IDs (where set with "msgid" option) */ +#ifdef PB_MSGID + +#define FIRESTORE_MESSAGES \ + + +#endif + +} // namespace firestore +} // namespace firebase + +/* @@protoc_insertion_point(eof) */ + +#endif diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/google/firestore/v1/query.nanopb.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/google/firestore/v1/query.nanopb.cc new file mode 100644 index 0000000..7e63a72 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/google/firestore/v1/query.nanopb.cc @@ -0,0 +1,130 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +/* Automatically generated nanopb constant definitions */ +/* Generated by nanopb-0.3.9.1 */ + +#include "query.nanopb.h" + +namespace firebase { +namespace firestore { + +/* @@protoc_insertion_point(includes) */ +#if PB_PROTO_HEADER_VERSION != 30 +#error Regenerate this file with the current version of nanopb generator. +#endif + + + +const pb_field_t google_firestore_v1_StructuredQuery_fields[9] = { + PB_FIELD( 1, MESSAGE , SINGULAR, STATIC , FIRST, google_firestore_v1_StructuredQuery, select, select, &google_firestore_v1_StructuredQuery_Projection_fields), + PB_FIELD( 2, MESSAGE , REPEATED, POINTER , OTHER, google_firestore_v1_StructuredQuery, from, select, &google_firestore_v1_StructuredQuery_CollectionSelector_fields), + PB_FIELD( 3, MESSAGE , SINGULAR, STATIC , OTHER, google_firestore_v1_StructuredQuery, where, from, &google_firestore_v1_StructuredQuery_Filter_fields), + PB_FIELD( 4, MESSAGE , REPEATED, POINTER , OTHER, google_firestore_v1_StructuredQuery, order_by, where, &google_firestore_v1_StructuredQuery_Order_fields), + PB_FIELD( 5, MESSAGE , SINGULAR, STATIC , OTHER, google_firestore_v1_StructuredQuery, limit, order_by, &google_protobuf_Int32Value_fields), + PB_FIELD( 6, INT32 , SINGULAR, STATIC , OTHER, google_firestore_v1_StructuredQuery, offset, limit, 0), + PB_FIELD( 7, MESSAGE , SINGULAR, STATIC , OTHER, google_firestore_v1_StructuredQuery, start_at, offset, &google_firestore_v1_Cursor_fields), + PB_FIELD( 8, MESSAGE , SINGULAR, STATIC , OTHER, google_firestore_v1_StructuredQuery, end_at, start_at, &google_firestore_v1_Cursor_fields), + PB_LAST_FIELD +}; + +const pb_field_t google_firestore_v1_StructuredQuery_CollectionSelector_fields[3] = { + PB_FIELD( 2, BYTES , SINGULAR, POINTER , FIRST, google_firestore_v1_StructuredQuery_CollectionSelector, collection_id, collection_id, 0), + PB_FIELD( 3, BOOL , SINGULAR, STATIC , OTHER, google_firestore_v1_StructuredQuery_CollectionSelector, all_descendants, collection_id, 0), + PB_LAST_FIELD +}; + +const pb_field_t google_firestore_v1_StructuredQuery_Filter_fields[4] = { + PB_ANONYMOUS_ONEOF_FIELD(filter_type, 1, MESSAGE , ONEOF, STATIC , FIRST, google_firestore_v1_StructuredQuery_Filter, composite_filter, composite_filter, &google_firestore_v1_StructuredQuery_CompositeFilter_fields), + PB_ANONYMOUS_ONEOF_FIELD(filter_type, 2, MESSAGE , ONEOF, STATIC , UNION, google_firestore_v1_StructuredQuery_Filter, field_filter, field_filter, &google_firestore_v1_StructuredQuery_FieldFilter_fields), + PB_ANONYMOUS_ONEOF_FIELD(filter_type, 3, MESSAGE , ONEOF, STATIC , UNION, google_firestore_v1_StructuredQuery_Filter, unary_filter, unary_filter, &google_firestore_v1_StructuredQuery_UnaryFilter_fields), + PB_LAST_FIELD +}; + +const pb_field_t google_firestore_v1_StructuredQuery_CompositeFilter_fields[3] = { + PB_FIELD( 1, UENUM , SINGULAR, STATIC , FIRST, google_firestore_v1_StructuredQuery_CompositeFilter, op, op, 0), + PB_FIELD( 2, MESSAGE , REPEATED, POINTER , OTHER, google_firestore_v1_StructuredQuery_CompositeFilter, filters, op, &google_firestore_v1_StructuredQuery_Filter_fields), + PB_LAST_FIELD +}; + +const pb_field_t google_firestore_v1_StructuredQuery_FieldFilter_fields[4] = { + PB_FIELD( 1, MESSAGE , SINGULAR, STATIC , FIRST, google_firestore_v1_StructuredQuery_FieldFilter, field, field, &google_firestore_v1_StructuredQuery_FieldReference_fields), + PB_FIELD( 2, UENUM , SINGULAR, STATIC , OTHER, google_firestore_v1_StructuredQuery_FieldFilter, op, field, 0), + PB_FIELD( 3, MESSAGE , SINGULAR, STATIC , OTHER, google_firestore_v1_StructuredQuery_FieldFilter, value, op, &google_firestore_v1_Value_fields), + PB_LAST_FIELD +}; + +const pb_field_t google_firestore_v1_StructuredQuery_UnaryFilter_fields[3] = { + PB_FIELD( 1, UENUM , SINGULAR, STATIC , FIRST, google_firestore_v1_StructuredQuery_UnaryFilter, op, op, 0), + PB_ANONYMOUS_ONEOF_FIELD(operand_type, 2, MESSAGE , ONEOF, STATIC , OTHER, google_firestore_v1_StructuredQuery_UnaryFilter, field, op, &google_firestore_v1_StructuredQuery_FieldReference_fields), + PB_LAST_FIELD +}; + +const pb_field_t google_firestore_v1_StructuredQuery_Order_fields[3] = { + PB_FIELD( 1, MESSAGE , SINGULAR, STATIC , FIRST, google_firestore_v1_StructuredQuery_Order, field, field, &google_firestore_v1_StructuredQuery_FieldReference_fields), + PB_FIELD( 2, UENUM , SINGULAR, STATIC , OTHER, google_firestore_v1_StructuredQuery_Order, direction, field, 0), + PB_LAST_FIELD +}; + +const pb_field_t google_firestore_v1_StructuredQuery_FieldReference_fields[2] = { + PB_FIELD( 2, BYTES , SINGULAR, POINTER , FIRST, google_firestore_v1_StructuredQuery_FieldReference, field_path, field_path, 0), + PB_LAST_FIELD +}; + +const pb_field_t google_firestore_v1_StructuredQuery_Projection_fields[2] = { + PB_FIELD( 2, MESSAGE , REPEATED, POINTER , FIRST, google_firestore_v1_StructuredQuery_Projection, fields, fields, &google_firestore_v1_StructuredQuery_FieldReference_fields), + PB_LAST_FIELD +}; + +const pb_field_t google_firestore_v1_Cursor_fields[3] = { + PB_FIELD( 1, MESSAGE , REPEATED, POINTER , FIRST, google_firestore_v1_Cursor, values, values, &google_firestore_v1_Value_fields), + PB_FIELD( 2, BOOL , SINGULAR, STATIC , OTHER, google_firestore_v1_Cursor, before, values, 0), + PB_LAST_FIELD +}; + + + + + + +/* Check that field information fits in pb_field_t */ +#if !defined(PB_FIELD_32BIT) +/* If you get an error here, it means that you need to define PB_FIELD_32BIT + * compile-time option. You can do that in pb.h or on compiler command line. + * + * The reason you need to do this is that some of your messages contain tag + * numbers or field sizes that are larger than what can fit in 8 or 16 bit + * field descriptors. + */ +PB_STATIC_ASSERT((pb_membersize(google_firestore_v1_StructuredQuery, select) < 65536 && pb_membersize(google_firestore_v1_StructuredQuery, where) < 65536 && pb_membersize(google_firestore_v1_StructuredQuery, start_at) < 65536 && pb_membersize(google_firestore_v1_StructuredQuery, end_at) < 65536 && pb_membersize(google_firestore_v1_StructuredQuery, limit) < 65536 && pb_membersize(google_firestore_v1_StructuredQuery_Filter, composite_filter) < 65536 && pb_membersize(google_firestore_v1_StructuredQuery_Filter, field_filter) < 65536 && pb_membersize(google_firestore_v1_StructuredQuery_Filter, unary_filter) < 65536 && pb_membersize(google_firestore_v1_StructuredQuery_FieldFilter, field) < 65536 && pb_membersize(google_firestore_v1_StructuredQuery_FieldFilter, value) < 65536 && pb_membersize(google_firestore_v1_StructuredQuery_UnaryFilter, field) < 65536 && pb_membersize(google_firestore_v1_StructuredQuery_Order, field) < 65536), YOU_MUST_DEFINE_PB_FIELD_32BIT_FOR_MESSAGES_google_firestore_v1_StructuredQuery_google_firestore_v1_StructuredQuery_CollectionSelector_google_firestore_v1_StructuredQuery_Filter_google_firestore_v1_StructuredQuery_CompositeFilter_google_firestore_v1_StructuredQuery_FieldFilter_google_firestore_v1_StructuredQuery_UnaryFilter_google_firestore_v1_StructuredQuery_Order_google_firestore_v1_StructuredQuery_FieldReference_google_firestore_v1_StructuredQuery_Projection_google_firestore_v1_Cursor) +#endif + +#if !defined(PB_FIELD_16BIT) && !defined(PB_FIELD_32BIT) +/* If you get an error here, it means that you need to define PB_FIELD_16BIT + * compile-time option. You can do that in pb.h or on compiler command line. + * + * The reason you need to do this is that some of your messages contain tag + * numbers or field sizes that are larger than what can fit in the default + * 8 bit descriptors. + */ +PB_STATIC_ASSERT((pb_membersize(google_firestore_v1_StructuredQuery, select) < 256 && pb_membersize(google_firestore_v1_StructuredQuery, where) < 256 && pb_membersize(google_firestore_v1_StructuredQuery, start_at) < 256 && pb_membersize(google_firestore_v1_StructuredQuery, end_at) < 256 && pb_membersize(google_firestore_v1_StructuredQuery, limit) < 256 && pb_membersize(google_firestore_v1_StructuredQuery_Filter, composite_filter) < 256 && pb_membersize(google_firestore_v1_StructuredQuery_Filter, field_filter) < 256 && pb_membersize(google_firestore_v1_StructuredQuery_Filter, unary_filter) < 256 && pb_membersize(google_firestore_v1_StructuredQuery_FieldFilter, field) < 256 && pb_membersize(google_firestore_v1_StructuredQuery_FieldFilter, value) < 256 && pb_membersize(google_firestore_v1_StructuredQuery_UnaryFilter, field) < 256 && pb_membersize(google_firestore_v1_StructuredQuery_Order, field) < 256), YOU_MUST_DEFINE_PB_FIELD_16BIT_FOR_MESSAGES_google_firestore_v1_StructuredQuery_google_firestore_v1_StructuredQuery_CollectionSelector_google_firestore_v1_StructuredQuery_Filter_google_firestore_v1_StructuredQuery_CompositeFilter_google_firestore_v1_StructuredQuery_FieldFilter_google_firestore_v1_StructuredQuery_UnaryFilter_google_firestore_v1_StructuredQuery_Order_google_firestore_v1_StructuredQuery_FieldReference_google_firestore_v1_StructuredQuery_Projection_google_firestore_v1_Cursor) +#endif + + +} // namespace firestore +} // namespace firebase + +/* @@protoc_insertion_point(eof) */ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/google/firestore/v1/query.nanopb.h b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/google/firestore/v1/query.nanopb.h new file mode 100644 index 0000000..70a7de2 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/google/firestore/v1/query.nanopb.h @@ -0,0 +1,246 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +/* Automatically generated nanopb header */ +/* Generated by nanopb-0.3.9.1 */ + +#ifndef PB_GOOGLE_FIRESTORE_V1_QUERY_NANOPB_H_INCLUDED +#define PB_GOOGLE_FIRESTORE_V1_QUERY_NANOPB_H_INCLUDED +#include + +#include "google/api/annotations.nanopb.h" + +#include "google/firestore/v1/document.nanopb.h" + +#include "google/protobuf/wrappers.nanopb.h" + +namespace firebase { +namespace firestore { + +/* @@protoc_insertion_point(includes) */ +#if PB_PROTO_HEADER_VERSION != 30 +#error Regenerate this file with the current version of nanopb generator. +#endif + + +/* Enum definitions */ +typedef enum _google_firestore_v1_StructuredQuery_Direction { + google_firestore_v1_StructuredQuery_Direction_DIRECTION_UNSPECIFIED = 0, + google_firestore_v1_StructuredQuery_Direction_ASCENDING = 1, + google_firestore_v1_StructuredQuery_Direction_DESCENDING = 2 +} google_firestore_v1_StructuredQuery_Direction; +#define _google_firestore_v1_StructuredQuery_Direction_MIN google_firestore_v1_StructuredQuery_Direction_DIRECTION_UNSPECIFIED +#define _google_firestore_v1_StructuredQuery_Direction_MAX google_firestore_v1_StructuredQuery_Direction_DESCENDING +#define _google_firestore_v1_StructuredQuery_Direction_ARRAYSIZE ((google_firestore_v1_StructuredQuery_Direction)(google_firestore_v1_StructuredQuery_Direction_DESCENDING+1)) + +typedef enum _google_firestore_v1_StructuredQuery_CompositeFilter_Operator { + google_firestore_v1_StructuredQuery_CompositeFilter_Operator_OPERATOR_UNSPECIFIED = 0, + google_firestore_v1_StructuredQuery_CompositeFilter_Operator_AND = 1 +} google_firestore_v1_StructuredQuery_CompositeFilter_Operator; +#define _google_firestore_v1_StructuredQuery_CompositeFilter_Operator_MIN google_firestore_v1_StructuredQuery_CompositeFilter_Operator_OPERATOR_UNSPECIFIED +#define _google_firestore_v1_StructuredQuery_CompositeFilter_Operator_MAX google_firestore_v1_StructuredQuery_CompositeFilter_Operator_AND +#define _google_firestore_v1_StructuredQuery_CompositeFilter_Operator_ARRAYSIZE ((google_firestore_v1_StructuredQuery_CompositeFilter_Operator)(google_firestore_v1_StructuredQuery_CompositeFilter_Operator_AND+1)) + +typedef enum _google_firestore_v1_StructuredQuery_FieldFilter_Operator { + google_firestore_v1_StructuredQuery_FieldFilter_Operator_OPERATOR_UNSPECIFIED = 0, + google_firestore_v1_StructuredQuery_FieldFilter_Operator_LESS_THAN = 1, + google_firestore_v1_StructuredQuery_FieldFilter_Operator_LESS_THAN_OR_EQUAL = 2, + google_firestore_v1_StructuredQuery_FieldFilter_Operator_GREATER_THAN = 3, + google_firestore_v1_StructuredQuery_FieldFilter_Operator_GREATER_THAN_OR_EQUAL = 4, + google_firestore_v1_StructuredQuery_FieldFilter_Operator_EQUAL = 5, + google_firestore_v1_StructuredQuery_FieldFilter_Operator_ARRAY_CONTAINS = 7 +} google_firestore_v1_StructuredQuery_FieldFilter_Operator; +#define _google_firestore_v1_StructuredQuery_FieldFilter_Operator_MIN google_firestore_v1_StructuredQuery_FieldFilter_Operator_OPERATOR_UNSPECIFIED +#define _google_firestore_v1_StructuredQuery_FieldFilter_Operator_MAX google_firestore_v1_StructuredQuery_FieldFilter_Operator_ARRAY_CONTAINS +#define _google_firestore_v1_StructuredQuery_FieldFilter_Operator_ARRAYSIZE ((google_firestore_v1_StructuredQuery_FieldFilter_Operator)(google_firestore_v1_StructuredQuery_FieldFilter_Operator_ARRAY_CONTAINS+1)) + +typedef enum _google_firestore_v1_StructuredQuery_UnaryFilter_Operator { + google_firestore_v1_StructuredQuery_UnaryFilter_Operator_OPERATOR_UNSPECIFIED = 0, + google_firestore_v1_StructuredQuery_UnaryFilter_Operator_IS_NAN = 2, + google_firestore_v1_StructuredQuery_UnaryFilter_Operator_IS_NULL = 3 +} google_firestore_v1_StructuredQuery_UnaryFilter_Operator; +#define _google_firestore_v1_StructuredQuery_UnaryFilter_Operator_MIN google_firestore_v1_StructuredQuery_UnaryFilter_Operator_OPERATOR_UNSPECIFIED +#define _google_firestore_v1_StructuredQuery_UnaryFilter_Operator_MAX google_firestore_v1_StructuredQuery_UnaryFilter_Operator_IS_NULL +#define _google_firestore_v1_StructuredQuery_UnaryFilter_Operator_ARRAYSIZE ((google_firestore_v1_StructuredQuery_UnaryFilter_Operator)(google_firestore_v1_StructuredQuery_UnaryFilter_Operator_IS_NULL+1)) + +/* Struct definitions */ +typedef struct _google_firestore_v1_StructuredQuery_FieldReference { + pb_bytes_array_t *field_path; +/* @@protoc_insertion_point(struct:google_firestore_v1_StructuredQuery_FieldReference) */ +} google_firestore_v1_StructuredQuery_FieldReference; + +typedef struct _google_firestore_v1_StructuredQuery_Projection { + pb_size_t fields_count; + struct _google_firestore_v1_StructuredQuery_FieldReference *fields; +/* @@protoc_insertion_point(struct:google_firestore_v1_StructuredQuery_Projection) */ +} google_firestore_v1_StructuredQuery_Projection; + +typedef struct _google_firestore_v1_Cursor { + pb_size_t values_count; + struct _google_firestore_v1_Value *values; + bool before; +/* @@protoc_insertion_point(struct:google_firestore_v1_Cursor) */ +} google_firestore_v1_Cursor; + +typedef struct _google_firestore_v1_StructuredQuery_CollectionSelector { + pb_bytes_array_t *collection_id; + bool all_descendants; +/* @@protoc_insertion_point(struct:google_firestore_v1_StructuredQuery_CollectionSelector) */ +} google_firestore_v1_StructuredQuery_CollectionSelector; + +typedef struct _google_firestore_v1_StructuredQuery_CompositeFilter { + google_firestore_v1_StructuredQuery_CompositeFilter_Operator op; + pb_size_t filters_count; + struct _google_firestore_v1_StructuredQuery_Filter *filters; +/* @@protoc_insertion_point(struct:google_firestore_v1_StructuredQuery_CompositeFilter) */ +} google_firestore_v1_StructuredQuery_CompositeFilter; + +typedef struct _google_firestore_v1_StructuredQuery_FieldFilter { + google_firestore_v1_StructuredQuery_FieldReference field; + google_firestore_v1_StructuredQuery_FieldFilter_Operator op; + google_firestore_v1_Value value; +/* @@protoc_insertion_point(struct:google_firestore_v1_StructuredQuery_FieldFilter) */ +} google_firestore_v1_StructuredQuery_FieldFilter; + +typedef struct _google_firestore_v1_StructuredQuery_Order { + google_firestore_v1_StructuredQuery_FieldReference field; + google_firestore_v1_StructuredQuery_Direction direction; +/* @@protoc_insertion_point(struct:google_firestore_v1_StructuredQuery_Order) */ +} google_firestore_v1_StructuredQuery_Order; + +typedef struct _google_firestore_v1_StructuredQuery_UnaryFilter { + google_firestore_v1_StructuredQuery_UnaryFilter_Operator op; + pb_size_t which_operand_type; + union { + google_firestore_v1_StructuredQuery_FieldReference field; + }; +/* @@protoc_insertion_point(struct:google_firestore_v1_StructuredQuery_UnaryFilter) */ +} google_firestore_v1_StructuredQuery_UnaryFilter; + +typedef struct _google_firestore_v1_StructuredQuery_Filter { + pb_size_t which_filter_type; + union { + google_firestore_v1_StructuredQuery_CompositeFilter composite_filter; + google_firestore_v1_StructuredQuery_FieldFilter field_filter; + google_firestore_v1_StructuredQuery_UnaryFilter unary_filter; + }; +/* @@protoc_insertion_point(struct:google_firestore_v1_StructuredQuery_Filter) */ +} google_firestore_v1_StructuredQuery_Filter; + +typedef struct _google_firestore_v1_StructuredQuery { + google_firestore_v1_StructuredQuery_Projection select; + pb_size_t from_count; + struct _google_firestore_v1_StructuredQuery_CollectionSelector *from; + google_firestore_v1_StructuredQuery_Filter where; + pb_size_t order_by_count; + struct _google_firestore_v1_StructuredQuery_Order *order_by; + google_protobuf_Int32Value limit; + int32_t offset; + google_firestore_v1_Cursor start_at; + google_firestore_v1_Cursor end_at; +/* @@protoc_insertion_point(struct:google_firestore_v1_StructuredQuery) */ +} google_firestore_v1_StructuredQuery; + +/* Default values for struct fields */ + +/* Initializer values for message structs */ +#define google_firestore_v1_StructuredQuery_init_default {google_firestore_v1_StructuredQuery_Projection_init_default, 0, NULL, google_firestore_v1_StructuredQuery_Filter_init_default, 0, NULL, google_protobuf_Int32Value_init_default, 0, google_firestore_v1_Cursor_init_default, google_firestore_v1_Cursor_init_default} +#define google_firestore_v1_StructuredQuery_CollectionSelector_init_default {NULL, 0} +#define google_firestore_v1_StructuredQuery_Filter_init_default {0, {google_firestore_v1_StructuredQuery_CompositeFilter_init_default}} +#define google_firestore_v1_StructuredQuery_CompositeFilter_init_default {_google_firestore_v1_StructuredQuery_CompositeFilter_Operator_MIN, 0, NULL} +#define google_firestore_v1_StructuredQuery_FieldFilter_init_default {google_firestore_v1_StructuredQuery_FieldReference_init_default, _google_firestore_v1_StructuredQuery_FieldFilter_Operator_MIN, google_firestore_v1_Value_init_default} +#define google_firestore_v1_StructuredQuery_UnaryFilter_init_default {_google_firestore_v1_StructuredQuery_UnaryFilter_Operator_MIN, 0, {google_firestore_v1_StructuredQuery_FieldReference_init_default}} +#define google_firestore_v1_StructuredQuery_Order_init_default {google_firestore_v1_StructuredQuery_FieldReference_init_default, _google_firestore_v1_StructuredQuery_Direction_MIN} +#define google_firestore_v1_StructuredQuery_FieldReference_init_default {NULL} +#define google_firestore_v1_StructuredQuery_Projection_init_default {0, NULL} +#define google_firestore_v1_Cursor_init_default {0, NULL, 0} +#define google_firestore_v1_StructuredQuery_init_zero {google_firestore_v1_StructuredQuery_Projection_init_zero, 0, NULL, google_firestore_v1_StructuredQuery_Filter_init_zero, 0, NULL, google_protobuf_Int32Value_init_zero, 0, google_firestore_v1_Cursor_init_zero, google_firestore_v1_Cursor_init_zero} +#define google_firestore_v1_StructuredQuery_CollectionSelector_init_zero {NULL, 0} +#define google_firestore_v1_StructuredQuery_Filter_init_zero {0, {google_firestore_v1_StructuredQuery_CompositeFilter_init_zero}} +#define google_firestore_v1_StructuredQuery_CompositeFilter_init_zero {_google_firestore_v1_StructuredQuery_CompositeFilter_Operator_MIN, 0, NULL} +#define google_firestore_v1_StructuredQuery_FieldFilter_init_zero {google_firestore_v1_StructuredQuery_FieldReference_init_zero, _google_firestore_v1_StructuredQuery_FieldFilter_Operator_MIN, google_firestore_v1_Value_init_zero} +#define google_firestore_v1_StructuredQuery_UnaryFilter_init_zero {_google_firestore_v1_StructuredQuery_UnaryFilter_Operator_MIN, 0, {google_firestore_v1_StructuredQuery_FieldReference_init_zero}} +#define google_firestore_v1_StructuredQuery_Order_init_zero {google_firestore_v1_StructuredQuery_FieldReference_init_zero, _google_firestore_v1_StructuredQuery_Direction_MIN} +#define google_firestore_v1_StructuredQuery_FieldReference_init_zero {NULL} +#define google_firestore_v1_StructuredQuery_Projection_init_zero {0, NULL} +#define google_firestore_v1_Cursor_init_zero {0, NULL, 0} + +/* Field tags (for use in manual encoding/decoding) */ +#define google_firestore_v1_StructuredQuery_FieldReference_field_path_tag 2 +#define google_firestore_v1_StructuredQuery_Projection_fields_tag 2 +#define google_firestore_v1_Cursor_values_tag 1 +#define google_firestore_v1_Cursor_before_tag 2 +#define google_firestore_v1_StructuredQuery_CollectionSelector_collection_id_tag 2 +#define google_firestore_v1_StructuredQuery_CollectionSelector_all_descendants_tag 3 +#define google_firestore_v1_StructuredQuery_CompositeFilter_op_tag 1 +#define google_firestore_v1_StructuredQuery_CompositeFilter_filters_tag 2 +#define google_firestore_v1_StructuredQuery_FieldFilter_field_tag 1 +#define google_firestore_v1_StructuredQuery_FieldFilter_op_tag 2 +#define google_firestore_v1_StructuredQuery_FieldFilter_value_tag 3 +#define google_firestore_v1_StructuredQuery_Order_field_tag 1 +#define google_firestore_v1_StructuredQuery_Order_direction_tag 2 +#define google_firestore_v1_StructuredQuery_UnaryFilter_field_tag 2 +#define google_firestore_v1_StructuredQuery_UnaryFilter_op_tag 1 +#define google_firestore_v1_StructuredQuery_Filter_composite_filter_tag 1 +#define google_firestore_v1_StructuredQuery_Filter_field_filter_tag 2 +#define google_firestore_v1_StructuredQuery_Filter_unary_filter_tag 3 +#define google_firestore_v1_StructuredQuery_select_tag 1 +#define google_firestore_v1_StructuredQuery_from_tag 2 +#define google_firestore_v1_StructuredQuery_where_tag 3 +#define google_firestore_v1_StructuredQuery_order_by_tag 4 +#define google_firestore_v1_StructuredQuery_start_at_tag 7 +#define google_firestore_v1_StructuredQuery_end_at_tag 8 +#define google_firestore_v1_StructuredQuery_offset_tag 6 +#define google_firestore_v1_StructuredQuery_limit_tag 5 + +/* Struct field encoding specification for nanopb */ +extern const pb_field_t google_firestore_v1_StructuredQuery_fields[9]; +extern const pb_field_t google_firestore_v1_StructuredQuery_CollectionSelector_fields[3]; +extern const pb_field_t google_firestore_v1_StructuredQuery_Filter_fields[4]; +extern const pb_field_t google_firestore_v1_StructuredQuery_CompositeFilter_fields[3]; +extern const pb_field_t google_firestore_v1_StructuredQuery_FieldFilter_fields[4]; +extern const pb_field_t google_firestore_v1_StructuredQuery_UnaryFilter_fields[3]; +extern const pb_field_t google_firestore_v1_StructuredQuery_Order_fields[3]; +extern const pb_field_t google_firestore_v1_StructuredQuery_FieldReference_fields[2]; +extern const pb_field_t google_firestore_v1_StructuredQuery_Projection_fields[2]; +extern const pb_field_t google_firestore_v1_Cursor_fields[3]; + +/* Maximum encoded size of messages (where known) */ +/* google_firestore_v1_StructuredQuery_size depends on runtime parameters */ +/* google_firestore_v1_StructuredQuery_CollectionSelector_size depends on runtime parameters */ +#define google_firestore_v1_StructuredQuery_Filter_size (0 + (((google_firestore_v1_StructuredQuery_UnaryFilter_size > google_firestore_v1_StructuredQuery_CompositeFilter_size ? google_firestore_v1_StructuredQuery_UnaryFilter_size : google_firestore_v1_StructuredQuery_CompositeFilter_size) > google_firestore_v1_StructuredQuery_FieldFilter_size ? (google_firestore_v1_StructuredQuery_UnaryFilter_size > google_firestore_v1_StructuredQuery_CompositeFilter_size ? google_firestore_v1_StructuredQuery_UnaryFilter_size : google_firestore_v1_StructuredQuery_CompositeFilter_size) : google_firestore_v1_StructuredQuery_FieldFilter_size) > 0 ? ((google_firestore_v1_StructuredQuery_UnaryFilter_size > google_firestore_v1_StructuredQuery_CompositeFilter_size ? google_firestore_v1_StructuredQuery_UnaryFilter_size : google_firestore_v1_StructuredQuery_CompositeFilter_size) > google_firestore_v1_StructuredQuery_FieldFilter_size ? (google_firestore_v1_StructuredQuery_UnaryFilter_size > google_firestore_v1_StructuredQuery_CompositeFilter_size ? google_firestore_v1_StructuredQuery_UnaryFilter_size : google_firestore_v1_StructuredQuery_CompositeFilter_size) : google_firestore_v1_StructuredQuery_FieldFilter_size) : 0)) +/* google_firestore_v1_StructuredQuery_CompositeFilter_size depends on runtime parameters */ +#define google_firestore_v1_StructuredQuery_FieldFilter_size (14 + google_firestore_v1_StructuredQuery_FieldReference_size + google_firestore_v1_Value_size) +#define google_firestore_v1_StructuredQuery_UnaryFilter_size (2 + (google_firestore_v1_StructuredQuery_FieldReference_size > 0 ? google_firestore_v1_StructuredQuery_FieldReference_size : 0)) +#define google_firestore_v1_StructuredQuery_Order_size (8 + google_firestore_v1_StructuredQuery_FieldReference_size) +/* google_firestore_v1_StructuredQuery_FieldReference_size depends on runtime parameters */ +/* google_firestore_v1_StructuredQuery_Projection_size depends on runtime parameters */ +/* google_firestore_v1_Cursor_size depends on runtime parameters */ + +/* Message IDs (where set with "msgid" option) */ +#ifdef PB_MSGID + +#define QUERY_MESSAGES \ + + +#endif + +} // namespace firestore +} // namespace firebase + +/* @@protoc_insertion_point(eof) */ + +#endif diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/google/firestore/v1/write.nanopb.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/google/firestore/v1/write.nanopb.cc new file mode 100644 index 0000000..98cb7da --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/google/firestore/v1/write.nanopb.cc @@ -0,0 +1,120 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +/* Automatically generated nanopb constant definitions */ +/* Generated by nanopb-0.3.9.1 */ + +#include "write.nanopb.h" + +namespace firebase { +namespace firestore { + +/* @@protoc_insertion_point(includes) */ +#if PB_PROTO_HEADER_VERSION != 30 +#error Regenerate this file with the current version of nanopb generator. +#endif + + + +const pb_field_t google_firestore_v1_Write_fields[6] = { + PB_ANONYMOUS_ONEOF_FIELD(operation, 1, MESSAGE , ONEOF, STATIC , FIRST, google_firestore_v1_Write, update, update, &google_firestore_v1_Document_fields), + PB_ANONYMOUS_ONEOF_FIELD(operation, 2, BYTES , ONEOF, POINTER , UNION, google_firestore_v1_Write, delete_, delete_, 0), + PB_ANONYMOUS_ONEOF_FIELD(operation, 6, MESSAGE , ONEOF, STATIC , UNION, google_firestore_v1_Write, transform, transform, &google_firestore_v1_DocumentTransform_fields), + PB_FIELD( 3, MESSAGE , SINGULAR, STATIC , OTHER, google_firestore_v1_Write, update_mask, transform, &google_firestore_v1_DocumentMask_fields), + PB_FIELD( 4, MESSAGE , SINGULAR, STATIC , OTHER, google_firestore_v1_Write, current_document, update_mask, &google_firestore_v1_Precondition_fields), + PB_LAST_FIELD +}; + +const pb_field_t google_firestore_v1_DocumentTransform_fields[3] = { + PB_FIELD( 1, BYTES , SINGULAR, POINTER , FIRST, google_firestore_v1_DocumentTransform, document, document, 0), + PB_FIELD( 2, MESSAGE , REPEATED, POINTER , OTHER, google_firestore_v1_DocumentTransform, field_transforms, document, &google_firestore_v1_DocumentTransform_FieldTransform_fields), + PB_LAST_FIELD +}; + +const pb_field_t google_firestore_v1_DocumentTransform_FieldTransform_fields[8] = { + PB_FIELD( 1, BYTES , SINGULAR, POINTER , FIRST, google_firestore_v1_DocumentTransform_FieldTransform, field_path, field_path, 0), + PB_ANONYMOUS_ONEOF_FIELD(transform_type, 2, ENUM , ONEOF, STATIC , OTHER, google_firestore_v1_DocumentTransform_FieldTransform, set_to_server_value, field_path, 0), + PB_ANONYMOUS_ONEOF_FIELD(transform_type, 3, MESSAGE , ONEOF, STATIC , UNION, google_firestore_v1_DocumentTransform_FieldTransform, increment, field_path, &google_firestore_v1_Value_fields), + PB_ANONYMOUS_ONEOF_FIELD(transform_type, 4, MESSAGE , ONEOF, STATIC , UNION, google_firestore_v1_DocumentTransform_FieldTransform, maximum, field_path, &google_firestore_v1_Value_fields), + PB_ANONYMOUS_ONEOF_FIELD(transform_type, 5, MESSAGE , ONEOF, STATIC , UNION, google_firestore_v1_DocumentTransform_FieldTransform, minimum, field_path, &google_firestore_v1_Value_fields), + PB_ANONYMOUS_ONEOF_FIELD(transform_type, 6, MESSAGE , ONEOF, STATIC , UNION, google_firestore_v1_DocumentTransform_FieldTransform, append_missing_elements, field_path, &google_firestore_v1_ArrayValue_fields), + PB_ANONYMOUS_ONEOF_FIELD(transform_type, 7, MESSAGE , ONEOF, STATIC , UNION, google_firestore_v1_DocumentTransform_FieldTransform, remove_all_from_array, field_path, &google_firestore_v1_ArrayValue_fields), + PB_LAST_FIELD +}; + +const pb_field_t google_firestore_v1_WriteResult_fields[3] = { + PB_FIELD( 1, MESSAGE , SINGULAR, STATIC , FIRST, google_firestore_v1_WriteResult, update_time, update_time, &google_protobuf_Timestamp_fields), + PB_FIELD( 2, MESSAGE , REPEATED, POINTER , OTHER, google_firestore_v1_WriteResult, transform_results, update_time, &google_firestore_v1_Value_fields), + PB_LAST_FIELD +}; + +const pb_field_t google_firestore_v1_DocumentChange_fields[4] = { + PB_FIELD( 1, MESSAGE , SINGULAR, STATIC , FIRST, google_firestore_v1_DocumentChange, document, document, &google_firestore_v1_Document_fields), + PB_FIELD( 5, INT32 , REPEATED, POINTER , OTHER, google_firestore_v1_DocumentChange, target_ids, document, 0), + PB_FIELD( 6, INT32 , REPEATED, POINTER , OTHER, google_firestore_v1_DocumentChange, removed_target_ids, target_ids, 0), + PB_LAST_FIELD +}; + +const pb_field_t google_firestore_v1_DocumentDelete_fields[4] = { + PB_FIELD( 1, BYTES , SINGULAR, POINTER , FIRST, google_firestore_v1_DocumentDelete, document, document, 0), + PB_FIELD( 4, MESSAGE , SINGULAR, STATIC , OTHER, google_firestore_v1_DocumentDelete, read_time, document, &google_protobuf_Timestamp_fields), + PB_FIELD( 6, INT32 , REPEATED, POINTER , OTHER, google_firestore_v1_DocumentDelete, removed_target_ids, read_time, 0), + PB_LAST_FIELD +}; + +const pb_field_t google_firestore_v1_DocumentRemove_fields[4] = { + PB_FIELD( 1, BYTES , SINGULAR, POINTER , FIRST, google_firestore_v1_DocumentRemove, document, document, 0), + PB_FIELD( 2, INT32 , REPEATED, POINTER , OTHER, google_firestore_v1_DocumentRemove, removed_target_ids, document, 0), + PB_FIELD( 4, MESSAGE , SINGULAR, STATIC , OTHER, google_firestore_v1_DocumentRemove, read_time, removed_target_ids, &google_protobuf_Timestamp_fields), + PB_LAST_FIELD +}; + +const pb_field_t google_firestore_v1_ExistenceFilter_fields[3] = { + PB_FIELD( 1, INT32 , SINGULAR, STATIC , FIRST, google_firestore_v1_ExistenceFilter, target_id, target_id, 0), + PB_FIELD( 2, INT32 , SINGULAR, STATIC , OTHER, google_firestore_v1_ExistenceFilter, count, target_id, 0), + PB_LAST_FIELD +}; + + + +/* Check that field information fits in pb_field_t */ +#if !defined(PB_FIELD_32BIT) +/* If you get an error here, it means that you need to define PB_FIELD_32BIT + * compile-time option. You can do that in pb.h or on compiler command line. + * + * The reason you need to do this is that some of your messages contain tag + * numbers or field sizes that are larger than what can fit in 8 or 16 bit + * field descriptors. + */ +PB_STATIC_ASSERT((pb_membersize(google_firestore_v1_Write, update) < 65536 && pb_membersize(google_firestore_v1_Write, transform) < 65536 && pb_membersize(google_firestore_v1_Write, update_mask) < 65536 && pb_membersize(google_firestore_v1_Write, current_document) < 65536 && pb_membersize(google_firestore_v1_DocumentTransform_FieldTransform, increment) < 65536 && pb_membersize(google_firestore_v1_DocumentTransform_FieldTransform, maximum) < 65536 && pb_membersize(google_firestore_v1_DocumentTransform_FieldTransform, minimum) < 65536 && pb_membersize(google_firestore_v1_DocumentTransform_FieldTransform, append_missing_elements) < 65536 && pb_membersize(google_firestore_v1_DocumentTransform_FieldTransform, remove_all_from_array) < 65536 && pb_membersize(google_firestore_v1_WriteResult, update_time) < 65536 && pb_membersize(google_firestore_v1_DocumentChange, document) < 65536 && pb_membersize(google_firestore_v1_DocumentDelete, read_time) < 65536 && pb_membersize(google_firestore_v1_DocumentRemove, read_time) < 65536), YOU_MUST_DEFINE_PB_FIELD_32BIT_FOR_MESSAGES_google_firestore_v1_Write_google_firestore_v1_DocumentTransform_google_firestore_v1_DocumentTransform_FieldTransform_google_firestore_v1_WriteResult_google_firestore_v1_DocumentChange_google_firestore_v1_DocumentDelete_google_firestore_v1_DocumentRemove_google_firestore_v1_ExistenceFilter) +#endif + +#if !defined(PB_FIELD_16BIT) && !defined(PB_FIELD_32BIT) +/* If you get an error here, it means that you need to define PB_FIELD_16BIT + * compile-time option. You can do that in pb.h or on compiler command line. + * + * The reason you need to do this is that some of your messages contain tag + * numbers or field sizes that are larger than what can fit in the default + * 8 bit descriptors. + */ +PB_STATIC_ASSERT((pb_membersize(google_firestore_v1_Write, update) < 256 && pb_membersize(google_firestore_v1_Write, transform) < 256 && pb_membersize(google_firestore_v1_Write, update_mask) < 256 && pb_membersize(google_firestore_v1_Write, current_document) < 256 && pb_membersize(google_firestore_v1_DocumentTransform_FieldTransform, increment) < 256 && pb_membersize(google_firestore_v1_DocumentTransform_FieldTransform, maximum) < 256 && pb_membersize(google_firestore_v1_DocumentTransform_FieldTransform, minimum) < 256 && pb_membersize(google_firestore_v1_DocumentTransform_FieldTransform, append_missing_elements) < 256 && pb_membersize(google_firestore_v1_DocumentTransform_FieldTransform, remove_all_from_array) < 256 && pb_membersize(google_firestore_v1_WriteResult, update_time) < 256 && pb_membersize(google_firestore_v1_DocumentChange, document) < 256 && pb_membersize(google_firestore_v1_DocumentDelete, read_time) < 256 && pb_membersize(google_firestore_v1_DocumentRemove, read_time) < 256), YOU_MUST_DEFINE_PB_FIELD_16BIT_FOR_MESSAGES_google_firestore_v1_Write_google_firestore_v1_DocumentTransform_google_firestore_v1_DocumentTransform_FieldTransform_google_firestore_v1_WriteResult_google_firestore_v1_DocumentChange_google_firestore_v1_DocumentDelete_google_firestore_v1_DocumentRemove_google_firestore_v1_ExistenceFilter) +#endif + + +} // namespace firestore +} // namespace firebase + +/* @@protoc_insertion_point(eof) */ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/google/firestore/v1/write.nanopb.h b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/google/firestore/v1/write.nanopb.h new file mode 100644 index 0000000..fb9c54e --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/google/firestore/v1/write.nanopb.h @@ -0,0 +1,204 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +/* Automatically generated nanopb header */ +/* Generated by nanopb-0.3.9.1 */ + +#ifndef PB_GOOGLE_FIRESTORE_V1_WRITE_NANOPB_H_INCLUDED +#define PB_GOOGLE_FIRESTORE_V1_WRITE_NANOPB_H_INCLUDED +#include + +#include "google/api/annotations.nanopb.h" + +#include "google/firestore/v1/common.nanopb.h" + +#include "google/firestore/v1/document.nanopb.h" + +#include "google/protobuf/timestamp.nanopb.h" + +namespace firebase { +namespace firestore { + +/* @@protoc_insertion_point(includes) */ +#if PB_PROTO_HEADER_VERSION != 30 +#error Regenerate this file with the current version of nanopb generator. +#endif + + +/* Enum definitions */ +typedef enum _google_firestore_v1_DocumentTransform_FieldTransform_ServerValue { + google_firestore_v1_DocumentTransform_FieldTransform_ServerValue_SERVER_VALUE_UNSPECIFIED = 0, + google_firestore_v1_DocumentTransform_FieldTransform_ServerValue_REQUEST_TIME = 1 +} google_firestore_v1_DocumentTransform_FieldTransform_ServerValue; +#define _google_firestore_v1_DocumentTransform_FieldTransform_ServerValue_MIN google_firestore_v1_DocumentTransform_FieldTransform_ServerValue_SERVER_VALUE_UNSPECIFIED +#define _google_firestore_v1_DocumentTransform_FieldTransform_ServerValue_MAX google_firestore_v1_DocumentTransform_FieldTransform_ServerValue_REQUEST_TIME +#define _google_firestore_v1_DocumentTransform_FieldTransform_ServerValue_ARRAYSIZE ((google_firestore_v1_DocumentTransform_FieldTransform_ServerValue)(google_firestore_v1_DocumentTransform_FieldTransform_ServerValue_REQUEST_TIME+1)) + +/* Struct definitions */ +typedef struct _google_firestore_v1_DocumentTransform { + pb_bytes_array_t *document; + pb_size_t field_transforms_count; + struct _google_firestore_v1_DocumentTransform_FieldTransform *field_transforms; +/* @@protoc_insertion_point(struct:google_firestore_v1_DocumentTransform) */ +} google_firestore_v1_DocumentTransform; + +typedef struct _google_firestore_v1_DocumentChange { + google_firestore_v1_Document document; + pb_size_t target_ids_count; + int32_t *target_ids; + pb_size_t removed_target_ids_count; + int32_t *removed_target_ids; +/* @@protoc_insertion_point(struct:google_firestore_v1_DocumentChange) */ +} google_firestore_v1_DocumentChange; + +typedef struct _google_firestore_v1_DocumentDelete { + pb_bytes_array_t *document; + google_protobuf_Timestamp read_time; + pb_size_t removed_target_ids_count; + int32_t *removed_target_ids; +/* @@protoc_insertion_point(struct:google_firestore_v1_DocumentDelete) */ +} google_firestore_v1_DocumentDelete; + +typedef struct _google_firestore_v1_DocumentRemove { + pb_bytes_array_t *document; + pb_size_t removed_target_ids_count; + int32_t *removed_target_ids; + google_protobuf_Timestamp read_time; +/* @@protoc_insertion_point(struct:google_firestore_v1_DocumentRemove) */ +} google_firestore_v1_DocumentRemove; + +typedef struct _google_firestore_v1_DocumentTransform_FieldTransform { + pb_bytes_array_t *field_path; + pb_size_t which_transform_type; + union { + google_firestore_v1_DocumentTransform_FieldTransform_ServerValue set_to_server_value; + google_firestore_v1_Value increment; + google_firestore_v1_Value maximum; + google_firestore_v1_Value minimum; + google_firestore_v1_ArrayValue append_missing_elements; + google_firestore_v1_ArrayValue remove_all_from_array; + }; +/* @@protoc_insertion_point(struct:google_firestore_v1_DocumentTransform_FieldTransform) */ +} google_firestore_v1_DocumentTransform_FieldTransform; + +typedef struct _google_firestore_v1_ExistenceFilter { + int32_t target_id; + int32_t count; +/* @@protoc_insertion_point(struct:google_firestore_v1_ExistenceFilter) */ +} google_firestore_v1_ExistenceFilter; + +typedef struct _google_firestore_v1_Write { + pb_size_t which_operation; + union { + google_firestore_v1_Document update; + pb_bytes_array_t *delete_; + google_firestore_v1_DocumentTransform transform; + }; + google_firestore_v1_DocumentMask update_mask; + google_firestore_v1_Precondition current_document; +/* @@protoc_insertion_point(struct:google_firestore_v1_Write) */ +} google_firestore_v1_Write; + +typedef struct _google_firestore_v1_WriteResult { + google_protobuf_Timestamp update_time; + pb_size_t transform_results_count; + struct _google_firestore_v1_Value *transform_results; +/* @@protoc_insertion_point(struct:google_firestore_v1_WriteResult) */ +} google_firestore_v1_WriteResult; + +/* Default values for struct fields */ + +/* Initializer values for message structs */ +#define google_firestore_v1_Write_init_default {0, {google_firestore_v1_Document_init_default}, google_firestore_v1_DocumentMask_init_default, google_firestore_v1_Precondition_init_default} +#define google_firestore_v1_DocumentTransform_init_default {NULL, 0, NULL} +#define google_firestore_v1_DocumentTransform_FieldTransform_init_default {NULL, 0, {_google_firestore_v1_DocumentTransform_FieldTransform_ServerValue_MIN}} +#define google_firestore_v1_WriteResult_init_default {google_protobuf_Timestamp_init_default, 0, NULL} +#define google_firestore_v1_DocumentChange_init_default {google_firestore_v1_Document_init_default, 0, NULL, 0, NULL} +#define google_firestore_v1_DocumentDelete_init_default {NULL, google_protobuf_Timestamp_init_default, 0, NULL} +#define google_firestore_v1_DocumentRemove_init_default {NULL, 0, NULL, google_protobuf_Timestamp_init_default} +#define google_firestore_v1_ExistenceFilter_init_default {0, 0} +#define google_firestore_v1_Write_init_zero {0, {google_firestore_v1_Document_init_zero}, google_firestore_v1_DocumentMask_init_zero, google_firestore_v1_Precondition_init_zero} +#define google_firestore_v1_DocumentTransform_init_zero {NULL, 0, NULL} +#define google_firestore_v1_DocumentTransform_FieldTransform_init_zero {NULL, 0, {_google_firestore_v1_DocumentTransform_FieldTransform_ServerValue_MIN}} +#define google_firestore_v1_WriteResult_init_zero {google_protobuf_Timestamp_init_zero, 0, NULL} +#define google_firestore_v1_DocumentChange_init_zero {google_firestore_v1_Document_init_zero, 0, NULL, 0, NULL} +#define google_firestore_v1_DocumentDelete_init_zero {NULL, google_protobuf_Timestamp_init_zero, 0, NULL} +#define google_firestore_v1_DocumentRemove_init_zero {NULL, 0, NULL, google_protobuf_Timestamp_init_zero} +#define google_firestore_v1_ExistenceFilter_init_zero {0, 0} + +/* Field tags (for use in manual encoding/decoding) */ +#define google_firestore_v1_DocumentTransform_document_tag 1 +#define google_firestore_v1_DocumentTransform_field_transforms_tag 2 +#define google_firestore_v1_DocumentChange_document_tag 1 +#define google_firestore_v1_DocumentChange_target_ids_tag 5 +#define google_firestore_v1_DocumentChange_removed_target_ids_tag 6 +#define google_firestore_v1_DocumentDelete_document_tag 1 +#define google_firestore_v1_DocumentDelete_removed_target_ids_tag 6 +#define google_firestore_v1_DocumentDelete_read_time_tag 4 +#define google_firestore_v1_DocumentRemove_document_tag 1 +#define google_firestore_v1_DocumentRemove_removed_target_ids_tag 2 +#define google_firestore_v1_DocumentRemove_read_time_tag 4 +#define google_firestore_v1_DocumentTransform_FieldTransform_set_to_server_value_tag 2 +#define google_firestore_v1_DocumentTransform_FieldTransform_increment_tag 3 +#define google_firestore_v1_DocumentTransform_FieldTransform_maximum_tag 4 +#define google_firestore_v1_DocumentTransform_FieldTransform_minimum_tag 5 +#define google_firestore_v1_DocumentTransform_FieldTransform_append_missing_elements_tag 6 +#define google_firestore_v1_DocumentTransform_FieldTransform_remove_all_from_array_tag 7 +#define google_firestore_v1_DocumentTransform_FieldTransform_field_path_tag 1 +#define google_firestore_v1_ExistenceFilter_target_id_tag 1 +#define google_firestore_v1_ExistenceFilter_count_tag 2 +#define google_firestore_v1_Write_update_tag 1 +#define google_firestore_v1_Write_delete_tag 2 +#define google_firestore_v1_Write_transform_tag 6 +#define google_firestore_v1_Write_update_mask_tag 3 +#define google_firestore_v1_Write_current_document_tag 4 +#define google_firestore_v1_WriteResult_update_time_tag 1 +#define google_firestore_v1_WriteResult_transform_results_tag 2 + +/* Struct field encoding specification for nanopb */ +extern const pb_field_t google_firestore_v1_Write_fields[6]; +extern const pb_field_t google_firestore_v1_DocumentTransform_fields[3]; +extern const pb_field_t google_firestore_v1_DocumentTransform_FieldTransform_fields[8]; +extern const pb_field_t google_firestore_v1_WriteResult_fields[3]; +extern const pb_field_t google_firestore_v1_DocumentChange_fields[4]; +extern const pb_field_t google_firestore_v1_DocumentDelete_fields[4]; +extern const pb_field_t google_firestore_v1_DocumentRemove_fields[4]; +extern const pb_field_t google_firestore_v1_ExistenceFilter_fields[3]; + +/* Maximum encoded size of messages (where known) */ +/* google_firestore_v1_Write_size depends on runtime parameters */ +/* google_firestore_v1_DocumentTransform_size depends on runtime parameters */ +/* google_firestore_v1_DocumentTransform_FieldTransform_size depends on runtime parameters */ +/* google_firestore_v1_WriteResult_size depends on runtime parameters */ +/* google_firestore_v1_DocumentChange_size depends on runtime parameters */ +/* google_firestore_v1_DocumentDelete_size depends on runtime parameters */ +/* google_firestore_v1_DocumentRemove_size depends on runtime parameters */ +#define google_firestore_v1_ExistenceFilter_size 22 + +/* Message IDs (where set with "msgid" option) */ +#ifdef PB_MSGID + +#define WRITE_MESSAGES \ + + +#endif + +} // namespace firestore +} // namespace firebase + +/* @@protoc_insertion_point(eof) */ + +#endif diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/google/protobuf/any.nanopb.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/google/protobuf/any.nanopb.cc new file mode 100644 index 0000000..f88662d --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/google/protobuf/any.nanopb.cc @@ -0,0 +1,42 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +/* Automatically generated nanopb constant definitions */ +/* Generated by nanopb-0.3.9.1 */ + +#include "any.nanopb.h" + +namespace firebase { +namespace firestore { + +/* @@protoc_insertion_point(includes) */ +#if PB_PROTO_HEADER_VERSION != 30 +#error Regenerate this file with the current version of nanopb generator. +#endif + + + +const pb_field_t google_protobuf_Any_fields[3] = { + PB_FIELD( 1, BYTES , SINGULAR, POINTER , FIRST, google_protobuf_Any, type_url, type_url, 0), + PB_FIELD( 2, BYTES , SINGULAR, POINTER , OTHER, google_protobuf_Any, value, type_url, 0), + PB_LAST_FIELD +}; + + +} // namespace firestore +} // namespace firebase + +/* @@protoc_insertion_point(eof) */ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/google/protobuf/any.nanopb.h b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/google/protobuf/any.nanopb.h new file mode 100644 index 0000000..a9ca0c1 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/google/protobuf/any.nanopb.h @@ -0,0 +1,69 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +/* Automatically generated nanopb header */ +/* Generated by nanopb-0.3.9.1 */ + +#ifndef PB_GOOGLE_PROTOBUF_ANY_NANOPB_H_INCLUDED +#define PB_GOOGLE_PROTOBUF_ANY_NANOPB_H_INCLUDED +#include + +namespace firebase { +namespace firestore { + +/* @@protoc_insertion_point(includes) */ +#if PB_PROTO_HEADER_VERSION != 30 +#error Regenerate this file with the current version of nanopb generator. +#endif + + +/* Struct definitions */ +typedef struct _google_protobuf_Any { + pb_bytes_array_t *type_url; + pb_bytes_array_t *value; +/* @@protoc_insertion_point(struct:google_protobuf_Any) */ +} google_protobuf_Any; + +/* Default values for struct fields */ + +/* Initializer values for message structs */ +#define google_protobuf_Any_init_default {NULL, NULL} +#define google_protobuf_Any_init_zero {NULL, NULL} + +/* Field tags (for use in manual encoding/decoding) */ +#define google_protobuf_Any_type_url_tag 1 +#define google_protobuf_Any_value_tag 2 + +/* Struct field encoding specification for nanopb */ +extern const pb_field_t google_protobuf_Any_fields[3]; + +/* Maximum encoded size of messages (where known) */ +/* google_protobuf_Any_size depends on runtime parameters */ + +/* Message IDs (where set with "msgid" option) */ +#ifdef PB_MSGID + +#define ANY_MESSAGES \ + + +#endif + +} // namespace firestore +} // namespace firebase + +/* @@protoc_insertion_point(eof) */ + +#endif diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/google/protobuf/empty.nanopb.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/google/protobuf/empty.nanopb.cc new file mode 100644 index 0000000..adce8fc --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/google/protobuf/empty.nanopb.cc @@ -0,0 +1,40 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +/* Automatically generated nanopb constant definitions */ +/* Generated by nanopb-0.3.9.1 */ + +#include "empty.nanopb.h" + +namespace firebase { +namespace firestore { + +/* @@protoc_insertion_point(includes) */ +#if PB_PROTO_HEADER_VERSION != 30 +#error Regenerate this file with the current version of nanopb generator. +#endif + + + +const pb_field_t google_protobuf_Empty_fields[1] = { + PB_LAST_FIELD +}; + + +} // namespace firestore +} // namespace firebase + +/* @@protoc_insertion_point(eof) */ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/google/protobuf/empty.nanopb.h b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/google/protobuf/empty.nanopb.h new file mode 100644 index 0000000..59070a0 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/google/protobuf/empty.nanopb.h @@ -0,0 +1,66 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +/* Automatically generated nanopb header */ +/* Generated by nanopb-0.3.9.1 */ + +#ifndef PB_GOOGLE_PROTOBUF_EMPTY_NANOPB_H_INCLUDED +#define PB_GOOGLE_PROTOBUF_EMPTY_NANOPB_H_INCLUDED +#include + +namespace firebase { +namespace firestore { + +/* @@protoc_insertion_point(includes) */ +#if PB_PROTO_HEADER_VERSION != 30 +#error Regenerate this file with the current version of nanopb generator. +#endif + + +/* Struct definitions */ +typedef struct _google_protobuf_Empty { + char dummy_field; +/* @@protoc_insertion_point(struct:google_protobuf_Empty) */ +} google_protobuf_Empty; + +/* Default values for struct fields */ + +/* Initializer values for message structs */ +#define google_protobuf_Empty_init_default {0} +#define google_protobuf_Empty_init_zero {0} + +/* Field tags (for use in manual encoding/decoding) */ + +/* Struct field encoding specification for nanopb */ +extern const pb_field_t google_protobuf_Empty_fields[1]; + +/* Maximum encoded size of messages (where known) */ +#define google_protobuf_Empty_size 0 + +/* Message IDs (where set with "msgid" option) */ +#ifdef PB_MSGID + +#define EMPTY_MESSAGES \ + + +#endif + +} // namespace firestore +} // namespace firebase + +/* @@protoc_insertion_point(eof) */ + +#endif diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/google/protobuf/struct.nanopb.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/google/protobuf/struct.nanopb.cc new file mode 100644 index 0000000..37644b1 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/google/protobuf/struct.nanopb.cc @@ -0,0 +1,87 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +/* Automatically generated nanopb constant definitions */ +/* Generated by nanopb-0.3.9.1 */ + +#include "struct.nanopb.h" + +namespace firebase { +namespace firestore { + +/* @@protoc_insertion_point(includes) */ +#if PB_PROTO_HEADER_VERSION != 30 +#error Regenerate this file with the current version of nanopb generator. +#endif + + + +const pb_field_t google_protobuf_Struct_fields[2] = { + PB_FIELD( 1, MESSAGE , REPEATED, POINTER , FIRST, google_protobuf_Struct, fields, fields, &google_protobuf_Struct_FieldsEntry_fields), + PB_LAST_FIELD +}; + +const pb_field_t google_protobuf_Struct_FieldsEntry_fields[3] = { + PB_FIELD( 1, BYTES , SINGULAR, POINTER , FIRST, google_protobuf_Struct_FieldsEntry, key, key, 0), + PB_FIELD( 2, MESSAGE , SINGULAR, STATIC , OTHER, google_protobuf_Struct_FieldsEntry, value, key, &google_protobuf_Value_fields), + PB_LAST_FIELD +}; + +const pb_field_t google_protobuf_Value_fields[7] = { + PB_ANONYMOUS_ONEOF_FIELD(kind, 1, ENUM , ONEOF, STATIC , FIRST, google_protobuf_Value, null_value, null_value, 0), + PB_ANONYMOUS_ONEOF_FIELD(kind, 2, DOUBLE , ONEOF, STATIC , UNION, google_protobuf_Value, number_value, number_value, 0), + PB_ANONYMOUS_ONEOF_FIELD(kind, 3, BYTES , ONEOF, POINTER , UNION, google_protobuf_Value, string_value, string_value, 0), + PB_ANONYMOUS_ONEOF_FIELD(kind, 4, BOOL , ONEOF, STATIC , UNION, google_protobuf_Value, bool_value, bool_value, 0), + PB_ANONYMOUS_ONEOF_FIELD(kind, 5, MESSAGE , ONEOF, STATIC , UNION, google_protobuf_Value, struct_value, struct_value, &google_protobuf_Struct_fields), + PB_ANONYMOUS_ONEOF_FIELD(kind, 6, MESSAGE , ONEOF, STATIC , UNION, google_protobuf_Value, list_value, list_value, &google_protobuf_ListValue_fields), + PB_LAST_FIELD +}; + +const pb_field_t google_protobuf_ListValue_fields[2] = { + PB_FIELD( 1, MESSAGE , REPEATED, POINTER , FIRST, google_protobuf_ListValue, values, values, &google_protobuf_Value_fields), + PB_LAST_FIELD +}; + + + +/* Check that field information fits in pb_field_t */ +#if !defined(PB_FIELD_32BIT) +/* If you get an error here, it means that you need to define PB_FIELD_32BIT + * compile-time option. You can do that in pb.h or on compiler command line. + * + * The reason you need to do this is that some of your messages contain tag + * numbers or field sizes that are larger than what can fit in 8 or 16 bit + * field descriptors. + */ +PB_STATIC_ASSERT((pb_membersize(google_protobuf_Struct_FieldsEntry, value) < 65536 && pb_membersize(google_protobuf_Value, struct_value) < 65536 && pb_membersize(google_protobuf_Value, list_value) < 65536), YOU_MUST_DEFINE_PB_FIELD_32BIT_FOR_MESSAGES_google_protobuf_Struct_google_protobuf_Struct_FieldsEntry_google_protobuf_Value_google_protobuf_ListValue) +#endif + +#if !defined(PB_FIELD_16BIT) && !defined(PB_FIELD_32BIT) +/* If you get an error here, it means that you need to define PB_FIELD_16BIT + * compile-time option. You can do that in pb.h or on compiler command line. + * + * The reason you need to do this is that some of your messages contain tag + * numbers or field sizes that are larger than what can fit in the default + * 8 bit descriptors. + */ +PB_STATIC_ASSERT((pb_membersize(google_protobuf_Struct_FieldsEntry, value) < 256 && pb_membersize(google_protobuf_Value, struct_value) < 256 && pb_membersize(google_protobuf_Value, list_value) < 256), YOU_MUST_DEFINE_PB_FIELD_16BIT_FOR_MESSAGES_google_protobuf_Struct_google_protobuf_Struct_FieldsEntry_google_protobuf_Value_google_protobuf_ListValue) +#endif + + +} // namespace firestore +} // namespace firebase + +/* @@protoc_insertion_point(eof) */ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/google/protobuf/struct.nanopb.h b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/google/protobuf/struct.nanopb.h new file mode 100644 index 0000000..a71439e --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/google/protobuf/struct.nanopb.h @@ -0,0 +1,122 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +/* Automatically generated nanopb header */ +/* Generated by nanopb-0.3.9.1 */ + +#ifndef PB_GOOGLE_PROTOBUF_STRUCT_NANOPB_H_INCLUDED +#define PB_GOOGLE_PROTOBUF_STRUCT_NANOPB_H_INCLUDED +#include + +namespace firebase { +namespace firestore { + +/* @@protoc_insertion_point(includes) */ +#if PB_PROTO_HEADER_VERSION != 30 +#error Regenerate this file with the current version of nanopb generator. +#endif + + +/* Enum definitions */ +typedef enum _google_protobuf_NullValue { + google_protobuf_NullValue_NULL_VALUE = 0 +} google_protobuf_NullValue; +#define _google_protobuf_NullValue_MIN google_protobuf_NullValue_NULL_VALUE +#define _google_protobuf_NullValue_MAX google_protobuf_NullValue_NULL_VALUE +#define _google_protobuf_NullValue_ARRAYSIZE ((google_protobuf_NullValue)(google_protobuf_NullValue_NULL_VALUE+1)) + +/* Struct definitions */ +typedef struct _google_protobuf_ListValue { + pb_size_t values_count; + struct _google_protobuf_Value *values; +/* @@protoc_insertion_point(struct:google_protobuf_ListValue) */ +} google_protobuf_ListValue; + +typedef struct _google_protobuf_Struct { + pb_size_t fields_count; + struct _google_protobuf_Struct_FieldsEntry *fields; +/* @@protoc_insertion_point(struct:google_protobuf_Struct) */ +} google_protobuf_Struct; + +typedef struct _google_protobuf_Value { + pb_size_t which_kind; + union { + google_protobuf_NullValue null_value; + double number_value; + pb_bytes_array_t *string_value; + bool bool_value; + google_protobuf_Struct struct_value; + google_protobuf_ListValue list_value; + }; +/* @@protoc_insertion_point(struct:google_protobuf_Value) */ +} google_protobuf_Value; + +typedef struct _google_protobuf_Struct_FieldsEntry { + pb_bytes_array_t *key; + google_protobuf_Value value; +/* @@protoc_insertion_point(struct:google_protobuf_Struct_FieldsEntry) */ +} google_protobuf_Struct_FieldsEntry; + +/* Default values for struct fields */ + +/* Initializer values for message structs */ +#define google_protobuf_Struct_init_default {0, NULL} +#define google_protobuf_Struct_FieldsEntry_init_default {NULL, google_protobuf_Value_init_default} +#define google_protobuf_Value_init_default {0, {_google_protobuf_NullValue_MIN}} +#define google_protobuf_ListValue_init_default {0, NULL} +#define google_protobuf_Struct_init_zero {0, NULL} +#define google_protobuf_Struct_FieldsEntry_init_zero {NULL, google_protobuf_Value_init_zero} +#define google_protobuf_Value_init_zero {0, {_google_protobuf_NullValue_MIN}} +#define google_protobuf_ListValue_init_zero {0, NULL} + +/* Field tags (for use in manual encoding/decoding) */ +#define google_protobuf_ListValue_values_tag 1 +#define google_protobuf_Struct_fields_tag 1 +#define google_protobuf_Value_null_value_tag 1 +#define google_protobuf_Value_number_value_tag 2 +#define google_protobuf_Value_string_value_tag 3 +#define google_protobuf_Value_bool_value_tag 4 +#define google_protobuf_Value_struct_value_tag 5 +#define google_protobuf_Value_list_value_tag 6 +#define google_protobuf_Struct_FieldsEntry_key_tag 1 +#define google_protobuf_Struct_FieldsEntry_value_tag 2 + +/* Struct field encoding specification for nanopb */ +extern const pb_field_t google_protobuf_Struct_fields[2]; +extern const pb_field_t google_protobuf_Struct_FieldsEntry_fields[3]; +extern const pb_field_t google_protobuf_Value_fields[7]; +extern const pb_field_t google_protobuf_ListValue_fields[2]; + +/* Maximum encoded size of messages (where known) */ +/* google_protobuf_Struct_size depends on runtime parameters */ +/* google_protobuf_Struct_FieldsEntry_size depends on runtime parameters */ +/* google_protobuf_Value_size depends on runtime parameters */ +/* google_protobuf_ListValue_size depends on runtime parameters */ + +/* Message IDs (where set with "msgid" option) */ +#ifdef PB_MSGID + +#define STRUCT_MESSAGES \ + + +#endif + +} // namespace firestore +} // namespace firebase + +/* @@protoc_insertion_point(eof) */ + +#endif diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/google/protobuf/timestamp.nanopb.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/google/protobuf/timestamp.nanopb.cc new file mode 100644 index 0000000..9814b20 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/google/protobuf/timestamp.nanopb.cc @@ -0,0 +1,42 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +/* Automatically generated nanopb constant definitions */ +/* Generated by nanopb-0.3.9.1 */ + +#include "timestamp.nanopb.h" + +namespace firebase { +namespace firestore { + +/* @@protoc_insertion_point(includes) */ +#if PB_PROTO_HEADER_VERSION != 30 +#error Regenerate this file with the current version of nanopb generator. +#endif + + + +const pb_field_t google_protobuf_Timestamp_fields[3] = { + PB_FIELD( 1, INT64 , SINGULAR, STATIC , FIRST, google_protobuf_Timestamp, seconds, seconds, 0), + PB_FIELD( 2, INT32 , SINGULAR, STATIC , OTHER, google_protobuf_Timestamp, nanos, seconds, 0), + PB_LAST_FIELD +}; + + +} // namespace firestore +} // namespace firebase + +/* @@protoc_insertion_point(eof) */ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/google/protobuf/timestamp.nanopb.h b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/google/protobuf/timestamp.nanopb.h new file mode 100644 index 0000000..57ac091 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/google/protobuf/timestamp.nanopb.h @@ -0,0 +1,69 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +/* Automatically generated nanopb header */ +/* Generated by nanopb-0.3.9.1 */ + +#ifndef PB_GOOGLE_PROTOBUF_TIMESTAMP_NANOPB_H_INCLUDED +#define PB_GOOGLE_PROTOBUF_TIMESTAMP_NANOPB_H_INCLUDED +#include + +namespace firebase { +namespace firestore { + +/* @@protoc_insertion_point(includes) */ +#if PB_PROTO_HEADER_VERSION != 30 +#error Regenerate this file with the current version of nanopb generator. +#endif + + +/* Struct definitions */ +typedef struct _google_protobuf_Timestamp { + int64_t seconds; + int32_t nanos; +/* @@protoc_insertion_point(struct:google_protobuf_Timestamp) */ +} google_protobuf_Timestamp; + +/* Default values for struct fields */ + +/* Initializer values for message structs */ +#define google_protobuf_Timestamp_init_default {0, 0} +#define google_protobuf_Timestamp_init_zero {0, 0} + +/* Field tags (for use in manual encoding/decoding) */ +#define google_protobuf_Timestamp_seconds_tag 1 +#define google_protobuf_Timestamp_nanos_tag 2 + +/* Struct field encoding specification for nanopb */ +extern const pb_field_t google_protobuf_Timestamp_fields[3]; + +/* Maximum encoded size of messages (where known) */ +#define google_protobuf_Timestamp_size 22 + +/* Message IDs (where set with "msgid" option) */ +#ifdef PB_MSGID + +#define TIMESTAMP_MESSAGES \ + + +#endif + +} // namespace firestore +} // namespace firebase + +/* @@protoc_insertion_point(eof) */ + +#endif diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/google/protobuf/wrappers.nanopb.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/google/protobuf/wrappers.nanopb.cc new file mode 100644 index 0000000..915459a --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/google/protobuf/wrappers.nanopb.cc @@ -0,0 +1,87 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +/* Automatically generated nanopb constant definitions */ +/* Generated by nanopb-0.3.9.1 */ + +#include "wrappers.nanopb.h" + +namespace firebase { +namespace firestore { + +/* @@protoc_insertion_point(includes) */ +#if PB_PROTO_HEADER_VERSION != 30 +#error Regenerate this file with the current version of nanopb generator. +#endif + + + +const pb_field_t google_protobuf_DoubleValue_fields[2] = { + PB_FIELD( 1, DOUBLE , SINGULAR, STATIC , FIRST, google_protobuf_DoubleValue, value, value, 0), + PB_LAST_FIELD +}; + +const pb_field_t google_protobuf_FloatValue_fields[2] = { + PB_FIELD( 1, FLOAT , SINGULAR, STATIC , FIRST, google_protobuf_FloatValue, value, value, 0), + PB_LAST_FIELD +}; + +const pb_field_t google_protobuf_Int64Value_fields[2] = { + PB_FIELD( 1, INT64 , SINGULAR, STATIC , FIRST, google_protobuf_Int64Value, value, value, 0), + PB_LAST_FIELD +}; + +const pb_field_t google_protobuf_UInt64Value_fields[2] = { + PB_FIELD( 1, UINT64 , SINGULAR, STATIC , FIRST, google_protobuf_UInt64Value, value, value, 0), + PB_LAST_FIELD +}; + +const pb_field_t google_protobuf_Int32Value_fields[2] = { + PB_FIELD( 1, INT32 , SINGULAR, STATIC , FIRST, google_protobuf_Int32Value, value, value, 0), + PB_LAST_FIELD +}; + +const pb_field_t google_protobuf_UInt32Value_fields[2] = { + PB_FIELD( 1, UINT32 , SINGULAR, STATIC , FIRST, google_protobuf_UInt32Value, value, value, 0), + PB_LAST_FIELD +}; + +const pb_field_t google_protobuf_BoolValue_fields[2] = { + PB_FIELD( 1, BOOL , SINGULAR, STATIC , FIRST, google_protobuf_BoolValue, value, value, 0), + PB_LAST_FIELD +}; + +const pb_field_t google_protobuf_StringValue_fields[2] = { + PB_FIELD( 1, BYTES , SINGULAR, POINTER , FIRST, google_protobuf_StringValue, value, value, 0), + PB_LAST_FIELD +}; + +const pb_field_t google_protobuf_BytesValue_fields[2] = { + PB_FIELD( 1, BYTES , SINGULAR, POINTER , FIRST, google_protobuf_BytesValue, value, value, 0), + PB_LAST_FIELD +}; + + +/* On some platforms (such as AVR), double is really float. + * These are not directly supported by nanopb, but see example_avr_double. + * To get rid of this error, remove any double fields from your .proto. + */ +PB_STATIC_ASSERT(sizeof(double) == 8, DOUBLE_MUST_BE_8_BYTES) + +} // namespace firestore +} // namespace firebase + +/* @@protoc_insertion_point(eof) */ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/google/protobuf/wrappers.nanopb.h b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/google/protobuf/wrappers.nanopb.h new file mode 100644 index 0000000..de0ed65 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/google/protobuf/wrappers.nanopb.h @@ -0,0 +1,147 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +/* Automatically generated nanopb header */ +/* Generated by nanopb-0.3.9.1 */ + +#ifndef PB_GOOGLE_PROTOBUF_WRAPPERS_NANOPB_H_INCLUDED +#define PB_GOOGLE_PROTOBUF_WRAPPERS_NANOPB_H_INCLUDED +#include + +namespace firebase { +namespace firestore { + +/* @@protoc_insertion_point(includes) */ +#if PB_PROTO_HEADER_VERSION != 30 +#error Regenerate this file with the current version of nanopb generator. +#endif + + +/* Struct definitions */ +typedef struct _google_protobuf_BytesValue { + pb_bytes_array_t *value; +/* @@protoc_insertion_point(struct:google_protobuf_BytesValue) */ +} google_protobuf_BytesValue; + +typedef struct _google_protobuf_StringValue { + pb_bytes_array_t *value; +/* @@protoc_insertion_point(struct:google_protobuf_StringValue) */ +} google_protobuf_StringValue; + +typedef struct _google_protobuf_BoolValue { + bool value; +/* @@protoc_insertion_point(struct:google_protobuf_BoolValue) */ +} google_protobuf_BoolValue; + +typedef struct _google_protobuf_DoubleValue { + double value; +/* @@protoc_insertion_point(struct:google_protobuf_DoubleValue) */ +} google_protobuf_DoubleValue; + +typedef struct _google_protobuf_FloatValue { + float value; +/* @@protoc_insertion_point(struct:google_protobuf_FloatValue) */ +} google_protobuf_FloatValue; + +typedef struct _google_protobuf_Int32Value { + int32_t value; +/* @@protoc_insertion_point(struct:google_protobuf_Int32Value) */ +} google_protobuf_Int32Value; + +typedef struct _google_protobuf_Int64Value { + int64_t value; +/* @@protoc_insertion_point(struct:google_protobuf_Int64Value) */ +} google_protobuf_Int64Value; + +typedef struct _google_protobuf_UInt32Value { + uint32_t value; +/* @@protoc_insertion_point(struct:google_protobuf_UInt32Value) */ +} google_protobuf_UInt32Value; + +typedef struct _google_protobuf_UInt64Value { + uint64_t value; +/* @@protoc_insertion_point(struct:google_protobuf_UInt64Value) */ +} google_protobuf_UInt64Value; + +/* Default values for struct fields */ + +/* Initializer values for message structs */ +#define google_protobuf_DoubleValue_init_default {0} +#define google_protobuf_FloatValue_init_default {0} +#define google_protobuf_Int64Value_init_default {0} +#define google_protobuf_UInt64Value_init_default {0} +#define google_protobuf_Int32Value_init_default {0} +#define google_protobuf_UInt32Value_init_default {0} +#define google_protobuf_BoolValue_init_default {0} +#define google_protobuf_StringValue_init_default {NULL} +#define google_protobuf_BytesValue_init_default {NULL} +#define google_protobuf_DoubleValue_init_zero {0} +#define google_protobuf_FloatValue_init_zero {0} +#define google_protobuf_Int64Value_init_zero {0} +#define google_protobuf_UInt64Value_init_zero {0} +#define google_protobuf_Int32Value_init_zero {0} +#define google_protobuf_UInt32Value_init_zero {0} +#define google_protobuf_BoolValue_init_zero {0} +#define google_protobuf_StringValue_init_zero {NULL} +#define google_protobuf_BytesValue_init_zero {NULL} + +/* Field tags (for use in manual encoding/decoding) */ +#define google_protobuf_BytesValue_value_tag 1 +#define google_protobuf_StringValue_value_tag 1 +#define google_protobuf_BoolValue_value_tag 1 +#define google_protobuf_DoubleValue_value_tag 1 +#define google_protobuf_FloatValue_value_tag 1 +#define google_protobuf_Int32Value_value_tag 1 +#define google_protobuf_Int64Value_value_tag 1 +#define google_protobuf_UInt32Value_value_tag 1 +#define google_protobuf_UInt64Value_value_tag 1 + +/* Struct field encoding specification for nanopb */ +extern const pb_field_t google_protobuf_DoubleValue_fields[2]; +extern const pb_field_t google_protobuf_FloatValue_fields[2]; +extern const pb_field_t google_protobuf_Int64Value_fields[2]; +extern const pb_field_t google_protobuf_UInt64Value_fields[2]; +extern const pb_field_t google_protobuf_Int32Value_fields[2]; +extern const pb_field_t google_protobuf_UInt32Value_fields[2]; +extern const pb_field_t google_protobuf_BoolValue_fields[2]; +extern const pb_field_t google_protobuf_StringValue_fields[2]; +extern const pb_field_t google_protobuf_BytesValue_fields[2]; + +/* Maximum encoded size of messages (where known) */ +#define google_protobuf_DoubleValue_size 9 +#define google_protobuf_FloatValue_size 5 +#define google_protobuf_Int64Value_size 11 +#define google_protobuf_UInt64Value_size 11 +#define google_protobuf_Int32Value_size 11 +#define google_protobuf_UInt32Value_size 6 +#define google_protobuf_BoolValue_size 2 +/* google_protobuf_StringValue_size depends on runtime parameters */ +/* google_protobuf_BytesValue_size depends on runtime parameters */ + +/* Message IDs (where set with "msgid" option) */ +#ifdef PB_MSGID + +#define WRAPPERS_MESSAGES \ + + +#endif + +} // namespace firestore +} // namespace firebase + +/* @@protoc_insertion_point(eof) */ + +#endif diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/google/rpc/status.nanopb.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/google/rpc/status.nanopb.cc new file mode 100644 index 0000000..e340d83 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/google/rpc/status.nanopb.cc @@ -0,0 +1,43 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +/* Automatically generated nanopb constant definitions */ +/* Generated by nanopb-0.3.9.1 */ + +#include "status.nanopb.h" + +namespace firebase { +namespace firestore { + +/* @@protoc_insertion_point(includes) */ +#if PB_PROTO_HEADER_VERSION != 30 +#error Regenerate this file with the current version of nanopb generator. +#endif + + + +const pb_field_t google_rpc_Status_fields[4] = { + PB_FIELD( 1, INT32 , SINGULAR, STATIC , FIRST, google_rpc_Status, code, code, 0), + PB_FIELD( 2, BYTES , SINGULAR, POINTER , OTHER, google_rpc_Status, message, code, 0), + PB_FIELD( 3, MESSAGE , REPEATED, POINTER , OTHER, google_rpc_Status, details, message, &google_protobuf_Any_fields), + PB_LAST_FIELD +}; + + +} // namespace firestore +} // namespace firebase + +/* @@protoc_insertion_point(eof) */ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/google/rpc/status.nanopb.h b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/google/rpc/status.nanopb.h new file mode 100644 index 0000000..6186d61 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/google/rpc/status.nanopb.h @@ -0,0 +1,74 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +/* Automatically generated nanopb header */ +/* Generated by nanopb-0.3.9.1 */ + +#ifndef PB_GOOGLE_RPC_STATUS_NANOPB_H_INCLUDED +#define PB_GOOGLE_RPC_STATUS_NANOPB_H_INCLUDED +#include + +#include "google/protobuf/any.nanopb.h" + +namespace firebase { +namespace firestore { + +/* @@protoc_insertion_point(includes) */ +#if PB_PROTO_HEADER_VERSION != 30 +#error Regenerate this file with the current version of nanopb generator. +#endif + + +/* Struct definitions */ +typedef struct _google_rpc_Status { + int32_t code; + pb_bytes_array_t *message; + pb_size_t details_count; + struct _google_protobuf_Any *details; +/* @@protoc_insertion_point(struct:google_rpc_Status) */ +} google_rpc_Status; + +/* Default values for struct fields */ + +/* Initializer values for message structs */ +#define google_rpc_Status_init_default {0, NULL, 0, NULL} +#define google_rpc_Status_init_zero {0, NULL, 0, NULL} + +/* Field tags (for use in manual encoding/decoding) */ +#define google_rpc_Status_code_tag 1 +#define google_rpc_Status_message_tag 2 +#define google_rpc_Status_details_tag 3 + +/* Struct field encoding specification for nanopb */ +extern const pb_field_t google_rpc_Status_fields[4]; + +/* Maximum encoded size of messages (where known) */ +/* google_rpc_Status_size depends on runtime parameters */ + +/* Message IDs (where set with "msgid" option) */ +#ifdef PB_MSGID + +#define STATUS_MESSAGES \ + + +#endif + +} // namespace firestore +} // namespace firebase + +/* @@protoc_insertion_point(eof) */ + +#endif diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/google/type/latlng.nanopb.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/google/type/latlng.nanopb.cc new file mode 100644 index 0000000..53a7d70 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/google/type/latlng.nanopb.cc @@ -0,0 +1,48 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +/* Automatically generated nanopb constant definitions */ +/* Generated by nanopb-0.3.9.1 */ + +#include "latlng.nanopb.h" + +namespace firebase { +namespace firestore { + +/* @@protoc_insertion_point(includes) */ +#if PB_PROTO_HEADER_VERSION != 30 +#error Regenerate this file with the current version of nanopb generator. +#endif + + + +const pb_field_t google_type_LatLng_fields[3] = { + PB_FIELD( 1, DOUBLE , SINGULAR, STATIC , FIRST, google_type_LatLng, latitude, latitude, 0), + PB_FIELD( 2, DOUBLE , SINGULAR, STATIC , OTHER, google_type_LatLng, longitude, latitude, 0), + PB_LAST_FIELD +}; + + +/* On some platforms (such as AVR), double is really float. + * These are not directly supported by nanopb, but see example_avr_double. + * To get rid of this error, remove any double fields from your .proto. + */ +PB_STATIC_ASSERT(sizeof(double) == 8, DOUBLE_MUST_BE_8_BYTES) + +} // namespace firestore +} // namespace firebase + +/* @@protoc_insertion_point(eof) */ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/google/type/latlng.nanopb.h b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/google/type/latlng.nanopb.h new file mode 100644 index 0000000..2b756f5 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/nanopb/google/type/latlng.nanopb.h @@ -0,0 +1,69 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +/* Automatically generated nanopb header */ +/* Generated by nanopb-0.3.9.1 */ + +#ifndef PB_GOOGLE_TYPE_LATLNG_NANOPB_H_INCLUDED +#define PB_GOOGLE_TYPE_LATLNG_NANOPB_H_INCLUDED +#include + +namespace firebase { +namespace firestore { + +/* @@protoc_insertion_point(includes) */ +#if PB_PROTO_HEADER_VERSION != 30 +#error Regenerate this file with the current version of nanopb generator. +#endif + + +/* Struct definitions */ +typedef struct _google_type_LatLng { + double latitude; + double longitude; +/* @@protoc_insertion_point(struct:google_type_LatLng) */ +} google_type_LatLng; + +/* Default values for struct fields */ + +/* Initializer values for message structs */ +#define google_type_LatLng_init_default {0, 0} +#define google_type_LatLng_init_zero {0, 0} + +/* Field tags (for use in manual encoding/decoding) */ +#define google_type_LatLng_latitude_tag 1 +#define google_type_LatLng_longitude_tag 2 + +/* Struct field encoding specification for nanopb */ +extern const pb_field_t google_type_LatLng_fields[3]; + +/* Maximum encoded size of messages (where known) */ +#define google_type_LatLng_size 18 + +/* Message IDs (where set with "msgid" option) */ +#ifdef PB_MSGID + +#define LATLNG_MESSAGES \ + + +#endif + +} // namespace firestore +} // namespace firebase + +/* @@protoc_insertion_point(eof) */ + +#endif diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/objc/firestore/local/MaybeDocument.pbobjc.h b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/objc/firestore/local/MaybeDocument.pbobjc.h new file mode 100644 index 0000000..cac8209 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/objc/firestore/local/MaybeDocument.pbobjc.h @@ -0,0 +1,174 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: firestore/local/maybe_document.proto + +// This CPP symbol can be defined to use imports that match up to the framework +// imports needed when using CocoaPods. +#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) + #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 +#endif + +#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS + #import +#else + #import "GPBProtocolBuffers.h" +#endif + +#if GOOGLE_PROTOBUF_OBJC_VERSION < 30002 +#error This file was generated by a newer version of protoc which is incompatible with your Protocol Buffer library sources. +#endif +#if 30002 < GOOGLE_PROTOBUF_OBJC_MIN_SUPPORTED_VERSION +#error This file was generated by an older version of protoc which is incompatible with your Protocol Buffer library sources. +#endif + +// @@protoc_insertion_point(imports) + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + +CF_EXTERN_C_BEGIN + +@class FSTPBNoDocument; +@class FSTPBUnknownDocument; +@class GCFSDocument; +@class GPBTimestamp; + +NS_ASSUME_NONNULL_BEGIN + +#pragma mark - FSTPBMaybeDocumentRoot + +/** + * Exposes the extension registry for this file. + * + * The base class provides: + * @code + * + (GPBExtensionRegistry *)extensionRegistry; + * @endcode + * which is a @c GPBExtensionRegistry that includes all the extensions defined by + * this file and all files that it depends on. + **/ +@interface FSTPBMaybeDocumentRoot : GPBRootObject +@end + +#pragma mark - FSTPBNoDocument + +typedef GPB_ENUM(FSTPBNoDocument_FieldNumber) { + FSTPBNoDocument_FieldNumber_Name = 1, + FSTPBNoDocument_FieldNumber_ReadTime = 2, +}; + +/** + * A message indicating that the document is known to not exist. + **/ +@interface FSTPBNoDocument : GPBMessage + +/** + * The name of the document that does not exist, in the standard format: + * `projects/{project_id}/databases/{database_id}/documents/{document_path}` + **/ +@property(nonatomic, readwrite, copy, null_resettable) NSString *name; + +/** The time at which we observed that it does not exist. */ +@property(nonatomic, readwrite, strong, null_resettable) GPBTimestamp *readTime; +/** Test to see if @c readTime has been set. */ +@property(nonatomic, readwrite) BOOL hasReadTime; + +@end + +#pragma mark - FSTPBUnknownDocument + +typedef GPB_ENUM(FSTPBUnknownDocument_FieldNumber) { + FSTPBUnknownDocument_FieldNumber_Name = 1, + FSTPBUnknownDocument_FieldNumber_Version = 2, +}; + +/** + * A message indicating that the document that is known to exist but its data + * is unknown. + **/ +@interface FSTPBUnknownDocument : GPBMessage + +/** + * The name of the document that is known to exist, in the standard format: + * `projects/{project_id}/databases/{database_id}/documents/{document_path}` + **/ +@property(nonatomic, readwrite, copy, null_resettable) NSString *name; + +/** The version at which we know the document exists. */ +@property(nonatomic, readwrite, strong, null_resettable) GPBTimestamp *version; +/** Test to see if @c version has been set. */ +@property(nonatomic, readwrite) BOOL hasVersion; + +@end + +#pragma mark - FSTPBMaybeDocument + +typedef GPB_ENUM(FSTPBMaybeDocument_FieldNumber) { + FSTPBMaybeDocument_FieldNumber_NoDocument = 1, + FSTPBMaybeDocument_FieldNumber_Document = 2, + FSTPBMaybeDocument_FieldNumber_UnknownDocument = 3, + FSTPBMaybeDocument_FieldNumber_HasCommittedMutations = 4, +}; + +typedef GPB_ENUM(FSTPBMaybeDocument_DocumentType_OneOfCase) { + FSTPBMaybeDocument_DocumentType_OneOfCase_GPBUnsetOneOfCase = 0, + FSTPBMaybeDocument_DocumentType_OneOfCase_NoDocument = 1, + FSTPBMaybeDocument_DocumentType_OneOfCase_Document = 2, + FSTPBMaybeDocument_DocumentType_OneOfCase_UnknownDocument = 3, +}; + +/** + * Represents either an existing document, the explicitly known absence of a + * document, or a document that is known to exist (at some version) but whose + * contents are unknown. + **/ +@interface FSTPBMaybeDocument : GPBMessage + +@property(nonatomic, readonly) FSTPBMaybeDocument_DocumentType_OneOfCase documentTypeOneOfCase; + +/** Used if the document is known to not exist. */ +@property(nonatomic, readwrite, strong, null_resettable) FSTPBNoDocument *noDocument; + +/** The document (if it exists). */ +@property(nonatomic, readwrite, strong, null_resettable) GCFSDocument *document; + +/** Used if the document is known to exist but its data is unknown. */ +@property(nonatomic, readwrite, strong, null_resettable) FSTPBUnknownDocument *unknownDocument; + +/** + * `has_committed_mutations` marks documents that were written to the remote + * document store based on a write acknowledgment. These documents are + * potentially inconsistent with the backend's copy and use the write's + * commit version as their document version. + **/ +@property(nonatomic, readwrite) BOOL hasCommittedMutations; + +@end + +/** + * Clears whatever value was set for the oneof 'documentType'. + **/ +void FSTPBMaybeDocument_ClearDocumentTypeOneOfCase(FSTPBMaybeDocument *message); + +NS_ASSUME_NONNULL_END + +CF_EXTERN_C_END + +#pragma clang diagnostic pop + +// @@protoc_insertion_point(global_scope) diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/objc/firestore/local/MaybeDocument.pbobjc.m b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/objc/firestore/local/MaybeDocument.pbobjc.m new file mode 100644 index 0000000..83bed77 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/objc/firestore/local/MaybeDocument.pbobjc.m @@ -0,0 +1,267 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: firestore/local/maybe_document.proto + +// This CPP symbol can be defined to use imports that match up to the framework +// imports needed when using CocoaPods. +#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) + #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 +#endif + +#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS + #import +#else + #import "GPBProtocolBuffers_RuntimeSupport.h" +#endif + +#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS + #import +#else + #import "Timestamp.pbobjc.h" +#endif + + #import "MaybeDocument.pbobjc.h" + #import "Document.pbobjc.h" + #import "Annotations.pbobjc.h" +// @@protoc_insertion_point(imports) + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" +#pragma clang diagnostic ignored "-Wdirect-ivar-access" + +#pragma mark - FSTPBMaybeDocumentRoot + +@implementation FSTPBMaybeDocumentRoot + + +@end + +#pragma mark - FSTPBMaybeDocumentRoot_FileDescriptor + +static GPBFileDescriptor *FSTPBMaybeDocumentRoot_FileDescriptor(void) { + // This is called by +initialize so there is no need to worry + // about thread safety of the singleton. + static GPBFileDescriptor *descriptor = NULL; + if (!descriptor) { + GPB_DEBUG_CHECK_RUNTIME_VERSIONS(); + descriptor = [[GPBFileDescriptor alloc] initWithPackage:@"firestore.client" + objcPrefix:@"FSTPB" + syntax:GPBFileSyntaxProto3]; + } + return descriptor; +} + +#pragma mark - FSTPBNoDocument + +@implementation FSTPBNoDocument + +@dynamic name; +@dynamic hasReadTime, readTime; + +typedef struct FSTPBNoDocument__storage_ { + uint32_t _has_storage_[1]; + NSString *name; + GPBTimestamp *readTime; +} FSTPBNoDocument__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "name", + .dataTypeSpecific.className = NULL, + .number = FSTPBNoDocument_FieldNumber_Name, + .hasIndex = 0, + .offset = (uint32_t)offsetof(FSTPBNoDocument__storage_, name), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "readTime", + .dataTypeSpecific.className = GPBStringifySymbol(GPBTimestamp), + .number = FSTPBNoDocument_FieldNumber_ReadTime, + .hasIndex = 1, + .offset = (uint32_t)offsetof(FSTPBNoDocument__storage_, readTime), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[FSTPBNoDocument class] + rootClass:[FSTPBMaybeDocumentRoot class] + file:FSTPBMaybeDocumentRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(FSTPBNoDocument__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - FSTPBUnknownDocument + +@implementation FSTPBUnknownDocument + +@dynamic name; +@dynamic hasVersion, version; + +typedef struct FSTPBUnknownDocument__storage_ { + uint32_t _has_storage_[1]; + NSString *name; + GPBTimestamp *version; +} FSTPBUnknownDocument__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "name", + .dataTypeSpecific.className = NULL, + .number = FSTPBUnknownDocument_FieldNumber_Name, + .hasIndex = 0, + .offset = (uint32_t)offsetof(FSTPBUnknownDocument__storage_, name), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "version", + .dataTypeSpecific.className = GPBStringifySymbol(GPBTimestamp), + .number = FSTPBUnknownDocument_FieldNumber_Version, + .hasIndex = 1, + .offset = (uint32_t)offsetof(FSTPBUnknownDocument__storage_, version), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[FSTPBUnknownDocument class] + rootClass:[FSTPBMaybeDocumentRoot class] + file:FSTPBMaybeDocumentRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(FSTPBUnknownDocument__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - FSTPBMaybeDocument + +@implementation FSTPBMaybeDocument + +@dynamic documentTypeOneOfCase; +@dynamic noDocument; +@dynamic document; +@dynamic unknownDocument; +@dynamic hasCommittedMutations; + +typedef struct FSTPBMaybeDocument__storage_ { + uint32_t _has_storage_[2]; + FSTPBNoDocument *noDocument; + GCFSDocument *document; + FSTPBUnknownDocument *unknownDocument; +} FSTPBMaybeDocument__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "noDocument", + .dataTypeSpecific.className = GPBStringifySymbol(FSTPBNoDocument), + .number = FSTPBMaybeDocument_FieldNumber_NoDocument, + .hasIndex = -1, + .offset = (uint32_t)offsetof(FSTPBMaybeDocument__storage_, noDocument), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + { + .name = "document", + .dataTypeSpecific.className = GPBStringifySymbol(GCFSDocument), + .number = FSTPBMaybeDocument_FieldNumber_Document, + .hasIndex = -1, + .offset = (uint32_t)offsetof(FSTPBMaybeDocument__storage_, document), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + { + .name = "unknownDocument", + .dataTypeSpecific.className = GPBStringifySymbol(FSTPBUnknownDocument), + .number = FSTPBMaybeDocument_FieldNumber_UnknownDocument, + .hasIndex = -1, + .offset = (uint32_t)offsetof(FSTPBMaybeDocument__storage_, unknownDocument), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + { + .name = "hasCommittedMutations", + .dataTypeSpecific.className = NULL, + .number = FSTPBMaybeDocument_FieldNumber_HasCommittedMutations, + .hasIndex = 0, + .offset = 1, // Stored in _has_storage_ to save space. + .flags = GPBFieldOptional, + .dataType = GPBDataTypeBool, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[FSTPBMaybeDocument class] + rootClass:[FSTPBMaybeDocumentRoot class] + file:FSTPBMaybeDocumentRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(FSTPBMaybeDocument__storage_) + flags:GPBDescriptorInitializationFlag_None]; + static const char *oneofs[] = { + "documentType", + }; + [localDescriptor setupOneofs:oneofs + count:(uint32_t)(sizeof(oneofs) / sizeof(char*)) + firstHasIndex:-1]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +void FSTPBMaybeDocument_ClearDocumentTypeOneOfCase(FSTPBMaybeDocument *message) { + GPBDescriptor *descriptor = [message descriptor]; + GPBOneofDescriptor *oneof = [descriptor.oneofs objectAtIndex:0]; + GPBMaybeClearOneof(message, oneof, -1, 0); +} + +#pragma clang diagnostic pop + +// @@protoc_insertion_point(global_scope) diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/objc/firestore/local/Mutation.pbobjc.h b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/objc/firestore/local/Mutation.pbobjc.h new file mode 100644 index 0000000..9091ba6 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/objc/firestore/local/Mutation.pbobjc.h @@ -0,0 +1,155 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: firestore/local/mutation.proto + +// This CPP symbol can be defined to use imports that match up to the framework +// imports needed when using CocoaPods. +#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) + #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 +#endif + +#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS + #import +#else + #import "GPBProtocolBuffers.h" +#endif + +#if GOOGLE_PROTOBUF_OBJC_VERSION < 30002 +#error This file was generated by a newer version of protoc which is incompatible with your Protocol Buffer library sources. +#endif +#if 30002 < GOOGLE_PROTOBUF_OBJC_MIN_SUPPORTED_VERSION +#error This file was generated by an older version of protoc which is incompatible with your Protocol Buffer library sources. +#endif + +// @@protoc_insertion_point(imports) + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + +CF_EXTERN_C_BEGIN + +@class GCFSWrite; +@class GPBTimestamp; + +NS_ASSUME_NONNULL_BEGIN + +#pragma mark - FSTPBMutationRoot + +/** + * Exposes the extension registry for this file. + * + * The base class provides: + * @code + * + (GPBExtensionRegistry *)extensionRegistry; + * @endcode + * which is a @c GPBExtensionRegistry that includes all the extensions defined by + * this file and all files that it depends on. + **/ +@interface FSTPBMutationRoot : GPBRootObject +@end + +#pragma mark - FSTPBMutationQueue + +typedef GPB_ENUM(FSTPBMutationQueue_FieldNumber) { + FSTPBMutationQueue_FieldNumber_LastAcknowledgedBatchId = 1, + FSTPBMutationQueue_FieldNumber_LastStreamToken = 2, +}; + +/** + * Each user gets a single queue of WriteBatches to apply to the server. + * MutationQueue tracks the metadata about the queue. + **/ +@interface FSTPBMutationQueue : GPBMessage + +/** + * An identifier for the highest numbered batch that has been acknowledged by + * the server. All WriteBatches in this queue with batch_ids less than or + * equal to this value are considered to have been acknowledged by the + * server. + **/ +@property(nonatomic, readwrite) int32_t lastAcknowledgedBatchId; + +/** + * A stream token that was previously sent by the server. + * + * See StreamingWriteRequest in datastore.proto for more details about usage. + * + * After sending this token, earlier tokens may not be used anymore so only a + * single stream token is retained. + **/ +@property(nonatomic, readwrite, copy, null_resettable) NSData *lastStreamToken; + +@end + +#pragma mark - FSTPBWriteBatch + +typedef GPB_ENUM(FSTPBWriteBatch_FieldNumber) { + FSTPBWriteBatch_FieldNumber_BatchId = 1, + FSTPBWriteBatch_FieldNumber_WritesArray = 2, + FSTPBWriteBatch_FieldNumber_LocalWriteTime = 3, + FSTPBWriteBatch_FieldNumber_BaseWritesArray = 4, +}; + +/** + * Message containing a batch of user-level writes intended to be sent to + * the server in a single call. Each user-level batch gets a separate + * WriteBatch with a new batch_id. + **/ +@interface FSTPBWriteBatch : GPBMessage + +/** + * An identifier for this batch, allocated by the mutation queue in a + * monotonically increasing manner. + **/ +@property(nonatomic, readwrite) int32_t batchId; + +/** A list of writes to apply. All writes will be applied atomically. */ +@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *writesArray; +/** The number of items in @c writesArray without causing the array to be created. */ +@property(nonatomic, readonly) NSUInteger writesArray_Count; + +/** The local time at which the write batch was initiated. */ +@property(nonatomic, readwrite, strong, null_resettable) GPBTimestamp *localWriteTime; +/** Test to see if @c localWriteTime has been set. */ +@property(nonatomic, readwrite) BOOL hasLocalWriteTime; + +/** + * A list of pseudo-writes that represent a partial base state from when this + * write batch was initially created. When computing the local view batch, + * these base_writes are applied prior to the real writes in order to + * override certain document fields from the remote document cache. This is + * necessary in the case of non-idempotent writes (e.g. numericAdd + * transforms) to make sure that the local view of the modified documents + * doesn't flicker if the remote document cache receives the result of the + * non-idempotent write before the write is removed from the queue. + * + * These writes are never sent to the backend. + **/ +@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *baseWritesArray; +/** The number of items in @c baseWritesArray without causing the array to be created. */ +@property(nonatomic, readonly) NSUInteger baseWritesArray_Count; + +@end + +NS_ASSUME_NONNULL_END + +CF_EXTERN_C_END + +#pragma clang diagnostic pop + +// @@protoc_insertion_point(global_scope) diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/objc/firestore/local/Mutation.pbobjc.m b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/objc/firestore/local/Mutation.pbobjc.m new file mode 100644 index 0000000..5c88e90 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/objc/firestore/local/Mutation.pbobjc.m @@ -0,0 +1,201 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: firestore/local/mutation.proto + +// This CPP symbol can be defined to use imports that match up to the framework +// imports needed when using CocoaPods. +#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) + #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 +#endif + +#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS + #import +#else + #import "GPBProtocolBuffers_RuntimeSupport.h" +#endif + +#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS + #import +#else + #import "Timestamp.pbobjc.h" +#endif + + #import "Mutation.pbobjc.h" + #import "Write.pbobjc.h" + #import "Annotations.pbobjc.h" +// @@protoc_insertion_point(imports) + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + +#pragma mark - FSTPBMutationRoot + +@implementation FSTPBMutationRoot + + +@end + +#pragma mark - FSTPBMutationRoot_FileDescriptor + +static GPBFileDescriptor *FSTPBMutationRoot_FileDescriptor(void) { + // This is called by +initialize so there is no need to worry + // about thread safety of the singleton. + static GPBFileDescriptor *descriptor = NULL; + if (!descriptor) { + GPB_DEBUG_CHECK_RUNTIME_VERSIONS(); + descriptor = [[GPBFileDescriptor alloc] initWithPackage:@"firestore.client" + objcPrefix:@"FSTPB" + syntax:GPBFileSyntaxProto3]; + } + return descriptor; +} + +#pragma mark - FSTPBMutationQueue + +@implementation FSTPBMutationQueue + +@dynamic lastAcknowledgedBatchId; +@dynamic lastStreamToken; + +typedef struct FSTPBMutationQueue__storage_ { + uint32_t _has_storage_[1]; + int32_t lastAcknowledgedBatchId; + NSData *lastStreamToken; +} FSTPBMutationQueue__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "lastAcknowledgedBatchId", + .dataTypeSpecific.className = NULL, + .number = FSTPBMutationQueue_FieldNumber_LastAcknowledgedBatchId, + .hasIndex = 0, + .offset = (uint32_t)offsetof(FSTPBMutationQueue__storage_, lastAcknowledgedBatchId), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + { + .name = "lastStreamToken", + .dataTypeSpecific.className = NULL, + .number = FSTPBMutationQueue_FieldNumber_LastStreamToken, + .hasIndex = 1, + .offset = (uint32_t)offsetof(FSTPBMutationQueue__storage_, lastStreamToken), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeBytes, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[FSTPBMutationQueue class] + rootClass:[FSTPBMutationRoot class] + file:FSTPBMutationRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(FSTPBMutationQueue__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - FSTPBWriteBatch + +@implementation FSTPBWriteBatch + +@dynamic batchId; +@dynamic writesArray, writesArray_Count; +@dynamic hasLocalWriteTime, localWriteTime; +@dynamic baseWritesArray, baseWritesArray_Count; + +typedef struct FSTPBWriteBatch__storage_ { + uint32_t _has_storage_[1]; + int32_t batchId; + NSMutableArray *writesArray; + GPBTimestamp *localWriteTime; + NSMutableArray *baseWritesArray; +} FSTPBWriteBatch__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "batchId", + .dataTypeSpecific.className = NULL, + .number = FSTPBWriteBatch_FieldNumber_BatchId, + .hasIndex = 0, + .offset = (uint32_t)offsetof(FSTPBWriteBatch__storage_, batchId), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + { + .name = "writesArray", + .dataTypeSpecific.className = GPBStringifySymbol(GCFSWrite), + .number = FSTPBWriteBatch_FieldNumber_WritesArray, + .hasIndex = GPBNoHasBit, + .offset = (uint32_t)offsetof(FSTPBWriteBatch__storage_, writesArray), + .flags = GPBFieldRepeated, + .dataType = GPBDataTypeMessage, + }, + { + .name = "localWriteTime", + .dataTypeSpecific.className = GPBStringifySymbol(GPBTimestamp), + .number = FSTPBWriteBatch_FieldNumber_LocalWriteTime, + .hasIndex = 1, + .offset = (uint32_t)offsetof(FSTPBWriteBatch__storage_, localWriteTime), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + { + .name = "baseWritesArray", + .dataTypeSpecific.className = GPBStringifySymbol(GCFSWrite), + .number = FSTPBWriteBatch_FieldNumber_BaseWritesArray, + .hasIndex = GPBNoHasBit, + .offset = (uint32_t)offsetof(FSTPBWriteBatch__storage_, baseWritesArray), + .flags = GPBFieldRepeated, + .dataType = GPBDataTypeMessage, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[FSTPBWriteBatch class] + rootClass:[FSTPBMutationRoot class] + file:FSTPBMutationRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(FSTPBWriteBatch__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + + +#pragma clang diagnostic pop + +// @@protoc_insertion_point(global_scope) diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/objc/firestore/local/Target.pbobjc.h b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/objc/firestore/local/Target.pbobjc.h new file mode 100644 index 0000000..88d9bff --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/objc/firestore/local/Target.pbobjc.h @@ -0,0 +1,214 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: firestore/local/target.proto + +// This CPP symbol can be defined to use imports that match up to the framework +// imports needed when using CocoaPods. +#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) + #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 +#endif + +#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS + #import +#else + #import "GPBProtocolBuffers.h" +#endif + +#if GOOGLE_PROTOBUF_OBJC_VERSION < 30002 +#error This file was generated by a newer version of protoc which is incompatible with your Protocol Buffer library sources. +#endif +#if 30002 < GOOGLE_PROTOBUF_OBJC_MIN_SUPPORTED_VERSION +#error This file was generated by an older version of protoc which is incompatible with your Protocol Buffer library sources. +#endif + +// @@protoc_insertion_point(imports) + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + +CF_EXTERN_C_BEGIN + +@class GCFSTarget_DocumentsTarget; +@class GCFSTarget_QueryTarget; +@class GPBTimestamp; + +NS_ASSUME_NONNULL_BEGIN + +#pragma mark - FSTPBTargetRoot + +/** + * Exposes the extension registry for this file. + * + * The base class provides: + * @code + * + (GPBExtensionRegistry *)extensionRegistry; + * @endcode + * which is a @c GPBExtensionRegistry that includes all the extensions defined by + * this file and all files that it depends on. + **/ +@interface FSTPBTargetRoot : GPBRootObject +@end + +#pragma mark - FSTPBTarget + +typedef GPB_ENUM(FSTPBTarget_FieldNumber) { + FSTPBTarget_FieldNumber_TargetId = 1, + FSTPBTarget_FieldNumber_SnapshotVersion = 2, + FSTPBTarget_FieldNumber_ResumeToken = 3, + FSTPBTarget_FieldNumber_LastListenSequenceNumber = 4, + FSTPBTarget_FieldNumber_Query = 5, + FSTPBTarget_FieldNumber_Documents = 6, +}; + +typedef GPB_ENUM(FSTPBTarget_TargetType_OneOfCase) { + FSTPBTarget_TargetType_OneOfCase_GPBUnsetOneOfCase = 0, + FSTPBTarget_TargetType_OneOfCase_Query = 5, + FSTPBTarget_TargetType_OneOfCase_Documents = 6, +}; + +/** + * A Target is a long-lived data structure representing a resumable listen on a + * particular user query. While the query describes what to listen to, the + * Target records data about when the results were last updated and enough + * information to be able to resume listening later. + **/ +@interface FSTPBTarget : GPBMessage + +/** + * An auto-generated sequential numeric identifier for the target. This + * serves as the identity of the target, and once assigned never changes. + **/ +@property(nonatomic, readwrite) int32_t targetId; + +/** + * The last snapshot version received from the Watch Service for this target. + * + * This is the same value as TargetChange.read_time + * https://github.com/googleapis/googleapis/blob/master/google/firestore/v1/firestore.proto#L734 + **/ +@property(nonatomic, readwrite, strong, null_resettable) GPBTimestamp *snapshotVersion; +/** Test to see if @c snapshotVersion has been set. */ +@property(nonatomic, readwrite) BOOL hasSnapshotVersion; + +/** + * An opaque, server-assigned token that allows watching a query to be + * resumed after disconnecting without retransmitting all the data that + * matches the query. The resume token essentially identifies a point in + * time from which the server should resume sending results. + * + * This is related to the snapshot_version in that the resume_token + * effectively also encodes that value, but the resume_token is opaque and + * sometimes encodes additional information. + * + * A consequence of this is that the resume_token should be used when asking + * the server to reason about where this client is in the watch stream, but + * the client should use the snapshot_version for its own purposes. + * + * This is the same value as TargetChange.resume_token + * https://github.com/googleapis/googleapis/blob/master/google/firestore/v1/firestore.proto#L722 + **/ +@property(nonatomic, readwrite, copy, null_resettable) NSData *resumeToken; + +/** + * A sequence number representing the last time this query was listened to, + * used for garbage collection purposes. + * + * Conventionally this would be a timestamp value, but device-local clocks + * are unreliable and they must be able to create new listens even while + * disconnected. Instead this should be a monotonically increasing number + * that's incremented on each listen call. + * + * This is different from the target_id since the target_id is an immutable + * identifier assigned to the Target on first use while + * last_listen_sequence_number is updated every time the query is listened + * to. + **/ +@property(nonatomic, readwrite) int64_t lastListenSequenceNumber; + +/** The server-side type of target to listen to. */ +@property(nonatomic, readonly) FSTPBTarget_TargetType_OneOfCase targetTypeOneOfCase; + +/** A target specified by a query. */ +@property(nonatomic, readwrite, strong, null_resettable) GCFSTarget_QueryTarget *query; + +/** A target specified by a set of document names. */ +@property(nonatomic, readwrite, strong, null_resettable) GCFSTarget_DocumentsTarget *documents; + +@end + +/** + * Clears whatever value was set for the oneof 'targetType'. + **/ +void FSTPBTarget_ClearTargetTypeOneOfCase(FSTPBTarget *message); + +#pragma mark - FSTPBTargetGlobal + +typedef GPB_ENUM(FSTPBTargetGlobal_FieldNumber) { + FSTPBTargetGlobal_FieldNumber_HighestTargetId = 1, + FSTPBTargetGlobal_FieldNumber_HighestListenSequenceNumber = 2, + FSTPBTargetGlobal_FieldNumber_LastRemoteSnapshotVersion = 3, + FSTPBTargetGlobal_FieldNumber_TargetCount = 4, +}; + +/** + * Global state tracked across all Targets, tracked separately to avoid the + * need for extra indexes. + **/ +@interface FSTPBTargetGlobal : GPBMessage + +/** + * The highest numbered target id across all Targets. + * + * See Target.target_id. + **/ +@property(nonatomic, readwrite) int32_t highestTargetId; + +/** + * The highest numbered last_listen_sequence_number across all Targets. + * + * See Target.last_listen_sequence_number. + **/ +@property(nonatomic, readwrite) int64_t highestListenSequenceNumber; + +/** + * A global snapshot version representing the last consistent snapshot we + * received from the backend. This is monotonically increasing and any + * snapshots received from the backend prior to this version (e.g. for + * targets resumed with a resume_token) should be suppressed (buffered) until + * the backend has caught up to this snapshot_version again. This prevents + * our cache from ever going backwards in time. + * + * This is updated whenever our we get a TargetChange with a read_time and + * empty target_ids. + **/ +@property(nonatomic, readwrite, strong, null_resettable) GPBTimestamp *lastRemoteSnapshotVersion; +/** Test to see if @c lastRemoteSnapshotVersion has been set. */ +@property(nonatomic, readwrite) BOOL hasLastRemoteSnapshotVersion; + +/** On platforms that need it, holds the number of targets persisted. */ +@property(nonatomic, readwrite) int32_t targetCount; + +@end + +NS_ASSUME_NONNULL_END + +CF_EXTERN_C_END + +#pragma clang diagnostic pop + +// @@protoc_insertion_point(global_scope) diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/objc/firestore/local/Target.pbobjc.m b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/objc/firestore/local/Target.pbobjc.m new file mode 100644 index 0000000..2c41472 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/objc/firestore/local/Target.pbobjc.m @@ -0,0 +1,258 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: firestore/local/target.proto + +// This CPP symbol can be defined to use imports that match up to the framework +// imports needed when using CocoaPods. +#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) + #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 +#endif + +#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS + #import +#else + #import "GPBProtocolBuffers_RuntimeSupport.h" +#endif + +#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS + #import +#else + #import "Timestamp.pbobjc.h" +#endif + + #import "Target.pbobjc.h" + #import "Firestore.pbobjc.h" + #import "Annotations.pbobjc.h" +// @@protoc_insertion_point(imports) + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" +#pragma clang diagnostic ignored "-Wdirect-ivar-access" + +#pragma mark - FSTPBTargetRoot + +@implementation FSTPBTargetRoot + + +@end + +#pragma mark - FSTPBTargetRoot_FileDescriptor + +static GPBFileDescriptor *FSTPBTargetRoot_FileDescriptor(void) { + // This is called by +initialize so there is no need to worry + // about thread safety of the singleton. + static GPBFileDescriptor *descriptor = NULL; + if (!descriptor) { + GPB_DEBUG_CHECK_RUNTIME_VERSIONS(); + descriptor = [[GPBFileDescriptor alloc] initWithPackage:@"firestore.client" + objcPrefix:@"FSTPB" + syntax:GPBFileSyntaxProto3]; + } + return descriptor; +} + +#pragma mark - FSTPBTarget + +@implementation FSTPBTarget + +@dynamic targetTypeOneOfCase; +@dynamic targetId; +@dynamic hasSnapshotVersion, snapshotVersion; +@dynamic resumeToken; +@dynamic lastListenSequenceNumber; +@dynamic query; +@dynamic documents; + +typedef struct FSTPBTarget__storage_ { + uint32_t _has_storage_[2]; + int32_t targetId; + GPBTimestamp *snapshotVersion; + NSData *resumeToken; + GCFSTarget_QueryTarget *query; + GCFSTarget_DocumentsTarget *documents; + int64_t lastListenSequenceNumber; +} FSTPBTarget__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "targetId", + .dataTypeSpecific.className = NULL, + .number = FSTPBTarget_FieldNumber_TargetId, + .hasIndex = 0, + .offset = (uint32_t)offsetof(FSTPBTarget__storage_, targetId), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + { + .name = "snapshotVersion", + .dataTypeSpecific.className = GPBStringifySymbol(GPBTimestamp), + .number = FSTPBTarget_FieldNumber_SnapshotVersion, + .hasIndex = 1, + .offset = (uint32_t)offsetof(FSTPBTarget__storage_, snapshotVersion), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + { + .name = "resumeToken", + .dataTypeSpecific.className = NULL, + .number = FSTPBTarget_FieldNumber_ResumeToken, + .hasIndex = 2, + .offset = (uint32_t)offsetof(FSTPBTarget__storage_, resumeToken), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeBytes, + }, + { + .name = "lastListenSequenceNumber", + .dataTypeSpecific.className = NULL, + .number = FSTPBTarget_FieldNumber_LastListenSequenceNumber, + .hasIndex = 3, + .offset = (uint32_t)offsetof(FSTPBTarget__storage_, lastListenSequenceNumber), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt64, + }, + { + .name = "query", + .dataTypeSpecific.className = GPBStringifySymbol(GCFSTarget_QueryTarget), + .number = FSTPBTarget_FieldNumber_Query, + .hasIndex = -1, + .offset = (uint32_t)offsetof(FSTPBTarget__storage_, query), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + { + .name = "documents", + .dataTypeSpecific.className = GPBStringifySymbol(GCFSTarget_DocumentsTarget), + .number = FSTPBTarget_FieldNumber_Documents, + .hasIndex = -1, + .offset = (uint32_t)offsetof(FSTPBTarget__storage_, documents), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[FSTPBTarget class] + rootClass:[FSTPBTargetRoot class] + file:FSTPBTargetRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(FSTPBTarget__storage_) + flags:GPBDescriptorInitializationFlag_None]; + static const char *oneofs[] = { + "targetType", + }; + [localDescriptor setupOneofs:oneofs + count:(uint32_t)(sizeof(oneofs) / sizeof(char*)) + firstHasIndex:-1]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +void FSTPBTarget_ClearTargetTypeOneOfCase(FSTPBTarget *message) { + GPBDescriptor *descriptor = [message descriptor]; + GPBOneofDescriptor *oneof = [descriptor.oneofs objectAtIndex:0]; + GPBMaybeClearOneof(message, oneof, -1, 0); +} +#pragma mark - FSTPBTargetGlobal + +@implementation FSTPBTargetGlobal + +@dynamic highestTargetId; +@dynamic highestListenSequenceNumber; +@dynamic hasLastRemoteSnapshotVersion, lastRemoteSnapshotVersion; +@dynamic targetCount; + +typedef struct FSTPBTargetGlobal__storage_ { + uint32_t _has_storage_[1]; + int32_t highestTargetId; + int32_t targetCount; + GPBTimestamp *lastRemoteSnapshotVersion; + int64_t highestListenSequenceNumber; +} FSTPBTargetGlobal__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "highestTargetId", + .dataTypeSpecific.className = NULL, + .number = FSTPBTargetGlobal_FieldNumber_HighestTargetId, + .hasIndex = 0, + .offset = (uint32_t)offsetof(FSTPBTargetGlobal__storage_, highestTargetId), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + { + .name = "highestListenSequenceNumber", + .dataTypeSpecific.className = NULL, + .number = FSTPBTargetGlobal_FieldNumber_HighestListenSequenceNumber, + .hasIndex = 1, + .offset = (uint32_t)offsetof(FSTPBTargetGlobal__storage_, highestListenSequenceNumber), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt64, + }, + { + .name = "lastRemoteSnapshotVersion", + .dataTypeSpecific.className = GPBStringifySymbol(GPBTimestamp), + .number = FSTPBTargetGlobal_FieldNumber_LastRemoteSnapshotVersion, + .hasIndex = 2, + .offset = (uint32_t)offsetof(FSTPBTargetGlobal__storage_, lastRemoteSnapshotVersion), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + { + .name = "targetCount", + .dataTypeSpecific.className = NULL, + .number = FSTPBTargetGlobal_FieldNumber_TargetCount, + .hasIndex = 3, + .offset = (uint32_t)offsetof(FSTPBTargetGlobal__storage_, targetCount), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[FSTPBTargetGlobal class] + rootClass:[FSTPBTargetRoot class] + file:FSTPBTargetRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(FSTPBTargetGlobal__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + + +#pragma clang diagnostic pop + +// @@protoc_insertion_point(global_scope) diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/objc/google/api/Annotations.pbobjc.h b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/objc/google/api/Annotations.pbobjc.h new file mode 100644 index 0000000..02b99dd --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/objc/google/api/Annotations.pbobjc.h @@ -0,0 +1,17 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +// Empty stub file diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/objc/google/api/Annotations.pbobjc.m b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/objc/google/api/Annotations.pbobjc.m new file mode 100644 index 0000000..71f8ef2 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/objc/google/api/Annotations.pbobjc.m @@ -0,0 +1,17 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +static int annotations_stub __attribute__((unused,used)) = 0; diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/objc/google/api/HTTP.pbobjc.h b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/objc/google/api/HTTP.pbobjc.h new file mode 100644 index 0000000..0b7da83 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/objc/google/api/HTTP.pbobjc.h @@ -0,0 +1,433 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/api/http.proto + +// This CPP symbol can be defined to use imports that match up to the framework +// imports needed when using CocoaPods. +#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) + #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 +#endif + +#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS + #import +#else + #import "GPBProtocolBuffers.h" +#endif + +#if GOOGLE_PROTOBUF_OBJC_VERSION < 30002 +#error This file was generated by a newer version of protoc which is incompatible with your Protocol Buffer library sources. +#endif +#if 30002 < GOOGLE_PROTOBUF_OBJC_MIN_SUPPORTED_VERSION +#error This file was generated by an older version of protoc which is incompatible with your Protocol Buffer library sources. +#endif + +// @@protoc_insertion_point(imports) + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + +CF_EXTERN_C_BEGIN + +@class GAPICustomHttpPattern; +@class GAPIHttpRule; + +NS_ASSUME_NONNULL_BEGIN + +#pragma mark - GAPIHTTPRoot + +/** + * Exposes the extension registry for this file. + * + * The base class provides: + * @code + * + (GPBExtensionRegistry *)extensionRegistry; + * @endcode + * which is a @c GPBExtensionRegistry that includes all the extensions defined by + * this file and all files that it depends on. + **/ +@interface GAPIHTTPRoot : GPBRootObject +@end + +#pragma mark - GAPIHttp + +typedef GPB_ENUM(GAPIHttp_FieldNumber) { + GAPIHttp_FieldNumber_RulesArray = 1, + GAPIHttp_FieldNumber_FullyDecodeReservedExpansion = 2, +}; + +/** + * Defines the HTTP configuration for an API service. It contains a list of + * [HttpRule][google.api.HttpRule], each specifying the mapping of an RPC method + * to one or more HTTP REST API methods. + **/ +@interface GAPIHttp : GPBMessage + +/** + * A list of HTTP configuration rules that apply to individual API methods. + * + * **NOTE:** All service configuration rules follow "last one wins" order. + **/ +@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *rulesArray; +/** The number of items in @c rulesArray without causing the array to be created. */ +@property(nonatomic, readonly) NSUInteger rulesArray_Count; + +/** + * When set to true, URL path parmeters will be fully URI-decoded except in + * cases of single segment matches in reserved expansion, where "%2F" will be + * left encoded. + * + * The default behavior is to not decode RFC 6570 reserved characters in multi + * segment matches. + **/ +@property(nonatomic, readwrite) BOOL fullyDecodeReservedExpansion; + +@end + +#pragma mark - GAPIHttpRule + +typedef GPB_ENUM(GAPIHttpRule_FieldNumber) { + GAPIHttpRule_FieldNumber_Selector = 1, + GAPIHttpRule_FieldNumber_Get = 2, + GAPIHttpRule_FieldNumber_Put = 3, + GAPIHttpRule_FieldNumber_Post = 4, + GAPIHttpRule_FieldNumber_Delete_p = 5, + GAPIHttpRule_FieldNumber_Patch = 6, + GAPIHttpRule_FieldNumber_Body = 7, + GAPIHttpRule_FieldNumber_Custom = 8, + GAPIHttpRule_FieldNumber_AdditionalBindingsArray = 11, +}; + +typedef GPB_ENUM(GAPIHttpRule_Pattern_OneOfCase) { + GAPIHttpRule_Pattern_OneOfCase_GPBUnsetOneOfCase = 0, + GAPIHttpRule_Pattern_OneOfCase_Get = 2, + GAPIHttpRule_Pattern_OneOfCase_Put = 3, + GAPIHttpRule_Pattern_OneOfCase_Post = 4, + GAPIHttpRule_Pattern_OneOfCase_Delete_p = 5, + GAPIHttpRule_Pattern_OneOfCase_Patch = 6, + GAPIHttpRule_Pattern_OneOfCase_Custom = 8, +}; + +/** + * `HttpRule` defines the mapping of an RPC method to one or more HTTP + * REST API methods. The mapping specifies how different portions of the RPC + * request message are mapped to URL path, URL query parameters, and + * HTTP request body. The mapping is typically specified as an + * `google.api.http` annotation on the RPC method, + * see "google/api/annotations.proto" for details. + * + * The mapping consists of a field specifying the path template and + * method kind. The path template can refer to fields in the request + * message, as in the example below which describes a REST GET + * operation on a resource collection of messages: + * + * + * service Messaging { + * rpc GetMessage(GetMessageRequest) returns (Message) { + * option (google.api.http).get = "/v1/messages/{message_id}/{sub.subfield}"; + * } + * } + * message GetMessageRequest { + * message SubMessage { + * string subfield = 1; + * } + * string message_id = 1; // mapped to the URL + * SubMessage sub = 2; // `sub.subfield` is url-mapped + * } + * message Message { + * string text = 1; // content of the resource + * } + * + * The same http annotation can alternatively be expressed inside the + * `GRPC API Configuration` YAML file. + * + * http: + * rules: + * - selector: .Messaging.GetMessage + * get: /v1/messages/{message_id}/{sub.subfield} + * + * This definition enables an automatic, bidrectional mapping of HTTP + * JSON to RPC. Example: + * + * HTTP | RPC + * -----|----- + * `GET /v1/messages/123456/foo` | `GetMessage(message_id: "123456" sub: SubMessage(subfield: "foo"))` + * + * In general, not only fields but also field paths can be referenced + * from a path pattern. Fields mapped to the path pattern cannot be + * repeated and must have a primitive (non-message) type. + * + * Any fields in the request message which are not bound by the path + * pattern automatically become (optional) HTTP query + * parameters. Assume the following definition of the request message: + * + * + * service Messaging { + * rpc GetMessage(GetMessageRequest) returns (Message) { + * option (google.api.http).get = "/v1/messages/{message_id}"; + * } + * } + * message GetMessageRequest { + * message SubMessage { + * string subfield = 1; + * } + * string message_id = 1; // mapped to the URL + * int64 revision = 2; // becomes a parameter + * SubMessage sub = 3; // `sub.subfield` becomes a parameter + * } + * + * + * This enables a HTTP JSON to RPC mapping as below: + * + * HTTP | RPC + * -----|----- + * `GET /v1/messages/123456?revision=2&sub.subfield=foo` | `GetMessage(message_id: "123456" revision: 2 sub: SubMessage(subfield: "foo"))` + * + * Note that fields which are mapped to HTTP parameters must have a + * primitive type or a repeated primitive type. Message types are not + * allowed. In the case of a repeated type, the parameter can be + * repeated in the URL, as in `...?param=A¶m=B`. + * + * For HTTP method kinds which allow a request body, the `body` field + * specifies the mapping. Consider a REST update method on the + * message resource collection: + * + * + * service Messaging { + * rpc UpdateMessage(UpdateMessageRequest) returns (Message) { + * option (google.api.http) = { + * put: "/v1/messages/{message_id}" + * body: "message" + * }; + * } + * } + * message UpdateMessageRequest { + * string message_id = 1; // mapped to the URL + * Message message = 2; // mapped to the body + * } + * + * + * The following HTTP JSON to RPC mapping is enabled, where the + * representation of the JSON in the request body is determined by + * protos JSON encoding: + * + * HTTP | RPC + * -----|----- + * `PUT /v1/messages/123456 { "text": "Hi!" }` | `UpdateMessage(message_id: "123456" message { text: "Hi!" })` + * + * The special name `*` can be used in the body mapping to define that + * every field not bound by the path template should be mapped to the + * request body. This enables the following alternative definition of + * the update method: + * + * service Messaging { + * rpc UpdateMessage(Message) returns (Message) { + * option (google.api.http) = { + * put: "/v1/messages/{message_id}" + * body: "*" + * }; + * } + * } + * message Message { + * string message_id = 1; + * string text = 2; + * } + * + * + * The following HTTP JSON to RPC mapping is enabled: + * + * HTTP | RPC + * -----|----- + * `PUT /v1/messages/123456 { "text": "Hi!" }` | `UpdateMessage(message_id: "123456" text: "Hi!")` + * + * Note that when using `*` in the body mapping, it is not possible to + * have HTTP parameters, as all fields not bound by the path end in + * the body. This makes this option more rarely used in practice of + * defining REST APIs. The common usage of `*` is in custom methods + * which don't use the URL at all for transferring data. + * + * It is possible to define multiple HTTP methods for one RPC by using + * the `additional_bindings` option. Example: + * + * service Messaging { + * rpc GetMessage(GetMessageRequest) returns (Message) { + * option (google.api.http) = { + * get: "/v1/messages/{message_id}" + * additional_bindings { + * get: "/v1/users/{user_id}/messages/{message_id}" + * } + * }; + * } + * } + * message GetMessageRequest { + * string message_id = 1; + * string user_id = 2; + * } + * + * + * This enables the following two alternative HTTP JSON to RPC + * mappings: + * + * HTTP | RPC + * -----|----- + * `GET /v1/messages/123456` | `GetMessage(message_id: "123456")` + * `GET /v1/users/me/messages/123456` | `GetMessage(user_id: "me" message_id: "123456")` + * + * # Rules for HTTP mapping + * + * The rules for mapping HTTP path, query parameters, and body fields + * to the request message are as follows: + * + * 1. The `body` field specifies either `*` or a field path, or is + * omitted. If omitted, it indicates there is no HTTP request body. + * 2. Leaf fields (recursive expansion of nested messages in the + * request) can be classified into three types: + * (a) Matched in the URL template. + * (b) Covered by body (if body is `*`, everything except (a) fields; + * else everything under the body field) + * (c) All other fields. + * 3. URL query parameters found in the HTTP request are mapped to (c) fields. + * 4. Any body sent with an HTTP request can contain only (b) fields. + * + * The syntax of the path template is as follows: + * + * Template = "/" Segments [ Verb ] ; + * Segments = Segment { "/" Segment } ; + * Segment = "*" | "**" | LITERAL | Variable ; + * Variable = "{" FieldPath [ "=" Segments ] "}" ; + * FieldPath = IDENT { "." IDENT } ; + * Verb = ":" LITERAL ; + * + * The syntax `*` matches a single path segment. The syntax `**` matches zero + * or more path segments, which must be the last part of the path except the + * `Verb`. The syntax `LITERAL` matches literal text in the path. + * + * The syntax `Variable` matches part of the URL path as specified by its + * template. A variable template must not contain other variables. If a variable + * matches a single path segment, its template may be omitted, e.g. `{var}` + * is equivalent to `{var=*}`. + * + * If a variable contains exactly one path segment, such as `"{var}"` or + * `"{var=*}"`, when such a variable is expanded into a URL path, all characters + * except `[-_.~0-9a-zA-Z]` are percent-encoded. Such variables show up in the + * Discovery Document as `{var}`. + * + * If a variable contains one or more path segments, such as `"{var=foo/\*}"` + * or `"{var=**}"`, when such a variable is expanded into a URL path, all + * characters except `[-_.~/0-9a-zA-Z]` are percent-encoded. Such variables + * show up in the Discovery Document as `{+var}`. + * + * NOTE: While the single segment variable matches the semantics of + * [RFC 6570](https://tools.ietf.org/html/rfc6570) Section 3.2.2 + * Simple String Expansion, the multi segment variable **does not** match + * RFC 6570 Reserved Expansion. The reason is that the Reserved Expansion + * does not expand special characters like `?` and `#`, which would lead + * to invalid URLs. + * + * NOTE: the field paths in variables and in the `body` must not refer to + * repeated fields or map fields. + **/ +@interface GAPIHttpRule : GPBMessage + +/** + * Selects methods to which this rule applies. + * + * Refer to [selector][google.api.DocumentationRule.selector] for syntax details. + **/ +@property(nonatomic, readwrite, copy, null_resettable) NSString *selector; + +/** + * Determines the URL pattern is matched by this rules. This pattern can be + * used with any of the {get|put|post|delete|patch} methods. A custom method + * can be defined using the 'custom' field. + **/ +@property(nonatomic, readonly) GAPIHttpRule_Pattern_OneOfCase patternOneOfCase; + +/** Used for listing and getting information about resources. */ +@property(nonatomic, readwrite, copy, null_resettable) NSString *get; + +/** Used for updating a resource. */ +@property(nonatomic, readwrite, copy, null_resettable) NSString *put; + +/** Used for creating a resource. */ +@property(nonatomic, readwrite, copy, null_resettable) NSString *post; + +/** Used for deleting a resource. */ +@property(nonatomic, readwrite, copy, null_resettable) NSString *delete_p; + +/** Used for updating a resource. */ +@property(nonatomic, readwrite, copy, null_resettable) NSString *patch; + +/** + * The custom pattern is used for specifying an HTTP method that is not + * included in the `pattern` field, such as HEAD, or "*" to leave the + * HTTP method unspecified for this rule. The wild-card rule is useful + * for services that provide content to Web (HTML) clients. + **/ +@property(nonatomic, readwrite, strong, null_resettable) GAPICustomHttpPattern *custom; + +/** + * The name of the request field whose value is mapped to the HTTP body, or + * `*` for mapping all fields not captured by the path pattern to the HTTP + * body. NOTE: the referred field must not be a repeated field and must be + * present at the top-level of request message type. + **/ +@property(nonatomic, readwrite, copy, null_resettable) NSString *body; + +/** + * Additional HTTP bindings for the selector. Nested bindings must + * not contain an `additional_bindings` field themselves (that is, + * the nesting may only be one level deep). + **/ +@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *additionalBindingsArray; +/** The number of items in @c additionalBindingsArray without causing the array to be created. */ +@property(nonatomic, readonly) NSUInteger additionalBindingsArray_Count; + +@end + +/** + * Clears whatever value was set for the oneof 'pattern'. + **/ +void GAPIHttpRule_ClearPatternOneOfCase(GAPIHttpRule *message); + +#pragma mark - GAPICustomHttpPattern + +typedef GPB_ENUM(GAPICustomHttpPattern_FieldNumber) { + GAPICustomHttpPattern_FieldNumber_Kind = 1, + GAPICustomHttpPattern_FieldNumber_Path = 2, +}; + +/** + * A custom pattern is used for defining custom HTTP verb. + **/ +@interface GAPICustomHttpPattern : GPBMessage + +/** The name of this custom HTTP verb. */ +@property(nonatomic, readwrite, copy, null_resettable) NSString *kind; + +/** The path matched by this custom verb. */ +@property(nonatomic, readwrite, copy, null_resettable) NSString *path; + +@end + +NS_ASSUME_NONNULL_END + +CF_EXTERN_C_END + +#pragma clang diagnostic pop + +// @@protoc_insertion_point(global_scope) diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/objc/google/api/HTTP.pbobjc.m b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/objc/google/api/HTTP.pbobjc.m new file mode 100644 index 0000000..4ae8e11 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/objc/google/api/HTTP.pbobjc.m @@ -0,0 +1,316 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/api/http.proto + +// This CPP symbol can be defined to use imports that match up to the framework +// imports needed when using CocoaPods. +#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) + #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 +#endif + +#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS + #import +#else + #import "GPBProtocolBuffers_RuntimeSupport.h" +#endif + + #import "HTTP.pbobjc.h" +// @@protoc_insertion_point(imports) + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" +#pragma clang diagnostic ignored "-Wdirect-ivar-access" + +#pragma mark - GAPIHTTPRoot + +@implementation GAPIHTTPRoot + +// No extensions in the file and no imports, so no need to generate +// +extensionRegistry. + +@end + +#pragma mark - GAPIHTTPRoot_FileDescriptor + +static GPBFileDescriptor *GAPIHTTPRoot_FileDescriptor(void) { + // This is called by +initialize so there is no need to worry + // about thread safety of the singleton. + static GPBFileDescriptor *descriptor = NULL; + if (!descriptor) { + GPB_DEBUG_CHECK_RUNTIME_VERSIONS(); + descriptor = [[GPBFileDescriptor alloc] initWithPackage:@"google.api" + objcPrefix:@"GAPI" + syntax:GPBFileSyntaxProto3]; + } + return descriptor; +} + +#pragma mark - GAPIHttp + +@implementation GAPIHttp + +@dynamic rulesArray, rulesArray_Count; +@dynamic fullyDecodeReservedExpansion; + +typedef struct GAPIHttp__storage_ { + uint32_t _has_storage_[1]; + NSMutableArray *rulesArray; +} GAPIHttp__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "rulesArray", + .dataTypeSpecific.className = GPBStringifySymbol(GAPIHttpRule), + .number = GAPIHttp_FieldNumber_RulesArray, + .hasIndex = GPBNoHasBit, + .offset = (uint32_t)offsetof(GAPIHttp__storage_, rulesArray), + .flags = GPBFieldRepeated, + .dataType = GPBDataTypeMessage, + }, + { + .name = "fullyDecodeReservedExpansion", + .dataTypeSpecific.className = NULL, + .number = GAPIHttp_FieldNumber_FullyDecodeReservedExpansion, + .hasIndex = 0, + .offset = 1, // Stored in _has_storage_ to save space. + .flags = GPBFieldOptional, + .dataType = GPBDataTypeBool, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GAPIHttp class] + rootClass:[GAPIHTTPRoot class] + file:GAPIHTTPRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GAPIHttp__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - GAPIHttpRule + +@implementation GAPIHttpRule + +@dynamic patternOneOfCase; +@dynamic selector; +@dynamic get; +@dynamic put; +@dynamic post; +@dynamic delete_p; +@dynamic patch; +@dynamic custom; +@dynamic body; +@dynamic additionalBindingsArray, additionalBindingsArray_Count; + +typedef struct GAPIHttpRule__storage_ { + uint32_t _has_storage_[2]; + NSString *selector; + NSString *get; + NSString *put; + NSString *post; + NSString *delete_p; + NSString *patch; + NSString *body; + GAPICustomHttpPattern *custom; + NSMutableArray *additionalBindingsArray; +} GAPIHttpRule__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "selector", + .dataTypeSpecific.className = NULL, + .number = GAPIHttpRule_FieldNumber_Selector, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GAPIHttpRule__storage_, selector), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "get", + .dataTypeSpecific.className = NULL, + .number = GAPIHttpRule_FieldNumber_Get, + .hasIndex = -1, + .offset = (uint32_t)offsetof(GAPIHttpRule__storage_, get), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "put", + .dataTypeSpecific.className = NULL, + .number = GAPIHttpRule_FieldNumber_Put, + .hasIndex = -1, + .offset = (uint32_t)offsetof(GAPIHttpRule__storage_, put), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "post", + .dataTypeSpecific.className = NULL, + .number = GAPIHttpRule_FieldNumber_Post, + .hasIndex = -1, + .offset = (uint32_t)offsetof(GAPIHttpRule__storage_, post), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "delete_p", + .dataTypeSpecific.className = NULL, + .number = GAPIHttpRule_FieldNumber_Delete_p, + .hasIndex = -1, + .offset = (uint32_t)offsetof(GAPIHttpRule__storage_, delete_p), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "patch", + .dataTypeSpecific.className = NULL, + .number = GAPIHttpRule_FieldNumber_Patch, + .hasIndex = -1, + .offset = (uint32_t)offsetof(GAPIHttpRule__storage_, patch), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "body", + .dataTypeSpecific.className = NULL, + .number = GAPIHttpRule_FieldNumber_Body, + .hasIndex = 1, + .offset = (uint32_t)offsetof(GAPIHttpRule__storage_, body), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "custom", + .dataTypeSpecific.className = GPBStringifySymbol(GAPICustomHttpPattern), + .number = GAPIHttpRule_FieldNumber_Custom, + .hasIndex = -1, + .offset = (uint32_t)offsetof(GAPIHttpRule__storage_, custom), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + { + .name = "additionalBindingsArray", + .dataTypeSpecific.className = GPBStringifySymbol(GAPIHttpRule), + .number = GAPIHttpRule_FieldNumber_AdditionalBindingsArray, + .hasIndex = GPBNoHasBit, + .offset = (uint32_t)offsetof(GAPIHttpRule__storage_, additionalBindingsArray), + .flags = GPBFieldRepeated, + .dataType = GPBDataTypeMessage, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GAPIHttpRule class] + rootClass:[GAPIHTTPRoot class] + file:GAPIHTTPRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GAPIHttpRule__storage_) + flags:GPBDescriptorInitializationFlag_None]; + static const char *oneofs[] = { + "pattern", + }; + [localDescriptor setupOneofs:oneofs + count:(uint32_t)(sizeof(oneofs) / sizeof(char*)) + firstHasIndex:-1]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +void GAPIHttpRule_ClearPatternOneOfCase(GAPIHttpRule *message) { + GPBDescriptor *descriptor = [message descriptor]; + GPBOneofDescriptor *oneof = [descriptor.oneofs objectAtIndex:0]; + GPBMaybeClearOneof(message, oneof, -1, 0); +} +#pragma mark - GAPICustomHttpPattern + +@implementation GAPICustomHttpPattern + +@dynamic kind; +@dynamic path; + +typedef struct GAPICustomHttpPattern__storage_ { + uint32_t _has_storage_[1]; + NSString *kind; + NSString *path; +} GAPICustomHttpPattern__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "kind", + .dataTypeSpecific.className = NULL, + .number = GAPICustomHttpPattern_FieldNumber_Kind, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GAPICustomHttpPattern__storage_, kind), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "path", + .dataTypeSpecific.className = NULL, + .number = GAPICustomHttpPattern_FieldNumber_Path, + .hasIndex = 1, + .offset = (uint32_t)offsetof(GAPICustomHttpPattern__storage_, path), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GAPICustomHttpPattern class] + rootClass:[GAPIHTTPRoot class] + file:GAPIHTTPRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GAPICustomHttpPattern__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + + +#pragma clang diagnostic pop + +// @@protoc_insertion_point(global_scope) diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/objc/google/firestore/v1/Common.pbobjc.h b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/objc/google/firestore/v1/Common.pbobjc.h new file mode 100644 index 0000000..0ffe06a --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/objc/google/firestore/v1/Common.pbobjc.h @@ -0,0 +1,223 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/firestore/v1/common.proto + +// This CPP symbol can be defined to use imports that match up to the framework +// imports needed when using CocoaPods. +#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) + #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 +#endif + +#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS + #import +#else + #import "GPBProtocolBuffers.h" +#endif + +#if GOOGLE_PROTOBUF_OBJC_VERSION < 30002 +#error This file was generated by a newer version of protoc which is incompatible with your Protocol Buffer library sources. +#endif +#if 30002 < GOOGLE_PROTOBUF_OBJC_MIN_SUPPORTED_VERSION +#error This file was generated by an older version of protoc which is incompatible with your Protocol Buffer library sources. +#endif + +// @@protoc_insertion_point(imports) + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + +CF_EXTERN_C_BEGIN + +@class GCFSTransactionOptions_ReadOnly; +@class GCFSTransactionOptions_ReadWrite; +@class GPBTimestamp; + +NS_ASSUME_NONNULL_BEGIN + +#pragma mark - GCFSCommonRoot + +/** + * Exposes the extension registry for this file. + * + * The base class provides: + * @code + * + (GPBExtensionRegistry *)extensionRegistry; + * @endcode + * which is a @c GPBExtensionRegistry that includes all the extensions defined by + * this file and all files that it depends on. + **/ +@interface GCFSCommonRoot : GPBRootObject +@end + +#pragma mark - GCFSDocumentMask + +typedef GPB_ENUM(GCFSDocumentMask_FieldNumber) { + GCFSDocumentMask_FieldNumber_FieldPathsArray = 1, +}; + +/** + * A set of field paths on a document. + * Used to restrict a get or update operation on a document to a subset of its + * fields. + * This is different from standard field masks, as this is always scoped to a + * [Document][google.firestore.v1.Document], and takes in account the dynamic nature of [Value][google.firestore.v1.Value]. + **/ +@interface GCFSDocumentMask : GPBMessage + +/** + * The list of field paths in the mask. See [Document.fields][google.firestore.v1.Document.fields] for a field + * path syntax reference. + **/ +@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *fieldPathsArray; +/** The number of items in @c fieldPathsArray without causing the array to be created. */ +@property(nonatomic, readonly) NSUInteger fieldPathsArray_Count; + +@end + +#pragma mark - GCFSPrecondition + +typedef GPB_ENUM(GCFSPrecondition_FieldNumber) { + GCFSPrecondition_FieldNumber_Exists = 1, + GCFSPrecondition_FieldNumber_UpdateTime = 2, +}; + +typedef GPB_ENUM(GCFSPrecondition_ConditionType_OneOfCase) { + GCFSPrecondition_ConditionType_OneOfCase_GPBUnsetOneOfCase = 0, + GCFSPrecondition_ConditionType_OneOfCase_Exists = 1, + GCFSPrecondition_ConditionType_OneOfCase_UpdateTime = 2, +}; + +/** + * A precondition on a document, used for conditional operations. + **/ +@interface GCFSPrecondition : GPBMessage + +/** The type of precondition. */ +@property(nonatomic, readonly) GCFSPrecondition_ConditionType_OneOfCase conditionTypeOneOfCase; + +/** + * When set to `true`, the target document must exist. + * When set to `false`, the target document must not exist. + **/ +@property(nonatomic, readwrite) BOOL exists; + +/** + * When set, the target document must exist and have been last updated at + * that time. + **/ +@property(nonatomic, readwrite, strong, null_resettable) GPBTimestamp *updateTime; + +@end + +/** + * Clears whatever value was set for the oneof 'conditionType'. + **/ +void GCFSPrecondition_ClearConditionTypeOneOfCase(GCFSPrecondition *message); + +#pragma mark - GCFSTransactionOptions + +typedef GPB_ENUM(GCFSTransactionOptions_FieldNumber) { + GCFSTransactionOptions_FieldNumber_ReadOnly = 2, + GCFSTransactionOptions_FieldNumber_ReadWrite = 3, +}; + +typedef GPB_ENUM(GCFSTransactionOptions_Mode_OneOfCase) { + GCFSTransactionOptions_Mode_OneOfCase_GPBUnsetOneOfCase = 0, + GCFSTransactionOptions_Mode_OneOfCase_ReadOnly = 2, + GCFSTransactionOptions_Mode_OneOfCase_ReadWrite = 3, +}; + +/** + * Options for creating a new transaction. + **/ +@interface GCFSTransactionOptions : GPBMessage + +/** The mode of the transaction. */ +@property(nonatomic, readonly) GCFSTransactionOptions_Mode_OneOfCase modeOneOfCase; + +/** The transaction can only be used for read operations. */ +@property(nonatomic, readwrite, strong, null_resettable) GCFSTransactionOptions_ReadOnly *readOnly; + +/** The transaction can be used for both read and write operations. */ +@property(nonatomic, readwrite, strong, null_resettable) GCFSTransactionOptions_ReadWrite *readWrite; + +@end + +/** + * Clears whatever value was set for the oneof 'mode'. + **/ +void GCFSTransactionOptions_ClearModeOneOfCase(GCFSTransactionOptions *message); + +#pragma mark - GCFSTransactionOptions_ReadWrite + +typedef GPB_ENUM(GCFSTransactionOptions_ReadWrite_FieldNumber) { + GCFSTransactionOptions_ReadWrite_FieldNumber_RetryTransaction = 1, +}; + +/** + * Options for a transaction that can be used to read and write documents. + **/ +@interface GCFSTransactionOptions_ReadWrite : GPBMessage + +/** An optional transaction to retry. */ +@property(nonatomic, readwrite, copy, null_resettable) NSData *retryTransaction; + +@end + +#pragma mark - GCFSTransactionOptions_ReadOnly + +typedef GPB_ENUM(GCFSTransactionOptions_ReadOnly_FieldNumber) { + GCFSTransactionOptions_ReadOnly_FieldNumber_ReadTime = 2, +}; + +typedef GPB_ENUM(GCFSTransactionOptions_ReadOnly_ConsistencySelector_OneOfCase) { + GCFSTransactionOptions_ReadOnly_ConsistencySelector_OneOfCase_GPBUnsetOneOfCase = 0, + GCFSTransactionOptions_ReadOnly_ConsistencySelector_OneOfCase_ReadTime = 2, +}; + +/** + * Options for a transaction that can only be used to read documents. + **/ +@interface GCFSTransactionOptions_ReadOnly : GPBMessage + +/** + * The consistency mode for this transaction. If not set, defaults to strong + * consistency. + **/ +@property(nonatomic, readonly) GCFSTransactionOptions_ReadOnly_ConsistencySelector_OneOfCase consistencySelectorOneOfCase; + +/** + * Reads documents at the given time. + * This may not be older than 60 seconds. + **/ +@property(nonatomic, readwrite, strong, null_resettable) GPBTimestamp *readTime; + +@end + +/** + * Clears whatever value was set for the oneof 'consistencySelector'. + **/ +void GCFSTransactionOptions_ReadOnly_ClearConsistencySelectorOneOfCase(GCFSTransactionOptions_ReadOnly *message); + +NS_ASSUME_NONNULL_END + +CF_EXTERN_C_END + +#pragma clang diagnostic pop + +// @@protoc_insertion_point(global_scope) diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/objc/google/firestore/v1/Common.pbobjc.m b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/objc/google/firestore/v1/Common.pbobjc.m new file mode 100644 index 0000000..cf112ba --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/objc/google/firestore/v1/Common.pbobjc.m @@ -0,0 +1,345 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/firestore/v1/common.proto + +// This CPP symbol can be defined to use imports that match up to the framework +// imports needed when using CocoaPods. +#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) + #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 +#endif + +#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS + #import +#else + #import "GPBProtocolBuffers_RuntimeSupport.h" +#endif + +#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS + #import +#else + #import "Timestamp.pbobjc.h" +#endif + + #import "Common.pbobjc.h" + #import "Annotations.pbobjc.h" +// @@protoc_insertion_point(imports) + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" +#pragma clang diagnostic ignored "-Wdirect-ivar-access" + +#pragma mark - GCFSCommonRoot + +@implementation GCFSCommonRoot + + +@end + +#pragma mark - GCFSCommonRoot_FileDescriptor + +static GPBFileDescriptor *GCFSCommonRoot_FileDescriptor(void) { + // This is called by +initialize so there is no need to worry + // about thread safety of the singleton. + static GPBFileDescriptor *descriptor = NULL; + if (!descriptor) { + GPB_DEBUG_CHECK_RUNTIME_VERSIONS(); + descriptor = [[GPBFileDescriptor alloc] initWithPackage:@"google.firestore.v1" + objcPrefix:@"GCFS" + syntax:GPBFileSyntaxProto3]; + } + return descriptor; +} + +#pragma mark - GCFSDocumentMask + +@implementation GCFSDocumentMask + +@dynamic fieldPathsArray, fieldPathsArray_Count; + +typedef struct GCFSDocumentMask__storage_ { + uint32_t _has_storage_[1]; + NSMutableArray *fieldPathsArray; +} GCFSDocumentMask__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "fieldPathsArray", + .dataTypeSpecific.className = NULL, + .number = GCFSDocumentMask_FieldNumber_FieldPathsArray, + .hasIndex = GPBNoHasBit, + .offset = (uint32_t)offsetof(GCFSDocumentMask__storage_, fieldPathsArray), + .flags = GPBFieldRepeated, + .dataType = GPBDataTypeString, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GCFSDocumentMask class] + rootClass:[GCFSCommonRoot class] + file:GCFSCommonRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GCFSDocumentMask__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - GCFSPrecondition + +@implementation GCFSPrecondition + +@dynamic conditionTypeOneOfCase; +@dynamic exists; +@dynamic updateTime; + +typedef struct GCFSPrecondition__storage_ { + uint32_t _has_storage_[2]; + GPBTimestamp *updateTime; +} GCFSPrecondition__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "exists", + .dataTypeSpecific.className = NULL, + .number = GCFSPrecondition_FieldNumber_Exists, + .hasIndex = -1, + .offset = 0, // Stored in _has_storage_ to save space. + .flags = GPBFieldOptional, + .dataType = GPBDataTypeBool, + }, + { + .name = "updateTime", + .dataTypeSpecific.className = GPBStringifySymbol(GPBTimestamp), + .number = GCFSPrecondition_FieldNumber_UpdateTime, + .hasIndex = -1, + .offset = (uint32_t)offsetof(GCFSPrecondition__storage_, updateTime), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GCFSPrecondition class] + rootClass:[GCFSCommonRoot class] + file:GCFSCommonRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GCFSPrecondition__storage_) + flags:GPBDescriptorInitializationFlag_None]; + static const char *oneofs[] = { + "conditionType", + }; + [localDescriptor setupOneofs:oneofs + count:(uint32_t)(sizeof(oneofs) / sizeof(char*)) + firstHasIndex:-1]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +void GCFSPrecondition_ClearConditionTypeOneOfCase(GCFSPrecondition *message) { + GPBDescriptor *descriptor = [message descriptor]; + GPBOneofDescriptor *oneof = [descriptor.oneofs objectAtIndex:0]; + GPBMaybeClearOneof(message, oneof, -1, 0); +} +#pragma mark - GCFSTransactionOptions + +@implementation GCFSTransactionOptions + +@dynamic modeOneOfCase; +@dynamic readOnly; +@dynamic readWrite; + +typedef struct GCFSTransactionOptions__storage_ { + uint32_t _has_storage_[2]; + GCFSTransactionOptions_ReadOnly *readOnly; + GCFSTransactionOptions_ReadWrite *readWrite; +} GCFSTransactionOptions__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "readOnly", + .dataTypeSpecific.className = GPBStringifySymbol(GCFSTransactionOptions_ReadOnly), + .number = GCFSTransactionOptions_FieldNumber_ReadOnly, + .hasIndex = -1, + .offset = (uint32_t)offsetof(GCFSTransactionOptions__storage_, readOnly), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + { + .name = "readWrite", + .dataTypeSpecific.className = GPBStringifySymbol(GCFSTransactionOptions_ReadWrite), + .number = GCFSTransactionOptions_FieldNumber_ReadWrite, + .hasIndex = -1, + .offset = (uint32_t)offsetof(GCFSTransactionOptions__storage_, readWrite), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GCFSTransactionOptions class] + rootClass:[GCFSCommonRoot class] + file:GCFSCommonRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GCFSTransactionOptions__storage_) + flags:GPBDescriptorInitializationFlag_None]; + static const char *oneofs[] = { + "mode", + }; + [localDescriptor setupOneofs:oneofs + count:(uint32_t)(sizeof(oneofs) / sizeof(char*)) + firstHasIndex:-1]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +void GCFSTransactionOptions_ClearModeOneOfCase(GCFSTransactionOptions *message) { + GPBDescriptor *descriptor = [message descriptor]; + GPBOneofDescriptor *oneof = [descriptor.oneofs objectAtIndex:0]; + GPBMaybeClearOneof(message, oneof, -1, 0); +} +#pragma mark - GCFSTransactionOptions_ReadWrite + +@implementation GCFSTransactionOptions_ReadWrite + +@dynamic retryTransaction; + +typedef struct GCFSTransactionOptions_ReadWrite__storage_ { + uint32_t _has_storage_[1]; + NSData *retryTransaction; +} GCFSTransactionOptions_ReadWrite__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "retryTransaction", + .dataTypeSpecific.className = NULL, + .number = GCFSTransactionOptions_ReadWrite_FieldNumber_RetryTransaction, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GCFSTransactionOptions_ReadWrite__storage_, retryTransaction), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeBytes, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GCFSTransactionOptions_ReadWrite class] + rootClass:[GCFSCommonRoot class] + file:GCFSCommonRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GCFSTransactionOptions_ReadWrite__storage_) + flags:GPBDescriptorInitializationFlag_None]; + [localDescriptor setupContainingMessageClassName:GPBStringifySymbol(GCFSTransactionOptions)]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - GCFSTransactionOptions_ReadOnly + +@implementation GCFSTransactionOptions_ReadOnly + +@dynamic consistencySelectorOneOfCase; +@dynamic readTime; + +typedef struct GCFSTransactionOptions_ReadOnly__storage_ { + uint32_t _has_storage_[2]; + GPBTimestamp *readTime; +} GCFSTransactionOptions_ReadOnly__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "readTime", + .dataTypeSpecific.className = GPBStringifySymbol(GPBTimestamp), + .number = GCFSTransactionOptions_ReadOnly_FieldNumber_ReadTime, + .hasIndex = -1, + .offset = (uint32_t)offsetof(GCFSTransactionOptions_ReadOnly__storage_, readTime), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GCFSTransactionOptions_ReadOnly class] + rootClass:[GCFSCommonRoot class] + file:GCFSCommonRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GCFSTransactionOptions_ReadOnly__storage_) + flags:GPBDescriptorInitializationFlag_None]; + static const char *oneofs[] = { + "consistencySelector", + }; + [localDescriptor setupOneofs:oneofs + count:(uint32_t)(sizeof(oneofs) / sizeof(char*)) + firstHasIndex:-1]; + [localDescriptor setupContainingMessageClassName:GPBStringifySymbol(GCFSTransactionOptions)]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +void GCFSTransactionOptions_ReadOnly_ClearConsistencySelectorOneOfCase(GCFSTransactionOptions_ReadOnly *message) { + GPBDescriptor *descriptor = [message descriptor]; + GPBOneofDescriptor *oneof = [descriptor.oneofs objectAtIndex:0]; + GPBMaybeClearOneof(message, oneof, -1, 0); +} + +#pragma clang diagnostic pop + +// @@protoc_insertion_point(global_scope) diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/objc/google/firestore/v1/Document.pbobjc.h b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/objc/google/firestore/v1/Document.pbobjc.h new file mode 100644 index 0000000..f474724 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/objc/google/firestore/v1/Document.pbobjc.h @@ -0,0 +1,310 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/firestore/v1/document.proto + +// This CPP symbol can be defined to use imports that match up to the framework +// imports needed when using CocoaPods. +#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) + #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 +#endif + +#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS + #import +#else + #import "GPBProtocolBuffers.h" +#endif + +#if GOOGLE_PROTOBUF_OBJC_VERSION < 30002 +#error This file was generated by a newer version of protoc which is incompatible with your Protocol Buffer library sources. +#endif +#if 30002 < GOOGLE_PROTOBUF_OBJC_MIN_SUPPORTED_VERSION +#error This file was generated by an older version of protoc which is incompatible with your Protocol Buffer library sources. +#endif + +// @@protoc_insertion_point(imports) + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + +CF_EXTERN_C_BEGIN + +@class GCFSArrayValue; +@class GCFSMapValue; +@class GCFSValue; +@class GPBTimestamp; +@class GTPLatLng; +GPB_ENUM_FWD_DECLARE(GPBNullValue); + +NS_ASSUME_NONNULL_BEGIN + +#pragma mark - GCFSDocumentRoot + +/** + * Exposes the extension registry for this file. + * + * The base class provides: + * @code + * + (GPBExtensionRegistry *)extensionRegistry; + * @endcode + * which is a @c GPBExtensionRegistry that includes all the extensions defined by + * this file and all files that it depends on. + **/ +@interface GCFSDocumentRoot : GPBRootObject +@end + +#pragma mark - GCFSDocument + +typedef GPB_ENUM(GCFSDocument_FieldNumber) { + GCFSDocument_FieldNumber_Name = 1, + GCFSDocument_FieldNumber_Fields = 2, + GCFSDocument_FieldNumber_CreateTime = 3, + GCFSDocument_FieldNumber_UpdateTime = 4, +}; + +/** + * A Firestore document. + * + * Must not exceed 1 MiB - 4 bytes. + **/ +@interface GCFSDocument : GPBMessage + +/** + * The resource name of the document, for example + * `projects/{project_id}/databases/{database_id}/documents/{document_path}`. + **/ +@property(nonatomic, readwrite, copy, null_resettable) NSString *name; + +/** + * The document's fields. + * + * The map keys represent field names. + * + * A simple field name contains only characters `a` to `z`, `A` to `Z`, + * `0` to `9`, or `_`, and must not start with `0` to `9`. For example, + * `foo_bar_17`. + * + * Field names matching the regular expression `__.*__` are reserved. Reserved + * field names are forbidden except in certain documented contexts. The map + * keys, represented as UTF-8, must not exceed 1,500 bytes and cannot be + * empty. + * + * Field paths may be used in other contexts to refer to structured fields + * defined here. For `map_value`, the field path is represented by the simple + * or quoted field names of the containing fields, delimited by `.`. For + * example, the structured field + * `"foo" : { map_value: { "x&y" : { string_value: "hello" }}}` would be + * represented by the field path `foo.x&y`. + * + * Within a field path, a quoted field name starts and ends with `` ` `` and + * may contain any character. Some characters, including `` ` ``, must be + * escaped using a `\\`. For example, `` `x&y` `` represents `x&y` and + * `` `bak\\`tik` `` represents `` bak`tik ``. + **/ +@property(nonatomic, readwrite, strong, null_resettable) NSMutableDictionary *fields; +/** The number of items in @c fields without causing the array to be created. */ +@property(nonatomic, readonly) NSUInteger fields_Count; + +/** + * Output only. The time at which the document was created. + * + * This value increases monotonically when a document is deleted then + * recreated. It can also be compared to values from other documents and + * the `read_time` of a query. + **/ +@property(nonatomic, readwrite, strong, null_resettable) GPBTimestamp *createTime; +/** Test to see if @c createTime has been set. */ +@property(nonatomic, readwrite) BOOL hasCreateTime; + +/** + * Output only. The time at which the document was last changed. + * + * This value is initially set to the `create_time` then increases + * monotonically with each change to the document. It can also be + * compared to values from other documents and the `read_time` of a query. + **/ +@property(nonatomic, readwrite, strong, null_resettable) GPBTimestamp *updateTime; +/** Test to see if @c updateTime has been set. */ +@property(nonatomic, readwrite) BOOL hasUpdateTime; + +@end + +#pragma mark - GCFSValue + +typedef GPB_ENUM(GCFSValue_FieldNumber) { + GCFSValue_FieldNumber_BooleanValue = 1, + GCFSValue_FieldNumber_IntegerValue = 2, + GCFSValue_FieldNumber_DoubleValue = 3, + GCFSValue_FieldNumber_ReferenceValue = 5, + GCFSValue_FieldNumber_MapValue = 6, + GCFSValue_FieldNumber_GeoPointValue = 8, + GCFSValue_FieldNumber_ArrayValue = 9, + GCFSValue_FieldNumber_TimestampValue = 10, + GCFSValue_FieldNumber_NullValue = 11, + GCFSValue_FieldNumber_StringValue = 17, + GCFSValue_FieldNumber_BytesValue = 18, +}; + +typedef GPB_ENUM(GCFSValue_ValueType_OneOfCase) { + GCFSValue_ValueType_OneOfCase_GPBUnsetOneOfCase = 0, + GCFSValue_ValueType_OneOfCase_NullValue = 11, + GCFSValue_ValueType_OneOfCase_BooleanValue = 1, + GCFSValue_ValueType_OneOfCase_IntegerValue = 2, + GCFSValue_ValueType_OneOfCase_DoubleValue = 3, + GCFSValue_ValueType_OneOfCase_TimestampValue = 10, + GCFSValue_ValueType_OneOfCase_StringValue = 17, + GCFSValue_ValueType_OneOfCase_BytesValue = 18, + GCFSValue_ValueType_OneOfCase_ReferenceValue = 5, + GCFSValue_ValueType_OneOfCase_GeoPointValue = 8, + GCFSValue_ValueType_OneOfCase_ArrayValue = 9, + GCFSValue_ValueType_OneOfCase_MapValue = 6, +}; + +/** + * A message that can hold any of the supported value types. + **/ +@interface GCFSValue : GPBMessage + +/** Must have a value set. */ +@property(nonatomic, readonly) GCFSValue_ValueType_OneOfCase valueTypeOneOfCase; + +/** A null value. */ +@property(nonatomic, readwrite) enum GPBNullValue nullValue; + +/** A boolean value. */ +@property(nonatomic, readwrite) BOOL booleanValue; + +/** An integer value. */ +@property(nonatomic, readwrite) int64_t integerValue; + +/** A double value. */ +@property(nonatomic, readwrite) double doubleValue; + +/** + * A timestamp value. + * + * Precise only to microseconds. When stored, any additional precision is + * rounded down. + **/ +@property(nonatomic, readwrite, strong, null_resettable) GPBTimestamp *timestampValue; + +/** + * A string value. + * + * The string, represented as UTF-8, must not exceed 1 MiB - 89 bytes. + * Only the first 1,500 bytes of the UTF-8 representation are considered by + * queries. + **/ +@property(nonatomic, readwrite, copy, null_resettable) NSString *stringValue; + +/** + * A bytes value. + * + * Must not exceed 1 MiB - 89 bytes. + * Only the first 1,500 bytes are considered by queries. + **/ +@property(nonatomic, readwrite, copy, null_resettable) NSData *bytesValue; + +/** + * A reference to a document. For example: + * `projects/{project_id}/databases/{database_id}/documents/{document_path}`. + **/ +@property(nonatomic, readwrite, copy, null_resettable) NSString *referenceValue; + +/** A geo point value representing a point on the surface of Earth. */ +@property(nonatomic, readwrite, strong, null_resettable) GTPLatLng *geoPointValue; + +/** + * An array value. + * + * Cannot directly contain another array value, though can contain an + * map which contains another array. + **/ +@property(nonatomic, readwrite, strong, null_resettable) GCFSArrayValue *arrayValue; + +/** A map value. */ +@property(nonatomic, readwrite, strong, null_resettable) GCFSMapValue *mapValue; + +@end + +/** + * Fetches the raw value of a @c GCFSValue's @c nullValue property, even + * if the value was not defined by the enum at the time the code was generated. + **/ +int32_t GCFSValue_NullValue_RawValue(GCFSValue *message); +/** + * Sets the raw value of an @c GCFSValue's @c nullValue property, allowing + * it to be set to a value that was not defined by the enum at the time the code + * was generated. + **/ +void SetGCFSValue_NullValue_RawValue(GCFSValue *message, int32_t value); + +/** + * Clears whatever value was set for the oneof 'valueType'. + **/ +void GCFSValue_ClearValueTypeOneOfCase(GCFSValue *message); + +#pragma mark - GCFSArrayValue + +typedef GPB_ENUM(GCFSArrayValue_FieldNumber) { + GCFSArrayValue_FieldNumber_ValuesArray = 1, +}; + +/** + * An array value. + **/ +@interface GCFSArrayValue : GPBMessage + +/** Values in the array. */ +@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *valuesArray; +/** The number of items in @c valuesArray without causing the array to be created. */ +@property(nonatomic, readonly) NSUInteger valuesArray_Count; + +@end + +#pragma mark - GCFSMapValue + +typedef GPB_ENUM(GCFSMapValue_FieldNumber) { + GCFSMapValue_FieldNumber_Fields = 1, +}; + +/** + * A map value. + **/ +@interface GCFSMapValue : GPBMessage + +/** + * The map's fields. + * + * The map keys represent field names. Field names matching the regular + * expression `__.*__` are reserved. Reserved field names are forbidden except + * in certain documented contexts. The map keys, represented as UTF-8, must + * not exceed 1,500 bytes and cannot be empty. + **/ +@property(nonatomic, readwrite, strong, null_resettable) NSMutableDictionary *fields; +/** The number of items in @c fields without causing the array to be created. */ +@property(nonatomic, readonly) NSUInteger fields_Count; + +@end + +NS_ASSUME_NONNULL_END + +CF_EXTERN_C_END + +#pragma clang diagnostic pop + +// @@protoc_insertion_point(global_scope) diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/objc/google/firestore/v1/Document.pbobjc.m b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/objc/google/firestore/v1/Document.pbobjc.m new file mode 100644 index 0000000..0d1c2da --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/objc/google/firestore/v1/Document.pbobjc.m @@ -0,0 +1,412 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/firestore/v1/document.proto + +// This CPP symbol can be defined to use imports that match up to the framework +// imports needed when using CocoaPods. +#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) + #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 +#endif + +#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS + #import +#else + #import "GPBProtocolBuffers_RuntimeSupport.h" +#endif + +#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS + #import + #import +#else + #import "Struct.pbobjc.h" + #import "Timestamp.pbobjc.h" +#endif + + #import "Document.pbobjc.h" + #import "Annotations.pbobjc.h" + #import "Latlng.pbobjc.h" +// @@protoc_insertion_point(imports) + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" +#pragma clang diagnostic ignored "-Wdirect-ivar-access" + +#pragma mark - GCFSDocumentRoot + +@implementation GCFSDocumentRoot + + +@end + +#pragma mark - GCFSDocumentRoot_FileDescriptor + +static GPBFileDescriptor *GCFSDocumentRoot_FileDescriptor(void) { + // This is called by +initialize so there is no need to worry + // about thread safety of the singleton. + static GPBFileDescriptor *descriptor = NULL; + if (!descriptor) { + GPB_DEBUG_CHECK_RUNTIME_VERSIONS(); + descriptor = [[GPBFileDescriptor alloc] initWithPackage:@"google.firestore.v1" + objcPrefix:@"GCFS" + syntax:GPBFileSyntaxProto3]; + } + return descriptor; +} + +#pragma mark - GCFSDocument + +@implementation GCFSDocument + +@dynamic name; +@dynamic fields, fields_Count; +@dynamic hasCreateTime, createTime; +@dynamic hasUpdateTime, updateTime; + +typedef struct GCFSDocument__storage_ { + uint32_t _has_storage_[1]; + NSString *name; + NSMutableDictionary *fields; + GPBTimestamp *createTime; + GPBTimestamp *updateTime; +} GCFSDocument__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "name", + .dataTypeSpecific.className = NULL, + .number = GCFSDocument_FieldNumber_Name, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GCFSDocument__storage_, name), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "fields", + .dataTypeSpecific.className = GPBStringifySymbol(GCFSValue), + .number = GCFSDocument_FieldNumber_Fields, + .hasIndex = GPBNoHasBit, + .offset = (uint32_t)offsetof(GCFSDocument__storage_, fields), + .flags = GPBFieldMapKeyString, + .dataType = GPBDataTypeMessage, + }, + { + .name = "createTime", + .dataTypeSpecific.className = GPBStringifySymbol(GPBTimestamp), + .number = GCFSDocument_FieldNumber_CreateTime, + .hasIndex = 1, + .offset = (uint32_t)offsetof(GCFSDocument__storage_, createTime), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + { + .name = "updateTime", + .dataTypeSpecific.className = GPBStringifySymbol(GPBTimestamp), + .number = GCFSDocument_FieldNumber_UpdateTime, + .hasIndex = 2, + .offset = (uint32_t)offsetof(GCFSDocument__storage_, updateTime), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GCFSDocument class] + rootClass:[GCFSDocumentRoot class] + file:GCFSDocumentRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GCFSDocument__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - GCFSValue + +@implementation GCFSValue + +@dynamic valueTypeOneOfCase; +@dynamic nullValue; +@dynamic booleanValue; +@dynamic integerValue; +@dynamic doubleValue; +@dynamic timestampValue; +@dynamic stringValue; +@dynamic bytesValue; +@dynamic referenceValue; +@dynamic geoPointValue; +@dynamic arrayValue; +@dynamic mapValue; + +typedef struct GCFSValue__storage_ { + uint32_t _has_storage_[2]; + GPBNullValue nullValue; + NSString *referenceValue; + GCFSMapValue *mapValue; + GTPLatLng *geoPointValue; + GCFSArrayValue *arrayValue; + GPBTimestamp *timestampValue; + NSString *stringValue; + NSData *bytesValue; + int64_t integerValue; + double doubleValue; +} GCFSValue__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "booleanValue", + .dataTypeSpecific.className = NULL, + .number = GCFSValue_FieldNumber_BooleanValue, + .hasIndex = -1, + .offset = 0, // Stored in _has_storage_ to save space. + .flags = GPBFieldOptional, + .dataType = GPBDataTypeBool, + }, + { + .name = "integerValue", + .dataTypeSpecific.className = NULL, + .number = GCFSValue_FieldNumber_IntegerValue, + .hasIndex = -1, + .offset = (uint32_t)offsetof(GCFSValue__storage_, integerValue), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt64, + }, + { + .name = "doubleValue", + .dataTypeSpecific.className = NULL, + .number = GCFSValue_FieldNumber_DoubleValue, + .hasIndex = -1, + .offset = (uint32_t)offsetof(GCFSValue__storage_, doubleValue), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeDouble, + }, + { + .name = "referenceValue", + .dataTypeSpecific.className = NULL, + .number = GCFSValue_FieldNumber_ReferenceValue, + .hasIndex = -1, + .offset = (uint32_t)offsetof(GCFSValue__storage_, referenceValue), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "mapValue", + .dataTypeSpecific.className = GPBStringifySymbol(GCFSMapValue), + .number = GCFSValue_FieldNumber_MapValue, + .hasIndex = -1, + .offset = (uint32_t)offsetof(GCFSValue__storage_, mapValue), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + { + .name = "geoPointValue", + .dataTypeSpecific.className = GPBStringifySymbol(GTPLatLng), + .number = GCFSValue_FieldNumber_GeoPointValue, + .hasIndex = -1, + .offset = (uint32_t)offsetof(GCFSValue__storage_, geoPointValue), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + { + .name = "arrayValue", + .dataTypeSpecific.className = GPBStringifySymbol(GCFSArrayValue), + .number = GCFSValue_FieldNumber_ArrayValue, + .hasIndex = -1, + .offset = (uint32_t)offsetof(GCFSValue__storage_, arrayValue), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + { + .name = "timestampValue", + .dataTypeSpecific.className = GPBStringifySymbol(GPBTimestamp), + .number = GCFSValue_FieldNumber_TimestampValue, + .hasIndex = -1, + .offset = (uint32_t)offsetof(GCFSValue__storage_, timestampValue), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + { + .name = "nullValue", + .dataTypeSpecific.enumDescFunc = GPBNullValue_EnumDescriptor, + .number = GCFSValue_FieldNumber_NullValue, + .hasIndex = -1, + .offset = (uint32_t)offsetof(GCFSValue__storage_, nullValue), + .flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldHasEnumDescriptor), + .dataType = GPBDataTypeEnum, + }, + { + .name = "stringValue", + .dataTypeSpecific.className = NULL, + .number = GCFSValue_FieldNumber_StringValue, + .hasIndex = -1, + .offset = (uint32_t)offsetof(GCFSValue__storage_, stringValue), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "bytesValue", + .dataTypeSpecific.className = NULL, + .number = GCFSValue_FieldNumber_BytesValue, + .hasIndex = -1, + .offset = (uint32_t)offsetof(GCFSValue__storage_, bytesValue), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeBytes, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GCFSValue class] + rootClass:[GCFSDocumentRoot class] + file:GCFSDocumentRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GCFSValue__storage_) + flags:GPBDescriptorInitializationFlag_None]; + static const char *oneofs[] = { + "valueType", + }; + [localDescriptor setupOneofs:oneofs + count:(uint32_t)(sizeof(oneofs) / sizeof(char*)) + firstHasIndex:-1]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +int32_t GCFSValue_NullValue_RawValue(GCFSValue *message) { + GPBDescriptor *descriptor = [GCFSValue descriptor]; + GPBFieldDescriptor *field = [descriptor fieldWithNumber:GCFSValue_FieldNumber_NullValue]; + return GPBGetMessageInt32Field(message, field); +} + +void SetGCFSValue_NullValue_RawValue(GCFSValue *message, int32_t value) { + GPBDescriptor *descriptor = [GCFSValue descriptor]; + GPBFieldDescriptor *field = [descriptor fieldWithNumber:GCFSValue_FieldNumber_NullValue]; + GPBSetInt32IvarWithFieldInternal(message, field, value, descriptor.file.syntax); +} + +void GCFSValue_ClearValueTypeOneOfCase(GCFSValue *message) { + GPBDescriptor *descriptor = [message descriptor]; + GPBOneofDescriptor *oneof = [descriptor.oneofs objectAtIndex:0]; + GPBMaybeClearOneof(message, oneof, -1, 0); +} +#pragma mark - GCFSArrayValue + +@implementation GCFSArrayValue + +@dynamic valuesArray, valuesArray_Count; + +typedef struct GCFSArrayValue__storage_ { + uint32_t _has_storage_[1]; + NSMutableArray *valuesArray; +} GCFSArrayValue__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "valuesArray", + .dataTypeSpecific.className = GPBStringifySymbol(GCFSValue), + .number = GCFSArrayValue_FieldNumber_ValuesArray, + .hasIndex = GPBNoHasBit, + .offset = (uint32_t)offsetof(GCFSArrayValue__storage_, valuesArray), + .flags = GPBFieldRepeated, + .dataType = GPBDataTypeMessage, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GCFSArrayValue class] + rootClass:[GCFSDocumentRoot class] + file:GCFSDocumentRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GCFSArrayValue__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - GCFSMapValue + +@implementation GCFSMapValue + +@dynamic fields, fields_Count; + +typedef struct GCFSMapValue__storage_ { + uint32_t _has_storage_[1]; + NSMutableDictionary *fields; +} GCFSMapValue__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "fields", + .dataTypeSpecific.className = GPBStringifySymbol(GCFSValue), + .number = GCFSMapValue_FieldNumber_Fields, + .hasIndex = GPBNoHasBit, + .offset = (uint32_t)offsetof(GCFSMapValue__storage_, fields), + .flags = GPBFieldMapKeyString, + .dataType = GPBDataTypeMessage, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GCFSMapValue class] + rootClass:[GCFSDocumentRoot class] + file:GCFSDocumentRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GCFSMapValue__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + + +#pragma clang diagnostic pop + +// @@protoc_insertion_point(global_scope) diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/objc/google/firestore/v1/Firestore.pbobjc.h b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/objc/google/firestore/v1/Firestore.pbobjc.h new file mode 100644 index 0000000..8833c84 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/objc/google/firestore/v1/Firestore.pbobjc.h @@ -0,0 +1,1339 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/firestore/v1/firestore.proto + +// This CPP symbol can be defined to use imports that match up to the framework +// imports needed when using CocoaPods. +#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) + #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 +#endif + +#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS + #import +#else + #import "GPBProtocolBuffers.h" +#endif + +#if GOOGLE_PROTOBUF_OBJC_VERSION < 30002 +#error This file was generated by a newer version of protoc which is incompatible with your Protocol Buffer library sources. +#endif +#if 30002 < GOOGLE_PROTOBUF_OBJC_MIN_SUPPORTED_VERSION +#error This file was generated by an older version of protoc which is incompatible with your Protocol Buffer library sources. +#endif + +// @@protoc_insertion_point(imports) + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + +CF_EXTERN_C_BEGIN + +@class GCFSDocument; +@class GCFSDocumentChange; +@class GCFSDocumentDelete; +@class GCFSDocumentMask; +@class GCFSDocumentRemove; +@class GCFSExistenceFilter; +@class GCFSPrecondition; +@class GCFSStructuredQuery; +@class GCFSTarget; +@class GCFSTargetChange; +@class GCFSTarget_DocumentsTarget; +@class GCFSTarget_QueryTarget; +@class GCFSTransactionOptions; +@class GCFSWrite; +@class GCFSWriteResult; +@class GPBTimestamp; +@class RPCStatus; + +NS_ASSUME_NONNULL_BEGIN + +#pragma mark - Enum GCFSTargetChange_TargetChangeType + +/** The type of change. */ +typedef GPB_ENUM(GCFSTargetChange_TargetChangeType) { + /** + * Value used if any message's field encounters a value that is not defined + * by this enum. The message will also have C functions to get/set the rawValue + * of the field. + **/ + GCFSTargetChange_TargetChangeType_GPBUnrecognizedEnumeratorValue = kGPBUnrecognizedEnumeratorValue, + /** No change has occurred. Used only to send an updated `resume_token`. */ + GCFSTargetChange_TargetChangeType_NoChange = 0, + + /** The targets have been added. */ + GCFSTargetChange_TargetChangeType_Add = 1, + + /** The targets have been removed. */ + GCFSTargetChange_TargetChangeType_Remove = 2, + + /** + * The targets reflect all changes committed before the targets were added + * to the stream. + * + * This will be sent after or with a `read_time` that is greater than or + * equal to the time at which the targets were added. + * + * Listeners can wait for this change if read-after-write semantics + * are desired. + **/ + GCFSTargetChange_TargetChangeType_Current = 3, + + /** + * The targets have been reset, and a new initial state for the targets + * will be returned in subsequent changes. + * + * After the initial state is complete, `CURRENT` will be returned even + * if the target was previously indicated to be `CURRENT`. + **/ + GCFSTargetChange_TargetChangeType_Reset = 4, +}; + +GPBEnumDescriptor *GCFSTargetChange_TargetChangeType_EnumDescriptor(void); + +/** + * Checks to see if the given value is defined by the enum or was not known at + * the time this source was generated. + **/ +BOOL GCFSTargetChange_TargetChangeType_IsValidValue(int32_t value); + +#pragma mark - GCFSFirestoreRoot + +/** + * Exposes the extension registry for this file. + * + * The base class provides: + * @code + * + (GPBExtensionRegistry *)extensionRegistry; + * @endcode + * which is a @c GPBExtensionRegistry that includes all the extensions defined by + * this file and all files that it depends on. + **/ +@interface GCFSFirestoreRoot : GPBRootObject +@end + +#pragma mark - GCFSGetDocumentRequest + +typedef GPB_ENUM(GCFSGetDocumentRequest_FieldNumber) { + GCFSGetDocumentRequest_FieldNumber_Name = 1, + GCFSGetDocumentRequest_FieldNumber_Mask = 2, + GCFSGetDocumentRequest_FieldNumber_Transaction = 3, + GCFSGetDocumentRequest_FieldNumber_ReadTime = 5, +}; + +typedef GPB_ENUM(GCFSGetDocumentRequest_ConsistencySelector_OneOfCase) { + GCFSGetDocumentRequest_ConsistencySelector_OneOfCase_GPBUnsetOneOfCase = 0, + GCFSGetDocumentRequest_ConsistencySelector_OneOfCase_Transaction = 3, + GCFSGetDocumentRequest_ConsistencySelector_OneOfCase_ReadTime = 5, +}; + +/** + * The request for [Firestore.GetDocument][google.firestore.v1.Firestore.GetDocument]. + **/ +@interface GCFSGetDocumentRequest : GPBMessage + +/** + * The resource name of the Document to get. In the format: + * `projects/{project_id}/databases/{database_id}/documents/{document_path}`. + **/ +@property(nonatomic, readwrite, copy, null_resettable) NSString *name; + +/** + * The fields to return. If not set, returns all fields. + * + * If the document has a field that is not present in this mask, that field + * will not be returned in the response. + **/ +@property(nonatomic, readwrite, strong, null_resettable) GCFSDocumentMask *mask; +/** Test to see if @c mask has been set. */ +@property(nonatomic, readwrite) BOOL hasMask; + +/** + * The consistency mode for this transaction. + * If not set, defaults to strong consistency. + **/ +@property(nonatomic, readonly) GCFSGetDocumentRequest_ConsistencySelector_OneOfCase consistencySelectorOneOfCase; + +/** Reads the document in a transaction. */ +@property(nonatomic, readwrite, copy, null_resettable) NSData *transaction; + +/** + * Reads the version of the document at the given time. + * This may not be older than 60 seconds. + **/ +@property(nonatomic, readwrite, strong, null_resettable) GPBTimestamp *readTime; + +@end + +/** + * Clears whatever value was set for the oneof 'consistencySelector'. + **/ +void GCFSGetDocumentRequest_ClearConsistencySelectorOneOfCase(GCFSGetDocumentRequest *message); + +#pragma mark - GCFSListDocumentsRequest + +typedef GPB_ENUM(GCFSListDocumentsRequest_FieldNumber) { + GCFSListDocumentsRequest_FieldNumber_Parent = 1, + GCFSListDocumentsRequest_FieldNumber_CollectionId = 2, + GCFSListDocumentsRequest_FieldNumber_PageSize = 3, + GCFSListDocumentsRequest_FieldNumber_PageToken = 4, + GCFSListDocumentsRequest_FieldNumber_OrderBy = 6, + GCFSListDocumentsRequest_FieldNumber_Mask = 7, + GCFSListDocumentsRequest_FieldNumber_Transaction = 8, + GCFSListDocumentsRequest_FieldNumber_ReadTime = 10, + GCFSListDocumentsRequest_FieldNumber_ShowMissing = 12, +}; + +typedef GPB_ENUM(GCFSListDocumentsRequest_ConsistencySelector_OneOfCase) { + GCFSListDocumentsRequest_ConsistencySelector_OneOfCase_GPBUnsetOneOfCase = 0, + GCFSListDocumentsRequest_ConsistencySelector_OneOfCase_Transaction = 8, + GCFSListDocumentsRequest_ConsistencySelector_OneOfCase_ReadTime = 10, +}; + +/** + * The request for [Firestore.ListDocuments][google.firestore.v1.Firestore.ListDocuments]. + **/ +@interface GCFSListDocumentsRequest : GPBMessage + +/** + * The parent resource name. In the format: + * `projects/{project_id}/databases/{database_id}/documents` or + * `projects/{project_id}/databases/{database_id}/documents/{document_path}`. + * For example: + * `projects/my-project/databases/my-database/documents` or + * `projects/my-project/databases/my-database/documents/chatrooms/my-chatroom` + **/ +@property(nonatomic, readwrite, copy, null_resettable) NSString *parent; + +/** + * The collection ID, relative to `parent`, to list. For example: `chatrooms` + * or `messages`. + **/ +@property(nonatomic, readwrite, copy, null_resettable) NSString *collectionId; + +/** The maximum number of documents to return. */ +@property(nonatomic, readwrite) int32_t pageSize; + +/** The `next_page_token` value returned from a previous List request, if any. */ +@property(nonatomic, readwrite, copy, null_resettable) NSString *pageToken; + +/** The order to sort results by. For example: `priority desc, name`. */ +@property(nonatomic, readwrite, copy, null_resettable) NSString *orderBy; + +/** + * The fields to return. If not set, returns all fields. + * + * If a document has a field that is not present in this mask, that field + * will not be returned in the response. + **/ +@property(nonatomic, readwrite, strong, null_resettable) GCFSDocumentMask *mask; +/** Test to see if @c mask has been set. */ +@property(nonatomic, readwrite) BOOL hasMask; + +/** + * The consistency mode for this transaction. + * If not set, defaults to strong consistency. + **/ +@property(nonatomic, readonly) GCFSListDocumentsRequest_ConsistencySelector_OneOfCase consistencySelectorOneOfCase; + +/** Reads documents in a transaction. */ +@property(nonatomic, readwrite, copy, null_resettable) NSData *transaction; + +/** + * Reads documents as they were at the given time. + * This may not be older than 60 seconds. + **/ +@property(nonatomic, readwrite, strong, null_resettable) GPBTimestamp *readTime; + +/** + * If the list should show missing documents. A missing document is a + * document that does not exist but has sub-documents. These documents will + * be returned with a key but will not have fields, [Document.create_time][google.firestore.v1.Document.create_time], + * or [Document.update_time][google.firestore.v1.Document.update_time] set. + * + * Requests with `show_missing` may not specify `where` or + * `order_by`. + **/ +@property(nonatomic, readwrite) BOOL showMissing; + +@end + +/** + * Clears whatever value was set for the oneof 'consistencySelector'. + **/ +void GCFSListDocumentsRequest_ClearConsistencySelectorOneOfCase(GCFSListDocumentsRequest *message); + +#pragma mark - GCFSListDocumentsResponse + +typedef GPB_ENUM(GCFSListDocumentsResponse_FieldNumber) { + GCFSListDocumentsResponse_FieldNumber_DocumentsArray = 1, + GCFSListDocumentsResponse_FieldNumber_NextPageToken = 2, +}; + +/** + * The response for [Firestore.ListDocuments][google.firestore.v1.Firestore.ListDocuments]. + **/ +@interface GCFSListDocumentsResponse : GPBMessage + +/** The Documents found. */ +@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *documentsArray; +/** The number of items in @c documentsArray without causing the array to be created. */ +@property(nonatomic, readonly) NSUInteger documentsArray_Count; + +/** The next page token. */ +@property(nonatomic, readwrite, copy, null_resettable) NSString *nextPageToken; + +@end + +#pragma mark - GCFSCreateDocumentRequest + +typedef GPB_ENUM(GCFSCreateDocumentRequest_FieldNumber) { + GCFSCreateDocumentRequest_FieldNumber_Parent = 1, + GCFSCreateDocumentRequest_FieldNumber_CollectionId = 2, + GCFSCreateDocumentRequest_FieldNumber_DocumentId = 3, + GCFSCreateDocumentRequest_FieldNumber_Document = 4, + GCFSCreateDocumentRequest_FieldNumber_Mask = 5, +}; + +/** + * The request for [Firestore.CreateDocument][google.firestore.v1.Firestore.CreateDocument]. + **/ +@interface GCFSCreateDocumentRequest : GPBMessage + +/** + * The parent resource. For example: + * `projects/{project_id}/databases/{database_id}/documents` or + * `projects/{project_id}/databases/{database_id}/documents/chatrooms/{chatroom_id}` + **/ +@property(nonatomic, readwrite, copy, null_resettable) NSString *parent; + +/** The collection ID, relative to `parent`, to list. For example: `chatrooms`. */ +@property(nonatomic, readwrite, copy, null_resettable) NSString *collectionId; + +/** + * The client-assigned document ID to use for this document. + * + * Optional. If not specified, an ID will be assigned by the service. + **/ +@property(nonatomic, readwrite, copy, null_resettable) NSString *documentId; + +/** The document to create. `name` must not be set. */ +@property(nonatomic, readwrite, strong, null_resettable) GCFSDocument *document; +/** Test to see if @c document has been set. */ +@property(nonatomic, readwrite) BOOL hasDocument; + +/** + * The fields to return. If not set, returns all fields. + * + * If the document has a field that is not present in this mask, that field + * will not be returned in the response. + **/ +@property(nonatomic, readwrite, strong, null_resettable) GCFSDocumentMask *mask; +/** Test to see if @c mask has been set. */ +@property(nonatomic, readwrite) BOOL hasMask; + +@end + +#pragma mark - GCFSUpdateDocumentRequest + +typedef GPB_ENUM(GCFSUpdateDocumentRequest_FieldNumber) { + GCFSUpdateDocumentRequest_FieldNumber_Document = 1, + GCFSUpdateDocumentRequest_FieldNumber_UpdateMask = 2, + GCFSUpdateDocumentRequest_FieldNumber_Mask = 3, + GCFSUpdateDocumentRequest_FieldNumber_CurrentDocument = 4, +}; + +/** + * The request for [Firestore.UpdateDocument][google.firestore.v1.Firestore.UpdateDocument]. + **/ +@interface GCFSUpdateDocumentRequest : GPBMessage + +/** + * The updated document. + * Creates the document if it does not already exist. + **/ +@property(nonatomic, readwrite, strong, null_resettable) GCFSDocument *document; +/** Test to see if @c document has been set. */ +@property(nonatomic, readwrite) BOOL hasDocument; + +/** + * The fields to update. + * None of the field paths in the mask may contain a reserved name. + * + * If the document exists on the server and has fields not referenced in the + * mask, they are left unchanged. + * Fields referenced in the mask, but not present in the input document, are + * deleted from the document on the server. + **/ +@property(nonatomic, readwrite, strong, null_resettable) GCFSDocumentMask *updateMask; +/** Test to see if @c updateMask has been set. */ +@property(nonatomic, readwrite) BOOL hasUpdateMask; + +/** + * The fields to return. If not set, returns all fields. + * + * If the document has a field that is not present in this mask, that field + * will not be returned in the response. + **/ +@property(nonatomic, readwrite, strong, null_resettable) GCFSDocumentMask *mask; +/** Test to see if @c mask has been set. */ +@property(nonatomic, readwrite) BOOL hasMask; + +/** + * An optional precondition on the document. + * The request will fail if this is set and not met by the target document. + **/ +@property(nonatomic, readwrite, strong, null_resettable) GCFSPrecondition *currentDocument; +/** Test to see if @c currentDocument has been set. */ +@property(nonatomic, readwrite) BOOL hasCurrentDocument; + +@end + +#pragma mark - GCFSDeleteDocumentRequest + +typedef GPB_ENUM(GCFSDeleteDocumentRequest_FieldNumber) { + GCFSDeleteDocumentRequest_FieldNumber_Name = 1, + GCFSDeleteDocumentRequest_FieldNumber_CurrentDocument = 2, +}; + +/** + * The request for [Firestore.DeleteDocument][google.firestore.v1.Firestore.DeleteDocument]. + **/ +@interface GCFSDeleteDocumentRequest : GPBMessage + +/** + * The resource name of the Document to delete. In the format: + * `projects/{project_id}/databases/{database_id}/documents/{document_path}`. + **/ +@property(nonatomic, readwrite, copy, null_resettable) NSString *name; + +/** + * An optional precondition on the document. + * The request will fail if this is set and not met by the target document. + **/ +@property(nonatomic, readwrite, strong, null_resettable) GCFSPrecondition *currentDocument; +/** Test to see if @c currentDocument has been set. */ +@property(nonatomic, readwrite) BOOL hasCurrentDocument; + +@end + +#pragma mark - GCFSBatchGetDocumentsRequest + +typedef GPB_ENUM(GCFSBatchGetDocumentsRequest_FieldNumber) { + GCFSBatchGetDocumentsRequest_FieldNumber_Database = 1, + GCFSBatchGetDocumentsRequest_FieldNumber_DocumentsArray = 2, + GCFSBatchGetDocumentsRequest_FieldNumber_Mask = 3, + GCFSBatchGetDocumentsRequest_FieldNumber_Transaction = 4, + GCFSBatchGetDocumentsRequest_FieldNumber_NewTransaction = 5, + GCFSBatchGetDocumentsRequest_FieldNumber_ReadTime = 7, +}; + +typedef GPB_ENUM(GCFSBatchGetDocumentsRequest_ConsistencySelector_OneOfCase) { + GCFSBatchGetDocumentsRequest_ConsistencySelector_OneOfCase_GPBUnsetOneOfCase = 0, + GCFSBatchGetDocumentsRequest_ConsistencySelector_OneOfCase_Transaction = 4, + GCFSBatchGetDocumentsRequest_ConsistencySelector_OneOfCase_NewTransaction = 5, + GCFSBatchGetDocumentsRequest_ConsistencySelector_OneOfCase_ReadTime = 7, +}; + +/** + * The request for [Firestore.BatchGetDocuments][google.firestore.v1.Firestore.BatchGetDocuments]. + **/ +@interface GCFSBatchGetDocumentsRequest : GPBMessage + +/** + * The database name. In the format: + * `projects/{project_id}/databases/{database_id}`. + **/ +@property(nonatomic, readwrite, copy, null_resettable) NSString *database; + +/** + * The names of the documents to retrieve. In the format: + * `projects/{project_id}/databases/{database_id}/documents/{document_path}`. + * The request will fail if any of the document is not a child resource of the + * given `database`. Duplicate names will be elided. + **/ +@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *documentsArray; +/** The number of items in @c documentsArray without causing the array to be created. */ +@property(nonatomic, readonly) NSUInteger documentsArray_Count; + +/** + * The fields to return. If not set, returns all fields. + * + * If a document has a field that is not present in this mask, that field will + * not be returned in the response. + **/ +@property(nonatomic, readwrite, strong, null_resettable) GCFSDocumentMask *mask; +/** Test to see if @c mask has been set. */ +@property(nonatomic, readwrite) BOOL hasMask; + +/** + * The consistency mode for this transaction. + * If not set, defaults to strong consistency. + **/ +@property(nonatomic, readonly) GCFSBatchGetDocumentsRequest_ConsistencySelector_OneOfCase consistencySelectorOneOfCase; + +/** Reads documents in a transaction. */ +@property(nonatomic, readwrite, copy, null_resettable) NSData *transaction; + +/** + * Starts a new transaction and reads the documents. + * Defaults to a read-only transaction. + * The new transaction ID will be returned as the first response in the + * stream. + **/ +@property(nonatomic, readwrite, strong, null_resettable) GCFSTransactionOptions *newTransaction NS_RETURNS_NOT_RETAINED; + +/** + * Reads documents as they were at the given time. + * This may not be older than 60 seconds. + **/ +@property(nonatomic, readwrite, strong, null_resettable) GPBTimestamp *readTime; + +@end + +/** + * Clears whatever value was set for the oneof 'consistencySelector'. + **/ +void GCFSBatchGetDocumentsRequest_ClearConsistencySelectorOneOfCase(GCFSBatchGetDocumentsRequest *message); + +#pragma mark - GCFSBatchGetDocumentsResponse + +typedef GPB_ENUM(GCFSBatchGetDocumentsResponse_FieldNumber) { + GCFSBatchGetDocumentsResponse_FieldNumber_Found = 1, + GCFSBatchGetDocumentsResponse_FieldNumber_Missing = 2, + GCFSBatchGetDocumentsResponse_FieldNumber_Transaction = 3, + GCFSBatchGetDocumentsResponse_FieldNumber_ReadTime = 4, +}; + +typedef GPB_ENUM(GCFSBatchGetDocumentsResponse_Result_OneOfCase) { + GCFSBatchGetDocumentsResponse_Result_OneOfCase_GPBUnsetOneOfCase = 0, + GCFSBatchGetDocumentsResponse_Result_OneOfCase_Found = 1, + GCFSBatchGetDocumentsResponse_Result_OneOfCase_Missing = 2, +}; + +/** + * The streamed response for [Firestore.BatchGetDocuments][google.firestore.v1.Firestore.BatchGetDocuments]. + **/ +@interface GCFSBatchGetDocumentsResponse : GPBMessage + +/** + * A single result. + * This can be empty if the server is just returning a transaction. + **/ +@property(nonatomic, readonly) GCFSBatchGetDocumentsResponse_Result_OneOfCase resultOneOfCase; + +/** A document that was requested. */ +@property(nonatomic, readwrite, strong, null_resettable) GCFSDocument *found; + +/** + * A document name that was requested but does not exist. In the format: + * `projects/{project_id}/databases/{database_id}/documents/{document_path}`. + **/ +@property(nonatomic, readwrite, copy, null_resettable) NSString *missing; + +/** + * The transaction that was started as part of this request. + * Will only be set in the first response, and only if + * [BatchGetDocumentsRequest.new_transaction][google.firestore.v1.BatchGetDocumentsRequest.new_transaction] was set in the request. + **/ +@property(nonatomic, readwrite, copy, null_resettable) NSData *transaction; + +/** + * The time at which the document was read. + * This may be monotically increasing, in this case the previous documents in + * the result stream are guaranteed not to have changed between their + * read_time and this one. + **/ +@property(nonatomic, readwrite, strong, null_resettable) GPBTimestamp *readTime; +/** Test to see if @c readTime has been set. */ +@property(nonatomic, readwrite) BOOL hasReadTime; + +@end + +/** + * Clears whatever value was set for the oneof 'result'. + **/ +void GCFSBatchGetDocumentsResponse_ClearResultOneOfCase(GCFSBatchGetDocumentsResponse *message); + +#pragma mark - GCFSBeginTransactionRequest + +typedef GPB_ENUM(GCFSBeginTransactionRequest_FieldNumber) { + GCFSBeginTransactionRequest_FieldNumber_Database = 1, + GCFSBeginTransactionRequest_FieldNumber_Options = 2, +}; + +/** + * The request for [Firestore.BeginTransaction][google.firestore.v1.Firestore.BeginTransaction]. + **/ +@interface GCFSBeginTransactionRequest : GPBMessage + +/** + * The database name. In the format: + * `projects/{project_id}/databases/{database_id}`. + **/ +@property(nonatomic, readwrite, copy, null_resettable) NSString *database; + +/** + * The options for the transaction. + * Defaults to a read-write transaction. + **/ +@property(nonatomic, readwrite, strong, null_resettable) GCFSTransactionOptions *options; +/** Test to see if @c options has been set. */ +@property(nonatomic, readwrite) BOOL hasOptions; + +@end + +#pragma mark - GCFSBeginTransactionResponse + +typedef GPB_ENUM(GCFSBeginTransactionResponse_FieldNumber) { + GCFSBeginTransactionResponse_FieldNumber_Transaction = 1, +}; + +/** + * The response for [Firestore.BeginTransaction][google.firestore.v1.Firestore.BeginTransaction]. + **/ +@interface GCFSBeginTransactionResponse : GPBMessage + +/** The transaction that was started. */ +@property(nonatomic, readwrite, copy, null_resettable) NSData *transaction; + +@end + +#pragma mark - GCFSCommitRequest + +typedef GPB_ENUM(GCFSCommitRequest_FieldNumber) { + GCFSCommitRequest_FieldNumber_Database = 1, + GCFSCommitRequest_FieldNumber_WritesArray = 2, + GCFSCommitRequest_FieldNumber_Transaction = 3, +}; + +/** + * The request for [Firestore.Commit][google.firestore.v1.Firestore.Commit]. + **/ +@interface GCFSCommitRequest : GPBMessage + +/** + * The database name. In the format: + * `projects/{project_id}/databases/{database_id}`. + **/ +@property(nonatomic, readwrite, copy, null_resettable) NSString *database; + +/** + * The writes to apply. + * + * Always executed atomically and in order. + **/ +@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *writesArray; +/** The number of items in @c writesArray without causing the array to be created. */ +@property(nonatomic, readonly) NSUInteger writesArray_Count; + +/** If set, applies all writes in this transaction, and commits it. */ +@property(nonatomic, readwrite, copy, null_resettable) NSData *transaction; + +@end + +#pragma mark - GCFSCommitResponse + +typedef GPB_ENUM(GCFSCommitResponse_FieldNumber) { + GCFSCommitResponse_FieldNumber_WriteResultsArray = 1, + GCFSCommitResponse_FieldNumber_CommitTime = 2, +}; + +/** + * The response for [Firestore.Commit][google.firestore.v1.Firestore.Commit]. + **/ +@interface GCFSCommitResponse : GPBMessage + +/** + * The result of applying the writes. + * + * This i-th write result corresponds to the i-th write in the + * request. + **/ +@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *writeResultsArray; +/** The number of items in @c writeResultsArray without causing the array to be created. */ +@property(nonatomic, readonly) NSUInteger writeResultsArray_Count; + +/** The time at which the commit occurred. */ +@property(nonatomic, readwrite, strong, null_resettable) GPBTimestamp *commitTime; +/** Test to see if @c commitTime has been set. */ +@property(nonatomic, readwrite) BOOL hasCommitTime; + +@end + +#pragma mark - GCFSRollbackRequest + +typedef GPB_ENUM(GCFSRollbackRequest_FieldNumber) { + GCFSRollbackRequest_FieldNumber_Database = 1, + GCFSRollbackRequest_FieldNumber_Transaction = 2, +}; + +/** + * The request for [Firestore.Rollback][google.firestore.v1.Firestore.Rollback]. + **/ +@interface GCFSRollbackRequest : GPBMessage + +/** + * The database name. In the format: + * `projects/{project_id}/databases/{database_id}`. + **/ +@property(nonatomic, readwrite, copy, null_resettable) NSString *database; + +/** The transaction to roll back. */ +@property(nonatomic, readwrite, copy, null_resettable) NSData *transaction; + +@end + +#pragma mark - GCFSRunQueryRequest + +typedef GPB_ENUM(GCFSRunQueryRequest_FieldNumber) { + GCFSRunQueryRequest_FieldNumber_Parent = 1, + GCFSRunQueryRequest_FieldNumber_StructuredQuery = 2, + GCFSRunQueryRequest_FieldNumber_Transaction = 5, + GCFSRunQueryRequest_FieldNumber_NewTransaction = 6, + GCFSRunQueryRequest_FieldNumber_ReadTime = 7, +}; + +typedef GPB_ENUM(GCFSRunQueryRequest_QueryType_OneOfCase) { + GCFSRunQueryRequest_QueryType_OneOfCase_GPBUnsetOneOfCase = 0, + GCFSRunQueryRequest_QueryType_OneOfCase_StructuredQuery = 2, +}; + +typedef GPB_ENUM(GCFSRunQueryRequest_ConsistencySelector_OneOfCase) { + GCFSRunQueryRequest_ConsistencySelector_OneOfCase_GPBUnsetOneOfCase = 0, + GCFSRunQueryRequest_ConsistencySelector_OneOfCase_Transaction = 5, + GCFSRunQueryRequest_ConsistencySelector_OneOfCase_NewTransaction = 6, + GCFSRunQueryRequest_ConsistencySelector_OneOfCase_ReadTime = 7, +}; + +/** + * The request for [Firestore.RunQuery][google.firestore.v1.Firestore.RunQuery]. + **/ +@interface GCFSRunQueryRequest : GPBMessage + +/** + * The parent resource name. In the format: + * `projects/{project_id}/databases/{database_id}/documents` or + * `projects/{project_id}/databases/{database_id}/documents/{document_path}`. + * For example: + * `projects/my-project/databases/my-database/documents` or + * `projects/my-project/databases/my-database/documents/chatrooms/my-chatroom` + **/ +@property(nonatomic, readwrite, copy, null_resettable) NSString *parent; + +/** The query to run. */ +@property(nonatomic, readonly) GCFSRunQueryRequest_QueryType_OneOfCase queryTypeOneOfCase; + +/** A structured query. */ +@property(nonatomic, readwrite, strong, null_resettable) GCFSStructuredQuery *structuredQuery; + +/** + * The consistency mode for this transaction. + * If not set, defaults to strong consistency. + **/ +@property(nonatomic, readonly) GCFSRunQueryRequest_ConsistencySelector_OneOfCase consistencySelectorOneOfCase; + +/** Reads documents in a transaction. */ +@property(nonatomic, readwrite, copy, null_resettable) NSData *transaction; + +/** + * Starts a new transaction and reads the documents. + * Defaults to a read-only transaction. + * The new transaction ID will be returned as the first response in the + * stream. + **/ +@property(nonatomic, readwrite, strong, null_resettable) GCFSTransactionOptions *newTransaction NS_RETURNS_NOT_RETAINED; + +/** + * Reads documents as they were at the given time. + * This may not be older than 60 seconds. + **/ +@property(nonatomic, readwrite, strong, null_resettable) GPBTimestamp *readTime; + +@end + +/** + * Clears whatever value was set for the oneof 'queryType'. + **/ +void GCFSRunQueryRequest_ClearQueryTypeOneOfCase(GCFSRunQueryRequest *message); +/** + * Clears whatever value was set for the oneof 'consistencySelector'. + **/ +void GCFSRunQueryRequest_ClearConsistencySelectorOneOfCase(GCFSRunQueryRequest *message); + +#pragma mark - GCFSRunQueryResponse + +typedef GPB_ENUM(GCFSRunQueryResponse_FieldNumber) { + GCFSRunQueryResponse_FieldNumber_Document = 1, + GCFSRunQueryResponse_FieldNumber_Transaction = 2, + GCFSRunQueryResponse_FieldNumber_ReadTime = 3, + GCFSRunQueryResponse_FieldNumber_SkippedResults = 4, +}; + +/** + * The response for [Firestore.RunQuery][google.firestore.v1.Firestore.RunQuery]. + **/ +@interface GCFSRunQueryResponse : GPBMessage + +/** + * The transaction that was started as part of this request. + * Can only be set in the first response, and only if + * [RunQueryRequest.new_transaction][google.firestore.v1.RunQueryRequest.new_transaction] was set in the request. + * If set, no other fields will be set in this response. + **/ +@property(nonatomic, readwrite, copy, null_resettable) NSData *transaction; + +/** + * A query result. + * Not set when reporting partial progress. + **/ +@property(nonatomic, readwrite, strong, null_resettable) GCFSDocument *document; +/** Test to see if @c document has been set. */ +@property(nonatomic, readwrite) BOOL hasDocument; + +/** + * The time at which the document was read. This may be monotonically + * increasing; in this case, the previous documents in the result stream are + * guaranteed not to have changed between their `read_time` and this one. + * + * If the query returns no results, a response with `read_time` and no + * `document` will be sent, and this represents the time at which the query + * was run. + **/ +@property(nonatomic, readwrite, strong, null_resettable) GPBTimestamp *readTime; +/** Test to see if @c readTime has been set. */ +@property(nonatomic, readwrite) BOOL hasReadTime; + +/** + * The number of results that have been skipped due to an offset between + * the last response and the current response. + **/ +@property(nonatomic, readwrite) int32_t skippedResults; + +@end + +#pragma mark - GCFSWriteRequest + +typedef GPB_ENUM(GCFSWriteRequest_FieldNumber) { + GCFSWriteRequest_FieldNumber_Database = 1, + GCFSWriteRequest_FieldNumber_StreamId = 2, + GCFSWriteRequest_FieldNumber_WritesArray = 3, + GCFSWriteRequest_FieldNumber_StreamToken = 4, + GCFSWriteRequest_FieldNumber_Labels = 5, +}; + +/** + * The request for [Firestore.Write][google.firestore.v1.Firestore.Write]. + * + * The first request creates a stream, or resumes an existing one from a token. + * + * When creating a new stream, the server replies with a response containing + * only an ID and a token, to use in the next request. + * + * When resuming a stream, the server first streams any responses later than the + * given token, then a response containing only an up-to-date token, to use in + * the next request. + **/ +@interface GCFSWriteRequest : GPBMessage + +/** + * The database name. In the format: + * `projects/{project_id}/databases/{database_id}`. + * This is only required in the first message. + **/ +@property(nonatomic, readwrite, copy, null_resettable) NSString *database; + +/** + * The ID of the write stream to resume. + * This may only be set in the first message. When left empty, a new write + * stream will be created. + **/ +@property(nonatomic, readwrite, copy, null_resettable) NSString *streamId; + +/** + * The writes to apply. + * + * Always executed atomically and in order. + * This must be empty on the first request. + * This may be empty on the last request. + * This must not be empty on all other requests. + **/ +@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *writesArray; +/** The number of items in @c writesArray without causing the array to be created. */ +@property(nonatomic, readonly) NSUInteger writesArray_Count; + +/** + * A stream token that was previously sent by the server. + * + * The client should set this field to the token from the most recent + * [WriteResponse][google.firestore.v1.WriteResponse] it has received. This acknowledges that the client has + * received responses up to this token. After sending this token, earlier + * tokens may not be used anymore. + * + * The server may close the stream if there are too many unacknowledged + * responses. + * + * Leave this field unset when creating a new stream. To resume a stream at + * a specific point, set this field and the `stream_id` field. + * + * Leave this field unset when creating a new stream. + **/ +@property(nonatomic, readwrite, copy, null_resettable) NSData *streamToken; + +/** Labels associated with this write request. */ +@property(nonatomic, readwrite, strong, null_resettable) NSMutableDictionary *labels; +/** The number of items in @c labels without causing the array to be created. */ +@property(nonatomic, readonly) NSUInteger labels_Count; + +@end + +#pragma mark - GCFSWriteResponse + +typedef GPB_ENUM(GCFSWriteResponse_FieldNumber) { + GCFSWriteResponse_FieldNumber_StreamId = 1, + GCFSWriteResponse_FieldNumber_StreamToken = 2, + GCFSWriteResponse_FieldNumber_WriteResultsArray = 3, + GCFSWriteResponse_FieldNumber_CommitTime = 4, +}; + +/** + * The response for [Firestore.Write][google.firestore.v1.Firestore.Write]. + **/ +@interface GCFSWriteResponse : GPBMessage + +/** + * The ID of the stream. + * Only set on the first message, when a new stream was created. + **/ +@property(nonatomic, readwrite, copy, null_resettable) NSString *streamId; + +/** + * A token that represents the position of this response in the stream. + * This can be used by a client to resume the stream at this point. + * + * This field is always set. + **/ +@property(nonatomic, readwrite, copy, null_resettable) NSData *streamToken; + +/** + * The result of applying the writes. + * + * This i-th write result corresponds to the i-th write in the + * request. + **/ +@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *writeResultsArray; +/** The number of items in @c writeResultsArray without causing the array to be created. */ +@property(nonatomic, readonly) NSUInteger writeResultsArray_Count; + +/** The time at which the commit occurred. */ +@property(nonatomic, readwrite, strong, null_resettable) GPBTimestamp *commitTime; +/** Test to see if @c commitTime has been set. */ +@property(nonatomic, readwrite) BOOL hasCommitTime; + +@end + +#pragma mark - GCFSListenRequest + +typedef GPB_ENUM(GCFSListenRequest_FieldNumber) { + GCFSListenRequest_FieldNumber_Database = 1, + GCFSListenRequest_FieldNumber_AddTarget = 2, + GCFSListenRequest_FieldNumber_RemoveTarget = 3, + GCFSListenRequest_FieldNumber_Labels = 4, +}; + +typedef GPB_ENUM(GCFSListenRequest_TargetChange_OneOfCase) { + GCFSListenRequest_TargetChange_OneOfCase_GPBUnsetOneOfCase = 0, + GCFSListenRequest_TargetChange_OneOfCase_AddTarget = 2, + GCFSListenRequest_TargetChange_OneOfCase_RemoveTarget = 3, +}; + +/** + * A request for [Firestore.Listen][google.firestore.v1.Firestore.Listen] + **/ +@interface GCFSListenRequest : GPBMessage + +/** + * The database name. In the format: + * `projects/{project_id}/databases/{database_id}`. + **/ +@property(nonatomic, readwrite, copy, null_resettable) NSString *database; + +/** The supported target changes. */ +@property(nonatomic, readonly) GCFSListenRequest_TargetChange_OneOfCase targetChangeOneOfCase; + +/** A target to add to this stream. */ +@property(nonatomic, readwrite, strong, null_resettable) GCFSTarget *addTarget; + +/** The ID of a target to remove from this stream. */ +@property(nonatomic, readwrite) int32_t removeTarget; + +/** Labels associated with this target change. */ +@property(nonatomic, readwrite, strong, null_resettable) NSMutableDictionary *labels; +/** The number of items in @c labels without causing the array to be created. */ +@property(nonatomic, readonly) NSUInteger labels_Count; + +@end + +/** + * Clears whatever value was set for the oneof 'targetChange'. + **/ +void GCFSListenRequest_ClearTargetChangeOneOfCase(GCFSListenRequest *message); + +#pragma mark - GCFSListenResponse + +typedef GPB_ENUM(GCFSListenResponse_FieldNumber) { + GCFSListenResponse_FieldNumber_TargetChange = 2, + GCFSListenResponse_FieldNumber_DocumentChange = 3, + GCFSListenResponse_FieldNumber_DocumentDelete = 4, + GCFSListenResponse_FieldNumber_Filter = 5, + GCFSListenResponse_FieldNumber_DocumentRemove = 6, +}; + +typedef GPB_ENUM(GCFSListenResponse_ResponseType_OneOfCase) { + GCFSListenResponse_ResponseType_OneOfCase_GPBUnsetOneOfCase = 0, + GCFSListenResponse_ResponseType_OneOfCase_TargetChange = 2, + GCFSListenResponse_ResponseType_OneOfCase_DocumentChange = 3, + GCFSListenResponse_ResponseType_OneOfCase_DocumentDelete = 4, + GCFSListenResponse_ResponseType_OneOfCase_DocumentRemove = 6, + GCFSListenResponse_ResponseType_OneOfCase_Filter = 5, +}; + +/** + * The response for [Firestore.Listen][google.firestore.v1.Firestore.Listen]. + **/ +@interface GCFSListenResponse : GPBMessage + +/** The supported responses. */ +@property(nonatomic, readonly) GCFSListenResponse_ResponseType_OneOfCase responseTypeOneOfCase; + +/** Targets have changed. */ +@property(nonatomic, readwrite, strong, null_resettable) GCFSTargetChange *targetChange; + +/** A [Document][google.firestore.v1.Document] has changed. */ +@property(nonatomic, readwrite, strong, null_resettable) GCFSDocumentChange *documentChange; + +/** A [Document][google.firestore.v1.Document] has been deleted. */ +@property(nonatomic, readwrite, strong, null_resettable) GCFSDocumentDelete *documentDelete; + +/** + * A [Document][google.firestore.v1.Document] has been removed from a target (because it is no longer + * relevant to that target). + **/ +@property(nonatomic, readwrite, strong, null_resettable) GCFSDocumentRemove *documentRemove; + +/** + * A filter to apply to the set of documents previously returned for the + * given target. + * + * Returned when documents may have been removed from the given target, but + * the exact documents are unknown. + **/ +@property(nonatomic, readwrite, strong, null_resettable) GCFSExistenceFilter *filter; + +@end + +/** + * Clears whatever value was set for the oneof 'responseType'. + **/ +void GCFSListenResponse_ClearResponseTypeOneOfCase(GCFSListenResponse *message); + +#pragma mark - GCFSTarget + +typedef GPB_ENUM(GCFSTarget_FieldNumber) { + GCFSTarget_FieldNumber_Query = 2, + GCFSTarget_FieldNumber_Documents = 3, + GCFSTarget_FieldNumber_ResumeToken = 4, + GCFSTarget_FieldNumber_TargetId = 5, + GCFSTarget_FieldNumber_Once = 6, + GCFSTarget_FieldNumber_ReadTime = 11, +}; + +typedef GPB_ENUM(GCFSTarget_TargetType_OneOfCase) { + GCFSTarget_TargetType_OneOfCase_GPBUnsetOneOfCase = 0, + GCFSTarget_TargetType_OneOfCase_Query = 2, + GCFSTarget_TargetType_OneOfCase_Documents = 3, +}; + +typedef GPB_ENUM(GCFSTarget_ResumeType_OneOfCase) { + GCFSTarget_ResumeType_OneOfCase_GPBUnsetOneOfCase = 0, + GCFSTarget_ResumeType_OneOfCase_ResumeToken = 4, + GCFSTarget_ResumeType_OneOfCase_ReadTime = 11, +}; + +/** + * A specification of a set of documents to listen to. + **/ +@interface GCFSTarget : GPBMessage + +/** The type of target to listen to. */ +@property(nonatomic, readonly) GCFSTarget_TargetType_OneOfCase targetTypeOneOfCase; + +/** A target specified by a query. */ +@property(nonatomic, readwrite, strong, null_resettable) GCFSTarget_QueryTarget *query; + +/** A target specified by a set of document names. */ +@property(nonatomic, readwrite, strong, null_resettable) GCFSTarget_DocumentsTarget *documents; + +/** + * When to start listening. + * + * If not specified, all matching Documents are returned before any + * subsequent changes. + **/ +@property(nonatomic, readonly) GCFSTarget_ResumeType_OneOfCase resumeTypeOneOfCase; + +/** + * A resume token from a prior [TargetChange][google.firestore.v1.TargetChange] for an identical target. + * + * Using a resume token with a different target is unsupported and may fail. + **/ +@property(nonatomic, readwrite, copy, null_resettable) NSData *resumeToken; + +/** + * Start listening after a specific `read_time`. + * + * The client must know the state of matching documents at this time. + **/ +@property(nonatomic, readwrite, strong, null_resettable) GPBTimestamp *readTime; + +/** + * A client provided target ID. + * + * If not set, the server will assign an ID for the target. + * + * Used for resuming a target without changing IDs. The IDs can either be + * client-assigned or be server-assigned in a previous stream. All targets + * with client provided IDs must be added before adding a target that needs + * a server-assigned id. + **/ +@property(nonatomic, readwrite) int32_t targetId; + +/** If the target should be removed once it is current and consistent. */ +@property(nonatomic, readwrite) BOOL once; + +@end + +/** + * Clears whatever value was set for the oneof 'targetType'. + **/ +void GCFSTarget_ClearTargetTypeOneOfCase(GCFSTarget *message); +/** + * Clears whatever value was set for the oneof 'resumeType'. + **/ +void GCFSTarget_ClearResumeTypeOneOfCase(GCFSTarget *message); + +#pragma mark - GCFSTarget_DocumentsTarget + +typedef GPB_ENUM(GCFSTarget_DocumentsTarget_FieldNumber) { + GCFSTarget_DocumentsTarget_FieldNumber_DocumentsArray = 2, +}; + +/** + * A target specified by a set of documents names. + **/ +@interface GCFSTarget_DocumentsTarget : GPBMessage + +/** + * The names of the documents to retrieve. In the format: + * `projects/{project_id}/databases/{database_id}/documents/{document_path}`. + * The request will fail if any of the document is not a child resource of + * the given `database`. Duplicate names will be elided. + **/ +@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *documentsArray; +/** The number of items in @c documentsArray without causing the array to be created. */ +@property(nonatomic, readonly) NSUInteger documentsArray_Count; + +@end + +#pragma mark - GCFSTarget_QueryTarget + +typedef GPB_ENUM(GCFSTarget_QueryTarget_FieldNumber) { + GCFSTarget_QueryTarget_FieldNumber_Parent = 1, + GCFSTarget_QueryTarget_FieldNumber_StructuredQuery = 2, +}; + +typedef GPB_ENUM(GCFSTarget_QueryTarget_QueryType_OneOfCase) { + GCFSTarget_QueryTarget_QueryType_OneOfCase_GPBUnsetOneOfCase = 0, + GCFSTarget_QueryTarget_QueryType_OneOfCase_StructuredQuery = 2, +}; + +/** + * A target specified by a query. + **/ +@interface GCFSTarget_QueryTarget : GPBMessage + +/** + * The parent resource name. In the format: + * `projects/{project_id}/databases/{database_id}/documents` or + * `projects/{project_id}/databases/{database_id}/documents/{document_path}`. + * For example: + * `projects/my-project/databases/my-database/documents` or + * `projects/my-project/databases/my-database/documents/chatrooms/my-chatroom` + **/ +@property(nonatomic, readwrite, copy, null_resettable) NSString *parent; + +/** The query to run. */ +@property(nonatomic, readonly) GCFSTarget_QueryTarget_QueryType_OneOfCase queryTypeOneOfCase; + +/** A structured query. */ +@property(nonatomic, readwrite, strong, null_resettable) GCFSStructuredQuery *structuredQuery; + +@end + +/** + * Clears whatever value was set for the oneof 'queryType'. + **/ +void GCFSTarget_QueryTarget_ClearQueryTypeOneOfCase(GCFSTarget_QueryTarget *message); + +#pragma mark - GCFSTargetChange + +typedef GPB_ENUM(GCFSTargetChange_FieldNumber) { + GCFSTargetChange_FieldNumber_TargetChangeType = 1, + GCFSTargetChange_FieldNumber_TargetIdsArray = 2, + GCFSTargetChange_FieldNumber_Cause = 3, + GCFSTargetChange_FieldNumber_ResumeToken = 4, + GCFSTargetChange_FieldNumber_ReadTime = 6, +}; + +/** + * Targets being watched have changed. + **/ +@interface GCFSTargetChange : GPBMessage + +/** The type of change that occurred. */ +@property(nonatomic, readwrite) GCFSTargetChange_TargetChangeType targetChangeType; + +/** + * The target IDs of targets that have changed. + * + * If empty, the change applies to all targets. + * + * For `target_change_type=ADD`, the order of the target IDs matches the order + * of the requests to add the targets. This allows clients to unambiguously + * associate server-assigned target IDs with added targets. + * + * For other states, the order of the target IDs is not defined. + **/ +@property(nonatomic, readwrite, strong, null_resettable) GPBInt32Array *targetIdsArray; +/** The number of items in @c targetIdsArray without causing the array to be created. */ +@property(nonatomic, readonly) NSUInteger targetIdsArray_Count; + +/** The error that resulted in this change, if applicable. */ +@property(nonatomic, readwrite, strong, null_resettable) RPCStatus *cause; +/** Test to see if @c cause has been set. */ +@property(nonatomic, readwrite) BOOL hasCause; + +/** + * A token that can be used to resume the stream for the given `target_ids`, + * or all targets if `target_ids` is empty. + * + * Not set on every target change. + **/ +@property(nonatomic, readwrite, copy, null_resettable) NSData *resumeToken; + +/** + * The consistent `read_time` for the given `target_ids` (omitted when the + * target_ids are not at a consistent snapshot). + * + * The stream is guaranteed to send a `read_time` with `target_ids` empty + * whenever the entire stream reaches a new consistent snapshot. ADD, + * CURRENT, and RESET messages are guaranteed to (eventually) result in a + * new consistent snapshot (while NO_CHANGE and REMOVE messages are not). + * + * For a given stream, `read_time` is guaranteed to be monotonically + * increasing. + **/ +@property(nonatomic, readwrite, strong, null_resettable) GPBTimestamp *readTime; +/** Test to see if @c readTime has been set. */ +@property(nonatomic, readwrite) BOOL hasReadTime; + +@end + +/** + * Fetches the raw value of a @c GCFSTargetChange's @c targetChangeType property, even + * if the value was not defined by the enum at the time the code was generated. + **/ +int32_t GCFSTargetChange_TargetChangeType_RawValue(GCFSTargetChange *message); +/** + * Sets the raw value of an @c GCFSTargetChange's @c targetChangeType property, allowing + * it to be set to a value that was not defined by the enum at the time the code + * was generated. + **/ +void SetGCFSTargetChange_TargetChangeType_RawValue(GCFSTargetChange *message, int32_t value); + +#pragma mark - GCFSListCollectionIdsRequest + +typedef GPB_ENUM(GCFSListCollectionIdsRequest_FieldNumber) { + GCFSListCollectionIdsRequest_FieldNumber_Parent = 1, + GCFSListCollectionIdsRequest_FieldNumber_PageSize = 2, + GCFSListCollectionIdsRequest_FieldNumber_PageToken = 3, +}; + +/** + * The request for [Firestore.ListCollectionIds][google.firestore.v1.Firestore.ListCollectionIds]. + **/ +@interface GCFSListCollectionIdsRequest : GPBMessage + +/** + * The parent document. In the format: + * `projects/{project_id}/databases/{database_id}/documents/{document_path}`. + * For example: + * `projects/my-project/databases/my-database/documents/chatrooms/my-chatroom` + **/ +@property(nonatomic, readwrite, copy, null_resettable) NSString *parent; + +/** The maximum number of results to return. */ +@property(nonatomic, readwrite) int32_t pageSize; + +/** + * A page token. Must be a value from + * [ListCollectionIdsResponse][google.firestore.v1.ListCollectionIdsResponse]. + **/ +@property(nonatomic, readwrite, copy, null_resettable) NSString *pageToken; + +@end + +#pragma mark - GCFSListCollectionIdsResponse + +typedef GPB_ENUM(GCFSListCollectionIdsResponse_FieldNumber) { + GCFSListCollectionIdsResponse_FieldNumber_CollectionIdsArray = 1, + GCFSListCollectionIdsResponse_FieldNumber_NextPageToken = 2, +}; + +/** + * The response from [Firestore.ListCollectionIds][google.firestore.v1.Firestore.ListCollectionIds]. + **/ +@interface GCFSListCollectionIdsResponse : GPBMessage + +/** The collection ids. */ +@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *collectionIdsArray; +/** The number of items in @c collectionIdsArray without causing the array to be created. */ +@property(nonatomic, readonly) NSUInteger collectionIdsArray_Count; + +/** A page token that may be used to continue the list. */ +@property(nonatomic, readwrite, copy, null_resettable) NSString *nextPageToken; + +@end + +NS_ASSUME_NONNULL_END + +CF_EXTERN_C_END + +#pragma clang diagnostic pop + +// @@protoc_insertion_point(global_scope) diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/objc/google/firestore/v1/Firestore.pbobjc.m b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/objc/google/firestore/v1/Firestore.pbobjc.m new file mode 100644 index 0000000..8ab8ca1 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/objc/google/firestore/v1/Firestore.pbobjc.m @@ -0,0 +1,2064 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/firestore/v1/firestore.proto + +// This CPP symbol can be defined to use imports that match up to the framework +// imports needed when using CocoaPods. +#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) + #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 +#endif + +#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS + #import +#else + #import "GPBProtocolBuffers_RuntimeSupport.h" +#endif + +#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS + #import + #import +#else + #import "Empty.pbobjc.h" + #import "Timestamp.pbobjc.h" +#endif + + #import "Firestore.pbobjc.h" + #import "Annotations.pbobjc.h" + #import "Common.pbobjc.h" + #import "Document.pbobjc.h" + #import "Query.pbobjc.h" + #import "Write.pbobjc.h" + #import "Status.pbobjc.h" +// @@protoc_insertion_point(imports) + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" +#pragma clang diagnostic ignored "-Wdirect-ivar-access" + +#pragma mark - GCFSFirestoreRoot + +@implementation GCFSFirestoreRoot + + +@end + +#pragma mark - GCFSFirestoreRoot_FileDescriptor + +static GPBFileDescriptor *GCFSFirestoreRoot_FileDescriptor(void) { + // This is called by +initialize so there is no need to worry + // about thread safety of the singleton. + static GPBFileDescriptor *descriptor = NULL; + if (!descriptor) { + GPB_DEBUG_CHECK_RUNTIME_VERSIONS(); + descriptor = [[GPBFileDescriptor alloc] initWithPackage:@"google.firestore.v1" + objcPrefix:@"GCFS" + syntax:GPBFileSyntaxProto3]; + } + return descriptor; +} + +#pragma mark - GCFSGetDocumentRequest + +@implementation GCFSGetDocumentRequest + +@dynamic consistencySelectorOneOfCase; +@dynamic name; +@dynamic hasMask, mask; +@dynamic transaction; +@dynamic readTime; + +typedef struct GCFSGetDocumentRequest__storage_ { + uint32_t _has_storage_[2]; + NSString *name; + GCFSDocumentMask *mask; + NSData *transaction; + GPBTimestamp *readTime; +} GCFSGetDocumentRequest__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "name", + .dataTypeSpecific.className = NULL, + .number = GCFSGetDocumentRequest_FieldNumber_Name, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GCFSGetDocumentRequest__storage_, name), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "mask", + .dataTypeSpecific.className = GPBStringifySymbol(GCFSDocumentMask), + .number = GCFSGetDocumentRequest_FieldNumber_Mask, + .hasIndex = 1, + .offset = (uint32_t)offsetof(GCFSGetDocumentRequest__storage_, mask), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + { + .name = "transaction", + .dataTypeSpecific.className = NULL, + .number = GCFSGetDocumentRequest_FieldNumber_Transaction, + .hasIndex = -1, + .offset = (uint32_t)offsetof(GCFSGetDocumentRequest__storage_, transaction), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeBytes, + }, + { + .name = "readTime", + .dataTypeSpecific.className = GPBStringifySymbol(GPBTimestamp), + .number = GCFSGetDocumentRequest_FieldNumber_ReadTime, + .hasIndex = -1, + .offset = (uint32_t)offsetof(GCFSGetDocumentRequest__storage_, readTime), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GCFSGetDocumentRequest class] + rootClass:[GCFSFirestoreRoot class] + file:GCFSFirestoreRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GCFSGetDocumentRequest__storage_) + flags:GPBDescriptorInitializationFlag_None]; + static const char *oneofs[] = { + "consistencySelector", + }; + [localDescriptor setupOneofs:oneofs + count:(uint32_t)(sizeof(oneofs) / sizeof(char*)) + firstHasIndex:-1]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +void GCFSGetDocumentRequest_ClearConsistencySelectorOneOfCase(GCFSGetDocumentRequest *message) { + GPBDescriptor *descriptor = [message descriptor]; + GPBOneofDescriptor *oneof = [descriptor.oneofs objectAtIndex:0]; + GPBMaybeClearOneof(message, oneof, -1, 0); +} +#pragma mark - GCFSListDocumentsRequest + +@implementation GCFSListDocumentsRequest + +@dynamic consistencySelectorOneOfCase; +@dynamic parent; +@dynamic collectionId; +@dynamic pageSize; +@dynamic pageToken; +@dynamic orderBy; +@dynamic hasMask, mask; +@dynamic transaction; +@dynamic readTime; +@dynamic showMissing; + +typedef struct GCFSListDocumentsRequest__storage_ { + uint32_t _has_storage_[2]; + int32_t pageSize; + NSString *parent; + NSString *collectionId; + NSString *pageToken; + NSString *orderBy; + GCFSDocumentMask *mask; + NSData *transaction; + GPBTimestamp *readTime; +} GCFSListDocumentsRequest__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "parent", + .dataTypeSpecific.className = NULL, + .number = GCFSListDocumentsRequest_FieldNumber_Parent, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GCFSListDocumentsRequest__storage_, parent), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "collectionId", + .dataTypeSpecific.className = NULL, + .number = GCFSListDocumentsRequest_FieldNumber_CollectionId, + .hasIndex = 1, + .offset = (uint32_t)offsetof(GCFSListDocumentsRequest__storage_, collectionId), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "pageSize", + .dataTypeSpecific.className = NULL, + .number = GCFSListDocumentsRequest_FieldNumber_PageSize, + .hasIndex = 2, + .offset = (uint32_t)offsetof(GCFSListDocumentsRequest__storage_, pageSize), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + { + .name = "pageToken", + .dataTypeSpecific.className = NULL, + .number = GCFSListDocumentsRequest_FieldNumber_PageToken, + .hasIndex = 3, + .offset = (uint32_t)offsetof(GCFSListDocumentsRequest__storage_, pageToken), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "orderBy", + .dataTypeSpecific.className = NULL, + .number = GCFSListDocumentsRequest_FieldNumber_OrderBy, + .hasIndex = 4, + .offset = (uint32_t)offsetof(GCFSListDocumentsRequest__storage_, orderBy), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "mask", + .dataTypeSpecific.className = GPBStringifySymbol(GCFSDocumentMask), + .number = GCFSListDocumentsRequest_FieldNumber_Mask, + .hasIndex = 5, + .offset = (uint32_t)offsetof(GCFSListDocumentsRequest__storage_, mask), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + { + .name = "transaction", + .dataTypeSpecific.className = NULL, + .number = GCFSListDocumentsRequest_FieldNumber_Transaction, + .hasIndex = -1, + .offset = (uint32_t)offsetof(GCFSListDocumentsRequest__storage_, transaction), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeBytes, + }, + { + .name = "readTime", + .dataTypeSpecific.className = GPBStringifySymbol(GPBTimestamp), + .number = GCFSListDocumentsRequest_FieldNumber_ReadTime, + .hasIndex = -1, + .offset = (uint32_t)offsetof(GCFSListDocumentsRequest__storage_, readTime), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + { + .name = "showMissing", + .dataTypeSpecific.className = NULL, + .number = GCFSListDocumentsRequest_FieldNumber_ShowMissing, + .hasIndex = 6, + .offset = 7, // Stored in _has_storage_ to save space. + .flags = GPBFieldOptional, + .dataType = GPBDataTypeBool, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GCFSListDocumentsRequest class] + rootClass:[GCFSFirestoreRoot class] + file:GCFSFirestoreRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GCFSListDocumentsRequest__storage_) + flags:GPBDescriptorInitializationFlag_None]; + static const char *oneofs[] = { + "consistencySelector", + }; + [localDescriptor setupOneofs:oneofs + count:(uint32_t)(sizeof(oneofs) / sizeof(char*)) + firstHasIndex:-1]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +void GCFSListDocumentsRequest_ClearConsistencySelectorOneOfCase(GCFSListDocumentsRequest *message) { + GPBDescriptor *descriptor = [message descriptor]; + GPBOneofDescriptor *oneof = [descriptor.oneofs objectAtIndex:0]; + GPBMaybeClearOneof(message, oneof, -1, 0); +} +#pragma mark - GCFSListDocumentsResponse + +@implementation GCFSListDocumentsResponse + +@dynamic documentsArray, documentsArray_Count; +@dynamic nextPageToken; + +typedef struct GCFSListDocumentsResponse__storage_ { + uint32_t _has_storage_[1]; + NSMutableArray *documentsArray; + NSString *nextPageToken; +} GCFSListDocumentsResponse__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "documentsArray", + .dataTypeSpecific.className = GPBStringifySymbol(GCFSDocument), + .number = GCFSListDocumentsResponse_FieldNumber_DocumentsArray, + .hasIndex = GPBNoHasBit, + .offset = (uint32_t)offsetof(GCFSListDocumentsResponse__storage_, documentsArray), + .flags = GPBFieldRepeated, + .dataType = GPBDataTypeMessage, + }, + { + .name = "nextPageToken", + .dataTypeSpecific.className = NULL, + .number = GCFSListDocumentsResponse_FieldNumber_NextPageToken, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GCFSListDocumentsResponse__storage_, nextPageToken), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GCFSListDocumentsResponse class] + rootClass:[GCFSFirestoreRoot class] + file:GCFSFirestoreRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GCFSListDocumentsResponse__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - GCFSCreateDocumentRequest + +@implementation GCFSCreateDocumentRequest + +@dynamic parent; +@dynamic collectionId; +@dynamic documentId; +@dynamic hasDocument, document; +@dynamic hasMask, mask; + +typedef struct GCFSCreateDocumentRequest__storage_ { + uint32_t _has_storage_[1]; + NSString *parent; + NSString *collectionId; + NSString *documentId; + GCFSDocument *document; + GCFSDocumentMask *mask; +} GCFSCreateDocumentRequest__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "parent", + .dataTypeSpecific.className = NULL, + .number = GCFSCreateDocumentRequest_FieldNumber_Parent, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GCFSCreateDocumentRequest__storage_, parent), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "collectionId", + .dataTypeSpecific.className = NULL, + .number = GCFSCreateDocumentRequest_FieldNumber_CollectionId, + .hasIndex = 1, + .offset = (uint32_t)offsetof(GCFSCreateDocumentRequest__storage_, collectionId), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "documentId", + .dataTypeSpecific.className = NULL, + .number = GCFSCreateDocumentRequest_FieldNumber_DocumentId, + .hasIndex = 2, + .offset = (uint32_t)offsetof(GCFSCreateDocumentRequest__storage_, documentId), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "document", + .dataTypeSpecific.className = GPBStringifySymbol(GCFSDocument), + .number = GCFSCreateDocumentRequest_FieldNumber_Document, + .hasIndex = 3, + .offset = (uint32_t)offsetof(GCFSCreateDocumentRequest__storage_, document), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + { + .name = "mask", + .dataTypeSpecific.className = GPBStringifySymbol(GCFSDocumentMask), + .number = GCFSCreateDocumentRequest_FieldNumber_Mask, + .hasIndex = 4, + .offset = (uint32_t)offsetof(GCFSCreateDocumentRequest__storage_, mask), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GCFSCreateDocumentRequest class] + rootClass:[GCFSFirestoreRoot class] + file:GCFSFirestoreRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GCFSCreateDocumentRequest__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - GCFSUpdateDocumentRequest + +@implementation GCFSUpdateDocumentRequest + +@dynamic hasDocument, document; +@dynamic hasUpdateMask, updateMask; +@dynamic hasMask, mask; +@dynamic hasCurrentDocument, currentDocument; + +typedef struct GCFSUpdateDocumentRequest__storage_ { + uint32_t _has_storage_[1]; + GCFSDocument *document; + GCFSDocumentMask *updateMask; + GCFSDocumentMask *mask; + GCFSPrecondition *currentDocument; +} GCFSUpdateDocumentRequest__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "document", + .dataTypeSpecific.className = GPBStringifySymbol(GCFSDocument), + .number = GCFSUpdateDocumentRequest_FieldNumber_Document, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GCFSUpdateDocumentRequest__storage_, document), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + { + .name = "updateMask", + .dataTypeSpecific.className = GPBStringifySymbol(GCFSDocumentMask), + .number = GCFSUpdateDocumentRequest_FieldNumber_UpdateMask, + .hasIndex = 1, + .offset = (uint32_t)offsetof(GCFSUpdateDocumentRequest__storage_, updateMask), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + { + .name = "mask", + .dataTypeSpecific.className = GPBStringifySymbol(GCFSDocumentMask), + .number = GCFSUpdateDocumentRequest_FieldNumber_Mask, + .hasIndex = 2, + .offset = (uint32_t)offsetof(GCFSUpdateDocumentRequest__storage_, mask), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + { + .name = "currentDocument", + .dataTypeSpecific.className = GPBStringifySymbol(GCFSPrecondition), + .number = GCFSUpdateDocumentRequest_FieldNumber_CurrentDocument, + .hasIndex = 3, + .offset = (uint32_t)offsetof(GCFSUpdateDocumentRequest__storage_, currentDocument), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GCFSUpdateDocumentRequest class] + rootClass:[GCFSFirestoreRoot class] + file:GCFSFirestoreRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GCFSUpdateDocumentRequest__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - GCFSDeleteDocumentRequest + +@implementation GCFSDeleteDocumentRequest + +@dynamic name; +@dynamic hasCurrentDocument, currentDocument; + +typedef struct GCFSDeleteDocumentRequest__storage_ { + uint32_t _has_storage_[1]; + NSString *name; + GCFSPrecondition *currentDocument; +} GCFSDeleteDocumentRequest__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "name", + .dataTypeSpecific.className = NULL, + .number = GCFSDeleteDocumentRequest_FieldNumber_Name, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GCFSDeleteDocumentRequest__storage_, name), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "currentDocument", + .dataTypeSpecific.className = GPBStringifySymbol(GCFSPrecondition), + .number = GCFSDeleteDocumentRequest_FieldNumber_CurrentDocument, + .hasIndex = 1, + .offset = (uint32_t)offsetof(GCFSDeleteDocumentRequest__storage_, currentDocument), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GCFSDeleteDocumentRequest class] + rootClass:[GCFSFirestoreRoot class] + file:GCFSFirestoreRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GCFSDeleteDocumentRequest__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - GCFSBatchGetDocumentsRequest + +@implementation GCFSBatchGetDocumentsRequest + +@dynamic consistencySelectorOneOfCase; +@dynamic database; +@dynamic documentsArray, documentsArray_Count; +@dynamic hasMask, mask; +@dynamic transaction; +@dynamic newTransaction; +@dynamic readTime; + +typedef struct GCFSBatchGetDocumentsRequest__storage_ { + uint32_t _has_storage_[2]; + NSString *database; + NSMutableArray *documentsArray; + GCFSDocumentMask *mask; + NSData *transaction; + GCFSTransactionOptions *newTransaction; + GPBTimestamp *readTime; +} GCFSBatchGetDocumentsRequest__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "database", + .dataTypeSpecific.className = NULL, + .number = GCFSBatchGetDocumentsRequest_FieldNumber_Database, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GCFSBatchGetDocumentsRequest__storage_, database), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "documentsArray", + .dataTypeSpecific.className = NULL, + .number = GCFSBatchGetDocumentsRequest_FieldNumber_DocumentsArray, + .hasIndex = GPBNoHasBit, + .offset = (uint32_t)offsetof(GCFSBatchGetDocumentsRequest__storage_, documentsArray), + .flags = GPBFieldRepeated, + .dataType = GPBDataTypeString, + }, + { + .name = "mask", + .dataTypeSpecific.className = GPBStringifySymbol(GCFSDocumentMask), + .number = GCFSBatchGetDocumentsRequest_FieldNumber_Mask, + .hasIndex = 1, + .offset = (uint32_t)offsetof(GCFSBatchGetDocumentsRequest__storage_, mask), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + { + .name = "transaction", + .dataTypeSpecific.className = NULL, + .number = GCFSBatchGetDocumentsRequest_FieldNumber_Transaction, + .hasIndex = -1, + .offset = (uint32_t)offsetof(GCFSBatchGetDocumentsRequest__storage_, transaction), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeBytes, + }, + { + .name = "newTransaction", + .dataTypeSpecific.className = GPBStringifySymbol(GCFSTransactionOptions), + .number = GCFSBatchGetDocumentsRequest_FieldNumber_NewTransaction, + .hasIndex = -1, + .offset = (uint32_t)offsetof(GCFSBatchGetDocumentsRequest__storage_, newTransaction), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + { + .name = "readTime", + .dataTypeSpecific.className = GPBStringifySymbol(GPBTimestamp), + .number = GCFSBatchGetDocumentsRequest_FieldNumber_ReadTime, + .hasIndex = -1, + .offset = (uint32_t)offsetof(GCFSBatchGetDocumentsRequest__storage_, readTime), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GCFSBatchGetDocumentsRequest class] + rootClass:[GCFSFirestoreRoot class] + file:GCFSFirestoreRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GCFSBatchGetDocumentsRequest__storage_) + flags:GPBDescriptorInitializationFlag_None]; + static const char *oneofs[] = { + "consistencySelector", + }; + [localDescriptor setupOneofs:oneofs + count:(uint32_t)(sizeof(oneofs) / sizeof(char*)) + firstHasIndex:-1]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +void GCFSBatchGetDocumentsRequest_ClearConsistencySelectorOneOfCase(GCFSBatchGetDocumentsRequest *message) { + GPBDescriptor *descriptor = [message descriptor]; + GPBOneofDescriptor *oneof = [descriptor.oneofs objectAtIndex:0]; + GPBMaybeClearOneof(message, oneof, -1, 0); +} +#pragma mark - GCFSBatchGetDocumentsResponse + +@implementation GCFSBatchGetDocumentsResponse + +@dynamic resultOneOfCase; +@dynamic found; +@dynamic missing; +@dynamic transaction; +@dynamic hasReadTime, readTime; + +typedef struct GCFSBatchGetDocumentsResponse__storage_ { + uint32_t _has_storage_[2]; + GCFSDocument *found; + NSString *missing; + NSData *transaction; + GPBTimestamp *readTime; +} GCFSBatchGetDocumentsResponse__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "found", + .dataTypeSpecific.className = GPBStringifySymbol(GCFSDocument), + .number = GCFSBatchGetDocumentsResponse_FieldNumber_Found, + .hasIndex = -1, + .offset = (uint32_t)offsetof(GCFSBatchGetDocumentsResponse__storage_, found), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + { + .name = "missing", + .dataTypeSpecific.className = NULL, + .number = GCFSBatchGetDocumentsResponse_FieldNumber_Missing, + .hasIndex = -1, + .offset = (uint32_t)offsetof(GCFSBatchGetDocumentsResponse__storage_, missing), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "transaction", + .dataTypeSpecific.className = NULL, + .number = GCFSBatchGetDocumentsResponse_FieldNumber_Transaction, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GCFSBatchGetDocumentsResponse__storage_, transaction), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeBytes, + }, + { + .name = "readTime", + .dataTypeSpecific.className = GPBStringifySymbol(GPBTimestamp), + .number = GCFSBatchGetDocumentsResponse_FieldNumber_ReadTime, + .hasIndex = 1, + .offset = (uint32_t)offsetof(GCFSBatchGetDocumentsResponse__storage_, readTime), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GCFSBatchGetDocumentsResponse class] + rootClass:[GCFSFirestoreRoot class] + file:GCFSFirestoreRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GCFSBatchGetDocumentsResponse__storage_) + flags:GPBDescriptorInitializationFlag_None]; + static const char *oneofs[] = { + "result", + }; + [localDescriptor setupOneofs:oneofs + count:(uint32_t)(sizeof(oneofs) / sizeof(char*)) + firstHasIndex:-1]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +void GCFSBatchGetDocumentsResponse_ClearResultOneOfCase(GCFSBatchGetDocumentsResponse *message) { + GPBDescriptor *descriptor = [message descriptor]; + GPBOneofDescriptor *oneof = [descriptor.oneofs objectAtIndex:0]; + GPBMaybeClearOneof(message, oneof, -1, 0); +} +#pragma mark - GCFSBeginTransactionRequest + +@implementation GCFSBeginTransactionRequest + +@dynamic database; +@dynamic hasOptions, options; + +typedef struct GCFSBeginTransactionRequest__storage_ { + uint32_t _has_storage_[1]; + NSString *database; + GCFSTransactionOptions *options; +} GCFSBeginTransactionRequest__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "database", + .dataTypeSpecific.className = NULL, + .number = GCFSBeginTransactionRequest_FieldNumber_Database, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GCFSBeginTransactionRequest__storage_, database), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "options", + .dataTypeSpecific.className = GPBStringifySymbol(GCFSTransactionOptions), + .number = GCFSBeginTransactionRequest_FieldNumber_Options, + .hasIndex = 1, + .offset = (uint32_t)offsetof(GCFSBeginTransactionRequest__storage_, options), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GCFSBeginTransactionRequest class] + rootClass:[GCFSFirestoreRoot class] + file:GCFSFirestoreRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GCFSBeginTransactionRequest__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - GCFSBeginTransactionResponse + +@implementation GCFSBeginTransactionResponse + +@dynamic transaction; + +typedef struct GCFSBeginTransactionResponse__storage_ { + uint32_t _has_storage_[1]; + NSData *transaction; +} GCFSBeginTransactionResponse__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "transaction", + .dataTypeSpecific.className = NULL, + .number = GCFSBeginTransactionResponse_FieldNumber_Transaction, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GCFSBeginTransactionResponse__storage_, transaction), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeBytes, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GCFSBeginTransactionResponse class] + rootClass:[GCFSFirestoreRoot class] + file:GCFSFirestoreRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GCFSBeginTransactionResponse__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - GCFSCommitRequest + +@implementation GCFSCommitRequest + +@dynamic database; +@dynamic writesArray, writesArray_Count; +@dynamic transaction; + +typedef struct GCFSCommitRequest__storage_ { + uint32_t _has_storage_[1]; + NSString *database; + NSMutableArray *writesArray; + NSData *transaction; +} GCFSCommitRequest__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "database", + .dataTypeSpecific.className = NULL, + .number = GCFSCommitRequest_FieldNumber_Database, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GCFSCommitRequest__storage_, database), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "writesArray", + .dataTypeSpecific.className = GPBStringifySymbol(GCFSWrite), + .number = GCFSCommitRequest_FieldNumber_WritesArray, + .hasIndex = GPBNoHasBit, + .offset = (uint32_t)offsetof(GCFSCommitRequest__storage_, writesArray), + .flags = GPBFieldRepeated, + .dataType = GPBDataTypeMessage, + }, + { + .name = "transaction", + .dataTypeSpecific.className = NULL, + .number = GCFSCommitRequest_FieldNumber_Transaction, + .hasIndex = 1, + .offset = (uint32_t)offsetof(GCFSCommitRequest__storage_, transaction), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeBytes, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GCFSCommitRequest class] + rootClass:[GCFSFirestoreRoot class] + file:GCFSFirestoreRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GCFSCommitRequest__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - GCFSCommitResponse + +@implementation GCFSCommitResponse + +@dynamic writeResultsArray, writeResultsArray_Count; +@dynamic hasCommitTime, commitTime; + +typedef struct GCFSCommitResponse__storage_ { + uint32_t _has_storage_[1]; + NSMutableArray *writeResultsArray; + GPBTimestamp *commitTime; +} GCFSCommitResponse__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "writeResultsArray", + .dataTypeSpecific.className = GPBStringifySymbol(GCFSWriteResult), + .number = GCFSCommitResponse_FieldNumber_WriteResultsArray, + .hasIndex = GPBNoHasBit, + .offset = (uint32_t)offsetof(GCFSCommitResponse__storage_, writeResultsArray), + .flags = GPBFieldRepeated, + .dataType = GPBDataTypeMessage, + }, + { + .name = "commitTime", + .dataTypeSpecific.className = GPBStringifySymbol(GPBTimestamp), + .number = GCFSCommitResponse_FieldNumber_CommitTime, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GCFSCommitResponse__storage_, commitTime), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GCFSCommitResponse class] + rootClass:[GCFSFirestoreRoot class] + file:GCFSFirestoreRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GCFSCommitResponse__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - GCFSRollbackRequest + +@implementation GCFSRollbackRequest + +@dynamic database; +@dynamic transaction; + +typedef struct GCFSRollbackRequest__storage_ { + uint32_t _has_storage_[1]; + NSString *database; + NSData *transaction; +} GCFSRollbackRequest__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "database", + .dataTypeSpecific.className = NULL, + .number = GCFSRollbackRequest_FieldNumber_Database, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GCFSRollbackRequest__storage_, database), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "transaction", + .dataTypeSpecific.className = NULL, + .number = GCFSRollbackRequest_FieldNumber_Transaction, + .hasIndex = 1, + .offset = (uint32_t)offsetof(GCFSRollbackRequest__storage_, transaction), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeBytes, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GCFSRollbackRequest class] + rootClass:[GCFSFirestoreRoot class] + file:GCFSFirestoreRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GCFSRollbackRequest__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - GCFSRunQueryRequest + +@implementation GCFSRunQueryRequest + +@dynamic queryTypeOneOfCase; +@dynamic consistencySelectorOneOfCase; +@dynamic parent; +@dynamic structuredQuery; +@dynamic transaction; +@dynamic newTransaction; +@dynamic readTime; + +typedef struct GCFSRunQueryRequest__storage_ { + uint32_t _has_storage_[3]; + NSString *parent; + GCFSStructuredQuery *structuredQuery; + NSData *transaction; + GCFSTransactionOptions *newTransaction; + GPBTimestamp *readTime; +} GCFSRunQueryRequest__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "parent", + .dataTypeSpecific.className = NULL, + .number = GCFSRunQueryRequest_FieldNumber_Parent, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GCFSRunQueryRequest__storage_, parent), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "structuredQuery", + .dataTypeSpecific.className = GPBStringifySymbol(GCFSStructuredQuery), + .number = GCFSRunQueryRequest_FieldNumber_StructuredQuery, + .hasIndex = -1, + .offset = (uint32_t)offsetof(GCFSRunQueryRequest__storage_, structuredQuery), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + { + .name = "transaction", + .dataTypeSpecific.className = NULL, + .number = GCFSRunQueryRequest_FieldNumber_Transaction, + .hasIndex = -2, + .offset = (uint32_t)offsetof(GCFSRunQueryRequest__storage_, transaction), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeBytes, + }, + { + .name = "newTransaction", + .dataTypeSpecific.className = GPBStringifySymbol(GCFSTransactionOptions), + .number = GCFSRunQueryRequest_FieldNumber_NewTransaction, + .hasIndex = -2, + .offset = (uint32_t)offsetof(GCFSRunQueryRequest__storage_, newTransaction), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + { + .name = "readTime", + .dataTypeSpecific.className = GPBStringifySymbol(GPBTimestamp), + .number = GCFSRunQueryRequest_FieldNumber_ReadTime, + .hasIndex = -2, + .offset = (uint32_t)offsetof(GCFSRunQueryRequest__storage_, readTime), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GCFSRunQueryRequest class] + rootClass:[GCFSFirestoreRoot class] + file:GCFSFirestoreRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GCFSRunQueryRequest__storage_) + flags:GPBDescriptorInitializationFlag_None]; + static const char *oneofs[] = { + "queryType", + "consistencySelector", + }; + [localDescriptor setupOneofs:oneofs + count:(uint32_t)(sizeof(oneofs) / sizeof(char*)) + firstHasIndex:-1]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +void GCFSRunQueryRequest_ClearQueryTypeOneOfCase(GCFSRunQueryRequest *message) { + GPBDescriptor *descriptor = [message descriptor]; + GPBOneofDescriptor *oneof = [descriptor.oneofs objectAtIndex:0]; + GPBMaybeClearOneof(message, oneof, -1, 0); +} +void GCFSRunQueryRequest_ClearConsistencySelectorOneOfCase(GCFSRunQueryRequest *message) { + GPBDescriptor *descriptor = [message descriptor]; + GPBOneofDescriptor *oneof = [descriptor.oneofs objectAtIndex:1]; + GPBMaybeClearOneof(message, oneof, -2, 0); +} +#pragma mark - GCFSRunQueryResponse + +@implementation GCFSRunQueryResponse + +@dynamic transaction; +@dynamic hasDocument, document; +@dynamic hasReadTime, readTime; +@dynamic skippedResults; + +typedef struct GCFSRunQueryResponse__storage_ { + uint32_t _has_storage_[1]; + int32_t skippedResults; + GCFSDocument *document; + NSData *transaction; + GPBTimestamp *readTime; +} GCFSRunQueryResponse__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "document", + .dataTypeSpecific.className = GPBStringifySymbol(GCFSDocument), + .number = GCFSRunQueryResponse_FieldNumber_Document, + .hasIndex = 1, + .offset = (uint32_t)offsetof(GCFSRunQueryResponse__storage_, document), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + { + .name = "transaction", + .dataTypeSpecific.className = NULL, + .number = GCFSRunQueryResponse_FieldNumber_Transaction, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GCFSRunQueryResponse__storage_, transaction), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeBytes, + }, + { + .name = "readTime", + .dataTypeSpecific.className = GPBStringifySymbol(GPBTimestamp), + .number = GCFSRunQueryResponse_FieldNumber_ReadTime, + .hasIndex = 2, + .offset = (uint32_t)offsetof(GCFSRunQueryResponse__storage_, readTime), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + { + .name = "skippedResults", + .dataTypeSpecific.className = NULL, + .number = GCFSRunQueryResponse_FieldNumber_SkippedResults, + .hasIndex = 3, + .offset = (uint32_t)offsetof(GCFSRunQueryResponse__storage_, skippedResults), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GCFSRunQueryResponse class] + rootClass:[GCFSFirestoreRoot class] + file:GCFSFirestoreRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GCFSRunQueryResponse__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - GCFSWriteRequest + +@implementation GCFSWriteRequest + +@dynamic database; +@dynamic streamId; +@dynamic writesArray, writesArray_Count; +@dynamic streamToken; +@dynamic labels, labels_Count; + +typedef struct GCFSWriteRequest__storage_ { + uint32_t _has_storage_[1]; + NSString *database; + NSString *streamId; + NSMutableArray *writesArray; + NSData *streamToken; + NSMutableDictionary *labels; +} GCFSWriteRequest__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "database", + .dataTypeSpecific.className = NULL, + .number = GCFSWriteRequest_FieldNumber_Database, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GCFSWriteRequest__storage_, database), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "streamId", + .dataTypeSpecific.className = NULL, + .number = GCFSWriteRequest_FieldNumber_StreamId, + .hasIndex = 1, + .offset = (uint32_t)offsetof(GCFSWriteRequest__storage_, streamId), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "writesArray", + .dataTypeSpecific.className = GPBStringifySymbol(GCFSWrite), + .number = GCFSWriteRequest_FieldNumber_WritesArray, + .hasIndex = GPBNoHasBit, + .offset = (uint32_t)offsetof(GCFSWriteRequest__storage_, writesArray), + .flags = GPBFieldRepeated, + .dataType = GPBDataTypeMessage, + }, + { + .name = "streamToken", + .dataTypeSpecific.className = NULL, + .number = GCFSWriteRequest_FieldNumber_StreamToken, + .hasIndex = 2, + .offset = (uint32_t)offsetof(GCFSWriteRequest__storage_, streamToken), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeBytes, + }, + { + .name = "labels", + .dataTypeSpecific.className = NULL, + .number = GCFSWriteRequest_FieldNumber_Labels, + .hasIndex = GPBNoHasBit, + .offset = (uint32_t)offsetof(GCFSWriteRequest__storage_, labels), + .flags = GPBFieldMapKeyString, + .dataType = GPBDataTypeString, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GCFSWriteRequest class] + rootClass:[GCFSFirestoreRoot class] + file:GCFSFirestoreRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GCFSWriteRequest__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - GCFSWriteResponse + +@implementation GCFSWriteResponse + +@dynamic streamId; +@dynamic streamToken; +@dynamic writeResultsArray, writeResultsArray_Count; +@dynamic hasCommitTime, commitTime; + +typedef struct GCFSWriteResponse__storage_ { + uint32_t _has_storage_[1]; + NSString *streamId; + NSData *streamToken; + NSMutableArray *writeResultsArray; + GPBTimestamp *commitTime; +} GCFSWriteResponse__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "streamId", + .dataTypeSpecific.className = NULL, + .number = GCFSWriteResponse_FieldNumber_StreamId, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GCFSWriteResponse__storage_, streamId), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "streamToken", + .dataTypeSpecific.className = NULL, + .number = GCFSWriteResponse_FieldNumber_StreamToken, + .hasIndex = 1, + .offset = (uint32_t)offsetof(GCFSWriteResponse__storage_, streamToken), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeBytes, + }, + { + .name = "writeResultsArray", + .dataTypeSpecific.className = GPBStringifySymbol(GCFSWriteResult), + .number = GCFSWriteResponse_FieldNumber_WriteResultsArray, + .hasIndex = GPBNoHasBit, + .offset = (uint32_t)offsetof(GCFSWriteResponse__storage_, writeResultsArray), + .flags = GPBFieldRepeated, + .dataType = GPBDataTypeMessage, + }, + { + .name = "commitTime", + .dataTypeSpecific.className = GPBStringifySymbol(GPBTimestamp), + .number = GCFSWriteResponse_FieldNumber_CommitTime, + .hasIndex = 2, + .offset = (uint32_t)offsetof(GCFSWriteResponse__storage_, commitTime), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GCFSWriteResponse class] + rootClass:[GCFSFirestoreRoot class] + file:GCFSFirestoreRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GCFSWriteResponse__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - GCFSListenRequest + +@implementation GCFSListenRequest + +@dynamic targetChangeOneOfCase; +@dynamic database; +@dynamic addTarget; +@dynamic removeTarget; +@dynamic labels, labels_Count; + +typedef struct GCFSListenRequest__storage_ { + uint32_t _has_storage_[2]; + int32_t removeTarget; + NSString *database; + GCFSTarget *addTarget; + NSMutableDictionary *labels; +} GCFSListenRequest__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "database", + .dataTypeSpecific.className = NULL, + .number = GCFSListenRequest_FieldNumber_Database, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GCFSListenRequest__storage_, database), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "addTarget", + .dataTypeSpecific.className = GPBStringifySymbol(GCFSTarget), + .number = GCFSListenRequest_FieldNumber_AddTarget, + .hasIndex = -1, + .offset = (uint32_t)offsetof(GCFSListenRequest__storage_, addTarget), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + { + .name = "removeTarget", + .dataTypeSpecific.className = NULL, + .number = GCFSListenRequest_FieldNumber_RemoveTarget, + .hasIndex = -1, + .offset = (uint32_t)offsetof(GCFSListenRequest__storage_, removeTarget), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + { + .name = "labels", + .dataTypeSpecific.className = NULL, + .number = GCFSListenRequest_FieldNumber_Labels, + .hasIndex = GPBNoHasBit, + .offset = (uint32_t)offsetof(GCFSListenRequest__storage_, labels), + .flags = GPBFieldMapKeyString, + .dataType = GPBDataTypeString, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GCFSListenRequest class] + rootClass:[GCFSFirestoreRoot class] + file:GCFSFirestoreRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GCFSListenRequest__storage_) + flags:GPBDescriptorInitializationFlag_None]; + static const char *oneofs[] = { + "targetChange", + }; + [localDescriptor setupOneofs:oneofs + count:(uint32_t)(sizeof(oneofs) / sizeof(char*)) + firstHasIndex:-1]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +void GCFSListenRequest_ClearTargetChangeOneOfCase(GCFSListenRequest *message) { + GPBDescriptor *descriptor = [message descriptor]; + GPBOneofDescriptor *oneof = [descriptor.oneofs objectAtIndex:0]; + GPBMaybeClearOneof(message, oneof, -1, 0); +} +#pragma mark - GCFSListenResponse + +@implementation GCFSListenResponse + +@dynamic responseTypeOneOfCase; +@dynamic targetChange; +@dynamic documentChange; +@dynamic documentDelete; +@dynamic documentRemove; +@dynamic filter; + +typedef struct GCFSListenResponse__storage_ { + uint32_t _has_storage_[2]; + GCFSTargetChange *targetChange; + GCFSDocumentChange *documentChange; + GCFSDocumentDelete *documentDelete; + GCFSExistenceFilter *filter; + GCFSDocumentRemove *documentRemove; +} GCFSListenResponse__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "targetChange", + .dataTypeSpecific.className = GPBStringifySymbol(GCFSTargetChange), + .number = GCFSListenResponse_FieldNumber_TargetChange, + .hasIndex = -1, + .offset = (uint32_t)offsetof(GCFSListenResponse__storage_, targetChange), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + { + .name = "documentChange", + .dataTypeSpecific.className = GPBStringifySymbol(GCFSDocumentChange), + .number = GCFSListenResponse_FieldNumber_DocumentChange, + .hasIndex = -1, + .offset = (uint32_t)offsetof(GCFSListenResponse__storage_, documentChange), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + { + .name = "documentDelete", + .dataTypeSpecific.className = GPBStringifySymbol(GCFSDocumentDelete), + .number = GCFSListenResponse_FieldNumber_DocumentDelete, + .hasIndex = -1, + .offset = (uint32_t)offsetof(GCFSListenResponse__storage_, documentDelete), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + { + .name = "filter", + .dataTypeSpecific.className = GPBStringifySymbol(GCFSExistenceFilter), + .number = GCFSListenResponse_FieldNumber_Filter, + .hasIndex = -1, + .offset = (uint32_t)offsetof(GCFSListenResponse__storage_, filter), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + { + .name = "documentRemove", + .dataTypeSpecific.className = GPBStringifySymbol(GCFSDocumentRemove), + .number = GCFSListenResponse_FieldNumber_DocumentRemove, + .hasIndex = -1, + .offset = (uint32_t)offsetof(GCFSListenResponse__storage_, documentRemove), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GCFSListenResponse class] + rootClass:[GCFSFirestoreRoot class] + file:GCFSFirestoreRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GCFSListenResponse__storage_) + flags:GPBDescriptorInitializationFlag_None]; + static const char *oneofs[] = { + "responseType", + }; + [localDescriptor setupOneofs:oneofs + count:(uint32_t)(sizeof(oneofs) / sizeof(char*)) + firstHasIndex:-1]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +void GCFSListenResponse_ClearResponseTypeOneOfCase(GCFSListenResponse *message) { + GPBDescriptor *descriptor = [message descriptor]; + GPBOneofDescriptor *oneof = [descriptor.oneofs objectAtIndex:0]; + GPBMaybeClearOneof(message, oneof, -1, 0); +} +#pragma mark - GCFSTarget + +@implementation GCFSTarget + +@dynamic targetTypeOneOfCase; +@dynamic resumeTypeOneOfCase; +@dynamic query; +@dynamic documents; +@dynamic resumeToken; +@dynamic readTime; +@dynamic targetId; +@dynamic once; + +typedef struct GCFSTarget__storage_ { + uint32_t _has_storage_[3]; + int32_t targetId; + GCFSTarget_QueryTarget *query; + GCFSTarget_DocumentsTarget *documents; + NSData *resumeToken; + GPBTimestamp *readTime; +} GCFSTarget__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "query", + .dataTypeSpecific.className = GPBStringifySymbol(GCFSTarget_QueryTarget), + .number = GCFSTarget_FieldNumber_Query, + .hasIndex = -1, + .offset = (uint32_t)offsetof(GCFSTarget__storage_, query), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + { + .name = "documents", + .dataTypeSpecific.className = GPBStringifySymbol(GCFSTarget_DocumentsTarget), + .number = GCFSTarget_FieldNumber_Documents, + .hasIndex = -1, + .offset = (uint32_t)offsetof(GCFSTarget__storage_, documents), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + { + .name = "resumeToken", + .dataTypeSpecific.className = NULL, + .number = GCFSTarget_FieldNumber_ResumeToken, + .hasIndex = -2, + .offset = (uint32_t)offsetof(GCFSTarget__storage_, resumeToken), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeBytes, + }, + { + .name = "targetId", + .dataTypeSpecific.className = NULL, + .number = GCFSTarget_FieldNumber_TargetId, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GCFSTarget__storage_, targetId), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + { + .name = "once", + .dataTypeSpecific.className = NULL, + .number = GCFSTarget_FieldNumber_Once, + .hasIndex = 1, + .offset = 2, // Stored in _has_storage_ to save space. + .flags = GPBFieldOptional, + .dataType = GPBDataTypeBool, + }, + { + .name = "readTime", + .dataTypeSpecific.className = GPBStringifySymbol(GPBTimestamp), + .number = GCFSTarget_FieldNumber_ReadTime, + .hasIndex = -2, + .offset = (uint32_t)offsetof(GCFSTarget__storage_, readTime), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GCFSTarget class] + rootClass:[GCFSFirestoreRoot class] + file:GCFSFirestoreRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GCFSTarget__storage_) + flags:GPBDescriptorInitializationFlag_None]; + static const char *oneofs[] = { + "targetType", + "resumeType", + }; + [localDescriptor setupOneofs:oneofs + count:(uint32_t)(sizeof(oneofs) / sizeof(char*)) + firstHasIndex:-1]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +void GCFSTarget_ClearTargetTypeOneOfCase(GCFSTarget *message) { + GPBDescriptor *descriptor = [message descriptor]; + GPBOneofDescriptor *oneof = [descriptor.oneofs objectAtIndex:0]; + GPBMaybeClearOneof(message, oneof, -1, 0); +} +void GCFSTarget_ClearResumeTypeOneOfCase(GCFSTarget *message) { + GPBDescriptor *descriptor = [message descriptor]; + GPBOneofDescriptor *oneof = [descriptor.oneofs objectAtIndex:1]; + GPBMaybeClearOneof(message, oneof, -2, 0); +} +#pragma mark - GCFSTarget_DocumentsTarget + +@implementation GCFSTarget_DocumentsTarget + +@dynamic documentsArray, documentsArray_Count; + +typedef struct GCFSTarget_DocumentsTarget__storage_ { + uint32_t _has_storage_[1]; + NSMutableArray *documentsArray; +} GCFSTarget_DocumentsTarget__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "documentsArray", + .dataTypeSpecific.className = NULL, + .number = GCFSTarget_DocumentsTarget_FieldNumber_DocumentsArray, + .hasIndex = GPBNoHasBit, + .offset = (uint32_t)offsetof(GCFSTarget_DocumentsTarget__storage_, documentsArray), + .flags = GPBFieldRepeated, + .dataType = GPBDataTypeString, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GCFSTarget_DocumentsTarget class] + rootClass:[GCFSFirestoreRoot class] + file:GCFSFirestoreRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GCFSTarget_DocumentsTarget__storage_) + flags:GPBDescriptorInitializationFlag_None]; + [localDescriptor setupContainingMessageClassName:GPBStringifySymbol(GCFSTarget)]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - GCFSTarget_QueryTarget + +@implementation GCFSTarget_QueryTarget + +@dynamic queryTypeOneOfCase; +@dynamic parent; +@dynamic structuredQuery; + +typedef struct GCFSTarget_QueryTarget__storage_ { + uint32_t _has_storage_[2]; + NSString *parent; + GCFSStructuredQuery *structuredQuery; +} GCFSTarget_QueryTarget__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "parent", + .dataTypeSpecific.className = NULL, + .number = GCFSTarget_QueryTarget_FieldNumber_Parent, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GCFSTarget_QueryTarget__storage_, parent), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "structuredQuery", + .dataTypeSpecific.className = GPBStringifySymbol(GCFSStructuredQuery), + .number = GCFSTarget_QueryTarget_FieldNumber_StructuredQuery, + .hasIndex = -1, + .offset = (uint32_t)offsetof(GCFSTarget_QueryTarget__storage_, structuredQuery), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GCFSTarget_QueryTarget class] + rootClass:[GCFSFirestoreRoot class] + file:GCFSFirestoreRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GCFSTarget_QueryTarget__storage_) + flags:GPBDescriptorInitializationFlag_None]; + static const char *oneofs[] = { + "queryType", + }; + [localDescriptor setupOneofs:oneofs + count:(uint32_t)(sizeof(oneofs) / sizeof(char*)) + firstHasIndex:-1]; + [localDescriptor setupContainingMessageClassName:GPBStringifySymbol(GCFSTarget)]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +void GCFSTarget_QueryTarget_ClearQueryTypeOneOfCase(GCFSTarget_QueryTarget *message) { + GPBDescriptor *descriptor = [message descriptor]; + GPBOneofDescriptor *oneof = [descriptor.oneofs objectAtIndex:0]; + GPBMaybeClearOneof(message, oneof, -1, 0); +} +#pragma mark - GCFSTargetChange + +@implementation GCFSTargetChange + +@dynamic targetChangeType; +@dynamic targetIdsArray, targetIdsArray_Count; +@dynamic hasCause, cause; +@dynamic resumeToken; +@dynamic hasReadTime, readTime; + +typedef struct GCFSTargetChange__storage_ { + uint32_t _has_storage_[1]; + GCFSTargetChange_TargetChangeType targetChangeType; + GPBInt32Array *targetIdsArray; + RPCStatus *cause; + NSData *resumeToken; + GPBTimestamp *readTime; +} GCFSTargetChange__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "targetChangeType", + .dataTypeSpecific.enumDescFunc = GCFSTargetChange_TargetChangeType_EnumDescriptor, + .number = GCFSTargetChange_FieldNumber_TargetChangeType, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GCFSTargetChange__storage_, targetChangeType), + .flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldHasEnumDescriptor), + .dataType = GPBDataTypeEnum, + }, + { + .name = "targetIdsArray", + .dataTypeSpecific.className = NULL, + .number = GCFSTargetChange_FieldNumber_TargetIdsArray, + .hasIndex = GPBNoHasBit, + .offset = (uint32_t)offsetof(GCFSTargetChange__storage_, targetIdsArray), + .flags = (GPBFieldFlags)(GPBFieldRepeated | GPBFieldPacked), + .dataType = GPBDataTypeInt32, + }, + { + .name = "cause", + .dataTypeSpecific.className = GPBStringifySymbol(RPCStatus), + .number = GCFSTargetChange_FieldNumber_Cause, + .hasIndex = 1, + .offset = (uint32_t)offsetof(GCFSTargetChange__storage_, cause), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + { + .name = "resumeToken", + .dataTypeSpecific.className = NULL, + .number = GCFSTargetChange_FieldNumber_ResumeToken, + .hasIndex = 2, + .offset = (uint32_t)offsetof(GCFSTargetChange__storage_, resumeToken), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeBytes, + }, + { + .name = "readTime", + .dataTypeSpecific.className = GPBStringifySymbol(GPBTimestamp), + .number = GCFSTargetChange_FieldNumber_ReadTime, + .hasIndex = 3, + .offset = (uint32_t)offsetof(GCFSTargetChange__storage_, readTime), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GCFSTargetChange class] + rootClass:[GCFSFirestoreRoot class] + file:GCFSFirestoreRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GCFSTargetChange__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +int32_t GCFSTargetChange_TargetChangeType_RawValue(GCFSTargetChange *message) { + GPBDescriptor *descriptor = [GCFSTargetChange descriptor]; + GPBFieldDescriptor *field = [descriptor fieldWithNumber:GCFSTargetChange_FieldNumber_TargetChangeType]; + return GPBGetMessageInt32Field(message, field); +} + +void SetGCFSTargetChange_TargetChangeType_RawValue(GCFSTargetChange *message, int32_t value) { + GPBDescriptor *descriptor = [GCFSTargetChange descriptor]; + GPBFieldDescriptor *field = [descriptor fieldWithNumber:GCFSTargetChange_FieldNumber_TargetChangeType]; + GPBSetInt32IvarWithFieldInternal(message, field, value, descriptor.file.syntax); +} + +#pragma mark - Enum GCFSTargetChange_TargetChangeType + +GPBEnumDescriptor *GCFSTargetChange_TargetChangeType_EnumDescriptor(void) { + static GPBEnumDescriptor *descriptor = NULL; + if (!descriptor) { + static const char *valueNames = + "NoChange\000Add\000Remove\000Current\000Reset\000"; + static const int32_t values[] = { + GCFSTargetChange_TargetChangeType_NoChange, + GCFSTargetChange_TargetChangeType_Add, + GCFSTargetChange_TargetChangeType_Remove, + GCFSTargetChange_TargetChangeType_Current, + GCFSTargetChange_TargetChangeType_Reset, + }; + GPBEnumDescriptor *worker = + [GPBEnumDescriptor allocDescriptorForName:GPBNSStringifySymbol(GCFSTargetChange_TargetChangeType) + valueNames:valueNames + values:values + count:(uint32_t)(sizeof(values) / sizeof(int32_t)) + enumVerifier:GCFSTargetChange_TargetChangeType_IsValidValue]; + if (!OSAtomicCompareAndSwapPtrBarrier(nil, worker, (void * volatile *)&descriptor)) { + [worker release]; + } + } + return descriptor; +} + +BOOL GCFSTargetChange_TargetChangeType_IsValidValue(int32_t value__) { + switch (value__) { + case GCFSTargetChange_TargetChangeType_NoChange: + case GCFSTargetChange_TargetChangeType_Add: + case GCFSTargetChange_TargetChangeType_Remove: + case GCFSTargetChange_TargetChangeType_Current: + case GCFSTargetChange_TargetChangeType_Reset: + return YES; + default: + return NO; + } +} + +#pragma mark - GCFSListCollectionIdsRequest + +@implementation GCFSListCollectionIdsRequest + +@dynamic parent; +@dynamic pageSize; +@dynamic pageToken; + +typedef struct GCFSListCollectionIdsRequest__storage_ { + uint32_t _has_storage_[1]; + int32_t pageSize; + NSString *parent; + NSString *pageToken; +} GCFSListCollectionIdsRequest__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "parent", + .dataTypeSpecific.className = NULL, + .number = GCFSListCollectionIdsRequest_FieldNumber_Parent, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GCFSListCollectionIdsRequest__storage_, parent), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "pageSize", + .dataTypeSpecific.className = NULL, + .number = GCFSListCollectionIdsRequest_FieldNumber_PageSize, + .hasIndex = 1, + .offset = (uint32_t)offsetof(GCFSListCollectionIdsRequest__storage_, pageSize), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + { + .name = "pageToken", + .dataTypeSpecific.className = NULL, + .number = GCFSListCollectionIdsRequest_FieldNumber_PageToken, + .hasIndex = 2, + .offset = (uint32_t)offsetof(GCFSListCollectionIdsRequest__storage_, pageToken), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GCFSListCollectionIdsRequest class] + rootClass:[GCFSFirestoreRoot class] + file:GCFSFirestoreRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GCFSListCollectionIdsRequest__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - GCFSListCollectionIdsResponse + +@implementation GCFSListCollectionIdsResponse + +@dynamic collectionIdsArray, collectionIdsArray_Count; +@dynamic nextPageToken; + +typedef struct GCFSListCollectionIdsResponse__storage_ { + uint32_t _has_storage_[1]; + NSMutableArray *collectionIdsArray; + NSString *nextPageToken; +} GCFSListCollectionIdsResponse__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "collectionIdsArray", + .dataTypeSpecific.className = NULL, + .number = GCFSListCollectionIdsResponse_FieldNumber_CollectionIdsArray, + .hasIndex = GPBNoHasBit, + .offset = (uint32_t)offsetof(GCFSListCollectionIdsResponse__storage_, collectionIdsArray), + .flags = GPBFieldRepeated, + .dataType = GPBDataTypeString, + }, + { + .name = "nextPageToken", + .dataTypeSpecific.className = NULL, + .number = GCFSListCollectionIdsResponse_FieldNumber_NextPageToken, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GCFSListCollectionIdsResponse__storage_, nextPageToken), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GCFSListCollectionIdsResponse class] + rootClass:[GCFSFirestoreRoot class] + file:GCFSFirestoreRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GCFSListCollectionIdsResponse__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + + +#pragma clang diagnostic pop + +// @@protoc_insertion_point(global_scope) diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/objc/google/firestore/v1/Query.pbobjc.h b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/objc/google/firestore/v1/Query.pbobjc.h new file mode 100644 index 0000000..e4ff487 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/objc/google/firestore/v1/Query.pbobjc.h @@ -0,0 +1,582 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/firestore/v1/query.proto + +// This CPP symbol can be defined to use imports that match up to the framework +// imports needed when using CocoaPods. +#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) + #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 +#endif + +#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS + #import +#else + #import "GPBProtocolBuffers.h" +#endif + +#if GOOGLE_PROTOBUF_OBJC_VERSION < 30002 +#error This file was generated by a newer version of protoc which is incompatible with your Protocol Buffer library sources. +#endif +#if 30002 < GOOGLE_PROTOBUF_OBJC_MIN_SUPPORTED_VERSION +#error This file was generated by an older version of protoc which is incompatible with your Protocol Buffer library sources. +#endif + +// @@protoc_insertion_point(imports) + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + +CF_EXTERN_C_BEGIN + +@class GCFSCursor; +@class GCFSStructuredQuery_CollectionSelector; +@class GCFSStructuredQuery_CompositeFilter; +@class GCFSStructuredQuery_FieldFilter; +@class GCFSStructuredQuery_FieldReference; +@class GCFSStructuredQuery_Filter; +@class GCFSStructuredQuery_Order; +@class GCFSStructuredQuery_Projection; +@class GCFSStructuredQuery_UnaryFilter; +@class GCFSValue; +@class GPBInt32Value; + +NS_ASSUME_NONNULL_BEGIN + +#pragma mark - Enum GCFSStructuredQuery_Direction + +/** A sort direction. */ +typedef GPB_ENUM(GCFSStructuredQuery_Direction) { + /** + * Value used if any message's field encounters a value that is not defined + * by this enum. The message will also have C functions to get/set the rawValue + * of the field. + **/ + GCFSStructuredQuery_Direction_GPBUnrecognizedEnumeratorValue = kGPBUnrecognizedEnumeratorValue, + /** Unspecified. */ + GCFSStructuredQuery_Direction_DirectionUnspecified = 0, + + /** Ascending. */ + GCFSStructuredQuery_Direction_Ascending = 1, + + /** Descending. */ + GCFSStructuredQuery_Direction_Descending = 2, +}; + +GPBEnumDescriptor *GCFSStructuredQuery_Direction_EnumDescriptor(void); + +/** + * Checks to see if the given value is defined by the enum or was not known at + * the time this source was generated. + **/ +BOOL GCFSStructuredQuery_Direction_IsValidValue(int32_t value); + +#pragma mark - Enum GCFSStructuredQuery_CompositeFilter_Operator + +/** A composite filter operator. */ +typedef GPB_ENUM(GCFSStructuredQuery_CompositeFilter_Operator) { + /** + * Value used if any message's field encounters a value that is not defined + * by this enum. The message will also have C functions to get/set the rawValue + * of the field. + **/ + GCFSStructuredQuery_CompositeFilter_Operator_GPBUnrecognizedEnumeratorValue = kGPBUnrecognizedEnumeratorValue, + /** Unspecified. This value must not be used. */ + GCFSStructuredQuery_CompositeFilter_Operator_OperatorUnspecified = 0, + + /** The results are required to satisfy each of the combined filters. */ + GCFSStructuredQuery_CompositeFilter_Operator_And = 1, +}; + +GPBEnumDescriptor *GCFSStructuredQuery_CompositeFilter_Operator_EnumDescriptor(void); + +/** + * Checks to see if the given value is defined by the enum or was not known at + * the time this source was generated. + **/ +BOOL GCFSStructuredQuery_CompositeFilter_Operator_IsValidValue(int32_t value); + +#pragma mark - Enum GCFSStructuredQuery_FieldFilter_Operator + +/** A field filter operator. */ +typedef GPB_ENUM(GCFSStructuredQuery_FieldFilter_Operator) { + /** + * Value used if any message's field encounters a value that is not defined + * by this enum. The message will also have C functions to get/set the rawValue + * of the field. + **/ + GCFSStructuredQuery_FieldFilter_Operator_GPBUnrecognizedEnumeratorValue = kGPBUnrecognizedEnumeratorValue, + /** Unspecified. This value must not be used. */ + GCFSStructuredQuery_FieldFilter_Operator_OperatorUnspecified = 0, + + /** Less than. Requires that the field come first in `order_by`. */ + GCFSStructuredQuery_FieldFilter_Operator_LessThan = 1, + + /** Less than or equal. Requires that the field come first in `order_by`. */ + GCFSStructuredQuery_FieldFilter_Operator_LessThanOrEqual = 2, + + /** Greater than. Requires that the field come first in `order_by`. */ + GCFSStructuredQuery_FieldFilter_Operator_GreaterThan = 3, + + /** + * Greater than or equal. Requires that the field come first in + * `order_by`. + **/ + GCFSStructuredQuery_FieldFilter_Operator_GreaterThanOrEqual = 4, + + /** Equal. */ + GCFSStructuredQuery_FieldFilter_Operator_Equal = 5, + + /** Contains. Requires that the field is an array. */ + GCFSStructuredQuery_FieldFilter_Operator_ArrayContains = 7, +}; + +GPBEnumDescriptor *GCFSStructuredQuery_FieldFilter_Operator_EnumDescriptor(void); + +/** + * Checks to see if the given value is defined by the enum or was not known at + * the time this source was generated. + **/ +BOOL GCFSStructuredQuery_FieldFilter_Operator_IsValidValue(int32_t value); + +#pragma mark - Enum GCFSStructuredQuery_UnaryFilter_Operator + +/** A unary operator. */ +typedef GPB_ENUM(GCFSStructuredQuery_UnaryFilter_Operator) { + /** + * Value used if any message's field encounters a value that is not defined + * by this enum. The message will also have C functions to get/set the rawValue + * of the field. + **/ + GCFSStructuredQuery_UnaryFilter_Operator_GPBUnrecognizedEnumeratorValue = kGPBUnrecognizedEnumeratorValue, + /** Unspecified. This value must not be used. */ + GCFSStructuredQuery_UnaryFilter_Operator_OperatorUnspecified = 0, + + /** Test if a field is equal to NaN. */ + GCFSStructuredQuery_UnaryFilter_Operator_IsNan = 2, + + /** Test if an exprestion evaluates to Null. */ + GCFSStructuredQuery_UnaryFilter_Operator_IsNull = 3, +}; + +GPBEnumDescriptor *GCFSStructuredQuery_UnaryFilter_Operator_EnumDescriptor(void); + +/** + * Checks to see if the given value is defined by the enum or was not known at + * the time this source was generated. + **/ +BOOL GCFSStructuredQuery_UnaryFilter_Operator_IsValidValue(int32_t value); + +#pragma mark - GCFSQueryRoot + +/** + * Exposes the extension registry for this file. + * + * The base class provides: + * @code + * + (GPBExtensionRegistry *)extensionRegistry; + * @endcode + * which is a @c GPBExtensionRegistry that includes all the extensions defined by + * this file and all files that it depends on. + **/ +@interface GCFSQueryRoot : GPBRootObject +@end + +#pragma mark - GCFSStructuredQuery + +typedef GPB_ENUM(GCFSStructuredQuery_FieldNumber) { + GCFSStructuredQuery_FieldNumber_Select = 1, + GCFSStructuredQuery_FieldNumber_FromArray = 2, + GCFSStructuredQuery_FieldNumber_Where = 3, + GCFSStructuredQuery_FieldNumber_OrderByArray = 4, + GCFSStructuredQuery_FieldNumber_Limit = 5, + GCFSStructuredQuery_FieldNumber_Offset = 6, + GCFSStructuredQuery_FieldNumber_StartAt = 7, + GCFSStructuredQuery_FieldNumber_EndAt = 8, +}; + +/** + * A Firestore query. + **/ +@interface GCFSStructuredQuery : GPBMessage + +/** The projection to return. */ +@property(nonatomic, readwrite, strong, null_resettable) GCFSStructuredQuery_Projection *select; +/** Test to see if @c select has been set. */ +@property(nonatomic, readwrite) BOOL hasSelect; + +/** The collections to query. */ +@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *fromArray; +/** The number of items in @c fromArray without causing the array to be created. */ +@property(nonatomic, readonly) NSUInteger fromArray_Count; + +/** The filter to apply. */ +@property(nonatomic, readwrite, strong, null_resettable) GCFSStructuredQuery_Filter *where; +/** Test to see if @c where has been set. */ +@property(nonatomic, readwrite) BOOL hasWhere; + +/** + * The order to apply to the query results. + * + * Firestore guarantees a stable ordering through the following rules: + * + * * Any field required to appear in `order_by`, that is not already + * specified in `order_by`, is appended to the order in field name order + * by default. + * * If an order on `__name__` is not specified, it is appended by default. + * + * Fields are appended with the same sort direction as the last order + * specified, or 'ASCENDING' if no order was specified. For example: + * + * * `SELECT * FROM Foo ORDER BY A` becomes + * `SELECT * FROM Foo ORDER BY A, __name__` + * * `SELECT * FROM Foo ORDER BY A DESC` becomes + * `SELECT * FROM Foo ORDER BY A DESC, __name__ DESC` + * * `SELECT * FROM Foo WHERE A > 1` becomes + * `SELECT * FROM Foo WHERE A > 1 ORDER BY A, __name__` + **/ +@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *orderByArray; +/** The number of items in @c orderByArray without causing the array to be created. */ +@property(nonatomic, readonly) NSUInteger orderByArray_Count; + +/** A starting point for the query results. */ +@property(nonatomic, readwrite, strong, null_resettable) GCFSCursor *startAt; +/** Test to see if @c startAt has been set. */ +@property(nonatomic, readwrite) BOOL hasStartAt; + +/** A end point for the query results. */ +@property(nonatomic, readwrite, strong, null_resettable) GCFSCursor *endAt; +/** Test to see if @c endAt has been set. */ +@property(nonatomic, readwrite) BOOL hasEndAt; + +/** + * The number of results to skip. + * + * Applies before limit, but after all other constraints. Must be >= 0 if + * specified. + **/ +@property(nonatomic, readwrite) int32_t offset; + +/** + * The maximum number of results to return. + * + * Applies after all other constraints. + * Must be >= 0 if specified. + **/ +@property(nonatomic, readwrite, strong, null_resettable) GPBInt32Value *limit; +/** Test to see if @c limit has been set. */ +@property(nonatomic, readwrite) BOOL hasLimit; + +@end + +#pragma mark - GCFSStructuredQuery_CollectionSelector + +typedef GPB_ENUM(GCFSStructuredQuery_CollectionSelector_FieldNumber) { + GCFSStructuredQuery_CollectionSelector_FieldNumber_CollectionId = 2, + GCFSStructuredQuery_CollectionSelector_FieldNumber_AllDescendants = 3, +}; + +/** + * A selection of a collection, such as `messages as m1`. + **/ +@interface GCFSStructuredQuery_CollectionSelector : GPBMessage + +/** + * The collection ID. + * When set, selects only collections with this ID. + **/ +@property(nonatomic, readwrite, copy, null_resettable) NSString *collectionId; + +/** + * When false, selects only collections that are immediate children of + * the `parent` specified in the containing `RunQueryRequest`. + * When true, selects all descendant collections. + **/ +@property(nonatomic, readwrite) BOOL allDescendants; + +@end + +#pragma mark - GCFSStructuredQuery_Filter + +typedef GPB_ENUM(GCFSStructuredQuery_Filter_FieldNumber) { + GCFSStructuredQuery_Filter_FieldNumber_CompositeFilter = 1, + GCFSStructuredQuery_Filter_FieldNumber_FieldFilter = 2, + GCFSStructuredQuery_Filter_FieldNumber_UnaryFilter = 3, +}; + +typedef GPB_ENUM(GCFSStructuredQuery_Filter_FilterType_OneOfCase) { + GCFSStructuredQuery_Filter_FilterType_OneOfCase_GPBUnsetOneOfCase = 0, + GCFSStructuredQuery_Filter_FilterType_OneOfCase_CompositeFilter = 1, + GCFSStructuredQuery_Filter_FilterType_OneOfCase_FieldFilter = 2, + GCFSStructuredQuery_Filter_FilterType_OneOfCase_UnaryFilter = 3, +}; + +/** + * A filter. + **/ +@interface GCFSStructuredQuery_Filter : GPBMessage + +/** The type of filter. */ +@property(nonatomic, readonly) GCFSStructuredQuery_Filter_FilterType_OneOfCase filterTypeOneOfCase; + +/** A composite filter. */ +@property(nonatomic, readwrite, strong, null_resettable) GCFSStructuredQuery_CompositeFilter *compositeFilter; + +/** A filter on a document field. */ +@property(nonatomic, readwrite, strong, null_resettable) GCFSStructuredQuery_FieldFilter *fieldFilter; + +/** A filter that takes exactly one argument. */ +@property(nonatomic, readwrite, strong, null_resettable) GCFSStructuredQuery_UnaryFilter *unaryFilter; + +@end + +/** + * Clears whatever value was set for the oneof 'filterType'. + **/ +void GCFSStructuredQuery_Filter_ClearFilterTypeOneOfCase(GCFSStructuredQuery_Filter *message); + +#pragma mark - GCFSStructuredQuery_CompositeFilter + +typedef GPB_ENUM(GCFSStructuredQuery_CompositeFilter_FieldNumber) { + GCFSStructuredQuery_CompositeFilter_FieldNumber_Op = 1, + GCFSStructuredQuery_CompositeFilter_FieldNumber_FiltersArray = 2, +}; + +/** + * A filter that merges multiple other filters using the given operator. + **/ +@interface GCFSStructuredQuery_CompositeFilter : GPBMessage + +/** The operator for combining multiple filters. */ +@property(nonatomic, readwrite) GCFSStructuredQuery_CompositeFilter_Operator op; + +/** + * The list of filters to combine. + * Must contain at least one filter. + **/ +@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *filtersArray; +/** The number of items in @c filtersArray without causing the array to be created. */ +@property(nonatomic, readonly) NSUInteger filtersArray_Count; + +@end + +/** + * Fetches the raw value of a @c GCFSStructuredQuery_CompositeFilter's @c op property, even + * if the value was not defined by the enum at the time the code was generated. + **/ +int32_t GCFSStructuredQuery_CompositeFilter_Op_RawValue(GCFSStructuredQuery_CompositeFilter *message); +/** + * Sets the raw value of an @c GCFSStructuredQuery_CompositeFilter's @c op property, allowing + * it to be set to a value that was not defined by the enum at the time the code + * was generated. + **/ +void SetGCFSStructuredQuery_CompositeFilter_Op_RawValue(GCFSStructuredQuery_CompositeFilter *message, int32_t value); + +#pragma mark - GCFSStructuredQuery_FieldFilter + +typedef GPB_ENUM(GCFSStructuredQuery_FieldFilter_FieldNumber) { + GCFSStructuredQuery_FieldFilter_FieldNumber_Field = 1, + GCFSStructuredQuery_FieldFilter_FieldNumber_Op = 2, + GCFSStructuredQuery_FieldFilter_FieldNumber_Value = 3, +}; + +/** + * A filter on a specific field. + **/ +@interface GCFSStructuredQuery_FieldFilter : GPBMessage + +/** The field to filter by. */ +@property(nonatomic, readwrite, strong, null_resettable) GCFSStructuredQuery_FieldReference *field; +/** Test to see if @c field has been set. */ +@property(nonatomic, readwrite) BOOL hasField; + +/** The operator to filter by. */ +@property(nonatomic, readwrite) GCFSStructuredQuery_FieldFilter_Operator op; + +/** The value to compare to. */ +@property(nonatomic, readwrite, strong, null_resettable) GCFSValue *value; +/** Test to see if @c value has been set. */ +@property(nonatomic, readwrite) BOOL hasValue; + +@end + +/** + * Fetches the raw value of a @c GCFSStructuredQuery_FieldFilter's @c op property, even + * if the value was not defined by the enum at the time the code was generated. + **/ +int32_t GCFSStructuredQuery_FieldFilter_Op_RawValue(GCFSStructuredQuery_FieldFilter *message); +/** + * Sets the raw value of an @c GCFSStructuredQuery_FieldFilter's @c op property, allowing + * it to be set to a value that was not defined by the enum at the time the code + * was generated. + **/ +void SetGCFSStructuredQuery_FieldFilter_Op_RawValue(GCFSStructuredQuery_FieldFilter *message, int32_t value); + +#pragma mark - GCFSStructuredQuery_UnaryFilter + +typedef GPB_ENUM(GCFSStructuredQuery_UnaryFilter_FieldNumber) { + GCFSStructuredQuery_UnaryFilter_FieldNumber_Op = 1, + GCFSStructuredQuery_UnaryFilter_FieldNumber_Field = 2, +}; + +typedef GPB_ENUM(GCFSStructuredQuery_UnaryFilter_OperandType_OneOfCase) { + GCFSStructuredQuery_UnaryFilter_OperandType_OneOfCase_GPBUnsetOneOfCase = 0, + GCFSStructuredQuery_UnaryFilter_OperandType_OneOfCase_Field = 2, +}; + +/** + * A filter with a single operand. + **/ +@interface GCFSStructuredQuery_UnaryFilter : GPBMessage + +/** The unary operator to apply. */ +@property(nonatomic, readwrite) GCFSStructuredQuery_UnaryFilter_Operator op; + +/** The argument to the filter. */ +@property(nonatomic, readonly) GCFSStructuredQuery_UnaryFilter_OperandType_OneOfCase operandTypeOneOfCase; + +/** The field to which to apply the operator. */ +@property(nonatomic, readwrite, strong, null_resettable) GCFSStructuredQuery_FieldReference *field; + +@end + +/** + * Fetches the raw value of a @c GCFSStructuredQuery_UnaryFilter's @c op property, even + * if the value was not defined by the enum at the time the code was generated. + **/ +int32_t GCFSStructuredQuery_UnaryFilter_Op_RawValue(GCFSStructuredQuery_UnaryFilter *message); +/** + * Sets the raw value of an @c GCFSStructuredQuery_UnaryFilter's @c op property, allowing + * it to be set to a value that was not defined by the enum at the time the code + * was generated. + **/ +void SetGCFSStructuredQuery_UnaryFilter_Op_RawValue(GCFSStructuredQuery_UnaryFilter *message, int32_t value); + +/** + * Clears whatever value was set for the oneof 'operandType'. + **/ +void GCFSStructuredQuery_UnaryFilter_ClearOperandTypeOneOfCase(GCFSStructuredQuery_UnaryFilter *message); + +#pragma mark - GCFSStructuredQuery_Order + +typedef GPB_ENUM(GCFSStructuredQuery_Order_FieldNumber) { + GCFSStructuredQuery_Order_FieldNumber_Field = 1, + GCFSStructuredQuery_Order_FieldNumber_Direction = 2, +}; + +/** + * An order on a field. + **/ +@interface GCFSStructuredQuery_Order : GPBMessage + +/** The field to order by. */ +@property(nonatomic, readwrite, strong, null_resettable) GCFSStructuredQuery_FieldReference *field; +/** Test to see if @c field has been set. */ +@property(nonatomic, readwrite) BOOL hasField; + +/** The direction to order by. Defaults to `ASCENDING`. */ +@property(nonatomic, readwrite) GCFSStructuredQuery_Direction direction; + +@end + +/** + * Fetches the raw value of a @c GCFSStructuredQuery_Order's @c direction property, even + * if the value was not defined by the enum at the time the code was generated. + **/ +int32_t GCFSStructuredQuery_Order_Direction_RawValue(GCFSStructuredQuery_Order *message); +/** + * Sets the raw value of an @c GCFSStructuredQuery_Order's @c direction property, allowing + * it to be set to a value that was not defined by the enum at the time the code + * was generated. + **/ +void SetGCFSStructuredQuery_Order_Direction_RawValue(GCFSStructuredQuery_Order *message, int32_t value); + +#pragma mark - GCFSStructuredQuery_FieldReference + +typedef GPB_ENUM(GCFSStructuredQuery_FieldReference_FieldNumber) { + GCFSStructuredQuery_FieldReference_FieldNumber_FieldPath = 2, +}; + +/** + * A reference to a field, such as `max(messages.time) as max_time`. + **/ +@interface GCFSStructuredQuery_FieldReference : GPBMessage + +@property(nonatomic, readwrite, copy, null_resettable) NSString *fieldPath; + +@end + +#pragma mark - GCFSStructuredQuery_Projection + +typedef GPB_ENUM(GCFSStructuredQuery_Projection_FieldNumber) { + GCFSStructuredQuery_Projection_FieldNumber_FieldsArray = 2, +}; + +/** + * The projection of document's fields to return. + **/ +@interface GCFSStructuredQuery_Projection : GPBMessage + +/** + * The fields to return. + * + * If empty, all fields are returned. To only return the name + * of the document, use `['__name__']`. + **/ +@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *fieldsArray; +/** The number of items in @c fieldsArray without causing the array to be created. */ +@property(nonatomic, readonly) NSUInteger fieldsArray_Count; + +@end + +#pragma mark - GCFSCursor + +typedef GPB_ENUM(GCFSCursor_FieldNumber) { + GCFSCursor_FieldNumber_ValuesArray = 1, + GCFSCursor_FieldNumber_Before = 2, +}; + +/** + * A position in a query result set. + **/ +@interface GCFSCursor : GPBMessage + +/** + * The values that represent a position, in the order they appear in + * the order by clause of a query. + * + * Can contain fewer values than specified in the order by clause. + **/ +@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *valuesArray; +/** The number of items in @c valuesArray without causing the array to be created. */ +@property(nonatomic, readonly) NSUInteger valuesArray_Count; + +/** + * If the position is just before or just after the given values, relative + * to the sort order defined by the query. + **/ +@property(nonatomic, readwrite) BOOL before; + +@end + +NS_ASSUME_NONNULL_END + +CF_EXTERN_C_END + +#pragma clang diagnostic pop + +// @@protoc_insertion_point(global_scope) diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/objc/google/firestore/v1/Query.pbobjc.m b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/objc/google/firestore/v1/Query.pbobjc.m new file mode 100644 index 0000000..ef716bb --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/objc/google/firestore/v1/Query.pbobjc.m @@ -0,0 +1,909 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/firestore/v1/query.proto + +// This CPP symbol can be defined to use imports that match up to the framework +// imports needed when using CocoaPods. +#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) + #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 +#endif + +#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS + #import +#else + #import "GPBProtocolBuffers_RuntimeSupport.h" +#endif + +#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS + #import +#else + #import "Wrappers.pbobjc.h" +#endif + + #import "Query.pbobjc.h" + #import "Annotations.pbobjc.h" + #import "Document.pbobjc.h" +// @@protoc_insertion_point(imports) + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" +#pragma clang diagnostic ignored "-Wdirect-ivar-access" + +#pragma mark - GCFSQueryRoot + +@implementation GCFSQueryRoot + + +@end + +#pragma mark - GCFSQueryRoot_FileDescriptor + +static GPBFileDescriptor *GCFSQueryRoot_FileDescriptor(void) { + // This is called by +initialize so there is no need to worry + // about thread safety of the singleton. + static GPBFileDescriptor *descriptor = NULL; + if (!descriptor) { + GPB_DEBUG_CHECK_RUNTIME_VERSIONS(); + descriptor = [[GPBFileDescriptor alloc] initWithPackage:@"google.firestore.v1" + objcPrefix:@"GCFS" + syntax:GPBFileSyntaxProto3]; + } + return descriptor; +} + +#pragma mark - GCFSStructuredQuery + +@implementation GCFSStructuredQuery + +@dynamic hasSelect, select; +@dynamic fromArray, fromArray_Count; +@dynamic hasWhere, where; +@dynamic orderByArray, orderByArray_Count; +@dynamic hasStartAt, startAt; +@dynamic hasEndAt, endAt; +@dynamic offset; +@dynamic hasLimit, limit; + +typedef struct GCFSStructuredQuery__storage_ { + uint32_t _has_storage_[1]; + int32_t offset; + GCFSStructuredQuery_Projection *select; + NSMutableArray *fromArray; + GCFSStructuredQuery_Filter *where; + NSMutableArray *orderByArray; + GPBInt32Value *limit; + GCFSCursor *startAt; + GCFSCursor *endAt; +} GCFSStructuredQuery__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "select", + .dataTypeSpecific.className = GPBStringifySymbol(GCFSStructuredQuery_Projection), + .number = GCFSStructuredQuery_FieldNumber_Select, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GCFSStructuredQuery__storage_, select), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + { + .name = "fromArray", + .dataTypeSpecific.className = GPBStringifySymbol(GCFSStructuredQuery_CollectionSelector), + .number = GCFSStructuredQuery_FieldNumber_FromArray, + .hasIndex = GPBNoHasBit, + .offset = (uint32_t)offsetof(GCFSStructuredQuery__storage_, fromArray), + .flags = GPBFieldRepeated, + .dataType = GPBDataTypeMessage, + }, + { + .name = "where", + .dataTypeSpecific.className = GPBStringifySymbol(GCFSStructuredQuery_Filter), + .number = GCFSStructuredQuery_FieldNumber_Where, + .hasIndex = 1, + .offset = (uint32_t)offsetof(GCFSStructuredQuery__storage_, where), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + { + .name = "orderByArray", + .dataTypeSpecific.className = GPBStringifySymbol(GCFSStructuredQuery_Order), + .number = GCFSStructuredQuery_FieldNumber_OrderByArray, + .hasIndex = GPBNoHasBit, + .offset = (uint32_t)offsetof(GCFSStructuredQuery__storage_, orderByArray), + .flags = GPBFieldRepeated, + .dataType = GPBDataTypeMessage, + }, + { + .name = "limit", + .dataTypeSpecific.className = GPBStringifySymbol(GPBInt32Value), + .number = GCFSStructuredQuery_FieldNumber_Limit, + .hasIndex = 5, + .offset = (uint32_t)offsetof(GCFSStructuredQuery__storage_, limit), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + { + .name = "offset", + .dataTypeSpecific.className = NULL, + .number = GCFSStructuredQuery_FieldNumber_Offset, + .hasIndex = 4, + .offset = (uint32_t)offsetof(GCFSStructuredQuery__storage_, offset), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + { + .name = "startAt", + .dataTypeSpecific.className = GPBStringifySymbol(GCFSCursor), + .number = GCFSStructuredQuery_FieldNumber_StartAt, + .hasIndex = 2, + .offset = (uint32_t)offsetof(GCFSStructuredQuery__storage_, startAt), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + { + .name = "endAt", + .dataTypeSpecific.className = GPBStringifySymbol(GCFSCursor), + .number = GCFSStructuredQuery_FieldNumber_EndAt, + .hasIndex = 3, + .offset = (uint32_t)offsetof(GCFSStructuredQuery__storage_, endAt), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GCFSStructuredQuery class] + rootClass:[GCFSQueryRoot class] + file:GCFSQueryRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GCFSStructuredQuery__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - Enum GCFSStructuredQuery_Direction + +GPBEnumDescriptor *GCFSStructuredQuery_Direction_EnumDescriptor(void) { + static GPBEnumDescriptor *descriptor = NULL; + if (!descriptor) { + static const char *valueNames = + "DirectionUnspecified\000Ascending\000Descendin" + "g\000"; + static const int32_t values[] = { + GCFSStructuredQuery_Direction_DirectionUnspecified, + GCFSStructuredQuery_Direction_Ascending, + GCFSStructuredQuery_Direction_Descending, + }; + GPBEnumDescriptor *worker = + [GPBEnumDescriptor allocDescriptorForName:GPBNSStringifySymbol(GCFSStructuredQuery_Direction) + valueNames:valueNames + values:values + count:(uint32_t)(sizeof(values) / sizeof(int32_t)) + enumVerifier:GCFSStructuredQuery_Direction_IsValidValue]; + if (!OSAtomicCompareAndSwapPtrBarrier(nil, worker, (void * volatile *)&descriptor)) { + [worker release]; + } + } + return descriptor; +} + +BOOL GCFSStructuredQuery_Direction_IsValidValue(int32_t value__) { + switch (value__) { + case GCFSStructuredQuery_Direction_DirectionUnspecified: + case GCFSStructuredQuery_Direction_Ascending: + case GCFSStructuredQuery_Direction_Descending: + return YES; + default: + return NO; + } +} + +#pragma mark - GCFSStructuredQuery_CollectionSelector + +@implementation GCFSStructuredQuery_CollectionSelector + +@dynamic collectionId; +@dynamic allDescendants; + +typedef struct GCFSStructuredQuery_CollectionSelector__storage_ { + uint32_t _has_storage_[1]; + NSString *collectionId; +} GCFSStructuredQuery_CollectionSelector__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "collectionId", + .dataTypeSpecific.className = NULL, + .number = GCFSStructuredQuery_CollectionSelector_FieldNumber_CollectionId, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GCFSStructuredQuery_CollectionSelector__storage_, collectionId), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "allDescendants", + .dataTypeSpecific.className = NULL, + .number = GCFSStructuredQuery_CollectionSelector_FieldNumber_AllDescendants, + .hasIndex = 1, + .offset = 2, // Stored in _has_storage_ to save space. + .flags = GPBFieldOptional, + .dataType = GPBDataTypeBool, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GCFSStructuredQuery_CollectionSelector class] + rootClass:[GCFSQueryRoot class] + file:GCFSQueryRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GCFSStructuredQuery_CollectionSelector__storage_) + flags:GPBDescriptorInitializationFlag_None]; + [localDescriptor setupContainingMessageClassName:GPBStringifySymbol(GCFSStructuredQuery)]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - GCFSStructuredQuery_Filter + +@implementation GCFSStructuredQuery_Filter + +@dynamic filterTypeOneOfCase; +@dynamic compositeFilter; +@dynamic fieldFilter; +@dynamic unaryFilter; + +typedef struct GCFSStructuredQuery_Filter__storage_ { + uint32_t _has_storage_[2]; + GCFSStructuredQuery_CompositeFilter *compositeFilter; + GCFSStructuredQuery_FieldFilter *fieldFilter; + GCFSStructuredQuery_UnaryFilter *unaryFilter; +} GCFSStructuredQuery_Filter__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "compositeFilter", + .dataTypeSpecific.className = GPBStringifySymbol(GCFSStructuredQuery_CompositeFilter), + .number = GCFSStructuredQuery_Filter_FieldNumber_CompositeFilter, + .hasIndex = -1, + .offset = (uint32_t)offsetof(GCFSStructuredQuery_Filter__storage_, compositeFilter), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + { + .name = "fieldFilter", + .dataTypeSpecific.className = GPBStringifySymbol(GCFSStructuredQuery_FieldFilter), + .number = GCFSStructuredQuery_Filter_FieldNumber_FieldFilter, + .hasIndex = -1, + .offset = (uint32_t)offsetof(GCFSStructuredQuery_Filter__storage_, fieldFilter), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + { + .name = "unaryFilter", + .dataTypeSpecific.className = GPBStringifySymbol(GCFSStructuredQuery_UnaryFilter), + .number = GCFSStructuredQuery_Filter_FieldNumber_UnaryFilter, + .hasIndex = -1, + .offset = (uint32_t)offsetof(GCFSStructuredQuery_Filter__storage_, unaryFilter), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GCFSStructuredQuery_Filter class] + rootClass:[GCFSQueryRoot class] + file:GCFSQueryRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GCFSStructuredQuery_Filter__storage_) + flags:GPBDescriptorInitializationFlag_None]; + static const char *oneofs[] = { + "filterType", + }; + [localDescriptor setupOneofs:oneofs + count:(uint32_t)(sizeof(oneofs) / sizeof(char*)) + firstHasIndex:-1]; + [localDescriptor setupContainingMessageClassName:GPBStringifySymbol(GCFSStructuredQuery)]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +void GCFSStructuredQuery_Filter_ClearFilterTypeOneOfCase(GCFSStructuredQuery_Filter *message) { + GPBDescriptor *descriptor = [message descriptor]; + GPBOneofDescriptor *oneof = [descriptor.oneofs objectAtIndex:0]; + GPBMaybeClearOneof(message, oneof, -1, 0); +} +#pragma mark - GCFSStructuredQuery_CompositeFilter + +@implementation GCFSStructuredQuery_CompositeFilter + +@dynamic op; +@dynamic filtersArray, filtersArray_Count; + +typedef struct GCFSStructuredQuery_CompositeFilter__storage_ { + uint32_t _has_storage_[1]; + GCFSStructuredQuery_CompositeFilter_Operator op; + NSMutableArray *filtersArray; +} GCFSStructuredQuery_CompositeFilter__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "op", + .dataTypeSpecific.enumDescFunc = GCFSStructuredQuery_CompositeFilter_Operator_EnumDescriptor, + .number = GCFSStructuredQuery_CompositeFilter_FieldNumber_Op, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GCFSStructuredQuery_CompositeFilter__storage_, op), + .flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldHasEnumDescriptor), + .dataType = GPBDataTypeEnum, + }, + { + .name = "filtersArray", + .dataTypeSpecific.className = GPBStringifySymbol(GCFSStructuredQuery_Filter), + .number = GCFSStructuredQuery_CompositeFilter_FieldNumber_FiltersArray, + .hasIndex = GPBNoHasBit, + .offset = (uint32_t)offsetof(GCFSStructuredQuery_CompositeFilter__storage_, filtersArray), + .flags = GPBFieldRepeated, + .dataType = GPBDataTypeMessage, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GCFSStructuredQuery_CompositeFilter class] + rootClass:[GCFSQueryRoot class] + file:GCFSQueryRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GCFSStructuredQuery_CompositeFilter__storage_) + flags:GPBDescriptorInitializationFlag_None]; + [localDescriptor setupContainingMessageClassName:GPBStringifySymbol(GCFSStructuredQuery)]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +int32_t GCFSStructuredQuery_CompositeFilter_Op_RawValue(GCFSStructuredQuery_CompositeFilter *message) { + GPBDescriptor *descriptor = [GCFSStructuredQuery_CompositeFilter descriptor]; + GPBFieldDescriptor *field = [descriptor fieldWithNumber:GCFSStructuredQuery_CompositeFilter_FieldNumber_Op]; + return GPBGetMessageInt32Field(message, field); +} + +void SetGCFSStructuredQuery_CompositeFilter_Op_RawValue(GCFSStructuredQuery_CompositeFilter *message, int32_t value) { + GPBDescriptor *descriptor = [GCFSStructuredQuery_CompositeFilter descriptor]; + GPBFieldDescriptor *field = [descriptor fieldWithNumber:GCFSStructuredQuery_CompositeFilter_FieldNumber_Op]; + GPBSetInt32IvarWithFieldInternal(message, field, value, descriptor.file.syntax); +} + +#pragma mark - Enum GCFSStructuredQuery_CompositeFilter_Operator + +GPBEnumDescriptor *GCFSStructuredQuery_CompositeFilter_Operator_EnumDescriptor(void) { + static GPBEnumDescriptor *descriptor = NULL; + if (!descriptor) { + static const char *valueNames = + "OperatorUnspecified\000And\000"; + static const int32_t values[] = { + GCFSStructuredQuery_CompositeFilter_Operator_OperatorUnspecified, + GCFSStructuredQuery_CompositeFilter_Operator_And, + }; + GPBEnumDescriptor *worker = + [GPBEnumDescriptor allocDescriptorForName:GPBNSStringifySymbol(GCFSStructuredQuery_CompositeFilter_Operator) + valueNames:valueNames + values:values + count:(uint32_t)(sizeof(values) / sizeof(int32_t)) + enumVerifier:GCFSStructuredQuery_CompositeFilter_Operator_IsValidValue]; + if (!OSAtomicCompareAndSwapPtrBarrier(nil, worker, (void * volatile *)&descriptor)) { + [worker release]; + } + } + return descriptor; +} + +BOOL GCFSStructuredQuery_CompositeFilter_Operator_IsValidValue(int32_t value__) { + switch (value__) { + case GCFSStructuredQuery_CompositeFilter_Operator_OperatorUnspecified: + case GCFSStructuredQuery_CompositeFilter_Operator_And: + return YES; + default: + return NO; + } +} + +#pragma mark - GCFSStructuredQuery_FieldFilter + +@implementation GCFSStructuredQuery_FieldFilter + +@dynamic hasField, field; +@dynamic op; +@dynamic hasValue, value; + +typedef struct GCFSStructuredQuery_FieldFilter__storage_ { + uint32_t _has_storage_[1]; + GCFSStructuredQuery_FieldFilter_Operator op; + GCFSStructuredQuery_FieldReference *field; + GCFSValue *value; +} GCFSStructuredQuery_FieldFilter__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "field", + .dataTypeSpecific.className = GPBStringifySymbol(GCFSStructuredQuery_FieldReference), + .number = GCFSStructuredQuery_FieldFilter_FieldNumber_Field, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GCFSStructuredQuery_FieldFilter__storage_, field), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + { + .name = "op", + .dataTypeSpecific.enumDescFunc = GCFSStructuredQuery_FieldFilter_Operator_EnumDescriptor, + .number = GCFSStructuredQuery_FieldFilter_FieldNumber_Op, + .hasIndex = 1, + .offset = (uint32_t)offsetof(GCFSStructuredQuery_FieldFilter__storage_, op), + .flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldHasEnumDescriptor), + .dataType = GPBDataTypeEnum, + }, + { + .name = "value", + .dataTypeSpecific.className = GPBStringifySymbol(GCFSValue), + .number = GCFSStructuredQuery_FieldFilter_FieldNumber_Value, + .hasIndex = 2, + .offset = (uint32_t)offsetof(GCFSStructuredQuery_FieldFilter__storage_, value), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GCFSStructuredQuery_FieldFilter class] + rootClass:[GCFSQueryRoot class] + file:GCFSQueryRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GCFSStructuredQuery_FieldFilter__storage_) + flags:GPBDescriptorInitializationFlag_None]; + [localDescriptor setupContainingMessageClassName:GPBStringifySymbol(GCFSStructuredQuery)]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +int32_t GCFSStructuredQuery_FieldFilter_Op_RawValue(GCFSStructuredQuery_FieldFilter *message) { + GPBDescriptor *descriptor = [GCFSStructuredQuery_FieldFilter descriptor]; + GPBFieldDescriptor *field = [descriptor fieldWithNumber:GCFSStructuredQuery_FieldFilter_FieldNumber_Op]; + return GPBGetMessageInt32Field(message, field); +} + +void SetGCFSStructuredQuery_FieldFilter_Op_RawValue(GCFSStructuredQuery_FieldFilter *message, int32_t value) { + GPBDescriptor *descriptor = [GCFSStructuredQuery_FieldFilter descriptor]; + GPBFieldDescriptor *field = [descriptor fieldWithNumber:GCFSStructuredQuery_FieldFilter_FieldNumber_Op]; + GPBSetInt32IvarWithFieldInternal(message, field, value, descriptor.file.syntax); +} + +#pragma mark - Enum GCFSStructuredQuery_FieldFilter_Operator + +GPBEnumDescriptor *GCFSStructuredQuery_FieldFilter_Operator_EnumDescriptor(void) { + static GPBEnumDescriptor *descriptor = NULL; + if (!descriptor) { + static const char *valueNames = + "OperatorUnspecified\000LessThan\000LessThanOrE" + "qual\000GreaterThan\000GreaterThanOrEqual\000Equa" + "l\000ArrayContains\000"; + static const int32_t values[] = { + GCFSStructuredQuery_FieldFilter_Operator_OperatorUnspecified, + GCFSStructuredQuery_FieldFilter_Operator_LessThan, + GCFSStructuredQuery_FieldFilter_Operator_LessThanOrEqual, + GCFSStructuredQuery_FieldFilter_Operator_GreaterThan, + GCFSStructuredQuery_FieldFilter_Operator_GreaterThanOrEqual, + GCFSStructuredQuery_FieldFilter_Operator_Equal, + GCFSStructuredQuery_FieldFilter_Operator_ArrayContains, + }; + GPBEnumDescriptor *worker = + [GPBEnumDescriptor allocDescriptorForName:GPBNSStringifySymbol(GCFSStructuredQuery_FieldFilter_Operator) + valueNames:valueNames + values:values + count:(uint32_t)(sizeof(values) / sizeof(int32_t)) + enumVerifier:GCFSStructuredQuery_FieldFilter_Operator_IsValidValue]; + if (!OSAtomicCompareAndSwapPtrBarrier(nil, worker, (void * volatile *)&descriptor)) { + [worker release]; + } + } + return descriptor; +} + +BOOL GCFSStructuredQuery_FieldFilter_Operator_IsValidValue(int32_t value__) { + switch (value__) { + case GCFSStructuredQuery_FieldFilter_Operator_OperatorUnspecified: + case GCFSStructuredQuery_FieldFilter_Operator_LessThan: + case GCFSStructuredQuery_FieldFilter_Operator_LessThanOrEqual: + case GCFSStructuredQuery_FieldFilter_Operator_GreaterThan: + case GCFSStructuredQuery_FieldFilter_Operator_GreaterThanOrEqual: + case GCFSStructuredQuery_FieldFilter_Operator_Equal: + case GCFSStructuredQuery_FieldFilter_Operator_ArrayContains: + return YES; + default: + return NO; + } +} + +#pragma mark - GCFSStructuredQuery_UnaryFilter + +@implementation GCFSStructuredQuery_UnaryFilter + +@dynamic operandTypeOneOfCase; +@dynamic op; +@dynamic field; + +typedef struct GCFSStructuredQuery_UnaryFilter__storage_ { + uint32_t _has_storage_[2]; + GCFSStructuredQuery_UnaryFilter_Operator op; + GCFSStructuredQuery_FieldReference *field; +} GCFSStructuredQuery_UnaryFilter__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "op", + .dataTypeSpecific.enumDescFunc = GCFSStructuredQuery_UnaryFilter_Operator_EnumDescriptor, + .number = GCFSStructuredQuery_UnaryFilter_FieldNumber_Op, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GCFSStructuredQuery_UnaryFilter__storage_, op), + .flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldHasEnumDescriptor), + .dataType = GPBDataTypeEnum, + }, + { + .name = "field", + .dataTypeSpecific.className = GPBStringifySymbol(GCFSStructuredQuery_FieldReference), + .number = GCFSStructuredQuery_UnaryFilter_FieldNumber_Field, + .hasIndex = -1, + .offset = (uint32_t)offsetof(GCFSStructuredQuery_UnaryFilter__storage_, field), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GCFSStructuredQuery_UnaryFilter class] + rootClass:[GCFSQueryRoot class] + file:GCFSQueryRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GCFSStructuredQuery_UnaryFilter__storage_) + flags:GPBDescriptorInitializationFlag_None]; + static const char *oneofs[] = { + "operandType", + }; + [localDescriptor setupOneofs:oneofs + count:(uint32_t)(sizeof(oneofs) / sizeof(char*)) + firstHasIndex:-1]; + [localDescriptor setupContainingMessageClassName:GPBStringifySymbol(GCFSStructuredQuery)]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +int32_t GCFSStructuredQuery_UnaryFilter_Op_RawValue(GCFSStructuredQuery_UnaryFilter *message) { + GPBDescriptor *descriptor = [GCFSStructuredQuery_UnaryFilter descriptor]; + GPBFieldDescriptor *field = [descriptor fieldWithNumber:GCFSStructuredQuery_UnaryFilter_FieldNumber_Op]; + return GPBGetMessageInt32Field(message, field); +} + +void SetGCFSStructuredQuery_UnaryFilter_Op_RawValue(GCFSStructuredQuery_UnaryFilter *message, int32_t value) { + GPBDescriptor *descriptor = [GCFSStructuredQuery_UnaryFilter descriptor]; + GPBFieldDescriptor *field = [descriptor fieldWithNumber:GCFSStructuredQuery_UnaryFilter_FieldNumber_Op]; + GPBSetInt32IvarWithFieldInternal(message, field, value, descriptor.file.syntax); +} + +void GCFSStructuredQuery_UnaryFilter_ClearOperandTypeOneOfCase(GCFSStructuredQuery_UnaryFilter *message) { + GPBDescriptor *descriptor = [message descriptor]; + GPBOneofDescriptor *oneof = [descriptor.oneofs objectAtIndex:0]; + GPBMaybeClearOneof(message, oneof, -1, 0); +} +#pragma mark - Enum GCFSStructuredQuery_UnaryFilter_Operator + +GPBEnumDescriptor *GCFSStructuredQuery_UnaryFilter_Operator_EnumDescriptor(void) { + static GPBEnumDescriptor *descriptor = NULL; + if (!descriptor) { + static const char *valueNames = + "OperatorUnspecified\000IsNan\000IsNull\000"; + static const int32_t values[] = { + GCFSStructuredQuery_UnaryFilter_Operator_OperatorUnspecified, + GCFSStructuredQuery_UnaryFilter_Operator_IsNan, + GCFSStructuredQuery_UnaryFilter_Operator_IsNull, + }; + GPBEnumDescriptor *worker = + [GPBEnumDescriptor allocDescriptorForName:GPBNSStringifySymbol(GCFSStructuredQuery_UnaryFilter_Operator) + valueNames:valueNames + values:values + count:(uint32_t)(sizeof(values) / sizeof(int32_t)) + enumVerifier:GCFSStructuredQuery_UnaryFilter_Operator_IsValidValue]; + if (!OSAtomicCompareAndSwapPtrBarrier(nil, worker, (void * volatile *)&descriptor)) { + [worker release]; + } + } + return descriptor; +} + +BOOL GCFSStructuredQuery_UnaryFilter_Operator_IsValidValue(int32_t value__) { + switch (value__) { + case GCFSStructuredQuery_UnaryFilter_Operator_OperatorUnspecified: + case GCFSStructuredQuery_UnaryFilter_Operator_IsNan: + case GCFSStructuredQuery_UnaryFilter_Operator_IsNull: + return YES; + default: + return NO; + } +} + +#pragma mark - GCFSStructuredQuery_Order + +@implementation GCFSStructuredQuery_Order + +@dynamic hasField, field; +@dynamic direction; + +typedef struct GCFSStructuredQuery_Order__storage_ { + uint32_t _has_storage_[1]; + GCFSStructuredQuery_Direction direction; + GCFSStructuredQuery_FieldReference *field; +} GCFSStructuredQuery_Order__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "field", + .dataTypeSpecific.className = GPBStringifySymbol(GCFSStructuredQuery_FieldReference), + .number = GCFSStructuredQuery_Order_FieldNumber_Field, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GCFSStructuredQuery_Order__storage_, field), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + { + .name = "direction", + .dataTypeSpecific.enumDescFunc = GCFSStructuredQuery_Direction_EnumDescriptor, + .number = GCFSStructuredQuery_Order_FieldNumber_Direction, + .hasIndex = 1, + .offset = (uint32_t)offsetof(GCFSStructuredQuery_Order__storage_, direction), + .flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldHasEnumDescriptor), + .dataType = GPBDataTypeEnum, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GCFSStructuredQuery_Order class] + rootClass:[GCFSQueryRoot class] + file:GCFSQueryRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GCFSStructuredQuery_Order__storage_) + flags:GPBDescriptorInitializationFlag_None]; + [localDescriptor setupContainingMessageClassName:GPBStringifySymbol(GCFSStructuredQuery)]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +int32_t GCFSStructuredQuery_Order_Direction_RawValue(GCFSStructuredQuery_Order *message) { + GPBDescriptor *descriptor = [GCFSStructuredQuery_Order descriptor]; + GPBFieldDescriptor *field = [descriptor fieldWithNumber:GCFSStructuredQuery_Order_FieldNumber_Direction]; + return GPBGetMessageInt32Field(message, field); +} + +void SetGCFSStructuredQuery_Order_Direction_RawValue(GCFSStructuredQuery_Order *message, int32_t value) { + GPBDescriptor *descriptor = [GCFSStructuredQuery_Order descriptor]; + GPBFieldDescriptor *field = [descriptor fieldWithNumber:GCFSStructuredQuery_Order_FieldNumber_Direction]; + GPBSetInt32IvarWithFieldInternal(message, field, value, descriptor.file.syntax); +} + +#pragma mark - GCFSStructuredQuery_FieldReference + +@implementation GCFSStructuredQuery_FieldReference + +@dynamic fieldPath; + +typedef struct GCFSStructuredQuery_FieldReference__storage_ { + uint32_t _has_storage_[1]; + NSString *fieldPath; +} GCFSStructuredQuery_FieldReference__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "fieldPath", + .dataTypeSpecific.className = NULL, + .number = GCFSStructuredQuery_FieldReference_FieldNumber_FieldPath, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GCFSStructuredQuery_FieldReference__storage_, fieldPath), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GCFSStructuredQuery_FieldReference class] + rootClass:[GCFSQueryRoot class] + file:GCFSQueryRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GCFSStructuredQuery_FieldReference__storage_) + flags:GPBDescriptorInitializationFlag_None]; + [localDescriptor setupContainingMessageClassName:GPBStringifySymbol(GCFSStructuredQuery)]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - GCFSStructuredQuery_Projection + +@implementation GCFSStructuredQuery_Projection + +@dynamic fieldsArray, fieldsArray_Count; + +typedef struct GCFSStructuredQuery_Projection__storage_ { + uint32_t _has_storage_[1]; + NSMutableArray *fieldsArray; +} GCFSStructuredQuery_Projection__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "fieldsArray", + .dataTypeSpecific.className = GPBStringifySymbol(GCFSStructuredQuery_FieldReference), + .number = GCFSStructuredQuery_Projection_FieldNumber_FieldsArray, + .hasIndex = GPBNoHasBit, + .offset = (uint32_t)offsetof(GCFSStructuredQuery_Projection__storage_, fieldsArray), + .flags = GPBFieldRepeated, + .dataType = GPBDataTypeMessage, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GCFSStructuredQuery_Projection class] + rootClass:[GCFSQueryRoot class] + file:GCFSQueryRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GCFSStructuredQuery_Projection__storage_) + flags:GPBDescriptorInitializationFlag_None]; + [localDescriptor setupContainingMessageClassName:GPBStringifySymbol(GCFSStructuredQuery)]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - GCFSCursor + +@implementation GCFSCursor + +@dynamic valuesArray, valuesArray_Count; +@dynamic before; + +typedef struct GCFSCursor__storage_ { + uint32_t _has_storage_[1]; + NSMutableArray *valuesArray; +} GCFSCursor__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "valuesArray", + .dataTypeSpecific.className = GPBStringifySymbol(GCFSValue), + .number = GCFSCursor_FieldNumber_ValuesArray, + .hasIndex = GPBNoHasBit, + .offset = (uint32_t)offsetof(GCFSCursor__storage_, valuesArray), + .flags = GPBFieldRepeated, + .dataType = GPBDataTypeMessage, + }, + { + .name = "before", + .dataTypeSpecific.className = NULL, + .number = GCFSCursor_FieldNumber_Before, + .hasIndex = 0, + .offset = 1, // Stored in _has_storage_ to save space. + .flags = GPBFieldOptional, + .dataType = GPBDataTypeBool, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GCFSCursor class] + rootClass:[GCFSQueryRoot class] + file:GCFSQueryRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GCFSCursor__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + + +#pragma clang diagnostic pop + +// @@protoc_insertion_point(global_scope) diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/objc/google/firestore/v1/Write.pbobjc.h b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/objc/google/firestore/v1/Write.pbobjc.h new file mode 100644 index 0000000..8d1b546 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/objc/google/firestore/v1/Write.pbobjc.h @@ -0,0 +1,515 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/firestore/v1/write.proto + +// This CPP symbol can be defined to use imports that match up to the framework +// imports needed when using CocoaPods. +#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) + #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 +#endif + +#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS + #import +#else + #import "GPBProtocolBuffers.h" +#endif + +#if GOOGLE_PROTOBUF_OBJC_VERSION < 30002 +#error This file was generated by a newer version of protoc which is incompatible with your Protocol Buffer library sources. +#endif +#if 30002 < GOOGLE_PROTOBUF_OBJC_MIN_SUPPORTED_VERSION +#error This file was generated by an older version of protoc which is incompatible with your Protocol Buffer library sources. +#endif + +// @@protoc_insertion_point(imports) + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + +CF_EXTERN_C_BEGIN + +@class GCFSArrayValue; +@class GCFSDocument; +@class GCFSDocumentMask; +@class GCFSDocumentTransform; +@class GCFSDocumentTransform_FieldTransform; +@class GCFSPrecondition; +@class GCFSValue; +@class GPBTimestamp; + +NS_ASSUME_NONNULL_BEGIN + +#pragma mark - Enum GCFSDocumentTransform_FieldTransform_ServerValue + +/** A value that is calculated by the server. */ +typedef GPB_ENUM(GCFSDocumentTransform_FieldTransform_ServerValue) { + /** + * Value used if any message's field encounters a value that is not defined + * by this enum. The message will also have C functions to get/set the rawValue + * of the field. + **/ + GCFSDocumentTransform_FieldTransform_ServerValue_GPBUnrecognizedEnumeratorValue = kGPBUnrecognizedEnumeratorValue, + /** Unspecified. This value must not be used. */ + GCFSDocumentTransform_FieldTransform_ServerValue_ServerValueUnspecified = 0, + + /** + * The time at which the server processed the request, with millisecond + * precision. + **/ + GCFSDocumentTransform_FieldTransform_ServerValue_RequestTime = 1, +}; + +GPBEnumDescriptor *GCFSDocumentTransform_FieldTransform_ServerValue_EnumDescriptor(void); + +/** + * Checks to see if the given value is defined by the enum or was not known at + * the time this source was generated. + **/ +BOOL GCFSDocumentTransform_FieldTransform_ServerValue_IsValidValue(int32_t value); + +#pragma mark - GCFSWriteRoot + +/** + * Exposes the extension registry for this file. + * + * The base class provides: + * @code + * + (GPBExtensionRegistry *)extensionRegistry; + * @endcode + * which is a @c GPBExtensionRegistry that includes all the extensions defined by + * this file and all files that it depends on. + **/ +@interface GCFSWriteRoot : GPBRootObject +@end + +#pragma mark - GCFSWrite + +typedef GPB_ENUM(GCFSWrite_FieldNumber) { + GCFSWrite_FieldNumber_Update = 1, + GCFSWrite_FieldNumber_Delete_p = 2, + GCFSWrite_FieldNumber_UpdateMask = 3, + GCFSWrite_FieldNumber_CurrentDocument = 4, + GCFSWrite_FieldNumber_Transform = 6, +}; + +typedef GPB_ENUM(GCFSWrite_Operation_OneOfCase) { + GCFSWrite_Operation_OneOfCase_GPBUnsetOneOfCase = 0, + GCFSWrite_Operation_OneOfCase_Update = 1, + GCFSWrite_Operation_OneOfCase_Delete_p = 2, + GCFSWrite_Operation_OneOfCase_Transform = 6, +}; + +/** + * A write on a document. + **/ +@interface GCFSWrite : GPBMessage + +/** The operation to execute. */ +@property(nonatomic, readonly) GCFSWrite_Operation_OneOfCase operationOneOfCase; + +/** A document to write. */ +@property(nonatomic, readwrite, strong, null_resettable) GCFSDocument *update; + +/** + * A document name to delete. In the format: + * `projects/{project_id}/databases/{database_id}/documents/{document_path}`. + **/ +@property(nonatomic, readwrite, copy, null_resettable) NSString *delete_p; + +/** + * Applies a tranformation to a document. + * At most one `transform` per document is allowed in a given request. + * An `update` cannot follow a `transform` on the same document in a given + * request. + **/ +@property(nonatomic, readwrite, strong, null_resettable) GCFSDocumentTransform *transform; + +/** + * The fields to update in this write. + * + * This field can be set only when the operation is `update`. + * If the mask is not set for an `update` and the document exists, any + * existing data will be overwritten. + * If the mask is set and the document on the server has fields not covered by + * the mask, they are left unchanged. + * Fields referenced in the mask, but not present in the input document, are + * deleted from the document on the server. + * The field paths in this mask must not contain a reserved field name. + **/ +@property(nonatomic, readwrite, strong, null_resettable) GCFSDocumentMask *updateMask; +/** Test to see if @c updateMask has been set. */ +@property(nonatomic, readwrite) BOOL hasUpdateMask; + +/** + * An optional precondition on the document. + * + * The write will fail if this is set and not met by the target document. + **/ +@property(nonatomic, readwrite, strong, null_resettable) GCFSPrecondition *currentDocument; +/** Test to see if @c currentDocument has been set. */ +@property(nonatomic, readwrite) BOOL hasCurrentDocument; + +@end + +/** + * Clears whatever value was set for the oneof 'operation'. + **/ +void GCFSWrite_ClearOperationOneOfCase(GCFSWrite *message); + +#pragma mark - GCFSDocumentTransform + +typedef GPB_ENUM(GCFSDocumentTransform_FieldNumber) { + GCFSDocumentTransform_FieldNumber_Document = 1, + GCFSDocumentTransform_FieldNumber_FieldTransformsArray = 2, +}; + +/** + * A transformation of a document. + **/ +@interface GCFSDocumentTransform : GPBMessage + +/** The name of the document to transform. */ +@property(nonatomic, readwrite, copy, null_resettable) NSString *document; + +/** + * The list of transformations to apply to the fields of the document, in + * order. + * This must not be empty. + **/ +@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *fieldTransformsArray; +/** The number of items in @c fieldTransformsArray without causing the array to be created. */ +@property(nonatomic, readonly) NSUInteger fieldTransformsArray_Count; + +@end + +#pragma mark - GCFSDocumentTransform_FieldTransform + +typedef GPB_ENUM(GCFSDocumentTransform_FieldTransform_FieldNumber) { + GCFSDocumentTransform_FieldTransform_FieldNumber_FieldPath = 1, + GCFSDocumentTransform_FieldTransform_FieldNumber_SetToServerValue = 2, + GCFSDocumentTransform_FieldTransform_FieldNumber_Increment = 3, + GCFSDocumentTransform_FieldTransform_FieldNumber_Maximum = 4, + GCFSDocumentTransform_FieldTransform_FieldNumber_Minimum = 5, + GCFSDocumentTransform_FieldTransform_FieldNumber_AppendMissingElements = 6, + GCFSDocumentTransform_FieldTransform_FieldNumber_RemoveAllFromArray_p = 7, +}; + +typedef GPB_ENUM(GCFSDocumentTransform_FieldTransform_TransformType_OneOfCase) { + GCFSDocumentTransform_FieldTransform_TransformType_OneOfCase_GPBUnsetOneOfCase = 0, + GCFSDocumentTransform_FieldTransform_TransformType_OneOfCase_SetToServerValue = 2, + GCFSDocumentTransform_FieldTransform_TransformType_OneOfCase_Increment = 3, + GCFSDocumentTransform_FieldTransform_TransformType_OneOfCase_Maximum = 4, + GCFSDocumentTransform_FieldTransform_TransformType_OneOfCase_Minimum = 5, + GCFSDocumentTransform_FieldTransform_TransformType_OneOfCase_AppendMissingElements = 6, + GCFSDocumentTransform_FieldTransform_TransformType_OneOfCase_RemoveAllFromArray_p = 7, +}; + +/** + * A transformation of a field of the document. + **/ +@interface GCFSDocumentTransform_FieldTransform : GPBMessage + +/** + * The path of the field. See [Document.fields][google.firestore.v1.Document.fields] for the field path syntax + * reference. + **/ +@property(nonatomic, readwrite, copy, null_resettable) NSString *fieldPath; + +/** The transformation to apply on the field. */ +@property(nonatomic, readonly) GCFSDocumentTransform_FieldTransform_TransformType_OneOfCase transformTypeOneOfCase; + +/** Sets the field to the given server value. */ +@property(nonatomic, readwrite) GCFSDocumentTransform_FieldTransform_ServerValue setToServerValue; + +/** + * Adds the given value to the field's current value. + * + * This must be an integer or a double value. + * If the field is not an integer or double, or if the field does not yet + * exist, the transformation will set the field to the given value. + * If either of the given value or the current field value are doubles, + * both values will be interpreted as doubles. Double arithmetic and + * representation of double values follow IEEE 754 semantics. + * If there is positive/negative integer overflow, the field is resolved + * to the largest magnitude positive/negative integer. + **/ +@property(nonatomic, readwrite, strong, null_resettable) GCFSValue *increment; + +/** + * Sets the field to the maximum of its current value and the given value. + * + * This must be an integer or a double value. + * If the field is not an integer or double, or if the field does not yet + * exist, the transformation will set the field to the given value. + * If a maximum operation is applied where the field and the input value + * are of mixed types (that is - one is an integer and one is a double) + * the field takes on the type of the larger operand. If the operands are + * equivalent (e.g. 3 and 3.0), the field does not change. + * 0, 0.0, and -0.0 are all zero. The maximum of a zero stored value and + * zero input value is always the stored value. + * The maximum of any numeric value x and NaN is NaN. + **/ +@property(nonatomic, readwrite, strong, null_resettable) GCFSValue *maximum; + +/** + * Sets the field to the minimum of its current value and the given value. + * + * This must be an integer or a double value. + * If the field is not an integer or double, or if the field does not yet + * exist, the transformation will set the field to the input value. + * If a minimum operation is applied where the field and the input value + * are of mixed types (that is - one is an integer and one is a double) + * the field takes on the type of the smaller operand. If the operands are + * equivalent (e.g. 3 and 3.0), the field does not change. + * 0, 0.0, and -0.0 are all zero. The minimum of a zero stored value and + * zero input value is always the stored value. + * The minimum of any numeric value x and NaN is NaN. + **/ +@property(nonatomic, readwrite, strong, null_resettable) GCFSValue *minimum; + +/** + * Append the given elements in order if they are not already present in + * the current field value. + * If the field is not an array, or if the field does not yet exist, it is + * first set to the empty array. + * + * Equivalent numbers of different types (e.g. 3L and 3.0) are + * considered equal when checking if a value is missing. + * NaN is equal to NaN, and Null is equal to Null. + * If the input contains multiple equivalent values, only the first will + * be considered. + * + * The corresponding transform_result will be the null value. + **/ +@property(nonatomic, readwrite, strong, null_resettable) GCFSArrayValue *appendMissingElements; + +/** + * Remove all of the given elements from the array in the field. + * If the field is not an array, or if the field does not yet exist, it is + * set to the empty array. + * + * Equivalent numbers of the different types (e.g. 3L and 3.0) are + * considered equal when deciding whether an element should be removed. + * NaN is equal to NaN, and Null is equal to Null. + * This will remove all equivalent values if there are duplicates. + * + * The corresponding transform_result will be the null value. + **/ +@property(nonatomic, readwrite, strong, null_resettable) GCFSArrayValue *removeAllFromArray_p; + +@end + +/** + * Fetches the raw value of a @c GCFSDocumentTransform_FieldTransform's @c setToServerValue property, even + * if the value was not defined by the enum at the time the code was generated. + **/ +int32_t GCFSDocumentTransform_FieldTransform_SetToServerValue_RawValue(GCFSDocumentTransform_FieldTransform *message); +/** + * Sets the raw value of an @c GCFSDocumentTransform_FieldTransform's @c setToServerValue property, allowing + * it to be set to a value that was not defined by the enum at the time the code + * was generated. + **/ +void SetGCFSDocumentTransform_FieldTransform_SetToServerValue_RawValue(GCFSDocumentTransform_FieldTransform *message, int32_t value); + +/** + * Clears whatever value was set for the oneof 'transformType'. + **/ +void GCFSDocumentTransform_FieldTransform_ClearTransformTypeOneOfCase(GCFSDocumentTransform_FieldTransform *message); + +#pragma mark - GCFSWriteResult + +typedef GPB_ENUM(GCFSWriteResult_FieldNumber) { + GCFSWriteResult_FieldNumber_UpdateTime = 1, + GCFSWriteResult_FieldNumber_TransformResultsArray = 2, +}; + +/** + * The result of applying a write. + **/ +@interface GCFSWriteResult : GPBMessage + +/** + * The last update time of the document after applying the write. Not set + * after a `delete`. + * + * If the write did not actually change the document, this will be the + * previous update_time. + **/ +@property(nonatomic, readwrite, strong, null_resettable) GPBTimestamp *updateTime; +/** Test to see if @c updateTime has been set. */ +@property(nonatomic, readwrite) BOOL hasUpdateTime; + +/** + * The results of applying each [DocumentTransform.FieldTransform][google.firestore.v1.DocumentTransform.FieldTransform], in the + * same order. + **/ +@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *transformResultsArray; +/** The number of items in @c transformResultsArray without causing the array to be created. */ +@property(nonatomic, readonly) NSUInteger transformResultsArray_Count; + +@end + +#pragma mark - GCFSDocumentChange + +typedef GPB_ENUM(GCFSDocumentChange_FieldNumber) { + GCFSDocumentChange_FieldNumber_Document = 1, + GCFSDocumentChange_FieldNumber_TargetIdsArray = 5, + GCFSDocumentChange_FieldNumber_RemovedTargetIdsArray = 6, +}; + +/** + * A [Document][google.firestore.v1.Document] has changed. + * + * May be the result of multiple [writes][google.firestore.v1.Write], including deletes, that + * ultimately resulted in a new value for the [Document][google.firestore.v1.Document]. + * + * Multiple [DocumentChange][google.firestore.v1.DocumentChange] messages may be returned for the same logical + * change, if multiple targets are affected. + **/ +@interface GCFSDocumentChange : GPBMessage + +/** + * The new state of the [Document][google.firestore.v1.Document]. + * + * If `mask` is set, contains only fields that were updated or added. + **/ +@property(nonatomic, readwrite, strong, null_resettable) GCFSDocument *document; +/** Test to see if @c document has been set. */ +@property(nonatomic, readwrite) BOOL hasDocument; + +/** A set of target IDs of targets that match this document. */ +@property(nonatomic, readwrite, strong, null_resettable) GPBInt32Array *targetIdsArray; +/** The number of items in @c targetIdsArray without causing the array to be created. */ +@property(nonatomic, readonly) NSUInteger targetIdsArray_Count; + +/** A set of target IDs for targets that no longer match this document. */ +@property(nonatomic, readwrite, strong, null_resettable) GPBInt32Array *removedTargetIdsArray; +/** The number of items in @c removedTargetIdsArray without causing the array to be created. */ +@property(nonatomic, readonly) NSUInteger removedTargetIdsArray_Count; + +@end + +#pragma mark - GCFSDocumentDelete + +typedef GPB_ENUM(GCFSDocumentDelete_FieldNumber) { + GCFSDocumentDelete_FieldNumber_Document = 1, + GCFSDocumentDelete_FieldNumber_ReadTime = 4, + GCFSDocumentDelete_FieldNumber_RemovedTargetIdsArray = 6, +}; + +/** + * A [Document][google.firestore.v1.Document] has been deleted. + * + * May be the result of multiple [writes][google.firestore.v1.Write], including updates, the + * last of which deleted the [Document][google.firestore.v1.Document]. + * + * Multiple [DocumentDelete][google.firestore.v1.DocumentDelete] messages may be returned for the same logical + * delete, if multiple targets are affected. + **/ +@interface GCFSDocumentDelete : GPBMessage + +/** The resource name of the [Document][google.firestore.v1.Document] that was deleted. */ +@property(nonatomic, readwrite, copy, null_resettable) NSString *document; + +/** A set of target IDs for targets that previously matched this entity. */ +@property(nonatomic, readwrite, strong, null_resettable) GPBInt32Array *removedTargetIdsArray; +/** The number of items in @c removedTargetIdsArray without causing the array to be created. */ +@property(nonatomic, readonly) NSUInteger removedTargetIdsArray_Count; + +/** + * The read timestamp at which the delete was observed. + * + * Greater or equal to the `commit_time` of the delete. + **/ +@property(nonatomic, readwrite, strong, null_resettable) GPBTimestamp *readTime; +/** Test to see if @c readTime has been set. */ +@property(nonatomic, readwrite) BOOL hasReadTime; + +@end + +#pragma mark - GCFSDocumentRemove + +typedef GPB_ENUM(GCFSDocumentRemove_FieldNumber) { + GCFSDocumentRemove_FieldNumber_Document = 1, + GCFSDocumentRemove_FieldNumber_RemovedTargetIdsArray = 2, + GCFSDocumentRemove_FieldNumber_ReadTime = 4, +}; + +/** + * A [Document][google.firestore.v1.Document] has been removed from the view of the targets. + * + * Sent if the document is no longer relevant to a target and is out of view. + * Can be sent instead of a DocumentDelete or a DocumentChange if the server + * can not send the new value of the document. + * + * Multiple [DocumentRemove][google.firestore.v1.DocumentRemove] messages may be returned for the same logical + * write or delete, if multiple targets are affected. + **/ +@interface GCFSDocumentRemove : GPBMessage + +/** The resource name of the [Document][google.firestore.v1.Document] that has gone out of view. */ +@property(nonatomic, readwrite, copy, null_resettable) NSString *document; + +/** A set of target IDs for targets that previously matched this document. */ +@property(nonatomic, readwrite, strong, null_resettable) GPBInt32Array *removedTargetIdsArray; +/** The number of items in @c removedTargetIdsArray without causing the array to be created. */ +@property(nonatomic, readonly) NSUInteger removedTargetIdsArray_Count; + +/** + * The read timestamp at which the remove was observed. + * + * Greater or equal to the `commit_time` of the change/delete/remove. + **/ +@property(nonatomic, readwrite, strong, null_resettable) GPBTimestamp *readTime; +/** Test to see if @c readTime has been set. */ +@property(nonatomic, readwrite) BOOL hasReadTime; + +@end + +#pragma mark - GCFSExistenceFilter + +typedef GPB_ENUM(GCFSExistenceFilter_FieldNumber) { + GCFSExistenceFilter_FieldNumber_TargetId = 1, + GCFSExistenceFilter_FieldNumber_Count = 2, +}; + +/** + * A digest of all the documents that match a given target. + **/ +@interface GCFSExistenceFilter : GPBMessage + +/** The target ID to which this filter applies. */ +@property(nonatomic, readwrite) int32_t targetId; + +/** + * The total count of documents that match [target_id][google.firestore.v1.ExistenceFilter.target_id]. + * + * If different from the count of documents in the client that match, the + * client must manually determine which documents no longer match the target. + **/ +@property(nonatomic, readwrite) int32_t count; + +@end + +NS_ASSUME_NONNULL_END + +CF_EXTERN_C_END + +#pragma clang diagnostic pop + +// @@protoc_insertion_point(global_scope) diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/objc/google/firestore/v1/Write.pbobjc.m b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/objc/google/firestore/v1/Write.pbobjc.m new file mode 100644 index 0000000..1114421 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/objc/google/firestore/v1/Write.pbobjc.m @@ -0,0 +1,697 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/firestore/v1/write.proto + +// This CPP symbol can be defined to use imports that match up to the framework +// imports needed when using CocoaPods. +#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) + #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 +#endif + +#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS + #import +#else + #import "GPBProtocolBuffers_RuntimeSupport.h" +#endif + +#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS + #import +#else + #import "Timestamp.pbobjc.h" +#endif + + #import "Write.pbobjc.h" + #import "Annotations.pbobjc.h" + #import "Common.pbobjc.h" + #import "Document.pbobjc.h" +// @@protoc_insertion_point(imports) + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" +#pragma clang diagnostic ignored "-Wdirect-ivar-access" + +#pragma mark - GCFSWriteRoot + +@implementation GCFSWriteRoot + + +@end + +#pragma mark - GCFSWriteRoot_FileDescriptor + +static GPBFileDescriptor *GCFSWriteRoot_FileDescriptor(void) { + // This is called by +initialize so there is no need to worry + // about thread safety of the singleton. + static GPBFileDescriptor *descriptor = NULL; + if (!descriptor) { + GPB_DEBUG_CHECK_RUNTIME_VERSIONS(); + descriptor = [[GPBFileDescriptor alloc] initWithPackage:@"google.firestore.v1" + objcPrefix:@"GCFS" + syntax:GPBFileSyntaxProto3]; + } + return descriptor; +} + +#pragma mark - GCFSWrite + +@implementation GCFSWrite + +@dynamic operationOneOfCase; +@dynamic update; +@dynamic delete_p; +@dynamic transform; +@dynamic hasUpdateMask, updateMask; +@dynamic hasCurrentDocument, currentDocument; + +typedef struct GCFSWrite__storage_ { + uint32_t _has_storage_[2]; + GCFSDocument *update; + NSString *delete_p; + GCFSDocumentMask *updateMask; + GCFSPrecondition *currentDocument; + GCFSDocumentTransform *transform; +} GCFSWrite__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "update", + .dataTypeSpecific.className = GPBStringifySymbol(GCFSDocument), + .number = GCFSWrite_FieldNumber_Update, + .hasIndex = -1, + .offset = (uint32_t)offsetof(GCFSWrite__storage_, update), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + { + .name = "delete_p", + .dataTypeSpecific.className = NULL, + .number = GCFSWrite_FieldNumber_Delete_p, + .hasIndex = -1, + .offset = (uint32_t)offsetof(GCFSWrite__storage_, delete_p), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "updateMask", + .dataTypeSpecific.className = GPBStringifySymbol(GCFSDocumentMask), + .number = GCFSWrite_FieldNumber_UpdateMask, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GCFSWrite__storage_, updateMask), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + { + .name = "currentDocument", + .dataTypeSpecific.className = GPBStringifySymbol(GCFSPrecondition), + .number = GCFSWrite_FieldNumber_CurrentDocument, + .hasIndex = 1, + .offset = (uint32_t)offsetof(GCFSWrite__storage_, currentDocument), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + { + .name = "transform", + .dataTypeSpecific.className = GPBStringifySymbol(GCFSDocumentTransform), + .number = GCFSWrite_FieldNumber_Transform, + .hasIndex = -1, + .offset = (uint32_t)offsetof(GCFSWrite__storage_, transform), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GCFSWrite class] + rootClass:[GCFSWriteRoot class] + file:GCFSWriteRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GCFSWrite__storage_) + flags:GPBDescriptorInitializationFlag_None]; + static const char *oneofs[] = { + "operation", + }; + [localDescriptor setupOneofs:oneofs + count:(uint32_t)(sizeof(oneofs) / sizeof(char*)) + firstHasIndex:-1]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +void GCFSWrite_ClearOperationOneOfCase(GCFSWrite *message) { + GPBDescriptor *descriptor = [message descriptor]; + GPBOneofDescriptor *oneof = [descriptor.oneofs objectAtIndex:0]; + GPBMaybeClearOneof(message, oneof, -1, 0); +} +#pragma mark - GCFSDocumentTransform + +@implementation GCFSDocumentTransform + +@dynamic document; +@dynamic fieldTransformsArray, fieldTransformsArray_Count; + +typedef struct GCFSDocumentTransform__storage_ { + uint32_t _has_storage_[1]; + NSString *document; + NSMutableArray *fieldTransformsArray; +} GCFSDocumentTransform__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "document", + .dataTypeSpecific.className = NULL, + .number = GCFSDocumentTransform_FieldNumber_Document, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GCFSDocumentTransform__storage_, document), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "fieldTransformsArray", + .dataTypeSpecific.className = GPBStringifySymbol(GCFSDocumentTransform_FieldTransform), + .number = GCFSDocumentTransform_FieldNumber_FieldTransformsArray, + .hasIndex = GPBNoHasBit, + .offset = (uint32_t)offsetof(GCFSDocumentTransform__storage_, fieldTransformsArray), + .flags = GPBFieldRepeated, + .dataType = GPBDataTypeMessage, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GCFSDocumentTransform class] + rootClass:[GCFSWriteRoot class] + file:GCFSWriteRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GCFSDocumentTransform__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - GCFSDocumentTransform_FieldTransform + +@implementation GCFSDocumentTransform_FieldTransform + +@dynamic transformTypeOneOfCase; +@dynamic fieldPath; +@dynamic setToServerValue; +@dynamic increment; +@dynamic maximum; +@dynamic minimum; +@dynamic appendMissingElements; +@dynamic removeAllFromArray_p; + +typedef struct GCFSDocumentTransform_FieldTransform__storage_ { + uint32_t _has_storage_[2]; + GCFSDocumentTransform_FieldTransform_ServerValue setToServerValue; + NSString *fieldPath; + GCFSValue *increment; + GCFSValue *maximum; + GCFSValue *minimum; + GCFSArrayValue *appendMissingElements; + GCFSArrayValue *removeAllFromArray_p; +} GCFSDocumentTransform_FieldTransform__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "fieldPath", + .dataTypeSpecific.className = NULL, + .number = GCFSDocumentTransform_FieldTransform_FieldNumber_FieldPath, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GCFSDocumentTransform_FieldTransform__storage_, fieldPath), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "setToServerValue", + .dataTypeSpecific.enumDescFunc = GCFSDocumentTransform_FieldTransform_ServerValue_EnumDescriptor, + .number = GCFSDocumentTransform_FieldTransform_FieldNumber_SetToServerValue, + .hasIndex = -1, + .offset = (uint32_t)offsetof(GCFSDocumentTransform_FieldTransform__storage_, setToServerValue), + .flags = (GPBFieldFlags)(GPBFieldOptional | GPBFieldHasEnumDescriptor), + .dataType = GPBDataTypeEnum, + }, + { + .name = "increment", + .dataTypeSpecific.className = GPBStringifySymbol(GCFSValue), + .number = GCFSDocumentTransform_FieldTransform_FieldNumber_Increment, + .hasIndex = -1, + .offset = (uint32_t)offsetof(GCFSDocumentTransform_FieldTransform__storage_, increment), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + { + .name = "maximum", + .dataTypeSpecific.className = GPBStringifySymbol(GCFSValue), + .number = GCFSDocumentTransform_FieldTransform_FieldNumber_Maximum, + .hasIndex = -1, + .offset = (uint32_t)offsetof(GCFSDocumentTransform_FieldTransform__storage_, maximum), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + { + .name = "minimum", + .dataTypeSpecific.className = GPBStringifySymbol(GCFSValue), + .number = GCFSDocumentTransform_FieldTransform_FieldNumber_Minimum, + .hasIndex = -1, + .offset = (uint32_t)offsetof(GCFSDocumentTransform_FieldTransform__storage_, minimum), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + { + .name = "appendMissingElements", + .dataTypeSpecific.className = GPBStringifySymbol(GCFSArrayValue), + .number = GCFSDocumentTransform_FieldTransform_FieldNumber_AppendMissingElements, + .hasIndex = -1, + .offset = (uint32_t)offsetof(GCFSDocumentTransform_FieldTransform__storage_, appendMissingElements), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + { + .name = "removeAllFromArray_p", + .dataTypeSpecific.className = GPBStringifySymbol(GCFSArrayValue), + .number = GCFSDocumentTransform_FieldTransform_FieldNumber_RemoveAllFromArray_p, + .hasIndex = -1, + .offset = (uint32_t)offsetof(GCFSDocumentTransform_FieldTransform__storage_, removeAllFromArray_p), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GCFSDocumentTransform_FieldTransform class] + rootClass:[GCFSWriteRoot class] + file:GCFSWriteRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GCFSDocumentTransform_FieldTransform__storage_) + flags:GPBDescriptorInitializationFlag_None]; + static const char *oneofs[] = { + "transformType", + }; + [localDescriptor setupOneofs:oneofs + count:(uint32_t)(sizeof(oneofs) / sizeof(char*)) + firstHasIndex:-1]; + [localDescriptor setupContainingMessageClassName:GPBStringifySymbol(GCFSDocumentTransform)]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +int32_t GCFSDocumentTransform_FieldTransform_SetToServerValue_RawValue(GCFSDocumentTransform_FieldTransform *message) { + GPBDescriptor *descriptor = [GCFSDocumentTransform_FieldTransform descriptor]; + GPBFieldDescriptor *field = [descriptor fieldWithNumber:GCFSDocumentTransform_FieldTransform_FieldNumber_SetToServerValue]; + return GPBGetMessageInt32Field(message, field); +} + +void SetGCFSDocumentTransform_FieldTransform_SetToServerValue_RawValue(GCFSDocumentTransform_FieldTransform *message, int32_t value) { + GPBDescriptor *descriptor = [GCFSDocumentTransform_FieldTransform descriptor]; + GPBFieldDescriptor *field = [descriptor fieldWithNumber:GCFSDocumentTransform_FieldTransform_FieldNumber_SetToServerValue]; + GPBSetInt32IvarWithFieldInternal(message, field, value, descriptor.file.syntax); +} + +void GCFSDocumentTransform_FieldTransform_ClearTransformTypeOneOfCase(GCFSDocumentTransform_FieldTransform *message) { + GPBDescriptor *descriptor = [message descriptor]; + GPBOneofDescriptor *oneof = [descriptor.oneofs objectAtIndex:0]; + GPBMaybeClearOneof(message, oneof, -1, 0); +} +#pragma mark - Enum GCFSDocumentTransform_FieldTransform_ServerValue + +GPBEnumDescriptor *GCFSDocumentTransform_FieldTransform_ServerValue_EnumDescriptor(void) { + static GPBEnumDescriptor *descriptor = NULL; + if (!descriptor) { + static const char *valueNames = + "ServerValueUnspecified\000RequestTime\000"; + static const int32_t values[] = { + GCFSDocumentTransform_FieldTransform_ServerValue_ServerValueUnspecified, + GCFSDocumentTransform_FieldTransform_ServerValue_RequestTime, + }; + GPBEnumDescriptor *worker = + [GPBEnumDescriptor allocDescriptorForName:GPBNSStringifySymbol(GCFSDocumentTransform_FieldTransform_ServerValue) + valueNames:valueNames + values:values + count:(uint32_t)(sizeof(values) / sizeof(int32_t)) + enumVerifier:GCFSDocumentTransform_FieldTransform_ServerValue_IsValidValue]; + if (!OSAtomicCompareAndSwapPtrBarrier(nil, worker, (void * volatile *)&descriptor)) { + [worker release]; + } + } + return descriptor; +} + +BOOL GCFSDocumentTransform_FieldTransform_ServerValue_IsValidValue(int32_t value__) { + switch (value__) { + case GCFSDocumentTransform_FieldTransform_ServerValue_ServerValueUnspecified: + case GCFSDocumentTransform_FieldTransform_ServerValue_RequestTime: + return YES; + default: + return NO; + } +} + +#pragma mark - GCFSWriteResult + +@implementation GCFSWriteResult + +@dynamic hasUpdateTime, updateTime; +@dynamic transformResultsArray, transformResultsArray_Count; + +typedef struct GCFSWriteResult__storage_ { + uint32_t _has_storage_[1]; + GPBTimestamp *updateTime; + NSMutableArray *transformResultsArray; +} GCFSWriteResult__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "updateTime", + .dataTypeSpecific.className = GPBStringifySymbol(GPBTimestamp), + .number = GCFSWriteResult_FieldNumber_UpdateTime, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GCFSWriteResult__storage_, updateTime), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + { + .name = "transformResultsArray", + .dataTypeSpecific.className = GPBStringifySymbol(GCFSValue), + .number = GCFSWriteResult_FieldNumber_TransformResultsArray, + .hasIndex = GPBNoHasBit, + .offset = (uint32_t)offsetof(GCFSWriteResult__storage_, transformResultsArray), + .flags = GPBFieldRepeated, + .dataType = GPBDataTypeMessage, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GCFSWriteResult class] + rootClass:[GCFSWriteRoot class] + file:GCFSWriteRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GCFSWriteResult__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - GCFSDocumentChange + +@implementation GCFSDocumentChange + +@dynamic hasDocument, document; +@dynamic targetIdsArray, targetIdsArray_Count; +@dynamic removedTargetIdsArray, removedTargetIdsArray_Count; + +typedef struct GCFSDocumentChange__storage_ { + uint32_t _has_storage_[1]; + GCFSDocument *document; + GPBInt32Array *targetIdsArray; + GPBInt32Array *removedTargetIdsArray; +} GCFSDocumentChange__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "document", + .dataTypeSpecific.className = GPBStringifySymbol(GCFSDocument), + .number = GCFSDocumentChange_FieldNumber_Document, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GCFSDocumentChange__storage_, document), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + { + .name = "targetIdsArray", + .dataTypeSpecific.className = NULL, + .number = GCFSDocumentChange_FieldNumber_TargetIdsArray, + .hasIndex = GPBNoHasBit, + .offset = (uint32_t)offsetof(GCFSDocumentChange__storage_, targetIdsArray), + .flags = (GPBFieldFlags)(GPBFieldRepeated | GPBFieldPacked), + .dataType = GPBDataTypeInt32, + }, + { + .name = "removedTargetIdsArray", + .dataTypeSpecific.className = NULL, + .number = GCFSDocumentChange_FieldNumber_RemovedTargetIdsArray, + .hasIndex = GPBNoHasBit, + .offset = (uint32_t)offsetof(GCFSDocumentChange__storage_, removedTargetIdsArray), + .flags = (GPBFieldFlags)(GPBFieldRepeated | GPBFieldPacked), + .dataType = GPBDataTypeInt32, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GCFSDocumentChange class] + rootClass:[GCFSWriteRoot class] + file:GCFSWriteRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GCFSDocumentChange__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - GCFSDocumentDelete + +@implementation GCFSDocumentDelete + +@dynamic document; +@dynamic removedTargetIdsArray, removedTargetIdsArray_Count; +@dynamic hasReadTime, readTime; + +typedef struct GCFSDocumentDelete__storage_ { + uint32_t _has_storage_[1]; + NSString *document; + GPBTimestamp *readTime; + GPBInt32Array *removedTargetIdsArray; +} GCFSDocumentDelete__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "document", + .dataTypeSpecific.className = NULL, + .number = GCFSDocumentDelete_FieldNumber_Document, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GCFSDocumentDelete__storage_, document), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "readTime", + .dataTypeSpecific.className = GPBStringifySymbol(GPBTimestamp), + .number = GCFSDocumentDelete_FieldNumber_ReadTime, + .hasIndex = 1, + .offset = (uint32_t)offsetof(GCFSDocumentDelete__storage_, readTime), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + { + .name = "removedTargetIdsArray", + .dataTypeSpecific.className = NULL, + .number = GCFSDocumentDelete_FieldNumber_RemovedTargetIdsArray, + .hasIndex = GPBNoHasBit, + .offset = (uint32_t)offsetof(GCFSDocumentDelete__storage_, removedTargetIdsArray), + .flags = (GPBFieldFlags)(GPBFieldRepeated | GPBFieldPacked), + .dataType = GPBDataTypeInt32, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GCFSDocumentDelete class] + rootClass:[GCFSWriteRoot class] + file:GCFSWriteRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GCFSDocumentDelete__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - GCFSDocumentRemove + +@implementation GCFSDocumentRemove + +@dynamic document; +@dynamic removedTargetIdsArray, removedTargetIdsArray_Count; +@dynamic hasReadTime, readTime; + +typedef struct GCFSDocumentRemove__storage_ { + uint32_t _has_storage_[1]; + NSString *document; + GPBInt32Array *removedTargetIdsArray; + GPBTimestamp *readTime; +} GCFSDocumentRemove__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "document", + .dataTypeSpecific.className = NULL, + .number = GCFSDocumentRemove_FieldNumber_Document, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GCFSDocumentRemove__storage_, document), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "removedTargetIdsArray", + .dataTypeSpecific.className = NULL, + .number = GCFSDocumentRemove_FieldNumber_RemovedTargetIdsArray, + .hasIndex = GPBNoHasBit, + .offset = (uint32_t)offsetof(GCFSDocumentRemove__storage_, removedTargetIdsArray), + .flags = (GPBFieldFlags)(GPBFieldRepeated | GPBFieldPacked), + .dataType = GPBDataTypeInt32, + }, + { + .name = "readTime", + .dataTypeSpecific.className = GPBStringifySymbol(GPBTimestamp), + .number = GCFSDocumentRemove_FieldNumber_ReadTime, + .hasIndex = 1, + .offset = (uint32_t)offsetof(GCFSDocumentRemove__storage_, readTime), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeMessage, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GCFSDocumentRemove class] + rootClass:[GCFSWriteRoot class] + file:GCFSWriteRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GCFSDocumentRemove__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + +#pragma mark - GCFSExistenceFilter + +@implementation GCFSExistenceFilter + +@dynamic targetId; +@dynamic count; + +typedef struct GCFSExistenceFilter__storage_ { + uint32_t _has_storage_[1]; + int32_t targetId; + int32_t count; +} GCFSExistenceFilter__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "targetId", + .dataTypeSpecific.className = NULL, + .number = GCFSExistenceFilter_FieldNumber_TargetId, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GCFSExistenceFilter__storage_, targetId), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + { + .name = "count", + .dataTypeSpecific.className = NULL, + .number = GCFSExistenceFilter_FieldNumber_Count, + .hasIndex = 1, + .offset = (uint32_t)offsetof(GCFSExistenceFilter__storage_, count), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GCFSExistenceFilter class] + rootClass:[GCFSWriteRoot class] + file:GCFSWriteRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GCFSExistenceFilter__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + + +#pragma clang diagnostic pop + +// @@protoc_insertion_point(global_scope) diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/objc/google/rpc/Status.pbobjc.h b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/objc/google/rpc/Status.pbobjc.h new file mode 100644 index 0000000..ad81346 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/objc/google/rpc/Status.pbobjc.h @@ -0,0 +1,155 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/rpc/status.proto + +// This CPP symbol can be defined to use imports that match up to the framework +// imports needed when using CocoaPods. +#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) + #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 +#endif + +#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS + #import +#else + #import "GPBProtocolBuffers.h" +#endif + +#if GOOGLE_PROTOBUF_OBJC_VERSION < 30002 +#error This file was generated by a newer version of protoc which is incompatible with your Protocol Buffer library sources. +#endif +#if 30002 < GOOGLE_PROTOBUF_OBJC_MIN_SUPPORTED_VERSION +#error This file was generated by an older version of protoc which is incompatible with your Protocol Buffer library sources. +#endif + +// @@protoc_insertion_point(imports) + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + +CF_EXTERN_C_BEGIN + +@class GPBAny; + +NS_ASSUME_NONNULL_BEGIN + +#pragma mark - RPCStatusRoot + +/** + * Exposes the extension registry for this file. + * + * The base class provides: + * @code + * + (GPBExtensionRegistry *)extensionRegistry; + * @endcode + * which is a @c GPBExtensionRegistry that includes all the extensions defined by + * this file and all files that it depends on. + **/ +@interface RPCStatusRoot : GPBRootObject +@end + +#pragma mark - RPCStatus + +typedef GPB_ENUM(RPCStatus_FieldNumber) { + RPCStatus_FieldNumber_Code = 1, + RPCStatus_FieldNumber_Message = 2, + RPCStatus_FieldNumber_DetailsArray = 3, +}; + +/** + * The `Status` type defines a logical error model that is suitable for different + * programming environments, including REST APIs and RPC APIs. It is used by + * [gRPC](https://github.com/grpc). The error model is designed to be: + * + * - Simple to use and understand for most users + * - Flexible enough to meet unexpected needs + * + * # Overview + * + * The `Status` message contains three pieces of data: error code, error message, + * and error details. The error code should be an enum value of + * [google.rpc.Code][google.rpc.Code], but it may accept additional error codes if needed. The + * error message should be a developer-facing English message that helps + * developers *understand* and *resolve* the error. If a localized user-facing + * error message is needed, put the localized message in the error details or + * localize it in the client. The optional error details may contain arbitrary + * information about the error. There is a predefined set of error detail types + * in the package `google.rpc` that can be used for common error conditions. + * + * # Language mapping + * + * The `Status` message is the logical representation of the error model, but it + * is not necessarily the actual wire format. When the `Status` message is + * exposed in different client libraries and different wire protocols, it can be + * mapped differently. For example, it will likely be mapped to some exceptions + * in Java, but more likely mapped to some error codes in C. + * + * # Other uses + * + * The error model and the `Status` message can be used in a variety of + * environments, either with or without APIs, to provide a + * consistent developer experience across different environments. + * + * Example uses of this error model include: + * + * - Partial errors. If a service needs to return partial errors to the client, + * it may embed the `Status` in the normal response to indicate the partial + * errors. + * + * - Workflow errors. A typical workflow has multiple steps. Each step may + * have a `Status` message for error reporting. + * + * - Batch operations. If a client uses batch request and batch response, the + * `Status` message should be used directly inside batch response, one for + * each error sub-response. + * + * - Asynchronous operations. If an API call embeds asynchronous operation + * results in its response, the status of those operations should be + * represented directly using the `Status` message. + * + * - Logging. If some API errors are stored in logs, the message `Status` could + * be used directly after any stripping needed for security/privacy reasons. + **/ +@interface RPCStatus : GPBMessage + +/** The status code, which should be an enum value of [google.rpc.Code][google.rpc.Code]. */ +@property(nonatomic, readwrite) int32_t code; + +/** + * A developer-facing error message, which should be in English. Any + * user-facing error message should be localized and sent in the + * [google.rpc.Status.details][google.rpc.Status.details] field, or localized by the client. + **/ +@property(nonatomic, readwrite, copy, null_resettable) NSString *message; + +/** + * A list of messages that carry the error details. There is a common set of + * message types for APIs to use. + **/ +@property(nonatomic, readwrite, strong, null_resettable) NSMutableArray *detailsArray; +/** The number of items in @c detailsArray without causing the array to be created. */ +@property(nonatomic, readonly) NSUInteger detailsArray_Count; + +@end + +NS_ASSUME_NONNULL_END + +CF_EXTERN_C_END + +#pragma clang diagnostic pop + +// @@protoc_insertion_point(global_scope) diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/objc/google/rpc/Status.pbobjc.m b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/objc/google/rpc/Status.pbobjc.m new file mode 100644 index 0000000..1183027 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/objc/google/rpc/Status.pbobjc.m @@ -0,0 +1,136 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/rpc/status.proto + +// This CPP symbol can be defined to use imports that match up to the framework +// imports needed when using CocoaPods. +#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) + #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 +#endif + +#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS + #import +#else + #import "GPBProtocolBuffers_RuntimeSupport.h" +#endif + +#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS + #import +#else + #import "Any.pbobjc.h" +#endif + + #import "Status.pbobjc.h" +// @@protoc_insertion_point(imports) + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + +#pragma mark - RPCStatusRoot + +@implementation RPCStatusRoot + +// No extensions in the file and none of the imports (direct or indirect) +// defined extensions, so no need to generate +extensionRegistry. + +@end + +#pragma mark - RPCStatusRoot_FileDescriptor + +static GPBFileDescriptor *RPCStatusRoot_FileDescriptor(void) { + // This is called by +initialize so there is no need to worry + // about thread safety of the singleton. + static GPBFileDescriptor *descriptor = NULL; + if (!descriptor) { + GPB_DEBUG_CHECK_RUNTIME_VERSIONS(); + descriptor = [[GPBFileDescriptor alloc] initWithPackage:@"google.rpc" + objcPrefix:@"RPC" + syntax:GPBFileSyntaxProto3]; + } + return descriptor; +} + +#pragma mark - RPCStatus + +@implementation RPCStatus + +@dynamic code; +@dynamic message; +@dynamic detailsArray, detailsArray_Count; + +typedef struct RPCStatus__storage_ { + uint32_t _has_storage_[1]; + int32_t code; + NSString *message; + NSMutableArray *detailsArray; +} RPCStatus__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "code", + .dataTypeSpecific.className = NULL, + .number = RPCStatus_FieldNumber_Code, + .hasIndex = 0, + .offset = (uint32_t)offsetof(RPCStatus__storage_, code), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeInt32, + }, + { + .name = "message", + .dataTypeSpecific.className = NULL, + .number = RPCStatus_FieldNumber_Message, + .hasIndex = 1, + .offset = (uint32_t)offsetof(RPCStatus__storage_, message), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeString, + }, + { + .name = "detailsArray", + .dataTypeSpecific.className = GPBStringifySymbol(GPBAny), + .number = RPCStatus_FieldNumber_DetailsArray, + .hasIndex = GPBNoHasBit, + .offset = (uint32_t)offsetof(RPCStatus__storage_, detailsArray), + .flags = GPBFieldRepeated, + .dataType = GPBDataTypeMessage, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[RPCStatus class] + rootClass:[RPCStatusRoot class] + file:RPCStatusRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(RPCStatus__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + + +#pragma clang diagnostic pop + +// @@protoc_insertion_point(global_scope) diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/objc/google/type/Latlng.pbobjc.h b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/objc/google/type/Latlng.pbobjc.h new file mode 100644 index 0000000..90dec0d --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/objc/google/type/Latlng.pbobjc.h @@ -0,0 +1,127 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/type/latlng.proto + +// This CPP symbol can be defined to use imports that match up to the framework +// imports needed when using CocoaPods. +#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) + #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 +#endif + +#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS + #import +#else + #import "GPBProtocolBuffers.h" +#endif + +#if GOOGLE_PROTOBUF_OBJC_VERSION < 30002 +#error This file was generated by a newer version of protoc which is incompatible with your Protocol Buffer library sources. +#endif +#if 30002 < GOOGLE_PROTOBUF_OBJC_MIN_SUPPORTED_VERSION +#error This file was generated by an older version of protoc which is incompatible with your Protocol Buffer library sources. +#endif + +// @@protoc_insertion_point(imports) + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + +CF_EXTERN_C_BEGIN + +NS_ASSUME_NONNULL_BEGIN + +#pragma mark - GTPLatlngRoot + +/** + * Exposes the extension registry for this file. + * + * The base class provides: + * @code + * + (GPBExtensionRegistry *)extensionRegistry; + * @endcode + * which is a @c GPBExtensionRegistry that includes all the extensions defined by + * this file and all files that it depends on. + **/ +@interface GTPLatlngRoot : GPBRootObject +@end + +#pragma mark - GTPLatLng + +typedef GPB_ENUM(GTPLatLng_FieldNumber) { + GTPLatLng_FieldNumber_Latitude = 1, + GTPLatLng_FieldNumber_Longitude = 2, +}; + +/** + * An object representing a latitude/longitude pair. This is expressed as a pair + * of doubles representing degrees latitude and degrees longitude. Unless + * specified otherwise, this must conform to the + * WGS84 + * standard. Values must be within normalized ranges. + * + * Example of normalization code in Python: + * + * def NormalizeLongitude(longitude): + * """Wraps decimal degrees longitude to [-180.0, 180.0].""" + * q, r = divmod(longitude, 360.0) + * if r > 180.0 or (r == 180.0 and q <= -1.0): + * return r - 360.0 + * return r + * + * def NormalizeLatLng(latitude, longitude): + * """Wraps decimal degrees latitude and longitude to + * [-90.0, 90.0] and [-180.0, 180.0], respectively.""" + * r = latitude % 360.0 + * if r <= 90.0: + * return r, NormalizeLongitude(longitude) + * elif r >= 270.0: + * return r - 360, NormalizeLongitude(longitude) + * else: + * return 180 - r, NormalizeLongitude(longitude + 180.0) + * + * assert 180.0 == NormalizeLongitude(180.0) + * assert -180.0 == NormalizeLongitude(-180.0) + * assert -179.0 == NormalizeLongitude(181.0) + * assert (0.0, 0.0) == NormalizeLatLng(360.0, 0.0) + * assert (0.0, 0.0) == NormalizeLatLng(-360.0, 0.0) + * assert (85.0, 180.0) == NormalizeLatLng(95.0, 0.0) + * assert (-85.0, -170.0) == NormalizeLatLng(-95.0, 10.0) + * assert (90.0, 10.0) == NormalizeLatLng(90.0, 10.0) + * assert (-90.0, -10.0) == NormalizeLatLng(-90.0, -10.0) + * assert (0.0, -170.0) == NormalizeLatLng(-180.0, 10.0) + * assert (0.0, -170.0) == NormalizeLatLng(180.0, 10.0) + * assert (-90.0, 10.0) == NormalizeLatLng(270.0, 10.0) + * assert (90.0, 10.0) == NormalizeLatLng(-270.0, 10.0) + **/ +@interface GTPLatLng : GPBMessage + +/** The latitude in degrees. It must be in the range [-90.0, +90.0]. */ +@property(nonatomic, readwrite) double latitude; + +/** The longitude in degrees. It must be in the range [-180.0, +180.0]. */ +@property(nonatomic, readwrite) double longitude; + +@end + +NS_ASSUME_NONNULL_END + +CF_EXTERN_C_END + +#pragma clang diagnostic pop + +// @@protoc_insertion_point(global_scope) diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/objc/google/type/Latlng.pbobjc.m b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/objc/google/type/Latlng.pbobjc.m new file mode 100644 index 0000000..337d16f --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Protos/objc/google/type/Latlng.pbobjc.m @@ -0,0 +1,119 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: google/type/latlng.proto + +// This CPP symbol can be defined to use imports that match up to the framework +// imports needed when using CocoaPods. +#if !defined(GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS) + #define GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS 0 +#endif + +#if GPB_USE_PROTOBUF_FRAMEWORK_IMPORTS + #import +#else + #import "GPBProtocolBuffers_RuntimeSupport.h" +#endif + + #import "Latlng.pbobjc.h" +// @@protoc_insertion_point(imports) + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-declarations" + +#pragma mark - GTPLatlngRoot + +@implementation GTPLatlngRoot + +// No extensions in the file and no imports, so no need to generate +// +extensionRegistry. + +@end + +#pragma mark - GTPLatlngRoot_FileDescriptor + +static GPBFileDescriptor *GTPLatlngRoot_FileDescriptor(void) { + // This is called by +initialize so there is no need to worry + // about thread safety of the singleton. + static GPBFileDescriptor *descriptor = NULL; + if (!descriptor) { + GPB_DEBUG_CHECK_RUNTIME_VERSIONS(); + descriptor = [[GPBFileDescriptor alloc] initWithPackage:@"google.type" + objcPrefix:@"GTP" + syntax:GPBFileSyntaxProto3]; + } + return descriptor; +} + +#pragma mark - GTPLatLng + +@implementation GTPLatLng + +@dynamic latitude; +@dynamic longitude; + +typedef struct GTPLatLng__storage_ { + uint32_t _has_storage_[1]; + double latitude; + double longitude; +} GTPLatLng__storage_; + +// This method is threadsafe because it is initially called +// in +initialize for each subclass. ++ (GPBDescriptor *)descriptor { + static GPBDescriptor *descriptor = nil; + if (!descriptor) { + static GPBMessageFieldDescription fields[] = { + { + .name = "latitude", + .dataTypeSpecific.className = NULL, + .number = GTPLatLng_FieldNumber_Latitude, + .hasIndex = 0, + .offset = (uint32_t)offsetof(GTPLatLng__storage_, latitude), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeDouble, + }, + { + .name = "longitude", + .dataTypeSpecific.className = NULL, + .number = GTPLatLng_FieldNumber_Longitude, + .hasIndex = 1, + .offset = (uint32_t)offsetof(GTPLatLng__storage_, longitude), + .flags = GPBFieldOptional, + .dataType = GPBDataTypeDouble, + }, + }; + GPBDescriptor *localDescriptor = + [GPBDescriptor allocDescriptorForClass:[GTPLatLng class] + rootClass:[GTPLatlngRoot class] + file:GTPLatlngRoot_FileDescriptor() + fields:fields + fieldCount:(uint32_t)(sizeof(fields) / sizeof(GPBMessageFieldDescription)) + storageSize:sizeof(GTPLatLng__storage_) + flags:GPBDescriptorInitializationFlag_None]; + NSAssert(descriptor == nil, @"Startup recursed!"); + descriptor = localDescriptor; + } + return descriptor; +} + +@end + + +#pragma clang diagnostic pop + +// @@protoc_insertion_point(global_scope) diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRCollectionReference+Internal.h b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRCollectionReference+Internal.h new file mode 100644 index 0000000..9d36ede --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRCollectionReference+Internal.h @@ -0,0 +1,29 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRCollectionReference.h" + +#include "Firestore/core/src/firebase/firestore/model/resource_path.h" + +NS_ASSUME_NONNULL_BEGIN + +/** Internal FIRCollectionReference API we don't want exposed in our public header files. */ +@interface FIRCollectionReference (Internal) ++ (instancetype)referenceWithPath:(const firebase::firestore::model::ResourcePath &)path + firestore:(FIRFirestore *)firestore; +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRCollectionReference.mm b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRCollectionReference.mm new file mode 100644 index 0000000..3156ef4 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRCollectionReference.mm @@ -0,0 +1,142 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRCollectionReference.h" + +#include + +#include "Firestore/core/src/firebase/firestore/util/autoid.h" + +#import "Firestore/Source/API/FIRDocumentReference+Internal.h" +#import "Firestore/Source/API/FIRFirestore+Internal.h" +#import "Firestore/Source/API/FIRQuery+Internal.h" +#import "Firestore/Source/API/FIRQuery_Init.h" +#import "Firestore/Source/Core/FSTQuery.h" +#import "Firestore/Source/Util/FSTUsageValidation.h" + +#include "Firestore/core/src/firebase/firestore/model/document_key.h" +#include "Firestore/core/src/firebase/firestore/model/resource_path.h" +#include "Firestore/core/src/firebase/firestore/util/string_apple.h" + +namespace util = firebase::firestore::util; +using firebase::firestore::model::DocumentKey; +using firebase::firestore::model::ResourcePath; +using firebase::firestore::util::CreateAutoId; + +NS_ASSUME_NONNULL_BEGIN + +@interface FIRCollectionReference () +- (instancetype)initWithPath:(const ResourcePath &)path + firestore:(FIRFirestore *)firestore NS_DESIGNATED_INITIALIZER; + +// Mark the super class designated initializer unavailable. +- (instancetype)initWithQuery:(FSTQuery *)query + firestore:(FIRFirestore *)firestore + __attribute__((unavailable("Use the initWithPath constructor of FIRCollectionReference."))); +@end + +@implementation FIRCollectionReference (Internal) ++ (instancetype)referenceWithPath:(const ResourcePath &)path firestore:(FIRFirestore *)firestore { + return [[FIRCollectionReference alloc] initWithPath:path firestore:firestore]; +} +@end + +@implementation FIRCollectionReference + +- (instancetype)initWithPath:(const ResourcePath &)path firestore:(FIRFirestore *)firestore { + if (path.size() % 2 != 1) { + FSTThrowInvalidArgument(@"Invalid collection reference. Collection references must have an odd " + "number of segments, but %s has %zu", + path.CanonicalString().c_str(), path.size()); + } + self = [super initWithQuery:[FSTQuery queryWithPath:path] firestore:firestore]; + return self; +} + +// Override the designated initializer from the super class. +- (instancetype)initWithQuery:(FSTQuery *)query firestore:(FIRFirestore *)firestore { + HARD_FAIL("Use FIRCollectionReference initWithPath: initializer."); +} + +// NSObject Methods +- (BOOL)isEqual:(nullable id)other { + if (other == self) return YES; + if (![[other class] isEqual:[self class]]) return NO; + + return [self isEqualToReference:other]; +} + +- (BOOL)isEqualToReference:(nullable FIRCollectionReference *)reference { + if (self == reference) return YES; + if (reference == nil) return NO; + return [self.firestore isEqual:reference.firestore] && [self.query isEqual:reference.query]; +} + +- (NSUInteger)hash { + NSUInteger hash = [self.firestore hash]; + hash = hash * 31u + [self.query hash]; + return hash; +} + +- (NSString *)collectionID { + return util::WrapNSString(self.query.path.last_segment()); +} + +- (FIRDocumentReference *_Nullable)parent { + const ResourcePath parentPath = self.query.path.PopLast(); + if (parentPath.empty()) { + return nil; + } else { + DocumentKey key{parentPath}; + return [[FIRDocumentReference alloc] initWithKey:std::move(key) + firestore:self.firestore.wrapped]; + } +} + +- (NSString *)path { + return util::WrapNSString(self.query.path.CanonicalString()); +} + +- (FIRDocumentReference *)documentWithPath:(NSString *)documentPath { + if (!documentPath) { + FSTThrowInvalidArgument(@"Document path cannot be nil."); + } + const ResourcePath subPath = ResourcePath::FromString(util::MakeString(documentPath)); + ResourcePath path = self.query.path.Append(subPath); + return [[FIRDocumentReference alloc] initWithPath:std::move(path) + firestore:self.firestore.wrapped]; +} + +- (FIRDocumentReference *)addDocumentWithData:(NSDictionary *)data { + return [self addDocumentWithData:data completion:nil]; +} + +- (FIRDocumentReference *)addDocumentWithData:(NSDictionary *)data + completion: + (nullable void (^)(NSError *_Nullable error))completion { + FIRDocumentReference *docRef = [self documentWithAutoID]; + [docRef setData:data completion:completion]; + return docRef; +} + +- (FIRDocumentReference *)documentWithAutoID { + DocumentKey key{self.query.path.Append(CreateAutoId())}; + return [[FIRDocumentReference alloc] initWithKey:std::move(key) firestore:self.firestore.wrapped]; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRDocumentChange+Internal.h b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRDocumentChange+Internal.h new file mode 100644 index 0000000..c1c2690 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRDocumentChange+Internal.h @@ -0,0 +1,37 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRDocumentChange.h" + +#include "Firestore/core/src/firebase/firestore/api/firestore.h" +#include "Firestore/core/src/firebase/firestore/core/view_snapshot.h" + +@class FIRFirestore; + +NS_ASSUME_NONNULL_BEGIN + +/** Internal FIRDocumentChange API we don't want exposed in our public header files. */ +@interface FIRDocumentChange (Internal) + +/** Calculates the array of FIRDocumentChange's based on the given FSTViewSnapshot. */ ++ (NSArray *) + documentChangesForSnapshot:(const firebase::firestore::core::ViewSnapshot &)snapshot + includeMetadataChanges:(bool)includeMetadataChanges + firestore:(firebase::firestore::api::Firestore *)firestore; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRDocumentChange.mm b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRDocumentChange.mm new file mode 100644 index 0000000..1a5bccd --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRDocumentChange.mm @@ -0,0 +1,162 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRDocumentChange.h" + +#import "Firestore/Source/API/FIRDocumentSnapshot+Internal.h" +#import "Firestore/Source/API/FIRFirestore+Internal.h" +#import "Firestore/Source/Core/FSTQuery.h" +#import "Firestore/Source/Model/FSTDocument.h" + +#include "Firestore/core/src/firebase/firestore/core/view_snapshot.h" +#include "Firestore/core/src/firebase/firestore/model/document_set.h" +#include "Firestore/core/src/firebase/firestore/util/hard_assert.h" + +using firebase::firestore::api::Firestore; +using firebase::firestore::core::DocumentViewChange; +using firebase::firestore::core::ViewSnapshot; +using firebase::firestore::model::DocumentSet; + +NS_ASSUME_NONNULL_BEGIN + +@interface FIRDocumentChange () + +- (instancetype)initWithType:(FIRDocumentChangeType)type + document:(FIRDocumentSnapshot *)document + oldIndex:(NSUInteger)oldIndex + newIndex:(NSUInteger)newIndex NS_DESIGNATED_INITIALIZER; + +@end + +@implementation FIRDocumentChange (Internal) + ++ (FIRDocumentChangeType)documentChangeTypeForChange:(const DocumentViewChange &)change { + switch (change.type()) { + case DocumentViewChange::Type::kAdded: + return FIRDocumentChangeTypeAdded; + case DocumentViewChange::Type::kModified: + case DocumentViewChange::Type::kMetadata: + return FIRDocumentChangeTypeModified; + case DocumentViewChange::Type::kRemoved: + return FIRDocumentChangeTypeRemoved; + } + + HARD_FAIL("Unknown DocumentViewChange::Type: %s", change.type()); +} + ++ (NSArray *)documentChangesForSnapshot:(const ViewSnapshot &)snapshot + includeMetadataChanges:(bool)includeMetadataChanges + firestore:(Firestore *)firestore { + if (snapshot.old_documents().empty()) { + // Special case the first snapshot because index calculation is easy and fast. Also all changes + // on the first snapshot are adds so there are also no metadata-only changes to filter out. + FSTDocument *_Nullable lastDocument = nil; + NSUInteger index = 0; + NSMutableArray *changes = [NSMutableArray array]; + for (const DocumentViewChange &change : snapshot.document_changes()) { + FIRQueryDocumentSnapshot *document = [[FIRQueryDocumentSnapshot alloc] + initWithFirestore:firestore + documentKey:change.document().key + document:change.document() + fromCache:snapshot.from_cache() + hasPendingWrites:snapshot.mutated_keys().contains(change.document().key)]; + HARD_ASSERT(change.type() == DocumentViewChange::Type::kAdded, + "Invalid event type for first snapshot"); + HARD_ASSERT(!lastDocument || snapshot.query().comparator(lastDocument, change.document()) == + NSOrderedAscending, + "Got added events in wrong order"); + [changes addObject:[[FIRDocumentChange alloc] initWithType:FIRDocumentChangeTypeAdded + document:document + oldIndex:NSNotFound + newIndex:index++]]; + } + return changes; + } else { + // A DocumentSet that is updated incrementally as changes are applied to use to lookup the index + // of a document. + DocumentSet indexTracker = snapshot.old_documents(); + NSMutableArray *changes = [NSMutableArray array]; + for (const DocumentViewChange &change : snapshot.document_changes()) { + if (!includeMetadataChanges && change.type() == DocumentViewChange::Type::kMetadata) { + continue; + } + + FIRQueryDocumentSnapshot *document = [[FIRQueryDocumentSnapshot alloc] + initWithFirestore:firestore + documentKey:change.document().key + document:change.document() + fromCache:snapshot.from_cache() + hasPendingWrites:snapshot.mutated_keys().contains(change.document().key)]; + + size_t oldIndex = DocumentSet::npos; + size_t newIndex = DocumentSet::npos; + if (change.type() != DocumentViewChange::Type::kAdded) { + oldIndex = indexTracker.IndexOf(change.document().key); + HARD_ASSERT(oldIndex != DocumentSet::npos, "Index for document not found"); + indexTracker = indexTracker.erase(change.document().key); + } + if (change.type() != DocumentViewChange::Type::kRemoved) { + indexTracker = indexTracker.insert(change.document()); + newIndex = indexTracker.IndexOf(change.document().key); + } + [FIRDocumentChange documentChangeTypeForChange:change]; + FIRDocumentChangeType type = [FIRDocumentChange documentChangeTypeForChange:change]; + [changes addObject:[[FIRDocumentChange alloc] initWithType:type + document:document + oldIndex:oldIndex + newIndex:newIndex]]; + } + return changes; + } +} + +@end + +@implementation FIRDocumentChange + +- (instancetype)initWithType:(FIRDocumentChangeType)type + document:(FIRQueryDocumentSnapshot *)document + oldIndex:(NSUInteger)oldIndex + newIndex:(NSUInteger)newIndex { + if (self = [super init]) { + _type = type; + _document = document; + _oldIndex = oldIndex; + _newIndex = newIndex; + } + return self; +} + +- (BOOL)isEqual:(nullable id)other { + if (other == self) return YES; + if (![other isKindOfClass:[FIRDocumentChange class]]) return NO; + + FIRDocumentChange *change = (FIRDocumentChange *)other; + return self.type == change.type && [self.document isEqual:change.document] && + self.oldIndex == change.oldIndex && self.newIndex == change.newIndex; +} + +- (NSUInteger)hash { + NSUInteger result = (NSUInteger)self.type; + result = result * 31u + [self.document hash]; + result = result * 31u + (NSUInteger)self.oldIndex; + result = result * 31u + (NSUInteger)self.newIndex; + return result; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRDocumentReference+Internal.h b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRDocumentReference+Internal.h new file mode 100644 index 0000000..aa12e97 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRDocumentReference+Internal.h @@ -0,0 +1,45 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRDocumentReference.h" + +#include "Firestore/core/src/firebase/firestore/api/document_reference.h" +#include "Firestore/core/src/firebase/firestore/model/document_key.h" +#include "Firestore/core/src/firebase/firestore/model/resource_path.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface FIRDocumentReference (/* Init */) + +- (instancetype)initWithReference:(firebase::firestore::api::DocumentReference &&)reference + NS_DESIGNATED_INITIALIZER; + +- (instancetype)initWithPath:(firebase::firestore::model::ResourcePath)path + firestore:(firebase::firestore::api::Firestore *)firestore; + +- (instancetype)initWithKey:(firebase::firestore::model::DocumentKey)key + firestore:(firebase::firestore::api::Firestore *)firestore; + +@end + +/** Internal FIRDocumentReference API we don't want exposed in our public header files. */ +@interface FIRDocumentReference (Internal) + +- (const firebase::firestore::model::DocumentKey &)key; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRDocumentReference.mm b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRDocumentReference.mm new file mode 100644 index 0000000..c1e838f --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRDocumentReference.mm @@ -0,0 +1,256 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRDocumentReference.h" + +#include +#include + +#import "FIRFirestoreErrors.h" +#import "FIRFirestoreSource.h" +#import "Firestore/Source/API/FIRCollectionReference+Internal.h" +#import "Firestore/Source/API/FIRDocumentReference+Internal.h" +#import "Firestore/Source/API/FIRDocumentSnapshot+Internal.h" +#import "Firestore/Source/API/FIRFirestore+Internal.h" +#import "Firestore/Source/API/FIRListenerRegistration+Internal.h" +#import "Firestore/Source/API/FSTUserDataConverter.h" +#import "Firestore/Source/Core/FSTEventManager.h" +#import "Firestore/Source/Core/FSTQuery.h" +#import "Firestore/Source/Model/FSTFieldValue.h" +#import "Firestore/Source/Util/FSTUsageValidation.h" + +#include "Firestore/core/src/firebase/firestore/api/document_reference.h" +#include "Firestore/core/src/firebase/firestore/api/document_snapshot.h" +#include "Firestore/core/src/firebase/firestore/core/event_listener.h" +#include "Firestore/core/src/firebase/firestore/model/document_key.h" +#include "Firestore/core/src/firebase/firestore/model/document_set.h" +#include "Firestore/core/src/firebase/firestore/model/precondition.h" +#include "Firestore/core/src/firebase/firestore/model/resource_path.h" +#include "Firestore/core/src/firebase/firestore/util/error_apple.h" +#include "Firestore/core/src/firebase/firestore/util/status.h" +#include "Firestore/core/src/firebase/firestore/util/statusor.h" +#include "Firestore/core/src/firebase/firestore/util/statusor_callback.h" +#include "Firestore/core/src/firebase/firestore/util/string_apple.h" + +namespace util = firebase::firestore::util; +using firebase::firestore::api::DocumentReference; +using firebase::firestore::api::DocumentSnapshot; +using firebase::firestore::api::Firestore; +using firebase::firestore::core::EventListener; +using firebase::firestore::core::ListenOptions; +using firebase::firestore::core::ParsedSetData; +using firebase::firestore::core::ParsedUpdateData; +using firebase::firestore::model::DocumentKey; +using firebase::firestore::model::Precondition; +using firebase::firestore::model::ResourcePath; +using firebase::firestore::util::Status; +using firebase::firestore::util::StatusOr; +using firebase::firestore::util::StatusOrCallback; + +NS_ASSUME_NONNULL_BEGIN + +#pragma mark - FIRDocumentReference + +@implementation FIRDocumentReference { + DocumentReference _documentReference; +} + +- (instancetype)initWithReference:(DocumentReference &&)reference { + if (self = [super init]) { + _documentReference = std::move(reference); + } + return self; +} + +- (instancetype)initWithPath:(ResourcePath)path firestore:(Firestore *)firestore { + if (path.size() % 2 != 0) { + FSTThrowInvalidArgument(@"Invalid document reference. Document references must have an even " + "number of segments, but %s has %zu", + path.CanonicalString().c_str(), path.size()); + } + return [self initWithKey:DocumentKey{std::move(path)} firestore:firestore]; +} + +- (instancetype)initWithKey:(DocumentKey)key firestore:(Firestore *)firestore { + DocumentReference delegate{std::move(key), firestore}; + return [self initWithReference:std::move(delegate)]; +} + +#pragma mark - NSObject Methods + +- (BOOL)isEqual:(nullable id)other { + if (other == self) return YES; + if (![[other class] isEqual:[self class]]) return NO; + + return _documentReference == static_cast(other)->_documentReference; +} + +- (NSUInteger)hash { + return _documentReference.Hash(); +} + +#pragma mark - Public Methods + +@dynamic firestore; + +- (FIRFirestore *)firestore { + return [FIRFirestore recoverFromFirestore:_documentReference.firestore()]; +} + +- (NSString *)documentID { + return util::WrapNSString(_documentReference.document_id()); +} + +- (FIRCollectionReference *)parent { + return [FIRCollectionReference referenceWithPath:_documentReference.key().path().PopLast() + firestore:self.firestore]; +} + +- (NSString *)path { + return util::WrapNSString(_documentReference.Path()); +} + +- (FIRCollectionReference *)collectionWithPath:(NSString *)collectionPath { + if (!collectionPath) { + FSTThrowInvalidArgument(@"Collection path cannot be nil."); + } + + ResourcePath subPath = ResourcePath::FromString(util::MakeString(collectionPath)); + ResourcePath path = _documentReference.key().path().Append(subPath); + return [FIRCollectionReference referenceWithPath:path firestore:self.firestore]; +} + +- (void)setData:(NSDictionary *)documentData { + [self setData:documentData merge:NO completion:nil]; +} + +- (void)setData:(NSDictionary *)documentData merge:(BOOL)merge { + [self setData:documentData merge:merge completion:nil]; +} + +- (void)setData:(NSDictionary *)documentData + mergeFields:(NSArray *)mergeFields { + [self setData:documentData mergeFields:mergeFields completion:nil]; +} + +- (void)setData:(NSDictionary *)documentData + completion:(nullable void (^)(NSError *_Nullable error))completion { + [self setData:documentData merge:NO completion:completion]; +} + +- (void)setData:(NSDictionary *)documentData + merge:(BOOL)merge + completion:(nullable void (^)(NSError *_Nullable error))completion { + auto dataConverter = self.firestore.dataConverter; + ParsedSetData parsed = merge ? [dataConverter parsedMergeData:documentData fieldMask:nil] + : [dataConverter parsedSetData:documentData]; + _documentReference.SetData( + std::move(parsed).ToMutations(_documentReference.key(), Precondition::None()), completion); +} + +- (void)setData:(NSDictionary *)documentData + mergeFields:(NSArray *)mergeFields + completion:(nullable void (^)(NSError *_Nullable error))completion { + ParsedSetData parsed = [self.firestore.dataConverter parsedMergeData:documentData + fieldMask:mergeFields]; + _documentReference.SetData( + std::move(parsed).ToMutations(_documentReference.key(), Precondition::None()), completion); +} + +- (void)updateData:(NSDictionary *)fields { + [self updateData:fields completion:nil]; +} + +- (void)updateData:(NSDictionary *)fields + completion:(nullable void (^)(NSError *_Nullable error))completion { + ParsedUpdateData parsed = [self.firestore.dataConverter parsedUpdateData:fields]; + _documentReference.UpdateData( + std::move(parsed).ToMutations(_documentReference.key(), Precondition::Exists(true)), + completion); +} + +- (void)deleteDocument { + [self deleteDocumentWithCompletion:nil]; +} + +- (void)deleteDocumentWithCompletion:(nullable void (^)(NSError *_Nullable error))completion { + _documentReference.DeleteDocument(completion); +} + +- (void)getDocumentWithCompletion:(FIRDocumentSnapshotBlock)completion { + _documentReference.GetDocument(FIRFirestoreSourceDefault, + [self wrapDocumentSnapshotBlock:completion]); +} + +- (void)getDocumentWithSource:(FIRFirestoreSource)source + completion:(FIRDocumentSnapshotBlock)completion { + _documentReference.GetDocument(source, [self wrapDocumentSnapshotBlock:completion]); +} + +- (id)addSnapshotListener:(FIRDocumentSnapshotBlock)listener { + return [self addSnapshotListenerWithIncludeMetadataChanges:NO listener:listener]; +} + +- (id) + addSnapshotListenerWithIncludeMetadataChanges:(BOOL)includeMetadataChanges + listener:(FIRDocumentSnapshotBlock)listener { + ListenOptions options = ListenOptions::FromIncludeMetadataChanges(includeMetadataChanges); + return [self addSnapshotListenerInternalWithOptions:options listener:listener]; +} + +- (id)addSnapshotListenerInternalWithOptions:(ListenOptions)internalOptions + listener:(FIRDocumentSnapshotBlock) + listener { + ListenerRegistration result = _documentReference.AddSnapshotListener( + std::move(internalOptions), [self wrapDocumentSnapshotBlock:listener]); + return [[FSTListenerRegistration alloc] initWithRegistration:std::move(result)]; +} + +- (DocumentSnapshot::Listener)wrapDocumentSnapshotBlock:(FIRDocumentSnapshotBlock)block { + class Converter : public EventListener { + public: + explicit Converter(FIRDocumentSnapshotBlock block) : block_(block) { + } + + void OnEvent(StatusOr maybe_snapshot) override { + if (maybe_snapshot.ok()) { + FIRDocumentSnapshot *result = + [[FIRDocumentSnapshot alloc] initWithSnapshot:std::move(maybe_snapshot).ValueOrDie()]; + block_(result, nil); + } else { + block_(nil, util::MakeNSError(maybe_snapshot.status())); + } + } + + private: + FIRDocumentSnapshotBlock block_; + }; + return absl::make_unique(block); +} + +@end + +#pragma mark - FIRDocumentReference (Internal) + +@implementation FIRDocumentReference (Internal) + +- (const DocumentKey &)key { + return _documentReference.key(); +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRDocumentSnapshot+Internal.h b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRDocumentSnapshot+Internal.h new file mode 100644 index 0000000..b371b6a --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRDocumentSnapshot+Internal.h @@ -0,0 +1,57 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRDocumentSnapshot.h" + +#include "Firestore/core/src/firebase/firestore/api/document_snapshot.h" +#include "Firestore/core/src/firebase/firestore/api/snapshot_metadata.h" +#include "Firestore/core/src/firebase/firestore/model/document_key.h" + +@class FIRFirestore; +@class FSTDocument; + +using firebase::firestore::api::DocumentSnapshot; +using firebase::firestore::api::Firestore; +using firebase::firestore::api::SnapshotMetadata; +using firebase::firestore::model::DocumentKey; + +NS_ASSUME_NONNULL_BEGIN + +@interface FIRDocumentSnapshot (/* Init */) + +- (instancetype)initWithSnapshot:(DocumentSnapshot &&)snapshot NS_DESIGNATED_INITIALIZER; + +- (instancetype)initWithFirestore:(Firestore *)firestore + documentKey:(DocumentKey)documentKey + document:(nullable FSTDocument *)document + metadata:(SnapshotMetadata)metadata; + +- (instancetype)initWithFirestore:(Firestore *)firestore + documentKey:(DocumentKey)documentKey + document:(nullable FSTDocument *)document + fromCache:(bool)fromCache + hasPendingWrites:(bool)hasPendingWrites; + +@end + +/** Internal FIRDocumentSnapshot API we don't want exposed in our public header files. */ +@interface FIRDocumentSnapshot (Internal) + +@property(nonatomic, strong, readonly, nullable) FSTDocument *internalDocument; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRDocumentSnapshot.mm b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRDocumentSnapshot.mm new file mode 100644 index 0000000..eb210d9 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRDocumentSnapshot.mm @@ -0,0 +1,252 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRDocumentSnapshot.h" + +#include + +#include "Firestore/core/src/firebase/firestore/util/warnings.h" + +#import "FIRFirestoreSettings.h" + +#import "Firestore/Source/API/FIRDocumentReference+Internal.h" +#import "Firestore/Source/API/FIRFieldPath+Internal.h" +#import "Firestore/Source/API/FIRFirestore+Internal.h" +#import "Firestore/Source/API/FIRSnapshotMetadata+Internal.h" +#import "Firestore/Source/Model/FSTDocument.h" +#import "Firestore/Source/Model/FSTFieldValue.h" +#import "Firestore/Source/Util/FSTUsageValidation.h" + +#include "Firestore/core/src/firebase/firestore/api/document_snapshot.h" +#include "Firestore/core/src/firebase/firestore/api/firestore.h" +#include "Firestore/core/src/firebase/firestore/model/database_id.h" +#include "Firestore/core/src/firebase/firestore/model/document_key.h" +#include "Firestore/core/src/firebase/firestore/util/hard_assert.h" +#include "Firestore/core/src/firebase/firestore/util/string_apple.h" + +namespace util = firebase::firestore::util; +using firebase::firestore::api::DocumentSnapshot; +using firebase::firestore::api::Firestore; +using firebase::firestore::model::DatabaseId; +using firebase::firestore::model::DocumentKey; +using firebase::firestore::util::WrapNSString; + +NS_ASSUME_NONNULL_BEGIN + +namespace { + +/** + * Converts a public FIRServerTimestampBehavior into its internal equivalent. + */ +ServerTimestampBehavior InternalServerTimestampBehavior(FIRServerTimestampBehavior behavior) { + switch (behavior) { + case FIRServerTimestampBehaviorNone: + return ServerTimestampBehavior::None; + case FIRServerTimestampBehaviorEstimate: + return ServerTimestampBehavior::Estimate; + case FIRServerTimestampBehaviorPrevious: + return ServerTimestampBehavior::Previous; + default: + HARD_FAIL("Unexpected server timestamp option: %s", behavior); + } +} + +} // namespace + +@implementation FIRDocumentSnapshot { + DocumentSnapshot _snapshot; + + FIRSnapshotMetadata *_cachedMetadata; +} + +- (instancetype)initWithSnapshot:(DocumentSnapshot &&)snapshot { + if (self = [super init]) { + _snapshot = std::move(snapshot); + } + return self; +} + +- (instancetype)initWithFirestore:(Firestore *)firestore + documentKey:(DocumentKey)documentKey + document:(nullable FSTDocument *)document + metadata:(SnapshotMetadata)metadata { + DocumentSnapshot wrapped{firestore, std::move(documentKey), document, std::move(metadata)}; + return [self initWithSnapshot:std::move(wrapped)]; +} + +- (instancetype)initWithFirestore:(Firestore *)firestore + documentKey:(DocumentKey)documentKey + document:(nullable FSTDocument *)document + fromCache:(bool)fromCache + hasPendingWrites:(bool)hasPendingWrites { + return [self initWithFirestore:firestore + documentKey:std::move(documentKey) + document:document + metadata:SnapshotMetadata(hasPendingWrites, fromCache)]; +} + +// NSObject Methods +- (BOOL)isEqual:(nullable id)other { + if (other == self) return YES; + // self class could be FIRDocumentSnapshot or subtype. So we compare with base type explicitly. + if (![other isKindOfClass:[FIRDocumentSnapshot class]]) return NO; + + return _snapshot == static_cast(other)->_snapshot; +} + +- (NSUInteger)hash { + return _snapshot.Hash(); +} + +@dynamic exists; + +- (BOOL)exists { + return _snapshot.exists(); +} + +- (FSTDocument *)internalDocument { + return _snapshot.internal_document(); +} + +- (FIRDocumentReference *)reference { + return [[FIRDocumentReference alloc] initWithReference:_snapshot.CreateReference()]; +} + +- (NSString *)documentID { + return WrapNSString(_snapshot.document_id()); +} + +@dynamic metadata; + +- (FIRSnapshotMetadata *)metadata { + if (!_cachedMetadata) { + _cachedMetadata = [[FIRSnapshotMetadata alloc] initWithMetadata:_snapshot.metadata()]; + } + return _cachedMetadata; +} + +- (nullable NSDictionary *)data { + return [self dataWithServerTimestampBehavior:FIRServerTimestampBehaviorNone]; +} + +- (nullable NSDictionary *)dataWithServerTimestampBehavior: + (FIRServerTimestampBehavior)serverTimestampBehavior { + FSTFieldValueOptions *options = [self optionsForServerTimestampBehavior:serverTimestampBehavior]; + FSTObjectValue *data = _snapshot.GetData(); + return data == nil ? nil : [self convertedObject:data options:options]; +} + +- (nullable id)valueForField:(id)field { + return [self valueForField:field serverTimestampBehavior:FIRServerTimestampBehaviorNone]; +} + +- (nullable id)valueForField:(id)field + serverTimestampBehavior:(FIRServerTimestampBehavior)serverTimestampBehavior { + FIRFieldPath *fieldPath; + if ([field isKindOfClass:[NSString class]]) { + fieldPath = [FIRFieldPath pathWithDotSeparatedString:field]; + } else if ([field isKindOfClass:[FIRFieldPath class]]) { + fieldPath = field; + } else { + FSTThrowInvalidArgument(@"Subscript key must be an NSString or FIRFieldPath."); + } + + FSTFieldValue *fieldValue = _snapshot.GetValue(fieldPath.internalValue); + FSTFieldValueOptions *options = [self optionsForServerTimestampBehavior:serverTimestampBehavior]; + return fieldValue == nil ? nil : [self convertedValue:fieldValue options:options]; +} + +- (nullable id)objectForKeyedSubscript:(id)key { + return [self valueForField:key]; +} + +- (FSTFieldValueOptions *)optionsForServerTimestampBehavior: + (FIRServerTimestampBehavior)serverTimestampBehavior { + SUPPRESS_DEPRECATED_DECLARATIONS_BEGIN() + return [[FSTFieldValueOptions alloc] + initWithServerTimestampBehavior:InternalServerTimestampBehavior(serverTimestampBehavior) + timestampsInSnapshotsEnabled:_snapshot.firestore() + ->settings() + .timestampsInSnapshotsEnabled]; + SUPPRESS_END() +} + +- (id)convertedValue:(FSTFieldValue *)value options:(FSTFieldValueOptions *)options { + if ([value isKindOfClass:[FSTObjectValue class]]) { + return [self convertedObject:(FSTObjectValue *)value options:options]; + } else if ([value isKindOfClass:[FSTArrayValue class]]) { + return [self convertedArray:(FSTArrayValue *)value options:options]; + } else if ([value isKindOfClass:[FSTReferenceValue class]]) { + FSTReferenceValue *ref = (FSTReferenceValue *)value; + const DatabaseId *refDatabase = ref.databaseID; + const DatabaseId *database = &_snapshot.firestore()->database_id(); + if (*refDatabase != *database) { + // TODO(b/32073923): Log this as a proper warning. + NSLog(@"WARNING: Document %@ contains a document reference within a different database " + "(%s/%s) which is not supported. It will be treated as a reference within the " + "current database (%s/%s) instead.", + self.reference.path, refDatabase->project_id().c_str(), + refDatabase->database_id().c_str(), database->project_id().c_str(), + database->database_id().c_str()); + } + DocumentKey key = [[ref valueWithOptions:options] key]; + return [[FIRDocumentReference alloc] initWithKey:key firestore:_snapshot.firestore()]; + } else { + return [value valueWithOptions:options]; + } +} + +- (NSDictionary *)convertedObject:(FSTObjectValue *)objectValue + options:(FSTFieldValueOptions *)options { + NSMutableDictionary *result = [NSMutableDictionary dictionary]; + [objectValue.internalValue + enumerateKeysAndObjectsUsingBlock:^(NSString *key, FSTFieldValue *value, BOOL *stop) { + result[key] = [self convertedValue:value options:options]; + }]; + return result; +} + +- (NSArray *)convertedArray:(FSTArrayValue *)arrayValue + options:(FSTFieldValueOptions *)options { + NSArray *internalValue = arrayValue.internalValue; + NSMutableArray *result = [NSMutableArray arrayWithCapacity:internalValue.count]; + [internalValue enumerateObjectsUsingBlock:^(id value, NSUInteger idx, BOOL *stop) { + [result addObject:[self convertedValue:value options:options]]; + }]; + return result; +} + +@end + +@implementation FIRQueryDocumentSnapshot + +- (NSDictionary *)data { + NSDictionary *data = [super data]; + HARD_ASSERT(data, "Document in a QueryDocumentSnapshot should exist"); + return data; +} + +- (NSDictionary *)dataWithServerTimestampBehavior: + (FIRServerTimestampBehavior)serverTimestampBehavior { + NSDictionary *data = + [super dataWithServerTimestampBehavior:serverTimestampBehavior]; + HARD_ASSERT(data, "Document in a QueryDocumentSnapshot should exist"); + return data; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRFieldPath+Internal.h b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRFieldPath+Internal.h new file mode 100644 index 0000000..6fb6add --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRFieldPath+Internal.h @@ -0,0 +1,39 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRFieldPath.h" + +#include "Firestore/core/src/firebase/firestore/model/field_path.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface FIRFieldPath () + +/** Internal field path representation */ +- (const firebase::firestore::model::FieldPath &)internalValue; + +- (instancetype)initPrivate:(firebase::firestore::model::FieldPath)path NS_DESIGNATED_INITIALIZER; + +@end + +/** Internal FIRFieldPath API we don't want exposed in our public header files. */ +@interface FIRFieldPath (Internal) + ++ (instancetype)pathWithDotSeparatedString:(NSString *)path; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRFieldPath.mm b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRFieldPath.mm new file mode 100644 index 0000000..68f3de1 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRFieldPath.mm @@ -0,0 +1,127 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRFieldPath.h" + +#include +#include +#include +#include + +#import "Firestore/Source/API/FIRFieldPath+Internal.h" +#import "Firestore/Source/Util/FSTUsageValidation.h" + +#include "Firestore/core/src/firebase/firestore/model/field_path.h" +#include "Firestore/core/src/firebase/firestore/util/hashing.h" +#include "Firestore/core/src/firebase/firestore/util/string_apple.h" + +namespace util = firebase::firestore::util; +using firebase::firestore::model::FieldPath; + +NS_ASSUME_NONNULL_BEGIN + +@interface FIRFieldPath () { + /** Internal field path representation */ + firebase::firestore::model::FieldPath _internalValue; +} + +@end + +@implementation FIRFieldPath + +- (instancetype)initWithFields:(NSArray *)fieldNames { + if (fieldNames.count == 0) { + FSTThrowInvalidArgument(@"Invalid field path. Provided names must not be empty."); + } + + std::vector field_names; + field_names.reserve(fieldNames.count); + for (int i = 0; i < fieldNames.count; ++i) { + if (fieldNames[i].length == 0) { + FSTThrowInvalidArgument(@"Invalid field name at index %d. Field names must not be empty.", i); + } + field_names.emplace_back(util::MakeString(fieldNames[i])); + } + + return [self initPrivate:FieldPath(std::move(field_names))]; +} + ++ (instancetype)documentID { + return [[FIRFieldPath alloc] initPrivate:FieldPath::KeyFieldPath()]; +} + +- (instancetype)initPrivate:(FieldPath)fieldPath { + if (self = [super init]) { + _internalValue = std::move(fieldPath); + } + return self; +} + ++ (instancetype)pathWithDotSeparatedString:(NSString *)path { + if ([[FIRFieldPath reservedCharactersRegex] + numberOfMatchesInString:path + options:0 + range:NSMakeRange(0, path.length)] > 0) { + FSTThrowInvalidArgument( + @"Invalid field path (%@). Paths must not contain '~', '*', '/', '[', or ']'", path); + } + @try { + return [[FIRFieldPath alloc] initWithFields:[path componentsSeparatedByString:@"."]]; + } @catch (NSException *exception) { + FSTThrowInvalidArgument( + @"Invalid field path (%@). Paths must not be empty, begin with '.', end with '.', or " + @"contain '..'", + path); + } +} + +/** Matches any characters in a field path string that are reserved. */ ++ (NSRegularExpression *)reservedCharactersRegex { + static NSRegularExpression *regex = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + regex = [NSRegularExpression regularExpressionWithPattern:@"[~*/\\[\\]]" options:0 error:nil]; + }); + return regex; +} + +- (id)copyWithZone:(NSZone *__nullable)zone { + return [[[self class] alloc] initPrivate:_internalValue]; +} + +- (BOOL)isEqual:(nullable id)object { + if (self == object) { + return YES; + } + + if (![object isKindOfClass:[FIRFieldPath class]]) { + return NO; + } + + return _internalValue == ((FIRFieldPath *)object)->_internalValue; +} + +- (NSUInteger)hash { + return util::Hash(_internalValue); +} + +- (const firebase::firestore::model::FieldPath &)internalValue { + return _internalValue; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRFieldValue+Internal.h b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRFieldValue+Internal.h new file mode 100644 index 0000000..7e0193d --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRFieldValue+Internal.h @@ -0,0 +1,63 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRFieldValue.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface FIRFieldValue (Internal) +/** + * The method name (e.g. "FieldValue.delete()") that was used to create this FIRFieldValue + * instance, for use in error messages, etc. + */ +@property(nonatomic, strong, readonly) NSString *methodName; +@end + +/** + * FIRFieldValue class for field deletes. Exposed internally so code can do isKindOfClass checks on + * it. + */ +@interface FSTDeleteFieldValue : FIRFieldValue +- (instancetype)init NS_UNAVAILABLE; +@end + +/** + * FIRFieldValue class for server timestamps. Exposed internally so code can do isKindOfClass checks + * on it. + */ +@interface FSTServerTimestampFieldValue : FIRFieldValue +- (instancetype)init NS_UNAVAILABLE; +@end + +/** FIRFieldValue class for array unions. */ +@interface FSTArrayUnionFieldValue : FIRFieldValue +- (instancetype)init NS_UNAVAILABLE; +@property(strong, nonatomic, readonly) NSArray *elements; +@end + +/** FIRFieldValue class for array removes. */ +@interface FSTArrayRemoveFieldValue : FIRFieldValue +- (instancetype)init NS_UNAVAILABLE; +@property(strong, nonatomic, readonly) NSArray *elements; +@end + +/** FIRFieldValue class for number increments. */ +@interface FSTNumericIncrementFieldValue : FIRFieldValue +- (instancetype)init NS_UNAVAILABLE; +@property(strong, nonatomic, readonly) NSNumber *operand; +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRFieldValue.mm b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRFieldValue.mm new file mode 100644 index 0000000..884b187 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRFieldValue.mm @@ -0,0 +1,182 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "Firestore/Source/API/FIRFieldValue+Internal.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface FIRFieldValue () +- (instancetype)initPrivate NS_DESIGNATED_INITIALIZER; +@end + +#pragma mark - FSTDeleteFieldValue + +@interface FSTDeleteFieldValue () +/** Returns a single shared instance of the class. */ ++ (instancetype)deleteFieldValue; +@end + +@implementation FSTDeleteFieldValue + +- (instancetype)initPrivate { + self = [super initPrivate]; + return self; +} + ++ (instancetype)deleteFieldValue { + static FSTDeleteFieldValue *sharedInstance = nil; + static dispatch_once_t onceToken; + + dispatch_once(&onceToken, ^{ + sharedInstance = [[FSTDeleteFieldValue alloc] initPrivate]; + }); + return sharedInstance; +} + +- (NSString *)methodName { + return @"FieldValue.delete()"; +} + +@end + +#pragma mark - FSTServerTimestampFieldValue + +@interface FSTServerTimestampFieldValue () +/** Returns a single shared instance of the class. */ ++ (instancetype)serverTimestampFieldValue; +@end + +@implementation FSTServerTimestampFieldValue + +- (instancetype)initPrivate { + self = [super initPrivate]; + return self; +} + ++ (instancetype)serverTimestampFieldValue { + static FSTServerTimestampFieldValue *sharedInstance = nil; + static dispatch_once_t onceToken; + + dispatch_once(&onceToken, ^{ + sharedInstance = [[FSTServerTimestampFieldValue alloc] initPrivate]; + }); + return sharedInstance; +} + +- (NSString *)methodName { + return @"FieldValue.serverTimestamp()"; +} + +@end + +#pragma mark - FSTArrayUnionFieldValue + +@interface FSTArrayUnionFieldValue () +- (instancetype)initWithElements:(NSArray *)elements; +@end + +@implementation FSTArrayUnionFieldValue +- (instancetype)initWithElements:(NSArray *)elements { + if (self = [super initPrivate]) { + _elements = elements; + } + return self; +} + +- (NSString *)methodName { + return @"FieldValue.arrayUnion()"; +} + +@end + +#pragma mark - FSTArrayRemoveFieldValue + +@interface FSTArrayRemoveFieldValue () +- (instancetype)initWithElements:(NSArray *)elements; +@end + +@implementation FSTArrayRemoveFieldValue +- (instancetype)initWithElements:(NSArray *)elements { + if (self = [super initPrivate]) { + _elements = elements; + } + return self; +} + +- (NSString *)methodName { + return @"FieldValue.arrayRemove()"; +} + +@end + +#pragma mark - FSTNumericIncrementFieldValue + +/* FieldValue class for increment() transforms. */ +@interface FSTNumericIncrementFieldValue () +- (instancetype)initWithOperand:(NSNumber *)operand; +@end + +@implementation FSTNumericIncrementFieldValue +- (instancetype)initWithOperand:(NSNumber *)operand; +{ + if (self = [super initPrivate]) { + _operand = operand; + } + return self; +} + +- (NSString *)methodName { + return @"FieldValue.increment()"; +} + +@end + +#pragma mark - FIRFieldValue + +@implementation FIRFieldValue + +- (instancetype)initPrivate { + self = [super init]; + return self; +} + ++ (instancetype)fieldValueForDelete { + return [FSTDeleteFieldValue deleteFieldValue]; +} + ++ (instancetype)fieldValueForServerTimestamp { + return [FSTServerTimestampFieldValue serverTimestampFieldValue]; +} + ++ (instancetype)fieldValueForArrayUnion:(NSArray *)elements { + return [[FSTArrayUnionFieldValue alloc] initWithElements:elements]; +} + ++ (instancetype)fieldValueForArrayRemove:(NSArray *)elements { + return [[FSTArrayRemoveFieldValue alloc] initWithElements:elements]; +} + ++ (instancetype)fieldValueForDoubleIncrement:(double)d { + return [[FSTNumericIncrementFieldValue alloc] initWithOperand:@(d)]; +} + ++ (instancetype)fieldValueForIntegerIncrement:(int64_t)l { + return [[FSTNumericIncrementFieldValue alloc] initWithOperand:@(l)]; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRFirestore+Internal.h b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRFirestore+Internal.h new file mode 100644 index 0000000..06d5b7d --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRFirestore+Internal.h @@ -0,0 +1,89 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRFirestore.h" + +#include +#include + +#include "Firestore/core/src/firebase/firestore/api/firestore.h" +#include "Firestore/core/src/firebase/firestore/auth/credentials_provider.h" +#include "Firestore/core/src/firebase/firestore/util/async_queue.h" + +NS_ASSUME_NONNULL_BEGIN + +@class FIRApp; +@class FSTFirestoreClient; +@class FSTUserDataConverter; + +@interface FIRFirestore (/* Init */) + +/** + * Initializes a Firestore object with all the required parameters directly. This exists so that + * tests can create FIRFirestore objects without needing FIRApp. + */ +- (instancetype) + initWithProjectID:(std::string)projectID + database:(std::string)database + persistenceKey:(std::string)persistenceKey + credentialsProvider: + (std::unique_ptr)credentialsProvider + workerQueue:(std::unique_ptr)workerQueue + firebaseApp:(FIRApp *)app; +@end + +/** Internal FIRFirestore API we don't want exposed in our public header files. */ +@interface FIRFirestore (Internal) + +// TODO(b/116617988): Move this to FIRFirestore.h and update CHANGELOG.md once backend support is +// ready. +#pragma mark - Collection Group Queries +/** + * Creates and returns a new `Query` that includes all documents in the database that are contained + * in a collection or subcollection with the given collectionID. + * + * @param collectionID Identifies the collections to query over. Every collection or subcollection + * with this ID as the last segment of its path will be included. Cannot contain a slash. + * @return The created `Query`. + */ +- (FIRQuery *)collectionGroupWithID:(NSString *)collectionID NS_SWIFT_NAME(collectionGroup(_:)); + +/** Checks to see if logging is is globally enabled for the Firestore client. */ ++ (BOOL)isLoggingEnabled; + ++ (FIRFirestore *)recoverFromFirestore:(firebase::firestore::api::Firestore *)firestore; + +/** + * Shutdown this `FIRFirestore`, releasing all resources (abandoning any outstanding writes, + * removing all listens, closing all network connections, etc.). + * + * @param completion A block to execute once everything has shut down. + */ +- (void)shutdownWithCompletion:(nullable void (^)(NSError *_Nullable error))completion + NS_SWIFT_NAME(shutdown(completion:)); + +@property(nonatomic, assign, readonly) firebase::firestore::api::Firestore *wrapped; + +@property(nonatomic, assign, readonly) firebase::firestore::util::AsyncQueue *workerQueue; + +// FIRFirestore ownes the DatabaseId instance. +@property(nonatomic, assign, readonly) const firebase::firestore::model::DatabaseId *databaseID; +@property(nonatomic, strong, readonly) FSTFirestoreClient *client; +@property(nonatomic, strong, readonly) FSTUserDataConverter *dataConverter; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRFirestore.mm b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRFirestore.mm new file mode 100644 index 0000000..e4761b1 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRFirestore.mm @@ -0,0 +1,294 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRFirestore.h" + +#import +#import +#import +#import +#import + +#include +#include +#include + +#import "FIRFirestore.h" + +#import "Firestore/Source/API/FIRDocumentReference+Internal.h" +#import "Firestore/Source/API/FIRFirestore+Internal.h" +#import "Firestore/Source/API/FSTFirestoreComponent.h" +#import "Firestore/Source/API/FSTUserDataConverter.h" +#import "Firestore/Source/Util/FSTUsageValidation.h" + +#include "Firestore/core/src/firebase/firestore/api/firestore.h" +#include "Firestore/core/src/firebase/firestore/auth/credentials_provider.h" +#include "Firestore/core/src/firebase/firestore/core/database_info.h" +#include "Firestore/core/src/firebase/firestore/model/database_id.h" +#include "Firestore/core/src/firebase/firestore/util/async_queue.h" +#include "Firestore/core/src/firebase/firestore/util/delayed_constructor.h" +#include "Firestore/core/src/firebase/firestore/util/log.h" +#include "Firestore/core/src/firebase/firestore/util/string_apple.h" + +namespace util = firebase::firestore::util; +using firebase::firestore::api::DocumentReference; +using firebase::firestore::api::Firestore; +using firebase::firestore::auth::CredentialsProvider; +using firebase::firestore::model::DatabaseId; +using firebase::firestore::util::AsyncQueue; +using firebase::firestore::util::DelayedConstructor; + +NS_ASSUME_NONNULL_BEGIN + +extern "C" NSString *const FIRFirestoreErrorDomain = @"FIRFirestoreErrorDomain"; + +#pragma mark - FIRFirestore + +@interface FIRFirestore () + +@property(nonatomic, strong, readonly) FSTUserDataConverter *dataConverter; + +@end + +@implementation FIRFirestore { + DelayedConstructor _firestore; +} + ++ (NSMutableDictionary *)instances { + static dispatch_once_t token = 0; + static NSMutableDictionary *instances; + dispatch_once(&token, ^{ + instances = [NSMutableDictionary dictionary]; + }); + return instances; +} + ++ (void)initialize { + NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; + [center addObserverForName:kFIRAppDeleteNotification + object:nil + queue:nil + usingBlock:^(NSNotification *_Nonnull note) { + NSString *appName = note.userInfo[kFIRAppNameKey]; + if (appName == nil) return; + + NSMutableDictionary *instances = [self instances]; + @synchronized(instances) { + // Since the key for instances isn't just the app name, iterate over all the + // keys to get the one(s) we have to delete. There could be multiple in case + // the user calls firestoreForApp:database:. + NSMutableArray *keysToDelete = [[NSMutableArray alloc] init]; + NSString *keyPrefix = [NSString stringWithFormat:@"%@|", appName]; + for (NSString *key in instances.allKeys) { + if ([key hasPrefix:keyPrefix]) { + [keysToDelete addObject:key]; + } + } + + // Loop through the keys found and delete them from the stored instances. + for (NSString *key in keysToDelete) { + [instances removeObjectForKey:key]; + } + } + }]; +} + ++ (instancetype)firestore { + FIRApp *app = [FIRApp defaultApp]; + if (!app) { + FSTThrowInvalidUsage(@"FIRAppNotConfiguredException", + @"Failed to get FirebaseApp instance. Please call FirebaseApp.configure() " + @"before using Firestore"); + } + return [self firestoreForApp:app database:util::WrapNSString(DatabaseId::kDefault)]; +} + ++ (instancetype)firestoreForApp:(FIRApp *)app { + return [self firestoreForApp:app database:util::WrapNSString(DatabaseId::kDefault)]; +} + +// TODO(b/62410906): make this public ++ (instancetype)firestoreForApp:(FIRApp *)app database:(NSString *)database { + if (!app) { + FSTThrowInvalidArgument(@"FirebaseApp instance may not be nil. Use FirebaseApp.app() if you'd " + "like to use the default FirebaseApp instance."); + } + if (!database) { + FSTThrowInvalidArgument(@"database identifier may not be nil. Use '%s' if you want the default " + "database", + DatabaseId::kDefault); + } + + id provider = + FIR_COMPONENT(FSTFirestoreMultiDBProvider, app.container); + return [provider firestoreForDatabase:database]; +} + +- (instancetype)initWithProjectID:(std::string)projectID + database:(std::string)database + persistenceKey:(std::string)persistenceKey + credentialsProvider:(std::unique_ptr)credentialsProvider + workerQueue:(std::unique_ptr)workerQueue + firebaseApp:(FIRApp *)app { + if (self = [super init]) { + _firestore.Init(std::move(projectID), std::move(database), std::move(persistenceKey), + std::move(credentialsProvider), std::move(workerQueue), (__bridge void *)self); + + _app = app; + + FSTPreConverterBlock block = ^id _Nullable(id _Nullable input) { + if ([input isKindOfClass:[FIRDocumentReference class]]) { + FIRDocumentReference *documentReference = (FIRDocumentReference *)input; + return [[FSTDocumentKeyReference alloc] initWithKey:documentReference.key + databaseID:documentReference.firestore.databaseID]; + } else { + return input; + } + }; + + _dataConverter = [[FSTUserDataConverter alloc] initWithDatabaseID:&_firestore->database_id() + preConverter:block]; + } + return self; +} + +- (FIRFirestoreSettings *)settings { + return _firestore->settings(); +} + +- (void)setSettings:(FIRFirestoreSettings *)settings { + _firestore->set_settings(settings); +} + +/** + * Ensures that the FirestoreClient is configured and returns it. + */ +- (FSTFirestoreClient *)client { + return _firestore->client(); +} + +- (FIRCollectionReference *)collectionWithPath:(NSString *)collectionPath { + if (!collectionPath) { + FSTThrowInvalidArgument(@"Collection path cannot be nil."); + } + if ([collectionPath containsString:@"//"]) { + FSTThrowInvalidArgument(@"Invalid path (%@). Paths must not contain // in them.", + collectionPath); + } + + return _firestore->GetCollection(util::MakeString(collectionPath)); +} + +- (FIRDocumentReference *)documentWithPath:(NSString *)documentPath { + if (!documentPath) { + FSTThrowInvalidArgument(@"Document path cannot be nil."); + } + if ([documentPath containsString:@"//"]) { + FSTThrowInvalidArgument(@"Invalid path (%@). Paths must not contain // in them.", documentPath); + } + + DocumentReference documentReference = _firestore->GetDocument(util::MakeString(documentPath)); + return [[FIRDocumentReference alloc] initWithReference:std::move(documentReference)]; +} + +- (FIRWriteBatch *)batch { + return _firestore->GetBatch(); +} + +- (void)runTransactionWithBlock:(id _Nullable (^)(FIRTransaction *, NSError **))updateBlock + dispatchQueue:(dispatch_queue_t)queue + completion: + (void (^)(id _Nullable result, NSError *_Nullable error))completion { + // We wrap the function they provide in order to use internal implementation classes for + // transaction, and to run the user callback block on the proper queue. + if (!updateBlock) { + FSTThrowInvalidArgument(@"Transaction block cannot be nil."); + } else if (!completion) { + FSTThrowInvalidArgument(@"Transaction completion block cannot be nil."); + } + + _firestore->RunTransaction(updateBlock, queue, completion); +} + +- (void)runTransactionWithBlock:(id _Nullable (^)(FIRTransaction *, NSError **error))updateBlock + completion: + (void (^)(id _Nullable result, NSError *_Nullable error))completion { + static dispatch_queue_t transactionDispatchQueue; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + transactionDispatchQueue = dispatch_queue_create("com.google.firebase.firestore.transaction", + DISPATCH_QUEUE_CONCURRENT); + }); + [self runTransactionWithBlock:updateBlock + dispatchQueue:transactionDispatchQueue + completion:completion]; +} + ++ (void)enableLogging:(BOOL)logging { + FIRSetLoggerLevel(logging ? FIRLoggerLevelDebug : FIRLoggerLevelNotice); +} + +- (void)enableNetworkWithCompletion:(nullable void (^)(NSError *_Nullable error))completion { + _firestore->EnableNetwork(completion); +} + +- (void)disableNetworkWithCompletion:(nullable void (^)(NSError *_Nullable))completion { + _firestore->DisableNetwork(completion); +} + +@end + +@implementation FIRFirestore (Internal) + +- (Firestore *)wrapped { + return _firestore.get(); +} + +- (AsyncQueue *)workerQueue { + return _firestore->worker_queue(); +} + +- (const DatabaseId *)databaseID { + return &_firestore->database_id(); +} + ++ (BOOL)isLoggingEnabled { + return FIRIsLoggableLevel(FIRLoggerLevelDebug, NO); +} + ++ (FIRFirestore *)recoverFromFirestore:(Firestore *)firestore { + return (__bridge FIRFirestore *)firestore->extension(); +} + +- (FIRQuery *)collectionGroupWithID:(NSString *)collectionID { + if (!collectionID) { + FSTThrowInvalidArgument(@"Collection ID cannot be nil."); + } + if ([collectionID containsString:@"/"]) { + FSTThrowInvalidArgument( + @"Invalid collection ID (%@). Collection IDs must not contain / in them.", collectionID); + } + + return _firestore->GetCollectionGroup(collectionID); +} + +- (void)shutdownWithCompletion:(nullable void (^)(NSError *_Nullable error))completion { + _firestore->Shutdown(completion); +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRFirestoreSettings.mm b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRFirestoreSettings.mm new file mode 100644 index 0000000..3dd7dbd --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRFirestoreSettings.mm @@ -0,0 +1,119 @@ +/* + * Copyright 2017 Google + * + * 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 "Firestore/core/src/firebase/firestore/util/warnings.h" + +#import "FIRFirestoreSettings.h" + +#import "Firestore/Source/Util/FSTUsageValidation.h" + +NS_ASSUME_NONNULL_BEGIN + +static NSString *const kDefaultHost = @"firestore.googleapis.com"; +static const BOOL kDefaultSSLEnabled = YES; +static const BOOL kDefaultPersistenceEnabled = YES; +static const int64_t kDefaultCacheSizeBytes = 100 * 1024 * 1024; +static const int64_t kMinimumCacheSizeBytes = 1 * 1024 * 1024; +static const BOOL kDefaultTimestampsInSnapshotsEnabled = YES; + +@implementation FIRFirestoreSettings + +- (instancetype)init { + if (self = [super init]) { + _host = kDefaultHost; + _sslEnabled = kDefaultSSLEnabled; + _dispatchQueue = dispatch_get_main_queue(); + _persistenceEnabled = kDefaultPersistenceEnabled; + _timestampsInSnapshotsEnabled = kDefaultTimestampsInSnapshotsEnabled; + _cacheSizeBytes = kDefaultCacheSizeBytes; + } + return self; +} + +- (BOOL)isEqual:(id)other { + if (self == other) { + return YES; + } else if (![other isKindOfClass:[FIRFirestoreSettings class]]) { + return NO; + } + + FIRFirestoreSettings *otherSettings = (FIRFirestoreSettings *)other; + SUPPRESS_DEPRECATED_DECLARATIONS_BEGIN() + return [self.host isEqual:otherSettings.host] && + self.isSSLEnabled == otherSettings.isSSLEnabled && + self.dispatchQueue == otherSettings.dispatchQueue && + self.isPersistenceEnabled == otherSettings.isPersistenceEnabled && + self.timestampsInSnapshotsEnabled == otherSettings.timestampsInSnapshotsEnabled && + self.cacheSizeBytes == otherSettings.cacheSizeBytes; + SUPPRESS_END() +} + +- (NSUInteger)hash { + NSUInteger result = [self.host hash]; + result = 31 * result + (self.isSSLEnabled ? 1231 : 1237); + // Ignore the dispatchQueue to avoid having to deal with sizeof(dispatch_queue_t). + result = 31 * result + (self.isPersistenceEnabled ? 1231 : 1237); + SUPPRESS_DEPRECATED_DECLARATIONS_BEGIN() + result = 31 * result + (self.timestampsInSnapshotsEnabled ? 1231 : 1237); + SUPPRESS_END() + result = 31 * result + (NSUInteger)self.cacheSizeBytes; + return result; +} + +- (id)copyWithZone:(nullable NSZone *)zone { + FIRFirestoreSettings *copy = [[FIRFirestoreSettings alloc] init]; + copy.host = _host; + copy.sslEnabled = _sslEnabled; + copy.dispatchQueue = _dispatchQueue; + copy.persistenceEnabled = _persistenceEnabled; + SUPPRESS_DEPRECATED_DECLARATIONS_BEGIN() + copy.timestampsInSnapshotsEnabled = _timestampsInSnapshotsEnabled; + SUPPRESS_END() + copy.cacheSizeBytes = _cacheSizeBytes; + return copy; +} + +- (void)setHost:(NSString *)host { + if (!host) { + FSTThrowInvalidArgument( + @"host setting may not be nil. You should generally just use the default value " + "(which is %@)", + kDefaultHost); + } + _host = [host mutableCopy]; +} + +- (void)setDispatchQueue:(dispatch_queue_t)dispatchQueue { + if (!dispatchQueue) { + FSTThrowInvalidArgument( + @"dispatch queue setting may not be nil. Create a new dispatch queue with " + "dispatch_queue_create(\"com.example.MyQueue\", NULL) or just use the default " + "(which is the main queue, returned from dispatch_get_main_queue())"); + } + _dispatchQueue = dispatchQueue; +} + +- (void)setCacheSizeBytes:(int64_t)cacheSizeBytes { + if (cacheSizeBytes != kFIRFirestoreCacheSizeUnlimited && + cacheSizeBytes < kMinimumCacheSizeBytes) { + FSTThrowInvalidArgument(@"Cache size must be set to at least %i bytes", kMinimumCacheSizeBytes); + } + _cacheSizeBytes = cacheSizeBytes; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRFirestoreVersion.h b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRFirestoreVersion.h new file mode 100644 index 0000000..ca1a166 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRFirestoreVersion.h @@ -0,0 +1,22 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +/** Version for Firestore. */ + +#import + +/** Version string for the Firebase Firestore SDK. */ +FOUNDATION_EXPORT const char *const FIRFirestoreVersionString; diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRFirestoreVersion.mm b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRFirestoreVersion.mm new file mode 100644 index 0000000..94d9103 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRFirestoreVersion.mm @@ -0,0 +1,25 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "Firestore/Source/API/FIRFirestoreVersion.h" + +#include "Firestore/core/include/firebase/firestore/firestore_version.h" + +using firebase::firestore::kFirestoreVersionString; + +// Because `kFirestoreVersionString` is subject to constant initialization, this +// is not affected by static initialization order fiasco. +extern "C" const char *const FIRFirestoreVersionString = kFirestoreVersionString; diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRGeoPoint+Internal.h b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRGeoPoint+Internal.h new file mode 100644 index 0000000..6eb8548 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRGeoPoint+Internal.h @@ -0,0 +1,26 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRGeoPoint.h" + +NS_ASSUME_NONNULL_BEGIN + +/** Internal FIRGeoPoint API we don't want exposed in our public header files. */ +@interface FIRGeoPoint (Internal) +- (NSComparisonResult)compare:(FIRGeoPoint *)other; +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRGeoPoint.mm b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRGeoPoint.mm new file mode 100644 index 0000000..cfd70fb --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRGeoPoint.mm @@ -0,0 +1,88 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "Firestore/Source/API/FIRGeoPoint+Internal.h" + +#import "Firestore/core/src/firebase/firestore/util/comparison.h" + +#import "Firestore/Source/Util/FSTUsageValidation.h" + +using firebase::firestore::util::DoubleBitwiseEquals; +using firebase::firestore::util::DoubleBitwiseHash; +using firebase::firestore::util::WrapCompare; + +NS_ASSUME_NONNULL_BEGIN + +@implementation FIRGeoPoint + +- (instancetype)initWithLatitude:(double)latitude longitude:(double)longitude { + if (self = [super init]) { + if (latitude < -90 || latitude > 90 || !isfinite(latitude)) { + FSTThrowInvalidArgument(@"GeoPoint requires a latitude value in the range of [-90, 90], " + "but was %f", + latitude); + } + if (longitude < -180 || longitude > 180 || !isfinite(longitude)) { + FSTThrowInvalidArgument(@"GeoPoint requires a longitude value in the range of [-180, 180], " + "but was %f", + longitude); + } + + _latitude = latitude; + _longitude = longitude; + } + return self; +} + +- (NSComparisonResult)compare:(FIRGeoPoint *)other { + NSComparisonResult result = WrapCompare(self.latitude, other.latitude); + if (result != NSOrderedSame) { + return result; + } else { + return WrapCompare(self.longitude, other.longitude); + } +} + +#pragma mark - NSObject methods + +- (NSString *)description { + return [NSString stringWithFormat:@"", self.latitude, self.longitude]; +} + +- (BOOL)isEqual:(id)other { + if (self == other) { + return YES; + } + if (![other isKindOfClass:[FIRGeoPoint class]]) { + return NO; + } + FIRGeoPoint *otherGeoPoint = (FIRGeoPoint *)other; + return DoubleBitwiseEquals(self.latitude, otherGeoPoint.latitude) && + DoubleBitwiseEquals(self.longitude, otherGeoPoint.longitude); +} + +- (NSUInteger)hash { + return 31 * DoubleBitwiseHash(self.latitude) + DoubleBitwiseHash(self.longitude); +} + +/** Implements NSCopying without actually copying because geopoints are immutable. */ +- (id)copyWithZone:(NSZone *_Nullable)zone { + return self; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRListenerRegistration+Internal.h b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRListenerRegistration+Internal.h new file mode 100644 index 0000000..e3f1cd5 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRListenerRegistration+Internal.h @@ -0,0 +1,32 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRListenerRegistration.h" + +#include "Firestore/core/src/firebase/firestore/api/listener_registration.h" + +NS_ASSUME_NONNULL_BEGIN + +using firebase::firestore::api::ListenerRegistration; + +/** Private implementation of the FIRListenerRegistration protocol. */ +@interface FSTListenerRegistration : NSObject + +- (instancetype)initWithRegistration:(ListenerRegistration &&)registration; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRListenerRegistration.mm b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRListenerRegistration.mm new file mode 100644 index 0000000..b69b9fb --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRListenerRegistration.mm @@ -0,0 +1,44 @@ +/* + * Copyright 2017 Google + * + * 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 + +#import "Firestore/Source/API/FIRListenerRegistration+Internal.h" + +#include "Firestore/core/src/firebase/firestore/util/delayed_constructor.h" + +NS_ASSUME_NONNULL_BEGIN + +using firebase::firestore::util::DelayedConstructor; + +@implementation FSTListenerRegistration { + DelayedConstructor _registration; +} + +- (instancetype)initWithRegistration:(ListenerRegistration &&)registration { + if (self = [super init]) { + _registration.Init(std::move(registration)); + } + return self; +} + +- (void)remove { + _registration->Remove(); +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRQuery+Internal.h b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRQuery+Internal.h new file mode 100644 index 0000000..fa6c415 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRQuery+Internal.h @@ -0,0 +1,31 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRQuery.h" + +@class FSTQuery; + +NS_ASSUME_NONNULL_BEGIN + +/** Internal FIRQuery API we don't want exposed in our public header files. */ +@interface FIRQuery (Internal) ++ (FIRQuery *)referenceWithQuery:(FSTQuery *)query firestore:(FIRFirestore *)firestore; + +@property(nonatomic, strong, readonly) FSTQuery *query; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRQuery.mm b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRQuery.mm new file mode 100644 index 0000000..507e1f3 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRQuery.mm @@ -0,0 +1,672 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRQuery.h" + +#include +#include + +#import "FIRDocumentReference.h" +#import "FIRFirestoreErrors.h" +#import "FIRFirestoreSource.h" +#import "Firestore/Source/API/FIRDocumentReference+Internal.h" +#import "Firestore/Source/API/FIRDocumentSnapshot+Internal.h" +#import "Firestore/Source/API/FIRFieldPath+Internal.h" +#import "Firestore/Source/API/FIRFieldValue+Internal.h" +#import "Firestore/Source/API/FIRFirestore+Internal.h" +#import "Firestore/Source/API/FIRListenerRegistration+Internal.h" +#import "Firestore/Source/API/FIRQuery+Internal.h" +#import "Firestore/Source/API/FIRQuerySnapshot+Internal.h" +#import "Firestore/Source/API/FIRQuery_Init.h" +#import "Firestore/Source/API/FIRSnapshotMetadata+Internal.h" +#import "Firestore/Source/API/FSTUserDataConverter.h" +#import "Firestore/Source/Core/FSTEventManager.h" +#import "Firestore/Source/Core/FSTFirestoreClient.h" +#import "Firestore/Source/Core/FSTQuery.h" +#import "Firestore/Source/Model/FSTDocument.h" +#import "Firestore/Source/Model/FSTFieldValue.h" +#import "Firestore/Source/Util/FSTUsageValidation.h" + +#include "Firestore/core/src/firebase/firestore/model/document_key.h" +#include "Firestore/core/src/firebase/firestore/model/field_path.h" +#include "Firestore/core/src/firebase/firestore/model/resource_path.h" +#include "Firestore/core/src/firebase/firestore/util/error_apple.h" +#include "Firestore/core/src/firebase/firestore/util/hard_assert.h" +#include "Firestore/core/src/firebase/firestore/util/statusor.h" +#include "Firestore/core/src/firebase/firestore/util/string_apple.h" + +namespace util = firebase::firestore::util; +using firebase::firestore::core::AsyncEventListener; +using firebase::firestore::core::EventListener; +using firebase::firestore::core::ViewSnapshot; +using firebase::firestore::model::DocumentKey; +using firebase::firestore::model::FieldPath; +using firebase::firestore::model::ResourcePath; +using firebase::firestore::util::MakeNSError; +using firebase::firestore::util::StatusOr; + +NS_ASSUME_NONNULL_BEGIN + +@interface FIRQuery () +@property(nonatomic, strong, readonly) FSTQuery *query; +@end + +@implementation FIRQuery (Internal) ++ (instancetype)referenceWithQuery:(FSTQuery *)query firestore:(FIRFirestore *)firestore { + return [[FIRQuery alloc] initWithQuery:query firestore:firestore]; +} +@end + +@implementation FIRQuery + +#pragma mark - Constructor Methods + +- (instancetype)initWithQuery:(FSTQuery *)query firestore:(FIRFirestore *)firestore { + if (self = [super init]) { + _query = query; + _firestore = firestore; + } + return self; +} + +#pragma mark - NSObject Methods + +- (BOOL)isEqual:(nullable id)other { + if (other == self) return YES; + if (![[other class] isEqual:[self class]]) return NO; + + return [self isEqualToQuery:other]; +} + +- (BOOL)isEqualToQuery:(nullable FIRQuery *)query { + if (self == query) return YES; + if (query == nil) return NO; + + return [self.firestore isEqual:query.firestore] && [self.query isEqual:query.query]; +} + +- (NSUInteger)hash { + NSUInteger hash = [self.firestore hash]; + hash = hash * 31u + [self.query hash]; + return hash; +} + +#pragma mark - Public Methods + +- (void)getDocumentsWithCompletion:(void (^)(FIRQuerySnapshot *_Nullable snapshot, + NSError *_Nullable error))completion { + [self getDocumentsWithSource:FIRFirestoreSourceDefault completion:completion]; +} + +- (void)getDocumentsWithSource:(FIRFirestoreSource)source + completion:(void (^)(FIRQuerySnapshot *_Nullable snapshot, + NSError *_Nullable error))completion { + if (source == FIRFirestoreSourceCache) { + [self.firestore.client getDocumentsFromLocalCache:self completion:completion]; + return; + } + + ListenOptions listenOptions( + /*include_query_metadata_changes=*/true, + /*include_document_metadata_changes=*/true, + /*wait_for_sync_when_online=*/true); + + dispatch_semaphore_t registered = dispatch_semaphore_create(0); + __block id listenerRegistration; + FIRQuerySnapshotBlock listener = ^(FIRQuerySnapshot *snapshot, NSError *error) { + if (error) { + completion(nil, error); + return; + } + + // Remove query first before passing event to user to avoid user actions affecting the + // now stale query. + dispatch_semaphore_wait(registered, DISPATCH_TIME_FOREVER); + [listenerRegistration remove]; + + if (snapshot.metadata.fromCache && source == FIRFirestoreSourceServer) { + completion(nil, + [NSError errorWithDomain:FIRFirestoreErrorDomain + code:FIRFirestoreErrorCodeUnavailable + userInfo:@{ + NSLocalizedDescriptionKey : + @"Failed to get documents from server. (However, these " + @"documents may exist in the local cache. Run again " + @"without setting source to FIRFirestoreSourceServer to " + @"retrieve the cached documents.)" + }]); + } else { + completion(snapshot, nil); + } + }; + + listenerRegistration = [self addSnapshotListenerInternalWithOptions:listenOptions + listener:listener]; + dispatch_semaphore_signal(registered); +} + +- (id)addSnapshotListener:(FIRQuerySnapshotBlock)listener { + return [self addSnapshotListenerWithIncludeMetadataChanges:NO listener:listener]; +} + +- (id) + addSnapshotListenerWithIncludeMetadataChanges:(BOOL)includeMetadataChanges + listener:(FIRQuerySnapshotBlock)listener { + auto options = ListenOptions::FromIncludeMetadataChanges(includeMetadataChanges); + return [self addSnapshotListenerInternalWithOptions:options listener:listener]; +} + +- (id)addSnapshotListenerInternalWithOptions:(ListenOptions)internalOptions + listener: + (FIRQuerySnapshotBlock)listener { + Firestore *firestore = self.firestore.wrapped; + FSTQuery *query = self.query; + + // Convert from ViewSnapshots to QuerySnapshots. + auto view_listener = EventListener::Create( + [listener, firestore, query](StatusOr maybe_snapshot) { + if (!maybe_snapshot.status().ok()) { + listener(nil, MakeNSError(maybe_snapshot.status())); + return; + } + + ViewSnapshot snapshot = std::move(maybe_snapshot).ValueOrDie(); + SnapshotMetadata metadata(snapshot.has_pending_writes(), snapshot.from_cache()); + + listener([[FIRQuerySnapshot alloc] initWithFirestore:firestore + originalQuery:query + snapshot:std::move(snapshot) + metadata:std::move(metadata)], + nil); + }); + + // Call the view_listener on the user Executor. + auto async_listener = AsyncEventListener::Create(firestore->client().userExecutor, + std::move(view_listener)); + + std::shared_ptr query_listener = + [firestore->client() listenToQuery:query options:internalOptions listener:async_listener]; + + return [[FSTListenerRegistration alloc] + initWithRegistration:ListenerRegistration(firestore->client(), std::move(async_listener), + std::move(query_listener))]; +} + +- (FIRQuery *)queryWhereField:(NSString *)field isEqualTo:(id)value { + return [self queryWithFilterOperator:FSTRelationFilterOperatorEqual field:field value:value]; +} + +- (FIRQuery *)queryWhereFieldPath:(FIRFieldPath *)path isEqualTo:(id)value { + return [self queryWithFilterOperator:FSTRelationFilterOperatorEqual + path:path.internalValue + value:value]; +} + +- (FIRQuery *)queryWhereField:(NSString *)field isLessThan:(id)value { + return [self queryWithFilterOperator:FSTRelationFilterOperatorLessThan field:field value:value]; +} + +- (FIRQuery *)queryWhereFieldPath:(FIRFieldPath *)path isLessThan:(id)value { + return [self queryWithFilterOperator:FSTRelationFilterOperatorLessThan + path:path.internalValue + value:value]; +} + +- (FIRQuery *)queryWhereField:(NSString *)field isLessThanOrEqualTo:(id)value { + return [self queryWithFilterOperator:FSTRelationFilterOperatorLessThanOrEqual + field:field + value:value]; +} + +- (FIRQuery *)queryWhereFieldPath:(FIRFieldPath *)path isLessThanOrEqualTo:(id)value { + return [self queryWithFilterOperator:FSTRelationFilterOperatorLessThanOrEqual + path:path.internalValue + value:value]; +} + +- (FIRQuery *)queryWhereField:(NSString *)field isGreaterThan:(id)value { + return [self queryWithFilterOperator:FSTRelationFilterOperatorGreaterThan + field:field + value:value]; +} + +- (FIRQuery *)queryWhereFieldPath:(FIRFieldPath *)path isGreaterThan:(id)value { + return [self queryWithFilterOperator:FSTRelationFilterOperatorGreaterThan + path:path.internalValue + value:value]; +} + +- (FIRQuery *)queryWhereField:(NSString *)field arrayContains:(id)value { + return [self queryWithFilterOperator:FSTRelationFilterOperatorArrayContains + field:field + value:value]; +} + +- (FIRQuery *)queryWhereFieldPath:(FIRFieldPath *)path arrayContains:(id)value { + return [self queryWithFilterOperator:FSTRelationFilterOperatorArrayContains + path:path.internalValue + value:value]; +} + +- (FIRQuery *)queryWhereField:(NSString *)field isGreaterThanOrEqualTo:(id)value { + return [self queryWithFilterOperator:FSTRelationFilterOperatorGreaterThanOrEqual + field:field + value:value]; +} + +- (FIRQuery *)queryWhereFieldPath:(FIRFieldPath *)path isGreaterThanOrEqualTo:(id)value { + return [self queryWithFilterOperator:FSTRelationFilterOperatorGreaterThanOrEqual + path:path.internalValue + value:value]; +} + +- (FIRQuery *)queryFilteredUsingComparisonPredicate:(NSPredicate *)predicate { + NSComparisonPredicate *comparison = (NSComparisonPredicate *)predicate; + if (comparison.comparisonPredicateModifier != NSDirectPredicateModifier) { + FSTThrowInvalidArgument(@"Invalid query. Predicate cannot have an aggregate modifier."); + } + NSString *path; + id value = nil; + if ([comparison.leftExpression expressionType] == NSKeyPathExpressionType && + [comparison.rightExpression expressionType] == NSConstantValueExpressionType) { + path = comparison.leftExpression.keyPath; + value = comparison.rightExpression.constantValue; + switch (comparison.predicateOperatorType) { + case NSEqualToPredicateOperatorType: + return [self queryWhereField:path isEqualTo:value]; + case NSLessThanPredicateOperatorType: + return [self queryWhereField:path isLessThan:value]; + case NSLessThanOrEqualToPredicateOperatorType: + return [self queryWhereField:path isLessThanOrEqualTo:value]; + case NSGreaterThanPredicateOperatorType: + return [self queryWhereField:path isGreaterThan:value]; + case NSGreaterThanOrEqualToPredicateOperatorType: + return [self queryWhereField:path isGreaterThanOrEqualTo:value]; + default:; // Fallback below to throw assertion. + } + } else if ([comparison.leftExpression expressionType] == NSConstantValueExpressionType && + [comparison.rightExpression expressionType] == NSKeyPathExpressionType) { + path = comparison.rightExpression.keyPath; + value = comparison.leftExpression.constantValue; + switch (comparison.predicateOperatorType) { + case NSEqualToPredicateOperatorType: + return [self queryWhereField:path isEqualTo:value]; + case NSLessThanPredicateOperatorType: + return [self queryWhereField:path isGreaterThan:value]; + case NSLessThanOrEqualToPredicateOperatorType: + return [self queryWhereField:path isGreaterThanOrEqualTo:value]; + case NSGreaterThanPredicateOperatorType: + return [self queryWhereField:path isLessThan:value]; + case NSGreaterThanOrEqualToPredicateOperatorType: + return [self queryWhereField:path isLessThanOrEqualTo:value]; + default:; // Fallback below to throw assertion. + } + } else { + FSTThrowInvalidArgument( + @"Invalid query. Predicate comparisons must include a key path and a constant."); + } + // Fallback cases of unsupported comparison operator. + switch (comparison.predicateOperatorType) { + case NSCustomSelectorPredicateOperatorType: + FSTThrowInvalidArgument(@"Invalid query. Custom predicate filters are not supported."); + break; + default: + FSTThrowInvalidArgument(@"Invalid query. Operator type %lu is not supported.", + (unsigned long)comparison.predicateOperatorType); + } +} + +- (FIRQuery *)queryFilteredUsingCompoundPredicate:(NSPredicate *)predicate { + NSCompoundPredicate *compound = (NSCompoundPredicate *)predicate; + if (compound.compoundPredicateType != NSAndPredicateType || compound.subpredicates.count == 0) { + FSTThrowInvalidArgument(@"Invalid query. Only compound queries using AND are supported."); + } + FIRQuery *query = self; + for (NSPredicate *pred in compound.subpredicates) { + query = [query queryFilteredUsingPredicate:pred]; + } + return query; +} + +- (FIRQuery *)queryFilteredUsingPredicate:(NSPredicate *)predicate { + if ([predicate isKindOfClass:[NSComparisonPredicate class]]) { + return [self queryFilteredUsingComparisonPredicate:predicate]; + } else if ([predicate isKindOfClass:[NSCompoundPredicate class]]) { + return [self queryFilteredUsingCompoundPredicate:predicate]; + } else if ([predicate isKindOfClass:[[NSPredicate + predicateWithBlock:^BOOL(id obj, NSDictionary *bindings) { + return true; + }] class]]) { + FSTThrowInvalidArgument(@"Invalid query. Block-based predicates are not " + "supported. Please use predicateWithFormat to " + "create predicates instead."); + } else { + FSTThrowInvalidArgument(@"Invalid query. Expect comparison or compound of " + "comparison predicate. Please use " + "predicateWithFormat to create predicates."); + } +} + +- (FIRQuery *)queryOrderedByField:(NSString *)field { + return [self queryOrderedByFieldPath:[FIRFieldPath pathWithDotSeparatedString:field] + descending:NO]; +} + +- (FIRQuery *)queryOrderedByFieldPath:(FIRFieldPath *)fieldPath { + return [self queryOrderedByFieldPath:fieldPath descending:NO]; +} + +- (FIRQuery *)queryOrderedByField:(NSString *)field descending:(BOOL)descending { + return [self queryOrderedByFieldPath:[FIRFieldPath pathWithDotSeparatedString:field] + descending:descending]; +} + +- (FIRQuery *)queryOrderedByFieldPath:(FIRFieldPath *)fieldPath descending:(BOOL)descending { + [self validateNewOrderByPath:fieldPath.internalValue]; + if (self.query.startAt) { + FSTThrowInvalidUsage( + @"InvalidQueryException", + @"Invalid query. You must not specify a starting point before specifying the order by."); + } + if (self.query.endAt) { + FSTThrowInvalidUsage( + @"InvalidQueryException", + @"Invalid query. You must not specify an ending point before specifying the order by."); + } + FSTSortOrder *sortOrder = [FSTSortOrder sortOrderWithFieldPath:fieldPath.internalValue + ascending:!descending]; + return [FIRQuery referenceWithQuery:[self.query queryByAddingSortOrder:sortOrder] + firestore:self.firestore]; +} + +- (FIRQuery *)queryLimitedTo:(NSInteger)limit { + if (limit <= 0) { + FSTThrowInvalidArgument(@"Invalid Query. Query limit (%ld) is invalid. Limit must be positive.", + (long)limit); + } + return [FIRQuery referenceWithQuery:[self.query queryBySettingLimit:limit] firestore:_firestore]; +} + +- (FIRQuery *)queryStartingAtDocument:(FIRDocumentSnapshot *)snapshot { + FSTBound *bound = [self boundFromSnapshot:snapshot isBefore:YES]; + return [FIRQuery referenceWithQuery:[self.query queryByAddingStartAt:bound] + firestore:self.firestore]; +} + +- (FIRQuery *)queryStartingAtValues:(NSArray *)fieldValues { + FSTBound *bound = [self boundFromFieldValues:fieldValues isBefore:YES]; + return [FIRQuery referenceWithQuery:[self.query queryByAddingStartAt:bound] + firestore:self.firestore]; +} + +- (FIRQuery *)queryStartingAfterDocument:(FIRDocumentSnapshot *)snapshot { + FSTBound *bound = [self boundFromSnapshot:snapshot isBefore:NO]; + return [FIRQuery referenceWithQuery:[self.query queryByAddingStartAt:bound] + firestore:self.firestore]; +} + +- (FIRQuery *)queryStartingAfterValues:(NSArray *)fieldValues { + FSTBound *bound = [self boundFromFieldValues:fieldValues isBefore:NO]; + return [FIRQuery referenceWithQuery:[self.query queryByAddingStartAt:bound] + firestore:self.firestore]; +} + +- (FIRQuery *)queryEndingBeforeDocument:(FIRDocumentSnapshot *)snapshot { + FSTBound *bound = [self boundFromSnapshot:snapshot isBefore:YES]; + return [FIRQuery referenceWithQuery:[self.query queryByAddingEndAt:bound] + firestore:self.firestore]; +} + +- (FIRQuery *)queryEndingBeforeValues:(NSArray *)fieldValues { + FSTBound *bound = [self boundFromFieldValues:fieldValues isBefore:YES]; + return [FIRQuery referenceWithQuery:[self.query queryByAddingEndAt:bound] + firestore:self.firestore]; +} + +- (FIRQuery *)queryEndingAtDocument:(FIRDocumentSnapshot *)snapshot { + FSTBound *bound = [self boundFromSnapshot:snapshot isBefore:NO]; + return [FIRQuery referenceWithQuery:[self.query queryByAddingEndAt:bound] + firestore:self.firestore]; +} + +- (FIRQuery *)queryEndingAtValues:(NSArray *)fieldValues { + FSTBound *bound = [self boundFromFieldValues:fieldValues isBefore:NO]; + return [FIRQuery referenceWithQuery:[self.query queryByAddingEndAt:bound] + firestore:self.firestore]; +} + +#pragma mark - Private Methods + +/** Private helper for all of the queryWhereField: methods. */ +- (FIRQuery *)queryWithFilterOperator:(FSTRelationFilterOperator)filterOperator + field:(NSString *)field + value:(id)value { + return [self queryWithFilterOperator:filterOperator + path:[FIRFieldPath pathWithDotSeparatedString:field].internalValue + value:value]; +} + +- (FIRQuery *)queryWithFilterOperator:(FSTRelationFilterOperator)filterOperator + path:(const FieldPath &)fieldPath + value:(id)value { + FSTFieldValue *fieldValue; + if (fieldPath.IsKeyFieldPath()) { + if (filterOperator == FSTRelationFilterOperatorArrayContains) { + FSTThrowInvalidArgument( + @"Invalid query. You can't perform arrayContains queries on document ID since document " + "IDs are not arrays."); + } + if ([value isKindOfClass:[NSString class]]) { + NSString *documentKey = (NSString *)value; + if (documentKey.length == 0) { + FSTThrowInvalidArgument(@"Invalid query. When querying by document ID you must provide " + "a valid document ID, but it was an empty string."); + } + if (![self.query isCollectionGroupQuery] && [documentKey containsString:@"/"]) { + FSTThrowInvalidArgument( + @"Invalid query. When querying a collection by document ID you must provide " + "a plain document ID, but '%@' contains a '/' character.", + documentKey); + } + ResourcePath path = + self.query.path.Append(ResourcePath::FromString([documentKey UTF8String])); + if (!DocumentKey::IsDocumentKey(path)) { + FSTThrowInvalidArgument( + @"Invalid query. When querying a collection group by document ID, " + "the value provided must result in a valid document path, but '%s' is not because it " + "has an odd number of segments.", + path.CanonicalString().c_str()); + } + fieldValue = + [FSTReferenceValue referenceValue:[FSTDocumentKey keyWithDocumentKey:DocumentKey{path}] + databaseID:self.firestore.databaseID]; + } else if ([value isKindOfClass:[FIRDocumentReference class]]) { + FIRDocumentReference *ref = (FIRDocumentReference *)value; + fieldValue = [FSTReferenceValue referenceValue:[FSTDocumentKey keyWithDocumentKey:ref.key] + databaseID:self.firestore.databaseID]; + } else { + FSTThrowInvalidArgument(@"Invalid query. When querying by document ID you must provide a " + "valid string or DocumentReference, but it was of type: %@", + NSStringFromClass([value class])); + } + } else { + fieldValue = [self.firestore.dataConverter parsedQueryValue:value]; + } + + FSTFilter *filter = [FSTFilter filterWithField:fieldPath + filterOperator:filterOperator + value:fieldValue]; + + if ([filter isKindOfClass:[FSTRelationFilter class]]) { + [self validateNewRelationFilter:(FSTRelationFilter *)filter]; + } + + return [FIRQuery referenceWithQuery:[self.query queryByAddingFilter:filter] + firestore:self.firestore]; +} + +- (void)validateNewRelationFilter:(FSTRelationFilter *)filter { + if ([filter isInequality]) { + const FieldPath *existingField = [self.query inequalityFilterField]; + if (existingField && *existingField != filter.field) { + FSTThrowInvalidUsage( + @"InvalidQueryException", + @"Invalid Query. All where filters with an inequality " + "(lessThan, lessThanOrEqual, greaterThan, or greaterThanOrEqual) must be on the same " + "field. But you have inequality filters on '%s' and '%s'", + existingField->CanonicalString().c_str(), filter.field.CanonicalString().c_str()); + } + + const FieldPath *firstOrderByField = [self.query firstSortOrderField]; + if (firstOrderByField) { + [self validateOrderByField:*firstOrderByField matchesInequalityField:filter.field]; + } + } else if (filter.filterOperator == FSTRelationFilterOperatorArrayContains) { + if ([self.query hasArrayContainsFilter]) { + FSTThrowInvalidUsage(@"InvalidQueryException", + @"Invalid Query. Queries only support a single arrayContains filter."); + } + } +} + +- (void)validateNewOrderByPath:(const FieldPath &)fieldPath { + if (![self.query firstSortOrderField]) { + // This is the first order by. It must match any inequality. + const FieldPath *inequalityField = [self.query inequalityFilterField]; + if (inequalityField) { + [self validateOrderByField:fieldPath matchesInequalityField:*inequalityField]; + } + } +} + +- (void)validateOrderByField:(const FieldPath &)orderByField + matchesInequalityField:(const FieldPath &)inequalityField { + if (orderByField != inequalityField) { + FSTThrowInvalidUsage( + @"InvalidQueryException", + @"Invalid query. You have a where filter with an " + "inequality (lessThan, lessThanOrEqual, greaterThan, or greaterThanOrEqual) on field '%s' " + "and so you must also use '%s' as your first queryOrderedBy field, but your first " + "queryOrderedBy is currently on field '%s' instead.", + inequalityField.CanonicalString().c_str(), inequalityField.CanonicalString().c_str(), + orderByField.CanonicalString().c_str()); + } +} + +/** + * Create a FSTBound from a query given the document. + * + * Note that the FSTBound will always include the key of the document and the position will be + * unambiguous. + * + * Will throw if the document does not contain all fields of the order by of + * the query or if any of the fields in the order by are an uncommitted server + * timestamp. + */ +- (FSTBound *)boundFromSnapshot:(FIRDocumentSnapshot *)snapshot isBefore:(BOOL)isBefore { + if (![snapshot exists]) { + FSTThrowInvalidUsage(@"InvalidQueryException", + @"Invalid query. You are trying to start or end a query using a document " + @"that doesn't exist."); + } + FSTDocument *document = snapshot.internalDocument; + NSMutableArray *components = [NSMutableArray array]; + + // Because people expect to continue/end a query at the exact document provided, we need to + // use the implicit sort order rather than the explicit sort order, because it's guaranteed to + // contain the document key. That way the position becomes unambiguous and the query + // continues/ends exactly at the provided document. Without the key (by using the explicit sort + // orders), multiple documents could match the position, yielding duplicate results. + for (FSTSortOrder *sortOrder in self.query.sortOrders) { + if (sortOrder.field == FieldPath::KeyFieldPath()) { + [components addObject:[FSTReferenceValue + referenceValue:[FSTDocumentKey keyWithDocumentKey:document.key] + databaseID:self.firestore.databaseID]]; + } else { + FSTFieldValue *value = [document fieldForPath:sortOrder.field]; + + if ([value isKindOfClass:[FSTServerTimestampValue class]]) { + FSTThrowInvalidUsage(@"InvalidQueryException", + @"Invalid query. You are trying to start or end a query using a " + "document for which the field '%s' is an uncommitted server " + "timestamp. (Since the value of this field is unknown, you cannot " + "start/end a query with it.)", + sortOrder.field.CanonicalString().c_str()); + } else if (value != nil) { + [components addObject:value]; + } else { + FSTThrowInvalidUsage(@"InvalidQueryException", + @"Invalid query. You are trying to start or end a query using a " + "document for which the field '%s' (used as the order by) " + "does not exist.", + sortOrder.field.CanonicalString().c_str()); + } + } + } + return [FSTBound boundWithPosition:components isBefore:isBefore]; +} + +/** Converts a list of field values to an FSTBound. */ +- (FSTBound *)boundFromFieldValues:(NSArray *)fieldValues isBefore:(BOOL)isBefore { + // Use explicit sort order because it has to match the query the user made + NSArray *explicitSortOrders = self.query.explicitSortOrders; + if (fieldValues.count > explicitSortOrders.count) { + FSTThrowInvalidUsage(@"InvalidQueryException", + @"Invalid query. You are trying to start or end a query using more values " + @"than were specified in the order by."); + } + + NSMutableArray *components = [NSMutableArray array]; + [fieldValues enumerateObjectsUsingBlock:^(id rawValue, NSUInteger idx, BOOL *stop) { + FSTSortOrder *sortOrder = explicitSortOrders[idx]; + if (sortOrder.field == FieldPath::KeyFieldPath()) { + if (![rawValue isKindOfClass:[NSString class]]) { + FSTThrowInvalidUsage(@"InvalidQueryException", + @"Invalid query. Expected a string for the document ID."); + } + NSString *documentID = (NSString *)rawValue; + if (![self.query isCollectionGroupQuery] && [documentID containsString:@"/"]) { + FSTThrowInvalidUsage( + @"InvalidQueryException", + @"Invalid query. When querying a collection and ordering by document ID, " + "you must pass a plain document ID, but '%@' contains a slash.", + documentID); + } + ResourcePath path = self.query.path.Append(ResourcePath::FromString([documentID UTF8String])); + if (!DocumentKey::IsDocumentKey(path)) { + FSTThrowInvalidUsage( + @"InvalidQueryException", + @"Invalid query. When querying a collection group and ordering by document ID, " + "you must pass a value that results in a valid document path, but '%s' " + "is not because it contains an odd number of segments.", + path.CanonicalString().c_str()); + } + DocumentKey key{path}; + [components + addObject:[FSTReferenceValue referenceValue:[FSTDocumentKey keyWithDocumentKey:key] + databaseID:self.firestore.databaseID]]; + } else { + FSTFieldValue *fieldValue = [self.firestore.dataConverter parsedQueryValue:rawValue]; + [components addObject:fieldValue]; + } + }]; + + return [FSTBound boundWithPosition:components isBefore:isBefore]; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRQuerySnapshot+Internal.h b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRQuerySnapshot+Internal.h new file mode 100644 index 0000000..96589d1 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRQuerySnapshot+Internal.h @@ -0,0 +1,47 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRQuerySnapshot.h" + +#include "Firestore/core/src/firebase/firestore/api/firestore.h" +#include "Firestore/core/src/firebase/firestore/api/query_snapshot.h" +#include "Firestore/core/src/firebase/firestore/api/snapshot_metadata.h" +#include "Firestore/core/src/firebase/firestore/core/view_snapshot.h" + +@class FIRFirestore; +@class FIRSnapshotMetadata; +@class FSTQuery; + +using firebase::firestore::api::Firestore; +using firebase::firestore::api::QuerySnapshot; +using firebase::firestore::api::SnapshotMetadata; +using firebase::firestore::core::ViewSnapshot; + +NS_ASSUME_NONNULL_BEGIN + +/** Internal FIRQuerySnapshot API we don't want exposed in our public header files. */ +@interface FIRQuerySnapshot (/* Init */) + +- (instancetype)initWithSnapshot:(QuerySnapshot &&)snapshot NS_DESIGNATED_INITIALIZER; + +- (instancetype)initWithFirestore:(Firestore *)firestore + originalQuery:(FSTQuery *)query + snapshot:(ViewSnapshot &&)snapshot + metadata:(SnapshotMetadata)metadata; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRQuerySnapshot.mm b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRQuerySnapshot.mm new file mode 100644 index 0000000..52a4810 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRQuerySnapshot.mm @@ -0,0 +1,142 @@ +/* + * Copyright 2017 Google + * + * 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 + +#import "Firestore/Source/API/FIRQuerySnapshot+Internal.h" + +#import "FIRSnapshotMetadata.h" +#import "Firestore/Source/API/FIRDocumentChange+Internal.h" +#import "Firestore/Source/API/FIRDocumentSnapshot+Internal.h" +#import "Firestore/Source/API/FIRFirestore+Internal.h" +#import "Firestore/Source/API/FIRQuery+Internal.h" +#import "Firestore/Source/API/FIRSnapshotMetadata+Internal.h" +#import "Firestore/Source/Core/FSTQuery.h" +#import "Firestore/Source/Model/FSTDocument.h" +#import "Firestore/Source/Util/FSTUsageValidation.h" + +#include "Firestore/core/src/firebase/firestore/core/view_snapshot.h" +#include "Firestore/core/src/firebase/firestore/model/document_set.h" +#include "Firestore/core/src/firebase/firestore/util/delayed_constructor.h" + +using firebase::firestore::api::Firestore; +using firebase::firestore::api::QuerySnapshot; +using firebase::firestore::core::ViewSnapshot; +using firebase::firestore::util::DelayedConstructor; + +NS_ASSUME_NONNULL_BEGIN + +@implementation FIRQuerySnapshot { + DelayedConstructor _snapshot; + + FIRSnapshotMetadata *_cached_metadata; + + // Cached value of the documents property. + NSArray *_documents; + + // Cached value of the documentChanges property. + NSArray *_documentChanges; + BOOL _documentChangesIncludeMetadataChanges; +} + +- (instancetype)initWithSnapshot:(QuerySnapshot &&)snapshot { + if (self = [super init]) { + _snapshot.Init(std::move(snapshot)); + } + return self; +} + +- (instancetype)initWithFirestore:(Firestore *)firestore + originalQuery:(FSTQuery *)query + snapshot:(ViewSnapshot &&)snapshot + metadata:(SnapshotMetadata)metadata { + QuerySnapshot wrapped(firestore, query, std::move(snapshot), std::move(metadata)); + return [self initWithSnapshot:std::move(wrapped)]; +} + +// NSObject Methods +- (BOOL)isEqual:(nullable id)other { + if (![other isKindOfClass:[FIRQuerySnapshot class]]) return NO; + + FIRQuerySnapshot *otherSnapshot = other; + return *_snapshot == *(otherSnapshot->_snapshot); +} + +- (NSUInteger)hash { + return _snapshot->Hash(); +} + +- (FIRQuery *)query { + FIRFirestore *firestore = [FIRFirestore recoverFromFirestore:_snapshot->firestore()]; + return [FIRQuery referenceWithQuery:_snapshot->internal_query() firestore:firestore]; +} + +- (FIRSnapshotMetadata *)metadata { + if (!_cached_metadata) { + _cached_metadata = [[FIRSnapshotMetadata alloc] initWithMetadata:_snapshot->metadata()]; + } + return _cached_metadata; +} + +@dynamic empty; + +- (BOOL)isEmpty { + return _snapshot->empty(); +} + +// This property is exposed as an NSInteger instead of an NSUInteger since (as of Xcode 8.1) +// Swift bridges NSUInteger as UInt, and we want to avoid forcing Swift users to cast their ints +// where we can. See cr/146959032 for additional context. +- (NSInteger)count { + return static_cast(_snapshot->size()); +} + +- (NSArray *)documents { + if (!_documents) { + NSMutableArray *result = [NSMutableArray array]; + _snapshot->ForEachDocument([&result](DocumentSnapshot snapshot) { + [result addObject:[[FIRQueryDocumentSnapshot alloc] initWithSnapshot:std::move(snapshot)]]; + }); + + _documents = result; + } + return _documents; +} + +- (NSArray *)documentChanges { + return [self documentChangesWithIncludeMetadataChanges:NO]; +} + +- (NSArray *)documentChangesWithIncludeMetadataChanges: + (BOOL)includeMetadataChanges { + if (includeMetadataChanges && _snapshot->view_snapshot().excludes_metadata_changes()) { + FSTThrowInvalidArgument( + @"To include metadata changes with your document changes, you must call " + @"addSnapshotListener(includeMetadataChanges: true)."); + } + + if (!_documentChanges || _documentChangesIncludeMetadataChanges != includeMetadataChanges) { + _documentChanges = [FIRDocumentChange documentChangesForSnapshot:_snapshot->view_snapshot() + includeMetadataChanges:includeMetadataChanges + firestore:_snapshot->firestore()]; + _documentChangesIncludeMetadataChanges = includeMetadataChanges; + } + return _documentChanges; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRQuery_Init.h b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRQuery_Init.h new file mode 100644 index 0000000..d6b0f37 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRQuery_Init.h @@ -0,0 +1,32 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRQuery.h" + +@class FSTQuery; + +NS_ASSUME_NONNULL_BEGIN + +/** + * An Internal class extension for `FIRQuery` that exposes the init method to classes + * that need to derive from it. + */ +@interface FIRQuery (/*Init*/) +- (instancetype)initWithQuery:(FSTQuery *)query + firestore:(FIRFirestore *)firestore NS_DESIGNATED_INITIALIZER; +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRSnapshotMetadata+Internal.h b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRSnapshotMetadata+Internal.h new file mode 100644 index 0000000..6c5c699 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRSnapshotMetadata+Internal.h @@ -0,0 +1,35 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRSnapshotMetadata.h" + +#import + +#include "Firestore/core/src/firebase/firestore/api/snapshot_metadata.h" + +using firebase::firestore::api::SnapshotMetadata; + +NS_ASSUME_NONNULL_BEGIN + +@interface FIRSnapshotMetadata (/* Init */) + +- (instancetype)initWithMetadata:(SnapshotMetadata)metadata NS_DESIGNATED_INITIALIZER; + +- (instancetype)initWithPendingWrites:(bool)pendingWrites fromCache:(bool)fromCache; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRSnapshotMetadata.mm b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRSnapshotMetadata.mm new file mode 100644 index 0000000..87fa45e --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRSnapshotMetadata.mm @@ -0,0 +1,66 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRSnapshotMetadata.h" + +#include + +#import "Firestore/Source/API/FIRSnapshotMetadata+Internal.h" + +#include "Firestore/core/src/firebase/firestore/api/snapshot_metadata.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation FIRSnapshotMetadata { + SnapshotMetadata _metadata; +} + +- (instancetype)initWithMetadata:(SnapshotMetadata)metadata { + if (self = [super init]) { + _metadata = std::move(metadata); + } + return self; +} + +- (instancetype)initWithPendingWrites:(bool)pendingWrites fromCache:(bool)fromCache { + SnapshotMetadata wrapped(pendingWrites, fromCache); + return [self initWithMetadata:std::move(wrapped)]; +} + +// NSObject Methods +- (BOOL)isEqual:(nullable id)other { + if (other == self) return YES; + if (![other isKindOfClass:[FIRSnapshotMetadata class]]) return NO; + + FIRSnapshotMetadata *otherMetadata = other; + return _metadata == otherMetadata->_metadata; +} + +- (NSUInteger)hash { + return _metadata.Hash(); +} + +- (BOOL)hasPendingWrites { + return _metadata.pending_writes(); +} + +- (BOOL)isFromCache { + return _metadata.from_cache(); +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRTimestamp+Internal.h b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRTimestamp+Internal.h new file mode 100644 index 0000000..48e38b2 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRTimestamp+Internal.h @@ -0,0 +1,35 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#import "FIRTimestamp.h" + +NS_ASSUME_NONNULL_BEGIN + +/** Internal FIRTimestamp API we don't want exposed in our public header files. */ +@interface FIRTimestamp (Internal) + +/** + * Converts the given date to an ISO 8601 timestamp string, useful for rendering in JSON. + * + * ISO 8601 dates times in UTC look like this: "1912-04-14T23:40:00.000000000Z". + * + * @see http://www.ecma-international.org/ecma-262/6.0/#sec-date-time-string-format + */ +- (NSString *)ISO8601String; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRTimestamp.m b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRTimestamp.m new file mode 100644 index 0000000..e5a2cd3 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRTimestamp.m @@ -0,0 +1,152 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "Firestore/Source/API/FIRTimestamp+Internal.h" + +NS_ASSUME_NONNULL_BEGIN + +static const int kNanosPerSecond = 1000000000; + +@implementation FIRTimestamp (Internal) + +#pragma mark - Internal public methods + +- (NSString *)ISO8601String { + NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; + formatter.dateFormat = @"yyyy-MM-dd'T'HH:mm:ss"; + formatter.timeZone = [NSTimeZone timeZoneWithName:@"UTC"]; + NSDate *secondsDate = [NSDate dateWithTimeIntervalSince1970:self.seconds]; + NSString *secondsString = [formatter stringFromDate:secondsDate]; + if (secondsString.length != 19) { + [NSException raise:@"Invalid ISO string" format:@"Invalid ISO string: %@", secondsString]; + } + + NSString *nanosString = [NSString stringWithFormat:@"%09d", self.nanoseconds]; + return [NSString stringWithFormat:@"%@.%@Z", secondsString, nanosString]; +} + +@end + +@implementation FIRTimestamp + +#pragma mark - Constructors + ++ (instancetype)timestampWithDate:(NSDate *)date { + double secondsDouble; + double fraction = modf(date.timeIntervalSince1970, &secondsDouble); + // GCP Timestamps always have non-negative nanos. + if (fraction < 0) { + fraction += 1.0; + secondsDouble -= 1.0; + } + int64_t seconds = (int64_t)secondsDouble; + int32_t nanos = (int32_t)(fraction * kNanosPerSecond); + return [[FIRTimestamp alloc] initWithSeconds:seconds nanoseconds:nanos]; +} + ++ (instancetype)timestampWithSeconds:(int64_t)seconds nanoseconds:(int32_t)nanoseconds { + return [[FIRTimestamp alloc] initWithSeconds:seconds nanoseconds:nanoseconds]; +} + ++ (instancetype)timestamp { + return [FIRTimestamp timestampWithDate:[NSDate date]]; +} + +- (instancetype)initWithSeconds:(int64_t)seconds nanoseconds:(int32_t)nanoseconds { + self = [super init]; + if (self) { + if (nanoseconds < 0) { + [NSException raise:@"Invalid timestamp" + format:@"Timestamp nanoseconds out of range: %d", nanoseconds]; + } + if (nanoseconds >= 1e9) { + [NSException raise:@"Invalid timestamp" + format:@"Timestamp nanoseconds out of range: %d", nanoseconds]; + } + // Midnight at the beginning of 1/1/1 is the earliest timestamp supported. + if (seconds < -62135596800L) { + [NSException raise:@"Invalid timestamp" + format:@"Timestamp seconds out of range: %lld", seconds]; + } + // This will break in the year 10,000. + if (seconds >= 253402300800L) { + [NSException raise:@"Invalid timestamp" + format:@"Timestamp seconds out of range: %lld", seconds]; + } + + _seconds = seconds; + _nanoseconds = nanoseconds; + } + return self; +} + +#pragma mark - NSObject methods + +- (BOOL)isEqual:(id)object { + if (self == object) { + return YES; + } + if (![object isKindOfClass:[FIRTimestamp class]]) { + return NO; + } + return [self isEqualToTimestamp:(FIRTimestamp *)object]; +} + +- (NSUInteger)hash { + return (NSUInteger)((self.seconds >> 32) ^ self.seconds ^ self.nanoseconds); +} + +- (NSString *)description { + return [NSString stringWithFormat:@"FIRTimestamp: seconds=%lld nanoseconds=%d>", self.seconds, + self.nanoseconds]; +} + +/** Implements NSCopying without actually copying because timestamps are immutable. */ +- (id)copyWithZone:(NSZone *_Nullable)zone { + return self; +} + +#pragma mark - Public methods + +- (NSDate *)dateValue { + NSTimeInterval interval = (NSTimeInterval)self.seconds + ((NSTimeInterval)self.nanoseconds) / 1e9; + return [NSDate dateWithTimeIntervalSince1970:interval]; +} + +- (NSComparisonResult)compare:(FIRTimestamp *)other { + if (self.seconds < other.seconds) { + return NSOrderedAscending; + } else if (self.seconds > other.seconds) { + return NSOrderedDescending; + } + + if (self.nanoseconds < other.nanoseconds) { + return NSOrderedAscending; + } else if (self.nanoseconds > other.nanoseconds) { + return NSOrderedDescending; + } + return NSOrderedSame; +} + +#pragma mark - Private methods + +- (BOOL)isEqualToTimestamp:(FIRTimestamp *)other { + return [self compare:other] == NSOrderedSame; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRTransaction+Internal.h b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRTransaction+Internal.h new file mode 100644 index 0000000..32abd3f --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRTransaction+Internal.h @@ -0,0 +1,31 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRTransaction.h" + +#include + +#include "Firestore/core/src/firebase/firestore/core/transaction.h" + +@class FIRFirestore; + +@interface FIRTransaction (Internal) + ++ (instancetype)transactionWithInternalTransaction: + (std::shared_ptr)transaction + firestore:(FIRFirestore *)firestore; + +@end diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRTransaction.mm b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRTransaction.mm new file mode 100644 index 0000000..b0d0f9f --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRTransaction.mm @@ -0,0 +1,180 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRTransaction.h" + +#include +#include +#include + +#import "Firestore/Source/API/FIRDocumentReference+Internal.h" +#import "Firestore/Source/API/FIRDocumentSnapshot+Internal.h" +#import "Firestore/Source/API/FIRFirestore+Internal.h" +#import "Firestore/Source/API/FIRTransaction+Internal.h" +#import "Firestore/Source/API/FSTUserDataConverter.h" +#import "Firestore/Source/Model/FSTDocument.h" +#import "Firestore/Source/Util/FSTUsageValidation.h" + +#include "Firestore/core/src/firebase/firestore/core/transaction.h" +#include "Firestore/core/src/firebase/firestore/util/error_apple.h" +#include "Firestore/core/src/firebase/firestore/util/hard_assert.h" +#include "Firestore/core/src/firebase/firestore/util/status.h" + +using firebase::firestore::core::ParsedSetData; +using firebase::firestore::core::ParsedUpdateData; +using firebase::firestore::core::Transaction; +using firebase::firestore::util::MakeNSError; +using firebase::firestore::util::Status; + +NS_ASSUME_NONNULL_BEGIN + +#pragma mark - FIRTransaction + +@interface FIRTransaction () + +- (instancetype)initWithTransaction:(std::shared_ptr)transaction + firestore:(FIRFirestore *)firestore NS_DESIGNATED_INITIALIZER; + +@property(nonatomic, strong, readonly) FIRFirestore *firestore; +@end + +@implementation FIRTransaction (Internal) + ++ (instancetype)transactionWithInternalTransaction:(std::shared_ptr)transaction + firestore:(FIRFirestore *)firestore { + return [[FIRTransaction alloc] initWithTransaction:std::move(transaction) firestore:firestore]; +} + +@end + +@implementation FIRTransaction { + std::shared_ptr _internalTransaction; +} + +- (instancetype)initWithTransaction:(std::shared_ptr)transaction + firestore:(FIRFirestore *)firestore { + self = [super init]; + if (self) { + _internalTransaction = std::move(transaction); + _firestore = firestore; + } + return self; +} + +- (FIRTransaction *)setData:(NSDictionary *)data + forDocument:(FIRDocumentReference *)document { + return [self setData:data forDocument:document merge:NO]; +} + +- (FIRTransaction *)setData:(NSDictionary *)data + forDocument:(FIRDocumentReference *)document + merge:(BOOL)merge { + [self validateReference:document]; + ParsedSetData parsed = merge ? [self.firestore.dataConverter parsedMergeData:data fieldMask:nil] + : [self.firestore.dataConverter parsedSetData:data]; + _internalTransaction->Set(document.key, std::move(parsed)); + return self; +} + +- (FIRTransaction *)setData:(NSDictionary *)data + forDocument:(FIRDocumentReference *)document + mergeFields:(NSArray *)mergeFields { + [self validateReference:document]; + ParsedSetData parsed = [self.firestore.dataConverter parsedMergeData:data fieldMask:mergeFields]; + _internalTransaction->Set(document.key, std::move(parsed)); + return self; +} + +- (FIRTransaction *)updateData:(NSDictionary *)fields + forDocument:(FIRDocumentReference *)document { + [self validateReference:document]; + ParsedUpdateData parsed = [self.firestore.dataConverter parsedUpdateData:fields]; + _internalTransaction->Update(document.key, std::move(parsed)); + return self; +} + +- (FIRTransaction *)deleteDocument:(FIRDocumentReference *)document { + [self validateReference:document]; + _internalTransaction->Delete(document.key); + return self; +} + +- (void)getDocument:(FIRDocumentReference *)document + completion:(void (^)(FIRDocumentSnapshot *_Nullable document, + NSError *_Nullable error))completion { + [self validateReference:document]; + _internalTransaction->Lookup( + {document.key}, [self, document, completion](const std::vector &documents, + const Status &status) { + if (!status.ok()) { + completion(nil, MakeNSError(status)); + return; + } + + HARD_ASSERT(documents.size() == 1, "Mismatch in docs returned from document lookup."); + FSTMaybeDocument *internalDoc = documents.front(); + if ([internalDoc isKindOfClass:[FSTDeletedDocument class]]) { + FIRDocumentSnapshot *doc = + [[FIRDocumentSnapshot alloc] initWithFirestore:self.firestore.wrapped + documentKey:document.key + document:nil + fromCache:false + hasPendingWrites:false]; + completion(doc, nil); + } else if ([internalDoc isKindOfClass:[FSTDocument class]]) { + FIRDocumentSnapshot *doc = + [[FIRDocumentSnapshot alloc] initWithFirestore:self.firestore.wrapped + documentKey:internalDoc.key + document:(FSTDocument *)internalDoc + fromCache:false + hasPendingWrites:false]; + completion(doc, nil); + } else { + HARD_FAIL("BatchGetDocumentsRequest returned unexpected document type: %s", + NSStringFromClass([internalDoc class])); + } + }); +} + +- (FIRDocumentSnapshot *_Nullable)getDocument:(FIRDocumentReference *)document + error:(NSError *__autoreleasing *)error { + [self validateReference:document]; + dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); + __block FIRDocumentSnapshot *result; + // We have to explicitly assign the innerError into a local to cause it to retain correctly. + __block NSError *outerError = nil; + [self getDocument:document + completion:^(FIRDocumentSnapshot *_Nullable snapshot, NSError *_Nullable innerError) { + result = snapshot; + outerError = innerError; + dispatch_semaphore_signal(semaphore); + }]; + dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); + if (error) { + *error = outerError; + } + return result; +} + +- (void)validateReference:(FIRDocumentReference *)reference { + if (reference.firestore != self.firestore) { + FSTThrowInvalidArgument(@"Provided document reference is from a different Firestore instance."); + } +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRWriteBatch+Internal.h b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRWriteBatch+Internal.h new file mode 100644 index 0000000..a434e02 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRWriteBatch+Internal.h @@ -0,0 +1,25 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRWriteBatch.h" + +@class FIRFirestore; + +@interface FIRWriteBatch (Internal) + ++ (instancetype)writeBatchWithFirestore:(FIRFirestore *)firestore; + +@end diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRWriteBatch.mm b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRWriteBatch.mm new file mode 100644 index 0000000..484b8b0 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FIRWriteBatch.mm @@ -0,0 +1,152 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRWriteBatch.h" + +#include +#include +#include + +#import "Firestore/Source/API/FIRDocumentReference+Internal.h" +#import "Firestore/Source/API/FIRFirestore+Internal.h" +#import "Firestore/Source/API/FIRWriteBatch+Internal.h" +#import "Firestore/Source/API/FSTUserDataConverter.h" +#import "Firestore/Source/Core/FSTFirestoreClient.h" +#import "Firestore/Source/Model/FSTMutation.h" +#import "Firestore/Source/Util/FSTUsageValidation.h" + +#include "Firestore/core/src/firebase/firestore/model/precondition.h" + +using firebase::firestore::core::ParsedSetData; +using firebase::firestore::core::ParsedUpdateData; +using firebase::firestore::model::Precondition; + +NS_ASSUME_NONNULL_BEGIN + +#pragma mark - FIRWriteBatch + +@interface FIRWriteBatch () + +- (instancetype)initWithFirestore:(FIRFirestore *)firestore NS_DESIGNATED_INITIALIZER; + +@property(nonatomic, strong, readonly) FIRFirestore *firestore; +@property(nonatomic, assign) BOOL committed; + +@end + +@implementation FIRWriteBatch (Internal) + ++ (instancetype)writeBatchWithFirestore:(FIRFirestore *)firestore { + return [[FIRWriteBatch alloc] initWithFirestore:firestore]; +} + +@end + +@implementation FIRWriteBatch { + std::vector _mutations; +} + +- (instancetype)initWithFirestore:(FIRFirestore *)firestore { + self = [super init]; + if (self) { + _firestore = firestore; + } + return self; +} + +- (FIRWriteBatch *)setData:(NSDictionary *)data + forDocument:(FIRDocumentReference *)document { + return [self setData:data forDocument:document merge:NO]; +} + +- (FIRWriteBatch *)setData:(NSDictionary *)data + forDocument:(FIRDocumentReference *)document + merge:(BOOL)merge { + [self verifyNotCommitted]; + [self validateReference:document]; + + ParsedSetData parsed = merge ? [self.firestore.dataConverter parsedMergeData:data fieldMask:nil] + : [self.firestore.dataConverter parsedSetData:data]; + std::vector append_mutations = + std::move(parsed).ToMutations(document.key, Precondition::None()); + std::move(append_mutations.begin(), append_mutations.end(), std::back_inserter(_mutations)); + + return self; +} + +- (FIRWriteBatch *)setData:(NSDictionary *)data + forDocument:(FIRDocumentReference *)document + mergeFields:(NSArray *)mergeFields { + [self verifyNotCommitted]; + [self validateReference:document]; + + ParsedSetData parsed = [self.firestore.dataConverter parsedMergeData:data fieldMask:mergeFields]; + std::vector append_mutations = + std::move(parsed).ToMutations(document.key, Precondition::None()); + std::move(append_mutations.begin(), append_mutations.end(), std::back_inserter(_mutations)); + + return self; +} + +- (FIRWriteBatch *)updateData:(NSDictionary *)fields + forDocument:(FIRDocumentReference *)document { + [self verifyNotCommitted]; + [self validateReference:document]; + + ParsedUpdateData parsed = [self.firestore.dataConverter parsedUpdateData:fields]; + std::vector append_mutations = + std::move(parsed).ToMutations(document.key, Precondition::Exists(true)); + std::move(append_mutations.begin(), append_mutations.end(), std::back_inserter(_mutations)); + + return self; +} + +- (FIRWriteBatch *)deleteDocument:(FIRDocumentReference *)document { + [self verifyNotCommitted]; + [self validateReference:document]; + + _mutations.push_back([[FSTDeleteMutation alloc] initWithKey:document.key + precondition:Precondition::None()]); + ; + return self; +} + +- (void)commit { + [self commitWithCompletion:nil]; +} + +- (void)commitWithCompletion:(nullable void (^)(NSError *_Nullable error))completion { + [self verifyNotCommitted]; + self.committed = TRUE; + [self.firestore.client writeMutations:std::move(_mutations) completion:completion]; +} + +- (void)verifyNotCommitted { + if (self.committed) { + FSTThrowInvalidUsage(@"FIRIllegalStateException", + @"A write batch can no longer be used after commit has been called."); + } +} + +- (void)validateReference:(FIRDocumentReference *)reference { + if (reference.firestore != self.firestore) { + FSTThrowInvalidArgument(@"Provided document reference is from a different Firestore instance."); + } +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FSTFirestoreComponent.h b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FSTFirestoreComponent.h new file mode 100644 index 0000000..62446f0 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FSTFirestoreComponent.h @@ -0,0 +1,56 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#import + +@class FIRApp; +@class FIRFirestore; + +NS_ASSUME_NONNULL_BEGIN + +/// Provides and creates instances of Firestore based on a specific key. Used in the interop +/// registration process to keep track of instances for `FIRApp` instances. +@protocol FSTFirestoreMultiDBProvider + +/// Cached instances of Firestore objects. +@property(nonatomic, strong) NSMutableDictionary *instances; + +/// Default method for retrieving a Firestore instance, or creating one if it doesn't exist. +- (FIRFirestore *)firestoreForDatabase:(NSString *)database; + +@end + +/// A concrete implementation for FSTInstanceProvider to create Firestore instances and register +/// with Core's component system. +@interface FSTFirestoreComponent : NSObject + +/// The FIRApp that instances will be set up with. +@property(nonatomic, weak, readonly) FIRApp *app; + +/// Cached instances of Firestore objects. +@property(nonatomic, strong) NSMutableDictionary *instances; + +/// Default method for retrieving a Firestore instance, or creating one if it doesn't exist. +- (FIRFirestore *)firestoreForDatabase:(NSString *)database; + +/// Default initializer. +- (instancetype)initWithApp:(FIRApp *)app NS_DESIGNATED_INITIALIZER; + +- (instancetype)init NS_UNAVAILABLE; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FSTFirestoreComponent.mm b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FSTFirestoreComponent.mm new file mode 100644 index 0000000..2d676d9 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FSTFirestoreComponent.mm @@ -0,0 +1,148 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#import "Firestore/Source/API/FSTFirestoreComponent.h" + +#import +#import +#import +#import +#import +#import +#import + +#include +#include +#include + +#import "Firestore/Source/API/FIRFirestore+Internal.h" +#import "Firestore/Source/Util/FSTUsageValidation.h" +#include "Firestore/core/include/firebase/firestore/firestore_version.h" +#include "Firestore/core/src/firebase/firestore/api/firestore.h" +#include "Firestore/core/src/firebase/firestore/auth/credentials_provider.h" +#include "Firestore/core/src/firebase/firestore/auth/firebase_credentials_provider_apple.h" +#include "Firestore/core/src/firebase/firestore/util/async_queue.h" +#include "Firestore/core/src/firebase/firestore/util/executor_libdispatch.h" +#include "Firestore/core/src/firebase/firestore/util/hard_assert.h" +#include "absl/memory/memory.h" + +namespace util = firebase::firestore::util; +using firebase::firestore::api::Firestore; +using firebase::firestore::auth::CredentialsProvider; +using firebase::firestore::auth::FirebaseCredentialsProvider; +using util::AsyncQueue; +using util::ExecutorLibdispatch; + +NS_ASSUME_NONNULL_BEGIN + +@interface FSTFirestoreComponent () +@end + +@implementation FSTFirestoreComponent + +// Explicitly @synthesize because instances is part of the FSTInstanceProvider protocol. +@synthesize instances = _instances; + +#pragma mark - Initialization + +- (instancetype)initWithApp:(FIRApp *)app { + self = [super init]; + if (self) { + _instances = [[NSMutableDictionary alloc] init]; + + HARD_ASSERT(app, "Cannot initialize Firestore with a nil FIRApp."); + _app = app; + } + return self; +} + +#pragma mark - FSTInstanceProvider Conformance + +- (FIRFirestore *)firestoreForDatabase:(NSString *)database { + if (!database) { + FSTThrowInvalidArgument(@"database identifier may not be nil."); + } + + NSString *key = [NSString stringWithFormat:@"%@|%@", self.app.name, database]; + + // Get the component from the container. + @synchronized(self.instances) { + FIRFirestore *firestore = _instances[key]; + if (!firestore) { + std::string queue_name{"com.google.firebase.firestore"}; + if (!self.app.isDefaultApp) { + absl::StrAppend(&queue_name, ".", util::MakeString(self.app.name)); + } + + auto executor = absl::make_unique( + dispatch_queue_create(queue_name.c_str(), DISPATCH_QUEUE_SERIAL)); + auto workerQueue = absl::make_unique(std::move(executor)); + + id auth = FIR_COMPONENT(FIRAuthInterop, self.app.container); + auto credentialsProvider = absl::make_unique(self.app, auth); + + std::string projectID = util::MakeString(self.app.options.projectID); + std::string persistenceKey = util::MakeString(self.app.name); + firestore = [[FIRFirestore alloc] initWithProjectID:std::move(projectID) + database:util::MakeString(database) + persistenceKey:std::move(persistenceKey) + credentialsProvider:std::move(credentialsProvider) + workerQueue:std::move(workerQueue) + firebaseApp:self.app]; + _instances[key] = firestore; + } + + return firestore; + } +} + +#pragma mark - FIRComponentLifecycleMaintainer + +- (void)appWillBeDeleted:(FIRApp *)app { + // Stop any actions and clean up resources since instances of Firestore associated with this app + // will be removed. Currently does not do anything. +} + +#pragma mark - Object Lifecycle + ++ (void)load { + [FIRApp registerInternalLibrary:(Class)self + withName:@"fire-fst" + withVersion:[NSString stringWithUTF8String:firebase::firestore:: + kFirestoreVersionString]]; +} + +#pragma mark - Interoperability + ++ (NSArray *)componentsToRegister { + FIRDependency *auth = [FIRDependency dependencyWithProtocol:@protocol(FIRAuthInterop) + isRequired:NO]; + FIRComponent *firestoreProvider = [FIRComponent + componentWithProtocol:@protocol(FSTFirestoreMultiDBProvider) + instantiationTiming:FIRInstantiationTimingLazy + dependencies:@[ auth ] + creationBlock:^id _Nullable(FIRComponentContainer *container, BOOL *isCacheable) { + FSTFirestoreComponent *multiDBComponent = + [[FSTFirestoreComponent alloc] initWithApp:container.app]; + *isCacheable = YES; + return multiDBComponent; + }]; + return @[ firestoreProvider ]; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FSTUserDataConverter.h b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FSTUserDataConverter.h new file mode 100644 index 0000000..d5cf3ca --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FSTUserDataConverter.h @@ -0,0 +1,87 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +#include + +#include "Firestore/core/src/firebase/firestore/core/user_data.h" +#include "Firestore/core/src/firebase/firestore/model/database_id.h" +#include "Firestore/core/src/firebase/firestore/model/document_key.h" +#include "Firestore/core/src/firebase/firestore/model/field_mask.h" +#include "Firestore/core/src/firebase/firestore/model/field_transform.h" +#include "Firestore/core/src/firebase/firestore/model/precondition.h" + +@class FSTObjectValue; +@class FSTFieldValue; +@class FSTMutation; + +NS_ASSUME_NONNULL_BEGIN + +/** + * An internal representation of FIRDocumentReference, representing a key in a specific database. + * This is necessary because keys assume a database from context (usually the current one). + * FSTDocumentKeyReference binds a key to a specific databaseID. + * + * TODO(b/64160088): Make DocumentKey aware of the specific databaseID it is tied to. + */ +@interface FSTDocumentKeyReference : NSObject + +- (instancetype)init NS_UNAVAILABLE; + +- (instancetype)initWithKey:(firebase::firestore::model::DocumentKey)key + databaseID:(const firebase::firestore::model::DatabaseId *)databaseID + NS_DESIGNATED_INITIALIZER; + +- (const firebase::firestore::model::DocumentKey &)key; + +// Does not own the DatabaseId instance. +@property(nonatomic, assign, readonly) const firebase::firestore::model::DatabaseId *databaseID; + +@end + +/** + * An interface that allows arbitrary pre-converting of user data. + * + * Returns the converted value (can return back the input to act as a no-op). + */ +typedef id _Nullable (^FSTPreConverterBlock)(id _Nullable); + +/** + * Helper for parsing raw user input (provided via the API) into internal model classes. + */ +@interface FSTUserDataConverter : NSObject + +- (instancetype)init NS_UNAVAILABLE; +- (instancetype)initWithDatabaseID:(const firebase::firestore::model::DatabaseId *)databaseID + preConverter:(FSTPreConverterBlock)preConverter NS_DESIGNATED_INITIALIZER; + +/** Parse document data from a non-merge setData call.*/ +- (firebase::firestore::core::ParsedSetData)parsedSetData:(id)input; + +/** Parse document data from a setData call with `merge:YES`. */ +- (firebase::firestore::core::ParsedSetData)parsedMergeData:(id)input + fieldMask:(nullable NSArray *)fieldMask; + +/** Parse update data from an updateData call. */ +- (firebase::firestore::core::ParsedUpdateData)parsedUpdateData:(id)input; + +/** Parse a "query value" (e.g. value in a where filter or a value in a cursor bound). */ +- (FSTFieldValue *)parsedQueryValue:(id)input; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FSTUserDataConverter.mm b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FSTUserDataConverter.mm new file mode 100644 index 0000000..0f0abd8 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/API/FSTUserDataConverter.mm @@ -0,0 +1,497 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "Firestore/Source/API/FSTUserDataConverter.h" + +#include +#include +#include +#include +#include + +#import "FIRGeoPoint.h" +#import "FIRTimestamp.h" + +#import "Firestore/Source/API/FIRDocumentReference+Internal.h" +#import "Firestore/Source/API/FIRFieldPath+Internal.h" +#import "Firestore/Source/API/FIRFieldValue+Internal.h" +#import "Firestore/Source/API/FIRFirestore+Internal.h" +#import "Firestore/Source/Model/FSTFieldValue.h" +#import "Firestore/Source/Model/FSTMutation.h" +#import "Firestore/Source/Util/FSTUsageValidation.h" + +#include "Firestore/core/src/firebase/firestore/core/user_data.h" +#include "Firestore/core/src/firebase/firestore/model/database_id.h" +#include "Firestore/core/src/firebase/firestore/model/document_key.h" +#include "Firestore/core/src/firebase/firestore/model/field_mask.h" +#include "Firestore/core/src/firebase/firestore/model/field_path.h" +#include "Firestore/core/src/firebase/firestore/model/field_transform.h" +#include "Firestore/core/src/firebase/firestore/model/precondition.h" +#include "Firestore/core/src/firebase/firestore/model/transform_operations.h" +#include "Firestore/core/src/firebase/firestore/util/hard_assert.h" +#include "Firestore/core/src/firebase/firestore/util/string_apple.h" +#include "absl/memory/memory.h" +#include "absl/strings/match.h" + +namespace util = firebase::firestore::util; +using firebase::firestore::core::ParsedSetData; +using firebase::firestore::core::ParsedUpdateData; +using firebase::firestore::core::ParseAccumulator; +using firebase::firestore::core::ParseContext; +using firebase::firestore::core::UserDataSource; +using firebase::firestore::model::ArrayTransform; +using firebase::firestore::model::DatabaseId; +using firebase::firestore::model::DocumentKey; +using firebase::firestore::model::FieldMask; +using firebase::firestore::model::FieldPath; +using firebase::firestore::model::FieldTransform; +using firebase::firestore::model::NumericIncrementTransform; +using firebase::firestore::model::Precondition; +using firebase::firestore::model::ServerTimestampTransform; +using firebase::firestore::model::TransformOperation; + +NS_ASSUME_NONNULL_BEGIN + +#pragma mark - FSTDocumentKeyReference + +@implementation FSTDocumentKeyReference { + DocumentKey _key; +} + +- (instancetype)initWithKey:(DocumentKey)key databaseID:(const DatabaseId *)databaseID { + self = [super init]; + if (self) { + _key = std::move(key); + _databaseID = databaseID; + } + return self; +} + +- (const firebase::firestore::model::DocumentKey &)key { + return _key; +} + +@end + +#pragma mark - FSTUserDataConverter + +@interface FSTUserDataConverter () +// Does not own the DatabaseId instance. +@property(assign, nonatomic, readonly) const DatabaseId *databaseID; +@property(strong, nonatomic, readonly) FSTPreConverterBlock preConverter; +@end + +@implementation FSTUserDataConverter + +- (instancetype)initWithDatabaseID:(const DatabaseId *)databaseID + preConverter:(FSTPreConverterBlock)preConverter { + self = [super init]; + if (self) { + _databaseID = databaseID; + _preConverter = preConverter; + } + return self; +} + +- (ParsedSetData)parsedSetData:(id)input { + // NOTE: The public API is typed as NSDictionary but we type 'input' as 'id' since we can't trust + // Obj-C to verify the type for us. + if (![input isKindOfClass:[NSDictionary class]]) { + FSTThrowInvalidArgument(@"Data to be written must be an NSDictionary."); + } + + ParseAccumulator accumulator{UserDataSource::Set}; + FSTFieldValue *updateData = [self parseData:input context:accumulator.RootContext()]; + + return std::move(accumulator).SetData((FSTObjectValue *)updateData); +} + +- (ParsedSetData)parsedMergeData:(id)input fieldMask:(nullable NSArray *)fieldMask { + // NOTE: The public API is typed as NSDictionary but we type 'input' as 'id' since we can't trust + // Obj-C to verify the type for us. + if (![input isKindOfClass:[NSDictionary class]]) { + FSTThrowInvalidArgument(@"Data to be written must be an NSDictionary."); + } + + ParseAccumulator accumulator{UserDataSource::MergeSet}; + + FSTObjectValue *updateData = (FSTObjectValue *)[self parseData:input + context:accumulator.RootContext()]; + + if (fieldMask) { + std::set validatedFieldPaths; + for (id fieldPath in fieldMask) { + FieldPath path; + + if ([fieldPath isKindOfClass:[NSString class]]) { + path = [FIRFieldPath pathWithDotSeparatedString:fieldPath].internalValue; + } else if ([fieldPath isKindOfClass:[FIRFieldPath class]]) { + path = ((FIRFieldPath *)fieldPath).internalValue; + } else { + FSTThrowInvalidArgument( + @"All elements in mergeFields: must be NSStrings or FIRFieldPaths."); + } + + // Verify that all elements specified in the field mask are part of the parsed context. + if (!accumulator.Contains(path)) { + FSTThrowInvalidArgument( + @"Field '%s' is specified in your field mask but missing from your input data.", + path.CanonicalString().c_str()); + } + + validatedFieldPaths.insert(path); + } + + return std::move(accumulator).MergeData(updateData, FieldMask{std::move(validatedFieldPaths)}); + + } else { + return std::move(accumulator).MergeData(updateData); + } +} + +- (ParsedUpdateData)parsedUpdateData:(id)input { + // NOTE: The public API is typed as NSDictionary but we type 'input' as 'id' since we can't trust + // Obj-C to verify the type for us. + if (![input isKindOfClass:[NSDictionary class]]) { + FSTThrowInvalidArgument(@"Data to be written must be an NSDictionary."); + } + + NSDictionary *dict = input; + + ParseAccumulator accumulator{UserDataSource::Update}; + __block ParseContext context = accumulator.RootContext(); + __block FSTObjectValue *updateData = [FSTObjectValue objectValue]; + + [dict enumerateKeysAndObjectsUsingBlock:^(id key, id value, BOOL *stop) { + FieldPath path; + + if ([key isKindOfClass:[NSString class]]) { + path = [FIRFieldPath pathWithDotSeparatedString:key].internalValue; + } else if ([key isKindOfClass:[FIRFieldPath class]]) { + path = ((FIRFieldPath *)key).internalValue; + } else { + FSTThrowInvalidArgument( + @"Dictionary keys in updateData: must be NSStrings or FIRFieldPaths."); + } + + value = self.preConverter(value); + if ([value isKindOfClass:[FSTDeleteFieldValue class]]) { + // Add it to the field mask, but don't add anything to updateData. + context.AddToFieldMask(std::move(path)); + } else { + FSTFieldValue *_Nullable parsedValue = [self parseData:value + context:context.ChildContext(path)]; + if (parsedValue) { + context.AddToFieldMask(path); + updateData = [updateData objectBySettingValue:parsedValue forPath:path]; + } + } + }]; + + return std::move(accumulator).UpdateData(updateData); +} + +- (FSTFieldValue *)parsedQueryValue:(id)input { + ParseAccumulator accumulator{UserDataSource::Argument}; + + FSTFieldValue *_Nullable parsed = [self parseData:input context:accumulator.RootContext()]; + HARD_ASSERT(parsed, "Parsed data should not be nil."); + HARD_ASSERT(accumulator.field_transforms().empty(), + "Field transforms should have been disallowed."); + return parsed; +} + +/** + * Internal helper for parsing user data. + * + * @param input Data to be parsed. + * @param context A context object representing the current path being parsed, the source of the + * data being parsed, etc. + * + * @return The parsed value, or nil if the value was a FieldValue sentinel that should not be + * included in the resulting parsed data. + */ +- (nullable FSTFieldValue *)parseData:(id)input context:(ParseContext &&)context { + input = self.preConverter(input); + if ([input isKindOfClass:[NSDictionary class]]) { + return [self parseDictionary:(NSDictionary *)input context:std::move(context)]; + + } else if ([input isKindOfClass:[FIRFieldValue class]]) { + // FieldValues usually parse into transforms (except FieldValue.delete()) in which case we + // do not want to include this field in our parsed data (as doing so will overwrite the field + // directly prior to the transform trying to transform it). So we don't call appendToFieldMask + // and we return nil as our parsing result. + [self parseSentinelFieldValue:(FIRFieldValue *)input context:std::move(context)]; + return nil; + + } else { + // If context path is unset we are already inside an array and we don't support field mask paths + // more granular than the top-level array. + if (context.path()) { + context.AddToFieldMask(*context.path()); + } + + if ([input isKindOfClass:[NSArray class]]) { + // TODO(b/34871131): Include the path containing the array in the error message. + if (context.array_element()) { + FSTThrowInvalidArgument(@"Nested arrays are not supported"); + } + return [self parseArray:(NSArray *)input context:std::move(context)]; + } else { + return [self parseScalarValue:input context:std::move(context)]; + } + } +} + +- (FSTFieldValue *)parseDictionary:(NSDictionary *)dict context:(ParseContext &&)context { + NSMutableDictionary *result = + [NSMutableDictionary dictionaryWithCapacity:dict.count]; + + if ([dict count] == 0) { + const FieldPath *path = context.path(); + if (path && !path->empty()) { + context.AddToFieldMask(*path); + } + return [FSTObjectValue objectValue]; + } else { + [dict enumerateKeysAndObjectsUsingBlock:^(NSString *key, id value, BOOL *stop) { + FSTFieldValue *_Nullable parsedValue = + [self parseData:value context:context.ChildContext(util::MakeString(key))]; + if (parsedValue) { + result[key] = parsedValue; + } + }]; + } + return [[FSTObjectValue alloc] initWithDictionary:result]; +} + +- (FSTFieldValue *)parseArray:(NSArray *)array context:(ParseContext &&)context { + NSMutableArray *result = [NSMutableArray arrayWithCapacity:array.count]; + [array enumerateObjectsUsingBlock:^(id entry, NSUInteger idx, BOOL *stop) { + FSTFieldValue *_Nullable parsedEntry = [self parseData:entry context:context.ChildContext(idx)]; + if (!parsedEntry) { + // Just include nulls in the array for fields being replaced with a sentinel. + parsedEntry = [FSTNullValue nullValue]; + } + [result addObject:parsedEntry]; + }]; + return [[FSTArrayValue alloc] initWithValueNoCopy:result]; +} + +/** + * "Parses" the provided FIRFieldValue, adding any necessary transforms to + * context.fieldTransforms. + */ +- (void)parseSentinelFieldValue:(FIRFieldValue *)fieldValue context:(ParseContext &&)context { + // Sentinels are only supported with writes, and not within arrays. + if (!context.write()) { + FSTThrowInvalidArgument(@"%@ can only be used with updateData() and setData()%s", + fieldValue.methodName, context.FieldDescription().c_str()); + } + if (!context.path()) { + FSTThrowInvalidArgument(@"%@ is not currently supported inside arrays", fieldValue.methodName); + } + + if ([fieldValue isKindOfClass:[FSTDeleteFieldValue class]]) { + if (context.data_source() == UserDataSource::MergeSet) { + // No transform to add for a delete, but we need to add it to our fieldMask so it gets + // deleted. + context.AddToFieldMask(*context.path()); + + } else if (context.data_source() == UserDataSource::Update) { + HARD_ASSERT(context.path()->size() > 0, + "FieldValue.delete() at the top level should have already been handled."); + FSTThrowInvalidArgument(@"FieldValue.delete() can only appear at the top level of your " + "update data%s", + context.FieldDescription().c_str()); + } else { + // We shouldn't encounter delete sentinels for queries or non-merge setData calls. + FSTThrowInvalidArgument( + @"FieldValue.delete() can only be used with updateData() and setData() with " + @"merge:true%s", + context.FieldDescription().c_str()); + } + + } else if ([fieldValue isKindOfClass:[FSTServerTimestampFieldValue class]]) { + context.AddToFieldTransforms(*context.path(), absl::make_unique( + ServerTimestampTransform::Get())); + + } else if ([fieldValue isKindOfClass:[FSTArrayUnionFieldValue class]]) { + std::vector parsedElements = + [self parseArrayTransformElements:((FSTArrayUnionFieldValue *)fieldValue).elements]; + auto array_union = absl::make_unique(TransformOperation::Type::ArrayUnion, + std::move(parsedElements)); + context.AddToFieldTransforms(*context.path(), std::move(array_union)); + + } else if ([fieldValue isKindOfClass:[FSTArrayRemoveFieldValue class]]) { + std::vector parsedElements = + [self parseArrayTransformElements:((FSTArrayRemoveFieldValue *)fieldValue).elements]; + auto array_remove = absl::make_unique(TransformOperation::Type::ArrayRemove, + std::move(parsedElements)); + context.AddToFieldTransforms(*context.path(), std::move(array_remove)); + + } else if ([fieldValue isKindOfClass:[FSTNumericIncrementFieldValue class]]) { + FSTNumericIncrementFieldValue *numericIncrementFieldValue = + (FSTNumericIncrementFieldValue *)fieldValue; + FSTNumberValue *operand = + (FSTNumberValue *)[self parsedQueryValue:numericIncrementFieldValue.operand]; + auto numeric_increment = absl::make_unique(operand); + + context.AddToFieldTransforms(*context.path(), std::move(numeric_increment)); + + } else { + HARD_FAIL("Unknown FIRFieldValue type: %s", NSStringFromClass([fieldValue class])); + } +} + +/** + * Helper to parse a scalar value (i.e. not an NSDictionary, NSArray, or FIRFieldValue). + * + * Note that it handles all NSNumber values that are encodable as int64_t or doubles + * (depending on the underlying type of the NSNumber). Unsigned integer values are handled though + * any value outside what is representable by int64_t (a signed 64-bit value) will throw an + * exception. + * + * @return The parsed value. + */ +- (nullable FSTFieldValue *)parseScalarValue:(nullable id)input context:(ParseContext &&)context { + if (!input || [input isMemberOfClass:[NSNull class]]) { + return [FSTNullValue nullValue]; + + } else if ([input isKindOfClass:[NSNumber class]]) { + // Recover the underlying type of the number, using the method described here: + // http://stackoverflow.com/questions/2518761/get-type-of-nsnumber + const char *cType = [input objCType]; + + // Type Encoding values taken from + // https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ObjCRuntimeGuide/ + // Articles/ocrtTypeEncodings.html + switch (cType[0]) { + case 'q': + return [FSTIntegerValue integerValue:[input longLongValue]]; + + case 'i': // Falls through. + case 's': // Falls through. + case 'l': // Falls through. + case 'I': // Falls through. + case 'S': + // Coerce integer values that aren't long long. Allow unsigned integer types that are + // guaranteed small enough to skip a length check. + return [FSTIntegerValue integerValue:[input longLongValue]]; + + case 'L': // Falls through. + case 'Q': + // Unsigned integers that could be too large. Note that the 'L' (long) case is handled here + // because when compiled for LP64, unsigned long is 64 bits and could overflow int64_t. + { + unsigned long long extended = [input unsignedLongLongValue]; + + if (extended > LLONG_MAX) { + FSTThrowInvalidArgument(@"NSNumber (%llu) is too large%s", + [input unsignedLongLongValue], + context.FieldDescription().c_str()); + + } else { + return [FSTIntegerValue integerValue:(int64_t)extended]; + } + } + + case 'f': + return [FSTDoubleValue doubleValue:[input doubleValue]]; + + case 'd': + // Double values are already the right type, so just reuse the existing boxed double. + // + // Note that NSNumber already performs NaN normalization to a single shared instance + // so there's no need to treat NaN specially here. + return [FSTDoubleValue doubleValue:[input doubleValue]]; + + case 'B': // Falls through. + case 'c': // Falls through. + case 'C': + // Boolean values are weird. + // + // On arm64, objCType of a BOOL-valued NSNumber will be "c", even though @encode(BOOL) + // returns "B". "c" is the same as @encode(signed char). Unfortunately this means that + // legitimate usage of signed chars is impossible, but this should be rare. + // + // Additionally, for consistency, map unsigned chars to bools in the same way. + return [FSTBooleanValue booleanValue:[input boolValue]]; + + default: + // All documented codes should be handled above, so this shouldn't happen. + HARD_FAIL("Unknown NSNumber objCType %s on %s", cType, input); + } + + } else if ([input isKindOfClass:[NSString class]]) { + return [FSTStringValue stringValue:input]; + + } else if ([input isKindOfClass:[NSDate class]]) { + return [FSTTimestampValue timestampValue:[FIRTimestamp timestampWithDate:input]]; + + } else if ([input isKindOfClass:[FIRTimestamp class]]) { + FIRTimestamp *originalTimestamp = (FIRTimestamp *)input; + FIRTimestamp *truncatedTimestamp = + [FIRTimestamp timestampWithSeconds:originalTimestamp.seconds + nanoseconds:originalTimestamp.nanoseconds / 1000 * 1000]; + return [FSTTimestampValue timestampValue:truncatedTimestamp]; + + } else if ([input isKindOfClass:[FIRGeoPoint class]]) { + return [FSTGeoPointValue geoPointValue:input]; + + } else if ([input isKindOfClass:[NSData class]]) { + return [FSTBlobValue blobValue:input]; + + } else if ([input isKindOfClass:[FSTDocumentKeyReference class]]) { + FSTDocumentKeyReference *reference = input; + if (*reference.databaseID != *self.databaseID) { + const DatabaseId *other = reference.databaseID; + FSTThrowInvalidArgument( + @"Document Reference is for database %s/%s but should be for database %s/%s%s", + other->project_id().c_str(), other->database_id().c_str(), + self.databaseID->project_id().c_str(), self.databaseID->database_id().c_str(), + context.FieldDescription().c_str()); + } + return [FSTReferenceValue referenceValue:[FSTDocumentKey keyWithDocumentKey:reference.key] + databaseID:self.databaseID]; + + } else { + FSTThrowInvalidArgument(@"Unsupported type: %@%s", NSStringFromClass([input class]), + context.FieldDescription().c_str()); + } +} + +- (std::vector)parseArrayTransformElements:(NSArray *)elements { + ParseAccumulator accumulator{UserDataSource::Argument}; + + std::vector values; + for (NSUInteger i = 0; i < elements.count; i++) { + id element = elements[i]; + // Although array transforms are used with writes, the actual elements being unioned or removed + // are not considered writes since they cannot contain any FieldValue sentinels, etc. + ParseContext context = accumulator.RootContext(); + + FSTFieldValue *parsedElement = [self parseData:element context:context.ChildContext(i)]; + HARD_ASSERT(parsedElement && accumulator.field_transforms().size() == 0, + "Failed to properly parse array transform element: %s", element); + values.push_back(parsedElement); + } + return values; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Core/FSTEventManager.h b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Core/FSTEventManager.h new file mode 100644 index 0000000..c3d9639 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Core/FSTEventManager.h @@ -0,0 +1,52 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +#include + +#include "Firestore/core/src/firebase/firestore/core/query_listener.h" +#include "Firestore/core/src/firebase/firestore/core/view_snapshot.h" +#include "Firestore/core/src/firebase/firestore/model/types.h" +#include "Firestore/core/src/firebase/firestore/util/status.h" + +@class FSTQuery; +@class FSTSyncEngine; + +NS_ASSUME_NONNULL_BEGIN + +using firebase::firestore::core::QueryListener; + +#pragma mark - FSTEventManager + +/** + * EventManager is responsible for mapping queries to query event emitters. It handles "fan-out." + * (Identical queries will re-use the same watch on the backend.) + */ +@interface FSTEventManager : NSObject + ++ (instancetype)eventManagerWithSyncEngine:(FSTSyncEngine *)syncEngine; + +- (instancetype)init __attribute__((unavailable("Use static constructor method."))); + +- (firebase::firestore::model::TargetId)addListener:(std::shared_ptr)listener; +- (void)removeListener:(const std::shared_ptr &)listener; + +- (void)applyChangedOnlineState:(firebase::firestore::model::OnlineState)onlineState; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Core/FSTEventManager.mm b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Core/FSTEventManager.mm new file mode 100644 index 0000000..93f5999 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Core/FSTEventManager.mm @@ -0,0 +1,185 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "Firestore/Source/Core/FSTEventManager.h" + +#include +#include +#include + +#import "Firestore/Source/Core/FSTQuery.h" +#import "Firestore/Source/Core/FSTSyncEngine.h" + +#include "Firestore/core/src/firebase/firestore/model/document_set.h" +#include "Firestore/core/src/firebase/firestore/util/error_apple.h" +#include "Firestore/core/src/firebase/firestore/util/hard_assert.h" +#include "Firestore/core/src/firebase/firestore/util/objc_compatibility.h" +#include "Firestore/core/src/firebase/firestore/util/status.h" +#include "absl/algorithm/container.h" +#include "absl/types/optional.h" + +NS_ASSUME_NONNULL_BEGIN + +namespace objc = firebase::firestore::util::objc; +using firebase::firestore::core::DocumentViewChange; +using firebase::firestore::core::ViewSnapshot; +using firebase::firestore::model::OnlineState; +using firebase::firestore::model::TargetId; +using firebase::firestore::util::MakeStatus; +using firebase::firestore::util::Status; + +#pragma mark - FSTQueryListenersInfo + +namespace { + +/** + * Holds the listeners and the last received ViewSnapshot for a query being tracked by + * EventManager. + */ +struct QueryListenersInfo { + TargetId target_id; + std::vector> listeners; + + void Erase(const std::shared_ptr &listener) { + auto found = absl::c_find(listeners, listener); + if (found != listeners.end()) { + listeners.erase(found); + } + } + + const absl::optional &view_snapshot() const { + return snapshot_; + } + + void set_view_snapshot(const absl::optional &snapshot) { + snapshot_ = snapshot; + } + + private: + // Other members are public in this struct, ensure that any reads are + // copies by requiring reads to go through a const getter. + absl::optional snapshot_; +}; + +} // namespace + +#pragma mark - FSTEventManager + +@interface FSTEventManager () + +- (instancetype)initWithSyncEngine:(FSTSyncEngine *)syncEngine NS_DESIGNATED_INITIALIZER; + +@property(nonatomic, strong, readonly) FSTSyncEngine *syncEngine; +@property(nonatomic, assign) OnlineState onlineState; + +@end + +@implementation FSTEventManager { + objc::unordered_map _queries; +} + ++ (instancetype)eventManagerWithSyncEngine:(FSTSyncEngine *)syncEngine { + return [[FSTEventManager alloc] initWithSyncEngine:syncEngine]; +} + +- (instancetype)initWithSyncEngine:(FSTSyncEngine *)syncEngine { + if (self = [super init]) { + _syncEngine = syncEngine; + _syncEngine.syncEngineDelegate = self; + } + return self; +} + +- (TargetId)addListener:(std::shared_ptr)listener { + FSTQuery *query = listener->query(); + + auto inserted = _queries.emplace(query, QueryListenersInfo{}); + bool first_listen = inserted.second; + QueryListenersInfo &query_info = inserted.first->second; + + query_info.listeners.push_back(listener); + + listener->OnOnlineStateChanged(self.onlineState); + + if (query_info.view_snapshot().has_value()) { + listener->OnViewSnapshot(query_info.view_snapshot().value()); + } + + if (first_listen) { + query_info.target_id = [self.syncEngine listenToQuery:query]; + } + return query_info.target_id; +} + +- (void)removeListener:(const std::shared_ptr &)listener { + FSTQuery *query = listener->query(); + bool last_listen = false; + + auto found_iter = _queries.find(query); + if (found_iter != _queries.end()) { + QueryListenersInfo &query_info = found_iter->second; + query_info.Erase(listener); + last_listen = query_info.listeners.empty(); + } + + if (last_listen) { + _queries.erase(found_iter); + [self.syncEngine stopListeningToQuery:query]; + } +} + +- (void)handleViewSnapshots:(std::vector &&)viewSnapshots { + for (ViewSnapshot &viewSnapshot : viewSnapshots) { + FSTQuery *query = viewSnapshot.query(); + auto found_iter = _queries.find(query); + if (found_iter != _queries.end()) { + QueryListenersInfo &query_info = found_iter->second; + for (const auto &listener : query_info.listeners) { + listener->OnViewSnapshot(viewSnapshot); + } + query_info.set_view_snapshot(std::move(viewSnapshot)); + } + } +} + +- (void)handleError:(NSError *)error forQuery:(FSTQuery *)query { + auto found_iter = _queries.find(query); + if (found_iter != _queries.end()) { + QueryListenersInfo &query_info = found_iter->second; + for (const auto &listener : query_info.listeners) { + listener->OnError(MakeStatus(error)); + } + + // Remove all listeners. NOTE: We don't need to call [FSTSyncEngine stopListening] after an + // error. + _queries.erase(found_iter); + } +} + +- (void)applyChangedOnlineState:(OnlineState)onlineState { + self.onlineState = onlineState; + + for (auto &&kv : _queries) { + QueryListenersInfo &info = kv.second; + for (auto &&listener : info.listeners) { + listener->OnOnlineStateChanged(onlineState); + } + } +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Core/FSTFirestoreClient.h b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Core/FSTFirestoreClient.h new file mode 100644 index 0000000..8d4c4cf --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Core/FSTFirestoreClient.h @@ -0,0 +1,133 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +#include +#include + +#import "Firestore/Source/Core/FSTTypes.h" + +#include "Firestore/core/src/firebase/firestore/api/document_reference.h" +#include "Firestore/core/src/firebase/firestore/api/document_snapshot.h" +#include "Firestore/core/src/firebase/firestore/auth/credentials_provider.h" +#include "Firestore/core/src/firebase/firestore/core/database_info.h" +#include "Firestore/core/src/firebase/firestore/core/listen_options.h" +#include "Firestore/core/src/firebase/firestore/core/query_listener.h" +#include "Firestore/core/src/firebase/firestore/core/view_snapshot.h" +#include "Firestore/core/src/firebase/firestore/model/database_id.h" +#include "Firestore/core/src/firebase/firestore/util/async_queue.h" +#include "Firestore/core/src/firebase/firestore/util/executor.h" +#include "Firestore/core/src/firebase/firestore/util/statusor_callback.h" + +@class FIRDocumentReference; +@class FIRDocumentSnapshot; +@class FIRFirestoreSettings; +@class FIRQuery; +@class FIRQuerySnapshot; +@class FSTDatabaseID; +@class FSTDatabaseInfo; +@class FSTDocument; +@class FSTMutation; +@class FSTQuery; +@class FSTTransaction; + +NS_ASSUME_NONNULL_BEGIN + +using firebase::firestore::api::DocumentSnapshot; +using firebase::firestore::core::ListenOptions; +using firebase::firestore::core::QueryListener; +using firebase::firestore::core::ViewSnapshot; + +/** + * FirestoreClient is a top-level class that constructs and owns all of the pieces of the client + * SDK architecture. It is responsible for creating the worker queue that is shared by all of the + * other components in the system. + */ +@interface FSTFirestoreClient : NSObject + +/** + * Creates and returns a FSTFirestoreClient with the given parameters. + * + * All callbacks and events will be triggered on the provided userExecutor. + */ ++ (instancetype) + clientWithDatabaseInfo:(const firebase::firestore::core::DatabaseInfo &)databaseInfo + settings:(FIRFirestoreSettings *)settings + credentialsProvider:(firebase::firestore::auth::CredentialsProvider *) + credentialsProvider // no passing ownership + userExecutor:(std::unique_ptr)userExecutor + workerQueue:(std::unique_ptr)workerQueue; + +- (instancetype)init __attribute__((unavailable("Use static constructor method."))); + +/** Shuts down this client, cancels all writes / listeners, and releases all resources. */ +- (void)shutdownWithCompletion:(nullable FSTVoidErrorBlock)completion; + +/** Disables the network connection. Pending operations will not complete. */ +- (void)disableNetworkWithCompletion:(nullable FSTVoidErrorBlock)completion; + +/** Enables the network connection and requeues all pending operations. */ +- (void)enableNetworkWithCompletion:(nullable FSTVoidErrorBlock)completion; + +/** Starts listening to a query. */ +- (std::shared_ptr)listenToQuery:(FSTQuery *)query + options:(ListenOptions)options + listener:(ViewSnapshot::SharedListener &&)listener; + +/** Stops listening to a query previously listened to. */ +- (void)removeListener:(const std::shared_ptr &)listener; + +/** + * Retrieves a document from the cache via the indicated completion. If the doc + * doesn't exist, an error will be sent to the completion. + */ +- (void)getDocumentFromLocalCache:(const firebase::firestore::api::DocumentReference &)doc + completion:(DocumentSnapshot::Listener &&)completion; + +/** + * Retrieves a (possibly empty) set of documents from the cache via the + * indicated completion. + */ +- (void)getDocumentsFromLocalCache:(FIRQuery *)query + completion:(void (^)(FIRQuerySnapshot *_Nullable query, + NSError *_Nullable error))completion; + +/** Write mutations. completion will be notified when it's written to the backend. */ +- (void)writeMutations:(std::vector &&)mutations + completion:(nullable FSTVoidErrorBlock)completion; + +/** Tries to execute the transaction in updateBlock up to retries times. */ +- (void)transactionWithRetries:(int)retries + updateBlock:(FSTTransactionBlock)updateBlock + completion:(FSTVoidIDErrorBlock)completion; + +/** The database ID of the databaseInfo this client was initialized with. */ +// Ownes a DatabaseInfo instance, which contains the id here. +@property(nonatomic, assign, readonly) const firebase::firestore::model::DatabaseId *databaseID; + +/** + * Dispatch queue for user callbacks / events. This will often be the "Main Dispatch Queue" of the + * app but the developer can configure it to a different queue if they so choose. + */ +- (firebase::firestore::util::Executor *)userExecutor; + +/** For testing only. */ +- (firebase::firestore::util::AsyncQueue *)workerQueue; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Core/FSTFirestoreClient.mm b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Core/FSTFirestoreClient.mm new file mode 100644 index 0000000..de03ebe --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Core/FSTFirestoreClient.mm @@ -0,0 +1,432 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "Firestore/Source/Core/FSTFirestoreClient.h" + +#include // NOLINT(build/c++11) +#include // NOLINT(build/c++11) +#include +#include + +#import "FIRFirestoreErrors.h" +#import "FIRFirestoreSettings.h" +#import "Firestore/Source/API/FIRDocumentReference+Internal.h" +#import "Firestore/Source/API/FIRDocumentSnapshot+Internal.h" +#import "Firestore/Source/API/FIRFirestore+Internal.h" +#import "Firestore/Source/API/FIRQuery+Internal.h" +#import "Firestore/Source/API/FIRQuerySnapshot+Internal.h" +#import "Firestore/Source/API/FIRSnapshotMetadata+Internal.h" +#import "Firestore/Source/Core/FSTEventManager.h" +#import "Firestore/Source/Core/FSTQuery.h" +#import "Firestore/Source/Core/FSTSyncEngine.h" +#import "Firestore/Source/Core/FSTView.h" +#import "Firestore/Source/Local/FSTLRUGarbageCollector.h" +#import "Firestore/Source/Local/FSTLevelDB.h" +#import "Firestore/Source/Local/FSTLocalSerializer.h" +#import "Firestore/Source/Local/FSTLocalStore.h" +#import "Firestore/Source/Local/FSTMemoryPersistence.h" +#import "Firestore/Source/Model/FSTDocument.h" +#import "Firestore/Source/Remote/FSTSerializerBeta.h" +#import "Firestore/Source/Util/FSTClasses.h" + +#include "Firestore/core/src/firebase/firestore/auth/credentials_provider.h" +#include "Firestore/core/src/firebase/firestore/core/database_info.h" +#include "Firestore/core/src/firebase/firestore/model/database_id.h" +#include "Firestore/core/src/firebase/firestore/model/document_set.h" +#include "Firestore/core/src/firebase/firestore/remote/datastore.h" +#include "Firestore/core/src/firebase/firestore/remote/remote_store.h" +#include "Firestore/core/src/firebase/firestore/util/async_queue.h" +#include "Firestore/core/src/firebase/firestore/util/hard_assert.h" +#include "Firestore/core/src/firebase/firestore/util/log.h" +#include "Firestore/core/src/firebase/firestore/util/status.h" +#include "Firestore/core/src/firebase/firestore/util/statusor.h" +#include "Firestore/core/src/firebase/firestore/util/string_apple.h" +#include "absl/memory/memory.h" + +namespace util = firebase::firestore::util; +using firebase::firestore::FirestoreErrorCode; +using firebase::firestore::api::DocumentReference; +using firebase::firestore::api::DocumentSnapshot; +using firebase::firestore::auth::CredentialsProvider; +using firebase::firestore::auth::User; +using firebase::firestore::core::DatabaseInfo; +using firebase::firestore::core::ViewSnapshot; +using firebase::firestore::local::LruParams; +using firebase::firestore::model::DatabaseId; +using firebase::firestore::model::DocumentKeySet; +using firebase::firestore::model::DocumentMap; +using firebase::firestore::model::MaybeDocumentMap; +using firebase::firestore::model::OnlineState; +using firebase::firestore::remote::Datastore; +using firebase::firestore::remote::RemoteStore; +using firebase::firestore::util::Path; +using firebase::firestore::util::Status; +using firebase::firestore::util::AsyncQueue; +using firebase::firestore::util::DelayedOperation; +using firebase::firestore::util::Executor; +using firebase::firestore::util::Status; +using firebase::firestore::util::StatusOr; +using firebase::firestore::util::StatusOrCallback; +using firebase::firestore::util::TimerId; + +NS_ASSUME_NONNULL_BEGIN + +/** How long we wait to try running LRU GC after SDK initialization. */ +static const std::chrono::milliseconds FSTLruGcInitialDelay = std::chrono::minutes(1); +/** Minimum amount of time between GC checks, after the first one. */ +static const std::chrono::milliseconds FSTLruGcRegularDelay = std::chrono::minutes(5); + +@interface FSTFirestoreClient () { + DatabaseInfo _databaseInfo; +} + +- (instancetype)initWithDatabaseInfo:(const DatabaseInfo &)databaseInfo + settings:(FIRFirestoreSettings *)settings + credentialsProvider: + (CredentialsProvider *)credentialsProvider // no passing ownership + userExecutor:(std::unique_ptr)userExecutor + workerQueue:(std::unique_ptr)queue NS_DESIGNATED_INITIALIZER; + +@property(nonatomic, assign, readonly) const DatabaseInfo *databaseInfo; +@property(nonatomic, strong, readonly) FSTEventManager *eventManager; +@property(nonatomic, strong, readonly) id persistence; +@property(nonatomic, strong, readonly) FSTSyncEngine *syncEngine; +@property(nonatomic, strong, readonly) FSTLocalStore *localStore; + +// Does not own the CredentialsProvider instance. +@property(nonatomic, assign, readonly) CredentialsProvider *credentialsProvider; + +@end + +@implementation FSTFirestoreClient { + /** + * Async queue responsible for all of our internal processing. When we get incoming work from + * the user (via public API) or the network (incoming gRPC messages), we should always dispatch + * onto this queue. This ensures our internal data structures are never accessed from multiple + * threads simultaneously. + */ + std::unique_ptr _workerQueue; + + std::unique_ptr _remoteStore; + + std::unique_ptr _userExecutor; + std::chrono::milliseconds _initialGcDelay; + std::chrono::milliseconds _regularGcDelay; + BOOL _gcHasRun; + _Nullable id _lruDelegate; + DelayedOperation _lruCallback; +} + +- (Executor *)userExecutor { + return _userExecutor.get(); +} + +- (AsyncQueue *)workerQueue { + return _workerQueue.get(); +} + ++ (instancetype)clientWithDatabaseInfo:(const DatabaseInfo &)databaseInfo + settings:(FIRFirestoreSettings *)settings + credentialsProvider: + (CredentialsProvider *)credentialsProvider // no passing ownership + userExecutor:(std::unique_ptr)userExecutor + workerQueue:(std::unique_ptr)workerQueue { + return [[FSTFirestoreClient alloc] initWithDatabaseInfo:databaseInfo + settings:settings + credentialsProvider:credentialsProvider + userExecutor:std::move(userExecutor) + workerQueue:std::move(workerQueue)]; +} + +- (instancetype)initWithDatabaseInfo:(const DatabaseInfo &)databaseInfo + settings:(FIRFirestoreSettings *)settings + credentialsProvider: + (CredentialsProvider *)credentialsProvider // no passing ownership + userExecutor:(std::unique_ptr)userExecutor + workerQueue:(std::unique_ptr)workerQueue { + if (self = [super init]) { + _databaseInfo = databaseInfo; + _credentialsProvider = credentialsProvider; + _userExecutor = std::move(userExecutor); + _workerQueue = std::move(workerQueue); + _gcHasRun = NO; + _initialGcDelay = FSTLruGcInitialDelay; + _regularGcDelay = FSTLruGcRegularDelay; + + auto userPromise = std::make_shared>(); + bool initialized = false; + + __weak __typeof__(self) weakSelf = self; + auto credentialChangeListener = [initialized, userPromise, weakSelf](User user) mutable { + __typeof__(self) strongSelf = weakSelf; + if (!strongSelf) return; + + if (!initialized) { + initialized = true; + userPromise->set_value(user); + } else { + strongSelf->_workerQueue->Enqueue( + [strongSelf, user] { [strongSelf credentialDidChangeWithUser:user]; }); + } + }; + + _credentialsProvider->SetCredentialChangeListener(credentialChangeListener); + + // Defer initialization until we get the current user from the credentialChangeListener. This is + // guaranteed to be synchronously dispatched onto our worker queue, so we will be initialized + // before any subsequently queued work runs. + _workerQueue->Enqueue([self, userPromise, settings] { + User user = userPromise->get_future().get(); + [self initializeWithUser:user settings:settings]; + }); + } + return self; +} + +- (void)initializeWithUser:(const User &)user settings:(FIRFirestoreSettings *)settings { + // Do all of our initialization on our own dispatch queue. + _workerQueue->VerifyIsCurrentQueue(); + LOG_DEBUG("Initializing. Current user: %s", user.uid()); + + // Note: The initialization work must all be synchronous (we can't dispatch more work) since + // external write/listen operations could get queued to run before that subsequent work + // completes. + if (settings.isPersistenceEnabled) { + Path dir = [FSTLevelDB storageDirectoryForDatabaseInfo:*self.databaseInfo + documentsDirectory:[FSTLevelDB documentsDirectory]]; + + FSTSerializerBeta *remoteSerializer = + [[FSTSerializerBeta alloc] initWithDatabaseID:&self.databaseInfo->database_id()]; + FSTLocalSerializer *serializer = + [[FSTLocalSerializer alloc] initWithRemoteSerializer:remoteSerializer]; + FSTLevelDB *ldb; + Status levelDbStatus = + [FSTLevelDB dbWithDirectory:std::move(dir) + serializer:serializer + lruParams:LruParams::WithCacheSize(settings.cacheSizeBytes) + ptr:&ldb]; + if (!levelDbStatus.ok()) { + // If leveldb fails to start then just throw up our hands: the error is unrecoverable. + // There's nothing an end-user can do and nearly all failures indicate the developer is doing + // something grossly wrong so we should stop them cold in their tracks with a failure they + // can't ignore. + [NSException raise:NSInternalInconsistencyException + format:@"Failed to open DB: %s", levelDbStatus.ToString().c_str()]; + } + _lruDelegate = ldb.referenceDelegate; + _persistence = ldb; + [self scheduleLruGarbageCollection]; + } else { + _persistence = [FSTMemoryPersistence persistenceWithEagerGC]; + } + + _localStore = [[FSTLocalStore alloc] initWithPersistence:_persistence initialUser:user]; + + auto datastore = + std::make_shared(*self.databaseInfo, _workerQueue.get(), _credentialsProvider); + + _remoteStore = absl::make_unique( + _localStore, std::move(datastore), _workerQueue.get(), + [self](OnlineState onlineState) { [self.syncEngine applyChangedOnlineState:onlineState]; }); + + _syncEngine = [[FSTSyncEngine alloc] initWithLocalStore:_localStore + remoteStore:_remoteStore.get() + initialUser:user]; + + _eventManager = [FSTEventManager eventManagerWithSyncEngine:_syncEngine]; + + // Setup wiring for remote store. + _remoteStore->set_sync_engine(_syncEngine); + + // NOTE: RemoteStore depends on LocalStore (for persisting stream tokens, refilling mutation + // queue, etc.) so must be started after LocalStore. + [_localStore start]; + _remoteStore->Start(); +} + +/** + * Schedules a callback to try running LRU garbage collection. Reschedules itself after the GC has + * run. + */ +- (void)scheduleLruGarbageCollection { + std::chrono::milliseconds delay = _gcHasRun ? _regularGcDelay : _initialGcDelay; + _lruCallback = _workerQueue->EnqueueAfterDelay(delay, TimerId::GarbageCollectionDelay, [self]() { + [self->_localStore collectGarbage:self->_lruDelegate.gc]; + self->_gcHasRun = YES; + [self scheduleLruGarbageCollection]; + }); +} + +- (void)credentialDidChangeWithUser:(const User &)user { + _workerQueue->VerifyIsCurrentQueue(); + + LOG_DEBUG("Credential Changed. Current user: %s", user.uid()); + [self.syncEngine credentialDidChangeWithUser:user]; +} + +- (void)disableNetworkWithCompletion:(nullable FSTVoidErrorBlock)completion { + _workerQueue->Enqueue([self, completion] { + _remoteStore->DisableNetwork(); + if (completion) { + self->_userExecutor->Execute([=] { completion(nil); }); + } + }); +} + +- (void)enableNetworkWithCompletion:(nullable FSTVoidErrorBlock)completion { + _workerQueue->Enqueue([self, completion] { + _remoteStore->EnableNetwork(); + if (completion) { + self->_userExecutor->Execute([=] { completion(nil); }); + } + }); +} + +- (void)shutdownWithCompletion:(nullable FSTVoidErrorBlock)completion { + _workerQueue->Enqueue([self, completion] { + self->_credentialsProvider->SetCredentialChangeListener(nullptr); + + // If we've scheduled LRU garbage collection, cancel it. + if (self->_lruCallback) { + self->_lruCallback.Cancel(); + } + _remoteStore->Shutdown(); + [self.persistence shutdown]; + if (completion) { + self->_userExecutor->Execute([=] { completion(nil); }); + } + }); +} + +- (std::shared_ptr)listenToQuery:(FSTQuery *)query + options:(ListenOptions)options + listener:(ViewSnapshot::SharedListener &&)listener { + auto query_listener = QueryListener::Create(query, std::move(options), std::move(listener)); + + _workerQueue->Enqueue([self, query_listener] { [self.eventManager addListener:query_listener]; }); + + return query_listener; +} + +- (void)removeListener:(const std::shared_ptr &)listener { + _workerQueue->Enqueue([self, listener] { [self.eventManager removeListener:listener]; }); +} + +- (void)getDocumentFromLocalCache:(const DocumentReference &)doc + completion:(DocumentSnapshot::Listener &&)completion { + auto shared_completion = absl::ShareUniquePtr(std::move(completion)); + _workerQueue->Enqueue([self, doc, shared_completion] { + FSTMaybeDocument *maybeDoc = [self.localStore readDocument:doc.key()]; + StatusOr maybe_snapshot; + + if ([maybeDoc isKindOfClass:[FSTDocument class]]) { + FSTDocument *document = (FSTDocument *)maybeDoc; + maybe_snapshot = DocumentSnapshot{doc.firestore(), doc.key(), document, + /*from_cache=*/true, + /*has_pending_writes=*/document.hasLocalMutations}; + } else if ([maybeDoc isKindOfClass:[FSTDeletedDocument class]]) { + maybe_snapshot = DocumentSnapshot{doc.firestore(), doc.key(), nil, + /*from_cache=*/true, + /*has_pending_writes=*/false}; + } else { + maybe_snapshot = Status{FirestoreErrorCode::Unavailable, + "Failed to get document from cache. (However, this document " + "may exist on the server. Run again without setting source to " + "FIRFirestoreSourceCache to attempt to retrieve the document "}; + } + + if (shared_completion) { + self->_userExecutor->Execute([=] { shared_completion->OnEvent(std::move(maybe_snapshot)); }); + } + }); +} + +- (void)getDocumentsFromLocalCache:(FIRQuery *)query + completion:(void (^)(FIRQuerySnapshot *_Nullable query, + NSError *_Nullable error))completion { + _workerQueue->Enqueue([self, query, completion] { + DocumentMap docs = [self.localStore executeQuery:query.query]; + + FSTView *view = [[FSTView alloc] initWithQuery:query.query remoteDocuments:DocumentKeySet{}]; + FSTViewDocumentChanges *viewDocChanges = + [view computeChangesWithDocuments:docs.underlying_map()]; + FSTViewChange *viewChange = [view applyChangesToDocuments:viewDocChanges]; + HARD_ASSERT(viewChange.limboChanges.count == 0, + "View returned limbo documents during local-only query execution."); + HARD_ASSERT(viewChange.snapshot.has_value(), "Expected a snapshot"); + + ViewSnapshot snapshot = std::move(viewChange.snapshot).value(); + SnapshotMetadata metadata(snapshot.has_pending_writes(), snapshot.from_cache()); + + FIRQuerySnapshot *result = [[FIRQuerySnapshot alloc] initWithFirestore:query.firestore.wrapped + originalQuery:query.query + snapshot:std::move(snapshot) + metadata:std::move(metadata)]; + + if (completion) { + self->_userExecutor->Execute([=] { completion(result, nil); }); + } + }); +} + +- (void)writeMutations:(std::vector &&)mutations + completion:(nullable FSTVoidErrorBlock)completion { + // TODO(c++14): move `mutations` into lambda (C++14). + _workerQueue->Enqueue([self, mutations, completion]() mutable { + if (mutations.empty()) { + if (completion) { + self->_userExecutor->Execute([=] { completion(nil); }); + } + } else { + [self.syncEngine writeMutations:std::move(mutations) + completion:^(NSError *error) { + // Dispatch the result back onto the user dispatch queue. + if (completion) { + self->_userExecutor->Execute([=] { completion(error); }); + } + }]; + } + }); +}; + +- (void)transactionWithRetries:(int)retries + updateBlock:(FSTTransactionBlock)updateBlock + completion:(FSTVoidIDErrorBlock)completion { + _workerQueue->Enqueue([self, retries, updateBlock, completion] { + [self.syncEngine + transactionWithRetries:retries + workerQueue:_workerQueue.get() + updateBlock:updateBlock + completion:^(id _Nullable result, NSError *_Nullable error) { + // Dispatch the result back onto the user dispatch queue. + if (completion) { + self->_userExecutor->Execute([=] { completion(result, error); }); + } + }]; + }); +} + +- (const DatabaseInfo *)databaseInfo { + return &_databaseInfo; +} + +- (const DatabaseId *)databaseID { + return &_databaseInfo.database_id(); +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Core/FSTQuery.h b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Core/FSTQuery.h new file mode 100644 index 0000000..851da92 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Core/FSTQuery.h @@ -0,0 +1,315 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +#include "Firestore/core/src/firebase/firestore/model/field_path.h" +#include "Firestore/core/src/firebase/firestore/model/resource_path.h" + +@class FSTDocument; +@class FSTFieldValue; + +NS_ASSUME_NONNULL_BEGIN + +/** + * FSTRelationFilterOperator is a value relation operator that can be used to filter documents. + * It is similar to NSPredicateOperatorType, but only has operators supported by Firestore. + */ +typedef NS_ENUM(NSInteger, FSTRelationFilterOperator) { + FSTRelationFilterOperatorLessThan = 0, + FSTRelationFilterOperatorLessThanOrEqual, + FSTRelationFilterOperatorEqual, + FSTRelationFilterOperatorGreaterThanOrEqual, + FSTRelationFilterOperatorGreaterThan, + FSTRelationFilterOperatorArrayContains, +}; + +/** Interface used for all query filters. */ +@interface FSTFilter : NSObject + +/** + * Creates a filter for the provided path, operator, and value. + * + * Note that if the relational operator is FSTRelationFilterOperatorEqual and + * the value is [FSTNullValue nullValue] or [FSTDoubleValue nanValue], this + * will return the appropriate FSTNullFilter or FSTNanFilter class instead of a + * FSTRelationFilter. + */ ++ (instancetype)filterWithField:(const firebase::firestore::model::FieldPath &)field + filterOperator:(FSTRelationFilterOperator)op + value:(FSTFieldValue *)value; + +/** Returns the field the Filter operates over. Abstract method. */ +- (const firebase::firestore::model::FieldPath &)field; + +/** Returns true if a document matches the filter. Abstract method. */ +- (BOOL)matchesDocument:(FSTDocument *)document; + +/** A unique ID identifying the filter; used when serializing queries. Abstract method. */ +- (NSString *)canonicalID; + +@end + +/** + * FSTRelationFilter is a document filter constraint on a query with a single relation operator. + * It is similar to NSComparisonPredicate, except customized for Firestore semantics. + */ +@interface FSTRelationFilter : FSTFilter + +/** + * Creates a new constraint for filtering documents. + * + * @param field A path to a field in the document to filter on. The LHS of the expression. + * @param filterOperator The binary operator to apply. + * @param value A constant value to compare @a field to. The RHS of the expression. + * @return A new instance of FSTRelationFilter. + */ +- (instancetype)initWithField:(firebase::firestore::model::FieldPath)field + filterOperator:(FSTRelationFilterOperator)filterOperator + value:(FSTFieldValue *)value; + +- (instancetype)init NS_UNAVAILABLE; + +/** Returns YES if the receiver is not an equality relation. */ +- (BOOL)isInequality; + +/** The left hand side of the relation. A path into a document field. */ +- (const firebase::firestore::model::FieldPath &)field; + +/** The type of equality/inequality operator to use in the relation. */ +@property(nonatomic, assign, readonly) FSTRelationFilterOperator filterOperator; + +/** The right hand side of the relation. A constant value to compare to. */ +@property(nonatomic, strong, readonly) FSTFieldValue *value; + +@end + +/** Filter that matches NULL values. */ +@interface FSTNullFilter : FSTFilter +- (instancetype)init NS_UNAVAILABLE; +- (instancetype)initWithField:(firebase::firestore::model::FieldPath)field + NS_DESIGNATED_INITIALIZER; +@end + +/** Filter that matches NAN values. */ +@interface FSTNanFilter : FSTFilter +- (instancetype)init NS_UNAVAILABLE; +- (instancetype)initWithField:(firebase::firestore::model::FieldPath)field + NS_DESIGNATED_INITIALIZER; +@end + +/** FSTSortOrder is a field and direction to order query results by. */ +@interface FSTSortOrder : NSObject + +/** Creates a new sort order with the given field and direction. */ ++ (instancetype)sortOrderWithFieldPath:(firebase::firestore::model::FieldPath)fieldPath + ascending:(BOOL)ascending; + +- (instancetype)init NS_UNAVAILABLE; + +/** Compares two documents based on the field and direction of this sort order. */ +- (NSComparisonResult)compareDocument:(FSTDocument *)document1 toDocument:(FSTDocument *)document2; + +/** The field to sort by. */ +- (const firebase::firestore::model::FieldPath &)field; + +/** The direction of the sort. */ +@property(nonatomic, assign, readonly, getter=isAscending) BOOL ascending; + +@end + +/** + * FSTBound represents a bound of a query. + * + * The bound is specified with the given components representing a position and whether it's just + * before or just after the position (relative to whatever the query order is). + * + * The position represents a logical index position for a query. It's a prefix of values for + * the (potentially implicit) order by clauses of a query. + * + * FSTBound provides a function to determine whether a document comes before or after a bound. + * This is influenced by whether the position is just before or just after the provided values. + */ +@interface FSTBound : NSObject + +/** + * Creates a new bound. + * + * @param position The position relative to the sort order. + * @param isBefore Whether this bound is just before or just after the position. + */ ++ (instancetype)boundWithPosition:(NSArray *)position isBefore:(BOOL)isBefore; + +/** Whether this bound is just before or just after the provided position */ +@property(nonatomic, assign, readonly, getter=isBefore) BOOL before; + +/** The index position of this bound represented as an array of field values. */ +@property(nonatomic, strong, readonly) NSArray *position; + +/** Returns YES if a document comes before a bound using the provided sort order. */ +- (BOOL)sortsBeforeDocument:(FSTDocument *)document + usingSortOrder:(NSArray *)sortOrder; + +@end + +/** FSTQuery represents the internal structure of a Firestore query. */ +@interface FSTQuery : NSObject + +- (id)init NS_UNAVAILABLE; + +/** + * Initializes a query with all of its components directly. + */ +- (instancetype)initWithPath:(firebase::firestore::model::ResourcePath)path + collectionGroup:(nullable NSString *)collectionGroup + filterBy:(NSArray *)filters + orderBy:(NSArray *)sortOrders + limit:(NSInteger)limit + startAt:(nullable FSTBound *)startAtBound + endAt:(nullable FSTBound *)endAtBound NS_DESIGNATED_INITIALIZER; + +/** + * Creates and returns a new FSTQuery. + * + * @param path The path to the collection to be queried over. + * @return A new instance of FSTQuery. + */ ++ (instancetype)queryWithPath:(firebase::firestore::model::ResourcePath)path; + +/** + * Creates and returns a new FSTQuery. + * + * @param path The path to the location to be queried over. Must currently be + * empty in the case of a collection group query. + * @param collectionGroup The collection group to be queried over. nil if this + * is not a collection group query. + * @return A new instance of FSTQuery. + */ ++ (instancetype)queryWithPath:(firebase::firestore::model::ResourcePath)path + collectionGroup:(nullable NSString *)collectionGroup; + +/** + * Returns the list of ordering constraints that were explicitly requested on the query by the + * user. + * + * Note that the actual query performed might add additional sort orders to match the behavior + * of the backend. + */ +- (NSArray *)explicitSortOrders; + +/** + * Returns the full list of ordering constraints on the query. + * + * This might include additional sort orders added implicitly to match the backend behavior. + */ +- (NSArray *)sortOrders; + +/** + * Creates a new FSTQuery with an additional filter. + * + * @param filter The predicate to filter by. + * @return the new FSTQuery. + */ +- (instancetype)queryByAddingFilter:(FSTFilter *)filter; + +/** + * Creates a new FSTQuery with an additional ordering constraint. + * + * @param sortOrder The key and direction to order by. + * @return the new FSTQuery. + */ +- (instancetype)queryByAddingSortOrder:(FSTSortOrder *)sortOrder; + +/** + * Returns a new FSTQuery with the given limit on how many results can be returned. + * + * @param limit The maximum number of results to return. If @a limit <= 0, behavior is unspecified. + * If @a limit == NSNotFound, then no limit is applied. + */ +- (instancetype)queryBySettingLimit:(NSInteger)limit; + +/** + * Creates a new FSTQuery starting at the provided bound. + * + * @param bound The bound to start this query at. + * @return the new FSTQuery. + */ +- (instancetype)queryByAddingStartAt:(FSTBound *)bound; + +/** + * Creates a new FSTQuery ending at the provided bound. + * + * @param bound The bound to end this query at. + * @return the new FSTQuery. + */ +- (instancetype)queryByAddingEndAt:(FSTBound *)bound; + +/** + * Helper to convert a collection group query into a collection query at a specific path. This is + * used when executing collection group queries, since we have to split the query into a set of + * collection queries at multiple paths. + */ +- (instancetype)collectionQueryAtPath:(firebase::firestore::model::ResourcePath)path; + +/** Returns YES if the receiver is query for a specific document. */ +- (BOOL)isDocumentQuery; + +/** Returns YES if the receiver is a collection group query. */ +- (BOOL)isCollectionGroupQuery; + +/** Returns YES if the @a document matches the constraints of the receiver. */ +- (BOOL)matchesDocument:(FSTDocument *)document; + +/** Returns a comparator that will sort documents according to the receiver's sort order. */ +- (NSComparator)comparator; + +/** Returns the field of the first filter on the receiver that's an inequality, or nullptr if none. + */ +- (nullable const firebase::firestore::model::FieldPath *)inequalityFilterField; + +/** Returns YES if the query has an arrayContains filter already. */ +- (BOOL)hasArrayContainsFilter; + +/** Returns the first field in an order-by constraint, or nullptr if none. */ +- (nullable const firebase::firestore::model::FieldPath *)firstSortOrderField; + +/** The base path of the query. */ +- (const firebase::firestore::model::ResourcePath &)path; + +/** The collection group of the query. */ +@property(nonatomic, nullable, strong, readonly) NSString *collectionGroup; + +/** The filters on the documents returned by the query. */ +@property(nonatomic, strong, readonly) NSArray *filters; + +/** The maximum number of results to return, or NSNotFound if no limit. */ +@property(nonatomic, assign, readonly) NSInteger limit; + +/** + * A canonical string identifying the query. Two different instances of equivalent queries will + * return the same canonicalID. + */ +@property(nonatomic, strong, readonly) NSString *canonicalID; + +/** An optional bound to start the query at. */ +@property(nonatomic, nullable, strong, readonly) FSTBound *startAt; + +/** An optional bound to end the query at. */ +@property(nonatomic, nullable, strong, readonly) FSTBound *endAt; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Core/FSTQuery.mm b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Core/FSTQuery.mm new file mode 100644 index 0000000..d057c87 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Core/FSTQuery.mm @@ -0,0 +1,901 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "Firestore/Source/Core/FSTQuery.h" + +#include +#include +#include + +#import "Firestore/Source/API/FIRFirestore+Internal.h" +#import "Firestore/Source/Model/FSTDocument.h" +#import "Firestore/Source/Model/FSTFieldValue.h" +#import "Firestore/Source/Util/FSTClasses.h" +#import "Firestore/Source/Util/FSTUsageValidation.h" + +#include "Firestore/core/src/firebase/firestore/model/document_key.h" +#include "Firestore/core/src/firebase/firestore/model/field_path.h" +#include "Firestore/core/src/firebase/firestore/model/resource_path.h" +#include "Firestore/core/src/firebase/firestore/util/hard_assert.h" +#include "Firestore/core/src/firebase/firestore/util/hashing.h" +#include "Firestore/core/src/firebase/firestore/util/string_apple.h" + +namespace util = firebase::firestore::util; +using firebase::firestore::model::DocumentKey; +using firebase::firestore::model::FieldPath; +using firebase::firestore::model::ResourcePath; + +NS_ASSUME_NONNULL_BEGIN + +#pragma mark - FSTRelationFilterOperator functions + +/** + * Returns the reverse order (i.e. Ascending => Descending) etc. + */ +static constexpr NSComparisonResult ReverseOrder(NSComparisonResult result) { + return static_cast(-static_cast(result)); +} + +NSString *FSTStringFromQueryRelationOperator(FSTRelationFilterOperator filterOperator) { + switch (filterOperator) { + case FSTRelationFilterOperatorLessThan: + return @"<"; + case FSTRelationFilterOperatorLessThanOrEqual: + return @"<="; + case FSTRelationFilterOperatorEqual: + return @"=="; + case FSTRelationFilterOperatorGreaterThanOrEqual: + return @">="; + case FSTRelationFilterOperatorGreaterThan: + return @">"; + case FSTRelationFilterOperatorArrayContains: + return @"array_contains"; + default: + HARD_FAIL("Unknown FSTRelationFilterOperator %s", filterOperator); + } +} + +@implementation FSTFilter + ++ (instancetype)filterWithField:(const FieldPath &)field + filterOperator:(FSTRelationFilterOperator)op + value:(FSTFieldValue *)value { + if ([value isEqual:[FSTNullValue nullValue]]) { + if (op != FSTRelationFilterOperatorEqual) { + FSTThrowInvalidUsage(@"InvalidQueryException", + @"Invalid Query. You can only perform equality comparisons on nil / " + "NSNull."); + } + return [[FSTNullFilter alloc] initWithField:field]; + } else if ([value isEqual:[FSTDoubleValue nanValue]]) { + if (op != FSTRelationFilterOperatorEqual) { + FSTThrowInvalidUsage(@"InvalidQueryException", + @"Invalid Query. You can only perform equality comparisons on NaN."); + } + return [[FSTNanFilter alloc] initWithField:field]; + } else { + return [[FSTRelationFilter alloc] initWithField:field filterOperator:op value:value]; + } +} + +- (const FieldPath &)field { + @throw FSTAbstractMethodException(); // NOLINT +} + +- (BOOL)matchesDocument:(FSTDocument *)document { + @throw FSTAbstractMethodException(); // NOLINT +} + +- (NSString *)canonicalID { + @throw FSTAbstractMethodException(); // NOLINT +} + +@end + +#pragma mark - FSTRelationFilter + +@interface FSTRelationFilter () { + /** The left hand side of the relation. A path into a document field. */ + firebase::firestore::model::FieldPath _field; +} + +/** + * Initializes the receiver relation filter. + * + * @param field A path to a field in the document to filter on. The LHS of the expression. + * @param filterOperator The binary operator to apply. + * @param value A constant value to compare @a field to. The RHS of the expression. + */ +- (instancetype)initWithField:(FieldPath)field + filterOperator:(FSTRelationFilterOperator)filterOperator + value:(FSTFieldValue *)value NS_DESIGNATED_INITIALIZER; + +/** Returns YES if @a document matches the receiver's constraint. */ +- (BOOL)matchesDocument:(FSTDocument *)document; + +/** + * A canonical string identifying the filter. Two different instances of equivalent filters will + * return the same canonicalID. + */ +- (NSString *)canonicalID; + +@end + +@implementation FSTRelationFilter + +#pragma mark - Constructor methods + +- (instancetype)initWithField:(FieldPath)field + filterOperator:(FSTRelationFilterOperator)filterOperator + value:(FSTFieldValue *)value { + self = [super init]; + if (self) { + _field = std::move(field); + _filterOperator = filterOperator; + _value = value; + } + return self; +} + +#pragma mark - Public Methods + +- (BOOL)isInequality { + return self.filterOperator != FSTRelationFilterOperatorEqual && + self.filterOperator != FSTRelationFilterOperatorArrayContains; +} + +- (const firebase::firestore::model::FieldPath &)field { + return _field; +} + +#pragma mark - NSObject methods + +- (NSString *)description { + return [NSString stringWithFormat:@"%s %@ %@", _field.CanonicalString().c_str(), + FSTStringFromQueryRelationOperator(self.filterOperator), + self.value]; +} + +- (BOOL)isEqual:(id)other { + if (self == other) { + return YES; + } + if (![other isKindOfClass:[FSTRelationFilter class]]) { + return NO; + } + return [self isEqualToFilter:(FSTRelationFilter *)other]; +} + +#pragma mark - Private methods + +- (BOOL)matchesDocument:(FSTDocument *)document { + if (_field.IsKeyFieldPath()) { + HARD_ASSERT([self.value isKindOfClass:[FSTReferenceValue class]], + "Comparing on key, but filter value not a FSTReferenceValue."); + HARD_ASSERT(self.filterOperator != FSTRelationFilterOperatorArrayContains, + "arrayContains queries don't make sense on document keys."); + FSTReferenceValue *refValue = (FSTReferenceValue *)self.value; + NSComparisonResult comparison = CompareKeys(document.key, refValue.value.key); + return [self matchesComparison:comparison]; + } else { + return [self matchesValue:[document fieldForPath:self.field]]; + } +} + +- (NSString *)canonicalID { + // TODO(b/37283291): This should be collision robust and avoid relying on |description| methods. + return [NSString stringWithFormat:@"%s%@%@", _field.CanonicalString().c_str(), + FSTStringFromQueryRelationOperator(self.filterOperator), + [self.value value]]; +} + +- (BOOL)isEqualToFilter:(FSTRelationFilter *)other { + if (self.filterOperator != other.filterOperator) { + return NO; + } + if (_field != other.field) { + return NO; + } + if (![self.value isEqual:other.value]) { + return NO; + } + return YES; +} + +/** Returns YES if receiver is true with the given value as its LHS. */ +- (BOOL)matchesValue:(FSTFieldValue *)other { + if (self.filterOperator == FSTRelationFilterOperatorArrayContains) { + if ([other isMemberOfClass:[FSTArrayValue class]]) { + FSTArrayValue *arrayValue = (FSTArrayValue *)other; + return [arrayValue.internalValue containsObject:self.value]; + } else { + return false; + } + } else { + // Only perform comparison queries on types with matching backend order (such as double and + // int). + return self.value.typeOrder == other.typeOrder && + [self matchesComparison:[other compare:self.value]]; + } +} + +- (BOOL)matchesComparison:(NSComparisonResult)comparison { + switch (self.filterOperator) { + case FSTRelationFilterOperatorLessThan: + return comparison == NSOrderedAscending; + case FSTRelationFilterOperatorLessThanOrEqual: + return comparison == NSOrderedAscending || comparison == NSOrderedSame; + case FSTRelationFilterOperatorEqual: + return comparison == NSOrderedSame; + case FSTRelationFilterOperatorGreaterThanOrEqual: + return comparison == NSOrderedDescending || comparison == NSOrderedSame; + case FSTRelationFilterOperatorGreaterThan: + return comparison == NSOrderedDescending; + default: + HARD_FAIL("Unknown operator: %s", self.filterOperator); + } +} + +@end + +#pragma mark - FSTNullFilter + +@interface FSTNullFilter () { + FieldPath _field; +} +@end + +@implementation FSTNullFilter +- (instancetype)initWithField:(FieldPath)field { + if (self = [super init]) { + _field = std::move(field); + } + return self; +} + +- (BOOL)matchesDocument:(FSTDocument *)document { + FSTFieldValue *fieldValue = [document fieldForPath:self.field]; + return fieldValue != nil && [fieldValue isEqual:[FSTNullValue nullValue]]; +} + +- (NSString *)canonicalID { + return [NSString stringWithFormat:@"%s IS NULL", _field.CanonicalString().c_str()]; +} + +- (const firebase::firestore::model::FieldPath &)field { + return _field; +} + +- (NSString *)description { + return [self canonicalID]; +} + +- (BOOL)isEqual:(id)other { + if (other == self) return YES; + if (![[other class] isEqual:[self class]]) return NO; + + return _field == ((FSTNullFilter *)other)->_field; +} + +- (NSUInteger)hash { + return util::Hash(_field); +} + +@end + +#pragma mark - FSTNanFilter + +@interface FSTNanFilter () { + FieldPath _field; +} +@end + +@implementation FSTNanFilter + +- (instancetype)initWithField:(FieldPath)field { + if (self = [super init]) { + _field = std::move(field); + } + return self; +} + +- (BOOL)matchesDocument:(FSTDocument *)document { + FSTFieldValue *fieldValue = [document fieldForPath:self.field]; + return fieldValue != nil && [fieldValue isEqual:[FSTDoubleValue nanValue]]; +} + +- (NSString *)canonicalID { + return [NSString stringWithFormat:@"%s IS NaN", _field.CanonicalString().c_str()]; +} + +- (const firebase::firestore::model::FieldPath &)field { + return _field; +} + +- (NSString *)description { + return [self canonicalID]; +} + +- (BOOL)isEqual:(id)other { + if (other == self) return YES; + if (![[other class] isEqual:[self class]]) return NO; + + return _field == ((FSTNanFilter *)other)->_field; +} + +- (NSUInteger)hash { + return util::Hash(_field); +} +@end + +#pragma mark - FSTSortOrder + +@interface FSTSortOrder () { + /** The field to sort by. */ + firebase::firestore::model::FieldPath _field; +} + +/** Creates a new sort order with the given field and direction. */ +- (instancetype)initWithFieldPath:(FieldPath)fieldPath ascending:(BOOL)ascending; + +- (NSString *)canonicalID; + +@end + +@implementation FSTSortOrder + +#pragma mark - Constructor methods + ++ (instancetype)sortOrderWithFieldPath:(FieldPath)fieldPath ascending:(BOOL)ascending { + return [[FSTSortOrder alloc] initWithFieldPath:std::move(fieldPath) ascending:ascending]; +} + +- (instancetype)initWithFieldPath:(FieldPath)fieldPath ascending:(BOOL)ascending { + self = [super init]; + if (self) { + _field = std::move(fieldPath); + _ascending = ascending; + } + return self; +} + +- (const firebase::firestore::model::FieldPath &)field { + return _field; +} + +#pragma mark - Public methods + +- (NSComparisonResult)compareDocument:(FSTDocument *)document1 toDocument:(FSTDocument *)document2 { + NSComparisonResult result; + if (_field == FieldPath::KeyFieldPath()) { + result = CompareKeys(document1.key, document2.key); + } else { + FSTFieldValue *value1 = [document1 fieldForPath:self.field]; + FSTFieldValue *value2 = [document2 fieldForPath:self.field]; + HARD_ASSERT(value1 != nil && value2 != nil, + "Trying to compare documents on fields that don't exist."); + result = [value1 compare:value2]; + } + if (!self.isAscending) { + result = ReverseOrder(result); + } + return result; +} + +- (NSString *)canonicalID { + return [NSString stringWithFormat:@"%s%@", _field.CanonicalString().c_str(), + self.isAscending ? @"asc" : @"desc"]; +} + +- (BOOL)isEqualToSortOrder:(FSTSortOrder *)other { + return _field == other->_field && self.isAscending == other.isAscending; +} + +#pragma mark - NSObject methods + +- (NSString *)description { + return [NSString stringWithFormat:@"", + _field.CanonicalString().c_str(), + self.ascending ? @"asc" : @"desc"]; +} + +- (BOOL)isEqual:(NSObject *)other { + if (self == other) { + return YES; + } + if (![other isKindOfClass:[FSTSortOrder class]]) { + return NO; + } + return [self isEqualToSortOrder:(FSTSortOrder *)other]; +} + +- (NSUInteger)hash { + return [self.canonicalID hash]; +} + +- (instancetype)copyWithZone:(nullable NSZone *)zone { + return self; +} + +@end + +#pragma mark - FSTBound + +@implementation FSTBound + +- (instancetype)initWithPosition:(NSArray *)position isBefore:(BOOL)isBefore { + if (self = [super init]) { + _position = position; + _before = isBefore; + } + return self; +} + ++ (instancetype)boundWithPosition:(NSArray *)position isBefore:(BOOL)isBefore { + return [[FSTBound alloc] initWithPosition:position isBefore:isBefore]; +} + +- (NSString *)canonicalString { + // TODO(b/29183165): Make this collision robust. + NSMutableString *string = [NSMutableString string]; + if (self.isBefore) { + [string appendString:@"b:"]; + } else { + [string appendString:@"a:"]; + } + for (FSTFieldValue *component in self.position) { + [string appendFormat:@"%@", component]; + } + return string; +} + +- (BOOL)sortsBeforeDocument:(FSTDocument *)document + usingSortOrder:(NSArray *)sortOrder { + HARD_ASSERT(self.position.count <= sortOrder.count, + "FSTIndexPosition has more components than provided sort order."); + __block NSComparisonResult result = NSOrderedSame; + [self.position enumerateObjectsUsingBlock:^(FSTFieldValue *fieldValue, NSUInteger idx, + BOOL *stop) { + FSTSortOrder *sortOrderComponent = sortOrder[idx]; + NSComparisonResult comparison; + if (sortOrderComponent.field == FieldPath::KeyFieldPath()) { + HARD_ASSERT([fieldValue isKindOfClass:[FSTReferenceValue class]], + "FSTBound has a non-key value where the key path is being used %s", fieldValue); + FSTReferenceValue *refValue = (FSTReferenceValue *)fieldValue; + comparison = CompareKeys(refValue.value.key, document.key); + } else { + FSTFieldValue *docValue = [document fieldForPath:sortOrderComponent.field]; + HARD_ASSERT(docValue != nil, + "Field should exist since document matched the orderBy already."); + comparison = [fieldValue compare:docValue]; + } + + if (!sortOrderComponent.isAscending) { + comparison = ReverseOrder(comparison); + } + + if (comparison != 0) { + result = comparison; + *stop = YES; + } + }]; + + return self.isBefore ? result <= NSOrderedSame : result < NSOrderedSame; +} + +#pragma mark - NSObject methods + +- (NSString *)description { + return [NSString stringWithFormat:@"", self.position, + self.isBefore ? @"YES" : @"NO"]; +} + +- (BOOL)isEqual:(NSObject *)other { + if (self == other) { + return YES; + } + if (![other isKindOfClass:[FSTBound class]]) { + return NO; + } + + FSTBound *otherBound = (FSTBound *)other; + + return [self.position isEqualToArray:otherBound.position] && self.isBefore == otherBound.isBefore; +} + +- (NSUInteger)hash { + return 31 * self.position.hash + (self.isBefore ? 0 : 1); +} + +- (instancetype)copyWithZone:(nullable NSZone *)zone { + return self; +} + +@end + +#pragma mark - FSTQuery + +@interface FSTQuery () { + // Cached value of the canonicalID property. + NSString *_canonicalID; + /** The base path of the query. */ + ResourcePath _path; +} + +/** A list of fields given to sort by. This does not include the implicit key sort at the end. */ +@property(nonatomic, strong, readonly) NSArray *explicitSortOrders; + +/** The memoized list of sort orders */ +@property(nonatomic, nullable, strong, readwrite) NSArray *memoizedSortOrders; + +@end + +@implementation FSTQuery + +#pragma mark - Constructors + ++ (instancetype)queryWithPath:(ResourcePath)path { + return [FSTQuery queryWithPath:std::move(path) collectionGroup:nil]; +} + ++ (instancetype)queryWithPath:(ResourcePath)path + collectionGroup:(nullable NSString *)collectionGroup { + return [[FSTQuery alloc] initWithPath:std::move(path) + collectionGroup:collectionGroup + filterBy:@[] + orderBy:@[] + limit:NSNotFound + startAt:nil + endAt:nil]; +} + +- (instancetype)initWithPath:(ResourcePath)path + collectionGroup:(nullable NSString *)collectionGroup + filterBy:(NSArray *)filters + orderBy:(NSArray *)sortOrders + limit:(NSInteger)limit + startAt:(nullable FSTBound *)startAtBound + endAt:(nullable FSTBound *)endAtBound { + if (self = [super init]) { + _path = std::move(path); + _collectionGroup = collectionGroup; + _filters = filters; + _explicitSortOrders = sortOrders; + _limit = limit; + _startAt = startAtBound; + _endAt = endAtBound; + } + return self; +} + +#pragma mark - NSObject methods + +- (NSString *)description { + return [NSString stringWithFormat:@"", self.canonicalID]; +} + +- (BOOL)isEqual:(id)object { + if (self == object) { + return YES; + } + if (![object isKindOfClass:[FSTQuery class]]) { + return NO; + } + return [self isEqualToQuery:(FSTQuery *)object]; +} + +- (NSUInteger)hash { + return [self.canonicalID hash]; +} + +- (instancetype)copyWithZone:(nullable NSZone *)zone { + return self; +} + +#pragma mark - Public methods + +- (NSArray *)sortOrders { + if (self.memoizedSortOrders == nil) { + const FieldPath *inequalityField = [self inequalityFilterField]; + const FieldPath *firstSortOrderField = [self firstSortOrderField]; + if (inequalityField && !firstSortOrderField) { + // In order to implicitly add key ordering, we must also add the inequality filter field for + // it to be a valid query. Note that the default inequality field and key ordering is + // ascending. + if (inequalityField->IsKeyFieldPath()) { + self.memoizedSortOrders = @[ [FSTSortOrder sortOrderWithFieldPath:FieldPath::KeyFieldPath() + ascending:YES] ]; + } else { + self.memoizedSortOrders = @[ + [FSTSortOrder sortOrderWithFieldPath:*inequalityField ascending:YES], + [FSTSortOrder sortOrderWithFieldPath:FieldPath::KeyFieldPath() ascending:YES] + ]; + } + } else { + HARD_ASSERT(!inequalityField || *inequalityField == *firstSortOrderField, + "First orderBy %s should match inequality field %s.", + firstSortOrderField->CanonicalString(), inequalityField->CanonicalString()); + + __block BOOL foundKeyOrder = NO; + + NSMutableArray *result = [NSMutableArray array]; + for (FSTSortOrder *sortOrder in self.explicitSortOrders) { + [result addObject:sortOrder]; + if (sortOrder.field == FieldPath::KeyFieldPath()) { + foundKeyOrder = YES; + } + } + + if (!foundKeyOrder) { + // The direction of the implicit key ordering always matches the direction of the last + // explicit sort order + BOOL lastIsAscending = + self.explicitSortOrders.count > 0 ? self.explicitSortOrders.lastObject.ascending : YES; + [result addObject:[FSTSortOrder sortOrderWithFieldPath:FieldPath::KeyFieldPath() + ascending:lastIsAscending]]; + } + + self.memoizedSortOrders = result; + } + } + return self.memoizedSortOrders; +} + +- (instancetype)queryByAddingFilter:(FSTFilter *)filter { + HARD_ASSERT(![self isDocumentQuery], "No filtering allowed for document query"); + + const FieldPath *newInequalityField = nullptr; + if ([filter isKindOfClass:[FSTRelationFilter class]] && + [((FSTRelationFilter *)filter) isInequality]) { + newInequalityField = &filter.field; + } + const FieldPath *queryInequalityField = [self inequalityFilterField]; + HARD_ASSERT( + !queryInequalityField || !newInequalityField || *queryInequalityField == *newInequalityField, + "Query must only have one inequality field."); + + return [[FSTQuery alloc] initWithPath:self.path + collectionGroup:self.collectionGroup + filterBy:[self.filters arrayByAddingObject:filter] + orderBy:self.explicitSortOrders + limit:self.limit + startAt:self.startAt + endAt:self.endAt]; +} + +- (instancetype)queryByAddingSortOrder:(FSTSortOrder *)sortOrder { + HARD_ASSERT(![self isDocumentQuery], "No ordering is allowed for a document query."); + + // TODO(klimt): Validate that the same key isn't added twice. + return [[FSTQuery alloc] initWithPath:self.path + collectionGroup:self.collectionGroup + filterBy:self.filters + orderBy:[self.explicitSortOrders arrayByAddingObject:sortOrder] + limit:self.limit + startAt:self.startAt + endAt:self.endAt]; +} + +- (instancetype)queryBySettingLimit:(NSInteger)limit { + return [[FSTQuery alloc] initWithPath:self.path + collectionGroup:self.collectionGroup + filterBy:self.filters + orderBy:self.explicitSortOrders + limit:limit + startAt:self.startAt + endAt:self.endAt]; +} + +- (instancetype)queryByAddingStartAt:(FSTBound *)bound { + return [[FSTQuery alloc] initWithPath:self.path + collectionGroup:self.collectionGroup + filterBy:self.filters + orderBy:self.explicitSortOrders + limit:self.limit + startAt:bound + endAt:self.endAt]; +} + +- (instancetype)queryByAddingEndAt:(FSTBound *)bound { + return [[FSTQuery alloc] initWithPath:self.path + collectionGroup:self.collectionGroup + filterBy:self.filters + orderBy:self.explicitSortOrders + limit:self.limit + startAt:self.startAt + endAt:bound]; +} + +- (instancetype)collectionQueryAtPath:(firebase::firestore::model::ResourcePath)path { + return [[FSTQuery alloc] initWithPath:path + collectionGroup:nil + filterBy:self.filters + orderBy:self.explicitSortOrders + limit:self.limit + startAt:self.startAt + endAt:self.endAt]; +} + +- (BOOL)isDocumentQuery { + return DocumentKey::IsDocumentKey(_path) && !self.collectionGroup && self.filters.count == 0; +} + +- (BOOL)isCollectionGroupQuery { + return self.collectionGroup != nil; +} + +- (BOOL)matchesDocument:(FSTDocument *)document { + return [self pathAndCollectionGroupMatchDocument:document] && + [self orderByMatchesDocument:document] && [self filtersMatchDocument:document] && + [self boundsMatchDocument:document]; +} + +- (NSComparator)comparator { + return ^NSComparisonResult(id document1, id document2) { + BOOL didCompareOnKeyField = NO; + for (FSTSortOrder *orderBy in self.sortOrders) { + NSComparisonResult comp = [orderBy compareDocument:document1 toDocument:document2]; + if (comp != NSOrderedSame) { + return comp; + } + didCompareOnKeyField = didCompareOnKeyField || orderBy.field == FieldPath::KeyFieldPath(); + } + HARD_ASSERT(didCompareOnKeyField, "sortOrder of query did not include key ordering"); + return NSOrderedSame; + }; +} + +- (nullable const FieldPath *)inequalityFilterField { + for (FSTFilter *filter in self.filters) { + if ([filter isKindOfClass:[FSTRelationFilter class]] && + ((FSTRelationFilter *)filter).isInequality) { + return &filter.field; + } + } + return nullptr; +} + +- (BOOL)hasArrayContainsFilter { + for (FSTFilter *filter in self.filters) { + if ([filter isKindOfClass:[FSTRelationFilter class]] && + ((FSTRelationFilter *)filter).filterOperator == FSTRelationFilterOperatorArrayContains) { + return YES; + } + } + return NO; +} + +- (nullable const FieldPath *)firstSortOrderField { + if (self.explicitSortOrders.count > 0) { + return &self.explicitSortOrders.firstObject.field; + } + return nullptr; +} + +/** The base path of the query. */ +- (const firebase::firestore::model::ResourcePath &)path { + return _path; +} + +#pragma mark - Private properties + +- (NSString *)canonicalID { + if (_canonicalID) { + return _canonicalID; + } + + NSMutableString *canonicalID = [NSMutableString string]; + [canonicalID appendFormat:@"%s", _path.CanonicalString().c_str()]; + + if (self.collectionGroup) { + [canonicalID appendFormat:@"|cg:%@", self.collectionGroup]; + } + + // Add filters. + [canonicalID appendString:@"|f:"]; + for (FSTFilter *predicate in self.filters) { + [canonicalID appendFormat:@"%@", [predicate canonicalID]]; + } + + // Add order by. + [canonicalID appendString:@"|ob:"]; + for (FSTSortOrder *orderBy in self.sortOrders) { + [canonicalID appendString:orderBy.canonicalID]; + } + + // Add limit. + if (self.limit != NSNotFound) { + [canonicalID appendFormat:@"|l:%ld", (long)self.limit]; + } + + if (self.startAt) { + [canonicalID appendFormat:@"|lb:%@", self.startAt.canonicalString]; + } + + if (self.endAt) { + [canonicalID appendFormat:@"|ub:%@", self.endAt.canonicalString]; + } + + _canonicalID = canonicalID; + return canonicalID; +} + +#pragma mark - Private methods + +- (BOOL)isEqualToQuery:(FSTQuery *)other { + return self.path == other.path && + (self.collectionGroup == other.collectionGroup || + [self.collectionGroup isEqual:other.collectionGroup]) && + self.limit == other.limit && [self.filters isEqual:other.filters] && + [self.sortOrders isEqual:other.sortOrders] && + (self.startAt == other.startAt || [self.startAt isEqual:other.startAt]) && + (self.endAt == other.endAt || [self.endAt isEqual:other.endAt]); +} + +/* Returns YES if the document matches the path and collection group for the receiver. */ +- (BOOL)pathAndCollectionGroupMatchDocument:(FSTDocument *)document { + const ResourcePath &documentPath = document.key.path(); + if (self.collectionGroup) { + // NOTE: self.path is currently always empty since we don't expose Collection Group queries + // rooted at a document path yet. + return document.key.HasCollectionId(util::MakeString(self.collectionGroup)) && + self.path.IsPrefixOf(documentPath); + } else if (DocumentKey::IsDocumentKey(_path)) { + // Exact match for document queries. + return self.path == documentPath; + } else { + // Shallow ancestor queries by default. + return self.path.IsPrefixOf(documentPath) && _path.size() == documentPath.size() - 1; + } +} + +/** + * A document must have a value for every ordering clause in order to show up in the results. + */ +- (BOOL)orderByMatchesDocument:(FSTDocument *)document { + for (FSTSortOrder *orderBy in self.explicitSortOrders) { + const FieldPath &fieldPath = orderBy.field; + // order by key always matches + if (fieldPath != FieldPath::KeyFieldPath() && [document fieldForPath:fieldPath] == nil) { + return NO; + } + } + return YES; +} + +/** Returns YES if the document matches all of the filters in the receiver. */ +- (BOOL)filtersMatchDocument:(FSTDocument *)document { + for (FSTFilter *filter in self.filters) { + if (![filter matchesDocument:document]) { + return NO; + } + } + return YES; +} + +- (BOOL)boundsMatchDocument:(FSTDocument *)document { + if (self.startAt && ![self.startAt sortsBeforeDocument:document usingSortOrder:self.sortOrders]) { + return NO; + } + if (self.endAt && [self.endAt sortsBeforeDocument:document usingSortOrder:self.sortOrders]) { + return NO; + } + return YES; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Core/FSTSyncEngine.h b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Core/FSTSyncEngine.h new file mode 100644 index 0000000..0409498 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Core/FSTSyncEngine.h @@ -0,0 +1,116 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +#include + +#import "Firestore/Source/Core/FSTTypes.h" + +#include "Firestore/core/src/firebase/firestore/auth/user.h" +#include "Firestore/core/src/firebase/firestore/model/types.h" +#include "Firestore/core/src/firebase/firestore/remote/remote_store.h" +#include "Firestore/core/src/firebase/firestore/util/async_queue.h" + +@class FSTLocalStore; +@class FSTMutation; +@class FSTQuery; + +using firebase::firestore::model::OnlineState; + +NS_ASSUME_NONNULL_BEGIN + +#pragma mark - FSTSyncEngineDelegate + +/** + * A delegate to be notified when the client's online state changes or when the sync engine produces + * new view snapshots or errors. + */ +@protocol FSTSyncEngineDelegate +- (void)handleViewSnapshots:(std::vector &&)viewSnapshots; +- (void)handleError:(NSError *)error forQuery:(FSTQuery *)query; +- (void)applyChangedOnlineState:(OnlineState)onlineState; +@end + +/** + * SyncEngine is the central controller in the client SDK architecture. It is the glue code + * between the EventManager, LocalStore, and RemoteStore. Some of SyncEngine's responsibilities + * include: + * 1. Coordinating client requests and remote events between the EventManager and the local and + * remote data stores. + * 2. Managing a View object for each query, providing the unified view between the local and + * remote data stores. + * 3. Notifying the RemoteStore when the LocalStore has new mutations in its queue that need + * sending to the backend. + * + * The SyncEngine’s methods should only ever be called by methods running on our own worker + * queue. + */ +@interface FSTSyncEngine : NSObject + +- (instancetype)init NS_UNAVAILABLE; +- (instancetype)initWithLocalStore:(FSTLocalStore *)localStore + remoteStore:(firebase::firestore::remote::RemoteStore *)remoteStore + initialUser:(const firebase::firestore::auth::User &)user + NS_DESIGNATED_INITIALIZER; + +/** + * A delegate to be notified when queries being listened to produce new view snapshots or errors. + */ +@property(nonatomic, weak) id syncEngineDelegate; + +/** + * Initiates a new listen. The FSTLocalStore will be queried for initial data and the listen will + * be sent to the `RemoteStore` to get remote data. The registered FSTSyncEngineDelegate will be + * notified of resulting view snapshots and/or listen errors. + * + * @return the target ID assigned to the query. + */ +- (firebase::firestore::model::TargetId)listenToQuery:(FSTQuery *)query; + +/** Stops listening to a query previously listened to via listenToQuery:. */ +- (void)stopListeningToQuery:(FSTQuery *)query; + +/** + * Initiates the write of local mutation batch which involves adding the writes to the mutation + * queue, notifying the remote store about new mutations, and raising events for any changes this + * write caused. The provided completion block will be called once the write has been acked or + * rejected by the backend (or failed locally for any other reason). + */ +- (void)writeMutations:(std::vector &&)mutations + completion:(FSTVoidErrorBlock)completion; + +/** + * Runs the given transaction block up to retries times and then calls completion. + * + * @param retries The number of times to try before giving up. + * @param workerQueue The queue to dispatch sync engine calls to. + * @param updateBlock The block to call to execute the user's transaction. + * @param completion The block to call when the transaction is finished or failed. + */ +- (void)transactionWithRetries:(int)retries + workerQueue:(firebase::firestore::util::AsyncQueue *)workerQueue + updateBlock:(FSTTransactionBlock)updateBlock + completion:(FSTVoidIDErrorBlock)completion; + +- (void)credentialDidChangeWithUser:(const firebase::firestore::auth::User &)user; + +/** Applies an OnlineState change to the sync engine and notifies any views of the change. */ +- (void)applyChangedOnlineState:(firebase::firestore::model::OnlineState)onlineState; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Core/FSTSyncEngine.mm b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Core/FSTSyncEngine.mm new file mode 100644 index 0000000..b00982f --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Core/FSTSyncEngine.mm @@ -0,0 +1,646 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "Firestore/Source/Core/FSTSyncEngine.h" + +#include +#include +#include +#include +#include +#include + +#import "FIRFirestoreErrors.h" +#import "Firestore/Source/Core/FSTQuery.h" +#import "Firestore/Source/Core/FSTView.h" +#import "Firestore/Source/Local/FSTLocalStore.h" +#import "Firestore/Source/Local/FSTLocalViewChanges.h" +#import "Firestore/Source/Local/FSTLocalWriteResult.h" +#import "Firestore/Source/Local/FSTQueryData.h" +#import "Firestore/Source/Model/FSTDocument.h" +#import "Firestore/Source/Model/FSTMutationBatch.h" + +#include "Firestore/core/src/firebase/firestore/auth/user.h" +#include "Firestore/core/src/firebase/firestore/core/target_id_generator.h" +#include "Firestore/core/src/firebase/firestore/core/transaction.h" +#include "Firestore/core/src/firebase/firestore/core/view_snapshot.h" +#include "Firestore/core/src/firebase/firestore/local/reference_set.h" +#include "Firestore/core/src/firebase/firestore/model/document_key.h" +#include "Firestore/core/src/firebase/firestore/model/document_map.h" +#include "Firestore/core/src/firebase/firestore/model/document_set.h" +#include "Firestore/core/src/firebase/firestore/model/snapshot_version.h" +#include "Firestore/core/src/firebase/firestore/remote/remote_event.h" +#include "Firestore/core/src/firebase/firestore/util/error_apple.h" +#include "Firestore/core/src/firebase/firestore/util/hard_assert.h" +#include "Firestore/core/src/firebase/firestore/util/log.h" +#include "Firestore/core/src/firebase/firestore/util/status.h" +#include "absl/types/optional.h" + +using firebase::firestore::auth::HashUser; +using firebase::firestore::auth::User; +using firebase::firestore::core::TargetIdGenerator; +using firebase::firestore::core::Transaction; +using firebase::firestore::core::ViewSnapshot; +using firebase::firestore::local::ReferenceSet; +using firebase::firestore::model::BatchId; +using firebase::firestore::model::DocumentKey; +using firebase::firestore::model::DocumentKeySet; +using firebase::firestore::model::DocumentMap; +using firebase::firestore::model::MaybeDocumentMap; +using firebase::firestore::model::ListenSequenceNumber; +using firebase::firestore::model::OnlineState; +using firebase::firestore::model::SnapshotVersion; +using firebase::firestore::model::TargetId; +using firebase::firestore::remote::RemoteEvent; +using firebase::firestore::remote::RemoteStore; +using firebase::firestore::remote::TargetChange; +using firebase::firestore::util::AsyncQueue; +using firebase::firestore::util::MakeNSError; +using firebase::firestore::util::Status; + +NS_ASSUME_NONNULL_BEGIN + +// Limbo documents don't use persistence, and are eagerly GC'd. So, listens for them don't need +// real sequence numbers. +static const ListenSequenceNumber kIrrelevantSequenceNumber = -1; + +#pragma mark - FSTQueryView + +/** + * FSTQueryView contains all of the info that FSTSyncEngine needs to track for a particular + * query and view. + */ +@interface FSTQueryView : NSObject + +- (instancetype)initWithQuery:(FSTQuery *)query + targetID:(TargetId)targetID + resumeToken:(NSData *)resumeToken + view:(FSTView *)view NS_DESIGNATED_INITIALIZER; + +- (instancetype)init NS_UNAVAILABLE; + +/** The query itself. */ +@property(nonatomic, strong, readonly) FSTQuery *query; + +/** The targetID created by the client that is used in the watch stream to identify this query. */ +@property(nonatomic, assign, readonly) TargetId targetID; + +/** + * An identifier from the datastore backend that indicates the last state of the results that + * was received. This can be used to indicate where to continue receiving new doc changes for the + * query. + */ +@property(nonatomic, copy, readonly) NSData *resumeToken; + +/** + * The view is responsible for computing the final merged truth of what docs are in the query. + * It gets notified of local and remote changes, and applies the query filters and limits to + * determine the most correct possible results. + */ +@property(nonatomic, strong, readonly) FSTView *view; + +@end + +@implementation FSTQueryView + +- (instancetype)initWithQuery:(FSTQuery *)query + targetID:(TargetId)targetID + resumeToken:(NSData *)resumeToken + view:(FSTView *)view { + if (self = [super init]) { + _query = query; + _targetID = targetID; + _resumeToken = resumeToken; + _view = view; + } + return self; +} + +@end + +#pragma mark - LimboResolution + +/** Tracks a limbo resolution. */ +class LimboResolution { + public: + LimboResolution() { + } + + explicit LimboResolution(const DocumentKey &key) : key{key} { + } + + DocumentKey key; + + /** + * Set to true once we've received a document. This is used in remoteKeysForTarget and + * ultimately used by `WatchChangeAggregator` to decide whether it needs to manufacture a delete + * event for the target once the target is CURRENT. + */ + bool document_received = false; +}; + +#pragma mark - FSTSyncEngine + +@interface FSTSyncEngine () + +/** The local store, used to persist mutations and cached documents. */ +@property(nonatomic, strong, readonly) FSTLocalStore *localStore; + +/** FSTQueryViews for all active queries, indexed by query. */ +@property(nonatomic, strong, readonly) + NSMutableDictionary *queryViewsByQuery; + +@end + +@implementation FSTSyncEngine { + /** The remote store for sending writes, watches, etc. to the backend. */ + RemoteStore *_remoteStore; + + /** Used for creating the TargetId for the listens used to resolve limbo documents. */ + TargetIdGenerator _targetIdGenerator; + + /** Stores user completion blocks, indexed by user and BatchId. */ + std::unordered_map *, HashUser> + _mutationCompletionBlocks; + + /** FSTQueryViews for all active queries, indexed by target ID. */ + std::unordered_map _queryViewsByTarget; + + /** + * When a document is in limbo, we create a special listen to resolve it. This maps the + * DocumentKey of each limbo document to the TargetId of the listen resolving it. + */ + std::map _limboTargetsByKey; + + /** + * Basically the inverse of limboTargetsByKey, a map of target ID to a LimboResolution (which + * includes the DocumentKey as well as whether we've received a document for the target). + */ + std::map _limboResolutionsByTarget; + + User _currentUser; + + /** Used to track any documents that are currently in limbo. */ + ReferenceSet _limboDocumentRefs; +} + +- (instancetype)initWithLocalStore:(FSTLocalStore *)localStore + remoteStore:(RemoteStore *)remoteStore + initialUser:(const User &)initialUser { + if (self = [super init]) { + _localStore = localStore; + _remoteStore = remoteStore; + + _queryViewsByQuery = [NSMutableDictionary dictionary]; + + _targetIdGenerator = TargetIdGenerator::SyncEngineTargetIdGenerator(); + _currentUser = initialUser; + } + return self; +} + +- (TargetId)listenToQuery:(FSTQuery *)query { + [self assertDelegateExistsForSelector:_cmd]; + HARD_ASSERT(self.queryViewsByQuery[query] == nil, "We already listen to query: %s", query); + + FSTQueryData *queryData = [self.localStore allocateQuery:query]; + ViewSnapshot viewSnapshot = [self initializeViewAndComputeSnapshotForQueryData:queryData]; + [self.syncEngineDelegate handleViewSnapshots:{viewSnapshot}]; + + _remoteStore->Listen(queryData); + return queryData.targetID; +} + +- (ViewSnapshot)initializeViewAndComputeSnapshotForQueryData:(FSTQueryData *)queryData { + DocumentMap docs = [self.localStore executeQuery:queryData.query]; + DocumentKeySet remoteKeys = [self.localStore remoteDocumentKeysForTarget:queryData.targetID]; + + FSTView *view = [[FSTView alloc] initWithQuery:queryData.query + remoteDocuments:std::move(remoteKeys)]; + FSTViewDocumentChanges *viewDocChanges = [view computeChangesWithDocuments:docs.underlying_map()]; + FSTViewChange *viewChange = [view applyChangesToDocuments:viewDocChanges]; + HARD_ASSERT(viewChange.limboChanges.count == 0, + "View returned limbo docs before target ack from the server."); + + FSTQueryView *queryView = [[FSTQueryView alloc] initWithQuery:queryData.query + targetID:queryData.targetID + resumeToken:queryData.resumeToken + view:view]; + self.queryViewsByQuery[queryData.query] = queryView; + _queryViewsByTarget[queryData.targetID] = queryView; + + HARD_ASSERT(viewChange.snapshot.has_value(), + "applyChangesToDocuments for new view should always return a snapshot"); + return viewChange.snapshot.value(); +} + +- (void)stopListeningToQuery:(FSTQuery *)query { + [self assertDelegateExistsForSelector:_cmd]; + + FSTQueryView *queryView = self.queryViewsByQuery[query]; + HARD_ASSERT(queryView, "Trying to stop listening to a query not found"); + + [self.localStore releaseQuery:query]; + _remoteStore->StopListening(queryView.targetID); + [self removeAndCleanupQuery:queryView]; +} + +- (void)writeMutations:(std::vector &&)mutations + completion:(FSTVoidErrorBlock)completion { + [self assertDelegateExistsForSelector:_cmd]; + + FSTLocalWriteResult *result = [self.localStore locallyWriteMutations:std::move(mutations)]; + [self addMutationCompletionBlock:completion batchID:result.batchID]; + + [self emitNewSnapshotsAndNotifyLocalStoreWithChanges:result.changes remoteEvent:absl::nullopt]; + _remoteStore->FillWritePipeline(); +} + +- (void)addMutationCompletionBlock:(FSTVoidErrorBlock)completion batchID:(BatchId)batchID { + NSMutableDictionary *completionBlocks = + _mutationCompletionBlocks[_currentUser]; + if (!completionBlocks) { + completionBlocks = [NSMutableDictionary dictionary]; + _mutationCompletionBlocks[_currentUser] = completionBlocks; + } + [completionBlocks setObject:completion forKey:@(batchID)]; +} + +/** + * Takes an updateBlock in which a set of reads and writes can be performed atomically. In the + * updateBlock, user code can read and write values using a transaction object. After the + * updateBlock, all changes will be committed. If someone else has changed any of the data + * referenced, then the updateBlock will be called again. If the updateBlock still fails after the + * given number of retries, then the transaction will be rejected. + * + * The transaction object passed to the updateBlock contains methods for accessing documents + * and collections. Unlike other firestore access, data accessed with the transaction will not + * reflect local changes that have not been committed. For this reason, it is required that all + * reads are performed before any writes. Transactions must be performed while online. + */ +- (void)transactionWithRetries:(int)retries + workerQueue:(AsyncQueue *)workerQueue + updateBlock:(FSTTransactionBlock)updateBlock + completion:(FSTVoidIDErrorBlock)completion { + workerQueue->VerifyIsCurrentQueue(); + HARD_ASSERT(retries >= 0, "Got negative number of retries for transaction"); + + std::shared_ptr transaction = _remoteStore->CreateTransaction(); + updateBlock(transaction, ^(id _Nullable result, NSError *_Nullable error) { + workerQueue->Enqueue( + [self, retries, workerQueue, updateBlock, completion, transaction, result, error] { + if (error) { + completion(nil, error); + return; + } + transaction->Commit([self, retries, workerQueue, updateBlock, completion, + result](const Status &status) { + if (status.ok()) { + completion(result, nil); + return; + } + + // TODO(b/35201829): Only retry on real transaction failures. + if (retries == 0) { + NSError *wrappedError = + [NSError errorWithDomain:FIRFirestoreErrorDomain + code:FIRFirestoreErrorCodeFailedPrecondition + userInfo:@{ + NSLocalizedDescriptionKey : @"Transaction failed all retries.", + NSUnderlyingErrorKey : MakeNSError(status) + }]; + completion(nil, wrappedError); + return; + } + workerQueue->VerifyIsCurrentQueue(); + return [self transactionWithRetries:(retries - 1) + workerQueue:workerQueue + updateBlock:updateBlock + completion:completion]; + }); + }); + }); +} + +- (void)applyRemoteEvent:(const RemoteEvent &)remoteEvent { + [self assertDelegateExistsForSelector:_cmd]; + + // Update `receivedDocument` as appropriate for any limbo targets. + for (const auto &entry : remoteEvent.target_changes()) { + TargetId targetID = entry.first; + const TargetChange &change = entry.second; + const auto iter = _limboResolutionsByTarget.find(targetID); + if (iter != _limboResolutionsByTarget.end()) { + LimboResolution &limboResolution = iter->second; + // Since this is a limbo resolution lookup, it's for a single document and it could be + // added, modified, or removed, but not a combination. + HARD_ASSERT(change.added_documents().size() + change.modified_documents().size() + + change.removed_documents().size() <= + 1, + "Limbo resolution for single document contains multiple changes."); + + if (change.added_documents().size() > 0) { + limboResolution.document_received = true; + } else if (change.modified_documents().size() > 0) { + HARD_ASSERT(limboResolution.document_received, + "Received change for limbo target document without add."); + } else if (change.removed_documents().size() > 0) { + HARD_ASSERT(limboResolution.document_received, + "Received remove for limbo target document without add."); + limboResolution.document_received = false; + } else { + // This was probably just a CURRENT targetChange or similar. + } + } + } + + MaybeDocumentMap changes = [self.localStore applyRemoteEvent:remoteEvent]; + [self emitNewSnapshotsAndNotifyLocalStoreWithChanges:changes remoteEvent:remoteEvent]; +} + +- (void)applyChangedOnlineState:(OnlineState)onlineState { + __block std::vector newViewSnapshots; + [self.queryViewsByQuery + enumerateKeysAndObjectsUsingBlock:^(FSTQuery *query, FSTQueryView *queryView, BOOL *stop) { + FSTViewChange *viewChange = [queryView.view applyChangedOnlineState:onlineState]; + HARD_ASSERT(viewChange.limboChanges.count == 0, + "OnlineState should not affect limbo documents."); + if (viewChange.snapshot.has_value()) { + newViewSnapshots.push_back(std::move(viewChange.snapshot.value())); + } + }]; + + [self.syncEngineDelegate handleViewSnapshots:std::move(newViewSnapshots)]; + [self.syncEngineDelegate applyChangedOnlineState:onlineState]; +} + +- (void)rejectListenWithTargetID:(const TargetId)targetID error:(NSError *)error { + [self assertDelegateExistsForSelector:_cmd]; + + const auto iter = _limboResolutionsByTarget.find(targetID); + if (iter != _limboResolutionsByTarget.end()) { + const DocumentKey limboKey = iter->second.key; + // Since this query failed, we won't want to manually unlisten to it. + // So go ahead and remove it from bookkeeping. + _limboTargetsByKey.erase(limboKey); + _limboResolutionsByTarget.erase(targetID); + + // TODO(dimond): Retry on transient errors? + + // It's a limbo doc. Create a synthetic event saying it was deleted. This is kind of a hack. + // Ideally, we would have a method in the local store to purge a document. However, it would + // be tricky to keep all of the local store's invariants with another method. + FSTDeletedDocument *doc = [FSTDeletedDocument documentWithKey:limboKey + version:SnapshotVersion::None() + hasCommittedMutations:NO]; + DocumentKeySet limboDocuments = DocumentKeySet{doc.key}; + RemoteEvent event{SnapshotVersion::None(), /*target_changes=*/{}, /*target_mismatches=*/{}, + /*document_updates=*/{{limboKey, doc}}, std::move(limboDocuments)}; + [self applyRemoteEvent:event]; + } else { + auto found = _queryViewsByTarget.find(targetID); + HARD_ASSERT(found != _queryViewsByTarget.end(), "Unknown targetId: %s", targetID); + FSTQueryView *queryView = found->second; + FSTQuery *query = queryView.query; + [self.localStore releaseQuery:query]; + [self removeAndCleanupQuery:queryView]; + if ([self errorIsInteresting:error]) { + LOG_WARN("Listen for query at %s failed: %s", query.path.CanonicalString(), + error.localizedDescription); + } + [self.syncEngineDelegate handleError:error forQuery:query]; + } +} + +- (void)applySuccessfulWriteWithResult:(FSTMutationBatchResult *)batchResult { + [self assertDelegateExistsForSelector:_cmd]; + + // The local store may or may not be able to apply the write result and raise events immediately + // (depending on whether the watcher is caught up), so we raise user callbacks first so that they + // consistently happen before listen events. + [self processUserCallbacksForBatchID:batchResult.batch.batchID error:nil]; + + MaybeDocumentMap changes = [self.localStore acknowledgeBatchWithResult:batchResult]; + [self emitNewSnapshotsAndNotifyLocalStoreWithChanges:changes remoteEvent:absl::nullopt]; +} + +- (void)rejectFailedWriteWithBatchID:(BatchId)batchID error:(NSError *)error { + [self assertDelegateExistsForSelector:_cmd]; + MaybeDocumentMap changes = [self.localStore rejectBatchID:batchID]; + + if (!changes.empty() && [self errorIsInteresting:error]) { + const DocumentKey &minKey = changes.min()->first; + LOG_WARN("Write at %s failed: %s", minKey.ToString(), error.localizedDescription); + } + + // The local store may or may not be able to apply the write result and raise events immediately + // (depending on whether the watcher is caught up), so we raise user callbacks first so that they + // consistently happen before listen events. + [self processUserCallbacksForBatchID:batchID error:error]; + + [self emitNewSnapshotsAndNotifyLocalStoreWithChanges:changes remoteEvent:absl::nullopt]; +} + +- (void)processUserCallbacksForBatchID:(BatchId)batchID error:(NSError *_Nullable)error { + NSMutableDictionary *completionBlocks = + _mutationCompletionBlocks[_currentUser]; + + // NOTE: Mutations restored from persistence won't have completion blocks, so it's okay for + // this (or the completion below) to be nil. + if (completionBlocks) { + NSNumber *boxedBatchID = @(batchID); + FSTVoidErrorBlock completion = completionBlocks[boxedBatchID]; + if (completion) { + completion(error); + [completionBlocks removeObjectForKey:boxedBatchID]; + } + } +} + +- (void)assertDelegateExistsForSelector:(SEL)methodSelector { + HARD_ASSERT(self.syncEngineDelegate, "Tried to call '%s' before delegate was registered.", + NSStringFromSelector(methodSelector)); +} + +- (void)removeAndCleanupQuery:(FSTQueryView *)queryView { + [self.queryViewsByQuery removeObjectForKey:queryView.query]; + _queryViewsByTarget.erase(queryView.targetID); + + DocumentKeySet limboKeys = _limboDocumentRefs.ReferencedKeys(queryView.targetID); + _limboDocumentRefs.RemoveReferences(queryView.targetID); + for (const DocumentKey &key : limboKeys) { + if (!_limboDocumentRefs.ContainsKey(key)) { + // We removed the last reference for this key. + [self removeLimboTargetForKey:key]; + } + } +} + +/** + * Computes a new snapshot from the changes and calls the registered callback with the new snapshot. + */ +- (void)emitNewSnapshotsAndNotifyLocalStoreWithChanges:(const MaybeDocumentMap &)changes + remoteEvent:(const absl::optional &) + maybeRemoteEvent { + __block std::vector newSnapshots; + NSMutableArray *documentChangesInAllViews = [NSMutableArray array]; + + [self.queryViewsByQuery + enumerateKeysAndObjectsUsingBlock:^(FSTQuery *query, FSTQueryView *queryView, BOOL *stop) { + FSTView *view = queryView.view; + FSTViewDocumentChanges *viewDocChanges = [view computeChangesWithDocuments:changes]; + if (viewDocChanges.needsRefill) { + // The query has a limit and some docs were removed/updated, so we need to re-run the + // query against the local store to make sure we didn't lose any good docs that had been + // past the limit. + DocumentMap docs = [self.localStore executeQuery:queryView.query]; + viewDocChanges = [view computeChangesWithDocuments:docs.underlying_map() + previousChanges:viewDocChanges]; + } + + absl::optional targetChange; + if (maybeRemoteEvent.has_value()) { + const RemoteEvent &remoteEvent = maybeRemoteEvent.value(); + auto it = remoteEvent.target_changes().find(queryView.targetID); + if (it != remoteEvent.target_changes().end()) { + targetChange = it->second; + } + } + FSTViewChange *viewChange = [queryView.view applyChangesToDocuments:viewDocChanges + targetChange:targetChange]; + + [self updateTrackedLimboDocumentsWithChanges:viewChange.limboChanges + targetID:queryView.targetID]; + + if (viewChange.snapshot.has_value()) { + newSnapshots.push_back(viewChange.snapshot.value()); + FSTLocalViewChanges *docChanges = + [FSTLocalViewChanges changesForViewSnapshot:viewChange.snapshot.value() + withTargetID:queryView.targetID]; + [documentChangesInAllViews addObject:docChanges]; + } + }]; + + [self.syncEngineDelegate handleViewSnapshots:std::move(newSnapshots)]; + [self.localStore notifyLocalViewChanges:documentChangesInAllViews]; +} + +/** Updates the limbo document state for the given targetID. */ +- (void)updateTrackedLimboDocumentsWithChanges:(NSArray *)limboChanges + targetID:(TargetId)targetID { + for (FSTLimboDocumentChange *limboChange in limboChanges) { + switch (limboChange.type) { + case FSTLimboDocumentChangeTypeAdded: + _limboDocumentRefs.AddReference(limboChange.key, targetID); + [self trackLimboChange:limboChange]; + break; + + case FSTLimboDocumentChangeTypeRemoved: + LOG_DEBUG("Document no longer in limbo: %s", limboChange.key.ToString()); + _limboDocumentRefs.RemoveReference(limboChange.key, targetID); + if (!_limboDocumentRefs.ContainsKey(limboChange.key)) { + // We removed the last reference for this key + [self removeLimboTargetForKey:limboChange.key]; + } + break; + + default: + HARD_FAIL("Unknown limbo change type: %s", limboChange.type); + } + } +} + +- (void)trackLimboChange:(FSTLimboDocumentChange *)limboChange { + DocumentKey key{limboChange.key}; + + if (_limboTargetsByKey.find(key) == _limboTargetsByKey.end()) { + LOG_DEBUG("New document in limbo: %s", key.ToString()); + TargetId limboTargetID = _targetIdGenerator.NextId(); + FSTQuery *query = [FSTQuery queryWithPath:key.path()]; + FSTQueryData *queryData = [[FSTQueryData alloc] initWithQuery:query + targetID:limboTargetID + listenSequenceNumber:kIrrelevantSequenceNumber + purpose:FSTQueryPurposeLimboResolution]; + _limboResolutionsByTarget.emplace(limboTargetID, LimboResolution{key}); + _remoteStore->Listen(queryData); + _limboTargetsByKey[key] = limboTargetID; + } +} + +- (void)removeLimboTargetForKey:(const DocumentKey &)key { + const auto iter = _limboTargetsByKey.find(key); + if (iter == _limboTargetsByKey.end()) { + // This target already got removed, because the query failed. + return; + } + TargetId limboTargetID = iter->second; + _remoteStore->StopListening(limboTargetID); + _limboTargetsByKey.erase(key); + _limboResolutionsByTarget.erase(limboTargetID); +} + +// Used for testing +- (std::map)currentLimboDocuments { + // Return defensive copy + return _limboTargetsByKey; +} + +- (void)credentialDidChangeWithUser:(const firebase::firestore::auth::User &)user { + BOOL userChanged = (_currentUser != user); + _currentUser = user; + + if (userChanged) { + // Notify local store and emit any resulting events from swapping out the mutation queue. + MaybeDocumentMap changes = [self.localStore userDidChange:user]; + [self emitNewSnapshotsAndNotifyLocalStoreWithChanges:changes remoteEvent:absl::nullopt]; + } + + // Notify remote store so it can restart its streams. + _remoteStore->HandleCredentialChange(); +} + +- (DocumentKeySet)remoteKeysForTarget:(TargetId)targetId { + const auto iter = _limboResolutionsByTarget.find(targetId); + if (iter != _limboResolutionsByTarget.end() && iter->second.document_received) { + return DocumentKeySet{iter->second.key}; + } else { + auto found = _queryViewsByTarget.find(targetId); + FSTQueryView *queryView = found != _queryViewsByTarget.end() ? found->second : nil; + return queryView ? queryView.view.syncedDocuments : DocumentKeySet{}; + } +} + +/** + * Decides if the error likely represents a developer mistake such as forgetting to create an index + * or permission denied. Used to decide whether an error is worth automatically logging as a + * warning. + */ +- (BOOL)errorIsInteresting:(NSError *)error { + if (error.domain == FIRFirestoreErrorDomain) { + if (error.code == FIRFirestoreErrorCodeFailedPrecondition && + [error.localizedDescription containsString:@"requires an index"]) { + return YES; + } else if (error.code == FIRFirestoreErrorCodePermissionDenied) { + return YES; + } + } + + return NO; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Core/FSTTypes.h b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Core/FSTTypes.h new file mode 100644 index 0000000..86c1e94 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Core/FSTTypes.h @@ -0,0 +1,71 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +#include + +namespace firebase { +namespace firestore { +namespace core { + +class Transaction; + +} +} +} + +NS_ASSUME_NONNULL_BEGIN + +@class FSTMaybeDocument; + +/** + * FSTVoidBlock is a block that's called when a specific event happens but that otherwise has + * no information associated with it. + */ +typedef void (^FSTVoidBlock)(void); + +/** + * FSTVoidErrorBlock is a block that gets an error, if one occurred. + * + * @param error The error if it occurred, or nil. + */ +typedef void (^FSTVoidErrorBlock)(NSError *_Nullable error); + +/** FSTVoidIDErrorBlock is a block that takes an optional value and error. */ +typedef void (^FSTVoidIDErrorBlock)(id _Nullable, NSError *_Nullable); + +/** + * FSTVoidMaybeDocumentErrorBlock is a block that gets either a list of documents or an error. + * + * @param documents The documents, if no error occurred, or nil. + * @param error The error, if one occurred, or nil. + */ +typedef void (^FSTVoidMaybeDocumentArrayErrorBlock)( + NSArray *_Nullable documents, NSError *_Nullable error); + +/** + * FSTTransactionBlock is a block that wraps a user's transaction update block internally. + * + * @param transaction An object with methods for performing reads and writes within the + * transaction. + * @param completion To be called by the block once the user's code is finished. + */ +typedef void (^FSTTransactionBlock)( + std::shared_ptr transaction, + void (^completion)(id _Nullable, NSError *_Nullable)); + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Core/FSTView.h b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Core/FSTView.h new file mode 100644 index 0000000..aed8732 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Core/FSTView.h @@ -0,0 +1,170 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +#include "Firestore/core/src/firebase/firestore/core/view_snapshot.h" +#include "Firestore/core/src/firebase/firestore/model/document_key.h" +#include "Firestore/core/src/firebase/firestore/model/document_key_set.h" +#include "Firestore/core/src/firebase/firestore/model/document_map.h" +#include "Firestore/core/src/firebase/firestore/model/types.h" + +#include "absl/types/optional.h" + +namespace firebase { +namespace firestore { +namespace remote { + +class TargetChange; + +} // namespace remote +} // namespace firestore +} // namespace firebase + +@class FSTQuery; + +NS_ASSUME_NONNULL_BEGIN + +#pragma mark - FSTViewDocumentChanges + +/** The result of applying a set of doc changes to a view. */ +@interface FSTViewDocumentChanges : NSObject + +- (instancetype)init NS_UNAVAILABLE; + +- (const firebase::firestore::model::DocumentKeySet &)mutatedKeys; + +/** The new set of docs that should be in the view. */ +- (const firebase::firestore::model::DocumentSet &)documentSet; + +/** The diff of this these docs with the previous set of docs. */ +- (const firebase::firestore::core::DocumentViewChangeSet &)changeSet; + +/** + * Whether the set of documents passed in was not sufficient to calculate the new state of the view + * and there needs to be another pass based on the local cache. + */ +@property(nonatomic, assign, readonly) BOOL needsRefill; + +@end + +#pragma mark - FSTLimboDocumentChange + +typedef NS_ENUM(NSInteger, FSTLimboDocumentChangeType) { + FSTLimboDocumentChangeTypeAdded = 0, + FSTLimboDocumentChangeTypeRemoved, +}; + +// A change to a particular document wrt to whether it is in "limbo". +@interface FSTLimboDocumentChange : NSObject + ++ (instancetype)changeWithType:(FSTLimboDocumentChangeType)type + key:(firebase::firestore::model::DocumentKey)key; + +- (id)init __attribute__((unavailable("Use a static constructor method."))); + +- (const firebase::firestore::model::DocumentKey &)key; + +@property(nonatomic, assign, readonly) FSTLimboDocumentChangeType type; +@end + +#pragma mark - FSTViewChange + +// A set of changes to a view. +@interface FSTViewChange : NSObject + +- (id)init __attribute__((unavailable("Use a static constructor method."))); + +- (absl::optional &)snapshot; +@property(nonatomic, strong, readonly) NSArray *limboChanges; +@end + +#pragma mark - FSTView + +/** + * View is responsible for computing the final merged truth of what docs are in a query. It gets + * notified of local and remote changes to docs, and applies the query filters and limits to + * determine the most correct possible results. + */ +@interface FSTView : NSObject + +- (instancetype)init NS_UNAVAILABLE; + +- (instancetype)initWithQuery:(FSTQuery *)query + remoteDocuments:(firebase::firestore::model::DocumentKeySet)remoteDocuments + NS_DESIGNATED_INITIALIZER; + +/** + * Iterates over a set of doc changes, applies the query limit, and computes what the new results + * should be, what the changes were, and whether we may need to go back to the local cache for + * more results. Does not make any changes to the view. + * + * @param docChanges The doc changes to apply to this view. + * @return a new set of docs, changes, and refill flag. + */ +- (FSTViewDocumentChanges *)computeChangesWithDocuments: + (const firebase::firestore::model::MaybeDocumentMap &)docChanges; + +/** + * Iterates over a set of doc changes, applies the query limit, and computes what the new results + * should be, what the changes were, and whether we may need to go back to the local cache for + * more results. Does not make any changes to the view. + * + * @param docChanges The doc changes to apply to this view. + * @param previousChanges If this is being called with a refill, then start with this set of docs + * and changes instead of the current view. + * @return a new set of docs, changes, and refill flag. + */ +- (FSTViewDocumentChanges *) + computeChangesWithDocuments:(const firebase::firestore::model::MaybeDocumentMap &)docChanges + previousChanges:(nullable FSTViewDocumentChanges *)previousChanges; + +/** + * Updates the view with the given ViewDocumentChanges. + * + * @param docChanges The set of changes to make to the view's docs. + * @return A new FSTViewChange with the given docs, changes, and sync state. + */ +- (FSTViewChange *)applyChangesToDocuments:(FSTViewDocumentChanges *)docChanges; + +/** + * Updates the view with the given FSTViewDocumentChanges and updates limbo docs and sync state from + * the given (optional) target change. + * + * @param docChanges The set of changes to make to the view's docs. + * @param targetChange A target change to apply for computing limbo docs and sync state. + * @return A new FSTViewChange with the given docs, changes, and sync state. + */ +- (FSTViewChange *) + applyChangesToDocuments:(FSTViewDocumentChanges *)docChanges + targetChange: + (const absl::optional &)targetChange; + +/** + * Applies an OnlineState change to the view, potentially generating an FSTViewChange if the + * view's syncState changes as a result. + */ +- (FSTViewChange *)applyChangedOnlineState:(firebase::firestore::model::OnlineState)onlineState; + +/** + * The set of remote documents that the server has told us belongs to the target associated with + * this view. + */ +- (const firebase::firestore::model::DocumentKeySet &)syncedDocuments; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Core/FSTView.mm b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Core/FSTView.mm new file mode 100644 index 0000000..079c547 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Core/FSTView.mm @@ -0,0 +1,528 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "Firestore/Source/Core/FSTView.h" + +#include +#include +#include + +#import "Firestore/Source/Core/FSTQuery.h" +#import "Firestore/Source/Model/FSTDocument.h" +#import "Firestore/Source/Model/FSTFieldValue.h" + +#include "Firestore/core/src/firebase/firestore/core/view_snapshot.h" +#include "Firestore/core/src/firebase/firestore/model/document_key.h" +#include "Firestore/core/src/firebase/firestore/model/document_key_set.h" +#include "Firestore/core/src/firebase/firestore/model/document_set.h" +#include "Firestore/core/src/firebase/firestore/remote/remote_event.h" +#include "Firestore/core/src/firebase/firestore/util/delayed_constructor.h" +#include "Firestore/core/src/firebase/firestore/util/hard_assert.h" + +using firebase::firestore::core::DocumentViewChange; +using firebase::firestore::core::DocumentViewChangeSet; +using firebase::firestore::core::SyncState; +using firebase::firestore::core::ViewSnapshot; +using firebase::firestore::model::DocumentKey; +using firebase::firestore::model::DocumentKeySet; +using firebase::firestore::model::DocumentSet; +using firebase::firestore::model::MaybeDocumentMap; +using firebase::firestore::model::OnlineState; +using firebase::firestore::remote::TargetChange; +using firebase::firestore::util::DelayedConstructor; + +NS_ASSUME_NONNULL_BEGIN + +namespace { + +int GetDocumentViewChangeTypePosition(DocumentViewChange::Type changeType) { + switch (changeType) { + case DocumentViewChange::Type::kRemoved: + return 0; + case DocumentViewChange::Type::kAdded: + return 1; + case DocumentViewChange::Type::kModified: + return 2; + case DocumentViewChange::Type::kMetadata: + // A metadata change is converted to a modified change at the public API layer. Since we sort + // by document key and then change type, metadata and modified changes must be sorted + // equivalently. + return 2; + } + HARD_FAIL("Unknown DocumentViewChange::Type %s", changeType); +} + +} // namespace + +#pragma mark - FSTViewDocumentChanges + +/** The result of applying a set of doc changes to a view. */ +@interface FSTViewDocumentChanges () + +- (instancetype)initWithDocumentSet:(DocumentSet)documentSet + changeSet:(DocumentViewChangeSet &&)changeSet + needsRefill:(BOOL)needsRefill + mutatedKeys:(DocumentKeySet)mutatedKeys NS_DESIGNATED_INITIALIZER; + +@end + +@implementation FSTViewDocumentChanges { + DelayedConstructor _documentSet; + DocumentKeySet _mutatedKeys; + DocumentViewChangeSet _changeSet; +} + +- (instancetype)initWithDocumentSet:(DocumentSet)documentSet + changeSet:(DocumentViewChangeSet &&)changeSet + needsRefill:(BOOL)needsRefill + mutatedKeys:(DocumentKeySet)mutatedKeys { + self = [super init]; + if (self) { + _documentSet.Init(std::move(documentSet)); + _changeSet = std::move(changeSet); + _needsRefill = needsRefill; + _mutatedKeys = std::move(mutatedKeys); + } + return self; +} + +- (const DocumentKeySet &)mutatedKeys { + return _mutatedKeys; +} + +- (const firebase::firestore::model::DocumentSet &)documentSet { + return *_documentSet; +} + +- (const firebase::firestore::core::DocumentViewChangeSet &)changeSet { + return _changeSet; +} + +@end + +#pragma mark - FSTLimboDocumentChange + +@interface FSTLimboDocumentChange () + ++ (instancetype)changeWithType:(FSTLimboDocumentChangeType)type key:(DocumentKey)key; + +- (instancetype)initWithType:(FSTLimboDocumentChangeType)type + key:(DocumentKey)key NS_DESIGNATED_INITIALIZER; + +@end + +@implementation FSTLimboDocumentChange { + DocumentKey _key; +} + ++ (instancetype)changeWithType:(FSTLimboDocumentChangeType)type key:(DocumentKey)key { + return [[FSTLimboDocumentChange alloc] initWithType:type key:std::move(key)]; +} + +- (instancetype)initWithType:(FSTLimboDocumentChangeType)type key:(DocumentKey)key { + self = [super init]; + if (self) { + _type = type; + _key = std::move(key); + } + return self; +} + +- (const DocumentKey &)key { + return _key; +} + +- (BOOL)isEqual:(id)other { + if (self == other) { + return YES; + } + if (![other isKindOfClass:[FSTLimboDocumentChange class]]) { + return NO; + } + FSTLimboDocumentChange *otherChange = (FSTLimboDocumentChange *)other; + return self.type == otherChange.type && self.key == otherChange.key; +} + +- (NSUInteger)hash { + NSUInteger hash = self.type; + hash = hash * 31u + self.key.Hash(); + return hash; +} + +@end + +#pragma mark - FSTViewChange + +@interface FSTViewChange () + ++ (FSTViewChange *)changeWithSnapshot:(absl::optional &&)snapshot + limboChanges:(NSArray *)limboChanges; + +- (instancetype)initWithSnapshot:(absl::optional &&)snapshot + limboChanges:(NSArray *)limboChanges + NS_DESIGNATED_INITIALIZER; + +@end + +@implementation FSTViewChange { + absl::optional _snapshot; +} + ++ (FSTViewChange *)changeWithSnapshot:(absl::optional &&)snapshot + limboChanges:(NSArray *)limboChanges { + return [[self alloc] initWithSnapshot:std::move(snapshot) limboChanges:limboChanges]; +} + +- (instancetype)initWithSnapshot:(absl::optional &&)snapshot + limboChanges:(NSArray *)limboChanges { + self = [super init]; + if (self) { + _snapshot = std::move(snapshot); + _limboChanges = limboChanges; + } + return self; +} + +- (absl::optional &)snapshot { + return _snapshot; +} + +@end + +#pragma mark - FSTView + +@interface FSTView () + +@property(nonatomic, strong, readonly) FSTQuery *query; + +@property(nonatomic, assign) firebase::firestore::core::SyncState syncState; + +/** + * A flag whether the view is current with the backend. A view is considered current after it + * has seen the current flag from the backend and did not lose consistency within the watch stream + * (e.g. because of an existence filter mismatch). + */ +@property(nonatomic, assign, getter=isCurrent) BOOL current; + +@end + +@implementation FSTView { + DelayedConstructor _documentSet; + + /** Documents included in the remote target. */ + DocumentKeySet _syncedDocuments; + + /** Documents in the view but not in the remote target */ + DocumentKeySet _limboDocuments; + + /** Document Keys that have local changes. */ + DocumentKeySet _mutatedKeys; +} + +- (instancetype)initWithQuery:(FSTQuery *)query remoteDocuments:(DocumentKeySet)remoteDocuments { + self = [super init]; + if (self) { + _query = query; + _documentSet.Init(query.comparator); + _syncedDocuments = std::move(remoteDocuments); + } + return self; +} + +- (const DocumentKeySet &)syncedDocuments { + return _syncedDocuments; +} + +- (FSTViewDocumentChanges *)computeChangesWithDocuments:(const MaybeDocumentMap &)docChanges { + return [self computeChangesWithDocuments:docChanges previousChanges:nil]; +} + +- (FSTViewDocumentChanges *)computeChangesWithDocuments:(const MaybeDocumentMap &)docChanges + previousChanges: + (nullable FSTViewDocumentChanges *)previousChanges { + DocumentViewChangeSet changeSet; + if (previousChanges) { + changeSet = previousChanges.changeSet; + } + DocumentSet oldDocumentSet = previousChanges ? previousChanges.documentSet : *_documentSet; + + DocumentKeySet newMutatedKeys = previousChanges ? previousChanges.mutatedKeys : _mutatedKeys; + DocumentKeySet oldMutatedKeys = _mutatedKeys; + DocumentSet newDocumentSet = oldDocumentSet; + BOOL needsRefill = NO; + + // Track the last doc in a (full) limit. This is necessary, because some update (a delete, or an + // update moving a doc past the old limit) might mean there is some other document in the local + // cache that either should come (1) between the old last limit doc and the new last document, + // in the case of updates, or (2) after the new last document, in the case of deletes. So we + // keep this doc at the old limit to compare the updates to. + // + // Note that this should never get used in a refill (when previousChanges is set), because there + // will only be adds -- no deletes or updates. + FSTDocument *_Nullable lastDocInLimit = + (self.query.limit != NSNotFound && oldDocumentSet.size() == self.query.limit) + ? oldDocumentSet.GetLastDocument() + : nil; + + for (const auto &kv : docChanges) { + const DocumentKey &key = kv.first; + FSTMaybeDocument *maybeNewDoc = kv.second; + + FSTDocument *_Nullable oldDoc = oldDocumentSet.GetDocument(key); + FSTDocument *_Nullable newDoc = nil; + if ([maybeNewDoc isKindOfClass:[FSTDocument class]]) { + newDoc = (FSTDocument *)maybeNewDoc; + } + if (newDoc) { + HARD_ASSERT(key == newDoc.key, "Mismatching key in document changes: %s != %s", + key.ToString(), newDoc.key.ToString()); + if (![self.query matchesDocument:newDoc]) { + newDoc = nil; + } + } + + BOOL oldDocHadPendingMutations = oldDoc && oldMutatedKeys.contains(oldDoc.key); + + // We only consider committed mutations for documents that were mutated during the lifetime of + // the view. + BOOL newDocHasPendingMutations = + newDoc && (newDoc.hasLocalMutations || + (oldMutatedKeys.contains(newDoc.key) && newDoc.hasCommittedMutations)); + + BOOL changeApplied = NO; + // Calculate change + if (oldDoc && newDoc) { + BOOL docsEqual = [oldDoc.data isEqual:newDoc.data]; + if (!docsEqual) { + if (![self shouldWaitForSyncedDocument:newDoc oldDocument:oldDoc]) { + changeSet.AddChange(DocumentViewChange{newDoc, DocumentViewChange::Type::kModified}); + changeApplied = YES; + + if (lastDocInLimit && self.query.comparator(newDoc, lastDocInLimit) > 0) { + // This doc moved from inside the limit to after the limit. That means there may be + // some doc in the local cache that's actually less than this one. + needsRefill = YES; + } + } + } else if (oldDocHadPendingMutations != newDocHasPendingMutations) { + changeSet.AddChange(DocumentViewChange{newDoc, DocumentViewChange::Type::kMetadata}); + changeApplied = YES; + } + + } else if (!oldDoc && newDoc) { + changeSet.AddChange(DocumentViewChange{newDoc, DocumentViewChange::Type::kAdded}); + changeApplied = YES; + } else if (oldDoc && !newDoc) { + changeSet.AddChange(DocumentViewChange{oldDoc, DocumentViewChange::Type::kRemoved}); + changeApplied = YES; + + if (lastDocInLimit) { + // A doc was removed from a full limit query. We'll need to re-query from the local cache + // to see if we know about some other doc that should be in the results. + needsRefill = YES; + } + } + + if (changeApplied) { + if (newDoc) { + newDocumentSet = newDocumentSet.insert(newDoc); + if (newDoc.hasLocalMutations) { + newMutatedKeys = newMutatedKeys.insert(key); + } else { + newMutatedKeys = newMutatedKeys.erase(key); + } + } else { + newDocumentSet = newDocumentSet.erase(key); + newMutatedKeys = newMutatedKeys.erase(key); + } + } + } + + if (self.query.limit != NSNotFound && newDocumentSet.size() > self.query.limit) { + for (size_t i = newDocumentSet.size() - self.query.limit; i > 0; --i) { + FSTDocument *oldDoc = newDocumentSet.GetLastDocument(); + newDocumentSet = newDocumentSet.erase(oldDoc.key); + newMutatedKeys = newMutatedKeys.erase(oldDoc.key); + changeSet.AddChange(DocumentViewChange{oldDoc, DocumentViewChange::Type::kRemoved}); + } + } + + HARD_ASSERT(!needsRefill || !previousChanges, + "View was refilled using docs that themselves needed refilling."); + + return [[FSTViewDocumentChanges alloc] initWithDocumentSet:std::move(newDocumentSet) + changeSet:std::move(changeSet) + needsRefill:needsRefill + mutatedKeys:newMutatedKeys]; +} + +- (BOOL)shouldWaitForSyncedDocument:(FSTDocument *)newDoc oldDocument:(FSTDocument *)oldDoc { + // We suppress the initial change event for documents that were modified as part of a write + // acknowledgment (e.g. when the value of a server transform is applied) as Watch will send us + // the same document again. By suppressing the event, we only raise two user visible events (one + // with `hasPendingWrites` and the final state of the document) instead of three (one with + // `hasPendingWrites`, the modified document with `hasPendingWrites` and the final state of the + // document). + return (oldDoc.hasLocalMutations && newDoc.hasCommittedMutations && !newDoc.hasLocalMutations); +} + +- (FSTViewChange *)applyChangesToDocuments:(FSTViewDocumentChanges *)docChanges { + return [self applyChangesToDocuments:docChanges targetChange:{}]; +} + +- (FSTViewChange *)applyChangesToDocuments:(FSTViewDocumentChanges *)docChanges + targetChange:(const absl::optional &)targetChange { + HARD_ASSERT(!docChanges.needsRefill, "Cannot apply changes that need a refill"); + + DocumentSet oldDocuments = *_documentSet; + *_documentSet = docChanges.documentSet; + _mutatedKeys = docChanges.mutatedKeys; + + // Sort changes based on type and query comparator. + std::vector changes = docChanges.changeSet.GetChanges(); + std::sort(changes.begin(), changes.end(), + [self](const DocumentViewChange &lhs, const DocumentViewChange &rhs) { + int pos1 = GetDocumentViewChangeTypePosition(lhs.type()); + int pos2 = GetDocumentViewChangeTypePosition(rhs.type()); + if (pos1 != pos2) { + return pos1 < pos2; + } + return self.query.comparator(lhs.document(), rhs.document()) == NSOrderedAscending; + }); + + [self applyTargetChange:targetChange]; + NSArray *limboChanges = [self updateLimboDocuments]; + BOOL synced = _limboDocuments.empty() && self.isCurrent; + SyncState newSyncState = synced ? SyncState::Synced : SyncState::Local; + bool syncStateChanged = newSyncState != self.syncState; + self.syncState = newSyncState; + + if (changes.empty() && !syncStateChanged) { + // No changes. + return [FSTViewChange changeWithSnapshot:absl::nullopt limboChanges:limboChanges]; + } else { + ViewSnapshot snapshot{self.query, + docChanges.documentSet, + oldDocuments, + std::move(changes), + docChanges.mutatedKeys, + /*from_cache=*/newSyncState == SyncState::Local, + syncStateChanged, + /*excludes_metadata_changes=*/false}; + + return [FSTViewChange changeWithSnapshot:std::move(snapshot) limboChanges:limboChanges]; + } +} + +- (FSTViewChange *)applyChangedOnlineState:(OnlineState)onlineState { + if (self.isCurrent && onlineState == OnlineState::Offline) { + // If we're offline, set `current` to NO and then call applyChanges to refresh our syncState + // and generate an FSTViewChange as appropriate. We are guaranteed to get a new `TargetChange` + // that sets `current` back to YES once the client is back online. + self.current = NO; + return [self applyChangesToDocuments:[[FSTViewDocumentChanges alloc] + initWithDocumentSet:*_documentSet + changeSet:DocumentViewChangeSet {} + needsRefill:NO + mutatedKeys:_mutatedKeys]]; + } else { + // No effect, just return a no-op FSTViewChange. + return [[FSTViewChange alloc] initWithSnapshot:absl::nullopt limboChanges:@[]]; + } +} + +#pragma mark - Private methods + +/** Returns whether the doc for the given key should be in limbo. */ +- (BOOL)shouldBeLimboDocumentKey:(const DocumentKey &)key { + // If the remote end says it's part of this query, it's not in limbo. + if (_syncedDocuments.contains(key)) { + return NO; + } + // The local store doesn't think it's a result, so it shouldn't be in limbo. + if (!_documentSet->ContainsKey(key)) { + return NO; + } + // If there are local changes to the doc, they might explain why the server doesn't know that it's + // part of the query. So don't put it in limbo. + // TODO(klimt): Ideally, we would only consider changes that might actually affect this specific + // query. + if (_documentSet->GetDocument(key).hasLocalMutations) { + return NO; + } + // Everything else is in limbo. + return YES; +} + +/** + * Updates syncedDocuments and current based on the given change. + */ +- (void)applyTargetChange:(const absl::optional &)maybeTargetChange { + if (maybeTargetChange.has_value()) { + const TargetChange &target_change = maybeTargetChange.value(); + + for (const DocumentKey &key : target_change.added_documents()) { + _syncedDocuments = _syncedDocuments.insert(key); + } + for (const DocumentKey &key : target_change.modified_documents()) { + HARD_ASSERT(_syncedDocuments.find(key) != _syncedDocuments.end(), + "Modified document %s not found in view.", key.ToString()); + } + for (const DocumentKey &key : target_change.removed_documents()) { + _syncedDocuments = _syncedDocuments.erase(key); + } + + self.current = target_change.current(); + } +} + +/** Updates limboDocuments and returns any changes as FSTLimboDocumentChanges. */ +- (NSArray *)updateLimboDocuments { + // We can only determine limbo documents when we're in-sync with the server. + if (!self.isCurrent) { + return @[]; + } + + // TODO(klimt): Do this incrementally so that it's not quadratic when updating many documents. + DocumentKeySet oldLimboDocuments = std::move(_limboDocuments); + _limboDocuments = DocumentKeySet{}; + for (FSTDocument *doc : *_documentSet) { + if ([self shouldBeLimboDocumentKey:doc.key]) { + _limboDocuments = _limboDocuments.insert(doc.key); + } + } + + // Diff the new limbo docs with the old limbo docs. + NSMutableArray *changes = + [NSMutableArray arrayWithCapacity:(oldLimboDocuments.size() + _limboDocuments.size())]; + for (const DocumentKey &key : oldLimboDocuments) { + if (!_limboDocuments.contains(key)) { + [changes addObject:[FSTLimboDocumentChange changeWithType:FSTLimboDocumentChangeTypeRemoved + key:key]]; + } + } + for (const DocumentKey &key : _limboDocuments) { + if (!oldLimboDocuments.contains(key)) { + [changes addObject:[FSTLimboDocumentChange changeWithType:FSTLimboDocumentChangeTypeAdded + key:key]]; + } + } + return changes; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Local/FSTLRUGarbageCollector.h b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Local/FSTLRUGarbageCollector.h new file mode 100644 index 0000000..9d59813 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Local/FSTLRUGarbageCollector.h @@ -0,0 +1,166 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#import + +#include +#include + +#import "FIRFirestoreSettings.h" +#import "Firestore/Source/Local/FSTQueryData.h" + +#include "Firestore/core/src/firebase/firestore/local/query_cache.h" +#include "Firestore/core/src/firebase/firestore/model/document_key.h" +#include "Firestore/core/src/firebase/firestore/model/types.h" + +@class FSTLRUGarbageCollector; + +extern const firebase::firestore::model::ListenSequenceNumber kFSTListenSequenceNumberInvalid; + +namespace firebase { +namespace firestore { +namespace local { + +struct LruParams { + static const int64_t CacheSizeUnlimited = -1; + + static LruParams Default() { + return LruParams{100 * 1024 * 1024, 10, 1000}; + } + + static LruParams Disabled() { + return LruParams{kFIRFirestoreCacheSizeUnlimited, 0, 0}; + } + + static LruParams WithCacheSize(int64_t cacheSize) { + LruParams params = Default(); + params.minBytesThreshold = cacheSize; + return params; + } + + int64_t minBytesThreshold; + int percentileToCollect; + int maximumSequenceNumbersToCollect; +}; + +struct LruResults { + static LruResults DidNotRun() { + return LruResults{/* didRun= */ false, 0, 0, 0}; + } + + bool didRun; + int sequenceNumbersCollected; + int targetsRemoved; + int documentsRemoved; +}; + +} // namespace local +} // namespace firestore +} // namespace firebase + +/** + * Persistence layers intending to use LRU Garbage collection should implement this protocol. This + * protocol defines the operations that the LRU garbage collector needs from the persistence layer. + */ +@protocol FSTLRUDelegate + +/** + * Enumerates all the targets that the delegate is aware of. This is typically all of the targets in + * an FSTQueryCache. + */ +- (void)enumerateTargetsUsingCallback:(const firebase::firestore::local::TargetCallback &)callback; + +/** + * Enumerates all of the outstanding mutations. + */ +- (void)enumerateMutationsUsingCallback: + (const firebase::firestore::local::OrphanedDocumentCallback &)callback; + +/** + * Removes all unreferenced documents from the cache that have a sequence number less than or equal + * to the given sequence number. Returns the number of documents removed. + */ +- (int)removeOrphanedDocumentsThroughSequenceNumber: + (firebase::firestore::model::ListenSequenceNumber)sequenceNumber; + +/** + * Removes all targets that are not currently being listened to and have a sequence number less than + * or equal to the given sequence number. Returns the number of targets removed. + */ +- (int)removeTargetsThroughSequenceNumber: + (firebase::firestore::model::ListenSequenceNumber)sequenceNumber + liveQueries: + (const std::unordered_map &)liveQueries; + +- (size_t)byteSize; + +/** Returns the number of targets and orphaned documents cached. */ +- (size_t)sequenceNumberCount; + +/** Access to the underlying LRU Garbage collector instance. */ +@property(strong, nonatomic, readonly) FSTLRUGarbageCollector *gc; + +@end + +/** + * FSTLRUGarbageCollector defines the LRU algorithm used to clean up old documents and targets. It + * is persistence-agnostic, as long as proper delegate is provided. + */ +@interface FSTLRUGarbageCollector : NSObject + +- (instancetype)initWithDelegate:(id)delegate + params:(firebase::firestore::local::LruParams)params + NS_DESIGNATED_INITIALIZER; + +- (instancetype)init NS_UNAVAILABLE; + +/** + * Given a target percentile, return the number of queries that make up that percentage of the + * queries that are cached. For instance, if 20 queries are cached, and the percentile is 40, the + * result will be 8. + */ +- (int)queryCountForPercentile:(NSUInteger)percentile; + +/** + * Given a number of queries n, return the nth sequence number in the cache. + */ +- (firebase::firestore::model::ListenSequenceNumber)sequenceNumberForQueryCount: + (NSUInteger)queryCount; + +/** + * Removes queries that are not currently live (as indicated by presence in the liveQueries map) and + * have a sequence number less than or equal to the given sequence number. + */ +- (int)removeQueriesUpThroughSequenceNumber: + (firebase::firestore::model::ListenSequenceNumber)sequenceNumber + liveQueries: + (const std::unordered_map &)liveQueries; + +/** + * Removes all unreferenced documents from the cache that have a sequence number less than or equal + * to the given sequence number. Returns the number of documents removed. + */ +- (int)removeOrphanedDocumentsThroughSequenceNumber: + (firebase::firestore::model::ListenSequenceNumber)sequenceNumber; + +- (size_t)byteSize; + +- (firebase::firestore::local::LruResults)collectWithLiveTargets: + (const std::unordered_map &)liveTargets; + +@end diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Local/FSTLRUGarbageCollector.mm b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Local/FSTLRUGarbageCollector.mm new file mode 100644 index 0000000..95a86fa --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Local/FSTLRUGarbageCollector.mm @@ -0,0 +1,187 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#import "Firestore/Source/Local/FSTLRUGarbageCollector.h" + +#include //NOLINT(build/c++11) +#include +#include + +#import "Firestore/Source/Local/FSTPersistence.h" +#include "Firestore/core/include/firebase/firestore/timestamp.h" +#include "Firestore/core/src/firebase/firestore/model/document_key.h" +#include "Firestore/core/src/firebase/firestore/util/log.h" + +using Millis = std::chrono::milliseconds; +using firebase::Timestamp; +using firebase::firestore::local::LruParams; +using firebase::firestore::local::LruResults; +using firebase::firestore::model::DocumentKey; +using firebase::firestore::model::ListenSequenceNumber; +using firebase::firestore::model::TargetId; + +const int64_t kFIRFirestoreCacheSizeUnlimited = LruParams::CacheSizeUnlimited; +const ListenSequenceNumber kFSTListenSequenceNumberInvalid = -1; + +static Millis::rep millisecondsBetween(const Timestamp &start, const Timestamp &end) { + return std::chrono::duration_cast(end.ToTimePoint() - start.ToTimePoint()).count(); +} + +/** + * RollingSequenceNumberBuffer tracks the nth sequence number in a series. Sequence numbers may be + * added out of order. + */ +class RollingSequenceNumberBuffer { + public: + explicit RollingSequenceNumberBuffer(size_t max_elements) + : queue_(std::priority_queue()), max_elements_(max_elements) { + } + + RollingSequenceNumberBuffer(const RollingSequenceNumberBuffer &other) = delete; + + RollingSequenceNumberBuffer &operator=(const RollingSequenceNumberBuffer &other) = delete; + + void AddElement(ListenSequenceNumber sequence_number) { + if (queue_.size() < max_elements_) { + queue_.push(sequence_number); + } else { + ListenSequenceNumber highestValue = queue_.top(); + if (sequence_number < highestValue) { + queue_.pop(); + queue_.push(sequence_number); + } + } + } + + ListenSequenceNumber max_value() const { + return queue_.top(); + } + + size_t size() const { + return queue_.size(); + } + + private: + std::priority_queue queue_; + const size_t max_elements_; +}; + +@implementation FSTLRUGarbageCollector { + __weak id _delegate; + LruParams _params; +} + +- (instancetype)initWithDelegate:(id)delegate params:(LruParams)params { + self = [super init]; + if (self) { + _delegate = delegate; + _params = std::move(params); + } + return self; +} + +- (LruResults)collectWithLiveTargets: + (const std::unordered_map &)liveTargets { + if (_params.minBytesThreshold == kFIRFirestoreCacheSizeUnlimited) { + LOG_DEBUG("Garbage collection skipped; disabled"); + return LruResults::DidNotRun(); + } + + size_t currentSize = [self byteSize]; + if (currentSize < _params.minBytesThreshold) { + // Not enough on disk to warrant collection. Wait another timeout cycle. + LOG_DEBUG("Garbage collection skipped; Cache size %s is lower than threshold %s", currentSize, + _params.minBytesThreshold); + return LruResults::DidNotRun(); + } else { + LOG_DEBUG("Running garbage collection on cache of size: %s", currentSize); + return [self runGCWithLiveTargets:liveTargets]; + } +} + +- (LruResults)runGCWithLiveTargets: + (const std::unordered_map &)liveTargets { + Timestamp start = Timestamp::Now(); + int sequenceNumbers = [self queryCountForPercentile:_params.percentileToCollect]; + // Cap at the configured max + if (sequenceNumbers > _params.maximumSequenceNumbersToCollect) { + sequenceNumbers = _params.maximumSequenceNumbersToCollect; + } + Timestamp countedTargets = Timestamp::Now(); + + ListenSequenceNumber upperBound = [self sequenceNumberForQueryCount:sequenceNumbers]; + Timestamp foundUpperBound = Timestamp::Now(); + + int numTargetsRemoved = [self removeQueriesUpThroughSequenceNumber:upperBound + liveQueries:liveTargets]; + Timestamp removedTargets = Timestamp::Now(); + + int numDocumentsRemoved = [self removeOrphanedDocumentsThroughSequenceNumber:upperBound]; + Timestamp removedDocuments = Timestamp::Now(); + + std::string desc = "LRU Garbage Collection:\n"; + absl::StrAppend(&desc, "\tCounted targets in ", millisecondsBetween(start, countedTargets), + "ms\n"); + absl::StrAppend(&desc, "\tDetermined least recently used ", sequenceNumbers, + " sequence numbers in ", millisecondsBetween(countedTargets, foundUpperBound), + "ms\n"); + absl::StrAppend(&desc, "\tRemoved ", numTargetsRemoved, " targets in ", + millisecondsBetween(foundUpperBound, removedTargets), "ms\n"); + absl::StrAppend(&desc, "\tRemoved ", numDocumentsRemoved, " documents in ", + millisecondsBetween(removedTargets, removedDocuments), "ms\n"); + absl::StrAppend(&desc, "Total duration: ", millisecondsBetween(start, removedDocuments), "ms"); + LOG_DEBUG(desc.c_str()); + + return LruResults{/* didRun= */ true, sequenceNumbers, numTargetsRemoved, numDocumentsRemoved}; +} + +- (int)queryCountForPercentile:(NSUInteger)percentile { + size_t totalCount = [_delegate sequenceNumberCount]; + int setSize = (int)((percentile / 100.0f) * totalCount); + return setSize; +} + +- (ListenSequenceNumber)sequenceNumberForQueryCount:(NSUInteger)queryCount { + if (queryCount == 0) { + return kFSTListenSequenceNumberInvalid; + } + RollingSequenceNumberBuffer buffer(queryCount); + + [_delegate enumerateTargetsUsingCallback:[&buffer](FSTQueryData *queryData) { + buffer.AddElement(queryData.sequenceNumber); + }]; + [_delegate enumerateMutationsUsingCallback:[&buffer](const DocumentKey &docKey, + ListenSequenceNumber sequenceNumber) { + buffer.AddElement(sequenceNumber); + }]; + return buffer.max_value(); +} + +- (int)removeQueriesUpThroughSequenceNumber:(ListenSequenceNumber)sequenceNumber + liveQueries:(const std::unordered_map &) + liveQueries { + return [_delegate removeTargetsThroughSequenceNumber:sequenceNumber liveQueries:liveQueries]; +} + +- (int)removeOrphanedDocumentsThroughSequenceNumber:(ListenSequenceNumber)sequenceNumber { + return [_delegate removeOrphanedDocumentsThroughSequenceNumber:sequenceNumber]; +} + +- (size_t)byteSize { + return [_delegate byteSize]; +} + +@end diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Local/FSTLevelDB.h b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Local/FSTLevelDB.h new file mode 100644 index 0000000..2ef3f6e --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Local/FSTLevelDB.h @@ -0,0 +1,90 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +#include +#include +#include + +#import "Firestore/Source/Local/FSTLRUGarbageCollector.h" +#import "Firestore/Source/Local/FSTPersistence.h" +#include "Firestore/core/src/firebase/firestore/core/database_info.h" +#include "Firestore/core/src/firebase/firestore/local/leveldb_transaction.h" +#include "Firestore/core/src/firebase/firestore/util/path.h" +#include "Firestore/core/src/firebase/firestore/util/status.h" +#include "Firestore/core/src/firebase/firestore/util/statusor.h" +#include "leveldb/db.h" + +@class FSTLocalSerializer; + +NS_ASSUME_NONNULL_BEGIN + +@interface FSTLevelDBLRUDelegate : NSObject +@end + +/** A LevelDB-backed instance of FSTPersistence. */ +// TODO(mikelehen): Rename to FSTLevelDBPersistence. +@interface FSTLevelDB : NSObject + +/** + * Creates a LevelDB in the given directory and sets `ptr` to point to it. Return value indicates + * success in creating the leveldb instance and must be checked before accessing `ptr`. C++ note: + * Once FSTLevelDB is ported to C++, this factory method should return StatusOr<>. It cannot + * currently do that because ObjC references are not allowed in StatusOr. + */ ++ (firebase::firestore::util::Status)dbWithDirectory:(firebase::firestore::util::Path)directory + serializer:(FSTLocalSerializer *)serializer + lruParams: + (firebase::firestore::local::LruParams)lruParams + ptr:(FSTLevelDB *_Nullable *_Nonnull)ptr; + +- (instancetype)init NS_UNAVAILABLE; + +/** Finds a suitable directory to serve as the root of all Firestore local storage. */ ++ (firebase::firestore::util::Path)documentsDirectory; + +/** + * Computes a unique storage directory for the given identifying components of local storage. + * + * @param databaseInfo The identifying information for the local storage instance. + * @param documentsDirectory The root document directory relative to which the storage directory + * will be created. Usually just +[FSTLevelDB documentsDir]. + * @return A storage directory unique to the instance identified by databaseInfo. + */ ++ (firebase::firestore::util::Path) + storageDirectoryForDatabaseInfo:(const firebase::firestore::core::DatabaseInfo &)databaseInfo + documentsDirectory:(const firebase::firestore::util::Path &)documentsDirectory; + +/** + * @return A standard set of read options + */ ++ (const leveldb::ReadOptions)standardReadOptions; + +/** The native db pointer, allocated during start. */ +@property(nonatomic, assign, readonly) leveldb::DB *ptr; + +@property(nonatomic, readonly) firebase::firestore::local::LevelDbTransaction *currentTransaction; + +@property(nonatomic, readonly) const std::set &users; + +@property(nonatomic, readonly, strong) FSTLevelDBLRUDelegate *referenceDelegate; + +@property(nonatomic, readonly, strong) FSTLocalSerializer *serializer; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Local/FSTLevelDB.mm b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Local/FSTLevelDB.mm new file mode 100644 index 0000000..478e68a --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Local/FSTLevelDB.mm @@ -0,0 +1,524 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "Firestore/Source/Local/FSTLevelDB.h" + +#include +#include +#include + +#import "FIRFirestoreErrors.h" +#import "Firestore/Source/Local/FSTLRUGarbageCollector.h" +#import "Firestore/Source/Remote/FSTSerializerBeta.h" + +#include "Firestore/core/include/firebase/firestore/firestore_errors.h" +#include "Firestore/core/src/firebase/firestore/auth/user.h" +#include "Firestore/core/src/firebase/firestore/core/database_info.h" +#include "Firestore/core/src/firebase/firestore/local/index_manager.h" +#include "Firestore/core/src/firebase/firestore/local/leveldb_index_manager.h" +#include "Firestore/core/src/firebase/firestore/local/leveldb_key.h" +#include "Firestore/core/src/firebase/firestore/local/leveldb_migrations.h" +#include "Firestore/core/src/firebase/firestore/local/leveldb_mutation_queue.h" +#include "Firestore/core/src/firebase/firestore/local/leveldb_query_cache.h" +#include "Firestore/core/src/firebase/firestore/local/leveldb_remote_document_cache.h" +#include "Firestore/core/src/firebase/firestore/local/leveldb_transaction.h" +#include "Firestore/core/src/firebase/firestore/local/leveldb_util.h" +#include "Firestore/core/src/firebase/firestore/local/listen_sequence.h" +#include "Firestore/core/src/firebase/firestore/local/reference_set.h" +#include "Firestore/core/src/firebase/firestore/local/remote_document_cache.h" +#include "Firestore/core/src/firebase/firestore/model/database_id.h" +#include "Firestore/core/src/firebase/firestore/model/document_key.h" +#include "Firestore/core/src/firebase/firestore/model/resource_path.h" +#include "Firestore/core/src/firebase/firestore/model/types.h" +#include "Firestore/core/src/firebase/firestore/util/filesystem.h" +#include "Firestore/core/src/firebase/firestore/util/hard_assert.h" +#include "Firestore/core/src/firebase/firestore/util/ordered_code.h" +#include "Firestore/core/src/firebase/firestore/util/statusor.h" +#include "Firestore/core/src/firebase/firestore/util/string_apple.h" +#include "Firestore/core/src/firebase/firestore/util/string_util.h" +#include "absl/memory/memory.h" +#include "absl/strings/match.h" +#include "absl/strings/str_cat.h" +#include "leveldb/db.h" + +NS_ASSUME_NONNULL_BEGIN + +namespace util = firebase::firestore::util; +using firebase::firestore::FirestoreErrorCode; +using firebase::firestore::auth::User; +using firebase::firestore::core::DatabaseInfo; +using firebase::firestore::local::ConvertStatus; +using firebase::firestore::local::IndexManager; +using firebase::firestore::local::LevelDbDocumentMutationKey; +using firebase::firestore::local::LevelDbDocumentTargetKey; +using firebase::firestore::local::LevelDbIndexManager; +using firebase::firestore::local::LevelDbMigrations; +using firebase::firestore::local::LevelDbMutationKey; +using firebase::firestore::local::LevelDbMutationQueue; +using firebase::firestore::local::LevelDbQueryCache; +using firebase::firestore::local::LevelDbRemoteDocumentCache; +using firebase::firestore::local::LevelDbTransaction; +using firebase::firestore::local::ListenSequence; +using firebase::firestore::local::LruParams; +using firebase::firestore::local::OrphanedDocumentCallback; +using firebase::firestore::local::ReferenceSet; +using firebase::firestore::local::RemoteDocumentCache; +using firebase::firestore::local::TargetCallback; +using firebase::firestore::model::DatabaseId; +using firebase::firestore::model::DocumentKey; +using firebase::firestore::model::ListenSequenceNumber; +using firebase::firestore::model::ResourcePath; +using firebase::firestore::model::TargetId; +using firebase::firestore::util::OrderedCode; +using firebase::firestore::util::Path; +using firebase::firestore::util::Status; +using firebase::firestore::util::StatusOr; +using firebase::firestore::util::StringFormat; +using leveldb::DB; +using leveldb::Options; +using leveldb::ReadOptions; +using leveldb::WriteOptions; + +static const char *kReservedPathComponent = "firestore"; + +@interface FSTLevelDB () + +- (size_t)byteSize; + +@property(nonatomic, assign, getter=isStarted) BOOL started; + +- (LevelDbQueryCache *)queryCache; + +- (LevelDbMutationQueue *)mutationQueueForUser:(const User &)user; + +@end + +/** + * Provides LRU functionality for leveldb persistence. + * + * Although this could implement FSTTransactional, it doesn't because it is not directly tied to + * a transaction runner, it just happens to be called from FSTLevelDB, which is FSTTransactional. + */ +@interface FSTLevelDBLRUDelegate () + +- (void)transactionWillStart; + +- (void)transactionWillCommit; + +- (void)start; + +@end + +@implementation FSTLevelDBLRUDelegate { + FSTLRUGarbageCollector *_gc; + // This delegate should have the same lifetime as the persistence layer, but mark as + // weak to avoid retain cycle. + __weak FSTLevelDB *_db; + ReferenceSet *_additionalReferences; + ListenSequenceNumber _currentSequenceNumber; + // PORTING NOTE: doesn't need to be a pointer once this class is ported to C++. + std::unique_ptr _listenSequence; +} + +- (instancetype)initWithPersistence:(FSTLevelDB *)persistence lruParams:(LruParams)lruParams { + if (self = [super init]) { + _gc = [[FSTLRUGarbageCollector alloc] initWithDelegate:self params:lruParams]; + _db = persistence; + _currentSequenceNumber = kFSTListenSequenceNumberInvalid; + } + return self; +} + +- (void)start { + ListenSequenceNumber highestSequenceNumber = _db.queryCache->highest_listen_sequence_number(); + _listenSequence = absl::make_unique(highestSequenceNumber); +} + +- (void)transactionWillStart { + HARD_ASSERT(_currentSequenceNumber == kFSTListenSequenceNumberInvalid, + "Previous sequence number is still in effect"); + _currentSequenceNumber = _listenSequence->Next(); +} + +- (void)transactionWillCommit { + _currentSequenceNumber = kFSTListenSequenceNumberInvalid; +} + +- (ListenSequenceNumber)currentSequenceNumber { + HARD_ASSERT(_currentSequenceNumber != kFSTListenSequenceNumberInvalid, + "Asking for a sequence number outside of a transaction"); + return _currentSequenceNumber; +} + +- (void)addInMemoryPins:(ReferenceSet *)set { + // We should be able to assert that _additionalReferences is nil, but due to restarts in spec + // tests it would fail. + _additionalReferences = set; +} + +- (void)removeTarget:(FSTQueryData *)queryData { + FSTQueryData *updated = + [queryData queryDataByReplacingSnapshotVersion:queryData.snapshotVersion + resumeToken:queryData.resumeToken + sequenceNumber:[self currentSequenceNumber]]; + _db.queryCache->UpdateTarget(updated); +} + +- (void)addReference:(const DocumentKey &)key { + [self writeSentinelForKey:key]; +} + +- (void)removeReference:(const DocumentKey &)key { + [self writeSentinelForKey:key]; +} + +- (BOOL)mutationQueuesContainKey:(const DocumentKey &)docKey { + const std::set &users = _db.users; + const ResourcePath &path = docKey.path(); + std::string buffer; + auto it = _db.currentTransaction->NewIterator(); + // For each user, if there is any batch that contains this document in any batch, we know it's + // pinned. + for (const std::string &user : users) { + std::string mutationKey = LevelDbDocumentMutationKey::KeyPrefix(user, path); + it->Seek(mutationKey); + if (it->Valid() && absl::StartsWith(it->key(), mutationKey)) { + return YES; + } + } + return NO; +} + +- (BOOL)isPinned:(const DocumentKey &)docKey { + if (_additionalReferences->ContainsKey(docKey)) { + return YES; + } + if ([self mutationQueuesContainKey:docKey]) { + return YES; + } + return NO; +} + +- (void)enumerateTargetsUsingCallback:(const TargetCallback &)callback { + _db.queryCache->EnumerateTargets(callback); +} + +- (void)enumerateMutationsUsingCallback:(const OrphanedDocumentCallback &)callback { + _db.queryCache->EnumerateOrphanedDocuments(callback); +} + +- (int)removeOrphanedDocumentsThroughSequenceNumber:(ListenSequenceNumber)upperBound { + int count = 0; + _db.queryCache->EnumerateOrphanedDocuments( + [&count, self, upperBound](const DocumentKey &docKey, ListenSequenceNumber sequenceNumber) { + if (sequenceNumber <= upperBound) { + if (![self isPinned:docKey]) { + count++; + self->_db.remoteDocumentCache->Remove(docKey); + [self removeSentinel:docKey]; + } + } + }); + return count; +} + +- (void)removeSentinel:(const DocumentKey &)key { + _db.currentTransaction->Delete(LevelDbDocumentTargetKey::SentinelKey(key)); +} + +- (int)removeTargetsThroughSequenceNumber:(ListenSequenceNumber)sequenceNumber + liveQueries:(const std::unordered_map &) + liveQueries { + return _db.queryCache->RemoveTargets(sequenceNumber, liveQueries); +} + +- (size_t)sequenceNumberCount { + size_t totalCount = _db.queryCache->size(); + [self enumerateMutationsUsingCallback:[&totalCount](const DocumentKey &key, + ListenSequenceNumber sequenceNumber) { + totalCount++; + }]; + return totalCount; +} + +- (FSTLRUGarbageCollector *)gc { + return _gc; +} + +- (void)writeSentinelForKey:(const DocumentKey &)key { + std::string sentinelKey = LevelDbDocumentTargetKey::SentinelKey(key); + std::string encodedSequenceNumber = + LevelDbDocumentTargetKey::EncodeSentinelValue([self currentSequenceNumber]); + _db.currentTransaction->Put(sentinelKey, encodedSequenceNumber); +} + +- (void)removeMutationReference:(const DocumentKey &)key { + [self writeSentinelForKey:key]; +} + +- (void)limboDocumentUpdated:(const DocumentKey &)key { + [self writeSentinelForKey:key]; +} + +- (size_t)byteSize { + return [_db byteSize]; +} + +@end + +@implementation FSTLevelDB { + Path _directory; + std::unique_ptr _transaction; + std::unique_ptr _ptr; + std::unique_ptr _documentCache; + std::unique_ptr _indexManager; + FSTTransactionRunner _transactionRunner; + FSTLevelDBLRUDelegate *_referenceDelegate; + std::unique_ptr _queryCache; + std::set _users; + std::unique_ptr _currentMutationQueue; +} + +/** + * For now this is paranoid, but perhaps disable that in production builds. + */ ++ (const ReadOptions)standardReadOptions { + ReadOptions options; + options.verify_checksums = true; + return options; +} + ++ (std::set)collectUserSet:(LevelDbTransaction *)transaction { + std::set users; + + std::string tablePrefix = LevelDbMutationKey::KeyPrefix(); + auto it = transaction->NewIterator(); + it->Seek(tablePrefix); + LevelDbMutationKey rowKey; + while (it->Valid() && absl::StartsWith(it->key(), tablePrefix) && rowKey.Decode(it->key())) { + users.insert(rowKey.user_id()); + + auto userEnd = LevelDbMutationKey::KeyPrefix(rowKey.user_id()); + userEnd = util::PrefixSuccessor(userEnd); + it->Seek(userEnd); + } + return users; +} + ++ (firebase::firestore::util::Status)dbWithDirectory:(firebase::firestore::util::Path)directory + serializer:(FSTLocalSerializer *)serializer + lruParams: + (firebase::firestore::local::LruParams)lruParams + ptr:(FSTLevelDB **)ptr { + Status status = [self ensureDirectory:directory]; + if (!status.ok()) return status; + + StatusOr> database = [self createDBWithDirectory:directory]; + if (!database.status().ok()) { + return database.status(); + } + + std::unique_ptr ldb = std::move(database.ValueOrDie()); + LevelDbMigrations::RunMigrations(ldb.get()); + LevelDbTransaction transaction(ldb.get(), "Start LevelDB"); + std::set users = [self collectUserSet:&transaction]; + transaction.Commit(); + FSTLevelDB *db = [[self alloc] initWithLevelDB:std::move(ldb) + users:users + directory:directory + serializer:serializer + lruParams:lruParams]; + *ptr = db; + return Status::OK(); +} + +- (instancetype)initWithLevelDB:(std::unique_ptr)db + users:(std::set)users + directory:(firebase::firestore::util::Path)directory + serializer:(FSTLocalSerializer *)serializer + lruParams:(firebase::firestore::local::LruParams)lruParams { + if (self = [super init]) { + self.started = YES; + _ptr = std::move(db); + _directory = std::move(directory); + _serializer = serializer; + _queryCache = absl::make_unique(self, _serializer); + _documentCache = absl::make_unique(self, _serializer); + _indexManager = absl::make_unique(self); + _referenceDelegate = [[FSTLevelDBLRUDelegate alloc] initWithPersistence:self + lruParams:lruParams]; + _transactionRunner.SetBackingPersistence(self); + _users = std::move(users); + // TODO(gsoltis): set up a leveldb transaction for these operations. + _queryCache->Start(); + [_referenceDelegate start]; + } + return self; +} + +- (size_t)byteSize { + int64_t count = 0; + auto iter = util::DirectoryIterator::Create(_directory); + for (; iter->Valid(); iter->Next()) { + int64_t fileSize = util::FileSize(iter->file()).ValueOrDie(); + count += fileSize; + } + HARD_ASSERT(iter->status().ok(), "Failed to iterate leveldb directory: %s", + iter->status().error_message().c_str()); + HARD_ASSERT(count >= 0 && count <= SIZE_MAX, "Overflowed counting bytes cached"); + return static_cast(count); +} + +- (const std::set &)users { + return _users; +} + +- (leveldb::DB *)ptr { + return _ptr.get(); +} + +- (const FSTTransactionRunner &)run { + return _transactionRunner; +} + ++ (Path)documentsDirectory { +#if TARGET_OS_IPHONE + NSArray *directories = + NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); + return Path::FromNSString(directories[0]).AppendUtf8(kReservedPathComponent); + +#elif TARGET_OS_OSX + std::string dotPrefixed = absl::StrCat(".", kReservedPathComponent); + return Path::FromNSString(NSHomeDirectory()).AppendUtf8(dotPrefixed); + +#else +#error "local storage on tvOS" + // TODO(mcg): Writing to NSDocumentsDirectory on tvOS will fail; we need to write to Caches + // https://developer.apple.com/library/content/documentation/General/Conceptual/AppleTV_PG/ + +#endif +} + ++ (Path)storageDirectoryForDatabaseInfo:(const DatabaseInfo &)databaseInfo + documentsDirectory:(const Path &)documentsDirectory { + // Use two different path formats: + // + // * persistenceKey / projectID . databaseID / name + // * persistenceKey / projectID / name + // + // projectIDs are DNS-compatible names and cannot contain dots so there's + // no danger of collisions. + std::string project_key = databaseInfo.database_id().project_id(); + if (!databaseInfo.database_id().IsDefaultDatabase()) { + absl::StrAppend(&project_key, ".", databaseInfo.database_id().database_id()); + } + + // Reserve one additional path component to allow multiple physical databases + return Path::JoinUtf8(documentsDirectory, databaseInfo.persistence_key(), project_key, "main"); +} + +#pragma mark - Startup + +/** Creates the directory at @a directory and marks it as excluded from iCloud backup. */ ++ (Status)ensureDirectory:(const Path &)directory { + Status status = util::RecursivelyCreateDir(directory); + if (!status.ok()) { + return Status{FirestoreErrorCode::Internal, "Failed to create persistence directory"}.CausedBy( + status); + } + + NSURL *dirURL = [NSURL fileURLWithPath:directory.ToNSString()]; + NSError *localError = nil; + if (![dirURL setResourceValue:@YES forKey:NSURLIsExcludedFromBackupKey error:&localError]) { + return Status{FirestoreErrorCode::Internal, + "Failed to mark persistence directory as excluded from backups"} + .CausedBy(Status::FromNSError(localError)); + } + + return Status::OK(); +} + +/** Opens the database within the given directory. */ ++ (StatusOr>)createDBWithDirectory:(const Path &)directory { + Options options; + options.create_if_missing = true; + + DB *database = nullptr; + leveldb::Status status = DB::Open(options, directory.ToUtf8String(), &database); + if (!status.ok()) { + return Status{FirestoreErrorCode::Internal, + StringFormat("Failed to open LevelDB database at %s", directory.ToUtf8String())} + .CausedBy(ConvertStatus(status)); + } + + return std::unique_ptr(database); +} + +- (LevelDbTransaction *)currentTransaction { + HARD_ASSERT(_transaction != nullptr, "Attempting to access transaction before one has started"); + return _transaction.get(); +} + +#pragma mark - Persistence Factory methods + +- (LevelDbMutationQueue *)mutationQueueForUser:(const User &)user { + _users.insert(user.uid()); + _currentMutationQueue.reset(new LevelDbMutationQueue(user, self, self.serializer)); + return _currentMutationQueue.get(); +} + +- (LevelDbQueryCache *)queryCache { + return _queryCache.get(); +} + +- (RemoteDocumentCache *)remoteDocumentCache { + return _documentCache.get(); +} + +- (IndexManager *)indexManager { + return _indexManager.get(); +} + +- (void)startTransaction:(absl::string_view)label { + HARD_ASSERT(_transaction == nullptr, "Starting a transaction while one is already outstanding"); + _transaction = absl::make_unique(_ptr.get(), label); + [_referenceDelegate transactionWillStart]; +} + +- (void)commitTransaction { + HARD_ASSERT(_transaction != nullptr, "Committing a transaction before one is started"); + [_referenceDelegate transactionWillCommit]; + _transaction->Commit(); + _transaction.reset(); +} + +- (void)shutdown { + HARD_ASSERT(self.isStarted, "FSTLevelDB shutdown without start!"); + self.started = NO; + _ptr.reset(); +} + +- (id)referenceDelegate { + return _referenceDelegate; +} + +- (ListenSequenceNumber)currentSequenceNumber { + return [_referenceDelegate currentSequenceNumber]; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Local/FSTLocalSerializer.h b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Local/FSTLocalSerializer.h new file mode 100644 index 0000000..3c57a35 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Local/FSTLocalSerializer.h @@ -0,0 +1,73 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +#include "Firestore/core/src/firebase/firestore/model/snapshot_version.h" + +@class FSTMaybeDocument; +@class FSTMutationBatch; +@class FSTQueryData; +@class FSTSerializerBeta; + +@class FSTPBMaybeDocument; +@class FSTPBTarget; +@class FSTPBWriteBatch; + +@class GPBTimestamp; + +NS_ASSUME_NONNULL_BEGIN + +/** + * Serializer for values stored in the LocalStore. + * + * Note that FSTLocalSerializer currently delegates to the serializer for the Firestore v1 RPC + * protocol to save implementation time and code duplication. We'll need to revisit this when the + * RPC protocol we use diverges from local storage. + */ +@interface FSTLocalSerializer : NSObject + +- (instancetype)initWithRemoteSerializer:(FSTSerializerBeta *)remoteSerializer; + +- (instancetype)init NS_UNAVAILABLE; + +/** Encodes an FSTMaybeDocument model to the equivalent protocol buffer for local storage. */ +- (FSTPBMaybeDocument *)encodedMaybeDocument:(FSTMaybeDocument *)document; + +/** Decodes an FSTPBMaybeDocument proto to the equivalent model. */ +- (FSTMaybeDocument *)decodedMaybeDocument:(FSTPBMaybeDocument *)proto; + +/** Encodes an FSTMutationBatch model for local storage in the mutation queue. */ +- (FSTPBWriteBatch *)encodedMutationBatch:(FSTMutationBatch *)batch; + +/** Decodes an FSTPBWriteBatch proto into a MutationBatch model. */ +- (FSTMutationBatch *)decodedMutationBatch:(FSTPBWriteBatch *)batch; + +/** Encodes an FSTQueryData model for local storage in the query cache. */ +- (FSTPBTarget *)encodedQueryData:(FSTQueryData *)queryData; + +/** Decodes an FSTPBTarget proto from local storage into an FSTQueryData model. */ +- (FSTQueryData *)decodedQueryData:(FSTPBTarget *)target; + +/** Encodes a SnapshotVersion model into a GPBTimestamp proto. */ +- (GPBTimestamp *)encodedVersion:(const firebase::firestore::model::SnapshotVersion &)version; + +/** Decodes a GPBTimestamp proto into a SnapshotVersion model. */ +- (firebase::firestore::model::SnapshotVersion)decodedVersion:(GPBTimestamp *)version; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Local/FSTLocalSerializer.mm b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Local/FSTLocalSerializer.mm new file mode 100644 index 0000000..97545aa --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Local/FSTLocalSerializer.mm @@ -0,0 +1,282 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "Firestore/Source/Local/FSTLocalSerializer.h" + +#include +#include +#include + +#import "FIRTimestamp.h" +#import "Firestore/Protos/objc/firestore/local/MaybeDocument.pbobjc.h" +#import "Firestore/Protos/objc/firestore/local/Mutation.pbobjc.h" +#import "Firestore/Protos/objc/firestore/local/Target.pbobjc.h" +#import "Firestore/Protos/objc/google/firestore/v1/Document.pbobjc.h" +#import "Firestore/Source/Core/FSTQuery.h" +#import "Firestore/Source/Local/FSTQueryData.h" +#import "Firestore/Source/Model/FSTDocument.h" +#import "Firestore/Source/Model/FSTFieldValue.h" +#import "Firestore/Source/Model/FSTMutationBatch.h" +#import "Firestore/Source/Remote/FSTSerializerBeta.h" + +#include "Firestore/core/include/firebase/firestore/timestamp.h" +#include "Firestore/core/src/firebase/firestore/model/document_key.h" +#include "Firestore/core/src/firebase/firestore/model/snapshot_version.h" +#include "Firestore/core/src/firebase/firestore/util/hard_assert.h" + +using firebase::Timestamp; +using firebase::firestore::model::DocumentKey; +using firebase::firestore::model::ListenSequenceNumber; +using firebase::firestore::model::SnapshotVersion; +using firebase::firestore::model::TargetId; + +@interface FSTLocalSerializer () + +@property(nonatomic, strong, readonly) FSTSerializerBeta *remoteSerializer; + +@end + +/** Serializer for values stored in the LocalStore. */ +@implementation FSTLocalSerializer + +- (instancetype)initWithRemoteSerializer:(FSTSerializerBeta *)remoteSerializer { + self = [super init]; + if (self) { + _remoteSerializer = remoteSerializer; + } + return self; +} + +- (FSTPBMaybeDocument *)encodedMaybeDocument:(FSTMaybeDocument *)document { + FSTPBMaybeDocument *proto = [FSTPBMaybeDocument message]; + + if ([document isKindOfClass:[FSTDeletedDocument class]]) { + FSTDeletedDocument *deletedDocument = (FSTDeletedDocument *)document; + proto.noDocument = [self encodedDeletedDocument:deletedDocument]; + proto.hasCommittedMutations = deletedDocument.hasCommittedMutations; + } else if ([document isKindOfClass:[FSTDocument class]]) { + FSTDocument *existingDocument = (FSTDocument *)document; + if (existingDocument.proto != nil) { + proto.document = existingDocument.proto; + } else { + proto.document = [self encodedDocument:existingDocument]; + } + proto.hasCommittedMutations = existingDocument.hasCommittedMutations; + } else if ([document isKindOfClass:[FSTUnknownDocument class]]) { + FSTUnknownDocument *unknownDocument = (FSTUnknownDocument *)document; + proto.unknownDocument = [self encodedUnknownDocument:unknownDocument]; + proto.hasCommittedMutations = YES; + } else { + HARD_FAIL("Unknown document type %s", NSStringFromClass([document class])); + } + + return proto; +} + +- (FSTMaybeDocument *)decodedMaybeDocument:(FSTPBMaybeDocument *)proto { + switch (proto.documentTypeOneOfCase) { + case FSTPBMaybeDocument_DocumentType_OneOfCase_Document: + return [self decodedDocument:proto.document + withCommittedMutations:proto.hasCommittedMutations]; + + case FSTPBMaybeDocument_DocumentType_OneOfCase_NoDocument: + return [self decodedDeletedDocument:proto.noDocument + withCommittedMutations:proto.hasCommittedMutations]; + + case FSTPBMaybeDocument_DocumentType_OneOfCase_UnknownDocument: + return [self decodedUnknownDocument:proto.unknownDocument]; + + default: + HARD_FAIL("Unknown MaybeDocument %s", proto); + } +} + +/** + * Encodes a Document for local storage. This differs from the v1 RPC serializer for Documents in + * that it preserves the updateTime, which is considered an output only value by the server. + */ +- (GCFSDocument *)encodedDocument:(FSTDocument *)document { + FSTSerializerBeta *remoteSerializer = self.remoteSerializer; + + GCFSDocument *proto = [GCFSDocument message]; + proto.name = [remoteSerializer encodedDocumentKey:document.key]; + proto.fields = [remoteSerializer encodedFields:document.data]; + proto.updateTime = [remoteSerializer encodedVersion:document.version]; + + return proto; +} + +/** Decodes a Document proto to the equivalent model. */ +- (FSTDocument *)decodedDocument:(GCFSDocument *)document + withCommittedMutations:(BOOL)committedMutations { + FSTSerializerBeta *remoteSerializer = self.remoteSerializer; + + FSTObjectValue *data = [remoteSerializer decodedFields:document.fields]; + DocumentKey key = [remoteSerializer decodedDocumentKey:document.name]; + SnapshotVersion version = [remoteSerializer decodedVersion:document.updateTime]; + return [FSTDocument documentWithData:data + key:key + version:version + state:committedMutations ? FSTDocumentStateCommittedMutations + : FSTDocumentStateSynced]; +} + +/** Encodes a NoDocument value to the equivalent proto. */ +- (FSTPBNoDocument *)encodedDeletedDocument:(FSTDeletedDocument *)document { + FSTSerializerBeta *remoteSerializer = self.remoteSerializer; + + FSTPBNoDocument *proto = [FSTPBNoDocument message]; + proto.name = [remoteSerializer encodedDocumentKey:document.key]; + proto.readTime = [remoteSerializer encodedVersion:document.version]; + return proto; +} + +/** Decodes a NoDocument proto to the equivalent model. */ +- (FSTDeletedDocument *)decodedDeletedDocument:(FSTPBNoDocument *)proto + withCommittedMutations:(BOOL)committedMutations { + FSTSerializerBeta *remoteSerializer = self.remoteSerializer; + + DocumentKey key = [remoteSerializer decodedDocumentKey:proto.name]; + SnapshotVersion version = [remoteSerializer decodedVersion:proto.readTime]; + return [FSTDeletedDocument documentWithKey:key + version:version + hasCommittedMutations:committedMutations]; +} + +/** Encodes an UnknownDocument value to the equivalent proto. */ +- (FSTPBUnknownDocument *)encodedUnknownDocument:(FSTUnknownDocument *)document { + FSTSerializerBeta *remoteSerializer = self.remoteSerializer; + + FSTPBUnknownDocument *proto = [FSTPBUnknownDocument message]; + proto.name = [remoteSerializer encodedDocumentKey:document.key]; + proto.version = [remoteSerializer encodedVersion:document.version]; + return proto; +} + +/** Decodes an UnknownDocument proto to the equivalent model. */ +- (FSTUnknownDocument *)decodedUnknownDocument:(FSTPBUnknownDocument *)proto { + FSTSerializerBeta *remoteSerializer = self.remoteSerializer; + + DocumentKey key = [remoteSerializer decodedDocumentKey:proto.name]; + SnapshotVersion version = [remoteSerializer decodedVersion:proto.version]; + return [FSTUnknownDocument documentWithKey:key version:version]; +} + +- (FSTPBWriteBatch *)encodedMutationBatch:(FSTMutationBatch *)batch { + FSTSerializerBeta *remoteSerializer = self.remoteSerializer; + + FSTPBWriteBatch *proto = [FSTPBWriteBatch message]; + proto.batchId = batch.batchID; + proto.localWriteTime = [remoteSerializer + encodedTimestamp:Timestamp{batch.localWriteTime.seconds, batch.localWriteTime.nanoseconds}]; + + NSMutableArray *baseWrites = proto.baseWritesArray; + for (FSTMutation *baseMutation : [batch baseMutations]) { + [baseWrites addObject:[remoteSerializer encodedMutation:baseMutation]]; + } + NSMutableArray *writes = proto.writesArray; + for (FSTMutation *mutation : [batch mutations]) { + [writes addObject:[remoteSerializer encodedMutation:mutation]]; + } + return proto; +} + +- (FSTMutationBatch *)decodedMutationBatch:(FSTPBWriteBatch *)batch { + FSTSerializerBeta *remoteSerializer = self.remoteSerializer; + + int batchID = batch.batchId; + + std::vector baseMutations; + for (GCFSWrite *write in batch.baseWritesArray) { + baseMutations.push_back([remoteSerializer decodedMutation:write]); + } + std::vector mutations; + for (GCFSWrite *write in batch.writesArray) { + mutations.push_back([remoteSerializer decodedMutation:write]); + } + + Timestamp localWriteTime = [remoteSerializer decodedTimestamp:batch.localWriteTime]; + + return [[FSTMutationBatch alloc] + initWithBatchID:batchID + localWriteTime:[FIRTimestamp timestampWithSeconds:localWriteTime.seconds() + nanoseconds:localWriteTime.nanoseconds()] + baseMutations:std::move(baseMutations) + mutations:std::move(mutations)]; +} + +- (FSTPBTarget *)encodedQueryData:(FSTQueryData *)queryData { + FSTSerializerBeta *remoteSerializer = self.remoteSerializer; + + HARD_ASSERT(queryData.purpose == FSTQueryPurposeListen, + "only queries with purpose %s may be stored, got %s", FSTQueryPurposeListen, + queryData.purpose); + + FSTPBTarget *proto = [FSTPBTarget message]; + proto.targetId = queryData.targetID; + proto.lastListenSequenceNumber = queryData.sequenceNumber; + proto.snapshotVersion = [remoteSerializer encodedVersion:queryData.snapshotVersion]; + proto.resumeToken = queryData.resumeToken; + + FSTQuery *query = queryData.query; + if ([query isDocumentQuery]) { + proto.documents = [remoteSerializer encodedDocumentsTarget:query]; + } else { + proto.query = [remoteSerializer encodedQueryTarget:query]; + } + + return proto; +} + +- (FSTQueryData *)decodedQueryData:(FSTPBTarget *)target { + FSTSerializerBeta *remoteSerializer = self.remoteSerializer; + + TargetId targetID = target.targetId; + ListenSequenceNumber sequenceNumber = target.lastListenSequenceNumber; + SnapshotVersion version = [remoteSerializer decodedVersion:target.snapshotVersion]; + NSData *resumeToken = target.resumeToken; + + FSTQuery *query; + switch (target.targetTypeOneOfCase) { + case FSTPBTarget_TargetType_OneOfCase_Documents: + query = [remoteSerializer decodedQueryFromDocumentsTarget:target.documents]; + break; + + case FSTPBTarget_TargetType_OneOfCase_Query: + query = [remoteSerializer decodedQueryFromQueryTarget:target.query]; + break; + + default: + HARD_FAIL("Unknown Target.targetType %s", target.targetTypeOneOfCase); + } + + return [[FSTQueryData alloc] initWithQuery:query + targetID:targetID + listenSequenceNumber:sequenceNumber + purpose:FSTQueryPurposeListen + snapshotVersion:version + resumeToken:resumeToken]; +} + +- (GPBTimestamp *)encodedVersion:(const SnapshotVersion &)version { + return [self.remoteSerializer encodedVersion:version]; +} + +- (SnapshotVersion)decodedVersion:(GPBTimestamp *)version { + return [self.remoteSerializer decodedVersion:version]; +} + +@end diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Local/FSTLocalStore.h b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Local/FSTLocalStore.h new file mode 100644 index 0000000..8d696fe --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Local/FSTLocalStore.h @@ -0,0 +1,199 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +#include + +#import "Firestore/Source/Local/FSTLRUGarbageCollector.h" + +#include "Firestore/core/src/firebase/firestore/auth/user.h" +#include "Firestore/core/src/firebase/firestore/model/document_key.h" +#include "Firestore/core/src/firebase/firestore/model/document_key_set.h" +#include "Firestore/core/src/firebase/firestore/model/document_map.h" +#include "Firestore/core/src/firebase/firestore/model/snapshot_version.h" +#include "Firestore/core/src/firebase/firestore/model/types.h" + +namespace firebase { +namespace firestore { +namespace remote { + +class RemoteEvent; + +} // namespace remote +} // namespace firestore +} // namespace firebase + +@class FSTLocalViewChanges; +@class FSTLocalWriteResult; +@class FSTMutation; +@class FSTMutationBatch; +@class FSTMutationBatchResult; +@class FSTQuery; +@class FSTQueryData; +@protocol FSTPersistence; + +NS_ASSUME_NONNULL_BEGIN + +/** + * Local storage in the Firestore client. Coordinates persistence components like the mutation + * queue and remote document cache to present a latency compensated view of stored data. + * + * The LocalStore is responsible for accepting mutations from the Sync Engine. Writes from the + * client are put into a queue as provisional Mutations until they are processed by the RemoteStore + * and confirmed as having been written to the server. + * + * The local store provides the local version of documents that have been modified locally. It + * maintains the constraint: + * + * LocalDocument = RemoteDocument + Active(LocalMutations) + * + * (Active mutations are those that are enqueued and have not been previously acknowledged or + * rejected). + * + * The RemoteDocument ("ground truth") state is provided via the applyChangeBatch method. It will + * be some version of a server-provided document OR will be a server-provided document PLUS + * acknowledged mutations: + * + * RemoteDocument' = RemoteDocument + Acknowledged(LocalMutations) + * + * Note that this "dirty" version of a RemoteDocument will not be identical to a server base + * version, since it has LocalMutations added to it pending getting an authoritative copy from the + * server. + * + * Since LocalMutations can be rejected by the server, we have to be able to revert a LocalMutation + * that has already been applied to the LocalDocument (typically done by replaying all remaining + * LocalMutations to the RemoteDocument to re-apply). + * + * It also maintains the persistence of mapping queries to resume tokens and target ids. + * + * The LocalStore must be able to efficiently execute queries against its local cache of the + * documents, to provide the initial set of results before any remote changes have been received. + */ +@interface FSTLocalStore : NSObject + +/** Creates a new instance of the FSTLocalStore with its required dependencies as parameters. */ +- (instancetype)initWithPersistence:(id)persistence + initialUser:(const firebase::firestore::auth::User &)initialUser + NS_DESIGNATED_INITIALIZER; + +- (instancetype)init NS_UNAVAILABLE; + +/** Performs any initial startup actions required by the local store. */ +- (void)start; + +/** + * Tells the FSTLocalStore that the currently authenticated user has changed. + * + * In response the local store switches the mutation queue to the new user and returns any + * resulting document changes. + */ +- (firebase::firestore::model::MaybeDocumentMap)userDidChange: + (const firebase::firestore::auth::User &)user; + +/** Accepts locally generated Mutations and commits them to storage. */ +- (FSTLocalWriteResult *)locallyWriteMutations:(std::vector &&)mutations; + +/** Returns the current value of a document with a given key, or nil if not found. */ +- (nullable FSTMaybeDocument *)readDocument:(const firebase::firestore::model::DocumentKey &)key; + +/** + * Acknowledges the given batch. + * + * On the happy path when a batch is acknowledged, the local store will + * + * + remove the batch from the mutation queue; + * + apply the changes to the remote document cache; + * + recalculate the latency compensated view implied by those changes (there may be mutations in + * the queue that affect the documents but haven't been acknowledged yet); and + * + give the changed documents back the sync engine + * + * @return The resulting (modified) documents. + */ +- (firebase::firestore::model::MaybeDocumentMap)acknowledgeBatchWithResult: + (FSTMutationBatchResult *)batchResult; + +/** + * Removes mutations from the MutationQueue for the specified batch. LocalDocuments will be + * recalculated. + * + * @return The resulting (modified) documents. + */ +- (firebase::firestore::model::MaybeDocumentMap)rejectBatchID: + (firebase::firestore::model::BatchId)batchID; + +/** Returns the last recorded stream token for the current user. */ +- (nullable NSData *)lastStreamToken; + +/** + * Sets the stream token for the current user without acknowledging any mutation batch. This is + * usually only useful after a stream handshake or in response to an error that requires clearing + * the stream token. + */ +- (void)setLastStreamToken:(nullable NSData *)streamToken; + +/** + * Returns the last consistent snapshot processed (used by the RemoteStore to determine whether to + * buffer incoming snapshots from the backend). + */ +- (const firebase::firestore::model::SnapshotVersion &)lastRemoteSnapshotVersion; + +/** + * Updates the "ground-state" (remote) documents. We assume that the remote event reflects any + * write batches that have been acknowledged or rejected (i.e. we do not re-apply local mutations + * to updates from this event). + * + * LocalDocuments are re-calculated if there are remaining mutations in the queue. + */ +- (firebase::firestore::model::MaybeDocumentMap)applyRemoteEvent: + (const firebase::firestore::remote::RemoteEvent &)remoteEvent; + +/** + * Returns the keys of the documents that are associated with the given targetID in the remote + * table. + */ +- (firebase::firestore::model::DocumentKeySet)remoteDocumentKeysForTarget: + (firebase::firestore::model::TargetId)targetID; + +/** + * Assigns @a query an internal ID so that its results can be pinned so they don't get GC'd. + * A query must be allocated in the local store before the store can be used to manage its view. + */ +- (FSTQueryData *)allocateQuery:(FSTQuery *)query; + +/** Unpin all the documents associated with @a query. */ +- (void)releaseQuery:(FSTQuery *)query; + +/** Runs @a query against all the documents in the local store and returns the results. */ +- (firebase::firestore::model::DocumentMap)executeQuery:(FSTQuery *)query; + +/** Notify the local store of the changed views to locally pin / unpin documents. */ +- (void)notifyLocalViewChanges:(NSArray *)viewChanges; + +/** + * Gets the mutation batch after the passed in batchId in the mutation queue or nil if empty. + * + * @param batchID The batch to search after, or -1 for the first mutation in the queue. + * @return the next mutation or nil if there wasn't one. + */ +- (nullable FSTMutationBatch *)nextMutationBatchAfterBatchID: + (firebase::firestore::model::BatchId)batchID; + +- (firebase::firestore::local::LruResults)collectGarbage:(FSTLRUGarbageCollector *)garbageCollector; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Local/FSTLocalStore.mm b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Local/FSTLocalStore.mm new file mode 100644 index 0000000..97d542b --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Local/FSTLocalStore.mm @@ -0,0 +1,531 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "Firestore/Source/Local/FSTLocalStore.h" + +#include +#include +#include +#include +#include + +#import "FIRTimestamp.h" +#import "Firestore/Source/Core/FSTQuery.h" +#import "Firestore/Source/Local/FSTLRUGarbageCollector.h" +#import "Firestore/Source/Local/FSTLocalViewChanges.h" +#import "Firestore/Source/Local/FSTLocalWriteResult.h" +#import "Firestore/Source/Local/FSTPersistence.h" +#import "Firestore/Source/Local/FSTQueryData.h" +#import "Firestore/Source/Model/FSTDocument.h" +#import "Firestore/Source/Model/FSTMutation.h" +#import "Firestore/Source/Model/FSTMutationBatch.h" + +#include "Firestore/core/src/firebase/firestore/auth/user.h" +#include "Firestore/core/src/firebase/firestore/core/target_id_generator.h" +#include "Firestore/core/src/firebase/firestore/immutable/sorted_set.h" +#include "Firestore/core/src/firebase/firestore/local/local_documents_view.h" +#include "Firestore/core/src/firebase/firestore/local/mutation_queue.h" +#include "Firestore/core/src/firebase/firestore/local/query_cache.h" +#include "Firestore/core/src/firebase/firestore/local/reference_set.h" +#include "Firestore/core/src/firebase/firestore/local/remote_document_cache.h" +#include "Firestore/core/src/firebase/firestore/model/document_key_set.h" +#include "Firestore/core/src/firebase/firestore/model/document_map.h" +#include "Firestore/core/src/firebase/firestore/model/snapshot_version.h" +#include "Firestore/core/src/firebase/firestore/remote/remote_event.h" +#include "Firestore/core/src/firebase/firestore/util/hard_assert.h" +#include "Firestore/core/src/firebase/firestore/util/log.h" +#include "absl/memory/memory.h" + +using firebase::firestore::auth::User; +using firebase::firestore::core::TargetIdGenerator; +using firebase::firestore::local::LocalDocumentsView; +using firebase::firestore::local::LruResults; +using firebase::firestore::local::MutationQueue; +using firebase::firestore::local::QueryCache; +using firebase::firestore::local::ReferenceSet; +using firebase::firestore::local::RemoteDocumentCache; +using firebase::firestore::model::BatchId; +using firebase::firestore::model::DocumentKey; +using firebase::firestore::model::DocumentKeySet; +using firebase::firestore::model::DocumentMap; +using firebase::firestore::model::DocumentVersionMap; +using firebase::firestore::model::FieldMask; +using firebase::firestore::model::FieldPath; +using firebase::firestore::model::MaybeDocumentMap; +using firebase::firestore::model::ListenSequenceNumber; +using firebase::firestore::model::Precondition; +using firebase::firestore::model::SnapshotVersion; +using firebase::firestore::model::TargetId; +using firebase::firestore::remote::RemoteEvent; +using firebase::firestore::remote::TargetChange; + +NS_ASSUME_NONNULL_BEGIN + +/** + * The maximum time to leave a resume token buffered without writing it out. This value is + * arbitrary: it's long enough to avoid several writes (possibly indefinitely if updates come more + * frequently than this) but short enough that restarting after crashing will still have a pretty + * recent resume token. + */ +static const int64_t kResumeTokenMaxAgeSeconds = 5 * 60; // 5 minutes + +@interface FSTLocalStore () + +/** Manages our in-memory or durable persistence. */ +@property(nonatomic, strong, readonly) id persistence; + +/** Maps a query to the data about that query. */ +@property(nonatomic) QueryCache *queryCache; + +@end + +@implementation FSTLocalStore { + /** Used to generate targetIDs for queries tracked locally. */ + TargetIdGenerator _targetIDGenerator; + /** The set of all cached remote documents. */ + RemoteDocumentCache *_remoteDocumentCache; + QueryCache *_queryCache; + /** The set of all mutations that have been sent but not yet been applied to the backend. */ + MutationQueue *_mutationQueue; + + /** The "local" view of all documents (layering mutationQueue on top of remoteDocumentCache). */ + std::unique_ptr _localDocuments; + + /** The set of document references maintained by any local views. */ + ReferenceSet _localViewReferences; + + /** Maps a targetID to data about its query. */ + std::unordered_map _targetIDs; +} + +- (instancetype)initWithPersistence:(id)persistence + initialUser:(const User &)initialUser { + if (self = [super init]) { + _persistence = persistence; + _mutationQueue = [persistence mutationQueueForUser:initialUser]; + _remoteDocumentCache = [persistence remoteDocumentCache]; + _queryCache = [persistence queryCache]; + _localDocuments = absl::make_unique(_remoteDocumentCache, _mutationQueue, + [_persistence indexManager]); + [_persistence.referenceDelegate addInMemoryPins:&_localViewReferences]; + + _targetIDGenerator = TargetIdGenerator::QueryCacheTargetIdGenerator(0); + } + return self; +} + +- (void)start { + [self startMutationQueue]; + TargetId targetID = _queryCache->highest_target_id(); + _targetIDGenerator = TargetIdGenerator::QueryCacheTargetIdGenerator(targetID); +} + +- (void)startMutationQueue { + self.persistence.run("Start MutationQueue", [&]() { _mutationQueue->Start(); }); +} + +- (MaybeDocumentMap)userDidChange:(const User &)user { + // Swap out the mutation queue, grabbing the pending mutation batches before and after. + std::vector oldBatches = self.persistence.run( + "OldBatches", + [&]() -> std::vector { return _mutationQueue->AllMutationBatches(); }); + + // The old one has a reference to the mutation queue, so nil it out first. + _localDocuments.reset(); + _mutationQueue = [self.persistence mutationQueueForUser:user]; + + [self startMutationQueue]; + + return self.persistence.run("NewBatches", [&]() -> MaybeDocumentMap { + std::vector newBatches = _mutationQueue->AllMutationBatches(); + + // Recreate our LocalDocumentsView using the new MutationQueue. + _localDocuments = absl::make_unique(_remoteDocumentCache, _mutationQueue, + [_persistence indexManager]); + + // Union the old/new changed keys. + DocumentKeySet changedKeys; + for (const std::vector &batches : {oldBatches, newBatches}) { + for (FSTMutationBatch *batch : batches) { + for (FSTMutation *mutation : [batch mutations]) { + changedKeys = changedKeys.insert(mutation.key); + } + } + } + + // Return the set of all (potentially) changed documents as the result of the user change. + return _localDocuments->GetDocuments(changedKeys); + }); +} + +- (FSTLocalWriteResult *)locallyWriteMutations:(std::vector &&)mutations { + FIRTimestamp *localWriteTime = [FIRTimestamp timestamp]; + DocumentKeySet keys; + for (FSTMutation *mutation : mutations) { + keys = keys.insert(mutation.key); + } + + return self.persistence.run("Locally write mutations", [&]() -> FSTLocalWriteResult * { + // Load and apply all existing mutations. This lets us compute the current base state for + // all non-idempotent transforms before applying any additional user-provided writes. + MaybeDocumentMap existingDocuments = _localDocuments->GetDocuments(keys); + + // For non-idempotent mutations (such as `FieldValue.increment()`), we record the base + // state in a separate patch mutation. This is later used to guarantee consistent values + // and prevents flicker even if the backend sends us an update that already includes our + // transform. + std::vector baseMutations; + for (FSTMutation *mutation : mutations) { + if (mutation.idempotent) { + continue; + } + + // Theoretically, we should only include non-idempotent fields in this field mask as this mask + // is used to prevent flicker for non-idempotent transforms by providing consistent base + // values. By including the fields for all DocumentTransforms, we incorrectly prevent rebasing + // of idempotent transforms (such as `arrayUnion()`) when any non-idempotent transforms are + // present. + // TODO(mrschmidt): Expose a method that only returns the a field mask for non-idempotent + // transforms + const FieldMask *fieldMask = [mutation fieldMask]; + if (fieldMask) { + // `documentsForKeys` is guaranteed to return a (nullable) entry for every document key. + FSTMaybeDocument *maybeDocument = existingDocuments.find(mutation.key)->second; + FSTObjectValue *baseValues = + [maybeDocument isKindOfClass:[FSTDocument class]] + ? [((FSTDocument *)maybeDocument).data objectByApplyingFieldMask:*fieldMask] + : [FSTObjectValue objectValue]; + // NOTE: The base state should only be applied if there's some existing document to + // override, so use a Precondition of exists=true + baseMutations.push_back([[FSTPatchMutation alloc] initWithKey:mutation.key + fieldMask:*fieldMask + value:baseValues + precondition:Precondition::Exists(true)]); + } + } + + FSTMutationBatch *batch = _mutationQueue->AddMutationBatch( + localWriteTime, std::move(baseMutations), std::move(mutations)); + MaybeDocumentMap changedDocuments = [batch applyToLocalDocumentSet:existingDocuments]; + return [FSTLocalWriteResult resultForBatchID:batch.batchID changes:std::move(changedDocuments)]; + }); +} + +- (MaybeDocumentMap)acknowledgeBatchWithResult:(FSTMutationBatchResult *)batchResult { + return self.persistence.run("Acknowledge batch", [&]() -> MaybeDocumentMap { + FSTMutationBatch *batch = batchResult.batch; + _mutationQueue->AcknowledgeBatch(batch, batchResult.streamToken); + [self applyBatchResult:batchResult]; + _mutationQueue->PerformConsistencyCheck(); + + return _localDocuments->GetDocuments(batch.keys); + }); +} + +- (MaybeDocumentMap)rejectBatchID:(BatchId)batchID { + return self.persistence.run("Reject batch", [&]() -> MaybeDocumentMap { + FSTMutationBatch *toReject = _mutationQueue->LookupMutationBatch(batchID); + HARD_ASSERT(toReject, "Attempt to reject nonexistent batch!"); + + _mutationQueue->RemoveMutationBatch(toReject); + _mutationQueue->PerformConsistencyCheck(); + + return _localDocuments->GetDocuments(toReject.keys); + }); +} + +- (nullable NSData *)lastStreamToken { + return _mutationQueue->GetLastStreamToken(); +} + +- (void)setLastStreamToken:(nullable NSData *)streamToken { + self.persistence.run("Set stream token", + [&]() { _mutationQueue->SetLastStreamToken(streamToken); }); +} + +- (const SnapshotVersion &)lastRemoteSnapshotVersion { + return self.queryCache->GetLastRemoteSnapshotVersion(); +} + +- (MaybeDocumentMap)applyRemoteEvent:(const RemoteEvent &)remoteEvent { + return self.persistence.run("Apply remote event", [&]() -> MaybeDocumentMap { + // TODO(gsoltis): move the sequence number into the reference delegate. + ListenSequenceNumber sequenceNumber = self.persistence.currentSequenceNumber; + + DocumentKeySet authoritativeUpdates; + for (const auto &entry : remoteEvent.target_changes()) { + TargetId targetID = entry.first; + const TargetChange &change = entry.second; + + // Do not ref/unref unassigned targetIDs - it may lead to leaks. + auto found = _targetIDs.find(targetID); + if (found == _targetIDs.end()) { + continue; + } + FSTQueryData *queryData = found->second; + + // When a global snapshot contains updates (either add or modify) we can completely trust + // these updates as authoritative and blindly apply them to our cache (as a defensive measure + // to promote self-healing in the unfortunate case that our cache is ever somehow corrupted / + // out-of-sync). + // + // If the document is only updated while removing it from a target then watch isn't obligated + // to send the absolute latest version: it can send the first version that caused the document + // not to match. + for (const DocumentKey &key : change.added_documents()) { + authoritativeUpdates = authoritativeUpdates.insert(key); + } + for (const DocumentKey &key : change.modified_documents()) { + authoritativeUpdates = authoritativeUpdates.insert(key); + } + + _queryCache->RemoveMatchingKeys(change.removed_documents(), targetID); + _queryCache->AddMatchingKeys(change.added_documents(), targetID); + + // Update the resume token if the change includes one. Don't clear any preexisting value. + // Bump the sequence number as well, so that documents being removed now are ordered later + // than documents that were previously removed from this target. + NSData *resumeToken = change.resume_token(); + if (resumeToken.length > 0) { + FSTQueryData *oldQueryData = queryData; + queryData = [queryData queryDataByReplacingSnapshotVersion:remoteEvent.snapshot_version() + resumeToken:resumeToken + sequenceNumber:sequenceNumber]; + _targetIDs[targetID] = queryData; + + if ([self shouldPersistQueryData:queryData oldQueryData:oldQueryData change:change]) { + _queryCache->UpdateTarget(queryData); + } + } + } + + MaybeDocumentMap changedDocs; + const DocumentKeySet &limboDocuments = remoteEvent.limbo_document_changes(); + DocumentKeySet updatedKeys; + for (const auto &kv : remoteEvent.document_updates()) { + updatedKeys = updatedKeys.insert(kv.first); + } + // Each loop iteration only affects its "own" doc, so it's safe to get all the remote + // documents in advance in a single call. + MaybeDocumentMap existingDocs = _remoteDocumentCache->GetAll(updatedKeys); + + for (const auto &kv : remoteEvent.document_updates()) { + const DocumentKey &key = kv.first; + FSTMaybeDocument *doc = kv.second; + FSTMaybeDocument *existingDoc = nil; + auto foundExisting = existingDocs.find(key); + if (foundExisting != existingDocs.end()) { + existingDoc = foundExisting->second; + } + + // If a document update isn't authoritative, make sure we don't apply an old document version + // to the remote cache. We make an exception for SnapshotVersion.MIN which can happen for + // manufactured events (e.g. in the case of a limbo document resolution failing). + if (!existingDoc || doc.version == SnapshotVersion::None() || + (authoritativeUpdates.contains(doc.key) && !existingDoc.hasPendingWrites) || + doc.version >= existingDoc.version) { + _remoteDocumentCache->Add(doc); + changedDocs = changedDocs.insert(key, doc); + } else { + LOG_DEBUG("FSTLocalStore Ignoring outdated watch update for %s. " + "Current version: %s Watch version: %s", + key.ToString(), existingDoc.version.timestamp().ToString(), + doc.version.timestamp().ToString()); + } + + // If this was a limbo resolution, make sure we mark when it was accessed. + if (limboDocuments.contains(key)) { + [self.persistence.referenceDelegate limboDocumentUpdated:key]; + } + } + + // HACK: The only reason we allow omitting snapshot version is so we can synthesize remote + // events when we get permission denied errors while trying to resolve the state of a locally + // cached document that is in limbo. + const SnapshotVersion &lastRemoteVersion = _queryCache->GetLastRemoteSnapshotVersion(); + const SnapshotVersion &remoteVersion = remoteEvent.snapshot_version(); + if (remoteVersion != SnapshotVersion::None()) { + HARD_ASSERT(remoteVersion >= lastRemoteVersion, + "Watch stream reverted to previous snapshot?? (%s < %s)", + remoteVersion.timestamp().ToString(), lastRemoteVersion.timestamp().ToString()); + _queryCache->SetLastRemoteSnapshotVersion(remoteVersion); + } + + return _localDocuments->GetLocalViewOfDocuments(changedDocs); + }); +} + +/** + * Returns YES if the newQueryData should be persisted during an update of an active target. + * QueryData should always be persisted when a target is being released and should not call this + * function. + * + * While the target is active, QueryData updates can be omitted when nothing about the target has + * changed except metadata like the resume token or snapshot version. Occasionally it's worth the + * extra write to prevent these values from getting too stale after a crash, but this doesn't have + * to be too frequent. + */ +- (BOOL)shouldPersistQueryData:(FSTQueryData *)newQueryData + oldQueryData:(FSTQueryData *)oldQueryData + change:(const TargetChange &)change { + // Avoid clearing any existing value + if (newQueryData.resumeToken.length == 0) return NO; + + // Any resume token is interesting if there isn't one already. + if (oldQueryData.resumeToken.length == 0) return YES; + + // Don't allow resume token changes to be buffered indefinitely. This allows us to be reasonably + // up-to-date after a crash and avoids needing to loop over all active queries on shutdown. + // Especially in the browser we may not get time to do anything interesting while the current + // tab is closing. + int64_t newSeconds = newQueryData.snapshotVersion.timestamp().seconds(); + int64_t oldSeconds = oldQueryData.snapshotVersion.timestamp().seconds(); + int64_t timeDelta = newSeconds - oldSeconds; + if (timeDelta >= kResumeTokenMaxAgeSeconds) return YES; + + // Otherwise if the only thing that has changed about a target is its resume token then it's not + // worth persisting. Note that the RemoteStore keeps an in-memory view of the currently active + // targets which includes the current resume token, so stream failure or user changes will still + // use an up-to-date resume token regardless of what we do here. + size_t changes = change.added_documents().size() + change.modified_documents().size() + + change.removed_documents().size(); + return changes > 0; +} + +- (void)notifyLocalViewChanges:(NSArray *)viewChanges { + self.persistence.run("NotifyLocalViewChanges", [&]() { + for (FSTLocalViewChanges *viewChange in viewChanges) { + for (const DocumentKey &key : viewChange.removedKeys) { + [self->_persistence.referenceDelegate removeReference:key]; + } + _localViewReferences.AddReferences(viewChange.addedKeys, viewChange.targetID); + _localViewReferences.AddReferences(viewChange.removedKeys, viewChange.targetID); + } + }); +} + +- (nullable FSTMutationBatch *)nextMutationBatchAfterBatchID:(BatchId)batchID { + FSTMutationBatch *result = + self.persistence.run("NextMutationBatchAfterBatchID", [&]() -> FSTMutationBatch * { + return _mutationQueue->NextMutationBatchAfterBatchId(batchID); + }); + return result; +} + +- (nullable FSTMaybeDocument *)readDocument:(const DocumentKey &)key { + return self.persistence.run("ReadDocument", [&]() -> FSTMaybeDocument *_Nullable { + return _localDocuments->GetDocument(key); + }); +} + +- (FSTQueryData *)allocateQuery:(FSTQuery *)query { + FSTQueryData *queryData = self.persistence.run("Allocate query", [&]() -> FSTQueryData * { + FSTQueryData *cached = _queryCache->GetTarget(query); + // TODO(mcg): freshen last accessed date if cached exists? + if (!cached) { + cached = [[FSTQueryData alloc] initWithQuery:query + targetID:_targetIDGenerator.NextId() + listenSequenceNumber:self.persistence.currentSequenceNumber + purpose:FSTQueryPurposeListen]; + _queryCache->AddTarget(cached); + } + return cached; + }); + // Sanity check to ensure that even when resuming a query it's not currently active. + TargetId targetID = queryData.targetID; + HARD_ASSERT(_targetIDs.find(targetID) == _targetIDs.end(), + "Tried to allocate an already allocated query: %s", query); + _targetIDs[targetID] = queryData; + return queryData; +} + +- (void)releaseQuery:(FSTQuery *)query { + self.persistence.run("Release query", [&]() { + FSTQueryData *queryData = _queryCache->GetTarget(query); + HARD_ASSERT(queryData, "Tried to release nonexistent query: %s", query); + + TargetId targetID = queryData.targetID; + + auto found = _targetIDs.find(targetID); + FSTQueryData *cachedQueryData = found != _targetIDs.end() ? found->second : nil; + if (cachedQueryData.snapshotVersion > queryData.snapshotVersion) { + // If we've been avoiding persisting the resumeToken (see shouldPersistQueryData for + // conditions and rationale) we need to persist the token now because there will no + // longer be an in-memory version to fall back on. + queryData = cachedQueryData; + _queryCache->UpdateTarget(queryData); + } + + // References for documents sent via Watch are automatically removed when we delete a + // query's target data from the reference delegate. Since this does not remove references + // for locally mutated documents, we have to remove the target associations for these + // documents manually. + DocumentKeySet removed = _localViewReferences.RemoveReferences(targetID); + for (const DocumentKey &key : removed) { + [self.persistence.referenceDelegate removeReference:key]; + } + _targetIDs.erase(targetID); + [self.persistence.referenceDelegate removeTarget:queryData]; + }); +} + +- (DocumentMap)executeQuery:(FSTQuery *)query { + return self.persistence.run("ExecuteQuery", [&]() -> DocumentMap { + return _localDocuments->GetDocumentsMatchingQuery(query); + }); +} + +- (DocumentKeySet)remoteDocumentKeysForTarget:(TargetId)targetID { + return self.persistence.run("RemoteDocumentKeysForTarget", [&]() -> DocumentKeySet { + return _queryCache->GetMatchingKeys(targetID); + }); +} + +- (void)applyBatchResult:(FSTMutationBatchResult *)batchResult { + FSTMutationBatch *batch = batchResult.batch; + DocumentKeySet docKeys = batch.keys; + const DocumentVersionMap &versions = batchResult.docVersions; + for (const DocumentKey &docKey : docKeys) { + FSTMaybeDocument *_Nullable remoteDoc = _remoteDocumentCache->Get(docKey); + FSTMaybeDocument *_Nullable doc = remoteDoc; + + auto ackVersionIter = versions.find(docKey); + HARD_ASSERT(ackVersionIter != versions.end(), + "docVersions should contain every doc in the write."); + const SnapshotVersion &ackVersion = ackVersionIter->second; + if (!doc || doc.version < ackVersion) { + doc = [batch applyToRemoteDocument:doc documentKey:docKey mutationBatchResult:batchResult]; + if (!doc) { + HARD_ASSERT(!remoteDoc, "Mutation batch %s applied to document %s resulted in nil.", batch, + remoteDoc); + } else { + _remoteDocumentCache->Add(doc); + } + } + } + + _mutationQueue->RemoveMutationBatch(batch); +} + +- (LruResults)collectGarbage:(FSTLRUGarbageCollector *)garbageCollector { + return self.persistence.run("Collect garbage", [&]() -> LruResults { + return [garbageCollector collectWithLiveTargets:_targetIDs]; + }); +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Local/FSTLocalViewChanges.h b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Local/FSTLocalViewChanges.h new file mode 100644 index 0000000..66ec863 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Local/FSTLocalViewChanges.h @@ -0,0 +1,51 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +#include "Firestore/core/src/firebase/firestore/core/view_snapshot.h" +#include "Firestore/core/src/firebase/firestore/model/document_key_set.h" +#include "Firestore/core/src/firebase/firestore/model/types.h" + +@class FSTMutation; +@class FSTQuery; + +NS_ASSUME_NONNULL_BEGIN + +/** + * A set of changes to what documents are currently in view and out of view for a given query. + * These changes are sent to the LocalStore by the View (via the SyncEngine) and are used to pin / + * unpin documents as appropriate. + */ +@interface FSTLocalViewChanges : NSObject + ++ (instancetype)changesForTarget:(firebase::firestore::model::TargetId)targetID + addedKeys:(firebase::firestore::model::DocumentKeySet)addedKeys + removedKeys:(firebase::firestore::model::DocumentKeySet)removedKeys; + ++ (instancetype)changesForViewSnapshot:(const firebase::firestore::core::ViewSnapshot &)viewSnapshot + withTargetID:(firebase::firestore::model::TargetId)targetID; + +- (id)init NS_UNAVAILABLE; + +@property(readonly) firebase::firestore::model::TargetId targetID; + +- (const firebase::firestore::model::DocumentKeySet &)addedKeys; +- (const firebase::firestore::model::DocumentKeySet &)removedKeys; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Local/FSTLocalViewChanges.mm b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Local/FSTLocalViewChanges.mm new file mode 100644 index 0000000..5169f6b --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Local/FSTLocalViewChanges.mm @@ -0,0 +1,99 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "Firestore/Source/Local/FSTLocalViewChanges.h" + +#include + +#import "Firestore/Source/Model/FSTDocument.h" + +#include "Firestore/core/src/firebase/firestore/core/view_snapshot.h" + +using firebase::firestore::core::DocumentViewChange; +using firebase::firestore::core::ViewSnapshot; +using firebase::firestore::model::DocumentKeySet; +using firebase::firestore::model::TargetId; + +NS_ASSUME_NONNULL_BEGIN + +@interface FSTLocalViewChanges () +- (instancetype)initWithTarget:(TargetId)targetID + addedKeys:(DocumentKeySet)addedKeys + removedKeys:(DocumentKeySet)removedKeys NS_DESIGNATED_INITIALIZER; +@end + +@implementation FSTLocalViewChanges { + DocumentKeySet _addedKeys; + DocumentKeySet _removedKeys; +} + ++ (instancetype)changesForViewSnapshot:(const ViewSnapshot &)viewSnapshot + withTargetID:(TargetId)targetID { + DocumentKeySet addedKeys; + DocumentKeySet removedKeys; + + for (const DocumentViewChange &docChange : viewSnapshot.document_changes()) { + switch (docChange.type()) { + case DocumentViewChange::Type::kAdded: + addedKeys = addedKeys.insert(docChange.document().key); + break; + + case DocumentViewChange::Type::kRemoved: + removedKeys = removedKeys.insert(docChange.document().key); + break; + + default: + // Do nothing. + break; + } + } + + return [self changesForTarget:targetID + addedKeys:std::move(addedKeys) + removedKeys:std::move(removedKeys)]; +} + ++ (instancetype)changesForTarget:(TargetId)targetID + addedKeys:(DocumentKeySet)addedKeys + removedKeys:(DocumentKeySet)removedKeys { + return [[FSTLocalViewChanges alloc] initWithTarget:targetID + addedKeys:std::move(addedKeys) + removedKeys:std::move(removedKeys)]; +} + +- (instancetype)initWithTarget:(TargetId)targetID + addedKeys:(DocumentKeySet)addedKeys + removedKeys:(DocumentKeySet)removedKeys { + self = [super init]; + if (self) { + _targetID = targetID; + _addedKeys = std::move(addedKeys); + _removedKeys = std::move(removedKeys); + } + return self; +} + +- (const DocumentKeySet &)addedKeys { + return _addedKeys; +} + +- (const DocumentKeySet &)removedKeys { + return _removedKeys; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Local/FSTLocalWriteResult.h b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Local/FSTLocalWriteResult.h new file mode 100644 index 0000000..e4b208d --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Local/FSTLocalWriteResult.h @@ -0,0 +1,38 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +#include "Firestore/core/src/firebase/firestore/model/document_map.h" +#include "Firestore/core/src/firebase/firestore/model/types.h" + +NS_ASSUME_NONNULL_BEGIN + +/** The result of a write to the local store. */ +@interface FSTLocalWriteResult : NSObject + ++ (instancetype)resultForBatchID:(firebase::firestore::model::BatchId)batchID + changes:(firebase::firestore::model::MaybeDocumentMap &&)changes; + +- (id)init __attribute__((unavailable("Use resultForBatchID:changes:"))); + +- (const firebase::firestore::model::MaybeDocumentMap &)changes; + +@property(nonatomic, assign, readonly) firebase::firestore::model::BatchId batchID; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Local/FSTLocalWriteResult.mm b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Local/FSTLocalWriteResult.mm new file mode 100644 index 0000000..fcad635 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Local/FSTLocalWriteResult.mm @@ -0,0 +1,54 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "Firestore/Source/Local/FSTLocalWriteResult.h" + +#include + +using firebase::firestore::model::BatchId; +using firebase::firestore::model::MaybeDocumentMap; + +NS_ASSUME_NONNULL_BEGIN + +@interface FSTLocalWriteResult () +- (instancetype)initWithBatchID:(BatchId)batchID + changes:(MaybeDocumentMap &&)changes NS_DESIGNATED_INITIALIZER; +@end + +@implementation FSTLocalWriteResult { + MaybeDocumentMap _changes; +} + +- (const MaybeDocumentMap &)changes { + return _changes; +} + ++ (instancetype)resultForBatchID:(BatchId)batchID changes:(MaybeDocumentMap &&)changes { + return [[FSTLocalWriteResult alloc] initWithBatchID:batchID changes:std::move(changes)]; +} + +- (instancetype)initWithBatchID:(BatchId)batchID changes:(MaybeDocumentMap &&)changes { + self = [super init]; + if (self) { + _batchID = batchID; + _changes = std::move(changes); + } + return self; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Local/FSTMemoryPersistence.h b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Local/FSTMemoryPersistence.h new file mode 100644 index 0000000..c293843 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Local/FSTMemoryPersistence.h @@ -0,0 +1,64 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +#import "Firestore/Source/Local/FSTLRUGarbageCollector.h" +#import "Firestore/Source/Local/FSTLocalSerializer.h" +#import "Firestore/Source/Local/FSTPersistence.h" +#include "Firestore/core/src/firebase/firestore/model/document_key.h" +#include "Firestore/core/src/firebase/firestore/model/types.h" + +NS_ASSUME_NONNULL_BEGIN + +/** + * An in-memory implementation of the FSTPersistence protocol. Values are stored only in RAM and + * are never persisted to any durable storage. + */ +@interface FSTMemoryPersistence : NSObject + ++ (instancetype)persistenceWithEagerGC; + ++ (instancetype)persistenceWithLruParams:(firebase::firestore::local::LruParams)lruParams + serializer:(FSTLocalSerializer *)serializer; + +@end + +/** + * Provides the eager GC implementation for memory persistence. + */ +@interface FSTMemoryEagerReferenceDelegate : NSObject + +- (instancetype)initWithPersistence:(FSTMemoryPersistence *)persistence; + +@end + +/** + * Provides the LRU GC implementation for memory persistence. + */ +@interface FSTMemoryLRUReferenceDelegate + : NSObject + +- (instancetype)initWithPersistence:(FSTMemoryPersistence *)persistence + serializer:(FSTLocalSerializer *)serializer + lruParams:(firebase::firestore::local::LruParams)lruParams; + +- (BOOL)isPinnedAtSequenceNumber:(firebase::firestore::model::ListenSequenceNumber)upperBound + document:(const firebase::firestore::model::DocumentKey &)key; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Local/FSTMemoryPersistence.mm b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Local/FSTMemoryPersistence.mm new file mode 100644 index 0000000..d60f7e3 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Local/FSTMemoryPersistence.mm @@ -0,0 +1,425 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "Firestore/Source/Local/FSTMemoryPersistence.h" + +#include +#include +#include +#include + +#include "Firestore/core/src/firebase/firestore/auth/user.h" +#include "Firestore/core/src/firebase/firestore/local/index_manager.h" +#include "Firestore/core/src/firebase/firestore/local/listen_sequence.h" +#include "Firestore/core/src/firebase/firestore/local/memory_index_manager.h" +#include "Firestore/core/src/firebase/firestore/local/memory_mutation_queue.h" +#include "Firestore/core/src/firebase/firestore/local/memory_query_cache.h" +#include "Firestore/core/src/firebase/firestore/local/memory_remote_document_cache.h" +#include "Firestore/core/src/firebase/firestore/local/reference_set.h" +#include "Firestore/core/src/firebase/firestore/model/document_key.h" +#include "Firestore/core/src/firebase/firestore/util/hard_assert.h" +#include "absl/memory/memory.h" + +using firebase::firestore::auth::HashUser; +using firebase::firestore::auth::User; +using firebase::firestore::local::ListenSequence; +using firebase::firestore::local::LruParams; +using firebase::firestore::local::MemoryIndexManager; +using firebase::firestore::local::MemoryMutationQueue; +using firebase::firestore::local::MemoryQueryCache; +using firebase::firestore::local::MemoryRemoteDocumentCache; +using firebase::firestore::local::ReferenceSet; +using firebase::firestore::local::TargetCallback; +using firebase::firestore::model::DocumentKey; +using firebase::firestore::model::DocumentKeyHash; +using firebase::firestore::model::ListenSequenceNumber; +using firebase::firestore::model::TargetId; +using firebase::firestore::util::Status; + +using MutationQueues = std::unordered_map, HashUser>; + +NS_ASSUME_NONNULL_BEGIN + +@interface FSTMemoryPersistence () + +- (MemoryQueryCache *)queryCache; + +- (MemoryRemoteDocumentCache *)remoteDocumentCache; + +- (MemoryIndexManager *)indexManager; + +- (MemoryMutationQueue *)mutationQueueForUser:(const User &)user; + +@property(nonatomic, readonly) MutationQueues &mutationQueues; + +@property(nonatomic, assign, getter=isStarted) BOOL started; + +// Make this property writable so we can wire up a delegate. +@property(nonatomic, strong) id referenceDelegate; + +@end + +@implementation FSTMemoryPersistence { + /** + * The QueryCache representing the persisted cache of queries. + * + * Note that this is retained here to make it easier to write tests affecting both the in-memory + * and LevelDB-backed persistence layers. Tests can create a new FSTLocalStore wrapping this + * FSTPersistence instance and this will make the in-memory persistence layer behave as if it + * were actually persisting values. + */ + std::unique_ptr _queryCache; + + /** The RemoteDocumentCache representing the persisted cache of remote documents. */ + std::unique_ptr _remoteDocumentCache; + + MemoryIndexManager _indexManager; + + FSTTransactionRunner _transactionRunner; + + id _referenceDelegate; +} + ++ (instancetype)persistenceWithEagerGC { + FSTMemoryPersistence *persistence = [[FSTMemoryPersistence alloc] init]; + persistence.referenceDelegate = + [[FSTMemoryEagerReferenceDelegate alloc] initWithPersistence:persistence]; + return persistence; +} + ++ (instancetype)persistenceWithLruParams:(firebase::firestore::local::LruParams)lruParams + serializer:(FSTLocalSerializer *)serializer { + FSTMemoryPersistence *persistence = [[FSTMemoryPersistence alloc] init]; + persistence.referenceDelegate = + [[FSTMemoryLRUReferenceDelegate alloc] initWithPersistence:persistence + serializer:serializer + lruParams:lruParams]; + return persistence; +} + +- (instancetype)init { + if (self = [super init]) { + _queryCache = absl::make_unique(self); + _remoteDocumentCache = absl::make_unique(self); + self.started = YES; + } + return self; +} + +- (void)setReferenceDelegate:(id)referenceDelegate { + _referenceDelegate = referenceDelegate; + id delegate = _referenceDelegate; + if ([delegate conformsToProtocol:@protocol(FSTTransactional)]) { + _transactionRunner.SetBackingPersistence((id)_referenceDelegate); + } +} + +- (void)shutdown { + // No durable state to ensure is closed on shutdown. + HARD_ASSERT(self.isStarted, "FSTMemoryPersistence shutdown without start!"); + self.started = NO; +} + +- (id)referenceDelegate { + return _referenceDelegate; +} + +- (ListenSequenceNumber)currentSequenceNumber { + return [_referenceDelegate currentSequenceNumber]; +} + +- (const FSTTransactionRunner &)run { + return _transactionRunner; +} + +- (MemoryMutationQueue *)mutationQueueForUser:(const User &)user { + const std::unique_ptr &existing = _mutationQueues[user]; + if (!existing) { + _mutationQueues[user] = absl::make_unique(self); + return _mutationQueues[user].get(); + } else { + return existing.get(); + } +} + +- (MemoryQueryCache *)queryCache { + return _queryCache.get(); +} + +- (MemoryRemoteDocumentCache *)remoteDocumentCache { + return _remoteDocumentCache.get(); +} + +- (MemoryIndexManager *)indexManager { + return &_indexManager; +} + +@end + +@implementation FSTMemoryLRUReferenceDelegate { + // This delegate should have the same lifetime as the persistence layer, but mark as + // weak to avoid retain cycle. + __weak FSTMemoryPersistence *_persistence; + // Tracks sequence numbers of when documents are used. Equivalent to sentinel rows in + // the leveldb implementation. + std::unordered_map _sequenceNumbers; + ReferenceSet *_additionalReferences; + FSTLRUGarbageCollector *_gc; + // PORTING NOTE: when this class is ported to C++, this does not need to be a pointer + std::unique_ptr _listenSequence; + ListenSequenceNumber _currentSequenceNumber; + FSTLocalSerializer *_serializer; +} + +- (instancetype)initWithPersistence:(FSTMemoryPersistence *)persistence + serializer:(FSTLocalSerializer *)serializer + lruParams:(firebase::firestore::local::LruParams)lruParams { + if (self = [super init]) { + _persistence = persistence; + _gc = [[FSTLRUGarbageCollector alloc] initWithDelegate:self params:lruParams]; + _currentSequenceNumber = kFSTListenSequenceNumberInvalid; + // Theoretically this is always 0, since this is all in-memory... + ListenSequenceNumber highestSequenceNumber = + _persistence.queryCache->highest_listen_sequence_number(); + _listenSequence = absl::make_unique(highestSequenceNumber); + _serializer = serializer; + } + return self; +} + +- (FSTLRUGarbageCollector *)gc { + return _gc; +} + +- (ListenSequenceNumber)currentSequenceNumber { + HARD_ASSERT(_currentSequenceNumber != kFSTListenSequenceNumberInvalid, + "Asking for a sequence number outside of a transaction"); + return _currentSequenceNumber; +} + +- (void)addInMemoryPins:(ReferenceSet *)set { + // Technically can't assert this, due to restartWithNoopGarbageCollector (for now...) + // FSTAssert(_additionalReferences == nil, @"Overwriting additional references"); + _additionalReferences = set; +} + +- (void)removeTarget:(FSTQueryData *)queryData { + FSTQueryData *updated = [queryData queryDataByReplacingSnapshotVersion:queryData.snapshotVersion + resumeToken:queryData.resumeToken + sequenceNumber:_currentSequenceNumber]; + _persistence.queryCache->UpdateTarget(updated); +} + +- (void)limboDocumentUpdated:(const DocumentKey &)key { + _sequenceNumbers[key] = self.currentSequenceNumber; +} + +- (void)startTransaction:(absl::string_view)label { + _currentSequenceNumber = _listenSequence->Next(); +} + +- (void)commitTransaction { + _currentSequenceNumber = kFSTListenSequenceNumberInvalid; +} + +- (void)enumerateTargetsUsingCallback:(const TargetCallback &)callback { + return _persistence.queryCache->EnumerateTargets(callback); +} + +- (void)enumerateMutationsUsingCallback: + (const firebase::firestore::local::OrphanedDocumentCallback &)callback { + for (const auto &entry : _sequenceNumbers) { + ListenSequenceNumber sequenceNumber = entry.second; + const DocumentKey &key = entry.first; + // Pass in the exact sequence number as the upper bound so we know it won't be pinned by being + // too recent. + if (![self isPinnedAtSequenceNumber:sequenceNumber document:key]) { + callback(key, sequenceNumber); + } + } +} + +- (int)removeTargetsThroughSequenceNumber:(ListenSequenceNumber)sequenceNumber + liveQueries:(const std::unordered_map &) + liveQueries { + return _persistence.queryCache->RemoveTargets(sequenceNumber, liveQueries); +} + +- (size_t)sequenceNumberCount { + size_t totalCount = _persistence.queryCache->size(); + [self enumerateMutationsUsingCallback:[&totalCount](const DocumentKey &key, + ListenSequenceNumber sequenceNumber) { + totalCount++; + }]; + return totalCount; +} + +- (int)removeOrphanedDocumentsThroughSequenceNumber:(ListenSequenceNumber)upperBound { + std::vector removed = + _persistence.remoteDocumentCache->RemoveOrphanedDocuments(self, upperBound); + for (const auto &key : removed) { + _sequenceNumbers.erase(key); + } + return static_cast(removed.size()); +} + +- (void)addReference:(const DocumentKey &)key { + _sequenceNumbers[key] = self.currentSequenceNumber; +} + +- (void)removeReference:(const DocumentKey &)key { + _sequenceNumbers[key] = self.currentSequenceNumber; +} + +- (BOOL)mutationQueuesContainKey:(const DocumentKey &)key { + const MutationQueues &queues = [_persistence mutationQueues]; + for (const auto &entry : queues) { + if (entry.second->ContainsKey(key)) { + return YES; + } + } + return NO; +} + +- (void)removeMutationReference:(const DocumentKey &)key { + _sequenceNumbers[key] = self.currentSequenceNumber; +} + +- (BOOL)isPinnedAtSequenceNumber:(ListenSequenceNumber)upperBound + document:(const DocumentKey &)key { + if ([self mutationQueuesContainKey:key]) { + return YES; + } + if (_additionalReferences->ContainsKey(key)) { + return YES; + } + if (_persistence.queryCache->Contains(key)) { + return YES; + } + auto it = _sequenceNumbers.find(key); + if (it != _sequenceNumbers.end() && it->second > upperBound) { + return YES; + } + return NO; +} + +- (size_t)byteSize { + // Note that this method is only used for testing because this delegate is only + // used for testing. The algorithm here (loop through everything, serialize it + // and count bytes) is inefficient and inexact, but won't run in production. + size_t count = 0; + count += _persistence.queryCache->CalculateByteSize(_serializer); + count += _persistence.remoteDocumentCache->CalculateByteSize(_serializer); + const MutationQueues &queues = [_persistence mutationQueues]; + for (const auto &entry : queues) { + count += entry.second->CalculateByteSize(_serializer); + } + return count; +} + +@end + +@implementation FSTMemoryEagerReferenceDelegate { + std::unique_ptr> _orphaned; + // This delegate should have the same lifetime as the persistence layer, but mark as + // weak to avoid retain cycle. + __weak FSTMemoryPersistence *_persistence; + ReferenceSet *_additionalReferences; +} + +- (instancetype)initWithPersistence:(FSTMemoryPersistence *)persistence { + if (self = [super init]) { + _persistence = persistence; + } + return self; +} + +- (ListenSequenceNumber)currentSequenceNumber { + return kFSTListenSequenceNumberInvalid; +} + +- (void)addInMemoryPins:(ReferenceSet *)set { + // We should be able to assert that _additionalReferences is nil, but due to restarts in spec + // tests it would fail. + _additionalReferences = set; +} + +- (void)removeTarget:(FSTQueryData *)queryData { + for (const DocumentKey &docKey : _persistence.queryCache->GetMatchingKeys(queryData.targetID)) { + _orphaned->insert(docKey); + } + _persistence.queryCache->RemoveTarget(queryData); +} + +- (void)addReference:(const DocumentKey &)key { + _orphaned->erase(key); +} + +- (void)removeReference:(const DocumentKey &)key { + _orphaned->insert(key); +} + +- (void)removeMutationReference:(const DocumentKey &)key { + _orphaned->insert(key); +} + +- (BOOL)isReferenced:(const DocumentKey &)key { + if (_persistence.queryCache->Contains(key)) { + return YES; + } + if ([self mutationQueuesContainKey:key]) { + return YES; + } + if (_additionalReferences->ContainsKey(key)) { + return YES; + } + return NO; +} + +- (void)limboDocumentUpdated:(const DocumentKey &)key { + if ([self isReferenced:key]) { + _orphaned->erase(key); + } else { + _orphaned->insert(key); + } +} + +- (void)startTransaction:(__unused absl::string_view)label { + _orphaned = absl::make_unique>(); +} + +- (BOOL)mutationQueuesContainKey:(const DocumentKey &)key { + const MutationQueues &queues = [_persistence mutationQueues]; + for (const auto &entry : queues) { + if (entry.second->ContainsKey(key)) { + return YES; + } + } + return NO; +} + +- (void)commitTransaction { + for (const auto &key : *_orphaned) { + if (![self isReferenced:key]) { + _persistence.remoteDocumentCache->Remove(key); + } + } + _orphaned.reset(); +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Local/FSTPersistence.h b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Local/FSTPersistence.h new file mode 100644 index 0000000..8595f10 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Local/FSTPersistence.h @@ -0,0 +1,228 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +#include "Firestore/core/src/firebase/firestore/auth/user.h" +#include "Firestore/core/src/firebase/firestore/local/index_manager.h" +#include "Firestore/core/src/firebase/firestore/local/mutation_queue.h" +#include "Firestore/core/src/firebase/firestore/local/query_cache.h" +#include "Firestore/core/src/firebase/firestore/local/reference_set.h" +#include "Firestore/core/src/firebase/firestore/local/remote_document_cache.h" +#include "Firestore/core/src/firebase/firestore/model/document_key.h" +#include "Firestore/core/src/firebase/firestore/model/types.h" +#include "Firestore/core/src/firebase/firestore/util/hard_assert.h" +#include "Firestore/core/src/firebase/firestore/util/status.h" + +@class FSTQueryData; +@protocol FSTReferenceDelegate; + +struct FSTTransactionRunner; + +NS_ASSUME_NONNULL_BEGIN + +/** + * FSTPersistence is the lowest-level shared interface to persistent storage in Firestore. + * + * FSTPersistence is used to create FSTMutationQueue and FSTRemoteDocumentCache instances backed + * by persistence (which might be in-memory or LevelDB). + * + * FSTPersistence also exposes an API to create and commit FSTWriteGroup instances. + * Implementations of FSTWriteGroup/FSTPersistence only need to guarantee that writes made + * against the FSTWriteGroup are not made to durable storage until commitGroup:action: is called + * here. Since memory-only storage components do not alter durable storage, they are free to ignore + * the group. + * + * This contract is enough to allow the FSTLocalStore be be written independently of whether or not + * the stored state actually is durably persisted. If persistent storage is enabled, writes are + * grouped together to avoid inconsistent state that could cause crashes. + * + * Concretely, when persistent storage is enabled, the persistent versions of FSTMutationQueue, + * FSTRemoteDocumentCache, and others (the mutators) will defer their writes into an FSTWriteGroup. + * Once the local store has completed one logical operation, it commits the write group using + * [FSTPersistence commitGroup:action:]. + * + * When persistent storage is disabled, the non-persistent versions of the mutators ignore the + * FSTWriteGroup and [FSTPersistence commitGroup:action:] is a no-op. This short-cut is allowed + * because memory-only storage leaves no state so it cannot be inconsistent. + * + * This simplifies the implementations of the mutators and allows memory-only implementations to + * supplement the persistent ones without requiring any special dual-store implementation of + * FSTPersistence. The cost is that the FSTLocalStore needs to be slightly careful about the order + * of its reads and writes in order to avoid relying on being able to read back uncommitted writes. + */ +@protocol FSTPersistence + +/** Releases any resources held during eager shutdown. */ +- (void)shutdown; + +/** + * Returns a MutationQueue representing the persisted mutations for the given user. + * + *

Note: The implementation is free to return the same instance every time this is called for a + * given user. In particular, the memory-backed implementation does this to emulate the persisted + * implementation to the extent possible (e.g. in the case of uid switching from + * sally=>jack=>sally, sally's mutation queue will be preserved). + */ +- (firebase::firestore::local::MutationQueue *)mutationQueueForUser: + (const firebase::firestore::auth::User &)user; + +/** Creates an FSTQueryCache representing the persisted cache of queries. */ +- (firebase::firestore::local::QueryCache *)queryCache; + +/** Creates a RemoteDocumentCache representing the persisted cache of remote documents. */ +- (firebase::firestore::local::RemoteDocumentCache *)remoteDocumentCache; + +/** Creates an IndexManager that manages our persisted query indexes. */ +- (firebase::firestore::local::IndexManager *)indexManager; + +@property(nonatomic, readonly, assign) const FSTTransactionRunner &run; + +/** + * This property provides access to hooks around the document reference lifecycle. It is initially + * nullable while being implemented, but the goal is to eventually have it be non-nil. + */ +@property(nonatomic, readonly, strong) id referenceDelegate; + +@property(nonatomic, readonly) + firebase::firestore::model::ListenSequenceNumber currentSequenceNumber; + +@end + +@protocol FSTTransactional + +- (void)startTransaction:(absl::string_view)label; + +- (void)commitTransaction; + +@end + +/** + * An FSTReferenceDelegate instance handles all of the hooks into the document-reference lifecycle. + * This includes being added to a target, being removed from a target, being subject to mutation, + * and being mutated by the user. + * + * Different implementations may do different things with each of these events. Not every + * implementation needs to do something with every lifecycle hook. + * + * Implementations that care about sequence numbers are responsible for generating them and making + * them available. + */ +@protocol FSTReferenceDelegate + +/** + * Registers an FSTReferenceSet of documents that should be considered 'referenced' and not eligible + * for removal during garbage collection. + */ +- (void)addInMemoryPins:(firebase::firestore::local::ReferenceSet *)set; + +/** + * Notify the delegate that a target was removed. + */ +- (void)removeTarget:(FSTQueryData *)queryData; + +/** + * Notify the delegate that the given document was added to a target. + */ +- (void)addReference:(const firebase::firestore::model::DocumentKey &)key; + +/** + * Notify the delegate that the given document was removed from a target. + */ +- (void)removeReference:(const firebase::firestore::model::DocumentKey &)key; + +/** + * Notify the delegate that a document is no longer being mutated by the user. + */ +- (void)removeMutationReference:(const firebase::firestore::model::DocumentKey &)key; + +/** + * Notify the delegate that a limbo document was updated. + */ +- (void)limboDocumentUpdated:(const firebase::firestore::model::DocumentKey &)key; + +@property(nonatomic, readonly) + firebase::firestore::model::ListenSequenceNumber currentSequenceNumber; + +@end + +struct FSTTransactionRunner { +// Intentionally disable nullability checking for this function. We cannot properly annotate +// the function because this function can handle both pointer and non-pointer types. It is an error +// to annotate non-pointer types with a nullability annotation. +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wnullability-completeness" + + /** + * The following two functions handle accepting callables and optionally running them within a + * transaction. Persistence layers that conform to the FSTTransactional protocol can set + * themselves as the backing persistence for a transaction runner, in which case a transaction + * will be started before a block is run, and committed after the block has executed. If there is + * no backing instance of FSTTransactional, the block will be run directly. + * + * There are two instances of operator() to handle the case where the block returns void, rather + * than a type. + * + * The transaction runner keeps a weak reference to the backing persistence so as not to cause a + * retain cycle. The reference is upgraded to strong (with a fatal error if it has disappeared) + * for the duration of running a transaction. + */ + + template + auto operator()(absl::string_view label, F block) const -> + typename std::enable_if::value, void>::type { + __strong id strongDb = _db; + if (!strongDb && _expect_db) { + HARD_FAIL("Transaction runner accessed without underlying db when it expected one"); + } + if (strongDb) { + [strongDb startTransaction:label]; + } + block(); + if (strongDb) { + [strongDb commitTransaction]; + } + } + + template + auto operator()(absl::string_view label, F block) const -> + typename std::enable_if::value, decltype(block())>::type { + using ReturnT = decltype(block()); + __strong id strongDb = _db; + if (!strongDb && _expect_db) { + HARD_FAIL("Transaction runner accessed without underlying db when it expected one"); + } + if (strongDb) { + [strongDb startTransaction:label]; + } + ReturnT result = block(); + if (strongDb) { + [strongDb commitTransaction]; + } + return result; + } +#pragma clang diagnostic pop + void SetBackingPersistence(id db) { + _db = db; + _expect_db = true; + } + + private: + __weak id _db; + bool _expect_db = false; +}; + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Local/FSTQueryData.h b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Local/FSTQueryData.h new file mode 100644 index 0000000..f96f327 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Local/FSTQueryData.h @@ -0,0 +1,93 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +#include "Firestore/core/src/firebase/firestore/model/snapshot_version.h" +#include "Firestore/core/src/firebase/firestore/model/types.h" + +@class FSTQuery; + +NS_ASSUME_NONNULL_BEGIN + +/** An enumeration of the different purposes we have for queries. */ +typedef NS_ENUM(NSInteger, FSTQueryPurpose) { + /** A regular, normal query. */ + FSTQueryPurposeListen, + + /** The query was used to refill a query after an existence filter mismatch. */ + FSTQueryPurposeExistenceFilterMismatch, + + /** The query was used to resolve a limbo document. */ + FSTQueryPurposeLimboResolution, +}; + +/** An immutable set of metadata that the store will need to keep track of for each query. */ +@interface FSTQueryData : NSObject + +- (instancetype)initWithQuery:(FSTQuery *)query + targetID:(firebase::firestore::model::TargetId)targetID + listenSequenceNumber:(firebase::firestore::model::ListenSequenceNumber)sequenceNumber + purpose:(FSTQueryPurpose)purpose + snapshotVersion:(firebase::firestore::model::SnapshotVersion)snapshotVersion + resumeToken:(NSData *)resumeToken NS_DESIGNATED_INITIALIZER; + +/** Convenience initializer for use when creating an FSTQueryData for the first time. */ +- (instancetype)initWithQuery:(FSTQuery *)query + targetID:(firebase::firestore::model::TargetId)targetID + listenSequenceNumber:(firebase::firestore::model::ListenSequenceNumber)sequenceNumber + purpose:(FSTQueryPurpose)purpose; + +- (instancetype)init NS_UNAVAILABLE; + +/** + * Creates a new query data instance with an updated snapshot version, resume token, and sequence + * number. + */ +- (instancetype) + queryDataByReplacingSnapshotVersion:(firebase::firestore::model::SnapshotVersion)snapshotVersion + resumeToken:(NSData *)resumeToken + sequenceNumber: + (firebase::firestore::model::ListenSequenceNumber)sequenceNumber; + +/** The latest snapshot version seen for this target. */ +- (const firebase::firestore::model::SnapshotVersion &)snapshotVersion; + +/** The query being listened to. */ +@property(nonatomic, strong, readonly) FSTQuery *query; + +/** + * The targetID to which the query corresponds, assigned by the FSTLocalStore for user queries or + * the FSTSyncEngine for limbo queries. + */ +@property(nonatomic, assign, readonly) firebase::firestore::model::TargetId targetID; + +@property(nonatomic, assign, readonly) + firebase::firestore::model::ListenSequenceNumber sequenceNumber; + +/** The purpose of the query. */ +@property(nonatomic, assign, readonly) FSTQueryPurpose purpose; + +/** + * An opaque, server-assigned token that allows watching a query to be resumed after disconnecting + * without retransmitting all the data that matches the query. The resume token essentially + * identifies a point in time from which the server should resume sending results. + */ +@property(nonatomic, copy, readonly) NSData *resumeToken; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Local/FSTQueryData.mm b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Local/FSTQueryData.mm new file mode 100644 index 0000000..dc174c3 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Local/FSTQueryData.mm @@ -0,0 +1,112 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "Firestore/Source/Local/FSTQueryData.h" + +#include + +#import "Firestore/Source/Core/FSTQuery.h" + +#include "Firestore/core/src/firebase/firestore/model/snapshot_version.h" +#include "Firestore/core/src/firebase/firestore/util/hashing.h" + +namespace util = firebase::firestore::util; +using firebase::firestore::model::ListenSequenceNumber; +using firebase::firestore::model::SnapshotVersion; +using firebase::firestore::model::TargetId; + +NS_ASSUME_NONNULL_BEGIN + +@implementation FSTQueryData { + SnapshotVersion _snapshotVersion; +} + +- (instancetype)initWithQuery:(FSTQuery *)query + targetID:(TargetId)targetID + listenSequenceNumber:(ListenSequenceNumber)sequenceNumber + purpose:(FSTQueryPurpose)purpose + snapshotVersion:(SnapshotVersion)snapshotVersion + resumeToken:(NSData *)resumeToken { + self = [super init]; + if (self) { + _query = query; + _targetID = targetID; + _sequenceNumber = sequenceNumber; + _purpose = purpose; + _snapshotVersion = std::move(snapshotVersion); + _resumeToken = [resumeToken copy]; + } + return self; +} + +- (instancetype)initWithQuery:(FSTQuery *)query + targetID:(TargetId)targetID + listenSequenceNumber:(ListenSequenceNumber)sequenceNumber + purpose:(FSTQueryPurpose)purpose { + return [self initWithQuery:query + targetID:targetID + listenSequenceNumber:sequenceNumber + purpose:purpose + snapshotVersion:SnapshotVersion::None() + resumeToken:[NSData data]]; +} + +- (const firebase::firestore::model::SnapshotVersion &)snapshotVersion { + return _snapshotVersion; +} + +- (BOOL)isEqual:(id)object { + if (self == object) { + return YES; + } + if (![object isKindOfClass:[FSTQueryData class]]) { + return NO; + } + + FSTQueryData *other = (FSTQueryData *)object; + return [self.query isEqual:other.query] && self.targetID == other.targetID && + self.sequenceNumber == other.sequenceNumber && self.purpose == other.purpose && + self.snapshotVersion == other.snapshotVersion && + [self.resumeToken isEqual:other.resumeToken]; +} + +- (NSUInteger)hash { + return util::Hash([self.query hash], self.targetID, self.sequenceNumber, + static_cast(self.purpose), self.snapshotVersion.Hash(), + [self.resumeToken hash]); +} + +- (NSString *)description { + return [NSString + stringWithFormat:@"", + self.query, self.targetID, (unsigned long)self.purpose, + self.snapshotVersion.timestamp().ToString().c_str(), self.resumeToken]; +} + +- (instancetype)queryDataByReplacingSnapshotVersion:(SnapshotVersion)snapshotVersion + resumeToken:(NSData *)resumeToken + sequenceNumber:(ListenSequenceNumber)sequenceNumber { + return [[FSTQueryData alloc] initWithQuery:self.query + targetID:self.targetID + listenSequenceNumber:sequenceNumber + purpose:self.purpose + snapshotVersion:std::move(snapshotVersion) + resumeToken:resumeToken]; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Model/FSTDocument.h b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Model/FSTDocument.h new file mode 100644 index 0000000..acbec89 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Model/FSTDocument.h @@ -0,0 +1,98 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +#include "Firestore/core/src/firebase/firestore/model/document_key.h" +#include "Firestore/core/src/firebase/firestore/model/field_path.h" +#include "Firestore/core/src/firebase/firestore/model/snapshot_version.h" + +@class FSTFieldValue; +@class GCFSDocument; +@class FSTObjectValue; + +NS_ASSUME_NONNULL_BEGIN + +/** Describes the `hasPendingWrites` state of a document. */ +typedef NS_ENUM(NSInteger, FSTDocumentState) { + /** Local mutations applied via the mutation queue. Document is potentially inconsistent. */ + FSTDocumentStateLocalMutations, + /** Mutations applied based on a write acknowledgment. Document is potentially inconsistent. */ + FSTDocumentStateCommittedMutations, + /** No mutations applied. Document was sent to us by Watch. */ + FSTDocumentStateSynced +}; + +/** + * The result of a lookup for a given path may be an existing document or a tombstone that marks + * the path deleted. + */ +@interface FSTMaybeDocument : NSObject +- (id)init __attribute__((unavailable("Abstract base class"))); +- (const firebase::firestore::model::DocumentKey &)key; +- (const firebase::firestore::model::SnapshotVersion &)version; + +/** + * Whether this document has a local mutation applied that has not yet been acknowledged by Watch. + */ +- (bool)hasPendingWrites; + +@end + +@interface FSTDocument : FSTMaybeDocument ++ (instancetype)documentWithData:(FSTObjectValue *)data + key:(firebase::firestore::model::DocumentKey)key + version:(firebase::firestore::model::SnapshotVersion)version + state:(FSTDocumentState)state; + ++ (instancetype)documentWithData:(FSTObjectValue *)data + key:(firebase::firestore::model::DocumentKey)key + version:(firebase::firestore::model::SnapshotVersion)version + state:(FSTDocumentState)state + proto:(GCFSDocument *)proto; + +- (nullable FSTFieldValue *)fieldForPath:(const firebase::firestore::model::FieldPath &)path; +- (bool)hasLocalMutations; +- (bool)hasCommittedMutations; + +@property(nonatomic, strong, readonly) FSTObjectValue *data; + +/** + * Memoized serialized form of the document for optimization purposes (avoids repeated + * serialization). Might be nil. + */ +@property(nonatomic, strong, readonly) GCFSDocument *proto; + +@end + +@interface FSTDeletedDocument : FSTMaybeDocument ++ (instancetype)documentWithKey:(firebase::firestore::model::DocumentKey)key + version:(firebase::firestore::model::SnapshotVersion)version + hasCommittedMutations:(bool)committedMutations; + +- (bool)hasCommittedMutations; + +@end + +@interface FSTUnknownDocument : FSTMaybeDocument ++ (instancetype)documentWithKey:(firebase::firestore::model::DocumentKey)key + version:(firebase::firestore::model::SnapshotVersion)version; +@end + +/** An NSComparator suitable for comparing docs using only their keys. */ +extern const NSComparator FSTDocumentComparatorByKey; + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Model/FSTDocument.mm b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Model/FSTDocument.mm new file mode 100644 index 0000000..1e35d5b --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Model/FSTDocument.mm @@ -0,0 +1,271 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "Firestore/Source/Model/FSTDocument.h" + +#include + +#import "Firestore/Source/Model/FSTFieldValue.h" +#import "Firestore/Source/Util/FSTClasses.h" + +#include "Firestore/core/src/firebase/firestore/model/document_key.h" +#include "Firestore/core/src/firebase/firestore/model/field_path.h" +#include "Firestore/core/src/firebase/firestore/util/hard_assert.h" +#include "Firestore/core/src/firebase/firestore/util/hashing.h" +#include "Firestore/core/src/firebase/firestore/util/string_apple.h" + +namespace util = firebase::firestore::util; +using firebase::firestore::model::DocumentKey; +using firebase::firestore::model::FieldPath; +using firebase::firestore::model::SnapshotVersion; + +NS_ASSUME_NONNULL_BEGIN + +@interface FSTMaybeDocument () + +- (instancetype)initWithKey:(DocumentKey)key + version:(SnapshotVersion)version NS_DESIGNATED_INITIALIZER; + +@end + +@implementation FSTMaybeDocument { + DocumentKey _key; + SnapshotVersion _version; +} + +- (instancetype)initWithKey:(DocumentKey)key version:(SnapshotVersion)version { + self = [super init]; + if (self) { + _key = std::move(key); + _version = std::move(version); + } + return self; +} + +- (bool)hasPendingWrites { + @throw FSTAbstractMethodException(); // NOLINT +} + +- (id)copyWithZone:(NSZone *_Nullable)zone { + // All document types are immutable + return self; +} + +- (const DocumentKey &)key { + return _key; +} + +- (const SnapshotVersion &)version { + return _version; +} + +@end + +@implementation FSTDocument { + FSTDocumentState _documentState; +} + ++ (instancetype)documentWithData:(FSTObjectValue *)data + key:(DocumentKey)key + version:(SnapshotVersion)version + state:(FSTDocumentState)state { + return [[FSTDocument alloc] initWithData:data + key:std::move(key) + version:std::move(version) + state:state]; +} + ++ (instancetype)documentWithData:(FSTObjectValue *)data + key:(DocumentKey)key + version:(SnapshotVersion)version + state:(FSTDocumentState)state + proto:(GCFSDocument *)proto { + return [[FSTDocument alloc] initWithData:data + key:std::move(key) + version:std::move(version) + state:state + proto:proto]; +} + +- (instancetype)initWithData:(FSTObjectValue *)data + key:(DocumentKey)key + version:(SnapshotVersion)version + state:(FSTDocumentState)state { + self = [super initWithKey:std::move(key) version:std::move(version)]; + if (self) { + _data = data; + _documentState = state; + _proto = nil; + } + return self; +} + +- (instancetype)initWithData:(FSTObjectValue *)data + key:(DocumentKey)key + version:(SnapshotVersion)version + state:(FSTDocumentState)state + proto:(GCFSDocument *)proto { + self = [super initWithKey:std::move(key) version:std::move(version)]; + if (self) { + _data = data; + _documentState = state; + _proto = proto; + } + return self; +} + +- (bool)hasLocalMutations { + return _documentState == FSTDocumentStateLocalMutations; +} + +- (bool)hasCommittedMutations { + return _documentState == FSTDocumentStateCommittedMutations; +} + +- (bool)hasPendingWrites { + return self.hasLocalMutations || self.hasCommittedMutations; +} + +- (BOOL)isEqual:(id)other { + if (other == self) { + return YES; + } + if (![other isKindOfClass:[FSTDocument class]]) { + return NO; + } + + FSTDocument *otherDoc = other; + return self.key == otherDoc.key && self.version == otherDoc.version && + _documentState == otherDoc->_documentState && [self.data isEqual:otherDoc.data]; +} + +- (NSUInteger)hash { + NSUInteger result = self.key.Hash(); + result = result * 31 + self.version.Hash(); + result = result * 31 + [self.data hash]; + result = result * 31 + _documentState; + return result; +} + +- (NSString *)description { + return [NSString stringWithFormat:@"", + self.key.ToString().c_str(), + self.version.timestamp().ToString().c_str(), + (long)_documentState, self.data]; +} + +- (nullable FSTFieldValue *)fieldForPath:(const FieldPath &)path { + return [_data valueForPath:path]; +} + +@end + +@implementation FSTDeletedDocument { + bool _hasCommittedMutations; +} + ++ (instancetype)documentWithKey:(DocumentKey)key + version:(SnapshotVersion)version + hasCommittedMutations:(bool)committedMutations { + FSTDeletedDocument *deletedDocument = [[FSTDeletedDocument alloc] initWithKey:std::move(key) + version:std::move(version)]; + + if (deletedDocument) { + deletedDocument->_hasCommittedMutations = committedMutations; + } + + return deletedDocument; +} + +- (bool)hasCommittedMutations { + return _hasCommittedMutations; +} + +- (bool)hasPendingWrites { + return self.hasCommittedMutations; +} + +- (BOOL)isEqual:(id)other { + if (other == self) { + return YES; + } + if (![other isKindOfClass:[FSTDeletedDocument class]]) { + return NO; + } + + FSTDeletedDocument *otherDoc = other; + return self.key == otherDoc.key && self.version == otherDoc.version && + _hasCommittedMutations == otherDoc->_hasCommittedMutations; +} + +- (NSUInteger)hash { + NSUInteger result = self.key.Hash(); + result = result * 31 + self.version.Hash(); + result = result * 31 + (_hasCommittedMutations ? 1 : 0); + return result; +} + +- (NSString *)description { + return [NSString + stringWithFormat:@"", + self.key.ToString().c_str(), self.version.timestamp().ToString().c_str(), + _hasCommittedMutations]; +} + +@end + +@implementation FSTUnknownDocument + ++ (instancetype)documentWithKey:(DocumentKey)key version:(SnapshotVersion)version { + return [[FSTUnknownDocument alloc] initWithKey:std::move(key) version:std::move(version)]; +} + +- (bool)hasPendingWrites { + return true; +} + +- (BOOL)isEqual:(id)other { + if (other == self) { + return YES; + } + if (![other isKindOfClass:[FSTUnknownDocument class]]) { + return NO; + } + + FSTDocument *otherDoc = other; + return self.key == otherDoc.key && self.version == otherDoc.version; +} + +- (NSUInteger)hash { + NSUInteger result = self.key.Hash(); + result = result * 31 + self.version.Hash(); + return result; +} + +- (NSString *)description { + return [NSString stringWithFormat:@"", + self.key.ToString().c_str(), + self.version.timestamp().ToString().c_str()]; +} + +@end + +const NSComparator FSTDocumentComparatorByKey = + ^NSComparisonResult(FSTMaybeDocument *doc1, FSTMaybeDocument *doc2) { + return CompareKeys(doc1.key, doc2.key); + }; + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Model/FSTDocumentKey.h b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Model/FSTDocumentKey.h new file mode 100644 index 0000000..80e6cc9 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Model/FSTDocumentKey.h @@ -0,0 +1,51 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +#include +#include + +#include "Firestore/core/src/firebase/firestore/model/resource_path.h" + +// Using forward declaration to avoid circular dependency (`document_key.h` includes this header).` +namespace firebase { +namespace firestore { +namespace model { +class DocumentKey; +} +} +} + +NS_ASSUME_NONNULL_BEGIN + +/** + * `FSTDocumentKey` is a thin wrapper over `DocumentKey`, necessary until full migration is + * possible. Use the underlying `DocumentKey` for any operations. + */ +@interface FSTDocumentKey : NSObject + ++ (instancetype)keyWithDocumentKey:(const firebase::firestore::model::DocumentKey &)documentKey; + +/** Gets the underlying C++ representation. */ +- (const firebase::firestore::model::DocumentKey &)key; + +@end + +/** The field path string that represents the document's key. */ +extern NSString *const kDocumentKeyPath; + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Model/FSTDocumentKey.mm b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Model/FSTDocumentKey.mm new file mode 100644 index 0000000..5fc78c1 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Model/FSTDocumentKey.mm @@ -0,0 +1,87 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "Firestore/Source/Model/FSTDocumentKey.h" + +#include +#include + +#import "Firestore/Source/Core/FSTFirestoreClient.h" + +#include "Firestore/core/src/firebase/firestore/model/document_key.h" +#include "Firestore/core/src/firebase/firestore/util/hard_assert.h" +#include "Firestore/core/src/firebase/firestore/util/hashing.h" +#include "Firestore/core/src/firebase/firestore/util/string_apple.h" + +namespace util = firebase::firestore::util; +using firebase::firestore::model::ResourcePath; +using firebase::firestore::model::DocumentKey; + +NS_ASSUME_NONNULL_BEGIN + +@interface FSTDocumentKey () { + // Forward most of the logic to the C++ implementation until FSTDocumentKey usages are completely + // migrated. + DocumentKey _delegate; +} +@end + +@implementation FSTDocumentKey + ++ (instancetype)keyWithDocumentKey:(const firebase::firestore::model::DocumentKey &)documentKey { + return [[FSTDocumentKey alloc] initWithDocumentKey:documentKey]; +} + +/** Designated initializer. */ +- (instancetype)initWithDocumentKey:(const DocumentKey &)key { + if (self = [super init]) { + _delegate = key; + } + return self; +} + +- (const DocumentKey &)key { + return _delegate; +} + +- (BOOL)isEqual:(id)object { + if (self == object) { + return YES; + } + if (![object isKindOfClass:[FSTDocumentKey class]]) { + return NO; + } + return _delegate == static_cast(object)->_delegate; +} + +- (NSUInteger)hash { + return _delegate.Hash(); +} + +- (NSString *)description { + return [NSString stringWithFormat:@"", _delegate.ToString().c_str()]; +} + +/** Implements NSCopying without actually copying because FSTDocumentKeys are immutable. */ +- (id)copyWithZone:(NSZone *_Nullable)zone { + return self; +} + +@end + +NSString *const kDocumentKeyPath = @"__name__"; + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Model/FSTFieldValue.h b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Model/FSTFieldValue.h new file mode 100644 index 0000000..5a9b696 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Model/FSTFieldValue.h @@ -0,0 +1,282 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +#import "Firestore/third_party/Immutable/FSTImmutableSortedDictionary.h" + +#include "Firestore/core/src/firebase/firestore/model/database_id.h" +#include "Firestore/core/src/firebase/firestore/model/field_mask.h" +#include "Firestore/core/src/firebase/firestore/model/field_path.h" + +@class FSTDocumentKey; +@class FIRTimestamp; +@class FSTFieldValueOptions; +@class FIRGeoPoint; + +NS_ASSUME_NONNULL_BEGIN + +/** The order of types in Firestore; this order is defined by the backend. */ +typedef NS_ENUM(NSInteger, FSTTypeOrder) { + FSTTypeOrderNull, + FSTTypeOrderBoolean, + FSTTypeOrderNumber, + FSTTypeOrderTimestamp, + FSTTypeOrderString, + FSTTypeOrderBlob, + FSTTypeOrderReference, + FSTTypeOrderGeoPoint, + FSTTypeOrderArray, + FSTTypeOrderObject, +}; + +/** Defines the return value for pending server timestamps. */ +enum class ServerTimestampBehavior { None, Estimate, Previous }; + +/** Holds properties that define field value deserialization options. */ +@interface FSTFieldValueOptions : NSObject + +@property(nonatomic, readonly, assign) ServerTimestampBehavior serverTimestampBehavior; + +@property(nonatomic) BOOL timestampsInSnapshotsEnabled; + +- (instancetype)init NS_UNAVAILABLE; + +/** + * Creates an FSTFieldValueOptions instance that specifies deserialization behavior for pending + * server timestamps. + */ +- (instancetype)initWithServerTimestampBehavior:(ServerTimestampBehavior)serverTimestampBehavior + timestampsInSnapshotsEnabled:(BOOL)timestampsInSnapshotsEnabled + NS_DESIGNATED_INITIALIZER; + +@end + +/** + * Abstract base class representing an immutable data value as stored in Firestore. FSTFieldValue + * represents all the different kinds of values that can be stored in fields in a document. + * + * Supported types are: + * - Null + * - Boolean + * - Long + * - Double + * - Timestamp + * - ServerTimestamp (a sentinel used in uncommitted writes) + * - String + * - Binary + * - (Document) References + * - GeoPoint + * - Array + * - Object + */ +@interface FSTFieldValue<__covariant T> : NSObject + +/** Returns the FSTTypeOrder for this value. */ +- (FSTTypeOrder)typeOrder; + +/** + * Converts an FSTFieldValue into the value that users will see in document snapshots. + * + * TODO(mikelehen): This conversion should probably happen at the API level and right now `value` is + * used inappropriately in the serializer implementation, etc. We need to do some reworking. + */ +- (T)value; + +/** + * Converts an FSTFieldValue into the value that users will see in document snapshots. + * + * Options can be provided to configure the deserialization of some field values (such as server + * timestamps). + */ +- (T)valueWithOptions:(FSTFieldValueOptions *)options; + +/** Compares against another FSTFieldValue. */ +- (NSComparisonResult)compare:(FSTFieldValue *)other; + +@end + +/** + * A null value stored in Firestore. The |value| of a FSTNullValue is [NSNull null]. + */ +@interface FSTNullValue : FSTFieldValue ++ (instancetype)nullValue; +@end + +/** + * A boolean value stored in Firestore. + */ +@interface FSTBooleanValue : FSTFieldValue ++ (instancetype)trueValue; ++ (instancetype)falseValue; ++ (instancetype)booleanValue:(BOOL)value; +@end + +/** + * Base class inherited from by FSTIntegerValue and FSTDoubleValue. It implements proper number + * comparisons between the two types. + */ +@interface FSTNumberValue : FSTFieldValue +@end + +/** + * An integer value stored in Firestore. + */ +@interface FSTIntegerValue : FSTNumberValue ++ (instancetype)integerValue:(int64_t)value; +- (int64_t)internalValue; +@end + +/** + * A double-precision floating point number stored in Firestore. + */ +@interface FSTDoubleValue : FSTNumberValue ++ (instancetype)doubleValue:(double)value; ++ (instancetype)nanValue; +- (double)internalValue; +@end + +/** + * A string stored in Firestore. + */ +@interface FSTStringValue : FSTFieldValue ++ (instancetype)stringValue:(NSString *)value; +@end + +/** + * A timestamp value stored in Firestore. + */ +@interface FSTTimestampValue : FSTFieldValue ++ (instancetype)timestampValue:(FIRTimestamp *)value; +@end + +/** + * Represents a locally-applied Server Timestamp. + * + * Notes: + * - FSTServerTimestampValue instances are created as the result of applying an FSTTransformMutation + * (see [FSTTransformMutation applyTo]). They can only exist in the local view of a document. + * Therefore they do not need to be parsed or serialized. + * - When evaluated locally (e.g. via FSTDocumentSnapshot data), they by default evaluate to NSNull. + * This behavior can be configured by passing custom FSTFieldValueOptions to `valueWithOptions:`. + * - They sort after all FSTTimestampValues. With respect to other FSTServerTimestampValues, they + * sort by their localWriteTime. + */ +@interface FSTServerTimestampValue : FSTFieldValue ++ (instancetype)serverTimestampValueWithLocalWriteTime:(FIRTimestamp *)localWriteTime + previousValue:(nullable FSTFieldValue *)previousValue; + +@property(nonatomic, strong, readonly) FIRTimestamp *localWriteTime; +@property(nonatomic, strong, readonly, nullable) FSTFieldValue *previousValue; + +@end + +/** + * A geo point value stored in Firestore. + */ +@interface FSTGeoPointValue : FSTFieldValue ++ (instancetype)geoPointValue:(FIRGeoPoint *)value; +@end + +/** + * A blob value stored in Firestore. + */ +@interface FSTBlobValue : FSTFieldValue ++ (instancetype)blobValue:(NSData *)value; +@end + +/** + * A reference value stored in Firestore. + */ +@interface FSTReferenceValue : FSTFieldValue ++ (instancetype)referenceValue:(FSTDocumentKey *)value + databaseID:(const firebase::firestore::model::DatabaseId *)databaseID; +// Does not own this DatabaseId. +@property(nonatomic, assign, readonly) const firebase::firestore::model::DatabaseId *databaseID; +@end + +/** + * A structured object value stored in Firestore. + */ +// clang-format off +@interface FSTObjectValue : FSTFieldValue < NSDictionary * > + +- (instancetype)init NS_UNAVAILABLE; +// clang-format on + +/** Returns an empty FSTObjectValue. */ ++ (instancetype)objectValue; + +/** + * Initializes this FSTObjectValue with the given dictionary. + */ +- (instancetype)initWithDictionary:(NSDictionary *)value; + +/** + * Initializes this FSTObjectValue with the given immutable dictionary. + */ +- (instancetype)initWithImmutableDictionary: + (FSTImmutableSortedDictionary *)value NS_DESIGNATED_INITIALIZER; + +- (FSTImmutableSortedDictionary *)internalValue; + +/** Returns the value at the given path if it exists. Returns nil otherwise. */ +- (nullable FSTFieldValue *)valueForPath:(const firebase::firestore::model::FieldPath &)fieldPath; + +/** + * Returns a new object where the field at the named path has its value set to the given value. + * This object remains unmodified. + */ +- (FSTObjectValue *)objectBySettingValue:(FSTFieldValue *)value + forPath:(const firebase::firestore::model::FieldPath &)fieldPath; + +/** + * Returns a new object where the field at the named path has been removed. If any segment of the + * path does not exist within this object's structure, no change is performed. + */ +- (FSTObjectValue *)objectByDeletingPath:(const firebase::firestore::model::FieldPath &)fieldPath; + +/** + * Applies this field mask to the provided object value and returns an object that only contains + * fields that are specified in both the input object and this field mask. + */ +// TODO(mrschmidt): Once FieldValues are C++, move this to FieldMask to match other platforms. +- (FSTObjectValue *)objectByApplyingFieldMask: + (const firebase::firestore::model::FieldMask &)fieldMask; +@end + +/** + * An array value stored in Firestore. + */ +// clang-format off +@interface FSTArrayValue : FSTFieldValue < NSArray * > + +- (instancetype)init NS_UNAVAILABLE; +// clang-format on + +/** + * Initializes this instance with the given array of wrapped values. + * + * @param value An immutable array of FSTFieldValue objects. Caller is responsible for copying the + * value or releasing all references. + */ +- (instancetype)initWithValueNoCopy:(NSArray *)value NS_DESIGNATED_INITIALIZER; + +- (NSArray *)internalValue; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Model/FSTFieldValue.mm b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Model/FSTFieldValue.mm new file mode 100644 index 0000000..7730f39 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Model/FSTFieldValue.mm @@ -0,0 +1,967 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "Firestore/Source/Model/FSTFieldValue.h" + +#import "FIRDocumentSnapshot.h" +#import "FIRTimestamp.h" + +#import "Firestore/Source/API/FIRGeoPoint+Internal.h" +#import "Firestore/Source/Model/FSTDocumentKey.h" +#import "Firestore/Source/Util/FSTClasses.h" + +#include "Firestore/core/src/firebase/firestore/model/database_id.h" +#include "Firestore/core/src/firebase/firestore/model/document_key.h" +#include "Firestore/core/src/firebase/firestore/model/field_path.h" +#include "Firestore/core/src/firebase/firestore/util/comparison.h" +#include "Firestore/core/src/firebase/firestore/util/hard_assert.h" +#include "Firestore/core/src/firebase/firestore/util/string_apple.h" + +namespace util = firebase::firestore::util; +using firebase::firestore::model::DatabaseId; +using firebase::firestore::model::FieldMask; +using firebase::firestore::model::FieldPath; +using firebase::firestore::util::Comparator; +using firebase::firestore::util::CompareMixedNumber; +using firebase::firestore::util::DoubleBitwiseEquals; +using firebase::firestore::util::DoubleBitwiseHash; +using firebase::firestore::util::MakeStringView; +using firebase::firestore::util::ReverseOrder; +using firebase::firestore::util::WrapCompare; + +NS_ASSUME_NONNULL_BEGIN + +#pragma mark - FSTFieldValueOptions + +@implementation FSTFieldValueOptions + +- (instancetype)initWithServerTimestampBehavior:(ServerTimestampBehavior)serverTimestampBehavior + timestampsInSnapshotsEnabled:(BOOL)timestampsInSnapshotsEnabled { + self = [super init]; + + if (self) { + _serverTimestampBehavior = serverTimestampBehavior; + _timestampsInSnapshotsEnabled = timestampsInSnapshotsEnabled; + } + return self; +} + +@end + +#pragma mark - FSTFieldValue + +@interface FSTFieldValue () +- (NSComparisonResult)defaultCompare:(FSTFieldValue *)other; +@end + +@implementation FSTFieldValue + +- (FSTTypeOrder)typeOrder { + @throw FSTAbstractMethodException(); // NOLINT +} + +- (id)value { + @throw FSTAbstractMethodException(); // NOLINT +} + +- (id)valueWithOptions:(FSTFieldValueOptions *)options { + return [self value]; +} + +- (BOOL)isEqual:(id)other { + @throw FSTAbstractMethodException(); // NOLINT +} + +- (NSUInteger)hash { + @throw FSTAbstractMethodException(); // NOLINT +} + +- (NSComparisonResult)compare:(FSTFieldValue *)other { + @throw FSTAbstractMethodException(); // NOLINT +} + +- (NSString *)description { + return [[self value] description]; +} + +- (NSComparisonResult)defaultCompare:(FSTFieldValue *)other { + if (self.typeOrder > other.typeOrder) { + return NSOrderedDescending; + } else { + HARD_ASSERT(self.typeOrder < other.typeOrder, + "defaultCompare should not be used for values of same type."); + return NSOrderedAscending; + } +} + +@end + +#pragma mark - FSTNullValue + +@implementation FSTNullValue + ++ (instancetype)nullValue { + static FSTNullValue *sharedInstance = nil; + static dispatch_once_t onceToken; + + dispatch_once(&onceToken, ^{ + sharedInstance = [[FSTNullValue alloc] init]; + }); + return sharedInstance; +} + +- (FSTTypeOrder)typeOrder { + return FSTTypeOrderNull; +} + +- (id)value { + return [NSNull null]; +} + +- (BOOL)isEqual:(id)other { + return [other isKindOfClass:[self class]]; +} + +- (NSUInteger)hash { + return 47; +} + +- (NSComparisonResult)compare:(FSTFieldValue *)other { + if ([other isKindOfClass:[self class]]) { + return NSOrderedSame; + } else { + return [self defaultCompare:other]; + } +} + +@end + +#pragma mark - FSTBooleanValue + +@interface FSTBooleanValue () +@property(nonatomic, assign, readonly) BOOL internalValue; +@end + +@implementation FSTBooleanValue + ++ (instancetype)trueValue { + static FSTBooleanValue *sharedInstance = nil; + static dispatch_once_t onceToken; + + dispatch_once(&onceToken, ^{ + sharedInstance = [[FSTBooleanValue alloc] initWithValue:YES]; + }); + return sharedInstance; +} + ++ (instancetype)falseValue { + static FSTBooleanValue *sharedInstance = nil; + static dispatch_once_t onceToken; + + dispatch_once(&onceToken, ^{ + sharedInstance = [[FSTBooleanValue alloc] initWithValue:NO]; + }); + return sharedInstance; +} + ++ (instancetype)booleanValue:(BOOL)value { + return value ? [FSTBooleanValue trueValue] : [FSTBooleanValue falseValue]; +} + +- (id)initWithValue:(BOOL)value { + self = [super init]; + if (self) { + _internalValue = value; + } + return self; +} + +- (FSTTypeOrder)typeOrder { + return FSTTypeOrderBoolean; +} + +- (id)value { + return self.internalValue ? @YES : @NO; +} + +- (BOOL)isEqual:(id)other { + // Since we create shared instances for true / false, we can use reference equality. + return self == other; +} + +- (NSUInteger)hash { + return self.internalValue ? 1231 : 1237; +} + +- (NSComparisonResult)compare:(FSTFieldValue *)other { + if ([other isKindOfClass:[FSTBooleanValue class]]) { + return WrapCompare(self.internalValue, ((FSTBooleanValue *)other).internalValue); + } else { + return [self defaultCompare:other]; + } +} + +@end + +#pragma mark - FSTNumberValue + +@implementation FSTNumberValue + +- (FSTTypeOrder)typeOrder { + return FSTTypeOrderNumber; +} + +- (NSComparisonResult)compare:(FSTFieldValue *)other { + if (![other isKindOfClass:[FSTNumberValue class]]) { + return [self defaultCompare:other]; + } else { + if ([self isKindOfClass:[FSTDoubleValue class]]) { + double thisDouble = ((FSTDoubleValue *)self).internalValue; + if ([other isKindOfClass:[FSTDoubleValue class]]) { + return WrapCompare(thisDouble, ((FSTDoubleValue *)other).internalValue); + } else { + HARD_ASSERT([other isKindOfClass:[FSTIntegerValue class]], "Unknown number value: %s", + other); + auto result = CompareMixedNumber(thisDouble, ((FSTIntegerValue *)other).internalValue); + return static_cast(result); + } + } else { + int64_t thisInt = ((FSTIntegerValue *)self).internalValue; + if ([other isKindOfClass:[FSTIntegerValue class]]) { + return WrapCompare(thisInt, ((FSTIntegerValue *)other).internalValue); + } else { + HARD_ASSERT([other isKindOfClass:[FSTDoubleValue class]], "Unknown number value: %s", + other); + double otherDouble = ((FSTDoubleValue *)other).internalValue; + auto result = ReverseOrder(CompareMixedNumber(otherDouble, thisInt)); + return static_cast(result); + } + } + } +} + +@end + +#pragma mark - FSTIntegerValue + +@interface FSTIntegerValue () +@property(nonatomic, assign, readonly) int64_t internalValue; +@end + +@implementation FSTIntegerValue + ++ (instancetype)integerValue:(int64_t)value { + return [[FSTIntegerValue alloc] initWithValue:value]; +} + +- (id)initWithValue:(int64_t)value { + self = [super init]; + if (self) { + _internalValue = value; + } + return self; +} + +- (id)value { + return @(self.internalValue); +} + +- (BOOL)isEqual:(id)other { + // NOTE: DoubleValue and LongValue instances may compare: the same, but that doesn't make them + // equal via isEqual: + return [other isKindOfClass:[FSTIntegerValue class]] && + self.internalValue == ((FSTIntegerValue *)other).internalValue; +} + +- (NSUInteger)hash { + return (((NSUInteger)self.internalValue) ^ (NSUInteger)(self.internalValue >> 32)); +} + +// NOTE: compare: is implemented in NumberValue. + +@end + +#pragma mark - FSTDoubleValue + +@interface FSTDoubleValue () +@property(nonatomic, assign, readonly) double internalValue; +@end + +@implementation FSTDoubleValue + ++ (instancetype)doubleValue:(double)value { + // Normalize NaNs to match the behavior on the backend (which uses Double.doubletoLongBits()). + if (isnan(value)) { + return [FSTDoubleValue nanValue]; + } + return [[FSTDoubleValue alloc] initWithValue:value]; +} + ++ (instancetype)nanValue { + static FSTDoubleValue *sharedInstance = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + sharedInstance = [[FSTDoubleValue alloc] initWithValue:NAN]; + }); + return sharedInstance; +} + +- (id)initWithValue:(double)value { + self = [super init]; + if (self) { + _internalValue = value; + } + return self; +} + +- (id)value { + return @(self.internalValue); +} + +- (BOOL)isEqual:(id)other { + // NOTE: DoubleValue and LongValue instances may compare: the same, but that doesn't make them + // equal via isEqual: + + // NOTE: isEqual: should compare NaN equal to itself and -0.0 not equal to 0.0. + + return [other isKindOfClass:[FSTDoubleValue class]] && + DoubleBitwiseEquals(self.internalValue, ((FSTDoubleValue *)other).internalValue); +} + +- (NSUInteger)hash { + return DoubleBitwiseHash(self.internalValue); +} + +// NOTE: compare: is implemented in NumberValue. + +@end + +#pragma mark - FSTStringValue + +/** + * Specialization of Comparator for NSStrings. + */ +template <> +struct Comparator { + bool operator()(NSString *left, NSString *right) const { + Comparator lessThan; + return lessThan(MakeString(left), MakeString(right)); + } +}; + +@interface FSTStringValue () +@property(nonatomic, copy, readonly) NSString *internalValue; +@end + +// TODO(b/37267885): Add truncation support +@implementation FSTStringValue + ++ (instancetype)stringValue:(NSString *)value { + return [[FSTStringValue alloc] initWithValue:value]; +} + +- (id)initWithValue:(NSString *)value { + self = [super init]; + if (self) { + _internalValue = [value copy]; + } + return self; +} + +- (FSTTypeOrder)typeOrder { + return FSTTypeOrderString; +} + +- (id)value { + return self.internalValue; +} + +- (BOOL)isEqual:(id)other { + return [other isKindOfClass:[FSTStringValue class]] && + [self.internalValue isEqualToString:((FSTStringValue *)other).internalValue]; +} + +- (NSUInteger)hash { + return self.internalValue ? 1 : 0; +} + +- (NSComparisonResult)compare:(FSTFieldValue *)other { + if ([other isKindOfClass:[FSTStringValue class]]) { + return WrapCompare(self.internalValue, ((FSTStringValue *)other).internalValue); + } else { + return [self defaultCompare:other]; + } +} + +@end + +#pragma mark - FSTTimestampValue + +@interface FSTTimestampValue () +@property(nonatomic, strong, readonly) FIRTimestamp *internalValue; +@end + +@implementation FSTTimestampValue + ++ (instancetype)timestampValue:(FIRTimestamp *)value { + return [[FSTTimestampValue alloc] initWithValue:value]; +} + +- (id)initWithValue:(FIRTimestamp *)value { + self = [super init]; + if (self) { + _internalValue = value; // FIRTimestamp is immutable. + } + return self; +} + +- (FSTTypeOrder)typeOrder { + return FSTTypeOrderTimestamp; +} + +- (id)value { + return self.internalValue; +} + +- (id)valueWithOptions:(FSTFieldValueOptions *)options { + if (options.timestampsInSnapshotsEnabled) { + return self.value; + } else { + return [self.value dateValue]; + } +} + +- (BOOL)isEqual:(id)other { + return [other isKindOfClass:[FSTTimestampValue class]] && + [self.internalValue isEqual:((FSTTimestampValue *)other).internalValue]; +} + +- (NSUInteger)hash { + return [self.internalValue hash]; +} + +- (NSComparisonResult)compare:(FSTFieldValue *)other { + if ([other isKindOfClass:[FSTTimestampValue class]]) { + return [self.internalValue compare:((FSTTimestampValue *)other).internalValue]; + } else if ([other isKindOfClass:[FSTServerTimestampValue class]]) { + // Concrete timestamps come before server timestamps. + return NSOrderedAscending; + } else { + return [self defaultCompare:other]; + } +} + +@end +#pragma mark - FSTServerTimestampValue + +@implementation FSTServerTimestampValue + ++ (instancetype)serverTimestampValueWithLocalWriteTime:(FIRTimestamp *)localWriteTime + previousValue:(nullable FSTFieldValue *)previousValue { + return [[FSTServerTimestampValue alloc] initWithLocalWriteTime:localWriteTime + previousValue:previousValue]; +} + +- (id)initWithLocalWriteTime:(FIRTimestamp *)localWriteTime + previousValue:(nullable FSTFieldValue *)previousValue { + self = [super init]; + if (self) { + _localWriteTime = localWriteTime; + _previousValue = previousValue; + } + return self; +} + +- (FSTTypeOrder)typeOrder { + return FSTTypeOrderTimestamp; +} + +- (id)value { + return [NSNull null]; +} + +- (id)valueWithOptions:(FSTFieldValueOptions *)options { + switch (options.serverTimestampBehavior) { + case ServerTimestampBehavior::None: + return [NSNull null]; + case ServerTimestampBehavior::Estimate: + return [[FSTTimestampValue timestampValue:self.localWriteTime] valueWithOptions:options]; + case ServerTimestampBehavior::Previous: + return self.previousValue ? [self.previousValue valueWithOptions:options] : [NSNull null]; + default: + HARD_FAIL("Unexpected server timestamp option: %s", options.serverTimestampBehavior); + } +} + +- (BOOL)isEqual:(id)other { + return [other isKindOfClass:[FSTServerTimestampValue class]] && + [self.localWriteTime isEqual:((FSTServerTimestampValue *)other).localWriteTime]; +} + +- (NSUInteger)hash { + return [self.localWriteTime hash]; +} + +- (NSString *)description { + return [NSString stringWithFormat:@"", self.localWriteTime]; +} + +- (NSComparisonResult)compare:(FSTFieldValue *)other { + if ([other isKindOfClass:[FSTServerTimestampValue class]]) { + return [self.localWriteTime compare:((FSTServerTimestampValue *)other).localWriteTime]; + } else if ([other isKindOfClass:[FSTTimestampValue class]]) { + // Server timestamps come after all concrete timestamps. + return NSOrderedDescending; + } else { + return [self defaultCompare:other]; + } +} + +@end + +#pragma mark - FSTGeoPointValue + +@interface FSTGeoPointValue () +@property(nonatomic, strong, readonly) FIRGeoPoint *internalValue; +@end + +@implementation FSTGeoPointValue + ++ (instancetype)geoPointValue:(FIRGeoPoint *)value { + return [[FSTGeoPointValue alloc] initWithValue:value]; +} + +- (id)initWithValue:(FIRGeoPoint *)value { + self = [super init]; + if (self) { + _internalValue = value; // FIRGeoPoint is immutable. + } + return self; +} + +- (FSTTypeOrder)typeOrder { + return FSTTypeOrderGeoPoint; +} + +- (id)value { + return self.internalValue; +} + +- (BOOL)isEqual:(id)other { + return [other isKindOfClass:[FSTGeoPointValue class]] && + [self.internalValue isEqual:((FSTGeoPointValue *)other).internalValue]; +} + +- (NSUInteger)hash { + return [self.internalValue hash]; +} + +- (NSComparisonResult)compare:(FSTFieldValue *)other { + if ([other isKindOfClass:[FSTGeoPointValue class]]) { + return [self.internalValue compare:((FSTGeoPointValue *)other).internalValue]; + } else { + return [self defaultCompare:other]; + } +} + +@end +#pragma mark - FSTBlobValue + +static NSComparisonResult CompareBytes(NSData *left, NSData *right) { + NSUInteger minLength = MIN(left.length, right.length); + int result = memcmp(left.bytes, right.bytes, minLength); + if (result < 0) { + return NSOrderedAscending; + } else if (result > 0) { + return NSOrderedDescending; + } else if (left.length < right.length) { + return NSOrderedAscending; + } else if (left.length > right.length) { + return NSOrderedDescending; + } else { + return NSOrderedSame; + } +} + +@interface FSTBlobValue () +@property(nonatomic, copy, readonly) NSData *internalValue; +@end + +// TODO(b/37267885): Add truncation support +@implementation FSTBlobValue + ++ (instancetype)blobValue:(NSData *)value { + return [[FSTBlobValue alloc] initWithValue:value]; +} + +- (id)initWithValue:(NSData *)value { + self = [super init]; + if (self) { + _internalValue = [value copy]; + } + return self; +} + +- (FSTTypeOrder)typeOrder { + return FSTTypeOrderBlob; +} + +- (id)value { + return self.internalValue; +} + +- (BOOL)isEqual:(id)other { + return [other isKindOfClass:[FSTBlobValue class]] && + [self.internalValue isEqual:((FSTBlobValue *)other).internalValue]; +} + +- (NSUInteger)hash { + return [self.internalValue hash]; +} + +- (NSComparisonResult)compare:(FSTFieldValue *)other { + if ([other isKindOfClass:[FSTBlobValue class]]) { + return CompareBytes(self.internalValue, ((FSTBlobValue *)other).internalValue); + } else { + return [self defaultCompare:other]; + } +} + +@end + +#pragma mark - FSTReferenceValue + +@interface FSTReferenceValue () +@property(nonatomic, strong, readonly) FSTDocumentKey *key; +@end + +@implementation FSTReferenceValue + ++ (instancetype)referenceValue:(FSTDocumentKey *)value databaseID:(const DatabaseId *)databaseID { + return [[FSTReferenceValue alloc] initWithValue:value databaseID:databaseID]; +} + +- (id)initWithValue:(FSTDocumentKey *)value databaseID:(const DatabaseId *)databaseID { + self = [super init]; + if (self) { + _key = value; + _databaseID = databaseID; + } + return self; +} + +- (id)value { + return self.key; +} + +- (FSTTypeOrder)typeOrder { + return FSTTypeOrderReference; +} + +- (BOOL)isEqual:(id)other { + if (other == self) { + return YES; + } + if (![other isKindOfClass:[FSTReferenceValue class]]) { + return NO; + } + + FSTReferenceValue *otherRef = (FSTReferenceValue *)other; + return self.key.key == otherRef.key.key && *self.databaseID == *otherRef.databaseID; +} + +- (NSUInteger)hash { + NSUInteger result = self.databaseID->Hash(); + result = 31 * result + [self.key hash]; + return result; +} + +- (NSComparisonResult)compare:(FSTFieldValue *)other { + if ([other isKindOfClass:[FSTReferenceValue class]]) { + FSTReferenceValue *ref = (FSTReferenceValue *)other; + NSComparisonResult cmp = + WrapCompare(self.databaseID->project_id(), ref.databaseID->project_id()); + if (cmp != NSOrderedSame) { + return cmp; + } + cmp = WrapCompare(self.databaseID->database_id(), ref.databaseID->database_id()); + return cmp != NSOrderedSame ? cmp : CompareKeys(self.key.key, ref.key.key); + } else { + return [self defaultCompare:other]; + } +} + +@end + +#pragma mark - FSTObjectValue + +static const NSComparator StringComparator = ^NSComparisonResult(NSString *left, NSString *right) { + return WrapCompare(left, right); +}; + +@interface FSTObjectValue () +@property(nonatomic, strong, readonly) + FSTImmutableSortedDictionary *internalValue; +@end + +@implementation FSTObjectValue + ++ (instancetype)objectValue { + static FSTObjectValue *sharedEmptyInstance = nil; + static dispatch_once_t onceToken; + + dispatch_once(&onceToken, ^{ + FSTImmutableSortedDictionary *empty = + [FSTImmutableSortedDictionary dictionaryWithComparator:StringComparator]; + sharedEmptyInstance = [[FSTObjectValue alloc] initWithImmutableDictionary:empty]; + }); + return sharedEmptyInstance; +} + +- (instancetype)initWithImmutableDictionary: + (FSTImmutableSortedDictionary *)value { + self = [super init]; + if (self) { + _internalValue = value; // FSTImmutableSortedDictionary is immutable. + } + return self; +} + +- (id)initWithDictionary:(NSDictionary *)value { + FSTImmutableSortedDictionary *dictionary = + [FSTImmutableSortedDictionary dictionaryWithDictionary:value comparator:StringComparator]; + return [self initWithImmutableDictionary:dictionary]; +} + +- (id)value { + NSMutableDictionary *result = [NSMutableDictionary dictionary]; + [self.internalValue + enumerateKeysAndObjectsUsingBlock:^(NSString *key, FSTFieldValue *obj, BOOL *stop) { + result[key] = [obj value]; + }]; + return result; +} + +- (id)valueWithOptions:(FSTFieldValueOptions *)options { + NSMutableDictionary *result = [NSMutableDictionary dictionary]; + [self.internalValue + enumerateKeysAndObjectsUsingBlock:^(NSString *key, FSTFieldValue *obj, BOOL *stop) { + result[key] = [obj valueWithOptions:options]; + }]; + return result; +} + +- (FSTTypeOrder)typeOrder { + return FSTTypeOrderObject; +} + +- (BOOL)isEqual:(id)other { + if (other == self) { + return YES; + } + if (![other isKindOfClass:[FSTObjectValue class]]) { + return NO; + } + + FSTObjectValue *otherObj = other; + return [self.internalValue isEqual:otherObj.internalValue]; +} + +- (NSUInteger)hash { + return [self.internalValue hash]; +} + +- (NSComparisonResult)compare:(FSTFieldValue *)other { + if ([other isKindOfClass:[FSTObjectValue class]]) { + FSTImmutableSortedDictionary *selfDict = self.internalValue; + FSTImmutableSortedDictionary *otherDict = ((FSTObjectValue *)other).internalValue; + NSEnumerator *enumerator1 = [selfDict keyEnumerator]; + NSEnumerator *enumerator2 = [otherDict keyEnumerator]; + NSString *key1 = [enumerator1 nextObject]; + NSString *key2 = [enumerator2 nextObject]; + while (key1 && key2) { + NSComparisonResult keyCompare = [key1 compare:key2]; + if (keyCompare != NSOrderedSame) { + return keyCompare; + } + NSComparisonResult valueCompare = [selfDict[key1] compare:otherDict[key2]]; + if (valueCompare != NSOrderedSame) { + return valueCompare; + } + key1 = [enumerator1 nextObject]; + key2 = [enumerator2 nextObject]; + } + // Only equal if both enumerators are exhausted. + return WrapCompare(key1 != nil, key2 != nil); + } else { + return [self defaultCompare:other]; + } +} + +- (nullable FSTFieldValue *)valueForPath:(const FieldPath &)fieldPath { + FSTFieldValue *value = self; + for (size_t i = 0, max = fieldPath.size(); value && i < max; i++) { + if (![value isMemberOfClass:[FSTObjectValue class]]) { + return nil; + } + + NSString *fieldName = util::WrapNSStringNoCopy(fieldPath[i]); + value = ((FSTObjectValue *)value).internalValue[fieldName]; + } + + return value; +} + +- (FSTObjectValue *)objectBySettingValue:(FSTFieldValue *)value + forPath:(const FieldPath &)fieldPath { + HARD_ASSERT(fieldPath.size() > 0, "Cannot set value with an empty path"); + + NSString *childName = util::WrapNSString(fieldPath.first_segment()); + if (fieldPath.size() == 1) { + // Recursive base case: + return [self objectBySettingValue:value forField:childName]; + } else { + // Nested path. Recursively generate a new sub-object and then wrap a new FSTObjectValue + // around the result. + FSTFieldValue *child = [_internalValue objectForKey:childName]; + FSTObjectValue *childObject; + if ([child isKindOfClass:[FSTObjectValue class]]) { + childObject = (FSTObjectValue *)child; + } else { + // If the child is not found or is a primitive type, pretend as if an empty object lived + // there. + childObject = [FSTObjectValue objectValue]; + } + FSTFieldValue *newChild = [childObject objectBySettingValue:value forPath:fieldPath.PopFirst()]; + return [self objectBySettingValue:newChild forField:childName]; + } +} + +- (FSTObjectValue *)objectByDeletingPath:(const FieldPath &)fieldPath { + HARD_ASSERT(fieldPath.size() > 0, "Cannot delete an empty path"); + NSString *childName = util::WrapNSString(fieldPath.first_segment()); + if (fieldPath.size() == 1) { + return [[FSTObjectValue alloc] + initWithImmutableDictionary:[_internalValue dictionaryByRemovingObjectForKey:childName]]; + } else { + FSTFieldValue *child = _internalValue[childName]; + if ([child isKindOfClass:[FSTObjectValue class]]) { + FSTObjectValue *newChild = + [((FSTObjectValue *)child) objectByDeletingPath:fieldPath.PopFirst()]; + return [self objectBySettingValue:newChild forField:childName]; + } else { + // If the child is not found or is a primitive type, make no modifications + return self; + } + } +} + +- (FSTObjectValue *)objectBySettingValue:(FSTFieldValue *)value forField:(NSString *)field { + return [[FSTObjectValue alloc] + initWithImmutableDictionary:[_internalValue dictionaryBySettingObject:value forKey:field]]; +} + +- (FSTObjectValue *)objectByApplyingFieldMask:(const FieldMask &)fieldMask { + FSTObjectValue *filteredObject = self; + for (const FieldPath &path : fieldMask) { + if (path.empty()) { + return self; + } else { + FSTFieldValue *newValue = [self valueForPath:path]; + if (newValue) { + filteredObject = [filteredObject objectBySettingValue:newValue forPath:path]; + } + } + } + return filteredObject; +} + +@end + +@interface FSTArrayValue () +@property(nonatomic, strong, readonly) NSArray *internalValue; +@end + +#pragma mark - FSTArrayValue + +@implementation FSTArrayValue + +- (id)initWithValueNoCopy:(NSArray *)value { + self = [super init]; + if (self) { + // Does not copy, assumes the caller has already copied. + _internalValue = value; + } + return self; +} + +- (BOOL)isEqual:(id)other { + if (other == self) { + return YES; + } + if (![other isKindOfClass:[self class]]) { + return NO; + } + + // NSArray's isEqual does the right thing for our purposes. + FSTArrayValue *otherArray = other; + return [self.internalValue isEqual:otherArray.internalValue]; +} + +- (NSUInteger)hash { + return [self.internalValue hash]; +} + +- (id)value { + NSMutableArray *result = [NSMutableArray arrayWithCapacity:_internalValue.count]; + [self.internalValue enumerateObjectsUsingBlock:^(FSTFieldValue *obj, NSUInteger idx, BOOL *stop) { + [result addObject:[obj value]]; + }]; + return result; +} + +- (id)valueWithOptions:(FSTFieldValueOptions *)options { + NSMutableArray *result = [NSMutableArray arrayWithCapacity:_internalValue.count]; + [self.internalValue enumerateObjectsUsingBlock:^(FSTFieldValue *obj, NSUInteger idx, BOOL *stop) { + [result addObject:[obj valueWithOptions:options]]; + }]; + return result; +} + +- (FSTTypeOrder)typeOrder { + return FSTTypeOrderArray; +} + +- (NSComparisonResult)compare:(FSTFieldValue *)other { + if ([other isKindOfClass:[FSTArrayValue class]]) { + NSArray *selfArray = self.internalValue; + NSArray *otherArray = ((FSTArrayValue *)other).internalValue; + NSUInteger minLength = MIN(selfArray.count, otherArray.count); + for (NSUInteger i = 0; i < minLength; i++) { + NSComparisonResult cmp = [selfArray[i] compare:otherArray[i]]; + if (cmp != NSOrderedSame) { + return cmp; + } + } + return WrapCompare(selfArray.count, otherArray.count); + } else { + return [self defaultCompare:other]; + } +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Model/FSTMutation.h b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Model/FSTMutation.h new file mode 100644 index 0000000..6eb38e2 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Model/FSTMutation.h @@ -0,0 +1,281 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +#include +#include + +#include "Firestore/core/src/firebase/firestore/model/document_key.h" +#include "Firestore/core/src/firebase/firestore/model/field_mask.h" +#include "Firestore/core/src/firebase/firestore/model/field_path.h" +#include "Firestore/core/src/firebase/firestore/model/field_transform.h" +#include "Firestore/core/src/firebase/firestore/model/precondition.h" +#include "Firestore/core/src/firebase/firestore/model/snapshot_version.h" +#include "Firestore/core/src/firebase/firestore/model/transform_operations.h" + +#include "absl/types/optional.h" + +@class FSTDocument; +@class FSTFieldValue; +@class FSTMaybeDocument; +@class FSTObjectValue; +@class FIRTimestamp; + +NS_ASSUME_NONNULL_BEGIN + +#pragma mark - FSTMutationResult + +@interface FSTMutationResult : NSObject + +- (instancetype)init NS_UNAVAILABLE; +- (instancetype)initWithVersion:(firebase::firestore::model::SnapshotVersion)version + transformResults:(NSArray *_Nullable)transformResults + NS_DESIGNATED_INITIALIZER; + +/** + * The version at which the mutation was committed. + * + * - For most operations, this is the updateTime in the WriteResult. + * - For deletes, it is the commitTime of the WriteResponse (because deletes are not stored + * and have no updateTime). + * + * Note that these versions can be different: No-op writes will not change the updateTime even + * though the commitTime advances. + */ +- (const firebase::firestore::model::SnapshotVersion &)version; + +/** + * The resulting fields returned from the backend after a FSTTransformMutation has been committed. + * Contains one FieldValue for each FieldTransform that was in the mutation. + * + * Will be nil if the mutation was not a FSTTransformMutation. + */ +@property(nonatomic, strong, readonly) NSArray *_Nullable transformResults; + +@end + +#pragma mark - FSTMutation + +/** + * Represents a Mutation of a document. Different subclasses of Mutation will perform different + * kinds of changes to a base document. For example, an FSTSetMutation replaces the value of a + * document and an FSTDeleteMutation deletes a document. + * + * Subclasses of FSTMutation need to implement `applyToRemoteDocument:mutationResult:` and + * `applyToLocalDocument:baseDocument:localWriteTime:` to implement the actual the behavior of + * mutations as applied to some source document. + * + * In addition to the value of the document mutations also operate on the version. For local + * mutations (mutations that haven't been committed yet), we preserve the existing version for Set, + * Patch, and Transform mutations. For local deletes, we reset the version to 0. + * + * Here's the expected transition table. + * + * MUTATION APPLIED TO RESULTS IN + * + * SetMutation Document(v3) Document(v3) + * SetMutation DeletedDocument(v3) Document(v0) + * SetMutation nil Document(v0) + * PatchMutation Document(v3) Document(v3) + * PatchMutation DeletedDocument(v3) DeletedDocument(v3) + * PatchMutation nil nil + * TransformMutation Document(v3) Document(v3) + * TransformMutation DeletedDocument(v3) DeletedDocument(v3) + * TransformMutation nil nil + * DeleteMutation Document(v3) DeletedDocument(v0) + * DeleteMutation DeletedDocument(v3) DeletedDocument(v0) + * DeleteMutation nil DeletedDocument(v0) + * + * For acknowledged mutations, we use the updateTime of the WriteResponse as the resulting version + * for Set, Patch, and Transform mutations. As deletes have no explicit update time, we use the + * commitTime of the WriteResponse for acknowledged deletes. + * + * If a mutation is acknowledged by the backend but fails the precondition check locally, we + * return an `FSTUnknownDocument` and rely on Watch to send us the updated version. + * + * Note that FSTTransformMutations don't create Documents (in the case of being applied to an + * FSTDeletedDocument), even though they would on the backend. This is because the client always + * combines the FSTTransformMutations with a FSTSetMutation or FSTPatchMutation and we only want to + * apply the transform if the prior mutation resulted in an FSTDocument (always true for an + * FSTSetMutation, but not necessarily for an FSTPatchMutation). + */ +@interface FSTMutation : NSObject + +- (id)init NS_UNAVAILABLE; + +- (instancetype)initWithKey:(firebase::firestore::model::DocumentKey)key + precondition:(firebase::firestore::model::Precondition)precondition + NS_DESIGNATED_INITIALIZER; + +/** + * Applies this mutation to the given FSTMaybeDocument for the purposes of computing a new remote + * document. If the input document doesn't match the expected state (e.g. it is nil or outdated), + * an `FSTUnknownDocument` can be returned. + * + * @param maybeDoc The document to mutate. The input document can be nil if the client has no + * knowledge of the pre-mutation state of the document. + * @param mutationResult The result of applying the mutation from the backend. + * @return The mutated document. The returned document may be an FSTUnknownDocument if the mutation + * could not be applied to the locally cached base document. + */ +- (FSTMaybeDocument *)applyToRemoteDocument:(nullable FSTMaybeDocument *)maybeDoc + mutationResult:(FSTMutationResult *)mutationResult; + +/** + * Applies this mutation to the given FSTMaybeDocument for the purposes of computing the new local + * view of a document. Both the input and returned documents can be nil. + * + * @param maybeDoc The document to mutate. The input document can be nil if the client has no + * knowledge of the pre-mutation state of the document. + * @param baseDoc The state of the document prior to this mutation batch. The input document can + * be nil if the client has no knowledge of the pre-mutation state of the document. + * @param localWriteTime A timestamp indicating the local write time of the batch this mutation is + * a part of. + * @return The mutated document. The returned document may be nil, but only if maybeDoc was nil + * and the mutation would not create a new document. + */ +- (nullable FSTMaybeDocument *)applyToLocalDocument:(nullable FSTMaybeDocument *)maybeDoc + baseDocument:(nullable FSTMaybeDocument *)baseDoc + localWriteTime:(FIRTimestamp *)localWriteTime; + +- (const firebase::firestore::model::DocumentKey &)key; + +- (const firebase::firestore::model::Precondition &)precondition; + +/** + * If applicable, returns the field mask for this mutation. Fields that are not included in this + * field mask are not modified when this mutation is applied. Mutations that replace all document + * values return 'nullptr'. + */ +- (const firebase::firestore::model::FieldMask *)fieldMask; + +/** Returns whether all operations in the mutation are idempotent. */ +@property(nonatomic, readonly) BOOL idempotent; + +@end + +#pragma mark - FSTSetMutation + +/** + * A mutation that creates or replaces the document at the given key with the object value + * contents. + */ +@interface FSTSetMutation : FSTMutation + +- (instancetype)initWithKey:(firebase::firestore::model::DocumentKey)key + precondition:(firebase::firestore::model::Precondition)precondition NS_UNAVAILABLE; + +/** + * Initializes the set mutation. + * + * @param key Identifies the location of the document to mutate. + * @param value An object value that describes the contents to store at the location named by the + * key. + * @param precondition The precondition for this mutation. + */ +- (instancetype)initWithKey:(firebase::firestore::model::DocumentKey)key + value:(FSTObjectValue *)value + precondition:(firebase::firestore::model::Precondition)precondition + NS_DESIGNATED_INITIALIZER; + +/** The object value to use when setting the document. */ +@property(nonatomic, strong, readonly) FSTObjectValue *value; +@end + +#pragma mark - FSTPatchMutation + +/** + * A mutation that modifies fields of the document at the given key with the given values. The + * values are applied through a field mask: + * + * * When a field is in both the mask and the values, the corresponding field is updated. + * * When a field is in neither the mask nor the values, the corresponding field is unmodified. + * * When a field is in the mask but not in the values, the corresponding field is deleted. + * * When a field is not in the mask but is in the values, the values map is ignored. + */ +@interface FSTPatchMutation : FSTMutation + +/** Returns the precondition for the given Precondition. */ +- (instancetype)initWithKey:(firebase::firestore::model::DocumentKey)key + precondition:(firebase::firestore::model::Precondition)precondition NS_UNAVAILABLE; + +/** + * Initializes a new patch mutation with an explicit FieldMask and FSTObjectValue representing + * the updates to perform + * + * @param key Identifies the location of the document to mutate. + * @param fieldMask The field mask specifying at what locations the data in value should be + * applied. + * @param value An FSTObjectValue containing the data to be written (using the paths in fieldMask + * to determine the locations at which it should be applied). + * @param precondition The precondition for this mutation. + */ +- (instancetype)initWithKey:(firebase::firestore::model::DocumentKey)key + fieldMask:(firebase::firestore::model::FieldMask)fieldMask + value:(FSTObjectValue *)value + precondition:(firebase::firestore::model::Precondition)precondition + NS_DESIGNATED_INITIALIZER; + +/** + * A mask to apply to |value|, where only fields that are in both the fieldMask and the value + * will be updated. + */ +- (const firebase::firestore::model::FieldMask *)fieldMask; + +/** The fields and associated values to use when patching the document. */ +@property(nonatomic, strong, readonly) FSTObjectValue *value; + +@end + +#pragma mark - FSTTransformMutation + +/** + * A mutation that modifies specific fields of the document with transform operations. Currently + * the only supported transform is a server timestamp, but IP Address, increment(n), etc. could + * be supported in the future. + * + * It is somewhat similar to an FSTPatchMutation in that it patches specific fields and has no + * effect when applied to nil or an FSTDeletedDocument (see comment on [FSTMutation applyTo] for + * rationale). + */ +@interface FSTTransformMutation : FSTMutation + +- (instancetype)initWithKey:(firebase::firestore::model::DocumentKey)key + precondition:(firebase::firestore::model::Precondition)precondition NS_UNAVAILABLE; + +/** + * Initializes a new transform mutation with the specified field transforms. + * + * @param key Identifies the location of the document to mutate. + * @param fieldTransforms A list of FieldTransform objects to perform to the document. + */ +- (instancetype)initWithKey:(firebase::firestore::model::DocumentKey)key + fieldTransforms:(std::vector)fieldTransforms + NS_DESIGNATED_INITIALIZER; + +/** The field transforms to use when transforming the document. */ +- (const std::vector &)fieldTransforms; + +@end + +#pragma mark - FSTDeleteMutation + +@interface FSTDeleteMutation : FSTMutation + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Model/FSTMutation.mm b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Model/FSTMutation.mm new file mode 100644 index 0000000..a805671 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Model/FSTMutation.mm @@ -0,0 +1,598 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "Firestore/Source/Model/FSTMutation.h" + +#include +#include +#include +#include +#include + +#import "FIRTimestamp.h" + +#import "Firestore/Source/Model/FSTDocument.h" +#import "Firestore/Source/Model/FSTFieldValue.h" +#import "Firestore/Source/Util/FSTClasses.h" + +#include "Firestore/core/src/firebase/firestore/model/document_key.h" +#include "Firestore/core/src/firebase/firestore/model/field_mask.h" +#include "Firestore/core/src/firebase/firestore/model/field_path.h" +#include "Firestore/core/src/firebase/firestore/model/field_transform.h" +#include "Firestore/core/src/firebase/firestore/model/precondition.h" +#include "Firestore/core/src/firebase/firestore/model/transform_operations.h" +#include "Firestore/core/src/firebase/firestore/util/hard_assert.h" + +using firebase::firestore::model::ArrayTransform; +using firebase::firestore::model::DocumentKey; +using firebase::firestore::model::FieldMask; +using firebase::firestore::model::FieldPath; +using firebase::firestore::model::FieldTransform; +using firebase::firestore::model::Precondition; +using firebase::firestore::model::ServerTimestampTransform; +using firebase::firestore::model::SnapshotVersion; +using firebase::firestore::model::TransformOperation; +using firebase::firestore::util::Hash; + +NS_ASSUME_NONNULL_BEGIN + +#pragma mark - FSTMutationResult + +@implementation FSTMutationResult { + SnapshotVersion _version; +} + +- (instancetype)initWithVersion:(SnapshotVersion)version + transformResults:(nullable NSArray *)transformResults { + if (self = [super init]) { + _version = std::move(version); + _transformResults = transformResults; + } + return self; +} + +- (const SnapshotVersion &)version { + return _version; +} + +@end + +#pragma mark - FSTMutation + +@implementation FSTMutation { + DocumentKey _key; + Precondition _precondition; +} + +- (instancetype)initWithKey:(DocumentKey)key precondition:(Precondition)precondition { + if (self = [super init]) { + _key = std::move(key); + _precondition = std::move(precondition); + } + return self; +} + +- (FSTMaybeDocument *)applyToRemoteDocument:(nullable FSTMaybeDocument *)maybeDoc + mutationResult:(FSTMutationResult *)mutationResult { + @throw FSTAbstractMethodException(); // NOLINT +} + +- (nullable FSTMaybeDocument *)applyToLocalDocument:(nullable FSTMaybeDocument *)maybeDoc + baseDocument:(nullable FSTMaybeDocument *)baseDoc + localWriteTime:(FIRTimestamp *)localWriteTime { + @throw FSTAbstractMethodException(); // NOLINT +} + +- (const DocumentKey &)key { + return _key; +} + +- (const firebase::firestore::model::Precondition &)precondition { + return _precondition; +} + +- (BOOL)idempotent { + @throw FSTAbstractMethodException(); // NOLINT +} + +- (const FieldMask *)fieldMask { + @throw FSTAbstractMethodException(); // NOLINT +} + +- (void)verifyKeyMatches:(nullable FSTMaybeDocument *)maybeDoc { + if (maybeDoc) { + HARD_ASSERT(maybeDoc.key == self.key, "Can only set a document with the same key"); + } +} + +/** + * Returns the version from the given document for use as the result of a mutation. Mutations are + * defined to return the version of the base document only if it is an existing document. Deleted + * and unknown documents have a post-mutation version of {@code SnapshotVersion::None()}. + */ +- (const SnapshotVersion &)postMutationVersionForDocument:(FSTMaybeDocument *)maybeDoc { + return [maybeDoc isKindOfClass:[FSTDocument class]] ? maybeDoc.version : SnapshotVersion::None(); +} +@end + +#pragma mark - FSTSetMutation + +@implementation FSTSetMutation + +- (instancetype)initWithKey:(DocumentKey)key + value:(FSTObjectValue *)value + precondition:(Precondition)precondition { + if (self = [super initWithKey:std::move(key) precondition:std::move(precondition)]) { + _value = value; + } + return self; +} + +- (NSString *)description { + return [NSString stringWithFormat:@"", + self.key.ToString().c_str(), self.value, + self.precondition.description()]; +} + +- (BOOL)isEqual:(id)other { + if (other == self) { + return YES; + } + if (![other isKindOfClass:[FSTSetMutation class]]) { + return NO; + } + + FSTSetMutation *otherMutation = (FSTSetMutation *)other; + return self.key == otherMutation.key && [self.value isEqual:otherMutation.value] && + self.precondition == otherMutation.precondition; +} + +- (NSUInteger)hash { + return Hash(self.key, self.precondition, [self.value hash]); +} + +- (nullable FSTMaybeDocument *)applyToLocalDocument:(nullable FSTMaybeDocument *)maybeDoc + baseDocument:(nullable FSTMaybeDocument *)baseDoc + localWriteTime:(FIRTimestamp *)localWriteTime { + [self verifyKeyMatches:maybeDoc]; + + if (!self.precondition.IsValidFor(maybeDoc)) { + return maybeDoc; + } + + SnapshotVersion version = [self postMutationVersionForDocument:maybeDoc]; + return [FSTDocument documentWithData:self.value + key:self.key + version:version + state:FSTDocumentStateLocalMutations]; +} + +- (FSTMaybeDocument *)applyToRemoteDocument:(nullable FSTMaybeDocument *)maybeDoc + mutationResult:(FSTMutationResult *)mutationResult { + [self verifyKeyMatches:maybeDoc]; + + HARD_ASSERT(!mutationResult.transformResults, "Transform results received by FSTSetMutation."); + + // Unlike applyToLocalView, if we're applying a mutation to a remote document the server has + // accepted the mutation so the precondition must have held. + + return [FSTDocument documentWithData:self.value + key:self.key + version:mutationResult.version + state:FSTDocumentStateCommittedMutations]; +} + +- (const FieldMask *)fieldMask { + return nullptr; +} + +- (BOOL)idempotent { + return YES; +} + +@end + +#pragma mark - FSTPatchMutation + +@implementation FSTPatchMutation { + FieldMask _fieldMask; +} + +- (instancetype)initWithKey:(DocumentKey)key + fieldMask:(FieldMask)fieldMask + value:(FSTObjectValue *)value + precondition:(Precondition)precondition { + self = [super initWithKey:std::move(key) precondition:std::move(precondition)]; + if (self) { + _fieldMask = std::move(fieldMask); + _value = value; + } + return self; +} + +- (const FieldMask *)fieldMask { + return &_fieldMask; +} + +- (BOOL)isEqual:(id)other { + if (other == self) { + return YES; + } + if (![other isKindOfClass:[FSTPatchMutation class]]) { + return NO; + } + + FSTPatchMutation *otherMutation = (FSTPatchMutation *)other; + return self.key == otherMutation.key && _fieldMask == *(otherMutation.fieldMask) && + [self.value isEqual:otherMutation.value] && + self.precondition == otherMutation.precondition; +} + +- (NSUInteger)hash { + return Hash(self.key, self.precondition, _fieldMask, [self.value hash]); +} + +- (NSString *)description { + return [NSString stringWithFormat:@"", + self.key.ToString().c_str(), _fieldMask.ToString().c_str(), + self.value, self.precondition.description()]; +} + +/** + * Patches the data of document if available or creates a new document. Note that this does not + * check whether or not the precondition of this patch holds. + */ +- (FSTObjectValue *)patchDocument:(nullable FSTMaybeDocument *)maybeDoc { + FSTObjectValue *data; + if ([maybeDoc isKindOfClass:[FSTDocument class]]) { + data = ((FSTDocument *)maybeDoc).data; + } else { + data = [FSTObjectValue objectValue]; + } + return [self patchObjectValue:data]; +} + +- (nullable FSTMaybeDocument *)applyToLocalDocument:(nullable FSTMaybeDocument *)maybeDoc + baseDocument:(nullable FSTMaybeDocument *)baseDoc + localWriteTime:(FIRTimestamp *)localWriteTime { + [self verifyKeyMatches:maybeDoc]; + + if (!self.precondition.IsValidFor(maybeDoc)) { + return maybeDoc; + } + + FSTObjectValue *newData = [self patchDocument:maybeDoc]; + SnapshotVersion version = [self postMutationVersionForDocument:maybeDoc]; + + return [FSTDocument documentWithData:newData + key:self.key + version:version + state:FSTDocumentStateLocalMutations]; +} + +- (FSTMaybeDocument *)applyToRemoteDocument:(nullable FSTMaybeDocument *)maybeDoc + mutationResult:(FSTMutationResult *)mutationResult { + [self verifyKeyMatches:maybeDoc]; + + HARD_ASSERT(!mutationResult.transformResults, "Transform results received by FSTPatchMutation."); + + if (!self.precondition.IsValidFor(maybeDoc)) { + // Since the mutation was not rejected, we know that the precondition matched on the backend. + // We therefore must not have the expected version of the document in our cache and return a + // FSTUnknownDocument with the known updateTime. + return [FSTUnknownDocument documentWithKey:self.key version:mutationResult.version]; + } + + FSTObjectValue *newData = [self patchDocument:maybeDoc]; + + return [FSTDocument documentWithData:newData + key:self.key + version:mutationResult.version + state:FSTDocumentStateCommittedMutations]; +} + +- (FSTObjectValue *)patchObjectValue:(FSTObjectValue *)objectValue { + FSTObjectValue *result = objectValue; + for (const FieldPath &fieldPath : _fieldMask) { + if (!fieldPath.empty()) { + FSTFieldValue *newValue = [self.value valueForPath:fieldPath]; + if (newValue) { + result = [result objectBySettingValue:newValue forPath:fieldPath]; + } else { + result = [result objectByDeletingPath:fieldPath]; + } + } + } + return result; +} + +- (BOOL)idempotent { + return YES; +} + +@end + +@implementation FSTTransformMutation { + /** The field transforms to use when transforming the document. */ + std::vector _fieldTransforms; + FieldMask _fieldMask; +} + +- (instancetype)initWithKey:(DocumentKey)key + fieldTransforms:(std::vector)fieldTransforms { + // NOTE: We set a precondition of exists: true as a safety-check, since we always combine + // FSTTransformMutations with a FSTSetMutation or FSTPatchMutation which (if successful) should + // end up with an existing document. + if (self = [super initWithKey:std::move(key) precondition:Precondition::Exists(true)]) { + _fieldTransforms = std::move(fieldTransforms); + + std::set fields; + for (const auto &transform : _fieldTransforms) { + fields.insert(transform.path()); + } + + _fieldMask = FieldMask(std::move(fields)); + } + return self; +} + +- (const std::vector &)fieldTransforms { + return _fieldTransforms; +} + +- (BOOL)isEqual:(id)other { + if (other == self) { + return YES; + } + if (![other isKindOfClass:[FSTTransformMutation class]]) { + return NO; + } + + FSTTransformMutation *otherMutation = (FSTTransformMutation *)other; + return self.key == otherMutation.key && self.fieldTransforms == otherMutation.fieldTransforms && + self.precondition == otherMutation.precondition; +} + +- (NSUInteger)hash { + NSUInteger result = self.key.Hash(); + result = 31 * result + self.precondition.Hash(); + for (const auto &transform : self.fieldTransforms) { + result = 31 * result + transform.Hash(); + } + return result; +} + +- (NSString *)description { + std::string fieldTransforms; + for (const auto &transform : self.fieldTransforms) { + fieldTransforms += " " + transform.path().CanonicalString(); + } + return [NSString stringWithFormat:@"", + self.key.ToString().c_str(), fieldTransforms.c_str(), + self.precondition.description()]; +} + +- (nullable FSTMaybeDocument *)applyToLocalDocument:(nullable FSTMaybeDocument *)maybeDoc + baseDocument:(nullable FSTMaybeDocument *)baseDoc + localWriteTime:(FIRTimestamp *)localWriteTime { + [self verifyKeyMatches:maybeDoc]; + + if (!self.precondition.IsValidFor(maybeDoc)) { + return maybeDoc; + } + + // We only support transforms with precondition exists, so we can only apply it to an existing + // document + HARD_ASSERT([maybeDoc isMemberOfClass:[FSTDocument class]], "Unknown MaybeDocument type %s", + [maybeDoc class]); + FSTDocument *doc = (FSTDocument *)maybeDoc; + + NSArray *transformResults = + [self localTransformResultsWithBaseDocument:baseDoc writeTime:localWriteTime]; + FSTObjectValue *newData = [self transformObject:doc.data transformResults:transformResults]; + + return [FSTDocument documentWithData:newData + key:doc.key + version:doc.version + state:FSTDocumentStateLocalMutations]; +} + +- (FSTMaybeDocument *)applyToRemoteDocument:(nullable FSTMaybeDocument *)maybeDoc + mutationResult:(FSTMutationResult *)mutationResult { + [self verifyKeyMatches:maybeDoc]; + + HARD_ASSERT(mutationResult.transformResults, + "Transform results missing for FSTTransformMutation."); + + if (!self.precondition.IsValidFor(maybeDoc)) { + // Since the mutation was not rejected, we know that the precondition matched on the backend. + // We therefore must not have the expected version of the document in our cache and return an + // FSTUnknownDocument with the known updateTime. + return [FSTUnknownDocument documentWithKey:self.key version:mutationResult.version]; + } + + // We only support transforms with precondition exists, so we can only apply it to an existing + // document + HARD_ASSERT([maybeDoc isMemberOfClass:[FSTDocument class]], "Unknown MaybeDocument type %s", + [maybeDoc class]); + FSTDocument *doc = (FSTDocument *)maybeDoc; + NSArray *transformResults = + [self serverTransformResultsWithBaseDocument:maybeDoc + serverTransformResults:mutationResult.transformResults]; + + FSTObjectValue *newData = [self transformObject:doc.data transformResults:transformResults]; + + return [FSTDocument documentWithData:newData + key:self.key + version:mutationResult.version + state:FSTDocumentStateCommittedMutations]; +} + +/** + * Creates an array of "transform results" (a transform result is a field value representing the + * result of applying a transform) for use after a FSTTransformMutation has been acknowledged by + * the server. + * + * @param baseDocument The document prior to applying this mutation batch. + * @param serverTransformResults The transform results received by the server. + * @return The transform results array. + */ +- (NSArray *) + serverTransformResultsWithBaseDocument:(nullable FSTMaybeDocument *)baseDocument + serverTransformResults:(NSArray *)serverTransformResults { + NSMutableArray *transformResults = [NSMutableArray array]; + HARD_ASSERT(self.fieldTransforms.size() == serverTransformResults.count, + "server transform result count (%s) should match field transforms count (%s)", + (unsigned long)serverTransformResults.count, self.fieldTransforms.size()); + + for (NSUInteger i = 0; i < serverTransformResults.count; i++) { + const FieldTransform &fieldTransform = self.fieldTransforms[i]; + const TransformOperation &transform = fieldTransform.transformation(); + + FSTFieldValue *previousValue = nil; + if ([baseDocument isMemberOfClass:[FSTDocument class]]) { + previousValue = [((FSTDocument *)baseDocument) fieldForPath:fieldTransform.path()]; + } + + [transformResults + addObject:transform.ApplyToRemoteDocument(previousValue, serverTransformResults[i])]; + } + return transformResults; +} + +/** + * Creates an array of "transform results" (a transform result is a field value representing the + * result of applying a transform) for use when applying an FSTTransformMutation locally. + * + * @param baseDocument The document prior to applying this mutation batch. + * @param localWriteTime The local time of the transform mutation (used to generate + * FSTServerTimestampValues). + * @return The transform results array. + */ +- (NSArray *)localTransformResultsWithBaseDocument: + (nullable FSTMaybeDocument *)baseDocument + writeTime:(FIRTimestamp *)localWriteTime { + NSMutableArray *transformResults = [NSMutableArray array]; + for (const FieldTransform &fieldTransform : self.fieldTransforms) { + const TransformOperation &transform = fieldTransform.transformation(); + + FSTFieldValue *previousValue = nil; + if ([baseDocument isMemberOfClass:[FSTDocument class]]) { + previousValue = [((FSTDocument *)baseDocument) fieldForPath:fieldTransform.path()]; + } + + [transformResults addObject:transform.ApplyToLocalView(previousValue, localWriteTime)]; + } + return transformResults; +} + +- (FSTObjectValue *)transformObject:(FSTObjectValue *)objectValue + transformResults:(NSArray *)transformResults { + HARD_ASSERT(transformResults.count == self.fieldTransforms.size(), + "Transform results length mismatch."); + + for (size_t i = 0; i < self.fieldTransforms.size(); i++) { + const FieldTransform &fieldTransform = self.fieldTransforms[i]; + const FieldPath &fieldPath = fieldTransform.path(); + objectValue = [objectValue objectBySettingValue:transformResults[i] forPath:fieldPath]; + } + return objectValue; +} + +- (const FieldMask *)fieldMask { + return &_fieldMask; +} + +- (BOOL)idempotent { + for (const auto &transform : self.fieldTransforms) { + if (!transform.idempotent()) { + return NO; + } + } + return YES; +} + +@end + +#pragma mark - FSTDeleteMutation + +@implementation FSTDeleteMutation + +- (BOOL)isEqual:(id)other { + if (other == self) { + return YES; + } + if (![other isKindOfClass:[FSTDeleteMutation class]]) { + return NO; + } + + FSTDeleteMutation *otherMutation = (FSTDeleteMutation *)other; + return self.key == otherMutation.key && self.precondition == otherMutation.precondition; +} + +- (NSUInteger)hash { + return Hash(self.key, self.precondition); +} + +- (NSString *)description { + return [NSString stringWithFormat:@"", + self.key.ToString().c_str(), self.precondition.description()]; +} + +- (nullable FSTMaybeDocument *)applyToLocalDocument:(nullable FSTMaybeDocument *)maybeDoc + baseDocument:(nullable FSTMaybeDocument *)baseDoc + localWriteTime:(FIRTimestamp *)localWriteTime { + [self verifyKeyMatches:maybeDoc]; + + if (!self.precondition.IsValidFor(maybeDoc)) { + return maybeDoc; + } + + return [FSTDeletedDocument documentWithKey:self.key + version:SnapshotVersion::None() + hasCommittedMutations:NO]; +} + +- (FSTMaybeDocument *)applyToRemoteDocument:(nullable FSTMaybeDocument *)maybeDoc + mutationResult:(FSTMutationResult *)mutationResult { + [self verifyKeyMatches:maybeDoc]; + + if (mutationResult) { + HARD_ASSERT(!mutationResult.transformResults, + "Transform results received by FSTDeleteMutation."); + } + + // Unlike applyToLocalView, if we're applying a mutation to a remote document the server has + // accepted the mutation so the precondition must have held. + + // We store the deleted document at the commit version of the delete. Any document version + // that the server sends us before the delete was applied is discarded + return [FSTDeletedDocument documentWithKey:self.key + version:mutationResult.version + hasCommittedMutations:YES]; +} + +- (const FieldMask *)fieldMask { + return nullptr; +} + +- (BOOL)idempotent { + return YES; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Model/FSTMutationBatch.h b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Model/FSTMutationBatch.h new file mode 100644 index 0000000..af07fcb --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Model/FSTMutationBatch.h @@ -0,0 +1,143 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +#include +#include + +#include "Firestore/core/src/firebase/firestore/model/document_key.h" +#include "Firestore/core/src/firebase/firestore/model/document_key_set.h" +#include "Firestore/core/src/firebase/firestore/model/document_map.h" +#include "Firestore/core/src/firebase/firestore/model/snapshot_version.h" +#include "Firestore/core/src/firebase/firestore/model/types.h" + +@class FIRTimestamp; +@class FSTMaybeDocument; +@class FSTMutation; +@class FSTMutationResult; +@class FSTMutationBatchResult; + +namespace firebase { +namespace firestore { +namespace model { + +// TODO(wilhuff): make this type a member of MutationBatchResult once that's a C++ class. +using DocumentVersionMap = std::unordered_map; + +} // namespace model +} // namespace firestore +} // namespace firebase + +NS_ASSUME_NONNULL_BEGIN + +/** + * A batch of mutations that will be sent as one unit to the backend. Batches can be marked as a + * tombstone if the mutation queue does not remove them immediately. When a batch is a tombstone + * it has no mutations. + */ +@interface FSTMutationBatch : NSObject + +/** + * Initializes a mutation batch with the given batchID, localWriteTime, base mutations, and + * mutations. + */ +- (instancetype)initWithBatchID:(firebase::firestore::model::BatchId)batchID + localWriteTime:(FIRTimestamp *)localWriteTime + baseMutations:(std::vector &&)baseMutations + mutations:(std::vector &&)mutations NS_DESIGNATED_INITIALIZER; + +- (id)init NS_UNAVAILABLE; + +/** + * Applies all the mutations in this FSTMutationBatch to the specified document to create a new + * remote document. + * + * @param maybeDoc The document to apply mutations to. + * @param documentKey The key of the document to apply mutations to. + * @param mutationBatchResult The result of applying the MutationBatch to the backend. If omitted + * it's assumed that this is a local (latency-compensated) application and documents will have + * their hasLocalMutations flag set. + */ +- (FSTMaybeDocument *_Nullable) + applyToRemoteDocument:(FSTMaybeDocument *_Nullable)maybeDoc + documentKey:(const firebase::firestore::model::DocumentKey &)documentKey + mutationBatchResult:(FSTMutationBatchResult *_Nullable)mutationBatchResult; + +/** + * A helper version of applyTo for applying mutations locally (without a mutation batch result from + * the backend). + */ +- (FSTMaybeDocument *_Nullable) + applyToLocalDocument:(FSTMaybeDocument *_Nullable)maybeDoc + documentKey:(const firebase::firestore::model::DocumentKey &)documentKey; + +/** Computes the local view for all provided documents given the mutations in this batch. */ +- (firebase::firestore::model::MaybeDocumentMap)applyToLocalDocumentSet: + (const firebase::firestore::model::MaybeDocumentMap &)documentSet; + +/** Returns the set of unique keys referenced by all mutations in the batch. */ +- (firebase::firestore::model::DocumentKeySet)keys; + +/** The unique ID of this mutation batch. */ +@property(nonatomic, assign, readonly) firebase::firestore::model::BatchId batchID; + +/** The original write time of this mutation. */ +@property(nonatomic, strong, readonly) FIRTimestamp *localWriteTime; + +/** + * Mutations that are used to populate the base values when this mutation is applied locally. This + * can be used to locally overwrite values that are persisted in the remote document cache. Base + * mutations are never sent to the backend. + */ +- (const std::vector &)baseMutations; + +/** + * The user-provided mutations in this mutation batch. User-provided mutations are applied both + * locally and remotely on the backend. + */ +- (const std::vector &)mutations; + +@end + +#pragma mark - FSTMutationBatchResult + +/** The result of applying a mutation batch to the backend. */ +@interface FSTMutationBatchResult : NSObject + +- (instancetype)init NS_UNAVAILABLE; + +/** + * Creates a new FSTMutationBatchResult for the given batch and results. There must be one result + * for each mutation in the batch. This static factory caches a document=>version mapping + * (as docVersions). + */ ++ (instancetype)resultWithBatch:(FSTMutationBatch *)batch + commitVersion:(firebase::firestore::model::SnapshotVersion)commitVersion + mutationResults:(std::vector)mutationResults + streamToken:(nullable NSData *)streamToken; + +- (const firebase::firestore::model::SnapshotVersion &)commitVersion; +- (const std::vector &)mutationResults; + +@property(nonatomic, strong, readonly) FSTMutationBatch *batch; +@property(nonatomic, strong, readonly, nullable) NSData *streamToken; + +- (const firebase::firestore::model::DocumentVersionMap &)docVersions; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Model/FSTMutationBatch.mm b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Model/FSTMutationBatch.mm new file mode 100644 index 0000000..2d1e2c3 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Model/FSTMutationBatch.mm @@ -0,0 +1,255 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "Firestore/Source/Model/FSTMutationBatch.h" + +#include +#include + +#import "FIRTimestamp.h" + +#import "Firestore/Source/Model/FSTDocument.h" +#import "Firestore/Source/Model/FSTMutation.h" + +#include "Firestore/core/src/firebase/firestore/model/document_map.h" +#include "Firestore/core/src/firebase/firestore/util/hard_assert.h" +#include "Firestore/core/src/firebase/firestore/util/hashing.h" +#include "Firestore/core/src/firebase/firestore/util/objc_compatibility.h" + +namespace objc = firebase::firestore::util::objc; +using firebase::firestore::model::BatchId; +using firebase::firestore::model::DocumentKey; +using firebase::firestore::model::DocumentKeyHash; +using firebase::firestore::model::DocumentKeySet; +using firebase::firestore::model::DocumentVersionMap; +using firebase::firestore::model::MaybeDocumentMap; +using firebase::firestore::model::SnapshotVersion; +using firebase::firestore::util::Hash; + +NS_ASSUME_NONNULL_BEGIN + +@implementation FSTMutationBatch { + std::vector _baseMutations; + std::vector _mutations; +} + +- (instancetype)initWithBatchID:(BatchId)batchID + localWriteTime:(FIRTimestamp *)localWriteTime + baseMutations:(std::vector &&)baseMutations + mutations:(std::vector &&)mutations { + HARD_ASSERT(!mutations.empty(), "Cannot create an empty mutation batch"); + self = [super init]; + if (self) { + _batchID = batchID; + _localWriteTime = localWriteTime; + _baseMutations = std::move(baseMutations); + _mutations = std::move(mutations); + } + return self; +} + +- (const std::vector &)baseMutations { + return _baseMutations; +} + +- (const std::vector &)mutations { + return _mutations; +} + +- (BOOL)isEqual:(id)other { + if (self == other) { + return YES; + } else if (![other isKindOfClass:[FSTMutationBatch class]]) { + return NO; + } + + FSTMutationBatch *otherBatch = (FSTMutationBatch *)other; + return self.batchID == otherBatch.batchID && + [self.localWriteTime isEqual:otherBatch.localWriteTime] && + objc::Equals(_baseMutations, otherBatch.baseMutations) && + objc::Equals(_mutations, otherBatch.mutations); +} + +- (NSUInteger)hash { + NSUInteger result = (NSUInteger)self.batchID; + result = result * 31 + self.localWriteTime.hash; + for (FSTMutation *mutation : _baseMutations) { + result = result * 31 + [mutation hash]; + } + for (FSTMutation *mutation : _mutations) { + result = result * 31 + [mutation hash]; + } + return result; +} + +- (NSString *)description { + return + [NSString stringWithFormat:@"", + self.batchID, self.localWriteTime, objc::Description(_mutations)]; +} + +- (FSTMaybeDocument *_Nullable)applyToRemoteDocument:(FSTMaybeDocument *_Nullable)maybeDoc + documentKey:(const DocumentKey &)documentKey + mutationBatchResult: + (FSTMutationBatchResult *_Nullable)mutationBatchResult { + HARD_ASSERT(!maybeDoc || maybeDoc.key == documentKey, + "applyTo: key %s doesn't match maybeDoc key %s", documentKey.ToString(), + maybeDoc.key.ToString()); + + HARD_ASSERT(mutationBatchResult.mutationResults.size() == _mutations.size(), + "Mismatch between mutations length (%s) and results length (%s)", _mutations.size(), + mutationBatchResult.mutationResults.size()); + + for (size_t i = 0; i < _mutations.size(); i++) { + FSTMutation *mutation = _mutations[i]; + FSTMutationResult *mutationResult = mutationBatchResult.mutationResults[i]; + if (mutation.key == documentKey) { + maybeDoc = [mutation applyToRemoteDocument:maybeDoc mutationResult:mutationResult]; + } + } + return maybeDoc; +} + +- (FSTMaybeDocument *_Nullable)applyToLocalDocument:(FSTMaybeDocument *_Nullable)maybeDoc + documentKey:(const DocumentKey &)documentKey { + HARD_ASSERT(!maybeDoc || maybeDoc.key == documentKey, + "applyTo: key %s doesn't match maybeDoc key %s", documentKey.ToString(), + maybeDoc.key.ToString()); + + // First, apply the base state. This allows us to apply non-idempotent transform against a + // consistent set of values. + for (FSTMutation *mutation : _baseMutations) { + if (mutation.key == documentKey) { + maybeDoc = [mutation applyToLocalDocument:maybeDoc + baseDocument:maybeDoc + localWriteTime:self.localWriteTime]; + } + } + + FSTMaybeDocument *baseDoc = maybeDoc; + + // Second, apply all user-provided mutations. + for (FSTMutation *mutation : _mutations) { + if (mutation.key == documentKey) { + maybeDoc = [mutation applyToLocalDocument:maybeDoc + baseDocument:baseDoc + localWriteTime:self.localWriteTime]; + } + } + return maybeDoc; +} + +- (MaybeDocumentMap)applyToLocalDocumentSet:(const MaybeDocumentMap &)documentSet { + // TODO(mrschmidt): This implementation is O(n^2). If we iterate through the mutations first (as + // done in `applyToLocalDocument:documentKey:`), we can reduce the complexity to O(n). + + MaybeDocumentMap mutatedDocuments = documentSet; + for (FSTMutation *mutation : _mutations) { + const DocumentKey &key = mutation.key; + auto maybeDocument = mutatedDocuments.find(key); + FSTMaybeDocument *mutatedDocument = [self + applyToLocalDocument:(maybeDocument != mutatedDocuments.end() ? maybeDocument->second : nil) + documentKey:key]; + if (mutatedDocument) { + mutatedDocuments = mutatedDocuments.insert(key, mutatedDocument); + } + } + return mutatedDocuments; +} + +- (DocumentKeySet)keys { + DocumentKeySet set; + for (FSTMutation *mutation : _mutations) { + set = set.insert(mutation.key); + } + return set; +} + +@end + +#pragma mark - FSTMutationBatchResult + +@interface FSTMutationBatchResult () +- (instancetype)initWithBatch:(FSTMutationBatch *)batch + commitVersion:(SnapshotVersion)commitVersion + mutationResults:(std::vector)mutationResults + streamToken:(nullable NSData *)streamToken + docVersions:(DocumentVersionMap)docVersions NS_DESIGNATED_INITIALIZER; +@end + +@implementation FSTMutationBatchResult { + SnapshotVersion _commitVersion; + std::vector _mutationResults; + DocumentVersionMap _docVersions; +} + +- (instancetype)initWithBatch:(FSTMutationBatch *)batch + commitVersion:(SnapshotVersion)commitVersion + mutationResults:(std::vector)mutationResults + streamToken:(nullable NSData *)streamToken + docVersions:(DocumentVersionMap)docVersions { + if (self = [super init]) { + _batch = batch; + _commitVersion = std::move(commitVersion); + _mutationResults = std::move(mutationResults); + _streamToken = streamToken; + _docVersions = std::move(docVersions); + } + return self; +} + +- (const SnapshotVersion &)commitVersion { + return _commitVersion; +} + +- (const std::vector &)mutationResults { + return _mutationResults; +} + +- (const DocumentVersionMap &)docVersions { + return _docVersions; +} + ++ (instancetype)resultWithBatch:(FSTMutationBatch *)batch + commitVersion:(SnapshotVersion)commitVersion + mutationResults:(std::vector)mutationResults + streamToken:(nullable NSData *)streamToken { + HARD_ASSERT(batch.mutations.size() == mutationResults.size(), + "Mutations sent %s must equal results received %s", batch.mutations.size(), + mutationResults.size()); + + DocumentVersionMap docVersions; + std::vector mutations = batch.mutations; + for (size_t i = 0; i < mutations.size(); i++) { + absl::optional version = mutationResults[i].version; + if (!version) { + // deletes don't have a version, so we substitute the commitVersion + // of the entire batch. + version = commitVersion; + } + + docVersions[mutations[i].key] = version.value(); + } + + return [[FSTMutationBatchResult alloc] initWithBatch:batch + commitVersion:std::move(commitVersion) + mutationResults:std::move(mutationResults) + streamToken:streamToken + docVersions:std::move(docVersions)]; +} + +@end +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Public/FIRCollectionReference.h b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Public/FIRCollectionReference.h new file mode 100644 index 0000000..39be000 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Public/FIRCollectionReference.h @@ -0,0 +1,100 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +#import "FIRQuery.h" + +NS_ASSUME_NONNULL_BEGIN + +@class FIRDocumentReference; + +/** + * A `FIRCollectionReference` object can be used for adding documents, getting document references, + * and querying for documents (using the methods inherited from `FIRQuery`). + */ +NS_SWIFT_NAME(CollectionReference) +@interface FIRCollectionReference : FIRQuery + +/** :nodoc: */ +- (id)init __attribute__((unavailable("FIRCollectionReference cannot be created directly."))); + +/** ID of the referenced collection. */ +@property(nonatomic, strong, readonly) NSString *collectionID; + +/** + * For subcollections, `parent` returns the containing `FIRDocumentReference`. For root + * collections, nil is returned. + */ +@property(nonatomic, strong, nullable, readonly) FIRDocumentReference *parent; + +/** + * A string containing the slash-separated path to this this `FIRCollectionReference` (relative to + * the root of the database). + */ +@property(nonatomic, strong, readonly) NSString *path; + +/** + * Returns a FIRDocumentReference pointing to a new document with an auto-generated ID. + * + * @return A FIRDocumentReference pointing to a new document with an auto-generated ID. + */ +- (FIRDocumentReference *)documentWithAutoID NS_SWIFT_NAME(document()); + +/** + * Gets a `FIRDocumentReference` referring to the document at the specified path, relative to this + * collection's own path. + * + * @param documentPath The slash-separated relative path of the document for which to get a + * `FIRDocumentReference`. + * + * @return The `FIRDocumentReference` for the specified document path. + */ +- (FIRDocumentReference *)documentWithPath:(NSString *)documentPath NS_SWIFT_NAME(document(_:)); + +/** + * Add a new document to this collection with the specified data, assigning it a document ID + * automatically. + * + * @param data An `NSDictionary` containing the data for the new document. + * + * @return A `FIRDocumentReference` pointing to the newly created document. + */ +- (FIRDocumentReference *)addDocumentWithData:(NSDictionary *)data + NS_SWIFT_NAME(addDocument(data:)); + +/** + * Add a new document to this collection with the specified data, assigning it a document ID + * automatically. + * + * @param data An `NSDictionary` containing the data for the new document. + * @param completion A block to execute once the document has been successfully written to + * the server. This block will not be called while the client is offline, though local + * changes will be visible immediately. + * + * @return A `FIRDocumentReference` pointing to the newly created document. + */ +// clang-format off +// clang-format breaks the NS_SWIFT_NAME attribute +- (FIRDocumentReference *)addDocumentWithData:(NSDictionary *)data + completion: + (nullable void (^)(NSError *_Nullable error))completion + NS_SWIFT_NAME(addDocument(data:completion:)); +// clang-format on + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Public/FIRDocumentChange.h b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Public/FIRDocumentChange.h new file mode 100644 index 0000000..3e4a012 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Public/FIRDocumentChange.h @@ -0,0 +1,68 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +NS_ASSUME_NONNULL_BEGIN + +@class FIRQueryDocumentSnapshot; + +/** An enumeration of document change types. */ +typedef NS_ENUM(NSInteger, FIRDocumentChangeType) { + /** Indicates a new document was added to the set of documents matching the query. */ + FIRDocumentChangeTypeAdded, + /** Indicates a document within the query was modified. */ + FIRDocumentChangeTypeModified, + /** + * Indicates a document within the query was removed (either deleted or no longer matches + * the query. + */ + FIRDocumentChangeTypeRemoved +} NS_SWIFT_NAME(DocumentChangeType); + +/** + * A `FIRDocumentChange` represents a change to the documents matching a query. It contains the + * document affected and the type of change that occurred (added, modified, or removed). + */ +NS_SWIFT_NAME(DocumentChange) +@interface FIRDocumentChange : NSObject + +/** :nodoc: */ +- (id)init __attribute__((unavailable("FIRDocumentChange cannot be created directly."))); + +/** The type of change that occurred (added, modified, or removed). */ +@property(nonatomic, readonly) FIRDocumentChangeType type; + +/** The document affected by this change. */ +@property(nonatomic, strong, readonly) FIRQueryDocumentSnapshot *document; + +/** + * The index of the changed document in the result set immediately prior to this FIRDocumentChange + * (i.e. supposing that all prior FIRDocumentChange objects have been applied). NSNotFound for + * FIRDocumentChangeTypeAdded events. + */ +@property(nonatomic, readonly) NSUInteger oldIndex; + +/** + * The index of the changed document in the result set immediately after this FIRDocumentChange + * (i.e. supposing that all prior FIRDocumentChange objects and the current FIRDocumentChange object + * have been applied). NSNotFound for FIRDocumentChangeTypeRemoved events. + */ +@property(nonatomic, readonly) NSUInteger newIndex; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Public/FIRDocumentReference.h b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Public/FIRDocumentReference.h new file mode 100644 index 0000000..c110bcd --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Public/FIRDocumentReference.h @@ -0,0 +1,261 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +#import "FIRFirestoreSource.h" +#import "FIRListenerRegistration.h" + +@class FIRCollectionReference; +@class FIRDocumentSnapshot; +@class FIRFirestore; + +NS_ASSUME_NONNULL_BEGIN + +typedef void (^FIRDocumentSnapshotBlock)(FIRDocumentSnapshot *_Nullable snapshot, + NSError *_Nullable error); + +/** + * A `FIRDocumentReference` refers to a document location in a Firestore database and can be + * used to write, read, or listen to the location. The document at the referenced location + * may or may not exist. A `FIRDocumentReference` can also be used to create a + * `FIRCollectionReference` to a subcollection. + */ +NS_SWIFT_NAME(DocumentReference) +@interface FIRDocumentReference : NSObject + +/** :nodoc: */ +- (instancetype)init + __attribute__((unavailable("FIRDocumentReference cannot be created directly."))); + +/** The ID of the document referred to. */ +@property(nonatomic, strong, readonly) NSString *documentID; + +/** A reference to the collection to which this `DocumentReference` belongs. */ +@property(nonatomic, strong, readonly) FIRCollectionReference *parent; + +/** The `FIRFirestore` for the Firestore database (useful for performing transactions, etc.). */ +@property(nonatomic, strong, readonly) FIRFirestore *firestore; + +/** + * A string representing the path of the referenced document (relative to the root of the + * database). + */ +@property(nonatomic, strong, readonly) NSString *path; + +/** + * Gets a `FIRCollectionReference` referring to the collection at the specified + * path, relative to this document. + * + * @param collectionPath The slash-separated relative path of the collection for which to get a + * `FIRCollectionReference`. + * + * @return The `FIRCollectionReference` at the specified _collectionPath_. + */ +- (FIRCollectionReference *)collectionWithPath:(NSString *)collectionPath + NS_SWIFT_NAME(collection(_:)); + +#pragma mark - Writing Data + +/** + * Writes to the document referred to by `FIRDocumentReference`. If the document doesn't yet exist, + * this method creates it and then sets the data. If the document exists, this method overwrites + * the document data with the new values. + * + * @param documentData An `NSDictionary` that contains the fields and data to write to the + * document. + */ +- (void)setData:(NSDictionary *)documentData; + +/** + * Writes to the document referred to by this DocumentReference. If the document does not yet + * exist, it will be created. If you pass `merge:YES`, the provided data will be merged into + * any existing document. + * + * @param documentData An `NSDictionary` that contains the fields and data to write to the + * document. + * @param merge Whether to merge the provided data into any existing document. + */ +- (void)setData:(NSDictionary *)documentData merge:(BOOL)merge; + +/** + * Writes to the document referred to by `document` and only replace the fields + * specified under `mergeFields`. Any field that is not specified in `mergeFields` + * is ignored and remains untouched. If the document doesn't yet exist, + * this method creates it and then sets the data. + * + * It is an error to include a field in `mergeFields` that does not have a corresponding + * value in the `data` dictionary. + * + * @param documentData An `NSDictionary` containing the fields that make up the document + * to be written. + * @param mergeFields An `NSArray` that contains a list of `NSString` or `FIRFieldPath` elements + * specifying which fields to merge. Fields can contain dots to reference nested fields within + * the document. + */ +- (void)setData:(NSDictionary *)documentData mergeFields:(NSArray *)mergeFields; + +/** + * Overwrites the document referred to by this `FIRDocumentReference`. If no document exists, it + * is created. If a document already exists, it is overwritten. + * + * @param documentData An `NSDictionary` containing the fields that make up the document + * to be written. + * @param completion A block to execute once the document has been successfully written to the + * server. This block will not be called while the client is offline, though local + * changes will be visible immediately. + */ +- (void)setData:(NSDictionary *)documentData + completion:(nullable void (^)(NSError *_Nullable error))completion; + +/** + * Writes to the document referred to by this DocumentReference. If the document does not yet + * exist, it will be created. If you pass `merge:YES`, the provided data will be merged into + * any existing document. + * + * @param documentData An `NSDictionary` containing the fields that make up the document + * to be written. + * @param merge Whether to merge the provided data into any existing document. + * @param completion A block to execute once the document has been successfully written to the + * server. This block will not be called while the client is offline, though local + * changes will be visible immediately. + */ +- (void)setData:(NSDictionary *)documentData + merge:(BOOL)merge + completion:(nullable void (^)(NSError *_Nullable error))completion; + +/** + * Writes to the document referred to by `document` and only replace the fields + * specified under `mergeFields`. Any field that is not specified in `mergeFields` + * is ignored and remains untouched. If the document doesn't yet exist, + * this method creates it and then sets the data. + * + * It is an error to include a field in `mergeFields` that does not have a corresponding + * value in the `data` dictionary. + * + * @param documentData An `NSDictionary` containing the fields that make up the document + * to be written. + * @param mergeFields An `NSArray` that contains a list of `NSString` or `FIRFieldPath` elements + * specifying which fields to merge. Fields can contain dots to reference nested fields within + * the document. + * @param completion A block to execute once the document has been successfully written to the + * server. This block will not be called while the client is offline, though local + * changes will be visible immediately. + */ +- (void)setData:(NSDictionary *)documentData + mergeFields:(NSArray *)mergeFields + completion:(nullable void (^)(NSError *_Nullable error))completion; + +/** + * Updates fields in the document referred to by this `FIRDocumentReference`. + * If the document does not exist, the update fails (specify a completion block to be notified). + * + * @param fields An `NSDictionary` containing the fields (expressed as an `NSString` or + * `FIRFieldPath`) and values with which to update the document. + */ +- (void)updateData:(NSDictionary *)fields; + +/** + * Updates fields in the document referred to by this `FIRDocumentReference`. If the document + * does not exist, the update fails and the specified completion block receives an error. + * + * @param fields An `NSDictionary` containing the fields (expressed as an `NSString` or + * `FIRFieldPath`) and values with which to update the document. + * @param completion A block to execute when the update is complete. If the update is successful the + * error parameter will be nil, otherwise it will give an indication of how the update failed. + * This block will only execute when the client is online and the commit has completed against + * the server. The completion handler will not be called when the device is offline, though + * local changes will be visible immediately. + */ +- (void)updateData:(NSDictionary *)fields + completion:(nullable void (^)(NSError *_Nullable error))completion; + +// NOTE: this is named 'deleteDocument' because 'delete' is a keyword in Objective-C++. +/** Deletes the document referred to by this `FIRDocumentReference`. */ +// clang-format off +- (void)deleteDocument NS_SWIFT_NAME(delete()); +// clang-format on + +/** + * Deletes the document referred to by this `FIRDocumentReference`. + * + * @param completion A block to execute once the document has been successfully written to the + * server. This block will not be called while the client is offline, though local + * changes will be visible immediately. + */ +// clang-format off +- (void)deleteDocumentWithCompletion:(nullable void (^)(NSError *_Nullable error))completion + NS_SWIFT_NAME(delete(completion:)); +// clang-format on + +#pragma mark - Retrieving Data + +/** + * Reads the document referenced by this `FIRDocumentReference`. + * + * This method attempts to provide up-to-date data when possible by waiting for + * data from the server, but it may return cached data or fail if you are + * offline and the server cannot be reached. See the + * `getDocument(source:completion:)` method to change this behavior. + * + * @param completion a block to execute once the document has been successfully read. + */ +- (void)getDocumentWithCompletion:(FIRDocumentSnapshotBlock)completion + NS_SWIFT_NAME(getDocument(completion:)); + +/** + * Reads the document referenced by this `FIRDocumentReference`. + * + * @param source indicates whether the results should be fetched from the cache + * only (`Source.cache`), the server only (`Source.server`), or to attempt + * the server and fall back to the cache (`Source.default`). + * @param completion a block to execute once the document has been successfully read. + */ +// clang-format off +- (void)getDocumentWithSource:(FIRFirestoreSource)source + completion:(FIRDocumentSnapshotBlock)completion + NS_SWIFT_NAME(getDocument(source:completion:)); +// clang-format on + +/** + * Attaches a listener for DocumentSnapshot events. + * + * @param listener The listener to attach. + * + * @return A FIRListenerRegistration that can be used to remove this listener. + */ +- (id)addSnapshotListener:(FIRDocumentSnapshotBlock)listener + NS_SWIFT_NAME(addSnapshotListener(_:)); + +/** + * Attaches a listener for DocumentSnapshot events. + * + * @param includeMetadataChanges Whether metadata-only changes (i.e. only + * `FIRDocumentSnapshot.metadata` changed) should trigger snapshot events. + * @param listener The listener to attach. + * + * @return A FIRListenerRegistration that can be used to remove this listener. + */ +// clang-format off +- (id) +addSnapshotListenerWithIncludeMetadataChanges:(BOOL)includeMetadataChanges + listener:(FIRDocumentSnapshotBlock)listener + NS_SWIFT_NAME(addSnapshotListener(includeMetadataChanges:listener:)); +// clang-format on + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Public/FIRDocumentSnapshot.h b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Public/FIRDocumentSnapshot.h new file mode 100644 index 0000000..9a3f61b --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Public/FIRDocumentSnapshot.h @@ -0,0 +1,180 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +@class FIRDocumentReference; +@class FIRSnapshotMetadata; + +NS_ASSUME_NONNULL_BEGIN + +/** + * Controls the return value for server timestamps that have not yet been set to + * their final value. + */ +typedef NS_ENUM(NSInteger, FIRServerTimestampBehavior) { + /** + * Return `NSNull` for `FieldValue.serverTimestamp()` fields that have not yet + * been set to their final value. + */ + FIRServerTimestampBehaviorNone, + + /** + * Return a local estimates for `FieldValue.serverTimestamp()` + * fields that have not yet been set to their final value. This estimate will + * likely differ from the final value and may cause these pending values to + * change once the server result becomes available. + */ + FIRServerTimestampBehaviorEstimate, + + /** + * Return the previous value for `FieldValue.serverTimestamp()` fields that + * have not yet been set to their final value. + */ + FIRServerTimestampBehaviorPrevious +} NS_SWIFT_NAME(ServerTimestampBehavior); + +/** + * A `FIRDocumentSnapshot` contains data read from a document in your Firestore database. The data + * can be extracted with the `data` property or by using subscript syntax to access a specific + * field. + * + * For a `FIRDocumentSnapshot` that points to a non-existing document, any data access will return + * `nil`. You can use the `exists` property to explicitly verify a documents existence. + */ +NS_SWIFT_NAME(DocumentSnapshot) +@interface FIRDocumentSnapshot : NSObject + +/** :nodoc: */ +- (instancetype)init + __attribute__((unavailable("FIRDocumentSnapshot cannot be created directly."))); + +/** True if the document exists. */ +@property(nonatomic, assign, readonly) BOOL exists; + +/** A `FIRDocumentReference` to the document location. */ +@property(nonatomic, strong, readonly) FIRDocumentReference *reference; + +/** The ID of the document for which this `FIRDocumentSnapshot` contains data. */ +@property(nonatomic, copy, readonly) NSString *documentID; + +/** Metadata about this snapshot concerning its source and if it has local modifications. */ +@property(nonatomic, strong, readonly) FIRSnapshotMetadata *metadata; + +/** + * Retrieves all fields in the document as an `NSDictionary`. Returns `nil` if the document doesn't + * exist. + * + * Server-provided timestamps that have not yet been set to their final value will be returned as + * `NSNull`. You can use `dataWithOptions()` to configure this behavior. + * + * @return An `NSDictionary` containing all fields in the document or `nil` if the document doesn't + * exist. + */ +- (nullable NSDictionary *)data; + +/** + * Retrieves all fields in the document as a `Dictionary`. Returns `nil` if the document doesn't + * exist. + * + * @param serverTimestampBehavior Configures how server timestamps that have not yet been set to + * their final value are returned from the snapshot. + * @return A `Dictionary` containing all fields in the document or `nil` if the document doesn't + * exist. + */ +- (nullable NSDictionary *)dataWithServerTimestampBehavior: + (FIRServerTimestampBehavior)serverTimestampBehavior; + +/** + * Retrieves a specific field from the document. Returns `nil` if the document or the field doesn't + * exist. + * + * The timestamps that have not yet been set to their final value will be returned as `NSNull`. The + * can use `get(_:options:)` to configure this behavior. + * + * @param field The field to retrieve. + * @return The value contained in the field or `nil` if the document or field doesn't exist. + */ +- (nullable id)valueForField:(id)field NS_SWIFT_NAME(get(_:)); + +/** + * Retrieves a specific field from the document. Returns `nil` if the document or the field doesn't + * exist. + * + * The timestamps that have not yet been set to their final value will be returned as `NSNull`. The + * can use `get(_:options:)` to configure this behavior. + * + * @param field The field to retrieve. + * @param serverTimestampBehavior Configures how server timestamps that have not yet been set to + * their final value are returned from the snapshot. + * @return The value contained in the field or `nil` if the document or field doesn't exist. + */ +// clang-format off +- (nullable id)valueForField:(id)field + serverTimestampBehavior:(FIRServerTimestampBehavior)serverTimestampBehavior + NS_SWIFT_NAME(get(_:serverTimestampBehavior:)); +// clang-format on + +/** + * Retrieves a specific field from the document. + * + * @param key The field to retrieve. + * + * @return The value contained in the field or `nil` if the document or field doesn't exist. + */ +- (nullable id)objectForKeyedSubscript:(id)key; + +@end + +/** + * A `FIRQueryDocumentSnapshot` contains data read from a document in your Firestore database as + * part of a query. The document is guaranteed to exist and its data can be extracted with the + * `data` property or by using subscript syntax to access a specific field. + * + * A `FIRQueryDocumentSnapshot` offers the same API surface as a `FIRDocumentSnapshot`. As + * deleted documents are not returned from queries, its `exists` property will always be true and + * `data:` will never return `nil`. + */ +NS_SWIFT_NAME(QueryDocumentSnapshot) +@interface FIRQueryDocumentSnapshot : FIRDocumentSnapshot + +/** :nodoc: */ +- (instancetype)init + __attribute__((unavailable("FIRQueryDocumentSnapshot cannot be created directly."))); + +/** + * Retrieves all fields in the document as an `NSDictionary`. + * + * Server-provided timestamps that have not yet been set to their final value will be returned as + * `NSNull`. You can use `dataWithOptions()` to configure this behavior. + * + * @return An `NSDictionary` containing all fields in the document. + */ +- (NSDictionary *)data; + +/** + * Retrieves all fields in the document as a `Dictionary`. + * + * @param serverTimestampBehavior Configures how server timestamps that have not yet been set to + * their final value are returned from the snapshot. + * @return A `Dictionary` containing all fields in the document. + */ +- (NSDictionary *)dataWithServerTimestampBehavior: + (FIRServerTimestampBehavior)serverTimestampBehavior; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Public/FIRFieldPath.h b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Public/FIRFieldPath.h new file mode 100644 index 0000000..3445f2e --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Public/FIRFieldPath.h @@ -0,0 +1,48 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * A `FieldPath` refers to a field in a document. The path may consist of a single field name + * (referring to a top level field in the document), or a list of field names (referring to a nested + * field in the document). + */ +NS_SWIFT_NAME(FieldPath) +@interface FIRFieldPath : NSObject + +- (instancetype)init NS_UNAVAILABLE; + +/** + * Creates a `FieldPath` from the provided field names. If more than one field name is provided, the + * path will point to a nested field in a document. + * + * @param fieldNames A list of field names. + * @return A `FieldPath` that points to a field location in a document. + */ +- (instancetype)initWithFields:(NSArray *)fieldNames NS_SWIFT_NAME(init(_:)); + +/** + * A special sentinel `FieldPath` to refer to the ID of a document. It can be used in queries to + * sort or filter by the document ID. + */ ++ (instancetype)documentID; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Public/FIRFieldValue.h b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Public/FIRFieldValue.h new file mode 100644 index 0000000..24d1007 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Public/FIRFieldValue.h @@ -0,0 +1,95 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * Sentinel values that can be used when writing document fields with setData() or updateData(). + */ +NS_SWIFT_NAME(FieldValue) +@interface FIRFieldValue : NSObject + +/** :nodoc: */ +- (instancetype)init NS_UNAVAILABLE; + +/** Used with updateData() to mark a field for deletion. */ +// clang-format off ++ (instancetype)fieldValueForDelete NS_SWIFT_NAME(delete()); +// clang-format on + +/** + * Used with setData() or updateData() to include a server-generated timestamp in the written + * data. + */ ++ (instancetype)fieldValueForServerTimestamp NS_SWIFT_NAME(serverTimestamp()); + +/** + * Returns a special value that can be used with setData() or updateData() that tells the server to + * union the given elements with any array value that already exists on the server. Each + * specified element that doesn't already exist in the array will be added to the end. If the + * field being modified is not already an array it will be overwritten with an array containing + * exactly the specified elements. + * + * @param elements The elements to union into the array. + * @return The FieldValue sentinel for use in a call to setData() or updateData(). + */ ++ (instancetype)fieldValueForArrayUnion:(NSArray *)elements NS_SWIFT_NAME(arrayUnion(_:)); + +/** + * Returns a special value that can be used with setData() or updateData() that tells the server to + * remove the given elements from any array value that already exists on the server. All + * instances of each element specified will be removed from the array. If the field being + * modified is not already an array it will be overwritten with an empty array. + * + * @param elements The elements to remove from the array. + * @return The FieldValue sentinel for use in a call to setData() or updateData(). + */ ++ (instancetype)fieldValueForArrayRemove:(NSArray *)elements NS_SWIFT_NAME(arrayRemove(_:)); + +/** + * Returns a special value that can be used with setData() or updateData() that tells the server to + * increment the field's current value by the given value. + * + * If the current value is an integer or a double, both the current and the given value will be + * interpreted as doubles and all arithmetic will follow IEEE 754 semantics. Otherwise, the + * transformation will set the field to the given value. + * + * @param d The double value to increment by. + * @return The FieldValue sentinel for use in a call to setData() or update(). + */ ++ (instancetype)fieldValueForDoubleIncrement:(double)d NS_SWIFT_NAME(increment(_:)); + +/** + * Returns a special value that can be used with setData() or updateData() that tells the server to + * increment the field's current value by the given value. + * + * If the current field value is an integer, possible integer overflows are resolved to LONG_MAX or + * LONG_MIN. If the current field value is a double, both values will be interpreted as doubles and + * the arithmetic will follow IEEE 754 semantics. + * + * If field is not an integer or double, or if the field does not yet exist, the transformation + * will set the field to the given value. + * + * @param l The integer value to increment by. + * @return The FieldValue sentinel for use in a call to setData() or updateData(). + */ ++ (instancetype)fieldValueForIntegerIncrement:(int64_t)l NS_SWIFT_NAME(increment(_:)); + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Public/FIRFirestore.h b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Public/FIRFirestore.h new file mode 100644 index 0000000..cd9302c --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Public/FIRFirestore.h @@ -0,0 +1,163 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +@class FIRApp; +@class FIRCollectionReference; +@class FIRDocumentReference; +@class FIRFirestoreSettings; +@class FIRQuery; +@class FIRTransaction; +@class FIRWriteBatch; + +NS_ASSUME_NONNULL_BEGIN + +/** + * `FIRFirestore` represents a Firestore Database and is the entry point for all Firestore + * operations. + */ +NS_SWIFT_NAME(Firestore) +@interface FIRFirestore : NSObject + +#pragma mark - Initializing +/** :nodoc: */ +- (instancetype)init __attribute__((unavailable("Use a static constructor method."))); + +/** + * Creates, caches, and returns a `FIRFirestore` using the default `FIRApp`. Each subsequent + * invocation returns the same `FIRFirestore` object. + * + * @return The `FIRFirestore` instance. + */ ++ (instancetype)firestore NS_SWIFT_NAME(firestore()); + +/** + * Creates, caches, and returns a `FIRFirestore` object for the specified _app_. Each subsequent + * invocation returns the same `FIRFirestore` object. + * + * @param app The `FIRApp` instance to use for authentication and as a source of the Google Cloud + * Project ID for your Firestore Database. If you want the default instance, you should explicitly + * set it to `[FIRApp defaultApp]`. + * + * @return The `FIRFirestore` instance. + */ ++ (instancetype)firestoreForApp:(FIRApp *)app NS_SWIFT_NAME(firestore(app:)); + +/** + * Custom settings used to configure this `FIRFirestore` object. + */ +@property(nonatomic, copy) FIRFirestoreSettings *settings; + +/** + * The Firebase App associated with this Firestore instance. + */ +@property(strong, nonatomic, readonly) FIRApp *app; + +#pragma mark - Collections and Documents + +/** + * Gets a `FIRCollectionReference` referring to the collection at the specified path within the + * database. + * + * @param collectionPath The slash-separated path of the collection for which to get a + * `FIRCollectionReference`. + * + * @return The `FIRCollectionReference` at the specified _collectionPath_. + */ +- (FIRCollectionReference *)collectionWithPath:(NSString *)collectionPath + NS_SWIFT_NAME(collection(_:)); + +/** + * Gets a `FIRDocumentReference` referring to the document at the specified path within the + * database. + * + * @param documentPath The slash-separated path of the document for which to get a + * `FIRDocumentReference`. + * + * @return The `FIRDocumentReference` for the specified _documentPath_. + */ +- (FIRDocumentReference *)documentWithPath:(NSString *)documentPath NS_SWIFT_NAME(document(_:)); + +#pragma mark - Transactions and Write Batches + +/** + * Executes the given updateBlock and then attempts to commit the changes applied within an atomic + * transaction. + * + * In the updateBlock, a set of reads and writes can be performed atomically using the + * `FIRTransaction` object passed to the block. After the updateBlock is run, Firestore will attempt + * to apply the changes to the server. If any of the data read has been modified outside of this + * transaction since being read, then the transaction will be retried by executing the updateBlock + * again. If the transaction still fails after 5 retries, then the transaction will fail. + * + * Since the updateBlock may be executed multiple times, it should avoiding doing anything that + * would cause side effects. + * + * Any value maybe be returned from the updateBlock. If the transaction is successfully committed, + * then the completion block will be passed that value. The updateBlock also has an `NSError` out + * parameter. If this is set, then the transaction will not attempt to commit, and the given error + * will be passed to the completion block. + * + * The `FIRTransaction` object passed to the updateBlock contains methods for accessing documents + * and collections. Unlike other firestore access, data accessed with the transaction will not + * reflect local changes that have not been committed. For this reason, it is required that all + * reads are performed before any writes. Transactions must be performed while online. Otherwise, + * reads will fail, the final commit will fail, and the completion block will return an error. + * + * @param updateBlock The block to execute within the transaction context. + * @param completion The block to call with the result or error of the transaction. This + * block will run even if the client is offline, unless the process is killed. + */ +- (void)runTransactionWithBlock:(id _Nullable (^)(FIRTransaction *, NSError **))updateBlock + completion:(void (^)(id _Nullable result, NSError *_Nullable error))completion; + +/** + * Creates a write batch, used for performing multiple writes as a single + * atomic operation. + * + * Unlike transactions, write batches are persisted offline and therefore are preferable when you + * don't need to condition your writes on read data. + */ +- (FIRWriteBatch *)batch; + +#pragma mark - Logging + +/** Enables or disables logging from the Firestore client. */ ++ (void)enableLogging:(BOOL)logging + DEPRECATED_MSG_ATTRIBUTE("Use FirebaseConfiguration.shared.setLoggerLevel(.debug) to enable " + "logging."); + +#pragma mark - Network + +/** + * Re-enables usage of the network by this Firestore instance after a prior call to + * `disableNetworkWithCompletion`. Completion block, if provided, will be called once network uasge + * has been enabled. + */ +- (void)enableNetworkWithCompletion:(nullable void (^)(NSError *_Nullable error))completion; + +/** + * Disables usage of the network by this Firestore instance. It can be re-enabled by via + * `enableNetworkWithCompletion`. While the network is disabled, any snapshot listeners or get calls + * will return results from cache and any write operations will be queued until the network is + * restored. The completion block, if provided, will be called once network usage has been disabled. + */ +- (void)disableNetworkWithCompletion:(nullable void (^)(NSError *_Nullable error))completion; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Public/FIRFirestoreErrors.h b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Public/FIRFirestoreErrors.h new file mode 100644 index 0000000..968391c --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Public/FIRFirestoreErrors.h @@ -0,0 +1,103 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** The Cloud Firestore error domain. */ +FOUNDATION_EXPORT NSString *const FIRFirestoreErrorDomain NS_SWIFT_NAME(FirestoreErrorDomain); + +/** Error codes used by Cloud Firestore. */ +typedef NS_ENUM(NSInteger, FIRFirestoreErrorCode) { + /** + * The operation completed successfully. NSError objects will never have a code with this value. + */ + FIRFirestoreErrorCodeOK = 0, + + /** The operation was cancelled (typically by the caller). */ + FIRFirestoreErrorCodeCancelled = 1, + + /** Unknown error or an error from a different error domain. */ + FIRFirestoreErrorCodeUnknown = 2, + + /** + * Client specified an invalid argument. Note that this differs from FailedPrecondition. + * InvalidArgument indicates arguments that are problematic regardless of the state of the + * system (e.g., an invalid field name). + */ + FIRFirestoreErrorCodeInvalidArgument = 3, + + /** + * Deadline expired before operation could complete. For operations that change the state of the + * system, this error may be returned even if the operation has completed successfully. For + * example, a successful response from a server could have been delayed long enough for the + * deadline to expire. + */ + FIRFirestoreErrorCodeDeadlineExceeded = 4, + + /** Some requested document was not found. */ + FIRFirestoreErrorCodeNotFound = 5, + + /** Some document that we attempted to create already exists. */ + FIRFirestoreErrorCodeAlreadyExists = 6, + + /** The caller does not have permission to execute the specified operation. */ + FIRFirestoreErrorCodePermissionDenied = 7, + + /** + * Some resource has been exhausted, perhaps a per-user quota, or perhaps the entire file system + * is out of space. + */ + FIRFirestoreErrorCodeResourceExhausted = 8, + + /** + * Operation was rejected because the system is not in a state required for the operation's + * execution. + */ + FIRFirestoreErrorCodeFailedPrecondition = 9, + + /** + * The operation was aborted, typically due to a concurrency issue like transaction aborts, etc. + */ + FIRFirestoreErrorCodeAborted = 10, + + /** Operation was attempted past the valid range. */ + FIRFirestoreErrorCodeOutOfRange = 11, + + /** Operation is not implemented or not supported/enabled. */ + FIRFirestoreErrorCodeUnimplemented = 12, + + /** + * Internal errors. Means some invariants expected by underlying system has been broken. If you + * see one of these errors, something is very broken. + */ + FIRFirestoreErrorCodeInternal = 13, + + /** + * The service is currently unavailable. This is a most likely a transient condition and may be + * corrected by retrying with a backoff. + */ + FIRFirestoreErrorCodeUnavailable = 14, + + /** Unrecoverable data loss or corruption. */ + FIRFirestoreErrorCodeDataLoss = 15, + + /** The request does not have valid authentication credentials for the operation. */ + FIRFirestoreErrorCodeUnauthenticated = 16 +} NS_SWIFT_NAME(FirestoreErrorCode); + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Public/FIRFirestoreSettings.h b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Public/FIRFirestoreSettings.h new file mode 100644 index 0000000..13ef56c --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Public/FIRFirestoreSettings.h @@ -0,0 +1,81 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** Used to set on-disk cache size to unlimited. Garbage collection will not run. */ +extern const int64_t kFIRFirestoreCacheSizeUnlimited NS_SWIFT_NAME(FirestoreCacheSizeUnlimited); + +/** Settings used to configure a `FIRFirestore` instance. */ +NS_SWIFT_NAME(FirestoreSettings) +@interface FIRFirestoreSettings : NSObject + +/** + * Creates and returns an empty `FIRFirestoreSettings` object. + * + * @return The created `FIRFirestoreSettings` object. + */ +- (instancetype)init NS_DESIGNATED_INITIALIZER; + +/** The hostname to connect to. */ +@property(nonatomic, copy) NSString *host; + +/** Whether to use SSL when connecting. */ +@property(nonatomic, getter=isSSLEnabled) BOOL sslEnabled; + +/** + * A dispatch queue to be used to execute all completion handlers and event handlers. By default, + * the main queue is used. + */ +@property(nonatomic, strong) dispatch_queue_t dispatchQueue; + +/** Set to false to disable local persistent storage. */ +@property(nonatomic, getter=isPersistenceEnabled) BOOL persistenceEnabled; + +/** + * Specifies whether to use FIRTimestamps for timestamp fields in FIRDocumentSnapshots. This is + * now enabled by default and should not be disabled. + * + * Previously, Firestore returned timestamp fields as NSDate but NSDate is implemented as a double + * which loses precision and causes unexpected behavior when using a timestamp from a snapshot as a + * part of a subsequent query. + * + * So now Firestore returns FIRTimestamp values instead of NSDate, avoiding this kind of problem. + * + * To opt into the old behavior of returning NSDate objects, you can temporarily set + * areTimestampsInSnapshotsEnabled to false. + * + * @deprecated This setting now defaults to true and will be removed in a future release. If you are + * already setting it to true, just remove the setting. If you are setting it to false, you should + * update your code to expect FIRTimestamp objects instead of NSDate and then remove the setting. + */ +@property(nonatomic, getter=areTimestampsInSnapshotsEnabled) BOOL timestampsInSnapshotsEnabled + __attribute__((deprecated)); + +/** + * Sets the cache size threshold above which the SDK will attempt to collect least-recently-used + * documents. The size is not a guarantee that the cache will stay below that size, only that if + * the cache exceeds the given size, cleanup will be attempted. Cannot be set lower than 1MB. + * + * Set to kFIRFirestoreCacheSizeUnlimited to disable garbage collection entirely. + */ +@property(nonatomic, assign) int64_t cacheSizeBytes; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Public/FIRFirestoreSource.h b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Public/FIRFirestoreSource.h new file mode 100644 index 0000000..c133747 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Public/FIRFirestoreSource.h @@ -0,0 +1,48 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#import + +/** + * An enum that configures the behavior of `DocumentReference.getDocument()` and + * `Query.getDocuments()`. By providing a source enum the `getDocument[s]` + * methods can be configured to fetch results only from the server, only from + * the local cache, or attempt to fetch results from the server and fall back to + * the cache (which is the default). + * + * Setting the source to `Source.default` causes Firestore to try to retrieve an + * up-to-date (server-retrieved) snapshot, but fall back to returning cached + * data if the server can't be reached. + * + * Setting the source to `Source.server` causes Firestore to avoid the cache, + * generating an error if the server cannot be reached. Note that the cache will + * still be updated if the server request succeeds. Also note that + * latency-compensation still takes effect, so any pending write operations will + * be visible in the returned data (merged into the server-provided data). + * + * Setting the source to `Source.cache` causes Firestore to immediately return a + * value from the cache, ignoring the server completely (implying that the + * returned value may be stale with respect to the value on the server). If + * there is no data in the cache to satisfy the `getDocument[s]` call, + * `DocumentReference.getDocument()` will return an error and + * `QuerySnapshot.getDocuments()` will return an empty `QuerySnapshot` with no + * documents. + */ +typedef NS_ENUM(NSUInteger, FIRFirestoreSource) { + FIRFirestoreSourceDefault, + FIRFirestoreSourceServer, + FIRFirestoreSourceCache +} NS_SWIFT_NAME(FirestoreSource); diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Public/FIRGeoPoint.h b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Public/FIRGeoPoint.h new file mode 100644 index 0000000..290b2b4 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Public/FIRGeoPoint.h @@ -0,0 +1,47 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * An immutable object representing a geographical point in Firestore. The point is represented as + * a latitude/longitude pair. + * + * Latitude values are in the range of [-90, 90]. + * Longitude values are in the range of [-180, 180]. + */ +NS_SWIFT_NAME(GeoPoint) +@interface FIRGeoPoint : NSObject + +/** :nodoc: */ +- (instancetype)init NS_UNAVAILABLE; + +/** + * Creates a `GeoPoint` from the provided latitude and longitude degrees. + * @param latitude The latitude as number between -90 and 90. + * @param longitude The longitude as number between -180 and 180. + */ +- (instancetype)initWithLatitude:(double)latitude + longitude:(double)longitude NS_DESIGNATED_INITIALIZER; + +@property(nonatomic, readonly) double latitude; +@property(nonatomic, readonly) double longitude; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Public/FIRListenerRegistration.h b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Public/FIRListenerRegistration.h new file mode 100644 index 0000000..c3a16cd --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Public/FIRListenerRegistration.h @@ -0,0 +1,33 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** Represents a listener that can be removed by calling remove. */ +NS_SWIFT_NAME(ListenerRegistration) +@protocol FIRListenerRegistration + +/** + * Removes the listener being tracked by this FIRListenerRegistration. After the initial call, + * subsequent calls have no effect. + */ +- (void)remove; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Public/FIRQuery.h b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Public/FIRQuery.h new file mode 100644 index 0000000..436c185 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Public/FIRQuery.h @@ -0,0 +1,439 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +#import "FIRFirestoreSource.h" +#import "FIRListenerRegistration.h" + +@class FIRFieldPath; +@class FIRFirestore; +@class FIRQuerySnapshot; +@class FIRDocumentSnapshot; + +NS_ASSUME_NONNULL_BEGIN + +typedef void (^FIRQuerySnapshotBlock)(FIRQuerySnapshot *_Nullable snapshot, + NSError *_Nullable error); + +/** + * A `FIRQuery` refers to a Query which you can read or listen to. You can also construct + * refined `FIRQuery` objects by adding filters and ordering. + */ +NS_SWIFT_NAME(Query) +@interface FIRQuery : NSObject +/** :nodoc: */ +- (id)init __attribute__((unavailable("FIRQuery cannot be created directly."))); + +/** The `FIRFirestore` for the Firestore database (useful for performing transactions, etc.). */ +@property(nonatomic, strong, readonly) FIRFirestore *firestore; + +#pragma mark - Retrieving Data +/** + * Reads the documents matching this query. + * + * This method attempts to provide up-to-date data when possible by waiting for + * data from the server, but it may return cached data or fail if you are + * offline and the server cannot be reached. See the + * `getDocuments(source:completion:)` method to change this behavior. + * + * @param completion a block to execute once the documents have been successfully read. + * documentSet will be `nil` only if error is `non-nil`. + */ +- (void)getDocumentsWithCompletion:(FIRQuerySnapshotBlock)completion + NS_SWIFT_NAME(getDocuments(completion:)); + +/** + * Reads the documents matching this query. + * + * @param source indicates whether the results should be fetched from the cache + * only (`Source.cache`), the server only (`Source.server`), or to attempt + * the server and fall back to the cache (`Source.default`). + * @param completion a block to execute once the documents have been successfully read. + * documentSet will be `nil` only if error is `non-nil`. + */ +// clang-format off +- (void)getDocumentsWithSource:(FIRFirestoreSource)source + completion:(FIRQuerySnapshotBlock)completion + NS_SWIFT_NAME(getDocuments(source:completion:)); +// clang-format on + +/** + * Attaches a listener for QuerySnapshot events. + * + * @param listener The listener to attach. + * + * @return A FIRListenerRegistration that can be used to remove this listener. + */ +- (id)addSnapshotListener:(FIRQuerySnapshotBlock)listener + NS_SWIFT_NAME(addSnapshotListener(_:)); + +/** + * Attaches a listener for QuerySnapshot events. + * + * @param includeMetadataChanges Whether metadata-only changes (i.e. only + * `FIRDocumentSnapshot.metadata` changed) should trigger snapshot events. + * @param listener The listener to attach. + * + * @return A FIRListenerRegistration that can be used to remove this listener. + */ +// clang-format off +- (id) +addSnapshotListenerWithIncludeMetadataChanges:(BOOL)includeMetadataChanges + listener:(FIRQuerySnapshotBlock)listener + NS_SWIFT_NAME(addSnapshotListener(includeMetadataChanges:listener:)); +// clang-format on + +#pragma mark - Filtering Data +/** + * Creates and returns a new `FIRQuery` with the additional filter that documents must + * contain the specified field and the value must be equal to the specified value. + * + * @param field The name of the field to compare. + * @param value The value the field must be equal to. + * + * @return The created `FIRQuery`. + */ +// clang-format off +- (FIRQuery *)queryWhereField:(NSString *)field + isEqualTo:(id)value NS_SWIFT_NAME(whereField(_:isEqualTo:)); +// clang-format on + +/** + * Creates and returns a new `FIRQuery` with the additional filter that documents must + * contain the specified field and the value must be equal to the specified value. + * + * @param path The path of the field to compare. + * @param value The value the field must be equal to. + * + * @return The created `FIRQuery`. + */ +// clang-format off +- (FIRQuery *)queryWhereFieldPath:(FIRFieldPath *)path + isEqualTo:(id)value NS_SWIFT_NAME(whereField(_:isEqualTo:)); +// clang-format on + +/** + * Creates and returns a new `FIRQuery` with the additional filter that documents must + * contain the specified field and the value must be less than the specified value. + * + * @param field The name of the field to compare. + * @param value The value the field must be less than. + * + * @return The created `FIRQuery`. + */ +// clang-format off +- (FIRQuery *)queryWhereField:(NSString *)field + isLessThan:(id)value NS_SWIFT_NAME(whereField(_:isLessThan:)); +// clang-format on + +/** + * Creates and returns a new `FIRQuery` with the additional filter that documents must + * contain the specified field and the value must be less than the specified value. + * + * @param path The path of the field to compare. + * @param value The value the field must be less than. + * + * @return The created `FIRQuery`. + */ +// clang-format off +- (FIRQuery *)queryWhereFieldPath:(FIRFieldPath *)path + isLessThan:(id)value NS_SWIFT_NAME(whereField(_:isLessThan:)); +// clang-format on + +/** + * Creates and returns a new `FIRQuery` with the additional filter that documents must + * contain the specified field and the value must be less than or equal to the specified value. + * + * @param field The name of the field to compare + * @param value The value the field must be less than or equal to. + * + * @return The created `FIRQuery`. + */ +// clang-format off +- (FIRQuery *)queryWhereField:(NSString *)field + isLessThanOrEqualTo:(id)value NS_SWIFT_NAME(whereField(_:isLessThanOrEqualTo:)); +// clang-format on + +/** + * Creates and returns a new `FIRQuery` with the additional filter that documents must + * contain the specified field and the value must be less than or equal to the specified value. + * + * @param path The path of the field to compare + * @param value The value the field must be less than or equal to. + * + * @return The created `FIRQuery`. + */ +// clang-format off +- (FIRQuery *)queryWhereFieldPath:(FIRFieldPath *)path + isLessThanOrEqualTo:(id)value NS_SWIFT_NAME(whereField(_:isLessThanOrEqualTo:)); +// clang-format on + +/** + * Creates and returns a new `FIRQuery` with the additional filter that documents must + * contain the specified field and the value must greater than the specified value. + * + * @param field The name of the field to compare + * @param value The value the field must be greater than. + * + * @return The created `FIRQuery`. + */ +// clang-format off +- (FIRQuery *)queryWhereField:(NSString *)field + isGreaterThan:(id)value NS_SWIFT_NAME(whereField(_:isGreaterThan:)); +// clang-format on + +/** + * Creates and returns a new `FIRQuery` with the additional filter that documents must + * contain the specified field and the value must greater than the specified value. + * + * @param path The path of the field to compare + * @param value The value the field must be greater than. + * + * @return The created `FIRQuery`. + */ +// clang-format off +- (FIRQuery *)queryWhereFieldPath:(FIRFieldPath *)path + isGreaterThan:(id)value NS_SWIFT_NAME(whereField(_:isGreaterThan:)); +// clang-format on + +/** + * Creates and returns a new `FIRQuery` with the additional filter that documents must + * contain the specified field and the value must be greater than or equal to the specified value. + * + * @param field The name of the field to compare + * @param value The value the field must be greater than. + * + * @return The created `FIRQuery`. + */ +// clang-format off +- (FIRQuery *)queryWhereField:(NSString *)field + isGreaterThanOrEqualTo:(id)value NS_SWIFT_NAME(whereField(_:isGreaterThanOrEqualTo:)); +// clang-format on + +/** + * Creates and returns a new `FIRQuery` with the additional filter that documents must + * contain the specified field and the value must be greater than or equal to the specified value. + * + * @param path The path of the field to compare + * @param value The value the field must be greater than. + * + * @return The created `FIRQuery`. + */ +// clang-format off +- (FIRQuery *)queryWhereFieldPath:(FIRFieldPath *)path + isGreaterThanOrEqualTo:(id)value NS_SWIFT_NAME(whereField(_:isGreaterThanOrEqualTo:)); +// clang-format on + +/** + * Creates and returns a new `FIRQuery` with the additional filter that documents must contain + * the specified field, it must be an array, and the array must contain the provided value. + * + * A query can have only one arrayContains filter. + * + * @param field The name of the field containing an array to search + * @param value The value that must be contained in the array + * + * @return The created `FIRQuery`. + */ +// clang-format off +- (FIRQuery *)queryWhereField:(NSString *)field + arrayContains:(id)value NS_SWIFT_NAME(whereField(_:arrayContains:)); +// clang-format on + +/** + * Creates and returns a new `FIRQuery` with the additional filter that documents must contain + * the specified field, it must be an array, and the array must contain the provided value. + * + * A query can have only one arrayContains filter. + * + * @param path The path of the field containing an array to search + * @param value The value that must be contained in the array + * + * @return The created `FIRQuery`. + */ +// clang-format off +- (FIRQuery *)queryWhereFieldPath:(FIRFieldPath *)path + arrayContains:(id)value NS_SWIFT_NAME(whereField(_:arrayContains:)); +// clang-format on + +/** + * Creates and returns a new `FIRQuery` with the additional filter that documents must + * satisfy the specified predicate. + * + * @param predicate The predicate the document must satisfy. Can be either comparison + * or compound of comparison. In particular, block-based predicate is not supported. + * + * @return The created `FIRQuery`. + */ +// clang-format off +- (FIRQuery *)queryFilteredUsingPredicate:(NSPredicate *)predicate NS_SWIFT_NAME(filter(using:)); +// clang-format on + +#pragma mark - Sorting Data +/** + * Creates and returns a new `FIRQuery` that's additionally sorted by the specified field. + * + * @param field The field to sort by. + * + * @return The created `FIRQuery`. + */ +- (FIRQuery *)queryOrderedByField:(NSString *)field NS_SWIFT_NAME(order(by:)); + +/** + * Creates and returns a new `FIRQuery` that's additionally sorted by the specified field. + * + * @param path The field to sort by. + * + * @return The created `FIRQuery`. + */ +- (FIRQuery *)queryOrderedByFieldPath:(FIRFieldPath *)path NS_SWIFT_NAME(order(by:)); + +/** + * Creates and returns a new `FIRQuery` that's additionally sorted by the specified field, + * optionally in descending order instead of ascending. + * + * @param field The field to sort by. + * @param descending Whether to sort descending. + * + * @return The created `FIRQuery`. + */ +// clang-format off +- (FIRQuery *)queryOrderedByField:(NSString *)field + descending:(BOOL)descending NS_SWIFT_NAME(order(by:descending:)); +// clang-format on + +/** + * Creates and returns a new `FIRQuery` that's additionally sorted by the specified field, + * optionally in descending order instead of ascending. + * + * @param path The field to sort by. + * @param descending Whether to sort descending. + * + * @return The created `FIRQuery`. + */ +// clang-format off +- (FIRQuery *)queryOrderedByFieldPath:(FIRFieldPath *)path + descending:(BOOL)descending NS_SWIFT_NAME(order(by:descending:)); +// clang-format on + +#pragma mark - Limiting Data +/** + * Creates and returns a new `FIRQuery` that's additionally limited to only return up to + * the specified number of documents. + * + * @param limit The maximum number of items to return. + * + * @return The created `FIRQuery`. + */ +- (FIRQuery *)queryLimitedTo:(NSInteger)limit NS_SWIFT_NAME(limit(to:)); + +#pragma mark - Choosing Endpoints +/** + * Creates and returns a new `FIRQuery` that starts at the provided document (inclusive). The + * starting position is relative to the order of the query. The document must contain all of the + * fields provided in the orderBy of this query. + * + * @param document The snapshot of the document to start at. + * + * @return The created `FIRQuery`. + */ +- (FIRQuery *)queryStartingAtDocument:(FIRDocumentSnapshot *)document + NS_SWIFT_NAME(start(atDocument:)); + +/** + * Creates and returns a new `FIRQuery` that starts at the provided fields relative to the order of + * the query. The order of the field values must match the order of the order by clauses of the + * query. + * + * @param fieldValues The field values to start this query at, in order of the query's order by. + * + * @return The created `FIRQuery`. + */ +- (FIRQuery *)queryStartingAtValues:(NSArray *)fieldValues NS_SWIFT_NAME(start(at:)); + +/** + * Creates and returns a new `FIRQuery` that starts after the provided document (exclusive). The + * starting position is relative to the order of the query. The document must contain all of the + * fields provided in the orderBy of this query. + * + * @param document The snapshot of the document to start after. + * + * @return The created `FIRQuery`. + */ +- (FIRQuery *)queryStartingAfterDocument:(FIRDocumentSnapshot *)document + NS_SWIFT_NAME(start(afterDocument:)); + +/** + * Creates and returns a new `FIRQuery` that starts after the provided fields relative to the order + * of the query. The order of the field values must match the order of the order by clauses of the + * query. + * + * @param fieldValues The field values to start this query after, in order of the query's order + * by. + * + * @return The created `FIRQuery`. + */ +- (FIRQuery *)queryStartingAfterValues:(NSArray *)fieldValues NS_SWIFT_NAME(start(after:)); + +/** + * Creates and returns a new `FIRQuery` that ends before the provided document (exclusive). The end + * position is relative to the order of the query. The document must contain all of the fields + * provided in the orderBy of this query. + * + * @param document The snapshot of the document to end before. + * + * @return The created `FIRQuery`. + */ +- (FIRQuery *)queryEndingBeforeDocument:(FIRDocumentSnapshot *)document + NS_SWIFT_NAME(end(beforeDocument:)); + +/** + * Creates and returns a new `FIRQuery` that ends before the provided fields relative to the order + * of the query. The order of the field values must match the order of the order by clauses of the + * query. + * + * @param fieldValues The field values to end this query before, in order of the query's order by. + * + * @return The created `FIRQuery`. + */ +- (FIRQuery *)queryEndingBeforeValues:(NSArray *)fieldValues NS_SWIFT_NAME(end(before:)); + +/** + * Creates and returns a new `FIRQuery` that ends at the provided document (exclusive). The end + * position is relative to the order of the query. The document must contain all of the fields + * provided in the orderBy of this query. + * + * @param document The snapshot of the document to end at. + * + * @return The created `FIRQuery`. + */ +- (FIRQuery *)queryEndingAtDocument:(FIRDocumentSnapshot *)document NS_SWIFT_NAME(end(atDocument:)); + +/** + * Creates and returns a new `FIRQuery` that ends at the provided fields relative to the order of + * the query. The order of the field values must match the order of the order by clauses of the + * query. + * + * @param fieldValues The field values to end this query at, in order of the query's order by. + * + * @return The created `FIRQuery`. + */ +- (FIRQuery *)queryEndingAtValues:(NSArray *)fieldValues NS_SWIFT_NAME(end(at:)); + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Public/FIRQuerySnapshot.h b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Public/FIRQuerySnapshot.h new file mode 100644 index 0000000..268598f --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Public/FIRQuerySnapshot.h @@ -0,0 +1,73 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +NS_ASSUME_NONNULL_BEGIN + +@class FIRDocumentChange; +@class FIRQuery; +@class FIRQueryDocumentSnapshot; +@class FIRSnapshotMetadata; + +/** + * A `FIRQuerySnapshot` contains zero or more `FIRDocumentSnapshot` objects. It can be enumerated + * using "for ... in documentSet.documents" and its size can be inspected with `isEmpty` and + * `count`. + */ +NS_SWIFT_NAME(QuerySnapshot) +@interface FIRQuerySnapshot : NSObject + +/** :nodoc: */ +- (id)init __attribute__((unavailable("FIRQuerySnapshot cannot be created directly."))); + +/** + * The query on which you called `getDocuments` or listened to in order to get this + * `FIRQuerySnapshot`. + */ +@property(nonatomic, strong, readonly) FIRQuery *query; + +/** Metadata about this snapshot, concerning its source and if it has local modifications. */ +@property(nonatomic, strong, readonly) FIRSnapshotMetadata *metadata; + +/** Indicates whether this `FIRQuerySnapshot` is empty (contains no documents). */ +@property(nonatomic, readonly, getter=isEmpty) BOOL empty; + +/** The count of documents in this `FIRQuerySnapshot`. */ +@property(nonatomic, readonly) NSInteger count; + +/** An Array of the `FIRDocumentSnapshots` that make up this document set. */ +@property(nonatomic, strong, readonly) NSArray *documents; + +/** + * An array of the documents that changed since the last snapshot. If this is the first snapshot, + * all documents will be in the list as Added changes. + */ +@property(nonatomic, strong, readonly) NSArray *documentChanges; + +/** + * Returns an array of the documents that changed since the last snapshot. If this is the first + * snapshot, all documents will be in the list as Added changes. + * + * @param includeMetadataChanges Whether metadata-only changes (i.e. only + * `FIRDocumentSnapshot.metadata` changed) should be included. + */ +- (NSArray *)documentChangesWithIncludeMetadataChanges: + (BOOL)includeMetadataChanges NS_SWIFT_NAME(documentChanges(includeMetadataChanges:)); + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Public/FIRSnapshotMetadata.h b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Public/FIRSnapshotMetadata.h new file mode 100644 index 0000000..043d819 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Public/FIRSnapshotMetadata.h @@ -0,0 +1,46 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** Metadata about a snapshot, describing the state of the snapshot. */ +NS_SWIFT_NAME(SnapshotMetadata) +@interface FIRSnapshotMetadata : NSObject + +/** :nodoc: */ +- (instancetype)init NS_UNAVAILABLE; + +/** + * Returns YES if the snapshot contains the result of local writes (e.g. set() or update() calls) + * that have not yet been committed to the backend. If your listener has opted into metadata updates + * (via `includeMetadataChanges:YES`) you will receive another snapshot with `hasPendingWrites` + * equal to NO once the writes have been committed to the backend. + */ +@property(nonatomic, assign, readonly, getter=hasPendingWrites) BOOL pendingWrites; + +/** + * Returns YES if the snapshot was created from cached data rather than guaranteed up-to-date server + * data. If your listener has opted into metadata updates (via `includeMetadataChanges:YES`) you + * will receive another snapshot with `isFromCache` equal to NO once the client has received + * up-to-date data from the backend. + */ +@property(nonatomic, assign, readonly, getter=isFromCache) BOOL fromCache; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Public/FIRTimestamp.h b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Public/FIRTimestamp.h new file mode 100644 index 0000000..cea316b --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Public/FIRTimestamp.h @@ -0,0 +1,82 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * A Timestamp represents a point in time independent of any time zone or calendar, represented as + * seconds and fractions of seconds at nanosecond resolution in UTC Epoch time. It is encoded using + * the Proleptic Gregorian Calendar which extends the Gregorian calendar backwards to year one. It + * is encoded assuming all minutes are 60 seconds long, i.e. leap seconds are "smeared" so that no + * leap second table is needed for interpretation. Range is from 0001-01-01T00:00:00Z to + * 9999-12-31T23:59:59.999999999Z. By restricting to that range, we ensure that we can convert to + * and from RFC 3339 date strings. + * + * @see https://github.com/google/protobuf/blob/master/src/google/protobuf/timestamp.proto for the + * reference timestamp definition. + */ +NS_SWIFT_NAME(Timestamp) +@interface FIRTimestamp : NSObject + +/** :nodoc: */ +- (instancetype)init NS_UNAVAILABLE; + +/** + * Creates a new timestamp. + * + * @param seconds the number of seconds since epoch. + * @param nanoseconds the number of nanoseconds after the seconds. + */ +- (instancetype)initWithSeconds:(int64_t)seconds + nanoseconds:(int32_t)nanoseconds NS_DESIGNATED_INITIALIZER; + +/** + * Creates a new timestamp. + * + * @param seconds the number of seconds since epoch. + * @param nanoseconds the number of nanoseconds after the seconds. + */ ++ (instancetype)timestampWithSeconds:(int64_t)seconds nanoseconds:(int32_t)nanoseconds; + +/** Creates a new timestamp from the given date. */ ++ (instancetype)timestampWithDate:(NSDate *)date; + +/** Creates a new timestamp with the current date / time. */ ++ (instancetype)timestamp; + +/** Returns a new NSDate corresponding to this timestamp. This may lose precision. */ +- (NSDate *)dateValue; + +- (NSComparisonResult)compare:(FIRTimestamp *)other; + +/** + * Represents seconds of UTC time since Unix epoch 1970-01-01T00:00:00Z. + * Must be from 0001-01-01T00:00:00Z to 9999-12-31T23:59:59Z inclusive. + */ +@property(nonatomic, assign, readonly) int64_t seconds; + +/** + * Non-negative fractions of a second at nanosecond resolution. Negative second values with + * fractions must still have non-negative nanos values that count forward in time. + * Must be from 0 to 999,999,999 inclusive. + */ +@property(nonatomic, assign, readonly) int32_t nanoseconds; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Public/FIRTransaction.h b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Public/FIRTransaction.h new file mode 100644 index 0000000..ede0fb9 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Public/FIRTransaction.h @@ -0,0 +1,127 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +NS_ASSUME_NONNULL_BEGIN + +@class FIRDocumentReference; +@class FIRDocumentSnapshot; + +/** + * `FIRTransaction` provides methods to read and write data within a transaction. + * + * @see FIRFirestore#transaction:completion: + */ +NS_SWIFT_NAME(Transaction) +@interface FIRTransaction : NSObject + +/** :nodoc: */ +- (id)init __attribute__((unavailable("FIRTransaction cannot be created directly."))); + +/** + * Writes to the document referred to by `document`. If the document doesn't yet exist, + * this method creates it and then sets the data. If the document exists, this method overwrites + * the document data with the new values. + * + * @param data An `NSDictionary` that contains the fields and data to write to the document. + * @param document A reference to the document whose data should be overwritten. + * @return This `FIRTransaction` instance. Used for chaining method calls. + */ +// clang-format off +- (FIRTransaction *)setData:(NSDictionary *)data + forDocument:(FIRDocumentReference *)document + NS_SWIFT_NAME(setData(_:forDocument:)); +// clang-format on + +/** + * Writes to the document referred to by `document`. If the document doesn't yet exist, + * this method creates it and then sets the data. If you pass `merge:YES`, the provided data will be + * merged into any existing document. + * + * @param data An `NSDictionary` that contains the fields and data to write to the document. + * @param document A reference to the document whose data should be overwritten. + * @param merge Whether to merge the provided data into any existing document. + * @return This `FIRTransaction` instance. Used for chaining method calls. + */ +// clang-format off +- (FIRTransaction *)setData:(NSDictionary *)data + forDocument:(FIRDocumentReference *)document + merge:(BOOL)merge + NS_SWIFT_NAME(setData(_:forDocument:merge:)); +// clang-format on + +/** + * Writes to the document referred to by `document` and only replace the fields + * specified under `mergeFields`. Any field that is not specified in `mergeFields` + * is ignored and remains untouched. If the document doesn't yet exist, + * this method creates it and then sets the data. + * + * It is an error to include a field in `mergeFields` that does not have a corresponding + * value in the `data` dictionary. + * + * @param data An `NSDictionary` containing the fields that make up the document + * to be written. + * @param document A reference to the document whose data should be overwritten. + * @param mergeFields An `NSArray` that contains a list of `NSString` or `FIRFieldPath` elements + * specifying which fields to merge. Fields can contain dots to reference nested fields within + * the document. + * @return This `FIRTransaction` instance. Used for chaining method calls. + */ +// clang-format off +- (FIRTransaction *)setData:(NSDictionary *)data + forDocument:(FIRDocumentReference *)document + mergeFields:(NSArray *)mergeFields + NS_SWIFT_NAME(setData(_:forDocument:mergeFields:)); +// clang-format on + +/** + * Updates fields in the document referred to by `document`. + * If the document does not exist, the transaction will fail. + * + * @param fields An `NSDictionary` containing the fields (expressed as an `NSString` or + * `FIRFieldPath`) and values with which to update the document. + * @param document A reference to the document whose data should be updated. + * @return This `FIRTransaction` instance. Used for chaining method calls. + */ +// clang-format off +- (FIRTransaction *)updateData:(NSDictionary *)fields + forDocument:(FIRDocumentReference *)document + NS_SWIFT_NAME(updateData(_:forDocument:)); +// clang-format on + +/** + * Deletes the document referred to by `document`. + * + * @param document A reference to the document that should be deleted. + * @return This `FIRTransaction` instance. Used for chaining method calls. + */ +- (FIRTransaction *)deleteDocument:(FIRDocumentReference *)document + NS_SWIFT_NAME(deleteDocument(_:)); + +/** + * Reads the document referenced by `document`. + * + * @param document A reference to the document to be read. + * @param error An out parameter to capture an error, if one occurred. + */ +- (FIRDocumentSnapshot *_Nullable)getDocument:(FIRDocumentReference *)document + error:(NSError *__autoreleasing *)error + NS_SWIFT_NAME(getDocument(_:)); + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Public/FIRWriteBatch.h b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Public/FIRWriteBatch.h new file mode 100644 index 0000000..22d1b16 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Public/FIRWriteBatch.h @@ -0,0 +1,135 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +NS_ASSUME_NONNULL_BEGIN + +@class FIRDocumentReference; + +/** + * A write batch is used to perform multiple writes as a single atomic unit. + * + * A WriteBatch object can be acquired by calling [FIRFirestore batch]. It provides methods for + * adding writes to the write batch. None of the writes will be committed (or visible locally) + * until [FIRWriteBatch commit] is called. + * + * Unlike transactions, write batches are persisted offline and therefore are preferable when you + * don't need to condition your writes on read data. + */ +NS_SWIFT_NAME(WriteBatch) +@interface FIRWriteBatch : NSObject + +/** :nodoc: */ +- (id)init __attribute__((unavailable("FIRWriteBatch cannot be created directly."))); + +/** + * Writes to the document referred to by `document`. If the document doesn't yet exist, + * this method creates it and then sets the data. If the document exists, this method overwrites + * the document data with the new values. + * + * @param data An `NSDictionary` that contains the fields and data to write to the document. + * @param document A reference to the document whose data should be overwritten. + * @return This `FIRWriteBatch` instance. Used for chaining method calls. + */ +// clang-format off +- (FIRWriteBatch *)setData:(NSDictionary *)data + forDocument:(FIRDocumentReference *)document NS_SWIFT_NAME(setData(_:forDocument:)); +// clang-format on + +/** + * Writes to the document referred to by `document`. If the document doesn't yet exist, + * this method creates it and then sets the data. If you pass `merge:YES`, the provided data will be + * merged into any existing document. + * + * @param data An `NSDictionary` that contains the fields and data to write to the document. + * @param document A reference to the document whose data should be overwritten. + * @param merge Whether to merge the provided data into any existing document. + * @return This `FIRWriteBatch` instance. Used for chaining method calls. + */ +// clang-format off +- (FIRWriteBatch *)setData:(NSDictionary *)data + forDocument:(FIRDocumentReference *)document + merge:(BOOL)merge + NS_SWIFT_NAME(setData(_:forDocument:merge:)); +// clang-format on + +/** + * Writes to the document referred to by `document` and only replace the fields + * specified under `mergeFields`. Any field that is not specified in `mergeFields` + * is ignored and remains untouched. If the document doesn't yet exist, + * this method creates it and then sets the data. + * + * It is an error to include a field in `mergeFields` that does not have a corresponding + * value in the `data` dictionary. + * + * @param data An `NSDictionary` that contains the fields and data to write to the document. + * @param document A reference to the document whose data should be overwritten. + * @param mergeFields An `NSArray` that contains a list of `NSString` or `FIRFieldPath` elements + * specifying which fields to merge. Fields can contain dots to reference nested fields within + * the document. + * @return This `FIRWriteBatch` instance. Used for chaining method calls. + */ +// clang-format off +- (FIRWriteBatch *)setData:(NSDictionary *)data + forDocument:(FIRDocumentReference *)document + mergeFields:(NSArray *)mergeFields + NS_SWIFT_NAME(setData(_:forDocument:mergeFields:)); +// clang-format on + +/** + * Updates fields in the document referred to by `document`. + * If document does not exist, the write batch will fail. + * + * @param fields An `NSDictionary` containing the fields (expressed as an `NSString` or + * `FIRFieldPath`) and values with which to update the document. + * @param document A reference to the document whose data should be updated. + * @return This `FIRWriteBatch` instance. Used for chaining method calls. + */ +// clang-format off +- (FIRWriteBatch *)updateData:(NSDictionary *)fields + forDocument:(FIRDocumentReference *)document + NS_SWIFT_NAME(updateData(_:forDocument:)); +// clang-format on + +/** + * Deletes the document referred to by `document`. + * + * @param document A reference to the document that should be deleted. + * @return This `FIRWriteBatch` instance. Used for chaining method calls. + */ +- (FIRWriteBatch *)deleteDocument:(FIRDocumentReference *)document + NS_SWIFT_NAME(deleteDocument(_:)); + +/** + * Commits all of the writes in this write batch as a single atomic unit. + */ +- (void)commit; + +/** + * Commits all of the writes in this write batch as a single atomic unit. + * + * @param completion A block to be called once all of the writes in the batch have been + * successfully written to the backend as an atomic unit. This block will only execute + * when the client is online and the commit has completed against the server. The + * completion handler will not be called when the device is offline, though local + * changes will be visible immediately. + */ +- (void)commitWithCompletion:(nullable void (^)(NSError *_Nullable error))completion; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Public/FirebaseFirestore.h b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Public/FirebaseFirestore.h new file mode 100644 index 0000000..127c935 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Public/FirebaseFirestore.h @@ -0,0 +1,33 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "FIRCollectionReference.h" +#import "FIRDocumentChange.h" +#import "FIRDocumentReference.h" +#import "FIRDocumentSnapshot.h" +#import "FIRFieldPath.h" +#import "FIRFieldValue.h" +#import "FIRFirestore.h" +#import "FIRFirestoreErrors.h" +#import "FIRFirestoreSettings.h" +#import "FIRGeoPoint.h" +#import "FIRListenerRegistration.h" +#import "FIRQuery.h" +#import "FIRQuerySnapshot.h" +#import "FIRSnapshotMetadata.h" +#import "FIRTimestamp.h" +#import "FIRTransaction.h" +#import "FIRWriteBatch.h" diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Remote/FSTSerializerBeta.h b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Remote/FSTSerializerBeta.h new file mode 100644 index 0000000..4b6c087 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Remote/FSTSerializerBeta.h @@ -0,0 +1,123 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +#include + +#include "Firestore/core/include/firebase/firestore/timestamp.h" +#include "Firestore/core/src/firebase/firestore/model/database_id.h" +#include "Firestore/core/src/firebase/firestore/model/document_key.h" +#include "Firestore/core/src/firebase/firestore/model/snapshot_version.h" +#include "Firestore/core/src/firebase/firestore/remote/watch_change.h" + +@class FSTFieldValue; +@class FSTMaybeDocument; +@class FSTMutation; +@class FSTMutationBatch; +@class FSTMutationResult; +@class FSTObjectValue; +@class FSTQuery; +@class FSTQueryData; + +@class GCFSBatchGetDocumentsResponse; +@class GCFSDocument; +@class GCFSDocumentMask; +@class GCFSListenResponse; +@class GCFSTarget; +@class GCFSTarget_DocumentsTarget; +@class GCFSTarget_QueryTarget; +@class GCFSValue; +@class GCFSWrite; +@class GCFSWriteResult; + +@class GPBTimestamp; + +NS_ASSUME_NONNULL_BEGIN + +/** + * Converts internal model objects to their equivalent protocol buffer form. Methods starting with + * "encoded" convert to a protocol buffer and methods starting with "decoded" convert from a + * protocol buffer. + * + * Throws an exception if a protocol buffer is missing a critical field or has a value we can't + * interpret. + */ +@interface FSTSerializerBeta : NSObject + +- (instancetype)init NS_UNAVAILABLE; + +- (instancetype)initWithDatabaseID:(const firebase::firestore::model::DatabaseId *)databaseID + NS_DESIGNATED_INITIALIZER; + +- (GPBTimestamp *)encodedTimestamp:(const firebase::Timestamp &)timestamp; +- (firebase::Timestamp)decodedTimestamp:(GPBTimestamp *)timestamp; + +- (GPBTimestamp *)encodedVersion:(const firebase::firestore::model::SnapshotVersion &)version; +- (firebase::firestore::model::SnapshotVersion)decodedVersion:(GPBTimestamp *)version; + +/** Returns the database ID, such as `projects/{project id}/databases/{database_id}`. */ +- (NSString *)encodedDatabaseID; + +/** + * Encodes the given document key as a fully qualified name. This includes the + * databaseId associated with this FSTSerializerBeta and the key path. + */ +- (NSString *)encodedDocumentKey:(const firebase::firestore::model::DocumentKey &)key; +- (firebase::firestore::model::DocumentKey)decodedDocumentKey:(NSString *)key; + +- (GCFSValue *)encodedFieldValue:(FSTFieldValue *)fieldValue; +- (FSTFieldValue *)decodedFieldValue:(GCFSValue *)valueProto; + +- (GCFSWrite *)encodedMutation:(FSTMutation *)mutation; +- (FSTMutation *)decodedMutation:(GCFSWrite *)mutation; + +- (FSTMutationResult *)decodedMutationResult:(GCFSWriteResult *)mutation + commitVersion:(const firebase::firestore::model::SnapshotVersion &) + commitVersion; + +- (nullable NSMutableDictionary *)encodedListenRequestLabelsForQueryData: + (FSTQueryData *)queryData; + +- (GCFSTarget *)encodedTarget:(FSTQueryData *)queryData; + +- (GCFSTarget_DocumentsTarget *)encodedDocumentsTarget:(FSTQuery *)query; +- (FSTQuery *)decodedQueryFromDocumentsTarget:(GCFSTarget_DocumentsTarget *)target; + +- (GCFSTarget_QueryTarget *)encodedQueryTarget:(FSTQuery *)query; +- (FSTQuery *)decodedQueryFromQueryTarget:(GCFSTarget_QueryTarget *)target; + +- (std::unique_ptr)decodedWatchChange: + (GCFSListenResponse *)watchChange; +- (firebase::firestore::model::SnapshotVersion)versionFromListenResponse: + (GCFSListenResponse *)watchChange; + +- (GCFSDocument *)encodedDocumentWithFields:(FSTObjectValue *)objectValue + key:(const firebase::firestore::model::DocumentKey &)key; + +/** + * Encodes an FSTObjectValue into a dictionary. + * @return a new dictionary that can be assigned to a field in another proto. + */ +- (NSMutableDictionary *)encodedFields:(FSTObjectValue *)value; + +- (FSTObjectValue *)decodedFields:(NSDictionary *)fields; + +- (FSTMaybeDocument *)decodedMaybeDocumentFromBatch:(GCFSBatchGetDocumentsResponse *)response; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Remote/FSTSerializerBeta.mm b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Remote/FSTSerializerBeta.mm new file mode 100644 index 0000000..e111572 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Remote/FSTSerializerBeta.mm @@ -0,0 +1,1227 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "Firestore/Source/Remote/FSTSerializerBeta.h" + +#include +#include +#include +#include +#include + +#import "Firestore/Protos/objc/google/firestore/v1/Common.pbobjc.h" +#import "Firestore/Protos/objc/google/firestore/v1/Document.pbobjc.h" +#import "Firestore/Protos/objc/google/firestore/v1/Firestore.pbobjc.h" +#import "Firestore/Protos/objc/google/firestore/v1/Query.pbobjc.h" +#import "Firestore/Protos/objc/google/firestore/v1/Write.pbobjc.h" +#import "Firestore/Protos/objc/google/rpc/Status.pbobjc.h" +#import "Firestore/Protos/objc/google/type/Latlng.pbobjc.h" + +#import "FIRFirestoreErrors.h" +#import "FIRGeoPoint.h" +#import "FIRTimestamp.h" +#import "Firestore/Source/Core/FSTQuery.h" +#import "Firestore/Source/Local/FSTQueryData.h" +#import "Firestore/Source/Model/FSTDocument.h" +#import "Firestore/Source/Model/FSTFieldValue.h" +#import "Firestore/Source/Model/FSTMutation.h" +#import "Firestore/Source/Model/FSTMutationBatch.h" + +#include "Firestore/core/include/firebase/firestore/firestore_errors.h" +#include "Firestore/core/src/firebase/firestore/model/database_id.h" +#include "Firestore/core/src/firebase/firestore/model/document_key.h" +#include "Firestore/core/src/firebase/firestore/model/field_mask.h" +#include "Firestore/core/src/firebase/firestore/model/field_path.h" +#include "Firestore/core/src/firebase/firestore/model/field_transform.h" +#include "Firestore/core/src/firebase/firestore/model/precondition.h" +#include "Firestore/core/src/firebase/firestore/model/resource_path.h" +#include "Firestore/core/src/firebase/firestore/model/transform_operations.h" +#include "Firestore/core/src/firebase/firestore/remote/existence_filter.h" +#include "Firestore/core/src/firebase/firestore/remote/watch_change.h" +#include "Firestore/core/src/firebase/firestore/util/hard_assert.h" +#include "Firestore/core/src/firebase/firestore/util/status.h" +#include "Firestore/core/src/firebase/firestore/util/string_apple.h" +#include "absl/memory/memory.h" +#include "absl/types/optional.h" + +namespace util = firebase::firestore::util; +using firebase::Timestamp; +using firebase::firestore::FirestoreErrorCode; +using firebase::firestore::model::ArrayTransform; +using firebase::firestore::model::DatabaseId; +using firebase::firestore::model::DocumentKey; +using firebase::firestore::model::FieldMask; +using firebase::firestore::model::FieldPath; +using firebase::firestore::model::FieldTransform; +using firebase::firestore::model::NumericIncrementTransform; +using firebase::firestore::model::Precondition; +using firebase::firestore::model::ResourcePath; +using firebase::firestore::model::ServerTimestampTransform; +using firebase::firestore::model::SnapshotVersion; +using firebase::firestore::model::TargetId; +using firebase::firestore::model::TransformOperation; +using firebase::firestore::remote::DocumentWatchChange; +using firebase::firestore::remote::ExistenceFilter; +using firebase::firestore::remote::ExistenceFilterWatchChange; +using firebase::firestore::remote::WatchChange; +using firebase::firestore::remote::WatchTargetChange; +using firebase::firestore::remote::WatchTargetChangeState; + +NS_ASSUME_NONNULL_BEGIN + +@interface FSTSerializerBeta () +// Does not own this DatabaseId. +@property(nonatomic, assign, readonly) const DatabaseId *databaseID; +@end + +@implementation FSTSerializerBeta + +- (instancetype)initWithDatabaseID:(const DatabaseId *)databaseID { + self = [super init]; + if (self) { + _databaseID = databaseID; + } + return self; +} + +#pragma mark - SnapshotVersion <=> GPBTimestamp + +- (GPBTimestamp *)encodedTimestamp:(const Timestamp &)timestamp { + GPBTimestamp *result = [GPBTimestamp message]; + result.seconds = timestamp.seconds(); + result.nanos = timestamp.nanoseconds(); + return result; +} + +- (Timestamp)decodedTimestamp:(GPBTimestamp *)timestamp { + return Timestamp{timestamp.seconds, timestamp.nanos}; +} + +- (GPBTimestamp *)encodedVersion:(const SnapshotVersion &)version { + return [self encodedTimestamp:version.timestamp()]; +} + +- (SnapshotVersion)decodedVersion:(GPBTimestamp *)version { + return SnapshotVersion{[self decodedTimestamp:version]}; +} + +#pragma mark - FIRGeoPoint <=> GTPLatLng + +- (GTPLatLng *)encodedGeoPoint:(FIRGeoPoint *)geoPoint { + GTPLatLng *latLng = [GTPLatLng message]; + latLng.latitude = geoPoint.latitude; + latLng.longitude = geoPoint.longitude; + return latLng; +} + +- (FIRGeoPoint *)decodedGeoPoint:(GTPLatLng *)latLng { + return [[FIRGeoPoint alloc] initWithLatitude:latLng.latitude longitude:latLng.longitude]; +} + +#pragma mark - DocumentKey <=> Key proto + +- (NSString *)encodedDocumentKey:(const DocumentKey &)key { + return [self encodedResourcePathForDatabaseID:self.databaseID path:key.path()]; +} + +- (DocumentKey)decodedDocumentKey:(NSString *)name { + const ResourcePath path = [self decodedResourcePathWithDatabaseID:name]; + HARD_ASSERT(path[1] == self.databaseID->project_id(), + "Tried to deserialize key from different project."); + HARD_ASSERT(path[3] == self.databaseID->database_id(), + "Tried to deserialize key from different datbase."); + return DocumentKey{[self localResourcePathForQualifiedResourcePath:path]}; +} + +- (NSString *)encodedResourcePathForDatabaseID:(const DatabaseId *)databaseID + path:(const ResourcePath &)path { + return util::WrapNSString([self encodedResourcePathForDatabaseID:databaseID] + .Append("documents") + .Append(path) + .CanonicalString()); +} + +- (ResourcePath)decodedResourcePathWithDatabaseID:(NSString *)name { + const ResourcePath path = ResourcePath::FromString(util::MakeString(name)); + HARD_ASSERT([self validQualifiedResourcePath:path], "Tried to deserialize invalid key %s", + path.CanonicalString()); + return path; +} + +- (NSString *)encodedQueryPath:(const ResourcePath &)path { + return [self encodedResourcePathForDatabaseID:self.databaseID path:path]; +} + +- (ResourcePath)decodedQueryPath:(NSString *)name { + const ResourcePath resource = [self decodedResourcePathWithDatabaseID:name]; + if (resource.size() == 4) { + // In v1beta1 queries for collections at the root did not have a trailing "/documents". In v1 + // all resource paths contain "/documents". Preserve the ability to read the v1beta1 form for + // compatibility with queries persisted in the local query cache. + return ResourcePath{}; + } else { + return [self localResourcePathForQualifiedResourcePath:resource]; + } +} + +- (ResourcePath)encodedResourcePathForDatabaseID:(const DatabaseId *)databaseID { + return ResourcePath{"projects", databaseID->project_id(), "databases", databaseID->database_id()}; +} + +- (ResourcePath)localResourcePathForQualifiedResourcePath:(const ResourcePath &)resourceName { + HARD_ASSERT(resourceName.size() > 4 && resourceName[4] == "documents", + "Tried to deserialize invalid key %s", resourceName.CanonicalString()); + return resourceName.PopFirst(5); +} + +- (BOOL)validQualifiedResourcePath:(const ResourcePath &)path { + return path.size() >= 4 && path[0] == "projects" && path[2] == "databases"; +} + +- (NSString *)encodedDatabaseID { + return util::WrapNSString( + [self encodedResourcePathForDatabaseID:self.databaseID].CanonicalString()); +} + +#pragma mark - FSTFieldValue <=> Value proto + +- (GCFSValue *)encodedFieldValue:(FSTFieldValue *)fieldValue { + Class fieldClass = [fieldValue class]; + if (fieldClass == [FSTNullValue class]) { + return [self encodedNull]; + + } else if (fieldClass == [FSTBooleanValue class]) { + return [self encodedBool:[[fieldValue value] boolValue]]; + + } else if (fieldClass == [FSTIntegerValue class]) { + return [self encodedInteger:[[fieldValue value] longLongValue]]; + + } else if (fieldClass == [FSTDoubleValue class]) { + return [self encodedDouble:[[fieldValue value] doubleValue]]; + + } else if (fieldClass == [FSTStringValue class]) { + return [self encodedString:[fieldValue value]]; + + } else if (fieldClass == [FSTTimestampValue class]) { + FIRTimestamp *value = static_cast([fieldValue value]); + return [self encodedTimestampValue:Timestamp{value.seconds, value.nanoseconds}]; + } else if (fieldClass == [FSTGeoPointValue class]) { + return [self encodedGeoPointValue:[fieldValue value]]; + + } else if (fieldClass == [FSTBlobValue class]) { + return [self encodedBlobValue:[fieldValue value]]; + + } else if (fieldClass == [FSTReferenceValue class]) { + FSTReferenceValue *ref = (FSTReferenceValue *)fieldValue; + DocumentKey key = [[ref value] key]; + return [self encodedReferenceValueForDatabaseID:[ref databaseID] key:key]; + + } else if (fieldClass == [FSTObjectValue class]) { + GCFSValue *result = [GCFSValue message]; + result.mapValue = [self encodedMapValue:(FSTObjectValue *)fieldValue]; + return result; + + } else if (fieldClass == [FSTArrayValue class]) { + GCFSValue *result = [GCFSValue message]; + result.arrayValue = [self encodedArrayValue:(FSTArrayValue *)fieldValue]; + return result; + + } else { + HARD_FAIL("Unhandled type %s on %s", NSStringFromClass([fieldValue class]), fieldValue); + } +} + +- (FSTFieldValue *)decodedFieldValue:(GCFSValue *)valueProto { + switch (valueProto.valueTypeOneOfCase) { + case GCFSValue_ValueType_OneOfCase_NullValue: + return [FSTNullValue nullValue]; + + case GCFSValue_ValueType_OneOfCase_BooleanValue: + return [FSTBooleanValue booleanValue:valueProto.booleanValue]; + + case GCFSValue_ValueType_OneOfCase_IntegerValue: + return [FSTIntegerValue integerValue:valueProto.integerValue]; + + case GCFSValue_ValueType_OneOfCase_DoubleValue: + return [FSTDoubleValue doubleValue:valueProto.doubleValue]; + + case GCFSValue_ValueType_OneOfCase_StringValue: + return [FSTStringValue stringValue:valueProto.stringValue]; + + case GCFSValue_ValueType_OneOfCase_TimestampValue: { + Timestamp value = [self decodedTimestamp:valueProto.timestampValue]; + return [FSTTimestampValue + timestampValue:[FIRTimestamp timestampWithSeconds:value.seconds() + nanoseconds:value.nanoseconds()]]; + } + + case GCFSValue_ValueType_OneOfCase_GeoPointValue: + return [FSTGeoPointValue geoPointValue:[self decodedGeoPoint:valueProto.geoPointValue]]; + + case GCFSValue_ValueType_OneOfCase_BytesValue: + return [FSTBlobValue blobValue:valueProto.bytesValue]; + + case GCFSValue_ValueType_OneOfCase_ReferenceValue: + return [self decodedReferenceValue:valueProto.referenceValue]; + + case GCFSValue_ValueType_OneOfCase_ArrayValue: + return [self decodedArrayValue:valueProto.arrayValue]; + + case GCFSValue_ValueType_OneOfCase_MapValue: + return [self decodedMapValue:valueProto.mapValue]; + + default: + HARD_FAIL("Unhandled type %s on %s", valueProto.valueTypeOneOfCase, valueProto); + } +} + +- (GCFSValue *)encodedNull { + GCFSValue *result = [GCFSValue message]; + result.nullValue = GPBNullValue_NullValue; + return result; +} + +- (GCFSValue *)encodedBool:(BOOL)value { + GCFSValue *result = [GCFSValue message]; + result.booleanValue = value; + return result; +} + +- (GCFSValue *)encodedDouble:(double)value { + GCFSValue *result = [GCFSValue message]; + result.doubleValue = value; + return result; +} + +- (GCFSValue *)encodedInteger:(int64_t)value { + GCFSValue *result = [GCFSValue message]; + result.integerValue = value; + return result; +} + +- (GCFSValue *)encodedString:(NSString *)value { + GCFSValue *result = [GCFSValue message]; + result.stringValue = value; + return result; +} + +- (GCFSValue *)encodedTimestampValue:(const Timestamp &)value { + GCFSValue *result = [GCFSValue message]; + result.timestampValue = [self encodedTimestamp:value]; + return result; +} + +- (GCFSValue *)encodedGeoPointValue:(FIRGeoPoint *)value { + GCFSValue *result = [GCFSValue message]; + result.geoPointValue = [self encodedGeoPoint:value]; + return result; +} + +- (GCFSValue *)encodedBlobValue:(NSData *)value { + GCFSValue *result = [GCFSValue message]; + result.bytesValue = value; + return result; +} + +- (GCFSValue *)encodedReferenceValueForDatabaseID:(const DatabaseId *)databaseID + key:(const DocumentKey &)key { + HARD_ASSERT(*databaseID == *self.databaseID, "Database %s:%s cannot encode reference from %s:%s", + self.databaseID->project_id(), self.databaseID->database_id(), + databaseID->project_id(), databaseID->database_id()); + GCFSValue *result = [GCFSValue message]; + result.referenceValue = [self encodedResourcePathForDatabaseID:databaseID path:key.path()]; + return result; +} + +- (FSTReferenceValue *)decodedReferenceValue:(NSString *)resourceName { + const ResourcePath path = [self decodedResourcePathWithDatabaseID:resourceName]; + const std::string &project = path[1]; + const std::string &database = path[3]; + const DocumentKey key{[self localResourcePathForQualifiedResourcePath:path]}; + + const DatabaseId database_id(project, database); + HARD_ASSERT(database_id == *self.databaseID, "Database %s:%s cannot encode reference from %s:%s", + self.databaseID->project_id(), self.databaseID->database_id(), + database_id.project_id(), database_id.database_id()); + return [FSTReferenceValue referenceValue:[FSTDocumentKey keyWithDocumentKey:key] + databaseID:self.databaseID]; +} + +- (GCFSArrayValue *)encodedArrayValue:(FSTArrayValue *)arrayValue { + GCFSArrayValue *proto = [GCFSArrayValue message]; + NSMutableArray *protoContents = [proto valuesArray]; + + [[arrayValue internalValue] + enumerateObjectsUsingBlock:^(FSTFieldValue *value, NSUInteger idx, BOOL *stop) { + GCFSValue *converted = [self encodedFieldValue:value]; + [protoContents addObject:converted]; + }]; + return proto; +} + +- (FSTArrayValue *)decodedArrayValue:(GCFSArrayValue *)arrayValue { + NSMutableArray *contents = + [NSMutableArray arrayWithCapacity:arrayValue.valuesArray_Count]; + + [arrayValue.valuesArray + enumerateObjectsUsingBlock:^(GCFSValue *value, NSUInteger idx, BOOL *stop) { + [contents addObject:[self decodedFieldValue:value]]; + }]; + return [[FSTArrayValue alloc] initWithValueNoCopy:contents]; +} + +- (GCFSMapValue *)encodedMapValue:(FSTObjectValue *)value { + GCFSMapValue *result = [GCFSMapValue message]; + result.fields = [self encodedFields:value]; + return result; +} + +- (FSTObjectValue *)decodedMapValue:(GCFSMapValue *)map { + return [self decodedFields:map.fields]; +} + +/** + * Encodes an FSTObjectValue into a dictionary. + * @return a new dictionary that can be assigned to a field in another proto. + */ +- (NSMutableDictionary *)encodedFields:(FSTObjectValue *)value { + FSTImmutableSortedDictionary *fields = value.internalValue; + NSMutableDictionary *result = [NSMutableDictionary dictionary]; + [fields enumerateKeysAndObjectsUsingBlock:^(NSString *key, FSTFieldValue *obj, BOOL *stop) { + GCFSValue *converted = [self encodedFieldValue:obj]; + result[key] = converted; + }]; + return result; +} + +- (FSTObjectValue *)decodedFields:(NSDictionary *)fields { + __block FSTObjectValue *result = [FSTObjectValue objectValue]; + [fields enumerateKeysAndObjectsUsingBlock:^(NSString *_Nonnull key, GCFSValue *_Nonnull obj, + BOOL *_Nonnull stop) { + FieldPath path{util::MakeString(key)}; + FSTFieldValue *value = [self decodedFieldValue:obj]; + result = [result objectBySettingValue:value forPath:path]; + }]; + return result; +} + +#pragma mark - FSTObjectValue <=> Document proto + +- (GCFSDocument *)encodedDocumentWithFields:(FSTObjectValue *)objectValue + key:(const DocumentKey &)key { + GCFSDocument *proto = [GCFSDocument message]; + proto.name = [self encodedDocumentKey:key]; + proto.fields = [self encodedFields:objectValue]; + return proto; +} + +#pragma mark - FSTMaybeDocument <= BatchGetDocumentsResponse proto + +- (FSTMaybeDocument *)decodedMaybeDocumentFromBatch:(GCFSBatchGetDocumentsResponse *)response { + switch (response.resultOneOfCase) { + case GCFSBatchGetDocumentsResponse_Result_OneOfCase_Found: + return [self decodedFoundDocument:response]; + case GCFSBatchGetDocumentsResponse_Result_OneOfCase_Missing: + return [self decodedDeletedDocument:response]; + default: + HARD_FAIL("Unknown document type: %s", response); + } +} + +- (FSTDocument *)decodedFoundDocument:(GCFSBatchGetDocumentsResponse *)response { + HARD_ASSERT(!!response.found, "Tried to deserialize a found document from a deleted document."); + const DocumentKey key = [self decodedDocumentKey:response.found.name]; + FSTObjectValue *value = [self decodedFields:response.found.fields]; + SnapshotVersion version = [self decodedVersion:response.found.updateTime]; + HARD_ASSERT(version != SnapshotVersion::None(), + "Got a document response with no snapshot version"); + + return [FSTDocument documentWithData:value + key:key + version:version + state:FSTDocumentStateSynced + proto:response.found]; +} + +- (FSTDeletedDocument *)decodedDeletedDocument:(GCFSBatchGetDocumentsResponse *)response { + HARD_ASSERT(!!response.missing, "Tried to deserialize a deleted document from a found document."); + const DocumentKey key = [self decodedDocumentKey:response.missing]; + SnapshotVersion version = [self decodedVersion:response.readTime]; + HARD_ASSERT(version != SnapshotVersion::None(), + "Got a no document response with no snapshot version"); + return [FSTDeletedDocument documentWithKey:key version:version hasCommittedMutations:NO]; +} + +#pragma mark - FSTMutation => GCFSWrite proto + +- (GCFSWrite *)encodedMutation:(FSTMutation *)mutation { + GCFSWrite *proto = [GCFSWrite message]; + + Class mutationClass = [mutation class]; + if (mutationClass == [FSTSetMutation class]) { + FSTSetMutation *set = (FSTSetMutation *)mutation; + proto.update = [self encodedDocumentWithFields:set.value key:set.key]; + + } else if (mutationClass == [FSTPatchMutation class]) { + FSTPatchMutation *patch = (FSTPatchMutation *)mutation; + proto.update = [self encodedDocumentWithFields:patch.value key:patch.key]; + proto.updateMask = [self encodedFieldMask:*(patch.fieldMask)]; + + } else if (mutationClass == [FSTTransformMutation class]) { + FSTTransformMutation *transform = (FSTTransformMutation *)mutation; + + proto.transform = [GCFSDocumentTransform message]; + proto.transform.document = [self encodedDocumentKey:transform.key]; + proto.transform.fieldTransformsArray = [self encodedFieldTransforms:transform.fieldTransforms]; + // NOTE: We set a precondition of exists: true as a safety-check, since we always combine + // FSTTransformMutations with an FSTSetMutation or FSTPatchMutation which (if successful) should + // end up with an existing document. + proto.currentDocument.exists = YES; + + } else if (mutationClass == [FSTDeleteMutation class]) { + FSTDeleteMutation *deleteMutation = (FSTDeleteMutation *)mutation; + proto.delete_p = [self encodedDocumentKey:deleteMutation.key]; + + } else { + HARD_FAIL("Unknown mutation type %s", NSStringFromClass(mutationClass)); + } + + if (!mutation.precondition.IsNone()) { + proto.currentDocument = [self encodedPrecondition:mutation.precondition]; + } + + return proto; +} + +- (FSTMutation *)decodedMutation:(GCFSWrite *)mutation { + Precondition precondition = [mutation hasCurrentDocument] + ? [self decodedPrecondition:mutation.currentDocument] + : Precondition::None(); + + switch (mutation.operationOneOfCase) { + case GCFSWrite_Operation_OneOfCase_Update: + if (mutation.hasUpdateMask) { + return [[FSTPatchMutation alloc] initWithKey:[self decodedDocumentKey:mutation.update.name] + fieldMask:[self decodedFieldMask:mutation.updateMask] + value:[self decodedFields:mutation.update.fields] + precondition:precondition]; + } else { + return [[FSTSetMutation alloc] initWithKey:[self decodedDocumentKey:mutation.update.name] + value:[self decodedFields:mutation.update.fields] + precondition:precondition]; + } + + case GCFSWrite_Operation_OneOfCase_Delete_p: + return [[FSTDeleteMutation alloc] initWithKey:[self decodedDocumentKey:mutation.delete_p] + precondition:precondition]; + + case GCFSWrite_Operation_OneOfCase_Transform: { + HARD_ASSERT(precondition == Precondition::Exists(true), + "Transforms must have precondition \"exists == true\""); + + return [[FSTTransformMutation alloc] + initWithKey:[self decodedDocumentKey:mutation.transform.document] + fieldTransforms:[self decodedFieldTransforms:mutation.transform.fieldTransformsArray]]; + } + + default: + // Note that insert is intentionally unhandled, since we don't ever deal in them. + HARD_FAIL("Unknown mutation operation: %s", mutation.operationOneOfCase); + } +} + +- (GCFSPrecondition *)encodedPrecondition:(const Precondition &)precondition { + HARD_ASSERT(!precondition.IsNone(), "Can't serialize an empty precondition"); + GCFSPrecondition *message = [GCFSPrecondition message]; + if (precondition.type() == Precondition::Type::UpdateTime) { + message.updateTime = [self encodedVersion:precondition.update_time()]; + } else if (precondition.type() == Precondition::Type::Exists) { + message.exists = precondition == Precondition::Exists(true); + } else { + HARD_FAIL("Unknown precondition: %s", precondition.description()); + } + return message; +} + +- (Precondition)decodedPrecondition:(GCFSPrecondition *)precondition { + switch (precondition.conditionTypeOneOfCase) { + case GCFSPrecondition_ConditionType_OneOfCase_GPBUnsetOneOfCase: + return Precondition::None(); + + case GCFSPrecondition_ConditionType_OneOfCase_Exists: + return Precondition::Exists(precondition.exists); + + case GCFSPrecondition_ConditionType_OneOfCase_UpdateTime: + return Precondition::UpdateTime([self decodedVersion:precondition.updateTime]); + + default: + HARD_FAIL("Unrecognized Precondition one-of case %s", precondition); + } +} + +- (GCFSDocumentMask *)encodedFieldMask:(const FieldMask &)fieldMask { + GCFSDocumentMask *mask = [GCFSDocumentMask message]; + for (const FieldPath &field : fieldMask) { + [mask.fieldPathsArray addObject:util::WrapNSString(field.CanonicalString())]; + } + return mask; +} + +- (FieldMask)decodedFieldMask:(GCFSDocumentMask *)fieldMask { + std::set fields; + for (NSString *path in fieldMask.fieldPathsArray) { + fields.insert(FieldPath::FromServerFormat(util::MakeString(path))); + } + return FieldMask(std::move(fields)); +} + +- (NSMutableArray *)encodedFieldTransforms: + (const std::vector &)fieldTransforms { + NSMutableArray *protos = [NSMutableArray array]; + for (const FieldTransform &fieldTransform : fieldTransforms) { + GCFSDocumentTransform_FieldTransform *proto = [self encodedFieldTransform:fieldTransform]; + [protos addObject:proto]; + } + return protos; +} + +- (GCFSDocumentTransform_FieldTransform *)encodedFieldTransform: + (const FieldTransform &)fieldTransform { + GCFSDocumentTransform_FieldTransform *proto = [GCFSDocumentTransform_FieldTransform message]; + proto.fieldPath = util::WrapNSString(fieldTransform.path().CanonicalString()); + if (fieldTransform.transformation().type() == TransformOperation::Type::ServerTimestamp) { + proto.setToServerValue = GCFSDocumentTransform_FieldTransform_ServerValue_RequestTime; + + } else if (fieldTransform.transformation().type() == TransformOperation::Type::ArrayUnion) { + proto.appendMissingElements = [self + encodedArrayTransformElements:ArrayTransform::Elements(fieldTransform.transformation())]; + + } else if (fieldTransform.transformation().type() == TransformOperation::Type::ArrayRemove) { + proto.removeAllFromArray_p = [self + encodedArrayTransformElements:ArrayTransform::Elements(fieldTransform.transformation())]; + } else if (fieldTransform.transformation().type() == TransformOperation::Type::Increment) { + const NumericIncrementTransform &incrementTransform = + static_cast(fieldTransform.transformation()); + proto.increment = [self encodedFieldValue:incrementTransform.operand()]; + } else { + HARD_FAIL("Unknown transform: %s type", fieldTransform.transformation().type()); + } + return proto; +} + +- (GCFSArrayValue *)encodedArrayTransformElements:(const std::vector &)elements { + GCFSArrayValue *proto = [GCFSArrayValue message]; + NSMutableArray *protoContents = [proto valuesArray]; + + for (FSTFieldValue *element : elements) { + GCFSValue *converted = [self encodedFieldValue:element]; + [protoContents addObject:converted]; + } + return proto; +} + +- (std::vector)decodedFieldTransforms: + (NSArray *)protos { + std::vector fieldTransforms; + fieldTransforms.reserve(protos.count); + + for (GCFSDocumentTransform_FieldTransform *proto in protos) { + switch (proto.transformTypeOneOfCase) { + case GCFSDocumentTransform_FieldTransform_TransformType_OneOfCase_SetToServerValue: { + HARD_ASSERT( + proto.setToServerValue == GCFSDocumentTransform_FieldTransform_ServerValue_RequestTime, + "Unknown transform setToServerValue: %s", proto.setToServerValue); + fieldTransforms.emplace_back( + FieldPath::FromServerFormat(util::MakeString(proto.fieldPath)), + absl::make_unique(ServerTimestampTransform::Get())); + break; + } + + case GCFSDocumentTransform_FieldTransform_TransformType_OneOfCase_AppendMissingElements: { + std::vector elements = + [self decodedArrayTransformElements:proto.appendMissingElements]; + fieldTransforms.emplace_back( + FieldPath::FromServerFormat(util::MakeString(proto.fieldPath)), + absl::make_unique(TransformOperation::Type::ArrayUnion, + std::move(elements))); + break; + } + + case GCFSDocumentTransform_FieldTransform_TransformType_OneOfCase_RemoveAllFromArray_p: { + std::vector elements = + [self decodedArrayTransformElements:proto.removeAllFromArray_p]; + fieldTransforms.emplace_back( + FieldPath::FromServerFormat(util::MakeString(proto.fieldPath)), + absl::make_unique(TransformOperation::Type::ArrayRemove, + std::move(elements))); + break; + } + + case GCFSDocumentTransform_FieldTransform_TransformType_OneOfCase_Increment: { + FSTNumberValue *operand = + static_cast([self decodedFieldValue:proto.increment]); + fieldTransforms.emplace_back(FieldPath::FromServerFormat(util::MakeString(proto.fieldPath)), + absl::make_unique(operand)); + break; + } + + default: + HARD_FAIL("Unknown transform: %s", proto); + } + } + + return fieldTransforms; +} + +- (std::vector)decodedArrayTransformElements:(GCFSArrayValue *)proto { + __block std::vector elements; + [proto.valuesArray enumerateObjectsUsingBlock:^(GCFSValue *value, NSUInteger idx, BOOL *stop) { + elements.push_back([self decodedFieldValue:value]); + }]; + return elements; +} + +#pragma mark - FSTMutationResult <= GCFSWriteResult proto + +- (FSTMutationResult *)decodedMutationResult:(GCFSWriteResult *)mutation + commitVersion:(const SnapshotVersion &)commitVersion { + // NOTE: Deletes don't have an updateTime. Use commitVersion instead. + SnapshotVersion version = + mutation.hasUpdateTime ? [self decodedVersion:mutation.updateTime] : commitVersion; + NSMutableArray *_Nullable transformResults = nil; + if (mutation.transformResultsArray.count > 0) { + transformResults = [NSMutableArray array]; + for (GCFSValue *result in mutation.transformResultsArray) { + [transformResults addObject:[self decodedFieldValue:result]]; + } + } + return [[FSTMutationResult alloc] initWithVersion:std::move(version) + transformResults:transformResults]; +} + +#pragma mark - FSTQueryData => GCFSTarget proto + +- (nullable NSMutableDictionary *)encodedListenRequestLabelsForQueryData: + (FSTQueryData *)queryData { + NSString *value = [self encodedLabelForPurpose:queryData.purpose]; + if (!value) { + return nil; + } + + NSMutableDictionary *result = + [NSMutableDictionary dictionaryWithCapacity:1]; + [result setObject:value forKey:@"goog-listen-tags"]; + return result; +} + +- (nullable NSString *)encodedLabelForPurpose:(FSTQueryPurpose)purpose { + switch (purpose) { + case FSTQueryPurposeListen: + return nil; + case FSTQueryPurposeExistenceFilterMismatch: + return @"existence-filter-mismatch"; + case FSTQueryPurposeLimboResolution: + return @"limbo-document"; + default: + HARD_FAIL("Unrecognized query purpose: %s", purpose); + } +} + +- (GCFSTarget *)encodedTarget:(FSTQueryData *)queryData { + GCFSTarget *result = [GCFSTarget message]; + FSTQuery *query = queryData.query; + + if ([query isDocumentQuery]) { + result.documents = [self encodedDocumentsTarget:query]; + } else { + result.query = [self encodedQueryTarget:query]; + } + + result.targetId = queryData.targetID; + if (queryData.resumeToken.length > 0) { + result.resumeToken = queryData.resumeToken; + } + + return result; +} + +- (GCFSTarget_DocumentsTarget *)encodedDocumentsTarget:(FSTQuery *)query { + GCFSTarget_DocumentsTarget *result = [GCFSTarget_DocumentsTarget message]; + NSMutableArray *docs = result.documentsArray; + [docs addObject:[self encodedQueryPath:query.path]]; + return result; +} + +- (FSTQuery *)decodedQueryFromDocumentsTarget:(GCFSTarget_DocumentsTarget *)target { + NSArray *documents = target.documentsArray; + HARD_ASSERT(documents.count == 1, "DocumentsTarget contained other than 1 document %s", + (unsigned long)documents.count); + + NSString *name = documents[0]; + return [FSTQuery queryWithPath:[self decodedQueryPath:name]]; +} + +- (GCFSTarget_QueryTarget *)encodedQueryTarget:(FSTQuery *)query { + // Dissect the path into parent, collectionId, and optional key filter. + GCFSTarget_QueryTarget *queryTarget = [GCFSTarget_QueryTarget message]; + const ResourcePath &path = query.path; + if (query.collectionGroup) { + HARD_ASSERT(path.size() % 2 == 0, + "Collection group queries should be within a document path or root."); + queryTarget.parent = [self encodedQueryPath:path]; + GCFSStructuredQuery_CollectionSelector *from = [GCFSStructuredQuery_CollectionSelector message]; + from.collectionId = query.collectionGroup; + from.allDescendants = YES; + [queryTarget.structuredQuery.fromArray addObject:from]; + } else { + HARD_ASSERT(path.size() % 2 != 0, "Document queries with filters are not supported."); + queryTarget.parent = [self encodedQueryPath:path.PopLast()]; + GCFSStructuredQuery_CollectionSelector *from = [GCFSStructuredQuery_CollectionSelector message]; + from.collectionId = util::WrapNSString(path.last_segment()); + [queryTarget.structuredQuery.fromArray addObject:from]; + } + + // Encode the filters. + GCFSStructuredQuery_Filter *_Nullable where = [self encodedFilters:query.filters]; + if (where) { + queryTarget.structuredQuery.where = where; + } + + NSArray *orders = [self encodedSortOrders:query.sortOrders]; + if (orders.count) { + [queryTarget.structuredQuery.orderByArray addObjectsFromArray:orders]; + } + + if (query.limit != NSNotFound) { + queryTarget.structuredQuery.limit.value = (int32_t)query.limit; + } + + if (query.startAt) { + queryTarget.structuredQuery.startAt = [self encodedBound:query.startAt]; + } + + if (query.endAt) { + queryTarget.structuredQuery.endAt = [self encodedBound:query.endAt]; + } + + return queryTarget; +} + +- (FSTQuery *)decodedQueryFromQueryTarget:(GCFSTarget_QueryTarget *)target { + ResourcePath path = [self decodedQueryPath:target.parent]; + + GCFSStructuredQuery *query = target.structuredQuery; + NSString *collectionGroup; + NSUInteger fromCount = query.fromArray_Count; + if (fromCount > 0) { + HARD_ASSERT(fromCount == 1, + "StructuredQuery.from with more than one collection is not supported."); + + GCFSStructuredQuery_CollectionSelector *from = query.fromArray[0]; + if (from.allDescendants) { + collectionGroup = from.collectionId; + } else { + path = path.Append(util::MakeString(from.collectionId)); + } + } + + NSArray *filterBy; + if (query.hasWhere) { + filterBy = [self decodedFilters:query.where]; + } else { + filterBy = @[]; + } + + NSArray *orderBy; + if (query.orderByArray_Count > 0) { + orderBy = [self decodedSortOrders:query.orderByArray]; + } else { + orderBy = @[]; + } + + NSInteger limit = NSNotFound; + if (query.hasLimit) { + limit = query.limit.value; + } + + FSTBound *_Nullable startAt; + if (query.hasStartAt) { + startAt = [self decodedBound:query.startAt]; + } + + FSTBound *_Nullable endAt; + if (query.hasEndAt) { + endAt = [self decodedBound:query.endAt]; + } + + return [[FSTQuery alloc] initWithPath:path + collectionGroup:collectionGroup + filterBy:filterBy + orderBy:orderBy + limit:limit + startAt:startAt + endAt:endAt]; +} + +#pragma mark Filters + +- (GCFSStructuredQuery_Filter *_Nullable)encodedFilters:(NSArray *)filters { + if (filters.count == 0) { + return nil; + } + NSMutableArray *protos = [NSMutableArray array]; + for (FSTFilter *filter in filters) { + if ([filter isKindOfClass:[FSTRelationFilter class]]) { + [protos addObject:[self encodedRelationFilter:(FSTRelationFilter *)filter]]; + } else { + [protos addObject:[self encodedUnaryFilter:filter]]; + } + } + if (protos.count == 1) { + // Special case: no existing filters and we only need to add one filter. This can be made the + // single root filter without a composite filter. + return protos[0]; + } + GCFSStructuredQuery_Filter *composite = [GCFSStructuredQuery_Filter message]; + composite.compositeFilter.op = GCFSStructuredQuery_CompositeFilter_Operator_And; + composite.compositeFilter.filtersArray = protos; + return composite; +} + +- (NSArray *)decodedFilters:(GCFSStructuredQuery_Filter *)proto { + NSMutableArray *result = [NSMutableArray array]; + + NSArray *filters; + if (proto.filterTypeOneOfCase == + GCFSStructuredQuery_Filter_FilterType_OneOfCase_CompositeFilter) { + HARD_ASSERT(proto.compositeFilter.op == GCFSStructuredQuery_CompositeFilter_Operator_And, + "Only AND-type composite filters are supported, got %s", proto.compositeFilter.op); + filters = proto.compositeFilter.filtersArray; + } else { + filters = @[ proto ]; + } + + for (GCFSStructuredQuery_Filter *filter in filters) { + switch (filter.filterTypeOneOfCase) { + case GCFSStructuredQuery_Filter_FilterType_OneOfCase_CompositeFilter: + HARD_FAIL("Nested composite filters are not supported"); + + case GCFSStructuredQuery_Filter_FilterType_OneOfCase_FieldFilter: + [result addObject:[self decodedRelationFilter:filter.fieldFilter]]; + break; + + case GCFSStructuredQuery_Filter_FilterType_OneOfCase_UnaryFilter: + [result addObject:[self decodedUnaryFilter:filter.unaryFilter]]; + break; + + default: + HARD_FAIL("Unrecognized Filter.filterType %s", filter.filterTypeOneOfCase); + } + } + return result; +} + +- (GCFSStructuredQuery_Filter *)encodedRelationFilter:(FSTRelationFilter *)filter { + GCFSStructuredQuery_Filter *proto = [GCFSStructuredQuery_Filter message]; + GCFSStructuredQuery_FieldFilter *fieldFilter = proto.fieldFilter; + fieldFilter.field = [self encodedFieldPath:filter.field]; + fieldFilter.op = [self encodedRelationFilterOperator:filter.filterOperator]; + fieldFilter.value = [self encodedFieldValue:filter.value]; + return proto; +} + +- (FSTRelationFilter *)decodedRelationFilter:(GCFSStructuredQuery_FieldFilter *)proto { + FieldPath fieldPath = FieldPath::FromServerFormat(util::MakeString(proto.field.fieldPath)); + FSTRelationFilterOperator filterOperator = [self decodedRelationFilterOperator:proto.op]; + FSTFieldValue *value = [self decodedFieldValue:proto.value]; + return [FSTRelationFilter filterWithField:fieldPath filterOperator:filterOperator value:value]; +} + +- (GCFSStructuredQuery_Filter *)encodedUnaryFilter:(FSTFilter *)filter { + GCFSStructuredQuery_Filter *proto = [GCFSStructuredQuery_Filter message]; + proto.unaryFilter.field = [self encodedFieldPath:filter.field]; + if ([filter isKindOfClass:[FSTNanFilter class]]) { + proto.unaryFilter.op = GCFSStructuredQuery_UnaryFilter_Operator_IsNan; + } else if ([filter isKindOfClass:[FSTNullFilter class]]) { + proto.unaryFilter.op = GCFSStructuredQuery_UnaryFilter_Operator_IsNull; + } else { + HARD_FAIL("Unrecognized filter: %s", filter); + } + return proto; +} + +- (FSTFilter *)decodedUnaryFilter:(GCFSStructuredQuery_UnaryFilter *)proto { + FieldPath field = FieldPath::FromServerFormat(util::MakeString(proto.field.fieldPath)); + switch (proto.op) { + case GCFSStructuredQuery_UnaryFilter_Operator_IsNan: + return [[FSTNanFilter alloc] initWithField:field]; + + case GCFSStructuredQuery_UnaryFilter_Operator_IsNull: + return [[FSTNullFilter alloc] initWithField:field]; + + default: + HARD_FAIL("Unrecognized UnaryFilter.operator %s", proto.op); + } +} + +- (GCFSStructuredQuery_FieldReference *)encodedFieldPath:(const FieldPath &)fieldPath { + GCFSStructuredQuery_FieldReference *ref = [GCFSStructuredQuery_FieldReference message]; + ref.fieldPath = util::WrapNSString(fieldPath.CanonicalString()); + return ref; +} + +- (GCFSStructuredQuery_FieldFilter_Operator)encodedRelationFilterOperator: + (FSTRelationFilterOperator)filterOperator { + switch (filterOperator) { + case FSTRelationFilterOperatorLessThan: + return GCFSStructuredQuery_FieldFilter_Operator_LessThan; + case FSTRelationFilterOperatorLessThanOrEqual: + return GCFSStructuredQuery_FieldFilter_Operator_LessThanOrEqual; + case FSTRelationFilterOperatorEqual: + return GCFSStructuredQuery_FieldFilter_Operator_Equal; + case FSTRelationFilterOperatorGreaterThanOrEqual: + return GCFSStructuredQuery_FieldFilter_Operator_GreaterThanOrEqual; + case FSTRelationFilterOperatorGreaterThan: + return GCFSStructuredQuery_FieldFilter_Operator_GreaterThan; + case FSTRelationFilterOperatorArrayContains: + return GCFSStructuredQuery_FieldFilter_Operator_ArrayContains; + default: + HARD_FAIL("Unhandled FSTRelationFilterOperator: %s", filterOperator); + } +} + +- (FSTRelationFilterOperator)decodedRelationFilterOperator: + (GCFSStructuredQuery_FieldFilter_Operator)filterOperator { + switch (filterOperator) { + case GCFSStructuredQuery_FieldFilter_Operator_LessThan: + return FSTRelationFilterOperatorLessThan; + case GCFSStructuredQuery_FieldFilter_Operator_LessThanOrEqual: + return FSTRelationFilterOperatorLessThanOrEqual; + case GCFSStructuredQuery_FieldFilter_Operator_Equal: + return FSTRelationFilterOperatorEqual; + case GCFSStructuredQuery_FieldFilter_Operator_GreaterThanOrEqual: + return FSTRelationFilterOperatorGreaterThanOrEqual; + case GCFSStructuredQuery_FieldFilter_Operator_GreaterThan: + return FSTRelationFilterOperatorGreaterThan; + case GCFSStructuredQuery_FieldFilter_Operator_ArrayContains: + return FSTRelationFilterOperatorArrayContains; + default: + HARD_FAIL("Unhandled FieldFilter.operator: %s", filterOperator); + } +} + +#pragma mark Property Orders + +- (NSArray *)encodedSortOrders:(NSArray *)orders { + NSMutableArray *protos = [NSMutableArray array]; + for (FSTSortOrder *order in orders) { + [protos addObject:[self encodedSortOrder:order]]; + } + return protos; +} + +- (NSArray *)decodedSortOrders:(NSArray *)protos { + NSMutableArray *result = [NSMutableArray arrayWithCapacity:protos.count]; + for (GCFSStructuredQuery_Order *orderProto in protos) { + [result addObject:[self decodedSortOrder:orderProto]]; + } + return result; +} + +- (GCFSStructuredQuery_Order *)encodedSortOrder:(FSTSortOrder *)sortOrder { + GCFSStructuredQuery_Order *proto = [GCFSStructuredQuery_Order message]; + proto.field = [self encodedFieldPath:sortOrder.field]; + if (sortOrder.ascending) { + proto.direction = GCFSStructuredQuery_Direction_Ascending; + } else { + proto.direction = GCFSStructuredQuery_Direction_Descending; + } + return proto; +} + +- (FSTSortOrder *)decodedSortOrder:(GCFSStructuredQuery_Order *)proto { + FieldPath fieldPath = FieldPath::FromServerFormat(util::MakeString(proto.field.fieldPath)); + BOOL ascending; + switch (proto.direction) { + case GCFSStructuredQuery_Direction_Ascending: + ascending = YES; + break; + case GCFSStructuredQuery_Direction_Descending: + ascending = NO; + break; + default: + HARD_FAIL("Unrecognized GCFSStructuredQuery_Direction %s", proto.direction); + } + return [FSTSortOrder sortOrderWithFieldPath:fieldPath ascending:ascending]; +} + +#pragma mark - Bounds/Cursors + +- (GCFSCursor *)encodedBound:(FSTBound *)bound { + GCFSCursor *proto = [GCFSCursor message]; + proto.before = bound.isBefore; + for (FSTFieldValue *fieldValue in bound.position) { + GCFSValue *value = [self encodedFieldValue:fieldValue]; + [proto.valuesArray addObject:value]; + } + return proto; +} + +- (FSTBound *)decodedBound:(GCFSCursor *)proto { + NSMutableArray *indexComponents = [NSMutableArray array]; + + for (GCFSValue *valueProto in proto.valuesArray) { + FSTFieldValue *value = [self decodedFieldValue:valueProto]; + [indexComponents addObject:value]; + } + + return [FSTBound boundWithPosition:indexComponents isBefore:proto.before]; +} + +#pragma mark - WatchChange <= GCFSListenResponse proto + +- (std::unique_ptr)decodedWatchChange:(GCFSListenResponse *)watchChange { + switch (watchChange.responseTypeOneOfCase) { + case GCFSListenResponse_ResponseType_OneOfCase_TargetChange: + return [self decodedTargetChangeFromWatchChange:watchChange.targetChange]; + + case GCFSListenResponse_ResponseType_OneOfCase_DocumentChange: + return [self decodedDocumentChange:watchChange.documentChange]; + + case GCFSListenResponse_ResponseType_OneOfCase_DocumentDelete: + return [self decodedDocumentDelete:watchChange.documentDelete]; + + case GCFSListenResponse_ResponseType_OneOfCase_DocumentRemove: + return [self decodedDocumentRemove:watchChange.documentRemove]; + + case GCFSListenResponse_ResponseType_OneOfCase_Filter: + return [self decodedExistenceFilterWatchChange:watchChange.filter]; + + default: + HARD_FAIL("Unknown WatchChange.changeType %s", watchChange.responseTypeOneOfCase); + } +} + +- (SnapshotVersion)versionFromListenResponse:(GCFSListenResponse *)watchChange { + // We have only reached a consistent snapshot for the entire stream if there is a read_time set + // and it applies to all targets (i.e. the list of targets is empty). The backend is guaranteed to + // send such responses. + if (watchChange.responseTypeOneOfCase != GCFSListenResponse_ResponseType_OneOfCase_TargetChange) { + return SnapshotVersion::None(); + } + if (watchChange.targetChange.targetIdsArray.count != 0) { + return SnapshotVersion::None(); + } + return [self decodedVersion:watchChange.targetChange.readTime]; +} + +- (std::unique_ptr)decodedTargetChangeFromWatchChange:(GCFSTargetChange *)change { + WatchTargetChangeState state = [self decodedWatchTargetChangeState:change.targetChangeType]; + __block std::vector targetIDs; + + [change.targetIdsArray enumerateValuesWithBlock:^(int32_t value, NSUInteger idx, BOOL *stop) { + targetIDs.push_back(value); + }]; + + NSData *resumeToken = change.resumeToken; + + util::Status cause; + if (change.hasCause) { + cause = util::Status{static_cast(change.cause.code), + util::MakeString(change.cause.message)}; + } + + return absl::make_unique(state, std::move(targetIDs), resumeToken, + std::move(cause)); +} + +- (WatchTargetChangeState)decodedWatchTargetChangeState:(GCFSTargetChange_TargetChangeType)state { + switch (state) { + case GCFSTargetChange_TargetChangeType_NoChange: + return WatchTargetChangeState::NoChange; + case GCFSTargetChange_TargetChangeType_Add: + return WatchTargetChangeState::Added; + case GCFSTargetChange_TargetChangeType_Remove: + return WatchTargetChangeState::Removed; + case GCFSTargetChange_TargetChangeType_Current: + return WatchTargetChangeState::Current; + case GCFSTargetChange_TargetChangeType_Reset: + return WatchTargetChangeState::Reset; + default: + HARD_FAIL("Unexpected TargetChange.state: %s", state); + } +} + +- (std::vector)decodedIntegerArray:(GPBInt32Array *)values { + __block std::vector result; + result.reserve(values.count); + [values enumerateValuesWithBlock:^(int32_t value, NSUInteger idx, BOOL *stop) { + result.push_back(value); + }]; + return result; +} + +- (std::unique_ptr)decodedDocumentChange:(GCFSDocumentChange *)change { + FSTObjectValue *value = [self decodedFields:change.document.fields]; + DocumentKey key = [self decodedDocumentKey:change.document.name]; + SnapshotVersion version = [self decodedVersion:change.document.updateTime]; + HARD_ASSERT(version != SnapshotVersion::None(), "Got a document change with no snapshot version"); + // The document may soon be re-serialized back to protos in order to store it in local + // persistence. Memoize the encoded form to avoid encoding it again. + FSTMaybeDocument *document = [FSTDocument documentWithData:value + key:key + version:version + state:FSTDocumentStateSynced + proto:change.document]; + + std::vector updatedTargetIDs = [self decodedIntegerArray:change.targetIdsArray]; + std::vector removedTargetIDs = [self decodedIntegerArray:change.removedTargetIdsArray]; + + return absl::make_unique( + std::move(updatedTargetIDs), std::move(removedTargetIDs), std::move(key), document); +} + +- (std::unique_ptr)decodedDocumentDelete:(GCFSDocumentDelete *)change { + DocumentKey key = [self decodedDocumentKey:change.document]; + // Note that version might be unset in which case we use SnapshotVersion::None() + SnapshotVersion version = [self decodedVersion:change.readTime]; + FSTMaybeDocument *document = [FSTDeletedDocument documentWithKey:key + version:version + hasCommittedMutations:NO]; + + std::vector removedTargetIDs = [self decodedIntegerArray:change.removedTargetIdsArray]; + + return absl::make_unique( + std::vector{}, std::move(removedTargetIDs), std::move(key), document); +} + +- (std::unique_ptr)decodedDocumentRemove:(GCFSDocumentRemove *)change { + DocumentKey key = [self decodedDocumentKey:change.document]; + std::vector removedTargetIDs = [self decodedIntegerArray:change.removedTargetIdsArray]; + + return absl::make_unique(std::vector{}, + std::move(removedTargetIDs), std::move(key), nil); +} + +- (std::unique_ptr)decodedExistenceFilterWatchChange:(GCFSExistenceFilter *)filter { + ExistenceFilter existenceFilter{filter.count}; + TargetId targetID = filter.targetId; + return absl::make_unique(existenceFilter, targetID); +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Util/FSTAsyncQueryListener.h b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Util/FSTAsyncQueryListener.h new file mode 100644 index 0000000..8588fbe --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Util/FSTAsyncQueryListener.h @@ -0,0 +1,46 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +#include "Firestore/core/src/firebase/firestore/core/view_snapshot.h" +#include "Firestore/core/src/firebase/firestore/util/executor.h" + +NS_ASSUME_NONNULL_BEGIN + +/** + * A wrapper class around QueryListener that dispatches events asynchronously. + */ +@interface FSTAsyncQueryListener : NSObject + +- (instancetype)initWithExecutor:(firebase::firestore::util::Executor*)executor + snapshotHandler:(firebase::firestore::core::ViewSnapshotHandler&&)snapshotHandler + NS_DESIGNATED_INITIALIZER; + +- (instancetype)init NS_UNAVAILABLE; + +/** + * Synchronously mutes the listener and raise no further events. This method is thread safe can be + * called from any queue. + */ +- (void)mute; + +/** Creates an asynchronous version of the provided snapshot handler. */ +- (firebase::firestore::core::ViewSnapshotHandler)asyncSnapshotHandler; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Util/FSTClasses.h b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Util/FSTClasses.h new file mode 100644 index 0000000..79d67c4 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Util/FSTClasses.h @@ -0,0 +1,40 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +NS_ASSUME_NONNULL_BEGIN + +// A convenience macro for unimplemented methods. Use as follows: +// +// @throw FSTAbstractMethodException(); // NOLINT +#define FSTAbstractMethodException() \ + [NSException exceptionWithName:NSInternalInconsistencyException \ + reason:[NSString stringWithFormat:@"You must override %s in a subclass", \ + __func__] \ + userInfo:nil]; + +// Declare a weak pointer to the given variable +#define FSTWeakify(var) __weak __typeof__(var) fstWeakPointerTo##var = var; + +// Declare a strong pointer to a variable that's been FSTWeakified. This creates a shadow of the +// original. +#define FSTStrongify(var) \ + _Pragma("clang diagnostic push") _Pragma("clang diagnostic ignored \"-Wshadow\"") \ + __strong __typeof__(var) var = fstWeakPointerTo##var; \ + _Pragma("clang diagnostic pop") + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Util/FSTUsageValidation.h b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Util/FSTUsageValidation.h new file mode 100644 index 0000000..afc5412 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Util/FSTUsageValidation.h @@ -0,0 +1,45 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** Helper for creating a general exception for invalid usage of an API. */ +NSException *FSTInvalidUsage(NSString *exceptionName, NSString *format, ...); + +/** + * Macro to throw exceptions in response to API usage errors. Avoids the lint warning you usually + * get when using @throw and (unlike a function) doesn't trigger warnings about not all codepaths + * returning a value. + * + * Exceptions should only be used for programmer errors made by consumers of the SDK, e.g. + * invalid method arguments. + * + * For recoverable runtime errors, use NSError**. + * For internal programming errors, use HARD_FAIL(). + */ +#define FSTThrowInvalidUsage(exceptionName, format, ...) \ + do { \ + @throw FSTInvalidUsage(exceptionName, format, ##__VA_ARGS__); \ + } while (0) + +#define FSTThrowInvalidArgument(format, ...) \ + do { \ + @throw FSTInvalidUsage(@"FIRInvalidArgumentException", format, ##__VA_ARGS__); \ + } while (0) + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Util/FSTUsageValidation.mm b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Util/FSTUsageValidation.mm new file mode 100644 index 0000000..93abf87 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/Source/Util/FSTUsageValidation.mm @@ -0,0 +1,30 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "Firestore/Source/Util/FSTUsageValidation.h" + +NS_ASSUME_NONNULL_BEGIN + +NSException *FSTInvalidUsage(NSString *exceptionName, NSString *format, ...) { + va_list arg_list; + va_start(arg_list, format); + NSString *formattedString = [[NSString alloc] initWithFormat:format arguments:arg_list]; + va_end(arg_list); + + return [[NSException alloc] initWithName:exceptionName reason:formattedString userInfo:nil]; +} + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/include/firebase/firestore/firestore_errors.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/include/firebase/firestore/firestore_errors.h new file mode 100644 index 0000000..92c0c92 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/include/firebase/firestore/firestore_errors.h @@ -0,0 +1,119 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_INCLUDE_FIREBASE_FIRESTORE_FIRESTORE_ERRORS_H_ +#define FIRESTORE_CORE_INCLUDE_FIREBASE_FIRESTORE_FIRESTORE_ERRORS_H_ + +namespace firebase { +namespace firestore { + +/** + * Error codes used by Cloud Firestore. + * + * The codes are in sync with the Firestore iOS client SDK header file + * FIRFirestoreErrors.h. + */ +enum FirestoreErrorCode { + /** + * The operation completed successfully. NSError objects will never have a + * code with this value. + */ + Ok = 0, + + /** The operation was cancelled (typically by the caller). */ + Cancelled = 1, + + /** Unknown error or an error from a different error domain. */ + Unknown = 2, + + /** + * Client specified an invalid argument. Note that this differs from + * FailedPrecondition. InvalidArgument indicates arguments that are + * problematic regardless of the state of the system (e.g., an invalid field + * name). + */ + InvalidArgument = 3, + + /** + * Deadline expired before operation could complete. For operations that + * change the state of the system, this error may be returned even if the + * operation has completed successfully. For example, a successful response + * from a server could have been delayed long enough for the deadline to + * expire. + */ + DeadlineExceeded = 4, + + /** Some requested document was not found. */ + NotFound = 5, + + /** Some document that we attempted to create already exists. */ + AlreadyExists = 6, + + /** The caller does not have permission to execute the specified operation. */ + PermissionDenied = 7, + + /** + * Some resource has been exhausted, perhaps a per-user quota, or perhaps the + * entire file system is out of space. + */ + ResourceExhausted = 8, + + /** + * Operation was rejected because the system is not in a state required for + * the operation's execution. + */ + FailedPrecondition = 9, + + /** + * The operation was aborted, typically due to a concurrency issue like + * transaction aborts, etc. + */ + Aborted = 10, + + /** Operation was attempted past the valid range. */ + OutOfRange = 11, + + /** Operation is not implemented or not supported/enabled. */ + Unimplemented = 12, + + /** + * Internal errors. Means some invariants expected by underlying system has + * been broken. If you see one of these errors, something is very broken. + */ + Internal = 13, + + /** + * The service is currently unavailable. This is a most likely a transient + * condition and may be corrected by retrying with a backoff. + */ + Unavailable = 14, + + /** Unrecoverable data loss or corruption. */ + DataLoss = 15, + + /** The request does not have valid authentication credentials for the + operation. */ + Unauthenticated = 16 +}; + +// TODO(zxu123): decide whether we actually want an Error class or just use +// enum. +using Error = FirestoreErrorCode; + +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_INCLUDE_FIREBASE_FIRESTORE_FIRESTORE_ERRORS_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/include/firebase/firestore/firestore_version.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/include/firebase/firestore/firestore_version.h new file mode 100644 index 0000000..7183040 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/include/firebase/firestore/firestore_version.h @@ -0,0 +1,31 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_INCLUDE_FIREBASE_FIRESTORE_FIRESTORE_VERSION_H_ +#define FIRESTORE_CORE_INCLUDE_FIREBASE_FIRESTORE_FIRESTORE_VERSION_H_ + +/** Version for Firestore. */ + +namespace firebase { +namespace firestore { + +/** Version string for the Firebase Firestore SDK. */ +extern const char* const kFirestoreVersionString; + +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_INCLUDE_FIREBASE_FIRESTORE_FIRESTORE_VERSION_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/include/firebase/firestore/geo_point.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/include/firebase/firestore/geo_point.h new file mode 100644 index 0000000..cc366be --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/include/firebase/firestore/geo_point.h @@ -0,0 +1,89 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_INCLUDE_FIREBASE_FIRESTORE_GEO_POINT_H_ +#define FIRESTORE_CORE_INCLUDE_FIREBASE_FIRESTORE_GEO_POINT_H_ + +namespace firebase { +namespace firestore { + +/** + * An immutable object representing a geographical point in Firestore. The point + * is represented as a latitude/longitude pair. + * + * Latitude values are in the range of [-90, 90]. + * Longitude values are in the range of [-180, 180]. + */ +class GeoPoint { + public: + /** + * Creates a `GeoPoint` with both latitude and longitude being 0. + */ + GeoPoint(); + + /** + * Creates a `GeoPoint` from the provided latitude and longitude degrees. + * + * @param latitude The latitude as number between -90 and 90. + * @param longitude The longitude as number between -180 and 180. + */ + GeoPoint(double latitude, double longitude); + + GeoPoint(const GeoPoint& other) = default; + GeoPoint(GeoPoint&& other) = default; + GeoPoint& operator=(const GeoPoint& other) = default; + GeoPoint& operator=(GeoPoint&& other) = default; + + double latitude() const { + return latitude_; + } + + double longitude() const { + return longitude_; + } + + private: + double latitude_; + double longitude_; +}; + +/** Compares against another GeoPoint. */ +bool operator<(const GeoPoint& lhs, const GeoPoint& rhs); + +inline bool operator>(const GeoPoint& lhs, const GeoPoint& rhs) { + return rhs < lhs; +} + +inline bool operator>=(const GeoPoint& lhs, const GeoPoint& rhs) { + return !(lhs < rhs); +} + +inline bool operator<=(const GeoPoint& lhs, const GeoPoint& rhs) { + return !(lhs > rhs); +} + +inline bool operator!=(const GeoPoint& lhs, const GeoPoint& rhs) { + return lhs < rhs || lhs > rhs; +} + +inline bool operator==(const GeoPoint& lhs, const GeoPoint& rhs) { + return !(lhs != rhs); +} + +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_INCLUDE_FIREBASE_FIRESTORE_GEO_POINT_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/include/firebase/firestore/timestamp.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/include/firebase/firestore/timestamp.h new file mode 100644 index 0000000..fe4ac8f --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/include/firebase/firestore/timestamp.h @@ -0,0 +1,224 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_INCLUDE_FIREBASE_FIRESTORE_TIMESTAMP_H_ +#define FIRESTORE_CORE_INCLUDE_FIREBASE_FIRESTORE_TIMESTAMP_H_ + +#include +#include +#include +#include + +#if !defined(_STLPORT_VERSION) +#include // NOLINT(build/c++11) +#endif // !defined(_STLPORT_VERSION) + +namespace firebase { + +/** + * A Timestamp represents a point in time independent of any time zone or + * calendar, represented as seconds and fractions of seconds at nanosecond + * resolution in UTC Epoch time. It is encoded using the Proleptic Gregorian + * Calendar which extends the Gregorian calendar backwards to year one. It is + * encoded assuming all minutes are 60 seconds long, i.e. leap seconds are + * "smeared" so that no leap second table is needed for interpretation. Range is + * from 0001-01-01T00:00:00Z to 9999-12-31T23:59:59.999999999Z. + * + * @see + * https://github.com/google/protobuf/blob/master/src/google/protobuf/timestamp.proto + */ +class Timestamp { + public: + /** + * Creates a new timestamp representing the epoch (with seconds and + * nanoseconds set to 0). + */ + Timestamp(); + + /** + * Creates a new timestamp. + * + * @param seconds The number of seconds of UTC time since Unix epoch + * 1970-01-01T00:00:00Z. Must be from 0001-01-01T00:00:00Z to + * 9999-12-31T23:59:59Z inclusive; otherwise, assertion failure will be + * triggered. + * @param nanoseconds The non-negative fractions of a second at nanosecond + * resolution. Negative second values with fractions must still have + * non-negative nanoseconds values that count forward in time. Must be + * from 0 to 999,999,999 inclusive; otherwise, assertion failure will be + * triggered. + */ + Timestamp(int64_t seconds, int32_t nanoseconds); + + /** + * Creates a new timestamp with the current date. + * + * The precision is up to nanoseconds, depending on the system clock. + * + * @return a new timestamp representing the current date. + */ + static Timestamp Now(); + + /** + * The number of seconds of UTC time since Unix epoch 1970-01-01T00:00:00Z. + */ + int64_t seconds() const { + return seconds_; + } + + /** + * The non-negative fractions of a second at nanosecond resolution. Negative + * second values with fractions still have non-negative nanoseconds values + * that count forward in time. + */ + int32_t nanoseconds() const { + return nanoseconds_; + } + + /** + * Converts `time_t` to a `Timestamp`. + * + * @param seconds_since_unix_epoch + * @parblock + * The number of seconds of UTC time since Unix epoch + * 1970-01-01T00:00:00Z. Can be negative to represent dates before the + * epoch. Must be from 0001-01-01T00:00:00Z to 9999-12-31T23:59:59Z + * inclusive; otherwise, assertion failure will be triggered. + * + * Note that while the epoch of `time_t` is unspecified, it's usually Unix + * epoch. If this assumption is broken, this function will produce + * incorrect results. + * @endparblock + * + * @return a new timestamp with the given number of seconds and zero + * nanoseconds. + */ + static Timestamp FromTimeT(time_t seconds_since_unix_epoch); + +#if !defined(_STLPORT_VERSION) + /** + * Converts `std::chrono::time_point` to a `Timestamp`. + * + * @param time_point + * @parblock + * The time point with system clock's epoch, which is + * presumed to be Unix epoch 1970-01-01T00:00:00Z. Can be negative to + * represent dates before the epoch. Must be from 0001-01-01T00:00:00Z to + * 9999-12-31T23:59:59Z inclusive; otherwise, assertion failure will be + * triggered. + * + * Note that while the epoch of `std::chrono::system_clock` is + * unspecified, it's usually Unix epoch. If this assumption is broken, + * this constructor will produce incorrect results. + * @endparblock + */ + static Timestamp FromTimePoint( + std::chrono::time_point time_point); + + /** + * Converts this `Timestamp` to a `time_point`. + * + * Important: if overflow would occur, the returned value will be the maximum + * or minimum value that `Duration` can hold. Note in particular that `long + * long` is insufficient to hold the full range of `Timestamp` values with + * nanosecond precision (which is why `Duration` defaults to `microseconds`). + */ + template + std::chrono::time_point ToTimePoint() const; +#endif // !defined(_STLPORT_VERSION) + + /** + * Returns a string representation of this `Timestamp` for logging/debugging + * purposes. + * + * Note: the exact string representation is unspecified and subject to change; + * don't rely on the format of the string. + */ + std::string ToString() const; + friend std::ostream& operator<<(std::ostream& out, + const Timestamp& timestamp); + + private: + // Checks that the number of seconds is within the supported date range, and + // that nanoseconds satisfy 0 <= ns <= 1second. + void ValidateBounds() const; + + int64_t seconds_ = 0; + int32_t nanoseconds_ = 0; +}; + +inline bool operator<(const Timestamp& lhs, const Timestamp& rhs) { + return lhs.seconds() < rhs.seconds() || + (lhs.seconds() == rhs.seconds() && + lhs.nanoseconds() < rhs.nanoseconds()); +} + +inline bool operator>(const Timestamp& lhs, const Timestamp& rhs) { + return rhs < lhs; +} + +inline bool operator>=(const Timestamp& lhs, const Timestamp& rhs) { + return !(lhs < rhs); +} + +inline bool operator<=(const Timestamp& lhs, const Timestamp& rhs) { + return !(lhs > rhs); +} + +inline bool operator!=(const Timestamp& lhs, const Timestamp& rhs) { + return lhs < rhs || lhs > rhs; +} + +inline bool operator==(const Timestamp& lhs, const Timestamp& rhs) { + return !(lhs != rhs); +} + +#if !defined(_STLPORT_VERSION) +template +std::chrono::time_point Timestamp::ToTimePoint() const { + namespace chr = std::chrono; + using TimePoint = chr::time_point; + + // Saturate on overflow + const auto max_seconds = chr::duration_cast(Duration::max()); + if (seconds_ > 0 && max_seconds.count() <= seconds_) { + return TimePoint{Duration::max()}; + } + const auto min_seconds = chr::duration_cast(Duration::min()); + if (seconds_ < 0 && min_seconds.count() >= seconds_) { + return TimePoint{Duration::min()}; + } + + const auto seconds = chr::duration_cast(chr::seconds(seconds_)); + const auto nanoseconds = + chr::duration_cast(chr::nanoseconds(nanoseconds_)); + return TimePoint{seconds + nanoseconds}; +} +#endif // !defined(_STLPORT_VERSION) + +} // namespace firebase + +namespace std { +template <> +struct hash { + // Note: specialization of `std::hash` is provided for convenience only. The + // implementation is subject to change. + size_t operator()(const firebase::Timestamp& timestamp) const; +}; +} // namespace std + +#endif // FIRESTORE_CORE_INCLUDE_FIREBASE_FIRESTORE_TIMESTAMP_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/api/document_reference.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/api/document_reference.h new file mode 100644 index 0000000..d107d45 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/api/document_reference.h @@ -0,0 +1,106 @@ +/* + * Copyright 2019 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_API_DOCUMENT_REFERENCE_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_API_DOCUMENT_REFERENCE_H_ + +#if !defined(__OBJC__) +#error "This header only supports Objective-C++" +#endif // !defined(__OBJC__) + +#import + +#include +#include +#include + +#import "FIRDocumentReference.h" +#import "FIRFirestoreSource.h" + +#include "Firestore/core/src/firebase/firestore/api/document_snapshot.h" +#include "Firestore/core/src/firebase/firestore/api/listener_registration.h" +#include "Firestore/core/src/firebase/firestore/core/listen_options.h" +#include "Firestore/core/src/firebase/firestore/model/document_key.h" +#include "Firestore/core/src/firebase/firestore/model/resource_path.h" +#include "Firestore/core/src/firebase/firestore/util/statusor_callback.h" + +NS_ASSUME_NONNULL_BEGIN + +@class FIRFirestore; +@class FSTMutation; + +namespace firebase { +namespace firestore { +namespace api { + +class Firestore; + +class DocumentReference { + public: + using Completion = void (^)(NSError* _Nullable error) _Nullable; + + DocumentReference() = default; + DocumentReference(model::ResourcePath path, Firestore* firestore); + DocumentReference(model::DocumentKey document_key, Firestore* firestore) + : firestore_{firestore}, key_{std::move(document_key)} { + } + + size_t Hash() const; + + Firestore* firestore() const { + return firestore_; + } + const model::DocumentKey& key() const { + return key_; + } + + const std::string& document_id() const; + + // TODO(varconst) uncomment when core API CollectionReference is implemented. + // CollectionReference Parent() const; + + std::string Path() const; + + // TODO(varconst) uncomment when core API CollectionReference is implemented. + // CollectionReference GetCollectionReference( + // const std::string& collection_path) const; + + void SetData(std::vector&& mutations, Completion completion); + + void UpdateData(std::vector&& mutations, Completion completion); + + void DeleteDocument(Completion completion); + + void GetDocument(FIRFirestoreSource source, + DocumentSnapshot::Listener&& completion); + + ListenerRegistration AddSnapshotListener( + core::ListenOptions options, DocumentSnapshot::Listener&& listener); + + private: + Firestore* firestore_ = nullptr; + model::DocumentKey key_; +}; + +bool operator==(const DocumentReference& lhs, const DocumentReference& rhs); + +} // namespace api +} // namespace firestore +} // namespace firebase + +NS_ASSUME_NONNULL_END + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_API_DOCUMENT_REFERENCE_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/api/document_reference.mm b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/api/document_reference.mm new file mode 100644 index 0000000..5e8de27 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/api/document_reference.mm @@ -0,0 +1,259 @@ +/* + * Copyright 2019 Google + * + * 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 "Firestore/core/src/firebase/firestore/api/document_reference.h" + +#include // NOLINT(build/c++11) +#include + +#import "Firestore/Source/API/FIRDocumentSnapshot+Internal.h" +#import "Firestore/Source/API/FIRFirestore+Internal.h" +#import "Firestore/Source/API/FIRListenerRegistration+Internal.h" +#import "Firestore/Source/Core/FSTEventManager.h" +#import "Firestore/Source/Core/FSTFirestoreClient.h" +#import "Firestore/Source/Core/FSTQuery.h" +#import "Firestore/Source/Model/FSTMutation.h" +#import "Firestore/Source/Util/FSTUsageValidation.h" + +#include "Firestore/core/src/firebase/firestore/core/view_snapshot.h" +#include "Firestore/core/src/firebase/firestore/model/document_key.h" +#include "Firestore/core/src/firebase/firestore/model/document_set.h" +#include "Firestore/core/src/firebase/firestore/model/precondition.h" +#include "Firestore/core/src/firebase/firestore/model/resource_path.h" +#include "Firestore/core/src/firebase/firestore/util/error_apple.h" +#include "Firestore/core/src/firebase/firestore/util/hard_assert.h" +#include "Firestore/core/src/firebase/firestore/util/hashing.h" +#include "Firestore/core/src/firebase/firestore/util/objc_compatibility.h" +#include "Firestore/core/src/firebase/firestore/util/status.h" +#include "Firestore/core/src/firebase/firestore/util/statusor.h" + +NS_ASSUME_NONNULL_BEGIN + +namespace firebase { +namespace firestore { +namespace api { + +namespace objc = util::objc; +using core::AsyncEventListener; +using core::EventListener; +using core::ViewSnapshot; +using model::DocumentKey; +using model::Precondition; +using model::ResourcePath; +using util::MakeNSError; +using util::Status; +using util::StatusOr; +using util::StatusOrCallback; + +DocumentReference::DocumentReference(model::ResourcePath path, + Firestore* firestore) + : firestore_{firestore} { + if (path.size() % 2 != 0) { + HARD_FAIL( + "Invalid document reference. Document references must have an even " + "number of segments, but %s has %s", + path.CanonicalString(), path.size()); + } + key_ = DocumentKey{std::move(path)}; +} + +size_t DocumentReference::Hash() const { + return util::Hash(firestore_, key_); +} + +const std::string& DocumentReference::document_id() const { + return key_.path().last_segment(); +} + +// TODO(varconst) uncomment when core API CollectionReference is implemented. +// CollectionReference DocumentReference::Parent() const { +// return CollectionReference{firestore_, key_.path().PopLast()}; +// } + +std::string DocumentReference::Path() const { + return key_.path().CanonicalString(); +} + +// TODO(varconst) uncomment when core API CollectionReference is implemented. +// CollectionReference DocumentReference::GetCollectionReference( +// const std::string& collection_path) const { +// ResourcePath sub_path = ResourcePath::FromString(collection_path); +// ResourcePath path = key_.path().Append(sub_path); +// return CollectionReference{firestore_, path}; +// } + +void DocumentReference::SetData(std::vector&& mutations, + Completion completion) { + [firestore_->client() writeMutations:std::move(mutations) + completion:completion]; +} + +void DocumentReference::UpdateData(std::vector&& mutations, + Completion completion) { + return [firestore_->client() writeMutations:std::move(mutations) + completion:completion]; +} + +void DocumentReference::DeleteDocument(Completion completion) { + FSTDeleteMutation* mutation = + [[FSTDeleteMutation alloc] initWithKey:key_ + precondition:Precondition::None()]; + [firestore_->client() writeMutations:{mutation} completion:completion]; +} + +void DocumentReference::GetDocument(FIRFirestoreSource source, + DocumentSnapshot::Listener&& completion) { + if (source == FIRFirestoreSourceCache) { + [firestore_->client() getDocumentFromLocalCache:*this + completion:std::move(completion)]; + return; + } + + ListenOptions options( + /*include_query_metadata_changes=*/true, + /*include_document_metadata_changes=*/true, + /*wait_for_sync_when_online=*/true); + + class ListenOnce : public EventListener { + public: + ListenOnce(FIRFirestoreSource source, + DocumentSnapshot::Listener&& completion) + : source_(source), completion_(std::move(completion)) { + } + + void OnEvent(StatusOr maybe_snapshot) override { + if (!maybe_snapshot.ok()) { + completion_->OnEvent(std::move(maybe_snapshot)); + return; + } + + DocumentSnapshot snapshot = std::move(maybe_snapshot).ValueOrDie(); + + // Remove query first before passing event to user to avoid user actions + // affecting the now stale query. + ListenerRegistration registration = + registration_promise_.get_future().get(); + registration.Remove(); + + if (!snapshot.exists() && snapshot.metadata().from_cache()) { + // TODO(dimond): Reconsider how to raise missing documents when + // offline. If we're online and the document doesn't exist then we + // call the completion with a document with document.exists set to + // false. If we're offline however, we call the completion handler + // with an error. Two options: 1) Cache the negative response from the + // server so we can deliver that even when you're offline. + // 2) Actually call the completion handler with an error if the + // document doesn't exist when you are offline. + completion_->OnEvent( + Status{FirestoreErrorCode::Unavailable, + "Failed to get document because the client is offline."}); + } else if (snapshot.exists() && snapshot.metadata().from_cache() && + source_ == FIRFirestoreSourceServer) { + completion_->OnEvent( + Status{FirestoreErrorCode::Unavailable, + "Failed to get document from server. (However, " + "this document does exist in the local cache. Run " + "again without setting source to " + "FIRFirestoreSourceServer to retrieve the cached " + "document.)"}); + } else { + completion_->OnEvent(std::move(snapshot)); + } + } + + void Resolve(ListenerRegistration&& registration) { + registration_promise_.set_value(std::move(registration)); + } + + private: + FIRFirestoreSource source_; + DocumentSnapshot::Listener completion_; + + std::promise registration_promise_; + }; + auto listener = absl::make_unique(source, std::move(completion)); + auto listener_unowned = listener.get(); + + ListenerRegistration registration = + AddSnapshotListener(std::move(options), std::move(listener)); + + listener_unowned->Resolve(std::move(registration)); +} + +ListenerRegistration DocumentReference::AddSnapshotListener( + ListenOptions options, DocumentSnapshot::Listener&& user_listener) { + FSTQuery* query = [FSTQuery queryWithPath:key_.path()]; + + // Convert from ViewSnapshots to DocumentSnapshots. + class Converter : public EventListener { + public: + Converter(DocumentReference* parent, + DocumentSnapshot::Listener&& user_listener) + : firestore_(parent->firestore_), + key_(parent->key_), + user_listener_(std::move(user_listener)) { + } + + void OnEvent(StatusOr maybe_snapshot) override { + if (!maybe_snapshot.ok()) { + user_listener_->OnEvent(maybe_snapshot.status()); + return; + } + + ViewSnapshot snapshot = std::move(maybe_snapshot).ValueOrDie(); + HARD_ASSERT(snapshot.documents().size() <= 1, + "Too many documents returned on a document query"); + FSTDocument* document = snapshot.documents().GetDocument(key_); + + bool has_pending_writes = + document ? snapshot.mutated_keys().contains(key_) + // We don't raise `has_pending_writes` for deleted documents. + : false; + + DocumentSnapshot result{firestore_, key_, document, snapshot.from_cache(), + has_pending_writes}; + user_listener_->OnEvent(std::move(result)); + } + + private: + Firestore* firestore_; + DocumentKey key_; + DocumentSnapshot::Listener user_listener_; + }; + auto view_listener = + absl::make_unique(this, std::move(user_listener)); + + // Call the view_listener on the user Executor. + auto async_listener = AsyncEventListener::Create( + firestore_->client().userExecutor, std::move(view_listener)); + + std::shared_ptr query_listener = + [firestore_->client() listenToQuery:query + options:options + listener:async_listener]; + return ListenerRegistration(firestore_->client(), std::move(async_listener), + std::move(query_listener)); +} + +bool operator==(const DocumentReference& lhs, const DocumentReference& rhs) { + return lhs.firestore() == rhs.firestore() && lhs.key() == rhs.key(); +} + +} // namespace api +} // namespace firestore +} // namespace firebase + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/api/document_snapshot.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/api/document_snapshot.h new file mode 100644 index 0000000..e0662e1 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/api/document_snapshot.h @@ -0,0 +1,114 @@ +/* + * Copyright 2019 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_API_DOCUMENT_SNAPSHOT_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_API_DOCUMENT_SNAPSHOT_H_ + +#if !defined(__OBJC__) +#error "This header only supports Objective-C++" +#endif // !defined(__OBJC__) + +#import + +#include +#include +#include + +#import "Firestore/Source/Model/FSTFieldValue.h" + +#include "Firestore/core/src/firebase/firestore/api/snapshot_metadata.h" +#include "Firestore/core/src/firebase/firestore/core/event_listener.h" +#include "Firestore/core/src/firebase/firestore/model/document_key.h" +#include "Firestore/core/src/firebase/firestore/model/field_path.h" + +NS_ASSUME_NONNULL_BEGIN + +@class FSTDocument; + +namespace firebase { +namespace firestore { +namespace api { + +class DocumentReference; +class Firestore; + +class DocumentSnapshot { + public: + using Listener = std::unique_ptr>; + + DocumentSnapshot() = default; + + DocumentSnapshot(Firestore* firestore, + model::DocumentKey document_key, + FSTDocument* _Nullable document, + SnapshotMetadata metadata) + : firestore_{firestore}, + internal_key_{std::move(document_key)}, + internal_document_{document}, + metadata_{std::move(metadata)} { + } + + DocumentSnapshot(Firestore* firestore, + model::DocumentKey document_key, + FSTDocument* _Nullable document, + bool from_cache, + bool has_pending_writes) + : firestore_{firestore}, + internal_key_{std::move(document_key)}, + internal_document_{document}, + metadata_{has_pending_writes, from_cache} { + } + + size_t Hash() const; + + bool exists() const { + return internal_document_ != nil; + } + FSTDocument* internal_document() const { + return internal_document_; + } + std::string document_id() const; + + const SnapshotMetadata& metadata() const { + return metadata_; + } + + DocumentReference CreateReference() const; + + FSTObjectValue* _Nullable GetData() const; + id _Nullable GetValue(const model::FieldPath& field_path) const; + + Firestore* firestore() const { + return firestore_; + } + + friend bool operator==(const DocumentSnapshot& lhs, + const DocumentSnapshot& rhs); + + private: + Firestore* firestore_ = nullptr; + model::DocumentKey internal_key_; + FSTDocument* internal_document_ = nil; + SnapshotMetadata metadata_; +}; + +} // namespace api +} // namespace firestore +} // namespace firebase + +NS_ASSUME_NONNULL_END + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_API_DOCUMENT_SNAPSHOT_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/api/document_snapshot.mm b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/api/document_snapshot.mm new file mode 100644 index 0000000..f07885b --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/api/document_snapshot.mm @@ -0,0 +1,66 @@ +/* + * Copyright 2019 Google + * + * 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 "Firestore/core/src/firebase/firestore/api/document_snapshot.h" + +#import "Firestore/Source/API/FIRDocumentReference+Internal.h" +#import "Firestore/Source/Model/FSTDocument.h" + +#include "Firestore/core/src/firebase/firestore/util/hashing.h" +#include "Firestore/core/src/firebase/firestore/util/objc_compatibility.h" + +NS_ASSUME_NONNULL_BEGIN + +namespace firebase { +namespace firestore { +namespace api { + +namespace objc = util::objc; +using model::DocumentKey; +using model::FieldPath; + +size_t DocumentSnapshot::Hash() const { + return util::Hash(firestore_, internal_key_, internal_document_, metadata_); +} + +DocumentReference DocumentSnapshot::CreateReference() const { + return DocumentReference{internal_key_, firestore_}; +} + +std::string DocumentSnapshot::document_id() const { + return internal_key_.path().last_segment(); +} + +FSTObjectValue* _Nullable DocumentSnapshot::GetData() const { + return internal_document_ == nil ? nil : [internal_document_ data]; +} + +id _Nullable DocumentSnapshot::GetValue(const FieldPath& field_path) const { + return [[internal_document_ data] valueForPath:field_path]; +} + +bool operator==(const DocumentSnapshot& lhs, const DocumentSnapshot& rhs) { + return lhs.firestore_ == rhs.firestore_ && + lhs.internal_key_ == rhs.internal_key_ && + objc::Equals(lhs.internal_document_, rhs.internal_document_) && + lhs.metadata_ == rhs.metadata_; +} + +} // namespace api +} // namespace firestore +} // namespace firebase + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/api/firestore.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/api/firestore.h new file mode 100644 index 0000000..4be3b0b --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/api/firestore.h @@ -0,0 +1,129 @@ +/* + * Copyright 2019 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_API_FIRESTORE_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_API_FIRESTORE_H_ + +#if !defined(__OBJC__) +#error "This header only supports Objective-C++" +#endif // !defined(__OBJC__) + +#import + +#include +#include // NOLINT(build/c++11) +#include +#include +#include "dispatch/dispatch.h" + +#include "Firestore/core/src/firebase/firestore/auth/credentials_provider.h" +#include "Firestore/core/src/firebase/firestore/model/database_id.h" +#include "Firestore/core/src/firebase/firestore/util/async_queue.h" + +NS_ASSUME_NONNULL_BEGIN + +@class FIRApp; +@class FIRCollectionReference; +@class FIRFirestore; +@class FIRFirestoreSettings; +@class FIRQuery; +@class FIRTransaction; +@class FIRWriteBatch; +@class FSTFirestoreClient; + +namespace firebase { +namespace firestore { +namespace api { + +class DocumentReference; + +class Firestore { + public: + using TransactionBlock = id _Nullable (^)(FIRTransaction*, NSError** error); + using ErrorCompletion = void (^)(NSError* _Nullable error); + using ResultOrErrorCompletion = void (^)(id _Nullable result, + NSError* _Nullable error); + + Firestore() = default; + + Firestore(std::string project_id, + std::string database, + std::string persistence_key, + std::unique_ptr credentials_provider, + std::unique_ptr worker_queue, + void* extension); + + const model::DatabaseId& database_id() const { + return database_id_; + } + + const std::string& persistence_key() const { + return persistence_key_; + } + + FSTFirestoreClient* client() { + return client_; + } + + util::AsyncQueue* worker_queue(); + + void* extension() { + return extension_; + } + + FIRFirestoreSettings* settings() const; + void set_settings(FIRFirestoreSettings* settings); + + FIRCollectionReference* GetCollection(absl::string_view collection_path); + DocumentReference GetDocument(absl::string_view document_path); + FIRWriteBatch* GetBatch(); + FIRQuery* GetCollectionGroup(NSString* collection_id); + + void RunTransaction(TransactionBlock update_block, + dispatch_queue_t queue, + ResultOrErrorCompletion completion); + + void Shutdown(ErrorCompletion completion); + + void EnableNetwork(ErrorCompletion completion); + void DisableNetwork(ErrorCompletion completion); + + private: + void EnsureClientConfigured(); + + model::DatabaseId database_id_; + std::unique_ptr credentials_provider_; + std::string persistence_key_; + FSTFirestoreClient* client_ = nil; + + // Ownership will be transferred to `FSTFirestoreClient` as soon as the + // client is created. + std::unique_ptr worker_queue_; + + void* extension_ = nullptr; + + FIRFirestoreSettings* settings_ = nil; + + mutable std::mutex mutex_; +}; + +} // namespace api +} // namespace firestore +} // namespace firebase + +NS_ASSUME_NONNULL_END + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_API_FIRESTORE_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/api/firestore.mm b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/api/firestore.mm new file mode 100644 index 0000000..e248dbc --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/api/firestore.mm @@ -0,0 +1,202 @@ +/* + * Copyright 2019 Google + * + * 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 "Firestore/core/src/firebase/firestore/api/firestore.h" + +#import "FIRFirestoreSettings.h" +#import "Firestore/Source/API/FIRCollectionReference+Internal.h" +#import "Firestore/Source/API/FIRDocumentReference+Internal.h" +#import "Firestore/Source/API/FIRFirestore+Internal.h" +#import "Firestore/Source/API/FIRQuery+Internal.h" +#import "Firestore/Source/API/FIRTransaction+Internal.h" +#import "Firestore/Source/API/FIRWriteBatch+Internal.h" +#import "Firestore/Source/Core/FSTFirestoreClient.h" +#import "Firestore/Source/Core/FSTQuery.h" + +#include "Firestore/core/src/firebase/firestore/api/document_reference.h" +#include "Firestore/core/src/firebase/firestore/auth/firebase_credentials_provider_apple.h" +#include "Firestore/core/src/firebase/firestore/core/transaction.h" +#include "Firestore/core/src/firebase/firestore/model/document_key.h" +#include "Firestore/core/src/firebase/firestore/model/resource_path.h" +#include "Firestore/core/src/firebase/firestore/util/async_queue.h" +#include "Firestore/core/src/firebase/firestore/util/executor_libdispatch.h" +#include "Firestore/core/src/firebase/firestore/util/hard_assert.h" +#include "absl/memory/memory.h" + +namespace firebase { +namespace firestore { +namespace api { + +using firebase::firestore::api::Firestore; +using firebase::firestore::auth::CredentialsProvider; +using firebase::firestore::core::DatabaseInfo; +using firebase::firestore::core::Transaction; +using firebase::firestore::model::DocumentKey; +using firebase::firestore::model::ResourcePath; +using util::AsyncQueue; +using util::Executor; +using util::ExecutorLibdispatch; + +Firestore::Firestore(std::string project_id, + std::string database, + std::string persistence_key, + std::unique_ptr credentials_provider, + std::unique_ptr worker_queue, + void* extension) + : database_id_{std::move(project_id), std::move(database)}, + credentials_provider_{std::move(credentials_provider)}, + persistence_key_{std::move(persistence_key)}, + worker_queue_{std::move(worker_queue)}, + extension_{extension} { + settings_ = [[FIRFirestoreSettings alloc] init]; +} + +AsyncQueue* Firestore::worker_queue() { + return [client_ workerQueue]; +} + +FIRFirestoreSettings* Firestore::settings() const { + std::lock_guard lock{mutex_}; + // Disallow mutation of our internal settings + return [settings_ copy]; +} + +void Firestore::set_settings(FIRFirestoreSettings* settings) { + std::lock_guard lock{mutex_}; + // As a special exception, don't throw if the same settings are passed + // repeatedly. This should make it more friendly to create a Firestore + // instance. + if (client_ && ![settings_ isEqual:settings]) { + HARD_FAIL( + "Firestore instance has already been started and its settings can " + "no longer be changed. You can only set settings before calling any " + "other methods on a Firestore instance."); + } + settings_ = [settings copy]; +} + +FIRCollectionReference* Firestore::GetCollection( + absl::string_view collection_path) { + EnsureClientConfigured(); + ResourcePath path = ResourcePath::FromString(collection_path); + return [FIRCollectionReference + referenceWithPath:path + firestore:[FIRFirestore recoverFromFirestore:this]]; +} + +DocumentReference Firestore::GetDocument(absl::string_view document_path) { + EnsureClientConfigured(); + return DocumentReference{ResourcePath::FromString(document_path), this}; +} + +FIRWriteBatch* Firestore::GetBatch() { + EnsureClientConfigured(); + FIRFirestore* wrapper = [FIRFirestore recoverFromFirestore:this]; + + return [FIRWriteBatch writeBatchWithFirestore:wrapper]; +} + +FIRQuery* Firestore::GetCollectionGroup(NSString* collection_id) { + EnsureClientConfigured(); + FIRFirestore* wrapper = [FIRFirestore recoverFromFirestore:this]; + + return + [FIRQuery referenceWithQuery:[FSTQuery queryWithPath:ResourcePath::Empty() + collectionGroup:collection_id] + firestore:wrapper]; +} + +void Firestore::RunTransaction(TransactionBlock update_block, + dispatch_queue_t queue, + ResultOrErrorCompletion completion) { + EnsureClientConfigured(); + FIRFirestore* wrapper = [FIRFirestore recoverFromFirestore:this]; + + FSTTransactionBlock wrapped_update = + ^(std::shared_ptr internal_transaction, + void (^internal_completion)(id _Nullable, NSError* _Nullable)) { + FIRTransaction* transaction = [FIRTransaction + transactionWithInternalTransaction:std::move(internal_transaction) + firestore:wrapper]; + + dispatch_async(queue, ^{ + NSError* _Nullable error = nil; + id _Nullable result = update_block(transaction, &error); + if (error) { + // Force the result to be nil in the case of an error, in case the + // user set both. + result = nil; + } + internal_completion(result, error); + }); + }; + + [client_ transactionWithRetries:5 + updateBlock:wrapped_update + completion:completion]; +} + +void Firestore::Shutdown(ErrorCompletion completion) { + if (!client_) { + if (completion) { + // We should be dispatching the callback on the user dispatch queue + // but if the client is nil here that queue was never created. + completion(nil); + } + } else { + [client_ shutdownWithCompletion:completion]; + } +} + +void Firestore::EnableNetwork(ErrorCompletion completion) { + EnsureClientConfigured(); + [client_ enableNetworkWithCompletion:completion]; +} + +void Firestore::DisableNetwork(ErrorCompletion completion) { + EnsureClientConfigured(); + [client_ disableNetworkWithCompletion:completion]; +} + +void Firestore::EnsureClientConfigured() { + std::lock_guard lock{mutex_}; + + if (!client_) { + // These values are validated elsewhere; this is just double-checking: + HARD_ASSERT(settings_.host, "FirestoreSettings.host cannot be nil."); + HARD_ASSERT(settings_.dispatchQueue, + "FirestoreSettings.dispatchQueue cannot be nil."); + + DatabaseInfo database_info(database_id_, persistence_key_, + util::MakeString(settings_.host), + settings_.sslEnabled); + + std::unique_ptr user_executor = + absl::make_unique(settings_.dispatchQueue); + + HARD_ASSERT(worker_queue_, "Expected non-null worker queue"); + client_ = + [FSTFirestoreClient clientWithDatabaseInfo:database_info + settings:settings_ + credentialsProvider:credentials_provider_.get() + userExecutor:std::move(user_executor) + workerQueue:std::move(worker_queue_)]; + } +} + +} // namespace api +} // namespace firestore +} // namespace firebase diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/api/listener_registration.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/api/listener_registration.h new file mode 100644 index 0000000..10fe4d0 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/api/listener_registration.h @@ -0,0 +1,93 @@ +/* + * Copyright 2019 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_API_LISTENER_REGISTRATION_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_API_LISTENER_REGISTRATION_H_ + +#if !defined(__OBJC__) +#error "This header only supports Objective-C++" +#endif // !defined(__OBJC__) + +#import + +#include +#include + +#include "Firestore/core/src/firebase/firestore/core/event_listener.h" +#include "Firestore/core/src/firebase/firestore/core/query_listener.h" + +@class FSTFirestoreClient; + +NS_ASSUME_NONNULL_BEGIN + +namespace firebase { +namespace firestore { +namespace api { + +/** + * An internal handle that encapsulates a user's ability to request that we + * stop listening to a query. When a user calls Remove(), ListenerRegistration + * will synchronously mute the listener and then send a request to the + * FirestoreClient to actually unlisten. + * + * ListenerRegistration will not automaticlaly stop listening if it is + * destroyed. We allow users to fire and forget listens if they never want to + * stop them. + * + * Getting shutdown code right is tricky so ListenerRegistration is very + * forgiving. It will tolerate: + * + * * Multiple calls to Remove(), + * * calls to Remove() after we send an error, + * * calls to Remove() even after deleting the App in which the listener was + * started. + */ +class ListenerRegistration { + public: + ListenerRegistration( + FSTFirestoreClient* client, + std::shared_ptr> + async_listener, + std::shared_ptr query_listener) + : client_(client), + async_listener_(std::move(async_listener)), + query_listener_(std::move(query_listener)) { + } + + /** + * Removes the listener being tracked by this FIRListenerRegistration. After + * the initial call, subsequent calls have no effect. + */ + void Remove(); + + private: + /** The client that was used to register this listen. */ + FSTFirestoreClient* client_ = nil; + + /** The async listener that is used to mute events synchronously. */ + std::weak_ptr> async_listener_; + + /** The internal QueryListener that can be used to unlisten the query. */ + std::weak_ptr query_listener_; +}; + +} // namespace api +} // namespace firestore +} // namespace firebase + +NS_ASSUME_NONNULL_END + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_API_LISTENER_REGISTRATION_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/api/listener_registration.mm b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/api/listener_registration.mm new file mode 100644 index 0000000..b885953 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/api/listener_registration.mm @@ -0,0 +1,43 @@ +/* + * Copyright 2019 Google + * + * 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 "Firestore/core/src/firebase/firestore/api/listener_registration.h" + +#import "Firestore/Source/Core/FSTFirestoreClient.h" + +namespace firebase { +namespace firestore { +namespace api { + +void ListenerRegistration::Remove() { + auto async_listener = async_listener_.lock(); + if (async_listener) { + async_listener->Mute(); + async_listener_.reset(); + } + + auto query_listener = query_listener_.lock(); + if (query_listener) { + [client_ removeListener:query_listener]; + query_listener_.reset(); + } + + client_ = nil; +} + +} // namespace api +} // namespace firestore +} // namespace firebase diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/api/query_snapshot.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/api/query_snapshot.h new file mode 100644 index 0000000..7c5f49d --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/api/query_snapshot.h @@ -0,0 +1,110 @@ +/* + * Copyright 2019 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_API_QUERY_SNAPSHOT_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_API_QUERY_SNAPSHOT_H_ + +#if !defined(__OBJC__) +#error "This header only supports Objective-C++" +#endif // !defined(__OBJC__) + +#import + +#include +#include + +#include "Firestore/core/src/firebase/firestore/api/document_snapshot.h" +#include "Firestore/core/src/firebase/firestore/api/snapshot_metadata.h" +#include "Firestore/core/src/firebase/firestore/core/view_snapshot.h" +#include "Firestore/core/src/firebase/firestore/model/document_set.h" + +NS_ASSUME_NONNULL_BEGIN + +@class FSTQuery; + +namespace firebase { +namespace firestore { +namespace api { + +/** + * A `QuerySnapshot` contains zero or more `DocumentSnapshot` objects. + */ +class QuerySnapshot { + public: + QuerySnapshot(Firestore* firestore, + FSTQuery* query, + core::ViewSnapshot&& snapshot, + SnapshotMetadata metadata) + : firestore_(firestore), + internal_query_(query), + snapshot_(std::move(snapshot)), + metadata_(std::move(metadata)) { + } + + size_t Hash() const; + + /** + * Indicates whether this `QuerySnapshot` is empty (contains no documents). + */ + bool empty() const { + return snapshot_.documents().empty(); + } + + /** The count of documents in this `QuerySnapshot`. */ + size_t size() const { + return snapshot_.documents().size(); + } + + Firestore* firestore() const { + return firestore_; + } + + FSTQuery* internal_query() const { + return internal_query_; + } + + const core::ViewSnapshot& view_snapshot() const { + return snapshot_; + } + + /** + * Metadata about this snapshot, concerning its source and if it has local + * modifications. + */ + const SnapshotMetadata& metadata() const { + return metadata_; + } + + /** Iterates over the `DocumentSnapshots` that make up this query snapshot. */ + void ForEachDocument( + const std::function& callback) const; + + friend bool operator==(const QuerySnapshot& lhs, const QuerySnapshot& rhs); + + private: + Firestore* firestore_ = nullptr; + FSTQuery* internal_query_ = nil; + core::ViewSnapshot snapshot_; + SnapshotMetadata metadata_; +}; + +} // namespace api +} // namespace firestore +} // namespace firebase + +NS_ASSUME_NONNULL_END + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_API_QUERY_SNAPSHOT_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/api/query_snapshot.mm b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/api/query_snapshot.mm new file mode 100644 index 0000000..7992cc1 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/api/query_snapshot.mm @@ -0,0 +1,71 @@ +/* + * Copyright 2019 Google + * + * 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 "Firestore/core/src/firebase/firestore/api/query_snapshot.h" + +#include + +#import "Firestore/Source/API/FIRDocumentChange+Internal.h" +#import "Firestore/Source/API/FIRDocumentSnapshot+Internal.h" +#import "Firestore/Source/API/FIRFirestore+Internal.h" +#import "Firestore/Source/API/FIRQuery+Internal.h" +#import "Firestore/Source/Core/FSTQuery.h" +#import "Firestore/Source/Model/FSTDocument.h" +#import "Firestore/Source/Util/FSTUsageValidation.h" + +#include "Firestore/core/src/firebase/firestore/core/view_snapshot.h" +#include "Firestore/core/src/firebase/firestore/model/document_set.h" +#include "Firestore/core/src/firebase/firestore/util/objc_compatibility.h" + +NS_ASSUME_NONNULL_BEGIN + +namespace firebase { +namespace firestore { +namespace api { + +namespace objc = util::objc; +using api::Firestore; +using core::ViewSnapshot; +using model::DocumentSet; + +bool operator==(const QuerySnapshot& lhs, const QuerySnapshot& rhs) { + return lhs.firestore_ == rhs.firestore_ && + objc::Equals(lhs.internal_query_, rhs.internal_query_) && + lhs.snapshot_ == rhs.snapshot_ && lhs.metadata_ == rhs.metadata_; +} + +size_t QuerySnapshot::Hash() const { + return util::Hash(firestore_, internal_query_, snapshot_, metadata_); +} + +void QuerySnapshot::ForEachDocument( + const std::function& callback) const { + DocumentSet documentSet = snapshot_.documents(); + bool from_cache = metadata_.from_cache(); + + for (FSTDocument* document : documentSet) { + bool has_pending_writes = snapshot_.mutated_keys().contains(document.key); + DocumentSnapshot snap(firestore_, document.key, document, from_cache, + has_pending_writes); + callback(std::move(snap)); + } +} + +} // namespace api +} // namespace firestore +} // namespace firebase + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/api/snapshot_metadata.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/api/snapshot_metadata.cc new file mode 100644 index 0000000..1790bfc --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/api/snapshot_metadata.cc @@ -0,0 +1,36 @@ +/* + * Copyright 2019 Google + * + * 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 "Firestore/core/src/firebase/firestore/api/snapshot_metadata.h" + +#include "Firestore/core/src/firebase/firestore/util/hashing.h" + +namespace firebase { +namespace firestore { +namespace api { + +bool operator==(const SnapshotMetadata& lhs, const SnapshotMetadata& rhs) { + return lhs.pending_writes_ == rhs.pending_writes_ && + lhs.from_cache_ == rhs.from_cache_; +} + +size_t SnapshotMetadata::Hash() const { + return util::Hash(pending_writes_, from_cache_); +} + +} // namespace api +} // namespace firestore +} // namespace firebase diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/api/snapshot_metadata.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/api/snapshot_metadata.h new file mode 100644 index 0000000..9fe2b80 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/api/snapshot_metadata.h @@ -0,0 +1,64 @@ +/* + * Copyright 2019 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_API_SNAPSHOT_METADATA_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_API_SNAPSHOT_METADATA_H_ + +#include + +namespace firebase { +namespace firestore { +namespace api { + +/** Metadata about a snapshot, describing the state of the snapshot. */ +class SnapshotMetadata { + public: + SnapshotMetadata() = default; + SnapshotMetadata(bool pending_writes, bool from_cache) + : pending_writes_(pending_writes), from_cache_(from_cache) { + } + + /** + * Returns true if the snapshot contains the result of local writes (e.g. + * set() or update() calls) that have not yet been committed to the backend. + */ + bool pending_writes() const { + return pending_writes_; + } + + /** + * Returns true if the snapshot was created from cached data rather than + * guaranteed up-to-date server data. + */ + bool from_cache() const { + return from_cache_; + } + + friend bool operator==(const SnapshotMetadata& lhs, + const SnapshotMetadata& rhs); + + size_t Hash() const; + + private: + bool pending_writes_ = false; + bool from_cache_ = false; +}; + +} // namespace api +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_API_SNAPSHOT_METADATA_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/auth/credentials_provider.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/auth/credentials_provider.cc new file mode 100644 index 0000000..d98fafb --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/auth/credentials_provider.cc @@ -0,0 +1,31 @@ +/* + * Copyright 2018 Google + * + * 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 "Firestore/core/src/firebase/firestore/auth/credentials_provider.h" + +namespace firebase { +namespace firestore { +namespace auth { + +CredentialsProvider::CredentialsProvider() : change_listener_(nullptr) { +} + +CredentialsProvider::~CredentialsProvider() { +} + +} // namespace auth +} // namespace firestore +} // namespace firebase diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/auth/credentials_provider.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/auth/credentials_provider.h new file mode 100644 index 0000000..cf952e0 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/auth/credentials_provider.h @@ -0,0 +1,83 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_AUTH_CREDENTIALS_PROVIDER_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_AUTH_CREDENTIALS_PROVIDER_H_ + +#include +#include + +#include "Firestore/core/include/firebase/firestore/firestore_errors.h" +#include "Firestore/core/src/firebase/firestore/auth/token.h" +#include "Firestore/core/src/firebase/firestore/auth/user.h" +#include "Firestore/core/src/firebase/firestore/util/statusor.h" +#include "absl/strings/string_view.h" + +namespace firebase { +namespace firestore { +namespace auth { + +// `TokenErrorListener` is a listener that gets a token or an error. +using TokenListener = std::function)>; + +// Listener notified with a credential change. +using CredentialChangeListener = std::function; + +/** + * Provides methods for getting the uid and token for the current user and + * listen for changes. + */ +class CredentialsProvider { + public: + CredentialsProvider(); + + virtual ~CredentialsProvider(); + + /** Requests token for the current user. */ + virtual void GetToken(TokenListener completion) = 0; + + /** + * Marks the last retrieved token as invalid, making the next `GetToken` + * request force refresh the token. + */ + virtual void InvalidateToken() = 0; + + /** + * Sets the listener to be notified of credential changes (sign-in / + * sign-out, token changes). It is immediately called once with the initial + * user. + * + * Call with nullptr to remove previous listener. + */ + virtual void SetCredentialChangeListener( + CredentialChangeListener changeListener) = 0; + + protected: + /** + * A listener to be notified of credential changes (sign-in / sign-out, token + * changes). It is immediately called once with the initial user. + * + * Note that this block will be called back on an arbitrary thread that is not + * the normal Firestore worker thread. + */ + CredentialChangeListener change_listener_; +}; + +} // namespace auth +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_AUTH_CREDENTIALS_PROVIDER_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/auth/empty_credentials_provider.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/auth/empty_credentials_provider.cc new file mode 100644 index 0000000..ebea459 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/auth/empty_credentials_provider.cc @@ -0,0 +1,43 @@ +/* + * Copyright 2018 Google + * + * 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 "Firestore/core/src/firebase/firestore/auth/empty_credentials_provider.h" + +namespace firebase { +namespace firestore { +namespace auth { + +void EmptyCredentialsProvider::GetToken(TokenListener completion) { + if (completion) { + // Unauthenticated token will force the GRPC fallback to use default + // settings. + completion(Token::Unauthenticated()); + } +} + +void EmptyCredentialsProvider::SetCredentialChangeListener( + CredentialChangeListener changeListener) { + if (changeListener) { + changeListener(User::Unauthenticated()); + } +} + +void EmptyCredentialsProvider::InvalidateToken() { +} + +} // namespace auth +} // namespace firestore +} // namespace firebase diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/auth/empty_credentials_provider.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/auth/empty_credentials_provider.h new file mode 100644 index 0000000..67b018e --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/auth/empty_credentials_provider.h @@ -0,0 +1,39 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_AUTH_EMPTY_CREDENTIALS_PROVIDER_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_AUTH_EMPTY_CREDENTIALS_PROVIDER_H_ + +#include "Firestore/core/src/firebase/firestore/auth/credentials_provider.h" + +namespace firebase { +namespace firestore { +namespace auth { + +/** `EmptyCredentialsProvider` always yields an empty token. */ +class EmptyCredentialsProvider : public CredentialsProvider { + public: + void GetToken(TokenListener completion) override; + void InvalidateToken() override; + void SetCredentialChangeListener( + CredentialChangeListener changeListener) override; +}; + +} // namespace auth +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_AUTH_EMPTY_CREDENTIALS_PROVIDER_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/auth/firebase_credentials_provider_apple.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/auth/firebase_credentials_provider_apple.h new file mode 100644 index 0000000..5a36ac5 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/auth/firebase_credentials_provider_apple.h @@ -0,0 +1,123 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +// Right now, FirebaseCredentialsProvider only support APPLE build. +#if !defined(__OBJC__) +#error "This header only supports Objective-C++." +#endif // !defined(__OBJC__) + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_AUTH_FIREBASE_CREDENTIALS_PROVIDER_APPLE_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_AUTH_FIREBASE_CREDENTIALS_PROVIDER_APPLE_H_ + +#import + +#include +#include // NOLINT(build/c++11) +#include + +#include "Firestore/core/src/firebase/firestore/auth/credentials_provider.h" +#include "Firestore/core/src/firebase/firestore/auth/user.h" +#include "absl/strings/string_view.h" + +@class FIRApp; +@protocol FIRAuthInterop; + +namespace firebase { +namespace firestore { +namespace auth { + +/** + * `FirebaseCredentialsProvider` uses Firebase Auth via `FIRApp` to get an auth + * token. + * + * NOTE: To simplify the implementation, it requires that you call + * `SetCredentialChangeListener()` with a non-nullptr value no more than once + * and don't call `GetToken()` after setting it to `nullptr`. + * + * This class must be implemented in a thread-safe manner since it is accessed + * from the thread backing our internal worker queue and the callbacks from + * FIRAuth will be executed on an arbitrary different thread. + * + * For non-Apple desktop build, this is right now just a stub. + */ +class FirebaseCredentialsProvider : public CredentialsProvider { + public: + // TODO(zxu123): Provide a ctor to accept the C++ Firebase Games App, which + // deals all platforms. Right now, only works for FIRApp*. + /** + * Initializes a new FirebaseCredentialsProvider. + * + * @param app The Firebase app instance associated with the credentials + * received. + * @param auth The auth instance from which to get credentials. + */ + explicit FirebaseCredentialsProvider(FIRApp* app, id auth); + + ~FirebaseCredentialsProvider() override; + + void GetToken(TokenListener completion) override; + + void SetCredentialChangeListener( + CredentialChangeListener changeListener) override; + + void InvalidateToken() override; + + private: + /** + * Most contents of the FirebaseCredentialProvider are kept in this + * Contents object and pointed to with a shared pointer. Callbacks + * registered with FirebaseAuth use weak pointers to the Contents to + * avoid races between notifications arriving and C++ object destruction. + */ + struct Contents { + Contents(FIRApp* app, id auth, User&& user) + : app(app), auth(auth), current_user(std::move(user)) { + } + + const FIRApp* app; + + const id auth; + + /** + * The current user as reported to us via our AuthStateDidChangeListener. + */ + User current_user; + + /** + * Counter used to detect if the token changed while a GetToken() request + * was outstanding. + */ + int token_counter = 0; + + std::mutex mutex; + + bool force_refresh = false; + }; + + /** + * Handle used to stop receiving auth changes once userChangeListener is + * removed. + */ + id auth_listener_handle_; + + std::shared_ptr contents_; +}; + +} // namespace auth +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_AUTH_FIREBASE_CREDENTIALS_PROVIDER_APPLE_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/auth/firebase_credentials_provider_apple.mm b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/auth/firebase_credentials_provider_apple.mm new file mode 100644 index 0000000..f167d3f --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/auth/firebase_credentials_provider_apple.mm @@ -0,0 +1,157 @@ +/* + * Copyright 2018 Google + * + * 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 "Firestore/core/src/firebase/firestore/auth/firebase_credentials_provider_apple.h" + +#import +#import +#import +#import +#import + +#include "Firestore/core/src/firebase/firestore/util/hard_assert.h" +#include "Firestore/core/src/firebase/firestore/util/string_apple.h" + +// NB: This is also defined in Firestore/Source/Public/FIRFirestoreErrors.h +// NOLINTNEXTLINE: public constant +NSString* const FIRFirestoreErrorDomain = @"FIRFirestoreErrorDomain"; + +namespace firebase { +namespace firestore { +namespace auth { + +FirebaseCredentialsProvider::FirebaseCredentialsProvider( + FIRApp* app, id auth) { + contents_ = + std::make_shared(app, auth, User::FromUid([auth getUserID])); + std::weak_ptr weak_contents = contents_; + + auth_listener_handle_ = [[NSNotificationCenter defaultCenter] + addObserverForName:FIRAuthStateDidChangeInternalNotification + object:nil + queue:nil + usingBlock:^(NSNotification* notification) { + std::shared_ptr contents = weak_contents.lock(); + if (!contents) { + return; + } + + std::unique_lock lock(contents->mutex); + NSDictionary* user_info = notification.userInfo; + + // ensure we're only notifying for the current app. + FIRApp* notified_app = + user_info[FIRAuthStateDidChangeInternalNotificationAppKey]; + if (![contents->app isEqual:notified_app]) { + return; + } + + NSString* user_id = + user_info[FIRAuthStateDidChangeInternalNotificationUIDKey]; + contents->current_user = User::FromUid(user_id); + contents->token_counter++; + CredentialChangeListener listener = change_listener_; + if (listener) { + listener(contents->current_user); + } + }]; +} + +FirebaseCredentialsProvider::~FirebaseCredentialsProvider() { + if (auth_listener_handle_) { + // Even though iOS 9 (and later) and macOS 10.11 (and later) keep a weak + // reference to the observer so we could avoid this removeObserver call, we + // still support iOS 8 which requires it. + [[NSNotificationCenter defaultCenter] removeObserver:auth_listener_handle_]; + } +} + +void FirebaseCredentialsProvider::GetToken(TokenListener completion) { + HARD_ASSERT(auth_listener_handle_, + "GetToken cannot be called after listener removed."); + + // Take note of the current value of the tokenCounter so that this method can + // fail if there is a token change while the request is outstanding. + int initial_token_counter = contents_->token_counter; + + std::weak_ptr weak_contents = contents_; + void (^get_token_callback)(NSString*, NSError*) = ^( + NSString* _Nullable token, NSError* _Nullable error) { + std::shared_ptr contents = weak_contents.lock(); + if (!contents) { + return; + } + + std::unique_lock lock(contents->mutex); + if (initial_token_counter != contents->token_counter) { + // Cancel the request since the user changed while the request was + // outstanding so the response is likely for a previous user (which + // user, we can't be sure). + completion(util::Status(FirestoreErrorCode::Aborted, + "getToken aborted due to token change.")); + } else { + if (error == nil) { + if (token != nil) { + completion(Token{util::MakeString(token), contents->current_user}); + } else { + completion(Token::Unauthenticated()); + } + } else { + FirestoreErrorCode error_code = FirestoreErrorCode::Unknown; + if (error.domain == FIRFirestoreErrorDomain) { + error_code = static_cast(error.code); + } + completion(util::Status(error_code, + util::MakeString(error.localizedDescription))); + } + } + }; + + // TODO(wilhuff): Need a better abstraction over a missing auth provider. + if (contents_->auth) { + [contents_->auth getTokenForcingRefresh:contents_->force_refresh + withCallback:get_token_callback]; + } else { + // If there's no Auth provider, call back immediately with a nil + // (unauthenticated) token. + get_token_callback(nil, nil); + } + contents_->force_refresh = false; +} + +void FirebaseCredentialsProvider::InvalidateToken() { + contents_->force_refresh = true; +} + +void FirebaseCredentialsProvider::SetCredentialChangeListener( + CredentialChangeListener changeListener) { + std::unique_lock lock(contents_->mutex); + if (changeListener) { + HARD_ASSERT(!change_listener_, "set change_listener twice!"); + // Fire initial event. + changeListener(contents_->current_user); + } else { + HARD_ASSERT(auth_listener_handle_, "removed change_listener twice!"); + HARD_ASSERT(change_listener_, "change_listener removed without being set!"); + [[NSNotificationCenter defaultCenter] removeObserver:auth_listener_handle_]; + auth_listener_handle_ = nil; + } + change_listener_ = changeListener; +} + +} // namespace auth +} // namespace firestore +} // namespace firebase diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/auth/token.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/auth/token.cc new file mode 100644 index 0000000..a317692 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/auth/token.cc @@ -0,0 +1,37 @@ +/* + * Copyright 2018 Google + * + * 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 "Firestore/core/src/firebase/firestore/auth/token.h" + +#include + +namespace firebase { +namespace firestore { +namespace auth { + +Token::Token(std::string token, User user) + : token_{std::move(token)}, user_{std::move(user)} { +} + +const Token& Token::Unauthenticated() { + static const Token kUnauthenticatedToken(std::string{}, + User::Unauthenticated()); + return kUnauthenticatedToken; +} + +} // namespace auth +} // namespace firestore +} // namespace firebase diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/auth/token.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/auth/token.h new file mode 100644 index 0000000..cce20ee --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/auth/token.h @@ -0,0 +1,79 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_AUTH_TOKEN_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_AUTH_TOKEN_H_ + +#include + +#include "Firestore/core/src/firebase/firestore/auth/user.h" +#include "Firestore/core/src/firebase/firestore/util/hard_assert.h" +#include "absl/strings/string_view.h" + +namespace firebase { +namespace firestore { +namespace auth { + +/** + * The current User and the authentication token provided by the underlying + * authentication mechanism. This is the result of calling + * CredentialsProvider::GetToken(). + * + * ## Portability notes: no TokenType on iOS + * + * The TypeScript client supports 1st party Oauth tokens (for the Firebase + * Console to auth as the developer) and OAuth2 tokens for the node.js sdk to + * auth with a service account. We don't have plans to support either case on + * mobile so there's no TokenType here. + */ +// TODO(zxu123): Make this support token-type for desktop workflow. +class Token { + public: + Token(std::string token, User user); + + /** The actual raw token. */ + const std::string& token() const { + HARD_ASSERT(user_.is_authenticated()); + return token_; + } + + /** + * The user with which the token is associated (used for persisting user + * state on disk, etc.). + */ + const User& user() const { + return user_; + } + + /** + * Returns a token for an unauthenticated user. + * + * ## Portability notes: An unauthenticated token is the equivalent of + * nil/null in the iOS/TypeScript token implementation. We use a reference + * instead of a pointer for Token instances in the C++ migration. + */ + static const Token& Unauthenticated(); + + private: + const std::string token_; + const User user_; +}; + +} // namespace auth +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_AUTH_TOKEN_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/auth/user.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/auth/user.cc new file mode 100644 index 0000000..501e522 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/auth/user.cc @@ -0,0 +1,41 @@ +/* + * Copyright 2018 Google + * + * 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 "Firestore/core/src/firebase/firestore/auth/user.h" + +#include + +#include "Firestore/core/src/firebase/firestore/util/hard_assert.h" + +namespace firebase { +namespace firestore { +namespace auth { + +User::User() : is_authenticated_{false} { +} + +User::User(std::string uid) : uid_{std::move(uid)}, is_authenticated_{true} { + HARD_ASSERT(!uid_.empty()); +} + +const User& User::Unauthenticated() { + static const User kUnauthenticated; + return kUnauthenticated; +} + +} // namespace auth +} // namespace firestore +} // namespace firebase diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/auth/user.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/auth/user.h new file mode 100644 index 0000000..f782b6e --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/auth/user.h @@ -0,0 +1,103 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_AUTH_USER_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_AUTH_USER_H_ + +#if defined(__OBJC__) +#import +#include "Firestore/core/src/firebase/firestore/util/string_apple.h" +#endif // defined(__OBJC__) + +#include + +#include "absl/strings/string_view.h" + +namespace firebase { +namespace firestore { +namespace auth { + +/** + * Simple wrapper around a nullable UID. Mostly exists to make code more + * readable and for compatibility with other clients where map keys cannot be + * null. + */ +class User { + public: + /** Construct an unauthenticated user. */ + User(); + + /** Construct an authenticated user with the given UID. */ + explicit User(std::string uid); + + const std::string& uid() const { + return uid_; + } + + // PORTING NOTE: Here use more clear naming is_authenticated() instead of + // is_unauthenticated(). + bool is_authenticated() const { + return is_authenticated_; + } + + /** Returns an unauthenticated instance. */ + static const User& Unauthenticated(); + +#if defined(__OBJC__) + /** + * Returns an authenticated user if uid is non-nil, otherwise an + * unauthenticated user. + */ + static User FromUid(NSString* _Nullable uid) { + if (uid == nil) { + return Unauthenticated(); + } else { + return User{util::MakeString(uid)}; + } + } +#endif // defined(__OBJC__) + + User& operator=(const User& other) = default; + + friend bool operator==(const User& lhs, const User& rhs); + + private: + std::string uid_; + bool is_authenticated_; +}; + +inline bool operator==(const User& lhs, const User& rhs) { + return lhs.is_authenticated_ == rhs.is_authenticated_ && + (!lhs.is_authenticated_ || lhs.uid_ == rhs.uid_); +} + +inline bool operator!=(const User& lhs, const User& rhs) { + return !(lhs == rhs); +} + +// Specializations of std::hash is prohibited. We define a hash function to be +// passed through manually. +struct HashUser { + inline int64_t operator()(const User& user) const { + return std::hash{}(user.uid()); + } +}; + +} // namespace auth +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_AUTH_USER_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/core/database_info.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/core/database_info.cc new file mode 100644 index 0000000..c0960bc --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/core/database_info.cc @@ -0,0 +1,38 @@ +/* + * Copyright 2018 Google + * + * 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 "Firestore/core/src/firebase/firestore/core/database_info.h" + +#include + +namespace firebase { +namespace firestore { +namespace core { + +DatabaseInfo::DatabaseInfo( + const firebase::firestore::model::DatabaseId& database_id, + std::string persistence_key, + std::string host, + bool ssl_enabled) + : database_id_{database_id}, + persistence_key_{std::move(persistence_key)}, + host_{std::move(host)}, + ssl_enabled_{ssl_enabled} { +} + +} // namespace core +} // namespace firestore +} // namespace firebase diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/core/database_info.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/core/database_info.h new file mode 100644 index 0000000..138aead --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/core/database_info.h @@ -0,0 +1,78 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_CORE_DATABASE_INFO_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_CORE_DATABASE_INFO_H_ + +#include + +#include "Firestore/core/src/firebase/firestore/model/database_id.h" + +namespace firebase { +namespace firestore { +namespace core { + +/** DatabaseInfo contains data about the database. */ +class DatabaseInfo { + public: +#if defined(__OBJC__) + // For objective-c++ initialization; to be removed after migration. + // Do NOT use in C++ code. + DatabaseInfo() = default; +#endif // defined(__OBJC__) + + /** + * Creates a new DatabaseInfo. + * + * @param database_id The project/database to use. + * @param persistence_key A unique identifier for this Firestore's local + * storage. Usually derived from -[FIRApp appName]. + * @param host The hostname of the Firestore backend. + * @param ssl_enabled Whether to use SSL when connecting. + */ + DatabaseInfo(const firebase::firestore::model::DatabaseId& database_id, + std::string persistence_key, + std::string host, + bool ssl_enabled); + + const firebase::firestore::model::DatabaseId& database_id() const { + return database_id_; + } + + const std::string& persistence_key() const { + return persistence_key_; + } + + const std::string& host() const { + return host_; + } + + bool ssl_enabled() const { + return ssl_enabled_; + } + + private: + firebase::firestore::model::DatabaseId database_id_; + std::string persistence_key_; + std::string host_; + bool ssl_enabled_; +}; + +} // namespace core +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_CORE_DATABASE_INFO_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/core/event_listener.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/core/event_listener.h new file mode 100644 index 0000000..dcb9b80 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/core/event_listener.h @@ -0,0 +1,144 @@ +/* + * Copyright 2019 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_CORE_EVENT_LISTENER_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_CORE_EVENT_LISTENER_H_ + +#include +#include +#include + +#include "Firestore/core/src/firebase/firestore/util/executor.h" +#include "Firestore/core/src/firebase/firestore/util/statusor.h" +#include "Firestore/core/src/firebase/firestore/util/statusor_callback.h" +#include "absl/memory/memory.h" + +namespace firebase { +namespace firestore { +namespace core { + +/** + * A general interface for listening to events internally. + */ +template +class EventListener { + public: + static std::unique_ptr> Create( + util::StatusOrCallback callback); + + virtual ~EventListener() { + } + + /** + * OnEvent will be called with the new value or the error if an error + * occurred. + * + * @param maybe_value The value of the event or the error. + */ + virtual void OnEvent(util::StatusOr maybe_value) = 0; +}; + +/** + * A wrapper around another EventListener that dispatches events asynchronously. + */ +template +class AsyncEventListener + : public EventListener, + public std::enable_shared_from_this> { + public: + using DelegateListener = std::unique_ptr>; + + AsyncEventListener(util::Executor* executor, DelegateListener&& delegate) + : executor_(executor), delegate_(std::move(delegate)) { + // std::atomic's constructor is not atomic, so assign after contruction + // (since assignment is atomic). + muted_ = false; + } + + static std::shared_ptr> Create( + util::Executor* executor, DelegateListener&& delegate); + + static std::shared_ptr> Create( + util::Executor* executor, EventListener&& delegate) { + return Create(executor, + absl::make_unique(std::move(delegate))); + } + + void OnEvent(util::StatusOr maybe_value) override; + + /** + * Synchronously mutes the listener and raises no further events. This method + * is thread safe and can be called from any queue. + */ + void Mute(); + + private: + std::atomic muted_; + util::Executor* executor_; + DelegateListener delegate_; +}; + +template +std::unique_ptr> EventListener::Create( + util::StatusOrCallback callback) { + class CallbackEventListener : public EventListener { + public: + explicit CallbackEventListener(util::StatusOrCallback&& callback) + : callback_(std::move(callback)) { + } + + void OnEvent(util::StatusOr maybe_value) override { + callback_(std::move(maybe_value)); + } + + private: + util::StatusOrCallback callback_; + }; + + return absl::make_unique(std::move(callback)); +} + +template +std::shared_ptr> AsyncEventListener::Create( + util::Executor* executor, DelegateListener&& delegate) { + return std::make_shared>(executor, std::move(delegate)); +} + +template +void AsyncEventListener::Mute() { + muted_ = true; +} + +template +void AsyncEventListener::OnEvent(util::StatusOr maybe_value) { + // Retain a strong reference to this. If the EventManager is sending an error + // it will immediately clear its strong reference to this after posting the + // event. The strong reference here allows the AsyncEventListener to survive + // until the executor gets around to calling. + std::shared_ptr> shared_this = this->shared_from_this(); + + executor_->Execute([shared_this, maybe_value]() { + if (!shared_this->muted_) { + shared_this->delegate_->OnEvent(std::move(maybe_value)); + } + }); +} + +} // namespace core +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_CORE_EVENT_LISTENER_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/core/filter.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/core/filter.cc new file mode 100644 index 0000000..ea0fab3 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/core/filter.cc @@ -0,0 +1,41 @@ +/* + * Copyright 2018 Google + * + * 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 "Firestore/core/src/firebase/firestore/core/filter.h" + +#include + +#include "Firestore/core/src/firebase/firestore/core/relation_filter.h" + +namespace firebase { +namespace firestore { +namespace core { + +using model::FieldPath; +using model::FieldValue; + +std::shared_ptr Filter::Create(FieldPath path, + Operator op, + FieldValue value_rhs) { + // TODO(rsgowman): Java performs a number of checks here, and then invokes the + // ctor of the relevant Filter subclass. Port those checks here. + return std::make_shared(std::move(path), op, + std::move(value_rhs)); +} + +} // namespace core +} // namespace firestore +} // namespace firebase diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/core/filter.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/core/filter.h new file mode 100644 index 0000000..4748566 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/core/filter.h @@ -0,0 +1,70 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_CORE_FILTER_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_CORE_FILTER_H_ + +#include +#include + +#include "Firestore/core/src/firebase/firestore/model/document.h" +#include "Firestore/core/src/firebase/firestore/model/field_path.h" +#include "Firestore/core/src/firebase/firestore/model/field_value.h" + +namespace firebase { +namespace firestore { +namespace core { + +/** Interface used for all query filters. All filters are immutable. */ +class Filter { + public: + enum class Operator { + LessThan, + LessThanOrEqual, + Equal, + GreaterThan, + GreaterThanOrEqual, + }; + + /** + * Creates a Filter instance for the provided path, operator, and value. + * + * Note that if the relational operator is Equal and the value is NullValue or + * NaN, then this will return the appropriate NullFilter or NaNFilter class + * instead of a RelationFilter. + */ + static std::shared_ptr Create(model::FieldPath path, + Operator op, + model::FieldValue value_rhs); + + virtual ~Filter() { + } + + /** Returns the field the Filter operates over. */ + virtual const model::FieldPath& field() const = 0; + + /** Returns true if a document matches the filter. */ + virtual bool Matches(const model::Document& doc) const = 0; + + /** A unique ID identifying the filter; used when serializing queries. */ + virtual std::string CanonicalId() const = 0; +}; + +} // namespace core +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_CORE_FILTER_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/core/listen_options.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/core/listen_options.h new file mode 100644 index 0000000..913fe86 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/core/listen_options.h @@ -0,0 +1,91 @@ +/* + * Copyright 2019 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_CORE_LISTEN_OPTIONS_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_CORE_LISTEN_OPTIONS_H_ + +namespace firebase { +namespace firestore { +namespace core { + +class ListenOptions { + public: + ListenOptions() = default; + + /** + * Creates a new ListenOptions. + * + * @param include_query_metadata_changes Raise events when only metadata of + * the query changes. + * @param include_document_metadata_changes Raise events when only metadata of + * documents changes. + * @param wait_for_sync_when_online Wait for a sync with the server when + * online, but still raise events while offline + */ + ListenOptions(bool include_query_metadata_changes, + bool include_document_metadata_changes, + bool wait_for_sync_when_online) + : include_query_metadata_changes_(include_query_metadata_changes), + include_document_metadata_changes_(include_document_metadata_changes), + wait_for_sync_when_online_(wait_for_sync_when_online) { + } + + /** + * Creates a default ListenOptions, with metadata changes and + * wait_for_sync_when_online disabled. + */ + static ListenOptions DefaultOptions() { + return ListenOptions( + /*include_query_metadata_changes=*/false, + /*include_document_metadata_changes=*/false, + /*wait_for_sync_when_online=*/false); + } + + /** + * Creates a ListenOptions which optionally includes both query and document + * metadata changes. + */ + static ListenOptions FromIncludeMetadataChanges( + bool include_metadata_changes) { + return ListenOptions( + /*include_query_metadata_changes=*/include_metadata_changes, + /*include_document_metadata_changes=*/include_metadata_changes, + /*wait_for_sync_when_online=*/false); + } + + bool include_query_metadata_changes() const { + return include_query_metadata_changes_; + } + + bool include_document_metadata_changes() const { + return include_document_metadata_changes_; + } + + bool wait_for_sync_when_online() const { + return wait_for_sync_when_online_; + } + + private: + bool include_query_metadata_changes_ = false; + bool include_document_metadata_changes_ = false; + bool wait_for_sync_when_online_ = false; +}; + +} // namespace core +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_CORE_LISTEN_OPTIONS_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/core/query.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/core/query.cc new file mode 100644 index 0000000..0c0a0fd --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/core/query.cc @@ -0,0 +1,79 @@ +/* + * Copyright 2018 Google + * + * 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 "Firestore/core/src/firebase/firestore/core/query.h" + +#include + +#include "Firestore/core/src/firebase/firestore/model/document_key.h" +#include "Firestore/core/src/firebase/firestore/model/field_path.h" +#include "Firestore/core/src/firebase/firestore/model/resource_path.h" +#include "Firestore/core/src/firebase/firestore/util/hard_assert.h" + +namespace firebase { +namespace firestore { +namespace core { + +using model::Document; +using model::DocumentKey; +using model::ResourcePath; + +bool Query::Matches(const Document& doc) const { + return MatchesPath(doc) && MatchesOrderBy(doc) && MatchesFilters(doc) && + MatchesBounds(doc); +} + +bool Query::MatchesPath(const Document& doc) const { + ResourcePath doc_path = doc.key().path(); + if (DocumentKey::IsDocumentKey(path_)) { + return path_ == doc_path; + } else { + return path_.IsPrefixOf(doc_path) && path_.size() == doc_path.size() - 1; + } +} + +bool Query::MatchesFilters(const Document& doc) const { + return std::all_of(filters_.begin(), filters_.end(), + [&](const std::shared_ptr& filter) { + return filter->Matches(doc); + }); +} + +bool Query::MatchesOrderBy(const Document&) const { + // TODO(rsgowman): Implement this correctly. + return true; +} + +bool Query::MatchesBounds(const Document&) const { + // TODO(rsgowman): Implement this correctly. + return true; +} + +Query Query::Filter(std::shared_ptr filter) const { + HARD_ASSERT(!DocumentKey::IsDocumentKey(path_), + "No filter is allowed for document query"); + + // TODO(rsgowman): ensure only one inequality field + // TODO(rsgowman): ensure first orderby must match inequality field + + std::vector> updated_filters = filters_; + updated_filters.push_back(std::move(filter)); + return Query(path_, std::move(updated_filters)); +} + +} // namespace core +} // namespace firestore +} // namespace firebase diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/core/query.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/core/query.h new file mode 100644 index 0000000..1d9bb37 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/core/query.h @@ -0,0 +1,115 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_CORE_QUERY_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_CORE_QUERY_H_ + +#include +#include +#include + +#include "Firestore/core/src/firebase/firestore/core/filter.h" +#include "Firestore/core/src/firebase/firestore/model/document.h" +#include "Firestore/core/src/firebase/firestore/model/resource_path.h" + +namespace firebase { +namespace firestore { +namespace core { + +/** + * Represents the internal structure of a Firestore Query. Query instances are + * immutable. + */ +class Query { + public: + /** + * Creates and returns a new Query. + * + * @param path The path to the collection to be queried over. + * @return A new instance of Query. + */ + static Query AtPath(model::ResourcePath path) { + return Query(std::move(path), {}); + } + + static Query Invalid() { + return Query::AtPath(model::ResourcePath::Empty()); + } + + /** Initializes a query with all of its components directly. */ + Query(model::ResourcePath path, + std::vector> + filters /* TODO(rsgowman): other params */) + : path_(std::move(path)), filters_(std::move(filters)) { + } + + /** The base path of the query. */ + const model::ResourcePath& path() const { + return path_; + } + + /** The filters on the documents returned by the query. */ + const std::vector>& filters() const { + return filters_; + } + + /** Returns true if the document matches the constraints of this query. */ + bool Matches(const model::Document& doc) const; + + /** Returns true if this Query is for a specific document. */ + bool IsDocumentQuery() const { + return model::DocumentKey::IsDocumentKey(path_) && filters_.empty(); + } + + /** + * Returns a copy of this Query object with the additional specified filter. + */ + Query Filter(std::shared_ptr filter) const; + + private: + bool MatchesPath(const model::Document& doc) const; + bool MatchesFilters(const model::Document& doc) const; + bool MatchesOrderBy(const model::Document& doc) const; + bool MatchesBounds(const model::Document& doc) const; + + model::ResourcePath path_; + + // Filters are shared across related Query instance. i.e. when you call + // Query::Filter(f), a new Query instance is created that contains all of the + // existing filters, plus the new one. (Both Query and Filter objects are + // immutable.) Filters are not shared across unrelated Query instances. + std::vector> filters_; + + // TODO(rsgowman): Port collection group queries logic. +}; + +inline bool operator==(const Query& lhs, const Query& rhs) { + // TODO(rsgowman): check limit (once it exists) + // TODO(rsgowman): check orderby (once it exists) + // TODO(rsgowman): check startat (once it exists) + // TODO(rsgowman): check endat (once it exists) + return lhs.path() == rhs.path() && lhs.filters() == rhs.filters(); +} + +inline bool operator!=(const Query& lhs, const Query& rhs) { + return !(lhs == rhs); +} + +} // namespace core +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_CORE_QUERY_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/core/query_listener.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/core/query_listener.h new file mode 100644 index 0000000..60cf13c --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/core/query_listener.h @@ -0,0 +1,134 @@ +/* + * Copyright 2019 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_CORE_QUERY_LISTENER_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_CORE_QUERY_LISTENER_H_ + +#if !defined(__OBJC__) +#error "This header only supports Objective-C++" +#endif // !defined(__OBJC__) + +#import + +#include +#include + +#include "Firestore/core/src/firebase/firestore/core/listen_options.h" +#include "Firestore/core/src/firebase/firestore/core/view_snapshot.h" +#include "Firestore/core/src/firebase/firestore/model/types.h" +#include "Firestore/core/src/firebase/firestore/util/status.h" +#include "Firestore/core/src/firebase/firestore/util/statusor_callback.h" +#include "absl/types/optional.h" + +@class FSTQuery; + +NS_ASSUME_NONNULL_BEGIN + +namespace firebase { +namespace firestore { +namespace core { + +/** + * QueryListener takes a series of internal view snapshots and determines when + * to raise user-facing events. + */ +class QueryListener { + public: + static std::shared_ptr Create( + FSTQuery* query, + ListenOptions options, + ViewSnapshot::SharedListener&& listener) { + return std::make_shared(query, std::move(options), + std::move(listener)); + } + + static std::shared_ptr Create( + FSTQuery* query, ViewSnapshot::SharedListener&& listener) { + return Create(query, ListenOptions::DefaultOptions(), std::move(listener)); + } + + static std::shared_ptr Create( + FSTQuery* query, + ListenOptions options, + util::StatusOrCallback&& listener) { + auto event_listener = + EventListener::Create(std::move(listener)); + return Create(query, std::move(options), std::move(event_listener)); + } + + static std::shared_ptr Create( + FSTQuery* query, util::StatusOrCallback&& listener) { + return Create(query, ListenOptions::DefaultOptions(), std::move(listener)); + } + + QueryListener(FSTQuery* query, + ListenOptions options, + ViewSnapshot::SharedListener&& listener) + : query_(query), + options_(std::move(options)), + listener_(std::move(listener)) { + } + virtual ~QueryListener() { + } + + FSTQuery* query() const { + return query_; + } + + /** The last received view snapshot. */ + const absl::optional& snapshot() const { + return snapshot_; + } + + virtual void OnViewSnapshot(ViewSnapshot snapshot); + virtual void OnError(util::Status error); + virtual void OnOnlineStateChanged(model::OnlineState online_state); + + private: + bool ShouldRaiseInitialEvent(const ViewSnapshot& snapshot, + model::OnlineState online_state) const; + bool ShouldRaiseEvent(const ViewSnapshot& snapshot) const; + void RaiseInitialEvent(const ViewSnapshot& snapshot); + + FSTQuery* query_ = nil; + ListenOptions options_; + + /** + * The EventListener that will process ViewSnapshots associated with this + * query listener. + */ + ViewSnapshot::SharedListener listener_; + + /** + * Initial snapshots (e.g. from cache) may not be propagated to the + * ViewSnapshotHandler. This flag is set to true once we've actually raised an + * event. + */ + bool raised_initial_event_ = false; + + /** The last online state this query listener got. */ + model::OnlineState online_state_ = model::OnlineState::Unknown; + + absl::optional snapshot_; +}; + +} // namespace core +} // namespace firestore +} // namespace firebase + +NS_ASSUME_NONNULL_END + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_CORE_QUERY_LISTENER_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/core/query_listener.mm b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/core/query_listener.mm new file mode 100644 index 0000000..df901f8 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/core/query_listener.mm @@ -0,0 +1,147 @@ +/* + * Copyright 2019 Google + * + * 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. + */ + +#import "Firestore/core/src/firebase/firestore/core/query_listener.h" + +#include +#include + +#include "Firestore/core/src/firebase/firestore/model/document_set.h" +#include "Firestore/core/src/firebase/firestore/util/error_apple.h" +#include "Firestore/core/src/firebase/firestore/util/hard_assert.h" +#include "Firestore/core/src/firebase/firestore/util/status.h" +#include "absl/types/optional.h" + +NS_ASSUME_NONNULL_BEGIN + +namespace firebase { +namespace firestore { +namespace core { + +using model::OnlineState; +using model::TargetId; +using util::MakeStatus; +using util::Status; + +void QueryListener::OnViewSnapshot(ViewSnapshot snapshot) { + HARD_ASSERT( + !snapshot.document_changes().empty() || snapshot.sync_state_changed(), + "We got a new snapshot with no changes?"); + + if (!options_.include_document_metadata_changes()) { + // Remove the metadata-only changes. + std::vector changes; + for (const DocumentViewChange& change : snapshot.document_changes()) { + if (change.type() != DocumentViewChange::Type::kMetadata) { + changes.push_back(change); + } + } + + snapshot = ViewSnapshot{snapshot.query(), + snapshot.documents(), + snapshot.old_documents(), + std::move(changes), + snapshot.mutated_keys(), + snapshot.from_cache(), + snapshot.sync_state_changed(), + /*excludes_metadata_changes=*/true}; + } + + if (!raised_initial_event_) { + if (ShouldRaiseInitialEvent(snapshot, online_state_)) { + RaiseInitialEvent(snapshot); + } + } else if (ShouldRaiseEvent(snapshot)) { + listener_->OnEvent(snapshot); + } + + snapshot_ = std::move(snapshot); +} + +void QueryListener::OnError(Status error) { + listener_->OnEvent(std::move(error)); +} + +void QueryListener::OnOnlineStateChanged(OnlineState online_state) { + online_state_ = online_state; + if (snapshot_.has_value() && !raised_initial_event_ && + ShouldRaiseInitialEvent(snapshot_.value(), online_state)) { + RaiseInitialEvent(snapshot_.value()); + } +} + +bool QueryListener::ShouldRaiseInitialEvent(const ViewSnapshot& snapshot, + OnlineState online_state) const { + HARD_ASSERT(!raised_initial_event_, "Determining whether to raise initial " + "event, but already had first event."); + + // Always raise the first event when we're synced + if (!snapshot.from_cache()) { + return true; + } + + // NOTE: We consider OnlineState::Unknown as online (it should become Offline + // or Online if we wait long enough). + bool maybe_online = online_state != OnlineState::Offline; + + // Don't raise the event if we're online, aren't synced yet (checked + // above) and are waiting for a sync. + if (options_.wait_for_sync_when_online() && maybe_online) { + HARD_ASSERT(snapshot.from_cache(), + "Waiting for sync, but snapshot is not from cache."); + return false; + } + + // Raise data from cache if we have any documents or we are offline + return !snapshot.documents().empty() || online_state == OnlineState::Offline; +} + +bool QueryListener::ShouldRaiseEvent(const ViewSnapshot& snapshot) const { + // We don't need to handle include_document_metadata_changes() here because + // the Metadata only changes have already been stripped out if needed. At this + // point the only changes we will see are the ones we should propagate. + if (!snapshot.document_changes().empty()) { + return true; + } + + bool has_pending_writes_changed = + snapshot_.has_value() && + snapshot_.value().has_pending_writes() != snapshot.has_pending_writes(); + if (snapshot.sync_state_changed() || has_pending_writes_changed) { + return options_.include_query_metadata_changes(); + } + + // Generally we should have hit one of the cases above, but it's possible to + // get here if there were only metadata docChanges and they got stripped out. + return false; +} + +void QueryListener::RaiseInitialEvent(const ViewSnapshot& snapshot) { + HARD_ASSERT(!raised_initial_event_, + "Trying to raise initial events for second time"); + + ViewSnapshot modified_snapshot = ViewSnapshot::FromInitialDocuments( + snapshot.query(), snapshot.documents(), snapshot.mutated_keys(), + snapshot.from_cache(), snapshot.excludes_metadata_changes()); + raised_initial_event_ = true; + listener_->OnEvent(std::move(modified_snapshot)); +} + +} // namespace core +} // namespace firestore +} // namespace firebase + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/core/relation_filter.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/core/relation_filter.cc new file mode 100644 index 0000000..07087e6 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/core/relation_filter.cc @@ -0,0 +1,79 @@ +/* + * Copyright 2018 Google + * + * 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 "Firestore/core/src/firebase/firestore/core/relation_filter.h" + +#include + +#include "absl/types/optional.h" + +namespace firebase { +namespace firestore { +namespace core { + +using model::FieldPath; +using model::FieldValue; + +RelationFilter::RelationFilter(FieldPath field, + Operator op, + FieldValue value_rhs) + : field_(std::move(field)), op_(op), value_rhs_(std::move(value_rhs)) { +} + +const FieldPath& RelationFilter::field() const { + return field_; +} + +bool RelationFilter::Matches(const model::Document& doc) const { + if (field_.IsKeyFieldPath()) { + // TODO(rsgowman): Port this case + abort(); + } else { + absl::optional doc_field_value = doc.field(field_); + return doc_field_value && MatchesValue(doc_field_value.value()); + } +} + +bool RelationFilter::MatchesValue(const FieldValue& other) const { + // Only compare types with matching backend order (such as double and int). + return FieldValue::Comparable(other.type(), value_rhs_.type()) && + MatchesComparison(other); +} + +bool RelationFilter::MatchesComparison(const FieldValue& other) const { + switch (op_) { + case Operator::LessThan: + return other < value_rhs_; + case Operator::LessThanOrEqual: + return other <= value_rhs_; + case Operator::Equal: + return other == value_rhs_; + case Operator::GreaterThan: + return other > value_rhs_; + case Operator::GreaterThanOrEqual: + return other >= value_rhs_; + } + UNREACHABLE(); +} + +std::string RelationFilter::CanonicalId() const { + // TODO(rsgowman): Port this + abort(); +} + +} // namespace core +} // namespace firestore +} // namespace firebase diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/core/relation_filter.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/core/relation_filter.h new file mode 100644 index 0000000..8110ac1 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/core/relation_filter.h @@ -0,0 +1,61 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_CORE_RELATION_FILTER_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_CORE_RELATION_FILTER_H_ + +#include + +#include "Firestore/core/src/firebase/firestore/core/filter.h" +#include "Firestore/core/src/firebase/firestore/model/document.h" +#include "Firestore/core/src/firebase/firestore/model/field_path.h" +#include "Firestore/core/src/firebase/firestore/model/field_value.h" + +namespace firebase { +namespace firestore { +namespace core { + +/** Represents a filter to be applied to the query. */ +class RelationFilter : public Filter { + public: + /** + * Creates a new filter that compares fields and values. Only intended to be + * called from Filter::Create(). + */ + RelationFilter(model::FieldPath field, + Operator op, + model::FieldValue value_rhs); + + const model::FieldPath& field() const override; + + bool Matches(const model::Document& doc) const override; + + std::string CanonicalId() const override; + + private: + bool MatchesValue(const model::FieldValue& other) const; + bool MatchesComparison(const model::FieldValue& other) const; + + const model::FieldPath field_; + const Operator op_; + const model::FieldValue value_rhs_; +}; + +} // namespace core +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_CORE_RELATION_FILTER_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/core/target_id_generator.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/core/target_id_generator.cc new file mode 100644 index 0000000..260cd32 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/core/target_id_generator.cc @@ -0,0 +1,52 @@ +/* + * Copyright 2018 Google + * + * 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 "Firestore/core/src/firebase/firestore/core/target_id_generator.h" +#include "Firestore/core/src/firebase/firestore/util/hard_assert.h" + +using firebase::firestore::model::TargetId; + +namespace firebase { +namespace firestore { +namespace core { + +TargetIdGenerator::TargetIdGenerator(const TargetIdGenerator& value) + : generator_id_(value.generator_id_), next_id_(value.next_id_) { +} + +TargetIdGenerator::TargetIdGenerator(TargetIdGeneratorId generator_id, + TargetId seed) + : generator_id_(generator_id) { + generator_id_ = generator_id; + seek(seed); +} + +void TargetIdGenerator::seek(TargetId target_id) { + const TargetId generator = static_cast(generator_id_); + HARD_ASSERT((target_id & generator) == generator, + "Cannot supply target ID from different generator ID"); + next_id_ = target_id; +} + +TargetId TargetIdGenerator::NextId() { + int next_id = next_id_; + next_id_ += 1 << kReservedBits; + return next_id; +} + +} // namespace core +} // namespace firestore +} // namespace firebase diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/core/target_id_generator.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/core/target_id_generator.h new file mode 100644 index 0000000..54c492a --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/core/target_id_generator.h @@ -0,0 +1,97 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_CORE_TARGET_ID_GENERATOR_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_CORE_TARGET_ID_GENERATOR_H_ + +#include "Firestore/core/src/firebase/firestore/model/types.h" + +namespace firebase { +namespace firestore { +namespace core { + +/** The set of all valid generators. */ +enum class TargetIdGeneratorId { QueryCache = 0, SyncEngine = 1 }; + +/** + * Generates monotonically increasing target IDs for sending targets to the + * watch stream. + * + * The client constructs two generators, one for the query cache (via + * `QueryCacheTargetIdGenerator(int after)`), and one for limbo documents (via + * `SyncEngineTargetIdGenerator()`). These two generators produce + * non-overlapping IDs (by using even and odd IDs respectively). + * + * By separating the target ID space, the query cache can generate target IDs + * that persist across client restarts, while sync engine can independently + * generate in-memory target IDs that are transient and can be reused after a + * restart. + * + * Not thread-safe. + */ +// TODO(mrschmidt): Explore removing this class in favor of generating these IDs +// directly in SyncEngine and LocalStore. +class TargetIdGenerator { + public: + // Makes Objective-C++ code happy to provide a default ctor. + TargetIdGenerator() = default; + + TargetIdGenerator(const TargetIdGenerator& value); + + /** + * Creates and returns the TargetIdGenerator for the local store. + * + * @param after An ID to start at. Every call to NextId returns a larger id. + * @return An instance of TargetIdGenerator. + */ + static TargetIdGenerator QueryCacheTargetIdGenerator(model::TargetId after) { + TargetIdGenerator generator(TargetIdGeneratorId::QueryCache, after); + // Make sure that the next call to `nextId()` returns the first value after + // 'after'. + generator.NextId(); + return generator; + } + + /** + * Creates and returns the TargetIdGenerator for the sync engine. + * + * @return An instance of TargetIdGenerator. + */ + static TargetIdGenerator SyncEngineTargetIdGenerator() { + // Sync engine assigns target IDs for limbo document detection. + return TargetIdGenerator(TargetIdGeneratorId::SyncEngine, 1); + } + + TargetIdGeneratorId generator_id() { + return generator_id_; + } + + model::TargetId NextId(); + + private: + TargetIdGenerator(TargetIdGeneratorId generator_id, model::TargetId seed); + void seek(model::TargetId target_id); + TargetIdGeneratorId generator_id_; + model::TargetId next_id_; + + static const int kReservedBits = 1; +}; + +} // namespace core +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_CORE_TARGET_ID_GENERATOR_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/core/transaction.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/core/transaction.h new file mode 100644 index 0000000..37d9d66 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/core/transaction.h @@ -0,0 +1,142 @@ +/* + * Copyright 2019 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_CORE_TRANSACTION_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_CORE_TRANSACTION_H_ + +#if !defined(__OBJC__) +#error "This header only supports Objective-C++" +#endif // !defined(__OBJC__) + +#include +#include +#include + +#include "Firestore/core/src/firebase/firestore/core/user_data.h" +#include "Firestore/core/src/firebase/firestore/model/document_key.h" +#include "Firestore/core/src/firebase/firestore/model/precondition.h" +#include "Firestore/core/src/firebase/firestore/model/snapshot_version.h" +#include "Firestore/core/src/firebase/firestore/remote/datastore.h" +#include "Firestore/core/src/firebase/firestore/util/status.h" +#include "Firestore/core/src/firebase/firestore/util/statusor.h" +#include "absl/types/optional.h" + +NS_ASSUME_NONNULL_BEGIN + +@class FSTMaybeDocument; +@class FSTMutation; + +namespace firebase { +namespace firestore { +namespace core { + +class Transaction { + public: + // TODO(varconst): once `FSTMaybeDocument` is replaced with a C++ equivalent, + // this function could take a single `StatusOr` parameter. + using LookupCallback = std::function&, const util::Status&)>; + using CommitCallback = std::function; + + Transaction() = default; + explicit Transaction(remote::Datastore* transaction); + + /** + * Takes a set of keys and asynchronously attempts to fetch all the documents + * from the backend, ignoring any local changes. + */ + void Lookup(const std::vector& keys, + LookupCallback&& callback); + + /** + * Stores mutation for the given key and set data, to be committed when + * `Commit` is called. + */ + void Set(const model::DocumentKey& key, ParsedSetData&& data); + + /** + * Stores mutations for the given key and update data, to be committed when + * `Commit` is called. + */ + void Update(const model::DocumentKey& key, ParsedUpdateData&& data); + + /** + * Stores a delete mutation for the given key, to be committed when `Commit` + * is called. + */ + void Delete(const model::DocumentKey& key); + + /** + * Attempts to commit the mutations set on this transaction. Invokes the given + * callback when finished. Once this is called, no other mutations or + * commits are allowed on the transaction. + */ + void Commit(CommitCallback&& callback); + + private: + /** + * Every time a document is read, this should be called to record its version. + * If we read two different versions of the same document, this will return an + * error. When the transaction is committed, the versions recorded will be set + * as preconditions on the writes sent to the backend. + */ + util::Status RecordVersion(FSTMaybeDocument* doc); + + /** Stores mutations to be written when `Commit` is called. */ + void WriteMutations(std::vector&& mutations); + + /** + * Returns version of this doc when it was read in this transaction as a + * precondition, or no precondition if it was not read. + */ + model::Precondition CreatePrecondition(const model::DocumentKey& key); + + /** + * Returns the precondition for a document if the operation is an update. Will + * return a failed status if an error occurred. + */ + util::StatusOr CreateUpdatePrecondition( + const model::DocumentKey& key); + + void EnsureCommitNotCalled(); + + absl::optional GetVersion( + const model::DocumentKey& key) const; + + remote::Datastore* datastore_ = nullptr; + + std::vector mutations_; + bool committed_ = false; + + /** + * An error that may have occurred as a consequence of a write. If set, needs + * to be raised in the completion handler instead of trying to commit. + */ + util::Status last_write_error_; + + std::unordered_map + read_versions_; +}; + +} // namespace core +} // namespace firestore +} // namespace firebase + +NS_ASSUME_NONNULL_END + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_CORE_TRANSACTION_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/core/transaction.mm b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/core/transaction.mm new file mode 100644 index 0000000..d4fa6ca --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/core/transaction.mm @@ -0,0 +1,210 @@ +/* + * Copyright 2019 Google + * + * 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 "Firestore/core/src/firebase/firestore/core/transaction.h" + +#include +#include +#include + +#import "Firestore/Source/Model/FSTDocument.h" +#import "Firestore/Source/Model/FSTMutation.h" + +#include "Firestore/core/include/firebase/firestore/firestore_errors.h" +#include "Firestore/core/src/firebase/firestore/util/hard_assert.h" + +using firebase::firestore::FirestoreErrorCode; +using firebase::firestore::core::ParsedSetData; +using firebase::firestore::core::ParsedUpdateData; +using firebase::firestore::model::DocumentKey; +using firebase::firestore::model::DocumentKeyHash; +using firebase::firestore::model::Precondition; +using firebase::firestore::model::SnapshotVersion; +using firebase::firestore::remote::Datastore; +using firebase::firestore::util::Status; +using firebase::firestore::util::StatusOr; + +namespace firebase { +namespace firestore { +namespace core { + +Transaction::Transaction(Datastore* datastore) + : datastore_{NOT_NULL(datastore)} { +} + +Status Transaction::RecordVersion(FSTMaybeDocument* doc) { + SnapshotVersion doc_version; + + if ([doc isKindOfClass:[FSTDocument class]]) { + doc_version = doc.version; + } else if ([doc isKindOfClass:[FSTDeletedDocument class]]) { + // For deleted docs, we must record an explicit no version to build the + // right precondition when writing. + doc_version = SnapshotVersion::None(); + } else { + HARD_FAIL("Unexpected document type in transaction: %s", + NSStringFromClass([doc class])); + } + + absl::optional existing_version = GetVersion(doc.key); + if (existing_version.has_value()) { + if (doc_version != existing_version.value()) { + // This transaction will fail no matter what. + return Status{FirestoreErrorCode::Aborted, + "Document version changed between two reads."}; + } + return Status::OK(); + } else { + read_versions_[doc.key] = doc_version; + return Status::OK(); + } +} + +void Transaction::Lookup(const std::vector& keys, + LookupCallback&& callback) { + EnsureCommitNotCalled(); + + HARD_ASSERT(mutations_.empty(), + "Transactions lookups are invalid after writes."); + + datastore_->LookupDocuments( + keys, [this, callback](const std::vector& documents, + const Status& status) { + if (!status.ok()) { + callback({}, status); + return; + } + + for (FSTMaybeDocument* doc : documents) { + Status record_error = RecordVersion(doc); + if (!record_error.ok()) { + callback({}, record_error); + return; + } + } + + callback(documents, Status::OK()); + }); +} + +void Transaction::WriteMutations(std::vector&& mutations) { + EnsureCommitNotCalled(); + // `move` will become appropriate once `FSTMutation` is replaced by the C++ + // equivalent. + std::move(mutations.begin(), mutations.end(), std::back_inserter(mutations_)); +} + +Precondition Transaction::CreatePrecondition(const DocumentKey& key) { + absl::optional version = GetVersion(key); + if (version.has_value()) { + return Precondition::UpdateTime(version.value()); + } else { + return Precondition::None(); + } +} + +StatusOr Transaction::CreateUpdatePrecondition( + const DocumentKey& key) { + absl::optional version = GetVersion(key); + + if (version.has_value() && version.value() == SnapshotVersion::None()) { + // The document to update doesn't exist, so fail the transaction. + return Status{FirestoreErrorCode::Aborted, + "Can't update a document that doesn't exist."}; + } else if (version.has_value()) { + // Document exists, just base precondition on document update time. + return Precondition::UpdateTime(version.value()); + } else { + // Document was not read, so we just use the preconditions for a blind + // update. + return Precondition::Exists(true); + } +} + +void Transaction::Set(const DocumentKey& key, ParsedSetData&& data) { + WriteMutations(std::move(data).ToMutations(key, CreatePrecondition(key))); +} + +void Transaction::Update(const DocumentKey& key, ParsedUpdateData&& data) { + StatusOr maybe_precondition = CreateUpdatePrecondition(key); + if (!maybe_precondition.ok()) { + last_write_error_ = maybe_precondition.status(); + } else { + WriteMutations( + std::move(data).ToMutations(key, maybe_precondition.ValueOrDie())); + } +} + +void Transaction::Delete(const DocumentKey& key) { + FSTMutation* mutation = + [[FSTDeleteMutation alloc] initWithKey:key + precondition:CreatePrecondition(key)]; + WriteMutations({mutation}); + + // Since the delete will be applied before all following writes, we need to + // ensure that the precondition for the next write will be exists: false. + read_versions_[key] = SnapshotVersion::None(); +} + +void Transaction::Commit(CommitCallback&& callback) { + EnsureCommitNotCalled(); + + // If there was an error writing, raise that error now + if (!last_write_error_.ok()) { + callback(last_write_error_); + return; + } + + // Make a list of read documents that haven't been written. + std::unordered_set unwritten; + for (const auto& kv : read_versions_) { + unwritten.insert(kv.first); + }; + // For each mutation, note that the doc was written. + for (FSTMutation* mutation : mutations_) { + unwritten.erase(mutation.key); + } + + if (!unwritten.empty()) { + // TODO(klimt): This is a temporary restriction, until "verify" is supported + // on the backend. + callback( + Status{FirestoreErrorCode::FailedPrecondition, + "Every document read in a transaction must also be written in " + "that transaction."}); + } else { + committed_ = true; + datastore_->CommitMutations(mutations_, std::move(callback)); + } +} + +void Transaction::EnsureCommitNotCalled() { + HARD_ASSERT(!committed_, "A transaction object cannot be used after its " + "update callback has been invoked."); +} + +absl::optional Transaction::GetVersion( + const DocumentKey& key) const { + auto found = read_versions_.find(key); + if (found != read_versions_.end()) { + return found->second; + } + return absl::nullopt; +} + +} // namespace core +} // namespace firestore +} // namespace firebase diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/core/user_data.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/core/user_data.h new file mode 100644 index 0000000..d3c3bf9 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/core/user_data.h @@ -0,0 +1,316 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_CORE_USER_DATA_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_CORE_USER_DATA_H_ + +#include +#include +#include +#include +#include + +#include "Firestore/core/src/firebase/firestore/model/document_key.h" +#include "Firestore/core/src/firebase/firestore/model/field_mask.h" +#include "Firestore/core/src/firebase/firestore/model/field_path.h" +#include "Firestore/core/src/firebase/firestore/model/field_transform.h" +#include "Firestore/core/src/firebase/firestore/model/precondition.h" + +@class FSTMutation; +@class FSTObjectValue; + +namespace firebase { +namespace firestore { +namespace core { + +/** + * Represents what type of API method provided the data being parsed; useful for + * determining which error conditions apply during parsing and providing better + * error messages. + */ +enum class UserDataSource { + /** The data comes from a regular Set operation, without merge. */ + Set, + /** The data comes from a Set operation with merge enabled. */ + MergeSet, + /** The data comes from an Update operation. */ + Update, + /** + * Indicates the source is a where clause, cursor bound, array union element, + * etc. In particular, this will result in ParseContext.write() returning + * false. + */ + Argument, +}; + +class ParseContext; +class ParsedSetData; +class ParsedUpdateData; + +/** + * Accumulates the side-effect results of parsing user input. These include: + * + * * The field mask naming all the fields that have values. + * * The transform operations that must be applied in the batch to implement + * server-generated behavior. In the wire protocol these are encoded + * separately from the Value. + */ +class ParseAccumulator { + public: + /** + * @param data_source Indicates what kind of API method this data came from. + */ + explicit ParseAccumulator(UserDataSource data_source) + : data_source_{data_source} { + } + + /** + * What type of API method provided the data being parsed; useful for + * determining which error conditions apply during parsing and providing + * better error messages. + */ + UserDataSource data_source() const { + return data_source_; + } + + /** + * Returns the current list of transforms. + */ + const std::vector& field_transforms() const { + return field_transforms_; + } + + /** + * Returns a new ParseContext representing the root of a user document. + */ + ParseContext RootContext(); + + /** + * Returns `true` if the given `field_path` was encountered in the current + * document. + */ + bool Contains(const model::FieldPath& field_path) const; + + /** + * Adds the given `field_path` to the accumulated FieldMask. + */ + void AddToFieldMask(model::FieldPath field_path); + + /** + * Adds a transformation for the given field path. + */ + void AddToFieldTransforms( + model::FieldPath field_path, + std::unique_ptr transform_operation); + + /** + * Wraps the given `data` along with any accumulated field mask and transforms + * into a ParsedSetData representing a user-issued merge. + * + * @return ParsedSetData that has consumed the contents of this + * ParseAccumulator. + */ + ParsedSetData MergeData(FSTObjectValue* data) &&; + + /** + * Wraps the given `data` and `user_field_mask` along with any accumulated + * transforms that are covered by the given field mask into a ParsedSetData + * that represents a user-issued merge. + * + * @param data The converted user data. + * @param user_field_mask The user-supplied field mask that masks out any + * changes that have been accumulated so far. + * + * @return ParsedSetData that has consumed the contents of this + * ParseAccumulator. The field mask in the result will be the user_field_mask + * and only transforms that are covered by the mask will be included. + */ + ParsedSetData MergeData(FSTObjectValue* data, + model::FieldMask user_field_mask) &&; + + /** + * Wraps the given `data` along with any accumulated transforms into a + * ParsedSetData that represents a user-issued Set. + * + * @return ParsedSetData that has consumed the contents of this + * ParseAccumulator. + */ + ParsedSetData SetData(FSTObjectValue* data) &&; + + /** + * Wraps the given `data` along with any accumulated field mask and transforms + * into a ParsedUpdateData that represents a user-issued Update. + * + * @return ParsedSetData that has consumed the contents of this + * ParseAccumulator. + */ + ParsedUpdateData UpdateData(FSTObjectValue* data) &&; + + private: + friend class ParseContext; + + UserDataSource data_source_; + + // field_mask_ and field_transforms_ are shared across all active context + // objects to accumulate the result. All ChildContext objects append their + // results here. + std::set field_mask_; + std::vector field_transforms_; +}; + +/** + * A "context" object that wraps a ParseAccumulator and refers to a specific + * location in a user-supplied document. Instances are created and passed around + * while traversing user data during parsing in order to conveniently accumulate + * data in the ParseAccumulator. + */ +class ParseContext { + public: + /** + * Initializes a FSTParseContext with the given source and path. + * + * @param path A path within the object being parsed. This could be an empty + * path (in which case the context represents the root of the data being + * parsed), or a nonempty path (indicating the context represents a nested + * location within the data). + * + * TODO(b/34871131): We don't support array paths right now, so path can be + * nullptr to indicate the context represents any location within an array (in + * which case certain features will not work and errors will be somewhat + * compromised). + */ + ParseContext(ParseAccumulator* accumulator, + std::unique_ptr path, + bool array_element) + : accumulator_{accumulator}, + path_{std::move(path)}, + array_element_{array_element} { + } + + /** Whether or not this context corresponds to an element of an array. */ + bool array_element() const { + return array_element_; + } + + /** + * What type of API method provided the data being parsed; useful for + * determining which error conditions apply during parsing and providing + * better error messages. + */ + UserDataSource data_source() const { + return accumulator_->data_source_; + } + + const model::FieldPath* path() const { + return path_.get(); + } + + /** + * Returns true for the non-query parse contexts (Set, MergeSet and Update). + */ + bool write() const; + + std::string FieldDescription() const; + + // Helpers to get a FSTParseContext for a child field. + ParseContext ChildContext(const std::string& field_name); + ParseContext ChildContext(const model::FieldPath& field_path); + ParseContext ChildContext(size_t array_index); + + void AddToFieldMask(model::FieldPath field_path); + + void AddToFieldTransforms( + model::FieldPath field_path, + std::unique_ptr transform_operation); + + private: + void ValidatePath() const; + void ValidatePathSegment(absl::string_view segment) const; + + ParseAccumulator* accumulator_; // Non owning + + /** The current path being parsed. */ + // TODO(b/34871131): path should never be nullptr, but we don't support array + // paths right now. + std::unique_ptr path_; + + bool array_element_ = false; +}; + +/** The result of parsing document data (e.g. for a SetData call). */ +class ParsedSetData { + public: + ParsedSetData(FSTObjectValue* data, + std::vector field_transforms); + ParsedSetData(FSTObjectValue* data, + model::FieldMask field_mask, + std::vector field_transforms); + + /** + * Converts the parsed document data into 1 or 2 mutations (depending on + * whether there are any field transforms) using the specified document key + * and precondition. + * + * This method consumes the values stored in the ParsedSetData + */ + std::vector ToMutations( + const model::DocumentKey& key, + const model::Precondition& precondition) &&; + + private: + FSTObjectValue* data_; + model::FieldMask field_mask_; + std::vector field_transforms_; + bool patch_; +}; + +/** The result of parsing "update" data (i.e. for an UpdateData call). */ +class ParsedUpdateData { + public: + ParsedUpdateData(FSTObjectValue* data, + model::FieldMask field_mask, + std::vector fieldTransforms); + + FSTObjectValue* data() const { + return data_; + } + + const std::vector& field_transforms() const { + return field_transforms_; + } + + /** + * Converts the parsed update data into 1 or 2 mutations (depending on whether + * there are any field transforms) using the specified document key and + * precondition. + * + * This method consumes the values stored in the ParsedUpdateData + */ + std::vector ToMutations( + const model::DocumentKey& key, + const model::Precondition& precondition) &&; + + private: + FSTObjectValue* data_; + model::FieldMask field_mask_; + std::vector field_transforms_; +}; + +} // namespace core +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_CORE_USER_DATA_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/core/user_data.mm b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/core/user_data.mm new file mode 100644 index 0000000..237e49f --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/core/user_data.mm @@ -0,0 +1,274 @@ +/* + * Copyright 2018 Google + * + * 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 "Firestore/core/src/firebase/firestore/core/user_data.h" + +#include + +#import "Firestore/Source/Model/FSTMutation.h" +#import "Firestore/Source/Util/FSTUsageValidation.h" + +#include "absl/strings/match.h" + +namespace firebase { +namespace firestore { +namespace core { + +using model::DocumentKey; +using model::FieldMask; +using model::FieldPath; +using model::FieldTransform; +using model::Precondition; +using model::TransformOperation; + +#pragma mark - ParseAccumulator + +ParseContext ParseAccumulator::RootContext() { + return ParseContext{ + this, absl::make_unique(FieldPath::EmptyPath()), false}; +} + +bool ParseAccumulator::Contains(const FieldPath& field_path) const { + for (const FieldPath& field : field_mask_) { + if (field_path.IsPrefixOf(field)) { + return true; + } + } + + for (const FieldTransform& field_transform : field_transforms_) { + if (field_path.IsPrefixOf(field_transform.path())) { + return true; + } + } + + return false; +} + +void ParseAccumulator::AddToFieldMask(FieldPath field_path) { + field_mask_.insert(std::move(field_path)); +} + +void ParseAccumulator::AddToFieldTransforms( + FieldPath field_path, + std::unique_ptr transform_operation) { + field_transforms_.emplace_back(std::move(field_path), + std::move(transform_operation)); +} + +ParsedSetData ParseAccumulator::MergeData(FSTObjectValue* data) && { + return ParsedSetData{data, FieldMask{std::move(field_mask_)}, + std::move(field_transforms_)}; +} + +ParsedSetData ParseAccumulator::MergeData(FSTObjectValue* data, + model::FieldMask user_field_mask) && { + std::vector covered_field_transforms; + + for (FieldTransform& field_transform : field_transforms_) { + if (user_field_mask.covers(field_transform.path())) { + covered_field_transforms.push_back(std::move(field_transform)); + } + } + + return ParsedSetData{data, std::move(user_field_mask), + std::move(covered_field_transforms)}; +} + +ParsedSetData ParseAccumulator::SetData(FSTObjectValue* data) && { + return ParsedSetData{data, std::move(field_transforms_)}; +} + +ParsedUpdateData ParseAccumulator::UpdateData(FSTObjectValue* data) && { + return ParsedUpdateData{data, FieldMask{std::move(field_mask_)}, + std::move(field_transforms_)}; +} + +#pragma mark - ParseContext + +namespace { + +const char* RESERVED_FIELD_DESIGNATOR = "__"; + +} // namespace + +ParseContext ParseContext::ChildContext(const std::string& field_name) { + std::unique_ptr path; + if (path_) { + path = absl::make_unique(path_->Append(field_name)); + } + + ParseContext context{accumulator_, std::move(path), false}; + context.ValidatePathSegment(field_name); + return context; +} + +ParseContext ParseContext::ChildContext(const FieldPath& fieldPath) { + std::unique_ptr path; + if (path_) { + path = absl::make_unique(path_->Append(fieldPath)); + } + + ParseContext context{accumulator_, std::move(path), false}; + context.ValidatePath(); + return context; +} + +ParseContext ParseContext::ChildContext(size_t array_index) { + // TODO(b/34871131): We don't support array paths right now; make path null. + (void)array_index; + return {accumulator_, /* path= */ nullptr, /* array_element= */ true}; +} + +/** + * Returns a string that can be appended to error messages indicating what field + * caused the error. + */ +std::string ParseContext::FieldDescription() const { + // TODO(b/34871131): Remove nullptr check once we have proper paths for fields + // within arrays. + if (!path_ || path_->empty()) { + return ""; + } else { + return util::StringFormat(" (found in field %s)", path_->CanonicalString()); + } +} + +bool ParseContext::write() const { + switch (accumulator_->data_source()) { + case UserDataSource::Set: // Falls through. + case UserDataSource::MergeSet: // Falls through. + case UserDataSource::Update: + return true; + case UserDataSource::Argument: + return false; + default: + FSTThrowInvalidArgument(@"Unexpected case for UserDataSource: %d", + accumulator_->data_source()); + } +} + +void ParseContext::ValidatePath() const { + // TODO(b/34871131): Remove nullptr check once we have proper paths for fields + // within arrays. + if (!path_) { + return; + } + for (const std::string& segment : *path_) { + ValidatePathSegment(segment); + } +} + +void ParseContext::ValidatePathSegment(absl::string_view segment) const { + absl::string_view designator{RESERVED_FIELD_DESIGNATOR}; + if (write() && absl::StartsWith(segment, designator) && + absl::EndsWith(segment, designator)) { + FSTThrowInvalidArgument(@"Document fields cannot begin and end with %s%s", + RESERVED_FIELD_DESIGNATOR, + FieldDescription().c_str()); + } +} + +void ParseContext::AddToFieldMask(FieldPath field_path) { + accumulator_->AddToFieldMask(std::move(field_path)); +} + +void ParseContext::AddToFieldTransforms( + FieldPath field_path, + std::unique_ptr transform_operation) { + accumulator_->AddToFieldTransforms(std::move(field_path), + std::move(transform_operation)); +} + +#pragma mark - ParsedSetData + +ParsedSetData::ParsedSetData(FSTObjectValue* data, + std::vector field_transforms) + : data_{data}, + field_transforms_{std::move(field_transforms)}, + patch_{false} { +} + +ParsedSetData::ParsedSetData(FSTObjectValue* data, + FieldMask field_mask, + std::vector field_transforms) + : data_{data}, + field_mask_{std::move(field_mask)}, + field_transforms_{std::move(field_transforms)}, + patch_{true} { +} + +std::vector ParsedSetData::ToMutations( + const DocumentKey& key, const Precondition& precondition) && { + std::vector mutations; + if (patch_) { + FSTMutation* mutation = + [[FSTPatchMutation alloc] initWithKey:key + fieldMask:std::move(field_mask_) + value:data_ + precondition:precondition]; + mutations.push_back(mutation); + } else { + FSTMutation* mutation = [[FSTSetMutation alloc] initWithKey:key + value:data_ + precondition:precondition]; + mutations.push_back(mutation); + } + + if (!field_transforms_.empty()) { + FSTMutation* mutation = + [[FSTTransformMutation alloc] initWithKey:key + fieldTransforms:field_transforms_]; + mutations.push_back(mutation); + } + + return mutations; +} + +#pragma mark - ParsedUpdateData + +ParsedUpdateData::ParsedUpdateData( + FSTObjectValue* data, + model::FieldMask field_mask, + std::vector field_transforms) + : data_{data}, + field_mask_{std::move(field_mask)}, + field_transforms_{std::move(field_transforms)} { +} + +std::vector ParsedUpdateData::ToMutations( + const DocumentKey& key, const Precondition& precondition) && { + std::vector mutations; + + FSTMutation* mutation = + [[FSTPatchMutation alloc] initWithKey:key + fieldMask:std::move(field_mask_) + value:data_ + precondition:precondition]; + mutations.push_back(mutation); + + if (!field_transforms_.empty()) { + FSTMutation* mutation = + [[FSTTransformMutation alloc] initWithKey:key + fieldTransforms:std::move(field_transforms_)]; + mutations.push_back(mutation); + } + + return mutations; +} + +} // namespace core +} // namespace firestore +} // namespace firebase diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/core/view_snapshot.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/core/view_snapshot.h new file mode 100644 index 0000000..5e4c7de --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/core/view_snapshot.h @@ -0,0 +1,203 @@ +/* + * Copyright 2019 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_CORE_VIEW_SNAPSHOT_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_CORE_VIEW_SNAPSHOT_H_ + +#if !defined(__OBJC__) +#error "This header only supports Objective-C++" +#endif // !defined(__OBJC__) + +#include +#include +#include +#include +#include +#include + +#include "Firestore/core/src/firebase/firestore/core/event_listener.h" +#include "Firestore/core/src/firebase/firestore/immutable/sorted_map.h" +#include "Firestore/core/src/firebase/firestore/model/document_key.h" +#include "Firestore/core/src/firebase/firestore/model/document_key_set.h" +#include "Firestore/core/src/firebase/firestore/model/document_set.h" +#include "Firestore/core/src/firebase/firestore/util/statusor.h" + +NS_ASSUME_NONNULL_BEGIN + +@class FSTDocument; +@class FSTQuery; + +namespace firebase { +namespace firestore { +namespace core { + +/** A change to a single document's state within a view. */ +class DocumentViewChange { + public: + /** + * The types of changes that can happen to a document with respect to a view. + * NOTE: We sort document changes by their type, so the ordering of this enum + * is significant. + */ + enum class Type { kRemoved = 0, kAdded, kModified, kMetadata }; + + DocumentViewChange() = default; + + DocumentViewChange(FSTDocument* document, Type type) + : document_{document}, type_{type} { + } + + FSTDocument* document() const { + return document_; + } + DocumentViewChange::Type type() const { + return type_; + } + + std::string ToString() const; + size_t Hash() const; + + private: + FSTDocument* document_ = nullptr; + Type type_{}; +}; + +bool operator==(const DocumentViewChange& lhs, const DocumentViewChange& rhs); + +/** + * The possible states a document can be in w.r.t syncing from local storage to + * the backend. + */ +enum class SyncState { None = 0, Local, Synced }; + +/** + * A set of changes to docs in a query, merging duplicate events for the same + * doc. + */ +class DocumentViewChangeSet { + public: + /** Takes a new change and applies it to the set. */ + void AddChange(DocumentViewChange&& change); + + /** Returns the set of all changes tracked in this set. */ + std::vector GetChanges() const; + + std::string ToString() const; + + private: + /** The set of all changes tracked so far, with redundant changes merged. */ + immutable::SortedMap change_map_; +}; + +/** + * A view snapshot is an immutable capture of the results of a query and the + * changes to them. + */ +class ViewSnapshot { + public: + using Listener = std::unique_ptr>; + using SharedListener = std::shared_ptr>; + + ViewSnapshot(FSTQuery* query, + model::DocumentSet documents, + model::DocumentSet old_documents, + std::vector document_changes, + model::DocumentKeySet mutated_keys, + bool from_cache, + bool sync_state_changed, + bool excludes_metadata_changes); + + /** + * Returns a view snapshot as if all documents in the snapshot were + * added. + */ + static ViewSnapshot FromInitialDocuments(FSTQuery* query, + model::DocumentSet documents, + model::DocumentKeySet mutated_keys, + bool from_cache, + bool excludes_metadata_changes); + + /** The query this view is tracking the results for. */ + FSTQuery* query() const { + return query_; + } + + /** The documents currently known to be results of the query. */ + const model::DocumentSet& documents() const { + return documents_; + } + + /** The documents of the last snapshot. */ + const model::DocumentSet& old_documents() const { + return old_documents_; + } + + /** The set of changes that have been applied to the documents. */ + const std::vector& document_changes() const { + return document_changes_; + } + + /** Whether any document in the snapshot was served from the local cache. */ + bool from_cache() const { + return from_cache_; + } + + /** Whether any document in the snapshot has pending local writes. */ + bool has_pending_writes() const { + return !mutated_keys_.empty(); + } + + /** Whether the sync state changed as part of this snapshot. */ + bool sync_state_changed() const { + return sync_state_changed_; + } + + /** Whether this snapshot has been filtered to not include metadata changes */ + bool excludes_metadata_changes() const { + return excludes_metadata_changes_; + } + + /** The document in this snapshot that have unconfirmed writes. */ + model::DocumentKeySet mutated_keys() const { + return mutated_keys_; + } + + std::string ToString() const; + friend std::ostream& operator<<(std::ostream& out, const ViewSnapshot& value); + size_t Hash() const; + + private: + FSTQuery* query_ = nil; + + model::DocumentSet documents_; + model::DocumentSet old_documents_; + std::vector document_changes_; + model::DocumentKeySet mutated_keys_; + + bool from_cache_ = false; + bool sync_state_changed_ = false; + bool excludes_metadata_changes_ = false; +}; + +bool operator==(const ViewSnapshot& lhs, const ViewSnapshot& rhs); + +} // namespace core +} // namespace firestore +} // namespace firebase + +NS_ASSUME_NONNULL_END + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_CORE_VIEW_SNAPSHOT_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/core/view_snapshot.mm b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/core/view_snapshot.mm new file mode 100644 index 0000000..6663063 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/core/view_snapshot.mm @@ -0,0 +1,210 @@ +/* + * Copyright 2019 Google + * + * 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 "Firestore/core/src/firebase/firestore/core/view_snapshot.h" + +#include + +#import "Firestore/Source/Core/FSTQuery.h" +#import "Firestore/Source/Model/FSTDocument.h" + +#include "Firestore/core/src/firebase/firestore/model/document_set.h" +#include "Firestore/core/src/firebase/firestore/util/hashing.h" +#include "Firestore/core/src/firebase/firestore/util/objc_compatibility.h" +#include "Firestore/core/src/firebase/firestore/util/string_format.h" +#include "Firestore/core/src/firebase/firestore/util/to_string.h" + +namespace firebase { +namespace firestore { +namespace core { + +namespace objc = util::objc; +using model::DocumentKey; +using model::DocumentKeySet; +using model::DocumentSet; +using util::StringFormat; + +// DocumentViewChange + +std::string DocumentViewChange::ToString() const { + return StringFormat("", + util::ToString(document()), type()); +} + +size_t DocumentViewChange::Hash() const { + size_t document_hash = static_cast([document() hash]); + return util::Hash(document_hash, static_cast(type())); +} + +bool operator==(const DocumentViewChange& lhs, const DocumentViewChange& rhs) { + return objc::Equals(lhs.document(), rhs.document()) && + lhs.type() == rhs.type(); +} + +// DocumentViewChangeSet + +void DocumentViewChangeSet::AddChange(DocumentViewChange&& change) { + const DocumentKey& key = change.document().key; + auto old_change_iter = change_map_.find(key); + if (old_change_iter == change_map_.end()) { + change_map_ = change_map_.insert(key, change); + return; + } + + const DocumentViewChange& old = old_change_iter->second; + DocumentViewChange::Type old_type = old.type(); + DocumentViewChange::Type new_type = change.type(); + + // Merge the new change with the existing change. + if (new_type != DocumentViewChange::Type::kAdded && + old_type == DocumentViewChange::Type::kMetadata) { + change_map_ = change_map_.insert(key, change); + + } else if (new_type == DocumentViewChange::Type::kMetadata && + old_type != DocumentViewChange::Type::kRemoved) { + DocumentViewChange new_change{change.document(), old_type}; + change_map_ = change_map_.insert(key, new_change); + + } else if (new_type == DocumentViewChange::Type::kModified && + old_type == DocumentViewChange::Type::kModified) { + DocumentViewChange new_change{change.document(), + DocumentViewChange::Type::kModified}; + change_map_ = change_map_.insert(key, new_change); + + } else if (new_type == DocumentViewChange::Type::kModified && + old_type == DocumentViewChange::Type::kAdded) { + DocumentViewChange new_change{change.document(), + DocumentViewChange::Type::kAdded}; + change_map_ = change_map_.insert(key, new_change); + + } else if (new_type == DocumentViewChange::Type::kRemoved && + old_type == DocumentViewChange::Type::kAdded) { + change_map_ = change_map_.erase(key); + + } else if (new_type == DocumentViewChange::Type::kRemoved && + old_type == DocumentViewChange::Type::kModified) { + DocumentViewChange new_change{old.document(), + DocumentViewChange::Type::kRemoved}; + change_map_ = change_map_.insert(key, new_change); + + } else if (new_type == DocumentViewChange::Type::kAdded && + old_type == DocumentViewChange::Type::kRemoved) { + DocumentViewChange new_change{change.document(), + DocumentViewChange::Type::kModified}; + change_map_ = change_map_.insert(key, new_change); + + } else { + // This includes these cases, which don't make sense: + // Added -> Added + // Removed -> Removed + // Modified -> Added + // Removed -> Modified + // Metadata -> Added + // Removed -> Metadata + HARD_FAIL("Unsupported combination of changes: %s after %s", new_type, + old_type); + } +} + +std::vector DocumentViewChangeSet::GetChanges() const { + std::vector changes; + for (const auto& kv : change_map_) { + const DocumentViewChange& change = kv.second; + changes.push_back(change); + } + return changes; +} + +std::string DocumentViewChangeSet::ToString() const { + return util::ToString(change_map_); +} + +// ViewSnapshot + +ViewSnapshot::ViewSnapshot(FSTQuery* query, + DocumentSet documents, + DocumentSet old_documents, + std::vector document_changes, + model::DocumentKeySet mutated_keys, + bool from_cache, + bool sync_state_changed, + bool excludes_metadata_changes) + : query_{query}, + documents_{std::move(documents)}, + old_documents_{std::move(old_documents)}, + document_changes_{std::move(document_changes)}, + mutated_keys_{std::move(mutated_keys)}, + from_cache_{from_cache}, + sync_state_changed_{sync_state_changed}, + excludes_metadata_changes_{excludes_metadata_changes} { +} + +ViewSnapshot ViewSnapshot::FromInitialDocuments( + FSTQuery* query, + DocumentSet documents, + DocumentKeySet mutated_keys, + bool from_cache, + bool excludes_metadata_changes) { + std::vector view_changes; + for (FSTDocument* doc : documents) { + view_changes.emplace_back(doc, DocumentViewChange::Type::kAdded); + } + + return ViewSnapshot{query, documents, + /*old_documents=*/ + DocumentSet{query.comparator}, std::move(view_changes), + std::move(mutated_keys), from_cache, + /*sync_state_changed=*/true, excludes_metadata_changes}; +} + +std::string ViewSnapshot::ToString() const { + return StringFormat( + "", + query(), documents_.ToString(), old_documents_.ToString(), + objc::Description(document_changes()), from_cache(), + mutated_keys().size(), sync_state_changed(), excludes_metadata_changes()); +} + +std::ostream& operator<<(std::ostream& out, const ViewSnapshot& value) { + return out << value.ToString(); +} + +size_t ViewSnapshot::Hash() const { + // Note: We are omitting `mutated_keys_` from the hash, since we don't have a + // straightforward way to compute its hash value. Since `ViewSnapshot` is + // currently not stored in any dictionaries, this has no side effects. + + return util::Hash([query() hash], documents(), old_documents(), + document_changes(), from_cache(), sync_state_changed(), + excludes_metadata_changes()); +} + +bool operator==(const ViewSnapshot& lhs, const ViewSnapshot& rhs) { + return objc::Equals(lhs.query(), rhs.query()) && + lhs.documents() == rhs.documents() && + lhs.old_documents() == rhs.old_documents() && + lhs.document_changes() == rhs.document_changes() && + lhs.from_cache() == rhs.from_cache() && + lhs.mutated_keys() == rhs.mutated_keys() && + lhs.sync_state_changed() == rhs.sync_state_changed() && + lhs.excludes_metadata_changes() == rhs.excludes_metadata_changes(); +} + +} // namespace core +} // namespace firestore +} // namespace firebase diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/firestore_version.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/firestore_version.cc new file mode 100644 index 0000000..57c4f08 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/firestore_version.cc @@ -0,0 +1,37 @@ +/* + * Copyright 2018 Google + * + * 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 "Firestore/core/include/firebase/firestore/firestore_version.h" + +#ifndef FIRFirestore_VERSION +#error \ + "FIRFirestore_VERSION is not defined: add -DFIRFirestore_VERSION=... to the build invocation" // NOLINT(whitespace/line_length) +#endif + +namespace firebase { +namespace firestore { + +// The following two macros supply the incantation so that the C +// preprocessor does not try to parse the version as a floating +// point number. See +// https://www.guyrutenberg.com/2008/12/20/expanding-macros-into-string-constants-in-c/ +#define STR(x) STR_EXPAND(x) +#define STR_EXPAND(x) #x + +const char* const kFirestoreVersionString = STR(FIRFirestore_VERSION); + +} // namespace firestore +} // namespace firebase diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/geo_point.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/geo_point.cc new file mode 100644 index 0000000..393b8f2 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/geo_point.cc @@ -0,0 +1,46 @@ +/* + * Copyright 2018 Google + * + * 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 "Firestore/core/include/firebase/firestore/geo_point.h" + +#include + +#include "Firestore/core/src/firebase/firestore/util/hard_assert.h" + +namespace firebase { +namespace firestore { + +GeoPoint::GeoPoint() : GeoPoint(0, 0) { +} + +GeoPoint::GeoPoint(double latitude, double longitude) + : latitude_(latitude), longitude_(longitude) { + HARD_ASSERT(!std::isnan(latitude) && -90 <= latitude && latitude <= 90, + "Latitude must be in the range of [-90, 90]"); + HARD_ASSERT(!std::isnan(longitude) && -180 <= longitude && longitude <= 180, + "Latitude must be in the range of [-180, 180]"); +} + +bool operator<(const GeoPoint& lhs, const GeoPoint& rhs) { + if (lhs.latitude() == rhs.latitude()) { + return lhs.longitude() < rhs.longitude(); + } else { + return lhs.latitude() < rhs.latitude(); + } +} + +} // namespace firestore +} // namespace firebase diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/immutable/array_sorted_map.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/immutable/array_sorted_map.h new file mode 100644 index 0000000..1a7076d --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/immutable/array_sorted_map.h @@ -0,0 +1,365 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_IMMUTABLE_ARRAY_SORTED_MAP_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_IMMUTABLE_ARRAY_SORTED_MAP_H_ + +#include +#include +#include +#include +#include +#include +#include + +#include "Firestore/core/src/firebase/firestore/immutable/keys_view.h" +#include "Firestore/core/src/firebase/firestore/immutable/map_entry.h" +#include "Firestore/core/src/firebase/firestore/immutable/sorted_container.h" +#include "Firestore/core/src/firebase/firestore/util/comparison.h" +#include "Firestore/core/src/firebase/firestore/util/hard_assert.h" +#include "Firestore/core/src/firebase/firestore/util/range.h" + +namespace firebase { +namespace firestore { +namespace immutable { +namespace impl { + +/** + * A bounded-size array that allocates its contents directly in itself. This + * saves a heap allocation when compared with std::vector (though std::vector + * can resize itself while FixedArray cannot). + * + * Unlike std::array, FixedArray keeps track of its size and grows up to the + * fixed_size limit. Inserting more elements than fixed_size will trigger an + * assertion failure. + * + * ArraySortedMap does not actually contain its array: it contains a shared_ptr + * to a FixedArray. + * + * @tparam T The type of an element in the array. + */ +template +class FixedArray { + public: + using size_type = SortedMapBase::size_type; + using array_type = std::array; + using iterator = typename array_type::iterator; + using const_iterator = typename array_type::const_iterator; + + FixedArray() { + } + + template + FixedArray(SourceIterator src_begin, SourceIterator src_end) { + append(src_begin, src_end); + } + + /** + * Appends to this array, copying from the given src_begin up to but not + * including the src_end. + */ + template + void append(SourceIterator src_begin, SourceIterator src_end) { + auto appending = static_cast(src_end - src_begin); + auto new_size = size_ + appending; + HARD_ASSERT(new_size <= SortedMapBase::kFixedSize); + + std::copy(src_begin, src_end, end()); + size_ = new_size; + } + + /** + * Appends a single value to the array. + */ + void append(T&& value) { + size_type new_size = size_ + 1; + HARD_ASSERT(new_size <= SortedMapBase::kFixedSize); + + *end() = std::move(value); + size_ = new_size; + } + + const_iterator begin() const { + return contents_.begin(); + } + + const_iterator end() const { + return begin() + size_; + } + + size_type size() const { + return size_; + } + + private: + iterator begin() { + return contents_.begin(); + } + + iterator end() { + return begin() + size_; + } + + array_type contents_; + size_type size_ = 0; +}; + +/** + * ArraySortedMap is a value type containing a map. It is immutable, but has + * methods to efficiently create new maps that are mutations of it. + */ +template > +class ArraySortedMap : public SortedMapBase { + public: + using key_comparator_type = KeyComparator; + + /** + * The type of the entries stored in the map. + */ + using value_type = std::pair; + + /** + * The type of the fixed-size array containing entries of value_type. + */ + using array_type = FixedArray; + using const_iterator = typename array_type::const_iterator; + using const_key_iterator = util::iterator_first; + + using array_pointer = std::shared_ptr; + + /** + * Creates an empty ArraySortedMap. + */ + explicit ArraySortedMap(const C& comparator = C()) + : array_{EmptyArray()}, key_comparator_{comparator} { + } + + /** + * Creates an ArraySortedMap containing the given entries. + */ + ArraySortedMap(std::initializer_list entries, + const C& comparator = C()) + : array_{SortedArray(entries, comparator)}, key_comparator_{comparator} { + } + + /** Returns true if the map contains no elements. */ + bool empty() const { + return size() == 0; + } + + /** Returns the number of items in this map. */ + size_type size() const { + return array_->size(); + } + + const C& comparator() const { + return key_comparator_.comparator(); + } + + /** + * Creates a new map identical to this one, but with a key-value pair added or + * updated. + * + * @param key The key to insert/update. + * @param value The value to associate with the key. + * @return A new dictionary with the added/updated value. + */ + ArraySortedMap insert(const K& key, const V& value) const { + const_iterator current_end = end(); + const_iterator pos = lower_bound(key); + bool replacing_entry = false; + + if (pos != current_end) { + // lower_bound found an entry where pos->first >= pair.first. Reversing + // the argument order here tests pair.first < pos->first. + replacing_entry = !key_comparator_(key, *pos); + if (replacing_entry && value == pos->second) { + return *this; + } + } + + // Copy the segment before the found position. If not found, this is + // everything. + auto copy = std::make_shared(begin(), pos); + + // Copy the value to be inserted. + copy->append({key, value}); + + if (replacing_entry) { + // Skip the thing at pos because it compares the same as the pair above. + copy->append(pos + 1, current_end); + } else { + copy->append(pos, current_end); + } + return wrap(copy); + } + + /** + * Creates a new map identical to this one, but with a key removed from it. + * + * @param key The key to remove. + * @return A new dictionary without that value. + */ + ArraySortedMap erase(const K& key) const { + const_iterator current_end = end(); + const_iterator pos = find(key); + if (pos == current_end) { + return *this; + } else if (size() <= 1) { + // If the key was found and it's the last entry, removing it would make + // the result empty. + return wrap(EmptyArray()); + } else { + auto copy = std::make_shared(begin(), pos); + copy->append(pos + 1, current_end); + return wrap(copy); + } + } + + bool contains(const K& key) const { + return find(key) != end(); + } + + /** + * Finds a value in the map. + * + * @param key The key to look up. + * @return An iterator pointing to the entry containing the key, or end() if + * not found. + */ + const_iterator find(const K& key) const { + const_iterator not_found = end(); + const_iterator bound = lower_bound(key); + if (bound != not_found && !key_comparator_(key, *bound)) { + return bound; + } else { + return not_found; + } + } + + /** + * Finds the index of the given key in the map. + * + * @param key The key to look up. + * @return The index of the entry containing the key, or npos if not found. + */ + size_type find_index(const K& key) const { + auto found = find(key); + return found == end() ? npos : static_cast(found - begin()); + } + + /** + * Finds the first entry in the map containing a key greater than or equal + * to the given key. + * + * @param key The key to look up. + * @return An iterator pointing to the entry containing the key or the next + * largest key. Can return end() if all keys in the map are less than the + * requested key. + */ + const_iterator lower_bound(const K& key) const { + return std::lower_bound(begin(), end(), key, key_comparator_); + } + + const_iterator min() const { + return begin(); + } + + const_iterator max() const { + if (empty()) { + return end(); + } + + return end() - 1; + } + + /** + * Returns an iterator pointing to the first entry in the map. If there are + * no entries in the map, begin() == end(). + */ + const_iterator begin() const { + return array_->begin(); + } + + /** + * Returns an iterator pointing past the last entry in the map. + */ + const_iterator end() const { + return array_->end(); + } + + /** + * Returns a view of this SortedMap containing just the keys that have been + * inserted. + */ + const util::range keys() const { + return KeysView(*this); + } + + /** + * Returns a view of this SortedMap containing just the keys that have been + * inserted that are greater than or equal to the given key. + */ + const util::range keys_from(const K& key) const { + return KeysViewFrom(*this, key); + } + + /** + * Returns a view of this SortedMap containing just the keys that have been + * inserted that are greater than or equal to the given start_key and less + * than the given end_key. + */ + const util::range keys_in(const K& start_key, + const K& end_key) const { + return impl::KeysViewIn(*this, start_key, end_key, comparator()); + } + + private: + static array_pointer EmptyArray() { + static const array_pointer kEmptyArray = + std::make_shared(); + return kEmptyArray; + } + + static array_pointer SortedArray(std::initializer_list entries, + const C& comparator) { + std::vector sorted{entries.begin(), entries.end()}; + std::sort(sorted.begin(), sorted.end(), + [&comparator](const value_type& lhs, const value_type& rhs) { + return comparator(lhs.first, rhs.first); + }); + return std::make_shared(sorted.begin(), sorted.end()); + } + + ArraySortedMap(const array_pointer& array, + const key_comparator_type& key_comparator) noexcept + : array_{array}, key_comparator_{key_comparator} { + } + + ArraySortedMap wrap(const array_pointer& array) const noexcept { + return ArraySortedMap{array, key_comparator_}; + } + + array_pointer array_; + key_comparator_type key_comparator_; +}; + +} // namespace impl +} // namespace immutable +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_IMMUTABLE_ARRAY_SORTED_MAP_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/immutable/keys_view.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/immutable/keys_view.h new file mode 100644 index 0000000..6cf04b6 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/immutable/keys_view.h @@ -0,0 +1,86 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_IMMUTABLE_KEYS_VIEW_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_IMMUTABLE_KEYS_VIEW_H_ + +#include + +#include "Firestore/core/src/firebase/firestore/util/iterator_adaptors.h" +#include "Firestore/core/src/firebase/firestore/util/range.h" + +namespace firebase { +namespace firestore { +namespace immutable { +namespace impl { + +template +using KeysRange = util::range>; + +template +KeysRange MakeKeysRange(Iterator begin, Iterator end) { + auto keys_begin = util::make_iterator_first(begin); + auto keys_end = util::make_iterator_first(end); + return util::make_range(keys_begin, keys_end); +} + +/** + * Returns a view of the keys of the given key-value range. + */ +template +auto KeysView(const Range& range) -> KeysRange { + return MakeKeysRange(std::begin(range), std::end(range)); +} + +template +auto KeysViewFrom(const Range& range, const K& key) + -> KeysRange { + auto keys_begin = util::make_iterator_first(range.lower_bound(key)); + auto keys_end = util::make_iterator_first(std::end(range)); + return util::make_range(keys_begin, keys_end); +} + +/** + * Returns a view of keys of the given key-value range that are greater than or + * equal to the given start_key and less than the given end_key. + * + * If `end_key` is less than or equal to `start_key`, creates empty range. + */ +template +auto KeysViewIn(const Range& range, + const K& start_key, + const K& end_key, + const C& comparator) + -> KeysRange { + // Forward iterators can't ever reach the end if the end is behind the start: + // they just keep incrementing until address space runs out. Adjust the range + // accordingly. + bool empty_range = !comparator(start_key, end_key); + if (empty_range) { + return MakeKeysRange(std::end(range), std::end(range)); + } + + auto range_begin = range.lower_bound(start_key); + auto range_end = range.lower_bound(end_key); + return MakeKeysRange(std::move(range_begin), std::move(range_end)); +} + +} // namespace impl +} // namespace immutable +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_IMMUTABLE_KEYS_VIEW_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/immutable/llrb_node.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/immutable/llrb_node.h new file mode 100644 index 0000000..0046580 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/immutable/llrb_node.h @@ -0,0 +1,471 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_IMMUTABLE_LLRB_NODE_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_IMMUTABLE_LLRB_NODE_H_ + +#include +#include + +#include "Firestore/core/src/firebase/firestore/immutable/llrb_node_iterator.h" +#include "Firestore/core/src/firebase/firestore/immutable/sorted_container.h" + +namespace firebase { +namespace firestore { +namespace immutable { +namespace impl { + +/** + * A Color of a tree node in a red-black tree. + */ +enum Color : unsigned int { + Black, + Red, +}; + +/** + * LlrbNode is a node in a TreeSortedMap. + */ +template +class LlrbNode : public SortedMapBase { + public: + using first_type = K; + using second_type = V; + + /** + * The type of the entries stored in the map. + */ + using value_type = std::pair; + using const_iterator = LlrbNodeIterator>; + + /** + * Constructs an empty node. + */ + LlrbNode() : LlrbNode{EmptyRep()} { + } + + /** Returns true if this is an empty node--a leaf node in the tree. */ + bool empty() const { + return size() == 0; + } + + /** Returns the number of elements at this node or beneath it in the tree. */ + size_type size() const { + return rep_->size_; + } + + /** Returns true if this node is red (as opposed to black). */ + bool red() const { + return static_cast(rep_->color_); + } + + const value_type& entry() const { + return rep_->entry_; + } + const K& key() const { + return entry().first; + } + const V& value() const { + return entry().second; + } + Color color() const { + return static_cast(rep_->color_); + } + const LlrbNode& left() const { + return rep_->left_; + } + const LlrbNode& right() const { + return rep_->right_; + } + + /** Returns a tree node with the given key-value pair set/updated. */ + template + LlrbNode insert(const K& key, + const V& value, + const Comparator& comparator) const; + + template + LlrbNode erase(const K& key, const Comparator& comparator) const; + + const LlrbNode& min() const { + const LlrbNode* node = this; + while (!node->left().empty()) { + node = &node->left(); + } + return *node; + } + + const LlrbNode& max() const { + const LlrbNode* node = this; + while (!node->right().empty()) { + node = &node->right(); + } + return *node; + } + + private: + struct Rep { + Rep(value_type&& entry, + size_type color, + size_type size, + LlrbNode left, + LlrbNode right) + : entry_{std::move(entry)}, + color_{color}, + size_{size}, + left_{std::move(left)}, + right_{std::move(right)} { + } + + Rep(value_type&& entry, size_type color, LlrbNode left, LlrbNode right) + : entry_{std::move(entry)}, + color_{color}, + size_{left.size() + 1 + right.size()}, + left_{std::move(left)}, + right_{std::move(right)} { + } + + value_type entry_; + + // Store the color in the high bit of the size to save memory. + size_type color_ : 1; + size_type size_ : 31; + + LlrbNode left_; + LlrbNode right_; + }; + + explicit LlrbNode(Rep rep) : rep_{std::make_shared(std::move(rep))} { + } + + explicit LlrbNode(const std::shared_ptr& rep) : rep_{rep} { + } + + explicit LlrbNode(std::shared_ptr&& rep) : rep_{std::move(rep)} { + } + + /** + * Returns a shared Empty node, to cut down on allocations in the base case. + */ + static const std::shared_ptr& EmptyRep() { + static const std::shared_ptr empty_rep = [] { + auto empty = std::make_shared(Rep{std::pair{}, Color::Black, + /* size= */ 0u, LlrbNode{nullptr}, + LlrbNode{nullptr}}); + + // Set up the empty Rep such that you can traverse infinitely down left + // and right links. + empty->left_.rep_ = empty; + empty->right_.rep_ = empty; + return empty; + }(); + return empty_rep; + } + + /** + * Creates a new copy of this node, duplicating the Rep but without + * duplicating the left_ and right_ children. + */ + LlrbNode Clone() const { + return LlrbNode{*rep_}; + } + + void set_size(size_type size) { + rep_->size_ = size; + } + + void set_entry(const value_type& entry) { + rep_->entry_ = entry; + } + void set_entry(value_type&& entry) { + rep_->entry_ = std::move(entry); + } + void set_value(const V& value) { + rep_->entry_.second = value; + } + void set_color(size_type color) { + rep_->color_ = color; + } + void set_left(const LlrbNode& left) { + rep_->left_ = left; + } + void set_left(LlrbNode&& left) { + rep_->left_ = std::move(left); + } + void set_right(const LlrbNode& right) { + rep_->right_ = right; + } + void set_right(LlrbNode&& right) { + rep_->right_ = std::move(right); + } + + template + LlrbNode InnerInsert(const K& key, + const V& value, + const Comparator& comparator) const; + + template + LlrbNode InnerErase(const K& key, const Comparator& comparator) const; + + void FixUp(); + void FixRootColor(); + + void RotateLeft(); + void RotateRight(); + void FlipColor(); + + void RemoveMin(); + void MoveRedLeft(); + void MoveRedRight(); + + size_type OppositeColor() const noexcept { + return rep_->color_ == Color::Red ? Color::Black : Color::Red; + } + + std::shared_ptr rep_; +}; + +template +template +LlrbNode LlrbNode::insert(const K& key, + const V& value, + const Comparator& comparator) const { + LlrbNode root = InnerInsert(key, value, comparator); + root.FixRootColor(); + return root; +} + +template +template +LlrbNode LlrbNode::InnerInsert(const K& key, + const V& value, + const Comparator& comparator) const { + if (empty()) { + return LlrbNode{Rep{{key, value}, Color::Red, LlrbNode{}, LlrbNode{}}}; + } + + // Inserting is going to result in a copy but we can save some allocations by + // creating the copy once and fixing that up, rather than copying and + // re-copying the result. + LlrbNode result = Clone(); + + const K& this_key = this->key(); + bool descending = comparator(key, this_key); + if (descending) { + result.set_left(result.left().InnerInsert(key, value, comparator)); + result.FixUp(); + + } else { + bool ascending = comparator(this_key, key); + if (ascending) { + result.set_right(result.right().InnerInsert(key, value, comparator)); + result.FixUp(); + + } else { + // keys are equal so update the value. + result.set_value(value); + } + } + return result; +} + +template +template +LlrbNode LlrbNode::erase(const K& key, + const Comparator& comparator) const { + LlrbNode root = InnerErase(key, comparator); + root.FixRootColor(); + return root; +} + +template +template +LlrbNode LlrbNode::InnerErase(const K& key, + const Comparator& comparator) const { + if (empty()) { + // Empty node already frozen + return LlrbNode{}; + } + + LlrbNode n = Clone(); + + bool descending = comparator(key, n.key()); + if (descending) { + if (!n.left().empty() && !n.left().red() && !n.left().left().red()) { + n.MoveRedLeft(); + } + n.set_left(n.left().InnerErase(key, comparator)); + + } else { + if (n.left().red()) { + n.RotateRight(); + } + + if (!n.right().empty() && !n.right().red() && !n.right().left().red()) { + n.MoveRedRight(); + } + + if (util::Compare(key, n.key(), comparator) == + util::ComparisonResult::Same) { + if (n.right().empty()) { + return LlrbNode{}; + + } else { + // Move the minimum node from the right subtree in place of this node. + LlrbNode smallest = n.right().min(); + LlrbNode new_right = n.right().Clone(); + new_right.RemoveMin(); + + n.set_entry(smallest.entry()); + n.set_right(std::move(new_right)); + } + } else { + n.set_right(n.right().InnerErase(key, comparator)); + } + } + n.FixUp(); + return n; +} + +template +void LlrbNode::FixUp() { + set_size(left().size() + 1 + right().size()); + + if (right().red() && !left().red()) { + RotateLeft(); + } + if (left().red() && left().left().red()) { + RotateRight(); + } + if (left().red() && right().red()) { + FlipColor(); + } +} + +/** + * Fixes the root node so its color is always black. + * + * This change is safe because a red `root` must be a new root: + * * If the key is not found, InnerErase returns an existing root, but + * existing roots will already be black (by the invariant). + * * If the key is found, InnerErase returns a new root, which is safe to + * modify. + */ +template +void LlrbNode::FixRootColor() { + if (red()) { + rep_->color_ = Color::Black; + } +} + +template +void LlrbNode::RemoveMin() { + // If the left node is empty then the right node must be empty (because the + // tree is left-leaning) and this node must be the minimum. + if (left().empty()) { + *this = LlrbNode{}; + return; + } + + if (!left().red() && !left().left().red()) { + MoveRedLeft(); + } + + LlrbNode new_left = left().Clone(); + new_left.RemoveMin(); + set_left(std::move(new_left)); + FixUp(); +} + +template +void LlrbNode::MoveRedLeft() { + FlipColor(); + if (right().left().red()) { + LlrbNode new_right = right().Clone(); + new_right.RotateRight(); + set_right(std::move(new_right)); + RotateLeft(); + FlipColor(); + } +} + +template +void LlrbNode::MoveRedRight() { + FlipColor(); + if (left().left().red()) { + RotateRight(); + FlipColor(); + } +} + +/* Rotates left: + * + * X R + * / \ / \ + * L R => X RR + * / \ / \ + * RL RR L RL + */ +template +void LlrbNode::RotateLeft() { + LlrbNode new_left{ + Rep{std::move(rep_->entry_), Color::Red, left(), right().left()}}; + + // size_ and color remain unchanged after a rotation. + set_entry(right().entry()); + set_left(std::move(new_left)); + set_right(right().right()); +} + +/* Rotates right: + * + * X L + * / \ / \ + * L R => LL X + * / \ / \ + * LL LR LR R + */ +template +void LlrbNode::RotateRight() { + LlrbNode new_right{ + Rep{std::move(rep_->entry_), Color::Red, left().right(), right()}}; + + // size_ remains unchanged after a rotation. Preserve color too. + set_entry(left().entry()); + set_left(left().left()); + set_right(std::move(new_right)); +} + +template +void LlrbNode::FlipColor() { + LlrbNode new_left = left().Clone(); + new_left.set_color(left().OppositeColor()); + + LlrbNode new_right = right().Clone(); + new_right.set_color(right().OppositeColor()); + + // Preserve contents_ and size_ + set_color(OppositeColor()); + set_left(std::move(new_left)); + set_right(std::move(new_right)); +} + +} // namespace impl +} // namespace immutable +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_IMMUTABLE_LLRB_NODE_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/immutable/llrb_node_iterator.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/immutable/llrb_node_iterator.h new file mode 100644 index 0000000..3092678 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/immutable/llrb_node_iterator.h @@ -0,0 +1,216 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_IMMUTABLE_LLRB_NODE_ITERATOR_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_IMMUTABLE_LLRB_NODE_ITERATOR_H_ + +#include +#include +#include + +#include "Firestore/core/src/firebase/firestore/immutable/llrb_node.h" +#include "Firestore/core/src/firebase/firestore/util/comparison.h" +#include "Firestore/core/src/firebase/firestore/util/hard_assert.h" + +namespace firebase { +namespace firestore { +namespace immutable { +namespace impl { + +/** + * A forward iterator for traversing LlrbNodes. LlrbNodes represent the nodes + * in a tree implementing a sorted map so iterating with LlrbNodeIterator is + * an in-order traversal of the map. + * + * ## Complexity + * + * LlrbNode is an immutable tree, where mutations create new trees without + * invalidating any of the old instances. This means the tree cannot contain + * parent pointers and thus this iterator implementation must keep an explicit + * stack. + * + * For an underlying tree of size `n`: + * + * * LlrbNodeIterator uses `O(lg(n))` memory for its stack, and + * * incrementing an iterator is an `O(lg(n))` operation. + * + * ## Invalidation and Comparison + * + * LlrbNodeIterators compare based on the identity of the nodes themselves, + * not based on the values of the keys in the nodes. When adding and removing + * the same key and iterator obtained before and after will not compare equal. + * + * LlrbNodeIterators are not invalidated in any conventional sense because + * mutations of the underlying tree create new trees. Together this means that + * any given version of the tree can be iterated over from the same iterator + * repeatedly, but a "mutable view" of the tree kept by replacing the pointer + * to the root is effectively invalidated on each mutation. + * + * Note: LlrbNodeIterator does not extend the lifetime of its underlying tree. + */ +template +class LlrbNodeIterator { + public: + using node_type = N; + using key_type = typename node_type::first_type; + + using stack_type = std::stack; + + using iterator_category = std::forward_iterator_tag; + using value_type = typename node_type::value_type; + + using pointer = typename node_type::value_type const*; + using reference = typename node_type::value_type const&; + using difference_type = std::ptrdiff_t; + + explicit LlrbNodeIterator(stack_type&& stack) : stack_(std::move(stack)) { + } + + /** + * Constructs an iterator starting at the first node in the iteration + * sequence of the tree represented by the given root node (i.e. it points at + * the left-most node). + */ + static LlrbNodeIterator Begin(const node_type* root) { + stack_type stack; + AccumulateLeft(root, &stack); + return LlrbNodeIterator{std::move(stack)}; + } + + /** + * Constructs an iterator pointing at the end of the iteration sequence of the + * tree pointed to by the given node (i.e. one past the right-most node) + */ + static LlrbNodeIterator End() { + return LlrbNodeIterator{stack_type{}}; + } + + // Default constructor to conform to the requirements of ForwardIterator + LlrbNodeIterator() { + } + + /** + * Constructs an iterator pointing to the first node whose key is not less + * than the given key. If the key is in the tree then the lower bound will be + * the node containing the key. If the key is not in the tree, the lower bound + * will the first node greater than the key. If all nodes in the tree are less + * than the given key, returns an equivalent to `End()`. + */ + template + static LlrbNodeIterator LowerBound(const node_type* root, + const key_type& key, + const C& comparator) { + stack_type stack; + + const node_type* node = root; + while (!node->empty()) { + util::ComparisonResult cmp = util::Compare(key, node->key(), comparator); + if (cmp == util::ComparisonResult::Same) { + // Found exactly what we're looking for so we're done. + stack.push(node); + return LlrbNodeIterator{std::move(stack)}; + + } else if (cmp == util::ComparisonResult::Ascending) { + // key < node.key (for the forward direction) + stack.push(node); + node = &node->left(); + } else { + // key > node.key (for the forward direction). Don't put this in the + // stack because we don't need to revisit it in the iteration order. + node = &node->right(); + } + } + + return LlrbNodeIterator{std::move(stack)}; + } + + /** + * Returns true if this iterator points at the end of the iteration sequence. + */ + bool is_end() const { + return stack_.empty(); + } + + /** + * Returns the address of the entry in the node that this iterator points to. + * This can only be called if `end()` is false. + */ + pointer get() const { + HARD_ASSERT(!is_end()); + return &(stack_.top()->entry()); + } + + reference operator*() const { + return *get(); + } + + pointer operator->() const { + return get(); + } + + LlrbNodeIterator& operator++() { + HARD_ASSERT(!is_end()); + + // Pop the stack, moving the currently pointed to node to the parent. + const node_type* node = stack_.top(); + stack_.pop(); + + // If the popped node has a right subtree that has to precede the parent in + // the iteration order so push those on. + node = &node->right(); + AccumulateLeft(node, &stack_); + + return *this; + } + + LlrbNodeIterator operator++(int /*unused*/) { + LlrbNodeIterator result = *this; + ++*this; + return result; + } + + friend bool operator==(const LlrbNodeIterator& a, const LlrbNodeIterator& b) { + if (a.is_end()) { + return b.is_end(); + } else if (b.is_end()) { + return false; + } else { + const key_type& left_key = a.get()->first; + const key_type& right_key = b.get()->first; + return left_key == right_key; + } + } + + bool operator!=(const LlrbNodeIterator& b) const { + return !(*this == b); + } + + private: + static void AccumulateLeft(const node_type* node, stack_type* stack) { + for (; !node->empty(); node = &node->left()) { + stack->push(node); + } + } + + stack_type stack_; +}; + +} // namespace impl +} // namespace immutable +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_IMMUTABLE_LLRB_NODE_ITERATOR_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/immutable/map_entry.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/immutable/map_entry.h new file mode 100644 index 0000000..b2b3c97 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/immutable/map_entry.h @@ -0,0 +1,66 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_IMMUTABLE_MAP_ENTRY_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_IMMUTABLE_MAP_ENTRY_H_ + +#include +#include + +namespace firebase { +namespace firestore { +namespace immutable { + +/** + * Compares two keys out of a map entry. + * + * @tparam K The type of the first value in the pair. + * @tparam V The type of the second value in the pair. + * @tparam C The comparator for use for values of type K + */ +template > +struct KeyComparator { + using pair_type = std::pair; + + explicit KeyComparator(const C& comparator = C()) + : key_comparator_(comparator) { + } + + bool operator()(const K& lhs, const pair_type& rhs) const noexcept { + return key_comparator_(lhs, rhs.first); + } + + bool operator()(const pair_type& lhs, const K& rhs) const noexcept { + return key_comparator_(lhs.first, rhs); + } + + bool operator()(const pair_type& lhs, const pair_type& rhs) const noexcept { + return key_comparator_(lhs.first, rhs.first); + } + + const C& comparator() const { + return key_comparator_; + } + + private: + C key_comparator_; +}; + +} // namespace immutable +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_IMMUTABLE_MAP_ENTRY_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/immutable/sorted_container.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/immutable/sorted_container.cc new file mode 100644 index 0000000..637270d --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/immutable/sorted_container.cc @@ -0,0 +1,29 @@ +/* + * Copyright 2018 Google + * + * 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 "Firestore/core/src/firebase/firestore/immutable/sorted_container.h" + +namespace firebase { +namespace firestore { +namespace immutable { + +// Define external storage for constants: +constexpr SortedContainer::size_type SortedContainer::npos; +constexpr SortedMapBase::size_type SortedMapBase::kFixedSize; + +} // namespace immutable +} // namespace firestore +} // namespace firebase diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/immutable/sorted_container.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/immutable/sorted_container.h new file mode 100644 index 0000000..1cf5eb7 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/immutable/sorted_container.h @@ -0,0 +1,79 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_IMMUTABLE_SORTED_CONTAINER_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_IMMUTABLE_SORTED_CONTAINER_H_ + +#include + +namespace firebase { +namespace firestore { +namespace immutable { + +/** + * A base class for implementing immutable sorted containers, containing types + * and constants that don't depend upon the template parameters to the main + * class. + * + * Note that this exists as a base class rather than as just a namespace in + * order to make it possible for users of the SortedMap classes to avoid needing + * to declare storage for each instantiation of the template. + */ +class SortedContainer { + public: + /** + * The type of size() methods on immutable collections. Note: + * * This is not size_t specifically to save space in the TreeSortedMap + * implementation. + * * This remains unsigned for straightforward casting to size_t. + */ + using size_type = uint32_t; + + /** + * A sentinel return value that indicates not found. Functionally similar to + * std::string::npos. + */ + static constexpr size_type npos = static_cast(-1); +}; + +/** + * A base class for implementing sorted maps, containing types and constants + * that don't depend upon the template parameters to the main class. + * + * Note that this exists as a base class rather than as just a namespace in + * order to make it possible for users of the SortedMap classes to avoid needing + * to declare storage for each instantiation of the template. + */ +class SortedMapBase : public SortedContainer { + public: + /** + * The maximum size of an ArraySortedMap. + * + * This is the size threshold where we use a tree backed sorted map instead of + * an array backed sorted map. This is a more or less arbitrary chosen value, + * that was chosen to be large enough to fit most of object kind of Firebase + * data, but small enough to not notice degradation in performance for + * inserting and lookups. Feel free to empirically determine this constant, + * but don't expect much gain in real world performance. + */ + static constexpr size_type kFixedSize = 25; +}; + +} // namespace immutable +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_IMMUTABLE_SORTED_CONTAINER_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/immutable/sorted_map.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/immutable/sorted_map.h new file mode 100644 index 0000000..f3c998b --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/immutable/sorted_map.h @@ -0,0 +1,384 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_IMMUTABLE_SORTED_MAP_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_IMMUTABLE_SORTED_MAP_H_ + +#include + +#include "Firestore/core/src/firebase/firestore/immutable/array_sorted_map.h" +#include "Firestore/core/src/firebase/firestore/immutable/keys_view.h" +#include "Firestore/core/src/firebase/firestore/immutable/sorted_container.h" +#include "Firestore/core/src/firebase/firestore/immutable/sorted_map_iterator.h" +#include "Firestore/core/src/firebase/firestore/immutable/tree_sorted_map.h" +#include "Firestore/core/src/firebase/firestore/util/comparison.h" +#include "absl/base/attributes.h" + +namespace firebase { +namespace firestore { +namespace immutable { + +/** + * SortedMap is a value type containing a map. It is immutable, but + * has methods to efficiently create new maps that are mutations of it. + */ +template > +class SortedMap : public SortedMapBase { + public: + using key_type = K; + using mapped_type = V; + /** The type of the entries stored in the map. */ + using value_type = std::pair; + using array_type = impl::ArraySortedMap; + using tree_type = impl::TreeSortedMap; + + using const_iterator = impl::SortedMapIterator< + value_type, + typename impl::FixedArray::const_iterator, + typename impl::LlrbNode::const_iterator>; + + using const_key_iterator = util::iterator_first; + + /** + * Creates an empty SortedMap. + */ + explicit SortedMap(const C& comparator = {}) + : SortedMap{array_type{comparator}} { + } + + /** + * Creates an SortedMap containing the given entries. + */ + SortedMap(std::initializer_list entries, + const C& comparator = {}) { + if (entries.size() <= kFixedSize) { + tag_ = Tag::Array; + new (&array_) array_type{entries, comparator}; + } else { + new (&tree_) tree_type{tree_type::Create(entries, comparator)}; + } + } + + SortedMap(const SortedMap& other) : tag_{other.tag_} { + switch (tag_) { + case Tag::Array: + new (&array_) array_type{other.array_}; + break; + case Tag::Tree: + new (&tree_) tree_type{other.tree_}; + break; + } + } + + SortedMap(SortedMap&& other) noexcept : tag_{other.tag_} { + switch (tag_) { + case Tag::Array: + new (&array_) array_type{std::move(other.array_)}; + break; + case Tag::Tree: + new (&tree_) tree_type{std::move(other.tree_)}; + break; + } + } + + ~SortedMap() { + switch (tag_) { + case Tag::Array: + array_.~ArraySortedMap(); + break; + case Tag::Tree: + tree_.~TreeSortedMap(); + break; + } + } + + SortedMap& operator=(const SortedMap& other) { + if (tag_ == other.tag_) { + switch (tag_) { + case Tag::Array: + array_ = other.array_; + break; + case Tag::Tree: + tree_ = other.tree_; + break; + } + } else { + this->~SortedMap(); + new (this) SortedMap{other}; + } + return *this; + } + + SortedMap& operator=(SortedMap&& other) noexcept { + if (tag_ == other.tag_) { + switch (tag_) { + case Tag::Array: + array_ = std::move(other.array_); + break; + case Tag::Tree: + tree_ = std::move(other.tree_); + break; + } + } else { + this->~SortedMap(); + new (this) SortedMap{std::move(other)}; + } + return *this; + } + + /** Returns true if the map contains no elements. */ + bool empty() const { + switch (tag_) { + case Tag::Array: + return array_.empty(); + case Tag::Tree: + return tree_.empty(); + } + UNREACHABLE(); + } + + /** Returns the number of items in this map. */ + size_type size() const { + switch (tag_) { + case Tag::Array: + return array_.size(); + case Tag::Tree: + return tree_.size(); + } + UNREACHABLE(); + } + + /** + * Creates a new map identical to this one, but with a key-value pair added or + * updated. + * + * @param key The key to insert/update. + * @param value The value to associate with the key. + * @return A new dictionary with the added/updated value. + */ + ABSL_MUST_USE_RESULT SortedMap insert(const K& key, const V& value) const { + switch (tag_) { + case Tag::Array: + if (array_.size() >= kFixedSize) { + // Strictly speaking this conversion is more eager than it needs to + // be since we could be replacing an existing key. However, the + // benefit of using the array for small maps doesn't really depend on + // exactly where this cut-off happens and just unconditionally + // converting if the next insertion could overflow keeps things + // simpler. + tree_type tree = tree_type::Create(array_, comparator()); + return SortedMap{tree.insert(key, value)}; + } else { + return SortedMap{array_.insert(key, value)}; + } + case Tag::Tree: + return SortedMap{tree_.insert(key, value)}; + } + UNREACHABLE(); + } + + /** + * Creates a new map identical to this one, but with a key removed from it. + * + * @param key The key to remove. + * @return A new map without that value. + */ + ABSL_MUST_USE_RESULT SortedMap erase(const K& key) const { + switch (tag_) { + case Tag::Array: + return SortedMap{array_.erase(key)}; + case Tag::Tree: + tree_type result = tree_.erase(key); + if (result.empty()) { + // Flip back to the array representation for empty arrays. + return SortedMap{comparator()}; + } + return SortedMap{std::move(result)}; + } + UNREACHABLE(); + } + + bool contains(const K& key) const { + switch (tag_) { + case Tag::Array: + return array_.contains(key); + case Tag::Tree: + return tree_.contains(key); + } + UNREACHABLE(); + } + + /** + * Finds a value in the map. + * + * @param key The key to look up. + * @return An iterator pointing to the entry containing the key, or end() if + * not found. + */ + const_iterator find(const K& key) const { + switch (tag_) { + case Tag::Array: + return const_iterator(array_.find(key)); + case Tag::Tree: + return const_iterator{tree_.find(key)}; + } + UNREACHABLE(); + } + + /** + * Finds the index of the given key in the map. + * + * @param key The key to look up. + * @return The index of the entry containing the key, or npos if not found. + */ + size_type find_index(const K& key) const { + switch (tag_) { + case Tag::Array: + return array_.find_index(key); + case Tag::Tree: + return tree_.find_index(key); + } + UNREACHABLE(); + } + + /** + * Finds the first entry in the map containing a key greater than or equal + * to the given key. + * + * @param key The key to look up. + * @return An iterator pointing to the entry containing the key or the next + * largest key. Can return end() if all keys in the map are less than the + * requested key. + */ + const_iterator lower_bound(const K& key) const { + switch (tag_) { + case Tag::Array: + return const_iterator(array_.lower_bound(key)); + case Tag::Tree: + return const_iterator{tree_.lower_bound(key)}; + } + UNREACHABLE(); + } + + const_iterator min() const { + switch (tag_) { + case Tag::Array: + return const_iterator(array_.min()); + case Tag::Tree: + return const_iterator{tree_.min()}; + } + UNREACHABLE(); + } + + const_iterator max() const { + switch (tag_) { + case Tag::Array: + return const_iterator(array_.max()); + case Tag::Tree: + return const_iterator{tree_.max()}; + } + UNREACHABLE(); + } + + /** + * Returns an iterator pointing to the first entry in the map. If there are + * no entries in the map, begin() == end(). + */ + const_iterator begin() const { + switch (tag_) { + case Tag::Array: + return const_iterator{array_.begin()}; + case Tag::Tree: + return const_iterator{tree_.begin()}; + } + UNREACHABLE(); + } + + /** + * Returns an iterator pointing past the last entry in the map. + */ + const_iterator end() const { + switch (tag_) { + case Tag::Array: + return const_iterator{array_.end()}; + case Tag::Tree: + return const_iterator{tree_.end()}; + } + UNREACHABLE(); + } + + /** + * Returns a view of this SortedMap containing just the keys that have been + * inserted. + */ + const util::range keys() const { + return impl::KeysView(*this); + } + + /** + * Returns a view of this SortedMap containing just the keys that have been + * inserted that are greater than or equal to the given key. + */ + const util::range keys_from(const K& key) const { + return impl::KeysViewFrom(*this, key); + } + + /** + * Returns a view of this SortedMap containing just the keys that have been + * inserted that are greater than or equal to the given start_key and less + * than the given end_key. + */ + const util::range keys_in(const K& start_key, + const K& end_key) const { + return impl::KeysViewIn(*this, start_key, end_key, comparator()); + } + + private: + explicit SortedMap(array_type&& array) + : tag_{Tag::Array}, array_{std::move(array)} { + } + + explicit SortedMap(tree_type&& tree) + : tag_{Tag::Tree}, tree_{std::move(tree)} { + } + + const C& comparator() const { + switch (tag_) { + case Tag::Array: + return array_.comparator(); + case Tag::Tree: + return tree_.comparator(); + } + UNREACHABLE(); + } + + enum class Tag { + Array, + Tree, + }; + + Tag tag_; + union { + array_type array_; + tree_type tree_; + }; +}; + +} // namespace immutable +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_IMMUTABLE_SORTED_MAP_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/immutable/sorted_map_iterator.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/immutable/sorted_map_iterator.h new file mode 100644 index 0000000..20c11a7 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/immutable/sorted_map_iterator.h @@ -0,0 +1,194 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_IMMUTABLE_SORTED_MAP_ITERATOR_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_IMMUTABLE_SORTED_MAP_ITERATOR_H_ + +#include + +#include "Firestore/core/src/firebase/firestore/immutable/array_sorted_map.h" +#include "Firestore/core/src/firebase/firestore/immutable/tree_sorted_map.h" + +namespace firebase { +namespace firestore { +namespace immutable { +namespace impl { + +template +class SortedMapIterator { + public: + using iterator_category = std::forward_iterator_tag; + using value_type = V; + using pointer = const value_type*; + using reference = const value_type&; + using difference_type = std::ptrdiff_t; + + public: + // Default constructor to conform to the requirements of ForwardIterator + SortedMapIterator() : tag_{Tag::Array}, array_iter_{} { + } + + explicit SortedMapIterator(ArrayIter&& delegate) + : tag_{Tag::Array}, array_iter_{std::move(delegate)} { + } + + explicit SortedMapIterator(TreeIter&& delegate) + : tag_{Tag::Tree}, tree_iter_{std::move(delegate)} { + } + + SortedMapIterator(const SortedMapIterator& other) : tag_(other.tag_) { + switch (tag_) { + case Tag::Array: + new (&array_iter_) ArrayIter{other.array_iter_}; + break; + case Tag::Tree: + new (&tree_iter_) TreeIter{other.tree_iter_}; + break; + } + } + + SortedMapIterator(SortedMapIterator&& other) : tag_(other.tag_) { + switch (tag_) { + case Tag::Array: + new (&array_iter_) ArrayIter{std::move(other.array_iter_)}; + break; + case Tag::Tree: + new (&tree_iter_) TreeIter{std::move(other.tree_iter_)}; + break; + } + } + + ~SortedMapIterator() { + switch (tag_) { + case Tag::Array: + array_iter_.~ArrayIter(); + break; + case Tag::Tree: + tree_iter_.~TreeIter(); + break; + } + } + + SortedMapIterator& operator=(const SortedMapIterator& other) { + if (tag_ == other.tag_) { + switch (tag_) { + case Tag::Array: + array_iter_ = other.array_iter_; + break; + case Tag::Tree: + tree_iter_ = other.tree_iter_; + break; + } + } else { + this->~SortedMapIterator(); + new (this) SortedMapIterator(other); + } + return *this; + } + + SortedMapIterator& operator=(SortedMapIterator&& other) { + if (tag_ == other.tag_) { + switch (tag_) { + case Tag::Array: + array_iter_ = std::move(other.array_iter_); + break; + case Tag::Tree: + tree_iter_ = std::move(other.tree_iter_); + break; + } + } else { + this->~SortedMapIterator(); + new (this) SortedMapIterator(std::move(other)); + } + return *this; + } + + pointer get() const { + switch (tag_) { + case Tag::Array: + // std::array::iterator is not guaranteed to be a bare pointer but will + // be a RandomAccessIterator which does have operator*(). + return &*array_iter_; + case Tag::Tree: + return tree_iter_.get(); + } + UNREACHABLE(); + } + + reference operator*() const { + return *get(); + } + + pointer operator->() const { + return get(); + } + + SortedMapIterator& operator++() { + switch (tag_) { + case Tag::Array: + ++array_iter_; + break; + case Tag::Tree: + ++tree_iter_; + break; + } + return *this; + } + + SortedMapIterator operator++(int /*unused*/) { + SortedMapIterator result = *this; + ++*this; + return result; + } + + friend bool operator==(const SortedMapIterator& a, + const SortedMapIterator& b) { + if (a.tag_ != b.tag_) { + return false; + } + + switch (a.tag_) { + case Tag::Array: + return a.array_iter_ == b.array_iter_; + case Tag::Tree: + return a.tree_iter_ == b.tree_iter_; + } + UNREACHABLE(); + } + + bool operator!=(const SortedMapIterator& b) const { + return !(*this == b); + } + + private: + enum class Tag { + Array, + Tree, + }; + + Tag tag_; + union { + ArrayIter array_iter_; + TreeIter tree_iter_; + }; +}; + +} // namespace impl +} // namespace immutable +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_IMMUTABLE_SORTED_MAP_ITERATOR_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/immutable/sorted_set.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/immutable/sorted_set.h new file mode 100644 index 0000000..36b6e16 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/immutable/sorted_set.h @@ -0,0 +1,158 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_IMMUTABLE_SORTED_SET_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_IMMUTABLE_SORTED_SET_H_ + +#include +#include + +#include "Firestore/core/src/firebase/firestore/immutable/sorted_container.h" +#include "Firestore/core/src/firebase/firestore/immutable/sorted_map.h" +#include "Firestore/core/src/firebase/firestore/util/comparison.h" +#include "Firestore/core/src/firebase/firestore/util/hard_assert.h" +#include "Firestore/core/src/firebase/firestore/util/hashing.h" +#include "absl/base/attributes.h" + +namespace firebase { +namespace firestore { +namespace immutable { + +namespace impl { + +// An empty value to associate with keys in the underlying map. +struct Empty { + friend bool operator==(Empty /* left */, Empty /* right */) { + return true; + } +}; + +} // namespace impl + +template , + typename V = impl::Empty, + typename M = SortedMap> +class SortedSet : public SortedContainer { + public: + using size_type = typename M::size_type; + using value_type = K; + + using const_iterator = typename M::const_key_iterator; + + explicit SortedSet(const C& comparator = C()) : map_{comparator} { + } + + explicit SortedSet(const M& map) : map_{map} { + } + + explicit SortedSet(M&& map) : map_{std::move(map)} { + } + + SortedSet(std::initializer_list entries, const C& comparator = {}) + : map_{comparator} { + for (auto&& value : entries) { + map_ = map_.insert(value, {}); + } + } + + bool empty() const { + return map_.empty(); + } + + size_type size() const { + return map_.size(); + } + + ABSL_MUST_USE_RESULT SortedSet insert(const K& key) const { + return SortedSet{map_.insert(key, {})}; + } + + ABSL_MUST_USE_RESULT SortedSet erase(const K& key) const { + return SortedSet{map_.erase(key)}; + } + + bool contains(const K& key) const { + return map_.contains(key); + } + + const_iterator find(const K& key) const { + return const_iterator{map_.find(key)}; + } + + size_type find_index(const K& key) const { + return map_.find_index(key); + } + + const_iterator min() const { + return const_iterator{map_.min()}; + } + + const_iterator max() const { + return const_iterator{map_.max()}; + } + + const_iterator begin() const { + return const_iterator{map_.begin()}; + } + + const_iterator end() const { + return const_iterator{map_.end()}; + } + + /** + * Returns a view of this SortedSet containing just the keys that have been + * inserted that are greater than or equal to the given key. + */ + const util::range values_from(const K& key) const { + return map_.keys_from(key); + } + + /** + * Returns a view of this SortedSet containing just the keys that have been + * inserted that are greater than or equal to the given start_key and less + * than the given end_key. + */ + const util::range values_in(const K& start_key, + const K& end_key) const { + return map_.keys_in(start_key, end_key); + } + + friend bool operator==(const SortedSet& lhs, const SortedSet& rhs) { + if (lhs.size() != rhs.size()) { + return false; + } + return std::equal(lhs.begin(), lhs.end(), rhs.begin()); + } + + friend bool operator!=(const SortedSet& lhs, const SortedSet& rhs) { + return !(lhs == rhs); + } + + private: + M map_; +}; + +template +SortedSet MakeSortedSet(const SortedMap& map) { + return SortedSet{map}; +} + +} // namespace immutable +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_IMMUTABLE_SORTED_SET_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/immutable/tree_sorted_map.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/immutable/tree_sorted_map.h new file mode 100644 index 0000000..9a1635c --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/immutable/tree_sorted_map.h @@ -0,0 +1,263 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_IMMUTABLE_TREE_SORTED_MAP_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_IMMUTABLE_TREE_SORTED_MAP_H_ + +#include +#include +#include +#include +#include + +#include "Firestore/core/src/firebase/firestore/immutable/keys_view.h" +#include "Firestore/core/src/firebase/firestore/immutable/llrb_node.h" +#include "Firestore/core/src/firebase/firestore/immutable/map_entry.h" +#include "Firestore/core/src/firebase/firestore/immutable/sorted_container.h" +#include "Firestore/core/src/firebase/firestore/util/comparator_holder.h" +#include "Firestore/core/src/firebase/firestore/util/comparison.h" + +namespace firebase { +namespace firestore { +namespace immutable { +namespace impl { + +/** + * TreeSortedMap is a value type containing a map. It is immutable, but has + * methods to efficiently create new maps that are mutations of it. + */ +template > +class TreeSortedMap : public SortedMapBase, public util::ComparatorHolder { + public: + /** + * The type of the entries stored in the map. + */ + using value_type = std::pair; + + /** + * The type of the node containing entries of value_type. + */ + using node_type = LlrbNode; + using const_iterator = typename node_type::const_iterator; + using const_key_iterator = util::iterator_first; + + /** + * Creates an empty TreeSortedMap. + */ + explicit TreeSortedMap(const C& comparator = {}) + : util::ComparatorHolder{comparator} { + } + + /** + * Creates a TreeSortedMap from a range of pairs to insert. + */ + template + static TreeSortedMap Create(const Range& range, const C& comparator) { + node_type node; + for (auto&& element : range) { + node = node.insert(element.first, element.second, comparator); + } + return TreeSortedMap{std::move(node), comparator}; + } + + /** Returns true if the map contains no elements. */ + bool empty() const { + return root_.empty(); + } + + /** Returns the number of items in this map. */ + size_type size() const { + return root_.size(); + } + + const node_type& root() const { + return root_; + } + + /** + * Creates a new map identical to this one, but with a key-value pair added or + * updated. + * + * @param key The key to insert/update. + * @param value The value to associate with the key. + * @return A new dictionary with the added/updated value. + */ + TreeSortedMap insert(const K& key, const V& value) const { + const C& comparator = this->comparator(); + return TreeSortedMap{root_.insert(key, value, comparator), comparator}; + } + + /** + * Creates a new map identical to this one, but with a key removed from it. + * + * @param key The key to remove. + * @return A new map without that value. + */ + TreeSortedMap erase(const K& key) const { + const C& comparator = this->comparator(); + return TreeSortedMap{root_.erase(key, comparator), comparator}; + } + + bool contains(const K& key) const { + // Inline the tree traversal here to avoid building up the stack required + // to construct a full iterator. + const C& comparator = this->comparator(); + const node_type* node = &root(); + while (!node->empty()) { + util::ComparisonResult cmp = util::Compare(key, node->key(), comparator); + if (cmp == util::ComparisonResult::Same) { + return true; + } else if (cmp == util::ComparisonResult::Ascending) { + node = &node->left(); + } else { + node = &node->right(); + } + } + return false; + } + + /** + * Finds a value in the map. + * + * @param key The key to look up. + * @return An iterator pointing to the entry containing the key, or end() if + * not found. + */ + const_iterator find(const K& key) const { + const_iterator found = lower_bound(key); + if (!found.is_end() && !this->comparator()(key, found->first)) { + return found; + } else { + return end(); + } + } + + /** + * Finds the index of the given key in the map. + * + * @param key The key to look up. + * @return The index of the entry containing the key, or npos if not found. + */ + size_type find_index(const K& key) const { + const C& comparator = this->comparator(); + + size_type pruned_nodes = 0; + const node_type* node = &root_; + while (!node->empty()) { + util::ComparisonResult cmp = util::Compare(key, node->key(), comparator); + if (cmp == util::ComparisonResult::Same) { + return pruned_nodes + node->left().size(); + + } else if (cmp == util::ComparisonResult::Ascending) { + node = &node->left(); + + } else if (cmp == util::ComparisonResult::Descending) { + pruned_nodes += node->left().size() + 1; + node = &node->right(); + } + } + return npos; + } + + /** + * Finds the first entry in the map containing a key greater than or equal + * to the given key. + * + * @param key The key to look up. + * @return An iterator pointing to the entry containing the key or the next + * largest key. Can return end() if all keys in the map are less than the + * requested key. + */ + const_iterator lower_bound(const K& key) const { + return const_iterator::LowerBound(&root_, key, this->comparator()); + } + + const_iterator min() const { + return begin(); + } + + const_iterator max() const { + if (empty()) { + return end(); + } + + const node_type& max_node = root_.max(); + typename const_iterator::stack_type stack; + stack.push(&max_node); + return const_iterator{std::move(stack)}; + } + + /** + * Returns a forward iterator pointing to the first entry in the map. If there + * are no entries in the map, begin() == end(). + * + * See LlrbNodeIterator for details + */ + const_iterator begin() const { + return const_iterator::Begin(&root_); + } + + /** + * Returns an iterator pointing past the last entry in the map. + */ + const_iterator end() const { + return const_iterator::End(); + } + + /** + * Returns a view of this SortedMap containing just the keys that have been + * inserted. + */ + const util::range keys() const { + return KeysView(*this); + } + + /** + * Returns a view of this SortedMap containing just the keys that have been + * inserted that are greater than or equal to the given key. + */ + const util::range keys_from(const K& key) const { + return KeysViewFrom(*this, key); + } + + /** + * Returns a view of this SortedMap containing just the keys that have been + * inserted that are greater than or equal to the given start_key and less + * than the given end_key. + */ + const util::range keys_in(const K& start_key, + const K& end_key) const { + return impl::KeysViewIn(*this, start_key, end_key, this->comparator()); + } + + private: + TreeSortedMap(node_type&& root, const C& comparator) noexcept + : util::ComparatorHolder{comparator}, root_{std::move(root)} { + } + + TreeSortedMap Wrap(node_type&& root) noexcept { + return TreeSortedMap{std::move(root), this->comparator()}; + } + + node_type root_; +}; + +} // namespace impl +} // namespace immutable +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_IMMUTABLE_TREE_SORTED_MAP_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/document_key_reference.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/document_key_reference.cc new file mode 100644 index 0000000..61c1b71 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/document_key_reference.cc @@ -0,0 +1,71 @@ +/* + * Copyright 2018 Google + * + * 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 "Firestore/core/src/firebase/firestore/local/document_key_reference.h" + +#include +#include + +#include "Firestore/core/src/firebase/firestore/model/document_key.h" +#include "Firestore/core/src/firebase/firestore/util/comparison.h" +#include "Firestore/core/src/firebase/firestore/util/hashing.h" + +namespace firebase { +namespace firestore { +namespace local { + +using model::DocumentKey; +using util::ComparisonResult; + +bool operator==(const DocumentKeyReference& lhs, + const DocumentKeyReference& rhs) { + return lhs.key_ == rhs.key_ && lhs.ref_id_ == rhs.ref_id_; +} + +size_t DocumentKeyReference::Hash() const { + return util::Hash(key_.ToString(), ref_id_); +} + +std::string DocumentKeyReference::ToString() const { + return util::StringFormat("", + key_.ToString(), ref_id_); +} + +/** Sorts document references by key then ID. */ +bool DocumentKeyReference::ByKey::operator()( + const DocumentKeyReference& lhs, const DocumentKeyReference& rhs) const { + util::Comparator key_less; + if (key_less(lhs.key_, rhs.key_)) return true; + if (key_less(rhs.key_, lhs.key_)) return false; + + util::Comparator id_less; + return id_less(lhs.ref_id_, rhs.ref_id_); +} + +/** Sorts document references by ID then key. */ +bool DocumentKeyReference::ById::operator()( + const DocumentKeyReference& lhs, const DocumentKeyReference& rhs) const { + util::Comparator id_less; + if (id_less(lhs.ref_id_, rhs.ref_id_)) return true; + if (id_less(rhs.ref_id_, lhs.ref_id_)) return false; + + util::Comparator key_less; + return key_less(lhs.key_, rhs.key_); +} + +} // namespace local +} // namespace firestore +} // namespace firebase diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/document_key_reference.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/document_key_reference.h new file mode 100644 index 0000000..257971b --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/document_key_reference.h @@ -0,0 +1,97 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_LOCAL_DOCUMENT_KEY_REFERENCE_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_LOCAL_DOCUMENT_KEY_REFERENCE_H_ + +#include +#include + +#include "Firestore/core/src/firebase/firestore/model/document_key.h" +#include "Firestore/core/src/firebase/firestore/model/types.h" +#include "Firestore/core/src/firebase/firestore/util/comparison.h" + +namespace firebase { +namespace firestore { +namespace local { + +/** + * An immutable value used to keep track of an association between some + * referencing target or batch and a document key that the target or batch + * references. + * + * A reference can be from either listen targets (identified by their TargetId) + * or mutation batches (identified by their BatchId). See FSTGarbageCollector + * for more details. + * + * Not to be confused with FIRDocumentReference. + */ +class DocumentKeyReference { + public: + DocumentKeyReference() { + } + + /** Initializes the document reference with the given key and Id. */ + DocumentKeyReference(model::DocumentKey key, int32_t ref_id) + : key_{std::move(key)}, ref_id_{ref_id} { + } + + /** The document key that's the target of this reference. */ + const model::DocumentKey& key() const { + return key_; + } + + /** + * The targetId of a referring target or the batchId of a referring mutation + * batch. (Which this is depends upon which FSTReferenceSet this reference is + * a part of.) + */ + int32_t ref_id() const { + return ref_id_; + } + + friend bool operator==(const DocumentKeyReference& lhs, + const DocumentKeyReference& rhs); + + size_t Hash() const; + + std::string ToString() const; + + /** Sorts document references by key then Id. */ + struct ByKey : public util::Comparator { + bool operator()(const DocumentKeyReference& lhs, + const DocumentKeyReference& rhs) const; + }; + + /** Sorts document references by Id then key. */ + struct ById : public util::Comparator { + bool operator()(const DocumentKeyReference& lhs, + const DocumentKeyReference& rhs) const; + }; + + private: + model::DocumentKey key_; + + // PORTING NOTE: this is `id` on other platforms but that's a reserved word in + // Objective-C++. + int32_t ref_id_ = 0; +}; + +} // namespace local +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_LOCAL_DOCUMENT_KEY_REFERENCE_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/index_manager.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/index_manager.h new file mode 100644 index 0000000..c4bad32 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/index_manager.h @@ -0,0 +1,65 @@ +/* + * Copyright 2019 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_LOCAL_INDEX_MANAGER_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_LOCAL_INDEX_MANAGER_H_ + +#include +#include + +#include "Firestore/core/src/firebase/firestore/model/resource_path.h" + +namespace firebase { +namespace firestore { +namespace local { + +/** + * Represents a set of indexes that are used to execute queries efficiently. + * + * Currently the only index is a [collection id] => [parent path] index, used + * to execute Collection Group queries. + */ +class IndexManager { + public: + virtual ~IndexManager() { + } + + /** + * Creates an index entry mapping the collectionId (last segment of the path) + * to the parent path (either the containing document location or the empty + * path for root-level collections). Index entries can be retrieved via + * GetCollectionParents(). + * + * NOTE: Currently we don't remove index entries. If this ends up being an + * issue we can devise some sort of GC strategy. + */ + virtual void AddToCollectionParentIndex( + const model::ResourcePath& collection_path) = 0; + + /** + * Retrieves all parent locations containing the given collectionId, as a set + * of paths (each path being either a document location or the empty path for + * a root-level collection). + */ + virtual std::vector GetCollectionParents( + const std::string& collection_id) = 0; +}; + +} // namespace local +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_LOCAL_INDEX_MANAGER_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/leveldb_index_manager.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/leveldb_index_manager.h new file mode 100644 index 0000000..3b44cbd --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/leveldb_index_manager.h @@ -0,0 +1,70 @@ +/* + * Copyright 2019 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_LOCAL_LEVELDB_INDEX_MANAGER_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_LOCAL_LEVELDB_INDEX_MANAGER_H_ + +#if !defined(__OBJC__) +#error "For now, this file must only be included by ObjC source files." +#endif // !defined(__OBJC__) + +#include +#include + +#include "Firestore/core/src/firebase/firestore/local/index_manager.h" +#include "Firestore/core/src/firebase/firestore/local/memory_index_manager.h" +#include "Firestore/core/src/firebase/firestore/model/resource_path.h" + +@class FSTLevelDB; + +NS_ASSUME_NONNULL_BEGIN + +namespace firebase { +namespace firestore { +namespace local { + +/** A persisted implementation of IndexManager. */ +class LevelDbIndexManager : public IndexManager { + public: + explicit LevelDbIndexManager(FSTLevelDB* db); + + void AddToCollectionParentIndex( + const model::ResourcePath& collection_path) override; + + std::vector GetCollectionParents( + const std::string& collection_id) override; + + private: + // This instance is owned by FSTLevelDB; avoid a retain cycle. + __weak FSTLevelDB* db_; + + /** + * An in-memory copy of the index entries we've already written since the SDK + * launched. Used to avoid re-writing the same entry repeatedly. + * + * This is *NOT* a complete cache of what's in persistence and so can never + * be used to satisfy reads. + */ + MemoryCollectionParentIndex collection_parents_cache_; +}; + +} // namespace local +} // namespace firestore +} // namespace firebase + +NS_ASSUME_NONNULL_END + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_LOCAL_LEVELDB_INDEX_MANAGER_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/leveldb_index_manager.mm b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/leveldb_index_manager.mm new file mode 100644 index 0000000..ef7773b --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/leveldb_index_manager.mm @@ -0,0 +1,81 @@ +/* + * Copyright 2019 Google + * + * 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 "Firestore/core/src/firebase/firestore/local/leveldb_index_manager.h" + +#include +#include + +#include "Firestore/core/src/firebase/firestore/local/leveldb_key.h" +#include "Firestore/core/src/firebase/firestore/local/memory_index_manager.h" +#include "Firestore/core/src/firebase/firestore/model/resource_path.h" +#include "Firestore/core/src/firebase/firestore/util/hard_assert.h" +#include "absl/strings/match.h" + +#import "Firestore/Source/Local/FSTLevelDB.h" + +NS_ASSUME_NONNULL_BEGIN + +namespace firebase { +namespace firestore { +namespace local { + +using model::ResourcePath; + +LevelDbIndexManager::LevelDbIndexManager(FSTLevelDB* db) : db_(db) { +} + +void LevelDbIndexManager::AddToCollectionParentIndex( + const ResourcePath& collection_path) { + HARD_ASSERT(collection_path.size() % 2 == 1, "Expected a collection path."); + + if (collection_parents_cache_.Add(collection_path)) { + std::string collection_id = collection_path.last_segment(); + ResourcePath parent_path = collection_path.PopLast(); + + std::string key = + LevelDbCollectionParentKey::Key(collection_id, parent_path); + std::string empty_buffer; + db_.currentTransaction->Put(key, empty_buffer); + } +} + +std::vector LevelDbIndexManager::GetCollectionParents( + const std::string& collection_id) { + std::vector results; + + auto index_iterator = db_.currentTransaction->NewIterator(); + std::string index_prefix = + LevelDbCollectionParentKey::KeyPrefix(collection_id); + LevelDbCollectionParentKey row_key; + for (index_iterator->Seek(index_prefix); index_iterator->Valid(); + index_iterator->Next()) { + if (!absl::StartsWith(index_iterator->key(), index_prefix) || + !row_key.Decode(index_iterator->key()) || + row_key.collection_id() != collection_id) { + break; + } + + results.push_back(row_key.parent()); + } + return results; +} + +} // namespace local +} // namespace firestore +} // namespace firebase + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/leveldb_key.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/leveldb_key.cc new file mode 100644 index 0000000..e0f6328 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/leveldb_key.cc @@ -0,0 +1,920 @@ +/* + * Copyright 2018 Google + * + * 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 "Firestore/core/src/firebase/firestore/local/leveldb_key.h" + +#include +#include + +#include "Firestore/core/src/firebase/firestore/local/leveldb_util.h" +#include "Firestore/core/src/firebase/firestore/util/ordered_code.h" +#include "absl/base/attributes.h" +#include "absl/strings/escaping.h" +#include "absl/strings/str_cat.h" + +using firebase::firestore::model::DocumentKey; +using firebase::firestore::model::ResourcePath; +using firebase::firestore::util::OrderedCode; + +namespace firebase { +namespace firestore { +namespace local { + +namespace { + +const char* kVersionGlobalTable = "version"; +const char* kMutationsTable = "mutation"; +const char* kDocumentMutationsTable = "document_mutation"; +const char* kMutationQueuesTable = "mutation_queue"; +const char* kTargetGlobalTable = "target_global"; +const char* kTargetsTable = "target"; +const char* kQueryTargetsTable = "query_target"; +const char* kTargetDocumentsTable = "target_document"; +const char* kDocumentTargetsTable = "document_target"; +const char* kRemoteDocumentsTable = "remote_document"; +const char* kCollectionParentsTable = "collection_parent"; + +/** + * Labels for the components of keys. These serve to make keys self-describing. + * + * These are intended to sort similarly to keys in the server storage format. + * + * Note that the server writes component labels using the equivalent to + * OrderedCode::WriteSignedNumDecreasing. This means that despite the higher + * numeric value, a terminator sorts before a path segment. In order to avoid + * needing the WriteSignedNumDecreasing code just for these values, this enum's + * values are in the reverse order to the server side. + * + * Most server-side values don't apply here. For example, the server embeds + * projects, databases, namespaces and similar values in its entity keys where + * the clients just open a different leveldb. Similarly, many of these values + * don't apply to the server since the server is backed by spanner which + * natively has concepts of tables and indexes. Where there's overlap, a comment + * denotes the server value from the storage_format_internal.proto. + */ +enum ComponentLabel { + /** + * A terminator is the final component of a key. All complete keys have a + * terminator and a key is known to be a key prefix if it doesn't have a + * terminator. + */ + Terminator = 0, // TERMINATOR_COMPONENT = 63, server-side + + /** + * A table name component names the logical table to which the key belongs. + */ + TableName = 5, + + /** A component containing the batch Id of a mutation. */ + BatchId = 10, + + /** A component containing the canonical Id of a query. */ + CanonicalId = 11, + + /** A component containing the target Id of a query. */ + TargetId = 12, + + /** A component containing a user Id. */ + UserId = 13, + + /** + * A component containing a standalone collection ID (e.g. as used by the + * collection_parent table, but not for collection IDs within paths). + */ + CollectionId = 14, + + /** + * A path segment describes just a single segment in a resource path. Path + * segments that occur sequentially in a key represent successive segments in + * a single path. + * + * This value must be greater than ComponentLabel::Terminator to ensure that + * longer paths sort after paths that are prefixes of them. + * + * This value must also be larger than other separators so that path suffixes + * sort after other key components. + */ + PathSegment = 62, // PATH = 60, server-side + + /** + * The maximum value that can be encoded by WriteSignedNumIncreasing in a + * single byte. + */ + Unknown = 63, +}; + +/** + * A helper for reading through the string form of a LevelDB key, as written + * by Writer. + */ +class Reader { + public: + explicit Reader(leveldb::Slice src) : src_(src), ok_(true) { + } + + explicit Reader(absl::string_view src) : Reader{MakeSlice(src)} { + } + + /** Returns true if the Reader has encountered no errors. */ + bool ok() const { + return ok_; + } + + /** Returns true if the Reader has no more bytes to read. */ + bool empty() const { + return !ok_ || src_.empty(); + } + + /** + * Parses the components of the key and returns a string description of them. + */ + std::string Describe(); + + void ReadTableNameMatching(const char* expected_table_name) { + if (!ReadLabeledStringMatching(ComponentLabel::TableName, + expected_table_name)) { + Fail(); + } + } + + model::BatchId ReadBatchId() { + return ReadLabeledInt32(ComponentLabel::BatchId); + } + + std::string ReadCanonicalId() { + return ReadLabeledString(ComponentLabel::CanonicalId); + } + + model::TargetId ReadTargetId() { + return ReadLabeledInt32(ComponentLabel::TargetId); + } + + std::string ReadUserId() { + return ReadLabeledString(ComponentLabel::UserId); + } + + std::string ReadCollectionId() { + return ReadLabeledString(ComponentLabel::CollectionId); + } + + /** + * Reads component labels and strings from the key until it finds a component + * label other than ComponentLabel::PathSegment (or the key is exhausted). + * All matched path segments are assembled into a ResourcePath. + */ + ResourcePath ReadResourcePath(); + + /** + * Reads component labels and strings from the key until it finds a component + * label other than ComponentLabel::PathSegment (or the key is exhausted). + * All matched path segments are assembled into a ResourcePath and wrapped in + * a DocumentKey. + * + * If the read is unsuccessful or the document key is invalid, returns a + * default DocumentKey and fails the Reader. + * + * Otherwise returns the decoded DocumentKey and the Reader advances to the + * next unread byte. + */ + DocumentKey ReadDocumentKey(); + + /** + * Reads a terminator component from the key. + * + * If the read is unsuccessful or the component wasn't a Terminator, fails + * the Reader. + * + * Otherwise the Reader advances to the next unread byte (which for valid + * keys should make the Reader empty). + */ + void ReadTerminator() { + if (!ReadComponentLabelMatching(ComponentLabel::Terminator)) { + Fail(); + } + } + + private: + /** OrderedCode::ReadSignedNumIncreasing adapted to leveldb::Slice. */ + int64_t ReadSignedNumIncreasing() { + if (ok_) { + int64_t result = 0; + absl::string_view tmp = MakeStringView(src_); + if (OrderedCode::ReadSignedNumIncreasing(&tmp, &result)) { + src_ = MakeSlice(tmp); + return result; + } + } + + Fail(); + return 0; + } + + /** OrderedCode::ReadString adapted to leveldb::Slice. */ + std::string ReadString() { + if (ok_) { + std::string result; + absl::string_view tmp = MakeStringView(src_); + if (OrderedCode::ReadString(&tmp, &result)) { + src_ = MakeSlice(tmp); + return result; + } + } + + Fail(); + return ""; + } + + /** + * Reads a component label from the key. + * + * If the read is unsuccessful, returns ComponentLabel::Unknown and fails the + * Reader. + * + * Otherwise, returns the ComponentLabel and advances the Reader to the next + * unread byte. + */ + ComponentLabel ReadComponentLabel() { + if (ok_) { + int64_t raw_result = ReadSignedNumIncreasing(); + if (ok_ && raw_result >= ComponentLabel::Terminator && + raw_result <= ComponentLabel::Unknown) { + return static_cast(raw_result); + } + } + + Fail(); + return ComponentLabel::Unknown; + } + + /** + * Reads a component label from the key. + * + * If the read is unsuccessful, returns false, and fails the Reader. + * + * Otherwise returns whether or not the component label is equal to the + * `expected_label` and advances the Reader to the next unread byte. + */ + ABSL_MUST_USE_RESULT + bool ReadComponentLabelMatching(ComponentLabel expected_label) { + if (ok_) { + int64_t raw_result = ReadSignedNumIncreasing(); + if (ok_) { + // Note: mismatch of a component label is not necessarily a failure. + // It's treated as a potential branch point within the parser. + return raw_result == expected_label; + } + } + + Fail(); + return false; + } + + /** + * Reads a signed number from the key and verifies that the value fits in a + * 32-bit integer. + * + * If the read is unsuccessful or the number was out of range, returns 0 and + * fails the Reader. + * + * Otherwise, returns the number and advances the Reader to the next unread + * byte. + */ + int32_t ReadInt32() { + if (ok_) { + int64_t raw_result = ReadSignedNumIncreasing(); + if (ok_ && raw_result >= INT32_MIN && raw_result <= INT32_MAX) { + return static_cast(raw_result); + } + } + + Fail(); + return 0; + } + + /** + * Reads a component label and signed number from the key and verifies that + * the label matches the expected_label and the value fits in a 32-bit + * integer. + * + * If the read is unsuccessful, the label didn't match, or the number was out + * of range, returns 0 and fails the Reader. + * + * Otherwise, returns the number and advances the Reader to the next unread + * byte. + */ + int32_t ReadLabeledInt32(ComponentLabel expected_label) { + if (!ReadComponentLabelMatching(expected_label)) { + Fail(); + } + return ReadInt32(); + } + + /** + * Reads a component label and a string from the key verifies that the label + * matches the expected_label. + * + * If the read is unsuccessful or the label didn't match, returns an empty + * string and fails the Reader. + * + * Otherwise, returns the string and advances the Reader to the next unread + * byte. + */ + std::string ReadLabeledString(ComponentLabel expected_label) { + if (!ReadComponentLabelMatching(expected_label)) { + Fail(); + } + return ReadString(); + } + + /** + * Reads a component label and a string from the key and verifies that the + * label matches the expected_label and the string matches the + * expected_value. + * + * If the read is unsuccessful or the label wasn't a string, returns false + * and fails the Reader. + * + * Otherwise returns whether or not the string that was read was equal to the + * expected value and advances the reader to the next unread byte. + */ + ABSL_MUST_USE_RESULT + bool ReadLabeledStringMatching(ComponentLabel expected_label, + const char* expected_value) { + std::string value = ReadLabeledString(expected_label); + if (ok_) { + // Value mismatch does not constitute a failure: + return value == expected_value; + } + + Fail(); + return false; + } + + /** + * Fails the Reader. All subsequent read operations will exit early if + * possible. Return values from any method will be defaults, as if those + * methods had failed themselves. + */ + void Fail() { + ok_ = false; + } + + leveldb::Slice src_; + bool ok_; +}; + +ResourcePath Reader::ReadResourcePath() { + std::vector path_segments; + while (!empty()) { + // Advance a temporary slice to avoid advancing contents into the next key + // component which may not be a path segment. + leveldb::Slice saved_position = src_; + if (!ReadComponentLabelMatching(ComponentLabel::PathSegment)) { + src_ = saved_position; + break; + } + + std::string segment = ReadString(); + if (!ok_) break; + + path_segments.push_back(std::move(segment)); + } + + return ResourcePath{std::move(path_segments)}; +} + +DocumentKey Reader::ReadDocumentKey() { + ResourcePath path = ReadResourcePath(); + + // Avoid assertion failures in DocumentKey if path is invalid. + if (ok_ && !path.empty() && DocumentKey::IsDocumentKey(path)) { + return DocumentKey{std::move(path)}; + } + + Fail(); + return DocumentKey{}; +} + +/** + * Returns a base64-encoded string for an invalid key, used for debug-friendly + * description text. + */ +std::string InvalidKey(leveldb::Slice key) { + std::string result; + absl::Base64Escape(MakeStringView(key), &result); + return result; +} + +std::string Reader::Describe() { + leveldb::Slice original = src_; + + bool is_terminated = false; + + std::string description; + absl::StrAppend(&description, "["); + + while (!empty()) { + leveldb::Slice saved_source = src_; + + ComponentLabel label = ReadComponentLabel(); + if (!ok_) { + break; + } + if (label == ComponentLabel::Terminator) { + is_terminated = true; + break; + } + + // Reset the reader since all the different read routines expect to see the + // separator first + src_ = saved_source; + + if (label == ComponentLabel::PathSegment) { + ResourcePath resource_path = ReadResourcePath(); + if (ok_) { + absl::StrAppend(&description, + " path=", resource_path.CanonicalString()); + } + + } else if (label == ComponentLabel::TableName) { + std::string table = ReadLabeledString(ComponentLabel::TableName); + if (ok_) { + absl::StrAppend(&description, table, ":"); + } + + } else if (label == ComponentLabel::BatchId) { + model::BatchId batch_id = ReadBatchId(); + if (ok_) { + absl::StrAppend(&description, " batch_id=", batch_id); + } + + } else if (label == ComponentLabel::CanonicalId) { + std::string canonical_id = ReadCanonicalId(); + if (ok_) { + absl::StrAppend(&description, " canonical_id=", canonical_id); + } + + } else if (label == ComponentLabel::TargetId) { + model::TargetId target_id = ReadTargetId(); + if (ok_) { + absl::StrAppend(&description, " target_id=", target_id); + } + + } else if (label == ComponentLabel::UserId) { + std::string user_id = ReadUserId(); + if (ok_) { + absl::StrAppend(&description, " user_id=", user_id); + } + + } else if (label == ComponentLabel::CollectionId) { + std::string collection_id = ReadCollectionId(); + if (ok_) { + absl::StrAppend(&description, " collection_id=", collection_id); + } + + } else { + absl::StrAppend(&description, " unknown label=", static_cast(label)); + Fail(); + } + } + + if (!ok_ || !empty()) { + absl::StrAppend(&description, " invalid key=<", InvalidKey(original), ">"); + + } else if (!is_terminated) { + absl::StrAppend(&description, " incomplete key"); + } + + absl::StrAppend(&description, "]"); + return description; +} + +class Writer { + public: + std::string result() const { + return dest_; + } + + void WriteTerminator() { + OrderedCode::WriteSignedNumIncreasing(&dest_, ComponentLabel::Terminator); + } + + void WriteTableName(const char* table_name) { + WriteLabeledString(ComponentLabel::TableName, table_name); + } + + void WriteBatchId(model::BatchId batch_id) { + WriteLabeledInt32(ComponentLabel::BatchId, batch_id); + } + + void WriteCanonicalId(absl::string_view canonical_id) { + WriteLabeledString(ComponentLabel::CanonicalId, canonical_id); + } + + void WriteTargetId(model::TargetId target_id) { + WriteLabeledInt32(ComponentLabel::TargetId, target_id); + } + + void WriteUserId(absl::string_view user_id) { + WriteLabeledString(ComponentLabel::UserId, user_id); + } + + void WriteCollectionId(absl::string_view collection_id) { + WriteLabeledString(ComponentLabel::CollectionId, collection_id); + } + + /** + * For each segment in the given resource path writes a + * ComponentLabel::PathSegment component label and a string containing the + * path segment. + */ + void WriteResourcePath(const ResourcePath& path) { + for (const auto& segment : path) { + WriteComponentLabel(ComponentLabel::PathSegment); + OrderedCode::WriteString(&dest_, segment); + } + } + + private: + /** Writes a component label to the given key destination. */ + void WriteComponentLabel(ComponentLabel label) { + OrderedCode::WriteSignedNumIncreasing(&dest_, label); + } + + /** + * Writes a component label and a signed integer to the given key destination. + */ + void WriteLabeledInt32(ComponentLabel label, int32_t value) { + WriteComponentLabel(label); + OrderedCode::WriteSignedNumIncreasing(&dest_, value); + } + + /** + * Writes a component label and an encoded string to the given key + * destination. + */ + void WriteLabeledString(ComponentLabel label, absl::string_view value) { + WriteComponentLabel(label); + OrderedCode::WriteString(&dest_, value); + } + + std::string dest_; +}; + +} // namespace + +std::string DescribeKey(leveldb::Slice key) { + Reader reader{key}; + return reader.Describe(); +} + +std::string DescribeKey(absl::string_view key) { + return DescribeKey(MakeSlice(key)); +} + +std::string DescribeKey(const std::string& key) { + return DescribeKey(leveldb::Slice{key}); +} + +std::string DescribeKey(const char* key) { + return DescribeKey(leveldb::Slice{key}); +} + +std::string LevelDbVersionKey::Key() { + Writer writer; + writer.WriteTableName(kVersionGlobalTable); + writer.WriteTerminator(); + return writer.result(); +} + +std::string LevelDbMutationKey::KeyPrefix() { + Writer writer; + writer.WriteTableName(kMutationsTable); + return writer.result(); +} + +std::string LevelDbMutationKey::KeyPrefix(absl::string_view user_id) { + Writer writer; + writer.WriteTableName(kMutationsTable); + writer.WriteUserId(user_id); + return writer.result(); +} + +std::string LevelDbMutationKey::Key(absl::string_view user_id, + model::BatchId batch_id) { + Writer writer; + writer.WriteTableName(kMutationsTable); + writer.WriteUserId(user_id); + writer.WriteBatchId(batch_id); + writer.WriteTerminator(); + return writer.result(); +} + +bool LevelDbMutationKey::Decode(absl::string_view key) { + Reader reader{key}; + reader.ReadTableNameMatching(kMutationsTable); + user_id_ = reader.ReadUserId(); + batch_id_ = reader.ReadBatchId(); + reader.ReadTerminator(); + return reader.ok(); +} + +std::string LevelDbDocumentMutationKey::KeyPrefix() { + Writer writer; + writer.WriteTableName(kDocumentMutationsTable); + return writer.result(); +} + +std::string LevelDbDocumentMutationKey::KeyPrefix(absl::string_view user_id) { + Writer writer; + writer.WriteTableName(kDocumentMutationsTable); + writer.WriteUserId(user_id); + return writer.result(); +} + +std::string LevelDbDocumentMutationKey::KeyPrefix( + absl::string_view user_id, const ResourcePath& resource_path) { + Writer writer; + writer.WriteTableName(kDocumentMutationsTable); + writer.WriteUserId(user_id); + writer.WriteResourcePath(resource_path); + return writer.result(); +} + +std::string LevelDbDocumentMutationKey::Key(absl::string_view user_id, + const DocumentKey& document_key, + model::BatchId batch_id) { + Writer writer; + writer.WriteTableName(kDocumentMutationsTable); + writer.WriteUserId(user_id); + writer.WriteResourcePath(document_key.path()); + writer.WriteBatchId(batch_id); + writer.WriteTerminator(); + return writer.result(); +} + +bool LevelDbDocumentMutationKey::Decode(absl::string_view key) { + Reader reader{key}; + reader.ReadTableNameMatching(kDocumentMutationsTable); + user_id_ = reader.ReadUserId(); + document_key_ = reader.ReadDocumentKey(); + batch_id_ = reader.ReadBatchId(); + reader.ReadTerminator(); + return reader.ok(); +} + +std::string LevelDbMutationQueueKey::KeyPrefix() { + Writer writer; + writer.WriteTableName(kMutationQueuesTable); + return writer.result(); +} + +std::string LevelDbMutationQueueKey::Key(absl::string_view user_id) { + Writer writer; + writer.WriteTableName(kMutationQueuesTable); + writer.WriteUserId(user_id); + writer.WriteTerminator(); + return writer.result(); +} + +bool LevelDbMutationQueueKey::Decode(absl::string_view key) { + Reader reader{key}; + reader.ReadTableNameMatching(kMutationQueuesTable); + user_id_ = reader.ReadUserId(); + reader.ReadTerminator(); + return reader.ok(); +} + +std::string LevelDbTargetGlobalKey::Key() { + Writer writer; + writer.WriteTableName(kTargetGlobalTable); + writer.WriteTerminator(); + return writer.result(); +} + +bool LevelDbTargetGlobalKey::Decode(leveldb::Slice key) { + Reader reader{key}; + reader.ReadTableNameMatching(kTargetGlobalTable); + reader.ReadTerminator(); + return reader.ok(); +} + +std::string LevelDbTargetKey::KeyPrefix() { + Writer writer; + writer.WriteTableName(kTargetsTable); + return writer.result(); +} + +std::string LevelDbTargetKey::Key(model::TargetId target_id) { + Writer writer; + writer.WriteTableName(kTargetsTable); + writer.WriteTargetId(target_id); + writer.WriteTerminator(); + return writer.result(); +} + +bool LevelDbTargetKey::Decode(leveldb::Slice key) { + Reader reader{key}; + reader.ReadTableNameMatching(kTargetsTable); + target_id_ = reader.ReadTargetId(); + reader.ReadTerminator(); + return reader.ok(); +} + +std::string LevelDbQueryTargetKey::KeyPrefix() { + Writer writer; + writer.WriteTableName(kQueryTargetsTable); + return writer.result(); +} + +std::string LevelDbQueryTargetKey::KeyPrefix(absl::string_view canonical_id) { + Writer writer; + writer.WriteTableName(kQueryTargetsTable); + writer.WriteCanonicalId(canonical_id); + return writer.result(); +} + +std::string LevelDbQueryTargetKey::Key(absl::string_view canonical_id, + model::TargetId target_id) { + Writer writer; + writer.WriteTableName(kQueryTargetsTable); + writer.WriteCanonicalId(canonical_id); + writer.WriteTargetId(target_id); + writer.WriteTerminator(); + return writer.result(); +} + +bool LevelDbQueryTargetKey::Decode(absl::string_view key) { + Reader reader{key}; + reader.ReadTableNameMatching(kQueryTargetsTable); + canonical_id_ = reader.ReadCanonicalId(); + target_id_ = reader.ReadTargetId(); + reader.ReadTerminator(); + return reader.ok(); +} + +std::string LevelDbTargetDocumentKey::KeyPrefix() { + Writer writer; + writer.WriteTableName(kTargetDocumentsTable); + return writer.result(); +} + +std::string LevelDbTargetDocumentKey::KeyPrefix(model::TargetId target_id) { + Writer writer; + writer.WriteTableName(kTargetDocumentsTable); + writer.WriteTargetId(target_id); + return writer.result(); +} + +std::string LevelDbTargetDocumentKey::Key(model::TargetId target_id, + const DocumentKey& document_key) { + Writer writer; + writer.WriteTableName(kTargetDocumentsTable); + writer.WriteTargetId(target_id); + writer.WriteResourcePath(document_key.path()); + writer.WriteTerminator(); + return writer.result(); +} + +bool LevelDbTargetDocumentKey::Decode(absl::string_view key) { + Reader reader{key}; + reader.ReadTableNameMatching(kTargetDocumentsTable); + target_id_ = reader.ReadTargetId(); + document_key_ = reader.ReadDocumentKey(); + reader.ReadTerminator(); + return reader.ok(); +} + +std::string LevelDbDocumentTargetKey::KeyPrefix() { + Writer writer; + writer.WriteTableName(kDocumentTargetsTable); + return writer.result(); +} + +std::string LevelDbDocumentTargetKey::KeyPrefix( + const ResourcePath& resource_path) { + Writer writer; + writer.WriteTableName(kDocumentTargetsTable); + writer.WriteResourcePath(resource_path); + return writer.result(); +} + +std::string LevelDbDocumentTargetKey::Key(const DocumentKey& document_key, + model::TargetId target_id) { + Writer writer; + writer.WriteTableName(kDocumentTargetsTable); + writer.WriteResourcePath(document_key.path()); + writer.WriteTargetId(target_id); + writer.WriteTerminator(); + return writer.result(); +} + +std::string LevelDbDocumentTargetKey::SentinelKey( + const DocumentKey& document_key) { + return Key(document_key, kInvalidTargetId); +} + +std::string LevelDbDocumentTargetKey::EncodeSentinelValue( + model::ListenSequenceNumber sequence_number) { + std::string encoded; + OrderedCode::WriteSignedNumIncreasing(&encoded, sequence_number); + return encoded; +} + +model::ListenSequenceNumber LevelDbDocumentTargetKey::DecodeSentinelValue( + absl::string_view slice) { + model::ListenSequenceNumber decoded; + if (!OrderedCode::ReadSignedNumIncreasing(&slice, &decoded)) { + HARD_FAIL("Failed to read sequence number from a sentinel row"); + } + return decoded; +} + +bool LevelDbDocumentTargetKey::Decode(absl::string_view key) { + Reader reader{key}; + reader.ReadTableNameMatching(kDocumentTargetsTable); + document_key_ = reader.ReadDocumentKey(); + target_id_ = reader.ReadTargetId(); + reader.ReadTerminator(); + return reader.ok(); +} + +std::string LevelDbRemoteDocumentKey::KeyPrefix() { + Writer writer; + writer.WriteTableName(kRemoteDocumentsTable); + return writer.result(); +} + +std::string LevelDbRemoteDocumentKey::KeyPrefix( + const ResourcePath& resource_path) { + Writer writer; + writer.WriteTableName(kRemoteDocumentsTable); + writer.WriteResourcePath(resource_path); + return writer.result(); +} + +std::string LevelDbRemoteDocumentKey::Key(const DocumentKey& key) { + Writer writer; + writer.WriteTableName(kRemoteDocumentsTable); + writer.WriteResourcePath(key.path()); + writer.WriteTerminator(); + return writer.result(); +} + +bool LevelDbRemoteDocumentKey::Decode(absl::string_view key) { + Reader reader{key}; + reader.ReadTableNameMatching(kRemoteDocumentsTable); + document_key_ = reader.ReadDocumentKey(); + reader.ReadTerminator(); + return reader.ok(); +} + +std::string LevelDbCollectionParentKey::KeyPrefix() { + Writer writer; + writer.WriteTableName(kCollectionParentsTable); + return writer.result(); +} + +std::string LevelDbCollectionParentKey::KeyPrefix( + absl::string_view collection_id) { + Writer writer; + writer.WriteTableName(kCollectionParentsTable); + writer.WriteCollectionId(collection_id); + return writer.result(); +} + +std::string LevelDbCollectionParentKey::Key(absl::string_view collection_id, + const ResourcePath& parent) { + Writer writer; + writer.WriteTableName(kCollectionParentsTable); + writer.WriteCollectionId(collection_id); + writer.WriteResourcePath(parent); + writer.WriteTerminator(); + return writer.result(); +} + +bool LevelDbCollectionParentKey::Decode(absl::string_view key) { + Reader reader{key}; + reader.ReadTableNameMatching(kCollectionParentsTable); + collection_id_ = reader.ReadCollectionId(); + parent_ = reader.ReadResourcePath(); + reader.ReadTerminator(); + return reader.ok(); +} + +} // namespace local +} // namespace firestore +} // namespace firebase diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/leveldb_key.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/leveldb_key.h new file mode 100644 index 0000000..505cb87 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/leveldb_key.h @@ -0,0 +1,585 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_LOCAL_LEVELDB_KEY_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_LOCAL_LEVELDB_KEY_H_ + +#include + +#include "Firestore/core/src/firebase/firestore/model/document_key.h" +#include "Firestore/core/src/firebase/firestore/model/resource_path.h" +#include "Firestore/core/src/firebase/firestore/model/types.h" +#include "absl/strings/string_view.h" +#include "leveldb/slice.h" + +namespace firebase { +namespace firestore { +namespace local { + +// Utilities for encoding and decoding LevelDB row keys and key prefixes. +// +// LevelDB keys are strings, so all the routines in here operate on strings to +// be able to produce and consume leveldb APIs directly. +// +// All leveldb logical tables should have their keys structures described in +// this file. +// +// mutations: +// - table_name: string = "mutation" +// - user_id: string +// - batch_id: model::BatchId +// +// document_mutations: +// - table_name: string = "document_mutation" +// - user_id: string +// - path: ResourcePath +// - batch_id: model::BatchId +// +// mutation_queues: +// - table_name: string = "mutation_queue" +// - user_id: string +// +// targets: +// - table_name: string = "target" +// - target_id: model::TargetId +// +// target_globals: +// - table_name: string = "target_global" +// +// query_targets: +// - table_name: string = "query_target" +// - canonical_id: string +// - target_id: model::TargetId +// +// target_documents: +// - table_name: string = "target_document" +// - target_id: model::TargetId +// - path: ResourcePath +// +// document_targets: +// - table_name: string = "document_target" +// - path: ResourcePath +// - target_id: model::TargetId +// +// remote_documents: +// - table_name: string = "remote_document" +// - path: ResourcePath +// +// collection_parents: +// - table_name: string = "collection_parent" +// - collectionId: string +// - parent: ResourcePath + +/** + * Parses the given key and returns a human readable description of its + * contents, suitable for error messages and logging. + */ +std::string DescribeKey(leveldb::Slice key); +std::string DescribeKey(absl::string_view key); +std::string DescribeKey(const std::string& key); +std::string DescribeKey(const char* key); + +/** A key to a singleton row storing the version of the schema. */ +class LevelDbVersionKey { + public: + /** + * Returns the key pointing to the singleton row storing the schema version. + */ + static std::string Key(); +}; + +/** A key in the mutations table. */ +class LevelDbMutationKey { + public: + /** + * Creates a key prefix that points just before the first key in the table. + */ + static std::string KeyPrefix(); + + /** + * Creates a key prefix that points just before the first key for the given + * user_id. + */ + static std::string KeyPrefix(absl::string_view user_id); + + /** Creates a complete key that points to a specific user_id and batch_id. */ + static std::string Key(absl::string_view user_id, model::BatchId batch_id); + + /** + * Decodes the given complete key, storing the decoded values in this + * instance. + * + * @return true if the key successfully decoded, false otherwise. If false is + * returned, this instance is in an undefined state until the next call to + * `Decode()`. + */ + ABSL_MUST_USE_RESULT + bool Decode(absl::string_view key); + + /** The user that owns the mutation batches. */ + const std::string& user_id() const { + return user_id_; + } + + /** The batch_id of the batch. */ + model::BatchId batch_id() const { + return batch_id_; + } + + private: + // Deliberately uninitialized: will be assigned in Decode + std::string user_id_; + model::BatchId batch_id_; +}; + +/** + * A key in the document mutations index, which stores the batches in which + * documents are mutated. + */ +class LevelDbDocumentMutationKey { + public: + /** + * Creates a key prefix that points just before the first key in the table. + */ + static std::string KeyPrefix(); + + /** + * Creates a key prefix that points just before the first key for the given + * user_id. + */ + static std::string KeyPrefix(absl::string_view user_id); + + /** + * Creates a key prefix that points just before the first key for the user_id + * and resource path. + * + * Note that this uses a ResourcePath rather than an DocumentKey in order to + * allow prefix scans over a collection. However a naive scan over those + * results isn't useful since it would match both immediate children of the + * collection and any subcollections. + */ + static std::string KeyPrefix(absl::string_view user_id, + const model::ResourcePath& resource_path); + + /** + * Creates a complete key that points to a specific user_id, document key, + * and batch_id. + */ + static std::string Key(absl::string_view user_id, + const model::DocumentKey& document_key, + model::BatchId batch_id); + + /** + * Decodes the given complete key, storing the decoded values in this + * instance. + * + * @return true if the key successfully decoded, false otherwise. If false is + * returned, this instance is in an undefined state until the next call to + * `Decode()`. + */ + ABSL_MUST_USE_RESULT + bool Decode(absl::string_view key); + + /** The user that owns the mutation batches. */ + const std::string& user_id() const { + return user_id_; + } + + /** The path to the document, as encoded in the key. */ + const model::DocumentKey& document_key() const { + return document_key_; + } + + /** The batch_id in which the document participates. */ + model::BatchId batch_id() const { + return batch_id_; + } + + private: + // Deliberately uninitialized: will be assigned in Decode + std::string user_id_; + model::DocumentKey document_key_; + model::BatchId batch_id_; +}; + +/** + * A key in the mutation_queues table. + * + * Note that where `mutation_queues` table contains one row about each queue, + * the `mutations` table contains the actual mutation batches themselves. + */ +class LevelDbMutationQueueKey { + public: + /** + * Creates a key prefix that points just before the first key in the table. + */ + static std::string KeyPrefix(); + + /** + * Creates a complete key that points to a specific mutation queue entry for + * the given user_id. + */ + static std::string Key(absl::string_view user_id); + + /** + * Decodes the given complete key, storing the decoded values in this + * instance. + * + * @return true if the key successfully decoded, false otherwise. If false is + * returned, this instance is in an undefined state until the next call to + * `Decode()`. + */ + ABSL_MUST_USE_RESULT + bool Decode(absl::string_view key); + + const std::string& user_id() const { + return user_id_; + } + + private: + // Deliberately uninitialized: will be assigned in Decode + std::string user_id_; +}; + +/** + * A key in the target globals table, a record of global values across all + * targets. + */ +class LevelDbTargetGlobalKey { + public: + /** Creates a key that points to the single target global row. */ + static std::string Key(); + + /** + * Decodes the contents of a target global key, essentially just verifying + * that the key has the correct table name. + */ + ABSL_MUST_USE_RESULT + bool Decode(leveldb::Slice key); +}; + +/** A key in the targets table. */ +class LevelDbTargetKey { + public: + /** + * Creates a key prefix that points just before the first key in the table. + */ + static std::string KeyPrefix(); + + /** Creates a complete key that points to a specific target, by target_id. */ + static std::string Key(model::TargetId target_id); + + /** + * Decodes the contents of a target key, storing the decoded values in this + * instance. + * + * @return true if the key successfully decoded, false otherwise. If false is + * returned, this instance is in an undefined state until the next call to + * `Decode()`. + */ + ABSL_MUST_USE_RESULT + bool Decode(leveldb::Slice key); + + model::TargetId target_id() { + return target_id_; + } + + private: + model::TargetId target_id_ = 0; +}; + +/** + * A key in the query targets table, an index of canonical_ids to the targets + * they may match. This is not a unique mapping because canonical_id does not + * promise a unique name for all possible queries. + */ +class LevelDbQueryTargetKey { + public: + /** + * Creates a key that contains just the query targets table prefix and points + * just before the first key. + */ + static std::string KeyPrefix(); + + /** + * Creates a key that points to the first query-target association for a + * canonical_id. + */ + static std::string KeyPrefix(absl::string_view canonical_id); + + /** Creates a key that points to a specific query-target entry. */ + static std::string Key(absl::string_view canonical_id, + model::TargetId target_id); + + /** + * Decodes the contents of a query target key, storing the decoded values in + * this instance. + * + * @return true if the key successfully decoded, false otherwise. If false is + * returned, this instance is in an undefined state until the next call to + * `Decode()`. + */ + ABSL_MUST_USE_RESULT + bool Decode(absl::string_view key); + + /** The canonical_id derived from the query. */ + const std::string& canonical_id() const { + return canonical_id_; + } + + /** The target_id identifying a target. */ + model::TargetId target_id() const { + return target_id_; + } + + private: + // Deliberately uninitialized: will be assigned in Decode + std::string canonical_id_; + model::TargetId target_id_; +}; + +/** + * A key in the target documents table, an index of target_ids to the documents + * they contain. + */ +class LevelDbTargetDocumentKey { + public: + /** + * Creates a key that contains just the target documents table prefix and + * points just before the first key. + */ + static std::string KeyPrefix(); + + /** + * Creates a key that points to the first target-document association for a + * target_id. + */ + static std::string KeyPrefix(model::TargetId target_id); + + /** Creates a key that points to a specific target-document entry. */ + static std::string Key(model::TargetId target_id, + const model::DocumentKey& document_key); + + /** + * Decodes the contents of a target document key, storing the decoded values + * in this instance. + * + * @return true if the key successfully decoded, false otherwise. If false is + * returned, this instance is in an undefined state until the next call to + * `Decode()`. + */ + ABSL_MUST_USE_RESULT + bool Decode(absl::string_view key); + + /** The target_id identifying a target. */ + model::TargetId target_id() { + return target_id_; + } + + /** The path to the document, as encoded in the key. */ + const model::DocumentKey& document_key() { + return document_key_; + } + + private: + // Deliberately uninitialized: will be assigned in Decode + model::TargetId target_id_; + model::DocumentKey document_key_; +}; + +/** + * A key in the document targets table, an index from documents to the targets + * that contain them. + */ +class LevelDbDocumentTargetKey { + public: + /** + * Creates a key that contains just the document targets table prefix and + * points just before the first key. + */ + static std::string KeyPrefix(); + + /** + * Creates a key that points to the first document-target association for + * document. + */ + static std::string KeyPrefix(const model::ResourcePath& resource_path); + + /** Creates a key that points to a specific document-target entry. */ + static std::string Key(const model::DocumentKey& document_key, + model::TargetId target_id); + + /** + * Creates a key that points to the sentinel row for the given document: a + * document-target entry with a special, invalid target_id. + */ + static std::string SentinelKey(const model::DocumentKey& document_key); + + /** + * Given a sequence number, encodes it for storage in a sentinel row. + */ + static std::string EncodeSentinelValue( + model::ListenSequenceNumber sequence_number); + + /** + * Given an encoded sentinel row, return the sequence number. + */ + static model::ListenSequenceNumber DecodeSentinelValue( + absl::string_view slice); + + /** + * Decodes the contents of a document target key, storing the decoded values + * in this instance. + * + * @return true if the key successfully decoded, false otherwise. If false is + * returned, this instance is in an undefined state until the next call to + * `Decode()`. + */ + ABSL_MUST_USE_RESULT + bool Decode(absl::string_view key); + + /** The target_id identifying a target. */ + model::TargetId target_id() const { + return target_id_; + } + + /** + * Returns true if the target_id in this row is a sentintel target ID. + */ + bool IsSentinel() { + return target_id_ == kInvalidTargetId; + } + + /** The path to the document, as encoded in the key. */ + const model::DocumentKey& document_key() const { + return document_key_; + } + + private: + // Used for sentinel row for a document in the document target index. No + // target has the ID 0, and it will sort first in the list of targets for a + // document. + static constexpr model::TargetId kInvalidTargetId = 0; + + // Deliberately uninitialized: will be assigned in Decode + model::TargetId target_id_; + model::DocumentKey document_key_; +}; + +/** A key in the remote documents table. */ +class LevelDbRemoteDocumentKey { + public: + /** + * Creates a key that contains just the remote documents table prefix and + * points just before the first remote document key. + */ + static std::string KeyPrefix(); + + /** + * Creates a complete key that points to a specific document. The document_key + * must have an even number of path segments. + */ + static std::string Key(const model::DocumentKey& document_key); + + /** + * Creates a key prefix that contains a part of a document path. Odd numbers + * of segments create a collection key prefix, while an even number of + * segments create a document key prefix. Note that a document key prefix will + * match the document itself and any documents that exist in its + * subcollections. + */ + static std::string KeyPrefix(const model::ResourcePath& resource_path); + + /** + * Decodes the contents of a remote document key, storing the decoded values + * in this instance. This can only decode complete document paths (i.e. the + * result of Key()). + * + * @return true if the key successfully decoded, false otherwise. If false is + * returned, this instance is in an undefined state until the next call to + * `Decode()`. + */ + ABSL_MUST_USE_RESULT + bool Decode(absl::string_view key); + + /** The path to the document, as encoded in the key. */ + const model::DocumentKey& document_key() const { + return document_key_; + } + + private: + // Deliberately uninitialized: will be assigned in Decode + model::DocumentKey document_key_; +}; + +/** + * A key in the collection parents index, which stores an association between a + * Collection ID (e.g. 'messages') to a parent path (e.g. '/chats/123') that + * contains it as a (sub)collection. This is used to efficiently find all + * collections to query when performing a Collection Group query. Note that the + * parent path will be an empty path in the case of root-level collections. + */ +class LevelDbCollectionParentKey { + public: + /** + * Creates a key prefix that points just before the first key in the table. + */ + static std::string KeyPrefix(); + + /** + * Creates a key prefix that points just before the first key for the given + * collection_id. + */ + static std::string KeyPrefix(absl::string_view collection_id); + + /** + * Creates a complete key that points to a specific collection_id and parent. + */ + static std::string Key(absl::string_view collection_id, + const model::ResourcePath& parent); + + /** + * Decodes the given complete key, storing the decoded values in this + * instance. + * + * @return true if the key successfully decoded, false otherwise. If false is + * returned, this instance is in an undefined state until the next call to + * `Decode()`. + */ + ABSL_MUST_USE_RESULT + bool Decode(absl::string_view key); + + /** The collection_id, as encoded in the key. */ + const std::string& collection_id() const { + return collection_id_; + } + + /** The parent path, as encoded in the key. */ + const model::ResourcePath& parent() const { + return parent_; + } + + private: + // Deliberately uninitialized: will be assigned in Decode + std::string collection_id_; + model::ResourcePath parent_; +}; + +} // namespace local +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_LOCAL_LEVELDB_KEY_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/leveldb_migrations.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/leveldb_migrations.cc new file mode 100644 index 0000000..dda29e7 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/leveldb_migrations.cc @@ -0,0 +1,363 @@ +/* + * Copyright 2018 Google + * + * 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 "Firestore/core/src/firebase/firestore/local/leveldb_migrations.h" + +#include +#include + +#include "Firestore/Protos/nanopb/firestore/local/mutation.nanopb.h" +#include "Firestore/Protos/nanopb/firestore/local/target.nanopb.h" +#include "Firestore/core/src/firebase/firestore/local/leveldb_key.h" +#include "Firestore/core/src/firebase/firestore/local/memory_index_manager.h" +#include "Firestore/core/src/firebase/firestore/model/document_key.h" +#include "Firestore/core/src/firebase/firestore/model/types.h" +#include "Firestore/core/src/firebase/firestore/nanopb/reader.h" +#include "Firestore/core/src/firebase/firestore/nanopb/writer.h" +#include "absl/strings/match.h" + +namespace firebase { +namespace firestore { +namespace local { + +using leveldb::Iterator; +using leveldb::Slice; +using leveldb::Status; +using leveldb::WriteOptions; +using model::DocumentKey; +using model::ResourcePath; +using nanopb::Reader; +using nanopb::Writer; + +namespace { + +/** + * Schema version for the iOS client. + * + * Note that tables aren't a concept in LevelDB. They exist in our schema as + * just prefixes on keys. This means tables don't need to be created but they + * also can't easily be dropped and re-created. + * + * Migrations: + * * Migration 1 used to ensure the target_global row existed, without + * clearing it. No longer required because migration 3 unconditionally + * clears it. + * * Migration 2 used to ensure that the target_global row had a correct count + * of targets. No longer required because migration 3 deletes them all. + * * Migration 3 deletes the entire query cache to deal with cache corruption + * related to limbo resolution. Addresses + * https://github.com/firebase/firebase-ios-sdk/issues/1548. + * * Migration 4 ensures that every document in the remote document cache + * has a sentinel row with a sequence number. + * * Migration 5 drops held write acks. + * * Migration 6 populates the collection_parents index. + */ +const LevelDbMigrations::SchemaVersion kSchemaVersion = 6; + +/** + * Save the given version number as the current version of the schema of the + * database. + * @param version The version to save + * @param transaction The transaction in which to save the new version number + */ +void SaveVersion(LevelDbMigrations::SchemaVersion version, + LevelDbTransaction* transaction) { + std::string key = LevelDbVersionKey::Key(); + std::string version_string = std::to_string(version); + transaction->Put(key, version_string); +} + +void DeleteEverythingWithPrefix(const std::string& prefix, leveldb::DB* db) { + bool more_deletes = true; + while (more_deletes) { + LevelDbTransaction transaction(db, "Delete everything with prefix"); + auto it = transaction.NewIterator(); + + more_deletes = false; + for (it->Seek(prefix); it->Valid() && absl::StartsWith(it->key(), prefix); + it->Next()) { + if (transaction.changed_keys() >= 1000) { + more_deletes = true; + break; + } + transaction.Delete(it->key()); + } + + transaction.Commit(); + } +} + +/** Migration 3. */ +void ClearQueryCache(leveldb::DB* db) { + DeleteEverythingWithPrefix(LevelDbTargetKey::KeyPrefix(), db); + DeleteEverythingWithPrefix(LevelDbDocumentTargetKey::KeyPrefix(), db); + DeleteEverythingWithPrefix(LevelDbTargetDocumentKey::KeyPrefix(), db); + DeleteEverythingWithPrefix(LevelDbQueryTargetKey::KeyPrefix(), db); + + LevelDbTransaction transaction(db, "Drop query cache"); + + // Reset the target global entry too (to reset the target count). + firestore_client_TargetGlobal target_global{}; + + std::string bytes; + Writer writer = Writer::Wrap(&bytes); + writer.WriteNanopbMessage(firestore_client_TargetGlobal_fields, + &target_global); + transaction.Put(LevelDbTargetGlobalKey::Key(), std::move(bytes)); + + SaveVersion(3, &transaction); + transaction.Commit(); +} + +/** + * Removes document associations for the given user's mutation queue for + * any mutation with a `batch_id` less than or equal to + * `last_acknowledged_batch_id`. + */ +void RemoveMutationDocuments(LevelDbTransaction* transaction, + absl::string_view user_id, + int32_t last_acknowledged_batch_id) { + LevelDbDocumentMutationKey doc_key; + std::string prefix = LevelDbDocumentMutationKey::KeyPrefix(user_id); + + auto it = transaction->NewIterator(); + it->Seek(prefix); + for (; it->Valid() && absl::StartsWith(it->key(), prefix); it->Next()) { + HARD_ASSERT(doc_key.Decode(it->key()), + "Failed to decode document mutation key"); + if (doc_key.batch_id() <= last_acknowledged_batch_id) { + transaction->Delete(it->key()); + } + } +} + +/** + * Removes mutation batches for the given user with a `batch_id` less than + * or equal to `last_acknowledged_batch_id` + */ +void RemoveMutationBatches(LevelDbTransaction* transaction, + absl::string_view user_id, + int32_t last_acknowledged_batch_id) { + std::string mutations_key = LevelDbMutationKey::KeyPrefix(user_id); + std::string last_key = + LevelDbMutationKey::Key(user_id, last_acknowledged_batch_id); + auto it = transaction->NewIterator(); + it->Seek(mutations_key); + for (; it->Valid() && it->key() <= last_key; it->Next()) { + transaction->Delete(it->key()); + } +} + +/** Migration 5. */ +void RemoveAcknowledgedMutations(leveldb::DB* db) { + LevelDbTransaction transaction(db, "remove acknowledged mutations"); + std::string mutation_queue_start = LevelDbMutationQueueKey::KeyPrefix(); + + LevelDbMutationQueueKey key; + + auto it = transaction.NewIterator(); + it->Seek(mutation_queue_start); + for (; it->Valid() && absl::StartsWith(it->key(), mutation_queue_start); + it->Next()) { + HARD_ASSERT(key.Decode(it->key()), "Failed to decode mutation queue key"); + firestore_client_MutationQueue mutation_queue{}; + Reader reader = Reader::Wrap(it->value()); + reader.ReadNanopbMessage(firestore_client_MutationQueue_fields, + &mutation_queue); + HARD_ASSERT(reader.status().ok(), "Failed to deserialize MutationQueue"); + RemoveMutationBatches(&transaction, key.user_id(), + mutation_queue.last_acknowledged_batch_id); + RemoveMutationDocuments(&transaction, key.user_id(), + mutation_queue.last_acknowledged_batch_id); + } + + SaveVersion(5, &transaction); + transaction.Commit(); +} + +/** + * Reads the highest sequence number from the target global row. + */ +model::ListenSequenceNumber GetHighestSequenceNumber( + LevelDbTransaction* transaction) { + std::string bytes; + transaction->Get(LevelDbTargetGlobalKey::Key(), &bytes); + + firestore_client_TargetGlobal target_global{}; + Reader reader = Reader::Wrap(bytes); + reader.ReadNanopbMessage(firestore_client_TargetGlobal_fields, + &target_global); + return target_global.highest_listen_sequence_number; +} + +/** + * Given a document key, ensure it has a sentinel row. If it doesn't have one, + * add it with the given value. + */ +void EnsureSentinelRow(LevelDbTransaction* transaction, + const model::DocumentKey& key, + const std::string& sentinel_value) { + std::string sentinel_key = LevelDbDocumentTargetKey::SentinelKey(key); + std::string unused_value; + if (transaction->Get(sentinel_key, &unused_value).IsNotFound()) { + transaction->Put(sentinel_key, sentinel_value); + } +} + +/** + * Migration 4. + * + * Ensure each document in the remote document table has a corresponding + * sentinel row in the document target index. + */ +void EnsureSentinelRows(leveldb::DB* db) { + LevelDbTransaction transaction(db, "Ensure sentinel rows"); + + // Get the value we'll use for anything that's missing a row. + model::ListenSequenceNumber sequence_number = + GetHighestSequenceNumber(&transaction); + std::string sentinel_value = + LevelDbDocumentTargetKey::EncodeSentinelValue(sequence_number); + + std::string documents_prefix = LevelDbRemoteDocumentKey::KeyPrefix(); + auto it = transaction.NewIterator(); + it->Seek(documents_prefix); + LevelDbRemoteDocumentKey document_key; + for (; it->Valid() && absl::StartsWith(it->key(), documents_prefix); + it->Next()) { + HARD_ASSERT(document_key.Decode(it->key()), + "Failed to decode document key"); + EnsureSentinelRow(&transaction, document_key.document_key(), + sentinel_value); + } + SaveVersion(4, &transaction); + transaction.Commit(); +} + +// Helper to add an index entry iff we haven't already written it (as determined +// by the provided cache). +void EnsureCollectionParentRow(LevelDbTransaction* transaction, + MemoryCollectionParentIndex* cache, + const DocumentKey& key) { + const ResourcePath& collection_path = key.path().PopLast(); + if (cache->Add(collection_path)) { + std::string collection_id = collection_path.last_segment(); + ResourcePath parent_path = collection_path.PopLast(); + + std::string key = + LevelDbCollectionParentKey::Key(collection_id, parent_path); + std::string empty_buffer; + transaction->Put(key, empty_buffer); + } +} + +/** + * Migration 6. + * + * Creates appropriate LevelDbCollectionParentKey rows for all collections + * of documents in the remote document cache and mutation queue. + */ +void EnsureCollectionParentsIndex(leveldb::DB* db) { + LevelDbTransaction transaction(db, "Ensure Collection Parents Index"); + + MemoryCollectionParentIndex cache; + + // Index existing remote documents. + std::string documents_prefix = LevelDbRemoteDocumentKey::KeyPrefix(); + auto it = transaction.NewIterator(); + it->Seek(documents_prefix); + LevelDbRemoteDocumentKey document_key; + for (; it->Valid() && absl::StartsWith(it->key(), documents_prefix); + it->Next()) { + HARD_ASSERT(document_key.Decode(it->key()), + "Failed to decode document key"); + + EnsureCollectionParentRow(&transaction, &cache, + document_key.document_key()); + } + + // Index existing mutations. + std::string mutations_prefix = LevelDbDocumentMutationKey::KeyPrefix(); + it = transaction.NewIterator(); + it->Seek(mutations_prefix); + LevelDbDocumentMutationKey key; + for (; it->Valid() && absl::StartsWith(it->key(), mutations_prefix); + it->Next()) { + HARD_ASSERT(key.Decode(it->key()), + "Failed to decode document-mutation key"); + + EnsureCollectionParentRow(&transaction, &cache, key.document_key()); + } + + SaveVersion(6, &transaction); + transaction.Commit(); +} + +} // namespace + +LevelDbMigrations::SchemaVersion LevelDbMigrations::ReadSchemaVersion( + leveldb::DB* db) { + LevelDbTransaction transaction(db, "Read schema version"); + std::string key = LevelDbVersionKey::Key(); + std::string version_string; + Status status = transaction.Get(key, &version_string); + if (status.IsNotFound()) { + return 0; + } else { + return stoi(version_string); + } +} + +void LevelDbMigrations::RunMigrations(leveldb::DB* db) { + RunMigrations(db, kSchemaVersion); +} + +void LevelDbMigrations::RunMigrations(leveldb::DB* db, + SchemaVersion to_version) { + SchemaVersion from_version = ReadSchemaVersion(db); + // If this is a downgrade, just save the downgrade version so we can + // detect it when we go to upgrade again, allowing us to rerun the + // data migrations. + if (from_version > to_version) { + LevelDbTransaction transaction(db, "Save downgrade version"); + SaveVersion(to_version, &transaction); + transaction.Commit(); + return; + } + + // This must run unconditionally because schema migrations were added to iOS + // after the first release. There may be clients that have never run any + // migrations that have existing targets. + if (from_version < 3 && to_version >= 3) { + ClearQueryCache(db); + } + + if (from_version < 4 && to_version >= 4) { + EnsureSentinelRows(db); + } + + if (from_version < 5 && to_version >= 5) { + RemoveAcknowledgedMutations(db); + } + + if (from_version < 6 && to_version >= 6) { + EnsureCollectionParentsIndex(db); + } +} + +} // namespace local +} // namespace firestore +} // namespace firebase diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/leveldb_migrations.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/leveldb_migrations.h new file mode 100644 index 0000000..d073ce3 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/leveldb_migrations.h @@ -0,0 +1,56 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_LOCAL_LEVELDB_MIGRATIONS_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_LOCAL_LEVELDB_MIGRATIONS_H_ + +#include + +#include "Firestore/core/src/firebase/firestore/local/leveldb_transaction.h" +#include "Firestore/core/src/firebase/firestore/local/local_serializer.h" +#include "leveldb/db.h" + +namespace firebase { +namespace firestore { +namespace local { + +class LevelDbMigrations { + public: + using SchemaVersion = int32_t; + + /** + * Returns the current version of the schema for the given database + */ + static SchemaVersion ReadSchemaVersion(leveldb::DB* db); + + /** + * Runs any migrations needed to bring the given database up to the current + * schema version + */ + static void RunMigrations(leveldb::DB* db); + + /** + * Runs any migrations needed to bring the given database up to the given + * schema version + */ + static void RunMigrations(leveldb::DB* db, SchemaVersion version); +}; + +} // namespace local +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_LOCAL_LEVELDB_MIGRATIONS_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/leveldb_mutation_queue.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/leveldb_mutation_queue.h new file mode 100644 index 0000000..676cc3f --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/leveldb_mutation_queue.h @@ -0,0 +1,156 @@ +/* + * Copyright 2019 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_LOCAL_LEVELDB_MUTATION_QUEUE_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_LOCAL_LEVELDB_MUTATION_QUEUE_H_ + +#if !defined(__OBJC__) +#error "For now, this file must only be included by ObjC source files." +#endif // !defined(__OBJC__) + +#import + +#include +#include +#include + +#import "Firestore/Source/Public/FIRTimestamp.h" + +#include "Firestore/core/src/firebase/firestore/auth/user.h" +#include "Firestore/core/src/firebase/firestore/local/leveldb_key.h" +#include "Firestore/core/src/firebase/firestore/local/mutation_queue.h" +#include "Firestore/core/src/firebase/firestore/model/document_key.h" +#include "Firestore/core/src/firebase/firestore/model/document_key_set.h" +#include "Firestore/core/src/firebase/firestore/model/types.h" +#include "absl/strings/string_view.h" +#include "leveldb/db.h" + +@class FSTLevelDB; +@class FSTLocalSerializer; +@class FSTMutation; +@class FSTMutationBatch; +@class FSTPBMutationQueue; +@class FSTQuery; + +NS_ASSUME_NONNULL_BEGIN + +namespace firebase { +namespace firestore { +namespace local { + +/** + * Returns one larger than the largest batch ID that has been stored. If there + * are no mutations returns 0. Note that batch IDs are global. + */ +model::BatchId LoadNextBatchIdFromDb(leveldb::DB* db); + +class LevelDbMutationQueue : public MutationQueue { + public: + LevelDbMutationQueue(const auth::User& user, + FSTLevelDB* db, + FSTLocalSerializer* serializer); + + void Start() override; + + bool IsEmpty() override; + + void AcknowledgeBatch(FSTMutationBatch* batch, + NSData* _Nullable stream_token) override; + + FSTMutationBatch* AddMutationBatch( + FIRTimestamp* local_write_time, + std::vector&& base_mutations, + std::vector&& mutations) override; + + void RemoveMutationBatch(FSTMutationBatch* batch) override; + + std::vector AllMutationBatches() override; + + std::vector AllMutationBatchesAffectingDocumentKeys( + const model::DocumentKeySet& document_keys) override; + + std::vector AllMutationBatchesAffectingDocumentKey( + const model::DocumentKey& key) override; + + std::vector AllMutationBatchesAffectingQuery( + FSTQuery* query) override; + + FSTMutationBatch* _Nullable LookupMutationBatch( + model::BatchId batch_id) override; + + FSTMutationBatch* _Nullable NextMutationBatchAfterBatchId( + model::BatchId batch_id) override; + + void PerformConsistencyCheck() override; + + NSData* _Nullable GetLastStreamToken() override; + + void SetLastStreamToken(NSData* _Nullable stream_token) override; + + private: + /** + * Constructs a vector of matching batches, sorted by batchID to ensure that + * multiple mutations affecting the same document key are applied in order. + */ + std::vector AllMutationBatchesWithIds( + const std::set& batch_ids); + + std::string mutation_queue_key() { + return LevelDbMutationQueueKey::Key(user_id_); + } + + std::string mutation_batch_key(model::BatchId batch_id) { + return LevelDbMutationKey::Key(user_id_, batch_id); + } + + /** Parses the MutationQueue metadata from the given LevelDB row contents. */ + FSTPBMutationQueue* _Nullable MetadataForKey(const std::string& key); + + FSTMutationBatch* ParseMutationBatch(absl::string_view encoded); + + // This instance is owned by FSTLevelDB; avoid a retain cycle. + __weak FSTLevelDB* db_; + + FSTLocalSerializer* serializer_; + + /** + * The normalized userID (e.g. nil UID => @"" userID) used in our LevelDB + * keys. + */ + std::string user_id_; + + /** + * Next value to use when assigning sequential IDs to each mutation batch. + * + * NOTE: There can only be one LevelDbMutationQueue for a given db at a time, + * hence it is safe to track next_batch_id_ as an instance-level property. + * Should we ever relax this constraint we'll need to revisit this. + */ + model::BatchId next_batch_id_; + + /** + * A write-through cache copy of the metadata describing the current queue. + */ + FSTPBMutationQueue* _Nullable metadata_; +}; + +} // namespace local +} // namespace firestore +} // namespace firebase + +NS_ASSUME_NONNULL_END + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_LOCAL_LEVELDB_MUTATION_QUEUE_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/leveldb_mutation_queue.mm b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/leveldb_mutation_queue.mm new file mode 100644 index 0000000..0abb5f1 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/leveldb_mutation_queue.mm @@ -0,0 +1,481 @@ +/* + * Copyright 2019 Google + * + * 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 "Firestore/core/src/firebase/firestore/local/leveldb_mutation_queue.h" + +#include +#include + +#import "Firestore/Protos/objc/firestore/local/Mutation.pbobjc.h" +#import "Firestore/Source/Core/FSTQuery.h" +#import "Firestore/Source/Local/FSTLevelDB.h" +#import "Firestore/Source/Local/FSTLocalSerializer.h" +#import "Firestore/Source/Model/FSTMutation.h" +#import "Firestore/Source/Model/FSTMutationBatch.h" + +#include "Firestore/core/src/firebase/firestore/local/leveldb_util.h" +#include "Firestore/core/src/firebase/firestore/model/mutation_batch.h" +#include "Firestore/core/src/firebase/firestore/model/resource_path.h" +#include "Firestore/core/src/firebase/firestore/util/string_util.h" +#include "Firestore/core/src/firebase/firestore/util/to_string.h" +#include "absl/strings/match.h" + +NS_ASSUME_NONNULL_BEGIN + +namespace firebase { +namespace firestore { +namespace local { + +using auth::User; +using leveldb::DB; +using leveldb::Iterator; +using leveldb::Status; +using model::BatchId; +using model::DocumentKey; +using model::DocumentKeySet; +using model::kBatchIdUnknown; +using model::ResourcePath; + +BatchId LoadNextBatchIdFromDb(DB* db) { + // TODO(gsoltis): implement Prev() and SeekToLast() on + // LevelDbTransaction::Iterator, then port this to a transaction. + std::unique_ptr it( + db->NewIterator(LevelDbTransaction::DefaultReadOptions())); + + std::string table_key = LevelDbMutationKey::KeyPrefix(); + + LevelDbMutationKey row_key; + BatchId max_batch_id = kBatchIdUnknown; + + bool more_user_ids = false; + std::string next_user_id; + + it->Seek(table_key); + if (it->Valid() && row_key.Decode(MakeStringView(it->key()))) { + more_user_ids = true; + next_user_id = row_key.user_id(); + } + + // This loop assumes that nextUserId contains the next username at the start + // of the iteration. + while (more_user_ids) { + // Compute the first key after the last mutation for next_user_id. + std::string user_end = LevelDbMutationKey::KeyPrefix(next_user_id); + user_end = util::PrefixSuccessor(user_end); + + // Seek to that key with the intent of finding the boundary between + // next_user_id's mutations and the one after that (if any). + it->Seek(user_end); + + // At this point there are three possible cases to handle differently. Each + // case must prepare the next iteration (by assigning to next_user_id or + // setting more_user_ids = NO) and seek the iterator to the last row in the + // current user's mutation sequence. + if (!it->Valid()) { + // The iterator is past the last row altogether (there are no additional + // userIDs and now rows in any table after mutations). The last row will + // have the highest batchID. + more_user_ids = false; + it->SeekToLast(); + + } else if (row_key.Decode(MakeStringView(it->key()))) { + // The iterator is valid and the key decoded successfully so the next user + // was just decoded. + next_user_id = row_key.user_id(); + it->Prev(); + + } else { + // The iterator is past the end of the mutations table but there are other + // rows. + more_user_ids = false; + it->Prev(); + } + + // In all the cases above there was at least one row for the current user + // and each case has set things up such that iterator points to it. + if (!row_key.Decode(MakeStringView(it->key()))) { + HARD_FAIL("There should have been a key previous to %s", user_end); + } + + if (row_key.batch_id() > max_batch_id) { + max_batch_id = row_key.batch_id(); + } + } + + return max_batch_id + 1; +} + +LevelDbMutationQueue::LevelDbMutationQueue(const User& user, + FSTLevelDB* db, + FSTLocalSerializer* serializer) + : db_(db), + serializer_(serializer), + user_id_(user.is_authenticated() ? user.uid() : "") { +} + +void LevelDbMutationQueue::Start() { + next_batch_id_ = LoadNextBatchIdFromDb(db_.ptr); + + std::string key = mutation_queue_key(); + FSTPBMutationQueue* metadata = MetadataForKey(key); + if (!metadata) { + metadata = [FSTPBMutationQueue message]; + } + metadata_ = metadata; +} + +bool LevelDbMutationQueue::IsEmpty() { + std::string user_key = LevelDbMutationKey::KeyPrefix(user_id_); + + auto it = db_.currentTransaction->NewIterator(); + it->Seek(user_key); + + bool empty = true; + if (it->Valid() && absl::StartsWith(it->key(), user_key)) { + empty = false; + } + return empty; +} + +void LevelDbMutationQueue::AcknowledgeBatch(FSTMutationBatch* batch, + NSData* _Nullable stream_token) { + SetLastStreamToken(stream_token); +} + +FSTMutationBatch* LevelDbMutationQueue::AddMutationBatch( + FIRTimestamp* local_write_time, + std::vector&& base_mutations, + std::vector&& mutations) { + BatchId batch_id = next_batch_id_; + next_batch_id_++; + + FSTMutationBatch* batch = + [[FSTMutationBatch alloc] initWithBatchID:batch_id + localWriteTime:local_write_time + baseMutations:std::move(base_mutations) + mutations:std::move(mutations)]; + std::string key = mutation_batch_key(batch_id); + db_.currentTransaction->Put(key, [serializer_ encodedMutationBatch:batch]); + + // Store an empty value in the index which is equivalent to serializing a + // GPBEmpty message. In the future if we wanted to store some other kind of + // value here, we can parse these empty values as with some other protocol + // buffer (and the parser will see all default values). + std::string empty_buffer; + + for (FSTMutation* mutation : [batch mutations]) { + key = LevelDbDocumentMutationKey::Key(user_id_, mutation.key, batch_id); + db_.currentTransaction->Put(key, empty_buffer); + + db_.indexManager->AddToCollectionParentIndex(mutation.key.path().PopLast()); + } + + return batch; +} + +void LevelDbMutationQueue::RemoveMutationBatch(FSTMutationBatch* batch) { + auto check_iterator = db_.currentTransaction->NewIterator(); + + BatchId batch_id = batch.batchID; + std::string key = mutation_batch_key(batch_id); + + // As a sanity check, verify that the mutation batch exists before deleting + // it. + check_iterator->Seek(key); + HARD_ASSERT(check_iterator->Valid(), "Mutation batch %s did not exist", + DescribeKey(key)); + + HARD_ASSERT(key == check_iterator->key(), + "Mutation batch %s not found; found %s", DescribeKey(key), + DescribeKey(check_iterator->key())); + + db_.currentTransaction->Delete(key); + + for (FSTMutation* mutation : [batch mutations]) { + key = LevelDbDocumentMutationKey::Key(user_id_, mutation.key, batch_id); + db_.currentTransaction->Delete(key); + [db_.referenceDelegate removeMutationReference:mutation.key]; + } +} + +std::vector LevelDbMutationQueue::AllMutationBatches() { + std::string user_key = LevelDbMutationKey::KeyPrefix(user_id_); + + auto it = db_.currentTransaction->NewIterator(); + it->Seek(user_key); + std::vector result; + for (; it->Valid() && absl::StartsWith(it->key(), user_key); it->Next()) { + result.push_back(ParseMutationBatch(it->value())); + } + return result; +} + +std::vector +LevelDbMutationQueue::AllMutationBatchesAffectingDocumentKeys( + const DocumentKeySet& document_keys) { + // Take a pass through the document keys and collect the set of unique + // mutation batch_ids that affect them all. Some batches can affect more than + // one key. + std::set batch_ids; + + auto index_iterator = db_.currentTransaction->NewIterator(); + LevelDbDocumentMutationKey row_key; + for (const DocumentKey& document_key : document_keys) { + std::string index_prefix = + LevelDbDocumentMutationKey::KeyPrefix(user_id_, document_key.path()); + for (index_iterator->Seek(index_prefix); index_iterator->Valid(); + index_iterator->Next()) { + // Only consider rows matching exactly the specific key of interest. Index + // rows have this form (with markers in brackets): + // + // user collection doc 2 + // user collection doc 3 + // user collection doc sub doc 3 + // + // + // Note that Path markers sort after BatchId markers so this means that + // when searching for collection/doc, all the entries for it will be + // contiguous in the table, allowing a break after any mismatch. + if (!absl::StartsWith(index_iterator->key(), index_prefix) || + !row_key.Decode(index_iterator->key()) || + row_key.document_key() != document_key) { + break; + } + + batch_ids.insert(row_key.batch_id()); + } + } + + return AllMutationBatchesWithIds(batch_ids); +} + +std::vector +LevelDbMutationQueue::AllMutationBatchesAffectingDocumentKey( + const DocumentKey& key) { + return AllMutationBatchesAffectingDocumentKeys(DocumentKeySet{key}); +} + +std::vector +LevelDbMutationQueue::AllMutationBatchesAffectingQuery(FSTQuery* query) { + HARD_ASSERT(![query isDocumentQuery], + "Document queries shouldn't go down this path"); + HARD_ASSERT( + ![query isCollectionGroupQuery], + "CollectionGroup queries should be handled in LocalDocumentsView"); + + const ResourcePath& query_path = query.path; + size_t immediate_children_path_length = query_path.size() + 1; + + // TODO(mcg): Actually implement a single-collection query + // + // This is actually executing an ancestor query, traversing the whole subtree + // below the collection which can be horrifically inefficient for some + // structures. The right way to solve this is to implement the full value + // index, but that's not in the cards in the near future so this is the best + // we can do for the moment. + // + // Since we don't yet index the actual properties in the mutations, our + // current approach is to just return all mutation batches that affect + // documents in the collection being queried. + // + // Unlike allMutationBatchesAffectingDocumentKey, this iteration will scan the + // document-mutation index for more than a single document so the associated + // batchIDs will be neither necessarily unique nor in order. This means an + // efficient simultaneous scan isn't possible. + std::string index_prefix = + LevelDbDocumentMutationKey::KeyPrefix(user_id_, query_path); + auto index_iterator = db_.currentTransaction->NewIterator(); + index_iterator->Seek(index_prefix); + + LevelDbDocumentMutationKey row_key; + + // Collect up unique batchIDs encountered during a scan of the index. Use a + // set to accumulate batch IDs so they can be traversed in order in a + // scan of the main table. + // + // This method is faster than performing lookups of the keys with _db->Get and + // keeping a hash of batchIDs that have already been looked up. The + // performance difference is minor for small numbers of keys but > 30% faster + // for larger numbers of keys. + std::set unique_batch_ids; + for (; index_iterator->Valid(); index_iterator->Next()) { + if (!absl::StartsWith(index_iterator->key(), index_prefix) || + !row_key.Decode(index_iterator->key())) { + break; + } + + // Rows with document keys more than one segment longer than the query path + // can't be matches. For example, a query on 'rooms' can't match the + // document /rooms/abc/messages/xyx. + // TODO(mcg): we'll need a different scanner when we implement ancestor + // queries. + if (row_key.document_key().path().size() != + immediate_children_path_length) { + continue; + } + + unique_batch_ids.insert(row_key.batch_id()); + } + + return AllMutationBatchesWithIds(unique_batch_ids); +} + +FSTMutationBatch* _Nullable LevelDbMutationQueue::LookupMutationBatch( + model::BatchId batch_id) { + std::string key = mutation_batch_key(batch_id); + + std::string value; + Status status = db_.currentTransaction->Get(key, &value); + if (!status.ok()) { + if (status.IsNotFound()) { + return nil; + } + HARD_FAIL("Lookup mutation batch (%s, %s) failed with status: %s", user_id_, + batch_id, status.ToString()); + } + + return ParseMutationBatch(value); +} + +FSTMutationBatch* _Nullable LevelDbMutationQueue::NextMutationBatchAfterBatchId( + model::BatchId batch_id) { + BatchId next_batch_id = batch_id + 1; + + std::string key = mutation_batch_key(next_batch_id); + auto it = db_.currentTransaction->NewIterator(); + it->Seek(key); + + LevelDbMutationKey row_key; + if (!it->Valid() || !row_key.Decode(it->key())) { + // Past the last row in the DB or out of the mutations table + return nil; + } + + if (row_key.user_id() != user_id_) { + // Jumped past the last mutation for this user + return nil; + } + + HARD_ASSERT(row_key.batch_id() >= next_batch_id, + "Should have found mutation after %s", next_batch_id); + return ParseMutationBatch(it->value()); +} + +void LevelDbMutationQueue::PerformConsistencyCheck() { + if (!IsEmpty()) { + return; + } + + // Verify that there are no entries in the document-mutation index if the + // queue is empty. + std::string index_prefix = LevelDbDocumentMutationKey::KeyPrefix(user_id_); + auto index_iterator = db_.currentTransaction->NewIterator(); + index_iterator->Seek(index_prefix); + + std::vector dangling_mutation_references; + + for (; index_iterator->Valid(); index_iterator->Next()) { + // Only consider rows matching this index prefix for the current user. + if (!absl::StartsWith(index_iterator->key(), index_prefix)) { + break; + } + + dangling_mutation_references.push_back(DescribeKey(index_iterator)); + } + + HARD_ASSERT( + dangling_mutation_references.empty(), + "Document leak -- detected dangling mutation references when queue " + "is empty. Dangling keys: %s", + util::ToString(dangling_mutation_references)); +} + +NSData* _Nullable LevelDbMutationQueue::GetLastStreamToken() { + return metadata_.lastStreamToken; +} + +void LevelDbMutationQueue::SetLastStreamToken(NSData* _Nullable stream_token) { + metadata_.lastStreamToken = stream_token; + + db_.currentTransaction->Put(mutation_queue_key(), metadata_); +} + +std::vector LevelDbMutationQueue::AllMutationBatchesWithIds( + const std::set& batch_ids) { + std::vector result; + + // Given an ordered set of unique batchIDs perform a skipping scan over the + // main table to find the mutation batches. + auto mutation_iterator = db_.currentTransaction->NewIterator(); + for (BatchId batch_id : batch_ids) { + std::string mutation_key = mutation_batch_key(batch_id); + mutation_iterator->Seek(mutation_key); + if (!mutation_iterator->Valid() || + mutation_iterator->key() != mutation_key) { + HARD_FAIL("Dangling document-mutation reference found: " + "Missing batch %s; seeking there found %s", + DescribeKey(mutation_key), DescribeKey(mutation_iterator)); + } + + result.push_back(ParseMutationBatch(mutation_iterator->value())); + } + return result; +} + +FSTPBMutationQueue* _Nullable LevelDbMutationQueue::MetadataForKey( + const std::string& key) { + std::string value; + Status status = db_.currentTransaction->Get(key, &value); + if (status.ok()) { + NSData* data = [[NSData alloc] initWithBytesNoCopy:(void*)value.data() + length:value.size() + freeWhenDone:NO]; + + NSError* error; + FSTPBMutationQueue* proto = [FSTPBMutationQueue parseFromData:data + error:&error]; + if (!proto) { + HARD_FAIL("FSTPBMutationQueue failed to parse: %s", error); + } + return proto; + } else if (status.IsNotFound()) { + return nil; + } else { + HARD_FAIL("MetadataForKey: failed loading key %s with status: %s", key, + status.ToString()); + } +} + +FSTMutationBatch* LevelDbMutationQueue::ParseMutationBatch( + absl::string_view encoded) { + NSData* data = [[NSData alloc] initWithBytesNoCopy:(void*)encoded.data() + length:encoded.size() + freeWhenDone:NO]; + + NSError* error; + FSTPBWriteBatch* proto = [FSTPBWriteBatch parseFromData:data error:&error]; + if (!proto) { + HARD_FAIL("FSTPBMutationBatch failed to parse: %s", error); + } + + return [serializer_ decodedMutationBatch:proto]; +} + +} // namespace local +} // namespace firestore +} // namespace firebase + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/leveldb_query_cache.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/leveldb_query_cache.h new file mode 100644 index 0000000..caf28c4 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/leveldb_query_cache.h @@ -0,0 +1,147 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_LOCAL_LEVELDB_QUERY_CACHE_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_LOCAL_LEVELDB_QUERY_CACHE_H_ + +#if !defined(__OBJC__) +#error "For now, this file must only be included by ObjC source files." +#endif // !defined(__OBJC__) + +#import + +#include + +#import "Firestore/Protos/objc/firestore/local/Target.pbobjc.h" +#include "Firestore/core/src/firebase/firestore/local/query_cache.h" +#include "Firestore/core/src/firebase/firestore/model/document_key.h" +#include "Firestore/core/src/firebase/firestore/model/document_key_set.h" +#include "Firestore/core/src/firebase/firestore/model/types.h" +#include "absl/strings/string_view.h" +#include "leveldb/db.h" + +@class FSTLevelDB; +@class FSTLocalSerializer; +@class FSTQuery; +@class FSTQueryData; + +NS_ASSUME_NONNULL_BEGIN + +namespace firebase { +namespace firestore { +namespace local { + +/** Cached Queries backed by LevelDB. */ +class LevelDbQueryCache : public QueryCache { + public: + /** + * Retrieves the global singleton metadata row from the given database, if it + * exists. + * TODO(gsoltis): remove this method once fully ported to transactions. + */ + static FSTPBTargetGlobal* ReadMetadata(leveldb::DB* db); + + /** + * Creates a new query cache in the given LevelDB. + * + * @param db The LevelDB in which to create the cache. + */ + LevelDbQueryCache(FSTLevelDB* db, FSTLocalSerializer* serializer); + + // Target-related methods + void AddTarget(FSTQueryData* query_data) override; + + void UpdateTarget(FSTQueryData* query_data) override; + + void RemoveTarget(FSTQueryData* query_data) override; + + FSTQueryData* _Nullable GetTarget(FSTQuery* query) override; + + void EnumerateTargets(const TargetCallback& callback) override; + + int RemoveTargets(model::ListenSequenceNumber upper_bound, + const std::unordered_map& + live_targets) override; + + // Key-related methods + + /** Adds the given document keys to cached query results of the given target + * ID. */ + void AddMatchingKeys(const model::DocumentKeySet& keys, + model::TargetId target_id) override; + + /** Removes the given document keys from the cached query results of the given + * target ID. */ + void RemoveMatchingKeys(const model::DocumentKeySet& keys, + model::TargetId target_id) override; + + /** Removes all the keys in the query results of the given target ID. */ + void RemoveAllKeysForTarget(model::TargetId target_id); + + model::DocumentKeySet GetMatchingKeys(model::TargetId target_id) override; + + /** + * Checks to see if there are any references to a document with the given key. + */ + bool Contains(const model::DocumentKey& key) override; + + // Other methods and accessors + size_t size() const override { + return metadata_.targetCount; + } + + model::TargetId highest_target_id() const override { + return metadata_.highestTargetId; + } + + model::ListenSequenceNumber highest_listen_sequence_number() const override { + return metadata_.highestListenSequenceNumber; + } + + const model::SnapshotVersion& GetLastRemoteSnapshotVersion() const override; + + void SetLastRemoteSnapshotVersion(model::SnapshotVersion version) override; + + // Non-interface methods + void Start(); + + void EnumerateOrphanedDocuments(const OrphanedDocumentCallback& callback); + + private: + void Save(FSTQueryData* query_data); + bool UpdateMetadata(FSTQueryData* query_data); + void SaveMetadata(); + /** + * Parses the given bytes as an FSTPBTarget protocol buffer and then converts + * to the equivalent query data. + */ + FSTQueryData* DecodeTarget(absl::string_view encoded); + + // This instance is owned by FSTLevelDB; avoid a retain cycle. + __weak FSTLevelDB* db_; + FSTLocalSerializer* serializer_; + /** A write-through cached copy of the metadata for the query cache. */ + FSTPBTargetGlobal* metadata_; + model::SnapshotVersion last_remote_snapshot_version_; +}; + +} // namespace local +} // namespace firestore +} // namespace firebase + +NS_ASSUME_NONNULL_END + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_LOCAL_LEVELDB_QUERY_CACHE_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/leveldb_query_cache.mm b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/leveldb_query_cache.mm new file mode 100644 index 0000000..4412c46 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/leveldb_query_cache.mm @@ -0,0 +1,384 @@ +/* + * Copyright 2018 Google + * + * 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 "Firestore/core/src/firebase/firestore/local/leveldb_query_cache.h" + +#include +#include + +#import "Firestore/Protos/objc/firestore/local/Target.pbobjc.h" +#import "Firestore/Source/Core/FSTQuery.h" +#import "Firestore/Source/Local/FSTLevelDB.h" +#import "Firestore/Source/Local/FSTLocalSerializer.h" +#import "Firestore/Source/Local/FSTQueryData.h" +#include "Firestore/core/src/firebase/firestore/local/leveldb_key.h" +#include "Firestore/core/src/firebase/firestore/model/document_key.h" +#include "Firestore/core/src/firebase/firestore/model/document_key_set.h" +#include "Firestore/core/src/firebase/firestore/util/string_apple.h" +#include "absl/strings/match.h" + +namespace firebase { +namespace firestore { +namespace local { + +using model::DocumentKey; +using model::DocumentKeySet; +using model::ListenSequenceNumber; +using model::SnapshotVersion; +using model::TargetId; +using util::MakeString; +using leveldb::Status; + +FSTPBTargetGlobal* LevelDbQueryCache::ReadMetadata(leveldb::DB* db) { + std::string key = LevelDbTargetGlobalKey::Key(); + std::string value; + Status status = db->Get([FSTLevelDB standardReadOptions], key, &value); + if (status.IsNotFound()) { + return nil; + } else if (!status.ok()) { + HARD_FAIL("metadataForKey: failed loading key %s with status: %s", key, + status.ToString()); + } + + NSData* data = [[NSData alloc] initWithBytesNoCopy:(void*)value.data() + length:value.size() + freeWhenDone:NO]; + + NSError* error; + FSTPBTargetGlobal* proto = [FSTPBTargetGlobal parseFromData:data + error:&error]; + if (!proto) { + HARD_FAIL("FSTPBTargetGlobal failed to parse: %s", error); + } + + return proto; +} + +LevelDbQueryCache::LevelDbQueryCache(FSTLevelDB* db, + FSTLocalSerializer* serializer) + : db_(db), serializer_(serializer) { +} + +// TODO(gsoltis): revisit having a Start method vs a static factory function +// that returns a started instance. +void LevelDbQueryCache::Start() { + // TODO(gsoltis): switch this usage of ptr to currentTransaction + metadata_ = ReadMetadata(db_.ptr); + HARD_ASSERT(metadata_ != nil, + "Found nil metadata, expected schema to be at version 0 which " + "ensures metadata existence"); + last_remote_snapshot_version_ = + [serializer_ decodedVersion:metadata_.lastRemoteSnapshotVersion]; +} + +void LevelDbQueryCache::AddTarget(FSTQueryData* query_data) { + Save(query_data); + + NSString* canonical_id = query_data.query.canonicalID; + std::string index_key = + LevelDbQueryTargetKey::Key(MakeString(canonical_id), query_data.targetID); + std::string empty_buffer; + db_.currentTransaction->Put(index_key, empty_buffer); + + metadata_.targetCount++; + UpdateMetadata(query_data); + SaveMetadata(); +} + +void LevelDbQueryCache::UpdateTarget(FSTQueryData* query_data) { + Save(query_data); + + if (UpdateMetadata(query_data)) { + SaveMetadata(); + } +} + +void LevelDbQueryCache::RemoveTarget(FSTQueryData* query_data) { + TargetId target_id = query_data.targetID; + + RemoveAllKeysForTarget(target_id); + + std::string key = LevelDbTargetKey::Key(target_id); + db_.currentTransaction->Delete(key); + + std::string index_key = LevelDbQueryTargetKey::Key( + MakeString(query_data.query.canonicalID), target_id); + db_.currentTransaction->Delete(index_key); + + metadata_.targetCount--; + SaveMetadata(); +} + +FSTQueryData* _Nullable LevelDbQueryCache::GetTarget(FSTQuery* query) { + // Scan the query-target index starting with a prefix starting with the given + // query's canonicalID. Note that this is a scan rather than a get because + // canonicalIDs are not required to be unique per target. + std::string canonical_id = MakeString(query.canonicalID); + auto index_iterator = db_.currentTransaction->NewIterator(); + std::string index_prefix = LevelDbQueryTargetKey::KeyPrefix(canonical_id); + index_iterator->Seek(index_prefix); + + // Simultaneously scan the targets table. This works because each + // (canonicalID, targetID) pair is unique and ordered, so when scanning a + // table prefixed by exactly one canonicalID, all the targetIDs will be unique + // and in order. + std::string target_prefix = LevelDbTargetKey::KeyPrefix(); + auto target_iterator = db_.currentTransaction->NewIterator(); + + LevelDbQueryTargetKey row_key; + for (; index_iterator->Valid(); index_iterator->Next()) { + // Only consider rows matching exactly the specific canonicalID of interest. + if (!absl::StartsWith(index_iterator->key(), index_prefix) || + !row_key.Decode(index_iterator->key()) || + canonical_id != row_key.canonical_id()) { + // End of this canonicalID's possible targets. + break; + } + + // Each row is a unique combination of canonicalID and targetID, so this + // foreign key reference can only occur once. + std::string target_key = LevelDbTargetKey::Key(row_key.target_id()); + target_iterator->Seek(target_key); + if (!target_iterator->Valid() || target_iterator->key() != target_key) { + HARD_FAIL("Dangling query-target reference found: " + "%s points to %s; seeking there found %s", + DescribeKey(index_iterator), DescribeKey(target_key), + DescribeKey(target_iterator)); + } + + // Finally after finding a potential match, check that the query is actually + // equal to the requested query. + FSTQueryData* target = DecodeTarget(target_iterator->value()); + if ([target.query isEqual:query]) { + return target; + } + } + + return nil; +} + +void LevelDbQueryCache::EnumerateTargets(const TargetCallback& callback) { + // Enumerate all targets, give their sequence numbers. + std::string target_prefix = LevelDbTargetKey::KeyPrefix(); + auto it = db_.currentTransaction->NewIterator(); + it->Seek(target_prefix); + for (; it->Valid() && absl::StartsWith(it->key(), target_prefix); + it->Next()) { + FSTQueryData* target = DecodeTarget(it->value()); + callback(target); + } +} + +int LevelDbQueryCache::RemoveTargets( + ListenSequenceNumber upper_bound, + const std::unordered_map& live_targets) { + int count = 0; + std::string target_prefix = LevelDbTargetKey::KeyPrefix(); + auto it = db_.currentTransaction->NewIterator(); + it->Seek(target_prefix); + for (; it->Valid() && absl::StartsWith(it->key(), target_prefix); + it->Next()) { + FSTQueryData* query_data = DecodeTarget(it->value()); + if (query_data.sequenceNumber <= upper_bound && + live_targets.find(query_data.targetID) == live_targets.end()) { + RemoveTarget(query_data); + count++; + } + } + return count; +} + +void LevelDbQueryCache::AddMatchingKeys(const DocumentKeySet& keys, + TargetId target_id) { + // Store an empty value in the index which is equivalent to serializing a + // GPBEmpty message. In the future if we wanted to store some other kind of + // value here, we can parse these empty values as with some other protocol + // buffer (and the parser will see all default values). + std::string empty_buffer; + + for (const DocumentKey& key : keys) { + db_.currentTransaction->Put(LevelDbTargetDocumentKey::Key(target_id, key), + empty_buffer); + db_.currentTransaction->Put(LevelDbDocumentTargetKey::Key(key, target_id), + empty_buffer); + [db_.referenceDelegate addReference:key]; + }; +} + +void LevelDbQueryCache::RemoveMatchingKeys(const DocumentKeySet& keys, + TargetId target_id) { + for (const DocumentKey& key : keys) { + db_.currentTransaction->Delete( + LevelDbTargetDocumentKey::Key(target_id, key)); + db_.currentTransaction->Delete( + LevelDbDocumentTargetKey::Key(key, target_id)); + [db_.referenceDelegate removeReference:key]; + } +} + +void LevelDbQueryCache::RemoveAllKeysForTarget(TargetId target_id) { + std::string index_prefix = LevelDbTargetDocumentKey::KeyPrefix(target_id); + auto index_iterator = db_.currentTransaction->NewIterator(); + index_iterator->Seek(index_prefix); + + LevelDbTargetDocumentKey row_key; + for (; index_iterator->Valid(); index_iterator->Next()) { + absl::string_view index_key = index_iterator->key(); + + // Only consider rows matching this specific targetID. + if (!row_key.Decode(index_key) || row_key.target_id() != target_id) { + break; + } + const DocumentKey& document_key = row_key.document_key(); + + // Delete both index rows + db_.currentTransaction->Delete(index_key); + db_.currentTransaction->Delete( + LevelDbDocumentTargetKey::Key(document_key, target_id)); + } +} + +DocumentKeySet LevelDbQueryCache::GetMatchingKeys(TargetId target_id) { + std::string index_prefix = LevelDbTargetDocumentKey::KeyPrefix(target_id); + auto index_iterator = db_.currentTransaction->NewIterator(); + index_iterator->Seek(index_prefix); + + DocumentKeySet result; + LevelDbTargetDocumentKey row_key; + for (; index_iterator->Valid(); index_iterator->Next()) { + // TODO(gsoltis): could we use a StartsWith instead? + // Only consider rows matching this specific target_id. + if (!row_key.Decode(index_iterator->key()) || + row_key.target_id() != target_id) { + break; + } + + result = result.insert(row_key.document_key()); + } + + return result; +} + +bool LevelDbQueryCache::Contains(const DocumentKey& key) { + // ignore sentinel rows when determining if a key belongs to a target. + // Sentinel row just says the document exists, not that it's a member of any + // particular target. + std::string index_prefix = LevelDbDocumentTargetKey::KeyPrefix(key.path()); + auto index_iterator = db_.currentTransaction->NewIterator(); + index_iterator->Seek(index_prefix); + + for (; index_iterator->Valid() && + absl::StartsWith(index_iterator->key(), index_prefix); + index_iterator->Next()) { + LevelDbDocumentTargetKey row_key; + if (row_key.Decode(index_iterator->key()) && !row_key.IsSentinel() && + row_key.document_key() == key) { + return true; + } + } + + return false; +} + +const SnapshotVersion& LevelDbQueryCache::GetLastRemoteSnapshotVersion() const { + return last_remote_snapshot_version_; +} + +void LevelDbQueryCache::SetLastRemoteSnapshotVersion(SnapshotVersion version) { + last_remote_snapshot_version_ = std::move(version); + metadata_.lastRemoteSnapshotVersion = + [serializer_ encodedVersion:last_remote_snapshot_version_]; + SaveMetadata(); +} + +void LevelDbQueryCache::EnumerateOrphanedDocuments( + const OrphanedDocumentCallback& callback) { + std::string document_target_prefix = LevelDbDocumentTargetKey::KeyPrefix(); + auto it = db_.currentTransaction->NewIterator(); + it->Seek(document_target_prefix); + ListenSequenceNumber next_to_report = 0; + DocumentKey key_to_report; + LevelDbDocumentTargetKey key; + + for (; it->Valid() && absl::StartsWith(it->key(), document_target_prefix); + it->Next()) { + HARD_ASSERT(key.Decode(it->key()), "Failed to decode DocumentTarget key"); + if (key.IsSentinel()) { + // if next_to_report is non-zero, report it, this is a new key so the last + // one must be not be a member of any targets. + if (next_to_report != 0) { + callback(key_to_report, next_to_report); + } + // set next_to_report to be this sequence number. It's the next one we + // might report, if we don't find any targets for this document. + next_to_report = + LevelDbDocumentTargetKey::DecodeSentinelValue(it->value()); + key_to_report = key.document_key(); + } else { + // set next_to_report to be 0, we know we don't need to report this one + // since we found a target for it. + next_to_report = 0; + } + } + // if next_to_report is non-zero, report it. We didn't find any targets for + // that document, and we weren't asked to stop. + if (next_to_report != 0) { + callback(key_to_report, next_to_report); + } +} + +void LevelDbQueryCache::Save(FSTQueryData* query_data) { + TargetId target_id = query_data.targetID; + std::string key = LevelDbTargetKey::Key(target_id); + db_.currentTransaction->Put(key, [serializer_ encodedQueryData:query_data]); +} + +bool LevelDbQueryCache::UpdateMetadata(FSTQueryData* query_data) { + bool updated = false; + if (query_data.targetID > metadata_.highestTargetId) { + metadata_.highestTargetId = query_data.targetID; + updated = true; + } + + if (query_data.sequenceNumber > metadata_.highestListenSequenceNumber) { + metadata_.highestListenSequenceNumber = query_data.sequenceNumber; + updated = true; + } + + return updated; +} + +void LevelDbQueryCache::SaveMetadata() { + db_.currentTransaction->Put(LevelDbTargetGlobalKey::Key(), metadata_); +} + +FSTQueryData* LevelDbQueryCache::DecodeTarget(absl::string_view encoded) { + NSData* data = [[NSData alloc] initWithBytesNoCopy:(void*)encoded.data() + length:encoded.size() + freeWhenDone:NO]; + + NSError* error; + FSTPBTarget* proto = [FSTPBTarget parseFromData:data error:&error]; + if (!proto) { + HARD_FAIL("FSTPBTarget failed to parse: %s", error); + } + + return [serializer_ decodedQueryData:proto]; +} + +} // namespace local +} // namespace firestore +} // namespace firebase diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/leveldb_remote_document_cache.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/leveldb_remote_document_cache.h new file mode 100644 index 0000000..99bf754 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/leveldb_remote_document_cache.h @@ -0,0 +1,71 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_LOCAL_LEVELDB_REMOTE_DOCUMENT_CACHE_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_LOCAL_LEVELDB_REMOTE_DOCUMENT_CACHE_H_ + +#if !defined(__OBJC__) +#error "For now, this file must only be included by ObjC source files." +#endif // !defined(__OBJC__) + +#include + +#include "Firestore/core/src/firebase/firestore/local/remote_document_cache.h" +#include "Firestore/core/src/firebase/firestore/model/document_key.h" +#include "Firestore/core/src/firebase/firestore/model/document_key_set.h" +#include "Firestore/core/src/firebase/firestore/model/document_map.h" +#include "Firestore/core/src/firebase/firestore/model/types.h" +#include "absl/strings/string_view.h" + +@class FSTLevelDB; +@class FSTLocalSerializer; +@class FSTMaybeDocument; +@class FSTQuery; + +NS_ASSUME_NONNULL_BEGIN + +namespace firebase { +namespace firestore { +namespace local { + +/** Cached Remote Documents backed by leveldb. */ +class LevelDbRemoteDocumentCache : public RemoteDocumentCache { + public: + LevelDbRemoteDocumentCache(FSTLevelDB* db, FSTLocalSerializer* serializer); + + void Add(FSTMaybeDocument* document) override; + void Remove(const model::DocumentKey& key) override; + + FSTMaybeDocument* _Nullable Get(const model::DocumentKey& key) override; + model::MaybeDocumentMap GetAll(const model::DocumentKeySet& keys) override; + model::DocumentMap GetMatching(FSTQuery* query) override; + + private: + FSTMaybeDocument* DecodeMaybeDocument(absl::string_view encoded, + const model::DocumentKey& key); + + // This instance is owned by FSTLevelDB; avoid a retain cycle. + __weak FSTLevelDB* db_; + FSTLocalSerializer* serializer_; +}; + +} // namespace local +} // namespace firestore +} // namespace firebase + +NS_ASSUME_NONNULL_END + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_LOCAL_LEVELDB_REMOTE_DOCUMENT_CACHE_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/leveldb_remote_document_cache.mm b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/leveldb_remote_document_cache.mm new file mode 100644 index 0000000..69002e0 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/leveldb_remote_document_cache.mm @@ -0,0 +1,158 @@ +/* + * Copyright 2018 Google + * + * 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 "Firestore/core/src/firebase/firestore/local/leveldb_remote_document_cache.h" + +#import + +#include + +#import "Firestore/Protos/objc/firestore/local/MaybeDocument.pbobjc.h" +#import "Firestore/Source/Core/FSTQuery.h" +#import "Firestore/Source/Local/FSTLevelDB.h" +#import "Firestore/Source/Local/FSTLocalSerializer.h" +#include "Firestore/core/src/firebase/firestore/local/leveldb_key.h" +#include "Firestore/core/src/firebase/firestore/util/status.h" +#include "leveldb/db.h" + +using firebase::firestore::model::DocumentKey; +using firebase::firestore::model::DocumentKeySet; +using firebase::firestore::model::DocumentMap; +using firebase::firestore::model::MaybeDocumentMap; +using leveldb::Status; + +namespace firebase { +namespace firestore { +namespace local { + +LevelDbRemoteDocumentCache::LevelDbRemoteDocumentCache( + FSTLevelDB* db, FSTLocalSerializer* serializer) + : db_(db), serializer_(serializer) { +} + +void LevelDbRemoteDocumentCache::Add(FSTMaybeDocument* document) { + std::string ldb_key = LevelDbRemoteDocumentKey::Key(document.key); + db_.currentTransaction->Put(ldb_key, + [serializer_ encodedMaybeDocument:document]); + + db_.indexManager->AddToCollectionParentIndex(document.key.path().PopLast()); +} + +void LevelDbRemoteDocumentCache::Remove(const DocumentKey& key) { + std::string ldb_key = LevelDbRemoteDocumentKey::Key(key); + db_.currentTransaction->Delete(ldb_key); +} + +FSTMaybeDocument* _Nullable LevelDbRemoteDocumentCache::Get( + const DocumentKey& key) { + std::string ldb_key = LevelDbRemoteDocumentKey::Key(key); + std::string value; + Status status = db_.currentTransaction->Get(ldb_key, &value); + if (status.IsNotFound()) { + return nil; + } else if (status.ok()) { + return DecodeMaybeDocument(value, key); + } else { + HARD_FAIL("Fetch document for key (%s) failed with status: %s", + key.ToString(), status.ToString()); + } +} + +MaybeDocumentMap LevelDbRemoteDocumentCache::GetAll( + const DocumentKeySet& keys) { + MaybeDocumentMap results; + + LevelDbRemoteDocumentKey currentKey; + auto it = db_.currentTransaction->NewIterator(); + + for (const DocumentKey& key : keys) { + it->Seek(LevelDbRemoteDocumentKey::Key(key)); + if (!it->Valid() || !currentKey.Decode(it->key()) || + currentKey.document_key() != key) { + results = results.insert(key, nil); + } else { + results = results.insert(key, DecodeMaybeDocument(it->value(), key)); + } + } + + return results; +} + +DocumentMap LevelDbRemoteDocumentCache::GetMatching(FSTQuery* query) { + HARD_ASSERT( + ![query isCollectionGroupQuery], + "CollectionGroup queries should be handled in LocalDocumentsView"); + + DocumentMap results; + + // Use the query path as a prefix for testing if a document matches the query. + const model::ResourcePath& query_path = query.path; + size_t immediate_children_path_length = query_path.size() + 1; + + // Documents are ordered by key, so we can use a prefix scan to narrow down + // the documents we need to match the query against. + std::string start_key = LevelDbRemoteDocumentKey::KeyPrefix(query_path); + auto it = db_.currentTransaction->NewIterator(); + it->Seek(start_key); + + LevelDbRemoteDocumentKey current_key; + for (; it->Valid() && current_key.Decode(it->key()); it->Next()) { + // The query is actually returning any path that starts with the query path + // prefix which may include documents in subcollections. For example, a + // query on 'rooms' will return rooms/abc/messages/xyx but we shouldn't + // match it. Fix this by discarding rows with document keys more than one + // segment longer than the query path. + const DocumentKey& document_key = current_key.document_key(); + if (document_key.path().size() != immediate_children_path_length) { + continue; + } + + FSTMaybeDocument* maybe_doc = + DecodeMaybeDocument(it->value(), document_key); + if (!query_path.IsPrefixOf(maybe_doc.key.path())) { + break; + } else if ([maybe_doc isKindOfClass:[FSTDocument class]]) { + results = + results.insert(maybe_doc.key, static_cast(maybe_doc)); + } + } + + return results; +} + +FSTMaybeDocument* LevelDbRemoteDocumentCache::DecodeMaybeDocument( + absl::string_view encoded, const DocumentKey& key) { + NSData* data = [[NSData alloc] initWithBytesNoCopy:(void*)encoded.data() + length:encoded.size() + freeWhenDone:NO]; + + NSError* error; + FSTPBMaybeDocument* proto = [FSTPBMaybeDocument parseFromData:data + error:&error]; + if (!proto) { + HARD_FAIL("FSTPBMaybeDocument failed to parse: %s", error); + } + + FSTMaybeDocument* maybeDocument = [serializer_ decodedMaybeDocument:proto]; + HARD_ASSERT(maybeDocument.key == key, + "Read document has key (%s) instead of expected key (%s).", + maybeDocument.key.ToString(), key.ToString()); + return maybeDocument; +} + +} // namespace local +} // namespace firestore +} // namespace firebase diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/leveldb_transaction.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/leveldb_transaction.cc new file mode 100644 index 0000000..b1d9f5c --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/leveldb_transaction.cc @@ -0,0 +1,245 @@ +/* + * Copyright 2018 Google + * + * 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 "Firestore/core/src/firebase/firestore/local/leveldb_transaction.h" + +#include "Firestore/core/src/firebase/firestore/local/leveldb_key.h" +#include "Firestore/core/src/firebase/firestore/util/hard_assert.h" +#include "Firestore/core/src/firebase/firestore/util/log.h" +#include "absl/memory/memory.h" +#include "absl/strings/str_cat.h" +#include "leveldb/write_batch.h" + +using leveldb::DB; +using leveldb::ReadOptions; +using leveldb::Slice; +using leveldb::Status; +using leveldb::WriteBatch; +using leveldb::WriteOptions; + +namespace firebase { +namespace firestore { +namespace local { + +LevelDbTransaction::Iterator::Iterator(LevelDbTransaction* txn) + : db_iter_(txn->db_->NewIterator(txn->read_options_)), + last_version_(txn->version_), + txn_(txn), + mutations_iter_(txn->mutations_.begin()), + current_(), + is_mutation_(false), + // Iterator doesn't really point to anything yet, so is + // invalid + is_valid_(false) { +} + +void LevelDbTransaction::Iterator::UpdateCurrent() { + bool mutation_is_valid = mutations_iter_ != txn_->mutations_.end(); + is_valid_ = mutation_is_valid || db_iter_->Valid(); + + if (is_valid_) { + if (!mutation_is_valid) { + is_mutation_ = false; + } else if (!db_iter_->Valid()) { + is_mutation_ = true; + } else { + // Both iterators are valid. If the leveldb key is equal to or greater + // than the current mutation key, we are looking at a mutation next. It's + // either sooner in the iteration or directly shadowing the underlying + // committed value in leveldb. + is_mutation_ = db_iter_->key().compare(mutations_iter_->first) >= 0; + } + if (is_mutation_) { + current_ = *mutations_iter_; + } else { + current_ = {db_iter_->key().ToString(), db_iter_->value().ToString()}; + } + } +} + +void LevelDbTransaction::Iterator::Seek(const std::string& key) { + db_iter_->Seek(key); + HARD_ASSERT(db_iter_->status().ok(), "leveldb iterator reported an error: %s", + db_iter_->status().ToString()); + for (; db_iter_->Valid() && IsDeleted(db_iter_->key()); db_iter_->Next()) { + } + HARD_ASSERT(db_iter_->status().ok(), "leveldb iterator reported an error: %s", + db_iter_->status().ToString()); + mutations_iter_ = txn_->mutations_.lower_bound(key); + UpdateCurrent(); + last_version_ = txn_->version_; +} + +absl::string_view LevelDbTransaction::Iterator::key() { + HARD_ASSERT(Valid(), "key() called on invalid iterator"); + return current_.first; +} + +absl::string_view LevelDbTransaction::Iterator::value() { + HARD_ASSERT(Valid(), "value() called on invalid iterator"); + return current_.second; +} + +bool LevelDbTransaction::Iterator::IsDeleted(leveldb::Slice slice) { + return txn_->deletions_.find(slice.ToString()) != txn_->deletions_.end(); +} + +bool LevelDbTransaction::Iterator::SyncToTransaction() { + if (last_version_ < txn_->version_) { + // Intentionally copying here since Seek() may update current_. We need the + // copy to do the comparison below. + const std::string current_key = current_.first; + Seek(current_key); + // If we advanced, we don't need to advance again. + return is_valid_ && current_.first > current_key; + } else { + return false; + } +} + +void LevelDbTransaction::Iterator::AdvanceLDB() { + do { + db_iter_->Next(); + } while (db_iter_->Valid() && IsDeleted(db_iter_->key())); + HARD_ASSERT(db_iter_->status().ok(), "leveldb iterator reported an error: %s", + db_iter_->status().ToString()); +} + +void LevelDbTransaction::Iterator::Next() { + HARD_ASSERT(Valid(), "Next() called on invalid iterator"); + bool advanced = SyncToTransaction(); + if (!advanced && is_valid_) { + if (is_mutation_) { + // A mutation might be shadowing leveldb. If so, advance both. + if (db_iter_->Valid() && db_iter_->key() == mutations_iter_->first) { + AdvanceLDB(); + } + ++mutations_iter_; + } else { + AdvanceLDB(); + } + UpdateCurrent(); + } +} + +LevelDbTransaction::LevelDbTransaction(DB* db, + absl::string_view label, + const ReadOptions& read_options, + const WriteOptions& write_options) + : db_(db), + mutations_(), + deletions_(), + read_options_(read_options), + write_options_(write_options), + version_(0), + label_(std::string{label}) { +} + +const ReadOptions& LevelDbTransaction::DefaultReadOptions() { + static ReadOptions options = ([]() { + ReadOptions read_options; + read_options.verify_checksums = true; + return read_options; + })(); + return options; +} + +const WriteOptions& LevelDbTransaction::DefaultWriteOptions() { + static WriteOptions options; + return options; +} + +void LevelDbTransaction::Put(std::string key, std::string value) { + deletions_.erase(key); + mutations_.emplace(std::make_pair(std::move(key), std::move(value))); + version_++; +} + +std::unique_ptr +LevelDbTransaction::NewIterator() { + return absl::make_unique(this); +} + +Status LevelDbTransaction::Get(absl::string_view key, std::string* value) { + std::string key_string(key); + if (deletions_.find(key_string) != deletions_.end()) { + return Status::NotFound(key_string + " is not present in the transaction"); + } else { + Mutations::iterator iter{mutations_.find(key_string)}; + if (iter != mutations_.end()) { + *value = iter->second; + return Status::OK(); + } else { + return db_->Get(read_options_, key_string, value); + } + } +} + +void LevelDbTransaction::Delete(absl::string_view key) { + std::string to_delete(key); + deletions_.insert(to_delete); + mutations_.erase(to_delete); + version_++; +} + +void LevelDbTransaction::Commit() { + WriteBatch batch; + for (const auto& deletion : deletions_) { + batch.Delete(deletion); + } + + for (const auto& entry : mutations_) { + batch.Put(entry.first, entry.second); + } + + LOG_DEBUG("Committing transaction: %s", ToString()); + + Status status = db_->Write(write_options_, &batch); + HARD_ASSERT(status.ok(), "Failed to commit transaction:\n%s\n Failed: %s", + ToString(), status.ToString()); +} + +std::string LevelDbTransaction::ToString() { + std::string dest = absl::StrCat(""); + return dest; +} + +std::string DescribeKey( + const std::unique_ptr& iterator) { + if (iterator->Valid()) { + return DescribeKey(iterator->key()); + } else { + return "the end of the table"; + } +} + +} // namespace local +} // namespace firestore +} // namespace firebase diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/leveldb_transaction.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/leveldb_transaction.h new file mode 100644 index 0000000..3dc06fe --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/leveldb_transaction.h @@ -0,0 +1,221 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_LOCAL_LEVELDB_TRANSACTION_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_LOCAL_LEVELDB_TRANSACTION_H_ + +#include +#include +#include +#include +#include +#include + +#include "absl/strings/string_view.h" +#include "leveldb/db.h" + +#if __OBJC__ +#import +#endif + +namespace firebase { +namespace firestore { +namespace local { + +/** + * LevelDBTransaction tracks pending changes to entries in leveldb, including + * deletions. It also provides an Iterator to traverse a merged view of pending + * changes and committed values. + */ +class LevelDbTransaction { + using Deletions = std::set; + using Mutations = std::map; + + public: + /** + * Iterator iterates over a merged view of pending changes from the + * transaction and any unchanged values in the underlying leveldb instance. + */ + class Iterator { + public: + explicit Iterator(LevelDbTransaction* txn); + + /** + * Returns true if this iterator points to an entry + */ + bool Valid() { + return is_valid_; + } + + /** + * Seeks this iterator to the first key equal to or greater than the given + * key + */ + void Seek(const std::string& key); + + /** + * Advances the iterator to the next entry + */ + void Next(); + + /** + * Returns the key of the current entry + */ + absl::string_view key(); + + /** + * Returns the value of the current entry + */ + absl::string_view value(); + + private: + /** + * Advances to the next non-deleted key in leveldb. + */ + void AdvanceLDB(); + + /** + * Returns true if the given slice matches a key present in the deletions_ + * set. + */ + bool IsDeleted(leveldb::Slice slice); + + /** + * Syncs with the underlying transaction. If the transaction has been + * updated, the mutation iterator may need to be reset. Returns true if this + * resulted in moving to a new underlying entry (i.e. the entry represented + * by current_ was deleted). + */ + bool SyncToTransaction(); + + /** + * Given the current state of the internal iterators, set is_valid_, + * is_mutation_, and current_. + */ + void UpdateCurrent(); + + std::unique_ptr db_iter_; + + // The last observed version of the underlying transaction + int32_t last_version_; + // The underlying transaction. + LevelDbTransaction* txn_; + Mutations::iterator mutations_iter_; + // We save the current key and value so that once an iterator is Valid(), it + // remains so at least until the next call to Seek() or Next(), even if the + // underlying data is deleted. + std::pair current_; + // True if current_ represents an entry in the mutations_ map, rather than + // committed data. + bool is_mutation_; + // True if the iterator pointed to a valid entry the last time Next() or + // Seek() was called. + bool is_valid_; + }; + + explicit LevelDbTransaction( + leveldb::DB* db, + absl::string_view label, + const leveldb::ReadOptions& read_options = DefaultReadOptions(), + const leveldb::WriteOptions& write_options = DefaultWriteOptions()); + + LevelDbTransaction(const LevelDbTransaction& other) = delete; + + LevelDbTransaction& operator=(const LevelDbTransaction& other) = delete; + + /** + * Returns a default set of ReadOptions + */ + static const leveldb::ReadOptions& DefaultReadOptions(); + + /** + * Returns a default set of WriteOptions + */ + static const leveldb::WriteOptions& DefaultWriteOptions(); + + size_t changed_keys() const { + return mutations_.size() + deletions_.size(); + } + + /** + * Remove the database entry (if any) for "key". It is not an error if "key" + * did not exist in the database. + */ + void Delete(absl::string_view key); + +#if __OBJC__ + /** + * Schedules the row identified by `key` to be set to the given protocol + * buffer message when this transaction commits. + */ + void Put(absl::string_view key, GPBMessage* message) { + NSData* data = [message data]; + std::string key_string(key); + mutations_[key_string] = std::string((const char*)data.bytes, data.length); + version_++; + } +#endif + + /** + * Schedules the row identified by `key` to be set to `value` when this + * transaction commits. + */ + void Put(std::string key, std::string value); + + /** + * Sets the contents of `value` to the latest known value for the given key, + * including any pending mutations and `Status::OK` is returned. If the key + * doesn't exist in leveldb, or it is scheduled for deletion in this + * transaction, `Status::NotFound` is returned. + */ + leveldb::Status Get(absl::string_view key, std::string* value); + + /** + * Returns a new Iterator over the pending changes in this transaction, merged + * with the existing values already in leveldb. + */ + std::unique_ptr NewIterator(); + + /** + * Commits the transaction. All pending changes are written. The transaction + * should not be used after calling this method. + */ + void Commit(); + + std::string ToString(); + + private: + leveldb::DB* db_; + Mutations mutations_; + Deletions deletions_; + leveldb::ReadOptions read_options_; + leveldb::WriteOptions write_options_; + int32_t version_; + std::string label_; +}; + +/** + * Returns a description of the current key if the iterator is Valid, otherwise + * the string "the end of the table." + */ +std::string DescribeKey( + const std::unique_ptr& iterator); + +} // namespace local +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_LOCAL_LEVELDB_TRANSACTION_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/leveldb_util.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/leveldb_util.cc new file mode 100644 index 0000000..3b5d14e --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/leveldb_util.cc @@ -0,0 +1,49 @@ +/* + * Copyright 2018 Google + * + * 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 "Firestore/core/src/firebase/firestore/local/leveldb_util.h" + +#include "Firestore/core/include/firebase/firestore/firestore_errors.h" +#include "absl/strings/str_cat.h" + +namespace firebase { +namespace firestore { +namespace local { + +namespace { + +FirestoreErrorCode ConvertStatusCode(const leveldb::Status& status) { + if (status.ok()) return FirestoreErrorCode::Ok; + if (status.IsNotFound()) return FirestoreErrorCode::NotFound; + if (status.IsCorruption()) return FirestoreErrorCode::DataLoss; + if (status.IsIOError()) return FirestoreErrorCode::Unavailable; + if (status.IsNotSupportedError()) return FirestoreErrorCode::Unimplemented; + if (status.IsInvalidArgument()) return FirestoreErrorCode::InvalidArgument; + return FirestoreErrorCode::Unknown; +} + +} // namespace + +util::Status ConvertStatus(const leveldb::Status& status) { + if (status.ok()) return util::Status::OK(); + + FirestoreErrorCode code = ConvertStatusCode(status); + return util::Status{code, absl::StrCat("LevelDB error: ", status.ToString())}; +} + +} // namespace local +} // namespace firestore +} // namespace firebase diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/leveldb_util.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/leveldb_util.h new file mode 100644 index 0000000..24a7537 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/leveldb_util.h @@ -0,0 +1,48 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_LOCAL_LEVELDB_UTIL_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_LOCAL_LEVELDB_UTIL_H_ + +#include + +#include "Firestore/core/src/firebase/firestore/util/status.h" +#include "absl/strings/string_view.h" +#include "leveldb/slice.h" +#include "leveldb/status.h" + +namespace firebase { +namespace firestore { +namespace local { + +/** Creates a Slice from a string_view. */ +inline leveldb::Slice MakeSlice(absl::string_view view) { + return leveldb::Slice{view.data(), view.size()}; +} + +/** Creates a string_view from a Slice. */ +inline absl::string_view MakeStringView(leveldb::Slice slice) { + return absl::string_view{slice.data(), slice.size()}; +} + +/** Converts the given LevelDB status to a Firestore status. */ +util::Status ConvertStatus(const leveldb::Status& status); + +} // namespace local +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_LOCAL_LEVELDB_UTIL_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/listen_sequence.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/listen_sequence.h new file mode 100644 index 0000000..6172e97 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/listen_sequence.h @@ -0,0 +1,49 @@ +/* + * Copyright 2019 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_LOCAL_LISTEN_SEQUENCE_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_LOCAL_LISTEN_SEQUENCE_H_ + +#include "Firestore/core/src/firebase/firestore/model/types.h" + +namespace firebase { +namespace firestore { +namespace local { + +/** + * ListenSequence is a monotonic sequence. It is initialized with a minimum + * value to exceed. All subsequent calls to next will return increasing values. + */ +class ListenSequence { + public: + explicit ListenSequence(model::ListenSequenceNumber starting_after) + : previous_sequence_number_(starting_after) { + } + + model::ListenSequenceNumber Next() { + previous_sequence_number_++; + return previous_sequence_number_; + } + + private: + model::ListenSequenceNumber previous_sequence_number_; +}; + +} // namespace local +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_LOCAL_LISTEN_SEQUENCE_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/local_documents_view.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/local_documents_view.h new file mode 100644 index 0000000..b4dd650 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/local_documents_view.h @@ -0,0 +1,117 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_LOCAL_LOCAL_DOCUMENTS_VIEW_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_LOCAL_LOCAL_DOCUMENTS_VIEW_H_ + +#import + +#include + +#include "Firestore/core/src/firebase/firestore/local/index_manager.h" +#include "Firestore/core/src/firebase/firestore/local/mutation_queue.h" +#include "Firestore/core/src/firebase/firestore/local/remote_document_cache.h" +#include "Firestore/core/src/firebase/firestore/model/document_key.h" +#include "Firestore/core/src/firebase/firestore/model/document_key_set.h" +#include "Firestore/core/src/firebase/firestore/model/document_map.h" + +NS_ASSUME_NONNULL_BEGIN + +@class FSTMaybeDocument; +@class FSTMutationBatch; +@class FSTQuery; + +namespace firebase { +namespace firestore { +namespace local { + +/** + * A readonly view of the local state of all documents we're tracking (i.e. we + * have a cached version in remoteDocumentCache or local mutations for the + * document). The view is computed by applying the mutations in the + * FSTMutationQueue to the FSTRemoteDocumentCache. + */ +class LocalDocumentsView { + public: + LocalDocumentsView(RemoteDocumentCache* remote_document_cache, + MutationQueue* mutation_queue, + IndexManager* index_manager) + : remote_document_cache_{remote_document_cache}, + mutation_queue_{mutation_queue}, + index_manager_{index_manager} { + } + + /** + * Gets the local view of the document identified by `key`. + * + * @return Local view of the document or nil if we don't have any cached state + * for it. + */ + FSTMaybeDocument* _Nullable GetDocument(const model::DocumentKey& key); + + /** + * Gets the local view of the documents identified by `keys`. + * + * If we don't have cached state for a document in `keys`, a + * FSTDeletedDocument will be stored for that key in the resulting set. + */ + model::MaybeDocumentMap GetDocuments(const model::DocumentKeySet& keys); + + /** + * Similar to `documentsForKeys`, but creates the local view from the given + * `baseDocs` without retrieving documents from the local store. + */ + model::MaybeDocumentMap GetLocalViewOfDocuments( + const model::MaybeDocumentMap& base_docs); + + /** Performs a query against the local view of all documents. */ + model::DocumentMap GetDocumentsMatchingQuery(FSTQuery* query); + + private: + /** Internal version of GetDocument that allows re-using batches. */ + FSTMaybeDocument* _Nullable GetDocument( + const model::DocumentKey& key, + const std::vector& batches); + + /** + * Returns the view of the given `docs` as they would appear after applying + * all mutations in the given `batches`. + */ + model::MaybeDocumentMap ApplyLocalMutationsToDocuments( + const model::MaybeDocumentMap& docs, + const std::vector& batches); + + /** Performs a simple document lookup for the given path. */ + model::DocumentMap GetDocumentsMatchingDocumentQuery( + const model::ResourcePath& doc_path); + + model::DocumentMap GetDocumentsMatchingCollectionGroupQuery(FSTQuery* query); + + /** Queries the remote documents and overlays mutations. */ + model::DocumentMap GetDocumentsMatchingCollectionQuery(FSTQuery* query); + + RemoteDocumentCache* remote_document_cache_; + MutationQueue* mutation_queue_; + IndexManager* index_manager_; +}; + +} // namespace local +} // namespace firestore +} // namespace firebase + +NS_ASSUME_NONNULL_END + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_LOCAL_LOCAL_DOCUMENTS_VIEW_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/local_documents_view.mm b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/local_documents_view.mm new file mode 100644 index 0000000..c27692b --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/local_documents_view.mm @@ -0,0 +1,222 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#import "Firestore/core/src/firebase/firestore/local/local_documents_view.h" + +#include + +#import "Firestore/Source/Core/FSTQuery.h" +#import "Firestore/Source/Model/FSTDocument.h" +#import "Firestore/Source/Model/FSTMutation.h" +#import "Firestore/Source/Model/FSTMutationBatch.h" + +#include "Firestore/core/src/firebase/firestore/local/mutation_queue.h" +#include "Firestore/core/src/firebase/firestore/local/remote_document_cache.h" +#include "Firestore/core/src/firebase/firestore/model/document_key.h" +#include "Firestore/core/src/firebase/firestore/model/document_map.h" +#include "Firestore/core/src/firebase/firestore/model/resource_path.h" +#include "Firestore/core/src/firebase/firestore/model/snapshot_version.h" +#include "Firestore/core/src/firebase/firestore/util/hard_assert.h" + +NS_ASSUME_NONNULL_BEGIN + +namespace firebase { +namespace firestore { +namespace local { + +using model::DocumentKey; +using model::DocumentKeySet; +using model::DocumentMap; +using model::MaybeDocumentMap; +using model::ResourcePath; +using model::SnapshotVersion; +using util::MakeString; + +FSTMaybeDocument* _Nullable LocalDocumentsView::GetDocument( + const DocumentKey& key) { + std::vector batches = + mutation_queue_->AllMutationBatchesAffectingDocumentKey(key); + return GetDocument(key, batches); +} + +FSTMaybeDocument* _Nullable LocalDocumentsView::GetDocument( + const DocumentKey& key, const std::vector& batches) { + FSTMaybeDocument* _Nullable document = remote_document_cache_->Get(key); + for (FSTMutationBatch* batch : batches) { + document = [batch applyToLocalDocument:document documentKey:key]; + } + + return document; +} + +MaybeDocumentMap LocalDocumentsView::ApplyLocalMutationsToDocuments( + const MaybeDocumentMap& docs, + const std::vector& batches) { + MaybeDocumentMap results; + + for (const auto& kv : docs) { + const DocumentKey& key = kv.first; + FSTMaybeDocument* local_view = kv.second; + for (FSTMutationBatch* batch : batches) { + local_view = [batch applyToLocalDocument:local_view documentKey:key]; + } + results = results.insert(key, local_view); + } + return results; +} + +MaybeDocumentMap LocalDocumentsView::GetDocuments(const DocumentKeySet& keys) { + MaybeDocumentMap docs = remote_document_cache_->GetAll(keys); + return GetLocalViewOfDocuments(docs); +} + +/** + * Similar to `documentsForKeys`, but creates the local view from the given + * `baseDocs` without retrieving documents from the local store. + */ +MaybeDocumentMap LocalDocumentsView::GetLocalViewOfDocuments( + const MaybeDocumentMap& base_docs) { + MaybeDocumentMap results; + + DocumentKeySet all_keys; + for (const auto& kv : base_docs) { + all_keys = all_keys.insert(kv.first); + } + std::vector batches = + mutation_queue_->AllMutationBatchesAffectingDocumentKeys(all_keys); + + MaybeDocumentMap docs = ApplyLocalMutationsToDocuments(base_docs, batches); + + for (const auto& kv : docs) { + const DocumentKey& key = kv.first; + FSTMaybeDocument* maybe_doc = kv.second; + + // TODO(http://b/32275378): Don't conflate missing / deleted. + if (!maybe_doc) { + maybe_doc = [FSTDeletedDocument documentWithKey:key + version:SnapshotVersion::None() + hasCommittedMutations:NO]; + } + results = results.insert(key, maybe_doc); + } + + return results; +} + +DocumentMap LocalDocumentsView::GetDocumentsMatchingQuery(FSTQuery* query) { + if ([query isDocumentQuery]) { + return GetDocumentsMatchingDocumentQuery(query.path); + } else if ([query isCollectionGroupQuery]) { + return GetDocumentsMatchingCollectionGroupQuery(query); + } else { + return GetDocumentsMatchingCollectionQuery(query); + } +} + +DocumentMap LocalDocumentsView::GetDocumentsMatchingDocumentQuery( + const ResourcePath& doc_path) { + DocumentMap result; + // Just do a simple document lookup. + FSTMaybeDocument* doc = GetDocument(DocumentKey{doc_path}); + if ([doc isKindOfClass:[FSTDocument class]]) { + result = result.insert(doc.key, static_cast(doc)); + } + return result; +} + +model::DocumentMap LocalDocumentsView::GetDocumentsMatchingCollectionGroupQuery( + FSTQuery* query) { + HARD_ASSERT( + query.path.empty(), + "Currently we only support collection group queries at the root."); + + std::string collection_id = MakeString(query.collectionGroup); + std::vector parents = + index_manager_->GetCollectionParents(collection_id); + DocumentMap results; + + // Perform a collection query against each parent that contains the + // collection_id and aggregate the results. + for (const ResourcePath& parent : parents) { + FSTQuery* collection_query = + [query collectionQueryAtPath:parent.Append(collection_id)]; + DocumentMap collection_results = + GetDocumentsMatchingCollectionQuery(collection_query); + for (const auto& kv : collection_results.underlying_map()) { + const DocumentKey& key = kv.first; + FSTDocument* doc = static_cast(kv.second); + results = results.insert(key, doc); + } + } + return results; +} + +DocumentMap LocalDocumentsView::GetDocumentsMatchingCollectionQuery( + FSTQuery* query) { + DocumentMap results = remote_document_cache_->GetMatching(query); + // Get locally persisted mutation batches. + std::vector matchingBatches = + mutation_queue_->AllMutationBatchesAffectingQuery(query); + + for (FSTMutationBatch* batch : matchingBatches) { + for (FSTMutation* mutation : [batch mutations]) { + // Only process documents belonging to the collection. + if (!query.path.IsImmediateParentOf(mutation.key.path())) { + continue; + } + + const DocumentKey& key = mutation.key; + // base_doc may be nil for the documents that weren't yet written to the + // backend. + FSTMaybeDocument* base_doc = nil; + auto found = results.underlying_map().find(key); + if (found != results.underlying_map().end()) { + base_doc = found->second; + } + FSTMaybeDocument* mutated_doc = + [mutation applyToLocalDocument:base_doc + baseDocument:base_doc + localWriteTime:batch.localWriteTime]; + + if ([mutated_doc isKindOfClass:[FSTDocument class]]) { + results = results.insert(key, static_cast(mutated_doc)); + } else { + results = results.erase(key); + } + } + } + + // Finally, filter out any documents that don't actually match the query. Note + // that the extra reference here prevents DocumentMap's destructor from + // deallocating the initial unfiltered results while we're iterating over + // them. + DocumentMap unfiltered = results; + for (const auto& kv : unfiltered.underlying_map()) { + const DocumentKey& key = kv.first; + auto* doc = static_cast(kv.second); + if (![query matchesDocument:doc]) { + results = results.erase(key); + } + } + + return results; +} + +} // namespace local +} // namespace firestore +} // namespace firebase + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/local_serializer.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/local_serializer.cc new file mode 100644 index 0000000..2b7944f --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/local_serializer.cc @@ -0,0 +1,292 @@ +/* + * Copyright 2018 Google + * + * 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 "Firestore/core/src/firebase/firestore/local/local_serializer.h" + +#include +#include +#include +#include + +#include "Firestore/Protos/nanopb/firestore/local/maybe_document.nanopb.h" +#include "Firestore/Protos/nanopb/firestore/local/target.nanopb.h" +#include "Firestore/Protos/nanopb/google/firestore/v1/document.nanopb.h" +#include "Firestore/core/src/firebase/firestore/core/query.h" +#include "Firestore/core/src/firebase/firestore/model/field_value.h" +#include "Firestore/core/src/firebase/firestore/model/no_document.h" +#include "Firestore/core/src/firebase/firestore/model/snapshot_version.h" +#include "Firestore/core/src/firebase/firestore/model/unknown_document.h" +#include "Firestore/core/src/firebase/firestore/nanopb/nanopb_util.h" +#include "Firestore/core/src/firebase/firestore/util/hard_assert.h" +#include "Firestore/core/src/firebase/firestore/util/string_format.h" + +namespace firebase { +namespace firestore { +namespace local { + +using core::Query; +using model::Document; +using model::MaybeDocument; +using model::Mutation; +using model::MutationBatch; +using model::NoDocument; +using model::SnapshotVersion; +using model::UnknownDocument; +using nanopb::CheckedSize; +using nanopb::Reader; +using nanopb::Writer; +using remote::MakeArray; +using util::Status; +using util::StringFormat; + +firestore_client_MaybeDocument LocalSerializer::EncodeMaybeDocument( + const MaybeDocument& maybe_doc) const { + firestore_client_MaybeDocument result{}; + + switch (maybe_doc.type()) { + case MaybeDocument::Type::Document: + result.which_document_type = firestore_client_MaybeDocument_document_tag; + result.document = EncodeDocument(static_cast(maybe_doc)); + // TODO(rsgowman): heldwriteacks: + // result.has_committed_mutations = existing_doc.HasCommittedMutations(); + return result; + + case MaybeDocument::Type::NoDocument: + result.which_document_type = + firestore_client_MaybeDocument_no_document_tag; + result.no_document = + EncodeNoDocument(static_cast(maybe_doc)); + // TODO(rsgowman): heldwriteacks: + // result.has_committed_mutations = no_doc.HasCommittedMutations(); + return result; + + case MaybeDocument::Type::UnknownDocument: + result.which_document_type = + firestore_client_MaybeDocument_unknown_document_tag; + result.unknown_document = + EncodeUnknownDocument(static_cast(maybe_doc)); + // TODO(rsgowman): heldwriteacks: + // result.has_committed_mutations = true; + return result; + + case MaybeDocument::Type::Unknown: + // TODO(rsgowman): Error handling + abort(); + } + + UNREACHABLE(); +} + +std::unique_ptr LocalSerializer::DecodeMaybeDocument( + Reader* reader, const firestore_client_MaybeDocument& proto) const { + if (!reader->status().ok()) return nullptr; + + switch (proto.which_document_type) { + case firestore_client_MaybeDocument_document_tag: + return rpc_serializer_.DecodeDocument(reader, proto.document); + + case firestore_client_MaybeDocument_no_document_tag: + return DecodeNoDocument(reader, proto.no_document); + + case firestore_client_MaybeDocument_unknown_document_tag: + return DecodeUnknownDocument(reader, proto.unknown_document); + + default: + reader->Fail( + StringFormat("Invalid MaybeDocument document type: %s. Expected " + "'no_document' (%s) or 'document' (%s)", + proto.which_document_type, + firestore_client_MaybeDocument_no_document_tag, + firestore_client_MaybeDocument_document_tag)); + return nullptr; + } + + UNREACHABLE(); +} + +google_firestore_v1_Document LocalSerializer::EncodeDocument( + const Document& doc) const { + google_firestore_v1_Document result{}; + + result.name = + rpc_serializer_.EncodeString(rpc_serializer_.EncodeKey(doc.key())); + + // Encode Document.fields (unless it's empty) + pb_size_t count = CheckedSize(doc.data().GetInternalValue().size()); + result.fields_count = count; + result.fields = MakeArray(count); + int i = 0; + for (const auto& kv : doc.data().GetInternalValue()) { + result.fields[i].key = rpc_serializer_.EncodeString(kv.first); + result.fields[i].value = rpc_serializer_.EncodeFieldValue(kv.second); + i++; + } + + result.update_time = rpc_serializer_.EncodeVersion(doc.version()); + + // Ignore Document.create_time. (We don't use this in our on-disk protos.) + + return result; +} + +firestore_client_NoDocument LocalSerializer::EncodeNoDocument( + const NoDocument& no_doc) const { + firestore_client_NoDocument result{}; + + result.name = + rpc_serializer_.EncodeString(rpc_serializer_.EncodeKey(no_doc.key())); + result.read_time = rpc_serializer_.EncodeVersion(no_doc.version()); + + return result; +} + +std::unique_ptr LocalSerializer::DecodeNoDocument( + Reader* reader, const firestore_client_NoDocument& proto) const { + SnapshotVersion version = + rpc_serializer_.DecodeSnapshotVersion(reader, proto.read_time); + + // TODO(rsgowman): Fix hardcoding of has_committed_mutations. + // Instead, we should grab this from the proto (see other ports). However, + // we'll defer until the nanopb-master gets merged to master. + return absl::make_unique( + rpc_serializer_.DecodeKey(reader, + rpc_serializer_.DecodeString(proto.name)), + std::move(version), + /*has_committed_mutations=*/false); +} + +firestore_client_UnknownDocument LocalSerializer::EncodeUnknownDocument( + const UnknownDocument& unknown_doc) const { + firestore_client_UnknownDocument result{}; + + result.name = rpc_serializer_.EncodeString( + rpc_serializer_.EncodeKey(unknown_doc.key())); + result.version = rpc_serializer_.EncodeVersion(unknown_doc.version()); + + return result; +} + +std::unique_ptr LocalSerializer::DecodeUnknownDocument( + Reader* reader, const firestore_client_UnknownDocument& proto) const { + SnapshotVersion version = + rpc_serializer_.DecodeSnapshotVersion(reader, proto.version); + + return absl::make_unique( + rpc_serializer_.DecodeKey(reader, + rpc_serializer_.DecodeString(proto.name)), + std::move(version)); +} + +firestore_client_Target LocalSerializer::EncodeQueryData( + const QueryData& query_data) const { + firestore_client_Target result{}; + + result.target_id = query_data.target_id(); + result.last_listen_sequence_number = query_data.sequence_number(); + result.snapshot_version = rpc_serializer_.EncodeTimestamp( + query_data.snapshot_version().timestamp()); + result.resume_token = rpc_serializer_.EncodeBytes(query_data.resume_token()); + + const Query& query = query_data.query(); + if (query.IsDocumentQuery()) { + // TODO(rsgowman): Implement. Probably like this (once EncodeDocumentsTarget + // exists): + /* + result.which_target_type = firestore_client_Target_document_tag; + result.documents = rpc_serializer_.EncodeDocumentsTarget(query); + */ + abort(); + } else { + result.which_target_type = firestore_client_Target_query_tag; + result.query = rpc_serializer_.EncodeQueryTarget(query); + } + + return result; +} + +QueryData LocalSerializer::DecodeQueryData( + Reader* reader, const firestore_client_Target& proto) const { + if (!reader->status().ok()) return QueryData::Invalid(); + + model::TargetId target_id = proto.target_id; + // TODO(rgowman): How to handle truncation of integer types? + model::ListenSequenceNumber sequence_number = + static_cast( + proto.last_listen_sequence_number); + SnapshotVersion version = + rpc_serializer_.DecodeSnapshotVersion(reader, proto.snapshot_version); + std::vector resume_token = + rpc_serializer_.DecodeBytes(proto.resume_token); + Query query = Query::Invalid(); + + switch (proto.which_target_type) { + case firestore_client_Target_query_tag: + query = rpc_serializer_.DecodeQueryTarget(reader, proto.query); + break; + + case firestore_client_Target_documents_tag: + // TODO(rsgowman): Implement. + abort(); + + default: + reader->Fail( + StringFormat("Unknown target_type: %s", proto.which_target_type)); + } + + if (!reader->status().ok()) return QueryData::Invalid(); + return QueryData(std::move(query), target_id, sequence_number, + QueryPurpose::kListen, std::move(version), + std::move(resume_token)); +} + +firestore_client_WriteBatch LocalSerializer::EncodeMutationBatch( + const MutationBatch& mutation_batch) const { + firestore_client_WriteBatch result{}; + + result.batch_id = mutation_batch.batch_id(); + pb_size_t count = CheckedSize(mutation_batch.mutations().size()); + result.writes_count = count; + result.writes = MakeArray(count); + int i = 0; + for (const std::unique_ptr& mutation : mutation_batch.mutations()) { + HARD_ASSERT(mutation, "Null mutation encountered."); + result.writes[i] = rpc_serializer_.EncodeMutation(*mutation.get()); + i++; + } + result.local_write_time = + rpc_serializer_.EncodeTimestamp(mutation_batch.local_write_time()); + + return result; +} + +MutationBatch LocalSerializer::DecodeMutationBatch( + nanopb::Reader* reader, const firestore_client_WriteBatch& proto) const { + int batch_id = proto.batch_id; + Timestamp local_write_time = + rpc_serializer_.DecodeTimestamp(reader, proto.local_write_time); + std::vector> mutations; + for (size_t i = 0; i < proto.writes_count; i++) { + mutations.push_back( + rpc_serializer_.DecodeMutation(reader, proto.writes[i])); + } + + return MutationBatch(batch_id, std::move(local_write_time), + std::move(mutations)); +} + +} // namespace local +} // namespace firestore +} // namespace firebase diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/local_serializer.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/local_serializer.h new file mode 100644 index 0000000..f9b2864 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/local_serializer.h @@ -0,0 +1,143 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_LOCAL_LOCAL_SERIALIZER_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_LOCAL_LOCAL_SERIALIZER_H_ + +#include +#include + +#include "Firestore/Protos/nanopb/firestore/local/maybe_document.nanopb.h" +#include "Firestore/Protos/nanopb/firestore/local/mutation.nanopb.h" +#include "Firestore/Protos/nanopb/firestore/local/target.nanopb.h" +#include "Firestore/core/src/firebase/firestore/local/query_data.h" +#include "Firestore/core/src/firebase/firestore/model/document.h" +#include "Firestore/core/src/firebase/firestore/model/maybe_document.h" +#include "Firestore/core/src/firebase/firestore/model/mutation_batch.h" +#include "Firestore/core/src/firebase/firestore/model/no_document.h" +#include "Firestore/core/src/firebase/firestore/model/types.h" +#include "Firestore/core/src/firebase/firestore/model/unknown_document.h" +#include "Firestore/core/src/firebase/firestore/nanopb/reader.h" +#include "Firestore/core/src/firebase/firestore/nanopb/writer.h" +#include "Firestore/core/src/firebase/firestore/remote/serializer.h" +#include "Firestore/core/src/firebase/firestore/util/status.h" + +namespace firebase { +namespace firestore { +namespace local { + +/** + * @brief Serializer for values stored in the LocalStore. + * + * All errors that occur during serialization are fatal. + * + * All deserialization methods (that can fail) take a nanopb::Reader parameter + * whose status will be set to failed upon an error. Callers must check this + * before using the returned value via `reader->status()`. A deserialization + * method might fail if a protocol buffer is missing a critical field or has a + * value we can't interpret. On error, the return value from a deserialization + * method is unspecified. + * + * Note that local::LocalSerializer currently delegates to the + * remote::Serializer (for the Firestore v1 RPC protocol) to save implementation + * time and code duplication. We'll need to revisit this when the RPC protocol + * we use diverges from local storage. + */ +class LocalSerializer { + public: + explicit LocalSerializer(const remote::Serializer& rpc_serializer) + : rpc_serializer_(rpc_serializer) { + } + + /** + * Release memory allocated by the Encode* methods that return protos. + * + * This essentially wraps calls to nanopb's pb_release() method. + */ + static void FreeNanopbMessage(const pb_field_t fields[], void* dest_struct) { + remote::Serializer::FreeNanopbMessage(fields, dest_struct); + } + + /** + * @brief Encodes a MaybeDocument model to the equivalent nanopb proto for + * local storage. + */ + firestore_client_MaybeDocument EncodeMaybeDocument( + const model::MaybeDocument& maybe_doc) const; + + /** + * @brief Decodes nanopb proto representing a MaybeDocument proto to the + * equivalent model. + */ + std::unique_ptr DecodeMaybeDocument( + nanopb::Reader* reader, + const firestore_client_MaybeDocument& proto) const; + + /** + * @brief Encodes a QueryData to the equivalent nanopb proto, representing a + * ::firestore::proto::Target, for local storage. + */ + firestore_client_Target EncodeQueryData(const QueryData& query_data) const; + + /** + * @brief Decodes nanopb proto representing a ::firestore::proto::Target proto + * to the equivalent QueryData. + */ + QueryData DecodeQueryData(nanopb::Reader* reader, + const firestore_client_Target& proto) const; + + /** + * @brief Encodes a MutationBatch to the equivalent nanopb proto, representing + * a ::firestore::client::WriteBatch, for local storage in the mutation queue. + */ + firestore_client_WriteBatch EncodeMutationBatch( + const model::MutationBatch& mutation_batch) const; + + /** + * @brief Decodes a nanopb proto representing a + * ::firestore::client::WriteBatch proto to the equivalent MutationBatch. + */ + model::MutationBatch DecodeMutationBatch( + nanopb::Reader* reader, const firestore_client_WriteBatch& proto) const; + + private: + /** + * Encodes a Document for local storage. This differs from the v1 RPC + * serializer for Documents in that it preserves the updateTime, which is + * considered an output only value by the server. + */ + google_firestore_v1_Document EncodeDocument(const model::Document& doc) const; + + firestore_client_NoDocument EncodeNoDocument( + const model::NoDocument& no_doc) const; + + std::unique_ptr DecodeNoDocument( + nanopb::Reader* reader, const firestore_client_NoDocument& proto) const; + + firestore_client_UnknownDocument EncodeUnknownDocument( + const model::UnknownDocument& unknown_doc) const; + std::unique_ptr DecodeUnknownDocument( + nanopb::Reader* reader, + const firestore_client_UnknownDocument& proto) const; + + const remote::Serializer& rpc_serializer_; +}; + +} // namespace local +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_LOCAL_LOCAL_SERIALIZER_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/memory_index_manager.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/memory_index_manager.cc new file mode 100644 index 0000000..0827416 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/memory_index_manager.cc @@ -0,0 +1,67 @@ +/* + * Copyright 2019 Google + * + * 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 "Firestore/core/src/firebase/firestore/local/memory_index_manager.h" + +#include +#include +#include +#include + +#include "Firestore/core/src/firebase/firestore/model/resource_path.h" +#include "Firestore/core/src/firebase/firestore/util/hard_assert.h" + +namespace firebase { +namespace firestore { +namespace local { + +using model::ResourcePath; + +bool MemoryCollectionParentIndex::Add(const ResourcePath& collection_path) { + HARD_ASSERT(collection_path.size() % 2 == 1, "Expected a collection path."); + + std::string collection_id = collection_path.last_segment(); + ResourcePath parent_path = collection_path.PopLast(); + std::set& existingParents = index_[collection_id]; + bool inserted = existingParents.insert(parent_path).second; + return inserted; +} + +std::vector MemoryCollectionParentIndex::GetEntries( + const std::string& collection_id) const { + std::vector result; + auto found = index_.find(collection_id); + if (found != index_.end()) { + const std::set& parent_paths = found->second; + std::copy(parent_paths.begin(), parent_paths.end(), + std::back_inserter(result)); + } + return result; +} + +void MemoryIndexManager::AddToCollectionParentIndex( + const ResourcePath& collection_path) { + collection_parents_index_.Add(collection_path); +} + +std::vector MemoryIndexManager::GetCollectionParents( + const std::string& collection_id) { + return collection_parents_index_.GetEntries(collection_id); +} + +} // namespace local +} // namespace firestore +} // namespace firebase diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/memory_index_manager.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/memory_index_manager.h new file mode 100644 index 0000000..06a0eb8 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/memory_index_manager.h @@ -0,0 +1,66 @@ +/* + * Copyright 2019 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_LOCAL_MEMORY_INDEX_MANAGER_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_LOCAL_MEMORY_INDEX_MANAGER_H_ + +#include +#include +#include +#include + +#include "Firestore/core/src/firebase/firestore/local/index_manager.h" +#include "Firestore/core/src/firebase/firestore/model/resource_path.h" + +namespace firebase { +namespace firestore { +namespace local { + +/** + * Internal implementation of the collection-parent index. Also used for + * in-memory caching by LevelDbIndexManager and initial index population during + * schema migration. + */ +class MemoryCollectionParentIndex { + public: + // Returns false if the entry already existed. + bool Add(const model::ResourcePath& collection_path); + + std::vector GetEntries( + const std::string& collection_id) const; + + private: + std::unordered_map> index_; +}; + +/** An in-memory implementation of IndexManager. */ +class MemoryIndexManager : public IndexManager { + public: + void AddToCollectionParentIndex( + const model::ResourcePath& collection_path) override; + + std::vector GetCollectionParents( + const std::string& collection_id) override; + + private: + MemoryCollectionParentIndex collection_parents_index_; +}; + +} // namespace local +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_LOCAL_MEMORY_INDEX_MANAGER_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/memory_mutation_queue.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/memory_mutation_queue.h new file mode 100644 index 0000000..927317c --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/memory_mutation_queue.h @@ -0,0 +1,159 @@ +/* + * Copyright 2019 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_LOCAL_MEMORY_MUTATION_QUEUE_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_LOCAL_MEMORY_MUTATION_QUEUE_H_ + +#if !defined(__OBJC__) +#error "For now, this file must only be included by ObjC source files." +#endif // !defined(__OBJC__) + +#import + +#include +#include + +#import "Firestore/Source/Public/FIRTimestamp.h" + +#include "Firestore/core/src/firebase/firestore/immutable/sorted_set.h" +#include "Firestore/core/src/firebase/firestore/local/document_key_reference.h" +#include "Firestore/core/src/firebase/firestore/local/mutation_queue.h" +#include "Firestore/core/src/firebase/firestore/model/document_key.h" +#include "Firestore/core/src/firebase/firestore/model/document_key_set.h" +#include "Firestore/core/src/firebase/firestore/model/types.h" + +@class FSTLocalSerializer; +@class FSTMemoryPersistence; +@class FSTMutation; +@class FSTMutationBatch; +@class FSTQuery; + +NS_ASSUME_NONNULL_BEGIN + +namespace firebase { +namespace firestore { +namespace local { + +class MemoryMutationQueue : public MutationQueue { + public: + explicit MemoryMutationQueue(FSTMemoryPersistence* persistence); + + void Start() override; + + bool IsEmpty() override; + + void AcknowledgeBatch(FSTMutationBatch* batch, + NSData* _Nullable stream_token) override; + + FSTMutationBatch* AddMutationBatch( + FIRTimestamp* local_write_time, + std::vector&& base_mutations, + std::vector&& mutations) override; + + void RemoveMutationBatch(FSTMutationBatch* batch) override; + + std::vector AllMutationBatches() override { + return queue_; + } + + std::vector AllMutationBatchesAffectingDocumentKeys( + const model::DocumentKeySet& document_keys) override; + + std::vector AllMutationBatchesAffectingDocumentKey( + const model::DocumentKey& key) override; + + std::vector AllMutationBatchesAffectingQuery( + FSTQuery* query) override; + + FSTMutationBatch* _Nullable LookupMutationBatch( + model::BatchId batch_id) override; + + FSTMutationBatch* _Nullable NextMutationBatchAfterBatchId( + model::BatchId batch_id) override; + + void PerformConsistencyCheck() override; + + bool ContainsKey(const model::DocumentKey& key); + + size_t CalculateByteSize(FSTLocalSerializer* serializer); + + NSData* _Nullable GetLastStreamToken() override; + void SetLastStreamToken(NSData* _Nullable token) override; + + private: + using DocumentKeyReferenceSet = + immutable::SortedSet; + + std::vector AllMutationBatchesWithIds( + const std::set& batch_ids); + + /** + * Finds the index of the given batchID in the mutation queue. This operation + * is O(1). + * + * @return The computed index of the batch with the given BatchID, based on + * the state of the queue. Note this index can negative if the requested + * BatchID has already been removed from the queue or past the end of the + * queue if the BatchID is larger than the last added batch. + */ + int IndexOfBatchId(model::BatchId batch_id); + + // This instance is owned by FSTMemoryPersistence; avoid a retain cycle. + __weak FSTMemoryPersistence* persistence_; + /** + * A FIFO queue of all mutations to apply to the backend. Mutations are added + * to the end of the queue as they're written, and removed from the front of + * the queue as the mutations become visible or are rejected. + * + * When successfully applied, mutations must be acknowledged by the write + * stream and made visible on the watch stream. It's possible for the watch + * stream to fall behind in which case the batches at the head of the queue + * will be acknowledged but held until the watch stream sees the changes. + * + * If a batch is rejected while there are held write acknowledgements at the + * head of the queue the rejected batch is converted to a tombstone: its + * mutations are removed but the batch remains in the queue. This maintains a + * simple consecutive ordering of batches in the queue. + * + * Once the held write acknowledgements become visible they are removed from + * the head of the queue along with any tombstones that follow. + */ + std::vector queue_; + + /** + * The next value to use when assigning sequential IDs to each mutation + * batch. + */ + model::BatchId next_batch_id_ = 1; + + /** + * The last received stream token from the server, used to acknowledge which + * responses the client has processed. Stream tokens are opaque checkpoint + * markers whose only real value is their inclusion in the next request. + */ + NSData* _Nullable last_stream_token_; + + /** An ordered mapping between documents and the mutation batch IDs. */ + DocumentKeyReferenceSet batches_by_document_key_; +}; + +} // namespace local +} // namespace firestore +} // namespace firebase + +NS_ASSUME_NONNULL_END + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_LOCAL_MEMORY_MUTATION_QUEUE_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/memory_mutation_queue.mm b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/memory_mutation_queue.mm new file mode 100644 index 0000000..aace5e5 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/memory_mutation_queue.mm @@ -0,0 +1,298 @@ +/* + * Copyright 2019 Google + * + * 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 "Firestore/core/src/firebase/firestore/local/memory_mutation_queue.h" + +#include + +#import "Firestore/Protos/objc/firestore/local/Mutation.pbobjc.h" +#import "Firestore/Source/Core/FSTQuery.h" +#import "Firestore/Source/Local/FSTLocalSerializer.h" +#import "Firestore/Source/Local/FSTMemoryPersistence.h" +#import "Firestore/Source/Model/FSTMutation.h" +#import "Firestore/Source/Model/FSTMutationBatch.h" + +#include "Firestore/core/src/firebase/firestore/local/document_key_reference.h" +#include "Firestore/core/src/firebase/firestore/model/resource_path.h" +#include "Firestore/core/src/firebase/firestore/util/hard_assert.h" + +NS_ASSUME_NONNULL_BEGIN + +namespace firebase { +namespace firestore { +namespace local { + +using model::BatchId; +using model::DocumentKey; +using model::DocumentKeySet; +using model::ResourcePath; + +MemoryMutationQueue::MemoryMutationQueue(FSTMemoryPersistence* persistence) + : persistence_(persistence) { +} + +bool MemoryMutationQueue::IsEmpty() { + // If the queue has any entries at all, the first entry must not be a + // tombstone (otherwise it would have been removed already). + return queue_.empty(); +} + +void MemoryMutationQueue::AcknowledgeBatch(FSTMutationBatch* batch, + NSData* _Nullable stream_token) { + HARD_ASSERT(!queue_.empty(), "Cannot acknowledge batch on an empty queue"); + + // Guaranteed to exist, due to above assert + FSTMutationBatch* check = queue_.front(); + // Verify that the batch in the queue is the one to be acknowledged. + HARD_ASSERT(batch.batchID == check.batchID, + "Queue ordering failure: expected batch %s, got batch %s", + batch.batchID, check.batchID); + last_stream_token_ = stream_token; +} + +void MemoryMutationQueue::Start() { + // Note: The queue may be shutdown / started multiple times, since we maintain + // the queue for the duration of the app session in case a user logs out / + // back in. To behave like the LevelDB-backed MutationQueue (and accommodate + // tests that expect as much), we reset nextBatchID if the queue is empty. + if (IsEmpty()) { + next_batch_id_ = 1; + } +} + +FSTMutationBatch* MemoryMutationQueue::AddMutationBatch( + FIRTimestamp* local_write_time, + std::vector&& base_mutations, + std::vector&& mutations) { + HARD_ASSERT(!mutations.empty(), "Mutation batches should not be empty"); + + BatchId batch_id = next_batch_id_; + next_batch_id_++; + + if (!queue_.empty()) { + FSTMutationBatch* prior = queue_.back(); + HARD_ASSERT(prior.batchID < batch_id, + "Mutation batchIDs must be in monotonically increasing order"); + } + + FSTMutationBatch* batch = + [[FSTMutationBatch alloc] initWithBatchID:batch_id + localWriteTime:local_write_time + baseMutations:std::move(base_mutations) + mutations:std::move(mutations)]; + queue_.push_back(batch); + + // Track references by document key and index collection parents. + for (FSTMutation* mutation : [batch mutations]) { + batches_by_document_key_ = batches_by_document_key_.insert( + DocumentKeyReference{mutation.key, batch_id}); + + persistence_.indexManager->AddToCollectionParentIndex( + mutation.key.path().PopLast()); + } + + return batch; +} + +void MemoryMutationQueue::RemoveMutationBatch(FSTMutationBatch* batch) { + // Can only remove the first batch + HARD_ASSERT(!queue_.empty(), "Trying to remove batch from empty queue"); + FSTMutationBatch* head = queue_.front(); + HARD_ASSERT(head.batchID == batch.batchID, + "Can only remove the first entry of the mutation queue"); + + queue_.erase(queue_.begin()); + + // Remove entries from the index too. + for (FSTMutation* mutation : [batch mutations]) { + const DocumentKey& key = mutation.key; + [persistence_.referenceDelegate removeMutationReference:key]; + + DocumentKeyReference reference{key, batch.batchID}; + batches_by_document_key_ = batches_by_document_key_.erase(reference); + } +} + +std::vector +MemoryMutationQueue::AllMutationBatchesAffectingDocumentKeys( + const DocumentKeySet& document_keys) { + // First find the set of affected batch IDs. + std::set batch_ids; + for (const DocumentKey& key : document_keys) { + DocumentKeyReference start{key, 0}; + + for (const auto& reference : batches_by_document_key_.values_from(start)) { + if (key != reference.key()) break; + + batch_ids.insert(reference.ref_id()); + } + } + + return AllMutationBatchesWithIds(batch_ids); +} + +std::vector +MemoryMutationQueue::AllMutationBatchesAffectingDocumentKey( + const DocumentKey& key) { + std::vector result; + + DocumentKeyReference start{key, 0}; + for (const auto& reference : batches_by_document_key_.values_from(start)) { + if (key != reference.key()) break; + + FSTMutationBatch* batch = LookupMutationBatch(reference.ref_id()); + HARD_ASSERT(batch, "Batches in the index must exist in the main table"); + result.push_back(batch); + } + return result; +} + +std::vector +MemoryMutationQueue::AllMutationBatchesAffectingQuery(FSTQuery* query) { + HARD_ASSERT( + ![query isCollectionGroupQuery], + "CollectionGroup queries should be handled in LocalDocumentsView"); + + // Use the query path as a prefix for testing if a document matches the query. + const ResourcePath& prefix = query.path; + size_t immediate_children_path_length = prefix.size() + 1; + + // Construct a document reference for actually scanning the index. Unlike the + // prefix, the document key in this reference must have an even number of + // segments. The empty segment can be used as a suffix of the query path + // because it precedes all other segments in an ordered traversal. + ResourcePath start_path = query.path; + if (!DocumentKey::IsDocumentKey(start_path)) { + start_path = start_path.Append(""); + } + DocumentKeyReference start{DocumentKey{start_path}, 0}; + + // Find unique batchIDs referenced by all documents potentially matching the + // query. + std::set unique_batch_ids; + for (const auto& reference : batches_by_document_key_.values_from(start)) { + const ResourcePath& row_key_path = reference.key().path(); + if (!prefix.IsPrefixOf(row_key_path)) { + break; + } + + // Rows with document keys more than one segment longer than the query path + // can't be matches. For example, a query on 'rooms' can't match the + // document /rooms/abc/messages/xyx. + // TODO(mcg): we'll need a different scanner when we implement ancestor + // queries. + if (row_key_path.size() != immediate_children_path_length) { + continue; + } + + unique_batch_ids.insert(reference.ref_id()); + }; + + return AllMutationBatchesWithIds(unique_batch_ids); +} + +FSTMutationBatch* _Nullable MemoryMutationQueue::NextMutationBatchAfterBatchId( + BatchId batch_id) { + BatchId next_batch_id = batch_id + 1; + + // The requested batchID may still be out of range so normalize it to the + // start of the queue. + int raw_index = IndexOfBatchId(next_batch_id); + int index = raw_index < 0 ? 0 : raw_index; + return queue_.size() > index ? queue_[index] : nil; +} + +FSTMutationBatch* _Nullable MemoryMutationQueue::LookupMutationBatch( + BatchId batch_id) { + if (queue_.empty()) { + return nil; + } + + int index = IndexOfBatchId(batch_id); + if (index < 0 || index >= queue_.size()) { + return nil; + } + + FSTMutationBatch* batch = queue_[index]; + HARD_ASSERT(batch.batchID == batch_id, "If found, batch must match"); + return batch; +} + +void MemoryMutationQueue::PerformConsistencyCheck() { + if (queue_.empty()) { + HARD_ASSERT(batches_by_document_key_.empty(), + "Document leak -- detected dangling mutation references when " + "queue is empty."); + } +} + +bool MemoryMutationQueue::ContainsKey(const model::DocumentKey& key) { + // Create a reference with a zero ID as the start position to find any + // document reference with this key. + DocumentKeyReference reference{key, 0}; + auto range = batches_by_document_key_.values_from(reference); + auto begin = range.begin(); + return begin != range.end() && begin->key() == key; +} + +size_t MemoryMutationQueue::CalculateByteSize(FSTLocalSerializer* serializer) { + size_t count = 0; + for (const auto& batch : queue_) { + count += [[serializer encodedMutationBatch:batch] serializedSize]; + }; + return count; +} + +NSData* _Nullable MemoryMutationQueue::GetLastStreamToken() { + return last_stream_token_; +} + +void MemoryMutationQueue::SetLastStreamToken(NSData* _Nullable token) { + last_stream_token_ = token; +} + +std::vector MemoryMutationQueue::AllMutationBatchesWithIds( + const std::set& batch_ids) { + std::vector result; + for (BatchId batch_id : batch_ids) { + FSTMutationBatch* batch = LookupMutationBatch(batch_id); + if (batch) { + result.push_back(batch); + } + } + + return result; +} + +int MemoryMutationQueue::IndexOfBatchId(BatchId batch_id) { + if (queue_.empty()) { + // As an index this is past the end of the queue + return 0; + } + + // Examine the front of the queue to figure out the difference between the + // batchID and indexes in the array. Note that since the queue is ordered by + // batchID, if the first batch has a larger batchID then the requested batchID + // doesn't exist in the queue. + FSTMutationBatch* first_batch = queue_.front(); + return batch_id - first_batch.batchID; +} + +} // namespace local +} // namespace firestore +} // namespace firebase + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/memory_query_cache.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/memory_query_cache.h new file mode 100644 index 0000000..747756a --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/memory_query_cache.h @@ -0,0 +1,124 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_LOCAL_MEMORY_QUERY_CACHE_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_LOCAL_MEMORY_QUERY_CACHE_H_ + +#if !defined(__OBJC__) +#error "For now, this file must only be included by ObjC source files." +#endif // !defined(__OBJC__) + +#import + +#include +#include +#include + +#include "Firestore/core/src/firebase/firestore/local/query_cache.h" +#include "Firestore/core/src/firebase/firestore/local/reference_set.h" +#include "Firestore/core/src/firebase/firestore/model/document_key_set.h" +#include "Firestore/core/src/firebase/firestore/model/snapshot_version.h" +#include "Firestore/core/src/firebase/firestore/model/types.h" +#include "Firestore/core/src/firebase/firestore/util/objc_compatibility.h" + +@class FSTLocalSerializer; +@class FSTMemoryPersistence; +@class FSTQuery; +@class FSTQueryData; + +NS_ASSUME_NONNULL_BEGIN + +namespace firebase { +namespace firestore { +namespace local { + +class MemoryQueryCache : public QueryCache { + public: + explicit MemoryQueryCache(FSTMemoryPersistence* persistence); + + // Target-related methods + void AddTarget(FSTQueryData* query_data) override; + + void UpdateTarget(FSTQueryData* query_data) override; + + void RemoveTarget(FSTQueryData* query_data) override; + + FSTQueryData* _Nullable GetTarget(FSTQuery* query) override; + + void EnumerateTargets(const TargetCallback& callback) override; + + int RemoveTargets(model::ListenSequenceNumber upper_bound, + const std::unordered_map& + live_targets) override; + + // Key-related methods + void AddMatchingKeys(const model::DocumentKeySet& keys, + model::TargetId target_id) override; + + void RemoveMatchingKeys(const model::DocumentKeySet& keys, + model::TargetId target_id) override; + + model::DocumentKeySet GetMatchingKeys(model::TargetId target_id) override; + + bool Contains(const model::DocumentKey& key) override; + + // Other methods and accessors + size_t CalculateByteSize(FSTLocalSerializer* serializer); + + size_t size() const override { + return queries_.size(); + } + + model::ListenSequenceNumber highest_listen_sequence_number() const override { + return highest_listen_sequence_number_; + } + + model::TargetId highest_target_id() const override { + return highest_target_id_; + } + + const model::SnapshotVersion& GetLastRemoteSnapshotVersion() const override; + + void SetLastRemoteSnapshotVersion(model::SnapshotVersion version) override; + + private: + // This instance is owned by FSTMemoryPersistence; avoid a retain cycle. + __weak FSTMemoryPersistence* persistence_; + + /** The highest sequence number encountered */ + model::ListenSequenceNumber highest_listen_sequence_number_; + /** The highest numbered target ID encountered. */ + model::TargetId highest_target_id_; + /** The last received snapshot version. */ + model::SnapshotVersion last_remote_snapshot_version_; + + /** Maps a query to the data about that query. */ + util::objc::unordered_map queries_; + + /** + * A ordered bidirectional mapping between documents and the remote target + * IDs. + */ + ReferenceSet references_; +}; + +} // namespace local +} // namespace firestore +} // namespace firebase + +NS_ASSUME_NONNULL_END + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_LOCAL_MEMORY_QUERY_CACHE_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/memory_query_cache.mm b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/memory_query_cache.mm new file mode 100644 index 0000000..05a6985 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/memory_query_cache.mm @@ -0,0 +1,148 @@ +/* + * Copyright 2018 Google + * + * 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 "Firestore/core/src/firebase/firestore/local/memory_query_cache.h" + +#import + +#include + +#import "Firestore/Protos/objc/firestore/local/Target.pbobjc.h" +#import "Firestore/Source/Core/FSTQuery.h" +#import "Firestore/Source/Local/FSTMemoryPersistence.h" +#import "Firestore/Source/Local/FSTQueryData.h" + +#include "Firestore/core/src/firebase/firestore/model/document_key.h" + +using firebase::firestore::model::DocumentKey; +using firebase::firestore::model::DocumentKeySet; +using firebase::firestore::model::ListenSequenceNumber; +using firebase::firestore::model::SnapshotVersion; +using firebase::firestore::model::TargetId; + +namespace firebase { +namespace firestore { +namespace local { + +NS_ASSUME_NONNULL_BEGIN + +MemoryQueryCache::MemoryQueryCache(FSTMemoryPersistence* persistence) + : persistence_(persistence), + highest_listen_sequence_number_(ListenSequenceNumber(0)), + highest_target_id_(TargetId(0)), + last_remote_snapshot_version_(SnapshotVersion::None()), + queries_() { +} + +void MemoryQueryCache::AddTarget(FSTQueryData* query_data) { + queries_[query_data.query] = query_data; + if (query_data.targetID > highest_target_id_) { + highest_target_id_ = query_data.targetID; + } + if (query_data.sequenceNumber > highest_listen_sequence_number_) { + highest_listen_sequence_number_ = query_data.sequenceNumber; + } +} + +void MemoryQueryCache::UpdateTarget(FSTQueryData* query_data) { + // For the memory query cache, adds and updates are treated the same. + AddTarget(query_data); +} + +void MemoryQueryCache::RemoveTarget(FSTQueryData* query_data) { + queries_.erase(query_data.query); + references_.RemoveReferences(query_data.targetID); +} + +FSTQueryData* _Nullable MemoryQueryCache::GetTarget(FSTQuery* query) { + auto iter = queries_.find(query); + return iter == queries_.end() ? nil : iter->second; +} + +void MemoryQueryCache::EnumerateTargets(const TargetCallback& callback) { + for (const auto& kv : queries_) { + callback(kv.second); + } +} + +int MemoryQueryCache::RemoveTargets( + model::ListenSequenceNumber upper_bound, + const std::unordered_map& live_targets) { + std::vector to_remove; + for (const auto& kv : queries_) { + FSTQuery* query = kv.first; + FSTQueryData* query_data = kv.second; + + if (query_data.sequenceNumber <= upper_bound) { + if (live_targets.find(query_data.targetID) == live_targets.end()) { + to_remove.push_back(query); + references_.RemoveReferences(query_data.targetID); + } + } + } + + for (FSTQuery* element : to_remove) { + queries_.erase(element); + } + return static_cast(to_remove.size()); +} + +void MemoryQueryCache::AddMatchingKeys(const DocumentKeySet& keys, + TargetId target_id) { + references_.AddReferences(keys, target_id); + for (const DocumentKey& key : keys) { + [persistence_.referenceDelegate addReference:key]; + } +} + +void MemoryQueryCache::RemoveMatchingKeys(const DocumentKeySet& keys, + TargetId target_id) { + references_.RemoveReferences(keys, target_id); + for (const DocumentKey& key : keys) { + [persistence_.referenceDelegate removeReference:key]; + } +} + +DocumentKeySet MemoryQueryCache::GetMatchingKeys(TargetId target_id) { + return references_.ReferencedKeys(target_id); +} + +bool MemoryQueryCache::Contains(const DocumentKey& key) { + return references_.ContainsKey(key); +} + +size_t MemoryQueryCache::CalculateByteSize(FSTLocalSerializer* serializer) { + size_t count = 0; + for (const auto& kv : queries_) { + FSTQueryData* query_data = kv.second; + count += [[serializer encodedQueryData:query_data] serializedSize]; + } + return count; +} + +const SnapshotVersion& MemoryQueryCache::GetLastRemoteSnapshotVersion() const { + return last_remote_snapshot_version_; +} + +void MemoryQueryCache::SetLastRemoteSnapshotVersion(SnapshotVersion version) { + last_remote_snapshot_version_ = std::move(version); +} + +NS_ASSUME_NONNULL_END + +} // namespace local +} // namespace firestore +} // namespace firebase diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/memory_remote_document_cache.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/memory_remote_document_cache.h new file mode 100644 index 0000000..e0f3cda --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/memory_remote_document_cache.h @@ -0,0 +1,75 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_LOCAL_MEMORY_REMOTE_DOCUMENT_CACHE_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_LOCAL_MEMORY_REMOTE_DOCUMENT_CACHE_H_ + +#if !defined(__OBJC__) +#error "For now, this file must only be included by ObjC source files." +#endif // !defined(__OBJC__) + +#include + +#include "Firestore/core/src/firebase/firestore/local/remote_document_cache.h" +#include "Firestore/core/src/firebase/firestore/model/document_key.h" +#include "Firestore/core/src/firebase/firestore/model/document_key_set.h" +#include "Firestore/core/src/firebase/firestore/model/document_map.h" +#include "Firestore/core/src/firebase/firestore/model/types.h" + +@class FSTLocalSerializer; +@class FSTMaybeDocument; +@class FSTMemoryLRUReferenceDelegate; +@class FSTMemoryPersistence; +@class FSTQuery; + +NS_ASSUME_NONNULL_BEGIN + +namespace firebase { +namespace firestore { +namespace local { + +class MemoryRemoteDocumentCache : public RemoteDocumentCache { + public: + explicit MemoryRemoteDocumentCache(FSTMemoryPersistence *persistence); + + void Add(FSTMaybeDocument *document) override; + void Remove(const model::DocumentKey &key) override; + + FSTMaybeDocument *_Nullable Get(const model::DocumentKey &key) override; + model::MaybeDocumentMap GetAll(const model::DocumentKeySet &keys) override; + model::DocumentMap GetMatching(FSTQuery *query) override; + + std::vector RemoveOrphanedDocuments( + FSTMemoryLRUReferenceDelegate *reference_delegate, + model::ListenSequenceNumber upper_bound); + + size_t CalculateByteSize(FSTLocalSerializer *serializer); + + private: + /** Underlying cache of documents. */ + model::MaybeDocumentMap docs_; + + // This instance is owned by FSTMemoryPersistence; avoid a retain cycle. + __weak FSTMemoryPersistence *persistence_; +}; + +} // namespace local +} // namespace firestore +} // namespace firebase + +NS_ASSUME_NONNULL_END + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_LOCAL_MEMORY_REMOTE_DOCUMENT_CACHE_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/memory_remote_document_cache.mm b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/memory_remote_document_cache.mm new file mode 100644 index 0000000..82503a0 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/memory_remote_document_cache.mm @@ -0,0 +1,139 @@ +/* + * Copyright 2018 Google + * + * 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 "Firestore/core/src/firebase/firestore/local/memory_remote_document_cache.h" + +#import "Firestore/Protos/objc/firestore/local/MaybeDocument.pbobjc.h" +#import "Firestore/Source/Core/FSTQuery.h" +#import "Firestore/Source/Local/FSTMemoryPersistence.h" + +#include "Firestore/core/src/firebase/firestore/util/hard_assert.h" + +using firebase::firestore::model::DocumentKey; +using firebase::firestore::model::DocumentKeySet; +using firebase::firestore::model::DocumentMap; +using firebase::firestore::model::ListenSequenceNumber; +using firebase::firestore::model::MaybeDocumentMap; + +namespace firebase { +namespace firestore { +namespace local { + +namespace { +/** + * Returns an estimate of the number of bytes used to store the given + * document key in memory. This is only an estimate and includes the size + * of the segments of the path, but not any object overhead or path separators. + */ +size_t DocumentKeyByteSize(const DocumentKey& key) { + size_t count = 0; + for (const auto& segment : key.path()) { + count += segment.size(); + } + return count; +} +} // namespace + +MemoryRemoteDocumentCache::MemoryRemoteDocumentCache( + FSTMemoryPersistence* persistence) { + persistence_ = persistence; +} + +void MemoryRemoteDocumentCache::Add(FSTMaybeDocument* document) { + docs_ = docs_.insert(document.key, document); + + persistence_.indexManager->AddToCollectionParentIndex( + document.key.path().PopLast()); +} + +void MemoryRemoteDocumentCache::Remove(const DocumentKey& key) { + docs_ = docs_.erase(key); +} + +FSTMaybeDocument* _Nullable MemoryRemoteDocumentCache::Get( + const DocumentKey& key) { + auto found = docs_.find(key); + return found != docs_.end() ? found->second : nil; +} + +MaybeDocumentMap MemoryRemoteDocumentCache::GetAll(const DocumentKeySet& keys) { + MaybeDocumentMap results; + for (const DocumentKey& key : keys) { + // Make sure each key has a corresponding entry, which is null in case the + // document is not found. + // TODO(http://b/32275378): Don't conflate missing / deleted. + results = results.insert(key, Get(key)); + } + return results; +} + +DocumentMap MemoryRemoteDocumentCache::GetMatching(FSTQuery* query) { + HARD_ASSERT( + ![query isCollectionGroupQuery], + "CollectionGroup queries should be handled in LocalDocumentsView"); + + DocumentMap results; + + // Documents are ordered by key, so we can use a prefix scan to narrow down + // the documents we need to match the query against. + DocumentKey prefix{query.path.Append("")}; + for (auto it = docs_.lower_bound(prefix); it != docs_.end(); ++it) { + const DocumentKey& key = it->first; + if (!query.path.IsPrefixOf(key.path())) { + break; + } + FSTMaybeDocument* maybeDoc = it->second; + if (![maybeDoc isKindOfClass:[FSTDocument class]]) { + continue; + } + FSTDocument* doc = static_cast(maybeDoc); + if ([query matchesDocument:doc]) { + results = results.insert(key, doc); + } + } + return results; +} + +std::vector MemoryRemoteDocumentCache::RemoveOrphanedDocuments( + FSTMemoryLRUReferenceDelegate* reference_delegate, + ListenSequenceNumber upper_bound) { + std::vector removed; + MaybeDocumentMap updated_docs = docs_; + for (const auto& kv : docs_) { + const DocumentKey& key = kv.first; + if (![reference_delegate isPinnedAtSequenceNumber:upper_bound + document:key]) { + updated_docs = updated_docs.erase(key); + removed.push_back(key); + } + } + docs_ = updated_docs; + return removed; +} + +size_t MemoryRemoteDocumentCache::CalculateByteSize( + FSTLocalSerializer* serializer) { + size_t count = 0; + for (const auto& kv : docs_) { + count += DocumentKeyByteSize(kv.first); + count += [[serializer encodedMaybeDocument:kv.second] serializedSize]; + } + return count; +} + +} // namespace local +} // namespace firestore +} // namespace firebase diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/mutation_queue.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/mutation_queue.h new file mode 100644 index 0000000..6977b73 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/mutation_queue.h @@ -0,0 +1,172 @@ +/* + * Copyright 2019 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_LOCAL_MUTATION_QUEUE_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_LOCAL_MUTATION_QUEUE_H_ + +#if !defined(__OBJC__) +#error "For now, this file must only be included by ObjC source files." +#endif // !defined(__OBJC__) + +#import + +#include + +#include "Firestore/core/src/firebase/firestore/model/document_key.h" +#include "Firestore/core/src/firebase/firestore/model/document_key_set.h" +#include "Firestore/core/src/firebase/firestore/model/types.h" + +@class FIRTimestamp; +@class FSTMutation; +@class FSTMutationBatch; +@class FSTQuery; + +NS_ASSUME_NONNULL_BEGIN + +namespace firebase { +namespace firestore { +namespace local { + +/** A queue of mutations to apply to the remote store. */ +class MutationQueue { + public: + virtual ~MutationQueue() { + } + + /** + * Starts the mutation queue, performing any initial reads that might be + * required to establish invariants, etc. + */ + virtual void Start() = 0; + + /** Returns true if this queue contains no mutation batches. */ + virtual bool IsEmpty() = 0; + + /** Acknowledges the given batch. */ + virtual void AcknowledgeBatch(FSTMutationBatch* batch, + NSData* _Nullable stream_token) = 0; + + /** + * Creates a new mutation batch and adds it to this mutation queue. + * + * @param local_write_time The original write time of this mutation. + * @param base_mutations Mutations that are used to populate the base values + * when this mutation is applied locally. These mutations are used to locally + * overwrite values that are persisted in the remote document cache. + * @param mutations The user-provided mutations in this mutation batch. + */ + virtual FSTMutationBatch* AddMutationBatch( + FIRTimestamp* local_write_time, + std::vector&& base_mutations, + std::vector&& mutations) = 0; + + /** + * Removes the given mutation batch from the queue. This is useful in two + * circumstances: + * + * + Removing applied mutations from the head of the queue + * + Removing rejected mutations from anywhere in the queue + */ + virtual void RemoveMutationBatch(FSTMutationBatch* batch) = 0; + + /** Gets all mutation batches in the mutation queue. */ + // TODO(mikelehen): PERF: Current consumer only needs mutated keys; if we can + // provide that cheaply, we should replace this. + virtual std::vector AllMutationBatches() = 0; + + /** + * Finds all mutation batches that could @em possibly affect the given + * document keys. Not all mutations in a batch will necessarily affect each + * key, so when looping through the batches you'll need to check that the + * mutation itself matches the key. + * + * Note that because of this requirement implementations are free to return + * mutation batches that don't contain any of the given document keys at all + * if it's convenient. + */ + // TODO(mcg): This should really return an iterator + virtual std::vector + AllMutationBatchesAffectingDocumentKeys( + const model::DocumentKeySet& document_keys) = 0; + + /** + * Finds all mutation batches that could @em possibly affect the given + * document key. Not all mutations in a batch will necessarily affect the + * document key, so when looping through the batch you'll need to check that + * the mutation itself matches the key. + * + * Note that because of this requirement implementations are free to return + * mutation batches that don't contain the document key at all if it's + * convenient. + */ + // TODO(mcg): This should really return an iterator + virtual std::vector AllMutationBatchesAffectingDocumentKey( + const model::DocumentKey& key) = 0; + + /** + * Finds all mutation batches that could affect the results for the given + * query. Not all mutations in a batch will necessarily affect the query, so + * when looping through the batch you'll need to check that the mutation + * itself matches the query. + * + * Note that because of this requirement implementations are free to return + * mutation batches that don't match the query at all if it's convenient. + * + * NOTE: A FSTPatchMutation does not need to include all fields in the query + * filter criteria in order to be a match (but any fields it does contain do + * need to match). + */ + // TODO(mikelehen): This should perhaps return an iterator, though I'm not + // sure we can avoid loading them all in memory. + virtual std::vector AllMutationBatchesAffectingQuery( + FSTQuery* query) = 0; + + /** Loads the mutation batch with the given batch_id. */ + virtual FSTMutationBatch* _Nullable LookupMutationBatch( + model::BatchId batch_id) = 0; + + /** + * Gets the first unacknowledged mutation batch after the passed in batchId in + * the mutation queue or nil if empty. + * + * @param batch_id The batch to search after, or kBatchIdUnknown for the first + * mutation in the queue. + * + * @return the next mutation or nil if there wasn't one. + */ + virtual FSTMutationBatch* _Nullable NextMutationBatchAfterBatchId( + model::BatchId batch_id) = 0; + + /** + * Performs a consistency check, examining the mutation queue for any leaks, + * if possible. + */ + virtual void PerformConsistencyCheck() = 0; + + /** Returns the current stream token for this mutation queue. */ + virtual NSData* _Nullable GetLastStreamToken() = 0; + + /** Sets the stream token for this mutation queue. */ + virtual void SetLastStreamToken(NSData* _Nullable stream_token) = 0; +}; + +} // namespace local +} // namespace firestore +} // namespace firebase + +NS_ASSUME_NONNULL_END + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_LOCAL_MUTATION_QUEUE_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/query_cache.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/query_cache.h new file mode 100644 index 0000000..75240ce --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/query_cache.h @@ -0,0 +1,161 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_LOCAL_QUERY_CACHE_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_LOCAL_QUERY_CACHE_H_ + +#if !defined(__OBJC__) +#error "For now, this file must only be included by ObjC source files." +#endif // !defined(__OBJC__) + +#import + +#include +#include + +#include "Firestore/core/src/firebase/firestore/model/document_key.h" +#include "Firestore/core/src/firebase/firestore/model/document_key_set.h" +#include "Firestore/core/src/firebase/firestore/model/snapshot_version.h" +#include "Firestore/core/src/firebase/firestore/model/types.h" + +@class FSTQuery; +@class FSTQueryData; + +NS_ASSUME_NONNULL_BEGIN + +namespace firebase { +namespace firestore { +namespace local { + +using OrphanedDocumentCallback = + std::function; + +using TargetCallback = std::function; + +/** + * Represents cached targets received from the remote backend. This contains + * both a mapping between targets and the documents that matched them according + * to the server, but also metadata about the targets. + * + * The cache is keyed by FSTQuery and entries in the cache are FSTQueryData + * instances. + */ +class QueryCache { + public: + virtual ~QueryCache() { + } + + // Target-related methods + + /** + * Adds an entry in the cache. + * + * The cache key is extracted from `queryData.query`. The key must not already + * exist in the cache. + * + * @param query_data A new FSTQueryData instance to put in the cache. + */ + virtual void AddTarget(FSTQueryData* query_data) = 0; + + /** + * Updates an entry in the cache. + * + * The cache key is extracted from `queryData.query`. The entry must already + * exist in the cache, and it will be replaced. + * @param query_data An FSTQueryData instance to replace an existing entry in + * the cache + */ + virtual void UpdateTarget(FSTQueryData* query_data) = 0; + + /** Removes the cached entry for the given query data. The entry must already + * exist in the cache. */ + virtual void RemoveTarget(FSTQueryData* query_data) = 0; + + /** + * Looks up an FSTQueryData entry in the cache. + * + * @param query The query corresponding to the entry to look up. + * @return The cached FSTQueryData entry, or nil if the cache has no entry for + * the query. + */ + virtual FSTQueryData* _Nullable GetTarget(FSTQuery* query) = 0; + + virtual void EnumerateTargets(const TargetCallback& callback) = 0; + + virtual int RemoveTargets( + model::ListenSequenceNumber upper_bound, + const std::unordered_map& + live_targets) = 0; + + // Key-related methods + virtual void AddMatchingKeys(const model::DocumentKeySet& keys, + model::TargetId target_id) = 0; + + virtual void RemoveMatchingKeys(const model::DocumentKeySet& keys, + model::TargetId target_id) = 0; + + virtual model::DocumentKeySet GetMatchingKeys(model::TargetId target_id) = 0; + + virtual bool Contains(const model::DocumentKey& key) = 0; + + // Accessors + + /** Returns the number of targets cached. */ + virtual size_t size() const = 0; + + /** + * Returns the highest listen sequence number of any query seen by the cache. + */ + virtual model::ListenSequenceNumber highest_listen_sequence_number() + const = 0; + + /** + * Returns the highest target ID of any query in the cache. Typically called + * during startup to seed a target ID generator and avoid collisions with + * existing queries. If there are no queries in the cache, returns zero. + */ + virtual model::TargetId highest_target_id() const = 0; + + /** + * A global snapshot version representing the last consistent snapshot we + * received from the backend. This is monotonically increasing and any + * snapshots received from the backend prior to this version (e.g. for targets + * resumed with a resume_token) should be suppressed (buffered) until the + * backend has caught up to this snapshot version again. This prevents our + * cache from ever going backwards in time. + * + * This is updated whenever our we get a TargetChange with a read_time and + * empty target_ids. + */ + virtual const model::SnapshotVersion& GetLastRemoteSnapshotVersion() + const = 0; + + /** + * Set the snapshot version representing the last consistent snapshot received + * from the backend. (see `GetLastRemoteSnapshotVersion()` for more details). + * + * @param version The new snapshot version. + */ + virtual void SetLastRemoteSnapshotVersion(model::SnapshotVersion version) = 0; +}; + +} // namespace local +} // namespace firestore +} // namespace firebase + +NS_ASSUME_NONNULL_END + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_LOCAL_QUERY_CACHE_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/query_data.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/query_data.cc new file mode 100644 index 0000000..0dc6ac5 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/query_data.cc @@ -0,0 +1,67 @@ +/* + * Copyright 2018 Google + * + * 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 "Firestore/core/src/firebase/firestore/local/query_data.h" + +#include + +namespace firebase { +namespace firestore { +namespace local { + +using core::Query; +using model::SnapshotVersion; + +QueryData::QueryData(Query&& query, + model::TargetId target_id, + model::ListenSequenceNumber sequence_number, + QueryPurpose purpose, + SnapshotVersion&& snapshot_version, + std::vector&& resume_token) + : query_(std::move(query)), + target_id_(target_id), + sequence_number_(sequence_number), + purpose_(purpose), + snapshot_version_(std::move(snapshot_version)), + resume_token_(std::move(resume_token)) { +} + +// TODO(rsgowman): Implement once WatchStream::EmptyResumeToken exists. +/* +QueryData::QueryData(const Query& query, int target_id, QueryPurpose purpose) + : QueryData(query, + target_id, + purpose, + model::SnapshotVersion::None(), + WatchStream::EmptyResumeToken()) { +} +*/ + +QueryData QueryData::Invalid() { + return QueryData(Query::Invalid(), /*target_id=*/-1, /*sequence_number=*/-1, + QueryPurpose::kListen, + SnapshotVersion(SnapshotVersion::None()), {}); +} + +QueryData QueryData::Copy(SnapshotVersion&& snapshot_version, + std::vector&& resume_token) const { + return QueryData(Query(query_), target_id_, sequence_number_, purpose_, + std::move(snapshot_version), std::move(resume_token)); +} + +} // namespace local +} // namespace firestore +} // namespace firebase diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/query_data.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/query_data.h new file mode 100644 index 0000000..0ec0883 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/query_data.h @@ -0,0 +1,136 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_LOCAL_QUERY_DATA_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_LOCAL_QUERY_DATA_H_ + +#include +#include + +#include "Firestore/core/src/firebase/firestore/core/query.h" +#include "Firestore/core/src/firebase/firestore/model/snapshot_version.h" +#include "Firestore/core/src/firebase/firestore/model/types.h" + +namespace firebase { +namespace firestore { +namespace local { + +/** An enumeration for the different purposes we have for queries. */ +enum class QueryPurpose { + /** A regular, normal query. */ + kListen, + + /** + * The query was used to refill a query after an existence filter mismatch. + */ + kExistenceFilterMismatch, + + /** The query was used to resolve a limbo document. */ + kLimboResolution, +}; + +/** + * An immutable set of metadata that the store will need to keep track of for + * each query. + */ +class QueryData { + public: + /** + * Creates a new QueryData with the given values. + * + * @param query The query being listened to. + * @param target_id The target to which the query corresponds, assigned by the + * LocalStore for user queries or the SyncEngine for limbo queries. + * @param purpose The purpose of the query. + * @param snapshot_version The latest snapshot version seen for this target. + * @param resume_token An opaque, server-assigned token that allows watching a + * query to be resumed after disconnecting without retransmitting all the + * data that matches the query. The resume token essentially identifies a + * point in time from which the server should resume sending results. + */ + QueryData(core::Query&& query, + model::TargetId target_id, + model::ListenSequenceNumber sequence_number, + QueryPurpose purpose, + model::SnapshotVersion&& snapshot_version, + std::vector&& resume_token); + + /** + * Convenience constructor for use when creating a QueryData for the first + * time. + */ + // TODO(rsgowman): Define once WatchStream::EmptyResumeToken exists. + // QueryData(const core::Query& query, int target_id, QueryPurpose purpose); + + /** + * Constructs an invalid QueryData. Reading any properties of the returned + * value is undefined. + */ + static QueryData Invalid(); + + const core::Query& query() const { + return query_; + } + + model::TargetId target_id() const { + return target_id_; + } + + model::ListenSequenceNumber sequence_number() const { + return sequence_number_; + } + + QueryPurpose purpose() const { + return purpose_; + } + + const model::SnapshotVersion& snapshot_version() const { + return snapshot_version_; + } + + const std::vector& resume_token() const { + return resume_token_; + } + + QueryData Copy(model::SnapshotVersion&& snapshot_version, + std::vector&& resume_token) const; + + private: + const core::Query query_; + model::TargetId target_id_; + model::ListenSequenceNumber sequence_number_; + QueryPurpose purpose_; + const model::SnapshotVersion snapshot_version_; + const std::vector resume_token_; +}; + +inline bool operator==(const QueryData& lhs, const QueryData& rhs) { + return lhs.query() == rhs.query() && lhs.target_id() == rhs.target_id() && + lhs.sequence_number() == rhs.sequence_number() && + lhs.purpose() == rhs.purpose() && + lhs.snapshot_version() == rhs.snapshot_version() && + lhs.resume_token() == rhs.resume_token(); +} + +inline bool operator!=(const QueryData& lhs, const QueryData& rhs) { + return !(lhs == rhs); +} + +} // namespace local +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_LOCAL_QUERY_DATA_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/reference_set.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/reference_set.cc new file mode 100644 index 0000000..57431d7 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/reference_set.cc @@ -0,0 +1,102 @@ +/* + * Copyright 2018 Google + * + * 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 "Firestore/core/src/firebase/firestore/local/reference_set.h" + +#include "Firestore/core/src/firebase/firestore/immutable/sorted_set.h" +#include "Firestore/core/src/firebase/firestore/local/document_key_reference.h" +#include "Firestore/core/src/firebase/firestore/model/document_key.h" + +namespace firebase { +namespace firestore { +namespace local { + +using model::DocumentKey; +using model::DocumentKeySet; + +void ReferenceSet::AddReference(const DocumentKey& key, int id) { + DocumentKeyReference reference{key, id}; + by_key_ = by_key_.insert(reference); + by_id_ = by_id_.insert(reference); +} + +void ReferenceSet::AddReferences(const DocumentKeySet& keys, int id) { + for (const DocumentKey& key : keys) { + AddReference(key, id); + } +} + +void ReferenceSet::RemoveReference(const DocumentKey& key, int id) { + RemoveReference(DocumentKeyReference{key, id}); +} + +void ReferenceSet::RemoveReferences( + const firebase::firestore::model::DocumentKeySet& keys, int id) { + for (const DocumentKey& key : keys) { + RemoveReference(key, id); + } +} + +DocumentKeySet ReferenceSet::RemoveReferences(int id) { + DocumentKeyReference start{DocumentKey::Empty(), id}; + DocumentKeyReference end{DocumentKey::Empty(), id + 1}; + + DocumentKeySet removed{}; + + auto initial = by_id_; + for (const auto& reference : initial.values_in(start, end)) { + RemoveReference(reference); + removed = removed.insert(reference.key()); + } + return removed; +} + +void ReferenceSet::RemoveAllReferences() { + auto initial = by_key_; + for (const DocumentKeyReference& reference : initial) { + RemoveReference(reference); + } +} + +void ReferenceSet::RemoveReference(const DocumentKeyReference& reference) { + by_key_ = by_key_.erase(reference); + by_id_ = by_id_.erase(reference); +} + +DocumentKeySet ReferenceSet::ReferencedKeys(int id) { + DocumentKeyReference start{DocumentKey::Empty(), id}; + DocumentKeyReference end{DocumentKey::Empty(), id + 1}; + + DocumentKeySet keys; + for (const auto& reference : by_id_.values_in(start, end)) { + keys = keys.insert(reference.key()); + } + return keys; +} + +bool ReferenceSet::ContainsKey(const DocumentKey& key) { + // Create a reference with a zero ID as the start position to find any + // document reference with this key. + DocumentKeyReference start{key, 0}; + + auto range = by_key_.values_from(start); + auto begin = range.begin(); + return begin != range.end() && begin->key() == key; +} + +} // namespace local +} // namespace firestore +} // namespace firebase diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/reference_set.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/reference_set.h new file mode 100644 index 0000000..0e14c99 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/reference_set.h @@ -0,0 +1,95 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_LOCAL_REFERENCE_SET_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_LOCAL_REFERENCE_SET_H_ + +#include "Firestore/core/src/firebase/firestore/immutable/sorted_set.h" +#include "Firestore/core/src/firebase/firestore/local/document_key_reference.h" +#include "Firestore/core/src/firebase/firestore/model/document_key.h" +#include "Firestore/core/src/firebase/firestore/model/document_key_set.h" + +namespace firebase { +namespace firestore { +namespace local { + +/** + * A collection of references to a document from some kind of numbered entity + * (either a TargetId or BatchId). As references are added to or removed from + * the set corresponding events are emitted to a registered garbage collector. + * + * Each reference is represented by a DocumentKeyReference object. Each of them + * contains enough information to uniquely identify the reference. They are all + * stored primarily in a set sorted by key. A document is considered garbage if + * there's no references in that set (this can be efficiently checked thanks to + * sorting by key). + * + * ReferenceSet also keeps a secondary set that contains references sorted by + * Id. This one is used to efficiently implement removal of all references by + * some TargetId. + */ +class ReferenceSet { + public: + /** Returns true if the reference set contains no references. */ + bool empty() const { + return by_key_.empty(); + } + + size_t size() const { + return by_key_.size(); + } + + /** Adds a reference to the given document key for the given Id. */ + void AddReference(const model::DocumentKey& key, int id); + + /** Add references to the given document keys for the given Id. */ + void AddReferences(const model::DocumentKeySet& keys, int id); + + /** Removes a reference to the given document key for the given Id. */ + void RemoveReference(const model::DocumentKey& key, int id); + + /** Removes references to the given document keys for the given Id. */ + void RemoveReferences(const model::DocumentKeySet& keys, int id); + + /** Clears all references with a given ID. Calls -removeReferenceToKey: for + * each key removed. */ + model::DocumentKeySet RemoveReferences(int id); + + /** Clears all references for all IDs. */ + void RemoveAllReferences(); + + /** Returns all of the document keys that have had references added for the + * given ID. */ + model::DocumentKeySet ReferencedKeys(int id); + + /** + * Checks to see if there are any references to a document with the given key. + */ + bool ContainsKey(const model::DocumentKey& key); + + private: + void RemoveReference(const DocumentKeyReference& reference); + + immutable::SortedSet + by_key_; + immutable::SortedSet by_id_; +}; + +} // namespace local +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_LOCAL_REFERENCE_SET_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/remote_document_cache.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/remote_document_cache.h new file mode 100644 index 0000000..f1ff54c --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/local/remote_document_cache.h @@ -0,0 +1,104 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_LOCAL_REMOTE_DOCUMENT_CACHE_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_LOCAL_REMOTE_DOCUMENT_CACHE_H_ + +#if !defined(__OBJC__) +#error "For now, this file must only be included by ObjC source files." +#endif // !defined(__OBJC__) + +#import + +#include "Firestore/core/src/firebase/firestore/model/document_key.h" +#include "Firestore/core/src/firebase/firestore/model/document_key_set.h" +#include "Firestore/core/src/firebase/firestore/model/document_map.h" +#include "Firestore/core/src/firebase/firestore/model/types.h" + +@class FSTMaybeDocument; +@class FSTQuery; + +NS_ASSUME_NONNULL_BEGIN + +namespace firebase { +namespace firestore { +namespace local { + +/** + * Represents cached documents received from the remote backend. + * + * The cache is keyed by DocumentKey and entries in the cache are + * FSTMaybeDocument instances, meaning we can cache both FSTDocument instances + * (an actual document with data) as well as FSTDeletedDocument instances + * (indicating that the document is known to not exist). + */ +class RemoteDocumentCache { + public: + virtual ~RemoteDocumentCache() { + } + + /** + * Adds or replaces an entry in the cache. + * + * The cache key is extracted from `document.key`. If there is already a cache + * entry for the key, it will be replaced. + * + * @param document A FSTDocument or FSTDeletedDocument to put in the cache. + */ + virtual void Add(FSTMaybeDocument* document) = 0; + + /** Removes the cached entry for the given key (no-op if no entry exists). */ + virtual void Remove(const model::DocumentKey& key) = 0; + + /** + * Looks up an entry in the cache. + * + * @param key The key of the entry to look up. + * @return The cached FSTDocument or FSTDeletedDocument entry, or nil if we + * have nothing cached. + */ + virtual FSTMaybeDocument* _Nullable Get(const model::DocumentKey& key) = 0; + + /** + * Looks up a set of entries in the cache. + * + * @param keys The keys of the entries to look up. + * @return The cached Document or NoDocument entries indexed by key. If an + * entry is not cached, the corresponding key will be mapped to a null value. + */ + virtual model::MaybeDocumentMap GetAll(const model::DocumentKeySet& keys) = 0; + + /** + * Executes a query against the cached FSTDocument entries + * + * Implementations may return extra documents if convenient. The results + * should be re-filtered by the consumer before presenting them to the user. + * + * Cached FSTDeletedDocument entries have no bearing on query results. + * + * @param query The query to match documents against. + * @return The set of matching documents. + */ + virtual model::DocumentMap GetMatching(FSTQuery* query) = 0; +}; + +} // namespace local +} // namespace firestore +} // namespace firebase + +NS_ASSUME_NONNULL_END + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_LOCAL_REMOTE_DOCUMENT_CACHE_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/base_path.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/base_path.h new file mode 100644 index 0000000..31aaebb --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/base_path.h @@ -0,0 +1,190 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_MODEL_BASE_PATH_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_MODEL_BASE_PATH_H_ + +#include +#include +#include +#include +#include +#include + +#include "Firestore/core/src/firebase/firestore/util/hard_assert.h" +#include "Firestore/core/src/firebase/firestore/util/hashing.h" + +namespace firebase { +namespace firestore { +namespace model { +namespace impl { + +/** + * BasePath represents a path sequence in the Firestore database. It is composed + * of an ordered sequence of string segments. + * + * BasePath is reassignable and movable. Apart from those, all other mutating + * operations return new independent instances. + * + * ## Subclassing Notes + * + * BasePath is strictly meant as a base class for concrete implementations. It + * doesn't contain a single virtual method, can't be instantiated, and should + * never be used in any polymorphic way. BasePath is templated to allow static + * factory methods to return objects of the derived class (the expected + * inheritance would use CRTP: struct Derived : BasePath). + */ +template +class BasePath { + protected: + using SegmentsT = std::vector; + + public: + using const_iterator = SegmentsT::const_iterator; + + /** Returns i-th segment of the path. */ + const std::string& operator[](const size_t i) const { + HARD_ASSERT(i < segments_.size(), "index %s out of range", i); + return segments_[i]; + } + + /** Returns the first segment of the path. */ + const std::string& first_segment() const { + HARD_ASSERT(!empty(), "Cannot call first_segment on empty path"); + return segments_[0]; + } + /** Returns the last segment of the path. */ + const std::string& last_segment() const { + HARD_ASSERT(!empty(), "Cannot call last_segment on empty path"); + return segments_[size() - 1]; + } + + size_t size() const { + return segments_.size(); + } + bool empty() const { + return segments_.empty(); + } + + const_iterator begin() const { + return segments_.begin(); + } + const_iterator end() const { + return segments_.end(); + } + + /** + * Returns a new path which is the result of concatenating this path with an + * additional segment. + */ + T Append(const std::string& segment) const { + auto appended = segments_; + appended.push_back(segment); + return T{std::move(appended)}; + } + T Append(std::string&& segment) const { + auto appended = segments_; + appended.push_back(std::move(segment)); + return T{std::move(appended)}; + } + + /** + * Returns a new path which is the result of concatenating this path with an + * another path. + */ + T Append(const T& path) const { + auto appended = segments_; + appended.insert(appended.end(), path.begin(), path.end()); + return T{std::move(appended)}; + } + + /** + * Returns a new path which is the result of omitting the first n segments of + * this path. + */ + T PopFirst(const size_t n = 1) const { + HARD_ASSERT(n <= size(), "Cannot call PopFirst(%s) on path of length %s", n, + size()); + return T{begin() + n, end()}; + } + + /** + * Returns a new path which is the result of omitting the last segment of + * this path. + */ + T PopLast() const { + HARD_ASSERT(!empty(), "Cannot call PopLast() on empty path"); + return T{begin(), end() - 1}; + } + + /** + * Returns true if this path is a prefix of the given path. + * + * Empty path is a prefix of any path. Any path is a prefix of itself. + */ + bool IsPrefixOf(const T& rhs) const { + return size() <= rhs.size() && std::equal(begin(), end(), rhs.begin()); + } + + /** + * Returns true if the given argument is a direct child of this path. + * + * Empty path is a parent of any path that consists of a single segment. + */ + bool IsImmediateParentOf(const T& potential_child) const { + return size() + 1 == potential_child.size() && + std::equal(begin(), end(), potential_child.begin()); + } + + bool operator==(const BasePath& rhs) const { + return segments_ == rhs.segments_; + } + bool operator!=(const BasePath& rhs) const { + return segments_ != rhs.segments_; + } + bool operator<(const BasePath& rhs) const { + return segments_ < rhs.segments_; + } + bool operator>(const BasePath& rhs) const { + return segments_ > rhs.segments_; + } + bool operator<=(const BasePath& rhs) const { + return segments_ <= rhs.segments_; + } + bool operator>=(const BasePath& rhs) const { + return segments_ >= rhs.segments_; + } + + protected: + BasePath() = default; + template + BasePath(const IterT begin, const IterT end) : segments_{begin, end} { + } + BasePath(std::initializer_list list) : segments_{list} { + } + explicit BasePath(SegmentsT&& segments) : segments_{std::move(segments)} { + } + + private: + SegmentsT segments_; +}; + +} // namespace impl +} // namespace model +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_MODEL_BASE_PATH_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/database_id.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/database_id.cc new file mode 100644 index 0000000..9fe7bb3 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/database_id.cc @@ -0,0 +1,37 @@ +/* + * Copyright 2018 Google + * + * 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 "Firestore/core/src/firebase/firestore/model/database_id.h" + +#include + +#include "Firestore/core/src/firebase/firestore/util/hard_assert.h" + +namespace firebase { +namespace firestore { +namespace model { + +constexpr const char* DatabaseId::kDefault; + +DatabaseId::DatabaseId(std::string project_id, std::string database_id) + : project_id_{std::move(project_id)}, database_id_{std::move(database_id)} { + HARD_ASSERT(!project_id_.empty()); + HARD_ASSERT(!database_id_.empty()); +} + +} // namespace model +} // namespace firestore +} // namespace firebase diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/database_id.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/database_id.h new file mode 100644 index 0000000..c7f66d1 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/database_id.h @@ -0,0 +1,109 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_MODEL_DATABASE_ID_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_MODEL_DATABASE_ID_H_ + +#include +#include + +#include "Firestore/core/src/firebase/firestore/util/hashing.h" +#include "absl/strings/string_view.h" + +namespace firebase { +namespace firestore { +namespace model { + +/** A DatabaseId represents a particular database in the Firestore. */ +class DatabaseId { + public: + /** The default name for "unset" database ID in resource names. */ + static constexpr const char* kDefault = "(default)"; + +#if defined(__OBJC__) + // For objective-c++ initialization; to be removed after migration. + // Do NOT use in C++ code. + DatabaseId() = default; +#endif // defined(__OBJC__) + + /** + * Creates and returns a new DatabaseId. + * + * @param project_id The project for the database. + * @param database_id The database in the project to use. + */ + DatabaseId(std::string project_id, std::string database_id); + + const std::string& project_id() const { + return project_id_; + } + + const std::string& database_id() const { + return database_id_; + } + + /** Whether this is the default database of the project. */ + bool IsDefaultDatabase() const { + return database_id_ == kDefault; + } + +#if defined(__OBJC__) + // For objective-c++ hash; to be removed after migration. + // Do NOT use in C++ code. + size_t Hash() const { + return util::Hash(project_id_, database_id_); + } +#endif // defined(__OBJC__) + + friend bool operator<(const DatabaseId& lhs, const DatabaseId& rhs); + + private: + std::string project_id_; + std::string database_id_; +}; + +/** Compares against another DatabaseId. */ +inline bool operator<(const DatabaseId& lhs, const DatabaseId& rhs) { + return lhs.project_id_ < rhs.project_id_ || + (lhs.project_id_ == rhs.project_id_ && + lhs.database_id_ < rhs.database_id_); +} + +inline bool operator>(const DatabaseId& lhs, const DatabaseId& rhs) { + return rhs < lhs; +} + +inline bool operator>=(const DatabaseId& lhs, const DatabaseId& rhs) { + return !(lhs < rhs); +} + +inline bool operator<=(const DatabaseId& lhs, const DatabaseId& rhs) { + return !(lhs > rhs); +} + +inline bool operator!=(const DatabaseId& lhs, const DatabaseId& rhs) { + return lhs < rhs || lhs > rhs; +} + +inline bool operator==(const DatabaseId& lhs, const DatabaseId& rhs) { + return !(lhs != rhs); +} + +} // namespace model +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_MODEL_DATABASE_ID_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/document.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/document.cc new file mode 100644 index 0000000..da540c8 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/document.cc @@ -0,0 +1,49 @@ +/* + * Copyright 2018 Google + * + * 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 "Firestore/core/src/firebase/firestore/model/document.h" + +#include + +#include "Firestore/core/src/firebase/firestore/util/hard_assert.h" + +namespace firebase { +namespace firestore { +namespace model { + +Document::Document(ObjectValue&& data, + DocumentKey key, + SnapshotVersion version, + DocumentState document_state) + : MaybeDocument(std::move(key), std::move(version)), + data_(std::move(data)), + document_state_(document_state) { + set_type(Type::Document); +} + +bool Document::Equals(const MaybeDocument& other) const { + if (other.type() != Type::Document) { + return false; + } + auto& other_doc = static_cast(other); + return MaybeDocument::Equals(other) && + document_state_ == other_doc.document_state_ && + data_ == other_doc.data_; +} + +} // namespace model +} // namespace firestore +} // namespace firebase diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/document.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/document.h new file mode 100644 index 0000000..acd0421 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/document.h @@ -0,0 +1,103 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_MODEL_DOCUMENT_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_MODEL_DOCUMENT_H_ + +#include "Firestore/core/src/firebase/firestore/model/field_path.h" +#include "Firestore/core/src/firebase/firestore/model/field_value.h" +#include "Firestore/core/src/firebase/firestore/model/maybe_document.h" +#include "absl/types/optional.h" + +namespace firebase { +namespace firestore { +namespace model { + +enum class DocumentState { + /** + * Local mutations applied via the mutation queue. Document is potentially + * inconsistent. + */ + kLocalMutations, + + /** + * Mutations applied based on a write acknowledgment. Document is potentially + * inconsistent. + */ + kCommittedMutations, + + /** No mutations applied. Document was sent to us by Watch. */ + kSynced, +}; + +/** + * Represents a document in Firestore with a key, version, data and whether the + * data has local mutations applied to it. + */ +class Document : public MaybeDocument { + public: + /** + * Construct a document. ObjectValue must be passed by rvalue. + */ + Document(ObjectValue&& data, + DocumentKey key, + SnapshotVersion version, + DocumentState document_state); + + const ObjectValue& data() const { + return data_; + } + + absl::optional field(const FieldPath& path) const { + return data_.Get(path); + } + + bool HasLocalMutations() const { + return document_state_ == DocumentState::kLocalMutations; + } + + bool HasCommittedMutations() const { + return document_state_ == DocumentState::kCommittedMutations; + } + + bool HasPendingWrites() const override { + return HasLocalMutations() || HasCommittedMutations(); + } + + protected: + bool Equals(const MaybeDocument& other) const override; + + private: + ObjectValue data_; + DocumentState document_state_; +}; + +/** Compares against another Document. */ +inline bool operator==(const Document& lhs, const Document& rhs) { + return lhs.version() == rhs.version() && lhs.key() == rhs.key() && + lhs.HasLocalMutations() == rhs.HasLocalMutations() && + lhs.data() == rhs.data(); +} + +inline bool operator!=(const Document& lhs, const Document& rhs) { + return !(lhs == rhs); +} + +} // namespace model +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_MODEL_DOCUMENT_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/document_key.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/document_key.cc new file mode 100644 index 0000000..7dae412 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/document_key.cc @@ -0,0 +1,53 @@ +/* + * Copyright 2018 Google + * + * 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 "Firestore/core/src/firebase/firestore/model/document_key.h" + +#include + +#include "Firestore/core/src/firebase/firestore/util/hard_assert.h" + +namespace firebase { +namespace firestore { +namespace model { + +namespace { + +void AssertValidPath(const ResourcePath& path) { + HARD_ASSERT(DocumentKey::IsDocumentKey(path), "invalid document key path: %s", + path.CanonicalString()); +} + +} // namespace + +DocumentKey::DocumentKey(const ResourcePath& path) + : path_{std::make_shared(path)} { + AssertValidPath(*path_); +} + +DocumentKey::DocumentKey(ResourcePath&& path) + : path_{std::make_shared(std::move(path))} { + AssertValidPath(*path_); +} + +const DocumentKey& DocumentKey::Empty() { + static const DocumentKey empty; + return empty; +} + +} // namespace model +} // namespace firestore +} // namespace firebase diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/document_key.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/document_key.h new file mode 100644 index 0000000..2443e26 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/document_key.h @@ -0,0 +1,151 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_MODEL_DOCUMENT_KEY_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_MODEL_DOCUMENT_KEY_H_ + +#include +#include +#include +#include + +#if defined(__OBJC__) +#import "Firestore/Source/Model/FSTDocumentKey.h" +#endif // defined(__OBJC__) + +#include "Firestore/core/src/firebase/firestore/model/resource_path.h" +#include "Firestore/core/src/firebase/firestore/util/comparison.h" +#include "Firestore/core/src/firebase/firestore/util/hashing.h" +#include "absl/strings/string_view.h" + +namespace firebase { +namespace firestore { +namespace model { + +/** + * DocumentKey represents the location of a document in the Firestore database. + */ +class DocumentKey { + public: + /** Creates a "blank" document key not associated with any document. */ + DocumentKey() : path_{std::make_shared()} { + } + + /** Creates a new document key containing a copy of the given path. */ + explicit DocumentKey(const ResourcePath& path); + + /** Creates a new document key, taking ownership of the given path. */ + explicit DocumentKey(ResourcePath&& path); + +#if defined(__OBJC__) + NSUInteger Hash() const { + return util::Hash(ToString()); + } +#endif // defined(__OBJC__) + + std::string ToString() const { + return path().CanonicalString(); + } + + /** + * Creates and returns a new document key using '/' to split the string into + * segments. + */ + static DocumentKey FromPathString(absl::string_view path) { + return DocumentKey{ResourcePath::FromString(path)}; + } + + /** Creates and returns a new document key with the given segments. */ + static DocumentKey FromSegments(std::initializer_list list) { + return DocumentKey{ResourcePath{list}}; + } + + /** Returns a shared instance of an empty document key. */ + static const DocumentKey& Empty(); + + /** Returns true iff the given path is a path to a document. */ + static bool IsDocumentKey(const ResourcePath& path) { + return path.size() % 2 == 0; + } + + /** The path to the document. */ + const ResourcePath& path() const { + return path_ ? *path_ : Empty().path(); + } + + /** Returns true if the document is in the specified collectionId. */ + bool HasCollectionId(absl::string_view collection_id) const { + size_t size = path().size(); + return size >= 2 && path()[size - 2] == collection_id; + } + + private: + // This is an optimization to make passing DocumentKey around cheaper (it's + // copied often). + std::shared_ptr path_; +}; + +inline bool operator==(const DocumentKey& lhs, const DocumentKey& rhs) { + return lhs.path() == rhs.path(); +} +inline bool operator!=(const DocumentKey& lhs, const DocumentKey& rhs) { + return lhs.path() != rhs.path(); +} +inline bool operator<(const DocumentKey& lhs, const DocumentKey& rhs) { + return lhs.path() < rhs.path(); +} +inline bool operator<=(const DocumentKey& lhs, const DocumentKey& rhs) { + return lhs.path() <= rhs.path(); +} +inline bool operator>(const DocumentKey& lhs, const DocumentKey& rhs) { + return lhs.path() > rhs.path(); +} +inline bool operator>=(const DocumentKey& lhs, const DocumentKey& rhs) { + return lhs.path() >= rhs.path(); +} + +struct DocumentKeyHash { + size_t operator()(const DocumentKey& key) const { + return util::Hash(key.path()); + } +}; + +#if defined(__OBJC__) +inline NSComparisonResult CompareKeys(const DocumentKey& lhs, + const DocumentKey& rhs) { + if (lhs < rhs) { + return NSOrderedAscending; + } + if (lhs > rhs) { + return NSOrderedDescending; + } + return NSOrderedSame; +} + +#endif // defined(__OBJC__) + +} // namespace model + +namespace util { + +template <> +struct Comparator : public std::less {}; + +} // namespace util +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_MODEL_DOCUMENT_KEY_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/document_key_set.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/document_key_set.h new file mode 100644 index 0000000..1301bf5 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/document_key_set.h @@ -0,0 +1,34 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_MODEL_DOCUMENT_KEY_SET_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_MODEL_DOCUMENT_KEY_SET_H_ + +#include "Firestore/core/src/firebase/firestore/immutable/sorted_set.h" +#include "Firestore/core/src/firebase/firestore/model/document_key.h" + +namespace firebase { +namespace firestore { +namespace model { + +/** Convenience type for a set of keys, since they are so common. */ +using DocumentKeySet = immutable::SortedSet; + +} // namespace model +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_MODEL_DOCUMENT_KEY_SET_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/document_map.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/document_map.h new file mode 100644 index 0000000..59ae69f --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/document_map.h @@ -0,0 +1,103 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_MODEL_DOCUMENT_MAP_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_MODEL_DOCUMENT_MAP_H_ + +#include + +#import "Firestore/Source/Model/FSTDocument.h" + +#include "Firestore/core/src/firebase/firestore/immutable/sorted_map.h" +#include "Firestore/core/src/firebase/firestore/model/document_key.h" + +#include "absl/base/attributes.h" + +namespace firebase { +namespace firestore { +namespace model { + +/** + * Convenience type for a map of keys to MaybeDocuments, since they are so + * common. + */ +using MaybeDocumentMap = immutable::SortedMap; + +/** + * Convenience type for a map of keys to Documents, since they are so common. + * + * PORTING NOTE: unlike other platforms, in C++ `Foo` cannot be + * converted to `Foo`; consequently, if `DocumentMap` were simply an + * alias similar to `MaybeDocumentMap`, it couldn't be passed to functions + * expecting `MaybeDocumentMap`. + * + * To work around this, in C++ `DocumentMap` is a simple wrapper over + * a `MaybeDocumentMap` that forwards all functions to the underlying map but + * with added type safety (it only accepts `FSTDocument`s, not + * `FSTMaybeDocument`s). Use `DocumentMap` in functions creating and/or + * returning maps that only contain `FSTDocument`s; when the `DocumentMap` needs + * to be passed to a function accepting a `MaybeDocumentMap`, use + * `underlying_map` function to get (read-only) access to the representation. + * Also use `underlying_map` for iterating and searching. + */ +class DocumentMap { + public: + DocumentMap() = default; + + ABSL_MUST_USE_RESULT DocumentMap insert(const DocumentKey& key, + FSTDocument* value) const { + return DocumentMap{map_.insert(key, value)}; + } + + ABSL_MUST_USE_RESULT DocumentMap erase(const DocumentKey& key) const { + return DocumentMap{map_.erase(key)}; + } + + bool empty() const { + return map_.empty(); + } + MaybeDocumentMap::size_type size() const { + return map_.size(); + } + + /** Use this function to "convert" `DocumentMap` to a `MaybeDocumentMap`. */ + const MaybeDocumentMap& underlying_map() const { + return map_; + } + + private: + explicit DocumentMap(MaybeDocumentMap&& map) : map_{std::move(map)} { + } + + MaybeDocumentMap map_; +}; + +inline FSTDocument* GetFSTDocumentOrNil(FSTMaybeDocument* maybeDoc) { + if ([maybeDoc isKindOfClass:[FSTDocument class]]) { + return static_cast(maybeDoc); + } + return nil; +} + +inline FSTDocument* GetFSTDocumentOrNil(FSTDocument* doc) { + return doc; +} + +} // namespace model +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_MODEL_DOCUMENT_MAP_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/document_set.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/document_set.h new file mode 100644 index 0000000..003f105 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/document_set.h @@ -0,0 +1,174 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_MODEL_DOCUMENT_SET_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_MODEL_DOCUMENT_SET_H_ + +#if !defined(__OBJC__) +#error "This header only supports Objective-C++" +#endif // !defined(__OBJC__) + +#import + +#include +#include +#include +#include + +#include "Firestore/core/src/firebase/firestore/immutable/sorted_container.h" +#include "Firestore/core/src/firebase/firestore/immutable/sorted_set.h" +#include "Firestore/core/src/firebase/firestore/model/document_key.h" +#include "Firestore/core/src/firebase/firestore/model/document_map.h" +#include "Firestore/core/src/firebase/firestore/util/comparison.h" + +@class FSTDocument; + +NS_ASSUME_NONNULL_BEGIN + +namespace firebase { +namespace firestore { +namespace model { + +/** + * A C++ comparator that returns less-than, implemented by delegating to + * an NSComparator. + */ +class DocumentSetComparator { + public: + explicit DocumentSetComparator(NSComparator delegate = nil) + : delegate_(delegate) { + } + + bool operator()(FSTDocument* lhs, FSTDocument* rhs) const { + return delegate_(lhs, rhs) == NSOrderedAscending; + } + + private: + NSComparator delegate_; +}; + +/** + * DocumentSet is an immutable (copy-on-write) collection that holds documents + * in order specified by the provided comparator. We always add a document key + * comparator on top of what is provided to guarantee document equality based on + * the key. + */ +class DocumentSet : public immutable::SortedContainer, + public util::Equatable { + public: + /** + * The type of the main collection of documents in an DocumentSet. + * @see sorted_set_. + */ + using SetType = immutable::SortedSet; + + // STL container types + using value_type = FSTDocument*; + using const_iterator = SetType::const_iterator; + + /** + * Creates a new, empty DocumentSet sorted by the given comparator, then by + * keys. + */ + explicit DocumentSet(NSComparator comparator); + + size_t size() const { + return index_.size(); + } + + /** Returns true if the dictionary contains no elements. */ + bool empty() const { + return index_.empty(); + } + + /** Returns true if this set contains a document with the given key. */ + bool ContainsKey(const DocumentKey& key) const; + + SetType::const_iterator begin() const { + return sorted_set_.begin(); + } + SetType::const_iterator end() const { + return sorted_set_.end(); + } + + /** + * Returns the document from this set with the given key if it exists or nil + * if it doesn't. + */ + FSTDocument* _Nullable GetDocument(const DocumentKey& key) const; + + /** + * Returns the first document in the set according to its built in ordering, + * or nil if the set is empty. + */ + FSTDocument* _Nullable GetFirstDocument() const; + + /** + * Returns the last document in the set according to its built in ordering, or + * nil if the set is empty. + */ + FSTDocument* _Nullable GetLastDocument() const; + + /** + * Returns the index of the document with the provided key in the document + * set. Returns `npos` if the key is not present. + */ + size_t IndexOf(const DocumentKey& key) const; + + /** Returns a new DocumentSet that contains the given document. */ + DocumentSet insert(FSTDocument* _Nullable document) const; + + /** + * Returns a new DocumentSet that excludes any document associated with + * the given key. + */ + DocumentSet erase(const DocumentKey& key) const; + + friend bool operator==(const DocumentSet& lhs, const DocumentSet& rhs); + + std::string ToString() const; + friend std::ostream& operator<<(std::ostream& os, const DocumentSet& set); + + size_t Hash() const; + + private: + DocumentSet(DocumentMap&& index, SetType&& sorted_set) + : index_(std::move(index)), sorted_set_(std::move(sorted_set)) { + } + + /** + * An index of the documents in the DocumentSet, indexed by document key. + * The index exists to guarantee the uniqueness of document keys in the set + * and to allow lookup and removal of documents by key. + */ + DocumentMap index_; + + /** + * The main collection of documents in the DocumentSet. The documents are + * ordered by a comparator supplied from a query. The SetType collection + * exists in addition to the index to allow ordered traversal of the + * DocumentSet. + */ + SetType sorted_set_; +}; + +} // namespace model +} // namespace firestore +} // namespace firebase + +NS_ASSUME_NONNULL_END + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_MODEL_DOCUMENT_SET_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/document_set.mm b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/document_set.mm new file mode 100644 index 0000000..47cb3d2 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/document_set.mm @@ -0,0 +1,121 @@ +/* + * Copyright 2017 Google + * + * 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 "Firestore/core/src/firebase/firestore/model/document_set.h" + +#include +#include + +#import "Firestore/Source/Model/FSTDocument.h" + +#include "Firestore/core/src/firebase/firestore/immutable/sorted_set.h" +#include "Firestore/core/src/firebase/firestore/model/document_key.h" +#include "Firestore/core/src/firebase/firestore/util/objc_compatibility.h" +#include "absl/algorithm/container.h" + +NS_ASSUME_NONNULL_BEGIN + +namespace firebase { +namespace firestore { +namespace model { + +namespace objc = util::objc; +using immutable::SortedSet; + +DocumentSet::DocumentSet(NSComparator comparator) + : index_{}, sorted_set_{DocumentSetComparator{comparator}} { +} + +bool operator==(const DocumentSet& lhs, const DocumentSet& rhs) { + return absl::c_equal(lhs.sorted_set_, rhs.sorted_set_, + [](FSTDocument* left_doc, FSTDocument* right_doc) { + return [left_doc isEqual:right_doc]; + }); +} + +std::string DocumentSet::ToString() const { + return util::ToString(sorted_set_); +} + +std::ostream& operator<<(std::ostream& os, const DocumentSet& set) { + return os << set.ToString(); +} + +size_t DocumentSet::Hash() const { + size_t hash = 0; + for (FSTDocument* doc : sorted_set_) { + hash = 31 * hash + [doc hash]; + } + return hash; +} + +bool DocumentSet::ContainsKey(const DocumentKey& key) const { + return index_.underlying_map().find(key) != index_.underlying_map().end(); +} + +FSTDocument* _Nullable DocumentSet::GetDocument(const DocumentKey& key) const { + auto found = index_.underlying_map().find(key); + return found != index_.underlying_map().end() + ? static_cast(found->second) + : nil; +} + +FSTDocument* _Nullable DocumentSet::GetFirstDocument() const { + auto result = sorted_set_.min(); + return result != sorted_set_.end() ? *result : nil; +} + +FSTDocument* _Nullable DocumentSet::GetLastDocument() const { + auto result = sorted_set_.max(); + return result != sorted_set_.end() ? *result : nil; +} + +size_t DocumentSet::IndexOf(const DocumentKey& key) const { + FSTDocument* doc = GetDocument(key); + return doc ? sorted_set_.find_index(doc) : npos; +} + +DocumentSet DocumentSet::insert(FSTDocument* _Nullable document) const { + // TODO(mcg): look into making document nonnull. + if (!document) { + return *this; + } + + // Remove any prior mapping of the document's key before adding, preventing + // sortedSet from accumulating values that aren't in the index. + DocumentSet removed = erase(document.key); + + DocumentMap index = removed.index_.insert(document.key, document); + SetType set = removed.sorted_set_.insert(document); + return {std::move(index), std::move(set)}; +} + +DocumentSet DocumentSet::erase(const DocumentKey& key) const { + FSTDocument* doc = GetDocument(key); + if (!doc) { + return *this; + } + + DocumentMap index = index_.erase(key); + SetType set = sorted_set_.erase(doc); + return {std::move(index), std::move(set)}; +} + +} // namespace model +} // namespace firestore +} // namespace firebase + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/field_mask.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/field_mask.h new file mode 100644 index 0000000..d8cdfba --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/field_mask.h @@ -0,0 +1,117 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_MODEL_FIELD_MASK_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_MODEL_FIELD_MASK_H_ + +#include +#include +#include +#include + +#include "Firestore/core/src/firebase/firestore/model/field_path.h" +#include "Firestore/core/src/firebase/firestore/util/hashing.h" + +namespace firebase { +namespace firestore { +namespace model { + +/** + * Provides a set of fields that can be used to partially patch a document. + * FieldMask is used in conjunction with FieldValue of Object type. + * + * Examples: + * foo - Overwrites foo entirely with the provided value. If foo is not + * present in the companion FieldValue, the field is deleted. + * foo.bar - Overwrites only the field bar of the object foo. If foo is not an + * object, foo is replaced with an object containing bar. + */ +class FieldMask { + public: + using const_iterator = std::set::const_iterator; + + FieldMask(std::initializer_list list) : fields_{list} { + } + template + FieldMask(InputIt first, InputIt last) : fields_{first, last} { + } + explicit FieldMask(std::set fields) : fields_{std::move(fields)} { + } + + FieldMask(const FieldMask& f) : fields_{f.begin(), f.end()} { + } + + const_iterator begin() const { + return fields_.begin(); + } + const_iterator end() const { + return fields_.end(); + } + + size_t size() const { + return fields_.size(); + } + + /** + * Verifies that `fieldPath` is included by at least one field in this field + * mask. + * + * This is an O(n) operation, where `n` is the size of the field mask. + */ + bool covers(const FieldPath& fieldPath) const { + for (const FieldPath& fieldMaskPath : fields_) { + if (fieldMaskPath.IsPrefixOf(fieldPath)) { + return true; + } + } + + return false; + } + + std::string ToString() const { + // Ideally, one should use a string builder. Since this is only non-critical + // code for logging and debugging, the logic is kept simple here. + std::string result("{ "); + for (const FieldPath& field : fields_) { + result += field.CanonicalString() + " "; + } + return result + "}"; + } + +#if defined(__OBJC__) + FieldMask() { + } + + NSUInteger Hash() const { + return util::Hash(fields_); + } +#endif + + friend bool operator==(const FieldMask& lhs, const FieldMask& rhs); + + private: + std::set fields_; +}; + +inline bool operator==(const FieldMask& lhs, const FieldMask& rhs) { + return lhs.fields_ == rhs.fields_; +} + +} // namespace model +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_MODEL_FIELD_MASK_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/field_path.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/field_path.cc new file mode 100644 index 0000000..b1dcad7 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/field_path.cc @@ -0,0 +1,161 @@ +/* + * Copyright 2018 Google + * + * 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 "Firestore/core/src/firebase/firestore/model/field_path.h" + +#include +#include + +#include "Firestore/core/src/firebase/firestore/util/hard_assert.h" +#include "absl/strings/str_join.h" +#include "absl/strings/str_replace.h" +#include "absl/strings/str_split.h" + +namespace firebase { +namespace firestore { +namespace model { + +namespace { + +/** + * True if the string could be used as a segment in a field path without + * escaping. Valid identifies follow the regex [a-zA-Z_][a-zA-Z0-9_]* + */ +bool IsValidIdentifier(const std::string& segment) { + if (segment.empty()) { + return false; + } + + // Note: strictly speaking, only digits are guaranteed by the Standard to + // be a contiguous range, while alphabetic characters may have gaps. Ignoring + // this peculiarity, because it doesn't affect the platforms that Firestore + // supports. + const unsigned char first = segment.front(); + if (first != '_' && (first < 'a' || first > 'z') && + (first < 'A' || first > 'Z')) { + return false; + } + for (size_t i = 1; i != segment.size(); ++i) { + const unsigned char c = segment[i]; + if (c != '_' && (c < 'a' || c > 'z') && (c < 'A' || c > 'Z') && + (c < '0' || c > '9')) { + return false; + } + } + + return true; +} + +/** A custom formatter to be used with absl::StrJoin(). */ +struct JoinEscaped { + static std::string escaped_segment(const std::string& segment) { + auto escaped = absl::StrReplaceAll(segment, {{"\\", "\\\\"}, {"`", "\\`"}}); + const bool needs_escaping = !IsValidIdentifier(escaped); + if (needs_escaping) { + escaped.insert(escaped.begin(), '`'); + escaped.push_back('`'); + } + return escaped; + } + + template + void operator()(T* out, const std::string& segment) { + out->append(escaped_segment(segment)); + } +}; +} // namespace + +FieldPath FieldPath::FromServerFormat(const absl::string_view path) { + SegmentsT segments; + std::string segment; + segment.reserve(path.size()); + + const auto finish_segment = [&segments, &segment, &path] { + HARD_ASSERT(!segment.empty(), + "Invalid field path (%s). Paths must not be empty, begin with " + "'.', end with '.', or contain '..'", + path); + // Move operation will clear segment, but capacity will remain the same + // (not, strictly speaking, required by the standard, but true in practice). + segments.push_back(std::move(segment)); + }; + + // Inside backticks, dots are treated literally. + bool inside_backticks = false; + size_t i = 0; + while (i < path.size()) { + const char c = path[i]; + // std::string (and string_view) may contain embedded nulls. For full + // compatibility with Objective C behavior, finish upon encountering the + // first terminating null. + if (c == '\0') { + break; + } + + switch (c) { + case '.': + if (!inside_backticks) { + finish_segment(); + } else { + segment += c; + } + break; + + case '`': + inside_backticks = !inside_backticks; + break; + + case '\\': + HARD_ASSERT(i + 1 != path.size(), + "Trailing escape characters not allowed in %s", path); + ++i; + segment += path[i]; + break; + + default: + segment += c; + break; + } + ++i; + } + finish_segment(); + + HARD_ASSERT(!inside_backticks, "Unterminated ` in path %s", path); + + return FieldPath{std::move(segments)}; +} + +const FieldPath& FieldPath::EmptyPath() { + static const FieldPath empty_path; + return empty_path; +} + +const FieldPath& FieldPath::KeyFieldPath() { + static const FieldPath key_field_path{FieldPath::kDocumentKeyPath}; + return key_field_path; +} + +bool FieldPath::IsKeyFieldPath() const { + return size() == 1 && first_segment() == FieldPath::kDocumentKeyPath; +} + +std::string FieldPath::CanonicalString() const { + return absl::StrJoin(begin(), end(), ".", JoinEscaped()); +} + +} // namespace model +} // namespace firestore +} // namespace firebase diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/field_path.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/field_path.h new file mode 100644 index 0000000..ce3527d --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/field_path.h @@ -0,0 +1,94 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_MODEL_FIELD_PATH_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_MODEL_FIELD_PATH_H_ + +#include +#include +#include + +#include "Firestore/core/src/firebase/firestore/model/base_path.h" +#include "absl/strings/string_view.h" + +namespace firebase { +namespace firestore { +namespace model { + +/** + * A dot-separated path for navigating sub-objects within a document. + * + * Immutable; all instances are fully independent. + */ +class FieldPath : public impl::BasePath { + public: + /** The field path string that represents the document's key. */ + static constexpr const char* kDocumentKeyPath = "__name__"; + + // Note: Xcode 8.2 requires explicit specification of the constructor. + FieldPath() : impl::BasePath() { + } + + /** Constructs the path from segments. */ + template + FieldPath(const IterT begin, const IterT end) : BasePath{begin, end} { + } + FieldPath(std::initializer_list list) : BasePath{list} { + } + explicit FieldPath(SegmentsT&& segments) : BasePath{std::move(segments)} { + } + + /** + * Creates and returns a new path from the server formatted field-path string, + * where path segments are separated by a dot "." and optionally encoded using + * backticks. + */ + static FieldPath FromServerFormat(absl::string_view path); + /** Returns a field path that represents an empty path. */ + static const FieldPath& EmptyPath(); + /** Returns a field path that represents a document key. */ + static const FieldPath& KeyFieldPath(); + + /** Returns a standardized string representation of this path. */ + std::string CanonicalString() const; + /** True if this FieldPath represents a document key. */ + bool IsKeyFieldPath() const; + + bool operator==(const FieldPath& rhs) const { + return BasePath::operator==(rhs); + } + bool operator!=(const FieldPath& rhs) const { + return BasePath::operator!=(rhs); + } + bool operator<(const FieldPath& rhs) const { + return BasePath::operator<(rhs); + } + bool operator>(const FieldPath& rhs) const { + return BasePath::operator>(rhs); + } + bool operator<=(const FieldPath& rhs) const { + return BasePath::operator<=(rhs); + } + bool operator>=(const FieldPath& rhs) const { + return BasePath::operator>=(rhs); + } +}; + +} // namespace model +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_MODEL_FIELD_PATH_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/field_transform.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/field_transform.h new file mode 100644 index 0000000..4591802 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/field_transform.h @@ -0,0 +1,73 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_MODEL_FIELD_TRANSFORM_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_MODEL_FIELD_TRANSFORM_H_ + +#include +#include + +#include "Firestore/core/src/firebase/firestore/model/field_path.h" +#include "Firestore/core/src/firebase/firestore/model/transform_operations.h" +#include "Firestore/core/src/firebase/firestore/util/hashing.h" + +namespace firebase { +namespace firestore { +namespace model { + +/** A field path and the TransformOperation to perform upon it. */ +class FieldTransform { + public: + FieldTransform(FieldPath path, + std::unique_ptr transformation) noexcept + : path_{std::move(path)}, transformation_{std::move(transformation)} { + } + + const FieldPath& path() const { + return path_; + } + + const TransformOperation& transformation() const { + return *transformation_.get(); + } + + bool idempotent() const { + return transformation_->idempotent(); + } + + bool operator==(const FieldTransform& other) const { + return path_ == other.path_ && *transformation_ == *other.transformation_; + } + +#if defined(__OBJC__) + // For Objective-C++ hash; to be removed after migration. + // Do NOT use in C++ code. + NSUInteger Hash() const { + return util::Hash(path_, transformation_->Hash()); + } +#endif // defined(__OBJC__) + + private: + FieldPath path_; + // Shared by copies of the same FieldTransform. + std::shared_ptr transformation_; +}; + +} // namespace model +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_MODEL_FIELD_TRANSFORM_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/field_value.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/field_value.cc new file mode 100644 index 0000000..fee1045 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/field_value.cc @@ -0,0 +1,501 @@ +/* + * Copyright 2018 Google + * + * 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 "Firestore/core/src/firebase/firestore/model/field_value.h" + +#include +#include +#include +#include +#include +#include + +#include "Firestore/core/src/firebase/firestore/immutable/sorted_map.h" +#include "Firestore/core/src/firebase/firestore/util/comparison.h" +#include "Firestore/core/src/firebase/firestore/util/hard_assert.h" +#include "absl/memory/memory.h" + +using firebase::firestore::util::Comparator; + +namespace firebase { +namespace firestore { +namespace model { + +using Type = FieldValue::Type; +using firebase::firestore::util::ComparisonResult; + +FieldValue::FieldValue(const FieldValue& value) { + *this = value; +} + +FieldValue::FieldValue(FieldValue&& value) { + *this = std::move(value); +} + +FieldValue::~FieldValue() { + SwitchTo(Type::Null); +} + +FieldValue& FieldValue::operator=(const FieldValue& value) { + SwitchTo(value.tag_); + switch (tag_) { + case Type::Null: + break; + case Type::Boolean: + boolean_value_ = value.boolean_value_; + break; + case Type::Integer: + integer_value_ = value.integer_value_; + break; + case Type::Double: + double_value_ = value.double_value_; + break; + case Type::Timestamp: + *timestamp_value_ = *value.timestamp_value_; + break; + case Type::ServerTimestamp: + *server_timestamp_value_ = *value.server_timestamp_value_; + break; + case Type::String: + *string_value_ = *value.string_value_; + break; + case Type::Blob: { + // copy-and-swap + std::vector tmp = *value.blob_value_; + std::swap(*blob_value_, tmp); + break; + } + case Type::Reference: + *reference_value_ = *value.reference_value_; + break; + case Type::GeoPoint: + *geo_point_value_ = *value.geo_point_value_; + break; + case Type::Array: { + // copy-and-swap + std::vector tmp = *value.array_value_; + std::swap(*array_value_, tmp); + break; + } + case Type::Object: { + // copy-and-swap + Map tmp = *value.object_value_; + std::swap(*object_value_, tmp); + break; + } + default: + HARD_FAIL("Unsupported type %s", value.type()); + } + return *this; +} + +FieldValue& FieldValue::operator=(FieldValue&& value) { + switch (value.tag_) { + case Type::String: + SwitchTo(Type::String); + string_value_->swap(*value.string_value_); + return *this; + case Type::Blob: + SwitchTo(Type::Blob); + std::swap(blob_value_, value.blob_value_); + return *this; + case Type::Reference: + SwitchTo(Type::Reference); + std::swap(reference_value_, value.reference_value_); + return *this; + case Type::Array: + SwitchTo(Type::Array); + std::swap(array_value_, value.array_value_); + return *this; + case Type::Object: + SwitchTo(Type::Object); + std::swap(object_value_, value.object_value_); + return *this; + default: + // We just copy over POD union types. + *this = value; + return *this; + } +} + +bool FieldValue::Comparable(Type lhs, Type rhs) { + switch (lhs) { + case Type::Integer: + case Type::Double: + return rhs == Type::Integer || rhs == Type::Double; + case Type::Timestamp: + case Type::ServerTimestamp: + return rhs == Type::Timestamp || rhs == Type::ServerTimestamp; + default: + return lhs == rhs; + } +} + +// TODO(rsgowman): Reorder this file to match its header. +ObjectValue ObjectValue::Set(const FieldPath& field_path, + const FieldValue& value) const { + HARD_ASSERT(!field_path.empty(), + "Cannot set field for empty path on FieldValue"); + // Set the value by recursively calling on child object. + const std::string& child_name = field_path.first_segment(); + if (field_path.size() == 1) { + return SetChild(child_name, value); + } else { + ObjectValue child = ObjectValue::Empty(); + const auto iter = fv_.object_value_->find(child_name); + if (iter != fv_.object_value_->end() && + iter->second.type() == Type::Object) { + child = ObjectValue(iter->second); + } + ObjectValue new_child = child.Set(field_path.PopFirst(), value); + return SetChild(child_name, new_child.fv_); + } +} + +ObjectValue ObjectValue::Delete(const FieldPath& field_path) const { + HARD_ASSERT(!field_path.empty(), + "Cannot delete field for empty path on FieldValue"); + // Delete the value by recursively calling on child object. + const std::string& child_name = field_path.first_segment(); + if (field_path.size() == 1) { + return ObjectValue::FromMap(fv_.object_value_->erase(child_name)); + } else { + const auto iter = fv_.object_value_->find(child_name); + if (iter != fv_.object_value_->end() && + iter->second.type() == Type::Object) { + ObjectValue new_child = + ObjectValue(iter->second).Delete(field_path.PopFirst()); + return SetChild(child_name, new_child.fv_); + } else { + // If the found value isn't an object, it cannot contain the remaining + // segments of the path. We don't actually change a primitive value to + // an object for a delete. + return *this; + } + } +} + +absl::optional ObjectValue::Get(const FieldPath& field_path) const { + const FieldValue* current = &this->fv_; + for (const auto& path : field_path) { + if (current->type() != Type::Object) { + return absl::nullopt; + } + const auto iter = current->object_value_->find(path); + if (iter == current->object_value_->end()) { + return absl::nullopt; + } else { + current = &iter->second; + } + } + return *current; +} + +ObjectValue ObjectValue::SetChild(const std::string& child_name, + const FieldValue& value) const { + return ObjectValue::FromMap(fv_.object_value_->insert(child_name, value)); +} + +FieldValue FieldValue::Null() { + return FieldValue(); +} + +FieldValue FieldValue::True() { + return FieldValue(true); +} + +FieldValue FieldValue::False() { + return FieldValue(false); +} + +FieldValue FieldValue::FromBoolean(bool value) { + return value ? True() : False(); +} + +FieldValue FieldValue::Nan() { + return FieldValue::FromDouble(NAN); +} + +FieldValue FieldValue::EmptyObject() { + return FieldValue::FromMap(FieldValue::Map()); +} + +FieldValue FieldValue::FromInteger(int64_t value) { + FieldValue result; + result.SwitchTo(Type::Integer); + result.integer_value_ = value; + return result; +} + +FieldValue FieldValue::FromDouble(double value) { + FieldValue result; + result.SwitchTo(Type::Double); + result.double_value_ = value; + return result; +} + +FieldValue FieldValue::FromTimestamp(const Timestamp& value) { + FieldValue result; + result.SwitchTo(Type::Timestamp); + *result.timestamp_value_ = value; + return result; +} + +FieldValue FieldValue::FromServerTimestamp(const Timestamp& local_write_time, + const Timestamp& previous_value) { + FieldValue result; + result.SwitchTo(Type::ServerTimestamp); + result.server_timestamp_value_->local_write_time = local_write_time; + result.server_timestamp_value_->previous_value = previous_value; + return result; +} + +FieldValue FieldValue::FromServerTimestamp(const Timestamp& local_write_time) { + FieldValue result; + result.SwitchTo(Type::ServerTimestamp); + result.server_timestamp_value_->local_write_time = local_write_time; + result.server_timestamp_value_->previous_value = absl::nullopt; + return result; +} + +FieldValue FieldValue::FromString(const char* value) { + std::string copy(value); + return FromString(std::move(copy)); +} + +FieldValue FieldValue::FromString(const std::string& value) { + std::string copy(value); + return FromString(std::move(copy)); +} + +FieldValue FieldValue::FromString(std::string&& value) { + FieldValue result; + result.SwitchTo(Type::String); + result.string_value_->swap(value); + return result; +} + +FieldValue FieldValue::FromBlob(const uint8_t* source, size_t size) { + FieldValue result; + result.SwitchTo(Type::Blob); + std::vector copy(source, source + size); + std::swap(*result.blob_value_, copy); + return result; +} + +// Does NOT pass ownership of database_id. +FieldValue FieldValue::FromReference(const DocumentKey& value, + const DatabaseId* database_id) { + FieldValue result; + result.SwitchTo(Type::Reference); + result.reference_value_->reference = value; + result.reference_value_->database_id = database_id; + return result; +} + +// Does NOT pass ownership of database_id. +FieldValue FieldValue::FromReference(DocumentKey&& value, + const DatabaseId* database_id) { + FieldValue result; + result.SwitchTo(Type::Reference); + std::swap(result.reference_value_->reference, value); + result.reference_value_->database_id = database_id; + return result; +} + +FieldValue FieldValue::FromGeoPoint(const GeoPoint& value) { + FieldValue result; + result.SwitchTo(Type::GeoPoint); + *result.geo_point_value_ = value; + return result; +} + +FieldValue FieldValue::FromArray(const std::vector& value) { + std::vector copy(value); + return FromArray(std::move(copy)); +} + +FieldValue FieldValue::FromArray(std::vector&& value) { + FieldValue result; + result.SwitchTo(Type::Array); + std::swap(*result.array_value_, value); + return result; +} + +FieldValue FieldValue::FromMap(const FieldValue::Map& value) { + FieldValue::Map copy(value); + return FromMap(std::move(copy)); +} + +FieldValue FieldValue::FromMap(FieldValue::Map&& value) { + FieldValue result; + result.SwitchTo(Type::Object); + std::swap(*result.object_value_, value); + return result; +} + +bool operator<(const FieldValue::Map& lhs, const FieldValue::Map& rhs) { + return std::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), + rhs.end()); +} + +bool operator<(const FieldValue& lhs, const FieldValue& rhs) { + if (!FieldValue::Comparable(lhs.type(), rhs.type())) { + return lhs.type() < rhs.type(); + } + + switch (lhs.type()) { + case Type::Null: + return false; + case Type::Boolean: + return Comparator()(lhs.boolean_value_, rhs.boolean_value_); + case Type::Integer: + if (rhs.type() == Type::Integer) { + return Comparator()(lhs.integer_value_, rhs.integer_value_); + } else { + return util::CompareMixedNumber(rhs.double_value_, + lhs.integer_value_) == + ComparisonResult::Descending; + } + case Type::Double: + if (rhs.type() == Type::Double) { + return Comparator()(lhs.double_value_, rhs.double_value_); + } else { + return util::CompareMixedNumber(lhs.double_value_, + rhs.integer_value_) == + ComparisonResult::Ascending; + } + case Type::Timestamp: + if (rhs.type() == Type::Timestamp) { + return *lhs.timestamp_value_ < *rhs.timestamp_value_; + } else { + return true; + } + case Type::ServerTimestamp: + if (rhs.type() == Type::ServerTimestamp) { + return lhs.server_timestamp_value_->local_write_time < + rhs.server_timestamp_value_->local_write_time; + } else { + return false; + } + case Type::String: + return lhs.string_value_->compare(*rhs.string_value_) < 0; + case Type::Blob: + return *lhs.blob_value_ < *rhs.blob_value_; + case Type::Reference: + return *lhs.reference_value_->database_id < + *rhs.reference_value_->database_id || + (*lhs.reference_value_->database_id == + *rhs.reference_value_->database_id && + lhs.reference_value_->reference < + rhs.reference_value_->reference); + case Type::GeoPoint: + return *lhs.geo_point_value_ < *rhs.geo_point_value_; + case Type::Array: + return *lhs.array_value_ < *rhs.array_value_; + case Type::Object: + return *lhs.object_value_ < *rhs.object_value_; + default: + HARD_FAIL("Unsupported type %s", lhs.type()); + // return false if assertion does not abort the program. We will say + // each unsupported type takes only one value thus everything is equal. + return false; + } +} + +void FieldValue::SwitchTo(const Type type) { + if (tag_ == type) { + return; + } + // Not same type. Destruct old type first and then initialize new type. + // Must call destructor explicitly for any non-POD type. + switch (tag_) { + case Type::Timestamp: + timestamp_value_.~unique_ptr(); + break; + case Type::ServerTimestamp: + server_timestamp_value_.~unique_ptr(); + break; + case Type::String: + string_value_.~unique_ptr(); + break; + case Type::Blob: + blob_value_.~unique_ptr>(); + break; + case Type::Reference: + reference_value_.~unique_ptr(); + break; + case Type::GeoPoint: + geo_point_value_.~unique_ptr(); + break; + case Type::Array: + array_value_.~unique_ptr>(); + break; + case Type::Object: + object_value_.~unique_ptr(); + break; + default: {} // The other types where there is nothing to worry about. + } + tag_ = type; + // Must call constructor explicitly for any non-POD type to initialize. + switch (tag_) { + case Type::Timestamp: + new (×tamp_value_) + std::unique_ptr(absl::make_unique(0, 0)); + break; + case Type::ServerTimestamp: + new (&server_timestamp_value_) std::unique_ptr( + absl::make_unique()); + break; + case Type::String: + new (&string_value_) + std::unique_ptr(absl::make_unique()); + break; + case Type::Blob: + // Do not even bother to allocate a new array of size 0. + new (&blob_value_) std::unique_ptr>( + absl::make_unique>()); + break; + case Type::Reference: + new (&reference_value_) + std::unique_ptr(absl::make_unique()); + break; + case Type::GeoPoint: + new (&geo_point_value_) + std::unique_ptr(absl::make_unique()); + break; + case Type::Array: + new (&array_value_) std::unique_ptr>( + absl::make_unique>()); + break; + case Type::Object: + new (&object_value_) std::unique_ptr(absl::make_unique()); + break; + default: {} // The other types where there is nothing to worry about. + } +} + +ObjectValue ObjectValue::FromMap(const FieldValue::Map& value) { + return ObjectValue(FieldValue::FromMap(value)); +} + +ObjectValue ObjectValue::FromMap(FieldValue::Map&& value) { + return ObjectValue(FieldValue::FromMap(std::move(value))); +} + +} // namespace model +} // namespace firestore +} // namespace firebase diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/field_value.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/field_value.h new file mode 100644 index 0000000..c7137c1 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/field_value.h @@ -0,0 +1,323 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_MODEL_FIELD_VALUE_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_MODEL_FIELD_VALUE_H_ + +#include +#include +#include +#include +#include + +#include "Firestore/core/include/firebase/firestore/geo_point.h" +#include "Firestore/core/include/firebase/firestore/timestamp.h" +#include "Firestore/core/src/firebase/firestore/immutable/sorted_map.h" +#include "Firestore/core/src/firebase/firestore/model/database_id.h" +#include "Firestore/core/src/firebase/firestore/model/document_key.h" +#include "Firestore/core/src/firebase/firestore/model/field_path.h" +#include "Firestore/core/src/firebase/firestore/util/hard_assert.h" +#include "absl/types/optional.h" + +namespace firebase { +namespace firestore { +namespace model { + +struct ServerTimestamp { + Timestamp local_write_time; + absl::optional previous_value; +}; + +struct ReferenceValue { + DocumentKey reference; + // Does not own the DatabaseId instance. + const DatabaseId* database_id; +}; + +/** + * tagged-union class representing an immutable data value as stored in + * Firestore. FieldValue represents all the different kinds of values + * that can be stored in fields in a document. + */ +class FieldValue { + public: + using Map = immutable::SortedMap; + + /** + * All the different kinds of values that can be stored in fields in + * a document. The types of the same comparison order should be defined + * together as a group. The order of each group is defined by the Firestore + * backend and is available at: + * https://firebase.google.com/docs/firestore/manage-data/data-types + */ + enum class Type { + Null, // Null + Boolean, // Boolean + Integer, // Number type starts here + Double, + Timestamp, // Timestamp type starts here + ServerTimestamp, + String, // String + Blob, // Blob + Reference, // Reference + GeoPoint, // GeoPoint + Array, // Array + Object, // Object + // New enum should not always been added at the tail. Add it to the correct + // position instead, see the doc comment above. + }; + + FieldValue() { + } + + // Do not inline these ctor/dtor below, which contain call to non-trivial + // operator=. + FieldValue(const FieldValue& value); + FieldValue(FieldValue&& value); + + ~FieldValue(); + + FieldValue& operator=(const FieldValue& value); + FieldValue& operator=(FieldValue&& value); + + /** Returns the true type for this value. */ + Type type() const { + return tag_; + } + + /** + * PORTING NOTE: This deviates from the other platforms that define TypeOrder. + * Since we already define Type for union types, we use it together with this + * function to achieve the equivalent order of types i.e. + * i) if two types are comparable, then they are of equal order; + * ii) otherwise, their order is the same as the order of their Type. + */ + static bool Comparable(Type lhs, Type rhs); + + bool boolean_value() const { + HARD_ASSERT(tag_ == Type::Boolean); + return boolean_value_; + } + + int64_t integer_value() const { + HARD_ASSERT(tag_ == Type::Integer); + return integer_value_; + } + + double double_value() const { + HARD_ASSERT(tag_ == Type::Double); + return double_value_; + } + + Timestamp timestamp_value() const { + HARD_ASSERT(tag_ == Type::Timestamp); + return *timestamp_value_; + } + + const std::string& string_value() const { + HARD_ASSERT(tag_ == Type::String); + return *string_value_; + } + + const std::vector& blob_value() const { + HARD_ASSERT(tag_ == Type::Blob); + return *blob_value_; + } + + const GeoPoint& geo_point_value() const { + HARD_ASSERT(tag_ == Type::GeoPoint); + return *geo_point_value_; + } + + const std::vector& array_value() const { + HARD_ASSERT(tag_ == Type::Array); + return *array_value_; + } + + /** factory methods. */ + static FieldValue Null(); + static FieldValue True(); + static FieldValue False(); + static FieldValue Nan(); + static FieldValue EmptyObject(); + static FieldValue FromBoolean(bool value); + static FieldValue FromInteger(int64_t value); + static FieldValue FromDouble(double value); + static FieldValue FromTimestamp(const Timestamp& value); + static FieldValue FromServerTimestamp(const Timestamp& local_write_time, + const Timestamp& previous_value); + static FieldValue FromServerTimestamp(const Timestamp& local_write_time); + static FieldValue FromString(const char* value); + static FieldValue FromString(const std::string& value); + static FieldValue FromString(std::string&& value); + static FieldValue FromBlob(const uint8_t* source, size_t size); + static FieldValue FromReference(const DocumentKey& value, + const DatabaseId* database_id); + static FieldValue FromReference(DocumentKey&& value, + const DatabaseId* database_id); + static FieldValue FromGeoPoint(const GeoPoint& value); + static FieldValue FromArray(const std::vector& value); + static FieldValue FromArray(std::vector&& value); + static FieldValue FromMap(const Map& value); + static FieldValue FromMap(Map&& value); + + friend bool operator<(const FieldValue& lhs, const FieldValue& rhs); + + private: + friend class ObjectValue; + + explicit FieldValue(bool value) : tag_(Type::Boolean), boolean_value_(value) { + } + + /** + * Switch to the specified type, if different from the current type. + */ + void SwitchTo(Type type); + + Type tag_ = Type::Null; + union { + // There is no null type as tag_ alone is enough for Null FieldValue. + bool boolean_value_; + int64_t integer_value_; + double double_value_; + std::unique_ptr timestamp_value_; + std::unique_ptr server_timestamp_value_; + // TODO(rsgowman): Change unique_ptr to nanopb::String? + std::unique_ptr string_value_; + std::unique_ptr> blob_value_; + std::unique_ptr reference_value_; + std::unique_ptr geo_point_value_; + std::unique_ptr> array_value_; + std::unique_ptr object_value_; + }; +}; + +/** A structured object value stored in Firestore. */ +class ObjectValue { + public: + explicit ObjectValue(FieldValue fv) : fv_(std::move(fv)) { + HARD_ASSERT(fv_.type() == FieldValue::Type::Object); + } + + static ObjectValue Empty() { + return ObjectValue(FieldValue::EmptyObject()); + } + + static ObjectValue FromMap(const FieldValue::Map& value); + static ObjectValue FromMap(FieldValue::Map&& value); + + /** + * Returns the value at the given path or absl::nullopt. If the path is empty, + * an identical copy of the FieldValue is returned. + * + * @param field_path the path to search. + * @return The value at the path or absl::nullopt if it doesn't exist. + */ + absl::optional Get(const FieldPath& field_path) const; + + /** + * Returns a FieldValue with the field at the named path set to value. + * Any absent parent of the field will also be created accordingly. + * + * @param field_path The field path to set. Cannot be empty. + * @param value The value to set. + * @return A new FieldValue with the field set. + */ + ObjectValue Set(const FieldPath& field_path, const FieldValue& value) const; + + /** + * Returns a FieldValue with the field path deleted. If there is no field at + * the specified path, the returned value is an identical copy. + * + * @param field_path The field path to remove. Cannot be empty. + * @return A new FieldValue with the field path removed. + */ + ObjectValue Delete(const FieldPath& field_path) const; + + // TODO(rsgowman): Add Value() method? + // + // Java has a value() method which returns a (non-immutable) java.util.Map, + // which is a copy of the immutable map, but with some fields (such as server + // timestamps) optionally resolved. Do we need the same here? + + const FieldValue::Map& GetInternalValue() const { + return *fv_.object_value_; + } + + private: + friend bool operator<(const ObjectValue& lhs, const ObjectValue& rhs); + + ObjectValue SetChild(const std::string& child_name, + const FieldValue& value) const; + + FieldValue fv_; +}; + +bool operator<(const FieldValue::Map& lhs, const FieldValue::Map& rhs); + +/** Compares against another FieldValue. */ +bool operator<(const FieldValue& lhs, const FieldValue& rhs); + +inline bool operator>(const FieldValue& lhs, const FieldValue& rhs) { + return rhs < lhs; +} + +inline bool operator>=(const FieldValue& lhs, const FieldValue& rhs) { + return !(lhs < rhs); +} + +inline bool operator<=(const FieldValue& lhs, const FieldValue& rhs) { + return !(lhs > rhs); +} + +inline bool operator!=(const FieldValue& lhs, const FieldValue& rhs) { + return lhs < rhs || lhs > rhs; +} + +inline bool operator==(const FieldValue& lhs, const FieldValue& rhs) { + return !(lhs != rhs); +} + +/** Compares against another ObjectValue. */ +inline bool operator<(const ObjectValue& lhs, const ObjectValue& rhs) { + return lhs.fv_ < rhs.fv_; +} + +inline bool operator>(const ObjectValue& lhs, const ObjectValue& rhs) { + return rhs < lhs; +} + +inline bool operator>=(const ObjectValue& lhs, const ObjectValue& rhs) { + return !(lhs < rhs); +} + +inline bool operator<=(const ObjectValue& lhs, const ObjectValue& rhs) { + return !(lhs > rhs); +} + +inline bool operator!=(const ObjectValue& lhs, const ObjectValue& rhs) { + return lhs < rhs || lhs > rhs; +} + +inline bool operator==(const ObjectValue& lhs, const ObjectValue& rhs) { + return !(lhs != rhs); +} + +} // namespace model +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_MODEL_FIELD_VALUE_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/maybe_document.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/maybe_document.cc new file mode 100644 index 0000000..aa5e15a --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/maybe_document.cc @@ -0,0 +1,36 @@ +/* + * Copyright 2018 Google + * + * 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 "Firestore/core/src/firebase/firestore/model/maybe_document.h" + +#include + +namespace firebase { +namespace firestore { +namespace model { + +MaybeDocument::MaybeDocument(DocumentKey key, SnapshotVersion version) + : key_(std::move(key)), version_(std::move(version)) { +} + +bool MaybeDocument::Equals(const MaybeDocument& other) const { + return type_ == other.type_ && version_ == other.version_ && + key_ == other.key_; +} + +} // namespace model +} // namespace firestore +} // namespace firebase diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/maybe_document.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/maybe_document.h new file mode 100644 index 0000000..1039de1 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/maybe_document.h @@ -0,0 +1,118 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_MODEL_MAYBE_DOCUMENT_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_MODEL_MAYBE_DOCUMENT_H_ + +#include +#include + +#include "Firestore/core/src/firebase/firestore/model/document_key.h" +#include "Firestore/core/src/firebase/firestore/model/snapshot_version.h" + +namespace firebase { +namespace firestore { +namespace model { + +/** + * The result of a lookup for a given path may be an existing document or a + * tombstone that marks the path deleted. + */ +class MaybeDocument { + public: + /** + * All the different kinds of documents, including MaybeDocument and its + * subclasses. This is used to provide RTTI for documents. See the docstrings + * of the subclasses for details. + */ + enum class Type { + // An unknown subclass of MaybeDocument. This should never happen. + // + // TODO(rsgowman): Since it's no longer possible to directly create + // MaybeDocument's, we can likely remove this value entirely. But + // investigate impact on the serializers first. + Unknown, + + Document, + NoDocument, + UnknownDocument, + }; + + MaybeDocument(DocumentKey key, SnapshotVersion version); + + virtual ~MaybeDocument() { + } + + /** The runtime type of this document. */ + Type type() const { + return type_; + } + + /** The key for this document. */ + const DocumentKey& key() const { + return key_; + } + + /** + * Returns the version of this document if it exists or a version at which + * this document was guaranteed to not exist. + */ + const SnapshotVersion& version() const { + return version_; + } + + /** + * Whether this document has a local mutation applied that has not yet been + * acknowledged by Watch. + */ + virtual bool HasPendingWrites() const = 0; + + protected: + // Only allow subclass to set their types. + void set_type(Type type) { + type_ = type; + } + + virtual bool Equals(const MaybeDocument& other) const; + + friend bool operator==(const MaybeDocument& lhs, const MaybeDocument& rhs); + + private: + Type type_ = Type::Unknown; + DocumentKey key_; + SnapshotVersion version_; +}; + +inline bool operator==(const MaybeDocument& lhs, const MaybeDocument& rhs) { + return lhs.Equals(rhs); +} + +inline bool operator!=(const MaybeDocument& lhs, const MaybeDocument& rhs) { + return !(lhs == rhs); +} + +/** Compares against another MaybeDocument by keys only. */ +struct DocumentKeyComparator : public std::less { + bool operator()(const MaybeDocument& lhs, const MaybeDocument& rhs) const { + return lhs.key() < rhs.key(); + } +}; + +} // namespace model +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_MODEL_MAYBE_DOCUMENT_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/mutation.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/mutation.cc new file mode 100644 index 0000000..e863b34 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/mutation.cc @@ -0,0 +1,207 @@ +/* + * Copyright 2018 Google + * + * 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 "Firestore/core/src/firebase/firestore/model/mutation.h" + +#include +#include + +#include "Firestore/core/src/firebase/firestore/model/document.h" +#include "Firestore/core/src/firebase/firestore/model/field_path.h" +#include "Firestore/core/src/firebase/firestore/model/field_value.h" +#include "Firestore/core/src/firebase/firestore/model/no_document.h" +#include "Firestore/core/src/firebase/firestore/util/hard_assert.h" + +namespace firebase { +namespace firestore { +namespace model { + +Mutation::Mutation(DocumentKey&& key, Precondition&& precondition) + : key_(std::move(key)), precondition_(std::move(precondition)) { +} + +void Mutation::VerifyKeyMatches(const MaybeDocument* maybe_doc) const { + if (maybe_doc) { + HARD_ASSERT(maybe_doc->key() == key(), + "Can only apply a mutation to a document with the same key"); + } +} + +SnapshotVersion Mutation::GetPostMutationVersion( + const MaybeDocument* maybe_doc) { + if (maybe_doc && maybe_doc->type() == MaybeDocument::Type::Document) { + return maybe_doc->version(); + } else { + return SnapshotVersion::None(); + } +} + +bool Mutation::equal_to(const Mutation& other) const { + return key_ == other.key_ && precondition_ == other.precondition_ && + type() == other.type(); +} + +SetMutation::SetMutation(DocumentKey&& key, + ObjectValue&& value, + Precondition&& precondition) + : Mutation(std::move(key), std::move(precondition)), + value_(std::move(value)) { +} + +MaybeDocumentPtr SetMutation::ApplyToRemoteDocument( + const MaybeDocumentPtr& maybe_doc, + const MutationResult& mutation_result) const { + VerifyKeyMatches(maybe_doc.get()); + + HARD_ASSERT(mutation_result.transform_results() == nullptr, + "Transform results received by SetMutation."); + + // Unlike applyToLocalView, if we're applying a mutation to a remote document + // the server has accepted the mutation so the precondition must have held. + + const SnapshotVersion& version = mutation_result.version(); + return absl::make_unique(ObjectValue(value_), key(), version, + DocumentState::kCommittedMutations); +} + +MaybeDocumentPtr SetMutation::ApplyToLocalView( + const MaybeDocumentPtr& maybe_doc, + const MaybeDocument*, + const Timestamp&) const { + VerifyKeyMatches(maybe_doc.get()); + + if (!precondition().IsValidFor(maybe_doc.get())) { + return maybe_doc; + } + + SnapshotVersion version = GetPostMutationVersion(maybe_doc.get()); + return absl::make_unique(ObjectValue(value_), key(), version, + DocumentState::kLocalMutations); +} + +bool SetMutation::equal_to(const Mutation& other) const { + if (!Mutation::equal_to(other)) return false; + return value_ == static_cast(other).value_; +} + +PatchMutation::PatchMutation(DocumentKey&& key, + ObjectValue&& value, + FieldMask&& mask, + Precondition&& precondition) + : Mutation(std::move(key), std::move(precondition)), + value_(std::move(value)), + mask_(std::move(mask)) { +} + +MaybeDocumentPtr PatchMutation::ApplyToRemoteDocument( + const MaybeDocumentPtr& maybe_doc, + const MutationResult& mutation_result) const { + VerifyKeyMatches(maybe_doc.get()); + HARD_ASSERT(mutation_result.transform_results() == nullptr, + "Transform results received by PatchMutation."); + + if (!precondition().IsValidFor(maybe_doc.get())) { + // Since the mutation was not rejected, we know that the precondition + // matched on the backend. We therefore must not have the expected version + // of the document in our cache and return an UnknownDocument with the known + // updateTime. + + // TODO(rsgowman): heldwriteacks: Implement. Like this (once UnknownDocument + // is ported): + // return absl::make_unique(key(), + // mutation_result.version()); + + abort(); + } + + const SnapshotVersion& version = mutation_result.version(); + ObjectValue new_data = PatchDocument(maybe_doc.get()); + return absl::make_unique(std::move(new_data), key(), version, + DocumentState::kCommittedMutations); +} + +MaybeDocumentPtr PatchMutation::ApplyToLocalView( + const MaybeDocumentPtr& maybe_doc, + const MaybeDocument*, + const Timestamp&) const { + VerifyKeyMatches(maybe_doc.get()); + + if (!precondition().IsValidFor(maybe_doc.get())) { + return maybe_doc; + } + + SnapshotVersion version = GetPostMutationVersion(maybe_doc.get()); + ObjectValue new_data = PatchDocument(maybe_doc.get()); + return absl::make_unique(std::move(new_data), key(), version, + DocumentState::kLocalMutations); +} + +ObjectValue PatchMutation::PatchDocument(const MaybeDocument* maybe_doc) const { + if (maybe_doc && maybe_doc->type() == MaybeDocument::Type::Document) { + return PatchObject(static_cast(maybe_doc)->data()); + } else { + return PatchObject(ObjectValue::Empty()); + } +} + +ObjectValue PatchMutation::PatchObject(ObjectValue obj) const { + for (const FieldPath& path : mask_) { + if (!path.empty()) { + absl::optional new_value = value_.Get(path); + if (!new_value) { + obj = obj.Delete(path); + } else { + obj = obj.Set(path, *new_value); + } + } + } + return obj; +} + +bool PatchMutation::equal_to(const Mutation& other) const { + if (!Mutation::equal_to(other)) return false; + const PatchMutation& patch_other = static_cast(other); + return value_ == patch_other.value_ && mask_ == patch_other.mask_; +} + +DeleteMutation::DeleteMutation(DocumentKey&& key, Precondition&& precondition) + : Mutation(std::move(key), std::move(precondition)) { +} + +MaybeDocumentPtr DeleteMutation::ApplyToRemoteDocument( + const MaybeDocumentPtr& /*maybe_doc*/, + const MutationResult& /*mutation_result*/) const { + // TODO(rsgowman): Implement. + abort(); +} + +MaybeDocumentPtr DeleteMutation::ApplyToLocalView( + const MaybeDocumentPtr& maybe_doc, + const MaybeDocument*, + const Timestamp&) const { + VerifyKeyMatches(maybe_doc.get()); + + if (!precondition().IsValidFor(maybe_doc.get())) { + return maybe_doc; + } + + return absl::make_unique(key(), SnapshotVersion::None(), + /*hasCommittedMutations=*/false); +} + +} // namespace model +} // namespace firestore +} // namespace firebase diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/mutation.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/mutation.h new file mode 100644 index 0000000..8e4ad56 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/mutation.h @@ -0,0 +1,330 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_MODEL_MUTATION_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_MODEL_MUTATION_H_ + +#include +#include +#include + +#include "Firestore/core/src/firebase/firestore/model/document_key.h" +#include "Firestore/core/src/firebase/firestore/model/field_mask.h" +#include "Firestore/core/src/firebase/firestore/model/field_value.h" +#include "Firestore/core/src/firebase/firestore/model/maybe_document.h" +#include "Firestore/core/src/firebase/firestore/model/precondition.h" +#include "Firestore/core/src/firebase/firestore/model/snapshot_version.h" + +namespace firebase { +namespace firestore { +namespace model { + +using MaybeDocumentPtr = std::shared_ptr; + +/** + * The result of applying a mutation to the server. This is a model of the + * WriteResult proto message. + * + * Note that MutationResult does not name which document was mutated. The + * association is implied positionally: for each entry in the array of + * Mutations, there's a corresponding entry in the array of MutationResults. + */ +class MutationResult { + public: + MutationResult( + SnapshotVersion&& version, + const std::shared_ptr>& transform_results) + : version_(std::move(version)), + transform_results_(std::move(transform_results)) { + } + + /** + * The version at which the mutation was committed. + * + * - For most operations, this is the update_time in the WriteResult. + * - For deletes, it is the commit_time of the WriteResponse (because + * deletes are not stored and have no update_time). + * + * Note that these versions can be different: No-op writes will not change + * the update_time even though the commit_time advances. + */ + const SnapshotVersion& version() const { + return version_; + } + + /** + * The resulting fields returned from the backend after a TransformMutation + * has been committed. Contains one ObjectValue for each FieldTransform + * that was in the mutation. + * + * Will be null if the mutation was not a TransformMutation. + */ + const std::shared_ptr>& transform_results() + const { + return transform_results_; + } + + private: + const SnapshotVersion version_; + const std::shared_ptr> transform_results_; +}; + +/** + * Represents a Mutation of a document. Different subclasses of Mutation will + * perform different kinds of changes to a base document. For example, a + * SetMutation replaces the value of a document and a DeleteMutation deletes a + * document. + * + * In addition to the value of the document mutations also operate on the + * version. For local mutations (mutations that haven't been committed yet), we + * preserve the existing version for Set, Patch, and Transform mutations. For + * local deletes, we reset the version to 0. + * + * Here's the expected transition table. + * + * MUTATION APPLIED TO RESULTS IN + * SetMutation Document(v3) Document(v3) + * SetMutation NoDocument(v3) Document(v0) + * SetMutation null Document(v0) + * PatchMutation Document(v3) Document(v3) + * PatchMutation NoDocument(v3) NoDocument(v3) + * PatchMutation null null + * TransformMutation Document(v3) Document(v3) + * TransformMutation NoDocument(v3) NoDocument(v3) + * TransformMutation null null + * DeleteMutation Document(v3) NoDocument(v0) + * DeleteMutation NoDocument(v3) NoDocument(v0) + * DeleteMutation null NoDocument(v0) + * + * For acknowledged mutations, we use the updateTime of the WriteResponse as the + * resulting version for Set, Patch, and Transform mutations. As deletes have no + * explicit update time, we use the commitTime of the WriteResponse for + * acknowledged deletes. + * + * If a mutation is acknowledged by the backend but fails the precondition check + * locally, we return an `UnknownDocument` and rely on Watch to send us the + * updated version. + * + * Note that TransformMutations don't create Documents (in the case of being + * applied to a NoDocument), even though they would on the backend. This is + * because the client always combines the TransformMutation with a SetMutation + * or PatchMutation and we only want to apply the transform if the prior + * mutation resulted in a Document (always true for a SetMutation, but not + * necessarily for an PatchMutation). + */ +class Mutation { + public: + /** + * Represents the mutation type. This is used in place of dynamic_cast. + */ + enum class Type { kSet, kPatch, kDelete }; + + virtual ~Mutation() { + } + + const DocumentKey& key() const { + return key_; + } + const Precondition& precondition() const { + return precondition_; + } + + /** The runtime type of this mutation. */ + virtual Type type() const = 0; + + /** + * Applies this mutation to the given MaybeDocument for the purposes of + * computing a new remote document. If the input document doesn't match the + * expected state (e.g. it is null or outdated), an `UnknownDocument` can be + * returned. + * + * @param maybe_doc The document to mutate. The input document can be nullptr + * if the client has no knowledge of the pre-mutation state of the + * document. + * @param mutation_result The result of applying the mutation from the + * backend. + * @return The mutated document. The returned document may be an + * UnknownDocument if the mutation could not be applied to the locally + * cached base document. + */ + virtual MaybeDocumentPtr ApplyToRemoteDocument( + const MaybeDocumentPtr& maybe_doc, + const MutationResult& mutation_result) const = 0; + + /** + * Applies this mutation to the given MaybeDocument for the purposes of + * computing the new local view of a document. Both the input and returned + * documents can be nullptr. + * + * @param maybe_doc The document to mutate. The input document can be nullptr + * if the client has no knowledge of the pre-mutation state of the + * document. + * @param base_doc The state of the document prior to this mutation batch. The + * input document can be nullptr if the client has no knowledge of the + * pre-mutation state of the document. + * @param local_write_time A timestamp indicating the local write time of the + * batch this mutation is a part of. + * @return The mutated document. The returned document may be nullptr, but + * only if maybe_doc was nullptr and the mutation would not create a new + * document. + */ + virtual MaybeDocumentPtr ApplyToLocalView( + const MaybeDocumentPtr& maybe_doc, + const MaybeDocument* base_doc, + const Timestamp& local_write_time) const = 0; + + friend bool operator==(const Mutation& lhs, const Mutation& rhs); + + protected: + Mutation(DocumentKey&& key, Precondition&& precondition); + + void VerifyKeyMatches(const MaybeDocument* maybe_doc) const; + + static SnapshotVersion GetPostMutationVersion(const MaybeDocument* maybe_doc); + + virtual bool equal_to(const Mutation& other) const; + + private: + const DocumentKey key_; + const Precondition precondition_; +}; + +inline bool operator==(const Mutation& lhs, const Mutation& rhs) { + return lhs.equal_to(rhs); +} + +inline bool operator!=(const Mutation& lhs, const Mutation& rhs) { + return !(lhs == rhs); +} + +/** + * A mutation that creates or replaces the document at the given key with the + * object value contents. + */ +class SetMutation : public Mutation { + public: + SetMutation(DocumentKey&& key, + ObjectValue&& value, + Precondition&& precondition); + + Type type() const override { + return Mutation::Type::kSet; + } + + MaybeDocumentPtr ApplyToRemoteDocument( + const MaybeDocumentPtr& maybe_doc, + const MutationResult& mutation_result) const override; + + MaybeDocumentPtr ApplyToLocalView( + const MaybeDocumentPtr& maybe_doc, + const MaybeDocument* base_doc, + const Timestamp& local_write_time) const override; + + /** Returns the object value to use when setting the document. */ + const ObjectValue& value() const { + return value_; + } + + protected: + bool equal_to(const Mutation& other) const override; + + private: + const ObjectValue value_; +}; + +/** + * A mutation that modifies fields of the document at the given key with the + * given values. The values are applied through a field mask: + * + * - When a field is in both the mask and the values, the corresponding field is + * updated. + * - When a field is in neither the mask nor the values, the corresponding field + * is unmodified. + * - When a field is in the mask but not in the values, the corresponding field + * is deleted. + * - When a field is not in the mask but is in the values, the values map is + * ignored. + */ +class PatchMutation : public Mutation { + public: + PatchMutation(DocumentKey&& key, + ObjectValue&& value, + FieldMask&& mask, + Precondition&& precondition); + + Type type() const override { + return Mutation::Type::kPatch; + } + + MaybeDocumentPtr ApplyToRemoteDocument( + const MaybeDocumentPtr& maybe_doc, + const MutationResult& mutation_result) const override; + + MaybeDocumentPtr ApplyToLocalView( + const MaybeDocumentPtr& maybe_doc, + const MaybeDocument* base_doc, + const Timestamp& local_write_time) const override; + + /** + * Returns the fields and associated values to use when patching the document. + */ + const ObjectValue& value() const { + return value_; + } + + /** + * Returns the mask to apply to value(), where only fields that are in both + * the field_mask and the value will be updated. + */ + const FieldMask& mask() const { + return mask_; + } + + protected: + bool equal_to(const Mutation& other) const override; + + private: + ObjectValue PatchDocument(const MaybeDocument* maybe_doc) const; + ObjectValue PatchObject(ObjectValue obj) const; + + const ObjectValue value_; + const FieldMask mask_; +}; + +/** Represents a Delete operation. */ +class DeleteMutation : public Mutation { + public: + DeleteMutation(DocumentKey&& key, Precondition&& precondition); + + Type type() const override { + return Mutation::Type::kDelete; + } + + MaybeDocumentPtr ApplyToRemoteDocument( + const MaybeDocumentPtr& maybe_doc, + const MutationResult& mutation_result) const override; + + MaybeDocumentPtr ApplyToLocalView( + const MaybeDocumentPtr& maybe_doc, + const MaybeDocument* base_doc, + const Timestamp& local_write_time) const override; +}; + +} // namespace model +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_MODEL_MUTATION_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/mutation_batch.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/mutation_batch.cc new file mode 100644 index 0000000..8c339bd --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/mutation_batch.cc @@ -0,0 +1,68 @@ +/* + * Copyright 2019 Google + * + * 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 "Firestore/core/src/firebase/firestore/model/mutation_batch.h" + +#include + +#include "Firestore/core/src/firebase/firestore/util/hard_assert.h" + +namespace firebase { +namespace firestore { +namespace model { + +namespace { + +/** + * Compares two vectors of unique pointers, and ensures the Mutation contents of + * the pointer (not just the memory address itself) is equal. + */ +bool deep_equals(const std::vector>& lhs, + const std::vector>& rhs) { + if (lhs.size() != rhs.size()) return false; + + for (size_t i = 0; i < lhs.size(); i++) { + if (!lhs[i] && !rhs[i]) + continue; + else if (!lhs[i] || !rhs[i]) + return false; + else if (*lhs[i] != *rhs[i]) + return false; + } + + return true; +} + +} // namespace + +MutationBatch::MutationBatch(int batch_id, + Timestamp local_write_time, + std::vector>&& mutations) + : batch_id_(batch_id), + local_write_time_(std::move(local_write_time)), + mutations_(std::move(mutations)) { + HARD_ASSERT(!mutations_.empty(), "Cannot create an empty mutation batch"); +} + +bool operator==(const MutationBatch& lhs, const MutationBatch& rhs) { + return lhs.batch_id() == rhs.batch_id() && + lhs.local_write_time() == rhs.local_write_time() && + deep_equals(lhs.mutations(), rhs.mutations()); +} + +} // namespace model +} // namespace firestore +} // namespace firebase diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/mutation_batch.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/mutation_batch.h new file mode 100644 index 0000000..6c498d5 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/mutation_batch.h @@ -0,0 +1,98 @@ +/* + * Copyright 2019 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_MODEL_MUTATION_BATCH_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_MODEL_MUTATION_BATCH_H_ + +#include +#include + +#include "Firestore/core/include/firebase/firestore/timestamp.h" +#include "Firestore/core/src/firebase/firestore/model/mutation.h" +#include "Firestore/core/src/firebase/firestore/model/types.h" + +namespace firebase { +namespace firestore { +namespace model { + +/** + * A BatchID that was searched for and not found or a batch ID value known to be + * before all known batches. + * + * BatchId values from the local store are non-negative so this value is before + * all batches. + */ +constexpr BatchId kBatchIdUnknown = -1; + +// TODO(rsgowman): Port MutationBatchResult + +/** + * A batch of mutations that will be sent as one unit to the backend. Batches + * can be marked as a tombstone if the mutation queue does not remove them + * immediately. When a batch is a tombstone it has no mutations. + */ +class MutationBatch { + public: + /** + * A batch ID that was searched for and not found or a batch ID value known to + * be before all known batches. + * + * Batch ID values from the local store are non-negative so this value is + * before all batches. + */ + constexpr static int kUnknown = -1; + + MutationBatch(int batch_id, + Timestamp local_write_time, + std::vector>&& mutations); + + // TODO(rsgowman): Port ApplyToRemoteDocument() + // TODO(rsgowman): Port ApplyToLocalView() + // TODO(rsgowman): Port GetKeys() + + int batch_id() const { + return batch_id_; + } + + /** + * Returns the local time at which the mutation batch was created / written; + * used to assign local times to server timestamps, etc. + */ + const Timestamp& local_write_time() const { + return local_write_time_; + } + + const std::vector>& mutations() const { + return mutations_; + } + + private: + int batch_id_; + const Timestamp local_write_time_; + std::vector> mutations_; +}; + +bool operator==(const MutationBatch& lhs, const MutationBatch& rhs); + +inline bool operator!=(const MutationBatch& lhs, const MutationBatch& rhs) { + return !(lhs == rhs); +} + +} // namespace model +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_MODEL_MUTATION_BATCH_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/no_document.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/no_document.cc new file mode 100644 index 0000000..5f348af --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/no_document.cc @@ -0,0 +1,35 @@ +/* + * Copyright 2018 Google + * + * 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 "Firestore/core/src/firebase/firestore/model/no_document.h" + +#include + +namespace firebase { +namespace firestore { +namespace model { + +NoDocument::NoDocument(DocumentKey key, + SnapshotVersion version, + bool has_committed_mutations) + : MaybeDocument(std::move(key), std::move(version)), + has_committed_mutations_(has_committed_mutations) { + set_type(Type::NoDocument); +} + +} // namespace model +} // namespace firestore +} // namespace firebase diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/no_document.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/no_document.h new file mode 100644 index 0000000..da2cac0 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/no_document.h @@ -0,0 +1,45 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_MODEL_NO_DOCUMENT_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_MODEL_NO_DOCUMENT_H_ + +#include "Firestore/core/src/firebase/firestore/model/maybe_document.h" + +namespace firebase { +namespace firestore { +namespace model { + +/** Represents that no documents exists for the key at the given version. */ +class NoDocument : public MaybeDocument { + public: + NoDocument(DocumentKey key, + SnapshotVersion version, + bool has_committed_mutations); + + bool HasPendingWrites() const override { + return has_committed_mutations_; + } + + private: + bool has_committed_mutations_; +}; + +} // namespace model +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_MODEL_NO_DOCUMENT_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/precondition.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/precondition.cc new file mode 100644 index 0000000..4d22eaa --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/precondition.cc @@ -0,0 +1,65 @@ +/* + * Copyright 2018 Google + * + * 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 "Firestore/core/src/firebase/firestore/model/precondition.h" + +#include "Firestore/core/src/firebase/firestore/model/maybe_document.h" +#include "Firestore/core/src/firebase/firestore/model/snapshot_version.h" +#include "Firestore/core/src/firebase/firestore/util/hard_assert.h" + +namespace firebase { +namespace firestore { +namespace model { + +Precondition::Precondition(Type type, SnapshotVersion update_time, bool exists) + : type_(type), update_time_(std::move(update_time)), exists_(exists) { +} + +/* static */ +Precondition Precondition::Exists(bool exists) { + return Precondition{Type::Exists, SnapshotVersion::None(), exists}; +} + +/* static */ +Precondition Precondition::UpdateTime(SnapshotVersion update_time) { + // update_time could be SnapshotVersion::None() in particular for locally + // deleted documents. + return Precondition{Type::UpdateTime, std::move(update_time), false}; +} + +/* static */ +Precondition Precondition::None() { + return Precondition{Type::None, SnapshotVersion::None(), false}; +} + +bool Precondition::IsValidFor(const MaybeDocument* maybe_doc) const { + switch (type_) { + case Type::UpdateTime: + return maybe_doc != nullptr && + maybe_doc->type() == MaybeDocument::Type::Document && + maybe_doc->version() == update_time_; + case Type::Exists: + return (exists_ == (maybe_doc != nullptr && + maybe_doc->type() == MaybeDocument::Type::Document)); + case Type::None: + return true; + } + UNREACHABLE(); +} + +} // namespace model +} // namespace firestore +} // namespace firebase diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/precondition.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/precondition.h new file mode 100644 index 0000000..6f9bb43 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/precondition.h @@ -0,0 +1,159 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_MODEL_PRECONDITION_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_MODEL_PRECONDITION_H_ + +#include + +#if defined(__OBJC__) +#import "Firestore/Source/Model/FSTDocument.h" +#include "Firestore/core/include/firebase/firestore/timestamp.h" +#endif // defined(__OBJC__) + +#include "Firestore/core/src/firebase/firestore/model/maybe_document.h" +#include "Firestore/core/src/firebase/firestore/model/snapshot_version.h" +#include "Firestore/core/src/firebase/firestore/util/hard_assert.h" + +namespace firebase { +namespace firestore { +namespace model { + +/** + * Encodes a precondition for a mutation. This follows the model that the + * backend accepts with the special case of an explicit "empty" precondition + * (meaning no precondition). + */ +class Precondition { + public: + enum class Type { + None, + Exists, + UpdateTime, + }; + + /** Creates a new Precondition with an exists flag. */ + static Precondition Exists(bool exists); + + /** Creates a new Precondition based on a time the document exists at. */ + static Precondition UpdateTime(SnapshotVersion update_time); + + /** Returns a precondition representing no precondition. */ + static Precondition None(); + + /** + * Returns true if the precondition is valid for the given document (and the + * document is available). + */ + bool IsValidFor(const MaybeDocument* maybe_doc) const; + + /** Returns whether this Precondition represents no precondition. */ + bool IsNone() const { + return type_ == Type::None; + } + + Type type() const { + return type_; + } + + const SnapshotVersion& update_time() const { + return update_time_; + } + + bool exists() const { + return exists_; + } + + bool operator==(const Precondition& other) const { + return type_ == other.type_ && update_time_ == other.update_time_ && + exists_ == other.exists_; + } + +#if defined(__OBJC__) + // Objective-C requires a default constructor. + Precondition() + : type_(Type::None), + update_time_(SnapshotVersion::None()), + exists_(false) { + } + + // MaybeDocument is not fully ported yet. So we suppose this addition helper. + bool IsValidFor(FSTMaybeDocument* maybe_doc) const { + switch (type_) { + case Type::UpdateTime: + return [maybe_doc isKindOfClass:[FSTDocument class]] && + firebase::firestore::model::SnapshotVersion(maybe_doc.version) == + update_time_; + case Type::Exists: + if (exists_) { + return [maybe_doc isKindOfClass:[FSTDocument class]]; + } else { + return maybe_doc == nil || + [maybe_doc isKindOfClass:[FSTDeletedDocument class]]; + } + case Type::None: + return true; + } + UNREACHABLE(); + } + + // For Objective-C++ hash; to be removed after migration. + // Do NOT use in C++ code. + NSUInteger Hash() const { + NSUInteger hash = std::hash()(update_time_.timestamp()); + hash = hash * 31 + exists_; + hash = hash * 31 + static_cast(type_); + return hash; + } + + NSString* description() const { + switch (type_) { + case Type::None: + return @">"; + case Type::Exists: + if (exists_) { + return @""; + } else { + return @""; + } + case Type::UpdateTime: + return [NSString + stringWithFormat:@"", + update_time_.timestamp().ToString().c_str()]; + } + UNREACHABLE(); + } +#endif // defined(__OBJC__) + + private: + Precondition(Type type, SnapshotVersion update_time, bool exists); + + // The actual time of this precondition. + Type type_ = Type::None; + + // For UpdateTime type, preconditions a mutation based on the last updateTime. + SnapshotVersion update_time_; + + // For Exists type, preconditions a mutation based on whether the document + // exists. + bool exists_; +}; + +} // namespace model +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_MODEL_PRECONDITION_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/resource_path.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/resource_path.cc new file mode 100644 index 0000000..cdd795f --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/resource_path.cc @@ -0,0 +1,56 @@ +/* + * Copyright 2018 Google + * + * 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 "Firestore/core/src/firebase/firestore/model/resource_path.h" + +#include +#include +#include + +#include "Firestore/core/src/firebase/firestore/util/hard_assert.h" +#include "absl/strings/str_join.h" +#include "absl/strings/str_split.h" + +namespace firebase { +namespace firestore { +namespace model { + +ResourcePath ResourcePath::FromString(const absl::string_view path) { + // NOTE: The client is ignorant of any path segments containing escape + // sequences (e.g. __id123__) and just passes them through raw (they exist + // for legacy reasons and should not be used frequently). + + HARD_ASSERT(path.find("//") == std::string::npos, + "Invalid path (%s). Paths must not contain // in them.", path); + + // SkipEmpty because we may still have an empty segment at the beginning or + // end if they had a leading or trailing slash (which we allow). + std::vector segments = + absl::StrSplit(path, '/', absl::SkipEmpty()); + return ResourcePath{std::move(segments)}; +} + +std::string ResourcePath::CanonicalString() const { + // NOTE: The client is ignorant of any path segments containing escape + // sequences (e.g. __id123__) and just passes them through raw (they exist + // for legacy reasons and should not be used frequently). + + return absl::StrJoin(begin(), end(), "/"); +} + +} // namespace model +} // namespace firestore +} // namespace firebase diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/resource_path.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/resource_path.h new file mode 100644 index 0000000..a149dc8 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/resource_path.h @@ -0,0 +1,83 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_MODEL_RESOURCE_PATH_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_MODEL_RESOURCE_PATH_H_ + +#include +#include +#include + +#include "Firestore/core/src/firebase/firestore/model/base_path.h" +#include "absl/strings/string_view.h" + +namespace firebase { +namespace firestore { +namespace model { + +/** + * A slash-separated path for navigating resources (documents and collections) + * within Firestore. Immutable; all instances are fully independent. + */ +class ResourcePath : public impl::BasePath { + public: + ResourcePath() = default; + /** Constructs the path from segments. */ + template + ResourcePath(const IterT begin, const IterT end) : BasePath{begin, end} { + } + ResourcePath(std::initializer_list list) : BasePath{list} { + } + explicit ResourcePath(SegmentsT&& segments) : BasePath{std::move(segments)} { + } + /** + * Creates and returns a new path from the given resource-path string, where + * the path segments are separated by a slash "/". + */ + static ResourcePath FromString(absl::string_view path); + + static ResourcePath Empty() { + return ResourcePath{}; + } + + /** Returns a standardized string representation of this path. */ + std::string CanonicalString() const; + + bool operator==(const ResourcePath& rhs) const { + return BasePath::operator==(rhs); + } + bool operator!=(const ResourcePath& rhs) const { + return BasePath::operator!=(rhs); + } + bool operator<(const ResourcePath& rhs) const { + return BasePath::operator<(rhs); + } + bool operator>(const ResourcePath& rhs) const { + return BasePath::operator>(rhs); + } + bool operator<=(const ResourcePath& rhs) const { + return BasePath::operator<=(rhs); + } + bool operator>=(const ResourcePath& rhs) const { + return BasePath::operator>=(rhs); + } +}; + +} // namespace model +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_MODEL_RESOURCE_PATH_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/snapshot_version.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/snapshot_version.cc new file mode 100644 index 0000000..114e313 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/snapshot_version.cc @@ -0,0 +1,34 @@ +/* + * Copyright 2018 Google + * + * 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 "Firestore/core/src/firebase/firestore/model/snapshot_version.h" + +namespace firebase { +namespace firestore { +namespace model { + +SnapshotVersion::SnapshotVersion(const Timestamp& timestamp) + : timestamp_(timestamp) { +} + +const SnapshotVersion& SnapshotVersion::None() { + static const SnapshotVersion kNone(Timestamp{}); + return kNone; +} + +} // namespace model +} // namespace firestore +} // namespace firebase diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/snapshot_version.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/snapshot_version.h new file mode 100644 index 0000000..dbecea1 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/snapshot_version.h @@ -0,0 +1,85 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_MODEL_SNAPSHOT_VERSION_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_MODEL_SNAPSHOT_VERSION_H_ + +#include "Firestore/core/include/firebase/firestore/timestamp.h" + +namespace firebase { +namespace firestore { +namespace model { + +/** + * A version of a document in Firestore. This corresponds to the version + * timestamp, such as update_time or read_time. + */ +class SnapshotVersion { + public: +#if __OBJC__ + SnapshotVersion() { + } +#endif // __OBJC__ + + explicit SnapshotVersion(const Timestamp& timestamp); + + const Timestamp& timestamp() const { + return timestamp_; + } + + /** Creates a new version that is smaller than all other versions. */ + static const SnapshotVersion& None(); + +#if __OBJC__ + size_t Hash() const { + return std::hash{}(timestamp_); + } +#endif // __OBJC__ + + private: + Timestamp timestamp_; +}; + +/** Compares against another SnapshotVersion. */ +inline bool operator<(const SnapshotVersion& lhs, const SnapshotVersion& rhs) { + return lhs.timestamp() < rhs.timestamp(); +} + +inline bool operator>(const SnapshotVersion& lhs, const SnapshotVersion& rhs) { + return lhs.timestamp() > rhs.timestamp(); +} + +inline bool operator>=(const SnapshotVersion& lhs, const SnapshotVersion& rhs) { + return lhs.timestamp() >= rhs.timestamp(); +} + +inline bool operator<=(const SnapshotVersion& lhs, const SnapshotVersion& rhs) { + return lhs.timestamp() <= rhs.timestamp(); +} + +inline bool operator!=(const SnapshotVersion& lhs, const SnapshotVersion& rhs) { + return lhs.timestamp() != rhs.timestamp(); +} + +inline bool operator==(const SnapshotVersion& lhs, const SnapshotVersion& rhs) { + return lhs.timestamp() == rhs.timestamp(); +} + +} // namespace model +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_MODEL_SNAPSHOT_VERSION_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/transform_operations.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/transform_operations.h new file mode 100644 index 0000000..8002907 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/transform_operations.h @@ -0,0 +1,347 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_MODEL_TRANSFORM_OPERATIONS_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_MODEL_TRANSFORM_OPERATIONS_H_ + +#if !defined(__OBJC__) +#error "This header only supports Objective-C++." +#endif // !defined(__OBJC__) + +#include +#include + +#import "Firestore/Source/Model/FSTFieldValue.h" + +#include "Firestore/core/include/firebase/firestore/timestamp.h" + +namespace firebase { +namespace firestore { +namespace model { + +// TODO(zxu123): We might want to refactor transform_operations.h into several +// files when the number of different types of operations grows gigantically. +// For now, put the interface and the only operation here. + +/** Represents a transform within a TransformMutation. */ +class TransformOperation { + public: + /** All the different kinds to TransformOperation. */ + enum class Type { + ServerTimestamp, + ArrayUnion, + ArrayRemove, + Increment, + Test, // Purely for test purpose. + }; + + virtual ~TransformOperation() { + } + + /** Returns the actual type. */ + virtual Type type() const = 0; + + /** + * Computes the local transform result against the provided `previousValue`, + * optionally using the provided localWriteTime. + */ + virtual FSTFieldValue* ApplyToLocalView( + FSTFieldValue* previousValue, FIRTimestamp* localWriteTime) const = 0; + + /** + * Computes a final transform result after the transform has been acknowledged + * by the server, potentially using the server-provided transformResult. + */ + virtual FSTFieldValue* ApplyToRemoteDocument( + FSTFieldValue* previousValue, FSTFieldValue* transformResult) const = 0; + + /** Returns whether this field transform is idempotent. */ + virtual bool idempotent() const = 0; + + /** Returns whether the two are equal. */ + virtual bool operator==(const TransformOperation& other) const = 0; + + /** Returns whether the two are not equal. */ + bool operator!=(const TransformOperation& other) const { + return !operator==(other); + } + + // For Objective-C++ hash; to be removed after migration. + // Do NOT use in C++ code. + virtual NSUInteger Hash() const = 0; +}; + +/** Transforms a value into a server-generated timestamp. */ +class ServerTimestampTransform : public TransformOperation { + public: + Type type() const override { + return Type::ServerTimestamp; + } + + FSTFieldValue* ApplyToLocalView(FSTFieldValue* previousValue, + FIRTimestamp* localWriteTime) const override { + return [FSTServerTimestampValue + serverTimestampValueWithLocalWriteTime:localWriteTime + previousValue:previousValue]; + } + + FSTFieldValue* ApplyToRemoteDocument( + FSTFieldValue* /* previousValue */, + FSTFieldValue* transformResult) const override { + return transformResult; + } + + bool idempotent() const override { + return true; + } + + bool operator==(const TransformOperation& other) const override { + // All ServerTimestampTransform objects are equal. + return other.type() == Type::ServerTimestamp; + } + + static const ServerTimestampTransform& Get() { + static ServerTimestampTransform shared_instance; + return shared_instance; + } + + // For Objective-C++ hash; to be removed after migration. + // Do NOT use in C++ code. + NSUInteger Hash() const override { + // arbitrary number, the same as used in ObjC implementation, since all + // instances are equal. + return 37; + } + + private: + ServerTimestampTransform() { + } +}; + +/** + * Transforms an array via a union or remove operation (for convenience, we use + * this class for both Type::ArrayUnion and Type::ArrayRemove). + */ +class ArrayTransform : public TransformOperation { + public: + ArrayTransform(Type type, std::vector elements) + : type_(type), elements_(std::move(elements)) { + } + + Type type() const override { + return type_; + } + + FSTFieldValue* ApplyToLocalView( + FSTFieldValue* previousValue, + FIRTimestamp* /* localWriteTime */) const override { + return Apply(previousValue); + } + + FSTFieldValue* ApplyToRemoteDocument( + FSTFieldValue* previousValue, + FSTFieldValue* /* transformResult */) const override { + // The server just sends null as the transform result for array operations, + // so we have to calculate a result the same as we do for local + // applications. + return Apply(previousValue); + } + + const std::vector& elements() const { + return elements_; + } + + bool idempotent() const override { + return true; + } + + bool operator==(const TransformOperation& other) const override { + if (other.type() != type()) { + return false; + } + auto array_transform = static_cast(other); + if (array_transform.elements_.size() != elements_.size()) { + return false; + } + for (size_t i = 0; i < elements_.size(); i++) { + if (![array_transform.elements_[i] isEqual:elements_[i]]) { + return false; + } + } + return true; + } + + // For Objective-C++ hash; to be removed after migration. + // Do NOT use in C++ code. + NSUInteger Hash() const override { + NSUInteger result = 37; + result = 31 * result + (type() == Type::ArrayUnion ? 1231 : 1237); + for (FSTFieldValue* element : elements_) { + result = 31 * result + [element hash]; + } + return result; + } + + static const std::vector& Elements( + const TransformOperation& op) { + HARD_ASSERT(op.type() == Type::ArrayUnion || + op.type() == Type::ArrayRemove); + return static_cast(op).elements(); + } + + private: + Type type_; + std::vector elements_; + + /** + * Inspects the provided value, returning a mutable copy of the internal array + * if it's an FSTArrayValue and an empty mutable array if it's nil or any + * other type of FSTFieldValue. + */ + static NSMutableArray* CoercedFieldValuesArray( + FSTFieldValue* value) { + if ([value isMemberOfClass:[FSTArrayValue class]]) { + return [NSMutableArray + arrayWithArray:reinterpret_cast(value).internalValue]; + } else { + // coerce to empty array. + return [NSMutableArray array]; + } + } + + FSTFieldValue* Apply(FSTFieldValue* previousValue) const { + NSMutableArray* result = + ArrayTransform::CoercedFieldValuesArray(previousValue); + for (FSTFieldValue* element : elements_) { + if (type_ == Type::ArrayUnion) { + if (![result containsObject:element]) { + [result addObject:element]; + } + } else { + HARD_ASSERT(type_ == Type::ArrayRemove); + [result removeObject:element]; + } + } + return [[FSTArrayValue alloc] initWithValueNoCopy:result]; + } +}; + +/** + * Implements the backend semantics for locally computed NUMERIC_ADD (increment) + * transforms. Converts all field values to longs or doubles and resolves + * overflows to LONG_MAX/LONG_MIN. + */ +class NumericIncrementTransform : public TransformOperation { + public: + explicit NumericIncrementTransform(FSTNumberValue* operand) + : operand_(operand) { + } + + Type type() const override { + return Type::Increment; + } + + FSTFieldValue* ApplyToLocalView( + FSTFieldValue* previousValue, + FIRTimestamp* /* localWriteTime */) const override { + // Return an integer value only if the previous value and the operand is an + // integer. + if ([previousValue isKindOfClass:[FSTIntegerValue class]] && + [operand_ isKindOfClass:[FSTIntegerValue class]]) { + int64_t sum = SafeIncrement( + (static_cast(previousValue)).internalValue, + (static_cast(operand_)).internalValue); + return [FSTIntegerValue integerValue:sum]; + } else if ([previousValue isKindOfClass:[FSTIntegerValue class]]) { + double sum = + (static_cast(previousValue)).internalValue + + OperandAsDouble(); + return [FSTDoubleValue doubleValue:sum]; + } else if ([previousValue isKindOfClass:[FSTDoubleValue class]]) { + double sum = (static_cast(previousValue)).internalValue + + OperandAsDouble(); + return [FSTDoubleValue doubleValue:sum]; + } else { + // If the existing value is not a number, use the value of the transform + // as the new base value. + return operand_; + } + } + + FSTFieldValue* ApplyToRemoteDocument( + FSTFieldValue*, FSTFieldValue* transformResult) const override { + return transformResult; + } + + FSTNumberValue* operand() const { + return operand_; + } + + bool idempotent() const override { + return false; + } + + bool operator==(const TransformOperation& other) const override { + if (other.type() != type()) { + return false; + } + auto numeric_add = static_cast(other); + return [operand_ isEqual:numeric_add.operand_]; + } + + // For Objective-C++ hash; to be removed after migration. + // Do NOT use in C++ code. + NSUInteger Hash() const override { + NSUInteger result = 37; + result = 31 * result + [operand_ hash]; + return result; + } + + private: + FSTNumberValue* operand_; + + /** + * Implements integer addition. Overflows are resolved to LONG_MAX/LONG_MIN. + */ + int64_t SafeIncrement(int64_t x, int64_t y) const { + if (x > 0 && y > LONG_MAX - x) { + return LONG_MAX; + } + + if (x < 0 && y < LONG_MIN - x) { + return LONG_MIN; + } + + return x + y; + } + + double OperandAsDouble() const { + if ([operand_ isKindOfClass:[FSTDoubleValue class]]) { + return (static_cast(operand_)).internalValue; + } else if ([operand_ isKindOfClass:[FSTIntegerValue class]]) { + return (static_cast(operand_)).internalValue; + } else { + HARD_FAIL("Expected 'operand' to be of FSTNumerValue type, but was %s", + NSStringFromClass([operand_ class])); + } + } +}; + +} // namespace model +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_MODEL_TRANSFORM_OPERATIONS_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/types.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/types.h new file mode 100644 index 0000000..39eb96a --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/types.h @@ -0,0 +1,84 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_MODEL_TYPES_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_MODEL_TYPES_H_ + +#include + +#if defined(__OBJC__) +#import +#endif + +namespace firebase { +namespace firestore { +namespace model { + +/** + * BatchId is a locally assigned identifier for a batch of mutations that have + * been applied by the user but have not yet been fully committed at the server. + */ +using BatchId = int32_t; + +/** + * A sequence number that's incremented on each "interesting" action in the + * local store that establishes the order in which items can be garbage + * collected. + */ +using ListenSequenceNumber = int64_t; + +/** + * TargetId is a stable numeric identifier assigned for a specific query + * applied. + */ +using TargetId = int32_t; + +/** + * Describes the online state of the Firestore client. Note that this does not + * indicate whether or not the remote store is trying to connect or not. This is + * primarily used by the View / EventManager code to change their behavior while + * offline (e.g. get() calls shouldn't wait for data from the server and + * snapshot events should set metadata.isFromCache=true). + */ +enum class OnlineState { + /** + * The Firestore client is in an unknown online state. This means the client + * is either not actively trying to establish a connection or it is currently + * trying to establish a connection, but it has not succeeded or failed yet. + * Higher-level components should not operate in offline mode. + */ + Unknown, + + /** + * The client is connected and the connections are healthy. This state is + * reached after a successful connection and there has been at least one + * successful message received from the backends. + */ + Online, + + /** + * The client is either trying to establish a connection but failing, or it + * has been explicitly marked offline via a call to `disableNetwork`. + * Higher-level components should operate in offline mode. + */ + Offline +}; + +} // namespace model +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_MODEL_TYPES_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/unknown_document.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/unknown_document.cc new file mode 100644 index 0000000..ea42c57 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/unknown_document.cc @@ -0,0 +1,32 @@ +/* + * Copyright 2018 Google + * + * 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 "Firestore/core/src/firebase/firestore/model/unknown_document.h" + +#include + +namespace firebase { +namespace firestore { +namespace model { + +UnknownDocument::UnknownDocument(DocumentKey key, SnapshotVersion version) + : MaybeDocument(std::move(key), std::move(version)) { + set_type(Type::UnknownDocument); +} + +} // namespace model +} // namespace firestore +} // namespace firebase diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/unknown_document.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/unknown_document.h new file mode 100644 index 0000000..fb031c7 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/model/unknown_document.h @@ -0,0 +1,43 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_MODEL_UNKNOWN_DOCUMENT_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_MODEL_UNKNOWN_DOCUMENT_H_ + +#include "Firestore/core/src/firebase/firestore/model/maybe_document.h" + +namespace firebase { +namespace firestore { +namespace model { + +/** + * A class representing an existing document whose data is unknown (e.g. a + * document that was updated without a known base document). + */ +class UnknownDocument : public MaybeDocument { + public: + UnknownDocument(DocumentKey key, SnapshotVersion version); + + bool HasPendingWrites() const override { + return true; + } +}; + +} // namespace model +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_MODEL_UNKNOWN_DOCUMENT_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/nanopb/nanopb_string.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/nanopb/nanopb_string.cc new file mode 100644 index 0000000..9085002 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/nanopb/nanopb_string.cc @@ -0,0 +1,72 @@ +/* + * Copyright 2018 Google + * + * 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 "Firestore/core/src/firebase/firestore/nanopb/nanopb_string.h" + +#include +#include + +#include "Firestore/core/src/firebase/firestore/nanopb/nanopb_util.h" + +namespace firebase { +namespace firestore { +namespace nanopb { + +String::~String() { + std::free(bytes_); +} + +/* static */ pb_bytes_array_t* String::MakeBytesArray(absl::string_view value) { + pb_size_t size = CheckedSize(value.size()); + + // Allocate one extra byte for the null terminator that's not necessarily + // there in a string_view. As long as we're making a copy, might as well + // make a copy that won't overrun when used as a regular C string. This is + // essentially just to make debugging easier--actual user data can have + // embedded nulls so we shouldn't be using this as a C string under normal + // circumstances. + auto result = static_cast( + malloc(PB_BYTES_ARRAY_T_ALLOCSIZE(size) + 1)); + result->size = size; + memcpy(result->bytes, value.data(), size); + result->bytes[size] = '\0'; + + return result; +} + +pb_bytes_array_t* String::release() { + pb_bytes_array_t* result = bytes_; + bytes_ = nullptr; + return result; +} + +void swap(String& lhs, String& rhs) noexcept { + using std::swap; + swap(lhs.bytes_, rhs.bytes_); +} + +/* static */ String String::Wrap(pb_bytes_array_t* bytes) { + return String{bytes}; +} + +/* static */ absl::string_view String::ToStringView(pb_bytes_array_t* bytes) { + const char* str = reinterpret_cast(bytes->bytes); + return absl::string_view{str, bytes->size}; +} + +} // namespace nanopb +} // namespace firestore +} // namespace firebase diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/nanopb/nanopb_string.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/nanopb/nanopb_string.h new file mode 100644 index 0000000..53a9668 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/nanopb/nanopb_string.h @@ -0,0 +1,151 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_NANOPB_NANOPB_STRING_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_NANOPB_NANOPB_STRING_H_ + +#include + +#include +#include + +#include "Firestore/core/src/firebase/firestore/util/comparison.h" +#include "absl/strings/string_view.h" + +namespace firebase { +namespace firestore { +namespace nanopb { + +/** + * A string-like object backed by a nanopb byte array. + */ +class String : public util::Comparable { + public: + /** + * Creates a new, null-terminated byte array that's a copy of the given string + * value. + */ + static pb_bytes_array_t* MakeBytesArray(absl::string_view value); + + String() { + } + + /** + * Creates a new String whose backing byte array is a copy of the of the + * given C string. + */ + explicit String(const char* value) : bytes_{MakeBytesArray(value)} { + } + + /** + * Creates a new String whose backing byte array is a copy of the of the + * given string. + */ + explicit String(const std::string& value) : bytes_{MakeBytesArray(value)} { + } + + /** + * Creates a new String whose backing byte array is a copy of the of the + * given string_view. + */ + explicit String(absl::string_view value) : bytes_{MakeBytesArray(value)} { + } + + String(const String& other) + : bytes_{MakeBytesArray(absl::string_view{other})} { + } + + String(String&& other) noexcept : String{} { + swap(*this, other); + } + + ~String(); + + String& operator=(String other) { + swap(*this, other); + return *this; + } + + /** + * Creates a new String that takes ownership of the given byte array. + */ + static String Wrap(pb_bytes_array_t* bytes); + + bool empty() const { + return !bytes_ || bytes_->size == 0; + } + + /** + * Returns a pointer to the character data backing this String. The return + * value is `nullptr` if the backing bytes are themselves null. + */ + const char* data() const { + return bytes_ ? reinterpret_cast(bytes_->bytes) : nullptr; + } + + /** Returns a const view of the underlying byte array. */ + const pb_bytes_array_t* get() const { + return bytes_; + } + + /** + * Returns the current byte array and assigns the backing byte array to + * nullptr, releasing the ownership of the array contents to the caller. + */ + pb_bytes_array_t* release(); + + /** + * Converts this String to an absl::string_view (without changing ownership). + */ + explicit operator absl::string_view() const { + return ToStringView(bytes_); + } + + /** + * Swaps the contents of the given Strings. + */ + friend void swap(String& lhs, String& rhs) noexcept; + + friend bool operator==(const String& lhs, const String& rhs) { + return absl::string_view{lhs} == absl::string_view{rhs}; + } + friend bool operator<(const String& lhs, const String& rhs) { + return absl::string_view{lhs} < absl::string_view{rhs}; + } + + friend bool operator==(const String& lhs, absl::string_view rhs) { + absl::string_view lhs_view{lhs}; + return lhs_view == rhs; + } + + friend bool operator!=(const String& lhs, absl::string_view rhs) { + return !(lhs == rhs); + } + + private: + explicit String(pb_bytes_array_t* bytes) : bytes_{bytes} { + } + + static absl::string_view ToStringView(pb_bytes_array_t* bytes); + + pb_bytes_array_t* bytes_ = nullptr; +}; + +} // namespace nanopb +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_NANOPB_NANOPB_STRING_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/nanopb/nanopb_util.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/nanopb/nanopb_util.h new file mode 100644 index 0000000..667c28a --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/nanopb/nanopb_util.h @@ -0,0 +1,42 @@ +/* + * Copyright 2019 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_NANOPB_NANOPB_UTIL_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_NANOPB_NANOPB_UTIL_H_ + +#include + +#include "Firestore/core/src/firebase/firestore/util/hard_assert.h" + +namespace firebase { +namespace firestore { +namespace nanopb { + +/** + * Static casts the given size_t value down to a nanopb compatible size, after + * asserting that the value isn't out of range. + */ +inline pb_size_t CheckedSize(size_t size) { + HARD_ASSERT(size <= PB_SIZE_MAX, + "Size exceeds nanopb limits. Too many entries."); + return static_cast(size); +} + +} // namespace nanopb +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_NANOPB_NANOPB_UTIL_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/nanopb/reader.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/nanopb/reader.cc new file mode 100644 index 0000000..d182102 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/nanopb/reader.cc @@ -0,0 +1,49 @@ +/* + * Copyright 2018 Google + * + * 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 "Firestore/core/src/firebase/firestore/nanopb/reader.h" + +namespace firebase { +namespace firestore { +namespace nanopb { + +using firebase::firestore::util::Status; + +Reader Reader::Wrap(const uint8_t* bytes, size_t length) { + return Reader{pb_istream_from_buffer(bytes, length)}; +} + +Reader Reader::Wrap(absl::string_view string_view) { + return Reader{pb_istream_from_buffer( + reinterpret_cast(string_view.data()), + string_view.size())}; +} + +void Reader::ReadNanopbMessage(const pb_field_t fields[], void* dest_struct) { + if (!status_.ok()) return; + + if (!pb_decode(&stream_, fields, dest_struct)) { + Fail(PB_GET_ERROR(&stream_)); + } +} + +void Reader::FreeNanopbMessage(const pb_field_t fields[], void* dest_struct) { + pb_release(fields, dest_struct); +} + +} // namespace nanopb +} // namespace firestore +} // namespace firebase diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/nanopb/reader.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/nanopb/reader.h new file mode 100644 index 0000000..eb95901 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/nanopb/reader.h @@ -0,0 +1,123 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_NANOPB_READER_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_NANOPB_READER_H_ + +#include +#include + +#include "Firestore/core/include/firebase/firestore/firestore_errors.h" +#include "Firestore/core/src/firebase/firestore/util/status.h" +#include "absl/strings/string_view.h" + +namespace firebase { +namespace firestore { +namespace nanopb { + +/** + * Docs TODO(rsgowman). But currently, this just wraps the underlying nanopb + * pb_istream_t. + * + * All 'ReadX' methods verify the wiretype (by examining the last_tag_ field, as + * set by ReadTag()) to ensure the correct type. If that fails, the status of + * the Reader instance is set to non-ok. + */ +class Reader { + public: + /** + * Creates an input stream that reads from the specified bytes. Note that + * this reference must remain valid for the lifetime of this Reader. + * + * (This is roughly equivalent to the nanopb function + * pb_istream_from_buffer()) + * + * @param bytes where the input should be deserialized from. + */ + static Reader Wrap(const uint8_t* bytes, size_t length); + + /** + * Creates an input stream from bytes backing the string_view. Note that + * the backing buffer must remain valid for the lifetime of this Reader. + * + * (This is roughly equivalent to the nanopb function + * pb_istream_from_buffer()) + */ + static Reader Wrap(absl::string_view); + + /** + * Reads a nanopb message from the input stream. + * + * This essentially wraps calls to nanopb's pb_decode() method. This is the + * primary way of decoding messages. + * + * Note that this allocates memory. You must call FreeNanopbMessage() (which + * essentially wraps pb_release()) on the dest_struct in order to avoid memory + * leaks. (This also implies code that uses this is not exception safe.) + */ + // TODO(rsgowman): At the moment we rely on the caller to manually free + // dest_struct via FreeNanopbMessage(). We might instead see if we can + // register allocated messages, track them, and free them ourselves. This may + // be especially relevant if we start to use nanopb messages as the underlying + // data within the model objects. + void ReadNanopbMessage(const pb_field_t fields[], void* dest_struct); + + /** + * Release memory allocated by ReadNanopbMessage(). + * + * This essentially wraps calls to nanopb's pb_release() method. + */ + void FreeNanopbMessage(const pb_field_t fields[], void* dest_struct); + + util::Status status() const { + return status_; + } + + void set_status(util::Status status) { + status_ = status; + } + + /** + * Ensures this Reader's status is `!ok(). + * + * If this Reader's status is already !ok(), then this may augment the + * description, but will otherwise leave it alone. Otherwise, this Reader's + * status will be set to FirestoreErrorCode::DataLoss with the specified + * description. + */ + void Fail(const absl::string_view description) { + status_.Update(util::Status(FirestoreErrorCode::DataLoss, description)); + } + + private: + /** + * Creates a new Reader, based on the given nanopb pb_istream_t. Note that + * a shallow copy will be taken. (Non-null pointers within this struct must + * remain valid for the lifetime of this Reader.) + */ + explicit Reader(pb_istream_t stream) : stream_(stream) { + } + + util::Status status_ = util::Status::OK(); + + pb_istream_t stream_; +}; + +} // namespace nanopb +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_NANOPB_READER_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/nanopb/writer.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/nanopb/writer.cc new file mode 100644 index 0000000..0a28add --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/nanopb/writer.cc @@ -0,0 +1,81 @@ +/* + * Copyright 2018 Google + * + * 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 "Firestore/core/src/firebase/firestore/nanopb/writer.h" + +#include "Firestore/core/src/firebase/firestore/util/hard_assert.h" + +namespace firebase { +namespace firestore { +namespace nanopb { + +namespace { + +// TODO(rsgowman): find a better home for this constant. +// A document is defined to have a max size of 1MiB - 4 bytes. +const size_t kMaxDocumentSize = 1 * 1024 * 1024 - 4; + +/** + * Creates a pb_ostream_t to the specified STL container. Note that this pointer + * must remain valid for the lifetime of the stream. + * + * (This is roughly equivalent to the nanopb function pb_ostream_from_buffer().) + * + * @tparm Container an STL container whose value_type is a char type. + * @param out_container where the output should be serialized to. + */ +template +pb_ostream_t WrapContainer(Container* out_container) { + // Construct a nanopb output stream. + // + // Set the max_size to be the max document size (as an upper bound; one would + // expect individual FieldValue's to be smaller than this). + // + // bytes_written is (always) initialized to 0. (NB: nanopb does not know or + // care about the underlying output vector, so where we are in the vector + // itself is irrelevant. i.e. don't use out_bytes->size()) + return {/*callback=*/[](pb_ostream_t* stream, const pb_byte_t* buf, + size_t count) -> bool { + auto* output = static_cast(stream->state); + output->insert(output->end(), buf, buf + count); + return true; + }, + /*state=*/out_container, + /*max_size=*/kMaxDocumentSize, + /*bytes_written=*/0, + /*errmsg=*/nullptr}; +} + +} // namespace + +Writer Writer::Wrap(std::vector* out_bytes) { + return Writer{WrapContainer(out_bytes)}; +} + +Writer Writer::Wrap(std::string* out_string) { + return Writer{WrapContainer(out_string)}; +} + +void Writer::WriteNanopbMessage(const pb_field_t fields[], + const void* src_struct) { + if (!pb_encode(&stream_, fields, src_struct)) { + HARD_FAIL(PB_GET_ERROR(&stream_)); + } +} + +} // namespace nanopb +} // namespace firestore +} // namespace firebase diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/nanopb/writer.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/nanopb/writer.h new file mode 100644 index 0000000..b910930 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/nanopb/writer.h @@ -0,0 +1,84 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_NANOPB_WRITER_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_NANOPB_WRITER_H_ + +#include +#include + +#include +#include +#include + +namespace firebase { +namespace firestore { +namespace nanopb { + +/** + * Docs TODO(rsgowman). But currently, this just wraps the underlying nanopb + * pb_ostream_t. All errors are considered fatal. + */ +class Writer { + public: + /** + * Creates an output stream that writes to the specified vector. Note that + * this vector pointer must remain valid for the lifetime of this Writer. + * + * (This is roughly equivalent to the nanopb function + * pb_ostream_from_buffer()) + * + * @param out_bytes where the output should be serialized to. + */ + static Writer Wrap(std::vector* out_bytes); + + /** + * Creates an output stream that writes to the specified string. Note that + * this string pointer must remain valid for the lifetime of this Writer. + * + * (This is roughly equivalent to the nanopb function + * pb_ostream_from_buffer()) + * + * @param out_string where the output should be serialized to. + */ + static Writer Wrap(std::string* out_string); + + /** + * Writes a nanopb message to the output stream. + * + * This essentially wraps calls to nanopb's `pb_encode()` method. If we didn't + * use `oneof`s in our protos, this would be the primary way of encoding + * messages. + */ + void WriteNanopbMessage(const pb_field_t fields[], const void* src_struct); + + private: + /** + * Creates a new Writer, based on the given nanopb pb_ostream_t. Note that + * a shallow copy will be taken. (Non-null pointers within this struct must + * remain valid for the lifetime of this Writer.) + */ + explicit Writer(const pb_ostream_t& stream) : stream_(stream) { + } + + pb_ostream_t stream_; +}; + +} // namespace nanopb +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_NANOPB_WRITER_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/connectivity_monitor.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/connectivity_monitor.cc new file mode 100644 index 0000000..924c4d8 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/connectivity_monitor.cc @@ -0,0 +1,45 @@ +/* + * Copyright 2018 Google + * + * 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 "Firestore/core/src/firebase/firestore/remote/connectivity_monitor.h" + +#include "Firestore/core/src/firebase/firestore/util/hard_assert.h" +#include "absl/memory/memory.h" + +namespace firebase { +namespace firestore { +namespace remote { + +void ConnectivityMonitor::SetInitialStatus(NetworkStatus new_status) { + HARD_ASSERT(!status_.has_value(), + "SetInitialStatus should only be called once"); + status_ = new_status; +} + +void ConnectivityMonitor::MaybeInvokeCallbacks(NetworkStatus new_status) { + if (new_status == status_) { + return; + } + status_ = new_status; + + for (auto& callback : callbacks_) { + callback(status_.value()); + } +} + +} // namespace remote +} // namespace firestore +} // namespace firebase diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/connectivity_monitor.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/connectivity_monitor.h new file mode 100644 index 0000000..6f7529c --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/connectivity_monitor.h @@ -0,0 +1,88 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_REMOTE_CONNECTIVITY_MONITOR_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_REMOTE_CONNECTIVITY_MONITOR_H_ + +#include +#include +#include +#include + +#include "Firestore/core/src/firebase/firestore/util/async_queue.h" +#include "absl/types/optional.h" + +namespace firebase { +namespace firestore { +namespace remote { + +/** + * A base class for monitoring changes in network connectivity; it is expected + * that each platform will have its own system-dependent implementation. + */ +class ConnectivityMonitor { + public: + /** + * The set of network states is deliberately simplified -- we only care about + * states such that transition between them should break currently + * established connections. + */ + enum class NetworkStatus { + Unavailable, + Available, + AvailableViaCellular, + }; + + using Callback = std::function; + + /** Creates a platform-specific connectivity monitor. */ + static std::unique_ptr Create( + util::AsyncQueue* worker_queue); + + explicit ConnectivityMonitor(util::AsyncQueue* worker_queue) + : worker_queue_{worker_queue} { + } + + virtual ~ConnectivityMonitor() { + } + + void AddCallback(Callback&& callback) { + callbacks_.push_back(std::move(callback)); + } + // TODO(varconst): RemoveCallback. + + protected: + // The status may be retrieved asynchronously. + void SetInitialStatus(NetworkStatus new_status); + + // Invokes callbacks only if the status changed. + void MaybeInvokeCallbacks(NetworkStatus new_status); + + util::AsyncQueue* queue() { + return worker_queue_; + } + + private: + util::AsyncQueue* worker_queue_ = nullptr; + std::vector callbacks_; + absl::optional status_; +}; + +} // namespace remote +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_REMOTE_CONNECTIVITY_MONITOR_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/connectivity_monitor_apple.mm b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/connectivity_monitor_apple.mm new file mode 100644 index 0000000..f77a331 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/connectivity_monitor_apple.mm @@ -0,0 +1,158 @@ +/* + * Copyright 2018 Google + * + * 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 "Firestore/core/src/firebase/firestore/remote/connectivity_monitor.h" + +#if defined(__APPLE__) + +#include +#include +#include + +#include + +#include "Firestore/core/src/firebase/firestore/util/executor_libdispatch.h" +#include "Firestore/core/src/firebase/firestore/util/hard_assert.h" +#include "Firestore/core/src/firebase/firestore/util/log.h" +#include "absl/memory/memory.h" + +namespace firebase { +namespace firestore { +namespace remote { + +namespace { + +using NetworkStatus = ConnectivityMonitor::NetworkStatus; +using util::AsyncQueue; +using util::ExecutorLibdispatch; + +NetworkStatus ToNetworkStatus(SCNetworkReachabilityFlags flags) { + if (!(flags & kSCNetworkReachabilityFlagsReachable)) { + return NetworkStatus::Unavailable; + } + if (flags & kSCNetworkReachabilityFlagsConnectionRequired) { + return NetworkStatus::Unavailable; + } + +#if TARGET_OS_IPHONE + if (flags & kSCNetworkReachabilityFlagsIsWWAN) { + return NetworkStatus::AvailableViaCellular; + } +#endif + return NetworkStatus::Available; +} + +SCNetworkReachabilityRef CreateReachability() { + // Pseudoaddress that monitors internet reachability in general. + sockaddr_in any_connection_addr{}; + any_connection_addr.sin_len = sizeof(any_connection_addr); + any_connection_addr.sin_family = AF_INET; + return SCNetworkReachabilityCreateWithAddress( + nullptr, reinterpret_cast(&any_connection_addr)); +} + +void OnReachabilityChangedCallback(SCNetworkReachabilityRef /*unused*/, + SCNetworkReachabilityFlags flags, + void* raw_this); + +} // namespace + +/** + * Implementation of `ConnectivityMonitor` based on `SCNetworkReachability` + * (iOS/MacOS). + */ +class ConnectivityMonitorApple : public ConnectivityMonitor { + public: + explicit ConnectivityMonitorApple(AsyncQueue* worker_queue) + : ConnectivityMonitor{worker_queue} { + reachability_ = CreateReachability(); + if (!reachability_) { + LOG_DEBUG("Failed to create reachability monitor."); + return; + } + + SCNetworkReachabilityFlags flags; + if (SCNetworkReachabilityGetFlags(reachability_, &flags)) { + SetInitialStatus(ToNetworkStatus(flags)); + } + + SCNetworkReachabilityContext context{}; + context.info = this; + bool success = SCNetworkReachabilitySetCallback( + reachability_, OnReachabilityChangedCallback, &context); + if (!success) { + LOG_DEBUG("Couldn't set reachability callback"); + return; + } + + // TODO(varconst): 1. Make this at least more robust by adding an enum to + // `Executor` that allows asserting on the actual type before casting. + // 2. This is an unfortunate, brittle mechanism, see if better alternatives + // come up. + // On Apple platforms, the executor implementation must be the + // libdispatch-based one. + auto executor = static_cast(queue()->executor()); + success = SCNetworkReachabilitySetDispatchQueue(reachability_, + executor->dispatch_queue()); + if (!success) { + LOG_DEBUG("Couldn't set reachability queue"); + return; + } + } + + ~ConnectivityMonitorApple() { + if (reachability_) { + bool success = + SCNetworkReachabilitySetDispatchQueue(reachability_, nullptr); + if (!success) { + LOG_DEBUG("Couldn't unset reachability queue"); + } + + CFRelease(reachability_); + } + } + + void OnReachabilityChanged(SCNetworkReachabilityFlags flags) { + queue()->ExecuteBlocking( + [this, flags] { MaybeInvokeCallbacks(ToNetworkStatus(flags)); }); + } + + private: + SCNetworkReachabilityRef reachability_ = nil; +}; + +namespace { + +void OnReachabilityChangedCallback(SCNetworkReachabilityRef /*unused*/, + SCNetworkReachabilityFlags flags, + void* raw_this) { + HARD_ASSERT(raw_this, "Received a null pointer as context"); + static_cast(raw_this)->OnReachabilityChanged( + flags); +} + +} // namespace + +std::unique_ptr ConnectivityMonitor::Create( + AsyncQueue* worker_queue) { + return absl::make_unique(worker_queue); +} + +} // namespace remote +} // namespace firestore +} // namespace firebase + +#endif // defined(__APPLE__) diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/datastore.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/datastore.h new file mode 100644 index 0000000..30ab827 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/datastore.h @@ -0,0 +1,211 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_REMOTE_DATASTORE_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_REMOTE_DATASTORE_H_ + +#if !defined(__OBJC__) +#error "This header only supports Objective-C++" +#endif // !defined(__OBJC__) + +#import + +#include +#include +#include +#include + +#include "Firestore/core/src/firebase/firestore/auth/credentials_provider.h" +#include "Firestore/core/src/firebase/firestore/auth/token.h" +#include "Firestore/core/src/firebase/firestore/core/database_info.h" +#include "Firestore/core/src/firebase/firestore/model/document_key.h" +#include "Firestore/core/src/firebase/firestore/remote/grpc_call.h" +#include "Firestore/core/src/firebase/firestore/remote/grpc_connection.h" +#include "Firestore/core/src/firebase/firestore/remote/remote_objc_bridge.h" +#include "Firestore/core/src/firebase/firestore/remote/watch_stream.h" +#include "Firestore/core/src/firebase/firestore/remote/write_stream.h" +#include "Firestore/core/src/firebase/firestore/util/async_queue.h" +#include "Firestore/core/src/firebase/firestore/util/executor.h" +#include "Firestore/core/src/firebase/firestore/util/status.h" +#include "Firestore/core/src/firebase/firestore/util/statusor.h" +#include "absl/strings/string_view.h" +#include "grpcpp/completion_queue.h" +#include "grpcpp/support/status.h" + +#import "Firestore/Source/Core/FSTTypes.h" + +namespace firebase { +namespace firestore { +namespace remote { + +/** + * `Datastore` represents a proxy for the remote server, hiding details of the + * RPC layer. It: + * + * - Manages connections to the server + * - Authenticates to the server + * - Manages threading and keeps higher-level code running on the worker queue + * - Serializes internal model objects to and from protocol buffers + * + * `Datastore` is generally not responsible for understanding the higher-level + * protocol involved in actually making changes or reading data, and aside from + * the connections it manages is otherwise stateless. + * + * This class is only intended to be inherited from by test mocks. + */ +class Datastore : public std::enable_shared_from_this { + public: + // TODO(varconst): once `FSTMaybeDocument` is replaced with a C++ equivalent, + // this function could take a single `StatusOr` parameter. + using LookupCallback = std::function&, const util::Status&)>; + using CommitCallback = std::function; + + Datastore(const core::DatabaseInfo& database_info, + util::AsyncQueue* worker_queue, + auth::CredentialsProvider* credentials); + + virtual ~Datastore() { + } + + /** Starts polling the gRPC completion queue. */ + void Start(); + /** Cancels any pending gRPC calls and drains the gRPC completion queue. */ + void Shutdown(); + + /** + * Creates a new `WatchStream` that is still unstarted but uses a common + * shared channel. + */ + virtual std::shared_ptr CreateWatchStream( + WatchStreamCallback* callback); + /** + * Creates a new `WriteStream` that is still unstarted but uses a common + * shared channel. + */ + virtual std::shared_ptr CreateWriteStream( + WriteStreamCallback* callback); + + void CommitMutations(const std::vector& mutations, + CommitCallback&& callback); + void LookupDocuments(const std::vector& keys, + LookupCallback&& callback); + + /** Returns true if the given error is a gRPC ABORTED error. */ + static bool IsAbortedError(const util::Status& status); + + /** + * Determines whether an error code represents a permanent error when received + * in response to a non-write operation. + * + * See `IsPermanentWriteError` for classifying write errors. + */ + static bool IsPermanentError(const util::Status& status); + + /** + * Determines whether an error code represents a permanent error when received + * in response to a write operation. + * + * Write operations must be handled specially because as of b/119437764, + * ABORTED errors on the write stream should be retried too (even though + * ABORTED errors are not generally retryable). + * + * Note that during the initial handshake on the write stream an ABORTED error + * signals that we should discard our stream token (i.e. it is permanent). + * This means a handshake error should be classified with `IsPermanentError`, + * above. + */ + static bool IsPermanentWriteError(const util::Status& status); + + static std::string GetWhitelistedHeadersAsString( + const GrpcCall::Metadata& headers); + + Datastore(const Datastore& other) = delete; + Datastore(Datastore&& other) = delete; + Datastore& operator=(const Datastore& other) = delete; + Datastore& operator=(Datastore&& other) = delete; + + protected: + /** Test-only constructor */ + Datastore(const core::DatabaseInfo& database_info, + util::AsyncQueue* worker_queue, + auth::CredentialsProvider* credentials, + std::unique_ptr connectivity_monitor); + + /** Test-only method */ + grpc::CompletionQueue* grpc_queue() { + return &grpc_queue_; + } + /** Test-only method */ + GrpcCall* LastCall() { + return !active_calls_.empty() ? active_calls_.back().get() : nullptr; + } + + /** Test-only getter for mocking */ + GrpcConnection* grpc_connection() { + return &grpc_connection_; + } + + private: + void PollGrpcQueue(); + + void CommitMutationsWithCredentials( + const auth::Token& token, + const std::vector& mutations, + CommitCallback&& callback); + + void LookupDocumentsWithCredentials( + const auth::Token& token, + const std::vector& keys, + LookupCallback&& callback); + void OnLookupDocumentsResponse( + const util::StatusOr>& result, + const LookupCallback& callback); + + using OnCredentials = std::function&)>; + void ResumeRpcWithCredentials(const OnCredentials& on_token); + + void HandleCallStatus(const util::Status& status); + + void RemoveGrpcCall(GrpcCall* to_remove); + + static GrpcCall::Metadata ExtractWhitelistedHeaders( + const GrpcCall::Metadata& headers); + + // In case Auth tries to invoke a callback after `Datastore` has been shut + // down. + bool is_shut_down_ = false; + + util::AsyncQueue* worker_queue_ = nullptr; + auth::CredentialsProvider* credentials_ = nullptr; + + // A separate executor dedicated to polling gRPC completion queue (which is + // shared for all spawned gRPC streams and calls). + std::unique_ptr rpc_executor_; + grpc::CompletionQueue grpc_queue_; + // TODO(varconst): move `ConnectivityMonitor` to `FSTFirestoreClient`. + std::unique_ptr connectivity_monitor_; + GrpcConnection grpc_connection_; + + std::vector> active_calls_; + bridge::DatastoreSerializer serializer_bridge_; +}; + +} // namespace remote +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_REMOTE_DATASTORE_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/datastore.mm b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/datastore.mm new file mode 100644 index 0000000..05806c2 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/datastore.mm @@ -0,0 +1,362 @@ +/* + * Copyright 2018 Google + * + * 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 "Firestore/core/src/firebase/firestore/remote/datastore.h" + +#include +#include + +#import "Firestore/Source/Remote/FSTSerializerBeta.h" + +#include "Firestore/core/include/firebase/firestore/firestore_errors.h" +#include "Firestore/core/src/firebase/firestore/auth/credentials_provider.h" +#include "Firestore/core/src/firebase/firestore/auth/token.h" +#include "Firestore/core/src/firebase/firestore/core/database_info.h" +#include "Firestore/core/src/firebase/firestore/model/database_id.h" +#include "Firestore/core/src/firebase/firestore/model/document_key.h" +#include "Firestore/core/src/firebase/firestore/remote/connectivity_monitor.h" +#include "Firestore/core/src/firebase/firestore/remote/grpc_completion.h" +#include "Firestore/core/src/firebase/firestore/remote/grpc_connection.h" +#include "Firestore/core/src/firebase/firestore/remote/grpc_stream.h" +#include "Firestore/core/src/firebase/firestore/remote/grpc_streaming_reader.h" +#include "Firestore/core/src/firebase/firestore/remote/grpc_unary_call.h" +#include "Firestore/core/src/firebase/firestore/util/async_queue.h" +#include "Firestore/core/src/firebase/firestore/util/error_apple.h" +#include "Firestore/core/src/firebase/firestore/util/executor_libdispatch.h" +#include "Firestore/core/src/firebase/firestore/util/hard_assert.h" +#include "Firestore/core/src/firebase/firestore/util/log.h" +#include "Firestore/core/src/firebase/firestore/util/statusor.h" +#include "absl/memory/memory.h" +#include "absl/strings/str_cat.h" + +namespace firebase { +namespace firestore { +namespace remote { + +using auth::CredentialsProvider; +using auth::Token; +using core::DatabaseInfo; +using model::DocumentKey; +using util::AsyncQueue; +using util::Status; +using util::StatusOr; +using util::Executor; +using util::ExecutorLibdispatch; + +namespace { + +const auto kRpcNameCommit = "/google.firestore.v1.Firestore/Commit"; +const auto kRpcNameLookup = "/google.firestore.v1.Firestore/BatchGetDocuments"; + +std::unique_ptr CreateExecutor() { + auto queue = dispatch_queue_create("com.google.firebase.firestore.rpc", + DISPATCH_QUEUE_SERIAL); + return absl::make_unique(queue); +} + +std::string MakeString(grpc::string_ref grpc_str) { + return {grpc_str.begin(), grpc_str.size()}; +} + +absl::string_view MakeStringView(grpc::string_ref grpc_str) { + return {grpc_str.begin(), grpc_str.size()}; +} + +void LogGrpcCallFinished(absl::string_view rpc_name, + GrpcCall* call, + const Status& status) { + LOG_DEBUG("RPC %s completed. Error: %s: %s", rpc_name, status.code(), + status.error_message()); + if (bridge::IsLoggingEnabled()) { + auto headers = + Datastore::GetWhitelistedHeadersAsString(call->GetResponseHeaders()); + LOG_DEBUG("RPC %s returned headers (whitelisted): %s", rpc_name, headers); + } +} + +} // namespace + +Datastore::Datastore(const DatabaseInfo& database_info, + AsyncQueue* worker_queue, + CredentialsProvider* credentials) + : Datastore{database_info, worker_queue, credentials, + ConnectivityMonitor::Create(worker_queue)} { +} + +Datastore::Datastore(const DatabaseInfo& database_info, + AsyncQueue* worker_queue, + CredentialsProvider* credentials, + std::unique_ptr connectivity_monitor) + : worker_queue_{NOT_NULL(worker_queue)}, + credentials_{credentials}, + rpc_executor_{CreateExecutor()}, + connectivity_monitor_{std::move(connectivity_monitor)}, + grpc_connection_{database_info, worker_queue, &grpc_queue_, + connectivity_monitor_.get()}, + serializer_bridge_{database_info} { + if (!database_info.ssl_enabled()) { + GrpcConnection::UseInsecureChannel(database_info.host()); + } +} + +void Datastore::Start() { + rpc_executor_->Execute([this] { PollGrpcQueue(); }); +} + +void Datastore::Shutdown() { + is_shut_down_ = true; + + // Order matters here: shutting down `grpc_connection_`, which will quickly + // finish any pending gRPC calls, must happen before shutting down the gRPC + // queue. + grpc_connection_.Shutdown(); + + // `grpc::CompletionQueue::Next` will only return `false` once `Shutdown` has + // been called and all submitted tags have been extracted. Without this call, + // `rpc_executor_` will never finish. + grpc_queue_.Shutdown(); + // Drain the executor to make sure it extracted all the operations from gRPC + // completion queue. + rpc_executor_->ExecuteBlocking([] {}); +} + +void Datastore::PollGrpcQueue() { + HARD_ASSERT(rpc_executor_->IsCurrentExecutor(), + "PollGrpcQueue should only be called on the " + "dedicated Datastore executor"); + + void* tag = nullptr; + bool ok = false; + while (grpc_queue_.Next(&tag, &ok)) { + auto completion = static_cast(tag); + // While it's valid in principle, we never deliberately pass a null pointer + // to gRPC completion queue and expect it back. This assertion might be + // relaxed if necessary. + HARD_ASSERT(tag, "gRPC queue returned a null tag"); + completion->Complete(ok); + } +} + +std::shared_ptr Datastore::CreateWatchStream( + WatchStreamCallback* callback) { + return std::make_shared(worker_queue_, credentials_, + serializer_bridge_.GetSerializer(), + &grpc_connection_, callback); +} + +std::shared_ptr Datastore::CreateWriteStream( + WriteStreamCallback* callback) { + return std::make_shared(worker_queue_, credentials_, + serializer_bridge_.GetSerializer(), + &grpc_connection_, callback); +} + +void Datastore::CommitMutations(const std::vector& mutations, + CommitCallback&& callback) { + ResumeRpcWithCredentials( + // TODO(c++14): move into lambda. + [this, mutations, + callback](const StatusOr& maybe_credentials) mutable { + if (!maybe_credentials.ok()) { + callback(maybe_credentials.status()); + return; + } + CommitMutationsWithCredentials(maybe_credentials.ValueOrDie(), + mutations, std::move(callback)); + }); +} + +void Datastore::CommitMutationsWithCredentials( + const Token& token, + const std::vector& mutations, + CommitCallback&& callback) { + grpc::ByteBuffer message = serializer_bridge_.ToByteBuffer( + serializer_bridge_.CreateCommitRequest(mutations)); + + std::unique_ptr call_owning = grpc_connection_.CreateUnaryCall( + kRpcNameCommit, token, std::move(message)); + GrpcUnaryCall* call = call_owning.get(); + active_calls_.push_back(std::move(call_owning)); + + call->Start( + // TODO(c++14): move into lambda. + [this, call, callback](const StatusOr& result) { + LogGrpcCallFinished("CommitRequest", call, result.status()); + HandleCallStatus(result.status()); + + // Response is deliberately ignored + callback(result.status()); + + RemoveGrpcCall(call); + }); +} + +void Datastore::LookupDocuments(const std::vector& keys, + LookupCallback&& callback) { + ResumeRpcWithCredentials( + // TODO(c++14): move into lambda. + [this, keys, callback](const StatusOr& maybe_credentials) mutable { + if (!maybe_credentials.ok()) { + callback({}, maybe_credentials.status()); + return; + } + LookupDocumentsWithCredentials(maybe_credentials.ValueOrDie(), keys, + std::move(callback)); + }); +} + +void Datastore::LookupDocumentsWithCredentials( + const Token& token, + const std::vector& keys, + LookupCallback&& callback) { + grpc::ByteBuffer message = serializer_bridge_.ToByteBuffer( + serializer_bridge_.CreateLookupRequest(keys)); + + std::unique_ptr call_owning = + grpc_connection_.CreateStreamingReader(kRpcNameLookup, token, + std::move(message)); + GrpcStreamingReader* call = call_owning.get(); + active_calls_.push_back(std::move(call_owning)); + + // TODO(c++14): move into lambda. + call->Start([this, call, callback]( + const StatusOr>& result) { + LogGrpcCallFinished("BatchGetDocuments", call, result.status()); + HandleCallStatus(result.status()); + + OnLookupDocumentsResponse(result, callback); + + RemoveGrpcCall(call); + }); +} + +void Datastore::OnLookupDocumentsResponse( + const StatusOr>& result, + const LookupCallback& callback) { + if (!result.ok()) { + callback({}, result.status()); + return; + } + + Status parse_status; + std::vector responses = std::move(result).ValueOrDie(); + std::vector docs = + serializer_bridge_.MergeLookupResponses(responses, &parse_status); + callback(docs, parse_status); +} + +void Datastore::ResumeRpcWithCredentials(const OnCredentials& on_credentials) { + // Auth may outlive Firestore + std::weak_ptr weak_this{shared_from_this()}; + + credentials_->GetToken( + [weak_this, on_credentials](const StatusOr& result) { + auto strong_this = weak_this.lock(); + if (!strong_this) { + return; + } + + strong_this->worker_queue_->EnqueueRelaxed( + [weak_this, result, on_credentials] { + auto strong_this = weak_this.lock(); + if (!strong_this) { + return; + } + // In case Auth callback is invoked after Datastore has been shut + // down. + if (strong_this->is_shut_down_) { + return; + } + + on_credentials(result); + }); + }); +} + +void Datastore::HandleCallStatus(const Status& status) { + if (status.code() == FirestoreErrorCode::Unauthenticated) { + credentials_->InvalidateToken(); + } +} + +void Datastore::RemoveGrpcCall(GrpcCall* to_remove) { + auto found = std::find_if(active_calls_.begin(), active_calls_.end(), + [to_remove](const std::unique_ptr& call) { + return call.get() == to_remove; + }); + HARD_ASSERT(found != active_calls_.end(), "Missing gRPC call"); + active_calls_.erase(found); +} + +bool Datastore::IsAbortedError(const Status& error) { + return error.code() == FirestoreErrorCode::Aborted; +} + +bool Datastore::IsPermanentError(const Status& error) { + switch (error.code()) { + case FirestoreErrorCode::Ok: + HARD_FAIL("Treated status OK as error"); + case FirestoreErrorCode::Cancelled: + case FirestoreErrorCode::Unknown: + case FirestoreErrorCode::DeadlineExceeded: + case FirestoreErrorCode::ResourceExhausted: + case FirestoreErrorCode::Internal: + case FirestoreErrorCode::Unavailable: + // Unauthenticated means something went wrong with our token and we need + // to retry with new credentials which will happen automatically. + case FirestoreErrorCode::Unauthenticated: + return false; + case FirestoreErrorCode::InvalidArgument: + case FirestoreErrorCode::NotFound: + case FirestoreErrorCode::AlreadyExists: + case FirestoreErrorCode::PermissionDenied: + case FirestoreErrorCode::FailedPrecondition: + case FirestoreErrorCode::Aborted: + // Aborted might be retried in some scenarios, but that is dependant on + // the context and should handled individually by the calling code. + // See https://cloud.google.com/apis/design/errors + case FirestoreErrorCode::OutOfRange: + case FirestoreErrorCode::Unimplemented: + case FirestoreErrorCode::DataLoss: + return true; + } + + HARD_FAIL("Unknown status code: %s", error.code()); +} + +bool Datastore::IsPermanentWriteError(const Status& error) { + return IsPermanentError(error) && !IsAbortedError(error); +} + +std::string Datastore::GetWhitelistedHeadersAsString( + const GrpcCall::Metadata& headers) { + static std::unordered_set whitelist = { + "date", "x-google-backends", "x-google-netmon-label", "x-google-service", + "x-google-gfe-request-trace"}; + + std::string result; + for (const auto& kv : headers) { + if (whitelist.find(MakeString(kv.first)) != whitelist.end()) { + absl::StrAppend(&result, MakeStringView(kv.first), ": ", + MakeStringView(kv.second), "\n"); + } + } + return result; +} + +} // namespace remote +} // namespace firestore +} // namespace firebase diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/existence_filter.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/existence_filter.h new file mode 100644 index 0000000..2f3de41 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/existence_filter.h @@ -0,0 +1,46 @@ +/* + * Copyright 2019 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_REMOTE_EXISTENCE_FILTER_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_REMOTE_EXISTENCE_FILTER_H_ + +namespace firebase { +namespace firestore { +namespace remote { + +class ExistenceFilter { + public: + ExistenceFilter() = default; + explicit ExistenceFilter(int count) : count_{count} { + } + + int count() const { + return count_; + } + + private: + int count_ = 0; +}; + +inline bool operator==(const ExistenceFilter& lhs, const ExistenceFilter& rhs) { + return lhs.count() == rhs.count(); +} + +} // namespace remote +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_REMOTE_EXISTENCE_FILTER_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/exponential_backoff.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/exponential_backoff.cc new file mode 100644 index 0000000..d93d081 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/exponential_backoff.cc @@ -0,0 +1,111 @@ +/* + * Copyright 2018 Google + * + * 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 "Firestore/core/src/firebase/firestore/remote/exponential_backoff.h" + +#include +#include +#include + +#include "Firestore/core/src/firebase/firestore/util/hard_assert.h" +#include "Firestore/core/src/firebase/firestore/util/log.h" + +namespace firebase { +namespace firestore { +namespace remote { + +using firebase::firestore::util::AsyncQueue; +using firebase::firestore::util::TimerId; +namespace chr = std::chrono; + +ExponentialBackoff::ExponentialBackoff(AsyncQueue* queue, + TimerId timer_id, + double backoff_factor, + Milliseconds initial_delay, + Milliseconds max_delay) + : queue_{queue}, + timer_id_{timer_id}, + backoff_factor_{backoff_factor}, + initial_delay_{initial_delay}, + max_delay_{max_delay}, + last_attempt_time_{chr::steady_clock::now()} { + HARD_ASSERT(queue, "Queue can't be null"); + + HARD_ASSERT(backoff_factor >= 1.0, "Backoff factor must be at least 1"); + + HARD_ASSERT(initial_delay.count() >= 0, "Delays must be non-negative"); + HARD_ASSERT(max_delay.count() >= 0, "Delays must be non-negative"); + HARD_ASSERT(initial_delay <= max_delay, + "Initial delay can't be greater than max delay"); +} + +void ExponentialBackoff::BackoffAndRun(AsyncQueue::Operation&& operation) { + Cancel(); + + // First schedule the block using the current base (which may be 0 and should + // be honored as such). + Milliseconds desired_delay_with_jitter = current_base_ + GetDelayWithJitter(); + + Milliseconds delay_so_far = chr::duration_cast( + chr::steady_clock::now() - last_attempt_time_); + + // Guard against the backoff delay already being past. + auto remaining_delay = + std::max(Milliseconds::zero(), desired_delay_with_jitter - delay_so_far); + + if (current_base_.count() > 0) { + LOG_DEBUG( + "Backing off for %s ms " + "(base delay: %s ms, " + "delay with jitter: %s ms, " + "last attempt: %s ms ago)", + remaining_delay.count(), current_base_.count(), + desired_delay_with_jitter.count(), delay_so_far.count()); + } + + delayed_operation_ = + queue_->EnqueueAfterDelay(remaining_delay, timer_id_, [this, operation] { + last_attempt_time_ = chr::steady_clock::now(); + operation(); + }); + + // Apply backoff factor to determine next delay, but ensure it is within + // bounds. + current_base_ = ClampDelay( + chr::duration_cast(current_base_ * backoff_factor_)); +} + +ExponentialBackoff::Milliseconds ExponentialBackoff::GetDelayWithJitter() { + std::uniform_real_distribution distribution; + double random_double = distribution(secure_random_); + return chr::duration_cast((random_double - 0.5) * + current_base_); +} + +ExponentialBackoff::Milliseconds ExponentialBackoff::ClampDelay( + Milliseconds delay) const { + if (delay < initial_delay_) { + return initial_delay_; + } + if (delay > max_delay_) { + return max_delay_; + } + return delay; +} + +} // namespace remote +} // namespace firestore +} // namespace firebase diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/exponential_backoff.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/exponential_backoff.h new file mode 100644 index 0000000..de2418c --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/exponential_backoff.h @@ -0,0 +1,117 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_REMOTE_EXPONENTIAL_BACKOFF_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_REMOTE_EXPONENTIAL_BACKOFF_H_ + +#include // NOLINT(build/c++11) + +#include "Firestore/core/src/firebase/firestore/util/async_queue.h" +#include "Firestore/core/src/firebase/firestore/util/secure_random.h" + +namespace firebase { +namespace firestore { +namespace remote { + +/** + * + * A helper for running delayed operations following an exponential backoff + * curve between attempts. + * + * The first attempt will be done immediately. After that, each retry will + * have a delay that is made up of a "base" delay which follows the + * exponential backoff curve, and a +/- <=50% "jitter" that is calculated and + * added to the base delay. This prevents clients from accidentally + * synchronizing their delays causing spikes of load to the backend. + * + */ +class ExponentialBackoff { + public: + /** + * @param queue The queue to run operations on. + * @param timer_id The id to use when scheduling backoff operations on the + * queue. + * @param backoff_factor The multiplier to use to determine the extended base + * delay after each attempt. + * @param initial_delay The initial delay (used as the base delay on the first + * retry attempt, that is, the second attempt). Note that jitter will + * still be applied, so the actual delay could be as little as + * `0.5*initial_delay`. + * @param max_delay The maximum base delay after which no further backoff is + * performed. Note that jitter will still be applied, so the actual delay + * could be as much as `1.5*max_delay`. + */ + ExponentialBackoff(util::AsyncQueue* queue, + util::TimerId timer_id, + double backoff_factor, + util::AsyncQueue::Milliseconds initial_delay, + util::AsyncQueue::Milliseconds max_delay); + + /** + * Resets the backoff delay. + * + * The very next `backoffAndRun` will have no delay. If it is called again + * (i.e. due to an error), `initial_delay` (plus jitter) will be used, and + * subsequent ones will increase according to the `backoff_factor`. + */ + void Reset() { + current_base_ = Milliseconds{0}; + } + + /** + * Resets the backoff to the maximum delay (e.g. for use after + * a RESOURCE_EXHAUSTED error). + */ + void ResetToMax() { + current_base_ = max_delay_; + } + + /** + * Waits for `current_base` seconds (which may be zero), increases the delay + * and runs the specified operation. If there was a pending operation waiting + * to be run already, it will be canceled. + */ + void BackoffAndRun(util::AsyncQueue::Operation&& operation); + + /** Cancels any pending backoff operation scheduled via `BackoffAndRun`. */ + void Cancel() { + delayed_operation_.Cancel(); + } + + private: + using Milliseconds = util::AsyncQueue::Milliseconds; + + // Returns a random value in the range [-current_base_/2, current_base_/2]. + Milliseconds GetDelayWithJitter(); + Milliseconds ClampDelay(Milliseconds delay) const; + + util::AsyncQueue* const queue_; + const util::TimerId timer_id_; + util::DelayedOperation delayed_operation_; + + const double backoff_factor_; + Milliseconds current_base_{0}; + const Milliseconds initial_delay_; + const Milliseconds max_delay_; + util::SecureRandom secure_random_; + std::chrono::steady_clock::time_point last_attempt_time_; +}; + +} // namespace remote +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_REMOTE_EXPONENTIAL_BACKOFF_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/grpc_call.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/grpc_call.h new file mode 100644 index 0000000..6cd0c33 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/grpc_call.h @@ -0,0 +1,68 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_REMOTE_GRPC_CALL_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_REMOTE_GRPC_CALL_H_ + +#include + +#include "Firestore/core/src/firebase/firestore/util/status.h" +#include "grpcpp/client_context.h" +#include "grpcpp/support/string_ref.h" + +namespace firebase { +namespace firestore { +namespace remote { + +/** + * Contains operations common to all wrappers over gRPC calls. A wrapper is + * presumed to: + * - wrap an asynchronous gRPC call/stream; + * - provide some notification mechanism (such as observers or callbacks). + */ +class GrpcCall { + public: + using Metadata = std::multimap; + + virtual ~GrpcCall() { + } + + /** + * Returns the metadata received from the server. + * + * Can only be called after the first response has been received from the + * server. + */ + virtual Metadata GetResponseHeaders() const = 0; + + /** + * Finishes the call gracefully. Doesn't produce a notification to any + * callbacks or observers. + */ + virtual void FinishImmediately() = 0; + + /** Finishes the call with an error, notifying any callbacks and observers. */ + virtual void FinishAndNotify(const util::Status& status) = 0; + + /** For tests only */ + virtual grpc::ClientContext* context() = 0; +}; + +} // namespace remote +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_REMOTE_GRPC_CALL_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/grpc_completion.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/grpc_completion.cc new file mode 100644 index 0000000..18574aa --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/grpc_completion.cc @@ -0,0 +1,75 @@ +/* + * Copyright 2018 Google + * + * 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 "Firestore/core/src/firebase/firestore/remote/grpc_completion.h" + +#include + +namespace firebase { +namespace firestore { +namespace remote { + +using util::AsyncQueue; + +GrpcCompletion::GrpcCompletion(Type type, + AsyncQueue* worker_queue, + Callback&& callback) + : worker_queue_{worker_queue}, callback_{std::move(callback)}, type_{type} { +} + +void GrpcCompletion::Cancel() { + worker_queue_->VerifyIsCurrentQueue(); + callback_ = {}; +} + +void GrpcCompletion::WaitUntilOffQueue() { + worker_queue_->VerifyIsCurrentQueue(); + + EnsureValidFuture(); + return off_queue_future_.wait(); +} + +std::future_status GrpcCompletion::WaitUntilOffQueue( + std::chrono::milliseconds timeout) { + worker_queue_->VerifyIsCurrentQueue(); + + EnsureValidFuture(); + return off_queue_future_.wait_for(timeout); +} + +void GrpcCompletion::EnsureValidFuture() { + if (!off_queue_future_.valid()) { + off_queue_future_ = off_queue_.get_future(); + } +} + +void GrpcCompletion::Complete(bool ok) { + // This mechanism allows `GrpcStream` to know when the completion is off the + // gRPC completion queue (and thus no longer requires the underlying gRPC + // objects to be valid). + off_queue_.set_value(); + + worker_queue_->Enqueue([this, ok] { + if (callback_) { + callback_(ok, this); + } + delete this; + }); +} + +} // namespace remote +} // namespace firestore +} // namespace firebase diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/grpc_completion.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/grpc_completion.h new file mode 100644 index 0000000..17641ba --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/grpc_completion.h @@ -0,0 +1,140 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_REMOTE_GRPC_COMPLETION_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_REMOTE_GRPC_COMPLETION_H_ + +#include // NOLINT(build/c++11) +#include +#include // NOLINT(build/c++11) +#include + +#include "Firestore/core/src/firebase/firestore/util/async_queue.h" +#include "Firestore/core/src/firebase/firestore/util/status.h" +#include "grpcpp/support/byte_buffer.h" + +namespace firebase { +namespace firestore { +namespace remote { + +/** + * A completion for a gRPC asynchronous operation that runs an arbitrary + * callback. + * + * All created `GrpcCompletion`s are expected to be put on the gRPC completion + * queue (as "tags"). `GrpcCompletion` expects that once it's received back from + * the gRPC completion queue, `Complete` will be called on it. `Complete` + * doesn't run the given callback immediately when taken off the queue; rather, + * it schedules running the callback on the worker queue. If the callback is no + * longer relevant, calling `Cancel` on the `GrpcCompletion` will turn the + * callback into a no-op. + * + * `GrpcCompletion` owns the objects that are used by gRPC operations for output + * (a `ByteBuffer` for reading a new message and a `Status` for finish + * operation). The buffer and/or the status may be unused by the corresponding + * gRPC operation. + * + * `GrpcCompletion` is "self-owned"; `GrpcCompletion` deletes itself in its + * `Complete` method. + * + * `GrpcCompletion` expects all gRPC objects pertaining to the current stream to + * remain valid until the `GrpcCompletion` comes back from the gRPC completion + * queue. + */ +class GrpcCompletion { + public: + /** + * This is only to aid debugging and testing; type allows easily + * distinguishing between pending completions of a gRPC call. + */ + enum class Type { Start, Read, Write, Finish }; + + /** + * The boolean parameter is used to indicate whether the corresponding gRPC + * operation finished successfully or not. + * + * The `GrpcCompletion` pointer will always point to `this`. + */ + using Callback = std::function; + + GrpcCompletion(Type type, + util::AsyncQueue* firestore_queue, + Callback&& callback); + + /** + * Marks the `GrpcCompletion` as having come back from the gRPC completion + * queue and puts notifying the observing stream on the Firestore async queue. + * The given `ok` value indicates whether the corresponding gRPC operation + * completed successfully. + * + * This function deletes the `GrpcCompletion`. + * + * Must be called outside of Firestore async queue. + */ + void Complete(bool ok); + + void Cancel(); + + /** + * Blocks until the `GrpcCompletion` comes back from the gRPC completion + * queue. It is important to only call this function when the `GrpcCompletion` + * is sure to come back from the queue quickly. + */ + void WaitUntilOffQueue(); + std::future_status WaitUntilOffQueue(std::chrono::milliseconds timeout); + + grpc::ByteBuffer* message() { + return &message_; + } + const grpc::ByteBuffer* message() const { + return &message_; + } + grpc::Status* status() { + return &status_; + } + const grpc::Status* status() const { + return &status_; + } + + Type type() const { + return type_; + } + + private: + util::AsyncQueue* worker_queue_ = nullptr; + Callback callback_; + + void EnsureValidFuture(); + + // Note that even though `grpc::GenericClientAsyncReaderWriter::Write` takes + // the byte buffer by const reference, it expects the buffer's lifetime to + // extend beyond `Write` (the buffer must be valid until the completion queue + // returns the tag associated with the write, see + // https://github.com/grpc/grpc/issues/13019#issuecomment-336932929, #5). + grpc::ByteBuffer message_; + grpc::Status status_; + + std::promise off_queue_; + std::future off_queue_future_; + + Type type_{}; +}; + +} // namespace remote +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_REMOTE_GRPC_COMPLETION_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/grpc_connection.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/grpc_connection.cc new file mode 100644 index 0000000..55ee82b --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/grpc_connection.cc @@ -0,0 +1,263 @@ +/* + * Copyright 2018 Google + * + * 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 "Firestore/core/src/firebase/firestore/remote/grpc_connection.h" + +#include +#include +#include + +#include "Firestore/core/include/firebase/firestore/firestore_errors.h" +#include "Firestore/core/include/firebase/firestore/firestore_version.h" +#include "Firestore/core/src/firebase/firestore/auth/token.h" +#include "Firestore/core/src/firebase/firestore/model/database_id.h" +#include "Firestore/core/src/firebase/firestore/remote/grpc_root_certificate_finder.h" +#include "Firestore/core/src/firebase/firestore/util/filesystem.h" +#include "Firestore/core/src/firebase/firestore/util/hard_assert.h" +#include "Firestore/core/src/firebase/firestore/util/log.h" +#include "Firestore/core/src/firebase/firestore/util/string_format.h" +#include "absl/memory/memory.h" +#include "grpcpp/create_channel.h" + +namespace firebase { +namespace firestore { +namespace remote { + +using auth::Token; +using core::DatabaseInfo; +using model::DatabaseId; +using util::Path; +using util::Status; +using util::StatusOr; +using util::StringFormat; + +namespace { + +const char* const kXGoogAPIClientHeader = "x-goog-api-client"; +const char* const kGoogleCloudResourcePrefix = "google-cloud-resource-prefix"; + +std::string MakeString(absl::string_view view) { + return view.data() ? std::string{view.data(), view.size()} : std::string{}; +} + +std::shared_ptr CreateSslCredentials( + const std::string& certificate) { + grpc::SslCredentialsOptions options; + options.pem_root_certs = certificate; + return grpc::SslCredentials(options); +} + +struct HostConfig { + util::Path certificate_path; + std::string target_name; + bool use_insecure_channel = false; +}; + +using ConfigByHost = std::unordered_map; + +ConfigByHost& Config() { + static ConfigByHost config_by_host_; + return config_by_host_; +} + +bool HasSpecialConfig(const std::string& host) { + return Config().find(host) != Config().end(); +} + +} // namespace + +GrpcConnection::GrpcConnection(const DatabaseInfo& database_info, + util::AsyncQueue* worker_queue, + grpc::CompletionQueue* grpc_queue, + ConnectivityMonitor* connectivity_monitor) + : database_info_{&database_info}, + worker_queue_{NOT_NULL(worker_queue)}, + grpc_queue_{NOT_NULL(grpc_queue)}, + connectivity_monitor_{NOT_NULL(connectivity_monitor)} { + RegisterConnectivityMonitor(); +} + +void GrpcConnection::Shutdown() { + // Fast finish any pending calls. This will not trigger the observers. + // Calls may unregister themselves on finish, so make a protective copy. + auto active_calls = active_calls_; + for (GrpcCall* call : active_calls) { + call->FinishImmediately(); + } +} + +std::unique_ptr GrpcConnection::CreateContext( + const Token& credential) const { + absl::string_view token = credential.user().is_authenticated() + ? credential.token() + : absl::string_view{}; + + auto context = absl::make_unique(); + if (token.data()) { + context->set_credentials(grpc::AccessTokenCredentials(MakeString(token))); + } + + // TODO(dimond): This should ideally also include the gRPC version, however, + // gRPC defines the version as a macro, so it would be hardcoded based on + // version we have at compile time of the Firestore library, rather than the + // version available at runtime/at compile time by the user of the library. + // + // TODO(varconst): this should be configurable (e.g., "gl-cpp" or similar for + // C++ SDK, etc.). + context->AddMetadata( + kXGoogAPIClientHeader, + StringFormat("gl-objc/ fire/%s grpc/", kFirestoreVersionString)); + + // This header is used to improve routing and project isolation by the + // backend. + const DatabaseId& db_id = database_info_->database_id(); + context->AddMetadata(kGoogleCloudResourcePrefix, + StringFormat("projects/%s/databases/%s", + db_id.project_id(), db_id.database_id())); + return context; +} + +void GrpcConnection::EnsureActiveStub() { + // TODO(varconst): find out in which cases a gRPC channel might shut down. + // This might be overkill. + if (!grpc_channel_ || grpc_channel_->GetState(/*try_to_connect=*/false) == + GRPC_CHANNEL_SHUTDOWN) { + LOG_DEBUG("Creating Firestore stub."); + grpc_channel_ = CreateChannel(); + grpc_stub_ = absl::make_unique(grpc_channel_); + } +} + +std::shared_ptr GrpcConnection::CreateChannel() const { + const std::string& host = database_info_->host(); + + if (!HasSpecialConfig(host)) { + std::string root_certificate = LoadGrpcRootCertificate(); + return grpc::CreateChannel(host, CreateSslCredentials(root_certificate)); + } + + const HostConfig& host_config = Config()[host]; + + // For the case when `Settings.sslEnabled == false`. + if (host_config.use_insecure_channel) { + return grpc::CreateChannel(host, grpc::InsecureChannelCredentials()); + } + + // For tests only + grpc::ChannelArguments args; + args.SetSslTargetNameOverride(host_config.target_name); + Path path = host_config.certificate_path; + StatusOr test_certificate = ReadFile(path); + HARD_ASSERT(test_certificate.ok(), + StringFormat("Unable to open root certificates at file path %s", + path.ToUtf8String()) + .c_str()); + + return grpc::CreateCustomChannel( + host, CreateSslCredentials(test_certificate.ValueOrDie()), args); +} + +std::unique_ptr GrpcConnection::CreateStream( + absl::string_view rpc_name, + const Token& token, + GrpcStreamObserver* observer) { + EnsureActiveStub(); + + auto context = CreateContext(token); + auto call = + grpc_stub_->PrepareCall(context.get(), MakeString(rpc_name), grpc_queue_); + return absl::make_unique(std::move(context), std::move(call), + worker_queue_, this, observer); +} + +std::unique_ptr GrpcConnection::CreateUnaryCall( + absl::string_view rpc_name, + const Token& token, + const grpc::ByteBuffer& message) { + EnsureActiveStub(); + + auto context = CreateContext(token); + auto call = grpc_stub_->PrepareUnaryCall(context.get(), MakeString(rpc_name), + message, grpc_queue_); + return absl::make_unique(std::move(context), std::move(call), + worker_queue_, this, message); +} + +std::unique_ptr GrpcConnection::CreateStreamingReader( + absl::string_view rpc_name, + const Token& token, + const grpc::ByteBuffer& message) { + EnsureActiveStub(); + + auto context = CreateContext(token); + auto call = + grpc_stub_->PrepareCall(context.get(), MakeString(rpc_name), grpc_queue_); + return absl::make_unique( + std::move(context), std::move(call), worker_queue_, this, message); +} + +void GrpcConnection::RegisterConnectivityMonitor() { + connectivity_monitor_->AddCallback( + [this](ConnectivityMonitor::NetworkStatus /*ignored*/) { + // Calls may unregister themselves on finish, so make a protective copy. + auto calls = active_calls_; + for (GrpcCall* call : calls) { + // This will trigger the observers. + call->FinishAndNotify(Status{FirestoreErrorCode::Unavailable, + "Network connectivity changed"}); + } + // The old channel may hang for a long time trying to reestablish + // connection before eventually failing. Note that gRPC Objective-C + // client does the same thing: + // https://github.com/grpc/grpc/blob/fe11db09575f2dfbe1f88cd44bd417acc168e354/src/objective-c/GRPCClient/private/GRPCHost.m#L309-L314 + grpc_channel_.reset(); + }); +} + +void GrpcConnection::Register(GrpcCall* call) { + active_calls_.push_back(call); +} + +void GrpcConnection::Unregister(GrpcCall* call) { + auto found = std::find(active_calls_.begin(), active_calls_.end(), call); + HARD_ASSERT(found != active_calls_.end(), "Missing a gRPC call"); + active_calls_.erase(found); +} + +/*static*/ void GrpcConnection::UseTestCertificate( + const std::string& host, + const Path& certificate_path, + const std::string& target_name) { + HARD_ASSERT(!host.empty(), "Empty host name"); + HARD_ASSERT(!certificate_path.native_value().empty(), + "Empty path to test certificate"); + HARD_ASSERT(!target_name.empty(), "Empty SSL target name"); + + HostConfig& host_config = Config()[host]; + host_config.certificate_path = certificate_path; + host_config.target_name = target_name; +} + +/*static*/ void GrpcConnection::UseInsecureChannel(const std::string& host) { + HARD_ASSERT(!host.empty(), "Empty host name"); + + HostConfig& host_config = Config()[host]; + host_config.use_insecure_channel = true; +} + +} // namespace remote +} // namespace firestore +} // namespace firebase diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/grpc_connection.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/grpc_connection.h new file mode 100644 index 0000000..8d201f4 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/grpc_connection.h @@ -0,0 +1,125 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_REMOTE_GRPC_CONNECTION_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_REMOTE_GRPC_CONNECTION_H_ + +#include +#include +#include +#include + +#include "Firestore/core/src/firebase/firestore/util/warnings.h" + +#include "Firestore/core/src/firebase/firestore/auth/token.h" +#include "Firestore/core/src/firebase/firestore/core/database_info.h" +#include "Firestore/core/src/firebase/firestore/remote/connectivity_monitor.h" +#include "Firestore/core/src/firebase/firestore/remote/grpc_call.h" +#include "Firestore/core/src/firebase/firestore/remote/grpc_stream.h" +#include "Firestore/core/src/firebase/firestore/remote/grpc_stream_observer.h" +#include "Firestore/core/src/firebase/firestore/remote/grpc_streaming_reader.h" +#include "Firestore/core/src/firebase/firestore/remote/grpc_unary_call.h" +#include "Firestore/core/src/firebase/firestore/util/path.h" +#include "absl/strings/string_view.h" +#include "grpcpp/channel.h" +#include "grpcpp/client_context.h" +#include "grpcpp/completion_queue.h" +SUPPRESS_DOCUMENTATION_WARNINGS_BEGIN() +#include "grpcpp/generic/generic_stub.h" +SUPPRESS_END() + +namespace firebase { +namespace firestore { +namespace remote { + +// PORTING NOTE: this class has limited resemblance to `GrpcConnection` in Web +// client. However, unlike Web client, it's not meant to hide different +// implementations of a `Connection` under a single interface. + +/** + * Creates and owns gRPC objects (channel and stub) necessary to produce a + * `GrpcStream`. + */ +class GrpcConnection { + public: + GrpcConnection(const core::DatabaseInfo& database_info, + util::AsyncQueue* worker_queue, + grpc::CompletionQueue* grpc_queue, + ConnectivityMonitor* connectivity_monitor); + + void Shutdown(); + + /** + * Creates a stream to the given stream RPC endpoint. The resulting stream + * needs to be `Start`ed before it can be used. + */ + // PORTING NOTE: unlike Web client, the created stream is not open and has to + // be started manually. + std::unique_ptr CreateStream(absl::string_view rpc_name, + const auth::Token& token, + GrpcStreamObserver* observer); + + std::unique_ptr CreateUnaryCall( + absl::string_view rpc_name, + const auth::Token& token, + const grpc::ByteBuffer& message); + + std::unique_ptr CreateStreamingReader( + absl::string_view rpc_name, + const auth::Token& token, + const grpc::ByteBuffer& message); + + void Register(GrpcCall* call); + void Unregister(GrpcCall* call); + + /** + * Don't use SSL, send all traffic unencrypted. Call before creating any + * streams or calls. + */ + static void UseInsecureChannel(const std::string& host); + + /** + * For tests only: use a custom root certificate file and the given SSL + * target name for all connections. Call before creating any streams or calls. + */ + static void UseTestCertificate(const std::string& host, + const util::Path& certificate_path, + const std::string& target_name); + + private: + std::unique_ptr CreateContext( + const auth::Token& credential) const; + std::shared_ptr CreateChannel() const; + void EnsureActiveStub(); + + void RegisterConnectivityMonitor(); + + const core::DatabaseInfo* database_info_ = nullptr; + util::AsyncQueue* worker_queue_ = nullptr; + grpc::CompletionQueue* grpc_queue_ = nullptr; + + std::shared_ptr grpc_channel_; + std::unique_ptr grpc_stub_; + + ConnectivityMonitor* connectivity_monitor_ = nullptr; + std::vector active_calls_; +}; + +} // namespace remote +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_REMOTE_GRPC_CONNECTION_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/grpc_root_certificate_finder.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/grpc_root_certificate_finder.h new file mode 100644 index 0000000..2d1104e --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/grpc_root_certificate_finder.h @@ -0,0 +1,39 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_REMOTE_GRPC_ROOT_CERTIFICATE_FINDER_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_REMOTE_GRPC_ROOT_CERTIFICATE_FINDER_H_ + +#include + +#include "Firestore/core/src/firebase/firestore/util/path.h" + +namespace firebase { +namespace firestore { +namespace remote { + +/** + * Finds the file containing gRPC root certificates (how it is stored differs by + * platform) and returns its contents as a string. Will trigger assertion + * failure if the file cannot be found or open. + */ +std::string LoadGrpcRootCertificate(); + +} // namespace remote +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_REMOTE_GRPC_ROOT_CERTIFICATE_FINDER_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/grpc_root_certificate_finder_apple.mm b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/grpc_root_certificate_finder_apple.mm new file mode 100644 index 0000000..b7e0db4 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/grpc_root_certificate_finder_apple.mm @@ -0,0 +1,154 @@ +/* + * Copyright 2018 Google + * + * 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 "Firestore/core/src/firebase/firestore/remote/grpc_root_certificate_finder.h" + +#import + +#include + +#include "Firestore/core/src/firebase/firestore/util/filesystem.h" +#include "Firestore/core/src/firebase/firestore/util/hard_assert.h" +#include "Firestore/core/src/firebase/firestore/util/log.h" +#include "Firestore/core/src/firebase/firestore/util/statusor.h" +#include "absl/strings/str_cat.h" + +namespace firebase { +namespace firestore { +namespace remote { + +using util::Path; +using util::ReadFile; +using util::StatusOr; +using util::StringFormat; + +namespace { + +/** + * Finds the roots.pem certificate file in the given resource bundle and logs + * the outcome. + * + * @param bundle The bundle to check. Can be a nested bundle in Resources or + * an app or framework bundle to look in directly. + * @param parent The parent bundle of the bundle to search. Used for logging. + */ +NSString* _Nullable FindCertFileInResourceBundle(NSBundle* _Nullable bundle, + NSBundle* _Nullable parent) { + if (!bundle) return nil; + + NSString* path = [bundle pathForResource:@"roots" ofType:@"pem"]; + if (util::LogIsDebugEnabled()) { + std::string message = + absl::StrCat("roots.pem ", path ? "found " : "not found ", "in bundle ", + util::MakeString([bundle bundleIdentifier])); + if (parent) { + absl::StrAppend(&message, " (in parent ", + util::MakeString([parent bundleIdentifier]), ")"); + } + LOG_DEBUG("%s", message); + } + + return path; +} + +/** + * Finds gRPCCertificates.bundle inside the given parent, if it exists. + * + * This function exists mostly to handle differences in platforms. + * On iOS, resources are nested directly within the top-level of the parent + * bundle, but on macOS this will actually be in Contents/Resources. + * + * @param parent A framework or app bundle to check. + * @return The nested gRPCCertificates.bundle if found, otherwise nil. + */ +NSBundle* _Nullable FindCertBundleInParent(NSBundle* _Nullable parent) { + if (!parent) return nil; + + NSString* path = [parent pathForResource:@"gRPCCertificates" + ofType:@"bundle"]; + if (!path) return nil; + + return [[NSBundle alloc] initWithPath:path]; +} + +NSBundle* _Nullable FindFirestoreFrameworkBundle() { + // Load FIRFirestore reflectively to avoid a circular reference at build time. + Class firestore_class = objc_getClass("FIRFirestore"); + if (!firestore_class) return nil; + + return [NSBundle bundleForClass:firestore_class]; +} + +/** + * Finds the path to the roots.pem certificates file, wherever it may be. + * + * Carthage users will find roots.pem inside gRPCCertificates.bundle in + * the main bundle. + * + * There have been enough variations and workarounds posted on this that + * this also accepts the roots.pem file outside gRPCCertificates.bundle. + */ +NSString* FindPathToCertificatesFile() { + // Certificates file might be present in either the gRPC-C++ framework or (for + // some projects) in the main bundle. + NSBundle* bundles[] = { + // CocoaPods: try to load from the gRPC-C++ Framework. + [NSBundle bundleWithIdentifier:@"org.cocoapods.grpcpp"], + + // Carthage: try to load from the FirebaseFirestore.framework + FindFirestoreFrameworkBundle(), + + // Carthage and manual projects: users manually adding resources to the + // project may add the certificate to the main application bundle. Note + // that `mainBundle` is nil for unit tests of library projects. + [NSBundle mainBundle], + }; + + NSString* path = nil; + + for (NSBundle* parent : bundles) { + if (!parent) continue; + + NSBundle* certs_bundle = FindCertBundleInParent(parent); + path = FindCertFileInResourceBundle(certs_bundle, parent); + if (path) break; + + path = FindCertFileInResourceBundle(parent, nil); + if (path) break; + } + + return path; +} + +} // namespace + +std::string LoadGrpcRootCertificate() { + NSString* path = FindPathToCertificatesFile(); + HARD_ASSERT( + path, + "Could not load root certificates from the bundle. SSL cannot work."); + + StatusOr certificate = ReadFile(Path::FromNSString(path)); + HARD_ASSERT( + certificate.ok(), + StringFormat("Unable to open root certificates at file path %s", path) + .c_str()); + return certificate.ValueOrDie(); +} + +} // namespace remote +} // namespace firestore +} // namespace firebase diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/grpc_stream.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/grpc_stream.cc new file mode 100644 index 0000000..9656dfe --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/grpc_stream.cc @@ -0,0 +1,354 @@ +/* + * Copyright 2018 Google + * + * 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 "Firestore/core/src/firebase/firestore/remote/grpc_stream.h" + +#include // NOLINT(build/c++11) +#include // NOLINT(build/c++11) + +#include "Firestore/core/src/firebase/firestore/remote/grpc_connection.h" +#include "Firestore/core/src/firebase/firestore/remote/grpc_util.h" +#include "Firestore/core/src/firebase/firestore/util/log.h" + +namespace firebase { +namespace firestore { +namespace remote { + +using util::AsyncQueue; +using util::Status; +using Type = GrpcCompletion::Type; + +// When invoking an async gRPC method, `GrpcStream` will create a new +// `GrpcCompletion` and use it as a tag to put on the gRPC completion queue. +// `GrpcStream` does not have a reference to the gRPC completion queue (this +// allows using the same completion queue for all streams); it expects that some +// different class (in practice, `RemoteStore`) will poll the gRPC completion +// queue and `Complete` all `GrpcCompletion`s that come out of the queue. +// `GrpcCompletion::Complete` will invoke the callback given to it by this +// `GrpcStream`. In turn, `GrpcStream` will decide whether to notify its +// observer. +// +// `GrpcStream` owns the gRPC objects (such as `grpc::ClientContext`) that must +// be valid until all `GrpcCompletion`s issued by this stream come back from the +// gRPC completion queue. `GrpcCompletion`s contain an `std::promise` that is +// fulfilled once the completion is taken off the gRPC completion queue, and +// `GrpcCompletion::WaitUntilOffQueue` allows blocking on this. `GrpcStream` +// holds non-owning pointers to all the completions that it issued (and removes +// pointers to completions once they ran). `GrpcStream::Finish` and +// `GrpcStream::WriteAndFinish` block on `GrpcCompletion::WaitUntilOffQueue` for +// all the currently-pending completions, thus ensuring that the stream can be +// safely released (along with the gRPC objects the stream owns) after `Finish` +// or `WriteAndFinish` have completed. + +namespace internal { + +absl::optional BufferedWriter::EnqueueWrite( + grpc::ByteBuffer&& message, const grpc::WriteOptions& options) { + queue_.push({std::move(message), options}); + return TryStartWrite(); +} + +absl::optional BufferedWriter::TryStartWrite() { + if (queue_.empty() || has_active_write_) { + return absl::nullopt; + } + + has_active_write_ = true; + BufferedWrite message = std::move(queue_.front()); + queue_.pop(); + return std::move(message); +} + +absl::optional BufferedWriter::DequeueNextWrite() { + has_active_write_ = false; + return TryStartWrite(); +} + +} // namespace internal + +using internal::BufferedWrite; +using internal::BufferedWriter; + +GrpcStream::GrpcStream( + std::unique_ptr context, + std::unique_ptr call, + AsyncQueue* worker_queue, + GrpcConnection* grpc_connection, + GrpcStreamObserver* observer) + : context_{std::move(NOT_NULL(context))}, + call_{std::move(NOT_NULL(call))}, + worker_queue_{NOT_NULL(worker_queue)}, + grpc_connection_{NOT_NULL(grpc_connection)}, + observer_{NOT_NULL(observer)} { + grpc_connection_->Register(this); +} + +GrpcStream::~GrpcStream() { + LOG_DEBUG("GrpcStream('%s'): destroying stream", this); + HARD_ASSERT(completions_.empty(), + "GrpcStream is being destroyed without proper shutdown"); + MaybeUnregister(); +} + +void GrpcStream::Start() { + // Make starting a quick operation that avoids a roundtrip to the server by + // skipping the wait for initial server metadata (instead, it will be + // automatically coalesced with the first write operation). + context_->set_initial_metadata_corked(true); + // It's generally okay to pass a null pointer as a tag; in this case in + // particular, the tag will never come back from the completion queue (by + // design). + call_->StartCall(nullptr); + + if (observer_) { + // Start listening for new messages. + // Order is important here -- any call to observer can potentially end this + // stream's lifetime, so call `Read` before notifying. + Read(); + observer_->OnStreamStart(); + } +} + +void GrpcStream::Read() { + if (!observer_) { + return; + } + + GrpcCompletion* completion = + NewCompletion(Type::Read, [this](const GrpcCompletion* completion) { + OnRead(*completion->message()); + }); + call_->Read(completion->message(), completion); +} + +void GrpcStream::Write(grpc::ByteBuffer&& message) { + MaybeWrite(buffered_writer_.EnqueueWrite(std::move(message))); +} + +void GrpcStream::WriteLast(grpc::ByteBuffer&& message) { + grpc::WriteOptions options; + options.set_last_message(); + MaybeWrite(buffered_writer_.EnqueueWrite(std::move(message), options)); +} + +void GrpcStream::MaybeWrite(absl::optional maybe_write) { + if (!maybe_write) { + return; + } + + BufferedWrite write = std::move(maybe_write).value(); + GrpcCompletion* completion = + NewCompletion(Type::Write, [this](const GrpcCompletion*) { OnWrite(); }); + *completion->message() = write.message; + + call_->Write(*completion->message(), write.options, completion); +} + +void GrpcStream::FinishImmediately() { + LOG_DEBUG("GrpcStream('%s'): finishing without notifying observers", this); + + Shutdown(); + UnsetObserver(); +} + +void GrpcStream::FinishAndNotify(const Status& status) { + LOG_DEBUG("GrpcStream('%s'): finishing and notifying observers", this); + + Shutdown(); + + if (observer_) { + // The call to observer could end this `GrpcStream`'s lifetime, so make + // a protective copy. + GrpcStreamObserver* observer = observer_; + UnsetObserver(); + observer->OnStreamFinish(status); + } +} + +void GrpcStream::Shutdown() { + LOG_DEBUG("GrpcStream('%s'): shutting down; completions: %s, is finished: %s", + this, completions_.size(), is_grpc_call_finished_); + + MaybeUnregister(); + + // If completions are empty but the call hasn't been finished, it means this + // stream has never started. Calling `Finish` on the underlying gRPC call is + // invalid if it wasn't started previously. + if (!completions_.empty() && !is_grpc_call_finished_) { + // Important: during normal operation, the stream always has a pending read + // operation, so `Shutdown` would hang indefinitely if we didn't cancel the + // `context_`. However, if the stream has already failed, avoid canceling + // the context to avoid overwriting the status captured during the + // `OnOperationFailed`. + + context_->TryCancel(); + FinishGrpcCall({}); + } + + // Drain the completions -- `Shutdown` guarantees to bring the stream into + // destructible state. Two possibilities here: + // - completions are empty -- nothing to block on; + // - the only completion is "finish" (whether enqueued by this function or + // previously) -- "finish" is a very fast operation. + FastFinishCompletionsBlocking(); +} + +void GrpcStream::MaybeUnregister() { + if (grpc_connection_) { + grpc_connection_->Unregister(this); + grpc_connection_ = nullptr; + } +} + +void GrpcStream::FinishGrpcCall(const OnSuccess& callback) { + LOG_DEBUG("GrpcStream('%s'): finishing the underlying call", this); + + HARD_ASSERT(!is_grpc_call_finished_, "FinishGrpcCall called twice"); + is_grpc_call_finished_ = true; + + // All completions issued by this call must be taken off the queue before + // finish operation can be enqueued. + FastFinishCompletionsBlocking(); + GrpcCompletion* completion = NewCompletion(Type::Finish, callback); + call_->Finish(completion->status(), completion); +} + +void GrpcStream::FastFinishCompletionsBlocking() { + LOG_DEBUG("GrpcStream('%s'): fast finishing %s completion(s)", this, + completions_.size()); + + // TODO(varconst): reset buffered_writer_? Should not be necessary, because it + // should never be called again after a call to Finish. + + for (auto completion : completions_) { + // `GrpcStream` cannot actually remove any of the completions that already + // have been enqueued on the worker queue, so instead turn them into no-ops. + completion->Cancel(); + } + + for (auto completion : completions_) { + // This is blocking. + completion->WaitUntilOffQueue(); + } + completions_.clear(); +} + +bool GrpcStream::WriteAndFinish(grpc::ByteBuffer&& message) { + bool did_last_write = false; + if (!is_grpc_call_finished_) { + did_last_write = TryLastWrite(std::move(message)); + } + FinishImmediately(); + return did_last_write; +} + +bool GrpcStream::TryLastWrite(grpc::ByteBuffer&& message) { + absl::optional maybe_write = + buffered_writer_.EnqueueWrite(std::move(message)); + // Only bother with the last write if there is no active write at the moment. + if (!maybe_write) { + return false; + } + + BufferedWrite last_write = std::move(maybe_write).value(); + GrpcCompletion* completion = NewCompletion(Type::Write, {}); + *completion->message() = last_write.message; + call_->WriteLast(*completion->message(), grpc::WriteOptions{}, completion); + + // Empirically, the write normally takes less than a millisecond to finish + // (both with and without network connection), and never more than several + // dozen milliseconds. Nevertheless, ensure `WriteAndFinish` doesn't hang if + // there happen to be circumstances under which the write may block + // indefinitely (in that case, rely on the fact that canceling a gRPC call + // makes all pending operations come back from the queue quickly). + + auto status = completion->WaitUntilOffQueue(std::chrono::milliseconds(500)); + return status == std::future_status::ready; +} + +GrpcStream::Metadata GrpcStream::GetResponseHeaders() const { + return context_->GetServerInitialMetadata(); +} + +// Callbacks + +void GrpcStream::OnRead(const grpc::ByteBuffer& message) { + if (observer_) { + // Continue waiting for new messages indefinitely as long as there is an + // interested observer. + // Order is important here -- any call to observer can potentially end this + // stream's lifetime, so call `Read` before notifying. + Read(); + observer_->OnStreamRead(message); + } +} + +void GrpcStream::OnWrite() { + if (observer_) { + MaybeWrite(buffered_writer_.DequeueNextWrite()); + // Observer is not interested in this event. + } +} + +void GrpcStream::OnOperationFailed() { + if (is_grpc_call_finished_) { + // If a finish operation has been enqueued already (possibly by a previous + // failed operation), there's nothing to do. + return; + } + + FinishGrpcCall([this](const GrpcCompletion* completion) { + Status status = ConvertStatus(*completion->status()); + FinishAndNotify(status); + }); +} + +void GrpcStream::RemoveCompletion(const GrpcCompletion* to_remove) { + auto found = std::find(completions_.begin(), completions_.end(), to_remove); + HARD_ASSERT(found != completions_.end(), "Missing GrpcCompletion"); + completions_.erase(found); +} + +GrpcCompletion* GrpcStream::NewCompletion(Type tag, + const OnSuccess& on_success) { + // Can't move into lambda until C++14. + GrpcCompletion::Callback decorated = + [this, on_success](bool ok, const GrpcCompletion* completion) { + RemoveCompletion(completion); + + if (ok) { + if (on_success) { + on_success(completion); + } + } else { + // Use the same error-handling for all operations; all errors are + // unrecoverable. + LOG_DEBUG("GrpcStream('%s'): operation of type %s failed", this, + completion->type()); + OnOperationFailed(); + } + }; + + // For lifetime details, see `GrpcCompletion` class comment. + auto* completion = + new GrpcCompletion{tag, worker_queue_, std::move(decorated)}; + completions_.push_back(completion); + return completion; +} + +} // namespace remote +} // namespace firestore +} // namespace firebase diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/grpc_stream.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/grpc_stream.h new file mode 100644 index 0000000..9b0a528 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/grpc_stream.h @@ -0,0 +1,248 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_REMOTE_GRPC_STREAM_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_REMOTE_GRPC_STREAM_H_ + +#include +#include +#include +#include +#include +#include +#include + +#include "Firestore/core/src/firebase/firestore/util/warnings.h" + +#include "Firestore/core/src/firebase/firestore/remote/grpc_call.h" +#include "Firestore/core/src/firebase/firestore/remote/grpc_completion.h" +#include "Firestore/core/src/firebase/firestore/remote/grpc_stream_observer.h" +#include "Firestore/core/src/firebase/firestore/util/async_queue.h" +#include "Firestore/core/src/firebase/firestore/util/status.h" +#include "absl/types/optional.h" +#include "grpcpp/client_context.h" +SUPPRESS_DOCUMENTATION_WARNINGS_BEGIN() +#include "grpcpp/generic/generic_stub.h" +SUPPRESS_END() +#include "grpcpp/support/byte_buffer.h" + +namespace firebase { +namespace firestore { +namespace remote { + +class GrpcConnection; +class GrpcStream; + +namespace internal { + +struct BufferedWrite { + grpc::ByteBuffer message; + grpc::WriteOptions options; +}; + +/** + * `BufferedWriter` accepts serialized protos ("writes") on its queue and + * writes them to the gRPC stream one by one. Only one write + * may be in progress ("active") at any given time. + * + * Writes are put on the queue using `EnqueueWrite`; if no other write is + * currently in progress, a write will be issued with the given proto + * immediately, otherwise, the proto will be "buffered" (put on the queue in + * this `BufferedWriter`). When a write becomes active, a `StreamWrite` + * operation is created with the proto and immediately executed; a write is + * active from the moment it is executed and until `DequeueNextWrite` is called + * on the `BufferedWriter`. `DequeueNextWrite` makes the next write active, if + * any. + * + * `BufferedWriter` does not store any of the operations it creates. + * + * This class exists to help Firestore streams adhere to the gRPC requirement + * that only one write operation may be active at any given time. + */ +class BufferedWriter { + public: + // Returns the newly-created write operation if the given `write` became + // active, null pointer otherwise. + absl::optional EnqueueWrite(grpc::ByteBuffer&& write, + const grpc::WriteOptions& options); + + absl::optional EnqueueWrite(grpc::ByteBuffer&& write) { + return EnqueueWrite(std::move(write), grpc::WriteOptions{}); + } + + // Returns the newly-created write operation if there was a next write in the + // queue, or nullptr if the queue was empty. + absl::optional DequeueNextWrite(); + + private: + absl::optional TryStartWrite(); + + std::queue queue_; + bool has_active_write_ = false; +}; + +} // namespace internal + +/** + * A gRPC bidirectional stream that notifies the given `observer` about stream + * events. + * + * The stream has to be explicitly opened (via `Start`) before it can be used. + * The stream is always listening for new messages from the server. The stream + * can be used to send messages to the server (via `Write`); messages are queued + * and sent out one by one. Both sent and received messages are raw bytes; + * serialization and deserialization are left to the caller. + * + * The observer will be notified about the following events: + * - stream has been started; + * - stream has received a new message from the server; + * - stream has been interrupted with an error. All errors are unrecoverable. + * + * Note that the stream will _not_ notify the observer about finish if the + * finish was initiated by the client. + * + * The stream is disposable; once it finishes, it cannot be restarted. + * + * This class is essentially a wrapper over + * `grpc::GenericClientAsyncReaderWriter`. See the source file for comments on + * implementation details. + */ +class GrpcStream : public GrpcCall { + public: + GrpcStream(std::unique_ptr context, + std::unique_ptr call, + util::AsyncQueue* worker_queue, + GrpcConnection* grpc_connection, + GrpcStreamObserver* observer); + ~GrpcStream(); + + void Start(); + + // Can only be called once the stream has opened. + void Write(grpc::ByteBuffer&& message); + + /** + * Writes the given message and indicates to the server that no more write + * operations will be sent using this stream. It is invalid to call `Write` or + * `WriteLast` after `WriteLast` was called. + */ + void WriteLast(grpc::ByteBuffer&& message); + + // Does not produce a notification. Once this method is called, the stream can + // no longer be used. + // + // This is a blocking operation; blocking time is expected to be in the order + // of tens of milliseconds. + // + // Can be called on a stream before it opens. + void FinishImmediately() override; + + // Like `FinishImmediately`, but will notify the observer. + void FinishAndNotify(const util::Status& status) override; + + /** + * Writes the given message and finishes the stream as soon as this final + * write succeeds. The final write is done on a best-effort basis; the return + * value indicates whether the final write went through. + * + * This is a blocking operation; blocking time is expected to be in the order + * of tens of milliseconds. + * + * Can only be called once the stream has opened. + */ + bool WriteAndFinish(grpc::ByteBuffer&& message); + + bool IsFinished() const { + return observer_ == nullptr; + } + + /** + * Returns the metadata received from the server. + * + * Can only be called once the stream has opened. + */ + Metadata GetResponseHeaders() const override; + + /** For tests only */ + grpc::ClientContext* context() override { + return context_.get(); + } + + private: + void Read(); + void MaybeWrite(absl::optional maybe_write); + bool TryLastWrite(grpc::ByteBuffer&& message); + + void Shutdown(); + void UnsetObserver() { + observer_ = nullptr; + } + void MaybeUnregister(); + + void OnStart(); + void OnRead(const grpc::ByteBuffer& message); + void OnWrite(); + void OnOperationFailed(); + void RemoveCompletion(const GrpcCompletion* to_remove); + + using OnSuccess = std::function; + GrpcCompletion* NewCompletion(GrpcCompletion::Type type, + const OnSuccess& callback); + // Finishes the underlying gRPC call. Must always be invoked on any call that + // was started. Presumes that any pending completions will quickly come off + // the queue and will block until they do, so this must only be invoked when + // the current call either failed (`OnOperationFailed`) or canceled. + void FinishGrpcCall(const OnSuccess& callback); + + // Blocks until all the completions issued by this stream come out from the + // gRPC completion queue. Once they do, it is safe to delete this `GrpcStream` + // (thus releasing `grpc::ClientContext`). This function should only be called + // during the stream finish. + // + // Important: before calling this function, the caller must be sure that any + // pending completions on the gRPC completion queue will come back quickly + // (either because the call has failed, or because the call has been + // canceled). Otherwise, this function will block indefinitely. + void FastFinishCompletionsBlocking(); + + // gRPC requires the `context_` and `call_` objects to be valid until the last + // gRPC operation associated with this stream finishes. Note that + // `grpc::ClientContext` is _not_ reference-counted. + // + // Important: `call_` has to be destroyed before `context_`, so declaration + // order matters here. Despite the unique pointer, `call_` is actually + // a non-owning handle, and the memory it refers to (part of a gRPC memory + // arena) will be released once `context_` (which is owning) is released. + std::unique_ptr context_; + std::unique_ptr call_; + + util::AsyncQueue* worker_queue_ = nullptr; + GrpcConnection* grpc_connection_ = nullptr; + + GrpcStreamObserver* observer_ = nullptr; + internal::BufferedWriter buffered_writer_; + + std::vector completions_; + + // gRPC asserts that a call is finished exactly once. + bool is_grpc_call_finished_ = false; +}; + +} // namespace remote +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_REMOTE_GRPC_STREAM_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/grpc_stream_observer.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/grpc_stream_observer.h new file mode 100644 index 0000000..0b0980b --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/grpc_stream_observer.h @@ -0,0 +1,45 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_REMOTE_GRPC_STREAM_OBSERVER_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_REMOTE_GRPC_STREAM_OBSERVER_H_ + +#include "Firestore/core/src/firebase/firestore/util/status.h" +#include "grpcpp/support/byte_buffer.h" + +namespace firebase { +namespace firestore { +namespace remote { + +/** Observer that gets notified of events on a gRPC stream. */ +class GrpcStreamObserver { + public: + virtual ~GrpcStreamObserver() { + } + + // Stream has been successfully established. + virtual void OnStreamStart() = 0; + // A message has been received from the server. + virtual void OnStreamRead(const grpc::ByteBuffer& message) = 0; + // Connection has been broken, perhaps by the server. + virtual void OnStreamFinish(const util::Status& status) = 0; +}; + +} // namespace remote +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_REMOTE_GRPC_STREAM_OBSERVER_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/grpc_streaming_reader.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/grpc_streaming_reader.cc new file mode 100644 index 0000000..64dac1b --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/grpc_streaming_reader.cc @@ -0,0 +1,84 @@ +/* + * Copyright 2018 Google + * + * 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 "Firestore/core/src/firebase/firestore/remote/grpc_streaming_reader.h" + +#include + +#include "Firestore/core/src/firebase/firestore/remote/grpc_connection.h" +#include "Firestore/core/src/firebase/firestore/util/hard_assert.h" + +namespace firebase { +namespace firestore { +namespace remote { + +using util::AsyncQueue; +using util::Status; +using util::StatusOr; + +GrpcStreamingReader::GrpcStreamingReader( + std::unique_ptr context, + std::unique_ptr call, + util::AsyncQueue* worker_queue, + GrpcConnection* grpc_connection, + const grpc::ByteBuffer& request) + : stream_{absl::make_unique(std::move(context), + std::move(call), + worker_queue, + grpc_connection, + this)}, + request_{request} { +} + +void GrpcStreamingReader::Start(Callback&& callback) { + callback_ = std::move(callback); + stream_->Start(); +} + +void GrpcStreamingReader::FinishImmediately() { + stream_->FinishImmediately(); +} + +void GrpcStreamingReader::FinishAndNotify(const Status& status) { + stream_->FinishAndNotify(status); +} + +void GrpcStreamingReader::OnStreamStart() { + // It is important to indicate to the server that there will be no follow-up + // writes; otherwise, the call will never finish. + stream_->WriteLast(std::move(request_)); +} + +void GrpcStreamingReader::OnStreamRead(const grpc::ByteBuffer& message) { + // Accumulate responses + responses_.push_back(message); +} + +void GrpcStreamingReader::OnStreamFinish(const util::Status& status) { + HARD_ASSERT(callback_, + "Received an event from stream after callback was unset"); + // Invoking the callback may end this reader's lifetime. + auto callback = std::move(callback_); + if (status.ok()) { + callback(responses_); + } else { + callback(status); + } +} + +} // namespace remote +} // namespace firestore +} // namespace firebase diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/grpc_streaming_reader.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/grpc_streaming_reader.h new file mode 100644 index 0000000..c31b096 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/grpc_streaming_reader.h @@ -0,0 +1,111 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_REMOTE_GRPC_STREAMING_READER_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_REMOTE_GRPC_STREAMING_READER_H_ + +#include +#include +#include +#include + +#include "Firestore/core/src/firebase/firestore/util/warnings.h" + +#include "Firestore/core/src/firebase/firestore/remote/grpc_stream.h" +#include "Firestore/core/src/firebase/firestore/remote/grpc_stream_observer.h" +#include "Firestore/core/src/firebase/firestore/util/status.h" +#include "Firestore/core/src/firebase/firestore/util/statusor.h" +#include "grpcpp/client_context.h" +SUPPRESS_DOCUMENTATION_WARNINGS_BEGIN() +#include "grpcpp/generic/generic_stub.h" +SUPPRESS_END() +#include "grpcpp/support/byte_buffer.h" + +namespace firebase { +namespace firestore { +namespace remote { + +class GrpcConnection; + +/** + * Sends a single request to the server, reads one or more streaming server + * responses, and invokes the given callback with the accumulated responses. + */ +class GrpcStreamingReader : public GrpcCall, public GrpcStreamObserver { + public: + using ResponsesT = std::vector; + using Callback = std::function&)>; + + GrpcStreamingReader( + std::unique_ptr context, + std::unique_ptr call, + util::AsyncQueue* worker_queue, + GrpcConnection* grpc_connection, + const grpc::ByteBuffer& request); + + /** + * Starts the call; the given `callback` will be invoked with the accumulated + * results of the call. If the call fails, the `callback` will be invoked with + * a non-ok status. + */ + void Start(Callback&& callback); + + /** + * If the call is in progress, attempts to cancel the call; otherwise, it's + * a no-op. Cancellation is done on best-effort basis; however: + * - the call is guaranteed to be finished when this function returns; + * - this function is blocking but should finish very fast (order of + * milliseconds). + * + * If this function succeeds in cancelling the call, the callback will not be + * invoked. + */ + void FinishImmediately() override; + + void FinishAndNotify(const util::Status& status) override; + + /** + * Returns the metadata received from the server. + * + * Can only be called once the `GrpcStreamingReader` has received the first + * message from the server. + */ + Metadata GetResponseHeaders() const override { + return stream_->GetResponseHeaders(); + } + + void OnStreamStart() override; + void OnStreamRead(const grpc::ByteBuffer& message) override; + void OnStreamFinish(const util::Status& status) override; + + /** For tests only */ + grpc::ClientContext* context() override { + return stream_->context(); + } + + private: + std::unique_ptr stream_; + grpc::ByteBuffer request_; + + Callback callback_; + ResponsesT responses_; +}; + +} // namespace remote +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_REMOTE_GRPC_STREAMING_READER_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/grpc_unary_call.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/grpc_unary_call.cc new file mode 100644 index 0000000..735ee1b --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/grpc_unary_call.cc @@ -0,0 +1,117 @@ +/* + * Copyright 2018 Google + * + * 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 "Firestore/core/src/firebase/firestore/remote/grpc_unary_call.h" + +#include + +#include "Firestore/core/src/firebase/firestore/remote/grpc_connection.h" +#include "Firestore/core/src/firebase/firestore/remote/grpc_util.h" + +namespace firebase { +namespace firestore { +namespace remote { + +using util::AsyncQueue; +using util::Status; +using Type = GrpcCompletion::Type; + +GrpcUnaryCall::GrpcUnaryCall( + std::unique_ptr context, + std::unique_ptr call, + AsyncQueue* worker_queue, + GrpcConnection* grpc_connection, + const grpc::ByteBuffer& request) + : context_{std::move(context)}, + call_{std::move(call)}, + request_{request}, + worker_queue_{worker_queue}, + grpc_connection_{grpc_connection} { + grpc_connection_->Register(this); +} + +GrpcUnaryCall::~GrpcUnaryCall() { + HARD_ASSERT(!finish_completion_, + "GrpcUnaryCall is being destroyed without proper shutdown"); + MaybeUnregister(); +} + +void GrpcUnaryCall::Start(Callback&& callback) { + callback_ = std::move(callback); + call_->StartCall(); + + // For lifetime details, see `GrpcCompletion` class comment. + finish_completion_ = new GrpcCompletion( + Type::Finish, worker_queue_, + [this](bool /*ignored_ok*/, const GrpcCompletion* completion) { + // Ignoring ok, status should contain all the relevant information. + finish_completion_ = nullptr; + Shutdown(); + + auto callback = std::move(callback_); + if (completion->status()->ok()) { + callback(*completion->message()); + } else { + callback(ConvertStatus(*completion->status())); + } + // This `GrpcUnaryCall`'s lifetime might have been ended by the + // callback. + }); + + call_->Finish(finish_completion_->message(), finish_completion_->status(), + finish_completion_); +} + +void GrpcUnaryCall::FinishImmediately() { + Shutdown(); +} + +void GrpcUnaryCall::FinishAndNotify(const util::Status& status) { + Shutdown(); + + auto callback = std::move(callback_); + callback(status); +} + +void GrpcUnaryCall::Shutdown() { + MaybeUnregister(); + if (!finish_completion_) { + // Nothing to cancel. + return; + } + + context_->TryCancel(); + + finish_completion_->Cancel(); + // This function blocks. + finish_completion_->WaitUntilOffQueue(); + finish_completion_ = nullptr; +} + +void GrpcUnaryCall::MaybeUnregister() { + if (grpc_connection_) { + grpc_connection_->Unregister(this); + grpc_connection_ = nullptr; + } +} + +GrpcCall::Metadata GrpcUnaryCall::GetResponseHeaders() const { + return context_->GetServerInitialMetadata(); +} + +} // namespace remote +} // namespace firestore +} // namespace firebase diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/grpc_unary_call.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/grpc_unary_call.h new file mode 100644 index 0000000..3edb2bb --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/grpc_unary_call.h @@ -0,0 +1,114 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_REMOTE_GRPC_UNARY_CALL_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_REMOTE_GRPC_UNARY_CALL_H_ + +#include +#include +#include + +#include "Firestore/core/src/firebase/firestore/util/warnings.h" + +#include "Firestore/core/src/firebase/firestore/remote/grpc_call.h" +#include "Firestore/core/src/firebase/firestore/remote/grpc_completion.h" +#include "Firestore/core/src/firebase/firestore/util/async_queue.h" +#include "Firestore/core/src/firebase/firestore/util/status.h" +#include "Firestore/core/src/firebase/firestore/util/statusor.h" +#include "grpcpp/client_context.h" +SUPPRESS_DOCUMENTATION_WARNINGS_BEGIN() +#include "grpcpp/generic/generic_stub.h" +SUPPRESS_END() +#include "grpcpp/support/byte_buffer.h" + +namespace firebase { +namespace firestore { +namespace remote { + +class GrpcConnection; + +/** + * Sends a single request to the server and invokes the given callback with the + * server response. + */ +class GrpcUnaryCall : public GrpcCall { + public: + using Callback = std::function&)>; + + GrpcUnaryCall(std::unique_ptr context, + std::unique_ptr call, + util::AsyncQueue* worker_queue, + GrpcConnection* grpc_connection, + const grpc::ByteBuffer& request); + ~GrpcUnaryCall(); + + /** + * Starts the call; the given `callback` will be invoked with the result of + * the call. If the call fails, the `callback` will be invoked with a non-ok + * status. + */ + void Start(Callback&& callback); + + /** + * If the call is in progress, attempts to finish the call early, effectively + * cancelling it; otherwise, it's a no-op. Cancellation is done on best-effort + * basis; however: + * - the call is guaranteed to be finished when this function returns; + * - this function is blocking but should be done very fast (order of + * milliseconds). + * + * If this function succeeds in cancelling the call, the callback will not be + * invoked. + */ + void FinishImmediately() override; + + /** Like `Finish`, but always invokes the callback with the given `status`. */ + void FinishAndNotify(const util::Status& status) override; + + /** + * Returns the metadata received from the server. + * + * Can only be called once the `GrpcUnaryCall` has finished. + */ + Metadata GetResponseHeaders() const override; + + /** For tests only */ + grpc::ClientContext* context() override { + return context_.get(); + } + + private: + void Shutdown(); + void MaybeUnregister(); + + // See comments in `GrpcStream` on lifetime issues for gRPC objects. + std::unique_ptr context_; + std::unique_ptr call_; + // Stored to avoid lifetime issues with gRPC. + grpc::ByteBuffer request_; + + util::AsyncQueue* worker_queue_ = nullptr; + GrpcConnection* grpc_connection_ = nullptr; + + GrpcCompletion* finish_completion_ = nullptr; + Callback callback_; +}; + +} // namespace remote +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_REMOTE_GRPC_UNARY_CALL_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/grpc_util.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/grpc_util.cc new file mode 100644 index 0000000..12db198 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/grpc_util.cc @@ -0,0 +1,47 @@ +/* + * Copyright 2018 Google + * + * 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 "Firestore/core/src/firebase/firestore/remote/grpc_util.h" + +#include "Firestore/core/src/firebase/firestore/util/hard_assert.h" + +namespace firebase { +namespace firestore { +namespace remote { + +using util::Status; + +Status ConvertStatus(const grpc::Status& from) { + if (from.ok()) { + return Status::OK(); + } + + grpc::StatusCode error_code = from.error_code(); + // Both `grpc::Status` and Firestore's `util::Status` use canonical error + // codes for Google APIs. The canonical codes define integer values, so this + // conversion should be safe. + // See + // https://github.com/googleapis/googleapis/blob/master/google/rpc/code.proto + HARD_ASSERT( + error_code >= grpc::CANCELLED && error_code <= grpc::UNAUTHENTICATED, + "Unknown gRPC error code: %s", error_code); + + return {static_cast(error_code), from.error_message()}; +} + +} // namespace remote +} // namespace firestore +} // namespace firebase diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/grpc_util.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/grpc_util.h new file mode 100644 index 0000000..89b8c7f --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/grpc_util.h @@ -0,0 +1,33 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_REMOTE_GRPC_UTIL_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_REMOTE_GRPC_UTIL_H_ + +#include "Firestore/core/src/firebase/firestore/util/status.h" +#include "grpcpp/support/status.h" + +namespace firebase { +namespace firestore { +namespace remote { + +util::Status ConvertStatus(const grpc::Status& from); + +} // namespace remote +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_REMOTE_GRPC_UTIL_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/online_state_tracker.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/online_state_tracker.cc new file mode 100644 index 0000000..afdc69d --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/online_state_tracker.cc @@ -0,0 +1,150 @@ +/* + * Copyright 2019 Google + * + * 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 "Firestore/core/src/firebase/firestore/remote/online_state_tracker.h" + +#include // NOLINT(build/c++11) + +#include "Firestore/core/src/firebase/firestore/util/executor.h" +#include "Firestore/core/src/firebase/firestore/util/hard_assert.h" +#include "Firestore/core/src/firebase/firestore/util/log.h" +#include "Firestore/core/src/firebase/firestore/util/string_format.h" + +namespace chr = std::chrono; +using firebase::firestore::model::OnlineState; +using firebase::firestore::util::AsyncQueue; +using firebase::firestore::util::DelayedOperation; +using firebase::firestore::util::Status; +using firebase::firestore::util::StringFormat; +using firebase::firestore::util::TimerId; + +namespace { + +// To deal with transient failures, we allow multiple stream attempts before +// giving up and transitioning from OnlineState Unknown to Offline. +// TODO(mikelehen): This used to be set to 2 as a mitigation for b/66228394. +// @jdimond thinks that bug is sufficiently fixed so that we can set this back +// to 1. If that works okay, we could potentially remove this logic entirely. +const int kMaxWatchStreamFailures = 1; + +// To deal with stream attempts that don't succeed or fail in a timely manner, +// we have a timeout for OnlineState to reach Online or Offline. If the timeout +// is reached, we transition to Offline rather than waiting indefinitely. +const AsyncQueue::Milliseconds kOnlineStateTimeout = chr::seconds(10); + +} // namespace + +namespace firebase { +namespace firestore { +namespace remote { + +void OnlineStateTracker::HandleWatchStreamStart() { + if (watch_stream_failures_ != 0) { + return; + } + + SetAndBroadcast(OnlineState::Unknown); + + HARD_ASSERT(!online_state_timer_, + "online_state_timer_ shouldn't be started yet"); + online_state_timer_ = worker_queue_->EnqueueAfterDelay( + kOnlineStateTimeout, TimerId::OnlineStateTimeout, [this] { + online_state_timer_ = {}; + + HARD_ASSERT(state_ == OnlineState::Unknown, + "Timer should be canceled if we transitioned to a " + "different state."); + LogClientOfflineWarningIfNecessary(StringFormat( + "Backend didn't respond within %s seconds.", + chr::duration_cast(kOnlineStateTimeout).count())); + SetAndBroadcast(OnlineState::Offline); + + // NOTE: `HandleWatchStreamFailure` will continue to increment + // `watch_stream_failures_` even though we are already marked `Offline` + // but this is non-harmful. + }); +} + +void OnlineStateTracker::HandleWatchStreamFailure(const Status& error) { + if (state_ == OnlineState::Online) { + SetAndBroadcast(OnlineState::Unknown); + + // To get to `OnlineState`::Online, `UpdateState` must have been called + // which would have reset our heuristics. + HARD_ASSERT(watch_stream_failures_ == 0, + "watch_stream_failures_ must be 0"); + HARD_ASSERT(!online_state_timer_, + "online_state_timer_ must not be set yet"); + } else { + ++watch_stream_failures_; + + if (watch_stream_failures_ >= kMaxWatchStreamFailures) { + ClearOnlineStateTimer(); + + LogClientOfflineWarningIfNecessary( + StringFormat("Connection failed %s times. Most recent error: %s", + kMaxWatchStreamFailures, error.error_message())); + + SetAndBroadcast(OnlineState::Offline); + } + } +} + +void OnlineStateTracker::UpdateState(OnlineState new_state) { + ClearOnlineStateTimer(); + watch_stream_failures_ = 0; + + if (new_state == OnlineState::Online) { + // We've connected to watch at least once. Don't warn the developer about + // being offline going forward. + should_warn_client_is_offline_ = false; + } + + SetAndBroadcast(new_state); +} + +void OnlineStateTracker::SetAndBroadcast(OnlineState new_state) { + if (new_state != state_) { + state_ = new_state; + online_state_handler_(new_state); + } +} + +void OnlineStateTracker::LogClientOfflineWarningIfNecessary( + const std::string& reason) { + std::string message = StringFormat( + "Could not reach Cloud Firestore backend. %s\n This " + "typically indicates that your device does not have a " + "healthy Internet connection at the moment. The client will " + "operate in offline mode until it is able to successfully " + "connect to the backend.", + reason); + + if (should_warn_client_is_offline_) { + LOG_WARN("%s", message); + should_warn_client_is_offline_ = false; + } else { + LOG_DEBUG("%s", message); + } +} + +void OnlineStateTracker::ClearOnlineStateTimer() { + online_state_timer_.Cancel(); +} + +} // namespace remote +} // namespace firestore +} // namespace firebase diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/online_state_tracker.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/online_state_tracker.h new file mode 100644 index 0000000..a061745 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/online_state_tracker.h @@ -0,0 +1,124 @@ +/* + * Copyright 2019 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_REMOTE_ONLINE_STATE_TRACKER_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_REMOTE_ONLINE_STATE_TRACKER_H_ + +#include +#include + +#include "Firestore/core/src/firebase/firestore/model/types.h" +#include "Firestore/core/src/firebase/firestore/util/async_queue.h" +#include "Firestore/core/src/firebase/firestore/util/status.h" + +namespace firebase { +namespace firestore { +namespace remote { + +/** + * A component used by the `RemoteStore` to track the `OnlineState` (that is, + * whether or not the client as a whole should be considered to be online or + * offline), implementing the appropriate heuristics. + * + * In particular, when the client is trying to connect to the backend, we allow + * up to `kMaxWatchStreamFailures` within `kOnlineStateTimeout` for a connection + * to succeed. If we have too many failures or the timeout elapses, then we set + * the `OnlineState` to `Offline`, and the client will behave as if it is + * offline (`getDocument()` calls will return cached data, etc.). + */ +class OnlineStateTracker { + public: + OnlineStateTracker() = default; + + OnlineStateTracker( + util::AsyncQueue* worker_queue, + std::function online_state_handler) + : worker_queue_{worker_queue}, + online_state_handler_{online_state_handler} { + } + + /** + * Called by `RemoteStore` when a watch stream is started (including on + * each backoff attempt). + * + * If this is the first attempt, it sets the `OnlineState` to `Unknown` and + * starts the `onlineStateTimer`. + */ + void HandleWatchStreamStart(); + + /** + * Called by `RemoteStore` when a watch stream fails. + * + * Updates our `OnlineState` as appropriate. The first failure moves us to + * `OnlineState::Unknown`. We then may allow multiple failures (based on + * `kMaxWatchStreamFailures`) before we actually transition to + * `OnlineState::Offline`. + */ + void HandleWatchStreamFailure(const util::Status& error); + + /** + * Explicitly sets the `OnlineState` to the specified state. + * + * Note that this resets the timers / failure counters, etc. used by our + * `Offline` heuristics, so it must not be used in place of + * `HandleWatchStreamStart` and `HandleWatchStreamFailure`. + */ + void UpdateState(model::OnlineState new_state); + + private: + void SetAndBroadcast(model::OnlineState new_state); + void LogClientOfflineWarningIfNecessary(const std::string& reason); + void ClearOnlineStateTimer(); + + /** The current `OnlineState`. */ + model::OnlineState state_ = model::OnlineState::Unknown; + + /** + * A count of consecutive failures to open the stream. If it reaches the + * maximum defined by `kMaxWatchStreamFailures`, we'll revert to + * `OnlineState::Offline`. + */ + int watch_stream_failures_ = 0; + + /** + * A timer that elapses after `kOnlineStateTimeout`, at which point we + * transition from `OnlineState` `Unknown` to `Offline` without waiting for + * the stream to actually fail (`kMaxWatchStreamFailures` times). + */ + util::DelayedOperation online_state_timer_; + + /** + * Whether the client should log a warning message if it fails to connect to + * the backend (initially true, cleared after a successful stream, or if we've + * logged the message already). + */ + bool should_warn_client_is_offline_ = true; + + /** + * The worker queue to use for running timers (and to call + * `online_state_handler_`). + */ + util::AsyncQueue* worker_queue_ = nullptr; + + /** A callback to be notified on `OnlineState` changes. */ + std::function online_state_handler_; +}; + +} // namespace remote +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_REMOTE_ONLINE_STATE_TRACKER_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/remote_event.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/remote_event.h new file mode 100644 index 0000000..8ce1e38 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/remote_event.h @@ -0,0 +1,449 @@ +/* + * Copyright 2019 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_REMOTE_REMOTE_EVENT_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_REMOTE_REMOTE_EVENT_H_ + +#if !defined(__OBJC__) +// TODO(varconst): the only dependencies are `FSTMaybeDocument` and `NSData` +// (the latter is used to represent the resume token). +#error "This header only supports Objective-C++" +#endif // !defined(__OBJC__) + +#import + +#include +#include +#include +#include +#include + +#include "Firestore/core/src/firebase/firestore/core/view_snapshot.h" +#include "Firestore/core/src/firebase/firestore/model/document_key.h" +#include "Firestore/core/src/firebase/firestore/model/document_key_set.h" +#include "Firestore/core/src/firebase/firestore/model/snapshot_version.h" +#include "Firestore/core/src/firebase/firestore/model/types.h" +#include "Firestore/core/src/firebase/firestore/remote/watch_change.h" + +@class FSTMaybeDocument; +@class FSTQueryData; + +NS_ASSUME_NONNULL_BEGIN + +namespace firebase { +namespace firestore { +namespace remote { + +/** + * Interface implemented by `RemoteStore` to expose target metadata to the + * `WatchChangeAggregator`. + */ +class TargetMetadataProvider { + public: + virtual ~TargetMetadataProvider() { + } + + /** + * Returns the set of remote document keys for the given target ID as of the + * last raised snapshot. + */ + virtual model::DocumentKeySet GetRemoteKeysForTarget( + model::TargetId target_id) const = 0; + + /** + * Returns the FSTQueryData for an active target ID or 'null' if this query + * has become inactive + */ + virtual FSTQueryData* GetQueryDataForTarget( + model::TargetId target_id) const = 0; +}; + +/** + * A `TargetChange` specifies the set of changes for a specific target as part + * of an `RemoteEvent`. These changes track which documents are added, + * modified or removed, as well as the target's resume token and whether the + * target is marked CURRENT. + * + * The actual changes *to* documents are not part of the `TargetChange` since + * documents may be part of multiple targets. + */ +class TargetChange { + public: + TargetChange() = default; + + TargetChange(NSData* resume_token, + bool current, + model::DocumentKeySet added_documents, + model::DocumentKeySet modified_documents, + model::DocumentKeySet removed_documents) + : resume_token_{resume_token}, + current_{current}, + added_documents_{std::move(added_documents)}, + modified_documents_{std::move(modified_documents)}, + removed_documents_{std::move(removed_documents)} { + } + + /** + * An opaque, server-assigned token that allows watching a query to be resumed + * after disconnecting without retransmitting all the data that matches the + * query. The resume token essentially identifies a point in time from which + * the server should resume sending results. + */ + NSData* resume_token() const { + return resume_token_; + } + + /** + * The "current" (synced) status of this target. Note that "current" has + * special meaning in the RPC protocol that implies that a target is both + * up-to-date and consistent with the rest of the watch stream. + */ + bool current() const { + return current_; + } + + /** + * The set of documents that were newly assigned to this target as part of + * this remote event. + */ + const model::DocumentKeySet& added_documents() const { + return added_documents_; + } + + /** + * The set of documents that were already assigned to this target but received + * an update during this remote event. + */ + const model::DocumentKeySet& modified_documents() const { + return modified_documents_; + } + + /** + * The set of documents that were removed from this target as part of this + * remote event. + */ + const model::DocumentKeySet& removed_documents() const { + return removed_documents_; + } + + private: + NSData* resume_token_ = nil; + bool current_ = false; + model::DocumentKeySet added_documents_; + model::DocumentKeySet modified_documents_; + model::DocumentKeySet removed_documents_; +}; + +bool operator==(const TargetChange& lhs, const TargetChange& rhs); + +/** Tracks the internal state of a Watch target. */ +class TargetState { + public: + TargetState(); + + /** + * Whether this target has been marked 'current'. + * + * 'current' has special meaning in the RPC protocol: It implies that the + * Watch backend has sent us all changes up to the point at which the target + * was added and that the target is consistent with the rest of the watch + * stream. + */ + bool current() const { + return current_; + } + + /** The last resume token sent to us for this target. */ + NSData* resume_token() const { + return resume_token_; + } + + /** Whether this target has pending target adds or target removes. */ + bool IsPending() const { + return outstanding_responses_ != 0; + } + + /** Whether we have modified any state that should trigger a snapshot. */ + bool HasPendingChanges() const { + return has_pending_changes_; + } + + /** + * Applies the resume token to the `TargetChange`, but only when it has a new + * value. Empty resume tokens are discarded. + */ + void UpdateResumeToken(NSData* resume_token); + + /** + * Creates a target change from the current set of changes. + * + * To reset the document changes after raising this snapshot, call + * `ClearPendingChanges()`. + */ + TargetChange ToTargetChange() const; + + /** Resets the document changes and sets `HasPendingChanges` to false. */ + void ClearPendingChanges(); + + void AddDocumentChange(const model::DocumentKey& document_key, + core::DocumentViewChange::Type type); + void RemoveDocumentChange(const model::DocumentKey& document_key); + void RecordPendingTargetRequest(); + void RecordTargetResponse(); + void MarkCurrent(); + + private: + /** + * The number of outstanding responses (adds or removes) that we are waiting + * on. We only consider targets active that have no outstanding responses. + */ + int outstanding_responses_ = 0; + + /** + * Keeps track of the document changes since the last raised snapshot. + * + * These changes are continuously updated as we receive document updates and + * always reflect the current set of changes against the last issued snapshot. + */ + std::unordered_map + document_changes_; + + NSData* resume_token_; + + bool current_ = false; + + /** + * Whether this target state should be included in the next snapshot. We + * initialize to true so that newly-added targets are included in the next + * RemoteEvent. + */ + bool has_pending_changes_ = true; +}; + +/** + * An event from the RemoteStore. It is split into `TargetChanges` (changes to + * the state or the set of documents in our watched targets) and + * `DocumentUpdates` (changes to the actual documents). + */ +class RemoteEvent { + public: + RemoteEvent(model::SnapshotVersion snapshot_version, + std::unordered_map target_changes, + std::unordered_set target_mismatches, + std::unordered_map document_updates, + model::DocumentKeySet limbo_document_changes) + : snapshot_version_{snapshot_version}, + target_changes_{std::move(target_changes)}, + target_mismatches_{std::move(target_mismatches)}, + document_updates_{std::move(document_updates)}, + limbo_document_changes_{std::move(limbo_document_changes)} { + } + + /** The snapshot version this event brings us up to. */ + const model::SnapshotVersion& snapshot_version() const { + return snapshot_version_; + } + + /** A map from target to changes to the target. See `TargetChange`. */ + const std::unordered_map& target_changes() + const { + return target_changes_; + } + + /** + * A set of targets that is known to be inconsistent. Listens for these + * targets should be re-established without resume tokens. + */ + const std::unordered_set& target_mismatches() const { + return target_mismatches_; + } + + /** + * A set of which documents have changed or been deleted, along with the doc's + * new values (if not deleted). + */ + const std::unordered_map& + document_updates() const { + return document_updates_; + } + + /** + * A set of which document updates are due only to limbo resolution targets. + */ + const model::DocumentKeySet& limbo_document_changes() const { + return limbo_document_changes_; + } + + private: + model::SnapshotVersion snapshot_version_; + std::unordered_map target_changes_; + std::unordered_set target_mismatches_; + std::unordered_map + document_updates_; + model::DocumentKeySet limbo_document_changes_; +}; + +/** + * A helper class to accumulate watch changes into a `RemoteEvent` and other + * target information. + */ +class WatchChangeAggregator { + public: + explicit WatchChangeAggregator( + TargetMetadataProvider* target_metadata_provider); + + /** + * Processes and adds the `DocumentWatchChange` to the current set of changes. + */ + void HandleDocumentChange(const DocumentWatchChange& document_change); + + /** + * Processes and adds the `WatchTargetChange` to the current set of changes. + */ + void HandleTargetChange(const WatchTargetChange& target_change); + + /** + * Handles existence filters and synthesizes deletes for filter mismatches. + * Targets that are invalidated by filter mismatches are added to + * `pending_target_resets_`. + */ + void HandleExistenceFilter( + const ExistenceFilterWatchChange& existence_filter); + + /** + * Converts the current state into a remote event with the snapshot version + * taken from the initializer. Resets the accumulated changes before + * returning. + */ + RemoteEvent CreateRemoteEvent(const model::SnapshotVersion& snapshot_version); + + /** Removes the in-memory state for the provided target. */ + void RemoveTarget(model::TargetId target_id); + + /** + * Increment the number of acks needed from watch before we can consider the + * server to be 'in-sync' with the client's active targets. + */ + void RecordPendingTargetRequest(model::TargetId target_id); + + private: + /** + * Returns all `targetId`s that the watch change applies to: either the + * `targetId`s explicitly listed in the change or the `targetId`s of all + * currently active targets. + */ + std::vector GetTargetIds( + const WatchTargetChange& target_change) const; + + /** + * Adds the provided document to the internal list of document updates and its + * document key to the given target's mapping. + */ + void AddDocumentToTarget(model::TargetId target_id, + FSTMaybeDocument* document); + + /** + * Removes the provided document from the target mapping. If the document no + * longer matches the target, but the document's state is still known (e.g. we + * know that the document was deleted or we received the change that caused + * the filter mismatch), the new document can be provided to update the remote + * document cache. + */ + void RemoveDocumentFromTarget(model::TargetId target_id, + const model::DocumentKey& key, + FSTMaybeDocument* _Nullable updated_document); + + /** + * Returns the current count of documents in the target. This includes both + * the number of documents that the LocalStore considers to be part of the + * target as well as any accumulated changes. + */ + int GetCurrentDocumentCountForTarget(model::TargetId target_id); + + // PORTING NOTE: this method exists only for consistency with other platforms; + // in C++, it's pretty much unnecessary. + TargetState& EnsureTargetState(model::TargetId target_id); + + /** + * Returns true if the given `target_id` is active. Active targets are those + * for which there are no pending requests to add a listen and are in the + * current list of targets the client cares about. + * + * Clients can repeatedly listen and stop listening to targets, so this check + * is useful in preventing race conditions for a target where events arrive + * but the server hasn't yet acknowledged the intended change in state. + */ + bool IsActiveTarget(model::TargetId target_id) const; + + /** + * Returns the `FSTQueryData` for an active target (i.e., a target that the + * user is still interested in that has no outstanding target change + * requests). + */ + FSTQueryData* QueryDataForActiveTarget(model::TargetId target_id) const; + + /** + * Resets the state of a Watch target to its initial state (e.g. sets + * 'current' to false, clears the resume token and removes its target mapping + * from all documents). + */ + void ResetTarget(model::TargetId target_id); + + /** Returns whether the local store considers the document to be part of the + * specified target. */ + bool TargetContainsDocument(model::TargetId target_id, + const model::DocumentKey& key); + + /** The internal state of all tracked targets. */ + std::unordered_map target_states_; + + /** Keeps track of the documents to update since the last raised snapshot. */ + std::unordered_map + pending_document_updates_; + + /** A mapping of document keys to their set of target IDs. */ + std::unordered_map, + model::DocumentKeyHash> + pending_document_target_mappings_; + + /** + * A list of targets with existence filter mismatches. These targets are known + * to be inconsistent and their listens needs to be re-established by + * `RemoteStore`. + */ + std::unordered_set pending_target_resets_; + + TargetMetadataProvider* target_metadata_provider_ = nullptr; +}; + +} // namespace remote +} // namespace firestore +} // namespace firebase + +NS_ASSUME_NONNULL_END + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_REMOTE_REMOTE_EVENT_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/remote_event.mm b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/remote_event.mm new file mode 100644 index 0000000..aa2fa33 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/remote_event.mm @@ -0,0 +1,424 @@ +/* + * Copyright 2019 Google + * + * 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 "Firestore/core/src/firebase/firestore/remote/remote_event.h" + +#include + +#import "Firestore/Source/Core/FSTQuery.h" +#import "Firestore/Source/Local/FSTQueryData.h" +#import "Firestore/Source/Model/FSTDocument.h" + +using firebase::firestore::core::DocumentViewChange; +using firebase::firestore::model::DocumentKey; +using firebase::firestore::model::DocumentKeySet; +using firebase::firestore::model::SnapshotVersion; +using firebase::firestore::model::TargetId; + +namespace firebase { +namespace firestore { +namespace remote { + +// TargetChange + +bool operator==(const TargetChange& lhs, const TargetChange& rhs) { + return [lhs.resume_token() isEqualToData:rhs.resume_token()] && + lhs.current() == rhs.current() && + lhs.added_documents() == rhs.added_documents() && + lhs.modified_documents() == rhs.modified_documents() && + lhs.removed_documents() == rhs.removed_documents(); +} + +// TargetState + +TargetState::TargetState() : resume_token_{[NSData data]} { +} + +void TargetState::UpdateResumeToken(NSData* resume_token) { + if (resume_token.length > 0) { + has_pending_changes_ = true; + resume_token_ = [resume_token copy]; + } +} + +TargetChange TargetState::ToTargetChange() const { + DocumentKeySet added_documents; + DocumentKeySet modified_documents; + DocumentKeySet removed_documents; + + for (const auto& entry : document_changes_) { + const DocumentKey& document_key = entry.first; + DocumentViewChange::Type change_type = entry.second; + + switch (change_type) { + case DocumentViewChange::Type::kAdded: + added_documents = added_documents.insert(document_key); + break; + case DocumentViewChange::Type::kModified: + modified_documents = modified_documents.insert(document_key); + break; + case DocumentViewChange::Type::kRemoved: + removed_documents = removed_documents.insert(document_key); + break; + default: + HARD_FAIL("Encountered invalid change type: %s", change_type); + } + } + + return TargetChange{resume_token(), current(), std::move(added_documents), + std::move(modified_documents), + std::move(removed_documents)}; +} + +void TargetState::ClearPendingChanges() { + has_pending_changes_ = false; + document_changes_.clear(); +} + +void TargetState::RecordPendingTargetRequest() { + ++outstanding_responses_; +} + +void TargetState::RecordTargetResponse() { + --outstanding_responses_; +} + +void TargetState::MarkCurrent() { + has_pending_changes_ = true; + current_ = true; +} + +void TargetState::AddDocumentChange(const DocumentKey& document_key, + DocumentViewChange::Type type) { + has_pending_changes_ = true; + document_changes_[document_key] = type; +} + +void TargetState::RemoveDocumentChange(const DocumentKey& document_key) { + has_pending_changes_ = true; + document_changes_.erase(document_key); +} + +// WatchChangeAggregator + +WatchChangeAggregator::WatchChangeAggregator( + TargetMetadataProvider* target_metadata_provider) + : target_metadata_provider_{NOT_NULL(target_metadata_provider)} { +} + +void WatchChangeAggregator::HandleDocumentChange( + const DocumentWatchChange& document_change) { + for (TargetId target_id : document_change.updated_target_ids()) { + if ([document_change.new_document() isKindOfClass:[FSTDocument class]]) { + AddDocumentToTarget(target_id, document_change.new_document()); + } else if ([document_change.new_document() + isKindOfClass:[FSTDeletedDocument class]]) { + RemoveDocumentFromTarget(target_id, document_change.document_key(), + document_change.new_document()); + } + } + + for (TargetId target_id : document_change.removed_target_ids()) { + RemoveDocumentFromTarget(target_id, document_change.document_key(), + document_change.new_document()); + } +} + +void WatchChangeAggregator::HandleTargetChange( + const WatchTargetChange& target_change) { + for (TargetId target_id : GetTargetIds(target_change)) { + TargetState& target_state = EnsureTargetState(target_id); + + switch (target_change.state()) { + case WatchTargetChangeState::NoChange: + if (IsActiveTarget(target_id)) { + target_state.UpdateResumeToken(target_change.resume_token()); + } + continue; + case WatchTargetChangeState::Added: + // We need to decrement the number of pending acks needed from watch for + // this target_id. + target_state.RecordTargetResponse(); + if (!target_state.IsPending()) { + // We have a freshly added target, so we need to reset any state that + // we had previously. This can happen e.g. when remove and add back a + // target for existence filter mismatches. + target_state.ClearPendingChanges(); + } + target_state.UpdateResumeToken(target_change.resume_token()); + continue; + case WatchTargetChangeState::Removed: + // We need to keep track of removed targets to we can post-filter and + // remove any target changes. + // We need to decrement the number of pending acks needed from watch for + // this targetId. + target_state.RecordTargetResponse(); + if (!target_state.IsPending()) { + RemoveTarget(target_id); + } + HARD_ASSERT(target_change.cause().ok(), + "WatchChangeAggregator does not handle errored targets"); + continue; + case WatchTargetChangeState::Current: + if (IsActiveTarget(target_id)) { + target_state.MarkCurrent(); + target_state.UpdateResumeToken(target_change.resume_token()); + } + continue; + case WatchTargetChangeState::Reset: + if (IsActiveTarget(target_id)) { + // Reset the target and synthesizes removes for all existing + // documents. The backend will re-add any documents that still match + // the target before it sends the next global snapshot. + ResetTarget(target_id); + target_state.UpdateResumeToken(target_change.resume_token()); + } + continue; + } + HARD_FAIL("Unknown target watch change state: %s", target_change.state()); + } +} + +std::vector WatchChangeAggregator::GetTargetIds( + const WatchTargetChange& target_change) const { + if (!target_change.target_ids().empty()) { + return target_change.target_ids(); + } + + std::vector result; + result.reserve(target_states_.size()); + for (const auto& entry : target_states_) { + result.push_back(entry.first); + } + + return result; +} + +void WatchChangeAggregator::HandleExistenceFilter( + const ExistenceFilterWatchChange& existence_filter) { + TargetId target_id = existence_filter.target_id(); + int expected_count = existence_filter.filter().count(); + + FSTQueryData* query_data = QueryDataForActiveTarget(target_id); + if (query_data) { + FSTQuery* query = query_data.query; + if ([query isDocumentQuery]) { + if (expected_count == 0) { + // The existence filter told us the document does not exist. We deduce + // that this document does not exist and apply a deleted document to our + // updates. Without applying this deleted document there might be + // another query that will raise this document as part of a snapshot + // until it is resolved, essentially exposing inconsistency between + // queries. + DocumentKey key{query.path}; + RemoveDocumentFromTarget( + target_id, key, + [FSTDeletedDocument documentWithKey:key + version:SnapshotVersion::None() + hasCommittedMutations:NO]); + } else { + HARD_ASSERT(expected_count == 1, + "Single document existence filter with count: %s", + expected_count); + } + } else { + int current_size = GetCurrentDocumentCountForTarget(target_id); + if (current_size != expected_count) { + // Existence filter mismatch: We reset the mapping and raise a new + // snapshot with `isFromCache:true`. + ResetTarget(target_id); + pending_target_resets_.insert(target_id); + } + } + } +} + +RemoteEvent WatchChangeAggregator::CreateRemoteEvent( + const SnapshotVersion& snapshot_version) { + std::unordered_map target_changes; + + for (auto& entry : target_states_) { + TargetId target_id = entry.first; + TargetState& target_state = entry.second; + + FSTQueryData* query_data = QueryDataForActiveTarget(target_id); + if (query_data) { + if (target_state.current() && [query_data.query isDocumentQuery]) { + // Document queries for document that don't exist can produce an empty + // result set. To update our local cache, we synthesize a document + // delete if we have not previously received the document. This resolves + // the limbo state of the document, removing it from limboDocumentRefs. + DocumentKey key{query_data.query.path}; + if (pending_document_updates_.find(key) == + pending_document_updates_.end() && + !TargetContainsDocument(target_id, key)) { + RemoveDocumentFromTarget( + target_id, key, + [FSTDeletedDocument documentWithKey:key + version:snapshot_version + hasCommittedMutations:NO]); + } + } + + if (target_state.HasPendingChanges()) { + target_changes[target_id] = target_state.ToTargetChange(); + target_state.ClearPendingChanges(); + } + } + } + + DocumentKeySet resolved_limbo_documents; + + // We extract the set of limbo-only document updates as the GC logic + // special-cases documents that do not appear in the query cache. + // + // TODO(gsoltis): Expand on this comment. + for (const auto& entry : pending_document_target_mappings_) { + bool is_only_limbo_target = true; + + for (TargetId target_id : entry.second) { + FSTQueryData* query_data = QueryDataForActiveTarget(target_id); + if (query_data && query_data.purpose != FSTQueryPurposeLimboResolution) { + is_only_limbo_target = false; + break; + } + } + + if (is_only_limbo_target) { + resolved_limbo_documents = resolved_limbo_documents.insert(entry.first); + } + } + + RemoteEvent remote_event{snapshot_version, std::move(target_changes), + std::move(pending_target_resets_), + std::move(pending_document_updates_), + std::move(resolved_limbo_documents)}; + + // Re-initialize the current state to ensure that we do not modify the + // generated `RemoteEvent`. + pending_document_updates_.clear(); + pending_document_target_mappings_.clear(); + pending_target_resets_.clear(); + + return remote_event; +} + +void WatchChangeAggregator::AddDocumentToTarget(TargetId target_id, + FSTMaybeDocument* document) { + if (!IsActiveTarget(target_id)) { + return; + } + + DocumentViewChange::Type change_type = + TargetContainsDocument(target_id, document.key) + ? DocumentViewChange::Type::kModified + : DocumentViewChange::Type::kAdded; + + TargetState& target_state = EnsureTargetState(target_id); + target_state.AddDocumentChange(document.key, change_type); + + pending_document_updates_[document.key] = document; + pending_document_target_mappings_[document.key].insert(target_id); +} + +void WatchChangeAggregator::RemoveDocumentFromTarget( + TargetId target_id, + const DocumentKey& key, + FSTMaybeDocument* _Nullable updated_document) { + if (!IsActiveTarget(target_id)) { + return; + } + + TargetState& target_state = EnsureTargetState(target_id); + if (TargetContainsDocument(target_id, key)) { + target_state.AddDocumentChange(key, DocumentViewChange::Type::kRemoved); + } else { + // The document may have entered and left the target before we raised a + // snapshot, so we can just ignore the change. + target_state.RemoveDocumentChange(key); + } + pending_document_target_mappings_[key].insert(target_id); + + if (updated_document) { + pending_document_updates_[key] = updated_document; + } +} + +void WatchChangeAggregator::RemoveTarget(TargetId target_id) { + target_states_.erase(target_id); +} + +int WatchChangeAggregator::GetCurrentDocumentCountForTarget( + TargetId target_id) { + TargetState& target_state = EnsureTargetState(target_id); + TargetChange target_change = target_state.ToTargetChange(); + return target_metadata_provider_->GetRemoteKeysForTarget(target_id).size() + + target_change.added_documents().size() - + target_change.removed_documents().size(); +} + +void WatchChangeAggregator::RecordPendingTargetRequest(TargetId target_id) { + // For each request we get we need to record we need a response for it. + TargetState& target_state = EnsureTargetState(target_id); + target_state.RecordPendingTargetRequest(); +} + +TargetState& WatchChangeAggregator::EnsureTargetState(TargetId target_id) { + return target_states_[target_id]; +} + +bool WatchChangeAggregator::IsActiveTarget(TargetId target_id) const { + return QueryDataForActiveTarget(target_id) != nil; +} + +FSTQueryData* WatchChangeAggregator::QueryDataForActiveTarget( + TargetId target_id) const { + auto target_state = target_states_.find(target_id); + return target_state != target_states_.end() && + target_state->second.IsPending() + ? nil + : target_metadata_provider_->GetQueryDataForTarget(target_id); +} + +void WatchChangeAggregator::ResetTarget(TargetId target_id) { + auto current_target_state = target_states_.find(target_id); + HARD_ASSERT(current_target_state != target_states_.end() && + !(current_target_state->second.IsPending()), + "Should only reset active targets"); + + target_states_[target_id] = {}; + + // Trigger removal for any documents currently mapped to this target. These + // removals will be part of the initial snapshot if Watch does not resend + // these documents. + DocumentKeySet existingKeys = + target_metadata_provider_->GetRemoteKeysForTarget(target_id); + + for (const DocumentKey& key : existingKeys) { + RemoveDocumentFromTarget(target_id, key, nil); + } +} + +bool WatchChangeAggregator::TargetContainsDocument(TargetId target_id, + const DocumentKey& key) { + const DocumentKeySet& existing_keys = + target_metadata_provider_->GetRemoteKeysForTarget(target_id); + return existing_keys.contains(key); +} + +} // namespace remote +} // namespace firestore +} // namespace firebase diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/remote_objc_bridge.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/remote_objc_bridge.h new file mode 100644 index 0000000..e77b062 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/remote_objc_bridge.h @@ -0,0 +1,179 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_REMOTE_REMOTE_OBJC_BRIDGE_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_REMOTE_REMOTE_OBJC_BRIDGE_H_ + +#if !defined(__OBJC__) +#error "This header only supports Objective-C++" +#endif // !defined(__OBJC__) + +#import + +#include +#include +#include + +#include "Firestore/core/src/firebase/firestore/core/database_info.h" +#include "Firestore/core/src/firebase/firestore/model/snapshot_version.h" +#include "Firestore/core/src/firebase/firestore/model/types.h" +#include "Firestore/core/src/firebase/firestore/remote/watch_change.h" +#include "Firestore/core/src/firebase/firestore/util/status.h" +#include "grpcpp/support/byte_buffer.h" + +#import "Firestore/Protos/objc/google/firestore/v1/Firestore.pbobjc.h" +#import "Firestore/Source/Core/FSTTypes.h" +#import "Firestore/Source/Local/FSTQueryData.h" +#import "Firestore/Source/Model/FSTMutation.h" +#import "Firestore/Source/Remote/FSTSerializerBeta.h" + +namespace firebase { +namespace firestore { +namespace remote { +namespace bridge { + +bool IsLoggingEnabled(); + +/** + * This file contains operations in remote/ folder that are still delegated to + * Objective-C: proto parsing and delegates. + * + * The principle is that the C++ implementation can only take Objective-C + * objects as parameters or return them, but never instantiate them or call any + * methods on them -- if that is necessary, it's delegated to one of the bridge + * classes. This allows easily identifying which parts of remote/ still rely on + * not-yet-ported code. + */ + +/** + * A C++ bridge to `FSTSerializerBeta` that allows creating + * `GCFSListenRequest`s and parsing `GCFSListenResponse`s. + */ +class WatchStreamSerializer { + public: + explicit WatchStreamSerializer(FSTSerializerBeta* serializer) + : serializer_{serializer} { + } + + GCFSListenRequest* CreateWatchRequest(FSTQueryData* query) const; + GCFSListenRequest* CreateUnwatchRequest(model::TargetId target_id) const; + static grpc::ByteBuffer ToByteBuffer(GCFSListenRequest* request); + + /** + * If parsing fails, will return nil and write information on the error to + * `out_status`. Otherwise, returns the parsed proto and sets `out_status` to + * ok. + */ + GCFSListenResponse* ParseResponse(const grpc::ByteBuffer& message, + util::Status* out_status) const; + std::unique_ptr ToWatchChange(GCFSListenResponse* proto) const; + model::SnapshotVersion ToSnapshotVersion(GCFSListenResponse* proto) const; + + /** Creates a pretty-printed description of the proto for debugging. */ + static NSString* Describe(GCFSListenRequest* request); + static NSString* Describe(GCFSListenResponse* request); + + private: + FSTSerializerBeta* serializer_; +}; + +/** + * A C++ bridge to `FSTSerializerBeta` that allows creating + * `GCFSWriteRequest`s and parsing `GCFSWriteResponse`s. + */ +class WriteStreamSerializer { + public: + explicit WriteStreamSerializer(FSTSerializerBeta* serializer) + : serializer_{serializer} { + } + + void UpdateLastStreamToken(GCFSWriteResponse* proto); + void SetLastStreamToken(NSData* token) { + last_stream_token_ = token; + } + NSData* GetLastStreamToken() const { + return last_stream_token_; + } + + GCFSWriteRequest* CreateHandshake() const; + GCFSWriteRequest* CreateWriteMutationsRequest( + const std::vector& mutations) const; + GCFSWriteRequest* CreateEmptyMutationsList() { + return CreateWriteMutationsRequest({}); + } + static grpc::ByteBuffer ToByteBuffer(GCFSWriteRequest* request); + + /** + * If parsing fails, will return nil and write information on the error to + * `out_status`. Otherwise, returns the parsed proto and sets `out_status` to + * ok. + */ + GCFSWriteResponse* ParseResponse(const grpc::ByteBuffer& message, + util::Status* out_status) const; + model::SnapshotVersion ToCommitVersion(GCFSWriteResponse* proto) const; + std::vector ToMutationResults( + GCFSWriteResponse* proto) const; + + /** Creates a pretty-printed description of the proto for debugging. */ + static NSString* Describe(GCFSWriteRequest* request); + static NSString* Describe(GCFSWriteResponse* request); + + private: + FSTSerializerBeta* serializer_; + NSData* last_stream_token_; +}; + +/** + * A C++ bridge to `FSTSerializerBeta` that allows creating + * `GCFSCommitRequest`s and `GCFSBatchGetDocumentsRequest`s and handling + * `GCFSBatchGetDocumentsResponse`s. + */ +class DatastoreSerializer { + public: + explicit DatastoreSerializer(const core::DatabaseInfo& database_info); + + GCFSCommitRequest* CreateCommitRequest( + const std::vector& mutations) const; + static grpc::ByteBuffer ToByteBuffer(GCFSCommitRequest* request); + + GCFSBatchGetDocumentsRequest* CreateLookupRequest( + const std::vector& keys) const; + static grpc::ByteBuffer ToByteBuffer(GCFSBatchGetDocumentsRequest* request); + + /** + * Merges results of the streaming read together. The array is sorted by the + * document key. + */ + std::vector MergeLookupResponses( + const std::vector& responses, + util::Status* out_status) const; + FSTMaybeDocument* ToMaybeDocument( + GCFSBatchGetDocumentsResponse* response) const; + + FSTSerializerBeta* GetSerializer() { + return serializer_; + } + + private: + FSTSerializerBeta* serializer_; +}; + +} // namespace bridge +} // namespace remote +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_REMOTE_REMOTE_OBJC_BRIDGE_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/remote_objc_bridge.mm b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/remote_objc_bridge.mm new file mode 100644 index 0000000..a3f3f65 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/remote_objc_bridge.mm @@ -0,0 +1,306 @@ +/* + * Copyright 2018 Google + * + * 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 "Firestore/core/src/firebase/firestore/remote/remote_objc_bridge.h" + +#include +#include +#include +#include + +#import "Firestore/Source/API/FIRFirestore+Internal.h" + +#include "Firestore/core/src/firebase/firestore/model/snapshot_version.h" +#include "Firestore/core/src/firebase/firestore/util/error_apple.h" +#include "Firestore/core/src/firebase/firestore/util/hard_assert.h" +#include "Firestore/core/src/firebase/firestore/util/string_apple.h" +#include "grpcpp/support/status.h" + +namespace firebase { +namespace firestore { +namespace remote { +namespace bridge { + +using core::DatabaseInfo; +using model::DocumentKey; +using model::TargetId; +using model::SnapshotVersion; +using util::MakeString; +using util::MakeNSError; +using util::Status; +using util::StringFormat; + +namespace { + +std::string ToHexString(const grpc::ByteBuffer& buffer) { + std::vector slices; + grpc::Status status = buffer.Dump(&slices); + + std::stringstream output; + // The output will look like "0x00 0x0a" + output << std::hex << std::setfill('0') << std::setw(2); + for (const auto& slice : slices) { + for (uint8_t c : slice) { + output << "0x" << static_cast(c) << " "; + } + } + + return output.str(); +} + +NSData* ConvertToNsData(const grpc::ByteBuffer& buffer, NSError** out_error) { + std::vector slices; + grpc::Status status = buffer.Dump(&slices); + if (!status.ok()) { + *out_error = + MakeNSError(Status{FirestoreErrorCode::Internal, + "Trying to convert an invalid grpc::ByteBuffer"}); + return nil; + } + + if (slices.size() == 1) { + return [NSData dataWithBytes:slices.front().begin() + length:slices.front().size()]; + } else { + NSMutableData* data = [NSMutableData dataWithCapacity:buffer.Length()]; + for (const auto& slice : slices) { + [data appendBytes:slice.begin() length:slice.size()]; + } + return data; + } +} + +grpc::ByteBuffer ConvertToByteBuffer(NSData* data) { + grpc::Slice slice{[data bytes], [data length]}; + return grpc::ByteBuffer{&slice, 1}; +} + +// Note: `StatusOr` cannot be used with ARC-managed objects. +template +Proto* ToProto(const grpc::ByteBuffer& message, Status* out_status) { + NSError* error = nil; + NSData* data = ConvertToNsData(message, &error); + if (!error) { + Proto* proto = [Proto parseFromData:data error:&error]; + if (!error) { + *out_status = Status::OK(); + return proto; + } + } + + std::string error_description = + StringFormat("Unable to parse response from the server.\n" + "Underlying error: %s\n" + "Expected class: %s\n" + "Received value: %s\n", + error, [Proto class], ToHexString(message)); + + *out_status = {FirestoreErrorCode::Internal, error_description}; + return nil; +} + +} // namespace + +bool IsLoggingEnabled() { + return [FIRFirestore isLoggingEnabled]; +} + +// WatchStreamSerializer + +GCFSListenRequest* WatchStreamSerializer::CreateWatchRequest( + FSTQueryData* query) const { + GCFSListenRequest* request = [GCFSListenRequest message]; + request.database = [serializer_ encodedDatabaseID]; + request.addTarget = [serializer_ encodedTarget:query]; + request.labels = [serializer_ encodedListenRequestLabelsForQueryData:query]; + return request; +} + +GCFSListenRequest* WatchStreamSerializer::CreateUnwatchRequest( + TargetId target_id) const { + GCFSListenRequest* request = [GCFSListenRequest message]; + request.database = [serializer_ encodedDatabaseID]; + request.removeTarget = target_id; + return request; +} + +grpc::ByteBuffer WatchStreamSerializer::ToByteBuffer( + GCFSListenRequest* request) { + return ConvertToByteBuffer([request data]); +} + +GCFSListenResponse* WatchStreamSerializer::ParseResponse( + const grpc::ByteBuffer& message, Status* out_status) const { + return ToProto(message, out_status); +} + +std::unique_ptr WatchStreamSerializer::ToWatchChange( + GCFSListenResponse* proto) const { + return [serializer_ decodedWatchChange:proto]; +} + +SnapshotVersion WatchStreamSerializer::ToSnapshotVersion( + GCFSListenResponse* proto) const { + return [serializer_ versionFromListenResponse:proto]; +} + +NSString* WatchStreamSerializer::Describe(GCFSListenRequest* request) { + return [request description]; +} + +NSString* WatchStreamSerializer::Describe(GCFSListenResponse* response) { + return [response description]; +} + +// WriteStreamSerializer + +void WriteStreamSerializer::UpdateLastStreamToken(GCFSWriteResponse* proto) { + last_stream_token_ = proto.streamToken; +} + +GCFSWriteRequest* WriteStreamSerializer::CreateHandshake() const { + // The initial request cannot contain mutations, but must contain a projectID. + GCFSWriteRequest* request = [GCFSWriteRequest message]; + request.database = [serializer_ encodedDatabaseID]; + return request; +} + +GCFSWriteRequest* WriteStreamSerializer::CreateWriteMutationsRequest( + const std::vector& mutations) const { + NSMutableArray* protos = + [NSMutableArray arrayWithCapacity:mutations.size()]; + for (FSTMutation* mutation : mutations) { + [protos addObject:[serializer_ encodedMutation:mutation]]; + }; + + GCFSWriteRequest* request = [GCFSWriteRequest message]; + request.writesArray = protos; + request.streamToken = last_stream_token_; + + return request; +} + +grpc::ByteBuffer WriteStreamSerializer::ToByteBuffer( + GCFSWriteRequest* request) { + return ConvertToByteBuffer([request data]); +} + +GCFSWriteResponse* WriteStreamSerializer::ParseResponse( + const grpc::ByteBuffer& message, Status* out_status) const { + return ToProto(message, out_status); +} + +model::SnapshotVersion WriteStreamSerializer::ToCommitVersion( + GCFSWriteResponse* proto) const { + return [serializer_ decodedVersion:proto.commitTime]; +} + +std::vector WriteStreamSerializer::ToMutationResults( + GCFSWriteResponse* response) const { + NSMutableArray* responses = response.writeResultsArray; + std::vector results; + results.reserve(responses.count); + + const model::SnapshotVersion commitVersion = ToCommitVersion(response); + for (GCFSWriteResult* proto in responses) { + results.push_back([serializer_ decodedMutationResult:proto + commitVersion:commitVersion]); + }; + return results; +} + +NSString* WriteStreamSerializer::Describe(GCFSWriteRequest* request) { + return [request description]; +} + +NSString* WriteStreamSerializer::Describe(GCFSWriteResponse* response) { + return [response description]; +} + +// DatastoreSerializer + +DatastoreSerializer::DatastoreSerializer(const DatabaseInfo& database_info) + : serializer_{[[FSTSerializerBeta alloc] + initWithDatabaseID:&database_info.database_id()]} { +} + +GCFSCommitRequest* DatastoreSerializer::CreateCommitRequest( + const std::vector& mutations) const { + GCFSCommitRequest* request = [GCFSCommitRequest message]; + request.database = [serializer_ encodedDatabaseID]; + + NSMutableArray* mutationProtos = [NSMutableArray array]; + for (FSTMutation* mutation : mutations) { + [mutationProtos addObject:[serializer_ encodedMutation:mutation]]; + } + request.writesArray = mutationProtos; + + return request; +} + +grpc::ByteBuffer DatastoreSerializer::ToByteBuffer(GCFSCommitRequest* request) { + return ConvertToByteBuffer([request data]); +} + +GCFSBatchGetDocumentsRequest* DatastoreSerializer::CreateLookupRequest( + const std::vector& keys) const { + GCFSBatchGetDocumentsRequest* request = + [GCFSBatchGetDocumentsRequest message]; + + request.database = [serializer_ encodedDatabaseID]; + for (const DocumentKey& key : keys) { + [request.documentsArray addObject:[serializer_ encodedDocumentKey:key]]; + } + + return request; +} + +grpc::ByteBuffer DatastoreSerializer::ToByteBuffer( + GCFSBatchGetDocumentsRequest* request) { + return ConvertToByteBuffer([request data]); +} + +std::vector DatastoreSerializer::MergeLookupResponses( + const std::vector& responses, Status* out_status) const { + // Sort by key. + std::map results; + + for (const auto& response : responses) { + auto* proto = ToProto(response, out_status); + if (!out_status->ok()) { + return {}; + } + FSTMaybeDocument* doc = [serializer_ decodedMaybeDocumentFromBatch:proto]; + results[doc.key] = doc; + } + + std::vector docs; + docs.reserve(results.size()); + for (const auto& kv : results) { + docs.push_back(kv.second); + } + return docs; +} + +FSTMaybeDocument* DatastoreSerializer::ToMaybeDocument( + GCFSBatchGetDocumentsResponse* response) const { + return [serializer_ decodedMaybeDocumentFromBatch:response]; +} + +} // namespace bridge +} // namespace remote +} // namespace firestore +} // namespace firebase diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/remote_store.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/remote_store.h new file mode 100644 index 0000000..6489f88 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/remote_store.h @@ -0,0 +1,306 @@ +/* + * Copyright 2019 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_REMOTE_REMOTE_STORE_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_REMOTE_REMOTE_STORE_H_ + +#if !defined(__OBJC__) +#error "This header only supports Objective-C++" +#endif // !defined(__OBJC__) + +#import + +#include +#include +#include + +#include "Firestore/core/src/firebase/firestore/core/transaction.h" +#include "Firestore/core/src/firebase/firestore/model/document_key_set.h" +#include "Firestore/core/src/firebase/firestore/model/snapshot_version.h" +#include "Firestore/core/src/firebase/firestore/model/types.h" +#include "Firestore/core/src/firebase/firestore/remote/datastore.h" +#include "Firestore/core/src/firebase/firestore/remote/online_state_tracker.h" +#include "Firestore/core/src/firebase/firestore/remote/remote_event.h" +#include "Firestore/core/src/firebase/firestore/remote/watch_change.h" +#include "Firestore/core/src/firebase/firestore/remote/watch_stream.h" +#include "Firestore/core/src/firebase/firestore/remote/write_stream.h" +#include "Firestore/core/src/firebase/firestore/util/async_queue.h" +#include "Firestore/core/src/firebase/firestore/util/status.h" + +@class FSTLocalStore; +@class FSTMutationBatch; +@class FSTMutationBatchResult; +@class FSTQueryData; +@class FSTTransaction; + +NS_ASSUME_NONNULL_BEGIN + +/** + * A protocol that describes the actions the `RemoteStore` needs to perform on + * a cooperating synchronization engine. + */ +@protocol FSTRemoteSyncer + +/** + * Applies one remote event to the sync engine, notifying any views of the + * changes, and releasing any pending mutation batches that would become visible + * because of the snapshot version the remote event contains. + */ +- (void)applyRemoteEvent: + (const firebase::firestore::remote::RemoteEvent&)remoteEvent; + +/** + * Rejects the listen for the given targetID. This can be triggered by the + * backend for any active target. + * + * @param targetID The targetID corresponding to a listen initiated via + * `RemoteStore::Listen`. + * @param error A description of the condition that has forced the rejection. + * Nearly always this will be an indication that the user is no longer + * authorized to see the data matching the target. + */ +- (void)rejectListenWithTargetID: + (const firebase::firestore::model::TargetId)targetID + error: + (NSError*)error; // NOLINT(readability/casting) + +/** + * Applies the result of a successful write of a mutation batch to the sync + * engine, emitting snapshots in any views that the mutation applies to, and + * removing the batch from the mutation queue. + */ +- (void)applySuccessfulWriteWithResult: + (FSTMutationBatchResult*)batchResult; // NOLINT(readability/casting) + +/** + * Rejects the batch, removing the batch from the mutation queue, recomputing + * the local view of any documents affected by the batch and then, emitting + * snapshots with the reverted value. + */ +- (void) + rejectFailedWriteWithBatchID:(firebase::firestore::model::BatchId)batchID + error: + (NSError*)error; // NOLINT(readability/casting) + +/** + * Returns the set of remote document keys for the given target ID. This list + * includes the documents that were assigned to the target when we received the + * last snapshot. + */ +- (firebase::firestore::model::DocumentKeySet)remoteKeysForTarget: + (firebase::firestore::model::TargetId)targetId; + +@end + +namespace firebase { +namespace firestore { +namespace remote { + +class RemoteStore : public TargetMetadataProvider, + public WatchStreamCallback, + public WriteStreamCallback { + public: + RemoteStore(FSTLocalStore* local_store, + std::shared_ptr datastore, + util::AsyncQueue* worker_queue, + std::function online_state_handler); + + void set_sync_engine(id sync_engine) { + sync_engine_ = sync_engine; + } + + /** + * Starts up the remote store, creating streams, restoring state from + * `FSTLocalStore`, etc. + */ + void Start(); + + /** + * Shuts down the remote store, tearing down connections and otherwise + * cleaning up. + */ + void Shutdown(); + + /** + * Temporarily disables the network. The network can be re-enabled using + * 'EnableNetwork'. + */ + void DisableNetwork(); + + /** + * Re-enables the network. Only to be called as the counterpart to + * 'DisableNetwork'. + */ + void EnableNetwork(); + + /** + * Tells the `RemoteStore` that the currently authenticated user has changed. + * + * In response the remote store tears down streams and clears up any tracked + * operations that should not persist across users. Restarts the streams if + * appropriate. + */ + void HandleCredentialChange(); + + /** Listens to the target identified by the given `FSTQueryData`. */ + void Listen(FSTQueryData* query_data); + + /** Stops listening to the target with the given target ID. */ + void StopListening(model::TargetId target_id); + + /** + * Attempts to fill our write pipeline with writes from the `FSTLocalStore`. + * + * Called internally to bootstrap or refill the write pipeline and by + * `FSTSyncEngine` whenever there are new mutations to process. + * + * Starts the write stream if necessary. + */ + void FillWritePipeline(); + + /** + * Queues additional writes to be sent to the write stream, sending them + * immediately if the write stream is established. + */ + void AddToWritePipeline(FSTMutationBatch* batch); + + /** Returns a new transaction backed by this remote store. */ + // TODO(c++14): return a plain value when it becomes possible to move + // `Transaction` into lambdas. + std::shared_ptr CreateTransaction(); + + model::DocumentKeySet GetRemoteKeysForTarget( + model::TargetId target_id) const override; + FSTQueryData* GetQueryDataForTarget(model::TargetId target_id) const override; + + void OnWatchStreamOpen() override; + void OnWatchStreamChange( + const WatchChange& change, + const model::SnapshotVersion& snapshot_version) override; + void OnWatchStreamClose(const util::Status& status) override; + + void OnWriteStreamOpen() override; + void OnWriteStreamHandshakeComplete() override; + void OnWriteStreamClose(const util::Status& status) override; + void OnWriteStreamMutationResult( + model::SnapshotVersion commit_version, + std::vector mutation_results) override; + + private: + void DisableNetworkInternal(); + + void SendWatchRequest(FSTQueryData* query_data); + void SendUnwatchRequest(model::TargetId target_id); + + /** + * Takes a batch of changes from the `Datastore`, repackages them as a + * `RemoteEvent`, and passes that on to the `SyncEngine`. + */ + void RaiseWatchSnapshot(const model::SnapshotVersion& snapshot_version); + + /** Process a target error and passes the error along to `SyncEngine`. */ + void ProcessTargetError(const WatchTargetChange& change); + + /** + * Returns true if we can add to the write pipeline (i.e. it is not full and + * the network is enabled). + */ + bool CanAddToWritePipeline() const; + + void StartWriteStream(); + + /** + * Returns true if the network is enabled, the write stream has not yet been + * started and there are pending writes. + */ + bool ShouldStartWriteStream() const; + + void HandleHandshakeError(const util::Status& status); + void HandleWriteError(const util::Status& status); + + bool CanUseNetwork() const; + + void StartWatchStream(); + + /** + * Returns true if the network is enabled, the watch stream has not yet been + * started and there are active watch targets. + */ + bool ShouldStartWatchStream() const; + + void CleanUpWatchStreamState(); + + id sync_engine_ = nil; + + /** + * The local store, used to fill the write pipeline with outbound mutations + * and resolve existence filter mismatches. + */ + FSTLocalStore* local_store_ = nil; + + /** The client-side proxy for interacting with the backend. */ + std::shared_ptr datastore_; + + /** + * A mapping of watched targets that the client cares about tracking and the + * user has explicitly called a 'listen' for this target. + * + * These targets may or may not have been sent to or acknowledged by the + * server. On re-establishing the listen stream, these targets should be sent + * to the server. The targets removed with unlistens are removed eagerly + * without waiting for confirmation from the listen stream. + */ + std::unordered_map listen_targets_; + + OnlineStateTracker online_state_tracker_; + + /** + * Set to true by `EnableNetwork` and false by `DisableNetwork` and indicates + * the user-preferred network state. + */ + bool is_network_enabled_ = false; + + std::shared_ptr watch_stream_; + std::shared_ptr write_stream_; + std::unique_ptr watch_change_aggregator_; + + /** + * A list of up to `kMaxPendingWrites` writes that we have fetched from the + * `LocalStore` via `FillWritePipeline` and have or will send to the write + * stream. + * + * Whenever `write_pipeline_` is not empty, the `RemoteStore` will attempt to + * start or restart the write stream. When the stream is established, the + * writes in the pipeline will be sent in order. + * + * Writes remain in `write_pipeline_` until they are acknowledged by the + * backend and thus will automatically be re-sent if the stream is interrupted + * / restarted before they're acknowledged. + * + * Write responses from the backend are linked to their originating request + * purely based on order, and so we can just remove writes from the front of + * the `write_pipeline_` as we receive responses. + */ + std::vector write_pipeline_; +}; + +} // namespace remote +} // namespace firestore +} // namespace firebase + +NS_ASSUME_NONNULL_END + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_REMOTE_REMOTE_STORE_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/remote_store.mm b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/remote_store.mm new file mode 100644 index 0000000..ce46f27 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/remote_store.mm @@ -0,0 +1,552 @@ +/* + * Copyright 2019 Google + * + * 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 "Firestore/core/src/firebase/firestore/remote/remote_store.h" + +#include + +#import "Firestore/Source/Local/FSTLocalStore.h" +#import "Firestore/Source/Local/FSTQueryData.h" +#import "Firestore/Source/Model/FSTMutationBatch.h" + +#include "Firestore/core/src/firebase/firestore/core/transaction.h" +#include "Firestore/core/src/firebase/firestore/model/mutation_batch.h" +#include "Firestore/core/src/firebase/firestore/util/error_apple.h" +#include "Firestore/core/src/firebase/firestore/util/hard_assert.h" +#include "Firestore/core/src/firebase/firestore/util/log.h" +#include "absl/memory/memory.h" + +using firebase::firestore::core::Transaction; +using firebase::firestore::model::BatchId; +using firebase::firestore::model::DocumentKeySet; +using firebase::firestore::model::OnlineState; +using firebase::firestore::model::SnapshotVersion; +using firebase::firestore::model::TargetId; +using firebase::firestore::model::kBatchIdUnknown; +using firebase::firestore::remote::Datastore; +using firebase::firestore::remote::WatchStream; +using firebase::firestore::remote::DocumentWatchChange; +using firebase::firestore::remote::ExistenceFilterWatchChange; +using firebase::firestore::remote::OnlineStateTracker; +using firebase::firestore::remote::RemoteEvent; +using firebase::firestore::remote::TargetChange; +using firebase::firestore::remote::WatchChange; +using firebase::firestore::remote::WatchChangeAggregator; +using firebase::firestore::remote::WatchTargetChange; +using firebase::firestore::remote::WatchTargetChangeState; +using firebase::firestore::util::AsyncQueue; +using firebase::firestore::util::Status; + +namespace firebase { +namespace firestore { +namespace remote { + +/** + * The maximum number of pending writes to allow. + * TODO(b/35853402): Negotiate this value with the backend. + */ +constexpr int kMaxPendingWrites = 10; + +RemoteStore::RemoteStore( + FSTLocalStore* local_store, + std::shared_ptr datastore, + AsyncQueue* worker_queue, + std::function online_state_handler) + : local_store_{local_store}, + datastore_{std::move(datastore)}, + online_state_tracker_{worker_queue, std::move(online_state_handler)} { + datastore_->Start(); + + // Create streams (but note they're not started yet) + watch_stream_ = datastore_->CreateWatchStream(this); + write_stream_ = datastore_->CreateWriteStream(this); +} + +void RemoteStore::Start() { + // For now, all setup is handled by `EnableNetwork`. We might expand on this + // in the future. + EnableNetwork(); +} + +void RemoteStore::EnableNetwork() { + is_network_enabled_ = true; + + if (CanUseNetwork()) { + // Load any saved stream token from persistent storage + write_stream_->SetLastStreamToken([local_store_ lastStreamToken]); + + if (ShouldStartWatchStream()) { + StartWatchStream(); + } else { + online_state_tracker_.UpdateState(OnlineState::Unknown); + } + + // This will start the write stream if necessary. + FillWritePipeline(); + } +} + +void RemoteStore::DisableNetwork() { + is_network_enabled_ = false; + DisableNetworkInternal(); + + // Set the OnlineState to Offline so get()s return from cache, etc. + online_state_tracker_.UpdateState(OnlineState::Offline); +} + +void RemoteStore::DisableNetworkInternal() { + watch_stream_->Stop(); + write_stream_->Stop(); + + if (!write_pipeline_.empty()) { + LOG_DEBUG("Stopping write stream with %s pending writes", + write_pipeline_.size()); + write_pipeline_.clear(); + } + + CleanUpWatchStreamState(); +} + +void RemoteStore::Shutdown() { + LOG_DEBUG("RemoteStore %s shutting down", this); + is_network_enabled_ = false; + DisableNetworkInternal(); + + // Set the `OnlineState` to `Unknown` (rather than `Offline`) to avoid + // potentially triggering spurious listener events with cached data, etc. + online_state_tracker_.UpdateState(OnlineState::Unknown); + + datastore_->Shutdown(); +} + +// Watch Stream + +void RemoteStore::Listen(FSTQueryData* query_data) { + TargetId targetKey = query_data.targetID; + HARD_ASSERT(listen_targets_.find(targetKey) == listen_targets_.end(), + "Listen called with duplicate target id: %s", targetKey); + + // Mark this as something the client is currently listening for. + listen_targets_[targetKey] = query_data; + + if (ShouldStartWatchStream()) { + // The listen will be sent in `OnWatchStreamOpen` + StartWatchStream(); + } else if (watch_stream_->IsOpen()) { + SendWatchRequest(query_data); + } +} + +void RemoteStore::StopListening(TargetId target_id) { + size_t num_erased = listen_targets_.erase(target_id); + HARD_ASSERT(num_erased == 1, + "StopListening: target not currently watched: %s", target_id); + + // The watch stream might not be started if we're in a disconnected state + if (watch_stream_->IsOpen()) { + SendUnwatchRequest(target_id); + } + if (listen_targets_.empty()) { + if (watch_stream_->IsOpen()) { + watch_stream_->MarkIdle(); + } else if (CanUseNetwork()) { + // Revert to `OnlineState::Unknown` if the watch stream is not open and we + // have no listeners, since without any listens to send we cannot confirm + // if the stream is healthy and upgrade to `OnlineState::Online`. + online_state_tracker_.UpdateState(OnlineState::Unknown); + } + } +} + +void RemoteStore::SendWatchRequest(FSTQueryData* query_data) { + // We need to increment the the expected number of pending responses we're due + // from watch so we wait for the ack to process any messages from this target. + watch_change_aggregator_->RecordPendingTargetRequest(query_data.targetID); + watch_stream_->WatchQuery(query_data); +} + +void RemoteStore::SendUnwatchRequest(TargetId target_id) { + // We need to increment the expected number of pending responses we're due + // from watch so we wait for the removal on the server before we process any + // messages from this target. + watch_change_aggregator_->RecordPendingTargetRequest(target_id); + watch_stream_->UnwatchTargetId(target_id); +} + +bool RemoteStore::ShouldStartWatchStream() const { + return CanUseNetwork() && !watch_stream_->IsStarted() && + !listen_targets_.empty(); +} + +void RemoteStore::StartWatchStream() { + HARD_ASSERT(ShouldStartWatchStream(), + "StartWatchStream called when ShouldStartWatchStream is false."); + watch_change_aggregator_ = absl::make_unique(this); + watch_stream_->Start(); + + online_state_tracker_.HandleWatchStreamStart(); +} + +void RemoteStore::CleanUpWatchStreamState() { + watch_change_aggregator_.reset(); +} + +void RemoteStore::OnWatchStreamOpen() { + // Restore any existing watches. + for (const auto& kv : listen_targets_) { + SendWatchRequest(kv.second); + } +} + +void RemoteStore::OnWatchStreamClose(const Status& status) { + if (status.ok()) { + // Graceful stop (due to Stop() or idle timeout). Make sure that's + // desirable. + HARD_ASSERT(!ShouldStartWatchStream(), + "Watch stream was stopped gracefully while still needed."); + } + + CleanUpWatchStreamState(); + + // If we still need the watch stream, retry the connection. + if (ShouldStartWatchStream()) { + online_state_tracker_.HandleWatchStreamFailure(status); + + StartWatchStream(); + } else { + // We don't need to restart the watch stream because there are no active + // targets. The online state is set to unknown because there is no active + // attempt at establishing a connection. + online_state_tracker_.UpdateState(OnlineState::Unknown); + } +} + +void RemoteStore::OnWatchStreamChange(const WatchChange& change, + const SnapshotVersion& snapshot_version) { + // Mark the connection as Online because we got a message from the server. + online_state_tracker_.UpdateState(OnlineState::Online); + + if (change.type() == WatchChange::Type::TargetChange) { + const WatchTargetChange& watch_target_change = + static_cast(change); + if (watch_target_change.state() == WatchTargetChangeState::Removed && + !watch_target_change.cause().ok()) { + // There was an error on a target, don't wait for a consistent snapshot to + // raise events + return ProcessTargetError(watch_target_change); + } else { + watch_change_aggregator_->HandleTargetChange(watch_target_change); + } + } else if (change.type() == WatchChange::Type::Document) { + watch_change_aggregator_->HandleDocumentChange( + static_cast(change)); + } else { + HARD_ASSERT( + change.type() == WatchChange::Type::ExistenceFilter, + "Expected watchChange to be an instance of ExistenceFilterWatchChange"); + watch_change_aggregator_->HandleExistenceFilter( + static_cast(change)); + } + + if (snapshot_version != SnapshotVersion::None() && + snapshot_version >= [local_store_ lastRemoteSnapshotVersion]) { + // We have received a target change with a global snapshot if the snapshot + // version is not equal to `SnapshotVersion::None()`. + RaiseWatchSnapshot(snapshot_version); + } +} + +void RemoteStore::RaiseWatchSnapshot(const SnapshotVersion& snapshot_version) { + HARD_ASSERT(snapshot_version != SnapshotVersion::None(), + "Can't raise event for unknown SnapshotVersion"); + + RemoteEvent remote_event = + watch_change_aggregator_->CreateRemoteEvent(snapshot_version); + + // Update in-memory resume tokens. `FSTLocalStore` will update the persistent + // view of these when applying the completed `RemoteEvent`. + for (const auto& entry : remote_event.target_changes()) { + const TargetChange& target_change = entry.second; + NSData* resumeToken = target_change.resume_token(); + + if (resumeToken.length > 0) { + TargetId target_id = entry.first; + auto found = listen_targets_.find(target_id); + FSTQueryData* query_data = + found != listen_targets_.end() ? found->second : nil; + + // A watched target might have been removed already. + if (query_data) { + listen_targets_[target_id] = [query_data + queryDataByReplacingSnapshotVersion:snapshot_version + resumeToken:resumeToken + sequenceNumber:query_data.sequenceNumber]; + } + } + } + + // Re-establish listens for the targets that have been invalidated by + // existence filter mismatches. + for (TargetId target_id : remote_event.target_mismatches()) { + auto found = listen_targets_.find(target_id); + if (found == listen_targets_.end()) { + // A watched target might have been removed already. + continue; + } + FSTQueryData* query_data = found->second; + + // Clear the resume token for the query, since we're in a known mismatch + // state. + query_data = [[FSTQueryData alloc] initWithQuery:query_data.query + targetID:target_id + listenSequenceNumber:query_data.sequenceNumber + purpose:query_data.purpose]; + listen_targets_[target_id] = query_data; + + // Cause a hard reset by unwatching and rewatching immediately, but + // deliberately don't send a resume token so that we get a full update. + SendUnwatchRequest(target_id); + + // Mark the query we send as being on behalf of an existence filter + // mismatch, but don't actually retain that in listen_targets_. This ensures + // that we flag the first re-listen this way without impacting future + // listens of this target (that might happen e.g. on reconnect). + FSTQueryData* request_query_data = [[FSTQueryData alloc] + initWithQuery:query_data.query + targetID:target_id + listenSequenceNumber:query_data.sequenceNumber + purpose:FSTQueryPurposeExistenceFilterMismatch]; + SendWatchRequest(request_query_data); + } + + // Finally handle remote event + [sync_engine_ applyRemoteEvent:remote_event]; +} + +void RemoteStore::ProcessTargetError(const WatchTargetChange& change) { + HARD_ASSERT(!change.cause().ok(), "Handling target error without a cause"); + + // Ignore targets that have been removed already. + for (TargetId target_id : change.target_ids()) { + auto found = listen_targets_.find(target_id); + if (found != listen_targets_.end()) { + listen_targets_.erase(found); + watch_change_aggregator_->RemoveTarget(target_id); + [sync_engine_ rejectListenWithTargetID:target_id + error:util::MakeNSError(change.cause())]; + } + } +} + +// Write Stream + +void RemoteStore::FillWritePipeline() { + BatchId last_batch_id_retrieved = write_pipeline_.empty() + ? kBatchIdUnknown + : write_pipeline_.back().batchID; + while (CanAddToWritePipeline()) { + FSTMutationBatch* batch = + [local_store_ nextMutationBatchAfterBatchID:last_batch_id_retrieved]; + if (!batch) { + if (write_pipeline_.empty()) { + write_stream_->MarkIdle(); + } + break; + } + AddToWritePipeline(batch); + last_batch_id_retrieved = batch.batchID; + } + + if (ShouldStartWriteStream()) { + StartWriteStream(); + } +} + +bool RemoteStore::CanAddToWritePipeline() const { + return CanUseNetwork() && write_pipeline_.size() < kMaxPendingWrites; +} + +void RemoteStore::AddToWritePipeline(FSTMutationBatch* batch) { + HARD_ASSERT(CanAddToWritePipeline(), + "AddToWritePipeline called when pipeline is full"); + + write_pipeline_.push_back(batch); + + if (write_stream_->IsOpen() && write_stream_->handshake_complete()) { + write_stream_->WriteMutations(batch.mutations); + } +} + +bool RemoteStore::ShouldStartWriteStream() const { + return CanUseNetwork() && !write_stream_->IsStarted() && + !write_pipeline_.empty(); +} + +void RemoteStore::StartWriteStream() { + HARD_ASSERT(ShouldStartWriteStream(), "StartWriteStream called when " + "ShouldStartWriteStream is false."); + write_stream_->Start(); +} + +void RemoteStore::OnWriteStreamOpen() { + write_stream_->WriteHandshake(); +} + +void RemoteStore::OnWriteStreamHandshakeComplete() { + // Record the stream token. + [local_store_ setLastStreamToken:write_stream_->GetLastStreamToken()]; + + // Send the write pipeline now that the stream is established. + for (FSTMutationBatch* write : write_pipeline_) { + write_stream_->WriteMutations(write.mutations); + } +} + +void RemoteStore::OnWriteStreamMutationResult( + SnapshotVersion commit_version, + std::vector mutation_results) { + // This is a response to a write containing mutations and should be correlated + // to the first write in our write pipeline. + HARD_ASSERT(!write_pipeline_.empty(), "Got result for empty write pipeline"); + + FSTMutationBatch* batch = write_pipeline_.front(); + write_pipeline_.erase(write_pipeline_.begin()); + + FSTMutationBatchResult* batchResult = [FSTMutationBatchResult + resultWithBatch:batch + commitVersion:commit_version + mutationResults:std::move(mutation_results) + streamToken:write_stream_->GetLastStreamToken()]; + [sync_engine_ applySuccessfulWriteWithResult:batchResult]; + + // It's possible that with the completion of this mutation another slot has + // freed up. + FillWritePipeline(); +} + +void RemoteStore::OnWriteStreamClose(const Status& status) { + if (status.ok()) { + // Graceful stop (due to Stop() or idle timeout). Make sure that's + // desirable. + HARD_ASSERT(!ShouldStartWriteStream(), + "Write stream was stopped gracefully while still needed."); + } + + // If the write stream closed due to an error, invoke the error callbacks if + // there are pending writes. + if (!status.ok() && !write_pipeline_.empty()) { + // TODO(varconst): handle UNAUTHENTICATED status, see + // go/firestore-client-errors + if (write_stream_->handshake_complete()) { + // This error affects the actual writes. + HandleWriteError(status); + } else { + // If there was an error before the handshake finished, it's possible that + // the server is unable to process the stream token we're sending. + // (Perhaps it's too old?) + HandleHandshakeError(status); + } + } + + // The write stream might have been started by refilling the write pipeline + // for failed writes + if (ShouldStartWriteStream()) { + StartWriteStream(); + } +} + +void RemoteStore::HandleHandshakeError(const Status& status) { + HARD_ASSERT(!status.ok(), "Handling write error with status OK."); + + // Reset the token if it's a permanent error, signaling the write stream is + // no longer valid. Note that the handshake does not count as a write: see + // comments on `Datastore::IsPermanentWriteError` for details. + if (Datastore::IsPermanentError(status)) { + NSString* token = + [write_stream_->GetLastStreamToken() base64EncodedStringWithOptions:0]; + LOG_DEBUG("RemoteStore %s error before completed handshake; resetting " + "stream token %s: " + "error code: '%s', details: '%s'", + this, token, status.code(), status.error_message()); + write_stream_->SetLastStreamToken(nil); + [local_store_ setLastStreamToken:nil]; + } else { + // Some other error, don't reset stream token. Our stream logic will just + // retry with exponential backoff. + } +} + +void RemoteStore::HandleWriteError(const Status& status) { + HARD_ASSERT(!status.ok(), "Handling write error with status OK."); + + // Only handle permanent errors here. If it's transient, just let the retry + // logic kick in. + if (!Datastore::IsPermanentWriteError(status)) { + return; + } + + // If this was a permanent error, the request itself was the problem so it's + // not going to succeed if we resend it. + FSTMutationBatch* batch = write_pipeline_.front(); + write_pipeline_.erase(write_pipeline_.begin()); + + // In this case it's also unlikely that the server itself is melting + // down--this was just a bad request so inhibit backoff on the next restart. + write_stream_->InhibitBackoff(); + + [sync_engine_ rejectFailedWriteWithBatchID:batch.batchID + error:util::MakeNSError(status)]; + + // It's possible that with the completion of this mutation another slot has + // freed up. + FillWritePipeline(); +} + +bool RemoteStore::CanUseNetwork() const { + // PORTING NOTE: This method exists mostly because web also has to take into + // account primary vs. secondary state. + return is_network_enabled_; +} + +std::shared_ptr RemoteStore::CreateTransaction() { + return std::make_shared(datastore_.get()); +} + +DocumentKeySet RemoteStore::GetRemoteKeysForTarget(TargetId target_id) const { + return [sync_engine_ remoteKeysForTarget:target_id]; +} + +FSTQueryData* RemoteStore::GetQueryDataForTarget(TargetId target_id) const { + auto found = listen_targets_.find(target_id); + return found != listen_targets_.end() ? found->second : nil; +} + +void RemoteStore::HandleCredentialChange() { + if (CanUseNetwork()) { + // Tear down and re-create our network streams. This will ensure we get a + // fresh auth token for the new user and re-fill the write pipeline with new + // mutations from the `FSTLocalStore` (since mutations are per-user). + LOG_DEBUG("RemoteStore %s restarting streams for new credential", this); + is_network_enabled_ = false; + DisableNetworkInternal(); + online_state_tracker_.UpdateState(OnlineState::Unknown); + EnableNetwork(); + } +} + +} // namespace remote +} // namespace firestore +} // namespace firebase diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/serializer.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/serializer.cc new file mode 100644 index 0000000..cd0b9a1 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/serializer.cc @@ -0,0 +1,925 @@ +/* + * Copyright 2018 Google + * + * 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 "Firestore/core/src/firebase/firestore/remote/serializer.h" + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "Firestore/Protos/nanopb/google/firestore/v1/document.nanopb.h" +#include "Firestore/Protos/nanopb/google/firestore/v1/firestore.nanopb.h" +#include "Firestore/core/include/firebase/firestore/firestore_errors.h" +#include "Firestore/core/include/firebase/firestore/timestamp.h" +#include "Firestore/core/src/firebase/firestore/model/document.h" +#include "Firestore/core/src/firebase/firestore/model/field_path.h" +#include "Firestore/core/src/firebase/firestore/model/field_value.h" +#include "Firestore/core/src/firebase/firestore/model/no_document.h" +#include "Firestore/core/src/firebase/firestore/model/resource_path.h" +#include "Firestore/core/src/firebase/firestore/nanopb/nanopb_util.h" +#include "Firestore/core/src/firebase/firestore/nanopb/reader.h" +#include "Firestore/core/src/firebase/firestore/nanopb/writer.h" +#include "Firestore/core/src/firebase/firestore/timestamp_internal.h" +#include "Firestore/core/src/firebase/firestore/util/hard_assert.h" +#include "Firestore/core/src/firebase/firestore/util/string_format.h" +#include "absl/base/casts.h" +#include "absl/memory/memory.h" + +namespace firebase { +namespace firestore { +namespace remote { + +using firebase::Timestamp; +using firebase::TimestampInternal; +using firebase::firestore::core::Query; +using firebase::firestore::model::DatabaseId; +using firebase::firestore::model::DeleteMutation; +using firebase::firestore::model::Document; +using firebase::firestore::model::DocumentKey; +using firebase::firestore::model::DocumentState; +using firebase::firestore::model::FieldMask; +using firebase::firestore::model::FieldPath; +using firebase::firestore::model::FieldValue; +using firebase::firestore::model::MaybeDocument; +using firebase::firestore::model::Mutation; +using firebase::firestore::model::NoDocument; +using firebase::firestore::model::ObjectValue; +using firebase::firestore::model::PatchMutation; +using firebase::firestore::model::Precondition; +using firebase::firestore::model::ResourcePath; +using firebase::firestore::model::SetMutation; +using firebase::firestore::model::SnapshotVersion; +using firebase::firestore::nanopb::CheckedSize; +using firebase::firestore::nanopb::Reader; +using firebase::firestore::nanopb::Writer; +using firebase::firestore::util::Status; +using firebase::firestore::util::StringFormat; + +pb_bytes_array_t* Serializer::EncodeString(const std::string& str) { + pb_size_t size = CheckedSize(str.size()); + auto result = + static_cast(malloc(PB_BYTES_ARRAY_T_ALLOCSIZE(size))); + result->size = size; + memcpy(result->bytes, str.c_str(), size); + return result; +} + +std::string Serializer::DecodeString(const pb_bytes_array_t* str) { + if (str == nullptr) return ""; + size_t size = static_cast(str->size); + return std::string{reinterpret_cast(str->bytes), size}; +} + +pb_bytes_array_t* Serializer::EncodeBytes(const std::vector& bytes) { + pb_size_t size = CheckedSize(bytes.size()); + auto result = + static_cast(malloc(PB_BYTES_ARRAY_T_ALLOCSIZE(size))); + result->size = size; + memcpy(result->bytes, bytes.data(), size); + return result; +} + +std::vector Serializer::DecodeBytes(const pb_bytes_array_t* bytes) { + if (bytes == nullptr) return {}; + return std::vector(bytes->bytes, bytes->bytes + bytes->size); +} + +namespace { + +FieldValue::Map DecodeMapValue(Reader* reader, + const google_firestore_v1_MapValue& map_value); + +// There's no f:f::model equivalent of StructuredQuery, so we'll create our +// own struct for decoding. We could use nanopb's struct, but it's slightly +// inconvenient since it's a fixed size (so uses callbacks to represent +// strings, repeated fields, etc.) +struct StructuredQuery { + struct CollectionSelector { + std::string collection_id; + bool all_descendants; + }; + // TODO(rsgowman): other submessages + + std::vector from; + // TODO(rsgowman): other fields +}; + +FieldValue::Map::value_type DecodeFieldsEntry( + Reader* reader, const google_firestore_v1_Document_FieldsEntry& fields) { + std::string key = Serializer::DecodeString(fields.key); + FieldValue value = Serializer::DecodeFieldValue(reader, fields.value); + + if (key.empty()) { + reader->Fail( + "Invalid message: Empty key while decoding a Map field value."); + return {}; + } + + return FieldValue::Map::value_type{std::move(key), std::move(value)}; +} + +FieldValue::Map DecodeFields( + Reader* reader, + size_t count, + const google_firestore_v1_Document_FieldsEntry* fields) { + FieldValue::Map result; + for (size_t i = 0; i < count; i++) { + FieldValue::Map::value_type kv = DecodeFieldsEntry(reader, fields[i]); + result = result.insert(std::move(kv.first), std::move(kv.second)); + } + + return result; +} + +google_firestore_v1_MapValue EncodeMapValue(const ObjectValue& object_value) { + google_firestore_v1_MapValue result{}; + + pb_size_t count = CheckedSize(object_value.GetInternalValue().size()); + + result.fields_count = count; + result.fields = MakeArray(count); + + int i = 0; + for (const auto& kv : object_value.GetInternalValue()) { + result.fields[i].key = Serializer::EncodeString(kv.first); + result.fields[i].value = Serializer::EncodeFieldValue(kv.second); + i++; + } + + return result; +} + +FieldValue::Map DecodeMapValue(Reader* reader, + const google_firestore_v1_MapValue& map_value) { + FieldValue::Map result; + + for (size_t i = 0; i < map_value.fields_count; i++) { + std::string key = Serializer::DecodeString(map_value.fields[i].key); + FieldValue value = + Serializer::DecodeFieldValue(reader, map_value.fields[i].value); + + result = result.insert(key, value); + } + + return result; +} + +/** + * Creates the prefix for a fully qualified resource path, without a local path + * on the end. + */ +ResourcePath EncodeDatabaseId(const DatabaseId& database_id) { + return ResourcePath{"projects", database_id.project_id(), "databases", + database_id.database_id()}; +} + +/** + * Encodes a databaseId and resource path into the following form: + * /projects/$projectId/database/$databaseId/documents/$path + */ +std::string EncodeResourceName(const DatabaseId& database_id, + const ResourcePath& path) { + return EncodeDatabaseId(database_id) + .Append("documents") + .Append(path) + .CanonicalString(); +} + +/** + * Validates that a path has a prefix that looks like a valid encoded + * databaseId. + */ +bool IsValidResourceName(const ResourcePath& path) { + // Resource names have at least 4 components (project ID, database ID) + // and commonly the (root) resource type, e.g. documents + return path.size() >= 4 && path[0] == "projects" && path[2] == "databases"; +} + +/** + * Decodes a fully qualified resource name into a resource path and validates + * that there is a project and database encoded in the path. There are no + * guarantees that a local path is also encoded in this resource name. + */ +ResourcePath DecodeResourceName(Reader* reader, absl::string_view encoded) { + ResourcePath resource = ResourcePath::FromString(encoded); + if (!IsValidResourceName(resource)) { + reader->Fail(StringFormat("Tried to deserialize an invalid key %s", + resource.CanonicalString())); + } + return resource; +} + +/** + * Decodes a fully qualified resource name into a resource path and validates + * that there is a project and database encoded in the path along with a local + * path. + */ +ResourcePath ExtractLocalPathFromResourceName( + Reader* reader, const ResourcePath& resource_name) { + if (resource_name.size() <= 4 || resource_name[4] != "documents") { + reader->Fail(StringFormat("Tried to deserialize invalid key %s", + resource_name.CanonicalString())); + return ResourcePath{}; + } + return resource_name.PopFirst(5); +} + +StructuredQuery::CollectionSelector DecodeCollectionSelector( + const google_firestore_v1_StructuredQuery_CollectionSelector& proto) { + StructuredQuery::CollectionSelector collection_selector{}; + + collection_selector.collection_id = + Serializer::DecodeString(proto.collection_id); + collection_selector.all_descendants = proto.all_descendants; + + return collection_selector; +} + +StructuredQuery DecodeStructuredQuery( + const google_firestore_v1_StructuredQuery& proto) { + StructuredQuery query{}; + + for (size_t i = 0; i < proto.from_count; i++) { + query.from.push_back(DecodeCollectionSelector(proto.from[i])); + } + + // TODO(rsgowman): decode other fields + + return query; +} + +} // namespace + +Serializer::Serializer( + const firebase::firestore::model::DatabaseId& database_id) + : database_id_(database_id), + database_name_(EncodeDatabaseId(database_id).CanonicalString()) { +} + +void Serializer::FreeNanopbMessage(const pb_field_t fields[], + void* dest_struct) { + pb_release(fields, dest_struct); +} + +google_firestore_v1_Value Serializer::EncodeFieldValue( + const FieldValue& field_value) { + // TODO(rsgowman): some refactoring is in order... but will wait until after a + // non-varint, non-fixed-size (i.e. string) type is present before doing so. + google_firestore_v1_Value result{}; + switch (field_value.type()) { + case FieldValue::Type::Null: + result.which_value_type = google_firestore_v1_Value_null_value_tag; + result.null_value = google_protobuf_NullValue_NULL_VALUE; + return result; + + case FieldValue::Type::Boolean: + result.which_value_type = google_firestore_v1_Value_boolean_value_tag; + result.boolean_value = field_value.boolean_value(); + return result; + + case FieldValue::Type::Integer: + result.which_value_type = google_firestore_v1_Value_integer_value_tag; + result.integer_value = field_value.integer_value(); + return result; + + case FieldValue::Type::Double: + result.which_value_type = google_firestore_v1_Value_double_value_tag; + result.double_value = field_value.double_value(); + return result; + + case FieldValue::Type::Timestamp: + result.which_value_type = google_firestore_v1_Value_timestamp_value_tag; + result.timestamp_value = EncodeTimestamp(field_value.timestamp_value()); + return result; + + case FieldValue::Type::ServerTimestamp: + // TODO(rsgowman): Implement + abort(); + + case FieldValue::Type::String: + result.which_value_type = google_firestore_v1_Value_string_value_tag; + result.string_value = EncodeString(field_value.string_value()); + return result; + + case FieldValue::Type::Blob: + result.which_value_type = google_firestore_v1_Value_bytes_value_tag; + result.bytes_value = EncodeBytes(field_value.blob_value()); + return result; + + case FieldValue::Type::Reference: + // TODO(rsgowman): Implement + abort(); + + case FieldValue::Type::GeoPoint: + result.which_value_type = google_firestore_v1_Value_geo_point_value_tag; + result.geo_point_value = EncodeGeoPoint(field_value.geo_point_value()); + return result; + + case FieldValue::Type::Array: + result.which_value_type = google_firestore_v1_Value_array_value_tag; + result.array_value = EncodeArray(field_value.array_value()); + return result; + + case FieldValue::Type::Object: + result.which_value_type = google_firestore_v1_Value_map_value_tag; + result.map_value = EncodeMapValue(ObjectValue(field_value)); + return result; + } + UNREACHABLE(); +} + +FieldValue Serializer::DecodeFieldValue(Reader* reader, + const google_firestore_v1_Value& msg) { + switch (msg.which_value_type) { + case google_firestore_v1_Value_null_value_tag: + if (msg.null_value != google_protobuf_NullValue_NULL_VALUE) { + reader->Fail("Input proto bytes cannot be parsed (invalid null value)"); + } + return FieldValue::Null(); + + case google_firestore_v1_Value_boolean_value_tag: { + // Due to the nanopb implementation, msg.boolean_value could be an integer + // other than 0 or 1, (such as 2). This leads to undefined behaviour when + // it's read as a boolean. eg. on at least gcc, the value is treated as + // both true *and* false. So we'll instead memcpy to an integer (via + // absl::bit_cast) and compare with 0. + int bool_as_int = absl::bit_cast(msg.boolean_value); + return FieldValue::FromBoolean(bool_as_int != 0); + } + + case google_firestore_v1_Value_integer_value_tag: + return FieldValue::FromInteger(msg.integer_value); + + case google_firestore_v1_Value_double_value_tag: + return FieldValue::FromDouble(msg.double_value); + + case google_firestore_v1_Value_timestamp_value_tag: { + return FieldValue::FromTimestamp( + DecodeTimestamp(reader, msg.timestamp_value)); + } + + case google_firestore_v1_Value_string_value_tag: + return FieldValue::FromString(DecodeString(msg.string_value)); + + case google_firestore_v1_Value_bytes_value_tag: { + std::vector bytes = DecodeBytes(msg.bytes_value); + return FieldValue::FromBlob(bytes.data(), bytes.size()); + } + + case google_firestore_v1_Value_reference_value_tag: + // TODO(b/74243929): Implement remaining types. + HARD_FAIL("Unhandled message field number (tag): %i.", + msg.which_value_type); + + case google_firestore_v1_Value_geo_point_value_tag: + return FieldValue::FromGeoPoint( + DecodeGeoPoint(reader, msg.geo_point_value)); + + case google_firestore_v1_Value_array_value_tag: + return FieldValue::FromArray(DecodeArray(reader, msg.array_value)); + + case google_firestore_v1_Value_map_value_tag: { + return FieldValue::FromMap(DecodeMapValue(reader, msg.map_value)); + } + + default: + reader->Fail(StringFormat("Invalid type while decoding FieldValue: %s", + msg.which_value_type)); + return FieldValue::Null(); + } + + UNREACHABLE(); +} + +std::string Serializer::EncodeKey(const DocumentKey& key) const { + return EncodeResourceName(database_id_, key.path()); +} + +DocumentKey Serializer::DecodeKey(Reader* reader, + absl::string_view name) const { + ResourcePath resource = DecodeResourceName(reader, name); + if (resource.size() < 5) { + reader->Fail( + StringFormat("Attempted to decode invalid key: '%s'. Should have at " + "least 5 segments.", + name)); + } else if (resource[1] != database_id_.project_id()) { + reader->Fail( + StringFormat("Tried to deserialize key from different project. " + "Expected: '%s'. Found: '%s'. (Full key: '%s')", + database_id_.project_id(), resource[1], name)); + } else if (resource[3] != database_id_.database_id()) { + reader->Fail( + StringFormat("Tried to deserialize key from different database. " + "Expected: '%s'. Found: '%s'. (Full key: '%s')", + database_id_.database_id(), resource[3], name)); + } + + ResourcePath local_path = ExtractLocalPathFromResourceName(reader, resource); + + if (!DocumentKey::IsDocumentKey(local_path)) { + reader->Fail(StringFormat("Invalid document key path: %s", + local_path.CanonicalString())); + } + + // Avoid assertion failures in DocumentKey if local_path is invalid. + if (!reader->status().ok()) return DocumentKey{}; + return DocumentKey{std::move(local_path)}; +} + +google_firestore_v1_Document Serializer::EncodeDocument( + const DocumentKey& key, const ObjectValue& object_value) const { + google_firestore_v1_Document result{}; + + result.name = EncodeString(EncodeKey(key)); + + // Encode Document.fields (unless it's empty) + pb_size_t count = CheckedSize(object_value.GetInternalValue().size()); + result.fields_count = count; + result.fields = MakeArray(count); + int i = 0; + for (const auto& kv : object_value.GetInternalValue()) { + result.fields[i].key = EncodeString(kv.first); + result.fields[i].value = EncodeFieldValue(kv.second); + i++; + } + + // Skip Document.create_time and Document.update_time, since they're + // output-only fields. + + return result; +} + +std::unique_ptr Serializer::DecodeMaybeDocument( + Reader* reader, + const google_firestore_v1_BatchGetDocumentsResponse& response) const { + switch (response.which_result) { + case google_firestore_v1_BatchGetDocumentsResponse_found_tag: + return DecodeFoundDocument(reader, response); + case google_firestore_v1_BatchGetDocumentsResponse_missing_tag: + return DecodeMissingDocument(reader, response); + default: + reader->Fail( + StringFormat("Unknown result case: %s", response.which_result)); + return nullptr; + } + + UNREACHABLE(); +} + +std::unique_ptr Serializer::DecodeFoundDocument( + Reader* reader, + const google_firestore_v1_BatchGetDocumentsResponse& response) const { + HARD_ASSERT(response.which_result == + google_firestore_v1_BatchGetDocumentsResponse_found_tag, + "Tried to deserialize a found document from a missing document."); + + DocumentKey key = DecodeKey(reader, DecodeString(response.found.name)); + FieldValue::Map value = + DecodeFields(reader, response.found.fields_count, response.found.fields); + SnapshotVersion version = + DecodeSnapshotVersion(reader, response.found.update_time); + + if (version == SnapshotVersion::None()) { + reader->Fail("Got a document response with no snapshot version"); + } + + return absl::make_unique(ObjectValue::FromMap(std::move(value)), + std::move(key), std::move(version), + DocumentState::kSynced); +} + +std::unique_ptr Serializer::DecodeMissingDocument( + Reader* reader, + const google_firestore_v1_BatchGetDocumentsResponse& response) const { + HARD_ASSERT(response.which_result == + google_firestore_v1_BatchGetDocumentsResponse_missing_tag, + "Tried to deserialize a missing document from a found document."); + + DocumentKey key = DecodeKey(reader, DecodeString(response.missing)); + SnapshotVersion version = DecodeSnapshotVersion(reader, response.read_time); + + if (version == SnapshotVersion::None()) { + reader->Fail("Got a no document response with no snapshot version"); + return nullptr; + } + + return absl::make_unique(std::move(key), std::move(version), + /*hasCommittedMutations=*/false); +} + +std::unique_ptr Serializer::DecodeDocument( + Reader* reader, const google_firestore_v1_Document& proto) const { + FieldValue::Map fields_internal = + DecodeFields(reader, proto.fields_count, proto.fields); + SnapshotVersion version = DecodeSnapshotVersion(reader, proto.update_time); + + return absl::make_unique( + ObjectValue::FromMap(std::move(fields_internal)), + DecodeKey(reader, DecodeString(proto.name)), std::move(version), + DocumentState::kSynced); +} + +google_firestore_v1_Write Serializer::EncodeMutation( + const model::Mutation& mutation) const { + google_firestore_v1_Write result{}; + + if (!mutation.precondition().IsNone()) { + result.current_document = EncodePrecondition(mutation.precondition()); + } + + switch (mutation.type()) { + case Mutation::Type::kSet: { + result.which_operation = google_firestore_v1_Write_update_tag; + result.update = EncodeDocument( + mutation.key(), static_cast(mutation).value()); + return result; + } + + case Mutation::Type::kPatch: { + result.which_operation = google_firestore_v1_Write_update_tag; + auto patch_mutation = static_cast(mutation); + result.update = EncodeDocument(mutation.key(), patch_mutation.value()); + result.update_mask = EncodeDocumentMask(patch_mutation.mask()); + return result; + } + + // TODO(rsgowman): Implement transform mutations. Probably like this: + /* + case Mutation::Type::kTransform: + result.which_operation = google_firestore_v1_Write_transform_tag; + auto transform = static_cast(mutation); + result.transform.document = EncodeKey(transform.key()); + + size_t count = transform.field_transforms.size(); + result.transform.field_transforms_count = count; + result.transform.field_transforms = + MakeArray(count); + int i = 0; + for (const FieldTransform& field_transform : + transform.field_transforms()) { result.transform.field_transforms[i] = + EncodeFieldTransform(field_transform); i++; + } + return result; + */ + + case Mutation::Type::kDelete: { + result.which_operation = google_firestore_v1_Write_delete_tag; + result.delete_ = EncodeString(EncodeKey(mutation.key())); + return result; + } + } + + UNREACHABLE(); +} + +std::unique_ptr Serializer::DecodeMutation( + nanopb::Reader* reader, const google_firestore_v1_Write& mutation) const { + Precondition precondition = + DecodePrecondition(reader, mutation.current_document); + + switch (mutation.which_operation) { + case google_firestore_v1_Write_update_tag: { + DocumentKey key = DecodeKey(reader, DecodeString(mutation.update.name)); + ObjectValue value = ObjectValue::FromMap(DecodeFields( + reader, mutation.update.fields_count, mutation.update.fields)); + FieldMask mask = DecodeDocumentMask(mutation.update_mask); + if (mask.size() > 0) { + return absl::make_unique( + std::move(key), std::move(value), std::move(mask), + std::move(precondition)); + } else { + return absl::make_unique(std::move(key), std::move(value), + std::move(precondition)); + } + UNREACHABLE(); + } + + case google_firestore_v1_Write_delete_tag: + return absl::make_unique( + DecodeKey(reader, DecodeString(mutation.delete_)), + std::move(precondition)); + + // TODO(rsgowman): Implement transform. Probably like this: + /* + case google_firestore_v1_Write_transform_tag: + std::vector field_transforms; + for (size_t i = 0; i( + DecodeKey(reader, mutation.transform.document), + field_transforms); + */ + + default: + reader->Fail(StringFormat("Unknown mutation operation: %s", + mutation.which_operation)); + return nullptr; + } + + UNREACHABLE(); +} + +/* static */ +google_firestore_v1_Precondition Serializer::EncodePrecondition( + const Precondition& precondition) { + google_firestore_v1_Precondition result{}; + + switch (precondition.type()) { + case Precondition::Type::None: + HARD_FAIL("Can't serialize an empty precondition"); + + case Precondition::Type::UpdateTime: + result.which_condition_type = + google_firestore_v1_Precondition_update_time_tag; + result.update_time = EncodeVersion(precondition.update_time()); + return result; + + case Precondition::Type::Exists: + result.which_condition_type = google_firestore_v1_Precondition_exists_tag; + result.exists = precondition.exists(); + return result; + } + + UNREACHABLE(); +} + +/* static */ +Precondition Serializer::DecodePrecondition( + nanopb::Reader* reader, + const google_firestore_v1_Precondition& precondition) { + switch (precondition.which_condition_type) { + // 0 => type unset. nanopb doesn't provide a constant for this, so we use a + // raw integer. + case 0: + return Precondition::None(); + case google_firestore_v1_Precondition_exists_tag: { + // TODO(rsgowman): Refactor with other instance of bit_cast. + + // Due to the nanopb implementation, precondition.exists could be an + // integer other than 0 or 1, (such as 2). This leads to undefined + // behaviour when it's read as a boolean. eg. on at least gcc, the value + // is treated as both true *and* false. So we'll instead memcpy to an + // integer (via absl::bit_cast) and compare with 0. + int bool_as_int = absl::bit_cast(precondition.exists); + return Precondition::Exists(bool_as_int != 0); + } + case google_firestore_v1_Precondition_update_time_tag: + return Precondition::UpdateTime( + DecodeSnapshotVersion(reader, precondition.update_time)); + } + + reader->Fail(StringFormat("Unknown Precondition type: %s", + precondition.which_condition_type)); + return Precondition::None(); +} + +/* static */ +google_firestore_v1_DocumentMask Serializer::EncodeDocumentMask( + const FieldMask& mask) { + google_firestore_v1_DocumentMask result{}; + + pb_size_t count = CheckedSize(mask.size()); + result.field_paths_count = count; + result.field_paths = MakeArray(count); + + int i = 0; + for (const FieldPath& path : mask) { + result.field_paths[i] = EncodeString(path.CanonicalString()); + i++; + } + + return result; +} + +/* static */ +model::FieldMask Serializer::DecodeDocumentMask( + const google_firestore_v1_DocumentMask& mask) { + std::set fields; + for (size_t i = 0; i < mask.field_paths_count; i++) { + auto path = DecodeString(mask.field_paths[i]); + fields.insert(FieldPath::FromServerFormat(path)); + } + return model::FieldMask(std::move(fields)); +} + +google_firestore_v1_Target_QueryTarget Serializer::EncodeQueryTarget( + const core::Query& query) const { + google_firestore_v1_Target_QueryTarget result{}; + + // Dissect the path into parent, collection_id and optional key filter. + std::string collection_id; + // TODO(rsgowman): Port Collection Group Queries logic. + if (query.path().empty()) { + result.parent = EncodeString(EncodeQueryPath(ResourcePath::Empty())); + } else { + ResourcePath path = query.path(); + HARD_ASSERT(path.size() % 2 != 0, + "Document queries with filters are not supported."); + result.parent = EncodeString(EncodeQueryPath(path.PopLast())); + collection_id = path.last_segment(); + } + + result.which_query_type = + google_firestore_v1_Target_QueryTarget_structured_query_tag; + + if (!collection_id.empty()) { + pb_size_t count = 1; + result.structured_query.from_count = count; + result.structured_query.from = + MakeArray( + count); + result.structured_query.from[0].collection_id = EncodeString(collection_id); + } else { + result.structured_query.from_count = 0; + } + + // Encode the filters. + if (!query.filters().empty()) { + // TODO(rsgowman): Implement + abort(); + } + + // TODO(rsgowman): Encode the orders. + // TODO(rsgowman): Encode the limit. + // TODO(rsgowman): Encode the startat. + // TODO(rsgowman): Encode the endat. + + return result; +} + +ResourcePath DecodeQueryPath(Reader* reader, absl::string_view name) { + ResourcePath resource = DecodeResourceName(reader, name); + if (resource.size() == 4) { + // In v1beta1 queries for collections at the root did not have a trailing + // "/documents". In v1 all resource paths contain "/documents". Preserve the + // ability to read the v1beta1 form for compatibility with queries persisted + // in the local query cache. + return ResourcePath::Empty(); + } else { + return ExtractLocalPathFromResourceName(reader, resource); + } +} + +Query Serializer::DecodeQueryTarget( + nanopb::Reader* reader, + const google_firestore_v1_Target_QueryTarget& proto) { + // The QueryTarget oneof only has a single valid value. + if (proto.which_query_type != + google_firestore_v1_Target_QueryTarget_structured_query_tag) { + reader->Fail( + StringFormat("Unknown query_type: %s", proto.which_query_type)); + return Query::Invalid(); + } + + ResourcePath path = DecodeQueryPath(reader, DecodeString(proto.parent)); + StructuredQuery query = DecodeStructuredQuery(proto.structured_query); + + size_t from_count = query.from.size(); + if (from_count > 0) { + if (from_count != 1) { + reader->Fail( + "StructuredQuery.from with more than one collection is not " + "supported."); + } + + path = path.Append(query.from[0].collection_id); + } + + // TODO(rsgowman): Dencode the filters. + // TODO(rsgowman): Dencode the orders. + // TODO(rsgowman): Dencode the limit. + // TODO(rsgowman): Dencode the startat. + // TODO(rsgowman): Dencode the endat. + + return Query(path, {}); +} + +std::string Serializer::EncodeQueryPath(const ResourcePath& path) const { + return EncodeResourceName(database_id_, path); +} + +google_protobuf_Timestamp Serializer::EncodeVersion( + const model::SnapshotVersion& version) { + return EncodeTimestamp(version.timestamp()); +} + +google_protobuf_Timestamp Serializer::EncodeTimestamp( + const Timestamp& timestamp_value) { + google_protobuf_Timestamp result{}; + result.seconds = timestamp_value.seconds(); + result.nanos = timestamp_value.nanoseconds(); + return result; +} + +SnapshotVersion Serializer::DecodeSnapshotVersion( + nanopb::Reader* reader, const google_protobuf_Timestamp& proto) { + return SnapshotVersion{DecodeTimestamp(reader, proto)}; +} + +Timestamp Serializer::DecodeTimestamp( + nanopb::Reader* reader, const google_protobuf_Timestamp& timestamp_proto) { + // The Timestamp ctor will assert if we provide values outside the valid + // range. However, since we're decoding, a single corrupt byte could cause + // this to occur, so we'll verify the ranges before passing them in since we'd + // rather not abort in these situations. + if (timestamp_proto.seconds < TimestampInternal::Min().seconds()) { + reader->Fail( + "Invalid message: timestamp beyond the earliest supported date"); + } else if (TimestampInternal::Max().seconds() < timestamp_proto.seconds) { + reader->Fail("Invalid message: timestamp beyond the latest supported date"); + } else if (timestamp_proto.nanos < 0 || timestamp_proto.nanos > 999999999) { + reader->Fail( + "Invalid message: timestamp nanos must be between 0 and 999999999"); + } + + if (!reader->status().ok()) return Timestamp(); + return Timestamp{timestamp_proto.seconds, timestamp_proto.nanos}; +} + +/* static */ +google_type_LatLng Serializer::EncodeGeoPoint(const GeoPoint& geo_point_value) { + google_type_LatLng result{}; + result.latitude = geo_point_value.latitude(); + result.longitude = geo_point_value.longitude(); + return result; +} + +/* static */ +GeoPoint Serializer::DecodeGeoPoint(nanopb::Reader* reader, + const google_type_LatLng& latlng_proto) { + // The GeoPoint ctor will assert if we provide values outside the valid range. + // However, since we're decoding, a single corrupt byte could cause this to + // occur, so we'll verify the ranges before passing them in since we'd rather + // not abort in these situations. + double latitude = latlng_proto.latitude; + double longitude = latlng_proto.longitude; + if (std::isnan(latitude) || latitude < -90 || 90 < latitude) { + reader->Fail("Invalid message: Latitude must be in the range of [-90, 90]"); + } else if (std::isnan(longitude) || longitude < -180 || 180 < longitude) { + reader->Fail( + "Invalid message: Latitude must be in the range of [-180, 180]"); + } + + if (!reader->status().ok()) return GeoPoint(); + return GeoPoint(latitude, longitude); +} + +/* static */ +google_firestore_v1_ArrayValue Serializer::EncodeArray( + const std::vector& array_value) { + google_firestore_v1_ArrayValue result{}; + + pb_size_t count = CheckedSize(array_value.size()); + result.values_count = count; + result.values = MakeArray(count); + + size_t i = 0; + for (const FieldValue& fv : array_value) { + result.values[i++] = EncodeFieldValue(fv); + } + + return result; +} + +/* static */ +std::vector Serializer::DecodeArray( + nanopb::Reader* reader, const google_firestore_v1_ArrayValue& array_proto) { + std::vector result; + result.reserve(array_proto.values_count); + + for (size_t i = 0; i < array_proto.values_count; i++) { + result.push_back(DecodeFieldValue(reader, array_proto.values[i])); + } + + return result; +} + +} // namespace remote +} // namespace firestore +} // namespace firebase diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/serializer.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/serializer.h new file mode 100644 index 0000000..ae011b3 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/serializer.h @@ -0,0 +1,242 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_REMOTE_SERIALIZER_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_REMOTE_SERIALIZER_H_ + +#include +#include +#include +#include +#include + +#include "Firestore/Protos/nanopb/google/firestore/v1/document.nanopb.h" +#include "Firestore/Protos/nanopb/google/firestore/v1/firestore.nanopb.h" +#include "Firestore/Protos/nanopb/google/type/latlng.nanopb.h" +#include "Firestore/core/src/firebase/firestore/core/query.h" +#include "Firestore/core/src/firebase/firestore/model/database_id.h" +#include "Firestore/core/src/firebase/firestore/model/document.h" +#include "Firestore/core/src/firebase/firestore/model/document_key.h" +#include "Firestore/core/src/firebase/firestore/model/field_mask.h" +#include "Firestore/core/src/firebase/firestore/model/field_value.h" +#include "Firestore/core/src/firebase/firestore/model/maybe_document.h" +#include "Firestore/core/src/firebase/firestore/model/mutation.h" +#include "Firestore/core/src/firebase/firestore/model/no_document.h" +#include "Firestore/core/src/firebase/firestore/model/snapshot_version.h" +#include "Firestore/core/src/firebase/firestore/nanopb/reader.h" +#include "Firestore/core/src/firebase/firestore/nanopb/writer.h" +#include "Firestore/core/src/firebase/firestore/util/hard_assert.h" +#include "Firestore/core/src/firebase/firestore/util/status.h" +#include "absl/base/attributes.h" +#include "absl/strings/string_view.h" + +namespace firebase { +namespace firestore { + +namespace local { +class LocalSerializer; +} + +namespace remote { + +template +T* MakeArray(pb_size_t count) { + return reinterpret_cast(calloc(count, sizeof(T))); +} + +/** + * @brief Converts internal model objects to their equivalent protocol buffer + * form, and protocol buffer objects to their equivalent bytes. + * + * Methods starting with "Encode" convert from a model object to a nanopb + * protocol buffer, and methods starting with "Decode" convert from a nanopb + * protocol buffer to a model object + * + * For encoded messages, FreeNanopbMessage() must be called on the returned + * nanopb proto buffer or a memory leak will occur. + * + * All errors that occur during serialization are fatal. + * + * All deserialization methods (that can fail) take a nanopb::Reader parameter + * whose status will be set to failed upon an error. Callers must check this + * before using the returned value via `reader->status()`. A deserialization + * method might fail if a protocol buffer is missing a critical field or has a + * value we can't interpret. On error, the return value from a deserialization + * method is unspecified. + */ +class Serializer { + public: + /** + * @param database_id Must remain valid for the lifetime of this Serializer + * object. + */ + explicit Serializer( + const firebase::firestore::model::DatabaseId& database_id); + + /** + * Encodes the string to nanopb bytes. + * + * This method allocates memory; the caller is responsible for freeing it. + * Typically, the returned value will be added to a pointer field within a + * nanopb proto struct. Calling pb_release() on the resulting struct will + * cause all proto fields to be freed. + */ + static pb_bytes_array_t* EncodeString(const std::string& str); + + /** + * Decodes the nanopb bytes to a std::string. If the input pointer is null, + * then this method will return an empty string. + */ + static std::string DecodeString(const pb_bytes_array_t* str); + + /** + * Encodes the std::vector to nanopb bytes. If the input vector is empty, then + * the resulting return bytes will have length 0 (but will otherwise be valid, + * i.e. not null.) + * + * This method allocates memory; the caller is responsible for freeing it. + * Typically, the returned value will be added to a pointer field within a + * nanopb proto struct. Calling pb_release() on the resulting struct will + * cause all proto fields to be freed. + */ + static pb_bytes_array_t* EncodeBytes(const std::vector& bytes); + + /** + * Decodes the nanopb bytes to a std::vector. If the input pointer is null, + * then this method will return an empty vector. + */ + static std::vector DecodeBytes(const pb_bytes_array_t* bytes); + + /** + * Release memory allocated by the Encode* methods that return protos. + * + * This essentially wraps calls to nanopb's pb_release() method. + */ + static void FreeNanopbMessage(const pb_field_t fields[], void* dest_struct); + + /** + * @brief Converts the FieldValue model passed into bytes. + */ + static google_firestore_v1_Value EncodeFieldValue( + const model::FieldValue& field_value); + + /** + * @brief Converts from nanopb proto to the model FieldValue format. + */ + // TODO(rsgowman): Once the proto is read, the only thing the reader object is + // used for is error handling. This seems questionable. We probably need to + // rework error handling. Again. But we'll defer that for now and continue + // just passing the reader object. + static model::FieldValue DecodeFieldValue( + nanopb::Reader* reader, const google_firestore_v1_Value& proto); + + /** + * Encodes the given document key as a fully qualified name. This includes the + * databaseId associated with this Serializer and the key path. + */ + std::string EncodeKey( + const firebase::firestore::model::DocumentKey& key) const; + + /** + * Decodes the given document key from a fully qualified name. + */ + firebase::firestore::model::DocumentKey DecodeKey( + nanopb::Reader* reader, absl::string_view name) const; + + /** + * @brief Converts the Document (i.e. key/value) into bytes. + */ + google_firestore_v1_Document EncodeDocument( + const model::DocumentKey& key, const model::ObjectValue& value) const; + + /** + * @brief Converts from nanopb proto to the model Document format. + */ + std::unique_ptr DecodeMaybeDocument( + nanopb::Reader* reader, + const google_firestore_v1_BatchGetDocumentsResponse& response) const; + + google_firestore_v1_Write EncodeMutation( + const model::Mutation& mutation) const; + std::unique_ptr DecodeMutation( + nanopb::Reader* reader, const google_firestore_v1_Write& mutation) const; + + static google_firestore_v1_Precondition EncodePrecondition( + const model::Precondition& precondition); + static model::Precondition DecodePrecondition( + nanopb::Reader* reader, + const google_firestore_v1_Precondition& precondition); + + static google_firestore_v1_DocumentMask EncodeDocumentMask( + const model::FieldMask& mask); + static model::FieldMask DecodeDocumentMask( + const google_firestore_v1_DocumentMask& mask); + + /** + * @brief Converts the Query into bytes, representing a + * firestore::v1::Target::QueryTarget. + */ + google_firestore_v1_Target_QueryTarget EncodeQueryTarget( + const core::Query& query) const; + + std::unique_ptr DecodeDocument( + nanopb::Reader* reader, const google_firestore_v1_Document& proto) const; + + static google_protobuf_Timestamp EncodeVersion( + const model::SnapshotVersion& version); + + static google_protobuf_Timestamp EncodeTimestamp( + const Timestamp& timestamp_value); + + static model::SnapshotVersion DecodeSnapshotVersion( + nanopb::Reader* reader, const google_protobuf_Timestamp& proto); + + static Timestamp DecodeTimestamp( + nanopb::Reader* reader, const google_protobuf_Timestamp& timestamp_proto); + + static core::Query DecodeQueryTarget( + nanopb::Reader* reader, + const google_firestore_v1_Target_QueryTarget& proto); + + static google_type_LatLng EncodeGeoPoint(const GeoPoint& geo_point_value); + static GeoPoint DecodeGeoPoint(nanopb::Reader* reader, + const google_type_LatLng& latlng_proto); + + static google_firestore_v1_ArrayValue EncodeArray( + const std::vector& array_value); + static std::vector DecodeArray( + nanopb::Reader* reader, + const google_firestore_v1_ArrayValue& array_proto); + + private: + std::unique_ptr DecodeFoundDocument( + nanopb::Reader* reader, + const google_firestore_v1_BatchGetDocumentsResponse& response) const; + std::unique_ptr DecodeMissingDocument( + nanopb::Reader* reader, + const google_firestore_v1_BatchGetDocumentsResponse& response) const; + + std::string EncodeQueryPath(const model::ResourcePath& path) const; + + const model::DatabaseId& database_id_; + const std::string database_name_; +}; + +} // namespace remote +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_REMOTE_SERIALIZER_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/stream.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/stream.h new file mode 100644 index 0000000..669c381 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/stream.h @@ -0,0 +1,246 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_REMOTE_STREAM_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_REMOTE_STREAM_H_ + +#include +#include + +#include "Firestore/core/src/firebase/firestore/auth/credentials_provider.h" +#include "Firestore/core/src/firebase/firestore/auth/token.h" +#include "Firestore/core/src/firebase/firestore/remote/exponential_backoff.h" +#include "Firestore/core/src/firebase/firestore/remote/grpc_completion.h" +#include "Firestore/core/src/firebase/firestore/remote/grpc_connection.h" +#include "Firestore/core/src/firebase/firestore/remote/grpc_stream.h" +#include "Firestore/core/src/firebase/firestore/remote/remote_objc_bridge.h" +#include "Firestore/core/src/firebase/firestore/util/async_queue.h" +#include "Firestore/core/src/firebase/firestore/util/status.h" +#include "Firestore/core/src/firebase/firestore/util/statusor.h" +#include "absl/strings/string_view.h" +#include "grpcpp/support/byte_buffer.h" + +namespace firebase { +namespace firestore { +namespace remote { + +/** + * A `Stream` is an abstract base class that represents a bidirectional + * streaming connection to the Firestore backend. It's built on top of gRPC C++ + * library and adds several critical features for our clients: + * + * - Exponential backoff on failure (independent of the gRPC mechanism) + * - Authentication via CredentialsProvider + * - Dispatching all callbacks into the shared Firestore async queue + * - Closing idle streams after 60 seconds of inactivity + * + * Subclasses of `Stream`: + * + * - Implement serialization and deserialization of protocol buffers + * - Notify their delegate about stream open/read/error events + * - Create and finish the underlying gRPC streams. + * + * ## Starting and Stopping + * + * Streams are stateful and need to be `Start`ed before messages can + * be sent and received. A `Stream` can be started and stopped repeatedly. + * + * All public virtual methods exist only for the sake of tests; the methods that + * are expected to be implemented by "normal" derived classes are pure virtual + * and private. + */ +class Stream : public GrpcStreamObserver, + public std::enable_shared_from_this { + public: + /** + * `Stream` can be in one of 5 states (each described in detail below) + * shown in the following state transition diagram: + * + * Start() called auth & connection succeeded + * INITIAL ----------------> STARTING -----------------------------> OPEN + * ^ | | + * | | error occurred | + * | \-----------------------------v-----/ + * | | + * backoff | | + * elapsed | Start() called | + * \--- BACKOFF <---------------- ERROR + * + * [any state] --------------------------> INITIAL + * Stop() called or + * idle timer expired + */ + enum class State { + /** + * The stream is not yet running and there's no error condition. + * Calling `Start` will start the stream immediately without backoff. + * While in this state, `IsStarted` will return false. + */ + Initial, + + /** + * The stream is starting, either waiting for an auth token or for the + * stream to successfully open. While in this state, `IsStarted` will + * return true but `IsOpen` will return false. + */ + Starting, + + /** + * The stream is up and running. Requests and responses can flow + * freely. Both `IsStarted` and `IsOpen` will return true. + */ + Open, + + /** + * The stream encountered an error. The next start attempt will back off. + * While in this state, `IsStarted` will return false. + */ + Error, + + /** + * An in-between state after an error where the stream is waiting before + * re-starting. After waiting is complete, the stream will try to open. + * While in this state, `IsStarted` will return true but `IsOpen` will + * return false. + */ + Backoff + }; + + Stream(util::AsyncQueue* async_queue, + auth::CredentialsProvider* credentials_provider, + GrpcConnection* grpc_connection, + util::TimerId backoff_timer_id, + util::TimerId idle_timer_id); + + /** + * Starts the stream. Only allowed if `IsStarted` returns false. The stream is + * not immediately ready for use: `OnStreamStart` will be invoked when the + * stream is ready for outbound requests, at which point `IsOpen` will return + * true. + * + * When start returns, `IsStarted` will return true. + */ + virtual void Start(); + + /** + * Stops the stream. This call is idempotent and allowed regardless of the + * current `IsStarted` state. + * + * When stop returns, `IsStarted` and `IsOpen` will both return false. + */ + virtual void Stop(); + + /** + * Returns true if `Start` has been called and no error has occurred. True + * indicates the stream is open or in the process of opening (which + * encompasses respecting backoff, getting auth tokens, and starting the + * actual stream). Use `IsOpen` to determine if the stream is open and ready + * for outbound requests. + */ + virtual bool IsStarted() const; + + /** + * Returns true if the underlying stream is open (`OnStreamStart` has been + * called) and the stream is ready for outbound requests. + */ + virtual bool IsOpen() const; + + /** + * After an error, the stream will usually back off on the next attempt to + * start it. If the error warrants an immediate restart of the stream, the + * caller can use this to indicate that the stream should not back off. + * + * Each error will call `OnStreamClose`. That function can decide to + * cancel backoff if required. + */ + void InhibitBackoff(); + + /** + * Marks this stream as idle. If no further actions are performed on the + * stream for one minute, the stream will automatically close itself and + * notify the stream's `OnClose` handler with Status::OK. The stream will then + * be in a non-started state, requiring the caller to start the stream again + * before further use. + * + * Only streams that are in state 'Open' can be marked idle, as all other + * states imply pending network operations. + */ + void MarkIdle(); + + /** + * Marks the stream as active again, preventing auto-closing of the stream. + * Can be called from any state -- if the stream is not in state `Open`, this + * is a no-op. + */ + void CancelIdleCheck(); + + // `GrpcStreamObserver` interface -- do not use. + void OnStreamStart() override; + void OnStreamRead(const grpc::ByteBuffer& message) override; + void OnStreamFinish(const util::Status& status) override; + + protected: + // `Stream` expects all its methods to be called on the worker queue. + void EnsureOnQueue() const; + void Write(grpc::ByteBuffer&& message); + std::string GetDebugDescription() const; + + ExponentialBackoff backoff_; + + private: + // The interface for the derived classes. + + virtual std::unique_ptr CreateGrpcStream( + GrpcConnection* grpc_connection, const auth::Token& token) = 0; + virtual void TearDown(GrpcStream* stream) = 0; + virtual void NotifyStreamOpen() = 0; + virtual util::Status NotifyStreamResponse( + const grpc::ByteBuffer& message) = 0; + virtual void NotifyStreamClose(const util::Status& status) = 0; + // PORTING NOTE: C++ cannot rely on RTTI, unlike other platforms. + virtual std::string GetDebugName() const = 0; + + void Close(const util::Status& status); + void HandleErrorStatus(const util::Status& status); + + void RequestCredentials(); + void ResumeStartWithCredentials( + const util::StatusOr& maybe_token); + + void BackoffAndTryRestarting(); + void StopDueToIdleness(); + + State state_ = State::Initial; + + std::unique_ptr grpc_stream_; + + auth::CredentialsProvider* credentials_provider_ = nullptr; + util::AsyncQueue* worker_queue_ = nullptr; + GrpcConnection* grpc_connection_ = nullptr; + + util::TimerId idle_timer_id_{}; + util::DelayedOperation idleness_timer_; + + // Used to prevent auth if the stream happens to be restarted before token is + // received. + int close_count_ = 0; +}; + +} // namespace remote +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_REMOTE_STREAM_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/stream.mm b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/stream.mm new file mode 100644 index 0000000..f03375d --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/stream.mm @@ -0,0 +1,323 @@ +/* + * Copyright 2018 Google + * + * 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 "Firestore/core/src/firebase/firestore/remote/stream.h" + +#include // NOLINT(build/c++11) +#include + +#include "Firestore/core/include/firebase/firestore/firestore_errors.h" +#include "Firestore/core/src/firebase/firestore/remote/datastore.h" +#include "Firestore/core/src/firebase/firestore/util/error_apple.h" +#include "Firestore/core/src/firebase/firestore/util/hard_assert.h" +#include "Firestore/core/src/firebase/firestore/util/log.h" +#include "Firestore/core/src/firebase/firestore/util/string_format.h" + +namespace firebase { +namespace firestore { +namespace remote { + +using auth::CredentialsProvider; +using auth::Token; +using util::AsyncQueue; +using util::TimerId; +using util::Status; +using util::StatusOr; +using util::StringFormat; + +namespace { + +/** + * Initial backoff time after an error. + * Set to 1s according to https://cloud.google.com/apis/design/errors. + */ +const double kBackoffFactor = 1.5; +const AsyncQueue::Milliseconds kBackoffInitialDelay{std::chrono::seconds(1)}; +const AsyncQueue::Milliseconds kBackoffMaxDelay{std::chrono::seconds(60)}; +/** The time a stream stays open after it is marked idle. */ +const AsyncQueue::Milliseconds kIdleTimeout{std::chrono::seconds(60)}; + +} // namespace + +Stream::Stream(AsyncQueue* worker_queue, + CredentialsProvider* credentials_provider, + GrpcConnection* grpc_connection, + TimerId backoff_timer_id, + TimerId idle_timer_id) + : backoff_{worker_queue, backoff_timer_id, kBackoffFactor, + kBackoffInitialDelay, kBackoffMaxDelay}, + credentials_provider_{credentials_provider}, + worker_queue_{worker_queue}, + grpc_connection_{grpc_connection}, + idle_timer_id_{idle_timer_id} { +} + +// Check state + +bool Stream::IsOpen() const { + EnsureOnQueue(); + return state_ == State::Open; +} + +bool Stream::IsStarted() const { + EnsureOnQueue(); + return state_ == State::Starting || state_ == State::Backoff || IsOpen(); +} + +// Starting + +void Stream::Start() { + EnsureOnQueue(); + + if (state_ == State::Error) { + BackoffAndTryRestarting(); + return; + } + + LOG_DEBUG("%s start", GetDebugDescription()); + + HARD_ASSERT(state_ == State::Initial, "Already started"); + state_ = State::Starting; + + RequestCredentials(); +} + +void Stream::RequestCredentials() { + EnsureOnQueue(); + + // Auth may outlive the stream, so make sure it doesn't try to access a + // deleted object. + std::weak_ptr weak_this{shared_from_this()}; + int initial_close_count = close_count_; + credentials_provider_->GetToken([weak_this, initial_close_count]( + const StatusOr& maybe_token) { + auto strong_this = weak_this.lock(); + if (!strong_this) { + return; + } + + strong_this->worker_queue_->EnqueueRelaxed([maybe_token, weak_this, + initial_close_count] { + auto strong_this = weak_this.lock(); + // Streams can be stopped while waiting for authorization, so need + // to check the close count. + if (!strong_this || strong_this->close_count_ != initial_close_count) { + return; + } + strong_this->ResumeStartWithCredentials(maybe_token); + }); + }); +} + +void Stream::ResumeStartWithCredentials(const StatusOr& maybe_token) { + EnsureOnQueue(); + + HARD_ASSERT(state_ == State::Starting, + "State should still be 'Starting' (was %s)", state_); + + if (!maybe_token.ok()) { + OnStreamFinish(maybe_token.status()); + return; + } + + grpc_stream_ = CreateGrpcStream(grpc_connection_, maybe_token.ValueOrDie()); + grpc_stream_->Start(); +} + +void Stream::OnStreamStart() { + EnsureOnQueue(); + + state_ = State::Open; + NotifyStreamOpen(); +} + +// Backoff + +void Stream::BackoffAndTryRestarting() { + EnsureOnQueue(); + + LOG_DEBUG("%s backoff", GetDebugDescription()); + + HARD_ASSERT(state_ == State::Error, + "Should only perform backoff in an error case"); + + state_ = State::Backoff; + backoff_.BackoffAndRun([this] { + HARD_ASSERT(state_ == State::Backoff, + "Backoff elapsed but state is now: %s", state_); + + state_ = State::Initial; + Start(); + HARD_ASSERT(IsStarted(), "Stream should have started."); + }); +} + +void Stream::InhibitBackoff() { + EnsureOnQueue(); + + HARD_ASSERT(!IsStarted(), + "Can only cancel backoff in a stopped state (was %s)", state_); + + // Clear the error condition. + state_ = State::Initial; + backoff_.Reset(); +} + +// Idleness + +void Stream::MarkIdle() { + EnsureOnQueue(); + + if (IsOpen() && !idleness_timer_) { + idleness_timer_ = worker_queue_->EnqueueAfterDelay( + kIdleTimeout, idle_timer_id_, [this] { Stop(); }); + } +} + +void Stream::CancelIdleCheck() { + EnsureOnQueue(); + idleness_timer_.Cancel(); +} + +// Read/write + +void Stream::OnStreamRead(const grpc::ByteBuffer& message) { + EnsureOnQueue(); + + HARD_ASSERT(IsStarted(), "OnStreamRead called for a stopped stream."); + + if (bridge::IsLoggingEnabled()) { + LOG_DEBUG("%s headers (whitelisted): %s", GetDebugDescription(), + Datastore::GetWhitelistedHeadersAsString( + grpc_stream_->GetResponseHeaders())); + } + + Status read_status = NotifyStreamResponse(message); + if (!read_status.ok()) { + grpc_stream_->FinishImmediately(); + // Don't expect gRPC to produce status -- since the error happened on the + // client, we have all the information we need. + OnStreamFinish(read_status); + return; + } +} + +// Stopping + +void Stream::Stop() { + EnsureOnQueue(); + LOG_DEBUG("%s stop", GetDebugDescription()); + + Close(Status::OK()); +} + +void Stream::Close(const Status& status) { + // This function ensures that both graceful stop and stop due to error go + // through the same sequence of steps. While it leads to more conditional + // logic, the benefit is reducing the chance of divergence across the two + // cases. + + EnsureOnQueue(); + bool graceful_stop = status.ok(); + + // Step 1 (both): check current state. + if (graceful_stop && !IsStarted()) { + // Graceful stop is idempotent. + return; + } + HARD_ASSERT(IsStarted(), "Trying to close a non-started stream"); + + // Step 2 (both): cancel any outstanding timers (they're guaranteed not to + // execute). + CancelIdleCheck(); + backoff_.Cancel(); + + // Step 3 (both): increment close count, which invalidates long-lived + // callbacks, guaranteeing they won't execute against a new instance of the + // stream or when the stream has been destroyed. + ++close_count_; + + // Step 4 (both): make small adjustments (to backoff/etc.) based on the + // status. + if (graceful_stop) { + // If this is an intentional close, ensure we don't delay our next + // connection attempt. + backoff_.Reset(); + } else { + HandleErrorStatus(status); + } + + // Step 5 (graceful stop only): give subclasses a chance to send final + // messages. + if (graceful_stop && grpc_stream_) { + // If the stream is in the auth stage, gRPC stream might not have been + // created yet. + LOG_DEBUG("%s Finishing gRPC stream", GetDebugDescription()); + TearDown(grpc_stream_.get()); + } + // Step 6 (both): destroy the underlying stream. + grpc_stream_.reset(); + + // Step 7 (both): update the state machine and notify the listener. + // State must be updated before calling the delegate. + state_ = graceful_stop ? State::Initial : State::Error; + NotifyStreamClose(status); +} + +void Stream::HandleErrorStatus(const Status& status) { + if (status.code() == FirestoreErrorCode::ResourceExhausted) { + LOG_DEBUG( + "%s Using maximum backoff delay to prevent overloading the backend.", + GetDebugDescription()); + backoff_.ResetToMax(); + } else if (status.code() == FirestoreErrorCode::Unauthenticated) { + // "unauthenticated" error means the token was rejected. Try force + // refreshing it in case it just expired. + credentials_provider_->InvalidateToken(); + } +} + +void Stream::OnStreamFinish(const Status& status) { + EnsureOnQueue(); + // TODO(varconst): log error here? + LOG_DEBUG("%s Stream error", GetDebugDescription()); + + Close(status); +} + +// Protected helpers + +void Stream::EnsureOnQueue() const { + worker_queue_->VerifyIsCurrentQueue(); +} + +void Stream::Write(grpc::ByteBuffer&& message) { + EnsureOnQueue(); + + HARD_ASSERT(IsOpen(), "Cannot write when the stream is not open."); + + CancelIdleCheck(); + grpc_stream_->Write(std::move(message)); +} + +std::string Stream::GetDebugDescription() const { + EnsureOnQueue(); + return StringFormat("%s (%s)", GetDebugName(), this); +} + +} // namespace remote +} // namespace firestore +} // namespace firebase diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/watch_change.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/watch_change.h new file mode 100644 index 0000000..885110c --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/watch_change.h @@ -0,0 +1,224 @@ +/* + * Copyright 2019 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_REMOTE_WATCH_CHANGE_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_REMOTE_WATCH_CHANGE_H_ + +#if !defined(__OBJC__) +// TODO(varconst): the only dependencies are `FSTMaybeDocument` and `NSData` +// (the latter is used to represent the resume token). +#error "This header only supports Objective-C++" +#endif // !defined(__OBJC__) + +#import + +#include +#include + +#include "Firestore/core/src/firebase/firestore/model/document_key.h" +#include "Firestore/core/src/firebase/firestore/model/types.h" +#include "Firestore/core/src/firebase/firestore/remote/existence_filter.h" +#include "Firestore/core/src/firebase/firestore/util/status.h" + +@class FSTMaybeDocument; + +namespace firebase { +namespace firestore { +namespace remote { + +/** + * `WatchChange` is the internal representation of the watcher API protocol + * buffers. This is an empty abstract class so that all the different kinds of + * changes can have a common base class. + */ +class WatchChange { + public: + // PORTING NOTE: `WatchChange` is expected to be downcast, but on C++ we can't + // rely on RTTI to be available. + enum class Type { + Document, + ExistenceFilter, + TargetChange, + }; + + virtual ~WatchChange() { + } + + virtual Type type() const = 0; +}; + +/** + * `DocumentWatchChange` represents a changed document and a list of target ids + * to which this change applies. + * + * If document has been deleted, a `DeletedDocument` will be provided. + */ +class DocumentWatchChange : public WatchChange { + public: + DocumentWatchChange(std::vector updated_target_ids, + std::vector removed_target_ids, + model::DocumentKey document_key, + FSTMaybeDocument* new_document) + : updated_target_ids_{std::move(updated_target_ids)}, + removed_target_ids_{std::move(removed_target_ids)}, + document_key_{std::move(document_key)}, + new_document_{new_document} { + } + + Type type() const override { + return Type::Document; + } + + /** The new document applies to all of these targets. */ + const std::vector& updated_target_ids() const { + return updated_target_ids_; + } + + /** The new document is removed from all of these targets. */ + const std::vector& removed_target_ids() const { + return removed_target_ids_; + } + + /** + * The new document, or `DeletedDocument` if it was deleted. Is null if the + * document went out of view without the server sending a new document. + */ + FSTMaybeDocument* new_document() const { + return new_document_; + } + + /** The key of the document for this change. */ + const model::DocumentKey& document_key() const { + return document_key_; + } + + private: + std::vector updated_target_ids_; + std::vector removed_target_ids_; + model::DocumentKey document_key_; + FSTMaybeDocument* new_document_; +}; + +bool operator==(const DocumentWatchChange& lhs, const DocumentWatchChange& rhs); + +/** + * An `ExistenceFilterWatchChange` applies to the targets and is required to + * verify the current client state against expected state sent from the server. + */ +class ExistenceFilterWatchChange : public WatchChange { + public: + ExistenceFilterWatchChange(ExistenceFilter filter, model::TargetId target_id) + : filter_{filter}, target_id_{target_id} { + } + + Type type() const override { + return Type::ExistenceFilter; + } + + const ExistenceFilter& filter() const { + return filter_; + } + model::TargetId target_id() const { + return target_id_; + } + + private: + ExistenceFilter filter_; + model::TargetId target_id_; +}; + +bool operator==(const ExistenceFilterWatchChange& lhs, + const ExistenceFilterWatchChange& rhs); + +enum class WatchTargetChangeState { NoChange, Added, Removed, Current, Reset }; + +class WatchTargetChange : public WatchChange { + public: + WatchTargetChange(WatchTargetChangeState state, + std::vector target_ids) + : WatchTargetChange{state, std::move(target_ids), [NSData data], + util::Status::OK()} { + } + + WatchTargetChange(WatchTargetChangeState state, + std::vector target_ids, + NSData* resume_token) + : WatchTargetChange{state, std::move(target_ids), resume_token, + util::Status::OK()} { + } + + WatchTargetChange(WatchTargetChangeState state, + std::vector target_ids, + util::Status cause) + : WatchTargetChange{state, std::move(target_ids), [NSData data], cause} { + } + + WatchTargetChange(WatchTargetChangeState state, + std::vector target_ids, + NSData* resume_token, + util::Status cause) + : state_{state}, + target_ids_{std::move(target_ids)}, + resume_token_{resume_token}, + cause_{std::move(cause)} { + } + + Type type() const override { + return Type::TargetChange; + } + + /** What kind of change occurred to the watch target. */ + WatchTargetChangeState state() const { + return state_; + } + + /** The target IDs that were added/removed/set. */ + const std::vector& target_ids() const { + return target_ids_; + } + + /** + * An opaque, server-assigned token that allows watching a query to be + * resumed after disconnecting without retransmitting all the data that + * matches the query. The resume token essentially identifies a point in + * time from which the server should resume sending results. + */ + NSData* resume_token() const { + return resume_token_; + } + + /** + * An RPC error indicating why the watch failed. Only valid if + * WatchChangeState == Removed. + */ + const util::Status& cause() const { + return cause_; + } + + private: + WatchTargetChangeState state_; + std::vector target_ids_; + NSData* resume_token_; + util::Status cause_; +}; + +bool operator==(const WatchTargetChange& lhs, const WatchTargetChange& rhs); + +} // namespace remote +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_REMOTE_WATCH_CHANGE_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/watch_change.mm b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/watch_change.mm new file mode 100644 index 0000000..e56d974 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/watch_change.mm @@ -0,0 +1,50 @@ +/* + * Copyright 2019 Google + * + * 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 "Firestore/core/src/firebase/firestore/remote/watch_change.h" + +#import "Firestore/Source/Model/FSTDocument.h" + +#include "Firestore/core/src/firebase/firestore/util/objc_compatibility.h" + +namespace objc = firebase::firestore::util::objc; + +namespace firebase { +namespace firestore { +namespace remote { + +bool operator==(const DocumentWatchChange& lhs, + const DocumentWatchChange& rhs) { + return lhs.updated_target_ids() == rhs.updated_target_ids() && + lhs.removed_target_ids() == rhs.removed_target_ids() && + lhs.document_key() == rhs.document_key() && + objc::Equals(lhs.new_document(), rhs.new_document()); +} + +bool operator==(const ExistenceFilterWatchChange& lhs, + const ExistenceFilterWatchChange& rhs) { + return lhs.filter() == rhs.filter() && lhs.target_id() == rhs.target_id(); +} + +bool operator==(const WatchTargetChange& lhs, const WatchTargetChange& rhs) { + return lhs.state() == rhs.state() && lhs.target_ids() == rhs.target_ids() && + objc::Equals(lhs.resume_token(), rhs.resume_token()) && + lhs.cause() == rhs.cause(); +} + +} // namespace remote +} // namespace firestore +} // namespace firebase diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/watch_stream.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/watch_stream.h new file mode 100644 index 0000000..b6136cf --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/watch_stream.h @@ -0,0 +1,126 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_REMOTE_WATCH_STREAM_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_REMOTE_WATCH_STREAM_H_ + +#if !defined(__OBJC__) +#error "This header only supports Objective-C++" +#endif // !defined(__OBJC__) + +#include +#include + +#include "Firestore/core/src/firebase/firestore/model/snapshot_version.h" +#include "Firestore/core/src/firebase/firestore/model/types.h" +#include "Firestore/core/src/firebase/firestore/remote/grpc_connection.h" +#include "Firestore/core/src/firebase/firestore/remote/remote_objc_bridge.h" +#include "Firestore/core/src/firebase/firestore/remote/stream.h" +#include "Firestore/core/src/firebase/firestore/remote/watch_change.h" +#include "Firestore/core/src/firebase/firestore/util/async_queue.h" +#include "Firestore/core/src/firebase/firestore/util/status.h" +#include "absl/strings/string_view.h" +#include "grpcpp/support/byte_buffer.h" + +#import "Firestore/Source/Core/FSTTypes.h" +#import "Firestore/Source/Local/FSTQueryData.h" +#import "Firestore/Source/Remote/FSTSerializerBeta.h" + +namespace firebase { +namespace firestore { +namespace remote { + +/** + * An interface defining the events that can be emitted by the `WatchStream`. + */ +class WatchStreamCallback { + public: + /** Called by the `WatchStream` when it is ready to accept outbound request + * messages. */ + virtual void OnWatchStreamOpen() = 0; + + /** + * Called by the `WatchStream` with changes and the snapshot versions + * included in in the `WatchChange` responses sent back by the server. + */ + virtual void OnWatchStreamChange( + const WatchChange& change, + const model::SnapshotVersion& snapshot_version) = 0; + + /** + * Called by the `WatchStream` when the underlying streaming RPC is + * interrupted for whatever reason, usually because of an error, but possibly + * due to an idle timeout. The status passed to this method may be ok, in + * which case the stream was closed without attributable fault. + * + * NOTE: This will not be called after `Stop` is called on the stream. See + * "Starting and Stopping" on `Stream` for details. + */ + virtual void OnWatchStreamClose(const util::Status& status) = 0; +}; + +/** + * A `Stream` that implements the StreamingWatch RPC. + * + * Once the `WatchStream` has called the `OnWatchStreamOpen` method on the + * callback, any number of `WatchQuery` and `UnwatchTargetId` calls can be sent + * to control what changes will be sent from the server for WatchChanges. + */ +class WatchStream : public Stream { + public: + WatchStream(util::AsyncQueue* async_queue, + auth::CredentialsProvider* credentials_provider, + FSTSerializerBeta* serializer, + GrpcConnection* grpc_connection, + WatchStreamCallback* callback); + + /** + * Registers interest in the results of the given query. If the query includes + * a resume token, it will be included in the request. Results that affect the + * query will be streamed back as WatchChange messages that reference the + * target ID included in `query`. + */ + virtual /*virtual for tests only*/ void WatchQuery(FSTQueryData* query); + + /** + * Unregisters interest in the results of the query associated with the given + * `target_id`. + */ + virtual /*virtual for tests only*/ void UnwatchTargetId( + model::TargetId target_id); + + private: + std::unique_ptr CreateGrpcStream( + GrpcConnection* grpc_connection, const auth::Token& token) override; + void TearDown(GrpcStream* grpc_stream) override; + + void NotifyStreamOpen() override; + util::Status NotifyStreamResponse(const grpc::ByteBuffer& message) override; + void NotifyStreamClose(const util::Status& status) override; + + std::string GetDebugName() const override { + return "WatchStream"; + } + + bridge::WatchStreamSerializer serializer_bridge_; + WatchStreamCallback* callback_; +}; + +} // namespace remote +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_REMOTE_WATCH_STREAM_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/watch_stream.mm b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/watch_stream.mm new file mode 100644 index 0000000..0066809 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/watch_stream.mm @@ -0,0 +1,108 @@ +/* + * Copyright 2018 Google + * + * 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 "Firestore/core/src/firebase/firestore/remote/watch_stream.h" + +#include "Firestore/core/src/firebase/firestore/util/hard_assert.h" +#include "Firestore/core/src/firebase/firestore/util/log.h" +#include "Firestore/core/src/firebase/firestore/util/status.h" + +#import "Firestore/Protos/objc/google/firestore/v1/Firestore.pbobjc.h" + +namespace firebase { +namespace firestore { +namespace remote { + +using auth::CredentialsProvider; +using auth::Token; +using model::TargetId; +using util::AsyncQueue; +using util::TimerId; +using util::Status; + +WatchStream::WatchStream(AsyncQueue* async_queue, + CredentialsProvider* credentials_provider, + FSTSerializerBeta* serializer, + GrpcConnection* grpc_connection, + WatchStreamCallback* callback) + : Stream{async_queue, credentials_provider, grpc_connection, + TimerId::ListenStreamConnectionBackoff, TimerId::ListenStreamIdle}, + serializer_bridge_{serializer}, + callback_{NOT_NULL(callback)} { +} + +void WatchStream::WatchQuery(FSTQueryData* query) { + EnsureOnQueue(); + + GCFSListenRequest* request = serializer_bridge_.CreateWatchRequest(query); + LOG_DEBUG("%s watch: %s", GetDebugDescription(), + serializer_bridge_.Describe(request)); + Write(serializer_bridge_.ToByteBuffer(request)); +} + +void WatchStream::UnwatchTargetId(TargetId target_id) { + EnsureOnQueue(); + + GCFSListenRequest* request = + serializer_bridge_.CreateUnwatchRequest(target_id); + LOG_DEBUG("%s unwatch: %s", GetDebugDescription(), + serializer_bridge_.Describe(request)); + Write(serializer_bridge_.ToByteBuffer(request)); +} + +std::unique_ptr WatchStream::CreateGrpcStream( + GrpcConnection* grpc_connection, const Token& token) { + return grpc_connection->CreateStream("/google.firestore.v1.Firestore/Listen", + token, this); +} + +void WatchStream::TearDown(GrpcStream* grpc_stream) { + grpc_stream->FinishImmediately(); +} + +void WatchStream::NotifyStreamOpen() { + callback_->OnWatchStreamOpen(); +} + +Status WatchStream::NotifyStreamResponse(const grpc::ByteBuffer& message) { + Status status; + GCFSListenResponse* response = + serializer_bridge_.ParseResponse(message, &status); + if (!status.ok()) { + return status; + } + + if (bridge::IsLoggingEnabled()) { + LOG_DEBUG("%s response: %s", GetDebugDescription(), + serializer_bridge_.Describe(response)); + } + + // A successful response means the stream is healthy. + backoff_.Reset(); + + callback_->OnWatchStreamChange( + *serializer_bridge_.ToWatchChange(response), + serializer_bridge_.ToSnapshotVersion(response)); + return Status::OK(); +} + +void WatchStream::NotifyStreamClose(const Status& status) { + callback_->OnWatchStreamClose(status); +} + +} // namespace remote +} // namespace firestore +} // namespace firebase diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/write_stream.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/write_stream.h new file mode 100644 index 0000000..bfa7530 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/write_stream.h @@ -0,0 +1,164 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_REMOTE_WRITE_STREAM_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_REMOTE_WRITE_STREAM_H_ + +#if !defined(__OBJC__) +#error "This header only supports Objective-C++" +#endif // !defined(__OBJC__) + +#import +#include +#include +#include + +#include "Firestore/core/src/firebase/firestore/model/snapshot_version.h" +#include "Firestore/core/src/firebase/firestore/remote/grpc_connection.h" +#include "Firestore/core/src/firebase/firestore/remote/remote_objc_bridge.h" +#include "Firestore/core/src/firebase/firestore/remote/stream.h" +#include "Firestore/core/src/firebase/firestore/util/async_queue.h" +#include "Firestore/core/src/firebase/firestore/util/status.h" +#include "absl/strings/string_view.h" +#include "grpcpp/support/byte_buffer.h" + +#import "Firestore/Source/Core/FSTTypes.h" +#import "Firestore/Source/Model/FSTMutation.h" +#import "Firestore/Source/Remote/FSTSerializerBeta.h" + +@class FSTMutationResult; + +namespace firebase { +namespace firestore { +namespace remote { + +class WriteStreamCallback { + public: + /** + * Called by the `WriteStream` when it is ready to accept outbound request + * messages. + */ + virtual void OnWriteStreamOpen() = 0; + + /** + * Called by the `WriteStream` upon a successful handshake response from the + * server, which is the receiver's cue to send any pending writes. + */ + virtual void OnWriteStreamHandshakeComplete() = 0; + + /** + * Called by the `WriteStream` upon receiving a StreamingWriteResponse from + * the server that contains mutation results. + */ + virtual void OnWriteStreamMutationResult( + model::SnapshotVersion commit_version, + std::vector results) = 0; + + /** + * Called when the `WriteStream`'s underlying RPC is interrupted for whatever + * reason, usually because of an error, but possibly due to an idle timeout. + * The status passed to this method may be "ok", in which case the stream was + * closed without attributable fault. + * + * NOTE: This will not be called after `Stop` is called on the stream. See + * "Starting and Stopping" on `Stream` for details. + */ + virtual void OnWriteStreamClose(const util::Status& status) = 0; +}; + +/** + * A Stream that implements the Write RPC. + * + * The Write RPC requires the caller to maintain special stream token + * state in-between calls, to help the server understand which responses the + * client has processed by the time the next request is made. Every response + * will contain a stream token; this value must be passed to the next + * request. + * + * After calling `Start` on this stream, the next request must be a handshake, + * containing whatever stream token is on hand. Once a response to this + * request is received, all pending mutations may be submitted. When + * submitting multiple batches of mutations at the same time, it's + * okay to use the same stream token for the calls to `WriteMutations`. + * + * This class is not intended as a base class; all virtual methods exist only + * for the sake of tests. + */ +class WriteStream : public Stream { + public: + WriteStream(util::AsyncQueue* async_queue, + auth::CredentialsProvider* credentials_provider, + FSTSerializerBeta* serializer, + GrpcConnection* grpc_connection, + WriteStreamCallback* callback); + + void SetLastStreamToken(NSData* token); + /** + * The last received stream token from the server, used to acknowledge which + * responses the client has processed. Stream tokens are opaque checkpoint + * markers whose only real value is their inclusion in the next request. + * + * `WriteStream` manages propagating this value from responses to the + * next request. + */ + NSData* GetLastStreamToken() const; + + /** + * Tracks whether or not a handshake has been successfully exchanged and + * the stream is ready to accept mutations. + */ + bool handshake_complete() const { + return handshake_complete_; + } + + /** + * Sends an initial stream token to the server, performing the handshake + * required to make the StreamingWrite RPC work. + */ + virtual void WriteHandshake(); + + /** Sends a group of mutations to the Firestore backend to apply. */ + virtual void WriteMutations(const std::vector& mutations); + + protected: + // For tests only + void SetHandshakeComplete(bool value = true) { + handshake_complete_ = value; + } + + private: + std::unique_ptr CreateGrpcStream( + GrpcConnection* grpc_connection, const auth::Token& token) override; + void TearDown(GrpcStream* call) override; + + void NotifyStreamOpen() override; + util::Status NotifyStreamResponse(const grpc::ByteBuffer& message) override; + void NotifyStreamClose(const util::Status& status) override; + + std::string GetDebugName() const override { + return "WriteStream"; + } + + bridge::WriteStreamSerializer serializer_bridge_; + WriteStreamCallback* callback_ = nullptr; + bool handshake_complete_ = false; +}; + +} // namespace remote +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_REMOTE_WRITE_STREAM_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/write_stream.mm b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/write_stream.mm new file mode 100644 index 0000000..7e0513a --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/remote/write_stream.mm @@ -0,0 +1,144 @@ +/* + * Copyright 2018 Google + * + * 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 "Firestore/core/src/firebase/firestore/remote/write_stream.h" + +#include "Firestore/core/src/firebase/firestore/util/hard_assert.h" +#include "Firestore/core/src/firebase/firestore/util/log.h" +#include "Firestore/core/src/firebase/firestore/util/status.h" + +#import "Firestore/Protos/objc/google/firestore/v1/Firestore.pbobjc.h" + +namespace firebase { +namespace firestore { +namespace remote { + +using auth::CredentialsProvider; +using auth::Token; +using util::AsyncQueue; +using util::TimerId; +using util::Status; + +WriteStream::WriteStream(AsyncQueue* async_queue, + CredentialsProvider* credentials_provider, + FSTSerializerBeta* serializer, + GrpcConnection* grpc_connection, + WriteStreamCallback* callback) + : Stream{async_queue, credentials_provider, grpc_connection, + TimerId::WriteStreamConnectionBackoff, TimerId::WriteStreamIdle}, + serializer_bridge_{serializer}, + callback_{NOT_NULL(callback)} { +} + +void WriteStream::SetLastStreamToken(NSData* token) { + serializer_bridge_.SetLastStreamToken(token); +} + +NSData* WriteStream::GetLastStreamToken() const { + return serializer_bridge_.GetLastStreamToken(); +} + +void WriteStream::WriteHandshake() { + EnsureOnQueue(); + HARD_ASSERT(IsOpen(), "Writing handshake requires an opened stream"); + HARD_ASSERT(!handshake_complete(), "Handshake already completed"); + + GCFSWriteRequest* request = serializer_bridge_.CreateHandshake(); + LOG_DEBUG("%s initial request: %s", GetDebugDescription(), + serializer_bridge_.Describe(request)); + Write(serializer_bridge_.ToByteBuffer(request)); + + // TODO(dimond): Support stream resumption. We intentionally do not set the + // stream token on the handshake, ignoring any stream token we might have. +} + +void WriteStream::WriteMutations(const std::vector& mutations) { + EnsureOnQueue(); + HARD_ASSERT(IsOpen(), "Writing mutations requires an opened stream"); + HARD_ASSERT(handshake_complete(), + "Handshake must be complete before writing mutations"); + + GCFSWriteRequest* request = + serializer_bridge_.CreateWriteMutationsRequest(mutations); + LOG_DEBUG("%s write request: %s", GetDebugDescription(), + serializer_bridge_.Describe(request)); + Write(serializer_bridge_.ToByteBuffer(request)); +} + +std::unique_ptr WriteStream::CreateGrpcStream( + GrpcConnection* grpc_connection, const Token& token) { + return grpc_connection->CreateStream("/google.firestore.v1.Firestore/Write", + token, this); +} + +void WriteStream::TearDown(GrpcStream* grpc_stream) { + if (handshake_complete()) { + // Send an empty write request to the backend to indicate imminent stream + // closure. This isn't mandatory, but it allows the backend to clean up + // resources. + GCFSWriteRequest* request = serializer_bridge_.CreateEmptyMutationsList(); + grpc_stream->WriteAndFinish(serializer_bridge_.ToByteBuffer(request)); + } else { + grpc_stream->FinishImmediately(); + } +} + +void WriteStream::NotifyStreamOpen() { + callback_->OnWriteStreamOpen(); +} + +void WriteStream::NotifyStreamClose(const Status& status) { + callback_->OnWriteStreamClose(status); + // Delegate's logic might depend on whether handshake was completed, so only + // reset it after notifying. + handshake_complete_ = false; +} + +Status WriteStream::NotifyStreamResponse(const grpc::ByteBuffer& message) { + Status status; + GCFSWriteResponse* response = + serializer_bridge_.ParseResponse(message, &status); + if (!status.ok()) { + return status; + } + + LOG_DEBUG("%s response: %s", GetDebugDescription(), + serializer_bridge_.Describe(response)); + + // Always capture the last stream token. + serializer_bridge_.UpdateLastStreamToken(response); + + if (!handshake_complete()) { + // The first response is the handshake response + handshake_complete_ = true; + callback_->OnWriteStreamHandshakeComplete(); + } else { + // A successful first write response means the stream is healthy. + // Note that we could consider a successful handshake healthy, however, the + // write itself might be causing an error we want to back off from. + backoff_.Reset(); + + callback_->OnWriteStreamMutationResult( + serializer_bridge_.ToCommitVersion(response), + serializer_bridge_.ToMutationResults(response)); + } + + return Status::OK(); +} + +} // namespace remote +} // namespace firestore +} // namespace firebase diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/timestamp.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/timestamp.cc new file mode 100644 index 0000000..50ddec6 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/timestamp.cc @@ -0,0 +1,122 @@ +/* + * Copyright 2018 Google + * + * 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 "Firestore/core/include/firebase/firestore/timestamp.h" + +#include + +#include "Firestore/core/src/firebase/firestore/util/hard_assert.h" +#include "absl/strings/str_cat.h" + +namespace firebase { + +Timestamp::Timestamp() { +} + +Timestamp::Timestamp(const int64_t seconds, const int32_t nanoseconds) + : seconds_(seconds), nanoseconds_(nanoseconds) { + ValidateBounds(); +} + +Timestamp Timestamp::Now() { +#if !defined(_STLPORT_VERSION) + // Use the standard library from C++11 if possible. + return FromTimePoint(std::chrono::system_clock::now()); +#else + // If is unavailable, use clock_gettime from POSIX, which supports up + // to nanosecond resolution. Note that it's a non-standard function contained + // in . + // + // Note: it's possible to check for availability of POSIX clock_gettime using + // macros (see "Availability" at https://linux.die.net/man/3/clock_gettime). + // However, the only platform where isn't available is Android with + // STLPort standard library, where clock_gettime is known to be available. + timespec now; + clock_gettime(CLOCK_REALTIME, &now); + return Timestamp(now.tv_sec, now.tv_nsec); +#endif // !defined(_STLPORT_VERSION) +} + +Timestamp Timestamp::FromTimeT(const time_t seconds_since_unix_epoch) { + return {seconds_since_unix_epoch, 0}; +} + +#if !defined(_STLPORT_VERSION) +Timestamp Timestamp::FromTimePoint( + const std::chrono::time_point time_point) { + namespace chr = std::chrono; + const auto epoch_time = time_point.time_since_epoch(); + auto seconds = chr::duration_cast>(epoch_time); + auto nanoseconds = chr::duration_cast(epoch_time - seconds); + HARD_ASSERT(nanoseconds.count() < 1 * 1000 * 1000 * 1000); + + if (nanoseconds.count() < 0) { + // Timestamp format always has a positive number of nanoseconds that is + // counting forward. For negative time, we need to transform chrono + // representation of (negative seconds s1 + negative nanoseconds ns1) to + // (negative seconds s2 + positive nanoseconds ns2). Since nanosecond part + // is always less than 1 second in our representation, instead of starting + // at s1 and going back ns1 nanoseconds, start at (s1 minus one second) and + // go *forward* ns2 = (1 second + ns1, ns1 < 0) nanoseconds. + // + // Note: if nanoseconds are negative, it must mean that seconds are + // non-positive, but the formula would still be valid, so no need to check. + seconds = seconds - chr::seconds(1); + nanoseconds = chr::seconds(1) + nanoseconds; + } + + const Timestamp result{seconds.count(), + static_cast(nanoseconds.count())}; + result.ValidateBounds(); + return result; +} + +#endif // !defined(_STLPORT_VERSION) + +std::string Timestamp::ToString() const { + return absl::StrCat("Timestamp(seconds=", seconds_, + ", nanoseconds=", nanoseconds_, ")"); +} + +std::ostream& operator<<(std::ostream& out, const Timestamp& timestamp) { + return out << timestamp.ToString(); +} + +void Timestamp::ValidateBounds() const { + HARD_ASSERT(nanoseconds_ >= 0, "Timestamp nanoseconds out of range: %s", + nanoseconds_); + HARD_ASSERT(nanoseconds_ < 1e9, "Timestamp nanoseconds out of range: %s", + nanoseconds_); + // Midnight at the beginning of 1/1/1 is the earliest timestamp Firestore + // supports. + HARD_ASSERT(seconds_ >= -62135596800L, "Timestamp seconds out of range: %s", + seconds_); + // This will break in the year 10,000. + HARD_ASSERT(seconds_ < 253402300800L, "Timestamp seconds out of range: %s", + seconds_); +} + +} // namespace firebase + +namespace std { +size_t hash::operator()( + const firebase::Timestamp& timestamp) const { + // Note: if sizeof(size_t) == 4, this discards high-order bits of seconds. + return 37 * static_cast(timestamp.seconds()) + + static_cast(timestamp.nanoseconds()); +} + +} // namespace std diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/timestamp_internal.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/timestamp_internal.h new file mode 100644 index 0000000..3516176 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/timestamp_internal.h @@ -0,0 +1,49 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_TIMESTAMP_INTERNAL_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_TIMESTAMP_INTERNAL_H_ + +#include "Firestore/core/include/firebase/firestore/timestamp.h" + +namespace firebase { + +/** + * Details about the Timestamp class which are useful internally, but we don't + * want to expose publicly. + */ +class TimestampInternal { + public: + /** + * Represents the maximum allowable time that the Timestamp class handles, + * specifically 9999-12-31T23:59:59.999999999Z. + */ + static firebase::Timestamp Max() { + return {253402300800L - 1, 999999999}; + } + + /** + * Represents the minimum allowable time that the Timestamp class handles, + * specifically 0001-01-01T00:00:00Z. + */ + static firebase::Timestamp Min() { + return {-62135596800L, 0}; + } +}; + +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_TIMESTAMP_INTERNAL_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/async_queue.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/async_queue.cc new file mode 100644 index 0000000..3b8c3c8 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/async_queue.cc @@ -0,0 +1,136 @@ +/* + * Copyright 2018 Google + * + * 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 "Firestore/core/src/firebase/firestore/util/async_queue.h" + +#include + +#include "Firestore/core/src/firebase/firestore/util/hard_assert.h" +#include "absl/memory/memory.h" + +namespace firebase { +namespace firestore { +namespace util { + +AsyncQueue::AsyncQueue(std::unique_ptr executor) + : executor_{std::move(executor)} { + is_operation_in_progress_ = false; +} + +// TODO(varconst): assert in destructor that the queue is empty. + +void AsyncQueue::VerifyIsCurrentExecutor() const { + HARD_ASSERT( + executor_->IsCurrentExecutor(), + "Expected to be called by the executor associated with this queue " + "(expected executor: '%s', actual executor: '%s')", + executor_->Name(), executor_->CurrentExecutorName()); +} + +void AsyncQueue::VerifyIsCurrentQueue() const { + VerifyIsCurrentExecutor(); + HARD_ASSERT(is_operation_in_progress_, + "VerifyIsCurrentQueue called when no operation is executing " + "(expected executor: '%s', actual executor: '%s')", + executor_->Name(), executor_->CurrentExecutorName()); +} + +void AsyncQueue::ExecuteBlocking(const Operation& operation) { + VerifyIsCurrentExecutor(); + HARD_ASSERT(!is_operation_in_progress_, + "ExecuteBlocking may not be called " + "before the previous operation finishes executing"); + + is_operation_in_progress_ = true; + operation(); + is_operation_in_progress_ = false; +} + +void AsyncQueue::Enqueue(const Operation& operation) { + VerifySequentialOrder(); + EnqueueRelaxed(operation); +} + +void AsyncQueue::EnqueueRelaxed(const Operation& operation) { + executor_->Execute(Wrap(operation)); +} + +DelayedOperation AsyncQueue::EnqueueAfterDelay(const Milliseconds delay, + const TimerId timer_id, + const Operation& operation) { + VerifyIsCurrentExecutor(); + + // While not necessarily harmful, we currently don't expect to have multiple + // callbacks with the same timer_id in the queue, so defensively reject + // them. + HARD_ASSERT(!IsScheduled(timer_id), + "Attempted to schedule multiple operations with id %s", timer_id); + + Executor::TaggedOperation tagged{static_cast(timer_id), Wrap(operation)}; + return executor_->Schedule(delay, std::move(tagged)); +} + +AsyncQueue::Operation AsyncQueue::Wrap(const Operation& operation) { + // Decorator pattern: wrap `operation` into a call to `ExecuteBlocking` to + // ensure that it doesn't spawn any nested operations. + + // Note: can't move `operation` into lambda until C++14. + return [this, operation] { ExecuteBlocking(operation); }; +} + +void AsyncQueue::VerifySequentialOrder() const { + // This is the inverse of `VerifyIsCurrentQueue`. + HARD_ASSERT(!is_operation_in_progress_ || !executor_->IsCurrentExecutor(), + "Enqueue methods cannot be called when we are already running on " + "target executor " + "(this queue's executor: '%s', current executor: '%s')", + executor_->Name(), executor_->CurrentExecutorName()); +} + +// Test-only functions + +void AsyncQueue::EnqueueBlocking(const Operation& operation) { + VerifySequentialOrder(); + executor_->ExecuteBlocking(Wrap(operation)); +} + +bool AsyncQueue::IsScheduled(const TimerId timer_id) const { + return executor_->IsScheduled(static_cast(timer_id)); +} + +void AsyncQueue::RunScheduledOperationsUntil(const TimerId last_timer_id) { + HARD_ASSERT(!executor_->IsCurrentExecutor(), + "RunScheduledOperationsUntil must not be called on the queue"); + + executor_->ExecuteBlocking([this, last_timer_id] { + HARD_ASSERT( + last_timer_id == TimerId::All || IsScheduled(last_timer_id), + "Attempted to run scheduled operations until missing timer id: %s", + last_timer_id); + + for (auto next = executor_->PopFromSchedule(); next.has_value(); + next = executor_->PopFromSchedule()) { + next->operation(); + if (next->tag == static_cast(last_timer_id)) { + break; + } + } + }); +} + +} // namespace util +} // namespace firestore +} // namespace firebase diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/async_queue.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/async_queue.h new file mode 100644 index 0000000..e3971ee --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/async_queue.h @@ -0,0 +1,173 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_ASYNC_QUEUE_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_ASYNC_QUEUE_H_ + +#include +#include // NOLINT(build/c++11) +#include +#include + +#include "Firestore/core/src/firebase/firestore/util/executor.h" + +namespace firebase { +namespace firestore { +namespace util { + +/** + * Well-known "timer" ids used when scheduling delayed operations on the + * AsyncQueue. These ids can then be used from tests to check for the + * presence of delayed operations or to run them early. + */ +enum class TimerId { + /** All can be used with `RunScheduledOperationsUntil` to run all timers. */ + All, + + /** + * The following 4 timers are used in `Stream` for the listen and write + * streams. The "Idle" timer is used to close the stream due to inactivity. + * The "ConnectionBackoff" timer is used to restart a stream once the + * appropriate backoff delay has elapsed. + */ + ListenStreamIdle, + ListenStreamConnectionBackoff, + WriteStreamIdle, + WriteStreamConnectionBackoff, + + /** + * A timer used in `OnlineStateTracker` to transition from + * `OnlineStateUnknown` to `Offline` after a set timeout, rather than waiting + * indefinitely for success or failure. + */ + OnlineStateTimeout, + /** + * A timer used to periodically attempt LRU Garbage collection + */ + GarbageCollectionDelay +}; + +// A serial queue that executes given operations asynchronously, one at a time. +// Operations may be scheduled to be executed as soon as possible or in the +// future. Operations scheduled for the same time are FIFO-ordered. +// +// `AsyncQueue` wraps a platform-specific executor, adding checks that enforce +// sequential ordering of operations: an enqueued operation, while being run, +// normally cannot enqueue other operations for immediate execution (but see +// `EnqueueRelaxed`). +// +// `AsyncQueue` methods have particular expectations about whether they must be +// invoked on the queue or not; check "preconditions" section in comments on +// each method. +// +// A significant portion of `AsyncQueue` interface only exists for test purposes +// and must *not* be used in regular code. +class AsyncQueue { + public: + using Operation = Executor::Operation; + using Milliseconds = Executor::Milliseconds; + + explicit AsyncQueue(std::unique_ptr executor); + + // Asserts for the caller that it is being invoked as part of an operation on + // the `AsyncQueue`. + void VerifyIsCurrentQueue() const; + + // Enqueue methods + + // Puts the `operation` on the queue to be executed as soon as possible, while + // maintaining FIFO order. + // + // Precondition: `Enqueue` calls cannot be nested; that is, `Enqueue` may not + // be called by a previously enqueued operation when it is run (as a special + // case, destructors invoked when an enqueued operation has run and is being + // destroyed may invoke `Enqueue`). + void Enqueue(const Operation& operation); + + // Like `Enqueue`, but without applying any prerequisite checks. + void EnqueueRelaxed(const Operation& operation); + + // Puts the `operation` on the queue to be executed `delay` milliseconds from + // now, and returns a handle that allows to cancel the operation (provided it + // hasn't run already). + // + // `operation` is tagged by a `timer_id` which allows to identify the caller. + // Only one operation tagged with any given `timer_id` may be on the queue at + // any time; an attempt to put another such operation will result in an + // assertion failure. In tests, these tags also allow to check for presence of + // certain operations and to run certain operations in advance. + // + // Precondition: `EnqueueAfterDelay` is being invoked asynchronously on the + // queue. + DelayedOperation EnqueueAfterDelay(Milliseconds delay, + TimerId timer_id, + const Operation& operation); + + // Direct execution + + // Immediately executes the `operation` on the queue. + // + // This is largely a workaround to allow other classes (GRPC) to directly + // access the underlying dispatch queue without getting `AsyncQueue` into an + // inconsistent state. + // + // Precondition: no other operation is being executed on the queue at the + // moment of the call (i.e., `ExecuteBlocking` cannot call `ExecuteBlocking`). + // + // Precondition: `ExecuteBlocking` is being invoked asynchronously on the + // queue. + void ExecuteBlocking(const Operation& operation); + + // Returns the underlying platform-dependent executor. + Executor* executor() { + return executor_.get(); + } + + // Test-only interface follows + // TODO(varconst): move the test-only interface into a helper object that is + // a friend of AsyncQueue and delegates its public methods to private methods + // on AsyncQueue. + + // Like `Enqueue`, but blocks until the `operation` is complete. + void EnqueueBlocking(const Operation& operation); + + // Checks whether an operation tagged with `timer_id` is currently scheduled + // for execution in the future. + bool IsScheduled(TimerId timer_id) const; + + // Force runs operations scheduled for future execution, in scheduled order, + // up to *and including* the operation tagged with `last_timer_id`. + // + // Precondition: `RunScheduledOperationsUntil` is *not* being invoked on the + // queue. + void RunScheduledOperationsUntil(TimerId last_timer_id); + + private: + Operation Wrap(const Operation& operation); + + // Asserts that the current invocation happens asynchronously on the queue. + void VerifyIsCurrentExecutor() const; + void VerifySequentialOrder() const; + + std::atomic is_operation_in_progress_; + std::unique_ptr executor_; +}; + +} // namespace util +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_ASYNC_QUEUE_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/autoid.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/autoid.cc new file mode 100644 index 0000000..10a2cde --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/autoid.cc @@ -0,0 +1,56 @@ +/* + * Copyright 2017 Google + * + * 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 "Firestore/core/src/firebase/firestore/util/autoid.h" + +#include +#include + +#include "Firestore/core/src/firebase/firestore/util/secure_random.h" + +namespace firebase { +namespace firestore { +namespace util { + +namespace { + +const int kAutoIdLength = 20; +const char kAutoIdAlphabet[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + +SecureRandom shared_random; + +} // namespace + +std::string CreateAutoId() { + std::string auto_id; + auto_id.reserve(kAutoIdLength); + + // -2 here because: + // * sizeof(kAutoIdAlphabet) includes the trailing null terminator + // * uniform_int_distribution is inclusive on both sizes + std::uniform_int_distribution letters(0, sizeof(kAutoIdAlphabet) - 2); + + for (int i = 0; i < kAutoIdLength; i++) { + int rand_index = letters(shared_random); + auto_id.append(1, kAutoIdAlphabet[rand_index]); + } + return auto_id; +} + +} // namespace util +} // namespace firestore +} // namespace firebase diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/autoid.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/autoid.h new file mode 100644 index 0000000..22d7d7d --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/autoid.h @@ -0,0 +1,33 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_AUTOID_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_AUTOID_H_ + +#include + +namespace firebase { +namespace firestore { +namespace util { + +// Generates a random ID suitable for use as a document ID. +std::string CreateAutoId(); + +} // namespace util +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_AUTOID_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/bits.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/bits.cc new file mode 100644 index 0000000..03d9b77 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/bits.cc @@ -0,0 +1,43 @@ +/* + * Copyright 2017 Google + * + * 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 "Firestore/core/src/firebase/firestore/util/bits.h" + +#include "Firestore/core/src/firebase/firestore/util/hard_assert.h" + +namespace firebase { +namespace firestore { +namespace util { + +int Bits::Log2Floor_Portable(uint32_t n) { + if (n == 0) return -1; + int log = 0; + uint32_t value = n; + for (int i = 4; i >= 0; --i) { + int shift = (1 << i); + uint32_t x = value >> shift; + if (x != 0) { + value = x; + log += shift; + } + } + HARD_ASSERT(value == 1); + return log; +} + +} // namespace util +} // namespace firestore +} // namespace firebase diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/bits.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/bits.h new file mode 100644 index 0000000..591c306 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/bits.h @@ -0,0 +1,166 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_BITS_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_BITS_H_ + +// Various bit-twiddling functions, all of which are static members of the Bits +// class (making it effectively a namespace). Operands are unsigned integers. +// Munging bits in _signed_ integers is fraught with peril! For example, +// -5 << n has undefined behavior (for some values of n). + +#include + +namespace firebase { +namespace firestore { +namespace util { + +class Bits_Port32_Test; +class Bits_Port64_Test; + +class Bits { + public: + /** Return floor(log2(n)) for positive integer n. Returns -1 iff n == 0. */ + static int Log2Floor(uint32_t n); + static int Log2Floor64(uint64_t n); + + /** + * Potentially faster version of Log2Floor() that returns an + * undefined value if n == 0. + */ + static int Log2FloorNonZero(uint32_t n); + static int Log2FloorNonZero64(uint64_t n); + + private: + // Portable implementations. + static int Log2Floor_Portable(uint32_t n); + static int Log2Floor64_Portable(uint64_t n); + static int Log2FloorNonZero_Portable(uint32_t n); + static int Log2FloorNonZero64_Portable(uint64_t n); + + Bits(Bits const&) = delete; + void operator=(Bits const&) = delete; + + // Allow tests to call _Portable variants directly. + friend class Bits_Port32_Test; + friend class Bits_Port64_Test; +}; + +// ------------------------------------------------------------------------ +// Implementation details follow +// ------------------------------------------------------------------------ + +#if defined(__GNUC__) + +inline int Bits::Log2Floor(uint32_t n) { + return n == 0 ? -1 : 31 ^ __builtin_clz(n); +} + +inline int Bits::Log2FloorNonZero(uint32_t n) { + return 31 ^ __builtin_clz(n); +} + +inline int Bits::Log2Floor64(uint64_t n) { + return n == 0 ? -1 : 63 ^ __builtin_clzll(n); +} + +inline int Bits::Log2FloorNonZero64(uint64_t n) { + return 63 ^ __builtin_clzll(n); +} + +#elif defined(_MSC_VER) + +inline int Bits::Log2FloorNonZero(uint32_t n) { +#ifdef _M_IX86 + _asm { + bsr ebx, n + mov n, ebx + } + return n; +#else + return Bits::Log2FloorNonZero_Portable(n); +#endif +} + +inline int Bits::Log2Floor(uint32_t n) { +#ifdef _M_IX86 + _asm { + xor ebx, ebx + mov eax, n + and eax, eax + jz return_ebx + bsr ebx, eax + return_ebx: + mov n, ebx + } + return n; +#else + return Bits::Log2Floor_Portable(n); +#endif +} + +inline int Bits::Log2Floor64(uint64_t n) { + return Bits::Log2Floor64_Portable(n); +} + +inline int Bits::Log2FloorNonZero64(uint64_t n) { + return Bits::Log2FloorNonZero64_Portable(n); +} + +#else // !__GNUC__ && !_MSC_VER + +inline int Bits::Log2Floor64(uint64_t n) { + return Bits::Log2Floor64_Portable(n); +} + +inline int Bits::Log2FloorNonZero64(uint64_t n) { + return Bits::Log2FloorNonZero64_Portable(n); +} + +#endif + +inline int Bits::Log2FloorNonZero_Portable(uint32_t n) { + // Just use the common routine + return Log2Floor(n); +} + +// Log2Floor64() is defined in terms of Log2Floor32(), Log2FloorNonZero32() +inline int Bits::Log2Floor64_Portable(uint64_t n) { + const auto top_bits = static_cast(n >> 32); + if (top_bits == 0) { + // Top bits are zero, so scan in bottom bits + return Log2Floor(static_cast(n)); + } else { + return 32 + Log2FloorNonZero(top_bits); + } +} + +// Log2FloorNonZero64() is defined in terms of Log2FloorNonZero32() +inline int Bits::Log2FloorNonZero64_Portable(uint64_t n) { + const auto top_bits = static_cast(n >> 32); + if (top_bits == 0) { + // Top bits are zero, so scan in bottom bits + return Log2FloorNonZero(static_cast(n)); + } else { + return 32 + Log2FloorNonZero(top_bits); + } +} + +} // namespace util +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_BITS_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/comparator_holder.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/comparator_holder.h new file mode 100644 index 0000000..3147117 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/comparator_holder.h @@ -0,0 +1,64 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_COMPARATOR_HOLDER_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_COMPARATOR_HOLDER_H_ + +#include + +namespace firebase { +namespace firestore { +namespace util { + +/** + * A holder of some comparator (e.g. std::less or util::Comparator) that + * implements the empty base optimization for the common case where the + * comparator occupies no storage. + */ +template ::value> +class ComparatorHolder { + protected: + explicit ComparatorHolder(const C& comparator) noexcept + : comparator_(comparator) { + } + + public: + const C& comparator() const noexcept { + return comparator_; + } + + private: + C comparator_; +}; + +// Implementation to use when C is empty. +template +class ComparatorHolder : private C { + protected: + explicit ComparatorHolder(const C& /* comparator */) noexcept { + } + + public: + const C& comparator() const noexcept { + return *this; + } +}; + +} // namespace util +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_COMPARATOR_HOLDER_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/comparison.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/comparison.cc new file mode 100644 index 0000000..0e7fe25 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/comparison.cc @@ -0,0 +1,118 @@ +/* + * Copyright 2018 Google + * + * 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 "Firestore/core/src/firebase/firestore/util/comparison.h" + +#include +#include + +namespace firebase { +namespace firestore { +namespace util { +using std::isnan; + +bool Comparator::operator()(absl::string_view left, + absl::string_view right) const { + // TODO(wilhuff): truncation aware comparison + return left < right; +} + +bool Comparator::operator()(const std::string& left, + const std::string& right) const { + // TODO(wilhuff): truncation aware comparison + return left < right; +} + +bool Comparator::operator()(double left, double right) const { + // NaN sorts equal to itself and before any other number. + if (left < right) { + return true; + } else if (left >= right) { + return false; + } else { + // One or both left and right is NaN. + return isnan(left) && !isnan(right); + } +} + +static constexpr double INT64_MIN_VALUE_AS_DOUBLE = + static_cast(std::numeric_limits::min()); + +static constexpr double INT64_MAX_VALUE_AS_DOUBLE = + static_cast(std::numeric_limits::max()); + +ComparisonResult CompareMixedNumber(double double_value, int64_t int64_value) { + // LLONG_MIN has an exact representation as double, so to check for a value + // outside the range representable by long, we have to check for strictly less + // than LLONG_MIN. Note that this also handles negative infinity. + if (double_value < INT64_MIN_VALUE_AS_DOUBLE) { + return ComparisonResult::Ascending; + } + + // LLONG_MAX has no exact representation as double (casting as we've done + // makes 2^63, which is larger than LLONG_MAX), so consider any value greater + // than or equal to the threshold to be out of range. This also handles + // positive infinity. + if (double_value >= INT64_MAX_VALUE_AS_DOUBLE) { + return ComparisonResult::Descending; + } + + // In Firestore NaN is defined to compare before all other numbers. + if (isnan(double_value)) { + return ComparisonResult::Ascending; + } + + auto double_as_int64 = static_cast(double_value); + ComparisonResult cmp = Compare(double_as_int64, int64_value); + if (cmp != ComparisonResult::Same) { + return cmp; + } + + // At this point the long representations are equal but this could be due to + // rounding. + auto int64_as_double = static_cast(int64_value); + return Compare(double_value, int64_as_double); +} + +/** Helper to normalize a double and then return the raw bits as a uint64_t. */ +uint64_t DoubleBits(double d) { + if (isnan(d)) { + d = NAN; + } + + // Unlike C, C++ does not define type punning through a union type. + + // TODO(wilhuff): replace with absl::bit_cast + static_assert(sizeof(double) == sizeof(uint64_t), "doubles must be 8 bytes"); + uint64_t bits; + memcpy(&bits, &d, sizeof(bits)); + return bits; +} + +bool DoubleBitwiseEquals(double left, double right) { + return DoubleBits(left) == DoubleBits(right); +} + +size_t DoubleBitwiseHash(double d) { + uint64_t bits = DoubleBits(d); + // Note that x ^ (x >> 32) works fine for both 32 and 64 bit definitions of + // size_t + return static_cast(bits) ^ static_cast(bits >> 32); +} + +} // namespace util +} // namespace firestore +} // namespace firebase diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/comparison.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/comparison.h new file mode 100644 index 0000000..98262fc --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/comparison.h @@ -0,0 +1,208 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_COMPARISON_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_COMPARISON_H_ + +#if __OBJC__ +#import +#endif + +#include + +#include +#include +#include +#include + +#include "Firestore/core/src/firebase/firestore/util/string_apple.h" +#include "absl/strings/string_view.h" + +namespace firebase { +namespace firestore { +namespace util { + +/** + * An enumeration describing the result of a three-way comparison among + * strongly-ordered values (i.e. where comparison between values always yields + * less-than, equal-to, or greater-than). + * + * This is equivalent to: + * + * * NSComparisonResult from the iOS/macOS Foundation framework. + * * std::strong_ordering from C++20 + * + * The values of the constants are specifically chosen so as to make casting + * between this type and NSComparisonResult possible. + */ +enum class ComparisonResult { + /** The left hand side was less than the right. */ + Ascending = -1, + + /** The left hand side was equal to the right. */ + Same = 0, + + /** The left hand side was greater than the right. */ + Descending = 1 +}; + +/** + * Returns the reverse order (i.e. Ascending => Descending) etc. + */ +constexpr ComparisonResult ReverseOrder(ComparisonResult result) { + return static_cast(-static_cast(result)); +} + +/** + * A generalized comparator for types in Firestore, with ordering defined + * according to Firestore's semantics. This is useful as argument to e.g. + * std::sort. + * + * Comparators are only defined for the limited set of types for which + * Firestore defines an ordering. + */ +template +struct Comparator { + // By default comparison is not defined +}; + +/** Compares two strings. */ +template <> +struct Comparator { + bool operator()(absl::string_view left, absl::string_view right) const; +}; + +template <> +struct Comparator { + bool operator()(const std::string& left, const std::string& right) const; +}; + +/** Compares two bools: false < true. */ +template <> +struct Comparator : public std::less {}; + +/** Compares two int32_t. */ +template <> +struct Comparator : public std::less {}; + +/** Compares two int64_t. */ +template <> +struct Comparator : public std::less {}; + +/** Compares two doubles (using Firestore semantics for NaN). */ +template <> +struct Comparator { + bool operator()(double left, double right) const; +}; + +/** Compare two byte sequences. */ +// TODO(wilhuff): perhaps absl::Span would be better? +template <> +struct Comparator> + : public std::less> {}; + +/** + * Perform a three-way comparison between the left and right values using + * the appropriate Comparator for the values based on their type. + */ +template > +ComparisonResult Compare(const T& left, + const T& right, + const C& less_than = C()) { + if (less_than(left, right)) { + return ComparisonResult::Ascending; + } else if (less_than(right, left)) { + return ComparisonResult::Descending; + } else { + return ComparisonResult::Same; + } +} + +#if __OBJC__ +/** + * Returns true if the given ComparisonResult and NSComparisonResult have the + * same integer values (at compile time). + */ +constexpr bool EqualValue(ComparisonResult lhs, NSComparisonResult rhs) { + return static_cast(lhs) == static_cast(rhs); +} + +/** + * Performs a three-way comparison, identically to Compare, but converts the + * result to an NSComparisonResult. + * + * This function exists for interoperation with Objective-C++ and should + * eventually be removed. + */ +template +inline NSComparisonResult WrapCompare(const T& left, const T& right) { + static_assert(EqualValue(ComparisonResult::Ascending, NSOrderedAscending), + "Ascending invalid"); + static_assert(EqualValue(ComparisonResult::Same, NSOrderedSame), + "Same invalid"); + static_assert(EqualValue(ComparisonResult::Descending, NSOrderedDescending), + "Descending invalid"); + + return static_cast(Compare(left, right)); +} +#endif + +/** Compares a double and an int64_t. */ +ComparisonResult CompareMixedNumber(double doubleValue, int64_t longValue); + +/** Normalizes a double and then return the raw bits as a uint64_t. */ +uint64_t DoubleBits(double d); + +/** + * Compares the bitwise representation of two doubles, but normalizes NaN + * values. This is similar to what the backend and android clients do, including + * comparing -0.0 as not equal to 0.0. + */ +bool DoubleBitwiseEquals(double left, double right); + +/** + * Computes a bitwise hash of a double, but normalizes NaN values, suitable for + * use when using FSTDoublesAreBitwiseEqual for equality. + */ +size_t DoubleBitwiseHash(double d); + +template +class Equatable { + public: + friend bool operator!=(const T& lhs, const T& rhs) { + return !(lhs == rhs); + } +}; + +template +class Comparable : public Equatable { + public: + friend bool operator>(const T& lhs, const T& rhs) { + return rhs < lhs; + } + friend bool operator<=(const T& lhs, const T& rhs) { + return !(rhs < lhs); + } + friend bool operator>=(const T& lhs, const T& rhs) { + return !(lhs < rhs); + } +}; + +} // namespace util +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_COMPARISON_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/config.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/config.h new file mode 100644 index 0000000..17f04b0 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/config.h @@ -0,0 +1,33 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_CONFIG_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_CONFIG_H_ + +// This header defines macros for all available platform configuration values. +// When building with CMake, it will substitute the lines marked with +// cmakedefine with values corresponding to the local configuration. +// +// On Apple platforms we support building via CocoaPods without CMake. When +// building this way we can't test the presence of features before building so +// predefine all the platform-support feature macros to their expected values. + +#if COCOAPODS +# define HAVE_ARC4RANDOM 1 +#endif + + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_CONFIG_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/config.h.in b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/config.h.in new file mode 100644 index 0000000..e7a0c03 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/config.h.in @@ -0,0 +1,35 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_CONFIG_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_CONFIG_H_ + +// This header defines macros for all available platform configuration values. +// When building with CMake, it will substitute the lines marked with +// cmakedefine with values corresponding to the local configuration. +// +// On Apple platforms we support building via CocoaPods without CMake. When +// building this way we can't test the presence of features before building so +// predefine all the platform-support feature macros to their expected values. + +#cmakedefine HAVE_ARC4RANDOM 1 +#if COCOAPODS +# define HAVE_ARC4RANDOM 1 +#endif + +#cmakedefine HAVE_OPENSSL_RAND_H 1 + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_CONFIG_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/delayed_constructor.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/delayed_constructor.h new file mode 100644 index 0000000..9c00e51 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/delayed_constructor.h @@ -0,0 +1,131 @@ +/* + * Copyright 2019 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_DELAYED_CONSTRUCTOR_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_DELAYED_CONSTRUCTOR_H_ + +#include +#include + +namespace firebase { +namespace firestore { +namespace util { + +// DelayedConstructor is a wrapper around an object of type T that +// +// * stores the object of type T inline inside DelayedConstructor; +// * initially does not call T's constructor, leaving storage uninitialized; +// * calls the constructor when you call Init(); +// * provides access to the object of type T like a pointer via ->, *, and +// get(); and +// * calls T's destructor as usual. +// +// This is useful for embedding objects of type T inside Objective-C objects +// when T has no default constructor. +// +// Objective-C separates allocation from initialization which is different from +// the way C++ does it. A C++ object embedded in an Objective-C object is +// normally default constructed then assigned a value later. This doesn't work +// for classes that have no default constructor. +// +// DelayedConstructor does not count or otherwise check that Init is only +// called once. For best results call Init() from the Objective-C class's +// designated initializer. +// +// Note that DelayedConstructor makes no guarantees about the state of the +// storage backing it before Init() is called. However, Objective-C objects are +// zero filled during allocation, so as a member of an Objective-C object, the +// default state will be zero-filled. +// +// Normally this doesn't matter, but DelayedConstructor unconditionally invokes +// T's destructor, even if you don't call Init(). This may cause problems in +// Objective-C classes where the initializer is designed to return an instance +// other than self. It's best to avoid such instance switching techniques in +// combination with DelayedConstructor, but it is possible: either ensure that +// T's destructor handles the zero-filled case correctly, or call Init() before +// switching instances. +template +class DelayedConstructor { + public: + typedef T element_type; + + /** + * Default constructor does nothing. + */ + DelayedConstructor() { + } + + /** + * Forwards arguments to the T's constructor: calls T(args...). + * + * This overload is disabled when it might collide with copy/move. + */ + template ::type...), + void(DelayedConstructor)>::value, + int>::type = 0> + void Init(Ts&&... args) { + new (&space_) T(std::forward(args)...); + } + + /** + * Forwards copy and move construction for T. + */ + void Init(const T& x) { + new (&space_) T(x); + } + void Init(T&& x) { + new (&space_) T(std::move(x)); + } + + // No copying. + DelayedConstructor(const DelayedConstructor&) = delete; + DelayedConstructor& operator=(const DelayedConstructor&) = delete; + + ~DelayedConstructor() { + get()->~T(); + } + + // Pretend to be a smart pointer to T. + T& operator*() { + return *get(); + } + T* operator->() { + return get(); + } + T* get() { + return reinterpret_cast(&space_); + } + const T& operator*() const { + return *get(); + } + const T* operator->() const { + return get(); + } + const T* get() const { + return reinterpret_cast(&space_); + } + + private: + typename std::aligned_storage::type space_; +}; + +} // namespace util +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_DELAYED_CONSTRUCTOR_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/error_apple.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/error_apple.h new file mode 100644 index 0000000..a091840 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/error_apple.h @@ -0,0 +1,73 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_ERROR_APPLE_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_ERROR_APPLE_H_ + +// Everything in this header exists for compatibility with Objective-C. +#if __OBJC__ + +#import + +#import // for FIRFirestoreErrorDomain + +#include "Firestore/core/include/firebase/firestore/firestore_errors.h" +#include "Firestore/core/src/firebase/firestore/util/status.h" +#include "Firestore/core/src/firebase/firestore/util/string_apple.h" +#include "absl/strings/string_view.h" + +namespace firebase { +namespace firestore { +namespace util { + +// Translates a set of error_code and error_msg to an NSError. +inline NSError* MakeNSError(const int64_t error_code, + const absl::string_view error_msg) { + if (error_code == FirestoreErrorCode::Ok) { + return nil; + } + return [NSError + errorWithDomain:FIRFirestoreErrorDomain + code:static_cast(error_code) + userInfo:@{NSLocalizedDescriptionKey : WrapNSString(error_msg)}]; +} + +inline NSError* MakeNSError(const util::Status& status) { + return MakeNSError(status.code(), status.error_message()); +} + +inline Status MakeStatus(NSError* error) { + if (!error) { + return Status::OK(); + } + + HARD_ASSERT(error.domain == FIRFirestoreErrorDomain, + "Can only translate a Firestore error to a status"); + auto error_code = static_cast(error.code); + HARD_ASSERT(error_code >= FirestoreErrorCode::Cancelled && + error_code <= FirestoreErrorCode::Unauthenticated, + "Unknown error code"); + return Status{static_cast(error_code), + MakeString(error.localizedDescription)}; +} + +} // namespace util +} // namespace firestore +} // namespace firebase + +#endif // __OBJC__ + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_ERROR_APPLE_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/executor.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/executor.h new file mode 100644 index 0000000..6299ae7 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/executor.h @@ -0,0 +1,137 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_EXECUTOR_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_EXECUTOR_H_ + +#include // NOLINT(build/c++11) +#include +#include +#include + +#include "absl/types/optional.h" + +namespace firebase { +namespace firestore { +namespace util { + +// A handle to an operation scheduled for future execution. The handle may +// outlive the operation, but it *cannot* outlive the executor that created it. +class DelayedOperation { + public: + // Creates an empty `DelayedOperation` not associated with any actual + // operation. Calling `Cancel` on it is a no-op. + DelayedOperation() { + } + + // Returns whether this `DelayedOperation` is associated with an actual + // operation. + explicit operator bool() const { + return static_cast(cancel_func_); + } + + // If the operation has not been run yet, cancels the operation. Otherwise, + // this function is a no-op. + void Cancel() { + if (cancel_func_) { + cancel_func_(); + cancel_func_ = {}; + } + } + + // Internal use only. + explicit DelayedOperation(std::function&& cancel_func) + : cancel_func_{std::move(cancel_func)} { + } + + private: + std::function cancel_func_; +}; + +// An interface to a platform-specific executor of asynchronous operations +// (called tasks on other platforms). +// +// Operations may be scheduled for immediate or delayed execution. Operations +// delayed until the exact same time are scheduled in FIFO order. +// +// The operations are executed sequentially; only a single operation is executed +// at any given time. +// +// Delayed operations may be canceled if they have not already been run. +class Executor { + public: + using Tag = int; + using Operation = std::function; + using Milliseconds = std::chrono::milliseconds; + + // Operations scheduled for future execution have an opaque tag. The value of + // the tag is ignored by the executor but can be used to find operations with + // a given tag after they are scheduled. + struct TaggedOperation { + TaggedOperation() { + } + TaggedOperation(const Tag tag, Operation&& operation) + : tag{tag}, operation{std::move(operation)} { + } + Tag tag = 0; + Operation operation; + }; + + virtual ~Executor() { + } + + // Schedules the `operation` to be asynchronously executed as soon as + // possible, in FIFO order. + virtual void Execute(Operation&& operation) = 0; + // Like `Execute`, but blocks until the `operation` finishes, consequently + // draining immediate operations from the executor. + virtual void ExecuteBlocking(Operation&& operation) = 0; + // Scheduled the given `operation` to be executed after `delay` milliseconds + // from now, and returns a handle that allows to cancel the operation + // (provided it hasn't been run already). The operation is tagged to allow + // retrieving it later. + // + // `delay` must be non-negative; use `Execute` to schedule operations for + // immediate execution. + virtual DelayedOperation Schedule(Milliseconds delay, + TaggedOperation&& operation) = 0; + + // Checks for the caller whether it is being invoked by this executor. + virtual bool IsCurrentExecutor() const = 0; + // Returns some sort of an identifier for the current execution context. The + // only guarantee is that it will return different values depending on whether + // this function is invoked by this executor or not. + virtual std::string CurrentExecutorName() const = 0; + // Like `CurrentExecutorName`, but returns an identifier for this executor, + // whether the caller code currently runs on this executor or not. + virtual std::string Name() const = 0; + + // Checks whether an operation tagged with the given `tag` is currently + // scheduled for future execution. + virtual bool IsScheduled(Tag tag) const = 0; + // Removes the nearest due scheduled operation from the schedule and returns + // it to the caller. This function may be used to reschedule operations. + // Immediate operations don't count; only operations scheduled for delayed + // execution may be removed. If no such operations are currently scheduled, an + // empty `optional` is returned. + virtual absl::optional PopFromSchedule() = 0; +}; + +} // namespace util +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_EXECUTOR_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/executor_libdispatch.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/executor_libdispatch.h new file mode 100644 index 0000000..459fa4e --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/executor_libdispatch.h @@ -0,0 +1,92 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_EXECUTOR_LIBDISPATCH_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_EXECUTOR_LIBDISPATCH_H_ + +#include // NOLINT(build/c++11) +#include +#include +#include +#include +#include +#include "dispatch/dispatch.h" + +#include "Firestore/core/src/firebase/firestore/util/executor.h" +#include "absl/strings/string_view.h" + +#if !defined(__OBJC__) +// `dispatch_queue_t` gets defined to different types when compiled in C++ or +// Objective-C mode. Source files including this header should all be compiled +// in the same mode to avoid linker errors. +#error "This header only supports Objective-C++ (see comment for more info)." +#endif // !defined(__OBJC__) + +namespace firebase { +namespace firestore { +namespace util { + +namespace internal { + +// Generic wrapper over `dispatch_async_f`, providing `dispatch_async`-like +// interface: accepts an arbitrary invocable object in place of an Objective-C +// block. +void DispatchAsync(dispatch_queue_t queue, std::function&& work); + +// Similar to `DispatchAsync` but wraps `dispatch_sync_f`. +void DispatchSync(dispatch_queue_t queue, std::function work); + +} // namespace internal + +class TimeSlot; + +// A serial queue built on top of libdispatch. The operations are run on +// a dedicated serial dispatch queue. +class ExecutorLibdispatch : public Executor { + public: + explicit ExecutorLibdispatch(dispatch_queue_t dispatch_queue); + ~ExecutorLibdispatch(); + + bool IsCurrentExecutor() const override; + std::string CurrentExecutorName() const override; + std::string Name() const override; + + void Execute(Operation&& operation) override; + void ExecuteBlocking(Operation&& operation) override; + DelayedOperation Schedule(Milliseconds delay, + TaggedOperation&& operation) override; + + void RemoveFromSchedule(const TimeSlot* to_remove); + + bool IsScheduled(Tag tag) const override; + absl::optional PopFromSchedule() override; + + dispatch_queue_t dispatch_queue() const { + return dispatch_queue_; + } + + private: + dispatch_queue_t dispatch_queue_; + // Stores non-owned pointers to `TimeSlot`s. + // Invariant: if a `TimeSlot` is in `schedule_`, it's a valid pointer. + std::vector schedule_; +}; + +} // namespace util +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_EXECUTOR_LIBDISPATCH_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/executor_libdispatch.mm b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/executor_libdispatch.mm new file mode 100644 index 0000000..0b16827 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/executor_libdispatch.mm @@ -0,0 +1,308 @@ +/* + * Copyright 2018 Google + * + * 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 "Firestore/core/src/firebase/firestore/util/executor_libdispatch.h" + +#include + +#include "Firestore/core/src/firebase/firestore/util/hard_assert.h" + +namespace firebase { +namespace firestore { +namespace util { + +namespace { + +absl::string_view StringViewFromDispatchLabel(const char* const label) { + // Make sure string_view's data is not null, because it's used for logging. + return label ? absl::string_view{label} : absl::string_view{""}; +} + +// GetLabel functions are guaranteed to never return a "null" string_view +// (i.e. data() != nullptr). +absl::string_view GetQueueLabel(const dispatch_queue_t queue) { + return StringViewFromDispatchLabel(dispatch_queue_get_label(queue)); +} +absl::string_view GetCurrentQueueLabel() { + // Note: dispatch_queue_get_label may return nullptr if the queue wasn't + // initialized with a label. + return StringViewFromDispatchLabel( + dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL)); +} + +} // namespace + +namespace internal { + +void DispatchAsync(const dispatch_queue_t queue, std::function&& work) { + // Dynamically allocate the function to make sure the object is valid by the + // time libdispatch gets to it. + const auto wrap = new std::function{std::move(work)}; + + dispatch_async_f(queue, wrap, [](void* const raw_work) { + const auto unwrap = static_cast*>(raw_work); + (*unwrap)(); + delete unwrap; + }); +} + +void DispatchSync(const dispatch_queue_t queue, std::function work) { + HARD_ASSERT( + GetCurrentQueueLabel() != GetQueueLabel(queue), + "Calling DispatchSync on the current queue will lead to a deadlock."); + + // Unlike dispatch_async_f, dispatch_sync_f blocks until the work passed to it + // is done, so passing a reference to a local variable is okay. + dispatch_sync_f(queue, &work, [](void* const raw_work) { + const auto unwrap = static_cast*>(raw_work); + (*unwrap)(); + }); +} + +} // namespace internal + +namespace { + +using internal::DispatchAsync; +using internal::DispatchSync; + +template +void RunSynchronized(const ExecutorLibdispatch* const executor, Work&& work) { + if (executor->IsCurrentExecutor()) { + work(); + } else { + DispatchSync(executor->dispatch_queue(), std::forward(work)); + } +} + +} // namespace + +// Represents a "busy" time slot on the schedule. +// +// Since libdispatch doesn't provide a way to cancel a scheduled operation, once +// a slot is created, it will always stay in the schedule until the time is +// past. Consequently, it is more useful to think of a time slot than +// a particular scheduled operation -- by the time the slot comes, operation may +// or may not be there (imagine getting to a meeting and finding out it's been +// canceled). +// +// Precondition: all member functions, including the constructor, are *only* +// invoked on the Firestore queue. +// +// Ownership: +// +// - `TimeSlot` is exclusively owned by libdispatch; +// - `ExecutorLibdispatch` contains non-owning pointers to `TimeSlot`s; +// - invariant: if the executor contains a pointer to a `TimeSlot`, it is +// a valid object. It is achieved because when libdispatch invokes +// a `TimeSlot`, it always removes it from the executor before deleting it. +// The reverse is not true: a canceled time slot is removed from the executor, +// but won't be destroyed until its original due time is past. + +class TimeSlot { + public: + TimeSlot(ExecutorLibdispatch* executor, + Executor::Milliseconds delay, + Executor::TaggedOperation&& operation); + + // Returns the operation that was scheduled for this time slot and turns the + // slot into a no-op. + Executor::TaggedOperation Unschedule(); + + bool operator<(const TimeSlot& rhs) const { + return target_time_ < rhs.target_time_; + } + bool operator==(const Executor::Tag tag) const { + return tagged_.tag == tag; + } + + void MarkDone() { + done_ = true; + } + + static void InvokedByLibdispatch(void* const raw_self); + + private: + void Execute(); + void RemoveFromSchedule(); + + using TimePoint = std::chrono::time_point; + + ExecutorLibdispatch* const executor_; + const TimePoint target_time_; // Used for sorting + Executor::TaggedOperation tagged_; + + // True if the operation has either been run or canceled. + // + // Note on thread-safety: this variable is accessed both from the dispatch + // queue and in the destructor, which may run on any queue. + std::atomic done_; +}; + +TimeSlot::TimeSlot(ExecutorLibdispatch* const executor, + const Executor::Milliseconds delay, + Executor::TaggedOperation&& operation) + : executor_{executor}, + target_time_{std::chrono::time_point_cast( + std::chrono::steady_clock::now()) + + delay}, + tagged_{std::move(operation)} { + // Only assignment of std::atomic is atomic; initialization in its constructor + // isn't + done_ = false; +} + +Executor::TaggedOperation TimeSlot::Unschedule() { + if (!done_) { + RemoveFromSchedule(); + } + return std::move(tagged_); +} + +void TimeSlot::InvokedByLibdispatch(void* const raw_self) { + auto const self = static_cast(raw_self); + self->Execute(); + delete self; +} + +void TimeSlot::Execute() { + if (done_) { + // `done_` might mean that the executor is already destroyed, so don't call + // `RemoveFromSchedule`. + return; + } + + RemoveFromSchedule(); + + HARD_ASSERT(tagged_.operation, + "TimeSlot contains an invalid function object"); + tagged_.operation(); +} + +void TimeSlot::RemoveFromSchedule() { + executor_->RemoveFromSchedule(this); +} + +// ExecutorLibdispatch + +ExecutorLibdispatch::ExecutorLibdispatch(const dispatch_queue_t dispatch_queue) + : dispatch_queue_{dispatch_queue} { +} + +ExecutorLibdispatch::~ExecutorLibdispatch() { + // Turn any operations that might still be in the queue into no-ops, lest + // they try to access `ExecutorLibdispatch` after it gets destroyed. Because + // the queue is serial, by the time libdispatch gets to the newly-enqueued + // work, the pending operations that might have been in progress would have + // already finished. + // Note: this is thread-safe, because the underlying variable `done_` is + // atomic. `RunSynchronized` may result in a deadlock. + for (auto slot : schedule_) { + slot->MarkDone(); + } +} + +bool ExecutorLibdispatch::IsCurrentExecutor() const { + return GetCurrentQueueLabel() == GetQueueLabel(dispatch_queue()); +} +std::string ExecutorLibdispatch::CurrentExecutorName() const { + return GetCurrentQueueLabel().data(); +} +std::string ExecutorLibdispatch::Name() const { + return GetQueueLabel(dispatch_queue()).data(); +} + +void ExecutorLibdispatch::Execute(Operation&& operation) { + DispatchAsync(dispatch_queue(), std::move(operation)); +} +void ExecutorLibdispatch::ExecuteBlocking(Operation&& operation) { + DispatchSync(dispatch_queue(), std::move(operation)); +} + +DelayedOperation ExecutorLibdispatch::Schedule(const Milliseconds delay, + TaggedOperation&& operation) { + namespace chr = std::chrono; + const dispatch_time_t delay_ns = dispatch_time( + DISPATCH_TIME_NOW, chr::duration_cast(delay).count()); + + // Ownership is fully transferred to libdispatch -- because it's impossible + // to truly cancel work after it's been dispatched, libdispatch is + // guaranteed to outlive the executor, and it's possible for work to be + // invoked by libdispatch after the executor is destroyed. Executor only + // stores an observer pointer to the operation. + + auto const time_slot = new TimeSlot{this, delay, std::move(operation)}; + dispatch_after_f(delay_ns, dispatch_queue(), time_slot, + TimeSlot::InvokedByLibdispatch); + RunSynchronized(this, [this, time_slot] { schedule_.push_back(time_slot); }); + return DelayedOperation{[this, time_slot] { + // `time_slot` might be destroyed by the time cancellation function runs. + // Therefore, don't access any methods on `time_slot`, only use it as + // a handle to remove from `schedule_`. + RemoveFromSchedule(time_slot); + }}; +} + +void ExecutorLibdispatch::RemoveFromSchedule(const TimeSlot* const to_remove) { + RunSynchronized(this, [this, to_remove] { + const auto found = std::find_if( + schedule_.begin(), schedule_.end(), + [to_remove](const TimeSlot* op) { return op == to_remove; }); + // It's possible for the operation to be missing if libdispatch gets to run + // it after it was force-run, for example. + if (found != schedule_.end()) { + (*found)->MarkDone(); + schedule_.erase(found); + } + }); +} + +// Test-only methods + +bool ExecutorLibdispatch::IsScheduled(const Tag tag) const { + bool result = false; + RunSynchronized(this, [this, tag, &result] { + result = std::any_of( + schedule_.begin(), schedule_.end(), + [&tag](const TimeSlot* const operation) { return *operation == tag; }); + }); + return result; +} + +absl::optional +ExecutorLibdispatch::PopFromSchedule() { + absl::optional result; + + RunSynchronized(this, [this, &result] { + if (schedule_.empty()) { + return; + } + // Sorting upon each call to `PopFromSchedule` is inefficient, which is + // consciously ignored because this function is only ever called from tests. + std::sort( + schedule_.begin(), schedule_.end(), + [](const TimeSlot* lhs, const TimeSlot* rhs) { return *lhs < *rhs; }); + const auto nearest = schedule_.begin(); + result = (*nearest)->Unschedule(); + }); + + return result; +} + +} // namespace util +} // namespace firestore +} // namespace firebase diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/executor_std.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/executor_std.cc new file mode 100644 index 0000000..bfc47fe --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/executor_std.cc @@ -0,0 +1,152 @@ +/* + * Copyright 2018 Google + * + * 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 "Firestore/core/src/firebase/firestore/util/executor_std.h" + +#include // NOLINT(build/c++11) +#include + +namespace firebase { +namespace firestore { +namespace util { + +namespace { + +// The only guarantee is that different `thread_id`s will produce different +// values. +std::string ThreadIdToString(const std::thread::id thread_id) { + std::ostringstream stream; + stream << thread_id; + return stream.str(); +} + +} // namespace + +ExecutorStd::ExecutorStd() { + // Somewhat counter-intuitively, constructor of `std::atomic` assigns the + // value non-atomically, so the atomic initialization must be provided here, + // before the worker thread is started. + // See [this thread](https://stackoverflow.com/questions/25609858) for context + // on the constructor. + current_id_ = 0; + shutting_down_ = false; + worker_thread_ = std::thread{&ExecutorStd::PollingThread, this}; +} + +ExecutorStd::~ExecutorStd() { + shutting_down_ = true; + // Make sure the worker thread is not blocked, so that the call to `join` + // doesn't hang. + UnblockQueue(); + worker_thread_.join(); +} + +void ExecutorStd::Execute(Operation&& operation) { + PushOnSchedule(std::move(operation), Immediate()); +} + +DelayedOperation ExecutorStd::Schedule(const Milliseconds delay, + TaggedOperation&& tagged) { + // While negative delay can be interpreted as a request for immediate + // execution, supporting it would provide a hacky way to modify FIFO ordering + // of immediate operations. + HARD_ASSERT(delay.count() >= 0, "Schedule: delay cannot be negative"); + + namespace chr = std::chrono; + const auto now = chr::time_point_cast(chr::steady_clock::now()); + const auto id = + PushOnSchedule(std::move(tagged.operation), now + delay, tagged.tag); + + return DelayedOperation{[this, id] { TryCancel(id); }}; +} + +void ExecutorStd::TryCancel(const Id operation_id) { + schedule_.RemoveIf( + [operation_id](const Entry& e) { return e.id == operation_id; }); +} + +ExecutorStd::Id ExecutorStd::PushOnSchedule(Operation&& operation, + const TimePoint when, + const Tag tag) { + // Note: operations scheduled for immediate execution don't actually need an + // id. This could be tweaked to reuse the same id for all such operations. + const auto id = NextId(); + schedule_.Push(Entry{std::move(operation), id, tag}, when); + return id; +} + +void ExecutorStd::PollingThread() { + while (!shutting_down_) { + Entry entry = schedule_.PopBlocking(); + if (entry.tagged.operation) { + entry.tagged.operation(); + } + } +} + +void ExecutorStd::UnblockQueue() { + // Put a no-op for immediate execution on the queue to ensure that + // `schedule_.PopBlocking` returns, and worker thread can notice that shutdown + // is in progress. + schedule_.Push(Entry{[] {}, /*id=*/0}, Immediate()); +} + +ExecutorStd::Id ExecutorStd::NextId() { + // The wrap around after ~4 billion operations is explicitly ignored. Even if + // an instance of `ExecutorStd` runs long enough to get `current_id_` to + // overflow, it's extremely unlikely that any object still holds a reference + // that is old enough to cause a conflict. + return current_id_++; +} + +bool ExecutorStd::IsCurrentExecutor() const { + return std::this_thread::get_id() == worker_thread_.get_id(); +} + +std::string ExecutorStd::CurrentExecutorName() const { + return ThreadIdToString(std::this_thread::get_id()); +} + +std::string ExecutorStd::Name() const { + return ThreadIdToString(worker_thread_.get_id()); +} + +void ExecutorStd::ExecuteBlocking(Operation&& operation) { + std::promise signal_finished; + Execute([&] { + operation(); + signal_finished.set_value(); + }); + signal_finished.get_future().wait(); +} + +bool ExecutorStd::IsScheduled(const Tag tag) const { + return schedule_.Contains( + [&tag](const Entry& e) { return e.tagged.tag == tag; }); +} + +absl::optional ExecutorStd::PopFromSchedule() { + auto removed = + schedule_.RemoveIf([](const Entry& e) { return !e.IsImmediate(); }); + if (!removed.has_value()) { + return {}; + } + return {std::move(removed.value().tagged)}; +} + +} // namespace util +} // namespace firestore +} // namespace firebase diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/executor_std.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/executor_std.h new file mode 100644 index 0000000..2550036 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/executor_std.h @@ -0,0 +1,279 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_EXECUTOR_STD_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_EXECUTOR_STD_H_ + +#include +#include +#include // NOLINT(build/c++11) +#include +#include // NOLINT(build/c++11) +#include +#include // NOLINT(build/c++11) +#include + +#include "Firestore/core/src/firebase/firestore/util/executor.h" +#include "Firestore/core/src/firebase/firestore/util/hard_assert.h" +#include "absl/types/optional.h" + +namespace firebase { +namespace firestore { +namespace util { + +namespace async { + +// A thread-safe class similar to a priority queue where the entries are +// prioritized by the time for which they're scheduled. Entries scheduled for +// the exact same time are prioritized in FIFO order. +// +// The main function of `Schedule` is `PopBlocking`, which sleeps until an entry +// becomes available. It correctly handles entries being asynchronously added or +// removed from the schedule. +// +// The details of time management are completely concealed within the class. +// Once an entry is scheduled, there is no way to reschedule or even retrieve +// the time. +template +class Schedule { + // Internal invariants: + // - entries are always in sorted order, leftmost entry is always the most + // due; + // - each operation modifying the queue notifies the condition variable `cv_`. + public: + using Duration = std::chrono::milliseconds; + using Clock = std::chrono::steady_clock; + // Entries are scheduled using absolute time. + using TimePoint = std::chrono::time_point; + + // Schedules an entry for the specified time due. `due` may be in the past. + void Push(const T& value, const TimePoint due) { + InsertPreservingOrder(Entry{value, due}); + } + void Push(T&& value, const TimePoint due) { + InsertPreservingOrder(Entry{std::move(value), due}); + } + + // If the queue contains at least one entry for which the scheduled time is + // due now (according to the system clock), removes the entry which is the + // most overdue from the queue and returns it. If no entry is due, returns an + // empty `optional`. + absl::optional PopIfDue() { + std::lock_guard lock{mutex_}; + + if (HasDueLocked()) { + return ExtractLocked(scheduled_.begin()); + } + return {}; + } + + // Blocks until at least one entry is available for which the scheduled time + // is due now (according to the system clock), removes the entry which is the + // most overdue from the queue and returns it. The function will + // attempt to minimize both the waiting time and busy waiting. + T PopBlocking() { + std::unique_lock lock{mutex_}; + + while (true) { + cv_.wait(lock, [this] { return !scheduled_.empty(); }); + + // To minimize busy waiting, sleep until either the nearest entry in the + // future either changes, or else becomes due. + const auto until = scheduled_.front().due; + cv_.wait_until(lock, until, [this, until] { + return scheduled_.empty() || scheduled_.front().due != until; + }); + // There are 3 possibilities why `wait_until` has returned: + // - `wait_until` has timed out, in which case the current time is at + // least `until`, so there must be an overdue entry; + // - a new entry has been added which comes before `until`. It must be + // either overdue (in which case `HasDueLocked` will break the cycle), + // or else `until` must be reevaluated (on the next iteration of the + // loop); + // - `until` entry has been removed (including the case where the queue + // has become empty). This means `until` has to be reevaluated, similar + // to #2. + + if (HasDueLocked()) { + return ExtractLocked(scheduled_.begin()); + } + } + } + + bool empty() const { + std::lock_guard lock{mutex_}; + return scheduled_.empty(); + } + + size_t size() const { + std::lock_guard lock{mutex_}; + return scheduled_.size(); + } + + // Removes the first entry satisfying predicate from the queue and returns it. + // If no such entry exists, returns an empty `optional`. Predicate is applied + // to entries in order according to their scheduled time. + // + // Note that this function doesn't take into account whether the removed entry + // is past its due time. + template + absl::optional RemoveIf(const Pred pred) { + std::lock_guard lock{mutex_}; + + for (auto iter = scheduled_.begin(), end = scheduled_.end(); iter != end; + ++iter) { + if (pred(iter->value)) { + return ExtractLocked(iter); + } + } + return {}; + } + + // Checks whether the queue contains an entry satisfying the given predicate. + template + bool Contains(const Pred pred) const { + std::lock_guard lock{mutex_}; + return std::any_of(scheduled_.begin(), scheduled_.end(), + [&pred](const Entry& s) { return pred(s.value); }); + } + + private: + struct Entry { + bool operator<(const Entry& rhs) const { + return due < rhs.due; + } + + T value; + TimePoint due; + }; + // All removals are on the front, but most insertions are expected to be on + // the back. + using Container = std::deque; + using Iterator = typename Container::iterator; + + void InsertPreservingOrder(Entry&& new_entry) { + std::lock_guard lock{mutex_}; + + const auto insertion_point = + std::upper_bound(scheduled_.begin(), scheduled_.end(), new_entry); + scheduled_.insert(insertion_point, std::move(new_entry)); + + cv_.notify_one(); + } + + // This function expects the mutex to be already locked. + bool HasDueLocked() const { + namespace chr = std::chrono; + const auto now = chr::time_point_cast(Clock::now()); + return !scheduled_.empty() && now >= scheduled_.front().due; + } + + // This function expects the mutex to be already locked. + T ExtractLocked(const Iterator where) { + HARD_ASSERT(!scheduled_.empty(), + "Trying to pop an entry from an empty queue."); + + T result = std::move(where->value); + scheduled_.erase(where); + cv_.notify_one(); + + return result; + } + + mutable std::mutex mutex_; + std::condition_variable cv_; + Container scheduled_; +}; + +} // namespace async + +// A serial queue that executes provided operations on a dedicated background +// thread, using C++11 standard library functionality. +class ExecutorStd : public Executor { + public: + ExecutorStd(); + ~ExecutorStd(); + + void Execute(Operation&& operation) override; + void ExecuteBlocking(Operation&& operation) override; + + DelayedOperation Schedule(Milliseconds delay, + TaggedOperation&& tagged) override; + + bool IsCurrentExecutor() const override; + std::string CurrentExecutorName() const override; + std::string Name() const override; + + bool IsScheduled(Tag tag) const override; + absl::optional PopFromSchedule() override; + + using TimePoint = async::Schedule::TimePoint; + // To allow canceling operations, each scheduled operation is assigned + // a monotonically increasing identifier. + using Id = unsigned int; + + // If the operation hasn't yet been run, it will be removed from the queue. + // Otherwise, this function is a no-op. + void TryCancel(Id operation_id); + + Id PushOnSchedule(Operation&& operation, TimePoint when, Tag tag = -1); + + void PollingThread(); + void UnblockQueue(); + Id NextId(); + + // As a convention, assign the epoch time to all operations scheduled for + // immediate execution. Note that it means that an immediate operation is + // always scheduled before any delayed operation, even in the corner case when + // the immediate operation was scheduled after a delayed operation was due + // (but hasn't yet run). + static TimePoint Immediate() { + return TimePoint{}; + } + + struct Entry { + Entry() { + } + Entry(Operation&& operation, + const ExecutorStd::Id id, + const ExecutorStd::Tag tag = kNoTag) + : tagged{tag, std::move(operation)}, id{id} { + } + + bool IsImmediate() const { + return tagged.tag == kNoTag; + } + + static constexpr Tag kNoTag = -1; + TaggedOperation tagged; + Id id = 0; + }; + // Operations scheduled for immediate execution are also put on the schedule + // (with due time set to `Immediate`). + async::Schedule schedule_; + + std::thread worker_thread_; + // Used to stop the worker thread. + std::atomic shutting_down_{false}; + + std::atomic current_id_{0}; +}; + +} // namespace util +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_EXECUTOR_STD_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/filesystem.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/filesystem.h new file mode 100644 index 0000000..532c954 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/filesystem.h @@ -0,0 +1,147 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_FILESYSTEM_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_FILESYSTEM_H_ + +#include +#include + +#include "Firestore/core/src/firebase/firestore/util/path.h" +#include "Firestore/core/src/firebase/firestore/util/status.h" +#include "Firestore/core/src/firebase/firestore/util/statusor.h" + +namespace firebase { +namespace firestore { +namespace util { + +// High-level routines for the manipulating the filesystem. All filesystems +// are required to implement these routines. + +/** + * Answers the question "is this path a directory? The path is not required to + * have a trailing slash. + * + * Typical return codes include: + * * Ok - The path exists and is a directory. + * * FailedPrecondition - Some component of the path is not a directory. This + * does not necessarily imply that the path exists and is a file. + * * NotFound - The path does not exist + * * PermissionDenied - Insufficient permissions to access the path. + */ +Status IsDirectory(const Path& path); + +/** + * Recursively creates all the directories in the path name if they don't + * exist. + * + * @return Ok if the directory was created or already existed. + */ +Status RecursivelyCreateDir(const Path& path); + +/** + * Recursively deletes the contents of the given pathname. If the pathname is + * a file, deletes just that file. The the pathname is a directory, deletes + * everything within the directory. + * + * @return Ok if the directory was deleted or did not exist. + */ +Status RecursivelyDelete(const Path& path); + +/** + * Returns system-defined best directory in which to create temporary files. + * Typical return values are like `/tmp` on UNIX systems. Clients should create + * randomly named directories or files within this location to avoid collisions. + * Absent any changes that might affect the underlying calls, the value returned + * from TempDir will be stable over time. + * + * Note: the returned path is just where the system thinks temporary files + * should be stored, but TempDir does not actually guarantee that this path + * exists. + */ +Path TempDir(); + +/** + * On success, returns the size in bytes of the file specified by + * `path`. + */ +StatusOr FileSize(const Path& path); + +/** + * On success, opens the file at the given `path` and returns its contents as + * a string. + */ +StatusOr ReadFile(const Path& path); + +/** + * Implements an iterator over the contents of a directory. Initializes to the + * first entry in the directory. + */ +class DirectoryIterator { + public: + /** + * Creates a new platform-specific directory iterator. + * + * @param path The path over which to iterate (must outlive the + * DirectoryIterator). + */ + static std::unique_ptr Create(const Path& path); + + virtual ~DirectoryIterator() { + } + + /** + * Advances the iterator. + */ + virtual void Next() = 0; + + /** + * Returns true if `Next()` and `file()` can be called on the iterator. + * If `Valid() == false && status().ok()`, then iteration has finished. + */ + virtual bool Valid() const = 0; + + /** + * Return the full path of the current entry pointed to by the iterator. + */ + virtual Path file() const = 0; + + /** + * Returns the last error encountered by the iterator, or OK. + */ + Status status() const { + return status_; + } + + protected: + /** + * `path` should outlive the iterator. + */ + explicit DirectoryIterator(const Path& path) : parent_{path} { + } + + DirectoryIterator(const DirectoryIterator& other) = delete; + DirectoryIterator& operator=(const DirectoryIterator& other) = delete; + + Status status_; + const Path& parent_; +}; + +} // namespace util +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_FILESYSTEM_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/filesystem_apple.mm b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/filesystem_apple.mm new file mode 100644 index 0000000..07c755e --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/filesystem_apple.mm @@ -0,0 +1,45 @@ +/* + * Copyright 2018 Google + * + * 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 "Firestore/core/src/firebase/firestore/util/filesystem.h" + +#if defined(__APPLE__) + +#import + +namespace firebase { +namespace firestore { +namespace util { + +Path TempDir() { + const char* env_tmpdir = getenv("TMPDIR"); + if (env_tmpdir) { + return Path::FromUtf8(env_tmpdir); + } + + NSString* ns_tmpdir = NSTemporaryDirectory(); + if (ns_tmpdir) { + return Path::FromNSString(ns_tmpdir); + } + + return Path::FromUtf8("/tmp"); +} + +} // namespace util +} // namespace firestore +} // namespace firebase + +#endif // defined(__APPLE__) diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/filesystem_common.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/filesystem_common.cc new file mode 100644 index 0000000..656eaf2 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/filesystem_common.cc @@ -0,0 +1,106 @@ +/* + * Copyright 2018 Google + * + * 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 "Firestore/core/src/firebase/firestore/util/filesystem_detail.h" + +#include +#include + +#include "Firestore/core/src/firebase/firestore/util/filesystem.h" +#include "Firestore/core/src/firebase/firestore/util/string_format.h" + +using firebase::firestore::util::Path; + +namespace firebase { +namespace firestore { +namespace util { +namespace detail { + +Status RecursivelyDeleteDir(const Path& parent) { + std::unique_ptr iter = DirectoryIterator::Create(parent); + for (; iter->Valid(); iter->Next()) { + Status status = RecursivelyDelete(iter->file()); + if (!status.ok()) { + return status; + } + } + if (!iter->status().ok()) { + if (iter->status().code() == FirestoreErrorCode::NotFound) { + return Status::OK(); + } + return iter->status(); + } + return detail::DeleteDir(parent); +} + +} // namespace detail + +Status RecursivelyCreateDir(const Path& path) { + Status result = detail::CreateDir(path); + if (result.ok() || result.code() != FirestoreErrorCode::NotFound) { + // Successfully created the directory, it already existed, or some other + // unrecoverable error. + return result; + } + + // Missing parent + Path parent = path.Dirname(); + result = RecursivelyCreateDir(parent); + if (!result.ok()) { + return result; + } + + // Successfully created the parent so try again. + return detail::CreateDir(path); +} + +Status RecursivelyDelete(const Path& path) { + Status status = IsDirectory(path); + switch (status.code()) { + case FirestoreErrorCode::Ok: + return detail::RecursivelyDeleteDir(path); + + case FirestoreErrorCode::FailedPrecondition: + // Could be a file or something else. Attempt to delete it as a file + // but otherwise allow that to fail if it's not a file. + return detail::DeleteFile(path); + + case FirestoreErrorCode::NotFound: + return Status::OK(); + + default: + return status; + } +} + +StatusOr ReadFile(const Path& path) { + std::ifstream file{path.native_value()}; + if (!file) { + // TODO(varconst): more error details. This will require platform-specific + // code, because `` may not update `errno`. + return Status{FirestoreErrorCode::Unknown, + StringFormat("File at path '%s' cannot be opened", + path.ToUtf8String())}; + } + + std::stringstream buffer; + buffer << file.rdbuf(); + return buffer.str(); +} + +} // namespace util +} // namespace firestore +} // namespace firebase diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/filesystem_detail.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/filesystem_detail.h new file mode 100644 index 0000000..f2b344d --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/filesystem_detail.h @@ -0,0 +1,72 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_FILESYSTEM_DETAIL_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_FILESYSTEM_DETAIL_H_ + +#include "Firestore/core/src/firebase/firestore/util/path.h" +#include "Firestore/core/src/firebase/firestore/util/status.h" + +namespace firebase { +namespace firestore { +namespace util { +namespace detail { + +// Additional routines for filesystem implementations that are not based on +// high-level mechanisms like NSFileManager. + +/** + * Creates the given directory. The immediate parent directory must already + * exist and not already be a file. + * + * @return Ok if the directory was created or already existed. On some systems + * this may also return Ok if a regular file exists at the given path. + */ +Status CreateDir(const Path& path); + +/** + * Deletes the given directory if it exists. + * + * @return Ok if the directory was deleted or did not exist. Returns a + * system-defined error if the path is not a directory or the directory is + * non-empty. + */ +Status DeleteDir(const Path& path); + +/** + * Deletes the given file if it exists. + * + * @return Ok if the file was deleted or did not exist. Returns a system-defined + * error if the path exists but is not a regular file. + */ +Status DeleteFile(const Path& path); + +/** + * Recursively deletes the contents of the given pathname that is known to be + * a directory. + * + * @return Ok if the directory was deleted or did not exist. Returns a + * system-defined error if the path exists but is not a directory. + * + */ +Status RecursivelyDeleteDir(const Path& path); + +} // namespace detail +} // namespace util +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_FILESYSTEM_DETAIL_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/filesystem_posix.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/filesystem_posix.cc new file mode 100644 index 0000000..650b821 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/filesystem_posix.cc @@ -0,0 +1,224 @@ +/* + * Copyright 2018 Google + * + * 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 "Firestore/core/src/firebase/firestore/util/filesystem.h" + +#include +#include +#include +#include + +#include +#include +#include + +#include "Firestore/core/src/firebase/firestore/util/filesystem_detail.h" +#include "Firestore/core/src/firebase/firestore/util/path.h" +#include "Firestore/core/src/firebase/firestore/util/string_format.h" +#include "absl/memory/memory.h" + +namespace firebase { +namespace firestore { +namespace util { + +Status IsDirectory(const Path& path) { + struct stat buffer {}; + if (::stat(path.c_str(), &buffer)) { + if (errno == ENOENT) { + // Expected common error case. + return Status{FirestoreErrorCode::NotFound, path.ToUtf8String()}; + + } else if (errno == ENOTDIR) { + // This is a case where POSIX and Windows differ in behavior in a way + // that's hard to reconcile from Windows. Under POSIX, ENOTDIR indicates + // that not only does the path not exist, but that some parent of the + // path also isn't a directory. + // + // Windows, OTOH, returns ERROR_FILE_NOT_FOUND if the file doesn't exist, + // its immediate parent exists, and the parent is a directory. Otherwise + // Windows returns ERROR_PATH_NOT_FOUND. To emulate POSIX behavior you + // have to find the leaf-most existing parent and figure out if it's not a + // directory. + // + // Since we really don't care about this distinction it's easier to + // resolve this by returning NotFound here. + return Status{FirestoreErrorCode::NotFound, path.ToUtf8String()}; + } else { + return Status::FromErrno(errno, path.ToUtf8String()); + } + } + + if (!S_ISDIR(buffer.st_mode)) { + return Status{FirestoreErrorCode::FailedPrecondition, + StringFormat("Path %s exists but is not a directory", + path.ToUtf8String())}; + } + + return Status::OK(); +} + +#if !defined(__APPLE__) +// See filesystem_apple.mm for an alternative implementation. +Path TempDir() { + const char* env_tmpdir = getenv("TMPDIR"); + if (env_tmpdir) { + return Path::FromUtf8(env_tmpdir); + } + +#if defined(__ANDROID__) + // The /tmp directory doesn't exist as a fallback; each application is + // supposed to keep its own temporary files. Previously /data/local/tmp may + // have been reasonable, but current lore points to this being unreliable for + // writing at higher API levels or certain phone models because default + // permissions on this directory no longer permit writing. + // + // TODO(wilhuff): Validate on recent Android. +#error "Not yet sure about temporary file locations on Android." + return Path::FromUtf8("/data/local/tmp"); + +#else + return Path::FromUtf8("/tmp"); +#endif // defined(__ANDROID__) +} +#endif // !defined(__APPLE__) + +StatusOr FileSize(const Path& path) { + struct stat st {}; + if (stat(path.c_str(), &st) == 0) { + return st.st_size; + } else { + return Status::FromErrno( + errno, StringFormat("Failed to stat file: %s", path.ToUtf8String())); + } +} + +namespace detail { + +Status CreateDir(const Path& path) { + if (::mkdir(path.c_str(), 0777)) { + if (errno != EEXIST) { + return Status::FromErrno( + errno, + StringFormat("Could not create directory %s", path.ToUtf8String())); + } + } + + return Status::OK(); +} + +Status DeleteDir(const Path& path) { + if (::rmdir(path.c_str())) { + if (errno != ENOENT) { + return Status::FromErrno( + errno, + StringFormat("Could not delete directory %s", path.ToUtf8String())); + } + } + return Status::OK(); +} + +Status DeleteFile(const Path& path) { + if (::unlink(path.c_str())) { + if (errno != ENOENT) { + return Status::FromErrno( + errno, StringFormat("Could not delete file %s", path.ToUtf8String())); + } + } + return Status::OK(); +} + +} // namespace detail + +namespace { + +class DirectoryIteratorPosix : public DirectoryIterator { + public: + explicit DirectoryIteratorPosix(const util::Path& path); + virtual ~DirectoryIteratorPosix(); + + void Next() override; + bool Valid() const override; + Path file() const override; + + private: + void Advance(); + + DIR* dir_ = nullptr; + struct dirent* entry_ = nullptr; +}; + +DirectoryIteratorPosix::DirectoryIteratorPosix(const util::Path& path) + : DirectoryIterator{path} { + dir_ = ::opendir(parent_.c_str()); + if (!dir_) { + status_ = Status::FromErrno( + errno, + StringFormat("Could not open directory %s", parent_.ToUtf8String())); + return; + } + Advance(); +} + +DirectoryIteratorPosix::~DirectoryIteratorPosix() { + if (dir_) { + if (::closedir(dir_) != 0) { + HARD_FAIL("Could not close directory %s", parent_.ToUtf8String()); + } + } +} + +void DirectoryIteratorPosix::Advance() { + HARD_ASSERT(status_.ok(), "Advancing an errored iterator"); + errno = 0; + entry_ = ::readdir(dir_); + if (!entry_) { + if (errno != 0) { + status_ = Status::FromErrno( + errno, StringFormat("Could not read %s", parent_.ToUtf8String())); + } + } else if (status_.ok()) { + // Skip self- and parent-pointer + if (::strcmp(".", entry_->d_name) == 0 || + ::strcmp("..", entry_->d_name) == 0) { + Advance(); + } + } +} + +void DirectoryIteratorPosix::Next() { + HARD_ASSERT(Valid(), "Next() called on invalid iterator"); + Advance(); +} + +bool DirectoryIteratorPosix::Valid() const { + return status_.ok() && entry_ != nullptr; +} + +Path DirectoryIteratorPosix::file() const { + HARD_ASSERT(Valid(), "file() called on invalid iterator"); + return parent_.AppendUtf8(entry_->d_name, strlen(entry_->d_name)); +} + +} // namespace + +std::unique_ptr DirectoryIterator::Create( + const util::Path& path) { + return absl::make_unique(path); +} + +} // namespace util +} // namespace firestore +} // namespace firebase diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/hard_assert.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/hard_assert.h new file mode 100644 index 0000000..6cea147 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/hard_assert.h @@ -0,0 +1,124 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_HARD_ASSERT_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_HARD_ASSERT_H_ + +#include +#include + +#include "Firestore/core/src/firebase/firestore/util/string_format.h" + +#if defined(_MSC_VER) +#define FIRESTORE_FUNCTION_NAME __FUNCSIG__ +#else +#define FIRESTORE_FUNCTION_NAME __PRETTY_FUNCTION__ +#endif + +/** + * Fails the current function if the given condition is false. + * + * Unlike assert(3) or NSAssert, this macro is never compiled out. + * + * @param condition The condition to test. + * @param format (optional) A format string suitable for util::StringFormat. + * @param ... format arguments to pass to util::StringFormat. + */ +#define HARD_ASSERT(condition, ...) \ + do { \ + if (!(condition)) { \ + std::string _message = \ + firebase::firestore::util::StringFormat(__VA_ARGS__); \ + firebase::firestore::util::internal::Fail( \ + __FILE__, FIRESTORE_FUNCTION_NAME, __LINE__, _message, #condition); \ + } \ + } while (0) + +/** + * Unconditionally fails the current function. + * + * Unlike assert(3) or NSAssert, this macro is never compiled out. + * + * @param format A format string suitable for util::StringFormat. + * @param ... format arguments to pass to util::StringFormat. + */ +#define HARD_FAIL(...) \ + do { \ + std::string _failure = \ + firebase::firestore::util::StringFormat(__VA_ARGS__); \ + firebase::firestore::util::internal::Fail( \ + __FILE__, FIRESTORE_FUNCTION_NAME, __LINE__, _failure); \ + } while (0) + +/** + * Indicates an area of the code that cannot be reached (except possibly due to + * undefined behaviour or other similar badness). The only reasonable thing to + * do in these cases is to immediately abort. + */ +#define UNREACHABLE() abort() + +/** + * Returns the given `ptr` if it is non-null; otherwise, results in a failed + * assertion, similar to `HARD_ASSERT`. This macro deliberately expands to an + * expression, so that it can be used in initialization and assignment: + * + * my_ptr_ = NOT_NULL(suspicious_ptr); + * my_smart_ptr_ = std::move(NOT_NULL(suspicious_smart_ptr)); + * + * MyClass() : my_ptr_{NOT_NULL(suspicious_ptr)} {} + * + * @param ptr The pointer to check and return. Can be a smart pointer. + */ +#define NOT_NULL(ptr) \ + firebase::firestore::util::internal::NotNull( \ + __FILE__, FIRESTORE_FUNCTION_NAME, __LINE__, "Expected non-null " #ptr, \ + ptr) + +namespace firebase { +namespace firestore { +namespace util { +namespace internal { + +// A no-return helper function. To raise an assertion, use Macro instead. +ABSL_ATTRIBUTE_NORETURN void Fail(const char* file, + const char* func, + int line, + const std::string& message); + +ABSL_ATTRIBUTE_NORETURN void Fail(const char* file, + const char* func, + int line, + const std::string& message, + const char* condition); + +template +T NotNull(const char* file, + const char* func, + int line, + const std::string& message, + T&& ptr) { + if (ptr == nullptr) { + Fail(file, func, line, message); + } + return std::forward(ptr); +} + +} // namespace internal +} // namespace util +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_HARD_ASSERT_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/hard_assert_apple.mm b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/hard_assert_apple.mm new file mode 100644 index 0000000..6abd324 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/hard_assert_apple.mm @@ -0,0 +1,60 @@ +/* + * Copyright 2018 Google + * + * 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 "Firestore/core/src/firebase/firestore/util/hard_assert.h" + +#import + +#include + +#include "Firestore/core/src/firebase/firestore/util/string_apple.h" + +namespace firebase { +namespace firestore { +namespace util { +namespace internal { + +void Fail(const char* file, + const char* func, + const int line, + const std::string& message) { + [[NSAssertionHandler currentHandler] + handleFailureInFunction:WrapNSString(func) + file:WrapNSString(file) + lineNumber:line + description:@"FIRESTORE INTERNAL ASSERTION FAILED: %s", + message.c_str()]; + abort(); +} + +void Fail(const char* file, + const char* func, + const int line, + const std::string& message, + const char* condition) { + std::string failure; + if (message.empty()) { + failure = condition; + } else { + failure = StringFormat("%s (expected %s)", message, condition); + } + Fail(file, func, line, failure); +} + +} // namespace internal +} // namespace util +} // namespace firestore +} // namespace firebase diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/hashing.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/hashing.h new file mode 100644 index 0000000..4d8462a --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/hashing.h @@ -0,0 +1,210 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_HASHING_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_HASHING_H_ + +#include +#include +#include +#include + +#include "Firestore/core/src/firebase/firestore/util/type_traits.h" +#include "absl/meta/type_traits.h" + +namespace firebase { +namespace firestore { +namespace util { + +// This is a pretty terrible hash implementation for lack of a better one being +// readily available. It exists as a portability crutch between our existing +// Objective-C code where overriding `-isEqual:` also requires `-hash` and C++ +// where `operator==()` can be defined without defining a hash code. +// +// It's based on the recommendation in Effective Java, Item 9, wherein you +// implement composite hashes like so: +// +// size_t result = first_; +// result = 31 * result + second_; +// result = 31 * result + third_; +// // ... +// return result; +// +// This is the basis of this implementation because that's what the existing +// Objective-C code mostly does by hand. Using this implementation gets the +// same result by calling +// +// return util::Hash(first_, second_, /* ..., */ third_); +// +// TODO(wilhuff): Replace this with whatever Abseil releases. + +namespace impl { + +/** + * A type trait that identifies whether or not std::hash is available for a + * given type. + * + * This type should not be necessary since specialization failure on an + * expression like `decltype(std::hash{}(value)` should be enough to disable + * overloads that require `std::hash` to be defined but unfortunately some + * standard libraries ship with std::hash defined for all types that only + * fail later (e.g. via static_assert). One such implementation is the libc++ + * that ships with Xcode 8.3.3, which is a supported platform. + */ +template +struct has_std_hash { + // There may be other types for which std::hash is defined but they don't + // matter for our purposes. + enum { + value = std::is_arithmetic{} || std::is_pointer{} || + std::is_same{} + }; + + constexpr operator bool() const { + return value; + } +}; + +/** + * A type that's equivalent to size_t if std::hash is defined or a compile + * error otherwise. + * + * This is effectively just a safe implementation of + * `decltype(std::hash{}(std::declval()))`. + */ +template +using std_hash_type = + typename absl::enable_if_t::value, size_t>; + +/** + * Combines a hash_value with whatever accumulated state there is so far. + */ +inline size_t Combine(size_t state, size_t hash_value) { + return 31 * state + hash_value; +} + +/** + * Explicit ordering of hashers, allowing SFINAE without all the enable_if + * cruft. + * + * In order we try: + * * A Hash() member, if defined and the return type is an integral type + * * A `-hash` method, if dealing with an Objective-C class + * * A std::hash specialization, if available + * * A range-based specialization, valid if either of the above hold on the + * members of the range. + * + * Explicit ordering resolves the ambiguity of the case where a std::hash + * specialization is available, but the type is also a range for whose members + * std::hash is also available, e.g. with std::string. + * + * HashChoice is a recursive type, defined such that HashChoice<0> is the most + * specific type with HashChoice<1> and beyond being progressively less + * specific. This causes the compiler to prioritize the overloads with + * lower-numbered HashChoice types, allowing compilation to succeed even if + * multiple specializations match. + */ +template +struct HashChoice : HashChoice {}; + +template <> +struct HashChoice<3> {}; + +template +size_t InvokeHash(const K& value); + +/** + * Hashes the given value if it defines a Hash() member. + * + * @return The result of `value.Hash()`. + */ +template +auto RankedInvokeHash(const K& value, HashChoice<0>) -> decltype(value.Hash()) { + return value.Hash(); +} + +#if __OBJC__ + +/** + * Hashes the given value if it's of an Objective-C class (and thus defines + * `-hash`. + * + * @return The result of `[value hash]`, converted to `size_t`. + */ +template ::value>> +size_t RankedInvokeHash(const K& value, HashChoice<1>) { + return static_cast([value hash]); +} + +#endif + +/** + * Hashes the given value if it has a specialization of std::hash. + * + * @return The result of `std::hash{}(value)` + */ +template +std_hash_type RankedInvokeHash(const K& value, HashChoice<2>) { + return std::hash{}(value); +} + +/** + * Hashes the contents of the given range of values if the value_type of the + * range can be hashed. + */ +template +auto RankedInvokeHash(const Range& range, HashChoice<3>) + -> decltype(impl::InvokeHash(*std::begin(range))) { + size_t result = 0; + size_t size = 0; + for (auto&& element : range) { + ++size; + size_t piece = InvokeHash(element); + result = Combine(result, piece); + } + size_t size_hash = InvokeHash(size); + result = Combine(result, size_hash); + return result; +} + +template +size_t InvokeHash(const K& value) { + return RankedInvokeHash(value, HashChoice<0>{}); +} + +inline size_t HashInternal(size_t state) { + return state; +} + +template +size_t HashInternal(size_t state, const T& value, const Ts&... rest) { + state = Combine(state, InvokeHash(value)); + return HashInternal(state, rest...); +} + +} // namespace impl + +template +size_t Hash(const Ts&... values) { + return impl::HashInternal(0u, values...); +} + +} // namespace util +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_HASHING_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/iterator_adaptors.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/iterator_adaptors.h new file mode 100644 index 0000000..042fd72 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/iterator_adaptors.h @@ -0,0 +1,812 @@ +/* + * Copyright 2005, 2018 Google + * + * 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. + */ + +// Provides some iterator adaptors and views. + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_ITERATOR_ADAPTORS_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_ITERATOR_ADAPTORS_H_ + +#include +#include +#include + +#include "absl/base/port.h" +#include "absl/meta/type_traits.h" + +namespace firebase { +namespace firestore { +namespace util { + +namespace internal { + +// value == true if Iter prohibits modification of its pointees. +template +struct IsConstIter + : std::is_const::reference>::type> {}; + +template +struct AddConstIf : std::conditional {}; + +// SynthIterTraits propagates the constness of the 'BaseIter' iterator +// type to its own exported 'pointer' and 'reference' typedefs. +template +struct SynthIterTraits : std::iterator_traits { + private: + static constexpr bool kIterConst = IsConstIter::value; + + public: + using value_type = typename std::remove_cv::type; + using pointer = typename AddConstIf::type*; + using reference = typename AddConstIf::type&; +}; + +// PointeeSynthIterTraits is similar to SynthIterTraits, but the 'Ptr' +// parameter is a pointer-like type, and value_type is the pointee. +template +struct PointeeSynthIterTraits : std::iterator_traits { + private: + static constexpr bool kIterConst = IsConstIter::value; + + public: + using value_type = typename std::pointer_traits::element_type; + using pointer = typename AddConstIf::type*; + using reference = typename AddConstIf::type&; +}; + +// CRTP base class for generating iterator adaptors. +// 'Sub' is the derived type, and 'Policy' encodes +// all of the behavior for the adaptor. +// Policy requirements: +// - type 'underlying_iterator': the underlying iterator type. +// - type 'adapted_traits': the traits of the adaptor. +// - static 'Extract(underlying_iterator)': convert iterator to reference. +// +template +class IteratorAdaptorBase { + private: + // Everything needed from the Policy type is expressed in this section. + using Iterator = typename Policy::underlying_iterator; + using OutTraits = typename Policy::adapted_traits; + static typename OutTraits::reference Extract(const Iterator& it) { + return Policy::Extract(it); + } + + public: + using iterator_category = typename OutTraits::iterator_category; + using value_type = typename OutTraits::value_type; + using pointer = typename OutTraits::pointer; + using reference = typename OutTraits::reference; + using difference_type = typename OutTraits::difference_type; + + IteratorAdaptorBase() : it_() { + } + // NOLINTNEXTLINE(runtime/explicit) + IteratorAdaptorBase(Iterator it) : it_(it) { + } + + Sub& sub() { + return static_cast(*this); + } + const Sub& sub() const { + return static_cast(*this); + } + + const Iterator& base() const { + return it_; + } + + reference get() const { + return Extract(base()); + } + reference operator*() const { + return get(); + } + pointer operator->() const { + return &get(); + } + reference operator[](difference_type d) const { + return *(sub() + d); + } + + Sub& operator++() { + ++it_; + return sub(); + } + Sub& operator--() { + --it_; + return sub(); + } + Sub operator++(int /*unused*/) { + return it_++; + } + Sub operator--(int /*unused*/) { + return it_--; + } + + Sub& operator+=(difference_type d) { + it_ += d; + return sub(); + } + Sub& operator-=(difference_type d) { + it_ -= d; + return sub(); + } + + bool operator==(Sub b) const { + return base() == b.base(); + } + bool operator!=(Sub b) const { + return base() != b.base(); + } + // These shouldn't be necessary, as implicit conversion from 'Iterator' + // should be enough to make such comparisons work. + bool operator==(Iterator b) const { + return *this == Sub(b); + } + bool operator!=(Iterator b) const { + return *this != Sub(b); + } + + friend Sub operator+(Sub it, difference_type d) { + return it.base() + d; + } + friend Sub operator+(difference_type d, Sub it) { + return it + d; + } + friend Sub operator-(Sub it, difference_type d) { + return it.base() - d; + } + friend difference_type operator-(Sub a, Sub b) { + return a.base() - b.base(); + } + + friend bool operator<(Sub a, Sub b) { + return a.base() < b.base(); + } + friend bool operator>(Sub a, Sub b) { + return a.base() > b.base(); + } + friend bool operator<=(Sub a, Sub b) { + return a.base() <= b.base(); + } + friend bool operator>=(Sub a, Sub b) { + return a.base() >= b.base(); + } + + private: + Iterator it_; +}; + +template +struct FirstPolicy { + using underlying_iterator = It; + using adapted_traits = + SynthIterTraits::value_type::first_type>; + static typename adapted_traits::reference Extract( + const underlying_iterator& it) { + return it->first; + } +}; + +template +struct SecondPolicy { + using underlying_iterator = It; + using adapted_traits = + SynthIterTraits::value_type::second_type>; + static typename adapted_traits::reference Extract( + const underlying_iterator& it) { + return it->second; + } +}; + +template +struct SecondPtrPolicy { + using underlying_iterator = It; + using adapted_traits = + PointeeSynthIterTraits::value_type::second_type>; + static typename adapted_traits::reference Extract( + const underlying_iterator& it) { + return *it->second; + } +}; + +template +struct PtrPolicy { + using underlying_iterator = It; + using adapted_traits = PointeeSynthIterTraits< + underlying_iterator, + typename std::iterator_traits::value_type>; + static typename adapted_traits::reference Extract( + const underlying_iterator& it) { + return **it; + } +}; + +} // namespace internal + +// In both iterator adaptors, iterator_first<> and iterator_second<>, +// we build a new iterator based on a parameterized iterator type, "It". +// The value type, "Val" is determined by "It::value_type::first" or +// "It::value_type::second", respectively. + +// iterator_first<> adapts an iterator to return the first value of a pair. +// It is equivalent to calling it->first on every value. +// Example: +// +// hash_map values; +// values["foo"] = 1; +// values["bar"] = 2; +// for (iterator_first::iterator> x = values.begin(); +// x != values.end(); ++x) { +// printf("%s", x->c_str()); +// } +template +struct iterator_first + : internal::IteratorAdaptorBase, + internal::FirstPolicy> { + using Base = internal::IteratorAdaptorBase, + internal::FirstPolicy>; + iterator_first() { + } + iterator_first(It it) // NOLINT(runtime/explicit) + : Base(it) { + } + template + iterator_first(iterator_first o) // NOLINT(runtime/explicit) + : Base(o.base()) { + } +}; + +template +iterator_first make_iterator_first(It it) { + return iterator_first(it); +} + +// iterator_second<> adapts an iterator to return the second value of a pair. +// It is equivalent to calling it->second on every value. +// Example: +// +// hash_map values; +// values["foo"] = 1; +// values["bar"] = 2; +// for (iterator_second::iterator> x = values.begin(); +// x != values.end(); ++x) { +// int v = *x; +// printf("%d", v); +// } +template +struct iterator_second + : internal::IteratorAdaptorBase, + internal::SecondPolicy> { + using Base = internal::IteratorAdaptorBase, + internal::SecondPolicy>; + iterator_second() { + } + iterator_second(It it) // NOLINT(runtime/explicit) + : Base(it) { + } + template + iterator_second(iterator_second o) // NOLINT(runtime/explicit) + : Base(o.base()) { + } +}; + +template +iterator_second make_iterator_second(It it) { + return iterator_second(it); +} + +// iterator_second_ptr<> adapts an iterator to return the dereferenced second +// value of a pair. +// It is equivalent to calling *it->second on every value. +// The same result can be achieved by composition +// iterator_ptr > +// Can be used with maps where values are regular pointers or pointers wrapped +// into linked_ptr. This iterator adaptor can be used by classes to give their +// clients access to some of their internal data without exposing too much of +// it. +// +// Example: +// class MyClass { +// public: +// MyClass(const string& s); +// string DebugString() const; +// }; +// typedef hash_map > MyMap; +// typedef iterator_second_ptr MyMapValuesIterator; +// MyMap values; +// values["foo"].reset(new MyClass("foo")); +// values["bar"].reset(new MyClass("bar")); +// for (MyMapValuesIterator it = values.begin(); it != values.end(); ++it) { +// printf("%s", it->DebugString().c_str()); +// } +template +struct iterator_second_ptr + : internal::IteratorAdaptorBase, + internal::SecondPtrPolicy> { + using Base = internal::IteratorAdaptorBase, + internal::SecondPtrPolicy>; + iterator_second_ptr() { + } + iterator_second_ptr(It it) // NOLINT(runtime/explicit) + : Base(it) { + } + template + iterator_second_ptr(iterator_second_ptr o) // NOLINT(runtime/explicit) + : Base(o.base()) { + } +}; + +template +iterator_second_ptr make_iterator_second_ptr(It it) { + return iterator_second_ptr(it); +} + +// iterator_ptr<> adapts an iterator to return the dereferenced value. +// With this adaptor you can write *it instead of **it, or it->something instead +// of (*it)->something. +// Can be used with vectors and lists where values are regular pointers +// or pointers wrapped into linked_ptr. This iterator adaptor can be used by +// classes to give their clients access to some of their internal data without +// exposing too much of it. +// +// Example: +// class MyClass { +// public: +// MyClass(const string& s); +// string DebugString() const; +// }; +// typedef vector > MyVector; +// typedef iterator_ptr DereferencingIterator; +// MyVector values; +// values.push_back(make_linked_ptr(new MyClass("foo"))); +// values.push_back(make_linked_ptr(new MyClass("bar"))); +// for (DereferencingIterator it = values.begin(); it != values.end(); ++it) { +// printf("%s", it->DebugString().c_str()); +// } +// +// Without iterator_ptr you would have to do (*it)->DebugString() +template +struct iterator_ptr : internal::IteratorAdaptorBase, + internal::PtrPolicy> { + using Base = internal::IteratorAdaptorBase, + internal::PtrPolicy>; + iterator_ptr() { + } + iterator_ptr(It it) // NOLINT(runtime/explicit) + : Base(it) { + } + template + iterator_ptr(iterator_ptr o) // NOLINT(runtime/explicit) + : Base(o.base()) { + } +}; + +template +iterator_ptr make_iterator_ptr(It it) { + return iterator_ptr(it); +} + +namespace internal { + +// Template that uses SFINAE to inspect Container abilities: +// . Set has_size_type true, iff T::size_type is defined +// . Define size_type as T::size_type if defined, or size_t otherwise +template +struct container_traits { + private: + // Test for availability of C::size_type. + template + struct test_size_type : std::false_type {}; + template + struct test_size_type> + : std::true_type {}; + + // Conditional provisioning of a size_type which defaults to size_t. + template + struct size_type_def { + using type = typename U::size_type; + }; + template + struct size_type_def { + using type = size_t; + }; + + public: + // Determine whether C::size_type is available. + static const bool has_size_type = test_size_type::value; + + // Provide size_type as either C::size_type if available, or as size_t. + using size_type = typename size_type_def::type; +}; + +template +struct IterGenerator { + using container_type = C; + using iterator = typename C::iterator; + using const_iterator = typename C::const_iterator; + + static iterator begin(container_type& c) { // NOLINT(runtime/references) + return c.begin(); + } + static iterator end(container_type& c) { // NOLINT(runtime/references) + return c.end(); + } + static const_iterator begin(const container_type& c) { + return c.begin(); + } + static const_iterator end(const container_type& c) { + return c.end(); + } +}; + +template +struct ReversingIterGeneratorAdaptor { + using container_type = typename SubIterGenerator::container_type; + using iterator = std::reverse_iterator; + using const_iterator = + std::reverse_iterator; + + static iterator begin(container_type& c) { // NOLINT(runtime/references) + return iterator(SubIterGenerator::end(c)); + } + static iterator end(container_type& c) { // NOLINT(runtime/references) + return iterator(SubIterGenerator::begin(c)); + } + static const_iterator begin(const container_type& c) { + return const_iterator(SubIterGenerator::end(c)); + } + static const_iterator end(const container_type& c) { + return const_iterator(SubIterGenerator::begin(c)); + } +}; + +// C: the container type +// Iter: the type of mutable iterator to generate +// ConstIter: the type of constant iterator to generate +// IterGenerator: a policy type that returns native iterators from a C +template > +class iterator_view_helper { + public: + using container_type = C; + using iterator = Iter; + using const_iterator = ConstIter; + using value_type = typename std::iterator_traits::value_type; + using size_type = typename internal::container_traits::size_type; + + explicit iterator_view_helper( + container_type& c) // NOLINT(runtime/references) + : c_(&c) { + } + + iterator begin() { + return iterator(IterGenerator::begin(container())); + } + iterator end() { + return iterator(IterGenerator::end(container())); + } + const_iterator begin() const { + return const_iterator(IterGenerator::begin(container())); + } + const_iterator end() const { + return const_iterator(IterGenerator::end(container())); + } + const_iterator cbegin() const { + return begin(); + } + const_iterator cend() const { + return end(); + } + const container_type& container() const { + return *c_; + } + container_type& container() { + return *c_; + } + + bool empty() const { + return begin() == end(); + } + size_type size() const { + return c_->size(); + } + + private: + container_type* c_; +}; + +template > +class const_iterator_view_helper { + public: + using container_type = C; + using const_iterator = ConstIter; + using value_type = typename std::iterator_traits::value_type; + using size_type = typename internal::container_traits::size_type; + + explicit const_iterator_view_helper(const container_type& c) : c_(&c) { + } + + // Allow implicit conversion from the corresponding iterator_view_helper. + // Erring on the side of constness should be allowed. E.g.: + // MyMap m; + // key_view_type::type keys = key_view(m); // ok + // key_view_type::type const_keys = key_view(m); // ok + template + const_iterator_view_helper(const iterator_view_helper& v) + : c_(&v.container()) { + } + + const_iterator begin() const { + return const_iterator(IterGenerator::begin(container())); + } + const_iterator end() const { + return const_iterator(IterGenerator::end(container())); + } + const_iterator cbegin() const { + return begin(); + } + const_iterator cend() const { + return end(); + } + const container_type& container() const { + return *c_; + } + + bool empty() const { + return begin() == end(); + } + size_type size() const { + return c_->size(); + } + + private: + const container_type* c_; +}; + +} // namespace internal + +// Note: The views like value_view, key_view should be in gtl namespace. +// Currently there are lot of callers that reference the methods in the global +// namespace. +// +// Traits to provide a typedef abstraction for the return value +// of the key_view() and value_view() functions, such that +// they can be declared as: +// +// template key_view_t key_view(C& c); +// template value_view_t value_view(C& c); +// +// This abstraction allows callers of these functions to use readable +// type names, and allows the maintainers of iterator_adaptors.h to +// change the return types if needed without updating callers. + +template +struct key_view_type { + using type = internal::iterator_view_helper< + C, + iterator_first, + iterator_first>; +}; + +template +struct key_view_type { + using type = internal:: + const_iterator_view_helper>; +}; + +template +struct value_view_type { + using type = internal::iterator_view_helper< + C, + iterator_second, + iterator_second>; +}; + +template +struct value_view_type { + using type = internal::const_iterator_view_helper< + C, + iterator_second>; +}; + +// The key_view and value_view functions provide pretty ways to iterate either +// the keys or the values of a map using range based for loops. +// +// Example: +// hash_map my_map; +// ... +// for (string val : value_view(my_map)) { +// ... +// } +// +// Note: If you pass a temporary container to key_view or value_view, be careful +// that the temporary container outlives the wrapper view to avoid dangling +// references. +// This is fine: PublishAll(value_view(Make()); +// This is not: for (const auto& v : value_view(Make())) Publish(v); + +template +typename key_view_type::type key_view( + C& map) { // NOLINT(runtime/references) + return typename key_view_type::type(map); +} + +template +typename key_view_type::type key_view(const C& map) { + return typename key_view_type::type(map); +} + +template +typename value_view_type::type value_view( + C& map) { // NOLINT(runtime/references) + return typename value_view_type::type(map); +} + +template +typename value_view_type::type value_view(const C& map) { + return typename value_view_type::type(map); +} + +// Abstract container view that dereferences the pointer-like .second member +// of a container's std::pair elements, such as the elements of std::map +// or of std::vector>. +// +// Example: +// map elements; +// for (const string& element : deref_second_view(elements)) { +// ... +// } +// +// Note: If you pass a temporary container to deref_second_view, be careful that +// the temporary container outlives the deref_second_view to avoid dangling +// references. +// This is fine: PublishAll(deref_second_view(Make()); +// This is not: for (const auto& v : deref_second_view(Make())) { +// Publish(v); +// } + +template +struct deref_second_view_type { + using type = internal::iterator_view_helper< + C, + iterator_second_ptr, + iterator_second_ptr>; +}; + +template +struct deref_second_view_type { + using type = internal::const_iterator_view_helper< + C, + iterator_second_ptr>; +}; + +template +typename deref_second_view_type::type deref_second_view( + C& map) { // NOLINT(runtime/references) + return typename deref_second_view_type::type(map); +} + +template +typename deref_second_view_type::type deref_second_view(const C& map) { + return typename deref_second_view_type::type(map); +} + +// Abstract container view that dereferences pointer elements. +// +// Example: +// vector elements; +// for (const string& element : deref_view(elements)) { +// ... +// } +// +// Note: If you pass a temporary container to deref_view, be careful that the +// temporary container outlives the deref_view to avoid dangling references. +// This is fine: PublishAll(deref_view(Make()); +// This is not: for (const auto& v : deref_view(Make())) { Publish(v); } + +template +struct deref_view_type { + using type = + internal::iterator_view_helper, + iterator_ptr>; +}; + +template +struct deref_view_type { + using type = internal:: + const_iterator_view_helper>; +}; + +template +typename deref_view_type::type deref_view( + C& c) { // NOLINT(runtime/references) + return typename deref_view_type::type(c); +} + +template +typename deref_view_type::type deref_view(const C& c) { + return typename deref_view_type::type(c); +} + +// Abstract container view that iterates backwards. +// +// Example: +// vector elements; +// for (const string& element : reversed_view(elements)) { +// ... +// } +// +// Note: If you pass a temporary container to reversed_view_type, be careful +// that the temporary container outlives the reversed_view to avoid dangling +// references. This is fine: PublishAll(reversed_view(Make()); +// This is not: for (const auto& v : reversed_view(Make())) { Publish(v); } + +template +struct reversed_view_type { + private: + using policy = + internal::ReversingIterGeneratorAdaptor>; + + public: + using type = internal::iterator_view_helper; +}; + +template +struct reversed_view_type { + private: + using policy = + internal::ReversingIterGeneratorAdaptor>; + + public: + using type = internal:: + const_iterator_view_helper; +}; + +template +typename reversed_view_type::type reversed_view( + C& c) { // NOLINT(runtime/references) + return typename reversed_view_type::type(c); +} + +template +typename reversed_view_type::type reversed_view(const C& c) { + return typename reversed_view_type::type(c); +} + +} // namespace util +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_ITERATOR_ADAPTORS_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/log.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/log.h new file mode 100644 index 0000000..248d434 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/log.h @@ -0,0 +1,84 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_LOG_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_LOG_H_ + +#include + +#include "Firestore/core/src/firebase/firestore/util/string_format.h" + +namespace firebase { +namespace firestore { +namespace util { + +// Levels used when logging messages. +enum LogLevel { + // Debug Log Level + kLogLevelDebug, + // Warning Log Level + kLogLevelWarning, +}; + +// Log a message if kLogLevelDebug is enabled. Arguments are not evaluated if +// logging is disabled. +// +// @param format A format string suitable for use with `util::StringFormat` +// @param ... C++ variadic arguments that match the format string. Not C +// varargs. +#define LOG_DEBUG(...) \ + do { \ + namespace _util = firebase::firestore::util; \ + if (_util::LogIsLoggable(_util::kLogLevelDebug)) { \ + std::string _message = _util::StringFormat(__VA_ARGS__); \ + _util::LogMessage(_util::kLogLevelDebug, _message); \ + } \ + } while (0) + +// Log a message if kLogLevelWarn is enabled (it is by default). Arguments are +// not evaluated if logging is disabled. +// +// @param format A format string suitable for use with `util::StringFormat` +// @param ... C++ variadic arguments that match the format string. Not C +// varargs. +#define LOG_WARN(...) \ + do { \ + namespace _util = firebase::firestore::util; \ + if (_util::LogIsLoggable(_util::kLogLevelWarning)) { \ + std::string _message = _util::StringFormat(__VA_ARGS__); \ + _util::LogMessage(_util::kLogLevelWarning, _message); \ + } \ + } while (0) + +// Tests to see if the given log level is loggable. +bool LogIsLoggable(LogLevel level); + +// Is debug logging enabled? +inline bool LogIsDebugEnabled() { + return LogIsLoggable(kLogLevelDebug); +} + +// All messages at or above the specified log level value are displayed. +void LogSetLevel(LogLevel level); + +// Log a message at the given level. +void LogMessage(LogLevel log_level, const std::string& message); + +} // namespace util +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_LOG_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/log_apple.mm b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/log_apple.mm new file mode 100644 index 0000000..e173b47 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/log_apple.mm @@ -0,0 +1,78 @@ +/* + * Copyright 2017 Google + * + * 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 "Firestore/core/src/firebase/firestore/util/log.h" + +#if defined(__APPLE__) + +#import +#import + +#include +#include + +#include "Firestore/core/src/firebase/firestore/util/string_apple.h" + +namespace firebase { +namespace firestore { +namespace util { + +namespace { + +// Translates a C++ LogLevel to the equivalent Objective-C FIRLoggerLevel +FIRLoggerLevel ToFIRLoggerLevel(LogLevel level) { + switch (level) { + case kLogLevelDebug: + return FIRLoggerLevelDebug; + case kLogLevelWarning: + return FIRLoggerLevelWarning; + default: + // Unsupported log level. FIRSetLoggerLevel will deal with it. + return static_cast(-1); + } +} + +// Actually logs a message via FIRLogger. This must be a C varargs function +// so that we can call FIRLogBasic which takes a `va_list`. +void LogMessageV(LogLevel level, NSString* format, ...) { + va_list list; + va_start(list, format); + + FIRLogBasic(ToFIRLoggerLevel(level), kFIRLoggerFirestore, @"I-FST000001", + format, list); + + va_end(list); +} + +} // namespace + +void LogSetLevel(LogLevel level) { + FIRSetLoggerLevel(ToFIRLoggerLevel(level)); +} + +bool LogIsLoggable(LogLevel level) { + return FIRIsLoggableLevel(ToFIRLoggerLevel(level), NO); +} + +void LogMessage(LogLevel level, const std::string& message) { + LogMessageV(level, @"%s", message.c_str()); +} + +} // namespace util +} // namespace firestore +} // namespace firebase + +#endif // defined(__APPLE__) diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/objc_compatibility.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/objc_compatibility.h new file mode 100644 index 0000000..5745d77 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/objc_compatibility.h @@ -0,0 +1,129 @@ +/* + * Copyright 2019 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_OBJC_COMPATIBILITY_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_OBJC_COMPATIBILITY_H_ + +#if !defined(__OBJC__) +#error "This header only supports Objective-C++" +#endif // !defined(__OBJC__) + +#import + +#include +#include +#include +#include + +#include "Firestore/core/src/firebase/firestore/util/string_apple.h" +#include "Firestore/core/src/firebase/firestore/util/to_string.h" +#include "Firestore/core/src/firebase/firestore/util/type_traits.h" +#include "absl/meta/type_traits.h" + +/** + * Utility functions that help C++ code interoperate with Objective-C while + * migration is in progress + */ + +namespace firebase { +namespace firestore { +namespace util { +namespace objc { + +namespace internal { + +template +using is_container_of_objc = + absl::conjunction, + is_objective_c_pointer>; + +} + +/** + * Checks two Objective-C objects for equality using `isEqual`. Two nil objects + * are considered equal, unlike the behavior of `isEqual`. + */ +template ::value>> +bool Equals(T* lhs, T* rhs) { + return (lhs == nil && rhs == nil) || [lhs isEqual:rhs]; +} + +/** Checks two C++ containers of Objective-C objects for "deep" equality. */ +template < + typename T, + typename = absl::enable_if_t::value>> +bool Equals(const T& lhs, const T& rhs) { + using Ptr = typename T::value_type; + + return lhs.size() == rhs.size() && + std::equal(lhs.begin(), lhs.end(), rhs.begin(), + [](Ptr o1, Ptr o2) { return Equals(o1, o2); }); +} + +/** + * A function object that implements equality for an Objective-C pointer by + * delegating to -isEqual:. This is useful for using Objective-C objects as + * keys in STL associative containers. + */ +template ::value>> +class EqualTo { + public: + bool operator()(T lhs, T rhs) const { + return [lhs isEqual:rhs]; + } +}; + +/** + * A function object that implements STL-compatible hash code for an Objective-C + * pointer by delegating to -hash. This is useful for using Objective-C objects + * as keys in std::unordered_map. + */ +template ::value>> +class Hash { + public: + size_t operator()(T value) const { + return static_cast([value hash]); + } +}; + +/** + * The equivalent of std::unordered_map, where the Key type is an Objective-C + * class. + */ +template ::value>> +using unordered_map = std::unordered_map, EqualTo>; + +/** + * Creates a debug description of the given `value` by calling `ToString` on it, + * converting the result to an `NSString`. Exists mainly to simplify writing + * `description:` methods for Objective-C classes. + */ +template +NSString* Description(const T& value) { + return WrapNSString(ToString(value)); +} + +} // namespace objc +} // namespace util +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_OBJC_COMPATIBILITY_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/ordered_code.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/ordered_code.cc new file mode 100644 index 0000000..03da08d --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/ordered_code.cc @@ -0,0 +1,618 @@ +/* + * Copyright 2017 Google + * + * 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 "Firestore/core/src/firebase/firestore/util/ordered_code.h" + +#include "Firestore/core/src/firebase/firestore/util/bits.h" +#include "Firestore/core/src/firebase/firestore/util/hard_assert.h" +#include "absl/base/internal/endian.h" +#include "absl/base/internal/unaligned_access.h" +#include "absl/base/port.h" + +#define UNALIGNED_LOAD32 ABSL_INTERNAL_UNALIGNED_LOAD32 +#define UNALIGNED_LOAD64 ABSL_INTERNAL_UNALIGNED_LOAD64 +#define UNALIGNED_STORE32 ABSL_INTERNAL_UNALIGNED_STORE32 +#define UNALIGNED_STORE64 ABSL_INTERNAL_UNALIGNED_STORE64 + +// We encode a string in different ways depending on whether the item +// should be in lexicographically increasing or decreasing order. +// +// +// Lexicographically increasing order +// +// We want a string-to-string mapping F(x) such that for any two strings +// +// x < y => F(x) < F(y) +// +// In addition to the normal characters '\x00' through '\xff', we want to +// encode a few extra symbols in strings: +// +// Separator between items +// Infinite string +// +// Therefore we need an alphabet with at least 258 symbols. Each +// character '\1' through '\xfe' is mapped to itself. The other four are +// encoded into two-letter sequences starting with '\0' and '\xff': +// +// encoded as => \0\1 +// \0 encoded as => \0\xff +// \xff encoded as => \xff\x00 +// encoded as => \xff\xff +// +// The remaining two-letter sequences starting with '\0' and '\xff' are +// currently unused. +// +// F() is defined above. For any finite string x, F(x) is the +// the encodings of x's characters followed by the encoding for . The +// ordering of two finite strings is the same as the ordering of the +// respective characters at the first position where they differ, which in +// turn is the same as the ordering of the encodings of those two +// characters. Moreover, for every finite string x, F(x) < F(). + +namespace firebase { +namespace firestore { +namespace util { + +static const char kEscape1 = '\000'; +static const char kNullCharacter = '\xff'; // Combined with kEscape1 +static const char kSeparator = '\001'; // Combined with kEscape1 + +static const char kEscape2 = '\xff'; +static const char kInfinity = '\xff'; // Combined with kEscape2 +static const char kFFCharacter = '\000'; // Combined with kEscape2 + +static const char kEscape1_Separator[2] = {kEscape1, kSeparator}; + +/** Append to "*dest" the "len" bytes starting from "*src". */ +inline static void AppendBytes(std::string* dest, const char* src, size_t len) { + dest->append(src, len); +} + +inline static bool IsSpecialByte(char c) { + return ((unsigned char)(c + 1)) < 2; +} + +/** + * Returns 0 if one or more of the bytes in the specified uint32 value + * are the special values 0 or 255, and returns 4 otherwise. The + * result of this routine can be added to "p" to either advance past + * the next 4 bytes if they do not contain a special byte, or to + * remain on this set of four bytes if they contain the next special + * byte occurrence. + * + * REQUIRES: v_32 is the value of loading the next 4 bytes from "*p" (we + * pass in v_32 rather than loading it because in some cases, the client + * may already have the value in a register: "p" is just used for + * assertion checking). + */ +inline static int AdvanceIfNoSpecialBytes(uint32_t v_32, const char* p) { + HARD_ASSERT(UNALIGNED_LOAD32(p) == v_32); + // See comments in SkipToNextSpecialByte if you wish to + // understand this expression (which checks for the occurrence + // of the special byte values 0 or 255 in any of the bytes of v_32). + if ((v_32 - 0x01010101u) & ~(v_32 + 0x01010101u) & 0x80808080u) { + // Special byte is in p[0..3] + HARD_ASSERT(IsSpecialByte(p[0]) || IsSpecialByte(p[1]) || + IsSpecialByte(p[2]) || IsSpecialByte(p[3])); + return 0; + } else { + HARD_ASSERT(!IsSpecialByte(p[0])); + HARD_ASSERT(!IsSpecialByte(p[1])); + HARD_ASSERT(!IsSpecialByte(p[2])); + HARD_ASSERT(!IsSpecialByte(p[3])); + return 4; + } +} + +/** + * Return a pointer to the first byte in the range "[start..limit)" + * whose value is 0 or 255 (kEscape1 or kEscape2). If no such byte + * exists in the range, returns "limit". + */ +inline static const char* SkipToNextSpecialByte(const char* start, + const char* limit) { + // If these constants were ever changed, this routine needs to change + HARD_ASSERT(kEscape1 == 0); + HARD_ASSERT((kEscape2 & 0xff) == 255); + const char* p = start; + while (p + 8 <= limit) { + // Find out if any of the next 8 bytes are either 0 or 255 (our + // two characters that require special handling). We do this using + // the technique described in: + // + // http://graphics.stanford.edu/~seander/bithacks.html#HasLessInWord + // + // We use the test (x + 1) < 2 to check x = 0 or -1(255) + // + // If x is a byte value (0x00..0xff): + // (x - 0x01) & 0x80 is true only when x = 0x81..0xff, 0x00 + // ~(x + 0x01) & 0x80 is true only when x = 0x00..0x7e, 0xff + // The intersection of the above two sets is x = 0x00 or 0xff. + // We can ignore carry between bytes because only x = 0x00 or 0xff + // can cause carry in the expression -- and such x already makes the + // result value non-zero. + uint64_t v = UNALIGNED_LOAD64(p); + bool hasZeroOr255Byte = (v - 0x0101010101010101ull) & + ~(v + 0x0101010101010101ull) & + 0x8080808080808080ull; + if (!hasZeroOr255Byte) { + // No special values in the next 8 bytes + p += 8; + } else { +// We know the next 8 bytes have a special byte: find it +#ifdef IS_LITTLE_ENDIAN + uint32_t v_32 = static_cast(v); // Low 32 bits of v +#else + uint32_t v_32 = UNALIGNED_LOAD32(p); +#endif + // Test 32 bits at once to see if special byte is in next 4 bytes + // or the following 4 bytes + p += AdvanceIfNoSpecialBytes(v_32, p); + if (IsSpecialByte(p[0])) return p; + if (IsSpecialByte(p[1])) return p + 1; + if (IsSpecialByte(p[2])) return p + 2; + HARD_ASSERT(IsSpecialByte(p[3])); // Last byte must be the special one + return p + 3; + } + } + if (p + 4 <= limit) { + uint32_t v_32 = UNALIGNED_LOAD32(p); + p += AdvanceIfNoSpecialBytes(v_32, p); + } + while (p < limit && !IsSpecialByte(*p)) { + p++; + } + return p; +} + +// Expose SkipToNextSpecialByte for testing purposes +const char* OrderedCode::TEST_SkipToNextSpecialByte(const char* start, + const char* limit) { + return SkipToNextSpecialByte(start, limit); +} + +/** + * Helper routine to encode "s" and append to "*dest", escaping special + * characters. + */ +inline static void EncodeStringFragment(std::string* dest, + absl::string_view s) { + const char* p = s.data(); + const char* limit = p + s.size(); + const char* copy_start = p; + while (true) { + p = SkipToNextSpecialByte(p, limit); + if (p >= limit) break; // No more special characters that need escaping + char c = *(p++); + HARD_ASSERT(IsSpecialByte(c)); + if (c == kEscape1) { + AppendBytes(dest, copy_start, static_cast(p - copy_start) - 1); + dest->push_back(kEscape1); + dest->push_back(kNullCharacter); + copy_start = p; + } else { + HARD_ASSERT(c == kEscape2); + AppendBytes(dest, copy_start, static_cast(p - copy_start) - 1); + dest->push_back(kEscape2); + dest->push_back(kFFCharacter); + copy_start = p; + } + } + if (p > copy_start) { + AppendBytes(dest, copy_start, static_cast(p - copy_start)); + } +} + +void OrderedCode::WriteString(std::string* dest, absl::string_view s) { + EncodeStringFragment(dest, s); + AppendBytes(dest, kEscape1_Separator, 2); +} + +/** + * Return number of bytes needed to encode the non-length portion + * of val in ordered coding. Returns number in range [0,8]. + */ +static inline unsigned int OrderedNumLength(uint64_t val) { + const int lg = Bits::Log2Floor64(val); // -1 if val==0 + return static_cast(lg + 1 + 7) / 8; +} + +/** + * Append n bytes from src to *dst. + * REQUIRES: n <= 9 + * REQUIRES: src[0..8] are readable bytes (even if n is smaller) + * + * If we use string::append() instead of this routine, it increases the + * runtime of WriteNumIncreasing from ~9ns to ~13ns. + */ +static inline void AppendUpto9(std::string* dst, + const char* src, + unsigned int n) { + dst->append(src, 9); // Fixed-length append + const size_t extra = 9 - n; // How many extra bytes we added + dst->erase(dst->size() - extra, extra); +} + +void OrderedCode::WriteNumIncreasing(std::string* dest, uint64_t val) { + // Values are encoded with a single byte length prefix, followed + // by the actual value in big-endian format with leading 0 bytes + // dropped. + + // 8 bytes for value plus one byte for length. In addition, we have + // 8 extra bytes at the end so that we can have a fixed-length append + // call on *dest. + char buf[17]; + + UNALIGNED_STORE64(buf + 1, + absl::ghtonll(val)); // buf[0] may be needed for length + const unsigned int length = OrderedNumLength(val); + char* start = buf + 9 - length - 1; + *start = static_cast(length); + AppendUpto9(dest, start, length + 1); +} + +inline static void WriteInfinityInternal(std::string* dest) { + // Make an array so that we can just do one string operation for performance + static const char buf[2] = {kEscape2, kInfinity}; + dest->append(buf, 2); +} + +void OrderedCode::WriteInfinity(std::string* dest) { + WriteInfinityInternal(dest); +} + +void OrderedCode::WriteTrailingString(std::string* dest, + absl::string_view str) { + dest->append(str.data(), str.size()); +} + +/** + * Parse the encoding of a string previously encoded with or without + * inversion. If parse succeeds, return true, consume encoding from + * "*src", and if result != NULL append the decoded string to "*result". + * Otherwise, return false and leave both undefined. + */ +inline static bool ReadStringInternal(absl::string_view* src, + std::string* result) { + const char* start = src->data(); + const char* string_limit = src->data() + src->size(); + + // We only scan up to "limit-2" since a valid string must end with + // a two character terminator: 'kEscape1 kSeparator' + const char* limit = string_limit - 1; + const char* copy_start = start; + while (true) { + start = SkipToNextSpecialByte(start, limit); + if (start >= limit) break; // No terminator sequence found + const char c = *(start++); + // If inversion is required, instead of inverting 'c', we invert the + // character constants to which 'c' is compared. We get the same + // behavior but save the runtime cost of inverting 'c'. + HARD_ASSERT(IsSpecialByte(c)); + if (c == kEscape1) { + if (result) { + AppendBytes(result, copy_start, + static_cast(start - copy_start) - 1); + } + // kEscape1 kSeparator ends component + // kEscape1 kNullCharacter represents '\0' + const char next = *(start++); + if (next == kSeparator) { + src->remove_prefix(static_cast(start - src->data())); + return true; + } else if (next == kNullCharacter) { + if (result) { + *result += '\0'; + } + } else { + return false; + } + copy_start = start; + } else { + HARD_ASSERT(c == kEscape2); + if (result) { + AppendBytes(result, copy_start, + static_cast(start - copy_start) - 1); + } + // kEscape2 kFFCharacter represents '\xff' + // kEscape2 kInfinity is an error + const char next = *(start++); + if (next == kFFCharacter) { + if (result) { + *result += '\xff'; + } + } else { + return false; + } + copy_start = start; + } + } + return false; +} + +bool OrderedCode::ReadString(absl::string_view* src, std::string* result) { + return ReadStringInternal(src, result); +} + +bool OrderedCode::ReadNumIncreasing(absl::string_view* src, uint64_t* result) { + if (src->empty()) { + return false; // Not enough bytes + } + + // Decode length byte + const size_t len = static_cast((*src)[0]); + + // If len > 0 and src is longer than 1, the first byte of "payload" + // must be non-zero (otherwise the encoding is not minimal). + // In opt mode, we don't enforce that encodings must be minimal. + HARD_ASSERT(0 == len || src->size() == 1 || (*src)[1] != '\0'); + + if (len + 1 > src->size() || len > 8) { + return false; // Not enough bytes or too many bytes + } + + if (result) { + uint64_t tmp = 0; + for (size_t i = 0; i < len; i++) { + tmp <<= 8; + tmp |= static_cast((*src)[1 + i]); + } + *result = tmp; + } + src->remove_prefix(len + 1); + return true; +} + +inline static bool ReadInfinityInternal(absl::string_view* src) { + if (src->size() >= 2 && ((*src)[0] == kEscape2) && ((*src)[1] == kInfinity)) { + src->remove_prefix(2); + return true; + } else { + return false; + } +} + +bool OrderedCode::ReadInfinity(absl::string_view* src) { + return ReadInfinityInternal(src); +} + +inline static bool ReadStringOrInfinityInternal(absl::string_view* src, + std::string* result, + bool* inf) { + if (ReadInfinityInternal(src)) { + if (inf) *inf = true; + return true; + } + + // We don't use ReadStringInternal here because that would inline + // the whole encoded string parsing code here. Depending on INVERT, only + // one of the following two calls will be generated at compile time. + bool success = OrderedCode::ReadString(src, result); + if (success) { + if (inf) *inf = false; + return true; + } else { + return false; + } +} + +bool OrderedCode::ReadStringOrInfinity(absl::string_view* src, + std::string* result, + bool* inf) { + return ReadStringOrInfinityInternal(src, result, inf); +} + +bool OrderedCode::ReadTrailingString(absl::string_view* src, + std::string* result) { + if (result) result->assign(src->data(), src->size()); + src->remove_prefix(src->size()); + return true; +} + +void OrderedCode::TEST_Corrupt(std::string* str, int k) { + int seen_seps = 0; + for (size_t i = 0; i < str->size() - 1; i++) { + if ((*str)[i] == kEscape1 && (*str)[i + 1] == kSeparator) { + seen_seps++; + if (seen_seps == k) { + (*str)[i + 1] = kSeparator + 1; + return; + } + } + } +} + +// Signed number encoding/decoding ///////////////////////////////////// +// +// The format is as follows: +// +// The first bit (the most significant bit of the first byte) +// represents the sign, 0 if the number is negative and +// 1 if the number is >= 0. +// +// Any unbroken sequence of successive bits with the same value as the sign +// bit, up to 9 (the 8th and 9th are the most significant bits of the next +// byte), are size bits that count the number of bytes after the first byte. +// That is, the total length is between 1 and 10 bytes. +// +// The value occupies the bits after the sign bit and the "size bits" +// till the end of the string, in network byte order. If the number +// is negative, the bits are in 2-complement. +// +// +// Example 1: number 0x424242 -> 4 byte big-endian hex string 0xf0424242: +// +// +---------------+---------------+---------------+---------------+ +// 1 1 1 1 0 0 0 0 0 1 0 0 0 0 1 0 0 1 0 0 0 1 0 0 0 1 0 0 0 0 1 0 +// +---------------+---------------+---------------+---------------+ +// ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ +// | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | +// | | | | payload: the remaining bits after the sign and size bits +// | | | | and the delimiter bit, the value is 0x424242 +// | | | | +// | size bits: 3 successive bits with the same value as the sign bit +// | (followed by a delimiter bit with the opposite value) +// | mean that there are 3 bytes after the first byte, 4 total +// | +// sign bit: 1 means that the number is non-negative +// +// Example 2: negative number -0x800 -> 2 byte big-endian hex string 0x3800: +// +// +---------------+---------------+ +// 0 0 1 1 1 0 0 0 0 0 0 0 0 0 0 0 +// +---------------+---------------+ +// ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ ^ +// | | | | | | | | | | | | | | | | | | | | | | | | | | | | | +// | | payload: the remaining bits after the sign and size bits and the +// | | delimiter bit, 2-complement because of the negative sign, +// | | value is ~0x7ff, represents the value -0x800 +// | | +// | size bits: 1 bit with the same value as the sign bit +// | (followed by a delimiter bit with the opposite value) +// | means that there is 1 byte after the first byte, 2 total +// | +// sign bit: 0 means that the number is negative +// +// +// Compared with the simpler unsigned format used for uint64_t numbers, +// this format is more compact for small numbers, namely one byte encodes +// numbers in the range [-64,64), two bytes cover the range [-2^13,2^13), etc. +// In general, n bytes encode numbers in the range [-2^(n*7-1),2^(n*7-1)). +// (The cross-over point for compactness of representation is 8 bytes, +// where this format only covers the range [-2^55,2^55), +// whereas an encoding with sign bit and length in the first byte and +// payload in all following bytes would cover [-2^56,2^56).) + +static const int kMaxSigned64Length = 10; + +// This array maps encoding length to header bits in the first two bytes. +static const char kLengthToHeaderBits[1 + kMaxSigned64Length][2] = { + {0, 0}, {'\x80', 0}, {'\xc0', 0}, {'\xe0', 0}, + {'\xf0', 0}, {'\xf8', 0}, {'\xfc', 0}, {'\xfe', 0}, + {'\xff', 0}, {'\xff', '\x80'}, {'\xff', '\xc0'}}; + +// This array maps encoding lengths to the header bits that overlap with +// the payload and need fixing when reading. +static const uint64_t kLengthToMask[1 + kMaxSigned64Length] = { + 0ULL, + 0x80ULL, + 0xc000ULL, + 0xe00000ULL, + 0xf0000000ULL, + 0xf800000000ULL, + 0xfc0000000000ULL, + 0xfe000000000000ULL, + 0xff00000000000000ULL, + 0x8000000000000000ULL, + 0ULL}; + +// This array maps the number of bits in a number to the encoding +// length produced by WriteSignedNumIncreasing. +// For positive numbers, the number of bits is 1 plus the most significant +// bit position (the highest bit position in a positive int64_t is 63). +// For a negative number n, we count the bits in ~n. +// That is, length = kBitsToLength[Bits::Log2Floor64(n < 0 ? ~n : n) + 1]. +static const int8_t kBitsToLength[1 + 63] = { + 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 4, + 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 7, 7, + 7, 7, 7, 7, 7, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 10}; + +/** Calculates the encoding length in bytes of the signed number n. */ +static inline int SignedEncodingLength(int64_t n) { + return kBitsToLength[Bits::Log2Floor64( + static_cast(n < 0 ? ~n : n)) + + 1]; +} + +/** Slightly faster version for n > 0. */ +static inline int SignedEncodingLengthPositive(int64_t n) { + return kBitsToLength[Bits::Log2FloorNonZero64(static_cast(n)) + 1]; +} + +void OrderedCode::WriteSignedNumIncreasing(std::string* dest, int64_t val) { + const int64_t x = val < 0 ? ~val : val; + if (x < 64) { // fast path for encoding length == 1 + *dest += static_cast(kLengthToHeaderBits[1][0] ^ val); + return; + } + // buf = val in network byte order, sign extended to 10 bytes + const char sign_byte = val < 0 ? '\xff' : '\0'; + char buf[10] = { + sign_byte, + sign_byte, + }; + UNALIGNED_STORE64(buf + 2, absl::ghtonll(static_cast(val))); + + HARD_ASSERT(sizeof(buf) == kMaxSigned64Length, "max length size mismatch"); + const size_t len = static_cast(SignedEncodingLengthPositive(x)); + HARD_ASSERT(len >= 2); + char* const begin = buf + sizeof(buf) - len; + begin[0] ^= kLengthToHeaderBits[len][0]; + begin[1] ^= kLengthToHeaderBits[len][1]; // ok because len >= 2 + dest->append(begin, len); +} + +bool OrderedCode::ReadSignedNumIncreasing(absl::string_view* src, + int64_t* result) { + if (src->empty()) return false; + const uint64_t xor_mask = (!((*src)[0] & 0x80)) ? ~0ULL : 0ULL; + const unsigned char first_byte = static_cast( + static_cast((*src)[0]) ^ (xor_mask & 0xff)); + + // now calculate and test length, and set x to raw (unmasked) result + size_t len; + uint64_t x; + if (first_byte != 0xff) { + len = static_cast(7 - Bits::Log2FloorNonZero(first_byte ^ 0xff)); + if (src->size() < len) return false; + x = xor_mask; // sign extend using xor_mask + for (size_t i = 0; i < len; ++i) + x = (x << 8) | static_cast((*src)[i]); + } else { + len = 8; + if (src->size() < len) return false; + const unsigned char second_byte = static_cast( + static_cast((*src)[1]) ^ (xor_mask & 0xff)); + if (second_byte >= 0x80) { + if (second_byte < 0xc0) { + len = 9; + } else { + const unsigned char third_byte = static_cast( + static_cast((*src)[2]) ^ (xor_mask & 0xff)); + if (second_byte == 0xc0 && third_byte < 0x80) { + len = 10; + } else { + return false; // either len > 10 or len == 10 and #bits > 63 + } + } + if (src->size() < len) return false; + } + x = absl::gntohll(UNALIGNED_LOAD64(src->data() + len - 8)); + } + + x ^= kLengthToMask[len]; // remove spurious header bits + + HARD_ASSERT(len == static_cast( + SignedEncodingLength(static_cast(x)))); + + if (result) *result = static_cast(x); + src->remove_prefix(static_cast(len)); + return true; +} + +} // namespace util +} // namespace firestore +} // namespace firebase diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/ordered_code.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/ordered_code.h new file mode 100644 index 0000000..57b84bd --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/ordered_code.h @@ -0,0 +1,129 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +// This module provides routines for encoding a sequence of typed +// entities into a string. The resulting strings can be +// lexicographically compared to yield the same comparison value that +// would have been generated if the encoded items had been compared +// one by one according to their type. +// +// More precisely, suppose: +// 1. string A is generated by encoding the sequence of items [A_1..A_n] +// 2. string B is generated by encoding the sequence of items [B_1..B_n] +// 3. The types match; i.e., for all i: A_i was encoded using +// the same routine as B_i +// Then: +// Comparing A vs. B lexicographically is the same as comparing +// the vectors [A_1..A_n] and [B_1..B_n] lexicographically. +// +// Furthermore, if n < m, the encoding of [A_1..A_n] is a strict prefix of +// [A_1..A_m] (unless m = n+1 and A_m is the empty string encoded with +// WriteTrailingString, in which case the encodings are equal). +// +// This module is often useful when generating multi-part sstable +// keys that have to be ordered in a particular fashion. + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_ORDERED_CODE_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_ORDERED_CODE_H_ + +#include + +#include "absl/strings/string_view.h" + +namespace firebase { +namespace firestore { +namespace util { + +class OrderedCode { + public: + // ------------------------------------------------------------------- + // Encoding routines: each one of the following routines append + // one item to "*dest". The Write(Signed)NumIncreasing() and + // Write(Signed)NumDecreasing() routines differ in whether the resulting + // encoding is ordered by increasing number or decreasing number. + // Similarly, WriteString() and WriteStringDecreasing() differ in whether + // the resulting encoding is ordered by the original string in + // lexicographically increasing or decreasing order. WriteString() + // is not called WriteStringIncreasing() for convenience and backward + // compatibility. + + static void WriteString(std::string* dest, absl::string_view str); + static void WriteNumIncreasing(std::string* dest, uint64_t num); + static void WriteSignedNumIncreasing(std::string* dest, int64_t num); + + /** + * Creates an encoding for the "infinite string", a value considered to + * be lexicographically after any real string. Note that in the case of + * WriteInfinityDecreasing(), this would come before any real string as + * the ordering puts lexicographically greater values first. + */ + static void WriteInfinity(std::string* dest); + + /** + * Special string append that can only be used at the tail end of + * an encoded string -- blindly appends "str" to "*dest". + */ + static void WriteTrailingString(std::string* dest, absl::string_view str); + + // ------------------------------------------------------------------- + // Decoding routines: these extract an item earlier encoded using + // the corresponding WriteXXX() routines above. The item is read + // from "*src"; "*src" is modified to point past the decoded item; + // and if "result" is non-NULL, "*result" is modified to contain the + // result. In case of string result, the decoded string is appended to + // "*result". Returns true if the next item was read successfully, false + // otherwise. + + static bool ReadString(absl::string_view* src, std::string* result); + static bool ReadNumIncreasing(absl::string_view* src, uint64_t* result); + static bool ReadSignedNumIncreasing(absl::string_view* src, int64_t* result); + + static bool ReadInfinity(absl::string_view* src); + static bool ReadTrailingString(absl::string_view* src, std::string* result); + + /** REQUIRES: next item was encoded by WriteInfinity() or WriteString(). */ + static bool ReadStringOrInfinity(absl::string_view* src, + std::string* result, + bool* inf); + + /** + * Helper for testing: corrupt "*str" by changing the kth item separator + * in the string. + */ + static void TEST_Corrupt(std::string* str, int k); + + /** + * Helper for testing. + * SkipToNextSpecialByte is an internal routine defined in the .cc file + * with the following semantics. Return a pointer to the first byte + * in the range "[start..limit)" whose value is 0 or 255. If no such + * byte exists in the range, returns "limit". + */ + static const char* TEST_SkipToNextSpecialByte(const char* start, + const char* limit); + + // Not an instantiable class, but the class exists to make it easy to + // use with a single using statement. + OrderedCode() = delete; + OrderedCode(const OrderedCode&) = delete; + OrderedCode& operator=(const OrderedCode&) = delete; +}; + +} // namespace util +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_ORDERED_CODE_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/path.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/path.cc new file mode 100644 index 0000000..0d2d33d --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/path.cc @@ -0,0 +1,244 @@ +/* + * Copyright 2018 Google + * + * 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 "Firestore/core/src/firebase/firestore/util/path.h" + +#include + +#include "Firestore/core/src/firebase/firestore/util/hard_assert.h" +#include "Firestore/core/src/firebase/firestore/util/string_win.h" +#include "absl/strings/ascii.h" +#include "absl/strings/string_view.h" + +namespace firebase { +namespace firestore { +namespace util { + +constexpr size_t Path::npos; + +namespace { + +#if defined(_WIN32) +constexpr Path::char_type kPreferredSeparator = L'\\'; +#else +constexpr Path::char_type kPreferredSeparator = '/'; +#endif + +/** + * Returns the offset within the given path that skips the leading drive letter. + * If there is no drive letter, returns zero. + */ +size_t OffsetAfterDriveLetter(const Path::char_type* path, size_t size) { +#if defined(_WIN32) + if (size >= 2 && path[1] == L':') { + wchar_t drive_letter = path[0]; + if (drive_letter <= 0xFF && + absl::ascii_isalpha(static_cast(drive_letter))) { + return 2; + } + } + return 0; + +#else + (void)path; + (void)size; + return 0; +#endif // defined(_WIN32) +} + +/** Returns true if the given character is a pathname separator. */ +inline bool IsSeparator(Path::char_type c) { +#if defined(_WIN32) + return c == L'/' || c == L'\\'; +#else + return c == '/'; +#endif // defined(_WIN32) +} + +bool IsAbsolute(const Path::char_type* path, size_t size) { + size_t offset = OffsetAfterDriveLetter(path, size); + return size >= offset && IsSeparator(path[offset]); +} + +size_t LastNonSeparator(const Path::char_type* path, size_t size) { + if (size == 0) return Path::npos; + + for (size_t i = size; i-- > 0;) { + if (!IsSeparator(path[i])) { + return i; + } + } + return Path::npos; +} + +size_t LastSeparator(const Path::char_type* path, size_t size) { + if (size == 0) return Path::npos; + + for (size_t i = size; i-- > 0;) { + if (IsSeparator(path[i])) { + return i; + } + } + return Path::npos; +} + +#if defined(_WIN32) +Path::string_type CanonicalPath(const Path::string_type& path) { + if (path.empty()) { + return path; + } + + // Remove trailing separators, but take care not to remove the trailing slash + // in a root path name (which can have a drive letter). + std::wstring copy{path}; + size_t rel_path_begin = OffsetAfterDriveLetter(copy.c_str(), copy.size()); + if (rel_path_begin < copy.size() && IsSeparator(copy[rel_path_begin])) { + rel_path_begin += 1; + } + + size_t non_slash = LastNonSeparator(copy.c_str(), copy.size()); + if (non_slash != Path::npos) { + size_t last_slash = std::max(non_slash + 1, rel_path_begin); + copy.resize(last_slash); + } + + // Convert separators to canonical separators. + std::replace(copy.begin(), copy.end(), L'/', kPreferredSeparator); + + // Convert to lowercase. This relies on C++11 semantics of std::basic_string, + // namely that: + // * s.c_str(), s.data(), and &s[0] are all aliases for each other; + // * strings are always contiguous and null terminated; and + // * Accessing s[s.size()] is valid and is the null terminator. + errno_t error = _wcslwr_s(©[0], copy.size() + 1); + HARD_ASSERT(error == 0); + + return copy; +} + +#else +absl::string_view CanonicalPath(const Path::string_type& path) { + size_t non_slash = LastNonSeparator(path.c_str(), path.size()); + if (non_slash == Path::npos) { + return path; + } + + return absl::string_view{path.c_str(), non_slash + 1}; +} +#endif // defined(_WIN32) + +} // namespace + +Path Path::FromUtf8(absl::string_view utf8_pathname) { +#if defined(_WIN32) + return Path{Utf8ToNative(utf8_pathname)}; + +#else + return Path{std::string{utf8_pathname}}; +#endif // defined(_WIN32) +} + +#if defined(_WIN32) +Path Path::FromUtf16(const wchar_t* path, size_t size) { + return Path{string_type{path, size}}; +} +#endif + +#if defined(_WIN32) +std::string Path::ToUtf8String() const { + return NativeToUtf8(pathname_); +} +#else +const std::string& Path::ToUtf8String() const { + return pathname_; +} +#endif // defined(_WIN32) + +Path Path::Basename() const { + size_t slash = LastSeparator(c_str(), size()); + if (slash == npos) { + // No path separator found => the whole string. + return *this; + } + + // Otherwise everything after the slash is the basename (even if empty string) + size_t start = slash + 1; + return Path{pathname_.substr(start)}; +} + +Path Path::Dirname() const { + size_t last_slash = LastSeparator(c_str(), size()); + if (last_slash == npos) { + // No path separator found => empty string. Conformance with POSIX would + // have us return "." here. + return {}; + } + + // Collapse runs of slashes. + size_t non_slash = LastNonSeparator(c_str(), last_slash); + if (non_slash == npos) { + // All characters preceding the last path separator are slashes + return Path{pathname_.substr(0, 1)}; + } + + // Otherwise everything up to the slash is the parent directory + last_slash = non_slash + 1; + return Path{pathname_.substr(0, last_slash)}; +} + +bool Path::IsAbsolute() const { + return util::IsAbsolute(c_str(), size()); +} + +Path Path::AppendUtf8(absl::string_view path) const { + Path result{*this}; + result.MutableAppendUtf8(path); + return result; +} + +void Path::MutableAppendSegment(const char_type* path, size_t size) { + if (util::IsAbsolute(path, size)) { + pathname_.assign(path, size); + + } else { + size_t non_slash = LastNonSeparator(pathname_.c_str(), pathname_.size()); + if (non_slash != npos) { + pathname_.resize(non_slash + 1); + pathname_.push_back(kPreferredSeparator); + } + + // If path started with a slash we'd treat it as absolute above + pathname_.append(path, size); + } +} + +void Path::MutableAppendUtf8Segment(absl::string_view path) { +#if defined(_WIN32) + Path segment = Path::FromUtf8(path); + MutableAppendSegment(segment.c_str(), segment.size()); + +#else + MutableAppendSegment(path.data(), path.size()); +#endif +} + +bool operator==(const Path& lhs, const Path& rhs) { + return CanonicalPath(lhs.pathname_) == CanonicalPath(rhs.pathname_); +} + +} // namespace util +} // namespace firestore +} // namespace firebase diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/path.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/path.h new file mode 100644 index 0000000..cecbc88 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/path.h @@ -0,0 +1,216 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_PATH_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_PATH_H_ + +#include +#include + +#include "Firestore/core/src/firebase/firestore/util/string_apple.h" +#include "absl/strings/string_view.h" + +namespace firebase { +namespace firestore { +namespace util { + +/** + * An immutable native pathname string. Paths can be absolute or relative. Paths + * internally maintain their filesystem-native encoding. + * + * The intent of the API is that high-level code generally just uses UTF-8- + * encoded string-literals or strings for the segments and constructs a + * filesystem-native Path using APIs like Path::JoinUtf8. + * + * Lower level code may need to construct derived Paths from values obtained + * from the filesystem that already are in the right encoding. + */ +class Path { + public: +#if defined(_WIN32) + using char_type = wchar_t; +#else + using char_type = char; +#endif + + using string_type = std::basic_string; + + static constexpr size_t npos = static_cast(-1); + + /** + * Creates a new Path from a UTF-8-encoded pathname. + */ + static Path FromUtf8(absl::string_view utf8_pathname); + +#if defined(_WIN32) + /** + * Creates a new Path from a UTF-16-encoded pathname. + */ + // absl::wstring_view does not exist :-(. + static Path FromUtf16(const wchar_t* begin, size_t size); +#endif + +#if defined(__OBJC__) + /** + * Creates a new Path from the given NSString pathname. + */ + static Path FromNSString(NSString* path) { + return FromUtf8(MakeString(path)); + } +#endif + + Path() { + } + + const string_type& native_value() const { + return pathname_; + } + + const char_type* c_str() const { + return pathname_.c_str(); + } + + size_t size() const { + return pathname_.size(); + } + +#if defined(_WIN32) + std::string ToUtf8String() const; +#else + const std::string& ToUtf8String() const; +#endif // defined(_WIN32) + +#if defined(__OBJC__) + NSString* ToNSString() const { + return WrapNSString(native_value()); + } +#endif + + /** + * Returns a new Path containing the unqualified trailing part of this path, + * e.g. "c" for "/a/b/c". + */ + Path Basename() const; + + /** + * Returns a new Path containing the parent directory of this path, e.g. + * "/a/b" for "/a/b/c". + * + * Note: + * * Trailing slashes are treated as a separator between an empty path + * segment and the dirname, so the Dirname of "/a/b/c/" is "/a/b/c". + * * Runs of more than one slash are treated as a single separator, so + * the Dirname of "/a/b//c" is "/a/b". + * * Paths are not canonicalized, so the Dirname of "/a//b//c" is "/a//b". + */ + Path Dirname() const; + + /** + * Returns true if this Path is an absolute path. + */ + bool IsAbsolute() const; + + /** + * Returns a new Path with the given UTF-8 encoded path segment appended, + * as if by calling `Append(Path::FromUtf8(path))`. + */ + Path AppendUtf8(absl::string_view path) const; + Path AppendUtf8(const char* path, size_t size) const { + return AppendUtf8(absl::string_view{path, size}); + } + +#if defined(_WIN32) + Path AppendUtf16(const wchar_t* path, size_t size) const { + Path result{*this}; + result.MutableAppendSegment(path, size); + return result; + } +#endif + + /** + * Returns the paths separated by path separators. + * + * @param base If base is of type std::string&& the result is moved from this + * value. Otherwise the first argument is copied. + * @param paths The rest of the path segments. + */ + template + static Path JoinUtf8(P1&& base, const PA&... paths) { + Path result = Path::FromUtf8(base); + result.MutableAppendUtf8(paths...); + return result; + } + + friend bool operator==(const Path& lhs, const Path& rhs); + friend bool operator!=(const Path& lhs, const Path& rhs) { + return !(lhs == rhs); + } + + private: + explicit Path(string_type&& native_pathname) + : pathname_{std::move(native_pathname)} { + } + + /** + * If `path` is relative, appends it to `*this`. If `path` is absolute, + * replaces `*this`. + */ + template + void MutableAppend(const Path& path, const P&... rest) { + MutableAppendSegment(path.c_str(), path.size()); + MutableAppend(rest...); + } + void MutableAppend() { + // Recursive base case; nothing to do. + } + void MutableAppendSegment(const char_type* path, size_t size); + + /** + * If `path` is relative, appends it to `*this`. If `path` is absolute, + * replaces `*this`. + */ + template + void MutableAppendUtf8(const P1& path, const P&... rest) { + MutableAppendUtf8Segment(path); + MutableAppendUtf8(rest...); + } + void MutableAppendUtf8Segment(absl::string_view path); + void MutableAppendUtf8Segment(const Path& path) { + // Allow existing Paths to be passed to Path::JoinUtf8. + MutableAppendSegment(path.c_str(), path.size()); + } + void MutableAppendUtf8() { + // Recursive base case; nothing to do. + } + + /** + * Returns a copy of the given path. + * + * This non-public variant of FromUtf8 allows JoinUtf8 to take a Path as its + * first argument. + */ + static Path FromUtf8(const Path& path) { + return path; + } + + string_type pathname_; +}; + +} // namespace util +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_PATH_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/range.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/range.h new file mode 100644 index 0000000..9e96c67 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/range.h @@ -0,0 +1,78 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_RANGE_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_RANGE_H_ + +#include +#include + +namespace firebase { +namespace firestore { +namespace util { + +/** + * Adapts a pair of iterators into a range suitable for use with range-based + * for loops. + */ +template +class range { + public: + using value_type = typename std::iterator_traits::value_type; + using iterator = Iterator; + using const_iterator = Iterator; + + /** + * Default range which constructs default begin and end pointers. For most + * implementations where the end pointer is a null pointer or some other + * default value, this ends up constructing the empty range. + */ + range() : begin_{}, end_{} { + } + + /** + * Creates a half-open range starting from begin up to, but not including end. + */ + range(iterator&& begin, iterator&& end) + : begin_{std::move(begin)}, end_{std::move(end)} { + } + + iterator begin() const { + return begin_; + } + + iterator end() const { + return end_; + } + + private: + Iterator begin_; + Iterator end_; +}; + +/** + * Creates ranges with type deduction. + */ +template +range make_range(Iterator begin, Iterator end) { + return range{std::move(begin), std::move(end)}; +} + +} // namespace util +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_RANGE_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/secure_random.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/secure_random.h new file mode 100644 index 0000000..f030b5e --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/secure_random.h @@ -0,0 +1,75 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_SECURE_RANDOM_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_SECURE_RANDOM_H_ + +#include + +#include + +namespace firebase { +namespace firestore { +namespace util { + +// A "secure" pseudorandom number generator, suitable for generating +// unguessable identifiers. This exists because +// +// * std::mt19937 is blazing fast but its outputs can be guessed once enough +// previous outputs have been observed. +// * std::random_device isn't guaranteed to come from a secure PRNG or be +// fast. +// +// The implementation satisfies the C++11 UniformRandomBitGenerator concept and +// delegates to an implementation that generates high quality random values +// quickly with periodic reseeding. +class SecureRandom { + public: + // C++11 UniformRandomBitGenerator interface + using result_type = uint32_t; + + static constexpr result_type min() { + return std::numeric_limits::min(); + } + + static constexpr result_type max() { + return std::numeric_limits::max(); + } + + result_type operator()(); + + /** Returns a uniformly distributed pseudorandom integer in [0, n). */ + inline result_type Uniform(result_type n) { + // Divides the range into buckets of size n plus leftovers. + const result_type rem = (max() - min()) % n + min() + 1; + result_type rnd; + // Generates random number until the number falls into a bucket. + do { + rnd = (*this)(); + } while (rnd < rem); + return rnd % n; + } + + inline bool OneIn(result_type n) { + return Uniform(n) == 0; + } +}; + +} // namespace util +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_SECURE_RANDOM_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/secure_random_arc4random.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/secure_random_arc4random.cc new file mode 100644 index 0000000..d7e9be3 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/secure_random_arc4random.cc @@ -0,0 +1,37 @@ +/* + * Copyright 2017 Google + * + * 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 "Firestore/core/src/firebase/firestore/util/secure_random.h" + +#include "Firestore/core/src/firebase/firestore/util/config.h" + +#if HAVE_ARC4RANDOM + +#include + +namespace firebase { +namespace firestore { +namespace util { + +SecureRandom::result_type SecureRandom::operator()() { + return arc4random(); +} + +} // namespace util +} // namespace firestore +} // namespace firebase + +#endif // HAVE_ARC4RANDOM diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/status.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/status.cc new file mode 100644 index 0000000..06a643d --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/status.cc @@ -0,0 +1,152 @@ +/* + * Copyright 2015, 2018 Google + * + * 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 "Firestore/core/src/firebase/firestore/util/status.h" + +#include + +#include "Firestore/core/src/firebase/firestore/util/string_format.h" +#include "absl/memory/memory.h" + +namespace firebase { +namespace firestore { +namespace util { + +Status::Status(FirestoreErrorCode code, absl::string_view msg) { + HARD_ASSERT(code != FirestoreErrorCode::Ok); + state_ = absl::make_unique(); + state_->code = code; + state_->msg = static_cast(msg); +} + +void Status::Update(const Status& new_status) { + if (ok()) { + *this = new_status; + } +} + +Status& Status::CausedBy(const Status& cause) { + if (cause.ok() || this == &cause) { + return *this; + } + + if (ok()) { + *this = cause; + return *this; + } + + absl::StrAppend(&state_->msg, ": ", cause.error_message()); + return *this; +} + +void Status::SlowCopyFrom(const State* src) { + if (src == nullptr) { + state_ = nullptr; + } else { + state_ = absl::make_unique(*src); + } +} + +const std::string& Status::empty_string() { + static std::string* empty = new std::string; + return *empty; +} + +std::string Status::ToString() const { + if (state_ == nullptr) { + return "OK"; + } else { + std::string result; + switch (code()) { + case FirestoreErrorCode::Cancelled: + result = "Cancelled"; + break; + case FirestoreErrorCode::Unknown: + result = "Unknown"; + break; + case FirestoreErrorCode::InvalidArgument: + result = "Invalid argument"; + break; + case FirestoreErrorCode::DeadlineExceeded: + result = "Deadline exceeded"; + break; + case FirestoreErrorCode::NotFound: + result = "Not found"; + break; + case FirestoreErrorCode::AlreadyExists: + result = "Already exists"; + break; + case FirestoreErrorCode::PermissionDenied: + result = "Permission denied"; + break; + case FirestoreErrorCode::Unauthenticated: + result = "Unauthenticated"; + break; + case FirestoreErrorCode::ResourceExhausted: + result = "Resource exhausted"; + break; + case FirestoreErrorCode::FailedPrecondition: + result = "Failed precondition"; + break; + case FirestoreErrorCode::Aborted: + result = "Aborted"; + break; + case FirestoreErrorCode::OutOfRange: + result = "Out of range"; + break; + case FirestoreErrorCode::Unimplemented: + result = "Unimplemented"; + break; + case FirestoreErrorCode::Internal: + result = "Internal"; + break; + case FirestoreErrorCode::Unavailable: + result = "Unavailable"; + break; + case FirestoreErrorCode::DataLoss: + result = "Data loss"; + break; + default: + result = StringFormat("Unknown code(%s)", code()); + break; + } + result += ": "; + result += state_->msg; + return result; + } +} + +std::ostream& operator<<(std::ostream& out, const Status& status) { + out << status.ToString(); + return out; +} + +void Status::IgnoreError() const { + // no-op +} + +std::string StatusCheckOpHelperOutOfLine(const Status& v, const char* msg) { + HARD_ASSERT(!v.ok()); + std::string r("Non-OK-status: "); + r += msg; + r += " status: "; + r += v.ToString(); + return r; +} + +} // namespace util +} // namespace firestore +} // namespace firebase diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/status.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/status.h new file mode 100644 index 0000000..d49089e --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/status.h @@ -0,0 +1,155 @@ +/* + * Copyright 2015, 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_STATUS_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_STATUS_H_ + +#if defined(_WIN32) +#include +#endif + +#include +#include +#include +#include + +#include "Firestore/core/include/firebase/firestore/firestore_errors.h" +#include "Firestore/core/src/firebase/firestore/util/hard_assert.h" +#include "absl/base/attributes.h" +#include "absl/strings/string_view.h" + +namespace firebase { +namespace firestore { +namespace util { + +/// Denotes success or failure of a call. +class ABSL_MUST_USE_RESULT Status { + public: + /// Create a success status. + Status() { + } + + /// \brief Create a status with the specified error code and msg as a + /// human-readable string containing more detailed information. + Status(FirestoreErrorCode code, absl::string_view msg); + + /// Copy the specified status. + Status(const Status& s); + void operator=(const Status& s); + + static Status OK() { + return Status(); + } + + /// Creates a status object from the given errno error code and message. + static Status FromErrno(int errno_code, absl::string_view message); + +#if defined(_WIN32) + static Status FromLastError(DWORD error, absl::string_view message); +#endif // defined(_WIN32) + +#if defined(__OBJC__) + static Status FromNSError(NSError* error); +#endif // defined(__OBJC__) + + /// Returns true iff the status indicates success. + bool ok() const { + return (state_ == nullptr); + } + + FirestoreErrorCode code() const { + return ok() ? FirestoreErrorCode::Ok : state_->code; + } + + const std::string& error_message() const { + return ok() ? empty_string() : state_->msg; + } + + bool operator==(const Status& x) const; + bool operator!=(const Status& x) const; + + /// \brief If `ok()`, stores `new_status` into `*this`. If `!ok()`, + /// preserves the current status, but may augment with additional + /// information about `new_status`. + /// + /// Convenient way of keeping track of the first error encountered. + /// Instead of: + /// `if (overall_status.ok()) overall_status = new_status` + /// Use: + /// `overall_status.Update(new_status);` + void Update(const Status& new_status); + + /// \brief Adds the message in the given cause to this Status. + /// + /// \return *this + Status& CausedBy(const Status& cause); + + /// \brief Return a string representation of this status suitable for + /// printing. Returns the string `"OK"` for success. + std::string ToString() const; + friend std::ostream& operator<<(std::ostream& out, const Status& status); + + // Ignores any errors. This method does nothing except potentially suppress + // complaints from any tools that are checking that errors are not dropped on + // the floor. + void IgnoreError() const; + + private: + static const std::string& empty_string(); + struct State { + FirestoreErrorCode code; + std::string msg; + }; + // OK status has a `NULL` state_. Otherwise, `state_` points to + // a `State` structure containing the error code and message(s) + std::unique_ptr state_; + + void SlowCopyFrom(const State* src); +}; + +inline Status::Status(const Status& s) + : state_((s.state_ == nullptr) ? nullptr : new State(*s.state_)) { +} + +inline void Status::operator=(const Status& s) { + // The following condition catches both aliasing (when this == &s), + // and the common case where both s and *this are ok. + if (state_ != s.state_) { + SlowCopyFrom(s.state_.get()); + } +} + +inline bool Status::operator==(const Status& x) const { + return (this->state_ == x.state_) || (ToString() == x.ToString()); +} + +inline bool Status::operator!=(const Status& x) const { + return !(*this == x); +} + +typedef std::function StatusCallback; + +extern std::string StatusCheckOpHelperOutOfLine(const Status& v, + const char* msg); + +#define STATUS_CHECK_OK(val) \ + HARD_ASSERT(val.ok(), "%s", StatusCheckOpHelperOutOfLine(val, #val)) + +} // namespace util +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_STATUS_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/status_apple.mm b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/status_apple.mm new file mode 100644 index 0000000..f0bf7a6 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/status_apple.mm @@ -0,0 +1,51 @@ +/* + * Copyright 2018 Google + * + * 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 "Firestore/core/src/firebase/firestore/util/status.h" + +#if defined(__APPLE__) + +#include "Firestore/core/src/firebase/firestore/util/string_format.h" + +namespace firebase { +namespace firestore { +namespace util { + +Status Status::FromNSError(NSError* error) { + if (!error) { + return Status::OK(); + } + + NSError* original = error; + + while (error) { + if ([error.domain isEqualToString:NSPOSIXErrorDomain]) { + return FromErrno(static_cast(error.code), + MakeString(original.localizedDescription)); + } + + error = error.userInfo[NSUnderlyingErrorKey]; + } + + return Status{FirestoreErrorCode::Unknown, + StringFormat("Unknown error: %s", original)}; +} + +} // namespace util +} // namespace firestore +} // namespace firebase + +#endif // defined(__APPLE__) diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/status_posix.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/status_posix.cc new file mode 100644 index 0000000..79c651b --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/status_posix.cc @@ -0,0 +1,195 @@ +/* + * Copyright 2018 Google + * + * 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 "Firestore/core/src/firebase/firestore/util/status.h" + +#include + +#include "Firestore/core/src/firebase/firestore/util/strerror.h" +#include "Firestore/core/src/firebase/firestore/util/string_format.h" + +namespace firebase { +namespace firestore { +namespace util { + +/// Returns the Canonical error code for the given errno value. +static FirestoreErrorCode CodeForErrno(int errno_code) { + switch (errno_code) { + case 0: + return FirestoreErrorCode::Ok; + + // Internal canonical mappings call these failed preconditions, but for + // our purposes these must indicate an internal error in file handling. + case EBADF: // Invalid file descriptor +#if defined(EBADFD) + case EBADFD: // File descriptor in bad state +#endif + return FirestoreErrorCode::Internal; + + case EINVAL: // Invalid argument + case ENAMETOOLONG: // Filename too long + case E2BIG: // Argument list too long + case EDESTADDRREQ: // Destination address required + case EDOM: // Mathematics argument out of domain of function + case EFAULT: // Bad address + case EILSEQ: // Illegal byte sequence + case ENOPROTOOPT: // Protocol not available + case ENOSTR: // Not a STREAM + case ENOTSOCK: // Not a socket + case ENOTTY: // Inappropriate I/O control operation + case EPROTOTYPE: // Protocol wrong type for socket + case ESPIPE: // Invalid seek + return FirestoreErrorCode::InvalidArgument; + + case ETIMEDOUT: // Connection timed out + case ETIME: // Timer expired + return FirestoreErrorCode::DeadlineExceeded; + + case ENODEV: // No such device + case ENOENT: // No such file or directory +#if defined(ENOMEDIUM) + case ENOMEDIUM: // No medium found +#endif + case ENXIO: // No such device or address + case ESRCH: // No such process + return FirestoreErrorCode::NotFound; + + case EEXIST: // File exists + case EADDRNOTAVAIL: // Address not available + case EALREADY: // Connection already in progress +#if defined(ENOTUNIQ) + case ENOTUNIQ: // Name not unique on network +#endif + return FirestoreErrorCode::AlreadyExists; + + case EPERM: // Operation not permitted + case EACCES: // Permission denied +#if defined(ENOKEY) + case ENOKEY: // Required key not available +#endif + case EROFS: // Read only file system + return FirestoreErrorCode::PermissionDenied; + + case ENOTEMPTY: // Directory not empty + case EISDIR: // Is a directory + case ENOTDIR: // Not a directory + case EADDRINUSE: // Address already in use + case EBUSY: // Device or resource busy + case ECHILD: // No child processes + case EISCONN: // Socket is connected +#if defined(EISNAM) + case EISNAM: // Is a named type file +#endif +#if defined(ENOTBLK) + case ENOTBLK: // Block device required +#endif + case ENOTCONN: // The socket is not connected + case EPIPE: // Broken pipe +#if defined(ESHUTDOWN) + case ESHUTDOWN: // Cannot send after transport endpoint shutdown +#endif + case ETXTBSY: // Text file busy +#if defined(EUNATCH) + case EUNATCH: // Protocol driver not attached +#endif + return FirestoreErrorCode::FailedPrecondition; + + case ENOSPC: // No space left on device +#if defined(EDQUOT) + case EDQUOT: // Disk quota exceeded +#endif + case EMFILE: // Too many open files + case EMLINK: // Too many links + case ENFILE: // Too many open files in system + case ENOBUFS: // No buffer space available + case ENODATA: // No message is available on the STREAM read queue + case ENOMEM: // Not enough space + case ENOSR: // No STREAM resources +#if defined(EUSERS) + case EUSERS: // Too many users +#endif + return FirestoreErrorCode::ResourceExhausted; + +#if defined(ECHRNG) + case ECHRNG: // Channel number out of range +#endif + case EFBIG: // File too large + case EOVERFLOW: // Value too large to be stored in data type + case ERANGE: // Result too large + return FirestoreErrorCode::OutOfRange; + +#if defined(ENOPKG) + case ENOPKG: // Package not installed +#endif + case ENOSYS: // Function not implemented + case ENOTSUP: // Operation not supported + case EAFNOSUPPORT: // Address family not supported +#if defined(EPFNOSUPPORT) + case EPFNOSUPPORT: // Protocol family not supported +#endif + case EPROTONOSUPPORT: // Protocol not supported +#if defined(ESOCKTNOSUPPORT) + case ESOCKTNOSUPPORT: // Socket type not supported +#endif + case EXDEV: // Improper link + return FirestoreErrorCode::Unimplemented; + + case EAGAIN: // Resource temporarily unavailable +#if defined(ECOMM) + case ECOMM: // Communication error on send +#endif + case ECONNREFUSED: // Connection refused + case ECONNABORTED: // Connection aborted + case ECONNRESET: // Connection reset + case EINTR: // Interrupted function call +#if defined(EHOSTDOWN) + case EHOSTDOWN: // Host is down +#endif + case EHOSTUNREACH: // Host is unreachable + case ENETDOWN: // Network is down + case ENETRESET: // Connection aborted by network + case ENETUNREACH: // Network unreachable + case ENOLCK: // No locks available + case ENOLINK: // Link has been severed +#if defined(ENONET) + case ENONET: // Machine is not on the network +#endif + return FirestoreErrorCode::Unavailable; + + case EDEADLK: // Resource deadlock avoided +#if defined(ESTALE) + case ESTALE: // Stale file handle +#endif + return FirestoreErrorCode::Aborted; + + case ECANCELED: // Operation cancelled + return FirestoreErrorCode::Cancelled; + + default: + return FirestoreErrorCode::Unknown; + } +} + +Status Status::FromErrno(int errno_code, absl::string_view msg) { + FirestoreErrorCode canonical_code = CodeForErrno(errno_code); + return Status{canonical_code, + util::StringFormat("%s (errno %s: %s)", msg, errno_code, + StrError(errno_code))}; +} + +} // namespace util +} // namespace firestore +} // namespace firebase diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/status_win.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/status_win.cc new file mode 100644 index 0000000..a268da2 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/status_win.cc @@ -0,0 +1,106 @@ +/* + * Copyright 2018 Google + * + * 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 "Firestore/core/src/firebase/firestore/util/status.h" + +#if defined(_WIN32) + +#include "Firestore/core/src/firebase/firestore/util/string_format.h" +#include "Firestore/core/src/firebase/firestore/util/string_win.h" + +namespace firebase { +namespace firestore { +namespace util { + +/** + * Returns the Canonical error code for the given Windows API error code as + * obtained from GetLastError(). + */ +static FirestoreErrorCode CodeForLastError(DWORD error) { + switch (error) { + case ERROR_SUCCESS: + return FirestoreErrorCode::Ok; + + // return FirestoreErrorCode::Internal; + + case ERROR_INVALID_FUNCTION: + case ERROR_INVALID_HANDLE: + case ERROR_INVALID_NAME: + return FirestoreErrorCode::InvalidArgument; + + // return FirestoreErrorCode::DeadlineExceeded; + + case ERROR_FILE_NOT_FOUND: + case ERROR_PATH_NOT_FOUND: + case ERROR_INVALID_DRIVE: + case ERROR_BAD_NETPATH: + case ERROR_DEV_NOT_EXIST: + return FirestoreErrorCode::NotFound; + + case ERROR_FILE_EXISTS: + case ERROR_ALREADY_EXISTS: + return FirestoreErrorCode::AlreadyExists; + + case ERROR_ACCESS_DENIED: + case ERROR_INVALID_ACCESS: + case ERROR_SHARING_VIOLATION: + case ERROR_WRITE_PROTECT: + case ERROR_LOCK_VIOLATION: + return FirestoreErrorCode::PermissionDenied; + + // return FirestoreErrorCode::FailedPrecondition; + + case ERROR_TOO_MANY_OPEN_FILES: + case ERROR_NOT_ENOUGH_MEMORY: + case ERROR_OUTOFMEMORY: + case ERROR_NO_MORE_FILES: + case ERROR_DISK_FULL: + case ERROR_HANDLE_DISK_FULL: + return FirestoreErrorCode::ResourceExhausted; + + // return FirestoreErrorCode::OutOfRange; + + case ERROR_CALL_NOT_IMPLEMENTED: + return FirestoreErrorCode::Unimplemented; + + case ERROR_NOT_READY: + return FirestoreErrorCode::Unavailable; + + // return FirestoreErrorCode::Aborted; + + // return FirestoreErrorCode::Cancelled; + + default: + return FirestoreErrorCode::Unknown; + } +} + +Status Status::FromLastError(DWORD error, absl::string_view msg) { + if (error == ERROR_SUCCESS) { + return Status::OK(); + } + + FirestoreErrorCode canonical_code = CodeForLastError(error); + std::string error_text = LastErrorMessage(error); + return Status{canonical_code, util::StringFormat("%s (error %s: %s)", msg, + error, error_text)}; +} + +} // namespace util +} // namespace firestore +} // namespace firebase + +#endif // defined(_WIN32) diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/statusor.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/statusor.cc new file mode 100644 index 0000000..bbd5781 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/statusor.cc @@ -0,0 +1,41 @@ +/* + * Copyright 2017, 2018 Google + * + * 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 "Firestore/core/src/firebase/firestore/util/statusor.h" +#include "Firestore/core/src/firebase/firestore/util/hard_assert.h" + +namespace firebase { +namespace firestore { +namespace util { +namespace internal_statusor { + +void Helper::HandleInvalidStatusCtorArg(Status* status) { + const char* kMessage = + "An OK status is not a valid constructor argument to StatusOr"; + HARD_FAIL("%s", kMessage); + // Fall back to Internal for non-debug builds + *status = Status(FirestoreErrorCode::Internal, kMessage); +} + +void Helper::Crash(const Status& status) { + HARD_FAIL("Attempting to fetch value instead of handling error %s", + status.ToString()); +} + +} // namespace internal_statusor +} // namespace util +} // namespace firestore +} // namespace firebase diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/statusor.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/statusor.h new file mode 100644 index 0000000..9985956 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/statusor.h @@ -0,0 +1,323 @@ +/* + * Copyright 2017, 2018 Google + * + * 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. + */ + +// StatusOr is the union of a Status object and a T +// object. StatusOr models the concept of an object that is either a +// usable value, or an error Status explaining why such a value is +// not present. To this end, StatusOr does not allow its Status +// value to be Status::OK. Furthermore, the value of a StatusOr +// must not be null. This is enforced by a debug check in most cases, +// but even when it is not, clients must not set the value to null. +// +// The primary use-case for StatusOr is as the return value of a +// function which may fail. +// +// Example client usage for a StatusOr, where T is not a pointer: +// +// StatusOr result = DoBigCalculationThatCouldFail(); +// if (result.ok()) { +// float answer = result.ValueOrDie(); +// printf("Big calculation yielded: %f", answer); +// } else { +// LOG(ERROR) << result.status(); +// } +// +// Example client usage for a StatusOr: +// +// StatusOr result = FooFactory::MakeNewFoo(arg); +// if (result.ok()) { +// std::unique_ptr foo(result.ValueOrDie()); +// foo->DoSomethingCool(); +// } else { +// LOG(ERROR) << result.status(); +// } +// +// Example client usage for a StatusOr>: +// +// StatusOr> result = FooFactory::MakeNewFoo(arg); +// if (result.ok()) { +// std::unique_ptr foo = std::move(result.ValueOrDie()); +// foo->DoSomethingCool(); +// } else { +// LOG(ERROR) << result.status(); +// } +// +// Example factory implementation returning StatusOr: +// +// StatusOr FooFactory::MakeNewFoo(int arg) { +// if (arg <= 0) { +// return Status(FirestoreErrorCode::InvalidArgument, +// "Arg must be positive"); +// } else { +// return new Foo(arg); +// } +// } +// +// Note that the assignment operators require that destroying the currently +// stored value cannot invalidate the argument; in other words, the argument +// cannot be an alias for the current value, or anything owned by the current +// value. + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_STATUSOR_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_STATUSOR_H_ + +#include + +#include "Firestore/core/include/firebase/firestore/firestore_errors.h" +#include "Firestore/core/src/firebase/firestore/util/status.h" +#include "Firestore/core/src/firebase/firestore/util/statusor_internals.h" +#include "absl/base/attributes.h" +#include "absl/strings/string_view.h" + +namespace firebase { +namespace firestore { +namespace util { + +template +class ABSL_MUST_USE_RESULT StatusOr + : private internal_statusor::StatusOrData, + private internal_statusor::TraitsBase< + std::is_copy_constructible::value, + std::is_move_constructible::value> { + template + friend class StatusOr; + + typedef internal_statusor::StatusOrData Base; + + public: + typedef T element_type; + + // Constructs a new StatusOr with FirebaseErrorCode::Unknown status. This is + // marked 'explicit' to try to catch cases like 'return {};', where people + // think StatusOr> will be initialized with an empty vector, + // instead of a FirebaseErrorCode::Unknown status. + explicit StatusOr(); // NOLINT: allow explicit zero-parameter ctor + + // StatusOr will be copy constructible/assignable if T is copy + // constructible. + StatusOr(const StatusOr&) = default; + StatusOr& operator=(const StatusOr&) = default; + + // StatusOr will be move constructible/assignable if T is move + // constructible. + StatusOr(StatusOr&&) = default; + StatusOr& operator=(StatusOr&&) = default; + + // Conversion copy/move constructor, T must be convertible from U. + // TODO(b/62186717): These should not participate in overload resolution if U + // is not convertible to T. + template + StatusOr(const StatusOr& other); + template + StatusOr(StatusOr&& other); + + // Conversion copy/move assignment operator, T must be convertible from U. + template + StatusOr& operator=(const StatusOr& other); + template + StatusOr& operator=(StatusOr&& other); + + // Constructs a new StatusOr with the given value. After calling this + // constructor, calls to ValueOrDie() will succeed, and calls to status() will + // return OK. + // + // NOTE: Not explicit - we want to use StatusOr as a return type + // so it is convenient and sensible to be able to do 'return T()' + // when the return type is StatusOr. + // + // REQUIRES: T is copy constructible. + StatusOr(const T& value); // NOLINT: allow non-explicit 1-param ctor + + // Constructs a new StatusOr with the given non-ok status. After calling + // this constructor, calls to ValueOrDie() will CHECK-fail. + // + // NOTE: Not explicit - we want to use StatusOr as a return + // value, so it is convenient and sensible to be able to do 'return + // Status()' when the return type is StatusOr. + // + // REQUIRES: !status.ok(). This requirement is DCHECKed. + // In optimized builds, passing Status::OK() here will have the effect + // of passing FirestoreErrorCode::Internal as a fallback. + StatusOr(const Status& status); // NOLINT: allow non-explicit 1-param ctor + StatusOr& operator=(const Status& status); + + // TODO(b/62186997): Add operator=(T) overloads. + + // Similar to the `const T&` overload. + // + // REQUIRES: T is move constructible. + StatusOr(T&& value); // NOLINT: allow non-explicit 1-param ctor + + // RValue versions of the operations declared above. + StatusOr(Status&& status); // NOLINT: allow non-explicit 1-param ctor + StatusOr& operator=(Status&& status); + + // Returns this->status().ok() + bool ok() const { + return this->status_.ok(); + } + + // Returns a reference to our status. If this contains a T, then + // returns Status::OK(). + const Status& status() const&; + Status status() &&; + + // Returns a reference to our current value, or CHECK-fails if !this->ok(). + // + // Note: for value types that are cheap to copy, prefer simple code: + // + // T value = statusor.ValueOrDie(); + // + // Otherwise, if the value type is expensive to copy, but can be left + // in the StatusOr, simply assign to a reference: + // + // T& value = statusor.ValueOrDie(); // or `const T&` + // + // Otherwise, if the value type supports an efficient move, it can be + // used as follows: + // + // T value = std::move(statusor).ValueOrDie(); + // + // The std::move on statusor instead of on the whole expression enables + // warnings about possible uses of the statusor object after the move. + // C++ style guide waiver for ref-qualified overloads granted in cl/143176389 + // See go/ref-qualifiers for more details on such overloads. + const T& ValueOrDie() const&; + T& ValueOrDie() &; + const T&& ValueOrDie() const&&; + T&& ValueOrDie() &&; + + T ConsumeValueOrDie() { + return std::move(ValueOrDie()); + } + + // Ignores any errors. This method does nothing except potentially suppress + // complaints from any tools that are checking that errors are not dropped on + // the floor. + void IgnoreError() const; +}; + +//////////////////////////////////////////////////////////////////////////////// +// Implementation details for StatusOr + +template +StatusOr::StatusOr() : Base(Status(FirestoreErrorCode::Unknown, "")) { +} + +template +StatusOr::StatusOr(const T& value) : Base(value) { +} + +template +StatusOr::StatusOr(const Status& status) : Base(status) { +} + +template +StatusOr& StatusOr::operator=(const Status& status) { + this->Assign(status); + return *this; +} + +template +StatusOr::StatusOr(T&& value) : Base(std::move(value)) { +} + +template +StatusOr::StatusOr(Status&& status) : Base(std::move(status)) { +} + +template +StatusOr& StatusOr::operator=(Status&& status) { + this->Assign(std::move(status)); + return *this; +} + +template +template +inline StatusOr::StatusOr(const StatusOr& other) + : Base(static_cast::Base&>(other)) { +} + +template +template +inline StatusOr& StatusOr::operator=(const StatusOr& other) { + if (other.ok()) + this->Assign(other.ValueOrDie()); + else + this->Assign(other.status()); + return *this; +} + +template +template +inline StatusOr::StatusOr(StatusOr&& other) + : Base(static_cast::Base&&>(other)) { +} + +template +template +inline StatusOr& StatusOr::operator=(StatusOr&& other) { + if (other.ok()) { + this->Assign(std::move(other).ValueOrDie()); + } else { + this->Assign(std::move(other).status()); + } + return *this; +} + +template +const Status& StatusOr::status() const& { + return this->status_; +} +template +Status StatusOr::status() && { + return ok() ? Status::OK() : std::move(this->status_); +} + +template +const T& StatusOr::ValueOrDie() const& { + this->EnsureOk(); + return this->data_; +} + +template +T& StatusOr::ValueOrDie() & { + this->EnsureOk(); + return this->data_; +} + +template +const T&& StatusOr::ValueOrDie() const&& { + this->EnsureOk(); + return std::move(this->data_); +} + +template +T&& StatusOr::ValueOrDie() && { + this->EnsureOk(); + return std::move(this->data_); +} + +template +void StatusOr::IgnoreError() const { + // no-op +} + +} // namespace util +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_STATUSOR_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/statusor_callback.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/statusor_callback.h new file mode 100644 index 0000000..ff39b5d --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/statusor_callback.h @@ -0,0 +1,35 @@ +/* + * Copyright 2019 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_STATUSOR_CALLBACK_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_STATUSOR_CALLBACK_H_ + +#include + +#include "Firestore/core/src/firebase/firestore/util/statusor.h" + +namespace firebase { +namespace firestore { +namespace util { + +template +using StatusOrCallback = std::function)>; + +} // namespace util +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_STATUSOR_CALLBACK_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/statusor_internals.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/statusor_internals.h new file mode 100644 index 0000000..d6c8de1 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/statusor_internals.h @@ -0,0 +1,258 @@ +/* + * Copyright 2017, 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_STATUSOR_INTERNALS_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_STATUSOR_INTERNALS_H_ + +#include + +#include "Firestore/core/src/firebase/firestore/util/status.h" +#include "absl/base/attributes.h" + +namespace firebase { +namespace firestore { +namespace util { +namespace internal_statusor { + +class Helper { + public: + // Move type-agnostic error handling to the .cc. + static void HandleInvalidStatusCtorArg(Status*); + ABSL_ATTRIBUTE_NORETURN static void Crash(const Status& status); +}; + +// Construct an instance of T in `p` through placement new, passing Args... to +// the constructor. +// This abstraction is here mostly for the gcc performance fix. +template +void PlacementNew(void* p, Args&&... args) { +#if defined(__GNUC__) && !defined(__clang__) + // Teach gcc that 'p' cannot be null, fixing code size issues. + if (p == nullptr) __builtin_unreachable(); +#endif + new (p) T(std::forward(args)...); +} + +// Helper base class to hold the data and all operations. +// We move all this to a base class to allow mixing with the appropriate +// TraitsBase specialization. +template +class StatusOrData { + template + friend class StatusOrData; + + public: + StatusOrData() = delete; + + StatusOrData(const StatusOrData& other) { + if (other.ok()) { + MakeValue(other.data_); + MakeStatus(); + } else { + MakeStatus(other.status_); + } + } + + StatusOrData(StatusOrData&& other) noexcept { + if (other.ok()) { + MakeValue(std::move(other.data_)); + MakeStatus(); + } else { + MakeStatus(std::move(other.status_)); + } + } + + template + StatusOrData(const StatusOrData& other) { + if (other.ok()) { + MakeValue(other.data_); + MakeStatus(); + } else { + MakeStatus(other.status_); + } + } + + template + StatusOrData(StatusOrData&& other) { + if (other.ok()) { + MakeValue(std::move(other.data_)); + MakeStatus(); + } else { + MakeStatus(std::move(other.status_)); + } + } + + explicit StatusOrData(const T& value) : data_(value) { + MakeStatus(); + } + explicit StatusOrData(T&& value) : data_(std::move(value)) { + MakeStatus(); + } + + explicit StatusOrData(const Status& status) : status_(status) { + EnsureNotOk(); + } + explicit StatusOrData(Status&& status) : status_(std::move(status)) { + EnsureNotOk(); + } + + StatusOrData& operator=(const StatusOrData& other) { + if (this == &other) return *this; + if (other.ok()) + Assign(other.data_); + else + Assign(other.status_); + return *this; + } + + StatusOrData& operator=(StatusOrData&& other) { + if (this == &other) return *this; + if (other.ok()) + Assign(std::move(other.data_)); + else + Assign(std::move(other.status_)); + return *this; + } + + ~StatusOrData() { + if (ok()) { + status_.~Status(); + data_.~T(); + } else { + status_.~Status(); + } + } + + void Assign(const T& value) { + if (ok()) { + data_.~T(); + MakeValue(value); + } else { + MakeValue(value); + status_ = Status::OK(); + } + } + + void Assign(T&& value) { + if (ok()) { + data_.~T(); + MakeValue(std::move(value)); + } else { + MakeValue(std::move(value)); + status_ = Status::OK(); + } + } + + void Assign(const Status& status) { + Clear(); + status_ = status; + EnsureNotOk(); + } + + void Assign(Status&& status) { + Clear(); + status_ = std::move(status); + EnsureNotOk(); + } + + bool ok() const { + return status_.ok(); + } + + protected: + // status_ will always be active after the constructor. + // We make it a union to be able to initialize exactly how we need without + // waste. + // Eg. in the copy constructor we use the default constructor of Status in + // the ok() path to avoid an extra Ref call. + union { + Status status_; + }; + + // data_ is active iff status_.ok()==true + struct Dummy {}; + union { + // When T is const, we need some non-const object we can cast to void* for + // the placement new. dummy_ is that object. + Dummy dummy_; + T data_; + }; + + void Clear() { + if (ok()) data_.~T(); + } + + void EnsureOk() const { + if (!ok()) Helper::Crash(status_); + } + + void EnsureNotOk() { + if (ok()) Helper::HandleInvalidStatusCtorArg(&status_); + } + + // Construct the value (ie. data_) through placement new with the passed + // argument. + template + void MakeValue(Arg&& arg) { + internal_statusor::PlacementNew(&dummy_, std::forward(arg)); + } + + // Construct the status (ie. status_) through placement new with the passed + // argument. + template + void MakeStatus(Args&&... args) { + internal_statusor::PlacementNew(&status_, + std::forward(args)...); + } +}; + +// Helper base class to allow implicitly deleted constructors and assignment +// operations in StatusOr. +// TraitsBase will explicitly delete what it can't support and StatusOr will +// inherit that behavior implicitly. +template +struct TraitsBase { + TraitsBase() = default; + TraitsBase(const TraitsBase&) = default; + TraitsBase(TraitsBase&&) = default; + TraitsBase& operator=(const TraitsBase&) = default; + TraitsBase& operator=(TraitsBase&&) = default; +}; + +template <> +struct TraitsBase { + TraitsBase() = default; + TraitsBase(const TraitsBase&) = delete; + TraitsBase(TraitsBase&&) = default; + TraitsBase& operator=(const TraitsBase&) = delete; + TraitsBase& operator=(TraitsBase&&) = default; +}; + +template <> +struct TraitsBase { + TraitsBase() = default; + TraitsBase(const TraitsBase&) = delete; + TraitsBase(TraitsBase&&) = delete; + TraitsBase& operator=(const TraitsBase&) = delete; + TraitsBase& operator=(TraitsBase&&) = delete; +}; + +} // namespace internal_statusor +} // namespace util +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_STATUSOR_INTERNALS_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/strerror.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/strerror.cc new file mode 100644 index 0000000..ab1bbbb --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/strerror.cc @@ -0,0 +1,92 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +// Implementation note: +// +// This is ported from //base/strerror.cc, with several local modifications: +// +// * Removed non-portable optimization around to use sys_errlist where +// available without warnings. +// * Added __attribute__((unused)) to compile with -Wno-unused-functions. +// * Conformed to style/lint rules. + +#include "Firestore/core/src/firebase/firestore/util/strerror.h" + +#include +#include + +#if defined(_WIN32) +#define HAVE_STRERROR_S 1 + +#elif defined(__GLIBC__) +#if (_POSIX_C_SOURCE >= 200112L) && !_GNU_SOURCE +#define HAVE_POSIX_STRERROR_R 1 +#else +#define HAVE_GNU_STRERROR_R 1 +#endif + +#else +#define HAVE_POSIX_STRERROR_R 1 + +#endif + +namespace firebase { +namespace firestore { +namespace util { + +namespace { + +inline const char* StrErrorAdaptor(int errnum, char* buf, size_t buflen) { +#if HAVE_STRERROR_S + int rc = strerror_s(buf, buflen, errnum); + buf[buflen - 1] = '\0'; // guarantee NUL termination + + if (rc == 0 && strcmp(buf, "Unknown error") == 0) { + *buf = '\0'; + } + return buf; + +#elif HAVE_POSIX_STRERROR_R + if (strerror_r(errnum, buf, buflen)) { + *buf = '\0'; + } + return buf; + +#elif HAVE_GNU_STRERROR_R + return strerror_r(errnum, buf, buflen); + +#endif // HAVE_STRERROR_S +} + +} // namespace + +std::string StrError(int errnum) { + const int saved_errno = errno; + + char buf[100]; + const char* str = StrErrorAdaptor(errnum, buf, sizeof buf); + if (*str == '\0') { + snprintf(buf, sizeof buf, "Unknown error %d", errnum); + str = buf; + } + + errno = saved_errno; + return str; +} + +} // namespace util +} // namespace firestore +} // namespace firebase diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/strerror.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/strerror.h new file mode 100644 index 0000000..72c0300 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/strerror.h @@ -0,0 +1,36 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_STRERROR_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_STRERROR_H_ + +#include + +namespace firebase { +namespace firestore { +namespace util { + +// A portable and thread-safe alternative to strerror(). +// Returns a human-readable string describing the given POSIX error +// code. If the error code is not translatable, the string will be +// "Unknown error nnn". errno will not be modified by this call. +std::string StrError(int errnum); + +} // namespace util +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_STRERROR_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/string_apple.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/string_apple.cc new file mode 100644 index 0000000..c896a5b --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/string_apple.cc @@ -0,0 +1,56 @@ +/* + * Copyright 2018 Google + * + * 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 "Firestore/core/src/firebase/firestore/util/string_apple.h" + +#if defined(__APPLE__) + +#include + +#include "Firestore/core/src/firebase/firestore/util/hard_assert.h" + +namespace firebase { +namespace firestore { +namespace util { + +std::string MakeString(CFStringRef str) { + CFIndex num_chars = CFStringGetLength(str); + if (num_chars == 0) { + return {}; + } + + // In the first pass figure the size required. The size does not include the + // null terminator. + CFRange range{0, num_chars}; + CFIndex num_bytes = 0; + CFIndex converted = CFStringGetBytes(str, range, kCFStringEncodingUTF8, 0u, + false, nullptr, 0, &num_bytes); + HARD_ASSERT(converted == num_chars); + + std::string result(static_cast(num_bytes), '\0'); + auto buffer = reinterpret_cast(&result[0]); + converted = CFStringGetBytes(str, range, kCFStringEncodingUTF8, 0u, false, + buffer, num_bytes, nullptr); + HARD_ASSERT(converted == num_chars); + + return result; +} + +} // namespace util +} // namespace firestore +} // namespace firebase + +#endif // defined(__APPLE__) diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/string_apple.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/string_apple.h new file mode 100644 index 0000000..436d2ab --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/string_apple.h @@ -0,0 +1,90 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_STRING_APPLE_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_STRING_APPLE_H_ + +#if defined(__APPLE__) +#import + +#if defined(__OBJC__) +#import +#endif + +#include + +#include "absl/strings/string_view.h" + +namespace firebase { +namespace firestore { +namespace util { + +/** + * Returns a copy of the given CFString (or NSString) encoded in UTF-8. + */ +std::string MakeString(CFStringRef str); + +inline CFStringRef MakeCFString(absl::string_view contents) { + auto bytes = reinterpret_cast(contents.data()); + return CFStringCreateWithBytes(kCFAllocatorDefault, bytes, contents.size(), + kCFStringEncodingUTF8, false); +} + +#if defined(__OBJC__) + +// Translates a C string to the equivalent NSString without making a copy. +inline NSString* WrapNSStringNoCopy(const char* c_str) { + return [[NSString alloc] + initWithBytesNoCopy:const_cast(static_cast(c_str)) + length:strlen(c_str) + encoding:NSUTF8StringEncoding + freeWhenDone:NO]; +} + +// Translates a string_view to the equivalent NSString without making a copy. +inline NSString* WrapNSStringNoCopy(const absl::string_view str) { + return WrapNSStringNoCopy(str.data()); +} + +// Translates a string_view string to the equivalent NSString by making a copy. +inline NSString* WrapNSString(const absl::string_view str) { + return [[NSString alloc] + initWithBytes:const_cast(static_cast(str.data())) + length:str.length() + encoding:NSUTF8StringEncoding]; +} + +// Creates an absl::string_view wrapper for the contents of the given +// NSString. +inline absl::string_view MakeStringView(NSString* str) { + return absl::string_view( + [str UTF8String], [str lengthOfBytesUsingEncoding:NSUTF8StringEncoding]); +} + +// Creates a std::string wrapper for the contents of the given NSString. +inline std::string MakeString(NSString* str) { + CFStringRef cf_str = (__bridge CFStringRef)str; + return MakeString(cf_str); +} + +#endif // defined(__OBJC__) + +} // namespace util +} // namespace firestore +} // namespace firebase + +#endif // defined(__APPLE__) +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_STRING_APPLE_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/string_format.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/string_format.cc new file mode 100644 index 0000000..bafdac2 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/string_format.cc @@ -0,0 +1,94 @@ +/* + * Copyright 2018 Google + * + * 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 "Firestore/core/src/firebase/firestore/util/string_format.h" + +namespace firebase { +namespace firestore { +namespace util { +namespace internal { + +static const char* kMissing = ""; +static const char* kInvalid = ""; + +std::string StringFormatPieces( + const char* format, std::initializer_list pieces) { + std::string result; + + const char* format_iter = format; + const char* format_end = format + strlen(format); + + auto pieces_iter = pieces.begin(); + auto pieces_end = pieces.end(); + auto append_next_piece = [&](std::string* dest) { + if (pieces_iter == pieces_end) { + dest->append(kMissing); + } else { + // Pass a piece through + dest->append(pieces_iter->data(), pieces_iter->size()); + ++pieces_iter; + } + }; + + auto append_specifier = [&](char spec) { + switch (spec) { + case '%': + // Pass through literal %. + result.push_back('%'); + break; + + case 's': { + append_next_piece(&result); + break; + } + + default: + result.append(kInvalid); + break; + } + }; + + // Iterate through the format string, advancing `format_iter` as we go. + while (true) { + const char* percent_ptr = std::find(format_iter, format_end, '%'); + + // percent either points to the next format specifier or the end of the + // format string. Either is safe to append here: + result.append(format_iter, percent_ptr); + if (percent_ptr == format_end) { + // No further pieces to format + break; + } + + // Examine the specifier: + const char* spec_ptr = percent_ptr + 1; + if (spec_ptr == format_end) { + // Incomplete specifier, treat as a literal "%" and be done. + append_specifier('%'); + break; + } + append_specifier(*spec_ptr); + + format_iter = spec_ptr + 1; + } + + return result; +} + +} // namespace internal +} // namespace util +} // namespace firestore +} // namespace firebase diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/string_format.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/string_format.h new file mode 100644 index 0000000..e76aeae --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/string_format.h @@ -0,0 +1,171 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_STRING_FORMAT_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_STRING_FORMAT_H_ + +#include +#include +#include + +#include "Firestore/core/src/firebase/firestore/util/string_apple.h" +#include "Firestore/core/src/firebase/firestore/util/type_traits.h" +#include "absl/base/attributes.h" +#include "absl/strings/str_cat.h" +#include "absl/strings/string_view.h" + +namespace firebase { +namespace firestore { +namespace util { + +namespace internal { + +std::string StringFormatPieces(const char* format, + std::initializer_list pieces); + +/** + * Explicit ranking for formatting choices. Only useful as an implementation + * detail of `FormatArg`. + */ +template +struct FormatChoice : FormatChoice {}; + +template <> +struct FormatChoice<5> {}; + +} // namespace internal + +/** + * Acts as the main value parameter to StringFormat and related functions. + * + * Chooses a conversion to a text form in this order: + * * If the value is exactly of `bool` type (without implicit conversions) + * the text will be "true" or "false". + * * If the value is of type `const char*`, the text will be the value + * interpreted as a C string. To show the address of a single char or to + * show the `const char*` as an address, cast to `void*`. + * * If the value is any other pointer type, the text will be the hexidecimal + * formatting of the value as an unsigned integer. + * * Otherwise the value is interpreted as anything absl::AlphaNum accepts. + */ +class FormatArg : public absl::AlphaNum { + public: + template + FormatArg(T&& value) // NOLINT(runtime/explicit) + : FormatArg{std::forward(value), internal::FormatChoice<0>{}} { + } + + private: + /** + * Creates a FormatArg from a boolean value, representing the string + * "true" or "false". + * + * This overload only applies if the type of the argument is exactly `bool`. + * No implicit conversions to bool are accepted. + */ + template {}>::type> + FormatArg(T bool_value, internal::FormatChoice<0>) + : AlphaNum{bool_value ? "true" : "false"} { + } + +#if __OBJC__ + /** + * Creates a FormatArg from any pointer to an object derived from NSObject. + */ + template < + typename T, + typename = typename std::enable_if{}>::type> + FormatArg(T object, internal::FormatChoice<1>) + : AlphaNum{MakeStringView([object description])} { + } + + /** + * Creates a FormatArg from any Objective-C Class type. Objective-C Class + * types are a special struct that aren't of a type derived from NSObject. + */ + FormatArg(Class object, internal::FormatChoice<1>) + : AlphaNum{MakeStringView(NSStringFromClass(object))} { + } +#endif + + /** + * Creates a FormatArg from a character string literal. This is + * handled specially to avoid ambiguity with generic pointers, which are + * handled differently. + */ + FormatArg(std::nullptr_t, internal::FormatChoice<2>) : AlphaNum{"null"} { + } + + /** + * Creates a FormatArg from a character string literal. This is + * handled specially to avoid ambiguity with generic pointers, which are + * handled differently. + */ + FormatArg(const char* string_value, internal::FormatChoice<3>) + : AlphaNum{string_value == nullptr ? "null" : string_value} { + } + + /** + * Creates a FormatArg from an arbitrary pointer, represented as a + * hexidecimal integer literal. + */ + template + FormatArg(T* pointer_value, internal::FormatChoice<4>) + : AlphaNum{absl::Hex{reinterpret_cast(pointer_value)}} { + } + + /** + * As a final fallback, creates a FormatArg from any type of value that + * absl::AlphaNum accepts. + */ + template + FormatArg(T&& value, internal::FormatChoice<5>) + : AlphaNum{std::forward(value)} { + } +}; + +/** + * Formats a string using a simplified printf-like formatting mechanism that + * does not rely on C varargs. + * + * The following format specifiers are recognized: + * * "%%" - A literal "%" + * * "%s" - The next parameter is copied through + * + * Note: + * * If you pass fewer arguments than the format requires, StringFormat will + * insert "". + * * If you pass more arguments than the format requires, any excess arguments + * are ignored. + * * If you use an invalid format specifier, StringFormat will insert + * . + */ +template +std::string StringFormat(const char* format, const FA&... args) { + return internal::StringFormatPieces( + format, {static_cast(args).Piece()...}); +} + +inline std::string StringFormat() { + return {}; +} + +} // namespace util +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_STRING_FORMAT_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/string_util.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/string_util.cc new file mode 100644 index 0000000..b7f1ed9 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/string_util.cc @@ -0,0 +1,53 @@ +/* + * Copyright 2017 Google + * + * 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 "Firestore/core/src/firebase/firestore/util/string_util.h" + +namespace firebase { +namespace firestore { +namespace util { + +std::string PrefixSuccessor(absl::string_view prefix) { + // We can increment the last character in the string and be done + // unless that character is 255 (0xff), in which case we have to erase the + // last character and increment the previous character, unless that + // is 255, etc. If the string is empty or consists entirely of + // 255's, we just return the empty string. + std::string limit(prefix); + while (!limit.empty()) { + size_t index = limit.length() - 1; + if (limit[index] == '\xff') { // char literal avoids signed/unsigned. + limit.erase(index); + } else { + limit[index]++; + break; + } + } + return limit; +} + +std::string ImmediateSuccessor(absl::string_view s) { + // Return the input string, with an additional NUL byte appended. + std::string out; + out.reserve(s.size() + 1); + out.append(s.data(), s.size()); + out.push_back('\0'); + return out; +} + +} // namespace util +} // namespace firestore +} // namespace firebase diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/string_util.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/string_util.h new file mode 100644 index 0000000..86acc56 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/string_util.h @@ -0,0 +1,72 @@ +/* + * Copyright 2017 Google + * + * 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. + */ + +// Useful string functions and so forth. This is a grab-bag file. +// +// These functions work fine for UTF-8 strings as long as you can +// consider them to be just byte strings. For example, due to the +// design of UTF-8 you do not need to worry about accidental matches, +// as long as all your inputs are valid UTF-8 (use \uHHHH, not \xHH or \oOOO). + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_STRING_UTIL_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_STRING_UTIL_H_ + +#include + +#include "absl/strings/string_view.h" + +namespace firebase { +namespace firestore { +namespace util { + +/** + * Returns the smallest lexicographically larger string of equal or smaller + * length. Returns an empty string if there is no such successor (if the input + * is empty or consists entirely of 0xff bytes). + * Useful for calculating the smallest lexicographically larger string + * that will not be prefixed by the input string. + * + * Examples: + * "a" -> "b", "aaa" -> "aab", "aa\xff" -> "ab", "\xff" -> "", "" -> "" + */ +std::string PrefixSuccessor(absl::string_view prefix); + +/** + * Returns the immediate lexicographically-following string. This is useful to + * turn an inclusive range into something that can be used with Bigtable's + * SetLimitRow(): + * + * // Inclusive range [min_element, max_element]. + * string min_element = ...; + * string max_element = ...; + * + * // Equivalent range [range_start, range_end). + * string range_start = min_element; + * string range_end = ImmediateSuccessor(max_element); + * + * WARNING: Returns the input string with a '\0' appended; if you call c_str() + * on the result, it will compare equal to s. + * + * WARNING: Transforms "" -> "\0"; this doesn't account for Bigtable's special + * treatment of "" as infinity. + */ +std::string ImmediateSuccessor(absl::string_view s); + +} // namespace util +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_STRING_UTIL_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/string_win.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/string_win.cc new file mode 100644 index 0000000..091c5a4 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/string_win.cc @@ -0,0 +1,126 @@ +/* + * Copyright 2018 Google + * + * 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 "Firestore/core/src/firebase/firestore/util/string_win.h" + +#if defined(_WIN32) +#include + +#include "Firestore/core/src/firebase/firestore/util/hard_assert.h" +#include "absl/memory/memory.h" +#include "absl/strings/match.h" + +namespace firebase { +namespace firestore { +namespace util { + +std::wstring Utf8ToNative(absl::string_view input) { + int input_len = static_cast(input.size()); + + // MultiByteToWideChar considers a zero length to be an error, so special case + // the empty string. + if (input_len == 0) { + return L""; + } + + // The input string_view may contain embedded nulls and isn't necessarily null + // terminated so we must pass an explicit length to MultiByteToWideChar. This + // means the result is the number of wchar_t required to hold the result, + // excluding the null terminator. + int output_len = + ::MultiByteToWideChar(CP_UTF8, 0, input.data(), input_len, nullptr, 0); + if (output_len == 0) { + DWORD error = ::GetLastError(); + HARD_FAIL("Utf8ToNative failed with code %s: %s", error, + LastErrorMessage(error)); + } + HARD_ASSERT(output_len > 0); + + int output_terminated_len = output_len + 1; + std::wstring output(output_terminated_len, L'\0'); + int result = ::MultiByteToWideChar(CP_UTF8, 0, input.data(), input_len, + &output[0], output_len); + HARD_ASSERT(result > 0 && result < output_terminated_len && + output[output_len] == '\0'); + + output.resize(result); + return output; +} + +std::string NativeToUtf8(const std::wstring& input) { + return NativeToUtf8(input.c_str(), input.size()); +} + +std::string NativeToUtf8(const wchar_t* input, size_t input_size) { + int input_len = static_cast(input_size); + if (input_len == 0) { + return ""; + } + + // The input buffer may contain embedded nulls and isn't necessarily null + // terminated so we must pass an explicit length to WideCharToMultiByte. This + // means the result is the number of char required to hold the result, + // excluding the null terminator. + int output_len = ::WideCharToMultiByte(CP_UTF8, 0, input, input_len, nullptr, + 0, nullptr, nullptr); + if (output_len == 0) { + DWORD error = ::GetLastError(); + HARD_FAIL("NativeToUtf8 failed with code %s: %s", error, + LastErrorMessage(error)); + } + HARD_ASSERT(output_len > 0); + + int output_terminated_len = output_len + 1; + std::string output(output_terminated_len, '\0'); + int result = ::WideCharToMultiByte(CP_UTF8, 0, input, input_len, &output[0], + output_len, nullptr, nullptr); + HARD_ASSERT(result > 0 && result < output_terminated_len && + output[output_len] == '\0'); + + output.resize(result); + return output; +} + +std::string LastErrorMessage(DWORD last_error) { + // Preallocate a buffer sufficiently large to receive any message. Since we're + // not asking for inserts this is already way too big. + size_t size = 16 * 1024; + auto error_text = absl::make_unique(size); + + // output_len excludes the trailing null. + DWORD output_len = ::FormatMessageW( + FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, nullptr, + last_error, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), error_text.get(), + static_cast(size), nullptr); + if (output_len == 0) { + DWORD format_error = ::GetLastError(); + return util::StringFormat( + "error %s; unknown error %s while getting error text", last_error, + format_error); + } + + std::string formatted = NativeToUtf8(error_text.get(), output_len); + if (absl::EndsWith(formatted, "\r\n")) { + formatted.resize(formatted.size() - 2); + } + return formatted; +} + +} // namespace util +} // namespace firestore +} // namespace firebase + +#endif // defined(_WIN32) diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/string_win.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/string_win.h new file mode 100644 index 0000000..0ba2784 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/string_win.h @@ -0,0 +1,55 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_STRING_WIN_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_STRING_WIN_H_ + +#if defined(_WIN32) +#include + +#include + +#include "absl/strings/string_view.h" + +namespace firebase { +namespace firestore { +namespace util { + +/** + * Converts a UTF-8-encoded string to the equivalent wide character form, + * suitable for use with Windows path-related functions. + */ +std::wstring Utf8ToNative(absl::string_view input); + +/** + * Converts a UTF-16-encoded filename to the equivalent in UTF-8, suitable for + * use in log messages or other non-path-related functions. + */ +std::string NativeToUtf8(const std::wstring& input); +std::string NativeToUtf8(const wchar_t* input, size_t length); + +/** + * Formats the given system error code from GetLastError() to a UTF-8 encoded + * string. + */ +std::string LastErrorMessage(DWORD last_error); + +} // namespace util +} // namespace firestore +} // namespace firebase + +#endif // defined(_WIN32) +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_STRING_WIN_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/to_string.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/to_string.h new file mode 100644 index 0000000..32f767f --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/to_string.h @@ -0,0 +1,197 @@ +/* + * Copyright 2019 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_TO_STRING_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_TO_STRING_H_ + +#if __OBJC__ +#import +#endif // __OBJC__ + +#include +#include +#include +#include +#include + +#include "Firestore/core/src/firebase/firestore/util/string_apple.h" +#include "Firestore/core/src/firebase/firestore/util/string_format.h" +#include "Firestore/core/src/firebase/firestore/util/type_traits.h" +#include "absl/meta/type_traits.h" +#include "absl/strings/str_join.h" +#include "absl/types/optional.h" + +namespace firebase { +namespace firestore { +namespace util { + +/** + * Creates a human-readable description of the given `value`. The representation + * is loosely inspired by Python. + * + * The general idea is to create the description by using the most specific + * available function that creates a string representation of the class; for + * containers, do this recursively, adding some minimal container formatting to + * the output. + * + * Example: + * + * std::vector v{ + * DocumentKey({"foo/bar"}), + * DocumentKey({"this/that"}) + * }; + * assert(ToString(v) == "[foo/bar, this/that]"); + * + * std::map m{ + {1, "foo"}, + {2, "bar"} + * }; + * assert(ToString(m) == "{1: foo, 2: bar}"); + * + * The following algorithm is used: + * + * - if `value` defines a member function called `ToString`, the description is + * created by invoking the function; + * + * - (in Objective-C++ only) otherwise, if `value` is an Objective-C object, + * the description is created by calling `[value description]`and converting + * the result to an `std::string`; + * + * - otherwise, if `value` is an `std::string`, it's used as is; + * + * - otherwise, if `value` is an associative container (`std::map`, + * `std::unordered_map`, `f:f:immutable::SortedMap`, etc.), the description is + * of the form: + * + * {key1: value1, key2: value2} + * + * where the description of each key and value is created by running + * `ToString` recursively; + * + * - otherwise, if `value` is a container, the description is of the form: + * + * [element1, element2] + * + * where the description of each element is created by running `ToString` + * recursively; + * + * - otherwise, `std::to_string` is used as a fallback. If `std::to_string` is + * not defined for the class, a compilation error will be produced. + * + * Implementation notes: to rank different choices and avoid clashes (e.g., + * a type that is an associative container is also a (simple) container), tag + * dispatch is used. Each function in the chain either is tagged by + * `std::true_type` and can process the value, or is tagged by `std::false_type` + * and passes the value to the next function by the rank. When passing to the + * next function, some trait corresponding to the function is given in place of + * the tag; for example, `StringToString`, which can handle `std::string`s, is + * invoked with `std::is_same` as the tag. + */ +template +std::string ToString(const T& value); + +namespace impl { + +// Checks whether the given type `T` defines a member function `ToString` + +template > +struct has_to_string : std::false_type {}; + +template +struct has_to_string().ToString())>> + : std::true_type {}; + +template +struct ToStringChoice : ToStringChoice {}; + +template <> +struct ToStringChoice<6> {}; + +#if __OBJC__ + +// Objective-C class +template ::value>> +std::string ToStringImpl(T value, ToStringChoice<0>) { + return MakeString([value description]); +} + +#endif // __OBJC__ + +// Has `ToString` member function +template ::value>> +std::string ToStringImpl(const T& value, ToStringChoice<1>) { + return value.ToString(); +} + +// `std::string` +template ::value>> +std::string ToStringImpl(const T& value, ToStringChoice<2>) { + return value; +} + +// `absl::optional` +template , T>::value>> +std::string ToStringImpl(const T& maybe_value, ToStringChoice<3>) { + return maybe_value.has_value() ? ToString(maybe_value.value()) + : std::string{"nullopt"}; +} + +// Associative container +template ::value>> +std::string ToStringImpl(const T& value, ToStringChoice<4>) { + std::string contents = absl::StrJoin( + value, ", ", [](std::string* out, const typename T::value_type& kv) { + out->append(ToString(kv.first)); + out->append(": "); + out->append(ToString(kv.second)); + }); + return std::string{"{"} + contents + "}"; // NOLINT(whitespace/braces) +} + +// Container +template ::value>> +std::string ToStringImpl(const T& value, ToStringChoice<5>) { + std::string contents = absl::StrJoin( + value, ", ", [](std::string* out, const typename T::value_type& element) { + out->append(ToString(element)); + }); + return std::string{"["} + contents + "]"; // NOLINT(whitespace/braces) +} + +// Fallback +template +std::string ToStringImpl(const T& value, ToStringChoice<6>) { + FormatArg arg{value}; + return std::string{arg.data(), arg.data() + arg.size()}; +} + +} // namespace impl + +template +std::string ToString(const T& value) { + return impl::ToStringImpl(value, impl::ToStringChoice<0>{}); +} + +} // namespace util +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_TO_STRING_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/type_traits.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/type_traits.h new file mode 100644 index 0000000..fbec417 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/type_traits.h @@ -0,0 +1,81 @@ +/* + * Copyright 2018 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_TYPE_TRAITS_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_TYPE_TRAITS_H_ + +#if __OBJC__ +#import // for id +#endif + +#include +#include + +#include "absl/meta/type_traits.h" + +namespace firebase { +namespace firestore { +namespace util { + +#if __OBJC__ + +/** + * A type trait that identifies whether or not the given pointer points to an + * Objective-C object. + * + * is_objective_c_pointer::value == true + * is_objective_c_pointer*>::value == true + * + * // id is a dynamically typed pointer to an Objective-C object. + * is_objective_c_pointer::value == true + * + * // pointers to C++ classes are not Objective-C pointers. + * is_objective_c_pointer::value == false + * is_objective_c_pointer::value == false + * is_objective_c_pointer>::value == false + */ +template +using is_objective_c_pointer = std::is_convertible; + +#endif // __OBJC__ + +// is_iterable + +template > +struct is_iterable : std::false_type {}; + +template +struct is_iterable< + T, + absl::void_t().begin(), std::declval().end())>> + : std::true_type {}; + +// is_associative_container + +template > +struct is_associative_container : std::false_type {}; + +template +struct is_associative_container< + T, + absl::void_t())>> + : std::true_type {}; + +} // namespace util +} // namespace firestore +} // namespace firebase + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_TYPE_TRAITS_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/warnings.h b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/warnings.h new file mode 100644 index 0000000..6ce6017 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/core/src/firebase/firestore/util/warnings.h @@ -0,0 +1,89 @@ +/* + * Copyright 2019 Google + * + * 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. + */ + +#ifndef FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_WARNINGS_H_ +#define FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_WARNINGS_H_ + +/** + * Macros for suppressing various warnings. Use like this: + * + * SUPPRESS_DOCUMENTATION_WARNINGS_BEGIN() + * #include "header/that/has/warnings.h" + * SUPPRESS_END() + * + * SUPPRESS_DEPRECATED_DECLARATIONS_BEGIN() + * #include "header/that/uses/deprecated/stuff.h" + * SUPPRESS_END() + * + * SUPPRESS_DOCUMENTATION_WARNINGS_BEGIN() + * SUPPRESS_DEPRECATED_DECLARATIONS_BEGIN() + * #include "something/awful.h" + * SUPPRESS_END() + * SUPPRESS_END() + */ + +// Define some primitives used by the 'public' macros below. + +#if defined(__clang__) || defined(__GNUC__) +#define SUPPRESS_BEGIN_UNIMPLEMENTED_() _Pragma("GCC diagnostic push") + +#define SUPPRESS_BEGIN_(name) _Pragma("GCC diagnostic push") _Pragma(name) + +#elif defined(_MSC_VER) +#define SUPPRESS_BEGIN_UNIMPLEMENTED_() __pragma(warning(push)) + +#define SUPPRESS_BEGIN_(name) \ + __pragma(warning(push)) __pragma(warning(disable : name)) + +#endif + +// 'Public' macros. + +#if defined(__clang__) +#define SUPPRESS_DOCUMENTATION_WARNINGS_BEGIN() \ + SUPPRESS_BEGIN_("GCC diagnostic ignored \"-Wdocumentation\"") + +#define SUPPRESS_DEPRECATED_DECLARATIONS_BEGIN() \ + SUPPRESS_BEGIN_("GCC diagnostic ignored \"-Wdeprecated-declarations\"") + +#define SUPPRESS_END() _Pragma("GCC diagnostic pop") + +#elif defined(__GNUC__) +#define SUPPRESS_DOCUMENTATION_WARNINGS_BEGIN() SUPPRESS_BEGIN_UNIMPLEMENTED_() + +#define SUPPRESS_DEPRECATED_DECLARATIONS_BEGIN() \ + SUPPRESS_BEGIN_("GCC diagnostic ignored \"-Wdeprecated-declarations\"") + +#define SUPPRESS_END() _Pragma("GCC diagnostic pop") + +#elif defined(_MSC_VER) +// MSVC compiler warnings can be found here: (Look at the navbar on the left +// and select the appropriate range): +// https://docs.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warnings-by-compiler-version?view=vs-2017 +#define SUPPRESS_DOCUMENTATION_WARNINGS_BEGIN() SUPPRESS_BEGIN_UNIMPLEMENTED_() + +#define SUPPRESS_DEPRECATED_DECLARATIONS_BEGIN() SUPPRESS_BEGIN_(4995) + +#define SUPPRESS_END() __pragma(warning(pop)) + +#else +#define SUPPRESS_DOCUMENTATION_WARNINGS_BEGIN() +#define SUPPRESS_DEPRECATED_DECLARATIONS_BEGIN() +#define SUPPRESS_END() + +#endif + +#endif // FIRESTORE_CORE_SRC_FIREBASE_FIRESTORE_UTIL_WARNINGS_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/Immutable/FSTArraySortedDictionary.h b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/Immutable/FSTArraySortedDictionary.h new file mode 100644 index 0000000..0fd7b44 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/Immutable/FSTArraySortedDictionary.h @@ -0,0 +1,35 @@ +#import + +#import "Firestore/third_party/Immutable/FSTImmutableSortedDictionary.h" + +NS_ASSUME_NONNULL_BEGIN + +/** + * FSTArraySortedDictionary is an array backed implementation of FSTImmutableSortedDictionary. + * + * You should not use this class directly. You should use FSTImmutableSortedDictionary. + * + * FSTArraySortedDictionary uses arrays and linear lookups to achieve good memory efficiency while + * maintaining good performance for small collections. It also uses fewer allocations than a + * comparable red black tree. To avoid degrading performance with increasing collection size it + * will automatically convert to a FSTTreeSortedDictionary after an insert call above a certain + * threshold. + */ +@interface FSTArraySortedDictionary : + FSTImmutableSortedDictionary + ++ (FSTArraySortedDictionary *) + dictionaryWithDictionary:(NSDictionary *)dictionary + comparator:(NSComparator)comparator; + +- (id)init __attribute__((unavailable("Use initWithComparator:keys:values: instead."))); + +- (instancetype)initWithComparator:(NSComparator)comparator; + +- (instancetype)initWithComparator:(NSComparator)comparator + keys:(NSArray *)keys + values:(NSArray *)values NS_DESIGNATED_INITIALIZER; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/Immutable/FSTArraySortedDictionary.m b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/Immutable/FSTArraySortedDictionary.m new file mode 100644 index 0000000..985b514 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/Immutable/FSTArraySortedDictionary.m @@ -0,0 +1,228 @@ +#import "Firestore/third_party/Immutable/FSTArraySortedDictionary.h" + +#import "Firestore/third_party/Immutable/FSTArraySortedDictionaryEnumerator.h" +#import "Firestore/third_party/Immutable/FSTTreeSortedDictionary.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface FSTArraySortedDictionary () +@property(nonatomic, copy, readwrite) NSComparator comparator; +@property(nonatomic, strong) NSArray *keys; +@property(nonatomic, strong) NSArray *values; +@end + +@implementation FSTArraySortedDictionary + ++ (FSTArraySortedDictionary *)dictionaryWithDictionary:(NSDictionary *)dictionary + comparator:(NSComparator)comparator { + NSMutableArray *keys = [NSMutableArray arrayWithCapacity:dictionary.count]; + [dictionary enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) { + [keys addObject:key]; + }]; + [keys sortUsingComparator:comparator]; + + [keys enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { + if (idx > 0) { + if (comparator(keys[idx - 1], obj) != NSOrderedAscending) { + [NSException raise:NSInvalidArgumentException + format: + @"Can't create FSTImmutableSortedDictionary with keys " + @"with same ordering!"]; + } + } + }]; + + NSMutableArray *values = [NSMutableArray arrayWithCapacity:keys.count]; + NSInteger pos = 0; + for (id key in keys) { + values[pos++] = dictionary[key]; + } + NSAssert(values.count == keys.count, @"We added as many keys as values"); + return [[FSTArraySortedDictionary alloc] initWithComparator:comparator keys:keys values:values]; +} + +- (id)initWithComparator:(NSComparator)comparator { + return [self initWithComparator:comparator keys:[NSArray array] values:[NSArray array]]; +} + +// Designated initializer. +- (id)initWithComparator:(NSComparator)comparator keys:(NSArray *)keys values:(NSArray *)values { + self = [super init]; + if (self != nil) { + NSAssert(keys.count == values.count, @"keys and values must have the same count"); + _comparator = comparator; + _keys = keys; + _values = values; + } + return self; +} + +/** Returns the index of the first position where array[position] >= key. */ +- (int)findInsertPositionForKey:(id)key { + int newPos = 0; + while (newPos < self.keys.count && self.comparator(self.keys[newPos], key) < NSOrderedSame) { + newPos++; + } + return newPos; +} + +- (NSInteger)findKey:(id)key { + if (key == nil) { + return NSNotFound; + } + for (NSInteger pos = 0; pos < self.keys.count; pos++) { + NSComparisonResult result = self.comparator(key, self.keys[pos]); + if (result == NSOrderedSame) { + return pos; + } else if (result == NSOrderedAscending) { + return NSNotFound; + } + } + return NSNotFound; +} + +- (FSTImmutableSortedDictionary *)dictionaryBySettingObject:(id)value forKey:(id)key { + NSInteger pos = [self findKey:key]; + + if (pos == NSNotFound) { + /* + * If we're above the threshold we want to convert it to a tree backed implementation to not + * have degrading performance + */ + if (self.count >= kSortedDictionaryArrayToRBTreeSizeThreshold) { + NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithCapacity:self.count]; + for (NSInteger i = 0; i < self.keys.count; i++) { + dict[self.keys[i]] = self.values[i]; + } + dict[key] = value; + return [FSTTreeSortedDictionary dictionaryWithDictionary:dict comparator:self.comparator]; + } else { + NSMutableArray *newKeys = [NSMutableArray arrayWithArray:self.keys]; + NSMutableArray *newValues = [NSMutableArray arrayWithArray:self.values]; + NSInteger newPos = [self findInsertPositionForKey:key]; + [newKeys insertObject:key atIndex:newPos]; + [newValues insertObject:value atIndex:newPos]; + return [[FSTArraySortedDictionary alloc] initWithComparator:self.comparator + keys:newKeys + values:newValues]; + } + } else { + NSMutableArray *newKeys = [NSMutableArray arrayWithArray:self.keys]; + NSMutableArray *newValues = [NSMutableArray arrayWithArray:self.values]; + newKeys[pos] = key; + newValues[pos] = value; + return [[FSTArraySortedDictionary alloc] initWithComparator:self.comparator + keys:newKeys + values:newValues]; + } +} + +- (FSTImmutableSortedDictionary *)dictionaryByRemovingObjectForKey:(id)key { + NSInteger pos = [self findKey:key]; + if (pos == NSNotFound) { + return self; + } else { + NSMutableArray *newKeys = [NSMutableArray arrayWithArray:self.keys]; + NSMutableArray *newValues = [NSMutableArray arrayWithArray:self.values]; + [newKeys removeObjectAtIndex:pos]; + [newValues removeObjectAtIndex:pos]; + return [[FSTArraySortedDictionary alloc] initWithComparator:self.comparator + keys:newKeys + values:newValues]; + } +} + +- (nullable id)objectForKey:(id)key { + NSInteger pos = [self findKey:key]; + if (pos == NSNotFound) { + return nil; + } else { + return self.values[pos]; + } +} + +- (NSUInteger)indexOfKey:(id)key { + return [self findKey:key]; +} + +- (BOOL)isEmpty { + return self.keys.count == 0; +} + +- (NSUInteger)count { + return self.keys.count; +} + +- (id)minKey { + return [self.keys firstObject]; +} + +- (id)maxKey { + return [self.keys lastObject]; +} + +- (void)enumerateKeysAndObjectsUsingBlock:(void (^)(id, id, BOOL *))block { + [self enumerateKeysAndObjectsReverse:NO usingBlock:block]; +} + +- (void)enumerateKeysAndObjectsReverse:(BOOL)reverse usingBlock:(void (^)(id, id, BOOL *))block { + if (reverse) { + BOOL stop = NO; + for (NSInteger i = self.keys.count - 1; i >= 0; i--) { + block(self.keys[i], self.values[i], &stop); + if (stop) return; + } + } else { + BOOL stop = NO; + for (NSInteger i = 0; i < self.keys.count; i++) { + block(self.keys[i], self.values[i], &stop); + if (stop) return; + } + } +} + +- (BOOL)containsKey:(id)key { + return [self findKey:key] != NSNotFound; +} + +- (NSEnumerator *)keyEnumerator { + return [self.keys objectEnumerator]; +} + +- (NSEnumerator *)keyEnumeratorFrom:(id)startKey { + return [self keyEnumeratorFrom:startKey to:nil]; +} + +- (NSEnumerator *)keyEnumeratorFrom:(id)startKey to:(nullable id)endKey { + int start = [self findInsertPositionForKey:startKey]; + int end = (int)self.count; + if (endKey) { + end = [self findInsertPositionForKey:endKey]; + } + return [[FSTArraySortedDictionaryEnumerator alloc] initWithKeys:self.keys + startPos:start + endPos:end + isReverse:NO]; +} + +- (NSEnumerator *)reverseKeyEnumerator { + return [self.keys reverseObjectEnumerator]; +} + +- (NSEnumerator *)reverseKeyEnumeratorFrom:(id)startKey { + int startPos = [self findInsertPositionForKey:startKey]; + // if there's no exact match, findKeyOrInsertPosition will return the index *after* the closest + // match, but since this is a reverse iterator, we want to start just *before* the closest match. + if (startPos >= self.keys.count || + self.comparator(self.keys[startPos], startKey) != NSOrderedSame) { + startPos -= 1; + } + return [[FSTArraySortedDictionaryEnumerator alloc] initWithKeys:self.keys + startPos:startPos + endPos:-1 + isReverse:YES]; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/Immutable/FSTArraySortedDictionaryEnumerator.h b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/Immutable/FSTArraySortedDictionaryEnumerator.h new file mode 100644 index 0000000..36c4f32 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/Immutable/FSTArraySortedDictionaryEnumerator.h @@ -0,0 +1,26 @@ +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface FSTArraySortedDictionaryEnumerator : NSEnumerator + +- (id)init __attribute__((unavailable("Use initWithKeys:startPos:endPos:isReverse: instead."))); + +/** + * An enumerator for use with a dictionary. + * + * @param keys The keys to enumerator within. + * @param start The index of the initial key to return. + * @param end If end is after (or equal to) start (or before, if reverse), then the enumerator will + * stop and not return the value once it reaches end. + */ +- (instancetype)initWithKeys:(NSArray *)keys + startPos:(int)start + endPos:(int)end + isReverse:(BOOL)reverse NS_DESIGNATED_INITIALIZER; + +- (_Nullable ValueType)nextObject; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/Immutable/FSTArraySortedDictionaryEnumerator.m b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/Immutable/FSTArraySortedDictionaryEnumerator.m new file mode 100644 index 0000000..9039f96 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/Immutable/FSTArraySortedDictionaryEnumerator.m @@ -0,0 +1,54 @@ +#import "Firestore/third_party/Immutable/FSTArraySortedDictionaryEnumerator.h" + +NS_ASSUME_NONNULL_BEGIN + +// clang-format off +// For some reason, clang-format messes this line up... +@interface FSTArraySortedDictionaryEnumerator () +@property(nonatomic, assign) int pos; +@property(nonatomic, assign) int start; +@property(nonatomic, assign) int end; +@property(nonatomic, assign) BOOL reverse; +@property(nonatomic, strong) NSArray *keys; +@end +// clang-format on + +@implementation FSTArraySortedDictionaryEnumerator + +- (id)initWithKeys:(NSArray *)keys startPos:(int)start endPos:(int)end isReverse:(BOOL)reverse { + self = [super init]; + if (self != nil) { + _keys = keys; + _start = start; + _end = end; + _pos = start; + _reverse = reverse; + } + return self; +} + +- (nullable id)nextObject { + if (self.pos < 0 || self.pos >= self.keys.count) { + return nil; + } + if (self.reverse) { + if (self.pos <= self.end) { + return nil; + } + } else { + if (self.pos >= self.end) { + return nil; + } + } + int pos = self.pos; + if (self.reverse) { + self.pos--; + } else { + self.pos++; + } + return self.keys[pos]; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/Immutable/FSTImmutableSortedDictionary.h b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/Immutable/FSTImmutableSortedDictionary.h new file mode 100644 index 0000000..cbb4da3 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/Immutable/FSTImmutableSortedDictionary.h @@ -0,0 +1,112 @@ +/** + * Implementation of an immutable SortedMap using a Left-leaning Red-Black Tree, adapted from the + * implementation in Mugs (http://mads379.github.com/mugs/) by Mads Hartmann Jensen + * (mads379@gmail.com). + * + * Original paper on Left-leaning Red-Black Trees: + * http://www.cs.princeton.edu/~rs/talks/LLRB/LLRB.pdf + * + * Invariant 1: No red node has a red child + * Invariant 2: Every leaf path has the same number of black nodes + * Invariant 3: Only the left child can be red (left leaning) + */ + +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * The size threshold where we use a tree backed sorted map instead of an array backed sorted map. + * This is a more or less arbitrary chosen value, that was chosen to be large enough to fit most of + * object kind of Firebase data, but small enough to not notice degradation in performance for + * inserting and lookups. Feel free to empirically determine this constant, but don't expect much + * gain in real world performance. + */ +extern const int kSortedDictionaryArrayToRBTreeSizeThreshold; + +/** + * FSTImmutableSortedDictionary is a dictionary. It is immutable, but has methods to create new + * dictionaries that are mutations of it, in an efficient way. + */ +@interface FSTImmutableSortedDictionary : NSObject + ++ (FSTImmutableSortedDictionary *)dictionaryWithComparator:(NSComparator)comparator; ++ (FSTImmutableSortedDictionary *)dictionaryWithDictionary: + (NSDictionary *)dictionary + comparator:(NSComparator)comparator; + +/** + * Creates a new dictionary identical to this one, but with a key-value pair added or updated. + * + * @param aValue The value to associate with the key. + * @param aKey The key to insert/update. + * @return A new dictionary with the added/updated value. + */ +- (FSTImmutableSortedDictionary *)dictionaryBySettingObject:(ValueType)aValue + forKey:(KeyType)aKey; + +/** + * Creates a new dictionary identical to this one, but with a key removed from it. + * + * @param aKey The key to remove. + * @return A new dictionary without that value. + */ +- (FSTImmutableSortedDictionary *)dictionaryByRemovingObjectForKey: + (KeyType)aKey; + +/** + * Looks up a value in the dictionary. + * + * @param key The key to look up. + * @return The value for the key, if present. + */ +- (nullable ValueType)objectForKey:(KeyType)key; + +/** + * Looks up a value in the dictionary. + * + * @param key The key to look up. + * @return The value for the key, if present. + */ +- (ValueType)objectForKeyedSubscript:(KeyType)key; + +/** + * Returns the index of the key or NSNotFound if the key is not found. + * + * @param key The key to return the index for. + * @return The index of the key, or NSNotFound if key not found. + */ +- (NSUInteger)indexOfKey:(KeyType)key; + +/** Returns true if the dictionary contains no elements. */ +- (BOOL)isEmpty; + +/** Returns the number of items in this dictionary. */ +- (NSUInteger)count; + +/** Returns the smallest key in this dictionary. */ +- (KeyType)minKey; + +/** Returns the largest key in this dictionary. */ +- (KeyType)maxKey; + +/** Calls the given block with each of the items in this dictionary, in order. */ +- (void)enumerateKeysAndObjectsUsingBlock:(void (^)(KeyType key, ValueType value, BOOL *stop))block; + +/** Calls the given block with each of the items in this dictionary, in reverse order. */ +- (void)enumerateKeysAndObjectsReverse:(BOOL)reverse + usingBlock:(void (^)(KeyType key, ValueType value, BOOL *stop))block; + +/** Returns true if the dictionary contains the given key. */ +- (BOOL)containsKey:(KeyType)key; + +- (NSEnumerator *)keyEnumerator; +- (NSEnumerator *)keyEnumeratorFrom:(KeyType)startKey; +/** Enumerator for the range [startKey, endKey). */ +- (NSEnumerator *)keyEnumeratorFrom:(KeyType)startKey to:(nullable KeyType)endKey; +- (NSEnumerator *)reverseKeyEnumerator; +- (NSEnumerator *)reverseKeyEnumeratorFrom:(KeyType)startKey; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/Immutable/FSTImmutableSortedDictionary.m b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/Immutable/FSTImmutableSortedDictionary.m new file mode 100644 index 0000000..87c21a5 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/Immutable/FSTImmutableSortedDictionary.m @@ -0,0 +1,139 @@ +#import "Firestore/third_party/Immutable/FSTImmutableSortedDictionary.h" + +#import "Firestore/third_party/Immutable/FSTArraySortedDictionary.h" +#import "Firestore/Source/Util/FSTClasses.h" +#import "Firestore/third_party/Immutable/FSTTreeSortedDictionary.h" + +NS_ASSUME_NONNULL_BEGIN + +const int kSortedDictionaryArrayToRBTreeSizeThreshold = 25; + +@implementation FSTImmutableSortedDictionary + ++ (FSTImmutableSortedDictionary *)dictionaryWithComparator:(NSComparator)comparator { + return [[FSTArraySortedDictionary alloc] initWithComparator:comparator]; +} + ++ (FSTImmutableSortedDictionary *)dictionaryWithDictionary:(NSDictionary *)dictionary + comparator:(NSComparator)comparator { + if (dictionary.count <= kSortedDictionaryArrayToRBTreeSizeThreshold) { + return [FSTArraySortedDictionary dictionaryWithDictionary:dictionary comparator:comparator]; + } else { + return [FSTTreeSortedDictionary dictionaryWithDictionary:dictionary comparator:comparator]; + } +} + +- (FSTImmutableSortedDictionary *)dictionaryBySettingObject:(id)aValue forKey:(id)aKey { + @throw FSTAbstractMethodException(); // NOLINT +} + +- (FSTImmutableSortedDictionary *)dictionaryByRemovingObjectForKey:(id)aKey { + @throw FSTAbstractMethodException(); // NOLINT +} + +- (BOOL)isEqual:(id)object { + if (![object isKindOfClass:[FSTImmutableSortedDictionary class]]) { + return NO; + } + + // TODO(klimt): We could make this more efficient if we put the comparison inside the + // implementations and short-circuit if they share the same tree node, for instance. + FSTImmutableSortedDictionary *other = (FSTImmutableSortedDictionary *)object; + if (self.count != other.count) { + return NO; + } + __block BOOL isEqual = YES; + [self enumerateKeysAndObjectsUsingBlock:^(id key, id value, BOOL *stop) { + id otherValue = [other objectForKey:key]; + isEqual = isEqual && (value == otherValue || [value isEqual:otherValue]); + *stop = !isEqual; + }]; + return isEqual; +} + +- (NSUInteger)hash { + __block NSUInteger hash = 0; + [self enumerateKeysAndObjectsUsingBlock:^(id key, id value, BOOL *stop) { + hash = (hash * 31 + [key hash]) * 17 + [value hash]; + }]; + return hash; +} + +- (NSString *)description { + NSMutableString *str = [[NSMutableString alloc] init]; + __block BOOL first = YES; + [str appendString:@"{ "]; + [self enumerateKeysAndObjectsUsingBlock:^(id key, id value, BOOL *stop) { + if (!first) { + [str appendString:@", "]; + } + first = NO; + [str appendString:[NSString stringWithFormat:@"%@: %@", key, value]]; + }]; + [str appendString:@" }"]; + return str; +} + +- (nullable id)objectForKey:(id)key { + @throw FSTAbstractMethodException(); // NOLINT +} + +- (id)objectForKeyedSubscript:(id)key { + return [self objectForKey:key]; +} + +- (NSUInteger)indexOfKey:(id)key { + @throw FSTAbstractMethodException(); // NOLINT +} + +- (BOOL)isEmpty { + @throw FSTAbstractMethodException(); // NOLINT +} + +- (NSUInteger)count { + @throw FSTAbstractMethodException(); // NOLINT +} + +- (id)minKey { + @throw FSTAbstractMethodException(); // NOLINT +} + +- (id)maxKey { + @throw FSTAbstractMethodException(); // NOLINT +} + +- (void)enumerateKeysAndObjectsUsingBlock:(void (^)(id, id, BOOL *))block { + @throw FSTAbstractMethodException(); // NOLINT +} + +- (void)enumerateKeysAndObjectsReverse:(BOOL)reverse usingBlock:(void (^)(id, id, BOOL *))block { + @throw FSTAbstractMethodException(); // NOLINT +} + +- (BOOL)containsKey:(id)key { + @throw FSTAbstractMethodException(); // NOLINT +} + +- (NSEnumerator *)keyEnumerator { + @throw FSTAbstractMethodException(); // NOLINT +} + +- (NSEnumerator *)keyEnumeratorFrom:(id)startKey { + @throw FSTAbstractMethodException(); // NOLINT +} + +- (NSEnumerator *)keyEnumeratorFrom:(id)startKey to:(nullable id)endKey { + @throw FSTAbstractMethodException(); // NOLINT +} + +- (NSEnumerator *)reverseKeyEnumerator { + @throw FSTAbstractMethodException(); // NOLINT +} + +- (NSEnumerator *)reverseKeyEnumeratorFrom:(id)startKey { + @throw FSTAbstractMethodException(); // NOLINT +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/Immutable/FSTImmutableSortedSet.h b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/Immutable/FSTImmutableSortedSet.h new file mode 100644 index 0000000..b432f98 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/Immutable/FSTImmutableSortedSet.h @@ -0,0 +1,45 @@ +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * FSTImmutableSortedSet is a set. It is immutable, but has methods to create new sets that are + * mutations of it, in an efficient way. + */ +@interface FSTImmutableSortedSet : NSObject + ++ (FSTImmutableSortedSet *)setWithComparator:(NSComparator)comparator; + ++ (FSTImmutableSortedSet *)setWithKeysFromDictionary:(NSDictionary *)array + comparator:(NSComparator)comparator; + +- (BOOL)containsObject:(KeyType)object; + +- (FSTImmutableSortedSet *)setByAddingObject:(KeyType)object; +- (FSTImmutableSortedSet *)setByRemovingObject:(KeyType)object; + +- (KeyType)firstObject; +- (KeyType)lastObject; +- (NSUInteger)count; +- (BOOL)isEmpty; + +/** + * Returns the index of the object or NSNotFound if the object is not found. + * + * @param object The object to return the index for. + * @return The index of the object, or NSNotFound if not found. + */ +- (NSUInteger)indexOfObject:(KeyType)object; + +- (void)enumerateObjectsUsingBlock:(void (^)(KeyType obj, BOOL *stop))block; +- (void)enumerateObjectsFrom:(KeyType)start + to:(_Nullable KeyType)end + usingBlock:(void (^)(KeyType obj, BOOL *stop))block; +- (void)enumerateObjectsReverse:(BOOL)reverse usingBlock:(void (^)(KeyType obj, BOOL *stop))block; + +- (NSEnumerator *)objectEnumerator; +- (NSEnumerator *)objectEnumeratorFrom:(KeyType)startKey; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/Immutable/FSTImmutableSortedSet.m b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/Immutable/FSTImmutableSortedSet.m new file mode 100644 index 0000000..1b63c2c --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/Immutable/FSTImmutableSortedSet.m @@ -0,0 +1,140 @@ +#import "Firestore/third_party/Immutable/FSTImmutableSortedSet.h" + +#import "Firestore/third_party/Immutable/FSTImmutableSortedDictionary.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface FSTImmutableSortedSet () +@property(nonatomic, strong) FSTImmutableSortedDictionary *dictionary; +@end + +@implementation FSTImmutableSortedSet + ++ (FSTImmutableSortedSet *)setWithComparator:(NSComparator)comparator { + return [FSTImmutableSortedSet setWithKeysFromDictionary:@{} comparator:comparator]; +} + ++ (FSTImmutableSortedSet *)setWithKeysFromDictionary:(NSDictionary *)dictionary + comparator:(NSComparator)comparator { + FSTImmutableSortedDictionary *setDict = + [FSTImmutableSortedDictionary dictionaryWithDictionary:dictionary comparator:comparator]; + return [[FSTImmutableSortedSet alloc] initWithDictionary:setDict]; +} + +// Designated initializer. +- (id)initWithDictionary:(FSTImmutableSortedDictionary *)dictionary { + self = [super init]; + if (self != nil) { + _dictionary = dictionary; + } + return self; +} + +- (BOOL)isEqual:(id)object { + if (![object isKindOfClass:[FSTImmutableSortedSet class]]) { + return NO; + } + + FSTImmutableSortedSet *other = (FSTImmutableSortedSet *)object; + + return [self.dictionary isEqual:other.dictionary]; +} + +- (NSUInteger)hash { + return [self.dictionary hash]; +} + +- (BOOL)containsObject:(id)object { + return [self.dictionary containsKey:object]; +} + +- (FSTImmutableSortedSet *)setByAddingObject:(id)object { + FSTImmutableSortedDictionary *newDictionary = + [self.dictionary dictionaryBySettingObject:[NSNull null] forKey:object]; + if (newDictionary != self.dictionary) { + return [[FSTImmutableSortedSet alloc] initWithDictionary:newDictionary]; + } else { + return self; + } +} + +- (FSTImmutableSortedSet *)setByRemovingObject:(id)object { + FSTImmutableSortedDictionary *newDictionary = + [self.dictionary dictionaryByRemovingObjectForKey:object]; + if (newDictionary != self.dictionary) { + return [[FSTImmutableSortedSet alloc] initWithDictionary:newDictionary]; + } else { + return self; + } +} + +- (id)firstObject { + return [self.dictionary minKey]; +} + +- (id)lastObject { + return [self.dictionary maxKey]; +} + +- (NSUInteger)indexOfObject:(id)object { + return [self.dictionary indexOfKey:object]; +} + +- (NSUInteger)count { + return [self.dictionary count]; +} + +- (BOOL)isEmpty { + return [self.dictionary isEmpty]; +} + +- (void)enumerateObjectsUsingBlock:(void (^)(id, BOOL *))block { + [self enumerateObjectsReverse:NO usingBlock:block]; +} + +- (void)enumerateObjectsFrom:(id)start to:(_Nullable id)end usingBlock:(void (^)(id, BOOL *))block { + NSEnumerator *enumerator = [self.dictionary keyEnumeratorFrom:start to:end]; + id item = [enumerator nextObject]; + while (item) { + BOOL stop = NO; + block(item, &stop); + if (stop) { + return; + } + item = [enumerator nextObject]; + } +} + +- (void)enumerateObjectsReverse:(BOOL)reverse usingBlock:(void (^)(id, BOOL *))block { + [self.dictionary enumerateKeysAndObjectsReverse:reverse + usingBlock:^(id key, id value, BOOL *stop) { + block(key, stop); + }]; +} + +- (NSEnumerator *)objectEnumerator { + return [self.dictionary keyEnumerator]; +} + +- (NSEnumerator *)objectEnumeratorFrom:(id)startKey { + return [self.dictionary keyEnumeratorFrom:startKey]; +} + +- (NSString *)description { + NSMutableString *str = [[NSMutableString alloc] init]; + __block BOOL first = YES; + [str appendString:@"FSTImmutableSortedSet ( "]; + [self enumerateObjectsUsingBlock:^(id obj, BOOL *stop) { + if (!first) { + [str appendString:@", "]; + } + first = NO; + [str appendString:[NSString stringWithFormat:@"%@", obj]]; + }]; + [str appendString:@" )"]; + return str; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/Immutable/FSTLLRBEmptyNode.h b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/Immutable/FSTLLRBEmptyNode.h new file mode 100644 index 0000000..13c3bf8 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/Immutable/FSTLLRBEmptyNode.h @@ -0,0 +1,11 @@ +#import + +#import "Firestore/third_party/Immutable/FSTLLRBNode.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface FSTLLRBEmptyNode : NSObject ++ (instancetype)emptyNode; +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/Immutable/FSTLLRBEmptyNode.m b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/Immutable/FSTLLRBEmptyNode.m new file mode 100644 index 0000000..45d2652 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/Immutable/FSTLLRBEmptyNode.m @@ -0,0 +1,102 @@ +#import "Firestore/third_party/Immutable/FSTLLRBEmptyNode.h" + +#import "Firestore/third_party/Immutable/FSTLLRBValueNode.h" + +NS_ASSUME_NONNULL_BEGIN + +@implementation FSTLLRBEmptyNode + +- (NSString *)description { + return @"[empty node]"; +} + ++ (instancetype)emptyNode { + static dispatch_once_t pred = 0; + __strong static id _sharedObject = nil; + dispatch_once(&pred, ^{ + _sharedObject = [[self alloc] init]; // or some other init method + }); + return _sharedObject; +} + +- (nullable id)key { + return nil; +} + +- (nullable id)value { + return nil; +} + +- (FSTLLRBColor)color { + return FSTLLRBColorUnspecified; +} + +- (nullable id)left { + return nil; +} + +- (nullable id)right { + return nil; +} + +- (instancetype)copyWith:(id _Nullable)aKey + withValue:(id _Nullable)aValue + withColor:(FSTLLRBColor)aColor + withLeft:(id _Nullable)aLeft + withRight:(id _Nullable)aRight { + // This class is a singleton anyway, so this is more efficient than calling the constructor again. + return self; +} + +- (id)insertKey:(id)aKey forValue:(id)aValue withComparator:(NSComparator)aComparator { + FSTLLRBValueNode *result = [[FSTLLRBValueNode alloc] initWithKey:aKey + withValue:aValue + withColor:FSTLLRBColorUnspecified + withLeft:nil + withRight:nil]; + return result; +} + +- (id)remove:(id)key withComparator:(NSComparator)aComparator { + return self; +} + +- (NSUInteger)count { + return 0; +} + +- (BOOL)isEmpty { + return YES; +} + +- (BOOL)inorderTraversal:(BOOL (^)(id key, id value))action { + return NO; +} + +- (BOOL)reverseTraversal:(BOOL (^)(id key, id value))action { + return NO; +} + +- (id)min { + return self; +} + +- (nullable id)minKey { + return nil; +} + +- (nullable id)maxKey { + return nil; +} + +- (BOOL)isRed { + return NO; +} + +- (int)check { + return 0; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/Immutable/FSTLLRBNode.h b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/Immutable/FSTLLRBNode.h new file mode 100644 index 0000000..082b875 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/Immutable/FSTLLRBNode.h @@ -0,0 +1,68 @@ +#import + +NS_ASSUME_NONNULL_BEGIN + +/** + * A FSTLLRBColor is the color of a tree node. It can be RED, BLACK, or unset. + */ +typedef NS_ENUM(NSInteger, FSTLLRBColor) { + FSTLLRBColorUnspecified = 0, + FSTLLRBColorRed = 1, + FSTLLRBColorBlack = 2, +}; + +/** + * FSTLLRBNode is the interface for a node in a FSTTreeSortedDictionary. + */ +@protocol FSTLLRBNode + +/** + * Creates a copy of the given node, changing any values that were specified. + * For any parameter that is left as nil, this instance's value will be used. + */ +- (instancetype)copyWith:(nullable id)aKey + withValue:(nullable id)aValue + withColor:(FSTLLRBColor)aColor + withLeft:(nullable id)aLeft + withRight:(nullable id)aRight; + +/** Returns a tree node with the given key-value pair set/updated. */ +- (id)insertKey:(id)aKey forValue:(id)aValue withComparator:(NSComparator)aComparator; + +/** Returns a tree node with the given key removed. */ +- (id)remove:(id)key withComparator:(NSComparator)aComparator; + +/** Returns the number of elements at this node or beneath it in the tree. */ +- (NSUInteger)count; + +/** Returns true if this is an FSTLLRBEmptyNode -- a leaf node in the tree. */ +- (BOOL)isEmpty; + +- (BOOL)inorderTraversal:(BOOL (^)(id key, id value))action; +- (BOOL)reverseTraversal:(BOOL (^)(id key, id value))action; + +/** Returns the left-most node under (or including) this node. */ +- (id)min; + +/** Returns the key of the left-most node under (or including) this node. */ +- (nullable id)minKey; + +/** Returns the key of the right-most node under (or including) this node. */ +- (nullable id)maxKey; + +/** Returns true if this node is red (as opposed to black). */ +- (BOOL)isRed; + +/** Checks that this node and below it hold the red-black invariants. Throws otherwise. */ +- (int)check; + +// Accessors for properties. +- (nullable id)key; +- (nullable id)value; +- (FSTLLRBColor)color; +- (nullable id)left; +- (nullable id)right; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/Immutable/FSTLLRBValueNode.h b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/Immutable/FSTLLRBValueNode.h new file mode 100644 index 0000000..9a62378 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/Immutable/FSTLLRBValueNode.h @@ -0,0 +1,29 @@ +#import + +#import "Firestore/third_party/Immutable/FSTLLRBNode.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface FSTLLRBValueNode : NSObject + +- (id)init __attribute__(( + unavailable("Use initWithKey:withValue:withColor:withLeft:withRight: instead."))); + +- (instancetype)initWithKey:(nullable id)key + withValue:(nullable id)value + withColor:(FSTLLRBColor)color + withLeft:(nullable id)left + withRight:(nullable id)right NS_DESIGNATED_INITIALIZER; + +@property(nonatomic, assign, readonly) FSTLLRBColor color; +@property(nonatomic, strong, readonly, nullable) id key; +@property(nonatomic, strong, readonly, nullable) id value; +@property(nonatomic, strong, readonly, nullable) id right; + +// This property cannot be readonly, because it is set when building the tree. +// TODO(klimt): Find a way to build the tree without mutating this. +@property(nonatomic, strong, nullable) id left; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/Immutable/FSTLLRBValueNode.m b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/Immutable/FSTLLRBValueNode.m new file mode 100644 index 0000000..e2590a1 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/Immutable/FSTLLRBValueNode.m @@ -0,0 +1,307 @@ +#import "Firestore/third_party/Immutable/FSTLLRBValueNode.h" + +#import "Firestore/third_party/Immutable/FSTLLRBEmptyNode.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface FSTLLRBValueNode () +@property(nonatomic, assign) FSTLLRBColor color; +@property(nonatomic, assign) NSUInteger count; +@property(nonatomic, strong) id key; +@property(nonatomic, strong) id value; +@property(nonatomic, strong) id right; +@end + +@implementation FSTLLRBValueNode + +- (NSString *)colorDescription { + NSString *color = @"unspecified"; + if (self.color == FSTLLRBColorRed) { + color = @"red"; + } else if (self.color == FSTLLRBColorBlack) { + color = @"black"; + } + return color; +} + +- (NSString *)description { + NSString *color = self.colorDescription; + return [NSString stringWithFormat:@"[key=%@ val=%@ color=%@]", self.key, self.value, color]; +} + +// Designated initializer. +- (instancetype)initWithKey:(id _Nullable)aKey + withValue:(id _Nullable)aValue + withColor:(FSTLLRBColor)aColor + withLeft:(id _Nullable)aLeft + withRight:(id _Nullable)aRight { + self = [super init]; + if (self) { + _key = aKey; + _value = aValue; + _color = aColor != FSTLLRBColorUnspecified ? aColor : FSTLLRBColorRed; + _left = aLeft != nil ? aLeft : [FSTLLRBEmptyNode emptyNode]; + _right = aRight != nil ? aRight : [FSTLLRBEmptyNode emptyNode]; + _count = NSNotFound; + } + return self; +} + +- (instancetype)copyWith:(id _Nullable)aKey + withValue:(id _Nullable)aValue + withColor:(FSTLLRBColor)aColor + withLeft:(id _Nullable)aLeft + withRight:(id _Nullable)aRight { + return [[FSTLLRBValueNode alloc] + initWithKey:(aKey != nil) ? aKey : self.key + withValue:(aValue != nil) ? aValue : self.value + withColor:(aColor != FSTLLRBColorUnspecified) ? aColor : self.color + withLeft:(aLeft != nil) ? aLeft : self.left + withRight:(aRight != nil) ? aRight : self.right]; +} + +- (void)setLeft:(nullable id)left { + // Setting the left node should be only done by the builder, so doing it after someone has + // memoized count is an error. + NSAssert(_count == NSNotFound, @"Can't update left node after using count"); + _left = left; +} + +- (NSUInteger)count { + if (_count == NSNotFound) { + _count = _left.count + 1 + _right.count; + } + return _count; +} + +- (BOOL)isEmpty { + return NO; +} + +/** + * Early terminates if action returns YES. + * + * @return The first truthy value returned by action, or the last falsey value returned by action. + */ +- (BOOL)inorderTraversal:(BOOL (^)(id key, id value))action { + return [self.left inorderTraversal:action] || action(self.key, self.value) || + [self.right inorderTraversal:action]; +} + +- (BOOL)reverseTraversal:(BOOL (^)(id key, id value))action { + return [self.right reverseTraversal:action] || action(self.key, self.value) || + [self.left reverseTraversal:action]; +} + +- (id)min { + if ([self.left isEmpty]) { + return self; + } else { + return [self.left min]; + } +} + +- (nullable id)minKey { + return [[self min] key]; +} + +- (nullable id)maxKey { + if ([self.right isEmpty]) { + return self.key; + } else { + return [self.right maxKey]; + } +} + +- (id)insertKey:(id)aKey forValue:(id)aValue withComparator:(NSComparator)aComparator { + NSComparisonResult cmp = aComparator(aKey, self.key); + FSTLLRBValueNode *n = self; + + if (cmp == NSOrderedAscending) { + n = [n copyWith:nil + withValue:nil + withColor:FSTLLRBColorUnspecified + withLeft:[n.left insertKey:aKey forValue:aValue withComparator:aComparator] + withRight:nil]; + } else if (cmp == NSOrderedSame) { + n = [n copyWith:nil + withValue:aValue + withColor:FSTLLRBColorUnspecified + withLeft:nil + withRight:nil]; + } else { + n = [n copyWith:nil + withValue:nil + withColor:FSTLLRBColorUnspecified + withLeft:nil + withRight:[n.right insertKey:aKey forValue:aValue withComparator:aComparator]]; + } + + return [n fixUp]; +} + +- (id)removeMin { + if ([self.left isEmpty]) { + return [FSTLLRBEmptyNode emptyNode]; + } + + FSTLLRBValueNode *n = self; + if (![n.left isRed] && ![n.left.left isRed]) { + n = [n moveRedLeft]; + } + + n = [n copyWith:nil + withValue:nil + withColor:FSTLLRBColorUnspecified + withLeft:[(FSTLLRBValueNode *)n.left removeMin] + withRight:nil]; + return [n fixUp]; +} + +- (id)fixUp { + FSTLLRBValueNode *n = self; + if ([n.right isRed] && ![n.left isRed]) n = [n rotateLeft]; + if ([n.left isRed] && [n.left.left isRed]) n = [n rotateRight]; + if ([n.left isRed] && [n.right isRed]) n = [n colorFlip]; + return n; +} + +- (FSTLLRBValueNode *)moveRedLeft { + FSTLLRBValueNode *n = [self colorFlip]; + if ([n.right.left isRed]) { + n = [n copyWith:nil + withValue:nil + withColor:FSTLLRBColorUnspecified + withLeft:nil + withRight:[(FSTLLRBValueNode *)n.right rotateRight]]; + n = [n rotateLeft]; + n = [n colorFlip]; + } + return n; +} + +- (FSTLLRBValueNode *)moveRedRight { + FSTLLRBValueNode *n = [self colorFlip]; + if ([n.left.left isRed]) { + n = [n rotateRight]; + n = [n colorFlip]; + } + return n; +} + +- (id)rotateLeft { + id nl = [self copyWith:nil + withValue:nil + withColor:FSTLLRBColorRed + withLeft:nil + withRight:self.right.left]; + return [self.right copyWith:nil withValue:nil withColor:self.color withLeft:nl withRight:nil]; +} + +- (id)rotateRight { + id nr = [self copyWith:nil + withValue:nil + withColor:FSTLLRBColorRed + withLeft:self.left.right + withRight:nil]; + return [self.left copyWith:nil withValue:nil withColor:self.color withLeft:nil withRight:nr]; +} + +- (id)colorFlip { + FSTLLRBColor color = self.color == FSTLLRBColorBlack ? FSTLLRBColorRed : FSTLLRBColorBlack; + FSTLLRBColor leftColor = + self.left.color == FSTLLRBColorBlack ? FSTLLRBColorRed : FSTLLRBColorBlack; + FSTLLRBColor rightColor = + self.right.color == FSTLLRBColorBlack ? FSTLLRBColorRed : FSTLLRBColorBlack; + + id nleft = + [self.left copyWith:nil withValue:nil withColor:leftColor withLeft:nil withRight:nil]; + id nright = + [self.right copyWith:nil withValue:nil withColor:rightColor withLeft:nil withRight:nil]; + + return [self copyWith:nil withValue:nil withColor:color withLeft:nleft withRight:nright]; +} + +- (id)remove:(id)aKey withComparator:(NSComparator)comparator { + id smallest; + FSTLLRBValueNode *n = self; + + if (comparator(aKey, n.key) == NSOrderedAscending) { + if (![n.left isEmpty] && ![n.left isRed] && ![n.left.left isRed]) { + n = [n moveRedLeft]; + } + n = [n copyWith:nil + withValue:nil + withColor:FSTLLRBColorUnspecified + withLeft:[n.left remove:aKey withComparator:comparator] + withRight:nil]; + } else { + if ([n.left isRed]) { + n = [n rotateRight]; + } + + if (![n.right isEmpty] && ![n.right isRed] && ![n.right.left isRed]) { + n = [n moveRedRight]; + } + + if (comparator(aKey, n.key) == NSOrderedSame) { + if ([n.right isEmpty]) { + return [FSTLLRBEmptyNode emptyNode]; + } else { + smallest = [n.right min]; + n = [n copyWith:smallest.key + withValue:smallest.value + withColor:FSTLLRBColorUnspecified + withLeft:nil + withRight:[(FSTLLRBValueNode *)n.right removeMin]]; + } + } + n = [n copyWith:nil + withValue:nil + withColor:FSTLLRBColorUnspecified + withLeft:nil + withRight:[n.right remove:aKey withComparator:comparator]]; + } + return [n fixUp]; +} + +- (BOOL)isRed { + return self.color == FSTLLRBColorRed; +} + +- (BOOL)checkMaxDepth { + int blackDepth = [self check]; + if (pow(2.0, blackDepth) <= ([self count] + 1)) { + return YES; + } else { + return NO; + } +} + +- (int)check { + int blackDepth = 0; + + if ([self isRed] && [self.left isRed]) { + @throw + [[NSException alloc] initWithName:@"check" reason:@"Red node has a red child" userInfo:nil]; + } + + if ([self.right isRed]) { + @throw [[NSException alloc] initWithName:@"check" reason:@"Right child is red" userInfo:nil]; + } + + blackDepth = [self.left check]; + if (blackDepth != [self.right check]) { + NSString *err = + [NSString stringWithFormat:@"(%@ -> %@)blackDepth: %d ; self.right check: %d", self.value, + self.colorDescription, blackDepth, [self.right check]]; + @throw [[NSException alloc] initWithName:@"check" reason:err userInfo:nil]; + } else { + int ret = blackDepth + ([self isRed] ? 0 : 1); + return ret; + } +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/Immutable/FSTTreeSortedDictionary.h b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/Immutable/FSTTreeSortedDictionary.h new file mode 100644 index 0000000..ca1a290 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/Immutable/FSTTreeSortedDictionary.h @@ -0,0 +1,41 @@ +/** + * Implementation of an immutable SortedMap using a Left-leaning + * Red-Black Tree, adapted from the implementation in Mugs + * (http://mads379.github.com/mugs/) by Mads Hartmann Jensen + * (mads379@gmail.com). + * + * Original paper on Left-leaning Red-Black Trees: + * http://www.cs.princeton.edu/~rs/talks/LLRB/LLRB.pdf + * + * Invariant 1: No red node has a red child + * Invariant 2: Every leaf path has the same number of black nodes + * Invariant 3: Only the left child can be red (left leaning) + */ + +#import + +#import "Firestore/third_party/Immutable/FSTImmutableSortedDictionary.h" +#import "Firestore/third_party/Immutable/FSTLLRBNode.h" + +NS_ASSUME_NONNULL_BEGIN + +/** + * FSTTreeSortedDictionary is a tree-based implementation of FSTImmutableSortedDictionary. + * You should not use this class directly. You should use FSTImmutableSortedDictionary. + */ +@interface FSTTreeSortedDictionary : + FSTImmutableSortedDictionary + +@property(nonatomic, copy, readonly) NSComparator comparator; +@property(nonatomic, strong, readonly) id root; + +- (id)init __attribute__((unavailable("Use initWithComparator:withRoot: instead."))); + +- (instancetype)initWithComparator:(NSComparator)aComparator; + +- (instancetype)initWithComparator:(NSComparator)aComparator + withRoot:(id)aRoot NS_DESIGNATED_INITIALIZER; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/Immutable/FSTTreeSortedDictionary.m b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/Immutable/FSTTreeSortedDictionary.m new file mode 100644 index 0000000..f113296 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/Immutable/FSTTreeSortedDictionary.m @@ -0,0 +1,352 @@ +#import "Firestore/third_party/Immutable/FSTTreeSortedDictionary.h" + +#import "Firestore/third_party/Immutable/FSTLLRBEmptyNode.h" +#import "Firestore/third_party/Immutable/FSTLLRBValueNode.h" +#import "Firestore/third_party/Immutable/FSTTreeSortedDictionaryEnumerator.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface FSTTreeSortedDictionary () + +- (FSTTreeSortedDictionary *)dictionaryBySettingObject:(id)aValue forKey:(id)aKey; + +@property(nonatomic, strong) id root; +@property(nonatomic, copy, readwrite) NSComparator comparator; +@end + +@implementation FSTTreeSortedDictionary + ++ (FSTTreeSortedDictionary *)dictionaryWithDictionary:(NSDictionary *)dictionary + comparator:(NSComparator)comparator { + __block FSTTreeSortedDictionary *dict = + [[FSTTreeSortedDictionary alloc] initWithComparator:comparator]; + [dictionary enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) { + dict = [dict dictionaryBySettingObject:obj forKey:key]; + }]; + return dict; +} + +- (id)initWithComparator:(NSComparator)aComparator { + return [self initWithComparator:aComparator withRoot:[FSTLLRBEmptyNode emptyNode]]; +} + +// Designated initializer. +- (id)initWithComparator:(NSComparator)aComparator withRoot:(id)aRoot { + self = [super init]; + if (self) { + self.root = aRoot; + self.comparator = aComparator; + } + return self; +} + +/** + * Returns a copy of the map, with the specified key/value added or replaced. + */ +- (FSTTreeSortedDictionary *)dictionaryBySettingObject:(id)aValue forKey:(id)aKey { + return [[FSTTreeSortedDictionary alloc] + initWithComparator:self.comparator + withRoot:[[self.root insertKey:aKey forValue:aValue withComparator:self.comparator] + copyWith:nil + withValue:nil + withColor:FSTLLRBColorBlack + withLeft:nil + withRight:nil]]; +} + +- (FSTTreeSortedDictionary *)dictionaryByRemovingObjectForKey:(id)aKey { + // Remove is somewhat expensive even if the key doesn't exist (the tree does rebalancing and + // stuff). So avoid it. + if (![self containsKey:aKey]) { + return self; + } else { + return [[FSTTreeSortedDictionary alloc] + initWithComparator:self.comparator + withRoot:[[self.root remove:aKey withComparator:self.comparator] + copyWith:nil + withValue:nil + withColor:FSTLLRBColorBlack + withLeft:nil + withRight:nil]]; + } +} + +- (nullable id)objectForKey:(id)key { + NSComparisonResult cmp; + id node = self.root; + while (![node isEmpty]) { + cmp = self.comparator(key, node.key); + if (cmp == NSOrderedSame) { + return node.value; + } else if (cmp == NSOrderedAscending) { + node = node.left; + } else { + node = node.right; + } + } + return nil; +} + +- (NSUInteger)indexOfKey:(id)key { + NSUInteger prunedNodes = 0; + id node = self.root; + while (![node isEmpty]) { + NSComparisonResult cmp = self.comparator(key, node.key); + if (cmp == NSOrderedSame) { + return prunedNodes + node.left.count; + } else if (cmp == NSOrderedAscending) { + node = node.left; + } else if (cmp == NSOrderedDescending) { + prunedNodes += node.left.count + 1; + node = node.right; + } + } + return NSNotFound; +} + +- (BOOL)isEmpty { + return [self.root isEmpty]; +} + +- (NSUInteger)count { + return [self.root count]; +} + +- (id)minKey { + return [self.root minKey]; +} + +- (id)maxKey { + return [self.root maxKey]; +} + +- (void)enumerateKeysAndObjectsUsingBlock:(void (^)(id, id, BOOL *))block { + [self enumerateKeysAndObjectsReverse:NO usingBlock:block]; +} + +- (void)enumerateKeysAndObjectsReverse:(BOOL)reverse usingBlock:(void (^)(id, id, BOOL *))block { + if (reverse) { + __block BOOL stop = NO; + [self.root reverseTraversal:^BOOL(id key, id value) { + block(key, value, &stop); + return stop; + }]; + } else { + __block BOOL stop = NO; + [self.root inorderTraversal:^BOOL(id key, id value) { + block(key, value, &stop); + return stop; + }]; + } +} + +- (BOOL)containsKey:(id)key { + return ([self objectForKey:key] != nil); +} + +- (NSEnumerator *)keyEnumerator { + return [[FSTTreeSortedDictionaryEnumerator alloc] initWithImmutableSortedDictionary:self + startKey:nil + endKey:nil + isReverse:NO]; +} + +- (NSEnumerator *)keyEnumeratorFrom:(id)startKey { + return [[FSTTreeSortedDictionaryEnumerator alloc] initWithImmutableSortedDictionary:self + startKey:startKey + endKey:nil + isReverse:NO]; +} + +- (NSEnumerator *)keyEnumeratorFrom:(id)startKey to:(nullable id)endKey { + return [[FSTTreeSortedDictionaryEnumerator alloc] initWithImmutableSortedDictionary:self + startKey:startKey + endKey:endKey + isReverse:NO]; +} + +- (NSEnumerator *)reverseKeyEnumerator { + return [[FSTTreeSortedDictionaryEnumerator alloc] initWithImmutableSortedDictionary:self + startKey:nil + endKey:nil + isReverse:YES]; +} + +- (NSEnumerator *)reverseKeyEnumeratorFrom:(id)startKey { + return [[FSTTreeSortedDictionaryEnumerator alloc] initWithImmutableSortedDictionary:self + startKey:startKey + endKey:nil + isReverse:YES]; +} + +#pragma mark - +#pragma mark Tree Builder + +// Code to efficiently build a red black tree. + +typedef struct { + unsigned int bits; + unsigned short count; + unsigned short current; +} Base12List; + +unsigned int LogBase2(unsigned int num) { + return (unsigned int)(log(num) / log(2)); +} + +/** + * Works like an iterator, so it moves to the next bit. Do not call more than list->count times. + * @return whether or not the next bit is a 1 in base {1,2}. + */ +BOOL Base12ListNext(Base12List *list) { + BOOL result = !(list->bits & (0x1 << list->current)); + list->current--; + return result; +} + +static inline unsigned BitMask(int x) { + return (x >= sizeof(unsigned) * CHAR_BIT) ? (unsigned)-1 : (1U << x) - 1; +} + +/** + * We represent the base{1,2} number as the combination of a binary number and a number of bits that + * we care about. We iterate backwards, from most significant bit to least, to build up the llrb + * nodes. 0 base 2 => 1 base {1,2}, 1 base 2 => 2 base {1,2} + */ +Base12List *NewBase12List(unsigned int length) { + size_t sz = sizeof(Base12List); + Base12List *list = calloc(1, sz); + // Calculate the number of bits that we care about + list->count = (unsigned short)LogBase2(length + 1); + unsigned int mask = BitMask(list->count); + list->bits = (length + 1) & mask; + list->current = list->count - 1; + return list; +} + +void FreeBase12List(Base12List *list) { + free(list); +} + ++ (nullable id)buildBalancedTree:(NSArray *)keys + dictionary:(NSDictionary *)dictionary + subArrayStartIndex:(NSUInteger)startIndex + length:(NSUInteger)length { + length = MIN(keys.count - startIndex, length); // Bound length by the actual length of the array + if (length == 0) { + return nil; + } else if (length == 1) { + id key = keys[startIndex]; + return [[FSTLLRBValueNode alloc] initWithKey:key + withValue:dictionary[key] + withColor:FSTLLRBColorBlack + withLeft:nil + withRight:nil]; + } else { + NSUInteger middle = length / 2; + id left = [FSTTreeSortedDictionary buildBalancedTree:keys + dictionary:dictionary + subArrayStartIndex:startIndex + length:middle]; + id right = [FSTTreeSortedDictionary buildBalancedTree:keys + dictionary:dictionary + subArrayStartIndex:(startIndex + middle + 1) + length:middle]; + id key = keys[startIndex + middle]; + return [[FSTLLRBValueNode alloc] initWithKey:key + withValue:dictionary[key] + withColor:FSTLLRBColorBlack + withLeft:left + withRight:right]; + } +} + ++ (nullable id)rootFrom12List:(Base12List *)base12List + keyList:(NSArray *)keyList + dictionary:(NSDictionary *)dictionary { + __block FSTLLRBValueNode *root = nil; + __block FSTLLRBValueNode *node = nil; + __block NSUInteger index = keyList.count; + + void (^buildPennant)(FSTLLRBColor, NSUInteger) = ^(FSTLLRBColor color, NSUInteger chunkSize) { + NSUInteger startIndex = index - chunkSize + 1; + index -= chunkSize; + id key = keyList[index]; + FSTLLRBValueNode *childTree = [self buildBalancedTree:keyList + dictionary:dictionary + subArrayStartIndex:startIndex + length:(chunkSize - 1)]; + FSTLLRBValueNode *pennant = [[FSTLLRBValueNode alloc] initWithKey:key + withValue:dictionary[key] + withColor:color + withLeft:nil + withRight:childTree]; + if (node) { + // This is the only place this property is set. + node.left = pennant; + node = pennant; + } else { + root = pennant; + node = pennant; + } + }; + + for (int i = 0; i < base12List->count; ++i) { + BOOL isOne = Base12ListNext(base12List); + NSUInteger chunkSize = (NSUInteger)pow(2.0, base12List->count - (i + 1)); + if (isOne) { + buildPennant(FSTLLRBColorBlack, chunkSize); + } else { + buildPennant(FSTLLRBColorBlack, chunkSize); + buildPennant(FSTLLRBColorRed, chunkSize); + } + } + return root; +} + +/** + * Uses the algorithm linked here: + * http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.46.1458 + */ ++ (FSTImmutableSortedDictionary *)fromDictionary:(NSDictionary *)dictionary + withComparator:(NSComparator)comparator { + // Steps: + // 0. Sort the array + // 1. Calculate the 1-2 number + // 2. Build From 1-2 number + // 0. for each digit in 1-2 number + // 0. calculate chunk size + // 1. build 1 or 2 pennants of that size + // 2. attach pennants and update node pointer + // 1. return root + NSMutableArray *sortedKeyList = [NSMutableArray arrayWithCapacity:dictionary.count]; + [dictionary enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) { + [sortedKeyList addObject:key]; + }]; + [sortedKeyList sortUsingComparator:comparator]; + + [sortedKeyList enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { + if (idx > 0) { + if (comparator(sortedKeyList[idx - 1], obj) != NSOrderedAscending) { + [NSException raise:NSInvalidArgumentException + format: + @"Can't create FSTImmutableSortedDictionary " + @"with keys with same ordering!"]; + } + } + }]; + + Base12List *list = NewBase12List((unsigned int)sortedKeyList.count); + id root = [self rootFrom12List:list keyList:sortedKeyList dictionary:dictionary]; + FreeBase12List(list); + + if (root != nil) { + return [[FSTTreeSortedDictionary alloc] initWithComparator:comparator withRoot:root]; + } else { + return [[FSTTreeSortedDictionary alloc] initWithComparator:comparator]; + } +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/Immutable/FSTTreeSortedDictionaryEnumerator.h b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/Immutable/FSTTreeSortedDictionaryEnumerator.h new file mode 100644 index 0000000..d31d4c2 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/Immutable/FSTTreeSortedDictionaryEnumerator.h @@ -0,0 +1,21 @@ +#import + +#import "Firestore/third_party/Immutable/FSTTreeSortedDictionary.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface FSTTreeSortedDictionaryEnumerator : NSEnumerator + +- (id)init __attribute__(( + unavailable("Use initWithImmutableSortedDictionary:startKey:isReverse: instead."))); + +- (instancetype)initWithImmutableSortedDictionary: + (FSTTreeSortedDictionary *)aDict + startKey:(KeyType _Nullable)startKey + endKey:(KeyType _Nullable)endKey + isReverse:(BOOL)reverse NS_DESIGNATED_INITIALIZER; +- (nullable ValueType)nextObject; + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/Immutable/FSTTreeSortedDictionaryEnumerator.m b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/Immutable/FSTTreeSortedDictionaryEnumerator.m new file mode 100644 index 0000000..b413792 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/Immutable/FSTTreeSortedDictionaryEnumerator.m @@ -0,0 +1,114 @@ +#import "Firestore/third_party/Immutable/FSTTreeSortedDictionaryEnumerator.h" + +NS_ASSUME_NONNULL_BEGIN + +// clang-format off +// For some reason, clang-format messes this line up... +@interface FSTTreeSortedDictionaryEnumerator () +/** The dictionary being enumerated. */ +@property(nonatomic, strong) FSTTreeSortedDictionary *immutableSortedDictionary; +/** The stack of tree nodes above the current node that will need to be revisited later. */ +@property(nonatomic, strong) NSMutableArray> *stack; +/** The direction of the traversal. YES=Descending. NO=Ascending. */ +@property(nonatomic, assign) BOOL isReverse; +/** If set, the enumerator should stop at this key and not return it. */ +@property(nonatomic, strong, nullable) id endKey; +@end +// clang-format on + +@implementation FSTTreeSortedDictionaryEnumerator + +- (instancetype)initWithImmutableSortedDictionary:(FSTTreeSortedDictionary *)aDict + startKey:(id _Nullable)startKey + endKey:(id _Nullable)endKey + isReverse:(BOOL)reverse { + self = [super init]; + if (self) { + _immutableSortedDictionary = aDict; + _stack = [[NSMutableArray alloc] init]; + _isReverse = reverse; + _endKey = endKey; + + NSComparator comparator = aDict.comparator; + id node = aDict.root; + + NSComparisonResult comparedToStart; + NSComparisonResult comparedToEnd; + while (![node isEmpty]) { + comparedToStart = NSOrderedDescending; + if (startKey) { + comparedToStart = comparator(node.key, startKey); + if (reverse) { + comparedToStart *= -1; + } + } + comparedToEnd = NSOrderedAscending; + if (endKey) { + comparedToEnd = comparator(node.key, endKey); + if (reverse) { + comparedToEnd *= -1; + } + } + + if (comparedToStart == NSOrderedAscending) { + // This node is less than our start key. Ignore it. + if (reverse) { + node = node.left; + } else { + node = node.right; + } + } else if (comparedToStart == NSOrderedSame) { + // This node is exactly equal to our start key. If it's less than the end key, push it on + // the stack, but stop iterating. + if (comparedToEnd == NSOrderedAscending) { + [_stack addObject:node]; + } + break; + } else { + // This node is greater than our start key. If it's less than our end key, add it to the + // stack and move on to the next one. + if (comparedToEnd == NSOrderedAscending) { + [_stack addObject:node]; + } + if (reverse) { + node = node.right; + } else { + node = node.left; + } + } + } + } + return self; +} + +- (nullable id)nextObject { + if ([self.stack count] == 0) { + return nil; + } + + id node = [self.stack lastObject]; + [self.stack removeLastObject]; + id result = node.key; + NSComparator comparator = self.immutableSortedDictionary.comparator; + + node = self.isReverse ? node.left : node.right; + while (![node isEmpty]) { + NSComparisonResult comparedToEnd = NSOrderedAscending; + if (self.endKey) { + comparedToEnd = comparator(node.key, self.endKey); + if (self.isReverse) { + comparedToEnd *= -1; + } + } + if (comparedToEnd == NSOrderedAscending) { + [self.stack addObject:node]; + } + node = self.isReverse ? node.right : node.left; + } + + return result; +} + +@end + +NS_ASSUME_NONNULL_END diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/BUILD.bazel b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/BUILD.bazel new file mode 100644 index 0000000..edd0274 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/BUILD.bazel @@ -0,0 +1,51 @@ +# +# Copyright 2017 The Abseil Authors. +# +# 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. +# + +package(default_visibility = ["//visibility:public"]) + +licenses(["notice"]) # Apache 2.0 + +load(":compiler_config_setting.bzl", "create_llvm_config") + +create_llvm_config( + name = "llvm_compiler", + visibility = [":__subpackages__"], +) + +# following configs are based on mapping defined in: https://git.io/v5Ijz +config_setting( + name = "ios", + values = { + "cpu": "darwin", + }, + visibility = [":__subpackages__"], +) + +config_setting( + name = "windows", + values = { + "cpu": "x64_windows", + }, + visibility = [":__subpackages__"], +) + +config_setting( + name = "ppc", + values = { + "cpu": "ppc", + }, + visibility = [":__subpackages__"], +) diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/CMakeLists.txt b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/CMakeLists.txt new file mode 100644 index 0000000..1d09b19 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/CMakeLists.txt @@ -0,0 +1,31 @@ +# +# Copyright 2017 The Abseil Authors. +# +# 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. +# + + + +add_subdirectory(base) +add_subdirectory(algorithm) +add_subdirectory(container) +add_subdirectory(debugging) +add_subdirectory(hash) +add_subdirectory(memory) +add_subdirectory(meta) +add_subdirectory(numeric) +add_subdirectory(strings) +add_subdirectory(synchronization) +add_subdirectory(time) +add_subdirectory(types) +add_subdirectory(utility) diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/algorithm/BUILD.bazel b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/algorithm/BUILD.bazel new file mode 100644 index 0000000..d04dc71 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/algorithm/BUILD.bazel @@ -0,0 +1,81 @@ +# +# Copyright 2017 The Abseil Authors. +# +# 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. +# + +load( + "//absl:copts.bzl", + "ABSL_DEFAULT_COPTS", + "ABSL_TEST_COPTS", +) + +package(default_visibility = ["//visibility:public"]) + +licenses(["notice"]) # Apache 2.0 + +cc_library( + name = "algorithm", + hdrs = ["algorithm.h"], + copts = ABSL_DEFAULT_COPTS, +) + +cc_test( + name = "algorithm_test", + size = "small", + srcs = ["algorithm_test.cc"], + copts = ABSL_TEST_COPTS, + deps = [ + ":algorithm", + "@com_google_googletest//:gtest_main", + ], +) + +cc_test( + name = "algorithm_benchmark", + srcs = ["equal_benchmark.cc"], + copts = ABSL_TEST_COPTS, + tags = ["benchmark"], + deps = [ + ":algorithm", + "//absl/base:core_headers", + "@com_github_google_benchmark//:benchmark_main", + ], +) + +cc_library( + name = "container", + hdrs = [ + "container.h", + ], + copts = ABSL_DEFAULT_COPTS, + deps = [ + ":algorithm", + "//absl/base:core_headers", + "//absl/meta:type_traits", + ], +) + +cc_test( + name = "container_test", + srcs = ["container_test.cc"], + copts = ABSL_TEST_COPTS, + deps = [ + ":container", + "//absl/base", + "//absl/base:core_headers", + "//absl/memory", + "//absl/types:span", + "@com_google_googletest//:gtest_main", + ], +) diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/algorithm/CMakeLists.txt b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/algorithm/CMakeLists.txt new file mode 100644 index 0000000..fdf45c5 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/algorithm/CMakeLists.txt @@ -0,0 +1,63 @@ +# +# Copyright 2017 The Abseil Authors. +# +# 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. +# + +list(APPEND ALGORITHM_PUBLIC_HEADERS + "algorithm.h" + "container.h" +) + + +# +## TESTS +# + +# test algorithm_test +list(APPEND ALGORITHM_TEST_SRC + "algorithm_test.cc" + ${ALGORITHM_PUBLIC_HEADERS} + ${ALGORITHM_INTERNAL_HEADERS} +) + +absl_header_library( + TARGET + absl_algorithm + EXPORT_NAME + algorithm +) + +absl_test( + TARGET + algorithm_test + SOURCES + ${ALGORITHM_TEST_SRC} + PUBLIC_LIBRARIES + absl::algorithm +) + + + + +# test container_test +set(CONTAINER_TEST_SRC "container_test.cc") + +absl_test( + TARGET + container_test + SOURCES + ${CONTAINER_TEST_SRC} + PUBLIC_LIBRARIES + absl::algorithm +) diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/algorithm/algorithm.h b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/algorithm/algorithm.h new file mode 100644 index 0000000..3d65864 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/algorithm/algorithm.h @@ -0,0 +1,150 @@ +// Copyright 2017 The Abseil Authors. +// +// 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. +// +// ----------------------------------------------------------------------------- +// File: algorithm.h +// ----------------------------------------------------------------------------- +// +// This header file contains Google extensions to the standard C++ +// header. + +#ifndef ABSL_ALGORITHM_ALGORITHM_H_ +#define ABSL_ALGORITHM_ALGORITHM_H_ + +#include +#include +#include + +namespace absl { + +namespace algorithm_internal { + +// Performs comparisons with operator==, similar to C++14's `std::equal_to<>`. +struct EqualTo { + template + bool operator()(const T& a, const U& b) const { + return a == b; + } +}; + +template +bool EqualImpl(InputIter1 first1, InputIter1 last1, InputIter2 first2, + InputIter2 last2, Pred pred, std::input_iterator_tag, + std::input_iterator_tag) { + while (true) { + if (first1 == last1) return first2 == last2; + if (first2 == last2) return false; + if (!pred(*first1, *first2)) return false; + ++first1; + ++first2; + } +} + +template +bool EqualImpl(InputIter1 first1, InputIter1 last1, InputIter2 first2, + InputIter2 last2, Pred&& pred, std::random_access_iterator_tag, + std::random_access_iterator_tag) { + return (last1 - first1 == last2 - first2) && + std::equal(first1, last1, first2, std::forward(pred)); +} + +// When we are using our own internal predicate that just applies operator==, we +// forward to the non-predicate form of std::equal. This enables an optimization +// in libstdc++ that can result in std::memcmp being used for integer types. +template +bool EqualImpl(InputIter1 first1, InputIter1 last1, InputIter2 first2, + InputIter2 last2, algorithm_internal::EqualTo /* unused */, + std::random_access_iterator_tag, + std::random_access_iterator_tag) { + return (last1 - first1 == last2 - first2) && + std::equal(first1, last1, first2); +} + +template +It RotateImpl(It first, It middle, It last, std::true_type) { + return std::rotate(first, middle, last); +} + +template +It RotateImpl(It first, It middle, It last, std::false_type) { + std::rotate(first, middle, last); + return std::next(first, std::distance(middle, last)); +} + +} // namespace algorithm_internal + +// Compares the equality of two ranges specified by pairs of iterators, using +// the given predicate, returning true iff for each corresponding iterator i1 +// and i2 in the first and second range respectively, pred(*i1, *i2) == true +// +// This comparison takes at most min(`last1` - `first1`, `last2` - `first2`) +// invocations of the predicate. Additionally, if InputIter1 and InputIter2 are +// both random-access iterators, and `last1` - `first1` != `last2` - `first2`, +// then the predicate is never invoked and the function returns false. +// +// This is a C++11-compatible implementation of C++14 `std::equal`. See +// http://en.cppreference.com/w/cpp/algorithm/equal for more information. +template +bool equal(InputIter1 first1, InputIter1 last1, InputIter2 first2, + InputIter2 last2, Pred&& pred) { + return algorithm_internal::EqualImpl( + first1, last1, first2, last2, std::forward(pred), + typename std::iterator_traits::iterator_category{}, + typename std::iterator_traits::iterator_category{}); +} + +// Performs comparison of two ranges specified by pairs of iterators using +// operator==. +template +bool equal(InputIter1 first1, InputIter1 last1, InputIter2 first2, + InputIter2 last2) { + return absl::equal(first1, last1, first2, last2, + algorithm_internal::EqualTo{}); +} + +// Performs a linear search for `value` using the iterator `first` up to +// but not including `last`, returning true if [`first`, `last`) contains an +// element equal to `value`. +// +// A linear search is of O(n) complexity which is guaranteed to make at most +// n = (`last` - `first`) comparisons. A linear search over short containers +// may be faster than a binary search, even when the container is sorted. +template +bool linear_search(InputIterator first, InputIterator last, + const EqualityComparable& value) { + return std::find(first, last, value) != last; +} + +// Performs a left rotation on a range of elements (`first`, `last`) such that +// `middle` is now the first element. `rotate()` returns an iterator pointing to +// the first element before rotation. This function is exactly the same as +// `std::rotate`, but fixes a bug in gcc +// <= 4.9 where `std::rotate` returns `void` instead of an iterator. +// +// The complexity of this algorithm is the same as that of `std::rotate`, but if +// `ForwardIterator` is not a random-access iterator, then `absl::rotate` +// performs an additional pass over the range to construct the return value. + +template +ForwardIterator rotate(ForwardIterator first, ForwardIterator middle, + ForwardIterator last) { + return algorithm_internal::RotateImpl( + first, middle, last, + std::is_same()); +} + +} // namespace absl + +#endif // ABSL_ALGORITHM_ALGORITHM_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/algorithm/algorithm_test.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/algorithm/algorithm_test.cc new file mode 100644 index 0000000..e4322bc --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/algorithm/algorithm_test.cc @@ -0,0 +1,182 @@ +// Copyright 2017 The Abseil Authors. +// +// 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 "absl/algorithm/algorithm.h" + +#include +#include +#include + +#include "gmock/gmock.h" +#include "gtest/gtest.h" + +namespace { + +TEST(EqualTest, DefaultComparisonRandomAccess) { + std::vector v1{1, 2, 3}; + std::vector v2 = v1; + std::vector v3 = {1, 2}; + std::vector v4 = {1, 2, 4}; + + EXPECT_TRUE(absl::equal(v1.begin(), v1.end(), v2.begin(), v2.end())); + EXPECT_FALSE(absl::equal(v1.begin(), v1.end(), v3.begin(), v3.end())); + EXPECT_FALSE(absl::equal(v1.begin(), v1.end(), v4.begin(), v4.end())); +} + +TEST(EqualTest, DefaultComparison) { + std::list lst1{1, 2, 3}; + std::list lst2 = lst1; + std::list lst3{1, 2}; + std::list lst4{1, 2, 4}; + + EXPECT_TRUE(absl::equal(lst1.begin(), lst1.end(), lst2.begin(), lst2.end())); + EXPECT_FALSE(absl::equal(lst1.begin(), lst1.end(), lst3.begin(), lst3.end())); + EXPECT_FALSE(absl::equal(lst1.begin(), lst1.end(), lst4.begin(), lst4.end())); +} + +TEST(EqualTest, EmptyRange) { + std::vector v1{1, 2, 3}; + std::vector empty1; + std::vector empty2; + + EXPECT_FALSE(absl::equal(v1.begin(), v1.end(), empty1.begin(), empty1.end())); + EXPECT_FALSE(absl::equal(empty1.begin(), empty1.end(), v1.begin(), v1.end())); + EXPECT_TRUE( + absl::equal(empty1.begin(), empty1.end(), empty2.begin(), empty2.end())); +} + +TEST(EqualTest, MixedIterTypes) { + std::vector v1{1, 2, 3}; + std::list lst1{v1.begin(), v1.end()}; + std::list lst2{1, 2, 4}; + std::list lst3{1, 2}; + + EXPECT_TRUE(absl::equal(v1.begin(), v1.end(), lst1.begin(), lst1.end())); + EXPECT_FALSE(absl::equal(v1.begin(), v1.end(), lst2.begin(), lst2.end())); + EXPECT_FALSE(absl::equal(v1.begin(), v1.end(), lst3.begin(), lst3.end())); +} + +TEST(EqualTest, MixedValueTypes) { + std::vector v1{1, 2, 3}; + std::vector v2{1, 2, 3}; + std::vector v3{1, 2}; + std::vector v4{1, 2, 4}; + + EXPECT_TRUE(absl::equal(v1.begin(), v1.end(), v2.begin(), v2.end())); + EXPECT_FALSE(absl::equal(v1.begin(), v1.end(), v3.begin(), v3.end())); + EXPECT_FALSE(absl::equal(v1.begin(), v1.end(), v4.begin(), v4.end())); +} + +TEST(EqualTest, WeirdIterators) { + std::vector v1{true, false}; + std::vector v2 = v1; + std::vector v3{true}; + std::vector v4{true, true, true}; + + EXPECT_TRUE(absl::equal(v1.begin(), v1.end(), v2.begin(), v2.end())); + EXPECT_FALSE(absl::equal(v1.begin(), v1.end(), v3.begin(), v3.end())); + EXPECT_FALSE(absl::equal(v1.begin(), v1.end(), v4.begin(), v4.end())); +} + +TEST(EqualTest, CustomComparison) { + int n[] = {1, 2, 3, 4}; + std::vector v1{&n[0], &n[1], &n[2]}; + std::vector v2 = v1; + std::vector v3{&n[0], &n[1], &n[3]}; + std::vector v4{&n[0], &n[1]}; + + auto eq = [](int* a, int* b) { return *a == *b; }; + + EXPECT_TRUE(absl::equal(v1.begin(), v1.end(), v2.begin(), v2.end(), eq)); + EXPECT_FALSE(absl::equal(v1.begin(), v1.end(), v3.begin(), v3.end(), eq)); + EXPECT_FALSE(absl::equal(v1.begin(), v1.end(), v4.begin(), v4.end(), eq)); +} + +TEST(EqualTest, MoveOnlyPredicate) { + std::vector v1{1, 2, 3}; + std::vector v2{4, 5, 6}; + + // move-only equality predicate + struct Eq { + Eq() = default; + Eq(Eq &&) = default; + Eq(const Eq &) = delete; + Eq &operator=(const Eq &) = delete; + bool operator()(const int a, const int b) const { return a == b; } + }; + + EXPECT_TRUE(absl::equal(v1.begin(), v1.end(), v1.begin(), v1.end(), Eq())); + EXPECT_FALSE(absl::equal(v1.begin(), v1.end(), v2.begin(), v2.end(), Eq())); +} + +struct CountingTrivialPred { + int* count; + bool operator()(int, int) const { + ++*count; + return true; + } +}; + +TEST(EqualTest, RandomAccessComplexity) { + std::vector v1{1, 1, 3}; + std::vector v2 = v1; + std::vector v3{1, 2}; + + do { + int count = 0; + absl::equal(v1.begin(), v1.end(), v2.begin(), v2.end(), + CountingTrivialPred{&count}); + EXPECT_LE(count, 3); + } while (std::next_permutation(v2.begin(), v2.end())); + + int count = 0; + absl::equal(v1.begin(), v1.end(), v3.begin(), v3.end(), + CountingTrivialPred{&count}); + EXPECT_EQ(count, 0); +} + +class LinearSearchTest : public testing::Test { + protected: + LinearSearchTest() : container_{1, 2, 3} {} + + static bool Is3(int n) { return n == 3; } + static bool Is4(int n) { return n == 4; } + + std::vector container_; +}; + +TEST_F(LinearSearchTest, linear_search) { + EXPECT_TRUE(absl::linear_search(container_.begin(), container_.end(), 3)); + EXPECT_FALSE(absl::linear_search(container_.begin(), container_.end(), 4)); +} + +TEST_F(LinearSearchTest, linear_searchConst) { + const std::vector *const const_container = &container_; + EXPECT_TRUE( + absl::linear_search(const_container->begin(), const_container->end(), 3)); + EXPECT_FALSE( + absl::linear_search(const_container->begin(), const_container->end(), 4)); +} + +TEST(RotateTest, Rotate) { + std::vector v{0, 1, 2, 3, 4}; + EXPECT_EQ(*absl::rotate(v.begin(), v.begin() + 2, v.end()), 0); + EXPECT_THAT(v, testing::ElementsAreArray({2, 3, 4, 0, 1})); + + std::list l{0, 1, 2, 3, 4}; + EXPECT_EQ(*absl::rotate(l.begin(), std::next(l.begin(), 3), l.end()), 0); + EXPECT_THAT(l, testing::ElementsAreArray({3, 4, 0, 1, 2})); +} + +} // namespace diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/algorithm/container.h b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/algorithm/container.h new file mode 100644 index 0000000..53ab156 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/algorithm/container.h @@ -0,0 +1,1642 @@ +// Copyright 2017 The Abseil Authors. +// +// 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. +// +// ----------------------------------------------------------------------------- +// File: container.h +// ----------------------------------------------------------------------------- +// +// This header file provides Container-based versions of algorithmic functions +// within the C++ standard library. The following standard library sets of +// functions are covered within this file: +// +// * Algorithmic functions +// * Algorithmic functions +// * functions +// +// The standard library functions operate on iterator ranges; the functions +// within this API operate on containers, though many return iterator ranges. +// +// All functions within this API are named with a `c_` prefix. Calls such as +// `absl::c_xx(container, ...) are equivalent to std:: functions such as +// `std::xx(std::begin(cont), std::end(cont), ...)`. Functions that act on +// iterators but not conceptually on iterator ranges (e.g. `std::iter_swap`) +// have no equivalent here. +// +// For template parameter and variable naming, `C` indicates the container type +// to which the function is applied, `Pred` indicates the predicate object type +// to be used by the function and `T` indicates the applicable element type. +// + +#ifndef ABSL_ALGORITHM_CONTAINER_H_ +#define ABSL_ALGORITHM_CONTAINER_H_ + +#include +#include +#include +#include +#include +#include +#include + +#include "absl/algorithm/algorithm.h" +#include "absl/base/macros.h" +#include "absl/meta/type_traits.h" + +namespace absl { + +namespace container_algorithm_internal { + +// NOTE: it is important to defer to ADL lookup for building with C++ modules, +// especially for headers like which are not visible from this file +// but specialize std::begin and std::end. +using std::begin; +using std::end; + +// The type of the iterator given by begin(c) (possibly std::begin(c)). +// ContainerIter> gives vector::const_iterator, +// while ContainerIter> gives vector::iterator. +template +using ContainerIter = decltype(begin(std::declval())); + +// An MSVC bug involving template parameter substitution requires us to use +// decltype() here instead of just std::pair. +template +using ContainerIterPairType = + decltype(std::make_pair(ContainerIter(), ContainerIter())); + +template +using ContainerDifferenceType = + decltype(std::distance(std::declval>(), + std::declval>())); + +template +using ContainerPointerType = + typename std::iterator_traits>::pointer; + +// container_algorithm_internal::c_begin and +// container_algorithm_internal::c_end are abbreviations for proper ADL +// lookup of std::begin and std::end, i.e. +// using std::begin; +// using std::end; +// std::foo(begin(c), end(c); +// becomes +// std::foo(container_algorithm_internal::begin(c), +// container_algorithm_internal::end(c)); +// These are meant for internal use only. + +template +ContainerIter c_begin(C& c) { return begin(c); } + +template +ContainerIter c_end(C& c) { return end(c); } + +} // namespace container_algorithm_internal + +// PUBLIC API + +//------------------------------------------------------------------------------ +// Abseil algorithm.h functions +//------------------------------------------------------------------------------ + +// c_linear_search() +// +// Container-based version of absl::linear_search() for performing a linear +// search within a container. +template +bool c_linear_search(const C& c, EqualityComparable&& value) { + return linear_search(container_algorithm_internal::c_begin(c), + container_algorithm_internal::c_end(c), + std::forward(value)); +} + +//------------------------------------------------------------------------------ +// algorithms +//------------------------------------------------------------------------------ + +// c_distance() +// +// Container-based version of the `std::distance()` function to +// return the number of elements within a container. +template +container_algorithm_internal::ContainerDifferenceType c_distance( + const C& c) { + return std::distance(container_algorithm_internal::c_begin(c), + container_algorithm_internal::c_end(c)); +} + +//------------------------------------------------------------------------------ +// Non-modifying sequence operations +//------------------------------------------------------------------------------ + +// c_all_of() +// +// Container-based version of the `std::all_of()` function to +// test a condition on all elements within a container. +template +bool c_all_of(const C& c, Pred&& pred) { + return std::all_of(container_algorithm_internal::c_begin(c), + container_algorithm_internal::c_end(c), + std::forward(pred)); +} + +// c_any_of() +// +// Container-based version of the `std::any_of()` function to +// test if any element in a container fulfills a condition. +template +bool c_any_of(const C& c, Pred&& pred) { + return std::any_of(container_algorithm_internal::c_begin(c), + container_algorithm_internal::c_end(c), + std::forward(pred)); +} + +// c_none_of() +// +// Container-based version of the `std::none_of()` function to +// test if no elements in a container fulfil a condition. +template +bool c_none_of(const C& c, Pred&& pred) { + return std::none_of(container_algorithm_internal::c_begin(c), + container_algorithm_internal::c_end(c), + std::forward(pred)); +} + +// c_for_each() +// +// Container-based version of the `std::for_each()` function to +// apply a function to a container's elements. +template +decay_t c_for_each(C&& c, Function&& f) { + return std::for_each(container_algorithm_internal::c_begin(c), + container_algorithm_internal::c_end(c), + std::forward(f)); +} + +// c_find() +// +// Container-based version of the `std::find()` function to find +// the first element containing the passed value within a container value. +template +container_algorithm_internal::ContainerIter c_find(C& c, T&& value) { + return std::find(container_algorithm_internal::c_begin(c), + container_algorithm_internal::c_end(c), + std::forward(value)); +} + +// c_find_if() +// +// Container-based version of the `std::find_if()` function to find +// the first element in a container matching the given condition. +template +container_algorithm_internal::ContainerIter c_find_if(C& c, Pred&& pred) { + return std::find_if(container_algorithm_internal::c_begin(c), + container_algorithm_internal::c_end(c), + std::forward(pred)); +} + +// c_find_if_not() +// +// Container-based version of the `std::find_if_not()` function to +// find the first element in a container not matching the given condition. +template +container_algorithm_internal::ContainerIter c_find_if_not(C& c, + Pred&& pred) { + return std::find_if_not(container_algorithm_internal::c_begin(c), + container_algorithm_internal::c_end(c), + std::forward(pred)); +} + +// c_find_end() +// +// Container-based version of the `std::find_end()` function to +// find the last subsequence within a container. +template +container_algorithm_internal::ContainerIter c_find_end( + Sequence1& sequence, Sequence2& subsequence) { + return std::find_end(container_algorithm_internal::c_begin(sequence), + container_algorithm_internal::c_end(sequence), + container_algorithm_internal::c_begin(subsequence), + container_algorithm_internal::c_end(subsequence)); +} + +// Overload of c_find_end() for using a predicate evaluation other than `==` as +// the function's test condition. +template +container_algorithm_internal::ContainerIter c_find_end( + Sequence1& sequence, Sequence2& subsequence, BinaryPredicate&& pred) { + return std::find_end(container_algorithm_internal::c_begin(sequence), + container_algorithm_internal::c_end(sequence), + container_algorithm_internal::c_begin(subsequence), + container_algorithm_internal::c_end(subsequence), + std::forward(pred)); +} + +// c_find_first_of() +// +// Container-based version of the `std::find_first_of()` function to +// find the first elements in an ordered set within a container. +template +container_algorithm_internal::ContainerIter c_find_first_of(C1& container, + C2& options) { + return std::find_first_of(container_algorithm_internal::c_begin(container), + container_algorithm_internal::c_end(container), + container_algorithm_internal::c_begin(options), + container_algorithm_internal::c_end(options)); +} + +// Overload of c_find_first_of() for using a predicate evaluation other than +// `==` as the function's test condition. +template +container_algorithm_internal::ContainerIter c_find_first_of( + C1& container, C2& options, BinaryPredicate&& pred) { + return std::find_first_of(container_algorithm_internal::c_begin(container), + container_algorithm_internal::c_end(container), + container_algorithm_internal::c_begin(options), + container_algorithm_internal::c_end(options), + std::forward(pred)); +} + +// c_adjacent_find() +// +// Container-based version of the `std::adjacent_find()` function to +// find equal adjacent elements within a container. +template +container_algorithm_internal::ContainerIter c_adjacent_find( + Sequence& sequence) { + return std::adjacent_find(container_algorithm_internal::c_begin(sequence), + container_algorithm_internal::c_end(sequence)); +} + +// Overload of c_adjacent_find() for using a predicate evaluation other than +// `==` as the function's test condition. +template +container_algorithm_internal::ContainerIter c_adjacent_find( + Sequence& sequence, BinaryPredicate&& pred) { + return std::adjacent_find(container_algorithm_internal::c_begin(sequence), + container_algorithm_internal::c_end(sequence), + std::forward(pred)); +} + +// c_count() +// +// Container-based version of the `std::count()` function to count +// values that match within a container. +template +container_algorithm_internal::ContainerDifferenceType c_count( + const C& c, T&& value) { + return std::count(container_algorithm_internal::c_begin(c), + container_algorithm_internal::c_end(c), + std::forward(value)); +} + +// c_count_if() +// +// Container-based version of the `std::count_if()` function to +// count values matching a condition within a container. +template +container_algorithm_internal::ContainerDifferenceType c_count_if( + const C& c, Pred&& pred) { + return std::count_if(container_algorithm_internal::c_begin(c), + container_algorithm_internal::c_end(c), + std::forward(pred)); +} + +// c_mismatch() +// +// Container-based version of the `std::mismatch()` function to +// return the first element where two ordered containers differ. +template +container_algorithm_internal::ContainerIterPairType +c_mismatch(C1& c1, C2& c2) { + return std::mismatch(container_algorithm_internal::c_begin(c1), + container_algorithm_internal::c_end(c1), + container_algorithm_internal::c_begin(c2)); +} + +// Overload of c_mismatch() for using a predicate evaluation other than `==` as +// the function's test condition. +template +container_algorithm_internal::ContainerIterPairType +c_mismatch(C1& c1, C2& c2, BinaryPredicate&& pred) { + return std::mismatch(container_algorithm_internal::c_begin(c1), + container_algorithm_internal::c_end(c1), + container_algorithm_internal::c_begin(c2), + std::forward(pred)); +} + +// c_equal() +// +// Container-based version of the `std::equal()` function to +// test whether two containers are equal. +// +// NOTE: the semantics of c_equal() are slightly different than those of +// equal(): while the latter iterates over the second container only up to the +// size of the first container, c_equal() also checks whether the container +// sizes are equal. This better matches expectations about c_equal() based on +// its signature. +// +// Example: +// vector v1 = <1, 2, 3>; +// vector v2 = <1, 2, 3, 4>; +// equal(std::begin(v1), std::end(v1), std::begin(v2)) returns true +// c_equal(v1, v2) returns false + +template +bool c_equal(const C1& c1, const C2& c2) { + return ((c1.size() == c2.size()) && + std::equal(container_algorithm_internal::c_begin(c1), + container_algorithm_internal::c_end(c1), + container_algorithm_internal::c_begin(c2))); +} + +// Overload of c_equal() for using a predicate evaluation other than `==` as +// the function's test condition. +template +bool c_equal(const C1& c1, const C2& c2, BinaryPredicate&& pred) { + return ((c1.size() == c2.size()) && + std::equal(container_algorithm_internal::c_begin(c1), + container_algorithm_internal::c_end(c1), + container_algorithm_internal::c_begin(c2), + std::forward(pred))); +} + +// c_is_permutation() +// +// Container-based version of the `std::is_permutation()` function +// to test whether a container is a permutation of another. +template +bool c_is_permutation(const C1& c1, const C2& c2) { + using std::begin; + using std::end; + return c1.size() == c2.size() && + std::is_permutation(begin(c1), end(c1), begin(c2)); +} + +// Overload of c_is_permutation() for using a predicate evaluation other than +// `==` as the function's test condition. +template +bool c_is_permutation(const C1& c1, const C2& c2, BinaryPredicate&& pred) { + using std::begin; + using std::end; + return c1.size() == c2.size() && + std::is_permutation(begin(c1), end(c1), begin(c2), + std::forward(pred)); +} + +// c_search() +// +// Container-based version of the `std::search()` function to search +// a container for a subsequence. +template +container_algorithm_internal::ContainerIter c_search( + Sequence1& sequence, Sequence2& subsequence) { + return std::search(container_algorithm_internal::c_begin(sequence), + container_algorithm_internal::c_end(sequence), + container_algorithm_internal::c_begin(subsequence), + container_algorithm_internal::c_end(subsequence)); +} + +// Overload of c_search() for using a predicate evaluation other than +// `==` as the function's test condition. +template +container_algorithm_internal::ContainerIter c_search( + Sequence1& sequence, Sequence2& subsequence, BinaryPredicate&& pred) { + return std::search(container_algorithm_internal::c_begin(sequence), + container_algorithm_internal::c_end(sequence), + container_algorithm_internal::c_begin(subsequence), + container_algorithm_internal::c_end(subsequence), + std::forward(pred)); +} + +// c_search_n() +// +// Container-based version of the `std::search_n()` function to +// search a container for the first sequence of N elements. +template +container_algorithm_internal::ContainerIter c_search_n( + Sequence& sequence, Size count, T&& value) { + return std::search_n(container_algorithm_internal::c_begin(sequence), + container_algorithm_internal::c_end(sequence), count, + std::forward(value)); +} + +// Overload of c_search_n() for using a predicate evaluation other than +// `==` as the function's test condition. +template +container_algorithm_internal::ContainerIter c_search_n( + Sequence& sequence, Size count, T&& value, BinaryPredicate&& pred) { + return std::search_n(container_algorithm_internal::c_begin(sequence), + container_algorithm_internal::c_end(sequence), count, + std::forward(value), + std::forward(pred)); +} + +//------------------------------------------------------------------------------ +// Modifying sequence operations +//------------------------------------------------------------------------------ + +// c_copy() +// +// Container-based version of the `std::copy()` function to copy a +// container's elements into an iterator. +template +OutputIterator c_copy(const InputSequence& input, OutputIterator output) { + return std::copy(container_algorithm_internal::c_begin(input), + container_algorithm_internal::c_end(input), output); +} + +// c_copy_n() +// +// Container-based version of the `std::copy_n()` function to copy a +// container's first N elements into an iterator. +template +OutputIterator c_copy_n(const C& input, Size n, OutputIterator output) { + return std::copy_n(container_algorithm_internal::c_begin(input), n, output); +} + +// c_copy_if() +// +// Container-based version of the `std::copy_if()` function to copy +// a container's elements satisfying some condition into an iterator. +template +OutputIterator c_copy_if(const InputSequence& input, OutputIterator output, + Pred&& pred) { + return std::copy_if(container_algorithm_internal::c_begin(input), + container_algorithm_internal::c_end(input), output, + std::forward(pred)); +} + +// c_copy_backward() +// +// Container-based version of the `std::copy_backward()` function to +// copy a container's elements in reverse order into an iterator. +template +BidirectionalIterator c_copy_backward(const C& src, + BidirectionalIterator dest) { + return std::copy_backward(container_algorithm_internal::c_begin(src), + container_algorithm_internal::c_end(src), dest); +} + +// c_move() +// +// Container-based version of the `std::move()` function to move +// a container's elements into an iterator. +template +OutputIterator c_move(C&& src, OutputIterator dest) { + return std::move(container_algorithm_internal::c_begin(src), + container_algorithm_internal::c_end(src), dest); +} + +// c_swap_ranges() +// +// Container-based version of the `std::swap_ranges()` function to +// swap a container's elements with another container's elements. +template +container_algorithm_internal::ContainerIter c_swap_ranges(C1& c1, C2& c2) { + return std::swap_ranges(container_algorithm_internal::c_begin(c1), + container_algorithm_internal::c_end(c1), + container_algorithm_internal::c_begin(c2)); +} + +// c_transform() +// +// Container-based version of the `std::transform()` function to +// transform a container's elements using the unary operation, storing the +// result in an iterator pointing to the last transformed element in the output +// range. +template +OutputIterator c_transform(const InputSequence& input, OutputIterator output, + UnaryOp&& unary_op) { + return std::transform(container_algorithm_internal::c_begin(input), + container_algorithm_internal::c_end(input), output, + std::forward(unary_op)); +} + +// Overload of c_transform() for performing a transformation using a binary +// predicate. +template +OutputIterator c_transform(const InputSequence1& input1, + const InputSequence2& input2, OutputIterator output, + BinaryOp&& binary_op) { + return std::transform(container_algorithm_internal::c_begin(input1), + container_algorithm_internal::c_end(input1), + container_algorithm_internal::c_begin(input2), output, + std::forward(binary_op)); +} + +// c_replace() +// +// Container-based version of the `std::replace()` function to +// replace a container's elements of some value with a new value. The container +// is modified in place. +template +void c_replace(Sequence& sequence, const T& old_value, const T& new_value) { + std::replace(container_algorithm_internal::c_begin(sequence), + container_algorithm_internal::c_end(sequence), old_value, + new_value); +} + +// c_replace_if() +// +// Container-based version of the `std::replace_if()` function to +// replace a container's elements of some value with a new value based on some +// condition. The container is modified in place. +template +void c_replace_if(C& c, Pred&& pred, T&& new_value) { + std::replace_if(container_algorithm_internal::c_begin(c), + container_algorithm_internal::c_end(c), + std::forward(pred), std::forward(new_value)); +} + +// c_replace_copy() +// +// Container-based version of the `std::replace_copy()` function to +// replace a container's elements of some value with a new value and return the +// results within an iterator. +template +OutputIterator c_replace_copy(const C& c, OutputIterator result, T&& old_value, + T&& new_value) { + return std::replace_copy(container_algorithm_internal::c_begin(c), + container_algorithm_internal::c_end(c), result, + std::forward(old_value), + std::forward(new_value)); +} + +// c_replace_copy_if() +// +// Container-based version of the `std::replace_copy_if()` function +// to replace a container's elements of some value with a new value based on +// some condition, and return the results within an iterator. +template +OutputIterator c_replace_copy_if(const C& c, OutputIterator result, Pred&& pred, + T&& new_value) { + return std::replace_copy_if(container_algorithm_internal::c_begin(c), + container_algorithm_internal::c_end(c), result, + std::forward(pred), + std::forward(new_value)); +} + +// c_fill() +// +// Container-based version of the `std::fill()` function to fill a +// container with some value. +template +void c_fill(C& c, T&& value) { + std::fill(container_algorithm_internal::c_begin(c), + container_algorithm_internal::c_end(c), std::forward(value)); +} + +// c_fill_n() +// +// Container-based version of the `std::fill_n()` function to fill +// the first N elements in a container with some value. +template +void c_fill_n(C& c, Size n, T&& value) { + std::fill_n(container_algorithm_internal::c_begin(c), n, + std::forward(value)); +} + +// c_generate() +// +// Container-based version of the `std::generate()` function to +// assign a container's elements to the values provided by the given generator. +template +void c_generate(C& c, Generator&& gen) { + std::generate(container_algorithm_internal::c_begin(c), + container_algorithm_internal::c_end(c), + std::forward(gen)); +} + +// c_generate_n() +// +// Container-based version of the `std::generate_n()` function to +// assign a container's first N elements to the values provided by the given +// generator. +template +container_algorithm_internal::ContainerIter c_generate_n(C& c, Size n, + Generator&& gen) { + return std::generate_n(container_algorithm_internal::c_begin(c), n, + std::forward(gen)); +} + +// Note: `c_xx()` container versions for `remove()`, `remove_if()`, +// and `unique()` are omitted, because it's not clear whether or not such +// functions should call erase on their supplied sequences afterwards. Either +// behavior would be surprising for a different set of users. +// + +// c_remove_copy() +// +// Container-based version of the `std::remove_copy()` function to +// copy a container's elements while removing any elements matching the given +// `value`. +template +OutputIterator c_remove_copy(const C& c, OutputIterator result, T&& value) { + return std::remove_copy(container_algorithm_internal::c_begin(c), + container_algorithm_internal::c_end(c), result, + std::forward(value)); +} + +// c_remove_copy_if() +// +// Container-based version of the `std::remove_copy_if()` function +// to copy a container's elements while removing any elements matching the given +// condition. +template +OutputIterator c_remove_copy_if(const C& c, OutputIterator result, + Pred&& pred) { + return std::remove_copy_if(container_algorithm_internal::c_begin(c), + container_algorithm_internal::c_end(c), result, + std::forward(pred)); +} + +// c_unique_copy() +// +// Container-based version of the `std::unique_copy()` function to +// copy a container's elements while removing any elements containing duplicate +// values. +template +OutputIterator c_unique_copy(const C& c, OutputIterator result) { + return std::unique_copy(container_algorithm_internal::c_begin(c), + container_algorithm_internal::c_end(c), result); +} + +// Overload of c_unique_copy() for using a predicate evaluation other than +// `==` for comparing uniqueness of the element values. +template +OutputIterator c_unique_copy(const C& c, OutputIterator result, + BinaryPredicate&& pred) { + return std::unique_copy(container_algorithm_internal::c_begin(c), + container_algorithm_internal::c_end(c), result, + std::forward(pred)); +} + +// c_reverse() +// +// Container-based version of the `std::reverse()` function to +// reverse a container's elements. +template +void c_reverse(Sequence& sequence) { + std::reverse(container_algorithm_internal::c_begin(sequence), + container_algorithm_internal::c_end(sequence)); +} + +// c_reverse_copy() +// +// Container-based version of the `std::reverse()` function to +// reverse a container's elements and write them to an iterator range. +template +OutputIterator c_reverse_copy(const C& sequence, OutputIterator result) { + return std::reverse_copy(container_algorithm_internal::c_begin(sequence), + container_algorithm_internal::c_end(sequence), + result); +} + +// c_rotate() +// +// Container-based version of the `std::rotate()` function to +// shift a container's elements leftward such that the `middle` element becomes +// the first element in the container. +template > +Iterator c_rotate(C& sequence, Iterator middle) { + return absl::rotate(container_algorithm_internal::c_begin(sequence), middle, + container_algorithm_internal::c_end(sequence)); +} + +// c_rotate_copy() +// +// Container-based version of the `std::rotate_copy()` function to +// shift a container's elements leftward such that the `middle` element becomes +// the first element in a new iterator range. +template +OutputIterator c_rotate_copy( + const C& sequence, + container_algorithm_internal::ContainerIter middle, + OutputIterator result) { + return std::rotate_copy(container_algorithm_internal::c_begin(sequence), + middle, container_algorithm_internal::c_end(sequence), + result); +} + +// c_shuffle() +// +// Container-based version of the `std::shuffle()` function to +// randomly shuffle elements within the container using a `gen()` uniform random +// number generator. +template +void c_shuffle(RandomAccessContainer& c, UniformRandomBitGenerator&& gen) { + std::shuffle(container_algorithm_internal::c_begin(c), + container_algorithm_internal::c_end(c), + std::forward(gen)); +} + +//------------------------------------------------------------------------------ +// Partition functions +//------------------------------------------------------------------------------ + +// c_is_partitioned() +// +// Container-based version of the `std::is_partitioned()` function +// to test whether all elements in the container for which `pred` returns `true` +// precede those for which `pred` is `false`. +template +bool c_is_partitioned(const C& c, Pred&& pred) { + return std::is_partitioned(container_algorithm_internal::c_begin(c), + container_algorithm_internal::c_end(c), + std::forward(pred)); +} + +// c_partition() +// +// Container-based version of the `std::partition()` function +// to rearrange all elements in a container in such a way that all elements for +// which `pred` returns `true` precede all those for which it returns `false`, +// returning an iterator to the first element of the second group. +template +container_algorithm_internal::ContainerIter c_partition(C& c, Pred&& pred) { + return std::partition(container_algorithm_internal::c_begin(c), + container_algorithm_internal::c_end(c), + std::forward(pred)); +} + +// c_stable_partition() +// +// Container-based version of the `std::stable_partition()` function +// to rearrange all elements in a container in such a way that all elements for +// which `pred` returns `true` precede all those for which it returns `false`, +// preserving the relative ordering between the two groups. The function returns +// an iterator to the first element of the second group. +template +container_algorithm_internal::ContainerIter c_stable_partition(C& c, + Pred&& pred) { + return std::stable_partition(container_algorithm_internal::c_begin(c), + container_algorithm_internal::c_end(c), + std::forward(pred)); +} + +// c_partition_copy() +// +// Container-based version of the `std::partition_copy()` function +// to partition a container's elements and return them into two iterators: one +// for which `pred` returns `true`, and one for which `pred` returns `false.` + +template +std::pair c_partition_copy( + const C& c, OutputIterator1 out_true, OutputIterator2 out_false, + Pred&& pred) { + return std::partition_copy(container_algorithm_internal::c_begin(c), + container_algorithm_internal::c_end(c), out_true, + out_false, std::forward(pred)); +} + +// c_partition_point() +// +// Container-based version of the `std::partition_point()` function +// to return the first element of an already partitioned container for which +// the given `pred` is not `true`. +template +container_algorithm_internal::ContainerIter c_partition_point(C& c, + Pred&& pred) { + return std::partition_point(container_algorithm_internal::c_begin(c), + container_algorithm_internal::c_end(c), + std::forward(pred)); +} + +//------------------------------------------------------------------------------ +// Sorting functions +//------------------------------------------------------------------------------ + +// c_sort() +// +// Container-based version of the `std::sort()` function +// to sort elements in ascending order of their values. +template +void c_sort(C& c) { + std::sort(container_algorithm_internal::c_begin(c), + container_algorithm_internal::c_end(c)); +} + +// Overload of c_sort() for performing a `comp` comparison other than the +// default `operator<`. +template +void c_sort(C& c, Compare&& comp) { + std::sort(container_algorithm_internal::c_begin(c), + container_algorithm_internal::c_end(c), + std::forward(comp)); +} + +// c_stable_sort() +// +// Container-based version of the `std::stable_sort()` function +// to sort elements in ascending order of their values, preserving the order +// of equivalents. +template +void c_stable_sort(C& c) { + std::stable_sort(container_algorithm_internal::c_begin(c), + container_algorithm_internal::c_end(c)); +} + +// Overload of c_stable_sort() for performing a `comp` comparison other than the +// default `operator<`. +template +void c_stable_sort(C& c, Compare&& comp) { + std::stable_sort(container_algorithm_internal::c_begin(c), + container_algorithm_internal::c_end(c), + std::forward(comp)); +} + +// c_is_sorted() +// +// Container-based version of the `std::is_sorted()` function +// to evaluate whether the given container is sorted in ascending order. +template +bool c_is_sorted(const C& c) { + return std::is_sorted(container_algorithm_internal::c_begin(c), + container_algorithm_internal::c_end(c)); +} + +// c_is_sorted() overload for performing a `comp` comparison other than the +// default `operator<`. +template +bool c_is_sorted(const C& c, Compare&& comp) { + return std::is_sorted(container_algorithm_internal::c_begin(c), + container_algorithm_internal::c_end(c), + std::forward(comp)); +} + +// c_partial_sort() +// +// Container-based version of the `std::partial_sort()` function +// to rearrange elements within a container such that elements before `middle` +// are sorted in ascending order. +template +void c_partial_sort( + RandomAccessContainer& sequence, + container_algorithm_internal::ContainerIter middle) { + std::partial_sort(container_algorithm_internal::c_begin(sequence), middle, + container_algorithm_internal::c_end(sequence)); +} + +// Overload of c_partial_sort() for performing a `comp` comparison other than +// the default `operator<`. +template +void c_partial_sort( + RandomAccessContainer& sequence, + container_algorithm_internal::ContainerIter middle, + Compare&& comp) { + std::partial_sort(container_algorithm_internal::c_begin(sequence), middle, + container_algorithm_internal::c_end(sequence), + std::forward(comp)); +} + +// c_partial_sort_copy() +// +// Container-based version of the `std::partial_sort_copy()` +// function to sort elements within a container such that elements before +// `middle` are sorted in ascending order, and return the result within an +// iterator. +template +container_algorithm_internal::ContainerIter +c_partial_sort_copy(const C& sequence, RandomAccessContainer& result) { + return std::partial_sort_copy(container_algorithm_internal::c_begin(sequence), + container_algorithm_internal::c_end(sequence), + container_algorithm_internal::c_begin(result), + container_algorithm_internal::c_end(result)); +} + +// Overload of c_partial_sort_copy() for performing a `comp` comparison other +// than the default `operator<`. +template +container_algorithm_internal::ContainerIter +c_partial_sort_copy(const C& sequence, RandomAccessContainer& result, + Compare&& comp) { + return std::partial_sort_copy(container_algorithm_internal::c_begin(sequence), + container_algorithm_internal::c_end(sequence), + container_algorithm_internal::c_begin(result), + container_algorithm_internal::c_end(result), + std::forward(comp)); +} + +// c_is_sorted_until() +// +// Container-based version of the `std::is_sorted_until()` function +// to return the first element within a container that is not sorted in +// ascending order as an iterator. +template +container_algorithm_internal::ContainerIter c_is_sorted_until(C& c) { + return std::is_sorted_until(container_algorithm_internal::c_begin(c), + container_algorithm_internal::c_end(c)); +} + +// Overload of c_is_sorted_until() for performing a `comp` comparison other than +// the default `operator<`. +template +container_algorithm_internal::ContainerIter c_is_sorted_until( + C& c, Compare&& comp) { + return std::is_sorted_until(container_algorithm_internal::c_begin(c), + container_algorithm_internal::c_end(c), + std::forward(comp)); +} + +// c_nth_element() +// +// Container-based version of the `std::nth_element()` function +// to rearrange the elements within a container such that the `nth` element +// would be in that position in an ordered sequence; other elements may be in +// any order, except that all preceding `nth` will be less than that element, +// and all following `nth` will be greater than that element. +template +void c_nth_element( + RandomAccessContainer& sequence, + container_algorithm_internal::ContainerIter nth) { + std::nth_element(container_algorithm_internal::c_begin(sequence), nth, + container_algorithm_internal::c_end(sequence)); +} + +// Overload of c_nth_element() for performing a `comp` comparison other than +// the default `operator<`. +template +void c_nth_element( + RandomAccessContainer& sequence, + container_algorithm_internal::ContainerIter nth, + Compare&& comp) { + std::nth_element(container_algorithm_internal::c_begin(sequence), nth, + container_algorithm_internal::c_end(sequence), + std::forward(comp)); +} + +//------------------------------------------------------------------------------ +// Binary Search +//------------------------------------------------------------------------------ + +// c_lower_bound() +// +// Container-based version of the `std::lower_bound()` function +// to return an iterator pointing to the first element in a sorted container +// which does not compare less than `value`. +template +container_algorithm_internal::ContainerIter c_lower_bound( + Sequence& sequence, T&& value) { + return std::lower_bound(container_algorithm_internal::c_begin(sequence), + container_algorithm_internal::c_end(sequence), + std::forward(value)); +} + +// Overload of c_lower_bound() for performing a `comp` comparison other than +// the default `operator<`. +template +container_algorithm_internal::ContainerIter c_lower_bound( + Sequence& sequence, T&& value, Compare&& comp) { + return std::lower_bound(container_algorithm_internal::c_begin(sequence), + container_algorithm_internal::c_end(sequence), + std::forward(value), std::forward(comp)); +} + +// c_upper_bound() +// +// Container-based version of the `std::upper_bound()` function +// to return an iterator pointing to the first element in a sorted container +// which is greater than `value`. +template +container_algorithm_internal::ContainerIter c_upper_bound( + Sequence& sequence, T&& value) { + return std::upper_bound(container_algorithm_internal::c_begin(sequence), + container_algorithm_internal::c_end(sequence), + std::forward(value)); +} + +// Overload of c_upper_bound() for performing a `comp` comparison other than +// the default `operator<`. +template +container_algorithm_internal::ContainerIter c_upper_bound( + Sequence& sequence, T&& value, Compare&& comp) { + return std::upper_bound(container_algorithm_internal::c_begin(sequence), + container_algorithm_internal::c_end(sequence), + std::forward(value), std::forward(comp)); +} + +// c_equal_range() +// +// Container-based version of the `std::equal_range()` function +// to return an iterator pair pointing to the first and last elements in a +// sorted container which compare equal to `value`. +template +container_algorithm_internal::ContainerIterPairType +c_equal_range(Sequence& sequence, T&& value) { + return std::equal_range(container_algorithm_internal::c_begin(sequence), + container_algorithm_internal::c_end(sequence), + std::forward(value)); +} + +// Overload of c_equal_range() for performing a `comp` comparison other than +// the default `operator<`. +template +container_algorithm_internal::ContainerIterPairType +c_equal_range(Sequence& sequence, T&& value, Compare&& comp) { + return std::equal_range(container_algorithm_internal::c_begin(sequence), + container_algorithm_internal::c_end(sequence), + std::forward(value), std::forward(comp)); +} + +// c_binary_search() +// +// Container-based version of the `std::binary_search()` function +// to test if any element in the sorted container contains a value equivalent to +// 'value'. +template +bool c_binary_search(Sequence&& sequence, T&& value) { + return std::binary_search(container_algorithm_internal::c_begin(sequence), + container_algorithm_internal::c_end(sequence), + std::forward(value)); +} + +// Overload of c_binary_search() for performing a `comp` comparison other than +// the default `operator<`. +template +bool c_binary_search(Sequence&& sequence, T&& value, Compare&& comp) { + return std::binary_search(container_algorithm_internal::c_begin(sequence), + container_algorithm_internal::c_end(sequence), + std::forward(value), + std::forward(comp)); +} + +//------------------------------------------------------------------------------ +// Merge functions +//------------------------------------------------------------------------------ + +// c_merge() +// +// Container-based version of the `std::merge()` function +// to merge two sorted containers into a single sorted iterator. +template +OutputIterator c_merge(const C1& c1, const C2& c2, OutputIterator result) { + return std::merge(container_algorithm_internal::c_begin(c1), + container_algorithm_internal::c_end(c1), + container_algorithm_internal::c_begin(c2), + container_algorithm_internal::c_end(c2), result); +} + +// Overload of c_merge() for performing a `comp` comparison other than +// the default `operator<`. +template +OutputIterator c_merge(const C1& c1, const C2& c2, OutputIterator result, + Compare&& comp) { + return std::merge(container_algorithm_internal::c_begin(c1), + container_algorithm_internal::c_end(c1), + container_algorithm_internal::c_begin(c2), + container_algorithm_internal::c_end(c2), result, + std::forward(comp)); +} + +// c_inplace_merge() +// +// Container-based version of the `std::inplace_merge()` function +// to merge a supplied iterator `middle` into a container. +template +void c_inplace_merge(C& c, + container_algorithm_internal::ContainerIter middle) { + std::inplace_merge(container_algorithm_internal::c_begin(c), middle, + container_algorithm_internal::c_end(c)); +} + +// Overload of c_inplace_merge() for performing a merge using a `comp` other +// than `operator<`. +template +void c_inplace_merge(C& c, + container_algorithm_internal::ContainerIter middle, + Compare&& comp) { + std::inplace_merge(container_algorithm_internal::c_begin(c), middle, + container_algorithm_internal::c_end(c), + std::forward(comp)); +} + +// c_includes() +// +// Container-based version of the `std::includes()` function +// to test whether a sorted container `c1` entirely contains another sorted +// container `c2`. +template +bool c_includes(const C1& c1, const C2& c2) { + return std::includes(container_algorithm_internal::c_begin(c1), + container_algorithm_internal::c_end(c1), + container_algorithm_internal::c_begin(c2), + container_algorithm_internal::c_end(c2)); +} + +// Overload of c_includes() for performing a merge using a `comp` other than +// `operator<`. +template +bool c_includes(const C1& c1, const C2& c2, Compare&& comp) { + return std::includes(container_algorithm_internal::c_begin(c1), + container_algorithm_internal::c_end(c1), + container_algorithm_internal::c_begin(c2), + container_algorithm_internal::c_end(c2), + std::forward(comp)); +} + +// c_set_union() +// +// Container-based version of the `std::set_union()` function +// to return an iterator containing the union of two containers; duplicate +// values are not copied into the output. +template +OutputIterator c_set_union(const C1& c1, const C2& c2, OutputIterator output) { + return std::set_union(container_algorithm_internal::c_begin(c1), + container_algorithm_internal::c_end(c1), + container_algorithm_internal::c_begin(c2), + container_algorithm_internal::c_end(c2), output); +} + +// Overload of c_set_union() for performing a merge using a `comp` other than +// `operator<`. +template +OutputIterator c_set_union(const C1& c1, const C2& c2, OutputIterator output, + Compare&& comp) { + return std::set_union(container_algorithm_internal::c_begin(c1), + container_algorithm_internal::c_end(c1), + container_algorithm_internal::c_begin(c2), + container_algorithm_internal::c_end(c2), output, + std::forward(comp)); +} + +// c_set_intersection() +// +// Container-based version of the `std::set_intersection()` function +// to return an iterator containing the intersection of two containers. +template +OutputIterator c_set_intersection(const C1& c1, const C2& c2, + OutputIterator output) { + return std::set_intersection(container_algorithm_internal::c_begin(c1), + container_algorithm_internal::c_end(c1), + container_algorithm_internal::c_begin(c2), + container_algorithm_internal::c_end(c2), output); +} + +// Overload of c_set_intersection() for performing a merge using a `comp` other +// than `operator<`. +template +OutputIterator c_set_intersection(const C1& c1, const C2& c2, + OutputIterator output, Compare&& comp) { + return std::set_intersection(container_algorithm_internal::c_begin(c1), + container_algorithm_internal::c_end(c1), + container_algorithm_internal::c_begin(c2), + container_algorithm_internal::c_end(c2), output, + std::forward(comp)); +} + +// c_set_difference() +// +// Container-based version of the `std::set_difference()` function +// to return an iterator containing elements present in the first container but +// not in the second. +template +OutputIterator c_set_difference(const C1& c1, const C2& c2, + OutputIterator output) { + return std::set_difference(container_algorithm_internal::c_begin(c1), + container_algorithm_internal::c_end(c1), + container_algorithm_internal::c_begin(c2), + container_algorithm_internal::c_end(c2), output); +} + +// Overload of c_set_difference() for performing a merge using a `comp` other +// than `operator<`. +template +OutputIterator c_set_difference(const C1& c1, const C2& c2, + OutputIterator output, Compare&& comp) { + return std::set_difference(container_algorithm_internal::c_begin(c1), + container_algorithm_internal::c_end(c1), + container_algorithm_internal::c_begin(c2), + container_algorithm_internal::c_end(c2), output, + std::forward(comp)); +} + +// c_set_symmetric_difference() +// +// Container-based version of the `std::set_symmetric_difference()` +// function to return an iterator containing elements present in either one +// container or the other, but not both. +template +OutputIterator c_set_symmetric_difference(const C1& c1, const C2& c2, + OutputIterator output) { + return std::set_symmetric_difference( + container_algorithm_internal::c_begin(c1), + container_algorithm_internal::c_end(c1), + container_algorithm_internal::c_begin(c2), + container_algorithm_internal::c_end(c2), output); +} + +// Overload of c_set_symmetric_difference() for performing a merge using a +// `comp` other than `operator<`. +template +OutputIterator c_set_symmetric_difference(const C1& c1, const C2& c2, + OutputIterator output, + Compare&& comp) { + return std::set_symmetric_difference( + container_algorithm_internal::c_begin(c1), + container_algorithm_internal::c_end(c1), + container_algorithm_internal::c_begin(c2), + container_algorithm_internal::c_end(c2), output, + std::forward(comp)); +} + +//------------------------------------------------------------------------------ +// Heap functions +//------------------------------------------------------------------------------ + +// c_push_heap() +// +// Container-based version of the `std::push_heap()` function +// to push a value onto a container heap. +template +void c_push_heap(RandomAccessContainer& sequence) { + std::push_heap(container_algorithm_internal::c_begin(sequence), + container_algorithm_internal::c_end(sequence)); +} + +// Overload of c_push_heap() for performing a push operation on a heap using a +// `comp` other than `operator<`. +template +void c_push_heap(RandomAccessContainer& sequence, Compare&& comp) { + std::push_heap(container_algorithm_internal::c_begin(sequence), + container_algorithm_internal::c_end(sequence), + std::forward(comp)); +} + +// c_pop_heap() +// +// Container-based version of the `std::pop_heap()` function +// to pop a value from a heap container. +template +void c_pop_heap(RandomAccessContainer& sequence) { + std::pop_heap(container_algorithm_internal::c_begin(sequence), + container_algorithm_internal::c_end(sequence)); +} + +// Overload of c_pop_heap() for performing a pop operation on a heap using a +// `comp` other than `operator<`. +template +void c_pop_heap(RandomAccessContainer& sequence, Compare&& comp) { + std::pop_heap(container_algorithm_internal::c_begin(sequence), + container_algorithm_internal::c_end(sequence), + std::forward(comp)); +} + +// c_make_heap() +// +// Container-based version of the `std::make_heap()` function +// to make a container a heap. +template +void c_make_heap(RandomAccessContainer& sequence) { + std::make_heap(container_algorithm_internal::c_begin(sequence), + container_algorithm_internal::c_end(sequence)); +} + +// Overload of c_make_heap() for performing heap comparisons using a +// `comp` other than `operator<` +template +void c_make_heap(RandomAccessContainer& sequence, Compare&& comp) { + std::make_heap(container_algorithm_internal::c_begin(sequence), + container_algorithm_internal::c_end(sequence), + std::forward(comp)); +} + +// c_sort_heap() +// +// Container-based version of the `std::sort_heap()` function +// to sort a heap into ascending order (after which it is no longer a heap). +template +void c_sort_heap(RandomAccessContainer& sequence) { + std::sort_heap(container_algorithm_internal::c_begin(sequence), + container_algorithm_internal::c_end(sequence)); +} + +// Overload of c_sort_heap() for performing heap comparisons using a +// `comp` other than `operator<` +template +void c_sort_heap(RandomAccessContainer& sequence, Compare&& comp) { + std::sort_heap(container_algorithm_internal::c_begin(sequence), + container_algorithm_internal::c_end(sequence), + std::forward(comp)); +} + +// c_is_heap() +// +// Container-based version of the `std::is_heap()` function +// to check whether the given container is a heap. +template +bool c_is_heap(const RandomAccessContainer& sequence) { + return std::is_heap(container_algorithm_internal::c_begin(sequence), + container_algorithm_internal::c_end(sequence)); +} + +// Overload of c_is_heap() for performing heap comparisons using a +// `comp` other than `operator<` +template +bool c_is_heap(const RandomAccessContainer& sequence, Compare&& comp) { + return std::is_heap(container_algorithm_internal::c_begin(sequence), + container_algorithm_internal::c_end(sequence), + std::forward(comp)); +} + +// c_is_heap_until() +// +// Container-based version of the `std::is_heap_until()` function +// to find the first element in a given container which is not in heap order. +template +container_algorithm_internal::ContainerIter +c_is_heap_until(RandomAccessContainer& sequence) { + return std::is_heap_until(container_algorithm_internal::c_begin(sequence), + container_algorithm_internal::c_end(sequence)); +} + +// Overload of c_is_heap_until() for performing heap comparisons using a +// `comp` other than `operator<` +template +container_algorithm_internal::ContainerIter +c_is_heap_until(RandomAccessContainer& sequence, Compare&& comp) { + return std::is_heap_until(container_algorithm_internal::c_begin(sequence), + container_algorithm_internal::c_end(sequence), + std::forward(comp)); +} + +//------------------------------------------------------------------------------ +// Min/max +//------------------------------------------------------------------------------ + +// c_min_element() +// +// Container-based version of the `std::min_element()` function +// to return an iterator pointing to the element with the smallest value, using +// `operator<` to make the comparisons. +template +container_algorithm_internal::ContainerIter c_min_element( + Sequence& sequence) { + return std::min_element(container_algorithm_internal::c_begin(sequence), + container_algorithm_internal::c_end(sequence)); +} + +// Overload of c_min_element() for performing a `comp` comparison other than +// `operator<`. +template +container_algorithm_internal::ContainerIter c_min_element( + Sequence& sequence, Compare&& comp) { + return std::min_element(container_algorithm_internal::c_begin(sequence), + container_algorithm_internal::c_end(sequence), + std::forward(comp)); +} + +// c_max_element() +// +// Container-based version of the `std::max_element()` function +// to return an iterator pointing to the element with the largest value, using +// `operator<` to make the comparisons. +template +container_algorithm_internal::ContainerIter c_max_element( + Sequence& sequence) { + return std::max_element(container_algorithm_internal::c_begin(sequence), + container_algorithm_internal::c_end(sequence)); +} + +// Overload of c_max_element() for performing a `comp` comparison other than +// `operator<`. +template +container_algorithm_internal::ContainerIter c_max_element( + Sequence& sequence, Compare&& comp) { + return std::max_element(container_algorithm_internal::c_begin(sequence), + container_algorithm_internal::c_end(sequence), + std::forward(comp)); +} + +// c_minmax_element() +// +// Container-based version of the `std::minmax_element()` function +// to return a pair of iterators pointing to the elements containing the +// smallest and largest values, respectively, using `operator<` to make the +// comparisons. +template +container_algorithm_internal::ContainerIterPairType +c_minmax_element(C& c) { + return std::minmax_element(container_algorithm_internal::c_begin(c), + container_algorithm_internal::c_end(c)); +} + +// Overload of c_minmax_element() for performing `comp` comparisons other than +// `operator<`. +template +container_algorithm_internal::ContainerIterPairType +c_minmax_element(C& c, Compare&& comp) { + return std::minmax_element(container_algorithm_internal::c_begin(c), + container_algorithm_internal::c_end(c), + std::forward(comp)); +} + +//------------------------------------------------------------------------------ +// Lexicographical Comparisons +//------------------------------------------------------------------------------ + +// c_lexicographical_compare() +// +// Container-based version of the `std::lexicographical_compare()` +// function to lexicographically compare (e.g. sort words alphabetically) two +// container sequences. The comparison is performed using `operator<`. Note +// that capital letters ("A-Z") have ASCII values less than lowercase letters +// ("a-z"). +template +bool c_lexicographical_compare(Sequence1&& sequence1, Sequence2&& sequence2) { + return std::lexicographical_compare( + container_algorithm_internal::c_begin(sequence1), + container_algorithm_internal::c_end(sequence1), + container_algorithm_internal::c_begin(sequence2), + container_algorithm_internal::c_end(sequence2)); +} + +// Overload of c_lexicographical_compare() for performing a lexicographical +// comparison using a `comp` operator instead of `operator<`. +template +bool c_lexicographical_compare(Sequence1&& sequence1, Sequence2&& sequence2, + Compare&& comp) { + return std::lexicographical_compare( + container_algorithm_internal::c_begin(sequence1), + container_algorithm_internal::c_end(sequence1), + container_algorithm_internal::c_begin(sequence2), + container_algorithm_internal::c_end(sequence2), + std::forward(comp)); +} + +// c_next_permutation() +// +// Container-based version of the `std::next_permutation()` function +// to rearrange a container's elements into the next lexicographically greater +// permutation. +template +bool c_next_permutation(C& c) { + return std::next_permutation(container_algorithm_internal::c_begin(c), + container_algorithm_internal::c_end(c)); +} + +// Overload of c_next_permutation() for performing a lexicographical +// comparison using a `comp` operator instead of `operator<`. +template +bool c_next_permutation(C& c, Compare&& comp) { + return std::next_permutation(container_algorithm_internal::c_begin(c), + container_algorithm_internal::c_end(c), + std::forward(comp)); +} + +// c_prev_permutation() +// +// Container-based version of the `std::prev_permutation()` function +// to rearrange a container's elements into the next lexicographically lesser +// permutation. +template +bool c_prev_permutation(C& c) { + return std::prev_permutation(container_algorithm_internal::c_begin(c), + container_algorithm_internal::c_end(c)); +} + +// Overload of c_prev_permutation() for performing a lexicographical +// comparison using a `comp` operator instead of `operator<`. +template +bool c_prev_permutation(C& c, Compare&& comp) { + return std::prev_permutation(container_algorithm_internal::c_begin(c), + container_algorithm_internal::c_end(c), + std::forward(comp)); +} + +//------------------------------------------------------------------------------ +// algorithms +//------------------------------------------------------------------------------ + +// c_iota() +// +// Container-based version of the `std::iota()` function +// to compute successive values of `value`, as if incremented with `++value` +// after each element is written. and write them to the container. +template +void c_iota(Sequence& sequence, T&& value) { + std::iota(container_algorithm_internal::c_begin(sequence), + container_algorithm_internal::c_end(sequence), + std::forward(value)); +} +// c_accumulate() +// +// Container-based version of the `std::accumulate()` function +// to accumulate the element values of a container to `init` and return that +// accumulation by value. +// +// Note: Due to a language technicality this function has return type +// absl::decay_t. As a user of this function you can casually read +// this as "returns T by value" and assume it does the right thing. +template +decay_t c_accumulate(const Sequence& sequence, T&& init) { + return std::accumulate(container_algorithm_internal::c_begin(sequence), + container_algorithm_internal::c_end(sequence), + std::forward(init)); +} + +// Overload of c_accumulate() for using a binary operations other than +// addition for computing the accumulation. +template +decay_t c_accumulate(const Sequence& sequence, T&& init, + BinaryOp&& binary_op) { + return std::accumulate(container_algorithm_internal::c_begin(sequence), + container_algorithm_internal::c_end(sequence), + std::forward(init), + std::forward(binary_op)); +} + +// c_inner_product() +// +// Container-based version of the `std::inner_product()` function +// to compute the cumulative inner product of container element pairs. +// +// Note: Due to a language technicality this function has return type +// absl::decay_t. As a user of this function you can casually read +// this as "returns T by value" and assume it does the right thing. +template +decay_t c_inner_product(const Sequence1& factors1, const Sequence2& factors2, + T&& sum) { + return std::inner_product(container_algorithm_internal::c_begin(factors1), + container_algorithm_internal::c_end(factors1), + container_algorithm_internal::c_begin(factors2), + std::forward(sum)); +} + +// Overload of c_inner_product() for using binary operations other than +// `operator+` (for computing the accumulation) and `operator*` (for computing +// the product between the two container's element pair). +template +decay_t c_inner_product(const Sequence1& factors1, const Sequence2& factors2, + T&& sum, BinaryOp1&& op1, BinaryOp2&& op2) { + return std::inner_product(container_algorithm_internal::c_begin(factors1), + container_algorithm_internal::c_end(factors1), + container_algorithm_internal::c_begin(factors2), + std::forward(sum), std::forward(op1), + std::forward(op2)); +} + +// c_adjacent_difference() +// +// Container-based version of the `std::adjacent_difference()` +// function to compute the difference between each element and the one preceding +// it and write it to an iterator. +template +OutputIt c_adjacent_difference(const InputSequence& input, + OutputIt output_first) { + return std::adjacent_difference(container_algorithm_internal::c_begin(input), + container_algorithm_internal::c_end(input), + output_first); +} + +// Overload of c_adjacent_difference() for using a binary operation other than +// subtraction to compute the adjacent difference. +template +OutputIt c_adjacent_difference(const InputSequence& input, + OutputIt output_first, BinaryOp&& op) { + return std::adjacent_difference(container_algorithm_internal::c_begin(input), + container_algorithm_internal::c_end(input), + output_first, std::forward(op)); +} + +// c_partial_sum() +// +// Container-based version of the `std::partial_sum()` function +// to compute the partial sum of the elements in a sequence and write them +// to an iterator. The partial sum is the sum of all element values so far in +// the sequence. +template +OutputIt c_partial_sum(const InputSequence& input, OutputIt output_first) { + return std::partial_sum(container_algorithm_internal::c_begin(input), + container_algorithm_internal::c_end(input), + output_first); +} + +// Overload of c_partial_sum() for using a binary operation other than addition +// to compute the "partial sum". +template +OutputIt c_partial_sum(const InputSequence& input, OutputIt output_first, + BinaryOp&& op) { + return std::partial_sum(container_algorithm_internal::c_begin(input), + container_algorithm_internal::c_end(input), + output_first, std::forward(op)); +} + +} // namespace absl + +#endif // ABSL_ALGORITHM_CONTAINER_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/algorithm/container_test.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/algorithm/container_test.cc new file mode 100644 index 0000000..1502b17 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/algorithm/container_test.cc @@ -0,0 +1,1012 @@ +// Copyright 2017 The Abseil Authors. +// +// 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 "absl/algorithm/container.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gmock/gmock.h" +#include "gtest/gtest.h" +#include "absl/base/casts.h" +#include "absl/base/macros.h" +#include "absl/memory/memory.h" +#include "absl/types/span.h" + +namespace { + +using ::testing::Each; +using ::testing::ElementsAre; +using ::testing::Gt; +using ::testing::IsNull; +using ::testing::Lt; +using ::testing::Pointee; +using ::testing::Truly; +using ::testing::UnorderedElementsAre; + +// Most of these tests just check that the code compiles, not that it +// does the right thing. That's fine since the functions just forward +// to the STL implementation. +class NonMutatingTest : public testing::Test { + protected: + std::unordered_set container_ = {1, 2, 3}; + std::list sequence_ = {1, 2, 3}; + std::vector vector_ = {1, 2, 3}; + int array_[3] = {1, 2, 3}; +}; + +struct AccumulateCalls { + void operator()(int value) { + calls.push_back(value); + } + std::vector calls; +}; + +bool Predicate(int value) { return value < 3; } +bool BinPredicate(int v1, int v2) { return v1 < v2; } +bool Equals(int v1, int v2) { return v1 == v2; } +bool IsOdd(int x) { return x % 2 != 0; } + + +TEST_F(NonMutatingTest, Distance) { + EXPECT_EQ(container_.size(), absl::c_distance(container_)); + EXPECT_EQ(sequence_.size(), absl::c_distance(sequence_)); + EXPECT_EQ(vector_.size(), absl::c_distance(vector_)); + EXPECT_EQ(ABSL_ARRAYSIZE(array_), absl::c_distance(array_)); + + // Works with a temporary argument. + EXPECT_EQ(vector_.size(), absl::c_distance(std::vector(vector_))); +} + +TEST_F(NonMutatingTest, Distance_OverloadedBeginEnd) { + // Works with classes which have custom ADL-selected overloads of std::begin + // and std::end. + std::initializer_list a = {1, 2, 3}; + std::valarray b = {1, 2, 3}; + EXPECT_EQ(3, absl::c_distance(a)); + EXPECT_EQ(3, absl::c_distance(b)); + + // It is assumed that other c_* functions use the same mechanism for + // ADL-selecting begin/end overloads. +} + +TEST_F(NonMutatingTest, ForEach) { + AccumulateCalls c = absl::c_for_each(container_, AccumulateCalls()); + // Don't rely on the unordered_set's order. + std::sort(c.calls.begin(), c.calls.end()); + EXPECT_EQ(vector_, c.calls); + + // Works with temporary container, too. + AccumulateCalls c2 = + absl::c_for_each(std::unordered_set(container_), AccumulateCalls()); + std::sort(c2.calls.begin(), c2.calls.end()); + EXPECT_EQ(vector_, c2.calls); +} + +TEST_F(NonMutatingTest, FindReturnsCorrectType) { + auto it = absl::c_find(container_, 3); + EXPECT_EQ(3, *it); + absl::c_find(absl::implicit_cast&>(sequence_), 3); +} + +TEST_F(NonMutatingTest, FindIf) { absl::c_find_if(container_, Predicate); } + +TEST_F(NonMutatingTest, FindIfNot) { + absl::c_find_if_not(container_, Predicate); +} + +TEST_F(NonMutatingTest, FindEnd) { + absl::c_find_end(sequence_, vector_); + absl::c_find_end(vector_, sequence_); +} + +TEST_F(NonMutatingTest, FindEndWithPredicate) { + absl::c_find_end(sequence_, vector_, BinPredicate); + absl::c_find_end(vector_, sequence_, BinPredicate); +} + +TEST_F(NonMutatingTest, FindFirstOf) { + absl::c_find_first_of(container_, sequence_); + absl::c_find_first_of(sequence_, container_); +} + +TEST_F(NonMutatingTest, FindFirstOfWithPredicate) { + absl::c_find_first_of(container_, sequence_, BinPredicate); + absl::c_find_first_of(sequence_, container_, BinPredicate); +} + +TEST_F(NonMutatingTest, AdjacentFind) { absl::c_adjacent_find(sequence_); } + +TEST_F(NonMutatingTest, AdjacentFindWithPredicate) { + absl::c_adjacent_find(sequence_, BinPredicate); +} + +TEST_F(NonMutatingTest, Count) { EXPECT_EQ(1, absl::c_count(container_, 3)); } + +TEST_F(NonMutatingTest, CountIf) { + EXPECT_EQ(2, absl::c_count_if(container_, Predicate)); + const std::unordered_set& const_container = container_; + EXPECT_EQ(2, absl::c_count_if(const_container, Predicate)); +} + +TEST_F(NonMutatingTest, Mismatch) { + absl::c_mismatch(container_, sequence_); + absl::c_mismatch(sequence_, container_); +} + +TEST_F(NonMutatingTest, MismatchWithPredicate) { + absl::c_mismatch(container_, sequence_, BinPredicate); + absl::c_mismatch(sequence_, container_, BinPredicate); +} + +TEST_F(NonMutatingTest, Equal) { + EXPECT_TRUE(absl::c_equal(vector_, sequence_)); + EXPECT_TRUE(absl::c_equal(sequence_, vector_)); + + // Test that behavior appropriately differs from that of equal(). + std::vector vector_plus = {1, 2, 3}; + vector_plus.push_back(4); + EXPECT_FALSE(absl::c_equal(vector_plus, sequence_)); + EXPECT_FALSE(absl::c_equal(sequence_, vector_plus)); +} + +TEST_F(NonMutatingTest, EqualWithPredicate) { + EXPECT_TRUE(absl::c_equal(vector_, sequence_, Equals)); + EXPECT_TRUE(absl::c_equal(sequence_, vector_, Equals)); + + // Test that behavior appropriately differs from that of equal(). + std::vector vector_plus = {1, 2, 3}; + vector_plus.push_back(4); + EXPECT_FALSE(absl::c_equal(vector_plus, sequence_, Equals)); + EXPECT_FALSE(absl::c_equal(sequence_, vector_plus, Equals)); +} + +TEST_F(NonMutatingTest, IsPermutation) { + auto vector_permut_ = vector_; + std::next_permutation(vector_permut_.begin(), vector_permut_.end()); + EXPECT_TRUE(absl::c_is_permutation(vector_permut_, sequence_)); + EXPECT_TRUE(absl::c_is_permutation(sequence_, vector_permut_)); + + // Test that behavior appropriately differs from that of is_permutation(). + std::vector vector_plus = {1, 2, 3}; + vector_plus.push_back(4); + EXPECT_FALSE(absl::c_is_permutation(vector_plus, sequence_)); + EXPECT_FALSE(absl::c_is_permutation(sequence_, vector_plus)); +} + +TEST_F(NonMutatingTest, IsPermutationWithPredicate) { + auto vector_permut_ = vector_; + std::next_permutation(vector_permut_.begin(), vector_permut_.end()); + EXPECT_TRUE(absl::c_is_permutation(vector_permut_, sequence_, Equals)); + EXPECT_TRUE(absl::c_is_permutation(sequence_, vector_permut_, Equals)); + + // Test that behavior appropriately differs from that of is_permutation(). + std::vector vector_plus = {1, 2, 3}; + vector_plus.push_back(4); + EXPECT_FALSE(absl::c_is_permutation(vector_plus, sequence_, Equals)); + EXPECT_FALSE(absl::c_is_permutation(sequence_, vector_plus, Equals)); +} + +TEST_F(NonMutatingTest, Search) { + absl::c_search(sequence_, vector_); + absl::c_search(vector_, sequence_); + absl::c_search(array_, sequence_); +} + +TEST_F(NonMutatingTest, SearchWithPredicate) { + absl::c_search(sequence_, vector_, BinPredicate); + absl::c_search(vector_, sequence_, BinPredicate); +} + +TEST_F(NonMutatingTest, SearchN) { absl::c_search_n(sequence_, 3, 1); } + +TEST_F(NonMutatingTest, SearchNWithPredicate) { + absl::c_search_n(sequence_, 3, 1, BinPredicate); +} + +TEST_F(NonMutatingTest, LowerBound) { + std::list::iterator i = absl::c_lower_bound(sequence_, 3); + ASSERT_TRUE(i != sequence_.end()); + EXPECT_EQ(2, std::distance(sequence_.begin(), i)); + EXPECT_EQ(3, *i); +} + +TEST_F(NonMutatingTest, LowerBoundWithPredicate) { + std::vector v(vector_); + std::sort(v.begin(), v.end(), std::greater()); + std::vector::iterator i = absl::c_lower_bound(v, 3, std::greater()); + EXPECT_TRUE(i == v.begin()); + EXPECT_EQ(3, *i); +} + +TEST_F(NonMutatingTest, UpperBound) { + std::list::iterator i = absl::c_upper_bound(sequence_, 1); + ASSERT_TRUE(i != sequence_.end()); + EXPECT_EQ(1, std::distance(sequence_.begin(), i)); + EXPECT_EQ(2, *i); +} + +TEST_F(NonMutatingTest, UpperBoundWithPredicate) { + std::vector v(vector_); + std::sort(v.begin(), v.end(), std::greater()); + std::vector::iterator i = absl::c_upper_bound(v, 1, std::greater()); + EXPECT_EQ(3, i - v.begin()); + EXPECT_TRUE(i == v.end()); +} + +TEST_F(NonMutatingTest, EqualRange) { + std::pair::iterator, std::list::iterator> p = + absl::c_equal_range(sequence_, 2); + EXPECT_EQ(1, std::distance(sequence_.begin(), p.first)); + EXPECT_EQ(2, std::distance(sequence_.begin(), p.second)); +} + +TEST_F(NonMutatingTest, EqualRangeArray) { + auto p = absl::c_equal_range(array_, 2); + EXPECT_EQ(1, std::distance(std::begin(array_), p.first)); + EXPECT_EQ(2, std::distance(std::begin(array_), p.second)); +} + +TEST_F(NonMutatingTest, EqualRangeWithPredicate) { + std::vector v(vector_); + std::sort(v.begin(), v.end(), std::greater()); + std::pair::iterator, std::vector::iterator> p = + absl::c_equal_range(v, 2, std::greater()); + EXPECT_EQ(1, std::distance(v.begin(), p.first)); + EXPECT_EQ(2, std::distance(v.begin(), p.second)); +} + +TEST_F(NonMutatingTest, BinarySearch) { + EXPECT_TRUE(absl::c_binary_search(vector_, 2)); + EXPECT_TRUE(absl::c_binary_search(std::vector(vector_), 2)); +} + +TEST_F(NonMutatingTest, BinarySearchWithPredicate) { + std::vector v(vector_); + std::sort(v.begin(), v.end(), std::greater()); + EXPECT_TRUE(absl::c_binary_search(v, 2, std::greater())); + EXPECT_TRUE( + absl::c_binary_search(std::vector(v), 2, std::greater())); +} + +TEST_F(NonMutatingTest, MinElement) { + std::list::iterator i = absl::c_min_element(sequence_); + ASSERT_TRUE(i != sequence_.end()); + EXPECT_EQ(*i, 1); +} + +TEST_F(NonMutatingTest, MinElementWithPredicate) { + std::list::iterator i = + absl::c_min_element(sequence_, std::greater()); + ASSERT_TRUE(i != sequence_.end()); + EXPECT_EQ(*i, 3); +} + +TEST_F(NonMutatingTest, MaxElement) { + std::list::iterator i = absl::c_max_element(sequence_); + ASSERT_TRUE(i != sequence_.end()); + EXPECT_EQ(*i, 3); +} + +TEST_F(NonMutatingTest, MaxElementWithPredicate) { + std::list::iterator i = + absl::c_max_element(sequence_, std::greater()); + ASSERT_TRUE(i != sequence_.end()); + EXPECT_EQ(*i, 1); +} + +TEST_F(NonMutatingTest, LexicographicalCompare) { + EXPECT_FALSE(absl::c_lexicographical_compare(sequence_, sequence_)); + + std::vector v; + v.push_back(1); + v.push_back(2); + v.push_back(4); + + EXPECT_TRUE(absl::c_lexicographical_compare(sequence_, v)); + EXPECT_TRUE(absl::c_lexicographical_compare(std::list(sequence_), v)); +} + +TEST_F(NonMutatingTest, LexicographicalCopmareWithPredicate) { + EXPECT_FALSE(absl::c_lexicographical_compare(sequence_, sequence_, + std::greater())); + + std::vector v; + v.push_back(1); + v.push_back(2); + v.push_back(4); + + EXPECT_TRUE( + absl::c_lexicographical_compare(v, sequence_, std::greater())); + EXPECT_TRUE(absl::c_lexicographical_compare( + std::vector(v), std::list(sequence_), std::greater())); +} + +TEST_F(NonMutatingTest, Includes) { + std::set s(vector_.begin(), vector_.end()); + s.insert(4); + EXPECT_TRUE(absl::c_includes(s, vector_)); +} + +TEST_F(NonMutatingTest, IncludesWithPredicate) { + std::vector v = {3, 2, 1}; + std::set> s(v.begin(), v.end()); + s.insert(4); + EXPECT_TRUE(absl::c_includes(s, v, std::greater())); +} + +class NumericMutatingTest : public testing::Test { + protected: + std::list list_ = {1, 2, 3}; + std::vector output_; +}; + +TEST_F(NumericMutatingTest, Iota) { + absl::c_iota(list_, 5); + std::list expected{5, 6, 7}; + EXPECT_EQ(list_, expected); +} + +TEST_F(NonMutatingTest, Accumulate) { + EXPECT_EQ(absl::c_accumulate(sequence_, 4), 1 + 2 + 3 + 4); +} + +TEST_F(NonMutatingTest, AccumulateWithBinaryOp) { + EXPECT_EQ(absl::c_accumulate(sequence_, 4, std::multiplies()), + 1 * 2 * 3 * 4); +} + +TEST_F(NonMutatingTest, AccumulateLvalueInit) { + int lvalue = 4; + EXPECT_EQ(absl::c_accumulate(sequence_, lvalue), 1 + 2 + 3 + 4); +} + +TEST_F(NonMutatingTest, AccumulateWithBinaryOpLvalueInit) { + int lvalue = 4; + EXPECT_EQ(absl::c_accumulate(sequence_, lvalue, std::multiplies()), + 1 * 2 * 3 * 4); +} + +TEST_F(NonMutatingTest, InnerProduct) { + EXPECT_EQ(absl::c_inner_product(sequence_, vector_, 1000), + 1000 + 1 * 1 + 2 * 2 + 3 * 3); +} + +TEST_F(NonMutatingTest, InnerProductWithBinaryOps) { + EXPECT_EQ(absl::c_inner_product(sequence_, vector_, 10, + std::multiplies(), std::plus()), + 10 * (1 + 1) * (2 + 2) * (3 + 3)); +} + +TEST_F(NonMutatingTest, InnerProductLvalueInit) { + int lvalue = 1000; + EXPECT_EQ(absl::c_inner_product(sequence_, vector_, lvalue), + 1000 + 1 * 1 + 2 * 2 + 3 * 3); +} + +TEST_F(NonMutatingTest, InnerProductWithBinaryOpsLvalueInit) { + int lvalue = 10; + EXPECT_EQ(absl::c_inner_product(sequence_, vector_, lvalue, + std::multiplies(), std::plus()), + 10 * (1 + 1) * (2 + 2) * (3 + 3)); +} + +TEST_F(NumericMutatingTest, AdjacentDifference) { + auto last = absl::c_adjacent_difference(list_, std::back_inserter(output_)); + *last = 1000; + std::vector expected{1, 2 - 1, 3 - 2, 1000}; + EXPECT_EQ(output_, expected); +} + +TEST_F(NumericMutatingTest, AdjacentDifferenceWithBinaryOp) { + auto last = absl::c_adjacent_difference(list_, std::back_inserter(output_), + std::multiplies()); + *last = 1000; + std::vector expected{1, 2 * 1, 3 * 2, 1000}; + EXPECT_EQ(output_, expected); +} + +TEST_F(NumericMutatingTest, PartialSum) { + auto last = absl::c_partial_sum(list_, std::back_inserter(output_)); + *last = 1000; + std::vector expected{1, 1 + 2, 1 + 2 + 3, 1000}; + EXPECT_EQ(output_, expected); +} + +TEST_F(NumericMutatingTest, PartialSumWithBinaryOp) { + auto last = absl::c_partial_sum(list_, std::back_inserter(output_), + std::multiplies()); + *last = 1000; + std::vector expected{1, 1 * 2, 1 * 2 * 3, 1000}; + EXPECT_EQ(output_, expected); +} + +TEST_F(NonMutatingTest, LinearSearch) { + EXPECT_TRUE(absl::c_linear_search(container_, 3)); + EXPECT_FALSE(absl::c_linear_search(container_, 4)); +} + +TEST_F(NonMutatingTest, AllOf) { + const std::vector& v = vector_; + EXPECT_FALSE(absl::c_all_of(v, [](int x) { return x > 1; })); + EXPECT_TRUE(absl::c_all_of(v, [](int x) { return x > 0; })); +} + +TEST_F(NonMutatingTest, AnyOf) { + const std::vector& v = vector_; + EXPECT_TRUE(absl::c_any_of(v, [](int x) { return x > 2; })); + EXPECT_FALSE(absl::c_any_of(v, [](int x) { return x > 5; })); +} + +TEST_F(NonMutatingTest, NoneOf) { + const std::vector& v = vector_; + EXPECT_FALSE(absl::c_none_of(v, [](int x) { return x > 2; })); + EXPECT_TRUE(absl::c_none_of(v, [](int x) { return x > 5; })); +} + +TEST_F(NonMutatingTest, MinMaxElementLess) { + std::pair::const_iterator, std::vector::const_iterator> + p = absl::c_minmax_element(vector_, std::less()); + EXPECT_TRUE(p.first == vector_.begin()); + EXPECT_TRUE(p.second == vector_.begin() + 2); +} + +TEST_F(NonMutatingTest, MinMaxElementGreater) { + std::pair::const_iterator, std::vector::const_iterator> + p = absl::c_minmax_element(vector_, std::greater()); + EXPECT_TRUE(p.first == vector_.begin() + 2); + EXPECT_TRUE(p.second == vector_.begin()); +} + +TEST_F(NonMutatingTest, MinMaxElementNoPredicate) { + std::pair::const_iterator, std::vector::const_iterator> + p = absl::c_minmax_element(vector_); + EXPECT_TRUE(p.first == vector_.begin()); + EXPECT_TRUE(p.second == vector_.begin() + 2); +} + +class SortingTest : public testing::Test { + protected: + std::list sorted_ = {1, 2, 3, 4}; + std::list unsorted_ = {2, 4, 1, 3}; + std::list reversed_ = {4, 3, 2, 1}; +}; + +TEST_F(SortingTest, IsSorted) { + EXPECT_TRUE(absl::c_is_sorted(sorted_)); + EXPECT_FALSE(absl::c_is_sorted(unsorted_)); + EXPECT_FALSE(absl::c_is_sorted(reversed_)); +} + +TEST_F(SortingTest, IsSortedWithPredicate) { + EXPECT_FALSE(absl::c_is_sorted(sorted_, std::greater())); + EXPECT_FALSE(absl::c_is_sorted(unsorted_, std::greater())); + EXPECT_TRUE(absl::c_is_sorted(reversed_, std::greater())); +} + +TEST_F(SortingTest, IsSortedUntil) { + EXPECT_EQ(1, *absl::c_is_sorted_until(unsorted_)); + EXPECT_EQ(4, *absl::c_is_sorted_until(unsorted_, std::greater())); +} + +TEST_F(SortingTest, NthElement) { + std::vector unsorted = {2, 4, 1, 3}; + absl::c_nth_element(unsorted, unsorted.begin() + 2); + EXPECT_THAT(unsorted, + ElementsAre(Lt(3), Lt(3), 3, Gt(3))); + absl::c_nth_element(unsorted, unsorted.begin() + 2, std::greater()); + EXPECT_THAT(unsorted, + ElementsAre(Gt(2), Gt(2), 2, Lt(2))); +} + +TEST(MutatingTest, IsPartitioned) { + EXPECT_TRUE( + absl::c_is_partitioned(std::vector{1, 3, 5, 2, 4, 6}, IsOdd)); + EXPECT_FALSE( + absl::c_is_partitioned(std::vector{1, 2, 3, 4, 5, 6}, IsOdd)); + EXPECT_FALSE( + absl::c_is_partitioned(std::vector{2, 4, 6, 1, 3, 5}, IsOdd)); +} + +TEST(MutatingTest, Partition) { + std::vector actual = {1, 2, 3, 4, 5}; + absl::c_partition(actual, IsOdd); + EXPECT_THAT(actual, Truly([](const std::vector& c) { + return absl::c_is_partitioned(c, IsOdd); + })); +} + +TEST(MutatingTest, StablePartition) { + std::vector actual = {1, 2, 3, 4, 5}; + absl::c_stable_partition(actual, IsOdd); + EXPECT_THAT(actual, ElementsAre(1, 3, 5, 2, 4)); +} + +TEST(MutatingTest, PartitionCopy) { + const std::vector initial = {1, 2, 3, 4, 5}; + std::vector odds, evens; + auto ends = absl::c_partition_copy(initial, back_inserter(odds), + back_inserter(evens), IsOdd); + *ends.first = 7; + *ends.second = 6; + EXPECT_THAT(odds, ElementsAre(1, 3, 5, 7)); + EXPECT_THAT(evens, ElementsAre(2, 4, 6)); +} + +TEST(MutatingTest, PartitionPoint) { + const std::vector initial = {1, 3, 5, 2, 4}; + auto middle = absl::c_partition_point(initial, IsOdd); + EXPECT_EQ(2, *middle); +} + +TEST(MutatingTest, CopyMiddle) { + const std::vector initial = {4, -1, -2, -3, 5}; + const std::list input = {1, 2, 3}; + const std::vector expected = {4, 1, 2, 3, 5}; + + std::list test_list(initial.begin(), initial.end()); + absl::c_copy(input, ++test_list.begin()); + EXPECT_EQ(std::list(expected.begin(), expected.end()), test_list); + + std::vector test_vector = initial; + absl::c_copy(input, test_vector.begin() + 1); + EXPECT_EQ(expected, test_vector); +} + +TEST(MutatingTest, CopyFrontInserter) { + const std::list initial = {4, 5}; + const std::list input = {1, 2, 3}; + const std::list expected = {3, 2, 1, 4, 5}; + + std::list test_list = initial; + absl::c_copy(input, std::front_inserter(test_list)); + EXPECT_EQ(expected, test_list); +} + +TEST(MutatingTest, CopyBackInserter) { + const std::vector initial = {4, 5}; + const std::list input = {1, 2, 3}; + const std::vector expected = {4, 5, 1, 2, 3}; + + std::list test_list(initial.begin(), initial.end()); + absl::c_copy(input, std::back_inserter(test_list)); + EXPECT_EQ(std::list(expected.begin(), expected.end()), test_list); + + std::vector test_vector = initial; + absl::c_copy(input, std::back_inserter(test_vector)); + EXPECT_EQ(expected, test_vector); +} + +TEST(MutatingTest, CopyN) { + const std::vector initial = {1, 2, 3, 4, 5}; + const std::vector expected = {1, 2}; + std::vector actual; + absl::c_copy_n(initial, 2, back_inserter(actual)); + EXPECT_EQ(expected, actual); +} + +TEST(MutatingTest, CopyIf) { + const std::list input = {1, 2, 3}; + std::vector output; + absl::c_copy_if(input, std::back_inserter(output), + [](int i) { return i != 2; }); + EXPECT_THAT(output, ElementsAre(1, 3)); +} + +TEST(MutatingTest, CopyBackward) { + std::vector actual = {1, 2, 3, 4, 5}; + std::vector expected = {1, 2, 1, 2, 3}; + absl::c_copy_backward(absl::MakeSpan(actual.data(), 3), actual.end()); + EXPECT_EQ(expected, actual); +} + +TEST(MutatingTest, Move) { + std::vector> src; + src.emplace_back(absl::make_unique(1)); + src.emplace_back(absl::make_unique(2)); + src.emplace_back(absl::make_unique(3)); + src.emplace_back(absl::make_unique(4)); + src.emplace_back(absl::make_unique(5)); + + std::vector> dest = {}; + absl::c_move(src, std::back_inserter(dest)); + EXPECT_THAT(src, Each(IsNull())); + EXPECT_THAT(dest, ElementsAre(Pointee(1), Pointee(2), Pointee(3), Pointee(4), + Pointee(5))); +} + +TEST(MutatingTest, MoveWithRvalue) { + auto MakeRValueSrc = [] { + std::vector> src; + src.emplace_back(absl::make_unique(1)); + src.emplace_back(absl::make_unique(2)); + src.emplace_back(absl::make_unique(3)); + return src; + }; + + std::vector> dest = MakeRValueSrc(); + absl::c_move(MakeRValueSrc(), std::back_inserter(dest)); + EXPECT_THAT(dest, ElementsAre(Pointee(1), Pointee(2), Pointee(3), Pointee(1), + Pointee(2), Pointee(3))); +} + +TEST(MutatingTest, SwapRanges) { + std::vector odds = {2, 4, 6}; + std::vector evens = {1, 3, 5}; + absl::c_swap_ranges(odds, evens); + EXPECT_THAT(odds, ElementsAre(1, 3, 5)); + EXPECT_THAT(evens, ElementsAre(2, 4, 6)); +} + +TEST_F(NonMutatingTest, Transform) { + std::vector x{0, 2, 4}, y, z; + auto end = absl::c_transform(x, back_inserter(y), std::negate()); + EXPECT_EQ(std::vector({0, -2, -4}), y); + *end = 7; + EXPECT_EQ(std::vector({0, -2, -4, 7}), y); + + y = {1, 3, 0}; + end = absl::c_transform(x, y, back_inserter(z), std::plus()); + EXPECT_EQ(std::vector({1, 5, 4}), z); + *end = 7; + EXPECT_EQ(std::vector({1, 5, 4, 7}), z); +} + +TEST(MutatingTest, Replace) { + const std::vector initial = {1, 2, 3, 1, 4, 5}; + const std::vector expected = {4, 2, 3, 4, 4, 5}; + + std::vector test_vector = initial; + absl::c_replace(test_vector, 1, 4); + EXPECT_EQ(expected, test_vector); + + std::list test_list(initial.begin(), initial.end()); + absl::c_replace(test_list, 1, 4); + EXPECT_EQ(std::list(expected.begin(), expected.end()), test_list); +} + +TEST(MutatingTest, ReplaceIf) { + std::vector actual = {1, 2, 3, 4, 5}; + const std::vector expected = {0, 2, 0, 4, 0}; + + absl::c_replace_if(actual, IsOdd, 0); + EXPECT_EQ(expected, actual); +} + +TEST(MutatingTest, ReplaceCopy) { + const std::vector initial = {1, 2, 3, 1, 4, 5}; + const std::vector expected = {4, 2, 3, 4, 4, 5}; + + std::vector actual; + absl::c_replace_copy(initial, back_inserter(actual), 1, 4); + EXPECT_EQ(expected, actual); +} + +TEST(MutatingTest, Sort) { + std::vector test_vector = {2, 3, 1, 4}; + absl::c_sort(test_vector); + EXPECT_THAT(test_vector, ElementsAre(1, 2, 3, 4)); +} + +TEST(MutatingTest, SortWithPredicate) { + std::vector test_vector = {2, 3, 1, 4}; + absl::c_sort(test_vector, std::greater()); + EXPECT_THAT(test_vector, ElementsAre(4, 3, 2, 1)); +} + +// For absl::c_stable_sort tests. Needs an operator< that does not cover all +// fields so that the test can check the sort preserves order of equal elements. +struct Element { + int key; + int value; + friend bool operator<(const Element& e1, const Element& e2) { + return e1.key < e2.key; + } + // Make gmock print useful diagnostics. + friend std::ostream& operator<<(std::ostream& o, const Element& e) { + return o << "{" << e.key << ", " << e.value << "}"; + } +}; + +MATCHER_P2(IsElement, key, value, "") { + return arg.key == key && arg.value == value; +} + +TEST(MutatingTest, StableSort) { + std::vector test_vector = {{1, 1}, {2, 1}, {2, 0}, {1, 0}, {2, 2}}; + absl::c_stable_sort(test_vector); + EXPECT_THAT( + test_vector, + ElementsAre(IsElement(1, 1), IsElement(1, 0), IsElement(2, 1), + IsElement(2, 0), IsElement(2, 2))); +} + +TEST(MutatingTest, StableSortWithPredicate) { + std::vector test_vector = {{1, 1}, {2, 1}, {2, 0}, {1, 0}, {2, 2}}; + absl::c_stable_sort(test_vector, [](const Element& e1, const Element& e2) { + return e2 < e1; + }); + EXPECT_THAT( + test_vector, + ElementsAre(IsElement(2, 1), IsElement(2, 0), IsElement(2, 2), + IsElement(1, 1), IsElement(1, 0))); +} + +TEST(MutatingTest, ReplaceCopyIf) { + const std::vector initial = {1, 2, 3, 4, 5}; + const std::vector expected = {0, 2, 0, 4, 0}; + + std::vector actual; + absl::c_replace_copy_if(initial, back_inserter(actual), IsOdd, 0); + EXPECT_EQ(expected, actual); +} + +TEST(MutatingTest, Fill) { + std::vector actual(5); + absl::c_fill(actual, 1); + EXPECT_THAT(actual, ElementsAre(1, 1, 1, 1, 1)); +} + +TEST(MutatingTest, FillN) { + std::vector actual(5, 0); + absl::c_fill_n(actual, 2, 1); + EXPECT_THAT(actual, ElementsAre(1, 1, 0, 0, 0)); +} + +TEST(MutatingTest, Generate) { + std::vector actual(5); + int x = 0; + absl::c_generate(actual, [&x]() { return ++x; }); + EXPECT_THAT(actual, ElementsAre(1, 2, 3, 4, 5)); +} + +TEST(MutatingTest, GenerateN) { + std::vector actual(5, 0); + int x = 0; + absl::c_generate_n(actual, 3, [&x]() { return ++x; }); + EXPECT_THAT(actual, ElementsAre(1, 2, 3, 0, 0)); +} + +TEST(MutatingTest, RemoveCopy) { + std::vector actual; + absl::c_remove_copy(std::vector{1, 2, 3}, back_inserter(actual), 2); + EXPECT_THAT(actual, ElementsAre(1, 3)); +} + +TEST(MutatingTest, RemoveCopyIf) { + std::vector actual; + absl::c_remove_copy_if(std::vector{1, 2, 3}, back_inserter(actual), + IsOdd); + EXPECT_THAT(actual, ElementsAre(2)); +} + +TEST(MutatingTest, UniqueCopy) { + std::vector actual; + absl::c_unique_copy(std::vector{1, 2, 2, 2, 3, 3, 2}, + back_inserter(actual)); + EXPECT_THAT(actual, ElementsAre(1, 2, 3, 2)); +} + +TEST(MutatingTest, UniqueCopyWithPredicate) { + std::vector actual; + absl::c_unique_copy(std::vector{1, 2, 3, -1, -2, -3, 1}, + back_inserter(actual), + [](int x, int y) { return (x < 0) == (y < 0); }); + EXPECT_THAT(actual, ElementsAre(1, -1, 1)); +} + +TEST(MutatingTest, Reverse) { + std::vector test_vector = {1, 2, 3, 4}; + absl::c_reverse(test_vector); + EXPECT_THAT(test_vector, ElementsAre(4, 3, 2, 1)); + + std::list test_list = {1, 2, 3, 4}; + absl::c_reverse(test_list); + EXPECT_THAT(test_list, ElementsAre(4, 3, 2, 1)); +} + +TEST(MutatingTest, ReverseCopy) { + std::vector actual; + absl::c_reverse_copy(std::vector{1, 2, 3, 4}, back_inserter(actual)); + EXPECT_THAT(actual, ElementsAre(4, 3, 2, 1)); +} + +TEST(MutatingTest, Rotate) { + std::vector actual = {1, 2, 3, 4}; + auto it = absl::c_rotate(actual, actual.begin() + 2); + EXPECT_THAT(actual, testing::ElementsAreArray({3, 4, 1, 2})); + EXPECT_EQ(*it, 1); +} + +TEST(MutatingTest, RotateCopy) { + std::vector initial = {1, 2, 3, 4}; + std::vector actual; + auto end = + absl::c_rotate_copy(initial, initial.begin() + 2, back_inserter(actual)); + *end = 5; + EXPECT_THAT(actual, ElementsAre(3, 4, 1, 2, 5)); +} + +TEST(MutatingTest, Shuffle) { + std::vector actual = {1, 2, 3, 4, 5}; + absl::c_shuffle(actual, std::random_device()); + EXPECT_THAT(actual, UnorderedElementsAre(1, 2, 3, 4, 5)); +} + +TEST(MutatingTest, PartialSort) { + std::vector sequence{5, 3, 42, 0}; + absl::c_partial_sort(sequence, sequence.begin() + 2); + EXPECT_THAT(absl::MakeSpan(sequence.data(), 2), ElementsAre(0, 3)); + absl::c_partial_sort(sequence, sequence.begin() + 2, std::greater()); + EXPECT_THAT(absl::MakeSpan(sequence.data(), 2), ElementsAre(42, 5)); +} + +TEST(MutatingTest, PartialSortCopy) { + const std::vector initial = {5, 3, 42, 0}; + std::vector actual(2); + absl::c_partial_sort_copy(initial, actual); + EXPECT_THAT(actual, ElementsAre(0, 3)); + absl::c_partial_sort_copy(initial, actual, std::greater()); + EXPECT_THAT(actual, ElementsAre(42, 5)); +} + +TEST(MutatingTest, Merge) { + std::vector actual; + absl::c_merge(std::vector{1, 3, 5}, std::vector{2, 4}, + back_inserter(actual)); + EXPECT_THAT(actual, ElementsAre(1, 2, 3, 4, 5)); +} + +TEST(MutatingTest, MergeWithComparator) { + std::vector actual; + absl::c_merge(std::vector{5, 3, 1}, std::vector{4, 2}, + back_inserter(actual), std::greater()); + EXPECT_THAT(actual, ElementsAre(5, 4, 3, 2, 1)); +} + +TEST(MutatingTest, InplaceMerge) { + std::vector actual = {1, 3, 5, 2, 4}; + absl::c_inplace_merge(actual, actual.begin() + 3); + EXPECT_THAT(actual, ElementsAre(1, 2, 3, 4, 5)); +} + +TEST(MutatingTest, InplaceMergeWithComparator) { + std::vector actual = {5, 3, 1, 4, 2}; + absl::c_inplace_merge(actual, actual.begin() + 3, std::greater()); + EXPECT_THAT(actual, ElementsAre(5, 4, 3, 2, 1)); +} + +class SetOperationsTest : public testing::Test { + protected: + std::vector a_ = {1, 2, 3}; + std::vector b_ = {1, 3, 5}; + + std::vector a_reversed_ = {3, 2, 1}; + std::vector b_reversed_ = {5, 3, 1}; +}; + +TEST_F(SetOperationsTest, SetUnion) { + std::vector actual; + absl::c_set_union(a_, b_, back_inserter(actual)); + EXPECT_THAT(actual, ElementsAre(1, 2, 3, 5)); +} + +TEST_F(SetOperationsTest, SetUnionWithComparator) { + std::vector actual; + absl::c_set_union(a_reversed_, b_reversed_, back_inserter(actual), + std::greater()); + EXPECT_THAT(actual, ElementsAre(5, 3, 2, 1)); +} + +TEST_F(SetOperationsTest, SetIntersection) { + std::vector actual; + absl::c_set_intersection(a_, b_, back_inserter(actual)); + EXPECT_THAT(actual, ElementsAre(1, 3)); +} + +TEST_F(SetOperationsTest, SetIntersectionWithComparator) { + std::vector actual; + absl::c_set_intersection(a_reversed_, b_reversed_, back_inserter(actual), + std::greater()); + EXPECT_THAT(actual, ElementsAre(3, 1)); +} + +TEST_F(SetOperationsTest, SetDifference) { + std::vector actual; + absl::c_set_difference(a_, b_, back_inserter(actual)); + EXPECT_THAT(actual, ElementsAre(2)); +} + +TEST_F(SetOperationsTest, SetDifferenceWithComparator) { + std::vector actual; + absl::c_set_difference(a_reversed_, b_reversed_, back_inserter(actual), + std::greater()); + EXPECT_THAT(actual, ElementsAre(2)); +} + +TEST_F(SetOperationsTest, SetSymmetricDifference) { + std::vector actual; + absl::c_set_symmetric_difference(a_, b_, back_inserter(actual)); + EXPECT_THAT(actual, ElementsAre(2, 5)); +} + +TEST_F(SetOperationsTest, SetSymmetricDifferenceWithComparator) { + std::vector actual; + absl::c_set_symmetric_difference(a_reversed_, b_reversed_, + back_inserter(actual), std::greater()); + EXPECT_THAT(actual, ElementsAre(5, 2)); +} + +TEST(HeapOperationsTest, WithoutComparator) { + std::vector heap = {1, 2, 3}; + EXPECT_FALSE(absl::c_is_heap(heap)); + absl::c_make_heap(heap); + EXPECT_TRUE(absl::c_is_heap(heap)); + heap.push_back(4); + EXPECT_EQ(3, absl::c_is_heap_until(heap) - heap.begin()); + absl::c_push_heap(heap); + EXPECT_EQ(4, heap[0]); + absl::c_pop_heap(heap); + EXPECT_EQ(4, heap[3]); + absl::c_make_heap(heap); + absl::c_sort_heap(heap); + EXPECT_THAT(heap, ElementsAre(1, 2, 3, 4)); + EXPECT_FALSE(absl::c_is_heap(heap)); +} + +TEST(HeapOperationsTest, WithComparator) { + using greater = std::greater; + std::vector heap = {3, 2, 1}; + EXPECT_FALSE(absl::c_is_heap(heap, greater())); + absl::c_make_heap(heap, greater()); + EXPECT_TRUE(absl::c_is_heap(heap, greater())); + heap.push_back(0); + EXPECT_EQ(3, absl::c_is_heap_until(heap, greater()) - heap.begin()); + absl::c_push_heap(heap, greater()); + EXPECT_EQ(0, heap[0]); + absl::c_pop_heap(heap, greater()); + EXPECT_EQ(0, heap[3]); + absl::c_make_heap(heap, greater()); + absl::c_sort_heap(heap, greater()); + EXPECT_THAT(heap, ElementsAre(3, 2, 1, 0)); + EXPECT_FALSE(absl::c_is_heap(heap, greater())); +} + +TEST(MutatingTest, PermutationOperations) { + std::vector initial = {1, 2, 3, 4}; + std::vector permuted = initial; + + absl::c_next_permutation(permuted); + EXPECT_TRUE(absl::c_is_permutation(initial, permuted)); + EXPECT_TRUE(absl::c_is_permutation(initial, permuted, std::equal_to())); + + std::vector permuted2 = initial; + absl::c_prev_permutation(permuted2, std::greater()); + EXPECT_EQ(permuted, permuted2); + + absl::c_prev_permutation(permuted); + EXPECT_EQ(initial, permuted); +} + +} // namespace diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/algorithm/equal_benchmark.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/algorithm/equal_benchmark.cc new file mode 100644 index 0000000..19c0780 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/algorithm/equal_benchmark.cc @@ -0,0 +1,126 @@ +// Copyright 2017 The Abseil Authors. +// +// 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 +#include + +#include "benchmark/benchmark.h" +#include "absl/algorithm/algorithm.h" + +namespace { + +// The range of sequence sizes to benchmark. +constexpr int kMinBenchmarkSize = 1024; +constexpr int kMaxBenchmarkSize = 8 * 1024 * 1024; + +// A user-defined type for use in equality benchmarks. Note that we expect +// std::memcmp to win for this type: libstdc++'s std::equal only defers to +// memcmp for integral types. This is because it is not straightforward to +// guarantee that std::memcmp would produce a result "as-if" compared by +// operator== for other types (example gotchas: NaN floats, structs with +// padding). +struct EightBits { + explicit EightBits(int /* unused */) : data(0) {} + bool operator==(const EightBits& rhs) const { return data == rhs.data; } + uint8_t data; +}; + +template +void BM_absl_equal_benchmark(benchmark::State& state) { + std::vector xs(state.range(0), T(0)); + std::vector ys = xs; + while (state.KeepRunning()) { + const bool same = absl::equal(xs.begin(), xs.end(), ys.begin(), ys.end()); + benchmark::DoNotOptimize(same); + } +} + +template +void BM_std_equal_benchmark(benchmark::State& state) { + std::vector xs(state.range(0), T(0)); + std::vector ys = xs; + while (state.KeepRunning()) { + const bool same = std::equal(xs.begin(), xs.end(), ys.begin()); + benchmark::DoNotOptimize(same); + } +} + +template +void BM_memcmp_benchmark(benchmark::State& state) { + std::vector xs(state.range(0), T(0)); + std::vector ys = xs; + while (state.KeepRunning()) { + const bool same = + std::memcmp(xs.data(), ys.data(), xs.size() * sizeof(T)) == 0; + benchmark::DoNotOptimize(same); + } +} + +// The expectation is that the compiler should be able to elide the equality +// comparison altogether for sufficiently simple types. +template +void BM_absl_equal_self_benchmark(benchmark::State& state) { + std::vector xs(state.range(0), T(0)); + while (state.KeepRunning()) { + const bool same = absl::equal(xs.begin(), xs.end(), xs.begin(), xs.end()); + benchmark::DoNotOptimize(same); + } +} + +BENCHMARK_TEMPLATE(BM_absl_equal_benchmark, uint8_t) + ->Range(kMinBenchmarkSize, kMaxBenchmarkSize); +BENCHMARK_TEMPLATE(BM_std_equal_benchmark, uint8_t) + ->Range(kMinBenchmarkSize, kMaxBenchmarkSize); +BENCHMARK_TEMPLATE(BM_memcmp_benchmark, uint8_t) + ->Range(kMinBenchmarkSize, kMaxBenchmarkSize); +BENCHMARK_TEMPLATE(BM_absl_equal_self_benchmark, uint8_t) + ->Range(kMinBenchmarkSize, kMaxBenchmarkSize); + +BENCHMARK_TEMPLATE(BM_absl_equal_benchmark, uint16_t) + ->Range(kMinBenchmarkSize, kMaxBenchmarkSize); +BENCHMARK_TEMPLATE(BM_std_equal_benchmark, uint16_t) + ->Range(kMinBenchmarkSize, kMaxBenchmarkSize); +BENCHMARK_TEMPLATE(BM_memcmp_benchmark, uint16_t) + ->Range(kMinBenchmarkSize, kMaxBenchmarkSize); +BENCHMARK_TEMPLATE(BM_absl_equal_self_benchmark, uint16_t) + ->Range(kMinBenchmarkSize, kMaxBenchmarkSize); + +BENCHMARK_TEMPLATE(BM_absl_equal_benchmark, uint32_t) + ->Range(kMinBenchmarkSize, kMaxBenchmarkSize); +BENCHMARK_TEMPLATE(BM_std_equal_benchmark, uint32_t) + ->Range(kMinBenchmarkSize, kMaxBenchmarkSize); +BENCHMARK_TEMPLATE(BM_memcmp_benchmark, uint32_t) + ->Range(kMinBenchmarkSize, kMaxBenchmarkSize); +BENCHMARK_TEMPLATE(BM_absl_equal_self_benchmark, uint32_t) + ->Range(kMinBenchmarkSize, kMaxBenchmarkSize); + +BENCHMARK_TEMPLATE(BM_absl_equal_benchmark, uint64_t) + ->Range(kMinBenchmarkSize, kMaxBenchmarkSize); +BENCHMARK_TEMPLATE(BM_std_equal_benchmark, uint64_t) + ->Range(kMinBenchmarkSize, kMaxBenchmarkSize); +BENCHMARK_TEMPLATE(BM_memcmp_benchmark, uint64_t) + ->Range(kMinBenchmarkSize, kMaxBenchmarkSize); +BENCHMARK_TEMPLATE(BM_absl_equal_self_benchmark, uint64_t) + ->Range(kMinBenchmarkSize, kMaxBenchmarkSize); + +BENCHMARK_TEMPLATE(BM_absl_equal_benchmark, EightBits) + ->Range(kMinBenchmarkSize, kMaxBenchmarkSize); +BENCHMARK_TEMPLATE(BM_std_equal_benchmark, EightBits) + ->Range(kMinBenchmarkSize, kMaxBenchmarkSize); +BENCHMARK_TEMPLATE(BM_memcmp_benchmark, EightBits) + ->Range(kMinBenchmarkSize, kMaxBenchmarkSize); +BENCHMARK_TEMPLATE(BM_absl_equal_self_benchmark, EightBits) + ->Range(kMinBenchmarkSize, kMaxBenchmarkSize); + +} // namespace diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/BUILD.bazel b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/BUILD.bazel new file mode 100644 index 0000000..44de05e --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/BUILD.bazel @@ -0,0 +1,457 @@ +# +# Copyright 2017 The Abseil Authors. +# +# 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. +# + +load( + "//absl:copts.bzl", + "ABSL_DEFAULT_COPTS", + "ABSL_TEST_COPTS", + "ABSL_EXCEPTIONS_FLAG", + "ABSL_EXCEPTIONS_FLAG_LINKOPTS", +) + +package(default_visibility = ["//visibility:public"]) + +licenses(["notice"]) # Apache 2.0 + +cc_library( + name = "spinlock_wait", + srcs = [ + "internal/spinlock_akaros.inc", + "internal/spinlock_linux.inc", + "internal/spinlock_posix.inc", + "internal/spinlock_wait.cc", + "internal/spinlock_win32.inc", + ], + hdrs = [ + "internal/scheduling_mode.h", + "internal/spinlock_wait.h", + ], + copts = ABSL_DEFAULT_COPTS, + visibility = [ + "//absl/base:__pkg__", + ], + deps = [":core_headers"], +) + +cc_library( + name = "config", + hdrs = [ + "config.h", + "policy_checks.h", + ], + copts = ABSL_DEFAULT_COPTS, +) + +cc_library( + name = "dynamic_annotations", + srcs = ["dynamic_annotations.cc"], + hdrs = ["dynamic_annotations.h"], + copts = ABSL_DEFAULT_COPTS, + defines = ["__CLANG_SUPPORT_DYN_ANNOTATION__"], +) + +cc_library( + name = "core_headers", + hdrs = [ + "attributes.h", + "macros.h", + "optimization.h", + "port.h", + "thread_annotations.h", + ], + copts = ABSL_DEFAULT_COPTS, + deps = [ + ":config", + ], +) + +cc_library( + name = "malloc_internal", + srcs = [ + "internal/low_level_alloc.cc", + ], + hdrs = [ + "internal/direct_mmap.h", + "internal/low_level_alloc.h", + ], + copts = ABSL_DEFAULT_COPTS, + visibility = [ + "//absl:__subpackages__", + ], + deps = [ + ":base", + ":config", + ":core_headers", + ":dynamic_annotations", + ":spinlock_wait", + ], +) + +cc_library( + name = "base_internal", + hdrs = [ + "internal/hide_ptr.h", + "internal/identity.h", + "internal/inline_variable.h", + "internal/invoke.h", + ], + copts = ABSL_DEFAULT_COPTS, + visibility = [ + "//absl:__subpackages__", + ], +) + +cc_library( + name = "base", + srcs = [ + "internal/cycleclock.cc", + "internal/raw_logging.cc", + "internal/spinlock.cc", + "internal/sysinfo.cc", + "internal/thread_identity.cc", + "internal/unscaledcycleclock.cc", + ], + hdrs = [ + "call_once.h", + "casts.h", + "internal/atomic_hook.h", + "internal/cycleclock.h", + "internal/low_level_scheduling.h", + "internal/per_thread_tls.h", + "internal/raw_logging.h", + "internal/spinlock.h", + "internal/sysinfo.h", + "internal/thread_identity.h", + "internal/tsan_mutex_interface.h", + "internal/unscaledcycleclock.h", + "log_severity.h", + ], + copts = ABSL_DEFAULT_COPTS, + deps = [ + ":base_internal", + ":config", + ":core_headers", + ":dynamic_annotations", + ":spinlock_wait", + ], +) + +cc_test( + name = "atomic_hook_test", + size = "small", + srcs = ["internal/atomic_hook_test.cc"], + copts = ABSL_TEST_COPTS, + deps = [ + ":base", + ":core_headers", + "@com_google_googletest//:gtest_main", + ], +) + +cc_test( + name = "bit_cast_test", + size = "small", + srcs = [ + "bit_cast_test.cc", + ], + copts = ABSL_TEST_COPTS, + deps = [ + ":base", + ":core_headers", + "@com_google_googletest//:gtest_main", + ], +) + +cc_library( + name = "throw_delegate", + srcs = ["internal/throw_delegate.cc"], + hdrs = ["internal/throw_delegate.h"], + copts = ABSL_DEFAULT_COPTS + ABSL_EXCEPTIONS_FLAG, + linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS, + visibility = [ + "//absl:__subpackages__", + ], + deps = [ + ":base", + ":config", + ], +) + +cc_test( + name = "throw_delegate_test", + srcs = ["throw_delegate_test.cc"], + copts = ABSL_TEST_COPTS + ABSL_EXCEPTIONS_FLAG, + linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS, + deps = [ + ":throw_delegate", + "@com_google_googletest//:gtest_main", + ], +) + +cc_library( + name = "exception_testing", + testonly = 1, + hdrs = ["internal/exception_testing.h"], + copts = ABSL_TEST_COPTS, + visibility = [ + "//absl:__subpackages__", + ], + deps = [ + ":config", + "@com_google_googletest//:gtest", + ], +) + +cc_library( + name = "pretty_function", + hdrs = ["internal/pretty_function.h"], + visibility = ["//absl:__subpackages__"], +) + +cc_library( + name = "exception_safety_testing", + testonly = 1, + srcs = ["internal/exception_safety_testing.cc"], + hdrs = ["internal/exception_safety_testing.h"], + copts = ABSL_TEST_COPTS + ABSL_EXCEPTIONS_FLAG, + linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS, + deps = [ + ":base", + ":config", + ":pretty_function", + "//absl/memory", + "//absl/meta:type_traits", + "//absl/strings", + "//absl/utility", + "@com_google_googletest//:gtest", + ], +) + +cc_test( + name = "exception_safety_testing_test", + srcs = ["exception_safety_testing_test.cc"], + copts = ABSL_TEST_COPTS + ABSL_EXCEPTIONS_FLAG, + linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS, + deps = [ + ":exception_safety_testing", + "//absl/memory", + "@com_google_googletest//:gtest_main", + ], +) + +cc_test( + name = "inline_variable_test", + size = "small", + srcs = [ + "inline_variable_test.cc", + "inline_variable_test_a.cc", + "inline_variable_test_b.cc", + "internal/inline_variable_testing.h", + ], + copts = ABSL_TEST_COPTS, + deps = [ + ":base_internal", + "@com_google_googletest//:gtest_main", + ], +) + +cc_test( + name = "invoke_test", + size = "small", + srcs = ["invoke_test.cc"], + copts = ABSL_TEST_COPTS, + deps = [ + ":base_internal", + "//absl/memory", + "//absl/strings", + "@com_google_googletest//:gtest_main", + ], +) + +# Common test library made available for use in non-absl code that overrides +# AbslInternalSpinLockDelay and AbslInternalSpinLockWake. +cc_library( + name = "spinlock_test_common", + testonly = 1, + srcs = ["spinlock_test_common.cc"], + copts = ABSL_TEST_COPTS, + deps = [ + ":base", + ":core_headers", + ":spinlock_wait", + "//absl/synchronization", + "@com_google_googletest//:gtest", + ], + alwayslink = 1, +) + +cc_test( + name = "spinlock_test", + size = "medium", + srcs = ["spinlock_test_common.cc"], + copts = ABSL_TEST_COPTS, + tags = ["no_test_wasm"], + deps = [ + ":base", + ":core_headers", + ":spinlock_wait", + "//absl/synchronization", + "@com_google_googletest//:gtest_main", + ], +) + +cc_library( + name = "endian", + hdrs = [ + "internal/endian.h", + "internal/unaligned_access.h", + ], + copts = ABSL_DEFAULT_COPTS, + deps = [ + ":config", + ":core_headers", + ], +) + +cc_test( + name = "endian_test", + srcs = ["internal/endian_test.cc"], + copts = ABSL_TEST_COPTS, + deps = [ + ":base", + ":config", + ":endian", + "@com_google_googletest//:gtest_main", + ], +) + +cc_test( + name = "config_test", + srcs = ["config_test.cc"], + copts = ABSL_TEST_COPTS, + tags = [ + "no_test_wasm", + ], + deps = [ + ":config", + "//absl/synchronization:thread_pool", + "@com_google_googletest//:gtest_main", + ], +) + +cc_test( + name = "call_once_test", + srcs = ["call_once_test.cc"], + copts = ABSL_TEST_COPTS, + tags = [ + "no_test_wasm", + ], + deps = [ + ":base", + ":core_headers", + "//absl/synchronization", + "@com_google_googletest//:gtest_main", + ], +) + +cc_test( + name = "raw_logging_test", + srcs = ["raw_logging_test.cc"], + copts = ABSL_TEST_COPTS, + deps = [ + ":base", + "//absl/strings", + "@com_google_googletest//:gtest_main", + ], +) + +cc_test( + name = "sysinfo_test", + size = "small", + srcs = ["internal/sysinfo_test.cc"], + copts = ABSL_TEST_COPTS, + deps = [ + ":base", + "//absl/synchronization", + "@com_google_googletest//:gtest_main", + ], +) + +cc_test( + name = "low_level_alloc_test", + size = "small", + srcs = ["internal/low_level_alloc_test.cc"], + copts = ABSL_TEST_COPTS, + linkopts = select({ + "//absl:windows": [], + "//conditions:default": ["-pthread"], + }), + tags = ["no_test_ios_x86_64"], + deps = [":malloc_internal"], +) + +cc_test( + name = "thread_identity_test", + size = "small", + srcs = ["internal/thread_identity_test.cc"], + copts = ABSL_TEST_COPTS, + linkopts = select({ + "//absl:windows": [], + "//conditions:default": ["-pthread"], + }), + tags = [ + "no_test_wasm", + ], + deps = [ + ":base", + ":core_headers", + "//absl/synchronization", + "@com_google_googletest//:gtest_main", + ], +) + +cc_test( + name = "thread_identity_benchmark", + srcs = ["internal/thread_identity_benchmark.cc"], + copts = ABSL_TEST_COPTS, + tags = ["benchmark"], + visibility = ["//visibility:private"], + deps = [ + ":base", + "//absl/synchronization", + "@com_github_google_benchmark//:benchmark_main", + ], +) + +cc_library( + name = "bits", + hdrs = ["internal/bits.h"], + visibility = [ + "//absl:__subpackages__", + ], + deps = [":core_headers"], +) + +cc_test( + name = "bits_test", + size = "small", + srcs = ["internal/bits_test.cc"], + copts = ABSL_TEST_COPTS, + deps = [ + ":bits", + "@com_google_googletest//:gtest_main", + ], +) diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/CMakeLists.txt b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/CMakeLists.txt new file mode 100644 index 0000000..d506bc4 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/CMakeLists.txt @@ -0,0 +1,396 @@ +# +# Copyright 2017 The Abseil Authors. +# +# 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. +# + +list(APPEND BASE_PUBLIC_HEADERS + "attributes.h" + "call_once.h" + "casts.h" + "config.h" + "dynamic_annotations.h" + "log_severity.h" + "macros.h" + "optimization.h" + "policy_checks.h" + "port.h" + "thread_annotations.h" +) + + +list(APPEND BASE_INTERNAL_HEADERS + "internal/atomic_hook.h" + "internal/bits.h" + "internal/cycleclock.h" + "internal/direct_mmap.h" + "internal/endian.h" + "internal/exception_testing.h" + "internal/exception_safety_testing.h" + "internal/hide_ptr.h" + "internal/identity.h" + "internal/invoke.h" + "internal/inline_variable.h" + "internal/low_level_alloc.h" + "internal/low_level_scheduling.h" + "internal/per_thread_tls.h" + "internal/pretty_function.h" + "internal/raw_logging.h" + "internal/scheduling_mode.h" + "internal/spinlock.h" + "internal/spinlock_wait.h" + "internal/sysinfo.h" + "internal/thread_identity.h" + "internal/throw_delegate.h" + "internal/tsan_mutex_interface.h" + "internal/unaligned_access.h" + "internal/unscaledcycleclock.h" +) + + +# absl_base main library +list(APPEND BASE_SRC + "internal/cycleclock.cc" + "internal/raw_logging.cc" + "internal/spinlock.cc" + "internal/sysinfo.cc" + "internal/thread_identity.cc" + "internal/unscaledcycleclock.cc" + "internal/low_level_alloc.cc" + ${BASE_PUBLIC_HEADERS} + ${BASE_INTERNAL_HEADERS} +) + +absl_library( + TARGET + absl_base + SOURCES + ${BASE_SRC} + PUBLIC_LIBRARIES + absl_dynamic_annotations + absl_internal_spinlock_wait + EXPORT_NAME + base +) + +absl_cc_library( + NAME + throw_delegate + SRCS + "internal/throw_delegate.cc" + HDRS + "internal/throw_delegate.h" + COPTS + ${ABSL_EXCEPTIONS_FLAG} + DEPS + absl::base +) + + +# exception-safety testing library +absl_cc_library( + NAME + exception_safety_testing + HDRS + "internal/exception_safety_testing.h" + SRCS + "internal/exception_safety_testing.cc" + COPTS + ${ABSL_EXCEPTIONS_FLAG} + DEPS + absl::base + absl::memory + absl::meta + absl::strings + absl::optional + gtest + TESTONLY +) + + +# dynamic_annotations library +set(DYNAMIC_ANNOTATIONS_SRC "dynamic_annotations.cc") + +absl_library( + TARGET + absl_dynamic_annotations + SOURCES + ${DYNAMIC_ANNOTATIONS_SRC} +) + +absl_cc_library( + NAME + config + HDRS + "config.h" + "policy_checks.h" + PUBLIC +) + +absl_cc_library( + NAME + core_headers + HDRS + "attributes.h" + "macros.h" + "optimization.h" + "port.h" + "thread_annotations.h" + DEPS + absl::config + PUBLIC +) + +absl_cc_library( + NAME + spinlock_wait + SRCS + "internal/spinlock_wait.cc" + HDRS + "internal/scheduling_mode.h" + "internal/spinlock_wait.h" +) + +absl_cc_library( + NAME + malloc_internal + SRCS + "internal/low_level_alloc.cc" + HDRS + "internal/direct_mmap.h" + "internal/low_level_alloc.h" + DEPS + absl_dynamic_annotations +) + + + +# +## TESTS +# + +# call once test +set(ATOMIC_HOOK_TEST_SRC "internal/atomic_hook_test.cc") +set(ATOMIC_HOOK_TEST_PUBLIC_LIBRARIES absl::base) + +absl_test( + TARGET + atomic_hook_test + SOURCES + ${ATOMIC_HOOK_TEST_SRC} + PUBLIC_LIBRARIES + ${ATOMIC_HOOK_TEST_PUBLIC_LIBRARIES} +) + + +# call once test +set(CALL_ONCE_TEST_SRC "call_once_test.cc") +set(CALL_ONCE_TEST_PUBLIC_LIBRARIES absl::base absl::synchronization) + +absl_test( + TARGET + call_once_test + SOURCES + ${CALL_ONCE_TEST_SRC} + PUBLIC_LIBRARIES + ${CALL_ONCE_TEST_PUBLIC_LIBRARIES} +) + + +# test bit_cast_test +set(BIT_CAST_TEST_SRC "bit_cast_test.cc") + +absl_test( + TARGET + bit_cast_test + SOURCES + ${BIT_CAST_TEST_SRC} +) + + +# test absl_throw_delegate_test +set(THROW_DELEGATE_TEST_SRC "throw_delegate_test.cc") +set(THROW_DELEGATE_TEST_PUBLIC_LIBRARIES absl::base absl_internal_throw_delegate) + +absl_test( + TARGET + throw_delegate_test + SOURCES + ${THROW_DELEGATE_TEST_SRC} + PUBLIC_LIBRARIES + ${THROW_DELEGATE_TEST_PUBLIC_LIBRARIES} +) + + +# test invoke_test +set(INVOKE_TEST_SRC "invoke_test.cc") +set(INVOKE_TEST_PUBLIC_LIBRARIES absl::strings) + +absl_test( + TARGET + invoke_test + SOURCES + ${INVOKE_TEST_SRC} + PUBLIC_LIBRARIES + ${INVOKE_TEST_PUBLIC_LIBRARIES} +) + + +# test inline_variable_test +list(APPEND INLINE_VARIABLE_TEST_SRC + "internal/inline_variable_testing.h" + "inline_variable_test.cc" + "inline_variable_test_a.cc" + "inline_variable_test_b.cc" +) + +set(INLINE_VARIABLE_TEST_PUBLIC_LIBRARIES absl::base) + +absl_test( + TARGET + inline_variable_test + SOURCES + ${INLINE_VARIABLE_TEST_SRC} + PUBLIC_LIBRARIES + ${INLINE_VARIABLE_TEST_PUBLIC_LIBRARIES} +) + + +# test spinlock_test_common +set(SPINLOCK_TEST_COMMON_SRC "spinlock_test_common.cc") +set(SPINLOCK_TEST_COMMON_PUBLIC_LIBRARIES absl::base absl::synchronization) + +absl_test( + TARGET + spinlock_test_common + SOURCES + ${SPINLOCK_TEST_COMMON_SRC} + PUBLIC_LIBRARIES + ${SPINLOCK_TEST_COMMON_PUBLIC_LIBRARIES} +) + + +# test spinlock_test +set(SPINLOCK_TEST_SRC "spinlock_test_common.cc") +set(SPINLOCK_TEST_PUBLIC_LIBRARIES absl::base absl::synchronization) + +absl_test( + TARGET + spinlock_test + SOURCES + ${SPINLOCK_TEST_SRC} + PUBLIC_LIBRARIES + ${SPINLOCK_TEST_PUBLIC_LIBRARIES} +) + + +# test endian_test +set(ENDIAN_TEST_SRC "internal/endian_test.cc") + +absl_test( + TARGET + endian_test + SOURCES + ${ENDIAN_TEST_SRC} +) + + +# test config_test +set(CONFIG_TEST_SRC "config_test.cc") +set(CONFIG_TEST_PUBLIC_LIBRARIES absl::base absl::synchronization) +absl_test( + TARGET + config_test + SOURCES + ${CONFIG_TEST_SRC} + PUBLIC_LIBRARIES + ${CONFIG_TEST_PUBLIC_LIBRARIES} +) + + +# test raw_logging_test +set(RAW_LOGGING_TEST_SRC "raw_logging_test.cc") +set(RAW_LOGGING_TEST_PUBLIC_LIBRARIES absl::base absl::strings) + +absl_test( + TARGET + raw_logging_test + SOURCES + ${RAW_LOGGING_TEST_SRC} + PUBLIC_LIBRARIES + ${RAW_LOGGING_TEST_PUBLIC_LIBRARIES} +) + + +# test sysinfo_test +set(SYSINFO_TEST_SRC "internal/sysinfo_test.cc") +set(SYSINFO_TEST_PUBLIC_LIBRARIES absl::base absl::synchronization) + +absl_test( + TARGET + sysinfo_test + SOURCES + ${SYSINFO_TEST_SRC} + PUBLIC_LIBRARIES + ${SYSINFO_TEST_PUBLIC_LIBRARIES} +) + + +# test low_level_alloc_test +set(LOW_LEVEL_ALLOC_TEST_SRC "internal/low_level_alloc_test.cc") +set(LOW_LEVEL_ALLOC_TEST_PUBLIC_LIBRARIES absl::base) + +absl_test( + TARGET + low_level_alloc_test + SOURCES + ${LOW_LEVEL_ALLOC_TEST_SRC} + PUBLIC_LIBRARIES + ${LOW_LEVEL_ALLOC_TEST_PUBLIC_LIBRARIES} +) + + +# test thread_identity_test +set(THREAD_IDENTITY_TEST_SRC "internal/thread_identity_test.cc") +set(THREAD_IDENTITY_TEST_PUBLIC_LIBRARIES absl::base absl::synchronization) + +absl_test( + TARGET + thread_identity_test + SOURCES + ${THREAD_IDENTITY_TEST_SRC} + PUBLIC_LIBRARIES + ${THREAD_IDENTITY_TEST_PUBLIC_LIBRARIES} +) + +#test exceptions_safety_testing_test +set(EXCEPTION_SAFETY_TESTING_TEST_SRC "exception_safety_testing_test.cc") +set(EXCEPTION_SAFETY_TESTING_TEST_PUBLIC_LIBRARIES + absl::base + absl_internal_exception_safety_testing + absl::memory + absl::meta + absl::strings + absl::utility +) + +absl_test( + TARGET + absl_exception_safety_testing_test + SOURCES + ${EXCEPTION_SAFETY_TESTING_TEST_SRC} + PUBLIC_LIBRARIES + ${EXCEPTION_SAFETY_TESTING_TEST_PUBLIC_LIBRARIES} + PRIVATE_COMPILE_FLAGS + ${ABSL_EXCEPTIONS_FLAG} +) diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/attributes.h b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/attributes.h new file mode 100644 index 0000000..c44b882 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/attributes.h @@ -0,0 +1,586 @@ +// Copyright 2017 The Abseil Authors. +// +// 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. +// +// This header file defines macros for declaring attributes for functions, +// types, and variables. +// +// These macros are used within Abseil and allow the compiler to optimize, where +// applicable, certain function calls. +// +// This file is used for both C and C++! +// +// Most macros here are exposing GCC or Clang features, and are stubbed out for +// other compilers. +// +// GCC attributes documentation: +// https://gcc.gnu.org/onlinedocs/gcc-4.7.0/gcc/Function-Attributes.html +// https://gcc.gnu.org/onlinedocs/gcc-4.7.0/gcc/Variable-Attributes.html +// https://gcc.gnu.org/onlinedocs/gcc-4.7.0/gcc/Type-Attributes.html +// +// Most attributes in this file are already supported by GCC 4.7. However, some +// of them are not supported in older version of Clang. Thus, we check +// `__has_attribute()` first. If the check fails, we check if we are on GCC and +// assume the attribute exists on GCC (which is verified on GCC 4.7). +// +// ----------------------------------------------------------------------------- +// Sanitizer Attributes +// ----------------------------------------------------------------------------- +// +// Sanitizer-related attributes are not "defined" in this file (and indeed +// are not defined as such in any file). To utilize the following +// sanitizer-related attributes within your builds, define the following macros +// within your build using a `-D` flag, along with the given value for +// `-fsanitize`: +// +// * `ADDRESS_SANITIZER` + `-fsanitize=address` (Clang, GCC 4.8) +// * `MEMORY_SANITIZER` + `-fsanitize=memory` (Clang-only) +// * `THREAD_SANITIZER + `-fsanitize=thread` (Clang, GCC 4.8+) +// * `UNDEFINED_BEHAVIOR_SANITIZER` + `-fsanitize=undefined` (Clang, GCC 4.9+) +// * `CONTROL_FLOW_INTEGRITY` + -fsanitize=cfi (Clang-only) +// +// Example: +// +// // Enable branches in the Abseil code that are tagged for ASan: +// $ bazel build --copt=-DADDRESS_SANITIZER --copt=-fsanitize=address +// --linkopt=-fsanitize=address *target* +// +// Since these macro names are only supported by GCC and Clang, we only check +// for `__GNUC__` (GCC or Clang) and the above macros. +#ifndef ABSL_BASE_ATTRIBUTES_H_ +#define ABSL_BASE_ATTRIBUTES_H_ + +// ABSL_HAVE_ATTRIBUTE +// +// A function-like feature checking macro that is a wrapper around +// `__has_attribute`, which is defined by GCC 5+ and Clang and evaluates to a +// nonzero constant integer if the attribute is supported or 0 if not. +// +// It evaluates to zero if `__has_attribute` is not defined by the compiler. +// +// GCC: https://gcc.gnu.org/gcc-5/changes.html +// Clang: https://clang.llvm.org/docs/LanguageExtensions.html +#ifdef __has_attribute +#define ABSL_HAVE_ATTRIBUTE(x) __has_attribute(x) +#else +#define ABSL_HAVE_ATTRIBUTE(x) 0 +#endif + +// ABSL_HAVE_CPP_ATTRIBUTE +// +// A function-like feature checking macro that accepts C++11 style attributes. +// It's a wrapper around `__has_cpp_attribute`, defined by ISO C++ SD-6 +// (http://en.cppreference.com/w/cpp/experimental/feature_test). If we don't +// find `__has_cpp_attribute`, will evaluate to 0. +#if defined(__cplusplus) && defined(__has_cpp_attribute) +// NOTE: requiring __cplusplus above should not be necessary, but +// works around https://bugs.llvm.org/show_bug.cgi?id=23435. +#define ABSL_HAVE_CPP_ATTRIBUTE(x) __has_cpp_attribute(x) +#else +#define ABSL_HAVE_CPP_ATTRIBUTE(x) 0 +#endif + +// ----------------------------------------------------------------------------- +// Function Attributes +// ----------------------------------------------------------------------------- +// +// GCC: https://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html +// Clang: https://clang.llvm.org/docs/AttributeReference.html + +// ABSL_PRINTF_ATTRIBUTE +// ABSL_SCANF_ATTRIBUTE +// +// Tells the compiler to perform `printf` format string checking if the +// compiler supports it; see the 'format' attribute in +// . +// +// Note: As the GCC manual states, "[s]ince non-static C++ methods +// have an implicit 'this' argument, the arguments of such methods +// should be counted from two, not one." +#if ABSL_HAVE_ATTRIBUTE(format) || (defined(__GNUC__) && !defined(__clang__)) +#define ABSL_PRINTF_ATTRIBUTE(string_index, first_to_check) \ + __attribute__((__format__(__printf__, string_index, first_to_check))) +#define ABSL_SCANF_ATTRIBUTE(string_index, first_to_check) \ + __attribute__((__format__(__scanf__, string_index, first_to_check))) +#else +#define ABSL_PRINTF_ATTRIBUTE(string_index, first_to_check) +#define ABSL_SCANF_ATTRIBUTE(string_index, first_to_check) +#endif + +// ABSL_ATTRIBUTE_ALWAYS_INLINE +// ABSL_ATTRIBUTE_NOINLINE +// +// Forces functions to either inline or not inline. Introduced in gcc 3.1. +#if ABSL_HAVE_ATTRIBUTE(always_inline) || \ + (defined(__GNUC__) && !defined(__clang__)) +#define ABSL_ATTRIBUTE_ALWAYS_INLINE __attribute__((always_inline)) +#define ABSL_HAVE_ATTRIBUTE_ALWAYS_INLINE 1 +#else +#define ABSL_ATTRIBUTE_ALWAYS_INLINE +#endif + +#if ABSL_HAVE_ATTRIBUTE(noinline) || (defined(__GNUC__) && !defined(__clang__)) +#define ABSL_ATTRIBUTE_NOINLINE __attribute__((noinline)) +#define ABSL_HAVE_ATTRIBUTE_NOINLINE 1 +#else +#define ABSL_ATTRIBUTE_NOINLINE +#endif + +// ABSL_ATTRIBUTE_NO_TAIL_CALL +// +// Prevents the compiler from optimizing away stack frames for functions which +// end in a call to another function. +#if ABSL_HAVE_ATTRIBUTE(disable_tail_calls) +#define ABSL_HAVE_ATTRIBUTE_NO_TAIL_CALL 1 +#define ABSL_ATTRIBUTE_NO_TAIL_CALL __attribute__((disable_tail_calls)) +#elif defined(__GNUC__) && !defined(__clang__) +#define ABSL_HAVE_ATTRIBUTE_NO_TAIL_CALL 1 +#define ABSL_ATTRIBUTE_NO_TAIL_CALL \ + __attribute__((optimize("no-optimize-sibling-calls"))) +#else +#define ABSL_ATTRIBUTE_NO_TAIL_CALL +#define ABSL_HAVE_ATTRIBUTE_NO_TAIL_CALL 0 +#endif + +// ABSL_ATTRIBUTE_WEAK +// +// Tags a function as weak for the purposes of compilation and linking. +// Weak attributes currently do not work properly in LLVM's Windows backend, +// so disable them there. See https://bugs.llvm.org/show_bug.cgi?id=37598 +// for futher information. +#if (ABSL_HAVE_ATTRIBUTE(weak) || \ + (defined(__GNUC__) && !defined(__clang__))) && \ + !(defined(__llvm__) && defined(_WIN32)) +#undef ABSL_ATTRIBUTE_WEAK +#define ABSL_ATTRIBUTE_WEAK __attribute__((weak)) +#define ABSL_HAVE_ATTRIBUTE_WEAK 1 +#else +#define ABSL_ATTRIBUTE_WEAK +#define ABSL_HAVE_ATTRIBUTE_WEAK 0 +#endif + +// ABSL_ATTRIBUTE_NONNULL +// +// Tells the compiler either (a) that a particular function parameter +// should be a non-null pointer, or (b) that all pointer arguments should +// be non-null. +// +// Note: As the GCC manual states, "[s]ince non-static C++ methods +// have an implicit 'this' argument, the arguments of such methods +// should be counted from two, not one." +// +// Args are indexed starting at 1. +// +// For non-static class member functions, the implicit `this` argument +// is arg 1, and the first explicit argument is arg 2. For static class member +// functions, there is no implicit `this`, and the first explicit argument is +// arg 1. +// +// Example: +// +// /* arg_a cannot be null, but arg_b can */ +// void Function(void* arg_a, void* arg_b) ABSL_ATTRIBUTE_NONNULL(1); +// +// class C { +// /* arg_a cannot be null, but arg_b can */ +// void Method(void* arg_a, void* arg_b) ABSL_ATTRIBUTE_NONNULL(2); +// +// /* arg_a cannot be null, but arg_b can */ +// static void StaticMethod(void* arg_a, void* arg_b) +// ABSL_ATTRIBUTE_NONNULL(1); +// }; +// +// If no arguments are provided, then all pointer arguments should be non-null. +// +// /* No pointer arguments may be null. */ +// void Function(void* arg_a, void* arg_b, int arg_c) ABSL_ATTRIBUTE_NONNULL(); +// +// NOTE: The GCC nonnull attribute actually accepts a list of arguments, but +// ABSL_ATTRIBUTE_NONNULL does not. +#if ABSL_HAVE_ATTRIBUTE(nonnull) || (defined(__GNUC__) && !defined(__clang__)) +#define ABSL_ATTRIBUTE_NONNULL(arg_index) __attribute__((nonnull(arg_index))) +#else +#define ABSL_ATTRIBUTE_NONNULL(...) +#endif + +// ABSL_ATTRIBUTE_NORETURN +// +// Tells the compiler that a given function never returns. +#if ABSL_HAVE_ATTRIBUTE(noreturn) || (defined(__GNUC__) && !defined(__clang__)) +#define ABSL_ATTRIBUTE_NORETURN __attribute__((noreturn)) +#elif defined(_MSC_VER) +#define ABSL_ATTRIBUTE_NORETURN __declspec(noreturn) +#else +#define ABSL_ATTRIBUTE_NORETURN +#endif + +// ABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS +// +// Tells the AddressSanitizer (or other memory testing tools) to ignore a given +// function. Useful for cases when a function reads random locations on stack, +// calls _exit from a cloned subprocess, deliberately accesses buffer +// out of bounds or does other scary things with memory. +// NOTE: GCC supports AddressSanitizer(asan) since 4.8. +// https://gcc.gnu.org/gcc-4.8/changes.html +#if defined(__GNUC__) && defined(ADDRESS_SANITIZER) +#define ABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS __attribute__((no_sanitize_address)) +#else +#define ABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS +#endif + +// ABSL_ATTRIBUTE_NO_SANITIZE_MEMORY +// +// Tells the MemorySanitizer to relax the handling of a given function. All +// "Use of uninitialized value" warnings from such functions will be suppressed, +// and all values loaded from memory will be considered fully initialized. +// This attribute is similar to the ADDRESS_SANITIZER attribute above, but deals +// with initialized-ness rather than addressability issues. +// NOTE: MemorySanitizer(msan) is supported by Clang but not GCC. +#if defined(__GNUC__) && defined(MEMORY_SANITIZER) +#define ABSL_ATTRIBUTE_NO_SANITIZE_MEMORY __attribute__((no_sanitize_memory)) +#else +#define ABSL_ATTRIBUTE_NO_SANITIZE_MEMORY +#endif + +// ABSL_ATTRIBUTE_NO_SANITIZE_THREAD +// +// Tells the ThreadSanitizer to not instrument a given function. +// NOTE: GCC supports ThreadSanitizer(tsan) since 4.8. +// https://gcc.gnu.org/gcc-4.8/changes.html +#if defined(__GNUC__) && defined(THREAD_SANITIZER) +#define ABSL_ATTRIBUTE_NO_SANITIZE_THREAD __attribute__((no_sanitize_thread)) +#else +#define ABSL_ATTRIBUTE_NO_SANITIZE_THREAD +#endif + +// ABSL_ATTRIBUTE_NO_SANITIZE_UNDEFINED +// +// Tells the UndefinedSanitizer to ignore a given function. Useful for cases +// where certain behavior (eg. division by zero) is being used intentionally. +// NOTE: GCC supports UndefinedBehaviorSanitizer(ubsan) since 4.9. +// https://gcc.gnu.org/gcc-4.9/changes.html +#if defined(__GNUC__) && \ + (defined(UNDEFINED_BEHAVIOR_SANITIZER) || defined(ADDRESS_SANITIZER)) +#define ABSL_ATTRIBUTE_NO_SANITIZE_UNDEFINED \ + __attribute__((no_sanitize("undefined"))) +#else +#define ABSL_ATTRIBUTE_NO_SANITIZE_UNDEFINED +#endif + +// ABSL_ATTRIBUTE_NO_SANITIZE_CFI +// +// Tells the ControlFlowIntegrity sanitizer to not instrument a given function. +// See https://clang.llvm.org/docs/ControlFlowIntegrity.html for details. +#if defined(__GNUC__) && defined(CONTROL_FLOW_INTEGRITY) +#define ABSL_ATTRIBUTE_NO_SANITIZE_CFI __attribute__((no_sanitize("cfi"))) +#else +#define ABSL_ATTRIBUTE_NO_SANITIZE_CFI +#endif + +// ABSL_ATTRIBUTE_RETURNS_NONNULL +// +// Tells the compiler that a particular function never returns a null pointer. +#if ABSL_HAVE_ATTRIBUTE(returns_nonnull) || \ + (defined(__GNUC__) && \ + (__GNUC__ > 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9)) && \ + !defined(__clang__)) +#define ABSL_ATTRIBUTE_RETURNS_NONNULL __attribute__((returns_nonnull)) +#else +#define ABSL_ATTRIBUTE_RETURNS_NONNULL +#endif + +// ABSL_HAVE_ATTRIBUTE_SECTION +// +// Indicates whether labeled sections are supported. Weak symbol support is +// a prerequisite. Labeled sections are not supported on Darwin/iOS. +#ifdef ABSL_HAVE_ATTRIBUTE_SECTION +#error ABSL_HAVE_ATTRIBUTE_SECTION cannot be directly set +#elif (ABSL_HAVE_ATTRIBUTE(section) || \ + (defined(__GNUC__) && !defined(__clang__))) && \ + !defined(__APPLE__) && ABSL_HAVE_ATTRIBUTE_WEAK +#define ABSL_HAVE_ATTRIBUTE_SECTION 1 + +// ABSL_ATTRIBUTE_SECTION +// +// Tells the compiler/linker to put a given function into a section and define +// `__start_ ## name` and `__stop_ ## name` symbols to bracket the section. +// This functionality is supported by GNU linker. Any function annotated with +// `ABSL_ATTRIBUTE_SECTION` must not be inlined, or it will be placed into +// whatever section its caller is placed into. +// +#ifndef ABSL_ATTRIBUTE_SECTION +#define ABSL_ATTRIBUTE_SECTION(name) \ + __attribute__((section(#name))) __attribute__((noinline)) +#endif + + +// ABSL_ATTRIBUTE_SECTION_VARIABLE +// +// Tells the compiler/linker to put a given variable into a section and define +// `__start_ ## name` and `__stop_ ## name` symbols to bracket the section. +// This functionality is supported by GNU linker. +#ifndef ABSL_ATTRIBUTE_SECTION_VARIABLE +#define ABSL_ATTRIBUTE_SECTION_VARIABLE(name) __attribute__((section(#name))) +#endif + +// ABSL_DECLARE_ATTRIBUTE_SECTION_VARS +// +// A weak section declaration to be used as a global declaration +// for ABSL_ATTRIBUTE_SECTION_START|STOP(name) to compile and link +// even without functions with ABSL_ATTRIBUTE_SECTION(name). +// ABSL_DEFINE_ATTRIBUTE_SECTION should be in the exactly one file; it's +// a no-op on ELF but not on Mach-O. +// +#ifndef ABSL_DECLARE_ATTRIBUTE_SECTION_VARS +#define ABSL_DECLARE_ATTRIBUTE_SECTION_VARS(name) \ + extern char __start_##name[] ABSL_ATTRIBUTE_WEAK; \ + extern char __stop_##name[] ABSL_ATTRIBUTE_WEAK +#endif +#ifndef ABSL_DEFINE_ATTRIBUTE_SECTION_VARS +#define ABSL_INIT_ATTRIBUTE_SECTION_VARS(name) +#define ABSL_DEFINE_ATTRIBUTE_SECTION_VARS(name) +#endif + +// ABSL_ATTRIBUTE_SECTION_START +// +// Returns `void*` pointers to start/end of a section of code with +// functions having ABSL_ATTRIBUTE_SECTION(name). +// Returns 0 if no such functions exist. +// One must ABSL_DECLARE_ATTRIBUTE_SECTION_VARS(name) for this to compile and +// link. +// +#define ABSL_ATTRIBUTE_SECTION_START(name) \ + (reinterpret_cast(__start_##name)) +#define ABSL_ATTRIBUTE_SECTION_STOP(name) \ + (reinterpret_cast(__stop_##name)) + +#else // !ABSL_HAVE_ATTRIBUTE_SECTION + +#define ABSL_HAVE_ATTRIBUTE_SECTION 0 + +// provide dummy definitions +#define ABSL_ATTRIBUTE_SECTION(name) +#define ABSL_ATTRIBUTE_SECTION_VARIABLE(name) +#define ABSL_INIT_ATTRIBUTE_SECTION_VARS(name) +#define ABSL_DEFINE_ATTRIBUTE_SECTION_VARS(name) +#define ABSL_DECLARE_ATTRIBUTE_SECTION_VARS(name) +#define ABSL_ATTRIBUTE_SECTION_START(name) (reinterpret_cast(0)) +#define ABSL_ATTRIBUTE_SECTION_STOP(name) (reinterpret_cast(0)) + +#endif // ABSL_ATTRIBUTE_SECTION + +// ABSL_ATTRIBUTE_STACK_ALIGN_FOR_OLD_LIBC +// +// Support for aligning the stack on 32-bit x86. +#if ABSL_HAVE_ATTRIBUTE(force_align_arg_pointer) || \ + (defined(__GNUC__) && !defined(__clang__)) +#if defined(__i386__) +#define ABSL_ATTRIBUTE_STACK_ALIGN_FOR_OLD_LIBC \ + __attribute__((force_align_arg_pointer)) +#define ABSL_REQUIRE_STACK_ALIGN_TRAMPOLINE (0) +#elif defined(__x86_64__) +#define ABSL_REQUIRE_STACK_ALIGN_TRAMPOLINE (1) +#define ABSL_ATTRIBUTE_STACK_ALIGN_FOR_OLD_LIBC +#else // !__i386__ && !__x86_64 +#define ABSL_REQUIRE_STACK_ALIGN_TRAMPOLINE (0) +#define ABSL_ATTRIBUTE_STACK_ALIGN_FOR_OLD_LIBC +#endif // __i386__ +#else +#define ABSL_ATTRIBUTE_STACK_ALIGN_FOR_OLD_LIBC +#define ABSL_REQUIRE_STACK_ALIGN_TRAMPOLINE (0) +#endif + +// ABSL_MUST_USE_RESULT +// +// Tells the compiler to warn about unused return values for functions declared +// with this macro. The macro must appear as the very first part of a function +// declaration or definition: +// +// Example: +// +// ABSL_MUST_USE_RESULT Sprocket* AllocateSprocket(); +// +// This placement has the broadest compatibility with GCC, Clang, and MSVC, with +// both defs and decls, and with GCC-style attributes, MSVC declspec, C++11 +// and C++17 attributes. +// +// ABSL_MUST_USE_RESULT allows using cast-to-void to suppress the unused result +// warning. For that, warn_unused_result is used only for clang but not for gcc. +// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66425 +// +// Note: past advice was to place the macro after the argument list. +#if ABSL_HAVE_ATTRIBUTE(nodiscard) +#define ABSL_MUST_USE_RESULT [[nodiscard]] +#elif defined(__clang__) && ABSL_HAVE_ATTRIBUTE(warn_unused_result) +#define ABSL_MUST_USE_RESULT __attribute__((warn_unused_result)) +#else +#define ABSL_MUST_USE_RESULT +#endif + +// ABSL_ATTRIBUTE_HOT, ABSL_ATTRIBUTE_COLD +// +// Tells GCC that a function is hot or cold. GCC can use this information to +// improve static analysis, i.e. a conditional branch to a cold function +// is likely to be not-taken. +// This annotation is used for function declarations. +// +// Example: +// +// int foo() ABSL_ATTRIBUTE_HOT; +#if ABSL_HAVE_ATTRIBUTE(hot) || (defined(__GNUC__) && !defined(__clang__)) +#define ABSL_ATTRIBUTE_HOT __attribute__((hot)) +#else +#define ABSL_ATTRIBUTE_HOT +#endif + +#if ABSL_HAVE_ATTRIBUTE(cold) || (defined(__GNUC__) && !defined(__clang__)) +#define ABSL_ATTRIBUTE_COLD __attribute__((cold)) +#else +#define ABSL_ATTRIBUTE_COLD +#endif + +// ABSL_XRAY_ALWAYS_INSTRUMENT, ABSL_XRAY_NEVER_INSTRUMENT, ABSL_XRAY_LOG_ARGS +// +// We define the ABSL_XRAY_ALWAYS_INSTRUMENT and ABSL_XRAY_NEVER_INSTRUMENT +// macro used as an attribute to mark functions that must always or never be +// instrumented by XRay. Currently, this is only supported in Clang/LLVM. +// +// For reference on the LLVM XRay instrumentation, see +// http://llvm.org/docs/XRay.html. +// +// A function with the XRAY_ALWAYS_INSTRUMENT macro attribute in its declaration +// will always get the XRay instrumentation sleds. These sleds may introduce +// some binary size and runtime overhead and must be used sparingly. +// +// These attributes only take effect when the following conditions are met: +// +// * The file/target is built in at least C++11 mode, with a Clang compiler +// that supports XRay attributes. +// * The file/target is built with the -fxray-instrument flag set for the +// Clang/LLVM compiler. +// * The function is defined in the translation unit (the compiler honors the +// attribute in either the definition or the declaration, and must match). +// +// There are cases when, even when building with XRay instrumentation, users +// might want to control specifically which functions are instrumented for a +// particular build using special-case lists provided to the compiler. These +// special case lists are provided to Clang via the +// -fxray-always-instrument=... and -fxray-never-instrument=... flags. The +// attributes in source take precedence over these special-case lists. +// +// To disable the XRay attributes at build-time, users may define +// ABSL_NO_XRAY_ATTRIBUTES. Do NOT define ABSL_NO_XRAY_ATTRIBUTES on specific +// packages/targets, as this may lead to conflicting definitions of functions at +// link-time. +// +#if ABSL_HAVE_CPP_ATTRIBUTE(clang::xray_always_instrument) && \ + !defined(ABSL_NO_XRAY_ATTRIBUTES) +#define ABSL_XRAY_ALWAYS_INSTRUMENT [[clang::xray_always_instrument]] +#define ABSL_XRAY_NEVER_INSTRUMENT [[clang::xray_never_instrument]] +#if ABSL_HAVE_CPP_ATTRIBUTE(clang::xray_log_args) +#define ABSL_XRAY_LOG_ARGS(N) \ + [[clang::xray_always_instrument, clang::xray_log_args(N)]] +#else +#define ABSL_XRAY_LOG_ARGS(N) [[clang::xray_always_instrument]] +#endif +#else +#define ABSL_XRAY_ALWAYS_INSTRUMENT +#define ABSL_XRAY_NEVER_INSTRUMENT +#define ABSL_XRAY_LOG_ARGS(N) +#endif + +// ABSL_ATTRIBUTE_REINITIALIZES +// +// Indicates that a member function reinitializes the entire object to a known +// state, independent of the previous state of the object. +// +// The clang-tidy check bugprone-use-after-move allows member functions marked +// with this attribute to be called on objects that have been moved from; +// without the attribute, this would result in a use-after-move warning. +#if ABSL_HAVE_CPP_ATTRIBUTE(clang::reinitializes) +#define ABSL_ATTRIBUTE_REINITIALIZES [[clang::reinitializes]] +#else +#define ABSL_ATTRIBUTE_REINITIALIZES +#endif + +// ----------------------------------------------------------------------------- +// Variable Attributes +// ----------------------------------------------------------------------------- + +// ABSL_ATTRIBUTE_UNUSED +// +// Prevents the compiler from complaining about variables that appear unused. +#if ABSL_HAVE_ATTRIBUTE(unused) || (defined(__GNUC__) && !defined(__clang__)) +#undef ABSL_ATTRIBUTE_UNUSED +#define ABSL_ATTRIBUTE_UNUSED __attribute__((__unused__)) +#else +#define ABSL_ATTRIBUTE_UNUSED +#endif + +// ABSL_ATTRIBUTE_INITIAL_EXEC +// +// Tells the compiler to use "initial-exec" mode for a thread-local variable. +// See http://people.redhat.com/drepper/tls.pdf for the gory details. +#if ABSL_HAVE_ATTRIBUTE(tls_model) || (defined(__GNUC__) && !defined(__clang__)) +#define ABSL_ATTRIBUTE_INITIAL_EXEC __attribute__((tls_model("initial-exec"))) +#else +#define ABSL_ATTRIBUTE_INITIAL_EXEC +#endif + +// ABSL_ATTRIBUTE_PACKED +// +// Prevents the compiler from padding a structure to natural alignment +#if ABSL_HAVE_ATTRIBUTE(packed) || (defined(__GNUC__) && !defined(__clang__)) +#define ABSL_ATTRIBUTE_PACKED __attribute__((__packed__)) +#else +#define ABSL_ATTRIBUTE_PACKED +#endif + +// ABSL_ATTRIBUTE_FUNC_ALIGN +// +// Tells the compiler to align the function start at least to certain +// alignment boundary +#if ABSL_HAVE_ATTRIBUTE(aligned) || (defined(__GNUC__) && !defined(__clang__)) +#define ABSL_ATTRIBUTE_FUNC_ALIGN(bytes) __attribute__((aligned(bytes))) +#else +#define ABSL_ATTRIBUTE_FUNC_ALIGN(bytes) +#endif + +// ABSL_CONST_INIT +// +// A variable declaration annotated with the `ABSL_CONST_INIT` attribute will +// not compile (on supported platforms) unless the variable has a constant +// initializer. This is useful for variables with static and thread storage +// duration, because it guarantees that they will not suffer from the so-called +// "static init order fiasco". Prefer to put this attribute on the most visible +// declaration of the variable, if there's more than one, because code that +// accesses the variable can then use the attribute for optimization. +// +// Example: +// +// class MyClass { +// public: +// ABSL_CONST_INIT static MyType my_var; +// }; +// +// MyType MyClass::my_var = MakeMyType(...); +// +// Note that this attribute is redundant if the variable is declared constexpr. +#if ABSL_HAVE_CPP_ATTRIBUTE(clang::require_constant_initialization) +// NOLINTNEXTLINE(whitespace/braces) +#define ABSL_CONST_INIT [[clang::require_constant_initialization]] +#else +#define ABSL_CONST_INIT +#endif // ABSL_HAVE_CPP_ATTRIBUTE(clang::require_constant_initialization) + +#endif // ABSL_BASE_ATTRIBUTES_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/bit_cast_test.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/bit_cast_test.cc new file mode 100644 index 0000000..8cd878d --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/bit_cast_test.cc @@ -0,0 +1,107 @@ +// Copyright 2017 The Abseil Authors. +// +// 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. + +// Unit test for bit_cast template. + +#include +#include + +#include "gtest/gtest.h" +#include "absl/base/casts.h" +#include "absl/base/macros.h" + +namespace absl { +namespace { + +template +struct marshall { char buf[N]; }; + +template +void TestMarshall(const T values[], int num_values) { + for (int i = 0; i < num_values; ++i) { + T t0 = values[i]; + marshall m0 = absl::bit_cast >(t0); + T t1 = absl::bit_cast(m0); + marshall m1 = absl::bit_cast >(t1); + ASSERT_EQ(0, memcmp(&t0, &t1, sizeof(T))); + ASSERT_EQ(0, memcmp(&m0, &m1, sizeof(T))); + } +} + +// Convert back and forth to an integral type. The C++ standard does +// not guarantee this will work, but we test that this works on all the +// platforms we support. +// +// Likewise, we below make assumptions about sizeof(float) and +// sizeof(double) which the standard does not guarantee, but which hold on the +// platforms we support. + +template +void TestIntegral(const T values[], int num_values) { + for (int i = 0; i < num_values; ++i) { + T t0 = values[i]; + I i0 = absl::bit_cast(t0); + T t1 = absl::bit_cast(i0); + I i1 = absl::bit_cast(t1); + ASSERT_EQ(0, memcmp(&t0, &t1, sizeof(T))); + ASSERT_EQ(i0, i1); + } +} + +TEST(BitCast, Bool) { + static const bool bool_list[] = { false, true }; + TestMarshall(bool_list, ABSL_ARRAYSIZE(bool_list)); +} + +TEST(BitCast, Int32) { + static const int32_t int_list[] = + { 0, 1, 100, 2147483647, -1, -100, -2147483647, -2147483647-1 }; + TestMarshall(int_list, ABSL_ARRAYSIZE(int_list)); +} + +TEST(BitCast, Int64) { + static const int64_t int64_list[] = + { 0, 1, 1LL << 40, -1, -(1LL<<40) }; + TestMarshall(int64_list, ABSL_ARRAYSIZE(int64_list)); +} + +TEST(BitCast, Uint64) { + static const uint64_t uint64_list[] = + { 0, 1, 1LLU << 40, 1LLU << 63 }; + TestMarshall(uint64_list, ABSL_ARRAYSIZE(uint64_list)); +} + +TEST(BitCast, Float) { + static const float float_list[] = + { 0.0f, 1.0f, -1.0f, 10.0f, -10.0f, + 1e10f, 1e20f, 1e-10f, 1e-20f, + 2.71828f, 3.14159f }; + TestMarshall(float_list, ABSL_ARRAYSIZE(float_list)); + TestIntegral(float_list, ABSL_ARRAYSIZE(float_list)); + TestIntegral(float_list, ABSL_ARRAYSIZE(float_list)); +} + +TEST(BitCast, Double) { + static const double double_list[] = + { 0.0, 1.0, -1.0, 10.0, -10.0, + 1e10, 1e100, 1e-10, 1e-100, + 2.718281828459045, + 3.141592653589793238462643383279502884197169399375105820974944 }; + TestMarshall(double_list, ABSL_ARRAYSIZE(double_list)); + TestIntegral(double_list, ABSL_ARRAYSIZE(double_list)); + TestIntegral(double_list, ABSL_ARRAYSIZE(double_list)); +} + +} // namespace +} // namespace absl diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/call_once.h b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/call_once.h new file mode 100644 index 0000000..532ee2e --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/call_once.h @@ -0,0 +1,216 @@ +// Copyright 2017 The Abseil Authors. +// +// 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. +// +// ----------------------------------------------------------------------------- +// File: call_once.h +// ----------------------------------------------------------------------------- +// +// This header file provides an Abseil version of `std::call_once` for invoking +// a given function at most once, across all threads. This Abseil version is +// faster than the C++11 version and incorporates the C++17 argument-passing +// fix, so that (for example) non-const references may be passed to the invoked +// function. + +#ifndef ABSL_BASE_CALL_ONCE_H_ +#define ABSL_BASE_CALL_ONCE_H_ + +#include +#include +#include +#include + +#include "absl/base/internal/invoke.h" +#include "absl/base/internal/low_level_scheduling.h" +#include "absl/base/internal/raw_logging.h" +#include "absl/base/internal/scheduling_mode.h" +#include "absl/base/internal/spinlock_wait.h" +#include "absl/base/macros.h" +#include "absl/base/port.h" + +namespace absl { + +class once_flag; + +namespace base_internal { +std::atomic* ControlWord(absl::once_flag* flag); +} // namespace base_internal + +// call_once() +// +// For all invocations using a given `once_flag`, invokes a given `fn` exactly +// once across all threads. The first call to `call_once()` with a particular +// `once_flag` argument (that does not throw an exception) will run the +// specified function with the provided `args`; other calls with the same +// `once_flag` argument will not run the function, but will wait +// for the provided function to finish running (if it is still running). +// +// This mechanism provides a safe, simple, and fast mechanism for one-time +// initialization in a multi-threaded process. +// +// Example: +// +// class MyInitClass { +// public: +// ... +// mutable absl::once_flag once_; +// +// MyInitClass* init() const { +// absl::call_once(once_, &MyInitClass::Init, this); +// return ptr_; +// } +// +template +void call_once(absl::once_flag& flag, Callable&& fn, Args&&... args); + +// once_flag +// +// Objects of this type are used to distinguish calls to `call_once()` and +// ensure the provided function is only invoked once across all threads. This +// type is not copyable or movable. However, it has a `constexpr` +// constructor, and is safe to use as a namespace-scoped global variable. +class once_flag { + public: + constexpr once_flag() : control_(0) {} + once_flag(const once_flag&) = delete; + once_flag& operator=(const once_flag&) = delete; + + private: + friend std::atomic* base_internal::ControlWord(once_flag* flag); + std::atomic control_; +}; + +//------------------------------------------------------------------------------ +// End of public interfaces. +// Implementation details follow. +//------------------------------------------------------------------------------ + +namespace base_internal { + +// Like call_once, but uses KERNEL_ONLY scheduling. Intended to be used to +// initialize entities used by the scheduler implementation. +template +void LowLevelCallOnce(absl::once_flag* flag, Callable&& fn, Args&&... args); + +// Disables scheduling while on stack when scheduling mode is non-cooperative. +// No effect for cooperative scheduling modes. +class SchedulingHelper { + public: + explicit SchedulingHelper(base_internal::SchedulingMode mode) : mode_(mode) { + if (mode_ == base_internal::SCHEDULE_KERNEL_ONLY) { + guard_result_ = base_internal::SchedulingGuard::DisableRescheduling(); + } + } + + ~SchedulingHelper() { + if (mode_ == base_internal::SCHEDULE_KERNEL_ONLY) { + base_internal::SchedulingGuard::EnableRescheduling(guard_result_); + } + } + + private: + base_internal::SchedulingMode mode_; + bool guard_result_; +}; + +// Bit patterns for call_once state machine values. Internal implementation +// detail, not for use by clients. +// +// The bit patterns are arbitrarily chosen from unlikely values, to aid in +// debugging. However, kOnceInit must be 0, so that a zero-initialized +// once_flag will be valid for immediate use. +enum { + kOnceInit = 0, + kOnceRunning = 0x65C2937B, + kOnceWaiter = 0x05A308D2, + // A very small constant is chosen for kOnceDone so that it fit in a single + // compare with immediate instruction for most common ISAs. This is verified + // for x86, POWER and ARM. + kOnceDone = 221, // Random Number +}; + +template +void CallOnceImpl(std::atomic* control, + base_internal::SchedulingMode scheduling_mode, Callable&& fn, + Args&&... args) { +#ifndef NDEBUG + { + uint32_t old_control = control->load(std::memory_order_acquire); + if (old_control != kOnceInit && + old_control != kOnceRunning && + old_control != kOnceWaiter && + old_control != kOnceDone) { + ABSL_RAW_LOG( + FATAL, + "Unexpected value for control word: %lx. Either the control word " + "has non-static storage duration (where GoogleOnceDynamic might " + "be appropriate), or there's been a memory corruption.", + static_cast(old_control)); // NOLINT + } + } +#endif // NDEBUG + static const base_internal::SpinLockWaitTransition trans[] = { + {kOnceInit, kOnceRunning, true}, + {kOnceRunning, kOnceWaiter, false}, + {kOnceDone, kOnceDone, true}}; + + // Must do this before potentially modifying control word's state. + base_internal::SchedulingHelper maybe_disable_scheduling(scheduling_mode); + // Short circuit the simplest case to avoid procedure call overhead. + uint32_t old_control = kOnceInit; + if (control->compare_exchange_strong(old_control, kOnceRunning, + std::memory_order_acquire, + std::memory_order_relaxed) || + base_internal::SpinLockWait(control, ABSL_ARRAYSIZE(trans), trans, + scheduling_mode) == kOnceInit) { + base_internal::Invoke(std::forward(fn), + std::forward(args)...); + old_control = control->load(std::memory_order_relaxed); + control->store(base_internal::kOnceDone, std::memory_order_release); + if (old_control == base_internal::kOnceWaiter) { + base_internal::SpinLockWake(control, true); + } + } // else *control is already kOnceDone +} + +inline std::atomic* ControlWord(once_flag* flag) { + return &flag->control_; +} + +template +void LowLevelCallOnce(absl::once_flag* flag, Callable&& fn, Args&&... args) { + std::atomic* once = base_internal::ControlWord(flag); + uint32_t s = once->load(std::memory_order_acquire); + if (ABSL_PREDICT_FALSE(s != base_internal::kOnceDone)) { + base_internal::CallOnceImpl(once, base_internal::SCHEDULE_KERNEL_ONLY, + std::forward(fn), + std::forward(args)...); + } +} + +} // namespace base_internal + +template +void call_once(absl::once_flag& flag, Callable&& fn, Args&&... args) { + std::atomic* once = base_internal::ControlWord(&flag); + uint32_t s = once->load(std::memory_order_acquire); + if (ABSL_PREDICT_FALSE(s != base_internal::kOnceDone)) { + base_internal::CallOnceImpl( + once, base_internal::SCHEDULE_COOPERATIVE_AND_KERNEL, + std::forward(fn), std::forward(args)...); + } +} + +} // namespace absl + +#endif // ABSL_BASE_CALL_ONCE_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/call_once_test.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/call_once_test.cc new file mode 100644 index 0000000..cd58ee1 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/call_once_test.cc @@ -0,0 +1,102 @@ +// Copyright 2017 The Abseil Authors. +// +// 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 "absl/base/call_once.h" + +#include +#include + +#include "gtest/gtest.h" +#include "absl/base/thread_annotations.h" +#include "absl/synchronization/mutex.h" + +namespace absl { +namespace { + +absl::once_flag once; +Mutex counters_mu; + +int running_thread_count GUARDED_BY(counters_mu) = 0; +int call_once_invoke_count GUARDED_BY(counters_mu) = 0; +int call_once_finished_count GUARDED_BY(counters_mu) = 0; +int call_once_return_count GUARDED_BY(counters_mu) = 0; +bool done_blocking GUARDED_BY(counters_mu) = false; + +// Function to be called from absl::call_once. Waits for a notification. +void WaitAndIncrement() { + counters_mu.Lock(); + ++call_once_invoke_count; + counters_mu.Unlock(); + + counters_mu.LockWhen(Condition(&done_blocking)); + ++call_once_finished_count; + counters_mu.Unlock(); +} + +void ThreadBody() { + counters_mu.Lock(); + ++running_thread_count; + counters_mu.Unlock(); + + absl::call_once(once, WaitAndIncrement); + + counters_mu.Lock(); + ++call_once_return_count; + counters_mu.Unlock(); +} + +// Returns true if all threads are set up for the test. +bool ThreadsAreSetup(void*) EXCLUSIVE_LOCKS_REQUIRED(counters_mu) { + // All ten threads must be running, and WaitAndIncrement should be blocked. + return running_thread_count == 10 && call_once_invoke_count == 1; +} + +TEST(CallOnceTest, ExecutionCount) { + std::vector threads; + + // Start 10 threads all calling call_once on the same once_flag. + for (int i = 0; i < 10; ++i) { + threads.emplace_back(ThreadBody); + } + + + // Wait until all ten threads have started, and WaitAndIncrement has been + // invoked. + counters_mu.LockWhen(Condition(ThreadsAreSetup, nullptr)); + + // WaitAndIncrement should have been invoked by exactly one call_once() + // instance. That thread should be blocking on a notification, and all other + // call_once instances should be blocking as well. + EXPECT_EQ(call_once_invoke_count, 1); + EXPECT_EQ(call_once_finished_count, 0); + EXPECT_EQ(call_once_return_count, 0); + + // Allow WaitAndIncrement to finish executing. Once it does, the other + // call_once waiters will be unblocked. + done_blocking = true; + counters_mu.Unlock(); + + for (std::thread& thread : threads) { + thread.join(); + } + + counters_mu.Lock(); + EXPECT_EQ(call_once_invoke_count, 1); + EXPECT_EQ(call_once_finished_count, 1); + EXPECT_EQ(call_once_return_count, 10); + counters_mu.Unlock(); +} + +} // namespace +} // namespace absl diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/casts.h b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/casts.h new file mode 100644 index 0000000..1eef6a6 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/casts.h @@ -0,0 +1,189 @@ +// +// Copyright 2017 The Abseil Authors. +// +// 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. +// +// ----------------------------------------------------------------------------- +// File: casts.h +// ----------------------------------------------------------------------------- +// +// This header file defines casting templates to fit use cases not covered by +// the standard casts provided in the C++ standard. As with all cast operations, +// use these with caution and only if alternatives do not exist. + +#ifndef ABSL_BASE_CASTS_H_ +#define ABSL_BASE_CASTS_H_ + +#include +#include +#include + +#include "absl/base/internal/identity.h" +#include "absl/base/macros.h" + +namespace absl { + +namespace internal_casts { + +// NOTE: Not a fully compliant implementation of `std::is_trivially_copyable`. +// TODO(calabrese) Branch on implementations that directly provide +// `std::is_trivially_copyable`, create a more rigorous workaround, and publicly +// expose in meta/type_traits. +template +struct is_trivially_copyable + : std::integral_constant< + bool, std::is_destructible::value&& __has_trivial_destructor(T) && + __has_trivial_copy(T) && __has_trivial_assign(T)> {}; + +template +struct is_bitcastable + : std::integral_constant::value && + is_trivially_copyable::value && + std::is_default_constructible::value> {}; + +} // namespace internal_casts + +// implicit_cast() +// +// Performs an implicit conversion between types following the language +// rules for implicit conversion; if an implicit conversion is otherwise +// allowed by the language in the given context, this function performs such an +// implicit conversion. +// +// Example: +// +// // If the context allows implicit conversion: +// From from; +// To to = from; +// +// // Such code can be replaced by: +// implicit_cast(from); +// +// An `implicit_cast()` may also be used to annotate numeric type conversions +// that, although safe, may produce compiler warnings (such as `long` to `int`). +// Additionally, an `implicit_cast()` is also useful within return statements to +// indicate a specific implicit conversion is being undertaken. +// +// Example: +// +// return implicit_cast(size_in_bytes) / capacity_; +// +// Annotating code with `implicit_cast()` allows you to explicitly select +// particular overloads and template instantiations, while providing a safer +// cast than `reinterpret_cast()` or `static_cast()`. +// +// Additionally, an `implicit_cast()` can be used to allow upcasting within a +// type hierarchy where incorrect use of `static_cast()` could accidentally +// allow downcasting. +// +// Finally, an `implicit_cast()` can be used to perform implicit conversions +// from unrelated types that otherwise couldn't be implicitly cast directly; +// C++ will normally only implicitly cast "one step" in such conversions. +// +// That is, if C is a type which can be implicitly converted to B, with B being +// a type that can be implicitly converted to A, an `implicit_cast()` can be +// used to convert C to B (which the compiler can then implicitly convert to A +// using language rules). +// +// Example: +// +// // Assume an object C is convertible to B, which is implicitly convertible +// // to A +// A a = implicit_cast(C); +// +// Such implicit cast chaining may be useful within template logic. +template +constexpr To implicit_cast(typename absl::internal::identity_t to) { + return to; +} + +// bit_cast() +// +// Performs a bitwise cast on a type without changing the underlying bit +// representation of that type's value. The two types must be of the same size +// and both types must be trivially copyable. As with most casts, use with +// caution. A `bit_cast()` might be needed when you need to temporarily treat a +// type as some other type, such as in the following cases: +// +// * Serialization (casting temporarily to `char *` for those purposes is +// always allowed by the C++ standard) +// * Managing the individual bits of a type within mathematical operations +// that are not normally accessible through that type +// * Casting non-pointer types to pointer types (casting the other way is +// allowed by `reinterpret_cast()` but round-trips cannot occur the other +// way). +// +// Example: +// +// float f = 3.14159265358979; +// int i = bit_cast(f); +// // i = 0x40490fdb +// +// Casting non-pointer types to pointer types and then dereferencing them +// traditionally produces undefined behavior. +// +// Example: +// +// // WRONG +// float f = 3.14159265358979; // WRONG +// int i = * reinterpret_cast(&f); // WRONG +// +// The address-casting method produces undefined behavior according to the ISO +// C++ specification section [basic.lval]. Roughly, this section says: if an +// object in memory has one type, and a program accesses it with a different +// type, the result is undefined behavior for most values of "different type". +// +// Such casting results in type punning: holding an object in memory of one type +// and reading its bits back using a different type. A `bit_cast()` avoids this +// issue by implementing its casts using `memcpy()`, which avoids introducing +// this undefined behavior. +// +// NOTE: The requirements here are more strict than the bit_cast of standard +// proposal p0476 due to the need for workarounds and lack of intrinsics. +// Specifically, this implementation also requires `Dest` to be +// default-constructible. +template < + typename Dest, typename Source, + typename std::enable_if::value, + int>::type = 0> +inline Dest bit_cast(const Source& source) { + Dest dest; + memcpy(static_cast(std::addressof(dest)), + static_cast(std::addressof(source)), sizeof(dest)); + return dest; +} + +// NOTE: This overload is only picked if the requirements of bit_cast are not +// met. It is therefore UB, but is provided temporarily as previous versions of +// this function template were unchecked. Do not use this in new code. +template < + typename Dest, typename Source, + typename std::enable_if< + !internal_casts::is_bitcastable::value, int>::type = 0> +ABSL_DEPRECATED( + "absl::bit_cast type requirements were violated. Update the types being " + "used such that they are the same size and are both TriviallyCopyable.") +inline Dest bit_cast(const Source& source) { + static_assert(sizeof(Dest) == sizeof(Source), + "Source and destination types should have equal sizes."); + + Dest dest; + memcpy(&dest, &source, sizeof(dest)); + return dest; +} + +} // namespace absl + +#endif // ABSL_BASE_CASTS_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/config.h b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/config.h new file mode 100644 index 0000000..695bfff --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/config.h @@ -0,0 +1,432 @@ +// +// Copyright 2017 The Abseil Authors. +// +// 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. +// +// ----------------------------------------------------------------------------- +// File: config.h +// ----------------------------------------------------------------------------- +// +// This header file defines a set of macros for checking the presence of +// important compiler and platform features. Such macros can be used to +// produce portable code by parameterizing compilation based on the presence or +// lack of a given feature. +// +// We define a "feature" as some interface we wish to program to: for example, +// a library function or system call. A value of `1` indicates support for +// that feature; any other value indicates the feature support is undefined. +// +// Example: +// +// Suppose a programmer wants to write a program that uses the 'mmap()' system +// call. The Abseil macro for that feature (`ABSL_HAVE_MMAP`) allows you to +// selectively include the `mmap.h` header and bracket code using that feature +// in the macro: +// +// #include "absl/base/config.h" +// +// #ifdef ABSL_HAVE_MMAP +// #include "sys/mman.h" +// #endif //ABSL_HAVE_MMAP +// +// ... +// #ifdef ABSL_HAVE_MMAP +// void *ptr = mmap(...); +// ... +// #endif // ABSL_HAVE_MMAP + +#ifndef ABSL_BASE_CONFIG_H_ +#define ABSL_BASE_CONFIG_H_ + +// Included for the __GLIBC__ macro (or similar macros on other systems). +#include + +#ifdef __cplusplus +// Included for __GLIBCXX__, _LIBCPP_VERSION +#include +#endif // __cplusplus + +#if defined(__APPLE__) +// Included for TARGET_OS_IPHONE, __IPHONE_OS_VERSION_MIN_REQUIRED, +// __IPHONE_8_0. +#include +#include +#endif + +#include "absl/base/policy_checks.h" + +// ----------------------------------------------------------------------------- +// Compiler Feature Checks +// ----------------------------------------------------------------------------- + +// ABSL_HAVE_BUILTIN() +// +// Checks whether the compiler supports a Clang Feature Checking Macro, and if +// so, checks whether it supports the provided builtin function "x" where x +// is one of the functions noted in +// https://clang.llvm.org/docs/LanguageExtensions.html +// +// Note: Use this macro to avoid an extra level of #ifdef __has_builtin check. +// http://releases.llvm.org/3.3/tools/clang/docs/LanguageExtensions.html +#ifdef __has_builtin +#define ABSL_HAVE_BUILTIN(x) __has_builtin(x) +#else +#define ABSL_HAVE_BUILTIN(x) 0 +#endif + +// ABSL_HAVE_TLS is defined to 1 when __thread should be supported. +// We assume __thread is supported on Linux when compiled with Clang or compiled +// against libstdc++ with _GLIBCXX_HAVE_TLS defined. +#ifdef ABSL_HAVE_TLS +#error ABSL_HAVE_TLS cannot be directly set +#elif defined(__linux__) && (defined(__clang__) || defined(_GLIBCXX_HAVE_TLS)) +#define ABSL_HAVE_TLS 1 +#endif + +// ABSL_HAVE_STD_IS_TRIVIALLY_DESTRUCTIBLE +// +// Checks whether `std::is_trivially_destructible` is supported. +// +// Notes: All supported compilers using libc++ support this feature, as does +// gcc >= 4.8.1 using libstdc++, and Visual Studio. +#ifdef ABSL_HAVE_STD_IS_TRIVIALLY_DESTRUCTIBLE +#error ABSL_HAVE_STD_IS_TRIVIALLY_DESTRUCTIBLE cannot be directly set +#elif defined(_LIBCPP_VERSION) || \ + (!defined(__clang__) && defined(__GNUC__) && defined(__GLIBCXX__) && \ + (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8))) || \ + defined(_MSC_VER) +#define ABSL_HAVE_STD_IS_TRIVIALLY_DESTRUCTIBLE 1 +#endif + +// ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE +// +// Checks whether `std::is_trivially_default_constructible` and +// `std::is_trivially_copy_constructible` are supported. + +// ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE +// +// Checks whether `std::is_trivially_copy_assignable` is supported. + +// Notes: Clang with libc++ supports these features, as does gcc >= 5.1 with +// either libc++ or libstdc++, and Visual Studio. +#if defined(ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE) +#error ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE cannot be directly set +#elif defined(ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE) +#error ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE cannot directly set +#elif (defined(__clang__) && defined(_LIBCPP_VERSION)) || \ + (!defined(__clang__) && defined(__GNUC__) && \ + (__GNUC__ > 5 || (__GNUC__ == 5 && __GNUC_MINOR__ >= 1)) && \ + (defined(_LIBCPP_VERSION) || defined(__GLIBCXX__))) || \ + defined(_MSC_VER) +#define ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE 1 +#define ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE 1 +#endif + +// ABSL_HAVE_THREAD_LOCAL +// +// Checks whether C++11's `thread_local` storage duration specifier is +// supported. +#ifdef ABSL_HAVE_THREAD_LOCAL +#error ABSL_HAVE_THREAD_LOCAL cannot be directly set +#elif defined(__APPLE__) +// Notes: +// * Xcode's clang did not support `thread_local` until version 8, and +// even then not for all iOS < 9.0. +// * Xcode 9.3 started disallowing `thread_local` for 32-bit iOS simulator +// targeting iOS 9.x. +// * Xcode 10 moves the deployment target check for iOS < 9.0 to link time +// making __has_feature unreliable there. +// +// Otherwise, `__has_feature` is only supported by Clang so it has be inside +// `defined(__APPLE__)` check. +#if __has_feature(cxx_thread_local) && \ + !(TARGET_OS_IPHONE && __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_9_0) +#define ABSL_HAVE_THREAD_LOCAL 1 +#endif +#else // !defined(__APPLE__) +#define ABSL_HAVE_THREAD_LOCAL 1 +#endif + +// There are platforms for which TLS should not be used even though the compiler +// makes it seem like it's supported (Android NDK < r12b for example). +// This is primarily because of linker problems and toolchain misconfiguration: +// Abseil does not intend to support this indefinitely. Currently, the newest +// toolchain that we intend to support that requires this behavior is the +// r11 NDK - allowing for a 5 year support window on that means this option +// is likely to be removed around June of 2021. +// TLS isn't supported until NDK r12b per +// https://developer.android.com/ndk/downloads/revision_history.html +// Since NDK r16, `__NDK_MAJOR__` and `__NDK_MINOR__` are defined in +// . For NDK < r16, users should define these macros, +// e.g. `-D__NDK_MAJOR__=11 -D__NKD_MINOR__=0` for NDK r11. +#if defined(__ANDROID__) && defined(__clang__) +#if __has_include() +#include +#endif // __has_include() +#if defined(__ANDROID__) && defined(__clang__) && defined(__NDK_MAJOR__) && \ + defined(__NDK_MINOR__) && \ + ((__NDK_MAJOR__ < 12) || ((__NDK_MAJOR__ == 12) && (__NDK_MINOR__ < 1))) +#undef ABSL_HAVE_TLS +#undef ABSL_HAVE_THREAD_LOCAL +#endif +#endif // defined(__ANDROID__) && defined(__clang__) + +// ABSL_HAVE_INTRINSIC_INT128 +// +// Checks whether the __int128 compiler extension for a 128-bit integral type is +// supported. +// +// Note: __SIZEOF_INT128__ is defined by Clang and GCC when __int128 is +// supported, but we avoid using it in certain cases: +// * On Clang: +// * Building using Clang for Windows, where the Clang runtime library has +// 128-bit support only on LP64 architectures, but Windows is LLP64. +// * Building for aarch64, where __int128 exists but has exhibits a sporadic +// compiler crashing bug. +// * On Nvidia's nvcc: +// * nvcc also defines __GNUC__ and __SIZEOF_INT128__, but not all versions +// actually support __int128. +#ifdef ABSL_HAVE_INTRINSIC_INT128 +#error ABSL_HAVE_INTRINSIC_INT128 cannot be directly set +#elif defined(__SIZEOF_INT128__) +#if (defined(__clang__) && !defined(_WIN32) && !defined(__aarch64__)) || \ + (defined(__CUDACC__) && __CUDACC_VER_MAJOR__ >= 9) || \ + (defined(__GNUC__) && !defined(__clang__) && !defined(__CUDACC__)) +#define ABSL_HAVE_INTRINSIC_INT128 1 +#elif defined(__CUDACC__) +// __CUDACC_VER__ is a full version number before CUDA 9, and is defined to a +// string explaining that it has been removed starting with CUDA 9. We use +// nested #ifs because there is no short-circuiting in the preprocessor. +// NOTE: `__CUDACC__` could be undefined while `__CUDACC_VER__` is defined. +#if __CUDACC_VER__ >= 70000 +#define ABSL_HAVE_INTRINSIC_INT128 1 +#endif // __CUDACC_VER__ >= 70000 +#endif // defined(__CUDACC__) +#endif // ABSL_HAVE_INTRINSIC_INT128 + +// ABSL_HAVE_EXCEPTIONS +// +// Checks whether the compiler both supports and enables exceptions. Many +// compilers support a "no exceptions" mode that disables exceptions. +// +// Generally, when ABSL_HAVE_EXCEPTIONS is not defined: +// +// * Code using `throw` and `try` may not compile. +// * The `noexcept` specifier will still compile and behave as normal. +// * The `noexcept` operator may still return `false`. +// +// For further details, consult the compiler's documentation. +#ifdef ABSL_HAVE_EXCEPTIONS +#error ABSL_HAVE_EXCEPTIONS cannot be directly set. + +#elif defined(__clang__) +// TODO(calabrese) +// Switch to using __cpp_exceptions when we no longer support versions < 3.6. +// For details on this check, see: +// http://releases.llvm.org/3.6.0/tools/clang/docs/ReleaseNotes.html#the-exceptions-macro +#if defined(__EXCEPTIONS) && __has_feature(cxx_exceptions) +#define ABSL_HAVE_EXCEPTIONS 1 +#endif // defined(__EXCEPTIONS) && __has_feature(cxx_exceptions) + +// Handle remaining special cases and default to exceptions being supported. +#elif !(defined(__GNUC__) && (__GNUC__ < 5) && !defined(__EXCEPTIONS)) && \ + !(defined(__GNUC__) && (__GNUC__ >= 5) && !defined(__cpp_exceptions)) && \ + !(defined(_MSC_VER) && !defined(_CPPUNWIND)) +#define ABSL_HAVE_EXCEPTIONS 1 +#endif + +// ----------------------------------------------------------------------------- +// Platform Feature Checks +// ----------------------------------------------------------------------------- + +// Currently supported operating systems and associated preprocessor +// symbols: +// +// Linux and Linux-derived __linux__ +// Android __ANDROID__ (implies __linux__) +// Linux (non-Android) __linux__ && !__ANDROID__ +// Darwin (Mac OS X and iOS) __APPLE__ +// Akaros (http://akaros.org) __ros__ +// Windows _WIN32 +// NaCL __native_client__ +// AsmJS __asmjs__ +// WebAssembly __wasm__ +// Fuchsia __Fuchsia__ +// +// Note that since Android defines both __ANDROID__ and __linux__, one +// may probe for either Linux or Android by simply testing for __linux__. + +// ABSL_HAVE_MMAP +// +// Checks whether the platform has an mmap(2) implementation as defined in +// POSIX.1-2001. +#ifdef ABSL_HAVE_MMAP +#error ABSL_HAVE_MMAP cannot be directly set +#elif defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) || \ + defined(__ros__) || defined(__native_client__) || defined(__asmjs__) || \ + defined(__wasm__) || defined(__Fuchsia__) || defined(__sun) +#define ABSL_HAVE_MMAP 1 +#endif + +// ABSL_HAVE_PTHREAD_GETSCHEDPARAM +// +// Checks whether the platform implements the pthread_(get|set)schedparam(3) +// functions as defined in POSIX.1-2001. +#ifdef ABSL_HAVE_PTHREAD_GETSCHEDPARAM +#error ABSL_HAVE_PTHREAD_GETSCHEDPARAM cannot be directly set +#elif defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) || \ + defined(__ros__) +#define ABSL_HAVE_PTHREAD_GETSCHEDPARAM 1 +#endif + +// ABSL_HAVE_SCHED_YIELD +// +// Checks whether the platform implements sched_yield(2) as defined in +// POSIX.1-2001. +#ifdef ABSL_HAVE_SCHED_YIELD +#error ABSL_HAVE_SCHED_YIELD cannot be directly set +#elif defined(__linux__) || defined(__ros__) || defined(__native_client__) +#define ABSL_HAVE_SCHED_YIELD 1 +#endif + +// ABSL_HAVE_SEMAPHORE_H +// +// Checks whether the platform supports the header and sem_open(3) +// family of functions as standardized in POSIX.1-2001. +// +// Note: While Apple provides for both iOS and macOS, it is +// explicitly deprecated and will cause build failures if enabled for those +// platforms. We side-step the issue by not defining it here for Apple +// platforms. +#ifdef ABSL_HAVE_SEMAPHORE_H +#error ABSL_HAVE_SEMAPHORE_H cannot be directly set +#elif defined(__linux__) || defined(__ros__) +#define ABSL_HAVE_SEMAPHORE_H 1 +#endif + +// ABSL_HAVE_ALARM +// +// Checks whether the platform supports the header and alarm(2) +// function as standardized in POSIX.1-2001. +#ifdef ABSL_HAVE_ALARM +#error ABSL_HAVE_ALARM cannot be directly set +#elif defined(__GOOGLE_GRTE_VERSION__) +// feature tests for Google's GRTE +#define ABSL_HAVE_ALARM 1 +#elif defined(__GLIBC__) +// feature test for glibc +#define ABSL_HAVE_ALARM 1 +#elif defined(_MSC_VER) +// feature tests for Microsoft's library +#elif defined(__native_client__) +#else +// other standard libraries +#define ABSL_HAVE_ALARM 1 +#endif + +// ABSL_IS_LITTLE_ENDIAN +// ABSL_IS_BIG_ENDIAN +// +// Checks the endianness of the platform. +// +// Notes: uses the built in endian macros provided by GCC (since 4.6) and +// Clang (since 3.2); see +// https://gcc.gnu.org/onlinedocs/cpp/Common-Predefined-Macros.html. +// Otherwise, if _WIN32, assume little endian. Otherwise, bail with an error. +#if defined(ABSL_IS_BIG_ENDIAN) +#error "ABSL_IS_BIG_ENDIAN cannot be directly set." +#endif +#if defined(ABSL_IS_LITTLE_ENDIAN) +#error "ABSL_IS_LITTLE_ENDIAN cannot be directly set." +#endif + +#if (defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && \ + __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) +#define ABSL_IS_LITTLE_ENDIAN 1 +#elif defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && \ + __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ +#define ABSL_IS_BIG_ENDIAN 1 +#elif defined(_WIN32) +#define ABSL_IS_LITTLE_ENDIAN 1 +#else +#error "absl endian detection needs to be set up for your compiler" +#endif + +// ABSL_HAVE_STD_ANY +// +// Checks whether C++17 std::any is available by checking whether exists. +#ifdef ABSL_HAVE_STD_ANY +#error "ABSL_HAVE_STD_ANY cannot be directly set." +#endif + +#ifdef __has_include +#if __has_include() && __cplusplus >= 201703L +#define ABSL_HAVE_STD_ANY 1 +#endif +#endif + +// ABSL_HAVE_STD_OPTIONAL +// +// Checks whether C++17 std::optional is available. +#ifdef ABSL_HAVE_STD_OPTIONAL +#error "ABSL_HAVE_STD_OPTIONAL cannot be directly set." +#endif + +#ifdef __has_include +#if __has_include() && __cplusplus >= 201703L +#define ABSL_HAVE_STD_OPTIONAL 1 +#endif +#endif + +// ABSL_HAVE_STD_VARIANT +// +// Checks whether C++17 std::variant is available. +#ifdef ABSL_HAVE_STD_VARIANT +#error "ABSL_HAVE_STD_VARIANT cannot be directly set." +#endif + +#ifdef __has_include +#if __has_include() && __cplusplus >= 201703L +#define ABSL_HAVE_STD_VARIANT 1 +#endif +#endif + +// ABSL_HAVE_STD_STRING_VIEW +// +// Checks whether C++17 std::string_view is available. +#ifdef ABSL_HAVE_STD_STRING_VIEW +#error "ABSL_HAVE_STD_STRING_VIEW cannot be directly set." +#endif + +#ifdef __has_include +#if __has_include() && __cplusplus >= 201703L +#define ABSL_HAVE_STD_STRING_VIEW 1 +#endif +#endif + +// For MSVC, `__has_include` is supported in VS 2017 15.3, which is later than +// the support for , , , . So we use +// _MSC_VER to check whether we have VS 2017 RTM (when , , +// , is implemented) or higher. Also, `__cplusplus` is +// not correctly set by MSVC, so we use `_MSVC_LANG` to check the language +// version. +// TODO(zhangxy): fix tests before enabling aliasing for `std::any`. +#if defined(_MSC_VER) && _MSC_VER >= 1910 && \ + ((defined(_MSVC_LANG) && _MSVC_LANG > 201402) || __cplusplus > 201402) +// #define ABSL_HAVE_STD_ANY 1 +#define ABSL_HAVE_STD_OPTIONAL 1 +#define ABSL_HAVE_STD_VARIANT 1 +#define ABSL_HAVE_STD_STRING_VIEW 1 +#endif + +#endif // ABSL_BASE_CONFIG_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/config_test.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/config_test.cc new file mode 100644 index 0000000..c839712 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/config_test.cc @@ -0,0 +1,60 @@ +// Copyright 2017 The Abseil Authors. +// +// 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 "absl/base/config.h" + +#include + +#include "gtest/gtest.h" +#include "absl/synchronization/internal/thread_pool.h" + +namespace { + +TEST(ConfigTest, Endianness) { + union { + uint32_t value; + uint8_t data[sizeof(uint32_t)]; + } number; + number.data[0] = 0x00; + number.data[1] = 0x01; + number.data[2] = 0x02; + number.data[3] = 0x03; +#if defined(ABSL_IS_LITTLE_ENDIAN) && defined(ABSL_IS_BIG_ENDIAN) +#error Both ABSL_IS_LITTLE_ENDIAN and ABSL_IS_BIG_ENDIAN are defined +#elif defined(ABSL_IS_LITTLE_ENDIAN) + EXPECT_EQ(UINT32_C(0x03020100), number.value); +#elif defined(ABSL_IS_BIG_ENDIAN) + EXPECT_EQ(UINT32_C(0x00010203), number.value); +#else +#error Unknown endianness +#endif +} + +#if defined(ABSL_HAVE_THREAD_LOCAL) +TEST(ConfigTest, ThreadLocal) { + static thread_local int mine_mine_mine = 16; + EXPECT_EQ(16, mine_mine_mine); + { + absl::synchronization_internal::ThreadPool pool(1); + pool.Schedule([&] { + EXPECT_EQ(16, mine_mine_mine); + mine_mine_mine = 32; + EXPECT_EQ(32, mine_mine_mine); + }); + } + EXPECT_EQ(16, mine_mine_mine); +} +#endif + +} // namespace diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/dynamic_annotations.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/dynamic_annotations.cc new file mode 100644 index 0000000..08c27e5 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/dynamic_annotations.cc @@ -0,0 +1,129 @@ +// Copyright 2017 The Abseil Authors. +// +// 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 +#include + +#include "absl/base/dynamic_annotations.h" + +#ifndef __has_feature +#define __has_feature(x) 0 +#endif + +/* Compiler-based ThreadSanitizer defines + DYNAMIC_ANNOTATIONS_EXTERNAL_IMPL = 1 + and provides its own definitions of the functions. */ + +#ifndef DYNAMIC_ANNOTATIONS_EXTERNAL_IMPL +# define DYNAMIC_ANNOTATIONS_EXTERNAL_IMPL 0 +#endif + +/* Each function is empty and called (via a macro) only in debug mode. + The arguments are captured by dynamic tools at runtime. */ + +#if DYNAMIC_ANNOTATIONS_EXTERNAL_IMPL == 0 && !defined(__native_client__) + +#if __has_feature(memory_sanitizer) +#include +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +void AnnotateRWLockCreate(const char *, int, + const volatile void *){} +void AnnotateRWLockDestroy(const char *, int, + const volatile void *){} +void AnnotateRWLockAcquired(const char *, int, + const volatile void *, long){} +void AnnotateRWLockReleased(const char *, int, + const volatile void *, long){} +void AnnotateBenignRace(const char *, int, + const volatile void *, + const char *){} +void AnnotateBenignRaceSized(const char *, int, + const volatile void *, + size_t, + const char *) {} +void AnnotateThreadName(const char *, int, + const char *){} +void AnnotateIgnoreReadsBegin(const char *, int){} +void AnnotateIgnoreReadsEnd(const char *, int){} +void AnnotateIgnoreWritesBegin(const char *, int){} +void AnnotateIgnoreWritesEnd(const char *, int){} +void AnnotateEnableRaceDetection(const char *, int, int){} +void AnnotateMemoryIsInitialized(const char *, int, + const volatile void *mem, size_t size) { +#if __has_feature(memory_sanitizer) + __msan_unpoison(mem, size); +#else + (void)mem; + (void)size; +#endif +} + +void AnnotateMemoryIsUninitialized(const char *, int, + const volatile void *mem, size_t size) { +#if __has_feature(memory_sanitizer) + __msan_allocated_memory(mem, size); +#else + (void)mem; + (void)size; +#endif +} + +static int GetRunningOnValgrind(void) { +#ifdef RUNNING_ON_VALGRIND + if (RUNNING_ON_VALGRIND) return 1; +#endif + char *running_on_valgrind_str = getenv("RUNNING_ON_VALGRIND"); + if (running_on_valgrind_str) { + return strcmp(running_on_valgrind_str, "0") != 0; + } + return 0; +} + +/* See the comments in dynamic_annotations.h */ +int RunningOnValgrind(void) { + static volatile int running_on_valgrind = -1; + int local_running_on_valgrind = running_on_valgrind; + /* C doesn't have thread-safe initialization of statics, and we + don't want to depend on pthread_once here, so hack it. */ + ANNOTATE_BENIGN_RACE(&running_on_valgrind, "safe hack"); + if (local_running_on_valgrind == -1) + running_on_valgrind = local_running_on_valgrind = GetRunningOnValgrind(); + return local_running_on_valgrind; +} + +/* See the comments in dynamic_annotations.h */ +double ValgrindSlowdown(void) { + /* Same initialization hack as in RunningOnValgrind(). */ + static volatile double slowdown = 0.0; + double local_slowdown = slowdown; + ANNOTATE_BENIGN_RACE(&slowdown, "safe hack"); + if (RunningOnValgrind() == 0) { + return 1.0; + } + if (local_slowdown == 0.0) { + char *env = getenv("VALGRIND_SLOWDOWN"); + slowdown = local_slowdown = env ? atof(env) : 50.0; + } + return local_slowdown; +} + +#ifdef __cplusplus +} // extern "C" +#endif +#endif /* DYNAMIC_ANNOTATIONS_EXTERNAL_IMPL == 0 */ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/dynamic_annotations.h b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/dynamic_annotations.h new file mode 100644 index 0000000..7e328d9 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/dynamic_annotations.h @@ -0,0 +1,388 @@ +/* + * Copyright 2017 The Abseil Authors. + * + * 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. + */ +/* This file defines dynamic annotations for use with dynamic analysis + tool such as valgrind, PIN, etc. + + Dynamic annotation is a source code annotation that affects + the generated code (that is, the annotation is not a comment). + Each such annotation is attached to a particular + instruction and/or to a particular object (address) in the program. + + The annotations that should be used by users are macros in all upper-case + (e.g., ANNOTATE_THREAD_NAME). + + Actual implementation of these macros may differ depending on the + dynamic analysis tool being used. + + This file supports the following configurations: + - Dynamic Annotations enabled (with static thread-safety warnings disabled). + In this case, macros expand to functions implemented by Thread Sanitizer, + when building with TSan. When not provided an external implementation, + dynamic_annotations.cc provides no-op implementations. + + - Static Clang thread-safety warnings enabled. + When building with a Clang compiler that supports thread-safety warnings, + a subset of annotations can be statically-checked at compile-time. We + expand these macros to static-inline functions that can be analyzed for + thread-safety, but afterwards elided when building the final binary. + + - All annotations are disabled. + If neither Dynamic Annotations nor Clang thread-safety warnings are + enabled, then all annotation-macros expand to empty. */ + +#ifndef ABSL_BASE_DYNAMIC_ANNOTATIONS_H_ +#define ABSL_BASE_DYNAMIC_ANNOTATIONS_H_ + +#ifndef DYNAMIC_ANNOTATIONS_ENABLED +# define DYNAMIC_ANNOTATIONS_ENABLED 0 +#endif + +#if DYNAMIC_ANNOTATIONS_ENABLED != 0 + + /* ------------------------------------------------------------- + Annotations that suppress errors. It is usually better to express the + program's synchronization using the other annotations, but these can + be used when all else fails. */ + + /* Report that we may have a benign race at "pointer", with size + "sizeof(*(pointer))". "pointer" must be a non-void* pointer. Insert at the + point where "pointer" has been allocated, preferably close to the point + where the race happens. See also ANNOTATE_BENIGN_RACE_STATIC. */ + #define ANNOTATE_BENIGN_RACE(pointer, description) \ + AnnotateBenignRaceSized(__FILE__, __LINE__, pointer, \ + sizeof(*(pointer)), description) + + /* Same as ANNOTATE_BENIGN_RACE(address, description), but applies to + the memory range [address, address+size). */ + #define ANNOTATE_BENIGN_RACE_SIZED(address, size, description) \ + AnnotateBenignRaceSized(__FILE__, __LINE__, address, size, description) + + /* Enable (enable!=0) or disable (enable==0) race detection for all threads. + This annotation could be useful if you want to skip expensive race analysis + during some period of program execution, e.g. during initialization. */ + #define ANNOTATE_ENABLE_RACE_DETECTION(enable) \ + AnnotateEnableRaceDetection(__FILE__, __LINE__, enable) + + /* ------------------------------------------------------------- + Annotations useful for debugging. */ + + /* Report the current thread name to a race detector. */ + #define ANNOTATE_THREAD_NAME(name) \ + AnnotateThreadName(__FILE__, __LINE__, name) + + /* ------------------------------------------------------------- + Annotations useful when implementing locks. They are not + normally needed by modules that merely use locks. + The "lock" argument is a pointer to the lock object. */ + + /* Report that a lock has been created at address "lock". */ + #define ANNOTATE_RWLOCK_CREATE(lock) \ + AnnotateRWLockCreate(__FILE__, __LINE__, lock) + + /* Report that a linker initialized lock has been created at address "lock". + */ +#ifdef THREAD_SANITIZER + #define ANNOTATE_RWLOCK_CREATE_STATIC(lock) \ + AnnotateRWLockCreateStatic(__FILE__, __LINE__, lock) +#else + #define ANNOTATE_RWLOCK_CREATE_STATIC(lock) ANNOTATE_RWLOCK_CREATE(lock) +#endif + + /* Report that the lock at address "lock" is about to be destroyed. */ + #define ANNOTATE_RWLOCK_DESTROY(lock) \ + AnnotateRWLockDestroy(__FILE__, __LINE__, lock) + + /* Report that the lock at address "lock" has been acquired. + is_w=1 for writer lock, is_w=0 for reader lock. */ + #define ANNOTATE_RWLOCK_ACQUIRED(lock, is_w) \ + AnnotateRWLockAcquired(__FILE__, __LINE__, lock, is_w) + + /* Report that the lock at address "lock" is about to be released. */ + #define ANNOTATE_RWLOCK_RELEASED(lock, is_w) \ + AnnotateRWLockReleased(__FILE__, __LINE__, lock, is_w) + +#else /* DYNAMIC_ANNOTATIONS_ENABLED == 0 */ + + #define ANNOTATE_RWLOCK_CREATE(lock) /* empty */ + #define ANNOTATE_RWLOCK_CREATE_STATIC(lock) /* empty */ + #define ANNOTATE_RWLOCK_DESTROY(lock) /* empty */ + #define ANNOTATE_RWLOCK_ACQUIRED(lock, is_w) /* empty */ + #define ANNOTATE_RWLOCK_RELEASED(lock, is_w) /* empty */ + #define ANNOTATE_BENIGN_RACE(address, description) /* empty */ + #define ANNOTATE_BENIGN_RACE_SIZED(address, size, description) /* empty */ + #define ANNOTATE_THREAD_NAME(name) /* empty */ + #define ANNOTATE_ENABLE_RACE_DETECTION(enable) /* empty */ + +#endif /* DYNAMIC_ANNOTATIONS_ENABLED */ + +/* These annotations are also made available to LLVM's Memory Sanitizer */ +#if DYNAMIC_ANNOTATIONS_ENABLED == 1 || defined(MEMORY_SANITIZER) + #define ANNOTATE_MEMORY_IS_INITIALIZED(address, size) \ + AnnotateMemoryIsInitialized(__FILE__, __LINE__, address, size) + + #define ANNOTATE_MEMORY_IS_UNINITIALIZED(address, size) \ + AnnotateMemoryIsUninitialized(__FILE__, __LINE__, address, size) +#else + #define ANNOTATE_MEMORY_IS_INITIALIZED(address, size) /* empty */ + #define ANNOTATE_MEMORY_IS_UNINITIALIZED(address, size) /* empty */ +#endif /* DYNAMIC_ANNOTATIONS_ENABLED || MEMORY_SANITIZER */ +/* TODO(delesley) -- Replace __CLANG_SUPPORT_DYN_ANNOTATION__ with the + appropriate feature ID. */ +#if defined(__clang__) && (!defined(SWIG)) \ + && defined(__CLANG_SUPPORT_DYN_ANNOTATION__) + + #if DYNAMIC_ANNOTATIONS_ENABLED == 0 + #define ANNOTALYSIS_ENABLED + #endif + + /* When running in opt-mode, GCC will issue a warning, if these attributes are + compiled. Only include them when compiling using Clang. */ + #define ATTRIBUTE_IGNORE_READS_BEGIN \ + __attribute((exclusive_lock_function("*"))) + #define ATTRIBUTE_IGNORE_READS_END \ + __attribute((unlock_function("*"))) +#else + #define ATTRIBUTE_IGNORE_READS_BEGIN /* empty */ + #define ATTRIBUTE_IGNORE_READS_END /* empty */ +#endif /* defined(__clang__) && ... */ + +#if (DYNAMIC_ANNOTATIONS_ENABLED != 0) || defined(ANNOTALYSIS_ENABLED) + #define ANNOTATIONS_ENABLED +#endif + +#if (DYNAMIC_ANNOTATIONS_ENABLED != 0) + + /* Request the analysis tool to ignore all reads in the current thread + until ANNOTATE_IGNORE_READS_END is called. + Useful to ignore intentional racey reads, while still checking + other reads and all writes. + See also ANNOTATE_UNPROTECTED_READ. */ + #define ANNOTATE_IGNORE_READS_BEGIN() \ + AnnotateIgnoreReadsBegin(__FILE__, __LINE__) + + /* Stop ignoring reads. */ + #define ANNOTATE_IGNORE_READS_END() \ + AnnotateIgnoreReadsEnd(__FILE__, __LINE__) + + /* Similar to ANNOTATE_IGNORE_READS_BEGIN, but ignore writes instead. */ + #define ANNOTATE_IGNORE_WRITES_BEGIN() \ + AnnotateIgnoreWritesBegin(__FILE__, __LINE__) + + /* Stop ignoring writes. */ + #define ANNOTATE_IGNORE_WRITES_END() \ + AnnotateIgnoreWritesEnd(__FILE__, __LINE__) + +/* Clang provides limited support for static thread-safety analysis + through a feature called Annotalysis. We configure macro-definitions + according to whether Annotalysis support is available. */ +#elif defined(ANNOTALYSIS_ENABLED) + + #define ANNOTATE_IGNORE_READS_BEGIN() \ + StaticAnnotateIgnoreReadsBegin(__FILE__, __LINE__) + + #define ANNOTATE_IGNORE_READS_END() \ + StaticAnnotateIgnoreReadsEnd(__FILE__, __LINE__) + + #define ANNOTATE_IGNORE_WRITES_BEGIN() \ + StaticAnnotateIgnoreWritesBegin(__FILE__, __LINE__) + + #define ANNOTATE_IGNORE_WRITES_END() \ + StaticAnnotateIgnoreWritesEnd(__FILE__, __LINE__) + +#else + #define ANNOTATE_IGNORE_READS_BEGIN() /* empty */ + #define ANNOTATE_IGNORE_READS_END() /* empty */ + #define ANNOTATE_IGNORE_WRITES_BEGIN() /* empty */ + #define ANNOTATE_IGNORE_WRITES_END() /* empty */ +#endif + +/* Implement the ANNOTATE_IGNORE_READS_AND_WRITES_* annotations using the more + primitive annotations defined above. */ +#if defined(ANNOTATIONS_ENABLED) + + /* Start ignoring all memory accesses (both reads and writes). */ + #define ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN() \ + do { \ + ANNOTATE_IGNORE_READS_BEGIN(); \ + ANNOTATE_IGNORE_WRITES_BEGIN(); \ + }while (0) + + /* Stop ignoring both reads and writes. */ + #define ANNOTATE_IGNORE_READS_AND_WRITES_END() \ + do { \ + ANNOTATE_IGNORE_WRITES_END(); \ + ANNOTATE_IGNORE_READS_END(); \ + }while (0) + +#else + #define ANNOTATE_IGNORE_READS_AND_WRITES_BEGIN() /* empty */ + #define ANNOTATE_IGNORE_READS_AND_WRITES_END() /* empty */ +#endif + +/* Use the macros above rather than using these functions directly. */ +#include +#ifdef __cplusplus +extern "C" { +#endif +void AnnotateRWLockCreate(const char *file, int line, + const volatile void *lock); +void AnnotateRWLockCreateStatic(const char *file, int line, + const volatile void *lock); +void AnnotateRWLockDestroy(const char *file, int line, + const volatile void *lock); +void AnnotateRWLockAcquired(const char *file, int line, + const volatile void *lock, long is_w); /* NOLINT */ +void AnnotateRWLockReleased(const char *file, int line, + const volatile void *lock, long is_w); /* NOLINT */ +void AnnotateBenignRace(const char *file, int line, + const volatile void *address, + const char *description); +void AnnotateBenignRaceSized(const char *file, int line, + const volatile void *address, + size_t size, + const char *description); +void AnnotateThreadName(const char *file, int line, + const char *name); +void AnnotateEnableRaceDetection(const char *file, int line, int enable); +void AnnotateMemoryIsInitialized(const char *file, int line, + const volatile void *mem, size_t size); +void AnnotateMemoryIsUninitialized(const char *file, int line, + const volatile void *mem, size_t size); + +/* Annotations expand to these functions, when Dynamic Annotations are enabled. + These functions are either implemented as no-op calls, if no Sanitizer is + attached, or provided with externally-linked implementations by a library + like ThreadSanitizer. */ +void AnnotateIgnoreReadsBegin(const char *file, int line) + ATTRIBUTE_IGNORE_READS_BEGIN; +void AnnotateIgnoreReadsEnd(const char *file, int line) + ATTRIBUTE_IGNORE_READS_END; +void AnnotateIgnoreWritesBegin(const char *file, int line); +void AnnotateIgnoreWritesEnd(const char *file, int line); + +#if defined(ANNOTALYSIS_ENABLED) +/* When Annotalysis is enabled without Dynamic Annotations, the use of + static-inline functions allows the annotations to be read at compile-time, + while still letting the compiler elide the functions from the final build. + + TODO(delesley) -- The exclusive lock here ignores writes as well, but + allows IGNORE_READS_AND_WRITES to work properly. */ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-function" +static inline void StaticAnnotateIgnoreReadsBegin(const char *file, int line) + ATTRIBUTE_IGNORE_READS_BEGIN { (void)file; (void)line; } +static inline void StaticAnnotateIgnoreReadsEnd(const char *file, int line) + ATTRIBUTE_IGNORE_READS_END { (void)file; (void)line; } +static inline void StaticAnnotateIgnoreWritesBegin( + const char *file, int line) { (void)file; (void)line; } +static inline void StaticAnnotateIgnoreWritesEnd( + const char *file, int line) { (void)file; (void)line; } +#pragma GCC diagnostic pop +#endif + +/* Return non-zero value if running under valgrind. + + If "valgrind.h" is included into dynamic_annotations.cc, + the regular valgrind mechanism will be used. + See http://valgrind.org/docs/manual/manual-core-adv.html about + RUNNING_ON_VALGRIND and other valgrind "client requests". + The file "valgrind.h" may be obtained by doing + svn co svn://svn.valgrind.org/valgrind/trunk/include + + If for some reason you can't use "valgrind.h" or want to fake valgrind, + there are two ways to make this function return non-zero: + - Use environment variable: export RUNNING_ON_VALGRIND=1 + - Make your tool intercept the function RunningOnValgrind() and + change its return value. + */ +int RunningOnValgrind(void); + +/* ValgrindSlowdown returns: + * 1.0, if (RunningOnValgrind() == 0) + * 50.0, if (RunningOnValgrind() != 0 && getenv("VALGRIND_SLOWDOWN") == NULL) + * atof(getenv("VALGRIND_SLOWDOWN")) otherwise + This function can be used to scale timeout values: + EXAMPLE: + for (;;) { + DoExpensiveBackgroundTask(); + SleepForSeconds(5 * ValgrindSlowdown()); + } + */ +double ValgrindSlowdown(void); + +#ifdef __cplusplus +} +#endif + +/* ANNOTATE_UNPROTECTED_READ is the preferred way to annotate racey reads. + + Instead of doing + ANNOTATE_IGNORE_READS_BEGIN(); + ... = x; + ANNOTATE_IGNORE_READS_END(); + one can use + ... = ANNOTATE_UNPROTECTED_READ(x); */ +#if defined(__cplusplus) && defined(ANNOTATIONS_ENABLED) +template +inline T ANNOTATE_UNPROTECTED_READ(const volatile T &x) { /* NOLINT */ + ANNOTATE_IGNORE_READS_BEGIN(); + T res = x; + ANNOTATE_IGNORE_READS_END(); + return res; + } +#else + #define ANNOTATE_UNPROTECTED_READ(x) (x) +#endif + +#if DYNAMIC_ANNOTATIONS_ENABLED != 0 && defined(__cplusplus) + /* Apply ANNOTATE_BENIGN_RACE_SIZED to a static variable. */ + #define ANNOTATE_BENIGN_RACE_STATIC(static_var, description) \ + namespace { \ + class static_var ## _annotator { \ + public: \ + static_var ## _annotator() { \ + ANNOTATE_BENIGN_RACE_SIZED(&static_var, \ + sizeof(static_var), \ + # static_var ": " description); \ + } \ + }; \ + static static_var ## _annotator the ## static_var ## _annotator;\ + } // namespace +#else /* DYNAMIC_ANNOTATIONS_ENABLED == 0 */ + #define ANNOTATE_BENIGN_RACE_STATIC(static_var, description) /* empty */ +#endif /* DYNAMIC_ANNOTATIONS_ENABLED */ + +#ifdef ADDRESS_SANITIZER +/* Describe the current state of a contiguous container such as e.g. + * std::vector or std::string. For more details see + * sanitizer/common_interface_defs.h, which is provided by the compiler. */ +#include +#define ANNOTATE_CONTIGUOUS_CONTAINER(beg, end, old_mid, new_mid) \ + __sanitizer_annotate_contiguous_container(beg, end, old_mid, new_mid) +#define ADDRESS_SANITIZER_REDZONE(name) \ + struct { char x[8] __attribute__ ((aligned (8))); } name +#else +#define ANNOTATE_CONTIGUOUS_CONTAINER(beg, end, old_mid, new_mid) +#define ADDRESS_SANITIZER_REDZONE(name) +#endif // ADDRESS_SANITIZER + +/* Undefine the macros intended only in this file. */ +#undef ANNOTALYSIS_ENABLED +#undef ANNOTATIONS_ENABLED +#undef ATTRIBUTE_IGNORE_READS_BEGIN +#undef ATTRIBUTE_IGNORE_READS_END + +#endif /* ABSL_BASE_DYNAMIC_ANNOTATIONS_H_ */ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/exception_safety_testing_test.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/exception_safety_testing_test.cc new file mode 100644 index 0000000..7518264 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/exception_safety_testing_test.cc @@ -0,0 +1,954 @@ +// Copyright 2017 The Abseil Authors. +// +// 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 "absl/base/internal/exception_safety_testing.h" + +#include +#include +#include +#include +#include +#include + +#include "gtest/gtest-spi.h" +#include "gtest/gtest.h" +#include "absl/memory/memory.h" + +namespace testing { + +namespace { + +using ::testing::exceptions_internal::SetCountdown; +using ::testing::exceptions_internal::TestException; +using ::testing::exceptions_internal::UnsetCountdown; + +// EXPECT_NO_THROW can't inspect the thrown inspection in general. +template +void ExpectNoThrow(const F& f) { + try { + f(); + } catch (const TestException& e) { + ADD_FAILURE() << "Unexpected exception thrown from " << e.what(); + } +} + +TEST(ThrowingValueTest, Throws) { + SetCountdown(); + EXPECT_THROW(ThrowingValue<> bomb, TestException); + + // It's not guaranteed that every operator only throws *once*. The default + // ctor only throws once, though, so use it to make sure we only throw when + // the countdown hits 0 + SetCountdown(2); + ExpectNoThrow([]() { ThrowingValue<> bomb; }); + ExpectNoThrow([]() { ThrowingValue<> bomb; }); + EXPECT_THROW(ThrowingValue<> bomb, TestException); + + UnsetCountdown(); +} + +// Tests that an operation throws when the countdown is at 0, doesn't throw when +// the countdown doesn't hit 0, and doesn't modify the state of the +// ThrowingValue if it throws +template +void TestOp(const F& f) { + ExpectNoThrow(f); + + SetCountdown(); + EXPECT_THROW(f(), TestException); + UnsetCountdown(); +} + +TEST(ThrowingValueTest, ThrowingCtors) { + ThrowingValue<> bomb; + + TestOp([]() { ThrowingValue<> bomb(1); }); + TestOp([&]() { ThrowingValue<> bomb1 = bomb; }); + TestOp([&]() { ThrowingValue<> bomb1 = std::move(bomb); }); +} + +TEST(ThrowingValueTest, ThrowingAssignment) { + ThrowingValue<> bomb, bomb1; + + TestOp([&]() { bomb = bomb1; }); + TestOp([&]() { bomb = std::move(bomb1); }); + + // Test that when assignment throws, the assignment should fail (lhs != rhs) + // and strong guarantee fails (lhs != lhs_copy). + { + ThrowingValue<> lhs(39), rhs(42); + ThrowingValue<> lhs_copy(lhs); + SetCountdown(); + EXPECT_THROW(lhs = rhs, TestException); + UnsetCountdown(); + EXPECT_NE(lhs, rhs); + EXPECT_NE(lhs_copy, lhs); + } + { + ThrowingValue<> lhs(39), rhs(42); + ThrowingValue<> lhs_copy(lhs), rhs_copy(rhs); + SetCountdown(); + EXPECT_THROW(lhs = std::move(rhs), TestException); + UnsetCountdown(); + EXPECT_NE(lhs, rhs_copy); + EXPECT_NE(lhs_copy, lhs); + } +} + +TEST(ThrowingValueTest, ThrowingComparisons) { + ThrowingValue<> bomb1, bomb2; + TestOp([&]() { return bomb1 == bomb2; }); + TestOp([&]() { return bomb1 != bomb2; }); + TestOp([&]() { return bomb1 < bomb2; }); + TestOp([&]() { return bomb1 <= bomb2; }); + TestOp([&]() { return bomb1 > bomb2; }); + TestOp([&]() { return bomb1 >= bomb2; }); +} + +TEST(ThrowingValueTest, ThrowingArithmeticOps) { + ThrowingValue<> bomb1(1), bomb2(2); + + TestOp([&bomb1]() { +bomb1; }); + TestOp([&bomb1]() { -bomb1; }); + TestOp([&bomb1]() { ++bomb1; }); + TestOp([&bomb1]() { bomb1++; }); + TestOp([&bomb1]() { --bomb1; }); + TestOp([&bomb1]() { bomb1--; }); + + TestOp([&]() { bomb1 + bomb2; }); + TestOp([&]() { bomb1 - bomb2; }); + TestOp([&]() { bomb1* bomb2; }); + TestOp([&]() { bomb1 / bomb2; }); + TestOp([&]() { bomb1 << 1; }); + TestOp([&]() { bomb1 >> 1; }); +} + +TEST(ThrowingValueTest, ThrowingLogicalOps) { + ThrowingValue<> bomb1, bomb2; + + TestOp([&bomb1]() { !bomb1; }); + TestOp([&]() { bomb1&& bomb2; }); + TestOp([&]() { bomb1 || bomb2; }); +} + +TEST(ThrowingValueTest, ThrowingBitwiseOps) { + ThrowingValue<> bomb1, bomb2; + + TestOp([&bomb1]() { ~bomb1; }); + TestOp([&]() { bomb1& bomb2; }); + TestOp([&]() { bomb1 | bomb2; }); + TestOp([&]() { bomb1 ^ bomb2; }); +} + +TEST(ThrowingValueTest, ThrowingCompoundAssignmentOps) { + ThrowingValue<> bomb1(1), bomb2(2); + + TestOp([&]() { bomb1 += bomb2; }); + TestOp([&]() { bomb1 -= bomb2; }); + TestOp([&]() { bomb1 *= bomb2; }); + TestOp([&]() { bomb1 /= bomb2; }); + TestOp([&]() { bomb1 %= bomb2; }); + TestOp([&]() { bomb1 &= bomb2; }); + TestOp([&]() { bomb1 |= bomb2; }); + TestOp([&]() { bomb1 ^= bomb2; }); + TestOp([&]() { bomb1 *= bomb2; }); +} + +TEST(ThrowingValueTest, ThrowingStreamOps) { + ThrowingValue<> bomb; + + TestOp([&]() { + std::istringstream stream; + stream >> bomb; + }); + TestOp([&]() { + std::stringstream stream; + stream << bomb; + }); +} + +// Tests the operator<< of ThrowingValue by forcing ConstructorTracker to emit +// a nonfatal failure that contains the string representation of the Thrower +TEST(ThrowingValueTest, StreamOpsOutput) { + using ::testing::TypeSpec; + exceptions_internal::ConstructorTracker ct(exceptions_internal::countdown); + + // Test default spec list (kEverythingThrows) + EXPECT_NONFATAL_FAILURE( + { + using Thrower = ThrowingValue; + auto thrower = Thrower(123); + thrower.~Thrower(); + }, + "ThrowingValue<>(123)"); + + // Test with one item in spec list (kNoThrowCopy) + EXPECT_NONFATAL_FAILURE( + { + using Thrower = ThrowingValue; + auto thrower = Thrower(234); + thrower.~Thrower(); + }, + "ThrowingValue(234)"); + + // Test with multiple items in spec list (kNoThrowMove, kNoThrowNew) + EXPECT_NONFATAL_FAILURE( + { + using Thrower = + ThrowingValue; + auto thrower = Thrower(345); + thrower.~Thrower(); + }, + "ThrowingValue(345)"); + + // Test with all items in spec list (kNoThrowCopy, kNoThrowMove, kNoThrowNew) + EXPECT_NONFATAL_FAILURE( + { + using Thrower = ThrowingValue(-1)>; + auto thrower = Thrower(456); + thrower.~Thrower(); + }, + "ThrowingValue(456)"); +} + +template +void TestAllocatingOp(const F& f) { + ExpectNoThrow(f); + + SetCountdown(); + EXPECT_THROW(f(), exceptions_internal::TestBadAllocException); + UnsetCountdown(); +} + +TEST(ThrowingValueTest, ThrowingAllocatingOps) { + // make_unique calls unqualified operator new, so these exercise the + // ThrowingValue overloads. + TestAllocatingOp([]() { return absl::make_unique>(1); }); + TestAllocatingOp([]() { return absl::make_unique[]>(2); }); +} + +TEST(ThrowingValueTest, NonThrowingMoveCtor) { + ThrowingValue nothrow_ctor; + + SetCountdown(); + ExpectNoThrow([¬hrow_ctor]() { + ThrowingValue nothrow1 = std::move(nothrow_ctor); + }); + UnsetCountdown(); +} + +TEST(ThrowingValueTest, NonThrowingMoveAssign) { + ThrowingValue nothrow_assign1, nothrow_assign2; + + SetCountdown(); + ExpectNoThrow([¬hrow_assign1, ¬hrow_assign2]() { + nothrow_assign1 = std::move(nothrow_assign2); + }); + UnsetCountdown(); +} + +TEST(ThrowingValueTest, ThrowingCopyCtor) { + ThrowingValue<> tv; + + TestOp([&]() { ThrowingValue<> tv_copy(tv); }); +} + +TEST(ThrowingValueTest, ThrowingCopyAssign) { + ThrowingValue<> tv1, tv2; + + TestOp([&]() { tv1 = tv2; }); +} + +TEST(ThrowingValueTest, NonThrowingCopyCtor) { + ThrowingValue nothrow_ctor; + + SetCountdown(); + ExpectNoThrow([¬hrow_ctor]() { + ThrowingValue nothrow1(nothrow_ctor); + }); + UnsetCountdown(); +} + +TEST(ThrowingValueTest, NonThrowingCopyAssign) { + ThrowingValue nothrow_assign1, nothrow_assign2; + + SetCountdown(); + ExpectNoThrow([¬hrow_assign1, ¬hrow_assign2]() { + nothrow_assign1 = nothrow_assign2; + }); + UnsetCountdown(); +} + +TEST(ThrowingValueTest, ThrowingSwap) { + ThrowingValue<> bomb1, bomb2; + TestOp([&]() { std::swap(bomb1, bomb2); }); +} + +TEST(ThrowingValueTest, NonThrowingSwap) { + ThrowingValue bomb1, bomb2; + ExpectNoThrow([&]() { std::swap(bomb1, bomb2); }); +} + +TEST(ThrowingValueTest, NonThrowingAllocation) { + ThrowingValue* allocated; + ThrowingValue* array; + + ExpectNoThrow([&allocated]() { + allocated = new ThrowingValue(1); + delete allocated; + }); + ExpectNoThrow([&array]() { + array = new ThrowingValue[2]; + delete[] array; + }); +} + +TEST(ThrowingValueTest, NonThrowingDelete) { + auto* allocated = new ThrowingValue<>(1); + auto* array = new ThrowingValue<>[2]; + + SetCountdown(); + ExpectNoThrow([allocated]() { delete allocated; }); + SetCountdown(); + ExpectNoThrow([array]() { delete[] array; }); + + UnsetCountdown(); +} + +using Storage = + absl::aligned_storage_t), alignof(ThrowingValue<>)>; + +TEST(ThrowingValueTest, NonThrowingPlacementDelete) { + constexpr int kArrayLen = 2; + // We intentionally create extra space to store the tag allocated by placement + // new[]. + constexpr int kStorageLen = 4; + + Storage buf; + Storage array_buf[kStorageLen]; + auto* placed = new (&buf) ThrowingValue<>(1); + auto placed_array = new (&array_buf) ThrowingValue<>[kArrayLen]; + + SetCountdown(); + ExpectNoThrow([placed, &buf]() { + placed->~ThrowingValue<>(); + ThrowingValue<>::operator delete(placed, &buf); + }); + + SetCountdown(); + ExpectNoThrow([&, placed_array]() { + for (int i = 0; i < kArrayLen; ++i) placed_array[i].~ThrowingValue<>(); + ThrowingValue<>::operator delete[](placed_array, &array_buf); + }); + + UnsetCountdown(); +} + +TEST(ThrowingValueTest, NonThrowingDestructor) { + auto* allocated = new ThrowingValue<>(); + + SetCountdown(); + ExpectNoThrow([allocated]() { delete allocated; }); + UnsetCountdown(); +} + +TEST(ThrowingBoolTest, ThrowingBool) { + ThrowingBool t = true; + + // Test that it's contextually convertible to bool + if (t) { // NOLINT(whitespace/empty_if_body) + } + EXPECT_TRUE(t); + + TestOp([&]() { (void)!t; }); +} + +TEST(ThrowingAllocatorTest, MemoryManagement) { + // Just exercise the memory management capabilities under LSan to make sure we + // don't leak. + ThrowingAllocator int_alloc; + int* ip = int_alloc.allocate(1); + int_alloc.deallocate(ip, 1); + int* i_array = int_alloc.allocate(2); + int_alloc.deallocate(i_array, 2); + + ThrowingAllocator> tv_alloc; + ThrowingValue<>* ptr = tv_alloc.allocate(1); + tv_alloc.deallocate(ptr, 1); + ThrowingValue<>* tv_array = tv_alloc.allocate(2); + tv_alloc.deallocate(tv_array, 2); +} + +TEST(ThrowingAllocatorTest, CallsGlobalNew) { + ThrowingAllocator, AllocSpec::kNoThrowAllocate> nothrow_alloc; + ThrowingValue<>* ptr; + + SetCountdown(); + // This will only throw if ThrowingValue::new is called. + ExpectNoThrow([&]() { ptr = nothrow_alloc.allocate(1); }); + nothrow_alloc.deallocate(ptr, 1); + + UnsetCountdown(); +} + +TEST(ThrowingAllocatorTest, ThrowingConstructors) { + ThrowingAllocator int_alloc; + int* ip = nullptr; + + SetCountdown(); + EXPECT_THROW(ip = int_alloc.allocate(1), TestException); + ExpectNoThrow([&]() { ip = int_alloc.allocate(1); }); + + *ip = 1; + SetCountdown(); + EXPECT_THROW(int_alloc.construct(ip, 2), TestException); + EXPECT_EQ(*ip, 1); + int_alloc.deallocate(ip, 1); + + UnsetCountdown(); +} + +TEST(ThrowingAllocatorTest, NonThrowingConstruction) { + { + ThrowingAllocator int_alloc; + int* ip = nullptr; + + SetCountdown(); + ExpectNoThrow([&]() { ip = int_alloc.allocate(1); }); + + SetCountdown(); + ExpectNoThrow([&]() { int_alloc.construct(ip, 2); }); + + EXPECT_EQ(*ip, 2); + int_alloc.deallocate(ip, 1); + + UnsetCountdown(); + } + + { + ThrowingAllocator int_alloc; + int* ip = nullptr; + ExpectNoThrow([&]() { ip = int_alloc.allocate(1); }); + ExpectNoThrow([&]() { int_alloc.construct(ip, 2); }); + EXPECT_EQ(*ip, 2); + int_alloc.deallocate(ip, 1); + } + + { + ThrowingAllocator, AllocSpec::kNoThrowAllocate> + nothrow_alloc; + ThrowingValue<>* ptr; + + SetCountdown(); + ExpectNoThrow([&]() { ptr = nothrow_alloc.allocate(1); }); + + SetCountdown(); + ExpectNoThrow( + [&]() { nothrow_alloc.construct(ptr, 2, testing::nothrow_ctor); }); + + EXPECT_EQ(ptr->Get(), 2); + nothrow_alloc.destroy(ptr); + nothrow_alloc.deallocate(ptr, 1); + + UnsetCountdown(); + } + + { + ThrowingAllocator a; + + SetCountdown(); + ExpectNoThrow([&]() { ThrowingAllocator a1 = a; }); + + SetCountdown(); + ExpectNoThrow([&]() { ThrowingAllocator a1 = std::move(a); }); + + UnsetCountdown(); + } +} + +TEST(ThrowingAllocatorTest, ThrowingAllocatorConstruction) { + ThrowingAllocator a; + TestOp([]() { ThrowingAllocator a; }); + TestOp([&]() { a.select_on_container_copy_construction(); }); +} + +TEST(ThrowingAllocatorTest, State) { + ThrowingAllocator a1, a2; + EXPECT_NE(a1, a2); + + auto a3 = a1; + EXPECT_EQ(a3, a1); + int* ip = a1.allocate(1); + EXPECT_EQ(a3, a1); + a3.deallocate(ip, 1); + EXPECT_EQ(a3, a1); +} + +TEST(ThrowingAllocatorTest, InVector) { + std::vector, ThrowingAllocator>> v; + for (int i = 0; i < 20; ++i) v.push_back({}); + for (int i = 0; i < 20; ++i) v.pop_back(); +} + +TEST(ThrowingAllocatorTest, InList) { + std::list, ThrowingAllocator>> l; + for (int i = 0; i < 20; ++i) l.push_back({}); + for (int i = 0; i < 20; ++i) l.pop_back(); + for (int i = 0; i < 20; ++i) l.push_front({}); + for (int i = 0; i < 20; ++i) l.pop_front(); +} + +template +struct NullaryTestValidator : public std::false_type {}; + +template +struct NullaryTestValidator< + TesterInstance, + absl::void_t().Test())>> + : public std::true_type {}; + +template +bool HasNullaryTest(const TesterInstance&) { + return NullaryTestValidator::value; +} + +void DummyOp(void*) {} + +template +struct UnaryTestValidator : public std::false_type {}; + +template +struct UnaryTestValidator< + TesterInstance, + absl::void_t().Test(DummyOp))>> + : public std::true_type {}; + +template +bool HasUnaryTest(const TesterInstance&) { + return UnaryTestValidator::value; +} + +TEST(ExceptionSafetyTesterTest, IncompleteTypesAreNotTestable) { + using T = exceptions_internal::UninitializedT; + auto op = [](T* t) {}; + auto inv = [](T*) { return testing::AssertionSuccess(); }; + auto fac = []() { return absl::make_unique(); }; + + // Test that providing operation and inveriants still does not allow for the + // the invocation of .Test() and .Test(op) because it lacks a factory + auto without_fac = + testing::MakeExceptionSafetyTester().WithOperation(op).WithContracts( + inv, testing::strong_guarantee); + EXPECT_FALSE(HasNullaryTest(without_fac)); + EXPECT_FALSE(HasUnaryTest(without_fac)); + + // Test that providing contracts and factory allows the invocation of + // .Test(op) but does not allow for .Test() because it lacks an operation + auto without_op = testing::MakeExceptionSafetyTester() + .WithContracts(inv, testing::strong_guarantee) + .WithFactory(fac); + EXPECT_FALSE(HasNullaryTest(without_op)); + EXPECT_TRUE(HasUnaryTest(without_op)); + + // Test that providing operation and factory still does not allow for the + // the invocation of .Test() and .Test(op) because it lacks contracts + auto without_inv = + testing::MakeExceptionSafetyTester().WithOperation(op).WithFactory(fac); + EXPECT_FALSE(HasNullaryTest(without_inv)); + EXPECT_FALSE(HasUnaryTest(without_inv)); +} + +struct ExampleStruct {}; + +std::unique_ptr ExampleFunctionFactory() { + return absl::make_unique(); +} + +void ExampleFunctionOperation(ExampleStruct*) {} + +testing::AssertionResult ExampleFunctionContract(ExampleStruct*) { + return testing::AssertionSuccess(); +} + +struct { + std::unique_ptr operator()() const { + return ExampleFunctionFactory(); + } +} example_struct_factory; + +struct { + void operator()(ExampleStruct*) const {} +} example_struct_operation; + +struct { + testing::AssertionResult operator()(ExampleStruct* example_struct) const { + return ExampleFunctionContract(example_struct); + } +} example_struct_contract; + +auto example_lambda_factory = []() { return ExampleFunctionFactory(); }; + +auto example_lambda_operation = [](ExampleStruct*) {}; + +auto example_lambda_contract = [](ExampleStruct* example_struct) { + return ExampleFunctionContract(example_struct); +}; + +// Testing that function references, pointers, structs with operator() and +// lambdas can all be used with ExceptionSafetyTester +TEST(ExceptionSafetyTesterTest, MixedFunctionTypes) { + // function reference + EXPECT_TRUE(testing::MakeExceptionSafetyTester() + .WithFactory(ExampleFunctionFactory) + .WithOperation(ExampleFunctionOperation) + .WithContracts(ExampleFunctionContract) + .Test()); + + // function pointer + EXPECT_TRUE(testing::MakeExceptionSafetyTester() + .WithFactory(&ExampleFunctionFactory) + .WithOperation(&ExampleFunctionOperation) + .WithContracts(&ExampleFunctionContract) + .Test()); + + // struct + EXPECT_TRUE(testing::MakeExceptionSafetyTester() + .WithFactory(example_struct_factory) + .WithOperation(example_struct_operation) + .WithContracts(example_struct_contract) + .Test()); + + // lambda + EXPECT_TRUE(testing::MakeExceptionSafetyTester() + .WithFactory(example_lambda_factory) + .WithOperation(example_lambda_operation) + .WithContracts(example_lambda_contract) + .Test()); +} + +struct NonNegative { + bool operator==(const NonNegative& other) const { return i == other.i; } + int i; +}; + +testing::AssertionResult CheckNonNegativeInvariants(NonNegative* g) { + if (g->i >= 0) { + return testing::AssertionSuccess(); + } + return testing::AssertionFailure() + << "i should be non-negative but is " << g->i; +} + +struct { + template + void operator()(T* t) const { + (*t)(); + } +} invoker; + +auto tester = + testing::MakeExceptionSafetyTester().WithOperation(invoker).WithContracts( + CheckNonNegativeInvariants); +auto strong_tester = tester.WithContracts(testing::strong_guarantee); + +struct FailsBasicGuarantee : public NonNegative { + void operator()() { + --i; + ThrowingValue<> bomb; + ++i; + } +}; + +TEST(ExceptionCheckTest, BasicGuaranteeFailure) { + EXPECT_FALSE(tester.WithInitialValue(FailsBasicGuarantee{}).Test()); +} + +struct FollowsBasicGuarantee : public NonNegative { + void operator()() { + ++i; + ThrowingValue<> bomb; + } +}; + +TEST(ExceptionCheckTest, BasicGuarantee) { + EXPECT_TRUE(tester.WithInitialValue(FollowsBasicGuarantee{}).Test()); +} + +TEST(ExceptionCheckTest, StrongGuaranteeFailure) { + EXPECT_FALSE(strong_tester.WithInitialValue(FailsBasicGuarantee{}).Test()); + EXPECT_FALSE(strong_tester.WithInitialValue(FollowsBasicGuarantee{}).Test()); +} + +struct BasicGuaranteeWithExtraContracts : public NonNegative { + // After operator(), i is incremented. If operator() throws, i is set to 9999 + void operator()() { + int old_i = i; + i = kExceptionSentinel; + ThrowingValue<> bomb; + i = ++old_i; + } + + static constexpr int kExceptionSentinel = 9999; +}; +constexpr int BasicGuaranteeWithExtraContracts::kExceptionSentinel; + +TEST(ExceptionCheckTest, BasicGuaranteeWithExtraContracts) { + auto tester_with_val = + tester.WithInitialValue(BasicGuaranteeWithExtraContracts{}); + EXPECT_TRUE(tester_with_val.Test()); + EXPECT_TRUE( + tester_with_val + .WithContracts([](BasicGuaranteeWithExtraContracts* o) { + if (o->i == BasicGuaranteeWithExtraContracts::kExceptionSentinel) { + return testing::AssertionSuccess(); + } + return testing::AssertionFailure() + << "i should be " + << BasicGuaranteeWithExtraContracts::kExceptionSentinel + << ", but is " << o->i; + }) + .Test()); +} + +struct FollowsStrongGuarantee : public NonNegative { + void operator()() { ThrowingValue<> bomb; } +}; + +TEST(ExceptionCheckTest, StrongGuarantee) { + EXPECT_TRUE(tester.WithInitialValue(FollowsStrongGuarantee{}).Test()); + EXPECT_TRUE(strong_tester.WithInitialValue(FollowsStrongGuarantee{}).Test()); +} + +struct HasReset : public NonNegative { + void operator()() { + i = -1; + ThrowingValue<> bomb; + i = 1; + } + + void reset() { i = 0; } +}; + +testing::AssertionResult CheckHasResetContracts(HasReset* h) { + h->reset(); + return testing::AssertionResult(h->i == 0); +} + +TEST(ExceptionCheckTest, ModifyingChecker) { + auto set_to_1000 = [](FollowsBasicGuarantee* g) { + g->i = 1000; + return testing::AssertionSuccess(); + }; + auto is_1000 = [](FollowsBasicGuarantee* g) { + return testing::AssertionResult(g->i == 1000); + }; + auto increment = [](FollowsStrongGuarantee* g) { + ++g->i; + return testing::AssertionSuccess(); + }; + + EXPECT_FALSE(tester.WithInitialValue(FollowsBasicGuarantee{}) + .WithContracts(set_to_1000, is_1000) + .Test()); + EXPECT_TRUE(strong_tester.WithInitialValue(FollowsStrongGuarantee{}) + .WithContracts(increment) + .Test()); + EXPECT_TRUE(testing::MakeExceptionSafetyTester() + .WithInitialValue(HasReset{}) + .WithContracts(CheckHasResetContracts) + .Test(invoker)); +} + +TEST(ExceptionSafetyTesterTest, ResetsCountdown) { + auto test = + testing::MakeExceptionSafetyTester() + .WithInitialValue(ThrowingValue<>()) + .WithContracts([](ThrowingValue<>*) { return AssertionSuccess(); }) + .WithOperation([](ThrowingValue<>*) {}); + ASSERT_TRUE(test.Test()); + // If the countdown isn't reset because there were no exceptions thrown, then + // this will fail with a termination from an unhandled exception + EXPECT_TRUE(test.Test()); +} + +struct NonCopyable : public NonNegative { + NonCopyable(const NonCopyable&) = delete; + NonCopyable() : NonNegative{0} {} + + void operator()() { ThrowingValue<> bomb; } +}; + +TEST(ExceptionCheckTest, NonCopyable) { + auto factory = []() { return absl::make_unique(); }; + EXPECT_TRUE(tester.WithFactory(factory).Test()); + EXPECT_TRUE(strong_tester.WithFactory(factory).Test()); +} + +struct NonEqualityComparable : public NonNegative { + void operator()() { ThrowingValue<> bomb; } + + void ModifyOnThrow() { + ++i; + ThrowingValue<> bomb; + static_cast(bomb); + --i; + } +}; + +TEST(ExceptionCheckTest, NonEqualityComparable) { + auto nec_is_strong = [](NonEqualityComparable* nec) { + return testing::AssertionResult(nec->i == NonEqualityComparable().i); + }; + auto strong_nec_tester = tester.WithInitialValue(NonEqualityComparable{}) + .WithContracts(nec_is_strong); + + EXPECT_TRUE(strong_nec_tester.Test()); + EXPECT_FALSE(strong_nec_tester.Test( + [](NonEqualityComparable* n) { n->ModifyOnThrow(); })); +} + +template +struct ExhaustivenessTester { + void operator()() { + successes |= 1; + T b1; + static_cast(b1); + successes |= (1 << 1); + T b2; + static_cast(b2); + successes |= (1 << 2); + T b3; + static_cast(b3); + successes |= (1 << 3); + } + + bool operator==(const ExhaustivenessTester>&) const { + return true; + } + + static unsigned char successes; +}; + +struct { + template + testing::AssertionResult operator()(ExhaustivenessTester*) const { + return testing::AssertionSuccess(); + } +} CheckExhaustivenessTesterContracts; + +template +unsigned char ExhaustivenessTester::successes = 0; + +TEST(ExceptionCheckTest, Exhaustiveness) { + auto exhaust_tester = testing::MakeExceptionSafetyTester() + .WithContracts(CheckExhaustivenessTesterContracts) + .WithOperation(invoker); + + EXPECT_TRUE( + exhaust_tester.WithInitialValue(ExhaustivenessTester{}).Test()); + EXPECT_EQ(ExhaustivenessTester::successes, 0xF); + + EXPECT_TRUE( + exhaust_tester.WithInitialValue(ExhaustivenessTester>{}) + .WithContracts(testing::strong_guarantee) + .Test()); + EXPECT_EQ(ExhaustivenessTester>::successes, 0xF); +} + +struct LeaksIfCtorThrows : private exceptions_internal::TrackedObject { + LeaksIfCtorThrows() : TrackedObject(ABSL_PRETTY_FUNCTION) { + ++counter; + ThrowingValue<> v; + static_cast(v); + --counter; + } + LeaksIfCtorThrows(const LeaksIfCtorThrows&) noexcept + : TrackedObject(ABSL_PRETTY_FUNCTION) {} + static int counter; +}; +int LeaksIfCtorThrows::counter = 0; + +TEST(ExceptionCheckTest, TestLeakyCtor) { + testing::TestThrowingCtor(); + EXPECT_EQ(LeaksIfCtorThrows::counter, 1); + LeaksIfCtorThrows::counter = 0; +} + +struct Tracked : private exceptions_internal::TrackedObject { + Tracked() : TrackedObject(ABSL_PRETTY_FUNCTION) {} +}; + +TEST(ConstructorTrackerTest, CreatedBefore) { + Tracked a, b, c; + exceptions_internal::ConstructorTracker ct(exceptions_internal::countdown); +} + +TEST(ConstructorTrackerTest, CreatedAfter) { + exceptions_internal::ConstructorTracker ct(exceptions_internal::countdown); + Tracked a, b, c; +} + +TEST(ConstructorTrackerTest, NotDestroyedAfter) { + absl::aligned_storage_t storage; + EXPECT_NONFATAL_FAILURE( + { + exceptions_internal::ConstructorTracker ct( + exceptions_internal::countdown); + new (&storage) Tracked; + }, + "not destroyed"); +} + +TEST(ConstructorTrackerTest, DestroyedTwice) { + exceptions_internal::ConstructorTracker ct(exceptions_internal::countdown); + EXPECT_NONFATAL_FAILURE( + { + Tracked t; + t.~Tracked(); + }, + "re-destroyed"); +} + +TEST(ConstructorTrackerTest, ConstructedTwice) { + exceptions_internal::ConstructorTracker ct(exceptions_internal::countdown); + absl::aligned_storage_t storage; + EXPECT_NONFATAL_FAILURE( + { + new (&storage) Tracked; + new (&storage) Tracked; + reinterpret_cast(&storage)->~Tracked(); + }, + "re-constructed"); +} + +TEST(ThrowingValueTraitsTest, RelationalOperators) { + ThrowingValue<> a, b; + EXPECT_TRUE((std::is_convertible::value)); + EXPECT_TRUE((std::is_convertible::value)); + EXPECT_TRUE((std::is_convertible::value)); + EXPECT_TRUE((std::is_convertible::value)); + EXPECT_TRUE((std::is_convertible b), bool>::value)); + EXPECT_TRUE((std::is_convertible= b), bool>::value)); +} + +TEST(ThrowingAllocatorTraitsTest, Assignablility) { + EXPECT_TRUE(absl::is_move_assignable>::value); + EXPECT_TRUE(absl::is_copy_assignable>::value); + EXPECT_TRUE(std::is_nothrow_move_assignable>::value); + EXPECT_TRUE(std::is_nothrow_copy_assignable>::value); +} + +} // namespace + +} // namespace testing diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/inline_variable_test.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/inline_variable_test.cc new file mode 100644 index 0000000..5499189 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/inline_variable_test.cc @@ -0,0 +1,62 @@ +// Copyright 2017 The Abseil Authors. +// +// 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 + +#include "absl/base/internal/inline_variable.h" +#include "absl/base/internal/inline_variable_testing.h" + +#include "gtest/gtest.h" + +namespace absl { +namespace inline_variable_testing_internal { +namespace { + +TEST(InlineVariableTest, Constexpr) { + static_assert(inline_variable_foo.value == 5, ""); + static_assert(other_inline_variable_foo.value == 5, ""); + static_assert(inline_variable_int == 5, ""); + static_assert(other_inline_variable_int == 5, ""); +} + +TEST(InlineVariableTest, DefaultConstructedIdentityEquality) { + EXPECT_EQ(get_foo_a().value, 5); + EXPECT_EQ(get_foo_b().value, 5); + EXPECT_EQ(&get_foo_a(), &get_foo_b()); +} + +TEST(InlineVariableTest, DefaultConstructedIdentityInequality) { + EXPECT_NE(&inline_variable_foo, &other_inline_variable_foo); +} + +TEST(InlineVariableTest, InitializedIdentityEquality) { + EXPECT_EQ(get_int_a(), 5); + EXPECT_EQ(get_int_b(), 5); + EXPECT_EQ(&get_int_a(), &get_int_b()); +} + +TEST(InlineVariableTest, InitializedIdentityInequality) { + EXPECT_NE(&inline_variable_int, &other_inline_variable_int); +} + +TEST(InlineVariableTest, FunPtrType) { + static_assert( + std::is_same::type>::value, + ""); +} + +} // namespace +} // namespace inline_variable_testing_internal +} // namespace absl diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/inline_variable_test_a.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/inline_variable_test_a.cc new file mode 100644 index 0000000..a3bf3b6 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/inline_variable_test_a.cc @@ -0,0 +1,25 @@ +// Copyright 2017 The Abseil Authors. +// +// 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 "absl/base/internal/inline_variable_testing.h" + +namespace absl { +namespace inline_variable_testing_internal { + +const Foo& get_foo_a() { return inline_variable_foo; } + +const int& get_int_a() { return inline_variable_int; } + +} // namespace inline_variable_testing_internal +} // namespace absl diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/inline_variable_test_b.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/inline_variable_test_b.cc new file mode 100644 index 0000000..b4b9393 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/inline_variable_test_b.cc @@ -0,0 +1,25 @@ +// Copyright 2017 The Abseil Authors. +// +// 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 "absl/base/internal/inline_variable_testing.h" + +namespace absl { +namespace inline_variable_testing_internal { + +const Foo& get_foo_b() { return inline_variable_foo; } + +const int& get_int_b() { return inline_variable_int; } + +} // namespace inline_variable_testing_internal +} // namespace absl diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/atomic_hook.h b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/atomic_hook.h new file mode 100644 index 0000000..b458511 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/atomic_hook.h @@ -0,0 +1,165 @@ +// Copyright 2017 The Abseil Authors. +// +// 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. +// + +#ifndef ABSL_BASE_INTERNAL_ATOMIC_HOOK_H_ +#define ABSL_BASE_INTERNAL_ATOMIC_HOOK_H_ + +#include +#include +#include +#include + +#ifdef _MSC_FULL_VER +#define ABSL_HAVE_WORKING_ATOMIC_POINTER 0 +#else +#define ABSL_HAVE_WORKING_ATOMIC_POINTER 1 +#endif + +namespace absl { +namespace base_internal { + +template +class AtomicHook; + +// AtomicHook is a helper class, templatized on a raw function pointer type, for +// implementing Abseil customization hooks. It is a callable object that +// dispatches to the registered hook. +// +// A default constructed object performs a no-op (and returns a default +// constructed object) if no hook has been registered. +// +// Hooks can be pre-registered via constant initialization, for example, +// ABSL_CONST_INIT static AtomicHook my_hook(DefaultAction); +// and then changed at runtime via a call to Store(). +// +// Reads and writes guarantee memory_order_acquire/memory_order_release +// semantics. +template +class AtomicHook { + public: + using FnPtr = ReturnType (*)(Args...); + + // Constructs an object that by default performs a no-op (and + // returns a default constructed object) when no hook as been registered. + constexpr AtomicHook() : AtomicHook(DummyFunction) {} + + // Constructs an object that by default dispatches to/returns the + // pre-registered default_fn when no hook has been registered at runtime. +#if ABSL_HAVE_WORKING_ATOMIC_POINTER + explicit constexpr AtomicHook(FnPtr default_fn) + : hook_(default_fn), default_fn_(default_fn) {} +#else + explicit constexpr AtomicHook(FnPtr default_fn) + : hook_(kUninitialized), default_fn_(default_fn) {} +#endif + + // Stores the provided function pointer as the value for this hook. + // + // This is intended to be called once. Multiple calls are legal only if the + // same function pointer is provided for each call. The store is implemented + // as a memory_order_release operation, and read accesses are implemented as + // memory_order_acquire. + void Store(FnPtr fn) { + bool success = DoStore(fn); + static_cast(success); + assert(success); + } + + // Invokes the registered callback. If no callback has yet been registered, a + // default-constructed object of the appropriate type is returned instead. + template + ReturnType operator()(CallArgs&&... args) const { + return DoLoad()(std::forward(args)...); + } + + // Returns the registered callback, or nullptr if none has been registered. + // Useful if client code needs to conditionalize behavior based on whether a + // callback was registered. + // + // Note that atomic_hook.Load()() and atomic_hook() have different semantics: + // operator()() will perform a no-op if no callback was registered, while + // Load()() will dereference a null function pointer. Prefer operator()() to + // Load()() unless you must conditionalize behavior on whether a hook was + // registered. + FnPtr Load() const { + FnPtr ptr = DoLoad(); + return (ptr == DummyFunction) ? nullptr : ptr; + } + + private: + static ReturnType DummyFunction(Args...) { + return ReturnType(); + } + + // Current versions of MSVC (as of September 2017) have a broken + // implementation of std::atomic: Its constructor attempts to do the + // equivalent of a reinterpret_cast in a constexpr context, which is not + // allowed. + // + // This causes an issue when building with LLVM under Windows. To avoid this, + // we use a less-efficient, intptr_t-based implementation on Windows. +#if ABSL_HAVE_WORKING_ATOMIC_POINTER + // Return the stored value, or DummyFunction if no value has been stored. + FnPtr DoLoad() const { return hook_.load(std::memory_order_acquire); } + + // Store the given value. Returns false if a different value was already + // stored to this object. + bool DoStore(FnPtr fn) { + assert(fn); + FnPtr expected = default_fn_; + const bool store_succeeded = hook_.compare_exchange_strong( + expected, fn, std::memory_order_acq_rel, std::memory_order_acquire); + const bool same_value_already_stored = (expected == fn); + return store_succeeded || same_value_already_stored; + } + + std::atomic hook_; +#else // !ABSL_HAVE_WORKING_ATOMIC_POINTER + // Use a sentinel value unlikely to be the address of an actual function. + static constexpr intptr_t kUninitialized = 0; + + static_assert(sizeof(intptr_t) >= sizeof(FnPtr), + "intptr_t can't contain a function pointer"); + + FnPtr DoLoad() const { + const intptr_t value = hook_.load(std::memory_order_acquire); + if (value == kUninitialized) { + return default_fn_; + } + return reinterpret_cast(value); + } + + bool DoStore(FnPtr fn) { + assert(fn); + const auto value = reinterpret_cast(fn); + intptr_t expected = kUninitialized; + const bool store_succeeded = hook_.compare_exchange_strong( + expected, value, std::memory_order_acq_rel, std::memory_order_acquire); + const bool same_value_already_stored = (expected == value); + return store_succeeded || same_value_already_stored; + } + + std::atomic hook_; +#endif + + const FnPtr default_fn_; +}; + +#undef ABSL_HAVE_WORKING_ATOMIC_POINTER + +} // namespace base_internal +} // namespace absl + +#endif // ABSL_BASE_INTERNAL_ATOMIC_HOOK_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/atomic_hook_test.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/atomic_hook_test.cc new file mode 100644 index 0000000..cf74075 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/atomic_hook_test.cc @@ -0,0 +1,70 @@ +// Copyright 2018 The Abseil Authors. +// +// 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 "absl/base/internal/atomic_hook.h" + +#include "gtest/gtest.h" +#include "absl/base/attributes.h" + +namespace { + +int value = 0; +void TestHook(int x) { value = x; } + +TEST(AtomicHookTest, NoDefaultFunction) { + ABSL_CONST_INIT static absl::base_internal::AtomicHook hook; + value = 0; + + // Test the default DummyFunction. + EXPECT_TRUE(hook.Load() == nullptr); + EXPECT_EQ(value, 0); + hook(1); + EXPECT_EQ(value, 0); + + // Test a stored hook. + hook.Store(TestHook); + EXPECT_TRUE(hook.Load() == TestHook); + EXPECT_EQ(value, 0); + hook(1); + EXPECT_EQ(value, 1); + + // Calling Store() with the same hook should not crash. + hook.Store(TestHook); + EXPECT_TRUE(hook.Load() == TestHook); + EXPECT_EQ(value, 1); + hook(2); + EXPECT_EQ(value, 2); +} + +TEST(AtomicHookTest, WithDefaultFunction) { + // Set the default value to TestHook at compile-time. + ABSL_CONST_INIT static absl::base_internal::AtomicHook hook( + TestHook); + value = 0; + + // Test the default value is TestHook. + EXPECT_TRUE(hook.Load() == TestHook); + EXPECT_EQ(value, 0); + hook(1); + EXPECT_EQ(value, 1); + + // Calling Store() with the same hook should not crash. + hook.Store(TestHook); + EXPECT_TRUE(hook.Load() == TestHook); + EXPECT_EQ(value, 1); + hook(2); + EXPECT_EQ(value, 2); +} + +} // namespace diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/bits.h b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/bits.h new file mode 100644 index 0000000..bc7faae --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/bits.h @@ -0,0 +1,193 @@ +// Copyright 2018 The Abseil Authors. +// +// 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. + +#ifndef ABSL_BASE_INTERNAL_BITS_H_ +#define ABSL_BASE_INTERNAL_BITS_H_ + +// This file contains bitwise ops which are implementation details of various +// absl libraries. + +#include + +// Clang on Windows has __builtin_clzll; otherwise we need to use the +// windows intrinsic functions. +#if defined(_MSC_VER) +#include +#if defined(_M_X64) +#pragma intrinsic(_BitScanReverse64) +#pragma intrinsic(_BitScanForward64) +#endif +#pragma intrinsic(_BitScanReverse) +#pragma intrinsic(_BitScanForward) +#endif + +#include "absl/base/attributes.h" + +#if defined(_MSC_VER) +// We can achieve something similar to attribute((always_inline)) with MSVC by +// using the __forceinline keyword, however this is not perfect. MSVC is +// much less aggressive about inlining, and even with the __forceinline keyword. +#define ABSL_BASE_INTERNAL_FORCEINLINE __forceinline +#else +// Use default attribute inline. +#define ABSL_BASE_INTERNAL_FORCEINLINE inline ABSL_ATTRIBUTE_ALWAYS_INLINE +#endif + + +namespace absl { +namespace base_internal { + +ABSL_BASE_INTERNAL_FORCEINLINE int CountLeadingZeros64Slow(uint64_t n) { + int zeroes = 60; + if (n >> 32) zeroes -= 32, n >>= 32; + if (n >> 16) zeroes -= 16, n >>= 16; + if (n >> 8) zeroes -= 8, n >>= 8; + if (n >> 4) zeroes -= 4, n >>= 4; + return "\4\3\2\2\1\1\1\1\0\0\0\0\0\0\0"[n] + zeroes; +} + +ABSL_BASE_INTERNAL_FORCEINLINE int CountLeadingZeros64(uint64_t n) { +#if defined(_MSC_VER) && defined(_M_X64) + // MSVC does not have __buitin_clzll. Use _BitScanReverse64. + unsigned long result = 0; // NOLINT(runtime/int) + if (_BitScanReverse64(&result, n)) { + return 63 - result; + } + return 64; +#elif defined(_MSC_VER) + // MSVC does not have __buitin_clzll. Compose two calls to _BitScanReverse + unsigned long result = 0; // NOLINT(runtime/int) + if ((n >> 32) && _BitScanReverse(&result, n >> 32)) { + return 31 - result; + } + if (_BitScanReverse(&result, n)) { + return 63 - result; + } + return 64; +#elif defined(__GNUC__) + // Use __builtin_clzll, which uses the following instructions: + // x86: bsr + // ARM64: clz + // PPC: cntlzd + static_assert(sizeof(unsigned long long) == sizeof(n), // NOLINT(runtime/int) + "__builtin_clzll does not take 64-bit arg"); + + // Handle 0 as a special case because __builtin_clzll(0) is undefined. + if (n == 0) { + return 64; + } + return __builtin_clzll(n); +#else + return CountLeadingZeros64Slow(n); +#endif +} + +ABSL_BASE_INTERNAL_FORCEINLINE int CountLeadingZeros32Slow(uint64_t n) { + int zeroes = 28; + if (n >> 16) zeroes -= 16, n >>= 16; + if (n >> 8) zeroes -= 8, n >>= 8; + if (n >> 4) zeroes -= 4, n >>= 4; + return "\4\3\2\2\1\1\1\1\0\0\0\0\0\0\0"[n] + zeroes; +} + +ABSL_BASE_INTERNAL_FORCEINLINE int CountLeadingZeros32(uint32_t n) { +#if defined(_MSC_VER) + unsigned long result = 0; // NOLINT(runtime/int) + if (_BitScanReverse(&result, n)) { + return 31 - result; + } + return 32; +#elif defined(__GNUC__) + // Use __builtin_clz, which uses the following instructions: + // x86: bsr + // ARM64: clz + // PPC: cntlzd + static_assert(sizeof(int) == sizeof(n), + "__builtin_clz does not take 32-bit arg"); + + // Handle 0 as a special case because __builtin_clz(0) is undefined. + if (n == 0) { + return 32; + } + return __builtin_clz(n); +#else + return CountLeadingZeros32Slow(n); +#endif +} + +ABSL_BASE_INTERNAL_FORCEINLINE int CountTrailingZerosNonZero64Slow(uint64_t n) { + int c = 63; + n &= ~n + 1; + if (n & 0x00000000FFFFFFFF) c -= 32; + if (n & 0x0000FFFF0000FFFF) c -= 16; + if (n & 0x00FF00FF00FF00FF) c -= 8; + if (n & 0x0F0F0F0F0F0F0F0F) c -= 4; + if (n & 0x3333333333333333) c -= 2; + if (n & 0x5555555555555555) c -= 1; + return c; +} + +ABSL_BASE_INTERNAL_FORCEINLINE int CountTrailingZerosNonZero64(uint64_t n) { +#if defined(_MSC_VER) && defined(_M_X64) + unsigned long result = 0; // NOLINT(runtime/int) + _BitScanForward64(&result, n); + return result; +#elif defined(_MSC_VER) + unsigned long result = 0; // NOLINT(runtime/int) + if (static_cast(n) == 0) { + _BitScanForward(&result, n >> 32); + return result + 32; + } + _BitScanForward(&result, n); + return result; +#elif defined(__GNUC__) + static_assert(sizeof(unsigned long long) == sizeof(n), // NOLINT(runtime/int) + "__builtin_ctzll does not take 64-bit arg"); + return __builtin_ctzll(n); +#else + return CountTrailingZerosNonZero64Slow(n); +#endif +} + +ABSL_BASE_INTERNAL_FORCEINLINE int CountTrailingZerosNonZero32Slow(uint32_t n) { + int c = 31; + n &= ~n + 1; + if (n & 0x0000FFFF) c -= 16; + if (n & 0x00FF00FF) c -= 8; + if (n & 0x0F0F0F0F) c -= 4; + if (n & 0x33333333) c -= 2; + if (n & 0x55555555) c -= 1; + return c; +} + +ABSL_BASE_INTERNAL_FORCEINLINE int CountTrailingZerosNonZero32(uint32_t n) { +#if defined(_MSC_VER) + unsigned long result = 0; // NOLINT(runtime/int) + _BitScanForward(&result, n); + return result; +#elif defined(__GNUC__) + static_assert(sizeof(int) == sizeof(n), + "__builtin_ctz does not take 32-bit arg"); + return __builtin_ctz(n); +#else + return CountTrailingZerosNonZero32Slow(n); +#endif +} + +#undef ABSL_BASE_INTERNAL_FORCEINLINE + +} // namespace base_internal +} // namespace absl + +#endif // ABSL_BASE_INTERNAL_BITS_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/bits_test.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/bits_test.cc new file mode 100644 index 0000000..e5d991d --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/bits_test.cc @@ -0,0 +1,97 @@ +// Copyright 2018 The Abseil Authors. +// +// 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 "absl/base/internal/bits.h" + +#include "gtest/gtest.h" + +namespace { + +int CLZ64(uint64_t n) { + int fast = absl::base_internal::CountLeadingZeros64(n); + int slow = absl::base_internal::CountLeadingZeros64Slow(n); + EXPECT_EQ(fast, slow) << n; + return fast; +} + +TEST(BitsTest, CountLeadingZeros64) { + EXPECT_EQ(64, CLZ64(uint64_t{})); + EXPECT_EQ(0, CLZ64(~uint64_t{})); + + for (int index = 0; index < 64; index++) { + uint64_t x = static_cast(1) << index; + const auto cnt = 63 - index; + ASSERT_EQ(cnt, CLZ64(x)) << index; + ASSERT_EQ(cnt, CLZ64(x + x - 1)) << index; + } +} + +int CLZ32(uint32_t n) { + int fast = absl::base_internal::CountLeadingZeros32(n); + int slow = absl::base_internal::CountLeadingZeros32Slow(n); + EXPECT_EQ(fast, slow) << n; + return fast; +} + +TEST(BitsTest, CountLeadingZeros32) { + EXPECT_EQ(32, CLZ32(uint32_t{})); + EXPECT_EQ(0, CLZ32(~uint32_t{})); + + for (int index = 0; index < 32; index++) { + uint32_t x = static_cast(1) << index; + const auto cnt = 31 - index; + ASSERT_EQ(cnt, CLZ32(x)) << index; + ASSERT_EQ(cnt, CLZ32(x + x - 1)) << index; + ASSERT_EQ(CLZ64(x), CLZ32(x) + 32); + } +} + +int CTZ64(uint64_t n) { + int fast = absl::base_internal::CountTrailingZerosNonZero64(n); + int slow = absl::base_internal::CountTrailingZerosNonZero64Slow(n); + EXPECT_EQ(fast, slow) << n; + return fast; +} + +TEST(BitsTest, CountTrailingZerosNonZero64) { + EXPECT_EQ(0, CTZ64(~uint64_t{})); + + for (int index = 0; index < 64; index++) { + uint64_t x = static_cast(1) << index; + const auto cnt = index; + ASSERT_EQ(cnt, CTZ64(x)) << index; + ASSERT_EQ(cnt, CTZ64(~(x - 1))) << index; + } +} + +int CTZ32(uint32_t n) { + int fast = absl::base_internal::CountTrailingZerosNonZero32(n); + int slow = absl::base_internal::CountTrailingZerosNonZero32Slow(n); + EXPECT_EQ(fast, slow) << n; + return fast; +} + +TEST(BitsTest, CountTrailingZerosNonZero32) { + EXPECT_EQ(0, CTZ32(~uint32_t{})); + + for (int index = 0; index < 32; index++) { + uint32_t x = static_cast(1) << index; + const auto cnt = index; + ASSERT_EQ(cnt, CTZ32(x)) << index; + ASSERT_EQ(cnt, CTZ32(~(x - 1))) << index; + } +} + + +} // namespace diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/cycleclock.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/cycleclock.cc new file mode 100644 index 0000000..a742df0 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/cycleclock.cc @@ -0,0 +1,81 @@ +// Copyright 2017 The Abseil Authors. +// +// 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. + +// The implementation of CycleClock::Frequency. +// +// NOTE: only i386 and x86_64 have been well tested. +// PPC, sparc, alpha, and ia64 are based on +// http://peter.kuscsik.com/wordpress/?p=14 +// with modifications by m3b. See also +// https://setisvn.ssl.berkeley.edu/svn/lib/fftw-3.0.1/kernel/cycle.h + +#include "absl/base/internal/cycleclock.h" + +#include // NOLINT(build/c++11) + +#include "absl/base/internal/unscaledcycleclock.h" + +namespace absl { +namespace base_internal { + +#if ABSL_USE_UNSCALED_CYCLECLOCK + +namespace { + +#ifdef NDEBUG +#ifdef ABSL_INTERNAL_UNSCALED_CYCLECLOCK_FREQUENCY_IS_CPU_FREQUENCY +// Not debug mode and the UnscaledCycleClock frequency is the CPU +// frequency. Scale the CycleClock to prevent overflow if someone +// tries to represent the time as cycles since the Unix epoch. +static constexpr int32_t kShift = 1; +#else +// Not debug mode and the UnscaledCycleClock isn't operating at the +// raw CPU frequency. There is no need to do any scaling, so don't +// needlessly sacrifice precision. +static constexpr int32_t kShift = 0; +#endif +#else +// In debug mode use a different shift to discourage depending on a +// particular shift value. +static constexpr int32_t kShift = 2; +#endif + +static constexpr double kFrequencyScale = 1.0 / (1 << kShift); + +} // namespace + +int64_t CycleClock::Now() { + return base_internal::UnscaledCycleClock::Now() >> kShift; +} + +double CycleClock::Frequency() { + return kFrequencyScale * base_internal::UnscaledCycleClock::Frequency(); +} + +#else + +int64_t CycleClock::Now() { + return std::chrono::duration_cast( + std::chrono::steady_clock::now().time_since_epoch()) + .count(); +} + +double CycleClock::Frequency() { + return 1e9; +} + +#endif + +} // namespace base_internal +} // namespace absl diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/cycleclock.h b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/cycleclock.h new file mode 100644 index 0000000..60e9715 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/cycleclock.h @@ -0,0 +1,77 @@ +// +// Copyright 2017 The Abseil Authors. +// +// 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. +// + +// ----------------------------------------------------------------------------- +// File: cycleclock.h +// ----------------------------------------------------------------------------- +// +// This header file defines a `CycleClock`, which yields the value and frequency +// of a cycle counter that increments at a rate that is approximately constant. +// +// NOTE: +// +// The cycle counter frequency is not necessarily related to the core clock +// frequency and should not be treated as such. That is, `CycleClock` cycles are +// not necessarily "CPU cycles" and code should not rely on that behavior, even +// if experimentally observed. +// +// +// An arbitrary offset may have been added to the counter at power on. +// +// On some platforms, the rate and offset of the counter may differ +// slightly when read from different CPUs of a multiprocessor. Usually, +// we try to ensure that the operating system adjusts values periodically +// so that values agree approximately. If you need stronger guarantees, +// consider using alternate interfaces. +// +// The CPU is not required to maintain the ordering of a cycle counter read +// with respect to surrounding instructions. + +#ifndef ABSL_BASE_INTERNAL_CYCLECLOCK_H_ +#define ABSL_BASE_INTERNAL_CYCLECLOCK_H_ + +#include + +namespace absl { +namespace base_internal { + +// ----------------------------------------------------------------------------- +// CycleClock +// ----------------------------------------------------------------------------- +class CycleClock { + public: + // CycleClock::Now() + // + // Returns the value of a cycle counter that counts at a rate that is + // approximately constant. + static int64_t Now(); + + // CycleClock::Frequency() + // + // Returns the amount by which `CycleClock::Now()` increases per second. Note + // that this value may not necessarily match the core CPU clock frequency. + static double Frequency(); + + private: + CycleClock() = delete; // no instances + CycleClock(const CycleClock&) = delete; + CycleClock& operator=(const CycleClock&) = delete; +}; + +} // namespace base_internal +} // namespace absl + +#endif // ABSL_BASE_INTERNAL_CYCLECLOCK_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/direct_mmap.h b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/direct_mmap.h new file mode 100644 index 0000000..0426e11 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/direct_mmap.h @@ -0,0 +1,153 @@ +// Copyright 2017 The Abseil Authors. +// +// 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. +// +// Functions for directly invoking mmap() via syscall, avoiding the case where +// mmap() has been locally overridden. + +#ifndef ABSL_BASE_INTERNAL_DIRECT_MMAP_H_ +#define ABSL_BASE_INTERNAL_DIRECT_MMAP_H_ + +#include "absl/base/config.h" + +#if ABSL_HAVE_MMAP + +#include + +#ifdef __linux__ + +#include +#ifdef __BIONIC__ +#include +#else +#include +#endif + +#include +#include +#include +#include +#include + +#ifdef __mips__ +// Include definitions of the ABI currently in use. +#ifdef __BIONIC__ +// Android doesn't have sgidefs.h, but does have asm/sgidefs.h, which has the +// definitions we need. +#include +#else +#include +#endif // __BIONIC__ +#endif // __mips__ + +// SYS_mmap and SYS_munmap are not defined in Android. +#ifdef __BIONIC__ +extern "C" void* __mmap2(void*, size_t, int, int, int, size_t); +#if defined(__NR_mmap) && !defined(SYS_mmap) +#define SYS_mmap __NR_mmap +#endif +#ifndef SYS_munmap +#define SYS_munmap __NR_munmap +#endif +#endif // __BIONIC__ + +namespace absl { +namespace base_internal { + +// Platform specific logic extracted from +// https://chromium.googlesource.com/linux-syscall-support/+/master/linux_syscall_support.h +inline void* DirectMmap(void* start, size_t length, int prot, int flags, int fd, + off64_t offset) noexcept { +#if defined(__i386__) || defined(__ARM_ARCH_3__) || defined(__ARM_EABI__) || \ + (defined(__mips__) && _MIPS_SIM == _MIPS_SIM_ABI32) || \ + (defined(__PPC__) && !defined(__PPC64__)) || \ + (defined(__s390__) && !defined(__s390x__)) + // On these architectures, implement mmap with mmap2. + static int pagesize = 0; + if (pagesize == 0) { + pagesize = getpagesize(); + } + if (offset < 0 || offset % pagesize != 0) { + errno = EINVAL; + return MAP_FAILED; + } +#ifdef __BIONIC__ + // SYS_mmap2 has problems on Android API level <= 16. + // Workaround by invoking __mmap2() instead. + return __mmap2(start, length, prot, flags, fd, offset / pagesize); +#else + return reinterpret_cast( + syscall(SYS_mmap2, start, length, prot, flags, fd, + static_cast(offset / pagesize))); +#endif +#elif defined(__s390x__) + // On s390x, mmap() arguments are passed in memory. + unsigned long buf[6] = {reinterpret_cast(start), // NOLINT + static_cast(length), // NOLINT + static_cast(prot), // NOLINT + static_cast(flags), // NOLINT + static_cast(fd), // NOLINT + static_cast(offset)}; // NOLINT + return reinterpret_cast(syscall(SYS_mmap, buf)); +#elif defined(__x86_64__) +// The x32 ABI has 32 bit longs, but the syscall interface is 64 bit. +// We need to explicitly cast to an unsigned 64 bit type to avoid implicit +// sign extension. We can't cast pointers directly because those are +// 32 bits, and gcc will dump ugly warnings about casting from a pointer +// to an integer of a different size. We also need to make sure __off64_t +// isn't truncated to 32-bits under x32. +#define MMAP_SYSCALL_ARG(x) ((uint64_t)(uintptr_t)(x)) + return reinterpret_cast( + syscall(SYS_mmap, MMAP_SYSCALL_ARG(start), MMAP_SYSCALL_ARG(length), + MMAP_SYSCALL_ARG(prot), MMAP_SYSCALL_ARG(flags), + MMAP_SYSCALL_ARG(fd), static_cast(offset))); +#undef MMAP_SYSCALL_ARG +#else // Remaining 64-bit aritectures. + static_assert(sizeof(unsigned long) == 8, "Platform is not 64-bit"); + return reinterpret_cast( + syscall(SYS_mmap, start, length, prot, flags, fd, offset)); +#endif +} + +inline int DirectMunmap(void* start, size_t length) { + return static_cast(syscall(SYS_munmap, start, length)); +} + +} // namespace base_internal +} // namespace absl + +#else // !__linux__ + +// For non-linux platforms where we have mmap, just dispatch directly to the +// actual mmap()/munmap() methods. + +namespace absl { +namespace base_internal { + +inline void* DirectMmap(void* start, size_t length, int prot, int flags, int fd, + off_t offset) { + return mmap(start, length, prot, flags, fd, offset); +} + +inline int DirectMunmap(void* start, size_t length) { + return munmap(start, length); +} + +} // namespace base_internal +} // namespace absl + +#endif // __linux__ + +#endif // ABSL_HAVE_MMAP + +#endif // ABSL_BASE_INTERNAL_DIRECT_MMAP_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/endian.h b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/endian.h new file mode 100644 index 0000000..d5dc51a --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/endian.h @@ -0,0 +1,272 @@ +// Copyright 2017 The Abseil Authors. +// +// 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. +// + +#ifndef ABSL_BASE_INTERNAL_ENDIAN_H_ +#define ABSL_BASE_INTERNAL_ENDIAN_H_ + +// The following guarantees declaration of the byte swap functions +#ifdef _MSC_VER +#include // NOLINT(build/include) +#elif defined(__APPLE__) +// Mac OS X / Darwin features +#include +#elif defined(__FreeBSD__) +#include +#elif defined(__GLIBC__) +#include // IWYU pragma: export +#endif + +#include +#include "absl/base/config.h" +#include "absl/base/internal/unaligned_access.h" +#include "absl/base/port.h" + +namespace absl { + +// Use compiler byte-swapping intrinsics if they are available. 32-bit +// and 64-bit versions are available in Clang and GCC as of GCC 4.3.0. +// The 16-bit version is available in Clang and GCC only as of GCC 4.8.0. +// For simplicity, we enable them all only for GCC 4.8.0 or later. +#if defined(__clang__) || \ + (defined(__GNUC__) && \ + ((__GNUC__ == 4 && __GNUC_MINOR__ >= 8) || __GNUC__ >= 5)) +inline uint64_t gbswap_64(uint64_t host_int) { + return __builtin_bswap64(host_int); +} +inline uint32_t gbswap_32(uint32_t host_int) { + return __builtin_bswap32(host_int); +} +inline uint16_t gbswap_16(uint16_t host_int) { + return __builtin_bswap16(host_int); +} + +#elif defined(_MSC_VER) +inline uint64_t gbswap_64(uint64_t host_int) { + return _byteswap_uint64(host_int); +} +inline uint32_t gbswap_32(uint32_t host_int) { + return _byteswap_ulong(host_int); +} +inline uint16_t gbswap_16(uint16_t host_int) { + return _byteswap_ushort(host_int); +} + +#elif defined(__APPLE__) +inline uint64_t gbswap_64(uint64_t host_int) { return OSSwapInt16(host_int); } +inline uint32_t gbswap_32(uint32_t host_int) { return OSSwapInt32(host_int); } +inline uint16_t gbswap_16(uint16_t host_int) { return OSSwapInt64(host_int); } + +#else +inline uint64_t gbswap_64(uint64_t host_int) { +#if defined(__GNUC__) && defined(__x86_64__) && !defined(__APPLE__) + // Adapted from /usr/include/byteswap.h. Not available on Mac. + if (__builtin_constant_p(host_int)) { + return __bswap_constant_64(host_int); + } else { + register uint64_t result; + __asm__("bswap %0" : "=r"(result) : "0"(host_int)); + return result; + } +#elif defined(__GLIBC__) + return bswap_64(host_int); +#else + return (((host_int & uint64_t{0xFF}) << 56) | + ((host_int & uint64_t{0xFF00}) << 40) | + ((host_int & uint64_t{0xFF0000}) << 24) | + ((host_int & uint64_t{0xFF000000}) << 8) | + ((host_int & uint64_t{0xFF00000000}) >> 8) | + ((host_int & uint64_t{0xFF0000000000}) >> 24) | + ((host_int & uint64_t{0xFF000000000000}) >> 40) | + ((host_int & uint64_t{0xFF00000000000000}) >> 56)); +#endif // bswap_64 +} + +inline uint32_t gbswap_32(uint32_t host_int) { +#if defined(__GLIBC__) + return bswap_32(host_int); +#else + return (((host_int & uint32_t{0xFF}) << 24) | + ((host_int & uint32_t{0xFF00}) << 8) | + ((host_int & uint32_t{0xFF0000}) >> 8) | + ((host_int & uint32_t{0xFF000000}) >> 24)); +#endif +} + +inline uint16_t gbswap_16(uint16_t host_int) { +#if defined(__GLIBC__) + return bswap_16(host_int); +#else + return (((host_int & uint16_t{0xFF}) << 8) | + ((host_int & uint16_t{0xFF00}) >> 8)); +#endif +} + +#endif // intrinics available + +#ifdef ABSL_IS_LITTLE_ENDIAN + +// Definitions for ntohl etc. that don't require us to include +// netinet/in.h. We wrap gbswap_32 and gbswap_16 in functions rather +// than just #defining them because in debug mode, gcc doesn't +// correctly handle the (rather involved) definitions of bswap_32. +// gcc guarantees that inline functions are as fast as macros, so +// this isn't a performance hit. +inline uint16_t ghtons(uint16_t x) { return gbswap_16(x); } +inline uint32_t ghtonl(uint32_t x) { return gbswap_32(x); } +inline uint64_t ghtonll(uint64_t x) { return gbswap_64(x); } + +#elif defined ABSL_IS_BIG_ENDIAN + +// These definitions are simpler on big-endian machines +// These are functions instead of macros to avoid self-assignment warnings +// on calls such as "i = ghtnol(i);". This also provides type checking. +inline uint16_t ghtons(uint16_t x) { return x; } +inline uint32_t ghtonl(uint32_t x) { return x; } +inline uint64_t ghtonll(uint64_t x) { return x; } + +#else +#error \ + "Unsupported byte order: Either ABSL_IS_BIG_ENDIAN or " \ + "ABSL_IS_LITTLE_ENDIAN must be defined" +#endif // byte order + +inline uint16_t gntohs(uint16_t x) { return ghtons(x); } +inline uint32_t gntohl(uint32_t x) { return ghtonl(x); } +inline uint64_t gntohll(uint64_t x) { return ghtonll(x); } + +// Utilities to convert numbers between the current hosts's native byte +// order and little-endian byte order +// +// Load/Store methods are alignment safe +namespace little_endian { +// Conversion functions. +#ifdef ABSL_IS_LITTLE_ENDIAN + +inline uint16_t FromHost16(uint16_t x) { return x; } +inline uint16_t ToHost16(uint16_t x) { return x; } + +inline uint32_t FromHost32(uint32_t x) { return x; } +inline uint32_t ToHost32(uint32_t x) { return x; } + +inline uint64_t FromHost64(uint64_t x) { return x; } +inline uint64_t ToHost64(uint64_t x) { return x; } + +inline constexpr bool IsLittleEndian() { return true; } + +#elif defined ABSL_IS_BIG_ENDIAN + +inline uint16_t FromHost16(uint16_t x) { return gbswap_16(x); } +inline uint16_t ToHost16(uint16_t x) { return gbswap_16(x); } + +inline uint32_t FromHost32(uint32_t x) { return gbswap_32(x); } +inline uint32_t ToHost32(uint32_t x) { return gbswap_32(x); } + +inline uint64_t FromHost64(uint64_t x) { return gbswap_64(x); } +inline uint64_t ToHost64(uint64_t x) { return gbswap_64(x); } + +inline constexpr bool IsLittleEndian() { return false; } + +#endif /* ENDIAN */ + +// Functions to do unaligned loads and stores in little-endian order. +inline uint16_t Load16(const void *p) { + return ToHost16(ABSL_INTERNAL_UNALIGNED_LOAD16(p)); +} + +inline void Store16(void *p, uint16_t v) { + ABSL_INTERNAL_UNALIGNED_STORE16(p, FromHost16(v)); +} + +inline uint32_t Load32(const void *p) { + return ToHost32(ABSL_INTERNAL_UNALIGNED_LOAD32(p)); +} + +inline void Store32(void *p, uint32_t v) { + ABSL_INTERNAL_UNALIGNED_STORE32(p, FromHost32(v)); +} + +inline uint64_t Load64(const void *p) { + return ToHost64(ABSL_INTERNAL_UNALIGNED_LOAD64(p)); +} + +inline void Store64(void *p, uint64_t v) { + ABSL_INTERNAL_UNALIGNED_STORE64(p, FromHost64(v)); +} + +} // namespace little_endian + +// Utilities to convert numbers between the current hosts's native byte +// order and big-endian byte order (same as network byte order) +// +// Load/Store methods are alignment safe +namespace big_endian { +#ifdef ABSL_IS_LITTLE_ENDIAN + +inline uint16_t FromHost16(uint16_t x) { return gbswap_16(x); } +inline uint16_t ToHost16(uint16_t x) { return gbswap_16(x); } + +inline uint32_t FromHost32(uint32_t x) { return gbswap_32(x); } +inline uint32_t ToHost32(uint32_t x) { return gbswap_32(x); } + +inline uint64_t FromHost64(uint64_t x) { return gbswap_64(x); } +inline uint64_t ToHost64(uint64_t x) { return gbswap_64(x); } + +inline constexpr bool IsLittleEndian() { return true; } + +#elif defined ABSL_IS_BIG_ENDIAN + +inline uint16_t FromHost16(uint16_t x) { return x; } +inline uint16_t ToHost16(uint16_t x) { return x; } + +inline uint32_t FromHost32(uint32_t x) { return x; } +inline uint32_t ToHost32(uint32_t x) { return x; } + +inline uint64_t FromHost64(uint64_t x) { return x; } +inline uint64_t ToHost64(uint64_t x) { return x; } + +inline constexpr bool IsLittleEndian() { return false; } + +#endif /* ENDIAN */ + +// Functions to do unaligned loads and stores in big-endian order. +inline uint16_t Load16(const void *p) { + return ToHost16(ABSL_INTERNAL_UNALIGNED_LOAD16(p)); +} + +inline void Store16(void *p, uint16_t v) { + ABSL_INTERNAL_UNALIGNED_STORE16(p, FromHost16(v)); +} + +inline uint32_t Load32(const void *p) { + return ToHost32(ABSL_INTERNAL_UNALIGNED_LOAD32(p)); +} + +inline void Store32(void *p, uint32_t v) { + ABSL_INTERNAL_UNALIGNED_STORE32(p, FromHost32(v)); +} + +inline uint64_t Load64(const void *p) { + return ToHost64(ABSL_INTERNAL_UNALIGNED_LOAD64(p)); +} + +inline void Store64(void *p, uint64_t v) { + ABSL_INTERNAL_UNALIGNED_STORE64(p, FromHost64(v)); +} + +} // namespace big_endian + +} // namespace absl + +#endif // ABSL_BASE_INTERNAL_ENDIAN_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/endian_test.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/endian_test.cc new file mode 100644 index 0000000..e276915 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/endian_test.cc @@ -0,0 +1,263 @@ +// Copyright 2017 The Abseil Authors. +// +// 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 "absl/base/internal/endian.h" + +#include +#include +#include +#include +#include + +#include "gtest/gtest.h" +#include "absl/base/config.h" + +namespace absl { +namespace { + +const uint64_t kInitialNumber{0x0123456789abcdef}; +const uint64_t k64Value{kInitialNumber}; +const uint32_t k32Value{0x01234567}; +const uint16_t k16Value{0x0123}; +const int kNumValuesToTest = 1000000; +const int kRandomSeed = 12345; + +#if defined(ABSL_IS_BIG_ENDIAN) +const uint64_t kInitialInNetworkOrder{kInitialNumber}; +const uint64_t k64ValueLE{0xefcdab8967452301}; +const uint32_t k32ValueLE{0x67452301}; +const uint16_t k16ValueLE{0x2301}; + +const uint64_t k64ValueBE{kInitialNumber}; +const uint32_t k32ValueBE{k32Value}; +const uint16_t k16ValueBE{k16Value}; +#elif defined(ABSL_IS_LITTLE_ENDIAN) +const uint64_t kInitialInNetworkOrder{0xefcdab8967452301}; +const uint64_t k64ValueLE{kInitialNumber}; +const uint32_t k32ValueLE{k32Value}; +const uint16_t k16ValueLE{k16Value}; + +const uint64_t k64ValueBE{0xefcdab8967452301}; +const uint32_t k32ValueBE{0x67452301}; +const uint16_t k16ValueBE{0x2301}; +#endif + +template +std::vector GenerateAllValuesForType() { + std::vector result; + T next = std::numeric_limits::min(); + while (true) { + result.push_back(next); + if (next == std::numeric_limits::max()) { + return result; + } + ++next; + } +} + +template +std::vector GenerateRandomIntegers(size_t numValuesToTest) { + std::vector result; + std::mt19937_64 rng(kRandomSeed); + for (size_t i = 0; i < numValuesToTest; ++i) { + result.push_back(rng()); + } + return result; +} + +void ManualByteSwap(char* bytes, int length) { + if (length == 1) + return; + + EXPECT_EQ(0, length % 2); + for (int i = 0; i < length / 2; ++i) { + int j = (length - 1) - i; + using std::swap; + swap(bytes[i], bytes[j]); + } +} + +template +inline T UnalignedLoad(const char* p) { + static_assert( + sizeof(T) == 1 || sizeof(T) == 2 || sizeof(T) == 4 || sizeof(T) == 8, + "Unexpected type size"); + + switch (sizeof(T)) { + case 1: return *reinterpret_cast(p); + case 2: + return ABSL_INTERNAL_UNALIGNED_LOAD16(p); + case 4: + return ABSL_INTERNAL_UNALIGNED_LOAD32(p); + case 8: + return ABSL_INTERNAL_UNALIGNED_LOAD64(p); + default: + // Suppresses invalid "not all control paths return a value" on MSVC + return {}; + } +} + +template +static void GBSwapHelper(const std::vector& host_values_to_test, + const ByteSwapper& byte_swapper) { + // Test byte_swapper against a manual byte swap. + for (typename std::vector::const_iterator it = host_values_to_test.begin(); + it != host_values_to_test.end(); ++it) { + T host_value = *it; + + char actual_value[sizeof(host_value)]; + memcpy(actual_value, &host_value, sizeof(host_value)); + byte_swapper(actual_value); + + char expected_value[sizeof(host_value)]; + memcpy(expected_value, &host_value, sizeof(host_value)); + ManualByteSwap(expected_value, sizeof(host_value)); + + ASSERT_EQ(0, memcmp(actual_value, expected_value, sizeof(host_value))) + << "Swap output for 0x" << std::hex << host_value << " does not match. " + << "Expected: 0x" << UnalignedLoad(expected_value) << "; " + << "actual: 0x" << UnalignedLoad(actual_value); + } +} + +void Swap16(char* bytes) { + ABSL_INTERNAL_UNALIGNED_STORE16( + bytes, gbswap_16(ABSL_INTERNAL_UNALIGNED_LOAD16(bytes))); +} + +void Swap32(char* bytes) { + ABSL_INTERNAL_UNALIGNED_STORE32( + bytes, gbswap_32(ABSL_INTERNAL_UNALIGNED_LOAD32(bytes))); +} + +void Swap64(char* bytes) { + ABSL_INTERNAL_UNALIGNED_STORE64( + bytes, gbswap_64(ABSL_INTERNAL_UNALIGNED_LOAD64(bytes))); +} + +TEST(EndianessTest, Uint16) { + GBSwapHelper(GenerateAllValuesForType(), &Swap16); +} + +TEST(EndianessTest, Uint32) { + GBSwapHelper(GenerateRandomIntegers(kNumValuesToTest), &Swap32); +} + +TEST(EndianessTest, Uint64) { + GBSwapHelper(GenerateRandomIntegers(kNumValuesToTest), &Swap64); +} + +TEST(EndianessTest, ghtonll_gntohll) { + // Test that absl::ghtonl compiles correctly + uint32_t test = 0x01234567; + EXPECT_EQ(absl::gntohl(absl::ghtonl(test)), test); + + uint64_t comp = absl::ghtonll(kInitialNumber); + EXPECT_EQ(comp, kInitialInNetworkOrder); + comp = absl::gntohll(kInitialInNetworkOrder); + EXPECT_EQ(comp, kInitialNumber); + + // Test that htonll and ntohll are each others' inverse functions on a + // somewhat assorted batch of numbers. 37 is chosen to not be anything + // particularly nice base 2. + uint64_t value = 1; + for (int i = 0; i < 100; ++i) { + comp = absl::ghtonll(absl::gntohll(value)); + EXPECT_EQ(value, comp); + comp = absl::gntohll(absl::ghtonll(value)); + EXPECT_EQ(value, comp); + value *= 37; + } +} + +TEST(EndianessTest, little_endian) { + // Check little_endian uint16_t. + uint64_t comp = little_endian::FromHost16(k16Value); + EXPECT_EQ(comp, k16ValueLE); + comp = little_endian::ToHost16(k16ValueLE); + EXPECT_EQ(comp, k16Value); + + // Check little_endian uint32_t. + comp = little_endian::FromHost32(k32Value); + EXPECT_EQ(comp, k32ValueLE); + comp = little_endian::ToHost32(k32ValueLE); + EXPECT_EQ(comp, k32Value); + + // Check little_endian uint64_t. + comp = little_endian::FromHost64(k64Value); + EXPECT_EQ(comp, k64ValueLE); + comp = little_endian::ToHost64(k64ValueLE); + EXPECT_EQ(comp, k64Value); + + // Check little-endian Load and store functions. + uint16_t u16Buf; + uint32_t u32Buf; + uint64_t u64Buf; + + little_endian::Store16(&u16Buf, k16Value); + EXPECT_EQ(u16Buf, k16ValueLE); + comp = little_endian::Load16(&u16Buf); + EXPECT_EQ(comp, k16Value); + + little_endian::Store32(&u32Buf, k32Value); + EXPECT_EQ(u32Buf, k32ValueLE); + comp = little_endian::Load32(&u32Buf); + EXPECT_EQ(comp, k32Value); + + little_endian::Store64(&u64Buf, k64Value); + EXPECT_EQ(u64Buf, k64ValueLE); + comp = little_endian::Load64(&u64Buf); + EXPECT_EQ(comp, k64Value); +} + +TEST(EndianessTest, big_endian) { + // Check big-endian Load and store functions. + uint16_t u16Buf; + uint32_t u32Buf; + uint64_t u64Buf; + + unsigned char buffer[10]; + big_endian::Store16(&u16Buf, k16Value); + EXPECT_EQ(u16Buf, k16ValueBE); + uint64_t comp = big_endian::Load16(&u16Buf); + EXPECT_EQ(comp, k16Value); + + big_endian::Store32(&u32Buf, k32Value); + EXPECT_EQ(u32Buf, k32ValueBE); + comp = big_endian::Load32(&u32Buf); + EXPECT_EQ(comp, k32Value); + + big_endian::Store64(&u64Buf, k64Value); + EXPECT_EQ(u64Buf, k64ValueBE); + comp = big_endian::Load64(&u64Buf); + EXPECT_EQ(comp, k64Value); + + big_endian::Store16(buffer + 1, k16Value); + EXPECT_EQ(u16Buf, k16ValueBE); + comp = big_endian::Load16(buffer + 1); + EXPECT_EQ(comp, k16Value); + + big_endian::Store32(buffer + 1, k32Value); + EXPECT_EQ(u32Buf, k32ValueBE); + comp = big_endian::Load32(buffer + 1); + EXPECT_EQ(comp, k32Value); + + big_endian::Store64(buffer + 1, k64Value); + EXPECT_EQ(u64Buf, k64ValueBE); + comp = big_endian::Load64(buffer + 1); + EXPECT_EQ(comp, k64Value); +} + +} // namespace +} // namespace absl diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/exception_safety_testing.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/exception_safety_testing.cc new file mode 100644 index 0000000..8207b7d --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/exception_safety_testing.cc @@ -0,0 +1,75 @@ +// Copyright 2017 The Abseil Authors. +// +// 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 "absl/base/internal/exception_safety_testing.h" + +#include "gtest/gtest.h" +#include "absl/meta/type_traits.h" + +namespace testing { + +exceptions_internal::NoThrowTag nothrow_ctor; + +exceptions_internal::StrongGuaranteeTagType strong_guarantee; + +exceptions_internal::ExceptionSafetyTestBuilder<> MakeExceptionSafetyTester() { + return {}; +} + +namespace exceptions_internal { + +int countdown = -1; + +ConstructorTracker* ConstructorTracker::current_tracker_instance_ = nullptr; + +void MaybeThrow(absl::string_view msg, bool throw_bad_alloc) { + if (countdown-- == 0) { + if (throw_bad_alloc) throw TestBadAllocException(msg); + throw TestException(msg); + } +} + +testing::AssertionResult FailureMessage(const TestException& e, + int countdown) noexcept { + return testing::AssertionFailure() << "Exception thrown from " << e.what(); +} + +std::string GetSpecString(TypeSpec spec) { + std::string out; + absl::string_view sep; + const auto append = [&](absl::string_view s) { + absl::StrAppend(&out, sep, s); + sep = " | "; + }; + if (static_cast(TypeSpec::kNoThrowCopy & spec)) { + append("kNoThrowCopy"); + } + if (static_cast(TypeSpec::kNoThrowMove & spec)) { + append("kNoThrowMove"); + } + if (static_cast(TypeSpec::kNoThrowNew & spec)) { + append("kNoThrowNew"); + } + return out; +} + +std::string GetSpecString(AllocSpec spec) { + return static_cast(AllocSpec::kNoThrowAllocate & spec) + ? "kNoThrowAllocate" + : ""; +} + +} // namespace exceptions_internal + +} // namespace testing diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/exception_safety_testing.h b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/exception_safety_testing.h new file mode 100644 index 0000000..d4d41a8 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/exception_safety_testing.h @@ -0,0 +1,1094 @@ +// Copyright 2017 The Abseil Authors. +// +// 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. + +// Utilities for testing exception-safety + +#ifndef ABSL_BASE_INTERNAL_EXCEPTION_SAFETY_TESTING_H_ +#define ABSL_BASE_INTERNAL_EXCEPTION_SAFETY_TESTING_H_ + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gtest/gtest.h" +#include "absl/base/config.h" +#include "absl/base/internal/pretty_function.h" +#include "absl/memory/memory.h" +#include "absl/meta/type_traits.h" +#include "absl/strings/string_view.h" +#include "absl/strings/substitute.h" +#include "absl/utility/utility.h" + +namespace testing { + +enum class TypeSpec; +enum class AllocSpec; + +constexpr TypeSpec operator|(TypeSpec a, TypeSpec b) { + using T = absl::underlying_type_t; + return static_cast(static_cast(a) | static_cast(b)); +} + +constexpr TypeSpec operator&(TypeSpec a, TypeSpec b) { + using T = absl::underlying_type_t; + return static_cast(static_cast(a) & static_cast(b)); +} + +constexpr AllocSpec operator|(AllocSpec a, AllocSpec b) { + using T = absl::underlying_type_t; + return static_cast(static_cast(a) | static_cast(b)); +} + +constexpr AllocSpec operator&(AllocSpec a, AllocSpec b) { + using T = absl::underlying_type_t; + return static_cast(static_cast(a) & static_cast(b)); +} + +namespace exceptions_internal { + +std::string GetSpecString(TypeSpec); +std::string GetSpecString(AllocSpec); + +struct NoThrowTag {}; +struct StrongGuaranteeTagType {}; + +// A simple exception class. We throw this so that test code can catch +// exceptions specifically thrown by ThrowingValue. +class TestException { + public: + explicit TestException(absl::string_view msg) : msg_(msg) {} + virtual ~TestException() {} + virtual const char* what() const noexcept { return msg_.c_str(); } + + private: + std::string msg_; +}; + +// TestBadAllocException exists because allocation functions must throw an +// exception which can be caught by a handler of std::bad_alloc. We use a child +// class of std::bad_alloc so we can customise the error message, and also +// derive from TestException so we don't accidentally end up catching an actual +// bad_alloc exception in TestExceptionSafety. +class TestBadAllocException : public std::bad_alloc, public TestException { + public: + explicit TestBadAllocException(absl::string_view msg) : TestException(msg) {} + using TestException::what; +}; + +extern int countdown; + +// Allows the countdown variable to be set manually (defaulting to the initial +// value of 0) +inline void SetCountdown(int i = 0) { countdown = i; } +// Sets the countdown to the terminal value -1 +inline void UnsetCountdown() { SetCountdown(-1); } + +void MaybeThrow(absl::string_view msg, bool throw_bad_alloc = false); + +testing::AssertionResult FailureMessage(const TestException& e, + int countdown) noexcept; + +struct TrackedAddress { + bool is_alive; + std::string description; +}; + +// Inspects the constructions and destructions of anything inheriting from +// TrackedObject. This allows us to safely "leak" TrackedObjects, as +// ConstructorTracker will destroy everything left over in its destructor. +class ConstructorTracker { + public: + explicit ConstructorTracker(int count) : countdown_(count) { + assert(current_tracker_instance_ == nullptr); + current_tracker_instance_ = this; + } + + ~ConstructorTracker() { + assert(current_tracker_instance_ == this); + current_tracker_instance_ = nullptr; + + for (auto& it : address_map_) { + void* address = it.first; + TrackedAddress& tracked_address = it.second; + if (tracked_address.is_alive) { + ADD_FAILURE() << ErrorMessage(address, tracked_address.description, + countdown_, "Object was not destroyed."); + } + } + } + + static void ObjectConstructed(void* address, std::string description) { + if (!CurrentlyTracking()) return; + + TrackedAddress& tracked_address = + current_tracker_instance_->address_map_[address]; + if (tracked_address.is_alive) { + ADD_FAILURE() << ErrorMessage( + address, tracked_address.description, + current_tracker_instance_->countdown_, + "Object was re-constructed. Current object was constructed by " + + description); + } + tracked_address = {true, std::move(description)}; + } + + static void ObjectDestructed(void* address) { + if (!CurrentlyTracking()) return; + + auto it = current_tracker_instance_->address_map_.find(address); + // Not tracked. Ignore. + if (it == current_tracker_instance_->address_map_.end()) return; + + TrackedAddress& tracked_address = it->second; + if (!tracked_address.is_alive) { + ADD_FAILURE() << ErrorMessage(address, tracked_address.description, + current_tracker_instance_->countdown_, + "Object was re-destroyed."); + } + tracked_address.is_alive = false; + } + + private: + static bool CurrentlyTracking() { + return current_tracker_instance_ != nullptr; + } + + static std::string ErrorMessage(void* address, const std::string& address_description, + int countdown, const std::string& error_description) { + return absl::Substitute( + "With coundtown at $0:\n" + " $1\n" + " Object originally constructed by $2\n" + " Object address: $3\n", + countdown, error_description, address_description, address); + } + + std::unordered_map address_map_; + int countdown_; + + static ConstructorTracker* current_tracker_instance_; +}; + +class TrackedObject { + public: + TrackedObject(const TrackedObject&) = delete; + TrackedObject(TrackedObject&&) = delete; + + protected: + explicit TrackedObject(std::string description) { + ConstructorTracker::ObjectConstructed(this, std::move(description)); + } + + ~TrackedObject() noexcept { ConstructorTracker::ObjectDestructed(this); } +}; +} // namespace exceptions_internal + +extern exceptions_internal::NoThrowTag nothrow_ctor; + +extern exceptions_internal::StrongGuaranteeTagType strong_guarantee; + +// A test class which is convertible to bool. The conversion can be +// instrumented to throw at a controlled time. +class ThrowingBool { + public: + ThrowingBool(bool b) noexcept : b_(b) {} // NOLINT(runtime/explicit) + operator bool() const { // NOLINT + exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); + return b_; + } + + private: + bool b_; +}; + +/* + * Configuration enum for the ThrowingValue type that defines behavior for the + * lifetime of the instance. Use testing::nothrow_ctor to prevent the integer + * constructor from throwing. + * + * kEverythingThrows: Every operation can throw an exception + * kNoThrowCopy: Copy construction and copy assignment will not throw + * kNoThrowMove: Move construction and move assignment will not throw + * kNoThrowNew: Overloaded operators new and new[] will not throw + */ +enum class TypeSpec { + kEverythingThrows = 0, + kNoThrowCopy = 1, + kNoThrowMove = 1 << 1, + kNoThrowNew = 1 << 2, +}; + +/* + * A testing class instrumented to throw an exception at a controlled time. + * + * ThrowingValue implements a slightly relaxed version of the Regular concept -- + * that is it's a value type with the expected semantics. It also implements + * arithmetic operations. It doesn't implement member and pointer operators + * like operator-> or operator[]. + * + * ThrowingValue can be instrumented to have certain operations be noexcept by + * using compile-time bitfield template arguments. That is, to make an + * ThrowingValue which has noexcept move construction/assignment and noexcept + * copy construction/assignment, use the following: + * ThrowingValue my_thrwr{val}; + */ +template +class ThrowingValue : private exceptions_internal::TrackedObject { + static constexpr bool IsSpecified(TypeSpec spec) { + return static_cast(Spec & spec); + } + + static constexpr int kDefaultValue = 0; + static constexpr int kBadValue = 938550620; + + public: + ThrowingValue() : TrackedObject(GetInstanceString(kDefaultValue)) { + exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); + dummy_ = kDefaultValue; + } + + ThrowingValue(const ThrowingValue& other) noexcept( + IsSpecified(TypeSpec::kNoThrowCopy)) + : TrackedObject(GetInstanceString(other.dummy_)) { + if (!IsSpecified(TypeSpec::kNoThrowCopy)) { + exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); + } + dummy_ = other.dummy_; + } + + ThrowingValue(ThrowingValue&& other) noexcept( + IsSpecified(TypeSpec::kNoThrowMove)) + : TrackedObject(GetInstanceString(other.dummy_)) { + if (!IsSpecified(TypeSpec::kNoThrowMove)) { + exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); + } + dummy_ = other.dummy_; + } + + explicit ThrowingValue(int i) : TrackedObject(GetInstanceString(i)) { + exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); + dummy_ = i; + } + + ThrowingValue(int i, exceptions_internal::NoThrowTag) noexcept + : TrackedObject(GetInstanceString(i)), dummy_(i) {} + + // absl expects nothrow destructors + ~ThrowingValue() noexcept = default; + + ThrowingValue& operator=(const ThrowingValue& other) noexcept( + IsSpecified(TypeSpec::kNoThrowCopy)) { + dummy_ = kBadValue; + if (!IsSpecified(TypeSpec::kNoThrowCopy)) { + exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); + } + dummy_ = other.dummy_; + return *this; + } + + ThrowingValue& operator=(ThrowingValue&& other) noexcept( + IsSpecified(TypeSpec::kNoThrowMove)) { + dummy_ = kBadValue; + if (!IsSpecified(TypeSpec::kNoThrowMove)) { + exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); + } + dummy_ = other.dummy_; + return *this; + } + + // Arithmetic Operators + ThrowingValue operator+(const ThrowingValue& other) const { + exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); + return ThrowingValue(dummy_ + other.dummy_, nothrow_ctor); + } + + ThrowingValue operator+() const { + exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); + return ThrowingValue(dummy_, nothrow_ctor); + } + + ThrowingValue operator-(const ThrowingValue& other) const { + exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); + return ThrowingValue(dummy_ - other.dummy_, nothrow_ctor); + } + + ThrowingValue operator-() const { + exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); + return ThrowingValue(-dummy_, nothrow_ctor); + } + + ThrowingValue& operator++() { + exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); + ++dummy_; + return *this; + } + + ThrowingValue operator++(int) { + exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); + auto out = ThrowingValue(dummy_, nothrow_ctor); + ++dummy_; + return out; + } + + ThrowingValue& operator--() { + exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); + --dummy_; + return *this; + } + + ThrowingValue operator--(int) { + exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); + auto out = ThrowingValue(dummy_, nothrow_ctor); + --dummy_; + return out; + } + + ThrowingValue operator*(const ThrowingValue& other) const { + exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); + return ThrowingValue(dummy_ * other.dummy_, nothrow_ctor); + } + + ThrowingValue operator/(const ThrowingValue& other) const { + exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); + return ThrowingValue(dummy_ / other.dummy_, nothrow_ctor); + } + + ThrowingValue operator%(const ThrowingValue& other) const { + exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); + return ThrowingValue(dummy_ % other.dummy_, nothrow_ctor); + } + + ThrowingValue operator<<(int shift) const { + exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); + return ThrowingValue(dummy_ << shift, nothrow_ctor); + } + + ThrowingValue operator>>(int shift) const { + exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); + return ThrowingValue(dummy_ >> shift, nothrow_ctor); + } + + // Comparison Operators + // NOTE: We use `ThrowingBool` instead of `bool` because most STL + // types/containers requires T to be convertible to bool. + friend ThrowingBool operator==(const ThrowingValue& a, + const ThrowingValue& b) { + exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); + return a.dummy_ == b.dummy_; + } + friend ThrowingBool operator!=(const ThrowingValue& a, + const ThrowingValue& b) { + exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); + return a.dummy_ != b.dummy_; + } + friend ThrowingBool operator<(const ThrowingValue& a, + const ThrowingValue& b) { + exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); + return a.dummy_ < b.dummy_; + } + friend ThrowingBool operator<=(const ThrowingValue& a, + const ThrowingValue& b) { + exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); + return a.dummy_ <= b.dummy_; + } + friend ThrowingBool operator>(const ThrowingValue& a, + const ThrowingValue& b) { + exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); + return a.dummy_ > b.dummy_; + } + friend ThrowingBool operator>=(const ThrowingValue& a, + const ThrowingValue& b) { + exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); + return a.dummy_ >= b.dummy_; + } + + // Logical Operators + ThrowingBool operator!() const { + exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); + return !dummy_; + } + + ThrowingBool operator&&(const ThrowingValue& other) const { + exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); + return dummy_ && other.dummy_; + } + + ThrowingBool operator||(const ThrowingValue& other) const { + exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); + return dummy_ || other.dummy_; + } + + // Bitwise Logical Operators + ThrowingValue operator~() const { + exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); + return ThrowingValue(~dummy_, nothrow_ctor); + } + + ThrowingValue operator&(const ThrowingValue& other) const { + exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); + return ThrowingValue(dummy_ & other.dummy_, nothrow_ctor); + } + + ThrowingValue operator|(const ThrowingValue& other) const { + exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); + return ThrowingValue(dummy_ | other.dummy_, nothrow_ctor); + } + + ThrowingValue operator^(const ThrowingValue& other) const { + exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); + return ThrowingValue(dummy_ ^ other.dummy_, nothrow_ctor); + } + + // Compound Assignment operators + ThrowingValue& operator+=(const ThrowingValue& other) { + exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); + dummy_ += other.dummy_; + return *this; + } + + ThrowingValue& operator-=(const ThrowingValue& other) { + exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); + dummy_ -= other.dummy_; + return *this; + } + + ThrowingValue& operator*=(const ThrowingValue& other) { + exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); + dummy_ *= other.dummy_; + return *this; + } + + ThrowingValue& operator/=(const ThrowingValue& other) { + exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); + dummy_ /= other.dummy_; + return *this; + } + + ThrowingValue& operator%=(const ThrowingValue& other) { + exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); + dummy_ %= other.dummy_; + return *this; + } + + ThrowingValue& operator&=(const ThrowingValue& other) { + exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); + dummy_ &= other.dummy_; + return *this; + } + + ThrowingValue& operator|=(const ThrowingValue& other) { + exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); + dummy_ |= other.dummy_; + return *this; + } + + ThrowingValue& operator^=(const ThrowingValue& other) { + exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); + dummy_ ^= other.dummy_; + return *this; + } + + ThrowingValue& operator<<=(int shift) { + exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); + dummy_ <<= shift; + return *this; + } + + ThrowingValue& operator>>=(int shift) { + exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); + dummy_ >>= shift; + return *this; + } + + // Pointer operators + void operator&() const = delete; // NOLINT(runtime/operator) + + // Stream operators + friend std::ostream& operator<<(std::ostream& os, const ThrowingValue& tv) { + exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); + return os << GetInstanceString(tv.dummy_); + } + + friend std::istream& operator>>(std::istream& is, const ThrowingValue&) { + exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); + return is; + } + + // Memory management operators + // Args.. allows us to overload regular and placement new in one shot + template + static void* operator new(size_t s, Args&&... args) noexcept( + IsSpecified(TypeSpec::kNoThrowNew)) { + if (!IsSpecified(TypeSpec::kNoThrowNew)) { + exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION, true); + } + return ::operator new(s, std::forward(args)...); + } + + template + static void* operator new[](size_t s, Args&&... args) noexcept( + IsSpecified(TypeSpec::kNoThrowNew)) { + if (!IsSpecified(TypeSpec::kNoThrowNew)) { + exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION, true); + } + return ::operator new[](s, std::forward(args)...); + } + + // Abseil doesn't support throwing overloaded operator delete. These are + // provided so a throwing operator-new can clean up after itself. + // + // We provide both regular and templated operator delete because if only the + // templated version is provided as we did with operator new, the compiler has + // no way of knowing which overload of operator delete to call. See + // http://en.cppreference.com/w/cpp/memory/new/operator_delete and + // http://en.cppreference.com/w/cpp/language/delete for the gory details. + void operator delete(void* p) noexcept { ::operator delete(p); } + + template + void operator delete(void* p, Args&&... args) noexcept { + ::operator delete(p, std::forward(args)...); + } + + void operator delete[](void* p) noexcept { return ::operator delete[](p); } + + template + void operator delete[](void* p, Args&&... args) noexcept { + return ::operator delete[](p, std::forward(args)...); + } + + // Non-standard access to the actual contained value. No need for this to + // throw. + int& Get() noexcept { return dummy_; } + const int& Get() const noexcept { return dummy_; } + + private: + static std::string GetInstanceString(int dummy) { + return absl::StrCat("ThrowingValue<", + exceptions_internal::GetSpecString(Spec), ">(", dummy, + ")"); + } + + int dummy_; +}; +// While not having to do with exceptions, explicitly delete comma operator, to +// make sure we don't use it on user-supplied types. +template +void operator,(const ThrowingValue&, T&&) = delete; +template +void operator,(T&&, const ThrowingValue&) = delete; + +/* + * Configuration enum for the ThrowingAllocator type that defines behavior for + * the lifetime of the instance. + * + * kEverythingThrows: Calls to the member functions may throw + * kNoThrowAllocate: Calls to the member functions will not throw + */ +enum class AllocSpec { + kEverythingThrows = 0, + kNoThrowAllocate = 1, +}; + +/* + * An allocator type which is instrumented to throw at a controlled time, or not + * to throw, using AllocSpec. The supported settings are the default of every + * function which is allowed to throw in a conforming allocator possibly + * throwing, or nothing throws, in line with the ABSL_ALLOCATOR_THROWS + * configuration macro. + */ +template +class ThrowingAllocator : private exceptions_internal::TrackedObject { + static constexpr bool IsSpecified(AllocSpec spec) { + return static_cast(Spec & spec); + } + + public: + using pointer = T*; + using const_pointer = const T*; + using reference = T&; + using const_reference = const T&; + using void_pointer = void*; + using const_void_pointer = const void*; + using value_type = T; + using size_type = size_t; + using difference_type = ptrdiff_t; + + using is_nothrow = + std::integral_constant; + using propagate_on_container_copy_assignment = std::true_type; + using propagate_on_container_move_assignment = std::true_type; + using propagate_on_container_swap = std::true_type; + using is_always_equal = std::false_type; + + ThrowingAllocator() : TrackedObject(GetInstanceString(next_id_)) { + exceptions_internal::MaybeThrow(ABSL_PRETTY_FUNCTION); + dummy_ = std::make_shared(next_id_++); + } + + template + ThrowingAllocator(const ThrowingAllocator& other) noexcept // NOLINT + : TrackedObject(GetInstanceString(*other.State())), + dummy_(other.State()) {} + + // According to C++11 standard [17.6.3.5], Table 28, the move/copy ctors of + // allocator shall not exit via an exception, thus they are marked noexcept. + ThrowingAllocator(const ThrowingAllocator& other) noexcept + : TrackedObject(GetInstanceString(*other.State())), + dummy_(other.State()) {} + + template + ThrowingAllocator(ThrowingAllocator&& other) noexcept // NOLINT + : TrackedObject(GetInstanceString(*other.State())), + dummy_(std::move(other.State())) {} + + ThrowingAllocator(ThrowingAllocator&& other) noexcept + : TrackedObject(GetInstanceString(*other.State())), + dummy_(std::move(other.State())) {} + + ~ThrowingAllocator() noexcept = default; + + ThrowingAllocator& operator=(const ThrowingAllocator& other) noexcept { + dummy_ = other.State(); + return *this; + } + + template + ThrowingAllocator& operator=( + const ThrowingAllocator& other) noexcept { + dummy_ = other.State(); + return *this; + } + + template + ThrowingAllocator& operator=(ThrowingAllocator&& other) noexcept { + dummy_ = std::move(other.State()); + return *this; + } + + template + struct rebind { + using other = ThrowingAllocator; + }; + + pointer allocate(size_type n) noexcept( + IsSpecified(AllocSpec::kNoThrowAllocate)) { + ReadStateAndMaybeThrow(ABSL_PRETTY_FUNCTION); + return static_cast(::operator new(n * sizeof(T))); + } + + pointer allocate(size_type n, const_void_pointer) noexcept( + IsSpecified(AllocSpec::kNoThrowAllocate)) { + return allocate(n); + } + + void deallocate(pointer ptr, size_type) noexcept { + ReadState(); + ::operator delete(static_cast(ptr)); + } + + template + void construct(U* ptr, Args&&... args) noexcept( + IsSpecified(AllocSpec::kNoThrowAllocate)) { + ReadStateAndMaybeThrow(ABSL_PRETTY_FUNCTION); + ::new (static_cast(ptr)) U(std::forward(args)...); + } + + template + void destroy(U* p) noexcept { + ReadState(); + p->~U(); + } + + size_type max_size() const noexcept { + return (std::numeric_limits::max)() / sizeof(value_type); + } + + ThrowingAllocator select_on_container_copy_construction() noexcept( + IsSpecified(AllocSpec::kNoThrowAllocate)) { + auto& out = *this; + ReadStateAndMaybeThrow(ABSL_PRETTY_FUNCTION); + return out; + } + + template + bool operator==(const ThrowingAllocator& other) const noexcept { + return dummy_ == other.dummy_; + } + + template + bool operator!=(const ThrowingAllocator& other) const noexcept { + return dummy_ != other.dummy_; + } + + template + friend class ThrowingAllocator; + + private: + static std::string GetInstanceString(int dummy) { + return absl::StrCat("ThrowingAllocator<", + exceptions_internal::GetSpecString(Spec), ">(", dummy, + ")"); + } + + const std::shared_ptr& State() const { return dummy_; } + std::shared_ptr& State() { return dummy_; } + + void ReadState() { + // we know that this will never be true, but the compiler doesn't, so this + // should safely force a read of the value. + if (*dummy_ < 0) std::abort(); + } + + void ReadStateAndMaybeThrow(absl::string_view msg) const { + if (!IsSpecified(AllocSpec::kNoThrowAllocate)) { + exceptions_internal::MaybeThrow( + absl::Substitute("Allocator id $0 threw from $1", *dummy_, msg)); + } + } + + static int next_id_; + std::shared_ptr dummy_; +}; + +template +int ThrowingAllocator::next_id_ = 0; + +// Tests for resource leaks by attempting to construct a T using args repeatedly +// until successful, using the countdown method. Side effects can then be +// tested for resource leaks. +template +void TestThrowingCtor(Args&&... args) { + struct Cleanup { + ~Cleanup() { exceptions_internal::UnsetCountdown(); } + } c; + for (int count = 0;; ++count) { + exceptions_internal::ConstructorTracker ct(count); + exceptions_internal::SetCountdown(count); + try { + T temp(std::forward(args)...); + static_cast(temp); + break; + } catch (const exceptions_internal::TestException&) { + } + } +} + +// Tests the nothrow guarantee of the provided nullary operation. If the an +// exception is thrown, the result will be AssertionFailure(). Otherwise, it +// will be AssertionSuccess(). +template +testing::AssertionResult TestNothrowOp(const Operation& operation) { + struct Cleanup { + Cleanup() { exceptions_internal::SetCountdown(); } + ~Cleanup() { exceptions_internal::UnsetCountdown(); } + } c; + try { + operation(); + return testing::AssertionSuccess(); + } catch (const exceptions_internal::TestException&) { + return testing::AssertionFailure() + << "TestException thrown during call to operation() when nothrow " + "guarantee was expected."; + } catch (...) { + return testing::AssertionFailure() + << "Unknown exception thrown during call to operation() when " + "nothrow guarantee was expected."; + } +} + +namespace exceptions_internal { + +// Dummy struct for ExceptionSafetyTestBuilder<> partial state. +struct UninitializedT {}; + +template +class DefaultFactory { + public: + explicit DefaultFactory(const T& t) : t_(t) {} + std::unique_ptr operator()() const { return absl::make_unique(t_); } + + private: + T t_; +}; + +template +using EnableIfTestable = typename absl::enable_if_t< + LazyContractsCount != 0 && + !std::is_same::value && + !std::is_same::value>; + +template +class ExceptionSafetyTestBuilder; + +} // namespace exceptions_internal + +/* + * Constructs an empty ExceptionSafetyTestBuilder. All + * ExceptionSafetyTestBuilder objects are immutable and all With[thing] mutation + * methods return new instances of ExceptionSafetyTestBuilder. + * + * In order to test a T for exception safety, a factory for that T, a testable + * operation, and at least one contract callback returning an assertion + * result must be applied using the respective methods. + */ +exceptions_internal::ExceptionSafetyTestBuilder<> MakeExceptionSafetyTester(); + +namespace exceptions_internal { +template +struct IsUniquePtr : std::false_type {}; + +template +struct IsUniquePtr> : std::true_type {}; + +template +struct FactoryPtrTypeHelper { + using type = decltype(std::declval()()); + + static_assert(IsUniquePtr::value, "Factories must return a unique_ptr"); +}; + +template +using FactoryPtrType = typename FactoryPtrTypeHelper::type; + +template +using FactoryElementType = typename FactoryPtrType::element_type; + +template +class ExceptionSafetyTest { + using Factory = std::function()>; + using Operation = std::function; + using Contract = std::function; + + public: + template + explicit ExceptionSafetyTest(const Factory& f, const Operation& op, + const Contracts&... contracts) + : factory_(f), operation_(op), contracts_{WrapContract(contracts)...} {} + + AssertionResult Test() const { + for (int count = 0;; ++count) { + exceptions_internal::ConstructorTracker ct(count); + + for (const auto& contract : contracts_) { + auto t_ptr = factory_(); + try { + SetCountdown(count); + operation_(t_ptr.get()); + // Unset for the case that the operation throws no exceptions, which + // would leave the countdown set and break the *next* exception safety + // test after this one. + UnsetCountdown(); + return AssertionSuccess(); + } catch (const exceptions_internal::TestException& e) { + if (!contract(t_ptr.get())) { + return AssertionFailure() << e.what() << " failed contract check"; + } + } + } + } + } + + private: + template + Contract WrapContract(const ContractFn& contract) { + return [contract](T* t_ptr) { return AssertionResult(contract(t_ptr)); }; + } + + Contract WrapContract(StrongGuaranteeTagType) { + return [this](T* t_ptr) { return AssertionResult(*factory_() == *t_ptr); }; + } + + Factory factory_; + Operation operation_; + std::vector contracts_; +}; + +/* + * Builds a tester object that tests if performing a operation on a T follows + * exception safety guarantees. Verification is done via contract assertion + * callbacks applied to T instances post-throw. + * + * Template parameters for ExceptionSafetyTestBuilder: + * + * - Factory: The factory object (passed in via tester.WithFactory(...) or + * tester.WithInitialValue(...)) must be invocable with the signature + * `std::unique_ptr operator()() const` where T is the type being tested. + * It is used for reliably creating identical T instances to test on. + * + * - Operation: The operation object (passsed in via tester.WithOperation(...) + * or tester.Test(...)) must be invocable with the signature + * `void operator()(T*) const` where T is the type being tested. It is used + * for performing steps on a T instance that may throw and that need to be + * checked for exception safety. Each call to the operation will receive a + * fresh T instance so it's free to modify and destroy the T instances as it + * pleases. + * + * - Contracts...: The contract assertion callback objects (passed in via + * tester.WithContracts(...)) must be invocable with the signature + * `testing::AssertionResult operator()(T*) const` where T is the type being + * tested. Contract assertion callbacks are provided T instances post-throw. + * They must return testing::AssertionSuccess when the type contracts of the + * provided T instance hold. If the type contracts of the T instance do not + * hold, they must return testing::AssertionFailure. Execution order of + * Contracts... is unspecified. They will each individually get a fresh T + * instance so they are free to modify and destroy the T instances as they + * please. + */ +template +class ExceptionSafetyTestBuilder { + public: + /* + * Returns a new ExceptionSafetyTestBuilder with an included T factory based + * on the provided T instance. The existing factory will not be included in + * the newly created tester instance. The created factory returns a new T + * instance by copy-constructing the provided const T& t. + * + * Preconditions for tester.WithInitialValue(const T& t): + * + * - The const T& t object must be copy-constructible where T is the type + * being tested. For non-copy-constructible objects, use the method + * tester.WithFactory(...). + */ + template + ExceptionSafetyTestBuilder, Operation, Contracts...> + WithInitialValue(const T& t) const { + return WithFactory(DefaultFactory(t)); + } + + /* + * Returns a new ExceptionSafetyTestBuilder with the provided T factory + * included. The existing factory will not be included in the newly-created + * tester instance. This method is intended for use with types lacking a copy + * constructor. Types that can be copy-constructed should instead use the + * method tester.WithInitialValue(...). + */ + template + ExceptionSafetyTestBuilder, Operation, Contracts...> + WithFactory(const NewFactory& new_factory) const { + return {new_factory, operation_, contracts_}; + } + + /* + * Returns a new ExceptionSafetyTestBuilder with the provided testable + * operation included. The existing operation will not be included in the + * newly created tester. + */ + template + ExceptionSafetyTestBuilder, Contracts...> + WithOperation(const NewOperation& new_operation) const { + return {factory_, new_operation, contracts_}; + } + + /* + * Returns a new ExceptionSafetyTestBuilder with the provided MoreContracts... + * combined with the Contracts... that were already included in the instance + * on which the method was called. Contracts... cannot be removed or replaced + * once added to an ExceptionSafetyTestBuilder instance. A fresh object must + * be created in order to get an empty Contracts... list. + * + * In addition to passing in custom contract assertion callbacks, this method + * accepts `testing::strong_guarantee` as an argument which checks T instances + * post-throw against freshly created T instances via operator== to verify + * that any state changes made during the execution of the operation were + * properly rolled back. + */ + template + ExceptionSafetyTestBuilder...> + WithContracts(const MoreContracts&... more_contracts) const { + return { + factory_, operation_, + std::tuple_cat(contracts_, std::tuple...>( + more_contracts...))}; + } + + /* + * Returns a testing::AssertionResult that is the reduced result of the + * exception safety algorithm. The algorithm short circuits and returns + * AssertionFailure after the first contract callback returns an + * AssertionFailure. Otherwise, if all contract callbacks return an + * AssertionSuccess, the reduced result is AssertionSuccess. + * + * The passed-in testable operation will not be saved in a new tester instance + * nor will it modify/replace the existing tester instance. This is useful + * when each operation being tested is unique and does not need to be reused. + * + * Preconditions for tester.Test(const NewOperation& new_operation): + * + * - May only be called after at least one contract assertion callback and a + * factory or initial value have been provided. + */ + template < + typename NewOperation, + typename = EnableIfTestable> + testing::AssertionResult Test(const NewOperation& new_operation) const { + return TestImpl(new_operation, absl::index_sequence_for()); + } + + /* + * Returns a testing::AssertionResult that is the reduced result of the + * exception safety algorithm. The algorithm short circuits and returns + * AssertionFailure after the first contract callback returns an + * AssertionFailure. Otherwise, if all contract callbacks return an + * AssertionSuccess, the reduced result is AssertionSuccess. + * + * Preconditions for tester.Test(): + * + * - May only be called after at least one contract assertion callback, a + * factory or initial value and a testable operation have been provided. + */ + template < + typename LazyOperation = Operation, + typename = EnableIfTestable> + testing::AssertionResult Test() const { + return Test(operation_); + } + + private: + template + friend class ExceptionSafetyTestBuilder; + + friend ExceptionSafetyTestBuilder<> testing::MakeExceptionSafetyTester(); + + ExceptionSafetyTestBuilder() {} + + ExceptionSafetyTestBuilder(const Factory& f, const Operation& o, + const std::tuple& i) + : factory_(f), operation_(o), contracts_(i) {} + + template + testing::AssertionResult TestImpl(SelectedOperation selected_operation, + absl::index_sequence) const { + return ExceptionSafetyTest>( + factory_, selected_operation, std::get(contracts_)...) + .Test(); + } + + Factory factory_; + Operation operation_; + std::tuple contracts_; +}; + +} // namespace exceptions_internal + +} // namespace testing + +#endif // ABSL_BASE_INTERNAL_EXCEPTION_SAFETY_TESTING_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/exception_testing.h b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/exception_testing.h new file mode 100644 index 0000000..0cf7918 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/exception_testing.h @@ -0,0 +1,42 @@ +// Copyright 2017 The Abseil Authors. +// +// 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. + +// Testing utilities for ABSL types which throw exceptions. + +#ifndef ABSL_BASE_INTERNAL_EXCEPTION_TESTING_H_ +#define ABSL_BASE_INTERNAL_EXCEPTION_TESTING_H_ + +#include "gtest/gtest.h" +#include "absl/base/config.h" + +// ABSL_BASE_INTERNAL_EXPECT_FAIL tests either for a specified thrown exception +// if exceptions are enabled, or for death with a specified text in the error +// message +#ifdef ABSL_HAVE_EXCEPTIONS + +#define ABSL_BASE_INTERNAL_EXPECT_FAIL(expr, exception_t, text) \ + EXPECT_THROW(expr, exception_t) + +#elif defined(__ANDROID__) +// Android asserts do not log anywhere that gtest can currently inspect. +// So we expect exit, but cannot match the message. +#define ABSL_BASE_INTERNAL_EXPECT_FAIL(expr, exception_t, text) \ + EXPECT_DEATH(expr, ".*") +#else +#define ABSL_BASE_INTERNAL_EXPECT_FAIL(expr, exception_t, text) \ + EXPECT_DEATH_IF_SUPPORTED(expr, text) + +#endif + +#endif // ABSL_BASE_INTERNAL_EXCEPTION_TESTING_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/hide_ptr.h b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/hide_ptr.h new file mode 100644 index 0000000..45cf438 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/hide_ptr.h @@ -0,0 +1,47 @@ +// Copyright 2018 The Abseil Authors. +// +// 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. + +#ifndef ABSL_BASE_INTERNAL_HIDE_PTR_H_ +#define ABSL_BASE_INTERNAL_HIDE_PTR_H_ + +#include + +namespace absl { +namespace base_internal { + +// Arbitrary value with high bits set. Xor'ing with it is unlikely +// to map one valid pointer to another valid pointer. +constexpr uintptr_t HideMask() { + return (uintptr_t{0xF03A5F7BU} << (sizeof(uintptr_t) - 4) * 8) | 0xF03A5F7BU; +} + +// Hide a pointer from the leak checker. For internal use only. +// Differs from absl::IgnoreLeak(ptr) in that absl::IgnoreLeak(ptr) causes ptr +// and all objects reachable from ptr to be ignored by the leak checker. +template +inline uintptr_t HidePtr(T* ptr) { + return reinterpret_cast(ptr) ^ HideMask(); +} + +// Return a pointer that has been hidden from the leak checker. +// For internal use only. +template +inline T* UnhidePtr(uintptr_t hidden) { + return reinterpret_cast(hidden ^ HideMask()); +} + +} // namespace base_internal +} // namespace absl + +#endif // ABSL_BASE_INTERNAL_HIDE_PTR_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/identity.h b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/identity.h new file mode 100644 index 0000000..a1a5d70 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/identity.h @@ -0,0 +1,33 @@ +// Copyright 2017 The Abseil Authors. +// +// 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. +// + +#ifndef ABSL_BASE_INTERNAL_IDENTITY_H_ +#define ABSL_BASE_INTERNAL_IDENTITY_H_ + +namespace absl { +namespace internal { + +template +struct identity { + typedef T type; +}; + +template +using identity_t = typename identity::type; + +} // namespace internal +} // namespace absl + +#endif // ABSL_BASE_INTERNAL_IDENTITY_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/inline_variable.h b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/inline_variable.h new file mode 100644 index 0000000..f7bb8c5 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/inline_variable.h @@ -0,0 +1,107 @@ +// Copyright 2017 The Abseil Authors. +// +// 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. + +#ifndef ABSL_BASE_INTERNAL_INLINE_VARIABLE_EMULATION_H_ +#define ABSL_BASE_INTERNAL_INLINE_VARIABLE_EMULATION_H_ + +#include + +#include "absl/base/internal/identity.h" + +// File: +// This file define a macro that allows the creation of or emulation of C++17 +// inline variables based on whether or not the feature is supported. + +//////////////////////////////////////////////////////////////////////////////// +// Macro: ABSL_INTERNAL_INLINE_CONSTEXPR(type, name, init) +// +// Description: +// Expands to the equivalent of an inline constexpr instance of the specified +// `type` and `name`, initialized to the value `init`. If the compiler being +// used is detected as supporting actual inline variables as a language +// feature, then the macro expands to an actual inline variable definition. +// +// Requires: +// `type` is a type that is usable in an extern variable declaration. +// +// Requires: `name` is a valid identifier +// +// Requires: +// `init` is an expression that can be used in the following definition: +// constexpr type name = init; +// +// Usage: +// +// // Equivalent to: `inline constexpr size_t variant_npos = -1;` +// ABSL_INTERNAL_INLINE_CONSTEXPR(size_t, variant_npos, -1); +// +// Differences in implementation: +// For a direct, language-level inline variable, decltype(name) will be the +// type that was specified along with const qualification, whereas for +// emulated inline variables, decltype(name) may be different (in practice +// it will likely be a reference type). +//////////////////////////////////////////////////////////////////////////////// + +#ifdef __cpp_inline_variables + +// Clang's -Wmissing-variable-declarations option erroneously warned that +// inline constexpr objects need to be pre-declared. This has now been fixed, +// but we will need to support this workaround for people building with older +// versions of clang. +// +// Bug: https://bugs.llvm.org/show_bug.cgi?id=35862 +// +// Note: +// identity_t is used here so that the const and name are in the +// appropriate place for pointer types, reference types, function pointer +// types, etc.. +#if defined(__clang__) +#define ABSL_INTERNAL_EXTERN_DECL(type, name) \ + extern const ::absl::internal::identity_t name; +#else // Otherwise, just define the macro to do nothing. +#define ABSL_INTERNAL_EXTERN_DECL(type, name) +#endif // defined(__clang__) + +// See above comment at top of file for details. +#define ABSL_INTERNAL_INLINE_CONSTEXPR(type, name, init) \ + ABSL_INTERNAL_EXTERN_DECL(type, name) \ + inline constexpr ::absl::internal::identity_t name = init + +#else + +// See above comment at top of file for details. +// +// Note: +// identity_t is used here so that the const and name are in the +// appropriate place for pointer types, reference types, function pointer +// types, etc.. +#define ABSL_INTERNAL_INLINE_CONSTEXPR(var_type, name, init) \ + template \ + struct AbslInternalInlineVariableHolder##name { \ + static constexpr ::absl::internal::identity_t kInstance = init; \ + }; \ + \ + template \ + constexpr ::absl::internal::identity_t \ + AbslInternalInlineVariableHolder##name::kInstance; \ + \ + static constexpr const ::absl::internal::identity_t& \ + name = /* NOLINT */ \ + AbslInternalInlineVariableHolder##name<>::kInstance; \ + static_assert(sizeof(void (*)(decltype(name))) != 0, \ + "Silence unused variable warnings.") + +#endif // __cpp_inline_variables + +#endif // ABSL_BASE_INTERNAL_INLINE_VARIABLE_EMULATION_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/inline_variable_testing.h b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/inline_variable_testing.h new file mode 100644 index 0000000..a0dd2bb --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/inline_variable_testing.h @@ -0,0 +1,44 @@ +// Copyright 2017 The Abseil Authors. +// +// 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. + +#ifndef ABSL_BASE_INLINE_VARIABLE_TESTING_H_ +#define ABSL_BASE_INLINE_VARIABLE_TESTING_H_ + +#include "absl/base/internal/inline_variable.h" + +namespace absl { +namespace inline_variable_testing_internal { + +struct Foo { + int value = 5; +}; + +ABSL_INTERNAL_INLINE_CONSTEXPR(Foo, inline_variable_foo, {}); +ABSL_INTERNAL_INLINE_CONSTEXPR(Foo, other_inline_variable_foo, {}); + +ABSL_INTERNAL_INLINE_CONSTEXPR(int, inline_variable_int, 5); +ABSL_INTERNAL_INLINE_CONSTEXPR(int, other_inline_variable_int, 5); + +ABSL_INTERNAL_INLINE_CONSTEXPR(void(*)(), inline_variable_fun_ptr, nullptr); + +const Foo& get_foo_a(); +const Foo& get_foo_b(); + +const int& get_int_a(); +const int& get_int_b(); + +} // namespace inline_variable_testing_internal +} // namespace absl + +#endif // ABSL_BASE_INLINE_VARIABLE_TESTING_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/invoke.h b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/invoke.h new file mode 100644 index 0000000..8c3f4f6 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/invoke.h @@ -0,0 +1,188 @@ +// Copyright 2017 The Abseil Authors. +// +// 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. +// +// absl::base_internal::Invoke(f, args...) is an implementation of +// INVOKE(f, args...) from section [func.require] of the C++ standard. +// +// [func.require] +// Define INVOKE (f, t1, t2, ..., tN) as follows: +// 1. (t1.*f)(t2, ..., tN) when f is a pointer to a member function of a class T +// and t1 is an object of type T or a reference to an object of type T or a +// reference to an object of a type derived from T; +// 2. ((*t1).*f)(t2, ..., tN) when f is a pointer to a member function of a +// class T and t1 is not one of the types described in the previous item; +// 3. t1.*f when N == 1 and f is a pointer to member data of a class T and t1 is +// an object of type T or a reference to an object of type T or a reference +// to an object of a type derived from T; +// 4. (*t1).*f when N == 1 and f is a pointer to member data of a class T and t1 +// is not one of the types described in the previous item; +// 5. f(t1, t2, ..., tN) in all other cases. +// +// The implementation is SFINAE-friendly: substitution failure within Invoke() +// isn't an error. + +#ifndef ABSL_BASE_INTERNAL_INVOKE_H_ +#define ABSL_BASE_INTERNAL_INVOKE_H_ + +#include +#include +#include + +// The following code is internal implementation detail. See the comment at the +// top of this file for the API documentation. + +namespace absl { +namespace base_internal { + +// The five classes below each implement one of the clauses from the definition +// of INVOKE. The inner class template Accept checks whether the +// clause is applicable; static function template Invoke(f, args...) does the +// invocation. +// +// By separating the clause selection logic from invocation we make sure that +// Invoke() does exactly what the standard says. + +template +struct StrippedAccept { + template + struct Accept : Derived::template AcceptImpl::type>::type...> {}; +}; + +// (t1.*f)(t2, ..., tN) when f is a pointer to a member function of a class T +// and t1 is an object of type T or a reference to an object of type T or a +// reference to an object of a type derived from T. +struct MemFunAndRef : StrippedAccept { + template + struct AcceptImpl : std::false_type {}; + + template + struct AcceptImpl + : std::is_base_of {}; + + template + struct AcceptImpl + : std::is_base_of {}; + + template + static decltype((std::declval().* + std::declval())(std::declval()...)) + Invoke(MemFun&& mem_fun, Obj&& obj, Args&&... args) { + return (std::forward(obj).* + std::forward(mem_fun))(std::forward(args)...); + } +}; + +// ((*t1).*f)(t2, ..., tN) when f is a pointer to a member function of a +// class T and t1 is not one of the types described in the previous item. +struct MemFunAndPtr : StrippedAccept { + template + struct AcceptImpl : std::false_type {}; + + template + struct AcceptImpl + : std::integral_constant::value> {}; + + template + struct AcceptImpl + : std::integral_constant::value> {}; + + template + static decltype(((*std::declval()).* + std::declval())(std::declval()...)) + Invoke(MemFun&& mem_fun, Ptr&& ptr, Args&&... args) { + return ((*std::forward(ptr)).* + std::forward(mem_fun))(std::forward(args)...); + } +}; + +// t1.*f when N == 1 and f is a pointer to member data of a class T and t1 is +// an object of type T or a reference to an object of type T or a reference +// to an object of a type derived from T. +struct DataMemAndRef : StrippedAccept { + template + struct AcceptImpl : std::false_type {}; + + template + struct AcceptImpl : std::is_base_of {}; + + template + static decltype(std::declval().*std::declval()) Invoke( + DataMem&& data_mem, Ref&& ref) { + return std::forward(ref).*std::forward(data_mem); + } +}; + +// (*t1).*f when N == 1 and f is a pointer to member data of a class T and t1 +// is not one of the types described in the previous item. +struct DataMemAndPtr : StrippedAccept { + template + struct AcceptImpl : std::false_type {}; + + template + struct AcceptImpl + : std::integral_constant::value> {}; + + template + static decltype((*std::declval()).*std::declval()) Invoke( + DataMem&& data_mem, Ptr&& ptr) { + return (*std::forward(ptr)).*std::forward(data_mem); + } +}; + +// f(t1, t2, ..., tN) in all other cases. +struct Callable { + // Callable doesn't have Accept because it's the last clause that gets picked + // when none of the previous clauses are applicable. + template + static decltype(std::declval()(std::declval()...)) Invoke( + F&& f, Args&&... args) { + return std::forward(f)(std::forward(args)...); + } +}; + +// Resolves to the first matching clause. +template +struct Invoker { + typedef typename std::conditional< + MemFunAndRef::Accept::value, MemFunAndRef, + typename std::conditional< + MemFunAndPtr::Accept::value, MemFunAndPtr, + typename std::conditional< + DataMemAndRef::Accept::value, DataMemAndRef, + typename std::conditional::value, + DataMemAndPtr, Callable>::type>::type>:: + type>::type type; +}; + +// The result type of Invoke. +template +using InvokeT = decltype(Invoker::type::Invoke( + std::declval(), std::declval()...)); + +// Invoke(f, args...) is an implementation of INVOKE(f, args...) from section +// [func.require] of the C++ standard. +template +InvokeT Invoke(F&& f, Args&&... args) { + return Invoker::type::Invoke(std::forward(f), + std::forward(args)...); +} +} // namespace base_internal +} // namespace absl + +#endif // ABSL_BASE_INTERNAL_INVOKE_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/low_level_alloc.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/low_level_alloc.cc new file mode 100644 index 0000000..6e636a0 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/low_level_alloc.cc @@ -0,0 +1,614 @@ +// Copyright 2017 The Abseil Authors. +// +// 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 low-level allocator that can be used by other low-level +// modules without introducing dependency cycles. +// This allocator is slow and wasteful of memory; +// it should not be used when performance is key. + +#include "absl/base/internal/low_level_alloc.h" + +#include + +#include "absl/base/call_once.h" +#include "absl/base/config.h" +#include "absl/base/internal/direct_mmap.h" +#include "absl/base/internal/scheduling_mode.h" +#include "absl/base/macros.h" +#include "absl/base/thread_annotations.h" + +// LowLevelAlloc requires that the platform support low-level +// allocation of virtual memory. Platforms lacking this cannot use +// LowLevelAlloc. +#ifndef ABSL_LOW_LEVEL_ALLOC_MISSING + +#ifndef _WIN32 +#include +#include +#include +#include +#else +#include +#endif + +#include +#include +#include +#include +#include +#include // for placement-new + +#include "absl/base/dynamic_annotations.h" +#include "absl/base/internal/raw_logging.h" +#include "absl/base/internal/spinlock.h" + +// MAP_ANONYMOUS +#if defined(__APPLE__) +// For mmap, Linux defines both MAP_ANONYMOUS and MAP_ANON and says MAP_ANON is +// deprecated. In Darwin, MAP_ANON is all there is. +#if !defined MAP_ANONYMOUS +#define MAP_ANONYMOUS MAP_ANON +#endif // !MAP_ANONYMOUS +#endif // __APPLE__ + +namespace absl { +namespace base_internal { + +// A first-fit allocator with amortized logarithmic free() time. + +// --------------------------------------------------------------------------- +static const int kMaxLevel = 30; + +namespace { +// This struct describes one allocated block, or one free block. +struct AllocList { + struct Header { + // Size of entire region, including this field. Must be + // first. Valid in both allocated and unallocated blocks. + uintptr_t size; + + // kMagicAllocated or kMagicUnallocated xor this. + uintptr_t magic; + + // Pointer to parent arena. + LowLevelAlloc::Arena *arena; + + // Aligns regions to 0 mod 2*sizeof(void*). + void *dummy_for_alignment; + } header; + + // Next two fields: in unallocated blocks: freelist skiplist data + // in allocated blocks: overlaps with client data + + // Levels in skiplist used. + int levels; + + // Actually has levels elements. The AllocList node may not have room + // for all kMaxLevel entries. See max_fit in LLA_SkiplistLevels(). + AllocList *next[kMaxLevel]; +}; +} // namespace + +// --------------------------------------------------------------------------- +// A trivial skiplist implementation. This is used to keep the freelist +// in address order while taking only logarithmic time per insert and delete. + +// An integer approximation of log2(size/base) +// Requires size >= base. +static int IntLog2(size_t size, size_t base) { + int result = 0; + for (size_t i = size; i > base; i >>= 1) { // i == floor(size/2**result) + result++; + } + // floor(size / 2**result) <= base < floor(size / 2**(result-1)) + // => log2(size/(base+1)) <= result < 1+log2(size/base) + // => result ~= log2(size/base) + return result; +} + +// Return a random integer n: p(n)=1/(2**n) if 1 <= n; p(n)=0 if n < 1. +static int Random(uint32_t *state) { + uint32_t r = *state; + int result = 1; + while ((((r = r*1103515245 + 12345) >> 30) & 1) == 0) { + result++; + } + *state = r; + return result; +} + +// Return a number of skiplist levels for a node of size bytes, where +// base is the minimum node size. Compute level=log2(size / base)+n +// where n is 1 if random is false and otherwise a random number generated with +// the standard distribution for a skiplist: See Random() above. +// Bigger nodes tend to have more skiplist levels due to the log2(size / base) +// term, so first-fit searches touch fewer nodes. "level" is clipped so +// level(level) > max_fit) level = static_cast(max_fit); + if (level > kMaxLevel-1) level = kMaxLevel - 1; + ABSL_RAW_CHECK(level >= 1, "block not big enough for even one level"); + return level; +} + +// Return "atleast", the first element of AllocList *head s.t. *atleast >= *e. +// For 0 <= i < head->levels, set prev[i] to "no_greater", where no_greater +// points to the last element at level i in the AllocList less than *e, or is +// head if no such element exists. +static AllocList *LLA_SkiplistSearch(AllocList *head, + AllocList *e, AllocList **prev) { + AllocList *p = head; + for (int level = head->levels - 1; level >= 0; level--) { + for (AllocList *n; (n = p->next[level]) != nullptr && n < e; p = n) { + } + prev[level] = p; + } + return (head->levels == 0) ? nullptr : prev[0]->next[0]; +} + +// Insert element *e into AllocList *head. Set prev[] as LLA_SkiplistSearch. +// Requires that e->levels be previously set by the caller (using +// LLA_SkiplistLevels()) +static void LLA_SkiplistInsert(AllocList *head, AllocList *e, + AllocList **prev) { + LLA_SkiplistSearch(head, e, prev); + for (; head->levels < e->levels; head->levels++) { // extend prev pointers + prev[head->levels] = head; // to all *e's levels + } + for (int i = 0; i != e->levels; i++) { // add element to list + e->next[i] = prev[i]->next[i]; + prev[i]->next[i] = e; + } +} + +// Remove element *e from AllocList *head. Set prev[] as LLA_SkiplistSearch(). +// Requires that e->levels be previous set by the caller (using +// LLA_SkiplistLevels()) +static void LLA_SkiplistDelete(AllocList *head, AllocList *e, + AllocList **prev) { + AllocList *found = LLA_SkiplistSearch(head, e, prev); + ABSL_RAW_CHECK(e == found, "element not in freelist"); + for (int i = 0; i != e->levels && prev[i]->next[i] == e; i++) { + prev[i]->next[i] = e->next[i]; + } + while (head->levels > 0 && head->next[head->levels - 1] == nullptr) { + head->levels--; // reduce head->levels if level unused + } +} + +// --------------------------------------------------------------------------- +// Arena implementation + +// Metadata for an LowLevelAlloc arena instance. +struct LowLevelAlloc::Arena { + // Constructs an arena with the given LowLevelAlloc flags. + explicit Arena(uint32_t flags_value); + + base_internal::SpinLock mu; + // Head of free list, sorted by address + AllocList freelist GUARDED_BY(mu); + // Count of allocated blocks + int32_t allocation_count GUARDED_BY(mu); + // flags passed to NewArena + const uint32_t flags; + // Result of getpagesize() + const size_t pagesize; + // Lowest power of two >= max(16, sizeof(AllocList)) + const size_t roundup; + // Smallest allocation block size + const size_t min_size; + // PRNG state + uint32_t random GUARDED_BY(mu); +}; + +namespace { +using ArenaStorage = std::aligned_storage::type; + +// Static storage space for the lazily-constructed, default global arena +// instances. We require this space because the whole point of LowLevelAlloc +// is to avoid relying on malloc/new. +ArenaStorage default_arena_storage; +ArenaStorage unhooked_arena_storage; +#ifndef ABSL_LOW_LEVEL_ALLOC_ASYNC_SIGNAL_SAFE_MISSING +ArenaStorage unhooked_async_sig_safe_arena_storage; +#endif + +// We must use LowLevelCallOnce here to construct the global arenas, rather than +// using function-level statics, to avoid recursively invoking the scheduler. +absl::once_flag create_globals_once; + +void CreateGlobalArenas() { + new (&default_arena_storage) + LowLevelAlloc::Arena(LowLevelAlloc::kCallMallocHook); + new (&unhooked_arena_storage) LowLevelAlloc::Arena(0); +#ifndef ABSL_LOW_LEVEL_ALLOC_ASYNC_SIGNAL_SAFE_MISSING + new (&unhooked_async_sig_safe_arena_storage) + LowLevelAlloc::Arena(LowLevelAlloc::kAsyncSignalSafe); +#endif +} + +// Returns a global arena that does not call into hooks. Used by NewArena() +// when kCallMallocHook is not set. +LowLevelAlloc::Arena* UnhookedArena() { + base_internal::LowLevelCallOnce(&create_globals_once, CreateGlobalArenas); + return reinterpret_cast(&unhooked_arena_storage); +} + +#ifndef ABSL_LOW_LEVEL_ALLOC_ASYNC_SIGNAL_SAFE_MISSING +// Returns a global arena that is async-signal safe. Used by NewArena() when +// kAsyncSignalSafe is set. +LowLevelAlloc::Arena *UnhookedAsyncSigSafeArena() { + base_internal::LowLevelCallOnce(&create_globals_once, CreateGlobalArenas); + return reinterpret_cast( + &unhooked_async_sig_safe_arena_storage); +} +#endif + +} // namespace + +// Returns the default arena, as used by LowLevelAlloc::Alloc() and friends. +LowLevelAlloc::Arena *LowLevelAlloc::DefaultArena() { + base_internal::LowLevelCallOnce(&create_globals_once, CreateGlobalArenas); + return reinterpret_cast(&default_arena_storage); +} + +// magic numbers to identify allocated and unallocated blocks +static const uintptr_t kMagicAllocated = 0x4c833e95U; +static const uintptr_t kMagicUnallocated = ~kMagicAllocated; + +namespace { +class SCOPED_LOCKABLE ArenaLock { + public: + explicit ArenaLock(LowLevelAlloc::Arena *arena) + EXCLUSIVE_LOCK_FUNCTION(arena->mu) + : arena_(arena) { +#ifndef ABSL_LOW_LEVEL_ALLOC_ASYNC_SIGNAL_SAFE_MISSING + if ((arena->flags & LowLevelAlloc::kAsyncSignalSafe) != 0) { + sigset_t all; + sigfillset(&all); + mask_valid_ = pthread_sigmask(SIG_BLOCK, &all, &mask_) == 0; + } +#endif + arena_->mu.Lock(); + } + ~ArenaLock() { ABSL_RAW_CHECK(left_, "haven't left Arena region"); } + void Leave() UNLOCK_FUNCTION() { + arena_->mu.Unlock(); +#ifndef ABSL_LOW_LEVEL_ALLOC_ASYNC_SIGNAL_SAFE_MISSING + if (mask_valid_) { + pthread_sigmask(SIG_SETMASK, &mask_, nullptr); + } +#endif + left_ = true; + } + + private: + bool left_ = false; // whether left region +#ifndef ABSL_LOW_LEVEL_ALLOC_ASYNC_SIGNAL_SAFE_MISSING + bool mask_valid_ = false; + sigset_t mask_; // old mask of blocked signals +#endif + LowLevelAlloc::Arena *arena_; + ArenaLock(const ArenaLock &) = delete; + ArenaLock &operator=(const ArenaLock &) = delete; +}; +} // namespace + +// create an appropriate magic number for an object at "ptr" +// "magic" should be kMagicAllocated or kMagicUnallocated +inline static uintptr_t Magic(uintptr_t magic, AllocList::Header *ptr) { + return magic ^ reinterpret_cast(ptr); +} + +namespace { +size_t GetPageSize() { +#ifdef _WIN32 + SYSTEM_INFO system_info; + GetSystemInfo(&system_info); + return std::max(system_info.dwPageSize, system_info.dwAllocationGranularity); +#else + return getpagesize(); +#endif +} + +size_t RoundedUpBlockSize() { + // Round up block sizes to a power of two close to the header size. + size_t roundup = 16; + while (roundup < sizeof(AllocList::Header)) { + roundup += roundup; + } + return roundup; +} + +} // namespace + +LowLevelAlloc::Arena::Arena(uint32_t flags_value) + : mu(base_internal::SCHEDULE_KERNEL_ONLY), + allocation_count(0), + flags(flags_value), + pagesize(GetPageSize()), + roundup(RoundedUpBlockSize()), + min_size(2 * roundup), + random(0) { + freelist.header.size = 0; + freelist.header.magic = + Magic(kMagicUnallocated, &freelist.header); + freelist.header.arena = this; + freelist.levels = 0; + memset(freelist.next, 0, sizeof(freelist.next)); +} + +// L < meta_data_arena->mu +LowLevelAlloc::Arena *LowLevelAlloc::NewArena(int32_t flags) { + Arena *meta_data_arena = DefaultArena(); +#ifndef ABSL_LOW_LEVEL_ALLOC_ASYNC_SIGNAL_SAFE_MISSING + if ((flags & LowLevelAlloc::kAsyncSignalSafe) != 0) { + meta_data_arena = UnhookedAsyncSigSafeArena(); + } else // NOLINT(readability/braces) +#endif + if ((flags & LowLevelAlloc::kCallMallocHook) == 0) { + meta_data_arena = UnhookedArena(); + } + Arena *result = + new (AllocWithArena(sizeof (*result), meta_data_arena)) Arena(flags); + return result; +} + +// L < arena->mu, L < arena->arena->mu +bool LowLevelAlloc::DeleteArena(Arena *arena) { + ABSL_RAW_CHECK( + arena != nullptr && arena != DefaultArena() && arena != UnhookedArena(), + "may not delete default arena"); + ArenaLock section(arena); + if (arena->allocation_count != 0) { + section.Leave(); + return false; + } + while (arena->freelist.next[0] != nullptr) { + AllocList *region = arena->freelist.next[0]; + size_t size = region->header.size; + arena->freelist.next[0] = region->next[0]; + ABSL_RAW_CHECK( + region->header.magic == Magic(kMagicUnallocated, ®ion->header), + "bad magic number in DeleteArena()"); + ABSL_RAW_CHECK(region->header.arena == arena, + "bad arena pointer in DeleteArena()"); + ABSL_RAW_CHECK(size % arena->pagesize == 0, + "empty arena has non-page-aligned block size"); + ABSL_RAW_CHECK(reinterpret_cast(region) % arena->pagesize == 0, + "empty arena has non-page-aligned block"); + int munmap_result; +#ifdef _WIN32 + munmap_result = VirtualFree(region, 0, MEM_RELEASE); + ABSL_RAW_CHECK(munmap_result != 0, + "LowLevelAlloc::DeleteArena: VitualFree failed"); +#else +#ifndef ABSL_LOW_LEVEL_ALLOC_ASYNC_SIGNAL_SAFE_MISSING + if ((arena->flags & LowLevelAlloc::kAsyncSignalSafe) == 0) { + munmap_result = munmap(region, size); + } else { + munmap_result = base_internal::DirectMunmap(region, size); + } +#else + munmap_result = munmap(region, size); +#endif // ABSL_LOW_LEVEL_ALLOC_ASYNC_SIGNAL_SAFE_MISSING + if (munmap_result != 0) { + ABSL_RAW_LOG(FATAL, "LowLevelAlloc::DeleteArena: munmap failed: %d", + errno); + } +#endif // _WIN32 + } + section.Leave(); + arena->~Arena(); + Free(arena); + return true; +} + +// --------------------------------------------------------------------------- + +// Addition, checking for overflow. The intent is to die if an external client +// manages to push through a request that would cause arithmetic to fail. +static inline uintptr_t CheckedAdd(uintptr_t a, uintptr_t b) { + uintptr_t sum = a + b; + ABSL_RAW_CHECK(sum >= a, "LowLevelAlloc arithmetic overflow"); + return sum; +} + +// Return value rounded up to next multiple of align. +// align must be a power of two. +static inline uintptr_t RoundUp(uintptr_t addr, uintptr_t align) { + return CheckedAdd(addr, align - 1) & ~(align - 1); +} + +// Equivalent to "return prev->next[i]" but with sanity checking +// that the freelist is in the correct order, that it +// consists of regions marked "unallocated", and that no two regions +// are adjacent in memory (they should have been coalesced). +// L < arena->mu +static AllocList *Next(int i, AllocList *prev, LowLevelAlloc::Arena *arena) { + ABSL_RAW_CHECK(i < prev->levels, "too few levels in Next()"); + AllocList *next = prev->next[i]; + if (next != nullptr) { + ABSL_RAW_CHECK( + next->header.magic == Magic(kMagicUnallocated, &next->header), + "bad magic number in Next()"); + ABSL_RAW_CHECK(next->header.arena == arena, "bad arena pointer in Next()"); + if (prev != &arena->freelist) { + ABSL_RAW_CHECK(prev < next, "unordered freelist"); + ABSL_RAW_CHECK(reinterpret_cast(prev) + prev->header.size < + reinterpret_cast(next), + "malformed freelist"); + } + } + return next; +} + +// Coalesce list item "a" with its successor if they are adjacent. +static void Coalesce(AllocList *a) { + AllocList *n = a->next[0]; + if (n != nullptr && reinterpret_cast(a) + a->header.size == + reinterpret_cast(n)) { + LowLevelAlloc::Arena *arena = a->header.arena; + a->header.size += n->header.size; + n->header.magic = 0; + n->header.arena = nullptr; + AllocList *prev[kMaxLevel]; + LLA_SkiplistDelete(&arena->freelist, n, prev); + LLA_SkiplistDelete(&arena->freelist, a, prev); + a->levels = LLA_SkiplistLevels(a->header.size, arena->min_size, + &arena->random); + LLA_SkiplistInsert(&arena->freelist, a, prev); + } +} + +// Adds block at location "v" to the free list +// L >= arena->mu +static void AddToFreelist(void *v, LowLevelAlloc::Arena *arena) { + AllocList *f = reinterpret_cast( + reinterpret_cast(v) - sizeof (f->header)); + ABSL_RAW_CHECK(f->header.magic == Magic(kMagicAllocated, &f->header), + "bad magic number in AddToFreelist()"); + ABSL_RAW_CHECK(f->header.arena == arena, + "bad arena pointer in AddToFreelist()"); + f->levels = LLA_SkiplistLevels(f->header.size, arena->min_size, + &arena->random); + AllocList *prev[kMaxLevel]; + LLA_SkiplistInsert(&arena->freelist, f, prev); + f->header.magic = Magic(kMagicUnallocated, &f->header); + Coalesce(f); // maybe coalesce with successor + Coalesce(prev[0]); // maybe coalesce with predecessor +} + +// Frees storage allocated by LowLevelAlloc::Alloc(). +// L < arena->mu +void LowLevelAlloc::Free(void *v) { + if (v != nullptr) { + AllocList *f = reinterpret_cast( + reinterpret_cast(v) - sizeof (f->header)); + ABSL_RAW_CHECK(f->header.magic == Magic(kMagicAllocated, &f->header), + "bad magic number in Free()"); + LowLevelAlloc::Arena *arena = f->header.arena; + ArenaLock section(arena); + AddToFreelist(v, arena); + ABSL_RAW_CHECK(arena->allocation_count > 0, "nothing in arena to free"); + arena->allocation_count--; + section.Leave(); + } +} + +// allocates and returns a block of size bytes, to be freed with Free() +// L < arena->mu +static void *DoAllocWithArena(size_t request, LowLevelAlloc::Arena *arena) { + void *result = nullptr; + if (request != 0) { + AllocList *s; // will point to region that satisfies request + ArenaLock section(arena); + // round up with header + size_t req_rnd = RoundUp(CheckedAdd(request, sizeof (s->header)), + arena->roundup); + for (;;) { // loop until we find a suitable region + // find the minimum levels that a block of this size must have + int i = LLA_SkiplistLevels(req_rnd, arena->min_size, nullptr) - 1; + if (i < arena->freelist.levels) { // potential blocks exist + AllocList *before = &arena->freelist; // predecessor of s + while ((s = Next(i, before, arena)) != nullptr && + s->header.size < req_rnd) { + before = s; + } + if (s != nullptr) { // we found a region + break; + } + } + // we unlock before mmap() both because mmap() may call a callback hook, + // and because it may be slow. + arena->mu.Unlock(); + // mmap generous 64K chunks to decrease + // the chances/impact of fragmentation: + size_t new_pages_size = RoundUp(req_rnd, arena->pagesize * 16); + void *new_pages; +#ifdef _WIN32 + new_pages = VirtualAlloc(0, new_pages_size, + MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); + ABSL_RAW_CHECK(new_pages != nullptr, "VirtualAlloc failed"); +#else +#ifndef ABSL_LOW_LEVEL_ALLOC_ASYNC_SIGNAL_SAFE_MISSING + if ((arena->flags & LowLevelAlloc::kAsyncSignalSafe) != 0) { + new_pages = base_internal::DirectMmap(nullptr, new_pages_size, + PROT_WRITE|PROT_READ, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0); + } else { + new_pages = mmap(nullptr, new_pages_size, PROT_WRITE | PROT_READ, + MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); + } +#else + new_pages = mmap(nullptr, new_pages_size, PROT_WRITE | PROT_READ, + MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); +#endif // ABSL_LOW_LEVEL_ALLOC_ASYNC_SIGNAL_SAFE_MISSING + if (new_pages == MAP_FAILED) { + ABSL_RAW_LOG(FATAL, "mmap error: %d", errno); + } + +#endif // _WIN32 + arena->mu.Lock(); + s = reinterpret_cast(new_pages); + s->header.size = new_pages_size; + // Pretend the block is allocated; call AddToFreelist() to free it. + s->header.magic = Magic(kMagicAllocated, &s->header); + s->header.arena = arena; + AddToFreelist(&s->levels, arena); // insert new region into free list + } + AllocList *prev[kMaxLevel]; + LLA_SkiplistDelete(&arena->freelist, s, prev); // remove from free list + // s points to the first free region that's big enough + if (CheckedAdd(req_rnd, arena->min_size) <= s->header.size) { + // big enough to split + AllocList *n = reinterpret_cast + (req_rnd + reinterpret_cast(s)); + n->header.size = s->header.size - req_rnd; + n->header.magic = Magic(kMagicAllocated, &n->header); + n->header.arena = arena; + s->header.size = req_rnd; + AddToFreelist(&n->levels, arena); + } + s->header.magic = Magic(kMagicAllocated, &s->header); + ABSL_RAW_CHECK(s->header.arena == arena, ""); + arena->allocation_count++; + section.Leave(); + result = &s->levels; + } + ANNOTATE_MEMORY_IS_UNINITIALIZED(result, request); + return result; +} + +void *LowLevelAlloc::Alloc(size_t request) { + void *result = DoAllocWithArena(request, DefaultArena()); + return result; +} + +void *LowLevelAlloc::AllocWithArena(size_t request, Arena *arena) { + ABSL_RAW_CHECK(arena != nullptr, "must pass a valid arena"); + void *result = DoAllocWithArena(request, arena); + return result; +} + +} // namespace base_internal +} // namespace absl + +#endif // ABSL_LOW_LEVEL_ALLOC_MISSING diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/low_level_alloc.h b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/low_level_alloc.h new file mode 100644 index 0000000..fba9466 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/low_level_alloc.h @@ -0,0 +1,122 @@ +// Copyright 2017 The Abseil Authors. +// +// 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. +// + +#ifndef ABSL_BASE_INTERNAL_LOW_LEVEL_ALLOC_H_ +#define ABSL_BASE_INTERNAL_LOW_LEVEL_ALLOC_H_ + +// A simple thread-safe memory allocator that does not depend on +// mutexes or thread-specific data. It is intended to be used +// sparingly, and only when malloc() would introduce an unwanted +// dependency, such as inside the heap-checker, or the Mutex +// implementation. + +// IWYU pragma: private, include "base/low_level_alloc.h" + +#include +#include + +#include "absl/base/attributes.h" +#include "absl/base/config.h" + +// LowLevelAlloc requires that the platform support low-level +// allocation of virtual memory. Platforms lacking this cannot use +// LowLevelAlloc. +#ifdef ABSL_LOW_LEVEL_ALLOC_MISSING +#error ABSL_LOW_LEVEL_ALLOC_MISSING cannot be directly set +#elif !defined(ABSL_HAVE_MMAP) && !defined(_WIN32) +#define ABSL_LOW_LEVEL_ALLOC_MISSING 1 +#endif + +// Using LowLevelAlloc with kAsyncSignalSafe isn't supported on Windows or +// asm.js / WebAssembly. +// See https://kripken.github.io/emscripten-site/docs/porting/pthreads.html +// for more information. +#ifdef ABSL_LOW_LEVEL_ALLOC_ASYNC_SIGNAL_SAFE_MISSING +#error ABSL_LOW_LEVEL_ALLOC_ASYNC_SIGNAL_SAFE_MISSING cannot be directly set +#elif defined(_WIN32) || defined(__asmjs__) || defined(__wasm__) +#define ABSL_LOW_LEVEL_ALLOC_ASYNC_SIGNAL_SAFE_MISSING 1 +#endif + +#include + +#include "absl/base/port.h" + +namespace absl { +namespace base_internal { + +class LowLevelAlloc { + public: + struct Arena; // an arena from which memory may be allocated + + // Returns a pointer to a block of at least "request" bytes + // that have been newly allocated from the specific arena. + // for Alloc() call the DefaultArena() is used. + // Returns 0 if passed request==0. + // Does not return 0 under other circumstances; it crashes if memory + // is not available. + static void *Alloc(size_t request) ABSL_ATTRIBUTE_SECTION(malloc_hook); + static void *AllocWithArena(size_t request, Arena *arena) + ABSL_ATTRIBUTE_SECTION(malloc_hook); + + // Deallocates a region of memory that was previously allocated with + // Alloc(). Does nothing if passed 0. "s" must be either 0, + // or must have been returned from a call to Alloc() and not yet passed to + // Free() since that call to Alloc(). The space is returned to the arena + // from which it was allocated. + static void Free(void *s) ABSL_ATTRIBUTE_SECTION(malloc_hook); + + // ABSL_ATTRIBUTE_SECTION(malloc_hook) for Alloc* and Free + // are to put all callers of MallocHook::Invoke* in this module + // into special section, + // so that MallocHook::GetCallerStackTrace can function accurately. + + // Create a new arena. + // The root metadata for the new arena is allocated in the + // meta_data_arena; the DefaultArena() can be passed for meta_data_arena. + // These values may be ored into flags: + enum { + // Report calls to Alloc() and Free() via the MallocHook interface. + // Set in the DefaultArena. + kCallMallocHook = 0x0001, + +#ifndef ABSL_LOW_LEVEL_ALLOC_ASYNC_SIGNAL_SAFE_MISSING + // Make calls to Alloc(), Free() be async-signal-safe. Not set in + // DefaultArena(). Not supported on all platforms. + kAsyncSignalSafe = 0x0002, +#endif + }; + // Construct a new arena. The allocation of the underlying metadata honors + // the provided flags. For example, the call NewArena(kAsyncSignalSafe) + // is itself async-signal-safe, as well as generatating an arena that provides + // async-signal-safe Alloc/Free. + static Arena *NewArena(int32_t flags); + + // Destroys an arena allocated by NewArena and returns true, + // provided no allocated blocks remain in the arena. + // If allocated blocks remain in the arena, does nothing and + // returns false. + // It is illegal to attempt to destroy the DefaultArena(). + static bool DeleteArena(Arena *arena); + + // The default arena that always exists. + static Arena *DefaultArena(); + + private: + LowLevelAlloc(); // no instances +}; + +} // namespace base_internal +} // namespace absl +#endif // ABSL_BASE_INTERNAL_LOW_LEVEL_ALLOC_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/low_level_alloc_test.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/low_level_alloc_test.cc new file mode 100644 index 0000000..cf2b363 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/low_level_alloc_test.cc @@ -0,0 +1,157 @@ +// Copyright 2017 The Abseil Authors. +// +// 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 "absl/base/internal/low_level_alloc.h" + +#include +#include +#include +#include // NOLINT(build/c++11) +#include +#include + +namespace absl { +namespace base_internal { +namespace { + +// This test doesn't use gtest since it needs to test that everything +// works before main(). +#define TEST_ASSERT(x) \ + if (!(x)) { \ + printf("TEST_ASSERT(%s) FAILED ON LINE %d\n", #x, __LINE__); \ + abort(); \ + } + +// a block of memory obtained from the allocator +struct BlockDesc { + char *ptr; // pointer to memory + int len; // number of bytes + int fill; // filled with data starting with this +}; + +// Check that the pattern placed in the block d +// by RandomizeBlockDesc is still there. +static void CheckBlockDesc(const BlockDesc &d) { + for (int i = 0; i != d.len; i++) { + TEST_ASSERT((d.ptr[i] & 0xff) == ((d.fill + i) & 0xff)); + } +} + +// Fill the block "*d" with a pattern +// starting with a random byte. +static void RandomizeBlockDesc(BlockDesc *d) { + d->fill = rand() & 0xff; + for (int i = 0; i != d->len; i++) { + d->ptr[i] = (d->fill + i) & 0xff; + } +} + +// Use to indicate to the malloc hooks that +// this calls is from LowLevelAlloc. +static bool using_low_level_alloc = false; + +// n times, toss a coin, and based on the outcome +// either allocate a new block or deallocate an old block. +// New blocks are placed in a std::unordered_map with a random key +// and initialized with RandomizeBlockDesc(). +// If keys conflict, the older block is freed. +// Old blocks are always checked with CheckBlockDesc() +// before being freed. At the end of the run, +// all remaining allocated blocks are freed. +// If use_new_arena is true, use a fresh arena, and then delete it. +// If call_malloc_hook is true and user_arena is true, +// allocations and deallocations are reported via the MallocHook +// interface. +static void Test(bool use_new_arena, bool call_malloc_hook, int n) { + typedef std::unordered_map AllocMap; + AllocMap allocated; + AllocMap::iterator it; + BlockDesc block_desc; + int rnd; + LowLevelAlloc::Arena *arena = 0; + if (use_new_arena) { + int32_t flags = call_malloc_hook ? LowLevelAlloc::kCallMallocHook : 0; + arena = LowLevelAlloc::NewArena(flags); + } + for (int i = 0; i != n; i++) { + if (i != 0 && i % 10000 == 0) { + printf("."); + fflush(stdout); + } + + switch (rand() & 1) { // toss a coin + case 0: // coin came up heads: add a block + using_low_level_alloc = true; + block_desc.len = rand() & 0x3fff; + block_desc.ptr = + reinterpret_cast( + arena == 0 + ? LowLevelAlloc::Alloc(block_desc.len) + : LowLevelAlloc::AllocWithArena(block_desc.len, arena)); + using_low_level_alloc = false; + RandomizeBlockDesc(&block_desc); + rnd = rand(); + it = allocated.find(rnd); + if (it != allocated.end()) { + CheckBlockDesc(it->second); + using_low_level_alloc = true; + LowLevelAlloc::Free(it->second.ptr); + using_low_level_alloc = false; + it->second = block_desc; + } else { + allocated[rnd] = block_desc; + } + break; + case 1: // coin came up tails: remove a block + it = allocated.begin(); + if (it != allocated.end()) { + CheckBlockDesc(it->second); + using_low_level_alloc = true; + LowLevelAlloc::Free(it->second.ptr); + using_low_level_alloc = false; + allocated.erase(it); + } + break; + } + } + // remove all remaining blocks + while ((it = allocated.begin()) != allocated.end()) { + CheckBlockDesc(it->second); + using_low_level_alloc = true; + LowLevelAlloc::Free(it->second.ptr); + using_low_level_alloc = false; + allocated.erase(it); + } + if (use_new_arena) { + TEST_ASSERT(LowLevelAlloc::DeleteArena(arena)); + } +} +// LowLevelAlloc is designed to be safe to call before main(). +static struct BeforeMain { + BeforeMain() { + Test(false, false, 50000); + Test(true, false, 50000); + Test(true, true, 50000); + } +} before_main; + +} // namespace +} // namespace base_internal +} // namespace absl + +int main(int argc, char *argv[]) { + // The actual test runs in the global constructor of `before_main`. + printf("PASS\n"); + return 0; +} diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/low_level_scheduling.h b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/low_level_scheduling.h new file mode 100644 index 0000000..e716f2b --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/low_level_scheduling.h @@ -0,0 +1,104 @@ +// Copyright 2017 The Abseil Authors. +// +// 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. +// +// Core interfaces and definitions used by by low-level interfaces such as +// SpinLock. + +#ifndef ABSL_BASE_INTERNAL_LOW_LEVEL_SCHEDULING_H_ +#define ABSL_BASE_INTERNAL_LOW_LEVEL_SCHEDULING_H_ + +#include "absl/base/internal/scheduling_mode.h" +#include "absl/base/macros.h" + +// The following two declarations exist so SchedulingGuard may friend them with +// the appropriate language linkage. These callbacks allow libc internals, such +// as function level statics, to schedule cooperatively when locking. +extern "C" bool __google_disable_rescheduling(void); +extern "C" void __google_enable_rescheduling(bool disable_result); + +namespace absl { +namespace base_internal { + +class SchedulingHelper; // To allow use of SchedulingGuard. +class SpinLock; // To allow use of SchedulingGuard. + +// SchedulingGuard +// Provides guard semantics that may be used to disable cooperative rescheduling +// of the calling thread within specific program blocks. This is used to +// protect resources (e.g. low-level SpinLocks or Domain code) that cooperative +// scheduling depends on. +// +// Domain implementations capable of rescheduling in reaction to involuntary +// kernel thread actions (e.g blocking due to a pagefault or syscall) must +// guarantee that an annotated thread is not allowed to (cooperatively) +// reschedule until the annotated region is complete. +// +// It is an error to attempt to use a cooperatively scheduled resource (e.g. +// Mutex) within a rescheduling-disabled region. +// +// All methods are async-signal safe. +class SchedulingGuard { + public: + // Returns true iff the calling thread may be cooperatively rescheduled. + static bool ReschedulingIsAllowed(); + + private: + // Disable cooperative rescheduling of the calling thread. It may still + // initiate scheduling operations (e.g. wake-ups), however, it may not itself + // reschedule. Nestable. The returned result is opaque, clients should not + // attempt to interpret it. + // REQUIRES: Result must be passed to a pairing EnableScheduling(). + static bool DisableRescheduling(); + + // Marks the end of a rescheduling disabled region, previously started by + // DisableRescheduling(). + // REQUIRES: Pairs with innermost call (and result) of DisableRescheduling(). + static void EnableRescheduling(bool disable_result); + + // A scoped helper for {Disable, Enable}Rescheduling(). + // REQUIRES: destructor must run in same thread as constructor. + struct ScopedDisable { + ScopedDisable() { disabled = SchedulingGuard::DisableRescheduling(); } + ~ScopedDisable() { SchedulingGuard::EnableRescheduling(disabled); } + + bool disabled; + }; + + // Access to SchedulingGuard is explicitly white-listed. + friend class SchedulingHelper; + friend class SpinLock; + + SchedulingGuard(const SchedulingGuard&) = delete; + SchedulingGuard& operator=(const SchedulingGuard&) = delete; +}; + +//------------------------------------------------------------------------------ +// End of public interfaces. +//------------------------------------------------------------------------------ +inline bool SchedulingGuard::ReschedulingIsAllowed() { + return false; +} + +inline bool SchedulingGuard::DisableRescheduling() { + return false; +} + +inline void SchedulingGuard::EnableRescheduling(bool /* disable_result */) { + return; +} + + +} // namespace base_internal +} // namespace absl +#endif // ABSL_BASE_INTERNAL_LOW_LEVEL_SCHEDULING_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/per_thread_tls.h b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/per_thread_tls.h new file mode 100644 index 0000000..2428bdc --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/per_thread_tls.h @@ -0,0 +1,48 @@ +// Copyright 2017 The Abseil Authors. +// +// 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. + +#ifndef ABSL_BASE_INTERNAL_PER_THREAD_TLS_H_ +#define ABSL_BASE_INTERNAL_PER_THREAD_TLS_H_ + +// This header defines two macros: +// If the platform supports thread-local storage: +// ABSL_PER_THREAD_TLS_KEYWORD is the C keyword needed to declare a +// thread-local variable ABSL_PER_THREAD_TLS is 1 +// +// Otherwise: +// ABSL_PER_THREAD_TLS_KEYWORD is empty +// ABSL_PER_THREAD_TLS is 0 +// +// Microsoft C supports thread-local storage. +// GCC supports it if the appropriate version of glibc is available, +// which the programmer can indicate by defining ABSL_HAVE_TLS + +#include "absl/base/port.h" // For ABSL_HAVE_TLS + +#if defined(ABSL_PER_THREAD_TLS) +#error ABSL_PER_THREAD_TLS cannot be directly set +#elif defined(ABSL_PER_THREAD_TLS_KEYWORD) +#error ABSL_PER_THREAD_TLS_KEYWORD cannot be directly set +#elif defined(ABSL_HAVE_TLS) +#define ABSL_PER_THREAD_TLS_KEYWORD __thread +#define ABSL_PER_THREAD_TLS 1 +#elif defined(_MSC_VER) +#define ABSL_PER_THREAD_TLS_KEYWORD __declspec(thread) +#define ABSL_PER_THREAD_TLS 1 +#else +#define ABSL_PER_THREAD_TLS_KEYWORD +#define ABSL_PER_THREAD_TLS 0 +#endif + +#endif // ABSL_BASE_INTERNAL_PER_THREAD_TLS_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/pretty_function.h b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/pretty_function.h new file mode 100644 index 0000000..01b0547 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/pretty_function.h @@ -0,0 +1,33 @@ +// Copyright 2017 The Abseil Authors. +// +// 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. + +#ifndef ABSL_BASE_INTERNAL_PRETTY_FUNCTION_H_ +#define ABSL_BASE_INTERNAL_PRETTY_FUNCTION_H_ + +// ABSL_PRETTY_FUNCTION +// +// In C++11, __func__ gives the undecorated name of the current function. That +// is, "main", not "int main()". Various compilers give extra macros to get the +// decorated function name, including return type and arguments, to +// differentiate between overload sets. ABSL_PRETTY_FUNCTION is a portable +// version of these macros which forwards to the correct macro on each compiler. +#if defined(_MSC_VER) +#define ABSL_PRETTY_FUNCTION __FUNCSIG__ +#elif defined(__GNUC__) +#define ABSL_PRETTY_FUNCTION __PRETTY_FUNCTION__ +#else +#error "Unsupported compiler" +#endif + +#endif // ABSL_BASE_INTERNAL_PRETTY_FUNCTION_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/raw_logging.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/raw_logging.cc new file mode 100644 index 0000000..d9485a6 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/raw_logging.cc @@ -0,0 +1,234 @@ +// Copyright 2017 The Abseil Authors. +// +// 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 "absl/base/internal/raw_logging.h" + +#include +#include +#include +#include +#include + +#include "absl/base/attributes.h" +#include "absl/base/config.h" +#include "absl/base/internal/atomic_hook.h" +#include "absl/base/log_severity.h" + +// We know how to perform low-level writes to stderr in POSIX and Windows. For +// these platforms, we define the token ABSL_LOW_LEVEL_WRITE_SUPPORTED. +// Much of raw_logging.cc becomes a no-op when we can't output messages, +// although a FATAL ABSL_RAW_LOG message will still abort the process. + +// ABSL_HAVE_POSIX_WRITE is defined when the platform provides posix write() +// (as from unistd.h) +// +// This preprocessor token is also defined in raw_io.cc. If you need to copy +// this, consider moving both to config.h instead. +#if defined(__linux__) || defined(__APPLE__) || defined(__FreeBSD__) || \ + defined(__Fuchsia__) || defined(__native_client__) +#include + + +#define ABSL_HAVE_POSIX_WRITE 1 +#define ABSL_LOW_LEVEL_WRITE_SUPPORTED 1 +#else +#undef ABSL_HAVE_POSIX_WRITE +#endif + +// ABSL_HAVE_SYSCALL_WRITE is defined when the platform provides the syscall +// syscall(SYS_write, /*int*/ fd, /*char* */ buf, /*size_t*/ len); +// for low level operations that want to avoid libc. +#if (defined(__linux__) || defined(__FreeBSD__)) && !defined(__ANDROID__) +#include +#define ABSL_HAVE_SYSCALL_WRITE 1 +#define ABSL_LOW_LEVEL_WRITE_SUPPORTED 1 +#else +#undef ABSL_HAVE_SYSCALL_WRITE +#endif + +#ifdef _WIN32 +#include + +#define ABSL_HAVE_RAW_IO 1 +#define ABSL_LOW_LEVEL_WRITE_SUPPORTED 1 +#else +#undef ABSL_HAVE_RAW_IO +#endif + +// TODO(gfalcon): We want raw-logging to work on as many platforms as possible. +// Explicitly #error out when not ABSL_LOW_LEVEL_WRITE_SUPPORTED, except for a +// whitelisted set of platforms for which we expect not to be able to raw log. + +ABSL_CONST_INIT static absl::base_internal::AtomicHook< + absl::raw_logging_internal::LogPrefixHook> log_prefix_hook; +ABSL_CONST_INIT static absl::base_internal::AtomicHook< + absl::raw_logging_internal::AbortHook> abort_hook; + +#ifdef ABSL_LOW_LEVEL_WRITE_SUPPORTED +static const char kTruncated[] = " ... (message truncated)\n"; + +// sprintf the format to the buffer, adjusting *buf and *size to reflect the +// consumed bytes, and return whether the message fit without truncation. If +// truncation occurred, if possible leave room in the buffer for the message +// kTruncated[]. +inline static bool VADoRawLog(char** buf, int* size, const char* format, + va_list ap) ABSL_PRINTF_ATTRIBUTE(3, 0); +inline static bool VADoRawLog(char** buf, int* size, + const char* format, va_list ap) { + int n = vsnprintf(*buf, *size, format, ap); + bool result = true; + if (n < 0 || n > *size) { + result = false; + if (static_cast(*size) > sizeof(kTruncated)) { + n = *size - sizeof(kTruncated); // room for truncation message + } else { + n = 0; // no room for truncation message + } + } + *size -= n; + *buf += n; + return result; +} +#endif // ABSL_LOW_LEVEL_WRITE_SUPPORTED + +static constexpr int kLogBufSize = 3000; + +namespace { + +// CAVEAT: vsnprintf called from *DoRawLog below has some (exotic) code paths +// that invoke malloc() and getenv() that might acquire some locks. + +// Helper for RawLog below. +// *DoRawLog writes to *buf of *size and move them past the written portion. +// It returns true iff there was no overflow or error. +bool DoRawLog(char** buf, int* size, const char* format, ...) + ABSL_PRINTF_ATTRIBUTE(3, 4); +bool DoRawLog(char** buf, int* size, const char* format, ...) { + va_list ap; + va_start(ap, format); + int n = vsnprintf(*buf, *size, format, ap); + va_end(ap); + if (n < 0 || n > *size) return false; + *size -= n; + *buf += n; + return true; +} + +void RawLogVA(absl::LogSeverity severity, const char* file, int line, + const char* format, va_list ap) ABSL_PRINTF_ATTRIBUTE(4, 0); +void RawLogVA(absl::LogSeverity severity, const char* file, int line, + const char* format, va_list ap) { + char buffer[kLogBufSize]; + char* buf = buffer; + int size = sizeof(buffer); +#ifdef ABSL_LOW_LEVEL_WRITE_SUPPORTED + bool enabled = true; +#else + bool enabled = false; +#endif + +#ifdef ABSL_MIN_LOG_LEVEL + if (severity < static_cast(ABSL_MIN_LOG_LEVEL) && + severity < absl::LogSeverity::kFatal) { + enabled = false; + } +#endif + + auto log_prefix_hook_ptr = log_prefix_hook.Load(); + if (log_prefix_hook_ptr) { + enabled = log_prefix_hook_ptr(severity, file, line, &buf, &size); + } else { + if (enabled) { + DoRawLog(&buf, &size, "[%s : %d] RAW: ", file, line); + } + } + const char* const prefix_end = buf; + +#ifdef ABSL_LOW_LEVEL_WRITE_SUPPORTED + if (enabled) { + bool no_chop = VADoRawLog(&buf, &size, format, ap); + if (no_chop) { + DoRawLog(&buf, &size, "\n"); + } else { + DoRawLog(&buf, &size, "%s", kTruncated); + } + absl::raw_logging_internal::SafeWriteToStderr(buffer, strlen(buffer)); + } +#else + static_cast(format); + static_cast(ap); +#endif + + // Abort the process after logging a FATAL message, even if the output itself + // was suppressed. + if (severity == absl::LogSeverity::kFatal) { + abort_hook(file, line, buffer, prefix_end, buffer + kLogBufSize); + abort(); + } +} + +} // namespace + +namespace absl { +namespace raw_logging_internal { +void SafeWriteToStderr(const char *s, size_t len) { +#if defined(ABSL_HAVE_SYSCALL_WRITE) + syscall(SYS_write, STDERR_FILENO, s, len); +#elif defined(ABSL_HAVE_POSIX_WRITE) + write(STDERR_FILENO, s, len); +#elif defined(ABSL_HAVE_RAW_IO) + _write(/* stderr */ 2, s, len); +#else + // stderr logging unsupported on this platform + (void) s; + (void) len; +#endif +} + +void RawLog(absl::LogSeverity severity, const char* file, int line, + const char* format, ...) ABSL_PRINTF_ATTRIBUTE(4, 5); +void RawLog(absl::LogSeverity severity, const char* file, int line, + const char* format, ...) { + va_list ap; + va_start(ap, format); + RawLogVA(severity, file, line, format, ap); + va_end(ap); +} + +// Non-formatting version of RawLog(). +// +// TODO(gfalcon): When string_view no longer depends on base, change this +// interface to take its message as a string_view instead. +static void DefaultInternalLog(absl::LogSeverity severity, const char* file, + int line, const std::string& message) { + RawLog(severity, file, line, "%s", message.c_str()); +} + +bool RawLoggingFullySupported() { +#ifdef ABSL_LOW_LEVEL_WRITE_SUPPORTED + return true; +#else // !ABSL_LOW_LEVEL_WRITE_SUPPORTED + return false; +#endif // !ABSL_LOW_LEVEL_WRITE_SUPPORTED +} + +ABSL_CONST_INIT absl::base_internal::AtomicHook + internal_log_function(DefaultInternalLog); + +void RegisterInternalLogFunction(InternalLogFunction func) { + internal_log_function.Store(func); +} + +} // namespace raw_logging_internal +} // namespace absl diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/raw_logging.h b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/raw_logging.h new file mode 100644 index 0000000..79a7bb9 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/raw_logging.h @@ -0,0 +1,180 @@ +// Copyright 2017 The Abseil Authors. +// +// 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. +// +// Thread-safe logging routines that do not allocate any memory or +// acquire any locks, and can therefore be used by low-level memory +// allocation, synchronization, and signal-handling code. + +#ifndef ABSL_BASE_INTERNAL_RAW_LOGGING_H_ +#define ABSL_BASE_INTERNAL_RAW_LOGGING_H_ + +#include + +#include "absl/base/attributes.h" +#include "absl/base/internal/atomic_hook.h" +#include "absl/base/log_severity.h" +#include "absl/base/macros.h" +#include "absl/base/port.h" + +// This is similar to LOG(severity) << format..., but +// * it is to be used ONLY by low-level modules that can't use normal LOG() +// * it is designed to be a low-level logger that does not allocate any +// memory and does not need any locks, hence: +// * it logs straight and ONLY to STDERR w/o buffering +// * it uses an explicit printf-format and arguments list +// * it will silently chop off really long message strings +// Usage example: +// ABSL_RAW_LOG(ERROR, "Failed foo with %i: %s", status, error); +// This will print an almost standard log line like this to stderr only: +// E0821 211317 file.cc:123] RAW: Failed foo with 22: bad_file +#define ABSL_RAW_LOG(severity, ...) \ + do { \ + constexpr const char* absl_raw_logging_internal_basename = \ + ::absl::raw_logging_internal::Basename(__FILE__, \ + sizeof(__FILE__) - 1); \ + ::absl::raw_logging_internal::RawLog(ABSL_RAW_LOGGING_INTERNAL_##severity, \ + absl_raw_logging_internal_basename, \ + __LINE__, __VA_ARGS__); \ + } while (0) + +// Similar to CHECK(condition) << message, but for low-level modules: +// we use only ABSL_RAW_LOG that does not allocate memory. +// We do not want to provide args list here to encourage this usage: +// if (!cond) ABSL_RAW_LOG(FATAL, "foo ...", hard_to_compute_args); +// so that the args are not computed when not needed. +#define ABSL_RAW_CHECK(condition, message) \ + do { \ + if (ABSL_PREDICT_FALSE(!(condition))) { \ + ABSL_RAW_LOG(FATAL, "Check %s failed: %s", #condition, message); \ + } \ + } while (0) + +// ABSL_INTERNAL_LOG and ABSL_INTERNAL_CHECK work like the RAW variants above, +// except that if the richer log library is linked into the binary, we dispatch +// to that instead. This is potentially useful for internal logging and +// assertions, where we are using RAW_LOG neither for its async-signal-safety +// nor for its non-allocating nature, but rather because raw logging has very +// few other dependencies. +// +// The API is a subset of the above: each macro only takes two arguments. Use +// StrCat if you need to build a richer message. +#define ABSL_INTERNAL_LOG(severity, message) \ + do { \ + constexpr const char* absl_raw_logging_internal_basename = \ + ::absl::raw_logging_internal::Basename(__FILE__, \ + sizeof(__FILE__) - 1); \ + ::absl::raw_logging_internal::internal_log_function( \ + ABSL_RAW_LOGGING_INTERNAL_##severity, \ + absl_raw_logging_internal_basename, __LINE__, message); \ + } while (0) + +#define ABSL_INTERNAL_CHECK(condition, message) \ + do { \ + if (ABSL_PREDICT_FALSE(!(condition))) { \ + std::string death_message = "Check " #condition " failed: "; \ + death_message += std::string(message); \ + ABSL_INTERNAL_LOG(FATAL, death_message); \ + } \ + } while (0) + +#define ABSL_RAW_LOGGING_INTERNAL_INFO ::absl::LogSeverity::kInfo +#define ABSL_RAW_LOGGING_INTERNAL_WARNING ::absl::LogSeverity::kWarning +#define ABSL_RAW_LOGGING_INTERNAL_ERROR ::absl::LogSeverity::kError +#define ABSL_RAW_LOGGING_INTERNAL_FATAL ::absl::LogSeverity::kFatal +#define ABSL_RAW_LOGGING_INTERNAL_LEVEL(severity) \ + ::absl::NormalizeLogSeverity(severity) + +namespace absl { +namespace raw_logging_internal { + +// Helper function to implement ABSL_RAW_LOG +// Logs format... at "severity" level, reporting it +// as called from file:line. +// This does not allocate memory or acquire locks. +void RawLog(absl::LogSeverity severity, const char* file, int line, + const char* format, ...) ABSL_PRINTF_ATTRIBUTE(4, 5); + +// Writes the provided buffer directly to stderr, in a safe, low-level manner. +// +// In POSIX this means calling write(), which is async-signal safe and does +// not malloc. If the platform supports the SYS_write syscall, we invoke that +// directly to side-step any libc interception. +void SafeWriteToStderr(const char *s, size_t len); + +// compile-time function to get the "base" filename, that is, the part of +// a filename after the last "/" or "\" path separator. The search starts at +// the end of the string; the second parameter is the length of the string. +constexpr const char* Basename(const char* fname, int offset) { + return offset == 0 || fname[offset - 1] == '/' || fname[offset - 1] == '\\' + ? fname + offset + : Basename(fname, offset - 1); +} + +// For testing only. +// Returns true if raw logging is fully supported. When it is not +// fully supported, no messages will be emitted, but a log at FATAL +// severity will cause an abort. +// +// TODO(gfalcon): Come up with a better name for this method. +bool RawLoggingFullySupported(); + +// Function type for a raw_logging customization hook for suppressing messages +// by severity, and for writing custom prefixes on non-suppressed messages. +// +// The installed hook is called for every raw log invocation. The message will +// be logged to stderr only if the hook returns true. FATAL errors will cause +// the process to abort, even if writing to stderr is suppressed. The hook is +// also provided with an output buffer, where it can write a custom log message +// prefix. +// +// The raw_logging system does not allocate memory or grab locks. User-provided +// hooks must avoid these operations, and must not throw exceptions. +// +// 'severity' is the severity level of the message being written. +// 'file' and 'line' are the file and line number where the ABSL_RAW_LOG macro +// was located. +// 'buffer' and 'buf_size' are pointers to the buffer and buffer size. If the +// hook writes a prefix, it must increment *buffer and decrement *buf_size +// accordingly. +using LogPrefixHook = bool (*)(absl::LogSeverity severity, const char* file, + int line, char** buffer, int* buf_size); + +// Function type for a raw_logging customization hook called to abort a process +// when a FATAL message is logged. If the provided AbortHook() returns, the +// logging system will call abort(). +// +// 'file' and 'line' are the file and line number where the ABSL_RAW_LOG macro +// was located. +// The null-terminated logged message lives in the buffer between 'buf_start' +// and 'buf_end'. 'prefix_end' points to the first non-prefix character of the +// buffer (as written by the LogPrefixHook.) +using AbortHook = void (*)(const char* file, int line, const char* buf_start, + const char* prefix_end, const char* buf_end); + +// Internal logging function for ABSL_INTERNAL_LOG to dispatch to. +// +// TODO(gfalcon): When string_view no longer depends on base, change this +// interface to take its message as a string_view instead. +using InternalLogFunction = void (*)(absl::LogSeverity severity, + const char* file, int line, + const std::string& message); + +extern base_internal::AtomicHook internal_log_function; + +void RegisterInternalLogFunction(InternalLogFunction func); + +} // namespace raw_logging_internal +} // namespace absl + +#endif // ABSL_BASE_INTERNAL_RAW_LOGGING_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/scheduling_mode.h b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/scheduling_mode.h new file mode 100644 index 0000000..1b6497a --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/scheduling_mode.h @@ -0,0 +1,54 @@ +// Copyright 2017 The Abseil Authors. +// +// 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. +// +// Core interfaces and definitions used by by low-level interfaces such as +// SpinLock. + +#ifndef ABSL_BASE_INTERNAL_SCHEDULING_MODE_H_ +#define ABSL_BASE_INTERNAL_SCHEDULING_MODE_H_ + +namespace absl { +namespace base_internal { + +// Used to describe how a thread may be scheduled. Typically associated with +// the declaration of a resource supporting synchronized access. +// +// SCHEDULE_COOPERATIVE_AND_KERNEL: +// Specifies that when waiting, a cooperative thread (e.g. a Fiber) may +// reschedule (using base::scheduling semantics); allowing other cooperative +// threads to proceed. +// +// SCHEDULE_KERNEL_ONLY: (Also described as "non-cooperative") +// Specifies that no cooperative scheduling semantics may be used, even if the +// current thread is itself cooperatively scheduled. This means that +// cooperative threads will NOT allow other cooperative threads to execute in +// their place while waiting for a resource of this type. Host operating system +// semantics (e.g. a futex) may still be used. +// +// When optional, clients should strongly prefer SCHEDULE_COOPERATIVE_AND_KERNEL +// by default. SCHEDULE_KERNEL_ONLY should only be used for resources on which +// base::scheduling (e.g. the implementation of a Scheduler) may depend. +// +// NOTE: Cooperative resources may not be nested below non-cooperative ones. +// This means that it is invalid to to acquire a SCHEDULE_COOPERATIVE_AND_KERNEL +// resource if a SCHEDULE_KERNEL_ONLY resource is already held. +enum SchedulingMode { + SCHEDULE_KERNEL_ONLY = 0, // Allow scheduling only the host OS. + SCHEDULE_COOPERATIVE_AND_KERNEL, // Also allow cooperative scheduling. +}; + +} // namespace base_internal +} // namespace absl + +#endif // ABSL_BASE_INTERNAL_SCHEDULING_MODE_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/spinlock.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/spinlock.cc new file mode 100644 index 0000000..cef149e --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/spinlock.cc @@ -0,0 +1,228 @@ +// Copyright 2017 The Abseil Authors. +// +// 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 "absl/base/internal/spinlock.h" + +#include +#include +#include + +#include "absl/base/attributes.h" +#include "absl/base/internal/atomic_hook.h" +#include "absl/base/internal/cycleclock.h" +#include "absl/base/internal/spinlock_wait.h" +#include "absl/base/internal/sysinfo.h" /* For NumCPUs() */ +#include "absl/base/call_once.h" + +// Description of lock-word: +// 31..00: [............................3][2][1][0] +// +// [0]: kSpinLockHeld +// [1]: kSpinLockCooperative +// [2]: kSpinLockDisabledScheduling +// [31..3]: ONLY kSpinLockSleeper OR +// Wait time in cycles >> PROFILE_TIMESTAMP_SHIFT +// +// Detailed descriptions: +// +// Bit [0]: The lock is considered held iff kSpinLockHeld is set. +// +// Bit [1]: Eligible waiters (e.g. Fibers) may co-operatively reschedule when +// contended iff kSpinLockCooperative is set. +// +// Bit [2]: This bit is exclusive from bit [1]. It is used only by a +// non-cooperative lock. When set, indicates that scheduling was +// successfully disabled when the lock was acquired. May be unset, +// even if non-cooperative, if a ThreadIdentity did not yet exist at +// time of acquisition. +// +// Bit [3]: If this is the only upper bit ([31..3]) set then this lock was +// acquired without contention, however, at least one waiter exists. +// +// Otherwise, bits [31..3] represent the time spent by the current lock +// holder to acquire the lock. There may be outstanding waiter(s). + +namespace absl { +namespace base_internal { + +ABSL_CONST_INIT static base_internal::AtomicHook + submit_profile_data; + +void RegisterSpinLockProfiler(void (*fn)(const void *contendedlock, + int64_t wait_cycles)) { + submit_profile_data.Store(fn); +} + +// Uncommon constructors. +SpinLock::SpinLock(base_internal::SchedulingMode mode) + : lockword_(IsCooperative(mode) ? kSpinLockCooperative : 0) { + ABSL_TSAN_MUTEX_CREATE(this, __tsan_mutex_not_static); +} + +SpinLock::SpinLock(base_internal::LinkerInitialized, + base_internal::SchedulingMode mode) { + ABSL_TSAN_MUTEX_CREATE(this, 0); + if (IsCooperative(mode)) { + InitLinkerInitializedAndCooperative(); + } + // Otherwise, lockword_ is already initialized. +} + +// Static (linker initialized) spinlocks always start life as functional +// non-cooperative locks. When their static constructor does run, it will call +// this initializer to augment the lockword with the cooperative bit. By +// actually taking the lock when we do this we avoid the need for an atomic +// operation in the regular unlock path. +// +// SlowLock() must be careful to re-test for this bit so that any outstanding +// waiters may be upgraded to cooperative status. +void SpinLock::InitLinkerInitializedAndCooperative() { + Lock(); + lockword_.fetch_or(kSpinLockCooperative, std::memory_order_relaxed); + Unlock(); +} + +// Monitor the lock to see if its value changes within some time period +// (adaptive_spin_count loop iterations). A timestamp indicating +// when the thread initially started waiting for the lock is passed in via +// the initial_wait_timestamp value. The total wait time in cycles for the +// lock is returned in the wait_cycles parameter. The last value read +// from the lock is returned from the method. +uint32_t SpinLock::SpinLoop(int64_t initial_wait_timestamp, + uint32_t *wait_cycles) { + // We are already in the slow path of SpinLock, initialize the + // adaptive_spin_count here. + ABSL_CONST_INIT static absl::once_flag init_adaptive_spin_count; + ABSL_CONST_INIT static int adaptive_spin_count = 0; + base_internal::LowLevelCallOnce(&init_adaptive_spin_count, []() { + adaptive_spin_count = base_internal::NumCPUs() > 1 ? 1000 : 1; + }); + + int c = adaptive_spin_count; + uint32_t lock_value; + do { + lock_value = lockword_.load(std::memory_order_relaxed); + } while ((lock_value & kSpinLockHeld) != 0 && --c > 0); + uint32_t spin_loop_wait_cycles = + EncodeWaitCycles(initial_wait_timestamp, CycleClock::Now()); + *wait_cycles = spin_loop_wait_cycles; + + return TryLockInternal(lock_value, spin_loop_wait_cycles); +} + +void SpinLock::SlowLock() { + // The lock was not obtained initially, so this thread needs to wait for + // it. Record the current timestamp in the local variable wait_start_time + // so the total wait time can be stored in the lockword once this thread + // obtains the lock. + int64_t wait_start_time = CycleClock::Now(); + uint32_t wait_cycles; + uint32_t lock_value = SpinLoop(wait_start_time, &wait_cycles); + + int lock_wait_call_count = 0; + while ((lock_value & kSpinLockHeld) != 0) { + // If the lock is currently held, but not marked as having a sleeper, mark + // it as having a sleeper. + if ((lock_value & kWaitTimeMask) == 0) { + // Here, just "mark" that the thread is going to sleep. Don't store the + // lock wait time in the lock as that will cause the current lock + // owner to think it experienced contention. + if (lockword_.compare_exchange_strong( + lock_value, lock_value | kSpinLockSleeper, + std::memory_order_relaxed, std::memory_order_relaxed)) { + // Successfully transitioned to kSpinLockSleeper. Pass + // kSpinLockSleeper to the SpinLockWait routine to properly indicate + // the last lock_value observed. + lock_value |= kSpinLockSleeper; + } else if ((lock_value & kSpinLockHeld) == 0) { + // Lock is free again, so try and acquire it before sleeping. The + // new lock state will be the number of cycles this thread waited if + // this thread obtains the lock. + lock_value = TryLockInternal(lock_value, wait_cycles); + continue; // Skip the delay at the end of the loop. + } + } + + base_internal::SchedulingMode scheduling_mode; + if ((lock_value & kSpinLockCooperative) != 0) { + scheduling_mode = base_internal::SCHEDULE_COOPERATIVE_AND_KERNEL; + } else { + scheduling_mode = base_internal::SCHEDULE_KERNEL_ONLY; + } + // SpinLockDelay() calls into fiber scheduler, we need to see + // synchronization there to avoid false positives. + ABSL_TSAN_MUTEX_PRE_DIVERT(this, 0); + // Wait for an OS specific delay. + base_internal::SpinLockDelay(&lockword_, lock_value, ++lock_wait_call_count, + scheduling_mode); + ABSL_TSAN_MUTEX_POST_DIVERT(this, 0); + // Spin again after returning from the wait routine to give this thread + // some chance of obtaining the lock. + lock_value = SpinLoop(wait_start_time, &wait_cycles); + } +} + +void SpinLock::SlowUnlock(uint32_t lock_value) { + base_internal::SpinLockWake(&lockword_, + false); // wake waiter if necessary + + // If our acquisition was contended, collect contentionz profile info. We + // reserve a unitary wait time to represent that a waiter exists without our + // own acquisition having been contended. + if ((lock_value & kWaitTimeMask) != kSpinLockSleeper) { + const uint64_t wait_cycles = DecodeWaitCycles(lock_value); + ABSL_TSAN_MUTEX_PRE_DIVERT(this, 0); + submit_profile_data(this, wait_cycles); + ABSL_TSAN_MUTEX_POST_DIVERT(this, 0); + } +} + +// We use the upper 29 bits of the lock word to store the time spent waiting to +// acquire this lock. This is reported by contentionz profiling. Since the +// lower bits of the cycle counter wrap very quickly on high-frequency +// processors we divide to reduce the granularity to 2^PROFILE_TIMESTAMP_SHIFT +// sized units. On a 4Ghz machine this will lose track of wait times greater +// than (2^29/4 Ghz)*128 =~ 17.2 seconds. Such waits should be extremely rare. +enum { PROFILE_TIMESTAMP_SHIFT = 7 }; +enum { LOCKWORD_RESERVED_SHIFT = 3 }; // We currently reserve the lower 3 bits. + +uint32_t SpinLock::EncodeWaitCycles(int64_t wait_start_time, + int64_t wait_end_time) { + static const int64_t kMaxWaitTime = + std::numeric_limits::max() >> LOCKWORD_RESERVED_SHIFT; + int64_t scaled_wait_time = + (wait_end_time - wait_start_time) >> PROFILE_TIMESTAMP_SHIFT; + + // Return a representation of the time spent waiting that can be stored in + // the lock word's upper bits. bit_cast is required as Atomic32 is signed. + const uint32_t clamped = static_cast( + std::min(scaled_wait_time, kMaxWaitTime) << LOCKWORD_RESERVED_SHIFT); + + // bump up value if necessary to avoid returning kSpinLockSleeper. + const uint32_t after_spinlock_sleeper = + kSpinLockSleeper + (1 << LOCKWORD_RESERVED_SHIFT); + return clamped == kSpinLockSleeper ? after_spinlock_sleeper : clamped; +} + +uint64_t SpinLock::DecodeWaitCycles(uint32_t lock_value) { + // Cast to uint32_t first to ensure bits [63:32] are cleared. + const uint64_t scaled_wait_time = + static_cast(lock_value & kWaitTimeMask); + return scaled_wait_time + << (PROFILE_TIMESTAMP_SHIFT - LOCKWORD_RESERVED_SHIFT); +} + +} // namespace base_internal +} // namespace absl diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/spinlock.h b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/spinlock.h new file mode 100644 index 0000000..212abc6 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/spinlock.h @@ -0,0 +1,239 @@ +// +// Copyright 2017 The Abseil Authors. +// +// 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. +// + +// Most users requiring mutual exclusion should use Mutex. +// SpinLock is provided for use in three situations: +// - for use in code that Mutex itself depends on +// - to get a faster fast-path release under low contention (without an +// atomic read-modify-write) In return, SpinLock has worse behaviour under +// contention, which is why Mutex is preferred in most situations. +// - for async signal safety (see below) + +// SpinLock is async signal safe. If a spinlock is used within a signal +// handler, all code that acquires the lock must ensure that the signal cannot +// arrive while they are holding the lock. Typically, this is done by blocking +// the signal. + +#ifndef ABSL_BASE_INTERNAL_SPINLOCK_H_ +#define ABSL_BASE_INTERNAL_SPINLOCK_H_ + +#include +#include +#include + +#include "absl/base/attributes.h" +#include "absl/base/dynamic_annotations.h" +#include "absl/base/internal/low_level_scheduling.h" +#include "absl/base/internal/raw_logging.h" +#include "absl/base/internal/scheduling_mode.h" +#include "absl/base/internal/tsan_mutex_interface.h" +#include "absl/base/macros.h" +#include "absl/base/port.h" +#include "absl/base/thread_annotations.h" + +namespace absl { +namespace base_internal { + +class LOCKABLE SpinLock { + public: + SpinLock() : lockword_(kSpinLockCooperative) { + ABSL_TSAN_MUTEX_CREATE(this, __tsan_mutex_not_static); + } + + // Special constructor for use with static SpinLock objects. E.g., + // + // static SpinLock lock(base_internal::kLinkerInitialized); + // + // When intialized using this constructor, we depend on the fact + // that the linker has already initialized the memory appropriately. + // A SpinLock constructed like this can be freely used from global + // initializers without worrying about the order in which global + // initializers run. + explicit SpinLock(base_internal::LinkerInitialized) { + // Does nothing; lockword_ is already initialized + ABSL_TSAN_MUTEX_CREATE(this, 0); + } + + // Constructors that allow non-cooperative spinlocks to be created for use + // inside thread schedulers. Normal clients should not use these. + explicit SpinLock(base_internal::SchedulingMode mode); + SpinLock(base_internal::LinkerInitialized, + base_internal::SchedulingMode mode); + + ~SpinLock() { ABSL_TSAN_MUTEX_DESTROY(this, __tsan_mutex_not_static); } + + // Acquire this SpinLock. + inline void Lock() EXCLUSIVE_LOCK_FUNCTION() { + ABSL_TSAN_MUTEX_PRE_LOCK(this, 0); + if (!TryLockImpl()) { + SlowLock(); + } + ABSL_TSAN_MUTEX_POST_LOCK(this, 0, 0); + } + + // Try to acquire this SpinLock without blocking and return true if the + // acquisition was successful. If the lock was not acquired, false is + // returned. If this SpinLock is free at the time of the call, TryLock + // will return true with high probability. + inline bool TryLock() EXCLUSIVE_TRYLOCK_FUNCTION(true) { + ABSL_TSAN_MUTEX_PRE_LOCK(this, __tsan_mutex_try_lock); + bool res = TryLockImpl(); + ABSL_TSAN_MUTEX_POST_LOCK( + this, __tsan_mutex_try_lock | (res ? 0 : __tsan_mutex_try_lock_failed), + 0); + return res; + } + + // Release this SpinLock, which must be held by the calling thread. + inline void Unlock() UNLOCK_FUNCTION() { + ABSL_TSAN_MUTEX_PRE_UNLOCK(this, 0); + uint32_t lock_value = lockword_.load(std::memory_order_relaxed); + lockword_.store(lock_value & kSpinLockCooperative, + std::memory_order_release); + + if ((lock_value & kSpinLockDisabledScheduling) != 0) { + base_internal::SchedulingGuard::EnableRescheduling(true); + } + if ((lock_value & kWaitTimeMask) != 0) { + // Collect contentionz profile info, and speed the wakeup of any waiter. + // The wait_cycles value indicates how long this thread spent waiting + // for the lock. + SlowUnlock(lock_value); + } + ABSL_TSAN_MUTEX_POST_UNLOCK(this, 0); + } + + // Determine if the lock is held. When the lock is held by the invoking + // thread, true will always be returned. Intended to be used as + // CHECK(lock.IsHeld()). + inline bool IsHeld() const { + return (lockword_.load(std::memory_order_relaxed) & kSpinLockHeld) != 0; + } + + protected: + // These should not be exported except for testing. + + // Store number of cycles between wait_start_time and wait_end_time in a + // lock value. + static uint32_t EncodeWaitCycles(int64_t wait_start_time, + int64_t wait_end_time); + + // Extract number of wait cycles in a lock value. + static uint64_t DecodeWaitCycles(uint32_t lock_value); + + // Provide access to protected method above. Use for testing only. + friend struct SpinLockTest; + + private: + // lockword_ is used to store the following: + // + // bit[0] encodes whether a lock is being held. + // bit[1] encodes whether a lock uses cooperative scheduling. + // bit[2] encodes whether a lock disables scheduling. + // bit[3:31] encodes time a lock spent on waiting as a 29-bit unsigned int. + enum { kSpinLockHeld = 1 }; + enum { kSpinLockCooperative = 2 }; + enum { kSpinLockDisabledScheduling = 4 }; + enum { kSpinLockSleeper = 8 }; + enum { kWaitTimeMask = // Includes kSpinLockSleeper. + ~(kSpinLockHeld | kSpinLockCooperative | kSpinLockDisabledScheduling) }; + + // Returns true if the provided scheduling mode is cooperative. + static constexpr bool IsCooperative( + base_internal::SchedulingMode scheduling_mode) { + return scheduling_mode == base_internal::SCHEDULE_COOPERATIVE_AND_KERNEL; + } + + uint32_t TryLockInternal(uint32_t lock_value, uint32_t wait_cycles); + void InitLinkerInitializedAndCooperative(); + void SlowLock() ABSL_ATTRIBUTE_COLD; + void SlowUnlock(uint32_t lock_value) ABSL_ATTRIBUTE_COLD; + uint32_t SpinLoop(int64_t initial_wait_timestamp, uint32_t* wait_cycles); + + inline bool TryLockImpl() { + uint32_t lock_value = lockword_.load(std::memory_order_relaxed); + return (TryLockInternal(lock_value, 0) & kSpinLockHeld) == 0; + } + + std::atomic lockword_; + + SpinLock(const SpinLock&) = delete; + SpinLock& operator=(const SpinLock&) = delete; +}; + +// Corresponding locker object that arranges to acquire a spinlock for +// the duration of a C++ scope. +class SCOPED_LOCKABLE SpinLockHolder { + public: + inline explicit SpinLockHolder(SpinLock* l) EXCLUSIVE_LOCK_FUNCTION(l) + : lock_(l) { + l->Lock(); + } + inline ~SpinLockHolder() UNLOCK_FUNCTION() { lock_->Unlock(); } + + SpinLockHolder(const SpinLockHolder&) = delete; + SpinLockHolder& operator=(const SpinLockHolder&) = delete; + + private: + SpinLock* lock_; +}; + +// Register a hook for profiling support. +// +// The function pointer registered here will be called whenever a spinlock is +// contended. The callback is given an opaque handle to the contended spinlock +// and the number of wait cycles. This is thread-safe, but only a single +// profiler can be registered. It is an error to call this function multiple +// times with different arguments. +void RegisterSpinLockProfiler(void (*fn)(const void* lock, + int64_t wait_cycles)); + +//------------------------------------------------------------------------------ +// Public interface ends here. +//------------------------------------------------------------------------------ + +// If (result & kSpinLockHeld) == 0, then *this was successfully locked. +// Otherwise, returns last observed value for lockword_. +inline uint32_t SpinLock::TryLockInternal(uint32_t lock_value, + uint32_t wait_cycles) { + if ((lock_value & kSpinLockHeld) != 0) { + return lock_value; + } + + uint32_t sched_disabled_bit = 0; + if ((lock_value & kSpinLockCooperative) == 0) { + // For non-cooperative locks we must make sure we mark ourselves as + // non-reschedulable before we attempt to CompareAndSwap. + if (base_internal::SchedulingGuard::DisableRescheduling()) { + sched_disabled_bit = kSpinLockDisabledScheduling; + } + } + + if (lockword_.compare_exchange_strong( + lock_value, + kSpinLockHeld | lock_value | wait_cycles | sched_disabled_bit, + std::memory_order_acquire, std::memory_order_relaxed)) { + } else { + base_internal::SchedulingGuard::EnableRescheduling(sched_disabled_bit != 0); + } + + return lock_value; +} + +} // namespace base_internal +} // namespace absl + +#endif // ABSL_BASE_INTERNAL_SPINLOCK_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/spinlock_akaros.inc b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/spinlock_akaros.inc new file mode 100644 index 0000000..051c8cf --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/spinlock_akaros.inc @@ -0,0 +1,35 @@ +// Copyright 2017 The Abseil Authors. +// +// 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. +// +// This file is an Akaros-specific part of spinlock_wait.cc + +#include + +#include "absl/base/internal/scheduling_mode.h" + +extern "C" { + +ABSL_ATTRIBUTE_WEAK void AbslInternalSpinLockDelay( + std::atomic* /* lock_word */, uint32_t /* value */, + int /* loop */, absl::base_internal::SchedulingMode /* mode */) { + // In Akaros, one must take care not to call anything that could cause a + // malloc(), a blocking system call, or a uthread_yield() while holding a + // spinlock. Our callers assume will not call into libraries or other + // arbitrary code. +} + +ABSL_ATTRIBUTE_WEAK void AbslInternalSpinLockWake( + std::atomic* /* lock_word */, bool /* all */) {} + +} // extern "C" diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/spinlock_linux.inc b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/spinlock_linux.inc new file mode 100644 index 0000000..94c861d --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/spinlock_linux.inc @@ -0,0 +1,72 @@ +// Copyright 2018 The Abseil Authors. +// +// 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. +// +// This file is a Linux-specific part of spinlock_wait.cc + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "absl/base/attributes.h" + +// The SpinLock lockword is `std::atomic`. Here we assert that +// `std::atomic` is bitwise equivalent of the `int` expected +// by SYS_futex. We also assume that reads/writes done to the lockword +// by SYS_futex have rational semantics with regard to the +// std::atomic<> API. C++ provides no guarantees of these assumptions, +// but they are believed to hold in practice. +static_assert(sizeof(std::atomic) == sizeof(int), + "SpinLock lockword has the wrong size for a futex"); + +// Some Android headers are missing these definitions even though they +// support these futex operations. +#ifdef __BIONIC__ +#ifndef SYS_futex +#define SYS_futex __NR_futex +#endif +#ifndef FUTEX_PRIVATE_FLAG +#define FUTEX_PRIVATE_FLAG 128 +#endif +#endif + +extern "C" { + +ABSL_ATTRIBUTE_WEAK void AbslInternalSpinLockDelay( + std::atomic *w, uint32_t value, int loop, + absl::base_internal::SchedulingMode) { + if (loop != 0) { + int save_errno = errno; + struct timespec tm; + tm.tv_sec = 0; + // Increase the delay; we expect (but do not rely on) explicit wakeups. + // We don't rely on explicit wakeups because we intentionally allow for + // a race on the kSpinLockSleeper bit. + tm.tv_nsec = 16 * absl::base_internal::SpinLockSuggestedDelayNS(loop); + syscall(SYS_futex, w, FUTEX_WAIT | FUTEX_PRIVATE_FLAG, value, &tm); + errno = save_errno; + } +} + +ABSL_ATTRIBUTE_WEAK void AbslInternalSpinLockWake(std::atomic *w, + bool all) { + syscall(SYS_futex, w, FUTEX_WAKE | FUTEX_PRIVATE_FLAG, all ? INT_MAX : 1, 0); +} + +} // extern "C" diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/spinlock_posix.inc b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/spinlock_posix.inc new file mode 100644 index 0000000..0098c1c --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/spinlock_posix.inc @@ -0,0 +1,46 @@ +// Copyright 2017 The Abseil Authors. +// +// 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. +// +// This file is a Posix-specific part of spinlock_wait.cc + +#include +#include +#include +#include + +#include "absl/base/internal/scheduling_mode.h" +#include "absl/base/port.h" + +extern "C" { + +ABSL_ATTRIBUTE_WEAK void AbslInternalSpinLockDelay( + std::atomic* /* lock_word */, uint32_t /* value */, int loop, + absl::base_internal::SchedulingMode /* mode */) { + int save_errno = errno; + if (loop == 0) { + } else if (loop == 1) { + sched_yield(); + } else { + struct timespec tm; + tm.tv_sec = 0; + tm.tv_nsec = absl::base_internal::SpinLockSuggestedDelayNS(loop); + nanosleep(&tm, nullptr); + } + errno = save_errno; +} + +ABSL_ATTRIBUTE_WEAK void AbslInternalSpinLockWake( + std::atomic* /* lock_word */, bool /* all */) {} + +} // extern "C" diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/spinlock_wait.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/spinlock_wait.cc new file mode 100644 index 0000000..365a793 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/spinlock_wait.cc @@ -0,0 +1,82 @@ +// Copyright 2017 The Abseil Authors. +// +// 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. + +// The OS-specific header included below must provide two calls: +// AbslInternalSpinLockDelay() and AbslInternalSpinLockWake(). +// See spinlock_wait.h for the specs. + +#include +#include + +#include "absl/base/internal/spinlock_wait.h" + +#if defined(_WIN32) +#include "absl/base/internal/spinlock_win32.inc" +#elif defined(__linux__) +#include "absl/base/internal/spinlock_linux.inc" +#elif defined(__akaros__) +#include "absl/base/internal/spinlock_akaros.inc" +#else +#include "absl/base/internal/spinlock_posix.inc" +#endif + +namespace absl { +namespace base_internal { + +// See spinlock_wait.h for spec. +uint32_t SpinLockWait(std::atomic *w, int n, + const SpinLockWaitTransition trans[], + base_internal::SchedulingMode scheduling_mode) { + int loop = 0; + for (;;) { + uint32_t v = w->load(std::memory_order_acquire); + int i; + for (i = 0; i != n && v != trans[i].from; i++) { + } + if (i == n) { + SpinLockDelay(w, v, ++loop, scheduling_mode); // no matching transition + } else if (trans[i].to == v || // null transition + w->compare_exchange_strong(v, trans[i].to, + std::memory_order_acquire, + std::memory_order_relaxed)) { + if (trans[i].done) return v; + } + } +} + +static std::atomic delay_rand; + +// Return a suggested delay in nanoseconds for iteration number "loop" +int SpinLockSuggestedDelayNS(int loop) { + // Weak pseudo-random number generator to get some spread between threads + // when many are spinning. + uint64_t r = delay_rand.load(std::memory_order_relaxed); + r = 0x5deece66dLL * r + 0xb; // numbers from nrand48() + delay_rand.store(r, std::memory_order_relaxed); + + r <<= 16; // 48-bit random number now in top 48-bits. + if (loop < 0 || loop > 32) { // limit loop to 0..32 + loop = 32; + } + // loop>>3 cannot exceed 4 because loop cannot exceed 32. + // Select top 20..24 bits of lower 48 bits, + // giving approximately 0ms to 16ms. + // Mean is exponential in loop for first 32 iterations, then 8ms. + // The futex path multiplies this by 16, since we expect explicit wakeups + // almost always on that path. + return static_cast(r >> (44 - (loop >> 3))); +} + +} // namespace base_internal +} // namespace absl diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/spinlock_wait.h b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/spinlock_wait.h new file mode 100644 index 0000000..5c6cc7f --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/spinlock_wait.h @@ -0,0 +1,91 @@ +// Copyright 2017 The Abseil Authors. +// +// 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. + +#ifndef ABSL_BASE_INTERNAL_SPINLOCK_WAIT_H_ +#define ABSL_BASE_INTERNAL_SPINLOCK_WAIT_H_ + +// Operations to make atomic transitions on a word, and to allow +// waiting for those transitions to become possible. + +#include +#include + +#include "absl/base/internal/scheduling_mode.h" + +namespace absl { +namespace base_internal { + +// SpinLockWait() waits until it can perform one of several transitions from +// "from" to "to". It returns when it performs a transition where done==true. +struct SpinLockWaitTransition { + uint32_t from; + uint32_t to; + bool done; +}; + +// Wait until *w can transition from trans[i].from to trans[i].to for some i +// satisfying 0<=i *w, int n, + const SpinLockWaitTransition trans[], + SchedulingMode scheduling_mode); + +// If possible, wake some thread that has called SpinLockDelay(w, ...). If +// "all" is true, wake all such threads. This call is a hint, and on some +// systems it may be a no-op; threads calling SpinLockDelay() will always wake +// eventually even if SpinLockWake() is never called. +void SpinLockWake(std::atomic *w, bool all); + +// Wait for an appropriate spin delay on iteration "loop" of a +// spin loop on location *w, whose previously observed value was "value". +// SpinLockDelay() may do nothing, may yield the CPU, may sleep a clock tick, +// or may wait for a delay that can be truncated by a call to SpinLockWake(w). +// In all cases, it must return in bounded time even if SpinLockWake() is not +// called. +void SpinLockDelay(std::atomic *w, uint32_t value, int loop, + base_internal::SchedulingMode scheduling_mode); + +// Helper used by AbslInternalSpinLockDelay. +// Returns a suggested delay in nanoseconds for iteration number "loop". +int SpinLockSuggestedDelayNS(int loop); + +} // namespace base_internal +} // namespace absl + +// In some build configurations we pass --detect-odr-violations to the +// gold linker. This causes it to flag weak symbol overrides as ODR +// violations. Because ODR only applies to C++ and not C, +// --detect-odr-violations ignores symbols not mangled with C++ names. +// By changing our extension points to be extern "C", we dodge this +// check. +extern "C" { +void AbslInternalSpinLockWake(std::atomic *w, bool all); +void AbslInternalSpinLockDelay( + std::atomic *w, uint32_t value, int loop, + absl::base_internal::SchedulingMode scheduling_mode); +} + +inline void absl::base_internal::SpinLockWake(std::atomic *w, + bool all) { + AbslInternalSpinLockWake(w, all); +} + +inline void absl::base_internal::SpinLockDelay( + std::atomic *w, uint32_t value, int loop, + absl::base_internal::SchedulingMode scheduling_mode) { + AbslInternalSpinLockDelay(w, value, loop, scheduling_mode); +} + +#endif // ABSL_BASE_INTERNAL_SPINLOCK_WAIT_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/spinlock_win32.inc b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/spinlock_win32.inc new file mode 100644 index 0000000..32c8fc0 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/spinlock_win32.inc @@ -0,0 +1,37 @@ +// Copyright 2017 The Abseil Authors. +// +// 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. +// +// This file is a Win32-specific part of spinlock_wait.cc + +#include +#include +#include "absl/base/internal/scheduling_mode.h" + +extern "C" { + +void AbslInternalSpinLockDelay(std::atomic* /* lock_word */, + uint32_t /* value */, int loop, + absl::base_internal::SchedulingMode /* mode */) { + if (loop == 0) { + } else if (loop == 1) { + Sleep(0); + } else { + Sleep(absl::base_internal::SpinLockSuggestedDelayNS(loop) / 1000000); + } +} + +void AbslInternalSpinLockWake(std::atomic* /* lock_word */, + bool /* all */) {} + +} // extern "C" diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/sysinfo.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/sysinfo.cc new file mode 100644 index 0000000..db41bac --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/sysinfo.cc @@ -0,0 +1,404 @@ +// Copyright 2017 The Abseil Authors. +// +// 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 "absl/base/internal/sysinfo.h" + +#include "absl/base/attributes.h" + +#ifdef _WIN32 +#include +#include +#else +#include +#include +#include +#include +#include +#endif + +#ifdef __linux__ +#include +#endif + +#if defined(__APPLE__) || defined(__FreeBSD__) +#include +#endif + +#if defined(__myriad2__) +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include // NOLINT(build/c++11) +#include +#include + +#include "absl/base/call_once.h" +#include "absl/base/internal/raw_logging.h" +#include "absl/base/internal/spinlock.h" +#include "absl/base/internal/unscaledcycleclock.h" + +namespace absl { +namespace base_internal { + +static once_flag init_system_info_once; +static int num_cpus = 0; +static double nominal_cpu_frequency = 1.0; // 0.0 might be dangerous. + +static int GetNumCPUs() { +#if defined(__myriad2__) + return 1; +#else + // Other possibilities: + // - Read /sys/devices/system/cpu/online and use cpumask_parse() + // - sysconf(_SC_NPROCESSORS_ONLN) + return std::thread::hardware_concurrency(); +#endif +} + +#if defined(_WIN32) + +static double GetNominalCPUFrequency() { + DWORD data; + DWORD data_size = sizeof(data); + #pragma comment(lib, "shlwapi.lib") // For SHGetValue(). + if (SUCCEEDED( + SHGetValueA(HKEY_LOCAL_MACHINE, + "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0", + "~MHz", nullptr, &data, &data_size))) { + return data * 1e6; // Value is MHz. + } + return 1.0; +} + +#elif defined(CTL_HW) && defined(HW_CPU_FREQ) + +static double GetNominalCPUFrequency() { + unsigned freq; + size_t size = sizeof(freq); + int mib[2] = {CTL_HW, HW_CPU_FREQ}; + if (sysctl(mib, 2, &freq, &size, nullptr, 0) == 0) { + return static_cast(freq); + } + return 1.0; +} + +#else + +// Helper function for reading a long from a file. Returns true if successful +// and the memory location pointed to by value is set to the value read. +static bool ReadLongFromFile(const char *file, long *value) { + bool ret = false; + int fd = open(file, O_RDONLY); + if (fd != -1) { + char line[1024]; + char *err; + memset(line, '\0', sizeof(line)); + int len = read(fd, line, sizeof(line) - 1); + if (len <= 0) { + ret = false; + } else { + const long temp_value = strtol(line, &err, 10); + if (line[0] != '\0' && (*err == '\n' || *err == '\0')) { + *value = temp_value; + ret = true; + } + } + close(fd); + } + return ret; +} + +#if defined(ABSL_INTERNAL_UNSCALED_CYCLECLOCK_FREQUENCY_IS_CPU_FREQUENCY) + +// Reads a monotonic time source and returns a value in +// nanoseconds. The returned value uses an arbitrary epoch, not the +// Unix epoch. +static int64_t ReadMonotonicClockNanos() { + struct timespec t; +#ifdef CLOCK_MONOTONIC_RAW + int rc = clock_gettime(CLOCK_MONOTONIC_RAW, &t); +#else + int rc = clock_gettime(CLOCK_MONOTONIC, &t); +#endif + if (rc != 0) { + perror("clock_gettime() failed"); + abort(); + } + return int64_t{t.tv_sec} * 1000000000 + t.tv_nsec; +} + +class UnscaledCycleClockWrapperForInitializeFrequency { + public: + static int64_t Now() { return base_internal::UnscaledCycleClock::Now(); } +}; + +struct TimeTscPair { + int64_t time; // From ReadMonotonicClockNanos(). + int64_t tsc; // From UnscaledCycleClock::Now(). +}; + +// Returns a pair of values (monotonic kernel time, TSC ticks) that +// approximately correspond to each other. This is accomplished by +// doing several reads and picking the reading with the lowest +// latency. This approach is used to minimize the probability that +// our thread was preempted between clock reads. +static TimeTscPair GetTimeTscPair() { + int64_t best_latency = std::numeric_limits::max(); + TimeTscPair best; + for (int i = 0; i < 10; ++i) { + int64_t t0 = ReadMonotonicClockNanos(); + int64_t tsc = UnscaledCycleClockWrapperForInitializeFrequency::Now(); + int64_t t1 = ReadMonotonicClockNanos(); + int64_t latency = t1 - t0; + if (latency < best_latency) { + best_latency = latency; + best.time = t0; + best.tsc = tsc; + } + } + return best; +} + +// Measures and returns the TSC frequency by taking a pair of +// measurements approximately `sleep_nanoseconds` apart. +static double MeasureTscFrequencyWithSleep(int sleep_nanoseconds) { + auto t0 = GetTimeTscPair(); + struct timespec ts; + ts.tv_sec = 0; + ts.tv_nsec = sleep_nanoseconds; + while (nanosleep(&ts, &ts) != 0 && errno == EINTR) {} + auto t1 = GetTimeTscPair(); + double elapsed_ticks = t1.tsc - t0.tsc; + double elapsed_time = (t1.time - t0.time) * 1e-9; + return elapsed_ticks / elapsed_time; +} + +// Measures and returns the TSC frequency by calling +// MeasureTscFrequencyWithSleep(), doubling the sleep interval until the +// frequency measurement stabilizes. +static double MeasureTscFrequency() { + double last_measurement = -1.0; + int sleep_nanoseconds = 1000000; // 1 millisecond. + for (int i = 0; i < 8; ++i) { + double measurement = MeasureTscFrequencyWithSleep(sleep_nanoseconds); + if (measurement * 0.99 < last_measurement && + last_measurement < measurement * 1.01) { + // Use the current measurement if it is within 1% of the + // previous measurement. + return measurement; + } + last_measurement = measurement; + sleep_nanoseconds *= 2; + } + return last_measurement; +} + +#endif // ABSL_INTERNAL_UNSCALED_CYCLECLOCK_FREQUENCY_IS_CPU_FREQUENCY + +static double GetNominalCPUFrequency() { + long freq = 0; + + // Google's production kernel has a patch to export the TSC + // frequency through sysfs. If the kernel is exporting the TSC + // frequency use that. There are issues where cpuinfo_max_freq + // cannot be relied on because the BIOS may be exporting an invalid + // p-state (on x86) or p-states may be used to put the processor in + // a new mode (turbo mode). Essentially, those frequencies cannot + // always be relied upon. The same reasons apply to /proc/cpuinfo as + // well. + if (ReadLongFromFile("/sys/devices/system/cpu/cpu0/tsc_freq_khz", &freq)) { + return freq * 1e3; // Value is kHz. + } + +#if defined(ABSL_INTERNAL_UNSCALED_CYCLECLOCK_FREQUENCY_IS_CPU_FREQUENCY) + // On these platforms, the TSC frequency is the nominal CPU + // frequency. But without having the kernel export it directly + // though /sys/devices/system/cpu/cpu0/tsc_freq_khz, there is no + // other way to reliably get the TSC frequency, so we have to + // measure it ourselves. Some CPUs abuse cpuinfo_max_freq by + // exporting "fake" frequencies for implementing new features. For + // example, Intel's turbo mode is enabled by exposing a p-state + // value with a higher frequency than that of the real TSC + // rate. Because of this, we prefer to measure the TSC rate + // ourselves on i386 and x86-64. + return MeasureTscFrequency(); +#else + + // If CPU scaling is in effect, we want to use the *maximum* + // frequency, not whatever CPU speed some random processor happens + // to be using now. + if (ReadLongFromFile("/sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq", + &freq)) { + return freq * 1e3; // Value is kHz. + } + + return 1.0; +#endif // !ABSL_INTERNAL_UNSCALED_CYCLECLOCK_FREQUENCY_IS_CPU_FREQUENCY +} + +#endif + +// InitializeSystemInfo() may be called before main() and before +// malloc is properly initialized, therefore this must not allocate +// memory. +static void InitializeSystemInfo() { + num_cpus = GetNumCPUs(); + nominal_cpu_frequency = GetNominalCPUFrequency(); +} + +int NumCPUs() { + base_internal::LowLevelCallOnce(&init_system_info_once, InitializeSystemInfo); + return num_cpus; +} + +double NominalCPUFrequency() { + base_internal::LowLevelCallOnce(&init_system_info_once, InitializeSystemInfo); + return nominal_cpu_frequency; +} + +#if defined(_WIN32) + +pid_t GetTID() { + return GetCurrentThreadId(); +} + +#elif defined(__linux__) + +#ifndef SYS_gettid +#define SYS_gettid __NR_gettid +#endif + +pid_t GetTID() { + return syscall(SYS_gettid); +} + +#elif defined(__akaros__) + +pid_t GetTID() { + // Akaros has a concept of "vcore context", which is the state the program + // is forced into when we need to make a user-level scheduling decision, or + // run a signal handler. This is analogous to the interrupt context that a + // CPU might enter if it encounters some kind of exception. + // + // There is no current thread context in vcore context, but we need to give + // a reasonable answer if asked for a thread ID (e.g., in a signal handler). + // Thread 0 always exists, so if we are in vcore context, we return that. + // + // Otherwise, we know (since we are using pthreads) that the uthread struct + // current_uthread is pointing to is the first element of a + // struct pthread_tcb, so we extract and return the thread ID from that. + // + // TODO(dcross): Akaros anticipates moving the thread ID to the uthread + // structure at some point. We should modify this code to remove the cast + // when that happens. + if (in_vcore_context()) + return 0; + return reinterpret_cast(current_uthread)->id; +} + +#elif defined(__myriad2__) + +pid_t GetTID() { + uint32_t tid; + rtems_task_ident(RTEMS_SELF, 0, &tid); + return tid; +} + +#else + +// Fallback implementation of GetTID using pthread_getspecific. +static once_flag tid_once; +static pthread_key_t tid_key; +static absl::base_internal::SpinLock tid_lock( + absl::base_internal::kLinkerInitialized); + +// We set a bit per thread in this array to indicate that an ID is in +// use. ID 0 is unused because it is the default value returned by +// pthread_getspecific(). +static std::vector* tid_array GUARDED_BY(tid_lock) = nullptr; +static constexpr int kBitsPerWord = 32; // tid_array is uint32_t. + +// Returns the TID to tid_array. +static void FreeTID(void *v) { + intptr_t tid = reinterpret_cast(v); + int word = tid / kBitsPerWord; + uint32_t mask = ~(1u << (tid % kBitsPerWord)); + absl::base_internal::SpinLockHolder lock(&tid_lock); + assert(0 <= word && static_cast(word) < tid_array->size()); + (*tid_array)[word] &= mask; +} + +static void InitGetTID() { + if (pthread_key_create(&tid_key, FreeTID) != 0) { + // The logging system calls GetTID() so it can't be used here. + perror("pthread_key_create failed"); + abort(); + } + + // Initialize tid_array. + absl::base_internal::SpinLockHolder lock(&tid_lock); + tid_array = new std::vector(1); + (*tid_array)[0] = 1; // ID 0 is never-allocated. +} + +// Return a per-thread small integer ID from pthread's thread-specific data. +pid_t GetTID() { + absl::call_once(tid_once, InitGetTID); + + intptr_t tid = reinterpret_cast(pthread_getspecific(tid_key)); + if (tid != 0) { + return tid; + } + + int bit; // tid_array[word] = 1u << bit; + size_t word; + { + // Search for the first unused ID. + absl::base_internal::SpinLockHolder lock(&tid_lock); + // First search for a word in the array that is not all ones. + word = 0; + while (word < tid_array->size() && ~(*tid_array)[word] == 0) { + ++word; + } + if (word == tid_array->size()) { + tid_array->push_back(0); // No space left, add kBitsPerWord more IDs. + } + // Search for a zero bit in the word. + bit = 0; + while (bit < kBitsPerWord && (((*tid_array)[word] >> bit) & 1) != 0) { + ++bit; + } + tid = (word * kBitsPerWord) + bit; + (*tid_array)[word] |= 1u << bit; // Mark the TID as allocated. + } + + if (pthread_setspecific(tid_key, reinterpret_cast(tid)) != 0) { + perror("pthread_setspecific failed"); + abort(); + } + + return static_cast(tid); +} + +#endif + +} // namespace base_internal +} // namespace absl diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/sysinfo.h b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/sysinfo.h new file mode 100644 index 0000000..5bd1c50 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/sysinfo.h @@ -0,0 +1,63 @@ +// Copyright 2017 The Abseil Authors. +// +// 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. +// +// This file includes routines to find out characteristics +// of the machine a program is running on. It is undoubtedly +// system-dependent. + +// Functions listed here that accept a pid_t as an argument act on the +// current process if the pid_t argument is 0 +// All functions here are thread-hostile due to file caching unless +// commented otherwise. + +#ifndef ABSL_BASE_INTERNAL_SYSINFO_H_ +#define ABSL_BASE_INTERNAL_SYSINFO_H_ + +#ifndef _WIN32 +#include +#else +#include +#endif + +#include "absl/base/port.h" + +namespace absl { +namespace base_internal { + +// Nominal core processor cycles per second of each processor. This is _not_ +// necessarily the frequency of the CycleClock counter (see cycleclock.h) +// Thread-safe. +double NominalCPUFrequency(); + +// Number of logical processors (hyperthreads) in system. Thread-safe. +int NumCPUs(); + +// Return the thread id of the current thread, as told by the system. +// No two currently-live threads implemented by the OS shall have the same ID. +// Thread ids of exited threads may be reused. Multiple user-level threads +// may have the same thread ID if multiplexed on the same OS thread. +// +// On Linux, you may send a signal to the resulting ID with kill(). However, +// it is recommended for portability that you use pthread_kill() instead. +#ifdef _WIN32 +// On Windows, process id and thread id are of the same type according to +// the return types of GetProcessId() and GetThreadId() are both DWORD. +using pid_t = DWORD; +#endif +pid_t GetTID(); + +} // namespace base_internal +} // namespace absl + +#endif // ABSL_BASE_INTERNAL_SYSINFO_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/sysinfo_test.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/sysinfo_test.cc new file mode 100644 index 0000000..e0d9aab --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/sysinfo_test.cc @@ -0,0 +1,98 @@ +// Copyright 2017 The Abseil Authors. +// +// 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 "absl/base/internal/sysinfo.h" + +#ifndef _WIN32 +#include +#include +#endif + +#include // NOLINT(build/c++11) +#include +#include + +#include "gtest/gtest.h" +#include "absl/synchronization/barrier.h" +#include "absl/synchronization/mutex.h" + +namespace absl { +namespace base_internal { +namespace { + +TEST(SysinfoTest, NumCPUs) { + EXPECT_NE(NumCPUs(), 0) + << "NumCPUs() should not have the default value of 0"; +} + +TEST(SysinfoTest, NominalCPUFrequency) { +#if !(defined(__aarch64__) && defined(__linux__)) + EXPECT_GE(NominalCPUFrequency(), 1000.0) + << "NominalCPUFrequency() did not return a reasonable value"; +#else + // TODO(absl-team): Aarch64 cannot read the CPU frequency from sysfs, so we + // get back 1.0. Fix once the value is available. + EXPECT_EQ(NominalCPUFrequency(), 1.0) + << "CPU frequency detection was fixed! Please update unittest."; +#endif +} + +TEST(SysinfoTest, GetTID) { + EXPECT_EQ(GetTID(), GetTID()); // Basic compile and equality test. +#ifdef __native_client__ + // Native Client has a race condition bug that leads to memory + // exaustion when repeatedly creating and joining threads. + // https://bugs.chromium.org/p/nativeclient/issues/detail?id=1027 + return; +#endif + // Test that TIDs are unique to each thread. + // Uses a few loops to exercise implementations that reallocate IDs. + for (int i = 0; i < 32; ++i) { + constexpr int kNumThreads = 64; + Barrier all_threads_done(kNumThreads); + std::vector threads; + + Mutex mutex; + std::unordered_set tids; + + for (int j = 0; j < kNumThreads; ++j) { + threads.push_back(std::thread([&]() { + pid_t id = GetTID(); + { + MutexLock lock(&mutex); + ASSERT_TRUE(tids.find(id) == tids.end()); + tids.insert(id); + } + // We can't simply join the threads here. The threads need to + // be alive otherwise the TID might have been reallocated to + // another live thread. + all_threads_done.Block(); + })); + } + for (auto& thread : threads) { + thread.join(); + } + } +} + +#ifdef __linux__ +TEST(SysinfoTest, LinuxGetTID) { + // On Linux, for the main thread, GetTID()==getpid() is guaranteed by the API. + EXPECT_EQ(GetTID(), getpid()); +} +#endif + +} // namespace +} // namespace base_internal +} // namespace absl diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/thread_identity.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/thread_identity.cc new file mode 100644 index 0000000..cff9c1b --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/thread_identity.cc @@ -0,0 +1,133 @@ +// Copyright 2017 The Abseil Authors. +// +// 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 "absl/base/internal/thread_identity.h" + +#ifndef _WIN32 +#include +#include +#endif + +#include +#include +#include + +#include "absl/base/call_once.h" +#include "absl/base/internal/raw_logging.h" +#include "absl/base/internal/spinlock.h" + +namespace absl { +namespace base_internal { + +#if ABSL_THREAD_IDENTITY_MODE != ABSL_THREAD_IDENTITY_MODE_USE_CPP11 +namespace { +// Used to co-ordinate one-time creation of our pthread_key +absl::once_flag init_thread_identity_key_once; +pthread_key_t thread_identity_pthread_key; +std::atomic pthread_key_initialized(false); + +void AllocateThreadIdentityKey(ThreadIdentityReclaimerFunction reclaimer) { + pthread_key_create(&thread_identity_pthread_key, reclaimer); + pthread_key_initialized.store(true, std::memory_order_release); +} +} // namespace +#endif + +#if ABSL_THREAD_IDENTITY_MODE == ABSL_THREAD_IDENTITY_MODE_USE_TLS || \ + ABSL_THREAD_IDENTITY_MODE == ABSL_THREAD_IDENTITY_MODE_USE_CPP11 +// The actual TLS storage for a thread's currently associated ThreadIdentity. +// This is referenced by inline accessors in the header. +// "protected" visibility ensures that if multiple instances of Abseil code +// exist within a process (via dlopen() or similar), references to +// thread_identity_ptr from each instance of the code will refer to +// *different* instances of this ptr. +#ifdef __GNUC__ +__attribute__((visibility("protected"))) +#endif // __GNUC__ + ABSL_PER_THREAD_TLS_KEYWORD ThreadIdentity* thread_identity_ptr; +#endif // TLS or CPP11 + +void SetCurrentThreadIdentity( + ThreadIdentity* identity, ThreadIdentityReclaimerFunction reclaimer) { + assert(CurrentThreadIdentityIfPresent() == nullptr); + // Associate our destructor. + // NOTE: This call to pthread_setspecific is currently the only immovable + // barrier to CurrentThreadIdentity() always being async signal safe. +#if ABSL_THREAD_IDENTITY_MODE == ABSL_THREAD_IDENTITY_MODE_USE_POSIX_SETSPECIFIC + // NOTE: Not async-safe. But can be open-coded. + absl::call_once(init_thread_identity_key_once, AllocateThreadIdentityKey, + reclaimer); + +#ifdef __EMSCRIPTEN__ + // Emscripten PThread implementation does not support signals. + // See https://kripken.github.io/emscripten-site/docs/porting/pthreads.html + // for more information. + pthread_setspecific(thread_identity_pthread_key, + reinterpret_cast(identity)); +#else + // We must mask signals around the call to setspecific as with current glibc, + // a concurrent getspecific (needed for GetCurrentThreadIdentityIfPresent()) + // may zero our value. + // + // While not officially async-signal safe, getspecific within a signal handler + // is otherwise OK. + sigset_t all_signals; + sigset_t curr_signals; + sigfillset(&all_signals); + pthread_sigmask(SIG_SETMASK, &all_signals, &curr_signals); + pthread_setspecific(thread_identity_pthread_key, + reinterpret_cast(identity)); + pthread_sigmask(SIG_SETMASK, &curr_signals, nullptr); +#endif // !__EMSCRIPTEN__ + +#elif ABSL_THREAD_IDENTITY_MODE == ABSL_THREAD_IDENTITY_MODE_USE_TLS + // NOTE: Not async-safe. But can be open-coded. + absl::call_once(init_thread_identity_key_once, AllocateThreadIdentityKey, + reclaimer); + pthread_setspecific(thread_identity_pthread_key, + reinterpret_cast(identity)); + thread_identity_ptr = identity; +#elif ABSL_THREAD_IDENTITY_MODE == ABSL_THREAD_IDENTITY_MODE_USE_CPP11 + thread_local std::unique_ptr + holder(identity, reclaimer); + thread_identity_ptr = identity; +#else +#error Unimplemented ABSL_THREAD_IDENTITY_MODE +#endif +} + +void ClearCurrentThreadIdentity() { +#if ABSL_THREAD_IDENTITY_MODE == ABSL_THREAD_IDENTITY_MODE_USE_TLS || \ + ABSL_THREAD_IDENTITY_MODE == ABSL_THREAD_IDENTITY_MODE_USE_CPP11 + thread_identity_ptr = nullptr; +#elif ABSL_THREAD_IDENTITY_MODE == \ + ABSL_THREAD_IDENTITY_MODE_USE_POSIX_SETSPECIFIC + // pthread_setspecific expected to clear value on destruction + assert(CurrentThreadIdentityIfPresent() == nullptr); +#endif +} + +#if ABSL_THREAD_IDENTITY_MODE == ABSL_THREAD_IDENTITY_MODE_USE_POSIX_SETSPECIFIC +ThreadIdentity* CurrentThreadIdentityIfPresent() { + bool initialized = pthread_key_initialized.load(std::memory_order_acquire); + if (!initialized) { + return nullptr; + } + return reinterpret_cast( + pthread_getspecific(thread_identity_pthread_key)); +} +#endif + +} // namespace base_internal +} // namespace absl diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/thread_identity.h b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/thread_identity.h new file mode 100644 index 0000000..a51722f --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/thread_identity.h @@ -0,0 +1,240 @@ +// Copyright 2017 The Abseil Authors. +// +// 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. +// +// Each active thread has an ThreadIdentity that may represent the thread in +// various level interfaces. ThreadIdentity objects are never deallocated. +// When a thread terminates, its ThreadIdentity object may be reused for a +// thread created later. + +#ifndef ABSL_BASE_INTERNAL_THREAD_IDENTITY_H_ +#define ABSL_BASE_INTERNAL_THREAD_IDENTITY_H_ + +#ifndef _WIN32 +#include +// Defines __GOOGLE_GRTE_VERSION__ (via glibc-specific features.h) when +// supported. +#include +#endif + +#include +#include + +#include "absl/base/internal/per_thread_tls.h" + +namespace absl { + +struct SynchLocksHeld; +struct SynchWaitParams; + +namespace base_internal { + +class SpinLock; +struct ThreadIdentity; + +// Used by the implementation of base::Mutex and base::CondVar. +struct PerThreadSynch { + // The internal representation of base::Mutex and base::CondVar rely + // on the alignment of PerThreadSynch. Both store the address of the + // PerThreadSynch in the high-order bits of their internal state, + // which means the low kLowZeroBits of the address of PerThreadSynch + // must be zero. + static constexpr int kLowZeroBits = 8; + static constexpr int kAlignment = 1 << kLowZeroBits; + + // Returns the associated ThreadIdentity. + // This can be implemented as a cast because we guarantee + // PerThreadSynch is the first element of ThreadIdentity. + ThreadIdentity* thread_identity() { + return reinterpret_cast(this); + } + + PerThreadSynch *next; // Circular waiter queue; initialized to 0. + PerThreadSynch *skip; // If non-zero, all entries in Mutex queue + // up to and including "skip" have same + // condition as this, and will be woken later + bool may_skip; // if false while on mutex queue, a mutex unlocker + // is using this PerThreadSynch as a terminator. Its + // skip field must not be filled in because the loop + // might then skip over the terminator. + + // The wait parameters of the current wait. waitp is null if the + // thread is not waiting. Transitions from null to non-null must + // occur before the enqueue commit point (state = kQueued in + // Enqueue() and CondVarEnqueue()). Transitions from non-null to + // null must occur after the wait is finished (state = kAvailable in + // Mutex::Block() and CondVar::WaitCommon()). This field may be + // changed only by the thread that describes this PerThreadSynch. A + // special case is Fer(), which calls Enqueue() on another thread, + // but with an identical SynchWaitParams pointer, thus leaving the + // pointer unchanged. + SynchWaitParams *waitp; + + bool suppress_fatal_errors; // If true, try to proceed even in the face of + // broken invariants. This is used within fatal + // signal handlers to improve the chances of + // debug logging information being output + // successfully. + + intptr_t readers; // Number of readers in mutex. + int priority; // Priority of thread (updated every so often). + + // When priority will next be read (cycles). + int64_t next_priority_read_cycles; + + // State values: + // kAvailable: This PerThreadSynch is available. + // kQueued: This PerThreadSynch is unavailable, it's currently queued on a + // Mutex or CondVar waistlist. + // + // Transitions from kQueued to kAvailable require a release + // barrier. This is needed as a waiter may use "state" to + // independently observe that it's no longer queued. + // + // Transitions from kAvailable to kQueued require no barrier, they + // are externally ordered by the Mutex. + enum State { + kAvailable, + kQueued + }; + std::atomic state; + + bool maybe_unlocking; // Valid at head of Mutex waiter queue; + // true if UnlockSlow could be searching + // for a waiter to wake. Used for an optimization + // in Enqueue(). true is always a valid value. + // Can be reset to false when the unlocker or any + // writer releases the lock, or a reader fully releases + // the lock. It may not be set to false by a reader + // that decrements the count to non-zero. + // protected by mutex spinlock + + bool wake; // This thread is to be woken from a Mutex. + + // If "x" is on a waiter list for a mutex, "x->cond_waiter" is true iff the + // waiter is waiting on the mutex as part of a CV Wait or Mutex Await. + // + // The value of "x->cond_waiter" is meaningless if "x" is not on a + // Mutex waiter list. + bool cond_waiter; + + // Locks held; used during deadlock detection. + // Allocated in Synch_GetAllLocks() and freed in ReclaimThreadIdentity(). + SynchLocksHeld *all_locks; +}; + +struct ThreadIdentity { + // Must be the first member. The Mutex implementation requires that + // the PerThreadSynch object associated with each thread is + // PerThreadSynch::kAlignment aligned. We provide this alignment on + // ThreadIdentity itself. + PerThreadSynch per_thread_synch; + + // Private: Reserved for absl::synchronization_internal::Waiter. + struct WaiterState { + char data[128]; + } waiter_state; + + // Used by PerThreadSem::{Get,Set}ThreadBlockedCounter(). + std::atomic* blocked_count_ptr; + + // The following variables are mostly read/written just by the + // thread itself. The only exception is that these are read by + // a ticker thread as a hint. + std::atomic ticker; // Tick counter, incremented once per second. + std::atomic wait_start; // Ticker value when thread started waiting. + std::atomic is_idle; // Has thread become idle yet? + + ThreadIdentity* next; +}; + +// Returns the ThreadIdentity object representing the calling thread; guaranteed +// to be unique for its lifetime. The returned object will remain valid for the +// program's lifetime; although it may be re-assigned to a subsequent thread. +// If one does not exist, return nullptr instead. +// +// Does not malloc(*), and is async-signal safe. +// [*] Technically pthread_setspecific() does malloc on first use; however this +// is handled internally within tcmalloc's initialization already. +// +// New ThreadIdentity objects can be constructed and associated with a thread +// by calling GetOrCreateCurrentThreadIdentity() in per-thread-sem.h. +ThreadIdentity* CurrentThreadIdentityIfPresent(); + +using ThreadIdentityReclaimerFunction = void (*)(void*); + +// Sets the current thread identity to the given value. 'reclaimer' is a +// pointer to the global function for cleaning up instances on thread +// destruction. +void SetCurrentThreadIdentity(ThreadIdentity* identity, + ThreadIdentityReclaimerFunction reclaimer); + +// Removes the currently associated ThreadIdentity from the running thread. +// This must be called from inside the ThreadIdentityReclaimerFunction, and only +// from that function. +void ClearCurrentThreadIdentity(); + +// May be chosen at compile time via: -DABSL_FORCE_THREAD_IDENTITY_MODE= +#ifdef ABSL_THREAD_IDENTITY_MODE_USE_POSIX_SETSPECIFIC +#error ABSL_THREAD_IDENTITY_MODE_USE_POSIX_SETSPECIFIC cannot be direcly set +#else +#define ABSL_THREAD_IDENTITY_MODE_USE_POSIX_SETSPECIFIC 0 +#endif + +#ifdef ABSL_THREAD_IDENTITY_MODE_USE_TLS +#error ABSL_THREAD_IDENTITY_MODE_USE_TLS cannot be direcly set +#else +#define ABSL_THREAD_IDENTITY_MODE_USE_TLS 1 +#endif + +#ifdef ABSL_THREAD_IDENTITY_MODE_USE_CPP11 +#error ABSL_THREAD_IDENTITY_MODE_USE_CPP11 cannot be direcly set +#else +#define ABSL_THREAD_IDENTITY_MODE_USE_CPP11 2 +#endif + +#ifdef ABSL_THREAD_IDENTITY_MODE +#error ABSL_THREAD_IDENTITY_MODE cannot be direcly set +#elif defined(ABSL_FORCE_THREAD_IDENTITY_MODE) +#define ABSL_THREAD_IDENTITY_MODE ABSL_FORCE_THREAD_IDENTITY_MODE +#elif defined(_WIN32) +#define ABSL_THREAD_IDENTITY_MODE ABSL_THREAD_IDENTITY_MODE_USE_CPP11 +#elif ABSL_PER_THREAD_TLS && defined(__GOOGLE_GRTE_VERSION__) && \ + (__GOOGLE_GRTE_VERSION__ >= 20140228L) +// Support for async-safe TLS was specifically added in GRTEv4. It's not +// present in the upstream eglibc. +// Note: Current default for production systems. +#define ABSL_THREAD_IDENTITY_MODE ABSL_THREAD_IDENTITY_MODE_USE_TLS +#else +#define ABSL_THREAD_IDENTITY_MODE \ + ABSL_THREAD_IDENTITY_MODE_USE_POSIX_SETSPECIFIC +#endif + +#if ABSL_THREAD_IDENTITY_MODE == ABSL_THREAD_IDENTITY_MODE_USE_TLS || \ + ABSL_THREAD_IDENTITY_MODE == ABSL_THREAD_IDENTITY_MODE_USE_CPP11 + +extern ABSL_PER_THREAD_TLS_KEYWORD ThreadIdentity* thread_identity_ptr; + +inline ThreadIdentity* CurrentThreadIdentityIfPresent() { + return thread_identity_ptr; +} + +#elif ABSL_THREAD_IDENTITY_MODE != \ + ABSL_THREAD_IDENTITY_MODE_USE_POSIX_SETSPECIFIC +#error Unknown ABSL_THREAD_IDENTITY_MODE +#endif + +} // namespace base_internal +} // namespace absl +#endif // ABSL_BASE_INTERNAL_THREAD_IDENTITY_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/thread_identity_benchmark.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/thread_identity_benchmark.cc new file mode 100644 index 0000000..242522b --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/thread_identity_benchmark.cc @@ -0,0 +1,38 @@ +// Copyright 2017 The Abseil Authors. +// +// 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 "benchmark/benchmark.h" +#include "absl/base/internal/thread_identity.h" +#include "absl/synchronization/internal/create_thread_identity.h" +#include "absl/synchronization/internal/per_thread_sem.h" + +namespace { + +void BM_SafeCurrentThreadIdentity(benchmark::State& state) { + for (auto _ : state) { + benchmark::DoNotOptimize( + absl::synchronization_internal::GetOrCreateCurrentThreadIdentity()); + } +} +BENCHMARK(BM_SafeCurrentThreadIdentity); + +void BM_UnsafeCurrentThreadIdentity(benchmark::State& state) { + for (auto _ : state) { + benchmark::DoNotOptimize( + absl::base_internal::CurrentThreadIdentityIfPresent()); + } +} +BENCHMARK(BM_UnsafeCurrentThreadIdentity); + +} // namespace diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/thread_identity_test.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/thread_identity_test.cc new file mode 100644 index 0000000..ecb8af6 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/thread_identity_test.cc @@ -0,0 +1,126 @@ +// Copyright 2017 The Abseil Authors. +// +// 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 "absl/base/internal/thread_identity.h" + +#include // NOLINT(build/c++11) +#include + +#include "gtest/gtest.h" +#include "absl/base/attributes.h" +#include "absl/base/internal/spinlock.h" +#include "absl/base/macros.h" +#include "absl/synchronization/internal/per_thread_sem.h" +#include "absl/synchronization/mutex.h" + +namespace absl { +namespace base_internal { +namespace { + +// protects num_identities_reused +static absl::base_internal::SpinLock map_lock( + absl::base_internal::kLinkerInitialized); +static int num_identities_reused; + +static const void* const kCheckNoIdentity = reinterpret_cast(1); + +static void TestThreadIdentityCurrent(const void* assert_no_identity) { + ThreadIdentity* identity; + + // We have to test this conditionally, because if the test framework relies + // on Abseil, then some previous action may have already allocated an + // identity. + if (assert_no_identity == kCheckNoIdentity) { + identity = CurrentThreadIdentityIfPresent(); + EXPECT_TRUE(identity == nullptr); + } + + identity = synchronization_internal::GetOrCreateCurrentThreadIdentity(); + EXPECT_TRUE(identity != nullptr); + ThreadIdentity* identity_no_init; + identity_no_init = CurrentThreadIdentityIfPresent(); + EXPECT_TRUE(identity == identity_no_init); + + // Check that per_thread_synch is correctly aligned. + EXPECT_EQ(0, reinterpret_cast(&identity->per_thread_synch) % + PerThreadSynch::kAlignment); + EXPECT_EQ(identity, identity->per_thread_synch.thread_identity()); + + absl::base_internal::SpinLockHolder l(&map_lock); + num_identities_reused++; +} + +TEST(ThreadIdentityTest, BasicIdentityWorks) { + // This tests for the main() thread. + TestThreadIdentityCurrent(nullptr); +} + +TEST(ThreadIdentityTest, BasicIdentityWorksThreaded) { + // Now try the same basic test with multiple threads being created and + // destroyed. This makes sure that: + // - New threads are created without a ThreadIdentity. + // - We re-allocate ThreadIdentity objects from the free-list. + // - If a thread implementation chooses to recycle threads, that + // correct re-initialization occurs. + static const int kNumLoops = 3; + static const int kNumThreads = 400; + for (int iter = 0; iter < kNumLoops; iter++) { + std::vector threads; + for (int i = 0; i < kNumThreads; ++i) { + threads.push_back( + std::thread(TestThreadIdentityCurrent, kCheckNoIdentity)); + } + for (auto& thread : threads) { + thread.join(); + } + } + + // We should have recycled ThreadIdentity objects above; while (external) + // library threads allocating their own identities may preclude some + // reuse, we should have sufficient repetitions to exclude this. + EXPECT_LT(kNumThreads, num_identities_reused); +} + +TEST(ThreadIdentityTest, ReusedThreadIdentityMutexTest) { + // This test repeatly creates and joins a series of threads, each of + // which acquires and releases shared Mutex locks. This verifies + // Mutex operations work correctly under a reused + // ThreadIdentity. Note that the most likely failure mode of this + // test is a crash or deadlock. + static const int kNumLoops = 10; + static const int kNumThreads = 12; + static const int kNumMutexes = 3; + static const int kNumLockLoops = 5; + + Mutex mutexes[kNumMutexes]; + for (int iter = 0; iter < kNumLoops; ++iter) { + std::vector threads; + for (int thread = 0; thread < kNumThreads; ++thread) { + threads.push_back(std::thread([&]() { + for (int l = 0; l < kNumLockLoops; ++l) { + for (int m = 0; m < kNumMutexes; ++m) { + MutexLock lock(&mutexes[m]); + } + } + })); + } + for (auto& thread : threads) { + thread.join(); + } + } +} + +} // namespace +} // namespace base_internal +} // namespace absl diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/throw_delegate.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/throw_delegate.cc new file mode 100644 index 0000000..46dc573 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/throw_delegate.cc @@ -0,0 +1,106 @@ +// Copyright 2017 The Abseil Authors. +// +// 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 "absl/base/internal/throw_delegate.h" + +#include +#include +#include +#include +#include "absl/base/config.h" +#include "absl/base/internal/raw_logging.h" + +namespace absl { +namespace base_internal { + +namespace { +template +[[noreturn]] void Throw(const T& error) { +#ifdef ABSL_HAVE_EXCEPTIONS + throw error; +#else + ABSL_RAW_LOG(ERROR, "%s", error.what()); + abort(); +#endif +} +} // namespace + +void ThrowStdLogicError(const std::string& what_arg) { + Throw(std::logic_error(what_arg)); +} +void ThrowStdLogicError(const char* what_arg) { + Throw(std::logic_error(what_arg)); +} +void ThrowStdInvalidArgument(const std::string& what_arg) { + Throw(std::invalid_argument(what_arg)); +} +void ThrowStdInvalidArgument(const char* what_arg) { + Throw(std::invalid_argument(what_arg)); +} + +void ThrowStdDomainError(const std::string& what_arg) { + Throw(std::domain_error(what_arg)); +} +void ThrowStdDomainError(const char* what_arg) { + Throw(std::domain_error(what_arg)); +} + +void ThrowStdLengthError(const std::string& what_arg) { + Throw(std::length_error(what_arg)); +} +void ThrowStdLengthError(const char* what_arg) { + Throw(std::length_error(what_arg)); +} + +void ThrowStdOutOfRange(const std::string& what_arg) { + Throw(std::out_of_range(what_arg)); +} +void ThrowStdOutOfRange(const char* what_arg) { + Throw(std::out_of_range(what_arg)); +} + +void ThrowStdRuntimeError(const std::string& what_arg) { + Throw(std::runtime_error(what_arg)); +} +void ThrowStdRuntimeError(const char* what_arg) { + Throw(std::runtime_error(what_arg)); +} + +void ThrowStdRangeError(const std::string& what_arg) { + Throw(std::range_error(what_arg)); +} +void ThrowStdRangeError(const char* what_arg) { + Throw(std::range_error(what_arg)); +} + +void ThrowStdOverflowError(const std::string& what_arg) { + Throw(std::overflow_error(what_arg)); +} +void ThrowStdOverflowError(const char* what_arg) { + Throw(std::overflow_error(what_arg)); +} + +void ThrowStdUnderflowError(const std::string& what_arg) { + Throw(std::underflow_error(what_arg)); +} +void ThrowStdUnderflowError(const char* what_arg) { + Throw(std::underflow_error(what_arg)); +} + +void ThrowStdBadFunctionCall() { Throw(std::bad_function_call()); } + +void ThrowStdBadAlloc() { Throw(std::bad_alloc()); } + +} // namespace base_internal +} // namespace absl diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/throw_delegate.h b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/throw_delegate.h new file mode 100644 index 0000000..70e2d77 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/throw_delegate.h @@ -0,0 +1,71 @@ +// +// Copyright 2017 The Abseil Authors. +// +// 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. +// + +#ifndef ABSL_BASE_INTERNAL_THROW_DELEGATE_H_ +#define ABSL_BASE_INTERNAL_THROW_DELEGATE_H_ + +#include + +namespace absl { +namespace base_internal { + +// Helper functions that allow throwing exceptions consistently from anywhere. +// The main use case is for header-based libraries (eg templates), as they will +// be built by many different targets with their own compiler options. +// In particular, this will allow a safe way to throw exceptions even if the +// caller is compiled with -fno-exceptions. This is intended for implementing +// things like map<>::at(), which the standard documents as throwing an +// exception on error. +// +// Using other techniques like #if tricks could lead to ODR violations. +// +// You shouldn't use it unless you're writing code that you know will be built +// both with and without exceptions and you need to conform to an interface +// that uses exceptions. + +[[noreturn]] void ThrowStdLogicError(const std::string& what_arg); +[[noreturn]] void ThrowStdLogicError(const char* what_arg); +[[noreturn]] void ThrowStdInvalidArgument(const std::string& what_arg); +[[noreturn]] void ThrowStdInvalidArgument(const char* what_arg); +[[noreturn]] void ThrowStdDomainError(const std::string& what_arg); +[[noreturn]] void ThrowStdDomainError(const char* what_arg); +[[noreturn]] void ThrowStdLengthError(const std::string& what_arg); +[[noreturn]] void ThrowStdLengthError(const char* what_arg); +[[noreturn]] void ThrowStdOutOfRange(const std::string& what_arg); +[[noreturn]] void ThrowStdOutOfRange(const char* what_arg); +[[noreturn]] void ThrowStdRuntimeError(const std::string& what_arg); +[[noreturn]] void ThrowStdRuntimeError(const char* what_arg); +[[noreturn]] void ThrowStdRangeError(const std::string& what_arg); +[[noreturn]] void ThrowStdRangeError(const char* what_arg); +[[noreturn]] void ThrowStdOverflowError(const std::string& what_arg); +[[noreturn]] void ThrowStdOverflowError(const char* what_arg); +[[noreturn]] void ThrowStdUnderflowError(const std::string& what_arg); +[[noreturn]] void ThrowStdUnderflowError(const char* what_arg); + +[[noreturn]] void ThrowStdBadFunctionCall(); +[[noreturn]] void ThrowStdBadAlloc(); + +// ThrowStdBadArrayNewLength() cannot be consistently supported because +// std::bad_array_new_length is missing in libstdc++ until 4.9.0. +// https://gcc.gnu.org/onlinedocs/gcc-4.8.3/libstdc++/api/a01379_source.html +// https://gcc.gnu.org/onlinedocs/gcc-4.9.0/libstdc++/api/a01327_source.html +// libcxx (as of 3.2) and msvc (as of 2015) both have it. +// [[noreturn]] void ThrowStdBadArrayNewLength(); + +} // namespace base_internal +} // namespace absl + +#endif // ABSL_BASE_INTERNAL_THROW_DELEGATE_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/tsan_mutex_interface.h b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/tsan_mutex_interface.h new file mode 100644 index 0000000..6bb4fae --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/tsan_mutex_interface.h @@ -0,0 +1,66 @@ +// Copyright 2017 The Abseil Authors. +// +// 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. +// +// This file is intended solely for spinlock.h. +// It provides ThreadSanitizer annotations for custom mutexes. +// See for meaning of these annotations. + +#ifndef ABSL_BASE_INTERNAL_TSAN_MUTEX_INTERFACE_H_ +#define ABSL_BASE_INTERNAL_TSAN_MUTEX_INTERFACE_H_ + +// ABSL_INTERNAL_HAVE_TSAN_INTERFACE +// Macro intended only for internal use. +// +// Checks whether LLVM Thread Sanitizer interfaces are available. +// First made available in LLVM 5.0 (Sep 2017). +#ifdef ABSL_INTERNAL_HAVE_TSAN_INTERFACE +#error "ABSL_INTERNAL_HAVE_TSAN_INTERFACE cannot be directly set." +#endif + +#if defined(THREAD_SANITIZER) && defined(__has_include) +#if __has_include() +#define ABSL_INTERNAL_HAVE_TSAN_INTERFACE 1 +#endif +#endif + +#ifdef ABSL_INTERNAL_HAVE_TSAN_INTERFACE +#include + +#define ABSL_TSAN_MUTEX_CREATE __tsan_mutex_create +#define ABSL_TSAN_MUTEX_DESTROY __tsan_mutex_destroy +#define ABSL_TSAN_MUTEX_PRE_LOCK __tsan_mutex_pre_lock +#define ABSL_TSAN_MUTEX_POST_LOCK __tsan_mutex_post_lock +#define ABSL_TSAN_MUTEX_PRE_UNLOCK __tsan_mutex_pre_unlock +#define ABSL_TSAN_MUTEX_POST_UNLOCK __tsan_mutex_post_unlock +#define ABSL_TSAN_MUTEX_PRE_SIGNAL __tsan_mutex_pre_signal +#define ABSL_TSAN_MUTEX_POST_SIGNAL __tsan_mutex_post_signal +#define ABSL_TSAN_MUTEX_PRE_DIVERT __tsan_mutex_pre_divert +#define ABSL_TSAN_MUTEX_POST_DIVERT __tsan_mutex_post_divert + +#else + +#define ABSL_TSAN_MUTEX_CREATE(...) +#define ABSL_TSAN_MUTEX_DESTROY(...) +#define ABSL_TSAN_MUTEX_PRE_LOCK(...) +#define ABSL_TSAN_MUTEX_POST_LOCK(...) +#define ABSL_TSAN_MUTEX_PRE_UNLOCK(...) +#define ABSL_TSAN_MUTEX_POST_UNLOCK(...) +#define ABSL_TSAN_MUTEX_PRE_SIGNAL(...) +#define ABSL_TSAN_MUTEX_POST_SIGNAL(...) +#define ABSL_TSAN_MUTEX_PRE_DIVERT(...) +#define ABSL_TSAN_MUTEX_POST_DIVERT(...) + +#endif + +#endif // ABSL_BASE_INTERNAL_TSAN_MUTEX_INTERFACE_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/unaligned_access.h b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/unaligned_access.h new file mode 100644 index 0000000..f9df3b7 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/unaligned_access.h @@ -0,0 +1,317 @@ +// +// Copyright 2017 The Abseil Authors. +// +// 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. +// + +#ifndef ABSL_BASE_INTERNAL_UNALIGNED_ACCESS_H_ +#define ABSL_BASE_INTERNAL_UNALIGNED_ACCESS_H_ + +#include +#include + +#include "absl/base/attributes.h" + +// unaligned APIs + +// Portable handling of unaligned loads, stores, and copies. +// On some platforms, like ARM, the copy functions can be more efficient +// then a load and a store. +// +// It is possible to implement all of these these using constant-length memcpy +// calls, which is portable and will usually be inlined into simple loads and +// stores if the architecture supports it. However, such inlining usually +// happens in a pass that's quite late in compilation, which means the resulting +// loads and stores cannot participate in many other optimizations, leading to +// overall worse code. + +// The unaligned API is C++ only. The declarations use C++ features +// (namespaces, inline) which are absent or incompatible in C. +#if defined(__cplusplus) + +#if defined(ADDRESS_SANITIZER) || defined(THREAD_SANITIZER) ||\ + defined(MEMORY_SANITIZER) +// Consider we have an unaligned load/store of 4 bytes from address 0x...05. +// AddressSanitizer will treat it as a 3-byte access to the range 05:07 and +// will miss a bug if 08 is the first unaddressable byte. +// ThreadSanitizer will also treat this as a 3-byte access to 05:07 and will +// miss a race between this access and some other accesses to 08. +// MemorySanitizer will correctly propagate the shadow on unaligned stores +// and correctly report bugs on unaligned loads, but it may not properly +// update and report the origin of the uninitialized memory. +// For all three tools, replacing an unaligned access with a tool-specific +// callback solves the problem. + +// Make sure uint16_t/uint32_t/uint64_t are defined. +#include + +extern "C" { +uint16_t __sanitizer_unaligned_load16(const void *p); +uint32_t __sanitizer_unaligned_load32(const void *p); +uint64_t __sanitizer_unaligned_load64(const void *p); +void __sanitizer_unaligned_store16(void *p, uint16_t v); +void __sanitizer_unaligned_store32(void *p, uint32_t v); +void __sanitizer_unaligned_store64(void *p, uint64_t v); +} // extern "C" + +namespace absl { +namespace base_internal { + +inline uint16_t UnalignedLoad16(const void *p) { + return __sanitizer_unaligned_load16(p); +} + +inline uint32_t UnalignedLoad32(const void *p) { + return __sanitizer_unaligned_load32(p); +} + +inline uint64_t UnalignedLoad64(const void *p) { + return __sanitizer_unaligned_load64(p); +} + +inline void UnalignedStore16(void *p, uint16_t v) { + __sanitizer_unaligned_store16(p, v); +} + +inline void UnalignedStore32(void *p, uint32_t v) { + __sanitizer_unaligned_store32(p, v); +} + +inline void UnalignedStore64(void *p, uint64_t v) { + __sanitizer_unaligned_store64(p, v); +} + +} // namespace base_internal +} // namespace absl + +#define ABSL_INTERNAL_UNALIGNED_LOAD16(_p) \ + (absl::base_internal::UnalignedLoad16(_p)) +#define ABSL_INTERNAL_UNALIGNED_LOAD32(_p) \ + (absl::base_internal::UnalignedLoad32(_p)) +#define ABSL_INTERNAL_UNALIGNED_LOAD64(_p) \ + (absl::base_internal::UnalignedLoad64(_p)) + +#define ABSL_INTERNAL_UNALIGNED_STORE16(_p, _val) \ + (absl::base_internal::UnalignedStore16(_p, _val)) +#define ABSL_INTERNAL_UNALIGNED_STORE32(_p, _val) \ + (absl::base_internal::UnalignedStore32(_p, _val)) +#define ABSL_INTERNAL_UNALIGNED_STORE64(_p, _val) \ + (absl::base_internal::UnalignedStore64(_p, _val)) + +#elif defined(UNDEFINED_BEHAVIOR_SANITIZER) + +namespace absl { +namespace base_internal { + +inline uint16_t UnalignedLoad16(const void *p) { + uint16_t t; + memcpy(&t, p, sizeof t); + return t; +} + +inline uint32_t UnalignedLoad32(const void *p) { + uint32_t t; + memcpy(&t, p, sizeof t); + return t; +} + +inline uint64_t UnalignedLoad64(const void *p) { + uint64_t t; + memcpy(&t, p, sizeof t); + return t; +} + +inline void UnalignedStore16(void *p, uint16_t v) { memcpy(p, &v, sizeof v); } + +inline void UnalignedStore32(void *p, uint32_t v) { memcpy(p, &v, sizeof v); } + +inline void UnalignedStore64(void *p, uint64_t v) { memcpy(p, &v, sizeof v); } + +} // namespace base_internal +} // namespace absl + +#define ABSL_INTERNAL_UNALIGNED_LOAD16(_p) \ + (absl::base_internal::UnalignedLoad16(_p)) +#define ABSL_INTERNAL_UNALIGNED_LOAD32(_p) \ + (absl::base_internal::UnalignedLoad32(_p)) +#define ABSL_INTERNAL_UNALIGNED_LOAD64(_p) \ + (absl::base_internal::UnalignedLoad64(_p)) + +#define ABSL_INTERNAL_UNALIGNED_STORE16(_p, _val) \ + (absl::base_internal::UnalignedStore16(_p, _val)) +#define ABSL_INTERNAL_UNALIGNED_STORE32(_p, _val) \ + (absl::base_internal::UnalignedStore32(_p, _val)) +#define ABSL_INTERNAL_UNALIGNED_STORE64(_p, _val) \ + (absl::base_internal::UnalignedStore64(_p, _val)) + +#elif defined(__x86_64__) || defined(_M_X64) || defined(__i386) || \ + defined(_M_IX86) || defined(__ppc__) || defined(__PPC__) || \ + defined(__ppc64__) || defined(__PPC64__) + +// x86 and x86-64 can perform unaligned loads/stores directly; +// modern PowerPC hardware can also do unaligned integer loads and stores; +// but note: the FPU still sends unaligned loads and stores to a trap handler! + +#define ABSL_INTERNAL_UNALIGNED_LOAD16(_p) \ + (*reinterpret_cast(_p)) +#define ABSL_INTERNAL_UNALIGNED_LOAD32(_p) \ + (*reinterpret_cast(_p)) +#define ABSL_INTERNAL_UNALIGNED_LOAD64(_p) \ + (*reinterpret_cast(_p)) + +#define ABSL_INTERNAL_UNALIGNED_STORE16(_p, _val) \ + (*reinterpret_cast(_p) = (_val)) +#define ABSL_INTERNAL_UNALIGNED_STORE32(_p, _val) \ + (*reinterpret_cast(_p) = (_val)) +#define ABSL_INTERNAL_UNALIGNED_STORE64(_p, _val) \ + (*reinterpret_cast(_p) = (_val)) + +#elif defined(__arm__) && \ + !defined(__ARM_ARCH_5__) && \ + !defined(__ARM_ARCH_5T__) && \ + !defined(__ARM_ARCH_5TE__) && \ + !defined(__ARM_ARCH_5TEJ__) && \ + !defined(__ARM_ARCH_6__) && \ + !defined(__ARM_ARCH_6J__) && \ + !defined(__ARM_ARCH_6K__) && \ + !defined(__ARM_ARCH_6Z__) && \ + !defined(__ARM_ARCH_6ZK__) && \ + !defined(__ARM_ARCH_6T2__) + + +// ARMv7 and newer support native unaligned accesses, but only of 16-bit +// and 32-bit values (not 64-bit); older versions either raise a fatal signal, +// do an unaligned read and rotate the words around a bit, or do the reads very +// slowly (trip through kernel mode). There's no simple #define that says just +// "ARMv7 or higher", so we have to filter away all ARMv5 and ARMv6 +// sub-architectures. Newer gcc (>= 4.6) set an __ARM_FEATURE_ALIGNED #define, +// so in time, maybe we can move on to that. +// +// This is a mess, but there's not much we can do about it. +// +// To further complicate matters, only LDR instructions (single reads) are +// allowed to be unaligned, not LDRD (two reads) or LDM (many reads). Unless we +// explicitly tell the compiler that these accesses can be unaligned, it can and +// will combine accesses. On armcc, the way to signal this is done by accessing +// through the type (uint32_t __packed *), but GCC has no such attribute +// (it ignores __attribute__((packed)) on individual variables). However, +// we can tell it that a _struct_ is unaligned, which has the same effect, +// so we do that. + +namespace absl { +namespace base_internal { + +struct Unaligned16Struct { + uint16_t value; + uint8_t dummy; // To make the size non-power-of-two. +} ABSL_ATTRIBUTE_PACKED; + +struct Unaligned32Struct { + uint32_t value; + uint8_t dummy; // To make the size non-power-of-two. +} ABSL_ATTRIBUTE_PACKED; + +} // namespace base_internal +} // namespace absl + +#define ABSL_INTERNAL_UNALIGNED_LOAD16(_p) \ + ((reinterpret_cast(_p)) \ + ->value) +#define ABSL_INTERNAL_UNALIGNED_LOAD32(_p) \ + ((reinterpret_cast(_p)) \ + ->value) + +#define ABSL_INTERNAL_UNALIGNED_STORE16(_p, _val) \ + ((reinterpret_cast< ::absl::base_internal::Unaligned16Struct *>(_p)) \ + ->value = (_val)) +#define ABSL_INTERNAL_UNALIGNED_STORE32(_p, _val) \ + ((reinterpret_cast< ::absl::base_internal::Unaligned32Struct *>(_p)) \ + ->value = (_val)) + +namespace absl { +namespace base_internal { + +inline uint64_t UnalignedLoad64(const void *p) { + uint64_t t; + memcpy(&t, p, sizeof t); + return t; +} + +inline void UnalignedStore64(void *p, uint64_t v) { memcpy(p, &v, sizeof v); } + +} // namespace base_internal +} // namespace absl + +#define ABSL_INTERNAL_UNALIGNED_LOAD64(_p) \ + (absl::base_internal::UnalignedLoad64(_p)) +#define ABSL_INTERNAL_UNALIGNED_STORE64(_p, _val) \ + (absl::base_internal::UnalignedStore64(_p, _val)) + +#else + +// ABSL_INTERNAL_NEED_ALIGNED_LOADS is defined when the underlying platform +// doesn't support unaligned access. +#define ABSL_INTERNAL_NEED_ALIGNED_LOADS + +// These functions are provided for architectures that don't support +// unaligned loads and stores. + +namespace absl { +namespace base_internal { + +inline uint16_t UnalignedLoad16(const void *p) { + uint16_t t; + memcpy(&t, p, sizeof t); + return t; +} + +inline uint32_t UnalignedLoad32(const void *p) { + uint32_t t; + memcpy(&t, p, sizeof t); + return t; +} + +inline uint64_t UnalignedLoad64(const void *p) { + uint64_t t; + memcpy(&t, p, sizeof t); + return t; +} + +inline void UnalignedStore16(void *p, uint16_t v) { memcpy(p, &v, sizeof v); } + +inline void UnalignedStore32(void *p, uint32_t v) { memcpy(p, &v, sizeof v); } + +inline void UnalignedStore64(void *p, uint64_t v) { memcpy(p, &v, sizeof v); } + +} // namespace base_internal +} // namespace absl + +#define ABSL_INTERNAL_UNALIGNED_LOAD16(_p) \ + (absl::base_internal::UnalignedLoad16(_p)) +#define ABSL_INTERNAL_UNALIGNED_LOAD32(_p) \ + (absl::base_internal::UnalignedLoad32(_p)) +#define ABSL_INTERNAL_UNALIGNED_LOAD64(_p) \ + (absl::base_internal::UnalignedLoad64(_p)) + +#define ABSL_INTERNAL_UNALIGNED_STORE16(_p, _val) \ + (absl::base_internal::UnalignedStore16(_p, _val)) +#define ABSL_INTERNAL_UNALIGNED_STORE32(_p, _val) \ + (absl::base_internal::UnalignedStore32(_p, _val)) +#define ABSL_INTERNAL_UNALIGNED_STORE64(_p, _val) \ + (absl::base_internal::UnalignedStore64(_p, _val)) + +#endif + +#endif // defined(__cplusplus), end of unaligned API + +#endif // ABSL_BASE_INTERNAL_UNALIGNED_ACCESS_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/unscaledcycleclock.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/unscaledcycleclock.cc new file mode 100644 index 0000000..a12d68b --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/unscaledcycleclock.cc @@ -0,0 +1,101 @@ +// Copyright 2017 The Abseil Authors. +// +// 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 "absl/base/internal/unscaledcycleclock.h" + +#if ABSL_USE_UNSCALED_CYCLECLOCK + +#if defined(_WIN32) +#include +#endif + +#if defined(__powerpc__) || defined(__ppc__) +#include +#endif + +#include "absl/base/internal/sysinfo.h" + +namespace absl { +namespace base_internal { + +#if defined(__i386__) + +int64_t UnscaledCycleClock::Now() { + int64_t ret; + __asm__ volatile("rdtsc" : "=A"(ret)); + return ret; +} + +double UnscaledCycleClock::Frequency() { + return base_internal::NominalCPUFrequency(); +} + +#elif defined(__x86_64__) + +int64_t UnscaledCycleClock::Now() { + uint64_t low, high; + __asm__ volatile("rdtsc" : "=a"(low), "=d"(high)); + return (high << 32) | low; +} + +double UnscaledCycleClock::Frequency() { + return base_internal::NominalCPUFrequency(); +} + +#elif defined(__powerpc__) || defined(__ppc__) + +int64_t UnscaledCycleClock::Now() { + return __ppc_get_timebase(); +} + +double UnscaledCycleClock::Frequency() { + return __ppc_get_timebase_freq(); +} + +#elif defined(__aarch64__) + +// System timer of ARMv8 runs at a different frequency than the CPU's. +// The frequency is fixed, typically in the range 1-50MHz. It can be +// read at CNTFRQ special register. We assume the OS has set up +// the virtual timer properly. +int64_t UnscaledCycleClock::Now() { + int64_t virtual_timer_value; + asm volatile("mrs %0, cntvct_el0" : "=r"(virtual_timer_value)); + return virtual_timer_value; +} + +double UnscaledCycleClock::Frequency() { + uint64_t aarch64_timer_frequency; + asm volatile("mrs %0, cntfrq_el0" : "=r"(aarch64_timer_frequency)); + return aarch64_timer_frequency; +} + +#elif defined(_M_IX86) || defined(_M_X64) + +#pragma intrinsic(__rdtsc) + +int64_t UnscaledCycleClock::Now() { + return __rdtsc(); +} + +double UnscaledCycleClock::Frequency() { + return base_internal::NominalCPUFrequency(); +} + +#endif + +} // namespace base_internal +} // namespace absl + +#endif // ABSL_USE_UNSCALED_CYCLECLOCK diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/unscaledcycleclock.h b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/unscaledcycleclock.h new file mode 100644 index 0000000..049f1ca --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/internal/unscaledcycleclock.h @@ -0,0 +1,119 @@ +// Copyright 2017 The Abseil Authors. +// +// 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. +// +// UnscaledCycleClock +// An UnscaledCycleClock yields the value and frequency of a cycle counter +// that increments at a rate that is approximately constant. +// This class is for internal / whitelisted use only, you should consider +// using CycleClock instead. +// +// Notes: +// The cycle counter frequency is not necessarily the core clock frequency. +// That is, CycleCounter cycles are not necessarily "CPU cycles". +// +// An arbitrary offset may have been added to the counter at power on. +// +// On some platforms, the rate and offset of the counter may differ +// slightly when read from different CPUs of a multiprocessor. Usually, +// we try to ensure that the operating system adjusts values periodically +// so that values agree approximately. If you need stronger guarantees, +// consider using alternate interfaces. +// +// The CPU is not required to maintain the ordering of a cycle counter read +// with respect to surrounding instructions. + +#ifndef ABSL_BASE_INTERNAL_UNSCALEDCYCLECLOCK_H_ +#define ABSL_BASE_INTERNAL_UNSCALEDCYCLECLOCK_H_ + +#include + +#if defined(__APPLE__) +#include +#endif + +#include "absl/base/port.h" + +// The following platforms have an implementation of a hardware counter. +#if defined(__i386__) || defined(__x86_64__) || defined(__aarch64__) || \ + defined(__powerpc__) || defined(__ppc__) || \ + defined(_M_IX86) || defined(_M_X64) +#define ABSL_HAVE_UNSCALED_CYCLECLOCK_IMPLEMENTATION 1 +#else +#define ABSL_HAVE_UNSCALED_CYCLECLOCK_IMPLEMENTATION 0 +#endif + +// The following platforms often disable access to the hardware +// counter (through a sandbox) even if the underlying hardware has a +// usable counter. The CycleTimer interface also requires a *scaled* +// CycleClock that runs at atleast 1 MHz. We've found some Android +// ARM64 devices where this is not the case, so we disable it by +// default on Android ARM64. +#if defined(__native_client__) || TARGET_OS_IPHONE || \ + (defined(__ANDROID__) && defined(__aarch64__)) +#define ABSL_USE_UNSCALED_CYCLECLOCK_DEFAULT 0 +#else +#define ABSL_USE_UNSCALED_CYCLECLOCK_DEFAULT 1 +#endif + +// UnscaledCycleClock is an optional internal feature. +// Use "#if ABSL_USE_UNSCALED_CYCLECLOCK" to test for its presence. +// Can be overridden at compile-time via -DABSL_USE_UNSCALED_CYCLECLOCK=0|1 +#if !defined(ABSL_USE_UNSCALED_CYCLECLOCK) +#define ABSL_USE_UNSCALED_CYCLECLOCK \ + (ABSL_HAVE_UNSCALED_CYCLECLOCK_IMPLEMENTATION && \ + ABSL_USE_UNSCALED_CYCLECLOCK_DEFAULT) +#endif + +#if ABSL_USE_UNSCALED_CYCLECLOCK + +// This macro can be used to test if UnscaledCycleClock::Frequency() +// is NominalCPUFrequency() on a particular platform. +#if (defined(__i386__) || defined(__x86_64__) || \ + defined(_M_IX86) || defined(_M_X64)) +#define ABSL_INTERNAL_UNSCALED_CYCLECLOCK_FREQUENCY_IS_CPU_FREQUENCY +#endif +namespace absl { +namespace time_internal { +class UnscaledCycleClockWrapperForGetCurrentTime; +} // namespace time_internal + +namespace base_internal { +class CycleClock; +class UnscaledCycleClockWrapperForInitializeFrequency; + +class UnscaledCycleClock { + private: + UnscaledCycleClock() = delete; + + // Return the value of a cycle counter that counts at a rate that is + // approximately constant. + static int64_t Now(); + + // Return the how much UnscaledCycleClock::Now() increases per second. + // This is not necessarily the core CPU clock frequency. + // It may be the nominal value report by the kernel, rather than a measured + // value. + static double Frequency(); + + // Whitelisted friends. + friend class base_internal::CycleClock; + friend class time_internal::UnscaledCycleClockWrapperForGetCurrentTime; + friend class base_internal::UnscaledCycleClockWrapperForInitializeFrequency; +}; + +} // namespace base_internal +} // namespace absl +#endif // ABSL_USE_UNSCALED_CYCLECLOCK + +#endif // ABSL_BASE_INTERNAL_UNSCALEDCYCLECLOCK_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/invoke_test.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/invoke_test.cc new file mode 100644 index 0000000..466bf11 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/invoke_test.cc @@ -0,0 +1,200 @@ +// Copyright 2017 The Abseil Authors. +// +// 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 "absl/base/internal/invoke.h" + +#include +#include +#include +#include + +#include "gmock/gmock.h" +#include "gtest/gtest.h" +#include "absl/memory/memory.h" +#include "absl/strings/str_cat.h" + +namespace absl { +namespace base_internal { +namespace { + +int Function(int a, int b) { return a - b; } + +int Sink(std::unique_ptr p) { + return *p; +} + +std::unique_ptr Factory(int n) { + return make_unique(n); +} + +void NoOp() {} + +struct ConstFunctor { + int operator()(int a, int b) const { return a - b; } +}; + +struct MutableFunctor { + int operator()(int a, int b) { return a - b; } +}; + +struct EphemeralFunctor { + int operator()(int a, int b) && { return a - b; } +}; + +struct OverloadedFunctor { + template + std::string operator()(const Args&... args) & { + return StrCat("&", args...); + } + template + std::string operator()(const Args&... args) const& { + return StrCat("const&", args...); + } + template + std::string operator()(const Args&... args) && { + return StrCat("&&", args...); + } +}; + +struct Class { + int Method(int a, int b) { return a - b; } + int ConstMethod(int a, int b) const { return a - b; } + + int member; +}; + +struct FlipFlop { + int ConstMethod() const { return member; } + FlipFlop operator*() const { return {-member}; } + + int member; +}; + +// CallMaybeWithArg(f) resolves either to Invoke(f) or Invoke(f, 42), depending +// on which one is valid. +template +decltype(Invoke(std::declval())) CallMaybeWithArg(const F& f) { + return Invoke(f); +} + +template +decltype(Invoke(std::declval(), 42)) CallMaybeWithArg(const F& f) { + return Invoke(f, 42); +} + +TEST(InvokeTest, Function) { + EXPECT_EQ(1, Invoke(Function, 3, 2)); + EXPECT_EQ(1, Invoke(&Function, 3, 2)); +} + +TEST(InvokeTest, NonCopyableArgument) { + EXPECT_EQ(42, Invoke(Sink, make_unique(42))); +} + +TEST(InvokeTest, NonCopyableResult) { + EXPECT_THAT(Invoke(Factory, 42), ::testing::Pointee(42)); +} + +TEST(InvokeTest, VoidResult) { + Invoke(NoOp); +} + +TEST(InvokeTest, ConstFunctor) { + EXPECT_EQ(1, Invoke(ConstFunctor(), 3, 2)); +} + +TEST(InvokeTest, MutableFunctor) { + MutableFunctor f; + EXPECT_EQ(1, Invoke(f, 3, 2)); + EXPECT_EQ(1, Invoke(MutableFunctor(), 3, 2)); +} + +TEST(InvokeTest, EphemeralFunctor) { + EphemeralFunctor f; + EXPECT_EQ(1, Invoke(std::move(f), 3, 2)); + EXPECT_EQ(1, Invoke(EphemeralFunctor(), 3, 2)); +} + +TEST(InvokeTest, OverloadedFunctor) { + OverloadedFunctor f; + const OverloadedFunctor& cf = f; + + EXPECT_EQ("&", Invoke(f)); + EXPECT_EQ("& 42", Invoke(f, " 42")); + + EXPECT_EQ("const&", Invoke(cf)); + EXPECT_EQ("const& 42", Invoke(cf, " 42")); + + EXPECT_EQ("&&", Invoke(std::move(f))); + EXPECT_EQ("&& 42", Invoke(std::move(f), " 42")); +} + +TEST(InvokeTest, ReferenceWrapper) { + ConstFunctor cf; + MutableFunctor mf; + EXPECT_EQ(1, Invoke(std::cref(cf), 3, 2)); + EXPECT_EQ(1, Invoke(std::ref(cf), 3, 2)); + EXPECT_EQ(1, Invoke(std::ref(mf), 3, 2)); +} + +TEST(InvokeTest, MemberFunction) { + std::unique_ptr p(new Class); + std::unique_ptr cp(new Class); + EXPECT_EQ(1, Invoke(&Class::Method, p, 3, 2)); + EXPECT_EQ(1, Invoke(&Class::Method, p.get(), 3, 2)); + + EXPECT_EQ(1, Invoke(&Class::ConstMethod, p, 3, 2)); + EXPECT_EQ(1, Invoke(&Class::ConstMethod, p.get(), 3, 2)); + EXPECT_EQ(1, Invoke(&Class::ConstMethod, *p, 3, 2)); + + EXPECT_EQ(1, Invoke(&Class::ConstMethod, cp, 3, 2)); + EXPECT_EQ(1, Invoke(&Class::ConstMethod, cp.get(), 3, 2)); + EXPECT_EQ(1, Invoke(&Class::ConstMethod, *cp, 3, 2)); + + EXPECT_EQ(1, Invoke(&Class::Method, make_unique(), 3, 2)); + EXPECT_EQ(1, Invoke(&Class::ConstMethod, make_unique(), 3, 2)); + EXPECT_EQ(1, Invoke(&Class::ConstMethod, make_unique(), 3, 2)); +} + +TEST(InvokeTest, DataMember) { + std::unique_ptr p(new Class{42}); + std::unique_ptr cp(new Class{42}); + EXPECT_EQ(42, Invoke(&Class::member, p)); + EXPECT_EQ(42, Invoke(&Class::member, *p)); + EXPECT_EQ(42, Invoke(&Class::member, p.get())); + + Invoke(&Class::member, p) = 42; + Invoke(&Class::member, p.get()) = 42; + + EXPECT_EQ(42, Invoke(&Class::member, cp)); + EXPECT_EQ(42, Invoke(&Class::member, *cp)); + EXPECT_EQ(42, Invoke(&Class::member, cp.get())); +} + +TEST(InvokeTest, FlipFlop) { + FlipFlop obj = {42}; + // This call could resolve to (obj.*&FlipFlop::ConstMethod)() or + // ((*obj).*&FlipFlop::ConstMethod)(). We verify that it's the former. + EXPECT_EQ(42, Invoke(&FlipFlop::ConstMethod, obj)); + EXPECT_EQ(42, Invoke(&FlipFlop::member, obj)); +} + +TEST(InvokeTest, SfinaeFriendly) { + CallMaybeWithArg(NoOp); + EXPECT_THAT(CallMaybeWithArg(Factory), ::testing::Pointee(42)); +} + +} // namespace +} // namespace base_internal +} // namespace absl diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/log_severity.h b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/log_severity.h new file mode 100644 index 0000000..5770d36 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/log_severity.h @@ -0,0 +1,67 @@ +// Copyright 2017 The Abseil Authors. +// +// 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. +// + +#ifndef ABSL_BASE_INTERNAL_LOG_SEVERITY_H_ +#define ABSL_BASE_INTERNAL_LOG_SEVERITY_H_ + +#include + +#include "absl/base/attributes.h" + +namespace absl { + +// Four severity levels are defined. Logging APIs should terminate the program +// when a message is logged at severity `kFatal`; the other levels have no +// special semantics. +enum class LogSeverity : int { + kInfo = 0, + kWarning = 1, + kError = 2, + kFatal = 3, +}; + +// Returns an iterable of all standard `absl::LogSeverity` values, ordered from +// least to most severe. +constexpr std::array LogSeverities() { + return {{absl::LogSeverity::kInfo, absl::LogSeverity::kWarning, + absl::LogSeverity::kError, absl::LogSeverity::kFatal}}; +} + +// Returns the all-caps string representation (e.g. "INFO") of the specified +// severity level if it is one of the normal levels and "UNKNOWN" otherwise. +constexpr const char* LogSeverityName(absl::LogSeverity s) { + return s == absl::LogSeverity::kInfo + ? "INFO" + : s == absl::LogSeverity::kWarning + ? "WARNING" + : s == absl::LogSeverity::kError + ? "ERROR" + : s == absl::LogSeverity::kFatal ? "FATAL" : "UNKNOWN"; +} + +// Values less than `kInfo` normalize to `kInfo`; values greater than `kFatal` +// normalize to `kError` (**NOT** `kFatal`). +constexpr absl::LogSeverity NormalizeLogSeverity(absl::LogSeverity s) { + return s < absl::LogSeverity::kInfo + ? absl::LogSeverity::kInfo + : s > absl::LogSeverity::kFatal ? absl::LogSeverity::kError : s; +} +constexpr absl::LogSeverity NormalizeLogSeverity(int s) { + return NormalizeLogSeverity(static_cast(s)); +} + +} // namespace absl + +#endif // ABSL_BASE_INTERNAL_LOG_SEVERITY_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/macros.h b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/macros.h new file mode 100644 index 0000000..96dc0e0 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/macros.h @@ -0,0 +1,212 @@ +// +// Copyright 2017 The Abseil Authors. +// +// 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. +// +// ----------------------------------------------------------------------------- +// File: macros.h +// ----------------------------------------------------------------------------- +// +// This header file defines the set of language macros used within Abseil code. +// For the set of macros used to determine supported compilers and platforms, +// see absl/base/config.h instead. +// +// This code is compiled directly on many platforms, including client +// platforms like Windows, Mac, and embedded systems. Before making +// any changes here, make sure that you're not breaking any platforms. +// + +#ifndef ABSL_BASE_MACROS_H_ +#define ABSL_BASE_MACROS_H_ + +#include +#include + +#include "absl/base/port.h" + +// ABSL_ARRAYSIZE() +// +// Returns the number of elements in an array as a compile-time constant, which +// can be used in defining new arrays. If you use this macro on a pointer by +// mistake, you will get a compile-time error. +#define ABSL_ARRAYSIZE(array) \ + (sizeof(::absl::macros_internal::ArraySizeHelper(array))) + +namespace absl { +namespace macros_internal { +// Note: this internal template function declaration is used by ABSL_ARRAYSIZE. +// The function doesn't need a definition, as we only use its type. +template +auto ArraySizeHelper(const T (&array)[N]) -> char (&)[N]; +} // namespace macros_internal +} // namespace absl + +// kLinkerInitialized +// +// An enum used only as a constructor argument to indicate that a variable has +// static storage duration, and that the constructor should do nothing to its +// state. Use of this macro indicates to the reader that it is legal to +// declare a static instance of the class, provided the constructor is given +// the absl::base_internal::kLinkerInitialized argument. +// +// Normally, it is unsafe to declare a static variable that has a constructor or +// a destructor because invocation order is undefined. However, if the type can +// be zero-initialized (which the loader does for static variables) into a valid +// state and the type's destructor does not affect storage, then a constructor +// for static initialization can be declared. +// +// Example: +// // Declaration +// explicit MyClass(absl::base_internal:LinkerInitialized x) {} +// +// // Invocation +// static MyClass my_global(absl::base_internal::kLinkerInitialized); +namespace absl { +namespace base_internal { +enum LinkerInitialized { + kLinkerInitialized = 0, +}; +} // namespace base_internal +} // namespace absl + +// ABSL_FALLTHROUGH_INTENDED +// +// Annotates implicit fall-through between switch labels, allowing a case to +// indicate intentional fallthrough and turn off warnings about any lack of a +// `break` statement. The ABSL_FALLTHROUGH_INTENDED macro should be followed by +// a semicolon and can be used in most places where `break` can, provided that +// no statements exist between it and the next switch label. +// +// Example: +// +// switch (x) { +// case 40: +// case 41: +// if (truth_is_out_there) { +// ++x; +// ABSL_FALLTHROUGH_INTENDED; // Use instead of/along with annotations +// // in comments +// } else { +// return x; +// } +// case 42: +// ... +// +// Notes: when compiled with clang in C++11 mode, the ABSL_FALLTHROUGH_INTENDED +// macro is expanded to the [[clang::fallthrough]] attribute, which is analysed +// when performing switch labels fall-through diagnostic +// (`-Wimplicit-fallthrough`). See clang documentation on language extensions +// for details: +// http://clang.llvm.org/docs/AttributeReference.html#fallthrough-clang-fallthrough +// +// When used with unsupported compilers, the ABSL_FALLTHROUGH_INTENDED macro +// has no effect on diagnostics. In any case this macro has no effect on runtime +// behavior and performance of code. +#ifdef ABSL_FALLTHROUGH_INTENDED +#error "ABSL_FALLTHROUGH_INTENDED should not be defined." +#endif + +// TODO(zhangxy): Use c++17 standard [[fallthrough]] macro, when supported. +#if defined(__clang__) && defined(__has_warning) +#if __has_feature(cxx_attributes) && __has_warning("-Wimplicit-fallthrough") +#define ABSL_FALLTHROUGH_INTENDED [[clang::fallthrough]] +#endif +#elif defined(__GNUC__) && __GNUC__ >= 7 +#define ABSL_FALLTHROUGH_INTENDED [[gnu::fallthrough]] +#endif + +#ifndef ABSL_FALLTHROUGH_INTENDED +#define ABSL_FALLTHROUGH_INTENDED \ + do { \ + } while (0) +#endif + +// ABSL_DEPRECATED() +// +// Marks a deprecated class, struct, enum, function, method and variable +// declarations. The macro argument is used as a custom diagnostic message (e.g. +// suggestion of a better alternative). +// +// Example: +// +// class ABSL_DEPRECATED("Use Bar instead") Foo {...}; +// ABSL_DEPRECATED("Use Baz instead") void Bar() {...} +// +// Every usage of a deprecated entity will trigger a warning when compiled with +// clang's `-Wdeprecated-declarations` option. This option is turned off by +// default, but the warnings will be reported by clang-tidy. +#if defined(__clang__) && __cplusplus >= 201103L +#define ABSL_DEPRECATED(message) __attribute__((deprecated(message))) +#endif + +#ifndef ABSL_DEPRECATED +#define ABSL_DEPRECATED(message) +#endif + +// ABSL_BAD_CALL_IF() +// +// Used on a function overload to trap bad calls: any call that matches the +// overload will cause a compile-time error. This macro uses a clang-specific +// "enable_if" attribute, as described at +// http://clang.llvm.org/docs/AttributeReference.html#enable-if +// +// Overloads which use this macro should be bracketed by +// `#ifdef ABSL_BAD_CALL_IF`. +// +// Example: +// +// int isdigit(int c); +// #ifdef ABSL_BAD_CALL_IF +// int isdigit(int c) +// ABSL_BAD_CALL_IF(c <= -1 || c > 255, +// "'c' must have the value of an unsigned char or EOF"); +// #endif // ABSL_BAD_CALL_IF + +#if defined(__clang__) +# if __has_attribute(enable_if) +# define ABSL_BAD_CALL_IF(expr, msg) \ + __attribute__((enable_if(expr, "Bad call trap"), unavailable(msg))) +# endif +#endif + +// ABSL_ASSERT() +// +// In C++11, `assert` can't be used portably within constexpr functions. +// ABSL_ASSERT functions as a runtime assert but works in C++11 constexpr +// functions. Example: +// +// constexpr double Divide(double a, double b) { +// return ABSL_ASSERT(b != 0), a / b; +// } +// +// This macro is inspired by +// https://akrzemi1.wordpress.com/2017/05/18/asserts-in-constexpr-functions/ +#if defined(NDEBUG) +#define ABSL_ASSERT(expr) (void) (false ? (void)(expr) : (void)0) +#else +#define ABSL_ASSERT(expr) \ + (void) (ABSL_PREDICT_TRUE((expr)) ? (void)0 \ + : [] { assert(false && #expr); }()) // NOLINT +#endif + +#ifdef ABSL_HAVE_EXCEPTIONS +#define ABSL_INTERNAL_TRY try +#define ABSL_INTERNAL_CATCH_ANY catch (...) +#define ABSL_INTERNAL_RETHROW do { throw; } while (false) +#else // ABSL_HAVE_EXCEPTIONS +#define ABSL_INTERNAL_TRY if (true) +#define ABSL_INTERNAL_CATCH_ANY else if (false) +#define ABSL_INTERNAL_RETHROW do {} while (false) +#endif // ABSL_HAVE_EXCEPTIONS + +#endif // ABSL_BASE_MACROS_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/optimization.h b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/optimization.h new file mode 100644 index 0000000..2fddfc8 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/optimization.h @@ -0,0 +1,165 @@ +// +// Copyright 2017 The Abseil Authors. +// +// 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. +// +// ----------------------------------------------------------------------------- +// File: optimization.h +// ----------------------------------------------------------------------------- +// +// This header file defines portable macros for performance optimization. + +#ifndef ABSL_BASE_OPTIMIZATION_H_ +#define ABSL_BASE_OPTIMIZATION_H_ + +#include "absl/base/config.h" + +// ABSL_BLOCK_TAIL_CALL_OPTIMIZATION +// +// Instructs the compiler to avoid optimizing tail-call recursion. Use of this +// macro is useful when you wish to preserve the existing function order within +// a stack trace for logging, debugging, or profiling purposes. +// +// Example: +// +// int f() { +// int result = g(); +// ABSL_BLOCK_TAIL_CALL_OPTIMIZATION(); +// return result; +// } +#if defined(__pnacl__) +#define ABSL_BLOCK_TAIL_CALL_OPTIMIZATION() if (volatile int x = 0) { (void)x; } +#elif defined(__clang__) +// Clang will not tail call given inline volatile assembly. +#define ABSL_BLOCK_TAIL_CALL_OPTIMIZATION() __asm__ __volatile__("") +#elif defined(__GNUC__) +// GCC will not tail call given inline volatile assembly. +#define ABSL_BLOCK_TAIL_CALL_OPTIMIZATION() __asm__ __volatile__("") +#elif defined(_MSC_VER) +#include +// The __nop() intrinsic blocks the optimisation. +#define ABSL_BLOCK_TAIL_CALL_OPTIMIZATION() __nop() +#else +#define ABSL_BLOCK_TAIL_CALL_OPTIMIZATION() if (volatile int x = 0) { (void)x; } +#endif + +// ABSL_CACHELINE_SIZE +// +// Explicitly defines the size of the L1 cache for purposes of alignment. +// Setting the cacheline size allows you to specify that certain objects be +// aligned on a cacheline boundary with `ABSL_CACHELINE_ALIGNED` declarations. +// (See below.) +// +// NOTE: this macro should be replaced with the following C++17 features, when +// those are generally available: +// +// * `std::hardware_constructive_interference_size` +// * `std::hardware_destructive_interference_size` +// +// See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0154r1.html +// for more information. +#if defined(__GNUC__) +// Cache line alignment +#if defined(__i386__) || defined(__x86_64__) +#define ABSL_CACHELINE_SIZE 64 +#elif defined(__powerpc64__) +#define ABSL_CACHELINE_SIZE 128 +#elif defined(__aarch64__) +// We would need to read special register ctr_el0 to find out L1 dcache size. +// This value is a good estimate based on a real aarch64 machine. +#define ABSL_CACHELINE_SIZE 64 +#elif defined(__arm__) +// Cache line sizes for ARM: These values are not strictly correct since +// cache line sizes depend on implementations, not architectures. There +// are even implementations with cache line sizes configurable at boot +// time. +#if defined(__ARM_ARCH_5T__) +#define ABSL_CACHELINE_SIZE 32 +#elif defined(__ARM_ARCH_7A__) +#define ABSL_CACHELINE_SIZE 64 +#endif +#endif + +#ifndef ABSL_CACHELINE_SIZE +// A reasonable default guess. Note that overestimates tend to waste more +// space, while underestimates tend to waste more time. +#define ABSL_CACHELINE_SIZE 64 +#endif + +// ABSL_CACHELINE_ALIGNED +// +// Indicates that the declared object be cache aligned using +// `ABSL_CACHELINE_SIZE` (see above). Cacheline aligning objects allows you to +// load a set of related objects in the L1 cache for performance improvements. +// Cacheline aligning objects properly allows constructive memory sharing and +// prevents destructive (or "false") memory sharing. +// +// NOTE: this macro should be replaced with usage of `alignas()` using +// `std::hardware_constructive_interference_size` and/or +// `std::hardware_destructive_interference_size` when available within C++17. +// +// See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0154r1.html +// for more information. +// +// On some compilers, `ABSL_CACHELINE_ALIGNED` expands to +// `__attribute__((aligned(ABSL_CACHELINE_SIZE)))`. For compilers where this is +// not known to work, the macro expands to nothing. +// +// No further guarantees are made here. The result of applying the macro +// to variables and types is always implementation-defined. +// +// WARNING: It is easy to use this attribute incorrectly, even to the point +// of causing bugs that are difficult to diagnose, crash, etc. It does not +// of itself guarantee that objects are aligned to a cache line. +// +// Recommendations: +// +// 1) Consult compiler documentation; this comment is not kept in sync as +// toolchains evolve. +// 2) Verify your use has the intended effect. This often requires inspecting +// the generated machine code. +// 3) Prefer applying this attribute to individual variables. Avoid +// applying it to types. This tends to localize the effect. +#define ABSL_CACHELINE_ALIGNED __attribute__((aligned(ABSL_CACHELINE_SIZE))) + +#else // not GCC +#define ABSL_CACHELINE_SIZE 64 +#define ABSL_CACHELINE_ALIGNED +#endif + +// ABSL_PREDICT_TRUE, ABSL_PREDICT_FALSE +// +// Enables the compiler to prioritize compilation using static analysis for +// likely paths within a boolean branch. +// +// Example: +// +// if (ABSL_PREDICT_TRUE(expression)) { +// return result; // Faster if more likely +// } else { +// return 0; +// } +// +// Compilers can use the information that a certain branch is not likely to be +// taken (for instance, a CHECK failure) to optimize for the common case in +// the absence of better information (ie. compiling gcc with `-fprofile-arcs`). +#if ABSL_HAVE_BUILTIN(__builtin_expect) || \ + (defined(__GNUC__) && !defined(__clang__)) +#define ABSL_PREDICT_FALSE(x) (__builtin_expect(x, 0)) +#define ABSL_PREDICT_TRUE(x) (__builtin_expect(!!(x), 1)) +#else +#define ABSL_PREDICT_FALSE(x) (x) +#define ABSL_PREDICT_TRUE(x) (x) +#endif + +#endif // ABSL_BASE_OPTIMIZATION_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/policy_checks.h b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/policy_checks.h new file mode 100644 index 0000000..0a07fc0 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/policy_checks.h @@ -0,0 +1,121 @@ +// Copyright 2017 The Abseil Authors. +// +// 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. +// +// ----------------------------------------------------------------------------- +// File: policy_checks.h +// ----------------------------------------------------------------------------- +// +// This header enforces a minimum set of policies at build time, such as the +// supported compiler and library versions. Unsupported configurations are +// reported with `#error`. This enforcement is best effort, so successfully +// compiling this header does not guarantee a supported configuration. + +#ifndef ABSL_BASE_POLICY_CHECKS_H_ +#define ABSL_BASE_POLICY_CHECKS_H_ + +// Included for the __GLIBC_PREREQ macro used below. +#include + +// Included for the _STLPORT_VERSION macro used below. +#if defined(__cplusplus) +#include +#endif + +// ----------------------------------------------------------------------------- +// Operating System Check +// ----------------------------------------------------------------------------- + +#if defined(__CYGWIN__) +#error "Cygwin is not supported." +#endif + +// ----------------------------------------------------------------------------- +// Compiler Check +// ----------------------------------------------------------------------------- + +// We support MSVC++ 14.0 update 2 and later. +// This minimum will go up. +#if defined(_MSC_FULL_VER) && _MSC_FULL_VER < 190023918 && !defined(__clang__) +#error "This package requires Visual Studio 2015 Update 2 or higher." +#endif + +// We support gcc 4.7 and later. +// This minimum will go up. +#if defined(__GNUC__) && !defined(__clang__) +#if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 7) +#error "This package requires gcc 4.7 or higher." +#endif +#endif + +// We support Apple Xcode clang 4.2.1 (version 421.11.65) and later. +// This corresponds to Apple Xcode version 4.5. +// This minimum will go up. +#if defined(__apple_build_version__) && __apple_build_version__ < 4211165 +#error "This package requires __apple_build_version__ of 4211165 or higher." +#endif + +// ----------------------------------------------------------------------------- +// C++ Version Check +// ----------------------------------------------------------------------------- + +// Enforce C++11 as the minimum. Note that Visual Studio has not +// advanced __cplusplus despite being good enough for our purposes, so +// so we exempt it from the check. +#if defined(__cplusplus) && !defined(_MSC_VER) +#if __cplusplus < 201103L +#error "C++ versions less than C++11 are not supported." +#endif +#endif + +// ----------------------------------------------------------------------------- +// Standard Library Check +// ----------------------------------------------------------------------------- + +// We have chosen glibc 2.12 as the minimum as it was tagged for release +// in May, 2010 and includes some functionality used in Google software +// (for instance pthread_setname_np): +// https://sourceware.org/ml/libc-alpha/2010-05/msg00000.html +#if defined(__GLIBC__) && defined(__GLIBC_PREREQ) +#if !__GLIBC_PREREQ(2, 12) +#error "Minimum required version of glibc is 2.12." +#endif +#endif + +#if defined(_STLPORT_VERSION) +#error "STLPort is not supported." +#endif + +// ----------------------------------------------------------------------------- +// `char` Size Check +// ----------------------------------------------------------------------------- + +// Abseil currently assumes CHAR_BIT == 8. If you would like to use Abseil on a +// platform where this is not the case, please provide us with the details about +// your platform so we can consider relaxing this requirement. +#if CHAR_BIT != 8 +#error "Abseil assumes CHAR_BIT == 8." +#endif + +// ----------------------------------------------------------------------------- +// `int` Size Check +// ----------------------------------------------------------------------------- + +// Abseil currently assumes that an int is 4 bytes. If you would like to use +// Abseil on a platform where this is not the case, please provide us with the +// details about your platform so we can consider relaxing this requirement. +#if INT_MAX < 2147483647 +#error "Abseil assumes that int is at least 4 bytes. " +#endif + +#endif // ABSL_BASE_POLICY_CHECKS_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/port.h b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/port.h new file mode 100644 index 0000000..1c67257 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/port.h @@ -0,0 +1,26 @@ +// Copyright 2017 The Abseil Authors. +// +// 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. +// +// This files is a forwarding header for other headers containing various +// portability macros and functions. +// This file is used for both C and C++! + +#ifndef ABSL_BASE_PORT_H_ +#define ABSL_BASE_PORT_H_ + +#include "absl/base/attributes.h" +#include "absl/base/config.h" +#include "absl/base/optimization.h" + +#endif // ABSL_BASE_PORT_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/raw_logging_test.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/raw_logging_test.cc new file mode 100644 index 0000000..b21cf65 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/raw_logging_test.cc @@ -0,0 +1,79 @@ +// Copyright 2017 The Abseil Authors. +// +// 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. + +// This test serves primarily as a compilation test for base/raw_logging.h. +// Raw logging testing is covered by logging_unittest.cc, which is not as +// portable as this test. + +#include "absl/base/internal/raw_logging.h" + +#include + +#include "gtest/gtest.h" +#include "absl/strings/str_cat.h" + +namespace { + +TEST(RawLoggingCompilationTest, Log) { + ABSL_RAW_LOG(INFO, "RAW INFO: %d", 1); + ABSL_RAW_LOG(INFO, "RAW INFO: %d %d", 1, 2); + ABSL_RAW_LOG(INFO, "RAW INFO: %d %d %d", 1, 2, 3); + ABSL_RAW_LOG(INFO, "RAW INFO: %d %d %d %d", 1, 2, 3, 4); + ABSL_RAW_LOG(INFO, "RAW INFO: %d %d %d %d %d", 1, 2, 3, 4, 5); + ABSL_RAW_LOG(WARNING, "RAW WARNING: %d", 1); + ABSL_RAW_LOG(ERROR, "RAW ERROR: %d", 1); +} + +TEST(RawLoggingCompilationTest, PassingCheck) { + ABSL_RAW_CHECK(true, "RAW CHECK"); +} + +// Not all platforms support output from raw log, so we don't verify any +// particular output for RAW check failures (expecting the empty string +// accomplishes this). This test is primarily a compilation test, but we +// are verifying process death when EXPECT_DEATH works for a platform. +const char kExpectedDeathOutput[] = ""; + +TEST(RawLoggingDeathTest, FailingCheck) { + EXPECT_DEATH_IF_SUPPORTED(ABSL_RAW_CHECK(1 == 0, "explanation"), + kExpectedDeathOutput); +} + +TEST(RawLoggingDeathTest, LogFatal) { + EXPECT_DEATH_IF_SUPPORTED(ABSL_RAW_LOG(FATAL, "my dog has fleas"), + kExpectedDeathOutput); +} + +TEST(InternalLog, CompilationTest) { + ABSL_INTERNAL_LOG(INFO, "Internal Log"); + std::string log_msg = "Internal Log"; + ABSL_INTERNAL_LOG(INFO, log_msg); + + ABSL_INTERNAL_LOG(INFO, log_msg + " 2"); + + float d = 1.1f; + ABSL_INTERNAL_LOG(INFO, absl::StrCat("Internal log ", 3, " + ", d)); +} + +TEST(InternalLogDeathTest, FailingCheck) { + EXPECT_DEATH_IF_SUPPORTED(ABSL_INTERNAL_CHECK(1 == 0, "explanation"), + kExpectedDeathOutput); +} + +TEST(InternalLogDeathTest, LogFatal) { + EXPECT_DEATH_IF_SUPPORTED(ABSL_INTERNAL_LOG(FATAL, "my dog has fleas"), + kExpectedDeathOutput); +} + +} // namespace diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/spinlock_test_common.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/spinlock_test_common.cc new file mode 100644 index 0000000..1b50884 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/spinlock_test_common.cc @@ -0,0 +1,266 @@ +// Copyright 2017 The Abseil Authors. +// +// 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 bunch of threads repeatedly hash an array of ints protected by a +// spinlock. If the spinlock is working properly, all elements of the +// array should be equal at the end of the test. + +#include +#include +#include +#include // NOLINT(build/c++11) +#include + +#include "gtest/gtest.h" +#include "absl/base/attributes.h" +#include "absl/base/internal/low_level_scheduling.h" +#include "absl/base/internal/scheduling_mode.h" +#include "absl/base/internal/spinlock.h" +#include "absl/base/internal/sysinfo.h" +#include "absl/base/macros.h" +#include "absl/synchronization/blocking_counter.h" +#include "absl/synchronization/notification.h" + +constexpr int32_t kNumThreads = 10; +constexpr int32_t kIters = 1000; + +namespace absl { +namespace base_internal { + +// This is defined outside of anonymous namespace so that it can be +// a friend of SpinLock to access protected methods for testing. +struct SpinLockTest { + static uint32_t EncodeWaitCycles(int64_t wait_start_time, + int64_t wait_end_time) { + return SpinLock::EncodeWaitCycles(wait_start_time, wait_end_time); + } + static uint64_t DecodeWaitCycles(uint32_t lock_value) { + return SpinLock::DecodeWaitCycles(lock_value); + } +}; + +namespace { + +static constexpr int kArrayLength = 10; +static uint32_t values[kArrayLength]; +static SpinLock static_spinlock(base_internal::kLinkerInitialized); +static SpinLock static_cooperative_spinlock( + base_internal::kLinkerInitialized, + base_internal::SCHEDULE_COOPERATIVE_AND_KERNEL); +static SpinLock static_noncooperative_spinlock( + base_internal::kLinkerInitialized, base_internal::SCHEDULE_KERNEL_ONLY); + + +// Simple integer hash function based on the public domain lookup2 hash. +// http://burtleburtle.net/bob/c/lookup2.c +static uint32_t Hash32(uint32_t a, uint32_t c) { + uint32_t b = 0x9e3779b9UL; // The golden ratio; an arbitrary value. + a -= b; a -= c; a ^= (c >> 13); + b -= c; b -= a; b ^= (a << 8); + c -= a; c -= b; c ^= (b >> 13); + a -= b; a -= c; a ^= (c >> 12); + b -= c; b -= a; b ^= (a << 16); + c -= a; c -= b; c ^= (b >> 5); + a -= b; a -= c; a ^= (c >> 3); + b -= c; b -= a; b ^= (a << 10); + c -= a; c -= b; c ^= (b >> 15); + return c; +} + +static void TestFunction(int thread_salt, SpinLock* spinlock) { + for (int i = 0; i < kIters; i++) { + SpinLockHolder h(spinlock); + for (int j = 0; j < kArrayLength; j++) { + const int index = (j + thread_salt) % kArrayLength; + values[index] = Hash32(values[index], thread_salt); + std::this_thread::yield(); + } + } +} + +static void ThreadedTest(SpinLock* spinlock) { + std::vector threads; + for (int i = 0; i < kNumThreads; ++i) { + threads.push_back(std::thread(TestFunction, i, spinlock)); + } + for (auto& thread : threads) { + thread.join(); + } + + SpinLockHolder h(spinlock); + for (int i = 1; i < kArrayLength; i++) { + EXPECT_EQ(values[0], values[i]); + } +} + +TEST(SpinLock, StackNonCooperativeDisablesScheduling) { + SpinLock spinlock(base_internal::SCHEDULE_KERNEL_ONLY); + spinlock.Lock(); + EXPECT_FALSE(base_internal::SchedulingGuard::ReschedulingIsAllowed()); + spinlock.Unlock(); +} + +TEST(SpinLock, StaticNonCooperativeDisablesScheduling) { + static_noncooperative_spinlock.Lock(); + EXPECT_FALSE(base_internal::SchedulingGuard::ReschedulingIsAllowed()); + static_noncooperative_spinlock.Unlock(); +} + +TEST(SpinLock, WaitCyclesEncoding) { + // These are implementation details not exported by SpinLock. + const int kProfileTimestampShift = 7; + const int kLockwordReservedShift = 3; + const uint32_t kSpinLockSleeper = 8; + + // We should be able to encode up to (1^kMaxCycleBits - 1) without clamping + // but the lower kProfileTimestampShift will be dropped. + const int kMaxCyclesShift = + 32 - kLockwordReservedShift + kProfileTimestampShift; + const uint64_t kMaxCycles = (int64_t{1} << kMaxCyclesShift) - 1; + + // These bits should be zero after encoding. + const uint32_t kLockwordReservedMask = (1 << kLockwordReservedShift) - 1; + + // These bits are dropped when wait cycles are encoded. + const uint64_t kProfileTimestampMask = (1 << kProfileTimestampShift) - 1; + + // Test a bunch of random values + std::default_random_engine generator; + // Shift to avoid overflow below. + std::uniform_int_distribution time_distribution( + 0, std::numeric_limits::max() >> 4); + std::uniform_int_distribution cycle_distribution(0, kMaxCycles); + + for (int i = 0; i < 100; i++) { + int64_t start_time = time_distribution(generator); + int64_t cycles = cycle_distribution(generator); + int64_t end_time = start_time + cycles; + uint32_t lock_value = SpinLockTest::EncodeWaitCycles(start_time, end_time); + EXPECT_EQ(0, lock_value & kLockwordReservedMask); + uint64_t decoded = SpinLockTest::DecodeWaitCycles(lock_value); + EXPECT_EQ(0, decoded & kProfileTimestampMask); + EXPECT_EQ(cycles & ~kProfileTimestampMask, decoded); + } + + // Test corner cases + int64_t start_time = time_distribution(generator); + EXPECT_EQ(0, SpinLockTest::EncodeWaitCycles(start_time, start_time)); + EXPECT_EQ(0, SpinLockTest::DecodeWaitCycles(0)); + EXPECT_EQ(0, SpinLockTest::DecodeWaitCycles(kLockwordReservedMask)); + EXPECT_EQ(kMaxCycles & ~kProfileTimestampMask, + SpinLockTest::DecodeWaitCycles(~kLockwordReservedMask)); + + // Check that we cannot produce kSpinLockSleeper during encoding. + int64_t sleeper_cycles = + kSpinLockSleeper << (kProfileTimestampShift - kLockwordReservedShift); + uint32_t sleeper_value = + SpinLockTest::EncodeWaitCycles(start_time, start_time + sleeper_cycles); + EXPECT_NE(sleeper_value, kSpinLockSleeper); + + // Test clamping + uint32_t max_value = + SpinLockTest::EncodeWaitCycles(start_time, start_time + kMaxCycles); + uint64_t max_value_decoded = SpinLockTest::DecodeWaitCycles(max_value); + uint64_t expected_max_value_decoded = kMaxCycles & ~kProfileTimestampMask; + EXPECT_EQ(expected_max_value_decoded, max_value_decoded); + + const int64_t step = (1 << kProfileTimestampShift); + uint32_t after_max_value = + SpinLockTest::EncodeWaitCycles(start_time, start_time + kMaxCycles + step); + uint64_t after_max_value_decoded = + SpinLockTest::DecodeWaitCycles(after_max_value); + EXPECT_EQ(expected_max_value_decoded, after_max_value_decoded); + + uint32_t before_max_value = SpinLockTest::EncodeWaitCycles( + start_time, start_time + kMaxCycles - step); + uint64_t before_max_value_decoded = + SpinLockTest::DecodeWaitCycles(before_max_value); + EXPECT_GT(expected_max_value_decoded, before_max_value_decoded); +} +TEST(SpinLockWithThreads, StaticSpinLock) { + ThreadedTest(&static_spinlock); +} +TEST(SpinLockWithThreads, StackSpinLock) { + SpinLock spinlock; + ThreadedTest(&spinlock); +} + +TEST(SpinLockWithThreads, StackCooperativeSpinLock) { + SpinLock spinlock(base_internal::SCHEDULE_COOPERATIVE_AND_KERNEL); + ThreadedTest(&spinlock); +} + +TEST(SpinLockWithThreads, StackNonCooperativeSpinLock) { + SpinLock spinlock(base_internal::SCHEDULE_KERNEL_ONLY); + ThreadedTest(&spinlock); +} + +TEST(SpinLockWithThreads, StaticCooperativeSpinLock) { + ThreadedTest(&static_cooperative_spinlock); +} + +TEST(SpinLockWithThreads, StaticNonCooperativeSpinLock) { + ThreadedTest(&static_noncooperative_spinlock); +} + +TEST(SpinLockWithThreads, DoesNotDeadlock) { + struct Helper { + static void NotifyThenLock(Notification* locked, SpinLock* spinlock, + BlockingCounter* b) { + locked->WaitForNotification(); // Wait for LockThenWait() to hold "s". + b->DecrementCount(); + SpinLockHolder l(spinlock); + } + + static void LockThenWait(Notification* locked, SpinLock* spinlock, + BlockingCounter* b) { + SpinLockHolder l(spinlock); + locked->Notify(); + b->Wait(); + } + + static void DeadlockTest(SpinLock* spinlock, int num_spinners) { + Notification locked; + BlockingCounter counter(num_spinners); + std::vector threads; + + threads.push_back( + std::thread(Helper::LockThenWait, &locked, spinlock, &counter)); + for (int i = 0; i < num_spinners; ++i) { + threads.push_back( + std::thread(Helper::NotifyThenLock, &locked, spinlock, &counter)); + } + + for (auto& thread : threads) { + thread.join(); + } + } + }; + + SpinLock stack_cooperative_spinlock( + base_internal::SCHEDULE_COOPERATIVE_AND_KERNEL); + SpinLock stack_noncooperative_spinlock(base_internal::SCHEDULE_KERNEL_ONLY); + Helper::DeadlockTest(&stack_cooperative_spinlock, + base_internal::NumCPUs() * 2); + Helper::DeadlockTest(&stack_noncooperative_spinlock, + base_internal::NumCPUs() * 2); + Helper::DeadlockTest(&static_cooperative_spinlock, + base_internal::NumCPUs() * 2); + Helper::DeadlockTest(&static_noncooperative_spinlock, + base_internal::NumCPUs() * 2); +} + +} // namespace +} // namespace base_internal +} // namespace absl diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/thread_annotations.h b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/thread_annotations.h new file mode 100644 index 0000000..2241ace --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/thread_annotations.h @@ -0,0 +1,267 @@ +// Copyright 2017 The Abseil Authors. +// +// 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. +// +// ----------------------------------------------------------------------------- +// File: thread_annotations.h +// ----------------------------------------------------------------------------- +// +// This header file contains macro definitions for thread safety annotations +// that allow developers to document the locking policies of multi-threaded +// code. The annotations can also help program analysis tools to identify +// potential thread safety issues. +// +// +// These annotations are implemented using compiler attributes. Using the macros +// defined here instead of raw attributes allow for portability and future +// compatibility. +// +// When referring to mutexes in the arguments of the attributes, you should +// use variable names or more complex expressions (e.g. my_object->mutex_) +// that evaluate to a concrete mutex object whenever possible. If the mutex +// you want to refer to is not in scope, you may use a member pointer +// (e.g. &MyClass::mutex_) to refer to a mutex in some (unknown) object. + +#ifndef ABSL_BASE_THREAD_ANNOTATIONS_H_ +#define ABSL_BASE_THREAD_ANNOTATIONS_H_ +#if defined(__clang__) +#define THREAD_ANNOTATION_ATTRIBUTE__(x) __attribute__((x)) +#else +#define THREAD_ANNOTATION_ATTRIBUTE__(x) // no-op +#endif + +// GUARDED_BY() +// +// Documents if a shared field or global variable needs to be protected by a +// mutex. GUARDED_BY() allows the user to specify a particular mutex that +// should be held when accessing the annotated variable. +// +// Although this annotation (and PT_GUARDED_BY, below) cannot be applied to +// local variables, a local variable and its associated mutex can often be +// combined into a small class or struct, thereby allowing the annotation. +// +// Example: +// +// class Foo { +// Mutex mu_; +// int p1_ GUARDED_BY(mu_); +// ... +// }; +#define GUARDED_BY(x) THREAD_ANNOTATION_ATTRIBUTE__(guarded_by(x)) + +// PT_GUARDED_BY() +// +// Documents if the memory location pointed to by a pointer should be guarded +// by a mutex when dereferencing the pointer. +// +// Example: +// class Foo { +// Mutex mu_; +// int *p1_ PT_GUARDED_BY(mu_); +// ... +// }; +// +// Note that a pointer variable to a shared memory location could itself be a +// shared variable. +// +// Example: +// +// // `q_`, guarded by `mu1_`, points to a shared memory location that is +// // guarded by `mu2_`: +// int *q_ GUARDED_BY(mu1_) PT_GUARDED_BY(mu2_); +#define PT_GUARDED_BY(x) THREAD_ANNOTATION_ATTRIBUTE__(pt_guarded_by(x)) + +// ACQUIRED_AFTER() / ACQUIRED_BEFORE() +// +// Documents the acquisition order between locks that can be held +// simultaneously by a thread. For any two locks that need to be annotated +// to establish an acquisition order, only one of them needs the annotation. +// (i.e. You don't have to annotate both locks with both ACQUIRED_AFTER +// and ACQUIRED_BEFORE.) +// +// As with GUARDED_BY, this is only applicable to mutexes that are shared +// fields or global variables. +// +// Example: +// +// Mutex m1_; +// Mutex m2_ ACQUIRED_AFTER(m1_); +#define ACQUIRED_AFTER(...) \ + THREAD_ANNOTATION_ATTRIBUTE__(acquired_after(__VA_ARGS__)) + +#define ACQUIRED_BEFORE(...) \ + THREAD_ANNOTATION_ATTRIBUTE__(acquired_before(__VA_ARGS__)) + +// EXCLUSIVE_LOCKS_REQUIRED() / SHARED_LOCKS_REQUIRED() +// +// Documents a function that expects a mutex to be held prior to entry. +// The mutex is expected to be held both on entry to, and exit from, the +// function. +// +// An exclusive lock allows read-write access to the guarded data member(s), and +// only one thread can acquire a lock exclusively at any one time. A shared lock +// allows read-only access, and any number of threads can acquire a shared lock +// concurrently. +// +// Generally, non-const methods should be annotated with +// EXCLUSIVE_LOCKS_REQUIRED, while const methods should be annotated with +// SHARED_LOCKS_REQUIRED. +// +// Example: +// +// Mutex mu1, mu2; +// int a GUARDED_BY(mu1); +// int b GUARDED_BY(mu2); +// +// void foo() EXCLUSIVE_LOCKS_REQUIRED(mu1, mu2) { ... } +// void bar() const SHARED_LOCKS_REQUIRED(mu1, mu2) { ... } +#define EXCLUSIVE_LOCKS_REQUIRED(...) \ + THREAD_ANNOTATION_ATTRIBUTE__(exclusive_locks_required(__VA_ARGS__)) + +#define SHARED_LOCKS_REQUIRED(...) \ + THREAD_ANNOTATION_ATTRIBUTE__(shared_locks_required(__VA_ARGS__)) + +// LOCKS_EXCLUDED() +// +// Documents the locks acquired in the body of the function. These locks +// cannot be held when calling this function (as Abseil's `Mutex` locks are +// non-reentrant). +#define LOCKS_EXCLUDED(...) \ + THREAD_ANNOTATION_ATTRIBUTE__(locks_excluded(__VA_ARGS__)) + +// LOCK_RETURNED() +// +// Documents a function that returns a mutex without acquiring it. For example, +// a public getter method that returns a pointer to a private mutex should +// be annotated with LOCK_RETURNED. +#define LOCK_RETURNED(x) \ + THREAD_ANNOTATION_ATTRIBUTE__(lock_returned(x)) + +// LOCKABLE +// +// Documents if a class/type is a lockable type (such as the `Mutex` class). +#define LOCKABLE \ + THREAD_ANNOTATION_ATTRIBUTE__(lockable) + +// SCOPED_LOCKABLE +// +// Documents if a class does RAII locking (such as the `MutexLock` class). +// The constructor should use `LOCK_FUNCTION()` to specify the mutex that is +// acquired, and the destructor should use `UNLOCK_FUNCTION()` with no +// arguments; the analysis will assume that the destructor unlocks whatever the +// constructor locked. +#define SCOPED_LOCKABLE \ + THREAD_ANNOTATION_ATTRIBUTE__(scoped_lockable) + +// EXCLUSIVE_LOCK_FUNCTION() +// +// Documents functions that acquire a lock in the body of a function, and do +// not release it. +#define EXCLUSIVE_LOCK_FUNCTION(...) \ + THREAD_ANNOTATION_ATTRIBUTE__(exclusive_lock_function(__VA_ARGS__)) + +// SHARED_LOCK_FUNCTION() +// +// Documents functions that acquire a shared (reader) lock in the body of a +// function, and do not release it. +#define SHARED_LOCK_FUNCTION(...) \ + THREAD_ANNOTATION_ATTRIBUTE__(shared_lock_function(__VA_ARGS__)) + +// UNLOCK_FUNCTION() +// +// Documents functions that expect a lock to be held on entry to the function, +// and release it in the body of the function. +#define UNLOCK_FUNCTION(...) \ + THREAD_ANNOTATION_ATTRIBUTE__(unlock_function(__VA_ARGS__)) + +// EXCLUSIVE_TRYLOCK_FUNCTION() / SHARED_TRYLOCK_FUNCTION() +// +// Documents functions that try to acquire a lock, and return success or failure +// (or a non-boolean value that can be interpreted as a boolean). +// The first argument should be `true` for functions that return `true` on +// success, or `false` for functions that return `false` on success. The second +// argument specifies the mutex that is locked on success. If unspecified, this +// mutex is assumed to be `this`. +#define EXCLUSIVE_TRYLOCK_FUNCTION(...) \ + THREAD_ANNOTATION_ATTRIBUTE__(exclusive_trylock_function(__VA_ARGS__)) + +#define SHARED_TRYLOCK_FUNCTION(...) \ + THREAD_ANNOTATION_ATTRIBUTE__(shared_trylock_function(__VA_ARGS__)) + +// ASSERT_EXCLUSIVE_LOCK() / ASSERT_SHARED_LOCK() +// +// Documents functions that dynamically check to see if a lock is held, and fail +// if it is not held. +#define ASSERT_EXCLUSIVE_LOCK(...) \ + THREAD_ANNOTATION_ATTRIBUTE__(assert_exclusive_lock(__VA_ARGS__)) + +#define ASSERT_SHARED_LOCK(...) \ + THREAD_ANNOTATION_ATTRIBUTE__(assert_shared_lock(__VA_ARGS__)) + +// NO_THREAD_SAFETY_ANALYSIS +// +// Turns off thread safety checking within the body of a particular function. +// This annotation is used to mark functions that are known to be correct, but +// the locking behavior is more complicated than the analyzer can handle. +#define NO_THREAD_SAFETY_ANALYSIS \ + THREAD_ANNOTATION_ATTRIBUTE__(no_thread_safety_analysis) + +//------------------------------------------------------------------------------ +// Tool-Supplied Annotations +//------------------------------------------------------------------------------ + +// TS_UNCHECKED should be placed around lock expressions that are not valid +// C++ syntax, but which are present for documentation purposes. These +// annotations will be ignored by the analysis. +#define TS_UNCHECKED(x) "" + +// TS_FIXME is used to mark lock expressions that are not valid C++ syntax. +// It is used by automated tools to mark and disable invalid expressions. +// The annotation should either be fixed, or changed to TS_UNCHECKED. +#define TS_FIXME(x) "" + +// Like NO_THREAD_SAFETY_ANALYSIS, this turns off checking within the body of +// a particular function. However, this attribute is used to mark functions +// that are incorrect and need to be fixed. It is used by automated tools to +// avoid breaking the build when the analysis is updated. +// Code owners are expected to eventually fix the routine. +#define NO_THREAD_SAFETY_ANALYSIS_FIXME NO_THREAD_SAFETY_ANALYSIS + +// Similar to NO_THREAD_SAFETY_ANALYSIS_FIXME, this macro marks a GUARDED_BY +// annotation that needs to be fixed, because it is producing thread safety +// warning. It disables the GUARDED_BY. +#define GUARDED_BY_FIXME(x) + +// Disables warnings for a single read operation. This can be used to avoid +// warnings when it is known that the read is not actually involved in a race, +// but the compiler cannot confirm that. +#define TS_UNCHECKED_READ(x) thread_safety_analysis::ts_unchecked_read(x) + + +namespace thread_safety_analysis { + +// Takes a reference to a guarded data member, and returns an unguarded +// reference. +template +inline const T& ts_unchecked_read(const T& v) NO_THREAD_SAFETY_ANALYSIS { + return v; +} + +template +inline T& ts_unchecked_read(T& v) NO_THREAD_SAFETY_ANALYSIS { + return v; +} + +} // namespace thread_safety_analysis + +#endif // ABSL_BASE_THREAD_ANNOTATIONS_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/throw_delegate_test.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/throw_delegate_test.cc new file mode 100644 index 0000000..0f15df0 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/base/throw_delegate_test.cc @@ -0,0 +1,94 @@ +// Copyright 2017 The Abseil Authors. +// +// 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 "absl/base/internal/throw_delegate.h" + +#include +#include +#include + +#include "gtest/gtest.h" + +namespace { + +using absl::base_internal::ThrowStdLogicError; +using absl::base_internal::ThrowStdInvalidArgument; +using absl::base_internal::ThrowStdDomainError; +using absl::base_internal::ThrowStdLengthError; +using absl::base_internal::ThrowStdOutOfRange; +using absl::base_internal::ThrowStdRuntimeError; +using absl::base_internal::ThrowStdRangeError; +using absl::base_internal::ThrowStdOverflowError; +using absl::base_internal::ThrowStdUnderflowError; +using absl::base_internal::ThrowStdBadFunctionCall; +using absl::base_internal::ThrowStdBadAlloc; + +constexpr const char* what_arg = "The quick brown fox jumps over the lazy dog"; + +template +void ExpectThrowChar(void (*f)(const char*)) { + try { + f(what_arg); + FAIL() << "Didn't throw"; + } catch (const E& e) { + EXPECT_STREQ(e.what(), what_arg); + } +} + +template +void ExpectThrowString(void (*f)(const std::string&)) { + try { + f(what_arg); + FAIL() << "Didn't throw"; + } catch (const E& e) { + EXPECT_STREQ(e.what(), what_arg); + } +} + +template +void ExpectThrowNoWhat(void (*f)()) { + try { + f(); + FAIL() << "Didn't throw"; + } catch (const E& e) { + } +} + +TEST(ThrowHelper, Test) { + // Not using EXPECT_THROW because we want to check the .what() message too. + ExpectThrowChar(ThrowStdLogicError); + ExpectThrowChar(ThrowStdInvalidArgument); + ExpectThrowChar(ThrowStdDomainError); + ExpectThrowChar(ThrowStdLengthError); + ExpectThrowChar(ThrowStdOutOfRange); + ExpectThrowChar(ThrowStdRuntimeError); + ExpectThrowChar(ThrowStdRangeError); + ExpectThrowChar(ThrowStdOverflowError); + ExpectThrowChar(ThrowStdUnderflowError); + + ExpectThrowString(ThrowStdLogicError); + ExpectThrowString(ThrowStdInvalidArgument); + ExpectThrowString(ThrowStdDomainError); + ExpectThrowString(ThrowStdLengthError); + ExpectThrowString(ThrowStdOutOfRange); + ExpectThrowString(ThrowStdRuntimeError); + ExpectThrowString(ThrowStdRangeError); + ExpectThrowString(ThrowStdOverflowError); + ExpectThrowString(ThrowStdUnderflowError); + + ExpectThrowNoWhat(ThrowStdBadFunctionCall); + ExpectThrowNoWhat(ThrowStdBadAlloc); +} + +} // namespace diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/compiler_config_setting.bzl b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/compiler_config_setting.bzl new file mode 100644 index 0000000..b77c4f5 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/compiler_config_setting.bzl @@ -0,0 +1,39 @@ +# +# Copyright 2018 The Abseil Authors. +# +# 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. +# + +"""Creates config_setting that allows selecting based on 'compiler' value.""" + +def create_llvm_config(name, visibility): + # The "do_not_use_tools_cpp_compiler_present" attribute exists to + # distinguish between older versions of Bazel that do not support + # "@bazel_tools//tools/cpp:compiler" flag_value, and newer ones that do. + # In the future, the only way to select on the compiler will be through + # flag_values{"@bazel_tools//tools/cpp:compiler"} and the else branch can + # be removed. + if hasattr(cc_common, "do_not_use_tools_cpp_compiler_present"): + native.config_setting( + name = name, + flag_values = { + "@bazel_tools//tools/cpp:compiler": "llvm", + }, + visibility = visibility, + ) + else: + native.config_setting( + name = name, + values = {"compiler": "llvm"}, + visibility = visibility, + ) diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/BUILD.bazel b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/BUILD.bazel new file mode 100644 index 0000000..d75f891 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/BUILD.bazel @@ -0,0 +1,646 @@ +# +# Copyright 2017 The Abseil Authors. +# +# 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. +# + +load( + "//absl:copts.bzl", + "ABSL_DEFAULT_COPTS", + "ABSL_TEST_COPTS", + "ABSL_EXCEPTIONS_FLAG", + "ABSL_EXCEPTIONS_FLAG_LINKOPTS", +) + +package(default_visibility = ["//visibility:public"]) + +licenses(["notice"]) # Apache 2.0 + +cc_library( + name = "compressed_tuple", + hdrs = ["internal/compressed_tuple.h"], + copts = ABSL_DEFAULT_COPTS, + deps = [ + "//absl/utility", + ], +) + +cc_test( + name = "compressed_tuple_test", + srcs = ["internal/compressed_tuple_test.cc"], + copts = ABSL_TEST_COPTS, + deps = [ + ":compressed_tuple", + "@com_google_googletest//:gtest_main", + ], +) + +cc_library( + name = "fixed_array", + hdrs = ["fixed_array.h"], + copts = ABSL_DEFAULT_COPTS, + deps = [ + ":compressed_tuple", + "//absl/algorithm", + "//absl/base:core_headers", + "//absl/base:dynamic_annotations", + "//absl/base:throw_delegate", + "//absl/memory", + ], +) + +cc_test( + name = "fixed_array_test", + srcs = ["fixed_array_test.cc"], + copts = ABSL_TEST_COPTS + ABSL_EXCEPTIONS_FLAG, + linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS, + deps = [ + ":fixed_array", + "//absl/base:exception_testing", + "//absl/hash:hash_testing", + "//absl/memory", + "@com_google_googletest//:gtest_main", + ], +) + +cc_test( + name = "fixed_array_test_noexceptions", + srcs = ["fixed_array_test.cc"], + copts = ABSL_TEST_COPTS, + deps = [ + ":fixed_array", + "//absl/base:exception_testing", + "//absl/hash:hash_testing", + "//absl/memory", + "@com_google_googletest//:gtest_main", + ], +) + +cc_test( + name = "fixed_array_exception_safety_test", + srcs = ["fixed_array_exception_safety_test.cc"], + copts = ABSL_TEST_COPTS + ABSL_EXCEPTIONS_FLAG, + linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS, + deps = [ + ":fixed_array", + "//absl/base:exception_safety_testing", + "@com_google_googletest//:gtest_main", + ], +) + +cc_test( + name = "fixed_array_benchmark", + srcs = ["fixed_array_benchmark.cc"], + copts = ABSL_TEST_COPTS + ["$(STACK_FRAME_UNLIMITED)"], + tags = ["benchmark"], + deps = [ + ":fixed_array", + "@com_github_google_benchmark//:benchmark_main", + ], +) + +cc_library( + name = "inlined_vector", + hdrs = ["inlined_vector.h"], + copts = ABSL_DEFAULT_COPTS, + deps = [ + "//absl/algorithm", + "//absl/base:core_headers", + "//absl/base:throw_delegate", + "//absl/memory", + ], +) + +cc_test( + name = "inlined_vector_test", + srcs = ["inlined_vector_test.cc"], + copts = ABSL_TEST_COPTS + ABSL_EXCEPTIONS_FLAG, + linkopts = ABSL_EXCEPTIONS_FLAG_LINKOPTS, + deps = [ + ":inlined_vector", + ":test_instance_tracker", + "//absl/base", + "//absl/base:core_headers", + "//absl/base:exception_testing", + "//absl/hash:hash_testing", + "//absl/memory", + "//absl/strings", + "@com_google_googletest//:gtest_main", + ], +) + +cc_test( + name = "inlined_vector_test_noexceptions", + srcs = ["inlined_vector_test.cc"], + copts = ABSL_TEST_COPTS, + deps = [ + ":inlined_vector", + ":test_instance_tracker", + "//absl/base", + "//absl/base:core_headers", + "//absl/base:exception_testing", + "//absl/hash:hash_testing", + "//absl/memory", + "//absl/strings", + "@com_google_googletest//:gtest_main", + ], +) + +cc_test( + name = "inlined_vector_benchmark", + srcs = ["inlined_vector_benchmark.cc"], + copts = ABSL_TEST_COPTS, + tags = ["benchmark"], + deps = [ + ":inlined_vector", + "//absl/base", + "//absl/strings", + "@com_github_google_benchmark//:benchmark_main", + ], +) + +cc_library( + name = "test_instance_tracker", + testonly = 1, + srcs = ["internal/test_instance_tracker.cc"], + hdrs = ["internal/test_instance_tracker.h"], + copts = ABSL_DEFAULT_COPTS, + visibility = [ + "//absl:__subpackages__", + ], +) + +cc_test( + name = "test_instance_tracker_test", + srcs = ["internal/test_instance_tracker_test.cc"], + copts = ABSL_TEST_COPTS, + deps = [ + ":test_instance_tracker", + "@com_google_googletest//:gtest_main", + ], +) + +NOTEST_TAGS_NONMOBILE = [ + "no_test_darwin_x86_64", + "no_test_loonix", +] + +NOTEST_TAGS_MOBILE = [ + "no_test_android_arm", + "no_test_android_arm64", + "no_test_android_x86", + "no_test_ios_x86_64", +] + +NOTEST_TAGS = NOTEST_TAGS_MOBILE + NOTEST_TAGS_NONMOBILE + +cc_library( + name = "flat_hash_map", + hdrs = ["flat_hash_map.h"], + copts = ABSL_DEFAULT_COPTS, + deps = [ + ":container_memory", + ":hash_function_defaults", + ":raw_hash_map", + "//absl/memory", + ], +) + +cc_test( + name = "flat_hash_map_test", + srcs = ["flat_hash_map_test.cc"], + copts = ABSL_TEST_COPTS + ["-DUNORDERED_MAP_CXX17"], + tags = NOTEST_TAGS_NONMOBILE, + deps = [ + ":flat_hash_map", + ":hash_generator_testing", + ":unordered_map_constructor_test", + ":unordered_map_lookup_test", + ":unordered_map_modifiers_test", + "//absl/types:any", + "@com_google_googletest//:gtest_main", + ], +) + +cc_library( + name = "flat_hash_set", + hdrs = ["flat_hash_set.h"], + copts = ABSL_DEFAULT_COPTS, + deps = [ + ":container_memory", + ":hash_function_defaults", + ":raw_hash_set", + "//absl/base:core_headers", + "//absl/memory", + ], +) + +cc_test( + name = "flat_hash_set_test", + srcs = ["flat_hash_set_test.cc"], + copts = ABSL_TEST_COPTS + ["-DUNORDERED_SET_CXX17"], + tags = NOTEST_TAGS_NONMOBILE, + deps = [ + ":flat_hash_set", + ":hash_generator_testing", + ":unordered_set_constructor_test", + ":unordered_set_lookup_test", + ":unordered_set_modifiers_test", + "//absl/memory", + "//absl/strings", + "@com_google_googletest//:gtest_main", + ], +) + +cc_library( + name = "node_hash_map", + hdrs = ["node_hash_map.h"], + copts = ABSL_DEFAULT_COPTS, + deps = [ + ":container_memory", + ":hash_function_defaults", + ":node_hash_policy", + ":raw_hash_map", + "//absl/memory", + ], +) + +cc_test( + name = "node_hash_map_test", + srcs = ["node_hash_map_test.cc"], + copts = ABSL_TEST_COPTS + ["-DUNORDERED_MAP_CXX17"], + tags = NOTEST_TAGS_NONMOBILE, + deps = [ + ":hash_generator_testing", + ":node_hash_map", + ":tracked", + ":unordered_map_constructor_test", + ":unordered_map_lookup_test", + ":unordered_map_modifiers_test", + "@com_google_googletest//:gtest_main", + ], +) + +cc_library( + name = "node_hash_set", + hdrs = ["node_hash_set.h"], + copts = ABSL_DEFAULT_COPTS, + deps = [ + ":hash_function_defaults", + ":node_hash_policy", + ":raw_hash_set", + "//absl/memory", + ], +) + +cc_test( + name = "node_hash_set_test", + srcs = ["node_hash_set_test.cc"], + copts = ABSL_TEST_COPTS + ["-DUNORDERED_SET_CXX17"], + tags = NOTEST_TAGS_NONMOBILE, + deps = [ + ":hash_generator_testing", + ":node_hash_set", + ":unordered_set_constructor_test", + ":unordered_set_lookup_test", + ":unordered_set_modifiers_test", + "@com_google_googletest//:gtest_main", + ], +) + +cc_library( + name = "container_memory", + hdrs = ["internal/container_memory.h"], + copts = ABSL_DEFAULT_COPTS, + deps = [ + "//absl/memory", + "//absl/utility", + ], +) + +cc_test( + name = "container_memory_test", + srcs = ["internal/container_memory_test.cc"], + copts = ABSL_TEST_COPTS, + tags = NOTEST_TAGS_NONMOBILE, + deps = [ + ":container_memory", + "//absl/strings", + "@com_google_googletest//:gtest_main", + ], +) + +cc_library( + name = "hash_function_defaults", + hdrs = ["internal/hash_function_defaults.h"], + copts = ABSL_DEFAULT_COPTS, + deps = [ + "//absl/base:config", + "//absl/hash", + "//absl/strings", + ], +) + +cc_test( + name = "hash_function_defaults_test", + srcs = ["internal/hash_function_defaults_test.cc"], + copts = ABSL_TEST_COPTS, + tags = NOTEST_TAGS, + deps = [ + ":hash_function_defaults", + "//absl/hash", + "//absl/strings", + "@com_google_googletest//:gtest_main", + ], +) + +cc_library( + name = "hash_generator_testing", + testonly = 1, + srcs = ["internal/hash_generator_testing.cc"], + hdrs = ["internal/hash_generator_testing.h"], + copts = ABSL_TEST_COPTS, + deps = [ + ":hash_policy_testing", + "//absl/meta:type_traits", + "//absl/strings", + ], +) + +cc_library( + name = "hash_policy_testing", + testonly = 1, + hdrs = ["internal/hash_policy_testing.h"], + copts = ABSL_TEST_COPTS, + deps = [ + "//absl/hash", + "//absl/strings", + ], +) + +cc_test( + name = "hash_policy_testing_test", + srcs = ["internal/hash_policy_testing_test.cc"], + copts = ABSL_TEST_COPTS, + deps = [ + ":hash_policy_testing", + "@com_google_googletest//:gtest_main", + ], +) + +cc_library( + name = "hash_policy_traits", + hdrs = ["internal/hash_policy_traits.h"], + copts = ABSL_DEFAULT_COPTS, + deps = ["//absl/meta:type_traits"], +) + +cc_test( + name = "hash_policy_traits_test", + srcs = ["internal/hash_policy_traits_test.cc"], + copts = ABSL_TEST_COPTS, + deps = [ + ":hash_policy_traits", + "@com_google_googletest//:gtest_main", + ], +) + +cc_library( + name = "hashtable_debug", + hdrs = ["internal/hashtable_debug.h"], + copts = ABSL_DEFAULT_COPTS, + deps = [ + ":hashtable_debug_hooks", + ], +) + +cc_library( + name = "hashtable_debug_hooks", + hdrs = ["internal/hashtable_debug_hooks.h"], + copts = ABSL_DEFAULT_COPTS, +) + +cc_library( + name = "node_hash_policy", + hdrs = ["internal/node_hash_policy.h"], + copts = ABSL_DEFAULT_COPTS, +) + +cc_test( + name = "node_hash_policy_test", + srcs = ["internal/node_hash_policy_test.cc"], + copts = ABSL_TEST_COPTS, + deps = [ + ":hash_policy_traits", + ":node_hash_policy", + "@com_google_googletest//:gtest_main", + ], +) + +cc_library( + name = "raw_hash_map", + hdrs = ["internal/raw_hash_map.h"], + copts = ABSL_DEFAULT_COPTS, + deps = [ + ":container_memory", + ":raw_hash_set", + ], +) + +cc_library( + name = "raw_hash_set", + srcs = ["internal/raw_hash_set.cc"], + hdrs = ["internal/raw_hash_set.h"], + copts = ABSL_DEFAULT_COPTS, + deps = [ + ":compressed_tuple", + ":container_memory", + ":hash_policy_traits", + ":hashtable_debug_hooks", + ":layout", + "//absl/base:bits", + "//absl/base:config", + "//absl/base:core_headers", + "//absl/base:endian", + "//absl/memory", + "//absl/meta:type_traits", + "//absl/types:optional", + "//absl/utility", + ], +) + +cc_test( + name = "raw_hash_set_test", + srcs = ["internal/raw_hash_set_test.cc"], + copts = ABSL_TEST_COPTS, + linkstatic = 1, + tags = NOTEST_TAGS, + deps = [ + ":container_memory", + ":hash_function_defaults", + ":hash_policy_testing", + ":hashtable_debug", + ":raw_hash_set", + "//absl/base", + "//absl/base:core_headers", + "//absl/strings", + "@com_google_googletest//:gtest_main", + ], +) + +cc_test( + name = "raw_hash_set_allocator_test", + size = "small", + srcs = ["internal/raw_hash_set_allocator_test.cc"], + copts = ABSL_TEST_COPTS, + deps = [ + ":raw_hash_set", + ":tracked", + "//absl/base:core_headers", + "@com_google_googletest//:gtest_main", + ], +) + +cc_library( + name = "layout", + hdrs = ["internal/layout.h"], + copts = ABSL_DEFAULT_COPTS, + deps = [ + "//absl/base:core_headers", + "//absl/meta:type_traits", + "//absl/strings", + "//absl/types:span", + "//absl/utility", + ], +) + +cc_test( + name = "layout_test", + size = "small", + srcs = ["internal/layout_test.cc"], + copts = ABSL_TEST_COPTS, + tags = NOTEST_TAGS, + visibility = ["//visibility:private"], + deps = [ + ":layout", + "//absl/base", + "//absl/base:core_headers", + "//absl/types:span", + "@com_google_googletest//:gtest_main", + ], +) + +cc_library( + name = "tracked", + testonly = 1, + hdrs = ["internal/tracked.h"], + copts = ABSL_TEST_COPTS, +) + +cc_library( + name = "unordered_map_constructor_test", + testonly = 1, + hdrs = ["internal/unordered_map_constructor_test.h"], + copts = ABSL_TEST_COPTS, + deps = [ + ":hash_generator_testing", + ":hash_policy_testing", + "@com_google_googletest//:gtest", + ], +) + +cc_library( + name = "unordered_map_lookup_test", + testonly = 1, + hdrs = ["internal/unordered_map_lookup_test.h"], + copts = ABSL_TEST_COPTS, + deps = [ + ":hash_generator_testing", + ":hash_policy_testing", + "@com_google_googletest//:gtest", + ], +) + +cc_library( + name = "unordered_map_modifiers_test", + testonly = 1, + hdrs = ["internal/unordered_map_modifiers_test.h"], + copts = ABSL_TEST_COPTS, + deps = [ + ":hash_generator_testing", + ":hash_policy_testing", + "@com_google_googletest//:gtest", + ], +) + +cc_library( + name = "unordered_set_constructor_test", + testonly = 1, + hdrs = ["internal/unordered_set_constructor_test.h"], + copts = ABSL_TEST_COPTS, + deps = [ + ":hash_generator_testing", + ":hash_policy_testing", + "@com_google_googletest//:gtest", + ], +) + +cc_library( + name = "unordered_set_lookup_test", + testonly = 1, + hdrs = ["internal/unordered_set_lookup_test.h"], + copts = ABSL_TEST_COPTS, + deps = [ + ":hash_generator_testing", + ":hash_policy_testing", + "@com_google_googletest//:gtest", + ], +) + +cc_library( + name = "unordered_set_modifiers_test", + testonly = 1, + hdrs = ["internal/unordered_set_modifiers_test.h"], + copts = ABSL_TEST_COPTS, + deps = [ + ":hash_generator_testing", + ":hash_policy_testing", + "@com_google_googletest//:gtest", + ], +) + +cc_test( + name = "unordered_set_test", + srcs = ["internal/unordered_set_test.cc"], + copts = ABSL_TEST_COPTS, + tags = NOTEST_TAGS_NONMOBILE, + deps = [ + ":unordered_set_constructor_test", + ":unordered_set_lookup_test", + ":unordered_set_modifiers_test", + "@com_google_googletest//:gtest_main", + ], +) + +cc_test( + name = "unordered_map_test", + srcs = ["internal/unordered_map_test.cc"], + copts = ABSL_TEST_COPTS, + tags = NOTEST_TAGS_NONMOBILE, + deps = [ + ":unordered_map_constructor_test", + ":unordered_map_lookup_test", + ":unordered_map_modifiers_test", + "@com_google_googletest//:gtest_main", + ], +) diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/CMakeLists.txt b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/CMakeLists.txt new file mode 100644 index 0000000..72113e1 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/CMakeLists.txt @@ -0,0 +1,177 @@ +# +# Copyright 2017 The Abseil Authors. +# +# 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. +# + + +list(APPEND CONTAINER_PUBLIC_HEADERS + "fixed_array.h" + "flat_hash_map.h" + "flat_hash_set.h" + "inlined_vector.h" + "node_hash_map.h" + "node_hash_set.h" +) + + +list(APPEND CONTAINER_INTERNAL_HEADERS + "internal/compressed_tuple.h" + "internal/container_memory.h" + "internal/hash_function_defaults.h" + "internal/hash_generator_testing.h" + "internal/hash_policy_testing.h" + "internal/hash_policy_traits.h" + "internal/hashtable_debug.h" + "internal/layout.h" + "internal/node_hash_policy.h" + "internal/raw_hash_map.h" + "internal/raw_hash_set.h" + "internal/test_instance_tracker.h" + "internal/tracked.h" + "internal/unordered_map_constructor_test.h" + "internal/unordered_map_lookup_test.h" + "internal/unordered_map_modifiers_test.h" + "internal/unordered_set_constructor_test.h" + "internal/unordered_set_lookup_test.h" + "internal/unordered_set_modifiers_test.h" +) + + +absl_library( + TARGET + absl_container + SOURCES + "internal/raw_hash_set.cc" + EXPORT_NAME + container +) + +# +## TESTS +# + +list(APPEND TEST_INSTANCE_TRACKER_LIB_SRC + "internal/test_instance_tracker.cc" + ${CONTAINER_PUBLIC_HEADERS} + ${CONTAINER_INTERNAL_HEADERS} +) + + +absl_library( + TARGET + test_instance_tracker_lib + SOURCES + ${TEST_INSTANCE_TRACKER_LIB_SRC} + PUBLIC_LIBRARIES + absl::container +) + + + +# test fixed_array_test +set(FIXED_ARRAY_TEST_SRC "fixed_array_test.cc") +set(FIXED_ARRAY_TEST_PUBLIC_LIBRARIES absl::base absl_internal_throw_delegate test_instance_tracker_lib) + +absl_test( + TARGET + fixed_array_test + SOURCES + ${FIXED_ARRAY_TEST_SRC} + PUBLIC_LIBRARIES + ${FIXED_ARRAY_TEST_PUBLIC_LIBRARIES} + PRIVATE_COMPILE_FLAGS + ${ABSL_EXCEPTIONS_FLAG} +) + + + +absl_test( + TARGET + fixed_array_test_noexceptions + SOURCES + ${FIXED_ARRAY_TEST_SRC} + PUBLIC_LIBRARIES + ${FIXED_ARRAY_TEST_PUBLIC_LIBRARIES} +) + + +# test fixed_array_exception_safety_test +set(FIXED_ARRAY_EXCEPTION_SAFETY_TEST_SRC "fixed_array_exception_safety_test.cc") +set(FIXED_ARRAY_EXCEPTION_SAFETY_TEST_PUBLIC_LIBRARIES + absl::container + absl_internal_exception_safety_testing +) + +absl_test( + TARGET + fixed_array_exception_safety_test + SOURCES + ${FIXED_ARRAY_EXCEPTION_SAFETY_TEST_SRC} + PUBLIC_LIBRARIES + ${FIXED_ARRAY_EXCEPTION_SAFETY_TEST_PUBLIC_LIBRARIES} + PRIVATE_COMPILE_FLAGS + ${ABSL_EXCEPTIONS_FLAG} +) + + +# test inlined_vector_test +set(INLINED_VECTOR_TEST_SRC "inlined_vector_test.cc") +set(INLINED_VECTOR_TEST_PUBLIC_LIBRARIES absl::base absl_internal_throw_delegate test_instance_tracker_lib) + +absl_test( + TARGET + inlined_vector_test + SOURCES + ${INLINED_VECTOR_TEST_SRC} + PUBLIC_LIBRARIES + ${INLINED_VECTOR_TEST_PUBLIC_LIBRARIES} +) + +absl_test( + TARGET + inlined_vector_test_noexceptions + SOURCES + ${INLINED_VECTOR_TEST_SRC} + PUBLIC_LIBRARIES + ${INLINED_VECTOR_TEST_PUBLIC_LIBRARIES} + PRIVATE_COMPILE_FLAGS + ${ABSL_NOEXCEPTION_CXXFLAGS} +) + + +# test test_instance_tracker_test +set(TEST_INSTANCE_TRACKER_TEST_SRC "internal/test_instance_tracker_test.cc") +set(TEST_INSTANCE_TRACKER_TEST_PUBLIC_LIBRARIES absl::base absl_internal_throw_delegate test_instance_tracker_lib) + + +absl_test( + TARGET + test_instance_tracker_test + SOURCES + ${TEST_INSTANCE_TRACKER_TEST_SRC} + PUBLIC_LIBRARIES + ${TEST_INSTANCE_TRACKER_TEST_PUBLIC_LIBRARIES} +) + +absl_test( + TARGET + raw_hash_set_test + SOURCES + "internal/raw_hash_set_test.cc" + PUBLIC_LIBRARIES + absl::base + absl::hash + absl_internal_throw_delegate + test_instance_tracker_lib +) diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/fixed_array.h b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/fixed_array.h new file mode 100644 index 0000000..6da8441 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/fixed_array.h @@ -0,0 +1,518 @@ +// Copyright 2018 The Abseil Authors. +// +// 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. +// +// ----------------------------------------------------------------------------- +// File: fixed_array.h +// ----------------------------------------------------------------------------- +// +// A `FixedArray` represents a non-resizable array of `T` where the length of +// the array can be determined at run-time. It is a good replacement for +// non-standard and deprecated uses of `alloca()` and variable length arrays +// within the GCC extension. (See +// https://gcc.gnu.org/onlinedocs/gcc/Variable-Length.html). +// +// `FixedArray` allocates small arrays inline, keeping performance fast by +// avoiding heap operations. It also helps reduce the chances of +// accidentally overflowing your stack if large input is passed to +// your function. + +#ifndef ABSL_CONTAINER_FIXED_ARRAY_H_ +#define ABSL_CONTAINER_FIXED_ARRAY_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "absl/algorithm/algorithm.h" +#include "absl/base/dynamic_annotations.h" +#include "absl/base/internal/throw_delegate.h" +#include "absl/base/macros.h" +#include "absl/base/optimization.h" +#include "absl/base/port.h" +#include "absl/container/internal/compressed_tuple.h" +#include "absl/memory/memory.h" + +namespace absl { + +constexpr static auto kFixedArrayUseDefault = static_cast(-1); + +// ----------------------------------------------------------------------------- +// FixedArray +// ----------------------------------------------------------------------------- +// +// A `FixedArray` provides a run-time fixed-size array, allocating a small array +// inline for efficiency. +// +// Most users should not specify an `inline_elements` argument and let +// `FixedArray` automatically determine the number of elements +// to store inline based on `sizeof(T)`. If `inline_elements` is specified, the +// `FixedArray` implementation will use inline storage for arrays with a +// length <= `inline_elements`. +// +// Note that a `FixedArray` constructed with a `size_type` argument will +// default-initialize its values by leaving trivially constructible types +// uninitialized (e.g. int, int[4], double), and others default-constructed. +// This matches the behavior of c-style arrays and `std::array`, but not +// `std::vector`. +// +// Note that `FixedArray` does not provide a public allocator; if it requires a +// heap allocation, it will do so with global `::operator new[]()` and +// `::operator delete[]()`, even if T provides class-scope overrides for these +// operators. +template > +class FixedArray { + static_assert(!std::is_array::value || std::extent::value > 0, + "Arrays with unknown bounds cannot be used with FixedArray."); + + static constexpr size_t kInlineBytesDefault = 256; + + using AllocatorTraits = std::allocator_traits; + // std::iterator_traits isn't guaranteed to be SFINAE-friendly until C++17, + // but this seems to be mostly pedantic. + template + using EnableIfForwardIterator = absl::enable_if_t::iterator_category, + std::forward_iterator_tag>::value>; + static constexpr bool NoexceptCopyable() { + return std::is_nothrow_copy_constructible::value && + absl::allocator_is_nothrow::value; + } + static constexpr bool NoexceptMovable() { + return std::is_nothrow_move_constructible::value && + absl::allocator_is_nothrow::value; + } + static constexpr bool DefaultConstructorIsNonTrivial() { + return !absl::is_trivially_default_constructible::value; + } + + public: + using allocator_type = typename AllocatorTraits::allocator_type; + using value_type = typename allocator_type::value_type; + using pointer = typename allocator_type::pointer; + using const_pointer = typename allocator_type::const_pointer; + using reference = typename allocator_type::reference; + using const_reference = typename allocator_type::const_reference; + using size_type = typename allocator_type::size_type; + using difference_type = typename allocator_type::difference_type; + using iterator = pointer; + using const_iterator = const_pointer; + using reverse_iterator = std::reverse_iterator; + using const_reverse_iterator = std::reverse_iterator; + + static constexpr size_type inline_elements = + (N == kFixedArrayUseDefault ? kInlineBytesDefault / sizeof(value_type) + : static_cast(N)); + + FixedArray( + const FixedArray& other, + const allocator_type& a = allocator_type()) noexcept(NoexceptCopyable()) + : FixedArray(other.begin(), other.end(), a) {} + + FixedArray( + FixedArray&& other, + const allocator_type& a = allocator_type()) noexcept(NoexceptMovable()) + : FixedArray(std::make_move_iterator(other.begin()), + std::make_move_iterator(other.end()), a) {} + + // Creates an array object that can store `n` elements. + // Note that trivially constructible elements will be uninitialized. + explicit FixedArray(size_type n, const allocator_type& a = allocator_type()) + : storage_(n, a) { + if (DefaultConstructorIsNonTrivial()) { + memory_internal::ConstructRange(storage_.alloc(), storage_.begin(), + storage_.end()); + } + } + + // Creates an array initialized with `n` copies of `val`. + FixedArray(size_type n, const value_type& val, + const allocator_type& a = allocator_type()) + : storage_(n, a) { + memory_internal::ConstructRange(storage_.alloc(), storage_.begin(), + storage_.end(), val); + } + + // Creates an array initialized with the size and contents of `init_list`. + FixedArray(std::initializer_list init_list, + const allocator_type& a = allocator_type()) + : FixedArray(init_list.begin(), init_list.end(), a) {} + + // Creates an array initialized with the elements from the input + // range. The array's size will always be `std::distance(first, last)`. + // REQUIRES: Iterator must be a forward_iterator or better. + template * = nullptr> + FixedArray(Iterator first, Iterator last, + const allocator_type& a = allocator_type()) + : storage_(std::distance(first, last), a) { + memory_internal::CopyRange(storage_.alloc(), storage_.begin(), first, last); + } + + ~FixedArray() noexcept { + for (auto* cur = storage_.begin(); cur != storage_.end(); ++cur) { + AllocatorTraits::destroy(storage_.alloc(), cur); + } + } + + // Assignments are deleted because they break the invariant that the size of a + // `FixedArray` never changes. + void operator=(FixedArray&&) = delete; + void operator=(const FixedArray&) = delete; + + // FixedArray::size() + // + // Returns the length of the fixed array. + size_type size() const { return storage_.size(); } + + // FixedArray::max_size() + // + // Returns the largest possible value of `std::distance(begin(), end())` for a + // `FixedArray`. This is equivalent to the most possible addressable bytes + // over the number of bytes taken by T. + constexpr size_type max_size() const { + return (std::numeric_limits::max)() / sizeof(value_type); + } + + // FixedArray::empty() + // + // Returns whether or not the fixed array is empty. + bool empty() const { return size() == 0; } + + // FixedArray::memsize() + // + // Returns the memory size of the fixed array in bytes. + size_t memsize() const { return size() * sizeof(value_type); } + + // FixedArray::data() + // + // Returns a const T* pointer to elements of the `FixedArray`. This pointer + // can be used to access (but not modify) the contained elements. + const_pointer data() const { return AsValueType(storage_.begin()); } + + // Overload of FixedArray::data() to return a T* pointer to elements of the + // fixed array. This pointer can be used to access and modify the contained + // elements. + pointer data() { return AsValueType(storage_.begin()); } + + // FixedArray::operator[] + // + // Returns a reference the ith element of the fixed array. + // REQUIRES: 0 <= i < size() + reference operator[](size_type i) { + assert(i < size()); + return data()[i]; + } + + // Overload of FixedArray::operator()[] to return a const reference to the + // ith element of the fixed array. + // REQUIRES: 0 <= i < size() + const_reference operator[](size_type i) const { + assert(i < size()); + return data()[i]; + } + + // FixedArray::at + // + // Bounds-checked access. Returns a reference to the ith element of the + // fiexed array, or throws std::out_of_range + reference at(size_type i) { + if (ABSL_PREDICT_FALSE(i >= size())) { + base_internal::ThrowStdOutOfRange("FixedArray::at failed bounds check"); + } + return data()[i]; + } + + // Overload of FixedArray::at() to return a const reference to the ith element + // of the fixed array. + const_reference at(size_type i) const { + if (ABSL_PREDICT_FALSE(i >= size())) { + base_internal::ThrowStdOutOfRange("FixedArray::at failed bounds check"); + } + return data()[i]; + } + + // FixedArray::front() + // + // Returns a reference to the first element of the fixed array. + reference front() { return *begin(); } + + // Overload of FixedArray::front() to return a reference to the first element + // of a fixed array of const values. + const_reference front() const { return *begin(); } + + // FixedArray::back() + // + // Returns a reference to the last element of the fixed array. + reference back() { return *(end() - 1); } + + // Overload of FixedArray::back() to return a reference to the last element + // of a fixed array of const values. + const_reference back() const { return *(end() - 1); } + + // FixedArray::begin() + // + // Returns an iterator to the beginning of the fixed array. + iterator begin() { return data(); } + + // Overload of FixedArray::begin() to return a const iterator to the + // beginning of the fixed array. + const_iterator begin() const { return data(); } + + // FixedArray::cbegin() + // + // Returns a const iterator to the beginning of the fixed array. + const_iterator cbegin() const { return begin(); } + + // FixedArray::end() + // + // Returns an iterator to the end of the fixed array. + iterator end() { return data() + size(); } + + // Overload of FixedArray::end() to return a const iterator to the end of the + // fixed array. + const_iterator end() const { return data() + size(); } + + // FixedArray::cend() + // + // Returns a const iterator to the end of the fixed array. + const_iterator cend() const { return end(); } + + // FixedArray::rbegin() + // + // Returns a reverse iterator from the end of the fixed array. + reverse_iterator rbegin() { return reverse_iterator(end()); } + + // Overload of FixedArray::rbegin() to return a const reverse iterator from + // the end of the fixed array. + const_reverse_iterator rbegin() const { + return const_reverse_iterator(end()); + } + + // FixedArray::crbegin() + // + // Returns a const reverse iterator from the end of the fixed array. + const_reverse_iterator crbegin() const { return rbegin(); } + + // FixedArray::rend() + // + // Returns a reverse iterator from the beginning of the fixed array. + reverse_iterator rend() { return reverse_iterator(begin()); } + + // Overload of FixedArray::rend() for returning a const reverse iterator + // from the beginning of the fixed array. + const_reverse_iterator rend() const { + return const_reverse_iterator(begin()); + } + + // FixedArray::crend() + // + // Returns a reverse iterator from the beginning of the fixed array. + const_reverse_iterator crend() const { return rend(); } + + // FixedArray::fill() + // + // Assigns the given `value` to all elements in the fixed array. + void fill(const value_type& val) { std::fill(begin(), end(), val); } + + // Relational operators. Equality operators are elementwise using + // `operator==`, while order operators order FixedArrays lexicographically. + friend bool operator==(const FixedArray& lhs, const FixedArray& rhs) { + return absl::equal(lhs.begin(), lhs.end(), rhs.begin(), rhs.end()); + } + + friend bool operator!=(const FixedArray& lhs, const FixedArray& rhs) { + return !(lhs == rhs); + } + + friend bool operator<(const FixedArray& lhs, const FixedArray& rhs) { + return std::lexicographical_compare(lhs.begin(), lhs.end(), rhs.begin(), + rhs.end()); + } + + friend bool operator>(const FixedArray& lhs, const FixedArray& rhs) { + return rhs < lhs; + } + + friend bool operator<=(const FixedArray& lhs, const FixedArray& rhs) { + return !(rhs < lhs); + } + + friend bool operator>=(const FixedArray& lhs, const FixedArray& rhs) { + return !(lhs < rhs); + } + + template + friend H AbslHashValue(H h, const FixedArray& v) { + return H::combine(H::combine_contiguous(std::move(h), v.data(), v.size()), + v.size()); + } + + private: + // StorageElement + // + // For FixedArrays with a C-style-array value_type, StorageElement is a POD + // wrapper struct called StorageElementWrapper that holds the value_type + // instance inside. This is needed for construction and destruction of the + // entire array regardless of how many dimensions it has. For all other cases, + // StorageElement is just an alias of value_type. + // + // Maintainer's Note: The simpler solution would be to simply wrap value_type + // in a struct whether it's an array or not. That causes some paranoid + // diagnostics to misfire, believing that 'data()' returns a pointer to a + // single element, rather than the packed array that it really is. + // e.g.: + // + // FixedArray buf(1); + // sprintf(buf.data(), "foo"); + // + // error: call to int __builtin___sprintf_chk(etc...) + // will always overflow destination buffer [-Werror] + // + template , + size_t InnerN = std::extent::value> + struct StorageElementWrapper { + InnerT array[InnerN]; + }; + + using StorageElement = + absl::conditional_t::value, + StorageElementWrapper, value_type>; + using StorageElementBuffer = + absl::aligned_storage_t; + + static pointer AsValueType(pointer ptr) { return ptr; } + static pointer AsValueType(StorageElementWrapper* ptr) { + return std::addressof(ptr->array); + } + + static_assert(sizeof(StorageElement) == sizeof(value_type), ""); + static_assert(alignof(StorageElement) == alignof(value_type), ""); + + struct NonEmptyInlinedStorage { + StorageElement* data() { + return reinterpret_cast(inlined_storage_.data()); + } + +#ifdef ADDRESS_SANITIZER + void* RedzoneBegin() { return &redzone_begin_; } + void* RedzoneEnd() { return &redzone_end_ + 1; } +#endif // ADDRESS_SANITIZER + + void AnnotateConstruct(size_type); + void AnnotateDestruct(size_type); + + ADDRESS_SANITIZER_REDZONE(redzone_begin_); + std::array inlined_storage_; + ADDRESS_SANITIZER_REDZONE(redzone_end_); + }; + + struct EmptyInlinedStorage { + StorageElement* data() { return nullptr; } + void AnnotateConstruct(size_type) {} + void AnnotateDestruct(size_type) {} + }; + + using InlinedStorage = + absl::conditional_t; + + // Storage + // + // An instance of Storage manages the inline and out-of-line memory for + // instances of FixedArray. This guarantees that even when construction of + // individual elements fails in the FixedArray constructor body, the + // destructor for Storage will still be called and out-of-line memory will be + // properly deallocated. + // + class Storage : public InlinedStorage { + public: + Storage(size_type n, const allocator_type& a) + : size_alloc_(n, a), data_(InitializeData()) {} + + ~Storage() noexcept { + if (UsingInlinedStorage(size())) { + InlinedStorage::AnnotateDestruct(size()); + } else { + AllocatorTraits::deallocate(alloc(), AsValueType(begin()), size()); + } + } + + size_type size() const { return size_alloc_.template get<0>(); } + StorageElement* begin() const { return data_; } + StorageElement* end() const { return begin() + size(); } + allocator_type& alloc() { + return size_alloc_.template get<1>(); + } + + private: + static bool UsingInlinedStorage(size_type n) { + return n <= inline_elements; + } + + StorageElement* InitializeData() { + if (UsingInlinedStorage(size())) { + InlinedStorage::AnnotateConstruct(size()); + return InlinedStorage::data(); + } else { + return reinterpret_cast( + AllocatorTraits::allocate(alloc(), size())); + } + } + + // `CompressedTuple` takes advantage of EBCO for stateless `allocator_type`s + container_internal::CompressedTuple size_alloc_; + StorageElement* data_; + }; + + Storage storage_; +}; + +template +constexpr size_t FixedArray::kInlineBytesDefault; + +template +constexpr typename FixedArray::size_type + FixedArray::inline_elements; + +template +void FixedArray::NonEmptyInlinedStorage::AnnotateConstruct( + typename FixedArray::size_type n) { +#ifdef ADDRESS_SANITIZER + if (!n) return; + ANNOTATE_CONTIGUOUS_CONTAINER(data(), RedzoneEnd(), RedzoneEnd(), data() + n); + ANNOTATE_CONTIGUOUS_CONTAINER(RedzoneBegin(), data(), data(), RedzoneBegin()); +#endif // ADDRESS_SANITIZER + static_cast(n); // Mark used when not in asan mode +} + +template +void FixedArray::NonEmptyInlinedStorage::AnnotateDestruct( + typename FixedArray::size_type n) { +#ifdef ADDRESS_SANITIZER + if (!n) return; + ANNOTATE_CONTIGUOUS_CONTAINER(data(), RedzoneEnd(), data() + n, RedzoneEnd()); + ANNOTATE_CONTIGUOUS_CONTAINER(RedzoneBegin(), data(), RedzoneBegin(), data()); +#endif // ADDRESS_SANITIZER + static_cast(n); // Mark used when not in asan mode +} +} // namespace absl +#endif // ABSL_CONTAINER_FIXED_ARRAY_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/fixed_array_benchmark.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/fixed_array_benchmark.cc new file mode 100644 index 0000000..b4f0cf2 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/fixed_array_benchmark.cc @@ -0,0 +1,66 @@ +// Copyright 2017 The Abseil Authors. +// +// 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 "absl/container/fixed_array.h" + +#include +#include + +#include "benchmark/benchmark.h" + +namespace { + +// For benchmarking -- simple class with constructor and destructor that +// set an int to a constant.. +class SimpleClass { + public: + SimpleClass() : i(3) { } + ~SimpleClass() { i = 0; } + private: + int i; +}; + +template +void BM_FixedArray(benchmark::State& state) { + const int size = state.range(0); + for (auto _ : state) { + absl::FixedArray fa(size); + benchmark::DoNotOptimize(fa.data()); + } +} +BENCHMARK_TEMPLATE(BM_FixedArray, char, absl::kFixedArrayUseDefault) + ->Range(0, 1 << 16); +BENCHMARK_TEMPLATE(BM_FixedArray, char, 0)->Range(0, 1 << 16); +BENCHMARK_TEMPLATE(BM_FixedArray, char, 1)->Range(0, 1 << 16); +BENCHMARK_TEMPLATE(BM_FixedArray, char, 16)->Range(0, 1 << 16); +BENCHMARK_TEMPLATE(BM_FixedArray, char, 256)->Range(0, 1 << 16); +BENCHMARK_TEMPLATE(BM_FixedArray, char, 65536)->Range(0, 1 << 16); + +BENCHMARK_TEMPLATE(BM_FixedArray, SimpleClass, absl::kFixedArrayUseDefault) + ->Range(0, 1 << 16); +BENCHMARK_TEMPLATE(BM_FixedArray, SimpleClass, 0)->Range(0, 1 << 16); +BENCHMARK_TEMPLATE(BM_FixedArray, SimpleClass, 1)->Range(0, 1 << 16); +BENCHMARK_TEMPLATE(BM_FixedArray, SimpleClass, 16)->Range(0, 1 << 16); +BENCHMARK_TEMPLATE(BM_FixedArray, SimpleClass, 256)->Range(0, 1 << 16); +BENCHMARK_TEMPLATE(BM_FixedArray, SimpleClass, 65536)->Range(0, 1 << 16); + +BENCHMARK_TEMPLATE(BM_FixedArray, std::string, absl::kFixedArrayUseDefault) + ->Range(0, 1 << 16); +BENCHMARK_TEMPLATE(BM_FixedArray, std::string, 0)->Range(0, 1 << 16); +BENCHMARK_TEMPLATE(BM_FixedArray, std::string, 1)->Range(0, 1 << 16); +BENCHMARK_TEMPLATE(BM_FixedArray, std::string, 16)->Range(0, 1 << 16); +BENCHMARK_TEMPLATE(BM_FixedArray, std::string, 256)->Range(0, 1 << 16); +BENCHMARK_TEMPLATE(BM_FixedArray, std::string, 65536)->Range(0, 1 << 16); + +} // namespace diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/fixed_array_exception_safety_test.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/fixed_array_exception_safety_test.cc new file mode 100644 index 0000000..da63dbf --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/fixed_array_exception_safety_test.cc @@ -0,0 +1,117 @@ +// Copyright 2017 The Abseil Authors. +// +// 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 + +#include "absl/container/fixed_array.h" + +#include "gtest/gtest.h" +#include "absl/base/internal/exception_safety_testing.h" + +namespace absl { + +namespace { + +constexpr size_t kInlined = 25; +constexpr size_t kSmallSize = kInlined / 2; +constexpr size_t kLargeSize = kInlined * 2; + +constexpr int kInitialValue = 5; +constexpr int kUpdatedValue = 10; + +using ::testing::TestThrowingCtor; + +using Thrower = testing::ThrowingValue; +using FixedArr = absl::FixedArray; + +using MoveThrower = testing::ThrowingValue; +using MoveFixedArr = absl::FixedArray; + +TEST(FixedArrayExceptionSafety, CopyConstructor) { + auto small = FixedArr(kSmallSize); + TestThrowingCtor(small); + + auto large = FixedArr(kLargeSize); + TestThrowingCtor(large); +} + +TEST(FixedArrayExceptionSafety, MoveConstructor) { + TestThrowingCtor(FixedArr(kSmallSize)); + TestThrowingCtor(FixedArr(kLargeSize)); + + // TypeSpec::kNoThrowMove + TestThrowingCtor(MoveFixedArr(kSmallSize)); + TestThrowingCtor(MoveFixedArr(kLargeSize)); +} + +TEST(FixedArrayExceptionSafety, SizeConstructor) { + TestThrowingCtor(kSmallSize); + TestThrowingCtor(kLargeSize); +} + +TEST(FixedArrayExceptionSafety, SizeValueConstructor) { + TestThrowingCtor(kSmallSize, Thrower()); + TestThrowingCtor(kLargeSize, Thrower()); +} + +TEST(FixedArrayExceptionSafety, IteratorConstructor) { + auto small = FixedArr(kSmallSize); + TestThrowingCtor(small.begin(), small.end()); + + auto large = FixedArr(kLargeSize); + TestThrowingCtor(large.begin(), large.end()); +} + +TEST(FixedArrayExceptionSafety, InitListConstructor) { + constexpr int small_inlined = 3; + using SmallFixedArr = absl::FixedArray; + + TestThrowingCtor(std::initializer_list{}); + // Test inlined allocation + TestThrowingCtor( + std::initializer_list{Thrower{}, Thrower{}}); + // Test out of line allocation + TestThrowingCtor(std::initializer_list{ + Thrower{}, Thrower{}, Thrower{}, Thrower{}, Thrower{}}); +} + +testing::AssertionResult ReadMemory(FixedArr* fixed_arr) { + // Marked volatile to prevent optimization. Used for running asan tests. + volatile int sum = 0; + for (const auto& thrower : *fixed_arr) { + sum += thrower.Get(); + } + return testing::AssertionSuccess() << "Values sum to [" << sum << "]"; +} + +TEST(FixedArrayExceptionSafety, Fill) { + auto test_fill = testing::MakeExceptionSafetyTester() + .WithContracts(ReadMemory) + .WithOperation([&](FixedArr* fixed_arr_ptr) { + auto thrower = + Thrower(kUpdatedValue, testing::nothrow_ctor); + fixed_arr_ptr->fill(thrower); + }); + + EXPECT_TRUE( + test_fill.WithInitialValue(FixedArr(kSmallSize, Thrower(kInitialValue))) + .Test()); + EXPECT_TRUE( + test_fill.WithInitialValue(FixedArr(kLargeSize, Thrower(kInitialValue))) + .Test()); +} + +} // namespace + +} // namespace absl diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/fixed_array_test.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/fixed_array_test.cc new file mode 100644 index 0000000..205ff41 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/fixed_array_test.cc @@ -0,0 +1,872 @@ +// Copyright 2017 The Abseil Authors. +// +// 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 "absl/container/fixed_array.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gmock/gmock.h" +#include "gtest/gtest.h" +#include "absl/base/internal/exception_testing.h" +#include "absl/hash/hash_testing.h" +#include "absl/memory/memory.h" + +using ::testing::ElementsAreArray; + +namespace { + +// Helper routine to determine if a absl::FixedArray used stack allocation. +template +static bool IsOnStack(const ArrayType& a) { + return a.size() <= ArrayType::inline_elements; +} + +class ConstructionTester { + public: + ConstructionTester() + : self_ptr_(this), + value_(0) { + constructions++; + } + ~ConstructionTester() { + assert(self_ptr_ == this); + self_ptr_ = nullptr; + destructions++; + } + + // These are incremented as elements are constructed and destructed so we can + // be sure all elements are properly cleaned up. + static int constructions; + static int destructions; + + void CheckConstructed() { + assert(self_ptr_ == this); + } + + void set(int value) { value_ = value; } + int get() { return value_; } + + private: + // self_ptr_ should always point to 'this' -- that's how we can be sure the + // constructor has been called. + ConstructionTester* self_ptr_; + int value_; +}; + +int ConstructionTester::constructions = 0; +int ConstructionTester::destructions = 0; + +// ThreeInts will initialize its three ints to the value stored in +// ThreeInts::counter. The constructor increments counter so that each object +// in an array of ThreeInts will have different values. +class ThreeInts { + public: + ThreeInts() { + x_ = counter; + y_ = counter; + z_ = counter; + ++counter; + } + + static int counter; + + int x_, y_, z_; +}; + +int ThreeInts::counter = 0; + +TEST(FixedArrayTest, CopyCtor) { + absl::FixedArray on_stack(5); + std::iota(on_stack.begin(), on_stack.end(), 0); + absl::FixedArray stack_copy = on_stack; + EXPECT_THAT(stack_copy, ElementsAreArray(on_stack)); + EXPECT_TRUE(IsOnStack(stack_copy)); + + absl::FixedArray allocated(15); + std::iota(allocated.begin(), allocated.end(), 0); + absl::FixedArray alloced_copy = allocated; + EXPECT_THAT(alloced_copy, ElementsAreArray(allocated)); + EXPECT_FALSE(IsOnStack(alloced_copy)); +} + +TEST(FixedArrayTest, MoveCtor) { + absl::FixedArray, 10> on_stack(5); + for (int i = 0; i < 5; ++i) { + on_stack[i] = absl::make_unique(i); + } + + absl::FixedArray, 10> stack_copy = std::move(on_stack); + for (int i = 0; i < 5; ++i) EXPECT_EQ(*(stack_copy[i]), i); + EXPECT_EQ(stack_copy.size(), on_stack.size()); + + absl::FixedArray, 10> allocated(15); + for (int i = 0; i < 15; ++i) { + allocated[i] = absl::make_unique(i); + } + + absl::FixedArray, 10> alloced_copy = + std::move(allocated); + for (int i = 0; i < 15; ++i) EXPECT_EQ(*(alloced_copy[i]), i); + EXPECT_EQ(allocated.size(), alloced_copy.size()); +} + +TEST(FixedArrayTest, SmallObjects) { + // Small object arrays + { + // Short arrays should be on the stack + absl::FixedArray array(4); + EXPECT_TRUE(IsOnStack(array)); + } + + { + // Large arrays should be on the heap + absl::FixedArray array(1048576); + EXPECT_FALSE(IsOnStack(array)); + } + + { + // Arrays of <= default size should be on the stack + absl::FixedArray array(100); + EXPECT_TRUE(IsOnStack(array)); + } + + { + // Arrays of > default size should be on the stack + absl::FixedArray array(101); + EXPECT_FALSE(IsOnStack(array)); + } + + { + // Arrays with different size elements should use approximately + // same amount of stack space + absl::FixedArray array1(0); + absl::FixedArray array2(0); + EXPECT_LE(sizeof(array1), sizeof(array2)+100); + EXPECT_LE(sizeof(array2), sizeof(array1)+100); + } + + { + // Ensure that vectors are properly constructed inside a fixed array. + absl::FixedArray > array(2); + EXPECT_EQ(0, array[0].size()); + EXPECT_EQ(0, array[1].size()); + } + + { + // Regardless of absl::FixedArray implementation, check that a type with a + // low alignment requirement and a non power-of-two size is initialized + // correctly. + ThreeInts::counter = 1; + absl::FixedArray array(2); + EXPECT_EQ(1, array[0].x_); + EXPECT_EQ(1, array[0].y_); + EXPECT_EQ(1, array[0].z_); + EXPECT_EQ(2, array[1].x_); + EXPECT_EQ(2, array[1].y_); + EXPECT_EQ(2, array[1].z_); + } +} + +TEST(FixedArrayTest, AtThrows) { + absl::FixedArray a = {1, 2, 3}; + EXPECT_EQ(a.at(2), 3); + ABSL_BASE_INTERNAL_EXPECT_FAIL(a.at(3), std::out_of_range, + "failed bounds check"); +} + +TEST(FixedArrayRelationalsTest, EqualArrays) { + for (int i = 0; i < 10; ++i) { + absl::FixedArray a1(i); + std::iota(a1.begin(), a1.end(), 0); + absl::FixedArray a2(a1.begin(), a1.end()); + + EXPECT_TRUE(a1 == a2); + EXPECT_FALSE(a1 != a2); + EXPECT_TRUE(a2 == a1); + EXPECT_FALSE(a2 != a1); + EXPECT_FALSE(a1 < a2); + EXPECT_FALSE(a1 > a2); + EXPECT_FALSE(a2 < a1); + EXPECT_FALSE(a2 > a1); + EXPECT_TRUE(a1 <= a2); + EXPECT_TRUE(a1 >= a2); + EXPECT_TRUE(a2 <= a1); + EXPECT_TRUE(a2 >= a1); + } +} + +TEST(FixedArrayRelationalsTest, UnequalArrays) { + for (int i = 1; i < 10; ++i) { + absl::FixedArray a1(i); + std::iota(a1.begin(), a1.end(), 0); + absl::FixedArray a2(a1.begin(), a1.end()); + --a2[i / 2]; + + EXPECT_FALSE(a1 == a2); + EXPECT_TRUE(a1 != a2); + EXPECT_FALSE(a2 == a1); + EXPECT_TRUE(a2 != a1); + EXPECT_FALSE(a1 < a2); + EXPECT_TRUE(a1 > a2); + EXPECT_TRUE(a2 < a1); + EXPECT_FALSE(a2 > a1); + EXPECT_FALSE(a1 <= a2); + EXPECT_TRUE(a1 >= a2); + EXPECT_TRUE(a2 <= a1); + EXPECT_FALSE(a2 >= a1); + } +} + +template +static void TestArray(int n) { + SCOPED_TRACE(n); + SCOPED_TRACE(stack_elements); + ConstructionTester::constructions = 0; + ConstructionTester::destructions = 0; + { + absl::FixedArray array(n); + + EXPECT_THAT(array.size(), n); + EXPECT_THAT(array.memsize(), sizeof(ConstructionTester) * n); + EXPECT_THAT(array.begin() + n, array.end()); + + // Check that all elements were constructed + for (int i = 0; i < n; i++) { + array[i].CheckConstructed(); + } + // Check that no other elements were constructed + EXPECT_THAT(ConstructionTester::constructions, n); + + // Test operator[] + for (int i = 0; i < n; i++) { + array[i].set(i); + } + for (int i = 0; i < n; i++) { + EXPECT_THAT(array[i].get(), i); + EXPECT_THAT(array.data()[i].get(), i); + } + + // Test data() + for (int i = 0; i < n; i++) { + array.data()[i].set(i + 1); + } + for (int i = 0; i < n; i++) { + EXPECT_THAT(array[i].get(), i+1); + EXPECT_THAT(array.data()[i].get(), i+1); + } + } // Close scope containing 'array'. + + // Check that all constructed elements were destructed. + EXPECT_EQ(ConstructionTester::constructions, + ConstructionTester::destructions); +} + +template +static void TestArrayOfArrays(int n) { + SCOPED_TRACE(n); + SCOPED_TRACE(inline_elements); + SCOPED_TRACE(elements_per_inner_array); + ConstructionTester::constructions = 0; + ConstructionTester::destructions = 0; + { + using InnerArray = ConstructionTester[elements_per_inner_array]; + // Heap-allocate the FixedArray to avoid blowing the stack frame. + auto array_ptr = + absl::make_unique>(n); + auto& array = *array_ptr; + + ASSERT_EQ(array.size(), n); + ASSERT_EQ(array.memsize(), + sizeof(ConstructionTester) * elements_per_inner_array * n); + ASSERT_EQ(array.begin() + n, array.end()); + + // Check that all elements were constructed + for (int i = 0; i < n; i++) { + for (int j = 0; j < elements_per_inner_array; j++) { + (array[i])[j].CheckConstructed(); + } + } + // Check that no other elements were constructed + ASSERT_EQ(ConstructionTester::constructions, n * elements_per_inner_array); + + // Test operator[] + for (int i = 0; i < n; i++) { + for (int j = 0; j < elements_per_inner_array; j++) { + (array[i])[j].set(i * elements_per_inner_array + j); + } + } + for (int i = 0; i < n; i++) { + for (int j = 0; j < elements_per_inner_array; j++) { + ASSERT_EQ((array[i])[j].get(), i * elements_per_inner_array + j); + ASSERT_EQ((array.data()[i])[j].get(), i * elements_per_inner_array + j); + } + } + + // Test data() + for (int i = 0; i < n; i++) { + for (int j = 0; j < elements_per_inner_array; j++) { + (array.data()[i])[j].set((i + 1) * elements_per_inner_array + j); + } + } + for (int i = 0; i < n; i++) { + for (int j = 0; j < elements_per_inner_array; j++) { + ASSERT_EQ((array[i])[j].get(), + (i + 1) * elements_per_inner_array + j); + ASSERT_EQ((array.data()[i])[j].get(), + (i + 1) * elements_per_inner_array + j); + } + } + } // Close scope containing 'array'. + + // Check that all constructed elements were destructed. + EXPECT_EQ(ConstructionTester::constructions, + ConstructionTester::destructions); +} + +TEST(IteratorConstructorTest, NonInline) { + int const kInput[] = { 2, 3, 5, 7, 11, 13, 17 }; + absl::FixedArray const fixed( + kInput, kInput + ABSL_ARRAYSIZE(kInput)); + ASSERT_EQ(ABSL_ARRAYSIZE(kInput), fixed.size()); + for (size_t i = 0; i < ABSL_ARRAYSIZE(kInput); ++i) { + ASSERT_EQ(kInput[i], fixed[i]); + } +} + +TEST(IteratorConstructorTest, Inline) { + int const kInput[] = { 2, 3, 5, 7, 11, 13, 17 }; + absl::FixedArray const fixed( + kInput, kInput + ABSL_ARRAYSIZE(kInput)); + ASSERT_EQ(ABSL_ARRAYSIZE(kInput), fixed.size()); + for (size_t i = 0; i < ABSL_ARRAYSIZE(kInput); ++i) { + ASSERT_EQ(kInput[i], fixed[i]); + } +} + +TEST(IteratorConstructorTest, NonPod) { + char const* kInput[] = + { "red", "orange", "yellow", "green", "blue", "indigo", "violet" }; + absl::FixedArray const fixed(kInput, kInput + ABSL_ARRAYSIZE(kInput)); + ASSERT_EQ(ABSL_ARRAYSIZE(kInput), fixed.size()); + for (size_t i = 0; i < ABSL_ARRAYSIZE(kInput); ++i) { + ASSERT_EQ(kInput[i], fixed[i]); + } +} + +TEST(IteratorConstructorTest, FromEmptyVector) { + std::vector const empty; + absl::FixedArray const fixed(empty.begin(), empty.end()); + EXPECT_EQ(0, fixed.size()); + EXPECT_EQ(empty.size(), fixed.size()); +} + +TEST(IteratorConstructorTest, FromNonEmptyVector) { + int const kInput[] = { 2, 3, 5, 7, 11, 13, 17 }; + std::vector const items(kInput, kInput + ABSL_ARRAYSIZE(kInput)); + absl::FixedArray const fixed(items.begin(), items.end()); + ASSERT_EQ(items.size(), fixed.size()); + for (size_t i = 0; i < items.size(); ++i) { + ASSERT_EQ(items[i], fixed[i]); + } +} + +TEST(IteratorConstructorTest, FromBidirectionalIteratorRange) { + int const kInput[] = { 2, 3, 5, 7, 11, 13, 17 }; + std::list const items(kInput, kInput + ABSL_ARRAYSIZE(kInput)); + absl::FixedArray const fixed(items.begin(), items.end()); + EXPECT_THAT(fixed, testing::ElementsAreArray(kInput)); +} + +TEST(InitListConstructorTest, InitListConstruction) { + absl::FixedArray fixed = {1, 2, 3}; + EXPECT_THAT(fixed, testing::ElementsAreArray({1, 2, 3})); +} + +TEST(FillConstructorTest, NonEmptyArrays) { + absl::FixedArray stack_array(4, 1); + EXPECT_THAT(stack_array, testing::ElementsAreArray({1, 1, 1, 1})); + + absl::FixedArray heap_array(4, 1); + EXPECT_THAT(stack_array, testing::ElementsAreArray({1, 1, 1, 1})); +} + +TEST(FillConstructorTest, EmptyArray) { + absl::FixedArray empty_fill(0, 1); + absl::FixedArray empty_size(0); + EXPECT_EQ(empty_fill, empty_size); +} + +TEST(FillConstructorTest, NotTriviallyCopyable) { + std::string str = "abcd"; + absl::FixedArray strings = {str, str, str, str}; + + absl::FixedArray array(4, str); + EXPECT_EQ(array, strings); +} + +TEST(FillConstructorTest, Disambiguation) { + absl::FixedArray a(1, 2); + EXPECT_THAT(a, testing::ElementsAre(2)); +} + +TEST(FixedArrayTest, ManySizedArrays) { + std::vector sizes; + for (int i = 1; i < 100; i++) sizes.push_back(i); + for (int i = 100; i <= 1000; i += 100) sizes.push_back(i); + for (int n : sizes) { + TestArray<0>(n); + TestArray<1>(n); + TestArray<64>(n); + TestArray<1000>(n); + } +} + +TEST(FixedArrayTest, ManySizedArraysOfArraysOf1) { + for (int n = 1; n < 1000; n++) { + ASSERT_NO_FATAL_FAILURE((TestArrayOfArrays<1, 0>(n))); + ASSERT_NO_FATAL_FAILURE((TestArrayOfArrays<1, 1>(n))); + ASSERT_NO_FATAL_FAILURE((TestArrayOfArrays<1, 64>(n))); + ASSERT_NO_FATAL_FAILURE((TestArrayOfArrays<1, 1000>(n))); + } +} + +TEST(FixedArrayTest, ManySizedArraysOfArraysOf2) { + for (int n = 1; n < 1000; n++) { + TestArrayOfArrays<2, 0>(n); + TestArrayOfArrays<2, 1>(n); + TestArrayOfArrays<2, 64>(n); + TestArrayOfArrays<2, 1000>(n); + } +} + +// If value_type is put inside of a struct container, +// we might evoke this error in a hardened build unless data() is carefully +// written, so check on that. +// error: call to int __builtin___sprintf_chk(etc...) +// will always overflow destination buffer [-Werror] +TEST(FixedArrayTest, AvoidParanoidDiagnostics) { + absl::FixedArray buf(32); + sprintf(buf.data(), "foo"); // NOLINT(runtime/printf) +} + +TEST(FixedArrayTest, TooBigInlinedSpace) { + struct TooBig { + char c[1 << 20]; + }; // too big for even one on the stack + + // Simulate the data members of absl::FixedArray, a pointer and a size_t. + struct Data { + TooBig* p; + size_t size; + }; + + // Make sure TooBig objects are not inlined for 0 or default size. + static_assert(sizeof(absl::FixedArray) == sizeof(Data), + "0-sized absl::FixedArray should have same size as Data."); + static_assert(alignof(absl::FixedArray) == alignof(Data), + "0-sized absl::FixedArray should have same alignment as Data."); + static_assert(sizeof(absl::FixedArray) == sizeof(Data), + "default-sized absl::FixedArray should have same size as Data"); + static_assert( + alignof(absl::FixedArray) == alignof(Data), + "default-sized absl::FixedArray should have same alignment as Data."); +} + +// PickyDelete EXPECTs its class-scope deallocation funcs are unused. +struct PickyDelete { + PickyDelete() {} + ~PickyDelete() {} + void operator delete(void* p) { + EXPECT_TRUE(false) << __FUNCTION__; + ::operator delete(p); + } + void operator delete[](void* p) { + EXPECT_TRUE(false) << __FUNCTION__; + ::operator delete[](p); + } +}; + +TEST(FixedArrayTest, UsesGlobalAlloc) { absl::FixedArray a(5); } + + +TEST(FixedArrayTest, Data) { + static const int kInput[] = { 2, 3, 5, 7, 11, 13, 17 }; + absl::FixedArray fa(std::begin(kInput), std::end(kInput)); + EXPECT_EQ(fa.data(), &*fa.begin()); + EXPECT_EQ(fa.data(), &fa[0]); + + const absl::FixedArray& cfa = fa; + EXPECT_EQ(cfa.data(), &*cfa.begin()); + EXPECT_EQ(cfa.data(), &cfa[0]); +} + +TEST(FixedArrayTest, Empty) { + absl::FixedArray empty(0); + absl::FixedArray inline_filled(1); + absl::FixedArray heap_filled(1); + EXPECT_TRUE(empty.empty()); + EXPECT_FALSE(inline_filled.empty()); + EXPECT_FALSE(heap_filled.empty()); +} + +TEST(FixedArrayTest, FrontAndBack) { + absl::FixedArray inlined = {1, 2, 3}; + EXPECT_EQ(inlined.front(), 1); + EXPECT_EQ(inlined.back(), 3); + + absl::FixedArray allocated = {1, 2, 3}; + EXPECT_EQ(allocated.front(), 1); + EXPECT_EQ(allocated.back(), 3); + + absl::FixedArray one_element = {1}; + EXPECT_EQ(one_element.front(), one_element.back()); +} + +TEST(FixedArrayTest, ReverseIteratorInlined) { + absl::FixedArray a = {0, 1, 2, 3, 4}; + + int counter = 5; + for (absl::FixedArray::reverse_iterator iter = a.rbegin(); + iter != a.rend(); ++iter) { + counter--; + EXPECT_EQ(counter, *iter); + } + EXPECT_EQ(counter, 0); + + counter = 5; + for (absl::FixedArray::const_reverse_iterator iter = a.rbegin(); + iter != a.rend(); ++iter) { + counter--; + EXPECT_EQ(counter, *iter); + } + EXPECT_EQ(counter, 0); + + counter = 5; + for (auto iter = a.crbegin(); iter != a.crend(); ++iter) { + counter--; + EXPECT_EQ(counter, *iter); + } + EXPECT_EQ(counter, 0); +} + +TEST(FixedArrayTest, ReverseIteratorAllocated) { + absl::FixedArray a = {0, 1, 2, 3, 4}; + + int counter = 5; + for (absl::FixedArray::reverse_iterator iter = a.rbegin(); + iter != a.rend(); ++iter) { + counter--; + EXPECT_EQ(counter, *iter); + } + EXPECT_EQ(counter, 0); + + counter = 5; + for (absl::FixedArray::const_reverse_iterator iter = a.rbegin(); + iter != a.rend(); ++iter) { + counter--; + EXPECT_EQ(counter, *iter); + } + EXPECT_EQ(counter, 0); + + counter = 5; + for (auto iter = a.crbegin(); iter != a.crend(); ++iter) { + counter--; + EXPECT_EQ(counter, *iter); + } + EXPECT_EQ(counter, 0); +} + +TEST(FixedArrayTest, Fill) { + absl::FixedArray inlined(5); + int fill_val = 42; + inlined.fill(fill_val); + for (int i : inlined) EXPECT_EQ(i, fill_val); + + absl::FixedArray allocated(5); + allocated.fill(fill_val); + for (int i : allocated) EXPECT_EQ(i, fill_val); + + // It doesn't do anything, just make sure this compiles. + absl::FixedArray empty(0); + empty.fill(fill_val); +} + +// TODO(johnsoncj): Investigate InlinedStorage default initialization in GCC 4.x +#ifndef __GNUC__ +TEST(FixedArrayTest, DefaultCtorDoesNotValueInit) { + using T = char; + constexpr auto capacity = 10; + using FixedArrType = absl::FixedArray; + using FixedArrBuffType = + absl::aligned_storage_t; + constexpr auto scrubbed_bits = 0x95; + constexpr auto length = capacity / 2; + + FixedArrBuffType buff; + std::memset(std::addressof(buff), scrubbed_bits, sizeof(FixedArrBuffType)); + + FixedArrType* arr = + ::new (static_cast(std::addressof(buff))) FixedArrType(length); + EXPECT_THAT(*arr, testing::Each(scrubbed_bits)); + arr->~FixedArrType(); +} +#endif // __GNUC__ + +// This is a stateful allocator, but the state lives outside of the +// allocator (in whatever test is using the allocator). This is odd +// but helps in tests where the allocator is propagated into nested +// containers - that chain of allocators uses the same state and is +// thus easier to query for aggregate allocation information. +template +class CountingAllocator : public std::allocator { + public: + using Alloc = std::allocator; + using pointer = typename Alloc::pointer; + using size_type = typename Alloc::size_type; + + CountingAllocator() : bytes_used_(nullptr), instance_count_(nullptr) {} + explicit CountingAllocator(int64_t* b) + : bytes_used_(b), instance_count_(nullptr) {} + CountingAllocator(int64_t* b, int64_t* a) + : bytes_used_(b), instance_count_(a) {} + + template + explicit CountingAllocator(const CountingAllocator& x) + : Alloc(x), + bytes_used_(x.bytes_used_), + instance_count_(x.instance_count_) {} + + pointer allocate(size_type n, const void* const hint = nullptr) { + assert(bytes_used_ != nullptr); + *bytes_used_ += n * sizeof(T); + return Alloc::allocate(n, hint); + } + + void deallocate(pointer p, size_type n) { + Alloc::deallocate(p, n); + assert(bytes_used_ != nullptr); + *bytes_used_ -= n * sizeof(T); + } + + template + void construct(pointer p, Args&&... args) { + Alloc::construct(p, absl::forward(args)...); + if (instance_count_) { + *instance_count_ += 1; + } + } + + void destroy(pointer p) { + Alloc::destroy(p); + if (instance_count_) { + *instance_count_ -= 1; + } + } + + template + class rebind { + public: + using other = CountingAllocator; + }; + + int64_t* bytes_used_; + int64_t* instance_count_; +}; + +TEST(AllocatorSupportTest, CountInlineAllocations) { + constexpr size_t inlined_size = 4; + using Alloc = CountingAllocator; + using AllocFxdArr = absl::FixedArray; + + int64_t allocated = 0; + int64_t active_instances = 0; + + { + const int ia[] = {0, 1, 2, 3, 4, 5, 6, 7}; + + Alloc alloc(&allocated, &active_instances); + + AllocFxdArr arr(ia, ia + inlined_size, alloc); + static_cast(arr); + } + + EXPECT_EQ(allocated, 0); + EXPECT_EQ(active_instances, 0); +} + +TEST(AllocatorSupportTest, CountOutoflineAllocations) { + constexpr size_t inlined_size = 4; + using Alloc = CountingAllocator; + using AllocFxdArr = absl::FixedArray; + + int64_t allocated = 0; + int64_t active_instances = 0; + + { + const int ia[] = {0, 1, 2, 3, 4, 5, 6, 7}; + Alloc alloc(&allocated, &active_instances); + + AllocFxdArr arr(ia, ia + ABSL_ARRAYSIZE(ia), alloc); + + EXPECT_EQ(allocated, arr.size() * sizeof(int)); + static_cast(arr); + } + + EXPECT_EQ(active_instances, 0); +} + +TEST(AllocatorSupportTest, CountCopyInlineAllocations) { + constexpr size_t inlined_size = 4; + using Alloc = CountingAllocator; + using AllocFxdArr = absl::FixedArray; + + int64_t allocated1 = 0; + int64_t allocated2 = 0; + int64_t active_instances = 0; + Alloc alloc(&allocated1, &active_instances); + Alloc alloc2(&allocated2, &active_instances); + + { + int initial_value = 1; + + AllocFxdArr arr1(inlined_size / 2, initial_value, alloc); + + EXPECT_EQ(allocated1, 0); + + AllocFxdArr arr2(arr1, alloc2); + + EXPECT_EQ(allocated2, 0); + static_cast(arr1); + static_cast(arr2); + } + + EXPECT_EQ(active_instances, 0); +} + +TEST(AllocatorSupportTest, CountCopyOutoflineAllocations) { + constexpr size_t inlined_size = 4; + using Alloc = CountingAllocator; + using AllocFxdArr = absl::FixedArray; + + int64_t allocated1 = 0; + int64_t allocated2 = 0; + int64_t active_instances = 0; + Alloc alloc(&allocated1, &active_instances); + Alloc alloc2(&allocated2, &active_instances); + + { + int initial_value = 1; + + AllocFxdArr arr1(inlined_size * 2, initial_value, alloc); + + EXPECT_EQ(allocated1, arr1.size() * sizeof(int)); + + AllocFxdArr arr2(arr1, alloc2); + + EXPECT_EQ(allocated2, inlined_size * 2 * sizeof(int)); + static_cast(arr1); + static_cast(arr2); + } + + EXPECT_EQ(active_instances, 0); +} + +TEST(AllocatorSupportTest, SizeValAllocConstructor) { + using testing::AllOf; + using testing::Each; + using testing::SizeIs; + + constexpr size_t inlined_size = 4; + using Alloc = CountingAllocator; + using AllocFxdArr = absl::FixedArray; + + { + auto len = inlined_size / 2; + auto val = 0; + int64_t allocated = 0; + AllocFxdArr arr(len, val, Alloc(&allocated)); + + EXPECT_EQ(allocated, 0); + EXPECT_THAT(arr, AllOf(SizeIs(len), Each(0))); + } + + { + auto len = inlined_size * 2; + auto val = 0; + int64_t allocated = 0; + AllocFxdArr arr(len, val, Alloc(&allocated)); + + EXPECT_EQ(allocated, len * sizeof(int)); + EXPECT_THAT(arr, AllOf(SizeIs(len), Each(0))); + } +} + +#ifdef ADDRESS_SANITIZER +TEST(FixedArrayTest, AddressSanitizerAnnotations1) { + absl::FixedArray a(10); + int *raw = a.data(); + raw[0] = 0; + raw[9] = 0; + EXPECT_DEATH(raw[-2] = 0, "container-overflow"); + EXPECT_DEATH(raw[-1] = 0, "container-overflow"); + EXPECT_DEATH(raw[10] = 0, "container-overflow"); + EXPECT_DEATH(raw[31] = 0, "container-overflow"); +} + +TEST(FixedArrayTest, AddressSanitizerAnnotations2) { + absl::FixedArray a(12); + char *raw = a.data(); + raw[0] = 0; + raw[11] = 0; + EXPECT_DEATH(raw[-7] = 0, "container-overflow"); + EXPECT_DEATH(raw[-1] = 0, "container-overflow"); + EXPECT_DEATH(raw[12] = 0, "container-overflow"); + EXPECT_DEATH(raw[17] = 0, "container-overflow"); +} + +TEST(FixedArrayTest, AddressSanitizerAnnotations3) { + absl::FixedArray a(20); + uint64_t *raw = a.data(); + raw[0] = 0; + raw[19] = 0; + EXPECT_DEATH(raw[-1] = 0, "container-overflow"); + EXPECT_DEATH(raw[20] = 0, "container-overflow"); +} + +TEST(FixedArrayTest, AddressSanitizerAnnotations4) { + absl::FixedArray a(10); + ThreeInts *raw = a.data(); + raw[0] = ThreeInts(); + raw[9] = ThreeInts(); + // Note: raw[-1] is pointing to 12 bytes before the container range. However, + // there is only a 8-byte red zone before the container range, so we only + // access the last 4 bytes of the struct to make sure it stays within the red + // zone. + EXPECT_DEATH(raw[-1].z_ = 0, "container-overflow"); + EXPECT_DEATH(raw[10] = ThreeInts(), "container-overflow"); + // The actual size of storage is kDefaultBytes=256, 21*12 = 252, + // so reading raw[21] should still trigger the correct warning. + EXPECT_DEATH(raw[21] = ThreeInts(), "container-overflow"); +} +#endif // ADDRESS_SANITIZER + +} // namespace diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/flat_hash_map.h b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/flat_hash_map.h new file mode 100644 index 0000000..de632be --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/flat_hash_map.h @@ -0,0 +1,568 @@ +// Copyright 2018 The Abseil Authors. +// +// 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. +// +// ----------------------------------------------------------------------------- +// File: flat_hash_map.h +// ----------------------------------------------------------------------------- +// +// An `absl::flat_hash_map` is an unordered associative container of +// unique keys and associated values designed to be a more efficient replacement +// for `std::unordered_map`. Like `unordered_map`, search, insertion, and +// deletion of map elements can be done as an `O(1)` operation. However, +// `flat_hash_map` (and other unordered associative containers known as the +// collection of Abseil "Swiss tables") contain other optimizations that result +// in both memory and computation advantages. +// +// In most cases, your default choice for a hash map should be a map of type +// `flat_hash_map`. + +#ifndef ABSL_CONTAINER_FLAT_HASH_MAP_H_ +#define ABSL_CONTAINER_FLAT_HASH_MAP_H_ + +#include +#include +#include +#include + +#include "absl/container/internal/container_memory.h" +#include "absl/container/internal/hash_function_defaults.h" // IWYU pragma: export +#include "absl/container/internal/raw_hash_map.h" // IWYU pragma: export +#include "absl/memory/memory.h" + +namespace absl { +namespace container_internal { +template +struct FlatHashMapPolicy; +} // namespace container_internal + +// ----------------------------------------------------------------------------- +// absl::flat_hash_map +// ----------------------------------------------------------------------------- +// +// An `absl::flat_hash_map` is an unordered associative container which +// has been optimized for both speed and memory footprint in most common use +// cases. Its interface is similar to that of `std::unordered_map` with +// the following notable differences: +// +// * Requires keys that are CopyConstructible +// * Requires values that are MoveConstructible +// * Supports heterogeneous lookup, through `find()`, `operator[]()` and +// `insert()`, provided that the map is provided a compatible heterogeneous +// hashing function and equality operator. +// * Invalidates any references and pointers to elements within the table after +// `rehash()`. +// * Contains a `capacity()` member function indicating the number of element +// slots (open, deleted, and empty) within the hash map. +// * Returns `void` from the `erase(iterator)` overload. +// +// By default, `flat_hash_map` uses the `absl::Hash` hashing framework. +// All fundamental and Abseil types that support the `absl::Hash` framework have +// a compatible equality operator for comparing insertions into `flat_hash_map`. +// If your type is not yet supported by the `asbl::Hash` framework, see +// absl/hash/hash.h for information on extending Abseil hashing to user-defined +// types. +// +// NOTE: A `flat_hash_map` stores its value types directly inside its +// implementation array to avoid memory indirection. Because a `flat_hash_map` +// is designed to move data when rehashed, map values will not retain pointer +// stability. If you require pointer stability, or your values are large, +// consider using `absl::flat_hash_map>` instead. +// If your types are not moveable or you require pointer stability for keys, +// consider `absl::node_hash_map`. +// +// Example: +// +// // Create a flat hash map of three strings (that map to strings) +// absl::flat_hash_map ducks = +// {{"a", "huey"}, {"b", "dewey"}, {"c", "louie"}}; +// +// // Insert a new element into the flat hash map +// ducks.insert({"d", "donald"}); +// +// // Force a rehash of the flat hash map +// ducks.rehash(0); +// +// // Find the element with the key "b" +// std::string search_key = "b"; +// auto result = ducks.find(search_key); +// if (result != ducks.end()) { +// std::cout << "Result: " << result->second << std::endl; +// } +template , + class Eq = absl::container_internal::hash_default_eq, + class Allocator = std::allocator>> +class flat_hash_map : public absl::container_internal::raw_hash_map< + absl::container_internal::FlatHashMapPolicy, + Hash, Eq, Allocator> { + using Base = typename flat_hash_map::raw_hash_map; + + public: + // Constructors and Assignment Operators + // + // A flat_hash_map supports the same overload set as `std::unordered_map` + // for construction and assignment: + // + // * Default constructor + // + // // No allocation for the table's elements is made. + // absl::flat_hash_map map1; + // + // * Initializer List constructor + // + // absl::flat_hash_map map2 = + // {{1, "huey"}, {2, "dewey"}, {3, "louie"},}; + // + // * Copy constructor + // + // absl::flat_hash_map map3(map2); + // + // * Copy assignment operator + // + // // Hash functor and Comparator are copied as well + // absl::flat_hash_map map4; + // map4 = map3; + // + // * Move constructor + // + // // Move is guaranteed efficient + // absl::flat_hash_map map5(std::move(map4)); + // + // * Move assignment operator + // + // // May be efficient if allocators are compatible + // absl::flat_hash_map map6; + // map6 = std::move(map5); + // + // * Range constructor + // + // std::vector> v = {{1, "a"}, {2, "b"}}; + // absl::flat_hash_map map7(v.begin(), v.end()); + flat_hash_map() {} + using Base::Base; + + // flat_hash_map::begin() + // + // Returns an iterator to the beginning of the `flat_hash_map`. + using Base::begin; + + // flat_hash_map::cbegin() + // + // Returns a const iterator to the beginning of the `flat_hash_map`. + using Base::cbegin; + + // flat_hash_map::cend() + // + // Returns a const iterator to the end of the `flat_hash_map`. + using Base::cend; + + // flat_hash_map::end() + // + // Returns an iterator to the end of the `flat_hash_map`. + using Base::end; + + // flat_hash_map::capacity() + // + // Returns the number of element slots (assigned, deleted, and empty) + // available within the `flat_hash_map`. + // + // NOTE: this member function is particular to `absl::flat_hash_map` and is + // not provided in the `std::unordered_map` API. + using Base::capacity; + + // flat_hash_map::empty() + // + // Returns whether or not the `flat_hash_map` is empty. + using Base::empty; + + // flat_hash_map::max_size() + // + // Returns the largest theoretical possible number of elements within a + // `flat_hash_map` under current memory constraints. This value can be thought + // of the largest value of `std::distance(begin(), end())` for a + // `flat_hash_map`. + using Base::max_size; + + // flat_hash_map::size() + // + // Returns the number of elements currently within the `flat_hash_map`. + using Base::size; + + // flat_hash_map::clear() + // + // Removes all elements from the `flat_hash_map`. Invalidates any references, + // pointers, or iterators referring to contained elements. + // + // NOTE: this operation may shrink the underlying buffer. To avoid shrinking + // the underlying buffer call `erase(begin(), end())`. + using Base::clear; + + // flat_hash_map::erase() + // + // Erases elements within the `flat_hash_map`. Erasing does not trigger a + // rehash. Overloads are listed below. + // + // void erase(const_iterator pos): + // + // Erases the element at `position` of the `flat_hash_map`, returning + // `void`. + // + // NOTE: this return behavior is different than that of STL containers in + // general and `std::unordered_map` in particular. + // + // iterator erase(const_iterator first, const_iterator last): + // + // Erases the elements in the open interval [`first`, `last`), returning an + // iterator pointing to `last`. + // + // size_type erase(const key_type& key): + // + // Erases the element with the matching key, if it exists. + using Base::erase; + + // flat_hash_map::insert() + // + // Inserts an element of the specified value into the `flat_hash_map`, + // returning an iterator pointing to the newly inserted element, provided that + // an element with the given key does not already exist. If rehashing occurs + // due to the insertion, all iterators are invalidated. Overloads are listed + // below. + // + // std::pair insert(const init_type& value): + // + // Inserts a value into the `flat_hash_map`. Returns a pair consisting of an + // iterator to the inserted element (or to the element that prevented the + // insertion) and a bool denoting whether the insertion took place. + // + // std::pair insert(T&& value): + // std::pair insert(init_type&& value): + // + // Inserts a moveable value into the `flat_hash_map`. Returns a pair + // consisting of an iterator to the inserted element (or to the element that + // prevented the insertion) and a bool denoting whether the insertion took + // place. + // + // iterator insert(const_iterator hint, const init_type& value): + // iterator insert(const_iterator hint, T&& value): + // iterator insert(const_iterator hint, init_type&& value); + // + // Inserts a value, using the position of `hint` as a non-binding suggestion + // for where to begin the insertion search. Returns an iterator to the + // inserted element, or to the existing element that prevented the + // insertion. + // + // void insert(InputIterator first, InputIterator last): + // + // Inserts a range of values [`first`, `last`). + // + // NOTE: Although the STL does not specify which element may be inserted if + // multiple keys compare equivalently, for `flat_hash_map` we guarantee the + // first match is inserted. + // + // void insert(std::initializer_list ilist): + // + // Inserts the elements within the initializer list `ilist`. + // + // NOTE: Although the STL does not specify which element may be inserted if + // multiple keys compare equivalently within the initializer list, for + // `flat_hash_map` we guarantee the first match is inserted. + using Base::insert; + + // flat_hash_map::insert_or_assign() + // + // Inserts an element of the specified value into the `flat_hash_map` provided + // that a value with the given key does not already exist, or replaces it with + // the element value if a key for that value already exists, returning an + // iterator pointing to the newly inserted element. If rehashing occurs due + // to the insertion, all existing iterators are invalidated. Overloads are + // listed below. + // + // pair insert_or_assign(const init_type& k, T&& obj): + // pair insert_or_assign(init_type&& k, T&& obj): + // + // Inserts/Assigns (or moves) the element of the specified key into the + // `flat_hash_map`. + // + // iterator insert_or_assign(const_iterator hint, + // const init_type& k, T&& obj): + // iterator insert_or_assign(const_iterator hint, init_type&& k, T&& obj): + // + // Inserts/Assigns (or moves) the element of the specified key into the + // `flat_hash_map` using the position of `hint` as a non-binding suggestion + // for where to begin the insertion search. + using Base::insert_or_assign; + + // flat_hash_map::emplace() + // + // Inserts an element of the specified value by constructing it in-place + // within the `flat_hash_map`, provided that no element with the given key + // already exists. + // + // The element may be constructed even if there already is an element with the + // key in the container, in which case the newly constructed element will be + // destroyed immediately. Prefer `try_emplace()` unless your key is not + // copyable or moveable. + // + // If rehashing occurs due to the insertion, all iterators are invalidated. + using Base::emplace; + + // flat_hash_map::emplace_hint() + // + // Inserts an element of the specified value by constructing it in-place + // within the `flat_hash_map`, using the position of `hint` as a non-binding + // suggestion for where to begin the insertion search, and only inserts + // provided that no element with the given key already exists. + // + // The element may be constructed even if there already is an element with the + // key in the container, in which case the newly constructed element will be + // destroyed immediately. Prefer `try_emplace()` unless your key is not + // copyable or moveable. + // + // If rehashing occurs due to the insertion, all iterators are invalidated. + using Base::emplace_hint; + + // flat_hash_map::try_emplace() + // + // Inserts an element of the specified value by constructing it in-place + // within the `flat_hash_map`, provided that no element with the given key + // already exists. Unlike `emplace()`, if an element with the given key + // already exists, we guarantee that no element is constructed. + // + // If rehashing occurs due to the insertion, all iterators are invalidated. + // Overloads are listed below. + // + // pair try_emplace(const key_type& k, Args&&... args): + // pair try_emplace(key_type&& k, Args&&... args): + // + // Inserts (via copy or move) the element of the specified key into the + // `flat_hash_map`. + // + // iterator try_emplace(const_iterator hint, + // const init_type& k, Args&&... args): + // iterator try_emplace(const_iterator hint, init_type&& k, Args&&... args): + // + // Inserts (via copy or move) the element of the specified key into the + // `flat_hash_map` using the position of `hint` as a non-binding suggestion + // for where to begin the insertion search. + using Base::try_emplace; + + // flat_hash_map::extract() + // + // Extracts the indicated element, erasing it in the process, and returns it + // as a C++17-compatible node handle. Overloads are listed below. + // + // node_type extract(const_iterator position): + // + // Extracts the key,value pair of the element at the indicated position and + // returns a node handle owning that extracted data. + // + // node_type extract(const key_type& x): + // + // Extracts the key,value pair of the element with a key matching the passed + // key value and returns a node handle owning that extracted data. If the + // `flat_hash_map` does not contain an element with a matching key, this + // function returns an empty node handle. + using Base::extract; + + // flat_hash_map::merge() + // + // Extracts elements from a given `source` flat hash map into this + // `flat_hash_map`. If the destination `flat_hash_map` already contains an + // element with an equivalent key, that element is not extracted. + using Base::merge; + + // flat_hash_map::swap(flat_hash_map& other) + // + // Exchanges the contents of this `flat_hash_map` with those of the `other` + // flat hash map, avoiding invocation of any move, copy, or swap operations on + // individual elements. + // + // All iterators and references on the `flat_hash_map` remain valid, excepting + // for the past-the-end iterator, which is invalidated. + // + // `swap()` requires that the flat hash map's hashing and key equivalence + // functions be Swappable, and are exchaged using unqualified calls to + // non-member `swap()`. If the map's allocator has + // `std::allocator_traits::propagate_on_container_swap::value` + // set to `true`, the allocators are also exchanged using an unqualified call + // to non-member `swap()`; otherwise, the allocators are not swapped. + using Base::swap; + + // flat_hash_map::rehash(count) + // + // Rehashes the `flat_hash_map`, setting the number of slots to be at least + // the passed value. If the new number of slots increases the load factor more + // than the current maximum load factor + // (`count` < `size()` / `max_load_factor()`), then the new number of slots + // will be at least `size()` / `max_load_factor()`. + // + // To force a rehash, pass rehash(0). + // + // NOTE: unlike behavior in `std::unordered_map`, references are also + // invalidated upon a `rehash()`. + using Base::rehash; + + // flat_hash_map::reserve(count) + // + // Sets the number of slots in the `flat_hash_map` to the number needed to + // accommodate at least `count` total elements without exceeding the current + // maximum load factor, and may rehash the container if needed. + using Base::reserve; + + // flat_hash_map::at() + // + // Returns a reference to the mapped value of the element with key equivalent + // to the passed key. + using Base::at; + + // flat_hash_map::contains() + // + // Determines whether an element with a key comparing equal to the given `key` + // exists within the `flat_hash_map`, returning `true` if so or `false` + // otherwise. + using Base::contains; + + // flat_hash_map::count(const Key& key) const + // + // Returns the number of elements with a key comparing equal to the given + // `key` within the `flat_hash_map`. note that this function will return + // either `1` or `0` since duplicate keys are not allowed within a + // `flat_hash_map`. + using Base::count; + + // flat_hash_map::equal_range() + // + // Returns a closed range [first, last], defined by a `std::pair` of two + // iterators, containing all elements with the passed key in the + // `flat_hash_map`. + using Base::equal_range; + + // flat_hash_map::find() + // + // Finds an element with the passed `key` within the `flat_hash_map`. + using Base::find; + + // flat_hash_map::operator[]() + // + // Returns a reference to the value mapped to the passed key within the + // `flat_hash_map`, performing an `insert()` if the key does not already + // exist. + // + // If an insertion occurs and results in a rehashing of the container, all + // iterators are invalidated. Otherwise iterators are not affected and + // references are not invalidated. Overloads are listed below. + // + // T& operator[](const Key& key): + // + // Inserts an init_type object constructed in-place if the element with the + // given key does not exist. + // + // T& operator[](Key&& key): + // + // Inserts an init_type object constructed in-place provided that an element + // with the given key does not exist. + using Base::operator[]; + + // flat_hash_map::bucket_count() + // + // Returns the number of "buckets" within the `flat_hash_map`. Note that + // because a flat hash map contains all elements within its internal storage, + // this value simply equals the current capacity of the `flat_hash_map`. + using Base::bucket_count; + + // flat_hash_map::load_factor() + // + // Returns the current load factor of the `flat_hash_map` (the average number + // of slots occupied with a value within the hash map). + using Base::load_factor; + + // flat_hash_map::max_load_factor() + // + // Manages the maximum load factor of the `flat_hash_map`. Overloads are + // listed below. + // + // float flat_hash_map::max_load_factor() + // + // Returns the current maximum load factor of the `flat_hash_map`. + // + // void flat_hash_map::max_load_factor(float ml) + // + // Sets the maximum load factor of the `flat_hash_map` to the passed value. + // + // NOTE: This overload is provided only for API compatibility with the STL; + // `flat_hash_map` will ignore any set load factor and manage its rehashing + // internally as an implementation detail. + using Base::max_load_factor; + + // flat_hash_map::get_allocator() + // + // Returns the allocator function associated with this `flat_hash_map`. + using Base::get_allocator; + + // flat_hash_map::hash_function() + // + // Returns the hashing function used to hash the keys within this + // `flat_hash_map`. + using Base::hash_function; + + // flat_hash_map::key_eq() + // + // Returns the function used for comparing keys equality. + using Base::key_eq; +}; + +namespace container_internal { + +template +struct FlatHashMapPolicy { + using slot_type = container_internal::slot_type; + using key_type = K; + using mapped_type = V; + using init_type = std::pair; + + template + static void construct(Allocator* alloc, slot_type* slot, Args&&... args) { + slot_type::construct(alloc, slot, std::forward(args)...); + } + + template + static void destroy(Allocator* alloc, slot_type* slot) { + slot_type::destroy(alloc, slot); + } + + template + static void transfer(Allocator* alloc, slot_type* new_slot, + slot_type* old_slot) { + slot_type::transfer(alloc, new_slot, old_slot); + } + + template + static decltype(absl::container_internal::DecomposePair( + std::declval(), std::declval()...)) + apply(F&& f, Args&&... args) { + return absl::container_internal::DecomposePair(std::forward(f), + std::forward(args)...); + } + + static size_t space_used(const slot_type*) { return 0; } + + static std::pair& element(slot_type* slot) { return slot->value; } + + static V& value(std::pair* kv) { return kv->second; } + static const V& value(const std::pair* kv) { return kv->second; } +}; + +} // namespace container_internal +} // namespace absl +#endif // ABSL_CONTAINER_FLAT_HASH_MAP_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/flat_hash_map_test.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/flat_hash_map_test.cc new file mode 100644 index 0000000..2c6f251 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/flat_hash_map_test.cc @@ -0,0 +1,241 @@ +// Copyright 2018 The Abseil Authors. +// +// 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 "absl/container/flat_hash_map.h" + +#include "absl/container/internal/hash_generator_testing.h" +#include "absl/container/internal/unordered_map_constructor_test.h" +#include "absl/container/internal/unordered_map_lookup_test.h" +#include "absl/container/internal/unordered_map_modifiers_test.h" +#include "absl/types/any.h" + +namespace absl { +namespace container_internal { +namespace { +using ::absl::container_internal::hash_internal::Enum; +using ::absl::container_internal::hash_internal::EnumClass; +using ::testing::_; +using ::testing::Pair; +using ::testing::UnorderedElementsAre; + +template +using Map = + flat_hash_map>; + +static_assert(!std::is_standard_layout(), ""); + +using MapTypes = + ::testing::Types, Map, Map, + Map, Map, + Map>; + +INSTANTIATE_TYPED_TEST_CASE_P(FlatHashMap, ConstructorTest, MapTypes); +INSTANTIATE_TYPED_TEST_CASE_P(FlatHashMap, LookupTest, MapTypes); +INSTANTIATE_TYPED_TEST_CASE_P(FlatHashMap, ModifiersTest, MapTypes); + +TEST(FlatHashMap, StandardLayout) { + struct Int { + explicit Int(size_t value) : value(value) {} + Int() : value(0) { ADD_FAILURE(); } + Int(const Int& other) : value(other.value) { ADD_FAILURE(); } + Int(Int&&) = default; + bool operator==(const Int& other) const { return value == other.value; } + size_t value; + }; + static_assert(std::is_standard_layout(), ""); + + struct Hash { + size_t operator()(const Int& obj) const { return obj.value; } + }; + + // Verify that neither the key nor the value get default-constructed or + // copy-constructed. + { + flat_hash_map m; + m.try_emplace(Int(1), Int(2)); + m.try_emplace(Int(3), Int(4)); + m.erase(Int(1)); + m.rehash(2 * m.bucket_count()); + } + { + flat_hash_map m; + m.try_emplace(Int(1), Int(2)); + m.try_emplace(Int(3), Int(4)); + m.erase(Int(1)); + m.clear(); + } +} + +// gcc becomes unhappy if this is inside the method, so pull it out here. +struct balast {}; + +TEST(FlatHashMap, IteratesMsan) { + // Because SwissTable randomizes on pointer addresses, we keep old tables + // around to ensure we don't reuse old memory. + std::vector> garbage; + for (int i = 0; i < 100; ++i) { + absl::flat_hash_map t; + for (int j = 0; j < 100; ++j) { + t[j]; + for (const auto& p : t) EXPECT_THAT(p, Pair(_, _)); + } + garbage.push_back(std::move(t)); + } +} + +// Demonstration of the "Lazy Key" pattern. This uses heterogeneous insert to +// avoid creating expensive key elements when the item is already present in the +// map. +struct LazyInt { + explicit LazyInt(size_t value, int* tracker) + : value(value), tracker(tracker) {} + + explicit operator size_t() const { + ++*tracker; + return value; + } + + size_t value; + int* tracker; +}; + +struct Hash { + using is_transparent = void; + int* tracker; + size_t operator()(size_t obj) const { + ++*tracker; + return obj; + } + size_t operator()(const LazyInt& obj) const { + ++*tracker; + return obj.value; + } +}; + +struct Eq { + using is_transparent = void; + bool operator()(size_t lhs, size_t rhs) const { + return lhs == rhs; + } + bool operator()(size_t lhs, const LazyInt& rhs) const { + return lhs == rhs.value; + } +}; + +TEST(FlatHashMap, LazyKeyPattern) { + // hashes are only guaranteed in opt mode, we use assertions to track internal + // state that can cause extra calls to hash. + int conversions = 0; + int hashes = 0; + flat_hash_map m(0, Hash{&hashes}); + + m[LazyInt(1, &conversions)] = 1; + EXPECT_THAT(m, UnorderedElementsAre(Pair(1, 1))); + EXPECT_EQ(conversions, 1); +#ifdef NDEBUG + EXPECT_EQ(hashes, 1); +#endif + + m[LazyInt(1, &conversions)] = 2; + EXPECT_THAT(m, UnorderedElementsAre(Pair(1, 2))); + EXPECT_EQ(conversions, 1); +#ifdef NDEBUG + EXPECT_EQ(hashes, 2); +#endif + + m.try_emplace(LazyInt(2, &conversions), 3); + EXPECT_THAT(m, UnorderedElementsAre(Pair(1, 2), Pair(2, 3))); + EXPECT_EQ(conversions, 2); +#ifdef NDEBUG + EXPECT_EQ(hashes, 3); +#endif + + m.try_emplace(LazyInt(2, &conversions), 4); + EXPECT_THAT(m, UnorderedElementsAre(Pair(1, 2), Pair(2, 3))); + EXPECT_EQ(conversions, 2); +#ifdef NDEBUG + EXPECT_EQ(hashes, 4); +#endif +} + +TEST(FlatHashMap, BitfieldArgument) { + union { + int n : 1; + }; + n = 0; + flat_hash_map m; + m.erase(n); + m.count(n); + m.prefetch(n); + m.find(n); + m.contains(n); + m.equal_range(n); + m.insert_or_assign(n, n); + m.insert_or_assign(m.end(), n, n); + m.try_emplace(n); + m.try_emplace(m.end(), n); + m.at(n); + m[n]; +} + +TEST(FlatHashMap, MergeExtractInsert) { + // We can't test mutable keys, or non-copyable keys with flat_hash_map. + // Test that the nodes have the proper API. + absl::flat_hash_map m = {{1, 7}, {2, 9}}; + auto node = m.extract(1); + EXPECT_TRUE(node); + EXPECT_EQ(node.key(), 1); + EXPECT_EQ(node.mapped(), 7); + EXPECT_THAT(m, UnorderedElementsAre(Pair(2, 9))); + + node.mapped() = 17; + m.insert(std::move(node)); + EXPECT_THAT(m, UnorderedElementsAre(Pair(1, 17), Pair(2, 9))); +} +#if !defined(__ANDROID__) && !defined(__APPLE__) && !defined(__EMSCRIPTEN__) +TEST(FlatHashMap, Any) { + absl::flat_hash_map m; + m.emplace(1, 7); + auto it = m.find(1); + ASSERT_NE(it, m.end()); + EXPECT_EQ(7, absl::any_cast(it->second)); + + m.emplace(std::piecewise_construct, std::make_tuple(2), std::make_tuple(8)); + it = m.find(2); + ASSERT_NE(it, m.end()); + EXPECT_EQ(8, absl::any_cast(it->second)); + + m.emplace(std::piecewise_construct, std::make_tuple(3), + std::make_tuple(absl::any(9))); + it = m.find(3); + ASSERT_NE(it, m.end()); + EXPECT_EQ(9, absl::any_cast(it->second)); + + struct H { + size_t operator()(const absl::any&) const { return 0; } + }; + struct E { + bool operator()(const absl::any&, const absl::any&) const { return true; } + }; + absl::flat_hash_map m2; + m2.emplace(1, 7); + auto it2 = m2.find(1); + ASSERT_NE(it2, m2.end()); + EXPECT_EQ(7, it2->second); +} +#endif // __ANDROID__ + +} // namespace +} // namespace container_internal +} // namespace absl diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/flat_hash_set.h b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/flat_hash_set.h new file mode 100644 index 0000000..a2584d6 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/flat_hash_set.h @@ -0,0 +1,479 @@ +// Copyright 2018 The Abseil Authors. +// +// 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. +// +// ----------------------------------------------------------------------------- +// File: flat_hash_set.h +// ----------------------------------------------------------------------------- +// +// An `absl::flat_hash_set` is an unordered associative container designed to +// be a more efficient replacement for `std::unordered_set`. Like +// `unordered_set`, search, insertion, and deletion of set elements can be done +// as an `O(1)` operation. However, `flat_hash_set` (and other unordered +// associative containers known as the collection of Abseil "Swiss tables") +// contain other optimizations that result in both memory and computation +// advantages. +// +// In most cases, your default choice for a hash set should be a set of type +// `flat_hash_set`. +#ifndef ABSL_CONTAINER_FLAT_HASH_SET_H_ +#define ABSL_CONTAINER_FLAT_HASH_SET_H_ + +#include +#include + +#include "absl/base/macros.h" +#include "absl/container/internal/container_memory.h" +#include "absl/container/internal/hash_function_defaults.h" // IWYU pragma: export +#include "absl/container/internal/raw_hash_set.h" // IWYU pragma: export +#include "absl/memory/memory.h" + +namespace absl { +namespace container_internal { +template +struct FlatHashSetPolicy; +} // namespace container_internal + +// ----------------------------------------------------------------------------- +// absl::flat_hash_set +// ----------------------------------------------------------------------------- +// +// An `absl::flat_hash_set` is an unordered associative container which has +// been optimized for both speed and memory footprint in most common use cases. +// Its interface is similar to that of `std::unordered_set` with the +// following notable differences: +// +// * Requires keys that are CopyConstructible +// * Supports heterogeneous lookup, through `find()`, `operator[]()` and +// `insert()`, provided that the set is provided a compatible heterogeneous +// hashing function and equality operator. +// * Invalidates any references and pointers to elements within the table after +// `rehash()`. +// * Contains a `capacity()` member function indicating the number of element +// slots (open, deleted, and empty) within the hash set. +// * Returns `void` from the `erase(iterator)` overload. +// +// By default, `flat_hash_set` uses the `absl::Hash` hashing framework. All +// fundamental and Abseil types that support the `absl::Hash` framework have a +// compatible equality operator for comparing insertions into `flat_hash_map`. +// If your type is not yet supported by the `asbl::Hash` framework, see +// absl/hash/hash.h for information on extending Abseil hashing to user-defined +// types. +// +// NOTE: A `flat_hash_set` stores its keys directly inside its implementation +// array to avoid memory indirection. Because a `flat_hash_set` is designed to +// move data when rehashed, set keys will not retain pointer stability. If you +// require pointer stability, consider using +// `absl::flat_hash_set>`. If your type is not moveable and +// you require pointer stability, consider `absl::node_hash_set` instead. +// +// Example: +// +// // Create a flat hash set of three strings +// absl::flat_hash_set ducks = +// {"huey", "dewey", "louie"}; +// +// // Insert a new element into the flat hash set +// ducks.insert("donald"); +// +// // Force a rehash of the flat hash set +// ducks.rehash(0); +// +// // See if "dewey" is present +// if (ducks.contains("dewey")) { +// std::cout << "We found dewey!" << std::endl; +// } +template , + class Eq = absl::container_internal::hash_default_eq, + class Allocator = std::allocator> +class flat_hash_set + : public absl::container_internal::raw_hash_set< + absl::container_internal::FlatHashSetPolicy, Hash, Eq, Allocator> { + using Base = typename flat_hash_set::raw_hash_set; + + public: + // Constructors and Assignment Operators + // + // A flat_hash_set supports the same overload set as `std::unordered_map` + // for construction and assignment: + // + // * Default constructor + // + // // No allocation for the table's elements is made. + // absl::flat_hash_set set1; + // + // * Initializer List constructor + // + // absl::flat_hash_set set2 = + // {{"huey"}, {"dewey"}, {"louie"},}; + // + // * Copy constructor + // + // absl::flat_hash_set set3(set2); + // + // * Copy assignment operator + // + // // Hash functor and Comparator are copied as well + // absl::flat_hash_set set4; + // set4 = set3; + // + // * Move constructor + // + // // Move is guaranteed efficient + // absl::flat_hash_set set5(std::move(set4)); + // + // * Move assignment operator + // + // // May be efficient if allocators are compatible + // absl::flat_hash_set set6; + // set6 = std::move(set5); + // + // * Range constructor + // + // std::vector v = {"a", "b"}; + // absl::flat_hash_set set7(v.begin(), v.end()); + flat_hash_set() {} + using Base::Base; + + // flat_hash_set::begin() + // + // Returns an iterator to the beginning of the `flat_hash_set`. + using Base::begin; + + // flat_hash_set::cbegin() + // + // Returns a const iterator to the beginning of the `flat_hash_set`. + using Base::cbegin; + + // flat_hash_set::cend() + // + // Returns a const iterator to the end of the `flat_hash_set`. + using Base::cend; + + // flat_hash_set::end() + // + // Returns an iterator to the end of the `flat_hash_set`. + using Base::end; + + // flat_hash_set::capacity() + // + // Returns the number of element slots (assigned, deleted, and empty) + // available within the `flat_hash_set`. + // + // NOTE: this member function is particular to `absl::flat_hash_set` and is + // not provided in the `std::unordered_map` API. + using Base::capacity; + + // flat_hash_set::empty() + // + // Returns whether or not the `flat_hash_set` is empty. + using Base::empty; + + // flat_hash_set::max_size() + // + // Returns the largest theoretical possible number of elements within a + // `flat_hash_set` under current memory constraints. This value can be thought + // of the largest value of `std::distance(begin(), end())` for a + // `flat_hash_set`. + using Base::max_size; + + // flat_hash_set::size() + // + // Returns the number of elements currently within the `flat_hash_set`. + using Base::size; + + // flat_hash_set::clear() + // + // Removes all elements from the `flat_hash_set`. Invalidates any references, + // pointers, or iterators referring to contained elements. + // + // NOTE: this operation may shrink the underlying buffer. To avoid shrinking + // the underlying buffer call `erase(begin(), end())`. + using Base::clear; + + // flat_hash_set::erase() + // + // Erases elements within the `flat_hash_set`. Erasing does not trigger a + // rehash. Overloads are listed below. + // + // void erase(const_iterator pos): + // + // Erases the element at `position` of the `flat_hash_set`, returning + // `void`. + // + // NOTE: this return behavior is different than that of STL containers in + // general and `std::unordered_map` in particular. + // + // iterator erase(const_iterator first, const_iterator last): + // + // Erases the elements in the open interval [`first`, `last`), returning an + // iterator pointing to `last`. + // + // size_type erase(const key_type& key): + // + // Erases the element with the matching key, if it exists. + using Base::erase; + + // flat_hash_set::insert() + // + // Inserts an element of the specified value into the `flat_hash_set`, + // returning an iterator pointing to the newly inserted element, provided that + // an element with the given key does not already exist. If rehashing occurs + // due to the insertion, all iterators are invalidated. Overloads are listed + // below. + // + // std::pair insert(const T& value): + // + // Inserts a value into the `flat_hash_set`. Returns a pair consisting of an + // iterator to the inserted element (or to the element that prevented the + // insertion) and a bool denoting whether the insertion took place. + // + // std::pair insert(T&& value): + // + // Inserts a moveable value into the `flat_hash_set`. Returns a pair + // consisting of an iterator to the inserted element (or to the element that + // prevented the insertion) and a bool denoting whether the insertion took + // place. + // + // iterator insert(const_iterator hint, const T& value): + // iterator insert(const_iterator hint, T&& value): + // + // Inserts a value, using the position of `hint` as a non-binding suggestion + // for where to begin the insertion search. Returns an iterator to the + // inserted element, or to the existing element that prevented the + // insertion. + // + // void insert(InputIterator first, InputIterator last): + // + // Inserts a range of values [`first`, `last`). + // + // NOTE: Although the STL does not specify which element may be inserted if + // multiple keys compare equivalently, for `flat_hash_set` we guarantee the + // first match is inserted. + // + // void insert(std::initializer_list ilist): + // + // Inserts the elements within the initializer list `ilist`. + // + // NOTE: Although the STL does not specify which element may be inserted if + // multiple keys compare equivalently within the initializer list, for + // `flat_hash_set` we guarantee the first match is inserted. + using Base::insert; + + // flat_hash_set::emplace() + // + // Inserts an element of the specified value by constructing it in-place + // within the `flat_hash_set`, provided that no element with the given key + // already exists. + // + // The element may be constructed even if there already is an element with the + // key in the container, in which case the newly constructed element will be + // destroyed immediately. Prefer `try_emplace()` unless your key is not + // copyable or moveable. + // + // If rehashing occurs due to the insertion, all iterators are invalidated. + using Base::emplace; + + // flat_hash_set::emplace_hint() + // + // Inserts an element of the specified value by constructing it in-place + // within the `flat_hash_set`, using the position of `hint` as a non-binding + // suggestion for where to begin the insertion search, and only inserts + // provided that no element with the given key already exists. + // + // The element may be constructed even if there already is an element with the + // key in the container, in which case the newly constructed element will be + // destroyed immediately. Prefer `try_emplace()` unless your key is not + // copyable or moveable. + // + // If rehashing occurs due to the insertion, all iterators are invalidated. + using Base::emplace_hint; + + // flat_hash_set::extract() + // + // Extracts the indicated element, erasing it in the process, and returns it + // as a C++17-compatible node handle. Overloads are listed below. + // + // node_type extract(const_iterator position): + // + // Extracts the element at the indicated position and returns a node handle + // owning that extracted data. + // + // node_type extract(const key_type& x): + // + // Extracts the element with the key matching the passed key value and + // returns a node handle owning that extracted data. If the `flat_hash_set` + // does not contain an element with a matching key, this function returns an + // empty node handle. + using Base::extract; + + // flat_hash_set::merge() + // + // Extracts elements from a given `source` flat hash map into this + // `flat_hash_set`. If the destination `flat_hash_set` already contains an + // element with an equivalent key, that element is not extracted. + using Base::merge; + + // flat_hash_set::swap(flat_hash_set& other) + // + // Exchanges the contents of this `flat_hash_set` with those of the `other` + // flat hash map, avoiding invocation of any move, copy, or swap operations on + // individual elements. + // + // All iterators and references on the `flat_hash_set` remain valid, excepting + // for the past-the-end iterator, which is invalidated. + // + // `swap()` requires that the flat hash set's hashing and key equivalence + // functions be Swappable, and are exchaged using unqualified calls to + // non-member `swap()`. If the map's allocator has + // `std::allocator_traits::propagate_on_container_swap::value` + // set to `true`, the allocators are also exchanged using an unqualified call + // to non-member `swap()`; otherwise, the allocators are not swapped. + using Base::swap; + + // flat_hash_set::rehash(count) + // + // Rehashes the `flat_hash_set`, setting the number of slots to be at least + // the passed value. If the new number of slots increases the load factor more + // than the current maximum load factor + // (`count` < `size()` / `max_load_factor()`), then the new number of slots + // will be at least `size()` / `max_load_factor()`. + // + // To force a rehash, pass rehash(0). + // + // NOTE: unlike behavior in `std::unordered_set`, references are also + // invalidated upon a `rehash()`. + using Base::rehash; + + // flat_hash_set::reserve(count) + // + // Sets the number of slots in the `flat_hash_set` to the number needed to + // accommodate at least `count` total elements without exceeding the current + // maximum load factor, and may rehash the container if needed. + using Base::reserve; + + // flat_hash_set::contains() + // + // Determines whether an element comparing equal to the given `key` exists + // within the `flat_hash_set`, returning `true` if so or `false` otherwise. + using Base::contains; + + // flat_hash_set::count(const Key& key) const + // + // Returns the number of elements comparing equal to the given `key` within + // the `flat_hash_set`. note that this function will return either `1` or `0` + // since duplicate elements are not allowed within a `flat_hash_set`. + using Base::count; + + // flat_hash_set::equal_range() + // + // Returns a closed range [first, last], defined by a `std::pair` of two + // iterators, containing all elements with the passed key in the + // `flat_hash_set`. + using Base::equal_range; + + // flat_hash_set::find() + // + // Finds an element with the passed `key` within the `flat_hash_set`. + using Base::find; + + // flat_hash_set::bucket_count() + // + // Returns the number of "buckets" within the `flat_hash_set`. Note that + // because a flat hash map contains all elements within its internal storage, + // this value simply equals the current capacity of the `flat_hash_set`. + using Base::bucket_count; + + // flat_hash_set::load_factor() + // + // Returns the current load factor of the `flat_hash_set` (the average number + // of slots occupied with a value within the hash map). + using Base::load_factor; + + // flat_hash_set::max_load_factor() + // + // Manages the maximum load factor of the `flat_hash_set`. Overloads are + // listed below. + // + // float flat_hash_set::max_load_factor() + // + // Returns the current maximum load factor of the `flat_hash_set`. + // + // void flat_hash_set::max_load_factor(float ml) + // + // Sets the maximum load factor of the `flat_hash_set` to the passed value. + // + // NOTE: This overload is provided only for API compatibility with the STL; + // `flat_hash_set` will ignore any set load factor and manage its rehashing + // internally as an implementation detail. + using Base::max_load_factor; + + // flat_hash_set::get_allocator() + // + // Returns the allocator function associated with this `flat_hash_set`. + using Base::get_allocator; + + // flat_hash_set::hash_function() + // + // Returns the hashing function used to hash the keys within this + // `flat_hash_set`. + using Base::hash_function; + + // flat_hash_set::key_eq() + // + // Returns the function used for comparing keys equality. + using Base::key_eq; +}; + +namespace container_internal { + +template +struct FlatHashSetPolicy { + using slot_type = T; + using key_type = T; + using init_type = T; + using constant_iterators = std::true_type; + + template + static void construct(Allocator* alloc, slot_type* slot, Args&&... args) { + absl::allocator_traits::construct(*alloc, slot, + std::forward(args)...); + } + + template + static void destroy(Allocator* alloc, slot_type* slot) { + absl::allocator_traits::destroy(*alloc, slot); + } + + template + static void transfer(Allocator* alloc, slot_type* new_slot, + slot_type* old_slot) { + construct(alloc, new_slot, std::move(*old_slot)); + destroy(alloc, old_slot); + } + + static T& element(slot_type* slot) { return *slot; } + + template + static decltype(absl::container_internal::DecomposeValue( + std::declval(), std::declval()...)) + apply(F&& f, Args&&... args) { + return absl::container_internal::DecomposeValue( + std::forward(f), std::forward(args)...); + } + + static size_t space_used(const T*) { return 0; } +}; +} // namespace container_internal +} // namespace absl +#endif // ABSL_CONTAINER_FLAT_HASH_SET_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/flat_hash_set_test.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/flat_hash_set_test.cc new file mode 100644 index 0000000..e52fd53 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/flat_hash_set_test.cc @@ -0,0 +1,126 @@ +// Copyright 2018 The Abseil Authors. +// +// 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 "absl/container/flat_hash_set.h" + +#include + +#include "absl/container/internal/hash_generator_testing.h" +#include "absl/container/internal/unordered_set_constructor_test.h" +#include "absl/container/internal/unordered_set_lookup_test.h" +#include "absl/container/internal/unordered_set_modifiers_test.h" +#include "absl/memory/memory.h" +#include "absl/strings/string_view.h" + +namespace absl { +namespace container_internal { +namespace { + +using ::absl::container_internal::hash_internal::Enum; +using ::absl::container_internal::hash_internal::EnumClass; +using ::testing::Pointee; +using ::testing::UnorderedElementsAre; +using ::testing::UnorderedElementsAreArray; + +template +using Set = + absl::flat_hash_set>; + +using SetTypes = + ::testing::Types, Set, Set, Set>; + +INSTANTIATE_TYPED_TEST_CASE_P(FlatHashSet, ConstructorTest, SetTypes); +INSTANTIATE_TYPED_TEST_CASE_P(FlatHashSet, LookupTest, SetTypes); +INSTANTIATE_TYPED_TEST_CASE_P(FlatHashSet, ModifiersTest, SetTypes); + +TEST(FlatHashSet, EmplaceString) { + std::vector v = {"a", "b"}; + absl::flat_hash_set hs(v.begin(), v.end()); + EXPECT_THAT(hs, UnorderedElementsAreArray(v)); +} + +TEST(FlatHashSet, BitfieldArgument) { + union { + int n : 1; + }; + n = 0; + absl::flat_hash_set s = {n}; + s.insert(n); + s.insert(s.end(), n); + s.insert({n}); + s.erase(n); + s.count(n); + s.prefetch(n); + s.find(n); + s.contains(n); + s.equal_range(n); +} + +TEST(FlatHashSet, MergeExtractInsert) { + struct Hash { + size_t operator()(const std::unique_ptr& p) const { return *p; } + }; + struct Eq { + bool operator()(const std::unique_ptr& a, + const std::unique_ptr& b) const { + return *a == *b; + } + }; + absl::flat_hash_set, Hash, Eq> set1, set2; + set1.insert(absl::make_unique(7)); + set1.insert(absl::make_unique(17)); + + set2.insert(absl::make_unique(7)); + set2.insert(absl::make_unique(19)); + + EXPECT_THAT(set1, UnorderedElementsAre(Pointee(7), Pointee(17))); + EXPECT_THAT(set2, UnorderedElementsAre(Pointee(7), Pointee(19))); + + set1.merge(set2); + + EXPECT_THAT(set1, UnorderedElementsAre(Pointee(7), Pointee(17), Pointee(19))); + EXPECT_THAT(set2, UnorderedElementsAre(Pointee(7))); + + auto node = set1.extract(absl::make_unique(7)); + EXPECT_TRUE(node); + EXPECT_THAT(node.value(), Pointee(7)); + EXPECT_THAT(set1, UnorderedElementsAre(Pointee(17), Pointee(19))); + + auto insert_result = set2.insert(std::move(node)); + EXPECT_FALSE(node); + EXPECT_FALSE(insert_result.inserted); + EXPECT_TRUE(insert_result.node); + EXPECT_THAT(insert_result.node.value(), Pointee(7)); + EXPECT_EQ(**insert_result.position, 7); + EXPECT_NE(insert_result.position->get(), insert_result.node.value().get()); + EXPECT_THAT(set2, UnorderedElementsAre(Pointee(7))); + + node = set1.extract(absl::make_unique(17)); + EXPECT_TRUE(node); + EXPECT_THAT(node.value(), Pointee(17)); + EXPECT_THAT(set1, UnorderedElementsAre(Pointee(19))); + + node.value() = absl::make_unique(23); + + insert_result = set2.insert(std::move(node)); + EXPECT_FALSE(node); + EXPECT_TRUE(insert_result.inserted); + EXPECT_FALSE(insert_result.node); + EXPECT_EQ(**insert_result.position, 23); + EXPECT_THAT(set2, UnorderedElementsAre(Pointee(7), Pointee(23))); +} + +} // namespace +} // namespace container_internal +} // namespace absl diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/inlined_vector.h b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/inlined_vector.h new file mode 100644 index 0000000..ea8cb02 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/inlined_vector.h @@ -0,0 +1,1452 @@ +// Copyright 2018 The Abseil Authors. +// +// 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. +// +// ----------------------------------------------------------------------------- +// File: inlined_vector.h +// ----------------------------------------------------------------------------- +// +// This header file contains the declaration and definition of an "inlined +// vector" which behaves in an equivalent fashion to a `std::vector`, except +// that storage for small sequences of the vector are provided inline without +// requiring any heap allocation. + +// An `absl::InlinedVector` specifies the size N at which to inline as one +// of its template parameters. Vectors of length <= N are provided inline. +// Typically N is very small (e.g., 4) so that sequences that are expected to be +// short do not require allocations. + +// An `absl::InlinedVector` does not usually require a specific allocator; if +// the inlined vector grows beyond its initial constraints, it will need to +// allocate (as any normal `std::vector` would) and it will generally use the +// default allocator in that case; optionally, a custom allocator may be +// specified using an `absl::InlinedVector` construction. + +#ifndef ABSL_CONTAINER_INLINED_VECTOR_H_ +#define ABSL_CONTAINER_INLINED_VECTOR_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "absl/algorithm/algorithm.h" +#include "absl/base/internal/throw_delegate.h" +#include "absl/base/optimization.h" +#include "absl/base/port.h" +#include "absl/memory/memory.h" + +namespace absl { + +// ----------------------------------------------------------------------------- +// InlinedVector +// ----------------------------------------------------------------------------- +// +// An `absl::InlinedVector` is designed to be a drop-in replacement for +// `std::vector` for use cases where the vector's size is sufficiently small +// that it can be inlined. If the inlined vector does grow beyond its estimated +// size, it will trigger an initial allocation on the heap, and will behave as a +// `std:vector`. The API of the `absl::InlinedVector` within this file is +// designed to cover the same API footprint as covered by `std::vector`. +template > +class InlinedVector { + constexpr static typename A::size_type inlined_capacity() { + return static_cast(N); + } + + static_assert(inlined_capacity() > 0, "InlinedVector needs inlined capacity"); + + template + using DisableIfIntegral = + absl::enable_if_t::value>; + + template + using EnableIfInputIterator = absl::enable_if_t::iterator_category, + std::input_iterator_tag>::value>; + + template + using IteratorCategory = + typename std::iterator_traits::iterator_category; + + using rvalue_reference = typename A::value_type&&; + + public: + using allocator_type = A; + using value_type = typename allocator_type::value_type; + using pointer = typename allocator_type::pointer; + using const_pointer = typename allocator_type::const_pointer; + using reference = typename allocator_type::reference; + using const_reference = typename allocator_type::const_reference; + using size_type = typename allocator_type::size_type; + using difference_type = typename allocator_type::difference_type; + using iterator = pointer; + using const_iterator = const_pointer; + using reverse_iterator = std::reverse_iterator; + using const_reverse_iterator = std::reverse_iterator; + + + // --------------------------------------------------------------------------- + // InlinedVector Constructors and Destructor + // --------------------------------------------------------------------------- + + // Creates an empty inlined vector with a default initialized allocator. + InlinedVector() noexcept(noexcept(allocator_type())) + : allocator_and_tag_(allocator_type()) {} + + // Creates an empty inlined vector with a specified allocator. + explicit InlinedVector(const allocator_type& alloc) noexcept + : allocator_and_tag_(alloc) {} + + // Creates an inlined vector with `n` copies of `value_type()`. + explicit InlinedVector(size_type n, + const allocator_type& alloc = allocator_type()) + : allocator_and_tag_(alloc) { + InitAssign(n); + } + + // Creates an inlined vector with `n` copies of `v`. + InlinedVector(size_type n, const_reference v, + const allocator_type& alloc = allocator_type()) + : allocator_and_tag_(alloc) { + InitAssign(n, v); + } + + // Creates an inlined vector of copies of the values in `init_list`. + InlinedVector(std::initializer_list init_list, + const allocator_type& alloc = allocator_type()) + : allocator_and_tag_(alloc) { + AppendRange(init_list.begin(), init_list.end()); + } + + // Creates and initialize with the elements [`first`, `last`). + // + // NOTE: The `enable_if` prevents ambiguous interpretation between a call to + // this constructor with two integral arguments and a call to the preceding + // `InlinedVector(n, v)` constructor. + template * = nullptr> + InlinedVector(InputIterator first, InputIterator last, + const allocator_type& alloc = allocator_type()) + : allocator_and_tag_(alloc) { + AppendRange(first, last); + } + + // Creates a copy of `other` using `other`'s allocator. + InlinedVector(const InlinedVector& other); + + // Creates a copy of `other` but with a specified allocator. + InlinedVector(const InlinedVector& other, const allocator_type& alloc); + + // Creates an inlined vector with the contents of `other`. + // + // NOTE: This move constructor does not allocate and only moves the underlying + // objects, so its `noexcept` specification depends on whether moving the + // underlying objects can throw or not. We assume + // a) move constructors should only throw due to allocation failure and + // b) if `value_type`'s move constructor allocates, it uses the same + // allocation function as the `InlinedVector`'s allocator, so the move + // constructor is non-throwing if the allocator is non-throwing or + // `value_type`'s move constructor is specified as `noexcept`. + InlinedVector(InlinedVector&& v) noexcept( + absl::allocator_is_nothrow::value || + std::is_nothrow_move_constructible::value); + + // Creates an inlined vector with the contents of `other`. + // + // NOTE: This move constructor allocates and also moves the underlying + // objects, so its `noexcept` specification depends on whether the allocation + // can throw and whether moving the underlying objects can throw. Based on the + // same assumptions as above, the `noexcept` specification is dominated by + // whether the allocation can throw regardless of whether `value_type`'s move + // constructor is specified as `noexcept`. + InlinedVector(InlinedVector&& v, const allocator_type& alloc) noexcept( + absl::allocator_is_nothrow::value); + + ~InlinedVector() { clear(); } + + + // --------------------------------------------------------------------------- + // InlinedVector Member Accessors + // --------------------------------------------------------------------------- + + // `InlinedVector::empty()` + // + // Checks if the inlined vector has no elements. + bool empty() const noexcept { return !size(); } + + // `InlinedVector::size()` + // + // Returns the number of elements in the inlined vector. + size_type size() const noexcept { return tag().size(); } + + // `InlinedVector::max_size()` + // + // Returns the maximum number of elements the vector can hold. + size_type max_size() const noexcept { + // One bit of the size storage is used to indicate whether the inlined + // vector is allocated. As a result, the maximum size of the container that + // we can express is half of the max for `size_type`. + return (std::numeric_limits::max)() / 2; + } + + // `InlinedVector::capacity()` + // + // Returns the number of elements that can be stored in the inlined vector + // without requiring a reallocation of underlying memory. + // + // NOTE: For most inlined vectors, `capacity()` should equal + // `inlined_capacity()`. For inlined vectors which exceed this capacity, they + // will no longer be inlined and `capacity()` will equal its capacity on the + // allocated heap. + size_type capacity() const noexcept { + return allocated() ? allocation().capacity() : inlined_capacity(); + } + + // `InlinedVector::data()` + // + // Returns a `pointer` to elements of the inlined vector. This pointer can be + // used to access and modify the contained elements. + // Only results within the range [`0`, `size()`) are defined. + pointer data() noexcept { + return allocated() ? allocated_space() : inlined_space(); + } + + // Overload of `InlinedVector::data()` to return a `const_pointer` to elements + // of the inlined vector. This pointer can be used to access (but not modify) + // the contained elements. + const_pointer data() const noexcept { + return allocated() ? allocated_space() : inlined_space(); + } + + // `InlinedVector::operator[]()` + // + // Returns a `reference` to the `i`th element of the inlined vector using the + // array operator. + reference operator[](size_type i) { + assert(i < size()); + return data()[i]; + } + + // Overload of `InlinedVector::operator[]()` to return a `const_reference` to + // the `i`th element of the inlined vector. + const_reference operator[](size_type i) const { + assert(i < size()); + return data()[i]; + } + + // `InlinedVector::at()` + // + // Returns a `reference` to the `i`th element of the inlined vector. + reference at(size_type i) { + if (ABSL_PREDICT_FALSE(i >= size())) { + base_internal::ThrowStdOutOfRange( + "InlinedVector::at() failed bounds check"); + } + return data()[i]; + } + + // Overload of `InlinedVector::at()` to return a `const_reference` to the + // `i`th element of the inlined vector. + const_reference at(size_type i) const { + if (ABSL_PREDICT_FALSE(i >= size())) { + base_internal::ThrowStdOutOfRange( + "InlinedVector::at() failed bounds check"); + } + return data()[i]; + } + + // `InlinedVector::front()` + // + // Returns a `reference` to the first element of the inlined vector. + reference front() { + assert(!empty()); + return at(0); + } + + // Overload of `InlinedVector::front()` returns a `const_reference` to the + // first element of the inlined vector. + const_reference front() const { + assert(!empty()); + return at(0); + } + + // `InlinedVector::back()` + // + // Returns a `reference` to the last element of the inlined vector. + reference back() { + assert(!empty()); + return at(size() - 1); + } + + // Overload of `InlinedVector::back()` to return a `const_reference` to the + // last element of the inlined vector. + const_reference back() const { + assert(!empty()); + return at(size() - 1); + } + + // `InlinedVector::begin()` + // + // Returns an `iterator` to the beginning of the inlined vector. + iterator begin() noexcept { return data(); } + + // Overload of `InlinedVector::begin()` to return a `const_iterator` to + // the beginning of the inlined vector. + const_iterator begin() const noexcept { return data(); } + + // `InlinedVector::end()` + // + // Returns an `iterator` to the end of the inlined vector. + iterator end() noexcept { return data() + size(); } + + // Overload of `InlinedVector::end()` to return a `const_iterator` to the + // end of the inlined vector. + const_iterator end() const noexcept { return data() + size(); } + + // `InlinedVector::cbegin()` + // + // Returns a `const_iterator` to the beginning of the inlined vector. + const_iterator cbegin() const noexcept { return begin(); } + + // `InlinedVector::cend()` + // + // Returns a `const_iterator` to the end of the inlined vector. + const_iterator cend() const noexcept { return end(); } + + // `InlinedVector::rbegin()` + // + // Returns a `reverse_iterator` from the end of the inlined vector. + reverse_iterator rbegin() noexcept { return reverse_iterator(end()); } + + // Overload of `InlinedVector::rbegin()` to return a + // `const_reverse_iterator` from the end of the inlined vector. + const_reverse_iterator rbegin() const noexcept { + return const_reverse_iterator(end()); + } + + // `InlinedVector::rend()` + // + // Returns a `reverse_iterator` from the beginning of the inlined vector. + reverse_iterator rend() noexcept { return reverse_iterator(begin()); } + + // Overload of `InlinedVector::rend()` to return a `const_reverse_iterator` + // from the beginning of the inlined vector. + const_reverse_iterator rend() const noexcept { + return const_reverse_iterator(begin()); + } + + // `InlinedVector::crbegin()` + // + // Returns a `const_reverse_iterator` from the end of the inlined vector. + const_reverse_iterator crbegin() const noexcept { return rbegin(); } + + // `InlinedVector::crend()` + // + // Returns a `const_reverse_iterator` from the beginning of the inlined + // vector. + const_reverse_iterator crend() const noexcept { return rend(); } + + // `InlinedVector::get_allocator()` + // + // Returns a copy of the allocator of the inlined vector. + allocator_type get_allocator() const { return allocator(); } + + + // --------------------------------------------------------------------------- + // InlinedVector Member Mutators + // --------------------------------------------------------------------------- + + // `InlinedVector::operator=()` + // + // Replaces the contents of the inlined vector with copies of the elements in + // the provided `std::initializer_list`. + InlinedVector& operator=(std::initializer_list init_list) { + AssignRange(init_list.begin(), init_list.end()); + return *this; + } + + // Overload of `InlinedVector::operator=()` to replace the contents of the + // inlined vector with the contents of `other`. + InlinedVector& operator=(const InlinedVector& other) { + if (ABSL_PREDICT_FALSE(this == &other)) return *this; + + // Optimized to avoid reallocation. + // Prefer reassignment to copy construction for elements. + if (size() < other.size()) { // grow + reserve(other.size()); + std::copy(other.begin(), other.begin() + size(), begin()); + std::copy(other.begin() + size(), other.end(), std::back_inserter(*this)); + } else { // maybe shrink + erase(begin() + other.size(), end()); + std::copy(other.begin(), other.end(), begin()); + } + return *this; + } + + // Overload of `InlinedVector::operator=()` to replace the contents of the + // inlined vector with the contents of `other`. + // + // NOTE: As a result of calling this overload, `other` may be empty or it's + // contents may be left in a moved-from state. + InlinedVector& operator=(InlinedVector&& other) { + if (ABSL_PREDICT_FALSE(this == &other)) return *this; + + if (other.allocated()) { + clear(); + tag().set_allocated_size(other.size()); + init_allocation(other.allocation()); + other.tag() = Tag(); + } else { + if (allocated()) clear(); + // Both are inlined now. + if (size() < other.size()) { + auto mid = std::make_move_iterator(other.begin() + size()); + std::copy(std::make_move_iterator(other.begin()), mid, begin()); + UninitializedCopy(mid, std::make_move_iterator(other.end()), end()); + } else { + auto new_end = std::copy(std::make_move_iterator(other.begin()), + std::make_move_iterator(other.end()), begin()); + Destroy(new_end, end()); + } + tag().set_inline_size(other.size()); + } + return *this; + } + + // `InlinedVector::assign()` + // + // Replaces the contents of the inlined vector with `n` copies of `v`. + void assign(size_type n, const_reference v) { + if (n <= size()) { // Possibly shrink + std::fill_n(begin(), n, v); + erase(begin() + n, end()); + return; + } + // Grow + reserve(n); + std::fill_n(begin(), size(), v); + if (allocated()) { + UninitializedFill(allocated_space() + size(), allocated_space() + n, v); + tag().set_allocated_size(n); + } else { + UninitializedFill(inlined_space() + size(), inlined_space() + n, v); + tag().set_inline_size(n); + } + } + + // Overload of `InlinedVector::assign()` to replace the contents of the + // inlined vector with copies of the values in the provided + // `std::initializer_list`. + void assign(std::initializer_list init_list) { + AssignRange(init_list.begin(), init_list.end()); + } + + // Overload of `InlinedVector::assign()` to replace the contents of the + // inlined vector with values constructed from the range [`first`, `last`). + template * = nullptr> + void assign(InputIterator first, InputIterator last) { + AssignRange(first, last); + } + + // `InlinedVector::resize()` + // + // Resizes the inlined vector to contain `n` elements. If `n` is smaller than + // the inlined vector's current size, extra elements are destroyed. If `n` is + // larger than the initial size, new elements are value-initialized. + void resize(size_type n); + + // Overload of `InlinedVector::resize()` to resize the inlined vector to + // contain `n` elements where, if `n` is larger than `size()`, the new values + // will be copy-constructed from `v`. + void resize(size_type n, const_reference v); + + // `InlinedVector::insert()` + // + // Copies `v` into `position`, returning an `iterator` pointing to the newly + // inserted element. + iterator insert(const_iterator position, const_reference v) { + return emplace(position, v); + } + + // Overload of `InlinedVector::insert()` for moving `v` into `position`, + // returning an iterator pointing to the newly inserted element. + iterator insert(const_iterator position, rvalue_reference v) { + return emplace(position, std::move(v)); + } + + // Overload of `InlinedVector::insert()` for inserting `n` contiguous copies + // of `v` starting at `position`. Returns an `iterator` pointing to the first + // of the newly inserted elements. + iterator insert(const_iterator position, size_type n, const_reference v) { + return InsertWithCount(position, n, v); + } + + // Overload of `InlinedVector::insert()` for copying the contents of the + // `std::initializer_list` into the vector starting at `position`. Returns an + // `iterator` pointing to the first of the newly inserted elements. + iterator insert(const_iterator position, + std::initializer_list init_list) { + return insert(position, init_list.begin(), init_list.end()); + } + + // Overload of `InlinedVector::insert()` for inserting elements constructed + // from the range [`first`, `last`). Returns an `iterator` pointing to the + // first of the newly inserted elements. + // + // NOTE: The `enable_if` is intended to disambiguate the two three-argument + // overloads of `insert()`. + template > + iterator insert(const_iterator position, InputIterator first, + InputIterator last) { + return InsertWithRange(position, first, last, + IteratorCategory()); + } + + // `InlinedVector::emplace()` + // + // Constructs and inserts an object in the inlined vector at the given + // `position`, returning an `iterator` pointing to the newly emplaced element. + template + iterator emplace(const_iterator position, Args&&... args); + + // `InlinedVector::emplace_back()` + // + // Constructs and appends a new element to the end of the inlined vector, + // returning a `reference` to the emplaced element. + template + reference emplace_back(Args&&... args) { + size_type s = size(); + assert(s <= capacity()); + if (ABSL_PREDICT_FALSE(s == capacity())) { + return GrowAndEmplaceBack(std::forward(args)...); + } + assert(s < capacity()); + + pointer space; + if (allocated()) { + tag().set_allocated_size(s + 1); + space = allocated_space(); + } else { + tag().set_inline_size(s + 1); + space = inlined_space(); + } + return Construct(space + s, std::forward(args)...); + } + + // `InlinedVector::push_back()` + // + // Appends a copy of `v` to the end of the inlined vector. + void push_back(const_reference v) { static_cast(emplace_back(v)); } + + // Overload of `InlinedVector::push_back()` for moving `v` into a newly + // appended element. + void push_back(rvalue_reference v) { + static_cast(emplace_back(std::move(v))); + } + + // `InlinedVector::pop_back()` + // + // Destroys the element at the end of the inlined vector and shrinks the size + // by `1` (unless the inlined vector is empty, in which case this is a no-op). + void pop_back() noexcept { + assert(!empty()); + size_type s = size(); + if (allocated()) { + Destroy(allocated_space() + s - 1, allocated_space() + s); + tag().set_allocated_size(s - 1); + } else { + Destroy(inlined_space() + s - 1, inlined_space() + s); + tag().set_inline_size(s - 1); + } + } + + // `InlinedVector::erase()` + // + // Erases the element at `position` of the inlined vector, returning an + // `iterator` pointing to the first element following the erased element. + // + // NOTE: May return the end iterator, which is not dereferencable. + iterator erase(const_iterator position) { + assert(position >= begin()); + assert(position < end()); + + iterator pos = const_cast(position); + std::move(pos + 1, end(), pos); + pop_back(); + return pos; + } + + // Overload of `InlinedVector::erase()` for erasing all elements in the + // range [`from`, `to`) in the inlined vector. Returns an `iterator` pointing + // to the first element following the range erased or the end iterator if `to` + // was the end iterator. + iterator erase(const_iterator from, const_iterator to); + + // `InlinedVector::clear()` + // + // Destroys all elements in the inlined vector, sets the size of `0` and + // deallocates the heap allocation if the inlined vector was allocated. + void clear() noexcept { + size_type s = size(); + if (allocated()) { + Destroy(allocated_space(), allocated_space() + s); + allocation().Dealloc(allocator()); + } else if (s != 0) { // do nothing for empty vectors + Destroy(inlined_space(), inlined_space() + s); + } + tag() = Tag(); + } + + // `InlinedVector::reserve()` + // + // Enlarges the underlying representation of the inlined vector so it can hold + // at least `n` elements. This method does not change `size()` or the actual + // contents of the vector. + // + // NOTE: If `n` does not exceed `capacity()`, `reserve()` will have no + // effects. Otherwise, `reserve()` will reallocate, performing an n-time + // element-wise move of everything contained. + void reserve(size_type n) { + if (n > capacity()) { + // Make room for new elements + EnlargeBy(n - size()); + } + } + + // `InlinedVector::shrink_to_fit()` + // + // Reduces memory usage by freeing unused memory. After this call, calls to + // `capacity()` will be equal to `(std::max)(inlined_capacity(), size())`. + // + // If `size() <= inlined_capacity()` and the elements are currently stored on + // the heap, they will be moved to the inlined storage and the heap memory + // will be deallocated. + // + // If `size() > inlined_capacity()` and `size() < capacity()` the elements + // will be moved to a smaller heap allocation. + void shrink_to_fit() { + const auto s = size(); + if (ABSL_PREDICT_FALSE(!allocated() || s == capacity())) return; + + if (s <= inlined_capacity()) { + // Move the elements to the inlined storage. + // We have to do this using a temporary, because `inlined_storage` and + // `allocation_storage` are in a union field. + auto temp = std::move(*this); + assign(std::make_move_iterator(temp.begin()), + std::make_move_iterator(temp.end())); + return; + } + + // Reallocate storage and move elements. + // We can't simply use the same approach as above, because `assign()` would + // call into `reserve()` internally and reserve larger capacity than we need + Allocation new_allocation(allocator(), s); + UninitializedCopy(std::make_move_iterator(allocated_space()), + std::make_move_iterator(allocated_space() + s), + new_allocation.buffer()); + ResetAllocation(new_allocation, s); + } + + // `InlinedVector::swap()` + // + // Swaps the contents of this inlined vector with the contents of `other`. + void swap(InlinedVector& other); + + template + friend Hash AbslHashValue(Hash hash, const InlinedVector& inlined_vector) { + const_pointer p = inlined_vector.data(); + size_type n = inlined_vector.size(); + return Hash::combine(Hash::combine_contiguous(std::move(hash), p, n), n); + } + + private: + // Holds whether the vector is allocated or not in the lowest bit and the size + // in the high bits: + // `size_ = (size << 1) | is_allocated;` + class Tag { + public: + Tag() : size_(0) {} + size_type size() const { return size_ / 2; } + void add_size(size_type n) { size_ += n * 2; } + void set_inline_size(size_type n) { size_ = n * 2; } + void set_allocated_size(size_type n) { size_ = (n * 2) + 1; } + bool allocated() const { return size_ % 2; } + + private: + size_type size_; + }; + + // Derives from `allocator_type` to use the empty base class optimization. + // If the `allocator_type` is stateless, we can store our instance for free. + class AllocatorAndTag : private allocator_type { + public: + explicit AllocatorAndTag(const allocator_type& a) : allocator_type(a) {} + + Tag& tag() { return tag_; } + const Tag& tag() const { return tag_; } + + allocator_type& allocator() { return *this; } + const allocator_type& allocator() const { return *this; } + + private: + Tag tag_; + }; + + class Allocation { + public: + Allocation(allocator_type& a, size_type capacity) + : capacity_(capacity), buffer_(Create(a, capacity)) {} + + void Dealloc(allocator_type& a) { + std::allocator_traits::deallocate(a, buffer_, capacity_); + } + + size_type capacity() const { return capacity_; } + + const_pointer buffer() const { return buffer_; } + + pointer buffer() { return buffer_; } + + private: + static pointer Create(allocator_type& a, size_type n) { + return std::allocator_traits::allocate(a, n); + } + + size_type capacity_; + pointer buffer_; + }; + + const Tag& tag() const { return allocator_and_tag_.tag(); } + + Tag& tag() { return allocator_and_tag_.tag(); } + + Allocation& allocation() { + return reinterpret_cast(rep_.allocation_storage.allocation); + } + + const Allocation& allocation() const { + return reinterpret_cast( + rep_.allocation_storage.allocation); + } + + void init_allocation(const Allocation& allocation) { + new (&rep_.allocation_storage.allocation) Allocation(allocation); + } + + // TODO(absl-team): investigate whether the reinterpret_cast is appropriate. + pointer inlined_space() { + return reinterpret_cast( + std::addressof(rep_.inlined_storage.inlined[0])); + } + + const_pointer inlined_space() const { + return reinterpret_cast( + std::addressof(rep_.inlined_storage.inlined[0])); + } + + pointer allocated_space() { return allocation().buffer(); } + + const_pointer allocated_space() const { return allocation().buffer(); } + + const allocator_type& allocator() const { + return allocator_and_tag_.allocator(); + } + + allocator_type& allocator() { return allocator_and_tag_.allocator(); } + + bool allocated() const { return tag().allocated(); } + + // Enlarge the underlying representation so we can store `size_ + delta` elems + // in allocated space. The size is not changed, and any newly added memory is + // not initialized. + void EnlargeBy(size_type delta); + + // Shift all elements from `position` to `end()` by `n` places to the right. + // If the vector needs to be enlarged, memory will be allocated. + // Returns `iterator`s pointing to the start of the previously-initialized + // portion and the start of the uninitialized portion of the created gap. + // The number of initialized spots is `pair.second - pair.first`. The number + // of raw spots is `n - (pair.second - pair.first)`. + // + // Updates the size of the InlinedVector internally. + std::pair ShiftRight(const_iterator position, + size_type n); + + void ResetAllocation(Allocation new_allocation, size_type new_size) { + if (allocated()) { + Destroy(allocated_space(), allocated_space() + size()); + assert(begin() == allocated_space()); + allocation().Dealloc(allocator()); + allocation() = new_allocation; + } else { + Destroy(inlined_space(), inlined_space() + size()); + init_allocation(new_allocation); // bug: only init once + } + tag().set_allocated_size(new_size); + } + + template + reference GrowAndEmplaceBack(Args&&... args) { + assert(size() == capacity()); + const size_type s = size(); + + Allocation new_allocation(allocator(), 2 * capacity()); + + reference new_element = + Construct(new_allocation.buffer() + s, std::forward(args)...); + UninitializedCopy(std::make_move_iterator(data()), + std::make_move_iterator(data() + s), + new_allocation.buffer()); + + ResetAllocation(new_allocation, s + 1); + + return new_element; + } + + void InitAssign(size_type n); + + void InitAssign(size_type n, const_reference v); + + template + reference Construct(pointer p, Args&&... args) { + std::allocator_traits::construct( + allocator(), p, std::forward(args)...); + return *p; + } + + template + void UninitializedCopy(Iterator src, Iterator src_last, pointer dst) { + for (; src != src_last; ++dst, ++src) Construct(dst, *src); + } + + template + void UninitializedFill(pointer dst, pointer dst_last, const Args&... args) { + for (; dst != dst_last; ++dst) Construct(dst, args...); + } + + // Destroy [`from`, `to`) in place. + void Destroy(pointer from, pointer to); + + template + void AppendRange(Iterator first, Iterator last, std::input_iterator_tag) { + std::copy(first, last, std::back_inserter(*this)); + } + + template + void AppendRange(Iterator first, Iterator last, std::forward_iterator_tag); + + template + void AppendRange(Iterator first, Iterator last) { + AppendRange(first, last, IteratorCategory()); + } + + template + void AssignRange(Iterator first, Iterator last, std::input_iterator_tag); + + template + void AssignRange(Iterator first, Iterator last, std::forward_iterator_tag); + + template + void AssignRange(Iterator first, Iterator last) { + AssignRange(first, last, IteratorCategory()); + } + + iterator InsertWithCount(const_iterator position, size_type n, + const_reference v); + + template + iterator InsertWithRange(const_iterator position, InputIterator first, + InputIterator last, std::input_iterator_tag); + + template + iterator InsertWithRange(const_iterator position, ForwardIterator first, + ForwardIterator last, std::forward_iterator_tag); + + // Stores either the inlined or allocated representation + union Rep { + using ValueTypeBuffer = + absl::aligned_storage_t; + using AllocationBuffer = + absl::aligned_storage_t; + + // Structs wrap the buffers to perform indirection that solves a bizarre + // compilation error on Visual Studio (all known versions). + struct InlinedRep { + ValueTypeBuffer inlined[inlined_capacity()]; + }; + struct AllocatedRep { + AllocationBuffer allocation; + }; + + InlinedRep inlined_storage; + AllocatedRep allocation_storage; + }; + + AllocatorAndTag allocator_and_tag_; + Rep rep_; +}; + +// ----------------------------------------------------------------------------- +// InlinedVector Non-Member Functions +// ----------------------------------------------------------------------------- + +// `swap()` +// +// Swaps the contents of two inlined vectors. This convenience function +// simply calls `InlinedVector::swap()`. +template +void swap(InlinedVector& a, + InlinedVector& b) noexcept(noexcept(a.swap(b))) { + a.swap(b); +} + +// `operator==()` +// +// Tests the equivalency of the contents of two inlined vectors. +template +bool operator==(const InlinedVector& a, + const InlinedVector& b) { + return absl::equal(a.begin(), a.end(), b.begin(), b.end()); +} + +// `operator!=()` +// +// Tests the inequality of the contents of two inlined vectors. +template +bool operator!=(const InlinedVector& a, + const InlinedVector& b) { + return !(a == b); +} + +// `operator<()` +// +// Tests whether the contents of one inlined vector are less than the contents +// of another through a lexicographical comparison operation. +template +bool operator<(const InlinedVector& a, + const InlinedVector& b) { + return std::lexicographical_compare(a.begin(), a.end(), b.begin(), b.end()); +} + +// `operator>()` +// +// Tests whether the contents of one inlined vector are greater than the +// contents of another through a lexicographical comparison operation. +template +bool operator>(const InlinedVector& a, + const InlinedVector& b) { + return b < a; +} + +// `operator<=()` +// +// Tests whether the contents of one inlined vector are less than or equal to +// the contents of another through a lexicographical comparison operation. +template +bool operator<=(const InlinedVector& a, + const InlinedVector& b) { + return !(b < a); +} + +// `operator>=()` +// +// Tests whether the contents of one inlined vector are greater than or equal to +// the contents of another through a lexicographical comparison operation. +template +bool operator>=(const InlinedVector& a, + const InlinedVector& b) { + return !(a < b); +} + +// ----------------------------------------------------------------------------- +// Implementation of InlinedVector +// +// Do not depend on any below implementation details! +// ----------------------------------------------------------------------------- + +template +InlinedVector::InlinedVector(const InlinedVector& other) + : allocator_and_tag_(other.allocator()) { + reserve(other.size()); + if (allocated()) { + UninitializedCopy(other.begin(), other.end(), allocated_space()); + tag().set_allocated_size(other.size()); + } else { + UninitializedCopy(other.begin(), other.end(), inlined_space()); + tag().set_inline_size(other.size()); + } +} + +template +InlinedVector::InlinedVector(const InlinedVector& other, + const allocator_type& alloc) + : allocator_and_tag_(alloc) { + reserve(other.size()); + if (allocated()) { + UninitializedCopy(other.begin(), other.end(), allocated_space()); + tag().set_allocated_size(other.size()); + } else { + UninitializedCopy(other.begin(), other.end(), inlined_space()); + tag().set_inline_size(other.size()); + } +} + +template +InlinedVector::InlinedVector(InlinedVector&& other) noexcept( + absl::allocator_is_nothrow::value || + std::is_nothrow_move_constructible::value) + : allocator_and_tag_(other.allocator_and_tag_) { + if (other.allocated()) { + // We can just steal the underlying buffer from the source. + // That leaves the source empty, so we clear its size. + init_allocation(other.allocation()); + other.tag() = Tag(); + } else { + UninitializedCopy( + std::make_move_iterator(other.inlined_space()), + std::make_move_iterator(other.inlined_space() + other.size()), + inlined_space()); + } +} + +template +InlinedVector::InlinedVector(InlinedVector&& other, + const allocator_type& alloc) noexcept( // + absl::allocator_is_nothrow::value) + : allocator_and_tag_(alloc) { + if (other.allocated()) { + if (alloc == other.allocator()) { + // We can just steal the allocation from the source. + tag() = other.tag(); + init_allocation(other.allocation()); + other.tag() = Tag(); + } else { + // We need to use our own allocator + reserve(other.size()); + UninitializedCopy(std::make_move_iterator(other.begin()), + std::make_move_iterator(other.end()), + allocated_space()); + tag().set_allocated_size(other.size()); + } + } else { + UninitializedCopy( + std::make_move_iterator(other.inlined_space()), + std::make_move_iterator(other.inlined_space() + other.size()), + inlined_space()); + tag().set_inline_size(other.size()); + } +} + +template +void InlinedVector::InitAssign(size_type n, const_reference v) { + if (n > inlined_capacity()) { + Allocation new_allocation(allocator(), n); + init_allocation(new_allocation); + UninitializedFill(allocated_space(), allocated_space() + n, v); + tag().set_allocated_size(n); + } else { + UninitializedFill(inlined_space(), inlined_space() + n, v); + tag().set_inline_size(n); + } +} + +template +void InlinedVector::InitAssign(size_type n) { + if (n > inlined_capacity()) { + Allocation new_allocation(allocator(), n); + init_allocation(new_allocation); + UninitializedFill(allocated_space(), allocated_space() + n); + tag().set_allocated_size(n); + } else { + UninitializedFill(inlined_space(), inlined_space() + n); + tag().set_inline_size(n); + } +} + +template +void InlinedVector::resize(size_type n) { + size_type s = size(); + if (n < s) { + erase(begin() + n, end()); + return; + } + reserve(n); + assert(capacity() >= n); + + // Fill new space with elements constructed in-place. + if (allocated()) { + UninitializedFill(allocated_space() + s, allocated_space() + n); + tag().set_allocated_size(n); + } else { + UninitializedFill(inlined_space() + s, inlined_space() + n); + tag().set_inline_size(n); + } +} + +template +void InlinedVector::resize(size_type n, const_reference v) { + size_type s = size(); + if (n < s) { + erase(begin() + n, end()); + return; + } + reserve(n); + assert(capacity() >= n); + + // Fill new space with copies of 'v'. + if (allocated()) { + UninitializedFill(allocated_space() + s, allocated_space() + n, v); + tag().set_allocated_size(n); + } else { + UninitializedFill(inlined_space() + s, inlined_space() + n, v); + tag().set_inline_size(n); + } +} + +template +template +auto InlinedVector::emplace(const_iterator position, Args&&... args) + -> iterator { + assert(position >= begin()); + assert(position <= end()); + if (ABSL_PREDICT_FALSE(position == end())) { + emplace_back(std::forward(args)...); + return end() - 1; + } + + T new_t = T(std::forward(args)...); + + auto range = ShiftRight(position, 1); + if (range.first == range.second) { + // constructing into uninitialized memory + Construct(range.first, std::move(new_t)); + } else { + // assigning into moved-from object + *range.first = T(std::move(new_t)); + } + + return range.first; +} + +template +auto InlinedVector::erase(const_iterator from, const_iterator to) + -> iterator { + assert(begin() <= from); + assert(from <= to); + assert(to <= end()); + + iterator range_start = const_cast(from); + iterator range_end = const_cast(to); + + size_type s = size(); + ptrdiff_t erase_gap = std::distance(range_start, range_end); + if (erase_gap > 0) { + pointer space; + if (allocated()) { + space = allocated_space(); + tag().set_allocated_size(s - erase_gap); + } else { + space = inlined_space(); + tag().set_inline_size(s - erase_gap); + } + std::move(range_end, space + s, range_start); + Destroy(space + s - erase_gap, space + s); + } + return range_start; +} + +template +void InlinedVector::swap(InlinedVector& other) { + using std::swap; // Augment ADL with `std::swap`. + if (ABSL_PREDICT_FALSE(this == &other)) return; + + if (allocated() && other.allocated()) { + // Both out of line, so just swap the tag, allocation, and allocator. + swap(tag(), other.tag()); + swap(allocation(), other.allocation()); + swap(allocator(), other.allocator()); + return; + } + if (!allocated() && !other.allocated()) { + // Both inlined: swap up to smaller size, then move remaining elements. + InlinedVector* a = this; + InlinedVector* b = &other; + if (size() < other.size()) { + swap(a, b); + } + + const size_type a_size = a->size(); + const size_type b_size = b->size(); + assert(a_size >= b_size); + // `a` is larger. Swap the elements up to the smaller array size. + std::swap_ranges(a->inlined_space(), a->inlined_space() + b_size, + b->inlined_space()); + + // Move the remaining elements: + // [`b_size`, `a_size`) from `a` -> [`b_size`, `a_size`) from `b` + b->UninitializedCopy(a->inlined_space() + b_size, + a->inlined_space() + a_size, + b->inlined_space() + b_size); + a->Destroy(a->inlined_space() + b_size, a->inlined_space() + a_size); + + swap(a->tag(), b->tag()); + swap(a->allocator(), b->allocator()); + assert(b->size() == a_size); + assert(a->size() == b_size); + return; + } + + // One is out of line, one is inline. + // We first move the elements from the inlined vector into the + // inlined space in the other vector. We then put the other vector's + // pointer/capacity into the originally inlined vector and swap + // the tags. + InlinedVector* a = this; + InlinedVector* b = &other; + if (a->allocated()) { + swap(a, b); + } + assert(!a->allocated()); + assert(b->allocated()); + const size_type a_size = a->size(); + const size_type b_size = b->size(); + // In an optimized build, `b_size` would be unused. + static_cast(b_size); + + // Made Local copies of `size()`, don't need `tag()` accurate anymore + swap(a->tag(), b->tag()); + + // Copy `b_allocation` out before `b`'s union gets clobbered by `inline_space` + Allocation b_allocation = b->allocation(); + + b->UninitializedCopy(a->inlined_space(), a->inlined_space() + a_size, + b->inlined_space()); + a->Destroy(a->inlined_space(), a->inlined_space() + a_size); + + a->allocation() = b_allocation; + + if (a->allocator() != b->allocator()) { + swap(a->allocator(), b->allocator()); + } + + assert(b->size() == a_size); + assert(a->size() == b_size); +} + +template +void InlinedVector::EnlargeBy(size_type delta) { + const size_type s = size(); + assert(s <= capacity()); + + size_type target = std::max(inlined_capacity(), s + delta); + + // Compute new capacity by repeatedly doubling current capacity + // TODO(psrc): Check and avoid overflow? + size_type new_capacity = capacity(); + while (new_capacity < target) { + new_capacity <<= 1; + } + + Allocation new_allocation(allocator(), new_capacity); + + UninitializedCopy(std::make_move_iterator(data()), + std::make_move_iterator(data() + s), + new_allocation.buffer()); + + ResetAllocation(new_allocation, s); +} + +template +auto InlinedVector::ShiftRight(const_iterator position, size_type n) + -> std::pair { + iterator start_used = const_cast(position); + iterator start_raw = const_cast(position); + size_type s = size(); + size_type required_size = s + n; + + if (required_size > capacity()) { + // Compute new capacity by repeatedly doubling current capacity + size_type new_capacity = capacity(); + while (new_capacity < required_size) { + new_capacity <<= 1; + } + // Move everyone into the new allocation, leaving a gap of `n` for the + // requested shift. + Allocation new_allocation(allocator(), new_capacity); + size_type index = position - begin(); + UninitializedCopy(std::make_move_iterator(data()), + std::make_move_iterator(data() + index), + new_allocation.buffer()); + UninitializedCopy(std::make_move_iterator(data() + index), + std::make_move_iterator(data() + s), + new_allocation.buffer() + index + n); + ResetAllocation(new_allocation, s); + + // New allocation means our iterator is invalid, so we'll recalculate. + // Since the entire gap is in new space, there's no used space to reuse. + start_raw = begin() + index; + start_used = start_raw; + } else { + // If we had enough space, it's a two-part move. Elements going into + // previously-unoccupied space need an `UninitializedCopy()`. Elements + // going into a previously-occupied space are just a `std::move()`. + iterator pos = const_cast(position); + iterator raw_space = end(); + size_type slots_in_used_space = raw_space - pos; + size_type new_elements_in_used_space = std::min(n, slots_in_used_space); + size_type new_elements_in_raw_space = n - new_elements_in_used_space; + size_type old_elements_in_used_space = + slots_in_used_space - new_elements_in_used_space; + + UninitializedCopy(std::make_move_iterator(pos + old_elements_in_used_space), + std::make_move_iterator(raw_space), + raw_space + new_elements_in_raw_space); + std::move_backward(pos, pos + old_elements_in_used_space, raw_space); + + // If the gap is entirely in raw space, the used space starts where the raw + // space starts, leaving no elements in used space. If the gap is entirely + // in used space, the raw space starts at the end of the gap, leaving all + // elements accounted for within the used space. + start_used = pos; + start_raw = pos + new_elements_in_used_space; + } + tag().add_size(n); + return std::make_pair(start_used, start_raw); +} + +template +void InlinedVector::Destroy(pointer from, pointer to) { + for (pointer cur = from; cur != to; ++cur) { + std::allocator_traits::destroy(allocator(), cur); + } +#ifndef NDEBUG + // Overwrite unused memory with `0xab` so we can catch uninitialized usage. + // Cast to `void*` to tell the compiler that we don't care that we might be + // scribbling on a vtable pointer. + if (from != to) { + auto len = sizeof(value_type) * std::distance(from, to); + std::memset(reinterpret_cast(from), 0xab, len); + } +#endif +} + +template +template +void InlinedVector::AppendRange(Iterator first, Iterator last, + std::forward_iterator_tag) { + auto length = std::distance(first, last); + reserve(size() + length); + if (allocated()) { + UninitializedCopy(first, last, allocated_space() + size()); + tag().set_allocated_size(size() + length); + } else { + UninitializedCopy(first, last, inlined_space() + size()); + tag().set_inline_size(size() + length); + } +} + +template +template +void InlinedVector::AssignRange(Iterator first, Iterator last, + std::input_iterator_tag) { + // Optimized to avoid reallocation. + // Prefer reassignment to copy construction for elements. + iterator out = begin(); + for (; first != last && out != end(); ++first, ++out) { + *out = *first; + } + erase(out, end()); + std::copy(first, last, std::back_inserter(*this)); +} + +template +template +void InlinedVector::AssignRange(Iterator first, Iterator last, + std::forward_iterator_tag) { + auto length = std::distance(first, last); + // Prefer reassignment to copy construction for elements. + if (static_cast(length) <= size()) { + erase(std::copy(first, last, begin()), end()); + return; + } + reserve(length); + iterator out = begin(); + for (; out != end(); ++first, ++out) *out = *first; + if (allocated()) { + UninitializedCopy(first, last, out); + tag().set_allocated_size(length); + } else { + UninitializedCopy(first, last, out); + tag().set_inline_size(length); + } +} + +template +auto InlinedVector::InsertWithCount(const_iterator position, + size_type n, const_reference v) + -> iterator { + assert(position >= begin() && position <= end()); + if (ABSL_PREDICT_FALSE(n == 0)) return const_cast(position); + + value_type copy = v; + std::pair it_pair = ShiftRight(position, n); + std::fill(it_pair.first, it_pair.second, copy); + UninitializedFill(it_pair.second, it_pair.first + n, copy); + + return it_pair.first; +} + +template +template +auto InlinedVector::InsertWithRange(const_iterator position, + InputIterator first, + InputIterator last, + std::input_iterator_tag) + -> iterator { + assert(position >= begin() && position <= end()); + size_type index = position - cbegin(); + size_type i = index; + while (first != last) insert(begin() + i++, *first++); + return begin() + index; +} + +template +template +auto InlinedVector::InsertWithRange(const_iterator position, + ForwardIterator first, + ForwardIterator last, + std::forward_iterator_tag) + -> iterator { + assert(position >= begin() && position <= end()); + if (ABSL_PREDICT_FALSE(first == last)) return const_cast(position); + + auto n = std::distance(first, last); + std::pair it_pair = ShiftRight(position, n); + size_type used_spots = it_pair.second - it_pair.first; + ForwardIterator open_spot = std::next(first, used_spots); + std::copy(first, open_spot, it_pair.first); + UninitializedCopy(open_spot, last, it_pair.second); + return it_pair.first; +} + +} // namespace absl + +#endif // ABSL_CONTAINER_INLINED_VECTOR_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/inlined_vector_benchmark.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/inlined_vector_benchmark.cc new file mode 100644 index 0000000..a3ad0f8 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/inlined_vector_benchmark.cc @@ -0,0 +1,385 @@ +// Copyright 2017 The Abseil Authors. +// +// 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 "absl/container/inlined_vector.h" + +#include +#include + +#include "benchmark/benchmark.h" +#include "absl/base/internal/raw_logging.h" +#include "absl/strings/str_cat.h" + +namespace { + +using IntVec = absl::InlinedVector; + +void BM_InlinedVectorFill(benchmark::State& state) { + const int len = state.range(0); + for (auto _ : state) { + IntVec v; + for (int i = 0; i < len; i++) { + v.push_back(i); + } + } + state.SetItemsProcessed(static_cast(state.iterations()) * len); +} +BENCHMARK(BM_InlinedVectorFill)->Range(0, 1024); + +void BM_InlinedVectorFillRange(benchmark::State& state) { + const int len = state.range(0); + std::unique_ptr ia(new int[len]); + for (int i = 0; i < len; i++) { + ia[i] = i; + } + for (auto _ : state) { + IntVec v(ia.get(), ia.get() + len); + benchmark::DoNotOptimize(v); + } + state.SetItemsProcessed(static_cast(state.iterations()) * len); +} +BENCHMARK(BM_InlinedVectorFillRange)->Range(0, 1024); + +void BM_StdVectorFill(benchmark::State& state) { + const int len = state.range(0); + for (auto _ : state) { + std::vector v; + for (int i = 0; i < len; i++) { + v.push_back(i); + } + } + state.SetItemsProcessed(static_cast(state.iterations()) * len); +} +BENCHMARK(BM_StdVectorFill)->Range(0, 1024); + +// The purpose of the next two benchmarks is to verify that +// absl::InlinedVector is efficient when moving is more efficent than +// copying. To do so, we use strings that are larger than the short +// string optimization. +bool StringRepresentedInline(std::string s) { + const char* chars = s.data(); + std::string s1 = std::move(s); + return s1.data() != chars; +} + +int GetNonShortStringOptimizationSize() { + for (int i = 24; i <= 192; i *= 2) { + if (!StringRepresentedInline(std::string(i, 'A'))) { + return i; + } + } + ABSL_RAW_LOG( + FATAL, + "Failed to find a std::string larger than the short std::string optimization"); + return -1; +} + +void BM_InlinedVectorFillString(benchmark::State& state) { + const int len = state.range(0); + const int no_sso = GetNonShortStringOptimizationSize(); + std::string strings[4] = {std::string(no_sso, 'A'), std::string(no_sso, 'B'), + std::string(no_sso, 'C'), std::string(no_sso, 'D')}; + + for (auto _ : state) { + absl::InlinedVector v; + for (int i = 0; i < len; i++) { + v.push_back(strings[i & 3]); + } + } + state.SetItemsProcessed(static_cast(state.iterations()) * len); +} +BENCHMARK(BM_InlinedVectorFillString)->Range(0, 1024); + +void BM_StdVectorFillString(benchmark::State& state) { + const int len = state.range(0); + const int no_sso = GetNonShortStringOptimizationSize(); + std::string strings[4] = {std::string(no_sso, 'A'), std::string(no_sso, 'B'), + std::string(no_sso, 'C'), std::string(no_sso, 'D')}; + + for (auto _ : state) { + std::vector v; + for (int i = 0; i < len; i++) { + v.push_back(strings[i & 3]); + } + } + state.SetItemsProcessed(static_cast(state.iterations()) * len); +} +BENCHMARK(BM_StdVectorFillString)->Range(0, 1024); + +struct Buffer { // some arbitrary structure for benchmarking. + char* base; + int length; + int capacity; + void* user_data; +}; + +void BM_InlinedVectorTenAssignments(benchmark::State& state) { + const int len = state.range(0); + using BufferVec = absl::InlinedVector; + + BufferVec src; + src.resize(len); + + BufferVec dst; + for (auto _ : state) { + for (int i = 0; i < 10; ++i) { + dst = src; + } + } +} +BENCHMARK(BM_InlinedVectorTenAssignments) + ->Arg(0)->Arg(1)->Arg(2)->Arg(3)->Arg(4)->Arg(20); + +void BM_CreateFromContainer(benchmark::State& state) { + for (auto _ : state) { + absl::InlinedVector x(absl::InlinedVector{1, 2, 3}); + benchmark::DoNotOptimize(x); + } +} +BENCHMARK(BM_CreateFromContainer); + +struct LargeCopyableOnly { + LargeCopyableOnly() : d(1024, 17) {} + LargeCopyableOnly(const LargeCopyableOnly& o) = default; + LargeCopyableOnly& operator=(const LargeCopyableOnly& o) = default; + + std::vector d; +}; + +struct LargeCopyableSwappable { + LargeCopyableSwappable() : d(1024, 17) {} + LargeCopyableSwappable(const LargeCopyableSwappable& o) = default; + LargeCopyableSwappable(LargeCopyableSwappable&& o) = delete; + + LargeCopyableSwappable& operator=(LargeCopyableSwappable o) { + using std::swap; + swap(*this, o); + return *this; + } + LargeCopyableSwappable& operator=(LargeCopyableSwappable&& o) = delete; + + friend void swap(LargeCopyableSwappable& a, LargeCopyableSwappable& b) { + using std::swap; + swap(a.d, b.d); + } + + std::vector d; +}; + +struct LargeCopyableMovable { + LargeCopyableMovable() : d(1024, 17) {} + // Use implicitly defined copy and move. + + std::vector d; +}; + +struct LargeCopyableMovableSwappable { + LargeCopyableMovableSwappable() : d(1024, 17) {} + LargeCopyableMovableSwappable(const LargeCopyableMovableSwappable& o) = + default; + LargeCopyableMovableSwappable(LargeCopyableMovableSwappable&& o) = default; + + LargeCopyableMovableSwappable& operator=(LargeCopyableMovableSwappable o) { + using std::swap; + swap(*this, o); + return *this; + } + LargeCopyableMovableSwappable& operator=(LargeCopyableMovableSwappable&& o) = + default; + + friend void swap(LargeCopyableMovableSwappable& a, + LargeCopyableMovableSwappable& b) { + using std::swap; + swap(a.d, b.d); + } + + std::vector d; +}; + +template +void BM_SwapElements(benchmark::State& state) { + const int len = state.range(0); + using Vec = absl::InlinedVector; + Vec a(len); + Vec b; + for (auto _ : state) { + using std::swap; + swap(a, b); + } +} +BENCHMARK_TEMPLATE(BM_SwapElements, LargeCopyableOnly)->Range(0, 1024); +BENCHMARK_TEMPLATE(BM_SwapElements, LargeCopyableSwappable)->Range(0, 1024); +BENCHMARK_TEMPLATE(BM_SwapElements, LargeCopyableMovable)->Range(0, 1024); +BENCHMARK_TEMPLATE(BM_SwapElements, LargeCopyableMovableSwappable) + ->Range(0, 1024); + +// The following benchmark is meant to track the efficiency of the vector size +// as a function of stored type via the benchmark label. It is not meant to +// output useful sizeof operator performance. The loop is a dummy operation +// to fulfill the requirement of running the benchmark. +template +void BM_Sizeof(benchmark::State& state) { + int size = 0; + for (auto _ : state) { + VecType vec; + size = sizeof(vec); + } + state.SetLabel(absl::StrCat("sz=", size)); +} +BENCHMARK_TEMPLATE(BM_Sizeof, absl::InlinedVector); +BENCHMARK_TEMPLATE(BM_Sizeof, absl::InlinedVector); +BENCHMARK_TEMPLATE(BM_Sizeof, absl::InlinedVector); +BENCHMARK_TEMPLATE(BM_Sizeof, absl::InlinedVector); + +BENCHMARK_TEMPLATE(BM_Sizeof, absl::InlinedVector); +BENCHMARK_TEMPLATE(BM_Sizeof, absl::InlinedVector); +BENCHMARK_TEMPLATE(BM_Sizeof, absl::InlinedVector); +BENCHMARK_TEMPLATE(BM_Sizeof, absl::InlinedVector); + +BENCHMARK_TEMPLATE(BM_Sizeof, absl::InlinedVector); +BENCHMARK_TEMPLATE(BM_Sizeof, absl::InlinedVector); +BENCHMARK_TEMPLATE(BM_Sizeof, absl::InlinedVector); +BENCHMARK_TEMPLATE(BM_Sizeof, absl::InlinedVector); + +BENCHMARK_TEMPLATE(BM_Sizeof, absl::InlinedVector); +BENCHMARK_TEMPLATE(BM_Sizeof, absl::InlinedVector); +BENCHMARK_TEMPLATE(BM_Sizeof, absl::InlinedVector); +BENCHMARK_TEMPLATE(BM_Sizeof, absl::InlinedVector); + +void BM_InlinedVectorIndexInlined(benchmark::State& state) { + absl::InlinedVector v = {1, 2, 3, 4, 5, 6, 7}; + for (auto _ : state) { + for (int i = 0; i < 1000; ++i) { + benchmark::DoNotOptimize(v); + benchmark::DoNotOptimize(v[4]); + } + } + state.SetItemsProcessed(1000 * static_cast(state.iterations())); +} +BENCHMARK(BM_InlinedVectorIndexInlined); + +void BM_InlinedVectorIndexExternal(benchmark::State& state) { + absl::InlinedVector v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + for (auto _ : state) { + for (int i = 0; i < 1000; ++i) { + benchmark::DoNotOptimize(v); + benchmark::DoNotOptimize(v[4]); + } + } + state.SetItemsProcessed(1000 * static_cast(state.iterations())); +} +BENCHMARK(BM_InlinedVectorIndexExternal); + +void BM_StdVectorIndex(benchmark::State& state) { + std::vector v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + for (auto _ : state) { + for (int i = 0; i < 1000; ++i) { + benchmark::DoNotOptimize(v); + benchmark::DoNotOptimize(v[4]); + } + } + state.SetItemsProcessed(1000 * static_cast(state.iterations())); +} +BENCHMARK(BM_StdVectorIndex); + +#define UNROLL_2(x) \ + benchmark::DoNotOptimize(x); \ + benchmark::DoNotOptimize(x); + +#define UNROLL_4(x) UNROLL_2(x) UNROLL_2(x) +#define UNROLL_8(x) UNROLL_4(x) UNROLL_4(x) +#define UNROLL_16(x) UNROLL_8(x) UNROLL_8(x); + +void BM_InlinedVectorDataInlined(benchmark::State& state) { + absl::InlinedVector v = {1, 2, 3, 4, 5, 6, 7}; + for (auto _ : state) { + UNROLL_16(v.data()); + } + state.SetItemsProcessed(16 * static_cast(state.iterations())); +} +BENCHMARK(BM_InlinedVectorDataInlined); + +void BM_InlinedVectorDataExternal(benchmark::State& state) { + absl::InlinedVector v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + for (auto _ : state) { + UNROLL_16(v.data()); + } + state.SetItemsProcessed(16 * static_cast(state.iterations())); +} +BENCHMARK(BM_InlinedVectorDataExternal); + +void BM_StdVectorData(benchmark::State& state) { + std::vector v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + for (auto _ : state) { + UNROLL_16(v.data()); + } + state.SetItemsProcessed(16 * static_cast(state.iterations())); +} +BENCHMARK(BM_StdVectorData); + +void BM_InlinedVectorSizeInlined(benchmark::State& state) { + absl::InlinedVector v = {1, 2, 3, 4, 5, 6, 7}; + for (auto _ : state) { + UNROLL_16(v.size()); + } + state.SetItemsProcessed(16 * static_cast(state.iterations())); +} +BENCHMARK(BM_InlinedVectorSizeInlined); + +void BM_InlinedVectorSizeExternal(benchmark::State& state) { + absl::InlinedVector v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + for (auto _ : state) { + UNROLL_16(v.size()); + } + state.SetItemsProcessed(16 * static_cast(state.iterations())); +} +BENCHMARK(BM_InlinedVectorSizeExternal); + +void BM_StdVectorSize(benchmark::State& state) { + std::vector v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + for (auto _ : state) { + UNROLL_16(v.size()); + } + state.SetItemsProcessed(16 * static_cast(state.iterations())); +} +BENCHMARK(BM_StdVectorSize); + +void BM_InlinedVectorEmptyInlined(benchmark::State& state) { + absl::InlinedVector v = {1, 2, 3, 4, 5, 6, 7}; + for (auto _ : state) { + UNROLL_16(v.empty()); + } + state.SetItemsProcessed(16 * static_cast(state.iterations())); +} +BENCHMARK(BM_InlinedVectorEmptyInlined); + +void BM_InlinedVectorEmptyExternal(benchmark::State& state) { + absl::InlinedVector v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + for (auto _ : state) { + UNROLL_16(v.empty()); + } + state.SetItemsProcessed(16 * static_cast(state.iterations())); +} +BENCHMARK(BM_InlinedVectorEmptyExternal); + +void BM_StdVectorEmpty(benchmark::State& state) { + std::vector v = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; + for (auto _ : state) { + UNROLL_16(v.empty()); + } + state.SetItemsProcessed(16 * static_cast(state.iterations())); +} +BENCHMARK(BM_StdVectorEmpty); + +} // namespace diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/inlined_vector_test.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/inlined_vector_test.cc new file mode 100644 index 0000000..5485f45 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/inlined_vector_test.cc @@ -0,0 +1,1795 @@ +// Copyright 2017 The Abseil Authors. +// +// 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 "absl/container/inlined_vector.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gmock/gmock.h" +#include "gtest/gtest.h" +#include "absl/base/attributes.h" +#include "absl/base/internal/exception_testing.h" +#include "absl/base/internal/raw_logging.h" +#include "absl/base/macros.h" +#include "absl/container/internal/test_instance_tracker.h" +#include "absl/hash/hash_testing.h" +#include "absl/memory/memory.h" +#include "absl/strings/str_cat.h" + +namespace { + +using absl::test_internal::CopyableMovableInstance; +using absl::test_internal::CopyableOnlyInstance; +using absl::test_internal::InstanceTracker; +using testing::AllOf; +using testing::Each; +using testing::ElementsAre; +using testing::ElementsAreArray; +using testing::Eq; +using testing::Gt; +using testing::PrintToString; + +using IntVec = absl::InlinedVector; + +MATCHER_P(SizeIs, n, "") { + return testing::ExplainMatchResult(n, arg.size(), result_listener); +} + +MATCHER_P(CapacityIs, n, "") { + return testing::ExplainMatchResult(n, arg.capacity(), result_listener); +} + +MATCHER_P(ValueIs, e, "") { + return testing::ExplainMatchResult(e, arg.value(), result_listener); +} + +// TODO(bsamwel): Add support for movable-only types. + +// Test fixture for typed tests on BaseCountedInstance derived classes, see +// test_instance_tracker.h. +template +class InstanceTest : public ::testing::Test {}; +TYPED_TEST_CASE_P(InstanceTest); + +// A simple reference counted class to make sure that the proper elements are +// destroyed in the erase(begin, end) test. +class RefCounted { + public: + RefCounted(int value, int* count) : value_(value), count_(count) { + Ref(); + } + + RefCounted(const RefCounted& v) + : value_(v.value_), count_(v.count_) { + Ref(); + } + + ~RefCounted() { + Unref(); + count_ = nullptr; + } + + friend void swap(RefCounted& a, RefCounted& b) { + using std::swap; + swap(a.value_, b.value_); + swap(a.count_, b.count_); + } + + RefCounted& operator=(RefCounted v) { + using std::swap; + swap(*this, v); + return *this; + } + + void Ref() const { + ABSL_RAW_CHECK(count_ != nullptr, ""); + ++(*count_); + } + + void Unref() const { + --(*count_); + ABSL_RAW_CHECK(*count_ >= 0, ""); + } + + int value_; + int* count_; +}; + +using RefCountedVec = absl::InlinedVector; + +// A class with a vtable pointer +class Dynamic { + public: + virtual ~Dynamic() {} +}; + +using DynamicVec = absl::InlinedVector; + +// Append 0..len-1 to *v +template +static void Fill(Container* v, int len, int offset = 0) { + for (int i = 0; i < len; i++) { + v->push_back(i + offset); + } +} + +static IntVec Fill(int len, int offset = 0) { + IntVec v; + Fill(&v, len, offset); + return v; +} + +// This is a stateful allocator, but the state lives outside of the +// allocator (in whatever test is using the allocator). This is odd +// but helps in tests where the allocator is propagated into nested +// containers - that chain of allocators uses the same state and is +// thus easier to query for aggregate allocation information. +template +class CountingAllocator : public std::allocator { + public: + using Alloc = std::allocator; + using pointer = typename Alloc::pointer; + using size_type = typename Alloc::size_type; + + CountingAllocator() : bytes_used_(nullptr) {} + explicit CountingAllocator(int64_t* b) : bytes_used_(b) {} + + template + CountingAllocator(const CountingAllocator& x) + : Alloc(x), bytes_used_(x.bytes_used_) {} + + pointer allocate(size_type n, + std::allocator::const_pointer hint = nullptr) { + assert(bytes_used_ != nullptr); + *bytes_used_ += n * sizeof(T); + return Alloc::allocate(n, hint); + } + + void deallocate(pointer p, size_type n) { + Alloc::deallocate(p, n); + assert(bytes_used_ != nullptr); + *bytes_used_ -= n * sizeof(T); + } + + template + class rebind { + public: + using other = CountingAllocator; + }; + + friend bool operator==(const CountingAllocator& a, + const CountingAllocator& b) { + return a.bytes_used_ == b.bytes_used_; + } + + friend bool operator!=(const CountingAllocator& a, + const CountingAllocator& b) { + return !(a == b); + } + + int64_t* bytes_used_; +}; + +TEST(IntVec, SimpleOps) { + for (int len = 0; len < 20; len++) { + IntVec v; + const IntVec& cv = v; // const alias + + Fill(&v, len); + EXPECT_EQ(len, v.size()); + EXPECT_LE(len, v.capacity()); + + for (int i = 0; i < len; i++) { + EXPECT_EQ(i, v[i]); + EXPECT_EQ(i, v.at(i)); + } + EXPECT_EQ(v.begin(), v.data()); + EXPECT_EQ(cv.begin(), cv.data()); + + int counter = 0; + for (IntVec::iterator iter = v.begin(); iter != v.end(); ++iter) { + EXPECT_EQ(counter, *iter); + counter++; + } + EXPECT_EQ(counter, len); + + counter = 0; + for (IntVec::const_iterator iter = v.begin(); iter != v.end(); ++iter) { + EXPECT_EQ(counter, *iter); + counter++; + } + EXPECT_EQ(counter, len); + + counter = 0; + for (IntVec::const_iterator iter = v.cbegin(); iter != v.cend(); ++iter) { + EXPECT_EQ(counter, *iter); + counter++; + } + EXPECT_EQ(counter, len); + + if (len > 0) { + EXPECT_EQ(0, v.front()); + EXPECT_EQ(len - 1, v.back()); + v.pop_back(); + EXPECT_EQ(len - 1, v.size()); + for (int i = 0; i < v.size(); ++i) { + EXPECT_EQ(i, v[i]); + EXPECT_EQ(i, v.at(i)); + } + } + } +} + +TEST(IntVec, AtThrows) { + IntVec v = {1, 2, 3}; + EXPECT_EQ(v.at(2), 3); + ABSL_BASE_INTERNAL_EXPECT_FAIL(v.at(3), std::out_of_range, + "failed bounds check"); +} + +TEST(IntVec, ReverseIterator) { + for (int len = 0; len < 20; len++) { + IntVec v; + Fill(&v, len); + + int counter = len; + for (IntVec::reverse_iterator iter = v.rbegin(); iter != v.rend(); ++iter) { + counter--; + EXPECT_EQ(counter, *iter); + } + EXPECT_EQ(counter, 0); + + counter = len; + for (IntVec::const_reverse_iterator iter = v.rbegin(); iter != v.rend(); + ++iter) { + counter--; + EXPECT_EQ(counter, *iter); + } + EXPECT_EQ(counter, 0); + + counter = len; + for (IntVec::const_reverse_iterator iter = v.crbegin(); iter != v.crend(); + ++iter) { + counter--; + EXPECT_EQ(counter, *iter); + } + EXPECT_EQ(counter, 0); + } +} + +TEST(IntVec, Erase) { + for (int len = 1; len < 20; len++) { + for (int i = 0; i < len; ++i) { + IntVec v; + Fill(&v, len); + v.erase(v.begin() + i); + EXPECT_EQ(len - 1, v.size()); + for (int j = 0; j < i; ++j) { + EXPECT_EQ(j, v[j]); + } + for (int j = i; j < len - 1; ++j) { + EXPECT_EQ(j + 1, v[j]); + } + } + } +} + +// At the end of this test loop, the elements between [erase_begin, erase_end) +// should have reference counts == 0, and all others elements should have +// reference counts == 1. +TEST(RefCountedVec, EraseBeginEnd) { + for (int len = 1; len < 20; ++len) { + for (int erase_begin = 0; erase_begin < len; ++erase_begin) { + for (int erase_end = erase_begin; erase_end <= len; ++erase_end) { + std::vector counts(len, 0); + RefCountedVec v; + for (int i = 0; i < len; ++i) { + v.push_back(RefCounted(i, &counts[i])); + } + + int erase_len = erase_end - erase_begin; + + v.erase(v.begin() + erase_begin, v.begin() + erase_end); + + EXPECT_EQ(len - erase_len, v.size()); + + // Check the elements before the first element erased. + for (int i = 0; i < erase_begin; ++i) { + EXPECT_EQ(i, v[i].value_); + } + + // Check the elements after the first element erased. + for (int i = erase_begin; i < v.size(); ++i) { + EXPECT_EQ(i + erase_len, v[i].value_); + } + + // Check that the elements at the beginning are preserved. + for (int i = 0; i < erase_begin; ++i) { + EXPECT_EQ(1, counts[i]); + } + + // Check that the erased elements are destroyed + for (int i = erase_begin; i < erase_end; ++i) { + EXPECT_EQ(0, counts[i]); + } + + // Check that the elements at the end are preserved. + for (int i = erase_end; i< len; ++i) { + EXPECT_EQ(1, counts[i]); + } + } + } + } +} + +struct NoDefaultCtor { + explicit NoDefaultCtor(int) {} +}; +struct NoCopy { + NoCopy() {} + NoCopy(const NoCopy&) = delete; +}; +struct NoAssign { + NoAssign() {} + NoAssign& operator=(const NoAssign&) = delete; +}; +struct MoveOnly { + MoveOnly() {} + MoveOnly(MoveOnly&&) = default; + MoveOnly& operator=(MoveOnly&&) = default; +}; +TEST(InlinedVectorTest, NoDefaultCtor) { + absl::InlinedVector v(10, NoDefaultCtor(2)); + (void)v; +} +TEST(InlinedVectorTest, NoCopy) { + absl::InlinedVector v(10); + (void)v; +} +TEST(InlinedVectorTest, NoAssign) { + absl::InlinedVector v(10); + (void)v; +} +TEST(InlinedVectorTest, MoveOnly) { + absl::InlinedVector v; + v.push_back(MoveOnly{}); + v.push_back(MoveOnly{}); + v.push_back(MoveOnly{}); + v.erase(v.begin()); + v.push_back(MoveOnly{}); + v.erase(v.begin(), v.begin() + 1); + v.insert(v.begin(), MoveOnly{}); + v.emplace(v.begin()); + v.emplace(v.begin(), MoveOnly{}); +} +TEST(InlinedVectorTest, Noexcept) { + EXPECT_TRUE(std::is_nothrow_move_constructible::value); + EXPECT_TRUE((std::is_nothrow_move_constructible< + absl::InlinedVector>::value)); + + struct MoveCanThrow { + MoveCanThrow(MoveCanThrow&&) {} + }; + EXPECT_EQ(absl::default_allocator_is_nothrow::value, + (std::is_nothrow_move_constructible< + absl::InlinedVector>::value)); +} + +TEST(InlinedVectorTest, EmplaceBack) { + absl::InlinedVector, 1> v; + + auto& inlined_element = v.emplace_back("answer", 42); + EXPECT_EQ(&inlined_element, &v[0]); + EXPECT_EQ(inlined_element.first, "answer"); + EXPECT_EQ(inlined_element.second, 42); + + auto& allocated_element = v.emplace_back("taxicab", 1729); + EXPECT_EQ(&allocated_element, &v[1]); + EXPECT_EQ(allocated_element.first, "taxicab"); + EXPECT_EQ(allocated_element.second, 1729); +} + +TEST(InlinedVectorTest, ShrinkToFitGrowingVector) { + absl::InlinedVector, 1> v; + + v.shrink_to_fit(); + EXPECT_EQ(v.capacity(), 1); + + v.emplace_back("answer", 42); + v.shrink_to_fit(); + EXPECT_EQ(v.capacity(), 1); + + v.emplace_back("taxicab", 1729); + EXPECT_GE(v.capacity(), 2); + v.shrink_to_fit(); + EXPECT_EQ(v.capacity(), 2); + + v.reserve(100); + EXPECT_GE(v.capacity(), 100); + v.shrink_to_fit(); + EXPECT_EQ(v.capacity(), 2); +} + +TEST(InlinedVectorTest, ShrinkToFitEdgeCases) { + { + absl::InlinedVector, 1> v; + v.emplace_back("answer", 42); + v.emplace_back("taxicab", 1729); + EXPECT_GE(v.capacity(), 2); + v.pop_back(); + v.shrink_to_fit(); + EXPECT_EQ(v.capacity(), 1); + EXPECT_EQ(v[0].first, "answer"); + EXPECT_EQ(v[0].second, 42); + } + + { + absl::InlinedVector v(100); + v.resize(0); + v.shrink_to_fit(); + EXPECT_EQ(v.capacity(), 2); // inlined capacity + } + + { + absl::InlinedVector v(100); + v.resize(1); + v.shrink_to_fit(); + EXPECT_EQ(v.capacity(), 2); // inlined capacity + } + + { + absl::InlinedVector v(100); + v.resize(2); + v.shrink_to_fit(); + EXPECT_EQ(v.capacity(), 2); + } + + { + absl::InlinedVector v(100); + v.resize(3); + v.shrink_to_fit(); + EXPECT_EQ(v.capacity(), 3); + } +} + +TEST(IntVec, Insert) { + for (int len = 0; len < 20; len++) { + for (int pos = 0; pos <= len; pos++) { + { + // Single element + std::vector std_v; + Fill(&std_v, len); + IntVec v; + Fill(&v, len); + + std_v.insert(std_v.begin() + pos, 9999); + IntVec::iterator it = v.insert(v.cbegin() + pos, 9999); + EXPECT_THAT(v, ElementsAreArray(std_v)); + EXPECT_EQ(it, v.cbegin() + pos); + } + { + // n elements + std::vector std_v; + Fill(&std_v, len); + IntVec v; + Fill(&v, len); + + IntVec::size_type n = 5; + std_v.insert(std_v.begin() + pos, n, 9999); + IntVec::iterator it = v.insert(v.cbegin() + pos, n, 9999); + EXPECT_THAT(v, ElementsAreArray(std_v)); + EXPECT_EQ(it, v.cbegin() + pos); + } + { + // Iterator range (random access iterator) + std::vector std_v; + Fill(&std_v, len); + IntVec v; + Fill(&v, len); + + const std::vector input = {9999, 8888, 7777}; + std_v.insert(std_v.begin() + pos, input.cbegin(), input.cend()); + IntVec::iterator it = + v.insert(v.cbegin() + pos, input.cbegin(), input.cend()); + EXPECT_THAT(v, ElementsAreArray(std_v)); + EXPECT_EQ(it, v.cbegin() + pos); + } + { + // Iterator range (forward iterator) + std::vector std_v; + Fill(&std_v, len); + IntVec v; + Fill(&v, len); + + const std::forward_list input = {9999, 8888, 7777}; + std_v.insert(std_v.begin() + pos, input.cbegin(), input.cend()); + IntVec::iterator it = + v.insert(v.cbegin() + pos, input.cbegin(), input.cend()); + EXPECT_THAT(v, ElementsAreArray(std_v)); + EXPECT_EQ(it, v.cbegin() + pos); + } + { + // Iterator range (input iterator) + std::vector std_v; + Fill(&std_v, len); + IntVec v; + Fill(&v, len); + + std_v.insert(std_v.begin() + pos, {9999, 8888, 7777}); + std::istringstream input("9999 8888 7777"); + IntVec::iterator it = + v.insert(v.cbegin() + pos, std::istream_iterator(input), + std::istream_iterator()); + EXPECT_THAT(v, ElementsAreArray(std_v)); + EXPECT_EQ(it, v.cbegin() + pos); + } + { + // Initializer list + std::vector std_v; + Fill(&std_v, len); + IntVec v; + Fill(&v, len); + + std_v.insert(std_v.begin() + pos, {9999, 8888}); + IntVec::iterator it = v.insert(v.cbegin() + pos, {9999, 8888}); + EXPECT_THAT(v, ElementsAreArray(std_v)); + EXPECT_EQ(it, v.cbegin() + pos); + } + } + } +} + +TEST(RefCountedVec, InsertConstructorDestructor) { + // Make sure the proper construction/destruction happen during insert + // operations. + for (int len = 0; len < 20; len++) { + SCOPED_TRACE(len); + for (int pos = 0; pos <= len; pos++) { + SCOPED_TRACE(pos); + std::vector counts(len, 0); + int inserted_count = 0; + RefCountedVec v; + for (int i = 0; i < len; ++i) { + SCOPED_TRACE(i); + v.push_back(RefCounted(i, &counts[i])); + } + + EXPECT_THAT(counts, Each(Eq(1))); + + RefCounted insert_element(9999, &inserted_count); + EXPECT_EQ(1, inserted_count); + v.insert(v.begin() + pos, insert_element); + EXPECT_EQ(2, inserted_count); + // Check that the elements at the end are preserved. + EXPECT_THAT(counts, Each(Eq(1))); + EXPECT_EQ(2, inserted_count); + } + } +} + +TEST(IntVec, Resize) { + for (int len = 0; len < 20; len++) { + IntVec v; + Fill(&v, len); + + // Try resizing up and down by k elements + static const int kResizeElem = 1000000; + for (int k = 0; k < 10; k++) { + // Enlarging resize + v.resize(len+k, kResizeElem); + EXPECT_EQ(len+k, v.size()); + EXPECT_LE(len+k, v.capacity()); + for (int i = 0; i < len+k; i++) { + if (i < len) { + EXPECT_EQ(i, v[i]); + } else { + EXPECT_EQ(kResizeElem, v[i]); + } + } + + // Shrinking resize + v.resize(len, kResizeElem); + EXPECT_EQ(len, v.size()); + EXPECT_LE(len, v.capacity()); + for (int i = 0; i < len; i++) { + EXPECT_EQ(i, v[i]); + } + } + } +} + +TEST(IntVec, InitWithLength) { + for (int len = 0; len < 20; len++) { + IntVec v(len, 7); + EXPECT_EQ(len, v.size()); + EXPECT_LE(len, v.capacity()); + for (int i = 0; i < len; i++) { + EXPECT_EQ(7, v[i]); + } + } +} + +TEST(IntVec, CopyConstructorAndAssignment) { + for (int len = 0; len < 20; len++) { + IntVec v; + Fill(&v, len); + EXPECT_EQ(len, v.size()); + EXPECT_LE(len, v.capacity()); + + IntVec v2(v); + EXPECT_TRUE(v == v2) << PrintToString(v) << PrintToString(v2); + + for (int start_len = 0; start_len < 20; start_len++) { + IntVec v3; + Fill(&v3, start_len, 99); // Add dummy elements that should go away + v3 = v; + EXPECT_TRUE(v == v3) << PrintToString(v) << PrintToString(v3); + } + } +} + +TEST(IntVec, AliasingCopyAssignment) { + for (int len = 0; len < 20; ++len) { + IntVec original; + Fill(&original, len); + IntVec dup = original; + dup = *&dup; + EXPECT_EQ(dup, original); + } +} + +TEST(IntVec, MoveConstructorAndAssignment) { + for (int len = 0; len < 20; len++) { + IntVec v_in; + const int inlined_capacity = v_in.capacity(); + Fill(&v_in, len); + EXPECT_EQ(len, v_in.size()); + EXPECT_LE(len, v_in.capacity()); + + { + IntVec v_temp(v_in); + auto* old_data = v_temp.data(); + IntVec v_out(std::move(v_temp)); + EXPECT_TRUE(v_in == v_out) << PrintToString(v_in) << PrintToString(v_out); + if (v_in.size() > inlined_capacity) { + // Allocation is moved as a whole, data stays in place. + EXPECT_TRUE(v_out.data() == old_data); + } else { + EXPECT_FALSE(v_out.data() == old_data); + } + } + for (int start_len = 0; start_len < 20; start_len++) { + IntVec v_out; + Fill(&v_out, start_len, 99); // Add dummy elements that should go away + IntVec v_temp(v_in); + auto* old_data = v_temp.data(); + v_out = std::move(v_temp); + EXPECT_TRUE(v_in == v_out) << PrintToString(v_in) << PrintToString(v_out); + if (v_in.size() > inlined_capacity) { + // Allocation is moved as a whole, data stays in place. + EXPECT_TRUE(v_out.data() == old_data); + } else { + EXPECT_FALSE(v_out.data() == old_data); + } + } + } +} + +class NotTriviallyDestructible { + public: + NotTriviallyDestructible() : p_(new int(1)) {} + explicit NotTriviallyDestructible(int i) : p_(new int(i)) {} + + NotTriviallyDestructible(const NotTriviallyDestructible& other) + : p_(new int(*other.p_)) {} + + NotTriviallyDestructible& operator=(const NotTriviallyDestructible& other) { + p_ = absl::make_unique(*other.p_); + return *this; + } + + bool operator==(const NotTriviallyDestructible& other) const { + return *p_ == *other.p_; + } + + private: + std::unique_ptr p_; +}; + +TEST(AliasingTest, Emplace) { + for (int i = 2; i < 20; ++i) { + absl::InlinedVector vec; + for (int j = 0; j < i; ++j) { + vec.push_back(NotTriviallyDestructible(j)); + } + vec.emplace(vec.begin(), vec[0]); + EXPECT_EQ(vec[0], vec[1]); + vec.emplace(vec.begin() + i / 2, vec[i / 2]); + EXPECT_EQ(vec[i / 2], vec[i / 2 + 1]); + vec.emplace(vec.end() - 1, vec.back()); + EXPECT_EQ(vec[vec.size() - 2], vec.back()); + } +} + +TEST(AliasingTest, InsertWithCount) { + for (int i = 1; i < 20; ++i) { + absl::InlinedVector vec; + for (int j = 0; j < i; ++j) { + vec.push_back(NotTriviallyDestructible(j)); + } + for (int n = 0; n < 5; ++n) { + // We use back where we can because it's guaranteed to become invalidated + vec.insert(vec.begin(), n, vec.back()); + auto b = vec.begin(); + EXPECT_TRUE( + std::all_of(b, b + n, [&vec](const NotTriviallyDestructible& x) { + return x == vec.back(); + })); + + auto m_idx = vec.size() / 2; + vec.insert(vec.begin() + m_idx, n, vec.back()); + auto m = vec.begin() + m_idx; + EXPECT_TRUE( + std::all_of(m, m + n, [&vec](const NotTriviallyDestructible& x) { + return x == vec.back(); + })); + + // We want distinct values so the equality test is meaningful, + // vec[vec.size() - 1] is also almost always invalidated. + auto old_e = vec.size() - 1; + auto val = vec[old_e]; + vec.insert(vec.end(), n, vec[old_e]); + auto e = vec.begin() + old_e; + EXPECT_TRUE(std::all_of( + e, e + n, + [&val](const NotTriviallyDestructible& x) { return x == val; })); + } + } +} + +TEST(OverheadTest, Storage) { + // Check for size overhead. + // In particular, ensure that std::allocator doesn't cost anything to store. + // The union should be absorbing some of the allocation bookkeeping overhead + // in the larger vectors, leaving only the size_ field as overhead. + EXPECT_EQ(2 * sizeof(int*), + sizeof(absl::InlinedVector) - 1 * sizeof(int*)); + EXPECT_EQ(1 * sizeof(int*), + sizeof(absl::InlinedVector) - 2 * sizeof(int*)); + EXPECT_EQ(1 * sizeof(int*), + sizeof(absl::InlinedVector) - 3 * sizeof(int*)); + EXPECT_EQ(1 * sizeof(int*), + sizeof(absl::InlinedVector) - 4 * sizeof(int*)); + EXPECT_EQ(1 * sizeof(int*), + sizeof(absl::InlinedVector) - 5 * sizeof(int*)); + EXPECT_EQ(1 * sizeof(int*), + sizeof(absl::InlinedVector) - 6 * sizeof(int*)); + EXPECT_EQ(1 * sizeof(int*), + sizeof(absl::InlinedVector) - 7 * sizeof(int*)); + EXPECT_EQ(1 * sizeof(int*), + sizeof(absl::InlinedVector) - 8 * sizeof(int*)); +} + +TEST(IntVec, Clear) { + for (int len = 0; len < 20; len++) { + SCOPED_TRACE(len); + IntVec v; + Fill(&v, len); + v.clear(); + EXPECT_EQ(0, v.size()); + EXPECT_EQ(v.begin(), v.end()); + } +} + +TEST(IntVec, Reserve) { + for (int len = 0; len < 20; len++) { + IntVec v; + Fill(&v, len); + + for (int newlen = 0; newlen < 100; newlen++) { + const int* start_rep = v.data(); + v.reserve(newlen); + const int* final_rep = v.data(); + if (newlen <= len) { + EXPECT_EQ(start_rep, final_rep); + } + EXPECT_LE(newlen, v.capacity()); + + // Filling up to newlen should not change rep + while (v.size() < newlen) { + v.push_back(0); + } + EXPECT_EQ(final_rep, v.data()); + } + } +} + +TEST(StringVec, SelfRefPushBack) { + std::vector std_v; + absl::InlinedVector v; + const std::string s = "A quite long std::string to ensure heap."; + std_v.push_back(s); + v.push_back(s); + for (int i = 0; i < 20; ++i) { + EXPECT_THAT(v, ElementsAreArray(std_v)); + + v.push_back(v.back()); + std_v.push_back(std_v.back()); + } + EXPECT_THAT(v, ElementsAreArray(std_v)); +} + +TEST(StringVec, SelfRefPushBackWithMove) { + std::vector std_v; + absl::InlinedVector v; + const std::string s = "A quite long std::string to ensure heap."; + std_v.push_back(s); + v.push_back(s); + for (int i = 0; i < 20; ++i) { + EXPECT_EQ(v.back(), std_v.back()); + + v.push_back(std::move(v.back())); + std_v.push_back(std::move(std_v.back())); + } + EXPECT_EQ(v.back(), std_v.back()); +} + +TEST(StringVec, SelfMove) { + const std::string s = "A quite long std::string to ensure heap."; + for (int len = 0; len < 20; len++) { + SCOPED_TRACE(len); + absl::InlinedVector v; + for (int i = 0; i < len; ++i) { + SCOPED_TRACE(i); + v.push_back(s); + } + // Indirection necessary to avoid compiler warning. + v = std::move(*(&v)); + // Ensure that the inlined vector is still in a valid state by copying it. + // We don't expect specific contents since a self-move results in an + // unspecified valid state. + std::vector copy(v.begin(), v.end()); + } +} + +TEST(IntVec, Swap) { + for (int l1 = 0; l1 < 20; l1++) { + SCOPED_TRACE(l1); + for (int l2 = 0; l2 < 20; l2++) { + SCOPED_TRACE(l2); + IntVec a = Fill(l1, 0); + IntVec b = Fill(l2, 100); + { + using std::swap; + swap(a, b); + } + EXPECT_EQ(l1, b.size()); + EXPECT_EQ(l2, a.size()); + for (int i = 0; i < l1; i++) { + SCOPED_TRACE(i); + EXPECT_EQ(i, b[i]); + } + for (int i = 0; i < l2; i++) { + SCOPED_TRACE(i); + EXPECT_EQ(100 + i, a[i]); + } + } + } +} + +TYPED_TEST_P(InstanceTest, Swap) { + using Instance = TypeParam; + using InstanceVec = absl::InlinedVector; + for (int l1 = 0; l1 < 20; l1++) { + SCOPED_TRACE(l1); + for (int l2 = 0; l2 < 20; l2++) { + SCOPED_TRACE(l2); + InstanceTracker tracker; + InstanceVec a, b; + const size_t inlined_capacity = a.capacity(); + auto min_len = std::min(l1, l2); + auto max_len = std::max(l1, l2); + for (int i = 0; i < l1; i++) a.push_back(Instance(i)); + for (int i = 0; i < l2; i++) b.push_back(Instance(100+i)); + EXPECT_EQ(tracker.instances(), l1 + l2); + tracker.ResetCopiesMovesSwaps(); + { + using std::swap; + swap(a, b); + } + EXPECT_EQ(tracker.instances(), l1 + l2); + if (a.size() > inlined_capacity && b.size() > inlined_capacity) { + EXPECT_EQ(tracker.swaps(), 0); // Allocations are swapped. + EXPECT_EQ(tracker.moves(), 0); + } else if (a.size() <= inlined_capacity && b.size() <= inlined_capacity) { + EXPECT_EQ(tracker.swaps(), min_len); + EXPECT_EQ((tracker.moves() ? tracker.moves() : tracker.copies()), + max_len - min_len); + } else { + // One is allocated and the other isn't. The allocation is transferred + // without copying elements, and the inlined instances are copied/moved. + EXPECT_EQ(tracker.swaps(), 0); + EXPECT_EQ((tracker.moves() ? tracker.moves() : tracker.copies()), + min_len); + } + + EXPECT_EQ(l1, b.size()); + EXPECT_EQ(l2, a.size()); + for (int i = 0; i < l1; i++) { + EXPECT_EQ(i, b[i].value()); + } + for (int i = 0; i < l2; i++) { + EXPECT_EQ(100 + i, a[i].value()); + } + } + } +} + +TEST(IntVec, EqualAndNotEqual) { + IntVec a, b; + EXPECT_TRUE(a == b); + EXPECT_FALSE(a != b); + + a.push_back(3); + EXPECT_FALSE(a == b); + EXPECT_TRUE(a != b); + + b.push_back(3); + EXPECT_TRUE(a == b); + EXPECT_FALSE(a != b); + + b.push_back(7); + EXPECT_FALSE(a == b); + EXPECT_TRUE(a != b); + + a.push_back(6); + EXPECT_FALSE(a == b); + EXPECT_TRUE(a != b); + + a.clear(); + b.clear(); + for (int i = 0; i < 100; i++) { + a.push_back(i); + b.push_back(i); + EXPECT_TRUE(a == b); + EXPECT_FALSE(a != b); + + b[i] = b[i] + 1; + EXPECT_FALSE(a == b); + EXPECT_TRUE(a != b); + + b[i] = b[i] - 1; // Back to before + EXPECT_TRUE(a == b); + EXPECT_FALSE(a != b); + } +} + +TEST(IntVec, RelationalOps) { + IntVec a, b; + EXPECT_FALSE(a < b); + EXPECT_FALSE(b < a); + EXPECT_FALSE(a > b); + EXPECT_FALSE(b > a); + EXPECT_TRUE(a <= b); + EXPECT_TRUE(b <= a); + EXPECT_TRUE(a >= b); + EXPECT_TRUE(b >= a); + b.push_back(3); + EXPECT_TRUE(a < b); + EXPECT_FALSE(b < a); + EXPECT_FALSE(a > b); + EXPECT_TRUE(b > a); + EXPECT_TRUE(a <= b); + EXPECT_FALSE(b <= a); + EXPECT_FALSE(a >= b); + EXPECT_TRUE(b >= a); +} + +TYPED_TEST_P(InstanceTest, CountConstructorsDestructors) { + using Instance = TypeParam; + using InstanceVec = absl::InlinedVector; + InstanceTracker tracker; + for (int len = 0; len < 20; len++) { + SCOPED_TRACE(len); + tracker.ResetCopiesMovesSwaps(); + + InstanceVec v; + const size_t inlined_capacity = v.capacity(); + for (int i = 0; i < len; i++) { + v.push_back(Instance(i)); + } + EXPECT_EQ(tracker.instances(), len); + EXPECT_GE(tracker.copies() + tracker.moves(), + len); // More due to reallocation. + tracker.ResetCopiesMovesSwaps(); + + // Enlarging resize() must construct some objects + tracker.ResetCopiesMovesSwaps(); + v.resize(len + 10, Instance(100)); + EXPECT_EQ(tracker.instances(), len + 10); + if (len <= inlined_capacity && len + 10 > inlined_capacity) { + EXPECT_EQ(tracker.copies() + tracker.moves(), 10 + len); + } else { + // Only specify a minimum number of copies + moves. We don't want to + // depend on the reallocation policy here. + EXPECT_GE(tracker.copies() + tracker.moves(), + 10); // More due to reallocation. + } + + // Shrinking resize() must destroy some objects + tracker.ResetCopiesMovesSwaps(); + v.resize(len, Instance(100)); + EXPECT_EQ(tracker.instances(), len); + EXPECT_EQ(tracker.copies(), 0); + EXPECT_EQ(tracker.moves(), 0); + + // reserve() must not increase the number of initialized objects + SCOPED_TRACE("reserve"); + v.reserve(len+1000); + EXPECT_EQ(tracker.instances(), len); + EXPECT_EQ(tracker.copies() + tracker.moves(), len); + + // pop_back() and erase() must destroy one object + if (len > 0) { + tracker.ResetCopiesMovesSwaps(); + v.pop_back(); + EXPECT_EQ(tracker.instances(), len - 1); + EXPECT_EQ(tracker.copies(), 0); + EXPECT_EQ(tracker.moves(), 0); + + if (!v.empty()) { + tracker.ResetCopiesMovesSwaps(); + v.erase(v.begin()); + EXPECT_EQ(tracker.instances(), len - 2); + EXPECT_EQ(tracker.copies() + tracker.moves(), len - 2); + } + } + + tracker.ResetCopiesMovesSwaps(); + int instances_before_empty_erase = tracker.instances(); + v.erase(v.begin(), v.begin()); + EXPECT_EQ(tracker.instances(), instances_before_empty_erase); + EXPECT_EQ(tracker.copies() + tracker.moves(), 0); + } +} + +TYPED_TEST_P(InstanceTest, CountConstructorsDestructorsOnCopyConstruction) { + using Instance = TypeParam; + using InstanceVec = absl::InlinedVector; + InstanceTracker tracker; + for (int len = 0; len < 20; len++) { + SCOPED_TRACE(len); + tracker.ResetCopiesMovesSwaps(); + + InstanceVec v; + for (int i = 0; i < len; i++) { + v.push_back(Instance(i)); + } + EXPECT_EQ(tracker.instances(), len); + EXPECT_GE(tracker.copies() + tracker.moves(), + len); // More due to reallocation. + tracker.ResetCopiesMovesSwaps(); + { // Copy constructor should create 'len' more instances. + InstanceVec v_copy(v); + EXPECT_EQ(tracker.instances(), len + len); + EXPECT_EQ(tracker.copies(), len); + EXPECT_EQ(tracker.moves(), 0); + } + EXPECT_EQ(tracker.instances(), len); + } +} + +TYPED_TEST_P(InstanceTest, CountConstructorsDestructorsOnMoveConstruction) { + using Instance = TypeParam; + using InstanceVec = absl::InlinedVector; + InstanceTracker tracker; + for (int len = 0; len < 20; len++) { + SCOPED_TRACE(len); + tracker.ResetCopiesMovesSwaps(); + + InstanceVec v; + const size_t inlined_capacity = v.capacity(); + for (int i = 0; i < len; i++) { + v.push_back(Instance(i)); + } + EXPECT_EQ(tracker.instances(), len); + EXPECT_GE(tracker.copies() + tracker.moves(), + len); // More due to reallocation. + tracker.ResetCopiesMovesSwaps(); + { + InstanceVec v_copy(std::move(v)); + if (len > inlined_capacity) { + // Allocation is moved as a whole. + EXPECT_EQ(tracker.instances(), len); + EXPECT_EQ(tracker.live_instances(), len); + // Tests an implementation detail, don't rely on this in your code. + EXPECT_EQ(v.size(), 0); // NOLINT misc-use-after-move + EXPECT_EQ(tracker.copies(), 0); + EXPECT_EQ(tracker.moves(), 0); + } else { + EXPECT_EQ(tracker.instances(), len + len); + if (Instance::supports_move()) { + EXPECT_EQ(tracker.live_instances(), len); + EXPECT_EQ(tracker.copies(), 0); + EXPECT_EQ(tracker.moves(), len); + } else { + EXPECT_EQ(tracker.live_instances(), len + len); + EXPECT_EQ(tracker.copies(), len); + EXPECT_EQ(tracker.moves(), 0); + } + } + EXPECT_EQ(tracker.swaps(), 0); + } + } +} + +TYPED_TEST_P(InstanceTest, CountConstructorsDestructorsOnAssignment) { + using Instance = TypeParam; + using InstanceVec = absl::InlinedVector; + InstanceTracker tracker; + for (int len = 0; len < 20; len++) { + SCOPED_TRACE(len); + for (int longorshort = 0; longorshort <= 1; ++longorshort) { + SCOPED_TRACE(longorshort); + tracker.ResetCopiesMovesSwaps(); + + InstanceVec longer, shorter; + for (int i = 0; i < len; i++) { + longer.push_back(Instance(i)); + shorter.push_back(Instance(i)); + } + longer.push_back(Instance(len)); + EXPECT_EQ(tracker.instances(), len + len + 1); + EXPECT_GE(tracker.copies() + tracker.moves(), + len + len + 1); // More due to reallocation. + + tracker.ResetCopiesMovesSwaps(); + if (longorshort) { + shorter = longer; + EXPECT_EQ(tracker.instances(), (len + 1) + (len + 1)); + EXPECT_GE(tracker.copies() + tracker.moves(), + len + 1); // More due to reallocation. + } else { + longer = shorter; + EXPECT_EQ(tracker.instances(), len + len); + EXPECT_EQ(tracker.copies() + tracker.moves(), len); + } + } + } +} + +TYPED_TEST_P(InstanceTest, CountConstructorsDestructorsOnMoveAssignment) { + using Instance = TypeParam; + using InstanceVec = absl::InlinedVector; + InstanceTracker tracker; + for (int len = 0; len < 20; len++) { + SCOPED_TRACE(len); + for (int longorshort = 0; longorshort <= 1; ++longorshort) { + SCOPED_TRACE(longorshort); + tracker.ResetCopiesMovesSwaps(); + + InstanceVec longer, shorter; + const int inlined_capacity = longer.capacity(); + for (int i = 0; i < len; i++) { + longer.push_back(Instance(i)); + shorter.push_back(Instance(i)); + } + longer.push_back(Instance(len)); + EXPECT_EQ(tracker.instances(), len + len + 1); + EXPECT_GE(tracker.copies() + tracker.moves(), + len + len + 1); // More due to reallocation. + + tracker.ResetCopiesMovesSwaps(); + int src_len; + if (longorshort) { + src_len = len + 1; + shorter = std::move(longer); + } else { + src_len = len; + longer = std::move(shorter); + } + if (src_len > inlined_capacity) { + // Allocation moved as a whole. + EXPECT_EQ(tracker.instances(), src_len); + EXPECT_EQ(tracker.live_instances(), src_len); + EXPECT_EQ(tracker.copies(), 0); + EXPECT_EQ(tracker.moves(), 0); + } else { + // Elements are all copied. + EXPECT_EQ(tracker.instances(), src_len + src_len); + if (Instance::supports_move()) { + EXPECT_EQ(tracker.copies(), 0); + EXPECT_EQ(tracker.moves(), src_len); + EXPECT_EQ(tracker.live_instances(), src_len); + } else { + EXPECT_EQ(tracker.copies(), src_len); + EXPECT_EQ(tracker.moves(), 0); + EXPECT_EQ(tracker.live_instances(), src_len + src_len); + } + } + EXPECT_EQ(tracker.swaps(), 0); + } + } +} + +TEST(CountElemAssign, SimpleTypeWithInlineBacking) { + for (size_t original_size = 0; original_size <= 5; ++original_size) { + SCOPED_TRACE(original_size); + // Original contents are [12345, 12345, ...] + std::vector original_contents(original_size, 12345); + + absl::InlinedVector v(original_contents.begin(), + original_contents.end()); + v.assign(2, 123); + EXPECT_THAT(v, AllOf(SizeIs(2), ElementsAre(123, 123))); + if (original_size <= 2) { + // If the original had inline backing, it should stay inline. + EXPECT_EQ(2, v.capacity()); + } + } +} + +TEST(CountElemAssign, SimpleTypeWithAllocation) { + for (size_t original_size = 0; original_size <= 5; ++original_size) { + SCOPED_TRACE(original_size); + // Original contents are [12345, 12345, ...] + std::vector original_contents(original_size, 12345); + + absl::InlinedVector v(original_contents.begin(), + original_contents.end()); + v.assign(3, 123); + EXPECT_THAT(v, AllOf(SizeIs(3), ElementsAre(123, 123, 123))); + EXPECT_LE(v.size(), v.capacity()); + } +} + +TYPED_TEST_P(InstanceTest, CountElemAssignInlineBacking) { + using Instance = TypeParam; + for (size_t original_size = 0; original_size <= 5; ++original_size) { + SCOPED_TRACE(original_size); + // Original contents are [12345, 12345, ...] + std::vector original_contents(original_size, Instance(12345)); + + absl::InlinedVector v(original_contents.begin(), + original_contents.end()); + v.assign(2, Instance(123)); + EXPECT_THAT(v, AllOf(SizeIs(2), ElementsAre(ValueIs(123), ValueIs(123)))); + if (original_size <= 2) { + // If the original had inline backing, it should stay inline. + EXPECT_EQ(2, v.capacity()); + } + } +} + +template +void InstanceCountElemAssignWithAllocationTest() { + for (size_t original_size = 0; original_size <= 5; ++original_size) { + SCOPED_TRACE(original_size); + // Original contents are [12345, 12345, ...] + std::vector original_contents(original_size, Instance(12345)); + + absl::InlinedVector v(original_contents.begin(), + original_contents.end()); + v.assign(3, Instance(123)); + EXPECT_THAT(v, + AllOf(SizeIs(3), + ElementsAre(ValueIs(123), ValueIs(123), ValueIs(123)))); + EXPECT_LE(v.size(), v.capacity()); + } +} +TEST(CountElemAssign, WithAllocationCopyableInstance) { + InstanceCountElemAssignWithAllocationTest(); +} +TEST(CountElemAssign, WithAllocationCopyableMovableInstance) { + InstanceCountElemAssignWithAllocationTest(); +} + +TEST(RangedConstructor, SimpleType) { + std::vector source_v = {4, 5, 6}; + // First try to fit in inline backing + absl::InlinedVector v(source_v.begin(), source_v.end()); + EXPECT_EQ(3, v.size()); + EXPECT_EQ(4, v.capacity()); // Indication that we're still on inlined storage + EXPECT_EQ(4, v[0]); + EXPECT_EQ(5, v[1]); + EXPECT_EQ(6, v[2]); + + // Now, force a re-allocate + absl::InlinedVector realloc_v(source_v.begin(), source_v.end()); + EXPECT_EQ(3, realloc_v.size()); + EXPECT_LT(2, realloc_v.capacity()); + EXPECT_EQ(4, realloc_v[0]); + EXPECT_EQ(5, realloc_v[1]); + EXPECT_EQ(6, realloc_v[2]); +} + +// Test for ranged constructors using Instance as the element type and +// SourceContainer as the source container type. +template +void InstanceRangedConstructorTestForContainer() { + InstanceTracker tracker; + SourceContainer source_v = {Instance(0), Instance(1)}; + tracker.ResetCopiesMovesSwaps(); + absl::InlinedVector v(source_v.begin(), + source_v.end()); + EXPECT_EQ(2, v.size()); + EXPECT_LT(1, v.capacity()); + EXPECT_EQ(0, v[0].value()); + EXPECT_EQ(1, v[1].value()); + EXPECT_EQ(tracker.copies(), 2); + EXPECT_EQ(tracker.moves(), 0); +} + +template +void InstanceRangedConstructorTestWithCapacity() { + // Test with const and non-const, random access and non-random-access sources. + // TODO(bsamwel): Test with an input iterator source. + { + SCOPED_TRACE("std::list"); + InstanceRangedConstructorTestForContainer, + inlined_capacity>(); + { + SCOPED_TRACE("const std::list"); + InstanceRangedConstructorTestForContainer< + Instance, const std::list, inlined_capacity>(); + } + { + SCOPED_TRACE("std::vector"); + InstanceRangedConstructorTestForContainer, + inlined_capacity>(); + } + { + SCOPED_TRACE("const std::vector"); + InstanceRangedConstructorTestForContainer< + Instance, const std::vector, inlined_capacity>(); + } + } +} + +TYPED_TEST_P(InstanceTest, RangedConstructor) { + using Instance = TypeParam; + SCOPED_TRACE("capacity=1"); + InstanceRangedConstructorTestWithCapacity(); + SCOPED_TRACE("capacity=2"); + InstanceRangedConstructorTestWithCapacity(); +} + +TEST(RangedConstructor, ElementsAreConstructed) { + std::vector source_v = {"cat", "dog"}; + + // Force expansion and re-allocation of v. Ensures that when the vector is + // expanded that new elements are constructed. + absl::InlinedVector v(source_v.begin(), source_v.end()); + EXPECT_EQ("cat", v[0]); + EXPECT_EQ("dog", v[1]); +} + +TEST(RangedAssign, SimpleType) { + // Test for all combinations of original sizes (empty and non-empty inline, + // and out of line) and target sizes. + for (size_t original_size = 0; original_size <= 5; ++original_size) { + SCOPED_TRACE(original_size); + // Original contents are [12345, 12345, ...] + std::vector original_contents(original_size, 12345); + + for (size_t target_size = 0; target_size <= 5; ++target_size) { + SCOPED_TRACE(target_size); + + // New contents are [3, 4, ...] + std::vector new_contents; + for (size_t i = 0; i < target_size; ++i) { + new_contents.push_back(i + 3); + } + + absl::InlinedVector v(original_contents.begin(), + original_contents.end()); + v.assign(new_contents.begin(), new_contents.end()); + + EXPECT_EQ(new_contents.size(), v.size()); + EXPECT_LE(new_contents.size(), v.capacity()); + if (target_size <= 3 && original_size <= 3) { + // Storage should stay inline when target size is small. + EXPECT_EQ(3, v.capacity()); + } + EXPECT_THAT(v, ElementsAreArray(new_contents)); + } + } +} + +// Returns true if lhs and rhs have the same value. +template +static bool InstanceValuesEqual(const Instance& lhs, const Instance& rhs) { + return lhs.value() == rhs.value(); +} + +// Test for ranged assign() using Instance as the element type and +// SourceContainer as the source container type. +template +void InstanceRangedAssignTestForContainer() { + // Test for all combinations of original sizes (empty and non-empty inline, + // and out of line) and target sizes. + for (size_t original_size = 0; original_size <= 5; ++original_size) { + SCOPED_TRACE(original_size); + // Original contents are [12345, 12345, ...] + std::vector original_contents(original_size, Instance(12345)); + + for (size_t target_size = 0; target_size <= 5; ++target_size) { + SCOPED_TRACE(target_size); + + // New contents are [3, 4, ...] + // Generate data using a non-const container, because SourceContainer + // itself may be const. + // TODO(bsamwel): Test with an input iterator. + std::vector new_contents_in; + for (size_t i = 0; i < target_size; ++i) { + new_contents_in.push_back(Instance(i + 3)); + } + SourceContainer new_contents(new_contents_in.begin(), + new_contents_in.end()); + + absl::InlinedVector v(original_contents.begin(), + original_contents.end()); + v.assign(new_contents.begin(), new_contents.end()); + + EXPECT_EQ(new_contents.size(), v.size()); + EXPECT_LE(new_contents.size(), v.capacity()); + if (target_size <= 3 && original_size <= 3) { + // Storage should stay inline when target size is small. + EXPECT_EQ(3, v.capacity()); + } + EXPECT_TRUE(std::equal(v.begin(), v.end(), new_contents.begin(), + InstanceValuesEqual)); + } + } +} + +TYPED_TEST_P(InstanceTest, RangedAssign) { + using Instance = TypeParam; + // Test with const and non-const, random access and non-random-access sources. + // TODO(bsamwel): Test with an input iterator source. + SCOPED_TRACE("std::list"); + InstanceRangedAssignTestForContainer>(); + SCOPED_TRACE("const std::list"); + InstanceRangedAssignTestForContainer>(); + SCOPED_TRACE("std::vector"); + InstanceRangedAssignTestForContainer>(); + SCOPED_TRACE("const std::vector"); + InstanceRangedAssignTestForContainer>(); +} + +TEST(InitializerListConstructor, SimpleTypeWithInlineBacking) { + EXPECT_THAT((absl::InlinedVector{4, 5, 6}), + AllOf(SizeIs(3), CapacityIs(4), ElementsAre(4, 5, 6))); +} + +TEST(InitializerListConstructor, SimpleTypeWithReallocationRequired) { + EXPECT_THAT((absl::InlinedVector{4, 5, 6}), + AllOf(SizeIs(3), CapacityIs(Gt(2)), ElementsAre(4, 5, 6))); +} + +TEST(InitializerListConstructor, DisparateTypesInList) { + EXPECT_THAT((absl::InlinedVector{-7, 8ULL}), ElementsAre(-7, 8)); + + EXPECT_THAT((absl::InlinedVector{"foo", std::string("bar")}), + ElementsAre("foo", "bar")); +} + +TEST(InitializerListConstructor, ComplexTypeWithInlineBacking) { + EXPECT_THAT((absl::InlinedVector{ + CopyableMovableInstance(0)}), + AllOf(SizeIs(1), CapacityIs(1), ElementsAre(ValueIs(0)))); +} + +TEST(InitializerListConstructor, ComplexTypeWithReallocationRequired) { + EXPECT_THAT( + (absl::InlinedVector{ + CopyableMovableInstance(0), CopyableMovableInstance(1)}), + AllOf(SizeIs(2), CapacityIs(Gt(1)), ElementsAre(ValueIs(0), ValueIs(1)))); +} + +TEST(InitializerListAssign, SimpleTypeFitsInlineBacking) { + for (size_t original_size = 0; original_size <= 4; ++original_size) { + SCOPED_TRACE(original_size); + + absl::InlinedVector v1(original_size, 12345); + const size_t original_capacity_v1 = v1.capacity(); + v1.assign({3}); + EXPECT_THAT( + v1, AllOf(SizeIs(1), CapacityIs(original_capacity_v1), ElementsAre(3))); + + absl::InlinedVector v2(original_size, 12345); + const size_t original_capacity_v2 = v2.capacity(); + v2 = {3}; + EXPECT_THAT( + v2, AllOf(SizeIs(1), CapacityIs(original_capacity_v2), ElementsAre(3))); + } +} + +TEST(InitializerListAssign, SimpleTypeDoesNotFitInlineBacking) { + for (size_t original_size = 0; original_size <= 4; ++original_size) { + SCOPED_TRACE(original_size); + absl::InlinedVector v1(original_size, 12345); + v1.assign({3, 4, 5}); + EXPECT_THAT(v1, AllOf(SizeIs(3), ElementsAre(3, 4, 5))); + EXPECT_LE(3, v1.capacity()); + + absl::InlinedVector v2(original_size, 12345); + v2 = {3, 4, 5}; + EXPECT_THAT(v2, AllOf(SizeIs(3), ElementsAre(3, 4, 5))); + EXPECT_LE(3, v2.capacity()); + } +} + +TEST(InitializerListAssign, DisparateTypesInList) { + absl::InlinedVector v_int1; + v_int1.assign({-7, 8ULL}); + EXPECT_THAT(v_int1, ElementsAre(-7, 8)); + + absl::InlinedVector v_int2; + v_int2 = {-7, 8ULL}; + EXPECT_THAT(v_int2, ElementsAre(-7, 8)); + + absl::InlinedVector v_string1; + v_string1.assign({"foo", std::string("bar")}); + EXPECT_THAT(v_string1, ElementsAre("foo", "bar")); + + absl::InlinedVector v_string2; + v_string2 = {"foo", std::string("bar")}; + EXPECT_THAT(v_string2, ElementsAre("foo", "bar")); +} + +TYPED_TEST_P(InstanceTest, InitializerListAssign) { + using Instance = TypeParam; + for (size_t original_size = 0; original_size <= 4; ++original_size) { + SCOPED_TRACE(original_size); + absl::InlinedVector v(original_size, Instance(12345)); + const size_t original_capacity = v.capacity(); + v.assign({Instance(3)}); + EXPECT_THAT(v, AllOf(SizeIs(1), CapacityIs(original_capacity), + ElementsAre(ValueIs(3)))); + } + for (size_t original_size = 0; original_size <= 4; ++original_size) { + SCOPED_TRACE(original_size); + absl::InlinedVector v(original_size, Instance(12345)); + v.assign({Instance(3), Instance(4), Instance(5)}); + EXPECT_THAT(v, AllOf(SizeIs(3), + ElementsAre(ValueIs(3), ValueIs(4), ValueIs(5)))); + EXPECT_LE(3, v.capacity()); + } +} + +REGISTER_TYPED_TEST_CASE_P(InstanceTest, Swap, CountConstructorsDestructors, + CountConstructorsDestructorsOnCopyConstruction, + CountConstructorsDestructorsOnMoveConstruction, + CountConstructorsDestructorsOnAssignment, + CountConstructorsDestructorsOnMoveAssignment, + CountElemAssignInlineBacking, RangedConstructor, + RangedAssign, InitializerListAssign); + +using InstanceTypes = + ::testing::Types; +INSTANTIATE_TYPED_TEST_CASE_P(InstanceTestOnTypes, InstanceTest, InstanceTypes); + +TEST(DynamicVec, DynamicVecCompiles) { + DynamicVec v; + (void)v; +} + +TEST(AllocatorSupportTest, Constructors) { + using MyAlloc = CountingAllocator; + using AllocVec = absl::InlinedVector; + const int ia[] = { 0, 1, 2, 3, 4, 5, 6, 7 }; + int64_t allocated = 0; + MyAlloc alloc(&allocated); + { AllocVec ABSL_ATTRIBUTE_UNUSED v; } + { AllocVec ABSL_ATTRIBUTE_UNUSED v(alloc); } + { AllocVec ABSL_ATTRIBUTE_UNUSED v(ia, ia + ABSL_ARRAYSIZE(ia), alloc); } + { AllocVec ABSL_ATTRIBUTE_UNUSED v({1, 2, 3}, alloc); } + + AllocVec v2; + { AllocVec ABSL_ATTRIBUTE_UNUSED v(v2, alloc); } + { AllocVec ABSL_ATTRIBUTE_UNUSED v(std::move(v2), alloc); } +} + +TEST(AllocatorSupportTest, CountAllocations) { + using MyAlloc = CountingAllocator; + using AllocVec = absl::InlinedVector; + const int ia[] = { 0, 1, 2, 3, 4, 5, 6, 7 }; + int64_t allocated = 0; + MyAlloc alloc(&allocated); + { + AllocVec ABSL_ATTRIBUTE_UNUSED v(ia, ia + 4, alloc); + EXPECT_THAT(allocated, 0); + } + EXPECT_THAT(allocated, 0); + { + AllocVec ABSL_ATTRIBUTE_UNUSED v(ia, ia + ABSL_ARRAYSIZE(ia), alloc); + EXPECT_THAT(allocated, v.size() * sizeof(int)); + } + EXPECT_THAT(allocated, 0); + { + AllocVec v(4, 1, alloc); + EXPECT_THAT(allocated, 0); + + int64_t allocated2 = 0; + MyAlloc alloc2(&allocated2); + AllocVec v2(v, alloc2); + EXPECT_THAT(allocated2, 0); + + int64_t allocated3 = 0; + MyAlloc alloc3(&allocated3); + AllocVec v3(std::move(v), alloc3); + EXPECT_THAT(allocated3, 0); + } + EXPECT_THAT(allocated, 0); + { + AllocVec v(8, 2, alloc); + EXPECT_THAT(allocated, v.size() * sizeof(int)); + + int64_t allocated2 = 0; + MyAlloc alloc2(&allocated2); + AllocVec v2(v, alloc2); + EXPECT_THAT(allocated2, v2.size() * sizeof(int)); + + int64_t allocated3 = 0; + MyAlloc alloc3(&allocated3); + AllocVec v3(std::move(v), alloc3); + EXPECT_THAT(allocated3, v3.size() * sizeof(int)); + } + EXPECT_EQ(allocated, 0); + { + // Test shrink_to_fit deallocations. + AllocVec v(8, 2, alloc); + EXPECT_EQ(allocated, 8 * sizeof(int)); + v.resize(5); + EXPECT_EQ(allocated, 8 * sizeof(int)); + v.shrink_to_fit(); + EXPECT_EQ(allocated, 5 * sizeof(int)); + v.resize(4); + EXPECT_EQ(allocated, 5 * sizeof(int)); + v.shrink_to_fit(); + EXPECT_EQ(allocated, 0); + } +} + +TEST(AllocatorSupportTest, SwapBothAllocated) { + using MyAlloc = CountingAllocator; + using AllocVec = absl::InlinedVector; + int64_t allocated1 = 0; + int64_t allocated2 = 0; + { + const int ia1[] = { 0, 1, 2, 3, 4, 5, 6, 7 }; + const int ia2[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8 }; + MyAlloc a1(&allocated1); + MyAlloc a2(&allocated2); + AllocVec v1(ia1, ia1 + ABSL_ARRAYSIZE(ia1), a1); + AllocVec v2(ia2, ia2 + ABSL_ARRAYSIZE(ia2), a2); + EXPECT_LT(v1.capacity(), v2.capacity()); + EXPECT_THAT(allocated1, v1.capacity() * sizeof(int)); + EXPECT_THAT(allocated2, v2.capacity() * sizeof(int)); + v1.swap(v2); + EXPECT_THAT(v1, ElementsAreArray(ia2)); + EXPECT_THAT(v2, ElementsAreArray(ia1)); + EXPECT_THAT(allocated1, v2.capacity() * sizeof(int)); + EXPECT_THAT(allocated2, v1.capacity() * sizeof(int)); + } + EXPECT_THAT(allocated1, 0); + EXPECT_THAT(allocated2, 0); +} + +TEST(AllocatorSupportTest, SwapOneAllocated) { + using MyAlloc = CountingAllocator; + using AllocVec = absl::InlinedVector; + int64_t allocated1 = 0; + int64_t allocated2 = 0; + { + const int ia1[] = { 0, 1, 2, 3, 4, 5, 6, 7 }; + const int ia2[] = { 0, 1, 2, 3 }; + MyAlloc a1(&allocated1); + MyAlloc a2(&allocated2); + AllocVec v1(ia1, ia1 + ABSL_ARRAYSIZE(ia1), a1); + AllocVec v2(ia2, ia2 + ABSL_ARRAYSIZE(ia2), a2); + EXPECT_THAT(allocated1, v1.capacity() * sizeof(int)); + EXPECT_THAT(allocated2, 0); + v1.swap(v2); + EXPECT_THAT(v1, ElementsAreArray(ia2)); + EXPECT_THAT(v2, ElementsAreArray(ia1)); + EXPECT_THAT(allocated1, v2.capacity() * sizeof(int)); + EXPECT_THAT(allocated2, 0); + EXPECT_TRUE(v2.get_allocator() == a1); + EXPECT_TRUE(v1.get_allocator() == a2); + } + EXPECT_THAT(allocated1, 0); + EXPECT_THAT(allocated2, 0); +} + +TEST(AllocatorSupportTest, ScopedAllocatorWorks) { + using StdVector = std::vector>; + using MyAlloc = + std::scoped_allocator_adaptor>; + using AllocVec = absl::InlinedVector; + + int64_t allocated = 0; + AllocVec vec(MyAlloc{CountingAllocator{&allocated}}); + EXPECT_EQ(allocated, 0); + + // This default constructs a vector, but the allocator should pass itself + // into the vector. + // The absl::InlinedVector does not allocate any memory. + // The vector does not allocate any memory. + vec.resize(1); + EXPECT_EQ(allocated, 0); + + // We make vector allocate memory. + // It must go through the allocator even though we didn't construct the + // vector directly. + vec[0].push_back(1); + EXPECT_EQ(allocated, sizeof(int) * 1); + + // Another allocating vector. + vec.push_back(vec[0]); + EXPECT_EQ(allocated, sizeof(int) * 2); + + // Overflow the inlined memory. + // The absl::InlinedVector will now allocate. + vec.resize(5); + EXPECT_EQ(allocated, sizeof(int) * 2 + sizeof(StdVector) * 8); + + // Adding one more in external mode should also work. + vec.push_back(vec[0]); + EXPECT_EQ(allocated, sizeof(int) * 3 + sizeof(StdVector) * 8); + + // And extending these should still work. + vec[0].push_back(1); + EXPECT_EQ(allocated, sizeof(int) * 4 + sizeof(StdVector) * 8); + + vec.clear(); + EXPECT_EQ(allocated, 0); +} + +TEST(AllocatorSupportTest, SizeAllocConstructor) { + constexpr int inlined_size = 4; + using Alloc = CountingAllocator; + using AllocVec = absl::InlinedVector; + + { + auto len = inlined_size / 2; + int64_t allocated = 0; + auto v = AllocVec(len, Alloc(&allocated)); + + // Inline storage used; allocator should not be invoked + EXPECT_THAT(allocated, 0); + EXPECT_THAT(v, AllOf(SizeIs(len), Each(0))); + } + + { + auto len = inlined_size * 2; + int64_t allocated = 0; + auto v = AllocVec(len, Alloc(&allocated)); + + // Out of line storage used; allocation of 8 elements expected + EXPECT_THAT(allocated, len * sizeof(int)); + EXPECT_THAT(v, AllOf(SizeIs(len), Each(0))); + } +} + +} // anonymous namespace diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/internal/compressed_tuple.h b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/internal/compressed_tuple.h new file mode 100644 index 0000000..cc52614 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/internal/compressed_tuple.h @@ -0,0 +1,175 @@ +// Copyright 2018 The Abseil Authors. +// +// 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. +// +// Helper class to perform the Empty Base Optimization. +// Ts can contain classes and non-classes, empty or not. For the ones that +// are empty classes, we perform the optimization. If all types in Ts are empty +// classes, then CompressedTuple is itself an empty class. +// +// To access the members, use member get() function. +// +// Eg: +// absl::container_internal::CompressedTuple value(7, t1, t2, +// t3); +// assert(value.get<0>() == 7); +// T1& t1 = value.get<1>(); +// const T2& t2 = value.get<2>(); +// ... +// +// http://en.cppreference.com/w/cpp/language/ebo + +#ifndef ABSL_CONTAINER_INTERNAL_COMPRESSED_TUPLE_H_ +#define ABSL_CONTAINER_INTERNAL_COMPRESSED_TUPLE_H_ + +#include +#include +#include + +#include "absl/utility/utility.h" + +#ifdef _MSC_VER +// We need to mark these classes with this declspec to ensure that +// CompressedTuple happens. +#define ABSL_INTERNAL_COMPRESSED_TUPLE_DECLSPEC __declspec(empty_bases) +#else // _MSC_VER +#define ABSL_INTERNAL_COMPRESSED_TUPLE_DECLSPEC +#endif // _MSC_VER + +namespace absl { +namespace container_internal { + +template +class CompressedTuple; + +namespace internal_compressed_tuple { + +template +struct Elem; +template +struct Elem, I> + : std::tuple_element> {}; +template +using ElemT = typename Elem::type; + +// Use the __is_final intrinsic if available. Where it's not available, classes +// declared with the 'final' specifier cannot be used as CompressedTuple +// elements. +// TODO(sbenza): Replace this with std::is_final in C++14. +template +constexpr bool IsFinal() { +#if defined(__clang__) || defined(__GNUC__) + return __is_final(T); +#else + return false; +#endif +} + +template +constexpr bool ShouldUseBase() { + return std::is_class::value && std::is_empty::value && !IsFinal(); +} + +// The storage class provides two specializations: +// - For empty classes, it stores T as a base class. +// - For everything else, it stores T as a member. +template >()> +struct Storage { + using T = ElemT; + T value; + constexpr Storage() = default; + explicit constexpr Storage(T&& v) : value(absl::forward(v)) {} + constexpr const T& get() const { return value; } + T& get() { return value; } +}; + +template +struct ABSL_INTERNAL_COMPRESSED_TUPLE_DECLSPEC Storage + : ElemT { + using T = internal_compressed_tuple::ElemT; + constexpr Storage() = default; + explicit constexpr Storage(T&& v) : T(absl::forward(v)) {} + constexpr const T& get() const { return *this; } + T& get() { return *this; } +}; + +template +struct ABSL_INTERNAL_COMPRESSED_TUPLE_DECLSPEC CompressedTupleImpl; + +template +struct ABSL_INTERNAL_COMPRESSED_TUPLE_DECLSPEC + CompressedTupleImpl, absl::index_sequence> + // We use the dummy identity function through std::integral_constant to + // convince MSVC of accepting and expanding I in that context. Without it + // you would get: + // error C3548: 'I': parameter pack cannot be used in this context + : Storage, + std::integral_constant::value>... { + constexpr CompressedTupleImpl() = default; + explicit constexpr CompressedTupleImpl(Ts&&... args) + : Storage, I>(absl::forward(args))... {} +}; + +} // namespace internal_compressed_tuple + +// Helper class to perform the Empty Base Class Optimization. +// Ts can contain classes and non-classes, empty or not. For the ones that +// are empty classes, we perform the CompressedTuple. If all types in Ts are +// empty classes, then CompressedTuple is itself an empty class. +// +// To access the members, use member .get() function. +// +// Eg: +// absl::container_internal::CompressedTuple value(7, t1, t2, +// t3); +// assert(value.get<0>() == 7); +// T1& t1 = value.get<1>(); +// const T2& t2 = value.get<2>(); +// ... +// +// http://en.cppreference.com/w/cpp/language/ebo +template +class ABSL_INTERNAL_COMPRESSED_TUPLE_DECLSPEC CompressedTuple + : private internal_compressed_tuple::CompressedTupleImpl< + CompressedTuple, absl::index_sequence_for> { + private: + template + using ElemT = internal_compressed_tuple::ElemT; + + public: + constexpr CompressedTuple() = default; + explicit constexpr CompressedTuple(Ts... base) + : CompressedTuple::CompressedTupleImpl(absl::forward(base)...) {} + + template + ElemT& get() { + return internal_compressed_tuple::Storage::get(); + } + + template + constexpr const ElemT& get() const { + return internal_compressed_tuple::Storage::get(); + } +}; + +// Explicit specialization for a zero-element tuple +// (needed to avoid ambiguous overloads for the default constructor). +template <> +class ABSL_INTERNAL_COMPRESSED_TUPLE_DECLSPEC CompressedTuple<> {}; + +} // namespace container_internal +} // namespace absl + +#undef ABSL_INTERNAL_COMPRESSED_TUPLE_DECLSPEC + +#endif // ABSL_CONTAINER_INTERNAL_COMPRESSED_TUPLE_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/internal/compressed_tuple_test.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/internal/compressed_tuple_test.cc new file mode 100644 index 0000000..45030c6 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/internal/compressed_tuple_test.cc @@ -0,0 +1,166 @@ +// Copyright 2018 The Abseil Authors. +// +// 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 "absl/container/internal/compressed_tuple.h" + +#include + +#include "gmock/gmock.h" +#include "gtest/gtest.h" + +namespace absl { +namespace container_internal { +namespace { + +template +struct Empty {}; + +template +struct NotEmpty { + T value; +}; + +template +struct TwoValues { + T value1; + U value2; +}; + +TEST(CompressedTupleTest, Sizeof) { + EXPECT_EQ(sizeof(int), sizeof(CompressedTuple)); + EXPECT_EQ(sizeof(int), sizeof(CompressedTuple>)); + EXPECT_EQ(sizeof(int), sizeof(CompressedTuple, Empty<1>>)); + EXPECT_EQ(sizeof(int), + sizeof(CompressedTuple, Empty<1>, Empty<2>>)); + + EXPECT_EQ(sizeof(TwoValues), + sizeof(CompressedTuple>)); + EXPECT_EQ(sizeof(TwoValues), + sizeof(CompressedTuple, NotEmpty>)); + EXPECT_EQ(sizeof(TwoValues), + sizeof(CompressedTuple, NotEmpty, Empty<1>>)); +} + +TEST(CompressedTupleTest, Access) { + struct S { + std::string x; + }; + CompressedTuple, S> x(7, {}, S{"ABC"}); + EXPECT_EQ(sizeof(x), sizeof(TwoValues)); + EXPECT_EQ(7, x.get<0>()); + EXPECT_EQ("ABC", x.get<2>().x); +} + +TEST(CompressedTupleTest, NonClasses) { + CompressedTuple x(7, "ABC"); + EXPECT_EQ(7, x.get<0>()); + EXPECT_STREQ("ABC", x.get<1>()); +} + +TEST(CompressedTupleTest, MixClassAndNonClass) { + CompressedTuple, NotEmpty> x(7, "ABC", {}, + {1.25}); + struct Mock { + int v; + const char* p; + double d; + }; + EXPECT_EQ(sizeof(x), sizeof(Mock)); + EXPECT_EQ(7, x.get<0>()); + EXPECT_STREQ("ABC", x.get<1>()); + EXPECT_EQ(1.25, x.get<3>().value); +} + +TEST(CompressedTupleTest, Nested) { + CompressedTuple, + CompressedTuple>> + x(1, CompressedTuple(2), + CompressedTuple>(3, CompressedTuple(4))); + EXPECT_EQ(1, x.get<0>()); + EXPECT_EQ(2, x.get<1>().get<0>()); + EXPECT_EQ(3, x.get<2>().get<0>()); + EXPECT_EQ(4, x.get<2>().get<1>().get<0>()); + + CompressedTuple, Empty<0>, + CompressedTuple, CompressedTuple>>> + y; + std::set*> empties{&y.get<0>(), &y.get<1>(), &y.get<2>().get<0>(), + &y.get<2>().get<1>().get<0>()}; +#ifdef _MSC_VER + // MSVC has a bug where many instances of the same base class are layed out in + // the same address when using __declspec(empty_bases). + // This will be fixed in a future version of MSVC. + int expected = 1; +#else + int expected = 4; +#endif + EXPECT_EQ(expected, sizeof(y)); + EXPECT_EQ(expected, empties.size()); + EXPECT_EQ(sizeof(y), sizeof(Empty<0>) * empties.size()); + + EXPECT_EQ(4 * sizeof(char), + sizeof(CompressedTuple, + CompressedTuple>)); + EXPECT_TRUE( + (std::is_empty>, + CompressedTuple>>>::value)); +} + +TEST(CompressedTupleTest, Reference) { + int i = 7; + std::string s = "Very long std::string that goes in the heap"; + CompressedTuple x(i, i, s, s); + + // Sanity check. We should have not moved from `s` + EXPECT_EQ(s, "Very long std::string that goes in the heap"); + + EXPECT_EQ(x.get<0>(), x.get<1>()); + EXPECT_NE(&x.get<0>(), &x.get<1>()); + EXPECT_EQ(&x.get<1>(), &i); + + EXPECT_EQ(x.get<2>(), x.get<3>()); + EXPECT_NE(&x.get<2>(), &x.get<3>()); + EXPECT_EQ(&x.get<3>(), &s); +} + +TEST(CompressedTupleTest, NoElements) { + CompressedTuple<> x; + static_cast(x); // Silence -Wunused-variable. + EXPECT_TRUE(std::is_empty>::value); +} + +TEST(CompressedTupleTest, Constexpr) { + constexpr CompressedTuple> x( + 7, 1.25, CompressedTuple(5)); + constexpr int x0 = x.get<0>(); + constexpr double x1 = x.get<1>(); + constexpr int x2 = x.get<2>().get<0>(); + EXPECT_EQ(x0, 7); + EXPECT_EQ(x1, 1.25); + EXPECT_EQ(x2, 5); +} + +#if defined(__clang__) || defined(__GNUC__) +TEST(CompressedTupleTest, EmptyFinalClass) { + struct S final { + int f() const { return 5; } + }; + CompressedTuple x; + EXPECT_EQ(x.get<0>().f(), 5); +} +#endif + +} // namespace +} // namespace container_internal +} // namespace absl diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/internal/container_memory.h b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/internal/container_memory.h new file mode 100644 index 0000000..56c5d2d --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/internal/container_memory.h @@ -0,0 +1,405 @@ +// Copyright 2018 The Abseil Authors. +// +// 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. + +#ifndef ABSL_CONTAINER_INTERNAL_CONTAINER_MEMORY_H_ +#define ABSL_CONTAINER_INTERNAL_CONTAINER_MEMORY_H_ + +#ifdef ADDRESS_SANITIZER +#include +#endif + +#ifdef MEMORY_SANITIZER +#include +#endif + +#include +#include +#include +#include +#include +#include + +#include "absl/memory/memory.h" +#include "absl/utility/utility.h" + +namespace absl { +namespace container_internal { + +// Allocates at least n bytes aligned to the specified alignment. +// Alignment must be a power of 2. It must be positive. +// +// Note that many allocators don't honor alignment requirements above certain +// threshold (usually either alignof(std::max_align_t) or alignof(void*)). +// Allocate() doesn't apply alignment corrections. If the underlying allocator +// returns insufficiently alignment pointer, that's what you are going to get. +template +void* Allocate(Alloc* alloc, size_t n) { + static_assert(Alignment > 0, ""); + assert(n && "n must be positive"); + struct alignas(Alignment) M {}; + using A = typename absl::allocator_traits::template rebind_alloc; + using AT = typename absl::allocator_traits::template rebind_traits; + A mem_alloc(*alloc); + void* p = AT::allocate(mem_alloc, (n + sizeof(M) - 1) / sizeof(M)); + assert(reinterpret_cast(p) % Alignment == 0 && + "allocator does not respect alignment"); + return p; +} + +// The pointer must have been previously obtained by calling +// Allocate(alloc, n). +template +void Deallocate(Alloc* alloc, void* p, size_t n) { + static_assert(Alignment > 0, ""); + assert(n && "n must be positive"); + struct alignas(Alignment) M {}; + using A = typename absl::allocator_traits::template rebind_alloc; + using AT = typename absl::allocator_traits::template rebind_traits; + A mem_alloc(*alloc); + AT::deallocate(mem_alloc, static_cast(p), + (n + sizeof(M) - 1) / sizeof(M)); +} + +namespace memory_internal { + +// Constructs T into uninitialized storage pointed by `ptr` using the args +// specified in the tuple. +template +void ConstructFromTupleImpl(Alloc* alloc, T* ptr, Tuple&& t, + absl::index_sequence) { + absl::allocator_traits::construct( + *alloc, ptr, std::get(std::forward(t))...); +} + +template +struct WithConstructedImplF { + template + decltype(std::declval()(std::declval())) operator()( + Args&&... args) const { + return std::forward(f)(T(std::forward(args)...)); + } + F&& f; +}; + +template +decltype(std::declval()(std::declval())) WithConstructedImpl( + Tuple&& t, absl::index_sequence, F&& f) { + return WithConstructedImplF{std::forward(f)}( + std::get(std::forward(t))...); +} + +template +auto TupleRefImpl(T&& t, absl::index_sequence) + -> decltype(std::forward_as_tuple(std::get(std::forward(t))...)) { + return std::forward_as_tuple(std::get(std::forward(t))...); +} + +// Returns a tuple of references to the elements of the input tuple. T must be a +// tuple. +template +auto TupleRef(T&& t) -> decltype( + TupleRefImpl(std::forward(t), + absl::make_index_sequence< + std::tuple_size::type>::value>())) { + return TupleRefImpl( + std::forward(t), + absl::make_index_sequence< + std::tuple_size::type>::value>()); +} + +template +decltype(std::declval()(std::declval(), std::piecewise_construct, + std::declval>(), std::declval())) +DecomposePairImpl(F&& f, std::pair, V> p) { + const auto& key = std::get<0>(p.first); + return std::forward(f)(key, std::piecewise_construct, std::move(p.first), + std::move(p.second)); +} + +} // namespace memory_internal + +// Constructs T into uninitialized storage pointed by `ptr` using the args +// specified in the tuple. +template +void ConstructFromTuple(Alloc* alloc, T* ptr, Tuple&& t) { + memory_internal::ConstructFromTupleImpl( + alloc, ptr, std::forward(t), + absl::make_index_sequence< + std::tuple_size::type>::value>()); +} + +// Constructs T using the args specified in the tuple and calls F with the +// constructed value. +template +decltype(std::declval()(std::declval())) WithConstructed( + Tuple&& t, F&& f) { + return memory_internal::WithConstructedImpl( + std::forward(t), + absl::make_index_sequence< + std::tuple_size::type>::value>(), + std::forward(f)); +} + +// Given arguments of an std::pair's consructor, PairArgs() returns a pair of +// tuples with references to the passed arguments. The tuples contain +// constructor arguments for the first and the second elements of the pair. +// +// The following two snippets are equivalent. +// +// 1. std::pair p(args...); +// +// 2. auto a = PairArgs(args...); +// std::pair p(std::piecewise_construct, +// std::move(p.first), std::move(p.second)); +inline std::pair, std::tuple<>> PairArgs() { return {}; } +template +std::pair, std::tuple> PairArgs(F&& f, S&& s) { + return {std::piecewise_construct, std::forward_as_tuple(std::forward(f)), + std::forward_as_tuple(std::forward(s))}; +} +template +std::pair, std::tuple> PairArgs( + const std::pair& p) { + return PairArgs(p.first, p.second); +} +template +std::pair, std::tuple> PairArgs(std::pair&& p) { + return PairArgs(std::forward(p.first), std::forward(p.second)); +} +template +auto PairArgs(std::piecewise_construct_t, F&& f, S&& s) + -> decltype(std::make_pair(memory_internal::TupleRef(std::forward(f)), + memory_internal::TupleRef(std::forward(s)))) { + return std::make_pair(memory_internal::TupleRef(std::forward(f)), + memory_internal::TupleRef(std::forward(s))); +} + +// A helper function for implementing apply() in map policies. +template +auto DecomposePair(F&& f, Args&&... args) + -> decltype(memory_internal::DecomposePairImpl( + std::forward(f), PairArgs(std::forward(args)...))) { + return memory_internal::DecomposePairImpl( + std::forward(f), PairArgs(std::forward(args)...)); +} + +// A helper function for implementing apply() in set policies. +template +decltype(std::declval()(std::declval(), std::declval())) +DecomposeValue(F&& f, Arg&& arg) { + const auto& key = arg; + return std::forward(f)(key, std::forward(arg)); +} + +// Helper functions for asan and msan. +inline void SanitizerPoisonMemoryRegion(const void* m, size_t s) { +#ifdef ADDRESS_SANITIZER + ASAN_POISON_MEMORY_REGION(m, s); +#endif +#ifdef MEMORY_SANITIZER + __msan_poison(m, s); +#endif + (void)m; + (void)s; +} + +inline void SanitizerUnpoisonMemoryRegion(const void* m, size_t s) { +#ifdef ADDRESS_SANITIZER + ASAN_UNPOISON_MEMORY_REGION(m, s); +#endif +#ifdef MEMORY_SANITIZER + __msan_unpoison(m, s); +#endif + (void)m; + (void)s; +} + +template +inline void SanitizerPoisonObject(const T* object) { + SanitizerPoisonMemoryRegion(object, sizeof(T)); +} + +template +inline void SanitizerUnpoisonObject(const T* object) { + SanitizerUnpoisonMemoryRegion(object, sizeof(T)); +} + +namespace memory_internal { + +// If Pair is a standard-layout type, OffsetOf::kFirst and +// OffsetOf::kSecond are equivalent to offsetof(Pair, first) and +// offsetof(Pair, second) respectively. Otherwise they are -1. +// +// The purpose of OffsetOf is to avoid calling offsetof() on non-standard-layout +// type, which is non-portable. +template +struct OffsetOf { + static constexpr size_t kFirst = -1; + static constexpr size_t kSecond = -1; +}; + +template +struct OffsetOf::type> { + static constexpr size_t kFirst = offsetof(Pair, first); + static constexpr size_t kSecond = offsetof(Pair, second); +}; + +template +struct IsLayoutCompatible { + private: + struct Pair { + K first; + V second; + }; + + // Is P layout-compatible with Pair? + template + static constexpr bool LayoutCompatible() { + return std::is_standard_layout

() && sizeof(P) == sizeof(Pair) && + alignof(P) == alignof(Pair) && + memory_internal::OffsetOf

::kFirst == + memory_internal::OffsetOf::kFirst && + memory_internal::OffsetOf

::kSecond == + memory_internal::OffsetOf::kSecond; + } + + public: + // Whether pair and pair are layout-compatible. If they are, + // then it is safe to store them in a union and read from either. + static constexpr bool value = std::is_standard_layout() && + std::is_standard_layout() && + memory_internal::OffsetOf::kFirst == 0 && + LayoutCompatible>() && + LayoutCompatible>(); +}; + +} // namespace memory_internal + +// If kMutableKeys is false, only the value member is accessed. +// +// If kMutableKeys is true, key is accessed through all slots while value and +// mutable_value are accessed only via INITIALIZED slots. Slots are created and +// destroyed via mutable_value so that the key can be moved later. +template +union slot_type { + private: + static void emplace(slot_type* slot) { + // The construction of union doesn't do anything at runtime but it allows us + // to access its members without violating aliasing rules. + new (slot) slot_type; + } + // If pair and pair are layout-compatible, we can accept one + // or the other via slot_type. We are also free to access the key via + // slot_type::key in this case. + using kMutableKeys = + std::integral_constant::value>; + + public: + slot_type() {} + ~slot_type() = delete; + using value_type = std::pair; + using mutable_value_type = std::pair; + + value_type value; + mutable_value_type mutable_value; + K key; + + template + static void construct(Allocator* alloc, slot_type* slot, Args&&... args) { + emplace(slot); + if (kMutableKeys::value) { + absl::allocator_traits::construct(*alloc, &slot->mutable_value, + std::forward(args)...); + } else { + absl::allocator_traits::construct(*alloc, &slot->value, + std::forward(args)...); + } + } + + // Construct this slot by moving from another slot. + template + static void construct(Allocator* alloc, slot_type* slot, slot_type* other) { + emplace(slot); + if (kMutableKeys::value) { + absl::allocator_traits::construct( + *alloc, &slot->mutable_value, std::move(other->mutable_value)); + } else { + absl::allocator_traits::construct(*alloc, &slot->value, + std::move(other->value)); + } + } + + template + static void destroy(Allocator* alloc, slot_type* slot) { + if (kMutableKeys::value) { + absl::allocator_traits::destroy(*alloc, &slot->mutable_value); + } else { + absl::allocator_traits::destroy(*alloc, &slot->value); + } + } + + template + static void transfer(Allocator* alloc, slot_type* new_slot, + slot_type* old_slot) { + emplace(new_slot); + if (kMutableKeys::value) { + absl::allocator_traits::construct( + *alloc, &new_slot->mutable_value, std::move(old_slot->mutable_value)); + } else { + absl::allocator_traits::construct(*alloc, &new_slot->value, + std::move(old_slot->value)); + } + destroy(alloc, old_slot); + } + + template + static void swap(Allocator* alloc, slot_type* a, slot_type* b) { + if (kMutableKeys::value) { + using std::swap; + swap(a->mutable_value, b->mutable_value); + } else { + value_type tmp = std::move(a->value); + absl::allocator_traits::destroy(*alloc, &a->value); + absl::allocator_traits::construct(*alloc, &a->value, + std::move(b->value)); + absl::allocator_traits::destroy(*alloc, &b->value); + absl::allocator_traits::construct(*alloc, &b->value, + std::move(tmp)); + } + } + + template + static void move(Allocator* alloc, slot_type* src, slot_type* dest) { + if (kMutableKeys::value) { + dest->mutable_value = std::move(src->mutable_value); + } else { + absl::allocator_traits::destroy(*alloc, &dest->value); + absl::allocator_traits::construct(*alloc, &dest->value, + std::move(src->value)); + } + } + + template + static void move(Allocator* alloc, slot_type* first, slot_type* last, + slot_type* result) { + for (slot_type *src = first, *dest = result; src != last; ++src, ++dest) + move(alloc, src, dest); + } +}; + +} // namespace container_internal +} // namespace absl + +#endif // ABSL_CONTAINER_INTERNAL_CONTAINER_MEMORY_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/internal/container_memory_test.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/internal/container_memory_test.cc new file mode 100644 index 0000000..f1c4058 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/internal/container_memory_test.cc @@ -0,0 +1,188 @@ +// Copyright 2018 The Abseil Authors. +// +// 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 "absl/container/internal/container_memory.h" + +#include +#include +#include + +#include "gmock/gmock.h" +#include "gtest/gtest.h" +#include "absl/strings/string_view.h" + +namespace absl { +namespace container_internal { +namespace { + +using ::testing::Pair; + +TEST(Memory, AlignmentLargerThanBase) { + std::allocator alloc; + void* mem = Allocate<2>(&alloc, 3); + EXPECT_EQ(0, reinterpret_cast(mem) % 2); + memcpy(mem, "abc", 3); + Deallocate<2>(&alloc, mem, 3); +} + +TEST(Memory, AlignmentSmallerThanBase) { + std::allocator alloc; + void* mem = Allocate<2>(&alloc, 3); + EXPECT_EQ(0, reinterpret_cast(mem) % 2); + memcpy(mem, "abc", 3); + Deallocate<2>(&alloc, mem, 3); +} + +class Fixture : public ::testing::Test { + using Alloc = std::allocator; + + public: + Fixture() { ptr_ = std::allocator_traits::allocate(*alloc(), 1); } + ~Fixture() override { + std::allocator_traits::destroy(*alloc(), ptr_); + std::allocator_traits::deallocate(*alloc(), ptr_, 1); + } + std::string* ptr() { return ptr_; } + Alloc* alloc() { return &alloc_; } + + private: + Alloc alloc_; + std::string* ptr_; +}; + +TEST_F(Fixture, ConstructNoArgs) { + ConstructFromTuple(alloc(), ptr(), std::forward_as_tuple()); + EXPECT_EQ(*ptr(), ""); +} + +TEST_F(Fixture, ConstructOneArg) { + ConstructFromTuple(alloc(), ptr(), std::forward_as_tuple("abcde")); + EXPECT_EQ(*ptr(), "abcde"); +} + +TEST_F(Fixture, ConstructTwoArg) { + ConstructFromTuple(alloc(), ptr(), std::forward_as_tuple(5, 'a')); + EXPECT_EQ(*ptr(), "aaaaa"); +} + +TEST(PairArgs, NoArgs) { + EXPECT_THAT(PairArgs(), + Pair(std::forward_as_tuple(), std::forward_as_tuple())); +} + +TEST(PairArgs, TwoArgs) { + EXPECT_EQ( + std::make_pair(std::forward_as_tuple(1), std::forward_as_tuple('A')), + PairArgs(1, 'A')); +} + +TEST(PairArgs, Pair) { + EXPECT_EQ( + std::make_pair(std::forward_as_tuple(1), std::forward_as_tuple('A')), + PairArgs(std::make_pair(1, 'A'))); +} + +TEST(PairArgs, Piecewise) { + EXPECT_EQ( + std::make_pair(std::forward_as_tuple(1), std::forward_as_tuple('A')), + PairArgs(std::piecewise_construct, std::forward_as_tuple(1), + std::forward_as_tuple('A'))); +} + +TEST(WithConstructed, Simple) { + EXPECT_EQ(1, WithConstructed( + std::make_tuple(std::string("a")), + [](absl::string_view str) { return str.size(); })); +} + +template +decltype(DecomposeValue(std::declval(), std::declval())) +DecomposeValueImpl(int, F&& f, Arg&& arg) { + return DecomposeValue(std::forward(f), std::forward(arg)); +} + +template +const char* DecomposeValueImpl(char, F&& f, Arg&& arg) { + return "not decomposable"; +} + +template +decltype(DecomposeValueImpl(0, std::declval(), std::declval())) +TryDecomposeValue(F&& f, Arg&& arg) { + return DecomposeValueImpl(0, std::forward(f), std::forward(arg)); +} + +TEST(DecomposeValue, Decomposable) { + auto f = [](const int& x, int&& y) { + EXPECT_EQ(&x, &y); + EXPECT_EQ(42, x); + return 'A'; + }; + EXPECT_EQ('A', TryDecomposeValue(f, 42)); +} + +TEST(DecomposeValue, NotDecomposable) { + auto f = [](void*) { + ADD_FAILURE() << "Must not be called"; + return 'A'; + }; + EXPECT_STREQ("not decomposable", TryDecomposeValue(f, 42)); +} + +template +decltype(DecomposePair(std::declval(), std::declval()...)) +DecomposePairImpl(int, F&& f, Args&&... args) { + return DecomposePair(std::forward(f), std::forward(args)...); +} + +template +const char* DecomposePairImpl(char, F&& f, Args&&... args) { + return "not decomposable"; +} + +template +decltype(DecomposePairImpl(0, std::declval(), std::declval()...)) +TryDecomposePair(F&& f, Args&&... args) { + return DecomposePairImpl(0, std::forward(f), std::forward(args)...); +} + +TEST(DecomposePair, Decomposable) { + auto f = [](const int& x, std::piecewise_construct_t, std::tuple k, + std::tuple&& v) { + EXPECT_EQ(&x, &std::get<0>(k)); + EXPECT_EQ(42, x); + EXPECT_EQ(0.5, std::get<0>(v)); + return 'A'; + }; + EXPECT_EQ('A', TryDecomposePair(f, 42, 0.5)); + EXPECT_EQ('A', TryDecomposePair(f, std::make_pair(42, 0.5))); + EXPECT_EQ('A', TryDecomposePair(f, std::piecewise_construct, + std::make_tuple(42), std::make_tuple(0.5))); +} + +TEST(DecomposePair, NotDecomposable) { + auto f = [](...) { + ADD_FAILURE() << "Must not be called"; + return 'A'; + }; + EXPECT_STREQ("not decomposable", + TryDecomposePair(f)); + EXPECT_STREQ("not decomposable", + TryDecomposePair(f, std::piecewise_construct, std::make_tuple(), + std::make_tuple(0.5))); +} + +} // namespace +} // namespace container_internal +} // namespace absl diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/internal/hash_function_defaults.h b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/internal/hash_function_defaults.h new file mode 100644 index 0000000..1f0d794 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/internal/hash_function_defaults.h @@ -0,0 +1,143 @@ +// Copyright 2018 The Abseil Authors. +// +// 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. +// +// Define the default Hash and Eq functions for SwissTable containers. +// +// std::hash and std::equal_to are not appropriate hash and equal +// functions for SwissTable containers. There are two reasons for this. +// +// SwissTable containers are power of 2 sized containers: +// +// This means they use the lower bits of the hash value to find the slot for +// each entry. The typical hash function for integral types is the identity. +// This is a very weak hash function for SwissTable and any power of 2 sized +// hashtable implementation which will lead to excessive collisions. For +// SwissTable we use murmur3 style mixing to reduce collisions to a minimum. +// +// SwissTable containers support heterogeneous lookup: +// +// In order to make heterogeneous lookup work, hash and equal functions must be +// polymorphic. At the same time they have to satisfy the same requirements the +// C++ standard imposes on hash functions and equality operators. That is: +// +// if hash_default_eq(a, b) returns true for any a and b of type T, then +// hash_default_hash(a) must equal hash_default_hash(b) +// +// For SwissTable containers this requirement is relaxed to allow a and b of +// any and possibly different types. Note that like the standard the hash and +// equal functions are still bound to T. This is important because some type U +// can be hashed by/tested for equality differently depending on T. A notable +// example is `const char*`. `const char*` is treated as a c-style string when +// the hash function is hash but as a pointer when the hash function is +// hash. +// +#ifndef ABSL_CONTAINER_INTERNAL_HASH_FUNCTION_DEFAULTS_H_ +#define ABSL_CONTAINER_INTERNAL_HASH_FUNCTION_DEFAULTS_H_ + +#include +#include +#include +#include +#include + +#include "absl/base/config.h" +#include "absl/hash/hash.h" +#include "absl/strings/string_view.h" + +namespace absl { +namespace container_internal { + +// The hash of an object of type T is computed by using absl::Hash. +template +struct HashEq { + using Hash = absl::Hash; + using Eq = std::equal_to; +}; + +struct StringHash { + using is_transparent = void; + + size_t operator()(absl::string_view v) const { + return absl::Hash{}(v); + } +}; + +// Supports heterogeneous lookup for string-like elements. +struct StringHashEq { + using Hash = StringHash; + struct Eq { + using is_transparent = void; + bool operator()(absl::string_view lhs, absl::string_view rhs) const { + return lhs == rhs; + } + }; +}; +template <> +struct HashEq : StringHashEq {}; +template <> +struct HashEq : StringHashEq {}; + +// Supports heterogeneous lookup for pointers and smart pointers. +template +struct HashEq { + struct Hash { + using is_transparent = void; + template + size_t operator()(const U& ptr) const { + return absl::Hash{}(HashEq::ToPtr(ptr)); + } + }; + struct Eq { + using is_transparent = void; + template + bool operator()(const A& a, const B& b) const { + return HashEq::ToPtr(a) == HashEq::ToPtr(b); + } + }; + + private: + static const T* ToPtr(const T* ptr) { return ptr; } + template + static const T* ToPtr(const std::unique_ptr& ptr) { + return ptr.get(); + } + template + static const T* ToPtr(const std::shared_ptr& ptr) { + return ptr.get(); + } +}; + +template +struct HashEq> : HashEq {}; +template +struct HashEq> : HashEq {}; + +// This header's visibility is restricted. If you need to access the default +// hasher please use the container's ::hasher alias instead. +// +// Example: typename Hash = typename absl::flat_hash_map::hasher +template +using hash_default_hash = typename container_internal::HashEq::Hash; + +// This header's visibility is restricted. If you need to access the default +// key equal please use the container's ::key_equal alias instead. +// +// Example: typename Eq = typename absl::flat_hash_map::key_equal +template +using hash_default_eq = typename container_internal::HashEq::Eq; + +} // namespace container_internal +} // namespace absl + +#endif // ABSL_CONTAINER_INTERNAL_HASH_FUNCTION_DEFAULTS_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/internal/hash_function_defaults_test.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/internal/hash_function_defaults_test.cc new file mode 100644 index 0000000..464baae --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/internal/hash_function_defaults_test.cc @@ -0,0 +1,299 @@ +// Copyright 2018 The Abseil Authors. +// +// 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 "absl/container/internal/hash_function_defaults.h" + +#include +#include +#include + +#include "gtest/gtest.h" +#include "absl/strings/string_view.h" + +namespace absl { +namespace container_internal { +namespace { + +using ::testing::Types; + +TEST(Eq, Int32) { + hash_default_eq eq; + EXPECT_TRUE(eq(1, 1u)); + EXPECT_TRUE(eq(1, char{1})); + EXPECT_TRUE(eq(1, true)); + EXPECT_TRUE(eq(1, double{1.1})); + EXPECT_FALSE(eq(1, char{2})); + EXPECT_FALSE(eq(1, 2u)); + EXPECT_FALSE(eq(1, false)); + EXPECT_FALSE(eq(1, 2.)); +} + +TEST(Hash, Int32) { + hash_default_hash hash; + auto h = hash(1); + EXPECT_EQ(h, hash(1u)); + EXPECT_EQ(h, hash(char{1})); + EXPECT_EQ(h, hash(true)); + EXPECT_EQ(h, hash(double{1.1})); + EXPECT_NE(h, hash(2u)); + EXPECT_NE(h, hash(char{2})); + EXPECT_NE(h, hash(false)); + EXPECT_NE(h, hash(2.)); +} + +enum class MyEnum { A, B, C, D }; + +TEST(Eq, Enum) { + hash_default_eq eq; + EXPECT_TRUE(eq(MyEnum::A, MyEnum::A)); + EXPECT_FALSE(eq(MyEnum::A, MyEnum::B)); +} + +TEST(Hash, Enum) { + hash_default_hash hash; + + for (MyEnum e : {MyEnum::A, MyEnum::B, MyEnum::C}) { + auto h = hash(e); + EXPECT_EQ(h, hash_default_hash{}(static_cast(e))); + EXPECT_NE(h, hash(MyEnum::D)); + } +} + +using StringTypes = ::testing::Types; + +template +struct EqString : ::testing::Test { + hash_default_eq key_eq; +}; + +TYPED_TEST_CASE(EqString, StringTypes); + +template +struct HashString : ::testing::Test { + hash_default_hash hasher; +}; + +TYPED_TEST_CASE(HashString, StringTypes); + +TYPED_TEST(EqString, Works) { + auto eq = this->key_eq; + EXPECT_TRUE(eq("a", "a")); + EXPECT_TRUE(eq("a", absl::string_view("a"))); + EXPECT_TRUE(eq("a", std::string("a"))); + EXPECT_FALSE(eq("a", "b")); + EXPECT_FALSE(eq("a", absl::string_view("b"))); + EXPECT_FALSE(eq("a", std::string("b"))); +} + +TYPED_TEST(HashString, Works) { + auto hash = this->hasher; + auto h = hash("a"); + EXPECT_EQ(h, hash(absl::string_view("a"))); + EXPECT_EQ(h, hash(std::string("a"))); + EXPECT_NE(h, hash(absl::string_view("b"))); + EXPECT_NE(h, hash(std::string("b"))); +} + +struct NoDeleter { + template + void operator()(const T* ptr) const {} +}; + +using PointerTypes = + ::testing::Types, + std::unique_ptr, + std::unique_ptr, std::unique_ptr, + std::shared_ptr, std::shared_ptr>; + +template +struct EqPointer : ::testing::Test { + hash_default_eq key_eq; +}; + +TYPED_TEST_CASE(EqPointer, PointerTypes); + +template +struct HashPointer : ::testing::Test { + hash_default_hash hasher; +}; + +TYPED_TEST_CASE(HashPointer, PointerTypes); + +TYPED_TEST(EqPointer, Works) { + int dummy; + auto eq = this->key_eq; + auto sptr = std::make_shared(); + std::shared_ptr csptr = sptr; + int* ptr = sptr.get(); + const int* cptr = ptr; + std::unique_ptr uptr(ptr); + std::unique_ptr cuptr(ptr); + + EXPECT_TRUE(eq(ptr, cptr)); + EXPECT_TRUE(eq(ptr, sptr)); + EXPECT_TRUE(eq(ptr, uptr)); + EXPECT_TRUE(eq(ptr, csptr)); + EXPECT_TRUE(eq(ptr, cuptr)); + EXPECT_FALSE(eq(&dummy, cptr)); + EXPECT_FALSE(eq(&dummy, sptr)); + EXPECT_FALSE(eq(&dummy, uptr)); + EXPECT_FALSE(eq(&dummy, csptr)); + EXPECT_FALSE(eq(&dummy, cuptr)); +} + +TEST(Hash, DerivedAndBase) { + struct Base {}; + struct Derived : Base {}; + + hash_default_hash hasher; + + Base base; + Derived derived; + EXPECT_NE(hasher(&base), hasher(&derived)); + EXPECT_EQ(hasher(static_cast(&derived)), hasher(&derived)); + + auto dp = std::make_shared(); + EXPECT_EQ(hasher(static_cast(dp.get())), hasher(dp)); +} + +TEST(Hash, FunctionPointer) { + using Func = int (*)(); + hash_default_hash hasher; + hash_default_eq eq; + + Func p1 = [] { return 1; }, p2 = [] { return 2; }; + EXPECT_EQ(hasher(p1), hasher(p1)); + EXPECT_TRUE(eq(p1, p1)); + + EXPECT_NE(hasher(p1), hasher(p2)); + EXPECT_FALSE(eq(p1, p2)); +} + +TYPED_TEST(HashPointer, Works) { + int dummy; + auto hash = this->hasher; + auto sptr = std::make_shared(); + std::shared_ptr csptr = sptr; + int* ptr = sptr.get(); + const int* cptr = ptr; + std::unique_ptr uptr(ptr); + std::unique_ptr cuptr(ptr); + + EXPECT_EQ(hash(ptr), hash(cptr)); + EXPECT_EQ(hash(ptr), hash(sptr)); + EXPECT_EQ(hash(ptr), hash(uptr)); + EXPECT_EQ(hash(ptr), hash(csptr)); + EXPECT_EQ(hash(ptr), hash(cuptr)); + EXPECT_NE(hash(&dummy), hash(cptr)); + EXPECT_NE(hash(&dummy), hash(sptr)); + EXPECT_NE(hash(&dummy), hash(uptr)); + EXPECT_NE(hash(&dummy), hash(csptr)); + EXPECT_NE(hash(&dummy), hash(cuptr)); +} + +// Cartesian product of (string, std::string, absl::string_view) +// with (string, std::string, absl::string_view, const char*). +using StringTypesCartesianProduct = Types< + // clang-format off + + std::pair, + std::pair, + std::pair, + + std::pair, + std::pair, + std::pair>; +// clang-format on + +constexpr char kFirstString[] = "abc123"; +constexpr char kSecondString[] = "ijk456"; + +template +struct StringLikeTest : public ::testing::Test { + typename T::first_type a1{kFirstString}; + typename T::second_type b1{kFirstString}; + typename T::first_type a2{kSecondString}; + typename T::second_type b2{kSecondString}; + hash_default_eq eq; + hash_default_hash hash; +}; + +TYPED_TEST_CASE_P(StringLikeTest); + +TYPED_TEST_P(StringLikeTest, Eq) { + EXPECT_TRUE(this->eq(this->a1, this->b1)); + EXPECT_TRUE(this->eq(this->b1, this->a1)); +} + +TYPED_TEST_P(StringLikeTest, NotEq) { + EXPECT_FALSE(this->eq(this->a1, this->b2)); + EXPECT_FALSE(this->eq(this->b2, this->a1)); +} + +TYPED_TEST_P(StringLikeTest, HashEq) { + EXPECT_EQ(this->hash(this->a1), this->hash(this->b1)); + EXPECT_EQ(this->hash(this->a2), this->hash(this->b2)); + // It would be a poor hash function which collides on these strings. + EXPECT_NE(this->hash(this->a1), this->hash(this->b2)); +} + +TYPED_TEST_CASE(StringLikeTest, StringTypesCartesianProduct); + +} // namespace +} // namespace container_internal +} // namespace absl + +enum Hash : size_t { + kStd = 0x2, // std::hash +#ifdef _MSC_VER + kExtension = kStd, // In MSVC, std::hash == ::hash +#else // _MSC_VER + kExtension = 0x4, // ::hash (GCC extension) +#endif // _MSC_VER +}; + +// H is a bitmask of Hash enumerations. +// Hashable is hashable via all means specified in H. +template +struct Hashable { + static constexpr bool HashableBy(Hash h) { return h & H; } +}; + +namespace std { +template +struct hash> { + template , + class = typename std::enable_if::type> + size_t operator()(E) const { + return kStd; + } +}; +} // namespace std + +namespace absl { +namespace container_internal { +namespace { + +template +size_t Hash(const T& v) { + return hash_default_hash()(v); +} + +TEST(Delegate, HashDispatch) { + EXPECT_EQ(Hash(kStd), Hash(Hashable())); +} + +} // namespace +} // namespace container_internal +} // namespace absl diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/internal/hash_generator_testing.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/internal/hash_generator_testing.cc new file mode 100644 index 0000000..0d6a9df --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/internal/hash_generator_testing.cc @@ -0,0 +1,72 @@ +// Copyright 2018 The Abseil Authors. +// +// 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 "absl/container/internal/hash_generator_testing.h" + +#include + +namespace absl { +namespace container_internal { +namespace hash_internal { +namespace { + +class RandomDeviceSeedSeq { + public: + using result_type = typename std::random_device::result_type; + + template + void generate(Iterator start, Iterator end) { + while (start != end) { + *start = gen_(); + ++start; + } + } + + private: + std::random_device gen_; +}; + +} // namespace + +std::mt19937_64* GetThreadLocalRng() { + RandomDeviceSeedSeq seed_seq; + thread_local auto* rng = new std::mt19937_64(seed_seq); + return rng; +} + +std::string Generator::operator()() const { + // NOLINTNEXTLINE(runtime/int) + std::uniform_int_distribution chars(0x20, 0x7E); + std::string res; + res.resize(32); + std::generate(res.begin(), res.end(), + [&]() { return chars(*GetThreadLocalRng()); }); + return res; +} + +absl::string_view Generator::operator()() const { + static auto* arena = new std::deque(); + // NOLINTNEXTLINE(runtime/int) + std::uniform_int_distribution chars(0x20, 0x7E); + arena->emplace_back(); + auto& res = arena->back(); + res.resize(32); + std::generate(res.begin(), res.end(), + [&]() { return chars(*GetThreadLocalRng()); }); + return res; +} + +} // namespace hash_internal +} // namespace container_internal +} // namespace absl diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/internal/hash_generator_testing.h b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/internal/hash_generator_testing.h new file mode 100644 index 0000000..50d7710 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/internal/hash_generator_testing.h @@ -0,0 +1,150 @@ +// Copyright 2018 The Abseil Authors. +// +// 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. +// +// Generates random values for testing. Specialized only for the few types we +// care about. + +#ifndef ABSL_CONTAINER_INTERNAL_HASH_GENERATOR_TESTING_H_ +#define ABSL_CONTAINER_INTERNAL_HASH_GENERATOR_TESTING_H_ + +#include +#include +#include +#include +#include +#include +#include + +#include "absl/container/internal/hash_policy_testing.h" +#include "absl/meta/type_traits.h" +#include "absl/strings/string_view.h" + +namespace absl { +namespace container_internal { +namespace hash_internal { +namespace generator_internal { + +template +struct IsMap : std::false_type {}; + +template +struct IsMap> : std::true_type {}; + +} // namespace generator_internal + +std::mt19937_64* GetThreadLocalRng(); + +enum Enum { + kEnumEmpty, + kEnumDeleted, +}; + +enum class EnumClass : uint64_t { + kEmpty, + kDeleted, +}; + +inline std::ostream& operator<<(std::ostream& o, const EnumClass& ec) { + return o << static_cast(ec); +} + +template +struct Generator; + +template +struct Generator::value>::type> { + T operator()() const { + std::uniform_int_distribution dist; + return dist(*GetThreadLocalRng()); + } +}; + +template <> +struct Generator { + Enum operator()() const { + std::uniform_int_distribution::type> + dist; + while (true) { + auto variate = dist(*GetThreadLocalRng()); + if (variate != kEnumEmpty && variate != kEnumDeleted) + return static_cast(variate); + } + } +}; + +template <> +struct Generator { + EnumClass operator()() const { + std::uniform_int_distribution< + typename std::underlying_type::type> + dist; + while (true) { + EnumClass variate = static_cast(dist(*GetThreadLocalRng())); + if (variate != EnumClass::kEmpty && variate != EnumClass::kDeleted) + return static_cast(variate); + } + } +}; + +template <> +struct Generator { + std::string operator()() const; +}; + +template <> +struct Generator { + absl::string_view operator()() const; +}; + +template <> +struct Generator { + NonStandardLayout operator()() const { + return NonStandardLayout(Generator()()); + } +}; + +template +struct Generator> { + std::pair operator()() const { + return std::pair(Generator::type>()(), + Generator::type>()()); + } +}; + +template +struct Generator> { + std::tuple operator()() const { + return std::tuple(Generator::type>()()...); + } +}; + +template +struct Generator().key()), + decltype(std::declval().value())>> + : Generator().key())>::type, + typename std::decay().value())>::type>> {}; + +template +using GeneratedType = decltype( + std::declval::value, + typename Container::value_type, + typename Container::key_type>::type>&>()()); + +} // namespace hash_internal +} // namespace container_internal +} // namespace absl + +#endif // ABSL_CONTAINER_INTERNAL_HASH_GENERATOR_TESTING_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/internal/hash_policy_testing.h b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/internal/hash_policy_testing.h new file mode 100644 index 0000000..38bbec7 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/internal/hash_policy_testing.h @@ -0,0 +1,178 @@ +// Copyright 2018 The Abseil Authors. +// +// 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. +// +// Utilities to help tests verify that hash tables properly handle stateful +// allocators and hash functions. + +#ifndef ABSL_CONTAINER_INTERNAL_HASH_POLICY_TESTING_H_ +#define ABSL_CONTAINER_INTERNAL_HASH_POLICY_TESTING_H_ + +#include +#include +#include +#include +#include +#include +#include + +#include "absl/hash/hash.h" +#include "absl/strings/string_view.h" + +namespace absl { +namespace container_internal { +namespace hash_testing_internal { + +template +struct WithId { + WithId() : id_(next_id()) {} + WithId(const WithId& that) : id_(that.id_) {} + WithId(WithId&& that) : id_(that.id_) { that.id_ = 0; } + WithId& operator=(const WithId& that) { + id_ = that.id_; + return *this; + } + WithId& operator=(WithId&& that) { + id_ = that.id_; + that.id_ = 0; + return *this; + } + + size_t id() const { return id_; } + + friend bool operator==(const WithId& a, const WithId& b) { + return a.id_ == b.id_; + } + friend bool operator!=(const WithId& a, const WithId& b) { return !(a == b); } + + protected: + explicit WithId(size_t id) : id_(id) {} + + private: + size_t id_; + + template + static size_t next_id() { + // 0 is reserved for moved from state. + static size_t gId = 1; + return gId++; + } +}; + +} // namespace hash_testing_internal + +struct NonStandardLayout { + NonStandardLayout() {} + explicit NonStandardLayout(std::string s) : value(std::move(s)) {} + virtual ~NonStandardLayout() {} + + friend bool operator==(const NonStandardLayout& a, + const NonStandardLayout& b) { + return a.value == b.value; + } + friend bool operator!=(const NonStandardLayout& a, + const NonStandardLayout& b) { + return a.value != b.value; + } + + template + friend H AbslHashValue(H h, const NonStandardLayout& v) { + return H::combine(std::move(h), v.value); + } + + std::string value; +}; + +struct StatefulTestingHash + : absl::container_internal::hash_testing_internal::WithId< + StatefulTestingHash> { + template + size_t operator()(const T& t) const { + return absl::Hash{}(t); + } +}; + +struct StatefulTestingEqual + : absl::container_internal::hash_testing_internal::WithId< + StatefulTestingEqual> { + template + bool operator()(const T& t, const U& u) const { + return t == u; + } +}; + +// It is expected that Alloc() == Alloc() for all allocators so we cannot use +// WithId base. We need to explicitly assign ids. +template +struct Alloc : std::allocator { + using propagate_on_container_swap = std::true_type; + + // Using old paradigm for this to ensure compatibility. + explicit Alloc(size_t id = 0) : id_(id) {} + + Alloc(const Alloc&) = default; + Alloc& operator=(const Alloc&) = default; + + template + Alloc(const Alloc& that) : std::allocator(that), id_(that.id()) {} + + template + struct rebind { + using other = Alloc; + }; + + size_t id() const { return id_; } + + friend bool operator==(const Alloc& a, const Alloc& b) { + return a.id_ == b.id_; + } + friend bool operator!=(const Alloc& a, const Alloc& b) { return !(a == b); } + + private: + size_t id_ = (std::numeric_limits::max)(); +}; + +template +auto items(const Map& m) -> std::vector< + std::pair> { + using std::get; + std::vector> res; + res.reserve(m.size()); + for (const auto& v : m) res.emplace_back(get<0>(v), get<1>(v)); + return res; +} + +template +auto keys(const Set& s) + -> std::vector::type> { + std::vector::type> res; + res.reserve(s.size()); + for (const auto& v : s) res.emplace_back(v); + return res; +} + +} // namespace container_internal +} // namespace absl + +// ABSL_UNORDERED_SUPPORTS_ALLOC_CTORS is false for glibcxx versions +// where the unordered containers are missing certain constructors that +// take allocator arguments. This test is defined ad-hoc for the platforms +// we care about (notably Crosstool 17) because libstdcxx's useless +// versioning scheme precludes a more principled solution. +#if defined(__GLIBCXX__) && __GLIBCXX__ <= 20140425 +#define ABSL_UNORDERED_SUPPORTS_ALLOC_CTORS 0 +#else +#define ABSL_UNORDERED_SUPPORTS_ALLOC_CTORS 1 +#endif + +#endif // ABSL_CONTAINER_INTERNAL_HASH_POLICY_TESTING_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/internal/hash_policy_testing_test.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/internal/hash_policy_testing_test.cc new file mode 100644 index 0000000..c215c42 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/internal/hash_policy_testing_test.cc @@ -0,0 +1,43 @@ +// Copyright 2018 The Abseil Authors. +// +// 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 "absl/container/internal/hash_policy_testing.h" + +#include "gtest/gtest.h" + +namespace absl { +namespace container_internal { +namespace { + +TEST(_, Hash) { + StatefulTestingHash h1; + EXPECT_EQ(1, h1.id()); + StatefulTestingHash h2; + EXPECT_EQ(2, h2.id()); + StatefulTestingHash h1c(h1); + EXPECT_EQ(1, h1c.id()); + StatefulTestingHash h2m(std::move(h2)); + EXPECT_EQ(2, h2m.id()); + EXPECT_EQ(0, h2.id()); + StatefulTestingHash h3; + EXPECT_EQ(3, h3.id()); + h3 = StatefulTestingHash(); + EXPECT_EQ(4, h3.id()); + h3 = std::move(h1); + EXPECT_EQ(1, h3.id()); +} + +} // namespace +} // namespace container_internal +} // namespace absl diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/internal/hash_policy_traits.h b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/internal/hash_policy_traits.h new file mode 100644 index 0000000..ace50a6 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/internal/hash_policy_traits.h @@ -0,0 +1,189 @@ +// Copyright 2018 The Abseil Authors. +// +// 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. + +#ifndef ABSL_CONTAINER_INTERNAL_HASH_POLICY_TRAITS_H_ +#define ABSL_CONTAINER_INTERNAL_HASH_POLICY_TRAITS_H_ + +#include +#include +#include +#include + +#include "absl/meta/type_traits.h" + +namespace absl { +namespace container_internal { + +// Defines how slots are initialized/destroyed/moved. +template +struct hash_policy_traits { + private: + struct ReturnKey { + // We return `Key` here. + // When Key=T&, we forward the lvalue reference. + // When Key=T, we return by value to avoid a dangling reference. + // eg, for string_hash_map. + template + Key operator()(Key&& k, const Args&...) const { + return std::forward(k); + } + }; + + template + struct ConstantIteratorsImpl : std::false_type {}; + + template + struct ConstantIteratorsImpl> + : P::constant_iterators {}; + + public: + // The actual object stored in the hash table. + using slot_type = typename Policy::slot_type; + + // The type of the keys stored in the hashtable. + using key_type = typename Policy::key_type; + + // The argument type for insertions into the hashtable. This is different + // from value_type for increased performance. See initializer_list constructor + // and insert() member functions for more details. + using init_type = typename Policy::init_type; + + using reference = decltype(Policy::element(std::declval())); + using pointer = typename std::remove_reference::type*; + using value_type = typename std::remove_reference::type; + + // Policies can set this variable to tell raw_hash_set that all iterators + // should be constant, even `iterator`. This is useful for set-like + // containers. + // Defaults to false if not provided by the policy. + using constant_iterators = ConstantIteratorsImpl<>; + + // PRECONDITION: `slot` is UNINITIALIZED + // POSTCONDITION: `slot` is INITIALIZED + template + static void construct(Alloc* alloc, slot_type* slot, Args&&... args) { + Policy::construct(alloc, slot, std::forward(args)...); + } + + // PRECONDITION: `slot` is INITIALIZED + // POSTCONDITION: `slot` is UNINITIALIZED + template + static void destroy(Alloc* alloc, slot_type* slot) { + Policy::destroy(alloc, slot); + } + + // Transfers the `old_slot` to `new_slot`. Any memory allocated by the + // allocator inside `old_slot` to `new_slot` can be transferred. + // + // OPTIONAL: defaults to: + // + // clone(new_slot, std::move(*old_slot)); + // destroy(old_slot); + // + // PRECONDITION: `new_slot` is UNINITIALIZED and `old_slot` is INITIALIZED + // POSTCONDITION: `new_slot` is INITIALIZED and `old_slot` is + // UNINITIALIZED + template + static void transfer(Alloc* alloc, slot_type* new_slot, slot_type* old_slot) { + transfer_impl(alloc, new_slot, old_slot, 0); + } + + // PRECONDITION: `slot` is INITIALIZED + // POSTCONDITION: `slot` is INITIALIZED + template + static auto element(slot_type* slot) -> decltype(P::element(slot)) { + return P::element(slot); + } + + // Returns the amount of memory owned by `slot`, exclusive of `sizeof(*slot)`. + // + // If `slot` is nullptr, returns the constant amount of memory owned by any + // full slot or -1 if slots own variable amounts of memory. + // + // PRECONDITION: `slot` is INITIALIZED or nullptr + template + static size_t space_used(const slot_type* slot) { + return P::space_used(slot); + } + + // Provides generalized access to the key for elements, both for elements in + // the table and for elements that have not yet been inserted (or even + // constructed). We would like an API that allows us to say: `key(args...)` + // but we cannot do that for all cases, so we use this more general API that + // can be used for many things, including the following: + // + // - Given an element in a table, get its key. + // - Given an element initializer, get its key. + // - Given `emplace()` arguments, get the element key. + // + // Implementations of this must adhere to a very strict technical + // specification around aliasing and consuming arguments: + // + // Let `value_type` be the result type of `element()` without ref- and + // cv-qualifiers. The first argument is a functor, the rest are constructor + // arguments for `value_type`. Returns `std::forward(f)(k, xs...)`, where + // `k` is the element key, and `xs...` are the new constructor arguments for + // `value_type`. It's allowed for `k` to alias `xs...`, and for both to alias + // `ts...`. The key won't be touched once `xs...` are used to construct an + // element; `ts...` won't be touched at all, which allows `apply()` to consume + // any rvalues among them. + // + // If `value_type` is constructible from `Ts&&...`, `Policy::apply()` must not + // trigger a hard compile error unless it originates from `f`. In other words, + // `Policy::apply()` must be SFINAE-friendly. If `value_type` is not + // constructible from `Ts&&...`, either SFINAE or a hard compile error is OK. + // + // If `Ts...` is `[cv] value_type[&]` or `[cv] init_type[&]`, + // `Policy::apply()` must work. A compile error is not allowed, SFINAE or not. + template + static auto apply(F&& f, Ts&&... ts) + -> decltype(P::apply(std::forward(f), std::forward(ts)...)) { + return P::apply(std::forward(f), std::forward(ts)...); + } + + // Returns the "key" portion of the slot. + // Used for node handle manipulation. + template + static auto key(slot_type* slot) + -> decltype(P::apply(ReturnKey(), element(slot))) { + return P::apply(ReturnKey(), element(slot)); + } + + // Returns the "value" (as opposed to the "key") portion of the element. Used + // by maps to implement `operator[]`, `at()` and `insert_or_assign()`. + template + static auto value(T* elem) -> decltype(P::value(elem)) { + return P::value(elem); + } + + private: + // Use auto -> decltype as an enabler. + template + static auto transfer_impl(Alloc* alloc, slot_type* new_slot, + slot_type* old_slot, int) + -> decltype((void)P::transfer(alloc, new_slot, old_slot)) { + P::transfer(alloc, new_slot, old_slot); + } + template + static void transfer_impl(Alloc* alloc, slot_type* new_slot, + slot_type* old_slot, char) { + construct(alloc, new_slot, std::move(element(old_slot))); + destroy(alloc, old_slot); + } +}; + +} // namespace container_internal +} // namespace absl + +#endif // ABSL_CONTAINER_INTERNAL_HASH_POLICY_TRAITS_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/internal/hash_policy_traits_test.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/internal/hash_policy_traits_test.cc new file mode 100644 index 0000000..423f154 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/internal/hash_policy_traits_test.cc @@ -0,0 +1,142 @@ +// Copyright 2018 The Abseil Authors. +// +// 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 "absl/container/internal/hash_policy_traits.h" + +#include +#include +#include + +#include "gmock/gmock.h" +#include "gtest/gtest.h" + +namespace absl { +namespace container_internal { +namespace { + +using ::testing::MockFunction; +using ::testing::Return; +using ::testing::ReturnRef; + +using Alloc = std::allocator; +using Slot = int; + +struct PolicyWithoutOptionalOps { + using slot_type = Slot; + using key_type = Slot; + using init_type = Slot; + + static std::function construct; + static std::function destroy; + + static std::function element; + static int apply(int v) { return apply_impl(v); } + static std::function apply_impl; + static std::function value; +}; + +std::function PolicyWithoutOptionalOps::construct; +std::function PolicyWithoutOptionalOps::destroy; + +std::function PolicyWithoutOptionalOps::element; +std::function PolicyWithoutOptionalOps::apply_impl; +std::function PolicyWithoutOptionalOps::value; + +struct PolicyWithOptionalOps : PolicyWithoutOptionalOps { + static std::function transfer; +}; + +std::function PolicyWithOptionalOps::transfer; + +struct Test : ::testing::Test { + Test() { + PolicyWithoutOptionalOps::construct = [&](void* a1, Slot* a2, Slot a3) { + construct.Call(a1, a2, std::move(a3)); + }; + PolicyWithoutOptionalOps::destroy = [&](void* a1, Slot* a2) { + destroy.Call(a1, a2); + }; + + PolicyWithoutOptionalOps::element = [&](Slot* a1) -> Slot& { + return element.Call(a1); + }; + PolicyWithoutOptionalOps::apply_impl = [&](int a1) -> int { + return apply.Call(a1); + }; + PolicyWithoutOptionalOps::value = [&](Slot* a1) -> Slot& { + return value.Call(a1); + }; + + PolicyWithOptionalOps::transfer = [&](void* a1, Slot* a2, Slot* a3) { + return transfer.Call(a1, a2, a3); + }; + } + + std::allocator alloc; + int a = 53; + + MockFunction construct; + MockFunction destroy; + + MockFunction element; + MockFunction apply; + MockFunction value; + + MockFunction transfer; +}; + +TEST_F(Test, construct) { + EXPECT_CALL(construct, Call(&alloc, &a, 53)); + hash_policy_traits::construct(&alloc, &a, 53); +} + +TEST_F(Test, destroy) { + EXPECT_CALL(destroy, Call(&alloc, &a)); + hash_policy_traits::destroy(&alloc, &a); +} + +TEST_F(Test, element) { + int b = 0; + EXPECT_CALL(element, Call(&a)).WillOnce(ReturnRef(b)); + EXPECT_EQ(&b, &hash_policy_traits::element(&a)); +} + +TEST_F(Test, apply) { + EXPECT_CALL(apply, Call(42)).WillOnce(Return(1337)); + EXPECT_EQ(1337, (hash_policy_traits::apply(42))); +} + +TEST_F(Test, value) { + int b = 0; + EXPECT_CALL(value, Call(&a)).WillOnce(ReturnRef(b)); + EXPECT_EQ(&b, &hash_policy_traits::value(&a)); +} + +TEST_F(Test, without_transfer) { + int b = 42; + EXPECT_CALL(element, Call(&b)).WillOnce(::testing::ReturnRef(b)); + EXPECT_CALL(construct, Call(&alloc, &a, b)); + EXPECT_CALL(destroy, Call(&alloc, &b)); + hash_policy_traits::transfer(&alloc, &a, &b); +} + +TEST_F(Test, with_transfer) { + int b = 42; + EXPECT_CALL(transfer, Call(&alloc, &a, &b)); + hash_policy_traits::transfer(&alloc, &a, &b); +} + +} // namespace +} // namespace container_internal +} // namespace absl diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/internal/hashtable_debug.h b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/internal/hashtable_debug.h new file mode 100644 index 0000000..c3bd65c --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/internal/hashtable_debug.h @@ -0,0 +1,108 @@ +// Copyright 2018 The Abseil Authors. +// +// 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. +// +// This library provides APIs to debug the probing behavior of hash tables. +// +// In general, the probing behavior is a black box for users and only the +// side effects can be measured in the form of performance differences. +// These APIs give a glimpse on the actual behavior of the probing algorithms in +// these hashtables given a specified hash function and a set of elements. +// +// The probe count distribution can be used to assess the quality of the hash +// function for that particular hash table. Note that a hash function that +// performs well in one hash table implementation does not necessarily performs +// well in a different one. +// +// This library supports std::unordered_{set,map}, dense_hash_{set,map} and +// absl::{flat,node,string}_hash_{set,map}. + +#ifndef ABSL_CONTAINER_INTERNAL_HASHTABLE_DEBUG_H_ +#define ABSL_CONTAINER_INTERNAL_HASHTABLE_DEBUG_H_ + +#include +#include +#include +#include + +#include "absl/container/internal/hashtable_debug_hooks.h" + +namespace absl { +namespace container_internal { + +// Returns the number of probes required to lookup `key`. Returns 0 for a +// search with no collisions. Higher values mean more hash collisions occurred; +// however, the exact meaning of this number varies according to the container +// type. +template +size_t GetHashtableDebugNumProbes( + const C& c, const typename C::key_type& key) { + return absl::container_internal::hashtable_debug_internal:: + HashtableDebugAccess::GetNumProbes(c, key); +} + +// Gets a histogram of the number of probes for each elements in the container. +// The sum of all the values in the vector is equal to container.size(). +template +std::vector GetHashtableDebugNumProbesHistogram(const C& container) { + std::vector v; + for (auto it = container.begin(); it != container.end(); ++it) { + size_t num_probes = GetHashtableDebugNumProbes( + container, + absl::container_internal::hashtable_debug_internal::GetKey(*it, 0)); + v.resize(std::max(v.size(), num_probes + 1)); + v[num_probes]++; + } + return v; +} + +struct HashtableDebugProbeSummary { + size_t total_elements; + size_t total_num_probes; + double mean; +}; + +// Gets a summary of the probe count distribution for the elements in the +// container. +template +HashtableDebugProbeSummary GetHashtableDebugProbeSummary(const C& container) { + auto probes = GetHashtableDebugNumProbesHistogram(container); + HashtableDebugProbeSummary summary = {}; + for (size_t i = 0; i < probes.size(); ++i) { + summary.total_elements += probes[i]; + summary.total_num_probes += probes[i] * i; + } + summary.mean = 1.0 * summary.total_num_probes / summary.total_elements; + return summary; +} + +// Returns the number of bytes requested from the allocator by the container +// and not freed. +template +size_t AllocatedByteSize(const C& c) { + return absl::container_internal::hashtable_debug_internal:: + HashtableDebugAccess::AllocatedByteSize(c); +} + +// Returns a tight lower bound for AllocatedByteSize(c) where `c` is of type `C` +// and `c.size()` is equal to `num_elements`. +template +size_t LowerBoundAllocatedByteSize(size_t num_elements) { + return absl::container_internal::hashtable_debug_internal:: + HashtableDebugAccess::LowerBoundAllocatedByteSize(num_elements); +} + +} // namespace container_internal +} // namespace absl + +#endif // ABSL_CONTAINER_INTERNAL_HASHTABLE_DEBUG_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/internal/hashtable_debug_hooks.h b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/internal/hashtable_debug_hooks.h new file mode 100644 index 0000000..8f21972 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/internal/hashtable_debug_hooks.h @@ -0,0 +1,81 @@ +// Copyright 2018 The Abseil Authors. +// +// 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. +// +// Provides the internal API for hashtable_debug.h. + +#ifndef ABSL_CONTAINER_INTERNAL_HASHTABLE_DEBUG_HOOKS_H_ +#define ABSL_CONTAINER_INTERNAL_HASHTABLE_DEBUG_HOOKS_H_ + +#include + +#include +#include +#include + +namespace absl { +namespace container_internal { +namespace hashtable_debug_internal { + +// If it is a map, call get<0>(). +using std::get; +template +auto GetKey(const typename T::value_type& pair, int) -> decltype(get<0>(pair)) { + return get<0>(pair); +} + +// If it is not a map, return the value directly. +template +const typename T::key_type& GetKey(const typename T::key_type& key, char) { + return key; +} + +// Containers should specialize this to provide debug information for that +// container. +template +struct HashtableDebugAccess { + // Returns the number of probes required to find `key` in `c`. The "number of + // probes" is a concept that can vary by container. Implementations should + // return 0 when `key` was found in the minimum number of operations and + // should increment the result for each non-trivial operation required to find + // `key`. + // + // The default implementation uses the bucket api from the standard and thus + // works for `std::unordered_*` containers. + static size_t GetNumProbes(const Container& c, + const typename Container::key_type& key) { + if (!c.bucket_count()) return {}; + size_t num_probes = 0; + size_t bucket = c.bucket(key); + for (auto it = c.begin(bucket), e = c.end(bucket);; ++it, ++num_probes) { + if (it == e) return num_probes; + if (c.key_eq()(key, GetKey(*it, 0))) return num_probes; + } + } + + // Returns the number of bytes requested from the allocator by the container + // and not freed. + // + // static size_t AllocatedByteSize(const Container& c); + + // Returns a tight lower bound for AllocatedByteSize(c) where `c` is of type + // `Container` and `c.size()` is equal to `num_elements`. + // + // static size_t LowerBoundAllocatedByteSize(size_t num_elements); +}; + +} // namespace hashtable_debug_internal +} // namespace container_internal +} // namespace absl + +#endif // ABSL_CONTAINER_INTERNAL_HASHTABLE_DEBUG_HOOKS_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/internal/layout.h b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/internal/layout.h new file mode 100644 index 0000000..676c7d6 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/internal/layout.h @@ -0,0 +1,732 @@ +// Copyright 2018 The Abseil Authors. +// +// 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. +// +// MOTIVATION AND TUTORIAL +// +// If you want to put in a single heap allocation N doubles followed by M ints, +// it's easy if N and M are known at compile time. +// +// struct S { +// double a[N]; +// int b[M]; +// }; +// +// S* p = new S; +// +// But what if N and M are known only in run time? Class template Layout to the +// rescue! It's a portable generalization of the technique known as struct hack. +// +// // This object will tell us everything we need to know about the memory +// // layout of double[N] followed by int[M]. It's structurally identical to +// // size_t[2] that stores N and M. It's very cheap to create. +// const Layout layout(N, M); +// +// // Allocate enough memory for both arrays. `AllocSize()` tells us how much +// // memory is needed. We are free to use any allocation function we want as +// // long as it returns aligned memory. +// std::unique_ptr p(new unsigned char[layout.AllocSize()]); +// +// // Obtain the pointer to the array of doubles. +// // Equivalent to `reinterpret_cast(p.get())`. +// // +// // We could have written layout.Pointer<0>(p) instead. If all the types are +// // unique you can use either form, but if some types are repeated you must +// // use the index form. +// double* a = layout.Pointer(p.get()); +// +// // Obtain the pointer to the array of ints. +// // Equivalent to `reinterpret_cast(p.get() + N * 8)`. +// int* b = layout.Pointer(p); +// +// If we are unable to specify sizes of all fields, we can pass as many sizes as +// we can to `Partial()`. In return, it'll allow us to access the fields whose +// locations and sizes can be computed from the provided information. +// `Partial()` comes in handy when the array sizes are embedded into the +// allocation. +// +// // size_t[1] containing N, size_t[1] containing M, double[N], int[M]. +// using L = Layout; +// +// unsigned char* Allocate(size_t n, size_t m) { +// const L layout(1, 1, n, m); +// unsigned char* p = new unsigned char[layout.AllocSize()]; +// *layout.Pointer<0>(p) = n; +// *layout.Pointer<1>(p) = m; +// return p; +// } +// +// void Use(unsigned char* p) { +// // First, extract N and M. +// // Specify that the first array has only one element. Using `prefix` we +// // can access the first two arrays but not more. +// constexpr auto prefix = L::Partial(1); +// size_t n = *prefix.Pointer<0>(p); +// size_t m = *prefix.Pointer<1>(p); +// +// // Now we can get pointers to the payload. +// const L layout(1, 1, n, m); +// double* a = layout.Pointer(p); +// int* b = layout.Pointer(p); +// } +// +// The layout we used above combines fixed-size with dynamically-sized fields. +// This is quite common. Layout is optimized for this use case and generates +// optimal code. All computations that can be performed at compile time are +// indeed performed at compile time. +// +// Efficiency tip: The order of fields matters. In `Layout` try to +// ensure that `alignof(T1) >= ... >= alignof(TN)`. This way you'll have no +// padding in between arrays. +// +// You can manually override the alignment of an array by wrapping the type in +// `Aligned`. `Layout<..., Aligned, ...>` has exactly the same API +// and behavior as `Layout<..., T, ...>` except that the first element of the +// array of `T` is aligned to `N` (the rest of the elements follow without +// padding). `N` cannot be less than `alignof(T)`. +// +// `AllocSize()` and `Pointer()` are the most basic methods for dealing with +// memory layouts. Check out the reference or code below to discover more. +// +// EXAMPLE +// +// // Immutable move-only string with sizeof equal to sizeof(void*). The +// // string size and the characters are kept in the same heap allocation. +// class CompactString { +// public: +// CompactString(const char* s = "") { +// const size_t size = strlen(s); +// // size_t[1] followed by char[size + 1]. +// const L layout(1, size + 1); +// p_.reset(new unsigned char[layout.AllocSize()]); +// // If running under ASAN, mark the padding bytes, if any, to catch +// // memory errors. +// layout.PoisonPadding(p_.get()); +// // Store the size in the allocation. +// *layout.Pointer(p_.get()) = size; +// // Store the characters in the allocation. +// memcpy(layout.Pointer(p_.get()), s, size + 1); +// } +// +// size_t size() const { +// // Equivalent to reinterpret_cast(*p). +// return *L::Partial().Pointer(p_.get()); +// } +// +// const char* c_str() const { +// // Equivalent to reinterpret_cast(p.get() + sizeof(size_t)). +// // The argument in Partial(1) specifies that we have size_t[1] in front +// // of the characters. +// return L::Partial(1).Pointer(p_.get()); +// } +// +// private: +// // Our heap allocation contains a size_t followed by an array of chars. +// using L = Layout; +// std::unique_ptr p_; +// }; +// +// int main() { +// CompactString s = "hello"; +// assert(s.size() == 5); +// assert(strcmp(s.c_str(), "hello") == 0); +// } +// +// DOCUMENTATION +// +// The interface exported by this file consists of: +// - class `Layout<>` and its public members. +// - The public members of class `internal_layout::LayoutImpl<>`. That class +// isn't intended to be used directly, and its name and template parameter +// list are internal implementation details, but the class itself provides +// most of the functionality in this file. See comments on its members for +// detailed documentation. +// +// `Layout::Partial(count1,..., countm)` (where `m` <= `n`) returns a +// `LayoutImpl<>` object. `Layout layout(count1,..., countn)` +// creates a `Layout` object, which exposes the same functionality by inheriting +// from `LayoutImpl<>`. + +#ifndef ABSL_CONTAINER_INTERNAL_LAYOUT_H_ +#define ABSL_CONTAINER_INTERNAL_LAYOUT_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef ADDRESS_SANITIZER +#include +#endif + +#include "absl/meta/type_traits.h" +#include "absl/strings/str_cat.h" +#include "absl/types/span.h" +#include "absl/utility/utility.h" + +#if defined(__GXX_RTTI) +#define ABSL_INTERNAL_HAS_CXA_DEMANGLE +#endif + +#ifdef ABSL_INTERNAL_HAS_CXA_DEMANGLE +#include +#endif + +namespace absl { +namespace container_internal { + +// A type wrapper that instructs `Layout` to use the specific alignment for the +// array. `Layout<..., Aligned, ...>` has exactly the same API +// and behavior as `Layout<..., T, ...>` except that the first element of the +// array of `T` is aligned to `N` (the rest of the elements follow without +// padding). +// +// Requires: `N >= alignof(T)` and `N` is a power of 2. +template +struct Aligned; + +namespace internal_layout { + +template +struct NotAligned {}; + +template +struct NotAligned> { + static_assert(sizeof(T) == 0, "Aligned cannot be const-qualified"); +}; + +template +using IntToSize = size_t; + +template +using TypeToSize = size_t; + +template +struct Type : NotAligned { + using type = T; +}; + +template +struct Type> { + using type = T; +}; + +template +struct SizeOf : NotAligned, std::integral_constant {}; + +template +struct SizeOf> : std::integral_constant {}; + +template +struct AlignOf : NotAligned, std::integral_constant {}; + +template +struct AlignOf> : std::integral_constant { + static_assert(N % alignof(T) == 0, + "Custom alignment can't be lower than the type's alignment"); +}; + +// Does `Ts...` contain `T`? +template +using Contains = absl::disjunction...>; + +template +using CopyConst = + typename std::conditional::value, const To, To>::type; + +template +using SliceType = absl::Span; + +// This namespace contains no types. It prevents functions defined in it from +// being found by ADL. +namespace adl_barrier { + +template +constexpr size_t Find(Needle, Needle, Ts...) { + static_assert(!Contains(), "Duplicate element type"); + return 0; +} + +template +constexpr size_t Find(Needle, T, Ts...) { + return adl_barrier::Find(Needle(), Ts()...) + 1; +} + +constexpr bool IsPow2(size_t n) { return !(n & (n - 1)); } + +// Returns `q * m` for the smallest `q` such that `q * m >= n`. +// Requires: `m` is a power of two. It's enforced by IsLegalElementType below. +constexpr size_t Align(size_t n, size_t m) { return (n + m - 1) & ~(m - 1); } + +constexpr size_t Min(size_t a, size_t b) { return b < a ? b : a; } + +constexpr size_t Max(size_t a) { return a; } + +template +constexpr size_t Max(size_t a, size_t b, Ts... rest) { + return adl_barrier::Max(b < a ? a : b, rest...); +} + +template +std::string TypeName() { + std::string out; + int status = 0; + char* demangled = nullptr; +#ifdef ABSL_INTERNAL_HAS_CXA_DEMANGLE + demangled = abi::__cxa_demangle(typeid(T).name(), nullptr, nullptr, &status); +#endif + if (status == 0 && demangled != nullptr) { // Demangling succeeeded. + absl::StrAppend(&out, "<", demangled, ">"); + free(demangled); + } else { +#if defined(__GXX_RTTI) || defined(_CPPRTTI) + absl::StrAppend(&out, "<", typeid(T).name(), ">"); +#endif + } + return out; +} + +} // namespace adl_barrier + +template +using EnableIf = typename std::enable_if::type; + +// Can `T` be a template argument of `Layout`? +template +using IsLegalElementType = std::integral_constant< + bool, !std::is_reference::value && !std::is_volatile::value && + !std::is_reference::type>::value && + !std::is_volatile::type>::value && + adl_barrier::IsPow2(AlignOf::value)>; + +template +class LayoutImpl; + +// Public base class of `Layout` and the result type of `Layout::Partial()`. +// +// `Elements...` contains all template arguments of `Layout` that created this +// instance. +// +// `SizeSeq...` is `[0, NumSizes)` where `NumSizes` is the number of arguments +// passed to `Layout::Partial()` or `Layout::Layout()`. +// +// `OffsetSeq...` is `[0, NumOffsets)` where `NumOffsets` is +// `Min(sizeof...(Elements), NumSizes + 1)` (the number of arrays for which we +// can compute offsets). +template +class LayoutImpl, absl::index_sequence, + absl::index_sequence> { + private: + static_assert(sizeof...(Elements) > 0, "At least one field is required"); + static_assert(absl::conjunction...>::value, + "Invalid element type (see IsLegalElementType)"); + + enum { + NumTypes = sizeof...(Elements), + NumSizes = sizeof...(SizeSeq), + NumOffsets = sizeof...(OffsetSeq), + }; + + // These are guaranteed by `Layout`. + static_assert(NumOffsets == adl_barrier::Min(NumTypes, NumSizes + 1), + "Internal error"); + static_assert(NumTypes > 0, "Internal error"); + + // Returns the index of `T` in `Elements...`. Results in a compilation error + // if `Elements...` doesn't contain exactly one instance of `T`. + template + static constexpr size_t ElementIndex() { + static_assert(Contains, Type::type>...>(), + "Type not found"); + return adl_barrier::Find(Type(), + Type::type>()...); + } + + template + using ElementAlignment = + AlignOf>::type>; + + public: + // Element types of all arrays packed in a tuple. + using ElementTypes = std::tuple::type...>; + + // Element type of the Nth array. + template + using ElementType = typename std::tuple_element::type; + + constexpr explicit LayoutImpl(IntToSize... sizes) + : size_{sizes...} {} + + // Alignment of the layout, equal to the strictest alignment of all elements. + // All pointers passed to the methods of layout must be aligned to this value. + static constexpr size_t Alignment() { + return adl_barrier::Max(AlignOf::value...); + } + + // Offset in bytes of the Nth array. + // + // // int[3], 4 bytes of padding, double[4]. + // Layout x(3, 4); + // assert(x.Offset<0>() == 0); // The ints starts from 0. + // assert(x.Offset<1>() == 16); // The doubles starts from 16. + // + // Requires: `N <= NumSizes && N < sizeof...(Ts)`. + template = 0> + constexpr size_t Offset() const { + return 0; + } + + template = 0> + constexpr size_t Offset() const { + static_assert(N < NumOffsets, "Index out of bounds"); + return adl_barrier::Align( + Offset() + SizeOf>() * size_[N - 1], + ElementAlignment()); + } + + // Offset in bytes of the array with the specified element type. There must + // be exactly one such array and its zero-based index must be at most + // `NumSizes`. + // + // // int[3], 4 bytes of padding, double[4]. + // Layout x(3, 4); + // assert(x.Offset() == 0); // The ints starts from 0. + // assert(x.Offset() == 16); // The doubles starts from 16. + template + constexpr size_t Offset() const { + return Offset()>(); + } + + // Offsets in bytes of all arrays for which the offsets are known. + constexpr std::array Offsets() const { + return {{Offset()...}}; + } + + // The number of elements in the Nth array. This is the Nth argument of + // `Layout::Partial()` or `Layout::Layout()` (zero-based). + // + // // int[3], 4 bytes of padding, double[4]. + // Layout x(3, 4); + // assert(x.Size<0>() == 3); + // assert(x.Size<1>() == 4); + // + // Requires: `N < NumSizes`. + template + constexpr size_t Size() const { + static_assert(N < NumSizes, "Index out of bounds"); + return size_[N]; + } + + // The number of elements in the array with the specified element type. + // There must be exactly one such array and its zero-based index must be + // at most `NumSizes`. + // + // // int[3], 4 bytes of padding, double[4]. + // Layout x(3, 4); + // assert(x.Size() == 3); + // assert(x.Size() == 4); + template + constexpr size_t Size() const { + return Size()>(); + } + + // The number of elements of all arrays for which they are known. + constexpr std::array Sizes() const { + return {{Size()...}}; + } + + // Pointer to the beginning of the Nth array. + // + // `Char` must be `[const] [signed|unsigned] char`. + // + // // int[3], 4 bytes of padding, double[4]. + // Layout x(3, 4); + // unsigned char* p = new unsigned char[x.AllocSize()]; + // int* ints = x.Pointer<0>(p); + // double* doubles = x.Pointer<1>(p); + // + // Requires: `N <= NumSizes && N < sizeof...(Ts)`. + // Requires: `p` is aligned to `Alignment()`. + template + CopyConst>* Pointer(Char* p) const { + using C = typename std::remove_const::type; + static_assert( + std::is_same() || std::is_same() || + std::is_same(), + "The argument must be a pointer to [const] [signed|unsigned] char"); + constexpr size_t alignment = Alignment(); + (void)alignment; + assert(reinterpret_cast(p) % alignment == 0); + return reinterpret_cast>*>(p + Offset()); + } + + // Pointer to the beginning of the array with the specified element type. + // There must be exactly one such array and its zero-based index must be at + // most `NumSizes`. + // + // `Char` must be `[const] [signed|unsigned] char`. + // + // // int[3], 4 bytes of padding, double[4]. + // Layout x(3, 4); + // unsigned char* p = new unsigned char[x.AllocSize()]; + // int* ints = x.Pointer(p); + // double* doubles = x.Pointer(p); + // + // Requires: `p` is aligned to `Alignment()`. + template + CopyConst* Pointer(Char* p) const { + return Pointer()>(p); + } + + // Pointers to all arrays for which pointers are known. + // + // `Char` must be `[const] [signed|unsigned] char`. + // + // // int[3], 4 bytes of padding, double[4]. + // Layout x(3, 4); + // unsigned char* p = new unsigned char[x.AllocSize()]; + // + // int* ints; + // double* doubles; + // std::tie(ints, doubles) = x.Pointers(p); + // + // Requires: `p` is aligned to `Alignment()`. + // + // Note: We're not using ElementType alias here because it does not compile + // under MSVC. + template + std::tuple::type>*...> + Pointers(Char* p) const { + return std::tuple>*...>( + Pointer(p)...); + } + + // The Nth array. + // + // `Char` must be `[const] [signed|unsigned] char`. + // + // // int[3], 4 bytes of padding, double[4]. + // Layout x(3, 4); + // unsigned char* p = new unsigned char[x.AllocSize()]; + // Span ints = x.Slice<0>(p); + // Span doubles = x.Slice<1>(p); + // + // Requires: `N < NumSizes`. + // Requires: `p` is aligned to `Alignment()`. + template + SliceType>> Slice(Char* p) const { + return SliceType>>(Pointer(p), Size()); + } + + // The array with the specified element type. There must be exactly one + // such array and its zero-based index must be less than `NumSizes`. + // + // `Char` must be `[const] [signed|unsigned] char`. + // + // // int[3], 4 bytes of padding, double[4]. + // Layout x(3, 4); + // unsigned char* p = new unsigned char[x.AllocSize()]; + // Span ints = x.Slice(p); + // Span doubles = x.Slice(p); + // + // Requires: `p` is aligned to `Alignment()`. + template + SliceType> Slice(Char* p) const { + return Slice()>(p); + } + + // All arrays with known sizes. + // + // `Char` must be `[const] [signed|unsigned] char`. + // + // // int[3], 4 bytes of padding, double[4]. + // Layout x(3, 4); + // unsigned char* p = new unsigned char[x.AllocSize()]; + // + // Span ints; + // Span doubles; + // std::tie(ints, doubles) = x.Slices(p); + // + // Requires: `p` is aligned to `Alignment()`. + // + // Note: We're not using ElementType alias here because it does not compile + // under MSVC. + template + std::tuple::type>>...> + Slices(Char* p) const { + // Workaround for https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63875 (fixed + // in 6.1). + (void)p; + return std::tuple>>...>( + Slice(p)...); + } + + // The size of the allocation that fits all arrays. + // + // // int[3], 4 bytes of padding, double[4]. + // Layout x(3, 4); + // unsigned char* p = new unsigned char[x.AllocSize()]; // 48 bytes + // + // Requires: `NumSizes == sizeof...(Ts)`. + constexpr size_t AllocSize() const { + static_assert(NumTypes == NumSizes, "You must specify sizes of all fields"); + return Offset() + + SizeOf>() * size_[NumTypes - 1]; + } + + // If built with --config=asan, poisons padding bytes (if any) in the + // allocation. The pointer must point to a memory block at least + // `AllocSize()` bytes in length. + // + // `Char` must be `[const] [signed|unsigned] char`. + // + // Requires: `p` is aligned to `Alignment()`. + template = 0> + void PoisonPadding(const Char* p) const { + Pointer<0>(p); // verify the requirements on `Char` and `p` + } + + template = 0> + void PoisonPadding(const Char* p) const { + static_assert(N < NumOffsets, "Index out of bounds"); + (void)p; +#ifdef ADDRESS_SANITIZER + PoisonPadding(p); + // The `if` is an optimization. It doesn't affect the observable behaviour. + if (ElementAlignment() % ElementAlignment()) { + size_t start = + Offset() + SizeOf>() * size_[N - 1]; + ASAN_POISON_MEMORY_REGION(p + start, Offset() - start); + } +#endif + } + + // Human-readable description of the memory layout. Useful for debugging. + // Slow. + // + // // char[5], 3 bytes of padding, int[3], 4 bytes of padding, followed + // // by an unknown number of doubles. + // auto x = Layout::Partial(5, 3); + // assert(x.DebugString() == + // "@0(1)[5]; @8(4)[3]; @24(8)"); + // + // Each field is in the following format: @offset(sizeof)[size] ( + // may be missing depending on the target platform). For example, + // @8(4)[3] means that at offset 8 we have an array of ints, where each + // int is 4 bytes, and we have 3 of those ints. The size of the last field may + // be missing (as in the example above). Only fields with known offsets are + // described. Type names may differ across platforms: one compiler might + // produce "unsigned*" where another produces "unsigned int *". + std::string DebugString() const { + const auto offsets = Offsets(); + const size_t sizes[] = {SizeOf>()...}; + const std::string types[] = {adl_barrier::TypeName>()...}; + std::string res = absl::StrCat("@0", types[0], "(", sizes[0], ")"); + for (size_t i = 0; i != NumOffsets - 1; ++i) { + absl::StrAppend(&res, "[", size_[i], "]; @", offsets[i + 1], types[i + 1], + "(", sizes[i + 1], ")"); + } + // NumSizes is a constant that may be zero. Some compilers cannot see that + // inside the if statement "size_[NumSizes - 1]" must be valid. + int last = static_cast(NumSizes) - 1; + if (NumTypes == NumSizes && last >= 0) { + absl::StrAppend(&res, "[", size_[last], "]"); + } + return res; + } + + private: + // Arguments of `Layout::Partial()` or `Layout::Layout()`. + size_t size_[NumSizes > 0 ? NumSizes : 1]; +}; + +template +using LayoutType = LayoutImpl< + std::tuple, absl::make_index_sequence, + absl::make_index_sequence>; + +} // namespace internal_layout + +// Descriptor of arrays of various types and sizes laid out in memory one after +// another. See the top of the file for documentation. +// +// Check out the public API of internal_layout::LayoutImpl above. The type is +// internal to the library but its methods are public, and they are inherited +// by `Layout`. +template +class Layout : public internal_layout::LayoutType { + public: + static_assert(sizeof...(Ts) > 0, "At least one field is required"); + static_assert( + absl::conjunction...>::value, + "Invalid element type (see IsLegalElementType)"); + + // The result type of `Partial()` with `NumSizes` arguments. + template + using PartialType = internal_layout::LayoutType; + + // `Layout` knows the element types of the arrays we want to lay out in + // memory but not the number of elements in each array. + // `Partial(size1, ..., sizeN)` allows us to specify the latter. The + // resulting immutable object can be used to obtain pointers to the + // individual arrays. + // + // It's allowed to pass fewer array sizes than the number of arrays. E.g., + // if all you need is to the offset of the second array, you only need to + // pass one argument -- the number of elements in the first arrays. + // + // // int[3] followed by 4 bytes of padding and an unknown number of + // // doubles. + // auto x = Layout::Partial(3); + // // doubles start at byte 16. + // assert(x.Offset<1>() == 16); + // + // If you know the number of elements in all arrays, you can still call + // `Partial()` but it's more convenient to use the constructor of `Layout`. + // + // Layout x(3, 5); + // + // Note: The sizes of the arrays must be specified in number of elements, + // not in bytes. + // + // Requires: `sizeof...(Sizes) <= sizeof...(Ts)`. + // Requires: all arguments are convertible to `size_t`. + template + static constexpr PartialType Partial(Sizes&&... sizes) { + static_assert(sizeof...(Sizes) <= sizeof...(Ts), ""); + return PartialType(absl::forward(sizes)...); + } + + // Creates a layout with the sizes of all arrays specified. If you know + // only the sizes of the first N arrays (where N can be zero), you can use + // `Partial()` defined above. The constructor is essentially equivalent to + // calling `Partial()` and passing in all array sizes; the constructor is + // provided as a convenient abbreviation. + // + // Note: The sizes of the arrays must be specified in number of elements, + // not in bytes. + constexpr explicit Layout(internal_layout::TypeToSize... sizes) + : internal_layout::LayoutType(sizes...) {} +}; + +} // namespace container_internal +} // namespace absl + +#endif // ABSL_CONTAINER_INTERNAL_LAYOUT_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/internal/layout_test.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/internal/layout_test.cc new file mode 100644 index 0000000..f35157a --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/internal/layout_test.cc @@ -0,0 +1,1552 @@ +// Copyright 2018 The Abseil Authors. +// +// 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 "absl/container/internal/layout.h" + +// We need ::max_align_t because some libstdc++ versions don't provide +// std::max_align_t +#include +#include +#include +#include +#include + +#include "gmock/gmock.h" +#include "gtest/gtest.h" +#include "absl/base/internal/raw_logging.h" +#include "absl/types/span.h" + +namespace absl { +namespace container_internal { +namespace { + +using ::absl::Span; +using ::testing::ElementsAre; + +size_t Distance(const void* from, const void* to) { + ABSL_RAW_CHECK(from <= to, "Distance must be non-negative"); + return static_cast(to) - static_cast(from); +} + +template +Expected Type(Actual val) { + static_assert(std::is_same(), ""); + return val; +} + +using Int128 = int64_t[2]; + +// Properties of types that this test relies on. +static_assert(sizeof(int8_t) == 1, ""); +static_assert(alignof(int8_t) == 1, ""); +static_assert(sizeof(int16_t) == 2, ""); +static_assert(alignof(int16_t) == 2, ""); +static_assert(sizeof(int32_t) == 4, ""); +static_assert(alignof(int32_t) == 4, ""); +static_assert(sizeof(Int128) == 16, ""); +static_assert(alignof(Int128) == 8, ""); + +template +void SameType() { + static_assert(std::is_same(), ""); +} + +TEST(Layout, ElementType) { + { + using L = Layout; + SameType>(); + SameType>(); + SameType>(); + } + { + using L = Layout; + SameType>(); + SameType>(); + SameType>(); + SameType>(); + SameType>(); + SameType>(); + } + { + using L = Layout; + SameType>(); + SameType>(); + SameType>(); + SameType>(); + SameType>(); + SameType>(); + SameType>(); + SameType>(); + SameType>(); + SameType>(); + SameType>(); + SameType>(); + } +} + +TEST(Layout, ElementTypes) { + { + using L = Layout; + SameType, L::ElementTypes>(); + SameType, decltype(L::Partial())::ElementTypes>(); + SameType, decltype(L::Partial(0))::ElementTypes>(); + } + { + using L = Layout; + SameType, L::ElementTypes>(); + SameType, decltype(L::Partial())::ElementTypes>(); + SameType, decltype(L::Partial(0))::ElementTypes>(); + } + { + using L = Layout; + SameType, L::ElementTypes>(); + SameType, + decltype(L::Partial())::ElementTypes>(); + SameType, + decltype(L::Partial(0))::ElementTypes>(); + SameType, + decltype(L::Partial(0, 0))::ElementTypes>(); + SameType, + decltype(L::Partial(0, 0, 0))::ElementTypes>(); + } +} + +TEST(Layout, OffsetByIndex) { + { + using L = Layout; + EXPECT_EQ(0, L::Partial().Offset<0>()); + EXPECT_EQ(0, L::Partial(3).Offset<0>()); + EXPECT_EQ(0, L(3).Offset<0>()); + } + { + using L = Layout; + EXPECT_EQ(0, L::Partial().Offset<0>()); + EXPECT_EQ(0, L::Partial(3).Offset<0>()); + EXPECT_EQ(12, L::Partial(3).Offset<1>()); + EXPECT_EQ(0, L::Partial(3, 5).Offset<0>()); + EXPECT_EQ(12, L::Partial(3, 5).Offset<1>()); + EXPECT_EQ(0, L(3, 5).Offset<0>()); + EXPECT_EQ(12, L(3, 5).Offset<1>()); + } + { + using L = Layout; + EXPECT_EQ(0, L::Partial().Offset<0>()); + EXPECT_EQ(0, L::Partial(0).Offset<0>()); + EXPECT_EQ(0, L::Partial(0).Offset<1>()); + EXPECT_EQ(0, L::Partial(1).Offset<0>()); + EXPECT_EQ(4, L::Partial(1).Offset<1>()); + EXPECT_EQ(0, L::Partial(5).Offset<0>()); + EXPECT_EQ(8, L::Partial(5).Offset<1>()); + EXPECT_EQ(0, L::Partial(0, 0).Offset<0>()); + EXPECT_EQ(0, L::Partial(0, 0).Offset<1>()); + EXPECT_EQ(0, L::Partial(0, 0).Offset<2>()); + EXPECT_EQ(0, L::Partial(1, 0).Offset<0>()); + EXPECT_EQ(4, L::Partial(1, 0).Offset<1>()); + EXPECT_EQ(8, L::Partial(1, 0).Offset<2>()); + EXPECT_EQ(0, L::Partial(5, 3).Offset<0>()); + EXPECT_EQ(8, L::Partial(5, 3).Offset<1>()); + EXPECT_EQ(24, L::Partial(5, 3).Offset<2>()); + EXPECT_EQ(0, L::Partial(0, 0, 0).Offset<0>()); + EXPECT_EQ(0, L::Partial(0, 0, 0).Offset<1>()); + EXPECT_EQ(0, L::Partial(0, 0, 0).Offset<2>()); + EXPECT_EQ(0, L::Partial(1, 0, 0).Offset<0>()); + EXPECT_EQ(4, L::Partial(1, 0, 0).Offset<1>()); + EXPECT_EQ(8, L::Partial(1, 0, 0).Offset<2>()); + EXPECT_EQ(0, L::Partial(5, 3, 1).Offset<0>()); + EXPECT_EQ(24, L::Partial(5, 3, 1).Offset<2>()); + EXPECT_EQ(8, L::Partial(5, 3, 1).Offset<1>()); + EXPECT_EQ(0, L(5, 3, 1).Offset<0>()); + EXPECT_EQ(24, L(5, 3, 1).Offset<2>()); + EXPECT_EQ(8, L(5, 3, 1).Offset<1>()); + } +} + +TEST(Layout, OffsetByType) { + { + using L = Layout; + EXPECT_EQ(0, L::Partial().Offset()); + EXPECT_EQ(0, L::Partial(3).Offset()); + EXPECT_EQ(0, L(3).Offset()); + } + { + using L = Layout; + EXPECT_EQ(0, L::Partial().Offset()); + EXPECT_EQ(0, L::Partial(0).Offset()); + EXPECT_EQ(0, L::Partial(0).Offset()); + EXPECT_EQ(0, L::Partial(1).Offset()); + EXPECT_EQ(4, L::Partial(1).Offset()); + EXPECT_EQ(0, L::Partial(5).Offset()); + EXPECT_EQ(8, L::Partial(5).Offset()); + EXPECT_EQ(0, L::Partial(0, 0).Offset()); + EXPECT_EQ(0, L::Partial(0, 0).Offset()); + EXPECT_EQ(0, L::Partial(0, 0).Offset()); + EXPECT_EQ(0, L::Partial(1, 0).Offset()); + EXPECT_EQ(4, L::Partial(1, 0).Offset()); + EXPECT_EQ(8, L::Partial(1, 0).Offset()); + EXPECT_EQ(0, L::Partial(5, 3).Offset()); + EXPECT_EQ(8, L::Partial(5, 3).Offset()); + EXPECT_EQ(24, L::Partial(5, 3).Offset()); + EXPECT_EQ(0, L::Partial(0, 0, 0).Offset()); + EXPECT_EQ(0, L::Partial(0, 0, 0).Offset()); + EXPECT_EQ(0, L::Partial(0, 0, 0).Offset()); + EXPECT_EQ(0, L::Partial(1, 0, 0).Offset()); + EXPECT_EQ(4, L::Partial(1, 0, 0).Offset()); + EXPECT_EQ(8, L::Partial(1, 0, 0).Offset()); + EXPECT_EQ(0, L::Partial(5, 3, 1).Offset()); + EXPECT_EQ(24, L::Partial(5, 3, 1).Offset()); + EXPECT_EQ(8, L::Partial(5, 3, 1).Offset()); + EXPECT_EQ(0, L(5, 3, 1).Offset()); + EXPECT_EQ(24, L(5, 3, 1).Offset()); + EXPECT_EQ(8, L(5, 3, 1).Offset()); + } +} + +TEST(Layout, Offsets) { + { + using L = Layout; + EXPECT_THAT(L::Partial().Offsets(), ElementsAre(0)); + EXPECT_THAT(L::Partial(3).Offsets(), ElementsAre(0)); + EXPECT_THAT(L(3).Offsets(), ElementsAre(0)); + } + { + using L = Layout; + EXPECT_THAT(L::Partial().Offsets(), ElementsAre(0)); + EXPECT_THAT(L::Partial(3).Offsets(), ElementsAre(0, 12)); + EXPECT_THAT(L::Partial(3, 5).Offsets(), ElementsAre(0, 12)); + EXPECT_THAT(L(3, 5).Offsets(), ElementsAre(0, 12)); + } + { + using L = Layout; + EXPECT_THAT(L::Partial().Offsets(), ElementsAre(0)); + EXPECT_THAT(L::Partial(1).Offsets(), ElementsAre(0, 4)); + EXPECT_THAT(L::Partial(5).Offsets(), ElementsAre(0, 8)); + EXPECT_THAT(L::Partial(0, 0).Offsets(), ElementsAre(0, 0, 0)); + EXPECT_THAT(L::Partial(1, 0).Offsets(), ElementsAre(0, 4, 8)); + EXPECT_THAT(L::Partial(5, 3).Offsets(), ElementsAre(0, 8, 24)); + EXPECT_THAT(L::Partial(0, 0, 0).Offsets(), ElementsAre(0, 0, 0)); + EXPECT_THAT(L::Partial(1, 0, 0).Offsets(), ElementsAre(0, 4, 8)); + EXPECT_THAT(L::Partial(5, 3, 1).Offsets(), ElementsAre(0, 8, 24)); + EXPECT_THAT(L(5, 3, 1).Offsets(), ElementsAre(0, 8, 24)); + } +} + +TEST(Layout, AllocSize) { + { + using L = Layout; + EXPECT_EQ(0, L::Partial(0).AllocSize()); + EXPECT_EQ(12, L::Partial(3).AllocSize()); + EXPECT_EQ(12, L(3).AllocSize()); + } + { + using L = Layout; + EXPECT_EQ(32, L::Partial(3, 5).AllocSize()); + EXPECT_EQ(32, L(3, 5).AllocSize()); + } + { + using L = Layout; + EXPECT_EQ(0, L::Partial(0, 0, 0).AllocSize()); + EXPECT_EQ(8, L::Partial(1, 0, 0).AllocSize()); + EXPECT_EQ(8, L::Partial(0, 1, 0).AllocSize()); + EXPECT_EQ(16, L::Partial(0, 0, 1).AllocSize()); + EXPECT_EQ(24, L::Partial(1, 1, 1).AllocSize()); + EXPECT_EQ(136, L::Partial(3, 5, 7).AllocSize()); + EXPECT_EQ(136, L(3, 5, 7).AllocSize()); + } +} + +TEST(Layout, SizeByIndex) { + { + using L = Layout; + EXPECT_EQ(0, L::Partial(0).Size<0>()); + EXPECT_EQ(3, L::Partial(3).Size<0>()); + EXPECT_EQ(3, L(3).Size<0>()); + } + { + using L = Layout; + EXPECT_EQ(0, L::Partial(0).Size<0>()); + EXPECT_EQ(3, L::Partial(3).Size<0>()); + EXPECT_EQ(3, L::Partial(3, 5).Size<0>()); + EXPECT_EQ(5, L::Partial(3, 5).Size<1>()); + EXPECT_EQ(3, L(3, 5).Size<0>()); + EXPECT_EQ(5, L(3, 5).Size<1>()); + } + { + using L = Layout; + EXPECT_EQ(3, L::Partial(3).Size<0>()); + EXPECT_EQ(3, L::Partial(3, 5).Size<0>()); + EXPECT_EQ(5, L::Partial(3, 5).Size<1>()); + EXPECT_EQ(3, L::Partial(3, 5, 7).Size<0>()); + EXPECT_EQ(5, L::Partial(3, 5, 7).Size<1>()); + EXPECT_EQ(7, L::Partial(3, 5, 7).Size<2>()); + EXPECT_EQ(3, L(3, 5, 7).Size<0>()); + EXPECT_EQ(5, L(3, 5, 7).Size<1>()); + EXPECT_EQ(7, L(3, 5, 7).Size<2>()); + } +} + +TEST(Layout, SizeByType) { + { + using L = Layout; + EXPECT_EQ(0, L::Partial(0).Size()); + EXPECT_EQ(3, L::Partial(3).Size()); + EXPECT_EQ(3, L(3).Size()); + } + { + using L = Layout; + EXPECT_EQ(3, L::Partial(3).Size()); + EXPECT_EQ(3, L::Partial(3, 5).Size()); + EXPECT_EQ(5, L::Partial(3, 5).Size()); + EXPECT_EQ(3, L::Partial(3, 5, 7).Size()); + EXPECT_EQ(5, L::Partial(3, 5, 7).Size()); + EXPECT_EQ(7, L::Partial(3, 5, 7).Size()); + EXPECT_EQ(3, L(3, 5, 7).Size()); + EXPECT_EQ(5, L(3, 5, 7).Size()); + EXPECT_EQ(7, L(3, 5, 7).Size()); + } +} + +TEST(Layout, Sizes) { + { + using L = Layout; + EXPECT_THAT(L::Partial().Sizes(), ElementsAre()); + EXPECT_THAT(L::Partial(3).Sizes(), ElementsAre(3)); + EXPECT_THAT(L(3).Sizes(), ElementsAre(3)); + } + { + using L = Layout; + EXPECT_THAT(L::Partial().Sizes(), ElementsAre()); + EXPECT_THAT(L::Partial(3).Sizes(), ElementsAre(3)); + EXPECT_THAT(L::Partial(3, 5).Sizes(), ElementsAre(3, 5)); + EXPECT_THAT(L(3, 5).Sizes(), ElementsAre(3, 5)); + } + { + using L = Layout; + EXPECT_THAT(L::Partial().Sizes(), ElementsAre()); + EXPECT_THAT(L::Partial(3).Sizes(), ElementsAre(3)); + EXPECT_THAT(L::Partial(3, 5).Sizes(), ElementsAre(3, 5)); + EXPECT_THAT(L::Partial(3, 5, 7).Sizes(), ElementsAre(3, 5, 7)); + EXPECT_THAT(L(3, 5, 7).Sizes(), ElementsAre(3, 5, 7)); + } +} + +TEST(Layout, PointerByIndex) { + alignas(max_align_t) const unsigned char p[100] = {}; + { + using L = Layout; + EXPECT_EQ(0, Distance(p, Type(L::Partial().Pointer<0>(p)))); + EXPECT_EQ(0, Distance(p, Type(L::Partial(3).Pointer<0>(p)))); + EXPECT_EQ(0, Distance(p, Type(L(3).Pointer<0>(p)))); + } + { + using L = Layout; + EXPECT_EQ(0, Distance(p, Type(L::Partial().Pointer<0>(p)))); + EXPECT_EQ(0, Distance(p, Type(L::Partial(3).Pointer<0>(p)))); + EXPECT_EQ(12, Distance(p, Type(L::Partial(3).Pointer<1>(p)))); + EXPECT_EQ(0, + Distance(p, Type(L::Partial(3, 5).Pointer<0>(p)))); + EXPECT_EQ(12, + Distance(p, Type(L::Partial(3, 5).Pointer<1>(p)))); + EXPECT_EQ(0, Distance(p, Type(L(3, 5).Pointer<0>(p)))); + EXPECT_EQ(12, Distance(p, Type(L(3, 5).Pointer<1>(p)))); + } + { + using L = Layout; + EXPECT_EQ(0, Distance(p, Type(L::Partial().Pointer<0>(p)))); + EXPECT_EQ(0, Distance(p, Type(L::Partial(0).Pointer<0>(p)))); + EXPECT_EQ(0, Distance(p, Type(L::Partial(0).Pointer<1>(p)))); + EXPECT_EQ(0, Distance(p, Type(L::Partial(1).Pointer<0>(p)))); + EXPECT_EQ(4, Distance(p, Type(L::Partial(1).Pointer<1>(p)))); + EXPECT_EQ(0, Distance(p, Type(L::Partial(5).Pointer<0>(p)))); + EXPECT_EQ(8, Distance(p, Type(L::Partial(5).Pointer<1>(p)))); + EXPECT_EQ(0, + Distance(p, Type(L::Partial(0, 0).Pointer<0>(p)))); + EXPECT_EQ(0, + Distance(p, Type(L::Partial(0, 0).Pointer<1>(p)))); + EXPECT_EQ(0, + Distance(p, Type(L::Partial(0, 0).Pointer<2>(p)))); + EXPECT_EQ(0, + Distance(p, Type(L::Partial(1, 0).Pointer<0>(p)))); + EXPECT_EQ(4, + Distance(p, Type(L::Partial(1, 0).Pointer<1>(p)))); + EXPECT_EQ(8, + Distance(p, Type(L::Partial(1, 0).Pointer<2>(p)))); + EXPECT_EQ(0, + Distance(p, Type(L::Partial(5, 3).Pointer<0>(p)))); + EXPECT_EQ(8, + Distance(p, Type(L::Partial(5, 3).Pointer<1>(p)))); + EXPECT_EQ(24, + Distance(p, Type(L::Partial(5, 3).Pointer<2>(p)))); + EXPECT_EQ( + 0, Distance(p, Type(L::Partial(0, 0, 0).Pointer<0>(p)))); + EXPECT_EQ( + 0, Distance(p, Type(L::Partial(0, 0, 0).Pointer<1>(p)))); + EXPECT_EQ( + 0, Distance(p, Type(L::Partial(0, 0, 0).Pointer<2>(p)))); + EXPECT_EQ( + 0, Distance(p, Type(L::Partial(1, 0, 0).Pointer<0>(p)))); + EXPECT_EQ( + 4, Distance(p, Type(L::Partial(1, 0, 0).Pointer<1>(p)))); + EXPECT_EQ( + 8, Distance(p, Type(L::Partial(1, 0, 0).Pointer<2>(p)))); + EXPECT_EQ( + 0, Distance(p, Type(L::Partial(5, 3, 1).Pointer<0>(p)))); + EXPECT_EQ( + 24, + Distance(p, Type(L::Partial(5, 3, 1).Pointer<2>(p)))); + EXPECT_EQ( + 8, Distance(p, Type(L::Partial(5, 3, 1).Pointer<1>(p)))); + EXPECT_EQ(0, Distance(p, Type(L(5, 3, 1).Pointer<0>(p)))); + EXPECT_EQ(24, Distance(p, Type(L(5, 3, 1).Pointer<2>(p)))); + EXPECT_EQ(8, Distance(p, Type(L(5, 3, 1).Pointer<1>(p)))); + } +} + +TEST(Layout, PointerByType) { + alignas(max_align_t) const unsigned char p[100] = {}; + { + using L = Layout; + EXPECT_EQ(0, + Distance(p, Type(L::Partial().Pointer(p)))); + EXPECT_EQ(0, + Distance(p, Type(L::Partial(3).Pointer(p)))); + EXPECT_EQ(0, Distance(p, Type(L(3).Pointer(p)))); + } + { + using L = Layout; + EXPECT_EQ(0, Distance(p, Type(L::Partial().Pointer(p)))); + EXPECT_EQ(0, + Distance(p, Type(L::Partial(0).Pointer(p)))); + EXPECT_EQ(0, + Distance(p, Type(L::Partial(0).Pointer(p)))); + EXPECT_EQ(0, + Distance(p, Type(L::Partial(1).Pointer(p)))); + EXPECT_EQ(4, + Distance(p, Type(L::Partial(1).Pointer(p)))); + EXPECT_EQ(0, + Distance(p, Type(L::Partial(5).Pointer(p)))); + EXPECT_EQ(8, + Distance(p, Type(L::Partial(5).Pointer(p)))); + EXPECT_EQ( + 0, Distance(p, Type(L::Partial(0, 0).Pointer(p)))); + EXPECT_EQ( + 0, Distance(p, Type(L::Partial(0, 0).Pointer(p)))); + EXPECT_EQ( + 0, + Distance(p, Type(L::Partial(0, 0).Pointer(p)))); + EXPECT_EQ( + 0, Distance(p, Type(L::Partial(1, 0).Pointer(p)))); + EXPECT_EQ( + 4, Distance(p, Type(L::Partial(1, 0).Pointer(p)))); + EXPECT_EQ( + 8, + Distance(p, Type(L::Partial(1, 0).Pointer(p)))); + EXPECT_EQ( + 0, Distance(p, Type(L::Partial(5, 3).Pointer(p)))); + EXPECT_EQ( + 8, Distance(p, Type(L::Partial(5, 3).Pointer(p)))); + EXPECT_EQ( + 24, + Distance(p, Type(L::Partial(5, 3).Pointer(p)))); + EXPECT_EQ( + 0, + Distance(p, Type(L::Partial(0, 0, 0).Pointer(p)))); + EXPECT_EQ( + 0, + Distance(p, Type(L::Partial(0, 0, 0).Pointer(p)))); + EXPECT_EQ(0, Distance(p, Type( + L::Partial(0, 0, 0).Pointer(p)))); + EXPECT_EQ( + 0, + Distance(p, Type(L::Partial(1, 0, 0).Pointer(p)))); + EXPECT_EQ( + 4, + Distance(p, Type(L::Partial(1, 0, 0).Pointer(p)))); + EXPECT_EQ(8, Distance(p, Type( + L::Partial(1, 0, 0).Pointer(p)))); + EXPECT_EQ( + 0, + Distance(p, Type(L::Partial(5, 3, 1).Pointer(p)))); + EXPECT_EQ(24, Distance(p, Type( + L::Partial(5, 3, 1).Pointer(p)))); + EXPECT_EQ( + 8, + Distance(p, Type(L::Partial(5, 3, 1).Pointer(p)))); + EXPECT_EQ(24, + Distance(p, Type(L(5, 3, 1).Pointer(p)))); + EXPECT_EQ(8, Distance(p, Type(L(5, 3, 1).Pointer(p)))); + } +} + +TEST(Layout, MutablePointerByIndex) { + alignas(max_align_t) unsigned char p[100]; + { + using L = Layout; + EXPECT_EQ(0, Distance(p, Type(L::Partial().Pointer<0>(p)))); + EXPECT_EQ(0, Distance(p, Type(L::Partial(3).Pointer<0>(p)))); + EXPECT_EQ(0, Distance(p, Type(L(3).Pointer<0>(p)))); + } + { + using L = Layout; + EXPECT_EQ(0, Distance(p, Type(L::Partial().Pointer<0>(p)))); + EXPECT_EQ(0, Distance(p, Type(L::Partial(3).Pointer<0>(p)))); + EXPECT_EQ(12, Distance(p, Type(L::Partial(3).Pointer<1>(p)))); + EXPECT_EQ(0, Distance(p, Type(L::Partial(3, 5).Pointer<0>(p)))); + EXPECT_EQ(12, Distance(p, Type(L::Partial(3, 5).Pointer<1>(p)))); + EXPECT_EQ(0, Distance(p, Type(L(3, 5).Pointer<0>(p)))); + EXPECT_EQ(12, Distance(p, Type(L(3, 5).Pointer<1>(p)))); + } + { + using L = Layout; + EXPECT_EQ(0, Distance(p, Type(L::Partial().Pointer<0>(p)))); + EXPECT_EQ(0, Distance(p, Type(L::Partial(0).Pointer<0>(p)))); + EXPECT_EQ(0, Distance(p, Type(L::Partial(0).Pointer<1>(p)))); + EXPECT_EQ(0, Distance(p, Type(L::Partial(1).Pointer<0>(p)))); + EXPECT_EQ(4, Distance(p, Type(L::Partial(1).Pointer<1>(p)))); + EXPECT_EQ(0, Distance(p, Type(L::Partial(5).Pointer<0>(p)))); + EXPECT_EQ(8, Distance(p, Type(L::Partial(5).Pointer<1>(p)))); + EXPECT_EQ(0, Distance(p, Type(L::Partial(0, 0).Pointer<0>(p)))); + EXPECT_EQ(0, Distance(p, Type(L::Partial(0, 0).Pointer<1>(p)))); + EXPECT_EQ(0, Distance(p, Type(L::Partial(0, 0).Pointer<2>(p)))); + EXPECT_EQ(0, Distance(p, Type(L::Partial(1, 0).Pointer<0>(p)))); + EXPECT_EQ(4, Distance(p, Type(L::Partial(1, 0).Pointer<1>(p)))); + EXPECT_EQ(8, Distance(p, Type(L::Partial(1, 0).Pointer<2>(p)))); + EXPECT_EQ(0, Distance(p, Type(L::Partial(5, 3).Pointer<0>(p)))); + EXPECT_EQ(8, Distance(p, Type(L::Partial(5, 3).Pointer<1>(p)))); + EXPECT_EQ(24, Distance(p, Type(L::Partial(5, 3).Pointer<2>(p)))); + EXPECT_EQ(0, Distance(p, Type(L::Partial(0, 0, 0).Pointer<0>(p)))); + EXPECT_EQ(0, Distance(p, Type(L::Partial(0, 0, 0).Pointer<1>(p)))); + EXPECT_EQ(0, Distance(p, Type(L::Partial(0, 0, 0).Pointer<2>(p)))); + EXPECT_EQ(0, Distance(p, Type(L::Partial(1, 0, 0).Pointer<0>(p)))); + EXPECT_EQ(4, Distance(p, Type(L::Partial(1, 0, 0).Pointer<1>(p)))); + EXPECT_EQ(8, Distance(p, Type(L::Partial(1, 0, 0).Pointer<2>(p)))); + EXPECT_EQ(0, Distance(p, Type(L::Partial(5, 3, 1).Pointer<0>(p)))); + EXPECT_EQ(24, + Distance(p, Type(L::Partial(5, 3, 1).Pointer<2>(p)))); + EXPECT_EQ(8, Distance(p, Type(L::Partial(5, 3, 1).Pointer<1>(p)))); + EXPECT_EQ(0, Distance(p, Type(L(5, 3, 1).Pointer<0>(p)))); + EXPECT_EQ(24, Distance(p, Type(L(5, 3, 1).Pointer<2>(p)))); + EXPECT_EQ(8, Distance(p, Type(L(5, 3, 1).Pointer<1>(p)))); + } +} + +TEST(Layout, MutablePointerByType) { + alignas(max_align_t) unsigned char p[100]; + { + using L = Layout; + EXPECT_EQ(0, Distance(p, Type(L::Partial().Pointer(p)))); + EXPECT_EQ(0, Distance(p, Type(L::Partial(3).Pointer(p)))); + EXPECT_EQ(0, Distance(p, Type(L(3).Pointer(p)))); + } + { + using L = Layout; + EXPECT_EQ(0, Distance(p, Type(L::Partial().Pointer(p)))); + EXPECT_EQ(0, Distance(p, Type(L::Partial(0).Pointer(p)))); + EXPECT_EQ(0, Distance(p, Type(L::Partial(0).Pointer(p)))); + EXPECT_EQ(0, Distance(p, Type(L::Partial(1).Pointer(p)))); + EXPECT_EQ(4, Distance(p, Type(L::Partial(1).Pointer(p)))); + EXPECT_EQ(0, Distance(p, Type(L::Partial(5).Pointer(p)))); + EXPECT_EQ(8, Distance(p, Type(L::Partial(5).Pointer(p)))); + EXPECT_EQ(0, Distance(p, Type(L::Partial(0, 0).Pointer(p)))); + EXPECT_EQ(0, Distance(p, Type(L::Partial(0, 0).Pointer(p)))); + EXPECT_EQ(0, + Distance(p, Type(L::Partial(0, 0).Pointer(p)))); + EXPECT_EQ(0, Distance(p, Type(L::Partial(1, 0).Pointer(p)))); + EXPECT_EQ(4, Distance(p, Type(L::Partial(1, 0).Pointer(p)))); + EXPECT_EQ(8, + Distance(p, Type(L::Partial(1, 0).Pointer(p)))); + EXPECT_EQ(0, Distance(p, Type(L::Partial(5, 3).Pointer(p)))); + EXPECT_EQ(8, Distance(p, Type(L::Partial(5, 3).Pointer(p)))); + EXPECT_EQ(24, + Distance(p, Type(L::Partial(5, 3).Pointer(p)))); + EXPECT_EQ(0, + Distance(p, Type(L::Partial(0, 0, 0).Pointer(p)))); + EXPECT_EQ(0, + Distance(p, Type(L::Partial(0, 0, 0).Pointer(p)))); + EXPECT_EQ( + 0, Distance(p, Type(L::Partial(0, 0, 0).Pointer(p)))); + EXPECT_EQ(0, + Distance(p, Type(L::Partial(1, 0, 0).Pointer(p)))); + EXPECT_EQ(4, + Distance(p, Type(L::Partial(1, 0, 0).Pointer(p)))); + EXPECT_EQ( + 8, Distance(p, Type(L::Partial(1, 0, 0).Pointer(p)))); + EXPECT_EQ(0, + Distance(p, Type(L::Partial(5, 3, 1).Pointer(p)))); + EXPECT_EQ( + 24, Distance(p, Type(L::Partial(5, 3, 1).Pointer(p)))); + EXPECT_EQ(8, + Distance(p, Type(L::Partial(5, 3, 1).Pointer(p)))); + EXPECT_EQ(0, Distance(p, Type(L(5, 3, 1).Pointer(p)))); + EXPECT_EQ(24, Distance(p, Type(L(5, 3, 1).Pointer(p)))); + EXPECT_EQ(8, Distance(p, Type(L(5, 3, 1).Pointer(p)))); + } +} + +TEST(Layout, Pointers) { + alignas(max_align_t) const unsigned char p[100] = {}; + using L = Layout; + { + const auto x = L::Partial(); + EXPECT_EQ(std::make_tuple(x.Pointer<0>(p)), + Type>(x.Pointers(p))); + } + { + const auto x = L::Partial(1); + EXPECT_EQ(std::make_tuple(x.Pointer<0>(p), x.Pointer<1>(p)), + (Type>(x.Pointers(p)))); + } + { + const auto x = L::Partial(1, 2); + EXPECT_EQ( + std::make_tuple(x.Pointer<0>(p), x.Pointer<1>(p), x.Pointer<2>(p)), + (Type>( + x.Pointers(p)))); + } + { + const auto x = L::Partial(1, 2, 3); + EXPECT_EQ( + std::make_tuple(x.Pointer<0>(p), x.Pointer<1>(p), x.Pointer<2>(p)), + (Type>( + x.Pointers(p)))); + } + { + const L x(1, 2, 3); + EXPECT_EQ( + std::make_tuple(x.Pointer<0>(p), x.Pointer<1>(p), x.Pointer<2>(p)), + (Type>( + x.Pointers(p)))); + } +} + +TEST(Layout, MutablePointers) { + alignas(max_align_t) unsigned char p[100]; + using L = Layout; + { + const auto x = L::Partial(); + EXPECT_EQ(std::make_tuple(x.Pointer<0>(p)), + Type>(x.Pointers(p))); + } + { + const auto x = L::Partial(1); + EXPECT_EQ(std::make_tuple(x.Pointer<0>(p), x.Pointer<1>(p)), + (Type>(x.Pointers(p)))); + } + { + const auto x = L::Partial(1, 2); + EXPECT_EQ( + std::make_tuple(x.Pointer<0>(p), x.Pointer<1>(p), x.Pointer<2>(p)), + (Type>(x.Pointers(p)))); + } + { + const auto x = L::Partial(1, 2, 3); + EXPECT_EQ( + std::make_tuple(x.Pointer<0>(p), x.Pointer<1>(p), x.Pointer<2>(p)), + (Type>(x.Pointers(p)))); + } + { + const L x(1, 2, 3); + EXPECT_EQ( + std::make_tuple(x.Pointer<0>(p), x.Pointer<1>(p), x.Pointer<2>(p)), + (Type>(x.Pointers(p)))); + } +} + +TEST(Layout, SliceByIndexSize) { + alignas(max_align_t) const unsigned char p[100] = {}; + { + using L = Layout; + EXPECT_EQ(0, L::Partial(0).Slice<0>(p).size()); + EXPECT_EQ(3, L::Partial(3).Slice<0>(p).size()); + EXPECT_EQ(3, L(3).Slice<0>(p).size()); + } + { + using L = Layout; + EXPECT_EQ(3, L::Partial(3).Slice<0>(p).size()); + EXPECT_EQ(5, L::Partial(3, 5).Slice<1>(p).size()); + EXPECT_EQ(5, L(3, 5).Slice<1>(p).size()); + } + { + using L = Layout; + EXPECT_EQ(3, L::Partial(3).Slice<0>(p).size()); + EXPECT_EQ(3, L::Partial(3, 5).Slice<0>(p).size()); + EXPECT_EQ(5, L::Partial(3, 5).Slice<1>(p).size()); + EXPECT_EQ(3, L::Partial(3, 5, 7).Slice<0>(p).size()); + EXPECT_EQ(5, L::Partial(3, 5, 7).Slice<1>(p).size()); + EXPECT_EQ(7, L::Partial(3, 5, 7).Slice<2>(p).size()); + EXPECT_EQ(3, L(3, 5, 7).Slice<0>(p).size()); + EXPECT_EQ(5, L(3, 5, 7).Slice<1>(p).size()); + EXPECT_EQ(7, L(3, 5, 7).Slice<2>(p).size()); + } +} + +TEST(Layout, SliceByTypeSize) { + alignas(max_align_t) const unsigned char p[100] = {}; + { + using L = Layout; + EXPECT_EQ(0, L::Partial(0).Slice(p).size()); + EXPECT_EQ(3, L::Partial(3).Slice(p).size()); + EXPECT_EQ(3, L(3).Slice(p).size()); + } + { + using L = Layout; + EXPECT_EQ(3, L::Partial(3).Slice(p).size()); + EXPECT_EQ(3, L::Partial(3, 5).Slice(p).size()); + EXPECT_EQ(5, L::Partial(3, 5).Slice(p).size()); + EXPECT_EQ(3, L::Partial(3, 5, 7).Slice(p).size()); + EXPECT_EQ(5, L::Partial(3, 5, 7).Slice(p).size()); + EXPECT_EQ(7, L::Partial(3, 5, 7).Slice(p).size()); + EXPECT_EQ(3, L(3, 5, 7).Slice(p).size()); + EXPECT_EQ(5, L(3, 5, 7).Slice(p).size()); + EXPECT_EQ(7, L(3, 5, 7).Slice(p).size()); + } +} + +TEST(Layout, MutableSliceByIndexSize) { + alignas(max_align_t) unsigned char p[100]; + { + using L = Layout; + EXPECT_EQ(0, L::Partial(0).Slice<0>(p).size()); + EXPECT_EQ(3, L::Partial(3).Slice<0>(p).size()); + EXPECT_EQ(3, L(3).Slice<0>(p).size()); + } + { + using L = Layout; + EXPECT_EQ(3, L::Partial(3).Slice<0>(p).size()); + EXPECT_EQ(5, L::Partial(3, 5).Slice<1>(p).size()); + EXPECT_EQ(5, L(3, 5).Slice<1>(p).size()); + } + { + using L = Layout; + EXPECT_EQ(3, L::Partial(3).Slice<0>(p).size()); + EXPECT_EQ(3, L::Partial(3, 5).Slice<0>(p).size()); + EXPECT_EQ(5, L::Partial(3, 5).Slice<1>(p).size()); + EXPECT_EQ(3, L::Partial(3, 5, 7).Slice<0>(p).size()); + EXPECT_EQ(5, L::Partial(3, 5, 7).Slice<1>(p).size()); + EXPECT_EQ(7, L::Partial(3, 5, 7).Slice<2>(p).size()); + EXPECT_EQ(3, L(3, 5, 7).Slice<0>(p).size()); + EXPECT_EQ(5, L(3, 5, 7).Slice<1>(p).size()); + EXPECT_EQ(7, L(3, 5, 7).Slice<2>(p).size()); + } +} + +TEST(Layout, MutableSliceByTypeSize) { + alignas(max_align_t) unsigned char p[100]; + { + using L = Layout; + EXPECT_EQ(0, L::Partial(0).Slice(p).size()); + EXPECT_EQ(3, L::Partial(3).Slice(p).size()); + EXPECT_EQ(3, L(3).Slice(p).size()); + } + { + using L = Layout; + EXPECT_EQ(3, L::Partial(3).Slice(p).size()); + EXPECT_EQ(3, L::Partial(3, 5).Slice(p).size()); + EXPECT_EQ(5, L::Partial(3, 5).Slice(p).size()); + EXPECT_EQ(3, L::Partial(3, 5, 7).Slice(p).size()); + EXPECT_EQ(5, L::Partial(3, 5, 7).Slice(p).size()); + EXPECT_EQ(7, L::Partial(3, 5, 7).Slice(p).size()); + EXPECT_EQ(3, L(3, 5, 7).Slice(p).size()); + EXPECT_EQ(5, L(3, 5, 7).Slice(p).size()); + EXPECT_EQ(7, L(3, 5, 7).Slice(p).size()); + } +} + +TEST(Layout, SliceByIndexData) { + alignas(max_align_t) const unsigned char p[100] = {}; + { + using L = Layout; + EXPECT_EQ( + 0, + Distance(p, Type>(L::Partial(0).Slice<0>(p)).data())); + EXPECT_EQ( + 0, + Distance(p, Type>(L::Partial(3).Slice<0>(p)).data())); + EXPECT_EQ(0, Distance(p, Type>(L(3).Slice<0>(p)).data())); + } + { + using L = Layout; + EXPECT_EQ( + 0, + Distance(p, Type>(L::Partial(3).Slice<0>(p)).data())); + EXPECT_EQ( + 0, + Distance(p, + Type>(L::Partial(3, 5).Slice<0>(p)).data())); + EXPECT_EQ( + 12, + Distance(p, + Type>(L::Partial(3, 5).Slice<1>(p)).data())); + EXPECT_EQ(0, + Distance(p, Type>(L(3, 5).Slice<0>(p)).data())); + EXPECT_EQ(12, + Distance(p, Type>(L(3, 5).Slice<1>(p)).data())); + } + { + using L = Layout; + EXPECT_EQ( + 0, + Distance(p, Type>(L::Partial(0).Slice<0>(p)).data())); + EXPECT_EQ( + 0, + Distance(p, Type>(L::Partial(1).Slice<0>(p)).data())); + EXPECT_EQ( + 0, + Distance(p, Type>(L::Partial(5).Slice<0>(p)).data())); + EXPECT_EQ( + 0, Distance( + p, Type>(L::Partial(0, 0).Slice<0>(p)).data())); + EXPECT_EQ( + 0, + Distance(p, + Type>(L::Partial(0, 0).Slice<1>(p)).data())); + EXPECT_EQ( + 0, Distance( + p, Type>(L::Partial(1, 0).Slice<0>(p)).data())); + EXPECT_EQ( + 4, + Distance(p, + Type>(L::Partial(1, 0).Slice<1>(p)).data())); + EXPECT_EQ( + 0, Distance( + p, Type>(L::Partial(5, 3).Slice<0>(p)).data())); + EXPECT_EQ( + 8, + Distance(p, + Type>(L::Partial(5, 3).Slice<1>(p)).data())); + EXPECT_EQ( + 0, + Distance( + p, Type>(L::Partial(0, 0, 0).Slice<0>(p)).data())); + EXPECT_EQ( + 0, + Distance( + p, + Type>(L::Partial(0, 0, 0).Slice<1>(p)).data())); + EXPECT_EQ( + 0, + Distance( + p, + Type>(L::Partial(0, 0, 0).Slice<2>(p)).data())); + EXPECT_EQ( + 0, + Distance( + p, Type>(L::Partial(1, 0, 0).Slice<0>(p)).data())); + EXPECT_EQ( + 4, + Distance( + p, + Type>(L::Partial(1, 0, 0).Slice<1>(p)).data())); + EXPECT_EQ( + 8, + Distance( + p, + Type>(L::Partial(1, 0, 0).Slice<2>(p)).data())); + EXPECT_EQ( + 0, + Distance( + p, Type>(L::Partial(5, 3, 1).Slice<0>(p)).data())); + EXPECT_EQ( + 24, + Distance( + p, + Type>(L::Partial(5, 3, 1).Slice<2>(p)).data())); + EXPECT_EQ( + 8, + Distance( + p, + Type>(L::Partial(5, 3, 1).Slice<1>(p)).data())); + EXPECT_EQ( + 0, Distance(p, Type>(L(5, 3, 1).Slice<0>(p)).data())); + EXPECT_EQ( + 24, + Distance(p, Type>(L(5, 3, 1).Slice<2>(p)).data())); + EXPECT_EQ( + 8, Distance(p, Type>(L(5, 3, 1).Slice<1>(p)).data())); + } +} + +TEST(Layout, SliceByTypeData) { + alignas(max_align_t) const unsigned char p[100] = {}; + { + using L = Layout; + EXPECT_EQ( + 0, + Distance( + p, Type>(L::Partial(0).Slice(p)).data())); + EXPECT_EQ( + 0, + Distance( + p, Type>(L::Partial(3).Slice(p)).data())); + EXPECT_EQ( + 0, Distance(p, Type>(L(3).Slice(p)).data())); + } + { + using L = Layout; + EXPECT_EQ( + 0, Distance( + p, Type>(L::Partial(0).Slice(p)).data())); + EXPECT_EQ( + 0, Distance( + p, Type>(L::Partial(1).Slice(p)).data())); + EXPECT_EQ( + 0, Distance( + p, Type>(L::Partial(5).Slice(p)).data())); + EXPECT_EQ( + 0, + Distance( + p, Type>(L::Partial(0, 0).Slice(p)).data())); + EXPECT_EQ( + 0, + Distance( + p, + Type>(L::Partial(0, 0).Slice(p)).data())); + EXPECT_EQ( + 0, + Distance( + p, Type>(L::Partial(1, 0).Slice(p)).data())); + EXPECT_EQ( + 4, + Distance( + p, + Type>(L::Partial(1, 0).Slice(p)).data())); + EXPECT_EQ( + 0, + Distance( + p, Type>(L::Partial(5, 3).Slice(p)).data())); + EXPECT_EQ( + 8, + Distance( + p, + Type>(L::Partial(5, 3).Slice(p)).data())); + EXPECT_EQ( + 0, + Distance( + p, + Type>(L::Partial(0, 0, 0).Slice(p)).data())); + EXPECT_EQ( + 0, + Distance(p, Type>(L::Partial(0, 0, 0).Slice(p)) + .data())); + EXPECT_EQ(0, Distance(p, Type>( + L::Partial(0, 0, 0).Slice(p)) + .data())); + EXPECT_EQ( + 0, + Distance( + p, + Type>(L::Partial(1, 0, 0).Slice(p)).data())); + EXPECT_EQ( + 4, + Distance(p, Type>(L::Partial(1, 0, 0).Slice(p)) + .data())); + EXPECT_EQ(8, Distance(p, Type>( + L::Partial(1, 0, 0).Slice(p)) + .data())); + EXPECT_EQ( + 0, + Distance( + p, + Type>(L::Partial(5, 3, 1).Slice(p)).data())); + EXPECT_EQ(24, Distance(p, Type>( + L::Partial(5, 3, 1).Slice(p)) + .data())); + EXPECT_EQ( + 8, + Distance(p, Type>(L::Partial(5, 3, 1).Slice(p)) + .data())); + EXPECT_EQ( + 0, + Distance(p, Type>(L(5, 3, 1).Slice(p)).data())); + EXPECT_EQ( + 24, + Distance(p, + Type>(L(5, 3, 1).Slice(p)).data())); + EXPECT_EQ( + 8, Distance( + p, Type>(L(5, 3, 1).Slice(p)).data())); + } +} + +TEST(Layout, MutableSliceByIndexData) { + alignas(max_align_t) unsigned char p[100]; + { + using L = Layout; + EXPECT_EQ(0, + Distance(p, Type>(L::Partial(0).Slice<0>(p)).data())); + EXPECT_EQ(0, + Distance(p, Type>(L::Partial(3).Slice<0>(p)).data())); + EXPECT_EQ(0, Distance(p, Type>(L(3).Slice<0>(p)).data())); + } + { + using L = Layout; + EXPECT_EQ(0, + Distance(p, Type>(L::Partial(3).Slice<0>(p)).data())); + EXPECT_EQ( + 0, Distance(p, Type>(L::Partial(3, 5).Slice<0>(p)).data())); + EXPECT_EQ( + 12, + Distance(p, Type>(L::Partial(3, 5).Slice<1>(p)).data())); + EXPECT_EQ(0, Distance(p, Type>(L(3, 5).Slice<0>(p)).data())); + EXPECT_EQ(12, Distance(p, Type>(L(3, 5).Slice<1>(p)).data())); + } + { + using L = Layout; + EXPECT_EQ(0, + Distance(p, Type>(L::Partial(0).Slice<0>(p)).data())); + EXPECT_EQ(0, + Distance(p, Type>(L::Partial(1).Slice<0>(p)).data())); + EXPECT_EQ(0, + Distance(p, Type>(L::Partial(5).Slice<0>(p)).data())); + EXPECT_EQ( + 0, Distance(p, Type>(L::Partial(0, 0).Slice<0>(p)).data())); + EXPECT_EQ( + 0, Distance(p, Type>(L::Partial(0, 0).Slice<1>(p)).data())); + EXPECT_EQ( + 0, Distance(p, Type>(L::Partial(1, 0).Slice<0>(p)).data())); + EXPECT_EQ( + 4, Distance(p, Type>(L::Partial(1, 0).Slice<1>(p)).data())); + EXPECT_EQ( + 0, Distance(p, Type>(L::Partial(5, 3).Slice<0>(p)).data())); + EXPECT_EQ( + 8, Distance(p, Type>(L::Partial(5, 3).Slice<1>(p)).data())); + EXPECT_EQ( + 0, + Distance(p, Type>(L::Partial(0, 0, 0).Slice<0>(p)).data())); + EXPECT_EQ( + 0, + Distance(p, Type>(L::Partial(0, 0, 0).Slice<1>(p)).data())); + EXPECT_EQ( + 0, Distance( + p, Type>(L::Partial(0, 0, 0).Slice<2>(p)).data())); + EXPECT_EQ( + 0, + Distance(p, Type>(L::Partial(1, 0, 0).Slice<0>(p)).data())); + EXPECT_EQ( + 4, + Distance(p, Type>(L::Partial(1, 0, 0).Slice<1>(p)).data())); + EXPECT_EQ( + 8, Distance( + p, Type>(L::Partial(1, 0, 0).Slice<2>(p)).data())); + EXPECT_EQ( + 0, + Distance(p, Type>(L::Partial(5, 3, 1).Slice<0>(p)).data())); + EXPECT_EQ( + 24, Distance( + p, Type>(L::Partial(5, 3, 1).Slice<2>(p)).data())); + EXPECT_EQ( + 8, + Distance(p, Type>(L::Partial(5, 3, 1).Slice<1>(p)).data())); + EXPECT_EQ(0, Distance(p, Type>(L(5, 3, 1).Slice<0>(p)).data())); + EXPECT_EQ(24, + Distance(p, Type>(L(5, 3, 1).Slice<2>(p)).data())); + EXPECT_EQ(8, Distance(p, Type>(L(5, 3, 1).Slice<1>(p)).data())); + } +} + +TEST(Layout, MutableSliceByTypeData) { + alignas(max_align_t) unsigned char p[100]; + { + using L = Layout; + EXPECT_EQ( + 0, + Distance(p, Type>(L::Partial(0).Slice(p)).data())); + EXPECT_EQ( + 0, + Distance(p, Type>(L::Partial(3).Slice(p)).data())); + EXPECT_EQ(0, Distance(p, Type>(L(3).Slice(p)).data())); + } + { + using L = Layout; + EXPECT_EQ( + 0, Distance(p, Type>(L::Partial(0).Slice(p)).data())); + EXPECT_EQ( + 0, Distance(p, Type>(L::Partial(1).Slice(p)).data())); + EXPECT_EQ( + 0, Distance(p, Type>(L::Partial(5).Slice(p)).data())); + EXPECT_EQ( + 0, + Distance(p, Type>(L::Partial(0, 0).Slice(p)).data())); + EXPECT_EQ( + 0, Distance( + p, Type>(L::Partial(0, 0).Slice(p)).data())); + EXPECT_EQ( + 0, + Distance(p, Type>(L::Partial(1, 0).Slice(p)).data())); + EXPECT_EQ( + 4, Distance( + p, Type>(L::Partial(1, 0).Slice(p)).data())); + EXPECT_EQ( + 0, + Distance(p, Type>(L::Partial(5, 3).Slice(p)).data())); + EXPECT_EQ( + 8, Distance( + p, Type>(L::Partial(5, 3).Slice(p)).data())); + EXPECT_EQ( + 0, Distance( + p, Type>(L::Partial(0, 0, 0).Slice(p)).data())); + EXPECT_EQ( + 0, + Distance( + p, Type>(L::Partial(0, 0, 0).Slice(p)).data())); + EXPECT_EQ( + 0, + Distance( + p, + Type>(L::Partial(0, 0, 0).Slice(p)).data())); + EXPECT_EQ( + 0, Distance( + p, Type>(L::Partial(1, 0, 0).Slice(p)).data())); + EXPECT_EQ( + 4, + Distance( + p, Type>(L::Partial(1, 0, 0).Slice(p)).data())); + EXPECT_EQ( + 8, + Distance( + p, + Type>(L::Partial(1, 0, 0).Slice(p)).data())); + EXPECT_EQ( + 0, Distance( + p, Type>(L::Partial(5, 3, 1).Slice(p)).data())); + EXPECT_EQ( + 24, + Distance( + p, + Type>(L::Partial(5, 3, 1).Slice(p)).data())); + EXPECT_EQ( + 8, + Distance( + p, Type>(L::Partial(5, 3, 1).Slice(p)).data())); + EXPECT_EQ(0, + Distance(p, Type>(L(5, 3, 1).Slice(p)).data())); + EXPECT_EQ( + 24, + Distance(p, Type>(L(5, 3, 1).Slice(p)).data())); + EXPECT_EQ( + 8, Distance(p, Type>(L(5, 3, 1).Slice(p)).data())); + } +} + +MATCHER_P(IsSameSlice, slice, "") { + return arg.size() == slice.size() && arg.data() == slice.data(); +} + +template +class TupleMatcher { + public: + explicit TupleMatcher(M... matchers) : matchers_(std::move(matchers)...) {} + + template + bool MatchAndExplain(const Tuple& p, + testing::MatchResultListener* /* listener */) const { + static_assert(std::tuple_size::value == sizeof...(M), ""); + return MatchAndExplainImpl( + p, absl::make_index_sequence::value>{}); + } + + // For the matcher concept. Left empty as we don't really need the diagnostics + // right now. + void DescribeTo(::std::ostream* os) const {} + void DescribeNegationTo(::std::ostream* os) const {} + + private: + template + bool MatchAndExplainImpl(const Tuple& p, absl::index_sequence) const { + // Using std::min as a simple variadic "and". + return std::min( + {true, testing::SafeMatcherCast< + const typename std::tuple_element::type&>( + std::get(matchers_)) + .Matches(std::get(p))...}); + } + + std::tuple matchers_; +}; + +template +testing::PolymorphicMatcher> Tuple(M... matchers) { + return testing::MakePolymorphicMatcher( + TupleMatcher(std::move(matchers)...)); +} + +TEST(Layout, Slices) { + alignas(max_align_t) const unsigned char p[100] = {}; + using L = Layout; + { + const auto x = L::Partial(); + EXPECT_THAT(Type>(x.Slices(p)), Tuple()); + } + { + const auto x = L::Partial(1); + EXPECT_THAT(Type>>(x.Slices(p)), + Tuple(IsSameSlice(x.Slice<0>(p)))); + } + { + const auto x = L::Partial(1, 2); + EXPECT_THAT( + (Type, Span>>(x.Slices(p))), + Tuple(IsSameSlice(x.Slice<0>(p)), IsSameSlice(x.Slice<1>(p)))); + } + { + const auto x = L::Partial(1, 2, 3); + EXPECT_THAT((Type, Span, + Span>>(x.Slices(p))), + Tuple(IsSameSlice(x.Slice<0>(p)), IsSameSlice(x.Slice<1>(p)), + IsSameSlice(x.Slice<2>(p)))); + } + { + const L x(1, 2, 3); + EXPECT_THAT((Type, Span, + Span>>(x.Slices(p))), + Tuple(IsSameSlice(x.Slice<0>(p)), IsSameSlice(x.Slice<1>(p)), + IsSameSlice(x.Slice<2>(p)))); + } +} + +TEST(Layout, MutableSlices) { + alignas(max_align_t) unsigned char p[100] = {}; + using L = Layout; + { + const auto x = L::Partial(); + EXPECT_THAT(Type>(x.Slices(p)), Tuple()); + } + { + const auto x = L::Partial(1); + EXPECT_THAT(Type>>(x.Slices(p)), + Tuple(IsSameSlice(x.Slice<0>(p)))); + } + { + const auto x = L::Partial(1, 2); + EXPECT_THAT((Type, Span>>(x.Slices(p))), + Tuple(IsSameSlice(x.Slice<0>(p)), IsSameSlice(x.Slice<1>(p)))); + } + { + const auto x = L::Partial(1, 2, 3); + EXPECT_THAT( + (Type, Span, Span>>(x.Slices(p))), + Tuple(IsSameSlice(x.Slice<0>(p)), IsSameSlice(x.Slice<1>(p)), + IsSameSlice(x.Slice<2>(p)))); + } + { + const L x(1, 2, 3); + EXPECT_THAT( + (Type, Span, Span>>(x.Slices(p))), + Tuple(IsSameSlice(x.Slice<0>(p)), IsSameSlice(x.Slice<1>(p)), + IsSameSlice(x.Slice<2>(p)))); + } +} + +TEST(Layout, UnalignedTypes) { + constexpr Layout x(1, 2, 3); + alignas(max_align_t) unsigned char p[x.AllocSize() + 1]; + EXPECT_THAT(x.Pointers(p + 1), Tuple(p + 1, p + 2, p + 4)); +} + +TEST(Layout, CustomAlignment) { + constexpr Layout> x(1, 2); + alignas(max_align_t) unsigned char p[x.AllocSize()]; + EXPECT_EQ(10, x.AllocSize()); + EXPECT_THAT(x.Pointers(p), Tuple(p + 0, p + 8)); +} + +TEST(Layout, OverAligned) { + constexpr size_t M = alignof(max_align_t); + constexpr Layout> x(1, 3); + alignas(2 * M) unsigned char p[x.AllocSize()]; + EXPECT_EQ(2 * M + 3, x.AllocSize()); + EXPECT_THAT(x.Pointers(p), Tuple(p + 0, p + 2 * M)); +} + +TEST(Layout, Alignment) { + static_assert(Layout::Alignment() == 1, ""); + static_assert(Layout::Alignment() == 4, ""); + static_assert(Layout::Alignment() == 8, ""); + static_assert(Layout>::Alignment() == 64, ""); + static_assert(Layout::Alignment() == 8, ""); + static_assert(Layout::Alignment() == 8, ""); + static_assert(Layout::Alignment() == 8, ""); + static_assert(Layout::Alignment() == 8, ""); + static_assert(Layout::Alignment() == 8, ""); + static_assert(Layout::Alignment() == 8, ""); +} + +TEST(Layout, ConstexprPartial) { + constexpr size_t M = alignof(max_align_t); + constexpr Layout> x(1, 3); + static_assert(x.Partial(1).template Offset<1>() == 2 * M, ""); +} +// [from, to) +struct Region { + size_t from; + size_t to; +}; + +void ExpectRegionPoisoned(const unsigned char* p, size_t n, bool poisoned) { +#ifdef ADDRESS_SANITIZER + for (size_t i = 0; i != n; ++i) { + EXPECT_EQ(poisoned, __asan_address_is_poisoned(p + i)); + } +#endif +} + +template +void ExpectPoisoned(const unsigned char (&buf)[N], + std::initializer_list reg) { + size_t prev = 0; + for (const Region& r : reg) { + ExpectRegionPoisoned(buf + prev, r.from - prev, false); + ExpectRegionPoisoned(buf + r.from, r.to - r.from, true); + prev = r.to; + } + ExpectRegionPoisoned(buf + prev, N - prev, false); +} + +TEST(Layout, PoisonPadding) { + using L = Layout; + + constexpr size_t n = L::Partial(1, 2, 3, 4).AllocSize(); + { + constexpr auto x = L::Partial(); + alignas(max_align_t) const unsigned char c[n] = {}; + x.PoisonPadding(c); + EXPECT_EQ(x.Slices(c), x.Slices(c)); + ExpectPoisoned(c, {}); + } + { + constexpr auto x = L::Partial(1); + alignas(max_align_t) const unsigned char c[n] = {}; + x.PoisonPadding(c); + EXPECT_EQ(x.Slices(c), x.Slices(c)); + ExpectPoisoned(c, {{1, 8}}); + } + { + constexpr auto x = L::Partial(1, 2); + alignas(max_align_t) const unsigned char c[n] = {}; + x.PoisonPadding(c); + EXPECT_EQ(x.Slices(c), x.Slices(c)); + ExpectPoisoned(c, {{1, 8}}); + } + { + constexpr auto x = L::Partial(1, 2, 3); + alignas(max_align_t) const unsigned char c[n] = {}; + x.PoisonPadding(c); + EXPECT_EQ(x.Slices(c), x.Slices(c)); + ExpectPoisoned(c, {{1, 8}, {36, 40}}); + } + { + constexpr auto x = L::Partial(1, 2, 3, 4); + alignas(max_align_t) const unsigned char c[n] = {}; + x.PoisonPadding(c); + EXPECT_EQ(x.Slices(c), x.Slices(c)); + ExpectPoisoned(c, {{1, 8}, {36, 40}}); + } + { + constexpr L x(1, 2, 3, 4); + alignas(max_align_t) const unsigned char c[n] = {}; + x.PoisonPadding(c); + EXPECT_EQ(x.Slices(c), x.Slices(c)); + ExpectPoisoned(c, {{1, 8}, {36, 40}}); + } +} + +TEST(Layout, DebugString) { + const std::string int64_type = +#ifdef _MSC_VER + "__int64"; +#else // _MSC_VER + std::is_same::value ? "long long" : "long"; // NOLINT +#endif // _MSC_VER + { + constexpr auto x = Layout::Partial(); + EXPECT_EQ("@0(1)", x.DebugString()); + } + { + constexpr auto x = Layout::Partial(1); + EXPECT_EQ("@0(1)[1]; @4(4)", x.DebugString()); + } + { + constexpr auto x = Layout::Partial(1, 2); + EXPECT_EQ("@0(1)[1]; @4(4)[2]; @12(1)", + x.DebugString()); + } + { + constexpr auto x = Layout::Partial(1, 2, 3); + EXPECT_EQ( + "@0(1)[1]; @4(4)[2]; @12(1)[3]; " + "@16<" + + int64_type + " [2]>(16)", + x.DebugString()); + } + { + constexpr auto x = Layout::Partial(1, 2, 3, 4); + EXPECT_EQ( + "@0(1)[1]; @4(4)[2]; @12(1)[3]; " + "@16<" + + int64_type + " [2]>(16)[4]", + x.DebugString()); + } + { + constexpr Layout x(1, 2, 3, 4); + EXPECT_EQ( + "@0(1)[1]; @4(4)[2]; @12(1)[3]; " + "@16<" + + int64_type + " [2]>(16)[4]", + x.DebugString()); + } +} + +TEST(Layout, CharTypes) { + constexpr Layout x(1); + alignas(max_align_t) char c[x.AllocSize()] = {}; + alignas(max_align_t) unsigned char uc[x.AllocSize()] = {}; + alignas(max_align_t) signed char sc[x.AllocSize()] = {}; + alignas(max_align_t) const char cc[x.AllocSize()] = {}; + alignas(max_align_t) const unsigned char cuc[x.AllocSize()] = {}; + alignas(max_align_t) const signed char csc[x.AllocSize()] = {}; + + Type(x.Pointer<0>(c)); + Type(x.Pointer<0>(uc)); + Type(x.Pointer<0>(sc)); + Type(x.Pointer<0>(cc)); + Type(x.Pointer<0>(cuc)); + Type(x.Pointer<0>(csc)); + + Type(x.Pointer(c)); + Type(x.Pointer(uc)); + Type(x.Pointer(sc)); + Type(x.Pointer(cc)); + Type(x.Pointer(cuc)); + Type(x.Pointer(csc)); + + Type>(x.Pointers(c)); + Type>(x.Pointers(uc)); + Type>(x.Pointers(sc)); + Type>(x.Pointers(cc)); + Type>(x.Pointers(cuc)); + Type>(x.Pointers(csc)); + + Type>(x.Slice<0>(c)); + Type>(x.Slice<0>(uc)); + Type>(x.Slice<0>(sc)); + Type>(x.Slice<0>(cc)); + Type>(x.Slice<0>(cuc)); + Type>(x.Slice<0>(csc)); + + Type>>(x.Slices(c)); + Type>>(x.Slices(uc)); + Type>>(x.Slices(sc)); + Type>>(x.Slices(cc)); + Type>>(x.Slices(cuc)); + Type>>(x.Slices(csc)); +} + +TEST(Layout, ConstElementType) { + constexpr Layout x(1); + alignas(int32_t) char c[x.AllocSize()] = {}; + const char* cc = c; + const int32_t* p = reinterpret_cast(cc); + + EXPECT_EQ(alignof(int32_t), x.Alignment()); + + EXPECT_EQ(0, x.Offset<0>()); + EXPECT_EQ(0, x.Offset()); + + EXPECT_THAT(x.Offsets(), ElementsAre(0)); + + EXPECT_EQ(1, x.Size<0>()); + EXPECT_EQ(1, x.Size()); + + EXPECT_THAT(x.Sizes(), ElementsAre(1)); + + EXPECT_EQ(sizeof(int32_t), x.AllocSize()); + + EXPECT_EQ(p, Type(x.Pointer<0>(c))); + EXPECT_EQ(p, Type(x.Pointer<0>(cc))); + + EXPECT_EQ(p, Type(x.Pointer(c))); + EXPECT_EQ(p, Type(x.Pointer(cc))); + + EXPECT_THAT(Type>(x.Pointers(c)), Tuple(p)); + EXPECT_THAT(Type>(x.Pointers(cc)), Tuple(p)); + + EXPECT_THAT(Type>(x.Slice<0>(c)), + IsSameSlice(Span(p, 1))); + EXPECT_THAT(Type>(x.Slice<0>(cc)), + IsSameSlice(Span(p, 1))); + + EXPECT_THAT(Type>(x.Slice(c)), + IsSameSlice(Span(p, 1))); + EXPECT_THAT(Type>(x.Slice(cc)), + IsSameSlice(Span(p, 1))); + + EXPECT_THAT(Type>>(x.Slices(c)), + Tuple(IsSameSlice(Span(p, 1)))); + EXPECT_THAT(Type>>(x.Slices(cc)), + Tuple(IsSameSlice(Span(p, 1)))); +} + +namespace example { + +// Immutable move-only string with sizeof equal to sizeof(void*). The string +// size and the characters are kept in the same heap allocation. +class CompactString { + public: + CompactString(const char* s = "") { // NOLINT + const size_t size = strlen(s); + // size_t[1], followed by char[size + 1]. + // This statement doesn't allocate memory. + const L layout(1, size + 1); + // AllocSize() tells us how much memory we need to allocate for all our + // data. + p_.reset(new unsigned char[layout.AllocSize()]); + // If running under ASAN, mark the padding bytes, if any, to catch memory + // errors. + layout.PoisonPadding(p_.get()); + // Store the size in the allocation. + // Pointer() is a synonym for Pointer<0>(). + *layout.Pointer(p_.get()) = size; + // Store the characters in the allocation. + memcpy(layout.Pointer(p_.get()), s, size + 1); + } + + size_t size() const { + // Equivalent to reinterpret_cast(*p). + return *L::Partial().Pointer(p_.get()); + } + + const char* c_str() const { + // Equivalent to reinterpret_cast(p.get() + sizeof(size_t)). + // The argument in Partial(1) specifies that we have size_t[1] in front of + // the + // characters. + return L::Partial(1).Pointer(p_.get()); + } + + private: + // Our heap allocation contains a size_t followed by an array of chars. + using L = Layout; + std::unique_ptr p_; +}; + +TEST(CompactString, Works) { + CompactString s = "hello"; + EXPECT_EQ(5, s.size()); + EXPECT_STREQ("hello", s.c_str()); +} + +} // namespace example + +} // namespace +} // namespace container_internal +} // namespace absl diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/internal/node_hash_policy.h b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/internal/node_hash_policy.h new file mode 100644 index 0000000..065e700 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/internal/node_hash_policy.h @@ -0,0 +1,88 @@ +// Copyright 2018 The Abseil Authors. +// +// 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. +// +// Adapts a policy for nodes. +// +// The node policy should model: +// +// struct Policy { +// // Returns a new node allocated and constructed using the allocator, using +// // the specified arguments. +// template +// value_type* new_element(Alloc* alloc, Args&&... args) const; +// +// // Destroys and deallocates node using the allocator. +// template +// void delete_element(Alloc* alloc, value_type* node) const; +// }; +// +// It may also optionally define `value()` and `apply()`. For documentation on +// these, see hash_policy_traits.h. + +#ifndef ABSL_CONTAINER_INTERNAL_NODE_HASH_POLICY_H_ +#define ABSL_CONTAINER_INTERNAL_NODE_HASH_POLICY_H_ + +#include +#include +#include +#include +#include + +namespace absl { +namespace container_internal { + +template +struct node_hash_policy { + static_assert(std::is_lvalue_reference::value, ""); + + using slot_type = typename std::remove_cv< + typename std::remove_reference::type>::type*; + + template + static void construct(Alloc* alloc, slot_type* slot, Args&&... args) { + *slot = Policy::new_element(alloc, std::forward(args)...); + } + + template + static void destroy(Alloc* alloc, slot_type* slot) { + Policy::delete_element(alloc, *slot); + } + + template + static void transfer(Alloc*, slot_type* new_slot, slot_type* old_slot) { + *new_slot = *old_slot; + } + + static size_t space_used(const slot_type* slot) { + if (slot == nullptr) return Policy::element_space_used(nullptr); + return Policy::element_space_used(*slot); + } + + static Reference element(slot_type* slot) { return **slot; } + + template + static auto value(T* elem) -> decltype(P::value(elem)) { + return P::value(elem); + } + + template + static auto apply(Ts&&... ts) -> decltype(P::apply(std::forward(ts)...)) { + return P::apply(std::forward(ts)...); + } +}; + +} // namespace container_internal +} // namespace absl + +#endif // ABSL_CONTAINER_INTERNAL_NODE_HASH_POLICY_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/internal/node_hash_policy_test.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/internal/node_hash_policy_test.cc new file mode 100644 index 0000000..43d287e --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/internal/node_hash_policy_test.cc @@ -0,0 +1,67 @@ +// Copyright 2018 The Abseil Authors. +// +// 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 "absl/container/internal/node_hash_policy.h" + +#include + +#include "gmock/gmock.h" +#include "gtest/gtest.h" +#include "absl/container/internal/hash_policy_traits.h" + +namespace absl { +namespace container_internal { +namespace { + +using ::testing::Pointee; + +struct Policy : node_hash_policy { + using key_type = int; + using init_type = int; + + template + static int* new_element(Alloc* alloc, int value) { + return new int(value); + } + + template + static void delete_element(Alloc* alloc, int* elem) { + delete elem; + } +}; + +using NodePolicy = hash_policy_traits; + +struct NodeTest : ::testing::Test { + std::allocator alloc; + int n = 53; + int* a = &n; +}; + +TEST_F(NodeTest, ConstructDestroy) { + NodePolicy::construct(&alloc, &a, 42); + EXPECT_THAT(a, Pointee(42)); + NodePolicy::destroy(&alloc, &a); +} + +TEST_F(NodeTest, transfer) { + int s = 42; + int* b = &s; + NodePolicy::transfer(&alloc, &a, &b); + EXPECT_EQ(&s, a); +} + +} // namespace +} // namespace container_internal +} // namespace absl diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/internal/raw_hash_map.h b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/internal/raw_hash_map.h new file mode 100644 index 0000000..05270ef --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/internal/raw_hash_map.h @@ -0,0 +1,185 @@ +// Copyright 2018 The Abseil Authors. +// +// 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. + +#ifndef ABSL_CONTAINER_INTERNAL_RAW_HASH_MAP_H_ +#define ABSL_CONTAINER_INTERNAL_RAW_HASH_MAP_H_ + +#include +#include +#include + +#include "absl/container/internal/container_memory.h" +#include "absl/container/internal/raw_hash_set.h" // IWYU pragma: export + +namespace absl { +namespace container_internal { + +template +class raw_hash_map : public raw_hash_set { + // P is Policy. It's passed as a template argument to support maps that have + // incomplete types as values, as in unordered_map. + // MappedReference<> may be a non-reference type. + template + using MappedReference = decltype(P::value( + std::addressof(std::declval()))); + + // MappedConstReference<> may be a non-reference type. + template + using MappedConstReference = decltype(P::value( + std::addressof(std::declval()))); + + using KeyArgImpl = container_internal::KeyArg::value && + IsTransparent::value>; + + public: + using key_type = typename Policy::key_type; + using mapped_type = typename Policy::mapped_type; + template + using key_arg = typename KeyArgImpl::template type; + + static_assert(!std::is_reference::value, ""); + // TODO(alkis): remove this assertion and verify that reference mapped_type is + // supported. + static_assert(!std::is_reference::value, ""); + + using iterator = typename raw_hash_map::raw_hash_set::iterator; + using const_iterator = typename raw_hash_map::raw_hash_set::const_iterator; + + raw_hash_map() {} + using raw_hash_map::raw_hash_set::raw_hash_set; + + // The last two template parameters ensure that both arguments are rvalues + // (lvalue arguments are handled by the overloads below). This is necessary + // for supporting bitfield arguments. + // + // union { int n : 1; }; + // flat_hash_map m; + // m.insert_or_assign(n, n); + template + std::pair insert_or_assign(key_arg&& k, V&& v) { + return insert_or_assign_impl(std::forward(k), std::forward(v)); + } + + template + std::pair insert_or_assign(key_arg&& k, const V& v) { + return insert_or_assign_impl(std::forward(k), v); + } + + template + std::pair insert_or_assign(const key_arg& k, V&& v) { + return insert_or_assign_impl(k, std::forward(v)); + } + + template + std::pair insert_or_assign(const key_arg& k, const V& v) { + return insert_or_assign_impl(k, v); + } + + template + iterator insert_or_assign(const_iterator, key_arg&& k, V&& v) { + return insert_or_assign(std::forward(k), std::forward(v)).first; + } + + template + iterator insert_or_assign(const_iterator, key_arg&& k, const V& v) { + return insert_or_assign(std::forward(k), v).first; + } + + template + iterator insert_or_assign(const_iterator, const key_arg& k, V&& v) { + return insert_or_assign(k, std::forward(v)).first; + } + + template + iterator insert_or_assign(const_iterator, const key_arg& k, const V& v) { + return insert_or_assign(k, v).first; + } + + template ::value, int>::type = 0, + K* = nullptr> + std::pair try_emplace(key_arg&& k, Args&&... args) { + return try_emplace_impl(std::forward(k), std::forward(args)...); + } + + template ::value, int>::type = 0> + std::pair try_emplace(const key_arg& k, Args&&... args) { + return try_emplace_impl(k, std::forward(args)...); + } + + template + iterator try_emplace(const_iterator, key_arg&& k, Args&&... args) { + return try_emplace(std::forward(k), std::forward(args)...).first; + } + + template + iterator try_emplace(const_iterator, const key_arg& k, Args&&... args) { + return try_emplace(k, std::forward(args)...).first; + } + + template + MappedReference

at(const key_arg& key) { + auto it = this->find(key); + if (it == this->end()) std::abort(); + return Policy::value(&*it); + } + + template + MappedConstReference

at(const key_arg& key) const { + auto it = this->find(key); + if (it == this->end()) std::abort(); + return Policy::value(&*it); + } + + template + MappedReference

operator[](key_arg&& key) { + return Policy::value(&*try_emplace(std::forward(key)).first); + } + + template + MappedReference

operator[](const key_arg& key) { + return Policy::value(&*try_emplace(key).first); + } + + private: + template + std::pair insert_or_assign_impl(K&& k, V&& v) { + auto res = this->find_or_prepare_insert(k); + if (res.second) + this->emplace_at(res.first, std::forward(k), std::forward(v)); + else + Policy::value(&*this->iterator_at(res.first)) = std::forward(v); + return {this->iterator_at(res.first), res.second}; + } + + template + std::pair try_emplace_impl(K&& k, Args&&... args) { + auto res = this->find_or_prepare_insert(k); + if (res.second) + this->emplace_at(res.first, std::piecewise_construct, + std::forward_as_tuple(std::forward(k)), + std::forward_as_tuple(std::forward(args)...)); + return {this->iterator_at(res.first), res.second}; + } +}; + +} // namespace container_internal +} // namespace absl + +#endif // ABSL_CONTAINER_INTERNAL_RAW_HASH_MAP_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/internal/raw_hash_set.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/internal/raw_hash_set.cc new file mode 100644 index 0000000..1015312 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/internal/raw_hash_set.cc @@ -0,0 +1,45 @@ +// Copyright 2018 The Abseil Authors. +// +// 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 "absl/container/internal/raw_hash_set.h" + +#include + +#include "absl/base/config.h" + +namespace absl { +namespace container_internal { + +constexpr size_t Group::kWidth; + +// Returns "random" seed. +inline size_t RandomSeed() { +#if ABSL_HAVE_THREAD_LOCAL + static thread_local size_t counter = 0; + size_t value = ++counter; +#else // ABSL_HAVE_THREAD_LOCAL + static std::atomic counter; + size_t value = counter.fetch_add(1, std::memory_order_relaxed); +#endif // ABSL_HAVE_THREAD_LOCAL + return value ^ static_cast(reinterpret_cast(&counter)); +} + +bool ShouldInsertBackwards(size_t hash, ctrl_t* ctrl) { + // To avoid problems with weak hashes and single bit tests, we use % 13. + // TODO(kfm,sbenza): revisit after we do unconditional mixing + return (H1(hash, ctrl) ^ RandomSeed()) % 13 > 6; +} + +} // namespace container_internal +} // namespace absl diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/internal/raw_hash_set.h b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/internal/raw_hash_set.h new file mode 100644 index 0000000..26d9972 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/internal/raw_hash_set.h @@ -0,0 +1,1945 @@ +// Copyright 2018 The Abseil Authors. +// +// 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. +// +// An open-addressing +// hashtable with quadratic probing. +// +// This is a low level hashtable on top of which different interfaces can be +// implemented, like flat_hash_set, node_hash_set, string_hash_set, etc. +// +// The table interface is similar to that of std::unordered_set. Notable +// differences are that most member functions support heterogeneous keys when +// BOTH the hash and eq functions are marked as transparent. They do so by +// providing a typedef called `is_transparent`. +// +// When heterogeneous lookup is enabled, functions that take key_type act as if +// they have an overload set like: +// +// iterator find(const key_type& key); +// template +// iterator find(const K& key); +// +// size_type erase(const key_type& key); +// template +// size_type erase(const K& key); +// +// std::pair equal_range(const key_type& key); +// template +// std::pair equal_range(const K& key); +// +// When heterogeneous lookup is disabled, only the explicit `key_type` overloads +// exist. +// +// find() also supports passing the hash explicitly: +// +// iterator find(const key_type& key, size_t hash); +// template +// iterator find(const U& key, size_t hash); +// +// In addition the pointer to element and iterator stability guarantees are +// weaker: all iterators and pointers are invalidated after a new element is +// inserted. +// +// IMPLEMENTATION DETAILS +// +// The table stores elements inline in a slot array. In addition to the slot +// array the table maintains some control state per slot. The extra state is one +// byte per slot and stores empty or deleted marks, or alternatively 7 bits from +// the hash of an occupied slot. The table is split into logical groups of +// slots, like so: +// +// Group 1 Group 2 Group 3 +// +---------------+---------------+---------------+ +// | | | | | | | | | | | | | | | | | | | | | | | | | +// +---------------+---------------+---------------+ +// +// On lookup the hash is split into two parts: +// - H2: 7 bits (those stored in the control bytes) +// - H1: the rest of the bits +// The groups are probed using H1. For each group the slots are matched to H2 in +// parallel. Because H2 is 7 bits (128 states) and the number of slots per group +// is low (8 or 16) in almost all cases a match in H2 is also a lookup hit. +// +// On insert, once the right group is found (as in lookup), its slots are +// filled in order. +// +// On erase a slot is cleared. In case the group did not have any empty slots +// before the erase, the erased slot is marked as deleted. +// +// Groups without empty slots (but maybe with deleted slots) extend the probe +// sequence. The probing algorithm is quadratic. Given N the number of groups, +// the probing function for the i'th probe is: +// +// P(0) = H1 % N +// +// P(i) = (P(i - 1) + i) % N +// +// This probing function guarantees that after N probes, all the groups of the +// table will be probed exactly once. + +#ifndef ABSL_CONTAINER_INTERNAL_RAW_HASH_SET_H_ +#define ABSL_CONTAINER_INTERNAL_RAW_HASH_SET_H_ + +#ifndef SWISSTABLE_HAVE_SSE2 +#if defined(__SSE2__) || \ + (defined(_MSC_VER) && \ + (defined(_M_X64) || (defined(_M_IX86) && _M_IX86_FP >= 2))) +#define SWISSTABLE_HAVE_SSE2 1 +#else +#define SWISSTABLE_HAVE_SSE2 0 +#endif +#endif + +#ifndef SWISSTABLE_HAVE_SSSE3 +#ifdef __SSSE3__ +#define SWISSTABLE_HAVE_SSSE3 1 +#else +#define SWISSTABLE_HAVE_SSSE3 0 +#endif +#endif + +#if SWISSTABLE_HAVE_SSSE3 && !SWISSTABLE_HAVE_SSE2 +#error "Bad configuration!" +#endif + +#if SWISSTABLE_HAVE_SSE2 +#include +#endif + +#if SWISSTABLE_HAVE_SSSE3 +#include +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "absl/base/internal/bits.h" +#include "absl/base/internal/endian.h" +#include "absl/base/port.h" +#include "absl/container/internal/compressed_tuple.h" +#include "absl/container/internal/container_memory.h" +#include "absl/container/internal/hash_policy_traits.h" +#include "absl/container/internal/hashtable_debug_hooks.h" +#include "absl/container/internal/layout.h" +#include "absl/memory/memory.h" +#include "absl/meta/type_traits.h" +#include "absl/types/optional.h" +#include "absl/utility/utility.h" + +namespace absl { +namespace container_internal { + +template +class probe_seq { + public: + probe_seq(size_t hash, size_t mask) { + assert(((mask + 1) & mask) == 0 && "not a mask"); + mask_ = mask; + offset_ = hash & mask_; + } + size_t offset() const { return offset_; } + size_t offset(size_t i) const { return (offset_ + i) & mask_; } + + void next() { + index_ += Width; + offset_ += index_; + offset_ &= mask_; + } + // 0-based probe index. The i-th probe in the probe sequence. + size_t index() const { return index_; } + + private: + size_t mask_; + size_t offset_; + size_t index_ = 0; +}; + +template +struct RequireUsableKey { + template + std::pair< + decltype(std::declval()(std::declval())), + decltype(std::declval()(std::declval(), + std::declval()))>* + operator()(const PassedKey&, const Args&...) const; +}; + +template +struct IsDecomposable : std::false_type {}; + +template +struct IsDecomposable< + absl::void_t(), + std::declval()...))>, + Policy, Hash, Eq, Ts...> : std::true_type {}; + +template +struct IsTransparent : std::false_type {}; +template +struct IsTransparent> + : std::true_type {}; + +// TODO(alkis): Switch to std::is_nothrow_swappable when gcc/clang supports it. +template +constexpr bool IsNoThrowSwappable() { + using std::swap; + return noexcept(swap(std::declval(), std::declval())); +} + +template +int TrailingZeros(T x) { + return sizeof(T) == 8 ? base_internal::CountTrailingZerosNonZero64(x) + : base_internal::CountTrailingZerosNonZero32(x); +} + +template +int LeadingZeros(T x) { + return sizeof(T) == 8 ? base_internal::CountLeadingZeros64(x) + : base_internal::CountLeadingZeros32(x); +} + +// An abstraction over a bitmask. It provides an easy way to iterate through the +// indexes of the set bits of a bitmask. When Shift=0 (platforms with SSE), +// this is a true bitmask. On non-SSE, platforms the arithematic used to +// emulate the SSE behavior works in bytes (Shift=3) and leaves each bytes as +// either 0x00 or 0x80. +// +// For example: +// for (int i : BitMask(0x5)) -> yields 0, 2 +// for (int i : BitMask(0x0000000080800000)) -> yields 2, 3 +template +class BitMask { + static_assert(std::is_unsigned::value, ""); + static_assert(Shift == 0 || Shift == 3, ""); + + public: + // These are useful for unit tests (gunit). + using value_type = int; + using iterator = BitMask; + using const_iterator = BitMask; + + explicit BitMask(T mask) : mask_(mask) {} + BitMask& operator++() { + mask_ &= (mask_ - 1); + return *this; + } + explicit operator bool() const { return mask_ != 0; } + int operator*() const { return LowestBitSet(); } + int LowestBitSet() const { + return container_internal::TrailingZeros(mask_) >> Shift; + } + int HighestBitSet() const { + return (sizeof(T) * CHAR_BIT - container_internal::LeadingZeros(mask_) - + 1) >> + Shift; + } + + BitMask begin() const { return *this; } + BitMask end() const { return BitMask(0); } + + int TrailingZeros() const { + return container_internal::TrailingZeros(mask_) >> Shift; + } + + int LeadingZeros() const { + constexpr int total_significant_bits = SignificantBits << Shift; + constexpr int extra_bits = sizeof(T) * 8 - total_significant_bits; + return container_internal::LeadingZeros(mask_ << extra_bits) >> Shift; + } + + private: + friend bool operator==(const BitMask& a, const BitMask& b) { + return a.mask_ == b.mask_; + } + friend bool operator!=(const BitMask& a, const BitMask& b) { + return a.mask_ != b.mask_; + } + + T mask_; +}; + +using ctrl_t = signed char; +using h2_t = uint8_t; + +// The values here are selected for maximum performance. See the static asserts +// below for details. +enum Ctrl : ctrl_t { + kEmpty = -128, // 0b10000000 + kDeleted = -2, // 0b11111110 + kSentinel = -1, // 0b11111111 +}; +static_assert( + kEmpty & kDeleted & kSentinel & 0x80, + "Special markers need to have the MSB to make checking for them efficient"); +static_assert(kEmpty < kSentinel && kDeleted < kSentinel, + "kEmpty and kDeleted must be smaller than kSentinel to make the " + "SIMD test of IsEmptyOrDeleted() efficient"); +static_assert(kSentinel == -1, + "kSentinel must be -1 to elide loading it from memory into SIMD " + "registers (pcmpeqd xmm, xmm)"); +static_assert(kEmpty == -128, + "kEmpty must be -128 to make the SIMD check for its " + "existence efficient (psignb xmm, xmm)"); +static_assert(~kEmpty & ~kDeleted & kSentinel & 0x7F, + "kEmpty and kDeleted must share an unset bit that is not shared " + "by kSentinel to make the scalar test for MatchEmptyOrDeleted() " + "efficient"); +static_assert(kDeleted == -2, + "kDeleted must be -2 to make the implementation of " + "ConvertSpecialToEmptyAndFullToDeleted efficient"); + +// A single block of empty control bytes for tables without any slots allocated. +// This enables removing a branch in the hot path of find(). +inline ctrl_t* EmptyGroup() { + alignas(16) static constexpr ctrl_t empty_group[] = { + kSentinel, kEmpty, kEmpty, kEmpty, kEmpty, kEmpty, kEmpty, kEmpty, + kEmpty, kEmpty, kEmpty, kEmpty, kEmpty, kEmpty, kEmpty, kEmpty}; + return const_cast(empty_group); +} + +// Mixes a randomly generated per-process seed with `hash` and `ctrl` to +// randomize insertion order within groups. +bool ShouldInsertBackwards(size_t hash, ctrl_t* ctrl); + +// Returns a hash seed. +// +// The seed consists of the ctrl_ pointer, which adds enough entropy to ensure +// non-determinism of iteration order in most cases. +inline size_t HashSeed(const ctrl_t* ctrl) { + // The low bits of the pointer have little or no entropy because of + // alignment. We shift the pointer to try to use higher entropy bits. A + // good number seems to be 12 bits, because that aligns with page size. + return reinterpret_cast(ctrl) >> 12; +} + +inline size_t H1(size_t hash, const ctrl_t* ctrl) { + return (hash >> 7) ^ HashSeed(ctrl); +} +inline ctrl_t H2(size_t hash) { return hash & 0x7F; } + +inline bool IsEmpty(ctrl_t c) { return c == kEmpty; } +inline bool IsFull(ctrl_t c) { return c >= 0; } +inline bool IsDeleted(ctrl_t c) { return c == kDeleted; } +inline bool IsEmptyOrDeleted(ctrl_t c) { return c < kSentinel; } + +#if SWISSTABLE_HAVE_SSE2 + +// https://github.com/abseil/abseil-cpp/issues/209 +// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87853 +// _mm_cmpgt_epi8 is broken under GCC with -funsigned-char +// Work around this by using the portable implementation of Group +// when using -funsigned-char under GCC. +inline __m128i _mm_cmpgt_epi8_fixed(__m128i a, __m128i b) { +#if defined(__GNUC__) && !defined(__clang__) + if (std::is_unsigned::value) { + const __m128i mask = _mm_set1_epi8(0x80); + const __m128i diff = _mm_subs_epi8(b, a); + return _mm_cmpeq_epi8(_mm_and_si128(diff, mask), mask); + } +#endif + return _mm_cmpgt_epi8(a, b); +} + +struct GroupSse2Impl { + static constexpr size_t kWidth = 16; // the number of slots per group + + explicit GroupSse2Impl(const ctrl_t* pos) { + ctrl = _mm_loadu_si128(reinterpret_cast(pos)); + } + + // Returns a bitmask representing the positions of slots that match hash. + BitMask Match(h2_t hash) const { + auto match = _mm_set1_epi8(hash); + return BitMask( + _mm_movemask_epi8(_mm_cmpeq_epi8(match, ctrl))); + } + + // Returns a bitmask representing the positions of empty slots. + BitMask MatchEmpty() const { +#if SWISSTABLE_HAVE_SSSE3 + // This only works because kEmpty is -128. + return BitMask( + _mm_movemask_epi8(_mm_sign_epi8(ctrl, ctrl))); +#else + return Match(kEmpty); +#endif + } + + // Returns a bitmask representing the positions of empty or deleted slots. + BitMask MatchEmptyOrDeleted() const { + auto special = _mm_set1_epi8(kSentinel); + return BitMask( + _mm_movemask_epi8(_mm_cmpgt_epi8_fixed(special, ctrl))); + } + + // Returns the number of trailing empty or deleted elements in the group. + uint32_t CountLeadingEmptyOrDeleted() const { + auto special = _mm_set1_epi8(kSentinel); + return TrailingZeros( + _mm_movemask_epi8(_mm_cmpgt_epi8_fixed(special, ctrl)) + 1); + } + + void ConvertSpecialToEmptyAndFullToDeleted(ctrl_t* dst) const { + auto msbs = _mm_set1_epi8(0x80); + auto x126 = _mm_set1_epi8(126); +#if SWISSTABLE_HAVE_SSSE3 + auto res = _mm_or_si128(_mm_shuffle_epi8(x126, ctrl), msbs); +#else + auto zero = _mm_setzero_si128(); + auto special_mask = _mm_cmpgt_epi8_fixed(zero, ctrl); + auto res = _mm_or_si128(msbs, _mm_andnot_si128(special_mask, x126)); +#endif + _mm_storeu_si128(reinterpret_cast<__m128i*>(dst), res); + } + + __m128i ctrl; +}; +#endif // SWISSTABLE_HAVE_SSE2 + +struct GroupPortableImpl { + static constexpr size_t kWidth = 8; + + explicit GroupPortableImpl(const ctrl_t* pos) + : ctrl(little_endian::Load64(pos)) {} + + BitMask Match(h2_t hash) const { + // For the technique, see: + // http://graphics.stanford.edu/~seander/bithacks.html##ValueInWord + // (Determine if a word has a byte equal to n). + // + // Caveat: there are false positives but: + // - they only occur if there is a real match + // - they never occur on kEmpty, kDeleted, kSentinel + // - they will be handled gracefully by subsequent checks in code + // + // Example: + // v = 0x1716151413121110 + // hash = 0x12 + // retval = (v - lsbs) & ~v & msbs = 0x0000000080800000 + constexpr uint64_t msbs = 0x8080808080808080ULL; + constexpr uint64_t lsbs = 0x0101010101010101ULL; + auto x = ctrl ^ (lsbs * hash); + return BitMask((x - lsbs) & ~x & msbs); + } + + BitMask MatchEmpty() const { + constexpr uint64_t msbs = 0x8080808080808080ULL; + return BitMask((ctrl & (~ctrl << 6)) & msbs); + } + + BitMask MatchEmptyOrDeleted() const { + constexpr uint64_t msbs = 0x8080808080808080ULL; + return BitMask((ctrl & (~ctrl << 7)) & msbs); + } + + uint32_t CountLeadingEmptyOrDeleted() const { + constexpr uint64_t gaps = 0x00FEFEFEFEFEFEFEULL; + return (TrailingZeros(((~ctrl & (ctrl >> 7)) | gaps) + 1) + 7) >> 3; + } + + void ConvertSpecialToEmptyAndFullToDeleted(ctrl_t* dst) const { + constexpr uint64_t msbs = 0x8080808080808080ULL; + constexpr uint64_t lsbs = 0x0101010101010101ULL; + auto x = ctrl & msbs; + auto res = (~x + (x >> 7)) & ~lsbs; + little_endian::Store64(dst, res); + } + + uint64_t ctrl; +}; + +#if SWISSTABLE_HAVE_SSE2 +using Group = GroupSse2Impl; +#else +using Group = GroupPortableImpl; +#endif + +template +class raw_hash_set; + +inline bool IsValidCapacity(size_t n) { + return ((n + 1) & n) == 0 && n >= Group::kWidth - 1; +} + +// PRECONDITION: +// IsValidCapacity(capacity) +// ctrl[capacity] == kSentinel +// ctrl[i] != kSentinel for all i < capacity +// Applies mapping for every byte in ctrl: +// DELETED -> EMPTY +// EMPTY -> EMPTY +// FULL -> DELETED +inline void ConvertDeletedToEmptyAndFullToDeleted( + ctrl_t* ctrl, size_t capacity) { + assert(ctrl[capacity] == kSentinel); + assert(IsValidCapacity(capacity)); + for (ctrl_t* pos = ctrl; pos != ctrl + capacity + 1; pos += Group::kWidth) { + Group{pos}.ConvertSpecialToEmptyAndFullToDeleted(pos); + } + // Copy the cloned ctrl bytes. + std::memcpy(ctrl + capacity + 1, ctrl, Group::kWidth); + ctrl[capacity] = kSentinel; +} + +// Rounds up the capacity to the next power of 2 minus 1 and ensures it is +// greater or equal to Group::kWidth - 1. +inline size_t NormalizeCapacity(size_t n) { + constexpr size_t kMinCapacity = Group::kWidth - 1; + return n <= kMinCapacity + ? kMinCapacity + : (std::numeric_limits::max)() >> LeadingZeros(n); +} + +// The node_handle concept from C++17. +// We specialize node_handle for sets and maps. node_handle_base holds the +// common API of both. +template +class node_handle_base { + protected: + using PolicyTraits = hash_policy_traits; + using slot_type = typename PolicyTraits::slot_type; + + public: + using allocator_type = Alloc; + + constexpr node_handle_base() {} + node_handle_base(node_handle_base&& other) noexcept { + *this = std::move(other); + } + ~node_handle_base() { destroy(); } + node_handle_base& operator=(node_handle_base&& other) { + destroy(); + if (!other.empty()) { + alloc_ = other.alloc_; + PolicyTraits::transfer(alloc(), slot(), other.slot()); + other.reset(); + } + return *this; + } + + bool empty() const noexcept { return !alloc_; } + explicit operator bool() const noexcept { return !empty(); } + allocator_type get_allocator() const { return *alloc_; } + + protected: + template + friend class raw_hash_set; + + node_handle_base(const allocator_type& a, slot_type* s) : alloc_(a) { + PolicyTraits::transfer(alloc(), slot(), s); + } + + void destroy() { + if (!empty()) { + PolicyTraits::destroy(alloc(), slot()); + reset(); + } + } + + void reset() { + assert(alloc_.has_value()); + alloc_ = absl::nullopt; + } + + slot_type* slot() const { + assert(!empty()); + return reinterpret_cast(std::addressof(slot_space_)); + } + allocator_type* alloc() { return std::addressof(*alloc_); } + + private: + absl::optional alloc_; + mutable absl::aligned_storage_t + slot_space_; +}; + +// For sets. +template +class node_handle : public node_handle_base { + using Base = typename node_handle::node_handle_base; + + public: + using value_type = typename Base::PolicyTraits::value_type; + + constexpr node_handle() {} + + value_type& value() const { + return Base::PolicyTraits::element(this->slot()); + } + + private: + template + friend class raw_hash_set; + + node_handle(const Alloc& a, typename Base::slot_type* s) : Base(a, s) {} +}; + +// For maps. +template +class node_handle> + : public node_handle_base { + using Base = typename node_handle::node_handle_base; + + public: + using key_type = typename Policy::key_type; + using mapped_type = typename Policy::mapped_type; + + constexpr node_handle() {} + + auto key() const -> decltype(Base::PolicyTraits::key(this->slot())) { + return Base::PolicyTraits::key(this->slot()); + } + + mapped_type& mapped() const { + return Base::PolicyTraits::value( + &Base::PolicyTraits::element(this->slot())); + } + + private: + template + friend class raw_hash_set; + + node_handle(const Alloc& a, typename Base::slot_type* s) : Base(a, s) {} +}; + +// Implement the insert_return_type<> concept of C++17. +template +struct insert_return_type { + Iterator position; + bool inserted; + NodeType node; +}; + +// Helper trait to allow or disallow arbitrary keys when the hash and +// eq functions are transparent. +// It is very important that the inner template is an alias and that the type it +// produces is not a dependent type. Otherwise, type deduction would fail. +template +struct KeyArg { + // Transparent. Forward `K`. + template + using type = K; +}; + +template <> +struct KeyArg { + // Not transparent. Always use `key_type`. + template + using type = key_type; +}; + +// Policy: a policy defines how to perform different operations on +// the slots of the hashtable (see hash_policy_traits.h for the full interface +// of policy). +// +// Hash: a (possibly polymorphic) functor that hashes keys of the hashtable. The +// functor should accept a key and return size_t as hash. For best performance +// it is important that the hash function provides high entropy across all bits +// of the hash. +// +// Eq: a (possibly polymorphic) functor that compares two keys for equality. It +// should accept two (of possibly different type) keys and return a bool: true +// if they are equal, false if they are not. If two keys compare equal, then +// their hash values as defined by Hash MUST be equal. +// +// Allocator: an Allocator [http://devdocs.io/cpp/concept/allocator] with which +// the storage of the hashtable will be allocated and the elements will be +// constructed and destroyed. +template +class raw_hash_set { + using PolicyTraits = hash_policy_traits; + using KeyArgImpl = container_internal::KeyArg::value && + IsTransparent::value>; + + public: + using init_type = typename PolicyTraits::init_type; + using key_type = typename PolicyTraits::key_type; + // TODO(sbenza): Hide slot_type as it is an implementation detail. Needs user + // code fixes! + using slot_type = typename PolicyTraits::slot_type; + using allocator_type = Alloc; + using size_type = size_t; + using difference_type = ptrdiff_t; + using hasher = Hash; + using key_equal = Eq; + using policy_type = Policy; + using value_type = typename PolicyTraits::value_type; + using reference = value_type&; + using const_reference = const value_type&; + using pointer = typename absl::allocator_traits< + allocator_type>::template rebind_traits::pointer; + using const_pointer = typename absl::allocator_traits< + allocator_type>::template rebind_traits::const_pointer; + + // Alias used for heterogeneous lookup functions. + // `key_arg` evaluates to `K` when the functors are transparent and to + // `key_type` otherwise. It permits template argument deduction on `K` for the + // transparent case. + template + using key_arg = typename KeyArgImpl::template type; + + private: + // Give an early error when key_type is not hashable/eq. + auto KeyTypeCanBeHashed(const Hash& h, const key_type& k) -> decltype(h(k)); + auto KeyTypeCanBeEq(const Eq& eq, const key_type& k) -> decltype(eq(k, k)); + + using Layout = absl::container_internal::Layout; + + static Layout MakeLayout(size_t capacity) { + assert(IsValidCapacity(capacity)); + return Layout(capacity + Group::kWidth + 1, capacity); + } + + using AllocTraits = absl::allocator_traits; + using SlotAlloc = typename absl::allocator_traits< + allocator_type>::template rebind_alloc; + using SlotAllocTraits = typename absl::allocator_traits< + allocator_type>::template rebind_traits; + + static_assert(std::is_lvalue_reference::value, + "Policy::element() must return a reference"); + + template + struct SameAsElementReference + : std::is_same::type>::type, + typename std::remove_cv< + typename std::remove_reference::type>::type> {}; + + // An enabler for insert(T&&): T must be convertible to init_type or be the + // same as [cv] value_type [ref]. + // Note: we separate SameAsElementReference into its own type to avoid using + // reference unless we need to. MSVC doesn't seem to like it in some + // cases. + template + using RequiresInsertable = typename std::enable_if< + absl::disjunction, + SameAsElementReference>::value, + int>::type; + + // RequiresNotInit is a workaround for gcc prior to 7.1. + // See https://godbolt.org/g/Y4xsUh. + template + using RequiresNotInit = + typename std::enable_if::value, int>::type; + + template + using IsDecomposable = IsDecomposable; + + public: + static_assert(std::is_same::value, + "Allocators with custom pointer types are not supported"); + static_assert(std::is_same::value, + "Allocators with custom pointer types are not supported"); + + class iterator { + friend class raw_hash_set; + + public: + using iterator_category = std::forward_iterator_tag; + using value_type = typename raw_hash_set::value_type; + using reference = + absl::conditional_t; + using pointer = absl::remove_reference_t*; + using difference_type = typename raw_hash_set::difference_type; + + iterator() {} + + // PRECONDITION: not an end() iterator. + reference operator*() const { return PolicyTraits::element(slot_); } + + // PRECONDITION: not an end() iterator. + pointer operator->() const { return &operator*(); } + + // PRECONDITION: not an end() iterator. + iterator& operator++() { + ++ctrl_; + ++slot_; + skip_empty_or_deleted(); + return *this; + } + // PRECONDITION: not an end() iterator. + iterator operator++(int) { + auto tmp = *this; + ++*this; + return tmp; + } + + friend bool operator==(const iterator& a, const iterator& b) { + return a.ctrl_ == b.ctrl_; + } + friend bool operator!=(const iterator& a, const iterator& b) { + return !(a == b); + } + + private: + iterator(ctrl_t* ctrl) : ctrl_(ctrl) {} // for end() + iterator(ctrl_t* ctrl, slot_type* slot) : ctrl_(ctrl), slot_(slot) {} + + void skip_empty_or_deleted() { + while (IsEmptyOrDeleted(*ctrl_)) { + // ctrl is not necessarily aligned to Group::kWidth. It is also likely + // to read past the space for ctrl bytes and into slots. This is ok + // because ctrl has sizeof() == 1 and slot has sizeof() >= 1 so there + // is no way to read outside the combined slot array. + uint32_t shift = Group{ctrl_}.CountLeadingEmptyOrDeleted(); + ctrl_ += shift; + slot_ += shift; + } + } + + ctrl_t* ctrl_ = nullptr; + slot_type* slot_; + }; + + class const_iterator { + friend class raw_hash_set; + + public: + using iterator_category = typename iterator::iterator_category; + using value_type = typename raw_hash_set::value_type; + using reference = typename raw_hash_set::const_reference; + using pointer = typename raw_hash_set::const_pointer; + using difference_type = typename raw_hash_set::difference_type; + + const_iterator() {} + // Implicit construction from iterator. + const_iterator(iterator i) : inner_(std::move(i)) {} + + reference operator*() const { return *inner_; } + pointer operator->() const { return inner_.operator->(); } + + const_iterator& operator++() { + ++inner_; + return *this; + } + const_iterator operator++(int) { return inner_++; } + + friend bool operator==(const const_iterator& a, const const_iterator& b) { + return a.inner_ == b.inner_; + } + friend bool operator!=(const const_iterator& a, const const_iterator& b) { + return !(a == b); + } + + private: + const_iterator(const ctrl_t* ctrl, const slot_type* slot) + : inner_(const_cast(ctrl), const_cast(slot)) {} + + iterator inner_; + }; + + using node_type = container_internal::node_handle; + + raw_hash_set() noexcept( + std::is_nothrow_default_constructible::value&& + std::is_nothrow_default_constructible::value&& + std::is_nothrow_default_constructible::value) {} + + explicit raw_hash_set(size_t bucket_count, const hasher& hash = hasher(), + const key_equal& eq = key_equal(), + const allocator_type& alloc = allocator_type()) + : ctrl_(EmptyGroup()), settings_(0, hash, eq, alloc) { + if (bucket_count) { + capacity_ = NormalizeCapacity(bucket_count); + growth_left() = static_cast(capacity_ * kMaxLoadFactor); + initialize_slots(); + } + } + + raw_hash_set(size_t bucket_count, const hasher& hash, + const allocator_type& alloc) + : raw_hash_set(bucket_count, hash, key_equal(), alloc) {} + + raw_hash_set(size_t bucket_count, const allocator_type& alloc) + : raw_hash_set(bucket_count, hasher(), key_equal(), alloc) {} + + explicit raw_hash_set(const allocator_type& alloc) + : raw_hash_set(0, hasher(), key_equal(), alloc) {} + + template + raw_hash_set(InputIter first, InputIter last, size_t bucket_count = 0, + const hasher& hash = hasher(), const key_equal& eq = key_equal(), + const allocator_type& alloc = allocator_type()) + : raw_hash_set(bucket_count, hash, eq, alloc) { + insert(first, last); + } + + template + raw_hash_set(InputIter first, InputIter last, size_t bucket_count, + const hasher& hash, const allocator_type& alloc) + : raw_hash_set(first, last, bucket_count, hash, key_equal(), alloc) {} + + template + raw_hash_set(InputIter first, InputIter last, size_t bucket_count, + const allocator_type& alloc) + : raw_hash_set(first, last, bucket_count, hasher(), key_equal(), alloc) {} + + template + raw_hash_set(InputIter first, InputIter last, const allocator_type& alloc) + : raw_hash_set(first, last, 0, hasher(), key_equal(), alloc) {} + + // Instead of accepting std::initializer_list as the first + // argument like std::unordered_set does, we have two overloads + // that accept std::initializer_list and std::initializer_list. + // This is advantageous for performance. + // + // // Turns {"abc", "def"} into std::initializer_list, then copies + // // the strings into the set. + // std::unordered_set s = {"abc", "def"}; + // + // // Turns {"abc", "def"} into std::initializer_list, then + // // copies the strings into the set. + // absl::flat_hash_set s = {"abc", "def"}; + // + // The same trick is used in insert(). + // + // The enabler is necessary to prevent this constructor from triggering where + // the copy constructor is meant to be called. + // + // absl::flat_hash_set a, b{a}; + // + // RequiresNotInit is a workaround for gcc prior to 7.1. + template = 0, RequiresInsertable = 0> + raw_hash_set(std::initializer_list init, size_t bucket_count = 0, + const hasher& hash = hasher(), const key_equal& eq = key_equal(), + const allocator_type& alloc = allocator_type()) + : raw_hash_set(init.begin(), init.end(), bucket_count, hash, eq, alloc) {} + + raw_hash_set(std::initializer_list init, size_t bucket_count = 0, + const hasher& hash = hasher(), const key_equal& eq = key_equal(), + const allocator_type& alloc = allocator_type()) + : raw_hash_set(init.begin(), init.end(), bucket_count, hash, eq, alloc) {} + + template = 0, RequiresInsertable = 0> + raw_hash_set(std::initializer_list init, size_t bucket_count, + const hasher& hash, const allocator_type& alloc) + : raw_hash_set(init, bucket_count, hash, key_equal(), alloc) {} + + raw_hash_set(std::initializer_list init, size_t bucket_count, + const hasher& hash, const allocator_type& alloc) + : raw_hash_set(init, bucket_count, hash, key_equal(), alloc) {} + + template = 0, RequiresInsertable = 0> + raw_hash_set(std::initializer_list init, size_t bucket_count, + const allocator_type& alloc) + : raw_hash_set(init, bucket_count, hasher(), key_equal(), alloc) {} + + raw_hash_set(std::initializer_list init, size_t bucket_count, + const allocator_type& alloc) + : raw_hash_set(init, bucket_count, hasher(), key_equal(), alloc) {} + + template = 0, RequiresInsertable = 0> + raw_hash_set(std::initializer_list init, const allocator_type& alloc) + : raw_hash_set(init, 0, hasher(), key_equal(), alloc) {} + + raw_hash_set(std::initializer_list init, + const allocator_type& alloc) + : raw_hash_set(init, 0, hasher(), key_equal(), alloc) {} + + raw_hash_set(const raw_hash_set& that) + : raw_hash_set(that, AllocTraits::select_on_container_copy_construction( + that.alloc_ref())) {} + + raw_hash_set(const raw_hash_set& that, const allocator_type& a) + : raw_hash_set(0, that.hash_ref(), that.eq_ref(), a) { + reserve(that.size()); + // Because the table is guaranteed to be empty, we can do something faster + // than a full `insert`. + for (const auto& v : that) { + const size_t hash = PolicyTraits::apply(HashElement{hash_ref()}, v); + const size_t i = find_first_non_full(hash); + set_ctrl(i, H2(hash)); + emplace_at(i, v); + } + size_ = that.size(); + growth_left() -= that.size(); + } + + raw_hash_set(raw_hash_set&& that) noexcept( + std::is_nothrow_copy_constructible::value&& + std::is_nothrow_copy_constructible::value&& + std::is_nothrow_copy_constructible::value) + : ctrl_(absl::exchange(that.ctrl_, EmptyGroup())), + slots_(absl::exchange(that.slots_, nullptr)), + size_(absl::exchange(that.size_, 0)), + capacity_(absl::exchange(that.capacity_, 0)), + // Hash, equality and allocator are copied instead of moved because + // `that` must be left valid. If Hash is std::function, moving it + // would create a nullptr functor that cannot be called. + settings_(that.settings_) { + // growth_left was copied above, reset the one from `that`. + that.growth_left() = 0; + } + + raw_hash_set(raw_hash_set&& that, const allocator_type& a) + : ctrl_(EmptyGroup()), + slots_(nullptr), + size_(0), + capacity_(0), + settings_(0, that.hash_ref(), that.eq_ref(), a) { + if (a == that.alloc_ref()) { + std::swap(ctrl_, that.ctrl_); + std::swap(slots_, that.slots_); + std::swap(size_, that.size_); + std::swap(capacity_, that.capacity_); + std::swap(growth_left(), that.growth_left()); + } else { + reserve(that.size()); + // Note: this will copy elements of dense_set and unordered_set instead of + // moving them. This can be fixed if it ever becomes an issue. + for (auto& elem : that) insert(std::move(elem)); + } + } + + raw_hash_set& operator=(const raw_hash_set& that) { + raw_hash_set tmp(that, + AllocTraits::propagate_on_container_copy_assignment::value + ? that.alloc_ref() + : alloc_ref()); + swap(tmp); + return *this; + } + + raw_hash_set& operator=(raw_hash_set&& that) noexcept( + absl::allocator_traits::is_always_equal::value&& + std::is_nothrow_move_assignable::value&& + std::is_nothrow_move_assignable::value) { + // TODO(sbenza): We should only use the operations from the noexcept clause + // to make sure we actually adhere to that contract. + return move_assign( + std::move(that), + typename AllocTraits::propagate_on_container_move_assignment()); + } + + ~raw_hash_set() { destroy_slots(); } + + iterator begin() { + auto it = iterator_at(0); + it.skip_empty_or_deleted(); + return it; + } + iterator end() { return {ctrl_ + capacity_}; } + + const_iterator begin() const { + return const_cast(this)->begin(); + } + const_iterator end() const { return const_cast(this)->end(); } + const_iterator cbegin() const { return begin(); } + const_iterator cend() const { return end(); } + + bool empty() const { return !size(); } + size_t size() const { return size_; } + size_t capacity() const { return capacity_; } + size_t max_size() const { return (std::numeric_limits::max)(); } + + void clear() { + // Iterating over this container is O(bucket_count()). When bucket_count() + // is much greater than size(), iteration becomes prohibitively expensive. + // For clear() it is more important to reuse the allocated array when the + // container is small because allocation takes comparatively long time + // compared to destruction of the elements of the container. So we pick the + // largest bucket_count() threshold for which iteration is still fast and + // past that we simply deallocate the array. + if (capacity_ > 127) { + destroy_slots(); + } else if (capacity_) { + for (size_t i = 0; i != capacity_; ++i) { + if (IsFull(ctrl_[i])) { + PolicyTraits::destroy(&alloc_ref(), slots_ + i); + } + } + size_ = 0; + reset_ctrl(); + growth_left() = static_cast(capacity_ * kMaxLoadFactor); + } + assert(empty()); + } + + // This overload kicks in when the argument is an rvalue of insertable and + // decomposable type other than init_type. + // + // flat_hash_map m; + // m.insert(std::make_pair("abc", 42)); + template = 0, + typename std::enable_if::value, int>::type = 0, + T* = nullptr> + std::pair insert(T&& value) { + return emplace(std::forward(value)); + } + + // This overload kicks in when the argument is a bitfield or an lvalue of + // insertable and decomposable type. + // + // union { int n : 1; }; + // flat_hash_set s; + // s.insert(n); + // + // flat_hash_set s; + // const char* p = "hello"; + // s.insert(p); + // + // TODO(romanp): Once we stop supporting gcc 5.1 and below, replace + // RequiresInsertable with RequiresInsertable. + // We are hitting this bug: https://godbolt.org/g/1Vht4f. + template < + class T, RequiresInsertable = 0, + typename std::enable_if::value, int>::type = 0> + std::pair insert(const T& value) { + return emplace(value); + } + + // This overload kicks in when the argument is an rvalue of init_type. Its + // purpose is to handle brace-init-list arguments. + // + // flat_hash_set s; + // s.insert({"abc", 42}); + std::pair insert(init_type&& value) { + return emplace(std::move(value)); + } + + template = 0, + typename std::enable_if::value, int>::type = 0, + T* = nullptr> + iterator insert(const_iterator, T&& value) { + return insert(std::forward(value)).first; + } + + // TODO(romanp): Once we stop supporting gcc 5.1 and below, replace + // RequiresInsertable with RequiresInsertable. + // We are hitting this bug: https://godbolt.org/g/1Vht4f. + template < + class T, RequiresInsertable = 0, + typename std::enable_if::value, int>::type = 0> + iterator insert(const_iterator, const T& value) { + return insert(value).first; + } + + iterator insert(const_iterator, init_type&& value) { + return insert(std::move(value)).first; + } + + template + void insert(InputIt first, InputIt last) { + for (; first != last; ++first) insert(*first); + } + + template = 0, RequiresInsertable = 0> + void insert(std::initializer_list ilist) { + insert(ilist.begin(), ilist.end()); + } + + void insert(std::initializer_list ilist) { + insert(ilist.begin(), ilist.end()); + } + + insert_return_type insert(node_type&& node) { + if (!node) return {end(), false, node_type()}; + const auto& elem = PolicyTraits::element(node.slot()); + auto res = PolicyTraits::apply( + InsertSlot{*this, std::move(*node.slot())}, elem); + if (res.second) { + node.reset(); + return {res.first, true, node_type()}; + } else { + return {res.first, false, std::move(node)}; + } + } + + iterator insert(const_iterator, node_type&& node) { + return insert(std::move(node)).first; + } + + // This overload kicks in if we can deduce the key from args. This enables us + // to avoid constructing value_type if an entry with the same key already + // exists. + // + // For example: + // + // flat_hash_map m = {{"abc", "def"}}; + // // Creates no std::string copies and makes no heap allocations. + // m.emplace("abc", "xyz"); + template ::value, int>::type = 0> + std::pair emplace(Args&&... args) { + return PolicyTraits::apply(EmplaceDecomposable{*this}, + std::forward(args)...); + } + + // This overload kicks in if we cannot deduce the key from args. It constructs + // value_type unconditionally and then either moves it into the table or + // destroys. + template ::value, int>::type = 0> + std::pair emplace(Args&&... args) { + typename std::aligned_storage::type + raw; + slot_type* slot = reinterpret_cast(&raw); + + PolicyTraits::construct(&alloc_ref(), slot, std::forward(args)...); + const auto& elem = PolicyTraits::element(slot); + return PolicyTraits::apply(InsertSlot{*this, std::move(*slot)}, elem); + } + + template + iterator emplace_hint(const_iterator, Args&&... args) { + return emplace(std::forward(args)...).first; + } + + // Extension API: support for lazy emplace. + // + // Looks up key in the table. If found, returns the iterator to the element. + // Otherwise calls f with one argument of type raw_hash_set::constructor. f + // MUST call raw_hash_set::constructor with arguments as if a + // raw_hash_set::value_type is constructed, otherwise the behavior is + // undefined. + // + // For example: + // + // std::unordered_set s; + // // Makes ArenaStr even if "abc" is in the map. + // s.insert(ArenaString(&arena, "abc")); + // + // flat_hash_set s; + // // Makes ArenaStr only if "abc" is not in the map. + // s.lazy_emplace("abc", [&](const constructor& ctor) { + // ctor(&arena, "abc"); + // }); + // + // WARNING: This API is currently experimental. If there is a way to implement + // the same thing with the rest of the API, prefer that. + class constructor { + friend class raw_hash_set; + + public: + template + void operator()(Args&&... args) const { + assert(*slot_); + PolicyTraits::construct(alloc_, *slot_, std::forward(args)...); + *slot_ = nullptr; + } + + private: + constructor(allocator_type* a, slot_type** slot) : alloc_(a), slot_(slot) {} + + allocator_type* alloc_; + slot_type** slot_; + }; + + template + iterator lazy_emplace(const key_arg& key, F&& f) { + auto res = find_or_prepare_insert(key); + if (res.second) { + slot_type* slot = slots_ + res.first; + std::forward(f)(constructor(&alloc_ref(), &slot)); + assert(!slot); + } + return iterator_at(res.first); + } + + // Extension API: support for heterogeneous keys. + // + // std::unordered_set s; + // // Turns "abc" into std::string. + // s.erase("abc"); + // + // flat_hash_set s; + // // Uses "abc" directly without copying it into std::string. + // s.erase("abc"); + template + size_type erase(const key_arg& key) { + auto it = find(key); + if (it == end()) return 0; + erase(it); + return 1; + } + + // Erases the element pointed to by `it`. Unlike `std::unordered_set::erase`, + // this method returns void to reduce algorithmic complexity to O(1). In + // order to erase while iterating across a map, use the following idiom (which + // also works for standard containers): + // + // for (auto it = m.begin(), end = m.end(); it != end;) { + // if () { + // m.erase(it++); + // } else { + // ++it; + // } + // } + void erase(const_iterator cit) { erase(cit.inner_); } + + // This overload is necessary because otherwise erase(const K&) would be + // a better match if non-const iterator is passed as an argument. + void erase(iterator it) { + assert(it != end()); + PolicyTraits::destroy(&alloc_ref(), it.slot_); + erase_meta_only(it); + } + + iterator erase(const_iterator first, const_iterator last) { + while (first != last) { + erase(first++); + } + return last.inner_; + } + + // Moves elements from `src` into `this`. + // If the element already exists in `this`, it is left unmodified in `src`. + template + void merge(raw_hash_set& src) { // NOLINT + assert(this != &src); + for (auto it = src.begin(), e = src.end(); it != e; ++it) { + if (PolicyTraits::apply(InsertSlot{*this, std::move(*it.slot_)}, + PolicyTraits::element(it.slot_)) + .second) { + src.erase_meta_only(it); + } + } + } + + template + void merge(raw_hash_set&& src) { + merge(src); + } + + node_type extract(const_iterator position) { + node_type node(alloc_ref(), position.inner_.slot_); + erase_meta_only(position); + return node; + } + + template < + class K = key_type, + typename std::enable_if::value, int>::type = 0> + node_type extract(const key_arg& key) { + auto it = find(key); + return it == end() ? node_type() : extract(const_iterator{it}); + } + + void swap(raw_hash_set& that) noexcept( + IsNoThrowSwappable() && IsNoThrowSwappable() && + (!AllocTraits::propagate_on_container_swap::value || + IsNoThrowSwappable())) { + using std::swap; + swap(ctrl_, that.ctrl_); + swap(slots_, that.slots_); + swap(size_, that.size_); + swap(capacity_, that.capacity_); + swap(growth_left(), that.growth_left()); + swap(hash_ref(), that.hash_ref()); + swap(eq_ref(), that.eq_ref()); + if (AllocTraits::propagate_on_container_swap::value) { + swap(alloc_ref(), that.alloc_ref()); + } else { + // If the allocators do not compare equal it is officially undefined + // behavior. We choose to do nothing. + } + } + + void rehash(size_t n) { + if (n == 0 && capacity_ == 0) return; + if (n == 0 && size_ == 0) return destroy_slots(); + auto m = NormalizeCapacity(std::max(n, NumSlotsFast(size()))); + // n == 0 unconditionally rehashes as per the standard. + if (n == 0 || m > capacity_) { + resize(m); + } + } + + void reserve(size_t n) { + rehash(NumSlotsFast(n)); + } + + // Extension API: support for heterogeneous keys. + // + // std::unordered_set s; + // // Turns "abc" into std::string. + // s.count("abc"); + // + // ch_set s; + // // Uses "abc" directly without copying it into std::string. + // s.count("abc"); + template + size_t count(const key_arg& key) const { + return find(key) == end() ? 0 : 1; + } + + // Issues CPU prefetch instructions for the memory needed to find or insert + // a key. Like all lookup functions, this support heterogeneous keys. + // + // NOTE: This is a very low level operation and should not be used without + // specific benchmarks indicating its importance. + template + void prefetch(const key_arg& key) const { + (void)key; +#if defined(__GNUC__) + auto seq = probe(hash_ref()(key)); + __builtin_prefetch(static_cast(ctrl_ + seq.offset())); + __builtin_prefetch(static_cast(slots_ + seq.offset())); +#endif // __GNUC__ + } + + // The API of find() has two extensions. + // + // 1. The hash can be passed by the user. It must be equal to the hash of the + // key. + // + // 2. The type of the key argument doesn't have to be key_type. This is so + // called heterogeneous key support. + template + iterator find(const key_arg& key, size_t hash) { + auto seq = probe(hash); + while (true) { + Group g{ctrl_ + seq.offset()}; + for (int i : g.Match(H2(hash))) { + if (ABSL_PREDICT_TRUE(PolicyTraits::apply( + EqualElement{key, eq_ref()}, + PolicyTraits::element(slots_ + seq.offset(i))))) + return iterator_at(seq.offset(i)); + } + if (ABSL_PREDICT_TRUE(g.MatchEmpty())) return end(); + seq.next(); + } + } + template + iterator find(const key_arg& key) { + return find(key, hash_ref()(key)); + } + + template + const_iterator find(const key_arg& key, size_t hash) const { + return const_cast(this)->find(key, hash); + } + template + const_iterator find(const key_arg& key) const { + return find(key, hash_ref()(key)); + } + + template + bool contains(const key_arg& key) const { + return find(key) != end(); + } + + template + std::pair equal_range(const key_arg& key) { + auto it = find(key); + if (it != end()) return {it, std::next(it)}; + return {it, it}; + } + template + std::pair equal_range( + const key_arg& key) const { + auto it = find(key); + if (it != end()) return {it, std::next(it)}; + return {it, it}; + } + + size_t bucket_count() const { return capacity_; } + float load_factor() const { + return capacity_ ? static_cast(size()) / capacity_ : 0.0; + } + float max_load_factor() const { return 1.0f; } + void max_load_factor(float) { + // Does nothing. + } + + hasher hash_function() const { return hash_ref(); } + key_equal key_eq() const { return eq_ref(); } + allocator_type get_allocator() const { return alloc_ref(); } + + friend bool operator==(const raw_hash_set& a, const raw_hash_set& b) { + if (a.size() != b.size()) return false; + const raw_hash_set* outer = &a; + const raw_hash_set* inner = &b; + if (outer->capacity() > inner->capacity()) std::swap(outer, inner); + for (const value_type& elem : *outer) + if (!inner->has_element(elem)) return false; + return true; + } + + friend bool operator!=(const raw_hash_set& a, const raw_hash_set& b) { + return !(a == b); + } + + friend void swap(raw_hash_set& a, + raw_hash_set& b) noexcept(noexcept(a.swap(b))) { + a.swap(b); + } + + private: + template + friend struct absl::container_internal::hashtable_debug_internal:: + HashtableDebugAccess; + + struct FindElement { + template + const_iterator operator()(const K& key, Args&&...) const { + return s.find(key); + } + const raw_hash_set& s; + }; + + struct HashElement { + template + size_t operator()(const K& key, Args&&...) const { + return h(key); + } + const hasher& h; + }; + + template + struct EqualElement { + template + bool operator()(const K2& lhs, Args&&...) const { + return eq(lhs, rhs); + } + const K1& rhs; + const key_equal& eq; + }; + + struct EmplaceDecomposable { + template + std::pair operator()(const K& key, Args&&... args) const { + auto res = s.find_or_prepare_insert(key); + if (res.second) { + s.emplace_at(res.first, std::forward(args)...); + } + return {s.iterator_at(res.first), res.second}; + } + raw_hash_set& s; + }; + + template + struct InsertSlot { + template + std::pair operator()(const K& key, Args&&...) && { + auto res = s.find_or_prepare_insert(key); + if (res.second) { + PolicyTraits::transfer(&s.alloc_ref(), s.slots_ + res.first, &slot); + } else if (do_destroy) { + PolicyTraits::destroy(&s.alloc_ref(), &slot); + } + return {s.iterator_at(res.first), res.second}; + } + raw_hash_set& s; + // Constructed slot. Either moved into place or destroyed. + slot_type&& slot; + }; + + // Computes std::ceil(n / kMaxLoadFactor). Faster than calling std::ceil. + static inline size_t NumSlotsFast(size_t n) { + return static_cast( + (n * kMaxLoadFactorDenominator + (kMaxLoadFactorNumerator - 1)) / + kMaxLoadFactorNumerator); + } + + // "erases" the object from the container, except that it doesn't actually + // destroy the object. It only updates all the metadata of the class. + // This can be used in conjunction with Policy::transfer to move the object to + // another place. + void erase_meta_only(const_iterator it) { + assert(IsFull(*it.inner_.ctrl_) && "erasing a dangling iterator"); + --size_; + const size_t index = it.inner_.ctrl_ - ctrl_; + const size_t index_before = (index - Group::kWidth) & capacity_; + const auto empty_after = Group(it.inner_.ctrl_).MatchEmpty(); + const auto empty_before = Group(ctrl_ + index_before).MatchEmpty(); + + // We count how many consecutive non empties we have to the right and to the + // left of `it`. If the sum is >= kWidth then there is at least one probe + // window that might have seen a full group. + bool was_never_full = + empty_before && empty_after && + static_cast(empty_after.TrailingZeros() + + empty_before.LeadingZeros()) < Group::kWidth; + + set_ctrl(index, was_never_full ? kEmpty : kDeleted); + growth_left() += was_never_full; + } + + void initialize_slots() { + assert(capacity_); + auto layout = MakeLayout(capacity_); + char* mem = static_cast( + Allocate(&alloc_ref(), layout.AllocSize())); + ctrl_ = reinterpret_cast(layout.template Pointer<0>(mem)); + slots_ = layout.template Pointer<1>(mem); + reset_ctrl(); + growth_left() = static_cast(capacity_ * kMaxLoadFactor) - size_; + } + + void destroy_slots() { + if (!capacity_) return; + for (size_t i = 0; i != capacity_; ++i) { + if (IsFull(ctrl_[i])) { + PolicyTraits::destroy(&alloc_ref(), slots_ + i); + } + } + auto layout = MakeLayout(capacity_); + // Unpoison before returning the memory to the allocator. + SanitizerUnpoisonMemoryRegion(slots_, sizeof(slot_type) * capacity_); + Deallocate(&alloc_ref(), ctrl_, layout.AllocSize()); + ctrl_ = EmptyGroup(); + slots_ = nullptr; + size_ = 0; + capacity_ = 0; + growth_left() = 0; + } + + void resize(size_t new_capacity) { + assert(IsValidCapacity(new_capacity)); + auto* old_ctrl = ctrl_; + auto* old_slots = slots_; + const size_t old_capacity = capacity_; + capacity_ = new_capacity; + initialize_slots(); + + for (size_t i = 0; i != old_capacity; ++i) { + if (IsFull(old_ctrl[i])) { + size_t hash = PolicyTraits::apply(HashElement{hash_ref()}, + PolicyTraits::element(old_slots + i)); + size_t new_i = find_first_non_full(hash); + set_ctrl(new_i, H2(hash)); + PolicyTraits::transfer(&alloc_ref(), slots_ + new_i, old_slots + i); + } + } + if (old_capacity) { + SanitizerUnpoisonMemoryRegion(old_slots, + sizeof(slot_type) * old_capacity); + auto layout = MakeLayout(old_capacity); + Deallocate(&alloc_ref(), old_ctrl, + layout.AllocSize()); + } + } + + void drop_deletes_without_resize() ABSL_ATTRIBUTE_NOINLINE { + assert(IsValidCapacity(capacity_)); + // Algorithm: + // - mark all DELETED slots as EMPTY + // - mark all FULL slots as DELETED + // - for each slot marked as DELETED + // hash = Hash(element) + // target = find_first_non_full(hash) + // if target is in the same group + // mark slot as FULL + // else if target is EMPTY + // transfer element to target + // mark slot as EMPTY + // mark target as FULL + // else if target is DELETED + // swap current element with target element + // mark target as FULL + // repeat procedure for current slot with moved from element (target) + ConvertDeletedToEmptyAndFullToDeleted(ctrl_, capacity_); + typename std::aligned_storage::type + raw; + slot_type* slot = reinterpret_cast(&raw); + for (size_t i = 0; i != capacity_; ++i) { + if (!IsDeleted(ctrl_[i])) continue; + size_t hash = PolicyTraits::apply(HashElement{hash_ref()}, + PolicyTraits::element(slots_ + i)); + size_t new_i = find_first_non_full(hash); + + // Verify if the old and new i fall within the same group wrt the hash. + // If they do, we don't need to move the object as it falls already in the + // best probe we can. + const auto probe_index = [&](size_t pos) { + return ((pos - probe(hash).offset()) & capacity_) / Group::kWidth; + }; + + // Element doesn't move. + if (ABSL_PREDICT_TRUE(probe_index(new_i) == probe_index(i))) { + set_ctrl(i, H2(hash)); + continue; + } + if (IsEmpty(ctrl_[new_i])) { + // Transfer element to the empty spot. + // set_ctrl poisons/unpoisons the slots so we have to call it at the + // right time. + set_ctrl(new_i, H2(hash)); + PolicyTraits::transfer(&alloc_ref(), slots_ + new_i, slots_ + i); + set_ctrl(i, kEmpty); + } else { + assert(IsDeleted(ctrl_[new_i])); + set_ctrl(new_i, H2(hash)); + // Until we are done rehashing, DELETED marks previously FULL slots. + // Swap i and new_i elements. + PolicyTraits::transfer(&alloc_ref(), slot, slots_ + i); + PolicyTraits::transfer(&alloc_ref(), slots_ + i, slots_ + new_i); + PolicyTraits::transfer(&alloc_ref(), slots_ + new_i, slot); + --i; // repeat + } + } + growth_left() = static_cast(capacity_ * kMaxLoadFactor) - size_; + } + + void rehash_and_grow_if_necessary() { + if (capacity_ == 0) { + resize(Group::kWidth - 1); + } else if (size() <= kMaxLoadFactor / 2 * capacity_) { + // Squash DELETED without growing if there is enough capacity. + drop_deletes_without_resize(); + } else { + // Otherwise grow the container. + resize(capacity_ * 2 + 1); + } + } + + bool has_element(const value_type& elem) const { + size_t hash = PolicyTraits::apply(HashElement{hash_ref()}, elem); + auto seq = probe(hash); + while (true) { + Group g{ctrl_ + seq.offset()}; + for (int i : g.Match(H2(hash))) { + if (ABSL_PREDICT_TRUE(PolicyTraits::element(slots_ + seq.offset(i)) == + elem)) + return true; + } + if (ABSL_PREDICT_TRUE(g.MatchEmpty())) return false; + seq.next(); + assert(seq.index() < capacity_ && "full table!"); + } + return false; + } + + // Probes the raw_hash_set with the probe sequence for hash and returns the + // pointer to the first empty or deleted slot. + // NOTE: this function must work with tables having both kEmpty and kDelete + // in one group. Such tables appears during drop_deletes_without_resize. + // + // This function is very useful when insertions happen and: + // - the input is already a set + // - there are enough slots + // - the element with the hash is not in the table + size_t find_first_non_full(size_t hash) { + auto seq = probe(hash); + while (true) { + Group g{ctrl_ + seq.offset()}; + auto mask = g.MatchEmptyOrDeleted(); + if (mask) { +#if !defined(NDEBUG) + // We want to force small tables to have random entries too, so + // in debug build we will randomly insert in either the front or back of + // the group. + // TODO(kfm,sbenza): revisit after we do unconditional mixing + if (ShouldInsertBackwards(hash, ctrl_)) + return seq.offset(mask.HighestBitSet()); + else + return seq.offset(mask.LowestBitSet()); +#else + return seq.offset(mask.LowestBitSet()); +#endif + } + assert(seq.index() < capacity_ && "full table!"); + seq.next(); + } + } + + // TODO(alkis): Optimize this assuming *this and that don't overlap. + raw_hash_set& move_assign(raw_hash_set&& that, std::true_type) { + raw_hash_set tmp(std::move(that)); + swap(tmp); + return *this; + } + raw_hash_set& move_assign(raw_hash_set&& that, std::false_type) { + raw_hash_set tmp(std::move(that), alloc_ref()); + swap(tmp); + return *this; + } + + protected: + template + std::pair find_or_prepare_insert(const K& key) { + auto hash = hash_ref()(key); + auto seq = probe(hash); + while (true) { + Group g{ctrl_ + seq.offset()}; + for (int i : g.Match(H2(hash))) { + if (ABSL_PREDICT_TRUE(PolicyTraits::apply( + EqualElement{key, eq_ref()}, + PolicyTraits::element(slots_ + seq.offset(i))))) + return {seq.offset(i), false}; + } + if (ABSL_PREDICT_TRUE(g.MatchEmpty())) break; + seq.next(); + } + return {prepare_insert(hash), true}; + } + + size_t prepare_insert(size_t hash) ABSL_ATTRIBUTE_NOINLINE { + size_t target = find_first_non_full(hash); + if (ABSL_PREDICT_FALSE(growth_left() == 0 && !IsDeleted(ctrl_[target]))) { + rehash_and_grow_if_necessary(); + target = find_first_non_full(hash); + } + ++size_; + growth_left() -= IsEmpty(ctrl_[target]); + set_ctrl(target, H2(hash)); + return target; + } + + // Constructs the value in the space pointed by the iterator. This only works + // after an unsuccessful find_or_prepare_insert() and before any other + // modifications happen in the raw_hash_set. + // + // PRECONDITION: i is an index returned from find_or_prepare_insert(k), where + // k is the key decomposed from `forward(args)...`, and the bool + // returned by find_or_prepare_insert(k) was true. + // POSTCONDITION: *m.iterator_at(i) == value_type(forward(args)...). + template + void emplace_at(size_t i, Args&&... args) { + PolicyTraits::construct(&alloc_ref(), slots_ + i, + std::forward(args)...); + + assert(PolicyTraits::apply(FindElement{*this}, *iterator_at(i)) == + iterator_at(i) && + "constructed value does not match the lookup key"); + } + + iterator iterator_at(size_t i) { return {ctrl_ + i, slots_ + i}; } + const_iterator iterator_at(size_t i) const { return {ctrl_ + i, slots_ + i}; } + + private: + friend struct RawHashSetTestOnlyAccess; + + probe_seq probe(size_t hash) const { + return probe_seq(H1(hash, ctrl_), capacity_); + } + + // Reset all ctrl bytes back to kEmpty, except the sentinel. + void reset_ctrl() { + std::memset(ctrl_, kEmpty, capacity_ + Group::kWidth); + ctrl_[capacity_] = kSentinel; + SanitizerPoisonMemoryRegion(slots_, sizeof(slot_type) * capacity_); + } + + // Sets the control byte, and if `i < Group::kWidth`, set the cloned byte at + // the end too. + void set_ctrl(size_t i, ctrl_t h) { + assert(i < capacity_); + + if (IsFull(h)) { + SanitizerUnpoisonObject(slots_ + i); + } else { + SanitizerPoisonObject(slots_ + i); + } + + ctrl_[i] = h; + ctrl_[((i - Group::kWidth) & capacity_) + Group::kWidth] = h; + } + + size_t& growth_left() { return settings_.template get<0>(); } + + hasher& hash_ref() { return settings_.template get<1>(); } + const hasher& hash_ref() const { return settings_.template get<1>(); } + key_equal& eq_ref() { return settings_.template get<2>(); } + const key_equal& eq_ref() const { return settings_.template get<2>(); } + allocator_type& alloc_ref() { return settings_.template get<3>(); } + const allocator_type& alloc_ref() const { + return settings_.template get<3>(); + } + + // On average each group has 2 empty slot (for the vectorized case). + static constexpr int64_t kMaxLoadFactorNumerator = 14; + static constexpr int64_t kMaxLoadFactorDenominator = 16; + static constexpr float kMaxLoadFactor = + 1.0 * kMaxLoadFactorNumerator / kMaxLoadFactorDenominator; + + // TODO(alkis): Investigate removing some of these fields: + // - ctrl/slots can be derived from each other + // - size can be moved into the slot array + ctrl_t* ctrl_ = EmptyGroup(); // [(capacity + 1) * ctrl_t] + slot_type* slots_ = nullptr; // [capacity * slot_type] + size_t size_ = 0; // number of full slots + size_t capacity_ = 0; // total number of slots + absl::container_internal::CompressedTuple + settings_{0, hasher{}, key_equal{}, allocator_type{}}; +}; + +namespace hashtable_debug_internal { +template +struct HashtableDebugAccess> { + using Traits = typename Set::PolicyTraits; + using Slot = typename Traits::slot_type; + + static size_t GetNumProbes(const Set& set, + const typename Set::key_type& key) { + size_t num_probes = 0; + size_t hash = set.hash_ref()(key); + auto seq = set.probe(hash); + while (true) { + container_internal::Group g{set.ctrl_ + seq.offset()}; + for (int i : g.Match(container_internal::H2(hash))) { + if (Traits::apply( + typename Set::template EqualElement{ + key, set.eq_ref()}, + Traits::element(set.slots_ + seq.offset(i)))) + return num_probes; + ++num_probes; + } + if (g.MatchEmpty()) return num_probes; + seq.next(); + ++num_probes; + } + } + + static size_t AllocatedByteSize(const Set& c) { + size_t capacity = c.capacity_; + if (capacity == 0) return 0; + auto layout = Set::MakeLayout(capacity); + size_t m = layout.AllocSize(); + + size_t per_slot = Traits::space_used(static_cast(nullptr)); + if (per_slot != ~size_t{}) { + m += per_slot * c.size(); + } else { + for (size_t i = 0; i != capacity; ++i) { + if (container_internal::IsFull(c.ctrl_[i])) { + m += Traits::space_used(c.slots_ + i); + } + } + } + return m; + } + + static size_t LowerBoundAllocatedByteSize(size_t size) { + size_t capacity = container_internal::NormalizeCapacity( + std::ceil(size / Set::kMaxLoadFactor)); + if (capacity == 0) return 0; + auto layout = Set::MakeLayout(capacity); + size_t m = layout.AllocSize(); + size_t per_slot = Traits::space_used(static_cast(nullptr)); + if (per_slot != ~size_t{}) { + m += per_slot * size; + } + return m; + } +}; + +} // namespace hashtable_debug_internal +} // namespace container_internal +} // namespace absl + +#endif // ABSL_CONTAINER_INTERNAL_RAW_HASH_SET_H_ diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/internal/raw_hash_set_allocator_test.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/internal/raw_hash_set_allocator_test.cc new file mode 100644 index 0000000..891fa45 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/internal/raw_hash_set_allocator_test.cc @@ -0,0 +1,428 @@ +// Copyright 2018 The Abseil Authors. +// +// 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 +#include + +#include "gtest/gtest.h" +#include "absl/container/internal/raw_hash_set.h" +#include "absl/container/internal/tracked.h" + +namespace absl { +namespace container_internal { +namespace { + +enum AllocSpec { + kPropagateOnCopy = 1, + kPropagateOnMove = 2, + kPropagateOnSwap = 4, +}; + +struct AllocState { + size_t num_allocs = 0; + std::set owned; +}; + +template +class CheckedAlloc { + public: + template + friend class CheckedAlloc; + + using value_type = T; + + CheckedAlloc() {} + explicit CheckedAlloc(size_t id) : id_(id) {} + CheckedAlloc(const CheckedAlloc&) = default; + CheckedAlloc& operator=(const CheckedAlloc&) = default; + + template + CheckedAlloc(const CheckedAlloc& that) + : id_(that.id_), state_(that.state_) {} + + template + struct rebind { + using other = CheckedAlloc; + }; + + using propagate_on_container_copy_assignment = + std::integral_constant; + + using propagate_on_container_move_assignment = + std::integral_constant; + + using propagate_on_container_swap = + std::integral_constant; + + CheckedAlloc select_on_container_copy_construction() const { + if (Spec & kPropagateOnCopy) return *this; + return {}; + } + + T* allocate(size_t n) { + T* ptr = std::allocator().allocate(n); + track_alloc(ptr); + return ptr; + } + void deallocate(T* ptr, size_t n) { + memset(ptr, 0, n * sizeof(T)); // The freed memory must be unpoisoned. + track_dealloc(ptr); + return std::allocator().deallocate(ptr, n); + } + + friend bool operator==(const CheckedAlloc& a, const CheckedAlloc& b) { + return a.id_ == b.id_; + } + friend bool operator!=(const CheckedAlloc& a, const CheckedAlloc& b) { + return !(a == b); + } + + size_t num_allocs() const { return state_->num_allocs; } + + void swap(CheckedAlloc& that) { + using std::swap; + swap(id_, that.id_); + swap(state_, that.state_); + } + + friend void swap(CheckedAlloc& a, CheckedAlloc& b) { a.swap(b); } + + friend std::ostream& operator<<(std::ostream& o, const CheckedAlloc& a) { + return o << "alloc(" << a.id_ << ")"; + } + + private: + void track_alloc(void* ptr) { + AllocState* state = state_.get(); + ++state->num_allocs; + if (!state->owned.insert(ptr).second) + ADD_FAILURE() << *this << " got previously allocated memory: " << ptr; + } + void track_dealloc(void* ptr) { + if (state_->owned.erase(ptr) != 1) + ADD_FAILURE() << *this + << " deleting memory owned by another allocator: " << ptr; + } + + size_t id_ = std::numeric_limits::max(); + + std::shared_ptr state_ = std::make_shared(); +}; + +struct Identity { + int32_t operator()(int32_t v) const { return v; } +}; + +struct Policy { + using slot_type = Tracked; + using init_type = Tracked; + using key_type = int32_t; + + template + static void construct(allocator_type* alloc, slot_type* slot, + Args&&... args) { + std::allocator_traits::construct( + *alloc, slot, std::forward(args)...); + } + + template + static void destroy(allocator_type* alloc, slot_type* slot) { + std::allocator_traits::destroy(*alloc, slot); + } + + template + static void transfer(allocator_type* alloc, slot_type* new_slot, + slot_type* old_slot) { + construct(alloc, new_slot, std::move(*old_slot)); + destroy(alloc, old_slot); + } + + template + static auto apply(F&& f, int32_t v) -> decltype(std::forward(f)(v, v)) { + return std::forward(f)(v, v); + } + + template + static auto apply(F&& f, const slot_type& v) + -> decltype(std::forward(f)(v.val(), v)) { + return std::forward(f)(v.val(), v); + } + + template + static auto apply(F&& f, slot_type&& v) + -> decltype(std::forward(f)(v.val(), std::move(v))) { + return std::forward(f)(v.val(), std::move(v)); + } + + static slot_type& element(slot_type* slot) { return *slot; } +}; + +template +struct PropagateTest : public ::testing::Test { + using Alloc = CheckedAlloc, Spec>; + + using Table = raw_hash_set, Alloc>; + + PropagateTest() { + EXPECT_EQ(a1, t1.get_allocator()); + EXPECT_NE(a2, t1.get_allocator()); + } + + Alloc a1 = Alloc(1); + Table t1 = Table(0, a1); + Alloc a2 = Alloc(2); +}; + +using PropagateOnAll = + PropagateTest; +using NoPropagateOnCopy = PropagateTest; +using NoPropagateOnMove = PropagateTest; + +TEST_F(PropagateOnAll, Empty) { EXPECT_EQ(0, a1.num_allocs()); } + +TEST_F(PropagateOnAll, InsertAllocates) { + auto it = t1.insert(0).first; + EXPECT_EQ(1, a1.num_allocs()); + EXPECT_EQ(0, it->num_moves()); + EXPECT_EQ(0, it->num_copies()); +} + +TEST_F(PropagateOnAll, InsertDecomposes) { + auto it = t1.insert(0).first; + EXPECT_EQ(1, a1.num_allocs()); + EXPECT_EQ(0, it->num_moves()); + EXPECT_EQ(0, it->num_copies()); + + EXPECT_FALSE(t1.insert(0).second); + EXPECT_EQ(1, a1.num_allocs()); + EXPECT_EQ(0, it->num_moves()); + EXPECT_EQ(0, it->num_copies()); +} + +TEST_F(PropagateOnAll, RehashMoves) { + auto it = t1.insert(0).first; + EXPECT_EQ(0, it->num_moves()); + t1.rehash(2 * t1.capacity()); + EXPECT_EQ(2, a1.num_allocs()); + it = t1.find(0); + EXPECT_EQ(1, it->num_moves()); + EXPECT_EQ(0, it->num_copies()); +} + +TEST_F(PropagateOnAll, CopyConstructor) { + auto it = t1.insert(0).first; + Table u(t1); + EXPECT_EQ(2, a1.num_allocs()); + EXPECT_EQ(0, it->num_moves()); + EXPECT_EQ(1, it->num_copies()); +} + +TEST_F(NoPropagateOnCopy, CopyConstructor) { + auto it = t1.insert(0).first; + Table u(t1); + EXPECT_EQ(1, a1.num_allocs()); + EXPECT_EQ(1, u.get_allocator().num_allocs()); + EXPECT_EQ(0, it->num_moves()); + EXPECT_EQ(1, it->num_copies()); +} + +TEST_F(PropagateOnAll, CopyConstructorWithSameAlloc) { + auto it = t1.insert(0).first; + Table u(t1, a1); + EXPECT_EQ(2, a1.num_allocs()); + EXPECT_EQ(0, it->num_moves()); + EXPECT_EQ(1, it->num_copies()); +} + +TEST_F(NoPropagateOnCopy, CopyConstructorWithSameAlloc) { + auto it = t1.insert(0).first; + Table u(t1, a1); + EXPECT_EQ(2, a1.num_allocs()); + EXPECT_EQ(0, it->num_moves()); + EXPECT_EQ(1, it->num_copies()); +} + +TEST_F(PropagateOnAll, CopyConstructorWithDifferentAlloc) { + auto it = t1.insert(0).first; + Table u(t1, a2); + EXPECT_EQ(a2, u.get_allocator()); + EXPECT_EQ(1, a1.num_allocs()); + EXPECT_EQ(1, a2.num_allocs()); + EXPECT_EQ(0, it->num_moves()); + EXPECT_EQ(1, it->num_copies()); +} + +TEST_F(NoPropagateOnCopy, CopyConstructorWithDifferentAlloc) { + auto it = t1.insert(0).first; + Table u(t1, a2); + EXPECT_EQ(a2, u.get_allocator()); + EXPECT_EQ(1, a1.num_allocs()); + EXPECT_EQ(1, a2.num_allocs()); + EXPECT_EQ(0, it->num_moves()); + EXPECT_EQ(1, it->num_copies()); +} + +TEST_F(PropagateOnAll, MoveConstructor) { + auto it = t1.insert(0).first; + Table u(std::move(t1)); + EXPECT_EQ(1, a1.num_allocs()); + EXPECT_EQ(0, it->num_moves()); + EXPECT_EQ(0, it->num_copies()); +} + +TEST_F(NoPropagateOnMove, MoveConstructor) { + auto it = t1.insert(0).first; + Table u(std::move(t1)); + EXPECT_EQ(1, a1.num_allocs()); + EXPECT_EQ(0, it->num_moves()); + EXPECT_EQ(0, it->num_copies()); +} + +TEST_F(PropagateOnAll, MoveConstructorWithSameAlloc) { + auto it = t1.insert(0).first; + Table u(std::move(t1), a1); + EXPECT_EQ(1, a1.num_allocs()); + EXPECT_EQ(0, it->num_moves()); + EXPECT_EQ(0, it->num_copies()); +} + +TEST_F(NoPropagateOnMove, MoveConstructorWithSameAlloc) { + auto it = t1.insert(0).first; + Table u(std::move(t1), a1); + EXPECT_EQ(1, a1.num_allocs()); + EXPECT_EQ(0, it->num_moves()); + EXPECT_EQ(0, it->num_copies()); +} + +TEST_F(PropagateOnAll, MoveConstructorWithDifferentAlloc) { + auto it = t1.insert(0).first; + Table u(std::move(t1), a2); + it = u.find(0); + EXPECT_EQ(a2, u.get_allocator()); + EXPECT_EQ(1, a1.num_allocs()); + EXPECT_EQ(1, a2.num_allocs()); + EXPECT_EQ(1, it->num_moves()); + EXPECT_EQ(0, it->num_copies()); +} + +TEST_F(NoPropagateOnMove, MoveConstructorWithDifferentAlloc) { + auto it = t1.insert(0).first; + Table u(std::move(t1), a2); + it = u.find(0); + EXPECT_EQ(a2, u.get_allocator()); + EXPECT_EQ(1, a1.num_allocs()); + EXPECT_EQ(1, a2.num_allocs()); + EXPECT_EQ(1, it->num_moves()); + EXPECT_EQ(0, it->num_copies()); +} + +TEST_F(PropagateOnAll, CopyAssignmentWithSameAlloc) { + auto it = t1.insert(0).first; + Table u(0, a1); + u = t1; + EXPECT_EQ(2, a1.num_allocs()); + EXPECT_EQ(0, it->num_moves()); + EXPECT_EQ(1, it->num_copies()); +} + +TEST_F(NoPropagateOnCopy, CopyAssignmentWithSameAlloc) { + auto it = t1.insert(0).first; + Table u(0, a1); + u = t1; + EXPECT_EQ(2, a1.num_allocs()); + EXPECT_EQ(0, it->num_moves()); + EXPECT_EQ(1, it->num_copies()); +} + +TEST_F(PropagateOnAll, CopyAssignmentWithDifferentAlloc) { + auto it = t1.insert(0).first; + Table u(0, a2); + u = t1; + EXPECT_EQ(a1, u.get_allocator()); + EXPECT_EQ(2, a1.num_allocs()); + EXPECT_EQ(0, a2.num_allocs()); + EXPECT_EQ(0, it->num_moves()); + EXPECT_EQ(1, it->num_copies()); +} + +TEST_F(NoPropagateOnCopy, CopyAssignmentWithDifferentAlloc) { + auto it = t1.insert(0).first; + Table u(0, a2); + u = t1; + EXPECT_EQ(a2, u.get_allocator()); + EXPECT_EQ(1, a1.num_allocs()); + EXPECT_EQ(1, a2.num_allocs()); + EXPECT_EQ(0, it->num_moves()); + EXPECT_EQ(1, it->num_copies()); +} + +TEST_F(PropagateOnAll, MoveAssignmentWithSameAlloc) { + auto it = t1.insert(0).first; + Table u(0, a1); + u = std::move(t1); + EXPECT_EQ(a1, u.get_allocator()); + EXPECT_EQ(1, a1.num_allocs()); + EXPECT_EQ(0, it->num_moves()); + EXPECT_EQ(0, it->num_copies()); +} + +TEST_F(NoPropagateOnMove, MoveAssignmentWithSameAlloc) { + auto it = t1.insert(0).first; + Table u(0, a1); + u = std::move(t1); + EXPECT_EQ(a1, u.get_allocator()); + EXPECT_EQ(1, a1.num_allocs()); + EXPECT_EQ(0, it->num_moves()); + EXPECT_EQ(0, it->num_copies()); +} + +TEST_F(PropagateOnAll, MoveAssignmentWithDifferentAlloc) { + auto it = t1.insert(0).first; + Table u(0, a2); + u = std::move(t1); + EXPECT_EQ(a1, u.get_allocator()); + EXPECT_EQ(1, a1.num_allocs()); + EXPECT_EQ(0, a2.num_allocs()); + EXPECT_EQ(0, it->num_moves()); + EXPECT_EQ(0, it->num_copies()); +} + +TEST_F(NoPropagateOnMove, MoveAssignmentWithDifferentAlloc) { + auto it = t1.insert(0).first; + Table u(0, a2); + u = std::move(t1); + it = u.find(0); + EXPECT_EQ(a2, u.get_allocator()); + EXPECT_EQ(1, a1.num_allocs()); + EXPECT_EQ(1, a2.num_allocs()); + EXPECT_EQ(1, it->num_moves()); + EXPECT_EQ(0, it->num_copies()); +} + +TEST_F(PropagateOnAll, Swap) { + auto it = t1.insert(0).first; + Table u(0, a2); + u.swap(t1); + EXPECT_EQ(a1, u.get_allocator()); + EXPECT_EQ(a2, t1.get_allocator()); + EXPECT_EQ(1, a1.num_allocs()); + EXPECT_EQ(0, a2.num_allocs()); + EXPECT_EQ(0, it->num_moves()); + EXPECT_EQ(0, it->num_copies()); +} + +} // namespace +} // namespace container_internal +} // namespace absl diff --git a/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/internal/raw_hash_set_test.cc b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/internal/raw_hash_set_test.cc new file mode 100644 index 0000000..9d92e15 --- /dev/null +++ b/FoodApp/Pods/FirebaseFirestore/Firestore/third_party/abseil-cpp/absl/container/internal/raw_hash_set_test.cc @@ -0,0 +1,1965 @@ +// Copyright 2018 The Abseil Authors. +// +// 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 "absl/container/internal/raw_hash_set.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gmock/gmock.h" +#include "gtest/gtest.h" +#include "absl/base/attributes.h" +#include "absl/base/internal/cycleclock.h" +#include "absl/base/internal/raw_logging.h" +#include "absl/container/internal/container_memory.h" +#include "absl/container/internal/hash_function_defaults.h" +#include "absl/container/internal/hash_policy_testing.h" +#include "absl/container/internal/hashtable_debug.h" +#include "absl/strings/string_view.h" + +namespace absl { +namespace container_internal { + +struct RawHashSetTestOnlyAccess { + template + static auto GetSlots(const C& c) -> decltype(c.slots_) { + return c.slots_; + } +}; + +namespace { + +using ::testing::DoubleNear; +using ::testing::ElementsAre; +using ::testing::Optional; +using ::testing::Pair; +using ::testing::UnorderedElementsAre; + +TEST(Util, NormalizeCapacity) { + constexpr size_t kMinCapacity = Group::kWidth - 1; + EXPECT_EQ(kMinCapacity, NormalizeCapacity(0)); + EXPECT_EQ(kMinCapacity, NormalizeCapacity(1)); + EXPECT_EQ(kMinCapacity, NormalizeCapacity(2)); + EXPECT_EQ(kMinCapacity, NormalizeCapacity(kMinCapacity)); + EXPECT_EQ(kMinCapacity * 2 + 1, NormalizeCapacity(kMinCapacity + 1)); + EXPECT_EQ(kMinCapacity * 2 + 1, NormalizeCapacity(kMinCapacity + 2)); +} + +TEST(Util, probe_seq) { + probe_seq<16> seq(0, 127); + auto gen = [&]() { + size_t res = seq.offset(); + seq.next(); + return res; + }; + std::vector offsets(8); + std::generate_n(offsets.begin(), 8, gen); + EXPECT_THAT(offsets, ElementsAre(0, 16, 48, 96, 32, 112, 80, 64)); + seq = probe_seq<16>(128, 127); + std::generate_n(offsets.begin(), 8, gen); + EXPECT_THAT(offsets, ElementsAre(0, 16, 48, 96, 32, 112, 80, 64)); +} + +TEST(BitMask, Smoke) { + EXPECT_FALSE((BitMask(0))); + EXPECT_TRUE((BitMask(5))); + + EXPECT_THAT((BitMask(0)), ElementsAre()); + EXPECT_THAT((BitMask(0x1)), ElementsAre(0)); + EXPECT_THAT((BitMask(0x2)), ElementsAre(1)); + EXPECT_THAT((BitMask(0x3)), ElementsAre(0, 1)); + EXPECT_THAT((BitMask(0x4)), ElementsAre(2)); + EXPECT_THAT((BitMask(0x5)), ElementsAre(0, 2)); + EXPECT_THAT((BitMask(0x55)), ElementsAre(0, 2, 4, 6)); + EXPECT_THAT((BitMask(0xAA)), ElementsAre(1, 3, 5, 7)); +} + +TEST(BitMask, WithShift) { + // See the non-SSE version of Group for details on what this math is for. + uint64_t ctrl = 0x1716151413121110; + uint64_t hash = 0x12; + constexpr uint64_t msbs = 0x8080808080808080ULL; + constexpr uint64_t lsbs = 0x0101010101010101ULL; + auto x = ctrl ^ (lsbs * hash); + uint64_t mask = (x - lsbs) & ~x & msbs; + EXPECT_EQ(0x0000000080800000, mask); + + BitMask b(mask); + EXPECT_EQ(*b, 2); +} + +TEST(BitMask, LeadingTrailing) { + EXPECT_EQ((BitMask(0b0001101001000000).LeadingZeros()), 3); + EXPECT_EQ((BitMask(0b0001101001000000).TrailingZeros()), 6); + + EXPECT_EQ((BitMask(0b0000000000000001).LeadingZeros()), 15); + EXPECT_EQ((BitMask(0b0000000000000001).TrailingZeros()), 0); + + EXPECT_EQ((BitMask(0b1000000000000000).LeadingZeros()), 0); + EXPECT_EQ((BitMask(0b1000000000000000).TrailingZeros()), 15); + + EXPECT_EQ((BitMask(0x0000008080808000).LeadingZeros()), 3); + EXPECT_EQ((BitMask(0x0000008080808000).TrailingZeros()), 1); + + EXPECT_EQ((BitMask(0x0000000000000080).LeadingZeros()), 7); + EXPECT_EQ((BitMask(0x0000000000000080).TrailingZeros()), 0); + + EXPECT_EQ((BitMask(0x8000000000000000).LeadingZeros()), 0); + EXPECT_EQ((BitMask(0x8000000000000000).TrailingZeros()), 7); +} + +TEST(Group, EmptyGroup) { + for (h2_t h = 0; h != 128; ++h) EXPECT_FALSE(Group{EmptyGroup()}.Match(h)); +} + +TEST(Group, Match) { + if (Group::kWidth == 16) { + ctrl_t group[] = {kEmpty, 1, kDeleted, 3, kEmpty, 5, kSentinel, 7, + 7, 5, 3, 1, 1, 1, 1, 1}; + EXPECT_THAT(Group{group}.Match(0), ElementsAre()); + EXPECT_THAT(Group{group}.Match(1), ElementsAre(1, 11, 12, 13, 14, 15)); + EXPECT_THAT(Group{group}.Match(3), ElementsAre(3, 10)); + EXPECT_THAT(Group{group}.Match(5), ElementsAre(5, 9)); + EXPECT_THAT(Group{group}.Match(7), ElementsAre(7, 8)); + } else if (Group::kWidth == 8) { + ctrl_t group[] = {kEmpty, 1, 2, kDeleted, 2, 1, kSentinel, 1}; + EXPECT_THAT(Group{group}.Match(0), ElementsAre()); + EXPECT_THAT(Group{group}.Match(1), ElementsAre(1, 5, 7)); + EXPECT_THAT(Group{group}.Match(2), ElementsAre(2, 4)); + } else { + FAIL() << "No test coverage for Group::kWidth==" << Group::kWidth; + } +} + +TEST(Group, MatchEmpty) { + if (Group::kWidth == 16) { + ctrl_t group[] = {kEmpty, 1, kDeleted, 3, kEmpty, 5, kSentinel, 7, + 7, 5, 3, 1, 1, 1, 1, 1}; + EXPECT_THAT(Group{group}.MatchEmpty(), ElementsAre(0, 4)); + } else if (Group::kWidth == 8) { + ctrl_t group[] = {kEmpty, 1, 2, kDeleted, 2, 1, kSentinel, 1}; + EXPECT_THAT(Group{group}.MatchEmpty(), ElementsAre(0)); + } else { + FAIL() << "No test coverage for Group::kWidth==" << Group::kWidth; + } +} + +TEST(Group, MatchEmptyOrDeleted) { + if (Group::kWidth == 16) { + ctrl_t group[] = {kEmpty, 1, kDeleted, 3, kEmpty, 5, kSentinel, 7, + 7, 5, 3, 1, 1, 1, 1, 1}; + EXPECT_THAT(Group{group}.MatchEmptyOrDeleted(), ElementsAre(0, 2, 4)); + } else if (Group::kWidth == 8) { + ctrl_t group[] = {kEmpty, 1, 2, kDeleted, 2, 1, kSentinel, 1}; + EXPECT_THAT(Group{group}.MatchEmptyOrDeleted(), ElementsAre(0, 3)); + } else { + FAIL() << "No test coverage for Group::kWidth==" << Group::kWidth; + } +} + +TEST(Batch, DropDeletes) { + constexpr size_t kCapacity = 63; + constexpr size_t kGroupWidth = container_internal::Group::kWidth; + std::vector ctrl(kCapacity + 1 + kGroupWidth); + ctrl[kCapacity] = kSentinel; + std::vector pattern = {kEmpty, 2, kDeleted, 2, kEmpty, 1, kDeleted}; + for (size_t i = 0; i != kCapacity; ++i) { + ctrl[i] = pattern[i % pattern.size()]; + if (i < kGroupWidth - 1) + ctrl[i + kCapacity + 1] = pattern[i % pattern.size()]; + } + ConvertDeletedToEmptyAndFullToDeleted(ctrl.data(), kCapacity); + ASSERT_EQ(ctrl[kCapacity], kSentinel); + for (size_t i = 0; i < kCapacity + 1 + kGroupWidth; ++i) { + ctrl_t expected = pattern[i % (kCapacity + 1) % pattern.size()]; + if (i == kCapacity) expected = kSentinel; + if (expected == kDeleted) expected = kEmpty; + if (IsFull(expected)) expected = kDeleted; + EXPECT_EQ(ctrl[i], expected) + << i << " " << int{pattern[i % pattern.size()]}; + } +} + +TEST(Group, CountLeadingEmptyOrDeleted) { + const std::vector empty_examples = {kEmpty, kDeleted}; + const std::vector full_examples = {0, 1, 2, 3, 5, 9, 127, kSentinel}; + + for (ctrl_t empty : empty_examples) { + std::vector e(Group::kWidth, empty); + EXPECT_EQ(Group::kWidth, Group{e.data()}.CountLeadingEmptyOrDeleted()); + for (ctrl_t full : full_examples) { + for (size_t i = 0; i != Group::kWidth; ++i) { + std::vector f(Group::kWidth, empty); + f[i] = full; + EXPECT_EQ(i, Group{f.data()}.CountLeadingEmptyOrDeleted()); + } + std::vector f(Group::kWidth, empty); + f[Group::kWidth * 2 / 3] = full; + f[Group::kWidth / 2] = full; + EXPECT_EQ( + Group::kWidth / 2, Group{f.data()}.CountLeadingEmptyOrDeleted()); + } + } +} + +struct IntPolicy { + using slot_type = int64_t; + using key_type = int64_t; + using init_type = int64_t; + + static void construct(void*, int64_t* slot, int64_t v) { *slot = v; } + static void destroy(void*, int64_t*) {} + static void transfer(void*, int64_t* new_slot, int64_t* old_slot) { + *new_slot = *old_slot; + } + + static int64_t& element(slot_type* slot) { return *slot; } + + template + static auto apply(F&& f, int64_t x) -> decltype(std::forward(f)(x, x)) { + return std::forward(f)(x, x); + } +}; + +class StringPolicy { + template ::value>::type> + decltype(std::declval()( + std::declval(), std::piecewise_construct, + std::declval>(), + std::declval())) static apply_impl(F&& f, + std::pair, V> p) { + const absl::string_view& key = std::get<0>(p.first); + return std::forward(f)(key, std::piecewise_construct, std::move(p.first), + std::move(p.second)); + } + + public: + struct slot_type { + struct ctor {}; + + template + slot_type(ctor, Ts&&... ts) : pair(std::forward(ts)...) {} + + std::pair pair; + }; + + using key_type = std::string; + using init_type = std::pair; + + template + static void construct(allocator_type* alloc, slot_type* slot, Args... args) { + std::allocator_traits::construct( + *alloc, slot, typename slot_type::ctor(), std::forward(args)...); + } + + template + static void destroy(allocator_type* alloc, slot_type* slot) { + std::allocator_traits::destroy(*alloc, slot); + } + + template + static void transfer(allocator_type* alloc, slot_type* new_slot, + slot_type* old_slot) { + construct(alloc, new_slot, std::move(old_slot->pair)); + destroy(alloc, old_slot); + } + + static std::pair& element(slot_type* slot) { + return slot->pair; + } + + template + static auto apply(F&& f, Args&&... args) + -> decltype(apply_impl(std::forward(f), + PairArgs(std::forward(args)...))) { + return apply_impl(std::forward(f), + PairArgs(std::forward(args)...)); + } +}; + +struct StringHash : absl::Hash { + using is_transparent = void; +}; +struct StringEq : std::equal_to { + using is_transparent = void; +}; + +struct StringTable + : raw_hash_set> { + using Base = typename StringTable::raw_hash_set; + StringTable() {} + using Base::Base; +}; + +struct IntTable + : raw_hash_set, + std::equal_to, std::allocator> { + using Base = typename IntTable::raw_hash_set; + IntTable() {} + using Base::Base; +}; + +struct BadFastHash { + template + size_t operator()(const T&) const { + return 0; + } +}; + +struct BadTable : raw_hash_set, + std::allocator> { + using Base = typename BadTable::raw_hash_set; + BadTable() {} + using Base::Base; +}; + +TEST(Table, EmptyFunctorOptimization) { + static_assert(std::is_empty>::value, ""); + static_assert(std::is_empty>::value, ""); + + struct MockTable { + void* ctrl; + void* slots; + size_t size; + size_t capacity; + size_t growth_left; + }; + struct StatelessHash { + size_t operator()(absl::string_view) const { return 0; } + }; + struct StatefulHash : StatelessHash { + size_t dummy; + }; + + EXPECT_EQ( + sizeof(MockTable), + sizeof( + raw_hash_set, std::allocator>)); + + EXPECT_EQ( + sizeof(MockTable) + sizeof(StatefulHash), + sizeof( + raw_hash_set, std::allocator>)); +} + +TEST(Table, Empty) { + IntTable t; + EXPECT_EQ(0, t.size()); + EXPECT_TRUE(t.empty()); +} + +#ifdef __GNUC__ +template +ABSL_ATTRIBUTE_ALWAYS_INLINE inline void DoNotOptimize(const T& v) { + asm volatile("" : : "r,m"(v) : "memory"); +} +#endif + +TEST(Table, Prefetch) { + IntTable t; + t.emplace(1); + // Works for both present and absent keys. + t.prefetch(1); + t.prefetch(2); + + // Do not run in debug mode, when prefetch is not implemented, or when + // sanitizers are enabled. +#if defined(NDEBUG) && defined(__GNUC__) && !defined(ADDRESS_SANITIZER) && \ + !defined(MEMORY_SANITIZER) && !defined(THREAD_SANITIZER) && \ + !defined(UNDEFINED_BEHAVIOR_SANITIZER) + const auto now = [] { return absl::base_internal::CycleClock::Now(); }; + + static constexpr int size = 1000000; + for (int i = 0; i < size; ++i) t.insert(i); + + int64_t no_prefetch = 0, prefetch = 0; + for (int iter = 0; iter < 10; ++iter) { + int64_t time = now(); + for (int i = 0; i < size; ++i) { + DoNotOptimize(t.find(i)); + } + no_prefetch += now() - time; + + time = now(); + for (int i = 0; i < size; ++i) { + t.prefetch(i + 20); + DoNotOptimize(t.find(i)); + } + prefetch += now() - time; + } + + // no_prefetch is at least 30% slower. + EXPECT_GE(1.0 * no_prefetch / prefetch, 1.3); +#endif +} + +TEST(Table, LookupEmpty) { + IntTable t; + auto it = t.find(0); + EXPECT_TRUE(it == t.end()); +} + +TEST(Table, Insert1) { + IntTable t; + EXPECT_TRUE(t.find(0) == t.end()); + auto res = t.emplace(0); + EXPECT_TRUE(res.second); + EXPECT_THAT(*res.first, 0); + EXPECT_EQ(1, t.size()); + EXPECT_THAT(*t.find(0), 0); +} + +TEST(Table, Insert2) { + IntTable t; + EXPECT_TRUE(t.find(0) == t.end()); + auto res = t.emplace(0); + EXPECT_TRUE(res.second); + EXPECT_THAT(*res.first, 0); + EXPECT_EQ(1, t.size()); + EXPECT_TRUE(t.find(1) == t.end()); + res = t.emplace(1); + EXPECT_TRUE(res.second); + EXPECT_THAT(*res.first, 1); + EXPECT_EQ(2, t.size()); + EXPECT_THAT(*t.find(0), 0); + EXPECT_THAT(*t.find(1), 1); +} + +TEST(Table, InsertCollision) { + BadTable t; + EXPECT_TRUE(t.find(1) == t.end()); + auto res = t.emplace(1); + EXPECT_TRUE(res.second); + EXPECT_THAT(*res.first, 1); + EXPECT_EQ(1, t.size()); + + EXPECT_TRUE(t.find(2) == t.end()); + res = t.emplace(2); + EXPECT_THAT(*res.first, 2); + EXPECT_TRUE(res.second); + EXPECT_EQ(2, t.size()); + + EXPECT_THAT(*t.find(1), 1); + EXPECT_THAT(*t.find(2), 2); +} + +// Test that we do not add existent element in case we need to search through +// many groups with deleted elements +TEST(Table, InsertCollisionAndFindAfterDelete) { + BadTable t; // all elements go to the same group. + // Have at least 2 groups with Group::kWidth collisions + // plus some extra collisions in the last group. + constexpr size_t kNumInserts = Group::kWidth * 2 + 5; + for (size_t i = 0; i < kNumInserts; ++i) { + auto res = t.emplace(i); + EXPECT_TRUE(res.second); + EXPECT_THAT(*res.first, i); + EXPECT_EQ(i + 1, t.size()); + } + + // Remove elements one by one and check + // that we still can find all other elements. + for (size_t i = 0; i < kNumInserts; ++i) { + EXPECT_EQ(1, t.erase(i)) << i; + for (size_t j = i + 1; j < kNumInserts; ++j) { + EXPECT_THAT(*t.find(j), j); + auto res = t.emplace(j); + EXPECT_FALSE(res.second) << i << " " << j; + EXPECT_THAT(*res.first, j); + EXPECT_EQ(kNumInserts - i - 1, t.size()); + } + } + EXPECT_TRUE(t.empty()); +} + +TEST(Table, LazyEmplace) { + StringTable t; + bool called = false; + auto it = t.lazy_emplace("abc", [&](const StringTable::constructor& f) { + called = true; + f("abc", "ABC"); + }); + EXPECT_TRUE(called); + EXPECT_THAT(*it, Pair("abc", "ABC")); + called = false; + it = t.lazy_emplace("abc", [&](const StringTable::constructor& f) { + called = true; + f("abc", "DEF"); + }); + EXPECT_FALSE(called); + EXPECT_THAT(*it, Pair("abc", "ABC")); +} + +TEST(Table, ContainsEmpty) { + IntTable t; + + EXPECT_FALSE(t.contains(0)); +} + +TEST(Table, Contains1) { + IntTable t; + + EXPECT_TRUE(t.insert(0).second); + EXPECT_TRUE(t.contains(0)); + EXPECT_FALSE(t.contains(1)); + + EXPECT_EQ(1, t.erase(0)); + EXPECT_FALSE(t.contains(0)); +} + +TEST(Table, Contains2) { + IntTable t; + + EXPECT_TRUE(t.insert(0).second); + EXPECT_TRUE(t.contains(0)); + EXPECT_FALSE(t.contains(1)); + + t.clear(); + EXPECT_FALSE(t.contains(0)); +} + +int decompose_constructed; +struct DecomposeType { + DecomposeType(int i) : i(i) { // NOLINT + ++decompose_constructed; + } + + explicit DecomposeType(const char* d) : DecomposeType(*d) {} + + int i; +}; + +struct DecomposeHash { + using is_transparent = void; + size_t operator()(DecomposeType a) const { return a.i; } + size_t operator()(int a) const { return a; } + size_t operator()(const char* a) const { return *a; } +}; + +struct DecomposeEq { + using is_transparent = void; + bool operator()(DecomposeType a, DecomposeType b) const { return a.i == b.i; } + bool operator()(DecomposeType a, int b) const { return a.i == b; } + bool operator()(DecomposeType a, const char* b) const { return a.i == *b; } +}; + +struct DecomposePolicy { + using slot_type = DecomposeType; + using key_type = DecomposeType; + using init_type = DecomposeType; + + template + static void construct(void*, DecomposeType* slot, T&& v) { + *slot = DecomposeType(std::forward(v)); + } + static void destroy(void*, DecomposeType*) {} + static DecomposeType& element(slot_type* slot) { return *slot; } + + template + static auto apply(F&& f, const T& x) -> decltype(std::forward(f)(x, x)) { + return std::forward(f)(x, x); + } +}; + +template +void TestDecompose(bool construct_three) { + DecomposeType elem{0}; + const int one = 1; + const char* three_p = "3"; + const auto& three = three_p; + + raw_hash_set> set1; + + decompose_constructed = 0; + int expected_constructed = 0; + EXPECT_EQ(expected_constructed, decompose_constructed); + set1.insert(elem); + EXPECT_EQ(expected_constructed, decompose_constructed); + set1.insert(1); + EXPECT_EQ(++expected_constructed, decompose_constructed); + set1.emplace("3"); + EXPECT_EQ(++expected_constructed, decompose_constructed); + EXPECT_EQ(expected_constructed, decompose_constructed); + + { // insert(T&&) + set1.insert(1); + EXPECT_EQ(expected_constructed, decompose_constructed); + } + + { // insert(const T&) + set1.insert(one); + EXPECT_EQ(expected_constructed, decompose_constructed); + } + + { // insert(hint, T&&) + set1.insert(set1.begin(), 1); + EXPECT_EQ(expected_constructed, decompose_constructed); + } + + { // insert(hint, const T&) + set1.insert(set1.begin(), one); + EXPECT_EQ(expected_constructed, decompose_constructed); + } + + { // emplace(...) + set1.emplace(1); + EXPECT_EQ(expected_constructed, decompose_constructed); + set1.emplace("3"); + expected_constructed += construct_three; + EXPECT_EQ(expected_constructed, decompose_constructed); + set1.emplace(one); + EXPECT_EQ(expected_constructed, decompose_constructed); + set1.emplace(three); + expected_constructed += construct_three; + EXPECT_EQ(expected_constructed, decompose_constructed); + } + + { // emplace_hint(...) + set1.emplace_hint(set1.begin(), 1); + EXPECT_EQ(expected_constructed, decompose_constructed); + set1.emplace_hint(set1.begin(), "3"); + expected_constructed += construct_three; + EXPECT_EQ(expected_constructed, decompose_constructed); + set1.emplace_hint(set1.begin(), one); + EXPECT_EQ(expected_constructed, decompose_constructed); + set1.emplace_hint(set1.begin(), three); + expected_constructed += construct_three; + EXPECT_EQ(expected_constructed, decompose_constructed); + } +} + +TEST(Table, Decompose) { + TestDecompose(false); + + struct TransparentHashIntOverload { + size_t operator()(DecomposeType a) const { return a.i; } + size_t operator()(int a) const { return a; } + }; + struct TransparentEqIntOverload { + bool operator()(DecomposeType a, DecomposeType b) const { + return a.i == b.i; + } + bool operator()(DecomposeType a, int b) const { return a.i == b; } + }; + TestDecompose(true); + TestDecompose(true); + TestDecompose(true); +} + +// Returns the largest m such that a table with m elements has the same number +// of buckets as a table with n elements. +size_t MaxDensitySize(size_t n) { + IntTable t; + t.reserve(n); + for (size_t i = 0; i != n; ++i) t.emplace(i); + const size_t c = t.bucket_count(); + while (c == t.bucket_count()) t.emplace(n++); + return t.size() - 1; +} + +struct Modulo1000Hash { + size_t operator()(int x) const { return x % 1000; } +}; + +struct Modulo1000HashTable + : public raw_hash_set, + std::allocator> {}; + +// Test that rehash with no resize happen in case of many deleted slots. +TEST(Table, RehashWithNoResize) { + Modulo1000HashTable t; + // Adding the same length (and the same hash) strings + // to have at least kMinFullGroups groups + // with Group::kWidth collisions. Then fill up to MaxDensitySize; + const size_t kMinFullGroups = 7; + std::vector keys; + for (size_t i = 0; i < MaxDensitySize(Group::kWidth * kMinFullGroups); ++i) { + int k = i * 1000; + t.emplace(k); + keys.push_back(k); + } + const size_t capacity = t.capacity(); + + // Remove elements from all groups except the first and the last one. + // All elements removed from full groups will be marked as kDeleted. + const size_t erase_begin = Group::kWidth / 2; + const size_t erase_end = (t.size() / Group::kWidth - 1) * Group::kWidth; + for (size_t i = erase_begin; i < erase_end; ++i) { + EXPECT_EQ(1, t.erase(keys[i])) << i; + } + keys.erase(keys.begin() + erase_begin, keys.begin() + erase_end); + + auto last_key = keys.back(); + size_t last_key_num_probes = GetHashtableDebugNumProbes(t, last_key); + + // Make sure that we have to make a lot of probes for last key. + ASSERT_GT(last_key_num_probes, kMinFullGroups); + + int x = 1; + // Insert and erase one element, before inplace rehash happen. + while (last_key_num_probes == GetHashtableDebugNumProbes(t, last_key)) { + t.emplace(x); + ASSERT_EQ(capacity, t.capacity()); + // All elements should be there. + ASSERT_TRUE(t.find(x) != t.end()) << x; + for (const auto& k : keys) { + ASSERT_TRUE(t.find(k) != t.end()) << k; + } + t.erase(x); + ++x; + } +} + +TEST(Table, InsertEraseStressTest) { + IntTable t; + const size_t kMinElementCount = 250; + std::deque keys; + size_t i = 0; + for (; i < MaxDensitySize(kMinElementCount); ++i) { + t.emplace(i); + keys.push_back(i); + } + const size_t kNumIterations = 1000000; + for (; i < kNumIterations; ++i) { + ASSERT_EQ(1, t.erase(keys.front())); + keys.pop_front(); + t.emplace(i); + keys.push_back(i); + } +} + +TEST(Table, InsertOverloads) { + StringTable t; + // These should all trigger the insert(init_type) overload. + t.insert({{}, {}}); + t.insert({"ABC", {}}); + t.insert({"DEF", "!!!"}); + + EXPECT_THAT(t, UnorderedElementsAre(Pair("", ""), Pair("ABC", ""), + Pair("DEF", "!!!"))); +} + +TEST(Table, LargeTable) { + IntTable t; + for (int64_t i = 0; i != 100000; ++i) t.emplace(i << 40); + for (int64_t i = 0; i != 100000; ++i) ASSERT_EQ(i << 40, *t.find(i << 40)); +} + +// Timeout if copy is quadratic as it was in Rust. +TEST(Table, EnsureNonQuadraticAsInRust) { + static const size_t kLargeSize = 1 << 15; + + IntTable t; + for (size_t i = 0; i != kLargeSize; ++i) { + t.insert(i); + } + + // If this is quadratic, the test will timeout. + IntTable t2; + for (const auto& entry : t) t2.insert(entry); +} + +TEST(Table, ClearBug) { + IntTable t; + constexpr size_t capacity = container_internal::Group::kWidth - 1; + constexpr size_t max_size = capacity / 2; + for (size_t i = 0; i < max_size; ++i) { + t.insert(i); + } + ASSERT_EQ(capacity, t.capacity()); + intptr_t original = reinterpret_cast(&*t.find(2)); + t.clear(); + ASSERT_EQ(capacity, t.capacity()); + for (size_t i = 0; i < max_size; ++i) { + t.insert(i); + } + ASSERT_EQ(capacity, t.capacity()); + intptr_t second = reinterpret_cast(&*t.find(2)); + // We are checking that original and second are close enough to each other + // that they are probably still in the same group. This is not strictly + // guaranteed. + EXPECT_LT(std::abs(original - second), + capacity * sizeof(IntTable::value_type)); +} + +TEST(Table, Erase) { + IntTable t; + EXPECT_TRUE(t.find(0) == t.end()); + auto res = t.emplace(0); + EXPECT_TRUE(res.second); + EXPECT_EQ(1, t.size()); + t.erase(res.first); + EXPECT_EQ(0, t.size()); + EXPECT_TRUE(t.find(0) == t.end()); +} + +// Collect N bad keys by following algorithm: +// 1. Create an empty table and reserve it to 2 * N. +// 2. Insert N random elements. +// 3. Take first Group::kWidth - 1 to bad_keys array. +// 4. Clear the table without resize. +// 5. Go to point 2 while N keys not collected +std::vector CollectBadMergeKeys(size_t N) { + static constexpr int kGroupSize = Group::kWidth - 1; + + auto topk_range = [](size_t b, size_t e, IntTable* t) -> std::vector { + for (size_t i = b; i != e; ++i) { + t->emplace(i); + } + std::vector res; + res.reserve(kGroupSize); + auto it = t->begin(); + for (size_t i = b; i != e && i != b + kGroupSize; ++i, ++it) { + res.push_back(*it); + } + return res; + }; + + std::vector bad_keys; + bad_keys.reserve(N); + IntTable t; + t.reserve(N * 2); + + for (size_t b = 0; bad_keys.size() < N; b += N) { + auto keys = topk_range(b, b + N, &t); + bad_keys.insert(bad_keys.end(), keys.begin(), keys.end()); + t.erase(t.begin(), t.end()); + EXPECT_TRUE(t.empty()); + } + return bad_keys; +} + +struct ProbeStats { + // Number of elements with specific probe length over all tested tables. + std::vector all_probes_histogram; + // Ratios total_probe_length/size for every tested table. + std::vector single_table_ratios; + + friend ProbeStats operator+(const ProbeStats& a, const ProbeStats& b) { + ProbeStats res = a; + res.all_probes_histogram.resize(std::max(res.all_probes_histogram.size(), + b.all_probes_histogram.size())); + std::transform(b.all_probes_histogram.begin(), b.all_probes_histogram.end(), + res.all_probes_histogram.begin(), + res.all_probes_histogram.begin(), std::plus()); + res.single_table_ratios.insert(res.single_table_ratios.end(), + b.single_table_ratios.begin(), + b.single_table_ratios.end()); + return res; + } + + // Average ratio total_probe_length/size over tables. + double AvgRatio() const { + return std::accumulate(single_table_ratios.begin(), + single_table_ratios.end(), 0.0) / + single_table_ratios.size(); + } + + // Maximum ratio total_probe_length/size over tables. + double MaxRatio() const { + return *std::max_element(single_table_ratios.begin(), + single_table_ratios.end()); + } + + // Percentile ratio total_probe_length/size over tables. + double PercentileRatio(double Percentile = 0.95) const { + auto r = single_table_ratios; + auto mid = r.begin() + static_cast(r.size() * Percentile); + if (mid != r.end()) { + std::nth_element(r.begin(), mid, r.end()); + return *mid; + } else { + return MaxRatio(); + } + } + + // Maximum probe length over all elements and all tables. + size_t MaxProbe() const { return all_probes_histogram.size(); } + + // Fraction of elements with specified probe length. + std::vector ProbeNormalizedHistogram() const { + double total_elements = std::accumulate(all_probes_histogram.begin(), + all_probes_histogram.end(), 0ull); + std::vector res; + for (size_t p : all_probes_histogram) { + res.push_back(p / total_elements); + } + return res; + } + + size_t PercentileProbe(double Percentile = 0.99) const { + size_t idx = 0; + for (double p : ProbeNormalizedHistogram()) { + if (Percentile > p) { + Percentile -= p; + ++idx; + } else { + return idx; + } + } + return idx; + } + + friend std::ostream& operator<<(std::ostream& out, const ProbeStats& s) { + out << "{AvgRatio:" << s.AvgRatio() << ", MaxRatio:" << s.MaxRatio() + << ", PercentileRatio:" << s.PercentileRatio() + << ", MaxProbe:" << s.MaxProbe() << ", Probes=["; + for (double p : s.ProbeNormalizedHistogram()) { + out << p << ","; + } + out << "]}"; + + return out; + } +}; + +struct ExpectedStats { + double avg_ratio; + double max_ratio; + std::vector> pecentile_ratios; + std::vector> pecentile_probes; + + friend std::ostream& operator<<(std::ostream& out, const ExpectedStats& s) { + out << "{AvgRatio:" << s.avg_ratio << ", MaxRatio:" << s.max_ratio + << ", PercentileRatios: ["; + for (auto el : s.pecentile_ratios) { + out << el.first << ":" << el.second << ", "; + } + out << "], PercentileProbes: ["; + for (auto el : s.pecentile_probes) { + out << el.first << ":" << el.second << ", "; + } + out << "]}"; + + return out; + } +}; + +void VerifyStats(size_t size, const ExpectedStats& exp, + const ProbeStats& stats) { + EXPECT_LT(stats.AvgRatio(), exp.avg_ratio) << size << " " << stats; + EXPECT_LT(stats.MaxRatio(), exp.max_ratio) << size << " " << stats; + for (auto pr : exp.pecentile_ratios) { + EXPECT_LE(stats.PercentileRatio(pr.first), pr.second) + << size << " " << pr.first << " " << stats; + } + + for (auto pr : exp.pecentile_probes) { + EXPECT_LE(stats.PercentileProbe(pr.first), pr.second) + << size << " " << pr.first << " " << stats; + } +} + +using ProbeStatsPerSize = std::map; + +// Collect total ProbeStats on num_iters iterations of the following algorithm: +// 1. Create new table and reserve it to keys.size() * 2 +// 2. Insert all keys xored with seed +// 3. Collect ProbeStats from final table. +ProbeStats CollectProbeStatsOnKeysXoredWithSeed(const std::vector& keys, + size_t num_iters) { + const size_t reserve_size = keys.size() * 2; + + ProbeStats stats; + + int64_t seed = 0x71b1a19b907d6e33; + while (num_iters--) { + seed = static_cast(static_cast(seed) * 17 + 13); + IntTable t1; + t1.reserve(reserve_size); + for (const auto& key : keys) { + t1.emplace(key ^ seed); + } + + auto probe_histogram = GetHashtableDebugNumProbesHistogram(t1); + stats.all_probes_histogram.resize( + std::max(stats.all_probes_histogram.size(), probe_histogram.size())); + std::transform(probe_histogram.begin(), probe_histogram.end(), + stats.all_probes_histogram.begin(), + stats.all_probes_histogram.begin(), std::plus()); + + size_t total_probe_seq_length = 0; + for (size_t i = 0; i < probe_histogram.size(); ++i) { + total_probe_seq_length += i * probe_histogram[i]; + } + stats.single_table_ratios.push_back(total_probe_seq_length * 1.0 / + keys.size()); + t1.erase(t1.begin(), t1.end()); + } + return stats; +} + +ExpectedStats XorSeedExpectedStats() { + constexpr bool kRandomizesInserts = +#if NDEBUG + false; +#else // NDEBUG + true; +#endif // NDEBUG + + // The effective load factor is larger in non-opt mode because we insert + // elements out of order. + switch (container_internal::Group::kWidth) { + case 8: + if (kRandomizesInserts) { + return {0.05, + 1.0, + {{0.95, 0.5}}, + {{0.95, 0}, {0.99, 2}, {0.999, 4}, {0.9999, 10}}}; + } else { + return {0.05, + 2.0, + {{0.95, 0.1}}, + {{0.95, 0}, {0.99, 2}, {0.999, 4}, {0.9999, 10}}}; + } + case 16: + if (kRandomizesInserts) { + return {0.1, + 1.0, + {{0.95, 0.1}}, + {{0.95, 0}, {0.99, 1}, {0.999, 8}, {0.9999, 15}}}; + } else { + return {0.05, + 1.0, + {{0.95, 0.05}}, + {{0.95, 0}, {0.99, 1}, {0.999, 4}, {0.9999, 10}}}; + } + } + ABSL_RAW_LOG(FATAL, "%s", "Unknown Group width"); + return {}; +} +TEST(Table, DISABLED_EnsureNonQuadraticTopNXorSeedByProbeSeqLength) { + ProbeStatsPerSize stats; + std::vector sizes = {Group::kWidth << 5, Group::kWidth << 10}; + for (size_t size : sizes) { + stats[size] = + CollectProbeStatsOnKeysXoredWithSeed(CollectBadMergeKeys(size), 200); + } + auto expected = XorSeedExpectedStats(); + for (size_t size : sizes) { + auto& stat = stats[size]; + VerifyStats(size, expected, stat); + } +} + +// Collect total ProbeStats on num_iters iterations of the following algorithm: +// 1. Create new table +// 2. Select 10% of keys and insert 10 elements key * 17 + j * 13 +// 3. Collect ProbeStats from final table +ProbeStats CollectProbeStatsOnLinearlyTransformedKeys( + const std::vector& keys, size_t num_iters) { + ProbeStats stats; + + std::random_device rd; + std::mt19937 rng(rd()); + auto linear_transform = [](size_t x, size_t y) { return x * 17 + y * 13; }; + std::uniform_int_distribution dist(0, keys.size()-1); + while (num_iters--) { + IntTable t1; + size_t num_keys = keys.size() / 10; + size_t start = dist(rng); + for (size_t i = 0; i != num_keys; ++i) { + for (size_t j = 0; j != 10; ++j) { + t1.emplace(linear_transform(keys[(i + start) % keys.size()], j)); + } + } + + auto probe_histogram = GetHashtableDebugNumProbesHistogram(t1); + stats.all_probes_histogram.resize( + std::max(stats.all_probes_histogram.size(), probe_histogram.size())); + std::transform(probe_histogram.begin(), probe_histogram.end(), + stats.all_probes_histogram.begin(), + stats.all_probes_histogram.begin(), std::plus()); + + size_t total_probe_seq_length = 0; + for (size_t i = 0; i < probe_histogram.size(); ++i) { + total_probe_seq_length += i * probe_histogram[i]; + } + stats.single_table_ratios.push_back(total_probe_seq_length * 1.0 / + t1.size()); + t1.erase(t1.begin(), t1.end()); + } + return stats; +} + +ExpectedStats LinearTransformExpectedStats() { + constexpr bool kRandomizesInserts = +#if NDEBUG + false; +#else // NDEBUG + true; +#endif // NDEBUG + + // The effective load factor is larger in non-opt mode because we insert + // elements out of order. + switch (container_internal::Group::kWidth) { + case 8: + if (kRandomizesInserts) { + return {0.1, + 0.5, + {{0.95, 0.3}}, + {{0.95, 0}, {0.99, 1}, {0.999, 8}, {0.9999, 15}}}; + } else { + return {0.15, + 0.5, + {{0.95, 0.3}}, + {{0.95, 0}, {0.99, 3}, {0.999, 15}, {0.9999, 25}}}; + } + case 16: + if (kRandomizesInserts) { + return {0.1, + 0.4, + {{0.95, 0.3}}, + {{0.95, 0}, {0.99, 1}, {0.999, 8}, {0.9999, 15}}}; + } else { + return {0.05, + 0.2, + {{0.95, 0.1}}, + {{0.95, 0}, {0.99, 1}, {0.999, 6}, {0.9999, 10}}}; + } + } + ABSL_RAW_LOG(FATAL, "%s", "Unknown Group width"); + return {}; +} +TEST(Table, DISABLED_EnsureNonQuadraticTopNLinearTransformByProbeSeqLength) { + ProbeStatsPerSize stats; + std::vector sizes = {Group::kWidth << 5, Group::kWidth << 10}; + for (size_t size : sizes) { + stats[size] = CollectProbeStatsOnLinearlyTransformedKeys( + CollectBadMergeKeys(size), 300); + } + auto expected = LinearTransformExpectedStats(); + for (size_t size : sizes) { + auto& stat = stats[size]; + VerifyStats(size, expected, stat); + } +} + +TEST(Table, EraseCollision) { + BadTable t; + + // 1 2 3 + t.emplace(1); + t.emplace(2); + t.emplace(3); + EXPECT_THAT(*t.find(1), 1); + EXPECT_THAT(*t.find(2), 2); + EXPECT_THAT(*t.find(3), 3); + EXPECT_EQ(3, t.size()); + + // 1 DELETED 3 + t.erase(t.find(2)); + EXPECT_THAT(*t.find(1), 1); + EXPECT_TRUE(t.find(2) == t.end()); + EXPECT_THAT(*t.find(3), 3); + EXPECT_EQ(2, t.size()); + + // DELETED DELETED 3 + t.erase(t.find(1)); + EXPECT_TRUE(t.find(1) == t.end()); + EXPECT_TRUE(t.find(2) == t.end()); + EXPECT_THAT(*t.find(3), 3); + EXPECT_EQ(1, t.size()); + + // DELETED DELETED DELETED + t.erase(t.find(3)); + EXPECT_TRUE(t.find(1) == t.end()); + EXPECT_TRUE(t.find(2) == t.end()); + EXPECT_TRUE(t.find(3) == t.end()); + EXPECT_EQ(0, t.size()); +} + +TEST(Table, EraseInsertProbing) { + BadTable t(100); + + // 1 2 3 4 + t.emplace(1); + t.emplace(2); + t.emplace(3); + t.emplace(4); + + // 1 DELETED 3 DELETED + t.erase(t.find(2)); + t.erase(t.find(4)); + + // 1 10 3 11 12 + t.emplace(10); + t.emplace(11); + t.emplace(12); + + EXPECT_EQ(5, t.size()); + EXPECT_THAT(t, UnorderedElementsAre(1, 10, 3, 11, 12)); +} + +TEST(Table, Clear) { + IntTable t; + EXPECT_TRUE(t.find(0) == t.end()); + t.clear(); + EXPECT_TRUE(t.find(0) == t.end()); + auto res = t.emplace(0); + EXPECT_TRUE(res.second); + EXPECT_EQ(1, t.size()); + t.clear(); + EXPECT_EQ(0, t.size()); + EXPECT_TRUE(t.find(0) == t.end()); +} + +TEST(Table, Swap) { + IntTable t; + EXPECT_TRUE(t.find(0) == t.end()); + auto res = t.emplace(0); + EXPECT_TRUE(res.second); + EXPECT_EQ(1, t.size()); + IntTable u; + t.swap(u); + EXPECT_EQ(0, t.size()); + EXPECT_EQ(1, u.size()); + EXPECT_TRUE(t.find(0) == t.end()); + EXPECT_THAT(*u.find(0), 0); +} + +TEST(Table, Rehash) { + IntTable t; + EXPECT_TRUE(t.find(0) == t.end()); + t.emplace(0); + t.emplace(1); + EXPECT_EQ(2, t.size()); + t.rehash(128); + EXPECT_EQ(2, t.size()); + EXPECT_THAT(*t.find(0), 0); + EXPECT_THAT(*t.find(1), 1); +} + +TEST(Table, RehashDoesNotRehashWhenNotNecessary) { + IntTable t; + t.emplace(0); + t.emplace(1); + auto* p = &*t.find(0); + t.rehash(1); + EXPECT_EQ(p, &*t.find(0)); +} + +TEST(Table, RehashZeroDoesNotAllocateOnEmptyTable) { + IntTable t; + t.rehash(0); + EXPECT_EQ(0, t.bucket_count()); +} + +TEST(Table, RehashZeroDeallocatesEmptyTable) { + IntTable t; + t.emplace(0); + t.clear(); + EXPECT_NE(0, t.bucket_count()); + t.rehash(0); + EXPECT_EQ(0, t.bucket_count()); +} + +TEST(Table, RehashZeroForcesRehash) { + IntTable t; + t.emplace(0); + t.emplace(1); + auto* p = &*t.find(0); + t.rehash(0); + EXPECT_NE(p, &*t.find(0)); +} + +TEST(Table, ConstructFromInitList) { + using P = std::pair; + struct Q { + operator P() const { return {}; } + }; + StringTable t = {P(), Q(), {}, {{}, {}}}; +} + +TEST(Table, CopyConstruct) { + IntTable t; + t.max_load_factor(.321f); + t.emplace(0); + EXPECT_EQ(1, t.size()); + { + IntTable u(t); + EXPECT_EQ(1, u.size()); + EXPECT_EQ(t.max_load_factor(), u.max_load_factor()); + EXPECT_THAT(*u.find(0), 0); + } + { + IntTable u{t}; + EXPECT_EQ(1, u.size()); + EXPECT_EQ(t.max_load_factor(), u.max_load_factor()); + EXPECT_THAT(*u.find(0), 0); + } + { + IntTable u = t; + EXPECT_EQ(1, u.size()); + EXPECT_EQ(t.max_load_factor(), u.max_load_factor()); + EXPECT_THAT(*u.find(0), 0); + } +} + +TEST(Table, CopyConstructWithAlloc) { + StringTable t; + t.max_load_factor(.321f); + t.emplace("a", "b"); + EXPECT_EQ(1, t.size()); + StringTable u(t, Alloc>()); + EXPECT_EQ(1, u.size()); + EXPECT_EQ(t.max_load_factor(), u.max_load_factor()); + EXPECT_THAT(*u.find("a"), Pair("a", "b")); +} + +struct ExplicitAllocIntTable + : raw_hash_set, + std::equal_to, Alloc> { + ExplicitAllocIntTable() {} +}; + +TEST(Table, AllocWithExplicitCtor) { + ExplicitAllocIntTable t; + EXPECT_EQ(0, t.size()); +} + +TEST(Table, MoveConstruct) { + { + StringTable t; + t.max_load_factor(.321f); + const float lf = t.max_load_factor(); + t.emplace("a", "b"); + EXPECT_EQ(1, t.size()); + + StringTable u(std::move(t)); + EXPECT_EQ(1, u.size()); + EXPECT_EQ(lf, u.max_load_factor()); + EXPECT_THAT(*u.find("a"), Pair("a", "b")); + } + { + StringTable t; + t.max_load_factor(.321f); + const float lf = t.max_load_factor(); + t.emplace("a", "b"); + EXPECT_EQ(1, t.size()); + + StringTable u{std::move(t)}; + EXPECT_EQ(1, u.size()); + EXPECT_EQ(lf, u.max_load_factor()); + EXPECT_THAT(*u.find("a"), Pair("a", "b")); + } + { + StringTable t; + t.max_load_factor(.321f); + const float lf = t.max_load_factor(); + t.emplace("a", "b"); + EXPECT_EQ(1, t.size()); + + StringTable u = std::move(t); + EXPECT_EQ(1, u.size()); + EXPECT_EQ(lf, u.max_load_factor()); + EXPECT_THAT(*u.find("a"), Pair("a", "b")); + } +} + +TEST(Table, MoveConstructWithAlloc) { + StringTable t; + t.max_load_factor(.321f); + const float lf = t.max_load_factor(); + t.emplace("a", "b"); + EXPECT_EQ(1, t.size()); + StringTable u(std::move(t), Alloc>()); + EXPECT_EQ(1, u.size()); + EXPECT_EQ(lf, u.max_load_factor()); + EXPECT_THAT(*u.find("a"), Pair("a", "b")); +} + +TEST(Table, CopyAssign) { + StringTable t; + t.max_load_factor(.321f); + t.emplace("a", "b"); + EXPECT_EQ(1, t.size()); + StringTable u; + u = t; + EXPECT_EQ(1, u.size()); + EXPECT_EQ(t.max_load_factor(), u.max_load_factor()); + EXPECT_THAT(*u.find("a"), Pair("a", "b")); +} + +TEST(Table, CopySelfAssign) { + StringTable t; + t.max_load_factor(.321f); + const float lf = t.max_load_factor(); + t.emplace("a", "b"); + EXPECT_EQ(1, t.size()); + t = *&t; + EXPECT_EQ(1, t.size()); + EXPECT_EQ(lf, t.max_load_factor()); + EXPECT_THAT(*t.find("a"), Pair("a", "b")); +} + +TEST(Table, MoveAssign) { + StringTable t; + t.max_load_factor(.321f); + const float lf = t.max_load_factor(); + t.emplace("a", "b"); + EXPECT_EQ(1, t.size()); + StringTable u; + u = std::move(t); + EXPECT_EQ(1, u.size()); + EXPECT_EQ(lf, u.max_load_factor()); + EXPECT_THAT(*u.find("a"), Pair("a", "b")); +} + +TEST(Table, Equality) { + StringTable t; + std::vector> v = {{"a", "b"}, {"aa", "bb"}}; + t.insert(std::begin(v), std::end(v)); + StringTable u = t; + EXPECT_EQ(u, t); +} + +TEST(Table, Equality2) { + StringTable t; + std::vector> v1 = {{"a", "b"}, {"aa", "bb"}}; + t.insert(std::begin(v1), std::end(v1)); + StringTable u; + std::vector> v2 = {{"a", "a"}, {"aa", "aa"}}; + u.insert(std::begin(v2), std::end(v2)); + EXPECT_NE(u, t); +} + +TEST(Table, Equality3) { + StringTable t; + std::vector> v1 = {{"b", "b"}, {"bb", "bb"}}; + t.insert(std::begin(v1), std::end(v1)); + StringTable u; + std::vector> v2 = {{"a", "a"}, {"aa", "aa"}}; + u.insert(std::begin(v2), std::end(v2)); + EXPECT_NE(u, t); +} + +TEST(Table, NumDeletedRegression) { + IntTable t; + t.emplace(0); + t.erase(t.find(0)); + // construct over a deleted slot. + t.emplace(0); + t.clear(); +} + +TEST(Table, FindFullDeletedRegression) { + IntTable t; + for (int i = 0; i < 1000; ++i) { + t.emplace(i); + t.erase(t.find(i)); + } + EXPECT_EQ(0, t.size()); +} + +TEST(Table, ReplacingDeletedSlotDoesNotRehash) { + size_t n; + { + // Compute n such that n is the maximum number of elements before rehash. + IntTable t; + t.emplace(0); + size_t c = t.bucket_count(); + for (n = 1; c == t.bucket_count(); ++n) t.emplace(n); + --n; + } + IntTable t; + t.rehash(n); + const size_t c = t.bucket_count(); + for (size_t i = 0; i != n; ++i) t.emplace(i); + EXPECT_EQ(c, t.bucket_count()) << "rehashing threshold = " << n; + t.erase(0); + t.emplace(0); + EXPECT_EQ(c, t.bucket_count()) << "rehashing threshold = " << n; +} + +TEST(Table, NoThrowMoveConstruct) { + ASSERT_TRUE( + std::is_nothrow_copy_constructible>::value); + ASSERT_TRUE(std::is_nothrow_copy_constructible< + std::equal_to>::value); + ASSERT_TRUE(std::is_nothrow_copy_constructible>::value); + EXPECT_TRUE(std::is_nothrow_move_constructible::value); +} + +TEST(Table, NoThrowMoveAssign) { + ASSERT_TRUE( + std::is_nothrow_move_assignable>::value); + ASSERT_TRUE( + std::is_nothrow_move_assignable>::value); + ASSERT_TRUE(std::is_nothrow_move_assignable>::value); + ASSERT_TRUE( + absl::allocator_traits>::is_always_equal::value); + EXPECT_TRUE(std::is_nothrow_move_assignable::value); +} + +TEST(Table, NoThrowSwappable) { + ASSERT_TRUE( + container_internal::IsNoThrowSwappable>()); + ASSERT_TRUE(container_internal::IsNoThrowSwappable< + std::equal_to>()); + ASSERT_TRUE(container_internal::IsNoThrowSwappable>()); + EXPECT_TRUE(container_internal::IsNoThrowSwappable()); +} + +TEST(Table, HeterogeneousLookup) { + struct Hash { + size_t operator()(int64_t i) const { return i; } + size_t operator()(double i) const { + ADD_FAILURE(); + return i; + } + }; + struct Eq { + bool operator()(int64_t a, int64_t b) const { return a == b; } + bool operator()(double a, int64_t b) const { + ADD_FAILURE(); + return a == b; + } + bool operator()(int64_t a, double b) const { + ADD_FAILURE(); + return a == b; + } + bool operator()(double a, double b) const { + ADD_FAILURE(); + return a == b; + } + }; + + struct THash { + using is_transparent = void; + size_t operator()(int64_t i) const { return i; } + size_t operator()(double i) const { return i; } + }; + struct TEq { + using is_transparent = void; + bool operator()(int64_t a, int64_t b) const { return a == b; } + bool operator()(double a, int64_t b) const { return a == b; } + bool operator()(int64_t a, double b) const { return a == b; } + bool operator()(double a, double b) const { return a == b; } + }; + + raw_hash_set> s{0, 1, 2}; + // It will convert to int64_t before the query. + EXPECT_EQ(1, *s.find(double{1.1})); + + raw_hash_set> ts{0, 1, 2}; + // It will try to use the double, and fail to find the object. + EXPECT_TRUE(ts.find(1.1) == ts.end()); +} + +template +using CallFind = decltype(std::declval().find(17)); + +template +using CallErase = decltype(std::declval().erase(17)); + +template +using CallExtract = decltype(std::declval().extract(17)); + +template +using CallPrefetch = decltype(std::declval().prefetch(17)); + +template +using CallCount = decltype(std::declval().count(17)); + +template